summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore16
-rw-r--r--.mailmap5
-rw-r--r--AUTHORS43
-rw-r--r--ChangeLog389
-rw-r--r--LICENSE145
-rw-r--r--Makefile88
-rw-r--r--benchmark/arrays/var-int.js20
-rw-r--r--benchmark/arrays/var_int.js15
-rw-r--r--benchmark/arrays/zero-float.js20
-rw-r--r--benchmark/arrays/zero-int.js20
-rw-r--r--benchmark/arrays/zero_float.js15
-rw-r--r--benchmark/arrays/zero_int.js15
-rw-r--r--benchmark/buffer_creation.js6
-rw-r--r--benchmark/buffers/buffer-base64-encode.js36
-rw-r--r--benchmark/buffers/buffer-creation.js19
-rw-r--r--benchmark/buffers/buffer-read.js28
-rw-r--r--benchmark/buffers/buffer-write.js63
-rw-r--r--benchmark/buffers/dataview-set.js57
-rw-r--r--benchmark/client_latency.js80
-rw-r--r--benchmark/common.js196
-rw-r--r--benchmark/compare.js138
-rw-r--r--benchmark/crypto/cipher-stream.js103
-rw-r--r--benchmark/fast_buffer2.js42
-rw-r--r--benchmark/fast_buffer2_creation.js6
-rw-r--r--benchmark/fast_buffer_creation.js4
-rw-r--r--benchmark/fs-readfile.js72
-rw-r--r--benchmark/fs-write-stream-throughput.js96
-rw-r--r--benchmark/fs/read-stream-throughput.js87
-rw-r--r--benchmark/fs/readfile.js48
-rw-r--r--benchmark/fs/write-stream-throughput.js78
-rw-r--r--benchmark/function_call/bench.js43
-rw-r--r--benchmark/function_call/binding.cc19
-rw-r--r--benchmark/function_call/wscript15
-rw-r--r--benchmark/http-flamegraph.sh116
-rw-r--r--benchmark/http/cluster.js38
-rw-r--r--benchmark/http/simple.js23
-rw-r--r--benchmark/http_simple.js16
-rwxr-xr-xbenchmark/http_simple_bench.sh5
-rw-r--r--benchmark/io.c9
-rw-r--r--benchmark/io.js109
-rw-r--r--benchmark/misc/function_call/.gitignore1
-rw-r--r--benchmark/misc/function_call/Makefile2
-rw-r--r--benchmark/misc/function_call/binding.cc18
-rw-r--r--benchmark/misc/function_call/binding.gyp8
-rw-r--r--benchmark/misc/function_call/index.js42
-rw-r--r--benchmark/misc/next-tick-breadth.js21
-rw-r--r--benchmark/misc/next-tick-depth.js40
-rw-r--r--benchmark/misc/spawn-echo.js25
-rw-r--r--benchmark/misc/startup.js40
-rw-r--r--benchmark/misc/string-creation.js16
-rw-r--r--benchmark/misc/timers.js40
-rw-r--r--benchmark/misc/url.js40
-rw-r--r--benchmark/misc/v8-bench.js18
-rw-r--r--benchmark/net/net-c2s.js112
-rw-r--r--benchmark/net/net-pipe.js115
-rw-r--r--benchmark/net/net-s2c.js112
-rw-r--r--benchmark/net/tcp-raw-c2s.js136
-rw-r--r--benchmark/net/tcp-raw-pipe.js149
-rw-r--r--benchmark/net/tcp-raw-s2c.js136
-rw-r--r--benchmark/next-tick-2.js41
-rw-r--r--benchmark/next-tick.js17
-rw-r--r--benchmark/process_loop.js19
-rw-r--r--benchmark/run.js31
-rw-r--r--benchmark/settimeout.js15
-rw-r--r--benchmark/startup.js26
-rw-r--r--benchmark/static_http_server.js1
-rw-r--r--benchmark/string_creation.js6
-rw-r--r--benchmark/throughput-child.js25
-rw-r--r--benchmark/throughput.js21
-rw-r--r--benchmark/timers.js5
-rw-r--r--benchmark/tls-connect.js86
-rw-r--r--benchmark/tls-fragmentation.js63
-rw-r--r--benchmark/tls/throughput.js74
-rw-r--r--benchmark/tls/tls-connect.js63
-rw-r--r--benchmark/v8_bench.js15
-rw-r--r--common.gypi20
-rwxr-xr-xconfigure224
-rw-r--r--deps/cares/.gitignore15
-rw-r--r--deps/cares/build/gcc_version.py20
-rw-r--r--deps/cares/cares.gyp160
-rw-r--r--deps/cares/common.gypi172
-rw-r--r--deps/cares/config/cygwin/ares_config.h (renamed from deps/uv/src/ares/config_cygwin/ares_config.h)0
-rw-r--r--deps/cares/config/darwin/ares_config.h (renamed from deps/uv/src/ares/config_darwin/ares_config.h)0
-rw-r--r--deps/cares/config/freebsd/ares_config.h (renamed from deps/uv/src/ares/config_freebsd/ares_config.h)0
-rw-r--r--deps/cares/config/linux/ares_config.h (renamed from deps/uv/src/ares/config_linux/ares_config.h)0
-rw-r--r--deps/cares/config/netbsd/ares_config.h (renamed from deps/uv/src/ares/config_netbsd/ares_config.h)0
-rw-r--r--deps/cares/config/openbsd/ares_config.h (renamed from deps/uv/src/ares/config_openbsd/ares_config.h)0
-rw-r--r--deps/cares/config/sunos/ares_config.h (renamed from deps/uv/src/ares/config_sunos/ares_config.h)0
-rw-r--r--deps/cares/config/win32/ares_config.h (renamed from deps/uv/src/ares/config_win32/ares_config.h)0
-rw-r--r--deps/cares/include/ares.h622
-rw-r--r--deps/cares/include/ares_version.h24
-rw-r--r--deps/cares/include/nameser.h (renamed from deps/uv/src/ares/nameser.h)0
-rw-r--r--deps/cares/src/AUTHORS (renamed from deps/uv/src/ares/AUTHORS)0
-rw-r--r--deps/cares/src/CHANGES7
-rw-r--r--deps/cares/src/NEWS (renamed from deps/uv/src/ares/NEWS)0
-rw-r--r--deps/cares/src/README (renamed from deps/uv/src/ares/README)0
-rw-r--r--deps/cares/src/README.cares (renamed from deps/uv/src/ares/README.cares)0
-rw-r--r--deps/cares/src/README.msvc (renamed from deps/uv/src/ares/README.msvc)0
-rw-r--r--deps/cares/src/RELEASE-NOTES16
-rw-r--r--deps/cares/src/TODO (renamed from deps/uv/src/ares/TODO)0
-rw-r--r--deps/cares/src/ares__close_sockets.c (renamed from deps/uv/src/ares/ares__close_sockets.c)0
-rw-r--r--deps/cares/src/ares__get_hostent.c264
-rw-r--r--deps/cares/src/ares__read_line.c (renamed from deps/uv/src/ares/ares__read_line.c)0
-rw-r--r--deps/cares/src/ares__timeval.c (renamed from deps/uv/src/ares/ares__timeval.c)0
-rw-r--r--deps/cares/src/ares_cancel.c (renamed from deps/uv/src/ares/ares_cancel.c)0
-rw-r--r--deps/cares/src/ares_data.c231
-rw-r--r--deps/cares/src/ares_data.h69
-rw-r--r--deps/cares/src/ares_destroy.c107
-rw-r--r--deps/cares/src/ares_dns.h103
-rw-r--r--deps/cares/src/ares_expand_name.c201
-rw-r--r--deps/cares/src/ares_expand_string.c (renamed from deps/uv/src/ares/ares_expand_string.c)0
-rw-r--r--deps/cares/src/ares_fds.c (renamed from deps/uv/src/ares/ares_fds.c)0
-rw-r--r--deps/cares/src/ares_free_hostent.c (renamed from deps/uv/src/ares/ares_free_hostent.c)0
-rw-r--r--deps/cares/src/ares_free_string.c (renamed from deps/uv/src/ares/ares_free_string.c)0
-rw-r--r--deps/cares/src/ares_getenv.c (renamed from deps/uv/src/ares/ares_getenv.c)0
-rw-r--r--deps/cares/src/ares_getenv.h (renamed from deps/uv/src/ares/ares_getenv.h)0
-rw-r--r--deps/cares/src/ares_gethostbyaddr.c (renamed from deps/uv/src/ares/ares_gethostbyaddr.c)0
-rw-r--r--deps/cares/src/ares_gethostbyname.c524
-rw-r--r--deps/cares/src/ares_getnameinfo.c427
-rw-r--r--deps/cares/src/ares_getopt.c (renamed from deps/uv/src/ares/ares_getopt.c)0
-rw-r--r--deps/cares/src/ares_getopt.h (renamed from deps/uv/src/ares/ares_getopt.h)0
-rw-r--r--deps/cares/src/ares_getsock.c (renamed from deps/uv/src/ares/ares_getsock.c)0
-rw-r--r--deps/cares/src/ares_init.c2021
-rw-r--r--deps/cares/src/ares_iphlpapi.h (renamed from deps/uv/src/ares/ares_iphlpapi.h)0
-rw-r--r--deps/cares/src/ares_ipv6.h (renamed from deps/uv/src/ares/ares_ipv6.h)0
-rw-r--r--deps/cares/src/ares_library_init.c (renamed from deps/uv/src/ares/ares_library_init.c)0
-rw-r--r--deps/cares/src/ares_library_init.h42
-rw-r--r--deps/cares/src/ares_llist.c (renamed from deps/uv/src/ares/ares_llist.c)0
-rw-r--r--deps/cares/src/ares_llist.h (renamed from deps/uv/src/ares/ares_llist.h)0
-rw-r--r--deps/cares/src/ares_mkquery.c (renamed from deps/uv/src/ares/ares_mkquery.c)0
-rw-r--r--deps/cares/src/ares_nowarn.c249
-rw-r--r--deps/cares/src/ares_nowarn.h61
-rw-r--r--deps/cares/src/ares_options.c (renamed from deps/uv/src/ares/ares_options.c)0
-rw-r--r--deps/cares/src/ares_parse_a_reply.c (renamed from deps/uv/src/ares/ares_parse_a_reply.c)0
-rw-r--r--deps/cares/src/ares_parse_aaaa_reply.c261
-rw-r--r--deps/cares/src/ares_parse_mx_reply.c (renamed from deps/uv/src/ares/ares_parse_mx_reply.c)0
-rw-r--r--deps/cares/src/ares_parse_naptr_reply.c188
-rw-r--r--deps/cares/src/ares_parse_ns_reply.c (renamed from deps/uv/src/ares/ares_parse_ns_reply.c)0
-rw-r--r--deps/cares/src/ares_parse_ptr_reply.c218
-rw-r--r--deps/cares/src/ares_parse_soa_reply.c135
-rw-r--r--deps/cares/src/ares_parse_srv_reply.c (renamed from deps/uv/src/ares/ares_parse_srv_reply.c)0
-rw-r--r--deps/cares/src/ares_parse_txt_reply.c (renamed from deps/uv/src/ares/ares_parse_txt_reply.c)0
-rw-r--r--deps/cares/src/ares_platform.c (renamed from deps/uv/src/ares/ares_platform.c)0
-rw-r--r--deps/cares/src/ares_platform.h (renamed from deps/uv/src/ares/ares_platform.h)0
-rw-r--r--deps/cares/src/ares_private.h355
-rw-r--r--deps/cares/src/ares_process.c1294
-rw-r--r--deps/cares/src/ares_query.c (renamed from deps/uv/src/ares/ares_query.c)0
-rw-r--r--deps/cares/src/ares_rules.h (renamed from deps/uv/src/ares/ares_rules.h)0
-rw-r--r--deps/cares/src/ares_search.c (renamed from deps/uv/src/ares/ares_search.c)0
-rw-r--r--deps/cares/src/ares_send.c134
-rw-r--r--deps/cares/src/ares_setup.h221
-rw-r--r--deps/cares/src/ares_strcasecmp.c (renamed from deps/uv/src/ares/ares_strcasecmp.c)0
-rw-r--r--deps/cares/src/ares_strcasecmp.h (renamed from deps/uv/src/ares/ares_strcasecmp.h)0
-rw-r--r--deps/cares/src/ares_strdup.c (renamed from deps/uv/src/ares/ares_strdup.c)0
-rw-r--r--deps/cares/src/ares_strdup.h (renamed from deps/uv/src/ares/ares_strdup.h)0
-rw-r--r--deps/cares/src/ares_strerror.c (renamed from deps/uv/src/ares/ares_strerror.c)0
-rw-r--r--deps/cares/src/ares_timeout.c81
-rw-r--r--deps/cares/src/ares_version.c (renamed from deps/uv/src/ares/ares_version.c)0
-rw-r--r--deps/cares/src/ares_writev.c (renamed from deps/uv/src/ares/ares_writev.c)0
-rw-r--r--deps/cares/src/ares_writev.h (renamed from deps/uv/src/ares/ares_writev.h)0
-rw-r--r--deps/cares/src/bitncmp.c (renamed from deps/uv/src/ares/bitncmp.c)0
-rw-r--r--deps/cares/src/bitncmp.h (renamed from deps/uv/src/ares/bitncmp.h)0
-rw-r--r--deps/cares/src/get_ver.awk (renamed from deps/uv/src/ares/get_ver.awk)0
-rw-r--r--deps/cares/src/inet_net_pton.c (renamed from deps/uv/src/ares/inet_net_pton.c)0
-rw-r--r--deps/cares/src/inet_net_pton.h (renamed from deps/uv/src/ares/inet_net_pton.h)0
-rw-r--r--deps/cares/src/inet_ntop.c (renamed from deps/uv/src/ares/inet_ntop.c)0
-rw-r--r--deps/cares/src/inet_ntop.h (renamed from deps/uv/src/ares/inet_ntop.h)0
-rw-r--r--deps/cares/src/setup_once.h512
-rw-r--r--deps/cares/src/windows_port.c (renamed from deps/uv/src/ares/windows_port.c)0
-rw-r--r--deps/http_parser/.gitignore3
-rw-r--r--deps/http_parser/.mailmap1
-rw-r--r--deps/http_parser/AUTHORS5
-rw-r--r--deps/http_parser/Makefile8
-rw-r--r--deps/http_parser/http_parser.c372
-rw-r--r--deps/http_parser/http_parser.h13
-rw-r--r--deps/http_parser/test.c1422
-rw-r--r--deps/http_parser/url_parser.c44
-rw-r--r--deps/npm/html/api/bin.html2
-rw-r--r--deps/npm/html/api/bugs.html2
-rw-r--r--deps/npm/html/api/commands.html2
-rw-r--r--deps/npm/html/api/config.html2
-rw-r--r--deps/npm/html/api/deprecate.html2
-rw-r--r--deps/npm/html/api/docs.html2
-rw-r--r--deps/npm/html/api/edit.html2
-rw-r--r--deps/npm/html/api/explore.html2
-rw-r--r--deps/npm/html/api/help-search.html2
-rw-r--r--deps/npm/html/api/init.html2
-rw-r--r--deps/npm/html/api/install.html2
-rw-r--r--deps/npm/html/api/link.html2
-rw-r--r--deps/npm/html/api/load.html2
-rw-r--r--deps/npm/html/api/ls.html2
-rw-r--r--deps/npm/html/api/npm.html4
-rw-r--r--deps/npm/html/api/outdated.html2
-rw-r--r--deps/npm/html/api/owner.html2
-rw-r--r--deps/npm/html/api/pack.html2
-rw-r--r--deps/npm/html/api/prefix.html2
-rw-r--r--deps/npm/html/api/prune.html2
-rw-r--r--deps/npm/html/api/publish.html2
-rw-r--r--deps/npm/html/api/rebuild.html2
-rw-r--r--deps/npm/html/api/restart.html2
-rw-r--r--deps/npm/html/api/root.html2
-rw-r--r--deps/npm/html/api/run-script.html2
-rw-r--r--deps/npm/html/api/search.html2
-rw-r--r--deps/npm/html/api/shrinkwrap.html2
-rw-r--r--deps/npm/html/api/start.html2
-rw-r--r--deps/npm/html/api/stop.html2
-rw-r--r--deps/npm/html/api/submodule.html2
-rw-r--r--deps/npm/html/api/tag.html2
-rw-r--r--deps/npm/html/api/test.html2
-rw-r--r--deps/npm/html/api/uninstall.html2
-rw-r--r--deps/npm/html/api/unpublish.html2
-rw-r--r--deps/npm/html/api/update.html2
-rw-r--r--deps/npm/html/api/version.html2
-rw-r--r--deps/npm/html/api/view.html2
-rw-r--r--deps/npm/html/api/whoami.html2
-rw-r--r--deps/npm/html/doc/README.html2
-rw-r--r--deps/npm/html/doc/adduser.html2
-rw-r--r--deps/npm/html/doc/bin.html2
-rw-r--r--deps/npm/html/doc/bugs.html2
-rw-r--r--deps/npm/html/doc/build.html2
-rw-r--r--deps/npm/html/doc/bundle.html2
-rw-r--r--deps/npm/html/doc/cache.html2
-rw-r--r--deps/npm/html/doc/changelog.html2
-rw-r--r--deps/npm/html/doc/coding-style.html2
-rw-r--r--deps/npm/html/doc/completion.html2
-rw-r--r--deps/npm/html/doc/config.html2
-rw-r--r--deps/npm/html/doc/dedupe.html2
-rw-r--r--deps/npm/html/doc/deprecate.html2
-rw-r--r--deps/npm/html/doc/developers.html2
-rw-r--r--deps/npm/html/doc/disputes.html2
-rw-r--r--deps/npm/html/doc/docs.html2
-rw-r--r--deps/npm/html/doc/edit.html2
-rw-r--r--deps/npm/html/doc/explore.html2
-rw-r--r--deps/npm/html/doc/faq.html2
-rw-r--r--deps/npm/html/doc/folders.html2
-rw-r--r--deps/npm/html/doc/global.html2
-rw-r--r--deps/npm/html/doc/help-search.html2
-rw-r--r--deps/npm/html/doc/help.html2
-rw-r--r--deps/npm/html/doc/index.html2
-rw-r--r--deps/npm/html/doc/init.html2
-rw-r--r--deps/npm/html/doc/install.html2
-rw-r--r--deps/npm/html/doc/json.html2
-rw-r--r--deps/npm/html/doc/link.html2
-rw-r--r--deps/npm/html/doc/ls.html4
-rw-r--r--deps/npm/html/doc/npm.html4
-rw-r--r--deps/npm/html/doc/outdated.html2
-rw-r--r--deps/npm/html/doc/owner.html2
-rw-r--r--deps/npm/html/doc/pack.html2
-rw-r--r--deps/npm/html/doc/prefix.html2
-rw-r--r--deps/npm/html/doc/prune.html2
-rw-r--r--deps/npm/html/doc/publish.html2
-rw-r--r--deps/npm/html/doc/rebuild.html2
-rw-r--r--deps/npm/html/doc/registry.html2
-rw-r--r--deps/npm/html/doc/removing-npm.html2
-rw-r--r--deps/npm/html/doc/restart.html2
-rw-r--r--deps/npm/html/doc/rm.html2
-rw-r--r--deps/npm/html/doc/root.html2
-rw-r--r--deps/npm/html/doc/run-script.html2
-rw-r--r--deps/npm/html/doc/scripts.html2
-rw-r--r--deps/npm/html/doc/search.html2
-rw-r--r--deps/npm/html/doc/semver.html2
-rw-r--r--deps/npm/html/doc/shrinkwrap.html2
-rw-r--r--deps/npm/html/doc/star.html2
-rw-r--r--deps/npm/html/doc/stars.html2
-rw-r--r--deps/npm/html/doc/start.html2
-rw-r--r--deps/npm/html/doc/stop.html2
-rw-r--r--deps/npm/html/doc/submodule.html2
-rw-r--r--deps/npm/html/doc/tag.html2
-rw-r--r--deps/npm/html/doc/test.html2
-rw-r--r--deps/npm/html/doc/uninstall.html2
-rw-r--r--deps/npm/html/doc/unpublish.html2
-rw-r--r--deps/npm/html/doc/update.html2
-rw-r--r--deps/npm/html/doc/version.html2
-rw-r--r--deps/npm/html/doc/view.html2
-rw-r--r--deps/npm/html/doc/whoami.html2
-rw-r--r--deps/npm/lib/cache.js2
-rw-r--r--deps/npm/man/man1/ls.12
-rw-r--r--deps/npm/man/man1/npm.12
-rw-r--r--deps/npm/man/man3/npm.32
-rw-r--r--deps/npm/node_modules/npm-registry-client/lib/publish.js42
-rw-r--r--deps/npm/node_modules/npm-registry-client/package.json10
-rw-r--r--deps/npm/package.json2
-rw-r--r--deps/openssl/README.chromium96
-rw-r--r--deps/openssl/asm/Makefile30
-rw-r--r--deps/openssl/asm/x64-elf-gas/aes/aes-x86_64.s25
-rw-r--r--deps/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s1402
-rw-r--r--deps/openssl/asm/x64-elf-gas/aes/aesni-x86_64.s2558
-rw-r--r--deps/openssl/asm/x64-elf-gas/bn/modexp512-x86_64.s1776
-rw-r--r--deps/openssl/asm/x64-elf-gas/bn/x86_64-mont.s1311
-rw-r--r--deps/openssl/asm/x64-elf-gas/rc4/rc4-md5-x86_64.s1260
-rw-r--r--deps/openssl/asm/x64-elf-gas/rc4/rc4-x86_64.s734
-rw-r--r--deps/openssl/asm/x64-elf-gas/sha/sha1-x86_64.s3531
-rw-r--r--deps/openssl/asm/x64-elf-gas/sha/sha512-x86_64.s2144
-rw-r--r--deps/openssl/asm/x64-elf-gas/x86_64cpuid.s70
-rw-r--r--deps/openssl/asm/x64-macosx-gas/aes/aes-x86_64.s17
-rw-r--r--deps/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s1402
-rw-r--r--deps/openssl/asm/x64-macosx-gas/aes/aesni-x86_64.s2558
-rw-r--r--deps/openssl/asm/x64-macosx-gas/bn/modexp512-x86_64.s1775
-rw-r--r--deps/openssl/asm/x64-macosx-gas/bn/x86_64-mont.s1309
-rw-r--r--deps/openssl/asm/x64-macosx-gas/md5/md5-x86_64.s1
-rw-r--r--deps/openssl/asm/x64-macosx-gas/rc4/rc4-md5-x86_64.s1259
-rw-r--r--deps/openssl/asm/x64-macosx-gas/rc4/rc4-x86_64.s731
-rw-r--r--deps/openssl/asm/x64-macosx-gas/sha/sha1-x86_64.s3529
-rw-r--r--deps/openssl/asm/x64-macosx-gas/sha/sha512-x86_64.s2144
-rw-r--r--deps/openssl/asm/x64-macosx-gas/x86_64cpuid.s69
-rw-r--r--deps/openssl/asm/x64-win32-masm/aes/aes-x86_64.asm45
-rw-r--r--deps/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm1554
-rw-r--r--deps/openssl/asm/x64-win32-masm/aes/aesni-x86_64.asm3062
-rw-r--r--deps/openssl/asm/x64-win32-masm/bn/modexp512-x86_64.asm1890
-rw-r--r--deps/openssl/asm/x64-win32-masm/bn/x86_64-mont.asm1428
-rw-r--r--deps/openssl/asm/x64-win32-masm/camellia/cmll-x86_64.asm4
-rw-r--r--deps/openssl/asm/x64-win32-masm/md5/md5-x86_64.asm280
-rw-r--r--deps/openssl/asm/x64-win32-masm/rc4/rc4-md5-x86_64.asm1375
-rw-r--r--deps/openssl/asm/x64-win32-masm/rc4/rc4-x86_64.asm744
-rw-r--r--deps/openssl/asm/x64-win32-masm/sha/sha1-x86_64.asm3624
-rw-r--r--deps/openssl/asm/x64-win32-masm/sha/sha512-x86_64.asm2248
-rw-r--r--deps/openssl/asm/x64-win32-masm/whrlpool/wp-x86_64.asm204
-rw-r--r--deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm72
-rw-r--r--deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm.orig235
-rw-r--r--deps/openssl/asm/x86-elf-gas/aes/aes-586.s22
-rw-r--r--deps/openssl/asm/x86-elf-gas/aes/aesni-x86.s2143
-rw-r--r--deps/openssl/asm/x86-elf-gas/camellia/cmll-x86.s10
-rw-r--r--deps/openssl/asm/x86-elf-gas/rc4/rc4-586.s218
-rw-r--r--deps/openssl/asm/x86-elf-gas/sha/sha1-586.s1262
-rw-r--r--deps/openssl/asm/x86-elf-gas/sha/sha256-586.s65
-rw-r--r--deps/openssl/asm/x86-elf-gas/x86cpuid.s135
-rw-r--r--deps/openssl/asm/x86-macosx-gas/aes/aes-586.s24
-rw-r--r--deps/openssl/asm/x86-macosx-gas/aes/aesni-x86.s2107
-rw-r--r--deps/openssl/asm/x86-macosx-gas/camellia/cmll-x86.s6
-rw-r--r--deps/openssl/asm/x86-macosx-gas/des/crypt586.s13
-rw-r--r--deps/openssl/asm/x86-macosx-gas/rc4/rc4-586.s231
-rw-r--r--deps/openssl/asm/x86-macosx-gas/sha/sha1-586.s1262
-rw-r--r--deps/openssl/asm/x86-macosx-gas/sha/sha256-586.s65
-rw-r--r--deps/openssl/asm/x86-macosx-gas/x86cpuid.s149
-rw-r--r--deps/openssl/asm/x86-win32-masm/aes/aes-586.asm14
-rw-r--r--deps/openssl/asm/x86-win32-masm/aes/aesni-x86.asm2133
-rw-r--r--deps/openssl/asm/x86-win32-masm/bf/bf-686.asm2
-rw-r--r--deps/openssl/asm/x86-win32-masm/bn/x86-mont.asm2
-rw-r--r--deps/openssl/asm/x86-win32-masm/bn/x86.asm2
-rw-r--r--deps/openssl/asm/x86-win32-masm/camellia/cmll-x86.asm8
-rw-r--r--deps/openssl/asm/x86-win32-masm/cast/cast-586.asm2
-rw-r--r--deps/openssl/asm/x86-win32-masm/des/crypt586.asm2
-rw-r--r--deps/openssl/asm/x86-win32-masm/des/des-586.asm2
-rw-r--r--deps/openssl/asm/x86-win32-masm/md5/md5-586.asm2
-rw-r--r--deps/openssl/asm/x86-win32-masm/rc4/rc4-586.asm225
-rw-r--r--deps/openssl/asm/x86-win32-masm/rc5/rc5-586.asm2
-rw-r--r--deps/openssl/asm/x86-win32-masm/ripemd/rmd-586.asm2
-rw-r--r--deps/openssl/asm/x86-win32-masm/sha/sha1-586.asm1264
-rw-r--r--deps/openssl/asm/x86-win32-masm/sha/sha256-586.asm67
-rw-r--r--deps/openssl/asm/x86-win32-masm/sha/sha512-586.asm2
-rw-r--r--deps/openssl/asm/x86-win32-masm/x86cpuid.asm132
-rw-r--r--deps/openssl/config/android/openssl/opensslconf.h253
-rw-r--r--deps/openssl/config/k8/openssl/opensslconf-posix.h273
-rw-r--r--deps/openssl/config/k8/openssl/opensslconf-win32.h262
-rw-r--r--deps/openssl/config/k8/openssl/opensslconf.h5
-rw-r--r--deps/openssl/config/opensslconf.h333
-rw-r--r--deps/openssl/config/piii/openssl/opensslconf-posix.h273
-rw-r--r--deps/openssl/config/piii/openssl/opensslconf-win32.h274
-rw-r--r--deps/openssl/config/piii/openssl/opensslconf.h5
-rw-r--r--deps/openssl/openssl.gyp134
-rw-r--r--deps/openssl/openssl/CHANGES473
-rwxr-xr-xdeps/openssl/openssl/Configure255
-rw-r--r--deps/openssl/openssl/FAQ24
-rw-r--r--deps/openssl/openssl/INSTALL.W324
-rw-r--r--deps/openssl/openssl/Makefile77
-rw-r--r--deps/openssl/openssl/Makefile.org69
-rw-r--r--deps/openssl/openssl/NEWS52
-rw-r--r--deps/openssl/openssl/PROBLEMS14
-rw-r--r--deps/openssl/openssl/README4
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/VMS/install-vms.com0
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/VMS/openssl_startup.com0
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/VMS/openssl_undo.com0
-rw-r--r--deps/openssl/openssl/apps/CA.com236
-rw-r--r--deps/openssl/openssl/apps/CA.pl189
-rw-r--r--deps/openssl/openssl/apps/CA.pl.in189
-rw-r--r--deps/openssl/openssl/apps/CA.sh198
-rw-r--r--deps/openssl/openssl/apps/Makefile1055
-rw-r--r--deps/openssl/openssl/apps/app_rand.c218
-rw-r--r--deps/openssl/openssl/apps/apps.c3094
-rw-r--r--deps/openssl/openssl/apps/apps.h373
-rw-r--r--deps/openssl/openssl/apps/asn1pars.c445
-rw-r--r--deps/openssl/openssl/apps/ca-cert.srl1
-rw-r--r--deps/openssl/openssl/apps/ca-key.pem15
-rw-r--r--deps/openssl/openssl/apps/ca-req.pem11
-rw-r--r--deps/openssl/openssl/apps/ca.c3010
-rw-r--r--deps/openssl/openssl/apps/cert.pem11
-rw-r--r--deps/openssl/openssl/apps/ciphers.c231
-rw-r--r--deps/openssl/openssl/apps/client.pem52
-rw-r--r--deps/openssl/openssl/apps/cms.c1397
-rw-r--r--deps/openssl/openssl/apps/crl.c446
-rw-r--r--deps/openssl/openssl/apps/crl2p7.c337
-rw-r--r--deps/openssl/openssl/apps/demoCA/cacert.pem14
-rw-r--r--deps/openssl/openssl/apps/demoCA/index.txt39
-rw-r--r--deps/openssl/openssl/apps/demoCA/private/cakey.pem24
-rw-r--r--deps/openssl/openssl/apps/demoCA/serial1
-rw-r--r--deps/openssl/openssl/apps/demoSRP/srp_verifier.txt6
-rw-r--r--deps/openssl/openssl/apps/demoSRP/srp_verifier.txt.attr1
-rw-r--r--deps/openssl/openssl/apps/dgst.c644
-rw-r--r--deps/openssl/openssl/apps/dh.c355
-rw-r--r--deps/openssl/openssl/apps/dh1024.pem10
-rw-r--r--deps/openssl/openssl/apps/dh2048.pem12
-rw-r--r--deps/openssl/openssl/apps/dh4096.pem18
-rw-r--r--deps/openssl/openssl/apps/dh512.pem9
-rw-r--r--deps/openssl/openssl/apps/dhparam.c559
-rw-r--r--deps/openssl/openssl/apps/dsa-ca.pem40
-rw-r--r--deps/openssl/openssl/apps/dsa-pca.pem46
-rw-r--r--deps/openssl/openssl/apps/dsa.c376
-rw-r--r--deps/openssl/openssl/apps/dsa1024.pem9
-rw-r--r--deps/openssl/openssl/apps/dsa512.pem6
-rw-r--r--deps/openssl/openssl/apps/dsap.pem6
-rw-r--r--deps/openssl/openssl/apps/dsaparam.c486
-rw-r--r--deps/openssl/openssl/apps/ec.c406
-rw-r--r--deps/openssl/openssl/apps/ecparam.c731
-rw-r--r--deps/openssl/openssl/apps/enc.c732
-rw-r--r--deps/openssl/openssl/apps/engine.c549
-rw-r--r--deps/openssl/openssl/apps/errstr.c128
-rw-r--r--deps/openssl/openssl/apps/gendh.c241
-rw-r--r--deps/openssl/openssl/apps/gendsa.c285
-rw-r--r--deps/openssl/openssl/apps/genpkey.c440
-rw-r--r--deps/openssl/openssl/apps/genrsa.c335
-rwxr-xr-xdeps/openssl/openssl/apps/install-apps.com107
-rw-r--r--deps/openssl/openssl/apps/makeapps.com1169
-rw-r--r--deps/openssl/openssl/apps/md4.c127
-rw-r--r--deps/openssl/openssl/apps/nseq.c167
-rw-r--r--deps/openssl/openssl/apps/ocsp.c1421
-rw-r--r--deps/openssl/openssl/apps/oid.cnf6
-rw-r--r--deps/openssl/openssl/apps/openssl-vms.cnf350
-rw-r--r--deps/openssl/openssl/apps/openssl.c728
-rw-r--r--deps/openssl/openssl/apps/openssl.cnf350
-rw-r--r--deps/openssl/openssl/apps/passwd.c512
-rw-r--r--deps/openssl/openssl/apps/pca-cert.srl1
-rw-r--r--deps/openssl/openssl/apps/pca-key.pem15
-rw-r--r--deps/openssl/openssl/apps/pca-req.pem11
-rw-r--r--deps/openssl/openssl/apps/pkcs12.c977
-rw-r--r--deps/openssl/openssl/apps/pkcs7.c320
-rw-r--r--deps/openssl/openssl/apps/pkcs8.c439
-rw-r--r--deps/openssl/openssl/apps/pkey.c284
-rw-r--r--deps/openssl/openssl/apps/pkeyparam.c200
-rw-r--r--deps/openssl/openssl/apps/pkeyutl.c570
-rw-r--r--deps/openssl/openssl/apps/prime.c160
-rw-r--r--deps/openssl/openssl/apps/privkey.pem18
-rw-r--r--deps/openssl/openssl/apps/progs.h366
-rw-r--r--deps/openssl/openssl/apps/progs.pl104
-rw-r--r--deps/openssl/openssl/apps/rand.c245
-rw-r--r--deps/openssl/openssl/apps/req.c1836
-rw-r--r--deps/openssl/openssl/apps/req.pem11
-rw-r--r--deps/openssl/openssl/apps/rsa.c450
-rw-r--r--deps/openssl/openssl/apps/rsa8192.pem101
-rw-r--r--deps/openssl/openssl/apps/rsautl.c351
-rw-r--r--deps/openssl/openssl/apps/s1024key.pem15
-rw-r--r--deps/openssl/openssl/apps/s1024req.pem11
-rw-r--r--deps/openssl/openssl/apps/s512-key.pem9
-rw-r--r--deps/openssl/openssl/apps/s512-req.pem8
-rw-r--r--deps/openssl/openssl/apps/s_apps.h176
-rw-r--r--deps/openssl/openssl/apps/s_cb.c930
-rw-r--r--deps/openssl/openssl/apps/s_client.c2151
-rw-r--r--deps/openssl/openssl/apps/s_server.c3011
-rw-r--r--deps/openssl/openssl/apps/s_socket.c619
-rw-r--r--deps/openssl/openssl/apps/s_time.c632
-rw-r--r--deps/openssl/openssl/apps/server.pem52
-rw-r--r--deps/openssl/openssl/apps/server.srl1
-rw-r--r--deps/openssl/openssl/apps/server2.pem52
-rw-r--r--deps/openssl/openssl/apps/sess_id.c322
-rw-r--r--deps/openssl/openssl/apps/set/set-g-ca.pem21
-rw-r--r--deps/openssl/openssl/apps/set/set-m-ca.pem21
-rw-r--r--deps/openssl/openssl/apps/set/set_b_ca.pem23
-rw-r--r--deps/openssl/openssl/apps/set/set_c_ca.pem21
-rw-r--r--deps/openssl/openssl/apps/set/set_d_ct.pem21
-rw-r--r--deps/openssl/openssl/apps/set/set_root.pem21
-rw-r--r--deps/openssl/openssl/apps/smime.c857
-rw-r--r--deps/openssl/openssl/apps/speed.c2842
-rw-r--r--deps/openssl/openssl/apps/spkac.c308
-rw-r--r--deps/openssl/openssl/apps/srp.c756
-rw-r--r--deps/openssl/openssl/apps/testCA.pem8
-rw-r--r--deps/openssl/openssl/apps/testdsa.h217
-rw-r--r--deps/openssl/openssl/apps/testrsa.h518
-rw-r--r--deps/openssl/openssl/apps/timeouts.h67
-rw-r--r--deps/openssl/openssl/apps/ts.c1147
-rw-r--r--deps/openssl/openssl/apps/tsget196
-rw-r--r--deps/openssl/openssl/apps/verify.c362
-rw-r--r--deps/openssl/openssl/apps/version.c217
-rwxr-xr-xdeps/openssl/openssl/apps/vms_decc_init.c188
-rw-r--r--deps/openssl/openssl/apps/winrand.c148
-rw-r--r--deps/openssl/openssl/apps/x509.c1310
-rwxr-xr-xdeps/openssl/openssl/config102
-rw-r--r--deps/openssl/openssl/crypto/Makefile34
-rw-r--r--deps/openssl/openssl/crypto/aes/Makefile29
-rw-r--r--deps/openssl/openssl/crypto/aes/aes.h5
-rw-r--r--deps/openssl/openssl/crypto/aes/aes_core.c12
-rw-r--r--deps/openssl/openssl/crypto/aes/aes_misc.c21
-rwxr-xr-xdeps/openssl/openssl/crypto/aes/asm/aes-586.pl14
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/aes-armv4.pl182
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/aes-mips.pl1611
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/aes-parisc.pl1021
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/aes-ppc.pl444
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/aes-s390x.pl1054
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/crypto/aes/asm/aes-sparcv9.pl3
-rwxr-xr-xdeps/openssl/openssl/crypto/aes/asm/aes-x86_64.pl48
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl1250
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/aesni-x86.pl2189
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/aesni-x86_64.pl3069
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/bsaes-x86_64.pl3045
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/vpaes-x86.pl903
-rw-r--r--deps/openssl/openssl/crypto/aes/asm/vpaes-x86_64.pl1207
-rw-r--r--deps/openssl/openssl/crypto/arm_arch.h51
-rw-r--r--deps/openssl/openssl/crypto/armcap.c80
-rw-r--r--deps/openssl/openssl/crypto/armv4cpuid.S154
-rw-r--r--deps/openssl/openssl/crypto/asn1/Makefile2
-rw-r--r--deps/openssl/openssl/crypto/asn1/a_digest.c6
-rw-r--r--deps/openssl/openssl/crypto/asn1/a_int.c4
-rw-r--r--deps/openssl/openssl/crypto/asn1/a_sign.c111
-rw-r--r--deps/openssl/openssl/crypto/asn1/a_strex.c1
-rw-r--r--deps/openssl/openssl/crypto/asn1/a_verify.c83
-rw-r--r--deps/openssl/openssl/crypto/asn1/ameth_lib.c12
-rw-r--r--deps/openssl/openssl/crypto/asn1/asn1.h8
-rw-r--r--deps/openssl/openssl/crypto/asn1/asn1_err.c5
-rw-r--r--deps/openssl/openssl/crypto/asn1/asn1_locl.h11
-rw-r--r--deps/openssl/openssl/crypto/asn1/asn_mime.c23
-rw-r--r--deps/openssl/openssl/crypto/asn1/n_pkey.c38
-rw-r--r--deps/openssl/openssl/crypto/asn1/p5_pbev2.c143
-rw-r--r--deps/openssl/openssl/crypto/asn1/t_crl.c3
-rw-r--r--deps/openssl/openssl/crypto/asn1/t_x509.c55
-rw-r--r--deps/openssl/openssl/crypto/asn1/tasn_prn.c12
-rw-r--r--deps/openssl/openssl/crypto/asn1/x_algor.c14
-rw-r--r--deps/openssl/openssl/crypto/asn1/x_name.c3
-rw-r--r--deps/openssl/openssl/crypto/asn1/x_pubkey.c14
-rw-r--r--deps/openssl/openssl/crypto/bf/Makefile7
-rw-r--r--deps/openssl/openssl/crypto/bf/bf_skey.c8
-rw-r--r--deps/openssl/openssl/crypto/bf/blowfish.h4
-rw-r--r--deps/openssl/openssl/crypto/bio/bio.h70
-rw-r--r--deps/openssl/openssl/crypto/bio/bio_err.c3
-rw-r--r--deps/openssl/openssl/crypto/bio/bio_lib.c28
-rw-r--r--deps/openssl/openssl/crypto/bio/bss_bio.c18
-rw-r--r--deps/openssl/openssl/crypto/bio/bss_dgram.c1073
-rw-r--r--deps/openssl/openssl/crypto/bn/Makefile34
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/armv4-gf2m.pl278
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/armv4-mont.pl23
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/ia64-mont.pl851
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/mips-mont.pl426
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/mips.pl2585
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/modexp512-x86_64.pl1497
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/parisc-mont.pl993
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/ppc-mont.pl107
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/ppc.pl43
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/ppc64-mont.pl338
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/s390x-gf2m.pl221
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/s390x-mont.pl102
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/crypto/bn/asm/s390x.S0
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/crypto/bn/asm/sparcv9a-mont.pl0
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/x86-gf2m.pl313
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/crypto/bn/asm/x86-mont.pl0
-rw-r--r--deps/openssl/openssl/crypto/bn/asm/x86_64-gf2m.pl389
-rwxr-xr-xdeps/openssl/openssl/crypto/bn/asm/x86_64-mont.pl1489
-rwxr-xr-xdeps/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl1071
-rw-r--r--deps/openssl/openssl/crypto/bn/bn.h15
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_div.c274
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_exp.c240
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_gcd.c1
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_gf2m.c114
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_lcl.h30
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_lib.c19
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_mont.c116
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_nist.c338
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_print.c19
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_shift.c27
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_word.c25
-rw-r--r--deps/openssl/openssl/crypto/bn/bn_x931p.c272
-rw-r--r--deps/openssl/openssl/crypto/bn/bntest.c8
-rw-r--r--deps/openssl/openssl/crypto/buffer/Makefile11
-rw-r--r--deps/openssl/openssl/crypto/buffer/buf_str.c119
-rw-r--r--deps/openssl/openssl/crypto/buffer/buffer.c58
-rw-r--r--deps/openssl/openssl/crypto/camellia/Makefile17
-rw-r--r--deps/openssl/openssl/crypto/camellia/asm/cmll-x86.pl6
-rw-r--r--deps/openssl/openssl/crypto/camellia/asm/cmll-x86_64.pl3
-rw-r--r--deps/openssl/openssl/crypto/camellia/camellia.h4
-rw-r--r--deps/openssl/openssl/crypto/camellia/cmll_locl.h5
-rw-r--r--deps/openssl/openssl/crypto/camellia/cmll_misc.c3
-rw-r--r--deps/openssl/openssl/crypto/camellia/cmll_utl.c64
-rw-r--r--deps/openssl/openssl/crypto/cast/Makefile5
-rw-r--r--deps/openssl/openssl/crypto/cast/c_skey.c9
-rw-r--r--deps/openssl/openssl/crypto/cast/cast.h4
-rw-r--r--deps/openssl/openssl/crypto/cmac/Makefile111
-rw-r--r--deps/openssl/openssl/crypto/cmac/cm_ameth.c97
-rw-r--r--deps/openssl/openssl/crypto/cmac/cm_pmeth.c224
-rw-r--r--deps/openssl/openssl/crypto/cmac/cmac.c308
-rw-r--r--deps/openssl/openssl/crypto/cmac/cmac.h82
-rw-r--r--deps/openssl/openssl/crypto/cms/Makefile24
-rw-r--r--deps/openssl/openssl/crypto/cms/cms.h22
-rw-r--r--deps/openssl/openssl/crypto/cms/cms_asn1.c9
-rw-r--r--deps/openssl/openssl/crypto/cms/cms_cd.c2
-rw-r--r--deps/openssl/openssl/crypto/cms/cms_enc.c60
-rw-r--r--deps/openssl/openssl/crypto/cms/cms_env.c22
-rw-r--r--deps/openssl/openssl/crypto/cms/cms_err.c13
-rw-r--r--deps/openssl/openssl/crypto/cms/cms_lcl.h12
-rw-r--r--deps/openssl/openssl/crypto/cms/cms_lib.c5
-rw-r--r--deps/openssl/openssl/crypto/cms/cms_pwri.c454
-rw-r--r--deps/openssl/openssl/crypto/cms/cms_sd.c3
-rw-r--r--deps/openssl/openssl/crypto/cms/cms_smime.c61
-rw-r--r--deps/openssl/openssl/crypto/comp/c_rle.c4
-rw-r--r--deps/openssl/openssl/crypto/conf/conf_mall.c1
-rw-r--r--deps/openssl/openssl/crypto/cpt_err.c4
-rw-r--r--deps/openssl/openssl/crypto/cryptlib.c56
-rw-r--r--deps/openssl/openssl/crypto/cryptlib.h4
-rw-r--r--deps/openssl/openssl/crypto/crypto-lib.com39
-rw-r--r--deps/openssl/openssl/crypto/crypto.h40
-rw-r--r--deps/openssl/openssl/crypto/des/Makefile5
-rw-r--r--deps/openssl/openssl/crypto/des/des.h3
-rw-r--r--deps/openssl/openssl/crypto/des/set_key.c8
-rw-r--r--deps/openssl/openssl/crypto/des/str2key.c2
-rw-r--r--deps/openssl/openssl/crypto/dh/dh.h20
-rw-r--r--deps/openssl/openssl/crypto/dh/dh_ameth.c1
-rw-r--r--deps/openssl/openssl/crypto/dh/dh_err.c7
-rw-r--r--deps/openssl/openssl/crypto/dh/dh_gen.c17
-rw-r--r--deps/openssl/openssl/crypto/dh/dh_key.c33
-rw-r--r--deps/openssl/openssl/crypto/dh/dh_lib.c15
-rw-r--r--deps/openssl/openssl/crypto/dsa/Makefile7
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa.h20
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_ameth.c47
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_asn1.c40
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_err.c7
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_gen.c35
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_key.c16
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_lib.c22
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_locl.h1
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_ossl.c16
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_pmeth.c6
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_sign.c50
-rw-r--r--deps/openssl/openssl/crypto/dsa/dsa_vrf.c29
-rw-r--r--deps/openssl/openssl/crypto/dso/dso_dlfcn.c3
-rw-r--r--deps/openssl/openssl/crypto/ec/Makefile36
-rw-r--r--deps/openssl/openssl/crypto/ec/ec.h97
-rw-r--r--deps/openssl/openssl/crypto/ec/ec2_mult.c4
-rw-r--r--deps/openssl/openssl/crypto/ec/ec2_oct.c407
-rw-r--r--deps/openssl/openssl/crypto/ec/ec2_smpl.c351
-rw-r--r--deps/openssl/openssl/crypto/ec/ec_ameth.c1
-rw-r--r--deps/openssl/openssl/crypto/ec/ec_asn1.c24
-rw-r--r--deps/openssl/openssl/crypto/ec/ec_curve.c197
-rw-r--r--deps/openssl/openssl/crypto/ec/ec_cvt.c28
-rw-r--r--deps/openssl/openssl/crypto/ec/ec_err.c20
-rw-r--r--deps/openssl/openssl/crypto/ec/ec_key.c115
-rw-r--r--deps/openssl/openssl/crypto/ec/ec_lcl.h55
-rw-r--r--deps/openssl/openssl/crypto/ec/ec_lib.c80
-rw-r--r--deps/openssl/openssl/crypto/ec/ec_oct.c199
-rw-r--r--deps/openssl/openssl/crypto/ec/ec_pmeth.c3
-rw-r--r--deps/openssl/openssl/crypto/ec/eck_prn.c3
-rw-r--r--deps/openssl/openssl/crypto/ec/ecp_mont.c13
-rw-r--r--deps/openssl/openssl/crypto/ec/ecp_nist.c13
-rw-r--r--deps/openssl/openssl/crypto/ec/ecp_nistp224.c1658
-rw-r--r--deps/openssl/openssl/crypto/ec/ecp_nistp256.c2171
-rw-r--r--deps/openssl/openssl/crypto/ec/ecp_nistp521.c2025
-rw-r--r--deps/openssl/openssl/crypto/ec/ecp_nistputil.c197
-rw-r--r--deps/openssl/openssl/crypto/ec/ecp_oct.c433
-rw-r--r--deps/openssl/openssl/crypto/ec/ecp_smpl.c379
-rw-r--r--deps/openssl/openssl/crypto/ec/ectest.c343
-rw-r--r--deps/openssl/openssl/crypto/ecdh/Makefile17
-rw-r--r--deps/openssl/openssl/crypto/ecdh/ecdh.h2
-rw-r--r--deps/openssl/openssl/crypto/ecdh/ecdhtest.c6
-rw-r--r--deps/openssl/openssl/crypto/ecdh/ech_err.c4
-rw-r--r--deps/openssl/openssl/crypto/ecdh/ech_key.c3
-rw-r--r--deps/openssl/openssl/crypto/ecdh/ech_lib.c31
-rw-r--r--deps/openssl/openssl/crypto/ecdh/ech_locl.h8
-rw-r--r--deps/openssl/openssl/crypto/ecdh/ech_ossl.c2
-rw-r--r--deps/openssl/openssl/crypto/ecdsa/ecdsa.h2
-rw-r--r--deps/openssl/openssl/crypto/ecdsa/ecdsatest.c14
-rw-r--r--deps/openssl/openssl/crypto/ecdsa/ecs_err.c4
-rw-r--r--deps/openssl/openssl/crypto/ecdsa/ecs_lib.c32
-rw-r--r--deps/openssl/openssl/crypto/ecdsa/ecs_locl.h8
-rw-r--r--deps/openssl/openssl/crypto/ecdsa/ecs_ossl.c5
-rw-r--r--deps/openssl/openssl/crypto/engine/Makefile34
-rw-r--r--deps/openssl/openssl/crypto/engine/eng_all.c9
-rw-r--r--deps/openssl/openssl/crypto/engine/eng_cryptodev.c71
-rw-r--r--deps/openssl/openssl/crypto/engine/eng_fat.c3
-rw-r--r--deps/openssl/openssl/crypto/engine/eng_rdrand.c142
-rw-r--r--deps/openssl/openssl/crypto/engine/eng_rsax.c668
-rw-r--r--deps/openssl/openssl/crypto/engine/engine.h9
-rw-r--r--deps/openssl/openssl/crypto/err/err.c13
-rw-r--r--deps/openssl/openssl/crypto/err/err.h3
-rw-r--r--deps/openssl/openssl/crypto/err/err_all.c12
-rw-r--r--deps/openssl/openssl/crypto/evp/Makefile125
-rw-r--r--deps/openssl/openssl/crypto/evp/bio_md.c11
-rw-r--r--deps/openssl/openssl/crypto/evp/bio_ok.c103
-rw-r--r--deps/openssl/openssl/crypto/evp/c_allc.c18
-rw-r--r--deps/openssl/openssl/crypto/evp/digest.c27
-rw-r--r--deps/openssl/openssl/crypto/evp/e_aes.c1274
-rw-r--r--deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c580
-rw-r--r--deps/openssl/openssl/crypto/evp/e_des3.c3
-rw-r--r--deps/openssl/openssl/crypto/evp/e_null.c4
-rw-r--r--deps/openssl/openssl/crypto/evp/e_rc2.c3
-rw-r--r--deps/openssl/openssl/crypto/evp/e_rc4.c1
-rw-r--r--deps/openssl/openssl/crypto/evp/e_rc4_hmac_md5.c298
-rw-r--r--deps/openssl/openssl/crypto/evp/evp.h101
-rw-r--r--deps/openssl/openssl/crypto/evp/evp_cnf.c125
-rw-r--r--deps/openssl/openssl/crypto/evp/evp_enc.c95
-rw-r--r--deps/openssl/openssl/crypto/evp/evp_err.c26
-rw-r--r--deps/openssl/openssl/crypto/evp/evp_fips.c113
-rw-r--r--deps/openssl/openssl/crypto/evp/evp_key.c27
-rw-r--r--deps/openssl/openssl/crypto/evp/evp_lib.c4
-rw-r--r--deps/openssl/openssl/crypto/evp/evp_locl.h40
-rw-r--r--deps/openssl/openssl/crypto/evp/evp_pbe.c5
-rw-r--r--deps/openssl/openssl/crypto/evp/evptests.txt13
-rw-r--r--deps/openssl/openssl/crypto/evp/m_dss.c4
-rw-r--r--deps/openssl/openssl/crypto/evp/m_dss1.c5
-rw-r--r--deps/openssl/openssl/crypto/evp/m_ecdsa.c3
-rw-r--r--deps/openssl/openssl/crypto/evp/m_md4.c2
-rw-r--r--deps/openssl/openssl/crypto/evp/m_md5.c1
-rw-r--r--deps/openssl/openssl/crypto/evp/m_mdc2.c2
-rw-r--r--deps/openssl/openssl/crypto/evp/m_ripemd.c1
-rw-r--r--deps/openssl/openssl/crypto/evp/m_sha.c1
-rw-r--r--deps/openssl/openssl/crypto/evp/m_sha1.c7
-rw-r--r--deps/openssl/openssl/crypto/evp/m_wp.c1
-rw-r--r--deps/openssl/openssl/crypto/evp/names.c5
-rw-r--r--deps/openssl/openssl/crypto/evp/p5_crpt.c33
-rw-r--r--deps/openssl/openssl/crypto/evp/p5_crpt2.c89
-rw-r--r--deps/openssl/openssl/crypto/evp/p_open.c3
-rw-r--r--deps/openssl/openssl/crypto/evp/p_seal.c3
-rw-r--r--deps/openssl/openssl/crypto/evp/p_sign.c10
-rw-r--r--deps/openssl/openssl/crypto/evp/p_verify.c10
-rw-r--r--deps/openssl/openssl/crypto/evp/pmeth_gn.c5
-rw-r--r--deps/openssl/openssl/crypto/evp/pmeth_lib.c55
-rw-r--r--deps/openssl/openssl/crypto/fips_err.h209
-rw-r--r--deps/openssl/openssl/crypto/fips_ers.c7
-rw-r--r--deps/openssl/openssl/crypto/hmac/hm_ameth.c2
-rw-r--r--deps/openssl/openssl/crypto/hmac/hm_pmeth.c14
-rw-r--r--deps/openssl/openssl/crypto/hmac/hmac.c37
-rw-r--r--deps/openssl/openssl/crypto/ia64cpuid.S2
-rw-r--r--deps/openssl/openssl/crypto/idea/Makefile5
-rw-r--r--deps/openssl/openssl/crypto/idea/i_skey.c8
-rw-r--r--deps/openssl/openssl/crypto/idea/idea.h3
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/crypto/install-crypto.com0
-rw-r--r--deps/openssl/openssl/crypto/md2/md2.h3
-rw-r--r--deps/openssl/openssl/crypto/md2/md2_dgst.c2
-rw-r--r--deps/openssl/openssl/crypto/md4/Makefile8
-rw-r--r--deps/openssl/openssl/crypto/md4/md4.h3
-rw-r--r--deps/openssl/openssl/crypto/md4/md4_dgst.c36
-rw-r--r--deps/openssl/openssl/crypto/md4/md4_locl.h8
-rw-r--r--deps/openssl/openssl/crypto/md5/Makefile8
-rwxr-xr-xdeps/openssl/openssl/crypto/md5/asm/md5-x86_64.pl3
-rw-r--r--deps/openssl/openssl/crypto/md5/md5.h3
-rw-r--r--deps/openssl/openssl/crypto/md5/md5_dgst.c3
-rw-r--r--deps/openssl/openssl/crypto/md5/md5_locl.h8
-rw-r--r--deps/openssl/openssl/crypto/mdc2/Makefile14
-rw-r--r--deps/openssl/openssl/crypto/mdc2/mdc2.h3
-rw-r--r--deps/openssl/openssl/crypto/mdc2/mdc2dgst.c3
-rw-r--r--deps/openssl/openssl/crypto/mem.c4
-rw-r--r--deps/openssl/openssl/crypto/modes/Makefile77
-rw-r--r--deps/openssl/openssl/crypto/modes/asm/ghash-alpha.pl451
-rw-r--r--deps/openssl/openssl/crypto/modes/asm/ghash-armv4.pl429
-rwxr-xr-xdeps/openssl/openssl/crypto/modes/asm/ghash-ia64.pl463
-rw-r--r--deps/openssl/openssl/crypto/modes/asm/ghash-parisc.pl730
-rw-r--r--deps/openssl/openssl/crypto/modes/asm/ghash-s390x.pl262
-rw-r--r--deps/openssl/openssl/crypto/modes/asm/ghash-sparcv9.pl330
-rw-r--r--deps/openssl/openssl/crypto/modes/asm/ghash-x86.pl1342
-rw-r--r--deps/openssl/openssl/crypto/modes/asm/ghash-x86_64.pl806
-rw-r--r--deps/openssl/openssl/crypto/modes/cbc128.c10
-rw-r--r--deps/openssl/openssl/crypto/modes/ccm128.c441
-rw-r--r--deps/openssl/openssl/crypto/modes/cfb128.c11
-rw-r--r--deps/openssl/openssl/crypto/modes/ctr128.c92
-rw-r--r--deps/openssl/openssl/crypto/modes/cts128.c226
-rw-r--r--deps/openssl/openssl/crypto/modes/gcm128.c1757
-rw-r--r--deps/openssl/openssl/crypto/modes/modes.h76
-rw-r--r--deps/openssl/openssl/crypto/modes/modes_lcl.h131
-rw-r--r--deps/openssl/openssl/crypto/modes/ofb128.c11
-rw-r--r--deps/openssl/openssl/crypto/modes/xts128.c187
-rw-r--r--deps/openssl/openssl/crypto/o_fips.c96
-rw-r--r--deps/openssl/openssl/crypto/o_init.c82
-rw-r--r--deps/openssl/openssl/crypto/objects/o_names.c2
-rw-r--r--deps/openssl/openssl/crypto/objects/obj_dat.h136
-rw-r--r--deps/openssl/openssl/crypto/objects/obj_mac.h142
-rw-r--r--deps/openssl/openssl/crypto/objects/obj_mac.num27
-rw-r--r--deps/openssl/openssl/crypto/objects/obj_xref.c9
-rw-r--r--deps/openssl/openssl/crypto/objects/obj_xref.h2
-rw-r--r--deps/openssl/openssl/crypto/objects/obj_xref.txt4
-rw-r--r--deps/openssl/openssl/crypto/objects/objects.txt41
-rw-r--r--deps/openssl/openssl/crypto/ocsp/ocsp_lib.c3
-rw-r--r--deps/openssl/openssl/crypto/ocsp/ocsp_vfy.c10
-rw-r--r--deps/openssl/openssl/crypto/opensslconf.h1
-rw-r--r--deps/openssl/openssl/crypto/opensslv.h6
-rw-r--r--deps/openssl/openssl/crypto/ossl_typ.h2
-rw-r--r--deps/openssl/openssl/crypto/pariscid.pl224
-rw-r--r--deps/openssl/openssl/crypto/pem/pem_all.c161
-rw-r--r--deps/openssl/openssl/crypto/pem/pem_lib.c27
-rw-r--r--deps/openssl/openssl/crypto/pem/pem_seal.c6
-rw-r--r--deps/openssl/openssl/crypto/pem/pvkfmt.c58
-rw-r--r--deps/openssl/openssl/crypto/perlasm/cbc.pl2
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/crypto/perlasm/ppc-xlate.pl13
-rwxr-xr-xdeps/openssl/openssl/crypto/perlasm/x86_64-xlate.pl218
-rw-r--r--deps/openssl/openssl/crypto/perlasm/x86asm.pl55
-rw-r--r--deps/openssl/openssl/crypto/perlasm/x86gas.pl34
-rw-r--r--deps/openssl/openssl/crypto/perlasm/x86masm.pl22
-rw-r--r--deps/openssl/openssl/crypto/perlasm/x86nasm.pl15
-rw-r--r--deps/openssl/openssl/crypto/pkcs12/p12_decr.c9
-rw-r--r--deps/openssl/openssl/crypto/pkcs12/p12_key.c40
-rw-r--r--deps/openssl/openssl/crypto/pkcs12/p12_kiss.c2
-rw-r--r--deps/openssl/openssl/crypto/pkcs12/p12_mutl.c12
-rw-r--r--deps/openssl/openssl/crypto/pkcs7/bio_pk7.c2
-rw-r--r--deps/openssl/openssl/crypto/pkcs7/pk7_doit.c101
-rw-r--r--deps/openssl/openssl/crypto/pkcs7/pk7_smime.c25
-rw-r--r--deps/openssl/openssl/crypto/ppccap.c126
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/crypto/ppccpuid.pl48
-rw-r--r--deps/openssl/openssl/crypto/rand/md_rand.c33
-rw-r--r--deps/openssl/openssl/crypto/rand/rand.h9
-rw-r--r--deps/openssl/openssl/crypto/rand/rand_err.c6
-rw-r--r--deps/openssl/openssl/crypto/rand/rand_lib.c122
-rw-r--r--deps/openssl/openssl/crypto/rand/randfile.c4
-rw-r--r--deps/openssl/openssl/crypto/rc2/Makefile6
-rw-r--r--deps/openssl/openssl/crypto/rc2/rc2.h4
-rw-r--r--deps/openssl/openssl/crypto/rc2/rc2_skey.c8
-rw-r--r--deps/openssl/openssl/crypto/rc4/Makefile18
-rw-r--r--deps/openssl/openssl/crypto/rc4/asm/rc4-586.pl162
-rw-r--r--deps/openssl/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl632
-rw-r--r--deps/openssl/openssl/crypto/rc4/asm/rc4-parisc.pl313
-rw-r--r--deps/openssl/openssl/crypto/rc4/asm/rc4-s390x.pl47
-rwxr-xr-xdeps/openssl/openssl/crypto/rc4/asm/rc4-x86_64.pl293
-rw-r--r--deps/openssl/openssl/crypto/rc4/rc4.h1
-rw-r--r--deps/openssl/openssl/crypto/rc4/rc4_skey.c36
-rw-r--r--deps/openssl/openssl/crypto/rc4/rc4_utl.c62
-rw-r--r--deps/openssl/openssl/crypto/rc4/rc4test.c6
-rw-r--r--deps/openssl/openssl/crypto/ripemd/Makefile7
-rw-r--r--deps/openssl/openssl/crypto/ripemd/ripemd.h3
-rw-r--r--deps/openssl/openssl/crypto/ripemd/rmd_dgst.c33
-rw-r--r--deps/openssl/openssl/crypto/ripemd/rmd_locl.h10
-rw-r--r--deps/openssl/openssl/crypto/rsa/Makefile39
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa.h81
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_ameth.c351
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_asn1.c10
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_crpt.c257
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_eay.c6
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_err.c21
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_gen.c15
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_lib.c172
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_oaep.c8
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_pmeth.c154
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_pss.c81
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_sign.c33
-rw-r--r--deps/openssl/openssl/crypto/s390xcap.c12
-rw-r--r--deps/openssl/openssl/crypto/s390xcpuid.S17
-rw-r--r--deps/openssl/openssl/crypto/seed/seed.c13
-rw-r--r--deps/openssl/openssl/crypto/seed/seed.h4
-rw-r--r--deps/openssl/openssl/crypto/sha/Makefile39
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha1-586.pl1107
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha1-alpha.pl322
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha1-armv4-large.pl41
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha1-ia64.pl193
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha1-mips.pl354
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha1-parisc.pl259
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/crypto/sha/asm/sha1-ppc.pl83
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha1-s390x.pl50
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha1-sparcv9a.pl2
-rwxr-xr-xdeps/openssl/openssl/crypto/sha/asm/sha1-x86_64.pl1188
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha256-586.pl52
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha256-armv4.pl55
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha512-586.pl16
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha512-armv4.pl357
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha512-mips.pl455
-rwxr-xr-xdeps/openssl/openssl/crypto/sha/asm/sha512-parisc.pl791
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/crypto/sha/asm/sha512-ppc.pl114
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha512-s390x.pl63
-rw-r--r--deps/openssl/openssl/crypto/sha/asm/sha512-sparcv9.pl6
-rwxr-xr-xdeps/openssl/openssl/crypto/sha/asm/sha512-x86_64.pl89
-rw-r--r--deps/openssl/openssl/crypto/sha/sha.h14
-rw-r--r--deps/openssl/openssl/crypto/sha/sha1_one.c2
-rw-r--r--deps/openssl/openssl/crypto/sha/sha1dgst.c1
-rw-r--r--deps/openssl/openssl/crypto/sha/sha256.c10
-rw-r--r--deps/openssl/openssl/crypto/sha/sha512.c54
-rw-r--r--deps/openssl/openssl/crypto/sha/sha_dgst.c1
-rw-r--r--deps/openssl/openssl/crypto/sha/sha_locl.h46
-rw-r--r--deps/openssl/openssl/crypto/sparccpuid.S4
-rw-r--r--deps/openssl/openssl/crypto/sparcv9cap.c4
-rw-r--r--deps/openssl/openssl/crypto/srp/Makefile98
-rw-r--r--deps/openssl/openssl/crypto/srp/srp.h172
-rw-r--r--deps/openssl/openssl/crypto/srp/srp_grps.h517
-rw-r--r--deps/openssl/openssl/crypto/srp/srp_lcl.h83
-rw-r--r--deps/openssl/openssl/crypto/srp/srp_lib.c357
-rw-r--r--deps/openssl/openssl/crypto/srp/srp_vfy.c658
-rw-r--r--deps/openssl/openssl/crypto/srp/srptest.c162
-rw-r--r--deps/openssl/openssl/crypto/stack/safestack.h138
-rw-r--r--deps/openssl/openssl/crypto/symhacks.h32
-rw-r--r--deps/openssl/openssl/crypto/ts/ts.h3
-rw-r--r--deps/openssl/openssl/crypto/ts/ts_rsp_verify.c9
-rw-r--r--deps/openssl/openssl/crypto/ui/ui.h2
-rw-r--r--deps/openssl/openssl/crypto/ui/ui_openssl.c8
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/crypto/vms_rms.h0
-rw-r--r--deps/openssl/openssl/crypto/whrlpool/Makefile5
-rw-r--r--deps/openssl/openssl/crypto/whrlpool/asm/wp-mmx.pl2
-rw-r--r--deps/openssl/openssl/crypto/whrlpool/asm/wp-x86_64.pl3
-rw-r--r--deps/openssl/openssl/crypto/whrlpool/whrlpool.h3
-rw-r--r--deps/openssl/openssl/crypto/whrlpool/wp_block.c4
-rw-r--r--deps/openssl/openssl/crypto/whrlpool/wp_dgst.c3
-rw-r--r--deps/openssl/openssl/crypto/x509/by_dir.c8
-rw-r--r--deps/openssl/openssl/crypto/x509/x509.h11
-rw-r--r--deps/openssl/openssl/crypto/x509/x509_cmp.c34
-rw-r--r--deps/openssl/openssl/crypto/x509/x509_lu.c2
-rw-r--r--deps/openssl/openssl/crypto/x509/x509_vfy.c9
-rw-r--r--deps/openssl/openssl/crypto/x509/x509type.c32
-rw-r--r--deps/openssl/openssl/crypto/x509/x_all.c19
-rw-r--r--deps/openssl/openssl/crypto/x509v3/v3_asid.c63
-rw-r--r--deps/openssl/openssl/crypto/x509v3/v3_purp.c4
-rw-r--r--deps/openssl/openssl/crypto/x509v3/v3_skey.c3
-rw-r--r--deps/openssl/openssl/crypto/x86_64cpuid.pl88
-rw-r--r--deps/openssl/openssl/crypto/x86cpuid.pl82
-rw-r--r--deps/openssl/openssl/doc/HOWTO/proxy_certificates.txt2
-rw-r--r--deps/openssl/openssl/doc/apps/CA.pl.pod8
-rw-r--r--deps/openssl/openssl/doc/apps/genpkey.pod2
-rw-r--r--deps/openssl/openssl/doc/apps/openssl.pod4
-rw-r--r--deps/openssl/openssl/doc/apps/verify.pod60
-rw-r--r--deps/openssl/openssl/doc/apps/x509.pod5
-rw-r--r--deps/openssl/openssl/doc/crypto/EVP_DigestInit.pod66
-rw-r--r--deps/openssl/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod2
-rw-r--r--deps/openssl/openssl/doc/crypto/EVP_PKEY_decrypt.pod2
-rw-r--r--deps/openssl/openssl/doc/crypto/EVP_PKEY_derive.pod2
-rw-r--r--deps/openssl/openssl/doc/crypto/EVP_PKEY_encrypt.pod2
-rw-r--r--deps/openssl/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod2
-rw-r--r--deps/openssl/openssl/doc/crypto/EVP_PKEY_keygen.pod2
-rw-r--r--deps/openssl/openssl/doc/crypto/EVP_PKEY_sign.pod2
-rw-r--r--deps/openssl/openssl/doc/crypto/EVP_PKEY_verify.pod2
-rw-r--r--deps/openssl/openssl/doc/crypto/EVP_PKEY_verify_recover.pod103
-rw-r--r--deps/openssl/openssl/doc/crypto/ecdsa.pod2
-rw-r--r--deps/openssl/openssl/doc/ssl/SSL_alert_type_string.pod5
-rw-r--r--deps/openssl/openssl/e_os.h12
-rw-r--r--deps/openssl/openssl/e_os2.h20
-rw-r--r--deps/openssl/openssl/engines/ccgost/Makefile14
-rw-r--r--deps/openssl/openssl/engines/ccgost/gost89.c14
-rw-r--r--deps/openssl/openssl/engines/ccgost/gost_ameth.c37
-rw-r--r--deps/openssl/openssl/engines/ccgost/gost_crypt.c29
-rw-r--r--deps/openssl/openssl/engines/ccgost/gost_eng.c17
-rw-r--r--deps/openssl/openssl/engines/ccgost/gost_lcl.h4
-rw-r--r--deps/openssl/openssl/engines/ccgost/gost_pmeth.c19
-rw-r--r--deps/openssl/openssl/engines/ccgost/gosthash.c2
-rw-r--r--deps/openssl/openssl/engines/e_aep.c1
-rw-r--r--deps/openssl/openssl/engines/e_capi.c56
-rw-r--r--deps/openssl/openssl/engines/e_padlock.c8
-rw-r--r--deps/openssl/openssl/include/openssl/cmac.h1
-rw-r--r--deps/openssl/openssl/include/openssl/opensslconf.h1
-rw-r--r--deps/openssl/openssl/include/openssl/srp.h1
-rw-r--r--deps/openssl/openssl/include/openssl/srtp.h1
-rwxr-xr-xdeps/openssl/openssl/makevms.com20
-rwxr-xr-xdeps/openssl/openssl/ms/do_win64a.bat18
-rwxr-xr-xdeps/openssl/openssl/ms/do_win64i.bat6
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/ms/uplink-common.pl0
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/ms/uplink-ia64.pl0
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/ms/uplink-x86.pl0
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/ms/uplink-x86_64.pl3
-rw-r--r--deps/openssl/openssl/ms/uplink.h4
-rw-r--r--deps/openssl/openssl/openssl.spec4
-rw-r--r--deps/openssl/openssl/ssl/Makefile556
-rw-r--r--deps/openssl/openssl/ssl/d1_both.c178
-rw-r--r--deps/openssl/openssl/ssl/d1_clnt.c200
-rw-r--r--deps/openssl/openssl/ssl/d1_enc.c59
-rw-r--r--deps/openssl/openssl/ssl/d1_lib.c53
-rw-r--r--deps/openssl/openssl/ssl/d1_pkt.c277
-rw-r--r--deps/openssl/openssl/ssl/d1_srtp.c494
-rw-r--r--deps/openssl/openssl/ssl/d1_srvr.c186
-rw-r--r--deps/openssl/openssl/ssl/dtls1.h26
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/ssl/install-ssl.com2
-rw-r--r--deps/openssl/openssl/ssl/kssl.c16
-rw-r--r--deps/openssl/openssl/ssl/kssl.h4
-rw-r--r--deps/openssl/openssl/ssl/s23_clnt.c118
-rw-r--r--deps/openssl/openssl/ssl/s23_meth.c4
-rw-r--r--deps/openssl/openssl/ssl/s23_srvr.c59
-rw-r--r--deps/openssl/openssl/ssl/s2_clnt.c14
-rw-r--r--deps/openssl/openssl/ssl/s2_pkt.c3
-rw-r--r--deps/openssl/openssl/ssl/s2_srvr.c16
-rw-r--r--deps/openssl/openssl/ssl/s3_both.c44
-rw-r--r--deps/openssl/openssl/ssl/s3_cbc.c790
-rw-r--r--deps/openssl/openssl/ssl/s3_clnt.c440
-rw-r--r--deps/openssl/openssl/ssl/s3_enc.c147
-rw-r--r--deps/openssl/openssl/ssl/s3_lib.c991
-rw-r--r--deps/openssl/openssl/ssl/s3_pkt.c225
-rw-r--r--deps/openssl/openssl/ssl/s3_srvr.c476
-rw-r--r--deps/openssl/openssl/ssl/srtp.h145
-rw-r--r--deps/openssl/openssl/ssl/ssl-lib.com4
-rw-r--r--deps/openssl/openssl/ssl/ssl.h331
-rw-r--r--deps/openssl/openssl/ssl/ssl2.h4
-rw-r--r--deps/openssl/openssl/ssl/ssl3.h45
-rw-r--r--deps/openssl/openssl/ssl/ssl_algs.c10
-rw-r--r--deps/openssl/openssl/ssl/ssl_asn1.c50
-rw-r--r--deps/openssl/openssl/ssl/ssl_cert.c21
-rw-r--r--deps/openssl/openssl/ssl/ssl_ciph.c178
-rw-r--r--deps/openssl/openssl/ssl/ssl_err.c35
-rw-r--r--deps/openssl/openssl/ssl/ssl_lib.c228
-rw-r--r--deps/openssl/openssl/ssl/ssl_locl.h111
-rw-r--r--deps/openssl/openssl/ssl/ssl_rsa.c50
-rw-r--r--deps/openssl/openssl/ssl/ssl_sess.c167
-rw-r--r--deps/openssl/openssl/ssl/ssl_txt.c8
-rw-r--r--deps/openssl/openssl/ssl/ssltest.c176
-rw-r--r--deps/openssl/openssl/ssl/t1_clnt.c21
-rw-r--r--deps/openssl/openssl/ssl/t1_enc.c353
-rw-r--r--deps/openssl/openssl/ssl/t1_lib.c955
-rw-r--r--deps/openssl/openssl/ssl/t1_meth.c22
-rw-r--r--deps/openssl/openssl/ssl/t1_srvr.c21
-rw-r--r--deps/openssl/openssl/ssl/tls1.h201
-rw-r--r--deps/openssl/openssl/ssl/tls_srp.c507
-rw-r--r--deps/openssl/openssl/test/CAss.cnf76
-rw-r--r--deps/openssl/openssl/test/CAssdh.cnf24
-rw-r--r--deps/openssl/openssl/test/CAssdsa.cnf23
-rw-r--r--deps/openssl/openssl/test/CAssrsa.cnf24
-rw-r--r--deps/openssl/openssl/test/CAtsa.cnf163
-rw-r--r--deps/openssl/openssl/test/Makefile729
-rw-r--r--deps/openssl/openssl/test/P1ss.cnf37
-rw-r--r--deps/openssl/openssl/test/P2ss.cnf45
-rw-r--r--deps/openssl/openssl/test/Sssdsa.cnf27
-rw-r--r--deps/openssl/openssl/test/Sssrsa.cnf26
-rw-r--r--deps/openssl/openssl/test/Uss.cnf36
-rw-r--r--deps/openssl/openssl/test/VMSca-response.11
-rw-r--r--deps/openssl/openssl/test/VMSca-response.22
-rwxr-xr-xdeps/openssl/openssl/test/asn1test.c22
-rwxr-xr-xdeps/openssl/openssl/test/bctest111
-rw-r--r--deps/openssl/openssl/test/bctest.com152
-rw-r--r--deps/openssl/openssl/test/bftest.c540
-rw-r--r--deps/openssl/openssl/test/bntest.c2013
-rw-r--r--deps/openssl/openssl/test/bntest.com76
-rw-r--r--deps/openssl/openssl/test/casttest.c233
-rwxr-xr-xdeps/openssl/openssl/test/clean_test.com35
-rw-r--r--deps/openssl/openssl/test/cms-examples.pl409
-rw-r--r--deps/openssl/openssl/test/cms-test.pl457
-rw-r--r--deps/openssl/openssl/test/destest.c952
-rw-r--r--deps/openssl/openssl/test/dhtest.c226
-rw-r--r--deps/openssl/openssl/test/dsatest.c259
-rw-r--r--deps/openssl/openssl/test/dummytest.c48
-rw-r--r--deps/openssl/openssl/test/ecdhtest.c374
-rw-r--r--deps/openssl/openssl/test/ecdsatest.c572
-rw-r--r--deps/openssl/openssl/test/ectest.c1489
-rw-r--r--deps/openssl/openssl/test/enginetest.c283
-rw-r--r--deps/openssl/openssl/test/evp_test.c450
-rw-r--r--deps/openssl/openssl/test/evptests.txt334
-rw-r--r--deps/openssl/openssl/test/exptest.c204
-rw-r--r--deps/openssl/openssl/test/hmactest.c175
-rw-r--r--deps/openssl/openssl/test/ideatest.c235
-rw-r--r--deps/openssl/openssl/test/igetest.c503
-rw-r--r--deps/openssl/openssl/test/jpaketest.c48
-rw-r--r--deps/openssl/openssl/test/maketests.com1087
-rw-r--r--deps/openssl/openssl/test/md2test.c48
-rw-r--r--deps/openssl/openssl/test/md4test.c136
-rw-r--r--deps/openssl/openssl/test/md5test.c140
-rw-r--r--deps/openssl/openssl/test/mdc2test.c149
-rw-r--r--deps/openssl/openssl/test/methtest.c105
-rw-r--r--deps/openssl/openssl/test/pkcs7-1.pem15
-rw-r--r--deps/openssl/openssl/test/pkcs7.pem54
-rw-r--r--deps/openssl/openssl/test/pkits-test.pl949
-rw-r--r--deps/openssl/openssl/test/r160test.c57
-rw-r--r--deps/openssl/openssl/test/randtest.c219
-rw-r--r--deps/openssl/openssl/test/rc2test.c274
-rw-r--r--deps/openssl/openssl/test/rc4test.c242
-rw-r--r--deps/openssl/openssl/test/rc5test.c48
-rw-r--r--deps/openssl/openssl/test/rmdtest.c145
-rw-r--r--deps/openssl/openssl/test/rsa_test.c340
-rw-r--r--deps/openssl/openssl/test/sha1test.c178
-rw-r--r--deps/openssl/openssl/test/sha256t.c147
-rw-r--r--deps/openssl/openssl/test/sha512t.c184
-rw-r--r--deps/openssl/openssl/test/shatest.c178
-rw-r--r--deps/openssl/openssl/test/smcont.txt1
-rw-r--r--deps/openssl/openssl/test/smime-certs/smdsa1.pem34
-rw-r--r--deps/openssl/openssl/test/smime-certs/smdsa2.pem34
-rw-r--r--deps/openssl/openssl/test/smime-certs/smdsa3.pem34
-rw-r--r--deps/openssl/openssl/test/smime-certs/smdsap.pem9
-rw-r--r--deps/openssl/openssl/test/smime-certs/smroot.pem30
-rw-r--r--deps/openssl/openssl/test/smime-certs/smrsa1.pem31
-rw-r--r--deps/openssl/openssl/test/smime-certs/smrsa2.pem31
-rw-r--r--deps/openssl/openssl/test/smime-certs/smrsa3.pem31
-rw-r--r--deps/openssl/openssl/test/srptest.c162
-rw-r--r--deps/openssl/openssl/test/ssltest.c2577
-rw-r--r--deps/openssl/openssl/test/tcrl78
-rw-r--r--deps/openssl/openssl/test/tcrl.com88
-rw-r--r--deps/openssl/openssl/test/test.cnf88
-rwxr-xr-xdeps/openssl/openssl/test/test_padlock64
-rw-r--r--deps/openssl/openssl/test/testca51
-rw-r--r--deps/openssl/openssl/test/testca.com52
-rw-r--r--deps/openssl/openssl/test/testcrl.pem16
-rw-r--r--deps/openssl/openssl/test/testenc54
-rw-r--r--deps/openssl/openssl/test/testenc.com66
-rw-r--r--deps/openssl/openssl/test/testfipsssl113
-rw-r--r--deps/openssl/openssl/test/testgen44
-rw-r--r--deps/openssl/openssl/test/testgen.com58
-rw-r--r--deps/openssl/openssl/test/testp7.pem46
-rw-r--r--deps/openssl/openssl/test/testreq2.pem7
-rw-r--r--deps/openssl/openssl/test/testrsa.pem9
-rw-r--r--deps/openssl/openssl/test/tests.com375
-rw-r--r--deps/openssl/openssl/test/testsid.pem12
-rw-r--r--deps/openssl/openssl/test/testss163
-rw-r--r--deps/openssl/openssl/test/testss.com123
-rw-r--r--deps/openssl/openssl/test/testssl178
-rw-r--r--deps/openssl/openssl/test/testssl.com208
-rw-r--r--deps/openssl/openssl/test/testsslproxy10
-rw-r--r--deps/openssl/openssl/test/testtsa238
-rw-r--r--deps/openssl/openssl/test/testtsa.com255
-rw-r--r--deps/openssl/openssl/test/testx509.pem10
-rw-r--r--deps/openssl/openssl/test/times113
-rw-r--r--deps/openssl/openssl/test/tpkcs748
-rw-r--r--deps/openssl/openssl/test/tpkcs7.com59
-rw-r--r--deps/openssl/openssl/test/tpkcs7d41
-rw-r--r--deps/openssl/openssl/test/tpkcs7d.com52
-rw-r--r--deps/openssl/openssl/test/treq83
-rw-r--r--deps/openssl/openssl/test/treq.com88
-rw-r--r--deps/openssl/openssl/test/trsa83
-rw-r--r--deps/openssl/openssl/test/trsa.com99
-rw-r--r--deps/openssl/openssl/test/tsid78
-rw-r--r--deps/openssl/openssl/test/tsid.com88
-rw-r--r--deps/openssl/openssl/test/tverify.com65
-rw-r--r--deps/openssl/openssl/test/tx50978
-rw-r--r--deps/openssl/openssl/test/tx509.com88
-rw-r--r--deps/openssl/openssl/test/v3-cert1.pem16
-rw-r--r--deps/openssl/openssl/test/v3-cert2.pem16
-rw-r--r--deps/openssl/openssl/test/wp_test.c228
-rw-r--r--deps/openssl/openssl/util/copy.pl11
-rwxr-xr-xdeps/openssl/openssl/util/cygwin.sh12
-rwxr-xr-xdeps/openssl/openssl/util/libeay.num219
-rwxr-xr-xdeps/openssl/openssl/util/mk1mf.pl85
-rwxr-xr-xdeps/openssl/openssl/util/mkdef.pl40
-rwxr-xr-xdeps/openssl/openssl/util/mkfiles.pl2
-rwxr-xr-x[-rw-r--r--]deps/openssl/openssl/util/mkrc.pl0
-rw-r--r--deps/openssl/openssl/util/pl/VC-32.pl81
-rwxr-xr-xdeps/openssl/openssl/util/ssleay.num61
-rw-r--r--deps/openssl/patches/handshake_cutthrough.patch275
-rw-r--r--deps/openssl/patches/jsse.patch426
-rw-r--r--deps/openssl/patches/npn.patch1293
-rw-r--r--deps/openssl/patches/openssl_no_dtls1.patch13
-rw-r--r--deps/openssl/patches/progs.patch54
-rw-r--r--deps/openssl/patches/sha1_armv4_large.patch21
-rw-r--r--deps/openssl/patches/small_records.patch337
-rwxr-xr-xdeps/openssl/patches/tls_exporter.patch220
-rw-r--r--deps/openssl/patches/x509_hash_name_algorithm_change.patch31
-rw-r--r--deps/uv/.gitignore25
-rw-r--r--deps/uv/.travis.yml9
-rw-r--r--deps/uv/AUTHORS16
-rw-r--r--deps/uv/LICENSE11
-rw-r--r--deps/uv/Makefile112
-rw-r--r--deps/uv/README.md52
-rw-r--r--deps/uv/build.mk164
-rwxr-xr-xdeps/uv/checksparse.sh230
-rw-r--r--deps/uv/common.gypi25
-rw-r--r--deps/uv/config-mingw.mk22
-rw-r--r--deps/uv/config-unix.mk164
-rwxr-xr-xdeps/uv/gyp_uv27
-rw-r--r--deps/uv/include/ares.h591
-rw-r--r--deps/uv/include/ares_version.h24
-rw-r--r--deps/uv/include/uv-private/eio.h403
-rw-r--r--deps/uv/include/uv-private/ev.h838
-rw-r--r--deps/uv/include/uv-private/ngx-queue.h39
-rw-r--r--deps/uv/include/uv-private/stdint-msvc2008.h247
-rw-r--r--deps/uv/include/uv-private/uv-bsd.h34
-rw-r--r--deps/uv/include/uv-private/uv-darwin.h61
-rw-r--r--deps/uv/include/uv-private/uv-linux.h34
-rw-r--r--deps/uv/include/uv-private/uv-sunos.h44
-rw-r--r--deps/uv/include/uv-private/uv-unix.h404
-rw-r--r--deps/uv/include/uv-private/uv-win.h535
-rw-r--r--deps/uv/include/uv.h647
-rw-r--r--deps/uv/src/ares/CHANGES1218
-rw-r--r--deps/uv/src/ares/CMakeLists.txt22
-rw-r--r--deps/uv/src/ares/README.node21
-rw-r--r--deps/uv/src/ares/RELEASE-NOTES26
-rw-r--r--deps/uv/src/ares/ares__get_hostent.c263
-rw-r--r--deps/uv/src/ares/ares_data.c190
-rw-r--r--deps/uv/src/ares/ares_data.h65
-rw-r--r--deps/uv/src/ares/ares_destroy.c105
-rw-r--r--deps/uv/src/ares/ares_dns.h90
-rw-r--r--deps/uv/src/ares/ares_expand_name.c200
-rw-r--r--deps/uv/src/ares/ares_gethostbyname.c523
-rw-r--r--deps/uv/src/ares/ares_getnameinfo.c427
-rw-r--r--deps/uv/src/ares/ares_init.c1809
-rw-r--r--deps/uv/src/ares/ares_library_init.h42
-rw-r--r--deps/uv/src/ares/ares_nowarn.c181
-rw-r--r--deps/uv/src/ares/ares_nowarn.h55
-rw-r--r--deps/uv/src/ares/ares_parse_aaaa_reply.c259
-rw-r--r--deps/uv/src/ares/ares_parse_ptr_reply.c217
-rw-r--r--deps/uv/src/ares/ares_private.h355
-rw-r--r--deps/uv/src/ares/ares_process.c1295
-rw-r--r--deps/uv/src/ares/ares_send.c134
-rw-r--r--deps/uv/src/ares/ares_setup.h199
-rw-r--r--deps/uv/src/ares/ares_timeout.c80
-rw-r--r--deps/uv/src/ares/setup_once.h504
-rw-r--r--deps/uv/src/cares.c225
-rw-r--r--deps/uv/src/fs-poll.c38
-rw-r--r--deps/uv/src/inet.c298
-rw-r--r--deps/uv/src/unix/aix.c393
-rw-r--r--deps/uv/src/unix/async.c232
-rw-r--r--deps/uv/src/unix/core.c431
-rw-r--r--deps/uv/src/unix/cygwin.c15
-rw-r--r--deps/uv/src/unix/darwin-proctitle.m78
-rw-r--r--deps/uv/src/unix/darwin.c194
-rw-r--r--deps/uv/src/unix/eio/Changes63
-rw-r--r--deps/uv/src/unix/eio/LICENSE36
-rw-r--r--deps/uv/src/unix/eio/Makefile.am15
-rw-r--r--deps/uv/src/unix/eio/aclocal.m48957
-rwxr-xr-xdeps/uv/src/unix/eio/autogen.sh3
-rw-r--r--deps/uv/src/unix/eio/config.h.in86
-rw-r--r--deps/uv/src/unix/eio/config_cygwin.h80
-rw-r--r--deps/uv/src/unix/eio/config_darwin.h141
-rw-r--r--deps/uv/src/unix/eio/config_freebsd.h81
-rw-r--r--deps/uv/src/unix/eio/config_linux.h94
-rw-r--r--deps/uv/src/unix/eio/config_netbsd.h81
-rw-r--r--deps/uv/src/unix/eio/config_openbsd.h137
-rw-r--r--deps/uv/src/unix/eio/config_sunos.h84
-rw-r--r--deps/uv/src/unix/eio/configure.ac22
-rw-r--r--deps/uv/src/unix/eio/demo.c194
-rw-r--r--deps/uv/src/unix/eio/ecb.h370
-rw-r--r--deps/uv/src/unix/eio/eio.33428
-rw-r--r--deps/uv/src/unix/eio/eio.c2593
-rw-r--r--deps/uv/src/unix/eio/eio.pod969
-rw-r--r--deps/uv/src/unix/eio/libeio.m4195
-rw-r--r--deps/uv/src/unix/eio/xthread.h164
-rw-r--r--deps/uv/src/unix/error.c2
-rw-r--r--deps/uv/src/unix/ev/Changes388
-rw-r--r--deps/uv/src/unix/ev/LICENSE36
-rw-r--r--deps/uv/src/unix/ev/Makefile.am18
-rw-r--r--deps/uv/src/unix/ev/Makefile.in771
-rw-r--r--deps/uv/src/unix/ev/README58
-rw-r--r--deps/uv/src/unix/ev/aclocal.m48957
-rw-r--r--deps/uv/src/unix/ev/autogen.sh6
-rwxr-xr-xdeps/uv/src/unix/ev/config.guess1526
-rw-r--r--deps/uv/src/unix/ev/config.h.in125
-rwxr-xr-xdeps/uv/src/unix/ev/config.sub1658
-rw-r--r--deps/uv/src/unix/ev/config_cygwin.h123
-rw-r--r--deps/uv/src/unix/ev/config_darwin.h122
-rw-r--r--deps/uv/src/unix/ev/config_freebsd.h120
-rw-r--r--deps/uv/src/unix/ev/config_linux.h141
-rw-r--r--deps/uv/src/unix/ev/config_netbsd.h120
-rw-r--r--deps/uv/src/unix/ev/config_openbsd.h126
-rw-r--r--deps/uv/src/unix/ev/config_sunos.h122
-rwxr-xr-xdeps/uv/src/unix/ev/configure13037
-rw-r--r--deps/uv/src/unix/ev/configure.ac18
-rwxr-xr-xdeps/uv/src/unix/ev/depcomp630
-rw-r--r--deps/uv/src/unix/ev/ev++.h816
-rw-r--r--deps/uv/src/unix/ev/ev.35311
-rw-r--r--deps/uv/src/unix/ev/ev.c3925
-rw-r--r--deps/uv/src/unix/ev/ev.pod5243
-rw-r--r--deps/uv/src/unix/ev/ev_epoll.c266
-rw-r--r--deps/uv/src/unix/ev/ev_kqueue.c235
-rw-r--r--deps/uv/src/unix/ev/ev_poll.c148
-rw-r--r--deps/uv/src/unix/ev/ev_port.c179
-rw-r--r--deps/uv/src/unix/ev/ev_select.c310
-rw-r--r--deps/uv/src/unix/ev/ev_vars.h203
-rw-r--r--deps/uv/src/unix/ev/ev_win32.c153
-rw-r--r--deps/uv/src/unix/ev/ev_wrap.h196
-rw-r--r--deps/uv/src/unix/ev/event.c402
-rw-r--r--deps/uv/src/unix/ev/event.h170
-rwxr-xr-xdeps/uv/src/unix/ev/install-sh294
-rw-r--r--deps/uv/src/unix/ev/libev.m439
-rwxr-xr-xdeps/uv/src/unix/ev/ltmain.sh8413
-rwxr-xr-xdeps/uv/src/unix/ev/missing336
-rwxr-xr-xdeps/uv/src/unix/ev/mkinstalldirs111
-rw-r--r--deps/uv/src/unix/freebsd.c37
-rw-r--r--deps/uv/src/unix/fs.c1158
-rw-r--r--deps/uv/src/unix/fsevents.c299
-rw-r--r--deps/uv/src/unix/getaddrinfo.c159
-rw-r--r--deps/uv/src/unix/internal.h174
-rw-r--r--deps/uv/src/unix/kqueue.c295
-rw-r--r--deps/uv/src/unix/linux-core.c711
-rw-r--r--deps/uv/src/unix/linux-inotify.c236
-rw-r--r--deps/uv/src/unix/linux-syscalls.c388
-rw-r--r--deps/uv/src/unix/linux-syscalls.h150
-rw-r--r--deps/uv/src/unix/linux/inotify.c241
-rw-r--r--deps/uv/src/unix/linux/linux-core.c586
-rw-r--r--deps/uv/src/unix/linux/syscalls.c280
-rw-r--r--deps/uv/src/unix/linux/syscalls.h93
-rw-r--r--deps/uv/src/unix/loop-watcher.c5
-rw-r--r--deps/uv/src/unix/loop.c99
-rw-r--r--deps/uv/src/unix/netbsd.c255
-rw-r--r--deps/uv/src/unix/openbsd.c11
-rw-r--r--deps/uv/src/unix/pipe.c51
-rw-r--r--deps/uv/src/unix/poll.c36
-rw-r--r--deps/uv/src/unix/process.c405
-rw-r--r--deps/uv/src/unix/proctitle.c103
-rw-r--r--deps/uv/src/unix/signal.c455
-rw-r--r--deps/uv/src/unix/stream.c832
-rw-r--r--deps/uv/src/unix/sunos.c218
-rw-r--r--deps/uv/src/unix/tcp.c140
-rw-r--r--deps/uv/src/unix/thread.c184
-rw-r--r--deps/uv/src/unix/threadpool.c257
-rw-r--r--deps/uv/src/unix/timer.c33
-rw-r--r--deps/uv/src/unix/tty.c9
-rw-r--r--deps/uv/src/unix/udp.c310
-rw-r--r--deps/uv/src/unix/uv-eio.c107
-rw-r--r--deps/uv/src/unix/uv-eio.h13
-rw-r--r--deps/uv/src/uv-common.c141
-rw-r--r--deps/uv/src/uv-common.h61
-rw-r--r--deps/uv/src/win/async.c43
-rw-r--r--deps/uv/src/win/atomicops-inl.h56
-rw-r--r--deps/uv/src/win/core.c124
-rw-r--r--deps/uv/src/win/dl.c2
-rw-r--r--deps/uv/src/win/error.c4
-rw-r--r--deps/uv/src/win/fs-event.c50
-rw-r--r--deps/uv/src/win/fs.c8
-rw-r--r--deps/uv/src/win/getaddrinfo.c22
-rw-r--r--deps/uv/src/win/handle-inl.h29
-rw-r--r--deps/uv/src/win/handle.c21
-rw-r--r--deps/uv/src/win/internal.h34
-rw-r--r--deps/uv/src/win/loop-watcher.c7
-rw-r--r--deps/uv/src/win/pipe.c97
-rw-r--r--deps/uv/src/win/poll.c17
-rw-r--r--deps/uv/src/win/process-stdio.c69
-rw-r--r--deps/uv/src/win/process.c585
-rw-r--r--deps/uv/src/win/req-inl.h9
-rw-r--r--deps/uv/src/win/signal.c354
-rw-r--r--deps/uv/src/win/stream-inl.h2
-rw-r--r--deps/uv/src/win/stream.c51
-rw-r--r--deps/uv/src/win/tcp.c91
-rw-r--r--deps/uv/src/win/thread.c308
-rw-r--r--deps/uv/src/win/threadpool.c12
-rw-r--r--deps/uv/src/win/timer.c26
-rw-r--r--deps/uv/src/win/tty.c189
-rw-r--r--deps/uv/src/win/udp.c95
-rw-r--r--deps/uv/src/win/util.c12
-rw-r--r--deps/uv/src/win/winapi.c20
-rw-r--r--deps/uv/src/win/winapi.h24
-rw-r--r--deps/uv/test/benchmark-ares.c117
-rw-r--r--deps/uv/test/benchmark-async-pummel.c119
-rw-r--r--deps/uv/test/benchmark-async.c139
-rw-r--r--deps/uv/test/benchmark-fs-stat.c38
-rw-r--r--deps/uv/test/benchmark-getaddrinfo.c9
-rw-r--r--deps/uv/test/benchmark-list.h97
-rw-r--r--deps/uv/test/benchmark-loop-count.c6
-rw-r--r--deps/uv/test/benchmark-million-async.c112
-rw-r--r--deps/uv/test/benchmark-million-timers.c14
-rw-r--r--deps/uv/test/benchmark-multi-accept.c432
-rw-r--r--deps/uv/test/benchmark-ping-pongs.c9
-rw-r--r--deps/uv/test/benchmark-pound.c3
-rw-r--r--deps/uv/test/benchmark-pump.c41
-rw-r--r--deps/uv/test/benchmark-spawn.c17
-rw-r--r--deps/uv/test/benchmark-tcp-write-batch.c5
-rw-r--r--deps/uv/test/benchmark-udp-packet-storm.c247
-rw-r--r--deps/uv/test/benchmark-udp-pummel.c238
-rw-r--r--deps/uv/test/blackhole-server.c2
-rw-r--r--deps/uv/test/dns-server.c22
-rw-r--r--deps/uv/test/echo-server.c30
-rw-r--r--deps/uv/test/run-benchmarks.c2
-rw-r--r--deps/uv/test/run-tests.c20
-rw-r--r--deps/uv/test/runner-unix.c72
-rw-r--r--deps/uv/test/runner-win.c13
-rw-r--r--deps/uv/test/runner-win.h1
-rw-r--r--deps/uv/test/runner.c91
-rw-r--r--deps/uv/test/runner.h24
-rw-r--r--deps/uv/test/task.h33
-rw-r--r--deps/uv/test/test-active.c83
-rw-r--r--deps/uv/test/test-async.c22
-rw-r--r--deps/uv/test/test-barrier.c98
-rw-r--r--deps/uv/test/test-callback-order.c3
-rw-r--r--deps/uv/test/test-callback-stack.c3
-rw-r--r--deps/uv/test/test-condvar.c173
-rw-r--r--deps/uv/test/test-connection-fail.c6
-rw-r--r--deps/uv/test/test-counters-init.c215
-rw-r--r--deps/uv/test/test-delayed-accept.c16
-rw-r--r--deps/uv/test/test-embed.c136
-rw-r--r--deps/uv/test/test-fs-event.c106
-rw-r--r--deps/uv/test/test-fs-poll.c8
-rw-r--r--deps/uv/test/test-fs.c156
-rw-r--r--deps/uv/test/test-getaddrinfo.c10
-rw-r--r--deps/uv/test/test-gethostbyname.c180
-rw-r--r--deps/uv/test/test-getsockname.c24
-rw-r--r--deps/uv/test/test-idle.c3
-rw-r--r--deps/uv/test/test-ipc-send-recv.c17
-rw-r--r--deps/uv/test/test-ipc.c17
-rw-r--r--deps/uv/test/test-list.h72
-rw-r--r--deps/uv/test/test-loop-handles.c3
-rw-r--r--deps/uv/test/test-loop-stop.c73
-rw-r--r--deps/uv/test/test-multiple-listen.c7
-rw-r--r--deps/uv/test/test-ping-pong.c57
-rw-r--r--deps/uv/test/test-pipe-bind-error.c12
-rw-r--r--deps/uv/test/test-pipe-connect-error.c6
-rw-r--r--deps/uv/test/test-poll-close.c8
-rw-r--r--deps/uv/test/test-poll.c14
-rw-r--r--deps/uv/test/test-ref.c127
-rw-r--r--deps/uv/test/test-run-nowait.c46
-rw-r--r--deps/uv/test/test-run-once.c3
-rw-r--r--deps/uv/test/test-shutdown-close.c10
-rw-r--r--deps/uv/test/test-shutdown-eof.c9
-rw-r--r--deps/uv/test/test-signal-multiple-loops.c270
-rw-r--r--deps/uv/test/test-signal.c152
-rw-r--r--deps/uv/test/test-spawn.c151
-rw-r--r--deps/uv/test/test-stdio-over-pipes.c16
-rw-r--r--deps/uv/test/test-tcp-bind-error.c19
-rw-r--r--deps/uv/test/test-tcp-bind6-error.c15
-rw-r--r--deps/uv/test/test-tcp-close-while-connecting.c5
-rw-r--r--deps/uv/test/test-tcp-close.c3
-rw-r--r--deps/uv/test/test-tcp-connect-error-after-write.c3
-rw-r--r--deps/uv/test/test-tcp-connect-error.c3
-rw-r--r--deps/uv/test/test-tcp-connect-timeout.c3
-rw-r--r--deps/uv/test/test-tcp-connect6-error.c3
-rw-r--r--deps/uv/test/test-tcp-flags.c3
-rw-r--r--deps/uv/test/test-tcp-open.c175
-rw-r--r--deps/uv/test/test-tcp-read-stop.c73
-rw-r--r--deps/uv/test/test-tcp-shutdown-after-write.c3
-rw-r--r--deps/uv/test/test-tcp-unexpected-read.c7
-rw-r--r--deps/uv/test/test-tcp-write-error.c168
-rw-r--r--deps/uv/test/test-tcp-write-to-half-open-connection.c3
-rw-r--r--deps/uv/test/test-tcp-writealot.c5
-rw-r--r--deps/uv/test/test-thread.c8
-rw-r--r--deps/uv/test/test-threadpool-cancel.c311
-rw-r--r--deps/uv/test/test-threadpool.c24
-rw-r--r--deps/uv/test/test-timer-again.c5
-rw-r--r--deps/uv/test/test-timer.c60
-rw-r--r--deps/uv/test/test-tty.c3
-rw-r--r--deps/uv/test/test-udp-dgram-too-big.c3
-rw-r--r--deps/uv/test/test-udp-ipv6.c4
-rw-r--r--deps/uv/test/test-udp-multicast-join.c3
-rw-r--r--deps/uv/test/test-udp-multicast-ttl.c3
-rw-r--r--deps/uv/test/test-udp-open.c154
-rw-r--r--deps/uv/test/test-udp-options.c3
-rw-r--r--deps/uv/test/test-udp-send-and-recv.c3
-rw-r--r--deps/uv/test/test-walk-handles.c3
-rw-r--r--deps/uv/uv.gyp226
-rw-r--r--deps/uv/vcbuild.bat50
-rw-r--r--deps/v8/.gitignore22
-rw-r--r--deps/v8/AUTHORS3
-rw-r--r--deps/v8/ChangeLog476
-rw-r--r--deps/v8/DEPS2
-rw-r--r--deps/v8/Makefile112
-rw-r--r--deps/v8/Makefile.android92
-rw-r--r--deps/v8/OWNERS11
-rw-r--r--deps/v8/PRESUBMIT.py71
-rw-r--r--deps/v8/SConstruct49
-rw-r--r--deps/v8/build/android.gypi84
-rw-r--r--deps/v8/build/common.gypi63
-rw-r--r--deps/v8/build/standalone.gypi11
-rwxr-xr-xdeps/v8/include/v8-debug.h10
-rw-r--r--deps/v8/include/v8-preparser.h7
-rw-r--r--deps/v8/include/v8-profiler.h27
-rw-r--r--deps/v8/include/v8-testing.h7
-rw-r--r--deps/v8/include/v8.h237
-rw-r--r--deps/v8/preparser/preparser-process.cc6
-rw-r--r--deps/v8/samples/lineprocessor.cc38
-rw-r--r--deps/v8/samples/process.cc14
-rw-r--r--deps/v8/samples/shell.cc2
-rwxr-xr-xdeps/v8/src/SConscript29
-rw-r--r--deps/v8/src/accessors.cc143
-rw-r--r--deps/v8/src/accessors.h4
-rw-r--r--deps/v8/src/api.cc371
-rw-r--r--deps/v8/src/api.h139
-rw-r--r--deps/v8/src/arm/assembler-arm-inl.h141
-rw-r--r--deps/v8/src/arm/assembler-arm.cc249
-rw-r--r--deps/v8/src/arm/assembler-arm.h144
-rw-r--r--deps/v8/src/arm/builtins-arm.cc68
-rw-r--r--deps/v8/src/arm/code-stubs-arm.cc376
-rw-r--r--deps/v8/src/arm/code-stubs-arm.h4
-rw-r--r--deps/v8/src/arm/codegen-arm.cc27
-rw-r--r--deps/v8/src/arm/constants-arm.h12
-rw-r--r--deps/v8/src/arm/debug-arm.cc4
-rw-r--r--deps/v8/src/arm/deoptimizer-arm.cc162
-rw-r--r--deps/v8/src/arm/disasm-arm.cc31
-rw-r--r--deps/v8/src/arm/full-codegen-arm.cc326
-rw-r--r--deps/v8/src/arm/ic-arm.cc271
-rw-r--r--deps/v8/src/arm/lithium-arm.cc296
-rw-r--r--deps/v8/src/arm/lithium-arm.h573
-rw-r--r--deps/v8/src/arm/lithium-codegen-arm.cc1122
-rw-r--r--deps/v8/src/arm/lithium-codegen-arm.h81
-rw-r--r--deps/v8/src/arm/macro-assembler-arm.cc359
-rw-r--r--deps/v8/src/arm/macro-assembler-arm.h95
-rw-r--r--deps/v8/src/arm/regexp-macro-assembler-arm.cc11
-rw-r--r--deps/v8/src/arm/regexp-macro-assembler-arm.h10
-rw-r--r--deps/v8/src/arm/simulator-arm.cc266
-rw-r--r--deps/v8/src/arm/simulator-arm.h36
-rw-r--r--deps/v8/src/arm/stub-cache-arm.cc342
-rw-r--r--deps/v8/src/array.js153
-rw-r--r--deps/v8/src/assembler.cc61
-rw-r--r--deps/v8/src/assembler.h26
-rw-r--r--deps/v8/src/ast.cc62
-rw-r--r--deps/v8/src/ast.h411
-rw-r--r--deps/v8/src/atomicops.h4
-rw-r--r--deps/v8/src/bootstrapper.cc807
-rw-r--r--deps/v8/src/bootstrapper.h4
-rw-r--r--deps/v8/src/builtins.cc45
-rw-r--r--deps/v8/src/builtins.h10
-rw-r--r--deps/v8/src/checks.h8
-rw-r--r--deps/v8/src/code-stubs.cc28
-rw-r--r--deps/v8/src/code-stubs.h61
-rw-r--r--deps/v8/src/collection.js27
-rw-r--r--deps/v8/src/compilation-cache.cc38
-rw-r--r--deps/v8/src/compilation-cache.h21
-rw-r--r--deps/v8/src/compiler.cc561
-rw-r--r--deps/v8/src/compiler.h198
-rw-r--r--deps/v8/src/contexts.cc65
-rw-r--r--deps/v8/src/contexts.h69
-rw-r--r--deps/v8/src/conversions-inl.h36
-rw-r--r--deps/v8/src/conversions.h11
-rw-r--r--deps/v8/src/counters.cc26
-rw-r--r--deps/v8/src/counters.h60
-rw-r--r--deps/v8/src/cpu-profiler.h2
-rw-r--r--deps/v8/src/d8.cc503
-rw-r--r--deps/v8/src/d8.h24
-rw-r--r--deps/v8/src/date.js41
-rw-r--r--deps/v8/src/dateparser-inl.h3
-rw-r--r--deps/v8/src/debug-debugger.js38
-rw-r--r--deps/v8/src/debug.cc340
-rw-r--r--deps/v8/src/debug.h24
-rw-r--r--deps/v8/src/deoptimizer.cc440
-rw-r--r--deps/v8/src/deoptimizer.h59
-rw-r--r--deps/v8/src/disassembler.cc4
-rw-r--r--deps/v8/src/elements.cc119
-rw-r--r--deps/v8/src/execution.cc61
-rw-r--r--deps/v8/src/execution.h5
-rw-r--r--deps/v8/src/extensions/statistics-extension.cc153
-rw-r--r--deps/v8/src/extensions/statistics-extension.h49
-rw-r--r--deps/v8/src/factory.cc183
-rw-r--r--deps/v8/src/factory.h38
-rw-r--r--deps/v8/src/flag-definitions.h66
-rw-r--r--deps/v8/src/flags.cc14
-rw-r--r--deps/v8/src/frames.cc24
-rw-r--r--deps/v8/src/frames.h2
-rw-r--r--deps/v8/src/full-codegen.cc132
-rw-r--r--deps/v8/src/full-codegen.h46
-rw-r--r--deps/v8/src/gdb-jit.cc128
-rw-r--r--deps/v8/src/global-handles.cc8
-rw-r--r--deps/v8/src/global-handles.h3
-rw-r--r--deps/v8/src/globals.h30
-rw-r--r--deps/v8/src/handles-inl.h30
-rw-r--r--deps/v8/src/handles.cc184
-rw-r--r--deps/v8/src/handles.h37
-rw-r--r--deps/v8/src/hashmap.h8
-rw-r--r--deps/v8/src/heap-inl.h74
-rw-r--r--deps/v8/src/heap.cc920
-rw-r--r--deps/v8/src/heap.h309
-rw-r--r--deps/v8/src/hydrogen-instructions.cc209
-rw-r--r--deps/v8/src/hydrogen-instructions.h500
-rw-r--r--deps/v8/src/hydrogen.cc2030
-rw-r--r--deps/v8/src/hydrogen.h244
-rw-r--r--deps/v8/src/ia32/assembler-ia32-inl.h16
-rw-r--r--deps/v8/src/ia32/assembler-ia32.cc33
-rw-r--r--deps/v8/src/ia32/assembler-ia32.h21
-rw-r--r--deps/v8/src/ia32/builtins-ia32.cc45
-rw-r--r--deps/v8/src/ia32/code-stubs-ia32.cc208
-rw-r--r--deps/v8/src/ia32/deoptimizer-ia32.cc158
-rw-r--r--deps/v8/src/ia32/disasm-ia32.cc20
-rw-r--r--deps/v8/src/ia32/full-codegen-ia32.cc294
-rw-r--r--deps/v8/src/ia32/ic-ia32.cc232
-rw-r--r--deps/v8/src/ia32/lithium-codegen-ia32.cc775
-rw-r--r--deps/v8/src/ia32/lithium-codegen-ia32.h48
-rw-r--r--deps/v8/src/ia32/lithium-ia32.cc347
-rw-r--r--deps/v8/src/ia32/lithium-ia32.h578
-rw-r--r--deps/v8/src/ia32/macro-assembler-ia32.cc257
-rw-r--r--deps/v8/src/ia32/macro-assembler-ia32.h37
-rw-r--r--deps/v8/src/ia32/regexp-macro-assembler-ia32.cc5
-rw-r--r--deps/v8/src/ia32/regexp-macro-assembler-ia32.h9
-rw-r--r--deps/v8/src/ia32/stub-cache-ia32.cc283
-rw-r--r--deps/v8/src/ic-inl.h10
-rw-r--r--deps/v8/src/ic.cc136
-rw-r--r--deps/v8/src/ic.h14
-rw-r--r--deps/v8/src/incremental-marking-inl.h29
-rw-r--r--deps/v8/src/incremental-marking.cc288
-rw-r--r--deps/v8/src/incremental-marking.h47
-rw-r--r--deps/v8/src/interface.cc14
-rw-r--r--deps/v8/src/interface.h42
-rw-r--r--deps/v8/src/isolate.cc141
-rw-r--r--deps/v8/src/isolate.h69
-rw-r--r--deps/v8/src/json-parser.h210
-rw-r--r--deps/v8/src/json.js33
-rw-r--r--deps/v8/src/jsregexp.cc342
-rw-r--r--deps/v8/src/jsregexp.h133
-rw-r--r--deps/v8/src/lithium-allocator.cc2
-rw-r--r--deps/v8/src/lithium-allocator.h6
-rw-r--r--deps/v8/src/lithium.cc198
-rw-r--r--deps/v8/src/lithium.h98
-rw-r--r--deps/v8/src/liveedit-debugger.js18
-rw-r--r--deps/v8/src/liveedit.cc269
-rw-r--r--deps/v8/src/liveedit.h6
-rw-r--r--deps/v8/src/liveobjectlist.cc4
-rw-r--r--deps/v8/src/log.cc113
-rw-r--r--deps/v8/src/log.h25
-rw-r--r--deps/v8/src/mark-compact-inl.h26
-rw-r--r--deps/v8/src/mark-compact.cc1156
-rw-r--r--deps/v8/src/mark-compact.h126
-rw-r--r--deps/v8/src/messages.cc15
-rw-r--r--deps/v8/src/messages.js69
-rw-r--r--deps/v8/src/mips/assembler-mips-inl.h10
-rw-r--r--deps/v8/src/mips/assembler-mips.cc23
-rw-r--r--deps/v8/src/mips/assembler-mips.h43
-rw-r--r--deps/v8/src/mips/builtins-mips.cc63
-rw-r--r--deps/v8/src/mips/code-stubs-mips.cc264
-rw-r--r--deps/v8/src/mips/deoptimizer-mips.cc155
-rw-r--r--deps/v8/src/mips/full-codegen-mips.cc300
-rw-r--r--deps/v8/src/mips/ic-mips.cc274
-rw-r--r--deps/v8/src/mips/lithium-codegen-mips.cc819
-rw-r--r--deps/v8/src/mips/lithium-codegen-mips.h58
-rw-r--r--deps/v8/src/mips/lithium-mips.cc306
-rw-r--r--deps/v8/src/mips/lithium-mips.h552
-rw-r--r--deps/v8/src/mips/macro-assembler-mips.cc180
-rw-r--r--deps/v8/src/mips/macro-assembler-mips.h41
-rw-r--r--deps/v8/src/mips/regexp-macro-assembler-mips.cc5
-rw-r--r--deps/v8/src/mips/regexp-macro-assembler-mips.h9
-rw-r--r--deps/v8/src/mips/simulator-mips.cc9
-rw-r--r--deps/v8/src/mips/stub-cache-mips.cc269
-rw-r--r--deps/v8/src/mirror-debugger.js162
-rw-r--r--deps/v8/src/mksnapshot.cc100
-rw-r--r--deps/v8/src/objects-debug.cc296
-rw-r--r--deps/v8/src/objects-inl.h1004
-rw-r--r--deps/v8/src/objects-printer.cc121
-rw-r--r--deps/v8/src/objects-visiting-inl.h514
-rw-r--r--deps/v8/src/objects-visiting.h220
-rw-r--r--deps/v8/src/objects.cc3114
-rw-r--r--deps/v8/src/objects.h1289
-rw-r--r--deps/v8/src/optimizing-compiler-thread.cc127
-rw-r--r--deps/v8/src/optimizing-compiler-thread.h101
-rw-r--r--deps/v8/src/parser.cc528
-rw-r--r--deps/v8/src/parser.h56
-rw-r--r--deps/v8/src/platform-linux.cc167
-rw-r--r--deps/v8/src/platform-nullos.cc7
-rw-r--r--deps/v8/src/platform-openbsd.cc5
-rw-r--r--deps/v8/src/platform-posix.cc5
-rw-r--r--deps/v8/src/platform-solaris.cc8
-rw-r--r--deps/v8/src/platform-win32.cc5
-rw-r--r--deps/v8/src/platform.h27
-rw-r--r--deps/v8/src/preparser.cc13
-rw-r--r--deps/v8/src/profile-generator-inl.h1
-rw-r--r--deps/v8/src/profile-generator.cc140
-rw-r--r--deps/v8/src/profile-generator.h4
-rw-r--r--deps/v8/src/property-details.h72
-rw-r--r--deps/v8/src/property.cc64
-rw-r--r--deps/v8/src/property.h167
-rw-r--r--deps/v8/src/regexp-macro-assembler-irregexp.cc6
-rw-r--r--deps/v8/src/regexp-macro-assembler-irregexp.h2
-rw-r--r--deps/v8/src/regexp-macro-assembler.cc6
-rw-r--r--deps/v8/src/regexp.js9
-rw-r--r--deps/v8/src/rewriter.cc14
-rw-r--r--deps/v8/src/runtime-profiler.cc29
-rw-r--r--deps/v8/src/runtime.cc1919
-rw-r--r--deps/v8/src/runtime.h26
-rwxr-xr-xdeps/v8/src/scanner.cc1
-rw-r--r--deps/v8/src/scopeinfo.cc9
-rw-r--r--deps/v8/src/scopes.cc215
-rw-r--r--deps/v8/src/scopes.h32
-rw-r--r--deps/v8/src/serialize.cc710
-rw-r--r--deps/v8/src/serialize.h233
-rw-r--r--deps/v8/src/smart-array-pointer.h100
-rw-r--r--deps/v8/src/smart-pointers.h139
-rw-r--r--deps/v8/src/snapshot-common.cc79
-rw-r--r--deps/v8/src/snapshot-empty.cc8
-rw-r--r--deps/v8/src/snapshot.h11
-rw-r--r--deps/v8/src/spaces-inl.h4
-rw-r--r--deps/v8/src/spaces.cc146
-rw-r--r--deps/v8/src/spaces.h87
-rw-r--r--deps/v8/src/store-buffer.cc6
-rw-r--r--deps/v8/src/store-buffer.h2
-rw-r--r--deps/v8/src/string-stream.cc7
-rw-r--r--deps/v8/src/stub-cache.cc127
-rw-r--r--deps/v8/src/stub-cache.h47
-rw-r--r--deps/v8/src/transitions-inl.h220
-rw-r--r--deps/v8/src/transitions.cc160
-rw-r--r--deps/v8/src/transitions.h207
-rw-r--r--deps/v8/src/type-info.cc154
-rw-r--r--deps/v8/src/type-info.h26
-rw-r--r--deps/v8/src/unicode-inl.h2
-rw-r--r--deps/v8/src/unicode.h4
-rw-r--r--deps/v8/src/utils.h62
-rw-r--r--deps/v8/src/v8-counters.cc58
-rw-r--r--deps/v8/src/v8-counters.h144
-rw-r--r--deps/v8/src/v8.cc11
-rw-r--r--deps/v8/src/v8globals.h69
-rw-r--r--deps/v8/src/v8threads.cc23
-rw-r--r--deps/v8/src/v8threads.h5
-rw-r--r--deps/v8/src/v8utils.cc9
-rw-r--r--deps/v8/src/v8utils.h5
-rw-r--r--deps/v8/src/variables.cc7
-rw-r--r--deps/v8/src/variables.h15
-rw-r--r--deps/v8/src/version.cc6
-rw-r--r--deps/v8/src/vm-state-inl.h2
-rw-r--r--deps/v8/src/x64/assembler-x64-inl.h17
-rw-r--r--deps/v8/src/x64/assembler-x64.cc22
-rw-r--r--deps/v8/src/x64/assembler-x64.h17
-rw-r--r--deps/v8/src/x64/builtins-x64.cc47
-rw-r--r--deps/v8/src/x64/code-stubs-x64.cc256
-rw-r--r--deps/v8/src/x64/deoptimizer-x64.cc158
-rw-r--r--deps/v8/src/x64/disasm-x64.cc3
-rw-r--r--deps/v8/src/x64/full-codegen-x64.cc297
-rw-r--r--deps/v8/src/x64/ic-x64.cc238
-rw-r--r--deps/v8/src/x64/lithium-codegen-x64.cc927
-rw-r--r--deps/v8/src/x64/lithium-codegen-x64.h44
-rw-r--r--deps/v8/src/x64/lithium-x64.cc364
-rw-r--r--deps/v8/src/x64/lithium-x64.h512
-rw-r--r--deps/v8/src/x64/macro-assembler-x64.cc402
-rw-r--r--deps/v8/src/x64/macro-assembler-x64.h65
-rw-r--r--deps/v8/src/x64/regexp-macro-assembler-x64.cc8
-rw-r--r--deps/v8/src/x64/stub-cache-x64.cc272
-rw-r--r--deps/v8/src/zone-inl.h17
-rw-r--r--deps/v8/src/zone.cc10
-rw-r--r--deps/v8/src/zone.h9
-rw-r--r--deps/v8/test/benchmarks/testcfg.py5
-rw-r--r--deps/v8/test/cctest/cctest.gyp2
-rw-r--r--deps/v8/test/cctest/cctest.h19
-rw-r--r--deps/v8/test/cctest/cctest.status21
-rw-r--r--deps/v8/test/cctest/test-alloc.cc23
-rw-r--r--deps/v8/test/cctest/test-api.cc798
-rw-r--r--deps/v8/test/cctest/test-ast.cc6
-rw-r--r--deps/v8/test/cctest/test-compiler.cc76
-rw-r--r--deps/v8/test/cctest/test-dataflow.cc4
-rw-r--r--deps/v8/test/cctest/test-debug.cc167
-rw-r--r--deps/v8/test/cctest/test-decls.cc327
-rw-r--r--deps/v8/test/cctest/test-dictionary.cc28
-rw-r--r--deps/v8/test/cctest/test-flags.cc15
-rw-r--r--deps/v8/test/cctest/test-func-name-inference.cc11
-rw-r--r--deps/v8/test/cctest/test-heap-profiler.cc69
-rw-r--r--deps/v8/test/cctest/test-heap.cc550
-rw-r--r--deps/v8/test/cctest/test-liveedit.cc6
-rw-r--r--deps/v8/test/cctest/test-mark-compact.cc25
-rwxr-xr-xdeps/v8/test/cctest/test-parsing.cc40
-rw-r--r--deps/v8/test/cctest/test-platform-linux.cc6
-rw-r--r--deps/v8/test/cctest/test-platform-win32.cc7
-rw-r--r--deps/v8/test/cctest/test-random.cc6
-rw-r--r--deps/v8/test/cctest/test-regexp.cc119
-rw-r--r--deps/v8/test/cctest/test-serialize.cc363
-rw-r--r--deps/v8/test/cctest/test-sockets.cc2
-rw-r--r--deps/v8/test/cctest/test-strings.cc36
-rw-r--r--deps/v8/test/cctest/test-utils.cc16
-rw-r--r--deps/v8/test/cctest/test-weakmaps.cc3
-rw-r--r--deps/v8/test/cctest/testcfg.py70
-rw-r--r--deps/v8/test/es5conform/testcfg.py5
-rw-r--r--deps/v8/test/message/testcfg.py97
-rw-r--r--deps/v8/test/message/try-catch-finally-no-message.out52
-rw-r--r--deps/v8/test/mjsunit/accessor-map-sharing.js18
-rw-r--r--deps/v8/test/mjsunit/array-bounds-check-removal.js39
-rw-r--r--deps/v8/test/mjsunit/array-iteration.js2
-rw-r--r--deps/v8/test/mjsunit/array-literal-transitions.js2
-rw-r--r--deps/v8/test/mjsunit/assert-opt-and-deopt.js2
-rw-r--r--deps/v8/test/mjsunit/bugs/bug-2337.js53
-rw-r--r--deps/v8/test/mjsunit/compiler/alloc-object-huge.js4
-rw-r--r--deps/v8/test/mjsunit/compiler/inline-accessors.js368
-rw-r--r--deps/v8/test/mjsunit/compiler/inline-arguments.js88
-rw-r--r--deps/v8/test/mjsunit/compiler/inline-construct.js98
-rw-r--r--deps/v8/test/mjsunit/compiler/inline-literals.js39
-rw-r--r--deps/v8/test/mjsunit/compiler/optimized-closures.js57
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-gvn.js5
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-or.js8
-rw-r--r--deps/v8/test/mjsunit/compiler/uint32.js173
-rw-r--r--deps/v8/test/mjsunit/count-based-osr.js3
-rw-r--r--deps/v8/test/mjsunit/d8-os.js6
-rw-r--r--deps/v8/test/mjsunit/date.js22
-rw-r--r--deps/v8/test/mjsunit/debug-break-inline.js1
-rw-r--r--deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js34
-rw-r--r--deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js31
-rw-r--r--deps/v8/test/mjsunit/debug-liveedit-double-call.js142
-rw-r--r--deps/v8/test/mjsunit/debug-liveedit-restart-frame.js153
-rw-r--r--deps/v8/test/mjsunit/debug-multiple-breakpoints.js2
-rw-r--r--deps/v8/test/mjsunit/debug-script-breakpoints-closure.js67
-rw-r--r--deps/v8/test/mjsunit/debug-script-breakpoints-nested.js82
-rw-r--r--deps/v8/test/mjsunit/debug-script.js6
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part1.js190
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part2.js83
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part3.js80
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part4.js80
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part5.js77
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part6.js79
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part7.js79
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part8.js234
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope.js423
-rw-r--r--deps/v8/test/mjsunit/delete-non-configurable.js74
-rw-r--r--deps/v8/test/mjsunit/deopt-minus-zero.js56
-rw-r--r--deps/v8/test/mjsunit/elements-kind.js2
-rw-r--r--deps/v8/test/mjsunit/elements-transition-hoisting.js23
-rw-r--r--deps/v8/test/mjsunit/eval-stack-trace.js203
-rw-r--r--deps/v8/test/mjsunit/external-array.js293
-rw-r--r--deps/v8/test/mjsunit/fuzz-natives-part1.js222
-rw-r--r--deps/v8/test/mjsunit/fuzz-natives-part2.js222
-rw-r--r--deps/v8/test/mjsunit/fuzz-natives-part3.js222
-rw-r--r--deps/v8/test/mjsunit/fuzz-natives-part4.js222
-rw-r--r--deps/v8/test/mjsunit/fuzz-natives.js219
-rw-r--r--deps/v8/test/mjsunit/greedy.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/block-conflicts.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/block-let-crankshaft.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/collections.js22
-rw-r--r--deps/v8/test/mjsunit/harmony/debug-blockscopes.js4
-rw-r--r--deps/v8/test/mjsunit/harmony/module-linking.js183
-rw-r--r--deps/v8/test/mjsunit/harmony/module-parsing.js31
-rw-r--r--deps/v8/test/mjsunit/harmony/module-recompile.js87
-rw-r--r--deps/v8/test/mjsunit/harmony/module-resolution.js17
-rw-r--r--deps/v8/test/mjsunit/json.js4
-rw-r--r--deps/v8/test/mjsunit/limit-locals.js9
-rw-r--r--deps/v8/test/mjsunit/math-floor-negative.js59
-rw-r--r--deps/v8/test/mjsunit/math-floor-of-div-minus-zero.js40
-rw-r--r--deps/v8/test/mjsunit/math-floor-part1.js88
-rw-r--r--deps/v8/test/mjsunit/math-floor-part2.js76
-rw-r--r--deps/v8/test/mjsunit/math-floor-part3.js78
-rw-r--r--deps/v8/test/mjsunit/math-floor-part4.js76
-rw-r--r--deps/v8/test/mjsunit/math-floor.js159
-rw-r--r--deps/v8/test/mjsunit/mirror-object.js52
-rw-r--r--deps/v8/test/mjsunit/mjsunit.js2
-rw-r--r--deps/v8/test/mjsunit/mjsunit.status52
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive-part1.js491
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive-part10.js470
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive-part2.js525
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive-part3.js532
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive-part4.js509
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive-part5.js505
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive-part6.js554
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive-part7.js497
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive-part8.js526
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive-part9.js533
-rw-r--r--deps/v8/test/mjsunit/mul-exhaustive.js4629
-rw-r--r--deps/v8/test/mjsunit/numops-fuzz-part1.js1172
-rw-r--r--deps/v8/test/mjsunit/numops-fuzz-part2.js1178
-rw-r--r--deps/v8/test/mjsunit/numops-fuzz-part3.js1178
-rw-r--r--deps/v8/test/mjsunit/numops-fuzz-part4.js1177
-rw-r--r--deps/v8/test/mjsunit/numops-fuzz.js4609
-rw-r--r--deps/v8/test/mjsunit/object-define-property.js109
-rw-r--r--deps/v8/test/mjsunit/packed-elements.js4
-rw-r--r--deps/v8/test/mjsunit/parse-int-float.js8
-rwxr-xr-x[-rw-r--r--]deps/v8/test/mjsunit/pixel-array-rounding.js2
-rwxr-xr-x[-rw-r--r--]deps/v8/test/mjsunit/regexp-capture-3.js0
-rw-r--r--deps/v8/test/mjsunit/regexp-global.js113
-rw-r--r--deps/v8/test/mjsunit/regexp-results-cache.js78
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1117.js15
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1118.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-131994.js70
-rw-r--r--deps/v8/test/mjsunit/regress/regress-136048.js34
-rw-r--r--deps/v8/test/mjsunit/regress/regress-137768.js73
-rw-r--r--deps/v8/test/mjsunit/regress/regress-143967.js34
-rw-r--r--deps/v8/test/mjsunit/regress/regress-148378.js38
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1563.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1591.js48
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1969.js5045
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2119.js36
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2172.js35
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2185-2.js145
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2185.js36
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2186.js49
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2193.js58
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2219.js32
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2225.js65
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2226.js36
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2249.js33
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2250.js68
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2261.js113
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2284.js32
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2285.js32
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2286.js32
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2289.js34
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2294.js70
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2296.js40
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2318.js66
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2322.js36
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2326.js54
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2336.js53
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2339.js59
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2346.js123
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2373.js29
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2374.js33
-rw-r--r--deps/v8/test/mjsunit/regress/regress-builtin-array-op.js38
-rw-r--r--deps/v8/test/mjsunit/regress/regress-cnlt-elements.js43
-rw-r--r--deps/v8/test/mjsunit/regress/regress-cnlt-enum-indices.js45
-rw-r--r--deps/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js46
-rw-r--r--deps/v8/test/mjsunit/regress/regress-convert-enum.js60
-rw-r--r--deps/v8/test/mjsunit/regress/regress-convert-enum2.js46
-rw-r--r--deps/v8/test/mjsunit/regress/regress-convert-transition.js40
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-119926.js4
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-125148.js72
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-134609.js59
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-135008.js45
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-135066.js53
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-137689.js47
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-138887.js48
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-140083.js44
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-142087.js38
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-142218.js44
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-145961.js39
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-146910.js38
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-147475.js48
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-148376.js35
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-150545.js53
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-150729.js39
-rw-r--r--deps/v8/test/mjsunit/regress/regress-debug-code-recompilation.js3
-rw-r--r--deps/v8/test/mjsunit/regress/regress-load-elements.js49
-rw-r--r--deps/v8/test/mjsunit/regress/regress-undefined-store-keyed-fast-element.js37
-rw-r--r--deps/v8/test/mjsunit/str-to-num.js9
-rw-r--r--deps/v8/test/mjsunit/string-charcodeat.js3
-rw-r--r--deps/v8/test/mjsunit/testcfg.py83
-rw-r--r--deps/v8/test/mjsunit/typed-array-slice.js61
-rw-r--r--deps/v8/test/mjsunit/unbox-double-arrays.js2
-rw-r--r--deps/v8/test/mozilla/mozilla.status95
-rw-r--r--deps/v8/test/mozilla/testcfg.py124
-rw-r--r--deps/v8/test/preparser/preparser.status5
-rw-r--r--deps/v8/test/preparser/strict-identifiers.pyt2
-rw-r--r--deps/v8/test/preparser/testcfg.py106
-rw-r--r--deps/v8/test/sputnik/sputnik.status2
-rw-r--r--deps/v8/test/sputnik/testcfg.py5
-rw-r--r--deps/v8/test/test262/test262.status28
-rw-r--r--deps/v8/test/test262/testcfg.py104
-rwxr-xr-xdeps/v8/tools/android-build.sh0
-rwxr-xr-xdeps/v8/tools/android-ll-prof.sh69
-rwxr-xr-xdeps/v8/tools/android-run.py109
-rwxr-xr-xdeps/v8/tools/android-sync.sh105
-rwxr-xr-x[-rw-r--r--]deps/v8/tools/bash-completion.sh0
-rwxr-xr-x[-rw-r--r--]deps/v8/tools/check-static-initializers.sh0
-rw-r--r--deps/v8/tools/common-includes.sh37
-rwxr-xr-x[-rw-r--r--]deps/v8/tools/fuzz-harness.sh0
-rw-r--r--deps/v8/tools/gen-postmortem-metadata.py15
-rwxr-xr-xdeps/v8/tools/grokdump.py235
-rw-r--r--deps/v8/tools/gyp/v8.gyp73
-rwxr-xr-xdeps/v8/tools/linux-tick-processor10
-rwxr-xr-xdeps/v8/tools/ll_prof.py27
-rwxr-xr-x[-rw-r--r--]deps/v8/tools/merge-to-branch.sh4
-rwxr-xr-xdeps/v8/tools/presubmit.py1
-rwxr-xr-xdeps/v8/tools/push-to-trunk.sh18
-rwxr-xr-xdeps/v8/tools/run-tests.py364
-rwxr-xr-xdeps/v8/tools/status-file-converter.py39
-rwxr-xr-xdeps/v8/tools/test-server.py224
-rwxr-xr-xdeps/v8/tools/test-wrapper-gypbuild.py21
-rwxr-xr-xdeps/v8/tools/test.py20
-rw-r--r--deps/v8/tools/testrunner/README174
-rw-r--r--deps/v8/tools/testrunner/__init__.py26
-rw-r--r--deps/v8/tools/testrunner/local/__init__.py26
-rw-r--r--deps/v8/tools/testrunner/local/commands.py153
-rw-r--r--deps/v8/tools/testrunner/local/execution.py182
-rw-r--r--deps/v8/tools/testrunner/local/old_statusfile.py460
-rw-r--r--deps/v8/tools/testrunner/local/progress.py238
-rw-r--r--deps/v8/tools/testrunner/local/statusfile.py145
-rw-r--r--deps/v8/tools/testrunner/local/testsuite.py184
-rw-r--r--deps/v8/tools/testrunner/local/utils.py108
-rw-r--r--deps/v8/tools/testrunner/local/verbose.py99
-rw-r--r--deps/v8/tools/testrunner/network/__init__.py26
-rw-r--r--deps/v8/tools/testrunner/network/distro.py90
-rw-r--r--deps/v8/tools/testrunner/network/endpoint.py124
-rw-r--r--deps/v8/tools/testrunner/network/network_execution.py253
-rw-r--r--deps/v8/tools/testrunner/network/perfdata.py120
-rw-r--r--deps/v8/tools/testrunner/objects/__init__.py26
-rw-r--r--deps/v8/tools/testrunner/objects/context.py50
-rw-r--r--deps/v8/tools/testrunner/objects/output.py60
-rw-r--r--deps/v8/tools/testrunner/objects/peer.py80
-rw-r--r--deps/v8/tools/testrunner/objects/testcase.py83
-rw-r--r--deps/v8/tools/testrunner/objects/workpacket.py90
-rw-r--r--deps/v8/tools/testrunner/server/__init__.py26
-rw-r--r--deps/v8/tools/testrunner/server/compression.py112
-rw-r--r--deps/v8/tools/testrunner/server/constants.py51
-rw-r--r--deps/v8/tools/testrunner/server/daemon.py147
-rw-r--r--deps/v8/tools/testrunner/server/local_handler.py119
-rw-r--r--deps/v8/tools/testrunner/server/main.py245
-rw-r--r--deps/v8/tools/testrunner/server/presence_handler.py120
-rw-r--r--deps/v8/tools/testrunner/server/signatures.py63
-rw-r--r--deps/v8/tools/testrunner/server/status_handler.py112
-rw-r--r--deps/v8/tools/testrunner/server/work_handler.py150
-rw-r--r--deps/v8/tools/tickprocessor-driver.js4
-rw-r--r--deps/v8/tools/tickprocessor.js18
-rw-r--r--doc/api/addons.markdown87
-rw-r--r--doc/api/assert.markdown2
-rw-r--r--doc/api/buffer.markdown55
-rw-r--r--doc/api/child_process.markdown23
-rw-r--r--doc/api/cluster.markdown17
-rw-r--r--doc/api/crypto.markdown404
-rw-r--r--doc/api/debugger.markdown7
-rw-r--r--doc/api/dgram.markdown12
-rw-r--r--doc/api/documentation.markdown34
-rw-r--r--doc/api/domain.markdown6
-rw-r--r--doc/api/events.markdown18
-rw-r--r--doc/api/fs.markdown49
-rw-r--r--doc/api/http.markdown262
-rw-r--r--doc/api/https.markdown2
-rw-r--r--doc/api/net.markdown47
-rw-r--r--doc/api/os.markdown10
-rw-r--r--doc/api/path.markdown30
-rw-r--r--doc/api/process.markdown146
-rw-r--r--doc/api/stream.markdown529
-rw-r--r--doc/api/string_decoder.markdown8
-rw-r--r--doc/api/timers.markdown35
-rw-r--r--doc/api/tls.markdown49
-rw-r--r--doc/api/util.markdown46
-rw-r--r--doc/api/zlib.markdown15
-rw-r--r--doc/api_assets/style.css24
-rw-r--r--doc/blog/feature/streams2.md79
-rw-r--r--doc/blog/release/v0.9.0.md61
-rw-r--r--lib/_debugger.js21
-rw-r--r--lib/_stream_duplex.js69
-rw-r--r--lib/_stream_passthrough.js41
-rw-r--r--lib/_stream_readable.js846
-rw-r--r--lib/_stream_transform.js203
-rw-r--r--lib/_stream_writable.js328
-rw-r--r--lib/assert.js4
-rw-r--r--lib/buffer.js697
-rw-r--r--lib/buffer_ieee754.js116
-rw-r--r--lib/child_process.js259
-rw-r--r--lib/cluster.js38
-rw-r--r--lib/console.js67
-rw-r--r--lib/crypto.js473
-rw-r--r--lib/dgram.js185
-rw-r--r--lib/dns.js8
-rw-r--r--lib/domain.js31
-rw-r--r--lib/events.js69
-rw-r--r--lib/fs.js710
-rw-r--r--lib/http.js369
-rw-r--r--lib/https.js62
-rw-r--r--lib/module.js31
-rw-r--r--lib/net.js676
-rw-r--r--lib/os.js5
-rw-r--r--lib/path.js90
-rw-r--r--lib/punycode.js32
-rw-r--r--lib/readline.js57
-rw-r--r--lib/repl.js63
-rw-r--r--lib/stream.js23
-rw-r--r--lib/string_decoder.js33
-rw-r--r--lib/timers.js209
-rw-r--r--lib/tls.js798
-rw-r--r--lib/tty.js37
-rw-r--r--lib/url.js386
-rw-r--r--lib/util.js49
-rw-r--r--lib/zlib.js208
-rw-r--r--node.gyp167
-rw-r--r--src/cares_wrap.cc225
-rw-r--r--src/eio-emul.h71
-rw-r--r--src/ev-emul.h268
-rw-r--r--src/fs_event_wrap.cc11
-rw-r--r--src/handle_wrap.cc22
-rw-r--r--src/handle_wrap.h2
-rw-r--r--src/node.cc984
-rw-r--r--src/node.h34
-rw-r--r--src/node.js389
-rw-r--r--src/node_buffer.cc404
-rw-r--r--src/node_buffer.h33
-rw-r--r--src/node_constants.cc7
-rw-r--r--src/node_counters.cc149
-rw-r--r--src/node_counters.h53
-rw-r--r--src/node_crypto.cc1589
-rw-r--r--src/node_crypto.h79
-rw-r--r--src/node_dtrace.cc92
-rw-r--r--src/node_extensions.h5
-rw-r--r--src/node_file.cc31
-rw-r--r--src/node_http_parser.cc50
-rw-r--r--src/node_internals.h11
-rw-r--r--src/node_io_watcher.cc166
-rw-r--r--src/node_io_watcher.h64
-rw-r--r--src/node_os.cc33
-rw-r--r--src/node_signal_watcher.cc119
-rw-r--r--src/node_signal_watcher.h62
-rw-r--r--src/node_systemtap.d51
-rw-r--r--src/node_version.h4
-rw-r--r--src/node_win32_etw_provider-inl.h120
-rw-r--r--src/node_win32_etw_provider.cc114
-rw-r--r--src/node_win32_etw_provider.h8
-rw-r--r--src/node_win32_perfctr_provider.cc345
-rw-r--r--src/node_win32_perfctr_provider.h55
-rw-r--r--src/node_zlib.cc29
-rw-r--r--src/perfctr_macros.py9
-rw-r--r--src/pipe_wrap.cc31
-rw-r--r--src/process_wrap.cc8
-rw-r--r--src/res/node_etw_provider.man77
-rw-r--r--src/res/node_perfctr_provider.man107
-rw-r--r--src/signal_wrap.cc132
-rw-r--r--src/stream_wrap.cc134
-rw-r--r--src/stream_wrap.h3
-rw-r--r--src/tcp_wrap.cc33
-rw-r--r--src/timer_wrap.cc2
-rw-r--r--src/tree.h768
-rw-r--r--src/tty_wrap.cc33
-rw-r--r--src/udp_wrap.cc78
-rw-r--r--src/udp_wrap.h54
-rw-r--r--src/v8_typed_array.cc279
-rw-r--r--src/v8_typed_array.h2
-rw-r--r--src/v8_typed_array_bswap.h201
-rw-r--r--src/v8abbr.h14
-rw-r--r--src/v8ustack.d468
-rw-r--r--test/addons/async-hello-world/binding.cc65
-rw-r--r--test/addons/async-hello-world/binding.gyp8
-rw-r--r--test/addons/async-hello-world/test.js15
-rw-r--r--test/addons/hello-world-function-export/binding.cc15
-rw-r--r--test/addons/hello-world-function-export/binding.gyp8
-rw-r--r--test/addons/hello-world-function-export/test.js4
-rw-r--r--test/common.js31
-rw-r--r--test/disabled/test-debug-brk-file.js108
-rw-r--r--test/disabled/test-eio-race.js (renamed from test/simple/test-eio-race.js)0
-rw-r--r--test/disabled/test-eio-race2.js43
-rw-r--r--test/disabled/test-eio-race4.js (renamed from test/simple/test-eio-race4.js)0
-rw-r--r--test/disabled/test-fs-sendfile.js52
-rw-r--r--test/fixtures/GH-892-request.js6
-rw-r--r--test/fixtures/breakpoints_utf8.js4
-rw-r--r--test/fixtures/catch-stdout-error.js2
-rw-r--r--test/fixtures/child-process-spawn-node.js8
-rw-r--r--test/fixtures/create-file.js4
-rw-r--r--test/fixtures/debug-target.js4
-rw-r--r--test/fixtures/fork2.js23
-rw-r--r--test/fixtures/test-fs-readfile-error.js22
-rw-r--r--test/fixtures/x1024.txt1
-rw-r--r--test/internet/test-http-dns-fail.js (renamed from test/simple/test-http-dns-fail.js)0
-rw-r--r--test/internet/test-net-connect-timeout.js (renamed from test/simple/test-net-connect-timeout.js)0
-rw-r--r--test/message/error_exit.js29
-rw-r--r--test/message/error_exit.out14
-rw-r--r--test/message/max_tick_depth.js30
-rw-r--r--test/message/max_tick_depth.out23
-rw-r--r--test/message/max_tick_depth_trace.js31
-rw-r--r--test/message/max_tick_depth_trace.out35
-rw-r--r--test/message/nexttick_throw.js33
-rw-r--r--test/message/nexttick_throw.out10
-rw-r--r--test/message/stdin_messages.out16
-rw-r--r--test/message/timeout_throw.js27
-rw-r--r--test/message/timeout_throw.out6
-rw-r--r--test/message/undefined_reference_in_new_context.js2
-rw-r--r--test/message/undefined_reference_in_new_context.out7
-rw-r--r--test/pummel/test-crypto-dh.js2
-rw-r--r--test/pummel/test-dh-regr.js2
-rw-r--r--test/pummel/test-dtrace-jsstack.js107
-rw-r--r--test/pummel/test-http-upload-timeout.js1
-rw-r--r--test/pummel/test-https-ci-reneg-attack.js2
-rw-r--r--test/pummel/test-https-large-response.js8
-rw-r--r--test/pummel/test-net-connect-econnrefused.js19
-rw-r--r--test/pummel/test-net-connect-memleak.js2
-rw-r--r--test/pummel/test-net-timeout2.js4
-rw-r--r--test/pummel/test-net-write-callbacks.js19
-rw-r--r--test/pummel/test-postmortem-findjsobjects.js99
-rw-r--r--test/pummel/test-postmortem-jsstack.js179
-rw-r--r--test/pummel/test-tls-ci-reneg-attack.js2
-rw-r--r--test/pummel/test-tls-connect-memleak.js2
-rw-r--r--test/pummel/test-tls-throttle.js9
-rw-r--r--test/simple/net-socket-readystate.js51
-rw-r--r--test/simple/test-arraybuffer-slice.js89
-rw-r--r--test/simple/test-buffer.js292
-rw-r--r--test/simple/test-child-process-cwd.js17
-rw-r--r--test/simple/test-child-process-disconnect.js2
-rw-r--r--test/simple/test-child-process-exec-error.js45
-rwxr-xr-xtest/simple/test-child-process-fork-exec-path.js57
-rw-r--r--test/simple/test-child-process-fork-getconnections.js106
-rw-r--r--test/simple/test-child-process-fork-net2.js87
-rw-r--r--test/simple/test-child-process-fork-ref.js57
-rw-r--r--test/simple/test-child-process-fork-ref2.js45
-rw-r--r--test/simple/test-child-process-fork2.js73
-rw-r--r--test/simple/test-child-process-fork3.js25
-rw-r--r--test/simple/test-child-process-ipc.js3
-rw-r--r--test/simple/test-child-process-kill-throw.js2
-rw-r--r--test/simple/test-child-process-stdio-inherit.js54
-rw-r--r--test/simple/test-cli-eval.js13
-rw-r--r--test/simple/test-cluster-dgram-1.js115
-rw-r--r--test/simple/test-cluster-dgram-2.js81
-rw-r--r--test/simple/test-cluster-eaddrinuse.js63
-rw-r--r--test/simple/test-cluster-http-pipe.js1
-rw-r--r--test/simple/test-cluster-listening-port.js44
-rw-r--r--test/simple/test-cluster-master-error.js5
-rw-r--r--test/simple/test-cluster-message.js2
-rw-r--r--test/simple/test-cluster-net-send.js67
-rw-r--r--test/simple/test-console-instance.js80
-rw-r--r--test/simple/test-console.js8
-rw-r--r--test/simple/test-crypto-binary-default.js690
-rw-r--r--test/simple/test-crypto-ecb.js2
-rw-r--r--test/simple/test-crypto-padding-aes256.js69
-rw-r--r--test/simple/test-crypto-padding.js2
-rw-r--r--test/simple/test-crypto-random.js2
-rw-r--r--test/simple/test-crypto.js312
-rw-r--r--test/simple/test-debug-brk-no-arg.js35
-rw-r--r--test/simple/test-debugger-client.js35
-rw-r--r--test/simple/test-debugger-repl-utf8.js155
-rw-r--r--test/simple/test-debugger-repl.js77
-rw-r--r--test/simple/test-dgram-broadcast-multi-process.js26
-rw-r--r--test/simple/test-dgram-implicit-bind.js49
-rw-r--r--test/simple/test-dgram-listen-after-bind.js43
-rw-r--r--test/simple/test-dgram-multicast-multi-process.js15
-rw-r--r--test/simple/test-dgram-multicast-setTTL.js22
-rw-r--r--test/simple/test-dgram-pingpong.js9
-rw-r--r--test/simple/test-dgram-unref.js39
-rw-r--r--test/simple/test-domain-http-server.js12
-rw-r--r--test/simple/test-domain-implicit-fs.js4
-rw-r--r--test/simple/test-domain-nested.js42
-rw-r--r--test/simple/test-domain-stack.js4
-rw-r--r--test/simple/test-domain-timers.js60
-rw-r--r--test/simple/test-domain.js142
-rw-r--r--test/simple/test-eio-limit.js50
-rw-r--r--test/simple/test-eio-race2.js45
-rw-r--r--test/simple/test-event-emitter-listeners-side-effects.js61
-rw-r--r--test/simple/test-event-emitter-listeners.js52
-rw-r--r--test/simple/test-event-emitter-remove-all-listeners.js15
-rw-r--r--test/simple/test-event-emitter-remove-listeners.js29
-rw-r--r--test/simple/test-event-emitter-set-max-listeners-side-effects.js30
-rw-r--r--test/simple/test-file-write-stream.js34
-rw-r--r--test/simple/test-file-write-stream2.js39
-rw-r--r--test/simple/test-fs-empty-readStream.js6
-rw-r--r--test/simple/test-fs-long-path.js1
-rw-r--r--test/simple/test-fs-null-bytes.js75
-rw-r--r--test/simple/test-fs-read-stream-err.js39
-rw-r--r--test/simple/test-fs-read-stream.js58
-rw-r--r--test/simple/test-fs-readfile-error.js55
-rw-r--r--test/simple/test-fs-truncate.js135
-rw-r--r--test/simple/test-fs-watch.js14
-rw-r--r--test/simple/test-fs-write-stream-end.js28
-rw-r--r--test/simple/test-fs-write-stream-err.js55
-rw-r--r--test/simple/test-http-1.0-keep-alive.js4
-rw-r--r--test/simple/test-http-abort-client.js10
-rw-r--r--test/simple/test-http-agent.js10
-rw-r--r--test/simple/test-http-byteswritten.js43
-rw-r--r--test/simple/test-http-chunked-304.js63
-rw-r--r--test/simple/test-http-client-agent.js1
-rw-r--r--test/simple/test-http-client-pipe-end.js5
-rw-r--r--test/simple/test-http-client-timeout-with-data.js4
-rw-r--r--test/simple/test-http-conn-reset.js1
-rw-r--r--test/simple/test-http-connect.js6
-rw-r--r--test/simple/test-http-date-header.js1
-rw-r--r--test/simple/test-http-default-encoding.js1
-rw-r--r--test/simple/test-http-header-read.js3
-rw-r--r--test/simple/test-http-header-response-splitting.js18
-rw-r--r--test/simple/test-http-host-headers.js86
-rw-r--r--test/simple/test-http-keep-alive-close-on-header.js7
-rw-r--r--test/simple/test-http-keep-alive.js3
-rw-r--r--test/simple/test-http-localaddress-bind-error.js1
-rw-r--r--test/simple/test-http-localaddress.js2
-rw-r--r--test/simple/test-http-many-keep-alive-connections.js1
-rw-r--r--test/simple/test-http-multi-line-headers.js7
-rw-r--r--test/simple/test-http-parser-free.js1
-rw-r--r--test/simple/test-http-request-end-twice.js1
-rw-r--r--test/simple/test-http-request-end.js1
-rw-r--r--test/simple/test-http-res-write-end-dont-take-array.js6
-rw-r--r--test/simple/test-http-response-no-headers.js4
-rw-r--r--test/simple/test-http-response-readable.js1
-rw-r--r--test/simple/test-http-server-stale-close.js3
-rw-r--r--test/simple/test-http-set-trailers.js1
-rw-r--r--test/simple/test-http-status-code.js1
-rw-r--r--test/simple/test-http-timeout.js5
-rw-r--r--test/simple/test-http-url.parse-https.request.js1
-rw-r--r--test/simple/test-https-agent.js10
-rw-r--r--test/simple/test-https-byteswritten.js56
-rw-r--r--test/simple/test-https-client-get-url.js3
-rw-r--r--test/simple/test-https-client-reject.js9
-rw-r--r--test/simple/test-https-drain.js3
-rw-r--r--test/simple/test-https-eof-for-eom.js8
-rw-r--r--test/simple/test-https-localaddress-bind-error.js1
-rw-r--r--test/simple/test-https-localaddress.js9
-rw-r--r--test/simple/test-https-no-reader.js68
-rw-r--r--test/simple/test-https-pfx.js5
-rw-r--r--test/simple/test-https-socket-options.js15
-rw-r--r--test/simple/test-https-strict.js4
-rw-r--r--test/simple/test-https-timeout-server-2.js51
-rw-r--r--test/simple/test-https-timeout-server.js58
-rw-r--r--test/simple/test-https-timeout.js3
-rw-r--r--test/simple/test-module-loading.js11
-rw-r--r--test/simple/test-net-after-close.js2
-rw-r--r--test/simple/test-net-binary.js25
-rw-r--r--test/simple/test-net-buffersize.js51
-rw-r--r--test/simple/test-net-bytes-stats.js15
-rw-r--r--test/simple/test-net-can-reset-timeout.js2
-rw-r--r--test/simple/test-net-connect-buffer.js13
-rw-r--r--test/simple/test-net-connect-options.js4
-rw-r--r--test/simple/test-net-connect-unref.js45
-rw-r--r--test/simple/test-net-end-without-connect.js26
-rw-r--r--test/simple/test-net-local-address-port.js47
-rw-r--r--test/simple/test-net-pingpong.js9
-rw-r--r--test/simple/test-net-reconnect.js18
-rw-r--r--test/simple/test-net-remote-address-port.js1
-rw-r--r--test/simple/test-net-server-unref.js39
-rw-r--r--test/simple/test-net-write-after-close.js4
-rw-r--r--test/simple/test-next-tick-error-spin.js69
-rw-r--r--test/simple/test-next-tick-intentional-starvation.js64
-rw-r--r--test/simple/test-next-tick.js4
-rw-r--r--test/simple/test-os.js12
-rw-r--r--test/simple/test-path-makelong.js14
-rw-r--r--test/simple/test-path.js140
-rw-r--r--test/simple/test-pipe-file-to-http.js13
-rw-r--r--test/simple/test-pipe-unref.js39
-rw-r--r--test/simple/test-pipe.js1
-rw-r--r--test/simple/test-process-active-wraps.js9
-rw-r--r--test/simple/test-process-env.js10
-rw-r--r--test/simple/test-process-getgroups.js41
-rw-r--r--test/simple/test-punycode.js13
-rw-r--r--test/simple/test-readline-interface.js237
-rw-r--r--test/simple/test-regress-GH-1531.js3
-rw-r--r--test/simple/test-regress-GH-1697.js4
-rw-r--r--test/simple/test-regress-GH-877.js1
-rw-r--r--test/simple/test-repl-autolibs.js5
-rw-r--r--test/simple/test-repl-console.js43
-rw-r--r--test/simple/test-repl-require-cache.js33
-rw-r--r--test/simple/test-repl.js12
-rw-r--r--test/simple/test-script-context.js8
-rw-r--r--test/simple/test-setproctitle.js6
-rw-r--r--test/simple/test-stdio-readable-writable.js32
-rw-r--r--test/simple/test-stdout-cannot-be-closed-child-process-pipe.js52
-rw-r--r--test/simple/test-stdout-stderr-reading.js94
-rw-r--r--test/simple/test-stdout-to-file.js2
-rw-r--r--test/simple/test-stream-big-push.js84
-rw-r--r--test/simple/test-stream-pipe-cleanup.js48
-rw-r--r--test/simple/test-stream-push-order.js51
-rw-r--r--test/simple/test-stream2-basic.js452
-rw-r--r--test/simple/test-stream2-compatibility.js50
-rw-r--r--test/simple/test-stream2-finish-pipe.js41
-rw-r--r--test/simple/test-stream2-fs.js76
-rw-r--r--test/simple/test-stream2-httpclient-response-end.js52
-rw-r--r--test/simple/test-stream2-large-read-stall.js82
-rw-r--r--test/simple/test-stream2-objects.js348
-rw-r--r--test/simple/test-stream2-pipe-error-handling.js105
-rw-r--r--test/simple/test-stream2-push.js138
-rw-r--r--test/simple/test-stream2-read-sync-stack.js54
-rw-r--r--test/simple/test-stream2-readable-empty-buffer-no-eof.js118
-rw-r--r--test/simple/test-stream2-readable-from-list.js120
-rw-r--r--test/simple/test-stream2-readable-legacy-drain.js75
-rw-r--r--test/simple/test-stream2-readable-non-empty-end.js78
-rw-r--r--test/simple/test-stream2-set-encoding.js314
-rw-r--r--test/simple/test-stream2-stderr-sync.js130
-rw-r--r--test/simple/test-stream2-transform.js437
-rw-r--r--test/simple/test-stream2-unpipe-drain.js76
-rw-r--r--test/simple/test-stream2-unpipe-leak.js63
-rw-r--r--test/simple/test-stream2-writable.js313
-rw-r--r--test/simple/test-string-decoder-end.js75
-rw-r--r--test/simple/test-tcp-wrap-connect.js1
-rw-r--r--test/simple/test-tcp-wrap.js4
-rw-r--r--test/simple/test-timers-immediate.js53
-rw-r--r--test/simple/test-timers-uncaught-exception.js8
-rw-r--r--test/simple/test-timers-unref.js62
-rw-r--r--test/simple/test-tls-client-reject.js10
-rw-r--r--test/simple/test-tls-client-resume.js12
-rw-r--r--test/simple/test-tls-client-verify.js3
-rw-r--r--test/simple/test-tls-connect-given-socket.js10
-rw-r--r--test/simple/test-tls-connect-pipe.js3
-rw-r--r--test/simple/test-tls-connect-simple.js10
-rw-r--r--test/simple/test-tls-fast-writing.js80
-rw-r--r--test/simple/test-tls-getcipher.js6
-rw-r--r--test/simple/test-tls-handshake-nohang.js28
-rw-r--r--test/simple/test-tls-honorcipherorder.js5
-rw-r--r--test/simple/test-tls-junk-closes-server.js2
-rw-r--r--test/simple/test-tls-npn-server-client.js9
-rw-r--r--test/simple/test-tls-over-http-tunnel.js12
-rw-r--r--test/simple/test-tls-passphrase.js6
-rw-r--r--test/simple/test-tls-pause-close.js5
-rw-r--r--test/simple/test-tls-pause.js20
-rw-r--r--test/simple/test-tls-peer-certificate-multi-keys.js5
-rw-r--r--test/simple/test-tls-peer-certificate.js5
-rw-r--r--test/simple/test-tls-remote.js6
-rw-r--r--test/simple/test-tls-request-timeout.js5
-rw-r--r--test/simple/test-tls-server-missing-options.js38
-rw-r--r--test/simple/test-tls-server-slab.js66
-rw-r--r--test/simple/test-tls-session-cache.js29
-rw-r--r--test/simple/test-tls-set-ciphers.js6
-rw-r--r--test/simple/test-tls-set-encoding.js5
-rw-r--r--test/simple/test-tls-sni-server-client.js9
-rw-r--r--test/simple/test-tls-timeout-server-2.js47
-rw-r--r--test/simple/test-tls-timeout-server.js52
-rw-r--r--test/simple/test-tty-wrap.js8
-rw-r--r--test/simple/test-typed-arrays.js117
-rw-r--r--test/simple/test-url.js74
-rw-r--r--test/simple/test-util-inspect.js45
-rw-r--r--test/simple/test-writedouble.js63
-rw-r--r--test/simple/test-writefloat.js61
-rw-r--r--test/simple/test-zlib-destroy.js36
-rw-r--r--test/simple/test-zlib-invalid-input.js7
-rw-r--r--test/simple/test-zlib-random-byte-pipes.js17
-rw-r--r--tools/addon.gypi24
-rw-r--r--tools/doc/html.js10
-rwxr-xr-xtools/genv8constants.py70
-rwxr-xr-xtools/gyp/gyptest.py4
-rw-r--r--tools/gyp/pylib/gyp/MSVSNew.py22
-rw-r--r--tools/gyp/pylib/gyp/MSVSVersion.py13
-rwxr-xr-xtools/gyp/pylib/gyp/__init__.py32
-rw-r--r--tools/gyp/pylib/gyp/common.py9
-rwxr-xr-xtools/gyp/pylib/gyp/common_test.py28
-rw-r--r--tools/gyp/pylib/gyp/generator/android.py27
-rw-r--r--tools/gyp/pylib/gyp/generator/dump_dependency_json.py31
-rw-r--r--tools/gyp/pylib/gyp/generator/make.py114
-rw-r--r--tools/gyp/pylib/gyp/generator/msvs.py46
-rwxr-xr-xtools/gyp/pylib/gyp/generator/msvs_test.py6
-rw-r--r--tools/gyp/pylib/gyp/generator/ninja.py223
-rw-r--r--tools/gyp/pylib/gyp/generator/scons.py25
-rw-r--r--tools/gyp/pylib/gyp/generator/xcode.py19
-rw-r--r--tools/gyp/pylib/gyp/input.py456
-rwxr-xr-xtools/gyp/pylib/gyp/mac_tool.py5
-rw-r--r--tools/gyp/pylib/gyp/msvs_emulation.py113
-rw-r--r--tools/gyp/pylib/gyp/ninja_syntax.py15
-rwxr-xr-xtools/gyp/pylib/gyp/system_test.py68
-rwxr-xr-x[-rw-r--r--]tools/gyp/pylib/gyp/win_tool.py43
-rw-r--r--tools/gyp/pylib/gyp/xcode_emulation.py21
-rw-r--r--tools/gyp/pylib/gyp/xcodeproj_file.py113
-rwxr-xr-xtools/gyp_addon42
-rwxr-xr-xtools/gyp_node3
-rwxr-xr-xtools/install.py79
-rwxr-xr-xtools/js2c.py12
-rw-r--r--tools/msvs/genfiles/MSG00001.binbin0 -> 48 bytes
-rw-r--r--tools/msvs/genfiles/node_etw_provider.h59
-rw-r--r--tools/msvs/genfiles/node_etw_provider.rc3
-rw-r--r--tools/msvs/genfiles/node_etw_providerTEMP.BINbin0 -> 5410 bytes
-rw-r--r--tools/msvs/genfiles/node_perfctr_provider.h79
-rw-r--r--tools/msvs/genfiles/node_perfctr_provider.rc36
-rw-r--r--tools/msvs/msi/WixUI_en-us.wxl4
-rw-r--r--tools/msvs/msi/nodemsi.wixproj36
-rwxr-xr-xtools/msvs/msi/product.wxs100
-rwxr-xr-xtools/node-waf17
-rwxr-xr-xtools/test.py13
-rwxr-xr-xtools/waf-light159
-rw-r--r--tools/wafadmin/Build.py1021
-rw-r--r--tools/wafadmin/Configure.py387
-rw-r--r--tools/wafadmin/Constants.py76
-rw-r--r--tools/wafadmin/Environment.py210
-rw-r--r--tools/wafadmin/Logs.py134
-rw-r--r--tools/wafadmin/Node.py693
-rw-r--r--tools/wafadmin/Options.py279
-rw-r--r--tools/wafadmin/Runner.py229
-rw-r--r--tools/wafadmin/Scripting.py586
-rw-r--r--tools/wafadmin/Task.py1171
-rw-r--r--tools/wafadmin/TaskGen.py588
-rw-r--r--tools/wafadmin/Tools/__init__.py4
-rw-r--r--tools/wafadmin/Tools/ar.py36
-rw-r--r--tools/wafadmin/Tools/cc.py100
-rw-r--r--tools/wafadmin/Tools/ccroot.py625
-rw-r--r--tools/wafadmin/Tools/compiler_cc.py66
-rw-r--r--tools/wafadmin/Tools/compiler_cxx.py61
-rw-r--r--tools/wafadmin/Tools/compiler_d.py33
-rw-r--r--tools/wafadmin/Tools/config_c.py729
-rw-r--r--tools/wafadmin/Tools/cxx.py104
-rw-r--r--tools/wafadmin/Tools/d.py540
-rw-r--r--tools/wafadmin/Tools/dmd.py64
-rw-r--r--tools/wafadmin/Tools/gas.py38
-rw-r--r--tools/wafadmin/Tools/gcc.py137
-rw-r--r--tools/wafadmin/Tools/gdc.py52
-rw-r--r--tools/wafadmin/Tools/gnu_dirs.py111
-rw-r--r--tools/wafadmin/Tools/gob2.py18
-rw-r--r--tools/wafadmin/Tools/gxx.py134
-rw-r--r--tools/wafadmin/Tools/icc.py37
-rw-r--r--tools/wafadmin/Tools/icpc.py34
-rw-r--r--tools/wafadmin/Tools/intltool.py139
-rw-r--r--tools/wafadmin/Tools/libtool.py330
-rw-r--r--tools/wafadmin/Tools/misc.py430
-rw-r--r--tools/wafadmin/Tools/nasm.py49
-rw-r--r--tools/wafadmin/Tools/node_addon.py86
-rw-r--r--tools/wafadmin/Tools/osx.py187
-rw-r--r--tools/wafadmin/Tools/preproc.py813
-rw-r--r--tools/wafadmin/Tools/python.py401
-rw-r--r--tools/wafadmin/Tools/suncc.py77
-rw-r--r--tools/wafadmin/Tools/suncxx.py75
-rw-r--r--tools/wafadmin/Tools/unittestw.py305
-rw-r--r--tools/wafadmin/Tools/winres.py45
-rw-r--r--tools/wafadmin/Tools/xlc.py77
-rw-r--r--tools/wafadmin/Tools/xlcxx.py77
-rw-r--r--tools/wafadmin/Utils.py707
-rw-r--r--tools/wafadmin/__init__.py3
-rw-r--r--tools/wafadmin/ansiterm.py221
-rw-r--r--tools/wafadmin/pproc.py620
-rw-r--r--tools/wafadmin/py3kfixes.py122
-rw-r--r--tools/wrk/.gitignore2
-rw-r--r--tools/wrk/LICENSE177
-rw-r--r--tools/wrk/Makefile35
-rw-r--r--tools/wrk/NOTICE115
-rw-r--r--tools/wrk/README37
-rw-r--r--tools/wrk/src/ae.c435
-rw-r--r--tools/wrk/src/ae.h118
-rw-r--r--tools/wrk/src/ae_epoll.c130
-rw-r--r--tools/wrk/src/ae_evport.c315
-rw-r--r--tools/wrk/src/ae_kqueue.c132
-rw-r--r--tools/wrk/src/ae_select.c99
-rw-r--r--tools/wrk/src/aprintf.c27
-rw-r--r--tools/wrk/src/aprintf.h6
-rw-r--r--tools/wrk/src/config.h13
-rw-r--r--tools/wrk/src/http_parser.c2058
-rw-r--r--tools/wrk/src/http_parser.h317
-rw-r--r--tools/wrk/src/stats.c73
-rw-r--r--tools/wrk/src/stats.h21
-rw-r--r--tools/wrk/src/tinymt64.c129
-rw-r--r--tools/wrk/src/tinymt64.h210
-rw-r--r--tools/wrk/src/units.c96
-rw-r--r--tools/wrk/src/units.h10
-rw-r--r--tools/wrk/src/wrk.c482
-rw-r--r--tools/wrk/src/wrk.h75
-rw-r--r--tools/wrk/src/zmalloc.c287
-rw-r--r--tools/wrk/src/zmalloc.h83
-rw-r--r--vcbuild.bat20
2436 files changed, 300935 insertions, 165156 deletions
diff --git a/.gitignore b/.gitignore
index 38e9ca975..b43635344 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,8 @@
core
vgcore.*
+v8*.log
+perf.data
+perf.data.old
.waf*
tags
.lock-wscript
@@ -42,4 +45,15 @@ ipch/
email.md
deps/v8-*
./node_modules
-.svn/ \ No newline at end of file
+.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
diff --git a/.mailmap b/.mailmap
index 33d125d20..3b5f111f7 100644
--- a/.mailmap
+++ b/.mailmap
@@ -13,6 +13,7 @@ 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>
+Bryan Cantrill <bmc@joyent.com> <bryan@joyent.com>
Chew Choon Keat <choonkeat@gmail.com>
Christopher Lenz <cmlenz@gmail.com> <chris@lamech.local>
Daniel Berger <code+node@dpbis.net>
@@ -20,6 +21,7 @@ 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>
@@ -46,6 +48,7 @@ Johan Dahlberg <jfd@distrop.com> <dahlberg.johan@gmail.com>
Jonas Pfenniger <jonas@pfenniger.name> <jonas@stvs.ch>
Jonathan Rentzsch <jwr.git@redshed.net>
Joshua S. Weinstein <josher19@users.sf.net>
+Kazuyuki Yamada <tasogare.pg@gmail.com>
Koichi Kobayashi <koichik@improvement.jp>
Kris Kowal <kris.kowal@cixar.com>
Kyle Robinson Young <kyle@dontkry.com>
@@ -83,9 +86,11 @@ Tim Smart <timehandgod@gmail.com> <tim@fostle.com>
Tim Smart <timehandgod@gmail.com> <timehandgod@gmail.com>
TJ Holowaychuk <tj@vision-media.ca>
TJ Holowaychuk <tj@vision-media.ca> <tjholowayhuk@gmail.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>
diff --git a/AUTHORS b/AUTHORS
index bf784aa76..891c701b9 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -223,8 +223,8 @@ Evan Martin <martine@danga.com>
Peter Lyons <pete@peterlyons.com>
Jann Horn <jannhorn@googlemail.com>
Abimanyu Raja <abimanyuraja@gmail.com>
-Karl Skomski <karl@skomski.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>
@@ -325,7 +325,6 @@ Garen Torikian <gjtorikian@gmail.com>
EungJun Yi <semtlenori@gmail.com>
Vincent Voyer <v@fasterize.com>
Takahiro ANDO <takahiro.ando@gmail.com>
-Erwin van der Koogh <github@koogh.com>
Brian Schroeder <bts@gmail.com>
J. Lee Coltrane <lee@projectmastermind.com>
Javier Hernández <jhernandez@emergya.com>
@@ -333,6 +332,7 @@ 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>
@@ -340,44 +340,79 @@ 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>
-George Shank <shankga@gmail.com>
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>
-Joshua Erickson <josh@snoj.us>
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>
Timothy J Fontaine <tjfontaine@gmail.com>
diff --git a/ChangeLog b/ChangeLog
index 769f62fb6..34d318c8a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,395 @@
* unix: Handle EINPROGRESS from domain sockets (Ben Noordhuis)
+2013.02.19, Version 0.9.10 (Unstable)
+
+* V8: Upgrade to 3.15.11.15
+
+* npm: Upgrade to 1.2.12
+
+* fs: Change default WriteStream config, increase perf (isaacs)
+
+* process: streamlining tick callback logic (Trevor Norris)
+
+* stream_wrap, udp_wrap: add read-only fd property (Ben Noordhuis)
+
+* buffer: accept negative indices in Buffer#slice() (Ben Noordhuis)
+
+* tls: Cycle data when underlying socket drains (isaacs)
+
+* stream: read(0) should not always trigger _read(n,cb) (isaacs)
+
+* stream: Empty strings/buffers do not signal EOF any longer (isaacs)
+
+* crypto: improve cipher/decipher error messages (Ben Noordhuis)
+
+* net: Respect the 'readable' flag on sockets (isaacs)
+
+* net: don't suppress ECONNRESET (Ben Noordhuis)
+
+* typed arrays: copy Buffer in typed array constructor (Ben Noordhuis)
+
+* typed arrays: make DataView throw on non-ArrayBuffer (Ben Noordhuis)
+
+* windows: MSI installer enhancements (Scott Blomquist, Jim Schubert)
+
+
+2013.02.07, Version 0.9.9 (Unstable), 4b9f0d190cd6b22853caeb0e07145a98ce1d1d7f
+
+* tls: port CryptoStream to streams2 (Fedor Indutny)
+
+* typed arrays: only share ArrayBuffer backing store (Ben Noordhuis)
+
+* stream: make Writable#end() accept a callback function (Nathan Rajlich)
+
+* buffer: optimize 'hex' handling (Ben Noordhuis)
+
+* dns, cares: don't filter NOTIMP, REFUSED, SERVFAIL (Ben Noordhuis)
+
+* readline: treat bare \r as a line ending (isaacs)
+
+* readline: make \r\n emit one 'line' event (Ben Noordhuis)
+
+* cluster: support datagram sockets (Bert Belder)
+
+* stream: Correct Transform class backpressure (isaacs)
+
+* addon: Pass module object to NODE_MODULE init function (isaacs, Rod Vagg)
+
+* buffer: slow buffer copy compatibility fix (Trevor Norris)
+
+* Add bytesWritten to tls.CryptoStream (Andy Burke)
+
+
+2013.01.24, Version 0.9.8 (Unstable), 5f2f8400f665dc32c3e10e7d31d53d756ded9156
+
+* npm: Upgrade to v1.2.3
+
+* V8: Upgrade to 3.15.11.10
+
+* streams: Support objects other than Buffers (Jake Verbaten)
+
+* buffer: remove float write range checks (Trevor Norris)
+
+* http: close connection on 304/204 responses with chunked encoding (Ben Noordhuis)
+
+* build: fix build with dtrace support on FreeBSD (Fedor Indutny)
+
+* console: Support formatting options in trace() (isaacs)
+
+* domain: empty stack on all exceptions (Dave Olszewski)
+
+* unix, windows: make uv_*_bind() error codes consistent (Andrius Bentkus)
+
+* linux: add futimes() fallback (Ben Noordhuis)
+
+
+2013.01.18, Version 0.9.7 (Unstable), 9e7bebeb8305edd55735a95955a98fdbe47572e5
+
+* V8: Upgrade to 3.15.11.7
+
+* npm: Upgrade to 1.2.2
+
+* punycode: Upgrade to 1.2.0 (Mathias Bynens)
+
+* repl: make built-in modules available by default (Felix Böhm)
+
+* windows: add support for '_Total' perf counters (Scott Blomquist)
+
+* cluster: make --prof work for workers (Ben Noordhuis)
+
+* child_process: do not keep list of sent sockets (Fedor Indutny)
+
+* tls: Follow RFC6125 more strictly (Fedor Indutny)
+
+* buffer: floating point read/write improvements (Trevor Norris)
+
+* TypedArrays: Improve dataview perf without endian param (Dean McNamee)
+
+* module: assert require() called with a non-empty string (Felix Böhm, James Campos)
+
+* stdio: Set readable/writable flags properly (isaacs)
+
+* stream: Properly handle large reads from push-streams (isaacs)
+
+
+2013.01.11, Version 0.9.6 (Unstable), 9313fdc71ca8335d5e3a391c103230ee6219b3e2
+
+* V8: update to 3.15.11.5
+
+* node: remove ev-emul.h (Ben Noordhuis)
+
+* path: make basename and extname ignore trailing slashes (Bert Belder)
+
+* typed arrays: fix sunos signed/unsigned char issue (Ben Noordhuis)
+
+* child_process: Fix {stdio:'inherit'} regression (Ben Noordhuis)
+
+* child_process: Fix pipe() from child stdio streams (Maciej Małecki)
+
+* child_process: make fork() execPath configurable (Bradley Meck)
+
+* stream: Add readable.push(chunk) method (isaacs)
+
+* dtrace: x64 ustack helper (Fedor Indutny)
+
+* repl: fix floating point number parsing (Nirk Niggler)
+
+* repl: allow overriding builtins (Ben Noordhuis)
+
+* net: add localAddress and localPort to Socket (James Hight)
+
+* fs: make pool size coincide with ReadStream bufferSize (Shigeki Ohtsu)
+
+* typed arrays: implement load and store swizzling (Dean McNamee)
+
+* windows: fix perfctr crash on XP and 2003 (Scott Blomquist)
+
+* dgram: fix double implicit bind error (Ben Noordhuis)
+
+
+2012.12.30, Version 0.9.5 (Unstable), 01994e8119c24f2284bac0779b32acb49c95bee7
+
+* assert: improve support for new execution contexts (lukebayes)
+
+* domain: use camelCase instead of snake_case (isaacs)
+
+* domain: Do not use uncaughtException handler (isaacs)
+
+* fs: make 'end' work with ReadStream without 'start' (Ben Noordhuis)
+
+* https: optimize createConnection() (Ryunosuke SATO)
+
+* buffer: speed up base64 encoding by 20% (Ben Noordhuis)
+
+* doc: Colorize API stabilitity index headers in docs (Luke Arduini)
+
+* net: socket.readyState corrections (bentaber)
+
+* http: Performance enhancements for http under streams2 (isaacs)
+
+* stream: fix to emit end event on http.ClientResponse (Shigeki Ohtsu)
+
+* stream: fix event handler leak in readstream pipe and unpipe (Andreas Madsen)
+
+* build: Support ./configure --tag switch (Maciej Małecki)
+
+* repl: don't touch `require.cache` (Nathan Rajlich)
+
+* node: Emit 'exit' event when exiting for an uncaught exception (isaacs)
+
+
+2012.12.21, Version 0.9.4 (Unstable), d86d83c75f6343b5368bb7bd328b4466a035e1d4
+
+* streams: Update all streaming interfaces to use new classes (isaacs)
+
+* node: remove idle gc (Ben Noordhuis)
+
+* http: protect against response splitting attacks (Bert Belder)
+
+* fs: Raise error when null bytes detected in paths (isaacs)
+
+* fs: fix 'object is not a function' callback errors (Ben Noordhuis)
+
+* fs: add autoClose=true option to fs.createReadStream (Farid Neshat)
+
+* process: add getgroups(), setgroups(), initgroups() (Ben Noordhuis)
+
+* openssl: optimized asm code on x86 and x64 (Bert Belder)
+
+* crypto: fix leak in GetPeerCertificate (Fedor Indutny)
+
+* add systemtap support (Jan Wynholds)
+
+* windows: add ETW and PerfCounters support (Scott Blomquist)
+
+* windows: fix normalization of UNC paths (Bert Belder)
+
+* crypto: fix ssl error handling (Sergey Kholodilov)
+
+* node: remove eio-emul.h (Ben Noordhuis)
+
+* os: add os.endianness() function (Nathan Rajlich)
+
+* readline: don't emit "line" events with a trailing '\n' char (Nathan Rajlich)
+
+* build: add configure option to generate xcode build files (Timothy J Fontaine)
+
+* build: allow linking against system libuv, cares, http_parser (Stephen Gallagher)
+
+* typed arrays: add slice() support to ArrayBuffer (Anthony Pesch)
+
+* debugger: exit and kill child on SIGTERM or SIGHUP (Fedor Indutny)
+
+* url: url.format escapes delimiters in path and query (J. Lee Coltrane)
+
+
+2012.10.24, Version 0.9.3 (Unstable), 1ed4c6776e4f52956918b70565502e0f8869829d
+
+* V8: Upgrade to 3.13.7.4
+
+* crypto: Default to buffers instead of binary strings (isaacs, Fedor Indutny)
+
+* crypto: add getHashes() and getCiphers() (Ben Noordhuis)
+
+* unix: add custom thread pool, remove libeio (Ben Noordhuis)
+
+* util: make `inspect()` accept an "options" argument (Nathan Rajlich)
+
+* https: fix renegotation attack protection (Ben Noordhuis)
+
+* cluster: make 'listening' handler see actual port (Aaditya Bhatia)
+
+* windows: use USERPROFILE to get the user's home dir (Bert Belder)
+
+* path: add platform specific path delimiter (Paul Serby)
+
+* http: add response.headersSent property (Pavel Lang)
+
+* child_process: make .fork()'d child auto-exit (Ben Noordhuis)
+
+* events: add 'removeListener' event (Ben Noordhuis)
+
+* string_decoder: Add 'end' method, do base64 properly (isaacs)
+
+* buffer: include encoding value in exception when invalid (Ricky Ng-Adam)
+
+* http: make http.ServerResponse no longer emit 'end' (isaacs)
+
+* streams: fix pipe is destructed by 'end' from destination (koichik)
+
+
+2012.09.17, Version 0.9.2 (Unstable), 6e2055889091a424fbb5c500bc3ab9c05d1c28b4
+
+* http_parser: upgrade to ad3b631
+
+* openssl: upgrade 1.0.1c
+
+* darwin: use FSEvents to watch directory changes (Fedor Indutny)
+
+* unix: support missing API on NetBSD (Shigeki Ohtsu)
+
+* unix: fix EMFILE busy loop (Ben Noordhuis)
+
+* windows: un-break writable tty handles (Bert Belder)
+
+* windows: map WSAESHUTDOWN to UV_EPIPE (Bert Belder)
+
+* windows: make spawn with custom environment work again (Bert Belder)
+
+* windows: map ERROR_DIRECTORY to UV_ENOENT (Bert Belder)
+
+* tls, https: validate server certificate by default (Ben Noordhuis)
+
+* tls, https: throw exception on missing key/cert (Ben Noordhuis)
+
+* tls: async session storage (Fedor Indutny)
+
+* installer: don't install header files (Ben Noordhuis)
+
+* buffer: implement Buffer.prototype.toJSON() (Nathan Rajlich)
+
+* buffer: added support for writing NaN and Infinity (koichik)
+
+* http: make http.ServerResponse emit 'end' (Ben Noordhuis)
+
+* build: ./configure --ninja (Ben Noordhuis, Timothy J Fontaine)
+
+* installer: fix --without-npm (Ben Noordhuis)
+
+* cli: make -p equivalent to -pe (Ben Noordhuis)
+
+* url: Go much faster by using Url class (isaacs)
+
+
+2012.08.28, Version 0.9.1 (Unstable), e6ce259d2caf338fec991c2dd447de763ce99ab7
+
+* buffer: Add Buffer.isEncoding(enc) to test for valid encoding values (isaacs)
+
+* Raise UV_ECANCELED on premature close. (Ben Noordhuis)
+
+* Remove c-ares from libuv, move to a top-level node dependency (Bert Belder)
+
+* ref/unref for all HandleWraps, timers, servers, and sockets (Timothy J Fontaine)
+
+* addon: remove node-waf, superseded by node-gyp (Ben Noordhuis)
+
+* child_process: emit error on exec failure (Ben Noordhuis)
+
+* cluster: do not use internal server API (Andreas Madsen)
+
+* constants: add O_DIRECT (Ian Babrou)
+
+* crypto: add sync interface to crypto.pbkdf2() (Ben Noordhuis)
+
+* darwin: emulate fdatasync() (Fedor Indutny)
+
+* dgram: make .bind() always asynchronous (Ben Noordhuis)
+
+* events: Make emitter.listeners() side-effect free (isaacs, Joe Andaverde)
+
+* fs: Throw early on invalid encoding args (isaacs)
+
+* fs: fix naming of truncate/ftruncate functions (isaacs)
+
+* http: bubble up parser errors to ClientRequest (Brian White)
+
+* linux: improve cpuinfo parser on ARM and MIPS (Ben Noordhuis)
+
+* net: add support for IPv6 addresses ending in :: (Josh Erickson)
+
+* net: support Server.listen(Pipe) (Andreas Madsen)
+
+* node: don't scan add-on for "init" symbol (Ben Noordhuis)
+
+* remove process.uvCounters() (Ben Noordhuis)
+
+* repl: console writes to repl rather than process stdio (Nathan Rajlich)
+
+* timers: implement setImmediate (Timothy J Fontaine)
+
+* tls: fix segfault in pummel/test-tls-ci-reneg-attack (Ben Noordhuis)
+
+* tools: Move gyp addon tools to node-gyp (Nathan Rajlich)
+
+* unix: preliminary signal handler support (Ben Noordhuis)
+
+* unix: remove dependency on ev_child (Ben Noordhuis)
+
+* unix: work around darwin bug, don't poll() on pipe (Fedor Indutny)
+
+* util: Formally deprecate util.pump() (Ben Noordhuis)
+
+* windows: make active and closing handle state independent (Bert Belder)
+
+* windows: report spawn errors to the exit callback (Bert Belder)
+
+* windows: signal handling support with uv_signal_t (Bert Belder)
+
+
+2012.07.20, Version 0.9.0 (Unstable), f9b237f478c372fd55e4590d7399dcd8f25f3603
+
+* punycode: update to v1.1.1 (Mathias Bynens)
+
+* c-ares: upgrade to 1.9.0 (Saúl Ibarra Corretgé)
+
+* dns: ignore rogue DNS servers reported by windows (Saúl Ibarra Corretgé)
+
+* unix: speed up uv_async_send() (Ben Noordhuis)
+
+* darwin: get cpu model correctly on mac (Xidorn Quan)
+
+* nextTick: Handle tick callbacks before any other I/O (isaacs)
+
+* Enable color customization of `util.inspect` (Pavel Lang)
+
+* tls: Speed and memory improvements (Fedor Indutny)
+
+* readline: Use one history item for reentered line (Vladimir Beloborodov)
+
+* Fix #3521 Make process.env more like a regular Object (isaacs)
+
+
2013.02.15, Version 0.8.20 (Stable), e10c75579b536581ddd7ae4e2c3bf8a9d550d343
* npm: Upgrade to v1.2.11
diff --git a/LICENSE b/LICENSE
index adc86f22a..494e37a76 100644
--- a/LICENSE
+++ b/LICENSE
@@ -84,118 +84,7 @@ maintained libraries. The externally maintained libraries used by Node are:
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
-- libev, located at deps/uv/src/unix/ev. libev's license follows:
- """
- All files in libev are Copyright (C)2007,2008,2009 Marc Alexander Lehmann.
-
- 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.
-
- 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.
-
- Alternatively, the contents of this package may be used under the terms
- of the GNU General Public License ("GPL") version 2 or any later version,
- in which case the provisions of the GPL are applicable instead of the
- above. If you wish to allow the use of your version of this package only
- under the terms of the GPL and not to allow others to use your version of
- this file under the BSD license, indicate your decision by deleting the
- provisions above and replace them with the notice and other provisions
- required by the GPL in this and the other files of this package. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the BSD or the GPL.
- """
-
-- libeio, located at deps/uv/src/unix/eio. libeio's license follows:
- """
- All files in libeio are Copyright (C)2007,2008 Marc Alexander Lehmann.
-
- 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.
-
- 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.
-
- Alternatively, the contents of this package may be used under the terms
- of the GNU General Public License ("GPL") version 2 or any later version,
- in which case the provisions of the GPL are applicable instead of the
- above. If you wish to allow the use of your version of this package only
- under the terms of the GPL and not to allow others to use your version of
- this file under the BSD license, indicate your decision by deleting the
- provisions above and replace them with the notice and other provisions
- required by the GPL in this and the other files of this package. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the BSD or the GPL.
- """
-
-- WAF build system, located at tools/waf*. WAF's license follows:
- """
- Copyright Thomas Nagy, 2005-2011
-
- 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. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 AUTHOR 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/uv/src/ares. C-Ares license
+- C-Ares, an asynchronous DNS client, located at deps/cares. C-Ares license
follows:
"""
/* Copyright 1998 by the Massachusetts Institute of Technology.
@@ -363,38 +252,6 @@ maintained libraries. The externally maintained libraries used by Node are:
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
-- lib/buffer_ieee754.js. Its license follows:
- """
- // Copyright (c) 2008, Fair Oaks Labs, 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 Fair Oaks Labs, 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.
"""
diff --git a/Makefile b/Makefile
index 0ebc14fc4..942bda31c 100644
--- a/Makefile
+++ b/Makefile
@@ -2,9 +2,12 @@
BUILDTYPE ?= Release
PYTHON ?= python
+NINJA ?= ninja
DESTDIR ?=
SIGN ?=
+NODE ?= ./node
+
# 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.
@@ -22,22 +25,34 @@ endif
# to check for changes.
.PHONY: node node_g
+ifeq ($(USE_NINJA),1)
+node: config.gypi
+ $(NINJA) -C out/Release/
+ ln -fs out/Release/node node
+
+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 node_g
-
-config.gypi: configure
- ./configure
-
-out/Debug/node:
- $(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 -f ninja
+else
$(PYTHON) tools/gyp_node -f make
+endif
+
+config.gypi: configure
+ $(PYTHON) ./configure
install: all
$(PYTHON) tools/install.py $@ $(DESTDIR)
@@ -59,7 +74,7 @@ distclean:
test: all
$(PYTHON) tools/test.py --mode=release simple message
- 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
+ $(MAKE) jslint
test-http1: all
$(PYTHON) tools/test.py --mode=release --use-http1 simple message
@@ -203,9 +218,17 @@ endif
ifeq ($(DESTCPU),x64)
ARCH=x64
else
+ifeq ($(DESTCPU),arm)
+ARCH=arm
+else
ARCH=x86
endif
+endif
TARNAME=node-$(VERSION)
+ifeq ($(NIGHTLY),1)
+TAG = nightly-$(shell date "+%Y%m%d")
+TARNAME=node-$(VERSION)-$(TAG)
+endif
TARBALL=$(TARNAME).tar.gz
BINARYNAME=$(TARNAME)-$(PLATFORM)-$(ARCH)
BINARYTAR=$(BINARYNAME).tar.gz
@@ -228,7 +251,7 @@ release-only:
echo "" >&2 ; \
exit 1 ; \
fi
- @if [ "$(RELEASE)" = "1" ]; then \
+ @if [ "$(NIGHTLY)" = "1" -o "$(RELEASE)" = "1" ]; then \
exit 0; \
else \
echo "" >&2 ; \
@@ -243,10 +266,10 @@ pkg: $(PKG)
$(PKG): release-only
rm -rf $(PKGDIR)
rm -rf out/deps out/Release
- ./configure --prefix=$(PKGDIR)/32/usr/local --without-snapshot --dest-cpu=ia32
+ $(PYTHON) ./configure --prefix=$(PKGDIR)/32/usr/local --without-snapshot --dest-cpu=ia32 --tag=$(TAG)
$(MAKE) install V=$(V)
rm -rf out/deps out/Release
- ./configure --prefix=$(PKGDIR)/usr/local --without-snapshot --dest-cpu=x64
+ $(PYTHON) ./configure --prefix=$(PKGDIR)/usr/local --without-snapshot --dest-cpu=x64 --tag=$(TAG)
$(MAKE) install V=$(V)
SIGN="$(SIGN)" PKGDIR="$(PKGDIR)" bash tools/osx-codesign.sh
lipo $(PKGDIR)/32/usr/local/bin/node \
@@ -278,7 +301,7 @@ tar: $(TARBALL)
$(BINARYTAR): release-only
rm -rf $(BINARYNAME)
rm -rf out/deps out/Release
- ./configure --prefix=/ --without-snapshot --dest-cpu=$(DESTCPU) $(CONFIG_FLAGS)
+ $(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)
@@ -294,7 +317,44 @@ dist-upload: $(TARBALL) $(PKG)
scp $(TARBALL) node@nodejs.org:~/web/nodejs.org/dist/$(VERSION)/$(TARBALL)
scp $(PKG) node@nodejs.org:~/web/nodejs.org/dist/$(VERSION)/$(TARNAME).pkg
-bench:
+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:
benchmark/http_simple_bench.sh
bench-idle:
@@ -313,4 +373,4 @@ cpplint:
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
+.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
diff --git a/benchmark/arrays/var-int.js b/benchmark/arrays/var-int.js
new file mode 100644
index 000000000..47a7e62dc
--- /dev/null
+++ b/benchmark/arrays/var-int.js
@@ -0,0 +1,20 @@
+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);
+}
diff --git a/benchmark/arrays/var_int.js b/benchmark/arrays/var_int.js
deleted file mode 100644
index 17e12989f..000000000
--- a/benchmark/arrays/var_int.js
+++ /dev/null
@@ -1,15 +0,0 @@
-var types = 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' ');
-
-var type = types[types.indexOf(process.argv[2])];
-if (!type)
- type = types[0];
-
-console.error('Benchmarking', type);
-var clazz = global[type];
-
-var arr = new clazz(25 * 10e5);
-for (var i = 0; i < 10; ++i) {
- for (var j = 0, k = arr.length; j < k; ++j) {
- arr[j] = (j ^ k) & 127;
- }
-}
diff --git a/benchmark/arrays/zero-float.js b/benchmark/arrays/zero-float.js
new file mode 100644
index 000000000..a6624205b
--- /dev/null
+++ b/benchmark/arrays/zero-float.js
@@ -0,0 +1,20 @@
+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);
+}
diff --git a/benchmark/arrays/zero-int.js b/benchmark/arrays/zero-int.js
new file mode 100644
index 000000000..29a2d58b6
--- /dev/null
+++ b/benchmark/arrays/zero-int.js
@@ -0,0 +1,20 @@
+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);
+}
diff --git a/benchmark/arrays/zero_float.js b/benchmark/arrays/zero_float.js
deleted file mode 100644
index bdb8765d0..000000000
--- a/benchmark/arrays/zero_float.js
+++ /dev/null
@@ -1,15 +0,0 @@
-var types = 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' ');
-
-var type = types[types.indexOf(process.argv[2])];
-if (!type)
- type = types[0];
-
-console.error('Benchmarking', type);
-var clazz = global[type];
-
-var arr = new clazz(25 * 10e5);
-for (var i = 0; i < 10; ++i) {
- for (var j = 0, k = arr.length; j < k; ++j) {
- arr[j] = 0.0;
- }
-}
diff --git a/benchmark/arrays/zero_int.js b/benchmark/arrays/zero_int.js
deleted file mode 100644
index 17dac62c1..000000000
--- a/benchmark/arrays/zero_int.js
+++ /dev/null
@@ -1,15 +0,0 @@
-var types = 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' ');
-
-var type = types[types.indexOf(process.argv[2])];
-if (!type)
- type = types[0];
-
-console.error('Benchmarking', type);
-var clazz = global[type];
-
-var arr = new clazz(25 * 10e5);
-for (var i = 0; i < 10; ++i) {
- for (var j = 0, k = arr.length; j < k; ++j) {
- arr[j] = 0;
- }
-}
diff --git a/benchmark/buffer_creation.js b/benchmark/buffer_creation.js
deleted file mode 100644
index 3bc711e3b..000000000
--- a/benchmark/buffer_creation.js
+++ /dev/null
@@ -1,6 +0,0 @@
-SlowBuffer = require('buffer').SlowBuffer;
-
-for (var i = 0; i < 1e6; i++) {
- b = new SlowBuffer(10);
- b[1] = 2
-}
diff --git a/benchmark/buffers/buffer-base64-encode.js b/benchmark/buffers/buffer-base64-encode.js
new file mode 100644
index 000000000..f2b8e9a48
--- /dev/null
+++ b/benchmark/buffers/buffer-base64-encode.js
@@ -0,0 +1,36 @@
+// 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);
+}
diff --git a/benchmark/buffers/buffer-creation.js b/benchmark/buffers/buffer-creation.js
new file mode 100644
index 000000000..bc0c55711
--- /dev/null
+++ b/benchmark/buffers/buffer-creation.js
@@ -0,0 +1,19 @@
+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);
+}
diff --git a/benchmark/buffers/buffer-read.js b/benchmark/buffers/buffer-read.js
new file mode 100644
index 000000000..fccd99dcd
--- /dev/null
+++ b/benchmark/buffers/buffer-read.js
@@ -0,0 +1,28 @@
+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);
+ bench.start();
+ for (var i = 0; i < len; i++) {
+ buff[fn](0, noAssert);
+ }
+ bench.end(len / 1e6);
+}
diff --git a/benchmark/buffers/buffer-write.js b/benchmark/buffers/buffer-write.js
new file mode 100644
index 000000000..4dbfcb609
--- /dev/null
+++ b/benchmark/buffers/buffer-write.js
@@ -0,0 +1,63 @@
+
+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;
+const UINT16 = INT16 * 2;
+const UINT32 = INT32 * 2;
+
+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];
+ bench.start();
+ for (var i = 0; i < len; i++) {
+ buff[fn](i % m, 0, noAssert);
+ }
+ bench.end(len / 1e6);
+}
+
+function benchFloat(buff, fn, len, noAssert) {
+ bench.start();
+ for (var i = 0; i < len; i++) {
+ buff[fn](i * 0.1, 0, noAssert);
+ }
+ bench.end(len / 1e6);
+}
diff --git a/benchmark/buffers/dataview-set.js b/benchmark/buffers/dataview-set.js
new file mode 100644
index 000000000..ce0064edb
--- /dev/null
+++ b/benchmark/buffers/dataview-set.js
@@ -0,0 +1,57 @@
+
+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);
+}
diff --git a/benchmark/client_latency.js b/benchmark/client_latency.js
deleted file mode 100644
index 09630a0da..000000000
--- a/benchmark/client_latency.js
+++ /dev/null
@@ -1,80 +0,0 @@
-// first start node http_simple.js
-var http = require('http');
-
-var latency = [];
-
-var numRequests = parseInt(process.argv[2], 10) || 100;
-var maxSockets = parseInt(process.argv[3], 10) || 100;
-var runs = parseInt(process.argv[4], 10) || 100;
-var prefix = process.argv[5] || '';
-if (prefix) prefix += '_';
-var r = 0;
-
-var port = parseInt(process.env.PORT, 10) || 8000;
-var host = process.env.HOST || '127.0.0.1';
-
-http.globalAgent.maxSockets = maxSockets;
-
-run();
-
-function run() {
- if (r++ === runs) {
- return finish();
- }
-
- // make numRequests in parallel
- // retain the order in which they are *made*. This requires trapping
- // each one in a closure, since otherwise, we'll of course end
- // up mostly sorting them in ascending order, since the cb from a
- // fast request will almost always be called before the cb from a
- // slow one.
- var c = numRequests;
- var lat = [];
- latency.push(lat);
- for (var i = 0; i < numRequests; i++) (function (i) {
- makeRequest(function(l) {
- lat[i] = l;
- c--;
- if (c === 0) run();
- });
- })(i);
-}
-
-function makeRequest(cb) {
- var opts = { host: host,
- port: port,
- uri: 'http://'+host+':'+port+'/bytes/12',
- forever: true,
- path: '/bytes/12' };
- var pre = Date.now();
- var req = http.get(opts, function(res) {
- return cb(Date.now() - pre);
- });
-}
-
-function finish() {
- var data = [];
- latency.forEach(function(run, i) {
- run.forEach(function(l, j) {
- data[j] = data[j] || [];
- data[j][i] = l;
- });
- });
-
- data = data.map(function (l, i) {
- return l.join('\t')
- }).join('\n') + '\n';
-
- var fname = prefix +
- 'client_latency_' +
- numRequests + '_' +
- maxSockets + '_' +
- runs + '.tab';
- var path = require('path');
- fname = path.resolve(__dirname, '..', 'out', fname);
- fname = path.relative(process.cwd(), fname);
- require('fs').writeFile(fname, data, function(er) {
- if (er) throw er;
- console.log('written: %s', fname);
- });
-}
diff --git a/benchmark/common.js b/benchmark/common.js
new file mode 100644
index 000000000..3c478bd01
--- /dev/null
+++ b/benchmark/common.js
@@ -0,0 +1,196 @@
+var assert = require('assert');
+var path = require('path');
+
+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 child = spawn(process.execPath, [ test ], { 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();
+ 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(' ');
+}
diff --git a/benchmark/compare.js b/benchmark/compare.js
new file mode 100644
index 000000000..b3576ba4a
--- /dev/null
+++ b/benchmark/compare.js
@@ -0,0 +1,138 @@
+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 n = 2;
+
+run();
+
+function run() {
+ if (n === 0)
+ return compare();
+
+ n--;
+
+ var node = nodes[n];
+ console.error('running %s', node);
+ var env = {};
+ for (var i in process.env)
+ env[i] = process.env[i];
+ env.NODE = node;
+ var child = spawn('make', [ runBench ], { env: env });
+
+ var out = '';
+ 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] = 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 = res[nodes[0]];
+ var n1 = 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, reset);
+ var r1 = util.format('%s%s: %d%s', r, nodes[1], n1, 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);
+}
diff --git a/benchmark/crypto/cipher-stream.js b/benchmark/crypto/cipher-stream.js
new file mode 100644
index 000000000..2a48a7e3f
--- /dev/null
+++ b/benchmark/crypto/cipher-stream.js
@@ -0,0 +1,103 @@
+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 dur = conf.dur;
+
+ 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 = written / (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);
+}
diff --git a/benchmark/fast_buffer2.js b/benchmark/fast_buffer2.js
deleted file mode 100644
index 861ae3baa..000000000
--- a/benchmark/fast_buffer2.js
+++ /dev/null
@@ -1,42 +0,0 @@
-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++
diff --git a/benchmark/fast_buffer2_creation.js b/benchmark/fast_buffer2_creation.js
deleted file mode 100644
index 877f5695d..000000000
--- a/benchmark/fast_buffer2_creation.js
+++ /dev/null
@@ -1,6 +0,0 @@
-
-FastBuffer = require('./fast_buffer2').FastBuffer;
-for (var i = 0; i < 1e6; i++) {
- b = new FastBuffer(10);
- b[1] = 2;
-}
diff --git a/benchmark/fast_buffer_creation.js b/benchmark/fast_buffer_creation.js
deleted file mode 100644
index fbd0c7579..000000000
--- a/benchmark/fast_buffer_creation.js
+++ /dev/null
@@ -1,4 +0,0 @@
-for (var i = 0; i < 1e6; i++) {
- b = new Buffer(10);
- b[1] = 2;
-}
diff --git a/benchmark/fs-readfile.js b/benchmark/fs-readfile.js
deleted file mode 100644
index 3aa72e1a4..000000000
--- a/benchmark/fs-readfile.js
+++ /dev/null
@@ -1,72 +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 filename = path.resolve(__dirname, 'http.sh');
-var fs = require('fs');
-var count = 0;
-var go = true;
-var len = -1;
-var assert = require('assert');
-
-var concurrency = 1;
-var encoding = null;
-var time = 10;
-
-for (var i = 2; i < process.argv.length; i++) {
- var arg = process.argv[i];
- if (arg.match(/^-e$/)) {
- encoding = process.argv[++i] || null;
- } else if (arg.match(/^-c$/)) {
- concurrency = ~~process.argv[++i];
- if (concurrency < 1) concurrency = 1;
- } else if (arg === '-t') {
- time = ~~process.argv[++i];
- if (time < 1) time = 1;
- }
-}
-
-
-setTimeout(function() {
- go = false;
-}, time * 1000);
-
-function round(n) {
- return Math.floor(n * 100) / 100;
-}
-
-var start = process.hrtime();
-while (concurrency--) readFile();
-
-function readFile() {
- if (!go) {
- process.stdout.write('\n');
- console.log('read the file %d times (higher is better)', count);
- var end = process.hrtime();
- var elapsed = [end[0] - start[0], end[1] - start[1]];
- var ns = elapsed[0] * 1E9 + elapsed[1];
- var nsper = round(ns / count);
- console.log('%d ns per read (lower is better)', nsper);
- var readsper = round(count / (ns / 1E9));
- console.log('%d reads per sec (higher is better)', readsper);
- process.exit(0);
- return;
- }
-
- if (!(count % 1000)) {
- process.stdout.write('.');
- }
-
- if (encoding) fs.readFile(filename, encoding, then);
- else fs.readFile(filename, then);
-
- function then(er, data) {
- assert.ifError(er);
- count++;
- // basic sanity test: we should get the same number of bytes each time.
- if (count === 1) len = data.length;
- else assert(len === data.length);
- readFile();
- }
-}
diff --git a/benchmark/fs-write-stream-throughput.js b/benchmark/fs-write-stream-throughput.js
new file mode 100644
index 000000000..b131d5b73
--- /dev/null
+++ b/benchmark/fs-write-stream-throughput.js
@@ -0,0 +1,96 @@
+
+// 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();
+ }
+ }
+}
diff --git a/benchmark/fs/read-stream-throughput.js b/benchmark/fs/read-stream-throughput.js
new file mode 100644
index 000000000..af9a235b9
--- /dev/null
+++ b/benchmark/fs/read-stream-throughput.js
@@ -0,0 +1,87 @@
+// 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();
+ }
+}
diff --git a/benchmark/fs/readfile.js b/benchmark/fs/readfile.js
new file mode 100644
index 000000000..ac3241901
--- /dev/null
+++ b/benchmark/fs/readfile.js
@@ -0,0 +1,48 @@
+// 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();
+}
diff --git a/benchmark/fs/write-stream-throughput.js b/benchmark/fs/write-stream-throughput.js
new file mode 100644
index 000000000..57ce4c4fe
--- /dev/null
+++ b/benchmark/fs/write-stream-throughput.js
@@ -0,0 +1,78 @@
+// 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');
+ }
+}
diff --git a/benchmark/function_call/bench.js b/benchmark/function_call/bench.js
deleted file mode 100644
index 55e6ea116..000000000
--- a/benchmark/function_call/bench.js
+++ /dev/null
@@ -1,43 +0,0 @@
-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));
-
-
diff --git a/benchmark/function_call/binding.cc b/benchmark/function_call/binding.cc
deleted file mode 100644
index 75882c1ef..000000000
--- a/benchmark/function_call/binding.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-#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);
-}
diff --git a/benchmark/function_call/wscript b/benchmark/function_call/wscript
deleted file mode 100644
index 3db367fe0..000000000
--- a/benchmark/function_call/wscript
+++ /dev/null
@@ -1,15 +0,0 @@
-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'
diff --git a/benchmark/http-flamegraph.sh b/benchmark/http-flamegraph.sh
new file mode 100644
index 000000000..7df0c1575
--- /dev/null
+++ b/benchmark/http-flamegraph.sh
@@ -0,0 +1,116 @@
+#!/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'
diff --git a/benchmark/http/cluster.js b/benchmark/http/cluster.js
new file mode 100644
index 000000000..12bb8d594
--- /dev/null
+++ b/benchmark/http/cluster.js
@@ -0,0 +1,38 @@
+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);
+ });
+}
diff --git a/benchmark/http/simple.js b/benchmark/http/simple.js
new file mode 100644
index 000000000..8a1be9805
--- /dev/null
+++ b/benchmark/http/simple.js
@@ -0,0 +1,23 @@
+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);
+}
diff --git a/benchmark/http_simple.js b/benchmark/http_simple.js
index 236b046e9..36800f2c9 100644
--- a/benchmark/http_simple.js
+++ b/benchmark/http_simple.js
@@ -4,8 +4,6 @@ var path = require('path'),
var port = parseInt(process.env.PORT || 8000);
-console.log('pid ' + process.pid);
-
var fixed = makeString(20 * 1024, 'C'),
storedBytes = {},
storedBuffer = {},
@@ -18,13 +16,13 @@ if (useDomains) {
var domain = require('domain');
var gdom = domain.create();
gdom.on('error', function(er) {
- console.log('Error on global domain', er);
+ console.error('Error on global domain', er);
throw er;
});
gdom.enter();
}
-var server = http.createServer(function (req, res) {
+var server = module.exports = http.createServer(function (req, res) {
if (useDomains) {
var dom = domain.create();
dom.add(req);
@@ -43,7 +41,6 @@ var server = http.createServer(function (req, res) {
if (n <= 0)
throw new Error('bytes called with n <= 0')
if (storedBytes[n] === undefined) {
- console.log('create storedBytes[n]');
storedBytes[n] = makeString(n, 'C');
}
body = storedBytes[n];
@@ -53,7 +50,6 @@ var server = http.createServer(function (req, res) {
if (n <= 0)
throw new Error('buffer 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);
@@ -66,7 +62,6 @@ var server = http.createServer(function (req, res) {
if (n <= 0)
throw new Error('unicode called with n <= 0');
if (storedUnicode[n] === undefined) {
- console.log('create storedUnicode[n]');
storedUnicode[n] = makeString(n, '\u263A');
}
body = storedUnicode[n];
@@ -120,9 +115,6 @@ function makeString(size, c) {
}
server.listen(port, function () {
- console.log('Listening at http://127.0.0.1:'+port+'/');
-});
-
-process.on('exit', function() {
- console.error('libuv counters', process.uvCounters());
+ if (module === require.main)
+ console.error('Listening at http://127.0.0.1:'+port+'/');
});
diff --git a/benchmark/http_simple_bench.sh b/benchmark/http_simple_bench.sh
index 6ba8e0664..694822797 100755
--- a/benchmark/http_simple_bench.sh
+++ b/benchmark/http_simple_bench.sh
@@ -1,7 +1,7 @@
#!/bin/bash
SERVER=127.0.0.1
-PORT=8000
+PORT=${PORT:=8000}
# You may want to configure your TCP settings to make many ports available
# to node and ab. On macintosh use:
@@ -19,9 +19,6 @@ 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() {
diff --git a/benchmark/io.c b/benchmark/io.c
index a4f457517..3b31eb02a 100644
--- a/benchmark/io.c
+++ b/benchmark/io.c
@@ -14,7 +14,7 @@
static int c = 0;
static int tsize = 1000 * 1048576;
-static const char path[] = "/tmp/wt.dat";
+static const char* path = "/tmp/wt.dat";
static char buf[65536];
static uint64_t now(void) {
@@ -45,7 +45,6 @@ static void writetest(int size, size_t bsize)
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);
@@ -66,7 +65,7 @@ static void writetest(int size, size_t bsize)
elapsed = (end - start) / 1e6;
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);
}
void readtest(int size, size_t bsize)
@@ -106,11 +105,13 @@ void cleanup() {
unlink(path);
}
-int main()
+int main(int argc, char** argv)
{
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]);
}
diff --git a/benchmark/io.js b/benchmark/io.js
deleted file mode 100644
index 1c18e05f6..000000000
--- a/benchmark/io.js
+++ /dev/null
@@ -1,109 +0,0 @@
-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, bsize);
- 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, bsize);
- 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();
diff --git a/benchmark/misc/function_call/.gitignore b/benchmark/misc/function_call/.gitignore
new file mode 100644
index 000000000..567609b12
--- /dev/null
+++ b/benchmark/misc/function_call/.gitignore
@@ -0,0 +1 @@
+build/
diff --git a/benchmark/misc/function_call/Makefile b/benchmark/misc/function_call/Makefile
new file mode 100644
index 000000000..9dc1f3032
--- /dev/null
+++ b/benchmark/misc/function_call/Makefile
@@ -0,0 +1,2 @@
+binding:
+ node-gyp rebuild --nodedir=../../..
diff --git a/benchmark/misc/function_call/binding.cc b/benchmark/misc/function_call/binding.cc
new file mode 100644
index 000000000..6ea928464
--- /dev/null
+++ b/benchmark/misc/function_call/binding.cc
@@ -0,0 +1,18 @@
+#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);
diff --git a/benchmark/misc/function_call/binding.gyp b/benchmark/misc/function_call/binding.gyp
new file mode 100644
index 000000000..3bfb84493
--- /dev/null
+++ b/benchmark/misc/function_call/binding.gyp
@@ -0,0 +1,8 @@
+{
+ 'targets': [
+ {
+ 'target_name': 'binding',
+ 'sources': [ 'binding.cc' ]
+ }
+ ]
+}
diff --git a/benchmark/misc/function_call/index.js b/benchmark/misc/function_call/index.js
new file mode 100644
index 000000000..fc8542a06
--- /dev/null
+++ b/benchmark/misc/function_call/index.js
@@ -0,0 +1,42 @@
+// 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);
+}
diff --git a/benchmark/misc/next-tick-breadth.js b/benchmark/misc/next-tick-breadth.js
new file mode 100644
index 000000000..652408144
--- /dev/null
+++ b/benchmark/misc/next-tick-breadth.js
@@ -0,0 +1,21 @@
+
+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);
+ }
+}
diff --git a/benchmark/misc/next-tick-depth.js b/benchmark/misc/next-tick-depth.js
new file mode 100644
index 000000000..b8ae27879
--- /dev/null
+++ b/benchmark/misc/next-tick-depth.js
@@ -0,0 +1,40 @@
+// 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);
+ }
+}
diff --git a/benchmark/misc/spawn-echo.js b/benchmark/misc/spawn-echo.js
new file mode 100644
index 000000000..2b1b989e6
--- /dev/null
+++ b/benchmark/misc/spawn-echo.js
@@ -0,0 +1,25 @@
+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);
+ });
+}
diff --git a/benchmark/misc/startup.js b/benchmark/misc/startup.js
new file mode 100644
index 000000000..aa5b4420f
--- /dev/null
+++ b/benchmark/misc/startup.js
@@ -0,0 +1,40 @@
+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);
+ });
+ }
+}
diff --git a/benchmark/misc/string-creation.js b/benchmark/misc/string-creation.js
new file mode 100644
index 000000000..74dabd66c
--- /dev/null
+++ b/benchmark/misc/string-creation.js
@@ -0,0 +1,16 @@
+
+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);
+}
diff --git a/benchmark/misc/timers.js b/benchmark/misc/timers.js
new file mode 100644
index 000000000..23f571bb4
--- /dev/null
+++ b/benchmark/misc/timers.js
@@ -0,0 +1,40 @@
+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);
+ }
+}
diff --git a/benchmark/misc/url.js b/benchmark/misc/url.js
new file mode 100644
index 000000000..6c2799b6c
--- /dev/null
+++ b/benchmark/misc/url.js
@@ -0,0 +1,40 @@
+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));
+}
diff --git a/benchmark/misc/v8-bench.js b/benchmark/misc/v8-bench.js
new file mode 100644
index 000000000..8bf49f3f6
--- /dev/null
+++ b/benchmark/misc/v8-bench.js
@@ -0,0 +1,18 @@
+// 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');
diff --git a/benchmark/net/net-c2s.js b/benchmark/net/net-c2s.js
new file mode 100644
index 000000000..49de7c77c
--- /dev/null
+++ b/benchmark/net/net-c2s.js
@@ -0,0 +1,112 @@
+// 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);
+ });
+ });
+}
diff --git a/benchmark/net/net-pipe.js b/benchmark/net/net-pipe.js
new file mode 100644
index 000000000..2a5ed8e48
--- /dev/null
+++ b/benchmark/net/net-pipe.js
@@ -0,0 +1,115 @@
+// 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);
+ });
+ });
+}
diff --git a/benchmark/net/net-s2c.js b/benchmark/net/net-s2c.js
new file mode 100644
index 000000000..79e22494a
--- /dev/null
+++ b/benchmark/net/net-s2c.js
@@ -0,0 +1,112 @@
+// 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);
+ });
+ });
+}
diff --git a/benchmark/net/tcp-raw-c2s.js b/benchmark/net/tcp-raw-c2s.js
new file mode 100644
index 000000000..e5b3662a8
--- /dev/null
+++ b/benchmark/net/tcp-raw-c2s.js
@@ -0,0 +1,136 @@
+// 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();
+ }
+}
diff --git a/benchmark/net/tcp-raw-pipe.js b/benchmark/net/tcp-raw-pipe.js
new file mode 100644
index 000000000..4e53c1f0c
--- /dev/null
+++ b/benchmark/net/tcp-raw-pipe.js
@@ -0,0 +1,149 @@
+// 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();
+ }
+}
diff --git a/benchmark/net/tcp-raw-s2c.js b/benchmark/net/tcp-raw-s2c.js
new file mode 100644
index 000000000..93a917e06
--- /dev/null
+++ b/benchmark/net/tcp-raw-s2c.js
@@ -0,0 +1,136 @@
+// 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);
+ };
+}
diff --git a/benchmark/next-tick-2.js b/benchmark/next-tick-2.js
deleted file mode 100644
index 44a2b41b5..000000000
--- a/benchmark/next-tick-2.js
+++ /dev/null
@@ -1,41 +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 count = 2e6,
- left = count,
- start;
-
-function onNextTick() {
- if (--left) {
- process.nextTick(onNextTick);
- } else {
- finalize();
- }
-}
-
-function finalize() {
- var duration = (new Date()).getTime() - start,
- ticksPerSec = count / duration * 1000;
- console.log("nextTick callbacks per second: " + Math.round(ticksPerSec));
-}
-
-start = (new Date()).getTime();
-process.nextTick(onNextTick);
diff --git a/benchmark/next-tick.js b/benchmark/next-tick.js
deleted file mode 100644
index 9352f8dc0..000000000
--- a/benchmark/next-tick.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// run with `time node benchmark/next-tick.js`
-var assert = require('assert');
-
-var N = 1e7;
-var n = 0;
-
-process.on('exit', function() {
- assert.equal(n, N);
-});
-
-function cb() {
- n++;
-}
-
-for (var i = 0; i < N; ++i) {
- process.nextTick(cb);
-}
diff --git a/benchmark/process_loop.js b/benchmark/process_loop.js
deleted file mode 100644
index eeba06ab9..000000000
--- a/benchmark/process_loop.js
+++ /dev/null
@@ -1,19 +0,0 @@
-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);
diff --git a/benchmark/run.js b/benchmark/run.js
deleted file mode 100644
index 289168737..000000000
--- a/benchmark/run.js
+++ /dev/null
@@ -1,31 +0,0 @@
-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);
diff --git a/benchmark/settimeout.js b/benchmark/settimeout.js
deleted file mode 100644
index dd52dc90e..000000000
--- a/benchmark/settimeout.js
+++ /dev/null
@@ -1,15 +0,0 @@
-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();
diff --git a/benchmark/startup.js b/benchmark/startup.js
deleted file mode 100644
index 97bb8d518..000000000
--- a/benchmark/startup.js
+++ /dev/null
@@ -1,26 +0,0 @@
-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();
diff --git a/benchmark/static_http_server.js b/benchmark/static_http_server.js
index 488422443..b3a83785e 100644
--- a/benchmark/static_http_server.js
+++ b/benchmark/static_http_server.js
@@ -31,6 +31,7 @@ server.listen(port, function() {
path: '/',
agent: agent
}, function(res) {
+ res.resume();
res.on('end', function() {
if (++responses === n) {
server.close();
diff --git a/benchmark/string_creation.js b/benchmark/string_creation.js
deleted file mode 100644
index 7f81ec109..000000000
--- a/benchmark/string_creation.js
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-for (var i = 0; i < 9e7; i++) {
- s = '01234567890';
- s[1] = "a";
-}
diff --git a/benchmark/throughput-child.js b/benchmark/throughput-child.js
deleted file mode 100644
index 5cd5c4764..000000000
--- a/benchmark/throughput-child.js
+++ /dev/null
@@ -1,25 +0,0 @@
-var net = require('net');
-var received = 0;
-var start = new Date();
-var socket = net.connect(8000);
-
-socket.on('data', function(d) {
- received += d.length;
-});
-
-var interval = setInterval(function() {
- // After 1 gigabyte shutdown.
- if (received > 10 * 1024 * 1024 * 1024) {
- socket.destroy();
- clearInterval(interval);
- process.exit(0);
- } else {
- // Otherwise print some stats.
- var now = new Date();
- var gigabytes = received / (1024 * 1024 * 1024);
- var gigabits = gigabytes * 8.0;
- var millisec = now - start;
- var sec = millisec / 1000;
- console.log((gigabits / sec) + " gbit/sec")
- }
-}, 1000);
diff --git a/benchmark/throughput.js b/benchmark/throughput.js
deleted file mode 100644
index a1ff1b653..000000000
--- a/benchmark/throughput.js
+++ /dev/null
@@ -1,21 +0,0 @@
-var fork = require('child_process').fork;
-var net = require('net');
-var buffer = new Buffer(1024 * 1024);
-
-function write(socket) {
- if (!socket.writable) return;
-
- socket.write(buffer, function() {
- write(socket);
- });
-}
-
-var server = net.createServer(function(socket) {
- server.close();
- write(socket);
-});
-
-server.listen(8000, function() {
- fork(__dirname + '/throughput-child.js');
-});
-
diff --git a/benchmark/timers.js b/benchmark/timers.js
deleted file mode 100644
index 095cca119..000000000
--- a/benchmark/timers.js
+++ /dev/null
@@ -1,5 +0,0 @@
-function next (i) {
- if (i <= 0) return;
- setTimeout(function () { next(i-1); }, 1);
-}
-next(700);
diff --git a/benchmark/tls-connect.js b/benchmark/tls-connect.js
deleted file mode 100644
index 512adca14..000000000
--- a/benchmark/tls-connect.js
+++ /dev/null
@@ -1,86 +0,0 @@
-
-var assert = require('assert'),
- fs = require('fs'),
- path = require('path'),
- tls = require('tls');
-
-
-var target_connections = 10000,
- concurrency = 10;
-
-for (var i = 2; i < process.argv.length; i++) {
- switch (process.argv[i]) {
- case '-c':
- concurrency = ~~process.argv[++i];
- break;
-
- case '-n':
- target_connections = ~~process.argv[++i];
- break;
-
- default:
- throw new Error('Invalid flag: ' + process.argv[i]);
- }
-}
-
-
-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') ] };
-
-var server = tls.createServer(options, onConnection);
-server.listen(8000);
-
-
-var initiated_connections = 0,
- server_connections = 0,
- client_connections = 0,
- start = Date.now();
-
-for (var i = 0; i < concurrency; i++)
- makeConnection();
-
-
-process.on('exit', onExit);
-
-
-function makeConnection() {
- if (initiated_connections >= target_connections)
- return;
-
- initiated_connections++;
-
- var conn = tls.connect(8000, function() {
- client_connections++;
-
- if (client_connections % 100 === 0)
- console.log(client_connections + ' of ' + target_connections +
- ' connections made');
-
- conn.end();
- makeConnection();
- });
-}
-
-
-function onConnection(conn) {
- server_connections++;
-
- if (server_connections === target_connections)
- server.close();
-}
-
-
-function onExit() {
- var end = Date.now(),
- s = (end - start) / 1000,
- persec = Math.round(target_connections / s);
-
- assert.equal(initiated_connections, target_connections);
- assert.equal(client_connections, target_connections);
- assert.equal(server_connections, target_connections);
-
- console.log('%d connections in %d s', target_connections, s);
- console.log('%d connections per second', persec);
-}
diff --git a/benchmark/tls-fragmentation.js b/benchmark/tls-fragmentation.js
deleted file mode 100644
index 5abe093cd..000000000
--- a/benchmark/tls-fragmentation.js
+++ /dev/null
@@ -1,63 +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.
-
-if (!process.versions.openssl) {
- console.error('Skipping because node compiled without OpenSSL.');
- process.exit(0);
-}
-
-var common = require('../common');
-var assert = require('assert');
-var tls = require('tls');
-var fs = require('fs');
-var path = require('path');
-
-var options = {
- key: fs.readFileSync(path.join(common.fixturesDir, 'test_key.pem')),
- cert: fs.readFileSync(path.join(common.fixturesDir, 'test_cert.pem'))
-};
-
-var fragment = 'fr';
-var dataSize = 1024 * 1024;
-var sent = 0;
-var received = 0;
-
-var server = tls.createServer(options, function (stream) {
- for (sent = 0; sent <= dataSize; sent += fragment.length) {
- stream.write(fragment);
- }
- stream.end();
-});
-
-server.listen(common.PORT, function () {
- var client = tls.connect(common.PORT, function () {
- client.on('data', function (data) {
- received += data.length;
- });
- client.on('end', function () {
- server.close();
- });
- });
-});
-
-process.on('exit', function () {
- assert.equal(sent, received);
-});
diff --git a/benchmark/tls/throughput.js b/benchmark/tls/throughput.js
new file mode 100644
index 000000000..88118afbc
--- /dev/null
+++ b/benchmark/tls/throughput.js
@@ -0,0 +1,74 @@
+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();
+ }
+}
+
diff --git a/benchmark/tls/tls-connect.js b/benchmark/tls/tls-connect.js
new file mode 100644
index 000000000..0da448ee8
--- /dev/null
+++ b/benchmark/tls/tls-connect.js
@@ -0,0 +1,63 @@
+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));
+}
diff --git a/benchmark/v8_bench.js b/benchmark/v8_bench.js
deleted file mode 100644
index fbd3748ca..000000000
--- a/benchmark/v8_bench.js
+++ /dev/null
@@ -1,15 +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 = console.log;
-
-global.load = function (x) {
- var source = fs.readFileSync(path.join(dir, x), 'utf8');
- vm.runInThisContext(source, x);
-}
-
-load('run.js');
diff --git a/common.gypi b/common.gypi
index 26a276cdc..72138f36b 100644
--- a/common.gypi
+++ b/common.gypi
@@ -9,6 +9,7 @@
'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.
@@ -45,6 +46,9 @@
'LinkIncremental': 2, # enable incremental linking
},
},
+ 'xcode_settings': {
+ 'GCC_OPTIMIZATION_LEVEL': '0', # stop gyp from defaulting to -Os
+ },
},
'Release': {
'conditions': [
@@ -155,16 +159,16 @@
'BUILDING_V8_SHARED=1',
'BUILDING_UV_SHARED=1',
],
- }, {
- 'defines': [
- '_LARGEFILE_SOURCE',
- '_FILE_OFFSET_BITS=64',
- ],
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
- 'cflags': [ '-Wall', '-pthread', ],
+ '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' ],
@@ -193,7 +197,6 @@
'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
- 'GCC_VERSION': '4.2',
'PREBINDING': 'NO', # No -Wl,-prebind
'MACOSX_DEPLOYMENT_TARGET': '10.5', # -mmacosx-version-min=10.5
'USE_HEADERMAP': 'NO',
@@ -221,6 +224,9 @@
}],
],
}],
+ ['OS=="freebsd" and node_use_dtrace=="true"', {
+ 'libraries': [ '-lelf' ],
+ }]
],
}
}
diff --git a/configure b/configure
index aa8c99846..a5a18e33d 100755
--- a/configure
+++ b/configure
@@ -3,6 +3,7 @@ import optparse
import os
import pprint
import re
+import shlex
import subprocess
import sys
@@ -29,11 +30,6 @@ parser.add_option("--without-npm",
dest="without_npm",
help="Don\'t install the bundled npm package manager")
-parser.add_option("--without-waf",
- action="store_true",
- dest="without_waf",
- help="Don\'t install node-waf")
-
parser.add_option("--without-ssl",
action="store_true",
dest="without_ssl",
@@ -103,6 +99,13 @@ parser.add_option("--openssl-libpath",
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("--no-ssl2",
action="store_true",
dest="no_ssl2",
@@ -128,10 +131,70 @@ parser.add_option("--shared-zlib-libname",
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 supported systems)")
+ help="Build with DTrace (default is true on sunos)")
parser.add_option("--without-dtrace",
action="store_true",
@@ -148,6 +211,16 @@ parser.add_option("--without-etw",
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",
@@ -176,12 +249,22 @@ parser.add_option("--with-arm-float-abi",
help="Specifies which floating-point ABI to use. Valid values are: "
"soft, softfp, 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",
@@ -216,7 +299,7 @@ def cc_macros():
"""Checks predefined macros using the CC command."""
try:
- p = subprocess.Popen(CC.split() + ['-dM', '-E', '-'],
+ p = subprocess.Popen(shlex.split(CC) + ['-dM', '-E', '-'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
@@ -236,7 +319,6 @@ def cc_macros():
k = {}
for line in out:
- import shlex
lst = shlex.split(line)
if len(lst) > 2:
key = lst[1]
@@ -254,6 +336,11 @@ def is_arch_armv7():
'__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
@@ -321,13 +408,13 @@ def host_arch_win():
def compiler_version():
try:
- proc = subprocess.Popen(CC.split() + ['--version'], stdout=subprocess.PIPE)
+ 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(CC.split() + ['-dumpversion'], stdout=subprocess.PIPE)
+ proc = subprocess.Popen(shlex.split(CC) + ['-dumpversion'], stdout=subprocess.PIPE)
version = tuple(map(int, proc.communicate()[0].split('.')))
return (version, is_clang)
@@ -340,22 +427,22 @@ def configure_arm(o):
hard_float = options.arm_float_abi == 'hard'
else:
hard_float = arm_hard_float_abi()
- o['variables']['v8_use_arm_eabi_hardfloat'] = b(hard_float)
armv7 = is_arch_armv7()
- if armv7:
- # CHECKME VFPv3 implies ARMv7+ but is the reverse true as well?
- o['variables']['arm_fpu'] = 'vfpv3'
- o['variables']['arm_neon'] = 0
+ # 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_node(o):
- # TODO add gdb
+ 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_install_waf'] = b(not options.without_waf)
o['variables']['node_unsafe_optimizations'] = (
1 if options.unsafe_optimizations else 0)
o['default_configuration'] = 'Debug' if options.debug else 'Release'
@@ -383,10 +470,17 @@ def configure_node(o):
# SunOS, and we haven't implemented it.)
if sys.platform.startswith('sunos'):
o['variables']['node_use_dtrace'] = b(not options.without_dtrace)
- elif b(options.with_dtrace) == 'true':
- raise Exception('DTrace is currently only supported on SunOS systems.')
+ elif sys.platform.startswith('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 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']
@@ -394,11 +488,19 @@ def configure_node(o):
# By default, enable ETW on Windows.
if sys.platform.startswith('win32'):
o['variables']['node_use_etw'] = b(not options.without_etw);
- elif b(options.with_etw) == 'true':
+ 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 sys.platform.startswith('win32'):
+ 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:
@@ -419,6 +521,48 @@ def configure_libz(o):
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)
@@ -462,8 +606,22 @@ def configure_openssl(o):
o['cflags'] += cflags.split()
+def configure_winsdk(o):
+ if not sys.platform.startswith('win32'):
+ 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."
+
+
output = {
- 'variables': {},
+ 'variables': { 'python': sys.executable },
'include_dirs': [],
'libraries': [],
'defines': [],
@@ -472,8 +630,12 @@ output = {
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
@@ -494,11 +656,23 @@ def write(filename, data):
write('config.gypi', "# Do not edit. Generated by the configure script.\n" +
pprint.pformat(output, indent=2) + "\n")
-write('config.mk', "# Do not edit. Generated by the configure script.\n" +
- ("BUILDTYPE=%s\n" % ('Debug' if options.debug else 'Release')))
+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)
-if os.name == 'nt':
- gyp_args = ['-f', 'msvs', '-G', 'msvs_version=2010']
+if options.use_ninja:
+ gyp_args = ['-f', 'ninja']
+elif options.use_xcode:
+ gyp_args = ['-f', 'xcode']
+elif os.name == 'nt':
+ gyp_args = ['-f', 'msvs', '-G', 'msvs_version=auto']
elif options.dest_os:
gyp_args = ['-f', 'make-' + options.dest_os]
else:
diff --git a/deps/cares/.gitignore b/deps/cares/.gitignore
new file mode 100644
index 000000000..79b4d2a16
--- /dev/null
+++ b/deps/cares/.gitignore
@@ -0,0 +1,15 @@
+/Debug/
+/out/
+/Release/
+
+/cares.Makefile
+/cares.target.mk
+/Makefile
+
+/*.opensdf
+/*.sdf
+/*.sln
+/*.suo
+/*.vcxproj
+/*.vcxproj.filters
+/*.vcxproj.user
diff --git a/deps/cares/build/gcc_version.py b/deps/cares/build/gcc_version.py
new file mode 100644
index 000000000..da019e866
--- /dev/null
+++ b/deps/cares/build/gcc_version.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+import os
+import re
+import subprocess
+import sys
+
+
+def DoMain(*args):
+ cc = os.environ.get('CC', 'gcc')
+ stdin, stderr = os.pipe()
+ subprocess.call([cc, '-v'], stderr=stderr)
+ output = os.read(stdin, 4096)
+ match = re.search("\ngcc version (\d+\.\d+\.\d+)", output)
+ if match:
+ print(match.group(1))
+
+
+if __name__ == '__main__':
+ DoMain(*sys.argv)
diff --git a/deps/cares/cares.gyp b/deps/cares/cares.gyp
new file mode 100644
index 000000000..757671271
--- /dev/null
+++ b/deps/cares/cares.gyp
@@ -0,0 +1,160 @@
+{
+ 'target_defaults': {
+ 'conditions': [
+ ['OS!="win"', {
+ 'defines': [
+ '_DARWIN_USE_64_BIT_INODE=1',
+ '_LARGEFILE_SOURCE',
+ '_FILE_OFFSET_BITS=64',
+ '_GNU_SOURCE'
+ ]
+ }],
+ ['OS=="solaris"', {
+ 'defines': [
+ '__EXTENSIONS__',
+ '_XOPEN_SOURCE=500'
+ ]
+ }]
+ ]
+ },
+
+ 'targets': [
+ {
+ 'target_name': 'cares',
+ 'type': '<(library)',
+ 'include_dirs': [ 'include', 'src' ],
+ 'direct_dependent_settings': {
+ 'include_dirs': [ 'include' ]
+ },
+ 'defines': [ 'HAVE_CONFIG_H' ],
+ 'sources': [
+ 'common.gypi',
+ 'include/ares.h',
+ 'include/ares_version.h',
+ 'include/nameser.h',
+ 'src/ares_cancel.c',
+ 'src/ares__close_sockets.c',
+ 'src/ares_data.c',
+ 'src/ares_data.h',
+ 'src/ares_destroy.c',
+ 'src/ares_dns.h',
+ 'src/ares_expand_name.c',
+ 'src/ares_expand_string.c',
+ 'src/ares_fds.c',
+ 'src/ares_free_hostent.c',
+ 'src/ares_free_string.c',
+ 'src/ares_getenv.h',
+ 'src/ares_gethostbyaddr.c',
+ 'src/ares_gethostbyname.c',
+ 'src/ares__get_hostent.c',
+ 'src/ares_getnameinfo.c',
+ 'src/ares_getopt.c',
+ 'src/ares_getopt.h',
+ 'src/ares_getsock.c',
+ 'src/ares_init.c',
+ 'src/ares_ipv6.h',
+ 'src/ares_library_init.c',
+ 'src/ares_library_init.h',
+ 'src/ares_llist.c',
+ 'src/ares_llist.h',
+ 'src/ares_mkquery.c',
+ 'src/ares_nowarn.c',
+ 'src/ares_nowarn.h',
+ 'src/ares_options.c',
+ 'src/ares_parse_aaaa_reply.c',
+ 'src/ares_parse_a_reply.c',
+ 'src/ares_parse_mx_reply.c',
+ 'src/ares_parse_naptr_reply.c',
+ 'src/ares_parse_ns_reply.c',
+ 'src/ares_parse_ptr_reply.c',
+ 'src/ares_parse_soa_reply.c',
+ 'src/ares_parse_srv_reply.c',
+ 'src/ares_parse_txt_reply.c',
+ 'src/ares_platform.h',
+ 'src/ares_private.h',
+ 'src/ares_process.c',
+ 'src/ares_query.c',
+ 'src/ares__read_line.c',
+ 'src/ares_rules.h',
+ 'src/ares_search.c',
+ 'src/ares_send.c',
+ 'src/ares_setup.h',
+ 'src/ares_strcasecmp.c',
+ 'src/ares_strcasecmp.h',
+ 'src/ares_strdup.c',
+ 'src/ares_strdup.h',
+ 'src/ares_strerror.c',
+ 'src/ares_timeout.c',
+ 'src/ares__timeval.c',
+ 'src/ares_version.c',
+ 'src/ares_writev.c',
+ 'src/ares_writev.h',
+ 'src/bitncmp.c',
+ 'src/bitncmp.h',
+ 'src/inet_net_pton.c',
+ 'src/inet_net_pton.h',
+ 'src/inet_ntop.c',
+ 'src/inet_ntop.h',
+ 'src/setup_once.h',
+ 'src/windows_port.c'
+ ],
+ 'conditions': [
+ [ 'library=="static_library"', {
+ 'defines': [ 'CARES_STATICLIB' ]
+ }, {
+ 'defines': [ 'CARES_BUILDING_LIBRARY' ]
+ }],
+ [ 'OS=="win"', {
+ 'include_dirs': [ 'config/win32' ],
+ 'sources': [
+ 'config/win32/ares_config.h',
+ 'src/windows_port.c',
+ 'src/ares_getenv.c',
+ 'src/ares_iphlpapi.h',
+ 'src/ares_platform.c'
+ ],
+ 'libraries': [
+ '-lws2_32.lib',
+ '-liphlpapi.lib'
+ ],
+ }, {
+ # Not Windows i.e. POSIX
+ 'cflags': [
+ '-g',
+ '--std=gnu89',
+ '-pedantic',
+ '-Wall',
+ '-Wextra',
+ '-Wno-unused-parameter'
+ ],
+ }],
+ [ 'OS=="linux"', {
+ 'include_dirs': [ 'config/linux' ],
+ 'sources': [ 'config/linux/ares_config.h' ]
+ }],
+ [ 'OS=="mac"', {
+ 'include_dirs': [ 'config/darwin' ],
+ 'sources': [ 'config/darwin/ares_config.h' ]
+ }],
+ [ 'OS=="freebsd" or OS=="dragonflybsd"', {
+ 'include_dirs': [ 'config/freebsd' ],
+ 'sources': [ 'config/freebsd/ares_config.h' ]
+ }],
+ [ 'OS=="openbsd"', {
+ 'include_dirs': [ 'config/openbsd' ],
+ 'sources': [ 'config/openbsd/ares_config.h' ]
+ }],
+ [ 'OS=="solaris"', {
+ 'include_dirs': [ 'config/sunos' ],
+ 'sources': [ 'config/sunos/ares_config.h' ],
+ 'direct_dependent_settings': {
+ 'libraries': [
+ '-lsocket',
+ '-lnsl'
+ ]
+ }
+ }]
+ ]
+ }
+ ]
+}
diff --git a/deps/cares/common.gypi b/deps/cares/common.gypi
new file mode 100644
index 000000000..e707e4404
--- /dev/null
+++ b/deps/cares/common.gypi
@@ -0,0 +1,172 @@
+{
+ 'variables': {
+ 'visibility%': 'hidden',
+ 'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
+ 'component%': 'static_library',
+ 'host_arch%': '',
+ 'target_arch%': ''
+ },
+
+ 'target_defaults': {
+ 'default_configuration': 'Debug',
+ 'configurations': {
+
+ 'Debug': {
+ 'defines': [ 'DEBUG', '_DEBUG' ],
+ 'cflags': [ '-g', '-O0' ],
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'target_conditions': [
+ ['library=="static_library"', {
+ 'RuntimeLibrary': 1 # static debug
+ }, {
+ 'RuntimeLibrary': 3 # DLL 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'
+ }
+ },
+
+ 'Release': {
+ 'defines': [ 'NDEBUG' ],
+ 'cflags': [
+ '-O3',
+ '-fomit-frame-pointer',
+ '-fdata-sections',
+ '-ffunction-sections'
+ ],
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'target_conditions': [
+ ['library=="static_library"', {
+ 'RuntimeLibrary': 0, # static release
+ }, {
+ 'RuntimeLibrary': 2, # debug 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'
+ },
+ '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',
+ 'AdditionalOptions': [
+ '/MP', # compile across multiple CPUs
+ ],
+ },
+ 'VCLinkerTool': {
+ 'GenerateDebugInformation': 'true',
+ 'RandomizedBaseAddress': 2, # enable ASLR
+ 'DataExecutionPrevention': 2, # enable DEP
+ 'AllowIsolation': 'true',
+ 'SuppressStartupBanner': 'true',
+ 'target_conditions': [
+ ['_type=="executable"', {
+ 'SubSystem': 1, # console executable
+ }],
+ ],
+ },
+ },
+
+ 'xcode_settings': {
+ 'ALWAYS_SEARCH_USER_PATHS': 'NO',
+ 'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
+ 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
+ 'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
+ 'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
+ # GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden
+ 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
+ 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
+ 'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
+ 'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof
+ 'PREBINDING': 'NO', # No -Wl,-prebind
+ 'USE_HEADERMAP': 'NO',
+ 'WARNING_CFLAGS': [
+ '-Wall',
+ '-Wendif-labels',
+ '-W',
+ '-Wno-unused-parameter'
+ ]
+ },
+
+ 'conditions': [
+ ['OS == "win"', {
+ 'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin
+ 'defines': [
+ 'WIN32',
+ # we don't 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'
+ ],
+ }],
+
+ [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
+ 'variables': {
+ 'gcc_version%': '<!(python build/gcc_version.py)>)'
+ },
+ 'cflags': [ '-Wall' ],
+ 'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
+ 'conditions': [
+ [ 'host_arch != target_arch and target_arch=="ia32"', {
+ 'cflags': [ '-m32' ],
+ 'ldflags': [ '-m32' ]
+ }],
+ [ 'OS=="linux"', {
+ 'cflags': [ '-ansi' ]
+ }],
+ [ 'visibility=="hidden" and gcc_version >= "4.0.0"', {
+ 'cflags': [ '-fvisibility=hidden' ]
+ }],
+ ]
+ }]
+ ],
+
+ 'target_conditions': [
+ ['_type!="static_library"', {
+ 'cflags': [ '-fPIC' ],
+ 'xcode_settings': {
+ 'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
+ # (Equivalent to -fPIC)
+ 'OTHER_LDFLAGS': [ '-Wl,-search_paths_first' ]
+ }
+ }]
+ ]
+ }
+}
diff --git a/deps/uv/src/ares/config_cygwin/ares_config.h b/deps/cares/config/cygwin/ares_config.h
index 592a24598..592a24598 100644
--- a/deps/uv/src/ares/config_cygwin/ares_config.h
+++ b/deps/cares/config/cygwin/ares_config.h
diff --git a/deps/uv/src/ares/config_darwin/ares_config.h b/deps/cares/config/darwin/ares_config.h
index 920d922c8..920d922c8 100644
--- a/deps/uv/src/ares/config_darwin/ares_config.h
+++ b/deps/cares/config/darwin/ares_config.h
diff --git a/deps/uv/src/ares/config_freebsd/ares_config.h b/deps/cares/config/freebsd/ares_config.h
index 2f9b75d02..2f9b75d02 100644
--- a/deps/uv/src/ares/config_freebsd/ares_config.h
+++ b/deps/cares/config/freebsd/ares_config.h
diff --git a/deps/uv/src/ares/config_linux/ares_config.h b/deps/cares/config/linux/ares_config.h
index 8f8e33074..8f8e33074 100644
--- a/deps/uv/src/ares/config_linux/ares_config.h
+++ b/deps/cares/config/linux/ares_config.h
diff --git a/deps/uv/src/ares/config_netbsd/ares_config.h b/deps/cares/config/netbsd/ares_config.h
index b58914865..b58914865 100644
--- a/deps/uv/src/ares/config_netbsd/ares_config.h
+++ b/deps/cares/config/netbsd/ares_config.h
diff --git a/deps/uv/src/ares/config_openbsd/ares_config.h b/deps/cares/config/openbsd/ares_config.h
index b58914865..b58914865 100644
--- a/deps/uv/src/ares/config_openbsd/ares_config.h
+++ b/deps/cares/config/openbsd/ares_config.h
diff --git a/deps/uv/src/ares/config_sunos/ares_config.h b/deps/cares/config/sunos/ares_config.h
index fb8565e15..fb8565e15 100644
--- a/deps/uv/src/ares/config_sunos/ares_config.h
+++ b/deps/cares/config/sunos/ares_config.h
diff --git a/deps/uv/src/ares/config_win32/ares_config.h b/deps/cares/config/win32/ares_config.h
index 6ded63809..6ded63809 100644
--- a/deps/uv/src/ares/config_win32/ares_config.h
+++ b/deps/cares/config/win32/ares_config.h
diff --git a/deps/cares/include/ares.h b/deps/cares/include/ares.h
new file mode 100644
index 000000000..96eccabda
--- /dev/null
+++ b/deps/cares/include/ares.h
@@ -0,0 +1,622 @@
+
+/* Copyright 1998, 2009 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2007-2011 by Daniel Stenberg
+ *
+ * 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.
+ */
+
+#ifndef ARES__H
+#define ARES__H
+
+#include "ares_version.h" /* c-ares version defines */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+ !defined(WIN32) && !defined(__SYMBIAN32__)
+# define WIN32
+#endif
+
+/*************************** libuv patch ***************/
+
+/*
+ * We want to avoid autoconf altogether since there are a finite number of
+ * operating systems and simply build c-ares. Therefore we do not want the
+ * configurations provided by ares_build.h since we are always statically
+ * linking c-ares into libuv. Having a system dependent ares_build.h forces
+ * all users of ares.h to include the correct ares_build.h. We do not care
+ * about the linking checks provided by ares_rules.h. This would complicate
+ * the libuv build process.
+ */
+
+
+#if defined(WIN32)
+/* Configure process defines this to 1 when it finds out that system */
+/* header file ws2tcpip.h must be included by the external interface. */
+/* #undef CARES_PULL_WS2TCPIP_H */
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <windows.h>
+
+#else /* Not Windows */
+
+# include <sys/time.h>
+# include <sys/types.h>
+# include <sys/socket.h>
+#endif
+
+#if 0
+/* The size of `long', as computed by sizeof. */
+#define CARES_SIZEOF_LONG 4
+#endif
+
+/* Integral data type used for ares_socklen_t. */
+#define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+
+#if 0
+/* The size of `ares_socklen_t', as computed by sizeof. */
+#define CARES_SIZEOF_ARES_SOCKLEN_T 4
+#endif
+
+/* Data type definition of ares_socklen_t. */
+typedef int ares_socklen_t;
+
+#if 0 /* libuv disabled */
+#include "ares_rules.h" /* c-ares rules enforcement */
+#endif
+
+/*********************** end libuv patch ***************/
+
+#include <sys/types.h>
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+ libc5-based Linux systems. Only include it on system that are known to
+ require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+ defined(ANDROID) || defined(__ANDROID__)
+#include <sys/select.h>
+#endif
+#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
+#include <sys/bsdskt.h>
+#endif
+
+#if defined(WATT32)
+# include <netinet/in.h>
+# include <sys/socket.h>
+# include <tcp.h>
+#elif defined(_WIN32_WCE)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# include <winsock.h>
+#elif defined(WIN32)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#else
+# include <sys/socket.h>
+# include <netinet/in.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** c-ares external API function linkage decorations.
+*/
+
+#if !defined(CARES_STATICLIB) && \
+ (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+ /* __declspec function decoration for Win32 and Symbian DLL's */
+# if defined(CARES_BUILDING_LIBRARY)
+# define CARES_EXTERN __declspec(dllexport)
+# else
+# define CARES_EXTERN __declspec(dllimport)
+# endif
+#else
+ /* visibility function decoration for other cases */
+# if !defined(CARES_SYMBOL_HIDING) || \
+ defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
+# define CARES_EXTERN
+# else
+# define CARES_EXTERN CARES_SYMBOL_SCOPE_EXTERN
+# endif
+#endif
+
+
+#define ARES_SUCCESS 0
+
+/* Server error codes (ARES_ENODATA indicates no relevant answer) */
+#define ARES_ENODATA 1
+#define ARES_EFORMERR 2
+#define ARES_ESERVFAIL 3
+#define ARES_ENOTFOUND 4
+#define ARES_ENOTIMP 5
+#define ARES_EREFUSED 6
+
+/* Locally generated error codes */
+#define ARES_EBADQUERY 7
+#define ARES_EBADNAME 8
+#define ARES_EBADFAMILY 9
+#define ARES_EBADRESP 10
+#define ARES_ECONNREFUSED 11
+#define ARES_ETIMEOUT 12
+#define ARES_EOF 13
+#define ARES_EFILE 14
+#define ARES_ENOMEM 15
+#define ARES_EDESTRUCTION 16
+#define ARES_EBADSTR 17
+
+/* ares_getnameinfo error codes */
+#define ARES_EBADFLAGS 18
+
+/* ares_getaddrinfo error codes */
+#define ARES_ENONAME 19
+#define ARES_EBADHINTS 20
+
+/* Uninitialized library error code */
+#define ARES_ENOTINITIALIZED 21 /* introduced in 1.7.0 */
+
+/* ares_library_init error codes */
+#define ARES_ELOADIPHLPAPI 22 /* introduced in 1.7.0 */
+#define ARES_EADDRGETNETWORKPARAMS 23 /* introduced in 1.7.0 */
+
+/* More error codes */
+#define ARES_ECANCELLED 24 /* introduced in 1.7.0 */
+
+/* Flag values */
+#define ARES_FLAG_USEVC (1 << 0)
+#define ARES_FLAG_PRIMARY (1 << 1)
+#define ARES_FLAG_IGNTC (1 << 2)
+#define ARES_FLAG_NORECURSE (1 << 3)
+#define ARES_FLAG_STAYOPEN (1 << 4)
+#define ARES_FLAG_NOSEARCH (1 << 5)
+#define ARES_FLAG_NOALIASES (1 << 6)
+#define ARES_FLAG_NOCHECKRESP (1 << 7)
+
+/* Option mask values */
+#define ARES_OPT_FLAGS (1 << 0)
+#define ARES_OPT_TIMEOUT (1 << 1)
+#define ARES_OPT_TRIES (1 << 2)
+#define ARES_OPT_NDOTS (1 << 3)
+#define ARES_OPT_UDP_PORT (1 << 4)
+#define ARES_OPT_TCP_PORT (1 << 5)
+#define ARES_OPT_SERVERS (1 << 6)
+#define ARES_OPT_DOMAINS (1 << 7)
+#define ARES_OPT_LOOKUPS (1 << 8)
+#define ARES_OPT_SOCK_STATE_CB (1 << 9)
+#define ARES_OPT_SORTLIST (1 << 10)
+#define ARES_OPT_SOCK_SNDBUF (1 << 11)
+#define ARES_OPT_SOCK_RCVBUF (1 << 12)
+#define ARES_OPT_TIMEOUTMS (1 << 13)
+#define ARES_OPT_ROTATE (1 << 14)
+
+/* Nameinfo flag values */
+#define ARES_NI_NOFQDN (1 << 0)
+#define ARES_NI_NUMERICHOST (1 << 1)
+#define ARES_NI_NAMEREQD (1 << 2)
+#define ARES_NI_NUMERICSERV (1 << 3)
+#define ARES_NI_DGRAM (1 << 4)
+#define ARES_NI_TCP 0
+#define ARES_NI_UDP ARES_NI_DGRAM
+#define ARES_NI_SCTP (1 << 5)
+#define ARES_NI_DCCP (1 << 6)
+#define ARES_NI_NUMERICSCOPE (1 << 7)
+#define ARES_NI_LOOKUPHOST (1 << 8)
+#define ARES_NI_LOOKUPSERVICE (1 << 9)
+/* Reserved for future use */
+#define ARES_NI_IDN (1 << 10)
+#define ARES_NI_IDN_ALLOW_UNASSIGNED (1 << 11)
+#define ARES_NI_IDN_USE_STD3_ASCII_RULES (1 << 12)
+
+/* Addrinfo flag values */
+#define ARES_AI_CANONNAME (1 << 0)
+#define ARES_AI_NUMERICHOST (1 << 1)
+#define ARES_AI_PASSIVE (1 << 2)
+#define ARES_AI_NUMERICSERV (1 << 3)
+#define ARES_AI_V4MAPPED (1 << 4)
+#define ARES_AI_ALL (1 << 5)
+#define ARES_AI_ADDRCONFIG (1 << 6)
+/* Reserved for future use */
+#define ARES_AI_IDN (1 << 10)
+#define ARES_AI_IDN_ALLOW_UNASSIGNED (1 << 11)
+#define ARES_AI_IDN_USE_STD3_ASCII_RULES (1 << 12)
+#define ARES_AI_CANONIDN (1 << 13)
+
+#define ARES_AI_MASK (ARES_AI_CANONNAME|ARES_AI_NUMERICHOST|ARES_AI_PASSIVE| \
+ ARES_AI_NUMERICSERV|ARES_AI_V4MAPPED|ARES_AI_ALL| \
+ ARES_AI_ADDRCONFIG)
+#define ARES_GETSOCK_MAXNUM 16 /* ares_getsock() can return info about this
+ many sockets */
+#define ARES_GETSOCK_READABLE(bits,num) (bits & (1<< (num)))
+#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
+ ARES_GETSOCK_MAXNUM)))
+
+/* c-ares library initialization flag values */
+#define ARES_LIB_INIT_NONE (0)
+#define ARES_LIB_INIT_WIN32 (1 << 0)
+#define ARES_LIB_INIT_ALL (ARES_LIB_INIT_WIN32)
+
+
+/*
+ * Typedef our socket type
+ */
+
+#ifndef ares_socket_typedef
+#ifdef WIN32
+typedef SOCKET ares_socket_t;
+#define ARES_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int ares_socket_t;
+#define ARES_SOCKET_BAD -1
+#endif
+#define ares_socket_typedef
+#endif /* ares_socket_typedef */
+
+typedef void (*ares_sock_state_cb)(void *data,
+ ares_socket_t socket_fd,
+ int readable,
+ int writable);
+
+struct apattern;
+
+/* NOTE about the ares_options struct to users and developers.
+
+ This struct will remain looking like this. It will not be extended nor
+ shrunk in future releases, but all new options will be set by ares_set_*()
+ options instead of with the ares_init_options() function.
+
+ Eventually (in a galaxy far far away), all options will be settable by
+ ares_set_*() options and the ares_init_options() function will become
+ deprecated.
+
+ When new options are added to c-ares, they are not added to this
+ struct. And they are not "saved" with the ares_save_options() function but
+ instead we encourage the use of the ares_dup() function. Needless to say,
+ if you add config options to c-ares you need to make sure ares_dup()
+ duplicates this new option.
+
+ */
+struct ares_options {
+ int flags;
+ int timeout; /* in seconds or milliseconds, depending on options */
+ int tries;
+ int ndots;
+ unsigned short udp_port;
+ unsigned short tcp_port;
+ int socket_send_buffer_size;
+ int socket_receive_buffer_size;
+ struct in_addr *servers;
+ int nservers;
+ char **domains;
+ int ndomains;
+ char *lookups;
+ ares_sock_state_cb sock_state_cb;
+ void *sock_state_cb_data;
+ struct apattern *sortlist;
+ int nsort;
+};
+
+struct hostent;
+struct timeval;
+struct sockaddr;
+struct ares_channeldata;
+
+typedef struct ares_channeldata *ares_channel;
+
+typedef void (*ares_callback)(void *arg,
+ int status,
+ int timeouts,
+ unsigned char *abuf,
+ int alen);
+
+typedef void (*ares_host_callback)(void *arg,
+ int status,
+ int timeouts,
+ struct hostent *hostent);
+
+typedef void (*ares_nameinfo_callback)(void *arg,
+ int status,
+ int timeouts,
+ char *node,
+ char *service);
+
+typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd,
+ int type,
+ void *data);
+
+CARES_EXTERN int ares_library_init(int flags);
+
+CARES_EXTERN void ares_library_cleanup(void);
+
+CARES_EXTERN const char *ares_version(int *version);
+
+CARES_EXTERN int ares_init(ares_channel *channelptr);
+
+CARES_EXTERN int ares_init_options(ares_channel *channelptr,
+ struct ares_options *options,
+ int optmask);
+
+CARES_EXTERN int ares_save_options(ares_channel channel,
+ struct ares_options *options,
+ int *optmask);
+
+CARES_EXTERN void ares_destroy_options(struct ares_options *options);
+
+CARES_EXTERN int ares_dup(ares_channel *dest,
+ ares_channel src);
+
+CARES_EXTERN void ares_destroy(ares_channel channel);
+
+CARES_EXTERN void ares_cancel(ares_channel channel);
+
+/* These next 3 configure local binding for the out-going socket
+ * connection. Use these to specify source IP and/or network device
+ * on multi-homed systems.
+ */
+CARES_EXTERN void ares_set_local_ip4(ares_channel channel, unsigned int local_ip);
+
+/* local_ip6 should be 16 bytes in length */
+CARES_EXTERN void ares_set_local_ip6(ares_channel channel,
+ const unsigned char* local_ip6);
+
+/* local_dev_name should be null terminated. */
+CARES_EXTERN void ares_set_local_dev(ares_channel channel,
+ const char* local_dev_name);
+
+CARES_EXTERN void ares_set_socket_callback(ares_channel channel,
+ ares_sock_create_callback callback,
+ void *user_data);
+
+CARES_EXTERN void ares_send(ares_channel channel,
+ const unsigned char *qbuf,
+ int qlen,
+ ares_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_query(ares_channel channel,
+ const char *name,
+ int dnsclass,
+ int type,
+ ares_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_search(ares_channel channel,
+ const char *name,
+ int dnsclass,
+ int type,
+ ares_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_gethostbyname(ares_channel channel,
+ const char *name,
+ int family,
+ ares_host_callback callback,
+ void *arg);
+
+CARES_EXTERN int ares_gethostbyname_file(ares_channel channel,
+ const char *name,
+ int family,
+ struct hostent **host);
+
+CARES_EXTERN void ares_gethostbyaddr(ares_channel channel,
+ const void *addr,
+ int addrlen,
+ int family,
+ ares_host_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_getnameinfo(ares_channel channel,
+ const struct sockaddr *sa,
+ ares_socklen_t salen,
+ int flags,
+ ares_nameinfo_callback callback,
+ void *arg);
+
+CARES_EXTERN int ares_fds(ares_channel channel,
+ fd_set *read_fds,
+ fd_set *write_fds);
+
+CARES_EXTERN int ares_getsock(ares_channel channel,
+ ares_socket_t *socks,
+ int numsocks);
+
+CARES_EXTERN struct timeval *ares_timeout(ares_channel channel,
+ struct timeval *maxtv,
+ struct timeval *tv);
+
+CARES_EXTERN void ares_process(ares_channel channel,
+ fd_set *read_fds,
+ fd_set *write_fds);
+
+CARES_EXTERN void ares_process_fd(ares_channel channel,
+ ares_socket_t read_fd,
+ ares_socket_t write_fd);
+
+CARES_EXTERN int ares_mkquery(const char *name,
+ int dnsclass,
+ int type,
+ unsigned short id,
+ int rd,
+ unsigned char **buf,
+ int *buflen);
+
+CARES_EXTERN int ares_expand_name(const unsigned char *encoded,
+ const unsigned char *abuf,
+ int alen,
+ char **s,
+ long *enclen);
+
+CARES_EXTERN int ares_expand_string(const unsigned char *encoded,
+ const unsigned char *abuf,
+ int alen,
+ unsigned char **s,
+ long *enclen);
+
+/*
+ * NOTE: before c-ares 1.7.0 we would most often use the system in6_addr
+ * struct below when ares itself was built, but many apps would use this
+ * private version since the header checked a HAVE_* define for it. Starting
+ * with 1.7.0 we always declare and use our own to stop relying on the
+ * system's one.
+ */
+struct ares_in6_addr {
+ union {
+ unsigned char _S6_u8[16];
+ } _S6_un;
+};
+
+struct ares_addrttl {
+ struct in_addr ipaddr;
+ int ttl;
+};
+
+struct ares_addr6ttl {
+ struct ares_in6_addr ip6addr;
+ int ttl;
+};
+
+struct ares_srv_reply {
+ struct ares_srv_reply *next;
+ char *host;
+ unsigned short priority;
+ unsigned short weight;
+ unsigned short port;
+};
+
+struct ares_mx_reply {
+ struct ares_mx_reply *next;
+ char *host;
+ unsigned short priority;
+};
+
+struct ares_txt_reply {
+ struct ares_txt_reply *next;
+ unsigned char *txt;
+ size_t length; /* length excludes null termination */
+};
+
+struct ares_naptr_reply {
+ struct ares_naptr_reply *next;
+ unsigned char *flags;
+ unsigned char *service;
+ unsigned char *regexp;
+ char *replacement;
+ unsigned short order;
+ unsigned short preference;
+};
+
+struct ares_soa_reply {
+ char *nsname;
+ char *hostmaster;
+ unsigned int serial;
+ unsigned int refresh;
+ unsigned int retry;
+ unsigned int expire;
+ unsigned int minttl;
+};
+
+/*
+** Parse the buffer, starting at *abuf and of length alen bytes, previously
+** obtained from an ares_search call. Put the results in *host, if nonnull.
+** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with
+** their TTLs in that array, and set *naddrttls to the number of addresses
+** so written.
+*/
+
+CARES_EXTERN int ares_parse_a_reply(const unsigned char *abuf,
+ int alen,
+ struct hostent **host,
+ struct ares_addrttl *addrttls,
+ int *naddrttls);
+
+CARES_EXTERN int ares_parse_aaaa_reply(const unsigned char *abuf,
+ int alen,
+ struct hostent **host,
+ struct ares_addr6ttl *addrttls,
+ int *naddrttls);
+
+CARES_EXTERN int ares_parse_ptr_reply(const unsigned char *abuf,
+ int alen,
+ const void *addr,
+ int addrlen,
+ int family,
+ struct hostent **host);
+
+CARES_EXTERN int ares_parse_ns_reply(const unsigned char *abuf,
+ int alen,
+ struct hostent **host);
+
+CARES_EXTERN int ares_parse_srv_reply(const unsigned char* abuf,
+ int alen,
+ struct ares_srv_reply** srv_out);
+
+CARES_EXTERN int ares_parse_mx_reply(const unsigned char* abuf,
+ int alen,
+ struct ares_mx_reply** mx_out);
+
+CARES_EXTERN int ares_parse_txt_reply(const unsigned char* abuf,
+ int alen,
+ struct ares_txt_reply** txt_out);
+
+CARES_EXTERN int ares_parse_naptr_reply(const unsigned char* abuf,
+ int alen,
+ struct ares_naptr_reply** naptr_out);
+
+CARES_EXTERN int ares_parse_soa_reply(const unsigned char* abuf,
+ int alen,
+ struct ares_soa_reply** soa_out);
+
+CARES_EXTERN void ares_free_string(void *str);
+
+CARES_EXTERN void ares_free_hostent(struct hostent *host);
+
+CARES_EXTERN void ares_free_soa(struct ares_soa_reply *soa);
+
+CARES_EXTERN void ares_free_data(void *dataptr);
+
+CARES_EXTERN const char *ares_strerror(int code);
+
+/* TODO: Hold port here as well. */
+struct ares_addr_node {
+ struct ares_addr_node *next;
+ int family;
+ union {
+ struct in_addr addr4;
+ struct ares_in6_addr addr6;
+ } addr;
+};
+
+CARES_EXTERN int ares_set_servers(ares_channel channel,
+ struct ares_addr_node *servers);
+
+/* Incomming string format: host[:port][,host[:port]]... */
+CARES_EXTERN int ares_set_servers_csv(ares_channel channel,
+ const char* servers);
+
+CARES_EXTERN int ares_get_servers(ares_channel channel,
+ struct ares_addr_node **servers);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ARES__H */
diff --git a/deps/cares/include/ares_version.h b/deps/cares/include/ares_version.h
new file mode 100644
index 000000000..84b97cd08
--- /dev/null
+++ b/deps/cares/include/ares_version.h
@@ -0,0 +1,24 @@
+
+#ifndef ARES__VERSION_H
+#define ARES__VERSION_H
+
+/* This is the global package copyright */
+#define ARES_COPYRIGHT "2004 - 2012 Daniel Stenberg, <daniel@haxx.se>."
+
+#define ARES_VERSION_MAJOR 1
+#define ARES_VERSION_MINOR 9
+#define ARES_VERSION_PATCH 0
+#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
+ (ARES_VERSION_MINOR<<8)|\
+ (ARES_VERSION_PATCH))
+#define ARES_VERSION_STR "1.9.0-DEV"
+
+#if (ARES_VERSION >= 0x010700)
+# define CARES_HAVE_ARES_LIBRARY_INIT 1
+# define CARES_HAVE_ARES_LIBRARY_CLEANUP 1
+#else
+# undef CARES_HAVE_ARES_LIBRARY_INIT
+# undef CARES_HAVE_ARES_LIBRARY_CLEANUP
+#endif
+
+#endif
diff --git a/deps/uv/src/ares/nameser.h b/deps/cares/include/nameser.h
index 45f1e3eb8..45f1e3eb8 100644
--- a/deps/uv/src/ares/nameser.h
+++ b/deps/cares/include/nameser.h
diff --git a/deps/uv/src/ares/AUTHORS b/deps/cares/src/AUTHORS
index e197a7419..e197a7419 100644
--- a/deps/uv/src/ares/AUTHORS
+++ b/deps/cares/src/AUTHORS
diff --git a/deps/cares/src/CHANGES b/deps/cares/src/CHANGES
new file mode 100644
index 000000000..f1426fda7
--- /dev/null
+++ b/deps/cares/src/CHANGES
@@ -0,0 +1,7 @@
+This file no longer holds the changelog. Now you can generate it yourself
+like this:
+
+ $ git log --pretty=fuller --no-color --date=short --decorate=full -1000 |
+ ./git2changes.pl
+
+The older, manually edited, changelog is found in git named CHANGES.0
diff --git a/deps/uv/src/ares/NEWS b/deps/cares/src/NEWS
index 95a2eeea2..95a2eeea2 100644
--- a/deps/uv/src/ares/NEWS
+++ b/deps/cares/src/NEWS
diff --git a/deps/uv/src/ares/README b/deps/cares/src/README
index 56a43c53a..56a43c53a 100644
--- a/deps/uv/src/ares/README
+++ b/deps/cares/src/README
diff --git a/deps/uv/src/ares/README.cares b/deps/cares/src/README.cares
index aca54c8cd..aca54c8cd 100644
--- a/deps/uv/src/ares/README.cares
+++ b/deps/cares/src/README.cares
diff --git a/deps/uv/src/ares/README.msvc b/deps/cares/src/README.msvc
index 4ff8700cb..4ff8700cb 100644
--- a/deps/uv/src/ares/README.msvc
+++ b/deps/cares/src/README.msvc
diff --git a/deps/cares/src/RELEASE-NOTES b/deps/cares/src/RELEASE-NOTES
new file mode 100644
index 000000000..3c437308f
--- /dev/null
+++ b/deps/cares/src/RELEASE-NOTES
@@ -0,0 +1,16 @@
+c-ares version 1.9.0
+
+Changed:
+
+ o Added ares_parse_soa_reply
+
+Fixed:
+
+ o libcares.pc generation for static MingW* cross builds
+ o ares_dup: UDP and TCP port byte order in saved options
+
+Thanks go to these friendly people for their efforts and contributions:
+
+ Yang Tse, Nick Alcock, Marko Kreen
+
+Have fun!
diff --git a/deps/uv/src/ares/TODO b/deps/cares/src/TODO
index fa31cea6f..fa31cea6f 100644
--- a/deps/uv/src/ares/TODO
+++ b/deps/cares/src/TODO
diff --git a/deps/uv/src/ares/ares__close_sockets.c b/deps/cares/src/ares__close_sockets.c
index 5d391a9ef..5d391a9ef 100644
--- a/deps/uv/src/ares/ares__close_sockets.c
+++ b/deps/cares/src/ares__close_sockets.c
diff --git a/deps/cares/src/ares__get_hostent.c b/deps/cares/src/ares__get_hostent.c
new file mode 100644
index 000000000..94428ee95
--- /dev/null
+++ b/deps/cares/src/ares__get_hostent.c
@@ -0,0 +1,264 @@
+
+/* Copyright 1998, 2011 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares.h"
+#include "inet_net_pton.h"
+#include "ares_nowarn.h"
+#include "ares_private.h"
+
+int ares__get_hostent(FILE *fp, int family, struct hostent **host)
+{
+ char *line = NULL, *p, *q, **alias;
+ char *txtaddr, *txthost, *txtalias;
+ int status;
+ size_t addrlen, linesize, naliases;
+ struct ares_addr addr;
+ struct hostent *hostent = NULL;
+
+ *host = NULL; /* Assume failure */
+
+ /* Validate family */
+ switch (family) {
+ case AF_INET:
+ case AF_INET6:
+ case AF_UNSPEC:
+ break;
+ default:
+ return ARES_EBADFAMILY;
+ }
+
+ while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
+ {
+
+ /* Trim line comment. */
+ p = line;
+ while (*p && (*p != '#'))
+ p++;
+ *p = '\0';
+
+ /* Trim trailing whitespace. */
+ q = p - 1;
+ while ((q >= line) && ISSPACE(*q))
+ q--;
+ *++q = '\0';
+
+ /* Skip leading whitespace. */
+ p = line;
+ while (*p && ISSPACE(*p))
+ p++;
+ if (!*p)
+ /* Ignore line if empty. */
+ continue;
+
+ /* Pointer to start of IPv4 or IPv6 address part. */
+ txtaddr = p;
+
+ /* Advance past address part. */
+ while (*p && !ISSPACE(*p))
+ p++;
+ if (!*p)
+ /* Ignore line if reached end of line. */
+ continue;
+
+ /* Null terminate address part. */
+ *p = '\0';
+
+ /* Advance to host name */
+ p++;
+ while (*p && ISSPACE(*p))
+ p++;
+ if (!*p)
+ /* Ignore line if reached end of line. */
+ continue;
+
+ /* Pointer to start of host name. */
+ txthost = p;
+
+ /* Advance past host name. */
+ while (*p && !ISSPACE(*p))
+ p++;
+
+ /* Pointer to start of first alias. */
+ txtalias = NULL;
+ if (*p)
+ {
+ q = p + 1;
+ while (*q && ISSPACE(*q))
+ q++;
+ if (*q)
+ txtalias = q;
+ }
+
+ /* Null terminate host name. */
+ *p = '\0';
+
+ /* find out number of aliases. */
+ naliases = 0;
+ if (txtalias)
+ {
+ p = txtalias;
+ while (*p)
+ {
+ while (*p && !ISSPACE(*p))
+ p++;
+ while (*p && ISSPACE(*p))
+ p++;
+ naliases++;
+ }
+ }
+
+ /* Convert address string to network address for the requested family. */
+ addrlen = 0;
+ addr.family = AF_UNSPEC;
+ addr.addrV4.s_addr = INADDR_NONE;
+ if ((family == AF_INET) || (family == AF_UNSPEC))
+ {
+ addr.addrV4.s_addr = inet_addr(txtaddr);
+ if (addr.addrV4.s_addr != INADDR_NONE)
+ {
+ /* Actual network address family and length. */
+ addr.family = AF_INET;
+ addrlen = sizeof(addr.addrV4);
+ }
+ }
+ if ((family == AF_INET6) || ((family == AF_UNSPEC) && (!addrlen)))
+ {
+ if (ares_inet_pton(AF_INET6, txtaddr, &addr.addrV6) > 0)
+ {
+ /* Actual network address family and length. */
+ addr.family = AF_INET6;
+ addrlen = sizeof(addr.addrV6);
+ }
+ }
+ if (!addrlen)
+ /* Ignore line if invalid address string for the requested family. */
+ continue;
+
+ /*
+ ** Actual address family possible values are AF_INET and AF_INET6 only.
+ */
+
+ /* Allocate memory for the hostent structure. */
+ hostent = malloc(sizeof(struct hostent));
+ if (!hostent)
+ break;
+
+ /* Initialize fields for out of memory condition. */
+ hostent->h_aliases = NULL;
+ hostent->h_addr_list = NULL;
+
+ /* Copy official host name. */
+ hostent->h_name = strdup(txthost);
+ if (!hostent->h_name)
+ break;
+
+ /* Copy network address. */
+ hostent->h_addr_list = malloc(2 * sizeof(char *));
+ if (!hostent->h_addr_list)
+ break;
+ hostent->h_addr_list[1] = NULL;
+ hostent->h_addr_list[0] = malloc(addrlen);
+ if (!hostent->h_addr_list[0])
+ break;
+ if (addr.family == AF_INET)
+ memcpy(hostent->h_addr_list[0], &addr.addrV4, sizeof(addr.addrV4));
+ else
+ memcpy(hostent->h_addr_list[0], &addr.addrV6, sizeof(addr.addrV6));
+
+ /* Copy aliases. */
+ hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
+ if (!hostent->h_aliases)
+ break;
+ alias = hostent->h_aliases;
+ while (naliases)
+ *(alias + naliases--) = NULL;
+ *alias = NULL;
+ while (txtalias)
+ {
+ p = txtalias;
+ while (*p && !ISSPACE(*p))
+ p++;
+ q = p;
+ while (*q && ISSPACE(*q))
+ q++;
+ *p = '\0';
+ if ((*alias = strdup(txtalias)) == NULL)
+ break;
+ alias++;
+ txtalias = *q ? q : NULL;
+ }
+ if (txtalias)
+ /* Alias memory allocation failure. */
+ break;
+
+ /* Copy actual network address family and length. */
+ hostent->h_addrtype = aresx_sitoss(addr.family);
+ hostent->h_length = aresx_uztoss(addrlen);
+
+ /* Free line buffer. */
+ free(line);
+
+ /* Return hostent successfully */
+ *host = hostent;
+ return ARES_SUCCESS;
+
+ }
+
+ /* If allocated, free line buffer. */
+ if (line)
+ free(line);
+
+ if (status == ARES_SUCCESS)
+ {
+ /* Memory allocation failure; clean up. */
+ if (hostent)
+ {
+ if (hostent->h_name)
+ free((char *) hostent->h_name);
+ if (hostent->h_aliases)
+ {
+ for (alias = hostent->h_aliases; *alias; alias++)
+ free(*alias);
+ free(hostent->h_aliases);
+ }
+ if (hostent->h_addr_list)
+ {
+ if (hostent->h_addr_list[0])
+ free(hostent->h_addr_list[0]);
+ free(hostent->h_addr_list);
+ }
+ free(hostent);
+ }
+ return ARES_ENOMEM;
+ }
+
+ return status;
+}
diff --git a/deps/uv/src/ares/ares__read_line.c b/deps/cares/src/ares__read_line.c
index ca018035e..ca018035e 100644
--- a/deps/uv/src/ares/ares__read_line.c
+++ b/deps/cares/src/ares__read_line.c
diff --git a/deps/uv/src/ares/ares__timeval.c b/deps/cares/src/ares__timeval.c
index f7aa7883f..f7aa7883f 100644
--- a/deps/uv/src/ares/ares__timeval.c
+++ b/deps/cares/src/ares__timeval.c
diff --git a/deps/uv/src/ares/ares_cancel.c b/deps/cares/src/ares_cancel.c
index eb790ae00..eb790ae00 100644
--- a/deps/uv/src/ares/ares_cancel.c
+++ b/deps/cares/src/ares_cancel.c
diff --git a/deps/cares/src/ares_data.c b/deps/cares/src/ares_data.c
new file mode 100644
index 000000000..7c0465073
--- /dev/null
+++ b/deps/cares/src/ares_data.c
@@ -0,0 +1,231 @@
+
+/* Copyright (C) 2009-2012 by Daniel Stenberg
+ *
+ * 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.
+ */
+
+
+#include "ares_setup.h"
+
+#include <stddef.h>
+
+#include "ares.h"
+#include "ares_data.h"
+#include "ares_private.h"
+
+
+/*
+** ares_free_data() - c-ares external API function.
+**
+** This function must be used by the application to free data memory that
+** has been internally allocated by some c-ares function and for which a
+** pointer has already been returned to the calling application. The list
+** of c-ares functions returning pointers that must be free'ed using this
+** function is:
+**
+** ares_get_servers()
+** ares_parse_srv_reply()
+** ares_parse_txt_reply()
+*/
+
+void ares_free_data(void *dataptr)
+{
+ struct ares_data *ptr;
+
+ if (!dataptr)
+ return;
+
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:1684)
+ /* 1684: conversion from pointer to same-sized integral type */
+#endif
+
+ ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+
+ if (ptr->mark != ARES_DATATYPE_MARK)
+ return;
+
+ switch (ptr->type)
+ {
+ case ARES_DATATYPE_MX_REPLY:
+
+ if (ptr->data.mx_reply.next)
+ ares_free_data(ptr->data.mx_reply.next);
+ if (ptr->data.mx_reply.host)
+ free(ptr->data.mx_reply.host);
+ break;
+
+ case ARES_DATATYPE_SRV_REPLY:
+
+ if (ptr->data.srv_reply.next)
+ ares_free_data(ptr->data.srv_reply.next);
+ if (ptr->data.srv_reply.host)
+ free(ptr->data.srv_reply.host);
+ break;
+
+ case ARES_DATATYPE_TXT_REPLY:
+
+ if (ptr->data.txt_reply.next)
+ ares_free_data(ptr->data.txt_reply.next);
+ if (ptr->data.txt_reply.txt)
+ free(ptr->data.txt_reply.txt);
+ break;
+
+ case ARES_DATATYPE_ADDR_NODE:
+
+ if (ptr->data.addr_node.next)
+ ares_free_data(ptr->data.addr_node.next);
+ break;
+
+ case ARES_DATATYPE_NAPTR_REPLY:
+
+ if (ptr->data.naptr_reply.next)
+ ares_free_data(ptr->data.naptr_reply.next);
+ if (ptr->data.naptr_reply.flags)
+ free(ptr->data.naptr_reply.flags);
+ if (ptr->data.naptr_reply.service)
+ free(ptr->data.naptr_reply.service);
+ if (ptr->data.naptr_reply.regexp)
+ free(ptr->data.naptr_reply.regexp);
+ if (ptr->data.naptr_reply.replacement)
+ free(ptr->data.naptr_reply.replacement);
+ break;
+
+ case ARES_DATATYPE_SOA_REPLY:
+ if (ptr->data.soa_reply.nsname)
+ free(ptr->data.soa_reply.nsname);
+ if (ptr->data.soa_reply.hostmaster)
+ free(ptr->data.soa_reply.hostmaster);
+ break;
+
+ default:
+ return;
+ }
+
+ free(ptr);
+}
+
+
+/*
+** ares_malloc_data() - c-ares internal helper function.
+**
+** This function allocates memory for a c-ares private ares_data struct
+** for the specified ares_datatype, initializes c-ares private fields
+** and zero initializes those which later might be used from the public
+** API. It returns an interior pointer which can be passed by c-ares
+** functions to the calling application, and that must be free'ed using
+** c-ares external API function ares_free_data().
+*/
+
+void *ares_malloc_data(ares_datatype type)
+{
+ struct ares_data *ptr;
+
+ ptr = malloc(sizeof(struct ares_data));
+ if (!ptr)
+ return NULL;
+
+ switch (type)
+ {
+ case ARES_DATATYPE_MX_REPLY:
+ ptr->data.mx_reply.next = NULL;
+ ptr->data.mx_reply.host = NULL;
+ ptr->data.mx_reply.priority = 0;
+ break;
+
+ case ARES_DATATYPE_SRV_REPLY:
+ ptr->data.srv_reply.next = NULL;
+ ptr->data.srv_reply.host = NULL;
+ ptr->data.srv_reply.priority = 0;
+ ptr->data.srv_reply.weight = 0;
+ ptr->data.srv_reply.port = 0;
+ break;
+
+ case ARES_DATATYPE_TXT_REPLY:
+ ptr->data.txt_reply.next = NULL;
+ ptr->data.txt_reply.txt = NULL;
+ ptr->data.txt_reply.length = 0;
+ break;
+
+ case ARES_DATATYPE_ADDR_NODE:
+ ptr->data.addr_node.next = NULL;
+ ptr->data.addr_node.family = 0;
+ memset(&ptr->data.addr_node.addrV6, 0,
+ sizeof(ptr->data.addr_node.addrV6));
+ break;
+
+ case ARES_DATATYPE_NAPTR_REPLY:
+ ptr->data.naptr_reply.next = NULL;
+ ptr->data.naptr_reply.flags = NULL;
+ ptr->data.naptr_reply.service = NULL;
+ ptr->data.naptr_reply.regexp = NULL;
+ ptr->data.naptr_reply.replacement = NULL;
+ ptr->data.naptr_reply.order = 0;
+ ptr->data.naptr_reply.preference = 0;
+ break;
+
+ case ARES_DATATYPE_SOA_REPLY:
+ ptr->data.soa_reply.nsname = NULL;
+ ptr->data.soa_reply.hostmaster = NULL;
+ ptr->data.soa_reply.serial = 0;
+ ptr->data.soa_reply.refresh = 0;
+ ptr->data.soa_reply.retry = 0;
+ ptr->data.soa_reply.expire = 0;
+ ptr->data.soa_reply.minttl = 0;
+ break;
+
+ default:
+ free(ptr);
+ return NULL;
+ }
+
+ ptr->mark = ARES_DATATYPE_MARK;
+ ptr->type = type;
+
+ return &ptr->data;
+}
+
+
+/*
+** ares_get_datatype() - c-ares internal helper function.
+**
+** This function returns the ares_datatype of the data stored in a
+** private ares_data struct when given the public API pointer.
+*/
+
+ares_datatype ares_get_datatype(void * dataptr)
+{
+ struct ares_data *ptr;
+
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:1684)
+ /* 1684: conversion from pointer to same-sized integral type */
+#endif
+
+ ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+
+ if (ptr->mark == ARES_DATATYPE_MARK)
+ return ptr->type;
+
+ return ARES_DATATYPE_UNKNOWN;
+}
diff --git a/deps/cares/src/ares_data.h b/deps/cares/src/ares_data.h
new file mode 100644
index 000000000..8974295fb
--- /dev/null
+++ b/deps/cares/src/ares_data.h
@@ -0,0 +1,69 @@
+
+/* Copyright (C) 2009-2012 by Daniel Stenberg
+ *
+ * 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.
+ */
+
+typedef enum {
+ ARES_DATATYPE_UNKNOWN = 1, /* unknown data type - introduced in 1.7.0 */
+ ARES_DATATYPE_SRV_REPLY, /* struct ares_srv_reply - introduced in 1.7.0 */
+ ARES_DATATYPE_TXT_REPLY, /* struct ares_txt_reply - introduced in 1.7.0 */
+ ARES_DATATYPE_ADDR_NODE, /* struct ares_addr_node - introduced in 1.7.1 */
+ ARES_DATATYPE_MX_REPLY, /* struct ares_mx_reply - introduced in 1.7.2 */
+ ARES_DATATYPE_NAPTR_REPLY,/* struct ares_naptr_reply - introduced in 1.7.6 */
+ ARES_DATATYPE_SOA_REPLY, /* struct ares_soa_reply - introduced in 1.9.0 */
+#if 0
+ ARES_DATATYPE_ADDR6TTL, /* struct ares_addrttl */
+ ARES_DATATYPE_ADDRTTL, /* struct ares_addr6ttl */
+ ARES_DATATYPE_HOSTENT, /* struct hostent */
+ ARES_DATATYPE_OPTIONS, /* struct ares_options */
+#endif
+ ARES_DATATYPE_LAST /* not used - introduced in 1.7.0 */
+} ares_datatype;
+
+#define ARES_DATATYPE_MARK 0xbead
+
+/*
+ * ares_data struct definition is internal to c-ares and shall not
+ * be exposed by the public API in order to allow future changes
+ * and extensions to it without breaking ABI. This will be used
+ * internally by c-ares as the container of multiple types of data
+ * dynamically allocated for which a reference will be returned
+ * to the calling application.
+ *
+ * c-ares API functions returning a pointer to c-ares internally
+ * allocated data will actually be returning an interior pointer
+ * into this ares_data struct.
+ *
+ * All this is 'invisible' to the calling application, the only
+ * requirement is that this kind of data must be free'ed by the
+ * calling application using ares_free_data() with the pointer
+ * it has received from a previous c-ares function call.
+ */
+
+struct ares_data {
+ ares_datatype type; /* Actual data type identifier. */
+ unsigned int mark; /* Private ares_data signature. */
+ union {
+ struct ares_txt_reply txt_reply;
+ struct ares_srv_reply srv_reply;
+ struct ares_addr_node addr_node;
+ struct ares_mx_reply mx_reply;
+ struct ares_naptr_reply naptr_reply;
+ struct ares_soa_reply soa_reply;
+ } data;
+};
+
+void *ares_malloc_data(ares_datatype type);
+
+ares_datatype ares_get_datatype(void * dataptr);
diff --git a/deps/cares/src/ares_destroy.c b/deps/cares/src/ares_destroy.c
new file mode 100644
index 000000000..a3f6ea200
--- /dev/null
+++ b/deps/cares/src/ares_destroy.c
@@ -0,0 +1,107 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2004-2011 by Daniel Stenberg
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+#include <assert.h>
+#include <stdlib.h>
+#include "ares.h"
+#include "ares_private.h"
+
+void ares_destroy_options(struct ares_options *options)
+{
+ int i;
+
+ if(options->servers)
+ free(options->servers);
+ for (i = 0; i < options->ndomains; i++)
+ free(options->domains[i]);
+ if(options->domains)
+ free(options->domains);
+ if(options->sortlist)
+ free(options->sortlist);
+ if(options->lookups)
+ free(options->lookups);
+}
+
+void ares_destroy(ares_channel channel)
+{
+ int i;
+ struct query *query;
+ struct list_node* list_head;
+ struct list_node* list_node;
+
+ if (!channel)
+ return;
+
+ list_head = &(channel->all_queries);
+ for (list_node = list_head->next; list_node != list_head; )
+ {
+ query = list_node->data;
+ list_node = list_node->next; /* since we're deleting the query */
+ query->callback(query->arg, ARES_EDESTRUCTION, 0, NULL, 0);
+ ares__free_query(query);
+ }
+#ifndef NDEBUG
+ /* Freeing the query should remove it from all the lists in which it sits,
+ * so all query lists should be empty now.
+ */
+ assert(ares__is_list_empty(&(channel->all_queries)));
+ for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
+ {
+ assert(ares__is_list_empty(&(channel->queries_by_qid[i])));
+ }
+ for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
+ {
+ assert(ares__is_list_empty(&(channel->queries_by_timeout[i])));
+ }
+#endif
+
+ ares__destroy_servers_state(channel);
+
+ if (channel->domains) {
+ for (i = 0; i < channel->ndomains; i++)
+ free(channel->domains[i]);
+ free(channel->domains);
+ }
+
+ if(channel->sortlist)
+ free(channel->sortlist);
+
+ if (channel->lookups)
+ free(channel->lookups);
+
+ free(channel);
+}
+
+void ares__destroy_servers_state(ares_channel channel)
+{
+ struct server_state *server;
+ int i;
+
+ if (channel->servers)
+ {
+ for (i = 0; i < channel->nservers; i++)
+ {
+ server = &channel->servers[i];
+ ares__close_sockets(channel, server);
+ assert(ares__is_list_empty(&server->queries_to_server));
+ }
+ free(channel->servers);
+ channel->servers = NULL;
+ }
+ channel->nservers = -1;
+}
diff --git a/deps/cares/src/ares_dns.h b/deps/cares/src/ares_dns.h
new file mode 100644
index 000000000..34cf790df
--- /dev/null
+++ b/deps/cares/src/ares_dns.h
@@ -0,0 +1,103 @@
+#ifndef HEADER_CARES_DNS_H
+#define HEADER_CARES_DNS_H
+
+/* Copyright 1998, 2011 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.
+ */
+
+/*
+ * Macro DNS__16BIT reads a network short (16 bit) given in network
+ * byte order, and returns its value as an unsigned short.
+ */
+#define DNS__16BIT(p) ((unsigned short)((unsigned int) 0xffff & \
+ (((unsigned int)((unsigned char)(p)[0]) << 8U) | \
+ ((unsigned int)((unsigned char)(p)[1])))))
+
+/*
+ * Macro DNS__32BIT reads a network long (32 bit) given in network
+ * byte order, and returns its value as an unsigned int.
+ */
+#define DNS__32BIT(p) ((unsigned int) \
+ (((unsigned int)((unsigned char)(p)[0]) << 24U) | \
+ ((unsigned int)((unsigned char)(p)[1]) << 16U) | \
+ ((unsigned int)((unsigned char)(p)[2]) << 8U) | \
+ ((unsigned int)((unsigned char)(p)[3]))))
+
+#define DNS__SET16BIT(p, v) (((p)[0] = (unsigned char)(((v) >> 8) & 0xff)), \
+ ((p)[1] = (unsigned char)((v) & 0xff)))
+#define DNS__SET32BIT(p, v) (((p)[0] = (unsigned char)(((v) >> 24) & 0xff)), \
+ ((p)[1] = (unsigned char)(((v) >> 16) & 0xff)), \
+ ((p)[2] = (unsigned char)(((v) >> 8) & 0xff)), \
+ ((p)[3] = (unsigned char)((v) & 0xff)))
+
+#if 0
+/* we cannot use this approach on systems where we can't access 16/32 bit
+ data on un-aligned addresses */
+#define DNS__16BIT(p) ntohs(*(unsigned short*)(p))
+#define DNS__32BIT(p) ntohl(*(unsigned long*)(p))
+#define DNS__SET16BIT(p, v) *(unsigned short*)(p) = htons(v)
+#define DNS__SET32BIT(p, v) *(unsigned long*)(p) = htonl(v)
+#endif
+
+/* Macros for parsing a DNS header */
+#define DNS_HEADER_QID(h) DNS__16BIT(h)
+#define DNS_HEADER_QR(h) (((h)[2] >> 7) & 0x1)
+#define DNS_HEADER_OPCODE(h) (((h)[2] >> 3) & 0xf)
+#define DNS_HEADER_AA(h) (((h)[2] >> 2) & 0x1)
+#define DNS_HEADER_TC(h) (((h)[2] >> 1) & 0x1)
+#define DNS_HEADER_RD(h) ((h)[2] & 0x1)
+#define DNS_HEADER_RA(h) (((h)[3] >> 7) & 0x1)
+#define DNS_HEADER_Z(h) (((h)[3] >> 4) & 0x7)
+#define DNS_HEADER_RCODE(h) ((h)[3] & 0xf)
+#define DNS_HEADER_QDCOUNT(h) DNS__16BIT((h) + 4)
+#define DNS_HEADER_ANCOUNT(h) DNS__16BIT((h) + 6)
+#define DNS_HEADER_NSCOUNT(h) DNS__16BIT((h) + 8)
+#define DNS_HEADER_ARCOUNT(h) DNS__16BIT((h) + 10)
+
+/* Macros for constructing a DNS header */
+#define DNS_HEADER_SET_QID(h, v) DNS__SET16BIT(h, v)
+#define DNS_HEADER_SET_QR(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 7))
+#define DNS_HEADER_SET_OPCODE(h, v) ((h)[2] |= (unsigned char)(((v) & 0xf) << 3))
+#define DNS_HEADER_SET_AA(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 2))
+#define DNS_HEADER_SET_TC(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 1))
+#define DNS_HEADER_SET_RD(h, v) ((h)[2] |= (unsigned char)((v) & 0x1))
+#define DNS_HEADER_SET_RA(h, v) ((h)[3] |= (unsigned char)(((v) & 0x1) << 7))
+#define DNS_HEADER_SET_Z(h, v) ((h)[3] |= (unsigned char)(((v) & 0x7) << 4))
+#define DNS_HEADER_SET_RCODE(h, v) ((h)[3] |= (unsigned char)((v) & 0xf))
+#define DNS_HEADER_SET_QDCOUNT(h, v) DNS__SET16BIT((h) + 4, v)
+#define DNS_HEADER_SET_ANCOUNT(h, v) DNS__SET16BIT((h) + 6, v)
+#define DNS_HEADER_SET_NSCOUNT(h, v) DNS__SET16BIT((h) + 8, v)
+#define DNS_HEADER_SET_ARCOUNT(h, v) DNS__SET16BIT((h) + 10, v)
+
+/* Macros for parsing the fixed part of a DNS question */
+#define DNS_QUESTION_TYPE(q) DNS__16BIT(q)
+#define DNS_QUESTION_CLASS(q) DNS__16BIT((q) + 2)
+
+/* Macros for constructing the fixed part of a DNS question */
+#define DNS_QUESTION_SET_TYPE(q, v) DNS__SET16BIT(q, v)
+#define DNS_QUESTION_SET_CLASS(q, v) DNS__SET16BIT((q) + 2, v)
+
+/* Macros for parsing the fixed part of a DNS resource record */
+#define DNS_RR_TYPE(r) DNS__16BIT(r)
+#define DNS_RR_CLASS(r) DNS__16BIT((r) + 2)
+#define DNS_RR_TTL(r) DNS__32BIT((r) + 4)
+#define DNS_RR_LEN(r) DNS__16BIT((r) + 8)
+
+/* Macros for constructing the fixed part of a DNS resource record */
+#define DNS_RR_SET_TYPE(r) DNS__SET16BIT(r, v)
+#define DNS_RR_SET_CLASS(r) DNS__SET16BIT((r) + 2, v)
+#define DNS_RR_SET_TTL(r) DNS__SET32BIT((r) + 4, v)
+#define DNS_RR_SET_LEN(r) DNS__SET16BIT((r) + 8, v)
+
+#endif /* HEADER_CARES_DNS_H */
diff --git a/deps/cares/src/ares_expand_name.c b/deps/cares/src/ares_expand_name.c
new file mode 100644
index 000000000..71ff0dae0
--- /dev/null
+++ b/deps/cares/src/ares_expand_name.c
@@ -0,0 +1,201 @@
+
+/* Copyright 1998, 2011 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#include <stdlib.h>
+#include "ares.h"
+#include "ares_nowarn.h"
+#include "ares_private.h" /* for the memdebug */
+
+static int name_length(const unsigned char *encoded, const unsigned char *abuf,
+ int alen);
+
+/* Expand an RFC1035-encoded domain name given by encoded. The
+ * containing message is given by abuf and alen. The result given by
+ * *s, which is set to a NUL-terminated allocated buffer. *enclen is
+ * set to the length of the encoded name (not the length of the
+ * expanded name; the goal is to tell the caller how many bytes to
+ * move forward to get past the encoded name).
+ *
+ * In the simple case, an encoded name is a series of labels, each
+ * composed of a one-byte length (limited to values between 0 and 63
+ * inclusive) followed by the label contents. The name is terminated
+ * by a zero-length label.
+ *
+ * In the more complicated case, a label may be terminated by an
+ * indirection pointer, specified by two bytes with the high bits of
+ * the first byte (corresponding to INDIR_MASK) set to 11. With the
+ * two high bits of the first byte stripped off, the indirection
+ * pointer gives an offset from the beginning of the containing
+ * message with more labels to decode. Indirection can happen an
+ * arbitrary number of times, so we have to detect loops.
+ *
+ * Since the expanded name uses '.' as a label separator, we use
+ * backslashes to escape periods or backslashes in the expanded name.
+ */
+
+int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
+ int alen, char **s, long *enclen)
+{
+ int len, indir = 0;
+ char *q;
+ const unsigned char *p;
+ union {
+ ssize_t sig;
+ size_t uns;
+ } nlen;
+
+ nlen.sig = name_length(encoded, abuf, alen);
+ if (nlen.sig < 0)
+ return ARES_EBADNAME;
+
+ *s = malloc(nlen.uns + 1);
+ if (!*s)
+ return ARES_ENOMEM;
+ q = *s;
+
+ if (nlen.uns == 0) {
+ /* RFC2181 says this should be ".": the root of the DNS tree.
+ * Since this function strips trailing dots though, it becomes ""
+ */
+ q[0] = '\0';
+
+ /* indirect root label (like 0xc0 0x0c) is 2 bytes long (stupid, but
+ valid) */
+ if ((*encoded & INDIR_MASK) == INDIR_MASK)
+ *enclen = 2L;
+ else
+ *enclen = 1L; /* the caller should move one byte to get past this */
+
+ return ARES_SUCCESS;
+ }
+
+ /* No error-checking necessary; it was all done by name_length(). */
+ p = encoded;
+ while (*p)
+ {
+ if ((*p & INDIR_MASK) == INDIR_MASK)
+ {
+ if (!indir)
+ {
+ *enclen = aresx_uztosl(p + 2U - encoded);
+ indir = 1;
+ }
+ p = abuf + ((*p & ~INDIR_MASK) << 8 | *(p + 1));
+ }
+ else
+ {
+ len = *p;
+ p++;
+ while (len--)
+ {
+ if (*p == '.' || *p == '\\')
+ *q++ = '\\';
+ *q++ = *p;
+ p++;
+ }
+ *q++ = '.';
+ }
+ }
+ if (!indir)
+ *enclen = aresx_uztosl(p + 1U - encoded);
+
+ /* Nuke the trailing period if we wrote one. */
+ if (q > *s)
+ *(q - 1) = 0;
+ else
+ *q = 0; /* zero terminate */
+
+ return ARES_SUCCESS;
+}
+
+/* Return the length of the expansion of an encoded domain name, or
+ * -1 if the encoding is invalid.
+ */
+static int name_length(const unsigned char *encoded, const unsigned char *abuf,
+ int alen)
+{
+ int n = 0, offset, indir = 0;
+
+ /* Allow the caller to pass us abuf + alen and have us check for it. */
+ if (encoded == abuf + alen)
+ return -1;
+
+ while (*encoded)
+ {
+ if ((*encoded & INDIR_MASK) == INDIR_MASK)
+ {
+ /* Check the offset and go there. */
+ if (encoded + 1 >= abuf + alen)
+ return -1;
+ offset = (*encoded & ~INDIR_MASK) << 8 | *(encoded + 1);
+ if (offset >= alen)
+ return -1;
+ encoded = abuf + offset;
+
+ /* If we've seen more indirects than the message length,
+ * then there's a loop.
+ */
+ if (++indir > alen)
+ return -1;
+ }
+ else
+ {
+ offset = *encoded;
+ if (encoded + offset + 1 >= abuf + alen)
+ return -1;
+ encoded++;
+ while (offset--)
+ {
+ n += (*encoded == '.' || *encoded == '\\') ? 2 : 1;
+ encoded++;
+ }
+ n++;
+ }
+ }
+
+ /* If there were any labels at all, then the number of dots is one
+ * less than the number of labels, so subtract one.
+ */
+ return (n) ? n - 1 : n;
+}
+
+/* Like ares_expand_name but returns EBADRESP in case of invalid input. */
+int ares__expand_name_for_response(const unsigned char *encoded,
+ const unsigned char *abuf, int alen,
+ char **s, long *enclen)
+{
+ int status = ares_expand_name(encoded, abuf, alen, s, enclen);
+ if (status == ARES_EBADNAME)
+ status = ARES_EBADRESP;
+ return status;
+}
diff --git a/deps/uv/src/ares/ares_expand_string.c b/deps/cares/src/ares_expand_string.c
index f24cccf64..f24cccf64 100644
--- a/deps/uv/src/ares/ares_expand_string.c
+++ b/deps/cares/src/ares_expand_string.c
diff --git a/deps/uv/src/ares/ares_fds.c b/deps/cares/src/ares_fds.c
index ac5eedb32..ac5eedb32 100644
--- a/deps/uv/src/ares/ares_fds.c
+++ b/deps/cares/src/ares_fds.c
diff --git a/deps/uv/src/ares/ares_free_hostent.c b/deps/cares/src/ares_free_hostent.c
index 349d379af..349d379af 100644
--- a/deps/uv/src/ares/ares_free_hostent.c
+++ b/deps/cares/src/ares_free_hostent.c
diff --git a/deps/uv/src/ares/ares_free_string.c b/deps/cares/src/ares_free_string.c
index e0545c1d1..e0545c1d1 100644
--- a/deps/uv/src/ares/ares_free_string.c
+++ b/deps/cares/src/ares_free_string.c
diff --git a/deps/uv/src/ares/ares_getenv.c b/deps/cares/src/ares_getenv.c
index 1b2e85d2b..1b2e85d2b 100644
--- a/deps/uv/src/ares/ares_getenv.c
+++ b/deps/cares/src/ares_getenv.c
diff --git a/deps/uv/src/ares/ares_getenv.h b/deps/cares/src/ares_getenv.h
index 6da6cc508..6da6cc508 100644
--- a/deps/uv/src/ares/ares_getenv.h
+++ b/deps/cares/src/ares_getenv.h
diff --git a/deps/uv/src/ares/ares_gethostbyaddr.c b/deps/cares/src/ares_gethostbyaddr.c
index 4b4c8a7db..4b4c8a7db 100644
--- a/deps/uv/src/ares/ares_gethostbyaddr.c
+++ b/deps/cares/src/ares_gethostbyaddr.c
diff --git a/deps/cares/src/ares_gethostbyname.c b/deps/cares/src/ares_gethostbyname.c
new file mode 100644
index 000000000..4869402ba
--- /dev/null
+++ b/deps/cares/src/ares_gethostbyname.c
@@ -0,0 +1,524 @@
+
+/* Copyright 1998, 2011 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "ares.h"
+#include "inet_net_pton.h"
+#include "bitncmp.h"
+#include "ares_platform.h"
+#include "ares_nowarn.h"
+#include "ares_private.h"
+
+#ifdef WATT32
+#undef WIN32
+#endif
+
+struct host_query {
+ /* Arguments passed to ares_gethostbyname() */
+ ares_channel channel;
+ char *name;
+ ares_host_callback callback;
+ void *arg;
+ int sent_family; /* this family is what was is being used */
+ int want_family; /* this family is what is asked for in the API */
+ const char *remaining_lookups;
+ int timeouts;
+};
+
+static void next_lookup(struct host_query *hquery, int status_code);
+static void host_callback(void *arg, int status, int timeouts,
+ unsigned char *abuf, int alen);
+static void end_hquery(struct host_query *hquery, int status,
+ struct hostent *host);
+static int fake_hostent(const char *name, int family,
+ ares_host_callback callback, void *arg);
+static int file_lookup(const char *name, int family, struct hostent **host);
+static void sort_addresses(struct hostent *host,
+ const struct apattern *sortlist, int nsort);
+static void sort6_addresses(struct hostent *host,
+ const struct apattern *sortlist, int nsort);
+static int get_address_index(const struct in_addr *addr,
+ const struct apattern *sortlist, int nsort);
+static int get6_address_index(const struct ares_in6_addr *addr,
+ const struct apattern *sortlist, int nsort);
+
+void ares_gethostbyname(ares_channel channel, const char *name, int family,
+ ares_host_callback callback, void *arg)
+{
+ struct host_query *hquery;
+
+ /* Right now we only know how to look up Internet addresses - and unspec
+ means try both basically. */
+ switch (family) {
+ case AF_INET:
+ case AF_INET6:
+ case AF_UNSPEC:
+ break;
+ default:
+ callback(arg, ARES_ENOTIMP, 0, NULL);
+ return;
+ }
+
+ if (fake_hostent(name, family, callback, arg))
+ return;
+
+ /* Allocate and fill in the host query structure. */
+ hquery = malloc(sizeof(struct host_query));
+ if (!hquery)
+ {
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return;
+ }
+ hquery->channel = channel;
+ hquery->name = strdup(name);
+ hquery->want_family = family;
+ hquery->sent_family = -1; /* nothing is sent yet */
+ if (!hquery->name) {
+ free(hquery);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return;
+ }
+ hquery->callback = callback;
+ hquery->arg = arg;
+ hquery->remaining_lookups = channel->lookups;
+ hquery->timeouts = 0;
+
+ /* Start performing lookups according to channel->lookups. */
+ next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */);
+}
+
+static void next_lookup(struct host_query *hquery, int status_code)
+{
+ const char *p;
+ struct hostent *host;
+ int status = status_code;
+
+ for (p = hquery->remaining_lookups; *p; p++)
+ {
+ switch (*p)
+ {
+ case 'b':
+ /* DNS lookup */
+ hquery->remaining_lookups = p + 1;
+ if ((hquery->want_family == AF_INET6) ||
+ (hquery->want_family == AF_UNSPEC)) {
+ /* if inet6 or unspec, start out with AAAA */
+ hquery->sent_family = AF_INET6;
+ ares_search(hquery->channel, hquery->name, C_IN, T_AAAA,
+ host_callback, hquery);
+ }
+ else {
+ hquery->sent_family = AF_INET;
+ ares_search(hquery->channel, hquery->name, C_IN, T_A,
+ host_callback, hquery);
+ }
+ return;
+
+ case 'f':
+ /* Host file lookup */
+ status = file_lookup(hquery->name, hquery->want_family, &host);
+
+ /* this status check below previously checked for !ARES_ENOTFOUND,
+ but we should not assume that this single error code is the one
+ that can occur, as that is in fact no longer the case */
+ if (status == ARES_SUCCESS)
+ {
+ end_hquery(hquery, status, host);
+ return;
+ }
+ status = status_code; /* Use original status code */
+ break;
+ }
+ }
+ end_hquery(hquery, status, NULL);
+}
+
+static void host_callback(void *arg, int status, int timeouts,
+ unsigned char *abuf, int alen)
+{
+ struct host_query *hquery = (struct host_query *) arg;
+ ares_channel channel = hquery->channel;
+ struct hostent *host = NULL;
+
+ hquery->timeouts += timeouts;
+ if (status == ARES_SUCCESS)
+ {
+ if (hquery->sent_family == AF_INET)
+ {
+ status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL);
+ if (host && channel->nsort)
+ sort_addresses(host, channel->sortlist, channel->nsort);
+ }
+ else if (hquery->sent_family == AF_INET6)
+ {
+ status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL);
+ if ((status == ARES_ENODATA || status == ARES_EBADRESP) &&
+ hquery->want_family == AF_UNSPEC) {
+ /* The query returned something but either there were no AAAA
+ records (e.g. just CNAME) or the response was malformed. Try
+ looking up A instead. */
+ hquery->sent_family = AF_INET;
+ ares_search(hquery->channel, hquery->name, C_IN, T_A,
+ host_callback, hquery);
+ return;
+ }
+ if (host && channel->nsort)
+ sort6_addresses(host, channel->sortlist, channel->nsort);
+ }
+ end_hquery(hquery, status, host);
+ }
+ else if ((status == ARES_ENODATA || status == ARES_EBADRESP ||
+ status == ARES_ETIMEOUT) && (hquery->sent_family == AF_INET6 &&
+ hquery->want_family == AF_UNSPEC))
+ {
+ /* The AAAA query yielded no useful result. Now look up an A instead. */
+ hquery->sent_family = AF_INET;
+ ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
+ hquery);
+ }
+ else if (status == ARES_EDESTRUCTION)
+ end_hquery(hquery, status, NULL);
+ else
+ next_lookup(hquery, status);
+}
+
+static void end_hquery(struct host_query *hquery, int status,
+ struct hostent *host)
+{
+ hquery->callback(hquery->arg, status, hquery->timeouts, host);
+ if (host)
+ ares_free_hostent(host);
+ free(hquery->name);
+ free(hquery);
+}
+
+/* If the name looks like an IP address, fake up a host entry, end the
+ * query immediately, and return true. Otherwise return false.
+ */
+static int fake_hostent(const char *name, int family,
+ ares_host_callback callback, void *arg)
+{
+ struct hostent hostent;
+ char *aliases[1] = { NULL };
+ char *addrs[2];
+ int result = 0;
+ struct in_addr in;
+ struct ares_in6_addr in6;
+
+ if (family == AF_INET || family == AF_INET6)
+ {
+ /* It only looks like an IP address if it's all numbers and dots. */
+ int numdots = 0, valid = 1;
+ const char *p;
+ for (p = name; *p; p++)
+ {
+ if (!ISDIGIT(*p) && *p != '.') {
+ valid = 0;
+ break;
+ } else if (*p == '.') {
+ numdots++;
+ }
+ }
+
+ /* if we don't have 3 dots, it is illegal
+ * (although inet_addr doesn't think so).
+ */
+ if (numdots != 3 || !valid)
+ result = 0;
+ else
+ result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1);
+
+ if (result)
+ family = AF_INET;
+ }
+ if (family == AF_INET6)
+ result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1);
+
+ if (!result)
+ return 0;
+
+ if (family == AF_INET)
+ {
+ hostent.h_length = (int)sizeof(struct in_addr);
+ addrs[0] = (char *)&in;
+ }
+ else if (family == AF_INET6)
+ {
+ hostent.h_length = (int)sizeof(struct ares_in6_addr);
+ addrs[0] = (char *)&in6;
+ }
+ /* Duplicate the name, to avoid a constness violation. */
+ hostent.h_name = strdup(name);
+ if (!hostent.h_name)
+ {
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return 1;
+ }
+
+ /* Fill in the rest of the host structure and terminate the query. */
+ addrs[1] = NULL;
+ hostent.h_aliases = aliases;
+ hostent.h_addrtype = aresx_sitoss(family);
+ hostent.h_addr_list = addrs;
+ callback(arg, ARES_SUCCESS, 0, &hostent);
+
+ free((char *)(hostent.h_name));
+ return 1;
+}
+
+/* This is an API method */
+int ares_gethostbyname_file(ares_channel channel, const char *name,
+ int family, struct hostent **host)
+{
+ int result;
+
+ /* We only take the channel to ensure that ares_init() been called. */
+ if(channel == NULL)
+ {
+ /* Anything will do, really. This seems fine, and is consistent with
+ other error cases. */
+ *host = NULL;
+ return ARES_ENOTFOUND;
+ }
+
+ /* Just chain to the internal implementation we use here; it's exactly
+ * what we want.
+ */
+ result = file_lookup(name, family, host);
+ if(result != ARES_SUCCESS)
+ {
+ /* We guarantee a NULL hostent on failure. */
+ *host = NULL;
+ }
+ return result;
+}
+
+static int file_lookup(const char *name, int family, struct hostent **host)
+{
+ FILE *fp;
+ char **alias;
+ int status;
+ int error;
+
+#ifdef WIN32
+ char PATH_HOSTS[MAX_PATH];
+ win_platform platform;
+
+ PATH_HOSTS[0] = '\0';
+
+ platform = ares__getplatform();
+
+ if (platform == WIN_NT) {
+ char tmp[MAX_PATH];
+ HKEY hkeyHosts;
+
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
+ &hkeyHosts) == ERROR_SUCCESS)
+ {
+ DWORD dwLength = MAX_PATH;
+ RegQueryValueEx(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp,
+ &dwLength);
+ ExpandEnvironmentStrings(tmp, PATH_HOSTS, MAX_PATH);
+ RegCloseKey(hkeyHosts);
+ }
+ }
+ else if (platform == WIN_9X)
+ GetWindowsDirectory(PATH_HOSTS, MAX_PATH);
+ else
+ return ARES_ENOTFOUND;
+
+ strcat(PATH_HOSTS, WIN_PATH_HOSTS);
+
+#elif defined(WATT32)
+ extern const char *_w32_GetHostsFile (void);
+ const char *PATH_HOSTS = _w32_GetHostsFile();
+
+ if (!PATH_HOSTS)
+ return ARES_ENOTFOUND;
+#endif
+
+ fp = fopen(PATH_HOSTS, "r");
+ if (!fp)
+ {
+ error = ERRNO;
+ switch(error)
+ {
+ case ENOENT:
+ case ESRCH:
+ return ARES_ENOTFOUND;
+ default:
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+ error, strerror(error)));
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n",
+ PATH_HOSTS));
+ *host = NULL;
+ return ARES_EFILE;
+ }
+ }
+ while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
+ {
+ if (strcasecmp((*host)->h_name, name) == 0)
+ break;
+ for (alias = (*host)->h_aliases; *alias; alias++)
+ {
+ if (strcasecmp(*alias, name) == 0)
+ break;
+ }
+ if (*alias)
+ break;
+ ares_free_hostent(*host);
+ }
+ fclose(fp);
+ if (status == ARES_EOF)
+ status = ARES_ENOTFOUND;
+ if (status != ARES_SUCCESS)
+ *host = NULL;
+ return status;
+}
+
+static void sort_addresses(struct hostent *host,
+ const struct apattern *sortlist, int nsort)
+{
+ struct in_addr a1, a2;
+ int i1, i2, ind1, ind2;
+
+ /* This is a simple insertion sort, not optimized at all. i1 walks
+ * through the address list, with the loop invariant that everything
+ * to the left of i1 is sorted. In the loop body, the value at i1 is moved
+ * back through the list (via i2) until it is in sorted order.
+ */
+ for (i1 = 0; host->h_addr_list[i1]; i1++)
+ {
+ memcpy(&a1, host->h_addr_list[i1], sizeof(struct in_addr));
+ ind1 = get_address_index(&a1, sortlist, nsort);
+ for (i2 = i1 - 1; i2 >= 0; i2--)
+ {
+ memcpy(&a2, host->h_addr_list[i2], sizeof(struct in_addr));
+ ind2 = get_address_index(&a2, sortlist, nsort);
+ if (ind2 <= ind1)
+ break;
+ memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in_addr));
+ }
+ memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in_addr));
+ }
+}
+
+/* Find the first entry in sortlist which matches addr. Return nsort
+ * if none of them match.
+ */
+static int get_address_index(const struct in_addr *addr,
+ const struct apattern *sortlist,
+ int nsort)
+{
+ int i;
+
+ for (i = 0; i < nsort; i++)
+ {
+ if (sortlist[i].family != AF_INET)
+ continue;
+ if (sortlist[i].type == PATTERN_MASK)
+ {
+ if ((addr->s_addr & sortlist[i].mask.addr4.s_addr)
+ == sortlist[i].addrV4.s_addr)
+ break;
+ }
+ else
+ {
+ if (!ares_bitncmp(&addr->s_addr, &sortlist[i].addrV4.s_addr,
+ sortlist[i].mask.bits))
+ break;
+ }
+ }
+ return i;
+}
+
+static void sort6_addresses(struct hostent *host,
+ const struct apattern *sortlist, int nsort)
+{
+ struct ares_in6_addr a1, a2;
+ int i1, i2, ind1, ind2;
+
+ /* This is a simple insertion sort, not optimized at all. i1 walks
+ * through the address list, with the loop invariant that everything
+ * to the left of i1 is sorted. In the loop body, the value at i1 is moved
+ * back through the list (via i2) until it is in sorted order.
+ */
+ for (i1 = 0; host->h_addr_list[i1]; i1++)
+ {
+ memcpy(&a1, host->h_addr_list[i1], sizeof(struct ares_in6_addr));
+ ind1 = get6_address_index(&a1, sortlist, nsort);
+ for (i2 = i1 - 1; i2 >= 0; i2--)
+ {
+ memcpy(&a2, host->h_addr_list[i2], sizeof(struct ares_in6_addr));
+ ind2 = get6_address_index(&a2, sortlist, nsort);
+ if (ind2 <= ind1)
+ break;
+ memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct ares_in6_addr));
+ }
+ memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct ares_in6_addr));
+ }
+}
+
+/* Find the first entry in sortlist which matches addr. Return nsort
+ * if none of them match.
+ */
+static int get6_address_index(const struct ares_in6_addr *addr,
+ const struct apattern *sortlist,
+ int nsort)
+{
+ int i;
+
+ for (i = 0; i < nsort; i++)
+ {
+ if (sortlist[i].family != AF_INET6)
+ continue;
+ if (!ares_bitncmp(addr,
+ &sortlist[i].addrV6,
+ sortlist[i].mask.bits))
+ break;
+ }
+ return i;
+}
diff --git a/deps/cares/src/ares_getnameinfo.c b/deps/cares/src/ares_getnameinfo.c
new file mode 100644
index 000000000..cdcd51649
--- /dev/null
+++ b/deps/cares/src/ares_getnameinfo.c
@@ -0,0 +1,427 @@
+
+/* Copyright 2005 by Dominick Meglio
+ *
+ * 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.
+ */
+#include "ares_setup.h"
+
+#ifdef HAVE_GETSERVBYPORT_R
+# if !defined(GETSERVBYPORT_R_ARGS) || \
+ (GETSERVBYPORT_R_ARGS < 4) || (GETSERVBYPORT_R_ARGS > 6)
+# error "you MUST specifiy a valid number of arguments for getservbyport_r"
+# endif
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ares.h"
+#include "ares_ipv6.h"
+#include "inet_ntop.h"
+#include "ares_nowarn.h"
+#include "ares_private.h"
+
+struct nameinfo_query {
+ ares_nameinfo_callback callback;
+ void *arg;
+ union {
+ struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+ } addr;
+ int family;
+ int flags;
+ int timeouts;
+};
+
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+#define IPBUFSIZ \
+ (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") + IF_NAMESIZE)
+#else
+#define IPBUFSIZ \
+ (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))
+#endif
+
+static void nameinfo_callback(void *arg, int status, int timeouts,
+ struct hostent *host);
+static char *lookup_service(unsigned short port, int flags,
+ char *buf, size_t buflen);
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid,
+ char *buf, size_t buflen);
+#endif
+static char *ares_striendstr(const char *s1, const char *s2);
+
+void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
+ ares_socklen_t salen,
+ int flags, ares_nameinfo_callback callback, void *arg)
+{
+ struct sockaddr_in *addr = NULL;
+ struct sockaddr_in6 *addr6 = NULL;
+ struct nameinfo_query *niquery;
+ unsigned int port = 0;
+
+ /* Validate socket address family and length */
+ if ((sa->sa_family == AF_INET) &&
+ (salen == sizeof(struct sockaddr_in)))
+ {
+ addr = (struct sockaddr_in *)sa;
+ port = addr->sin_port;
+ }
+ else if ((sa->sa_family == AF_INET6) &&
+ (salen == sizeof(struct sockaddr_in6)))
+ {
+ addr6 = (struct sockaddr_in6 *)sa;
+ port = addr6->sin6_port;
+ }
+ else
+ {
+ callback(arg, ARES_ENOTIMP, 0, NULL, NULL);
+ return;
+ }
+
+ /* If neither, assume they want a host */
+ if (!(flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST))
+ flags |= ARES_NI_LOOKUPHOST;
+
+ /* All they want is a service, no need for DNS */
+ if ((flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST))
+ {
+ char buf[33], *service;
+
+ service = lookup_service((unsigned short)(port & 0xffff),
+ flags, buf, sizeof(buf));
+ callback(arg, ARES_SUCCESS, 0, NULL, service);
+ return;
+ }
+
+ /* They want a host lookup */
+ if ((flags & ARES_NI_LOOKUPHOST))
+ {
+ /* A numeric host can be handled without DNS */
+ if ((flags & ARES_NI_NUMERICHOST))
+ {
+ char ipbuf[IPBUFSIZ];
+ char srvbuf[33];
+ char *service = NULL;
+ ipbuf[0] = 0;
+
+ /* Specifying not to lookup a host, but then saying a host
+ * is required has to be illegal.
+ */
+ if (flags & ARES_NI_NAMEREQD)
+ {
+ callback(arg, ARES_EBADFLAGS, 0, NULL, NULL);
+ return;
+ }
+ if (salen == sizeof(struct sockaddr_in6))
+ {
+ ares_inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, IPBUFSIZ);
+ /* If the system supports scope IDs, use it */
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+ append_scopeid(addr6, flags, ipbuf, sizeof(ipbuf));
+#endif
+ }
+ else
+ {
+ ares_inet_ntop(AF_INET, &addr->sin_addr, ipbuf, IPBUFSIZ);
+ }
+ /* They also want a service */
+ if (flags & ARES_NI_LOOKUPSERVICE)
+ service = lookup_service((unsigned short)(port & 0xffff),
+ flags, srvbuf, sizeof(srvbuf));
+ callback(arg, ARES_SUCCESS, 0, ipbuf, service);
+ return;
+ }
+ /* This is where a DNS lookup becomes necessary */
+ else
+ {
+ niquery = malloc(sizeof(struct nameinfo_query));
+ if (!niquery)
+ {
+ callback(arg, ARES_ENOMEM, 0, NULL, NULL);
+ return;
+ }
+ niquery->callback = callback;
+ niquery->arg = arg;
+ niquery->flags = flags;
+ niquery->timeouts = 0;
+ if (sa->sa_family == AF_INET)
+ {
+ niquery->family = AF_INET;
+ memcpy(&niquery->addr.addr4, addr, sizeof(niquery->addr.addr4));
+ ares_gethostbyaddr(channel, &addr->sin_addr,
+ sizeof(struct in_addr), AF_INET,
+ nameinfo_callback, niquery);
+ }
+ else
+ {
+ niquery->family = AF_INET6;
+ memcpy(&niquery->addr.addr6, addr6, sizeof(niquery->addr.addr6));
+ ares_gethostbyaddr(channel, &addr6->sin6_addr,
+ sizeof(struct ares_in6_addr), AF_INET6,
+ nameinfo_callback, niquery);
+ }
+ }
+ }
+}
+
+static void nameinfo_callback(void *arg, int status, int timeouts,
+ struct hostent *host)
+{
+ struct nameinfo_query *niquery = (struct nameinfo_query *) arg;
+ char srvbuf[33];
+ char *service = NULL;
+
+ niquery->timeouts += timeouts;
+ if (status == ARES_SUCCESS)
+ {
+ /* They want a service too */
+ if (niquery->flags & ARES_NI_LOOKUPSERVICE)
+ {
+ if (niquery->family == AF_INET)
+ service = lookup_service(niquery->addr.addr4.sin_port,
+ niquery->flags, srvbuf, sizeof(srvbuf));
+ else
+ service = lookup_service(niquery->addr.addr6.sin6_port,
+ niquery->flags, srvbuf, sizeof(srvbuf));
+ }
+ /* NOFQDN means we have to strip off the domain name portion. We do
+ this by determining our own domain name, then searching the string
+ for this domain name and removing it.
+ */
+#ifdef HAVE_GETHOSTNAME
+ if (niquery->flags & ARES_NI_NOFQDN)
+ {
+ char buf[255];
+ char *domain;
+ gethostname(buf, 255);
+ if ((domain = strchr(buf, '.')) != NULL)
+ {
+ char *end = ares_striendstr(host->h_name, domain);
+ if (end)
+ *end = 0;
+ }
+ }
+#endif
+ niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts,
+ (char *)(host->h_name),
+ service);
+ free(niquery);
+ return;
+ }
+ /* We couldn't find the host, but it's OK, we can use the IP */
+ else if (status == ARES_ENOTFOUND && !(niquery->flags & ARES_NI_NAMEREQD))
+ {
+ char ipbuf[IPBUFSIZ];
+ if (niquery->family == AF_INET)
+ ares_inet_ntop(AF_INET, &niquery->addr.addr4.sin_addr, ipbuf,
+ IPBUFSIZ);
+ else
+ {
+ ares_inet_ntop(AF_INET6, &niquery->addr.addr6.sin6_addr, ipbuf,
+ IPBUFSIZ);
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+ append_scopeid(&niquery->addr.addr6, niquery->flags, ipbuf,
+ sizeof(ipbuf));
+#endif
+ }
+ /* They want a service too */
+ if (niquery->flags & ARES_NI_LOOKUPSERVICE)
+ {
+ if (niquery->family == AF_INET)
+ service = lookup_service(niquery->addr.addr4.sin_port,
+ niquery->flags, srvbuf, sizeof(srvbuf));
+ else
+ service = lookup_service(niquery->addr.addr6.sin6_port,
+ niquery->flags, srvbuf, sizeof(srvbuf));
+ }
+ niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, ipbuf,
+ service);
+ free(niquery);
+ return;
+ }
+ niquery->callback(niquery->arg, status, niquery->timeouts, NULL, NULL);
+ free(niquery);
+}
+
+static char *lookup_service(unsigned short port, int flags,
+ char *buf, size_t buflen)
+{
+ const char *proto;
+ struct servent *sep;
+#ifdef HAVE_GETSERVBYPORT_R
+ struct servent se;
+#endif
+ char tmpbuf[4096];
+
+ if (port)
+ {
+ if (flags & ARES_NI_NUMERICSERV)
+ sep = NULL;
+ else
+ {
+ if (flags & ARES_NI_UDP)
+ proto = "udp";
+ else if (flags & ARES_NI_SCTP)
+ proto = "sctp";
+ else if (flags & ARES_NI_DCCP)
+ proto = "dccp";
+ else
+ proto = "tcp";
+#ifdef HAVE_GETSERVBYPORT_R
+ sep = &se;
+ memset(tmpbuf, 0, sizeof(tmpbuf));
+#if GETSERVBYPORT_R_ARGS == 6
+ if (getservbyport_r(port, proto, &se, (void *)tmpbuf,
+ sizeof(tmpbuf), &sep) != 0)
+ sep = NULL;
+#elif GETSERVBYPORT_R_ARGS == 5
+ sep = getservbyport_r(port, proto, &se, (void *)tmpbuf,
+ sizeof(tmpbuf));
+#elif GETSERVBYPORT_R_ARGS == 4
+ if (getservbyport_r(port, proto, &se, (void *)tmpbuf) != 0)
+ sep = NULL;
+#else
+ /* Lets just hope the OS uses TLS! */
+ sep = getservbyport(port, proto);
+#endif
+#else
+ /* Lets just hope the OS uses TLS! */
+#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
+ sep = getservbyport(port, (char*)proto);
+#else
+ sep = getservbyport(port, proto);
+#endif
+#endif
+ }
+ if (sep && sep->s_name)
+ /* get service name */
+ strcpy(tmpbuf, sep->s_name);
+ else
+ /* get port as a string */
+ sprintf(tmpbuf, "%u", (unsigned int)ntohs(port));
+ if (strlen(tmpbuf) < buflen)
+ /* return it if buffer big enough */
+ strcpy(buf, tmpbuf);
+ else
+ /* avoid reusing previous one */
+ buf[0] = '\0';
+ return buf;
+ }
+ buf[0] = '\0';
+ return NULL;
+}
+
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
+ char *buf, size_t buflen)
+{
+#ifdef HAVE_IF_INDEXTONAME
+ int is_ll, is_mcll;
+#endif
+ static const char fmt_u[] = "%u";
+ static const char fmt_lu[] = "%lu";
+ char tmpbuf[IF_NAMESIZE + 2];
+ size_t bufl;
+ const char *fmt = (sizeof(addr6->sin6_scope_id) > sizeof(unsigned int))?
+ fmt_lu:fmt_u;
+
+ tmpbuf[0] = '%';
+
+#ifdef HAVE_IF_INDEXTONAME
+ is_ll = IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr);
+ is_mcll = IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr);
+ if ((flags & ARES_NI_NUMERICSCOPE) ||
+ (!is_ll && !is_mcll))
+ {
+ sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
+ }
+ else
+ {
+ if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL)
+ sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
+ }
+#else
+ sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
+ (void) flags;
+#endif
+ tmpbuf[IF_NAMESIZE + 1] = '\0';
+ bufl = strlen(buf);
+
+ if(bufl + strlen(tmpbuf) < buflen)
+ /* only append the scopeid string if it fits in the target buffer */
+ strcpy(&buf[bufl], tmpbuf);
+}
+#endif
+
+/* Determines if s1 ends with the string in s2 (case-insensitive) */
+static char *ares_striendstr(const char *s1, const char *s2)
+{
+ const char *c1, *c2, *c1_begin;
+ int lo1, lo2;
+ size_t s1_len = strlen(s1), s2_len = strlen(s2);
+
+ /* If the substr is longer than the full str, it can't match */
+ if (s2_len > s1_len)
+ return NULL;
+
+ /* Jump to the end of s1 minus the length of s2 */
+ c1_begin = s1+s1_len-s2_len;
+ c1 = (const char *)c1_begin;
+ c2 = s2;
+ while (c2 < s2+s2_len)
+ {
+ lo1 = TOLOWER(*c1);
+ lo2 = TOLOWER(*c2);
+ if (lo1 != lo2)
+ return NULL;
+ else
+ {
+ c1++;
+ c2++;
+ }
+ }
+ if (c2 == c1 && c2 == NULL)
+ return (char *)c1_begin;
+ return NULL;
+}
diff --git a/deps/uv/src/ares/ares_getopt.c b/deps/cares/src/ares_getopt.c
index 1e02d0868..1e02d0868 100644
--- a/deps/uv/src/ares/ares_getopt.c
+++ b/deps/cares/src/ares_getopt.c
diff --git a/deps/uv/src/ares/ares_getopt.h b/deps/cares/src/ares_getopt.h
index 63acb3b42..63acb3b42 100644
--- a/deps/uv/src/ares/ares_getopt.h
+++ b/deps/cares/src/ares_getopt.h
diff --git a/deps/uv/src/ares/ares_getsock.c b/deps/cares/src/ares_getsock.c
index 72e467f2e..72e467f2e 100644
--- a/deps/uv/src/ares/ares_getsock.c
+++ b/deps/cares/src/ares_getsock.c
diff --git a/deps/cares/src/ares_init.c b/deps/cares/src/ares_init.c
new file mode 100644
index 000000000..4aef21ad4
--- /dev/null
+++ b/deps/cares/src/ares_init.c
@@ -0,0 +1,2021 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2007-2012 by Daniel Stenberg
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+
+#if defined(ANDROID) || defined(__ANDROID__)
+#include <sys/system_properties.h>
+/* From the Bionic sources */
+#define DNS_PROP_NAME_PREFIX "net.dns"
+#define MAX_DNS_PROPERTIES 8
+#endif
+
+#include "ares.h"
+#include "inet_ntop.h"
+#include "inet_net_pton.h"
+#include "ares_library_init.h"
+#include "ares_nowarn.h"
+#include "ares_platform.h"
+#include "ares_private.h"
+
+#ifdef WATT32
+#undef WIN32 /* Redefined in MingW/MSVC headers */
+#endif
+
+static int init_by_options(ares_channel channel,
+ const struct ares_options *options,
+ int optmask);
+static int init_by_environment(ares_channel channel);
+static int init_by_resolv_conf(ares_channel channel);
+static int init_by_defaults(ares_channel channel);
+
+#ifndef WATT32
+static int config_nameserver(struct server_state **servers, int *nservers,
+ char *str);
+#endif
+static int set_search(ares_channel channel, const char *str);
+static int set_options(ares_channel channel, const char *str);
+static const char *try_option(const char *p, const char *q, const char *opt);
+static int init_id_key(rc4_key* key,int key_data_len);
+
+#if !defined(WIN32) && !defined(WATT32) && \
+ !defined(ANDROID) && !defined(__ANDROID__)
+static int sortlist_alloc(struct apattern **sortlist, int *nsort,
+ struct apattern *pat);
+static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
+static void natural_mask(struct apattern *pat);
+static int config_domain(ares_channel channel, char *str);
+static int config_lookup(ares_channel channel, const char *str,
+ const char *bindch, const char *filech);
+static int config_sortlist(struct apattern **sortlist, int *nsort,
+ const char *str);
+static char *try_config(char *s, const char *opt, char scc);
+#endif
+
+#define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
+ x->nservers > -1 && \
+ x->ndomains > -1 && \
+ x->ndots > -1 && x->timeout > -1 && \
+ x->tries > -1)
+
+int ares_init(ares_channel *channelptr)
+{
+ return ares_init_options(channelptr, NULL, 0);
+}
+
+int ares_init_options(ares_channel *channelptr, struct ares_options *options,
+ int optmask)
+{
+ ares_channel channel;
+ int i;
+ int status = ARES_SUCCESS;
+ struct timeval now;
+
+#ifdef CURLDEBUG
+ const char *env = getenv("CARES_MEMDEBUG");
+
+ if (env)
+ curl_memdebug(env);
+ env = getenv("CARES_MEMLIMIT");
+ if (env) {
+ char *endptr;
+ long num = strtol(env, &endptr, 10);
+ if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
+ curl_memlimit(num);
+ }
+#endif
+
+ if (ares_library_initialized() != ARES_SUCCESS)
+ return ARES_ENOTINITIALIZED;
+
+ channel = malloc(sizeof(struct ares_channeldata));
+ if (!channel) {
+ *channelptr = NULL;
+ return ARES_ENOMEM;
+ }
+
+ now = ares__tvnow();
+
+ /* Set everything to distinguished values so we know they haven't
+ * been set yet.
+ */
+ channel->flags = -1;
+ channel->timeout = -1;
+ channel->tries = -1;
+ channel->ndots = -1;
+ channel->rotate = -1;
+ channel->udp_port = -1;
+ channel->tcp_port = -1;
+ channel->socket_send_buffer_size = -1;
+ channel->socket_receive_buffer_size = -1;
+ channel->nservers = -1;
+ channel->ndomains = -1;
+ channel->nsort = -1;
+ channel->tcp_connection_generation = 0;
+ channel->lookups = NULL;
+ channel->domains = NULL;
+ channel->sortlist = NULL;
+ channel->servers = NULL;
+ channel->sock_state_cb = NULL;
+ channel->sock_state_cb_data = NULL;
+ channel->sock_create_cb = NULL;
+ channel->sock_create_cb_data = NULL;
+
+ channel->last_server = 0;
+ channel->last_timeout_processed = (time_t)now.tv_sec;
+
+ memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
+ channel->local_ip4 = 0;
+ memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
+
+ /* Initialize our lists of queries */
+ ares__init_list_head(&(channel->all_queries));
+ for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
+ {
+ ares__init_list_head(&(channel->queries_by_qid[i]));
+ }
+ for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
+ {
+ ares__init_list_head(&(channel->queries_by_timeout[i]));
+ }
+
+ /* Initialize configuration by each of the four sources, from highest
+ * precedence to lowest.
+ */
+
+ if (status == ARES_SUCCESS) {
+ status = init_by_options(channel, options, optmask);
+ if (status != ARES_SUCCESS)
+ DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
+ ares_strerror(status)));
+ }
+ if (status == ARES_SUCCESS) {
+ status = init_by_environment(channel);
+ if (status != ARES_SUCCESS)
+ DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
+ ares_strerror(status)));
+ }
+ if (status == ARES_SUCCESS) {
+ status = init_by_resolv_conf(channel);
+ if (status != ARES_SUCCESS)
+ DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
+ ares_strerror(status)));
+ }
+
+ /*
+ * No matter what failed or succeeded, seed defaults to provide
+ * useful behavior for things that we missed.
+ */
+ status = init_by_defaults(channel);
+ if (status != ARES_SUCCESS)
+ DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
+ ares_strerror(status)));
+
+ /* Generate random key */
+
+ if (status == ARES_SUCCESS) {
+ status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
+ if (status == ARES_SUCCESS)
+ channel->next_id = ares__generate_new_id(&channel->id_key);
+ else
+ DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
+ ares_strerror(status)));
+ }
+
+ if (status != ARES_SUCCESS)
+ {
+ /* Something failed; clean up memory we may have allocated. */
+ if (channel->servers)
+ free(channel->servers);
+ if (channel->domains)
+ {
+ for (i = 0; i < channel->ndomains; i++)
+ free(channel->domains[i]);
+ free(channel->domains);
+ }
+ if (channel->sortlist)
+ free(channel->sortlist);
+ if(channel->lookups)
+ free(channel->lookups);
+ free(channel);
+ return status;
+ }
+
+ /* Trim to one server if ARES_FLAG_PRIMARY is set. */
+ if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
+ channel->nservers = 1;
+
+ ares__init_servers_state(channel);
+
+ *channelptr = channel;
+ return ARES_SUCCESS;
+}
+
+/* ares_dup() duplicates a channel handle with all its options and returns a
+ new channel handle */
+int ares_dup(ares_channel *dest, ares_channel src)
+{
+ struct ares_options opts;
+ struct ares_addr_node *servers;
+ int ipv6_nservers = 0;
+ int i, rc;
+ int optmask;
+
+ *dest = NULL; /* in case of failure return NULL explicitly */
+
+ /* First get the options supported by the old ares_save_options() function,
+ which is most of them */
+ rc = ares_save_options(src, &opts, &optmask);
+ if(rc)
+ return rc;
+
+ /* Then create the new channel with those options */
+ rc = ares_init_options(dest, &opts, optmask);
+
+ /* destroy the options copy to not leak any memory */
+ ares_destroy_options(&opts);
+
+ if(rc)
+ return rc;
+
+ /* Now clone the options that ares_save_options() doesn't support. */
+ (*dest)->sock_create_cb = src->sock_create_cb;
+ (*dest)->sock_create_cb_data = src->sock_create_cb_data;
+
+ strncpy((*dest)->local_dev_name, src->local_dev_name,
+ sizeof(src->local_dev_name));
+ (*dest)->local_ip4 = src->local_ip4;
+ memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
+
+ /* Full name server cloning required when not all are IPv4 */
+ for (i = 0; i < src->nservers; i++)
+ {
+ if (src->servers[i].addr.family != AF_INET) {
+ ipv6_nservers++;
+ break;
+ }
+ }
+ if (ipv6_nservers) {
+ rc = ares_get_servers(src, &servers);
+ if (rc != ARES_SUCCESS)
+ return rc;
+ rc = ares_set_servers(*dest, servers);
+ ares_free_data(servers);
+ if (rc != ARES_SUCCESS)
+ return rc;
+ }
+
+ return ARES_SUCCESS; /* everything went fine */
+}
+
+/* Save options from initialized channel */
+int ares_save_options(ares_channel channel, struct ares_options *options,
+ int *optmask)
+{
+ int i, j;
+ int ipv4_nservers = 0;
+
+ /* Zero everything out */
+ memset(options, 0, sizeof(struct ares_options));
+
+ if (!ARES_CONFIG_CHECK(channel))
+ return ARES_ENODATA;
+
+ /* Traditionally the optmask wasn't saved in the channel struct so it was
+ recreated here. ROTATE is the first option that has no struct field of
+ its own in the public config struct */
+ (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
+ ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
+ ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
+ ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
+ (channel->optmask & ARES_OPT_ROTATE);
+
+ /* Copy easy stuff */
+ options->flags = channel->flags;
+
+ /* We return full millisecond resolution but that's only because we don't
+ set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
+ options->timeout = channel->timeout;
+ options->tries = channel->tries;
+ options->ndots = channel->ndots;
+ options->udp_port = ntohs(aresx_sitous(channel->udp_port));
+ options->tcp_port = ntohs(aresx_sitous(channel->tcp_port));
+ options->sock_state_cb = channel->sock_state_cb;
+ options->sock_state_cb_data = channel->sock_state_cb_data;
+
+ /* Copy IPv4 servers */
+ if (channel->nservers) {
+ for (i = 0; i < channel->nservers; i++)
+ {
+ if (channel->servers[i].addr.family == AF_INET)
+ ipv4_nservers++;
+ }
+ if (ipv4_nservers) {
+ options->servers = malloc(ipv4_nservers * sizeof(struct in_addr));
+ if (!options->servers)
+ return ARES_ENOMEM;
+ for (i = j = 0; i < channel->nservers; i++)
+ {
+ if (channel->servers[i].addr.family == AF_INET)
+ memcpy(&options->servers[j++],
+ &channel->servers[i].addr.addrV4,
+ sizeof(channel->servers[i].addr.addrV4));
+ }
+ }
+ }
+ options->nservers = ipv4_nservers;
+
+ /* copy domains */
+ if (channel->ndomains) {
+ options->domains = malloc(channel->ndomains * sizeof(char *));
+ if (!options->domains)
+ return ARES_ENOMEM;
+
+ for (i = 0; i < channel->ndomains; i++)
+ {
+ options->ndomains = i;
+ options->domains[i] = strdup(channel->domains[i]);
+ if (!options->domains[i])
+ return ARES_ENOMEM;
+ }
+ }
+ options->ndomains = channel->ndomains;
+
+ /* copy lookups */
+ if (channel->lookups) {
+ options->lookups = strdup(channel->lookups);
+ if (!options->lookups && channel->lookups)
+ return ARES_ENOMEM;
+ }
+
+ /* copy sortlist */
+ if (channel->nsort) {
+ options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
+ if (!options->sortlist)
+ return ARES_ENOMEM;
+ for (i = 0; i < channel->nsort; i++)
+ options->sortlist[i] = channel->sortlist[i];
+ }
+ options->nsort = channel->nsort;
+
+ return ARES_SUCCESS;
+}
+
+static int init_by_options(ares_channel channel,
+ const struct ares_options *options,
+ int optmask)
+{
+ int i;
+
+ /* Easy stuff. */
+ if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
+ channel->flags = options->flags;
+ if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
+ channel->timeout = options->timeout;
+ else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
+ channel->timeout = options->timeout * 1000;
+ if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
+ channel->tries = options->tries;
+ if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
+ channel->ndots = options->ndots;
+ if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
+ channel->rotate = 1;
+ if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
+ channel->udp_port = htons(options->udp_port);
+ if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
+ channel->tcp_port = htons(options->tcp_port);
+ if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
+ {
+ channel->sock_state_cb = options->sock_state_cb;
+ channel->sock_state_cb_data = options->sock_state_cb_data;
+ }
+ if ((optmask & ARES_OPT_SOCK_SNDBUF)
+ && channel->socket_send_buffer_size == -1)
+ channel->socket_send_buffer_size = options->socket_send_buffer_size;
+ if ((optmask & ARES_OPT_SOCK_RCVBUF)
+ && channel->socket_receive_buffer_size == -1)
+ channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
+
+ /* Copy the IPv4 servers, if given. */
+ if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
+ {
+ /* Avoid zero size allocations at any cost */
+ if (options->nservers > 0)
+ {
+ channel->servers =
+ malloc(options->nservers * sizeof(struct server_state));
+ if (!channel->servers)
+ return ARES_ENOMEM;
+ for (i = 0; i < options->nservers; i++)
+ {
+ channel->servers[i].addr.family = AF_INET;
+ memcpy(&channel->servers[i].addr.addrV4,
+ &options->servers[i],
+ sizeof(channel->servers[i].addr.addrV4));
+ }
+ }
+ channel->nservers = options->nservers;
+ }
+
+ /* Copy the domains, if given. Keep channel->ndomains consistent so
+ * we can clean up in case of error.
+ */
+ if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
+ {
+ /* Avoid zero size allocations at any cost */
+ if (options->ndomains > 0)
+ {
+ channel->domains = malloc(options->ndomains * sizeof(char *));
+ if (!channel->domains)
+ return ARES_ENOMEM;
+ for (i = 0; i < options->ndomains; i++)
+ {
+ channel->ndomains = i;
+ channel->domains[i] = strdup(options->domains[i]);
+ if (!channel->domains[i])
+ return ARES_ENOMEM;
+ }
+ }
+ channel->ndomains = options->ndomains;
+ }
+
+ /* Set lookups, if given. */
+ if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
+ {
+ channel->lookups = strdup(options->lookups);
+ if (!channel->lookups)
+ return ARES_ENOMEM;
+ }
+
+ /* copy sortlist */
+ if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
+ (options->nsort>0)) {
+ channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
+ if (!channel->sortlist)
+ return ARES_ENOMEM;
+ for (i = 0; i < options->nsort; i++)
+ channel->sortlist[i] = options->sortlist[i];
+ channel->nsort = options->nsort;
+ }
+
+ channel->optmask = optmask;
+
+ return ARES_SUCCESS;
+}
+
+static int init_by_environment(ares_channel channel)
+{
+ const char *localdomain, *res_options;
+ int status;
+
+ localdomain = getenv("LOCALDOMAIN");
+ if (localdomain && channel->ndomains == -1)
+ {
+ status = set_search(channel, localdomain);
+ if (status != ARES_SUCCESS)
+ return status;
+ }
+
+ res_options = getenv("RES_OPTIONS");
+ if (res_options)
+ {
+ status = set_options(channel, res_options);
+ if (status != ARES_SUCCESS)
+ return status;
+ }
+
+ return ARES_SUCCESS;
+}
+
+#ifdef WIN32
+/*
+ * get_REG_SZ()
+ *
+ * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer
+ * to the name of the registry leaf key to be queried, fetch it's string
+ * value and return a pointer in *outptr to a newly allocated memory area
+ * holding it as a null-terminated string.
+ *
+ * Returns 0 and nullifies *outptr upon inability to return a string value.
+ *
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
+ *
+ * Supported on Windows NT 3.5 and newer.
+ */
+static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
+{
+ DWORD size = 0;
+ int res;
+
+ *outptr = NULL;
+
+ /* Find out size of string stored in registry */
+ res = RegQueryValueEx(hKey, leafKeyName, 0, NULL, NULL, &size);
+ if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
+ return 0;
+
+ /* Allocate buffer of indicated size plus one given that string
+ might have been stored without null termination */
+ *outptr = malloc(size+1);
+ if (!*outptr)
+ return 0;
+
+ /* Get the value for real */
+ res = RegQueryValueEx(hKey, leafKeyName, 0, NULL,
+ (unsigned char *)*outptr, &size);
+ if ((res != ERROR_SUCCESS) || (size == 1))
+ {
+ free(*outptr);
+ *outptr = NULL;
+ return 0;
+ }
+
+ /* Null terminate buffer allways */
+ *(*outptr + size) = '\0';
+
+ return 1;
+}
+
+/*
+ * get_REG_SZ_9X()
+ *
+ * Functionally identical to get_REG_SZ()
+ *
+ * Supported on Windows 95, 98 and ME.
+ */
+static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
+{
+ DWORD dataType = 0;
+ DWORD size = 0;
+ int res;
+
+ *outptr = NULL;
+
+ /* Find out size of string stored in registry */
+ res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType, NULL, &size);
+ if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
+ return 0;
+
+ /* Allocate buffer of indicated size plus one given that string
+ might have been stored without null termination */
+ *outptr = malloc(size+1);
+ if (!*outptr)
+ return 0;
+
+ /* Get the value for real */
+ res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType,
+ (unsigned char *)*outptr, &size);
+ if ((res != ERROR_SUCCESS) || (size == 1))
+ {
+ free(*outptr);
+ *outptr = NULL;
+ return 0;
+ }
+
+ /* Null terminate buffer allways */
+ *(*outptr + size) = '\0';
+
+ return 1;
+}
+
+/*
+ * get_enum_REG_SZ()
+ *
+ * Given a 'hKeyParent' handle to an open registry key and a 'leafKeyName'
+ * pointer to the name of the registry leaf key to be queried, parent key
+ * is enumerated searching in child keys for given leaf key name and its
+ * associated string value. When located, this returns a pointer in *outptr
+ * to a newly allocated memory area holding it as a null-terminated string.
+ *
+ * Returns 0 and nullifies *outptr upon inability to return a string value.
+ *
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
+ *
+ * Supported on Windows NT 3.5 and newer.
+ */
+static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName,
+ char **outptr)
+{
+ char enumKeyName[256];
+ DWORD enumKeyNameBuffSize;
+ DWORD enumKeyIdx = 0;
+ HKEY hKeyEnum;
+ int gotString;
+ int res;
+
+ *outptr = NULL;
+
+ for(;;)
+ {
+ enumKeyNameBuffSize = sizeof(enumKeyName);
+ res = RegEnumKeyEx(hKeyParent, enumKeyIdx++, enumKeyName,
+ &enumKeyNameBuffSize, 0, NULL, NULL, NULL);
+ if (res != ERROR_SUCCESS)
+ break;
+ res = RegOpenKeyEx(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE,
+ &hKeyEnum);
+ if (res != ERROR_SUCCESS)
+ continue;
+ gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr);
+ RegCloseKey(hKeyEnum);
+ if (gotString)
+ break;
+ }
+
+ if (!*outptr)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * get_DNS_Registry_9X()
+ *
+ * Functionally identical to get_DNS_Registry()
+ *
+ * Implementation supports Windows 95, 98 and ME.
+ */
+static int get_DNS_Registry_9X(char **outptr)
+{
+ HKEY hKey_VxD_MStcp;
+ int gotString;
+ int res;
+
+ *outptr = NULL;
+
+ res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ,
+ &hKey_VxD_MStcp);
+ if (res != ERROR_SUCCESS)
+ return 0;
+
+ gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr);
+ RegCloseKey(hKey_VxD_MStcp);
+
+ if (!gotString || !*outptr)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * get_DNS_Registry_NT()
+ *
+ * Functionally identical to get_DNS_Registry()
+ *
+ * Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
+ *
+ * Implementation supports Windows NT 3.5 and newer.
+ */
+static int get_DNS_Registry_NT(char **outptr)
+{
+ HKEY hKey_Interfaces = NULL;
+ HKEY hKey_Tcpip_Parameters;
+ int gotString;
+ int res;
+
+ *outptr = NULL;
+
+ res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
+ &hKey_Tcpip_Parameters);
+ if (res != ERROR_SUCCESS)
+ return 0;
+
+ /*
+ ** Global DNS settings override adapter specific parameters when both
+ ** are set. Additionally static DNS settings override DHCP-configured
+ ** parameters when both are set.
+ */
+
+ /* Global DNS static parameters */
+ gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr);
+ if (gotString)
+ goto done;
+
+ /* Global DNS DHCP-configured parameters */
+ gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr);
+ if (gotString)
+ goto done;
+
+ /* Try adapter specific parameters */
+ res = RegOpenKeyEx(hKey_Tcpip_Parameters, "Interfaces", 0,
+ KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
+ &hKey_Interfaces);
+ if (res != ERROR_SUCCESS)
+ {
+ hKey_Interfaces = NULL;
+ goto done;
+ }
+
+ /* Adapter specific DNS static parameters */
+ gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr);
+ if (gotString)
+ goto done;
+
+ /* Adapter specific DNS DHCP-configured parameters */
+ gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr);
+
+done:
+ if (hKey_Interfaces)
+ RegCloseKey(hKey_Interfaces);
+
+ RegCloseKey(hKey_Tcpip_Parameters);
+
+ if (!gotString || !*outptr)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * get_DNS_Registry()
+ *
+ * Locates DNS info in the registry. When located, this returns a pointer
+ * in *outptr to a newly allocated memory area holding a null-terminated
+ * string with a space or comma seperated list of DNS IP addresses.
+ *
+ * Returns 0 and nullifies *outptr upon inability to return DNSes string.
+ *
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
+ */
+static int get_DNS_Registry(char **outptr)
+{
+ win_platform platform;
+ int gotString = 0;
+
+ *outptr = NULL;
+
+ platform = ares__getplatform();
+
+ if (platform == WIN_NT)
+ gotString = get_DNS_Registry_NT(outptr);
+ else if (platform == WIN_9X)
+ gotString = get_DNS_Registry_9X(outptr);
+
+ if (!gotString)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * commajoin()
+ *
+ * RTF code.
+ */
+static void commajoin(char **dst, const char *src)
+{
+ char *tmp;
+
+ if (*dst)
+ {
+ tmp = malloc(strlen(*dst) + strlen(src) + 2);
+ if (!tmp)
+ return;
+ sprintf(tmp, "%s,%s", *dst, src);
+ free(*dst);
+ *dst = tmp;
+ }
+ else
+ {
+ *dst = malloc(strlen(src) + 1);
+ if (!*dst)
+ return;
+ strcpy(*dst, src);
+ }
+}
+
+/*
+ * get_DNS_NetworkParams()
+ *
+ * Locates DNS info using GetNetworkParams() function from the Internet
+ * Protocol Helper (IP Helper) API. When located, this returns a pointer
+ * in *outptr to a newly allocated memory area holding a null-terminated
+ * string with a space or comma seperated list of DNS IP addresses.
+ *
+ * Returns 0 and nullifies *outptr upon inability to return DNSes string.
+ *
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
+ *
+ * Implementation supports Windows 98 and newer.
+ *
+ * Note: Ancient PSDK required in order to build a W98 target.
+ */
+static int get_DNS_NetworkParams(char **outptr)
+{
+ FIXED_INFO *fi, *newfi;
+ struct ares_addr namesrvr;
+ char *txtaddr;
+ IP_ADDR_STRING *ipAddr;
+ int res;
+ DWORD size = sizeof (*fi);
+
+ *outptr = NULL;
+
+ /* Verify run-time availability of GetNetworkParams() */
+ if (ares_fpGetNetworkParams == ZERO_NULL)
+ return 0;
+
+ fi = malloc(size);
+ if (!fi)
+ return 0;
+
+ res = (*ares_fpGetNetworkParams) (fi, &size);
+ if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
+ goto done;
+
+ newfi = realloc(fi, size);
+ if (!newfi)
+ goto done;
+
+ fi = newfi;
+ res = (*ares_fpGetNetworkParams) (fi, &size);
+ if (res != ERROR_SUCCESS)
+ goto done;
+
+ for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
+ {
+ txtaddr = &ipAddr->IpAddress.String[0];
+
+ /* Validate converting textual address to binary format. */
+ if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
+ {
+ if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
+ (namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
+ continue;
+ }
+ else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
+ {
+ if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
+ sizeof(namesrvr.addrV6)) == 0)
+ continue;
+ }
+ else
+ continue;
+
+ commajoin(outptr, txtaddr);
+
+ if (!*outptr)
+ break;
+ }
+
+done:
+ if (fi)
+ free(fi);
+
+ if (!*outptr)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * get_DNS_AdaptersAddresses()
+ *
+ * Locates DNS info using GetAdaptersAddresses() function from the Internet
+ * Protocol Helper (IP Helper) API. When located, this returns a pointer
+ * in *outptr to a newly allocated memory area holding a null-terminated
+ * string with a space or comma seperated list of DNS IP addresses.
+ *
+ * Returns 0 and nullifies *outptr upon inability to return DNSes string.
+ *
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
+ *
+ * Implementation supports Windows XP and newer.
+ */
+#define IPAA_INITIAL_BUF_SZ 15 * 1024
+#define IPAA_MAX_TRIES 3
+static int get_DNS_AdaptersAddresses(char **outptr)
+{
+ IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
+ IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
+ ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ;
+ ULONG Bufsz = IPAA_INITIAL_BUF_SZ;
+ ULONG AddrFlags = 0;
+ int trying = IPAA_MAX_TRIES;
+ int res;
+
+ union {
+ struct sockaddr *sa;
+ struct sockaddr_in *sa4;
+ struct sockaddr_in6 *sa6;
+ } namesrvr;
+
+ char txtaddr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+
+ *outptr = NULL;
+
+ /* Verify run-time availability of GetAdaptersAddresses() */
+ if (ares_fpGetAdaptersAddresses == ZERO_NULL)
+ return 0;
+
+ ipaa = malloc(Bufsz);
+ if (!ipaa)
+ return 0;
+
+ /* Usually this call suceeds with initial buffer size */
+ res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
+ ipaa, &ReqBufsz);
+ if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
+ goto done;
+
+ while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
+ {
+ if (Bufsz < ReqBufsz)
+ {
+ newipaa = realloc(ipaa, ReqBufsz);
+ if (!newipaa)
+ goto done;
+ Bufsz = ReqBufsz;
+ ipaa = newipaa;
+ }
+ res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
+ ipaa, &ReqBufsz);
+ if (res == ERROR_SUCCESS)
+ break;
+ }
+ if (res != ERROR_SUCCESS)
+ goto done;
+
+ for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
+ {
+ for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
+ ipaDNSAddr;
+ ipaDNSAddr = ipaDNSAddr->Next)
+ {
+ namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
+
+ if (namesrvr.sa->sa_family == AF_INET)
+ {
+ if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
+ (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
+ continue;
+ if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
+ txtaddr, sizeof(txtaddr)))
+ continue;
+ }
+ else if (namesrvr.sa->sa_family == AF_INET6)
+ {
+ /* Windows apparently always reports some IPv6 DNS servers that
+ * prefixed with fec0:0:0:ffff. These ususally do not point to
+ * working DNS servers, so we ignore them. */
+ if (strncmp(txtaddr, "fec0:0:0:ffff:", 14) == 0)
+ continue;
+ if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
+ sizeof(namesrvr.sa6->sin6_addr)) == 0)
+ continue;
+ if (! ares_inet_ntop(AF_INET, &namesrvr.sa6->sin6_addr,
+ txtaddr, sizeof(txtaddr)))
+ continue;
+ }
+ else
+ continue;
+
+ commajoin(outptr, txtaddr);
+
+ if (!*outptr)
+ goto done;
+ }
+ }
+
+done:
+ if (ipaa)
+ free(ipaa);
+
+ if (!*outptr)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * get_DNS_Windows()
+ *
+ * Locates DNS info from Windows employing most suitable methods available at
+ * run-time no matter which Windows version it is. When located, this returns
+ * a pointer in *outptr to a newly allocated memory area holding a string with
+ * a space or comma seperated list of DNS IP addresses, null-terminated.
+ *
+ * Returns 0 and nullifies *outptr upon inability to return DNSes string.
+ *
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
+ *
+ * Implementation supports Windows 95 and newer.
+ */
+static int get_DNS_Windows(char **outptr)
+{
+ /* Try using IP helper API GetAdaptersAddresses() */
+ if (get_DNS_AdaptersAddresses(outptr))
+ return 1;
+
+ /* Try using IP helper API GetNetworkParams() */
+ if (get_DNS_NetworkParams(outptr))
+ return 1;
+
+ /* Fall-back to registry information */
+ return get_DNS_Registry(outptr);
+}
+#endif
+
+static int init_by_resolv_conf(ares_channel channel)
+{
+#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32)
+ char *line = NULL;
+#endif
+ int status = -1, nservers = 0, nsort = 0;
+ struct server_state *servers = NULL;
+ struct apattern *sortlist = NULL;
+
+#ifdef WIN32
+
+ if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
+ return ARES_SUCCESS;
+
+ if (get_DNS_Windows(&line))
+ {
+ status = config_nameserver(&servers, &nservers, line);
+ free(line);
+ }
+
+ if (status == ARES_SUCCESS)
+ status = ARES_EOF;
+ else
+ /* Catch the case when all the above checks fail (which happens when there
+ is no network card or the cable is unplugged) */
+ status = ARES_EFILE;
+
+#elif defined(__riscos__)
+
+ /* Under RISC OS, name servers are listed in the
+ system variable Inet$Resolvers, space separated. */
+
+ line = getenv("Inet$Resolvers");
+ status = ARES_EOF;
+ if (line) {
+ char *resolvers = strdup(line), *pos, *space;
+
+ if (!resolvers)
+ return ARES_ENOMEM;
+
+ pos = resolvers;
+ do {
+ space = strchr(pos, ' ');
+ if (space)
+ *space = '\0';
+ status = config_nameserver(&servers, &nservers, pos);
+ if (status != ARES_SUCCESS)
+ break;
+ pos = space + 1;
+ } while (space);
+
+ if (status == ARES_SUCCESS)
+ status = ARES_EOF;
+
+ free(resolvers);
+ }
+
+#elif defined(WATT32)
+ int i;
+
+ sock_init();
+ for (i = 0; def_nameservers[i]; i++)
+ ;
+ if (i == 0)
+ return ARES_SUCCESS; /* use localhost DNS server */
+
+ nservers = i;
+ servers = calloc(i, sizeof(struct server_state));
+ if (!servers)
+ return ARES_ENOMEM;
+
+ for (i = 0; def_nameservers[i]; i++)
+ {
+ servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
+ servers[i].addr.family = AF_INET;
+ }
+ status = ARES_EOF;
+
+#elif defined(ANDROID) || defined(__ANDROID__)
+ unsigned int i;
+ char propname[PROP_NAME_MAX];
+ char propvalue[PROP_VALUE_MAX]="";
+
+ for (i = 1; i <= MAX_DNS_PROPERTIES; i++) {
+ snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i);
+ if (__system_property_get(propname, propvalue) < 1) {
+ status = ARES_EOF;
+ break;
+ }
+ status = config_nameserver(&servers, &nservers, propvalue);
+ if (status != ARES_SUCCESS)
+ break;
+ status = ARES_EOF;
+ }
+#else
+ {
+ char *p;
+ FILE *fp;
+ size_t linesize;
+ int error;
+
+ /* Don't read resolv.conf and friends if we don't have to */
+ if (ARES_CONFIG_CHECK(channel))
+ return ARES_SUCCESS;
+
+ fp = fopen(PATH_RESOLV_CONF, "r");
+ if (fp) {
+ while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
+ {
+ if ((p = try_config(line, "domain", ';')))
+ status = config_domain(channel, p);
+ else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
+ status = config_lookup(channel, p, "bind", "file");
+ else if ((p = try_config(line, "search", ';')))
+ status = set_search(channel, p);
+ else if ((p = try_config(line, "nameserver", ';')) &&
+ channel->nservers == -1)
+ status = config_nameserver(&servers, &nservers, p);
+ else if ((p = try_config(line, "sortlist", ';')) &&
+ channel->nsort == -1)
+ status = config_sortlist(&sortlist, &nsort, p);
+ else if ((p = try_config(line, "options", ';')))
+ status = set_options(channel, p);
+ else
+ status = ARES_SUCCESS;
+ if (status != ARES_SUCCESS)
+ break;
+ }
+ fclose(fp);
+ }
+ else {
+ error = ERRNO;
+ switch(error) {
+ case ENOENT:
+ case ESRCH:
+ status = ARES_EOF;
+ break;
+ default:
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+ error, strerror(error)));
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
+ status = ARES_EFILE;
+ }
+ }
+
+ if ((status == ARES_EOF) && (!channel->lookups)) {
+ /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
+ fp = fopen("/etc/nsswitch.conf", "r");
+ if (fp) {
+ while ((status = ares__read_line(fp, &line, &linesize)) ==
+ ARES_SUCCESS)
+ {
+ if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
+ /* ignore errors */
+ (void)config_lookup(channel, p, "dns", "files");
+ }
+ fclose(fp);
+ }
+ else {
+ error = ERRNO;
+ switch(error) {
+ case ENOENT:
+ case ESRCH:
+ status = ARES_EOF;
+ break;
+ default:
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+ error, strerror(error)));
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n",
+ "/etc/nsswitch.conf"));
+ status = ARES_EFILE;
+ }
+ }
+ }
+
+ if ((status == ARES_EOF) && (!channel->lookups)) {
+ /* Linux / GNU libc 2.x and possibly others have host.conf */
+ fp = fopen("/etc/host.conf", "r");
+ if (fp) {
+ while ((status = ares__read_line(fp, &line, &linesize)) ==
+ ARES_SUCCESS)
+ {
+ if ((p = try_config(line, "order", '\0')) && !channel->lookups)
+ /* ignore errors */
+ (void)config_lookup(channel, p, "bind", "hosts");
+ }
+ fclose(fp);
+ }
+ else {
+ error = ERRNO;
+ switch(error) {
+ case ENOENT:
+ case ESRCH:
+ status = ARES_EOF;
+ break;
+ default:
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+ error, strerror(error)));
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n",
+ "/etc/host.conf"));
+ status = ARES_EFILE;
+ }
+ }
+ }
+
+ if ((status == ARES_EOF) && (!channel->lookups)) {
+ /* Tru64 uses /etc/svc.conf */
+ fp = fopen("/etc/svc.conf", "r");
+ if (fp) {
+ while ((status = ares__read_line(fp, &line, &linesize)) ==
+ ARES_SUCCESS)
+ {
+ if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
+ /* ignore errors */
+ (void)config_lookup(channel, p, "bind", "local");
+ }
+ fclose(fp);
+ }
+ else {
+ error = ERRNO;
+ switch(error) {
+ case ENOENT:
+ case ESRCH:
+ status = ARES_EOF;
+ break;
+ default:
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+ error, strerror(error)));
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
+ status = ARES_EFILE;
+ }
+ }
+ }
+
+ if(line)
+ free(line);
+ }
+
+#endif
+
+ /* Handle errors. */
+ if (status != ARES_EOF)
+ {
+ if (servers != NULL)
+ free(servers);
+ if (sortlist != NULL)
+ free(sortlist);
+ return status;
+ }
+
+ /* If we got any name server entries, fill them in. */
+ if (servers)
+ {
+ channel->servers = servers;
+ channel->nservers = nservers;
+ }
+
+ /* If we got any sortlist entries, fill them in. */
+ if (sortlist)
+ {
+ channel->sortlist = sortlist;
+ channel->nsort = nsort;
+ }
+
+ return ARES_SUCCESS;
+}
+
+static int init_by_defaults(ares_channel channel)
+{
+ char *hostname = NULL;
+ int rc = ARES_SUCCESS;
+#ifdef HAVE_GETHOSTNAME
+ char *dot;
+#endif
+
+ if (channel->flags == -1)
+ channel->flags = 0;
+ if (channel->timeout == -1)
+ channel->timeout = DEFAULT_TIMEOUT;
+ if (channel->tries == -1)
+ channel->tries = DEFAULT_TRIES;
+ if (channel->ndots == -1)
+ channel->ndots = 1;
+ if (channel->rotate == -1)
+ channel->rotate = 0;
+ if (channel->udp_port == -1)
+ channel->udp_port = htons(NAMESERVER_PORT);
+ if (channel->tcp_port == -1)
+ channel->tcp_port = htons(NAMESERVER_PORT);
+
+ if (channel->nservers == -1) {
+ /* If nobody specified servers, try a local named. */
+ channel->servers = malloc(sizeof(struct server_state));
+ if (!channel->servers) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+ channel->servers[0].addr.family = AF_INET;
+ channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
+ channel->nservers = 1;
+ }
+
+#if defined(USE_WINSOCK)
+#define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
+#elif defined(ENAMETOOLONG)
+#define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
+ (SOCKERRNO == EINVAL))
+#else
+#define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
+#endif
+
+ if (channel->ndomains == -1) {
+ /* Derive a default domain search list from the kernel hostname,
+ * or set it to empty if the hostname isn't helpful.
+ */
+#ifndef HAVE_GETHOSTNAME
+ channel->ndomains = 0; /* default to none */
+#else
+ GETHOSTNAME_TYPE_ARG2 lenv = 64;
+ size_t len = 64;
+ int res;
+ channel->ndomains = 0; /* default to none */
+
+ hostname = malloc(len);
+ if(!hostname) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+
+ do {
+ res = gethostname(hostname, lenv);
+
+ if(toolong(res)) {
+ char *p;
+ len *= 2;
+ lenv *= 2;
+ p = realloc(hostname, len);
+ if(!p) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+ hostname = p;
+ continue;
+ }
+ else if(res) {
+ rc = ARES_EBADNAME;
+ goto error;
+ }
+
+ } WHILE_FALSE;
+
+ dot = strchr(hostname, '.');
+ if (dot) {
+ /* a dot was found */
+ channel->domains = malloc(sizeof(char *));
+ if (!channel->domains) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+ channel->domains[0] = strdup(dot + 1);
+ if (!channel->domains[0]) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+ channel->ndomains = 1;
+ }
+#endif
+ }
+
+ if (channel->nsort == -1) {
+ channel->sortlist = NULL;
+ channel->nsort = 0;
+ }
+
+ if (!channel->lookups) {
+ channel->lookups = strdup("fb");
+ if (!channel->lookups)
+ rc = ARES_ENOMEM;
+ }
+
+ error:
+ if(rc) {
+ if(channel->servers) {
+ free(channel->servers);
+ channel->servers = NULL;
+ }
+
+ if(channel->domains && channel->domains[0])
+ free(channel->domains[0]);
+ if(channel->domains) {
+ free(channel->domains);
+ channel->domains = NULL;
+ }
+
+ if(channel->lookups) {
+ free(channel->lookups);
+ channel->lookups = NULL;
+ }
+ }
+
+ if(hostname)
+ free(hostname);
+
+ return rc;
+}
+
+#if !defined(WIN32) && !defined(WATT32) && \
+ !defined(ANDROID) && !defined(__ANDROID__)
+static int config_domain(ares_channel channel, char *str)
+{
+ char *q;
+
+ /* Set a single search domain. */
+ q = str;
+ while (*q && !ISSPACE(*q))
+ q++;
+ *q = '\0';
+ return set_search(channel, str);
+}
+
+#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
+ defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
+ /* workaround icc 9.1 optimizer issue */
+# define vqualifier volatile
+#else
+# define vqualifier
+#endif
+
+static int config_lookup(ares_channel channel, const char *str,
+ const char *bindch, const char *filech)
+{
+ char lookups[3], *l;
+ const char *vqualifier p;
+
+ /* Set the lookup order. Only the first letter of each work
+ * is relevant, and it has to be "b" for DNS or "f" for the
+ * host file. Ignore everything else.
+ */
+ l = lookups;
+ p = str;
+ while (*p)
+ {
+ if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
+ if (*p == *bindch) *l++ = 'b';
+ else *l++ = 'f';
+ }
+ while (*p && !ISSPACE(*p) && (*p != ','))
+ p++;
+ while (*p && (ISSPACE(*p) || (*p == ',')))
+ p++;
+ }
+ *l = '\0';
+ channel->lookups = strdup(lookups);
+ return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
+}
+#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
+
+#ifndef WATT32
+static int config_nameserver(struct server_state **servers, int *nservers,
+ char *str)
+{
+ struct ares_addr host;
+ struct server_state *newserv;
+ char *p, *txtaddr;
+ /* On Windows, there may be more than one nameserver specified in the same
+ * registry key, so we parse input as a space or comma seperated list.
+ */
+ for (p = str; p;)
+ {
+ /* Skip whitespace and commas. */
+ while (*p && (ISSPACE(*p) || (*p == ',')))
+ p++;
+ if (!*p)
+ /* No more input, done. */
+ break;
+
+ /* Pointer to start of IPv4 or IPv6 address part. */
+ txtaddr = p;
+
+ /* Advance past this address. */
+ while (*p && !ISSPACE(*p) && (*p != ','))
+ p++;
+ if (*p)
+ /* Null terminate this address. */
+ *p++ = '\0';
+ else
+ /* Reached end of input, done when this address is processed. */
+ p = NULL;
+
+ /* Convert textual address to binary format. */
+ if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
+ host.family = AF_INET;
+ else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
+ host.family = AF_INET6;
+ else
+ continue;
+
+ /* Resize servers state array. */
+ newserv = realloc(*servers, (*nservers + 1) *
+ sizeof(struct server_state));
+ if (!newserv)
+ return ARES_ENOMEM;
+
+ /* Store address data. */
+ newserv[*nservers].addr.family = host.family;
+ if (host.family == AF_INET)
+ memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
+ sizeof(host.addrV4));
+ else
+ memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
+ sizeof(host.addrV6));
+
+ /* Update arguments. */
+ *servers = newserv;
+ *nservers += 1;
+ }
+
+ return ARES_SUCCESS;
+}
+
+#if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__)
+static int config_sortlist(struct apattern **sortlist, int *nsort,
+ const char *str)
+{
+ struct apattern pat;
+ const char *q;
+
+ /* Add sortlist entries. */
+ while (*str && *str != ';')
+ {
+ int bits;
+ char ipbuf[16], ipbufpfx[32];
+ /* Find just the IP */
+ q = str;
+ while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
+ q++;
+ memcpy(ipbuf, str, q-str);
+ ipbuf[q-str] = '\0';
+ /* Find the prefix */
+ if (*q == '/')
+ {
+ const char *str2 = q+1;
+ while (*q && *q != ';' && !ISSPACE(*q))
+ q++;
+ memcpy(ipbufpfx, str, q-str);
+ ipbufpfx[q-str] = '\0';
+ str = str2;
+ }
+ else
+ ipbufpfx[0] = '\0';
+ /* Lets see if it is CIDR */
+ /* First we'll try IPv6 */
+ if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
+ &pat.addrV6,
+ sizeof(pat.addrV6))) > 0)
+ {
+ pat.type = PATTERN_CIDR;
+ pat.mask.bits = (unsigned short)bits;
+ pat.family = AF_INET6;
+ if (!sortlist_alloc(sortlist, nsort, &pat))
+ return ARES_ENOMEM;
+ }
+ else if (ipbufpfx[0] &&
+ (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
+ sizeof(pat.addrV4))) > 0)
+ {
+ pat.type = PATTERN_CIDR;
+ pat.mask.bits = (unsigned short)bits;
+ pat.family = AF_INET;
+ if (!sortlist_alloc(sortlist, nsort, &pat))
+ return ARES_ENOMEM;
+ }
+ /* See if it is just a regular IP */
+ else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
+ {
+ if (ipbufpfx[0])
+ {
+ memcpy(ipbuf, str, q-str);
+ ipbuf[q-str] = '\0';
+ if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
+ natural_mask(&pat);
+ }
+ else
+ natural_mask(&pat);
+ pat.family = AF_INET;
+ pat.type = PATTERN_MASK;
+ if (!sortlist_alloc(sortlist, nsort, &pat))
+ return ARES_ENOMEM;
+ }
+ else
+ {
+ while (*q && *q != ';' && !ISSPACE(*q))
+ q++;
+ }
+ str = q;
+ while (ISSPACE(*str))
+ str++;
+ }
+
+ return ARES_SUCCESS;
+}
+#endif /* !WIN32 & !ANDROID & !__ANDROID__ */
+#endif /* !WATT32 */
+
+static int set_search(ares_channel channel, const char *str)
+{
+ int n;
+ const char *p, *q;
+
+ if(channel->ndomains != -1) {
+ /* if we already have some domains present, free them first */
+ for(n=0; n < channel->ndomains; n++)
+ free(channel->domains[n]);
+ free(channel->domains);
+ channel->domains = NULL;
+ channel->ndomains = -1;
+ }
+
+ /* Count the domains given. */
+ n = 0;
+ p = str;
+ while (*p)
+ {
+ while (*p && !ISSPACE(*p))
+ p++;
+ while (ISSPACE(*p))
+ p++;
+ n++;
+ }
+
+ if (!n)
+ {
+ channel->ndomains = 0;
+ return ARES_SUCCESS;
+ }
+
+ channel->domains = malloc(n * sizeof(char *));
+ if (!channel->domains)
+ return ARES_ENOMEM;
+
+ /* Now copy the domains. */
+ n = 0;
+ p = str;
+ while (*p)
+ {
+ channel->ndomains = n;
+ q = p;
+ while (*q && !ISSPACE(*q))
+ q++;
+ channel->domains[n] = malloc(q - p + 1);
+ if (!channel->domains[n])
+ return ARES_ENOMEM;
+ memcpy(channel->domains[n], p, q - p);
+ channel->domains[n][q - p] = 0;
+ p = q;
+ while (ISSPACE(*p))
+ p++;
+ n++;
+ }
+ channel->ndomains = n;
+
+ return ARES_SUCCESS;
+}
+
+static int set_options(ares_channel channel, const char *str)
+{
+ const char *p, *q, *val;
+
+ p = str;
+ while (*p)
+ {
+ q = p;
+ while (*q && !ISSPACE(*q))
+ q++;
+ val = try_option(p, q, "ndots:");
+ if (val && channel->ndots == -1)
+ channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
+ val = try_option(p, q, "retrans:");
+ if (val && channel->timeout == -1)
+ channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
+ val = try_option(p, q, "retry:");
+ if (val && channel->tries == -1)
+ channel->tries = aresx_sltosi(strtol(val, NULL, 10));
+ val = try_option(p, q, "rotate");
+ if (val && channel->rotate == -1)
+ channel->rotate = 1;
+ p = q;
+ while (ISSPACE(*p))
+ p++;
+ }
+
+ return ARES_SUCCESS;
+}
+
+static const char *try_option(const char *p, const char *q, const char *opt)
+{
+ size_t len = strlen(opt);
+ return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
+}
+
+#if !defined(WIN32) && !defined(WATT32) && \
+ !defined(ANDROID) && !defined(__ANDROID__)
+static char *try_config(char *s, const char *opt, char scc)
+{
+ size_t len;
+ char *p;
+ char *q;
+
+ if (!s || !opt)
+ /* no line or no option */
+ return NULL;
+
+ /* Hash '#' character is always used as primary comment char, additionally
+ a not-NUL secondary comment char will be considered when specified. */
+
+ /* trim line comment */
+ p = s;
+ if(scc)
+ while (*p && (*p != '#') && (*p != scc))
+ p++;
+ else
+ while (*p && (*p != '#'))
+ p++;
+ *p = '\0';
+
+ /* trim trailing whitespace */
+ q = p - 1;
+ while ((q >= s) && ISSPACE(*q))
+ q--;
+ *++q = '\0';
+
+ /* skip leading whitespace */
+ p = s;
+ while (*p && ISSPACE(*p))
+ p++;
+
+ if (!*p)
+ /* empty line */
+ return NULL;
+
+ if ((len = strlen(opt)) == 0)
+ /* empty option */
+ return NULL;
+
+ if (strncmp(p, opt, len) != 0)
+ /* line and option do not match */
+ return NULL;
+
+ /* skip over given option name */
+ p += len;
+
+ if (!*p)
+ /* no option value */
+ return NULL;
+
+ if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
+ /* whitespace between option name and value is mandatory
+ for given option names which do not end with ':' or '=' */
+ return NULL;
+
+ /* skip over whitespace */
+ while (*p && ISSPACE(*p))
+ p++;
+
+ if (!*p)
+ /* no option value */
+ return NULL;
+
+ /* return pointer to option value */
+ return p;
+}
+
+static int sortlist_alloc(struct apattern **sortlist, int *nsort,
+ struct apattern *pat)
+{
+ struct apattern *newsort;
+ newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
+ if (!newsort)
+ return 0;
+ newsort[*nsort] = *pat;
+ *sortlist = newsort;
+ (*nsort)++;
+ return 1;
+}
+
+static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
+{
+
+ /* Four octets and three periods yields at most 15 characters. */
+ if (len > 15)
+ return -1;
+
+ addr->s_addr = inet_addr(ipbuf);
+ if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
+ return -1;
+ return 0;
+}
+
+static void natural_mask(struct apattern *pat)
+{
+ struct in_addr addr;
+
+ /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
+ * but portable.
+ */
+ addr.s_addr = ntohl(pat->addrV4.s_addr);
+
+ /* This is out of date in the CIDR world, but some people might
+ * still rely on it.
+ */
+ if (IN_CLASSA(addr.s_addr))
+ pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
+ else if (IN_CLASSB(addr.s_addr))
+ pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
+ else
+ pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
+}
+#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
+
+/* initialize an rc4 key. If possible a cryptographically secure random key
+ is generated using a suitable function (for example win32's RtlGenRandom as
+ described in
+ http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
+ otherwise the code defaults to cross-platform albeit less secure mechanism
+ using rand
+*/
+static void randomize_key(unsigned char* key,int key_data_len)
+{
+ int randomized = 0;
+ int counter=0;
+#ifdef WIN32
+ BOOLEAN res;
+ if (ares_fpSystemFunction036)
+ {
+ res = (*ares_fpSystemFunction036) (key, key_data_len);
+ if (res)
+ randomized = 1;
+ }
+#else /* !WIN32 */
+#ifdef RANDOM_FILE
+ FILE *f = fopen(RANDOM_FILE, "rb");
+ if(f) {
+ counter = aresx_uztosi(fread(key, 1, key_data_len, f));
+ fclose(f);
+ }
+#endif
+#endif /* WIN32 */
+
+ if (!randomized) {
+ for (;counter<key_data_len;counter++)
+ key[counter]=(unsigned char)(rand() % 256);
+ }
+}
+
+static int init_id_key(rc4_key* key,int key_data_len)
+{
+ unsigned char index1;
+ unsigned char index2;
+ unsigned char* state;
+ short counter;
+ unsigned char *key_data_ptr = 0;
+
+ key_data_ptr = calloc(1,key_data_len);
+ if (!key_data_ptr)
+ return ARES_ENOMEM;
+
+ state = &key->state[0];
+ for(counter = 0; counter < 256; counter++)
+ /* unnecessary AND but it keeps some compilers happier */
+ state[counter] = (unsigned char)(counter & 0xff);
+ randomize_key(key->state,key_data_len);
+ key->x = 0;
+ key->y = 0;
+ index1 = 0;
+ index2 = 0;
+ for(counter = 0; counter < 256; counter++)
+ {
+ index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
+ index2) % 256);
+ ARES_SWAP_BYTE(&state[counter], &state[index2]);
+
+ index1 = (unsigned char)((index1 + 1) % key_data_len);
+ }
+ free(key_data_ptr);
+ return ARES_SUCCESS;
+}
+
+unsigned short ares__generate_new_id(rc4_key* key)
+{
+ unsigned short r=0;
+ ares__rc4(key, (unsigned char *)&r, sizeof(r));
+ return r;
+}
+
+void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
+{
+ channel->local_ip4 = local_ip;
+}
+
+/* local_ip6 should be 16 bytes in length */
+void ares_set_local_ip6(ares_channel channel,
+ const unsigned char* local_ip6)
+{
+ memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
+}
+
+/* local_dev_name should be null terminated. */
+void ares_set_local_dev(ares_channel channel,
+ const char* local_dev_name)
+{
+ strncpy(channel->local_dev_name, local_dev_name,
+ sizeof(channel->local_dev_name));
+ channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
+}
+
+
+void ares_set_socket_callback(ares_channel channel,
+ ares_sock_create_callback cb,
+ void *data)
+{
+ channel->sock_create_cb = cb;
+ channel->sock_create_cb_data = data;
+}
+
+void ares__init_servers_state(ares_channel channel)
+{
+ struct server_state *server;
+ int i;
+
+ for (i = 0; i < channel->nservers; i++)
+ {
+ server = &channel->servers[i];
+ server->udp_socket = ARES_SOCKET_BAD;
+ server->tcp_socket = ARES_SOCKET_BAD;
+ server->tcp_connection_generation = ++channel->tcp_connection_generation;
+ server->tcp_lenbuf_pos = 0;
+ server->tcp_buffer_pos = 0;
+ server->tcp_buffer = NULL;
+ server->tcp_length = 0;
+ server->qhead = NULL;
+ server->qtail = NULL;
+ ares__init_list_head(&server->queries_to_server);
+ server->channel = channel;
+ server->is_broken = 0;
+ }
+}
diff --git a/deps/uv/src/ares/ares_iphlpapi.h b/deps/cares/src/ares_iphlpapi.h
index 343aee3ff..343aee3ff 100644
--- a/deps/uv/src/ares/ares_iphlpapi.h
+++ b/deps/cares/src/ares_iphlpapi.h
diff --git a/deps/uv/src/ares/ares_ipv6.h b/deps/cares/src/ares_ipv6.h
index 6f1022a76..6f1022a76 100644
--- a/deps/uv/src/ares/ares_ipv6.h
+++ b/deps/cares/src/ares_ipv6.h
diff --git a/deps/uv/src/ares/ares_library_init.c b/deps/cares/src/ares_library_init.c
index f0137a182..f0137a182 100644
--- a/deps/uv/src/ares/ares_library_init.c
+++ b/deps/cares/src/ares_library_init.c
diff --git a/deps/cares/src/ares_library_init.h b/deps/cares/src/ares_library_init.h
new file mode 100644
index 000000000..59e5cc589
--- /dev/null
+++ b/deps/cares/src/ares_library_init.h
@@ -0,0 +1,42 @@
+#ifndef HEADER_CARES_LIBRARY_INIT_H
+#define HEADER_CARES_LIBRARY_INIT_H
+
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2004-2011 by Daniel Stenberg
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef USE_WINSOCK
+
+#include <iphlpapi.h>
+#include <ares_iphlpapi.h>
+
+typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*);
+typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG);
+typedef ULONG (WINAPI *fpGetAdaptersAddresses_t) ( ULONG, ULONG, void*, IP_ADAPTER_ADDRESSES*, ULONG* );
+
+/* Forward-declaration of variables defined in ares_library_init.c */
+/* that are global and unique instances for whole c-ares library. */
+
+extern fpGetNetworkParams_t ares_fpGetNetworkParams;
+extern fpSystemFunction036_t ares_fpSystemFunction036;
+extern fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses;
+
+#endif /* USE_WINSOCK */
+
+#endif /* HEADER_CARES_LIBRARY_INIT_H */
+
diff --git a/deps/uv/src/ares/ares_llist.c b/deps/cares/src/ares_llist.c
index c0acd90a8..c0acd90a8 100644
--- a/deps/uv/src/ares/ares_llist.c
+++ b/deps/cares/src/ares_llist.c
diff --git a/deps/uv/src/ares/ares_llist.h b/deps/cares/src/ares_llist.h
index b09f0de6d..b09f0de6d 100644
--- a/deps/uv/src/ares/ares_llist.h
+++ b/deps/cares/src/ares_llist.h
diff --git a/deps/uv/src/ares/ares_mkquery.c b/deps/cares/src/ares_mkquery.c
index e33f13ff2..e33f13ff2 100644
--- a/deps/uv/src/ares/ares_mkquery.c
+++ b/deps/cares/src/ares_mkquery.c
diff --git a/deps/cares/src/ares_nowarn.c b/deps/cares/src/ares_nowarn.c
new file mode 100644
index 000000000..e29efd333
--- /dev/null
+++ b/deps/cares/src/ares_nowarn.c
@@ -0,0 +1,249 @@
+
+/* Copyright (C) 2010-2012 by Daniel Stenberg
+ *
+ * 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.
+ */
+
+
+#include "ares_setup.h"
+
+#ifdef HAVE_ASSERT_H
+# include <assert.h>
+#endif
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#endif /* __INTEL_COMPILER && __unix__ */
+
+#define BUILDING_ARES_NOWARN_C 1
+
+#include "ares_nowarn.h"
+
+#define CARES_MASK_USHORT (~(unsigned short) 0)
+#define CARES_MASK_UINT (~(unsigned int) 0)
+#define CARES_MASK_ULONG (~(unsigned long) 0)
+
+#define CARES_MASK_SSHORT (CARES_MASK_USHORT >> 1)
+#define CARES_MASK_SINT (CARES_MASK_UINT >> 1)
+#define CARES_MASK_SLONG (CARES_MASK_ULONG >> 1)
+
+/*
+** unsigned size_t to signed long
+*/
+
+long aresx_uztosl(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ return (long)(uznum & (size_t) CARES_MASK_SLONG);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed int
+*/
+
+int aresx_uztosi(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ return (int)(uznum & (size_t) CARES_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed short
+*/
+
+short aresx_uztoss(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ return (short)(uznum & (size_t) CARES_MASK_SSHORT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed int to signed short
+*/
+
+short aresx_sitoss(int sinum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(sinum >= 0);
+ return (short)(sinum & (int) CARES_MASK_SSHORT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed long to signed int
+*/
+
+int aresx_sltosi(long slnum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(slnum >= 0);
+ return (int)(slnum & (long) CARES_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed ssize_t to signed int
+*/
+
+int aresx_sztosi(ssize_t sznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(sznum >= 0);
+ return (int)(sznum & (ssize_t) CARES_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed ssize_t to unsigned int
+*/
+
+unsigned int aresx_sztoui(ssize_t sznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(sznum >= 0);
+ return (unsigned int)(sznum & (ssize_t) CARES_MASK_UINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed int to unsigned short
+*/
+
+unsigned short aresx_sitous(int sinum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(sinum >= 0);
+ return (unsigned short)(sinum & (int) CARES_MASK_USHORT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+int aresx_FD_ISSET(int fd, fd_set *fdset)
+{
+ #pragma warning(push)
+ #pragma warning(disable:1469) /* clobber ignored */
+ return FD_ISSET(fd, fdset);
+ #pragma warning(pop)
+}
+
+void aresx_FD_SET(int fd, fd_set *fdset)
+{
+ #pragma warning(push)
+ #pragma warning(disable:1469) /* clobber ignored */
+ FD_SET(fd, fdset);
+ #pragma warning(pop)
+}
+
+void aresx_FD_ZERO(fd_set *fdset)
+{
+ #pragma warning(push)
+ #pragma warning(disable:593) /* variable was set but never used */
+ FD_ZERO(fdset);
+ #pragma warning(pop)
+}
+
+unsigned short aresx_htons(unsigned short usnum)
+{
+#if (__INTEL_COMPILER == 910) && defined(__i386__)
+ return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
+#else
+ #pragma warning(push)
+ #pragma warning(disable:810) /* conversion may lose significant bits */
+ return htons(usnum);
+ #pragma warning(pop)
+#endif
+}
+
+unsigned short aresx_ntohs(unsigned short usnum)
+{
+#if (__INTEL_COMPILER == 910) && defined(__i386__)
+ return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
+#else
+ #pragma warning(push)
+ #pragma warning(disable:810) /* conversion may lose significant bits */
+ return ntohs(usnum);
+ #pragma warning(pop)
+#endif
+}
+
+#endif /* __INTEL_COMPILER && __unix__ */
diff --git a/deps/cares/src/ares_nowarn.h b/deps/cares/src/ares_nowarn.h
new file mode 100644
index 000000000..9b76d6632
--- /dev/null
+++ b/deps/cares/src/ares_nowarn.h
@@ -0,0 +1,61 @@
+#ifndef HEADER_CARES_NOWARN_H
+#define HEADER_CARES_NOWARN_H
+
+
+/* Copyright (C) 2010-2012 by Daniel Stenberg
+ *
+ * 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.
+ */
+
+long aresx_uztosl(size_t uznum);
+int aresx_uztosi(size_t uznum);
+short aresx_uztoss(size_t uznum);
+
+short aresx_sitoss(int sinum);
+
+int aresx_sltosi(long slnum);
+
+int aresx_sztosi(ssize_t sznum);
+
+unsigned int aresx_sztoui(ssize_t sznum);
+
+unsigned short aresx_sitous(int sinum);
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+int aresx_FD_ISSET(int fd, fd_set *fdset);
+
+void aresx_FD_SET(int fd, fd_set *fdset);
+
+void aresx_FD_ZERO(fd_set *fdset);
+
+unsigned short aresx_htons(unsigned short usnum);
+
+unsigned short aresx_ntohs(unsigned short usnum);
+
+#ifndef BUILDING_ARES_NOWARN_C
+# undef FD_ISSET
+# define FD_ISSET(a,b) aresx_FD_ISSET((a),(b))
+# undef FD_SET
+# define FD_SET(a,b) aresx_FD_SET((a),(b))
+# undef FD_ZERO
+# define FD_ZERO(a) aresx_FD_ZERO((a))
+# undef htons
+# define htons(a) aresx_htons((a))
+# undef ntohs
+# define ntohs(a) aresx_ntohs((a))
+#endif
+
+#endif /* __INTEL_COMPILER && __unix__ */
+
+#endif /* HEADER_CARES_NOWARN_H */
diff --git a/deps/uv/src/ares/ares_options.c b/deps/cares/src/ares_options.c
index 5174ef26e..5174ef26e 100644
--- a/deps/uv/src/ares/ares_options.c
+++ b/deps/cares/src/ares_options.c
diff --git a/deps/uv/src/ares/ares_parse_a_reply.c b/deps/cares/src/ares_parse_a_reply.c
index 4bd084588..4bd084588 100644
--- a/deps/uv/src/ares/ares_parse_a_reply.c
+++ b/deps/cares/src/ares_parse_a_reply.c
diff --git a/deps/cares/src/ares_parse_aaaa_reply.c b/deps/cares/src/ares_parse_aaaa_reply.c
new file mode 100644
index 000000000..b11df5249
--- /dev/null
+++ b/deps/cares/src/ares_parse_aaaa_reply.c
@@ -0,0 +1,261 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright 2005 Dominick Meglio
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "inet_net_pton.h"
+#include "ares_private.h"
+
+int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
+ struct hostent **host, struct ares_addr6ttl *addrttls,
+ int *naddrttls)
+{
+ unsigned int qdcount, ancount;
+ int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs;
+ int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */
+ int naliases;
+ long len;
+ const unsigned char *aptr;
+ char *hostname, *rr_name, *rr_data, **aliases;
+ struct ares_in6_addr *addrs;
+ struct hostent *hostent;
+ const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0;
+
+ /* Set *host to NULL for all failure cases. */
+ if (host)
+ *host = NULL;
+ /* Same with *naddrttls. */
+ if (naddrttls)
+ *naddrttls = 0;
+
+ /* Give up if abuf doesn't have room for a header. */
+ if (alen < HFIXEDSZ)
+ return ARES_EBADRESP;
+
+ /* Fetch the question and answer count from the header. */
+ qdcount = DNS_HEADER_QDCOUNT(abuf);
+ ancount = DNS_HEADER_ANCOUNT(abuf);
+ if (qdcount != 1)
+ return ARES_EBADRESP;
+
+ /* Expand the name from the question, and skip past the question. */
+ aptr = abuf + HFIXEDSZ;
+ status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len);
+ if (status != ARES_SUCCESS)
+ return status;
+ if (aptr + len + QFIXEDSZ > abuf + alen)
+ {
+ free(hostname);
+ return ARES_EBADRESP;
+ }
+ aptr += len + QFIXEDSZ;
+
+ /* Allocate addresses and aliases; ancount gives an upper bound for both. */
+ if (host)
+ {
+ addrs = malloc(ancount * sizeof(struct ares_in6_addr));
+ if (!addrs)
+ {
+ free(hostname);
+ return ARES_ENOMEM;
+ }
+ aliases = malloc((ancount + 1) * sizeof(char *));
+ if (!aliases)
+ {
+ free(hostname);
+ free(addrs);
+ return ARES_ENOMEM;
+ }
+ }
+ else
+ {
+ addrs = NULL;
+ aliases = NULL;
+ }
+ naddrs = 0;
+ naliases = 0;
+
+ /* Examine each answer resource record (RR) in turn. */
+ for (i = 0; i < (int)ancount; i++)
+ {
+ /* Decode the RR up to the data field. */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
+ if (status != ARES_SUCCESS)
+ break;
+ aptr += len;
+ if (aptr + RRFIXEDSZ > abuf + alen)
+ {
+ free(rr_name);
+ status = ARES_EBADRESP;
+ break;
+ }
+ rr_type = DNS_RR_TYPE(aptr);
+ rr_class = DNS_RR_CLASS(aptr);
+ rr_len = DNS_RR_LEN(aptr);
+ rr_ttl = DNS_RR_TTL(aptr);
+ aptr += RRFIXEDSZ;
+
+ if (rr_class == C_IN && rr_type == T_AAAA
+ && rr_len == sizeof(struct ares_in6_addr)
+ && strcasecmp(rr_name, hostname) == 0)
+ {
+ if (addrs)
+ {
+ if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
+ {
+ free(rr_name);
+ status = ARES_EBADRESP;
+ break;
+ }
+ memcpy(&addrs[naddrs], aptr, sizeof(struct ares_in6_addr));
+ }
+ if (naddrs < max_addr_ttls)
+ {
+ struct ares_addr6ttl * const at = &addrttls[naddrs];
+ if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
+ {
+ free(rr_name);
+ status = ARES_EBADRESP;
+ break;
+ }
+ memcpy(&at->ip6addr, aptr, sizeof(struct ares_in6_addr));
+ at->ttl = rr_ttl;
+ }
+ naddrs++;
+ status = ARES_SUCCESS;
+ }
+
+ if (rr_class == C_IN && rr_type == T_CNAME)
+ {
+ /* Record the RR name as an alias. */
+ if (aliases)
+ aliases[naliases] = rr_name;
+ else
+ free(rr_name);
+ naliases++;
+
+ /* Decode the RR data and replace the hostname with it. */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
+ &len);
+ if (status != ARES_SUCCESS)
+ break;
+ free(hostname);
+ hostname = rr_data;
+
+ /* Take the min of the TTLs we see in the CNAME chain. */
+ if (cname_ttl > rr_ttl)
+ cname_ttl = rr_ttl;
+ }
+ else
+ free(rr_name);
+
+ aptr += rr_len;
+ if (aptr > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+ }
+
+ /* the check for naliases to be zero is to make sure CNAME responses
+ don't get caught here */
+ if (status == ARES_SUCCESS && naddrs == 0 && naliases == 0)
+ status = ARES_ENODATA;
+ if (status == ARES_SUCCESS)
+ {
+ /* We got our answer. */
+ if (naddrttls)
+ {
+ const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls;
+ for (i = 0; i < n; i++)
+ {
+ /* Ensure that each A TTL is no larger than the CNAME TTL. */
+ if (addrttls[i].ttl > cname_ttl)
+ addrttls[i].ttl = cname_ttl;
+ }
+ *naddrttls = n;
+ }
+ if (aliases)
+ aliases[naliases] = NULL;
+ if (host)
+ {
+ /* Allocate memory to build the host entry. */
+ hostent = malloc(sizeof(struct hostent));
+ if (hostent)
+ {
+ hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *));
+ if (hostent->h_addr_list)
+ {
+ /* Fill in the hostent and return successfully. */
+ hostent->h_name = hostname;
+ hostent->h_aliases = aliases;
+ hostent->h_addrtype = AF_INET6;
+ hostent->h_length = sizeof(struct ares_in6_addr);
+ for (i = 0; i < naddrs; i++)
+ hostent->h_addr_list[i] = (char *) &addrs[i];
+ hostent->h_addr_list[naddrs] = NULL;
+ *host = hostent;
+ return ARES_SUCCESS;
+ }
+ free(hostent);
+ }
+ status = ARES_ENOMEM;
+ }
+ }
+ if (aliases)
+ {
+ for (i = 0; i < naliases; i++)
+ free(aliases[i]);
+ free(aliases);
+ }
+ free(addrs);
+ free(hostname);
+ return status;
+}
diff --git a/deps/uv/src/ares/ares_parse_mx_reply.c b/deps/cares/src/ares_parse_mx_reply.c
index 21800546b..21800546b 100644
--- a/deps/uv/src/ares/ares_parse_mx_reply.c
+++ b/deps/cares/src/ares_parse_mx_reply.c
diff --git a/deps/cares/src/ares_parse_naptr_reply.c b/deps/cares/src/ares_parse_naptr_reply.c
new file mode 100644
index 000000000..6a9d09ecb
--- /dev/null
+++ b/deps/cares/src/ares_parse_naptr_reply.c
@@ -0,0 +1,188 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2009 by Jakub Hrozek <jhrozek@redhat.com>
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_data.h"
+#include "ares_private.h"
+
+/* AIX portability check */
+#ifndef T_NAPTR
+ #define T_NAPTR 35 /* naming authority pointer */
+#endif
+
+int
+ares_parse_naptr_reply (const unsigned char *abuf, int alen,
+ struct ares_naptr_reply **naptr_out)
+{
+ unsigned int qdcount, ancount, i;
+ const unsigned char *aptr, *vptr;
+ int status, rr_type, rr_class, rr_len;
+ long len;
+ char *hostname = NULL, *rr_name = NULL;
+ struct ares_naptr_reply *naptr_head = NULL;
+ struct ares_naptr_reply *naptr_last = NULL;
+ struct ares_naptr_reply *naptr_curr;
+
+ /* Set *naptr_out to NULL for all failure cases. */
+ *naptr_out = NULL;
+
+ /* Give up if abuf doesn't have room for a header. */
+ if (alen < HFIXEDSZ)
+ return ARES_EBADRESP;
+
+ /* Fetch the question and answer count from the header. */
+ qdcount = DNS_HEADER_QDCOUNT (abuf);
+ ancount = DNS_HEADER_ANCOUNT (abuf);
+ if (qdcount != 1)
+ return ARES_EBADRESP;
+ if (ancount == 0)
+ return ARES_ENODATA;
+
+ /* Expand the name from the question, and skip past the question. */
+ aptr = abuf + HFIXEDSZ;
+ status = ares_expand_name (aptr, abuf, alen, &hostname, &len);
+ if (status != ARES_SUCCESS)
+ return status;
+
+ if (aptr + len + QFIXEDSZ > abuf + alen)
+ {
+ free (hostname);
+ return ARES_EBADRESP;
+ }
+ aptr += len + QFIXEDSZ;
+
+ /* Examine each answer resource record (RR) in turn. */
+ for (i = 0; i < ancount; i++)
+ {
+ /* Decode the RR up to the data field. */
+ status = ares_expand_name (aptr, abuf, alen, &rr_name, &len);
+ if (status != ARES_SUCCESS)
+ {
+ break;
+ }
+ aptr += len;
+ if (aptr + RRFIXEDSZ > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+ rr_type = DNS_RR_TYPE (aptr);
+ rr_class = DNS_RR_CLASS (aptr);
+ rr_len = DNS_RR_LEN (aptr);
+ aptr += RRFIXEDSZ;
+
+ /* Check if we are really looking at a NAPTR record */
+ if (rr_class == C_IN && rr_type == T_NAPTR)
+ {
+ /* parse the NAPTR record itself */
+
+ /* Allocate storage for this NAPTR answer appending it to the list */
+ naptr_curr = ares_malloc_data(ARES_DATATYPE_NAPTR_REPLY);
+ if (!naptr_curr)
+ {
+ status = ARES_ENOMEM;
+ break;
+ }
+ if (naptr_last)
+ {
+ naptr_last->next = naptr_curr;
+ }
+ else
+ {
+ naptr_head = naptr_curr;
+ }
+ naptr_last = naptr_curr;
+
+ vptr = aptr;
+ naptr_curr->order = DNS__16BIT(vptr);
+ vptr += sizeof(unsigned short);
+ naptr_curr->preference = DNS__16BIT(vptr);
+ vptr += sizeof(unsigned short);
+
+ status = ares_expand_string(vptr, abuf, alen, &naptr_curr->flags, &len);
+ if (status != ARES_SUCCESS)
+ break;
+ vptr += len;
+
+ status = ares_expand_string(vptr, abuf, alen, &naptr_curr->service, &len);
+ if (status != ARES_SUCCESS)
+ break;
+ vptr += len;
+
+ status = ares_expand_string(vptr, abuf, alen, &naptr_curr->regexp, &len);
+ if (status != ARES_SUCCESS)
+ break;
+ vptr += len;
+
+ status = ares_expand_name(vptr, abuf, alen, &naptr_curr->replacement, &len);
+ if (status != ARES_SUCCESS)
+ break;
+ }
+
+ /* Don't lose memory in the next iteration */
+ free (rr_name);
+ rr_name = NULL;
+
+ /* Move on to the next record */
+ aptr += rr_len;
+ }
+
+ if (hostname)
+ free (hostname);
+ if (rr_name)
+ free (rr_name);
+
+ /* clean up on error */
+ if (status != ARES_SUCCESS)
+ {
+ if (naptr_head)
+ ares_free_data (naptr_head);
+ return status;
+ }
+
+ /* everything looks fine, return the data */
+ *naptr_out = naptr_head;
+
+ return ARES_SUCCESS;
+}
+
diff --git a/deps/uv/src/ares/ares_parse_ns_reply.c b/deps/cares/src/ares_parse_ns_reply.c
index 5e9af71d1..5e9af71d1 100644
--- a/deps/uv/src/ares/ares_parse_ns_reply.c
+++ b/deps/cares/src/ares_parse_ns_reply.c
diff --git a/deps/cares/src/ares_parse_ptr_reply.c b/deps/cares/src/ares_parse_ptr_reply.c
new file mode 100644
index 000000000..ed4a405bc
--- /dev/null
+++ b/deps/cares/src/ares_parse_ptr_reply.c
@@ -0,0 +1,218 @@
+
+/* 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_nowarn.h"
+#include "ares_private.h"
+
+int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
+ int addrlen, int family, struct hostent **host)
+{
+ unsigned int qdcount, ancount;
+ int status, i, rr_type, rr_class, rr_len;
+ long len;
+ const unsigned char *aptr;
+ char *ptrname, *hostname, *rr_name, *rr_data;
+ struct hostent *hostent;
+ int aliascnt = 0;
+ int alias_alloc = 8;
+ char ** aliases;
+
+ /* Set *host to NULL for all failure cases. */
+ *host = NULL;
+
+ /* Give up if abuf doesn't have room for a header. */
+ if (alen < HFIXEDSZ)
+ return ARES_EBADRESP;
+
+ /* Fetch the question and answer count from the header. */
+ qdcount = DNS_HEADER_QDCOUNT(abuf);
+ ancount = DNS_HEADER_ANCOUNT(abuf);
+ if (qdcount != 1)
+ return ARES_EBADRESP;
+
+ /* Expand the name from the question, and skip past the question. */
+ aptr = abuf + HFIXEDSZ;
+ status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len);
+ if (status != ARES_SUCCESS)
+ return status;
+ if (aptr + len + QFIXEDSZ > abuf + alen)
+ {
+ free(ptrname);
+ return ARES_EBADRESP;
+ }
+ aptr += len + QFIXEDSZ;
+
+ /* Examine each answer resource record (RR) in turn. */
+ hostname = NULL;
+ aliases = malloc(alias_alloc * sizeof(char *));
+ if (!aliases)
+ {
+ free(ptrname);
+ return ARES_ENOMEM;
+ }
+ for (i = 0; i < (int)ancount; i++)
+ {
+ /* Decode the RR up to the data field. */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
+ if (status != ARES_SUCCESS)
+ break;
+ aptr += len;
+ if (aptr + RRFIXEDSZ > abuf + alen)
+ {
+ free(rr_name);
+ status = ARES_EBADRESP;
+ break;
+ }
+ rr_type = DNS_RR_TYPE(aptr);
+ rr_class = DNS_RR_CLASS(aptr);
+ rr_len = DNS_RR_LEN(aptr);
+ aptr += RRFIXEDSZ;
+
+ if (rr_class == C_IN && rr_type == T_PTR
+ && strcasecmp(rr_name, ptrname) == 0)
+ {
+ /* Decode the RR data and set hostname to it. */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
+ &len);
+ if (status != ARES_SUCCESS)
+ {
+ free(rr_name);
+ break;
+ }
+ if (hostname)
+ free(hostname);
+ hostname = rr_data;
+ aliases[aliascnt] = malloc((strlen(rr_data)+1) * sizeof(char));
+ if (!aliases[aliascnt])
+ {
+ free(rr_name);
+ status = ARES_ENOMEM;
+ break;
+ }
+ strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1);
+ aliascnt++;
+ if (aliascnt >= alias_alloc) {
+ char **ptr;
+ alias_alloc *= 2;
+ ptr = realloc(aliases, alias_alloc * sizeof(char *));
+ if(!ptr) {
+ free(rr_name);
+ status = ARES_ENOMEM;
+ break;
+ }
+ aliases = ptr;
+ }
+ }
+
+ if (rr_class == C_IN && rr_type == T_CNAME)
+ {
+ /* Decode the RR data and replace ptrname with it. */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
+ &len);
+ if (status != ARES_SUCCESS)
+ {
+ free(rr_name);
+ break;
+ }
+ free(ptrname);
+ ptrname = rr_data;
+ }
+
+ free(rr_name);
+ aptr += rr_len;
+ if (aptr > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+ }
+
+ if (status == ARES_SUCCESS && !hostname)
+ status = ARES_ENODATA;
+ if (status == ARES_SUCCESS)
+ {
+ /* We got our answer. Allocate memory to build the host entry. */
+ hostent = malloc(sizeof(struct hostent));
+ if (hostent)
+ {
+ hostent->h_addr_list = malloc(2 * sizeof(char *));
+ if (hostent->h_addr_list)
+ {
+ hostent->h_addr_list[0] = malloc(addrlen);
+ if (hostent->h_addr_list[0])
+ {
+ hostent->h_aliases = malloc((aliascnt+1) * sizeof (char *));
+ if (hostent->h_aliases)
+ {
+ /* Fill in the hostent and return successfully. */
+ hostent->h_name = hostname;
+ for (i=0 ; i<aliascnt ; i++)
+ hostent->h_aliases[i] = aliases[i];
+ hostent->h_aliases[aliascnt] = NULL;
+ hostent->h_addrtype = aresx_sitoss(family);
+ hostent->h_length = aresx_sitoss(addrlen);
+ memcpy(hostent->h_addr_list[0], addr, addrlen);
+ hostent->h_addr_list[1] = NULL;
+ *host = hostent;
+ free(aliases);
+ free(ptrname);
+ return ARES_SUCCESS;
+ }
+ free(hostent->h_addr_list[0]);
+ }
+ free(hostent->h_addr_list);
+ }
+ free(hostent);
+ }
+ status = ARES_ENOMEM;
+ }
+ for (i=0 ; i<aliascnt ; i++)
+ if (aliases[i])
+ free(aliases[i]);
+ free(aliases);
+ if (hostname)
+ free(hostname);
+ free(ptrname);
+ return status;
+}
diff --git a/deps/cares/src/ares_parse_soa_reply.c b/deps/cares/src/ares_parse_soa_reply.c
new file mode 100644
index 000000000..b8119544b
--- /dev/null
+++ b/deps/cares/src/ares_parse_soa_reply.c
@@ -0,0 +1,135 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2012 Marko Kreen <markokr@gmail.com>
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_data.h"
+#include "ares_private.h"
+
+int
+ares_parse_soa_reply(const unsigned char *abuf, int alen,
+ struct ares_soa_reply **soa_out)
+{
+ const unsigned char *aptr;
+ long len;
+ char *qname = NULL, *rr_name = NULL;
+ struct ares_soa_reply *soa = NULL;
+ int qdcount, ancount;
+ int status;
+
+ if (alen < HFIXEDSZ)
+ return ARES_EBADRESP;
+
+ /* parse message header */
+ qdcount = DNS_HEADER_QDCOUNT(abuf);
+ ancount = DNS_HEADER_ANCOUNT(abuf);
+ if (qdcount != 1 || ancount != 1)
+ return ARES_EBADRESP;
+ aptr = abuf + HFIXEDSZ;
+
+ /* query name */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len);
+ if (status != ARES_SUCCESS)
+ goto failed_stat;
+ aptr += len;
+
+ /* skip qtype & qclass */
+ if (aptr + QFIXEDSZ > abuf + alen)
+ goto failed;
+ aptr += QFIXEDSZ;
+
+ /* rr_name */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
+ if (status != ARES_SUCCESS)
+ goto failed_stat;
+ aptr += len;
+
+ /* skip rr_type, rr_class, rr_ttl, rr_rdlen */
+ if (aptr + RRFIXEDSZ > abuf + alen)
+ goto failed;
+ aptr += RRFIXEDSZ;
+
+ /* allocate result struct */
+ soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY);
+ if (!soa)
+ return ARES_ENOMEM;
+
+ /* nsname */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname, &len);
+ if (status != ARES_SUCCESS)
+ goto failed_stat;
+ aptr += len;
+
+ /* hostmaster */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &soa->hostmaster, &len);
+ if (status != ARES_SUCCESS)
+ goto failed_stat;
+ aptr += len;
+
+ /* integer fields */
+ if (aptr + 5 * 4 > abuf + alen)
+ goto failed;
+ soa->serial = DNS__32BIT(aptr + 0 * 4);
+ soa->refresh = DNS__32BIT(aptr + 1 * 4);
+ soa->retry = DNS__32BIT(aptr + 2 * 4);
+ soa->expire = DNS__32BIT(aptr + 3 * 4);
+ soa->minttl = DNS__32BIT(aptr + 4 * 4);
+
+ free(qname);
+ free(rr_name);
+
+ *soa_out = soa;
+
+ return ARES_SUCCESS;
+
+failed:
+ status = ARES_EBADRESP;
+
+failed_stat:
+ ares_free_data(soa);
+ if (qname)
+ free(qname);
+ if (rr_name)
+ free(rr_name);
+ return status;
+}
+
diff --git a/deps/uv/src/ares/ares_parse_srv_reply.c b/deps/cares/src/ares_parse_srv_reply.c
index 9c7eb6ee3..9c7eb6ee3 100644
--- a/deps/uv/src/ares/ares_parse_srv_reply.c
+++ b/deps/cares/src/ares_parse_srv_reply.c
diff --git a/deps/uv/src/ares/ares_parse_txt_reply.c b/deps/cares/src/ares_parse_txt_reply.c
index 51653328e..51653328e 100644
--- a/deps/uv/src/ares/ares_parse_txt_reply.c
+++ b/deps/cares/src/ares_parse_txt_reply.c
diff --git a/deps/uv/src/ares/ares_platform.c b/deps/cares/src/ares_platform.c
index c20061583..c20061583 100644
--- a/deps/uv/src/ares/ares_platform.c
+++ b/deps/cares/src/ares_platform.c
diff --git a/deps/uv/src/ares/ares_platform.h b/deps/cares/src/ares_platform.h
index e6885ae54..e6885ae54 100644
--- a/deps/uv/src/ares/ares_platform.h
+++ b/deps/cares/src/ares_platform.h
diff --git a/deps/cares/src/ares_private.h b/deps/cares/src/ares_private.h
new file mode 100644
index 000000000..3c56bbcf3
--- /dev/null
+++ b/deps/cares/src/ares_private.h
@@ -0,0 +1,355 @@
+#ifndef __ARES_PRIVATE_H
+#define __ARES_PRIVATE_H
+
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2004-2010 by Daniel Stenberg
+ *
+ * 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.
+ */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#define WIN32
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef WATT32
+#include <tcp.h>
+#include <sys/ioctl.h>
+#define writev(s,v,c) writev_s(s,v,c)
+#define HAVE_WRITEV 1
+#endif
+
+#ifdef NETWARE
+#include <time.h>
+#endif
+
+#define DEFAULT_TIMEOUT 5000 /* milliseconds */
+#define DEFAULT_TRIES 4
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+#if defined(WIN32) && !defined(WATT32)
+
+#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
+#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
+#define NAMESERVER "NameServer"
+#define DHCPNAMESERVER "DhcpNameServer"
+#define DATABASEPATH "DatabasePath"
+#define WIN_PATH_HOSTS "\\hosts"
+
+#elif defined(WATT32)
+
+#define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf"
+
+#elif defined(NETWARE)
+
+#define PATH_RESOLV_CONF "sys:/etc/resolv.cfg"
+#define PATH_HOSTS "sys:/etc/hosts"
+
+#elif defined(__riscos__)
+
+#define PATH_HOSTS "InetDBase:Hosts"
+
+#else
+
+#define PATH_RESOLV_CONF "/etc/resolv.conf"
+#ifdef ETC_INET
+#define PATH_HOSTS "/etc/inet/hosts"
+#else
+#define PATH_HOSTS "/etc/hosts"
+#endif
+
+#endif
+
+#define ARES_ID_KEY_LEN 31
+
+#include "ares_ipv6.h"
+#include "ares_llist.h"
+
+#ifndef HAVE_GETENV
+# include "ares_getenv.h"
+# define getenv(ptr) ares_getenv(ptr)
+#endif
+
+#ifndef HAVE_STRDUP
+# include "ares_strdup.h"
+# define strdup(ptr) ares_strdup(ptr)
+#endif
+
+#ifndef HAVE_STRCASECMP
+# include "ares_strcasecmp.h"
+# define strcasecmp(p1,p2) ares_strcasecmp(p1,p2)
+#endif
+
+#ifndef HAVE_STRNCASECMP
+# include "ares_strcasecmp.h"
+# define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n)
+#endif
+
+#ifndef HAVE_WRITEV
+# include "ares_writev.h"
+# define writev(s,ptr,cnt) ares_writev(s,ptr,cnt)
+#endif
+
+struct ares_addr {
+ int family;
+ union {
+ struct in_addr addr4;
+ struct ares_in6_addr addr6;
+ } addr;
+};
+#define addrV4 addr.addr4
+#define addrV6 addr.addr6
+
+struct query;
+
+struct send_request {
+ /* Remaining data to send */
+ const unsigned char *data;
+ size_t len;
+
+ /* The query for which we're sending this data */
+ struct query* owner_query;
+ /* The buffer we're using, if we have our own copy of the packet */
+ unsigned char *data_storage;
+
+ /* Next request in queue */
+ struct send_request *next;
+};
+
+struct server_state {
+ struct ares_addr addr;
+ ares_socket_t udp_socket;
+ ares_socket_t tcp_socket;
+
+ /* Mini-buffer for reading the length word */
+ unsigned char tcp_lenbuf[2];
+ int tcp_lenbuf_pos;
+ int tcp_length;
+
+ /* Buffer for reading actual TCP data */
+ unsigned char *tcp_buffer;
+ int tcp_buffer_pos;
+
+ /* TCP output queue */
+ struct send_request *qhead;
+ struct send_request *qtail;
+
+ /* Which incarnation of this connection is this? We don't want to
+ * retransmit requests into the very same socket, but if the server
+ * closes on us and we re-open the connection, then we do want to
+ * re-send. */
+ int tcp_connection_generation;
+
+ /* Circular, doubly-linked list of outstanding queries to this server */
+ struct list_node queries_to_server;
+
+ /* Link back to owning channel */
+ ares_channel channel;
+
+ /* Is this server broken? We mark connections as broken when a
+ * request that is queued for sending times out.
+ */
+ int is_broken;
+};
+
+/* State to represent a DNS query */
+struct query {
+ /* Query ID from qbuf, for faster lookup, and current timeout */
+ unsigned short qid;
+ struct timeval timeout;
+
+ /*
+ * Links for the doubly-linked lists in which we insert a query.
+ * These circular, doubly-linked lists that are hash-bucketed based
+ * the attributes we care about, help making most important
+ * operations O(1).
+ */
+ struct list_node queries_by_qid; /* hopefully in same cache line as qid */
+ struct list_node queries_by_timeout;
+ struct list_node queries_to_server;
+ struct list_node all_queries;
+
+ /* Query buf with length at beginning, for TCP transmission */
+ unsigned char *tcpbuf;
+ int tcplen;
+
+ /* Arguments passed to ares_send() (qbuf points into tcpbuf) */
+ const unsigned char *qbuf;
+ int qlen;
+ ares_callback callback;
+ void *arg;
+
+ /* Query status */
+ int try_count; /* Number of times we tried this query already. */
+ int server; /* Server this query has last been sent to. */
+ struct query_server_info *server_info; /* per-server state */
+ int using_tcp;
+ int error_status;
+ int timeouts; /* number of timeouts we saw for this request */
+};
+
+/* Per-server state for a query */
+struct query_server_info {
+ int skip_server; /* should we skip server, due to errors, etc? */
+ int tcp_connection_generation; /* into which TCP connection did we send? */
+};
+
+/* An IP address pattern; matches an IP address X if X & mask == addr */
+#define PATTERN_MASK 0x1
+#define PATTERN_CIDR 0x2
+
+struct apattern {
+ union
+ {
+ struct in_addr addr4;
+ struct ares_in6_addr addr6;
+ } addr;
+ union
+ {
+ struct in_addr addr4;
+ struct ares_in6_addr addr6;
+ unsigned short bits;
+ } mask;
+ int family;
+ unsigned short type;
+};
+
+typedef struct rc4_key
+{
+ unsigned char state[256];
+ unsigned char x;
+ unsigned char y;
+} rc4_key;
+
+struct ares_channeldata {
+ /* Configuration data */
+ int flags;
+ int timeout; /* in milliseconds */
+ int tries;
+ int ndots;
+ int rotate; /* if true, all servers specified are used */
+ int udp_port;
+ int tcp_port;
+ int socket_send_buffer_size;
+ int socket_receive_buffer_size;
+ char **domains;
+ int ndomains;
+ struct apattern *sortlist;
+ int nsort;
+ char *lookups;
+
+ /* For binding to local devices and/or IP addresses. Leave
+ * them null/zero for no binding.
+ */
+ char local_dev_name[32];
+ unsigned int local_ip4;
+ unsigned char local_ip6[16];
+
+ int optmask; /* the option bitfield passed in at init time */
+
+ /* Server addresses and communications state */
+ struct server_state *servers;
+ int nservers;
+
+ /* ID to use for next query */
+ unsigned short next_id;
+ /* key to use when generating new ids */
+ rc4_key id_key;
+
+ /* Generation number to use for the next TCP socket open/close */
+ int tcp_connection_generation;
+
+ /* The time at which we last called process_timeouts(). Uses integer seconds
+ just to draw the line somewhere. */
+ time_t last_timeout_processed;
+
+ /* Last server we sent a query to. */
+ int last_server;
+
+ /* Circular, doubly-linked list of queries, bucketed various ways.... */
+ /* All active queries in a single list: */
+ struct list_node all_queries;
+ /* Queries bucketed by qid, for quickly dispatching DNS responses: */
+#define ARES_QID_TABLE_SIZE 2048
+ struct list_node queries_by_qid[ARES_QID_TABLE_SIZE];
+ /* Queries bucketed by timeout, for quickly handling timeouts: */
+#define ARES_TIMEOUT_TABLE_SIZE 1024
+ struct list_node queries_by_timeout[ARES_TIMEOUT_TABLE_SIZE];
+
+ ares_sock_state_cb sock_state_cb;
+ void *sock_state_cb_data;
+
+ ares_sock_create_callback sock_create_cb;
+ void *sock_create_cb_data;
+};
+
+/* return true if now is exactly check time or later */
+int ares__timedout(struct timeval *now,
+ struct timeval *check);
+/* add the specific number of milliseconds to the time in the first argument */
+int ares__timeadd(struct timeval *now,
+ int millisecs);
+/* return time offset between now and (future) check, in milliseconds */
+long ares__timeoffset(struct timeval *now,
+ struct timeval *check);
+/* returns ARES_SUCCESS if library has been initialized */
+int ares_library_initialized(void);
+void ares__rc4(rc4_key* key,unsigned char *buffer_ptr, int buffer_len);
+void ares__send_query(ares_channel channel, struct query *query,
+ struct timeval *now);
+void ares__close_sockets(ares_channel channel, struct server_state *server);
+int ares__get_hostent(FILE *fp, int family, struct hostent **host);
+int ares__read_line(FILE *fp, char **buf, size_t *bufsize);
+void ares__free_query(struct query *query);
+unsigned short ares__generate_new_id(rc4_key* key);
+struct timeval ares__tvnow(void);
+int ares__expand_name_for_response(const unsigned char *encoded,
+ const unsigned char *abuf, int alen,
+ char **s, long *enclen);
+void ares__init_servers_state(ares_channel channel);
+void ares__destroy_servers_state(ares_channel channel);
+#if 0 /* Not used */
+long ares__tvdiff(struct timeval t1, struct timeval t2);
+#endif
+
+#define ARES_SWAP_BYTE(a,b) \
+ { unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; }
+
+#define SOCK_STATE_CALLBACK(c, s, r, w) \
+ do { \
+ if ((c)->sock_state_cb) \
+ (c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \
+ } WHILE_FALSE
+
+#ifdef CURLDEBUG
+/* This is low-level hard-hacking memory leak tracking and similar. Using the
+ libcurl lowlevel code from within library is ugly and only works when
+ c-ares is built and linked with a similarly curldebug-enabled libcurl,
+ but we do this anyway for convenience. */
+#include "../lib/memdebug.h"
+#endif
+
+#endif /* __ARES_PRIVATE_H */
diff --git a/deps/cares/src/ares_process.c b/deps/cares/src/ares_process.c
new file mode 100644
index 000000000..79a999fdf
--- /dev/null
+++ b/deps/cares/src/ares_process.c
@@ -0,0 +1,1294 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2004-2012 by Daniel Stenberg
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+# include <sys/uio.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+# include <netinet/tcp.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef NETWARE
+# include <sys/filio.h>
+#endif
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <time.h>
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_nowarn.h"
+#include "ares_private.h"
+
+
+static int try_again(int errnum);
+static void write_tcp_data(ares_channel channel, fd_set *write_fds,
+ ares_socket_t write_fd, struct timeval *now);
+static void read_tcp_data(ares_channel channel, fd_set *read_fds,
+ ares_socket_t read_fd, struct timeval *now);
+static void read_udp_packets(ares_channel channel, fd_set *read_fds,
+ ares_socket_t read_fd, struct timeval *now);
+static void advance_tcp_send_queue(ares_channel channel, int whichserver,
+ ssize_t num_bytes);
+static void process_timeouts(ares_channel channel, struct timeval *now);
+static void process_broken_connections(ares_channel channel,
+ struct timeval *now);
+static void process_answer(ares_channel channel, unsigned char *abuf,
+ int alen, int whichserver, int tcp,
+ struct timeval *now);
+static void handle_error(ares_channel channel, int whichserver,
+ struct timeval *now);
+static void skip_server(ares_channel channel, struct query *query,
+ int whichserver);
+static void next_server(ares_channel channel, struct query *query,
+ struct timeval *now);
+static int open_tcp_socket(ares_channel channel, struct server_state *server);
+static int open_udp_socket(ares_channel channel, struct server_state *server);
+static int same_questions(const unsigned char *qbuf, int qlen,
+ const unsigned char *abuf, int alen);
+static int same_address(struct sockaddr *sa, struct ares_addr *aa);
+static void end_query(ares_channel channel, struct query *query, int status,
+ unsigned char *abuf, int alen);
+
+/* return true if now is exactly check time or later */
+int ares__timedout(struct timeval *now,
+ struct timeval *check)
+{
+ long secs = (now->tv_sec - check->tv_sec);
+
+ if(secs > 0)
+ return 1; /* yes, timed out */
+ if(secs < 0)
+ return 0; /* nope, not timed out */
+
+ /* if the full seconds were identical, check the sub second parts */
+ return (now->tv_usec - check->tv_usec >= 0);
+}
+
+/* add the specific number of milliseconds to the time in the first argument */
+int ares__timeadd(struct timeval *now,
+ int millisecs)
+{
+ now->tv_sec += millisecs/1000;
+ now->tv_usec += (millisecs%1000)*1000;
+
+ if(now->tv_usec >= 1000000) {
+ ++(now->tv_sec);
+ now->tv_usec -= 1000000;
+ }
+
+ return 0;
+}
+
+/* return time offset between now and (future) check, in milliseconds */
+long ares__timeoffset(struct timeval *now,
+ struct timeval *check)
+{
+ return (check->tv_sec - now->tv_sec)*1000 +
+ (check->tv_usec - now->tv_usec)/1000;
+}
+
+
+/*
+ * generic process function
+ */
+static void processfds(ares_channel channel,
+ fd_set *read_fds, ares_socket_t read_fd,
+ fd_set *write_fds, ares_socket_t write_fd)
+{
+ struct timeval now = ares__tvnow();
+
+ write_tcp_data(channel, write_fds, write_fd, &now);
+ read_tcp_data(channel, read_fds, read_fd, &now);
+ read_udp_packets(channel, read_fds, read_fd, &now);
+ process_timeouts(channel, &now);
+ process_broken_connections(channel, &now);
+}
+
+/* Something interesting happened on the wire, or there was a timeout.
+ * See what's up and respond accordingly.
+ */
+void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
+{
+ processfds(channel, read_fds, ARES_SOCKET_BAD, write_fds, ARES_SOCKET_BAD);
+}
+
+/* Something interesting happened on the wire, or there was a timeout.
+ * See what's up and respond accordingly.
+ */
+void ares_process_fd(ares_channel channel,
+ ares_socket_t read_fd, /* use ARES_SOCKET_BAD or valid
+ file descriptors */
+ ares_socket_t write_fd)
+{
+ processfds(channel, NULL, read_fd, NULL, write_fd);
+}
+
+
+/* Return 1 if the specified error number describes a readiness error, or 0
+ * otherwise. This is mostly for HP-UX, which could return EAGAIN or
+ * EWOULDBLOCK. See this man page
+ *
+ * http://devrsrc1.external.hp.com/STKS/cgi-bin/man2html?
+ * manpage=/usr/share/man/man2.Z/send.2
+ */
+static int try_again(int errnum)
+{
+#if !defined EWOULDBLOCK && !defined EAGAIN
+#error "Neither EWOULDBLOCK nor EAGAIN defined"
+#endif
+ switch (errnum)
+ {
+#ifdef EWOULDBLOCK
+ case EWOULDBLOCK:
+ return 1;
+#endif
+#if defined EAGAIN && EAGAIN != EWOULDBLOCK
+ case EAGAIN:
+ return 1;
+#endif
+ }
+ return 0;
+}
+
+/* If any TCP sockets select true for writing, write out queued data
+ * we have for them.
+ */
+static void write_tcp_data(ares_channel channel,
+ fd_set *write_fds,
+ ares_socket_t write_fd,
+ struct timeval *now)
+{
+ struct server_state *server;
+ struct send_request *sendreq;
+ struct iovec *vec;
+ int i;
+ ssize_t scount;
+ ssize_t wcount;
+ size_t n;
+
+ if(!write_fds && (write_fd == ARES_SOCKET_BAD))
+ /* no possible action */
+ return;
+
+ for (i = 0; i < channel->nservers; i++)
+ {
+ /* Make sure server has data to send and is selected in write_fds or
+ write_fd. */
+ server = &channel->servers[i];
+ if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD ||
+ server->is_broken)
+ continue;
+
+ if(write_fds) {
+ if(!FD_ISSET(server->tcp_socket, write_fds))
+ continue;
+ }
+ else {
+ if(server->tcp_socket != write_fd)
+ continue;
+ }
+
+ if(write_fds)
+ /* If there's an error and we close this socket, then open
+ * another with the same fd to talk to another server, then we
+ * don't want to think that it was the new socket that was
+ * ready. This is not disastrous, but is likely to result in
+ * extra system calls and confusion. */
+ FD_CLR(server->tcp_socket, write_fds);
+
+ /* Count the number of send queue items. */
+ n = 0;
+ for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
+ n++;
+
+ /* Allocate iovecs so we can send all our data at once. */
+ vec = malloc(n * sizeof(struct iovec));
+ if (vec)
+ {
+ /* Fill in the iovecs and send. */
+ n = 0;
+ for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
+ {
+ vec[n].iov_base = (char *) sendreq->data;
+ vec[n].iov_len = sendreq->len;
+ n++;
+ }
+ wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n);
+ free(vec);
+ if (wcount < 0)
+ {
+ if (!try_again(SOCKERRNO))
+ handle_error(channel, i, now);
+ continue;
+ }
+
+ /* Advance the send queue by as many bytes as we sent. */
+ advance_tcp_send_queue(channel, i, wcount);
+ }
+ else
+ {
+ /* Can't allocate iovecs; just send the first request. */
+ sendreq = server->qhead;
+
+ scount = swrite(server->tcp_socket, sendreq->data, sendreq->len);
+ if (scount < 0)
+ {
+ if (!try_again(SOCKERRNO))
+ handle_error(channel, i, now);
+ continue;
+ }
+
+ /* Advance the send queue by as many bytes as we sent. */
+ advance_tcp_send_queue(channel, i, scount);
+ }
+ }
+}
+
+/* Consume the given number of bytes from the head of the TCP send queue. */
+static void advance_tcp_send_queue(ares_channel channel, int whichserver,
+ ssize_t num_bytes)
+{
+ struct send_request *sendreq;
+ struct server_state *server = &channel->servers[whichserver];
+ while (num_bytes > 0) {
+ sendreq = server->qhead;
+ if ((size_t)num_bytes >= sendreq->len) {
+ num_bytes -= sendreq->len;
+ server->qhead = sendreq->next;
+ if (sendreq->data_storage)
+ free(sendreq->data_storage);
+ free(sendreq);
+ if (server->qhead == NULL) {
+ SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
+ server->qtail = NULL;
+
+ /* qhead is NULL so we cannot continue this loop */
+ break;
+ }
+ }
+ else {
+ sendreq->data += num_bytes;
+ sendreq->len -= num_bytes;
+ num_bytes = 0;
+ }
+ }
+}
+
+/* If any TCP socket selects true for reading, read some data,
+ * allocate a buffer if we finish reading the length word, and process
+ * a packet if we finish reading one.
+ */
+static void read_tcp_data(ares_channel channel, fd_set *read_fds,
+ ares_socket_t read_fd, struct timeval *now)
+{
+ struct server_state *server;
+ int i;
+ ssize_t count;
+
+ if(!read_fds && (read_fd == ARES_SOCKET_BAD))
+ /* no possible action */
+ return;
+
+ for (i = 0; i < channel->nservers; i++)
+ {
+ /* Make sure the server has a socket and is selected in read_fds. */
+ server = &channel->servers[i];
+ if (server->tcp_socket == ARES_SOCKET_BAD || server->is_broken)
+ continue;
+
+ if(read_fds) {
+ if(!FD_ISSET(server->tcp_socket, read_fds))
+ continue;
+ }
+ else {
+ if(server->tcp_socket != read_fd)
+ continue;
+ }
+
+ if(read_fds)
+ /* If there's an error and we close this socket, then open
+ * another with the same fd to talk to another server, then we
+ * don't want to think that it was the new socket that was
+ * ready. This is not disastrous, but is likely to result in
+ * extra system calls and confusion. */
+ FD_CLR(server->tcp_socket, read_fds);
+
+ if (server->tcp_lenbuf_pos != 2)
+ {
+ /* We haven't yet read a length word, so read that (or
+ * what's left to read of it).
+ */
+ count = sread(server->tcp_socket,
+ server->tcp_lenbuf + server->tcp_lenbuf_pos,
+ 2 - server->tcp_lenbuf_pos);
+ if (count <= 0)
+ {
+ if (!(count == -1 && try_again(SOCKERRNO)))
+ handle_error(channel, i, now);
+ continue;
+ }
+
+ server->tcp_lenbuf_pos += (int)count;
+ if (server->tcp_lenbuf_pos == 2)
+ {
+ /* We finished reading the length word. Decode the
+ * length and allocate a buffer for the data.
+ */
+ server->tcp_length = server->tcp_lenbuf[0] << 8
+ | server->tcp_lenbuf[1];
+ server->tcp_buffer = malloc(server->tcp_length);
+ if (!server->tcp_buffer)
+ handle_error(channel, i, now);
+ server->tcp_buffer_pos = 0;
+ }
+ }
+ else
+ {
+ /* Read data into the allocated buffer. */
+ count = sread(server->tcp_socket,
+ server->tcp_buffer + server->tcp_buffer_pos,
+ server->tcp_length - server->tcp_buffer_pos);
+ if (count <= 0)
+ {
+ if (!(count == -1 && try_again(SOCKERRNO)))
+ handle_error(channel, i, now);
+ continue;
+ }
+
+ server->tcp_buffer_pos += (int)count;
+ if (server->tcp_buffer_pos == server->tcp_length)
+ {
+ /* We finished reading this answer; process it and
+ * prepare to read another length word.
+ */
+ process_answer(channel, server->tcp_buffer, server->tcp_length,
+ i, 1, now);
+ if (server->tcp_buffer)
+ free(server->tcp_buffer);
+ server->tcp_buffer = NULL;
+ server->tcp_lenbuf_pos = 0;
+ server->tcp_buffer_pos = 0;
+ }
+ }
+ }
+}
+
+/* If any UDP sockets select true for reading, process them. */
+static void read_udp_packets(ares_channel channel, fd_set *read_fds,
+ ares_socket_t read_fd, struct timeval *now)
+{
+ struct server_state *server;
+ int i;
+ ssize_t count;
+ unsigned char buf[PACKETSZ + 1];
+#ifdef HAVE_RECVFROM
+ ares_socklen_t fromlen;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sa4;
+ struct sockaddr_in6 sa6;
+ } from;
+#endif
+
+ if(!read_fds && (read_fd == ARES_SOCKET_BAD))
+ /* no possible action */
+ return;
+
+ for (i = 0; i < channel->nservers; i++)
+ {
+ /* Make sure the server has a socket and is selected in read_fds. */
+ server = &channel->servers[i];
+
+ if (server->udp_socket == ARES_SOCKET_BAD || server->is_broken)
+ continue;
+
+ if(read_fds) {
+ if(!FD_ISSET(server->udp_socket, read_fds))
+ continue;
+ }
+ else {
+ if(server->udp_socket != read_fd)
+ continue;
+ }
+
+ if(read_fds)
+ /* If there's an error and we close this socket, then open
+ * another with the same fd to talk to another server, then we
+ * don't want to think that it was the new socket that was
+ * ready. This is not disastrous, but is likely to result in
+ * extra system calls and confusion. */
+ FD_CLR(server->udp_socket, read_fds);
+
+ /* To reduce event loop overhead, read and process as many
+ * packets as we can. */
+ do {
+#ifdef HAVE_RECVFROM
+ if (server->addr.family == AF_INET)
+ fromlen = sizeof(from.sa4);
+ else
+ fromlen = sizeof(from.sa6);
+ count = (ssize_t)recvfrom(server->udp_socket, (void *)buf, sizeof(buf),
+ 0, &from.sa, &fromlen);
+#else
+ count = sread(server->udp_socket, buf, sizeof(buf));
+#endif
+ if (count == -1 && try_again(SOCKERRNO))
+ continue;
+ else if (count <= 0)
+ handle_error(channel, i, now);
+#ifdef HAVE_RECVFROM
+ else if (!same_address(&from.sa, &server->addr))
+ /* The address the response comes from does not match
+ * the address we sent the request to. Someone may be
+ * attempting to perform a cache poisoning attack. */
+ break;
+#endif
+ else
+ process_answer(channel, buf, (int)count, i, 0, now);
+ } while (count > 0);
+ }
+}
+
+/* If any queries have timed out, note the timeout and move them on. */
+static void process_timeouts(ares_channel channel, struct timeval *now)
+{
+ time_t t; /* the time of the timeouts we're processing */
+ struct query *query;
+ struct list_node* list_head;
+ struct list_node* list_node;
+
+ /* Process all the timeouts that have fired since the last time we
+ * processed timeouts. If things are going well, then we'll have
+ * hundreds/thousands of queries that fall into future buckets, and
+ * only a handful of requests that fall into the "now" bucket, so
+ * this should be quite quick.
+ */
+ for (t = channel->last_timeout_processed; t <= now->tv_sec; t++)
+ {
+ list_head = &(channel->queries_by_timeout[t % ARES_TIMEOUT_TABLE_SIZE]);
+ for (list_node = list_head->next; list_node != list_head; )
+ {
+ query = list_node->data;
+ list_node = list_node->next; /* in case the query gets deleted */
+ if (query->timeout.tv_sec && ares__timedout(now, &query->timeout))
+ {
+ query->error_status = ARES_ETIMEOUT;
+ ++query->timeouts;
+ next_server(channel, query, now);
+ }
+ }
+ }
+ channel->last_timeout_processed = now->tv_sec;
+}
+
+/* Handle an answer from a server. */
+static void process_answer(ares_channel channel, unsigned char *abuf,
+ int alen, int whichserver, int tcp,
+ struct timeval *now)
+{
+ int tc, rcode;
+ unsigned short id;
+ struct query *query;
+ struct list_node* list_head;
+ struct list_node* list_node;
+
+ /* If there's no room in the answer for a header, we can't do much
+ * with it. */
+ if (alen < HFIXEDSZ)
+ return;
+
+ /* Grab the query ID, truncate bit, and response code from the packet. */
+ id = DNS_HEADER_QID(abuf);
+ tc = DNS_HEADER_TC(abuf);
+ rcode = DNS_HEADER_RCODE(abuf);
+
+ /* Find the query corresponding to this packet. The queries are
+ * hashed/bucketed by query id, so this lookup should be quick.
+ * Note that both the query id and the questions must be the same;
+ * when the query id wraps around we can have multiple outstanding
+ * queries with the same query id, so we need to check both the id and
+ * question.
+ */
+ query = NULL;
+ list_head = &(channel->queries_by_qid[id % ARES_QID_TABLE_SIZE]);
+ for (list_node = list_head->next; list_node != list_head;
+ list_node = list_node->next)
+ {
+ struct query *q = list_node->data;
+ if ((q->qid == id) && same_questions(q->qbuf, q->qlen, abuf, alen))
+ {
+ query = q;
+ break;
+ }
+ }
+ if (!query)
+ return;
+
+ /* If we got a truncated UDP packet and are not ignoring truncation,
+ * don't accept the packet, and switch the query to TCP if we hadn't
+ * done so already.
+ */
+ if ((tc || alen > PACKETSZ) && !tcp && !(channel->flags & ARES_FLAG_IGNTC))
+ {
+ if (!query->using_tcp)
+ {
+ query->using_tcp = 1;
+ ares__send_query(channel, query, now);
+ }
+ return;
+ }
+
+ /* Limit alen to PACKETSZ if we aren't using TCP (only relevant if we
+ * are ignoring truncation.
+ */
+ if (alen > PACKETSZ && !tcp)
+ alen = PACKETSZ;
+
+ /* If we aren't passing through all error packets, discard packets
+ * with SERVFAIL, NOTIMP, or REFUSED response codes.
+ */
+ if (!(channel->flags & ARES_FLAG_NOCHECKRESP))
+ {
+ if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED)
+ {
+ skip_server(channel, query, whichserver);
+ if (query->server == whichserver)
+ next_server(channel, query, now);
+ return;
+ }
+ }
+
+ end_query(channel, query, ARES_SUCCESS, abuf, alen);
+}
+
+/* Close all the connections that are no longer usable. */
+static void process_broken_connections(ares_channel channel,
+ struct timeval *now)
+{
+ int i;
+ for (i = 0; i < channel->nservers; i++)
+ {
+ struct server_state *server = &channel->servers[i];
+ if (server->is_broken)
+ {
+ handle_error(channel, i, now);
+ }
+ }
+}
+
+static void handle_error(ares_channel channel, int whichserver,
+ struct timeval *now)
+{
+ struct server_state *server;
+ struct query *query;
+ struct list_node list_head;
+ struct list_node* list_node;
+
+ server = &channel->servers[whichserver];
+
+ /* Reset communications with this server. */
+ ares__close_sockets(channel, server);
+
+ /* Tell all queries talking to this server to move on and not try
+ * this server again. We steal the current list of queries that were
+ * in-flight to this server, since when we call next_server this can
+ * cause the queries to be re-sent to this server, which will
+ * re-insert these queries in that same server->queries_to_server
+ * list.
+ */
+ ares__init_list_head(&list_head);
+ ares__swap_lists(&list_head, &(server->queries_to_server));
+ for (list_node = list_head.next; list_node != &list_head; )
+ {
+ query = list_node->data;
+ list_node = list_node->next; /* in case the query gets deleted */
+ assert(query->server == whichserver);
+ skip_server(channel, query, whichserver);
+ next_server(channel, query, now);
+ }
+ /* Each query should have removed itself from our temporary list as
+ * it re-sent itself or finished up...
+ */
+ assert(ares__is_list_empty(&list_head));
+}
+
+static void skip_server(ares_channel channel, struct query *query,
+ int whichserver) {
+ /* The given server gave us problems with this query, so if we have
+ * the luxury of using other servers, then let's skip the
+ * potentially broken server and just use the others. If we only
+ * have one server and we need to retry then we should just go ahead
+ * and re-use that server, since it's our only hope; perhaps we
+ * just got unlucky, and retrying will work (eg, the server timed
+ * out our TCP connection just as we were sending another request).
+ */
+ if (channel->nservers > 1)
+ {
+ query->server_info[whichserver].skip_server = 1;
+ }
+}
+
+static void next_server(ares_channel channel, struct query *query,
+ struct timeval *now)
+{
+ /* We need to try each server channel->tries times. We have channel->nservers
+ * servers to try. In total, we need to do channel->nservers * channel->tries
+ * attempts. Use query->try to remember how many times we already attempted
+ * this query. Use modular arithmetic to find the next server to try. */
+ while (++(query->try_count) < (channel->nservers * channel->tries))
+ {
+ struct server_state *server;
+
+ /* Move on to the next server. */
+ query->server = (query->server + 1) % channel->nservers;
+ server = &channel->servers[query->server];
+
+ /* We don't want to use this server if (1) we decided this
+ * connection is broken, and thus about to be closed, (2)
+ * we've decided to skip this server because of earlier
+ * errors we encountered, or (3) we already sent this query
+ * over this exact connection.
+ */
+ if (!server->is_broken &&
+ !query->server_info[query->server].skip_server &&
+ !(query->using_tcp &&
+ (query->server_info[query->server].tcp_connection_generation ==
+ server->tcp_connection_generation)))
+ {
+ ares__send_query(channel, query, now);
+ return;
+ }
+
+ /* You might think that with TCP we only need one try. However,
+ * even when using TCP, servers can time-out our connection just
+ * as we're sending a request, or close our connection because
+ * they die, or never send us a reply because they get wedged or
+ * tickle a bug that drops our request.
+ */
+ }
+
+ /* If we are here, all attempts to perform query failed. */
+ end_query(channel, query, query->error_status, NULL, 0);
+}
+
+void ares__send_query(ares_channel channel, struct query *query,
+ struct timeval *now)
+{
+ struct send_request *sendreq;
+ struct server_state *server;
+ int timeplus;
+
+ server = &channel->servers[query->server];
+ if (query->using_tcp)
+ {
+ /* Make sure the TCP socket for this server is set up and queue
+ * a send request.
+ */
+ if (server->tcp_socket == ARES_SOCKET_BAD)
+ {
+ if (open_tcp_socket(channel, server) == -1)
+ {
+ skip_server(channel, query, query->server);
+ next_server(channel, query, now);
+ return;
+ }
+ }
+ sendreq = calloc(1, sizeof(struct send_request));
+ if (!sendreq)
+ {
+ end_query(channel, query, ARES_ENOMEM, NULL, 0);
+ return;
+ }
+ /* To make the common case fast, we avoid copies by using the
+ * query's tcpbuf for as long as the query is alive. In the rare
+ * case where the query ends while it's queued for transmission,
+ * then we give the sendreq its own copy of the request packet
+ * and put it in sendreq->data_storage.
+ */
+ sendreq->data_storage = NULL;
+ sendreq->data = query->tcpbuf;
+ sendreq->len = query->tcplen;
+ sendreq->owner_query = query;
+ sendreq->next = NULL;
+ if (server->qtail)
+ server->qtail->next = sendreq;
+ else
+ {
+ SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 1);
+ server->qhead = sendreq;
+ }
+ server->qtail = sendreq;
+ query->server_info[query->server].tcp_connection_generation =
+ server->tcp_connection_generation;
+ }
+ else
+ {
+ if (server->udp_socket == ARES_SOCKET_BAD)
+ {
+ if (open_udp_socket(channel, server) == -1)
+ {
+ skip_server(channel, query, query->server);
+ next_server(channel, query, now);
+ return;
+ }
+ }
+ if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1)
+ {
+ /* FIXME: Handle EAGAIN here since it likely can happen. */
+ skip_server(channel, query, query->server);
+ next_server(channel, query, now);
+ return;
+ }
+ }
+ timeplus = channel->timeout << (query->try_count / channel->nservers);
+ timeplus = (timeplus * (9 + (rand () & 7))) / 16;
+ query->timeout = *now;
+ ares__timeadd(&query->timeout,
+ timeplus);
+ /* Keep track of queries bucketed by timeout, so we can process
+ * timeout events quickly.
+ */
+ ares__remove_from_list(&(query->queries_by_timeout));
+ ares__insert_in_list(
+ &(query->queries_by_timeout),
+ &(channel->queries_by_timeout[query->timeout.tv_sec %
+ ARES_TIMEOUT_TABLE_SIZE]));
+
+ /* Keep track of queries bucketed by server, so we can process server
+ * errors quickly.
+ */
+ ares__remove_from_list(&(query->queries_to_server));
+ ares__insert_in_list(&(query->queries_to_server),
+ &(server->queries_to_server));
+}
+
+/*
+ * setsocknonblock sets the given socket to either blocking or non-blocking
+ * mode based on the 'nonblock' boolean argument. This function is highly
+ * portable.
+ */
+static int setsocknonblock(ares_socket_t sockfd, /* operate on this */
+ int nonblock /* TRUE or FALSE */)
+{
+#if defined(USE_BLOCKING_SOCKETS)
+
+ return 0; /* returns success */
+
+#elif defined(HAVE_FCNTL_O_NONBLOCK)
+
+ /* most recent unix versions */
+ int flags;
+ flags = fcntl(sockfd, F_GETFL, 0);
+ if (FALSE != nonblock)
+ return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+ else
+ return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
+
+#elif defined(HAVE_IOCTL_FIONBIO)
+
+ /* older unix versions */
+ int flags = nonblock ? 1 : 0;
+ return ioctl(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
+
+#ifdef WATT32
+ char flags = nonblock ? 1 : 0;
+#else
+ /* Windows */
+ unsigned long flags = nonblock ? 1UL : 0UL;
+#endif
+ return ioctlsocket(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
+
+ /* Amiga */
+ long flags = nonblock ? 1L : 0L;
+ return IoctlSocket(sockfd, FIONBIO, flags);
+
+#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
+
+ /* BeOS */
+ long b = nonblock ? 1L : 0L;
+ return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
+
+#else
+# error "no non-blocking method was found/used/set"
+#endif
+}
+
+static int configure_socket(ares_socket_t s, int family, ares_channel channel)
+{
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sa4;
+ struct sockaddr_in6 sa6;
+ } local;
+
+ setsocknonblock(s, TRUE);
+
+#if defined(FD_CLOEXEC) && !defined(MSDOS)
+ /* Configure the socket fd as close-on-exec. */
+ if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1)
+ return -1;
+#endif
+
+ /* Set the socket's send and receive buffer sizes. */
+ if ((channel->socket_send_buffer_size > 0) &&
+ setsockopt(s, SOL_SOCKET, SO_SNDBUF,
+ (void *)&channel->socket_send_buffer_size,
+ sizeof(channel->socket_send_buffer_size)) == -1)
+ return -1;
+
+ if ((channel->socket_receive_buffer_size > 0) &&
+ setsockopt(s, SOL_SOCKET, SO_RCVBUF,
+ (void *)&channel->socket_receive_buffer_size,
+ sizeof(channel->socket_receive_buffer_size)) == -1)
+ return -1;
+
+#ifdef SO_BINDTODEVICE
+ if (channel->local_dev_name[0]) {
+ if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
+ channel->local_dev_name, sizeof(channel->local_dev_name))) {
+ /* Only root can do this, and usually not fatal if it doesn't work, so */
+ /* just continue on. */
+ }
+ }
+#endif
+
+ if (family == AF_INET) {
+ if (channel->local_ip4) {
+ memset(&local.sa4, 0, sizeof(local.sa4));
+ local.sa4.sin_family = AF_INET;
+ local.sa4.sin_addr.s_addr = htonl(channel->local_ip4);
+ if (bind(s, &local.sa, sizeof(local.sa4)) < 0)
+ return -1;
+ }
+ }
+ else if (family == AF_INET6) {
+ if (memcmp(channel->local_ip6, &ares_in6addr_any, sizeof(channel->local_ip6)) != 0) {
+ memset(&local.sa6, 0, sizeof(local.sa6));
+ local.sa6.sin6_family = AF_INET6;
+ memcpy(&local.sa6.sin6_addr, channel->local_ip6, sizeof(channel->local_ip6));
+ if (bind(s, &local.sa, sizeof(local.sa6)) < 0)
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int open_tcp_socket(ares_channel channel, struct server_state *server)
+{
+ ares_socket_t s;
+ int opt;
+ ares_socklen_t salen;
+ union {
+ struct sockaddr_in sa4;
+ struct sockaddr_in6 sa6;
+ } saddr;
+ struct sockaddr *sa;
+
+ switch (server->addr.family)
+ {
+ case AF_INET:
+ sa = (void *)&saddr.sa4;
+ salen = sizeof(saddr.sa4);
+ memset(sa, 0, salen);
+ saddr.sa4.sin_family = AF_INET;
+ saddr.sa4.sin_port = aresx_sitous(channel->tcp_port);
+ memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4,
+ sizeof(server->addr.addrV4));
+ break;
+ case AF_INET6:
+ sa = (void *)&saddr.sa6;
+ salen = sizeof(saddr.sa6);
+ memset(sa, 0, salen);
+ saddr.sa6.sin6_family = AF_INET6;
+ saddr.sa6.sin6_port = aresx_sitous(channel->tcp_port);
+ memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6,
+ sizeof(server->addr.addrV6));
+ break;
+ default:
+ return -1;
+ }
+
+ /* Acquire a socket. */
+ s = socket(server->addr.family, SOCK_STREAM, 0);
+ if (s == ARES_SOCKET_BAD)
+ return -1;
+
+ /* Configure it. */
+ if (configure_socket(s, server->addr.family, channel) < 0)
+ {
+ sclose(s);
+ return -1;
+ }
+
+#ifdef TCP_NODELAY
+ /*
+ * Disable the Nagle algorithm (only relevant for TCP sockets, and thus not
+ * in configure_socket). In general, in DNS lookups we're pretty much
+ * interested in firing off a single request and then waiting for a reply,
+ * so batching isn't very interesting.
+ */
+ opt = 1;
+ if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
+ (void *)&opt, sizeof(opt)) == -1)
+ {
+ sclose(s);
+ return -1;
+ }
+#endif
+
+ /* Connect to the server. */
+ if (connect(s, sa, salen) == -1)
+ {
+ int err = SOCKERRNO;
+
+ if (err != EINPROGRESS && err != EWOULDBLOCK)
+ {
+ sclose(s);
+ return -1;
+ }
+ }
+
+ if (channel->sock_create_cb)
+ {
+ int err = channel->sock_create_cb(s, SOCK_STREAM,
+ channel->sock_create_cb_data);
+ if (err < 0)
+ {
+ sclose(s);
+ return err;
+ }
+ }
+
+ SOCK_STATE_CALLBACK(channel, s, 1, 0);
+ server->tcp_buffer_pos = 0;
+ server->tcp_socket = s;
+ server->tcp_connection_generation = ++channel->tcp_connection_generation;
+ return 0;
+}
+
+static int open_udp_socket(ares_channel channel, struct server_state *server)
+{
+ ares_socket_t s;
+ ares_socklen_t salen;
+ union {
+ struct sockaddr_in sa4;
+ struct sockaddr_in6 sa6;
+ } saddr;
+ struct sockaddr *sa;
+
+ switch (server->addr.family)
+ {
+ case AF_INET:
+ sa = (void *)&saddr.sa4;
+ salen = sizeof(saddr.sa4);
+ memset(sa, 0, salen);
+ saddr.sa4.sin_family = AF_INET;
+ saddr.sa4.sin_port = aresx_sitous(channel->udp_port);
+ memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4,
+ sizeof(server->addr.addrV4));
+ break;
+ case AF_INET6:
+ sa = (void *)&saddr.sa6;
+ salen = sizeof(saddr.sa6);
+ memset(sa, 0, salen);
+ saddr.sa6.sin6_family = AF_INET6;
+ saddr.sa6.sin6_port = aresx_sitous(channel->udp_port);
+ memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6,
+ sizeof(server->addr.addrV6));
+ break;
+ default:
+ return -1;
+ }
+
+ /* Acquire a socket. */
+ s = socket(server->addr.family, SOCK_DGRAM, 0);
+ if (s == ARES_SOCKET_BAD)
+ return -1;
+
+ /* Set the socket non-blocking. */
+ if (configure_socket(s, server->addr.family, channel) < 0)
+ {
+ sclose(s);
+ return -1;
+ }
+
+ /* Connect to the server. */
+ if (connect(s, sa, salen) == -1)
+ {
+ int err = SOCKERRNO;
+
+ if (err != EINPROGRESS && err != EWOULDBLOCK)
+ {
+ sclose(s);
+ return -1;
+ }
+ }
+
+ if (channel->sock_create_cb)
+ {
+ int err = channel->sock_create_cb(s, SOCK_DGRAM,
+ channel->sock_create_cb_data);
+ if (err < 0)
+ {
+ sclose(s);
+ return err;
+ }
+ }
+
+ SOCK_STATE_CALLBACK(channel, s, 1, 0);
+
+ server->udp_socket = s;
+ return 0;
+}
+
+static int same_questions(const unsigned char *qbuf, int qlen,
+ const unsigned char *abuf, int alen)
+{
+ struct {
+ const unsigned char *p;
+ int qdcount;
+ char *name;
+ long namelen;
+ int type;
+ int dnsclass;
+ } q, a;
+ int i, j;
+
+ if (qlen < HFIXEDSZ || alen < HFIXEDSZ)
+ return 0;
+
+ /* Extract qdcount from the request and reply buffers and compare them. */
+ q.qdcount = DNS_HEADER_QDCOUNT(qbuf);
+ a.qdcount = DNS_HEADER_QDCOUNT(abuf);
+ if (q.qdcount != a.qdcount)
+ return 0;
+
+ /* For each question in qbuf, find it in abuf. */
+ q.p = qbuf + HFIXEDSZ;
+ for (i = 0; i < q.qdcount; i++)
+ {
+ /* Decode the question in the query. */
+ if (ares_expand_name(q.p, qbuf, qlen, &q.name, &q.namelen)
+ != ARES_SUCCESS)
+ return 0;
+ q.p += q.namelen;
+ if (q.p + QFIXEDSZ > qbuf + qlen)
+ {
+ free(q.name);
+ return 0;
+ }
+ q.type = DNS_QUESTION_TYPE(q.p);
+ q.dnsclass = DNS_QUESTION_CLASS(q.p);
+ q.p += QFIXEDSZ;
+
+ /* Search for this question in the answer. */
+ a.p = abuf + HFIXEDSZ;
+ for (j = 0; j < a.qdcount; j++)
+ {
+ /* Decode the question in the answer. */
+ if (ares_expand_name(a.p, abuf, alen, &a.name, &a.namelen)
+ != ARES_SUCCESS)
+ {
+ free(q.name);
+ return 0;
+ }
+ a.p += a.namelen;
+ if (a.p + QFIXEDSZ > abuf + alen)
+ {
+ free(q.name);
+ free(a.name);
+ return 0;
+ }
+ a.type = DNS_QUESTION_TYPE(a.p);
+ a.dnsclass = DNS_QUESTION_CLASS(a.p);
+ a.p += QFIXEDSZ;
+
+ /* Compare the decoded questions. */
+ if (strcasecmp(q.name, a.name) == 0 && q.type == a.type
+ && q.dnsclass == a.dnsclass)
+ {
+ free(a.name);
+ break;
+ }
+ free(a.name);
+ }
+
+ free(q.name);
+ if (j == a.qdcount)
+ return 0;
+ }
+ return 1;
+}
+
+static int same_address(struct sockaddr *sa, struct ares_addr *aa)
+{
+ void *addr1;
+ void *addr2;
+
+ if (sa->sa_family == aa->family)
+ {
+ switch (aa->family)
+ {
+ case AF_INET:
+ addr1 = &aa->addrV4;
+ addr2 = &((struct sockaddr_in *)sa)->sin_addr;
+ if (memcmp(addr1, addr2, sizeof(aa->addrV4)) == 0)
+ return 1; /* match */
+ break;
+ case AF_INET6:
+ addr1 = &aa->addrV6;
+ addr2 = &((struct sockaddr_in6 *)sa)->sin6_addr;
+ if (memcmp(addr1, addr2, sizeof(aa->addrV6)) == 0)
+ return 1; /* match */
+ break;
+ default:
+ break;
+ }
+ }
+ return 0; /* different */
+}
+
+static void end_query (ares_channel channel, struct query *query, int status,
+ unsigned char *abuf, int alen)
+{
+ int i;
+
+ /* First we check to see if this query ended while one of our send
+ * queues still has pointers to it.
+ */
+ for (i = 0; i < channel->nservers; i++)
+ {
+ struct server_state *server = &channel->servers[i];
+ struct send_request *sendreq;
+ for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
+ if (sendreq->owner_query == query)
+ {
+ sendreq->owner_query = NULL;
+ assert(sendreq->data_storage == NULL);
+ if (status == ARES_SUCCESS)
+ {
+ /* We got a reply for this query, but this queued
+ * sendreq points into this soon-to-be-gone query's
+ * tcpbuf. Probably this means we timed out and queued
+ * the query for retransmission, then received a
+ * response before actually retransmitting. This is
+ * perfectly fine, so we want to keep the connection
+ * running smoothly if we can. But in the worst case
+ * we may have sent only some prefix of the query,
+ * with some suffix of the query left to send. Also,
+ * the buffer may be queued on multiple queues. To
+ * prevent dangling pointers to the query's tcpbuf and
+ * handle these cases, we just give such sendreqs
+ * their own copy of the query packet.
+ */
+ sendreq->data_storage = malloc(sendreq->len);
+ if (sendreq->data_storage != NULL)
+ {
+ memcpy(sendreq->data_storage, sendreq->data, sendreq->len);
+ sendreq->data = sendreq->data_storage;
+ }
+ }
+ if ((status != ARES_SUCCESS) || (sendreq->data_storage == NULL))
+ {
+ /* We encountered an error (probably a timeout,
+ * suggesting the DNS server we're talking to is
+ * probably unreachable, wedged, or severely
+ * overloaded) or we couldn't copy the request, so
+ * mark the connection as broken. When we get to
+ * process_broken_connections() we'll close the
+ * connection and try to re-send requests to another
+ * server.
+ */
+ server->is_broken = 1;
+ /* Just to be paranoid, zero out this sendreq... */
+ sendreq->data = NULL;
+ sendreq->len = 0;
+ }
+ }
+ }
+
+ /* Invoke the callback */
+ query->callback(query->arg, status, query->timeouts, abuf, alen);
+ ares__free_query(query);
+
+ /* Simple cleanup policy: if no queries are remaining, close all
+ * network sockets unless STAYOPEN is set.
+ */
+ if (!(channel->flags & ARES_FLAG_STAYOPEN) &&
+ ares__is_list_empty(&(channel->all_queries)))
+ {
+ for (i = 0; i < channel->nservers; i++)
+ ares__close_sockets(channel, &channel->servers[i]);
+ }
+}
+
+void ares__free_query(struct query *query)
+{
+ /* Remove the query from all the lists in which it is linked */
+ ares__remove_from_list(&(query->queries_by_qid));
+ ares__remove_from_list(&(query->queries_by_timeout));
+ ares__remove_from_list(&(query->queries_to_server));
+ ares__remove_from_list(&(query->all_queries));
+ /* Zero out some important stuff, to help catch bugs */
+ query->callback = NULL;
+ query->arg = NULL;
+ /* Deallocate the memory associated with the query */
+ free(query->tcpbuf);
+ free(query->server_info);
+ free(query);
+}
diff --git a/deps/uv/src/ares/ares_query.c b/deps/cares/src/ares_query.c
index 63652e229..63652e229 100644
--- a/deps/uv/src/ares/ares_query.c
+++ b/deps/cares/src/ares_query.c
diff --git a/deps/uv/src/ares/ares_rules.h b/deps/cares/src/ares_rules.h
index f94c5b591..f94c5b591 100644
--- a/deps/uv/src/ares/ares_rules.h
+++ b/deps/cares/src/ares_rules.h
diff --git a/deps/uv/src/ares/ares_search.c b/deps/cares/src/ares_search.c
index 1877c19f7..1877c19f7 100644
--- a/deps/uv/src/ares/ares_search.c
+++ b/deps/cares/src/ares_search.c
diff --git a/deps/cares/src/ares_send.c b/deps/cares/src/ares_send.c
new file mode 100644
index 000000000..75a84f687
--- /dev/null
+++ b/deps/cares/src/ares_send.c
@@ -0,0 +1,134 @@
+
+/* 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
+ ares_callback callback, void *arg)
+{
+ struct query *query;
+ int i;
+ struct timeval now;
+
+ /* Verify that the query is at least long enough to hold the header. */
+ if (qlen < HFIXEDSZ || qlen >= (1 << 16))
+ {
+ callback(arg, ARES_EBADQUERY, 0, NULL, 0);
+ return;
+ }
+
+ /* Allocate space for query and allocated fields. */
+ query = malloc(sizeof(struct query));
+ if (!query)
+ {
+ callback(arg, ARES_ENOMEM, 0, NULL, 0);
+ return;
+ }
+ query->tcpbuf = malloc(qlen + 2);
+ if (!query->tcpbuf)
+ {
+ free(query);
+ callback(arg, ARES_ENOMEM, 0, NULL, 0);
+ return;
+ }
+ query->server_info = malloc(channel->nservers *
+ sizeof(query->server_info[0]));
+ if (!query->server_info)
+ {
+ free(query->tcpbuf);
+ free(query);
+ callback(arg, ARES_ENOMEM, 0, NULL, 0);
+ return;
+ }
+
+ /* Compute the query ID. Start with no timeout. */
+ query->qid = DNS_HEADER_QID(qbuf);
+ query->timeout.tv_sec = 0;
+ query->timeout.tv_usec = 0;
+
+ /* Form the TCP query buffer by prepending qlen (as two
+ * network-order bytes) to qbuf.
+ */
+ query->tcpbuf[0] = (unsigned char)((qlen >> 8) & 0xff);
+ query->tcpbuf[1] = (unsigned char)(qlen & 0xff);
+ memcpy(query->tcpbuf + 2, qbuf, qlen);
+ query->tcplen = qlen + 2;
+
+ /* Fill in query arguments. */
+ query->qbuf = query->tcpbuf + 2;
+ query->qlen = qlen;
+ query->callback = callback;
+ query->arg = arg;
+
+ /* Initialize query status. */
+ query->try_count = 0;
+
+ /* Choose the server to send the query to. If rotation is enabled, keep track
+ * of the next server we want to use. */
+ query->server = channel->last_server;
+ if (channel->rotate == 1)
+ channel->last_server = (channel->last_server + 1) % channel->nservers;
+
+ for (i = 0; i < channel->nservers; i++)
+ {
+ query->server_info[i].skip_server = 0;
+ query->server_info[i].tcp_connection_generation = 0;
+ }
+ query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > PACKETSZ;
+ query->error_status = ARES_ECONNREFUSED;
+ query->timeouts = 0;
+
+ /* Initialize our list nodes. */
+ ares__init_list_node(&(query->queries_by_qid), query);
+ ares__init_list_node(&(query->queries_by_timeout), query);
+ ares__init_list_node(&(query->queries_to_server), query);
+ ares__init_list_node(&(query->all_queries), query);
+
+ /* Chain the query into the list of all queries. */
+ ares__insert_in_list(&(query->all_queries), &(channel->all_queries));
+ /* Keep track of queries bucketed by qid, so we can process DNS
+ * responses quickly.
+ */
+ ares__insert_in_list(
+ &(query->queries_by_qid),
+ &(channel->queries_by_qid[query->qid % ARES_QID_TABLE_SIZE]));
+
+ /* Perform the first query action. */
+ now = ares__tvnow();
+ ares__send_query(channel, query, &now);
+}
diff --git a/deps/cares/src/ares_setup.h b/deps/cares/src/ares_setup.h
new file mode 100644
index 000000000..18e14557c
--- /dev/null
+++ b/deps/cares/src/ares_setup.h
@@ -0,0 +1,221 @@
+#ifndef HEADER_CARES_SETUP_H
+#define HEADER_CARES_SETUP_H
+
+
+/* Copyright (C) 2004 - 2012 by Daniel Stenberg et al
+ *
+ * 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.
+ */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#define WIN32
+#endif
+
+/*
+ * Include configuration script results or hand-crafted
+ * configuration file for platforms which lack config tool.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "ares_config.h"
+#else
+
+#ifdef WIN32
+#include "config-win32.h"
+#endif
+
+#endif /* HAVE_CONFIG_H */
+
+/* ================================================================ */
+/* Definition of preprocessor macros/symbols which modify compiler */
+/* behaviour or generated code characteristics must be done here, */
+/* as appropriate, before any system header file is included. It is */
+/* also possible to have them defined in the config file included */
+/* before this point. As a result of all this we frown inclusion of */
+/* system header files in our config files, avoid this at any cost. */
+/* ================================================================ */
+
+/*
+ * AIX 4.3 and newer needs _THREAD_SAFE defined to build
+ * proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_THREAD_SAFE
+# ifndef _THREAD_SAFE
+# define _THREAD_SAFE
+# endif
+#endif
+
+/*
+ * Tru64 needs _REENTRANT set for a few function prototypes and
+ * things to appear in the system header files. Unixware needs it
+ * to build proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_REENTRANT
+# ifndef _REENTRANT
+# define _REENTRANT
+# endif
+#endif
+
+/* ================================================================ */
+/* If you need to include a system header file for your platform, */
+/* please, do it beyond the point further indicated in this file. */
+/* ================================================================ */
+
+#if 1 /* libuv hack */
+#include <errno.h> /* needed on windows */
+#else
+/*
+ * c-ares external interface definitions are also used internally,
+ * and might also include required system header files to define them.
+ */
+
+#include <ares_build.h>
+
+/*
+ * Compile time sanity checks must also be done when building the library.
+ */
+
+#include <ares_rules.h>
+#endif /* libuv hack */
+
+/* ================================================================= */
+/* No system header file shall be included in this file before this */
+/* point. The only allowed ones are those included from ares_build.h */
+/* ================================================================= */
+
+/*
+ * Include header files for windows builds before redefining anything.
+ * Use this preproessor block only to include or exclude windows.h,
+ * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
+ * to any other further and independent block. Under Cygwin things work
+ * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
+ * never be included when __CYGWIN__ is defined. configure script takes
+ * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
+ * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
+ */
+
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+# ifdef HAVE_WS2TCPIP_H
+# include <ws2tcpip.h>
+# endif
+# else
+# ifdef HAVE_WINSOCK_H
+# include <winsock.h>
+# endif
+# endif
+#endif
+
+/*
+ * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
+ * define USE_WINSOCK to 1 if we have and use WINSOCK API, else
+ * undefine USE_WINSOCK.
+ */
+
+#undef USE_WINSOCK
+
+#ifdef HAVE_WINSOCK2_H
+# define USE_WINSOCK 2
+#else
+# ifdef HAVE_WINSOCK_H
+# define USE_WINSOCK 1
+# endif
+#endif
+
+/*
+ * Work-arounds for systems without configure support
+ */
+
+#ifndef HAVE_CONFIG_H
+
+#if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER) && !defined(__WATCOMC__)
+#define HAVE_SYS_TIME_H
+#endif
+
+#if !defined(HAVE_UNISTD_H) && !defined(_MSC_VER)
+#define HAVE_UNISTD_H 1
+#endif
+
+#if !defined(HAVE_SYS_UIO_H) && !defined(WIN32) && !defined(MSDOS)
+#define HAVE_SYS_UIO_H
+#endif
+
+#endif /* HAVE_CONFIG_H */
+
+/*
+ * Arg 2 type for gethostname in case it hasn't been defined in config file.
+ */
+
+#ifndef GETHOSTNAME_TYPE_ARG2
+# ifdef USE_WINSOCK
+# define GETHOSTNAME_TYPE_ARG2 int
+# else
+# define GETHOSTNAME_TYPE_ARG2 size_t
+# endif
+#endif
+
+#ifdef __POCC__
+# include <sys/types.h>
+# include <unistd.h>
+# define ESRCH 3
+#endif
+
+/*
+ * Android does have the arpa/nameser.h header which is detected by configure
+ * but it appears to be empty with recent NDK r7b / r7c, so we undefine here.
+ */
+#if (defined(ANDROID) || defined(__ANDROID__)) && defined(HAVE_ARPA_NAMESER_H)
+# undef HAVE_ARPA_NAMESER_H
+#endif
+
+/*
+ * Recent autoconf versions define these symbols in ares_config.h. We don't
+ * want them (since they collide with the libcurl ones when we build
+ * --enable-debug) so we undef them again here.
+ */
+
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef VERSION
+#undef PACKAGE
+
+/* IPv6 compatibility */
+#if !defined(HAVE_AF_INET6)
+#if defined(HAVE_PF_INET6)
+#define AF_INET6 PF_INET6
+#else
+#define AF_INET6 AF_MAX+1
+#endif
+#endif
+
+/*
+ * Include macros and defines that should only be processed once.
+ */
+
+#ifndef __SETUP_ONCE_H
+#include "setup_once.h"
+#endif
+
+#endif /* HEADER_CARES_SETUP_H */
diff --git a/deps/uv/src/ares/ares_strcasecmp.c b/deps/cares/src/ares_strcasecmp.c
index f9c85e209..f9c85e209 100644
--- a/deps/uv/src/ares/ares_strcasecmp.c
+++ b/deps/cares/src/ares_strcasecmp.c
diff --git a/deps/uv/src/ares/ares_strcasecmp.h b/deps/cares/src/ares_strcasecmp.h
index 57d86f963..57d86f963 100644
--- a/deps/uv/src/ares/ares_strcasecmp.h
+++ b/deps/cares/src/ares_strcasecmp.h
diff --git a/deps/uv/src/ares/ares_strdup.c b/deps/cares/src/ares_strdup.c
index 18043274e..18043274e 100644
--- a/deps/uv/src/ares/ares_strdup.c
+++ b/deps/cares/src/ares_strdup.c
diff --git a/deps/uv/src/ares/ares_strdup.h b/deps/cares/src/ares_strdup.h
index c413a941c..c413a941c 100644
--- a/deps/uv/src/ares/ares_strdup.h
+++ b/deps/cares/src/ares_strdup.h
diff --git a/deps/uv/src/ares/ares_strerror.c b/deps/cares/src/ares_strerror.c
index c3ecbd7b4..c3ecbd7b4 100644
--- a/deps/uv/src/ares/ares_strerror.c
+++ b/deps/cares/src/ares_strerror.c
diff --git a/deps/cares/src/ares_timeout.c b/deps/cares/src/ares_timeout.c
new file mode 100644
index 000000000..738ad1528
--- /dev/null
+++ b/deps/cares/src/ares_timeout.c
@@ -0,0 +1,81 @@
+
+/* 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include <time.h>
+
+#include "ares.h"
+#include "ares_private.h"
+
+/* WARNING: Beware that this is linear in the number of outstanding
+ * requests! You are probably far better off just calling ares_process()
+ * once per second, rather than calling ares_timeout() to figure out
+ * when to next call ares_process().
+ */
+struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
+ struct timeval *tvbuf)
+{
+ struct query *query;
+ struct list_node* list_head;
+ struct list_node* list_node;
+ struct timeval now;
+ struct timeval nextstop;
+ long offset, min_offset;
+
+ /* No queries, no timeout (and no fetch of the current time). */
+ if (ares__is_list_empty(&(channel->all_queries)))
+ return maxtv;
+
+ /* Find the minimum timeout for the current set of queries. */
+ now = ares__tvnow();
+ min_offset = -1;
+
+ list_head = &(channel->all_queries);
+ for (list_node = list_head->next; list_node != list_head;
+ list_node = list_node->next)
+ {
+ query = list_node->data;
+ if (query->timeout.tv_sec == 0)
+ continue;
+ offset = ares__timeoffset(&now, &query->timeout);
+ if (offset < 0)
+ offset = 0;
+ if (min_offset == -1 || offset < min_offset)
+ min_offset = offset;
+ }
+
+ /* If we found a minimum timeout and it's sooner than the one specified in
+ * maxtv (if any), return it. Otherwise go with maxtv.
+ */
+ if (min_offset != -1)
+ {
+ nextstop.tv_sec = min_offset/1000;
+ nextstop.tv_usec = (min_offset%1000)*1000;
+
+ if (!maxtv || ares__timedout(maxtv, &nextstop))
+ {
+ *tvbuf = nextstop;
+ return tvbuf;
+ }
+ }
+
+ return maxtv;
+}
diff --git a/deps/uv/src/ares/ares_version.c b/deps/cares/src/ares_version.c
index 4f8c42f2c..4f8c42f2c 100644
--- a/deps/uv/src/ares/ares_version.c
+++ b/deps/cares/src/ares_version.c
diff --git a/deps/uv/src/ares/ares_writev.c b/deps/cares/src/ares_writev.c
index 9e8e2d657..9e8e2d657 100644
--- a/deps/uv/src/ares/ares_writev.c
+++ b/deps/cares/src/ares_writev.c
diff --git a/deps/uv/src/ares/ares_writev.h b/deps/cares/src/ares_writev.h
index 1a23a0f3d..1a23a0f3d 100644
--- a/deps/uv/src/ares/ares_writev.h
+++ b/deps/cares/src/ares_writev.h
diff --git a/deps/uv/src/ares/bitncmp.c b/deps/cares/src/bitncmp.c
index 5c89506b3..5c89506b3 100644
--- a/deps/uv/src/ares/bitncmp.c
+++ b/deps/cares/src/bitncmp.c
diff --git a/deps/uv/src/ares/bitncmp.h b/deps/cares/src/bitncmp.h
index b0a5c812b..b0a5c812b 100644
--- a/deps/uv/src/ares/bitncmp.h
+++ b/deps/cares/src/bitncmp.h
diff --git a/deps/uv/src/ares/get_ver.awk b/deps/cares/src/get_ver.awk
index a63c729a9..a63c729a9 100644
--- a/deps/uv/src/ares/get_ver.awk
+++ b/deps/cares/src/get_ver.awk
diff --git a/deps/uv/src/ares/inet_net_pton.c b/deps/cares/src/inet_net_pton.c
index 45bb5d48f..45bb5d48f 100644
--- a/deps/uv/src/ares/inet_net_pton.c
+++ b/deps/cares/src/inet_net_pton.c
diff --git a/deps/uv/src/ares/inet_net_pton.h b/deps/cares/src/inet_net_pton.h
index 5396a7f2a..5396a7f2a 100644
--- a/deps/uv/src/ares/inet_net_pton.h
+++ b/deps/cares/src/inet_net_pton.h
diff --git a/deps/uv/src/ares/inet_ntop.c b/deps/cares/src/inet_ntop.c
index 57e1146b7..57e1146b7 100644
--- a/deps/uv/src/ares/inet_ntop.c
+++ b/deps/cares/src/inet_ntop.c
diff --git a/deps/uv/src/ares/inet_ntop.h b/deps/cares/src/inet_ntop.h
index c583488f7..c583488f7 100644
--- a/deps/uv/src/ares/inet_ntop.h
+++ b/deps/cares/src/inet_ntop.h
diff --git a/deps/cares/src/setup_once.h b/deps/cares/src/setup_once.h
new file mode 100644
index 000000000..fc630ef27
--- /dev/null
+++ b/deps/cares/src/setup_once.h
@@ -0,0 +1,512 @@
+#ifndef __SETUP_ONCE_H
+#define __SETUP_ONCE_H
+
+
+/* Copyright (C) 2004 - 2012 by Daniel Stenberg et al
+ *
+ * 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.
+ */
+
+
+/********************************************************************
+ * NOTICE *
+ * ======== *
+ * *
+ * Content of header files lib/setup_once.h and ares/setup_once.h *
+ * must be kept in sync. Modify the other one if you change this. *
+ * *
+ ********************************************************************/
+
+
+/*
+ * Inclusion of common header files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef NEED_MALLOC_H
+#include <malloc.h>
+#endif
+
+#ifdef NEED_MEMORY_H
+#include <memory.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+#else
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#endif
+
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#if defined(HAVE_STDBOOL_H) && defined(HAVE_BOOL_T)
+#include <stdbool.h>
+#endif
+
+
+/*
+ * Definition of timeval struct for platforms that don't have it.
+ */
+
+#ifndef HAVE_STRUCT_TIMEVAL
+struct timeval {
+ long tv_sec;
+ long tv_usec;
+};
+#endif
+
+
+/*
+ * If we have the MSG_NOSIGNAL define, make sure we use
+ * it as the fourth argument of function send()
+ */
+
+#ifdef HAVE_MSG_NOSIGNAL
+#define SEND_4TH_ARG MSG_NOSIGNAL
+#else
+#define SEND_4TH_ARG 0
+#endif
+
+
+#if defined(__minix)
+/* Minix doesn't support recv on TCP sockets */
+#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
+ (RECV_TYPE_ARG2)(y), \
+ (RECV_TYPE_ARG3)(z))
+
+#elif defined(HAVE_RECV)
+/*
+ * The definitions for the return type and arguments types
+ * of functions recv() and send() belong and come from the
+ * configuration file. Do not define them in any other place.
+ *
+ * HAVE_RECV is defined if you have a function named recv()
+ * which is used to read incoming data from sockets. If your
+ * function has another name then don't define HAVE_RECV.
+ *
+ * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
+ * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
+ * be defined.
+ *
+ * HAVE_SEND is defined if you have a function named send()
+ * which is used to write outgoing data on a connected socket.
+ * If yours has another name then don't define HAVE_SEND.
+ *
+ * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
+ * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
+ * SEND_TYPE_RETV must also be defined.
+ */
+
+#if !defined(RECV_TYPE_ARG1) || \
+ !defined(RECV_TYPE_ARG2) || \
+ !defined(RECV_TYPE_ARG3) || \
+ !defined(RECV_TYPE_ARG4) || \
+ !defined(RECV_TYPE_RETV)
+ /* */
+ Error Missing_definition_of_return_and_arguments_types_of_recv
+ /* */
+#else
+#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
+ (RECV_TYPE_ARG2)(y), \
+ (RECV_TYPE_ARG3)(z), \
+ (RECV_TYPE_ARG4)(0))
+#endif
+#else /* HAVE_RECV */
+#ifndef sread
+ /* */
+ Error Missing_definition_of_macro_sread
+ /* */
+#endif
+#endif /* HAVE_RECV */
+
+
+#if defined(__minix)
+/* Minix doesn't support send on TCP sockets */
+#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
+ (SEND_TYPE_ARG2)(y), \
+ (SEND_TYPE_ARG3)(z))
+
+#elif defined(HAVE_SEND)
+#if !defined(SEND_TYPE_ARG1) || \
+ !defined(SEND_QUAL_ARG2) || \
+ !defined(SEND_TYPE_ARG2) || \
+ !defined(SEND_TYPE_ARG3) || \
+ !defined(SEND_TYPE_ARG4) || \
+ !defined(SEND_TYPE_RETV)
+ /* */
+ Error Missing_definition_of_return_and_arguments_types_of_send
+ /* */
+#else
+#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
+ (SEND_TYPE_ARG2)(y), \
+ (SEND_TYPE_ARG3)(z), \
+ (SEND_TYPE_ARG4)(SEND_4TH_ARG))
+#endif
+#else /* HAVE_SEND */
+#ifndef swrite
+ /* */
+ Error Missing_definition_of_macro_swrite
+ /* */
+#endif
+#endif /* HAVE_SEND */
+
+
+#if 0
+#if defined(HAVE_RECVFROM)
+/*
+ * Currently recvfrom is only used on udp sockets.
+ */
+#if !defined(RECVFROM_TYPE_ARG1) || \
+ !defined(RECVFROM_TYPE_ARG2) || \
+ !defined(RECVFROM_TYPE_ARG3) || \
+ !defined(RECVFROM_TYPE_ARG4) || \
+ !defined(RECVFROM_TYPE_ARG5) || \
+ !defined(RECVFROM_TYPE_ARG6) || \
+ !defined(RECVFROM_TYPE_RETV)
+ /* */
+ Error Missing_definition_of_return_and_arguments_types_of_recvfrom
+ /* */
+#else
+#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \
+ (RECVFROM_TYPE_ARG2 *)(b), \
+ (RECVFROM_TYPE_ARG3) (bl), \
+ (RECVFROM_TYPE_ARG4) (0), \
+ (RECVFROM_TYPE_ARG5 *)(f), \
+ (RECVFROM_TYPE_ARG6 *)(fl))
+#endif
+#else /* HAVE_RECVFROM */
+#ifndef sreadfrom
+ /* */
+ Error Missing_definition_of_macro_sreadfrom
+ /* */
+#endif
+#endif /* HAVE_RECVFROM */
+
+
+#ifdef RECVFROM_TYPE_ARG6_IS_VOID
+# define RECVFROM_ARG6_T int
+#else
+# define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6
+#endif
+#endif /* if 0 */
+
+
+/*
+ * Function-like macro definition used to close a socket.
+ */
+
+#if defined(HAVE_CLOSESOCKET)
+# define sclose(x) closesocket((x))
+#elif defined(HAVE_CLOSESOCKET_CAMEL)
+# define sclose(x) CloseSocket((x))
+#else
+# define sclose(x) close((x))
+#endif
+
+
+/*
+ * Uppercase macro versions of ANSI/ISO is*() functions/macros which
+ * avoid negative number inputs with argument byte codes > 127.
+ */
+
+#define ISSPACE(x) (isspace((int) ((unsigned char)x)))
+#define ISDIGIT(x) (isdigit((int) ((unsigned char)x)))
+#define ISALNUM(x) (isalnum((int) ((unsigned char)x)))
+#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
+#define ISGRAPH(x) (isgraph((int) ((unsigned char)x)))
+#define ISALPHA(x) (isalpha((int) ((unsigned char)x)))
+#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
+#define ISUPPER(x) (isupper((int) ((unsigned char)x)))
+#define ISLOWER(x) (islower((int) ((unsigned char)x)))
+#define ISASCII(x) (isascii((int) ((unsigned char)x)))
+
+#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \
+ (((unsigned char)x) == '\t'))
+
+#define TOLOWER(x) (tolower((int) ((unsigned char)x)))
+
+
+/*
+ * 'bool' exists on platforms with <stdbool.h>, i.e. C99 platforms.
+ * On non-C99 platforms there's no bool, so define an enum for that.
+ * On C99 platforms 'false' and 'true' also exist. Enum uses a
+ * global namespace though, so use bool_false and bool_true.
+ */
+
+#ifndef HAVE_BOOL_T
+ typedef enum {
+ bool_false = 0,
+ bool_true = 1
+ } bool;
+
+/*
+ * Use a define to let 'true' and 'false' use those enums. There
+ * are currently no use of true and false in libcurl proper, but
+ * there are some in the examples. This will cater for any later
+ * code happening to use true and false.
+ */
+# define false bool_false
+# define true bool_true
+# define HAVE_BOOL_T
+#endif
+
+
+/*
+ * Redefine TRUE and FALSE too, to catch current use. With this
+ * change, 'bool found = 1' will give a warning on MIPSPro, but
+ * 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro,
+ * AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too.
+ */
+
+#ifndef TRUE
+#define TRUE true
+#endif
+#ifndef FALSE
+#define FALSE false
+#endif
+
+
+/*
+ * Macro WHILE_FALSE may be used to build single-iteration do-while loops,
+ * avoiding compiler warnings. Mostly intended for other macro definitions.
+ */
+
+#define WHILE_FALSE while(0)
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+# undef WHILE_FALSE
+# if (_MSC_VER < 1500)
+# define WHILE_FALSE while(1, 0)
+# else
+# define WHILE_FALSE \
+__pragma(warning(push)) \
+__pragma(warning(disable:4127)) \
+while(0) \
+__pragma(warning(pop))
+# endif
+#endif
+
+
+/*
+ * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
+ */
+
+#ifndef HAVE_SIG_ATOMIC_T
+typedef int sig_atomic_t;
+#define HAVE_SIG_ATOMIC_T
+#endif
+
+
+/*
+ * Convenience SIG_ATOMIC_T definition
+ */
+
+#ifdef HAVE_SIG_ATOMIC_T_VOLATILE
+#define SIG_ATOMIC_T static sig_atomic_t
+#else
+#define SIG_ATOMIC_T static volatile sig_atomic_t
+#endif
+
+
+/*
+ * Default return type for signal handlers.
+ */
+
+#ifndef RETSIGTYPE
+#define RETSIGTYPE void
+#endif
+
+
+/*
+ * Macro used to include code only in debug builds.
+ */
+
+#ifdef DEBUGBUILD
+#define DEBUGF(x) x
+#else
+#define DEBUGF(x) do { } WHILE_FALSE
+#endif
+
+
+/*
+ * Macro used to include assertion code only in debug builds.
+ */
+
+#if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H)
+#define DEBUGASSERT(x) assert(x)
+#else
+#define DEBUGASSERT(x) do { } WHILE_FALSE
+#endif
+
+
+/*
+ * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno
+ * (or equivalent) on this platform to hide platform details to code using it.
+ */
+
+#ifdef USE_WINSOCK
+#define SOCKERRNO ((int)WSAGetLastError())
+#define SET_SOCKERRNO(x) (WSASetLastError((int)(x)))
+#else
+#define SOCKERRNO (errno)
+#define SET_SOCKERRNO(x) (errno = (x))
+#endif
+
+
+/*
+ * Macro ERRNO / SET_ERRNO() returns / sets the NOT *socket-related* errno
+ * (or equivalent) on this platform to hide platform details to code using it.
+ */
+
+#if defined(WIN32) && !defined(WATT32)
+#define ERRNO ((int)GetLastError())
+#define SET_ERRNO(x) (SetLastError((DWORD)(x)))
+#else
+#define ERRNO (errno)
+#define SET_ERRNO(x) (errno = (x))
+#endif
+
+
+/*
+ * Portable error number symbolic names defined to Winsock error codes.
+ */
+
+#ifdef USE_WINSOCK
+#undef EBADF /* override definition in errno.h */
+#define EBADF WSAEBADF
+#undef EINTR /* override definition in errno.h */
+#define EINTR WSAEINTR
+#undef EINVAL /* override definition in errno.h */
+#define EINVAL WSAEINVAL
+#undef EWOULDBLOCK /* override definition in errno.h */
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#undef EINPROGRESS /* override definition in errno.h */
+#define EINPROGRESS WSAEINPROGRESS
+#undef EALREADY /* override definition in errno.h */
+#define EALREADY WSAEALREADY
+#undef ENOTSOCK /* override definition in errno.h */
+#define ENOTSOCK WSAENOTSOCK
+#undef EDESTADDRREQ /* override definition in errno.h */
+#define EDESTADDRREQ WSAEDESTADDRREQ
+#undef EMSGSIZE /* override definition in errno.h */
+#define EMSGSIZE WSAEMSGSIZE
+#undef EPROTOTYPE /* override definition in errno.h */
+#define EPROTOTYPE WSAEPROTOTYPE
+#undef ENOPROTOOPT /* override definition in errno.h */
+#define ENOPROTOOPT WSAENOPROTOOPT
+#undef EPROTONOSUPPORT /* override definition in errno.h */
+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
+#undef EOPNOTSUPP /* override definition in errno.h */
+#define EOPNOTSUPP WSAEOPNOTSUPP
+#define EPFNOSUPPORT WSAEPFNOSUPPORT
+#undef EAFNOSUPPORT /* override definition in errno.h */
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#undef EADDRINUSE /* override definition in errno.h */
+#define EADDRINUSE WSAEADDRINUSE
+#undef EADDRNOTAVAIL /* override definition in errno.h */
+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#undef ENETDOWN /* override definition in errno.h */
+#define ENETDOWN WSAENETDOWN
+#undef ENETUNREACH /* override definition in errno.h */
+#define ENETUNREACH WSAENETUNREACH
+#undef ENETRESET /* override definition in errno.h */
+#define ENETRESET WSAENETRESET
+#undef ECONNABORTED /* override definition in errno.h */
+#define ECONNABORTED WSAECONNABORTED
+#undef ECONNRESET /* override definition in errno.h */
+#define ECONNRESET WSAECONNRESET
+#undef ENOBUFS /* override definition in errno.h */
+#define ENOBUFS WSAENOBUFS
+#undef EISCONN /* override definition in errno.h */
+#define EISCONN WSAEISCONN
+#undef ENOTCONN /* override definition in errno.h */
+#define ENOTCONN WSAENOTCONN
+#define ESHUTDOWN WSAESHUTDOWN
+#define ETOOMANYREFS WSAETOOMANYREFS
+#undef ETIMEDOUT /* override definition in errno.h */
+#define ETIMEDOUT WSAETIMEDOUT
+#undef ECONNREFUSED /* override definition in errno.h */
+#define ECONNREFUSED WSAECONNREFUSED
+#undef ELOOP /* override definition in errno.h */
+#define ELOOP WSAELOOP
+#ifndef ENAMETOOLONG /* possible previous definition in errno.h */
+#define ENAMETOOLONG WSAENAMETOOLONG
+#endif
+#define EHOSTDOWN WSAEHOSTDOWN
+#undef EHOSTUNREACH /* override definition in errno.h */
+#define EHOSTUNREACH WSAEHOSTUNREACH
+#ifndef ENOTEMPTY /* possible previous definition in errno.h */
+#define ENOTEMPTY WSAENOTEMPTY
+#endif
+#define EPROCLIM WSAEPROCLIM
+#define EUSERS WSAEUSERS
+#define EDQUOT WSAEDQUOT
+#define ESTALE WSAESTALE
+#define EREMOTE WSAEREMOTE
+#endif
+
+
+/*
+ * Actually use __32_getpwuid() on 64-bit VMS builds for getpwuid()
+ */
+
+#if defined(__VMS) && \
+ defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
+#define getpwuid __32_getpwuid
+#endif
+
+
+/*
+ * Macro argv_item_t hides platform details to code using it.
+ */
+
+#ifdef __VMS
+#define argv_item_t __char_ptr32
+#else
+#define argv_item_t char *
+#endif
+
+
+/*
+ * We use this ZERO_NULL to avoid picky compiler warnings,
+ * when assigning a NULL pointer to a function pointer var.
+ */
+
+#define ZERO_NULL 0
+
+
+#endif /* __SETUP_ONCE_H */
diff --git a/deps/uv/src/ares/windows_port.c b/deps/cares/src/windows_port.c
index 03acd1c1e..03acd1c1e 100644
--- a/deps/uv/src/ares/windows_port.c
+++ b/deps/cares/src/windows_port.c
diff --git a/deps/http_parser/.gitignore b/deps/http_parser/.gitignore
index cfadcbe0a..3b868c507 100644
--- a/deps/http_parser/.gitignore
+++ b/deps/http_parser/.gitignore
@@ -4,5 +4,8 @@ tags
test
test_g
test_fast
+url_parser
*.mk
*.Makefile
+*.so
+*.a
diff --git a/deps/http_parser/.mailmap b/deps/http_parser/.mailmap
index c25ea8692..c73c0f93e 100644
--- a/deps/http_parser/.mailmap
+++ b/deps/http_parser/.mailmap
@@ -2,3 +2,4 @@
# git log --all --reverse --format='%aN <%aE>' | perl -ne 'BEGIN{print "# Authors ordered by first contribution.\n"} print unless $h{$_}; $h{$_} = 1' > AUTHORS
Ryan Dahl <ry@tinyclouds.org>
Salman Haq <salman.haq@asti-usa.com>
+Simon Zimmermann <simonz05@gmail.com>
diff --git a/deps/http_parser/AUTHORS b/deps/http_parser/AUTHORS
index abe99dee4..c0d2fe4d5 100644
--- a/deps/http_parser/AUTHORS
+++ b/deps/http_parser/AUTHORS
@@ -30,3 +30,8 @@ James McLaughlin <jamie@lacewing-project.org>
David Gwynne <loki@animata.net>
LE ROUX Thomas <thomas@procheo.fr>
Randy Rizun <rrizun@ortivawireless.com>
+Andre Louis Caron <andre.louis.caron@usherbrooke.ca>
+Simon Zimmermann <simonz05@gmail.com>
+Erik Dubbelboer <erik@dubbelboer.com>
+Martell Malone <martellmalone@gmail.com>
+Bertrand Paquet <bpaquet@octo.com>
diff --git a/deps/http_parser/Makefile b/deps/http_parser/Makefile
index 8d90f8ddd..d9bf839b2 100644
--- a/deps/http_parser/Makefile
+++ b/deps/http_parser/Makefile
@@ -31,6 +31,12 @@ test_fast: http_parser.o test.o http_parser.h
test.o: test.c http_parser.h Makefile
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -c test.c -o $@
+url_parser: http_parser_g.o url_parser.o
+ $(CC) $(CFLAGS_DEBUG) $(LDFLAGS) http_parser_g.o url_parser.o -o $@
+
+url_parser.o: url_parser.c http_parser.h Makefile
+ $(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) -c url_parser.c -o $@
+
http_parser.o: http_parser.c http_parser.h Makefile
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -c http_parser.c
@@ -53,6 +59,6 @@ tags: http_parser.c http_parser.h test.c
ctags $^
clean:
- rm -f *.o *.a test test_fast test_g http_parser.tar tags libhttp_parser.so libhttp_parser.o
+ rm -f *.o *.a test test_fast test_g url_parser http_parser.tar tags libhttp_parser.so libhttp_parser.o
.PHONY: clean package test-run test-run-timed test-valgrind
diff --git a/deps/http_parser/http_parser.c b/deps/http_parser/http_parser.c
index acd41307f..5e0a950a6 100644
--- a/deps/http_parser/http_parser.c
+++ b/deps/http_parser/http_parser.c
@@ -37,6 +37,19 @@
# define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#endif
+
+#ifndef BIT_AT
+# define BIT_AT(a, i) \
+ (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \
+ (1 << ((unsigned int) (i) & 7))))
+#endif
+
+#ifndef ELEM_AT
+# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v))
+#endif
#if HTTP_PARSER_DEBUG
#define SET_ERRNO(e) \
@@ -184,40 +197,48 @@ static const int8_t unhex[256] =
};
-static const uint8_t normal_url_char[256] = {
+#if HTTP_PARSER_STRICT
+# define T(v) 0
+#else
+# define T(v) v
+#endif
+
+
+static const uint8_t normal_url_char[32] = {
/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0,
/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0,
/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0,
/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0,
/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
- 0, 1, 1, 0, 1, 1, 1, 1,
+ 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128,
/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
- 1, 1, 1, 1, 1, 1, 1, 1,
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
- 1, 1, 1, 1, 1, 1, 1, 1,
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
- 1, 1, 1, 1, 1, 1, 1, 0,
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0,
/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */
- 1, 1, 1, 1, 1, 1, 1, 1,
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */
- 1, 1, 1, 1, 1, 1, 1, 1,
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */
- 1, 1, 1, 1, 1, 1, 1, 1,
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
- 1, 1, 1, 1, 1, 1, 1, 1,
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
- 1, 1, 1, 1, 1, 1, 1, 1,
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
- 1, 1, 1, 1, 1, 1, 1, 1,
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
- 1, 1, 1, 1, 1, 1, 1, 1,
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
- 1, 1, 1, 1, 1, 1, 1, 0, };
+ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, };
+#undef T
enum state
{ s_dead = 1 /* important that this is > 0 */
@@ -245,13 +266,9 @@ enum state
, s_req_schema
, s_req_schema_slash
, s_req_schema_slash_slash
- , s_req_host_start
- , s_req_host_v6_start
- , s_req_host_v6
- , s_req_host_v6_end
- , s_req_host
- , s_req_port_start
- , s_req_port
+ , s_req_server_start
+ , s_req_server
+ , s_req_server_with_at
, s_req_path
, s_req_query_string_start
, s_req_query_string
@@ -329,6 +346,19 @@ enum header_states
, h_connection_close
};
+enum http_host_state
+ {
+ s_http_host_dead = 1
+ , s_http_userinfo_start
+ , s_http_userinfo
+ , s_http_host_start
+ , s_http_host_v6_start
+ , s_http_host
+ , s_http_host_v6
+ , s_http_host_v6_end
+ , s_http_host_port_start
+ , s_http_host_port
+};
/* Macros for character classes; depends on strict-mode */
#define CR '\r'
@@ -338,15 +368,21 @@ enum header_states
#define IS_NUM(c) ((c) >= '0' && (c) <= '9')
#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c))
#define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f'))
+#define IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \
+ (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \
+ (c) == ')')
+#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \
+ (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \
+ (c) == '$' || (c) == ',')
#if HTTP_PARSER_STRICT
#define TOKEN(c) (tokens[(unsigned char)c])
-#define IS_URL_CHAR(c) (normal_url_char[(unsigned char) (c)])
+#define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c))
#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
#else
#define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c])
#define IS_URL_CHAR(c) \
- (normal_url_char[(unsigned char) (c)] || ((c) & 0x80))
+ (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80))
#define IS_HOST_CHAR(c) \
(IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')
#endif
@@ -380,7 +416,7 @@ static struct {
};
#undef HTTP_STRERROR_GEN
-int http_message_needs_eof(http_parser *parser);
+int http_message_needs_eof(const http_parser *parser);
/* Our URL parser.
*
@@ -396,7 +432,15 @@ int http_message_needs_eof(http_parser *parser);
static enum state
parse_url_char(enum state s, const char ch)
{
- assert(!isspace(ch));
+ if (ch == ' ' || ch == '\r' || ch == '\n') {
+ return s_dead;
+ }
+
+#if HTTP_PARSER_STRICT
+ if (ch == '\t' || ch == '\f') {
+ return s_dead;
+ }
+#endif
switch (s) {
case s_req_spaces_before_url:
@@ -434,67 +478,33 @@ parse_url_char(enum state s, const char ch)
case s_req_schema_slash_slash:
if (ch == '/') {
- return s_req_host_start;
+ return s_req_server_start;
}
break;
- case s_req_host_start:
- if (ch == '[') {
- return s_req_host_v6_start;
+ case s_req_server_with_at:
+ if (ch == '@') {
+ return s_dead;
}
- if (IS_HOST_CHAR(ch)) {
- return s_req_host;
- }
-
- break;
-
- case s_req_host:
- if (IS_HOST_CHAR(ch)) {
- return s_req_host;
- }
-
- /* FALLTHROUGH */
- case s_req_host_v6_end:
- switch (ch) {
- case ':':
- return s_req_port_start;
-
- case '/':
- return s_req_path;
-
- case '?':
- return s_req_query_string_start;
+ /* FALLTHROUGH */
+ case s_req_server_start:
+ case s_req_server:
+ if (ch == '/') {
+ return s_req_path;
}
- break;
-
- case s_req_host_v6:
- if (ch == ']') {
- return s_req_host_v6_end;
+ if (ch == '?') {
+ return s_req_query_string_start;
}
- /* FALLTHROUGH */
- case s_req_host_v6_start:
- if (IS_HEX(ch) || ch == ':') {
- return s_req_host_v6;
+ if (ch == '@') {
+ return s_req_server_with_at;
}
- break;
-
- case s_req_port:
- switch (ch) {
- case '/':
- return s_req_path;
- case '?':
- return s_req_query_string_start;
- }
-
- /* FALLTHROUGH */
- case s_req_port_start:
- if (IS_NUM(ch)) {
- return s_req_port;
+ if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') {
+ return s_req_server;
}
break;
@@ -616,13 +626,9 @@ size_t http_parser_execute (http_parser *parser,
case s_req_schema:
case s_req_schema_slash:
case s_req_schema_slash_slash:
- case s_req_host_start:
- case s_req_host_v6_start:
- case s_req_host_v6:
- case s_req_host_v6_end:
- case s_req_host:
- case s_req_port_start:
- case s_req_port:
+ case s_req_server_start:
+ case s_req_server:
+ case s_req_server_with_at:
case s_req_query_string_start:
case s_req_query_string:
case s_req_fragment_start:
@@ -983,7 +989,7 @@ size_t http_parser_execute (http_parser *parser,
MARK(url);
if (parser->method == HTTP_CONNECT) {
- parser->state = s_req_host_start;
+ parser->state = s_req_server_start;
}
parser->state = parse_url_char((enum state)parser->state, ch);
@@ -998,10 +1004,7 @@ size_t http_parser_execute (http_parser *parser,
case s_req_schema:
case s_req_schema_slash:
case s_req_schema_slash_slash:
- case s_req_host_start:
- case s_req_host_v6_start:
- case s_req_host_v6:
- case s_req_port_start:
+ case s_req_server_start:
{
switch (ch) {
/* No whitespace allowed here */
@@ -1021,9 +1024,8 @@ size_t http_parser_execute (http_parser *parser,
break;
}
- case s_req_host:
- case s_req_host_v6_end:
- case s_req_port:
+ case s_req_server:
+ case s_req_server_with_at:
case s_req_path:
case s_req_query_string_start:
case s_req_query_string:
@@ -1852,7 +1854,7 @@ error:
/* Does the parser need to see an EOF to find the end of the message? */
int
-http_message_needs_eof (http_parser *parser)
+http_message_needs_eof (const http_parser *parser)
{
if (parser->type == HTTP_REQUEST) {
return 0;
@@ -1875,7 +1877,7 @@ http_message_needs_eof (http_parser *parser)
int
-http_should_keep_alive (http_parser *parser)
+http_should_keep_alive (const http_parser *parser)
{
if (parser->http_major > 0 && parser->http_minor > 0) {
/* HTTP/1.1 */
@@ -1893,9 +1895,10 @@ http_should_keep_alive (http_parser *parser)
}
-const char * http_method_str (enum http_method m)
+const char *
+http_method_str (enum http_method m)
{
- return method_strings[m];
+ return ELEM_AT(method_strings, m, "<unknown>");
}
@@ -1922,6 +1925,144 @@ http_errno_description(enum http_errno err) {
return http_strerror_tab[err].description;
}
+static enum http_host_state
+http_parse_host_char(enum http_host_state s, const char ch) {
+ switch(s) {
+ case s_http_userinfo:
+ case s_http_userinfo_start:
+ if (ch == '@') {
+ return s_http_host_start;
+ }
+
+ if (IS_USERINFO_CHAR(ch)) {
+ return s_http_userinfo;
+ }
+ break;
+
+ case s_http_host_start:
+ if (ch == '[') {
+ return s_http_host_v6_start;
+ }
+
+ if (IS_HOST_CHAR(ch)) {
+ return s_http_host;
+ }
+
+ break;
+
+ case s_http_host:
+ if (IS_HOST_CHAR(ch)) {
+ return s_http_host;
+ }
+
+ /* FALLTHROUGH */
+ case s_http_host_v6_end:
+ if (ch == ':') {
+ return s_http_host_port_start;
+ }
+
+ break;
+
+ case s_http_host_v6:
+ if (ch == ']') {
+ return s_http_host_v6_end;
+ }
+
+ /* FALLTHROUGH */
+ case s_http_host_v6_start:
+ if (IS_HEX(ch) || ch == ':') {
+ return s_http_host_v6;
+ }
+
+ break;
+
+ case s_http_host_port:
+ case s_http_host_port_start:
+ if (IS_NUM(ch)) {
+ return s_http_host_port;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ return s_http_host_dead;
+}
+
+static int
+http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
+ enum http_host_state s;
+
+ const char *p;
+ size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len;
+
+ u->field_data[UF_HOST].len = 0;
+
+ s = found_at ? s_http_userinfo_start : s_http_host_start;
+
+ for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) {
+ enum http_host_state new_s = http_parse_host_char(s, *p);
+
+ if (new_s == s_http_host_dead) {
+ return 1;
+ }
+
+ switch(new_s) {
+ case s_http_host:
+ if (s != s_http_host) {
+ u->field_data[UF_HOST].off = p - buf;
+ }
+ u->field_data[UF_HOST].len++;
+ break;
+
+ case s_http_host_v6:
+ if (s != s_http_host_v6) {
+ u->field_data[UF_HOST].off = p - buf;
+ }
+ u->field_data[UF_HOST].len++;
+ break;
+
+ case s_http_host_port:
+ if (s != s_http_host_port) {
+ u->field_data[UF_PORT].off = p - buf;
+ u->field_data[UF_PORT].len = 0;
+ u->field_set |= (1 << UF_PORT);
+ }
+ u->field_data[UF_PORT].len++;
+ break;
+
+ case s_http_userinfo:
+ if (s != s_http_userinfo) {
+ u->field_data[UF_USERINFO].off = p - buf ;
+ u->field_data[UF_USERINFO].len = 0;
+ u->field_set |= (1 << UF_USERINFO);
+ }
+ u->field_data[UF_USERINFO].len++;
+ break;
+
+ default:
+ break;
+ }
+ s = new_s;
+ }
+
+ /* Make sure we don't end somewhere unexpected */
+ switch (s) {
+ case s_http_host_start:
+ case s_http_host_v6_start:
+ case s_http_host_v6:
+ case s_http_host_port_start:
+ case s_http_userinfo:
+ case s_http_userinfo_start:
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
int
http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
struct http_parser_url *u)
@@ -1929,9 +2070,10 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
enum state s;
const char *p;
enum http_parser_url_fields uf, old_uf;
+ int found_at = 0;
u->port = u->field_set = 0;
- s = is_connect ? s_req_host_start : s_req_spaces_before_url;
+ s = is_connect ? s_req_server_start : s_req_spaces_before_url;
uf = old_uf = UF_MAX;
for (p = buf; p < buf + buflen; p++) {
@@ -1945,10 +2087,7 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
/* Skip delimeters */
case s_req_schema_slash:
case s_req_schema_slash_slash:
- case s_req_host_start:
- case s_req_host_v6_start:
- case s_req_host_v6_end:
- case s_req_port_start:
+ case s_req_server_start:
case s_req_query_string_start:
case s_req_fragment_start:
continue;
@@ -1957,13 +2096,12 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
uf = UF_SCHEMA;
break;
- case s_req_host:
- case s_req_host_v6:
- uf = UF_HOST;
- break;
+ case s_req_server_with_at:
+ found_at = 1;
- case s_req_port:
- uf = UF_PORT;
+ /* FALLTROUGH */
+ case s_req_server:
+ uf = UF_HOST;
break;
case s_req_path:
@@ -1996,21 +2134,17 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
old_uf = uf;
}
- /* CONNECT requests can only contain "hostname:port" */
- if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) {
- return 1;
+ /* host must be present if there is a schema */
+ /* parsing http:///toto will fail */
+ if ((u->field_set & ((1 << UF_SCHEMA) | (1 << UF_HOST))) != 0) {
+ if (http_parse_host(buf, u, found_at) != 0) {
+ return 1;
+ }
}
- /* Make sure we don't end somewhere unexpected */
- switch (s) {
- case s_req_host_v6_start:
- case s_req_host_v6:
- case s_req_host_v6_end:
- case s_req_host:
- case s_req_port_start:
+ /* CONNECT requests can only contain "hostname:port" */
+ if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) {
return 1;
- default:
- break;
}
if (u->field_set & (1 << UF_PORT)) {
diff --git a/deps/http_parser/http_parser.h b/deps/http_parser/http_parser.h
index 8ed41803e..7908ad03b 100644
--- a/deps/http_parser/http_parser.h
+++ b/deps/http_parser/http_parser.h
@@ -29,6 +29,7 @@ extern "C" {
#include <sys/types.h>
#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600)
+#include <BaseTsd.h>
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
@@ -37,9 +38,8 @@ typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
-
-typedef unsigned int size_t;
-typedef int ssize_t;
+typedef SIZE_T size_t;
+typedef SSIZE_T ssize_t;
#else
#include <stdint.h>
#endif
@@ -256,7 +256,8 @@ enum http_parser_url_fields
, UF_PATH = 3
, UF_QUERY = 4
, UF_FRAGMENT = 5
- , UF_MAX = 6
+ , UF_USERINFO = 6
+ , UF_MAX = 7
};
@@ -288,12 +289,12 @@ size_t http_parser_execute(http_parser *parser,
/* If http_should_keep_alive() in the on_headers_complete or
- * on_message_complete callback returns true, then this will be should be
+ * on_message_complete callback returns 0, then this should be
* the last message on the connection.
* If you are the server, respond with the "Connection: close" header.
* If you are the client, close the connection.
*/
-int http_should_keep_alive(http_parser *parser);
+int http_should_keep_alive(const http_parser *parser);
/* Returns a string version of the HTTP method. */
const char *http_method_str(enum http_method m);
diff --git a/deps/http_parser/test.c b/deps/http_parser/test.c
index 6af0e787e..81e0c3bdd 100644
--- a/deps/http_parser/test.c
+++ b/deps/http_parser/test.c
@@ -44,9 +44,15 @@ struct message {
enum http_parser_type type;
enum http_method method;
int status_code;
+ char request_path[MAX_ELEMENT_SIZE];
char request_url[MAX_ELEMENT_SIZE];
+ char fragment[MAX_ELEMENT_SIZE];
+ char query_string[MAX_ELEMENT_SIZE];
char body[MAX_ELEMENT_SIZE];
size_t body_size;
+ const char *host;
+ const char *userinfo;
+ uint16_t port;
int num_headers;
enum { NONE=0, FIELD, VALUE } last_header_element;
char headers [MAX_HEADERS][2][MAX_ELEMENT_SIZE];
@@ -67,6 +73,7 @@ static int currently_parsing_eof;
static struct message messages[5];
static int num_messages;
+static http_parser_settings *current_pause_parser;
/* * R E Q U E S T S * */
const struct message requests[] =
@@ -83,6 +90,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/test"
,.request_url= "/test"
,.num_headers= 3
,.headers=
@@ -111,6 +121,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/favicon.ico"
,.request_url= "/favicon.ico"
,.num_headers= 8
,.headers=
@@ -137,6 +150,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/dumbfuck"
,.request_url= "/dumbfuck"
,.num_headers= 1
,.headers=
@@ -155,6 +171,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= "page=1"
+ ,.fragment= "posts-17408"
+ ,.request_path= "/forums/1/topics/2375"
/* XXX request url does include fragment? */
,.request_url= "/forums/1/topics/2375?page=1#posts-17408"
,.num_headers= 0
@@ -171,6 +190,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/get_no_headers_no_body/world"
,.request_url= "/get_no_headers_no_body/world"
,.num_headers= 0
,.body= ""
@@ -187,6 +209,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/get_one_header_no_body"
,.request_url= "/get_one_header_no_body"
,.num_headers= 1
,.headers=
@@ -207,6 +232,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 0
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/get_funky_content_length_body_hello"
,.request_url= "/get_funky_content_length_body_hello"
,.num_headers= 1
,.headers=
@@ -229,6 +257,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_POST
+ ,.query_string= "q=search"
+ ,.fragment= "hey"
+ ,.request_path= "/post_identity_body_world"
,.request_url= "/post_identity_body_world?q=search#hey"
,.num_headers= 3
,.headers=
@@ -253,6 +284,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_POST
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/post_chunked_all_your_base"
,.request_url= "/post_chunked_all_your_base"
,.num_headers= 1
,.headers=
@@ -276,6 +310,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_POST
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/two_chunks_mult_zero_end"
,.request_url= "/two_chunks_mult_zero_end"
,.num_headers= 1
,.headers=
@@ -301,6 +338,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_POST
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/chunked_w_trailing_headers"
,.request_url= "/chunked_w_trailing_headers"
,.num_headers= 3
,.headers=
@@ -326,6 +366,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_POST
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/chunked_w_bullshit_after_length"
,.request_url= "/chunked_w_bullshit_after_length"
,.num_headers= 1
,.headers=
@@ -343,6 +386,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= "foo=\"bar\""
+ ,.fragment= ""
+ ,.request_path= "/with_\"stupid\"_quotes"
,.request_url= "/with_\"stupid\"_quotes?foo=\"bar\""
,.num_headers= 0
,.headers= { }
@@ -366,6 +412,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 0
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/test"
,.request_url= "/test"
,.num_headers= 3
,.headers= { { "Host", "0.0.0.0:5000" }
@@ -386,6 +435,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= "foo=bar?baz"
+ ,.fragment= ""
+ ,.request_path= "/test.cgi"
,.request_url= "/test.cgi?foo=bar?baz"
,.num_headers= 0
,.headers= {}
@@ -404,6 +456,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/test"
,.request_url= "/test"
,.num_headers= 0
,.headers= { }
@@ -428,6 +483,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/demo"
,.request_url= "/demo"
,.num_headers= 7
,.upgrade="Hot diggity dogg"
@@ -456,6 +514,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 0
,.method= HTTP_CONNECT
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= ""
,.request_url= "0-home0.netscape.com:443"
,.num_headers= 2
,.upgrade="some data\r\nand yet even more data"
@@ -475,6 +536,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_REPORT
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/test"
,.request_url= "/test"
,.num_headers= 0
,.headers= {}
@@ -491,6 +555,9 @@ const struct message requests[] =
,.http_major= 0
,.http_minor= 9
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/"
,.request_url= "/"
,.num_headers= 0
,.headers= {}
@@ -510,6 +577,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_MSEARCH
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "*"
,.request_url= "*"
,.num_headers= 3
,.headers= { { "HOST", "239.255.255.250:1900" }
@@ -519,7 +589,7 @@ const struct message requests[] =
,.body= ""
}
-#define LINE_FOLDING_IN_HEADER 20
+#define LINE_FOLDING_IN_HEADER 21
, {.name= "line folding in header value"
,.type= HTTP_REQUEST
,.raw= "GET / HTTP/1.1\r\n"
@@ -536,6 +606,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/"
,.request_url= "/"
,.num_headers= 2
,.headers= { { "Line1", "abcdefghijklmno qrs" }
@@ -545,7 +618,7 @@ const struct message requests[] =
}
-#define QUERY_TERMINATED_HOST 21
+#define QUERY_TERMINATED_HOST 22
, {.name= "host terminated by a query string"
,.type= HTTP_REQUEST
,.raw= "GET http://hypnotoad.org?hail=all HTTP/1.1\r\n"
@@ -555,13 +628,17 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= "hail=all"
+ ,.fragment= ""
+ ,.request_path= ""
,.request_url= "http://hypnotoad.org?hail=all"
+ ,.host= "hypnotoad.org"
,.num_headers= 0
,.headers= { }
,.body= ""
}
-#define QUERY_TERMINATED_HOSTPORT 22
+#define QUERY_TERMINATED_HOSTPORT 23
, {.name= "host:port terminated by a query string"
,.type= HTTP_REQUEST
,.raw= "GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n"
@@ -571,13 +648,18 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= "hail=all"
+ ,.fragment= ""
+ ,.request_path= ""
,.request_url= "http://hypnotoad.org:1234?hail=all"
+ ,.host= "hypnotoad.org"
+ ,.port= 1234
,.num_headers= 0
,.headers= { }
,.body= ""
}
-#define SPACE_TERMINATED_HOSTPORT 23
+#define SPACE_TERMINATED_HOSTPORT 24
, {.name= "host:port terminated by a space"
,.type= HTTP_REQUEST
,.raw= "GET http://hypnotoad.org:1234 HTTP/1.1\r\n"
@@ -587,14 +669,71 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= ""
,.request_url= "http://hypnotoad.org:1234"
+ ,.host= "hypnotoad.org"
+ ,.port= 1234
,.num_headers= 0
,.headers= { }
,.body= ""
}
+#define PATCH_REQ 25
+, {.name = "PATCH request"
+ ,.type= HTTP_REQUEST
+ ,.raw= "PATCH /file.txt HTTP/1.1\r\n"
+ "Host: www.example.com\r\n"
+ "Content-Type: application/example\r\n"
+ "If-Match: \"e0023aa4e\"\r\n"
+ "Content-Length: 10\r\n"
+ "\r\n"
+ "cccccccccc"
+ ,.should_keep_alive= TRUE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.method= HTTP_PATCH
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/file.txt"
+ ,.request_url= "/file.txt"
+ ,.num_headers= 4
+ ,.headers= { { "Host", "www.example.com" }
+ , { "Content-Type", "application/example" }
+ , { "If-Match", "\"e0023aa4e\"" }
+ , { "Content-Length", "10" }
+ }
+ ,.body= "cccccccccc"
+ }
+
+#define CONNECT_CAPS_REQUEST 26
+, {.name = "connect caps request"
+ ,.type= HTTP_REQUEST
+ ,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n"
+ "User-agent: Mozilla/1.1N\r\n"
+ "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
+ "\r\n"
+ ,.should_keep_alive= FALSE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 0
+ ,.method= HTTP_CONNECT
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= ""
+ ,.request_url= "HOME0.NETSCAPE.COM:443"
+ ,.num_headers= 2
+ ,.upgrade=""
+ ,.headers= { { "User-agent", "Mozilla/1.1N" }
+ , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" }
+ }
+ ,.body= ""
+ }
+
#if !HTTP_PARSER_STRICT
-#define UTF8_PATH_REQ 24
+#define UTF8_PATH_REQ 27
, {.name= "utf-8 path request"
,.type= HTTP_REQUEST
,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n"
@@ -605,6 +744,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
+ ,.query_string= "q=1"
+ ,.fragment= "narf"
+ ,.request_path= "/δ¶/δt/pope"
,.request_url= "/δ¶/δt/pope?q=1#narf"
,.num_headers= 1
,.headers= { {"Host", "github.com" }
@@ -612,7 +754,7 @@ const struct message requests[] =
,.body= ""
}
-#define HOSTNAME_UNDERSCORE 25
+#define HOSTNAME_UNDERSCORE 28
, {.name = "hostname underscore"
,.type= HTTP_REQUEST
,.raw= "CONNECT home_0.netscape.com:443 HTTP/1.0\r\n"
@@ -624,6 +766,9 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 0
,.method= HTTP_CONNECT
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= ""
,.request_url= "home_0.netscape.com:443"
,.num_headers= 2
,.upgrade=""
@@ -634,52 +779,124 @@ const struct message requests[] =
}
#endif /* !HTTP_PARSER_STRICT */
-#define PATCH_REQ 26
-, {.name = "PATCH request"
- ,.type= HTTP_REQUEST
- ,.raw= "PATCH /file.txt HTTP/1.1\r\n"
+/* see https://github.com/ry/http-parser/issues/47 */
+#define EAT_TRAILING_CRLF_NO_CONNECTION_CLOSE 29
+, {.name = "eat CRLF between requests, no \"Connection: close\" header"
+ ,.raw= "POST / HTTP/1.1\r\n"
"Host: www.example.com\r\n"
- "Content-Type: application/example\r\n"
- "If-Match: \"e0023aa4e\"\r\n"
- "Content-Length: 10\r\n"
+ "Content-Type: application/x-www-form-urlencoded\r\n"
+ "Content-Length: 4\r\n"
"\r\n"
- "cccccccccc"
+ "q=42\r\n" /* note the trailing CRLF */
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
- ,.method= HTTP_PATCH
- ,.request_url= "/file.txt"
+ ,.method= HTTP_POST
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/"
+ ,.request_url= "/"
+ ,.num_headers= 3
+ ,.upgrade= 0
+ ,.headers= { { "Host", "www.example.com" }
+ , { "Content-Type", "application/x-www-form-urlencoded" }
+ , { "Content-Length", "4" }
+ }
+ ,.body= "q=42"
+ }
+
+/* see https://github.com/ry/http-parser/issues/47 */
+#define EAT_TRAILING_CRLF_WITH_CONNECTION_CLOSE 30
+, {.name = "eat CRLF between requests even if \"Connection: close\" is set"
+ ,.raw= "POST / HTTP/1.1\r\n"
+ "Host: www.example.com\r\n"
+ "Content-Type: application/x-www-form-urlencoded\r\n"
+ "Content-Length: 4\r\n"
+ "Connection: close\r\n"
+ "\r\n"
+ "q=42\r\n" /* note the trailing CRLF */
+ ,.should_keep_alive= FALSE
+ ,.message_complete_on_eof= FALSE /* input buffer isn't empty when on_message_complete is called */
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.method= HTTP_POST
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/"
+ ,.request_url= "/"
,.num_headers= 4
+ ,.upgrade= 0
,.headers= { { "Host", "www.example.com" }
- , { "Content-Type", "application/example" }
- , { "If-Match", "\"e0023aa4e\"" }
- , { "Content-Length", "10" }
+ , { "Content-Type", "application/x-www-form-urlencoded" }
+ , { "Content-Length", "4" }
+ , { "Connection", "close" }
}
- ,.body= "cccccccccc"
+ ,.body= "q=42"
}
-#define CONNECT_CAPS_REQUEST 27
-, {.name = "connect caps request"
+#define PURGE_REQ 31
+, {.name = "PURGE request"
,.type= HTTP_REQUEST
- ,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n"
- "User-agent: Mozilla/1.1N\r\n"
- "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
+ ,.raw= "PURGE /file.txt HTTP/1.1\r\n"
+ "Host: www.example.com\r\n"
"\r\n"
- ,.should_keep_alive= FALSE
+ ,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
- ,.http_minor= 0
- ,.method= HTTP_CONNECT
- ,.request_url= "HOME0.NETSCAPE.COM:443"
- ,.num_headers= 2
- ,.upgrade=""
- ,.headers= { { "User-agent", "Mozilla/1.1N" }
- , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" }
- }
+ ,.http_minor= 1
+ ,.method= HTTP_PURGE
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/file.txt"
+ ,.request_url= "/file.txt"
+ ,.num_headers= 1
+ ,.headers= { { "Host", "www.example.com" } }
,.body= ""
}
+#define SEARCH_REQ 32
+, {.name = "SEARCH request"
+ ,.type= HTTP_REQUEST
+ ,.raw= "SEARCH / HTTP/1.1\r\n"
+ "Host: www.example.com\r\n"
+ "\r\n"
+ ,.should_keep_alive= TRUE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.method= HTTP_SEARCH
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/"
+ ,.request_url= "/"
+ ,.num_headers= 1
+ ,.headers= { { "Host", "www.example.com" } }
+ ,.body= ""
+ }
+
+#define PROXY_WITH_BASIC_AUTH 33
+, {.name= "host:port and basic_auth"
+ ,.type= HTTP_REQUEST
+ ,.raw= "GET http://a%12:b!&*$@hypnotoad.org:1234/toto HTTP/1.1\r\n"
+ "\r\n"
+ ,.should_keep_alive= TRUE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.method= HTTP_GET
+ ,.fragment= ""
+ ,.request_path= "/toto"
+ ,.request_url= "http://a%12:b!&*$@hypnotoad.org:1234/toto"
+ ,.host= "hypnotoad.org"
+ ,.userinfo= "a%12:b!&*$"
+ ,.port= 1234
+ ,.num_headers= 0
+ ,.headers= { }
+ ,.body= ""
+ }
+
+
, {.name= NULL } /* sentinel */
};
@@ -780,8 +997,8 @@ const struct message responses[] =
, {.name= "404 no headers no body"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 404 Not Found\r\n\r\n"
- ,.should_keep_alive= TRUE
- ,.message_complete_on_eof= FALSE
+ ,.should_keep_alive= FALSE
+ ,.message_complete_on_eof= TRUE
,.http_major= 1
,.http_minor= 1
,.status_code= 404
@@ -795,8 +1012,8 @@ const struct message responses[] =
, {.name= "301 no response phrase"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 301\r\n\r\n"
- ,.should_keep_alive = TRUE
- ,.message_complete_on_eof= FALSE
+ ,.should_keep_alive = FALSE
+ ,.message_complete_on_eof= TRUE
,.http_major= 1
,.http_minor= 1
,.status_code= 301
@@ -945,40 +1162,7 @@ const struct message responses[] =
,.body= ""
}
-#define SPACE_IN_FIELD_RES 9
-/* Should handle spaces in header fields */
-, {.name= "field space"
- ,.type= HTTP_RESPONSE
- ,.raw= "HTTP/1.1 200 OK\r\n"
- "Server: Microsoft-IIS/6.0\r\n"
- "X-Powered-By: ASP.NET\r\n"
- "en-US Content-Type: text/xml\r\n" /* this is the problem */
- "Content-Type: text/xml\r\n"
- "Content-Length: 16\r\n"
- "Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n"
- "Connection: keep-alive\r\n"
- "\r\n"
- "<xml>hello</xml>" /* fake body */
- ,.should_keep_alive= TRUE
- ,.message_complete_on_eof= FALSE
- ,.http_major= 1
- ,.http_minor= 1
- ,.status_code= 200
- ,.num_headers= 7
- ,.headers=
- { { "Server", "Microsoft-IIS/6.0" }
- , { "X-Powered-By", "ASP.NET" }
- , { "en-US Content-Type", "text/xml" }
- , { "Content-Type", "text/xml" }
- , { "Content-Length", "16" }
- , { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" }
- , { "Connection", "keep-alive" }
- }
- ,.body= "<xml>hello</xml>"
- }
-
-
-#define RES_FIELD_UNDERSCORE 10
+#define RES_FIELD_UNDERSCORE 9
/* Should handle spaces in header fields */
, {.name= "field underscore"
,.type= HTTP_RESPONSE
@@ -1018,7 +1202,7 @@ const struct message responses[] =
,.body= ""
}
-#define NON_ASCII_IN_STATUS_LINE 11
+#define NON_ASCII_IN_STATUS_LINE 10
/* Should handle non-ASCII in status line */
, {.name= "non-ASCII in status line"
,.type= HTTP_RESPONSE
@@ -1041,7 +1225,7 @@ const struct message responses[] =
,.body= ""
}
-#define HTTP_VERSION_0_9 12
+#define HTTP_VERSION_0_9 11
/* Should handle HTTP/0.9 */
, {.name= "http version 0.9"
,.type= HTTP_RESPONSE
@@ -1057,8 +1241,175 @@ const struct message responses[] =
{}
,.body= ""
}
-, {.name= NULL } /* sentinel */
+#define NO_CONTENT_LENGTH_NO_TRANSFER_ENCODING_RESPONSE 12
+/* The client should wait for the server's EOF. That is, when neither
+ * content-length nor transfer-encoding is specified, the end of body
+ * is specified by the EOF.
+ */
+, {.name= "neither content-length nor transfer-encoding response"
+ ,.type= HTTP_RESPONSE
+ ,.raw= "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/plain\r\n"
+ "\r\n"
+ "hello world"
+ ,.should_keep_alive= FALSE
+ ,.message_complete_on_eof= TRUE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.status_code= 200
+ ,.num_headers= 1
+ ,.headers=
+ { { "Content-Type", "text/plain" }
+ }
+ ,.body= "hello world"
+ }
+
+#define NO_BODY_HTTP10_KA_200 13
+, {.name= "HTTP/1.0 with keep-alive and EOF-terminated 200 status"
+ ,.type= HTTP_RESPONSE
+ ,.raw= "HTTP/1.0 200 OK\r\n"
+ "Connection: keep-alive\r\n"
+ "\r\n"
+ ,.should_keep_alive= FALSE
+ ,.message_complete_on_eof= TRUE
+ ,.http_major= 1
+ ,.http_minor= 0
+ ,.status_code= 200
+ ,.num_headers= 1
+ ,.headers=
+ { { "Connection", "keep-alive" }
+ }
+ ,.body_size= 0
+ ,.body= ""
+ }
+
+#define NO_BODY_HTTP10_KA_204 14
+, {.name= "HTTP/1.0 with keep-alive and a 204 status"
+ ,.type= HTTP_RESPONSE
+ ,.raw= "HTTP/1.0 204 No content\r\n"
+ "Connection: keep-alive\r\n"
+ "\r\n"
+ ,.should_keep_alive= TRUE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 0
+ ,.status_code= 204
+ ,.num_headers= 1
+ ,.headers=
+ { { "Connection", "keep-alive" }
+ }
+ ,.body_size= 0
+ ,.body= ""
+ }
+
+#define NO_BODY_HTTP11_KA_200 15
+, {.name= "HTTP/1.1 with an EOF-terminated 200 status"
+ ,.type= HTTP_RESPONSE
+ ,.raw= "HTTP/1.1 200 OK\r\n"
+ "\r\n"
+ ,.should_keep_alive= FALSE
+ ,.message_complete_on_eof= TRUE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.status_code= 200
+ ,.num_headers= 0
+ ,.headers={}
+ ,.body_size= 0
+ ,.body= ""
+ }
+
+#define NO_BODY_HTTP11_KA_204 16
+, {.name= "HTTP/1.1 with a 204 status"
+ ,.type= HTTP_RESPONSE
+ ,.raw= "HTTP/1.1 204 No content\r\n"
+ "\r\n"
+ ,.should_keep_alive= TRUE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.status_code= 204
+ ,.num_headers= 0
+ ,.headers={}
+ ,.body_size= 0
+ ,.body= ""
+ }
+
+#define NO_BODY_HTTP11_NOKA_204 17
+, {.name= "HTTP/1.1 with a 204 status and keep-alive disabled"
+ ,.type= HTTP_RESPONSE
+ ,.raw= "HTTP/1.1 204 No content\r\n"
+ "Connection: close\r\n"
+ "\r\n"
+ ,.should_keep_alive= FALSE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.status_code= 204
+ ,.num_headers= 1
+ ,.headers=
+ { { "Connection", "close" }
+ }
+ ,.body_size= 0
+ ,.body= ""
+ }
+
+#define NO_BODY_HTTP11_KA_CHUNKED_200 18
+, {.name= "HTTP/1.1 with chunked endocing and a 200 response"
+ ,.type= HTTP_RESPONSE
+ ,.raw= "HTTP/1.1 200 OK\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "0\r\n"
+ "\r\n"
+ ,.should_keep_alive= TRUE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.status_code= 200
+ ,.num_headers= 1
+ ,.headers=
+ { { "Transfer-Encoding", "chunked" }
+ }
+ ,.body_size= 0
+ ,.body= ""
+ }
+
+#if !HTTP_PARSER_STRICT
+#define SPACE_IN_FIELD_RES 19
+/* Should handle spaces in header fields */
+, {.name= "field space"
+ ,.type= HTTP_RESPONSE
+ ,.raw= "HTTP/1.1 200 OK\r\n"
+ "Server: Microsoft-IIS/6.0\r\n"
+ "X-Powered-By: ASP.NET\r\n"
+ "en-US Content-Type: text/xml\r\n" /* this is the problem */
+ "Content-Type: text/xml\r\n"
+ "Content-Length: 16\r\n"
+ "Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n"
+ "Connection: keep-alive\r\n"
+ "\r\n"
+ "<xml>hello</xml>" /* fake body */
+ ,.should_keep_alive= TRUE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.status_code= 200
+ ,.num_headers= 7
+ ,.headers=
+ { { "Server", "Microsoft-IIS/6.0" }
+ , { "X-Powered-By", "ASP.NET" }
+ , { "en-US Content-Type", "text/xml" }
+ , { "Content-Type", "text/xml" }
+ , { "Content-Length", "16" }
+ , { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" }
+ , { "Connection", "keep-alive" }
+ }
+ ,.body= "<xml>hello</xml>"
+ }
+#endif /* !HTTP_PARSER_STRICT */
+
+, {.name= NULL } /* sentinel */
};
int
@@ -1148,7 +1499,7 @@ message_complete_cb (http_parser *p)
"value in both on_message_complete and on_headers_complete "
"but it doesn't! ***\n\n");
assert(0);
- exit(1);
+ abort();
}
messages[num_messages].message_complete_cb_called = TRUE;
@@ -1158,6 +1509,146 @@ message_complete_cb (http_parser *p)
return 0;
}
+/* These dontcall_* callbacks exist so that we can verify that when we're
+ * paused, no additional callbacks are invoked */
+int
+dontcall_message_begin_cb (http_parser *p)
+{
+ if (p) { } // gcc
+ fprintf(stderr, "\n\n*** on_message_begin() called on paused parser ***\n\n");
+ abort();
+}
+
+int
+dontcall_header_field_cb (http_parser *p, const char *buf, size_t len)
+{
+ if (p || buf || len) { } // gcc
+ fprintf(stderr, "\n\n*** on_header_field() called on paused parser ***\n\n");
+ abort();
+}
+
+int
+dontcall_header_value_cb (http_parser *p, const char *buf, size_t len)
+{
+ if (p || buf || len) { } // gcc
+ fprintf(stderr, "\n\n*** on_header_value() called on paused parser ***\n\n");
+ abort();
+}
+
+int
+dontcall_request_url_cb (http_parser *p, const char *buf, size_t len)
+{
+ if (p || buf || len) { } // gcc
+ fprintf(stderr, "\n\n*** on_request_url() called on paused parser ***\n\n");
+ abort();
+}
+
+int
+dontcall_body_cb (http_parser *p, const char *buf, size_t len)
+{
+ if (p || buf || len) { } // gcc
+ fprintf(stderr, "\n\n*** on_body_cb() called on paused parser ***\n\n");
+ abort();
+}
+
+int
+dontcall_headers_complete_cb (http_parser *p)
+{
+ if (p) { } // gcc
+ fprintf(stderr, "\n\n*** on_headers_complete() called on paused "
+ "parser ***\n\n");
+ abort();
+}
+
+int
+dontcall_message_complete_cb (http_parser *p)
+{
+ if (p) { } // gcc
+ fprintf(stderr, "\n\n*** on_message_complete() called on paused "
+ "parser ***\n\n");
+ abort();
+}
+
+static http_parser_settings settings_dontcall =
+ {.on_message_begin = dontcall_message_begin_cb
+ ,.on_header_field = dontcall_header_field_cb
+ ,.on_header_value = dontcall_header_value_cb
+ ,.on_url = dontcall_request_url_cb
+ ,.on_body = dontcall_body_cb
+ ,.on_headers_complete = dontcall_headers_complete_cb
+ ,.on_message_complete = dontcall_message_complete_cb
+ };
+
+/* These pause_* callbacks always pause the parser and just invoke the regular
+ * callback that tracks content. Before returning, we overwrite the parser
+ * settings to point to the _dontcall variety so that we can verify that
+ * the pause actually did, you know, pause. */
+int
+pause_message_begin_cb (http_parser *p)
+{
+ http_parser_pause(p, 1);
+ *current_pause_parser = settings_dontcall;
+ return message_begin_cb(p);
+}
+
+int
+pause_header_field_cb (http_parser *p, const char *buf, size_t len)
+{
+ http_parser_pause(p, 1);
+ *current_pause_parser = settings_dontcall;
+ return header_field_cb(p, buf, len);
+}
+
+int
+pause_header_value_cb (http_parser *p, const char *buf, size_t len)
+{
+ http_parser_pause(p, 1);
+ *current_pause_parser = settings_dontcall;
+ return header_value_cb(p, buf, len);
+}
+
+int
+pause_request_url_cb (http_parser *p, const char *buf, size_t len)
+{
+ http_parser_pause(p, 1);
+ *current_pause_parser = settings_dontcall;
+ return request_url_cb(p, buf, len);
+}
+
+int
+pause_body_cb (http_parser *p, const char *buf, size_t len)
+{
+ http_parser_pause(p, 1);
+ *current_pause_parser = settings_dontcall;
+ return body_cb(p, buf, len);
+}
+
+int
+pause_headers_complete_cb (http_parser *p)
+{
+ http_parser_pause(p, 1);
+ *current_pause_parser = settings_dontcall;
+ return headers_complete_cb(p);
+}
+
+int
+pause_message_complete_cb (http_parser *p)
+{
+ http_parser_pause(p, 1);
+ *current_pause_parser = settings_dontcall;
+ return message_complete_cb(p);
+}
+
+static http_parser_settings settings_pause =
+ {.on_message_begin = pause_message_begin_cb
+ ,.on_header_field = pause_header_field_cb
+ ,.on_header_value = pause_header_value_cb
+ ,.on_url = pause_request_url_cb
+ ,.on_body = pause_body_cb
+ ,.on_headers_complete = pause_headers_complete_cb
+ ,.on_message_complete = pause_message_complete_cb
+ };
+
static http_parser_settings settings =
{.on_message_begin = message_begin_cb
,.on_header_field = header_field_cb
@@ -1227,6 +1718,17 @@ size_t parse_count_body (const char *buf, size_t len)
return nparsed;
}
+size_t parse_pause (const char *buf, size_t len)
+{
+ size_t nparsed;
+ http_parser_settings s = settings_pause;
+
+ currently_parsing_eof = (len == 0);
+ current_pause_parser = &s;
+ nparsed = http_parser_execute(parser, current_pause_parser, buf, len);
+ return nparsed;
+}
+
static inline int
check_str_eq (const struct message *m,
const char *prop,
@@ -1267,6 +1769,20 @@ check_num_eq (const struct message *m,
#define MESSAGE_CHECK_NUM_EQ(expected, found, prop) \
if (!check_num_eq(expected, #prop, expected->prop, found->prop)) return 0
+#define MESSAGE_CHECK_URL_EQ(u, expected, found, prop, fn) \
+do { \
+ char ubuf[256]; \
+ \
+ if ((u)->field_set & (1 << (fn))) { \
+ memcpy(ubuf, (found)->request_url + (u)->field_data[(fn)].off, \
+ (u)->field_data[(fn)].len); \
+ ubuf[(u)->field_data[(fn)].len] = '\0'; \
+ } else { \
+ ubuf[0] = '\0'; \
+ } \
+ \
+ check_str_eq(expected, #prop, expected->prop, ubuf); \
+} while(0)
int
message_eq (int index, const struct message *expected)
@@ -1292,6 +1808,36 @@ message_eq (int index, const struct message *expected)
MESSAGE_CHECK_STR_EQ(expected, m, request_url);
+
+ /* Check URL components; we can't do this w/ CONNECT since it doesn't
+ * send us a well-formed URL.
+ */
+ if (*m->request_url && m->method != HTTP_CONNECT) {
+ struct http_parser_url u;
+
+ if (http_parser_parse_url(m->request_url, strlen(m->request_url), 0, &u)) {
+ fprintf(stderr, "\n\n*** failed to parse URL %s ***\n\n",
+ m->request_url);
+ abort();
+ }
+
+ if (expected->host) {
+ MESSAGE_CHECK_URL_EQ(&u, expected, m, host, UF_HOST);
+ }
+
+ if (expected->userinfo) {
+ MESSAGE_CHECK_URL_EQ(&u, expected, m, userinfo, UF_USERINFO);
+ }
+
+ m->port = (u.field_set & (1 << UF_PORT)) ?
+ u.port : 0;
+
+ MESSAGE_CHECK_URL_EQ(&u, expected, m, query_string, UF_QUERY);
+ MESSAGE_CHECK_URL_EQ(&u, expected, m, fragment, UF_FRAGMENT);
+ MESSAGE_CHECK_URL_EQ(&u, expected, m, request_path, UF_PATH);
+ MESSAGE_CHECK_NUM_EQ(expected, m, port);
+ }
+
if (expected->body_size) {
MESSAGE_CHECK_NUM_EQ(expected, m, body_size);
} else {
@@ -1358,7 +1904,7 @@ upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) {
/* Check the portion of the response after its specified upgrade */
if (!check_str_eq(m, "upgrade", body + off, body + nread)) {
- exit(1);
+ abort();
}
/* Fix up the response so that message_eq() will verify the beginning
@@ -1374,7 +1920,7 @@ upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) {
va_end(ap);
printf("\n\n*** Error: expected a message with upgrade ***\n");
- exit(1);
+ abort();
}
static void
@@ -1420,6 +1966,563 @@ print_error (const char *raw, size_t error_location)
fprintf(stderr, "^\n\nerror location: %u\n", (unsigned int)error_location);
}
+void
+test_preserve_data (void)
+{
+ char my_data[] = "application-specific data";
+ http_parser parser;
+ parser.data = my_data;
+ http_parser_init(&parser, HTTP_REQUEST);
+ if (parser.data != my_data) {
+ printf("\n*** parser.data not preserved accross http_parser_init ***\n\n");
+ abort();
+ }
+}
+
+struct url_test {
+ const char *name;
+ const char *url;
+ int is_connect;
+ struct http_parser_url u;
+ int rv;
+};
+
+const struct url_test url_tests[] =
+{ {.name="proxy request"
+ ,.url="http://hostname/"
+ ,.is_connect=0
+ ,.u=
+ {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH)
+ ,.port=0
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 7, 8 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 15, 1 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="proxy request with port"
+ ,.url="http://hostname:444/"
+ ,.is_connect=0
+ ,.u=
+ {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH)
+ ,.port=444
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 7, 8 } /* UF_HOST */
+ ,{ 16, 3 } /* UF_PORT */
+ ,{ 19, 1 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="CONNECT request"
+ ,.url="hostname:443"
+ ,.is_connect=1
+ ,.u=
+ {.field_set=(1 << UF_HOST) | (1 << UF_PORT)
+ ,.port=443
+ ,.field_data=
+ {{ 0, 0 } /* UF_SCHEMA */
+ ,{ 0, 8 } /* UF_HOST */
+ ,{ 9, 3 } /* UF_PORT */
+ ,{ 0, 0 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="CONNECT request but not connect"
+ ,.url="hostname:443"
+ ,.is_connect=0
+ ,.rv=1
+ }
+
+, {.name="proxy ipv6 request"
+ ,.url="http://[1:2::3:4]/"
+ ,.is_connect=0
+ ,.u=
+ {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH)
+ ,.port=0
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 8, 8 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 17, 1 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="proxy ipv6 request with port"
+ ,.url="http://[1:2::3:4]:67/"
+ ,.is_connect=0
+ ,.u=
+ {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH)
+ ,.port=67
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 8, 8 } /* UF_HOST */
+ ,{ 18, 2 } /* UF_PORT */
+ ,{ 20, 1 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="CONNECT ipv6 address"
+ ,.url="[1:2::3:4]:443"
+ ,.is_connect=1
+ ,.u=
+ {.field_set=(1 << UF_HOST) | (1 << UF_PORT)
+ ,.port=443
+ ,.field_data=
+ {{ 0, 0 } /* UF_SCHEMA */
+ ,{ 1, 8 } /* UF_HOST */
+ ,{ 11, 3 } /* UF_PORT */
+ ,{ 0, 0 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="extra ? in query string"
+ ,.url="http://a.tbcdn.cn/p/fp/2010c/??fp-header-min.css,fp-base-min.css,"
+ "fp-channel-min.css,fp-product-min.css,fp-mall-min.css,fp-category-min.css,"
+ "fp-sub-min.css,fp-gdp4p-min.css,fp-css3-min.css,fp-misc-min.css?t=20101022.css"
+ ,.is_connect=0
+ ,.u=
+ {.field_set=(1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH) | (1<<UF_QUERY)
+ ,.port=0
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 7, 10 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 17, 12 } /* UF_PATH */
+ ,{ 30,187 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="space URL encoded"
+ ,.url="/toto.html?toto=a%20b"
+ ,.is_connect=0
+ ,.u=
+ {.field_set= (1<<UF_PATH) | (1<<UF_QUERY)
+ ,.port=0
+ ,.field_data=
+ {{ 0, 0 } /* UF_SCHEMA */
+ ,{ 0, 0 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 0, 10 } /* UF_PATH */
+ ,{ 11, 10 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+
+, {.name="URL fragment"
+ ,.url="/toto.html#titi"
+ ,.is_connect=0
+ ,.u=
+ {.field_set= (1<<UF_PATH) | (1<<UF_FRAGMENT)
+ ,.port=0
+ ,.field_data=
+ {{ 0, 0 } /* UF_SCHEMA */
+ ,{ 0, 0 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 0, 10 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 11, 4 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="complex URL fragment"
+ ,.url="http://www.webmasterworld.com/r.cgi?f=21&d=8405&url="
+ "http://www.example.com/index.html?foo=bar&hello=world#midpage"
+ ,.is_connect=0
+ ,.u=
+ {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH) | (1<<UF_QUERY) |\
+ (1<<UF_FRAGMENT)
+ ,.port=0
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 7, 22 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 29, 6 } /* UF_PATH */
+ ,{ 36, 69 } /* UF_QUERY */
+ ,{106, 7 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="complex URL from node js url parser doc"
+ ,.url="http://host.com:8080/p/a/t/h?query=string#hash"
+ ,.is_connect=0
+ ,.u=
+ {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PORT) | (1<<UF_PATH) |\
+ (1<<UF_QUERY) | (1<<UF_FRAGMENT)
+ ,.port=8080
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 7, 8 } /* UF_HOST */
+ ,{ 16, 4 } /* UF_PORT */
+ ,{ 20, 8 } /* UF_PATH */
+ ,{ 29, 12 } /* UF_QUERY */
+ ,{ 42, 4 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="complex URL with basic auth from node js url parser doc"
+ ,.url="http://a:b@host.com:8080/p/a/t/h?query=string#hash"
+ ,.is_connect=0
+ ,.u=
+ {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PORT) | (1<<UF_PATH) |\
+ (1<<UF_QUERY) | (1<<UF_FRAGMENT) | (1<<UF_USERINFO)
+ ,.port=8080
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 11, 8 } /* UF_HOST */
+ ,{ 20, 4 } /* UF_PORT */
+ ,{ 24, 8 } /* UF_PATH */
+ ,{ 33, 12 } /* UF_QUERY */
+ ,{ 46, 4 } /* UF_FRAGMENT */
+ ,{ 7, 3 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="double @"
+ ,.url="http://a:b@@hostname:443/"
+ ,.is_connect=0
+ ,.rv=1
+ }
+
+, {.name="proxy empty host"
+ ,.url="http://:443/"
+ ,.is_connect=0
+ ,.rv=1
+ }
+
+, {.name="proxy empty port"
+ ,.url="http://hostname:/"
+ ,.is_connect=0
+ ,.rv=1
+ }
+
+, {.name="CONNECT with basic auth"
+ ,.url="a:b@hostname:443"
+ ,.is_connect=1
+ ,.rv=1
+ }
+
+, {.name="CONNECT empty host"
+ ,.url=":443"
+ ,.is_connect=1
+ ,.rv=1
+ }
+
+, {.name="CONNECT empty port"
+ ,.url="hostname:"
+ ,.is_connect=1
+ ,.rv=1
+ }
+
+, {.name="CONNECT with extra bits"
+ ,.url="hostname:443/"
+ ,.is_connect=1
+ ,.rv=1
+ }
+
+, {.name="space in URL"
+ ,.url="/foo bar/"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="proxy basic auth with space url encoded"
+ ,.url="http://a%20:b@host.com/"
+ ,.is_connect=0
+ ,.u=
+ {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH) | (1<<UF_USERINFO)
+ ,.port=0
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 14, 8 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 22, 1 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 7, 6 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="carriage return in URL"
+ ,.url="/foo\rbar/"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="proxy double : in URL"
+ ,.url="http://hostname::443/"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="proxy basic auth with double :"
+ ,.url="http://a::b@host.com/"
+ ,.is_connect=0
+ ,.u=
+ {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH) | (1<<UF_USERINFO)
+ ,.port=0
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 12, 8 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 20, 1 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 7, 4 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="line feed in URL"
+ ,.url="/foo\nbar/"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="proxy empty basic auth"
+ ,.url="http://@hostname/fo"
+ ,.u=
+ {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH)
+ ,.port=0
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 8, 8 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 16, 3 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+, {.name="proxy line feed in hostname"
+ ,.url="http://host\name/fo"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="proxy % in hostname"
+ ,.url="http://host%name/fo"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="proxy ; in hostname"
+ ,.url="http://host;ame/fo"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="proxy basic auth with unreservedchars"
+ ,.url="http://a!;-_!=+$@host.com/"
+ ,.is_connect=0
+ ,.u=
+ {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH) | (1<<UF_USERINFO)
+ ,.port=0
+ ,.field_data=
+ {{ 0, 4 } /* UF_SCHEMA */
+ ,{ 17, 8 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 25, 1 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 7, 9 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="proxy only empty basic auth"
+ ,.url="http://@/fo"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="proxy only basic auth"
+ ,.url="http://toto@/fo"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="proxy emtpy hostname"
+ ,.url="http:///fo"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="proxy = in URL"
+ ,.url="http://host=ame/fo"
+ ,.rv=1 /* s_dead */
+ }
+
+#if HTTP_PARSER_STRICT
+
+, {.name="tab in URL"
+ ,.url="/foo\tbar/"
+ ,.rv=1 /* s_dead */
+ }
+
+, {.name="form feed in URL"
+ ,.url="/foo\fbar/"
+ ,.rv=1 /* s_dead */
+ }
+
+#else /* !HTTP_PARSER_STRICT */
+
+, {.name="tab in URL"
+ ,.url="/foo\tbar/"
+ ,.u=
+ {.field_set=(1 << UF_PATH)
+ ,.field_data=
+ {{ 0, 0 } /* UF_SCHEMA */
+ ,{ 0, 0 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 0, 9 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+
+, {.name="form feed in URL"
+ ,.url="/foo\fbar/"
+ ,.u=
+ {.field_set=(1 << UF_PATH)
+ ,.field_data=
+ {{ 0, 0 } /* UF_SCHEMA */
+ ,{ 0, 0 } /* UF_HOST */
+ ,{ 0, 0 } /* UF_PORT */
+ ,{ 0, 9 } /* UF_PATH */
+ ,{ 0, 0 } /* UF_QUERY */
+ ,{ 0, 0 } /* UF_FRAGMENT */
+ ,{ 0, 0 } /* UF_USERINFO */
+ }
+ }
+ ,.rv=0
+ }
+#endif
+};
+
+void
+dump_url (const char *url, const struct http_parser_url *u)
+{
+ unsigned int i;
+
+ printf("\tfield_set: 0x%x, port: %u\n", u->field_set, u->port);
+ for (i = 0; i < UF_MAX; i++) {
+ if ((u->field_set & (1 << i)) == 0) {
+ printf("\tfield_data[%u]: unset\n", i);
+ continue;
+ }
+
+ printf("\tfield_data[%u]: off: %u len: %u part: \"%.*s\n",
+ i,
+ u->field_data[i].off,
+ u->field_data[i].len,
+ u->field_data[i].len,
+ url + u->field_data[i].off);
+ }
+}
+
+void
+test_parse_url (void)
+{
+ struct http_parser_url u;
+ const struct url_test *test;
+ unsigned int i;
+ int rv;
+
+ for (i = 0; i < (sizeof(url_tests) / sizeof(url_tests[0])); i++) {
+ test = &url_tests[i];
+ memset(&u, 0, sizeof(u));
+
+ rv = http_parser_parse_url(test->url,
+ strlen(test->url),
+ test->is_connect,
+ &u);
+
+ if (test->rv == 0) {
+ if (rv != 0) {
+ printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, "
+ "unexpected rv %d ***\n\n", test->url, test->name, rv);
+ abort();
+ }
+
+ if (memcmp(&u, &test->u, sizeof(u)) != 0) {
+ printf("\n*** http_parser_parse_url(\"%s\") \"%s\" failed ***\n",
+ test->url, test->name);
+
+ printf("target http_parser_url:\n");
+ dump_url(test->url, &test->u);
+ printf("result http_parser_url:\n");
+ dump_url(test->url, &u);
+
+ abort();
+ }
+ } else {
+ /* test->rv != 0 */
+ if (rv == 0) {
+ printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, "
+ "unexpected rv %d ***\n\n", test->url, test->name, rv);
+ abort();
+ }
+ }
+ }
+}
+
+void
+test_method_str (void)
+{
+ assert(0 == strcmp("GET", http_method_str(HTTP_GET)));
+ assert(0 == strcmp("<unknown>", http_method_str(1337)));
+}
void
test_message (const struct message *message)
@@ -1444,7 +2547,7 @@ test_message (const struct message *message)
if (read != msg1len) {
print_error(msg1, read);
- exit(1);
+ abort();
}
}
@@ -1458,24 +2561,24 @@ test_message (const struct message *message)
if (read != msg2len) {
print_error(msg2, read);
- exit(1);
+ abort();
}
read = parse(NULL, 0);
if (read != 0) {
print_error(message->raw, read);
- exit(1);
+ abort();
}
test:
if (num_messages != 1) {
printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name);
- exit(1);
+ abort();
}
- if(!message_eq(0, message)) exit(1);
+ if(!message_eq(0, message)) abort();
parser_free();
}
@@ -1496,7 +2599,7 @@ test_message_count_body (const struct message *message)
read = parse_count_body(message->raw + i, toread);
if (read != toread) {
print_error(message->raw, read);
- exit(1);
+ abort();
}
}
@@ -1504,15 +2607,15 @@ test_message_count_body (const struct message *message)
read = parse_count_body(NULL, 0);
if (read != 0) {
print_error(message->raw, read);
- exit(1);
+ abort();
}
if (num_messages != 1) {
printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name);
- exit(1);
+ abort();
}
- if(!message_eq(0, message)) exit(1);
+ if(!message_eq(0, message)) abort();
parser_free();
}
@@ -1544,7 +2647,7 @@ test_simple (const char *buf, enum http_errno err_expected)
#endif
fprintf(stderr, "\n*** test_simple expected %s, but saw %s ***\n\n%s\n",
http_errno_name(err_expected), http_errno_name(err), buf);
- exit(1);
+ abort();
}
}
@@ -1573,7 +2676,54 @@ test_header_overflow_error (int req)
}
fprintf(stderr, "\n*** Error expected but none in header overflow test ***\n");
- exit(1);
+ abort();
+}
+
+static void
+test_content_length_overflow (const char *buf, size_t buflen, int expect_ok)
+{
+ http_parser parser;
+ http_parser_init(&parser, HTTP_RESPONSE);
+ http_parser_execute(&parser, &settings_null, buf, buflen);
+
+ if (expect_ok)
+ assert(HTTP_PARSER_ERRNO(&parser) == HPE_OK);
+ else
+ assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_CONTENT_LENGTH);
+}
+
+void
+test_header_content_length_overflow_error (void)
+{
+#define X(size) \
+ "HTTP/1.1 200 OK\r\n" \
+ "Content-Length: " #size "\r\n" \
+ "\r\n"
+ const char a[] = X(18446744073709551614); /* 2^64-2 */
+ const char b[] = X(18446744073709551615); /* 2^64-1 */
+ const char c[] = X(18446744073709551616); /* 2^64 */
+#undef X
+ test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */
+ test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */
+ test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */
+}
+
+void
+test_chunk_content_length_overflow_error (void)
+{
+#define X(size) \
+ "HTTP/1.1 200 OK\r\n" \
+ "Transfer-Encoding: chunked\r\n" \
+ "\r\n" \
+ #size "\r\n" \
+ "..."
+ const char a[] = X(FFFFFFFFFFFFFFFE); /* 2^64-2 */
+ const char b[] = X(FFFFFFFFFFFFFFFF); /* 2^64-1 */
+ const char c[] = X(10000000000000000); /* 2^64 */
+#undef X
+ test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */
+ test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */
+ test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */
}
void
@@ -1584,8 +2734,8 @@ test_no_overflow_long_body (int req, size_t length)
size_t parsed;
size_t i;
char buf1[3000];
- size_t buf1len = sprintf(buf1, "%s\r\nConnection: Keep-Alive\r\nContent-Length: %zu\r\n\r\n",
- req ? "POST / HTTP/1.0" : "HTTP/1.0 200 OK", length);
+ size_t buf1len = sprintf(buf1, "%s\r\nConnection: Keep-Alive\r\nContent-Length: %lu\r\n\r\n",
+ req ? "POST / HTTP/1.0" : "HTTP/1.0 200 OK", (unsigned long)length);
parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len);
if (parsed != buf1len)
goto err;
@@ -1603,10 +2753,10 @@ test_no_overflow_long_body (int req, size_t length)
err:
fprintf(stderr,
- "\n*** error in test_no_overflow_long_body %s of length %zu ***\n",
+ "\n*** error in test_no_overflow_long_body %s of length %lu ***\n",
req ? "REQUEST" : "RESPONSE",
- length);
- exit(1);
+ (unsigned long)length);
+ abort();
}
void
@@ -1638,26 +2788,26 @@ test_multiple3 (const struct message *r1, const struct message *r2, const struct
if (read != strlen(total)) {
print_error(total, read);
- exit(1);
+ abort();
}
read = parse(NULL, 0);
if (read != 0) {
print_error(total, read);
- exit(1);
+ abort();
}
test:
if (message_count != num_messages) {
fprintf(stderr, "\n\n*** Parser didn't see 3 messages only %d *** \n", num_messages);
- exit(1);
+ abort();
}
- if (!message_eq(0, r1)) exit(1);
- if (message_count > 1 && !message_eq(1, r2)) exit(1);
- if (message_count > 2 && !message_eq(2, r3)) exit(1);
+ if (!message_eq(0, r1)) abort();
+ if (message_count > 1 && !message_eq(1, r2)) abort();
+ if (message_count > 2 && !message_eq(2, r3)) abort();
parser_free();
}
@@ -1780,7 +2930,7 @@ test:
fprintf(stderr, "buf1 (%u) %s\n\n", (unsigned int)buf1_len, buf1);
fprintf(stderr, "buf2 (%u) %s\n\n", (unsigned int)buf2_len , buf2);
fprintf(stderr, "buf3 (%u) %s\n", (unsigned int)buf3_len, buf3);
- exit(1);
+ abort();
}
// user required to free the result
@@ -1814,6 +2964,58 @@ create_large_chunked_message (int body_size_in_kb, const char* headers)
return buf;
}
+/* Verify that we can pause parsing at any of the bytes in the
+ * message and still get the result that we're expecting. */
+void
+test_message_pause (const struct message *msg)
+{
+ char *buf = (char*) msg->raw;
+ size_t buflen = strlen(msg->raw);
+ size_t nread;
+
+ parser_init(msg->type);
+
+ do {
+ nread = parse_pause(buf, buflen);
+
+ // We can only set the upgrade buffer once we've gotten our message
+ // completion callback.
+ if (messages[0].message_complete_cb_called &&
+ msg->upgrade &&
+ parser->upgrade) {
+ messages[0].upgrade = buf + nread;
+ goto test;
+ }
+
+ if (nread < buflen) {
+
+ // Not much do to if we failed a strict-mode check
+ if (HTTP_PARSER_ERRNO(parser) == HPE_STRICT) {
+ parser_free();
+ return;
+ }
+
+ assert (HTTP_PARSER_ERRNO(parser) == HPE_PAUSED);
+ }
+
+ buf += nread;
+ buflen -= nread;
+ http_parser_pause(parser, 0);
+ } while (buflen > 0);
+
+ nread = parse_pause(NULL, 0);
+ assert (nread == 0);
+
+test:
+ if (num_messages != 1) {
+ printf("\n*** num_messages != 1 after testing '%s' ***\n\n", msg->name);
+ abort();
+ }
+
+ if(!message_eq(0, msg)) abort();
+
+ parser_free();
+}
int
main (void)
@@ -1828,6 +3030,11 @@ main (void)
for (request_count = 0; requests[request_count].name; request_count++);
for (response_count = 0; responses[response_count].name; response_count++);
+ //// API
+ test_preserve_data();
+ test_parse_url();
+ test_method_str();
+
//// OVERFLOW CONDITIONS
test_header_overflow_error(HTTP_REQUEST);
@@ -1838,6 +3045,9 @@ main (void)
test_no_overflow_long_body(HTTP_RESPONSE, 1000);
test_no_overflow_long_body(HTTP_RESPONSE, 100000);
+ test_header_content_length_overflow_error();
+ test_chunk_content_length_overflow_error();
+
//// RESPONSES
for (i = 0; i < response_count; i++) {
@@ -1845,6 +3055,10 @@ main (void)
}
for (i = 0; i < response_count; i++) {
+ test_message_pause(&responses[i]);
+ }
+
+ for (i = 0; i < response_count; i++) {
if (!responses[i].should_keep_alive) continue;
for (j = 0; j < response_count; j++) {
if (!responses[j].should_keep_alive) continue;
@@ -1888,7 +3102,7 @@ main (void)
printf("response scan 1/2 ");
test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY]
- , &responses[NO_HEADERS_NO_BODY_404]
+ , &responses[NO_BODY_HTTP10_KA_204]
, &responses[NO_REASON_PHRASE]
);
@@ -2019,7 +3233,9 @@ main (void)
test_message(&requests[i]);
}
-
+ for (i = 0; i < request_count; i++) {
+ test_message_pause(&requests[i]);
+ }
for (i = 0; i < request_count; i++) {
if (!requests[i].should_keep_alive) continue;
diff --git a/deps/http_parser/url_parser.c b/deps/http_parser/url_parser.c
new file mode 100644
index 000000000..b1f9c979f
--- /dev/null
+++ b/deps/http_parser/url_parser.c
@@ -0,0 +1,44 @@
+#include "http_parser.h"
+#include <stdio.h>
+#include <string.h>
+
+void
+dump_url (const char *url, const struct http_parser_url *u)
+{
+ unsigned int i;
+
+ printf("\tfield_set: 0x%x, port: %u\n", u->field_set, u->port);
+ for (i = 0; i < UF_MAX; i++) {
+ if ((u->field_set & (1 << i)) == 0) {
+ printf("\tfield_data[%u]: unset\n", i);
+ continue;
+ }
+
+ printf("\tfield_data[%u]: off: %u len: %u part: \"%.*s\n",
+ i,
+ u->field_data[i].off,
+ u->field_data[i].len,
+ u->field_data[i].len,
+ url + u->field_data[i].off);
+ }
+}
+
+int main(int argc, char ** argv) {
+ if (argc != 3) {
+ printf("Syntax : %s connect|get url\n", argv[0]);
+ return 1;
+ }
+ struct http_parser_url u;
+ int len = strlen(argv[2]);
+ int connect = strcmp("connect", argv[1]) == 0 ? 1 : 0;
+ printf("Parsing %s, connect %d\n", argv[2], connect);
+
+ int result = http_parser_parse_url(argv[2], len, connect, &u);
+ if (result != 0) {
+ printf("Parse error : %d\n", result);
+ return result;
+ }
+ printf("Parse ok, result : \n");
+ dump_url(argv[2], &u);
+ return 0;
+} \ No newline at end of file
diff --git a/deps/npm/html/api/bin.html b/deps/npm/html/api/bin.html
index 762ed898d..0bd20c6ce 100644
--- a/deps/npm/html/api/bin.html
+++ b/deps/npm/html/api/bin.html
@@ -19,7 +19,7 @@
<p>This function should not be used programmatically. Instead, just refer
to the <code>npm.bin</code> member.</p>
</div>
-<p id="footer">bin &mdash; npm@1.2.11</p>
+<p id="footer">bin &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/bugs.html b/deps/npm/html/api/bugs.html
index d7b615fbf..95e67967e 100644
--- a/deps/npm/html/api/bugs.html
+++ b/deps/npm/html/api/bugs.html
@@ -25,7 +25,7 @@ optional version number.</p>
<p>This command will launch a browser, so this command may not be the most
friendly for programmatic use.</p>
</div>
-<p id="footer">bugs &mdash; npm@1.2.11</p>
+<p id="footer">bugs &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/commands.html b/deps/npm/html/api/commands.html
index ee98554c9..c87c22b95 100644
--- a/deps/npm/html/api/commands.html
+++ b/deps/npm/html/api/commands.html
@@ -28,7 +28,7 @@ usage, or <code>man 3 npm-&lt;command&gt;</code> for programmatic usage.</p>
<ul><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer">commands &mdash; npm@1.2.11</p>
+<p id="footer">commands &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/config.html b/deps/npm/html/api/config.html
index facb4ee83..ef2c319bf 100644
--- a/deps/npm/html/api/config.html
+++ b/deps/npm/html/api/config.html
@@ -33,7 +33,7 @@ functions instead.</p>
<ul><li><a href="../api/npm.html">npm(3)</a></li></ul>
</div>
-<p id="footer">config &mdash; npm@1.2.11</p>
+<p id="footer">config &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/deprecate.html b/deps/npm/html/api/deprecate.html
index ab671f286..a18e13c08 100644
--- a/deps/npm/html/api/deprecate.html
+++ b/deps/npm/html/api/deprecate.html
@@ -32,7 +32,7 @@ install the package.</p></li></ul>
<ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../api/unpublish.html">unpublish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">deprecate &mdash; npm@1.2.11</p>
+<p id="footer">deprecate &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/docs.html b/deps/npm/html/api/docs.html
index 1b3d0c872..78aab44fa 100644
--- a/deps/npm/html/api/docs.html
+++ b/deps/npm/html/api/docs.html
@@ -25,7 +25,7 @@ optional version number.</p>
<p>This command will launch a browser, so this command may not be the most
friendly for programmatic use.</p>
</div>
-<p id="footer">docs &mdash; npm@1.2.11</p>
+<p id="footer">docs &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/edit.html b/deps/npm/html/api/edit.html
index 85acc0880..ef95e6a01 100644
--- a/deps/npm/html/api/edit.html
+++ b/deps/npm/html/api/edit.html
@@ -30,7 +30,7 @@ to open. The package can optionally have a version number attached.</p>
<p>Since this command opens an editor in a new process, be careful about where
and how this is used.</p>
</div>
-<p id="footer">edit &mdash; npm@1.2.11</p>
+<p id="footer">edit &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/explore.html b/deps/npm/html/api/explore.html
index ddf38e77a..eca14b0e5 100644
--- a/deps/npm/html/api/explore.html
+++ b/deps/npm/html/api/explore.html
@@ -24,7 +24,7 @@ sure to use <code>npm rebuild &lt;pkg&gt;</code> if you make any changes.</p>
<p>The first element in the &#39;args&#39; parameter must be a package name. After that is the optional command, which can be any number of strings. All of the strings will be combined into one, space-delimited command.</p>
</div>
-<p id="footer">explore &mdash; npm@1.2.11</p>
+<p id="footer">explore &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/help-search.html b/deps/npm/html/api/help-search.html
index 3615e7ede..c46b39e71 100644
--- a/deps/npm/html/api/help-search.html
+++ b/deps/npm/html/api/help-search.html
@@ -32,7 +32,7 @@ Name of the file that matched</li></ul>
<p>The silent parameter is not neccessary not used, but it may in the future.</p>
</div>
-<p id="footer">help-search &mdash; npm@1.2.11</p>
+<p id="footer">help-search &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/init.html b/deps/npm/html/api/init.html
index a8a62a6ed..3312c90e0 100644
--- a/deps/npm/html/api/init.html
+++ b/deps/npm/html/api/init.html
@@ -35,7 +35,7 @@ then go ahead and use this programmatically.</p>
<p><a href="../doc/json.html">json(1)</a></p>
</div>
-<p id="footer">init &mdash; npm@1.2.11</p>
+<p id="footer">init &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/install.html b/deps/npm/html/api/install.html
index a2a7666b3..1cf252c56 100644
--- a/deps/npm/html/api/install.html
+++ b/deps/npm/html/api/install.html
@@ -25,7 +25,7 @@ the name of a package to be installed.</p>
<p>Finally, &#39;callback&#39; is a function that will be called when all packages have been
installed or when an error has been encountered.</p>
</div>
-<p id="footer">install &mdash; npm@1.2.11</p>
+<p id="footer">install &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/link.html b/deps/npm/html/api/link.html
index f84326275..ed20e09c1 100644
--- a/deps/npm/html/api/link.html
+++ b/deps/npm/html/api/link.html
@@ -39,7 +39,7 @@ npm.commands.link(&#39;redis&#39;, cb) # link-install the package</code></pre>
<p>Now, any changes to the redis package will be reflected in
the package in the current working directory</p>
</div>
-<p id="footer">link &mdash; npm@1.2.11</p>
+<p id="footer">link &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/load.html b/deps/npm/html/api/load.html
index cea0c3f8d..b32472332 100644
--- a/deps/npm/html/api/load.html
+++ b/deps/npm/html/api/load.html
@@ -32,7 +32,7 @@ config object.</p>
<p>For a list of all the available command-line configs, see <code>npm help config</code></p>
</div>
-<p id="footer">load &mdash; npm@1.2.11</p>
+<p id="footer">load &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/ls.html b/deps/npm/html/api/ls.html
index 5e5671a08..851cbf2e3 100644
--- a/deps/npm/html/api/ls.html
+++ b/deps/npm/html/api/ls.html
@@ -59,7 +59,7 @@ project.</p>
This means that if a submodule a same dependency as a parent module, then the
dependency will only be output once.</p>
</div>
-<p id="footer">ls &mdash; npm@1.2.11</p>
+<p id="footer">ls &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/npm.html b/deps/npm/html/api/npm.html
index 26e133c70..2e1ec7bfc 100644
--- a/deps/npm/html/api/npm.html
+++ b/deps/npm/html/api/npm.html
@@ -24,7 +24,7 @@ npm.load([configObject,] function (er, npm) {
<h2 id="VERSION">VERSION</h2>
-<p>1.2.11</p>
+<p>1.2.12</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
@@ -92,7 +92,7 @@ method names. Use the <code>npm.deref</code> method to find the real name.</p>
<pre><code>var cmd = npm.deref(&quot;unp&quot;) // cmd === &quot;unpublish&quot;</code></pre>
</div>
-<p id="footer">npm &mdash; npm@1.2.11</p>
+<p id="footer">npm &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/outdated.html b/deps/npm/html/api/outdated.html
index 7a693e051..9eb469edb 100644
--- a/deps/npm/html/api/outdated.html
+++ b/deps/npm/html/api/outdated.html
@@ -19,7 +19,7 @@ currently outdated.</p>
<p>If the &#39;packages&#39; parameter is left out, npm will check all packages.</p>
</div>
-<p id="footer">outdated &mdash; npm@1.2.11</p>
+<p id="footer">outdated &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/owner.html b/deps/npm/html/api/owner.html
index 10263d85e..dbd54c82d 100644
--- a/deps/npm/html/api/owner.html
+++ b/deps/npm/html/api/owner.html
@@ -34,7 +34,7 @@ that is not implemented at this time.</p>
<ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">owner &mdash; npm@1.2.11</p>
+<p id="footer">owner &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/pack.html b/deps/npm/html/api/pack.html
index 75bfb9733..1ab776917 100644
--- a/deps/npm/html/api/pack.html
+++ b/deps/npm/html/api/pack.html
@@ -25,7 +25,7 @@ overwritten the second time.</p>
<p>If no arguments are supplied, then npm packs the current package folder.</p>
</div>
-<p id="footer">pack &mdash; npm@1.2.11</p>
+<p id="footer">pack &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/prefix.html b/deps/npm/html/api/prefix.html
index 14056f247..c1b7c24ce 100644
--- a/deps/npm/html/api/prefix.html
+++ b/deps/npm/html/api/prefix.html
@@ -21,7 +21,7 @@
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">prefix &mdash; npm@1.2.11</p>
+<p id="footer">prefix &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/prune.html b/deps/npm/html/api/prune.html
index adefa1703..5583db0f1 100644
--- a/deps/npm/html/api/prune.html
+++ b/deps/npm/html/api/prune.html
@@ -23,7 +23,7 @@
<p>Extraneous packages are packages that are not listed on the parent
package&#39;s dependencies list.</p>
</div>
-<p id="footer">prune &mdash; npm@1.2.11</p>
+<p id="footer">prune &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/publish.html b/deps/npm/html/api/publish.html
index 3b50a9e73..cd13104c4 100644
--- a/deps/npm/html/api/publish.html
+++ b/deps/npm/html/api/publish.html
@@ -32,7 +32,7 @@ the registry. Overwrites when the &quot;force&quot; environment variable is set
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../api/owner.html">owner(3)</a></li></ul>
</div>
-<p id="footer">publish &mdash; npm@1.2.11</p>
+<p id="footer">publish &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/rebuild.html b/deps/npm/html/api/rebuild.html
index c9e805c1c..bb0cf1b59 100644
--- a/deps/npm/html/api/rebuild.html
+++ b/deps/npm/html/api/rebuild.html
@@ -22,7 +22,7 @@ the new binary. If no &#39;packages&#39; parameter is specify, every package wil
<p>See <code>npm help build</code></p>
</div>
-<p id="footer">rebuild &mdash; npm@1.2.11</p>
+<p id="footer">rebuild &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/restart.html b/deps/npm/html/api/restart.html
index 0378b94dd..cbdfca883 100644
--- a/deps/npm/html/api/restart.html
+++ b/deps/npm/html/api/restart.html
@@ -27,7 +27,7 @@ in the <code>packages</code> parameter.</p>
<ul><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul>
</div>
-<p id="footer">restart &mdash; npm@1.2.11</p>
+<p id="footer">restart &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/root.html b/deps/npm/html/api/root.html
index d2f6aab72..73ee81ca1 100644
--- a/deps/npm/html/api/root.html
+++ b/deps/npm/html/api/root.html
@@ -21,7 +21,7 @@
<p>This function is not useful programmatically.</p>
</div>
-<p id="footer">root &mdash; npm@1.2.11</p>
+<p id="footer">root &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/run-script.html b/deps/npm/html/api/run-script.html
index 5d93e41ed..00c1e84ec 100644
--- a/deps/npm/html/api/run-script.html
+++ b/deps/npm/html/api/run-script.html
@@ -29,7 +29,7 @@ assumed to be the command to run. All other elements are ignored.</p>
<ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../api/test.html">test(3)</a></li><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/restart.html">restart(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul>
</div>
-<p id="footer">run-script &mdash; npm@1.2.11</p>
+<p id="footer">run-script &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/search.html b/deps/npm/html/api/search.html
index fefbed550..1d6630bbb 100644
--- a/deps/npm/html/api/search.html
+++ b/deps/npm/html/api/search.html
@@ -32,7 +32,7 @@ excluded term (the &quot;searchexclude&quot; config). The search is case insensi
and doesn&#39;t try to read your mind (it doesn&#39;t do any verb tense matching or the
like).</p>
</div>
-<p id="footer">search &mdash; npm@1.2.11</p>
+<p id="footer">search &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/shrinkwrap.html b/deps/npm/html/api/shrinkwrap.html
index 50ca19817..8c8a97adb 100644
--- a/deps/npm/html/api/shrinkwrap.html
+++ b/deps/npm/html/api/shrinkwrap.html
@@ -26,7 +26,7 @@ but the shrinkwrap file will still be written.</p>
<p>Finally, &#39;callback&#39; is a function that will be called when the shrinkwrap has
been saved.</p>
</div>
-<p id="footer">shrinkwrap &mdash; npm@1.2.11</p>
+<p id="footer">shrinkwrap &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/start.html b/deps/npm/html/api/start.html
index 5dbbcb74d..ca77f0a70 100644
--- a/deps/npm/html/api/start.html
+++ b/deps/npm/html/api/start.html
@@ -19,7 +19,7 @@
<p>npm can run tests on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">start &mdash; npm@1.2.11</p>
+<p id="footer">start &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/stop.html b/deps/npm/html/api/stop.html
index 733a1e262..93afd4ff9 100644
--- a/deps/npm/html/api/stop.html
+++ b/deps/npm/html/api/stop.html
@@ -19,7 +19,7 @@
<p>npm can run stop on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">stop &mdash; npm@1.2.11</p>
+<p id="footer">stop &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/submodule.html b/deps/npm/html/api/submodule.html
index b655c4150..6d292de14 100644
--- a/deps/npm/html/api/submodule.html
+++ b/deps/npm/html/api/submodule.html
@@ -33,7 +33,7 @@ dependencies into the submodule folder.</p>
<ul><li>npm help json</li><li>git help submodule</li></ul>
</div>
-<p id="footer">submodule &mdash; npm@1.2.11</p>
+<p id="footer">submodule &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/tag.html b/deps/npm/html/api/tag.html
index cee47192a..c4d3b1871 100644
--- a/deps/npm/html/api/tag.html
+++ b/deps/npm/html/api/tag.html
@@ -29,7 +29,7 @@ parameter is missing or falsey (empty), the default froom the config will be
used. For more information about how to set this config, check
<code>man 3 npm-config</code> for programmatic usage or <code>man npm-config</code> for cli usage.</p>
</div>
-<p id="footer">tag &mdash; npm@1.2.11</p>
+<p id="footer">tag &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/test.html b/deps/npm/html/api/test.html
index 8086289a4..5fe57b377 100644
--- a/deps/npm/html/api/test.html
+++ b/deps/npm/html/api/test.html
@@ -22,7 +22,7 @@ true.</p>
<p>npm can run tests on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">test &mdash; npm@1.2.11</p>
+<p id="footer">test &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/uninstall.html b/deps/npm/html/api/uninstall.html
index 1aac296d1..4ea91cbf1 100644
--- a/deps/npm/html/api/uninstall.html
+++ b/deps/npm/html/api/uninstall.html
@@ -22,7 +22,7 @@ the name of a package to be uninstalled.</p>
<p>Finally, &#39;callback&#39; is a function that will be called when all packages have been
uninstalled or when an error has been encountered.</p>
</div>
-<p id="footer">uninstall &mdash; npm@1.2.11</p>
+<p id="footer">uninstall &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/unpublish.html b/deps/npm/html/api/unpublish.html
index 43aadee64..b2ffeabcb 100644
--- a/deps/npm/html/api/unpublish.html
+++ b/deps/npm/html/api/unpublish.html
@@ -26,7 +26,7 @@ is what is meant.</p>
<p>If no version is specified, or if all versions are removed then
the root package entry is removed from the registry entirely.</p>
</div>
-<p id="footer">unpublish &mdash; npm@1.2.11</p>
+<p id="footer">unpublish &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/update.html b/deps/npm/html/api/update.html
index 3aa2780df..3841480ef 100644
--- a/deps/npm/html/api/update.html
+++ b/deps/npm/html/api/update.html
@@ -18,7 +18,7 @@
<p>The &#39;packages&#39; argument is an array of packages to update. The &#39;callback&#39; parameter will be called when done or when an error occurs.</p>
</div>
-<p id="footer">update &mdash; npm@1.2.11</p>
+<p id="footer">update &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/version.html b/deps/npm/html/api/version.html
index 44dc04b01..792a3eabc 100644
--- a/deps/npm/html/api/version.html
+++ b/deps/npm/html/api/version.html
@@ -24,7 +24,7 @@ fail if the repo is not clean.</p>
parameter. The difference, however, is this function will fail if it does
not have exactly one element. The only element should be a version number.</p>
</div>
-<p id="footer">version &mdash; npm@1.2.11</p>
+<p id="footer">version &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/view.html b/deps/npm/html/api/view.html
index 5d3318c32..08cf6829a 100644
--- a/deps/npm/html/api/view.html
+++ b/deps/npm/html/api/view.html
@@ -99,7 +99,7 @@ the field name.</p>
<p>corresponding to the list of fields selected.</p>
</div>
-<p id="footer">view &mdash; npm@1.2.11</p>
+<p id="footer">view &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/api/whoami.html b/deps/npm/html/api/whoami.html
index 8a6bb178a..c902ee1c1 100644
--- a/deps/npm/html/api/whoami.html
+++ b/deps/npm/html/api/whoami.html
@@ -21,7 +21,7 @@
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">whoami &mdash; npm@1.2.11</p>
+<p id="footer">whoami &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/README.html b/deps/npm/html/doc/README.html
index 6a006e81c..2de39770b 100644
--- a/deps/npm/html/doc/README.html
+++ b/deps/npm/html/doc/README.html
@@ -240,7 +240,7 @@ will no doubt tell you to put the output in a gist or email.</p>
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer"><a href="../doc/README.html">README</a> &mdash; npm@1.2.11</p>
+<p id="footer"><a href="../doc/README.html">README</a> &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/adduser.html b/deps/npm/html/doc/adduser.html
index b0d9e5e3d..fa5b6d02d 100644
--- a/deps/npm/html/doc/adduser.html
+++ b/deps/npm/html/doc/adduser.html
@@ -39,7 +39,7 @@ authorize on a new machine.</p>
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li></ul>
</div>
-<p id="footer">adduser &mdash; npm@1.2.11</p>
+<p id="footer">adduser &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/bin.html b/deps/npm/html/doc/bin.html
index 45e300431..90cf76e44 100644
--- a/deps/npm/html/doc/bin.html
+++ b/deps/npm/html/doc/bin.html
@@ -20,7 +20,7 @@
<ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">bin &mdash; npm@1.2.11</p>
+<p id="footer">bin &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/bugs.html b/deps/npm/html/doc/bugs.html
index dd98badb3..51bc9b006 100644
--- a/deps/npm/html/doc/bugs.html
+++ b/deps/npm/html/doc/bugs.html
@@ -36,7 +36,7 @@ config param.</p>
<ul><li><a href="../doc/docs.html">docs(1)</a></li><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">bugs &mdash; npm@1.2.11</p>
+<p id="footer">bugs &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/build.html b/deps/npm/html/doc/build.html
index 05ff474d4..f3e31bc25 100644
--- a/deps/npm/html/doc/build.html
+++ b/deps/npm/html/doc/build.html
@@ -25,7 +25,7 @@ A folder containing a <code>package.json</code> file in its root.</li></ul>
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">build &mdash; npm@1.2.11</p>
+<p id="footer">build &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/bundle.html b/deps/npm/html/doc/bundle.html
index bdb98c26d..cedcb8aef 100644
--- a/deps/npm/html/doc/bundle.html
+++ b/deps/npm/html/doc/bundle.html
@@ -20,7 +20,7 @@ install packages into the local space.</p>
<ul><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">bundle &mdash; npm@1.2.11</p>
+<p id="footer">bundle &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/cache.html b/deps/npm/html/doc/cache.html
index da99303bd..3c437f1bb 100644
--- a/deps/npm/html/doc/cache.html
+++ b/deps/npm/html/doc/cache.html
@@ -66,7 +66,7 @@ they do not make an HTTP request to the registry.</p>
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li></ul>
</div>
-<p id="footer">cache &mdash; npm@1.2.11</p>
+<p id="footer">cache &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/changelog.html b/deps/npm/html/doc/changelog.html
index cae5b2b7f..83c5e1c8a 100644
--- a/deps/npm/html/doc/changelog.html
+++ b/deps/npm/html/doc/changelog.html
@@ -65,7 +65,7 @@
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li></ul>
</div>
-<p id="footer">changelog &mdash; npm@1.2.11</p>
+<p id="footer">changelog &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/coding-style.html b/deps/npm/html/doc/coding-style.html
index a595d403c..c1343b270 100644
--- a/deps/npm/html/doc/coding-style.html
+++ b/deps/npm/html/doc/coding-style.html
@@ -182,7 +182,7 @@ set to anything.&quot;</p>
<ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
</div>
-<p id="footer">coding-style &mdash; npm@1.2.11</p>
+<p id="footer">coding-style &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/completion.html b/deps/npm/html/doc/completion.html
index cb8f57e07..a246fb675 100644
--- a/deps/npm/html/doc/completion.html
+++ b/deps/npm/html/doc/completion.html
@@ -33,7 +33,7 @@ completions based on the arguments.</p>
<ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
</div>
-<p id="footer">completion &mdash; npm@1.2.11</p>
+<p id="footer">completion &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/config.html b/deps/npm/html/doc/config.html
index 7a1598829..0abff54e7 100644
--- a/deps/npm/html/doc/config.html
+++ b/deps/npm/html/doc/config.html
@@ -771,7 +771,7 @@ then answer &quot;no&quot; to any prompt.</p>
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
</div>
-<p id="footer">config &mdash; npm@1.2.11</p>
+<p id="footer">config &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/dedupe.html b/deps/npm/html/doc/dedupe.html
index 019e6562a..5bc787bb3 100644
--- a/deps/npm/html/doc/dedupe.html
+++ b/deps/npm/html/doc/dedupe.html
@@ -57,7 +57,7 @@ registry.</p>
<ul><li><a href="../doc/ls.html">ls(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">dedupe &mdash; npm@1.2.11</p>
+<p id="footer">dedupe &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/deprecate.html b/deps/npm/html/doc/deprecate.html
index eab223d62..77b287bcd 100644
--- a/deps/npm/html/doc/deprecate.html
+++ b/deps/npm/html/doc/deprecate.html
@@ -31,7 +31,7 @@ something like this:</p>
<ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">deprecate &mdash; npm@1.2.11</p>
+<p id="footer">deprecate &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/developers.html b/deps/npm/html/doc/developers.html
index 14eee8488..4389453a7 100644
--- a/deps/npm/html/doc/developers.html
+++ b/deps/npm/html/doc/developers.html
@@ -160,7 +160,7 @@ from a fresh checkout.</p>
<ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">developers &mdash; npm@1.2.11</p>
+<p id="footer">developers &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/disputes.html b/deps/npm/html/doc/disputes.html
index b363efb59..58613347a 100644
--- a/deps/npm/html/doc/disputes.html
+++ b/deps/npm/html/doc/disputes.html
@@ -86,7 +86,7 @@ an empty tarball, you&#39;re going to be evicted.</li></ol>
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul>
</div>
-<p id="footer">disputes &mdash; npm@1.2.11</p>
+<p id="footer">disputes &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/docs.html b/deps/npm/html/doc/docs.html
index ba7988451..f46072561 100644
--- a/deps/npm/html/doc/docs.html
+++ b/deps/npm/html/doc/docs.html
@@ -37,7 +37,7 @@ config param.</p>
<ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">docs &mdash; npm@1.2.11</p>
+<p id="footer">docs &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/edit.html b/deps/npm/html/doc/edit.html
index 293a66ac9..1859b6332 100644
--- a/deps/npm/html/doc/edit.html
+++ b/deps/npm/html/doc/edit.html
@@ -37,7 +37,7 @@ or <code>&quot;notepad&quot;</code> on Windows.</li><li>Type: path</li></ul>
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/explore.html">explore(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">edit &mdash; npm@1.2.11</p>
+<p id="footer">edit &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/explore.html b/deps/npm/html/doc/explore.html
index 5577e8596..3a761b622 100644
--- a/deps/npm/html/doc/explore.html
+++ b/deps/npm/html/doc/explore.html
@@ -40,7 +40,7 @@ Windows</li><li>Type: path</li></ul>
<ul><li><a href="../doc/submodule.html">submodule(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/edit.html">edit(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">explore &mdash; npm@1.2.11</p>
+<p id="footer">explore &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/faq.html b/deps/npm/html/doc/faq.html
index 81852a01b..db8c30a98 100644
--- a/deps/npm/html/doc/faq.html
+++ b/deps/npm/html/doc/faq.html
@@ -296,7 +296,7 @@ There is not sufficient need to impose namespace rules on everyone.</p>
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul>
</div>
-<p id="footer">faq &mdash; npm@1.2.11</p>
+<p id="footer">faq &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/folders.html b/deps/npm/html/doc/folders.html
index 7870b3fbf..b6fad396c 100644
--- a/deps/npm/html/doc/folders.html
+++ b/deps/npm/html/doc/folders.html
@@ -205,7 +205,7 @@ cannot be found elsewhere. See <code><a href="../doc/json.html">json(1)</a></co
<ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li></ul>
</div>
-<p id="footer">folders &mdash; npm@1.2.11</p>
+<p id="footer">folders &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/global.html b/deps/npm/html/doc/global.html
index 9bdd61bda..c1b470b24 100644
--- a/deps/npm/html/doc/global.html
+++ b/deps/npm/html/doc/global.html
@@ -205,7 +205,7 @@ cannot be found elsewhere. See <code><a href="../doc/json.html">json(1)</a></co
<ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li></ul>
</div>
-<p id="footer">global &mdash; npm@1.2.11</p>
+<p id="footer">global &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/help-search.html b/deps/npm/html/doc/help-search.html
index 6343d4ab2..b0a6e5d91 100644
--- a/deps/npm/html/doc/help-search.html
+++ b/deps/npm/html/doc/help-search.html
@@ -38,7 +38,7 @@ where the terms were found in the documentation.</p>
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li></ul>
</div>
-<p id="footer">help-search &mdash; npm@1.2.11</p>
+<p id="footer">help-search &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/help.html b/deps/npm/html/doc/help.html
index 623bce606..99172e941 100644
--- a/deps/npm/html/doc/help.html
+++ b/deps/npm/html/doc/help.html
@@ -36,7 +36,7 @@ matches are equivalent to specifying a topic name.</p>
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/help-search.html">help-search(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer">help &mdash; npm@1.2.11</p>
+<p id="footer">help &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/index.html b/deps/npm/html/doc/index.html
index c7e6af084..519be14a0 100644
--- a/deps/npm/html/doc/index.html
+++ b/deps/npm/html/doc/index.html
@@ -400,7 +400,7 @@
<p> Display npm username</p>
</div>
-<p id="footer">index &mdash; npm@1.2.11</p>
+<p id="footer">index &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/init.html b/deps/npm/html/doc/init.html
index b5ebffb4d..2d11b55dd 100644
--- a/deps/npm/html/doc/init.html
+++ b/deps/npm/html/doc/init.html
@@ -29,7 +29,7 @@ without a really good reason to do so.</p>
<ul><li><a href="https://github.com/isaacs/init-package-json">https://github.com/isaacs/init-package-json</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/version.html">version(1)</a></li></ul>
</div>
-<p id="footer">init &mdash; npm@1.2.11</p>
+<p id="footer">init &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/install.html b/deps/npm/html/doc/install.html
index 1a1680731..01a0220a5 100644
--- a/deps/npm/html/doc/install.html
+++ b/deps/npm/html/doc/install.html
@@ -136,7 +136,7 @@ affects a real use-case, it will be investigated.</p>
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/shrinkwrap.html">shrinkwrap(1)</a></li></ul>
</div>
-<p id="footer">install &mdash; npm@1.2.11</p>
+<p id="footer">install &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/json.html b/deps/npm/html/doc/json.html
index 5970718a7..b810f996f 100644
--- a/deps/npm/html/doc/json.html
+++ b/deps/npm/html/doc/json.html
@@ -525,7 +525,7 @@ overridden.</p>
<ul><li><a href="../doc/semver.html">semver(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/version.html">version(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li></ul>
</div>
-<p id="footer">json &mdash; npm@1.2.11</p>
+<p id="footer">json &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/link.html b/deps/npm/html/doc/link.html
index 72491138f..5d2d1b44f 100644
--- a/deps/npm/html/doc/link.html
+++ b/deps/npm/html/doc/link.html
@@ -58,7 +58,7 @@ installation target into your project&#39;s <code>node_modules</code> folder.</p
<ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">link &mdash; npm@1.2.11</p>
+<p id="footer">link &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/ls.html b/deps/npm/html/doc/ls.html
index bdd63237d..c95b0f749 100644
--- a/deps/npm/html/doc/ls.html
+++ b/deps/npm/html/doc/ls.html
@@ -25,7 +25,7 @@ limit the results to only the paths to the packages named. Note that
nested packages will <em>also</em> show the paths to the specified packages.
For example, running <code>npm ls promzard</code> in npm&#39;s source tree will show:</p>
-<pre><code>npm@1.2.11 /path/to/npm
+<pre><code>npm@1.2.12 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5</code></pre>
@@ -64,7 +64,7 @@ project.</p>
<ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/update.html">update(1)</a></li></ul>
</div>
-<p id="footer">ls &mdash; npm@1.2.11</p>
+<p id="footer">ls &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/npm.html b/deps/npm/html/doc/npm.html
index 09ff19a4c..d89af65e8 100644
--- a/deps/npm/html/doc/npm.html
+++ b/deps/npm/html/doc/npm.html
@@ -14,7 +14,7 @@
<h2 id="VERSION">VERSION</h2>
-<p>1.2.11</p>
+<p>1.2.12</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
@@ -135,7 +135,7 @@ will no doubt tell you to put the output in a gist or email.</p>
<ul><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/index.html">index(1)</a></li><li><a href="../api/npm.html">npm(3)</a></li></ul>
</div>
-<p id="footer">npm &mdash; npm@1.2.11</p>
+<p id="footer">npm &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/outdated.html b/deps/npm/html/doc/outdated.html
index b00991b51..9b972c00f 100644
--- a/deps/npm/html/doc/outdated.html
+++ b/deps/npm/html/doc/outdated.html
@@ -21,7 +21,7 @@ packages are currently outdated.</p>
<ul><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul>
</div>
-<p id="footer">outdated &mdash; npm@1.2.11</p>
+<p id="footer">outdated &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/owner.html b/deps/npm/html/doc/owner.html
index 105dd163c..2b187876e 100644
--- a/deps/npm/html/doc/owner.html
+++ b/deps/npm/html/doc/owner.html
@@ -34,7 +34,7 @@ that is not implemented at this time.</p>
<ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul>
</div>
-<p id="footer">owner &mdash; npm@1.2.11</p>
+<p id="footer">owner &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/pack.html b/deps/npm/html/doc/pack.html
index d386b816b..de98434b4 100644
--- a/deps/npm/html/doc/pack.html
+++ b/deps/npm/html/doc/pack.html
@@ -29,7 +29,7 @@ overwritten the second time.</p>
<ul><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">pack &mdash; npm@1.2.11</p>
+<p id="footer">pack &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/prefix.html b/deps/npm/html/doc/prefix.html
index 49aff1a10..368ae2e25 100644
--- a/deps/npm/html/doc/prefix.html
+++ b/deps/npm/html/doc/prefix.html
@@ -20,7 +20,7 @@
<ul><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">prefix &mdash; npm@1.2.11</p>
+<p id="footer">prefix &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/prune.html b/deps/npm/html/doc/prune.html
index e633dcfec..0dc9ea376 100644
--- a/deps/npm/html/doc/prune.html
+++ b/deps/npm/html/doc/prune.html
@@ -25,7 +25,7 @@ package&#39;s dependencies list.</p>
<ul><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
-<p id="footer">prune &mdash; npm@1.2.11</p>
+<p id="footer">prune &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/publish.html b/deps/npm/html/doc/publish.html
index 2fbc9cea4..d6964b9e2 100644
--- a/deps/npm/html/doc/publish.html
+++ b/deps/npm/html/doc/publish.html
@@ -29,7 +29,7 @@ the registry. Overwrites when the &quot;--force&quot; flag is set.</p>
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li></ul>
</div>
-<p id="footer">publish &mdash; npm@1.2.11</p>
+<p id="footer">publish &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/rebuild.html b/deps/npm/html/doc/rebuild.html
index 3f62305a5..c46f574cb 100644
--- a/deps/npm/html/doc/rebuild.html
+++ b/deps/npm/html/doc/rebuild.html
@@ -25,7 +25,7 @@ the new binary.</p>
<ul><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">rebuild &mdash; npm@1.2.11</p>
+<p id="footer">rebuild &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/registry.html b/deps/npm/html/doc/registry.html
index de0416957..89979c72a 100644
--- a/deps/npm/html/doc/registry.html
+++ b/deps/npm/html/doc/registry.html
@@ -95,7 +95,7 @@ ask for help on the <a href="mailto:npm-@googlegroups.com">npm-@googlegroups.com
<ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul>
</div>
-<p id="footer">registry &mdash; npm@1.2.11</p>
+<p id="footer">registry &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/removing-npm.html b/deps/npm/html/doc/removing-npm.html
index e575a9456..7c0898f30 100644
--- a/deps/npm/html/doc/removing-npm.html
+++ b/deps/npm/html/doc/removing-npm.html
@@ -58,7 +58,7 @@ modules. To track those down, you can do the following:</p>
<ul><li><a href="../doc/README.html">README</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li></ul>
</div>
-<p id="footer">removing-npm &mdash; npm@1.2.11</p>
+<p id="footer">removing-npm &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/restart.html b/deps/npm/html/doc/restart.html
index b9b83d73e..6e9487c96 100644
--- a/deps/npm/html/doc/restart.html
+++ b/deps/npm/html/doc/restart.html
@@ -24,7 +24,7 @@ the &quot;start&quot; script.</p>
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">restart &mdash; npm@1.2.11</p>
+<p id="footer">restart &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/rm.html b/deps/npm/html/doc/rm.html
index 97331bf65..81225b41e 100644
--- a/deps/npm/html/doc/rm.html
+++ b/deps/npm/html/doc/rm.html
@@ -22,7 +22,7 @@ on its behalf.</p>
<ul><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">rm &mdash; npm@1.2.11</p>
+<p id="footer">rm &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/root.html b/deps/npm/html/doc/root.html
index 165e337f4..56f847a86 100644
--- a/deps/npm/html/doc/root.html
+++ b/deps/npm/html/doc/root.html
@@ -20,7 +20,7 @@
<ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">root &mdash; npm@1.2.11</p>
+<p id="footer">root &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/run-script.html b/deps/npm/html/doc/run-script.html
index 0d9548d75..5c71b8fc9 100644
--- a/deps/npm/html/doc/run-script.html
+++ b/deps/npm/html/doc/run-script.html
@@ -23,7 +23,7 @@ called directly, as well.</p>
<ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">run-script &mdash; npm@1.2.11</p>
+<p id="footer">run-script &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/scripts.html b/deps/npm/html/doc/scripts.html
index aade7cf1a..50ace45b8 100644
--- a/deps/npm/html/doc/scripts.html
+++ b/deps/npm/html/doc/scripts.html
@@ -218,7 +218,7 @@ will sudo the npm command in question.</li></ul>
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">scripts &mdash; npm@1.2.11</p>
+<p id="footer">scripts &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/search.html b/deps/npm/html/doc/search.html
index 8a201ae30..fd9cef159 100644
--- a/deps/npm/html/doc/search.html
+++ b/deps/npm/html/doc/search.html
@@ -24,7 +24,7 @@ expression characters must be escaped or quoted in most shells.)</p>
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/view.html">view(1)</a></li></ul>
</div>
-<p id="footer">search &mdash; npm@1.2.11</p>
+<p id="footer">search &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/semver.html b/deps/npm/html/doc/semver.html
index 410695dd8..958be484b 100644
--- a/deps/npm/html/doc/semver.html
+++ b/deps/npm/html/doc/semver.html
@@ -104,7 +104,7 @@ that satisfies the range, or null if none of them do.</li></ul>
<ul><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">semver &mdash; npm@1.2.11</p>
+<p id="footer">semver &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/shrinkwrap.html b/deps/npm/html/doc/shrinkwrap.html
index efed37184..e76548c32 100644
--- a/deps/npm/html/doc/shrinkwrap.html
+++ b/deps/npm/html/doc/shrinkwrap.html
@@ -169,7 +169,7 @@ versions.</p>
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
-<p id="footer">shrinkwrap &mdash; npm@1.2.11</p>
+<p id="footer">shrinkwrap &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/star.html b/deps/npm/html/doc/star.html
index 7f7cb787f..fdd1f8608 100644
--- a/deps/npm/html/doc/star.html
+++ b/deps/npm/html/doc/star.html
@@ -26,7 +26,7 @@ a vaguely positive way to show that you care.</p>
<ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
</div>
-<p id="footer">star &mdash; npm@1.2.11</p>
+<p id="footer">star &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/stars.html b/deps/npm/html/doc/stars.html
index a3204e6aa..382cb9772 100644
--- a/deps/npm/html/doc/stars.html
+++ b/deps/npm/html/doc/stars.html
@@ -25,7 +25,7 @@ you will most certainly enjoy this command.</p>
<ul><li><a href="../doc/star.html">star(1)</a></li><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
</div>
-<p id="footer">stars &mdash; npm@1.2.11</p>
+<p id="footer">stars &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/start.html b/deps/npm/html/doc/start.html
index 4a42ee1e1..a5f357f46 100644
--- a/deps/npm/html/doc/start.html
+++ b/deps/npm/html/doc/start.html
@@ -20,7 +20,7 @@
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">start &mdash; npm@1.2.11</p>
+<p id="footer">start &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/stop.html b/deps/npm/html/doc/stop.html
index 98a4b5c90..f08a32a8f 100644
--- a/deps/npm/html/doc/stop.html
+++ b/deps/npm/html/doc/stop.html
@@ -20,7 +20,7 @@
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li></ul>
</div>
-<p id="footer">stop &mdash; npm@1.2.11</p>
+<p id="footer">stop &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/submodule.html b/deps/npm/html/doc/submodule.html
index fdb7797d3..52e3dc8eb 100644
--- a/deps/npm/html/doc/submodule.html
+++ b/deps/npm/html/doc/submodule.html
@@ -33,7 +33,7 @@ dependencies into the submodule folder.</p>
<ul><li><a href="../doc/json.html">json(1)</a></li><li>git help submodule</li></ul>
</div>
-<p id="footer">submodule &mdash; npm@1.2.11</p>
+<p id="footer">submodule &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/tag.html b/deps/npm/html/doc/tag.html
index a7290cade..d5a2d2f93 100644
--- a/deps/npm/html/doc/tag.html
+++ b/deps/npm/html/doc/tag.html
@@ -21,7 +21,7 @@
<ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">tag &mdash; npm@1.2.11</p>
+<p id="footer">tag &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/test.html b/deps/npm/html/doc/test.html
index 297062f22..171a4b6e8 100644
--- a/deps/npm/html/doc/test.html
+++ b/deps/npm/html/doc/test.html
@@ -23,7 +23,7 @@ true.</p>
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">test &mdash; npm@1.2.11</p>
+<p id="footer">test &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/uninstall.html b/deps/npm/html/doc/uninstall.html
index 1632ff27e..20465e80b 100644
--- a/deps/npm/html/doc/uninstall.html
+++ b/deps/npm/html/doc/uninstall.html
@@ -22,7 +22,7 @@ on its behalf.</p>
<ul><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">uninstall &mdash; npm@1.2.11</p>
+<p id="footer">uninstall &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/unpublish.html b/deps/npm/html/doc/unpublish.html
index 92636e134..23bf755ed 100644
--- a/deps/npm/html/doc/unpublish.html
+++ b/deps/npm/html/doc/unpublish.html
@@ -34,7 +34,7 @@ the root package entry is removed from the registry entirely.</p>
<ul><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul>
</div>
-<p id="footer">unpublish &mdash; npm@1.2.11</p>
+<p id="footer">unpublish &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/update.html b/deps/npm/html/doc/update.html
index 9652a53a4..4e21edc67 100644
--- a/deps/npm/html/doc/update.html
+++ b/deps/npm/html/doc/update.html
@@ -26,7 +26,7 @@ If no package name is specified, all packages in the specified location (global
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
-<p id="footer">update &mdash; npm@1.2.11</p>
+<p id="footer">update &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/version.html b/deps/npm/html/doc/version.html
index 953db5eb1..8af678c47 100644
--- a/deps/npm/html/doc/version.html
+++ b/deps/npm/html/doc/version.html
@@ -49,7 +49,7 @@ Enter passphrase:</code></pre>
<ul><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/semver.html">semver(1)</a></li></ul>
</div>
-<p id="footer">version &mdash; npm@1.2.11</p>
+<p id="footer">version &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/view.html b/deps/npm/html/doc/view.html
index 1a36e1194..daaa5f15f 100644
--- a/deps/npm/html/doc/view.html
+++ b/deps/npm/html/doc/view.html
@@ -90,7 +90,7 @@ the field name.</p>
<ul><li><a href="../doc/search.html">search(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/docs.html">docs(1)</a></li></ul>
</div>
-<p id="footer">view &mdash; npm@1.2.11</p>
+<p id="footer">view &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/whoami.html b/deps/npm/html/doc/whoami.html
index 0b07228d7..397002467 100644
--- a/deps/npm/html/doc/whoami.html
+++ b/deps/npm/html/doc/whoami.html
@@ -20,7 +20,7 @@
<ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
</div>
-<p id="footer">whoami &mdash; npm@1.2.11</p>
+<p id="footer">whoami &mdash; npm@1.2.12</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/lib/cache.js b/deps/npm/lib/cache.js
index a7a7a4216..13d726429 100644
--- a/deps/npm/lib/cache.js
+++ b/deps/npm/lib/cache.js
@@ -739,7 +739,7 @@ function addNameVersion (name, ver, data, cb) {
// only add non-shasum'ed packages if --forced.
// only ancient things would lack this for good reasons nowadays.
if (!dist.shasum && !npm.config.get("force")) {
- return cb(new Error("package lacks shasum"))
+ return cb(new Error("package lacks shasum: " + data._id))
}
return addRemoteTarball( tb
, dist.shasum
diff --git a/deps/npm/man/man1/ls.1 b/deps/npm/man/man1/ls.1
index fadb701f2..5d7fd8a05 100644
--- a/deps/npm/man/man1/ls.1
+++ b/deps/npm/man/man1/ls.1
@@ -29,7 +29,7 @@ For example, running \fBnpm ls promzard\fR in npm\'s source tree will show:
.IP "" 4
.
.nf
-npm@1.2.11 /path/to/npm
+npm@1.2.12 /path/to/npm
└─┬ init\-package\-json@0\.0\.4
└── promzard@0\.1\.5
.
diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1
index b0bc36d8f..51c41d885 100644
--- a/deps/npm/man/man1/npm.1
+++ b/deps/npm/man/man1/npm.1
@@ -14,7 +14,7 @@ npm <command> [args]
.fi
.
.SH "VERSION"
-1.2.11
+1.2.12
.
.SH "DESCRIPTION"
npm is the package manager for the Node JavaScript platform\. It puts
diff --git a/deps/npm/man/man3/npm.3 b/deps/npm/man/man3/npm.3
index 06d00903e..477d2df94 100644
--- a/deps/npm/man/man3/npm.3
+++ b/deps/npm/man/man3/npm.3
@@ -21,7 +21,7 @@ npm\.load([configObject,] function (er, npm) {
.fi
.
.SH "VERSION"
-1.2.11
+1.2.12
.
.SH "DESCRIPTION"
This is the API documentation for npm\.
diff --git a/deps/npm/node_modules/npm-registry-client/lib/publish.js b/deps/npm/node_modules/npm-registry-client/lib/publish.js
index b44b801b3..f657d44dc 100644
--- a/deps/npm/node_modules/npm-registry-client/lib/publish.js
+++ b/deps/npm/node_modules/npm-registry-client/lib/publish.js
@@ -72,22 +72,23 @@ function publish (data, tarball, cb) {
this.request("GET", data.name, function (er, fullData) {
if (er) return cb(er)
+ function handle(er) {
+ if (er.message.indexOf("conflict Document update conflict.") === 0) {
+ return cb(conflictError.call(this, data._id));
+ }
+ this.log.error("publish", "Error uploading package");
+ return cb(er)
+ }
+
var exists = fullData.versions && fullData.versions[data.version]
if (exists) return cb(conflictError.call(this, data._id))
- this.request("PUT", dataURI, data, function (er) {
- if (er) {
- if (er.message.indexOf("conflict Document update conflict.") === 0) {
- return cb(conflictError.call(this, data._id))
- }
- this.log.error("publish", "Error sending version data")
- return cb(er)
- }
-
- this.log.verbose("publish", "attach 2", [data.name, tarball, tbName])
- attach.call(this, data.name, tarball, tbName, function (er) {
- this.log.verbose("publish", "attach 3"
- ,[er, data.name])
+ var rev = fullData._rev;
+ attach.call(this, data.name, tarball, tbName, rev, function (er) {
+ if (er) return handle(er)
+ this.log.verbose("publish", "attached", [data.name, tarball, tbName])
+ this.request("PUT", dataURI, data, function (er) {
+ if (er) return handle(er)
return cb(er)
}.bind(this))
}.bind(this))
@@ -102,15 +103,10 @@ function conflictError (pkgid) {
return e
}
-function attach (doc, file, filename, cb) {
+function attach (doc, file, filename, rev, cb) {
doc = encodeURIComponent(doc)
- this.request("GET", doc, function (er, d) {
- if (er) return cb(er)
- if (!d) return cb(new Error(
- "Attempting to upload to invalid doc "+doc))
- var rev = "-rev/"+d._rev
- , attURI = doc + "/-/" + encodeURIComponent(filename) + "/" + rev
- this.log.verbose("uploading", [attURI, file])
- this.upload(attURI, file, cb)
- }.bind(this))
+ var revu = "-rev/"+rev
+ , attURI = doc + "/-/" + encodeURIComponent(filename) + "/" + revu
+ this.log.verbose("uploading", [attURI, file])
+ this.upload(attURI, file, cb)
}
diff --git a/deps/npm/node_modules/npm-registry-client/package.json b/deps/npm/node_modules/npm-registry-client/package.json
index 5b23a9ec4..a31b62a56 100644
--- a/deps/npm/node_modules/npm-registry-client/package.json
+++ b/deps/npm/node_modules/npm-registry-client/package.json
@@ -6,7 +6,7 @@
},
"name": "npm-registry-client",
"description": "Client for the npm registry",
- "version": "0.2.16",
+ "version": "0.2.17",
"repository": {
"url": "git://github.com/isaacs/npm-registry-client"
},
@@ -35,6 +35,10 @@
"license": "BSD",
"readme": "# npm-registry-client\n\nThe code that npm uses to talk to the registry.\n\nIt handles all the caching and HTTP calls.\n\n## Usage\n\n```javascript\nvar RegClient = require('npm-registry-client')\nvar client = new RegClient(config)\n\nclient.get(\"npm\", \"latest\", 1000, function (er, data, raw, res) {\n // error is an error if there was a problem.\n // data is the parsed data object\n // raw is the json string\n // res is the response from couch\n})\n```\n\n# Configuration\n\nThis program is designed to work with\n[npmconf](https://npmjs.org/package/npmconf), but you can also pass in\na plain-jane object with the appropriate configs, and it'll shim it\nfor you. Any configuration thingie that has get/set/del methods will\nalso be accepted.\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `always-auth` {Boolean} Auth even for GET requests.\n* `auth` {String} A base64-encoded `username:password`\n* `email` {String} User's email address\n* `tag` {String} The default tag to use when publishing new packages.\n Default = `\"latest\"`\n* `ca` {String} Cerficate signing authority certificates to trust.\n* `strict-ssl` {Boolean} Whether or not to be strict with SSL\n certificates. Default = `true`\n* `user-agent` {String} User agent header to send. Default =\n `\"node/{process.version} {process.platform} {process.arch}\"`\n* `log` {Object} The logger to use. Defaults to `require(\"npmlog\")` if\n that works, otherwise logs are disabled.\n* `fetch-retries` {Number} Number of times to retry on GET failures.\n Default=2\n* `fetch-retry-factor` {Number} `factor` setting for `node-retry`. Default=10\n* `fetch-retry-mintimeout` {Number} `minTimeout` setting for `node-retry`.\n Default=10000 (10 seconds)\n* `fetch-retry-maxtimeout` {Number} `maxTimeout` setting for `node-retry`.\n Default=60000 (60 seconds)\n* `proxy` {URL} The url to proxy requests through.\n* `https-proxy` {URL} The url to proxy https requests through.\n Defaults to be the same as `proxy` if unset.\n* `_auth` {String} The base64-encoded authorization header.\n* `username` `_password` {String} Username/password to use to generate\n `_auth` if not supplied.\n* `_token` {Object} A token for use with\n [couch-login](https://npmjs.org/package/couch-login)\n\n# client.request(method, where, [what], [etag], [nofollow], cb)\n\n* `method` {String} HTTP method\n* `where` {String} Path to request on the server\n* `what` {Stream | Buffer | String | Object} The request body. Objects\n that are not Buffers or Streams are encoded as JSON.\n* `etag` {String} The cached ETag\n* `nofollow` {Boolean} Prevent following 302/301 responses\n* `cb` {Function}\n * `error` {Error | null}\n * `data` {Object} the parsed data object\n * `raw` {String} the json\n * `res` {Response Object} response from couch\n\nMake a request to the registry. All the other methods are wrappers\naround this. one.\n\n# client.adduser(username, password, email, cb)\n\n* `username` {String}\n* `password` {String}\n* `email` {String}\n* `cb` {Function}\n\nAdd a user account to the registry, or verify the credentials.\n\n# client.get(url, [timeout], [nofollow], [staleOk], cb)\n\n* `url` {String} The url path to fetch\n* `timeout` {Number} Number of seconds old that a cached copy must be\n before a new request will be made.\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `staleOk` {Boolean} If there's cached data available, then return that\n to the callback quickly, and update the cache the background.\n\nFetches data from the registry via a GET request, saving it in\nthe cache folder with the ETag.\n\n# client.publish(data, tarball, [readme], cb)\n\n* `data` {Object} Package data\n* `tarball` {String | Stream} Filename or stream of the package tarball\n* `readme` {String} Contents of the README markdown file\n* `cb` {Function}\n\nPublish a package to the registry.\n\nNote that this does not create the tarball from a folder. However, it\ncan accept a gzipped tar stream or a filename to a tarball.\n\n# client.star(package, starred, cb)\n\n* `package` {String} Name of the package to star\n* `starred` {Boolean} True to star the package, false to unstar it.\n* `cb` {Function}\n\nStar or unstar a package.\n\nNote that the user does not have to be the package owner to star or\nunstar a package, though other writes do require that the user be the\npackage owner.\n\n# client.stars(username, cb)\n\n* `username` {String} Name of user to fetch starred packages for.\n* `cb` {Function}\n\nView your own or another user's starred packages.\n\n# client.tag(project, version, tag, cb)\n\n* `project` {String} Project name\n* `version` {String} Version to tag\n* `tag` {String} Tag name to apply\n* `cb` {Function}\n\nMark a version in the `dist-tags` hash, so that `pkg@tag`\nwill fetch the specified version.\n\n# client.unpublish(name, [ver], cb)\n\n* `name` {String} package name\n* `ver` {String} version to unpublish. Leave blank to unpublish all\n versions.\n* `cb` {Function}\n\nRemove a version of a package (or all versions) from the registry. When\nthe last version us unpublished, the entire document is removed from the\ndatabase.\n\n# client.upload(where, file, [etag], [nofollow], cb)\n\n* `where` {String} URL path to upload to\n* `file` {String | Stream} Either the filename or a readable stream\n* `etag` {String} Cache ETag\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `cb` {Function}\n\nUpload an attachment. Mostly used by `client.publish()`.\n",
"readmeFilename": "README.md",
- "_id": "npm-registry-client@0.2.16",
- "_from": "npm-registry-client@latest"
+ "_id": "npm-registry-client@0.2.17",
+ "dist": {
+ "shasum": "1df2bbecac6751f5d9600fb43722aef96d956773"
+ },
+ "_from": "npm-registry-client@0.2.17",
+ "_resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-0.2.17.tgz"
}
diff --git a/deps/npm/package.json b/deps/npm/package.json
index 517cac5ff..b804b8770 100644
--- a/deps/npm/package.json
+++ b/deps/npm/package.json
@@ -1,5 +1,5 @@
{
- "version": "1.2.11",
+ "version": "1.2.12",
"name": "npm",
"publishConfig": {
"proprietary-attribs": false
diff --git a/deps/openssl/README.chromium b/deps/openssl/README.chromium
deleted file mode 100644
index aec361b66..000000000
--- a/deps/openssl/README.chromium
+++ /dev/null
@@ -1,96 +0,0 @@
-Name: openssl
-URL: http://openssl.org/source/
-Version: 1.0.0f
-License: BSDish
-License File: openssl/LICENSE
-
-Description:
-This is OpenSSL, the standard SSL/TLS library, which is used only in Android.
-
-It's an unmodified, upstream source except for the patches listed below.
-
-
-********************************************************************************
-The following patches are taken from Android Open Source Project.
-
-
-progs.patch:
-
-Fixup sources under the apps/ directory that are not built under the android environment.
-
-
-small_records.patch:
-
-Reduce OpenSSL memory consumption.
-SSL records may be as large as 16K, but are typically < 2K. In
-addition, a historic bug in Windows allowed records to be as large
-32K. OpenSSL statically allocates read and write buffers (34K and
-18K respectively) used for processing records.
-With this patch, OpenSSL statically allocates 4K + 4K buffers, with
-the option of dynamically growing buffers to 34K + 4K, which is a
-saving of 44K per connection for the typical case.
-
-
-handshake_cutthrough.patch
-
-Enables SSL3+ clients to send application data immediately following the
-Finished message even when negotiating full-handshakes. With this patch,
-clients can negotiate SSL connections in 1-RTT even when performing
-full-handshakes.
-
-
-jsse.patch
-
-Support for JSSE implementation based on OpenSSL.
-
-
-npn.patch
-
-Transport Layer Security (TLS) Next Protocol Negotiation Extension
-
-
-sha1_armv4_large.patch
-
-This patch eliminates memory stores to addresses below SP.
-
-
-openssl_no_dtls1.patch
-
-Add missing #ifndef OPENSSL_NO_DTLS1
-
-
-********************************************************************************
-The following patches are needed to compile this openssl on Chromium and pass
-the related net unit tests.
-
-
-empty_OPENSSL_cpuid_setup.patch
-
-Use a empty implementation for function OPENSSL_cpuid_setup to resolve link
-error. We should figure out how to geenrate platform specific implementation
-of OPENSSL_cpuid_setup by leveraging crypto/*cpuid.pl.
-
-
-x509_hash_name_algorithm_change.patch
-
-There are many symbolic links under /etc/ssl/certs created by using hash of
-the pem certificates in order for OpenSSL to find those certificate.
-Openssl has a tool to help you create hash symbolic links. (See tools/c_rehash)
-However the new openssl changed the hash algorithm, Unless you compile/install
-the latest openssl library and re-create all related symbolic links, the new
-openssl can not find some certificates because the links of those certificates
-were created by using old hash algorithm, which causes some tests failed.
-This patch gives a way to find a certificate according to its hash by using both
-new algorithm and old algorithm.
-crbug.com/111045 is used to track this issue.
-
-
-tls_exporter.patch
-
-Keying Material Exporters for Transport Layer Security (RFC 5705).
-
-
-Android platform support
-
-Copy config/android/openssl/opensslconf.h from Android's
-external/openssl/include/openssl/opensslconf.h
diff --git a/deps/openssl/asm/Makefile b/deps/openssl/asm/Makefile
index 383d5f64c..9f54785b4 100644
--- a/deps/openssl/asm/Makefile
+++ b/deps/openssl/asm/Makefile
@@ -3,6 +3,7 @@ PERL += -I../openssl/crypto/perlasm -I../openssl/crypto/bn/asm
OUTPUTS = \
x86-elf-gas/aes/aes-586.s \
+ x86-elf-gas/aes/aesni-x86.s \
x86-elf-gas/bf/bf-686.s \
x86-elf-gas/bn/x86-mont.s \
x86-elf-gas/bn/x86.s \
@@ -20,15 +21,20 @@ OUTPUTS = \
x86-elf-gas/whrlpool/wp-mmx.s \
x86-elf-gas/x86cpuid.s \
x64-elf-gas/aes/aes-x86_64.s \
+ x64-elf-gas/aes/aesni-x86_64.s \
+ x64-elf-gas/aes/aesni-sha1-x86_64.s \
+ x64-elf-gas/bn/modexp512-x86_64.s \
x64-elf-gas/bn/x86_64-mont.s \
x64-elf-gas/camellia/cmll-x86_64.s \
x64-elf-gas/md5/md5-x86_64.s \
x64-elf-gas/rc4/rc4-x86_64.s \
+ x64-elf-gas/rc4/rc4-md5-x86_64.s \
x64-elf-gas/sha/sha1-x86_64.s \
x64-elf-gas/sha/sha512-x86_64.s \
x64-elf-gas/whrlpool/wp-x86_64.s \
x64-elf-gas/x86_64cpuid.s \
x86-macosx-gas/aes/aes-586.s \
+ x86-macosx-gas/aes/aesni-x86.s \
x86-macosx-gas/bf/bf-686.s \
x86-macosx-gas/bn/x86-mont.s \
x86-macosx-gas/bn/x86.s \
@@ -46,15 +52,20 @@ OUTPUTS = \
x86-macosx-gas/whrlpool/wp-mmx.s \
x86-macosx-gas/x86cpuid.s \
x64-macosx-gas/aes/aes-x86_64.s \
+ x64-macosx-gas/aes/aesni-x86_64.s \
+ x64-macosx-gas/aes/aesni-sha1-x86_64.s \
+ x64-macosx-gas/bn/modexp512-x86_64.s \
x64-macosx-gas/bn/x86_64-mont.s \
x64-macosx-gas/camellia/cmll-x86_64.s \
x64-macosx-gas/md5/md5-x86_64.s \
x64-macosx-gas/rc4/rc4-x86_64.s \
+ x64-macosx-gas/rc4/rc4-md5-x86_64.s \
x64-macosx-gas/sha/sha1-x86_64.s \
x64-macosx-gas/sha/sha512-x86_64.s \
x64-macosx-gas/whrlpool/wp-x86_64.s \
x64-macosx-gas/x86_64cpuid.s \
x86-win32-masm/aes/aes-586.asm \
+ x86-win32-masm/aes/aesni-x86.asm \
x86-win32-masm/bf/bf-686.asm \
x86-win32-masm/bn/x86-mont.asm \
x86-win32-masm/bn/x86.asm \
@@ -72,10 +83,14 @@ OUTPUTS = \
x86-win32-masm/whrlpool/wp-mmx.asm \
x86-win32-masm/x86cpuid.asm \
x64-win32-masm/aes/aes-x86_64.asm \
+ x64-win32-masm/aes/aesni-x86_64.asm \
+ x64-win32-masm/aes/aesni-sha1-x86_64.asm \
+ x64-win32-masm/bn/modexp512-x86_64.asm \
x64-win32-masm/bn/x86_64-mont.asm \
x64-win32-masm/camellia/cmll-x86_64.asm \
x64-win32-masm/md5/md5-x86_64.asm \
x64-win32-masm/rc4/rc4-x86_64.asm \
+ x64-win32-masm/rc4/rc4-md5-x86_64.asm \
x64-win32-masm/sha/sha1-x86_64.asm \
x64-win32-masm/sha/sha512-x86_64.asm \
x64-win32-masm/whrlpool/wp-x86_64.asm \
@@ -103,33 +118,46 @@ clean:
find . -iname '*.s' -exec rm "{}" \;
x64-elf-gas/aes/aes-x86_64.s: ../openssl/crypto/aes/asm/aes-x86_64.pl
+x64-elf-gas/aes/aesni-x86_64.s: ../openssl/crypto/aes/asm/aesni-x86_64.pl
+x64-elf-gas/aes/aesni-sha1-x86_64.s: ../openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
+x64-elf-gas/bn/modexp512-x86_64.s: ../openssl/crypto/bn/asm/modexp512-x86_64.pl
x64-elf-gas/bn/x86_64-mont.s: ../openssl/crypto/bn/asm/x86_64-mont.pl
x64-elf-gas/camellia/cmll-x86_64.s: ../openssl/crypto/camellia/asm/cmll-x86_64.pl
x64-elf-gas/md5/md5-x86_64.s: ../openssl/crypto/md5/asm/md5-x86_64.pl
x64-elf-gas/rc4/rc4-x86_64.s: ../openssl/crypto/rc4/asm/rc4-x86_64.pl
+x64-elf-gas/rc4/rc4-md5-x86_64.s: ../openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
x64-elf-gas/sha/sha1-x86_64.s: ../openssl/crypto/sha/asm/sha1-x86_64.pl
x64-elf-gas/sha/sha512-x86_64.s: ../openssl/crypto/sha/asm/sha512-x86_64.pl
x64-elf-gas/whrlpool/wp-x86_64.s: ../openssl/crypto/whrlpool/asm/wp-x86_64.pl
x64-elf-gas/x86_64cpuid.s: ../openssl/crypto/x86_64cpuid.pl
x64-macosx-gas/aes/aes-x86_64.s: ../openssl/crypto/aes/asm/aes-x86_64.pl
+x64-macosx-gas/aes/aesni-x86_64.s: ../openssl/crypto/aes/asm/aesni-x86_64.pl
+x64-macosx-gas/aes/aesni-sha1-x86_64.s: ../openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
+x64-macosx-gas/bn/modexp512-x86_64.s: ../openssl/crypto/bn/asm/modexp512-x86_64.pl
x64-macosx-gas/bn/x86_64-mont.s: ../openssl/crypto/bn/asm/x86_64-mont.pl
x64-macosx-gas/camellia/cmll-x86_64.s: ../openssl/crypto/camellia/asm/cmll-x86_64.pl
x64-macosx-gas/md5/md5-x86_64.s: ../openssl/crypto/md5/asm/md5-x86_64.pl
x64-macosx-gas/rc4/rc4-x86_64.s: ../openssl/crypto/rc4/asm/rc4-x86_64.pl
+x64-macosx-gas/rc4/rc4-md5-x86_64.s: ../openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
x64-macosx-gas/sha/sha1-x86_64.s: ../openssl/crypto/sha/asm/sha1-x86_64.pl
x64-macosx-gas/sha/sha512-x86_64.s: ../openssl/crypto/sha/asm/sha512-x86_64.pl
x64-macosx-gas/whrlpool/wp-x86_64.s: ../openssl/crypto/whrlpool/asm/wp-x86_64.pl
x64-macosx-gas/x86_64cpuid.s: ../openssl/crypto/x86_64cpuid.pl
x64-win32-masm/aes/aes-x86_64.asm: ../openssl/crypto/aes/asm/aes-x86_64.pl
+x64-win32-masm/aes/aesni-x86_64.asm: ../openssl/crypto/aes/asm/aesni-x86_64.pl
+x64-win32-masm/aes/aesni-sha1-x86_64.asm: ../openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
+x64-win32-masm/bn/modexp512-x86_64.asm: ../openssl/crypto/bn/asm/modexp512-x86_64.pl
x64-win32-masm/bn/x86_64-mont.asm: ../openssl/crypto/bn/asm/x86_64-mont.pl
x64-win32-masm/camellia/cmll-x86_64.asm: ../openssl/crypto/camellia/asm/cmll-x86_64.pl
x64-win32-masm/md5/md5-x86_64.asm: ../openssl/crypto/md5/asm/md5-x86_64.pl
x64-win32-masm/rc4/rc4-x86_64.asm: ../openssl/crypto/rc4/asm/rc4-x86_64.pl
+x64-win32-masm/rc4/rc4-md5-x86_64.asm: ../openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
x64-win32-masm/sha/sha1-x86_64.asm: ../openssl/crypto/sha/asm/sha1-x86_64.pl
x64-win32-masm/sha/sha512-x86_64.asm: ../openssl/crypto/sha/asm/sha512-x86_64.pl
x64-win32-masm/whrlpool/wp-x86_64.asm: ../openssl/crypto/whrlpool/asm/wp-x86_64.pl
x64-win32-masm/x86_64cpuid.asm: ../openssl/crypto/x86_64cpuid.pl
x86-elf-gas/aes/aes-586.s: ../openssl/crypto/aes/asm/aes-586.pl
+x86-elf-gas/aes/aesni-x86.s: ../openssl/crypto/aes/asm/aesni-x86.pl
x86-elf-gas/bf/bf-686.s: ../openssl/crypto/bf/asm/bf-686.pl
x86-elf-gas/bn/x86-mont.s: ../openssl/crypto/bn/asm/x86-mont.pl
x86-elf-gas/bn/x86.s: ../openssl/crypto/bn/asm/x86.pl
@@ -147,6 +175,7 @@ x86-elf-gas/sha/sha512-586.s: ../openssl/crypto/sha/asm/sha512-586.pl
x86-elf-gas/whrlpool/wp-mmx.s: ../openssl/crypto/whrlpool/asm/wp-mmx.pl
x86-elf-gas/x86cpuid.s: ../openssl/crypto/x86cpuid.pl
x86-macosx-gas/aes/aes-586.s: ../openssl/crypto/aes/asm/aes-586.pl
+x86-macosx-gas/aes/aesni-x86.s: ../openssl/crypto/aes/asm/aesni-x86.pl
x86-macosx-gas/bf/bf-686.s: ../openssl/crypto/bf/asm/bf-686.pl
x86-macosx-gas/bn/x86-mont.s: ../openssl/crypto/bn/asm/x86-mont.pl
x86-macosx-gas/bn/x86.s: ../openssl/crypto/bn/asm/x86.pl
@@ -164,6 +193,7 @@ x86-macosx-gas/sha/sha512-586.s: ../openssl/crypto/sha/asm/sha512-586.pl
x86-macosx-gas/whrlpool/wp-mmx.s: ../openssl/crypto/whrlpool/asm/wp-mmx.pl
x86-macosx-gas/x86cpuid.s: ../openssl/crypto/x86cpuid.pl
x86-win32-masm/aes/aes-586.asm: ../openssl/crypto/aes/asm/aes-586.pl
+x86-win32-masm/aes/aesni-x86.asm: ../openssl/crypto/aes/asm/aesni-x86.pl
x86-win32-masm/bf/bf-686.asm: ../openssl/crypto/bf/asm/bf-686.pl
x86-win32-masm/bn/x86.asm: ../openssl/crypto/bn/asm/x86.pl
x86-win32-masm/bn/x86-mont.asm: ../openssl/crypto/bn/asm/x86-mont.pl
diff --git a/deps/openssl/asm/x64-elf-gas/aes/aes-x86_64.s b/deps/openssl/asm/x64-elf-gas/aes/aes-x86_64.s
index d7feffbfa..e7c261fe4 100644
--- a/deps/openssl/asm/x64-elf-gas/aes/aes-x86_64.s
+++ b/deps/openssl/asm/x64-elf-gas/aes/aes-x86_64.s
@@ -333,6 +333,9 @@ _x86_64_AES_encrypt_compact:
.globl AES_encrypt
.type AES_encrypt,@function
.align 16
+.globl asm_AES_encrypt
+.hidden asm_AES_encrypt
+asm_AES_encrypt:
AES_encrypt:
pushq %rbx
pushq %rbp
@@ -780,6 +783,9 @@ _x86_64_AES_decrypt_compact:
.globl AES_decrypt
.type AES_decrypt,@function
.align 16
+.globl asm_AES_decrypt
+.hidden asm_AES_decrypt
+asm_AES_decrypt:
AES_decrypt:
pushq %rbx
pushq %rbp
@@ -843,10 +849,10 @@ AES_decrypt:
.Ldec_epilogue:
.byte 0xf3,0xc3
.size AES_decrypt,.-AES_decrypt
-.globl AES_set_encrypt_key
-.type AES_set_encrypt_key,@function
+.globl private_AES_set_encrypt_key
+.type private_AES_set_encrypt_key,@function
.align 16
-AES_set_encrypt_key:
+private_AES_set_encrypt_key:
pushq %rbx
pushq %rbp
pushq %r12
@@ -867,7 +873,7 @@ AES_set_encrypt_key:
addq $56,%rsp
.Lenc_key_epilogue:
.byte 0xf3,0xc3
-.size AES_set_encrypt_key,.-AES_set_encrypt_key
+.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
.type _x86_64_AES_set_encrypt_key,@function
.align 16
@@ -1109,10 +1115,10 @@ _x86_64_AES_set_encrypt_key:
.byte 0xf3,0xc3
.size _x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
-.globl AES_set_decrypt_key
-.type AES_set_decrypt_key,@function
+.globl private_AES_set_decrypt_key
+.type private_AES_set_decrypt_key,@function
.align 16
-AES_set_decrypt_key:
+private_AES_set_decrypt_key:
pushq %rbx
pushq %rbp
pushq %r12
@@ -1295,11 +1301,14 @@ AES_set_decrypt_key:
addq $56,%rsp
.Ldec_key_epilogue:
.byte 0xf3,0xc3
-.size AES_set_decrypt_key,.-AES_set_decrypt_key
+.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
.globl AES_cbc_encrypt
.type AES_cbc_encrypt,@function
.align 16
+.globl asm_AES_cbc_encrypt
+.hidden asm_AES_cbc_encrypt
+asm_AES_cbc_encrypt:
AES_cbc_encrypt:
cmpq $0,%rdx
je .Lcbc_epilogue
diff --git a/deps/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s b/deps/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s
new file mode 100644
index 000000000..8f0475e0d
--- /dev/null
+++ b/deps/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s
@@ -0,0 +1,1402 @@
+.text
+
+
+
+.globl aesni_cbc_sha1_enc
+.type aesni_cbc_sha1_enc,@function
+.align 16
+aesni_cbc_sha1_enc:
+
+ movl OPENSSL_ia32cap_P+0(%rip),%r10d
+ movl OPENSSL_ia32cap_P+4(%rip),%r11d
+ jmp aesni_cbc_sha1_enc_ssse3
+ .byte 0xf3,0xc3
+.size aesni_cbc_sha1_enc,.-aesni_cbc_sha1_enc
+.type aesni_cbc_sha1_enc_ssse3,@function
+.align 16
+aesni_cbc_sha1_enc_ssse3:
+ movq 8(%rsp),%r10
+
+
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ leaq -104(%rsp),%rsp
+
+
+ movq %rdi,%r12
+ movq %rsi,%r13
+ movq %rdx,%r14
+ movq %rcx,%r15
+ movdqu (%r8),%xmm11
+ movq %r8,88(%rsp)
+ shlq $6,%r14
+ subq %r12,%r13
+ movl 240(%r15),%r8d
+ addq %r10,%r14
+
+ leaq K_XX_XX(%rip),%r11
+ movl 0(%r9),%eax
+ movl 4(%r9),%ebx
+ movl 8(%r9),%ecx
+ movl 12(%r9),%edx
+ movl %ebx,%esi
+ movl 16(%r9),%ebp
+
+ movdqa 64(%r11),%xmm6
+ movdqa 0(%r11),%xmm9
+ movdqu 0(%r10),%xmm0
+ movdqu 16(%r10),%xmm1
+ movdqu 32(%r10),%xmm2
+ movdqu 48(%r10),%xmm3
+.byte 102,15,56,0,198
+ addq $64,%r10
+.byte 102,15,56,0,206
+.byte 102,15,56,0,214
+.byte 102,15,56,0,222
+ paddd %xmm9,%xmm0
+ paddd %xmm9,%xmm1
+ paddd %xmm9,%xmm2
+ movdqa %xmm0,0(%rsp)
+ psubd %xmm9,%xmm0
+ movdqa %xmm1,16(%rsp)
+ psubd %xmm9,%xmm1
+ movdqa %xmm2,32(%rsp)
+ psubd %xmm9,%xmm2
+ movups (%r15),%xmm13
+ movups 16(%r15),%xmm14
+ jmp .Loop_ssse3
+.align 16
+.Loop_ssse3:
+ movdqa %xmm1,%xmm4
+ addl 0(%rsp),%ebp
+ movups 0(%r12),%xmm12
+ xorps %xmm13,%xmm12
+ xorps %xmm12,%xmm11
+.byte 102,69,15,56,220,222
+ movups 32(%r15),%xmm15
+ xorl %edx,%ecx
+ movdqa %xmm3,%xmm8
+.byte 102,15,58,15,224,8
+ movl %eax,%edi
+ roll $5,%eax
+ paddd %xmm3,%xmm9
+ andl %ecx,%esi
+ xorl %edx,%ecx
+ psrldq $4,%xmm8
+ xorl %edx,%esi
+ addl %eax,%ebp
+ pxor %xmm0,%xmm4
+ rorl $2,%ebx
+ addl %esi,%ebp
+ pxor %xmm2,%xmm8
+ addl 4(%rsp),%edx
+ xorl %ecx,%ebx
+ movl %ebp,%esi
+ roll $5,%ebp
+ pxor %xmm8,%xmm4
+ andl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa %xmm9,48(%rsp)
+ xorl %ecx,%edi
+.byte 102,69,15,56,220,223
+ movups 48(%r15),%xmm14
+ addl %ebp,%edx
+ movdqa %xmm4,%xmm10
+ movdqa %xmm4,%xmm8
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 8(%rsp),%ecx
+ xorl %ebx,%eax
+ pslldq $12,%xmm10
+ paddd %xmm4,%xmm4
+ movl %edx,%edi
+ roll $5,%edx
+ andl %eax,%esi
+ xorl %ebx,%eax
+ psrld $31,%xmm8
+ xorl %ebx,%esi
+ addl %edx,%ecx
+ movdqa %xmm10,%xmm9
+ rorl $7,%ebp
+ addl %esi,%ecx
+ psrld $30,%xmm10
+ por %xmm8,%xmm4
+ addl 12(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%esi
+ roll $5,%ecx
+.byte 102,69,15,56,220,222
+ movups 64(%r15),%xmm15
+ pslld $2,%xmm9
+ pxor %xmm10,%xmm4
+ andl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa 0(%r11),%xmm10
+ xorl %eax,%edi
+ addl %ecx,%ebx
+ pxor %xmm9,%xmm4
+ rorl $7,%edx
+ addl %edi,%ebx
+ movdqa %xmm2,%xmm5
+ addl 16(%rsp),%eax
+ xorl %ebp,%edx
+ movdqa %xmm4,%xmm9
+.byte 102,15,58,15,233,8
+ movl %ebx,%edi
+ roll $5,%ebx
+ paddd %xmm4,%xmm10
+ andl %edx,%esi
+ xorl %ebp,%edx
+ psrldq $4,%xmm9
+ xorl %ebp,%esi
+ addl %ebx,%eax
+ pxor %xmm1,%xmm5
+ rorl $7,%ecx
+ addl %esi,%eax
+ pxor %xmm3,%xmm9
+ addl 20(%rsp),%ebp
+.byte 102,69,15,56,220,223
+ movups 80(%r15),%xmm14
+ xorl %edx,%ecx
+ movl %eax,%esi
+ roll $5,%eax
+ pxor %xmm9,%xmm5
+ andl %ecx,%edi
+ xorl %edx,%ecx
+ movdqa %xmm10,0(%rsp)
+ xorl %edx,%edi
+ addl %eax,%ebp
+ movdqa %xmm5,%xmm8
+ movdqa %xmm5,%xmm9
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 24(%rsp),%edx
+ xorl %ecx,%ebx
+ pslldq $12,%xmm8
+ paddd %xmm5,%xmm5
+ movl %ebp,%edi
+ roll $5,%ebp
+ andl %ebx,%esi
+ xorl %ecx,%ebx
+ psrld $31,%xmm9
+ xorl %ecx,%esi
+.byte 102,69,15,56,220,222
+ movups 96(%r15),%xmm15
+ addl %ebp,%edx
+ movdqa %xmm8,%xmm10
+ rorl $7,%eax
+ addl %esi,%edx
+ psrld $30,%xmm8
+ por %xmm9,%xmm5
+ addl 28(%rsp),%ecx
+ xorl %ebx,%eax
+ movl %edx,%esi
+ roll $5,%edx
+ pslld $2,%xmm10
+ pxor %xmm8,%xmm5
+ andl %eax,%edi
+ xorl %ebx,%eax
+ movdqa 16(%r11),%xmm8
+ xorl %ebx,%edi
+ addl %edx,%ecx
+ pxor %xmm10,%xmm5
+ rorl $7,%ebp
+ addl %edi,%ecx
+ movdqa %xmm3,%xmm6
+ addl 32(%rsp),%ebx
+ xorl %eax,%ebp
+ movdqa %xmm5,%xmm10
+.byte 102,15,58,15,242,8
+ movl %ecx,%edi
+ roll $5,%ecx
+.byte 102,69,15,56,220,223
+ movups 112(%r15),%xmm14
+ paddd %xmm5,%xmm8
+ andl %ebp,%esi
+ xorl %eax,%ebp
+ psrldq $4,%xmm10
+ xorl %eax,%esi
+ addl %ecx,%ebx
+ pxor %xmm2,%xmm6
+ rorl $7,%edx
+ addl %esi,%ebx
+ pxor %xmm4,%xmm10
+ addl 36(%rsp),%eax
+ xorl %ebp,%edx
+ movl %ebx,%esi
+ roll $5,%ebx
+ pxor %xmm10,%xmm6
+ andl %edx,%edi
+ xorl %ebp,%edx
+ movdqa %xmm8,16(%rsp)
+ xorl %ebp,%edi
+ addl %ebx,%eax
+ movdqa %xmm6,%xmm9
+ movdqa %xmm6,%xmm10
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 40(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 128(%r15),%xmm15
+ xorl %edx,%ecx
+ pslldq $12,%xmm9
+ paddd %xmm6,%xmm6
+ movl %eax,%edi
+ roll $5,%eax
+ andl %ecx,%esi
+ xorl %edx,%ecx
+ psrld $31,%xmm10
+ xorl %edx,%esi
+ addl %eax,%ebp
+ movdqa %xmm9,%xmm8
+ rorl $7,%ebx
+ addl %esi,%ebp
+ psrld $30,%xmm9
+ por %xmm10,%xmm6
+ addl 44(%rsp),%edx
+ xorl %ecx,%ebx
+ movl %ebp,%esi
+ roll $5,%ebp
+ pslld $2,%xmm8
+ pxor %xmm9,%xmm6
+ andl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa 16(%r11),%xmm9
+ xorl %ecx,%edi
+.byte 102,69,15,56,220,223
+ movups 144(%r15),%xmm14
+ addl %ebp,%edx
+ pxor %xmm8,%xmm6
+ rorl $7,%eax
+ addl %edi,%edx
+ movdqa %xmm4,%xmm7
+ addl 48(%rsp),%ecx
+ xorl %ebx,%eax
+ movdqa %xmm6,%xmm8
+.byte 102,15,58,15,251,8
+ movl %edx,%edi
+ roll $5,%edx
+ paddd %xmm6,%xmm9
+ andl %eax,%esi
+ xorl %ebx,%eax
+ psrldq $4,%xmm8
+ xorl %ebx,%esi
+ addl %edx,%ecx
+ pxor %xmm3,%xmm7
+ rorl $7,%ebp
+ addl %esi,%ecx
+ pxor %xmm5,%xmm8
+ addl 52(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%esi
+ roll $5,%ecx
+.byte 102,69,15,56,220,222
+ movups 160(%r15),%xmm15
+ pxor %xmm8,%xmm7
+ andl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa %xmm9,32(%rsp)
+ xorl %eax,%edi
+ addl %ecx,%ebx
+ movdqa %xmm7,%xmm10
+ movdqa %xmm7,%xmm8
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 56(%rsp),%eax
+ xorl %ebp,%edx
+ pslldq $12,%xmm10
+ paddd %xmm7,%xmm7
+ movl %ebx,%edi
+ roll $5,%ebx
+ andl %edx,%esi
+ xorl %ebp,%edx
+ psrld $31,%xmm8
+ xorl %ebp,%esi
+ addl %ebx,%eax
+ movdqa %xmm10,%xmm9
+ rorl $7,%ecx
+ addl %esi,%eax
+ psrld $30,%xmm10
+ por %xmm8,%xmm7
+ addl 60(%rsp),%ebp
+ cmpl $11,%r8d
+ jb .Laesenclast1
+ movups 176(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 192(%r15),%xmm15
+.byte 102,69,15,56,220,222
+ je .Laesenclast1
+ movups 208(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 224(%r15),%xmm15
+.byte 102,69,15,56,220,222
+.Laesenclast1:
+.byte 102,69,15,56,221,223
+ movups 16(%r15),%xmm14
+ xorl %edx,%ecx
+ movl %eax,%esi
+ roll $5,%eax
+ pslld $2,%xmm9
+ pxor %xmm10,%xmm7
+ andl %ecx,%edi
+ xorl %edx,%ecx
+ movdqa 16(%r11),%xmm10
+ xorl %edx,%edi
+ addl %eax,%ebp
+ pxor %xmm9,%xmm7
+ rorl $7,%ebx
+ addl %edi,%ebp
+ movdqa %xmm7,%xmm9
+ addl 0(%rsp),%edx
+ pxor %xmm4,%xmm0
+.byte 102,68,15,58,15,206,8
+ xorl %ecx,%ebx
+ movl %ebp,%edi
+ roll $5,%ebp
+ pxor %xmm1,%xmm0
+ andl %ebx,%esi
+ xorl %ecx,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm7,%xmm10
+ xorl %ecx,%esi
+ movups 16(%r12),%xmm12
+ xorps %xmm13,%xmm12
+ movups %xmm11,0(%r13,%r12,1)
+ xorps %xmm12,%xmm11
+.byte 102,69,15,56,220,222
+ movups 32(%r15),%xmm15
+ addl %ebp,%edx
+ pxor %xmm9,%xmm0
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 4(%rsp),%ecx
+ xorl %ebx,%eax
+ movdqa %xmm0,%xmm9
+ movdqa %xmm10,48(%rsp)
+ movl %edx,%esi
+ roll $5,%edx
+ andl %eax,%edi
+ xorl %ebx,%eax
+ pslld $2,%xmm0
+ xorl %ebx,%edi
+ addl %edx,%ecx
+ psrld $30,%xmm9
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 8(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%edi
+ roll $5,%ecx
+.byte 102,69,15,56,220,223
+ movups 48(%r15),%xmm14
+ por %xmm9,%xmm0
+ andl %ebp,%esi
+ xorl %eax,%ebp
+ movdqa %xmm0,%xmm10
+ xorl %eax,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 12(%rsp),%eax
+ xorl %ebp,%edx
+ movl %ebx,%esi
+ roll $5,%ebx
+ andl %edx,%edi
+ xorl %ebp,%edx
+ xorl %ebp,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 16(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 64(%r15),%xmm15
+ pxor %xmm5,%xmm1
+.byte 102,68,15,58,15,215,8
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ pxor %xmm2,%xmm1
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ movdqa %xmm8,%xmm9
+ paddd %xmm0,%xmm8
+ rorl $7,%ebx
+ addl %esi,%ebp
+ pxor %xmm10,%xmm1
+ addl 20(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ movdqa %xmm1,%xmm10
+ movdqa %xmm8,0(%rsp)
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ pslld $2,%xmm1
+ addl 24(%rsp),%ecx
+ xorl %ebx,%esi
+ psrld $30,%xmm10
+ movl %edx,%edi
+ roll $5,%edx
+ xorl %eax,%esi
+.byte 102,69,15,56,220,223
+ movups 80(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ por %xmm10,%xmm1
+ addl 28(%rsp),%ebx
+ xorl %eax,%edi
+ movdqa %xmm1,%xmm8
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 32(%rsp),%eax
+ pxor %xmm6,%xmm2
+.byte 102,68,15,58,15,192,8
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ pxor %xmm3,%xmm2
+ xorl %edx,%esi
+ addl %ebx,%eax
+ movdqa 32(%r11),%xmm10
+ paddd %xmm1,%xmm9
+ rorl $7,%ecx
+ addl %esi,%eax
+ pxor %xmm8,%xmm2
+ addl 36(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 96(%r15),%xmm15
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ movdqa %xmm2,%xmm8
+ movdqa %xmm9,16(%rsp)
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ pslld $2,%xmm2
+ addl 40(%rsp),%edx
+ xorl %ecx,%esi
+ psrld $30,%xmm8
+ movl %ebp,%edi
+ roll $5,%ebp
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ por %xmm8,%xmm2
+ addl 44(%rsp),%ecx
+ xorl %ebx,%edi
+ movdqa %xmm2,%xmm9
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+.byte 102,69,15,56,220,223
+ movups 112(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 48(%rsp),%ebx
+ pxor %xmm7,%xmm3
+.byte 102,68,15,58,15,201,8
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ pxor %xmm4,%xmm3
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm2,%xmm10
+ rorl $7,%edx
+ addl %esi,%ebx
+ pxor %xmm9,%xmm3
+ addl 52(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ movdqa %xmm3,%xmm9
+ movdqa %xmm10,32(%rsp)
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ pslld $2,%xmm3
+ addl 56(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 128(%r15),%xmm15
+ xorl %edx,%esi
+ psrld $30,%xmm9
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ por %xmm9,%xmm3
+ addl 60(%rsp),%edx
+ xorl %ecx,%edi
+ movdqa %xmm3,%xmm10
+ movl %ebp,%esi
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 0(%rsp),%ecx
+ pxor %xmm0,%xmm4
+.byte 102,68,15,58,15,210,8
+ xorl %ebx,%esi
+ movl %edx,%edi
+ roll $5,%edx
+ pxor %xmm5,%xmm4
+ xorl %eax,%esi
+.byte 102,69,15,56,220,223
+ movups 144(%r15),%xmm14
+ addl %edx,%ecx
+ movdqa %xmm8,%xmm9
+ paddd %xmm3,%xmm8
+ rorl $7,%ebp
+ addl %esi,%ecx
+ pxor %xmm10,%xmm4
+ addl 4(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ movdqa %xmm4,%xmm10
+ movdqa %xmm8,48(%rsp)
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ pslld $2,%xmm4
+ addl 8(%rsp),%eax
+ xorl %ebp,%esi
+ psrld $30,%xmm10
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ por %xmm10,%xmm4
+ addl 12(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 160(%r15),%xmm15
+ xorl %edx,%edi
+ movdqa %xmm4,%xmm8
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 16(%rsp),%edx
+ pxor %xmm1,%xmm5
+.byte 102,68,15,58,15,195,8
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ pxor %xmm6,%xmm5
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ movdqa %xmm9,%xmm10
+ paddd %xmm4,%xmm9
+ rorl $7,%eax
+ addl %esi,%edx
+ pxor %xmm8,%xmm5
+ addl 20(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ movdqa %xmm5,%xmm8
+ movdqa %xmm9,0(%rsp)
+ xorl %eax,%edi
+ cmpl $11,%r8d
+ jb .Laesenclast2
+ movups 176(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 192(%r15),%xmm15
+.byte 102,69,15,56,220,222
+ je .Laesenclast2
+ movups 208(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 224(%r15),%xmm15
+.byte 102,69,15,56,220,222
+.Laesenclast2:
+.byte 102,69,15,56,221,223
+ movups 16(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ pslld $2,%xmm5
+ addl 24(%rsp),%ebx
+ xorl %eax,%esi
+ psrld $30,%xmm8
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ por %xmm8,%xmm5
+ addl 28(%rsp),%eax
+ xorl %ebp,%edi
+ movdqa %xmm5,%xmm9
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ movl %ecx,%edi
+ movups 32(%r12),%xmm12
+ xorps %xmm13,%xmm12
+ movups %xmm11,16(%r13,%r12,1)
+ xorps %xmm12,%xmm11
+.byte 102,69,15,56,220,222
+ movups 32(%r15),%xmm15
+ pxor %xmm2,%xmm6
+.byte 102,68,15,58,15,204,8
+ xorl %edx,%ecx
+ addl 32(%rsp),%ebp
+ andl %edx,%edi
+ pxor %xmm7,%xmm6
+ andl %ecx,%esi
+ rorl $7,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm5,%xmm10
+ addl %edi,%ebp
+ movl %eax,%edi
+ pxor %xmm9,%xmm6
+ roll $5,%eax
+ addl %esi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movdqa %xmm6,%xmm9
+ movdqa %xmm10,16(%rsp)
+ movl %ebx,%esi
+ xorl %ecx,%ebx
+ addl 36(%rsp),%edx
+ andl %ecx,%esi
+ pslld $2,%xmm6
+ andl %ebx,%edi
+ rorl $7,%eax
+ psrld $30,%xmm9
+ addl %esi,%edx
+ movl %ebp,%esi
+ roll $5,%ebp
+.byte 102,69,15,56,220,223
+ movups 48(%r15),%xmm14
+ addl %edi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ por %xmm9,%xmm6
+ movl %eax,%edi
+ xorl %ebx,%eax
+ movdqa %xmm6,%xmm10
+ addl 40(%rsp),%ecx
+ andl %ebx,%edi
+ andl %eax,%esi
+ rorl $7,%ebp
+ addl %edi,%ecx
+ movl %edx,%edi
+ roll $5,%edx
+ addl %esi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movl %ebp,%esi
+ xorl %eax,%ebp
+ addl 44(%rsp),%ebx
+ andl %eax,%esi
+ andl %ebp,%edi
+.byte 102,69,15,56,220,222
+ movups 64(%r15),%xmm15
+ rorl $7,%edx
+ addl %esi,%ebx
+ movl %ecx,%esi
+ roll $5,%ecx
+ addl %edi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movl %edx,%edi
+ pxor %xmm3,%xmm7
+.byte 102,68,15,58,15,213,8
+ xorl %ebp,%edx
+ addl 48(%rsp),%eax
+ andl %ebp,%edi
+ pxor %xmm0,%xmm7
+ andl %edx,%esi
+ rorl $7,%ecx
+ movdqa 48(%r11),%xmm9
+ paddd %xmm6,%xmm8
+ addl %edi,%eax
+ movl %ebx,%edi
+ pxor %xmm10,%xmm7
+ roll $5,%ebx
+ addl %esi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ movdqa %xmm7,%xmm10
+ movdqa %xmm8,32(%rsp)
+ movl %ecx,%esi
+.byte 102,69,15,56,220,223
+ movups 80(%r15),%xmm14
+ xorl %edx,%ecx
+ addl 52(%rsp),%ebp
+ andl %edx,%esi
+ pslld $2,%xmm7
+ andl %ecx,%edi
+ rorl $7,%ebx
+ psrld $30,%xmm10
+ addl %esi,%ebp
+ movl %eax,%esi
+ roll $5,%eax
+ addl %edi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ por %xmm10,%xmm7
+ movl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa %xmm7,%xmm8
+ addl 56(%rsp),%edx
+ andl %ecx,%edi
+ andl %ebx,%esi
+ rorl $7,%eax
+ addl %edi,%edx
+ movl %ebp,%edi
+ roll $5,%ebp
+.byte 102,69,15,56,220,222
+ movups 96(%r15),%xmm15
+ addl %esi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movl %eax,%esi
+ xorl %ebx,%eax
+ addl 60(%rsp),%ecx
+ andl %ebx,%esi
+ andl %eax,%edi
+ rorl $7,%ebp
+ addl %esi,%ecx
+ movl %edx,%esi
+ roll $5,%edx
+ addl %edi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movl %ebp,%edi
+ pxor %xmm4,%xmm0
+.byte 102,68,15,58,15,198,8
+ xorl %eax,%ebp
+ addl 0(%rsp),%ebx
+ andl %eax,%edi
+ pxor %xmm1,%xmm0
+ andl %ebp,%esi
+.byte 102,69,15,56,220,223
+ movups 112(%r15),%xmm14
+ rorl $7,%edx
+ movdqa %xmm9,%xmm10
+ paddd %xmm7,%xmm9
+ addl %edi,%ebx
+ movl %ecx,%edi
+ pxor %xmm8,%xmm0
+ roll $5,%ecx
+ addl %esi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movdqa %xmm0,%xmm8
+ movdqa %xmm9,48(%rsp)
+ movl %edx,%esi
+ xorl %ebp,%edx
+ addl 4(%rsp),%eax
+ andl %ebp,%esi
+ pslld $2,%xmm0
+ andl %edx,%edi
+ rorl $7,%ecx
+ psrld $30,%xmm8
+ addl %esi,%eax
+ movl %ebx,%esi
+ roll $5,%ebx
+ addl %edi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ por %xmm8,%xmm0
+ movl %ecx,%edi
+.byte 102,69,15,56,220,222
+ movups 128(%r15),%xmm15
+ xorl %edx,%ecx
+ movdqa %xmm0,%xmm9
+ addl 8(%rsp),%ebp
+ andl %edx,%edi
+ andl %ecx,%esi
+ rorl $7,%ebx
+ addl %edi,%ebp
+ movl %eax,%edi
+ roll $5,%eax
+ addl %esi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movl %ebx,%esi
+ xorl %ecx,%ebx
+ addl 12(%rsp),%edx
+ andl %ecx,%esi
+ andl %ebx,%edi
+ rorl $7,%eax
+ addl %esi,%edx
+ movl %ebp,%esi
+ roll $5,%ebp
+.byte 102,69,15,56,220,223
+ movups 144(%r15),%xmm14
+ addl %edi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movl %eax,%edi
+ pxor %xmm5,%xmm1
+.byte 102,68,15,58,15,207,8
+ xorl %ebx,%eax
+ addl 16(%rsp),%ecx
+ andl %ebx,%edi
+ pxor %xmm2,%xmm1
+ andl %eax,%esi
+ rorl $7,%ebp
+ movdqa %xmm10,%xmm8
+ paddd %xmm0,%xmm10
+ addl %edi,%ecx
+ movl %edx,%edi
+ pxor %xmm9,%xmm1
+ roll $5,%edx
+ addl %esi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movdqa %xmm1,%xmm9
+ movdqa %xmm10,0(%rsp)
+ movl %ebp,%esi
+ xorl %eax,%ebp
+ addl 20(%rsp),%ebx
+ andl %eax,%esi
+ pslld $2,%xmm1
+ andl %ebp,%edi
+.byte 102,69,15,56,220,222
+ movups 160(%r15),%xmm15
+ rorl $7,%edx
+ psrld $30,%xmm9
+ addl %esi,%ebx
+ movl %ecx,%esi
+ roll $5,%ecx
+ addl %edi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ por %xmm9,%xmm1
+ movl %edx,%edi
+ xorl %ebp,%edx
+ movdqa %xmm1,%xmm10
+ addl 24(%rsp),%eax
+ andl %ebp,%edi
+ andl %edx,%esi
+ rorl $7,%ecx
+ addl %edi,%eax
+ movl %ebx,%edi
+ roll $5,%ebx
+ addl %esi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ movl %ecx,%esi
+ cmpl $11,%r8d
+ jb .Laesenclast3
+ movups 176(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 192(%r15),%xmm15
+.byte 102,69,15,56,220,222
+ je .Laesenclast3
+ movups 208(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 224(%r15),%xmm15
+.byte 102,69,15,56,220,222
+.Laesenclast3:
+.byte 102,69,15,56,221,223
+ movups 16(%r15),%xmm14
+ xorl %edx,%ecx
+ addl 28(%rsp),%ebp
+ andl %edx,%esi
+ andl %ecx,%edi
+ rorl $7,%ebx
+ addl %esi,%ebp
+ movl %eax,%esi
+ roll $5,%eax
+ addl %edi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movl %ebx,%edi
+ pxor %xmm6,%xmm2
+.byte 102,68,15,58,15,208,8
+ xorl %ecx,%ebx
+ addl 32(%rsp),%edx
+ andl %ecx,%edi
+ pxor %xmm3,%xmm2
+ andl %ebx,%esi
+ rorl $7,%eax
+ movdqa %xmm8,%xmm9
+ paddd %xmm1,%xmm8
+ addl %edi,%edx
+ movl %ebp,%edi
+ pxor %xmm10,%xmm2
+ roll $5,%ebp
+ movups 48(%r12),%xmm12
+ xorps %xmm13,%xmm12
+ movups %xmm11,32(%r13,%r12,1)
+ xorps %xmm12,%xmm11
+.byte 102,69,15,56,220,222
+ movups 32(%r15),%xmm15
+ addl %esi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movdqa %xmm2,%xmm10
+ movdqa %xmm8,16(%rsp)
+ movl %eax,%esi
+ xorl %ebx,%eax
+ addl 36(%rsp),%ecx
+ andl %ebx,%esi
+ pslld $2,%xmm2
+ andl %eax,%edi
+ rorl $7,%ebp
+ psrld $30,%xmm10
+ addl %esi,%ecx
+ movl %edx,%esi
+ roll $5,%edx
+ addl %edi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ por %xmm10,%xmm2
+ movl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa %xmm2,%xmm8
+ addl 40(%rsp),%ebx
+ andl %eax,%edi
+ andl %ebp,%esi
+.byte 102,69,15,56,220,223
+ movups 48(%r15),%xmm14
+ rorl $7,%edx
+ addl %edi,%ebx
+ movl %ecx,%edi
+ roll $5,%ecx
+ addl %esi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movl %edx,%esi
+ xorl %ebp,%edx
+ addl 44(%rsp),%eax
+ andl %ebp,%esi
+ andl %edx,%edi
+ rorl $7,%ecx
+ addl %esi,%eax
+ movl %ebx,%esi
+ roll $5,%ebx
+ addl %edi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ addl 48(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 64(%r15),%xmm15
+ pxor %xmm7,%xmm3
+.byte 102,68,15,58,15,193,8
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ pxor %xmm4,%xmm3
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ movdqa %xmm9,%xmm10
+ paddd %xmm2,%xmm9
+ rorl $7,%ebx
+ addl %esi,%ebp
+ pxor %xmm8,%xmm3
+ addl 52(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ movdqa %xmm3,%xmm8
+ movdqa %xmm9,32(%rsp)
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ pslld $2,%xmm3
+ addl 56(%rsp),%ecx
+ xorl %ebx,%esi
+ psrld $30,%xmm8
+ movl %edx,%edi
+ roll $5,%edx
+ xorl %eax,%esi
+.byte 102,69,15,56,220,223
+ movups 80(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ por %xmm8,%xmm3
+ addl 60(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 0(%rsp),%eax
+ paddd %xmm3,%xmm10
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ movdqa %xmm10,48(%rsp)
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 4(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 96(%r15),%xmm15
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 8(%rsp),%edx
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 12(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+.byte 102,69,15,56,220,223
+ movups 112(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ cmpq %r14,%r10
+ je .Ldone_ssse3
+ movdqa 64(%r11),%xmm6
+ movdqa 0(%r11),%xmm9
+ movdqu 0(%r10),%xmm0
+ movdqu 16(%r10),%xmm1
+ movdqu 32(%r10),%xmm2
+ movdqu 48(%r10),%xmm3
+.byte 102,15,56,0,198
+ addq $64,%r10
+ addl 16(%rsp),%ebx
+ xorl %eax,%esi
+.byte 102,15,56,0,206
+ movl %ecx,%edi
+ roll $5,%ecx
+ paddd %xmm9,%xmm0
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ movdqa %xmm0,0(%rsp)
+ addl 20(%rsp),%eax
+ xorl %ebp,%edi
+ psubd %xmm9,%xmm0
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 24(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 128(%r15),%xmm15
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ addl 28(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 32(%rsp),%ecx
+ xorl %ebx,%esi
+.byte 102,15,56,0,214
+ movl %edx,%edi
+ roll $5,%edx
+ paddd %xmm9,%xmm1
+ xorl %eax,%esi
+.byte 102,69,15,56,220,223
+ movups 144(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ movdqa %xmm1,16(%rsp)
+ addl 36(%rsp),%ebx
+ xorl %eax,%edi
+ psubd %xmm9,%xmm1
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 40(%rsp),%eax
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 44(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 160(%r15),%xmm15
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 48(%rsp),%edx
+ xorl %ecx,%esi
+.byte 102,15,56,0,222
+ movl %ebp,%edi
+ roll $5,%ebp
+ paddd %xmm9,%xmm2
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ movdqa %xmm2,32(%rsp)
+ addl 52(%rsp),%ecx
+ xorl %ebx,%edi
+ psubd %xmm9,%xmm2
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ cmpl $11,%r8d
+ jb .Laesenclast4
+ movups 176(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 192(%r15),%xmm15
+.byte 102,69,15,56,220,222
+ je .Laesenclast4
+ movups 208(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 224(%r15),%xmm15
+.byte 102,69,15,56,220,222
+.Laesenclast4:
+.byte 102,69,15,56,221,223
+ movups 16(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 56(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 60(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ movups %xmm11,48(%r13,%r12,1)
+ leaq 64(%r12),%r12
+
+ addl 0(%r9),%eax
+ addl 4(%r9),%esi
+ addl 8(%r9),%ecx
+ addl 12(%r9),%edx
+ movl %eax,0(%r9)
+ addl 16(%r9),%ebp
+ movl %esi,4(%r9)
+ movl %esi,%ebx
+ movl %ecx,8(%r9)
+ movl %edx,12(%r9)
+ movl %ebp,16(%r9)
+ jmp .Loop_ssse3
+
+.align 16
+.Ldone_ssse3:
+ addl 16(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 20(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 24(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 128(%r15),%xmm15
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ addl 28(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 32(%rsp),%ecx
+ xorl %ebx,%esi
+ movl %edx,%edi
+ roll $5,%edx
+ xorl %eax,%esi
+.byte 102,69,15,56,220,223
+ movups 144(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ addl 36(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 40(%rsp),%eax
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 44(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 160(%r15),%xmm15
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 48(%rsp),%edx
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 52(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ cmpl $11,%r8d
+ jb .Laesenclast5
+ movups 176(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 192(%r15),%xmm15
+.byte 102,69,15,56,220,222
+ je .Laesenclast5
+ movups 208(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 224(%r15),%xmm15
+.byte 102,69,15,56,220,222
+.Laesenclast5:
+.byte 102,69,15,56,221,223
+ movups 16(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 56(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 60(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ movups %xmm11,48(%r13,%r12,1)
+ movq 88(%rsp),%r8
+
+ addl 0(%r9),%eax
+ addl 4(%r9),%esi
+ addl 8(%r9),%ecx
+ movl %eax,0(%r9)
+ addl 12(%r9),%edx
+ movl %esi,4(%r9)
+ addl 16(%r9),%ebp
+ movl %ecx,8(%r9)
+ movl %edx,12(%r9)
+ movl %ebp,16(%r9)
+ movups %xmm11,(%r8)
+ leaq 104(%rsp),%rsi
+ movq 0(%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+.Lepilogue_ssse3:
+ .byte 0xf3,0xc3
+.size aesni_cbc_sha1_enc_ssse3,.-aesni_cbc_sha1_enc_ssse3
+.align 64
+K_XX_XX:
+.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999
+
+.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1
+
+.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc
+
+.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6
+
+.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
+
+
+.byte 65,69,83,78,73,45,67,66,67,43,83,72,65,49,32,115,116,105,116,99,104,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 64
diff --git a/deps/openssl/asm/x64-elf-gas/aes/aesni-x86_64.s b/deps/openssl/asm/x64-elf-gas/aes/aesni-x86_64.s
new file mode 100644
index 000000000..2d24b7b28
--- /dev/null
+++ b/deps/openssl/asm/x64-elf-gas/aes/aesni-x86_64.s
@@ -0,0 +1,2558 @@
+.text
+
+.globl aesni_encrypt
+.type aesni_encrypt,@function
+.align 16
+aesni_encrypt:
+ movups (%rdi),%xmm2
+ movl 240(%rdx),%eax
+ movups (%rdx),%xmm0
+ movups 16(%rdx),%xmm1
+ leaq 32(%rdx),%rdx
+ xorps %xmm0,%xmm2
+.Loop_enc1_1:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rdx),%xmm1
+ leaq 16(%rdx),%rdx
+ jnz .Loop_enc1_1
+
+.byte 102,15,56,221,209
+ movups %xmm2,(%rsi)
+ .byte 0xf3,0xc3
+.size aesni_encrypt,.-aesni_encrypt
+
+.globl aesni_decrypt
+.type aesni_decrypt,@function
+.align 16
+aesni_decrypt:
+ movups (%rdi),%xmm2
+ movl 240(%rdx),%eax
+ movups (%rdx),%xmm0
+ movups 16(%rdx),%xmm1
+ leaq 32(%rdx),%rdx
+ xorps %xmm0,%xmm2
+.Loop_dec1_2:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rdx),%xmm1
+ leaq 16(%rdx),%rdx
+ jnz .Loop_dec1_2
+
+.byte 102,15,56,223,209
+ movups %xmm2,(%rsi)
+ .byte 0xf3,0xc3
+.size aesni_decrypt, .-aesni_decrypt
+.type _aesni_encrypt3,@function
+.align 16
+_aesni_encrypt3:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+ xorps %xmm0,%xmm4
+ movups (%rcx),%xmm0
+
+.Lenc_loop3:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+ movups (%rcx),%xmm0
+ jnz .Lenc_loop3
+
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+ .byte 0xf3,0xc3
+.size _aesni_encrypt3,.-_aesni_encrypt3
+.type _aesni_decrypt3,@function
+.align 16
+_aesni_decrypt3:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+ xorps %xmm0,%xmm4
+ movups (%rcx),%xmm0
+
+.Ldec_loop3:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %eax
+.byte 102,15,56,222,225
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,222,224
+ movups (%rcx),%xmm0
+ jnz .Ldec_loop3
+
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+ .byte 0xf3,0xc3
+.size _aesni_decrypt3,.-_aesni_decrypt3
+.type _aesni_encrypt4,@function
+.align 16
+_aesni_encrypt4:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+ xorps %xmm0,%xmm4
+ xorps %xmm0,%xmm5
+ movups (%rcx),%xmm0
+
+.Lenc_loop4:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+ movups (%rcx),%xmm0
+ jnz .Lenc_loop4
+
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+.byte 102,15,56,221,232
+ .byte 0xf3,0xc3
+.size _aesni_encrypt4,.-_aesni_encrypt4
+.type _aesni_decrypt4,@function
+.align 16
+_aesni_decrypt4:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+ xorps %xmm0,%xmm4
+ xorps %xmm0,%xmm5
+ movups (%rcx),%xmm0
+
+.Ldec_loop4:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %eax
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+ movups (%rcx),%xmm0
+ jnz .Ldec_loop4
+
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+.byte 102,15,56,223,232
+ .byte 0xf3,0xc3
+.size _aesni_decrypt4,.-_aesni_decrypt4
+.type _aesni_encrypt6,@function
+.align 16
+_aesni_encrypt6:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+.byte 102,15,56,220,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,220,217
+ pxor %xmm0,%xmm5
+.byte 102,15,56,220,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+ decl %eax
+.byte 102,15,56,220,241
+ movups (%rcx),%xmm0
+.byte 102,15,56,220,249
+ jmp .Lenc_loop6_enter
+.align 16
+.Lenc_loop6:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.Lenc_loop6_enter:
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+ movups (%rcx),%xmm0
+ jnz .Lenc_loop6
+
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+.byte 102,15,56,221,232
+.byte 102,15,56,221,240
+.byte 102,15,56,221,248
+ .byte 0xf3,0xc3
+.size _aesni_encrypt6,.-_aesni_encrypt6
+.type _aesni_decrypt6,@function
+.align 16
+_aesni_decrypt6:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+.byte 102,15,56,222,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,222,217
+ pxor %xmm0,%xmm5
+.byte 102,15,56,222,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+ decl %eax
+.byte 102,15,56,222,241
+ movups (%rcx),%xmm0
+.byte 102,15,56,222,249
+ jmp .Ldec_loop6_enter
+.align 16
+.Ldec_loop6:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %eax
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.Ldec_loop6_enter:
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+.byte 102,15,56,222,240
+.byte 102,15,56,222,248
+ movups (%rcx),%xmm0
+ jnz .Ldec_loop6
+
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+.byte 102,15,56,223,232
+.byte 102,15,56,223,240
+.byte 102,15,56,223,248
+ .byte 0xf3,0xc3
+.size _aesni_decrypt6,.-_aesni_decrypt6
+.type _aesni_encrypt8,@function
+.align 16
+_aesni_encrypt8:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+.byte 102,15,56,220,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,220,217
+ pxor %xmm0,%xmm5
+.byte 102,15,56,220,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+ decl %eax
+.byte 102,15,56,220,241
+ pxor %xmm0,%xmm8
+.byte 102,15,56,220,249
+ pxor %xmm0,%xmm9
+ movups (%rcx),%xmm0
+.byte 102,68,15,56,220,193
+.byte 102,68,15,56,220,201
+ movups 16(%rcx),%xmm1
+ jmp .Lenc_loop8_enter
+.align 16
+.Lenc_loop8:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.byte 102,68,15,56,220,193
+.byte 102,68,15,56,220,201
+ movups 16(%rcx),%xmm1
+.Lenc_loop8_enter:
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+.byte 102,68,15,56,220,192
+.byte 102,68,15,56,220,200
+ movups (%rcx),%xmm0
+ jnz .Lenc_loop8
+
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.byte 102,68,15,56,220,193
+.byte 102,68,15,56,220,201
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+.byte 102,15,56,221,232
+.byte 102,15,56,221,240
+.byte 102,15,56,221,248
+.byte 102,68,15,56,221,192
+.byte 102,68,15,56,221,200
+ .byte 0xf3,0xc3
+.size _aesni_encrypt8,.-_aesni_encrypt8
+.type _aesni_decrypt8,@function
+.align 16
+_aesni_decrypt8:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+.byte 102,15,56,222,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,222,217
+ pxor %xmm0,%xmm5
+.byte 102,15,56,222,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+ decl %eax
+.byte 102,15,56,222,241
+ pxor %xmm0,%xmm8
+.byte 102,15,56,222,249
+ pxor %xmm0,%xmm9
+ movups (%rcx),%xmm0
+.byte 102,68,15,56,222,193
+.byte 102,68,15,56,222,201
+ movups 16(%rcx),%xmm1
+ jmp .Ldec_loop8_enter
+.align 16
+.Ldec_loop8:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %eax
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.byte 102,68,15,56,222,193
+.byte 102,68,15,56,222,201
+ movups 16(%rcx),%xmm1
+.Ldec_loop8_enter:
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+.byte 102,15,56,222,240
+.byte 102,15,56,222,248
+.byte 102,68,15,56,222,192
+.byte 102,68,15,56,222,200
+ movups (%rcx),%xmm0
+ jnz .Ldec_loop8
+
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.byte 102,68,15,56,222,193
+.byte 102,68,15,56,222,201
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+.byte 102,15,56,223,232
+.byte 102,15,56,223,240
+.byte 102,15,56,223,248
+.byte 102,68,15,56,223,192
+.byte 102,68,15,56,223,200
+ .byte 0xf3,0xc3
+.size _aesni_decrypt8,.-_aesni_decrypt8
+.globl aesni_ecb_encrypt
+.type aesni_ecb_encrypt,@function
+.align 16
+aesni_ecb_encrypt:
+ andq $-16,%rdx
+ jz .Lecb_ret
+
+ movl 240(%rcx),%eax
+ movups (%rcx),%xmm0
+ movq %rcx,%r11
+ movl %eax,%r10d
+ testl %r8d,%r8d
+ jz .Lecb_decrypt
+
+ cmpq $128,%rdx
+ jb .Lecb_enc_tail
+
+ movdqu (%rdi),%xmm2
+ movdqu 16(%rdi),%xmm3
+ movdqu 32(%rdi),%xmm4
+ movdqu 48(%rdi),%xmm5
+ movdqu 64(%rdi),%xmm6
+ movdqu 80(%rdi),%xmm7
+ movdqu 96(%rdi),%xmm8
+ movdqu 112(%rdi),%xmm9
+ leaq 128(%rdi),%rdi
+ subq $128,%rdx
+ jmp .Lecb_enc_loop8_enter
+.align 16
+.Lecb_enc_loop8:
+ movups %xmm2,(%rsi)
+ movq %r11,%rcx
+ movdqu (%rdi),%xmm2
+ movl %r10d,%eax
+ movups %xmm3,16(%rsi)
+ movdqu 16(%rdi),%xmm3
+ movups %xmm4,32(%rsi)
+ movdqu 32(%rdi),%xmm4
+ movups %xmm5,48(%rsi)
+ movdqu 48(%rdi),%xmm5
+ movups %xmm6,64(%rsi)
+ movdqu 64(%rdi),%xmm6
+ movups %xmm7,80(%rsi)
+ movdqu 80(%rdi),%xmm7
+ movups %xmm8,96(%rsi)
+ movdqu 96(%rdi),%xmm8
+ movups %xmm9,112(%rsi)
+ leaq 128(%rsi),%rsi
+ movdqu 112(%rdi),%xmm9
+ leaq 128(%rdi),%rdi
+.Lecb_enc_loop8_enter:
+
+ call _aesni_encrypt8
+
+ subq $128,%rdx
+ jnc .Lecb_enc_loop8
+
+ movups %xmm2,(%rsi)
+ movq %r11,%rcx
+ movups %xmm3,16(%rsi)
+ movl %r10d,%eax
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ movups %xmm8,96(%rsi)
+ movups %xmm9,112(%rsi)
+ leaq 128(%rsi),%rsi
+ addq $128,%rdx
+ jz .Lecb_ret
+
+.Lecb_enc_tail:
+ movups (%rdi),%xmm2
+ cmpq $32,%rdx
+ jb .Lecb_enc_one
+ movups 16(%rdi),%xmm3
+ je .Lecb_enc_two
+ movups 32(%rdi),%xmm4
+ cmpq $64,%rdx
+ jb .Lecb_enc_three
+ movups 48(%rdi),%xmm5
+ je .Lecb_enc_four
+ movups 64(%rdi),%xmm6
+ cmpq $96,%rdx
+ jb .Lecb_enc_five
+ movups 80(%rdi),%xmm7
+ je .Lecb_enc_six
+ movdqu 96(%rdi),%xmm8
+ call _aesni_encrypt8
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ movups %xmm8,96(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_one:
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+.Loop_enc1_3:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_enc1_3
+
+.byte 102,15,56,221,209
+ movups %xmm2,(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_two:
+ xorps %xmm4,%xmm4
+ call _aesni_encrypt3
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_three:
+ call _aesni_encrypt3
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_four:
+ call _aesni_encrypt4
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_five:
+ xorps %xmm7,%xmm7
+ call _aesni_encrypt6
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_six:
+ call _aesni_encrypt6
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ jmp .Lecb_ret
+
+.align 16
+.Lecb_decrypt:
+ cmpq $128,%rdx
+ jb .Lecb_dec_tail
+
+ movdqu (%rdi),%xmm2
+ movdqu 16(%rdi),%xmm3
+ movdqu 32(%rdi),%xmm4
+ movdqu 48(%rdi),%xmm5
+ movdqu 64(%rdi),%xmm6
+ movdqu 80(%rdi),%xmm7
+ movdqu 96(%rdi),%xmm8
+ movdqu 112(%rdi),%xmm9
+ leaq 128(%rdi),%rdi
+ subq $128,%rdx
+ jmp .Lecb_dec_loop8_enter
+.align 16
+.Lecb_dec_loop8:
+ movups %xmm2,(%rsi)
+ movq %r11,%rcx
+ movdqu (%rdi),%xmm2
+ movl %r10d,%eax
+ movups %xmm3,16(%rsi)
+ movdqu 16(%rdi),%xmm3
+ movups %xmm4,32(%rsi)
+ movdqu 32(%rdi),%xmm4
+ movups %xmm5,48(%rsi)
+ movdqu 48(%rdi),%xmm5
+ movups %xmm6,64(%rsi)
+ movdqu 64(%rdi),%xmm6
+ movups %xmm7,80(%rsi)
+ movdqu 80(%rdi),%xmm7
+ movups %xmm8,96(%rsi)
+ movdqu 96(%rdi),%xmm8
+ movups %xmm9,112(%rsi)
+ leaq 128(%rsi),%rsi
+ movdqu 112(%rdi),%xmm9
+ leaq 128(%rdi),%rdi
+.Lecb_dec_loop8_enter:
+
+ call _aesni_decrypt8
+
+ movups (%r11),%xmm0
+ subq $128,%rdx
+ jnc .Lecb_dec_loop8
+
+ movups %xmm2,(%rsi)
+ movq %r11,%rcx
+ movups %xmm3,16(%rsi)
+ movl %r10d,%eax
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ movups %xmm8,96(%rsi)
+ movups %xmm9,112(%rsi)
+ leaq 128(%rsi),%rsi
+ addq $128,%rdx
+ jz .Lecb_ret
+
+.Lecb_dec_tail:
+ movups (%rdi),%xmm2
+ cmpq $32,%rdx
+ jb .Lecb_dec_one
+ movups 16(%rdi),%xmm3
+ je .Lecb_dec_two
+ movups 32(%rdi),%xmm4
+ cmpq $64,%rdx
+ jb .Lecb_dec_three
+ movups 48(%rdi),%xmm5
+ je .Lecb_dec_four
+ movups 64(%rdi),%xmm6
+ cmpq $96,%rdx
+ jb .Lecb_dec_five
+ movups 80(%rdi),%xmm7
+ je .Lecb_dec_six
+ movups 96(%rdi),%xmm8
+ movups (%rcx),%xmm0
+ call _aesni_decrypt8
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ movups %xmm8,96(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_one:
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+.Loop_dec1_4:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_dec1_4
+
+.byte 102,15,56,223,209
+ movups %xmm2,(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_two:
+ xorps %xmm4,%xmm4
+ call _aesni_decrypt3
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_three:
+ call _aesni_decrypt3
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_four:
+ call _aesni_decrypt4
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_five:
+ xorps %xmm7,%xmm7
+ call _aesni_decrypt6
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_six:
+ call _aesni_decrypt6
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+
+.Lecb_ret:
+ .byte 0xf3,0xc3
+.size aesni_ecb_encrypt,.-aesni_ecb_encrypt
+.globl aesni_ccm64_encrypt_blocks
+.type aesni_ccm64_encrypt_blocks,@function
+.align 16
+aesni_ccm64_encrypt_blocks:
+ movl 240(%rcx),%eax
+ movdqu (%r8),%xmm9
+ movdqa .Lincrement64(%rip),%xmm6
+ movdqa .Lbswap_mask(%rip),%xmm7
+
+ shrl $1,%eax
+ leaq 0(%rcx),%r11
+ movdqu (%r9),%xmm3
+ movdqa %xmm9,%xmm2
+ movl %eax,%r10d
+.byte 102,68,15,56,0,207
+ jmp .Lccm64_enc_outer
+.align 16
+.Lccm64_enc_outer:
+ movups (%r11),%xmm0
+ movl %r10d,%eax
+ movups (%rdi),%xmm8
+
+ xorps %xmm0,%xmm2
+ movups 16(%r11),%xmm1
+ xorps %xmm8,%xmm0
+ leaq 32(%r11),%rcx
+ xorps %xmm0,%xmm3
+ movups (%rcx),%xmm0
+
+.Lccm64_enc2_loop:
+.byte 102,15,56,220,209
+ decl %eax
+.byte 102,15,56,220,217
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,216
+ movups 0(%rcx),%xmm0
+ jnz .Lccm64_enc2_loop
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ paddq %xmm6,%xmm9
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+
+ decq %rdx
+ leaq 16(%rdi),%rdi
+ xorps %xmm2,%xmm8
+ movdqa %xmm9,%xmm2
+ movups %xmm8,(%rsi)
+ leaq 16(%rsi),%rsi
+.byte 102,15,56,0,215
+ jnz .Lccm64_enc_outer
+
+ movups %xmm3,(%r9)
+ .byte 0xf3,0xc3
+.size aesni_ccm64_encrypt_blocks,.-aesni_ccm64_encrypt_blocks
+.globl aesni_ccm64_decrypt_blocks
+.type aesni_ccm64_decrypt_blocks,@function
+.align 16
+aesni_ccm64_decrypt_blocks:
+ movl 240(%rcx),%eax
+ movups (%r8),%xmm9
+ movdqu (%r9),%xmm3
+ movdqa .Lincrement64(%rip),%xmm6
+ movdqa .Lbswap_mask(%rip),%xmm7
+
+ movaps %xmm9,%xmm2
+ movl %eax,%r10d
+ movq %rcx,%r11
+.byte 102,68,15,56,0,207
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+.Loop_enc1_5:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_enc1_5
+
+.byte 102,15,56,221,209
+ movups (%rdi),%xmm8
+ paddq %xmm6,%xmm9
+ leaq 16(%rdi),%rdi
+ jmp .Lccm64_dec_outer
+.align 16
+.Lccm64_dec_outer:
+ xorps %xmm2,%xmm8
+ movdqa %xmm9,%xmm2
+ movl %r10d,%eax
+ movups %xmm8,(%rsi)
+ leaq 16(%rsi),%rsi
+.byte 102,15,56,0,215
+
+ subq $1,%rdx
+ jz .Lccm64_dec_break
+
+ movups (%r11),%xmm0
+ shrl $1,%eax
+ movups 16(%r11),%xmm1
+ xorps %xmm0,%xmm8
+ leaq 32(%r11),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm8,%xmm3
+ movups (%rcx),%xmm0
+
+.Lccm64_dec2_loop:
+.byte 102,15,56,220,209
+ decl %eax
+.byte 102,15,56,220,217
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,216
+ movups 0(%rcx),%xmm0
+ jnz .Lccm64_dec2_loop
+ movups (%rdi),%xmm8
+ paddq %xmm6,%xmm9
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ leaq 16(%rdi),%rdi
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+ jmp .Lccm64_dec_outer
+
+.align 16
+.Lccm64_dec_break:
+
+ movups (%r11),%xmm0
+ movups 16(%r11),%xmm1
+ xorps %xmm0,%xmm8
+ leaq 32(%r11),%r11
+ xorps %xmm8,%xmm3
+.Loop_enc1_6:
+.byte 102,15,56,220,217
+ decl %eax
+ movups (%r11),%xmm1
+ leaq 16(%r11),%r11
+ jnz .Loop_enc1_6
+
+.byte 102,15,56,221,217
+ movups %xmm3,(%r9)
+ .byte 0xf3,0xc3
+.size aesni_ccm64_decrypt_blocks,.-aesni_ccm64_decrypt_blocks
+.globl aesni_ctr32_encrypt_blocks
+.type aesni_ctr32_encrypt_blocks,@function
+.align 16
+aesni_ctr32_encrypt_blocks:
+ cmpq $1,%rdx
+ je .Lctr32_one_shortcut
+
+ movdqu (%r8),%xmm14
+ movdqa .Lbswap_mask(%rip),%xmm15
+ xorl %eax,%eax
+.byte 102,69,15,58,22,242,3
+.byte 102,68,15,58,34,240,3
+
+ movl 240(%rcx),%eax
+ bswapl %r10d
+ pxor %xmm12,%xmm12
+ pxor %xmm13,%xmm13
+.byte 102,69,15,58,34,226,0
+ leaq 3(%r10),%r11
+.byte 102,69,15,58,34,235,0
+ incl %r10d
+.byte 102,69,15,58,34,226,1
+ incq %r11
+.byte 102,69,15,58,34,235,1
+ incl %r10d
+.byte 102,69,15,58,34,226,2
+ incq %r11
+.byte 102,69,15,58,34,235,2
+ movdqa %xmm12,-40(%rsp)
+.byte 102,69,15,56,0,231
+ movdqa %xmm13,-24(%rsp)
+.byte 102,69,15,56,0,239
+
+ pshufd $192,%xmm12,%xmm2
+ pshufd $128,%xmm12,%xmm3
+ pshufd $64,%xmm12,%xmm4
+ cmpq $6,%rdx
+ jb .Lctr32_tail
+ shrl $1,%eax
+ movq %rcx,%r11
+ movl %eax,%r10d
+ subq $6,%rdx
+ jmp .Lctr32_loop6
+
+.align 16
+.Lctr32_loop6:
+ pshufd $192,%xmm13,%xmm5
+ por %xmm14,%xmm2
+ movups (%r11),%xmm0
+ pshufd $128,%xmm13,%xmm6
+ por %xmm14,%xmm3
+ movups 16(%r11),%xmm1
+ pshufd $64,%xmm13,%xmm7
+ por %xmm14,%xmm4
+ por %xmm14,%xmm5
+ xorps %xmm0,%xmm2
+ por %xmm14,%xmm6
+ por %xmm14,%xmm7
+
+
+
+
+ pxor %xmm0,%xmm3
+.byte 102,15,56,220,209
+ leaq 32(%r11),%rcx
+ pxor %xmm0,%xmm4
+.byte 102,15,56,220,217
+ movdqa .Lincrement32(%rip),%xmm13
+ pxor %xmm0,%xmm5
+.byte 102,15,56,220,225
+ movdqa -40(%rsp),%xmm12
+ pxor %xmm0,%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+ movups (%rcx),%xmm0
+ decl %eax
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+ jmp .Lctr32_enc_loop6_enter
+.align 16
+.Lctr32_enc_loop6:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.Lctr32_enc_loop6_enter:
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+ movups (%rcx),%xmm0
+ jnz .Lctr32_enc_loop6
+
+.byte 102,15,56,220,209
+ paddd %xmm13,%xmm12
+.byte 102,15,56,220,217
+ paddd -24(%rsp),%xmm13
+.byte 102,15,56,220,225
+ movdqa %xmm12,-40(%rsp)
+.byte 102,15,56,220,233
+ movdqa %xmm13,-24(%rsp)
+.byte 102,15,56,220,241
+.byte 102,69,15,56,0,231
+.byte 102,15,56,220,249
+.byte 102,69,15,56,0,239
+
+.byte 102,15,56,221,208
+ movups (%rdi),%xmm8
+.byte 102,15,56,221,216
+ movups 16(%rdi),%xmm9
+.byte 102,15,56,221,224
+ movups 32(%rdi),%xmm10
+.byte 102,15,56,221,232
+ movups 48(%rdi),%xmm11
+.byte 102,15,56,221,240
+ movups 64(%rdi),%xmm1
+.byte 102,15,56,221,248
+ movups 80(%rdi),%xmm0
+ leaq 96(%rdi),%rdi
+
+ xorps %xmm2,%xmm8
+ pshufd $192,%xmm12,%xmm2
+ xorps %xmm3,%xmm9
+ pshufd $128,%xmm12,%xmm3
+ movups %xmm8,(%rsi)
+ xorps %xmm4,%xmm10
+ pshufd $64,%xmm12,%xmm4
+ movups %xmm9,16(%rsi)
+ xorps %xmm5,%xmm11
+ movups %xmm10,32(%rsi)
+ xorps %xmm6,%xmm1
+ movups %xmm11,48(%rsi)
+ xorps %xmm7,%xmm0
+ movups %xmm1,64(%rsi)
+ movups %xmm0,80(%rsi)
+ leaq 96(%rsi),%rsi
+ movl %r10d,%eax
+ subq $6,%rdx
+ jnc .Lctr32_loop6
+
+ addq $6,%rdx
+ jz .Lctr32_done
+ movq %r11,%rcx
+ leal 1(%rax,%rax,1),%eax
+
+.Lctr32_tail:
+ por %xmm14,%xmm2
+ movups (%rdi),%xmm8
+ cmpq $2,%rdx
+ jb .Lctr32_one
+
+ por %xmm14,%xmm3
+ movups 16(%rdi),%xmm9
+ je .Lctr32_two
+
+ pshufd $192,%xmm13,%xmm5
+ por %xmm14,%xmm4
+ movups 32(%rdi),%xmm10
+ cmpq $4,%rdx
+ jb .Lctr32_three
+
+ pshufd $128,%xmm13,%xmm6
+ por %xmm14,%xmm5
+ movups 48(%rdi),%xmm11
+ je .Lctr32_four
+
+ por %xmm14,%xmm6
+ xorps %xmm7,%xmm7
+
+ call _aesni_encrypt6
+
+ movups 64(%rdi),%xmm1
+ xorps %xmm2,%xmm8
+ xorps %xmm3,%xmm9
+ movups %xmm8,(%rsi)
+ xorps %xmm4,%xmm10
+ movups %xmm9,16(%rsi)
+ xorps %xmm5,%xmm11
+ movups %xmm10,32(%rsi)
+ xorps %xmm6,%xmm1
+ movups %xmm11,48(%rsi)
+ movups %xmm1,64(%rsi)
+ jmp .Lctr32_done
+
+.align 16
+.Lctr32_one_shortcut:
+ movups (%r8),%xmm2
+ movups (%rdi),%xmm8
+ movl 240(%rcx),%eax
+.Lctr32_one:
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+.Loop_enc1_7:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_enc1_7
+
+.byte 102,15,56,221,209
+ xorps %xmm2,%xmm8
+ movups %xmm8,(%rsi)
+ jmp .Lctr32_done
+
+.align 16
+.Lctr32_two:
+ xorps %xmm4,%xmm4
+ call _aesni_encrypt3
+ xorps %xmm2,%xmm8
+ xorps %xmm3,%xmm9
+ movups %xmm8,(%rsi)
+ movups %xmm9,16(%rsi)
+ jmp .Lctr32_done
+
+.align 16
+.Lctr32_three:
+ call _aesni_encrypt3
+ xorps %xmm2,%xmm8
+ xorps %xmm3,%xmm9
+ movups %xmm8,(%rsi)
+ xorps %xmm4,%xmm10
+ movups %xmm9,16(%rsi)
+ movups %xmm10,32(%rsi)
+ jmp .Lctr32_done
+
+.align 16
+.Lctr32_four:
+ call _aesni_encrypt4
+ xorps %xmm2,%xmm8
+ xorps %xmm3,%xmm9
+ movups %xmm8,(%rsi)
+ xorps %xmm4,%xmm10
+ movups %xmm9,16(%rsi)
+ xorps %xmm5,%xmm11
+ movups %xmm10,32(%rsi)
+ movups %xmm11,48(%rsi)
+
+.Lctr32_done:
+ .byte 0xf3,0xc3
+.size aesni_ctr32_encrypt_blocks,.-aesni_ctr32_encrypt_blocks
+.globl aesni_xts_encrypt
+.type aesni_xts_encrypt,@function
+.align 16
+aesni_xts_encrypt:
+ leaq -104(%rsp),%rsp
+ movups (%r9),%xmm15
+ movl 240(%r8),%eax
+ movl 240(%rcx),%r10d
+ movups (%r8),%xmm0
+ movups 16(%r8),%xmm1
+ leaq 32(%r8),%r8
+ xorps %xmm0,%xmm15
+.Loop_enc1_8:
+.byte 102,68,15,56,220,249
+ decl %eax
+ movups (%r8),%xmm1
+ leaq 16(%r8),%r8
+ jnz .Loop_enc1_8
+
+.byte 102,68,15,56,221,249
+ movq %rcx,%r11
+ movl %r10d,%eax
+ movq %rdx,%r9
+ andq $-16,%rdx
+
+ movdqa .Lxts_magic(%rip),%xmm8
+ pxor %xmm14,%xmm14
+ pcmpgtd %xmm15,%xmm14
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm10
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm11
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm12
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm13
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ subq $96,%rdx
+ jc .Lxts_enc_short
+
+ shrl $1,%eax
+ subl $1,%eax
+ movl %eax,%r10d
+ jmp .Lxts_enc_grandloop
+
+.align 16
+.Lxts_enc_grandloop:
+ pshufd $19,%xmm14,%xmm9
+ movdqa %xmm15,%xmm14
+ paddq %xmm15,%xmm15
+ movdqu 0(%rdi),%xmm2
+ pand %xmm8,%xmm9
+ movdqu 16(%rdi),%xmm3
+ pxor %xmm9,%xmm15
+
+ movdqu 32(%rdi),%xmm4
+ pxor %xmm10,%xmm2
+ movdqu 48(%rdi),%xmm5
+ pxor %xmm11,%xmm3
+ movdqu 64(%rdi),%xmm6
+ pxor %xmm12,%xmm4
+ movdqu 80(%rdi),%xmm7
+ leaq 96(%rdi),%rdi
+ pxor %xmm13,%xmm5
+ movups (%r11),%xmm0
+ pxor %xmm14,%xmm6
+ pxor %xmm15,%xmm7
+
+
+
+ movups 16(%r11),%xmm1
+ pxor %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ movdqa %xmm10,0(%rsp)
+.byte 102,15,56,220,209
+ leaq 32(%r11),%rcx
+ pxor %xmm0,%xmm4
+ movdqa %xmm11,16(%rsp)
+.byte 102,15,56,220,217
+ pxor %xmm0,%xmm5
+ movdqa %xmm12,32(%rsp)
+.byte 102,15,56,220,225
+ pxor %xmm0,%xmm6
+ movdqa %xmm13,48(%rsp)
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+ movups (%rcx),%xmm0
+ decl %eax
+ movdqa %xmm14,64(%rsp)
+.byte 102,15,56,220,241
+ movdqa %xmm15,80(%rsp)
+.byte 102,15,56,220,249
+ pxor %xmm14,%xmm14
+ pcmpgtd %xmm15,%xmm14
+ jmp .Lxts_enc_loop6_enter
+
+.align 16
+.Lxts_enc_loop6:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.Lxts_enc_loop6_enter:
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+ movups (%rcx),%xmm0
+ jnz .Lxts_enc_loop6
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ paddq %xmm15,%xmm15
+.byte 102,15,56,220,209
+ pand %xmm8,%xmm9
+.byte 102,15,56,220,217
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,220,225
+ pxor %xmm9,%xmm15
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+ movups 16(%rcx),%xmm1
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm10
+ paddq %xmm15,%xmm15
+.byte 102,15,56,220,208
+ pand %xmm8,%xmm9
+.byte 102,15,56,220,216
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,220,224
+ pxor %xmm9,%xmm15
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+ movups 32(%rcx),%xmm0
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm11
+ paddq %xmm15,%xmm15
+.byte 102,15,56,220,209
+ pand %xmm8,%xmm9
+.byte 102,15,56,220,217
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,220,225
+ pxor %xmm9,%xmm15
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm12
+ paddq %xmm15,%xmm15
+.byte 102,15,56,221,208
+ pand %xmm8,%xmm9
+.byte 102,15,56,221,216
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,221,224
+ pxor %xmm9,%xmm15
+.byte 102,15,56,221,232
+.byte 102,15,56,221,240
+.byte 102,15,56,221,248
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm13
+ paddq %xmm15,%xmm15
+ xorps 0(%rsp),%xmm2
+ pand %xmm8,%xmm9
+ xorps 16(%rsp),%xmm3
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+
+ xorps 32(%rsp),%xmm4
+ movups %xmm2,0(%rsi)
+ xorps 48(%rsp),%xmm5
+ movups %xmm3,16(%rsi)
+ xorps 64(%rsp),%xmm6
+ movups %xmm4,32(%rsi)
+ xorps 80(%rsp),%xmm7
+ movups %xmm5,48(%rsi)
+ movl %r10d,%eax
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ leaq 96(%rsi),%rsi
+ subq $96,%rdx
+ jnc .Lxts_enc_grandloop
+
+ leal 3(%rax,%rax,1),%eax
+ movq %r11,%rcx
+ movl %eax,%r10d
+
+.Lxts_enc_short:
+ addq $96,%rdx
+ jz .Lxts_enc_done
+
+ cmpq $32,%rdx
+ jb .Lxts_enc_one
+ je .Lxts_enc_two
+
+ cmpq $64,%rdx
+ jb .Lxts_enc_three
+ je .Lxts_enc_four
+
+ pshufd $19,%xmm14,%xmm9
+ movdqa %xmm15,%xmm14
+ paddq %xmm15,%xmm15
+ movdqu (%rdi),%xmm2
+ pand %xmm8,%xmm9
+ movdqu 16(%rdi),%xmm3
+ pxor %xmm9,%xmm15
+
+ movdqu 32(%rdi),%xmm4
+ pxor %xmm10,%xmm2
+ movdqu 48(%rdi),%xmm5
+ pxor %xmm11,%xmm3
+ movdqu 64(%rdi),%xmm6
+ leaq 80(%rdi),%rdi
+ pxor %xmm12,%xmm4
+ pxor %xmm13,%xmm5
+ pxor %xmm14,%xmm6
+
+ call _aesni_encrypt6
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm15,%xmm10
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ movdqu %xmm2,(%rsi)
+ xorps %xmm13,%xmm5
+ movdqu %xmm3,16(%rsi)
+ xorps %xmm14,%xmm6
+ movdqu %xmm4,32(%rsi)
+ movdqu %xmm5,48(%rsi)
+ movdqu %xmm6,64(%rsi)
+ leaq 80(%rsi),%rsi
+ jmp .Lxts_enc_done
+
+.align 16
+.Lxts_enc_one:
+ movups (%rdi),%xmm2
+ leaq 16(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+.Loop_enc1_9:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_enc1_9
+
+.byte 102,15,56,221,209
+ xorps %xmm10,%xmm2
+ movdqa %xmm11,%xmm10
+ movups %xmm2,(%rsi)
+ leaq 16(%rsi),%rsi
+ jmp .Lxts_enc_done
+
+.align 16
+.Lxts_enc_two:
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ leaq 32(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ xorps %xmm11,%xmm3
+
+ call _aesni_encrypt3
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm12,%xmm10
+ xorps %xmm11,%xmm3
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ leaq 32(%rsi),%rsi
+ jmp .Lxts_enc_done
+
+.align 16
+.Lxts_enc_three:
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ movups 32(%rdi),%xmm4
+ leaq 48(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+
+ call _aesni_encrypt3
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm13,%xmm10
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ leaq 48(%rsi),%rsi
+ jmp .Lxts_enc_done
+
+.align 16
+.Lxts_enc_four:
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ movups 32(%rdi),%xmm4
+ xorps %xmm10,%xmm2
+ movups 48(%rdi),%xmm5
+ leaq 64(%rdi),%rdi
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ xorps %xmm13,%xmm5
+
+ call _aesni_encrypt4
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm15,%xmm10
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ movups %xmm2,(%rsi)
+ xorps %xmm13,%xmm5
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ leaq 64(%rsi),%rsi
+ jmp .Lxts_enc_done
+
+.align 16
+.Lxts_enc_done:
+ andq $15,%r9
+ jz .Lxts_enc_ret
+ movq %r9,%rdx
+
+.Lxts_enc_steal:
+ movzbl (%rdi),%eax
+ movzbl -16(%rsi),%ecx
+ leaq 1(%rdi),%rdi
+ movb %al,-16(%rsi)
+ movb %cl,0(%rsi)
+ leaq 1(%rsi),%rsi
+ subq $1,%rdx
+ jnz .Lxts_enc_steal
+
+ subq %r9,%rsi
+ movq %r11,%rcx
+ movl %r10d,%eax
+
+ movups -16(%rsi),%xmm2
+ xorps %xmm10,%xmm2
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+.Loop_enc1_10:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_enc1_10
+
+.byte 102,15,56,221,209
+ xorps %xmm10,%xmm2
+ movups %xmm2,-16(%rsi)
+
+.Lxts_enc_ret:
+ leaq 104(%rsp),%rsp
+.Lxts_enc_epilogue:
+ .byte 0xf3,0xc3
+.size aesni_xts_encrypt,.-aesni_xts_encrypt
+.globl aesni_xts_decrypt
+.type aesni_xts_decrypt,@function
+.align 16
+aesni_xts_decrypt:
+ leaq -104(%rsp),%rsp
+ movups (%r9),%xmm15
+ movl 240(%r8),%eax
+ movl 240(%rcx),%r10d
+ movups (%r8),%xmm0
+ movups 16(%r8),%xmm1
+ leaq 32(%r8),%r8
+ xorps %xmm0,%xmm15
+.Loop_enc1_11:
+.byte 102,68,15,56,220,249
+ decl %eax
+ movups (%r8),%xmm1
+ leaq 16(%r8),%r8
+ jnz .Loop_enc1_11
+
+.byte 102,68,15,56,221,249
+ xorl %eax,%eax
+ testq $15,%rdx
+ setnz %al
+ shlq $4,%rax
+ subq %rax,%rdx
+
+ movq %rcx,%r11
+ movl %r10d,%eax
+ movq %rdx,%r9
+ andq $-16,%rdx
+
+ movdqa .Lxts_magic(%rip),%xmm8
+ pxor %xmm14,%xmm14
+ pcmpgtd %xmm15,%xmm14
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm10
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm11
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm12
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm13
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ subq $96,%rdx
+ jc .Lxts_dec_short
+
+ shrl $1,%eax
+ subl $1,%eax
+ movl %eax,%r10d
+ jmp .Lxts_dec_grandloop
+
+.align 16
+.Lxts_dec_grandloop:
+ pshufd $19,%xmm14,%xmm9
+ movdqa %xmm15,%xmm14
+ paddq %xmm15,%xmm15
+ movdqu 0(%rdi),%xmm2
+ pand %xmm8,%xmm9
+ movdqu 16(%rdi),%xmm3
+ pxor %xmm9,%xmm15
+
+ movdqu 32(%rdi),%xmm4
+ pxor %xmm10,%xmm2
+ movdqu 48(%rdi),%xmm5
+ pxor %xmm11,%xmm3
+ movdqu 64(%rdi),%xmm6
+ pxor %xmm12,%xmm4
+ movdqu 80(%rdi),%xmm7
+ leaq 96(%rdi),%rdi
+ pxor %xmm13,%xmm5
+ movups (%r11),%xmm0
+ pxor %xmm14,%xmm6
+ pxor %xmm15,%xmm7
+
+
+
+ movups 16(%r11),%xmm1
+ pxor %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ movdqa %xmm10,0(%rsp)
+.byte 102,15,56,222,209
+ leaq 32(%r11),%rcx
+ pxor %xmm0,%xmm4
+ movdqa %xmm11,16(%rsp)
+.byte 102,15,56,222,217
+ pxor %xmm0,%xmm5
+ movdqa %xmm12,32(%rsp)
+.byte 102,15,56,222,225
+ pxor %xmm0,%xmm6
+ movdqa %xmm13,48(%rsp)
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+ movups (%rcx),%xmm0
+ decl %eax
+ movdqa %xmm14,64(%rsp)
+.byte 102,15,56,222,241
+ movdqa %xmm15,80(%rsp)
+.byte 102,15,56,222,249
+ pxor %xmm14,%xmm14
+ pcmpgtd %xmm15,%xmm14
+ jmp .Lxts_dec_loop6_enter
+
+.align 16
+.Lxts_dec_loop6:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %eax
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.Lxts_dec_loop6_enter:
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+.byte 102,15,56,222,240
+.byte 102,15,56,222,248
+ movups (%rcx),%xmm0
+ jnz .Lxts_dec_loop6
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ paddq %xmm15,%xmm15
+.byte 102,15,56,222,209
+ pand %xmm8,%xmm9
+.byte 102,15,56,222,217
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,222,225
+ pxor %xmm9,%xmm15
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+ movups 16(%rcx),%xmm1
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm10
+ paddq %xmm15,%xmm15
+.byte 102,15,56,222,208
+ pand %xmm8,%xmm9
+.byte 102,15,56,222,216
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,222,224
+ pxor %xmm9,%xmm15
+.byte 102,15,56,222,232
+.byte 102,15,56,222,240
+.byte 102,15,56,222,248
+ movups 32(%rcx),%xmm0
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm11
+ paddq %xmm15,%xmm15
+.byte 102,15,56,222,209
+ pand %xmm8,%xmm9
+.byte 102,15,56,222,217
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,222,225
+ pxor %xmm9,%xmm15
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm12
+ paddq %xmm15,%xmm15
+.byte 102,15,56,223,208
+ pand %xmm8,%xmm9
+.byte 102,15,56,223,216
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,223,224
+ pxor %xmm9,%xmm15
+.byte 102,15,56,223,232
+.byte 102,15,56,223,240
+.byte 102,15,56,223,248
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm13
+ paddq %xmm15,%xmm15
+ xorps 0(%rsp),%xmm2
+ pand %xmm8,%xmm9
+ xorps 16(%rsp),%xmm3
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+
+ xorps 32(%rsp),%xmm4
+ movups %xmm2,0(%rsi)
+ xorps 48(%rsp),%xmm5
+ movups %xmm3,16(%rsi)
+ xorps 64(%rsp),%xmm6
+ movups %xmm4,32(%rsi)
+ xorps 80(%rsp),%xmm7
+ movups %xmm5,48(%rsi)
+ movl %r10d,%eax
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ leaq 96(%rsi),%rsi
+ subq $96,%rdx
+ jnc .Lxts_dec_grandloop
+
+ leal 3(%rax,%rax,1),%eax
+ movq %r11,%rcx
+ movl %eax,%r10d
+
+.Lxts_dec_short:
+ addq $96,%rdx
+ jz .Lxts_dec_done
+
+ cmpq $32,%rdx
+ jb .Lxts_dec_one
+ je .Lxts_dec_two
+
+ cmpq $64,%rdx
+ jb .Lxts_dec_three
+ je .Lxts_dec_four
+
+ pshufd $19,%xmm14,%xmm9
+ movdqa %xmm15,%xmm14
+ paddq %xmm15,%xmm15
+ movdqu (%rdi),%xmm2
+ pand %xmm8,%xmm9
+ movdqu 16(%rdi),%xmm3
+ pxor %xmm9,%xmm15
+
+ movdqu 32(%rdi),%xmm4
+ pxor %xmm10,%xmm2
+ movdqu 48(%rdi),%xmm5
+ pxor %xmm11,%xmm3
+ movdqu 64(%rdi),%xmm6
+ leaq 80(%rdi),%rdi
+ pxor %xmm12,%xmm4
+ pxor %xmm13,%xmm5
+ pxor %xmm14,%xmm6
+
+ call _aesni_decrypt6
+
+ xorps %xmm10,%xmm2
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ movdqu %xmm2,(%rsi)
+ xorps %xmm13,%xmm5
+ movdqu %xmm3,16(%rsi)
+ xorps %xmm14,%xmm6
+ movdqu %xmm4,32(%rsi)
+ pxor %xmm14,%xmm14
+ movdqu %xmm5,48(%rsi)
+ pcmpgtd %xmm15,%xmm14
+ movdqu %xmm6,64(%rsi)
+ leaq 80(%rsi),%rsi
+ pshufd $19,%xmm14,%xmm11
+ andq $15,%r9
+ jz .Lxts_dec_ret
+
+ movdqa %xmm15,%xmm10
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm11
+ pxor %xmm15,%xmm11
+ jmp .Lxts_dec_done2
+
+.align 16
+.Lxts_dec_one:
+ movups (%rdi),%xmm2
+ leaq 16(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+.Loop_dec1_12:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_dec1_12
+
+.byte 102,15,56,223,209
+ xorps %xmm10,%xmm2
+ movdqa %xmm11,%xmm10
+ movups %xmm2,(%rsi)
+ movdqa %xmm12,%xmm11
+ leaq 16(%rsi),%rsi
+ jmp .Lxts_dec_done
+
+.align 16
+.Lxts_dec_two:
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ leaq 32(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ xorps %xmm11,%xmm3
+
+ call _aesni_decrypt3
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm12,%xmm10
+ xorps %xmm11,%xmm3
+ movdqa %xmm13,%xmm11
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ leaq 32(%rsi),%rsi
+ jmp .Lxts_dec_done
+
+.align 16
+.Lxts_dec_three:
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ movups 32(%rdi),%xmm4
+ leaq 48(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+
+ call _aesni_decrypt3
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm13,%xmm10
+ xorps %xmm11,%xmm3
+ movdqa %xmm15,%xmm11
+ xorps %xmm12,%xmm4
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ leaq 48(%rsi),%rsi
+ jmp .Lxts_dec_done
+
+.align 16
+.Lxts_dec_four:
+ pshufd $19,%xmm14,%xmm9
+ movdqa %xmm15,%xmm14
+ paddq %xmm15,%xmm15
+ movups (%rdi),%xmm2
+ pand %xmm8,%xmm9
+ movups 16(%rdi),%xmm3
+ pxor %xmm9,%xmm15
+
+ movups 32(%rdi),%xmm4
+ xorps %xmm10,%xmm2
+ movups 48(%rdi),%xmm5
+ leaq 64(%rdi),%rdi
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ xorps %xmm13,%xmm5
+
+ call _aesni_decrypt4
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm14,%xmm10
+ xorps %xmm11,%xmm3
+ movdqa %xmm15,%xmm11
+ xorps %xmm12,%xmm4
+ movups %xmm2,(%rsi)
+ xorps %xmm13,%xmm5
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ leaq 64(%rsi),%rsi
+ jmp .Lxts_dec_done
+
+.align 16
+.Lxts_dec_done:
+ andq $15,%r9
+ jz .Lxts_dec_ret
+.Lxts_dec_done2:
+ movq %r9,%rdx
+ movq %r11,%rcx
+ movl %r10d,%eax
+
+ movups (%rdi),%xmm2
+ xorps %xmm11,%xmm2
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+.Loop_dec1_13:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_dec1_13
+
+.byte 102,15,56,223,209
+ xorps %xmm11,%xmm2
+ movups %xmm2,(%rsi)
+
+.Lxts_dec_steal:
+ movzbl 16(%rdi),%eax
+ movzbl (%rsi),%ecx
+ leaq 1(%rdi),%rdi
+ movb %al,(%rsi)
+ movb %cl,16(%rsi)
+ leaq 1(%rsi),%rsi
+ subq $1,%rdx
+ jnz .Lxts_dec_steal
+
+ subq %r9,%rsi
+ movq %r11,%rcx
+ movl %r10d,%eax
+
+ movups (%rsi),%xmm2
+ xorps %xmm10,%xmm2
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+.Loop_dec1_14:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_dec1_14
+
+.byte 102,15,56,223,209
+ xorps %xmm10,%xmm2
+ movups %xmm2,(%rsi)
+
+.Lxts_dec_ret:
+ leaq 104(%rsp),%rsp
+.Lxts_dec_epilogue:
+ .byte 0xf3,0xc3
+.size aesni_xts_decrypt,.-aesni_xts_decrypt
+.globl aesni_cbc_encrypt
+.type aesni_cbc_encrypt,@function
+.align 16
+aesni_cbc_encrypt:
+ testq %rdx,%rdx
+ jz .Lcbc_ret
+
+ movl 240(%rcx),%r10d
+ movq %rcx,%r11
+ testl %r9d,%r9d
+ jz .Lcbc_decrypt
+
+ movups (%r8),%xmm2
+ movl %r10d,%eax
+ cmpq $16,%rdx
+ jb .Lcbc_enc_tail
+ subq $16,%rdx
+ jmp .Lcbc_enc_loop
+.align 16
+.Lcbc_enc_loop:
+ movups (%rdi),%xmm3
+ leaq 16(%rdi),%rdi
+
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ xorps %xmm0,%xmm3
+ leaq 32(%rcx),%rcx
+ xorps %xmm3,%xmm2
+.Loop_enc1_15:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_enc1_15
+
+.byte 102,15,56,221,209
+ movl %r10d,%eax
+ movq %r11,%rcx
+ movups %xmm2,0(%rsi)
+ leaq 16(%rsi),%rsi
+ subq $16,%rdx
+ jnc .Lcbc_enc_loop
+ addq $16,%rdx
+ jnz .Lcbc_enc_tail
+ movups %xmm2,(%r8)
+ jmp .Lcbc_ret
+
+.Lcbc_enc_tail:
+ movq %rdx,%rcx
+ xchgq %rdi,%rsi
+.long 0x9066A4F3
+
+ movl $16,%ecx
+ subq %rdx,%rcx
+ xorl %eax,%eax
+.long 0x9066AAF3
+
+ leaq -16(%rdi),%rdi
+ movl %r10d,%eax
+ movq %rdi,%rsi
+ movq %r11,%rcx
+ xorq %rdx,%rdx
+ jmp .Lcbc_enc_loop
+
+
+.align 16
+.Lcbc_decrypt:
+ movups (%r8),%xmm9
+ movl %r10d,%eax
+ cmpq $112,%rdx
+ jbe .Lcbc_dec_tail
+ shrl $1,%r10d
+ subq $112,%rdx
+ movl %r10d,%eax
+ movaps %xmm9,-24(%rsp)
+ jmp .Lcbc_dec_loop8_enter
+.align 16
+.Lcbc_dec_loop8:
+ movaps %xmm0,-24(%rsp)
+ movups %xmm9,(%rsi)
+ leaq 16(%rsi),%rsi
+.Lcbc_dec_loop8_enter:
+ movups (%rcx),%xmm0
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ movups 16(%rcx),%xmm1
+
+ leaq 32(%rcx),%rcx
+ movdqu 32(%rdi),%xmm4
+ xorps %xmm0,%xmm2
+ movdqu 48(%rdi),%xmm5
+ xorps %xmm0,%xmm3
+ movdqu 64(%rdi),%xmm6
+.byte 102,15,56,222,209
+ pxor %xmm0,%xmm4
+ movdqu 80(%rdi),%xmm7
+.byte 102,15,56,222,217
+ pxor %xmm0,%xmm5
+ movdqu 96(%rdi),%xmm8
+.byte 102,15,56,222,225
+ pxor %xmm0,%xmm6
+ movdqu 112(%rdi),%xmm9
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+ decl %eax
+.byte 102,15,56,222,241
+ pxor %xmm0,%xmm8
+.byte 102,15,56,222,249
+ pxor %xmm0,%xmm9
+ movups (%rcx),%xmm0
+.byte 102,68,15,56,222,193
+.byte 102,68,15,56,222,201
+ movups 16(%rcx),%xmm1
+
+ call .Ldec_loop8_enter
+
+ movups (%rdi),%xmm1
+ movups 16(%rdi),%xmm0
+ xorps -24(%rsp),%xmm2
+ xorps %xmm1,%xmm3
+ movups 32(%rdi),%xmm1
+ xorps %xmm0,%xmm4
+ movups 48(%rdi),%xmm0
+ xorps %xmm1,%xmm5
+ movups 64(%rdi),%xmm1
+ xorps %xmm0,%xmm6
+ movups 80(%rdi),%xmm0
+ xorps %xmm1,%xmm7
+ movups 96(%rdi),%xmm1
+ xorps %xmm0,%xmm8
+ movups 112(%rdi),%xmm0
+ xorps %xmm1,%xmm9
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movl %r10d,%eax
+ movups %xmm6,64(%rsi)
+ movq %r11,%rcx
+ movups %xmm7,80(%rsi)
+ leaq 128(%rdi),%rdi
+ movups %xmm8,96(%rsi)
+ leaq 112(%rsi),%rsi
+ subq $128,%rdx
+ ja .Lcbc_dec_loop8
+
+ movaps %xmm9,%xmm2
+ movaps %xmm0,%xmm9
+ addq $112,%rdx
+ jle .Lcbc_dec_tail_collected
+ movups %xmm2,(%rsi)
+ leal 1(%r10,%r10,1),%eax
+ leaq 16(%rsi),%rsi
+.Lcbc_dec_tail:
+ movups (%rdi),%xmm2
+ movaps %xmm2,%xmm8
+ cmpq $16,%rdx
+ jbe .Lcbc_dec_one
+
+ movups 16(%rdi),%xmm3
+ movaps %xmm3,%xmm7
+ cmpq $32,%rdx
+ jbe .Lcbc_dec_two
+
+ movups 32(%rdi),%xmm4
+ movaps %xmm4,%xmm6
+ cmpq $48,%rdx
+ jbe .Lcbc_dec_three
+
+ movups 48(%rdi),%xmm5
+ cmpq $64,%rdx
+ jbe .Lcbc_dec_four
+
+ movups 64(%rdi),%xmm6
+ cmpq $80,%rdx
+ jbe .Lcbc_dec_five
+
+ movups 80(%rdi),%xmm7
+ cmpq $96,%rdx
+ jbe .Lcbc_dec_six
+
+ movups 96(%rdi),%xmm8
+ movaps %xmm9,-24(%rsp)
+ call _aesni_decrypt8
+ movups (%rdi),%xmm1
+ movups 16(%rdi),%xmm0
+ xorps -24(%rsp),%xmm2
+ xorps %xmm1,%xmm3
+ movups 32(%rdi),%xmm1
+ xorps %xmm0,%xmm4
+ movups 48(%rdi),%xmm0
+ xorps %xmm1,%xmm5
+ movups 64(%rdi),%xmm1
+ xorps %xmm0,%xmm6
+ movups 80(%rdi),%xmm0
+ xorps %xmm1,%xmm7
+ movups 96(%rdi),%xmm9
+ xorps %xmm0,%xmm8
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ leaq 96(%rsi),%rsi
+ movaps %xmm8,%xmm2
+ subq $112,%rdx
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_one:
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+.Loop_dec1_16:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz .Loop_dec1_16
+
+.byte 102,15,56,223,209
+ xorps %xmm9,%xmm2
+ movaps %xmm8,%xmm9
+ subq $16,%rdx
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_two:
+ xorps %xmm4,%xmm4
+ call _aesni_decrypt3
+ xorps %xmm9,%xmm2
+ xorps %xmm8,%xmm3
+ movups %xmm2,(%rsi)
+ movaps %xmm7,%xmm9
+ movaps %xmm3,%xmm2
+ leaq 16(%rsi),%rsi
+ subq $32,%rdx
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_three:
+ call _aesni_decrypt3
+ xorps %xmm9,%xmm2
+ xorps %xmm8,%xmm3
+ movups %xmm2,(%rsi)
+ xorps %xmm7,%xmm4
+ movups %xmm3,16(%rsi)
+ movaps %xmm6,%xmm9
+ movaps %xmm4,%xmm2
+ leaq 32(%rsi),%rsi
+ subq $48,%rdx
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_four:
+ call _aesni_decrypt4
+ xorps %xmm9,%xmm2
+ movups 48(%rdi),%xmm9
+ xorps %xmm8,%xmm3
+ movups %xmm2,(%rsi)
+ xorps %xmm7,%xmm4
+ movups %xmm3,16(%rsi)
+ xorps %xmm6,%xmm5
+ movups %xmm4,32(%rsi)
+ movaps %xmm5,%xmm2
+ leaq 48(%rsi),%rsi
+ subq $64,%rdx
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_five:
+ xorps %xmm7,%xmm7
+ call _aesni_decrypt6
+ movups 16(%rdi),%xmm1
+ movups 32(%rdi),%xmm0
+ xorps %xmm9,%xmm2
+ xorps %xmm8,%xmm3
+ xorps %xmm1,%xmm4
+ movups 48(%rdi),%xmm1
+ xorps %xmm0,%xmm5
+ movups 64(%rdi),%xmm9
+ xorps %xmm1,%xmm6
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ leaq 64(%rsi),%rsi
+ movaps %xmm6,%xmm2
+ subq $80,%rdx
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_six:
+ call _aesni_decrypt6
+ movups 16(%rdi),%xmm1
+ movups 32(%rdi),%xmm0
+ xorps %xmm9,%xmm2
+ xorps %xmm8,%xmm3
+ xorps %xmm1,%xmm4
+ movups 48(%rdi),%xmm1
+ xorps %xmm0,%xmm5
+ movups 64(%rdi),%xmm0
+ xorps %xmm1,%xmm6
+ movups 80(%rdi),%xmm9
+ xorps %xmm0,%xmm7
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ leaq 80(%rsi),%rsi
+ movaps %xmm7,%xmm2
+ subq $96,%rdx
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_tail_collected:
+ andq $15,%rdx
+ movups %xmm9,(%r8)
+ jnz .Lcbc_dec_tail_partial
+ movups %xmm2,(%rsi)
+ jmp .Lcbc_dec_ret
+.align 16
+.Lcbc_dec_tail_partial:
+ movaps %xmm2,-24(%rsp)
+ movq $16,%rcx
+ movq %rsi,%rdi
+ subq %rdx,%rcx
+ leaq -24(%rsp),%rsi
+.long 0x9066A4F3
+
+
+.Lcbc_dec_ret:
+.Lcbc_ret:
+ .byte 0xf3,0xc3
+.size aesni_cbc_encrypt,.-aesni_cbc_encrypt
+.globl aesni_set_decrypt_key
+.type aesni_set_decrypt_key,@function
+.align 16
+aesni_set_decrypt_key:
+.byte 0x48,0x83,0xEC,0x08
+
+ call __aesni_set_encrypt_key
+ shll $4,%esi
+ testl %eax,%eax
+ jnz .Ldec_key_ret
+ leaq 16(%rdx,%rsi,1),%rdi
+
+ movups (%rdx),%xmm0
+ movups (%rdi),%xmm1
+ movups %xmm0,(%rdi)
+ movups %xmm1,(%rdx)
+ leaq 16(%rdx),%rdx
+ leaq -16(%rdi),%rdi
+
+.Ldec_key_inverse:
+ movups (%rdx),%xmm0
+ movups (%rdi),%xmm1
+.byte 102,15,56,219,192
+.byte 102,15,56,219,201
+ leaq 16(%rdx),%rdx
+ leaq -16(%rdi),%rdi
+ movups %xmm0,16(%rdi)
+ movups %xmm1,-16(%rdx)
+ cmpq %rdx,%rdi
+ ja .Ldec_key_inverse
+
+ movups (%rdx),%xmm0
+.byte 102,15,56,219,192
+ movups %xmm0,(%rdi)
+.Ldec_key_ret:
+ addq $8,%rsp
+ .byte 0xf3,0xc3
+.LSEH_end_set_decrypt_key:
+.size aesni_set_decrypt_key,.-aesni_set_decrypt_key
+.globl aesni_set_encrypt_key
+.type aesni_set_encrypt_key,@function
+.align 16
+aesni_set_encrypt_key:
+__aesni_set_encrypt_key:
+.byte 0x48,0x83,0xEC,0x08
+
+ movq $-1,%rax
+ testq %rdi,%rdi
+ jz .Lenc_key_ret
+ testq %rdx,%rdx
+ jz .Lenc_key_ret
+
+ movups (%rdi),%xmm0
+ xorps %xmm4,%xmm4
+ leaq 16(%rdx),%rax
+ cmpl $256,%esi
+ je .L14rounds
+ cmpl $192,%esi
+ je .L12rounds
+ cmpl $128,%esi
+ jne .Lbad_keybits
+
+.L10rounds:
+ movl $9,%esi
+ movups %xmm0,(%rdx)
+.byte 102,15,58,223,200,1
+ call .Lkey_expansion_128_cold
+.byte 102,15,58,223,200,2
+ call .Lkey_expansion_128
+.byte 102,15,58,223,200,4
+ call .Lkey_expansion_128
+.byte 102,15,58,223,200,8
+ call .Lkey_expansion_128
+.byte 102,15,58,223,200,16
+ call .Lkey_expansion_128
+.byte 102,15,58,223,200,32
+ call .Lkey_expansion_128
+.byte 102,15,58,223,200,64
+ call .Lkey_expansion_128
+.byte 102,15,58,223,200,128
+ call .Lkey_expansion_128
+.byte 102,15,58,223,200,27
+ call .Lkey_expansion_128
+.byte 102,15,58,223,200,54
+ call .Lkey_expansion_128
+ movups %xmm0,(%rax)
+ movl %esi,80(%rax)
+ xorl %eax,%eax
+ jmp .Lenc_key_ret
+
+.align 16
+.L12rounds:
+ movq 16(%rdi),%xmm2
+ movl $11,%esi
+ movups %xmm0,(%rdx)
+.byte 102,15,58,223,202,1
+ call .Lkey_expansion_192a_cold
+.byte 102,15,58,223,202,2
+ call .Lkey_expansion_192b
+.byte 102,15,58,223,202,4
+ call .Lkey_expansion_192a
+.byte 102,15,58,223,202,8
+ call .Lkey_expansion_192b
+.byte 102,15,58,223,202,16
+ call .Lkey_expansion_192a
+.byte 102,15,58,223,202,32
+ call .Lkey_expansion_192b
+.byte 102,15,58,223,202,64
+ call .Lkey_expansion_192a
+.byte 102,15,58,223,202,128
+ call .Lkey_expansion_192b
+ movups %xmm0,(%rax)
+ movl %esi,48(%rax)
+ xorq %rax,%rax
+ jmp .Lenc_key_ret
+
+.align 16
+.L14rounds:
+ movups 16(%rdi),%xmm2
+ movl $13,%esi
+ leaq 16(%rax),%rax
+ movups %xmm0,(%rdx)
+ movups %xmm2,16(%rdx)
+.byte 102,15,58,223,202,1
+ call .Lkey_expansion_256a_cold
+.byte 102,15,58,223,200,1
+ call .Lkey_expansion_256b
+.byte 102,15,58,223,202,2
+ call .Lkey_expansion_256a
+.byte 102,15,58,223,200,2
+ call .Lkey_expansion_256b
+.byte 102,15,58,223,202,4
+ call .Lkey_expansion_256a
+.byte 102,15,58,223,200,4
+ call .Lkey_expansion_256b
+.byte 102,15,58,223,202,8
+ call .Lkey_expansion_256a
+.byte 102,15,58,223,200,8
+ call .Lkey_expansion_256b
+.byte 102,15,58,223,202,16
+ call .Lkey_expansion_256a
+.byte 102,15,58,223,200,16
+ call .Lkey_expansion_256b
+.byte 102,15,58,223,202,32
+ call .Lkey_expansion_256a
+.byte 102,15,58,223,200,32
+ call .Lkey_expansion_256b
+.byte 102,15,58,223,202,64
+ call .Lkey_expansion_256a
+ movups %xmm0,(%rax)
+ movl %esi,16(%rax)
+ xorq %rax,%rax
+ jmp .Lenc_key_ret
+
+.align 16
+.Lbad_keybits:
+ movq $-2,%rax
+.Lenc_key_ret:
+ addq $8,%rsp
+ .byte 0xf3,0xc3
+.LSEH_end_set_encrypt_key:
+
+.align 16
+.Lkey_expansion_128:
+ movups %xmm0,(%rax)
+ leaq 16(%rax),%rax
+.Lkey_expansion_128_cold:
+ shufps $16,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $255,%xmm1,%xmm1
+ xorps %xmm1,%xmm0
+ .byte 0xf3,0xc3
+
+.align 16
+.Lkey_expansion_192a:
+ movups %xmm0,(%rax)
+ leaq 16(%rax),%rax
+.Lkey_expansion_192a_cold:
+ movaps %xmm2,%xmm5
+.Lkey_expansion_192b_warm:
+ shufps $16,%xmm0,%xmm4
+ movdqa %xmm2,%xmm3
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ pslldq $4,%xmm3
+ xorps %xmm4,%xmm0
+ pshufd $85,%xmm1,%xmm1
+ pxor %xmm3,%xmm2
+ pxor %xmm1,%xmm0
+ pshufd $255,%xmm0,%xmm3
+ pxor %xmm3,%xmm2
+ .byte 0xf3,0xc3
+
+.align 16
+.Lkey_expansion_192b:
+ movaps %xmm0,%xmm3
+ shufps $68,%xmm0,%xmm5
+ movups %xmm5,(%rax)
+ shufps $78,%xmm2,%xmm3
+ movups %xmm3,16(%rax)
+ leaq 32(%rax),%rax
+ jmp .Lkey_expansion_192b_warm
+
+.align 16
+.Lkey_expansion_256a:
+ movups %xmm2,(%rax)
+ leaq 16(%rax),%rax
+.Lkey_expansion_256a_cold:
+ shufps $16,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $255,%xmm1,%xmm1
+ xorps %xmm1,%xmm0
+ .byte 0xf3,0xc3
+
+.align 16
+.Lkey_expansion_256b:
+ movups %xmm0,(%rax)
+ leaq 16(%rax),%rax
+
+ shufps $16,%xmm2,%xmm4
+ xorps %xmm4,%xmm2
+ shufps $140,%xmm2,%xmm4
+ xorps %xmm4,%xmm2
+ shufps $170,%xmm1,%xmm1
+ xorps %xmm1,%xmm2
+ .byte 0xf3,0xc3
+.size aesni_set_encrypt_key,.-aesni_set_encrypt_key
+.size __aesni_set_encrypt_key,.-__aesni_set_encrypt_key
+.align 64
+.Lbswap_mask:
+.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+.Lincrement32:
+.long 6,6,6,0
+.Lincrement64:
+.long 1,0,0,0
+.Lxts_magic:
+.long 0x87,0,1,0
+
+.byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 64
diff --git a/deps/openssl/asm/x64-elf-gas/bn/modexp512-x86_64.s b/deps/openssl/asm/x64-elf-gas/bn/modexp512-x86_64.s
new file mode 100644
index 000000000..c980dd073
--- /dev/null
+++ b/deps/openssl/asm/x64-elf-gas/bn/modexp512-x86_64.s
@@ -0,0 +1,1776 @@
+.text
+
+
+.type MULADD_128x512,@function
+.align 16
+MULADD_128x512:
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ movq %r8,0(%rcx)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%r8
+ movq 8(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ movq %r9,8(%rcx)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%r9
+ .byte 0xf3,0xc3
+.size MULADD_128x512,.-MULADD_128x512
+.type mont_reduce,@function
+.align 16
+mont_reduce:
+ leaq 192(%rsp),%rdi
+ movq 32(%rsp),%rsi
+ addq $576,%rsi
+ leaq 520(%rsp),%rcx
+
+ movq 96(%rcx),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ movq (%rcx),%r8
+ addq %rax,%r8
+ adcq $0,%rdx
+ movq %r8,0(%rdi)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ movq 8(%rcx),%r9
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ movq 16(%rcx),%r10
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ movq 24(%rcx),%r11
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ movq 32(%rcx),%r12
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ movq 40(%rcx),%r13
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ movq 48(%rcx),%r14
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ movq 56(%rcx),%r15
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%r8
+ movq 104(%rcx),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ movq %r9,8(%rdi)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%r9
+ movq 112(%rcx),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ movq %r10,16(%rdi)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%r10
+ movq 120(%rcx),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %r11,24(%rdi)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+ xorq %rax,%rax
+
+ addq 64(%rcx),%r8
+ adcq 72(%rcx),%r9
+ adcq 80(%rcx),%r10
+ adcq 88(%rcx),%r11
+ adcq $0,%rax
+
+
+
+
+ movq %r8,64(%rdi)
+ movq %r9,72(%rdi)
+ movq %r10,%rbp
+ movq %r11,88(%rdi)
+
+ movq %rax,384(%rsp)
+
+ movq 0(%rdi),%r8
+ movq 8(%rdi),%r9
+ movq 16(%rdi),%r10
+ movq 24(%rdi),%r11
+
+
+
+
+
+
+
+
+ addq $80,%rdi
+
+ addq $64,%rsi
+ leaq 296(%rsp),%rcx
+
+ call MULADD_128x512
+
+
+ movq 384(%rsp),%rax
+
+
+ addq -16(%rdi),%r8
+ adcq -8(%rdi),%r9
+ movq %r8,64(%rcx)
+ movq %r9,72(%rcx)
+
+ adcq %rax,%rax
+ movq %rax,384(%rsp)
+
+ leaq 192(%rsp),%rdi
+ addq $64,%rsi
+
+
+
+
+
+ movq (%rsi),%r8
+ movq 8(%rsi),%rbx
+
+ movq (%rcx),%rax
+ mulq %r8
+ movq %rax,%rbp
+ movq %rdx,%r9
+
+ movq 8(%rcx),%rax
+ mulq %r8
+ addq %rax,%r9
+
+ movq (%rcx),%rax
+ mulq %rbx
+ addq %rax,%r9
+
+ movq %r9,8(%rdi)
+
+
+ subq $192,%rsi
+
+ movq (%rcx),%r8
+ movq 8(%rcx),%r9
+
+ call MULADD_128x512
+
+
+
+
+
+ movq 0(%rsi),%rax
+ movq 8(%rsi),%rbx
+ movq 16(%rsi),%rdi
+ movq 24(%rsi),%rdx
+
+
+ movq 384(%rsp),%rbp
+
+ addq 64(%rcx),%r8
+ adcq 72(%rcx),%r9
+
+
+ adcq %rbp,%rbp
+
+
+
+ shlq $3,%rbp
+ movq 32(%rsp),%rcx
+ addq %rcx,%rbp
+
+
+ xorq %rsi,%rsi
+
+ addq 0(%rbp),%r10
+ adcq 64(%rbp),%r11
+ adcq 128(%rbp),%r12
+ adcq 192(%rbp),%r13
+ adcq 256(%rbp),%r14
+ adcq 320(%rbp),%r15
+ adcq 384(%rbp),%r8
+ adcq 448(%rbp),%r9
+
+
+
+ sbbq $0,%rsi
+
+
+ andq %rsi,%rax
+ andq %rsi,%rbx
+ andq %rsi,%rdi
+ andq %rsi,%rdx
+
+ movq $1,%rbp
+ subq %rax,%r10
+ sbbq %rbx,%r11
+ sbbq %rdi,%r12
+ sbbq %rdx,%r13
+
+
+
+
+ sbbq $0,%rbp
+
+
+
+ addq $512,%rcx
+ movq 32(%rcx),%rax
+ movq 40(%rcx),%rbx
+ movq 48(%rcx),%rdi
+ movq 56(%rcx),%rdx
+
+
+
+ andq %rsi,%rax
+ andq %rsi,%rbx
+ andq %rsi,%rdi
+ andq %rsi,%rdx
+
+
+
+ subq $1,%rbp
+
+ sbbq %rax,%r14
+ sbbq %rbx,%r15
+ sbbq %rdi,%r8
+ sbbq %rdx,%r9
+
+
+
+ movq 144(%rsp),%rsi
+ movq %r10,0(%rsi)
+ movq %r11,8(%rsi)
+ movq %r12,16(%rsi)
+ movq %r13,24(%rsi)
+ movq %r14,32(%rsi)
+ movq %r15,40(%rsi)
+ movq %r8,48(%rsi)
+ movq %r9,56(%rsi)
+
+ .byte 0xf3,0xc3
+.size mont_reduce,.-mont_reduce
+.type mont_mul_a3b,@function
+.align 16
+mont_mul_a3b:
+
+
+
+
+ movq 0(%rdi),%rbp
+
+ movq %r10,%rax
+ mulq %rbp
+ movq %rax,520(%rsp)
+ movq %rdx,%r10
+ movq %r11,%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+ movq %r12,%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %rdx,%r12
+ movq %r13,%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ movq %rdx,%r13
+ movq %r14,%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ movq %rdx,%r14
+ movq %r15,%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ movq %rdx,%r15
+ movq %r8,%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ movq %rdx,%r8
+ movq %r9,%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ movq %rdx,%r9
+ movq 8(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ movq %r10,528(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%r10
+ movq 16(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %r11,536(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+ movq 24(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ movq %r12,544(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%r12
+ movq 32(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ movq %r13,552(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%r13
+ movq 40(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ movq %r14,560(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%r14
+ movq 48(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ movq %r15,568(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%r15
+ movq 56(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ movq %r8,576(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%r8
+ movq %r9,584(%rsp)
+ movq %r10,592(%rsp)
+ movq %r11,600(%rsp)
+ movq %r12,608(%rsp)
+ movq %r13,616(%rsp)
+ movq %r14,624(%rsp)
+ movq %r15,632(%rsp)
+ movq %r8,640(%rsp)
+
+
+
+
+
+ jmp mont_reduce
+
+
+.size mont_mul_a3b,.-mont_mul_a3b
+.type sqr_reduce,@function
+.align 16
+sqr_reduce:
+ movq 16(%rsp),%rcx
+
+
+
+ movq %r10,%rbx
+
+ movq %r11,%rax
+ mulq %rbx
+ movq %rax,528(%rsp)
+ movq %rdx,%r10
+ movq %r12,%rax
+ mulq %rbx
+ addq %rax,%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+ movq %r13,%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %rdx,%r12
+ movq %r14,%rax
+ mulq %rbx
+ addq %rax,%r12
+ adcq $0,%rdx
+ movq %rdx,%r13
+ movq %r15,%rax
+ mulq %rbx
+ addq %rax,%r13
+ adcq $0,%rdx
+ movq %rdx,%r14
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%r14
+ adcq $0,%rdx
+ movq %rdx,%r15
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ movq %rdx,%rsi
+
+ movq %r10,536(%rsp)
+
+
+
+
+
+ movq 8(%rcx),%rbx
+
+ movq 16(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %r11,544(%rsp)
+
+ movq %rdx,%r10
+ movq 24(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %r10,%r12
+ adcq $0,%rdx
+ movq %r12,552(%rsp)
+
+ movq %rdx,%r10
+ movq 32(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq 40(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %r10,%r14
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %r10,%r15
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%rsi
+ adcq $0,%rdx
+ addq %r10,%rsi
+ adcq $0,%rdx
+
+ movq %rdx,%r11
+
+
+
+
+ movq 16(%rcx),%rbx
+
+ movq 24(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r13
+ adcq $0,%rdx
+ movq %r13,560(%rsp)
+
+ movq %rdx,%r10
+ movq 32(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %r10,%r14
+ adcq $0,%rdx
+ movq %r14,568(%rsp)
+
+ movq %rdx,%r10
+ movq 40(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %r10,%r15
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%rsi
+ adcq $0,%rdx
+ addq %r10,%rsi
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %r10,%r11
+ adcq $0,%rdx
+
+ movq %rdx,%r12
+
+
+
+
+
+ movq 24(%rcx),%rbx
+
+ movq 32(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ movq %r15,576(%rsp)
+
+ movq %rdx,%r10
+ movq 40(%rcx),%rax
+ mulq %rbx
+ addq %rax,%rsi
+ adcq $0,%rdx
+ addq %r10,%rsi
+ adcq $0,%rdx
+ movq %rsi,584(%rsp)
+
+ movq %rdx,%r10
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %r10,%r11
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %r10,%r12
+ adcq $0,%rdx
+
+ movq %rdx,%r15
+
+
+
+
+ movq 32(%rcx),%rbx
+
+ movq 40(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %r11,592(%rsp)
+
+ movq %rdx,%r10
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %r10,%r12
+ adcq $0,%rdx
+ movq %r12,600(%rsp)
+
+ movq %rdx,%r10
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %r10,%r15
+ adcq $0,%rdx
+
+ movq %rdx,%r11
+
+
+
+
+ movq 40(%rcx),%rbx
+
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ movq %r15,608(%rsp)
+
+ movq %rdx,%r10
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %r10,%r11
+ adcq $0,%rdx
+ movq %r11,616(%rsp)
+
+ movq %rdx,%r12
+
+
+
+
+ movq %r8,%rbx
+
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r12
+ adcq $0,%rdx
+ movq %r12,624(%rsp)
+
+ movq %rdx,632(%rsp)
+
+
+ movq 528(%rsp),%r10
+ movq 536(%rsp),%r11
+ movq 544(%rsp),%r12
+ movq 552(%rsp),%r13
+ movq 560(%rsp),%r14
+ movq 568(%rsp),%r15
+
+ movq 24(%rcx),%rax
+ mulq %rax
+ movq %rax,%rdi
+ movq %rdx,%r8
+
+ addq %r10,%r10
+ adcq %r11,%r11
+ adcq %r12,%r12
+ adcq %r13,%r13
+ adcq %r14,%r14
+ adcq %r15,%r15
+ adcq $0,%r8
+
+ movq 0(%rcx),%rax
+ mulq %rax
+ movq %rax,520(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rcx),%rax
+ mulq %rax
+
+ addq %rbx,%r10
+ adcq %rax,%r11
+ adcq $0,%rdx
+
+ movq %rdx,%rbx
+ movq %r10,528(%rsp)
+ movq %r11,536(%rsp)
+
+ movq 16(%rcx),%rax
+ mulq %rax
+
+ addq %rbx,%r12
+ adcq %rax,%r13
+ adcq $0,%rdx
+
+ movq %rdx,%rbx
+
+ movq %r12,544(%rsp)
+ movq %r13,552(%rsp)
+
+ xorq %rbp,%rbp
+ addq %rbx,%r14
+ adcq %rdi,%r15
+ adcq $0,%rbp
+
+ movq %r14,560(%rsp)
+ movq %r15,568(%rsp)
+
+
+
+
+ movq 576(%rsp),%r10
+ movq 584(%rsp),%r11
+ movq 592(%rsp),%r12
+ movq 600(%rsp),%r13
+ movq 608(%rsp),%r14
+ movq 616(%rsp),%r15
+ movq 624(%rsp),%rdi
+ movq 632(%rsp),%rsi
+
+ movq %r9,%rax
+ mulq %rax
+ movq %rax,%r9
+ movq %rdx,%rbx
+
+ addq %r10,%r10
+ adcq %r11,%r11
+ adcq %r12,%r12
+ adcq %r13,%r13
+ adcq %r14,%r14
+ adcq %r15,%r15
+ adcq %rdi,%rdi
+ adcq %rsi,%rsi
+ adcq $0,%rbx
+
+ addq %rbp,%r10
+
+ movq 32(%rcx),%rax
+ mulq %rax
+
+ addq %r8,%r10
+ adcq %rax,%r11
+ adcq $0,%rdx
+
+ movq %rdx,%rbp
+
+ movq %r10,576(%rsp)
+ movq %r11,584(%rsp)
+
+ movq 40(%rcx),%rax
+ mulq %rax
+
+ addq %rbp,%r12
+ adcq %rax,%r13
+ adcq $0,%rdx
+
+ movq %rdx,%rbp
+
+ movq %r12,592(%rsp)
+ movq %r13,600(%rsp)
+
+ movq 48(%rcx),%rax
+ mulq %rax
+
+ addq %rbp,%r14
+ adcq %rax,%r15
+ adcq $0,%rdx
+
+ movq %r14,608(%rsp)
+ movq %r15,616(%rsp)
+
+ addq %rdx,%rdi
+ adcq %r9,%rsi
+ adcq $0,%rbx
+
+ movq %rdi,624(%rsp)
+ movq %rsi,632(%rsp)
+ movq %rbx,640(%rsp)
+
+ jmp mont_reduce
+
+
+.size sqr_reduce,.-sqr_reduce
+.globl mod_exp_512
+.type mod_exp_512,@function
+mod_exp_512:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+
+ movq %rsp,%r8
+ subq $2688,%rsp
+ andq $-64,%rsp
+
+
+ movq %r8,0(%rsp)
+ movq %rdi,8(%rsp)
+ movq %rsi,16(%rsp)
+ movq %rcx,24(%rsp)
+.Lbody:
+
+
+
+ pxor %xmm4,%xmm4
+ movdqu 0(%rsi),%xmm0
+ movdqu 16(%rsi),%xmm1
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm3
+ movdqa %xmm4,512(%rsp)
+ movdqa %xmm4,528(%rsp)
+ movdqa %xmm4,608(%rsp)
+ movdqa %xmm4,624(%rsp)
+ movdqa %xmm0,544(%rsp)
+ movdqa %xmm1,560(%rsp)
+ movdqa %xmm2,576(%rsp)
+ movdqa %xmm3,592(%rsp)
+
+
+ movdqu 0(%rdx),%xmm0
+ movdqu 16(%rdx),%xmm1
+ movdqu 32(%rdx),%xmm2
+ movdqu 48(%rdx),%xmm3
+
+ leaq 384(%rsp),%rbx
+ movq %rbx,136(%rsp)
+ call mont_reduce
+
+
+ leaq 448(%rsp),%rcx
+ xorq %rax,%rax
+ movq %rax,0(%rcx)
+ movq %rax,8(%rcx)
+ movq %rax,24(%rcx)
+ movq %rax,32(%rcx)
+ movq %rax,40(%rcx)
+ movq %rax,48(%rcx)
+ movq %rax,56(%rcx)
+ movq %rax,128(%rsp)
+ movq $1,16(%rcx)
+
+ leaq 640(%rsp),%rbp
+ movq %rcx,%rsi
+ movq %rbp,%rdi
+ movq $8,%rax
+loop_0:
+ movq (%rcx),%rbx
+ movw %bx,(%rdi)
+ shrq $16,%rbx
+ movw %bx,64(%rdi)
+ shrq $16,%rbx
+ movw %bx,128(%rdi)
+ shrq $16,%rbx
+ movw %bx,192(%rdi)
+ leaq 8(%rcx),%rcx
+ leaq 256(%rdi),%rdi
+ decq %rax
+ jnz loop_0
+ movq $31,%rax
+ movq %rax,32(%rsp)
+ movq %rbp,40(%rsp)
+
+ movq %rsi,136(%rsp)
+ movq 0(%rsi),%r10
+ movq 8(%rsi),%r11
+ movq 16(%rsi),%r12
+ movq 24(%rsi),%r13
+ movq 32(%rsi),%r14
+ movq 40(%rsi),%r15
+ movq 48(%rsi),%r8
+ movq 56(%rsi),%r9
+init_loop:
+ leaq 384(%rsp),%rdi
+ call mont_mul_a3b
+ leaq 448(%rsp),%rsi
+ movq 40(%rsp),%rbp
+ addq $2,%rbp
+ movq %rbp,40(%rsp)
+ movq %rsi,%rcx
+ movq $8,%rax
+loop_1:
+ movq (%rcx),%rbx
+ movw %bx,(%rbp)
+ shrq $16,%rbx
+ movw %bx,64(%rbp)
+ shrq $16,%rbx
+ movw %bx,128(%rbp)
+ shrq $16,%rbx
+ movw %bx,192(%rbp)
+ leaq 8(%rcx),%rcx
+ leaq 256(%rbp),%rbp
+ decq %rax
+ jnz loop_1
+ movq 32(%rsp),%rax
+ subq $1,%rax
+ movq %rax,32(%rsp)
+ jne init_loop
+
+
+
+ movdqa %xmm0,64(%rsp)
+ movdqa %xmm1,80(%rsp)
+ movdqa %xmm2,96(%rsp)
+ movdqa %xmm3,112(%rsp)
+
+
+
+
+
+ movl 126(%rsp),%eax
+ movq %rax,%rdx
+ shrq $11,%rax
+ andl $2047,%edx
+ movl %edx,126(%rsp)
+ leaq 640(%rsp,%rax,2),%rsi
+ movq 8(%rsp),%rdx
+ movq $4,%rbp
+loop_2:
+ movzwq 192(%rsi),%rbx
+ movzwq 448(%rsi),%rax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 128(%rsi),%bx
+ movw 384(%rsi),%ax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 64(%rsi),%bx
+ movw 320(%rsi),%ax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 0(%rsi),%bx
+ movw 256(%rsi),%ax
+ movq %rbx,0(%rdx)
+ movq %rax,8(%rdx)
+ leaq 512(%rsi),%rsi
+ leaq 16(%rdx),%rdx
+ subq $1,%rbp
+ jnz loop_2
+ movq $505,48(%rsp)
+
+ movq 8(%rsp),%rcx
+ movq %rcx,136(%rsp)
+ movq 0(%rcx),%r10
+ movq 8(%rcx),%r11
+ movq 16(%rcx),%r12
+ movq 24(%rcx),%r13
+ movq 32(%rcx),%r14
+ movq 40(%rcx),%r15
+ movq 48(%rcx),%r8
+ movq 56(%rcx),%r9
+ jmp sqr_2
+
+main_loop_a3b:
+ call sqr_reduce
+ call sqr_reduce
+ call sqr_reduce
+sqr_2:
+ call sqr_reduce
+ call sqr_reduce
+
+
+
+ movq 48(%rsp),%rcx
+ movq %rcx,%rax
+ shrq $4,%rax
+ movl 64(%rsp,%rax,2),%edx
+ andq $15,%rcx
+ shrq %cl,%rdx
+ andq $31,%rdx
+
+ leaq 640(%rsp,%rdx,2),%rsi
+ leaq 448(%rsp),%rdx
+ movq %rdx,%rdi
+ movq $4,%rbp
+loop_3:
+ movzwq 192(%rsi),%rbx
+ movzwq 448(%rsi),%rax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 128(%rsi),%bx
+ movw 384(%rsi),%ax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 64(%rsi),%bx
+ movw 320(%rsi),%ax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 0(%rsi),%bx
+ movw 256(%rsi),%ax
+ movq %rbx,0(%rdx)
+ movq %rax,8(%rdx)
+ leaq 512(%rsi),%rsi
+ leaq 16(%rdx),%rdx
+ subq $1,%rbp
+ jnz loop_3
+ movq 8(%rsp),%rsi
+ call mont_mul_a3b
+
+
+
+ movq 48(%rsp),%rcx
+ subq $5,%rcx
+ movq %rcx,48(%rsp)
+ jge main_loop_a3b
+
+
+
+end_main_loop_a3b:
+
+
+ movq 8(%rsp),%rdx
+ pxor %xmm4,%xmm4
+ movdqu 0(%rdx),%xmm0
+ movdqu 16(%rdx),%xmm1
+ movdqu 32(%rdx),%xmm2
+ movdqu 48(%rdx),%xmm3
+ movdqa %xmm4,576(%rsp)
+ movdqa %xmm4,592(%rsp)
+ movdqa %xmm4,608(%rsp)
+ movdqa %xmm4,624(%rsp)
+ movdqa %xmm0,512(%rsp)
+ movdqa %xmm1,528(%rsp)
+ movdqa %xmm2,544(%rsp)
+ movdqa %xmm3,560(%rsp)
+ call mont_reduce
+
+
+
+ movq 8(%rsp),%rax
+ movq 0(%rax),%r8
+ movq 8(%rax),%r9
+ movq 16(%rax),%r10
+ movq 24(%rax),%r11
+ movq 32(%rax),%r12
+ movq 40(%rax),%r13
+ movq 48(%rax),%r14
+ movq 56(%rax),%r15
+
+
+ movq 24(%rsp),%rbx
+ addq $512,%rbx
+
+ subq 0(%rbx),%r8
+ sbbq 8(%rbx),%r9
+ sbbq 16(%rbx),%r10
+ sbbq 24(%rbx),%r11
+ sbbq 32(%rbx),%r12
+ sbbq 40(%rbx),%r13
+ sbbq 48(%rbx),%r14
+ sbbq 56(%rbx),%r15
+
+
+ movq 0(%rax),%rsi
+ movq 8(%rax),%rdi
+ movq 16(%rax),%rcx
+ movq 24(%rax),%rdx
+ cmovncq %r8,%rsi
+ cmovncq %r9,%rdi
+ cmovncq %r10,%rcx
+ cmovncq %r11,%rdx
+ movq %rsi,0(%rax)
+ movq %rdi,8(%rax)
+ movq %rcx,16(%rax)
+ movq %rdx,24(%rax)
+
+ movq 32(%rax),%rsi
+ movq 40(%rax),%rdi
+ movq 48(%rax),%rcx
+ movq 56(%rax),%rdx
+ cmovncq %r12,%rsi
+ cmovncq %r13,%rdi
+ cmovncq %r14,%rcx
+ cmovncq %r15,%rdx
+ movq %rsi,32(%rax)
+ movq %rdi,40(%rax)
+ movq %rcx,48(%rax)
+ movq %rdx,56(%rax)
+
+ movq 0(%rsp),%rsi
+ movq 0(%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbx
+ movq 40(%rsi),%rbp
+ leaq 48(%rsi),%rsp
+.Lepilogue:
+ .byte 0xf3,0xc3
+.size mod_exp_512, . - mod_exp_512
diff --git a/deps/openssl/asm/x64-elf-gas/bn/x86_64-mont.s b/deps/openssl/asm/x64-elf-gas/bn/x86_64-mont.s
index 2dbcffc59..ea12bd408 100644
--- a/deps/openssl/asm/x64-elf-gas/bn/x86_64-mont.s
+++ b/deps/openssl/asm/x64-elf-gas/bn/x86_64-mont.s
@@ -5,6 +5,16 @@
.type bn_mul_mont,@function
.align 16
bn_mul_mont:
+ testl $3,%r9d
+ jnz .Lmul_enter
+ cmpl $8,%r9d
+ jb .Lmul_enter
+ cmpq %rsi,%rdx
+ jne .Lmul4x_enter
+ jmp .Lsqr4x_enter
+
+.align 16
+.Lmul_enter:
pushq %rbx
pushq %rbp
pushq %r12
@@ -20,48 +30,63 @@ bn_mul_mont:
andq $-1024,%rsp
movq %r11,8(%rsp,%r9,8)
-.Lprologue:
+.Lmul_body:
movq %rdx,%r12
-
movq (%r8),%r8
+ movq (%r12),%rbx
+ movq (%rsi),%rax
xorq %r14,%r14
xorq %r15,%r15
- movq (%r12),%rbx
- movq (%rsi),%rax
+ movq %r8,%rbp
mulq %rbx
movq %rax,%r10
- movq %rdx,%r11
+ movq (%rcx),%rax
- imulq %r8,%rax
- movq %rax,%rbp
+ imulq %r10,%rbp
+ movq %rdx,%r11
- mulq (%rcx)
- addq %r10,%rax
+ mulq %rbp
+ addq %rax,%r10
+ movq 8(%rsi),%rax
adcq $0,%rdx
movq %rdx,%r13
leaq 1(%r15),%r15
+ jmp .L1st_enter
+
+.align 16
.L1st:
+ addq %rax,%r13
movq (%rsi,%r15,8),%rax
- mulq %rbx
- addq %r11,%rax
adcq $0,%rdx
- movq %rax,%r10
+ addq %r11,%r13
+ movq %r10,%r11
+ adcq $0,%rdx
+ movq %r13,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+.L1st_enter:
+ mulq %rbx
+ addq %rax,%r11
movq (%rcx,%r15,8),%rax
- movq %rdx,%r11
+ adcq $0,%rdx
+ leaq 1(%r15),%r15
+ movq %rdx,%r10
mulq %rbp
- addq %r13,%rax
- leaq 1(%r15),%r15
+ cmpq %r9,%r15
+ jne .L1st
+
+ addq %rax,%r13
+ movq (%rsi),%rax
adcq $0,%rdx
- addq %r10,%rax
+ addq %r11,%r13
adcq $0,%rdx
- movq %rax,-16(%rsp,%r15,8)
- cmpq %r9,%r15
+ movq %r13,-16(%rsp,%r15,8)
movq %rdx,%r13
- jl .L1st
+ movq %r10,%r11
xorq %rdx,%rdx
addq %r11,%r13
@@ -70,50 +95,64 @@ bn_mul_mont:
movq %rdx,(%rsp,%r9,8)
leaq 1(%r14),%r14
-.align 4
+ jmp .Louter
+.align 16
.Louter:
- xorq %r15,%r15
-
movq (%r12,%r14,8),%rbx
- movq (%rsi),%rax
+ xorq %r15,%r15
+ movq %r8,%rbp
+ movq (%rsp),%r10
mulq %rbx
- addq (%rsp),%rax
+ addq %rax,%r10
+ movq (%rcx),%rax
adcq $0,%rdx
- movq %rax,%r10
- movq %rdx,%r11
- imulq %r8,%rax
- movq %rax,%rbp
+ imulq %r10,%rbp
+ movq %rdx,%r11
- mulq (%rcx,%r15,8)
- addq %r10,%rax
- movq 8(%rsp),%r10
+ mulq %rbp
+ addq %rax,%r10
+ movq 8(%rsi),%rax
adcq $0,%rdx
+ movq 8(%rsp),%r10
movq %rdx,%r13
leaq 1(%r15),%r15
-.align 4
+ jmp .Linner_enter
+
+.align 16
.Linner:
+ addq %rax,%r13
movq (%rsi,%r15,8),%rax
- mulq %rbx
- addq %r11,%rax
adcq $0,%rdx
- addq %rax,%r10
+ addq %r10,%r13
+ movq (%rsp,%r15,8),%r10
+ adcq $0,%rdx
+ movq %r13,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+.Linner_enter:
+ mulq %rbx
+ addq %rax,%r11
movq (%rcx,%r15,8),%rax
adcq $0,%rdx
+ addq %r11,%r10
movq %rdx,%r11
+ adcq $0,%r11
+ leaq 1(%r15),%r15
mulq %rbp
- addq %r13,%rax
- leaq 1(%r15),%r15
- adcq $0,%rdx
- addq %r10,%rax
+ cmpq %r9,%r15
+ jne .Linner
+
+ addq %rax,%r13
+ movq (%rsi),%rax
adcq $0,%rdx
+ addq %r10,%r13
movq (%rsp,%r15,8),%r10
- cmpq %r9,%r15
- movq %rax,-16(%rsp,%r15,8)
+ adcq $0,%rdx
+ movq %r13,-16(%rsp,%r15,8)
movq %rdx,%r13
- jl .Linner
xorq %rdx,%rdx
addq %r11,%r13
@@ -127,35 +166,434 @@ bn_mul_mont:
cmpq %r9,%r14
jl .Louter
- leaq (%rsp),%rsi
- leaq -1(%r9),%r15
-
- movq (%rsi),%rax
xorq %r14,%r14
+ movq (%rsp),%rax
+ leaq (%rsp),%rsi
+ movq %r9,%r15
jmp .Lsub
.align 16
.Lsub: sbbq (%rcx,%r14,8),%rax
movq %rax,(%rdi,%r14,8)
- decq %r15
movq 8(%rsi,%r14,8),%rax
leaq 1(%r14),%r14
- jge .Lsub
+ decq %r15
+ jnz .Lsub
sbbq $0,%rax
+ xorq %r14,%r14
andq %rax,%rsi
notq %rax
movq %rdi,%rcx
andq %rax,%rcx
- leaq -1(%r9),%r15
+ movq %r9,%r15
orq %rcx,%rsi
.align 16
.Lcopy:
+ movq (%rsi,%r14,8),%rax
+ movq %r14,(%rsp,%r14,8)
+ movq %rax,(%rdi,%r14,8)
+ leaq 1(%r14),%r14
+ subq $1,%r15
+ jnz .Lcopy
+
+ movq 8(%rsp,%r9,8),%rsi
+ movq $1,%rax
+ movq (%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+.Lmul_epilogue:
+ .byte 0xf3,0xc3
+.size bn_mul_mont,.-bn_mul_mont
+.type bn_mul4x_mont,@function
+.align 16
+bn_mul4x_mont:
+.Lmul4x_enter:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ movl %r9d,%r9d
+ leaq 4(%r9),%r10
+ movq %rsp,%r11
+ negq %r10
+ leaq (%rsp,%r10,8),%rsp
+ andq $-1024,%rsp
+
+ movq %r11,8(%rsp,%r9,8)
+.Lmul4x_body:
+ movq %rdi,16(%rsp,%r9,8)
+ movq %rdx,%r12
+ movq (%r8),%r8
+ movq (%r12),%rbx
+ movq (%rsi),%rax
+
+ xorq %r14,%r14
+ xorq %r15,%r15
+
+ movq %r8,%rbp
+ mulq %rbx
+ movq %rax,%r10
+ movq (%rcx),%rax
+
+ imulq %r10,%rbp
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r10
+ movq 8(%rsi),%rax
+ adcq $0,%rdx
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq 8(%rcx),%rax
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq 16(%rsi),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ leaq 4(%r15),%r15
+ adcq $0,%rdx
+ movq %rdi,(%rsp)
+ movq %rdx,%r13
+ jmp .L1st4x
+.align 16
+.L1st4x:
+ mulq %rbx
+ addq %rax,%r10
+ movq -16(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq -8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-24(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq -8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq (%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+ mulq %rbx
+ addq %rax,%r10
+ movq (%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq 8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-8(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq 8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ leaq 4(%r15),%r15
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq -16(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-32(%rsp,%r15,8)
+ movq %rdx,%r13
+ cmpq %r9,%r15
+ jl .L1st4x
+
+ mulq %rbx
+ addq %rax,%r10
+ movq -16(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq -8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-24(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq -8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq (%rsi),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+ xorq %rdi,%rdi
+ addq %r10,%r13
+ adcq $0,%rdi
+ movq %r13,-8(%rsp,%r15,8)
+ movq %rdi,(%rsp,%r15,8)
+
+ leaq 1(%r14),%r14
+.align 4
+.Louter4x:
+ movq (%r12,%r14,8),%rbx
+ xorq %r15,%r15
+ movq (%rsp),%r10
+ movq %r8,%rbp
+ mulq %rbx
+ addq %rax,%r10
+ movq (%rcx),%rax
+ adcq $0,%rdx
+
+ imulq %r10,%rbp
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r10
+ movq 8(%rsi),%rax
+ adcq $0,%rdx
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq 8(%rcx),%rax
+ adcq $0,%rdx
+ addq 8(%rsp),%r11
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq 16(%rsi),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ leaq 4(%r15),%r15
+ adcq $0,%rdx
+ movq %rdi,(%rsp)
+ movq %rdx,%r13
+ jmp .Linner4x
+.align 16
+.Linner4x:
+ mulq %rbx
+ addq %rax,%r10
+ movq -16(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq -16(%rsp,%r15,8),%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq -8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-24(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq -8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq -8(%rsp,%r15,8),%r11
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
movq (%rsi,%r15,8),%rax
- movq %rax,(%rdi,%r15,8)
- movq %r14,(%rsp,%r15,8)
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+ mulq %rbx
+ addq %rax,%r10
+ movq (%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq (%rsp,%r15,8),%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq 8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-8(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq 8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq 8(%rsp,%r15,8),%r11
+ adcq $0,%rdx
+ leaq 4(%r15),%r15
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq -16(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-32(%rsp,%r15,8)
+ movq %rdx,%r13
+ cmpq %r9,%r15
+ jl .Linner4x
+
+ mulq %rbx
+ addq %rax,%r10
+ movq -16(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq -16(%rsp,%r15,8),%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq -8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-24(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq -8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq -8(%rsp,%r15,8),%r11
+ adcq $0,%rdx
+ leaq 1(%r14),%r14
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq (%rsi),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+ xorq %rdi,%rdi
+ addq %r10,%r13
+ adcq $0,%rdi
+ addq (%rsp,%r9,8),%r13
+ adcq $0,%rdi
+ movq %r13,-8(%rsp,%r15,8)
+ movq %rdi,(%rsp,%r15,8)
+
+ cmpq %r9,%r14
+ jl .Louter4x
+ movq 16(%rsp,%r9,8),%rdi
+ movq 0(%rsp),%rax
+ pxor %xmm0,%xmm0
+ movq 8(%rsp),%rdx
+ shrq $2,%r9
+ leaq (%rsp),%rsi
+ xorq %r14,%r14
+
+ subq 0(%rcx),%rax
+ movq 16(%rsi),%rbx
+ movq 24(%rsi),%rbp
+ sbbq 8(%rcx),%rdx
+ leaq -1(%r9),%r15
+ jmp .Lsub4x
+.align 16
+.Lsub4x:
+ movq %rax,0(%rdi,%r14,8)
+ movq %rdx,8(%rdi,%r14,8)
+ sbbq 16(%rcx,%r14,8),%rbx
+ movq 32(%rsi,%r14,8),%rax
+ movq 40(%rsi,%r14,8),%rdx
+ sbbq 24(%rcx,%r14,8),%rbp
+ movq %rbx,16(%rdi,%r14,8)
+ movq %rbp,24(%rdi,%r14,8)
+ sbbq 32(%rcx,%r14,8),%rax
+ movq 48(%rsi,%r14,8),%rbx
+ movq 56(%rsi,%r14,8),%rbp
+ sbbq 40(%rcx,%r14,8),%rdx
+ leaq 4(%r14),%r14
+ decq %r15
+ jnz .Lsub4x
+
+ movq %rax,0(%rdi,%r14,8)
+ movq 32(%rsi,%r14,8),%rax
+ sbbq 16(%rcx,%r14,8),%rbx
+ movq %rdx,8(%rdi,%r14,8)
+ sbbq 24(%rcx,%r14,8),%rbp
+ movq %rbx,16(%rdi,%r14,8)
+
+ sbbq $0,%rax
+ movq %rbp,24(%rdi,%r14,8)
+ xorq %r14,%r14
+ andq %rax,%rsi
+ notq %rax
+ movq %rdi,%rcx
+ andq %rax,%rcx
+ leaq -1(%r9),%r15
+ orq %rcx,%rsi
+
+ movdqu (%rsi),%xmm1
+ movdqa %xmm0,(%rsp)
+ movdqu %xmm1,(%rdi)
+ jmp .Lcopy4x
+.align 16
+.Lcopy4x:
+ movdqu 16(%rsi,%r14,1),%xmm2
+ movdqu 32(%rsi,%r14,1),%xmm1
+ movdqa %xmm0,16(%rsp,%r14,1)
+ movdqu %xmm2,16(%rdi,%r14,1)
+ movdqa %xmm0,32(%rsp,%r14,1)
+ movdqu %xmm1,32(%rdi,%r14,1)
+ leaq 32(%r14),%r14
decq %r15
- jge .Lcopy
+ jnz .Lcopy4x
+ shlq $2,%r9
+ movdqu 16(%rsi,%r14,1),%xmm2
+ movdqa %xmm0,16(%rsp,%r14,1)
+ movdqu %xmm2,16(%rdi,%r14,1)
movq 8(%rsp,%r9,8),%rsi
movq $1,%rax
movq (%rsi),%r15
@@ -165,8 +603,773 @@ bn_mul_mont:
movq 32(%rsi),%rbp
movq 40(%rsi),%rbx
leaq 48(%rsi),%rsp
-.Lepilogue:
+.Lmul4x_epilogue:
.byte 0xf3,0xc3
-.size bn_mul_mont,.-bn_mul_mont
+.size bn_mul4x_mont,.-bn_mul4x_mont
+.type bn_sqr4x_mont,@function
+.align 16
+bn_sqr4x_mont:
+.Lsqr4x_enter:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ shll $3,%r9d
+ xorq %r10,%r10
+ movq %rsp,%r11
+ subq %r9,%r10
+ movq (%r8),%r8
+ leaq -72(%rsp,%r10,2),%rsp
+ andq $-1024,%rsp
+
+
+
+
+
+
+
+
+
+
+
+ movq %rdi,32(%rsp)
+ movq %rcx,40(%rsp)
+ movq %r8,48(%rsp)
+ movq %r11,56(%rsp)
+.Lsqr4x_body:
+
+
+
+
+
+
+
+ leaq 32(%r10),%rbp
+ leaq (%rsi,%r9,1),%rsi
+
+ movq %r9,%rcx
+
+
+ movq -32(%rsi,%rbp,1),%r14
+ leaq 64(%rsp,%r9,2),%rdi
+ movq -24(%rsi,%rbp,1),%rax
+ leaq -32(%rdi,%rbp,1),%rdi
+ movq -16(%rsi,%rbp,1),%rbx
+ movq %rax,%r15
+
+ mulq %r14
+ movq %rax,%r10
+ movq %rbx,%rax
+ movq %rdx,%r11
+ movq %r10,-24(%rdi,%rbp,1)
+
+ xorq %r10,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,-16(%rdi,%rbp,1)
+
+ leaq -16(%rbp),%rcx
+
+
+ movq 8(%rsi,%rcx,1),%rbx
+ mulq %r15
+ movq %rax,%r12
+ movq %rbx,%rax
+ movq %rdx,%r13
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ leaq 16(%rcx),%rcx
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-8(%rdi,%rcx,1)
+ jmp .Lsqr4x_1st
+
+.align 16
+.Lsqr4x_1st:
+ movq (%rsi,%rcx,1),%rbx
+ xorq %r12,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %rbx,%rax
+ adcq %rdx,%r12
+
+ xorq %r10,%r10
+ addq %r13,%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,(%rdi,%rcx,1)
+
+
+ movq 8(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,8(%rdi,%rcx,1)
+
+ movq 16(%rsi,%rcx,1),%rbx
+ xorq %r12,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %rbx,%rax
+ adcq %rdx,%r12
+
+ xorq %r10,%r10
+ addq %r13,%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,16(%rdi,%rcx,1)
+
+
+ movq 24(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ leaq 32(%rcx),%rcx
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-8(%rdi,%rcx,1)
+
+ cmpq $0,%rcx
+ jne .Lsqr4x_1st
+
+ xorq %r12,%r12
+ addq %r11,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ adcq %rdx,%r12
+
+ movq %r13,(%rdi)
+ leaq 16(%rbp),%rbp
+ movq %r12,8(%rdi)
+ jmp .Lsqr4x_outer
+
+.align 16
+.Lsqr4x_outer:
+ movq -32(%rsi,%rbp,1),%r14
+ leaq 64(%rsp,%r9,2),%rdi
+ movq -24(%rsi,%rbp,1),%rax
+ leaq -32(%rdi,%rbp,1),%rdi
+ movq -16(%rsi,%rbp,1),%rbx
+ movq %rax,%r15
+
+ movq -24(%rdi,%rbp,1),%r10
+ xorq %r11,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-24(%rdi,%rbp,1)
+
+ xorq %r10,%r10
+ addq -16(%rdi,%rbp,1),%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,-16(%rdi,%rbp,1)
+
+ leaq -16(%rbp),%rcx
+ xorq %r12,%r12
+
+
+ movq 8(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ addq 8(%rdi,%rcx,1),%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,8(%rdi,%rcx,1)
+
+ leaq 16(%rcx),%rcx
+ jmp .Lsqr4x_inner
+
+.align 16
+.Lsqr4x_inner:
+ movq (%rsi,%rcx,1),%rbx
+ xorq %r12,%r12
+ addq (%rdi,%rcx,1),%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %rbx,%rax
+ adcq %rdx,%r12
+
+ xorq %r10,%r10
+ addq %r13,%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,(%rdi,%rcx,1)
+
+ movq 8(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ addq 8(%rdi,%rcx,1),%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ leaq 16(%rcx),%rcx
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-8(%rdi,%rcx,1)
+
+ cmpq $0,%rcx
+ jne .Lsqr4x_inner
+
+ xorq %r12,%r12
+ addq %r11,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ adcq %rdx,%r12
+
+ movq %r13,(%rdi)
+ movq %r12,8(%rdi)
+
+ addq $16,%rbp
+ jnz .Lsqr4x_outer
+
+
+ movq -32(%rsi),%r14
+ leaq 64(%rsp,%r9,2),%rdi
+ movq -24(%rsi),%rax
+ leaq -32(%rdi,%rbp,1),%rdi
+ movq -16(%rsi),%rbx
+ movq %rax,%r15
+
+ xorq %r11,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-24(%rdi)
+
+ xorq %r10,%r10
+ addq %r13,%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,-16(%rdi)
+
+ movq -8(%rsi),%rbx
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq $0,%rdx
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ movq %rdx,%r13
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-8(%rdi)
+
+ xorq %r12,%r12
+ addq %r11,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq -16(%rsi),%rax
+ adcq %rdx,%r12
+
+ movq %r13,(%rdi)
+ movq %r12,8(%rdi)
+
+ mulq %rbx
+ addq $16,%rbp
+ xorq %r14,%r14
+ subq %r9,%rbp
+ xorq %r15,%r15
+
+ addq %r12,%rax
+ adcq $0,%rdx
+ movq %rax,8(%rdi)
+ movq %rdx,16(%rdi)
+ movq %r15,24(%rdi)
+
+ movq -16(%rsi,%rbp,1),%rax
+ leaq 64(%rsp,%r9,2),%rdi
+ xorq %r10,%r10
+ movq -24(%rdi,%rbp,2),%r11
+
+ leaq (%r14,%r10,2),%r12
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r13
+ shrq $63,%r11
+ orq %r10,%r13
+ movq -16(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq -8(%rdi,%rbp,2),%r11
+ adcq %rax,%r12
+ movq -8(%rsi,%rbp,1),%rax
+ movq %r12,-32(%rdi,%rbp,2)
+ adcq %rdx,%r13
+
+ leaq (%r14,%r10,2),%rbx
+ movq %r13,-24(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r8
+ shrq $63,%r11
+ orq %r10,%r8
+ movq 0(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq 8(%rdi,%rbp,2),%r11
+ adcq %rax,%rbx
+ movq 0(%rsi,%rbp,1),%rax
+ movq %rbx,-16(%rdi,%rbp,2)
+ adcq %rdx,%r8
+ leaq 16(%rbp),%rbp
+ movq %r8,-40(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ jmp .Lsqr4x_shift_n_add
+
+.align 16
+.Lsqr4x_shift_n_add:
+ leaq (%r14,%r10,2),%r12
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r13
+ shrq $63,%r11
+ orq %r10,%r13
+ movq -16(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq -8(%rdi,%rbp,2),%r11
+ adcq %rax,%r12
+ movq -8(%rsi,%rbp,1),%rax
+ movq %r12,-32(%rdi,%rbp,2)
+ adcq %rdx,%r13
+
+ leaq (%r14,%r10,2),%rbx
+ movq %r13,-24(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r8
+ shrq $63,%r11
+ orq %r10,%r8
+ movq 0(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq 8(%rdi,%rbp,2),%r11
+ adcq %rax,%rbx
+ movq 0(%rsi,%rbp,1),%rax
+ movq %rbx,-16(%rdi,%rbp,2)
+ adcq %rdx,%r8
+
+ leaq (%r14,%r10,2),%r12
+ movq %r8,-8(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r13
+ shrq $63,%r11
+ orq %r10,%r13
+ movq 16(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq 24(%rdi,%rbp,2),%r11
+ adcq %rax,%r12
+ movq 8(%rsi,%rbp,1),%rax
+ movq %r12,0(%rdi,%rbp,2)
+ adcq %rdx,%r13
+
+ leaq (%r14,%r10,2),%rbx
+ movq %r13,8(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r8
+ shrq $63,%r11
+ orq %r10,%r8
+ movq 32(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq 40(%rdi,%rbp,2),%r11
+ adcq %rax,%rbx
+ movq 16(%rsi,%rbp,1),%rax
+ movq %rbx,16(%rdi,%rbp,2)
+ adcq %rdx,%r8
+ movq %r8,24(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ addq $32,%rbp
+ jnz .Lsqr4x_shift_n_add
+
+ leaq (%r14,%r10,2),%r12
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r13
+ shrq $63,%r11
+ orq %r10,%r13
+ movq -16(%rdi),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq -8(%rdi),%r11
+ adcq %rax,%r12
+ movq -8(%rsi),%rax
+ movq %r12,-32(%rdi)
+ adcq %rdx,%r13
+
+ leaq (%r14,%r10,2),%rbx
+ movq %r13,-24(%rdi)
+ sbbq %r15,%r15
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r8
+ shrq $63,%r11
+ orq %r10,%r8
+ mulq %rax
+ negq %r15
+ adcq %rax,%rbx
+ adcq %rdx,%r8
+ movq %rbx,-16(%rdi)
+ movq %r8,-8(%rdi)
+ movq 40(%rsp),%rsi
+ movq 48(%rsp),%r8
+ xorq %rcx,%rcx
+ movq %r9,0(%rsp)
+ subq %r9,%rcx
+ movq 64(%rsp),%r10
+ movq %r8,%r14
+ leaq 64(%rsp,%r9,2),%rax
+ leaq 64(%rsp,%r9,1),%rdi
+ movq %rax,8(%rsp)
+ leaq (%rsi,%r9,1),%rsi
+ xorq %rbp,%rbp
+
+ movq 0(%rsi,%rcx,1),%rax
+ movq 8(%rsi,%rcx,1),%r9
+ imulq %r10,%r14
+ movq %rax,%rbx
+ jmp .Lsqr4x_mont_outer
+
+.align 16
+.Lsqr4x_mont_outer:
+ xorq %r11,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %r9,%rax
+ adcq %rdx,%r11
+ movq %r8,%r15
+
+ xorq %r10,%r10
+ addq 8(%rdi,%rcx,1),%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+
+ imulq %r11,%r15
+
+ movq 16(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ addq %r11,%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+ movq %r12,8(%rdi,%rcx,1)
+
+ xorq %r11,%r11
+ addq 16(%rdi,%rcx,1),%r10
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %r9,%rax
+ adcq %rdx,%r11
+
+ movq 24(%rsi,%rcx,1),%r9
+ xorq %r12,%r12
+ addq %r10,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %r9,%rax
+ adcq %rdx,%r12
+ movq %r13,16(%rdi,%rcx,1)
+
+ xorq %r10,%r10
+ addq 24(%rdi,%rcx,1),%r11
+ leaq 32(%rcx),%rcx
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ jmp .Lsqr4x_mont_inner
+
+.align 16
+.Lsqr4x_mont_inner:
+ movq (%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ addq %r11,%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+ movq %r12,-8(%rdi,%rcx,1)
+
+ xorq %r11,%r11
+ addq (%rdi,%rcx,1),%r10
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %r9,%rax
+ adcq %rdx,%r11
+
+ movq 8(%rsi,%rcx,1),%r9
+ xorq %r12,%r12
+ addq %r10,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %r9,%rax
+ adcq %rdx,%r12
+ movq %r13,(%rdi,%rcx,1)
+
+ xorq %r10,%r10
+ addq 8(%rdi,%rcx,1),%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+
+
+ movq 16(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ addq %r11,%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+ movq %r12,8(%rdi,%rcx,1)
+
+ xorq %r11,%r11
+ addq 16(%rdi,%rcx,1),%r10
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %r9,%rax
+ adcq %rdx,%r11
+
+ movq 24(%rsi,%rcx,1),%r9
+ xorq %r12,%r12
+ addq %r10,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %r9,%rax
+ adcq %rdx,%r12
+ movq %r13,16(%rdi,%rcx,1)
+
+ xorq %r10,%r10
+ addq 24(%rdi,%rcx,1),%r11
+ leaq 32(%rcx),%rcx
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ cmpq $0,%rcx
+ jne .Lsqr4x_mont_inner
+
+ subq 0(%rsp),%rcx
+ movq %r8,%r14
+
+ xorq %r13,%r13
+ addq %r11,%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %r9,%rax
+ adcq %rdx,%r13
+ movq %r12,-8(%rdi)
+
+ xorq %r11,%r11
+ addq (%rdi),%r10
+ adcq $0,%r11
+ movq 0(%rsi,%rcx,1),%rbx
+ addq %rbp,%r10
+ adcq $0,%r11
+
+ imulq 16(%rdi,%rcx,1),%r14
+ xorq %r12,%r12
+ movq 8(%rsi,%rcx,1),%r9
+ addq %r10,%r13
+ movq 16(%rdi,%rcx,1),%r10
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %rbx,%rax
+ adcq %rdx,%r12
+ movq %r13,(%rdi)
+
+ xorq %rbp,%rbp
+ addq 8(%rdi),%r12
+ adcq %rbp,%rbp
+ addq %r11,%r12
+ leaq 16(%rdi),%rdi
+ adcq $0,%rbp
+ movq %r12,-8(%rdi)
+ cmpq 8(%rsp),%rdi
+ jb .Lsqr4x_mont_outer
+
+ movq 0(%rsp),%r9
+ movq %rbp,(%rdi)
+ movq 64(%rsp,%r9,1),%rax
+ leaq 64(%rsp,%r9,1),%rbx
+ movq 40(%rsp),%rsi
+ shrq $5,%r9
+ movq 8(%rbx),%rdx
+ xorq %rbp,%rbp
+
+ movq 32(%rsp),%rdi
+ subq 0(%rsi),%rax
+ movq 16(%rbx),%r10
+ movq 24(%rbx),%r11
+ sbbq 8(%rsi),%rdx
+ leaq -1(%r9),%rcx
+ jmp .Lsqr4x_sub
+.align 16
+.Lsqr4x_sub:
+ movq %rax,0(%rdi,%rbp,8)
+ movq %rdx,8(%rdi,%rbp,8)
+ sbbq 16(%rsi,%rbp,8),%r10
+ movq 32(%rbx,%rbp,8),%rax
+ movq 40(%rbx,%rbp,8),%rdx
+ sbbq 24(%rsi,%rbp,8),%r11
+ movq %r10,16(%rdi,%rbp,8)
+ movq %r11,24(%rdi,%rbp,8)
+ sbbq 32(%rsi,%rbp,8),%rax
+ movq 48(%rbx,%rbp,8),%r10
+ movq 56(%rbx,%rbp,8),%r11
+ sbbq 40(%rsi,%rbp,8),%rdx
+ leaq 4(%rbp),%rbp
+ decq %rcx
+ jnz .Lsqr4x_sub
+
+ movq %rax,0(%rdi,%rbp,8)
+ movq 32(%rbx,%rbp,8),%rax
+ sbbq 16(%rsi,%rbp,8),%r10
+ movq %rdx,8(%rdi,%rbp,8)
+ sbbq 24(%rsi,%rbp,8),%r11
+ movq %r10,16(%rdi,%rbp,8)
+
+ sbbq $0,%rax
+ movq %r11,24(%rdi,%rbp,8)
+ xorq %rbp,%rbp
+ andq %rax,%rbx
+ notq %rax
+ movq %rdi,%rsi
+ andq %rax,%rsi
+ leaq -1(%r9),%rcx
+ orq %rsi,%rbx
+
+ pxor %xmm0,%xmm0
+ leaq 64(%rsp,%r9,8),%rsi
+ movdqu (%rbx),%xmm1
+ leaq (%rsi,%r9,8),%rsi
+ movdqa %xmm0,64(%rsp)
+ movdqa %xmm0,(%rsi)
+ movdqu %xmm1,(%rdi)
+ jmp .Lsqr4x_copy
+.align 16
+.Lsqr4x_copy:
+ movdqu 16(%rbx,%rbp,1),%xmm2
+ movdqu 32(%rbx,%rbp,1),%xmm1
+ movdqa %xmm0,80(%rsp,%rbp,1)
+ movdqa %xmm0,96(%rsp,%rbp,1)
+ movdqa %xmm0,16(%rsi,%rbp,1)
+ movdqa %xmm0,32(%rsi,%rbp,1)
+ movdqu %xmm2,16(%rdi,%rbp,1)
+ movdqu %xmm1,32(%rdi,%rbp,1)
+ leaq 32(%rbp),%rbp
+ decq %rcx
+ jnz .Lsqr4x_copy
+
+ movdqu 16(%rbx,%rbp,1),%xmm2
+ movdqa %xmm0,80(%rsp,%rbp,1)
+ movdqa %xmm0,16(%rsi,%rbp,1)
+ movdqu %xmm2,16(%rdi,%rbp,1)
+ movq 56(%rsp),%rsi
+ movq $1,%rax
+ movq 0(%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+.Lsqr4x_epilogue:
+ .byte 0xf3,0xc3
+.size bn_sqr4x_mont,.-bn_sqr4x_mont
.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 16
diff --git a/deps/openssl/asm/x64-elf-gas/rc4/rc4-md5-x86_64.s b/deps/openssl/asm/x64-elf-gas/rc4/rc4-md5-x86_64.s
new file mode 100644
index 000000000..501027a80
--- /dev/null
+++ b/deps/openssl/asm/x64-elf-gas/rc4/rc4-md5-x86_64.s
@@ -0,0 +1,1260 @@
+.text
+
+.align 16
+
+.globl rc4_md5_enc
+.type rc4_md5_enc,@function
+rc4_md5_enc:
+ cmpq $0,%r9
+ je .Labort
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $40,%rsp
+.Lbody:
+ movq %rcx,%r11
+ movq %r9,%r12
+ movq %rsi,%r13
+ movq %rdx,%r14
+ movq %r8,%r15
+ xorq %rbp,%rbp
+ xorq %rcx,%rcx
+
+ leaq 8(%rdi),%rdi
+ movb -8(%rdi),%bpl
+ movb -4(%rdi),%cl
+
+ incb %bpl
+ subq %r13,%r14
+ movl (%rdi,%rbp,4),%eax
+ addb %al,%cl
+ leaq (%rdi,%rbp,4),%rsi
+ shlq $6,%r12
+ addq %r15,%r12
+ movq %r12,16(%rsp)
+
+ movq %r11,24(%rsp)
+ movl 0(%r11),%r8d
+ movl 4(%r11),%r9d
+ movl 8(%r11),%r10d
+ movl 12(%r11),%r11d
+ jmp .Loop
+
+.align 16
+.Loop:
+ movl %r8d,0(%rsp)
+ movl %r9d,4(%rsp)
+ movl %r10d,8(%rsp)
+ movl %r11d,%r12d
+ movl %r11d,12(%rsp)
+ pxor %xmm0,%xmm0
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 0(%r15),%r8d
+ addb %dl,%al
+ movl 4(%rsi),%ebx
+ addl $3614090360,%r8d
+ xorl %r11d,%r12d
+ movzbl %al,%eax
+ movl %edx,0(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $7,%r8d
+ movl %r10d,%r12d
+ movd (%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ pxor %xmm1,%xmm1
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 4(%r15),%r11d
+ addb %dl,%bl
+ movl 8(%rsi),%eax
+ addl $3905402710,%r11d
+ xorl %r10d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,4(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $12,%r11d
+ movl %r9d,%r12d
+ movd (%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 8(%r15),%r10d
+ addb %dl,%al
+ movl 12(%rsi),%ebx
+ addl $606105819,%r10d
+ xorl %r9d,%r12d
+ movzbl %al,%eax
+ movl %edx,8(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $17,%r10d
+ movl %r8d,%r12d
+ pinsrw $1,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 12(%r15),%r9d
+ addb %dl,%bl
+ movl 16(%rsi),%eax
+ addl $3250441966,%r9d
+ xorl %r8d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,12(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $22,%r9d
+ movl %r11d,%r12d
+ pinsrw $1,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 16(%r15),%r8d
+ addb %dl,%al
+ movl 20(%rsi),%ebx
+ addl $4118548399,%r8d
+ xorl %r11d,%r12d
+ movzbl %al,%eax
+ movl %edx,16(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $7,%r8d
+ movl %r10d,%r12d
+ pinsrw $2,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 20(%r15),%r11d
+ addb %dl,%bl
+ movl 24(%rsi),%eax
+ addl $1200080426,%r11d
+ xorl %r10d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,20(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $12,%r11d
+ movl %r9d,%r12d
+ pinsrw $2,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 24(%r15),%r10d
+ addb %dl,%al
+ movl 28(%rsi),%ebx
+ addl $2821735955,%r10d
+ xorl %r9d,%r12d
+ movzbl %al,%eax
+ movl %edx,24(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $17,%r10d
+ movl %r8d,%r12d
+ pinsrw $3,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 28(%r15),%r9d
+ addb %dl,%bl
+ movl 32(%rsi),%eax
+ addl $4249261313,%r9d
+ xorl %r8d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,28(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $22,%r9d
+ movl %r11d,%r12d
+ pinsrw $3,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 32(%r15),%r8d
+ addb %dl,%al
+ movl 36(%rsi),%ebx
+ addl $1770035416,%r8d
+ xorl %r11d,%r12d
+ movzbl %al,%eax
+ movl %edx,32(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $7,%r8d
+ movl %r10d,%r12d
+ pinsrw $4,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 36(%r15),%r11d
+ addb %dl,%bl
+ movl 40(%rsi),%eax
+ addl $2336552879,%r11d
+ xorl %r10d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,36(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $12,%r11d
+ movl %r9d,%r12d
+ pinsrw $4,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 40(%r15),%r10d
+ addb %dl,%al
+ movl 44(%rsi),%ebx
+ addl $4294925233,%r10d
+ xorl %r9d,%r12d
+ movzbl %al,%eax
+ movl %edx,40(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $17,%r10d
+ movl %r8d,%r12d
+ pinsrw $5,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 44(%r15),%r9d
+ addb %dl,%bl
+ movl 48(%rsi),%eax
+ addl $2304563134,%r9d
+ xorl %r8d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,44(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $22,%r9d
+ movl %r11d,%r12d
+ pinsrw $5,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 48(%r15),%r8d
+ addb %dl,%al
+ movl 52(%rsi),%ebx
+ addl $1804603682,%r8d
+ xorl %r11d,%r12d
+ movzbl %al,%eax
+ movl %edx,48(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $7,%r8d
+ movl %r10d,%r12d
+ pinsrw $6,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 52(%r15),%r11d
+ addb %dl,%bl
+ movl 56(%rsi),%eax
+ addl $4254626195,%r11d
+ xorl %r10d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,52(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $12,%r11d
+ movl %r9d,%r12d
+ pinsrw $6,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 56(%r15),%r10d
+ addb %dl,%al
+ movl 60(%rsi),%ebx
+ addl $2792965006,%r10d
+ xorl %r9d,%r12d
+ movzbl %al,%eax
+ movl %edx,56(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $17,%r10d
+ movl %r8d,%r12d
+ pinsrw $7,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movdqu (%r13),%xmm2
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 60(%r15),%r9d
+ addb %dl,%bl
+ movl 64(%rsi),%eax
+ addl $1236535329,%r9d
+ xorl %r8d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,60(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $22,%r9d
+ movl %r10d,%r12d
+ pinsrw $7,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm2
+ pxor %xmm1,%xmm2
+ pxor %xmm0,%xmm0
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 4(%r15),%r8d
+ addb %dl,%al
+ movl 68(%rsi),%ebx
+ addl $4129170786,%r8d
+ xorl %r10d,%r12d
+ movzbl %al,%eax
+ movl %edx,64(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $5,%r8d
+ movl %r9d,%r12d
+ movd (%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ pxor %xmm1,%xmm1
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 24(%r15),%r11d
+ addb %dl,%bl
+ movl 72(%rsi),%eax
+ addl $3225465664,%r11d
+ xorl %r9d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,68(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $9,%r11d
+ movl %r8d,%r12d
+ movd (%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 44(%r15),%r10d
+ addb %dl,%al
+ movl 76(%rsi),%ebx
+ addl $643717713,%r10d
+ xorl %r8d,%r12d
+ movzbl %al,%eax
+ movl %edx,72(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $14,%r10d
+ movl %r11d,%r12d
+ pinsrw $1,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 0(%r15),%r9d
+ addb %dl,%bl
+ movl 80(%rsi),%eax
+ addl $3921069994,%r9d
+ xorl %r11d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,76(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $20,%r9d
+ movl %r10d,%r12d
+ pinsrw $1,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 20(%r15),%r8d
+ addb %dl,%al
+ movl 84(%rsi),%ebx
+ addl $3593408605,%r8d
+ xorl %r10d,%r12d
+ movzbl %al,%eax
+ movl %edx,80(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $5,%r8d
+ movl %r9d,%r12d
+ pinsrw $2,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 40(%r15),%r11d
+ addb %dl,%bl
+ movl 88(%rsi),%eax
+ addl $38016083,%r11d
+ xorl %r9d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,84(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $9,%r11d
+ movl %r8d,%r12d
+ pinsrw $2,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 60(%r15),%r10d
+ addb %dl,%al
+ movl 92(%rsi),%ebx
+ addl $3634488961,%r10d
+ xorl %r8d,%r12d
+ movzbl %al,%eax
+ movl %edx,88(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $14,%r10d
+ movl %r11d,%r12d
+ pinsrw $3,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 16(%r15),%r9d
+ addb %dl,%bl
+ movl 96(%rsi),%eax
+ addl $3889429448,%r9d
+ xorl %r11d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,92(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $20,%r9d
+ movl %r10d,%r12d
+ pinsrw $3,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 36(%r15),%r8d
+ addb %dl,%al
+ movl 100(%rsi),%ebx
+ addl $568446438,%r8d
+ xorl %r10d,%r12d
+ movzbl %al,%eax
+ movl %edx,96(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $5,%r8d
+ movl %r9d,%r12d
+ pinsrw $4,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 56(%r15),%r11d
+ addb %dl,%bl
+ movl 104(%rsi),%eax
+ addl $3275163606,%r11d
+ xorl %r9d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,100(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $9,%r11d
+ movl %r8d,%r12d
+ pinsrw $4,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 12(%r15),%r10d
+ addb %dl,%al
+ movl 108(%rsi),%ebx
+ addl $4107603335,%r10d
+ xorl %r8d,%r12d
+ movzbl %al,%eax
+ movl %edx,104(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $14,%r10d
+ movl %r11d,%r12d
+ pinsrw $5,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 32(%r15),%r9d
+ addb %dl,%bl
+ movl 112(%rsi),%eax
+ addl $1163531501,%r9d
+ xorl %r11d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,108(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $20,%r9d
+ movl %r10d,%r12d
+ pinsrw $5,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 52(%r15),%r8d
+ addb %dl,%al
+ movl 116(%rsi),%ebx
+ addl $2850285829,%r8d
+ xorl %r10d,%r12d
+ movzbl %al,%eax
+ movl %edx,112(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $5,%r8d
+ movl %r9d,%r12d
+ pinsrw $6,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 8(%r15),%r11d
+ addb %dl,%bl
+ movl 120(%rsi),%eax
+ addl $4243563512,%r11d
+ xorl %r9d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,116(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $9,%r11d
+ movl %r8d,%r12d
+ pinsrw $6,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 28(%r15),%r10d
+ addb %dl,%al
+ movl 124(%rsi),%ebx
+ addl $1735328473,%r10d
+ xorl %r8d,%r12d
+ movzbl %al,%eax
+ movl %edx,120(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $14,%r10d
+ movl %r11d,%r12d
+ pinsrw $7,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movdqu 16(%r13),%xmm3
+ addb $32,%bpl
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 48(%r15),%r9d
+ addb %dl,%bl
+ movl 0(%rdi,%rbp,4),%eax
+ addl $2368359562,%r9d
+ xorl %r11d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,124(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $20,%r9d
+ movl %r11d,%r12d
+ pinsrw $7,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movq %rcx,%rsi
+ xorq %rcx,%rcx
+ movb %sil,%cl
+ leaq (%rdi,%rbp,4),%rsi
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm3
+ pxor %xmm1,%xmm3
+ pxor %xmm0,%xmm0
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r9d,%r12d
+ addl 20(%r15),%r8d
+ addb %dl,%al
+ movl 4(%rsi),%ebx
+ addl $4294588738,%r8d
+ movzbl %al,%eax
+ addl %r12d,%r8d
+ movl %edx,0(%rsi)
+ addb %bl,%cl
+ roll $4,%r8d
+ movl %r10d,%r12d
+ movd (%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ pxor %xmm1,%xmm1
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r8d,%r12d
+ addl 32(%r15),%r11d
+ addb %dl,%bl
+ movl 8(%rsi),%eax
+ addl $2272392833,%r11d
+ movzbl %bl,%ebx
+ addl %r12d,%r11d
+ movl %edx,4(%rsi)
+ addb %al,%cl
+ roll $11,%r11d
+ movl %r9d,%r12d
+ movd (%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r11d,%r12d
+ addl 44(%r15),%r10d
+ addb %dl,%al
+ movl 12(%rsi),%ebx
+ addl $1839030562,%r10d
+ movzbl %al,%eax
+ addl %r12d,%r10d
+ movl %edx,8(%rsi)
+ addb %bl,%cl
+ roll $16,%r10d
+ movl %r8d,%r12d
+ pinsrw $1,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r10d,%r12d
+ addl 56(%r15),%r9d
+ addb %dl,%bl
+ movl 16(%rsi),%eax
+ addl $4259657740,%r9d
+ movzbl %bl,%ebx
+ addl %r12d,%r9d
+ movl %edx,12(%rsi)
+ addb %al,%cl
+ roll $23,%r9d
+ movl %r11d,%r12d
+ pinsrw $1,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r9d,%r12d
+ addl 4(%r15),%r8d
+ addb %dl,%al
+ movl 20(%rsi),%ebx
+ addl $2763975236,%r8d
+ movzbl %al,%eax
+ addl %r12d,%r8d
+ movl %edx,16(%rsi)
+ addb %bl,%cl
+ roll $4,%r8d
+ movl %r10d,%r12d
+ pinsrw $2,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r8d,%r12d
+ addl 16(%r15),%r11d
+ addb %dl,%bl
+ movl 24(%rsi),%eax
+ addl $1272893353,%r11d
+ movzbl %bl,%ebx
+ addl %r12d,%r11d
+ movl %edx,20(%rsi)
+ addb %al,%cl
+ roll $11,%r11d
+ movl %r9d,%r12d
+ pinsrw $2,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r11d,%r12d
+ addl 28(%r15),%r10d
+ addb %dl,%al
+ movl 28(%rsi),%ebx
+ addl $4139469664,%r10d
+ movzbl %al,%eax
+ addl %r12d,%r10d
+ movl %edx,24(%rsi)
+ addb %bl,%cl
+ roll $16,%r10d
+ movl %r8d,%r12d
+ pinsrw $3,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r10d,%r12d
+ addl 40(%r15),%r9d
+ addb %dl,%bl
+ movl 32(%rsi),%eax
+ addl $3200236656,%r9d
+ movzbl %bl,%ebx
+ addl %r12d,%r9d
+ movl %edx,28(%rsi)
+ addb %al,%cl
+ roll $23,%r9d
+ movl %r11d,%r12d
+ pinsrw $3,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r9d,%r12d
+ addl 52(%r15),%r8d
+ addb %dl,%al
+ movl 36(%rsi),%ebx
+ addl $681279174,%r8d
+ movzbl %al,%eax
+ addl %r12d,%r8d
+ movl %edx,32(%rsi)
+ addb %bl,%cl
+ roll $4,%r8d
+ movl %r10d,%r12d
+ pinsrw $4,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r8d,%r12d
+ addl 0(%r15),%r11d
+ addb %dl,%bl
+ movl 40(%rsi),%eax
+ addl $3936430074,%r11d
+ movzbl %bl,%ebx
+ addl %r12d,%r11d
+ movl %edx,36(%rsi)
+ addb %al,%cl
+ roll $11,%r11d
+ movl %r9d,%r12d
+ pinsrw $4,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r11d,%r12d
+ addl 12(%r15),%r10d
+ addb %dl,%al
+ movl 44(%rsi),%ebx
+ addl $3572445317,%r10d
+ movzbl %al,%eax
+ addl %r12d,%r10d
+ movl %edx,40(%rsi)
+ addb %bl,%cl
+ roll $16,%r10d
+ movl %r8d,%r12d
+ pinsrw $5,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r10d,%r12d
+ addl 24(%r15),%r9d
+ addb %dl,%bl
+ movl 48(%rsi),%eax
+ addl $76029189,%r9d
+ movzbl %bl,%ebx
+ addl %r12d,%r9d
+ movl %edx,44(%rsi)
+ addb %al,%cl
+ roll $23,%r9d
+ movl %r11d,%r12d
+ pinsrw $5,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r9d,%r12d
+ addl 36(%r15),%r8d
+ addb %dl,%al
+ movl 52(%rsi),%ebx
+ addl $3654602809,%r8d
+ movzbl %al,%eax
+ addl %r12d,%r8d
+ movl %edx,48(%rsi)
+ addb %bl,%cl
+ roll $4,%r8d
+ movl %r10d,%r12d
+ pinsrw $6,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r8d,%r12d
+ addl 48(%r15),%r11d
+ addb %dl,%bl
+ movl 56(%rsi),%eax
+ addl $3873151461,%r11d
+ movzbl %bl,%ebx
+ addl %r12d,%r11d
+ movl %edx,52(%rsi)
+ addb %al,%cl
+ roll $11,%r11d
+ movl %r9d,%r12d
+ pinsrw $6,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r11d,%r12d
+ addl 60(%r15),%r10d
+ addb %dl,%al
+ movl 60(%rsi),%ebx
+ addl $530742520,%r10d
+ movzbl %al,%eax
+ addl %r12d,%r10d
+ movl %edx,56(%rsi)
+ addb %bl,%cl
+ roll $16,%r10d
+ movl %r8d,%r12d
+ pinsrw $7,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movdqu 32(%r13),%xmm4
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r10d,%r12d
+ addl 8(%r15),%r9d
+ addb %dl,%bl
+ movl 64(%rsi),%eax
+ addl $3299628645,%r9d
+ movzbl %bl,%ebx
+ addl %r12d,%r9d
+ movl %edx,60(%rsi)
+ addb %al,%cl
+ roll $23,%r9d
+ movl $-1,%r12d
+ pinsrw $7,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm4
+ pxor %xmm1,%xmm4
+ pxor %xmm0,%xmm0
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r9d,%r12d
+ addl 0(%r15),%r8d
+ addb %dl,%al
+ movl 68(%rsi),%ebx
+ addl $4096336452,%r8d
+ movzbl %al,%eax
+ xorl %r10d,%r12d
+ movl %edx,64(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $6,%r8d
+ movl $-1,%r12d
+ movd (%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ pxor %xmm1,%xmm1
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r8d,%r12d
+ addl 28(%r15),%r11d
+ addb %dl,%bl
+ movl 72(%rsi),%eax
+ addl $1126891415,%r11d
+ movzbl %bl,%ebx
+ xorl %r9d,%r12d
+ movl %edx,68(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $10,%r11d
+ movl $-1,%r12d
+ movd (%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r11d,%r12d
+ addl 56(%r15),%r10d
+ addb %dl,%al
+ movl 76(%rsi),%ebx
+ addl $2878612391,%r10d
+ movzbl %al,%eax
+ xorl %r8d,%r12d
+ movl %edx,72(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $15,%r10d
+ movl $-1,%r12d
+ pinsrw $1,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r10d,%r12d
+ addl 20(%r15),%r9d
+ addb %dl,%bl
+ movl 80(%rsi),%eax
+ addl $4237533241,%r9d
+ movzbl %bl,%ebx
+ xorl %r11d,%r12d
+ movl %edx,76(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $21,%r9d
+ movl $-1,%r12d
+ pinsrw $1,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r9d,%r12d
+ addl 48(%r15),%r8d
+ addb %dl,%al
+ movl 84(%rsi),%ebx
+ addl $1700485571,%r8d
+ movzbl %al,%eax
+ xorl %r10d,%r12d
+ movl %edx,80(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $6,%r8d
+ movl $-1,%r12d
+ pinsrw $2,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r8d,%r12d
+ addl 12(%r15),%r11d
+ addb %dl,%bl
+ movl 88(%rsi),%eax
+ addl $2399980690,%r11d
+ movzbl %bl,%ebx
+ xorl %r9d,%r12d
+ movl %edx,84(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $10,%r11d
+ movl $-1,%r12d
+ pinsrw $2,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r11d,%r12d
+ addl 40(%r15),%r10d
+ addb %dl,%al
+ movl 92(%rsi),%ebx
+ addl $4293915773,%r10d
+ movzbl %al,%eax
+ xorl %r8d,%r12d
+ movl %edx,88(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $15,%r10d
+ movl $-1,%r12d
+ pinsrw $3,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r10d,%r12d
+ addl 4(%r15),%r9d
+ addb %dl,%bl
+ movl 96(%rsi),%eax
+ addl $2240044497,%r9d
+ movzbl %bl,%ebx
+ xorl %r11d,%r12d
+ movl %edx,92(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $21,%r9d
+ movl $-1,%r12d
+ pinsrw $3,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r9d,%r12d
+ addl 32(%r15),%r8d
+ addb %dl,%al
+ movl 100(%rsi),%ebx
+ addl $1873313359,%r8d
+ movzbl %al,%eax
+ xorl %r10d,%r12d
+ movl %edx,96(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $6,%r8d
+ movl $-1,%r12d
+ pinsrw $4,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r8d,%r12d
+ addl 60(%r15),%r11d
+ addb %dl,%bl
+ movl 104(%rsi),%eax
+ addl $4264355552,%r11d
+ movzbl %bl,%ebx
+ xorl %r9d,%r12d
+ movl %edx,100(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $10,%r11d
+ movl $-1,%r12d
+ pinsrw $4,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r11d,%r12d
+ addl 24(%r15),%r10d
+ addb %dl,%al
+ movl 108(%rsi),%ebx
+ addl $2734768916,%r10d
+ movzbl %al,%eax
+ xorl %r8d,%r12d
+ movl %edx,104(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $15,%r10d
+ movl $-1,%r12d
+ pinsrw $5,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r10d,%r12d
+ addl 52(%r15),%r9d
+ addb %dl,%bl
+ movl 112(%rsi),%eax
+ addl $1309151649,%r9d
+ movzbl %bl,%ebx
+ xorl %r11d,%r12d
+ movl %edx,108(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $21,%r9d
+ movl $-1,%r12d
+ pinsrw $5,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r9d,%r12d
+ addl 16(%r15),%r8d
+ addb %dl,%al
+ movl 116(%rsi),%ebx
+ addl $4149444226,%r8d
+ movzbl %al,%eax
+ xorl %r10d,%r12d
+ movl %edx,112(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $6,%r8d
+ movl $-1,%r12d
+ pinsrw $6,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r8d,%r12d
+ addl 44(%r15),%r11d
+ addb %dl,%bl
+ movl 120(%rsi),%eax
+ addl $3174756917,%r11d
+ movzbl %bl,%ebx
+ xorl %r9d,%r12d
+ movl %edx,116(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $10,%r11d
+ movl $-1,%r12d
+ pinsrw $6,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r11d,%r12d
+ addl 8(%r15),%r10d
+ addb %dl,%al
+ movl 124(%rsi),%ebx
+ addl $718787259,%r10d
+ movzbl %al,%eax
+ xorl %r8d,%r12d
+ movl %edx,120(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $15,%r10d
+ movl $-1,%r12d
+ pinsrw $7,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movdqu 48(%r13),%xmm5
+ addb $32,%bpl
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r10d,%r12d
+ addl 36(%r15),%r9d
+ addb %dl,%bl
+ movl 0(%rdi,%rbp,4),%eax
+ addl $3951481745,%r9d
+ movzbl %bl,%ebx
+ xorl %r11d,%r12d
+ movl %edx,124(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $21,%r9d
+ movl $-1,%r12d
+ pinsrw $7,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movq %rbp,%rsi
+ xorq %rbp,%rbp
+ movb %sil,%bpl
+ movq %rcx,%rsi
+ xorq %rcx,%rcx
+ movb %sil,%cl
+ leaq (%rdi,%rbp,4),%rsi
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm5
+ pxor %xmm1,%xmm5
+ addl 0(%rsp),%r8d
+ addl 4(%rsp),%r9d
+ addl 8(%rsp),%r10d
+ addl 12(%rsp),%r11d
+
+ movdqu %xmm2,(%r14,%r13,1)
+ movdqu %xmm3,16(%r14,%r13,1)
+ movdqu %xmm4,32(%r14,%r13,1)
+ movdqu %xmm5,48(%r14,%r13,1)
+ leaq 64(%r15),%r15
+ leaq 64(%r13),%r13
+ cmpq 16(%rsp),%r15
+ jb .Loop
+
+ movq 24(%rsp),%r12
+ subb %al,%cl
+ movl %r8d,0(%r12)
+ movl %r9d,4(%r12)
+ movl %r10d,8(%r12)
+ movl %r11d,12(%r12)
+ subb $1,%bpl
+ movl %ebp,-8(%rdi)
+ movl %ecx,-4(%rdi)
+
+ movq 40(%rsp),%r15
+ movq 48(%rsp),%r14
+ movq 56(%rsp),%r13
+ movq 64(%rsp),%r12
+ movq 72(%rsp),%rbp
+ movq 80(%rsp),%rbx
+ leaq 88(%rsp),%rsp
+.Lepilogue:
+.Labort:
+ .byte 0xf3,0xc3
+.size rc4_md5_enc,.-rc4_md5_enc
diff --git a/deps/openssl/asm/x64-elf-gas/rc4/rc4-x86_64.s b/deps/openssl/asm/x64-elf-gas/rc4/rc4-x86_64.s
index 1bafefeb0..f2b8a8bc0 100644
--- a/deps/openssl/asm/x64-elf-gas/rc4/rc4-x86_64.s
+++ b/deps/openssl/asm/x64-elf-gas/rc4/rc4-x86_64.s
@@ -1,6 +1,7 @@
.text
+
.globl RC4
.type RC4,@function
.align 16
@@ -12,316 +13,511 @@ RC4: orq %rsi,%rsi
pushq %r12
pushq %r13
.Lprologue:
+ movq %rsi,%r11
+ movq %rdx,%r12
+ movq %rcx,%r13
+ xorq %r10,%r10
+ xorq %rcx,%rcx
- addq $8,%rdi
- movl -8(%rdi),%r8d
- movl -4(%rdi),%r12d
+ leaq 8(%rdi),%rdi
+ movb -8(%rdi),%r10b
+ movb -4(%rdi),%cl
cmpl $-1,256(%rdi)
je .LRC4_CHAR
- incb %r8b
- movl (%rdi,%r8,4),%r9d
- testq $-8,%rsi
- jz .Lloop1
- jmp .Lloop8
-.align 16
-.Lloop8:
- addb %r9b,%r12b
- movq %r8,%r10
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
- incb %r10b
- movl (%rdi,%r10,4),%r11d
- cmpq %r10,%r12
- movl %r9d,(%rdi,%r12,4)
- cmoveq %r9,%r11
- movl %r13d,(%rdi,%r8,4)
- addb %r9b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r11b,%r12b
- movq %r10,%r8
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
- incb %r8b
- movl (%rdi,%r8,4),%r9d
- cmpq %r8,%r12
- movl %r11d,(%rdi,%r12,4)
- cmoveq %r11,%r9
- movl %r13d,(%rdi,%r10,4)
- addb %r11b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r9b,%r12b
- movq %r8,%r10
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
+ movl OPENSSL_ia32cap_P(%rip),%r8d
+ xorq %rbx,%rbx
incb %r10b
- movl (%rdi,%r10,4),%r11d
- cmpq %r10,%r12
- movl %r9d,(%rdi,%r12,4)
- cmoveq %r9,%r11
- movl %r13d,(%rdi,%r8,4)
- addb %r9b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r11b,%r12b
- movq %r10,%r8
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
- incb %r8b
- movl (%rdi,%r8,4),%r9d
- cmpq %r8,%r12
- movl %r11d,(%rdi,%r12,4)
- cmoveq %r11,%r9
- movl %r13d,(%rdi,%r10,4)
- addb %r11b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r9b,%r12b
- movq %r8,%r10
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
+ subq %r10,%rbx
+ subq %r12,%r13
+ movl (%rdi,%r10,4),%eax
+ testq $-16,%r11
+ jz .Lloop1
+ btl $30,%r8d
+ jc .Lintel
+ andq $7,%rbx
+ leaq 1(%r10),%rsi
+ jz .Loop8
+ subq %rbx,%r11
+.Loop8_warmup:
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl %edx,(%rdi,%r10,4)
+ addb %dl,%al
incb %r10b
- movl (%rdi,%r10,4),%r11d
- cmpq %r10,%r12
- movl %r9d,(%rdi,%r12,4)
- cmoveq %r9,%r11
- movl %r13d,(%rdi,%r8,4)
- addb %r9b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r11b,%r12b
- movq %r10,%r8
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
- incb %r8b
- movl (%rdi,%r8,4),%r9d
- cmpq %r8,%r12
- movl %r11d,(%rdi,%r12,4)
- cmoveq %r11,%r9
- movl %r13d,(%rdi,%r10,4)
- addb %r11b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r9b,%r12b
- movq %r8,%r10
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
+ movl (%rdi,%rax,4),%edx
+ movl (%rdi,%r10,4),%eax
+ xorb (%r12),%dl
+ movb %dl,(%r13,%r12,1)
+ leaq 1(%r12),%r12
+ decq %rbx
+ jnz .Loop8_warmup
+
+ leaq 1(%r10),%rsi
+ jmp .Loop8
+.align 16
+.Loop8:
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl 0(%rdi,%rsi,4),%ebx
+ rorq $8,%r8
+ movl %edx,0(%rdi,%r10,4)
+ addb %al,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %bl,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ movl 4(%rdi,%rsi,4),%eax
+ rorq $8,%r8
+ movl %edx,4(%rdi,%r10,4)
+ addb %bl,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl 8(%rdi,%rsi,4),%ebx
+ rorq $8,%r8
+ movl %edx,8(%rdi,%r10,4)
+ addb %al,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %bl,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ movl 12(%rdi,%rsi,4),%eax
+ rorq $8,%r8
+ movl %edx,12(%rdi,%r10,4)
+ addb %bl,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl 16(%rdi,%rsi,4),%ebx
+ rorq $8,%r8
+ movl %edx,16(%rdi,%r10,4)
+ addb %al,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %bl,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ movl 20(%rdi,%rsi,4),%eax
+ rorq $8,%r8
+ movl %edx,20(%rdi,%r10,4)
+ addb %bl,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl 24(%rdi,%rsi,4),%ebx
+ rorq $8,%r8
+ movl %edx,24(%rdi,%r10,4)
+ addb %al,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb $8,%sil
+ addb %bl,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ movl -4(%rdi,%rsi,4),%eax
+ rorq $8,%r8
+ movl %edx,28(%rdi,%r10,4)
+ addb %bl,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb $8,%r10b
+ rorq $8,%r8
+ subq $8,%r11
+
+ xorq (%r12),%r8
+ movq %r8,(%r13,%r12,1)
+ leaq 8(%r12),%r12
+
+ testq $-8,%r11
+ jnz .Loop8
+ cmpq $0,%r11
+ jne .Lloop1
+ jmp .Lexit
+
+.align 16
+.Lintel:
+ testq $-32,%r11
+ jz .Lloop1
+ andq $15,%rbx
+ jz .Loop16_is_hot
+ subq %rbx,%r11
+.Loop16_warmup:
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl %edx,(%rdi,%r10,4)
+ addb %dl,%al
incb %r10b
- movl (%rdi,%r10,4),%r11d
- cmpq %r10,%r12
- movl %r9d,(%rdi,%r12,4)
- cmoveq %r9,%r11
- movl %r13d,(%rdi,%r8,4)
- addb %r9b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r11b,%r12b
- movq %r10,%r8
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
- incb %r8b
- movl (%rdi,%r8,4),%r9d
- cmpq %r8,%r12
- movl %r11d,(%rdi,%r12,4)
- cmoveq %r11,%r9
- movl %r13d,(%rdi,%r10,4)
- addb %r11b,%r13b
- movb (%rdi,%r13,4),%al
- rorq $8,%rax
- subq $8,%rsi
-
- xorq (%rdx),%rax
- addq $8,%rdx
- movq %rax,(%rcx)
- addq $8,%rcx
-
- testq $-8,%rsi
- jnz .Lloop8
- cmpq $0,%rsi
+ movl (%rdi,%rax,4),%edx
+ movl (%rdi,%r10,4),%eax
+ xorb (%r12),%dl
+ movb %dl,(%r13,%r12,1)
+ leaq 1(%r12),%r12
+ decq %rbx
+ jnz .Loop16_warmup
+
+ movq %rcx,%rbx
+ xorq %rcx,%rcx
+ movb %bl,%cl
+
+.Loop16_is_hot:
+ leaq (%rdi,%r10,4),%rsi
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ pxor %xmm0,%xmm0
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 4(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,0(%rsi)
+ addb %bl,%cl
+ pinsrw $0,(%rdi,%rax,4),%xmm0
+ jmp .Loop16_enter
+.align 16
+.Loop16:
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ pxor %xmm0,%xmm2
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm0
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 4(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,0(%rsi)
+ pxor %xmm1,%xmm2
+ addb %bl,%cl
+ pinsrw $0,(%rdi,%rax,4),%xmm0
+ movdqu %xmm2,(%r13,%r12,1)
+ leaq 16(%r12),%r12
+.Loop16_enter:
+ movl (%rdi,%rcx,4),%edx
+ pxor %xmm1,%xmm1
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 8(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,4(%rsi)
+ addb %al,%cl
+ pinsrw $0,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 12(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,8(%rsi)
+ addb %bl,%cl
+ pinsrw $1,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 16(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,12(%rsi)
+ addb %al,%cl
+ pinsrw $1,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 20(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,16(%rsi)
+ addb %bl,%cl
+ pinsrw $2,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 24(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,20(%rsi)
+ addb %al,%cl
+ pinsrw $2,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 28(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,24(%rsi)
+ addb %bl,%cl
+ pinsrw $3,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 32(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,28(%rsi)
+ addb %al,%cl
+ pinsrw $3,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 36(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,32(%rsi)
+ addb %bl,%cl
+ pinsrw $4,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 40(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,36(%rsi)
+ addb %al,%cl
+ pinsrw $4,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 44(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,40(%rsi)
+ addb %bl,%cl
+ pinsrw $5,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 48(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,44(%rsi)
+ addb %al,%cl
+ pinsrw $5,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 52(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,48(%rsi)
+ addb %bl,%cl
+ pinsrw $6,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 56(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,52(%rsi)
+ addb %al,%cl
+ pinsrw $6,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 60(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,56(%rsi)
+ addb %bl,%cl
+ pinsrw $7,(%rdi,%rax,4),%xmm0
+ addb $16,%r10b
+ movdqu (%r12),%xmm2
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movzbl %bl,%ebx
+ movl %edx,60(%rsi)
+ leaq (%rdi,%r10,4),%rsi
+ pinsrw $7,(%rdi,%rbx,4),%xmm1
+ movl (%rsi),%eax
+ movq %rcx,%rbx
+ xorq %rcx,%rcx
+ subq $16,%r11
+ movb %bl,%cl
+ testq $-16,%r11
+ jnz .Loop16
+
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm2
+ pxor %xmm1,%xmm2
+ movdqu %xmm2,(%r13,%r12,1)
+ leaq 16(%r12),%r12
+
+ cmpq $0,%r11
jne .Lloop1
jmp .Lexit
.align 16
.Lloop1:
- addb %r9b,%r12b
- movl (%rdi,%r12,4),%r13d
- movl %r9d,(%rdi,%r12,4)
- movl %r13d,(%rdi,%r8,4)
- addb %r13b,%r9b
- incb %r8b
- movl (%rdi,%r9,4),%r13d
- movl (%rdi,%r8,4),%r9d
- xorb (%rdx),%r13b
- incq %rdx
- movb %r13b,(%rcx)
- incq %rcx
- decq %rsi
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl %edx,(%rdi,%r10,4)
+ addb %dl,%al
+ incb %r10b
+ movl (%rdi,%rax,4),%edx
+ movl (%rdi,%r10,4),%eax
+ xorb (%r12),%dl
+ movb %dl,(%r13,%r12,1)
+ leaq 1(%r12),%r12
+ decq %r11
jnz .Lloop1
jmp .Lexit
.align 16
.LRC4_CHAR:
- addb $1,%r8b
- movzbl (%rdi,%r8,1),%r9d
- testq $-8,%rsi
+ addb $1,%r10b
+ movzbl (%rdi,%r10,1),%eax
+ testq $-8,%r11
jz .Lcloop1
- cmpl $0,260(%rdi)
- jnz .Lcloop1
jmp .Lcloop8
.align 16
.Lcloop8:
- movl (%rdx),%eax
- movl 4(%rdx),%ebx
- addb %r9b,%r12b
- leaq 1(%r8),%r10
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%r11d
- movb %r9b,(%rdi,%r12,1)
- cmpq %r10,%r12
- movb %r13b,(%rdi,%r8,1)
+ movl (%r12),%r8d
+ movl 4(%r12),%r9d
+ addb %al,%cl
+ leaq 1(%r10),%rsi
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %sil,%esi
+ movzbl (%rdi,%rsi,1),%ebx
+ movb %al,(%rdi,%rcx,1)
+ cmpq %rsi,%rcx
+ movb %dl,(%rdi,%r10,1)
jne .Lcmov0
- movq %r9,%r11
+ movq %rax,%rbx
.Lcmov0:
- addb %r9b,%r13b
- xorb (%rdi,%r13,1),%al
- rorl $8,%eax
- addb %r11b,%r12b
- leaq 1(%r10),%r8
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r8b,%r8d
- movzbl (%rdi,%r8,1),%r9d
- movb %r11b,(%rdi,%r12,1)
- cmpq %r8,%r12
- movb %r13b,(%rdi,%r10,1)
+ addb %al,%dl
+ xorb (%rdi,%rdx,1),%r8b
+ rorl $8,%r8d
+ addb %bl,%cl
+ leaq 1(%rsi),%r10
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %r10b,%r10d
+ movzbl (%rdi,%r10,1),%eax
+ movb %bl,(%rdi,%rcx,1)
+ cmpq %r10,%rcx
+ movb %dl,(%rdi,%rsi,1)
jne .Lcmov1
- movq %r11,%r9
+ movq %rbx,%rax
.Lcmov1:
- addb %r11b,%r13b
- xorb (%rdi,%r13,1),%al
- rorl $8,%eax
- addb %r9b,%r12b
- leaq 1(%r8),%r10
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%r11d
- movb %r9b,(%rdi,%r12,1)
- cmpq %r10,%r12
- movb %r13b,(%rdi,%r8,1)
+ addb %bl,%dl
+ xorb (%rdi,%rdx,1),%r8b
+ rorl $8,%r8d
+ addb %al,%cl
+ leaq 1(%r10),%rsi
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %sil,%esi
+ movzbl (%rdi,%rsi,1),%ebx
+ movb %al,(%rdi,%rcx,1)
+ cmpq %rsi,%rcx
+ movb %dl,(%rdi,%r10,1)
jne .Lcmov2
- movq %r9,%r11
+ movq %rax,%rbx
.Lcmov2:
- addb %r9b,%r13b
- xorb (%rdi,%r13,1),%al
- rorl $8,%eax
- addb %r11b,%r12b
- leaq 1(%r10),%r8
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r8b,%r8d
- movzbl (%rdi,%r8,1),%r9d
- movb %r11b,(%rdi,%r12,1)
- cmpq %r8,%r12
- movb %r13b,(%rdi,%r10,1)
+ addb %al,%dl
+ xorb (%rdi,%rdx,1),%r8b
+ rorl $8,%r8d
+ addb %bl,%cl
+ leaq 1(%rsi),%r10
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %r10b,%r10d
+ movzbl (%rdi,%r10,1),%eax
+ movb %bl,(%rdi,%rcx,1)
+ cmpq %r10,%rcx
+ movb %dl,(%rdi,%rsi,1)
jne .Lcmov3
- movq %r11,%r9
+ movq %rbx,%rax
.Lcmov3:
- addb %r11b,%r13b
- xorb (%rdi,%r13,1),%al
- rorl $8,%eax
- addb %r9b,%r12b
- leaq 1(%r8),%r10
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%r11d
- movb %r9b,(%rdi,%r12,1)
- cmpq %r10,%r12
- movb %r13b,(%rdi,%r8,1)
+ addb %bl,%dl
+ xorb (%rdi,%rdx,1),%r8b
+ rorl $8,%r8d
+ addb %al,%cl
+ leaq 1(%r10),%rsi
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %sil,%esi
+ movzbl (%rdi,%rsi,1),%ebx
+ movb %al,(%rdi,%rcx,1)
+ cmpq %rsi,%rcx
+ movb %dl,(%rdi,%r10,1)
jne .Lcmov4
- movq %r9,%r11
+ movq %rax,%rbx
.Lcmov4:
- addb %r9b,%r13b
- xorb (%rdi,%r13,1),%bl
- rorl $8,%ebx
- addb %r11b,%r12b
- leaq 1(%r10),%r8
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r8b,%r8d
- movzbl (%rdi,%r8,1),%r9d
- movb %r11b,(%rdi,%r12,1)
- cmpq %r8,%r12
- movb %r13b,(%rdi,%r10,1)
+ addb %al,%dl
+ xorb (%rdi,%rdx,1),%r9b
+ rorl $8,%r9d
+ addb %bl,%cl
+ leaq 1(%rsi),%r10
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %r10b,%r10d
+ movzbl (%rdi,%r10,1),%eax
+ movb %bl,(%rdi,%rcx,1)
+ cmpq %r10,%rcx
+ movb %dl,(%rdi,%rsi,1)
jne .Lcmov5
- movq %r11,%r9
+ movq %rbx,%rax
.Lcmov5:
- addb %r11b,%r13b
- xorb (%rdi,%r13,1),%bl
- rorl $8,%ebx
- addb %r9b,%r12b
- leaq 1(%r8),%r10
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%r11d
- movb %r9b,(%rdi,%r12,1)
- cmpq %r10,%r12
- movb %r13b,(%rdi,%r8,1)
+ addb %bl,%dl
+ xorb (%rdi,%rdx,1),%r9b
+ rorl $8,%r9d
+ addb %al,%cl
+ leaq 1(%r10),%rsi
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %sil,%esi
+ movzbl (%rdi,%rsi,1),%ebx
+ movb %al,(%rdi,%rcx,1)
+ cmpq %rsi,%rcx
+ movb %dl,(%rdi,%r10,1)
jne .Lcmov6
- movq %r9,%r11
+ movq %rax,%rbx
.Lcmov6:
- addb %r9b,%r13b
- xorb (%rdi,%r13,1),%bl
- rorl $8,%ebx
- addb %r11b,%r12b
- leaq 1(%r10),%r8
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r8b,%r8d
- movzbl (%rdi,%r8,1),%r9d
- movb %r11b,(%rdi,%r12,1)
- cmpq %r8,%r12
- movb %r13b,(%rdi,%r10,1)
+ addb %al,%dl
+ xorb (%rdi,%rdx,1),%r9b
+ rorl $8,%r9d
+ addb %bl,%cl
+ leaq 1(%rsi),%r10
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %r10b,%r10d
+ movzbl (%rdi,%r10,1),%eax
+ movb %bl,(%rdi,%rcx,1)
+ cmpq %r10,%rcx
+ movb %dl,(%rdi,%rsi,1)
jne .Lcmov7
- movq %r11,%r9
+ movq %rbx,%rax
.Lcmov7:
- addb %r11b,%r13b
- xorb (%rdi,%r13,1),%bl
- rorl $8,%ebx
- leaq -8(%rsi),%rsi
- movl %eax,(%rcx)
- leaq 8(%rdx),%rdx
- movl %ebx,4(%rcx)
- leaq 8(%rcx),%rcx
-
- testq $-8,%rsi
+ addb %bl,%dl
+ xorb (%rdi,%rdx,1),%r9b
+ rorl $8,%r9d
+ leaq -8(%r11),%r11
+ movl %r8d,(%r13)
+ leaq 8(%r12),%r12
+ movl %r9d,4(%r13)
+ leaq 8(%r13),%r13
+
+ testq $-8,%r11
jnz .Lcloop8
- cmpq $0,%rsi
+ cmpq $0,%r11
jne .Lcloop1
jmp .Lexit
.align 16
.Lcloop1:
- addb %r9b,%r12b
- movzbl (%rdi,%r12,1),%r13d
- movb %r9b,(%rdi,%r12,1)
- movb %r13b,(%rdi,%r8,1)
- addb %r9b,%r13b
- addb $1,%r8b
- movzbl %r13b,%r13d
- movzbl %r8b,%r8d
- movzbl (%rdi,%r13,1),%r13d
- movzbl (%rdi,%r8,1),%r9d
- xorb (%rdx),%r13b
- leaq 1(%rdx),%rdx
- movb %r13b,(%rcx)
- leaq 1(%rcx),%rcx
- subq $1,%rsi
+ addb %al,%cl
+ movzbl %cl,%ecx
+ movzbl (%rdi,%rcx,1),%edx
+ movb %al,(%rdi,%rcx,1)
+ movb %dl,(%rdi,%r10,1)
+ addb %al,%dl
+ addb $1,%r10b
+ movzbl %dl,%edx
+ movzbl %r10b,%r10d
+ movzbl (%rdi,%rdx,1),%edx
+ movzbl (%rdi,%r10,1),%eax
+ xorb (%r12),%dl
+ leaq 1(%r12),%r12
+ movb %dl,(%r13)
+ leaq 1(%r13),%r13
+ subq $1,%r11
jnz .Lcloop1
jmp .Lexit
.align 16
.Lexit:
- subb $1,%r8b
- movl %r8d,-8(%rdi)
- movl %r12d,-4(%rdi)
+ subb $1,%r10b
+ movl %r10d,-8(%rdi)
+ movl %ecx,-4(%rdi)
movq (%rsp),%r13
movq 8(%rsp),%r12
@@ -330,11 +526,10 @@ RC4: orq %rsi,%rsi
.Lepilogue:
.byte 0xf3,0xc3
.size RC4,.-RC4
-
-.globl RC4_set_key
-.type RC4_set_key,@function
+.globl private_RC4_set_key
+.type private_RC4_set_key,@function
.align 16
-RC4_set_key:
+private_RC4_set_key:
leaq 8(%rdi),%rdi
leaq (%rdx,%rsi,1),%rdx
negq %rsi
@@ -346,11 +541,8 @@ RC4_set_key:
movl OPENSSL_ia32cap_P(%rip),%r8d
btl $20,%r8d
- jnc .Lw1stloop
- btl $30,%r8d
- setc %r9b
- movl %r9d,260(%rdi)
- jmp .Lc1stloop
+ jc .Lc1stloop
+ jmp .Lw1stloop
.align 16
.Lw1stloop:
@@ -404,7 +596,7 @@ RC4_set_key:
movl %eax,-8(%rdi)
movl %eax,-4(%rdi)
.byte 0xf3,0xc3
-.size RC4_set_key,.-RC4_set_key
+.size private_RC4_set_key,.-private_RC4_set_key
.globl RC4_options
.type RC4_options,@function
@@ -413,18 +605,20 @@ RC4_options:
leaq .Lopts(%rip),%rax
movl OPENSSL_ia32cap_P(%rip),%edx
btl $20,%edx
- jnc .Ldone
- addq $12,%rax
+ jc .L8xchar
btl $30,%edx
jnc .Ldone
- addq $13,%rax
+ addq $25,%rax
+ .byte 0xf3,0xc3
+.L8xchar:
+ addq $12,%rax
.Ldone:
.byte 0xf3,0xc3
.align 64
.Lopts:
.byte 114,99,52,40,56,120,44,105,110,116,41,0
.byte 114,99,52,40,56,120,44,99,104,97,114,41,0
-.byte 114,99,52,40,49,120,44,99,104,97,114,41,0
+.byte 114,99,52,40,49,54,120,44,105,110,116,41,0
.byte 82,67,52,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 64
.size RC4_options,.-RC4_options
diff --git a/deps/openssl/asm/x64-elf-gas/sha/sha1-x86_64.s b/deps/openssl/asm/x64-elf-gas/sha/sha1-x86_64.s
index 208c2cdd2..c11c6f650 100644
--- a/deps/openssl/asm/x64-elf-gas/sha/sha1-x86_64.s
+++ b/deps/openssl/asm/x64-elf-gas/sha/sha1-x86_64.s
@@ -1,12 +1,23 @@
.text
+
+
.globl sha1_block_data_order
.type sha1_block_data_order,@function
.align 16
sha1_block_data_order:
+ movl OPENSSL_ia32cap_P+0(%rip),%r9d
+ movl OPENSSL_ia32cap_P+4(%rip),%r8d
+ testl $512,%r8d
+ jz .Lialu
+ jmp _ssse3_shortcut
+
+.align 16
+.Lialu:
pushq %rbx
pushq %rbp
pushq %r12
+ pushq %r13
movq %rsp,%r11
movq %rdi,%r8
subq $72,%rsp
@@ -16,1268 +27,2466 @@ sha1_block_data_order:
movq %r11,64(%rsp)
.Lprologue:
- movl 0(%r8),%edx
- movl 4(%r8),%esi
- movl 8(%r8),%edi
- movl 12(%r8),%ebp
- movl 16(%r8),%r11d
-.align 4
+ movl 0(%r8),%esi
+ movl 4(%r8),%edi
+ movl 8(%r8),%r11d
+ movl 12(%r8),%r12d
+ movl 16(%r8),%r13d
+ jmp .Lloop
+
+.align 16
.Lloop:
- movl 0(%r9),%eax
- bswapl %eax
- movl %eax,0(%rsp)
- leal 1518500249(%rax,%r11,1),%r12d
- movl %edi,%ebx
- movl 4(%r9),%eax
- movl %edx,%r11d
- xorl %ebp,%ebx
- bswapl %eax
- roll $5,%r11d
- andl %esi,%ebx
- movl %eax,4(%rsp)
- addl %r11d,%r12d
- xorl %ebp,%ebx
+ movl 0(%r9),%edx
+ bswapl %edx
+ movl %edx,0(%rsp)
+ movl %r11d,%eax
+ movl 4(%r9),%ebp
+ movl %esi,%ecx
+ xorl %r12d,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%r13,1),%r13d
+ andl %edi,%eax
+ movl %ebp,4(%rsp)
+ addl %ecx,%r13d
+ xorl %r12d,%eax
+ roll $30,%edi
+ addl %eax,%r13d
+ movl %edi,%eax
+ movl 8(%r9),%edx
+ movl %r13d,%ecx
+ xorl %r11d,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%r12,1),%r12d
+ andl %esi,%eax
+ movl %edx,8(%rsp)
+ addl %ecx,%r12d
+ xorl %r11d,%eax
roll $30,%esi
- addl %ebx,%r12d
- leal 1518500249(%rax,%rbp,1),%r11d
- movl %esi,%ebx
- movl 8(%r9),%eax
- movl %r12d,%ebp
- xorl %edi,%ebx
- bswapl %eax
- roll $5,%ebp
- andl %edx,%ebx
- movl %eax,8(%rsp)
- addl %ebp,%r11d
- xorl %edi,%ebx
- roll $30,%edx
- addl %ebx,%r11d
- leal 1518500249(%rax,%rdi,1),%ebp
- movl %edx,%ebx
- movl 12(%r9),%eax
- movl %r11d,%edi
- xorl %esi,%ebx
- bswapl %eax
- roll $5,%edi
- andl %r12d,%ebx
- movl %eax,12(%rsp)
- addl %edi,%ebp
- xorl %esi,%ebx
+ addl %eax,%r12d
+ movl %esi,%eax
+ movl 12(%r9),%ebp
+ movl %r12d,%ecx
+ xorl %edi,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%r11,1),%r11d
+ andl %r13d,%eax
+ movl %ebp,12(%rsp)
+ addl %ecx,%r11d
+ xorl %edi,%eax
+ roll $30,%r13d
+ addl %eax,%r11d
+ movl %r13d,%eax
+ movl 16(%r9),%edx
+ movl %r11d,%ecx
+ xorl %esi,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%rdi,1),%edi
+ andl %r12d,%eax
+ movl %edx,16(%rsp)
+ addl %ecx,%edi
+ xorl %esi,%eax
roll $30,%r12d
- addl %ebx,%ebp
- leal 1518500249(%rax,%rsi,1),%edi
- movl %r12d,%ebx
- movl 16(%r9),%eax
- movl %ebp,%esi
- xorl %edx,%ebx
- bswapl %eax
- roll $5,%esi
- andl %r11d,%ebx
- movl %eax,16(%rsp)
- addl %esi,%edi
- xorl %edx,%ebx
+ addl %eax,%edi
+ movl %r12d,%eax
+ movl 20(%r9),%ebp
+ movl %edi,%ecx
+ xorl %r13d,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%rsi,1),%esi
+ andl %r11d,%eax
+ movl %ebp,20(%rsp)
+ addl %ecx,%esi
+ xorl %r13d,%eax
roll $30,%r11d
- addl %ebx,%edi
- leal 1518500249(%rax,%rdx,1),%esi
+ addl %eax,%esi
+ movl %r11d,%eax
+ movl 24(%r9),%edx
+ movl %esi,%ecx
+ xorl %r12d,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%r13,1),%r13d
+ andl %edi,%eax
+ movl %edx,24(%rsp)
+ addl %ecx,%r13d
+ xorl %r12d,%eax
+ roll $30,%edi
+ addl %eax,%r13d
+ movl %edi,%eax
+ movl 28(%r9),%ebp
+ movl %r13d,%ecx
+ xorl %r11d,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%r12,1),%r12d
+ andl %esi,%eax
+ movl %ebp,28(%rsp)
+ addl %ecx,%r12d
+ xorl %r11d,%eax
+ roll $30,%esi
+ addl %eax,%r12d
+ movl %esi,%eax
+ movl 32(%r9),%edx
+ movl %r12d,%ecx
+ xorl %edi,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%r11,1),%r11d
+ andl %r13d,%eax
+ movl %edx,32(%rsp)
+ addl %ecx,%r11d
+ xorl %edi,%eax
+ roll $30,%r13d
+ addl %eax,%r11d
+ movl %r13d,%eax
+ movl 36(%r9),%ebp
+ movl %r11d,%ecx
+ xorl %esi,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%rdi,1),%edi
+ andl %r12d,%eax
+ movl %ebp,36(%rsp)
+ addl %ecx,%edi
+ xorl %esi,%eax
+ roll $30,%r12d
+ addl %eax,%edi
+ movl %r12d,%eax
+ movl 40(%r9),%edx
+ movl %edi,%ecx
+ xorl %r13d,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%rsi,1),%esi
+ andl %r11d,%eax
+ movl %edx,40(%rsp)
+ addl %ecx,%esi
+ xorl %r13d,%eax
+ roll $30,%r11d
+ addl %eax,%esi
+ movl %r11d,%eax
+ movl 44(%r9),%ebp
+ movl %esi,%ecx
+ xorl %r12d,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%r13,1),%r13d
+ andl %edi,%eax
+ movl %ebp,44(%rsp)
+ addl %ecx,%r13d
+ xorl %r12d,%eax
+ roll $30,%edi
+ addl %eax,%r13d
+ movl %edi,%eax
+ movl 48(%r9),%edx
+ movl %r13d,%ecx
+ xorl %r11d,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%r12,1),%r12d
+ andl %esi,%eax
+ movl %edx,48(%rsp)
+ addl %ecx,%r12d
+ xorl %r11d,%eax
+ roll $30,%esi
+ addl %eax,%r12d
+ movl %esi,%eax
+ movl 52(%r9),%ebp
+ movl %r12d,%ecx
+ xorl %edi,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%r11,1),%r11d
+ andl %r13d,%eax
+ movl %ebp,52(%rsp)
+ addl %ecx,%r11d
+ xorl %edi,%eax
+ roll $30,%r13d
+ addl %eax,%r11d
+ movl %r13d,%eax
+ movl 56(%r9),%edx
+ movl %r11d,%ecx
+ xorl %esi,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%rdi,1),%edi
+ andl %r12d,%eax
+ movl %edx,56(%rsp)
+ addl %ecx,%edi
+ xorl %esi,%eax
+ roll $30,%r12d
+ addl %eax,%edi
+ movl %r12d,%eax
+ movl 60(%r9),%ebp
+ movl %edi,%ecx
+ xorl %r13d,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%rsi,1),%esi
+ andl %r11d,%eax
+ movl %ebp,60(%rsp)
+ addl %ecx,%esi
+ xorl %r13d,%eax
+ roll $30,%r11d
+ addl %eax,%esi
+ movl 0(%rsp),%edx
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 8(%rsp),%edx
+ xorl %r12d,%eax
+ roll $5,%ecx
+ xorl 32(%rsp),%edx
+ andl %edi,%eax
+ leal 1518500249(%rbp,%r13,1),%r13d
+ xorl 52(%rsp),%edx
+ xorl %r12d,%eax
+ roll $1,%edx
+ addl %ecx,%r13d
+ roll $30,%edi
+ movl %edx,0(%rsp)
+ addl %eax,%r13d
+ movl 4(%rsp),%ebp
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 12(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $5,%ecx
+ xorl 36(%rsp),%ebp
+ andl %esi,%eax
+ leal 1518500249(%rdx,%r12,1),%r12d
+ xorl 56(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $1,%ebp
+ addl %ecx,%r12d
+ roll $30,%esi
+ movl %ebp,4(%rsp)
+ addl %eax,%r12d
+ movl 8(%rsp),%edx
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 16(%rsp),%edx
+ xorl %edi,%eax
+ roll $5,%ecx
+ xorl 40(%rsp),%edx
+ andl %r13d,%eax
+ leal 1518500249(%rbp,%r11,1),%r11d
+ xorl 60(%rsp),%edx
+ xorl %edi,%eax
+ roll $1,%edx
+ addl %ecx,%r11d
+ roll $30,%r13d
+ movl %edx,8(%rsp)
+ addl %eax,%r11d
+ movl 12(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 20(%rsp),%ebp
+ xorl %esi,%eax
+ roll $5,%ecx
+ xorl 44(%rsp),%ebp
+ andl %r12d,%eax
+ leal 1518500249(%rdx,%rdi,1),%edi
+ xorl 0(%rsp),%ebp
+ xorl %esi,%eax
+ roll $1,%ebp
+ addl %ecx,%edi
+ roll $30,%r12d
+ movl %ebp,12(%rsp)
+ addl %eax,%edi
+ movl 16(%rsp),%edx
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 24(%rsp),%edx
+ xorl %r13d,%eax
+ roll $5,%ecx
+ xorl 48(%rsp),%edx
+ andl %r11d,%eax
+ leal 1518500249(%rbp,%rsi,1),%esi
+ xorl 4(%rsp),%edx
+ xorl %r13d,%eax
+ roll $1,%edx
+ addl %ecx,%esi
+ roll $30,%r11d
+ movl %edx,16(%rsp)
+ addl %eax,%esi
+ movl 20(%rsp),%ebp
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 28(%rsp),%ebp
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r13,1),%r13d
+ xorl 52(%rsp),%ebp
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 8(%rsp),%ebp
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%ebp
+ movl %ebp,20(%rsp)
+ movl 24(%rsp),%edx
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 32(%rsp),%edx
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r12,1),%r12d
+ xorl 56(%rsp),%edx
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 12(%rsp),%edx
+ roll $30,%esi
+ addl %eax,%r12d
+ roll $1,%edx
+ movl %edx,24(%rsp)
+ movl 28(%rsp),%ebp
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 36(%rsp),%ebp
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r11,1),%r11d
+ xorl 60(%rsp),%ebp
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 16(%rsp),%ebp
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%ebp
+ movl %ebp,28(%rsp)
+ movl 32(%rsp),%edx
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 40(%rsp),%edx
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%rdi,1),%edi
+ xorl 0(%rsp),%edx
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 20(%rsp),%edx
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%edx
+ movl %edx,32(%rsp)
+ movl 36(%rsp),%ebp
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 44(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%rsi,1),%esi
+ xorl 4(%rsp),%ebp
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 24(%rsp),%ebp
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%ebp
+ movl %ebp,36(%rsp)
+ movl 40(%rsp),%edx
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 48(%rsp),%edx
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r13,1),%r13d
+ xorl 8(%rsp),%edx
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 28(%rsp),%edx
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%edx
+ movl %edx,40(%rsp)
+ movl 44(%rsp),%ebp
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 52(%rsp),%ebp
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r12,1),%r12d
+ xorl 12(%rsp),%ebp
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 32(%rsp),%ebp
+ roll $30,%esi
+ addl %eax,%r12d
+ roll $1,%ebp
+ movl %ebp,44(%rsp)
+ movl 48(%rsp),%edx
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 56(%rsp),%edx
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r11,1),%r11d
+ xorl 16(%rsp),%edx
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 36(%rsp),%edx
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%edx
+ movl %edx,48(%rsp)
+ movl 52(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 60(%rsp),%ebp
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%rdi,1),%edi
+ xorl 20(%rsp),%ebp
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 40(%rsp),%ebp
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%ebp
+ movl %ebp,52(%rsp)
+ movl 56(%rsp),%edx
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 0(%rsp),%edx
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%rsi,1),%esi
+ xorl 24(%rsp),%edx
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 44(%rsp),%edx
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%edx
+ movl %edx,56(%rsp)
+ movl 60(%rsp),%ebp
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 4(%rsp),%ebp
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r13,1),%r13d
+ xorl 28(%rsp),%ebp
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 48(%rsp),%ebp
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%ebp
+ movl %ebp,60(%rsp)
+ movl 0(%rsp),%edx
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 8(%rsp),%edx
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r12,1),%r12d
+ xorl 32(%rsp),%edx
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 52(%rsp),%edx
+ roll $30,%esi
+ addl %eax,%r12d
+ roll $1,%edx
+ movl %edx,0(%rsp)
+ movl 4(%rsp),%ebp
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 12(%rsp),%ebp
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r11,1),%r11d
+ xorl 36(%rsp),%ebp
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 56(%rsp),%ebp
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%ebp
+ movl %ebp,4(%rsp)
+ movl 8(%rsp),%edx
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 16(%rsp),%edx
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%rdi,1),%edi
+ xorl 40(%rsp),%edx
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 60(%rsp),%edx
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%edx
+ movl %edx,8(%rsp)
+ movl 12(%rsp),%ebp
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 20(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%rsi,1),%esi
+ xorl 44(%rsp),%ebp
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 0(%rsp),%ebp
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%ebp
+ movl %ebp,12(%rsp)
+ movl 16(%rsp),%edx
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 24(%rsp),%edx
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r13,1),%r13d
+ xorl 48(%rsp),%edx
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 4(%rsp),%edx
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%edx
+ movl %edx,16(%rsp)
+ movl 20(%rsp),%ebp
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 28(%rsp),%ebp
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r12,1),%r12d
+ xorl 52(%rsp),%ebp
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 8(%rsp),%ebp
+ roll $30,%esi
+ addl %eax,%r12d
+ roll $1,%ebp
+ movl %ebp,20(%rsp)
+ movl 24(%rsp),%edx
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 32(%rsp),%edx
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r11,1),%r11d
+ xorl 56(%rsp),%edx
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 12(%rsp),%edx
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%edx
+ movl %edx,24(%rsp)
+ movl 28(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 36(%rsp),%ebp
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%rdi,1),%edi
+ xorl 60(%rsp),%ebp
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 16(%rsp),%ebp
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%ebp
+ movl %ebp,28(%rsp)
+ movl 32(%rsp),%edx
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 40(%rsp),%edx
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%rsi,1),%esi
+ xorl 0(%rsp),%edx
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 20(%rsp),%edx
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%edx
+ movl %edx,32(%rsp)
+ movl 36(%rsp),%ebp
+ movl %r11d,%eax
movl %r11d,%ebx
- movl 20(%r9),%eax
- movl %edi,%edx
- xorl %r12d,%ebx
- bswapl %eax
- roll $5,%edx
- andl %ebp,%ebx
- movl %eax,20(%rsp)
- addl %edx,%esi
+ xorl 44(%rsp),%ebp
+ andl %r12d,%eax
+ movl %esi,%ecx
+ xorl 4(%rsp),%ebp
xorl %r12d,%ebx
- roll $30,%ebp
- addl %ebx,%esi
- leal 1518500249(%rax,%r12,1),%edx
- movl %ebp,%ebx
- movl 24(%r9),%eax
- movl %esi,%r12d
- xorl %r11d,%ebx
- bswapl %eax
- roll $5,%r12d
+ leal -1894007588(%rdx,%r13,1),%r13d
+ roll $5,%ecx
+ xorl 24(%rsp),%ebp
+ addl %eax,%r13d
andl %edi,%ebx
- movl %eax,24(%rsp)
- addl %r12d,%edx
- xorl %r11d,%ebx
+ roll $1,%ebp
+ addl %ebx,%r13d
roll $30,%edi
- addl %ebx,%edx
- leal 1518500249(%rax,%r11,1),%r12d
+ movl %ebp,36(%rsp)
+ addl %ecx,%r13d
+ movl 40(%rsp),%edx
+ movl %edi,%eax
movl %edi,%ebx
- movl 28(%r9),%eax
- movl %edx,%r11d
- xorl %ebp,%ebx
- bswapl %eax
- roll $5,%r11d
+ xorl 48(%rsp),%edx
+ andl %r11d,%eax
+ movl %r13d,%ecx
+ xorl 8(%rsp),%edx
+ xorl %r11d,%ebx
+ leal -1894007588(%rbp,%r12,1),%r12d
+ roll $5,%ecx
+ xorl 28(%rsp),%edx
+ addl %eax,%r12d
andl %esi,%ebx
- movl %eax,28(%rsp)
- addl %r11d,%r12d
- xorl %ebp,%ebx
- roll $30,%esi
+ roll $1,%edx
addl %ebx,%r12d
- leal 1518500249(%rax,%rbp,1),%r11d
+ roll $30,%esi
+ movl %edx,40(%rsp)
+ addl %ecx,%r12d
+ movl 44(%rsp),%ebp
+ movl %esi,%eax
movl %esi,%ebx
- movl 32(%r9),%eax
- movl %r12d,%ebp
- xorl %edi,%ebx
- bswapl %eax
- roll $5,%ebp
- andl %edx,%ebx
- movl %eax,32(%rsp)
- addl %ebp,%r11d
+ xorl 52(%rsp),%ebp
+ andl %edi,%eax
+ movl %r12d,%ecx
+ xorl 12(%rsp),%ebp
xorl %edi,%ebx
- roll $30,%edx
+ leal -1894007588(%rdx,%r11,1),%r11d
+ roll $5,%ecx
+ xorl 32(%rsp),%ebp
+ addl %eax,%r11d
+ andl %r13d,%ebx
+ roll $1,%ebp
addl %ebx,%r11d
- leal 1518500249(%rax,%rdi,1),%ebp
- movl %edx,%ebx
- movl 36(%r9),%eax
- movl %r11d,%edi
+ roll $30,%r13d
+ movl %ebp,44(%rsp)
+ addl %ecx,%r11d
+ movl 48(%rsp),%edx
+ movl %r13d,%eax
+ movl %r13d,%ebx
+ xorl 56(%rsp),%edx
+ andl %esi,%eax
+ movl %r11d,%ecx
+ xorl 16(%rsp),%edx
xorl %esi,%ebx
- bswapl %eax
- roll $5,%edi
+ leal -1894007588(%rbp,%rdi,1),%edi
+ roll $5,%ecx
+ xorl 36(%rsp),%edx
+ addl %eax,%edi
andl %r12d,%ebx
- movl %eax,36(%rsp)
- addl %edi,%ebp
- xorl %esi,%ebx
+ roll $1,%edx
+ addl %ebx,%edi
roll $30,%r12d
- addl %ebx,%ebp
- leal 1518500249(%rax,%rsi,1),%edi
+ movl %edx,48(%rsp)
+ addl %ecx,%edi
+ movl 52(%rsp),%ebp
+ movl %r12d,%eax
movl %r12d,%ebx
- movl 40(%r9),%eax
- movl %ebp,%esi
- xorl %edx,%ebx
- bswapl %eax
- roll $5,%esi
+ xorl 60(%rsp),%ebp
+ andl %r13d,%eax
+ movl %edi,%ecx
+ xorl 20(%rsp),%ebp
+ xorl %r13d,%ebx
+ leal -1894007588(%rdx,%rsi,1),%esi
+ roll $5,%ecx
+ xorl 40(%rsp),%ebp
+ addl %eax,%esi
andl %r11d,%ebx
- movl %eax,40(%rsp)
- addl %esi,%edi
- xorl %edx,%ebx
+ roll $1,%ebp
+ addl %ebx,%esi
roll $30,%r11d
- addl %ebx,%edi
- leal 1518500249(%rax,%rdx,1),%esi
+ movl %ebp,52(%rsp)
+ addl %ecx,%esi
+ movl 56(%rsp),%edx
+ movl %r11d,%eax
movl %r11d,%ebx
- movl 44(%r9),%eax
- movl %edi,%edx
- xorl %r12d,%ebx
- bswapl %eax
- roll $5,%edx
- andl %ebp,%ebx
- movl %eax,44(%rsp)
- addl %edx,%esi
+ xorl 0(%rsp),%edx
+ andl %r12d,%eax
+ movl %esi,%ecx
+ xorl 24(%rsp),%edx
xorl %r12d,%ebx
- roll $30,%ebp
- addl %ebx,%esi
- leal 1518500249(%rax,%r12,1),%edx
- movl %ebp,%ebx
- movl 48(%r9),%eax
- movl %esi,%r12d
- xorl %r11d,%ebx
- bswapl %eax
- roll $5,%r12d
+ leal -1894007588(%rbp,%r13,1),%r13d
+ roll $5,%ecx
+ xorl 44(%rsp),%edx
+ addl %eax,%r13d
andl %edi,%ebx
- movl %eax,48(%rsp)
- addl %r12d,%edx
- xorl %r11d,%ebx
+ roll $1,%edx
+ addl %ebx,%r13d
roll $30,%edi
- addl %ebx,%edx
- leal 1518500249(%rax,%r11,1),%r12d
+ movl %edx,56(%rsp)
+ addl %ecx,%r13d
+ movl 60(%rsp),%ebp
+ movl %edi,%eax
movl %edi,%ebx
- movl 52(%r9),%eax
- movl %edx,%r11d
- xorl %ebp,%ebx
- bswapl %eax
- roll $5,%r11d
+ xorl 4(%rsp),%ebp
+ andl %r11d,%eax
+ movl %r13d,%ecx
+ xorl 28(%rsp),%ebp
+ xorl %r11d,%ebx
+ leal -1894007588(%rdx,%r12,1),%r12d
+ roll $5,%ecx
+ xorl 48(%rsp),%ebp
+ addl %eax,%r12d
andl %esi,%ebx
- movl %eax,52(%rsp)
- addl %r11d,%r12d
- xorl %ebp,%ebx
- roll $30,%esi
+ roll $1,%ebp
addl %ebx,%r12d
- leal 1518500249(%rax,%rbp,1),%r11d
+ roll $30,%esi
+ movl %ebp,60(%rsp)
+ addl %ecx,%r12d
+ movl 0(%rsp),%edx
+ movl %esi,%eax
movl %esi,%ebx
- movl 56(%r9),%eax
- movl %r12d,%ebp
- xorl %edi,%ebx
- bswapl %eax
- roll $5,%ebp
- andl %edx,%ebx
- movl %eax,56(%rsp)
- addl %ebp,%r11d
+ xorl 8(%rsp),%edx
+ andl %edi,%eax
+ movl %r12d,%ecx
+ xorl 32(%rsp),%edx
xorl %edi,%ebx
- roll $30,%edx
+ leal -1894007588(%rbp,%r11,1),%r11d
+ roll $5,%ecx
+ xorl 52(%rsp),%edx
+ addl %eax,%r11d
+ andl %r13d,%ebx
+ roll $1,%edx
addl %ebx,%r11d
- leal 1518500249(%rax,%rdi,1),%ebp
- movl %edx,%ebx
- movl 60(%r9),%eax
- movl %r11d,%edi
+ roll $30,%r13d
+ movl %edx,0(%rsp)
+ addl %ecx,%r11d
+ movl 4(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r13d,%ebx
+ xorl 12(%rsp),%ebp
+ andl %esi,%eax
+ movl %r11d,%ecx
+ xorl 36(%rsp),%ebp
xorl %esi,%ebx
- bswapl %eax
- roll $5,%edi
+ leal -1894007588(%rdx,%rdi,1),%edi
+ roll $5,%ecx
+ xorl 56(%rsp),%ebp
+ addl %eax,%edi
andl %r12d,%ebx
- movl %eax,60(%rsp)
- addl %edi,%ebp
- xorl %esi,%ebx
+ roll $1,%ebp
+ addl %ebx,%edi
roll $30,%r12d
- addl %ebx,%ebp
- leal 1518500249(%rax,%rsi,1),%edi
- movl 0(%rsp),%eax
+ movl %ebp,4(%rsp)
+ addl %ecx,%edi
+ movl 8(%rsp),%edx
+ movl %r12d,%eax
movl %r12d,%ebx
- movl %ebp,%esi
- xorl 8(%rsp),%eax
- xorl %edx,%ebx
- roll $5,%esi
- xorl 32(%rsp),%eax
+ xorl 16(%rsp),%edx
+ andl %r13d,%eax
+ movl %edi,%ecx
+ xorl 40(%rsp),%edx
+ xorl %r13d,%ebx
+ leal -1894007588(%rbp,%rsi,1),%esi
+ roll $5,%ecx
+ xorl 60(%rsp),%edx
+ addl %eax,%esi
andl %r11d,%ebx
- addl %esi,%edi
- xorl 52(%rsp),%eax
- xorl %edx,%ebx
+ roll $1,%edx
+ addl %ebx,%esi
roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,0(%rsp)
- leal 1518500249(%rax,%rdx,1),%esi
- movl 4(%rsp),%eax
+ movl %edx,8(%rsp)
+ addl %ecx,%esi
+ movl 12(%rsp),%ebp
+ movl %r11d,%eax
movl %r11d,%ebx
- movl %edi,%edx
- xorl 12(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edx
- xorl 36(%rsp),%eax
- andl %ebp,%ebx
- addl %edx,%esi
- xorl 56(%rsp),%eax
+ xorl 20(%rsp),%ebp
+ andl %r12d,%eax
+ movl %esi,%ecx
+ xorl 44(%rsp),%ebp
xorl %r12d,%ebx
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- movl %eax,4(%rsp)
- leal 1518500249(%rax,%r12,1),%edx
- movl 8(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 16(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%r12d
- xorl 40(%rsp),%eax
+ leal -1894007588(%rdx,%r13,1),%r13d
+ roll $5,%ecx
+ xorl 0(%rsp),%ebp
+ addl %eax,%r13d
andl %edi,%ebx
- addl %r12d,%edx
- xorl 60(%rsp),%eax
- xorl %r11d,%ebx
+ roll $1,%ebp
+ addl %ebx,%r13d
roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,8(%rsp)
- leal 1518500249(%rax,%r11,1),%r12d
- movl 12(%rsp),%eax
+ movl %ebp,12(%rsp)
+ addl %ecx,%r13d
+ movl 16(%rsp),%edx
+ movl %edi,%eax
movl %edi,%ebx
- movl %edx,%r11d
- xorl 20(%rsp),%eax
- xorl %ebp,%ebx
- roll $5,%r11d
- xorl 44(%rsp),%eax
+ xorl 24(%rsp),%edx
+ andl %r11d,%eax
+ movl %r13d,%ecx
+ xorl 48(%rsp),%edx
+ xorl %r11d,%ebx
+ leal -1894007588(%rbp,%r12,1),%r12d
+ roll $5,%ecx
+ xorl 4(%rsp),%edx
+ addl %eax,%r12d
andl %esi,%ebx
- addl %r11d,%r12d
- xorl 0(%rsp),%eax
- xorl %ebp,%ebx
- roll $30,%esi
+ roll $1,%edx
addl %ebx,%r12d
- roll $1,%eax
- movl %eax,12(%rsp)
- leal 1518500249(%rax,%rbp,1),%r11d
- movl 16(%rsp),%eax
+ roll $30,%esi
+ movl %edx,16(%rsp)
+ addl %ecx,%r12d
+ movl 20(%rsp),%ebp
+ movl %esi,%eax
movl %esi,%ebx
- movl %r12d,%ebp
- xorl 24(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%ebp
- xorl 48(%rsp),%eax
- andl %edx,%ebx
- addl %ebp,%r11d
- xorl 4(%rsp),%eax
+ xorl 28(%rsp),%ebp
+ andl %edi,%eax
+ movl %r12d,%ecx
+ xorl 52(%rsp),%ebp
xorl %edi,%ebx
- roll $30,%edx
+ leal -1894007588(%rdx,%r11,1),%r11d
+ roll $5,%ecx
+ xorl 8(%rsp),%ebp
+ addl %eax,%r11d
+ andl %r13d,%ebx
+ roll $1,%ebp
addl %ebx,%r11d
- roll $1,%eax
- movl %eax,16(%rsp)
- leal 1859775393(%rax,%rdi,1),%ebp
- movl 20(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 28(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 52(%rsp),%eax
+ roll $30,%r13d
+ movl %ebp,20(%rsp)
+ addl %ecx,%r11d
+ movl 24(%rsp),%edx
+ movl %r13d,%eax
+ movl %r13d,%ebx
+ xorl 32(%rsp),%edx
+ andl %esi,%eax
+ movl %r11d,%ecx
+ xorl 56(%rsp),%edx
xorl %esi,%ebx
- addl %edi,%ebp
- xorl 8(%rsp),%eax
+ leal -1894007588(%rbp,%rdi,1),%edi
+ roll $5,%ecx
+ xorl 12(%rsp),%edx
+ addl %eax,%edi
+ andl %r12d,%ebx
+ roll $1,%edx
+ addl %ebx,%edi
roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,20(%rsp)
- leal 1859775393(%rax,%rsi,1),%edi
- movl 24(%rsp),%eax
+ movl %edx,24(%rsp)
+ addl %ecx,%edi
+ movl 28(%rsp),%ebp
+ movl %r12d,%eax
movl %r12d,%ebx
- movl %ebp,%esi
- xorl 32(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 56(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 12(%rsp),%eax
+ xorl 36(%rsp),%ebp
+ andl %r13d,%eax
+ movl %edi,%ecx
+ xorl 60(%rsp),%ebp
+ xorl %r13d,%ebx
+ leal -1894007588(%rdx,%rsi,1),%esi
+ roll $5,%ecx
+ xorl 16(%rsp),%ebp
+ addl %eax,%esi
+ andl %r11d,%ebx
+ roll $1,%ebp
+ addl %ebx,%esi
roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,24(%rsp)
- leal 1859775393(%rax,%rdx,1),%esi
- movl 28(%rsp),%eax
+ movl %ebp,28(%rsp)
+ addl %ecx,%esi
+ movl 32(%rsp),%edx
+ movl %r11d,%eax
movl %r11d,%ebx
- movl %edi,%edx
- xorl 36(%rsp),%eax
- xorl %ebp,%ebx
- roll $5,%edx
- xorl 60(%rsp),%eax
+ xorl 40(%rsp),%edx
+ andl %r12d,%eax
+ movl %esi,%ecx
+ xorl 0(%rsp),%edx
xorl %r12d,%ebx
- addl %edx,%esi
- xorl 16(%rsp),%eax
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- movl %eax,28(%rsp)
- leal 1859775393(%rax,%r12,1),%edx
- movl 32(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 40(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 0(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 20(%rsp),%eax
+ leal -1894007588(%rbp,%r13,1),%r13d
+ roll $5,%ecx
+ xorl 20(%rsp),%edx
+ addl %eax,%r13d
+ andl %edi,%ebx
+ roll $1,%edx
+ addl %ebx,%r13d
roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,32(%rsp)
- leal 1859775393(%rax,%r11,1),%r12d
- movl 36(%rsp),%eax
+ movl %edx,32(%rsp)
+ addl %ecx,%r13d
+ movl 36(%rsp),%ebp
+ movl %edi,%eax
movl %edi,%ebx
- movl %edx,%r11d
- xorl 44(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 4(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 24(%rsp),%eax
- roll $30,%esi
+ xorl 44(%rsp),%ebp
+ andl %r11d,%eax
+ movl %r13d,%ecx
+ xorl 4(%rsp),%ebp
+ xorl %r11d,%ebx
+ leal -1894007588(%rdx,%r12,1),%r12d
+ roll $5,%ecx
+ xorl 24(%rsp),%ebp
+ addl %eax,%r12d
+ andl %esi,%ebx
+ roll $1,%ebp
addl %ebx,%r12d
- roll $1,%eax
- movl %eax,36(%rsp)
- leal 1859775393(%rax,%rbp,1),%r11d
- movl 40(%rsp),%eax
+ roll $30,%esi
+ movl %ebp,36(%rsp)
+ addl %ecx,%r12d
+ movl 40(%rsp),%edx
+ movl %esi,%eax
movl %esi,%ebx
- movl %r12d,%ebp
- xorl 48(%rsp),%eax
- xorl %edx,%ebx
- roll $5,%ebp
- xorl 8(%rsp),%eax
+ xorl 48(%rsp),%edx
+ andl %edi,%eax
+ movl %r12d,%ecx
+ xorl 8(%rsp),%edx
xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 28(%rsp),%eax
- roll $30,%edx
+ leal -1894007588(%rbp,%r11,1),%r11d
+ roll $5,%ecx
+ xorl 28(%rsp),%edx
+ addl %eax,%r11d
+ andl %r13d,%ebx
+ roll $1,%edx
addl %ebx,%r11d
- roll $1,%eax
- movl %eax,40(%rsp)
- leal 1859775393(%rax,%rdi,1),%ebp
- movl 44(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 52(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 12(%rsp),%eax
+ roll $30,%r13d
+ movl %edx,40(%rsp)
+ addl %ecx,%r11d
+ movl 44(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r13d,%ebx
+ xorl 52(%rsp),%ebp
+ andl %esi,%eax
+ movl %r11d,%ecx
+ xorl 12(%rsp),%ebp
xorl %esi,%ebx
- addl %edi,%ebp
- xorl 32(%rsp),%eax
+ leal -1894007588(%rdx,%rdi,1),%edi
+ roll $5,%ecx
+ xorl 32(%rsp),%ebp
+ addl %eax,%edi
+ andl %r12d,%ebx
+ roll $1,%ebp
+ addl %ebx,%edi
roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,44(%rsp)
- leal 1859775393(%rax,%rsi,1),%edi
- movl 48(%rsp),%eax
+ movl %ebp,44(%rsp)
+ addl %ecx,%edi
+ movl 48(%rsp),%edx
+ movl %r12d,%eax
movl %r12d,%ebx
- movl %ebp,%esi
- xorl 56(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 16(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 36(%rsp),%eax
- roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,48(%rsp)
- leal 1859775393(%rax,%rdx,1),%esi
- movl 52(%rsp),%eax
- movl %r11d,%ebx
- movl %edi,%edx
- xorl 60(%rsp),%eax
- xorl %ebp,%ebx
- roll $5,%edx
- xorl 20(%rsp),%eax
- xorl %r12d,%ebx
- addl %edx,%esi
- xorl 40(%rsp),%eax
- roll $30,%ebp
+ xorl 56(%rsp),%edx
+ andl %r13d,%eax
+ movl %edi,%ecx
+ xorl 16(%rsp),%edx
+ xorl %r13d,%ebx
+ leal -1894007588(%rbp,%rsi,1),%esi
+ roll $5,%ecx
+ xorl 36(%rsp),%edx
+ addl %eax,%esi
+ andl %r11d,%ebx
+ roll $1,%edx
addl %ebx,%esi
- roll $1,%eax
- movl %eax,52(%rsp)
- leal 1859775393(%rax,%r12,1),%edx
- movl 56(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 0(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 24(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 44(%rsp),%eax
+ roll $30,%r11d
+ movl %edx,48(%rsp)
+ addl %ecx,%esi
+ movl 52(%rsp),%ebp
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 60(%rsp),%ebp
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r13,1),%r13d
+ xorl 20(%rsp),%ebp
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 40(%rsp),%ebp
roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,56(%rsp)
- leal 1859775393(%rax,%r11,1),%r12d
- movl 60(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 4(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 28(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 48(%rsp),%eax
+ addl %eax,%r13d
+ roll $1,%ebp
+ movl %ebp,52(%rsp)
+ movl 56(%rsp),%edx
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 0(%rsp),%edx
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r12,1),%r12d
+ xorl 24(%rsp),%edx
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 44(%rsp),%edx
roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- movl %eax,60(%rsp)
- leal 1859775393(%rax,%rbp,1),%r11d
- movl 0(%rsp),%eax
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl 8(%rsp),%eax
- xorl %edx,%ebx
- roll $5,%ebp
- xorl 32(%rsp),%eax
- xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 52(%rsp),%eax
- roll $30,%edx
- addl %ebx,%r11d
- roll $1,%eax
- movl %eax,0(%rsp)
- leal 1859775393(%rax,%rdi,1),%ebp
- movl 4(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 12(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 36(%rsp),%eax
- xorl %esi,%ebx
- addl %edi,%ebp
- xorl 56(%rsp),%eax
+ addl %eax,%r12d
+ roll $1,%edx
+ movl %edx,56(%rsp)
+ movl 60(%rsp),%ebp
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 4(%rsp),%ebp
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r11,1),%r11d
+ xorl 28(%rsp),%ebp
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 48(%rsp),%ebp
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%ebp
+ movl %ebp,60(%rsp)
+ movl 0(%rsp),%edx
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 8(%rsp),%edx
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%rdi,1),%edi
+ xorl 32(%rsp),%edx
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 52(%rsp),%edx
roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,4(%rsp)
- leal 1859775393(%rax,%rsi,1),%edi
- movl 8(%rsp),%eax
- movl %r12d,%ebx
- movl %ebp,%esi
- xorl 16(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 40(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 60(%rsp),%eax
+ addl %eax,%edi
+ roll $1,%edx
+ movl %edx,0(%rsp)
+ movl 4(%rsp),%ebp
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 12(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%rsi,1),%esi
+ xorl 36(%rsp),%ebp
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 56(%rsp),%ebp
roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,8(%rsp)
- leal 1859775393(%rax,%rdx,1),%esi
- movl 12(%rsp),%eax
- movl %r11d,%ebx
- movl %edi,%edx
- xorl 20(%rsp),%eax
- xorl %ebp,%ebx
- roll $5,%edx
- xorl 44(%rsp),%eax
- xorl %r12d,%ebx
- addl %edx,%esi
- xorl 0(%rsp),%eax
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- movl %eax,12(%rsp)
- leal 1859775393(%rax,%r12,1),%edx
- movl 16(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 24(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 48(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 4(%rsp),%eax
+ addl %eax,%esi
+ roll $1,%ebp
+ movl %ebp,4(%rsp)
+ movl 8(%rsp),%edx
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 16(%rsp),%edx
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r13,1),%r13d
+ xorl 40(%rsp),%edx
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 60(%rsp),%edx
roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,16(%rsp)
- leal 1859775393(%rax,%r11,1),%r12d
- movl 20(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 28(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 52(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 8(%rsp),%eax
+ addl %eax,%r13d
+ roll $1,%edx
+ movl %edx,8(%rsp)
+ movl 12(%rsp),%ebp
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 20(%rsp),%ebp
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r12,1),%r12d
+ xorl 44(%rsp),%ebp
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 0(%rsp),%ebp
roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- movl %eax,20(%rsp)
- leal 1859775393(%rax,%rbp,1),%r11d
- movl 24(%rsp),%eax
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl 32(%rsp),%eax
- xorl %edx,%ebx
- roll $5,%ebp
- xorl 56(%rsp),%eax
- xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 12(%rsp),%eax
- roll $30,%edx
- addl %ebx,%r11d
- roll $1,%eax
- movl %eax,24(%rsp)
- leal 1859775393(%rax,%rdi,1),%ebp
- movl 28(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 36(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 60(%rsp),%eax
- xorl %esi,%ebx
- addl %edi,%ebp
- xorl 16(%rsp),%eax
+ addl %eax,%r12d
+ roll $1,%ebp
+ movl %ebp,12(%rsp)
+ movl 16(%rsp),%edx
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 24(%rsp),%edx
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r11,1),%r11d
+ xorl 48(%rsp),%edx
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 4(%rsp),%edx
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%edx
+ movl %edx,16(%rsp)
+ movl 20(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 28(%rsp),%ebp
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%rdi,1),%edi
+ xorl 52(%rsp),%ebp
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 8(%rsp),%ebp
roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,28(%rsp)
- leal 1859775393(%rax,%rsi,1),%edi
- movl 32(%rsp),%eax
- movl %r12d,%ebx
- movl %ebp,%esi
- xorl 40(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 0(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 20(%rsp),%eax
- roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,32(%rsp)
- leal -1894007588(%rax,%rdx,1),%esi
- movl 36(%rsp),%eax
- movl %ebp,%ebx
- movl %ebp,%ecx
- xorl 44(%rsp),%eax
- movl %edi,%edx
- andl %r11d,%ebx
- xorl 4(%rsp),%eax
- orl %r11d,%ecx
- roll $5,%edx
- xorl 24(%rsp),%eax
- andl %r12d,%ecx
- addl %edx,%esi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%ebp
- movl %eax,36(%rsp)
- addl %ebx,%esi
- leal -1894007588(%rax,%r12,1),%edx
- movl 40(%rsp),%eax
- movl %edi,%ebx
+ addl %eax,%edi
+ roll $1,%ebp
+ movl %ebp,20(%rsp)
+ movl 24(%rsp),%edx
+ movl %r12d,%eax
movl %edi,%ecx
- xorl 48(%rsp),%eax
- movl %esi,%r12d
- andl %ebp,%ebx
- xorl 8(%rsp),%eax
- orl %ebp,%ecx
- roll $5,%r12d
- xorl 28(%rsp),%eax
- andl %r11d,%ecx
- addl %r12d,%edx
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edi
- movl %eax,40(%rsp)
- addl %ebx,%edx
- leal -1894007588(%rax,%r11,1),%r12d
- movl 44(%rsp),%eax
- movl %esi,%ebx
+ xorl 32(%rsp),%edx
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%rsi,1),%esi
+ xorl 56(%rsp),%edx
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 12(%rsp),%edx
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%edx
+ movl %edx,24(%rsp)
+ movl 28(%rsp),%ebp
+ movl %r11d,%eax
movl %esi,%ecx
- xorl 52(%rsp),%eax
- movl %edx,%r11d
- andl %edi,%ebx
- xorl 12(%rsp),%eax
- orl %edi,%ecx
- roll $5,%r11d
- xorl 32(%rsp),%eax
- andl %ebp,%ecx
- addl %r11d,%r12d
- roll $1,%eax
- orl %ecx,%ebx
+ xorl 36(%rsp),%ebp
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r13,1),%r13d
+ xorl 60(%rsp),%ebp
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 16(%rsp),%ebp
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%ebp
+ movl %ebp,28(%rsp)
+ movl 32(%rsp),%edx
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 40(%rsp),%edx
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r12,1),%r12d
+ xorl 0(%rsp),%edx
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 20(%rsp),%edx
roll $30,%esi
- movl %eax,44(%rsp)
- addl %ebx,%r12d
- leal -1894007588(%rax,%rbp,1),%r11d
- movl 48(%rsp),%eax
- movl %edx,%ebx
- movl %edx,%ecx
- xorl 56(%rsp),%eax
- movl %r12d,%ebp
- andl %esi,%ebx
- xorl 16(%rsp),%eax
- orl %esi,%ecx
- roll $5,%ebp
- xorl 36(%rsp),%eax
- andl %edi,%ecx
- addl %ebp,%r11d
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edx
- movl %eax,48(%rsp)
- addl %ebx,%r11d
- leal -1894007588(%rax,%rdi,1),%ebp
- movl 52(%rsp),%eax
- movl %r12d,%ebx
+ addl %eax,%r12d
+ roll $1,%edx
+ movl %edx,32(%rsp)
+ movl 36(%rsp),%ebp
+ movl %esi,%eax
movl %r12d,%ecx
- xorl 60(%rsp),%eax
- movl %r11d,%edi
- andl %edx,%ebx
- xorl 20(%rsp),%eax
- orl %edx,%ecx
- roll $5,%edi
- xorl 40(%rsp),%eax
- andl %esi,%ecx
- addl %edi,%ebp
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%r12d
- movl %eax,52(%rsp)
- addl %ebx,%ebp
- leal -1894007588(%rax,%rsi,1),%edi
- movl 56(%rsp),%eax
- movl %r11d,%ebx
+ xorl 44(%rsp),%ebp
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r11,1),%r11d
+ xorl 4(%rsp),%ebp
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 24(%rsp),%ebp
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%ebp
+ movl %ebp,36(%rsp)
+ movl 40(%rsp),%edx
+ movl %r13d,%eax
movl %r11d,%ecx
- xorl 0(%rsp),%eax
- movl %ebp,%esi
- andl %r12d,%ebx
- xorl 24(%rsp),%eax
- orl %r12d,%ecx
- roll $5,%esi
- xorl 44(%rsp),%eax
- andl %edx,%ecx
- addl %esi,%edi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%r11d
- movl %eax,56(%rsp)
- addl %ebx,%edi
- leal -1894007588(%rax,%rdx,1),%esi
- movl 60(%rsp),%eax
- movl %ebp,%ebx
- movl %ebp,%ecx
- xorl 4(%rsp),%eax
- movl %edi,%edx
- andl %r11d,%ebx
- xorl 28(%rsp),%eax
- orl %r11d,%ecx
- roll $5,%edx
- xorl 48(%rsp),%eax
- andl %r12d,%ecx
- addl %edx,%esi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%ebp
- movl %eax,60(%rsp)
- addl %ebx,%esi
- leal -1894007588(%rax,%r12,1),%edx
- movl 0(%rsp),%eax
- movl %edi,%ebx
+ xorl 48(%rsp),%edx
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%rdi,1),%edi
+ xorl 8(%rsp),%edx
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 28(%rsp),%edx
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%edx
+ movl %edx,40(%rsp)
+ movl 44(%rsp),%ebp
+ movl %r12d,%eax
movl %edi,%ecx
- xorl 8(%rsp),%eax
- movl %esi,%r12d
- andl %ebp,%ebx
- xorl 32(%rsp),%eax
- orl %ebp,%ecx
- roll $5,%r12d
- xorl 52(%rsp),%eax
- andl %r11d,%ecx
- addl %r12d,%edx
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edi
- movl %eax,0(%rsp)
- addl %ebx,%edx
- leal -1894007588(%rax,%r11,1),%r12d
- movl 4(%rsp),%eax
- movl %esi,%ebx
+ xorl 52(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%rsi,1),%esi
+ xorl 12(%rsp),%ebp
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 32(%rsp),%ebp
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%ebp
+ movl %ebp,44(%rsp)
+ movl 48(%rsp),%edx
+ movl %r11d,%eax
movl %esi,%ecx
- xorl 12(%rsp),%eax
- movl %edx,%r11d
- andl %edi,%ebx
- xorl 36(%rsp),%eax
- orl %edi,%ecx
- roll $5,%r11d
- xorl 56(%rsp),%eax
- andl %ebp,%ecx
- addl %r11d,%r12d
- roll $1,%eax
- orl %ecx,%ebx
+ xorl 56(%rsp),%edx
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r13,1),%r13d
+ xorl 16(%rsp),%edx
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 36(%rsp),%edx
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%edx
+ movl %edx,48(%rsp)
+ movl 52(%rsp),%ebp
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 60(%rsp),%ebp
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r12,1),%r12d
+ xorl 20(%rsp),%ebp
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 40(%rsp),%ebp
roll $30,%esi
- movl %eax,4(%rsp)
- addl %ebx,%r12d
- leal -1894007588(%rax,%rbp,1),%r11d
- movl 8(%rsp),%eax
- movl %edx,%ebx
- movl %edx,%ecx
- xorl 16(%rsp),%eax
- movl %r12d,%ebp
- andl %esi,%ebx
- xorl 40(%rsp),%eax
- orl %esi,%ecx
- roll $5,%ebp
- xorl 60(%rsp),%eax
- andl %edi,%ecx
- addl %ebp,%r11d
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edx
- movl %eax,8(%rsp)
- addl %ebx,%r11d
- leal -1894007588(%rax,%rdi,1),%ebp
- movl 12(%rsp),%eax
- movl %r12d,%ebx
+ addl %eax,%r12d
+ roll $1,%ebp
+ movl 56(%rsp),%edx
+ movl %esi,%eax
movl %r12d,%ecx
- xorl 20(%rsp),%eax
- movl %r11d,%edi
- andl %edx,%ebx
- xorl 44(%rsp),%eax
- orl %edx,%ecx
- roll $5,%edi
- xorl 0(%rsp),%eax
- andl %esi,%ecx
- addl %edi,%ebp
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%r12d
- movl %eax,12(%rsp)
- addl %ebx,%ebp
- leal -1894007588(%rax,%rsi,1),%edi
- movl 16(%rsp),%eax
- movl %r11d,%ebx
+ xorl 0(%rsp),%edx
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r11,1),%r11d
+ xorl 24(%rsp),%edx
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 44(%rsp),%edx
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%edx
+ movl 60(%rsp),%ebp
+ movl %r13d,%eax
movl %r11d,%ecx
- xorl 24(%rsp),%eax
- movl %ebp,%esi
- andl %r12d,%ebx
- xorl 48(%rsp),%eax
- orl %r12d,%ecx
- roll $5,%esi
- xorl 4(%rsp),%eax
- andl %edx,%ecx
- addl %esi,%edi
- roll $1,%eax
- orl %ecx,%ebx
+ xorl 4(%rsp),%ebp
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%rdi,1),%edi
+ xorl 28(%rsp),%ebp
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 48(%rsp),%ebp
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%ebp
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl %r11d,%eax
+ leal -899497514(%rbp,%rsi,1),%esi
+ roll $5,%ecx
+ xorl %r13d,%eax
+ addl %ecx,%esi
roll $30,%r11d
- movl %eax,16(%rsp)
- addl %ebx,%edi
- leal -1894007588(%rax,%rdx,1),%esi
- movl 20(%rsp),%eax
- movl %ebp,%ebx
- movl %ebp,%ecx
- xorl 28(%rsp),%eax
- movl %edi,%edx
- andl %r11d,%ebx
- xorl 52(%rsp),%eax
- orl %r11d,%ecx
+ addl %eax,%esi
+ addl 0(%r8),%esi
+ addl 4(%r8),%edi
+ addl 8(%r8),%r11d
+ addl 12(%r8),%r12d
+ addl 16(%r8),%r13d
+ movl %esi,0(%r8)
+ movl %edi,4(%r8)
+ movl %r11d,8(%r8)
+ movl %r12d,12(%r8)
+ movl %r13d,16(%r8)
+
+ subq $1,%r10
+ leaq 64(%r9),%r9
+ jnz .Lloop
+
+ movq 64(%rsp),%rsi
+ movq (%rsi),%r13
+ movq 8(%rsi),%r12
+ movq 16(%rsi),%rbp
+ movq 24(%rsi),%rbx
+ leaq 32(%rsi),%rsp
+.Lepilogue:
+ .byte 0xf3,0xc3
+.size sha1_block_data_order,.-sha1_block_data_order
+.type sha1_block_data_order_ssse3,@function
+.align 16
+sha1_block_data_order_ssse3:
+_ssse3_shortcut:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ leaq -64(%rsp),%rsp
+ movq %rdi,%r8
+ movq %rsi,%r9
+ movq %rdx,%r10
+
+ shlq $6,%r10
+ addq %r9,%r10
+ leaq K_XX_XX(%rip),%r11
+
+ movl 0(%r8),%eax
+ movl 4(%r8),%ebx
+ movl 8(%r8),%ecx
+ movl 12(%r8),%edx
+ movl %ebx,%esi
+ movl 16(%r8),%ebp
+
+ movdqa 64(%r11),%xmm6
+ movdqa 0(%r11),%xmm9
+ movdqu 0(%r9),%xmm0
+ movdqu 16(%r9),%xmm1
+ movdqu 32(%r9),%xmm2
+ movdqu 48(%r9),%xmm3
+.byte 102,15,56,0,198
+ addq $64,%r9
+.byte 102,15,56,0,206
+.byte 102,15,56,0,214
+.byte 102,15,56,0,222
+ paddd %xmm9,%xmm0
+ paddd %xmm9,%xmm1
+ paddd %xmm9,%xmm2
+ movdqa %xmm0,0(%rsp)
+ psubd %xmm9,%xmm0
+ movdqa %xmm1,16(%rsp)
+ psubd %xmm9,%xmm1
+ movdqa %xmm2,32(%rsp)
+ psubd %xmm9,%xmm2
+ jmp .Loop_ssse3
+.align 16
+.Loop_ssse3:
+ movdqa %xmm1,%xmm4
+ addl 0(%rsp),%ebp
+ xorl %edx,%ecx
+ movdqa %xmm3,%xmm8
+.byte 102,15,58,15,224,8
+ movl %eax,%edi
+ roll $5,%eax
+ paddd %xmm3,%xmm9
+ andl %ecx,%esi
+ xorl %edx,%ecx
+ psrldq $4,%xmm8
+ xorl %edx,%esi
+ addl %eax,%ebp
+ pxor %xmm0,%xmm4
+ rorl $2,%ebx
+ addl %esi,%ebp
+ pxor %xmm2,%xmm8
+ addl 4(%rsp),%edx
+ xorl %ecx,%ebx
+ movl %ebp,%esi
+ roll $5,%ebp
+ pxor %xmm8,%xmm4
+ andl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa %xmm9,48(%rsp)
+ xorl %ecx,%edi
+ addl %ebp,%edx
+ movdqa %xmm4,%xmm10
+ movdqa %xmm4,%xmm8
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 8(%rsp),%ecx
+ xorl %ebx,%eax
+ pslldq $12,%xmm10
+ paddd %xmm4,%xmm4
+ movl %edx,%edi
roll $5,%edx
- xorl 8(%rsp),%eax
- andl %r12d,%ecx
- addl %edx,%esi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%ebp
- movl %eax,20(%rsp)
- addl %ebx,%esi
- leal -1894007588(%rax,%r12,1),%edx
- movl 24(%rsp),%eax
- movl %edi,%ebx
- movl %edi,%ecx
- xorl 32(%rsp),%eax
- movl %esi,%r12d
- andl %ebp,%ebx
- xorl 56(%rsp),%eax
- orl %ebp,%ecx
- roll $5,%r12d
- xorl 12(%rsp),%eax
- andl %r11d,%ecx
- addl %r12d,%edx
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edi
- movl %eax,24(%rsp)
- addl %ebx,%edx
- leal -1894007588(%rax,%r11,1),%r12d
- movl 28(%rsp),%eax
- movl %esi,%ebx
- movl %esi,%ecx
- xorl 36(%rsp),%eax
- movl %edx,%r11d
- andl %edi,%ebx
- xorl 60(%rsp),%eax
- orl %edi,%ecx
- roll $5,%r11d
- xorl 16(%rsp),%eax
- andl %ebp,%ecx
- addl %r11d,%r12d
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%esi
- movl %eax,28(%rsp)
- addl %ebx,%r12d
- leal -1894007588(%rax,%rbp,1),%r11d
- movl 32(%rsp),%eax
- movl %edx,%ebx
- movl %edx,%ecx
- xorl 40(%rsp),%eax
- movl %r12d,%ebp
- andl %esi,%ebx
- xorl 0(%rsp),%eax
- orl %esi,%ecx
+ andl %eax,%esi
+ xorl %ebx,%eax
+ psrld $31,%xmm8
+ xorl %ebx,%esi
+ addl %edx,%ecx
+ movdqa %xmm10,%xmm9
+ rorl $7,%ebp
+ addl %esi,%ecx
+ psrld $30,%xmm10
+ por %xmm8,%xmm4
+ addl 12(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%esi
+ roll $5,%ecx
+ pslld $2,%xmm9
+ pxor %xmm10,%xmm4
+ andl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa 0(%r11),%xmm10
+ xorl %eax,%edi
+ addl %ecx,%ebx
+ pxor %xmm9,%xmm4
+ rorl $7,%edx
+ addl %edi,%ebx
+ movdqa %xmm2,%xmm5
+ addl 16(%rsp),%eax
+ xorl %ebp,%edx
+ movdqa %xmm4,%xmm9
+.byte 102,15,58,15,233,8
+ movl %ebx,%edi
+ roll $5,%ebx
+ paddd %xmm4,%xmm10
+ andl %edx,%esi
+ xorl %ebp,%edx
+ psrldq $4,%xmm9
+ xorl %ebp,%esi
+ addl %ebx,%eax
+ pxor %xmm1,%xmm5
+ rorl $7,%ecx
+ addl %esi,%eax
+ pxor %xmm3,%xmm9
+ addl 20(%rsp),%ebp
+ xorl %edx,%ecx
+ movl %eax,%esi
+ roll $5,%eax
+ pxor %xmm9,%xmm5
+ andl %ecx,%edi
+ xorl %edx,%ecx
+ movdqa %xmm10,0(%rsp)
+ xorl %edx,%edi
+ addl %eax,%ebp
+ movdqa %xmm5,%xmm8
+ movdqa %xmm5,%xmm9
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 24(%rsp),%edx
+ xorl %ecx,%ebx
+ pslldq $12,%xmm8
+ paddd %xmm5,%xmm5
+ movl %ebp,%edi
roll $5,%ebp
- xorl 20(%rsp),%eax
- andl %edi,%ecx
- addl %ebp,%r11d
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edx
- movl %eax,32(%rsp)
- addl %ebx,%r11d
- leal -1894007588(%rax,%rdi,1),%ebp
- movl 36(%rsp),%eax
- movl %r12d,%ebx
- movl %r12d,%ecx
- xorl 44(%rsp),%eax
- movl %r11d,%edi
- andl %edx,%ebx
- xorl 4(%rsp),%eax
- orl %edx,%ecx
- roll $5,%edi
- xorl 24(%rsp),%eax
- andl %esi,%ecx
+ andl %ebx,%esi
+ xorl %ecx,%ebx
+ psrld $31,%xmm9
+ xorl %ecx,%esi
+ addl %ebp,%edx
+ movdqa %xmm8,%xmm10
+ rorl $7,%eax
+ addl %esi,%edx
+ psrld $30,%xmm8
+ por %xmm9,%xmm5
+ addl 28(%rsp),%ecx
+ xorl %ebx,%eax
+ movl %edx,%esi
+ roll $5,%edx
+ pslld $2,%xmm10
+ pxor %xmm8,%xmm5
+ andl %eax,%edi
+ xorl %ebx,%eax
+ movdqa 16(%r11),%xmm8
+ xorl %ebx,%edi
+ addl %edx,%ecx
+ pxor %xmm10,%xmm5
+ rorl $7,%ebp
+ addl %edi,%ecx
+ movdqa %xmm3,%xmm6
+ addl 32(%rsp),%ebx
+ xorl %eax,%ebp
+ movdqa %xmm5,%xmm10
+.byte 102,15,58,15,242,8
+ movl %ecx,%edi
+ roll $5,%ecx
+ paddd %xmm5,%xmm8
+ andl %ebp,%esi
+ xorl %eax,%ebp
+ psrldq $4,%xmm10
+ xorl %eax,%esi
+ addl %ecx,%ebx
+ pxor %xmm2,%xmm6
+ rorl $7,%edx
+ addl %esi,%ebx
+ pxor %xmm4,%xmm10
+ addl 36(%rsp),%eax
+ xorl %ebp,%edx
+ movl %ebx,%esi
+ roll $5,%ebx
+ pxor %xmm10,%xmm6
+ andl %edx,%edi
+ xorl %ebp,%edx
+ movdqa %xmm8,16(%rsp)
+ xorl %ebp,%edi
+ addl %ebx,%eax
+ movdqa %xmm6,%xmm9
+ movdqa %xmm6,%xmm10
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 40(%rsp),%ebp
+ xorl %edx,%ecx
+ pslldq $12,%xmm9
+ paddd %xmm6,%xmm6
+ movl %eax,%edi
+ roll $5,%eax
+ andl %ecx,%esi
+ xorl %edx,%ecx
+ psrld $31,%xmm10
+ xorl %edx,%esi
+ addl %eax,%ebp
+ movdqa %xmm9,%xmm8
+ rorl $7,%ebx
+ addl %esi,%ebp
+ psrld $30,%xmm9
+ por %xmm10,%xmm6
+ addl 44(%rsp),%edx
+ xorl %ecx,%ebx
+ movl %ebp,%esi
+ roll $5,%ebp
+ pslld $2,%xmm8
+ pxor %xmm9,%xmm6
+ andl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa 16(%r11),%xmm9
+ xorl %ecx,%edi
+ addl %ebp,%edx
+ pxor %xmm8,%xmm6
+ rorl $7,%eax
+ addl %edi,%edx
+ movdqa %xmm4,%xmm7
+ addl 48(%rsp),%ecx
+ xorl %ebx,%eax
+ movdqa %xmm6,%xmm8
+.byte 102,15,58,15,251,8
+ movl %edx,%edi
+ roll $5,%edx
+ paddd %xmm6,%xmm9
+ andl %eax,%esi
+ xorl %ebx,%eax
+ psrldq $4,%xmm8
+ xorl %ebx,%esi
+ addl %edx,%ecx
+ pxor %xmm3,%xmm7
+ rorl $7,%ebp
+ addl %esi,%ecx
+ pxor %xmm5,%xmm8
+ addl 52(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%esi
+ roll $5,%ecx
+ pxor %xmm8,%xmm7
+ andl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa %xmm9,32(%rsp)
+ xorl %eax,%edi
+ addl %ecx,%ebx
+ movdqa %xmm7,%xmm10
+ movdqa %xmm7,%xmm8
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 56(%rsp),%eax
+ xorl %ebp,%edx
+ pslldq $12,%xmm10
+ paddd %xmm7,%xmm7
+ movl %ebx,%edi
+ roll $5,%ebx
+ andl %edx,%esi
+ xorl %ebp,%edx
+ psrld $31,%xmm8
+ xorl %ebp,%esi
+ addl %ebx,%eax
+ movdqa %xmm10,%xmm9
+ rorl $7,%ecx
+ addl %esi,%eax
+ psrld $30,%xmm10
+ por %xmm8,%xmm7
+ addl 60(%rsp),%ebp
+ xorl %edx,%ecx
+ movl %eax,%esi
+ roll $5,%eax
+ pslld $2,%xmm9
+ pxor %xmm10,%xmm7
+ andl %ecx,%edi
+ xorl %edx,%ecx
+ movdqa 16(%r11),%xmm10
+ xorl %edx,%edi
+ addl %eax,%ebp
+ pxor %xmm9,%xmm7
+ rorl $7,%ebx
addl %edi,%ebp
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%r12d
- movl %eax,36(%rsp)
- addl %ebx,%ebp
- leal -1894007588(%rax,%rsi,1),%edi
- movl 40(%rsp),%eax
- movl %r11d,%ebx
- movl %r11d,%ecx
- xorl 48(%rsp),%eax
+ movdqa %xmm7,%xmm9
+ addl 0(%rsp),%edx
+ pxor %xmm4,%xmm0
+.byte 102,68,15,58,15,206,8
+ xorl %ecx,%ebx
+ movl %ebp,%edi
+ roll $5,%ebp
+ pxor %xmm1,%xmm0
+ andl %ebx,%esi
+ xorl %ecx,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm7,%xmm10
+ xorl %ecx,%esi
+ addl %ebp,%edx
+ pxor %xmm9,%xmm0
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 4(%rsp),%ecx
+ xorl %ebx,%eax
+ movdqa %xmm0,%xmm9
+ movdqa %xmm10,48(%rsp)
+ movl %edx,%esi
+ roll $5,%edx
+ andl %eax,%edi
+ xorl %ebx,%eax
+ pslld $2,%xmm0
+ xorl %ebx,%edi
+ addl %edx,%ecx
+ psrld $30,%xmm9
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 8(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%edi
+ roll $5,%ecx
+ por %xmm9,%xmm0
+ andl %ebp,%esi
+ xorl %eax,%ebp
+ movdqa %xmm0,%xmm10
+ xorl %eax,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 12(%rsp),%eax
+ xorl %ebp,%edx
+ movl %ebx,%esi
+ roll $5,%ebx
+ andl %edx,%edi
+ xorl %ebp,%edx
+ xorl %ebp,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 16(%rsp),%ebp
+ pxor %xmm5,%xmm1
+.byte 102,68,15,58,15,215,8
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ pxor %xmm2,%xmm1
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ movdqa %xmm8,%xmm9
+ paddd %xmm0,%xmm8
+ rorl $7,%ebx
+ addl %esi,%ebp
+ pxor %xmm10,%xmm1
+ addl 20(%rsp),%edx
+ xorl %ecx,%edi
movl %ebp,%esi
- andl %r12d,%ebx
- xorl 8(%rsp),%eax
- orl %r12d,%ecx
- roll $5,%esi
- xorl 28(%rsp),%eax
- andl %edx,%ecx
- addl %esi,%edi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%r11d
- movl %eax,40(%rsp)
- addl %ebx,%edi
- leal -1894007588(%rax,%rdx,1),%esi
- movl 44(%rsp),%eax
- movl %ebp,%ebx
- movl %ebp,%ecx
- xorl 52(%rsp),%eax
- movl %edi,%edx
- andl %r11d,%ebx
- xorl 12(%rsp),%eax
- orl %r11d,%ecx
+ roll $5,%ebp
+ movdqa %xmm1,%xmm10
+ movdqa %xmm8,0(%rsp)
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ pslld $2,%xmm1
+ addl 24(%rsp),%ecx
+ xorl %ebx,%esi
+ psrld $30,%xmm10
+ movl %edx,%edi
roll $5,%edx
- xorl 32(%rsp),%eax
- andl %r12d,%ecx
- addl %edx,%esi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%ebp
- movl %eax,44(%rsp)
- addl %ebx,%esi
- leal -1894007588(%rax,%r12,1),%edx
- movl 48(%rsp),%eax
- movl %edi,%ebx
- movl %edi,%ecx
- xorl 56(%rsp),%eax
- movl %esi,%r12d
- andl %ebp,%ebx
- xorl 16(%rsp),%eax
- orl %ebp,%ecx
- roll $5,%r12d
- xorl 36(%rsp),%eax
- andl %r11d,%ecx
- addl %r12d,%edx
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edi
- movl %eax,48(%rsp)
- addl %ebx,%edx
- leal -899497514(%rax,%r11,1),%r12d
- movl 52(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 60(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 20(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 40(%rsp),%eax
- roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- movl %eax,52(%rsp)
- leal -899497514(%rax,%rbp,1),%r11d
- movl 56(%rsp),%eax
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl 0(%rsp),%eax
- xorl %edx,%ebx
+ xorl %eax,%esi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ por %xmm10,%xmm1
+ addl 28(%rsp),%ebx
+ xorl %eax,%edi
+ movdqa %xmm1,%xmm8
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 32(%rsp),%eax
+ pxor %xmm6,%xmm2
+.byte 102,68,15,58,15,192,8
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ pxor %xmm3,%xmm2
+ xorl %edx,%esi
+ addl %ebx,%eax
+ movdqa 32(%r11),%xmm10
+ paddd %xmm1,%xmm9
+ rorl $7,%ecx
+ addl %esi,%eax
+ pxor %xmm8,%xmm2
+ addl 36(%rsp),%ebp
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ movdqa %xmm2,%xmm8
+ movdqa %xmm9,16(%rsp)
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ pslld $2,%xmm2
+ addl 40(%rsp),%edx
+ xorl %ecx,%esi
+ psrld $30,%xmm8
+ movl %ebp,%edi
roll $5,%ebp
- xorl 24(%rsp),%eax
- xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 44(%rsp),%eax
- roll $30,%edx
- addl %ebx,%r11d
- roll $1,%eax
- movl %eax,56(%rsp)
- leal -899497514(%rax,%rdi,1),%ebp
- movl 60(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 4(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 28(%rsp),%eax
- xorl %esi,%ebx
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ por %xmm8,%xmm2
+ addl 44(%rsp),%ecx
+ xorl %ebx,%edi
+ movdqa %xmm2,%xmm9
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 48(%rsp),%ebx
+ pxor %xmm7,%xmm3
+.byte 102,68,15,58,15,201,8
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ pxor %xmm4,%xmm3
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm2,%xmm10
+ rorl $7,%edx
+ addl %esi,%ebx
+ pxor %xmm9,%xmm3
+ addl 52(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ movdqa %xmm3,%xmm9
+ movdqa %xmm10,32(%rsp)
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ pslld $2,%xmm3
+ addl 56(%rsp),%ebp
+ xorl %edx,%esi
+ psrld $30,%xmm9
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ por %xmm9,%xmm3
+ addl 60(%rsp),%edx
+ xorl %ecx,%edi
+ movdqa %xmm3,%xmm10
+ movl %ebp,%esi
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 0(%rsp),%ecx
+ pxor %xmm0,%xmm4
+.byte 102,68,15,58,15,210,8
+ xorl %ebx,%esi
+ movl %edx,%edi
+ roll $5,%edx
+ pxor %xmm5,%xmm4
+ xorl %eax,%esi
+ addl %edx,%ecx
+ movdqa %xmm8,%xmm9
+ paddd %xmm3,%xmm8
+ rorl $7,%ebp
+ addl %esi,%ecx
+ pxor %xmm10,%xmm4
+ addl 4(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ movdqa %xmm4,%xmm10
+ movdqa %xmm8,48(%rsp)
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ pslld $2,%xmm4
+ addl 8(%rsp),%eax
+ xorl %ebp,%esi
+ psrld $30,%xmm10
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ por %xmm10,%xmm4
+ addl 12(%rsp),%ebp
+ xorl %edx,%edi
+ movdqa %xmm4,%xmm8
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
addl %edi,%ebp
- xorl 48(%rsp),%eax
- roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,60(%rsp)
- leal -899497514(%rax,%rsi,1),%edi
- movl 0(%rsp),%eax
- movl %r12d,%ebx
+ addl 16(%rsp),%edx
+ pxor %xmm1,%xmm5
+.byte 102,68,15,58,15,195,8
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ pxor %xmm6,%xmm5
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ movdqa %xmm9,%xmm10
+ paddd %xmm4,%xmm9
+ rorl $7,%eax
+ addl %esi,%edx
+ pxor %xmm8,%xmm5
+ addl 20(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ movdqa %xmm5,%xmm8
+ movdqa %xmm9,0(%rsp)
+ xorl %eax,%edi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ pslld $2,%xmm5
+ addl 24(%rsp),%ebx
+ xorl %eax,%esi
+ psrld $30,%xmm8
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ por %xmm8,%xmm5
+ addl 28(%rsp),%eax
+ xorl %ebp,%edi
+ movdqa %xmm5,%xmm9
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ movl %ecx,%edi
+ pxor %xmm2,%xmm6
+.byte 102,68,15,58,15,204,8
+ xorl %edx,%ecx
+ addl 32(%rsp),%ebp
+ andl %edx,%edi
+ pxor %xmm7,%xmm6
+ andl %ecx,%esi
+ rorl $7,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm5,%xmm10
+ addl %edi,%ebp
+ movl %eax,%edi
+ pxor %xmm9,%xmm6
+ roll $5,%eax
+ addl %esi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movdqa %xmm6,%xmm9
+ movdqa %xmm10,16(%rsp)
+ movl %ebx,%esi
+ xorl %ecx,%ebx
+ addl 36(%rsp),%edx
+ andl %ecx,%esi
+ pslld $2,%xmm6
+ andl %ebx,%edi
+ rorl $7,%eax
+ psrld $30,%xmm9
+ addl %esi,%edx
movl %ebp,%esi
- xorl 8(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 32(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 52(%rsp),%eax
- roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,0(%rsp)
- leal -899497514(%rax,%rdx,1),%esi
- movl 4(%rsp),%eax
- movl %r11d,%ebx
- movl %edi,%edx
- xorl 12(%rsp),%eax
- xorl %ebp,%ebx
+ roll $5,%ebp
+ addl %edi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ por %xmm9,%xmm6
+ movl %eax,%edi
+ xorl %ebx,%eax
+ movdqa %xmm6,%xmm10
+ addl 40(%rsp),%ecx
+ andl %ebx,%edi
+ andl %eax,%esi
+ rorl $7,%ebp
+ addl %edi,%ecx
+ movl %edx,%edi
roll $5,%edx
- xorl 36(%rsp),%eax
- xorl %r12d,%ebx
- addl %edx,%esi
- xorl 56(%rsp),%eax
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- movl %eax,4(%rsp)
- leal -899497514(%rax,%r12,1),%edx
- movl 8(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 16(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 40(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 60(%rsp),%eax
- roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,8(%rsp)
- leal -899497514(%rax,%r11,1),%r12d
- movl 12(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 20(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 44(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 0(%rsp),%eax
- roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- movl %eax,12(%rsp)
- leal -899497514(%rax,%rbp,1),%r11d
- movl 16(%rsp),%eax
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl 24(%rsp),%eax
- xorl %edx,%ebx
+ addl %esi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movl %ebp,%esi
+ xorl %eax,%ebp
+ addl 44(%rsp),%ebx
+ andl %eax,%esi
+ andl %ebp,%edi
+ rorl $7,%edx
+ addl %esi,%ebx
+ movl %ecx,%esi
+ roll $5,%ecx
+ addl %edi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movl %edx,%edi
+ pxor %xmm3,%xmm7
+.byte 102,68,15,58,15,213,8
+ xorl %ebp,%edx
+ addl 48(%rsp),%eax
+ andl %ebp,%edi
+ pxor %xmm0,%xmm7
+ andl %edx,%esi
+ rorl $7,%ecx
+ movdqa 48(%r11),%xmm9
+ paddd %xmm6,%xmm8
+ addl %edi,%eax
+ movl %ebx,%edi
+ pxor %xmm10,%xmm7
+ roll $5,%ebx
+ addl %esi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ movdqa %xmm7,%xmm10
+ movdqa %xmm8,32(%rsp)
+ movl %ecx,%esi
+ xorl %edx,%ecx
+ addl 52(%rsp),%ebp
+ andl %edx,%esi
+ pslld $2,%xmm7
+ andl %ecx,%edi
+ rorl $7,%ebx
+ psrld $30,%xmm10
+ addl %esi,%ebp
+ movl %eax,%esi
+ roll $5,%eax
+ addl %edi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ por %xmm10,%xmm7
+ movl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa %xmm7,%xmm8
+ addl 56(%rsp),%edx
+ andl %ecx,%edi
+ andl %ebx,%esi
+ rorl $7,%eax
+ addl %edi,%edx
+ movl %ebp,%edi
roll $5,%ebp
- xorl 48(%rsp),%eax
- xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 4(%rsp),%eax
- roll $30,%edx
- addl %ebx,%r11d
- roll $1,%eax
- movl %eax,16(%rsp)
- leal -899497514(%rax,%rdi,1),%ebp
- movl 20(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 28(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 52(%rsp),%eax
- xorl %esi,%ebx
+ addl %esi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movl %eax,%esi
+ xorl %ebx,%eax
+ addl 60(%rsp),%ecx
+ andl %ebx,%esi
+ andl %eax,%edi
+ rorl $7,%ebp
+ addl %esi,%ecx
+ movl %edx,%esi
+ roll $5,%edx
+ addl %edi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movl %ebp,%edi
+ pxor %xmm4,%xmm0
+.byte 102,68,15,58,15,198,8
+ xorl %eax,%ebp
+ addl 0(%rsp),%ebx
+ andl %eax,%edi
+ pxor %xmm1,%xmm0
+ andl %ebp,%esi
+ rorl $7,%edx
+ movdqa %xmm9,%xmm10
+ paddd %xmm7,%xmm9
+ addl %edi,%ebx
+ movl %ecx,%edi
+ pxor %xmm8,%xmm0
+ roll $5,%ecx
+ addl %esi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movdqa %xmm0,%xmm8
+ movdqa %xmm9,48(%rsp)
+ movl %edx,%esi
+ xorl %ebp,%edx
+ addl 4(%rsp),%eax
+ andl %ebp,%esi
+ pslld $2,%xmm0
+ andl %edx,%edi
+ rorl $7,%ecx
+ psrld $30,%xmm8
+ addl %esi,%eax
+ movl %ebx,%esi
+ roll $5,%ebx
+ addl %edi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ por %xmm8,%xmm0
+ movl %ecx,%edi
+ xorl %edx,%ecx
+ movdqa %xmm0,%xmm9
+ addl 8(%rsp),%ebp
+ andl %edx,%edi
+ andl %ecx,%esi
+ rorl $7,%ebx
addl %edi,%ebp
- xorl 8(%rsp),%eax
- roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,20(%rsp)
- leal -899497514(%rax,%rsi,1),%edi
- movl 24(%rsp),%eax
- movl %r12d,%ebx
+ movl %eax,%edi
+ roll $5,%eax
+ addl %esi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movl %ebx,%esi
+ xorl %ecx,%ebx
+ addl 12(%rsp),%edx
+ andl %ecx,%esi
+ andl %ebx,%edi
+ rorl $7,%eax
+ addl %esi,%edx
movl %ebp,%esi
- xorl 32(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 56(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 12(%rsp),%eax
- roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,24(%rsp)
- leal -899497514(%rax,%rdx,1),%esi
- movl 28(%rsp),%eax
- movl %r11d,%ebx
- movl %edi,%edx
- xorl 36(%rsp),%eax
- xorl %ebp,%ebx
+ roll $5,%ebp
+ addl %edi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movl %eax,%edi
+ pxor %xmm5,%xmm1
+.byte 102,68,15,58,15,207,8
+ xorl %ebx,%eax
+ addl 16(%rsp),%ecx
+ andl %ebx,%edi
+ pxor %xmm2,%xmm1
+ andl %eax,%esi
+ rorl $7,%ebp
+ movdqa %xmm10,%xmm8
+ paddd %xmm0,%xmm10
+ addl %edi,%ecx
+ movl %edx,%edi
+ pxor %xmm9,%xmm1
roll $5,%edx
- xorl 60(%rsp),%eax
- xorl %r12d,%ebx
- addl %edx,%esi
- xorl 16(%rsp),%eax
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- movl %eax,28(%rsp)
- leal -899497514(%rax,%r12,1),%edx
- movl 32(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 40(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 0(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 20(%rsp),%eax
- roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,32(%rsp)
- leal -899497514(%rax,%r11,1),%r12d
- movl 36(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 44(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 4(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 24(%rsp),%eax
- roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- movl %eax,36(%rsp)
- leal -899497514(%rax,%rbp,1),%r11d
- movl 40(%rsp),%eax
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl 48(%rsp),%eax
- xorl %edx,%ebx
+ addl %esi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movdqa %xmm1,%xmm9
+ movdqa %xmm10,0(%rsp)
+ movl %ebp,%esi
+ xorl %eax,%ebp
+ addl 20(%rsp),%ebx
+ andl %eax,%esi
+ pslld $2,%xmm1
+ andl %ebp,%edi
+ rorl $7,%edx
+ psrld $30,%xmm9
+ addl %esi,%ebx
+ movl %ecx,%esi
+ roll $5,%ecx
+ addl %edi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ por %xmm9,%xmm1
+ movl %edx,%edi
+ xorl %ebp,%edx
+ movdqa %xmm1,%xmm10
+ addl 24(%rsp),%eax
+ andl %ebp,%edi
+ andl %edx,%esi
+ rorl $7,%ecx
+ addl %edi,%eax
+ movl %ebx,%edi
+ roll $5,%ebx
+ addl %esi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ movl %ecx,%esi
+ xorl %edx,%ecx
+ addl 28(%rsp),%ebp
+ andl %edx,%esi
+ andl %ecx,%edi
+ rorl $7,%ebx
+ addl %esi,%ebp
+ movl %eax,%esi
+ roll $5,%eax
+ addl %edi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movl %ebx,%edi
+ pxor %xmm6,%xmm2
+.byte 102,68,15,58,15,208,8
+ xorl %ecx,%ebx
+ addl 32(%rsp),%edx
+ andl %ecx,%edi
+ pxor %xmm3,%xmm2
+ andl %ebx,%esi
+ rorl $7,%eax
+ movdqa %xmm8,%xmm9
+ paddd %xmm1,%xmm8
+ addl %edi,%edx
+ movl %ebp,%edi
+ pxor %xmm10,%xmm2
roll $5,%ebp
- xorl 8(%rsp),%eax
- xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 28(%rsp),%eax
- roll $30,%edx
- addl %ebx,%r11d
- roll $1,%eax
- movl %eax,40(%rsp)
- leal -899497514(%rax,%rdi,1),%ebp
- movl 44(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 52(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 12(%rsp),%eax
- xorl %esi,%ebx
+ addl %esi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movdqa %xmm2,%xmm10
+ movdqa %xmm8,16(%rsp)
+ movl %eax,%esi
+ xorl %ebx,%eax
+ addl 36(%rsp),%ecx
+ andl %ebx,%esi
+ pslld $2,%xmm2
+ andl %eax,%edi
+ rorl $7,%ebp
+ psrld $30,%xmm10
+ addl %esi,%ecx
+ movl %edx,%esi
+ roll $5,%edx
+ addl %edi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ por %xmm10,%xmm2
+ movl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa %xmm2,%xmm8
+ addl 40(%rsp),%ebx
+ andl %eax,%edi
+ andl %ebp,%esi
+ rorl $7,%edx
+ addl %edi,%ebx
+ movl %ecx,%edi
+ roll $5,%ecx
+ addl %esi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movl %edx,%esi
+ xorl %ebp,%edx
+ addl 44(%rsp),%eax
+ andl %ebp,%esi
+ andl %edx,%edi
+ rorl $7,%ecx
+ addl %esi,%eax
+ movl %ebx,%esi
+ roll $5,%ebx
+ addl %edi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ addl 48(%rsp),%ebp
+ pxor %xmm7,%xmm3
+.byte 102,68,15,58,15,193,8
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ pxor %xmm4,%xmm3
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ movdqa %xmm9,%xmm10
+ paddd %xmm2,%xmm9
+ rorl $7,%ebx
+ addl %esi,%ebp
+ pxor %xmm8,%xmm3
+ addl 52(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ movdqa %xmm3,%xmm8
+ movdqa %xmm9,32(%rsp)
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ pslld $2,%xmm3
+ addl 56(%rsp),%ecx
+ xorl %ebx,%esi
+ psrld $30,%xmm8
+ movl %edx,%edi
+ roll $5,%edx
+ xorl %eax,%esi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ por %xmm8,%xmm3
+ addl 60(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 0(%rsp),%eax
+ paddd %xmm3,%xmm10
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ movdqa %xmm10,48(%rsp)
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 4(%rsp),%ebp
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
addl %edi,%ebp
- xorl 32(%rsp),%eax
- roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,44(%rsp)
- leal -899497514(%rax,%rsi,1),%edi
- movl 48(%rsp),%eax
- movl %r12d,%ebx
+ addl 8(%rsp),%edx
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 12(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ cmpq %r10,%r9
+ je .Ldone_ssse3
+ movdqa 64(%r11),%xmm6
+ movdqa 0(%r11),%xmm9
+ movdqu 0(%r9),%xmm0
+ movdqu 16(%r9),%xmm1
+ movdqu 32(%r9),%xmm2
+ movdqu 48(%r9),%xmm3
+.byte 102,15,56,0,198
+ addq $64,%r9
+ addl 16(%rsp),%ebx
+ xorl %eax,%esi
+.byte 102,15,56,0,206
+ movl %ecx,%edi
+ roll $5,%ecx
+ paddd %xmm9,%xmm0
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ movdqa %xmm0,0(%rsp)
+ addl 20(%rsp),%eax
+ xorl %ebp,%edi
+ psubd %xmm9,%xmm0
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 24(%rsp),%ebp
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ addl 28(%rsp),%edx
+ xorl %ecx,%edi
movl %ebp,%esi
- xorl 56(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 16(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 36(%rsp),%eax
- roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,48(%rsp)
- leal -899497514(%rax,%rdx,1),%esi
- movl 52(%rsp),%eax
- movl %r11d,%ebx
- movl %edi,%edx
- xorl 60(%rsp),%eax
- xorl %ebp,%ebx
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 32(%rsp),%ecx
+ xorl %ebx,%esi
+.byte 102,15,56,0,214
+ movl %edx,%edi
roll $5,%edx
- xorl 20(%rsp),%eax
- xorl %r12d,%ebx
- addl %edx,%esi
- xorl 40(%rsp),%eax
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- leal -899497514(%rax,%r12,1),%edx
- movl 56(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 0(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 24(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 44(%rsp),%eax
- roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- leal -899497514(%rax,%r11,1),%r12d
- movl 60(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 4(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 28(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 48(%rsp),%eax
- roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- leal -899497514(%rax,%rbp,1),%r11d
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl %edx,%ebx
+ paddd %xmm9,%xmm1
+ xorl %eax,%esi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ movdqa %xmm1,16(%rsp)
+ addl 36(%rsp),%ebx
+ xorl %eax,%edi
+ psubd %xmm9,%xmm1
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 40(%rsp),%eax
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 44(%rsp),%ebp
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 48(%rsp),%edx
+ xorl %ecx,%esi
+.byte 102,15,56,0,222
+ movl %ebp,%edi
roll $5,%ebp
- xorl %edi,%ebx
- addl %ebp,%r11d
- roll $30,%edx
- addl %ebx,%r11d
- addl 0(%r8),%r11d
- addl 4(%r8),%r12d
- addl 8(%r8),%edx
- addl 12(%r8),%esi
- addl 16(%r8),%edi
- movl %r11d,0(%r8)
- movl %r12d,4(%r8)
- movl %edx,8(%r8)
- movl %esi,12(%r8)
- movl %edi,16(%r8)
-
- xchgl %r11d,%edx
- xchgl %r12d,%esi
- xchgl %r11d,%edi
- xchgl %r12d,%ebp
+ paddd %xmm9,%xmm2
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ movdqa %xmm2,32(%rsp)
+ addl 52(%rsp),%ecx
+ xorl %ebx,%edi
+ psubd %xmm9,%xmm2
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 56(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 60(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 0(%r8),%eax
+ addl 4(%r8),%esi
+ addl 8(%r8),%ecx
+ addl 12(%r8),%edx
+ movl %eax,0(%r8)
+ addl 16(%r8),%ebp
+ movl %esi,4(%r8)
+ movl %esi,%ebx
+ movl %ecx,8(%r8)
+ movl %edx,12(%r8)
+ movl %ebp,16(%r8)
+ jmp .Loop_ssse3
- leaq 64(%r9),%r9
- subq $1,%r10
- jnz .Lloop
- movq 64(%rsp),%rsi
- movq (%rsi),%r12
+.align 16
+.Ldone_ssse3:
+ addl 16(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 20(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 24(%rsp),%ebp
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ addl 28(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 32(%rsp),%ecx
+ xorl %ebx,%esi
+ movl %edx,%edi
+ roll $5,%edx
+ xorl %eax,%esi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ addl 36(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 40(%rsp),%eax
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 44(%rsp),%ebp
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 48(%rsp),%edx
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 52(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 56(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 60(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 0(%r8),%eax
+ addl 4(%r8),%esi
+ addl 8(%r8),%ecx
+ movl %eax,0(%r8)
+ addl 12(%r8),%edx
+ movl %esi,4(%r8)
+ addl 16(%r8),%ebp
+ movl %ecx,8(%r8)
+ movl %edx,12(%r8)
+ movl %ebp,16(%r8)
+ leaq 64(%rsp),%rsi
+ movq 0(%rsi),%r12
movq 8(%rsi),%rbp
movq 16(%rsi),%rbx
leaq 24(%rsi),%rsp
-.Lepilogue:
+.Lepilogue_ssse3:
.byte 0xf3,0xc3
-.size sha1_block_data_order,.-sha1_block_data_order
+.size sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3
+.align 64
+K_XX_XX:
+.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999
+
+.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1
+
+.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc
+
+.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6
+
+.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
+
.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-.align 16
+.align 64
diff --git a/deps/openssl/asm/x64-elf-gas/sha/sha512-x86_64.s b/deps/openssl/asm/x64-elf-gas/sha/sha512-x86_64.s
index ddf7b907a..576d7d8bf 100644
--- a/deps/openssl/asm/x64-elf-gas/sha/sha512-x86_64.s
+++ b/deps/openssl/asm/x64-elf-gas/sha/sha512-x86_64.s
@@ -38,1880 +38,1688 @@ sha256_block_data_order:
.Lloop:
xorq %rdi,%rdi
movl 0(%rsi),%r12d
- bswapl %r12d
movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %eax,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r9d,%r15d
+ movl %r12d,0(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r11d,%r12d
+ xorl %eax,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r8d,%r15d
- movl %r12d,0(%rsp)
+ movl %ebx,%r11d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- addl %r11d,%r12d
-
- movl %eax,%r11d
- addl %r13d,%r12d
+ xorl %ecx,%r11d
+ xorl %eax,%r14d
addl %r15d,%r12d
- movl %eax,%r13d
- movl %eax,%r14d
+ movl %ebx,%r15d
- rorl $2,%r11d
- rorl $13,%r13d
- movl %eax,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %eax,%r11d
+ andl %ecx,%r15d
- xorl %r13d,%r11d
- rorl $9,%r13d
- orl %ecx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r11d
- xorl %r13d,%r11d
- andl %ecx,%r15d
addl %r12d,%edx
-
- andl %ebx,%r14d
addl %r12d,%r11d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r11d
+
movl 4(%rsi),%r12d
- bswapl %r12d
movl %edx,%r13d
- movl %edx,%r14d
+ movl %r11d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r8d,%r15d
+ movl %r12d,4(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r10d,%r12d
+ xorl %r11d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %edx,%r15d
- movl %r12d,4(%rsp)
+ movl %eax,%r10d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- addl %r10d,%r12d
-
- movl %r11d,%r10d
- addl %r13d,%r12d
+ xorl %ebx,%r10d
+ xorl %r11d,%r14d
addl %r15d,%r12d
- movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %eax,%r15d
- rorl $2,%r10d
- rorl $13,%r13d
- movl %r11d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r11d,%r10d
+ andl %ebx,%r15d
- xorl %r13d,%r10d
- rorl $9,%r13d
- orl %ebx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r10d
- xorl %r13d,%r10d
- andl %ebx,%r15d
addl %r12d,%ecx
-
- andl %eax,%r14d
addl %r12d,%r10d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r10d
+
movl 8(%rsi),%r12d
- bswapl %r12d
movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %r10d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %edx,%r15d
+ movl %r12d,8(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r9d,%r12d
+ xorl %r10d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ecx,%r15d
- movl %r12d,8(%rsp)
+ movl %r11d,%r9d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- addl %r9d,%r12d
-
- movl %r10d,%r9d
- addl %r13d,%r12d
+ xorl %eax,%r9d
+ xorl %r10d,%r14d
addl %r15d,%r12d
- movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %r11d,%r15d
- rorl $2,%r9d
- rorl $13,%r13d
- movl %r10d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r10d,%r9d
+ andl %eax,%r15d
- xorl %r13d,%r9d
- rorl $9,%r13d
- orl %eax,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r9d
- xorl %r13d,%r9d
- andl %eax,%r15d
addl %r12d,%ebx
-
- andl %r11d,%r14d
addl %r12d,%r9d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r9d
+
movl 12(%rsi),%r12d
- bswapl %r12d
movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %r9d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %ecx,%r15d
+ movl %r12d,12(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r8d,%r12d
+ xorl %r9d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ebx,%r15d
- movl %r12d,12(%rsp)
+ movl %r10d,%r8d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- addl %r8d,%r12d
-
- movl %r9d,%r8d
- addl %r13d,%r12d
+ xorl %r11d,%r8d
+ xorl %r9d,%r14d
addl %r15d,%r12d
- movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %r10d,%r15d
- rorl $2,%r8d
- rorl $13,%r13d
- movl %r9d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r9d,%r8d
+ andl %r11d,%r15d
- xorl %r13d,%r8d
- rorl $9,%r13d
- orl %r11d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r8d
- xorl %r13d,%r8d
- andl %r11d,%r15d
addl %r12d,%eax
-
- andl %r10d,%r14d
addl %r12d,%r8d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r8d
+
movl 16(%rsi),%r12d
- bswapl %r12d
movl %eax,%r13d
- movl %eax,%r14d
+ movl %r8d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %ebx,%r15d
+ movl %r12d,16(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %edx,%r12d
+ xorl %r8d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %eax,%r15d
- movl %r12d,16(%rsp)
+ movl %r9d,%edx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- addl %edx,%r12d
-
- movl %r8d,%edx
- addl %r13d,%r12d
+ xorl %r10d,%edx
+ xorl %r8d,%r14d
addl %r15d,%r12d
- movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %r9d,%r15d
- rorl $2,%edx
- rorl $13,%r13d
- movl %r8d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r8d,%edx
+ andl %r10d,%r15d
- xorl %r13d,%edx
- rorl $9,%r13d
- orl %r10d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%edx
- xorl %r13d,%edx
- andl %r10d,%r15d
addl %r12d,%r11d
-
- andl %r9d,%r14d
addl %r12d,%edx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%edx
+
movl 20(%rsi),%r12d
- bswapl %r12d
movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %edx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %eax,%r15d
+ movl %r12d,20(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ecx,%r12d
+ xorl %edx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r11d,%r15d
- movl %r12d,20(%rsp)
+ movl %r8d,%ecx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- addl %ecx,%r12d
-
- movl %edx,%ecx
- addl %r13d,%r12d
+ xorl %r9d,%ecx
+ xorl %edx,%r14d
addl %r15d,%r12d
- movl %edx,%r13d
- movl %edx,%r14d
+ movl %r8d,%r15d
- rorl $2,%ecx
- rorl $13,%r13d
- movl %edx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %edx,%ecx
+ andl %r9d,%r15d
- xorl %r13d,%ecx
- rorl $9,%r13d
- orl %r9d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ecx
- xorl %r13d,%ecx
- andl %r9d,%r15d
addl %r12d,%r10d
-
- andl %r8d,%r14d
addl %r12d,%ecx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ecx
+
movl 24(%rsi),%r12d
- bswapl %r12d
movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %ecx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r11d,%r15d
+ movl %r12d,24(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ebx,%r12d
+ xorl %ecx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r10d,%r15d
- movl %r12d,24(%rsp)
+ movl %edx,%ebx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- addl %ebx,%r12d
-
- movl %ecx,%ebx
- addl %r13d,%r12d
+ xorl %r8d,%ebx
+ xorl %ecx,%r14d
addl %r15d,%r12d
- movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %edx,%r15d
- rorl $2,%ebx
- rorl $13,%r13d
- movl %ecx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ecx,%ebx
+ andl %r8d,%r15d
- xorl %r13d,%ebx
- rorl $9,%r13d
- orl %r8d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ebx
- xorl %r13d,%ebx
- andl %r8d,%r15d
addl %r12d,%r9d
-
- andl %edx,%r14d
addl %r12d,%ebx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ebx
+
movl 28(%rsi),%r12d
- bswapl %r12d
movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %ebx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r10d,%r15d
+ movl %r12d,28(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %eax,%r12d
+ xorl %ebx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r9d,%r15d
- movl %r12d,28(%rsp)
+ movl %ecx,%eax
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- addl %eax,%r12d
-
- movl %ebx,%eax
- addl %r13d,%r12d
+ xorl %edx,%eax
+ xorl %ebx,%r14d
addl %r15d,%r12d
- movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %ecx,%r15d
- rorl $2,%eax
- rorl $13,%r13d
- movl %ebx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ebx,%eax
+ andl %edx,%r15d
- xorl %r13d,%eax
- rorl $9,%r13d
- orl %edx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%eax
- xorl %r13d,%eax
- andl %edx,%r15d
addl %r12d,%r8d
-
- andl %ecx,%r14d
addl %r12d,%eax
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%eax
+
movl 32(%rsi),%r12d
- bswapl %r12d
movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %eax,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r9d,%r15d
+ movl %r12d,32(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r11d,%r12d
+ xorl %eax,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r8d,%r15d
- movl %r12d,32(%rsp)
+ movl %ebx,%r11d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- addl %r11d,%r12d
-
- movl %eax,%r11d
- addl %r13d,%r12d
+ xorl %ecx,%r11d
+ xorl %eax,%r14d
addl %r15d,%r12d
- movl %eax,%r13d
- movl %eax,%r14d
+ movl %ebx,%r15d
- rorl $2,%r11d
- rorl $13,%r13d
- movl %eax,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %eax,%r11d
+ andl %ecx,%r15d
- xorl %r13d,%r11d
- rorl $9,%r13d
- orl %ecx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r11d
- xorl %r13d,%r11d
- andl %ecx,%r15d
addl %r12d,%edx
-
- andl %ebx,%r14d
addl %r12d,%r11d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r11d
+
movl 36(%rsi),%r12d
- bswapl %r12d
movl %edx,%r13d
- movl %edx,%r14d
+ movl %r11d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r8d,%r15d
+ movl %r12d,36(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r10d,%r12d
+ xorl %r11d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %edx,%r15d
- movl %r12d,36(%rsp)
+ movl %eax,%r10d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- addl %r10d,%r12d
-
- movl %r11d,%r10d
- addl %r13d,%r12d
+ xorl %ebx,%r10d
+ xorl %r11d,%r14d
addl %r15d,%r12d
- movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %eax,%r15d
- rorl $2,%r10d
- rorl $13,%r13d
- movl %r11d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r11d,%r10d
+ andl %ebx,%r15d
- xorl %r13d,%r10d
- rorl $9,%r13d
- orl %ebx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r10d
- xorl %r13d,%r10d
- andl %ebx,%r15d
addl %r12d,%ecx
-
- andl %eax,%r14d
addl %r12d,%r10d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r10d
+
movl 40(%rsi),%r12d
- bswapl %r12d
movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %r10d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %edx,%r15d
+ movl %r12d,40(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r9d,%r12d
+ xorl %r10d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ecx,%r15d
- movl %r12d,40(%rsp)
+ movl %r11d,%r9d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- addl %r9d,%r12d
-
- movl %r10d,%r9d
- addl %r13d,%r12d
+ xorl %eax,%r9d
+ xorl %r10d,%r14d
addl %r15d,%r12d
- movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %r11d,%r15d
- rorl $2,%r9d
- rorl $13,%r13d
- movl %r10d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r10d,%r9d
+ andl %eax,%r15d
- xorl %r13d,%r9d
- rorl $9,%r13d
- orl %eax,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r9d
- xorl %r13d,%r9d
- andl %eax,%r15d
addl %r12d,%ebx
-
- andl %r11d,%r14d
addl %r12d,%r9d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r9d
+
movl 44(%rsi),%r12d
- bswapl %r12d
movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %r9d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %ecx,%r15d
+ movl %r12d,44(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r8d,%r12d
+ xorl %r9d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ebx,%r15d
- movl %r12d,44(%rsp)
+ movl %r10d,%r8d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- addl %r8d,%r12d
-
- movl %r9d,%r8d
- addl %r13d,%r12d
+ xorl %r11d,%r8d
+ xorl %r9d,%r14d
addl %r15d,%r12d
- movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %r10d,%r15d
- rorl $2,%r8d
- rorl $13,%r13d
- movl %r9d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r9d,%r8d
+ andl %r11d,%r15d
- xorl %r13d,%r8d
- rorl $9,%r13d
- orl %r11d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r8d
- xorl %r13d,%r8d
- andl %r11d,%r15d
addl %r12d,%eax
-
- andl %r10d,%r14d
addl %r12d,%r8d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r8d
+
movl 48(%rsi),%r12d
- bswapl %r12d
movl %eax,%r13d
- movl %eax,%r14d
+ movl %r8d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %ebx,%r15d
+ movl %r12d,48(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %edx,%r12d
+ xorl %r8d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %eax,%r15d
- movl %r12d,48(%rsp)
+ movl %r9d,%edx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- addl %edx,%r12d
-
- movl %r8d,%edx
- addl %r13d,%r12d
+ xorl %r10d,%edx
+ xorl %r8d,%r14d
addl %r15d,%r12d
- movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %r9d,%r15d
- rorl $2,%edx
- rorl $13,%r13d
- movl %r8d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r8d,%edx
+ andl %r10d,%r15d
- xorl %r13d,%edx
- rorl $9,%r13d
- orl %r10d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%edx
- xorl %r13d,%edx
- andl %r10d,%r15d
addl %r12d,%r11d
-
- andl %r9d,%r14d
addl %r12d,%edx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%edx
+
movl 52(%rsi),%r12d
- bswapl %r12d
movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %edx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %eax,%r15d
+ movl %r12d,52(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ecx,%r12d
+ xorl %edx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r11d,%r15d
- movl %r12d,52(%rsp)
+ movl %r8d,%ecx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- addl %ecx,%r12d
-
- movl %edx,%ecx
- addl %r13d,%r12d
+ xorl %r9d,%ecx
+ xorl %edx,%r14d
addl %r15d,%r12d
- movl %edx,%r13d
- movl %edx,%r14d
+ movl %r8d,%r15d
- rorl $2,%ecx
- rorl $13,%r13d
- movl %edx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %edx,%ecx
+ andl %r9d,%r15d
- xorl %r13d,%ecx
- rorl $9,%r13d
- orl %r9d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ecx
- xorl %r13d,%ecx
- andl %r9d,%r15d
addl %r12d,%r10d
-
- andl %r8d,%r14d
addl %r12d,%ecx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ecx
+
movl 56(%rsi),%r12d
- bswapl %r12d
movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %ecx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r11d,%r15d
+ movl %r12d,56(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ebx,%r12d
+ xorl %ecx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r10d,%r15d
- movl %r12d,56(%rsp)
+ movl %edx,%ebx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- addl %ebx,%r12d
-
- movl %ecx,%ebx
- addl %r13d,%r12d
+ xorl %r8d,%ebx
+ xorl %ecx,%r14d
addl %r15d,%r12d
- movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %edx,%r15d
- rorl $2,%ebx
- rorl $13,%r13d
- movl %ecx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ecx,%ebx
+ andl %r8d,%r15d
- xorl %r13d,%ebx
- rorl $9,%r13d
- orl %r8d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ebx
- xorl %r13d,%ebx
- andl %r8d,%r15d
addl %r12d,%r9d
-
- andl %edx,%r14d
addl %r12d,%ebx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ebx
+
movl 60(%rsi),%r12d
- bswapl %r12d
movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %ebx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r10d,%r15d
+ movl %r12d,60(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %eax,%r12d
+ xorl %ebx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r9d,%r15d
- movl %r12d,60(%rsp)
+ movl %ecx,%eax
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- addl %eax,%r12d
-
- movl %ebx,%eax
- addl %r13d,%r12d
+ xorl %edx,%eax
+ xorl %ebx,%r14d
addl %r15d,%r12d
- movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %ecx,%r15d
- rorl $2,%eax
- rorl $13,%r13d
- movl %ebx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ebx,%eax
+ andl %edx,%r15d
- xorl %r13d,%eax
- rorl $9,%r13d
- orl %edx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%eax
- xorl %r13d,%eax
- andl %edx,%r15d
addl %r12d,%r8d
-
- andl %ecx,%r14d
addl %r12d,%eax
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%eax
+
jmp .Lrounds_16_xx
.align 16
.Lrounds_16_xx:
movl 4(%rsp),%r13d
- movl 56(%rsp),%r12d
-
- movl %r13d,%r15d
+ movl 56(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 36(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 36(%rsp),%r12d
+ xorl %r15d,%r14d
addl 0(%rsp),%r12d
movl %r8d,%r13d
- movl %r8d,%r14d
+ addl %r14d,%r12d
+ movl %eax,%r14d
+ rorl $14,%r13d
movl %r9d,%r15d
+ movl %r12d,0(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r11d,%r12d
+ xorl %eax,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r8d,%r15d
- movl %r12d,0(%rsp)
+ movl %ebx,%r11d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- addl %r11d,%r12d
-
- movl %eax,%r11d
- addl %r13d,%r12d
+ xorl %ecx,%r11d
+ xorl %eax,%r14d
addl %r15d,%r12d
- movl %eax,%r13d
- movl %eax,%r14d
+ movl %ebx,%r15d
- rorl $2,%r11d
- rorl $13,%r13d
- movl %eax,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %eax,%r11d
+ andl %ecx,%r15d
- xorl %r13d,%r11d
- rorl $9,%r13d
- orl %ecx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r11d
- xorl %r13d,%r11d
- andl %ecx,%r15d
addl %r12d,%edx
-
- andl %ebx,%r14d
addl %r12d,%r11d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r11d
- movl 8(%rsp),%r13d
- movl 60(%rsp),%r12d
- movl %r13d,%r15d
+ movl 8(%rsp),%r13d
+ movl 60(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 40(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 40(%rsp),%r12d
+ xorl %r15d,%r14d
addl 4(%rsp),%r12d
movl %edx,%r13d
- movl %edx,%r14d
+ addl %r14d,%r12d
+ movl %r11d,%r14d
+ rorl $14,%r13d
movl %r8d,%r15d
+ movl %r12d,4(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r10d,%r12d
+ xorl %r11d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %edx,%r15d
- movl %r12d,4(%rsp)
+ movl %eax,%r10d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- addl %r10d,%r12d
-
- movl %r11d,%r10d
- addl %r13d,%r12d
+ xorl %ebx,%r10d
+ xorl %r11d,%r14d
addl %r15d,%r12d
- movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %eax,%r15d
- rorl $2,%r10d
- rorl $13,%r13d
- movl %r11d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r11d,%r10d
+ andl %ebx,%r15d
- xorl %r13d,%r10d
- rorl $9,%r13d
- orl %ebx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r10d
- xorl %r13d,%r10d
- andl %ebx,%r15d
addl %r12d,%ecx
-
- andl %eax,%r14d
addl %r12d,%r10d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r10d
- movl 12(%rsp),%r13d
- movl 0(%rsp),%r12d
- movl %r13d,%r15d
+ movl 12(%rsp),%r13d
+ movl 0(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 44(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 44(%rsp),%r12d
+ xorl %r15d,%r14d
addl 8(%rsp),%r12d
movl %ecx,%r13d
- movl %ecx,%r14d
+ addl %r14d,%r12d
+ movl %r10d,%r14d
+ rorl $14,%r13d
movl %edx,%r15d
+ movl %r12d,8(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r9d,%r12d
+ xorl %r10d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ecx,%r15d
- movl %r12d,8(%rsp)
+ movl %r11d,%r9d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- addl %r9d,%r12d
-
- movl %r10d,%r9d
- addl %r13d,%r12d
+ xorl %eax,%r9d
+ xorl %r10d,%r14d
addl %r15d,%r12d
- movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %r11d,%r15d
- rorl $2,%r9d
- rorl $13,%r13d
- movl %r10d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r10d,%r9d
+ andl %eax,%r15d
- xorl %r13d,%r9d
- rorl $9,%r13d
- orl %eax,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r9d
- xorl %r13d,%r9d
- andl %eax,%r15d
addl %r12d,%ebx
-
- andl %r11d,%r14d
addl %r12d,%r9d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r9d
- movl 16(%rsp),%r13d
- movl 4(%rsp),%r12d
- movl %r13d,%r15d
+ movl 16(%rsp),%r13d
+ movl 4(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 48(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 48(%rsp),%r12d
+ xorl %r15d,%r14d
addl 12(%rsp),%r12d
movl %ebx,%r13d
- movl %ebx,%r14d
+ addl %r14d,%r12d
+ movl %r9d,%r14d
+ rorl $14,%r13d
movl %ecx,%r15d
+ movl %r12d,12(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r8d,%r12d
+ xorl %r9d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ebx,%r15d
- movl %r12d,12(%rsp)
+ movl %r10d,%r8d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- addl %r8d,%r12d
-
- movl %r9d,%r8d
- addl %r13d,%r12d
+ xorl %r11d,%r8d
+ xorl %r9d,%r14d
addl %r15d,%r12d
- movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %r10d,%r15d
- rorl $2,%r8d
- rorl $13,%r13d
- movl %r9d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r9d,%r8d
+ andl %r11d,%r15d
- xorl %r13d,%r8d
- rorl $9,%r13d
- orl %r11d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r8d
- xorl %r13d,%r8d
- andl %r11d,%r15d
addl %r12d,%eax
-
- andl %r10d,%r14d
addl %r12d,%r8d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r8d
- movl 20(%rsp),%r13d
- movl 8(%rsp),%r12d
- movl %r13d,%r15d
+ movl 20(%rsp),%r13d
+ movl 8(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 52(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 52(%rsp),%r12d
+ xorl %r15d,%r14d
addl 16(%rsp),%r12d
movl %eax,%r13d
- movl %eax,%r14d
+ addl %r14d,%r12d
+ movl %r8d,%r14d
+ rorl $14,%r13d
movl %ebx,%r15d
+ movl %r12d,16(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %edx,%r12d
+ xorl %r8d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %eax,%r15d
- movl %r12d,16(%rsp)
+ movl %r9d,%edx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- addl %edx,%r12d
-
- movl %r8d,%edx
- addl %r13d,%r12d
+ xorl %r10d,%edx
+ xorl %r8d,%r14d
addl %r15d,%r12d
- movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %r9d,%r15d
- rorl $2,%edx
- rorl $13,%r13d
- movl %r8d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r8d,%edx
+ andl %r10d,%r15d
- xorl %r13d,%edx
- rorl $9,%r13d
- orl %r10d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%edx
- xorl %r13d,%edx
- andl %r10d,%r15d
addl %r12d,%r11d
-
- andl %r9d,%r14d
addl %r12d,%edx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%edx
- movl 24(%rsp),%r13d
- movl 12(%rsp),%r12d
- movl %r13d,%r15d
+ movl 24(%rsp),%r13d
+ movl 12(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 56(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 56(%rsp),%r12d
+ xorl %r15d,%r14d
addl 20(%rsp),%r12d
movl %r11d,%r13d
- movl %r11d,%r14d
+ addl %r14d,%r12d
+ movl %edx,%r14d
+ rorl $14,%r13d
movl %eax,%r15d
+ movl %r12d,20(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ecx,%r12d
+ xorl %edx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r11d,%r15d
- movl %r12d,20(%rsp)
+ movl %r8d,%ecx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- addl %ecx,%r12d
-
- movl %edx,%ecx
- addl %r13d,%r12d
+ xorl %r9d,%ecx
+ xorl %edx,%r14d
addl %r15d,%r12d
- movl %edx,%r13d
- movl %edx,%r14d
+ movl %r8d,%r15d
- rorl $2,%ecx
- rorl $13,%r13d
- movl %edx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %edx,%ecx
+ andl %r9d,%r15d
- xorl %r13d,%ecx
- rorl $9,%r13d
- orl %r9d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ecx
- xorl %r13d,%ecx
- andl %r9d,%r15d
addl %r12d,%r10d
-
- andl %r8d,%r14d
addl %r12d,%ecx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ecx
- movl 28(%rsp),%r13d
- movl 16(%rsp),%r12d
- movl %r13d,%r15d
+ movl 28(%rsp),%r13d
+ movl 16(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 60(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 60(%rsp),%r12d
+ xorl %r15d,%r14d
addl 24(%rsp),%r12d
movl %r10d,%r13d
- movl %r10d,%r14d
+ addl %r14d,%r12d
+ movl %ecx,%r14d
+ rorl $14,%r13d
movl %r11d,%r15d
+ movl %r12d,24(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ebx,%r12d
+ xorl %ecx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r10d,%r15d
- movl %r12d,24(%rsp)
+ movl %edx,%ebx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- addl %ebx,%r12d
-
- movl %ecx,%ebx
- addl %r13d,%r12d
+ xorl %r8d,%ebx
+ xorl %ecx,%r14d
addl %r15d,%r12d
- movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %edx,%r15d
- rorl $2,%ebx
- rorl $13,%r13d
- movl %ecx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ecx,%ebx
+ andl %r8d,%r15d
- xorl %r13d,%ebx
- rorl $9,%r13d
- orl %r8d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ebx
- xorl %r13d,%ebx
- andl %r8d,%r15d
addl %r12d,%r9d
-
- andl %edx,%r14d
addl %r12d,%ebx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ebx
- movl 32(%rsp),%r13d
- movl 20(%rsp),%r12d
- movl %r13d,%r15d
+ movl 32(%rsp),%r13d
+ movl 20(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 0(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 0(%rsp),%r12d
+ xorl %r15d,%r14d
addl 28(%rsp),%r12d
movl %r9d,%r13d
- movl %r9d,%r14d
+ addl %r14d,%r12d
+ movl %ebx,%r14d
+ rorl $14,%r13d
movl %r10d,%r15d
+ movl %r12d,28(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %eax,%r12d
+ xorl %ebx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r9d,%r15d
- movl %r12d,28(%rsp)
+ movl %ecx,%eax
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- addl %eax,%r12d
-
- movl %ebx,%eax
- addl %r13d,%r12d
+ xorl %edx,%eax
+ xorl %ebx,%r14d
addl %r15d,%r12d
- movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %ecx,%r15d
- rorl $2,%eax
- rorl $13,%r13d
- movl %ebx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ebx,%eax
+ andl %edx,%r15d
- xorl %r13d,%eax
- rorl $9,%r13d
- orl %edx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%eax
- xorl %r13d,%eax
- andl %edx,%r15d
addl %r12d,%r8d
-
- andl %ecx,%r14d
addl %r12d,%eax
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%eax
- movl 36(%rsp),%r13d
- movl 24(%rsp),%r12d
- movl %r13d,%r15d
+ movl 36(%rsp),%r13d
+ movl 24(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 4(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 4(%rsp),%r12d
+ xorl %r15d,%r14d
addl 32(%rsp),%r12d
movl %r8d,%r13d
- movl %r8d,%r14d
+ addl %r14d,%r12d
+ movl %eax,%r14d
+ rorl $14,%r13d
movl %r9d,%r15d
+ movl %r12d,32(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r11d,%r12d
+ xorl %eax,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r8d,%r15d
- movl %r12d,32(%rsp)
+ movl %ebx,%r11d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- addl %r11d,%r12d
-
- movl %eax,%r11d
- addl %r13d,%r12d
+ xorl %ecx,%r11d
+ xorl %eax,%r14d
addl %r15d,%r12d
- movl %eax,%r13d
- movl %eax,%r14d
+ movl %ebx,%r15d
- rorl $2,%r11d
- rorl $13,%r13d
- movl %eax,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %eax,%r11d
+ andl %ecx,%r15d
- xorl %r13d,%r11d
- rorl $9,%r13d
- orl %ecx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r11d
- xorl %r13d,%r11d
- andl %ecx,%r15d
addl %r12d,%edx
-
- andl %ebx,%r14d
addl %r12d,%r11d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r11d
- movl 40(%rsp),%r13d
- movl 28(%rsp),%r12d
- movl %r13d,%r15d
+ movl 40(%rsp),%r13d
+ movl 28(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 8(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 8(%rsp),%r12d
+ xorl %r15d,%r14d
addl 36(%rsp),%r12d
movl %edx,%r13d
- movl %edx,%r14d
+ addl %r14d,%r12d
+ movl %r11d,%r14d
+ rorl $14,%r13d
movl %r8d,%r15d
+ movl %r12d,36(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r10d,%r12d
+ xorl %r11d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %edx,%r15d
- movl %r12d,36(%rsp)
+ movl %eax,%r10d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- addl %r10d,%r12d
-
- movl %r11d,%r10d
- addl %r13d,%r12d
+ xorl %ebx,%r10d
+ xorl %r11d,%r14d
addl %r15d,%r12d
- movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %eax,%r15d
- rorl $2,%r10d
- rorl $13,%r13d
- movl %r11d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r11d,%r10d
+ andl %ebx,%r15d
- xorl %r13d,%r10d
- rorl $9,%r13d
- orl %ebx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r10d
- xorl %r13d,%r10d
- andl %ebx,%r15d
addl %r12d,%ecx
-
- andl %eax,%r14d
addl %r12d,%r10d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r10d
- movl 44(%rsp),%r13d
- movl 32(%rsp),%r12d
- movl %r13d,%r15d
+ movl 44(%rsp),%r13d
+ movl 32(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 12(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 12(%rsp),%r12d
+ xorl %r15d,%r14d
addl 40(%rsp),%r12d
movl %ecx,%r13d
- movl %ecx,%r14d
+ addl %r14d,%r12d
+ movl %r10d,%r14d
+ rorl $14,%r13d
movl %edx,%r15d
+ movl %r12d,40(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r9d,%r12d
+ xorl %r10d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ecx,%r15d
- movl %r12d,40(%rsp)
+ movl %r11d,%r9d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- addl %r9d,%r12d
-
- movl %r10d,%r9d
- addl %r13d,%r12d
+ xorl %eax,%r9d
+ xorl %r10d,%r14d
addl %r15d,%r12d
- movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %r11d,%r15d
- rorl $2,%r9d
- rorl $13,%r13d
- movl %r10d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r10d,%r9d
+ andl %eax,%r15d
- xorl %r13d,%r9d
- rorl $9,%r13d
- orl %eax,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r9d
- xorl %r13d,%r9d
- andl %eax,%r15d
addl %r12d,%ebx
-
- andl %r11d,%r14d
addl %r12d,%r9d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r9d
- movl 48(%rsp),%r13d
- movl 36(%rsp),%r12d
- movl %r13d,%r15d
+ movl 48(%rsp),%r13d
+ movl 36(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 16(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 16(%rsp),%r12d
+ xorl %r15d,%r14d
addl 44(%rsp),%r12d
movl %ebx,%r13d
- movl %ebx,%r14d
+ addl %r14d,%r12d
+ movl %r9d,%r14d
+ rorl $14,%r13d
movl %ecx,%r15d
+ movl %r12d,44(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r8d,%r12d
+ xorl %r9d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ebx,%r15d
- movl %r12d,44(%rsp)
+ movl %r10d,%r8d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- addl %r8d,%r12d
-
- movl %r9d,%r8d
- addl %r13d,%r12d
+ xorl %r11d,%r8d
+ xorl %r9d,%r14d
addl %r15d,%r12d
- movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %r10d,%r15d
- rorl $2,%r8d
- rorl $13,%r13d
- movl %r9d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r9d,%r8d
+ andl %r11d,%r15d
- xorl %r13d,%r8d
- rorl $9,%r13d
- orl %r11d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r8d
- xorl %r13d,%r8d
- andl %r11d,%r15d
addl %r12d,%eax
-
- andl %r10d,%r14d
addl %r12d,%r8d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r8d
- movl 52(%rsp),%r13d
- movl 40(%rsp),%r12d
- movl %r13d,%r15d
+ movl 52(%rsp),%r13d
+ movl 40(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 20(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 20(%rsp),%r12d
+ xorl %r15d,%r14d
addl 48(%rsp),%r12d
movl %eax,%r13d
- movl %eax,%r14d
+ addl %r14d,%r12d
+ movl %r8d,%r14d
+ rorl $14,%r13d
movl %ebx,%r15d
+ movl %r12d,48(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %edx,%r12d
+ xorl %r8d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %eax,%r15d
- movl %r12d,48(%rsp)
+ movl %r9d,%edx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- addl %edx,%r12d
-
- movl %r8d,%edx
- addl %r13d,%r12d
+ xorl %r10d,%edx
+ xorl %r8d,%r14d
addl %r15d,%r12d
- movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %r9d,%r15d
- rorl $2,%edx
- rorl $13,%r13d
- movl %r8d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r8d,%edx
+ andl %r10d,%r15d
- xorl %r13d,%edx
- rorl $9,%r13d
- orl %r10d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%edx
- xorl %r13d,%edx
- andl %r10d,%r15d
addl %r12d,%r11d
-
- andl %r9d,%r14d
addl %r12d,%edx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%edx
- movl 56(%rsp),%r13d
- movl 44(%rsp),%r12d
- movl %r13d,%r15d
+ movl 56(%rsp),%r13d
+ movl 44(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 24(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 24(%rsp),%r12d
+ xorl %r15d,%r14d
addl 52(%rsp),%r12d
movl %r11d,%r13d
- movl %r11d,%r14d
+ addl %r14d,%r12d
+ movl %edx,%r14d
+ rorl $14,%r13d
movl %eax,%r15d
+ movl %r12d,52(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ecx,%r12d
+ xorl %edx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r11d,%r15d
- movl %r12d,52(%rsp)
+ movl %r8d,%ecx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- addl %ecx,%r12d
-
- movl %edx,%ecx
- addl %r13d,%r12d
+ xorl %r9d,%ecx
+ xorl %edx,%r14d
addl %r15d,%r12d
- movl %edx,%r13d
- movl %edx,%r14d
+ movl %r8d,%r15d
- rorl $2,%ecx
- rorl $13,%r13d
- movl %edx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %edx,%ecx
+ andl %r9d,%r15d
- xorl %r13d,%ecx
- rorl $9,%r13d
- orl %r9d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ecx
- xorl %r13d,%ecx
- andl %r9d,%r15d
addl %r12d,%r10d
-
- andl %r8d,%r14d
addl %r12d,%ecx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ecx
- movl 60(%rsp),%r13d
- movl 48(%rsp),%r12d
- movl %r13d,%r15d
+ movl 60(%rsp),%r13d
+ movl 48(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 28(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 28(%rsp),%r12d
+ xorl %r15d,%r14d
addl 56(%rsp),%r12d
movl %r10d,%r13d
- movl %r10d,%r14d
+ addl %r14d,%r12d
+ movl %ecx,%r14d
+ rorl $14,%r13d
movl %r11d,%r15d
+ movl %r12d,56(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ebx,%r12d
+ xorl %ecx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r10d,%r15d
- movl %r12d,56(%rsp)
+ movl %edx,%ebx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- addl %ebx,%r12d
-
- movl %ecx,%ebx
- addl %r13d,%r12d
+ xorl %r8d,%ebx
+ xorl %ecx,%r14d
addl %r15d,%r12d
- movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %edx,%r15d
- rorl $2,%ebx
- rorl $13,%r13d
- movl %ecx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ecx,%ebx
+ andl %r8d,%r15d
- xorl %r13d,%ebx
- rorl $9,%r13d
- orl %r8d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ebx
- xorl %r13d,%ebx
- andl %r8d,%r15d
addl %r12d,%r9d
-
- andl %edx,%r14d
addl %r12d,%ebx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ebx
- movl 0(%rsp),%r13d
- movl 52(%rsp),%r12d
- movl %r13d,%r15d
+ movl 0(%rsp),%r13d
+ movl 52(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 32(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 32(%rsp),%r12d
+ xorl %r15d,%r14d
addl 60(%rsp),%r12d
movl %r9d,%r13d
- movl %r9d,%r14d
+ addl %r14d,%r12d
+ movl %ebx,%r14d
+ rorl $14,%r13d
movl %r10d,%r15d
+ movl %r12d,60(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %eax,%r12d
+ xorl %ebx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r9d,%r15d
- movl %r12d,60(%rsp)
+ movl %ecx,%eax
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- addl %eax,%r12d
-
- movl %ebx,%eax
- addl %r13d,%r12d
+ xorl %edx,%eax
+ xorl %ebx,%r14d
addl %r15d,%r12d
- movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %ecx,%r15d
- rorl $2,%eax
- rorl $13,%r13d
- movl %ebx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ebx,%eax
+ andl %edx,%r15d
- xorl %r13d,%eax
- rorl $9,%r13d
- orl %edx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%eax
- xorl %r13d,%eax
- andl %edx,%r15d
addl %r12d,%r8d
-
- andl %ecx,%r14d
addl %r12d,%eax
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%eax
+
cmpq $64,%rdi
jb .Lrounds_16_xx
diff --git a/deps/openssl/asm/x64-elf-gas/x86_64cpuid.s b/deps/openssl/asm/x64-elf-gas/x86_64cpuid.s
index 0a565a989..e0a828708 100644
--- a/deps/openssl/asm/x64-elf-gas/x86_64cpuid.s
+++ b/deps/openssl/asm/x64-elf-gas/x86_64cpuid.s
@@ -1,7 +1,11 @@
+.hidden OPENSSL_cpuid_setup
.section .init
call OPENSSL_cpuid_setup
+.hidden OPENSSL_ia32cap_P
+.comm OPENSSL_ia32cap_P,8,4
+
.text
@@ -67,7 +71,15 @@ OPENSSL_ia32_cpuid:
movl $2147483648,%eax
cpuid
- cmpl $2147483656,%eax
+ cmpl $2147483649,%eax
+ jb .Lintel
+ movl %eax,%r10d
+ movl $2147483649,%eax
+ cpuid
+ orl %ecx,%r9d
+ andl $2049,%r9d
+
+ cmpl $2147483656,%r10d
jb .Lintel
movl $2147483656,%eax
@@ -78,12 +90,12 @@ OPENSSL_ia32_cpuid:
movl $1,%eax
cpuid
btl $28,%edx
- jnc .Ldone
+ jnc .Lgeneric
shrl $16,%ebx
cmpb %r10b,%bl
- ja .Ldone
+ ja .Lgeneric
andl $4026531839,%edx
- jmp .Ldone
+ jmp .Lgeneric
.Lintel:
cmpl $4,%r11d
@@ -100,30 +112,48 @@ OPENSSL_ia32_cpuid:
.Lnocacheinfo:
movl $1,%eax
cpuid
+ andl $3220176895,%edx
cmpl $0,%r9d
jne .Lnotintel
- orl $1048576,%edx
+ orl $1073741824,%edx
andb $15,%ah
cmpb $15,%ah
- je .Lnotintel
- orl $1073741824,%edx
+ jne .Lnotintel
+ orl $1048576,%edx
.Lnotintel:
btl $28,%edx
- jnc .Ldone
+ jnc .Lgeneric
andl $4026531839,%edx
cmpl $0,%r10d
- je .Ldone
+ je .Lgeneric
orl $268435456,%edx
shrl $16,%ebx
cmpb $1,%bl
- ja .Ldone
+ ja .Lgeneric
andl $4026531839,%edx
+.Lgeneric:
+ andl $2048,%r9d
+ andl $4294965247,%ecx
+ orl %ecx,%r9d
+
+ movl %edx,%r10d
+ btl $27,%r9d
+ jnc .Lclear_avx
+ xorl %ecx,%ecx
+.byte 0x0f,0x01,0xd0
+
+ andl $6,%eax
+ cmpl $6,%eax
+ je .Ldone
+.Lclear_avx:
+ movl $4026525695,%eax
+ andl %eax,%r9d
.Ldone:
- shlq $32,%rcx
- movl %edx,%eax
+ shlq $32,%r9
+ movl %r10d,%eax
movq %r8,%rbx
- orq %rcx,%rax
+ orq %r9,%rax
.byte 0xf3,0xc3
.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
@@ -192,3 +222,17 @@ OPENSSL_wipe_cpu:
leaq 8(%rsp),%rax
.byte 0xf3,0xc3
.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
+.globl OPENSSL_ia32_rdrand
+.type OPENSSL_ia32_rdrand,@function
+.align 16
+OPENSSL_ia32_rdrand:
+ movl $8,%ecx
+.Loop_rdrand:
+.byte 72,15,199,240
+ jc .Lbreak_rdrand
+ loop .Loop_rdrand
+.Lbreak_rdrand:
+ cmpq $0,%rax
+ cmoveq %rcx,%rax
+ .byte 0xf3,0xc3
+.size OPENSSL_ia32_rdrand,.-OPENSSL_ia32_rdrand
diff --git a/deps/openssl/asm/x64-macosx-gas/aes/aes-x86_64.s b/deps/openssl/asm/x64-macosx-gas/aes/aes-x86_64.s
index d42e1ea79..88120a189 100644
--- a/deps/openssl/asm/x64-macosx-gas/aes/aes-x86_64.s
+++ b/deps/openssl/asm/x64-macosx-gas/aes/aes-x86_64.s
@@ -333,6 +333,9 @@ L$enc_compact_done:
.globl _AES_encrypt
.p2align 4
+.globl _asm_AES_encrypt
+.private_extern _asm_AES_encrypt
+_asm_AES_encrypt:
_AES_encrypt:
pushq %rbx
pushq %rbp
@@ -780,6 +783,9 @@ L$dec_compact_done:
.globl _AES_decrypt
.p2align 4
+.globl _asm_AES_decrypt
+.private_extern _asm_AES_decrypt
+_asm_AES_decrypt:
_AES_decrypt:
pushq %rbx
pushq %rbp
@@ -843,10 +849,10 @@ L$dec_prologue:
L$dec_epilogue:
.byte 0xf3,0xc3
-.globl _AES_set_encrypt_key
+.globl _private_AES_set_encrypt_key
.p2align 4
-_AES_set_encrypt_key:
+_private_AES_set_encrypt_key:
pushq %rbx
pushq %rbp
pushq %r12
@@ -1109,10 +1115,10 @@ L$exit:
.byte 0xf3,0xc3
-.globl _AES_set_decrypt_key
+.globl _private_AES_set_decrypt_key
.p2align 4
-_AES_set_decrypt_key:
+_private_AES_set_decrypt_key:
pushq %rbx
pushq %rbp
pushq %r12
@@ -1300,6 +1306,9 @@ L$dec_key_epilogue:
.p2align 4
+.globl _asm_AES_cbc_encrypt
+.private_extern _asm_AES_cbc_encrypt
+_asm_AES_cbc_encrypt:
_AES_cbc_encrypt:
cmpq $0,%rdx
je L$cbc_epilogue
diff --git a/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s b/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s
new file mode 100644
index 000000000..5ae41e019
--- /dev/null
+++ b/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s
@@ -0,0 +1,1402 @@
+.text
+
+
+
+.globl _aesni_cbc_sha1_enc
+
+.p2align 4
+_aesni_cbc_sha1_enc:
+
+ movl _OPENSSL_ia32cap_P+0(%rip),%r10d
+ movl _OPENSSL_ia32cap_P+4(%rip),%r11d
+ jmp aesni_cbc_sha1_enc_ssse3
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+aesni_cbc_sha1_enc_ssse3:
+ movq 8(%rsp),%r10
+
+
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ leaq -104(%rsp),%rsp
+
+
+ movq %rdi,%r12
+ movq %rsi,%r13
+ movq %rdx,%r14
+ movq %rcx,%r15
+ movdqu (%r8),%xmm11
+ movq %r8,88(%rsp)
+ shlq $6,%r14
+ subq %r12,%r13
+ movl 240(%r15),%r8d
+ addq %r10,%r14
+
+ leaq K_XX_XX(%rip),%r11
+ movl 0(%r9),%eax
+ movl 4(%r9),%ebx
+ movl 8(%r9),%ecx
+ movl 12(%r9),%edx
+ movl %ebx,%esi
+ movl 16(%r9),%ebp
+
+ movdqa 64(%r11),%xmm6
+ movdqa 0(%r11),%xmm9
+ movdqu 0(%r10),%xmm0
+ movdqu 16(%r10),%xmm1
+ movdqu 32(%r10),%xmm2
+ movdqu 48(%r10),%xmm3
+.byte 102,15,56,0,198
+ addq $64,%r10
+.byte 102,15,56,0,206
+.byte 102,15,56,0,214
+.byte 102,15,56,0,222
+ paddd %xmm9,%xmm0
+ paddd %xmm9,%xmm1
+ paddd %xmm9,%xmm2
+ movdqa %xmm0,0(%rsp)
+ psubd %xmm9,%xmm0
+ movdqa %xmm1,16(%rsp)
+ psubd %xmm9,%xmm1
+ movdqa %xmm2,32(%rsp)
+ psubd %xmm9,%xmm2
+ movups (%r15),%xmm13
+ movups 16(%r15),%xmm14
+ jmp L$oop_ssse3
+.p2align 4
+L$oop_ssse3:
+ movdqa %xmm1,%xmm4
+ addl 0(%rsp),%ebp
+ movups 0(%r12),%xmm12
+ xorps %xmm13,%xmm12
+ xorps %xmm12,%xmm11
+.byte 102,69,15,56,220,222
+ movups 32(%r15),%xmm15
+ xorl %edx,%ecx
+ movdqa %xmm3,%xmm8
+.byte 102,15,58,15,224,8
+ movl %eax,%edi
+ roll $5,%eax
+ paddd %xmm3,%xmm9
+ andl %ecx,%esi
+ xorl %edx,%ecx
+ psrldq $4,%xmm8
+ xorl %edx,%esi
+ addl %eax,%ebp
+ pxor %xmm0,%xmm4
+ rorl $2,%ebx
+ addl %esi,%ebp
+ pxor %xmm2,%xmm8
+ addl 4(%rsp),%edx
+ xorl %ecx,%ebx
+ movl %ebp,%esi
+ roll $5,%ebp
+ pxor %xmm8,%xmm4
+ andl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa %xmm9,48(%rsp)
+ xorl %ecx,%edi
+.byte 102,69,15,56,220,223
+ movups 48(%r15),%xmm14
+ addl %ebp,%edx
+ movdqa %xmm4,%xmm10
+ movdqa %xmm4,%xmm8
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 8(%rsp),%ecx
+ xorl %ebx,%eax
+ pslldq $12,%xmm10
+ paddd %xmm4,%xmm4
+ movl %edx,%edi
+ roll $5,%edx
+ andl %eax,%esi
+ xorl %ebx,%eax
+ psrld $31,%xmm8
+ xorl %ebx,%esi
+ addl %edx,%ecx
+ movdqa %xmm10,%xmm9
+ rorl $7,%ebp
+ addl %esi,%ecx
+ psrld $30,%xmm10
+ por %xmm8,%xmm4
+ addl 12(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%esi
+ roll $5,%ecx
+.byte 102,69,15,56,220,222
+ movups 64(%r15),%xmm15
+ pslld $2,%xmm9
+ pxor %xmm10,%xmm4
+ andl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa 0(%r11),%xmm10
+ xorl %eax,%edi
+ addl %ecx,%ebx
+ pxor %xmm9,%xmm4
+ rorl $7,%edx
+ addl %edi,%ebx
+ movdqa %xmm2,%xmm5
+ addl 16(%rsp),%eax
+ xorl %ebp,%edx
+ movdqa %xmm4,%xmm9
+.byte 102,15,58,15,233,8
+ movl %ebx,%edi
+ roll $5,%ebx
+ paddd %xmm4,%xmm10
+ andl %edx,%esi
+ xorl %ebp,%edx
+ psrldq $4,%xmm9
+ xorl %ebp,%esi
+ addl %ebx,%eax
+ pxor %xmm1,%xmm5
+ rorl $7,%ecx
+ addl %esi,%eax
+ pxor %xmm3,%xmm9
+ addl 20(%rsp),%ebp
+.byte 102,69,15,56,220,223
+ movups 80(%r15),%xmm14
+ xorl %edx,%ecx
+ movl %eax,%esi
+ roll $5,%eax
+ pxor %xmm9,%xmm5
+ andl %ecx,%edi
+ xorl %edx,%ecx
+ movdqa %xmm10,0(%rsp)
+ xorl %edx,%edi
+ addl %eax,%ebp
+ movdqa %xmm5,%xmm8
+ movdqa %xmm5,%xmm9
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 24(%rsp),%edx
+ xorl %ecx,%ebx
+ pslldq $12,%xmm8
+ paddd %xmm5,%xmm5
+ movl %ebp,%edi
+ roll $5,%ebp
+ andl %ebx,%esi
+ xorl %ecx,%ebx
+ psrld $31,%xmm9
+ xorl %ecx,%esi
+.byte 102,69,15,56,220,222
+ movups 96(%r15),%xmm15
+ addl %ebp,%edx
+ movdqa %xmm8,%xmm10
+ rorl $7,%eax
+ addl %esi,%edx
+ psrld $30,%xmm8
+ por %xmm9,%xmm5
+ addl 28(%rsp),%ecx
+ xorl %ebx,%eax
+ movl %edx,%esi
+ roll $5,%edx
+ pslld $2,%xmm10
+ pxor %xmm8,%xmm5
+ andl %eax,%edi
+ xorl %ebx,%eax
+ movdqa 16(%r11),%xmm8
+ xorl %ebx,%edi
+ addl %edx,%ecx
+ pxor %xmm10,%xmm5
+ rorl $7,%ebp
+ addl %edi,%ecx
+ movdqa %xmm3,%xmm6
+ addl 32(%rsp),%ebx
+ xorl %eax,%ebp
+ movdqa %xmm5,%xmm10
+.byte 102,15,58,15,242,8
+ movl %ecx,%edi
+ roll $5,%ecx
+.byte 102,69,15,56,220,223
+ movups 112(%r15),%xmm14
+ paddd %xmm5,%xmm8
+ andl %ebp,%esi
+ xorl %eax,%ebp
+ psrldq $4,%xmm10
+ xorl %eax,%esi
+ addl %ecx,%ebx
+ pxor %xmm2,%xmm6
+ rorl $7,%edx
+ addl %esi,%ebx
+ pxor %xmm4,%xmm10
+ addl 36(%rsp),%eax
+ xorl %ebp,%edx
+ movl %ebx,%esi
+ roll $5,%ebx
+ pxor %xmm10,%xmm6
+ andl %edx,%edi
+ xorl %ebp,%edx
+ movdqa %xmm8,16(%rsp)
+ xorl %ebp,%edi
+ addl %ebx,%eax
+ movdqa %xmm6,%xmm9
+ movdqa %xmm6,%xmm10
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 40(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 128(%r15),%xmm15
+ xorl %edx,%ecx
+ pslldq $12,%xmm9
+ paddd %xmm6,%xmm6
+ movl %eax,%edi
+ roll $5,%eax
+ andl %ecx,%esi
+ xorl %edx,%ecx
+ psrld $31,%xmm10
+ xorl %edx,%esi
+ addl %eax,%ebp
+ movdqa %xmm9,%xmm8
+ rorl $7,%ebx
+ addl %esi,%ebp
+ psrld $30,%xmm9
+ por %xmm10,%xmm6
+ addl 44(%rsp),%edx
+ xorl %ecx,%ebx
+ movl %ebp,%esi
+ roll $5,%ebp
+ pslld $2,%xmm8
+ pxor %xmm9,%xmm6
+ andl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa 16(%r11),%xmm9
+ xorl %ecx,%edi
+.byte 102,69,15,56,220,223
+ movups 144(%r15),%xmm14
+ addl %ebp,%edx
+ pxor %xmm8,%xmm6
+ rorl $7,%eax
+ addl %edi,%edx
+ movdqa %xmm4,%xmm7
+ addl 48(%rsp),%ecx
+ xorl %ebx,%eax
+ movdqa %xmm6,%xmm8
+.byte 102,15,58,15,251,8
+ movl %edx,%edi
+ roll $5,%edx
+ paddd %xmm6,%xmm9
+ andl %eax,%esi
+ xorl %ebx,%eax
+ psrldq $4,%xmm8
+ xorl %ebx,%esi
+ addl %edx,%ecx
+ pxor %xmm3,%xmm7
+ rorl $7,%ebp
+ addl %esi,%ecx
+ pxor %xmm5,%xmm8
+ addl 52(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%esi
+ roll $5,%ecx
+.byte 102,69,15,56,220,222
+ movups 160(%r15),%xmm15
+ pxor %xmm8,%xmm7
+ andl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa %xmm9,32(%rsp)
+ xorl %eax,%edi
+ addl %ecx,%ebx
+ movdqa %xmm7,%xmm10
+ movdqa %xmm7,%xmm8
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 56(%rsp),%eax
+ xorl %ebp,%edx
+ pslldq $12,%xmm10
+ paddd %xmm7,%xmm7
+ movl %ebx,%edi
+ roll $5,%ebx
+ andl %edx,%esi
+ xorl %ebp,%edx
+ psrld $31,%xmm8
+ xorl %ebp,%esi
+ addl %ebx,%eax
+ movdqa %xmm10,%xmm9
+ rorl $7,%ecx
+ addl %esi,%eax
+ psrld $30,%xmm10
+ por %xmm8,%xmm7
+ addl 60(%rsp),%ebp
+ cmpl $11,%r8d
+ jb L$aesenclast1
+ movups 176(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 192(%r15),%xmm15
+.byte 102,69,15,56,220,222
+ je L$aesenclast1
+ movups 208(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 224(%r15),%xmm15
+.byte 102,69,15,56,220,222
+L$aesenclast1:
+.byte 102,69,15,56,221,223
+ movups 16(%r15),%xmm14
+ xorl %edx,%ecx
+ movl %eax,%esi
+ roll $5,%eax
+ pslld $2,%xmm9
+ pxor %xmm10,%xmm7
+ andl %ecx,%edi
+ xorl %edx,%ecx
+ movdqa 16(%r11),%xmm10
+ xorl %edx,%edi
+ addl %eax,%ebp
+ pxor %xmm9,%xmm7
+ rorl $7,%ebx
+ addl %edi,%ebp
+ movdqa %xmm7,%xmm9
+ addl 0(%rsp),%edx
+ pxor %xmm4,%xmm0
+.byte 102,68,15,58,15,206,8
+ xorl %ecx,%ebx
+ movl %ebp,%edi
+ roll $5,%ebp
+ pxor %xmm1,%xmm0
+ andl %ebx,%esi
+ xorl %ecx,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm7,%xmm10
+ xorl %ecx,%esi
+ movups 16(%r12),%xmm12
+ xorps %xmm13,%xmm12
+ movups %xmm11,0(%r13,%r12,1)
+ xorps %xmm12,%xmm11
+.byte 102,69,15,56,220,222
+ movups 32(%r15),%xmm15
+ addl %ebp,%edx
+ pxor %xmm9,%xmm0
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 4(%rsp),%ecx
+ xorl %ebx,%eax
+ movdqa %xmm0,%xmm9
+ movdqa %xmm10,48(%rsp)
+ movl %edx,%esi
+ roll $5,%edx
+ andl %eax,%edi
+ xorl %ebx,%eax
+ pslld $2,%xmm0
+ xorl %ebx,%edi
+ addl %edx,%ecx
+ psrld $30,%xmm9
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 8(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%edi
+ roll $5,%ecx
+.byte 102,69,15,56,220,223
+ movups 48(%r15),%xmm14
+ por %xmm9,%xmm0
+ andl %ebp,%esi
+ xorl %eax,%ebp
+ movdqa %xmm0,%xmm10
+ xorl %eax,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 12(%rsp),%eax
+ xorl %ebp,%edx
+ movl %ebx,%esi
+ roll $5,%ebx
+ andl %edx,%edi
+ xorl %ebp,%edx
+ xorl %ebp,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 16(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 64(%r15),%xmm15
+ pxor %xmm5,%xmm1
+.byte 102,68,15,58,15,215,8
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ pxor %xmm2,%xmm1
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ movdqa %xmm8,%xmm9
+ paddd %xmm0,%xmm8
+ rorl $7,%ebx
+ addl %esi,%ebp
+ pxor %xmm10,%xmm1
+ addl 20(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ movdqa %xmm1,%xmm10
+ movdqa %xmm8,0(%rsp)
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ pslld $2,%xmm1
+ addl 24(%rsp),%ecx
+ xorl %ebx,%esi
+ psrld $30,%xmm10
+ movl %edx,%edi
+ roll $5,%edx
+ xorl %eax,%esi
+.byte 102,69,15,56,220,223
+ movups 80(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ por %xmm10,%xmm1
+ addl 28(%rsp),%ebx
+ xorl %eax,%edi
+ movdqa %xmm1,%xmm8
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 32(%rsp),%eax
+ pxor %xmm6,%xmm2
+.byte 102,68,15,58,15,192,8
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ pxor %xmm3,%xmm2
+ xorl %edx,%esi
+ addl %ebx,%eax
+ movdqa 32(%r11),%xmm10
+ paddd %xmm1,%xmm9
+ rorl $7,%ecx
+ addl %esi,%eax
+ pxor %xmm8,%xmm2
+ addl 36(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 96(%r15),%xmm15
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ movdqa %xmm2,%xmm8
+ movdqa %xmm9,16(%rsp)
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ pslld $2,%xmm2
+ addl 40(%rsp),%edx
+ xorl %ecx,%esi
+ psrld $30,%xmm8
+ movl %ebp,%edi
+ roll $5,%ebp
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ por %xmm8,%xmm2
+ addl 44(%rsp),%ecx
+ xorl %ebx,%edi
+ movdqa %xmm2,%xmm9
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+.byte 102,69,15,56,220,223
+ movups 112(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 48(%rsp),%ebx
+ pxor %xmm7,%xmm3
+.byte 102,68,15,58,15,201,8
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ pxor %xmm4,%xmm3
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm2,%xmm10
+ rorl $7,%edx
+ addl %esi,%ebx
+ pxor %xmm9,%xmm3
+ addl 52(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ movdqa %xmm3,%xmm9
+ movdqa %xmm10,32(%rsp)
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ pslld $2,%xmm3
+ addl 56(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 128(%r15),%xmm15
+ xorl %edx,%esi
+ psrld $30,%xmm9
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ por %xmm9,%xmm3
+ addl 60(%rsp),%edx
+ xorl %ecx,%edi
+ movdqa %xmm3,%xmm10
+ movl %ebp,%esi
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 0(%rsp),%ecx
+ pxor %xmm0,%xmm4
+.byte 102,68,15,58,15,210,8
+ xorl %ebx,%esi
+ movl %edx,%edi
+ roll $5,%edx
+ pxor %xmm5,%xmm4
+ xorl %eax,%esi
+.byte 102,69,15,56,220,223
+ movups 144(%r15),%xmm14
+ addl %edx,%ecx
+ movdqa %xmm8,%xmm9
+ paddd %xmm3,%xmm8
+ rorl $7,%ebp
+ addl %esi,%ecx
+ pxor %xmm10,%xmm4
+ addl 4(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ movdqa %xmm4,%xmm10
+ movdqa %xmm8,48(%rsp)
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ pslld $2,%xmm4
+ addl 8(%rsp),%eax
+ xorl %ebp,%esi
+ psrld $30,%xmm10
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ por %xmm10,%xmm4
+ addl 12(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 160(%r15),%xmm15
+ xorl %edx,%edi
+ movdqa %xmm4,%xmm8
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 16(%rsp),%edx
+ pxor %xmm1,%xmm5
+.byte 102,68,15,58,15,195,8
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ pxor %xmm6,%xmm5
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ movdqa %xmm9,%xmm10
+ paddd %xmm4,%xmm9
+ rorl $7,%eax
+ addl %esi,%edx
+ pxor %xmm8,%xmm5
+ addl 20(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ movdqa %xmm5,%xmm8
+ movdqa %xmm9,0(%rsp)
+ xorl %eax,%edi
+ cmpl $11,%r8d
+ jb L$aesenclast2
+ movups 176(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 192(%r15),%xmm15
+.byte 102,69,15,56,220,222
+ je L$aesenclast2
+ movups 208(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 224(%r15),%xmm15
+.byte 102,69,15,56,220,222
+L$aesenclast2:
+.byte 102,69,15,56,221,223
+ movups 16(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ pslld $2,%xmm5
+ addl 24(%rsp),%ebx
+ xorl %eax,%esi
+ psrld $30,%xmm8
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ por %xmm8,%xmm5
+ addl 28(%rsp),%eax
+ xorl %ebp,%edi
+ movdqa %xmm5,%xmm9
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ movl %ecx,%edi
+ movups 32(%r12),%xmm12
+ xorps %xmm13,%xmm12
+ movups %xmm11,16(%r13,%r12,1)
+ xorps %xmm12,%xmm11
+.byte 102,69,15,56,220,222
+ movups 32(%r15),%xmm15
+ pxor %xmm2,%xmm6
+.byte 102,68,15,58,15,204,8
+ xorl %edx,%ecx
+ addl 32(%rsp),%ebp
+ andl %edx,%edi
+ pxor %xmm7,%xmm6
+ andl %ecx,%esi
+ rorl $7,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm5,%xmm10
+ addl %edi,%ebp
+ movl %eax,%edi
+ pxor %xmm9,%xmm6
+ roll $5,%eax
+ addl %esi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movdqa %xmm6,%xmm9
+ movdqa %xmm10,16(%rsp)
+ movl %ebx,%esi
+ xorl %ecx,%ebx
+ addl 36(%rsp),%edx
+ andl %ecx,%esi
+ pslld $2,%xmm6
+ andl %ebx,%edi
+ rorl $7,%eax
+ psrld $30,%xmm9
+ addl %esi,%edx
+ movl %ebp,%esi
+ roll $5,%ebp
+.byte 102,69,15,56,220,223
+ movups 48(%r15),%xmm14
+ addl %edi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ por %xmm9,%xmm6
+ movl %eax,%edi
+ xorl %ebx,%eax
+ movdqa %xmm6,%xmm10
+ addl 40(%rsp),%ecx
+ andl %ebx,%edi
+ andl %eax,%esi
+ rorl $7,%ebp
+ addl %edi,%ecx
+ movl %edx,%edi
+ roll $5,%edx
+ addl %esi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movl %ebp,%esi
+ xorl %eax,%ebp
+ addl 44(%rsp),%ebx
+ andl %eax,%esi
+ andl %ebp,%edi
+.byte 102,69,15,56,220,222
+ movups 64(%r15),%xmm15
+ rorl $7,%edx
+ addl %esi,%ebx
+ movl %ecx,%esi
+ roll $5,%ecx
+ addl %edi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movl %edx,%edi
+ pxor %xmm3,%xmm7
+.byte 102,68,15,58,15,213,8
+ xorl %ebp,%edx
+ addl 48(%rsp),%eax
+ andl %ebp,%edi
+ pxor %xmm0,%xmm7
+ andl %edx,%esi
+ rorl $7,%ecx
+ movdqa 48(%r11),%xmm9
+ paddd %xmm6,%xmm8
+ addl %edi,%eax
+ movl %ebx,%edi
+ pxor %xmm10,%xmm7
+ roll $5,%ebx
+ addl %esi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ movdqa %xmm7,%xmm10
+ movdqa %xmm8,32(%rsp)
+ movl %ecx,%esi
+.byte 102,69,15,56,220,223
+ movups 80(%r15),%xmm14
+ xorl %edx,%ecx
+ addl 52(%rsp),%ebp
+ andl %edx,%esi
+ pslld $2,%xmm7
+ andl %ecx,%edi
+ rorl $7,%ebx
+ psrld $30,%xmm10
+ addl %esi,%ebp
+ movl %eax,%esi
+ roll $5,%eax
+ addl %edi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ por %xmm10,%xmm7
+ movl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa %xmm7,%xmm8
+ addl 56(%rsp),%edx
+ andl %ecx,%edi
+ andl %ebx,%esi
+ rorl $7,%eax
+ addl %edi,%edx
+ movl %ebp,%edi
+ roll $5,%ebp
+.byte 102,69,15,56,220,222
+ movups 96(%r15),%xmm15
+ addl %esi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movl %eax,%esi
+ xorl %ebx,%eax
+ addl 60(%rsp),%ecx
+ andl %ebx,%esi
+ andl %eax,%edi
+ rorl $7,%ebp
+ addl %esi,%ecx
+ movl %edx,%esi
+ roll $5,%edx
+ addl %edi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movl %ebp,%edi
+ pxor %xmm4,%xmm0
+.byte 102,68,15,58,15,198,8
+ xorl %eax,%ebp
+ addl 0(%rsp),%ebx
+ andl %eax,%edi
+ pxor %xmm1,%xmm0
+ andl %ebp,%esi
+.byte 102,69,15,56,220,223
+ movups 112(%r15),%xmm14
+ rorl $7,%edx
+ movdqa %xmm9,%xmm10
+ paddd %xmm7,%xmm9
+ addl %edi,%ebx
+ movl %ecx,%edi
+ pxor %xmm8,%xmm0
+ roll $5,%ecx
+ addl %esi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movdqa %xmm0,%xmm8
+ movdqa %xmm9,48(%rsp)
+ movl %edx,%esi
+ xorl %ebp,%edx
+ addl 4(%rsp),%eax
+ andl %ebp,%esi
+ pslld $2,%xmm0
+ andl %edx,%edi
+ rorl $7,%ecx
+ psrld $30,%xmm8
+ addl %esi,%eax
+ movl %ebx,%esi
+ roll $5,%ebx
+ addl %edi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ por %xmm8,%xmm0
+ movl %ecx,%edi
+.byte 102,69,15,56,220,222
+ movups 128(%r15),%xmm15
+ xorl %edx,%ecx
+ movdqa %xmm0,%xmm9
+ addl 8(%rsp),%ebp
+ andl %edx,%edi
+ andl %ecx,%esi
+ rorl $7,%ebx
+ addl %edi,%ebp
+ movl %eax,%edi
+ roll $5,%eax
+ addl %esi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movl %ebx,%esi
+ xorl %ecx,%ebx
+ addl 12(%rsp),%edx
+ andl %ecx,%esi
+ andl %ebx,%edi
+ rorl $7,%eax
+ addl %esi,%edx
+ movl %ebp,%esi
+ roll $5,%ebp
+.byte 102,69,15,56,220,223
+ movups 144(%r15),%xmm14
+ addl %edi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movl %eax,%edi
+ pxor %xmm5,%xmm1
+.byte 102,68,15,58,15,207,8
+ xorl %ebx,%eax
+ addl 16(%rsp),%ecx
+ andl %ebx,%edi
+ pxor %xmm2,%xmm1
+ andl %eax,%esi
+ rorl $7,%ebp
+ movdqa %xmm10,%xmm8
+ paddd %xmm0,%xmm10
+ addl %edi,%ecx
+ movl %edx,%edi
+ pxor %xmm9,%xmm1
+ roll $5,%edx
+ addl %esi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movdqa %xmm1,%xmm9
+ movdqa %xmm10,0(%rsp)
+ movl %ebp,%esi
+ xorl %eax,%ebp
+ addl 20(%rsp),%ebx
+ andl %eax,%esi
+ pslld $2,%xmm1
+ andl %ebp,%edi
+.byte 102,69,15,56,220,222
+ movups 160(%r15),%xmm15
+ rorl $7,%edx
+ psrld $30,%xmm9
+ addl %esi,%ebx
+ movl %ecx,%esi
+ roll $5,%ecx
+ addl %edi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ por %xmm9,%xmm1
+ movl %edx,%edi
+ xorl %ebp,%edx
+ movdqa %xmm1,%xmm10
+ addl 24(%rsp),%eax
+ andl %ebp,%edi
+ andl %edx,%esi
+ rorl $7,%ecx
+ addl %edi,%eax
+ movl %ebx,%edi
+ roll $5,%ebx
+ addl %esi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ movl %ecx,%esi
+ cmpl $11,%r8d
+ jb L$aesenclast3
+ movups 176(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 192(%r15),%xmm15
+.byte 102,69,15,56,220,222
+ je L$aesenclast3
+ movups 208(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 224(%r15),%xmm15
+.byte 102,69,15,56,220,222
+L$aesenclast3:
+.byte 102,69,15,56,221,223
+ movups 16(%r15),%xmm14
+ xorl %edx,%ecx
+ addl 28(%rsp),%ebp
+ andl %edx,%esi
+ andl %ecx,%edi
+ rorl $7,%ebx
+ addl %esi,%ebp
+ movl %eax,%esi
+ roll $5,%eax
+ addl %edi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movl %ebx,%edi
+ pxor %xmm6,%xmm2
+.byte 102,68,15,58,15,208,8
+ xorl %ecx,%ebx
+ addl 32(%rsp),%edx
+ andl %ecx,%edi
+ pxor %xmm3,%xmm2
+ andl %ebx,%esi
+ rorl $7,%eax
+ movdqa %xmm8,%xmm9
+ paddd %xmm1,%xmm8
+ addl %edi,%edx
+ movl %ebp,%edi
+ pxor %xmm10,%xmm2
+ roll $5,%ebp
+ movups 48(%r12),%xmm12
+ xorps %xmm13,%xmm12
+ movups %xmm11,32(%r13,%r12,1)
+ xorps %xmm12,%xmm11
+.byte 102,69,15,56,220,222
+ movups 32(%r15),%xmm15
+ addl %esi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movdqa %xmm2,%xmm10
+ movdqa %xmm8,16(%rsp)
+ movl %eax,%esi
+ xorl %ebx,%eax
+ addl 36(%rsp),%ecx
+ andl %ebx,%esi
+ pslld $2,%xmm2
+ andl %eax,%edi
+ rorl $7,%ebp
+ psrld $30,%xmm10
+ addl %esi,%ecx
+ movl %edx,%esi
+ roll $5,%edx
+ addl %edi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ por %xmm10,%xmm2
+ movl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa %xmm2,%xmm8
+ addl 40(%rsp),%ebx
+ andl %eax,%edi
+ andl %ebp,%esi
+.byte 102,69,15,56,220,223
+ movups 48(%r15),%xmm14
+ rorl $7,%edx
+ addl %edi,%ebx
+ movl %ecx,%edi
+ roll $5,%ecx
+ addl %esi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movl %edx,%esi
+ xorl %ebp,%edx
+ addl 44(%rsp),%eax
+ andl %ebp,%esi
+ andl %edx,%edi
+ rorl $7,%ecx
+ addl %esi,%eax
+ movl %ebx,%esi
+ roll $5,%ebx
+ addl %edi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ addl 48(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 64(%r15),%xmm15
+ pxor %xmm7,%xmm3
+.byte 102,68,15,58,15,193,8
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ pxor %xmm4,%xmm3
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ movdqa %xmm9,%xmm10
+ paddd %xmm2,%xmm9
+ rorl $7,%ebx
+ addl %esi,%ebp
+ pxor %xmm8,%xmm3
+ addl 52(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ movdqa %xmm3,%xmm8
+ movdqa %xmm9,32(%rsp)
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ pslld $2,%xmm3
+ addl 56(%rsp),%ecx
+ xorl %ebx,%esi
+ psrld $30,%xmm8
+ movl %edx,%edi
+ roll $5,%edx
+ xorl %eax,%esi
+.byte 102,69,15,56,220,223
+ movups 80(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ por %xmm8,%xmm3
+ addl 60(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 0(%rsp),%eax
+ paddd %xmm3,%xmm10
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ movdqa %xmm10,48(%rsp)
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 4(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 96(%r15),%xmm15
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 8(%rsp),%edx
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 12(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+.byte 102,69,15,56,220,223
+ movups 112(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ cmpq %r14,%r10
+ je L$done_ssse3
+ movdqa 64(%r11),%xmm6
+ movdqa 0(%r11),%xmm9
+ movdqu 0(%r10),%xmm0
+ movdqu 16(%r10),%xmm1
+ movdqu 32(%r10),%xmm2
+ movdqu 48(%r10),%xmm3
+.byte 102,15,56,0,198
+ addq $64,%r10
+ addl 16(%rsp),%ebx
+ xorl %eax,%esi
+.byte 102,15,56,0,206
+ movl %ecx,%edi
+ roll $5,%ecx
+ paddd %xmm9,%xmm0
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ movdqa %xmm0,0(%rsp)
+ addl 20(%rsp),%eax
+ xorl %ebp,%edi
+ psubd %xmm9,%xmm0
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 24(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 128(%r15),%xmm15
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ addl 28(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 32(%rsp),%ecx
+ xorl %ebx,%esi
+.byte 102,15,56,0,214
+ movl %edx,%edi
+ roll $5,%edx
+ paddd %xmm9,%xmm1
+ xorl %eax,%esi
+.byte 102,69,15,56,220,223
+ movups 144(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ movdqa %xmm1,16(%rsp)
+ addl 36(%rsp),%ebx
+ xorl %eax,%edi
+ psubd %xmm9,%xmm1
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 40(%rsp),%eax
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 44(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 160(%r15),%xmm15
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 48(%rsp),%edx
+ xorl %ecx,%esi
+.byte 102,15,56,0,222
+ movl %ebp,%edi
+ roll $5,%ebp
+ paddd %xmm9,%xmm2
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ movdqa %xmm2,32(%rsp)
+ addl 52(%rsp),%ecx
+ xorl %ebx,%edi
+ psubd %xmm9,%xmm2
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ cmpl $11,%r8d
+ jb L$aesenclast4
+ movups 176(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 192(%r15),%xmm15
+.byte 102,69,15,56,220,222
+ je L$aesenclast4
+ movups 208(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 224(%r15),%xmm15
+.byte 102,69,15,56,220,222
+L$aesenclast4:
+.byte 102,69,15,56,221,223
+ movups 16(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 56(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 60(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ movups %xmm11,48(%r13,%r12,1)
+ leaq 64(%r12),%r12
+
+ addl 0(%r9),%eax
+ addl 4(%r9),%esi
+ addl 8(%r9),%ecx
+ addl 12(%r9),%edx
+ movl %eax,0(%r9)
+ addl 16(%r9),%ebp
+ movl %esi,4(%r9)
+ movl %esi,%ebx
+ movl %ecx,8(%r9)
+ movl %edx,12(%r9)
+ movl %ebp,16(%r9)
+ jmp L$oop_ssse3
+
+.p2align 4
+L$done_ssse3:
+ addl 16(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 20(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 24(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 128(%r15),%xmm15
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ addl 28(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 32(%rsp),%ecx
+ xorl %ebx,%esi
+ movl %edx,%edi
+ roll $5,%edx
+ xorl %eax,%esi
+.byte 102,69,15,56,220,223
+ movups 144(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ addl 36(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 40(%rsp),%eax
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 44(%rsp),%ebp
+.byte 102,69,15,56,220,222
+ movups 160(%r15),%xmm15
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 48(%rsp),%edx
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 52(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ cmpl $11,%r8d
+ jb L$aesenclast5
+ movups 176(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 192(%r15),%xmm15
+.byte 102,69,15,56,220,222
+ je L$aesenclast5
+ movups 208(%r15),%xmm14
+.byte 102,69,15,56,220,223
+ movups 224(%r15),%xmm15
+.byte 102,69,15,56,220,222
+L$aesenclast5:
+.byte 102,69,15,56,221,223
+ movups 16(%r15),%xmm14
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 56(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 60(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ movups %xmm11,48(%r13,%r12,1)
+ movq 88(%rsp),%r8
+
+ addl 0(%r9),%eax
+ addl 4(%r9),%esi
+ addl 8(%r9),%ecx
+ movl %eax,0(%r9)
+ addl 12(%r9),%edx
+ movl %esi,4(%r9)
+ addl 16(%r9),%ebp
+ movl %ecx,8(%r9)
+ movl %edx,12(%r9)
+ movl %ebp,16(%r9)
+ movups %xmm11,(%r8)
+ leaq 104(%rsp),%rsi
+ movq 0(%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+L$epilogue_ssse3:
+ .byte 0xf3,0xc3
+
+.p2align 6
+K_XX_XX:
+.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999
+
+.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1
+
+.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc
+
+.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6
+
+.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
+
+
+.byte 65,69,83,78,73,45,67,66,67,43,83,72,65,49,32,115,116,105,116,99,104,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align 6
diff --git a/deps/openssl/asm/x64-macosx-gas/aes/aesni-x86_64.s b/deps/openssl/asm/x64-macosx-gas/aes/aesni-x86_64.s
new file mode 100644
index 000000000..2ea2d3460
--- /dev/null
+++ b/deps/openssl/asm/x64-macosx-gas/aes/aesni-x86_64.s
@@ -0,0 +1,2558 @@
+.text
+
+.globl _aesni_encrypt
+
+.p2align 4
+_aesni_encrypt:
+ movups (%rdi),%xmm2
+ movl 240(%rdx),%eax
+ movups (%rdx),%xmm0
+ movups 16(%rdx),%xmm1
+ leaq 32(%rdx),%rdx
+ xorps %xmm0,%xmm2
+L$oop_enc1_1:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rdx),%xmm1
+ leaq 16(%rdx),%rdx
+ jnz L$oop_enc1_1
+
+.byte 102,15,56,221,209
+ movups %xmm2,(%rsi)
+ .byte 0xf3,0xc3
+
+
+.globl _aesni_decrypt
+
+.p2align 4
+_aesni_decrypt:
+ movups (%rdi),%xmm2
+ movl 240(%rdx),%eax
+ movups (%rdx),%xmm0
+ movups 16(%rdx),%xmm1
+ leaq 32(%rdx),%rdx
+ xorps %xmm0,%xmm2
+L$oop_dec1_2:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rdx),%xmm1
+ leaq 16(%rdx),%rdx
+ jnz L$oop_dec1_2
+
+.byte 102,15,56,223,209
+ movups %xmm2,(%rsi)
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+_aesni_encrypt3:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+ xorps %xmm0,%xmm4
+ movups (%rcx),%xmm0
+
+L$enc_loop3:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+ movups (%rcx),%xmm0
+ jnz L$enc_loop3
+
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+_aesni_decrypt3:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+ xorps %xmm0,%xmm4
+ movups (%rcx),%xmm0
+
+L$dec_loop3:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %eax
+.byte 102,15,56,222,225
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,222,224
+ movups (%rcx),%xmm0
+ jnz L$dec_loop3
+
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+_aesni_encrypt4:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+ xorps %xmm0,%xmm4
+ xorps %xmm0,%xmm5
+ movups (%rcx),%xmm0
+
+L$enc_loop4:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+ movups (%rcx),%xmm0
+ jnz L$enc_loop4
+
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+.byte 102,15,56,221,232
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+_aesni_decrypt4:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+ xorps %xmm0,%xmm4
+ xorps %xmm0,%xmm5
+ movups (%rcx),%xmm0
+
+L$dec_loop4:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %eax
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+ movups (%rcx),%xmm0
+ jnz L$dec_loop4
+
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+.byte 102,15,56,223,232
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+_aesni_encrypt6:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+.byte 102,15,56,220,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,220,217
+ pxor %xmm0,%xmm5
+.byte 102,15,56,220,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+ decl %eax
+.byte 102,15,56,220,241
+ movups (%rcx),%xmm0
+.byte 102,15,56,220,249
+ jmp L$enc_loop6_enter
+.p2align 4
+L$enc_loop6:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+L$enc_loop6_enter:
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+ movups (%rcx),%xmm0
+ jnz L$enc_loop6
+
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+.byte 102,15,56,221,232
+.byte 102,15,56,221,240
+.byte 102,15,56,221,248
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+_aesni_decrypt6:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+.byte 102,15,56,222,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,222,217
+ pxor %xmm0,%xmm5
+.byte 102,15,56,222,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+ decl %eax
+.byte 102,15,56,222,241
+ movups (%rcx),%xmm0
+.byte 102,15,56,222,249
+ jmp L$dec_loop6_enter
+.p2align 4
+L$dec_loop6:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %eax
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+L$dec_loop6_enter:
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+.byte 102,15,56,222,240
+.byte 102,15,56,222,248
+ movups (%rcx),%xmm0
+ jnz L$dec_loop6
+
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+.byte 102,15,56,223,232
+.byte 102,15,56,223,240
+.byte 102,15,56,223,248
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+_aesni_encrypt8:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+.byte 102,15,56,220,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,220,217
+ pxor %xmm0,%xmm5
+.byte 102,15,56,220,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+ decl %eax
+.byte 102,15,56,220,241
+ pxor %xmm0,%xmm8
+.byte 102,15,56,220,249
+ pxor %xmm0,%xmm9
+ movups (%rcx),%xmm0
+.byte 102,68,15,56,220,193
+.byte 102,68,15,56,220,201
+ movups 16(%rcx),%xmm1
+ jmp L$enc_loop8_enter
+.p2align 4
+L$enc_loop8:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.byte 102,68,15,56,220,193
+.byte 102,68,15,56,220,201
+ movups 16(%rcx),%xmm1
+L$enc_loop8_enter:
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+.byte 102,68,15,56,220,192
+.byte 102,68,15,56,220,200
+ movups (%rcx),%xmm0
+ jnz L$enc_loop8
+
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.byte 102,68,15,56,220,193
+.byte 102,68,15,56,220,201
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+.byte 102,15,56,221,232
+.byte 102,15,56,221,240
+.byte 102,15,56,221,248
+.byte 102,68,15,56,221,192
+.byte 102,68,15,56,221,200
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+_aesni_decrypt8:
+ movups (%rcx),%xmm0
+ shrl $1,%eax
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm0,%xmm3
+.byte 102,15,56,222,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,222,217
+ pxor %xmm0,%xmm5
+.byte 102,15,56,222,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+ decl %eax
+.byte 102,15,56,222,241
+ pxor %xmm0,%xmm8
+.byte 102,15,56,222,249
+ pxor %xmm0,%xmm9
+ movups (%rcx),%xmm0
+.byte 102,68,15,56,222,193
+.byte 102,68,15,56,222,201
+ movups 16(%rcx),%xmm1
+ jmp L$dec_loop8_enter
+.p2align 4
+L$dec_loop8:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %eax
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.byte 102,68,15,56,222,193
+.byte 102,68,15,56,222,201
+ movups 16(%rcx),%xmm1
+L$dec_loop8_enter:
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+.byte 102,15,56,222,240
+.byte 102,15,56,222,248
+.byte 102,68,15,56,222,192
+.byte 102,68,15,56,222,200
+ movups (%rcx),%xmm0
+ jnz L$dec_loop8
+
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.byte 102,68,15,56,222,193
+.byte 102,68,15,56,222,201
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+.byte 102,15,56,223,232
+.byte 102,15,56,223,240
+.byte 102,15,56,223,248
+.byte 102,68,15,56,223,192
+.byte 102,68,15,56,223,200
+ .byte 0xf3,0xc3
+
+.globl _aesni_ecb_encrypt
+
+.p2align 4
+_aesni_ecb_encrypt:
+ andq $-16,%rdx
+ jz L$ecb_ret
+
+ movl 240(%rcx),%eax
+ movups (%rcx),%xmm0
+ movq %rcx,%r11
+ movl %eax,%r10d
+ testl %r8d,%r8d
+ jz L$ecb_decrypt
+
+ cmpq $128,%rdx
+ jb L$ecb_enc_tail
+
+ movdqu (%rdi),%xmm2
+ movdqu 16(%rdi),%xmm3
+ movdqu 32(%rdi),%xmm4
+ movdqu 48(%rdi),%xmm5
+ movdqu 64(%rdi),%xmm6
+ movdqu 80(%rdi),%xmm7
+ movdqu 96(%rdi),%xmm8
+ movdqu 112(%rdi),%xmm9
+ leaq 128(%rdi),%rdi
+ subq $128,%rdx
+ jmp L$ecb_enc_loop8_enter
+.p2align 4
+L$ecb_enc_loop8:
+ movups %xmm2,(%rsi)
+ movq %r11,%rcx
+ movdqu (%rdi),%xmm2
+ movl %r10d,%eax
+ movups %xmm3,16(%rsi)
+ movdqu 16(%rdi),%xmm3
+ movups %xmm4,32(%rsi)
+ movdqu 32(%rdi),%xmm4
+ movups %xmm5,48(%rsi)
+ movdqu 48(%rdi),%xmm5
+ movups %xmm6,64(%rsi)
+ movdqu 64(%rdi),%xmm6
+ movups %xmm7,80(%rsi)
+ movdqu 80(%rdi),%xmm7
+ movups %xmm8,96(%rsi)
+ movdqu 96(%rdi),%xmm8
+ movups %xmm9,112(%rsi)
+ leaq 128(%rsi),%rsi
+ movdqu 112(%rdi),%xmm9
+ leaq 128(%rdi),%rdi
+L$ecb_enc_loop8_enter:
+
+ call _aesni_encrypt8
+
+ subq $128,%rdx
+ jnc L$ecb_enc_loop8
+
+ movups %xmm2,(%rsi)
+ movq %r11,%rcx
+ movups %xmm3,16(%rsi)
+ movl %r10d,%eax
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ movups %xmm8,96(%rsi)
+ movups %xmm9,112(%rsi)
+ leaq 128(%rsi),%rsi
+ addq $128,%rdx
+ jz L$ecb_ret
+
+L$ecb_enc_tail:
+ movups (%rdi),%xmm2
+ cmpq $32,%rdx
+ jb L$ecb_enc_one
+ movups 16(%rdi),%xmm3
+ je L$ecb_enc_two
+ movups 32(%rdi),%xmm4
+ cmpq $64,%rdx
+ jb L$ecb_enc_three
+ movups 48(%rdi),%xmm5
+ je L$ecb_enc_four
+ movups 64(%rdi),%xmm6
+ cmpq $96,%rdx
+ jb L$ecb_enc_five
+ movups 80(%rdi),%xmm7
+ je L$ecb_enc_six
+ movdqu 96(%rdi),%xmm8
+ call _aesni_encrypt8
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ movups %xmm8,96(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_enc_one:
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+L$oop_enc1_3:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_enc1_3
+
+.byte 102,15,56,221,209
+ movups %xmm2,(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_enc_two:
+ xorps %xmm4,%xmm4
+ call _aesni_encrypt3
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_enc_three:
+ call _aesni_encrypt3
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_enc_four:
+ call _aesni_encrypt4
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_enc_five:
+ xorps %xmm7,%xmm7
+ call _aesni_encrypt6
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_enc_six:
+ call _aesni_encrypt6
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ jmp L$ecb_ret
+
+.p2align 4
+L$ecb_decrypt:
+ cmpq $128,%rdx
+ jb L$ecb_dec_tail
+
+ movdqu (%rdi),%xmm2
+ movdqu 16(%rdi),%xmm3
+ movdqu 32(%rdi),%xmm4
+ movdqu 48(%rdi),%xmm5
+ movdqu 64(%rdi),%xmm6
+ movdqu 80(%rdi),%xmm7
+ movdqu 96(%rdi),%xmm8
+ movdqu 112(%rdi),%xmm9
+ leaq 128(%rdi),%rdi
+ subq $128,%rdx
+ jmp L$ecb_dec_loop8_enter
+.p2align 4
+L$ecb_dec_loop8:
+ movups %xmm2,(%rsi)
+ movq %r11,%rcx
+ movdqu (%rdi),%xmm2
+ movl %r10d,%eax
+ movups %xmm3,16(%rsi)
+ movdqu 16(%rdi),%xmm3
+ movups %xmm4,32(%rsi)
+ movdqu 32(%rdi),%xmm4
+ movups %xmm5,48(%rsi)
+ movdqu 48(%rdi),%xmm5
+ movups %xmm6,64(%rsi)
+ movdqu 64(%rdi),%xmm6
+ movups %xmm7,80(%rsi)
+ movdqu 80(%rdi),%xmm7
+ movups %xmm8,96(%rsi)
+ movdqu 96(%rdi),%xmm8
+ movups %xmm9,112(%rsi)
+ leaq 128(%rsi),%rsi
+ movdqu 112(%rdi),%xmm9
+ leaq 128(%rdi),%rdi
+L$ecb_dec_loop8_enter:
+
+ call _aesni_decrypt8
+
+ movups (%r11),%xmm0
+ subq $128,%rdx
+ jnc L$ecb_dec_loop8
+
+ movups %xmm2,(%rsi)
+ movq %r11,%rcx
+ movups %xmm3,16(%rsi)
+ movl %r10d,%eax
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ movups %xmm8,96(%rsi)
+ movups %xmm9,112(%rsi)
+ leaq 128(%rsi),%rsi
+ addq $128,%rdx
+ jz L$ecb_ret
+
+L$ecb_dec_tail:
+ movups (%rdi),%xmm2
+ cmpq $32,%rdx
+ jb L$ecb_dec_one
+ movups 16(%rdi),%xmm3
+ je L$ecb_dec_two
+ movups 32(%rdi),%xmm4
+ cmpq $64,%rdx
+ jb L$ecb_dec_three
+ movups 48(%rdi),%xmm5
+ je L$ecb_dec_four
+ movups 64(%rdi),%xmm6
+ cmpq $96,%rdx
+ jb L$ecb_dec_five
+ movups 80(%rdi),%xmm7
+ je L$ecb_dec_six
+ movups 96(%rdi),%xmm8
+ movups (%rcx),%xmm0
+ call _aesni_decrypt8
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ movups %xmm8,96(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_dec_one:
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+L$oop_dec1_4:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_dec1_4
+
+.byte 102,15,56,223,209
+ movups %xmm2,(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_dec_two:
+ xorps %xmm4,%xmm4
+ call _aesni_decrypt3
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_dec_three:
+ call _aesni_decrypt3
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_dec_four:
+ call _aesni_decrypt4
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_dec_five:
+ xorps %xmm7,%xmm7
+ call _aesni_decrypt6
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ jmp L$ecb_ret
+.p2align 4
+L$ecb_dec_six:
+ call _aesni_decrypt6
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+
+L$ecb_ret:
+ .byte 0xf3,0xc3
+
+.globl _aesni_ccm64_encrypt_blocks
+
+.p2align 4
+_aesni_ccm64_encrypt_blocks:
+ movl 240(%rcx),%eax
+ movdqu (%r8),%xmm9
+ movdqa L$increment64(%rip),%xmm6
+ movdqa L$bswap_mask(%rip),%xmm7
+
+ shrl $1,%eax
+ leaq 0(%rcx),%r11
+ movdqu (%r9),%xmm3
+ movdqa %xmm9,%xmm2
+ movl %eax,%r10d
+.byte 102,68,15,56,0,207
+ jmp L$ccm64_enc_outer
+.p2align 4
+L$ccm64_enc_outer:
+ movups (%r11),%xmm0
+ movl %r10d,%eax
+ movups (%rdi),%xmm8
+
+ xorps %xmm0,%xmm2
+ movups 16(%r11),%xmm1
+ xorps %xmm8,%xmm0
+ leaq 32(%r11),%rcx
+ xorps %xmm0,%xmm3
+ movups (%rcx),%xmm0
+
+L$ccm64_enc2_loop:
+.byte 102,15,56,220,209
+ decl %eax
+.byte 102,15,56,220,217
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,216
+ movups 0(%rcx),%xmm0
+ jnz L$ccm64_enc2_loop
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ paddq %xmm6,%xmm9
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+
+ decq %rdx
+ leaq 16(%rdi),%rdi
+ xorps %xmm2,%xmm8
+ movdqa %xmm9,%xmm2
+ movups %xmm8,(%rsi)
+ leaq 16(%rsi),%rsi
+.byte 102,15,56,0,215
+ jnz L$ccm64_enc_outer
+
+ movups %xmm3,(%r9)
+ .byte 0xf3,0xc3
+
+.globl _aesni_ccm64_decrypt_blocks
+
+.p2align 4
+_aesni_ccm64_decrypt_blocks:
+ movl 240(%rcx),%eax
+ movups (%r8),%xmm9
+ movdqu (%r9),%xmm3
+ movdqa L$increment64(%rip),%xmm6
+ movdqa L$bswap_mask(%rip),%xmm7
+
+ movaps %xmm9,%xmm2
+ movl %eax,%r10d
+ movq %rcx,%r11
+.byte 102,68,15,56,0,207
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+L$oop_enc1_5:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_enc1_5
+
+.byte 102,15,56,221,209
+ movups (%rdi),%xmm8
+ paddq %xmm6,%xmm9
+ leaq 16(%rdi),%rdi
+ jmp L$ccm64_dec_outer
+.p2align 4
+L$ccm64_dec_outer:
+ xorps %xmm2,%xmm8
+ movdqa %xmm9,%xmm2
+ movl %r10d,%eax
+ movups %xmm8,(%rsi)
+ leaq 16(%rsi),%rsi
+.byte 102,15,56,0,215
+
+ subq $1,%rdx
+ jz L$ccm64_dec_break
+
+ movups (%r11),%xmm0
+ shrl $1,%eax
+ movups 16(%r11),%xmm1
+ xorps %xmm0,%xmm8
+ leaq 32(%r11),%rcx
+ xorps %xmm0,%xmm2
+ xorps %xmm8,%xmm3
+ movups (%rcx),%xmm0
+
+L$ccm64_dec2_loop:
+.byte 102,15,56,220,209
+ decl %eax
+.byte 102,15,56,220,217
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,216
+ movups 0(%rcx),%xmm0
+ jnz L$ccm64_dec2_loop
+ movups (%rdi),%xmm8
+ paddq %xmm6,%xmm9
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ leaq 16(%rdi),%rdi
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+ jmp L$ccm64_dec_outer
+
+.p2align 4
+L$ccm64_dec_break:
+
+ movups (%r11),%xmm0
+ movups 16(%r11),%xmm1
+ xorps %xmm0,%xmm8
+ leaq 32(%r11),%r11
+ xorps %xmm8,%xmm3
+L$oop_enc1_6:
+.byte 102,15,56,220,217
+ decl %eax
+ movups (%r11),%xmm1
+ leaq 16(%r11),%r11
+ jnz L$oop_enc1_6
+
+.byte 102,15,56,221,217
+ movups %xmm3,(%r9)
+ .byte 0xf3,0xc3
+
+.globl _aesni_ctr32_encrypt_blocks
+
+.p2align 4
+_aesni_ctr32_encrypt_blocks:
+ cmpq $1,%rdx
+ je L$ctr32_one_shortcut
+
+ movdqu (%r8),%xmm14
+ movdqa L$bswap_mask(%rip),%xmm15
+ xorl %eax,%eax
+.byte 102,69,15,58,22,242,3
+.byte 102,68,15,58,34,240,3
+
+ movl 240(%rcx),%eax
+ bswapl %r10d
+ pxor %xmm12,%xmm12
+ pxor %xmm13,%xmm13
+.byte 102,69,15,58,34,226,0
+ leaq 3(%r10),%r11
+.byte 102,69,15,58,34,235,0
+ incl %r10d
+.byte 102,69,15,58,34,226,1
+ incq %r11
+.byte 102,69,15,58,34,235,1
+ incl %r10d
+.byte 102,69,15,58,34,226,2
+ incq %r11
+.byte 102,69,15,58,34,235,2
+ movdqa %xmm12,-40(%rsp)
+.byte 102,69,15,56,0,231
+ movdqa %xmm13,-24(%rsp)
+.byte 102,69,15,56,0,239
+
+ pshufd $192,%xmm12,%xmm2
+ pshufd $128,%xmm12,%xmm3
+ pshufd $64,%xmm12,%xmm4
+ cmpq $6,%rdx
+ jb L$ctr32_tail
+ shrl $1,%eax
+ movq %rcx,%r11
+ movl %eax,%r10d
+ subq $6,%rdx
+ jmp L$ctr32_loop6
+
+.p2align 4
+L$ctr32_loop6:
+ pshufd $192,%xmm13,%xmm5
+ por %xmm14,%xmm2
+ movups (%r11),%xmm0
+ pshufd $128,%xmm13,%xmm6
+ por %xmm14,%xmm3
+ movups 16(%r11),%xmm1
+ pshufd $64,%xmm13,%xmm7
+ por %xmm14,%xmm4
+ por %xmm14,%xmm5
+ xorps %xmm0,%xmm2
+ por %xmm14,%xmm6
+ por %xmm14,%xmm7
+
+
+
+
+ pxor %xmm0,%xmm3
+.byte 102,15,56,220,209
+ leaq 32(%r11),%rcx
+ pxor %xmm0,%xmm4
+.byte 102,15,56,220,217
+ movdqa L$increment32(%rip),%xmm13
+ pxor %xmm0,%xmm5
+.byte 102,15,56,220,225
+ movdqa -40(%rsp),%xmm12
+ pxor %xmm0,%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+ movups (%rcx),%xmm0
+ decl %eax
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+ jmp L$ctr32_enc_loop6_enter
+.p2align 4
+L$ctr32_enc_loop6:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+L$ctr32_enc_loop6_enter:
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+ movups (%rcx),%xmm0
+ jnz L$ctr32_enc_loop6
+
+.byte 102,15,56,220,209
+ paddd %xmm13,%xmm12
+.byte 102,15,56,220,217
+ paddd -24(%rsp),%xmm13
+.byte 102,15,56,220,225
+ movdqa %xmm12,-40(%rsp)
+.byte 102,15,56,220,233
+ movdqa %xmm13,-24(%rsp)
+.byte 102,15,56,220,241
+.byte 102,69,15,56,0,231
+.byte 102,15,56,220,249
+.byte 102,69,15,56,0,239
+
+.byte 102,15,56,221,208
+ movups (%rdi),%xmm8
+.byte 102,15,56,221,216
+ movups 16(%rdi),%xmm9
+.byte 102,15,56,221,224
+ movups 32(%rdi),%xmm10
+.byte 102,15,56,221,232
+ movups 48(%rdi),%xmm11
+.byte 102,15,56,221,240
+ movups 64(%rdi),%xmm1
+.byte 102,15,56,221,248
+ movups 80(%rdi),%xmm0
+ leaq 96(%rdi),%rdi
+
+ xorps %xmm2,%xmm8
+ pshufd $192,%xmm12,%xmm2
+ xorps %xmm3,%xmm9
+ pshufd $128,%xmm12,%xmm3
+ movups %xmm8,(%rsi)
+ xorps %xmm4,%xmm10
+ pshufd $64,%xmm12,%xmm4
+ movups %xmm9,16(%rsi)
+ xorps %xmm5,%xmm11
+ movups %xmm10,32(%rsi)
+ xorps %xmm6,%xmm1
+ movups %xmm11,48(%rsi)
+ xorps %xmm7,%xmm0
+ movups %xmm1,64(%rsi)
+ movups %xmm0,80(%rsi)
+ leaq 96(%rsi),%rsi
+ movl %r10d,%eax
+ subq $6,%rdx
+ jnc L$ctr32_loop6
+
+ addq $6,%rdx
+ jz L$ctr32_done
+ movq %r11,%rcx
+ leal 1(%rax,%rax,1),%eax
+
+L$ctr32_tail:
+ por %xmm14,%xmm2
+ movups (%rdi),%xmm8
+ cmpq $2,%rdx
+ jb L$ctr32_one
+
+ por %xmm14,%xmm3
+ movups 16(%rdi),%xmm9
+ je L$ctr32_two
+
+ pshufd $192,%xmm13,%xmm5
+ por %xmm14,%xmm4
+ movups 32(%rdi),%xmm10
+ cmpq $4,%rdx
+ jb L$ctr32_three
+
+ pshufd $128,%xmm13,%xmm6
+ por %xmm14,%xmm5
+ movups 48(%rdi),%xmm11
+ je L$ctr32_four
+
+ por %xmm14,%xmm6
+ xorps %xmm7,%xmm7
+
+ call _aesni_encrypt6
+
+ movups 64(%rdi),%xmm1
+ xorps %xmm2,%xmm8
+ xorps %xmm3,%xmm9
+ movups %xmm8,(%rsi)
+ xorps %xmm4,%xmm10
+ movups %xmm9,16(%rsi)
+ xorps %xmm5,%xmm11
+ movups %xmm10,32(%rsi)
+ xorps %xmm6,%xmm1
+ movups %xmm11,48(%rsi)
+ movups %xmm1,64(%rsi)
+ jmp L$ctr32_done
+
+.p2align 4
+L$ctr32_one_shortcut:
+ movups (%r8),%xmm2
+ movups (%rdi),%xmm8
+ movl 240(%rcx),%eax
+L$ctr32_one:
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+L$oop_enc1_7:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_enc1_7
+
+.byte 102,15,56,221,209
+ xorps %xmm2,%xmm8
+ movups %xmm8,(%rsi)
+ jmp L$ctr32_done
+
+.p2align 4
+L$ctr32_two:
+ xorps %xmm4,%xmm4
+ call _aesni_encrypt3
+ xorps %xmm2,%xmm8
+ xorps %xmm3,%xmm9
+ movups %xmm8,(%rsi)
+ movups %xmm9,16(%rsi)
+ jmp L$ctr32_done
+
+.p2align 4
+L$ctr32_three:
+ call _aesni_encrypt3
+ xorps %xmm2,%xmm8
+ xorps %xmm3,%xmm9
+ movups %xmm8,(%rsi)
+ xorps %xmm4,%xmm10
+ movups %xmm9,16(%rsi)
+ movups %xmm10,32(%rsi)
+ jmp L$ctr32_done
+
+.p2align 4
+L$ctr32_four:
+ call _aesni_encrypt4
+ xorps %xmm2,%xmm8
+ xorps %xmm3,%xmm9
+ movups %xmm8,(%rsi)
+ xorps %xmm4,%xmm10
+ movups %xmm9,16(%rsi)
+ xorps %xmm5,%xmm11
+ movups %xmm10,32(%rsi)
+ movups %xmm11,48(%rsi)
+
+L$ctr32_done:
+ .byte 0xf3,0xc3
+
+.globl _aesni_xts_encrypt
+
+.p2align 4
+_aesni_xts_encrypt:
+ leaq -104(%rsp),%rsp
+ movups (%r9),%xmm15
+ movl 240(%r8),%eax
+ movl 240(%rcx),%r10d
+ movups (%r8),%xmm0
+ movups 16(%r8),%xmm1
+ leaq 32(%r8),%r8
+ xorps %xmm0,%xmm15
+L$oop_enc1_8:
+.byte 102,68,15,56,220,249
+ decl %eax
+ movups (%r8),%xmm1
+ leaq 16(%r8),%r8
+ jnz L$oop_enc1_8
+
+.byte 102,68,15,56,221,249
+ movq %rcx,%r11
+ movl %r10d,%eax
+ movq %rdx,%r9
+ andq $-16,%rdx
+
+ movdqa L$xts_magic(%rip),%xmm8
+ pxor %xmm14,%xmm14
+ pcmpgtd %xmm15,%xmm14
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm10
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm11
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm12
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm13
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ subq $96,%rdx
+ jc L$xts_enc_short
+
+ shrl $1,%eax
+ subl $1,%eax
+ movl %eax,%r10d
+ jmp L$xts_enc_grandloop
+
+.p2align 4
+L$xts_enc_grandloop:
+ pshufd $19,%xmm14,%xmm9
+ movdqa %xmm15,%xmm14
+ paddq %xmm15,%xmm15
+ movdqu 0(%rdi),%xmm2
+ pand %xmm8,%xmm9
+ movdqu 16(%rdi),%xmm3
+ pxor %xmm9,%xmm15
+
+ movdqu 32(%rdi),%xmm4
+ pxor %xmm10,%xmm2
+ movdqu 48(%rdi),%xmm5
+ pxor %xmm11,%xmm3
+ movdqu 64(%rdi),%xmm6
+ pxor %xmm12,%xmm4
+ movdqu 80(%rdi),%xmm7
+ leaq 96(%rdi),%rdi
+ pxor %xmm13,%xmm5
+ movups (%r11),%xmm0
+ pxor %xmm14,%xmm6
+ pxor %xmm15,%xmm7
+
+
+
+ movups 16(%r11),%xmm1
+ pxor %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ movdqa %xmm10,0(%rsp)
+.byte 102,15,56,220,209
+ leaq 32(%r11),%rcx
+ pxor %xmm0,%xmm4
+ movdqa %xmm11,16(%rsp)
+.byte 102,15,56,220,217
+ pxor %xmm0,%xmm5
+ movdqa %xmm12,32(%rsp)
+.byte 102,15,56,220,225
+ pxor %xmm0,%xmm6
+ movdqa %xmm13,48(%rsp)
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+ movups (%rcx),%xmm0
+ decl %eax
+ movdqa %xmm14,64(%rsp)
+.byte 102,15,56,220,241
+ movdqa %xmm15,80(%rsp)
+.byte 102,15,56,220,249
+ pxor %xmm14,%xmm14
+ pcmpgtd %xmm15,%xmm14
+ jmp L$xts_enc_loop6_enter
+
+.p2align 4
+L$xts_enc_loop6:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %eax
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+L$xts_enc_loop6_enter:
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+ movups (%rcx),%xmm0
+ jnz L$xts_enc_loop6
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ paddq %xmm15,%xmm15
+.byte 102,15,56,220,209
+ pand %xmm8,%xmm9
+.byte 102,15,56,220,217
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,220,225
+ pxor %xmm9,%xmm15
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+ movups 16(%rcx),%xmm1
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm10
+ paddq %xmm15,%xmm15
+.byte 102,15,56,220,208
+ pand %xmm8,%xmm9
+.byte 102,15,56,220,216
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,220,224
+ pxor %xmm9,%xmm15
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+ movups 32(%rcx),%xmm0
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm11
+ paddq %xmm15,%xmm15
+.byte 102,15,56,220,209
+ pand %xmm8,%xmm9
+.byte 102,15,56,220,217
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,220,225
+ pxor %xmm9,%xmm15
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm12
+ paddq %xmm15,%xmm15
+.byte 102,15,56,221,208
+ pand %xmm8,%xmm9
+.byte 102,15,56,221,216
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,221,224
+ pxor %xmm9,%xmm15
+.byte 102,15,56,221,232
+.byte 102,15,56,221,240
+.byte 102,15,56,221,248
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm13
+ paddq %xmm15,%xmm15
+ xorps 0(%rsp),%xmm2
+ pand %xmm8,%xmm9
+ xorps 16(%rsp),%xmm3
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+
+ xorps 32(%rsp),%xmm4
+ movups %xmm2,0(%rsi)
+ xorps 48(%rsp),%xmm5
+ movups %xmm3,16(%rsi)
+ xorps 64(%rsp),%xmm6
+ movups %xmm4,32(%rsi)
+ xorps 80(%rsp),%xmm7
+ movups %xmm5,48(%rsi)
+ movl %r10d,%eax
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ leaq 96(%rsi),%rsi
+ subq $96,%rdx
+ jnc L$xts_enc_grandloop
+
+ leal 3(%rax,%rax,1),%eax
+ movq %r11,%rcx
+ movl %eax,%r10d
+
+L$xts_enc_short:
+ addq $96,%rdx
+ jz L$xts_enc_done
+
+ cmpq $32,%rdx
+ jb L$xts_enc_one
+ je L$xts_enc_two
+
+ cmpq $64,%rdx
+ jb L$xts_enc_three
+ je L$xts_enc_four
+
+ pshufd $19,%xmm14,%xmm9
+ movdqa %xmm15,%xmm14
+ paddq %xmm15,%xmm15
+ movdqu (%rdi),%xmm2
+ pand %xmm8,%xmm9
+ movdqu 16(%rdi),%xmm3
+ pxor %xmm9,%xmm15
+
+ movdqu 32(%rdi),%xmm4
+ pxor %xmm10,%xmm2
+ movdqu 48(%rdi),%xmm5
+ pxor %xmm11,%xmm3
+ movdqu 64(%rdi),%xmm6
+ leaq 80(%rdi),%rdi
+ pxor %xmm12,%xmm4
+ pxor %xmm13,%xmm5
+ pxor %xmm14,%xmm6
+
+ call _aesni_encrypt6
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm15,%xmm10
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ movdqu %xmm2,(%rsi)
+ xorps %xmm13,%xmm5
+ movdqu %xmm3,16(%rsi)
+ xorps %xmm14,%xmm6
+ movdqu %xmm4,32(%rsi)
+ movdqu %xmm5,48(%rsi)
+ movdqu %xmm6,64(%rsi)
+ leaq 80(%rsi),%rsi
+ jmp L$xts_enc_done
+
+.p2align 4
+L$xts_enc_one:
+ movups (%rdi),%xmm2
+ leaq 16(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+L$oop_enc1_9:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_enc1_9
+
+.byte 102,15,56,221,209
+ xorps %xmm10,%xmm2
+ movdqa %xmm11,%xmm10
+ movups %xmm2,(%rsi)
+ leaq 16(%rsi),%rsi
+ jmp L$xts_enc_done
+
+.p2align 4
+L$xts_enc_two:
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ leaq 32(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ xorps %xmm11,%xmm3
+
+ call _aesni_encrypt3
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm12,%xmm10
+ xorps %xmm11,%xmm3
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ leaq 32(%rsi),%rsi
+ jmp L$xts_enc_done
+
+.p2align 4
+L$xts_enc_three:
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ movups 32(%rdi),%xmm4
+ leaq 48(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+
+ call _aesni_encrypt3
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm13,%xmm10
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ leaq 48(%rsi),%rsi
+ jmp L$xts_enc_done
+
+.p2align 4
+L$xts_enc_four:
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ movups 32(%rdi),%xmm4
+ xorps %xmm10,%xmm2
+ movups 48(%rdi),%xmm5
+ leaq 64(%rdi),%rdi
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ xorps %xmm13,%xmm5
+
+ call _aesni_encrypt4
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm15,%xmm10
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ movups %xmm2,(%rsi)
+ xorps %xmm13,%xmm5
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ leaq 64(%rsi),%rsi
+ jmp L$xts_enc_done
+
+.p2align 4
+L$xts_enc_done:
+ andq $15,%r9
+ jz L$xts_enc_ret
+ movq %r9,%rdx
+
+L$xts_enc_steal:
+ movzbl (%rdi),%eax
+ movzbl -16(%rsi),%ecx
+ leaq 1(%rdi),%rdi
+ movb %al,-16(%rsi)
+ movb %cl,0(%rsi)
+ leaq 1(%rsi),%rsi
+ subq $1,%rdx
+ jnz L$xts_enc_steal
+
+ subq %r9,%rsi
+ movq %r11,%rcx
+ movl %r10d,%eax
+
+ movups -16(%rsi),%xmm2
+ xorps %xmm10,%xmm2
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+L$oop_enc1_10:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_enc1_10
+
+.byte 102,15,56,221,209
+ xorps %xmm10,%xmm2
+ movups %xmm2,-16(%rsi)
+
+L$xts_enc_ret:
+ leaq 104(%rsp),%rsp
+L$xts_enc_epilogue:
+ .byte 0xf3,0xc3
+
+.globl _aesni_xts_decrypt
+
+.p2align 4
+_aesni_xts_decrypt:
+ leaq -104(%rsp),%rsp
+ movups (%r9),%xmm15
+ movl 240(%r8),%eax
+ movl 240(%rcx),%r10d
+ movups (%r8),%xmm0
+ movups 16(%r8),%xmm1
+ leaq 32(%r8),%r8
+ xorps %xmm0,%xmm15
+L$oop_enc1_11:
+.byte 102,68,15,56,220,249
+ decl %eax
+ movups (%r8),%xmm1
+ leaq 16(%r8),%r8
+ jnz L$oop_enc1_11
+
+.byte 102,68,15,56,221,249
+ xorl %eax,%eax
+ testq $15,%rdx
+ setnz %al
+ shlq $4,%rax
+ subq %rax,%rdx
+
+ movq %rcx,%r11
+ movl %r10d,%eax
+ movq %rdx,%r9
+ andq $-16,%rdx
+
+ movdqa L$xts_magic(%rip),%xmm8
+ pxor %xmm14,%xmm14
+ pcmpgtd %xmm15,%xmm14
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm10
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm11
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm12
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm13
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm9
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+ subq $96,%rdx
+ jc L$xts_dec_short
+
+ shrl $1,%eax
+ subl $1,%eax
+ movl %eax,%r10d
+ jmp L$xts_dec_grandloop
+
+.p2align 4
+L$xts_dec_grandloop:
+ pshufd $19,%xmm14,%xmm9
+ movdqa %xmm15,%xmm14
+ paddq %xmm15,%xmm15
+ movdqu 0(%rdi),%xmm2
+ pand %xmm8,%xmm9
+ movdqu 16(%rdi),%xmm3
+ pxor %xmm9,%xmm15
+
+ movdqu 32(%rdi),%xmm4
+ pxor %xmm10,%xmm2
+ movdqu 48(%rdi),%xmm5
+ pxor %xmm11,%xmm3
+ movdqu 64(%rdi),%xmm6
+ pxor %xmm12,%xmm4
+ movdqu 80(%rdi),%xmm7
+ leaq 96(%rdi),%rdi
+ pxor %xmm13,%xmm5
+ movups (%r11),%xmm0
+ pxor %xmm14,%xmm6
+ pxor %xmm15,%xmm7
+
+
+
+ movups 16(%r11),%xmm1
+ pxor %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ movdqa %xmm10,0(%rsp)
+.byte 102,15,56,222,209
+ leaq 32(%r11),%rcx
+ pxor %xmm0,%xmm4
+ movdqa %xmm11,16(%rsp)
+.byte 102,15,56,222,217
+ pxor %xmm0,%xmm5
+ movdqa %xmm12,32(%rsp)
+.byte 102,15,56,222,225
+ pxor %xmm0,%xmm6
+ movdqa %xmm13,48(%rsp)
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+ movups (%rcx),%xmm0
+ decl %eax
+ movdqa %xmm14,64(%rsp)
+.byte 102,15,56,222,241
+ movdqa %xmm15,80(%rsp)
+.byte 102,15,56,222,249
+ pxor %xmm14,%xmm14
+ pcmpgtd %xmm15,%xmm14
+ jmp L$xts_dec_loop6_enter
+
+.p2align 4
+L$xts_dec_loop6:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %eax
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+L$xts_dec_loop6_enter:
+ movups 16(%rcx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leaq 32(%rcx),%rcx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+.byte 102,15,56,222,240
+.byte 102,15,56,222,248
+ movups (%rcx),%xmm0
+ jnz L$xts_dec_loop6
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ paddq %xmm15,%xmm15
+.byte 102,15,56,222,209
+ pand %xmm8,%xmm9
+.byte 102,15,56,222,217
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,222,225
+ pxor %xmm9,%xmm15
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+ movups 16(%rcx),%xmm1
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm10
+ paddq %xmm15,%xmm15
+.byte 102,15,56,222,208
+ pand %xmm8,%xmm9
+.byte 102,15,56,222,216
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,222,224
+ pxor %xmm9,%xmm15
+.byte 102,15,56,222,232
+.byte 102,15,56,222,240
+.byte 102,15,56,222,248
+ movups 32(%rcx),%xmm0
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm11
+ paddq %xmm15,%xmm15
+.byte 102,15,56,222,209
+ pand %xmm8,%xmm9
+.byte 102,15,56,222,217
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,222,225
+ pxor %xmm9,%xmm15
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm12
+ paddq %xmm15,%xmm15
+.byte 102,15,56,223,208
+ pand %xmm8,%xmm9
+.byte 102,15,56,223,216
+ pcmpgtd %xmm15,%xmm14
+.byte 102,15,56,223,224
+ pxor %xmm9,%xmm15
+.byte 102,15,56,223,232
+.byte 102,15,56,223,240
+.byte 102,15,56,223,248
+
+ pshufd $19,%xmm14,%xmm9
+ pxor %xmm14,%xmm14
+ movdqa %xmm15,%xmm13
+ paddq %xmm15,%xmm15
+ xorps 0(%rsp),%xmm2
+ pand %xmm8,%xmm9
+ xorps 16(%rsp),%xmm3
+ pcmpgtd %xmm15,%xmm14
+ pxor %xmm9,%xmm15
+
+ xorps 32(%rsp),%xmm4
+ movups %xmm2,0(%rsi)
+ xorps 48(%rsp),%xmm5
+ movups %xmm3,16(%rsi)
+ xorps 64(%rsp),%xmm6
+ movups %xmm4,32(%rsi)
+ xorps 80(%rsp),%xmm7
+ movups %xmm5,48(%rsi)
+ movl %r10d,%eax
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ leaq 96(%rsi),%rsi
+ subq $96,%rdx
+ jnc L$xts_dec_grandloop
+
+ leal 3(%rax,%rax,1),%eax
+ movq %r11,%rcx
+ movl %eax,%r10d
+
+L$xts_dec_short:
+ addq $96,%rdx
+ jz L$xts_dec_done
+
+ cmpq $32,%rdx
+ jb L$xts_dec_one
+ je L$xts_dec_two
+
+ cmpq $64,%rdx
+ jb L$xts_dec_three
+ je L$xts_dec_four
+
+ pshufd $19,%xmm14,%xmm9
+ movdqa %xmm15,%xmm14
+ paddq %xmm15,%xmm15
+ movdqu (%rdi),%xmm2
+ pand %xmm8,%xmm9
+ movdqu 16(%rdi),%xmm3
+ pxor %xmm9,%xmm15
+
+ movdqu 32(%rdi),%xmm4
+ pxor %xmm10,%xmm2
+ movdqu 48(%rdi),%xmm5
+ pxor %xmm11,%xmm3
+ movdqu 64(%rdi),%xmm6
+ leaq 80(%rdi),%rdi
+ pxor %xmm12,%xmm4
+ pxor %xmm13,%xmm5
+ pxor %xmm14,%xmm6
+
+ call _aesni_decrypt6
+
+ xorps %xmm10,%xmm2
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ movdqu %xmm2,(%rsi)
+ xorps %xmm13,%xmm5
+ movdqu %xmm3,16(%rsi)
+ xorps %xmm14,%xmm6
+ movdqu %xmm4,32(%rsi)
+ pxor %xmm14,%xmm14
+ movdqu %xmm5,48(%rsi)
+ pcmpgtd %xmm15,%xmm14
+ movdqu %xmm6,64(%rsi)
+ leaq 80(%rsi),%rsi
+ pshufd $19,%xmm14,%xmm11
+ andq $15,%r9
+ jz L$xts_dec_ret
+
+ movdqa %xmm15,%xmm10
+ paddq %xmm15,%xmm15
+ pand %xmm8,%xmm11
+ pxor %xmm15,%xmm11
+ jmp L$xts_dec_done2
+
+.p2align 4
+L$xts_dec_one:
+ movups (%rdi),%xmm2
+ leaq 16(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+L$oop_dec1_12:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_dec1_12
+
+.byte 102,15,56,223,209
+ xorps %xmm10,%xmm2
+ movdqa %xmm11,%xmm10
+ movups %xmm2,(%rsi)
+ movdqa %xmm12,%xmm11
+ leaq 16(%rsi),%rsi
+ jmp L$xts_dec_done
+
+.p2align 4
+L$xts_dec_two:
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ leaq 32(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ xorps %xmm11,%xmm3
+
+ call _aesni_decrypt3
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm12,%xmm10
+ xorps %xmm11,%xmm3
+ movdqa %xmm13,%xmm11
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ leaq 32(%rsi),%rsi
+ jmp L$xts_dec_done
+
+.p2align 4
+L$xts_dec_three:
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ movups 32(%rdi),%xmm4
+ leaq 48(%rdi),%rdi
+ xorps %xmm10,%xmm2
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+
+ call _aesni_decrypt3
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm13,%xmm10
+ xorps %xmm11,%xmm3
+ movdqa %xmm15,%xmm11
+ xorps %xmm12,%xmm4
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ leaq 48(%rsi),%rsi
+ jmp L$xts_dec_done
+
+.p2align 4
+L$xts_dec_four:
+ pshufd $19,%xmm14,%xmm9
+ movdqa %xmm15,%xmm14
+ paddq %xmm15,%xmm15
+ movups (%rdi),%xmm2
+ pand %xmm8,%xmm9
+ movups 16(%rdi),%xmm3
+ pxor %xmm9,%xmm15
+
+ movups 32(%rdi),%xmm4
+ xorps %xmm10,%xmm2
+ movups 48(%rdi),%xmm5
+ leaq 64(%rdi),%rdi
+ xorps %xmm11,%xmm3
+ xorps %xmm12,%xmm4
+ xorps %xmm13,%xmm5
+
+ call _aesni_decrypt4
+
+ xorps %xmm10,%xmm2
+ movdqa %xmm14,%xmm10
+ xorps %xmm11,%xmm3
+ movdqa %xmm15,%xmm11
+ xorps %xmm12,%xmm4
+ movups %xmm2,(%rsi)
+ xorps %xmm13,%xmm5
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ leaq 64(%rsi),%rsi
+ jmp L$xts_dec_done
+
+.p2align 4
+L$xts_dec_done:
+ andq $15,%r9
+ jz L$xts_dec_ret
+L$xts_dec_done2:
+ movq %r9,%rdx
+ movq %r11,%rcx
+ movl %r10d,%eax
+
+ movups (%rdi),%xmm2
+ xorps %xmm11,%xmm2
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+L$oop_dec1_13:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_dec1_13
+
+.byte 102,15,56,223,209
+ xorps %xmm11,%xmm2
+ movups %xmm2,(%rsi)
+
+L$xts_dec_steal:
+ movzbl 16(%rdi),%eax
+ movzbl (%rsi),%ecx
+ leaq 1(%rdi),%rdi
+ movb %al,(%rsi)
+ movb %cl,16(%rsi)
+ leaq 1(%rsi),%rsi
+ subq $1,%rdx
+ jnz L$xts_dec_steal
+
+ subq %r9,%rsi
+ movq %r11,%rcx
+ movl %r10d,%eax
+
+ movups (%rsi),%xmm2
+ xorps %xmm10,%xmm2
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+L$oop_dec1_14:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_dec1_14
+
+.byte 102,15,56,223,209
+ xorps %xmm10,%xmm2
+ movups %xmm2,(%rsi)
+
+L$xts_dec_ret:
+ leaq 104(%rsp),%rsp
+L$xts_dec_epilogue:
+ .byte 0xf3,0xc3
+
+.globl _aesni_cbc_encrypt
+
+.p2align 4
+_aesni_cbc_encrypt:
+ testq %rdx,%rdx
+ jz L$cbc_ret
+
+ movl 240(%rcx),%r10d
+ movq %rcx,%r11
+ testl %r9d,%r9d
+ jz L$cbc_decrypt
+
+ movups (%r8),%xmm2
+ movl %r10d,%eax
+ cmpq $16,%rdx
+ jb L$cbc_enc_tail
+ subq $16,%rdx
+ jmp L$cbc_enc_loop
+.p2align 4
+L$cbc_enc_loop:
+ movups (%rdi),%xmm3
+ leaq 16(%rdi),%rdi
+
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ xorps %xmm0,%xmm3
+ leaq 32(%rcx),%rcx
+ xorps %xmm3,%xmm2
+L$oop_enc1_15:
+.byte 102,15,56,220,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_enc1_15
+
+.byte 102,15,56,221,209
+ movl %r10d,%eax
+ movq %r11,%rcx
+ movups %xmm2,0(%rsi)
+ leaq 16(%rsi),%rsi
+ subq $16,%rdx
+ jnc L$cbc_enc_loop
+ addq $16,%rdx
+ jnz L$cbc_enc_tail
+ movups %xmm2,(%r8)
+ jmp L$cbc_ret
+
+L$cbc_enc_tail:
+ movq %rdx,%rcx
+ xchgq %rdi,%rsi
+.long 0x9066A4F3
+
+ movl $16,%ecx
+ subq %rdx,%rcx
+ xorl %eax,%eax
+.long 0x9066AAF3
+
+ leaq -16(%rdi),%rdi
+ movl %r10d,%eax
+ movq %rdi,%rsi
+ movq %r11,%rcx
+ xorq %rdx,%rdx
+ jmp L$cbc_enc_loop
+
+
+.p2align 4
+L$cbc_decrypt:
+ movups (%r8),%xmm9
+ movl %r10d,%eax
+ cmpq $112,%rdx
+ jbe L$cbc_dec_tail
+ shrl $1,%r10d
+ subq $112,%rdx
+ movl %r10d,%eax
+ movaps %xmm9,-24(%rsp)
+ jmp L$cbc_dec_loop8_enter
+.p2align 4
+L$cbc_dec_loop8:
+ movaps %xmm0,-24(%rsp)
+ movups %xmm9,(%rsi)
+ leaq 16(%rsi),%rsi
+L$cbc_dec_loop8_enter:
+ movups (%rcx),%xmm0
+ movups (%rdi),%xmm2
+ movups 16(%rdi),%xmm3
+ movups 16(%rcx),%xmm1
+
+ leaq 32(%rcx),%rcx
+ movdqu 32(%rdi),%xmm4
+ xorps %xmm0,%xmm2
+ movdqu 48(%rdi),%xmm5
+ xorps %xmm0,%xmm3
+ movdqu 64(%rdi),%xmm6
+.byte 102,15,56,222,209
+ pxor %xmm0,%xmm4
+ movdqu 80(%rdi),%xmm7
+.byte 102,15,56,222,217
+ pxor %xmm0,%xmm5
+ movdqu 96(%rdi),%xmm8
+.byte 102,15,56,222,225
+ pxor %xmm0,%xmm6
+ movdqu 112(%rdi),%xmm9
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+ decl %eax
+.byte 102,15,56,222,241
+ pxor %xmm0,%xmm8
+.byte 102,15,56,222,249
+ pxor %xmm0,%xmm9
+ movups (%rcx),%xmm0
+.byte 102,68,15,56,222,193
+.byte 102,68,15,56,222,201
+ movups 16(%rcx),%xmm1
+
+ call L$dec_loop8_enter
+
+ movups (%rdi),%xmm1
+ movups 16(%rdi),%xmm0
+ xorps -24(%rsp),%xmm2
+ xorps %xmm1,%xmm3
+ movups 32(%rdi),%xmm1
+ xorps %xmm0,%xmm4
+ movups 48(%rdi),%xmm0
+ xorps %xmm1,%xmm5
+ movups 64(%rdi),%xmm1
+ xorps %xmm0,%xmm6
+ movups 80(%rdi),%xmm0
+ xorps %xmm1,%xmm7
+ movups 96(%rdi),%xmm1
+ xorps %xmm0,%xmm8
+ movups 112(%rdi),%xmm0
+ xorps %xmm1,%xmm9
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movl %r10d,%eax
+ movups %xmm6,64(%rsi)
+ movq %r11,%rcx
+ movups %xmm7,80(%rsi)
+ leaq 128(%rdi),%rdi
+ movups %xmm8,96(%rsi)
+ leaq 112(%rsi),%rsi
+ subq $128,%rdx
+ ja L$cbc_dec_loop8
+
+ movaps %xmm9,%xmm2
+ movaps %xmm0,%xmm9
+ addq $112,%rdx
+ jle L$cbc_dec_tail_collected
+ movups %xmm2,(%rsi)
+ leal 1(%r10,%r10,1),%eax
+ leaq 16(%rsi),%rsi
+L$cbc_dec_tail:
+ movups (%rdi),%xmm2
+ movaps %xmm2,%xmm8
+ cmpq $16,%rdx
+ jbe L$cbc_dec_one
+
+ movups 16(%rdi),%xmm3
+ movaps %xmm3,%xmm7
+ cmpq $32,%rdx
+ jbe L$cbc_dec_two
+
+ movups 32(%rdi),%xmm4
+ movaps %xmm4,%xmm6
+ cmpq $48,%rdx
+ jbe L$cbc_dec_three
+
+ movups 48(%rdi),%xmm5
+ cmpq $64,%rdx
+ jbe L$cbc_dec_four
+
+ movups 64(%rdi),%xmm6
+ cmpq $80,%rdx
+ jbe L$cbc_dec_five
+
+ movups 80(%rdi),%xmm7
+ cmpq $96,%rdx
+ jbe L$cbc_dec_six
+
+ movups 96(%rdi),%xmm8
+ movaps %xmm9,-24(%rsp)
+ call _aesni_decrypt8
+ movups (%rdi),%xmm1
+ movups 16(%rdi),%xmm0
+ xorps -24(%rsp),%xmm2
+ xorps %xmm1,%xmm3
+ movups 32(%rdi),%xmm1
+ xorps %xmm0,%xmm4
+ movups 48(%rdi),%xmm0
+ xorps %xmm1,%xmm5
+ movups 64(%rdi),%xmm1
+ xorps %xmm0,%xmm6
+ movups 80(%rdi),%xmm0
+ xorps %xmm1,%xmm7
+ movups 96(%rdi),%xmm9
+ xorps %xmm0,%xmm8
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ movups %xmm7,80(%rsi)
+ leaq 96(%rsi),%rsi
+ movaps %xmm8,%xmm2
+ subq $112,%rdx
+ jmp L$cbc_dec_tail_collected
+.p2align 4
+L$cbc_dec_one:
+ movups (%rcx),%xmm0
+ movups 16(%rcx),%xmm1
+ leaq 32(%rcx),%rcx
+ xorps %xmm0,%xmm2
+L$oop_dec1_16:
+.byte 102,15,56,222,209
+ decl %eax
+ movups (%rcx),%xmm1
+ leaq 16(%rcx),%rcx
+ jnz L$oop_dec1_16
+
+.byte 102,15,56,223,209
+ xorps %xmm9,%xmm2
+ movaps %xmm8,%xmm9
+ subq $16,%rdx
+ jmp L$cbc_dec_tail_collected
+.p2align 4
+L$cbc_dec_two:
+ xorps %xmm4,%xmm4
+ call _aesni_decrypt3
+ xorps %xmm9,%xmm2
+ xorps %xmm8,%xmm3
+ movups %xmm2,(%rsi)
+ movaps %xmm7,%xmm9
+ movaps %xmm3,%xmm2
+ leaq 16(%rsi),%rsi
+ subq $32,%rdx
+ jmp L$cbc_dec_tail_collected
+.p2align 4
+L$cbc_dec_three:
+ call _aesni_decrypt3
+ xorps %xmm9,%xmm2
+ xorps %xmm8,%xmm3
+ movups %xmm2,(%rsi)
+ xorps %xmm7,%xmm4
+ movups %xmm3,16(%rsi)
+ movaps %xmm6,%xmm9
+ movaps %xmm4,%xmm2
+ leaq 32(%rsi),%rsi
+ subq $48,%rdx
+ jmp L$cbc_dec_tail_collected
+.p2align 4
+L$cbc_dec_four:
+ call _aesni_decrypt4
+ xorps %xmm9,%xmm2
+ movups 48(%rdi),%xmm9
+ xorps %xmm8,%xmm3
+ movups %xmm2,(%rsi)
+ xorps %xmm7,%xmm4
+ movups %xmm3,16(%rsi)
+ xorps %xmm6,%xmm5
+ movups %xmm4,32(%rsi)
+ movaps %xmm5,%xmm2
+ leaq 48(%rsi),%rsi
+ subq $64,%rdx
+ jmp L$cbc_dec_tail_collected
+.p2align 4
+L$cbc_dec_five:
+ xorps %xmm7,%xmm7
+ call _aesni_decrypt6
+ movups 16(%rdi),%xmm1
+ movups 32(%rdi),%xmm0
+ xorps %xmm9,%xmm2
+ xorps %xmm8,%xmm3
+ xorps %xmm1,%xmm4
+ movups 48(%rdi),%xmm1
+ xorps %xmm0,%xmm5
+ movups 64(%rdi),%xmm9
+ xorps %xmm1,%xmm6
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ leaq 64(%rsi),%rsi
+ movaps %xmm6,%xmm2
+ subq $80,%rdx
+ jmp L$cbc_dec_tail_collected
+.p2align 4
+L$cbc_dec_six:
+ call _aesni_decrypt6
+ movups 16(%rdi),%xmm1
+ movups 32(%rdi),%xmm0
+ xorps %xmm9,%xmm2
+ xorps %xmm8,%xmm3
+ xorps %xmm1,%xmm4
+ movups 48(%rdi),%xmm1
+ xorps %xmm0,%xmm5
+ movups 64(%rdi),%xmm0
+ xorps %xmm1,%xmm6
+ movups 80(%rdi),%xmm9
+ xorps %xmm0,%xmm7
+ movups %xmm2,(%rsi)
+ movups %xmm3,16(%rsi)
+ movups %xmm4,32(%rsi)
+ movups %xmm5,48(%rsi)
+ movups %xmm6,64(%rsi)
+ leaq 80(%rsi),%rsi
+ movaps %xmm7,%xmm2
+ subq $96,%rdx
+ jmp L$cbc_dec_tail_collected
+.p2align 4
+L$cbc_dec_tail_collected:
+ andq $15,%rdx
+ movups %xmm9,(%r8)
+ jnz L$cbc_dec_tail_partial
+ movups %xmm2,(%rsi)
+ jmp L$cbc_dec_ret
+.p2align 4
+L$cbc_dec_tail_partial:
+ movaps %xmm2,-24(%rsp)
+ movq $16,%rcx
+ movq %rsi,%rdi
+ subq %rdx,%rcx
+ leaq -24(%rsp),%rsi
+.long 0x9066A4F3
+
+
+L$cbc_dec_ret:
+L$cbc_ret:
+ .byte 0xf3,0xc3
+
+.globl _aesni_set_decrypt_key
+
+.p2align 4
+_aesni_set_decrypt_key:
+.byte 0x48,0x83,0xEC,0x08
+
+ call __aesni_set_encrypt_key
+ shll $4,%esi
+ testl %eax,%eax
+ jnz L$dec_key_ret
+ leaq 16(%rdx,%rsi,1),%rdi
+
+ movups (%rdx),%xmm0
+ movups (%rdi),%xmm1
+ movups %xmm0,(%rdi)
+ movups %xmm1,(%rdx)
+ leaq 16(%rdx),%rdx
+ leaq -16(%rdi),%rdi
+
+L$dec_key_inverse:
+ movups (%rdx),%xmm0
+ movups (%rdi),%xmm1
+.byte 102,15,56,219,192
+.byte 102,15,56,219,201
+ leaq 16(%rdx),%rdx
+ leaq -16(%rdi),%rdi
+ movups %xmm0,16(%rdi)
+ movups %xmm1,-16(%rdx)
+ cmpq %rdx,%rdi
+ ja L$dec_key_inverse
+
+ movups (%rdx),%xmm0
+.byte 102,15,56,219,192
+ movups %xmm0,(%rdi)
+L$dec_key_ret:
+ addq $8,%rsp
+ .byte 0xf3,0xc3
+L$SEH_end_set_decrypt_key:
+
+.globl _aesni_set_encrypt_key
+
+.p2align 4
+_aesni_set_encrypt_key:
+__aesni_set_encrypt_key:
+.byte 0x48,0x83,0xEC,0x08
+
+ movq $-1,%rax
+ testq %rdi,%rdi
+ jz L$enc_key_ret
+ testq %rdx,%rdx
+ jz L$enc_key_ret
+
+ movups (%rdi),%xmm0
+ xorps %xmm4,%xmm4
+ leaq 16(%rdx),%rax
+ cmpl $256,%esi
+ je L$14rounds
+ cmpl $192,%esi
+ je L$12rounds
+ cmpl $128,%esi
+ jne L$bad_keybits
+
+L$10rounds:
+ movl $9,%esi
+ movups %xmm0,(%rdx)
+.byte 102,15,58,223,200,1
+ call L$key_expansion_128_cold
+.byte 102,15,58,223,200,2
+ call L$key_expansion_128
+.byte 102,15,58,223,200,4
+ call L$key_expansion_128
+.byte 102,15,58,223,200,8
+ call L$key_expansion_128
+.byte 102,15,58,223,200,16
+ call L$key_expansion_128
+.byte 102,15,58,223,200,32
+ call L$key_expansion_128
+.byte 102,15,58,223,200,64
+ call L$key_expansion_128
+.byte 102,15,58,223,200,128
+ call L$key_expansion_128
+.byte 102,15,58,223,200,27
+ call L$key_expansion_128
+.byte 102,15,58,223,200,54
+ call L$key_expansion_128
+ movups %xmm0,(%rax)
+ movl %esi,80(%rax)
+ xorl %eax,%eax
+ jmp L$enc_key_ret
+
+.p2align 4
+L$12rounds:
+ movq 16(%rdi),%xmm2
+ movl $11,%esi
+ movups %xmm0,(%rdx)
+.byte 102,15,58,223,202,1
+ call L$key_expansion_192a_cold
+.byte 102,15,58,223,202,2
+ call L$key_expansion_192b
+.byte 102,15,58,223,202,4
+ call L$key_expansion_192a
+.byte 102,15,58,223,202,8
+ call L$key_expansion_192b
+.byte 102,15,58,223,202,16
+ call L$key_expansion_192a
+.byte 102,15,58,223,202,32
+ call L$key_expansion_192b
+.byte 102,15,58,223,202,64
+ call L$key_expansion_192a
+.byte 102,15,58,223,202,128
+ call L$key_expansion_192b
+ movups %xmm0,(%rax)
+ movl %esi,48(%rax)
+ xorq %rax,%rax
+ jmp L$enc_key_ret
+
+.p2align 4
+L$14rounds:
+ movups 16(%rdi),%xmm2
+ movl $13,%esi
+ leaq 16(%rax),%rax
+ movups %xmm0,(%rdx)
+ movups %xmm2,16(%rdx)
+.byte 102,15,58,223,202,1
+ call L$key_expansion_256a_cold
+.byte 102,15,58,223,200,1
+ call L$key_expansion_256b
+.byte 102,15,58,223,202,2
+ call L$key_expansion_256a
+.byte 102,15,58,223,200,2
+ call L$key_expansion_256b
+.byte 102,15,58,223,202,4
+ call L$key_expansion_256a
+.byte 102,15,58,223,200,4
+ call L$key_expansion_256b
+.byte 102,15,58,223,202,8
+ call L$key_expansion_256a
+.byte 102,15,58,223,200,8
+ call L$key_expansion_256b
+.byte 102,15,58,223,202,16
+ call L$key_expansion_256a
+.byte 102,15,58,223,200,16
+ call L$key_expansion_256b
+.byte 102,15,58,223,202,32
+ call L$key_expansion_256a
+.byte 102,15,58,223,200,32
+ call L$key_expansion_256b
+.byte 102,15,58,223,202,64
+ call L$key_expansion_256a
+ movups %xmm0,(%rax)
+ movl %esi,16(%rax)
+ xorq %rax,%rax
+ jmp L$enc_key_ret
+
+.p2align 4
+L$bad_keybits:
+ movq $-2,%rax
+L$enc_key_ret:
+ addq $8,%rsp
+ .byte 0xf3,0xc3
+L$SEH_end_set_encrypt_key:
+
+.p2align 4
+L$key_expansion_128:
+ movups %xmm0,(%rax)
+ leaq 16(%rax),%rax
+L$key_expansion_128_cold:
+ shufps $16,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $255,%xmm1,%xmm1
+ xorps %xmm1,%xmm0
+ .byte 0xf3,0xc3
+
+.p2align 4
+L$key_expansion_192a:
+ movups %xmm0,(%rax)
+ leaq 16(%rax),%rax
+L$key_expansion_192a_cold:
+ movaps %xmm2,%xmm5
+L$key_expansion_192b_warm:
+ shufps $16,%xmm0,%xmm4
+ movdqa %xmm2,%xmm3
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ pslldq $4,%xmm3
+ xorps %xmm4,%xmm0
+ pshufd $85,%xmm1,%xmm1
+ pxor %xmm3,%xmm2
+ pxor %xmm1,%xmm0
+ pshufd $255,%xmm0,%xmm3
+ pxor %xmm3,%xmm2
+ .byte 0xf3,0xc3
+
+.p2align 4
+L$key_expansion_192b:
+ movaps %xmm0,%xmm3
+ shufps $68,%xmm0,%xmm5
+ movups %xmm5,(%rax)
+ shufps $78,%xmm2,%xmm3
+ movups %xmm3,16(%rax)
+ leaq 32(%rax),%rax
+ jmp L$key_expansion_192b_warm
+
+.p2align 4
+L$key_expansion_256a:
+ movups %xmm2,(%rax)
+ leaq 16(%rax),%rax
+L$key_expansion_256a_cold:
+ shufps $16,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $255,%xmm1,%xmm1
+ xorps %xmm1,%xmm0
+ .byte 0xf3,0xc3
+
+.p2align 4
+L$key_expansion_256b:
+ movups %xmm0,(%rax)
+ leaq 16(%rax),%rax
+
+ shufps $16,%xmm2,%xmm4
+ xorps %xmm4,%xmm2
+ shufps $140,%xmm2,%xmm4
+ xorps %xmm4,%xmm2
+ shufps $170,%xmm1,%xmm1
+ xorps %xmm1,%xmm2
+ .byte 0xf3,0xc3
+
+
+.p2align 6
+L$bswap_mask:
+.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+L$increment32:
+.long 6,6,6,0
+L$increment64:
+.long 1,0,0,0
+L$xts_magic:
+.long 0x87,0,1,0
+
+.byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align 6
diff --git a/deps/openssl/asm/x64-macosx-gas/bn/modexp512-x86_64.s b/deps/openssl/asm/x64-macosx-gas/bn/modexp512-x86_64.s
new file mode 100644
index 000000000..00c529a07
--- /dev/null
+++ b/deps/openssl/asm/x64-macosx-gas/bn/modexp512-x86_64.s
@@ -0,0 +1,1775 @@
+.text
+
+
+
+.p2align 4
+MULADD_128x512:
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ movq %r8,0(%rcx)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%r8
+ movq 8(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ movq %r9,8(%rcx)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%r9
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+mont_reduce:
+ leaq 192(%rsp),%rdi
+ movq 32(%rsp),%rsi
+ addq $576,%rsi
+ leaq 520(%rsp),%rcx
+
+ movq 96(%rcx),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ movq (%rcx),%r8
+ addq %rax,%r8
+ adcq $0,%rdx
+ movq %r8,0(%rdi)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ movq 8(%rcx),%r9
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ movq 16(%rcx),%r10
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ movq 24(%rcx),%r11
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ movq 32(%rcx),%r12
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ movq 40(%rcx),%r13
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ movq 48(%rcx),%r14
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ movq 56(%rcx),%r15
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%r8
+ movq 104(%rcx),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ movq %r9,8(%rdi)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%r9
+ movq 112(%rcx),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ movq %r10,16(%rdi)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%r10
+ movq 120(%rcx),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %r11,24(%rdi)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+ xorq %rax,%rax
+
+ addq 64(%rcx),%r8
+ adcq 72(%rcx),%r9
+ adcq 80(%rcx),%r10
+ adcq 88(%rcx),%r11
+ adcq $0,%rax
+
+
+
+
+ movq %r8,64(%rdi)
+ movq %r9,72(%rdi)
+ movq %r10,%rbp
+ movq %r11,88(%rdi)
+
+ movq %rax,384(%rsp)
+
+ movq 0(%rdi),%r8
+ movq 8(%rdi),%r9
+ movq 16(%rdi),%r10
+ movq 24(%rdi),%r11
+
+
+
+
+
+
+
+
+ addq $80,%rdi
+
+ addq $64,%rsi
+ leaq 296(%rsp),%rcx
+
+ call MULADD_128x512
+
+
+ movq 384(%rsp),%rax
+
+
+ addq -16(%rdi),%r8
+ adcq -8(%rdi),%r9
+ movq %r8,64(%rcx)
+ movq %r9,72(%rcx)
+
+ adcq %rax,%rax
+ movq %rax,384(%rsp)
+
+ leaq 192(%rsp),%rdi
+ addq $64,%rsi
+
+
+
+
+
+ movq (%rsi),%r8
+ movq 8(%rsi),%rbx
+
+ movq (%rcx),%rax
+ mulq %r8
+ movq %rax,%rbp
+ movq %rdx,%r9
+
+ movq 8(%rcx),%rax
+ mulq %r8
+ addq %rax,%r9
+
+ movq (%rcx),%rax
+ mulq %rbx
+ addq %rax,%r9
+
+ movq %r9,8(%rdi)
+
+
+ subq $192,%rsi
+
+ movq (%rcx),%r8
+ movq 8(%rcx),%r9
+
+ call MULADD_128x512
+
+
+
+
+
+ movq 0(%rsi),%rax
+ movq 8(%rsi),%rbx
+ movq 16(%rsi),%rdi
+ movq 24(%rsi),%rdx
+
+
+ movq 384(%rsp),%rbp
+
+ addq 64(%rcx),%r8
+ adcq 72(%rcx),%r9
+
+
+ adcq %rbp,%rbp
+
+
+
+ shlq $3,%rbp
+ movq 32(%rsp),%rcx
+ addq %rcx,%rbp
+
+
+ xorq %rsi,%rsi
+
+ addq 0(%rbp),%r10
+ adcq 64(%rbp),%r11
+ adcq 128(%rbp),%r12
+ adcq 192(%rbp),%r13
+ adcq 256(%rbp),%r14
+ adcq 320(%rbp),%r15
+ adcq 384(%rbp),%r8
+ adcq 448(%rbp),%r9
+
+
+
+ sbbq $0,%rsi
+
+
+ andq %rsi,%rax
+ andq %rsi,%rbx
+ andq %rsi,%rdi
+ andq %rsi,%rdx
+
+ movq $1,%rbp
+ subq %rax,%r10
+ sbbq %rbx,%r11
+ sbbq %rdi,%r12
+ sbbq %rdx,%r13
+
+
+
+
+ sbbq $0,%rbp
+
+
+
+ addq $512,%rcx
+ movq 32(%rcx),%rax
+ movq 40(%rcx),%rbx
+ movq 48(%rcx),%rdi
+ movq 56(%rcx),%rdx
+
+
+
+ andq %rsi,%rax
+ andq %rsi,%rbx
+ andq %rsi,%rdi
+ andq %rsi,%rdx
+
+
+
+ subq $1,%rbp
+
+ sbbq %rax,%r14
+ sbbq %rbx,%r15
+ sbbq %rdi,%r8
+ sbbq %rdx,%r9
+
+
+
+ movq 144(%rsp),%rsi
+ movq %r10,0(%rsi)
+ movq %r11,8(%rsi)
+ movq %r12,16(%rsi)
+ movq %r13,24(%rsi)
+ movq %r14,32(%rsi)
+ movq %r15,40(%rsi)
+ movq %r8,48(%rsi)
+ movq %r9,56(%rsi)
+
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+mont_mul_a3b:
+
+
+
+
+ movq 0(%rdi),%rbp
+
+ movq %r10,%rax
+ mulq %rbp
+ movq %rax,520(%rsp)
+ movq %rdx,%r10
+ movq %r11,%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+ movq %r12,%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %rdx,%r12
+ movq %r13,%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ movq %rdx,%r13
+ movq %r14,%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ movq %rdx,%r14
+ movq %r15,%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ movq %rdx,%r15
+ movq %r8,%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ movq %rdx,%r8
+ movq %r9,%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ movq %rdx,%r9
+ movq 8(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ movq %r10,528(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%r10
+ movq 16(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %r11,536(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+ movq 24(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ movq %r12,544(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%r12
+ movq 32(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ movq %r13,552(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%r13
+ movq 40(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ movq %r14,560(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%r14
+ movq 48(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ movq %r15,568(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ addq %rbx,%r8
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%r15
+ movq 56(%rdi),%rbp
+ movq 0(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r8
+ adcq $0,%rdx
+ movq %r8,576(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r9
+ adcq $0,%rdx
+ addq %rbx,%r9
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 16(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r10
+ adcq $0,%rdx
+ addq %rbx,%r10
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 24(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %rbx,%r11
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 32(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %rbx,%r12
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 40(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %rbx,%r13
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 48(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %rbx,%r14
+ adcq $0,%rdx
+ movq %rdx,%rbx
+
+ movq 56(%rsi),%rax
+ mulq %rbp
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %rbx,%r15
+ adcq $0,%rdx
+ movq %rdx,%r8
+ movq %r9,584(%rsp)
+ movq %r10,592(%rsp)
+ movq %r11,600(%rsp)
+ movq %r12,608(%rsp)
+ movq %r13,616(%rsp)
+ movq %r14,624(%rsp)
+ movq %r15,632(%rsp)
+ movq %r8,640(%rsp)
+
+
+
+
+
+ jmp mont_reduce
+
+
+
+
+.p2align 4
+sqr_reduce:
+ movq 16(%rsp),%rcx
+
+
+
+ movq %r10,%rbx
+
+ movq %r11,%rax
+ mulq %rbx
+ movq %rax,528(%rsp)
+ movq %rdx,%r10
+ movq %r12,%rax
+ mulq %rbx
+ addq %rax,%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+ movq %r13,%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %rdx,%r12
+ movq %r14,%rax
+ mulq %rbx
+ addq %rax,%r12
+ adcq $0,%rdx
+ movq %rdx,%r13
+ movq %r15,%rax
+ mulq %rbx
+ addq %rax,%r13
+ adcq $0,%rdx
+ movq %rdx,%r14
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%r14
+ adcq $0,%rdx
+ movq %rdx,%r15
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ movq %rdx,%rsi
+
+ movq %r10,536(%rsp)
+
+
+
+
+
+ movq 8(%rcx),%rbx
+
+ movq 16(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %r11,544(%rsp)
+
+ movq %rdx,%r10
+ movq 24(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %r10,%r12
+ adcq $0,%rdx
+ movq %r12,552(%rsp)
+
+ movq %rdx,%r10
+ movq 32(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r13
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq 40(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %r10,%r14
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %r10,%r15
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%rsi
+ adcq $0,%rdx
+ addq %r10,%rsi
+ adcq $0,%rdx
+
+ movq %rdx,%r11
+
+
+
+
+ movq 16(%rcx),%rbx
+
+ movq 24(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r13
+ adcq $0,%rdx
+ movq %r13,560(%rsp)
+
+ movq %rdx,%r10
+ movq 32(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r14
+ adcq $0,%rdx
+ addq %r10,%r14
+ adcq $0,%rdx
+ movq %r14,568(%rsp)
+
+ movq %rdx,%r10
+ movq 40(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %r10,%r15
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%rsi
+ adcq $0,%rdx
+ addq %r10,%rsi
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %r10,%r11
+ adcq $0,%rdx
+
+ movq %rdx,%r12
+
+
+
+
+
+ movq 24(%rcx),%rbx
+
+ movq 32(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ movq %r15,576(%rsp)
+
+ movq %rdx,%r10
+ movq 40(%rcx),%rax
+ mulq %rbx
+ addq %rax,%rsi
+ adcq $0,%rdx
+ addq %r10,%rsi
+ adcq $0,%rdx
+ movq %rsi,584(%rsp)
+
+ movq %rdx,%r10
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %r10,%r11
+ adcq $0,%rdx
+
+ movq %rdx,%r10
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %r10,%r12
+ adcq $0,%rdx
+
+ movq %rdx,%r15
+
+
+
+
+ movq 32(%rcx),%rbx
+
+ movq 40(%rcx),%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ movq %r11,592(%rsp)
+
+ movq %rdx,%r10
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%r12
+ adcq $0,%rdx
+ addq %r10,%r12
+ adcq $0,%rdx
+ movq %r12,600(%rsp)
+
+ movq %rdx,%r10
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ addq %r10,%r15
+ adcq $0,%rdx
+
+ movq %rdx,%r11
+
+
+
+
+ movq 40(%rcx),%rbx
+
+ movq %r8,%rax
+ mulq %rbx
+ addq %rax,%r15
+ adcq $0,%rdx
+ movq %r15,608(%rsp)
+
+ movq %rdx,%r10
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r11
+ adcq $0,%rdx
+ addq %r10,%r11
+ adcq $0,%rdx
+ movq %r11,616(%rsp)
+
+ movq %rdx,%r12
+
+
+
+
+ movq %r8,%rbx
+
+ movq %r9,%rax
+ mulq %rbx
+ addq %rax,%r12
+ adcq $0,%rdx
+ movq %r12,624(%rsp)
+
+ movq %rdx,632(%rsp)
+
+
+ movq 528(%rsp),%r10
+ movq 536(%rsp),%r11
+ movq 544(%rsp),%r12
+ movq 552(%rsp),%r13
+ movq 560(%rsp),%r14
+ movq 568(%rsp),%r15
+
+ movq 24(%rcx),%rax
+ mulq %rax
+ movq %rax,%rdi
+ movq %rdx,%r8
+
+ addq %r10,%r10
+ adcq %r11,%r11
+ adcq %r12,%r12
+ adcq %r13,%r13
+ adcq %r14,%r14
+ adcq %r15,%r15
+ adcq $0,%r8
+
+ movq 0(%rcx),%rax
+ mulq %rax
+ movq %rax,520(%rsp)
+ movq %rdx,%rbx
+
+ movq 8(%rcx),%rax
+ mulq %rax
+
+ addq %rbx,%r10
+ adcq %rax,%r11
+ adcq $0,%rdx
+
+ movq %rdx,%rbx
+ movq %r10,528(%rsp)
+ movq %r11,536(%rsp)
+
+ movq 16(%rcx),%rax
+ mulq %rax
+
+ addq %rbx,%r12
+ adcq %rax,%r13
+ adcq $0,%rdx
+
+ movq %rdx,%rbx
+
+ movq %r12,544(%rsp)
+ movq %r13,552(%rsp)
+
+ xorq %rbp,%rbp
+ addq %rbx,%r14
+ adcq %rdi,%r15
+ adcq $0,%rbp
+
+ movq %r14,560(%rsp)
+ movq %r15,568(%rsp)
+
+
+
+
+ movq 576(%rsp),%r10
+ movq 584(%rsp),%r11
+ movq 592(%rsp),%r12
+ movq 600(%rsp),%r13
+ movq 608(%rsp),%r14
+ movq 616(%rsp),%r15
+ movq 624(%rsp),%rdi
+ movq 632(%rsp),%rsi
+
+ movq %r9,%rax
+ mulq %rax
+ movq %rax,%r9
+ movq %rdx,%rbx
+
+ addq %r10,%r10
+ adcq %r11,%r11
+ adcq %r12,%r12
+ adcq %r13,%r13
+ adcq %r14,%r14
+ adcq %r15,%r15
+ adcq %rdi,%rdi
+ adcq %rsi,%rsi
+ adcq $0,%rbx
+
+ addq %rbp,%r10
+
+ movq 32(%rcx),%rax
+ mulq %rax
+
+ addq %r8,%r10
+ adcq %rax,%r11
+ adcq $0,%rdx
+
+ movq %rdx,%rbp
+
+ movq %r10,576(%rsp)
+ movq %r11,584(%rsp)
+
+ movq 40(%rcx),%rax
+ mulq %rax
+
+ addq %rbp,%r12
+ adcq %rax,%r13
+ adcq $0,%rdx
+
+ movq %rdx,%rbp
+
+ movq %r12,592(%rsp)
+ movq %r13,600(%rsp)
+
+ movq 48(%rcx),%rax
+ mulq %rax
+
+ addq %rbp,%r14
+ adcq %rax,%r15
+ adcq $0,%rdx
+
+ movq %r14,608(%rsp)
+ movq %r15,616(%rsp)
+
+ addq %rdx,%rdi
+ adcq %r9,%rsi
+ adcq $0,%rbx
+
+ movq %rdi,624(%rsp)
+ movq %rsi,632(%rsp)
+ movq %rbx,640(%rsp)
+
+ jmp mont_reduce
+
+
+
+.globl _mod_exp_512
+
+_mod_exp_512:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+
+ movq %rsp,%r8
+ subq $2688,%rsp
+ andq $-64,%rsp
+
+
+ movq %r8,0(%rsp)
+ movq %rdi,8(%rsp)
+ movq %rsi,16(%rsp)
+ movq %rcx,24(%rsp)
+L$body:
+
+
+
+ pxor %xmm4,%xmm4
+ movdqu 0(%rsi),%xmm0
+ movdqu 16(%rsi),%xmm1
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm3
+ movdqa %xmm4,512(%rsp)
+ movdqa %xmm4,528(%rsp)
+ movdqa %xmm4,608(%rsp)
+ movdqa %xmm4,624(%rsp)
+ movdqa %xmm0,544(%rsp)
+ movdqa %xmm1,560(%rsp)
+ movdqa %xmm2,576(%rsp)
+ movdqa %xmm3,592(%rsp)
+
+
+ movdqu 0(%rdx),%xmm0
+ movdqu 16(%rdx),%xmm1
+ movdqu 32(%rdx),%xmm2
+ movdqu 48(%rdx),%xmm3
+
+ leaq 384(%rsp),%rbx
+ movq %rbx,136(%rsp)
+ call mont_reduce
+
+
+ leaq 448(%rsp),%rcx
+ xorq %rax,%rax
+ movq %rax,0(%rcx)
+ movq %rax,8(%rcx)
+ movq %rax,24(%rcx)
+ movq %rax,32(%rcx)
+ movq %rax,40(%rcx)
+ movq %rax,48(%rcx)
+ movq %rax,56(%rcx)
+ movq %rax,128(%rsp)
+ movq $1,16(%rcx)
+
+ leaq 640(%rsp),%rbp
+ movq %rcx,%rsi
+ movq %rbp,%rdi
+ movq $8,%rax
+loop_0:
+ movq (%rcx),%rbx
+ movw %bx,(%rdi)
+ shrq $16,%rbx
+ movw %bx,64(%rdi)
+ shrq $16,%rbx
+ movw %bx,128(%rdi)
+ shrq $16,%rbx
+ movw %bx,192(%rdi)
+ leaq 8(%rcx),%rcx
+ leaq 256(%rdi),%rdi
+ decq %rax
+ jnz loop_0
+ movq $31,%rax
+ movq %rax,32(%rsp)
+ movq %rbp,40(%rsp)
+
+ movq %rsi,136(%rsp)
+ movq 0(%rsi),%r10
+ movq 8(%rsi),%r11
+ movq 16(%rsi),%r12
+ movq 24(%rsi),%r13
+ movq 32(%rsi),%r14
+ movq 40(%rsi),%r15
+ movq 48(%rsi),%r8
+ movq 56(%rsi),%r9
+init_loop:
+ leaq 384(%rsp),%rdi
+ call mont_mul_a3b
+ leaq 448(%rsp),%rsi
+ movq 40(%rsp),%rbp
+ addq $2,%rbp
+ movq %rbp,40(%rsp)
+ movq %rsi,%rcx
+ movq $8,%rax
+loop_1:
+ movq (%rcx),%rbx
+ movw %bx,(%rbp)
+ shrq $16,%rbx
+ movw %bx,64(%rbp)
+ shrq $16,%rbx
+ movw %bx,128(%rbp)
+ shrq $16,%rbx
+ movw %bx,192(%rbp)
+ leaq 8(%rcx),%rcx
+ leaq 256(%rbp),%rbp
+ decq %rax
+ jnz loop_1
+ movq 32(%rsp),%rax
+ subq $1,%rax
+ movq %rax,32(%rsp)
+ jne init_loop
+
+
+
+ movdqa %xmm0,64(%rsp)
+ movdqa %xmm1,80(%rsp)
+ movdqa %xmm2,96(%rsp)
+ movdqa %xmm3,112(%rsp)
+
+
+
+
+
+ movl 126(%rsp),%eax
+ movq %rax,%rdx
+ shrq $11,%rax
+ andl $2047,%edx
+ movl %edx,126(%rsp)
+ leaq 640(%rsp,%rax,2),%rsi
+ movq 8(%rsp),%rdx
+ movq $4,%rbp
+loop_2:
+ movzwq 192(%rsi),%rbx
+ movzwq 448(%rsi),%rax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 128(%rsi),%bx
+ movw 384(%rsi),%ax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 64(%rsi),%bx
+ movw 320(%rsi),%ax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 0(%rsi),%bx
+ movw 256(%rsi),%ax
+ movq %rbx,0(%rdx)
+ movq %rax,8(%rdx)
+ leaq 512(%rsi),%rsi
+ leaq 16(%rdx),%rdx
+ subq $1,%rbp
+ jnz loop_2
+ movq $505,48(%rsp)
+
+ movq 8(%rsp),%rcx
+ movq %rcx,136(%rsp)
+ movq 0(%rcx),%r10
+ movq 8(%rcx),%r11
+ movq 16(%rcx),%r12
+ movq 24(%rcx),%r13
+ movq 32(%rcx),%r14
+ movq 40(%rcx),%r15
+ movq 48(%rcx),%r8
+ movq 56(%rcx),%r9
+ jmp sqr_2
+
+main_loop_a3b:
+ call sqr_reduce
+ call sqr_reduce
+ call sqr_reduce
+sqr_2:
+ call sqr_reduce
+ call sqr_reduce
+
+
+
+ movq 48(%rsp),%rcx
+ movq %rcx,%rax
+ shrq $4,%rax
+ movl 64(%rsp,%rax,2),%edx
+ andq $15,%rcx
+ shrq %cl,%rdx
+ andq $31,%rdx
+
+ leaq 640(%rsp,%rdx,2),%rsi
+ leaq 448(%rsp),%rdx
+ movq %rdx,%rdi
+ movq $4,%rbp
+loop_3:
+ movzwq 192(%rsi),%rbx
+ movzwq 448(%rsi),%rax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 128(%rsi),%bx
+ movw 384(%rsi),%ax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 64(%rsi),%bx
+ movw 320(%rsi),%ax
+ shlq $16,%rbx
+ shlq $16,%rax
+ movw 0(%rsi),%bx
+ movw 256(%rsi),%ax
+ movq %rbx,0(%rdx)
+ movq %rax,8(%rdx)
+ leaq 512(%rsi),%rsi
+ leaq 16(%rdx),%rdx
+ subq $1,%rbp
+ jnz loop_3
+ movq 8(%rsp),%rsi
+ call mont_mul_a3b
+
+
+
+ movq 48(%rsp),%rcx
+ subq $5,%rcx
+ movq %rcx,48(%rsp)
+ jge main_loop_a3b
+
+
+
+end_main_loop_a3b:
+
+
+ movq 8(%rsp),%rdx
+ pxor %xmm4,%xmm4
+ movdqu 0(%rdx),%xmm0
+ movdqu 16(%rdx),%xmm1
+ movdqu 32(%rdx),%xmm2
+ movdqu 48(%rdx),%xmm3
+ movdqa %xmm4,576(%rsp)
+ movdqa %xmm4,592(%rsp)
+ movdqa %xmm4,608(%rsp)
+ movdqa %xmm4,624(%rsp)
+ movdqa %xmm0,512(%rsp)
+ movdqa %xmm1,528(%rsp)
+ movdqa %xmm2,544(%rsp)
+ movdqa %xmm3,560(%rsp)
+ call mont_reduce
+
+
+
+ movq 8(%rsp),%rax
+ movq 0(%rax),%r8
+ movq 8(%rax),%r9
+ movq 16(%rax),%r10
+ movq 24(%rax),%r11
+ movq 32(%rax),%r12
+ movq 40(%rax),%r13
+ movq 48(%rax),%r14
+ movq 56(%rax),%r15
+
+
+ movq 24(%rsp),%rbx
+ addq $512,%rbx
+
+ subq 0(%rbx),%r8
+ sbbq 8(%rbx),%r9
+ sbbq 16(%rbx),%r10
+ sbbq 24(%rbx),%r11
+ sbbq 32(%rbx),%r12
+ sbbq 40(%rbx),%r13
+ sbbq 48(%rbx),%r14
+ sbbq 56(%rbx),%r15
+
+
+ movq 0(%rax),%rsi
+ movq 8(%rax),%rdi
+ movq 16(%rax),%rcx
+ movq 24(%rax),%rdx
+ cmovncq %r8,%rsi
+ cmovncq %r9,%rdi
+ cmovncq %r10,%rcx
+ cmovncq %r11,%rdx
+ movq %rsi,0(%rax)
+ movq %rdi,8(%rax)
+ movq %rcx,16(%rax)
+ movq %rdx,24(%rax)
+
+ movq 32(%rax),%rsi
+ movq 40(%rax),%rdi
+ movq 48(%rax),%rcx
+ movq 56(%rax),%rdx
+ cmovncq %r12,%rsi
+ cmovncq %r13,%rdi
+ cmovncq %r14,%rcx
+ cmovncq %r15,%rdx
+ movq %rsi,32(%rax)
+ movq %rdi,40(%rax)
+ movq %rcx,48(%rax)
+ movq %rdx,56(%rax)
+
+ movq 0(%rsp),%rsi
+ movq 0(%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbx
+ movq 40(%rsi),%rbp
+ leaq 48(%rsi),%rsp
+L$epilogue:
+ .byte 0xf3,0xc3
diff --git a/deps/openssl/asm/x64-macosx-gas/bn/x86_64-mont.s b/deps/openssl/asm/x64-macosx-gas/bn/x86_64-mont.s
index 23292a071..ece106c49 100644
--- a/deps/openssl/asm/x64-macosx-gas/bn/x86_64-mont.s
+++ b/deps/openssl/asm/x64-macosx-gas/bn/x86_64-mont.s
@@ -5,6 +5,16 @@
.p2align 4
_bn_mul_mont:
+ testl $3,%r9d
+ jnz L$mul_enter
+ cmpl $8,%r9d
+ jb L$mul_enter
+ cmpq %rsi,%rdx
+ jne L$mul4x_enter
+ jmp L$sqr4x_enter
+
+.p2align 4
+L$mul_enter:
pushq %rbx
pushq %rbp
pushq %r12
@@ -20,48 +30,63 @@ _bn_mul_mont:
andq $-1024,%rsp
movq %r11,8(%rsp,%r9,8)
-L$prologue:
+L$mul_body:
movq %rdx,%r12
-
movq (%r8),%r8
+ movq (%r12),%rbx
+ movq (%rsi),%rax
xorq %r14,%r14
xorq %r15,%r15
- movq (%r12),%rbx
- movq (%rsi),%rax
+ movq %r8,%rbp
mulq %rbx
movq %rax,%r10
- movq %rdx,%r11
+ movq (%rcx),%rax
- imulq %r8,%rax
- movq %rax,%rbp
+ imulq %r10,%rbp
+ movq %rdx,%r11
- mulq (%rcx)
- addq %r10,%rax
+ mulq %rbp
+ addq %rax,%r10
+ movq 8(%rsi),%rax
adcq $0,%rdx
movq %rdx,%r13
leaq 1(%r15),%r15
+ jmp L$1st_enter
+
+.p2align 4
L$1st:
+ addq %rax,%r13
movq (%rsi,%r15,8),%rax
- mulq %rbx
- addq %r11,%rax
adcq $0,%rdx
- movq %rax,%r10
+ addq %r11,%r13
+ movq %r10,%r11
+ adcq $0,%rdx
+ movq %r13,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+L$1st_enter:
+ mulq %rbx
+ addq %rax,%r11
movq (%rcx,%r15,8),%rax
- movq %rdx,%r11
+ adcq $0,%rdx
+ leaq 1(%r15),%r15
+ movq %rdx,%r10
mulq %rbp
- addq %r13,%rax
- leaq 1(%r15),%r15
+ cmpq %r9,%r15
+ jne L$1st
+
+ addq %rax,%r13
+ movq (%rsi),%rax
adcq $0,%rdx
- addq %r10,%rax
+ addq %r11,%r13
adcq $0,%rdx
- movq %rax,-16(%rsp,%r15,8)
- cmpq %r9,%r15
+ movq %r13,-16(%rsp,%r15,8)
movq %rdx,%r13
- jl L$1st
+ movq %r10,%r11
xorq %rdx,%rdx
addq %r11,%r13
@@ -70,50 +95,64 @@ L$1st:
movq %rdx,(%rsp,%r9,8)
leaq 1(%r14),%r14
-.p2align 2
+ jmp L$outer
+.p2align 4
L$outer:
- xorq %r15,%r15
-
movq (%r12,%r14,8),%rbx
- movq (%rsi),%rax
+ xorq %r15,%r15
+ movq %r8,%rbp
+ movq (%rsp),%r10
mulq %rbx
- addq (%rsp),%rax
+ addq %rax,%r10
+ movq (%rcx),%rax
adcq $0,%rdx
- movq %rax,%r10
- movq %rdx,%r11
- imulq %r8,%rax
- movq %rax,%rbp
+ imulq %r10,%rbp
+ movq %rdx,%r11
- mulq (%rcx,%r15,8)
- addq %r10,%rax
- movq 8(%rsp),%r10
+ mulq %rbp
+ addq %rax,%r10
+ movq 8(%rsi),%rax
adcq $0,%rdx
+ movq 8(%rsp),%r10
movq %rdx,%r13
leaq 1(%r15),%r15
-.p2align 2
+ jmp L$inner_enter
+
+.p2align 4
L$inner:
+ addq %rax,%r13
movq (%rsi,%r15,8),%rax
- mulq %rbx
- addq %r11,%rax
adcq $0,%rdx
- addq %rax,%r10
+ addq %r10,%r13
+ movq (%rsp,%r15,8),%r10
+ adcq $0,%rdx
+ movq %r13,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+L$inner_enter:
+ mulq %rbx
+ addq %rax,%r11
movq (%rcx,%r15,8),%rax
adcq $0,%rdx
+ addq %r11,%r10
movq %rdx,%r11
+ adcq $0,%r11
+ leaq 1(%r15),%r15
mulq %rbp
- addq %r13,%rax
- leaq 1(%r15),%r15
- adcq $0,%rdx
- addq %r10,%rax
+ cmpq %r9,%r15
+ jne L$inner
+
+ addq %rax,%r13
+ movq (%rsi),%rax
adcq $0,%rdx
+ addq %r10,%r13
movq (%rsp,%r15,8),%r10
- cmpq %r9,%r15
- movq %rax,-16(%rsp,%r15,8)
+ adcq $0,%rdx
+ movq %r13,-16(%rsp,%r15,8)
movq %rdx,%r13
- jl L$inner
xorq %rdx,%rdx
addq %r11,%r13
@@ -127,35 +166,434 @@ L$inner:
cmpq %r9,%r14
jl L$outer
- leaq (%rsp),%rsi
- leaq -1(%r9),%r15
-
- movq (%rsi),%rax
xorq %r14,%r14
+ movq (%rsp),%rax
+ leaq (%rsp),%rsi
+ movq %r9,%r15
jmp L$sub
.p2align 4
L$sub: sbbq (%rcx,%r14,8),%rax
movq %rax,(%rdi,%r14,8)
- decq %r15
movq 8(%rsi,%r14,8),%rax
leaq 1(%r14),%r14
- jge L$sub
+ decq %r15
+ jnz L$sub
sbbq $0,%rax
+ xorq %r14,%r14
andq %rax,%rsi
notq %rax
movq %rdi,%rcx
andq %rax,%rcx
- leaq -1(%r9),%r15
+ movq %r9,%r15
orq %rcx,%rsi
.p2align 4
L$copy:
+ movq (%rsi,%r14,8),%rax
+ movq %r14,(%rsp,%r14,8)
+ movq %rax,(%rdi,%r14,8)
+ leaq 1(%r14),%r14
+ subq $1,%r15
+ jnz L$copy
+
+ movq 8(%rsp,%r9,8),%rsi
+ movq $1,%rax
+ movq (%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+L$mul_epilogue:
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+bn_mul4x_mont:
+L$mul4x_enter:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ movl %r9d,%r9d
+ leaq 4(%r9),%r10
+ movq %rsp,%r11
+ negq %r10
+ leaq (%rsp,%r10,8),%rsp
+ andq $-1024,%rsp
+
+ movq %r11,8(%rsp,%r9,8)
+L$mul4x_body:
+ movq %rdi,16(%rsp,%r9,8)
+ movq %rdx,%r12
+ movq (%r8),%r8
+ movq (%r12),%rbx
+ movq (%rsi),%rax
+
+ xorq %r14,%r14
+ xorq %r15,%r15
+
+ movq %r8,%rbp
+ mulq %rbx
+ movq %rax,%r10
+ movq (%rcx),%rax
+
+ imulq %r10,%rbp
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r10
+ movq 8(%rsi),%rax
+ adcq $0,%rdx
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq 8(%rcx),%rax
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq 16(%rsi),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ leaq 4(%r15),%r15
+ adcq $0,%rdx
+ movq %rdi,(%rsp)
+ movq %rdx,%r13
+ jmp L$1st4x
+.p2align 4
+L$1st4x:
+ mulq %rbx
+ addq %rax,%r10
+ movq -16(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq -8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-24(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq -8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq (%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+ mulq %rbx
+ addq %rax,%r10
+ movq (%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq 8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-8(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq 8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ leaq 4(%r15),%r15
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq -16(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-32(%rsp,%r15,8)
+ movq %rdx,%r13
+ cmpq %r9,%r15
+ jl L$1st4x
+
+ mulq %rbx
+ addq %rax,%r10
+ movq -16(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq -8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-24(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq -8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq (%rsi),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+ xorq %rdi,%rdi
+ addq %r10,%r13
+ adcq $0,%rdi
+ movq %r13,-8(%rsp,%r15,8)
+ movq %rdi,(%rsp,%r15,8)
+
+ leaq 1(%r14),%r14
+.p2align 2
+L$outer4x:
+ movq (%r12,%r14,8),%rbx
+ xorq %r15,%r15
+ movq (%rsp),%r10
+ movq %r8,%rbp
+ mulq %rbx
+ addq %rax,%r10
+ movq (%rcx),%rax
+ adcq $0,%rdx
+
+ imulq %r10,%rbp
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r10
+ movq 8(%rsi),%rax
+ adcq $0,%rdx
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq 8(%rcx),%rax
+ adcq $0,%rdx
+ addq 8(%rsp),%r11
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq 16(%rsi),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ leaq 4(%r15),%r15
+ adcq $0,%rdx
+ movq %rdi,(%rsp)
+ movq %rdx,%r13
+ jmp L$inner4x
+.p2align 4
+L$inner4x:
+ mulq %rbx
+ addq %rax,%r10
+ movq -16(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq -16(%rsp,%r15,8),%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq -8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-24(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq -8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq -8(%rsp,%r15,8),%r11
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
movq (%rsi,%r15,8),%rax
- movq %rax,(%rdi,%r15,8)
- movq %r14,(%rsp,%r15,8)
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+ mulq %rbx
+ addq %rax,%r10
+ movq (%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq (%rsp,%r15,8),%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq 8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-8(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq 8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq 8(%rsp,%r15,8),%r11
+ adcq $0,%rdx
+ leaq 4(%r15),%r15
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq -16(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-32(%rsp,%r15,8)
+ movq %rdx,%r13
+ cmpq %r9,%r15
+ jl L$inner4x
+
+ mulq %rbx
+ addq %rax,%r10
+ movq -16(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq -16(%rsp,%r15,8),%r10
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %rbp
+ addq %rax,%r13
+ movq -8(%rsi,%r15,8),%rax
+ adcq $0,%rdx
+ addq %r10,%r13
+ adcq $0,%rdx
+ movq %r13,-24(%rsp,%r15,8)
+ movq %rdx,%rdi
+
+ mulq %rbx
+ addq %rax,%r11
+ movq -8(%rcx,%r15,8),%rax
+ adcq $0,%rdx
+ addq -8(%rsp,%r15,8),%r11
+ adcq $0,%rdx
+ leaq 1(%r14),%r14
+ movq %rdx,%r10
+
+ mulq %rbp
+ addq %rax,%rdi
+ movq (%rsi),%rax
+ adcq $0,%rdx
+ addq %r11,%rdi
+ adcq $0,%rdx
+ movq %rdi,-16(%rsp,%r15,8)
+ movq %rdx,%r13
+
+ xorq %rdi,%rdi
+ addq %r10,%r13
+ adcq $0,%rdi
+ addq (%rsp,%r9,8),%r13
+ adcq $0,%rdi
+ movq %r13,-8(%rsp,%r15,8)
+ movq %rdi,(%rsp,%r15,8)
+
+ cmpq %r9,%r14
+ jl L$outer4x
+ movq 16(%rsp,%r9,8),%rdi
+ movq 0(%rsp),%rax
+ pxor %xmm0,%xmm0
+ movq 8(%rsp),%rdx
+ shrq $2,%r9
+ leaq (%rsp),%rsi
+ xorq %r14,%r14
+
+ subq 0(%rcx),%rax
+ movq 16(%rsi),%rbx
+ movq 24(%rsi),%rbp
+ sbbq 8(%rcx),%rdx
+ leaq -1(%r9),%r15
+ jmp L$sub4x
+.p2align 4
+L$sub4x:
+ movq %rax,0(%rdi,%r14,8)
+ movq %rdx,8(%rdi,%r14,8)
+ sbbq 16(%rcx,%r14,8),%rbx
+ movq 32(%rsi,%r14,8),%rax
+ movq 40(%rsi,%r14,8),%rdx
+ sbbq 24(%rcx,%r14,8),%rbp
+ movq %rbx,16(%rdi,%r14,8)
+ movq %rbp,24(%rdi,%r14,8)
+ sbbq 32(%rcx,%r14,8),%rax
+ movq 48(%rsi,%r14,8),%rbx
+ movq 56(%rsi,%r14,8),%rbp
+ sbbq 40(%rcx,%r14,8),%rdx
+ leaq 4(%r14),%r14
decq %r15
- jge L$copy
+ jnz L$sub4x
+ movq %rax,0(%rdi,%r14,8)
+ movq 32(%rsi,%r14,8),%rax
+ sbbq 16(%rcx,%r14,8),%rbx
+ movq %rdx,8(%rdi,%r14,8)
+ sbbq 24(%rcx,%r14,8),%rbp
+ movq %rbx,16(%rdi,%r14,8)
+
+ sbbq $0,%rax
+ movq %rbp,24(%rdi,%r14,8)
+ xorq %r14,%r14
+ andq %rax,%rsi
+ notq %rax
+ movq %rdi,%rcx
+ andq %rax,%rcx
+ leaq -1(%r9),%r15
+ orq %rcx,%rsi
+
+ movdqu (%rsi),%xmm1
+ movdqa %xmm0,(%rsp)
+ movdqu %xmm1,(%rdi)
+ jmp L$copy4x
+.p2align 4
+L$copy4x:
+ movdqu 16(%rsi,%r14,1),%xmm2
+ movdqu 32(%rsi,%r14,1),%xmm1
+ movdqa %xmm0,16(%rsp,%r14,1)
+ movdqu %xmm2,16(%rdi,%r14,1)
+ movdqa %xmm0,32(%rsp,%r14,1)
+ movdqu %xmm1,32(%rdi,%r14,1)
+ leaq 32(%r14),%r14
+ decq %r15
+ jnz L$copy4x
+
+ shlq $2,%r9
+ movdqu 16(%rsi,%r14,1),%xmm2
+ movdqa %xmm0,16(%rsp,%r14,1)
+ movdqu %xmm2,16(%rdi,%r14,1)
movq 8(%rsp,%r9,8),%rsi
movq $1,%rax
movq (%rsi),%r15
@@ -165,7 +603,772 @@ L$copy:
movq 32(%rsi),%rbp
movq 40(%rsi),%rbx
leaq 48(%rsi),%rsp
-L$epilogue:
+L$mul4x_epilogue:
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+bn_sqr4x_mont:
+L$sqr4x_enter:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ shll $3,%r9d
+ xorq %r10,%r10
+ movq %rsp,%r11
+ subq %r9,%r10
+ movq (%r8),%r8
+ leaq -72(%rsp,%r10,2),%rsp
+ andq $-1024,%rsp
+
+
+
+
+
+
+
+
+
+
+
+ movq %rdi,32(%rsp)
+ movq %rcx,40(%rsp)
+ movq %r8,48(%rsp)
+ movq %r11,56(%rsp)
+L$sqr4x_body:
+
+
+
+
+
+
+
+ leaq 32(%r10),%rbp
+ leaq (%rsi,%r9,1),%rsi
+
+ movq %r9,%rcx
+
+
+ movq -32(%rsi,%rbp,1),%r14
+ leaq 64(%rsp,%r9,2),%rdi
+ movq -24(%rsi,%rbp,1),%rax
+ leaq -32(%rdi,%rbp,1),%rdi
+ movq -16(%rsi,%rbp,1),%rbx
+ movq %rax,%r15
+
+ mulq %r14
+ movq %rax,%r10
+ movq %rbx,%rax
+ movq %rdx,%r11
+ movq %r10,-24(%rdi,%rbp,1)
+
+ xorq %r10,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,-16(%rdi,%rbp,1)
+
+ leaq -16(%rbp),%rcx
+
+
+ movq 8(%rsi,%rcx,1),%rbx
+ mulq %r15
+ movq %rax,%r12
+ movq %rbx,%rax
+ movq %rdx,%r13
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ leaq 16(%rcx),%rcx
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-8(%rdi,%rcx,1)
+ jmp L$sqr4x_1st
+
+.p2align 4
+L$sqr4x_1st:
+ movq (%rsi,%rcx,1),%rbx
+ xorq %r12,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %rbx,%rax
+ adcq %rdx,%r12
+
+ xorq %r10,%r10
+ addq %r13,%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,(%rdi,%rcx,1)
+
+
+ movq 8(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,8(%rdi,%rcx,1)
+
+ movq 16(%rsi,%rcx,1),%rbx
+ xorq %r12,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %rbx,%rax
+ adcq %rdx,%r12
+
+ xorq %r10,%r10
+ addq %r13,%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,16(%rdi,%rcx,1)
+
+
+ movq 24(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ leaq 32(%rcx),%rcx
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-8(%rdi,%rcx,1)
+
+ cmpq $0,%rcx
+ jne L$sqr4x_1st
+
+ xorq %r12,%r12
+ addq %r11,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ adcq %rdx,%r12
+
+ movq %r13,(%rdi)
+ leaq 16(%rbp),%rbp
+ movq %r12,8(%rdi)
+ jmp L$sqr4x_outer
+
+.p2align 4
+L$sqr4x_outer:
+ movq -32(%rsi,%rbp,1),%r14
+ leaq 64(%rsp,%r9,2),%rdi
+ movq -24(%rsi,%rbp,1),%rax
+ leaq -32(%rdi,%rbp,1),%rdi
+ movq -16(%rsi,%rbp,1),%rbx
+ movq %rax,%r15
+
+ movq -24(%rdi,%rbp,1),%r10
+ xorq %r11,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-24(%rdi,%rbp,1)
+
+ xorq %r10,%r10
+ addq -16(%rdi,%rbp,1),%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,-16(%rdi,%rbp,1)
+
+ leaq -16(%rbp),%rcx
+ xorq %r12,%r12
+
+
+ movq 8(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ addq 8(%rdi,%rcx,1),%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,8(%rdi,%rcx,1)
+
+ leaq 16(%rcx),%rcx
+ jmp L$sqr4x_inner
+
+.p2align 4
+L$sqr4x_inner:
+ movq (%rsi,%rcx,1),%rbx
+ xorq %r12,%r12
+ addq (%rdi,%rcx,1),%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %rbx,%rax
+ adcq %rdx,%r12
+
+ xorq %r10,%r10
+ addq %r13,%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,(%rdi,%rcx,1)
+
+ movq 8(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ addq 8(%rdi,%rcx,1),%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ leaq 16(%rcx),%rcx
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-8(%rdi,%rcx,1)
+
+ cmpq $0,%rcx
+ jne L$sqr4x_inner
+
+ xorq %r12,%r12
+ addq %r11,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ adcq %rdx,%r12
+
+ movq %r13,(%rdi)
+ movq %r12,8(%rdi)
+
+ addq $16,%rbp
+ jnz L$sqr4x_outer
+
+
+ movq -32(%rsi),%r14
+ leaq 64(%rsp,%r9,2),%rdi
+ movq -24(%rsi),%rax
+ leaq -32(%rdi,%rbp,1),%rdi
+ movq -16(%rsi),%rbx
+ movq %rax,%r15
+
+ xorq %r11,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-24(%rdi)
+
+ xorq %r10,%r10
+ addq %r13,%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ movq %r11,-16(%rdi)
+
+ movq -8(%rsi),%rbx
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq $0,%rdx
+
+ xorq %r11,%r11
+ addq %r12,%r10
+ movq %rdx,%r13
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %rbx,%rax
+ adcq %rdx,%r11
+ movq %r10,-8(%rdi)
+
+ xorq %r12,%r12
+ addq %r11,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq -16(%rsi),%rax
+ adcq %rdx,%r12
+
+ movq %r13,(%rdi)
+ movq %r12,8(%rdi)
+
+ mulq %rbx
+ addq $16,%rbp
+ xorq %r14,%r14
+ subq %r9,%rbp
+ xorq %r15,%r15
+
+ addq %r12,%rax
+ adcq $0,%rdx
+ movq %rax,8(%rdi)
+ movq %rdx,16(%rdi)
+ movq %r15,24(%rdi)
+
+ movq -16(%rsi,%rbp,1),%rax
+ leaq 64(%rsp,%r9,2),%rdi
+ xorq %r10,%r10
+ movq -24(%rdi,%rbp,2),%r11
+
+ leaq (%r14,%r10,2),%r12
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r13
+ shrq $63,%r11
+ orq %r10,%r13
+ movq -16(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq -8(%rdi,%rbp,2),%r11
+ adcq %rax,%r12
+ movq -8(%rsi,%rbp,1),%rax
+ movq %r12,-32(%rdi,%rbp,2)
+ adcq %rdx,%r13
+
+ leaq (%r14,%r10,2),%rbx
+ movq %r13,-24(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r8
+ shrq $63,%r11
+ orq %r10,%r8
+ movq 0(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq 8(%rdi,%rbp,2),%r11
+ adcq %rax,%rbx
+ movq 0(%rsi,%rbp,1),%rax
+ movq %rbx,-16(%rdi,%rbp,2)
+ adcq %rdx,%r8
+ leaq 16(%rbp),%rbp
+ movq %r8,-40(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ jmp L$sqr4x_shift_n_add
+
+.p2align 4
+L$sqr4x_shift_n_add:
+ leaq (%r14,%r10,2),%r12
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r13
+ shrq $63,%r11
+ orq %r10,%r13
+ movq -16(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq -8(%rdi,%rbp,2),%r11
+ adcq %rax,%r12
+ movq -8(%rsi,%rbp,1),%rax
+ movq %r12,-32(%rdi,%rbp,2)
+ adcq %rdx,%r13
+
+ leaq (%r14,%r10,2),%rbx
+ movq %r13,-24(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r8
+ shrq $63,%r11
+ orq %r10,%r8
+ movq 0(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq 8(%rdi,%rbp,2),%r11
+ adcq %rax,%rbx
+ movq 0(%rsi,%rbp,1),%rax
+ movq %rbx,-16(%rdi,%rbp,2)
+ adcq %rdx,%r8
+
+ leaq (%r14,%r10,2),%r12
+ movq %r8,-8(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r13
+ shrq $63,%r11
+ orq %r10,%r13
+ movq 16(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq 24(%rdi,%rbp,2),%r11
+ adcq %rax,%r12
+ movq 8(%rsi,%rbp,1),%rax
+ movq %r12,0(%rdi,%rbp,2)
+ adcq %rdx,%r13
+
+ leaq (%r14,%r10,2),%rbx
+ movq %r13,8(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r8
+ shrq $63,%r11
+ orq %r10,%r8
+ movq 32(%rdi,%rbp,2),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq 40(%rdi,%rbp,2),%r11
+ adcq %rax,%rbx
+ movq 16(%rsi,%rbp,1),%rax
+ movq %rbx,16(%rdi,%rbp,2)
+ adcq %rdx,%r8
+ movq %r8,24(%rdi,%rbp,2)
+ sbbq %r15,%r15
+ addq $32,%rbp
+ jnz L$sqr4x_shift_n_add
+
+ leaq (%r14,%r10,2),%r12
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r13
+ shrq $63,%r11
+ orq %r10,%r13
+ movq -16(%rdi),%r10
+ movq %r11,%r14
+ mulq %rax
+ negq %r15
+ movq -8(%rdi),%r11
+ adcq %rax,%r12
+ movq -8(%rsi),%rax
+ movq %r12,-32(%rdi)
+ adcq %rdx,%r13
+
+ leaq (%r14,%r10,2),%rbx
+ movq %r13,-24(%rdi)
+ sbbq %r15,%r15
+ shrq $63,%r10
+ leaq (%rcx,%r11,2),%r8
+ shrq $63,%r11
+ orq %r10,%r8
+ mulq %rax
+ negq %r15
+ adcq %rax,%rbx
+ adcq %rdx,%r8
+ movq %rbx,-16(%rdi)
+ movq %r8,-8(%rdi)
+ movq 40(%rsp),%rsi
+ movq 48(%rsp),%r8
+ xorq %rcx,%rcx
+ movq %r9,0(%rsp)
+ subq %r9,%rcx
+ movq 64(%rsp),%r10
+ movq %r8,%r14
+ leaq 64(%rsp,%r9,2),%rax
+ leaq 64(%rsp,%r9,1),%rdi
+ movq %rax,8(%rsp)
+ leaq (%rsi,%r9,1),%rsi
+ xorq %rbp,%rbp
+
+ movq 0(%rsi,%rcx,1),%rax
+ movq 8(%rsi,%rcx,1),%r9
+ imulq %r10,%r14
+ movq %rax,%rbx
+ jmp L$sqr4x_mont_outer
+
+.p2align 4
+L$sqr4x_mont_outer:
+ xorq %r11,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %r9,%rax
+ adcq %rdx,%r11
+ movq %r8,%r15
+
+ xorq %r10,%r10
+ addq 8(%rdi,%rcx,1),%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+
+ imulq %r11,%r15
+
+ movq 16(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ addq %r11,%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+ movq %r12,8(%rdi,%rcx,1)
+
+ xorq %r11,%r11
+ addq 16(%rdi,%rcx,1),%r10
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %r9,%rax
+ adcq %rdx,%r11
+
+ movq 24(%rsi,%rcx,1),%r9
+ xorq %r12,%r12
+ addq %r10,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %r9,%rax
+ adcq %rdx,%r12
+ movq %r13,16(%rdi,%rcx,1)
+
+ xorq %r10,%r10
+ addq 24(%rdi,%rcx,1),%r11
+ leaq 32(%rcx),%rcx
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ jmp L$sqr4x_mont_inner
+
+.p2align 4
+L$sqr4x_mont_inner:
+ movq (%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ addq %r11,%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+ movq %r12,-8(%rdi,%rcx,1)
+
+ xorq %r11,%r11
+ addq (%rdi,%rcx,1),%r10
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %r9,%rax
+ adcq %rdx,%r11
+
+ movq 8(%rsi,%rcx,1),%r9
+ xorq %r12,%r12
+ addq %r10,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %r9,%rax
+ adcq %rdx,%r12
+ movq %r13,(%rdi,%rcx,1)
+
+ xorq %r10,%r10
+ addq 8(%rdi,%rcx,1),%r11
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+
+
+ movq 16(%rsi,%rcx,1),%rbx
+ xorq %r13,%r13
+ addq %r11,%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %rbx,%rax
+ adcq %rdx,%r13
+ movq %r12,8(%rdi,%rcx,1)
+
+ xorq %r11,%r11
+ addq 16(%rdi,%rcx,1),%r10
+ adcq $0,%r11
+ mulq %r14
+ addq %rax,%r10
+ movq %r9,%rax
+ adcq %rdx,%r11
+
+ movq 24(%rsi,%rcx,1),%r9
+ xorq %r12,%r12
+ addq %r10,%r13
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %r9,%rax
+ adcq %rdx,%r12
+ movq %r13,16(%rdi,%rcx,1)
+
+ xorq %r10,%r10
+ addq 24(%rdi,%rcx,1),%r11
+ leaq 32(%rcx),%rcx
+ adcq $0,%r10
+ mulq %r14
+ addq %rax,%r11
+ movq %rbx,%rax
+ adcq %rdx,%r10
+ cmpq $0,%rcx
+ jne L$sqr4x_mont_inner
+
+ subq 0(%rsp),%rcx
+ movq %r8,%r14
+
+ xorq %r13,%r13
+ addq %r11,%r12
+ adcq $0,%r13
+ mulq %r15
+ addq %rax,%r12
+ movq %r9,%rax
+ adcq %rdx,%r13
+ movq %r12,-8(%rdi)
+
+ xorq %r11,%r11
+ addq (%rdi),%r10
+ adcq $0,%r11
+ movq 0(%rsi,%rcx,1),%rbx
+ addq %rbp,%r10
+ adcq $0,%r11
+
+ imulq 16(%rdi,%rcx,1),%r14
+ xorq %r12,%r12
+ movq 8(%rsi,%rcx,1),%r9
+ addq %r10,%r13
+ movq 16(%rdi,%rcx,1),%r10
+ adcq $0,%r12
+ mulq %r15
+ addq %rax,%r13
+ movq %rbx,%rax
+ adcq %rdx,%r12
+ movq %r13,(%rdi)
+
+ xorq %rbp,%rbp
+ addq 8(%rdi),%r12
+ adcq %rbp,%rbp
+ addq %r11,%r12
+ leaq 16(%rdi),%rdi
+ adcq $0,%rbp
+ movq %r12,-8(%rdi)
+ cmpq 8(%rsp),%rdi
+ jb L$sqr4x_mont_outer
+
+ movq 0(%rsp),%r9
+ movq %rbp,(%rdi)
+ movq 64(%rsp,%r9,1),%rax
+ leaq 64(%rsp,%r9,1),%rbx
+ movq 40(%rsp),%rsi
+ shrq $5,%r9
+ movq 8(%rbx),%rdx
+ xorq %rbp,%rbp
+
+ movq 32(%rsp),%rdi
+ subq 0(%rsi),%rax
+ movq 16(%rbx),%r10
+ movq 24(%rbx),%r11
+ sbbq 8(%rsi),%rdx
+ leaq -1(%r9),%rcx
+ jmp L$sqr4x_sub
+.p2align 4
+L$sqr4x_sub:
+ movq %rax,0(%rdi,%rbp,8)
+ movq %rdx,8(%rdi,%rbp,8)
+ sbbq 16(%rsi,%rbp,8),%r10
+ movq 32(%rbx,%rbp,8),%rax
+ movq 40(%rbx,%rbp,8),%rdx
+ sbbq 24(%rsi,%rbp,8),%r11
+ movq %r10,16(%rdi,%rbp,8)
+ movq %r11,24(%rdi,%rbp,8)
+ sbbq 32(%rsi,%rbp,8),%rax
+ movq 48(%rbx,%rbp,8),%r10
+ movq 56(%rbx,%rbp,8),%r11
+ sbbq 40(%rsi,%rbp,8),%rdx
+ leaq 4(%rbp),%rbp
+ decq %rcx
+ jnz L$sqr4x_sub
+
+ movq %rax,0(%rdi,%rbp,8)
+ movq 32(%rbx,%rbp,8),%rax
+ sbbq 16(%rsi,%rbp,8),%r10
+ movq %rdx,8(%rdi,%rbp,8)
+ sbbq 24(%rsi,%rbp,8),%r11
+ movq %r10,16(%rdi,%rbp,8)
+
+ sbbq $0,%rax
+ movq %r11,24(%rdi,%rbp,8)
+ xorq %rbp,%rbp
+ andq %rax,%rbx
+ notq %rax
+ movq %rdi,%rsi
+ andq %rax,%rsi
+ leaq -1(%r9),%rcx
+ orq %rsi,%rbx
+
+ pxor %xmm0,%xmm0
+ leaq 64(%rsp,%r9,8),%rsi
+ movdqu (%rbx),%xmm1
+ leaq (%rsi,%r9,8),%rsi
+ movdqa %xmm0,64(%rsp)
+ movdqa %xmm0,(%rsi)
+ movdqu %xmm1,(%rdi)
+ jmp L$sqr4x_copy
+.p2align 4
+L$sqr4x_copy:
+ movdqu 16(%rbx,%rbp,1),%xmm2
+ movdqu 32(%rbx,%rbp,1),%xmm1
+ movdqa %xmm0,80(%rsp,%rbp,1)
+ movdqa %xmm0,96(%rsp,%rbp,1)
+ movdqa %xmm0,16(%rsi,%rbp,1)
+ movdqa %xmm0,32(%rsi,%rbp,1)
+ movdqu %xmm2,16(%rdi,%rbp,1)
+ movdqu %xmm1,32(%rdi,%rbp,1)
+ leaq 32(%rbp),%rbp
+ decq %rcx
+ jnz L$sqr4x_copy
+
+ movdqu 16(%rbx,%rbp,1),%xmm2
+ movdqa %xmm0,80(%rsp,%rbp,1)
+ movdqa %xmm0,16(%rsi,%rbp,1)
+ movdqu %xmm2,16(%rdi,%rbp,1)
+ movq 56(%rsp),%rsi
+ movq $1,%rax
+ movq 0(%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+L$sqr4x_epilogue:
.byte 0xf3,0xc3
.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
diff --git a/deps/openssl/asm/x64-macosx-gas/md5/md5-x86_64.s b/deps/openssl/asm/x64-macosx-gas/md5/md5-x86_64.s
index 96f6ea16c..cdecac7b4 100644
--- a/deps/openssl/asm/x64-macosx-gas/md5/md5-x86_64.s
+++ b/deps/openssl/asm/x64-macosx-gas/md5/md5-x86_64.s
@@ -668,4 +668,3 @@ L$end:
addq $40,%rsp
L$epilogue:
.byte 0xf3,0xc3
-
diff --git a/deps/openssl/asm/x64-macosx-gas/rc4/rc4-md5-x86_64.s b/deps/openssl/asm/x64-macosx-gas/rc4/rc4-md5-x86_64.s
new file mode 100644
index 000000000..85f9905a8
--- /dev/null
+++ b/deps/openssl/asm/x64-macosx-gas/rc4/rc4-md5-x86_64.s
@@ -0,0 +1,1259 @@
+.text
+
+.p2align 4
+
+.globl _rc4_md5_enc
+
+_rc4_md5_enc:
+ cmpq $0,%r9
+ je L$abort
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $40,%rsp
+L$body:
+ movq %rcx,%r11
+ movq %r9,%r12
+ movq %rsi,%r13
+ movq %rdx,%r14
+ movq %r8,%r15
+ xorq %rbp,%rbp
+ xorq %rcx,%rcx
+
+ leaq 8(%rdi),%rdi
+ movb -8(%rdi),%bpl
+ movb -4(%rdi),%cl
+
+ incb %bpl
+ subq %r13,%r14
+ movl (%rdi,%rbp,4),%eax
+ addb %al,%cl
+ leaq (%rdi,%rbp,4),%rsi
+ shlq $6,%r12
+ addq %r15,%r12
+ movq %r12,16(%rsp)
+
+ movq %r11,24(%rsp)
+ movl 0(%r11),%r8d
+ movl 4(%r11),%r9d
+ movl 8(%r11),%r10d
+ movl 12(%r11),%r11d
+ jmp L$oop
+
+.p2align 4
+L$oop:
+ movl %r8d,0(%rsp)
+ movl %r9d,4(%rsp)
+ movl %r10d,8(%rsp)
+ movl %r11d,%r12d
+ movl %r11d,12(%rsp)
+ pxor %xmm0,%xmm0
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 0(%r15),%r8d
+ addb %dl,%al
+ movl 4(%rsi),%ebx
+ addl $3614090360,%r8d
+ xorl %r11d,%r12d
+ movzbl %al,%eax
+ movl %edx,0(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $7,%r8d
+ movl %r10d,%r12d
+ movd (%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ pxor %xmm1,%xmm1
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 4(%r15),%r11d
+ addb %dl,%bl
+ movl 8(%rsi),%eax
+ addl $3905402710,%r11d
+ xorl %r10d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,4(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $12,%r11d
+ movl %r9d,%r12d
+ movd (%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 8(%r15),%r10d
+ addb %dl,%al
+ movl 12(%rsi),%ebx
+ addl $606105819,%r10d
+ xorl %r9d,%r12d
+ movzbl %al,%eax
+ movl %edx,8(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $17,%r10d
+ movl %r8d,%r12d
+ pinsrw $1,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 12(%r15),%r9d
+ addb %dl,%bl
+ movl 16(%rsi),%eax
+ addl $3250441966,%r9d
+ xorl %r8d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,12(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $22,%r9d
+ movl %r11d,%r12d
+ pinsrw $1,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 16(%r15),%r8d
+ addb %dl,%al
+ movl 20(%rsi),%ebx
+ addl $4118548399,%r8d
+ xorl %r11d,%r12d
+ movzbl %al,%eax
+ movl %edx,16(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $7,%r8d
+ movl %r10d,%r12d
+ pinsrw $2,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 20(%r15),%r11d
+ addb %dl,%bl
+ movl 24(%rsi),%eax
+ addl $1200080426,%r11d
+ xorl %r10d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,20(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $12,%r11d
+ movl %r9d,%r12d
+ pinsrw $2,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 24(%r15),%r10d
+ addb %dl,%al
+ movl 28(%rsi),%ebx
+ addl $2821735955,%r10d
+ xorl %r9d,%r12d
+ movzbl %al,%eax
+ movl %edx,24(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $17,%r10d
+ movl %r8d,%r12d
+ pinsrw $3,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 28(%r15),%r9d
+ addb %dl,%bl
+ movl 32(%rsi),%eax
+ addl $4249261313,%r9d
+ xorl %r8d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,28(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $22,%r9d
+ movl %r11d,%r12d
+ pinsrw $3,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 32(%r15),%r8d
+ addb %dl,%al
+ movl 36(%rsi),%ebx
+ addl $1770035416,%r8d
+ xorl %r11d,%r12d
+ movzbl %al,%eax
+ movl %edx,32(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $7,%r8d
+ movl %r10d,%r12d
+ pinsrw $4,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 36(%r15),%r11d
+ addb %dl,%bl
+ movl 40(%rsi),%eax
+ addl $2336552879,%r11d
+ xorl %r10d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,36(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $12,%r11d
+ movl %r9d,%r12d
+ pinsrw $4,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 40(%r15),%r10d
+ addb %dl,%al
+ movl 44(%rsi),%ebx
+ addl $4294925233,%r10d
+ xorl %r9d,%r12d
+ movzbl %al,%eax
+ movl %edx,40(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $17,%r10d
+ movl %r8d,%r12d
+ pinsrw $5,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 44(%r15),%r9d
+ addb %dl,%bl
+ movl 48(%rsi),%eax
+ addl $2304563134,%r9d
+ xorl %r8d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,44(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $22,%r9d
+ movl %r11d,%r12d
+ pinsrw $5,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 48(%r15),%r8d
+ addb %dl,%al
+ movl 52(%rsi),%ebx
+ addl $1804603682,%r8d
+ xorl %r11d,%r12d
+ movzbl %al,%eax
+ movl %edx,48(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $7,%r8d
+ movl %r10d,%r12d
+ pinsrw $6,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 52(%r15),%r11d
+ addb %dl,%bl
+ movl 56(%rsi),%eax
+ addl $4254626195,%r11d
+ xorl %r10d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,52(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $12,%r11d
+ movl %r9d,%r12d
+ pinsrw $6,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 56(%r15),%r10d
+ addb %dl,%al
+ movl 60(%rsi),%ebx
+ addl $2792965006,%r10d
+ xorl %r9d,%r12d
+ movzbl %al,%eax
+ movl %edx,56(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $17,%r10d
+ movl %r8d,%r12d
+ pinsrw $7,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movdqu (%r13),%xmm2
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 60(%r15),%r9d
+ addb %dl,%bl
+ movl 64(%rsi),%eax
+ addl $1236535329,%r9d
+ xorl %r8d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,60(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $22,%r9d
+ movl %r10d,%r12d
+ pinsrw $7,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm2
+ pxor %xmm1,%xmm2
+ pxor %xmm0,%xmm0
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 4(%r15),%r8d
+ addb %dl,%al
+ movl 68(%rsi),%ebx
+ addl $4129170786,%r8d
+ xorl %r10d,%r12d
+ movzbl %al,%eax
+ movl %edx,64(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $5,%r8d
+ movl %r9d,%r12d
+ movd (%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ pxor %xmm1,%xmm1
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 24(%r15),%r11d
+ addb %dl,%bl
+ movl 72(%rsi),%eax
+ addl $3225465664,%r11d
+ xorl %r9d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,68(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $9,%r11d
+ movl %r8d,%r12d
+ movd (%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 44(%r15),%r10d
+ addb %dl,%al
+ movl 76(%rsi),%ebx
+ addl $643717713,%r10d
+ xorl %r8d,%r12d
+ movzbl %al,%eax
+ movl %edx,72(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $14,%r10d
+ movl %r11d,%r12d
+ pinsrw $1,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 0(%r15),%r9d
+ addb %dl,%bl
+ movl 80(%rsi),%eax
+ addl $3921069994,%r9d
+ xorl %r11d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,76(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $20,%r9d
+ movl %r10d,%r12d
+ pinsrw $1,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 20(%r15),%r8d
+ addb %dl,%al
+ movl 84(%rsi),%ebx
+ addl $3593408605,%r8d
+ xorl %r10d,%r12d
+ movzbl %al,%eax
+ movl %edx,80(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $5,%r8d
+ movl %r9d,%r12d
+ pinsrw $2,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 40(%r15),%r11d
+ addb %dl,%bl
+ movl 88(%rsi),%eax
+ addl $38016083,%r11d
+ xorl %r9d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,84(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $9,%r11d
+ movl %r8d,%r12d
+ pinsrw $2,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 60(%r15),%r10d
+ addb %dl,%al
+ movl 92(%rsi),%ebx
+ addl $3634488961,%r10d
+ xorl %r8d,%r12d
+ movzbl %al,%eax
+ movl %edx,88(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $14,%r10d
+ movl %r11d,%r12d
+ pinsrw $3,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 16(%r15),%r9d
+ addb %dl,%bl
+ movl 96(%rsi),%eax
+ addl $3889429448,%r9d
+ xorl %r11d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,92(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $20,%r9d
+ movl %r10d,%r12d
+ pinsrw $3,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 36(%r15),%r8d
+ addb %dl,%al
+ movl 100(%rsi),%ebx
+ addl $568446438,%r8d
+ xorl %r10d,%r12d
+ movzbl %al,%eax
+ movl %edx,96(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $5,%r8d
+ movl %r9d,%r12d
+ pinsrw $4,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 56(%r15),%r11d
+ addb %dl,%bl
+ movl 104(%rsi),%eax
+ addl $3275163606,%r11d
+ xorl %r9d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,100(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $9,%r11d
+ movl %r8d,%r12d
+ pinsrw $4,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 12(%r15),%r10d
+ addb %dl,%al
+ movl 108(%rsi),%ebx
+ addl $4107603335,%r10d
+ xorl %r8d,%r12d
+ movzbl %al,%eax
+ movl %edx,104(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $14,%r10d
+ movl %r11d,%r12d
+ pinsrw $5,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 32(%r15),%r9d
+ addb %dl,%bl
+ movl 112(%rsi),%eax
+ addl $1163531501,%r9d
+ xorl %r11d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,108(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $20,%r9d
+ movl %r10d,%r12d
+ pinsrw $5,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r11d,%r12d
+ addl 52(%r15),%r8d
+ addb %dl,%al
+ movl 116(%rsi),%ebx
+ addl $2850285829,%r8d
+ xorl %r10d,%r12d
+ movzbl %al,%eax
+ movl %edx,112(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $5,%r8d
+ movl %r9d,%r12d
+ pinsrw $6,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r10d,%r12d
+ addl 8(%r15),%r11d
+ addb %dl,%bl
+ movl 120(%rsi),%eax
+ addl $4243563512,%r11d
+ xorl %r9d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,116(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $9,%r11d
+ movl %r8d,%r12d
+ pinsrw $6,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ andl %r9d,%r12d
+ addl 28(%r15),%r10d
+ addb %dl,%al
+ movl 124(%rsi),%ebx
+ addl $1735328473,%r10d
+ xorl %r8d,%r12d
+ movzbl %al,%eax
+ movl %edx,120(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $14,%r10d
+ movl %r11d,%r12d
+ pinsrw $7,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movdqu 16(%r13),%xmm3
+ addb $32,%bpl
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ andl %r8d,%r12d
+ addl 48(%r15),%r9d
+ addb %dl,%bl
+ movl 0(%rdi,%rbp,4),%eax
+ addl $2368359562,%r9d
+ xorl %r11d,%r12d
+ movzbl %bl,%ebx
+ movl %edx,124(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $20,%r9d
+ movl %r11d,%r12d
+ pinsrw $7,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movq %rcx,%rsi
+ xorq %rcx,%rcx
+ movb %sil,%cl
+ leaq (%rdi,%rbp,4),%rsi
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm3
+ pxor %xmm1,%xmm3
+ pxor %xmm0,%xmm0
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r9d,%r12d
+ addl 20(%r15),%r8d
+ addb %dl,%al
+ movl 4(%rsi),%ebx
+ addl $4294588738,%r8d
+ movzbl %al,%eax
+ addl %r12d,%r8d
+ movl %edx,0(%rsi)
+ addb %bl,%cl
+ roll $4,%r8d
+ movl %r10d,%r12d
+ movd (%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ pxor %xmm1,%xmm1
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r8d,%r12d
+ addl 32(%r15),%r11d
+ addb %dl,%bl
+ movl 8(%rsi),%eax
+ addl $2272392833,%r11d
+ movzbl %bl,%ebx
+ addl %r12d,%r11d
+ movl %edx,4(%rsi)
+ addb %al,%cl
+ roll $11,%r11d
+ movl %r9d,%r12d
+ movd (%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r11d,%r12d
+ addl 44(%r15),%r10d
+ addb %dl,%al
+ movl 12(%rsi),%ebx
+ addl $1839030562,%r10d
+ movzbl %al,%eax
+ addl %r12d,%r10d
+ movl %edx,8(%rsi)
+ addb %bl,%cl
+ roll $16,%r10d
+ movl %r8d,%r12d
+ pinsrw $1,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r10d,%r12d
+ addl 56(%r15),%r9d
+ addb %dl,%bl
+ movl 16(%rsi),%eax
+ addl $4259657740,%r9d
+ movzbl %bl,%ebx
+ addl %r12d,%r9d
+ movl %edx,12(%rsi)
+ addb %al,%cl
+ roll $23,%r9d
+ movl %r11d,%r12d
+ pinsrw $1,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r9d,%r12d
+ addl 4(%r15),%r8d
+ addb %dl,%al
+ movl 20(%rsi),%ebx
+ addl $2763975236,%r8d
+ movzbl %al,%eax
+ addl %r12d,%r8d
+ movl %edx,16(%rsi)
+ addb %bl,%cl
+ roll $4,%r8d
+ movl %r10d,%r12d
+ pinsrw $2,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r8d,%r12d
+ addl 16(%r15),%r11d
+ addb %dl,%bl
+ movl 24(%rsi),%eax
+ addl $1272893353,%r11d
+ movzbl %bl,%ebx
+ addl %r12d,%r11d
+ movl %edx,20(%rsi)
+ addb %al,%cl
+ roll $11,%r11d
+ movl %r9d,%r12d
+ pinsrw $2,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r11d,%r12d
+ addl 28(%r15),%r10d
+ addb %dl,%al
+ movl 28(%rsi),%ebx
+ addl $4139469664,%r10d
+ movzbl %al,%eax
+ addl %r12d,%r10d
+ movl %edx,24(%rsi)
+ addb %bl,%cl
+ roll $16,%r10d
+ movl %r8d,%r12d
+ pinsrw $3,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r10d,%r12d
+ addl 40(%r15),%r9d
+ addb %dl,%bl
+ movl 32(%rsi),%eax
+ addl $3200236656,%r9d
+ movzbl %bl,%ebx
+ addl %r12d,%r9d
+ movl %edx,28(%rsi)
+ addb %al,%cl
+ roll $23,%r9d
+ movl %r11d,%r12d
+ pinsrw $3,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r9d,%r12d
+ addl 52(%r15),%r8d
+ addb %dl,%al
+ movl 36(%rsi),%ebx
+ addl $681279174,%r8d
+ movzbl %al,%eax
+ addl %r12d,%r8d
+ movl %edx,32(%rsi)
+ addb %bl,%cl
+ roll $4,%r8d
+ movl %r10d,%r12d
+ pinsrw $4,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r8d,%r12d
+ addl 0(%r15),%r11d
+ addb %dl,%bl
+ movl 40(%rsi),%eax
+ addl $3936430074,%r11d
+ movzbl %bl,%ebx
+ addl %r12d,%r11d
+ movl %edx,36(%rsi)
+ addb %al,%cl
+ roll $11,%r11d
+ movl %r9d,%r12d
+ pinsrw $4,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r11d,%r12d
+ addl 12(%r15),%r10d
+ addb %dl,%al
+ movl 44(%rsi),%ebx
+ addl $3572445317,%r10d
+ movzbl %al,%eax
+ addl %r12d,%r10d
+ movl %edx,40(%rsi)
+ addb %bl,%cl
+ roll $16,%r10d
+ movl %r8d,%r12d
+ pinsrw $5,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r10d,%r12d
+ addl 24(%r15),%r9d
+ addb %dl,%bl
+ movl 48(%rsi),%eax
+ addl $76029189,%r9d
+ movzbl %bl,%ebx
+ addl %r12d,%r9d
+ movl %edx,44(%rsi)
+ addb %al,%cl
+ roll $23,%r9d
+ movl %r11d,%r12d
+ pinsrw $5,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r9d,%r12d
+ addl 36(%r15),%r8d
+ addb %dl,%al
+ movl 52(%rsi),%ebx
+ addl $3654602809,%r8d
+ movzbl %al,%eax
+ addl %r12d,%r8d
+ movl %edx,48(%rsi)
+ addb %bl,%cl
+ roll $4,%r8d
+ movl %r10d,%r12d
+ pinsrw $6,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r8d,%r12d
+ addl 48(%r15),%r11d
+ addb %dl,%bl
+ movl 56(%rsi),%eax
+ addl $3873151461,%r11d
+ movzbl %bl,%ebx
+ addl %r12d,%r11d
+ movl %edx,52(%rsi)
+ addb %al,%cl
+ roll $11,%r11d
+ movl %r9d,%r12d
+ pinsrw $6,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ xorl %r11d,%r12d
+ addl 60(%r15),%r10d
+ addb %dl,%al
+ movl 60(%rsi),%ebx
+ addl $530742520,%r10d
+ movzbl %al,%eax
+ addl %r12d,%r10d
+ movl %edx,56(%rsi)
+ addb %bl,%cl
+ roll $16,%r10d
+ movl %r8d,%r12d
+ pinsrw $7,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movdqu 32(%r13),%xmm4
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ xorl %r10d,%r12d
+ addl 8(%r15),%r9d
+ addb %dl,%bl
+ movl 64(%rsi),%eax
+ addl $3299628645,%r9d
+ movzbl %bl,%ebx
+ addl %r12d,%r9d
+ movl %edx,60(%rsi)
+ addb %al,%cl
+ roll $23,%r9d
+ movl $-1,%r12d
+ pinsrw $7,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm4
+ pxor %xmm1,%xmm4
+ pxor %xmm0,%xmm0
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r9d,%r12d
+ addl 0(%r15),%r8d
+ addb %dl,%al
+ movl 68(%rsi),%ebx
+ addl $4096336452,%r8d
+ movzbl %al,%eax
+ xorl %r10d,%r12d
+ movl %edx,64(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $6,%r8d
+ movl $-1,%r12d
+ movd (%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ pxor %xmm1,%xmm1
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r8d,%r12d
+ addl 28(%r15),%r11d
+ addb %dl,%bl
+ movl 72(%rsi),%eax
+ addl $1126891415,%r11d
+ movzbl %bl,%ebx
+ xorl %r9d,%r12d
+ movl %edx,68(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $10,%r11d
+ movl $-1,%r12d
+ movd (%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r11d,%r12d
+ addl 56(%r15),%r10d
+ addb %dl,%al
+ movl 76(%rsi),%ebx
+ addl $2878612391,%r10d
+ movzbl %al,%eax
+ xorl %r8d,%r12d
+ movl %edx,72(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $15,%r10d
+ movl $-1,%r12d
+ pinsrw $1,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r10d,%r12d
+ addl 20(%r15),%r9d
+ addb %dl,%bl
+ movl 80(%rsi),%eax
+ addl $4237533241,%r9d
+ movzbl %bl,%ebx
+ xorl %r11d,%r12d
+ movl %edx,76(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $21,%r9d
+ movl $-1,%r12d
+ pinsrw $1,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r9d,%r12d
+ addl 48(%r15),%r8d
+ addb %dl,%al
+ movl 84(%rsi),%ebx
+ addl $1700485571,%r8d
+ movzbl %al,%eax
+ xorl %r10d,%r12d
+ movl %edx,80(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $6,%r8d
+ movl $-1,%r12d
+ pinsrw $2,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r8d,%r12d
+ addl 12(%r15),%r11d
+ addb %dl,%bl
+ movl 88(%rsi),%eax
+ addl $2399980690,%r11d
+ movzbl %bl,%ebx
+ xorl %r9d,%r12d
+ movl %edx,84(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $10,%r11d
+ movl $-1,%r12d
+ pinsrw $2,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r11d,%r12d
+ addl 40(%r15),%r10d
+ addb %dl,%al
+ movl 92(%rsi),%ebx
+ addl $4293915773,%r10d
+ movzbl %al,%eax
+ xorl %r8d,%r12d
+ movl %edx,88(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $15,%r10d
+ movl $-1,%r12d
+ pinsrw $3,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r10d,%r12d
+ addl 4(%r15),%r9d
+ addb %dl,%bl
+ movl 96(%rsi),%eax
+ addl $2240044497,%r9d
+ movzbl %bl,%ebx
+ xorl %r11d,%r12d
+ movl %edx,92(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $21,%r9d
+ movl $-1,%r12d
+ pinsrw $3,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r9d,%r12d
+ addl 32(%r15),%r8d
+ addb %dl,%al
+ movl 100(%rsi),%ebx
+ addl $1873313359,%r8d
+ movzbl %al,%eax
+ xorl %r10d,%r12d
+ movl %edx,96(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $6,%r8d
+ movl $-1,%r12d
+ pinsrw $4,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r8d,%r12d
+ addl 60(%r15),%r11d
+ addb %dl,%bl
+ movl 104(%rsi),%eax
+ addl $4264355552,%r11d
+ movzbl %bl,%ebx
+ xorl %r9d,%r12d
+ movl %edx,100(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $10,%r11d
+ movl $-1,%r12d
+ pinsrw $4,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r11d,%r12d
+ addl 24(%r15),%r10d
+ addb %dl,%al
+ movl 108(%rsi),%ebx
+ addl $2734768916,%r10d
+ movzbl %al,%eax
+ xorl %r8d,%r12d
+ movl %edx,104(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $15,%r10d
+ movl $-1,%r12d
+ pinsrw $5,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r10d,%r12d
+ addl 52(%r15),%r9d
+ addb %dl,%bl
+ movl 112(%rsi),%eax
+ addl $1309151649,%r9d
+ movzbl %bl,%ebx
+ xorl %r11d,%r12d
+ movl %edx,108(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $21,%r9d
+ movl $-1,%r12d
+ pinsrw $5,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r11d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r9d,%r12d
+ addl 16(%r15),%r8d
+ addb %dl,%al
+ movl 116(%rsi),%ebx
+ addl $4149444226,%r8d
+ movzbl %al,%eax
+ xorl %r10d,%r12d
+ movl %edx,112(%rsi)
+ addl %r12d,%r8d
+ addb %bl,%cl
+ roll $6,%r8d
+ movl $-1,%r12d
+ pinsrw $6,(%rdi,%rax,4),%xmm0
+
+ addl %r9d,%r8d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r10d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r8d,%r12d
+ addl 44(%r15),%r11d
+ addb %dl,%bl
+ movl 120(%rsi),%eax
+ addl $3174756917,%r11d
+ movzbl %bl,%ebx
+ xorl %r9d,%r12d
+ movl %edx,116(%rsi)
+ addl %r12d,%r11d
+ addb %al,%cl
+ roll $10,%r11d
+ movl $-1,%r12d
+ pinsrw $6,(%rdi,%rbx,4),%xmm1
+
+ addl %r8d,%r11d
+ movl (%rdi,%rcx,4),%edx
+ xorl %r9d,%r12d
+ movl %eax,(%rdi,%rcx,4)
+ orl %r11d,%r12d
+ addl 8(%r15),%r10d
+ addb %dl,%al
+ movl 124(%rsi),%ebx
+ addl $718787259,%r10d
+ movzbl %al,%eax
+ xorl %r8d,%r12d
+ movl %edx,120(%rsi)
+ addl %r12d,%r10d
+ addb %bl,%cl
+ roll $15,%r10d
+ movl $-1,%r12d
+ pinsrw $7,(%rdi,%rax,4),%xmm0
+
+ addl %r11d,%r10d
+ movdqu 48(%r13),%xmm5
+ addb $32,%bpl
+ movl (%rdi,%rcx,4),%edx
+ xorl %r8d,%r12d
+ movl %ebx,(%rdi,%rcx,4)
+ orl %r10d,%r12d
+ addl 36(%r15),%r9d
+ addb %dl,%bl
+ movl 0(%rdi,%rbp,4),%eax
+ addl $3951481745,%r9d
+ movzbl %bl,%ebx
+ xorl %r11d,%r12d
+ movl %edx,124(%rsi)
+ addl %r12d,%r9d
+ addb %al,%cl
+ roll $21,%r9d
+ movl $-1,%r12d
+ pinsrw $7,(%rdi,%rbx,4),%xmm1
+
+ addl %r10d,%r9d
+ movq %rbp,%rsi
+ xorq %rbp,%rbp
+ movb %sil,%bpl
+ movq %rcx,%rsi
+ xorq %rcx,%rcx
+ movb %sil,%cl
+ leaq (%rdi,%rbp,4),%rsi
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm5
+ pxor %xmm1,%xmm5
+ addl 0(%rsp),%r8d
+ addl 4(%rsp),%r9d
+ addl 8(%rsp),%r10d
+ addl 12(%rsp),%r11d
+
+ movdqu %xmm2,(%r14,%r13,1)
+ movdqu %xmm3,16(%r14,%r13,1)
+ movdqu %xmm4,32(%r14,%r13,1)
+ movdqu %xmm5,48(%r14,%r13,1)
+ leaq 64(%r15),%r15
+ leaq 64(%r13),%r13
+ cmpq 16(%rsp),%r15
+ jb L$oop
+
+ movq 24(%rsp),%r12
+ subb %al,%cl
+ movl %r8d,0(%r12)
+ movl %r9d,4(%r12)
+ movl %r10d,8(%r12)
+ movl %r11d,12(%r12)
+ subb $1,%bpl
+ movl %ebp,-8(%rdi)
+ movl %ecx,-4(%rdi)
+
+ movq 40(%rsp),%r15
+ movq 48(%rsp),%r14
+ movq 56(%rsp),%r13
+ movq 64(%rsp),%r12
+ movq 72(%rsp),%rbp
+ movq 80(%rsp),%rbx
+ leaq 88(%rsp),%rsp
+L$epilogue:
+L$abort:
+ .byte 0xf3,0xc3
diff --git a/deps/openssl/asm/x64-macosx-gas/rc4/rc4-x86_64.s b/deps/openssl/asm/x64-macosx-gas/rc4/rc4-x86_64.s
index 41183cebe..8c4f29ecb 100644
--- a/deps/openssl/asm/x64-macosx-gas/rc4/rc4-x86_64.s
+++ b/deps/openssl/asm/x64-macosx-gas/rc4/rc4-x86_64.s
@@ -1,6 +1,7 @@
.text
+
.globl _RC4
.p2align 4
@@ -12,316 +13,511 @@ L$entry:
pushq %r12
pushq %r13
L$prologue:
+ movq %rsi,%r11
+ movq %rdx,%r12
+ movq %rcx,%r13
+ xorq %r10,%r10
+ xorq %rcx,%rcx
- addq $8,%rdi
- movl -8(%rdi),%r8d
- movl -4(%rdi),%r12d
+ leaq 8(%rdi),%rdi
+ movb -8(%rdi),%r10b
+ movb -4(%rdi),%cl
cmpl $-1,256(%rdi)
je L$RC4_CHAR
- incb %r8b
- movl (%rdi,%r8,4),%r9d
- testq $-8,%rsi
- jz L$loop1
- jmp L$loop8
-.p2align 4
-L$loop8:
- addb %r9b,%r12b
- movq %r8,%r10
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
- incb %r10b
- movl (%rdi,%r10,4),%r11d
- cmpq %r10,%r12
- movl %r9d,(%rdi,%r12,4)
- cmoveq %r9,%r11
- movl %r13d,(%rdi,%r8,4)
- addb %r9b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r11b,%r12b
- movq %r10,%r8
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
- incb %r8b
- movl (%rdi,%r8,4),%r9d
- cmpq %r8,%r12
- movl %r11d,(%rdi,%r12,4)
- cmoveq %r11,%r9
- movl %r13d,(%rdi,%r10,4)
- addb %r11b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r9b,%r12b
- movq %r8,%r10
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
+ movl _OPENSSL_ia32cap_P(%rip),%r8d
+ xorq %rbx,%rbx
incb %r10b
- movl (%rdi,%r10,4),%r11d
- cmpq %r10,%r12
- movl %r9d,(%rdi,%r12,4)
- cmoveq %r9,%r11
- movl %r13d,(%rdi,%r8,4)
- addb %r9b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r11b,%r12b
- movq %r10,%r8
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
- incb %r8b
- movl (%rdi,%r8,4),%r9d
- cmpq %r8,%r12
- movl %r11d,(%rdi,%r12,4)
- cmoveq %r11,%r9
- movl %r13d,(%rdi,%r10,4)
- addb %r11b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r9b,%r12b
- movq %r8,%r10
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
+ subq %r10,%rbx
+ subq %r12,%r13
+ movl (%rdi,%r10,4),%eax
+ testq $-16,%r11
+ jz L$loop1
+ btl $30,%r8d
+ jc L$intel
+ andq $7,%rbx
+ leaq 1(%r10),%rsi
+ jz L$oop8
+ subq %rbx,%r11
+L$oop8_warmup:
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl %edx,(%rdi,%r10,4)
+ addb %dl,%al
incb %r10b
- movl (%rdi,%r10,4),%r11d
- cmpq %r10,%r12
- movl %r9d,(%rdi,%r12,4)
- cmoveq %r9,%r11
- movl %r13d,(%rdi,%r8,4)
- addb %r9b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r11b,%r12b
- movq %r10,%r8
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
- incb %r8b
- movl (%rdi,%r8,4),%r9d
- cmpq %r8,%r12
- movl %r11d,(%rdi,%r12,4)
- cmoveq %r11,%r9
- movl %r13d,(%rdi,%r10,4)
- addb %r11b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r9b,%r12b
- movq %r8,%r10
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
+ movl (%rdi,%rax,4),%edx
+ movl (%rdi,%r10,4),%eax
+ xorb (%r12),%dl
+ movb %dl,(%r13,%r12,1)
+ leaq 1(%r12),%r12
+ decq %rbx
+ jnz L$oop8_warmup
+
+ leaq 1(%r10),%rsi
+ jmp L$oop8
+.p2align 4
+L$oop8:
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl 0(%rdi,%rsi,4),%ebx
+ rorq $8,%r8
+ movl %edx,0(%rdi,%r10,4)
+ addb %al,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %bl,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ movl 4(%rdi,%rsi,4),%eax
+ rorq $8,%r8
+ movl %edx,4(%rdi,%r10,4)
+ addb %bl,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl 8(%rdi,%rsi,4),%ebx
+ rorq $8,%r8
+ movl %edx,8(%rdi,%r10,4)
+ addb %al,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %bl,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ movl 12(%rdi,%rsi,4),%eax
+ rorq $8,%r8
+ movl %edx,12(%rdi,%r10,4)
+ addb %bl,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl 16(%rdi,%rsi,4),%ebx
+ rorq $8,%r8
+ movl %edx,16(%rdi,%r10,4)
+ addb %al,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %bl,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ movl 20(%rdi,%rsi,4),%eax
+ rorq $8,%r8
+ movl %edx,20(%rdi,%r10,4)
+ addb %bl,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl 24(%rdi,%rsi,4),%ebx
+ rorq $8,%r8
+ movl %edx,24(%rdi,%r10,4)
+ addb %al,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb $8,%sil
+ addb %bl,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ movl -4(%rdi,%rsi,4),%eax
+ rorq $8,%r8
+ movl %edx,28(%rdi,%r10,4)
+ addb %bl,%dl
+ movb (%rdi,%rdx,4),%r8b
+ addb $8,%r10b
+ rorq $8,%r8
+ subq $8,%r11
+
+ xorq (%r12),%r8
+ movq %r8,(%r13,%r12,1)
+ leaq 8(%r12),%r12
+
+ testq $-8,%r11
+ jnz L$oop8
+ cmpq $0,%r11
+ jne L$loop1
+ jmp L$exit
+
+.p2align 4
+L$intel:
+ testq $-32,%r11
+ jz L$loop1
+ andq $15,%rbx
+ jz L$oop16_is_hot
+ subq %rbx,%r11
+L$oop16_warmup:
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl %edx,(%rdi,%r10,4)
+ addb %dl,%al
incb %r10b
- movl (%rdi,%r10,4),%r11d
- cmpq %r10,%r12
- movl %r9d,(%rdi,%r12,4)
- cmoveq %r9,%r11
- movl %r13d,(%rdi,%r8,4)
- addb %r9b,%r13b
- movb (%rdi,%r13,4),%al
- addb %r11b,%r12b
- movq %r10,%r8
- movl (%rdi,%r12,4),%r13d
- rorq $8,%rax
- incb %r8b
- movl (%rdi,%r8,4),%r9d
- cmpq %r8,%r12
- movl %r11d,(%rdi,%r12,4)
- cmoveq %r11,%r9
- movl %r13d,(%rdi,%r10,4)
- addb %r11b,%r13b
- movb (%rdi,%r13,4),%al
- rorq $8,%rax
- subq $8,%rsi
-
- xorq (%rdx),%rax
- addq $8,%rdx
- movq %rax,(%rcx)
- addq $8,%rcx
-
- testq $-8,%rsi
- jnz L$loop8
- cmpq $0,%rsi
+ movl (%rdi,%rax,4),%edx
+ movl (%rdi,%r10,4),%eax
+ xorb (%r12),%dl
+ movb %dl,(%r13,%r12,1)
+ leaq 1(%r12),%r12
+ decq %rbx
+ jnz L$oop16_warmup
+
+ movq %rcx,%rbx
+ xorq %rcx,%rcx
+ movb %bl,%cl
+
+L$oop16_is_hot:
+ leaq (%rdi,%r10,4),%rsi
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ pxor %xmm0,%xmm0
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 4(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,0(%rsi)
+ addb %bl,%cl
+ pinsrw $0,(%rdi,%rax,4),%xmm0
+ jmp L$oop16_enter
+.p2align 4
+L$oop16:
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ pxor %xmm0,%xmm2
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm0
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 4(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,0(%rsi)
+ pxor %xmm1,%xmm2
+ addb %bl,%cl
+ pinsrw $0,(%rdi,%rax,4),%xmm0
+ movdqu %xmm2,(%r13,%r12,1)
+ leaq 16(%r12),%r12
+L$oop16_enter:
+ movl (%rdi,%rcx,4),%edx
+ pxor %xmm1,%xmm1
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 8(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,4(%rsi)
+ addb %al,%cl
+ pinsrw $0,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 12(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,8(%rsi)
+ addb %bl,%cl
+ pinsrw $1,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 16(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,12(%rsi)
+ addb %al,%cl
+ pinsrw $1,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 20(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,16(%rsi)
+ addb %bl,%cl
+ pinsrw $2,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 24(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,20(%rsi)
+ addb %al,%cl
+ pinsrw $2,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 28(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,24(%rsi)
+ addb %bl,%cl
+ pinsrw $3,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 32(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,28(%rsi)
+ addb %al,%cl
+ pinsrw $3,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 36(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,32(%rsi)
+ addb %bl,%cl
+ pinsrw $4,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 40(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,36(%rsi)
+ addb %al,%cl
+ pinsrw $4,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 44(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,40(%rsi)
+ addb %bl,%cl
+ pinsrw $5,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 48(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,44(%rsi)
+ addb %al,%cl
+ pinsrw $5,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 52(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,48(%rsi)
+ addb %bl,%cl
+ pinsrw $6,(%rdi,%rax,4),%xmm0
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movl 56(%rsi),%eax
+ movzbl %bl,%ebx
+ movl %edx,52(%rsi)
+ addb %al,%cl
+ pinsrw $6,(%rdi,%rbx,4),%xmm1
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ addb %dl,%al
+ movl 60(%rsi),%ebx
+ movzbl %al,%eax
+ movl %edx,56(%rsi)
+ addb %bl,%cl
+ pinsrw $7,(%rdi,%rax,4),%xmm0
+ addb $16,%r10b
+ movdqu (%r12),%xmm2
+ movl (%rdi,%rcx,4),%edx
+ movl %ebx,(%rdi,%rcx,4)
+ addb %dl,%bl
+ movzbl %bl,%ebx
+ movl %edx,60(%rsi)
+ leaq (%rdi,%r10,4),%rsi
+ pinsrw $7,(%rdi,%rbx,4),%xmm1
+ movl (%rsi),%eax
+ movq %rcx,%rbx
+ xorq %rcx,%rcx
+ subq $16,%r11
+ movb %bl,%cl
+ testq $-16,%r11
+ jnz L$oop16
+
+ psllq $8,%xmm1
+ pxor %xmm0,%xmm2
+ pxor %xmm1,%xmm2
+ movdqu %xmm2,(%r13,%r12,1)
+ leaq 16(%r12),%r12
+
+ cmpq $0,%r11
jne L$loop1
jmp L$exit
.p2align 4
L$loop1:
- addb %r9b,%r12b
- movl (%rdi,%r12,4),%r13d
- movl %r9d,(%rdi,%r12,4)
- movl %r13d,(%rdi,%r8,4)
- addb %r13b,%r9b
- incb %r8b
- movl (%rdi,%r9,4),%r13d
- movl (%rdi,%r8,4),%r9d
- xorb (%rdx),%r13b
- incq %rdx
- movb %r13b,(%rcx)
- incq %rcx
- decq %rsi
+ addb %al,%cl
+ movl (%rdi,%rcx,4),%edx
+ movl %eax,(%rdi,%rcx,4)
+ movl %edx,(%rdi,%r10,4)
+ addb %dl,%al
+ incb %r10b
+ movl (%rdi,%rax,4),%edx
+ movl (%rdi,%r10,4),%eax
+ xorb (%r12),%dl
+ movb %dl,(%r13,%r12,1)
+ leaq 1(%r12),%r12
+ decq %r11
jnz L$loop1
jmp L$exit
.p2align 4
L$RC4_CHAR:
- addb $1,%r8b
- movzbl (%rdi,%r8,1),%r9d
- testq $-8,%rsi
+ addb $1,%r10b
+ movzbl (%rdi,%r10,1),%eax
+ testq $-8,%r11
jz L$cloop1
- cmpl $0,260(%rdi)
- jnz L$cloop1
jmp L$cloop8
.p2align 4
L$cloop8:
- movl (%rdx),%eax
- movl 4(%rdx),%ebx
- addb %r9b,%r12b
- leaq 1(%r8),%r10
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%r11d
- movb %r9b,(%rdi,%r12,1)
- cmpq %r10,%r12
- movb %r13b,(%rdi,%r8,1)
+ movl (%r12),%r8d
+ movl 4(%r12),%r9d
+ addb %al,%cl
+ leaq 1(%r10),%rsi
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %sil,%esi
+ movzbl (%rdi,%rsi,1),%ebx
+ movb %al,(%rdi,%rcx,1)
+ cmpq %rsi,%rcx
+ movb %dl,(%rdi,%r10,1)
jne L$cmov0
- movq %r9,%r11
+ movq %rax,%rbx
L$cmov0:
- addb %r9b,%r13b
- xorb (%rdi,%r13,1),%al
- rorl $8,%eax
- addb %r11b,%r12b
- leaq 1(%r10),%r8
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r8b,%r8d
- movzbl (%rdi,%r8,1),%r9d
- movb %r11b,(%rdi,%r12,1)
- cmpq %r8,%r12
- movb %r13b,(%rdi,%r10,1)
+ addb %al,%dl
+ xorb (%rdi,%rdx,1),%r8b
+ rorl $8,%r8d
+ addb %bl,%cl
+ leaq 1(%rsi),%r10
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %r10b,%r10d
+ movzbl (%rdi,%r10,1),%eax
+ movb %bl,(%rdi,%rcx,1)
+ cmpq %r10,%rcx
+ movb %dl,(%rdi,%rsi,1)
jne L$cmov1
- movq %r11,%r9
+ movq %rbx,%rax
L$cmov1:
- addb %r11b,%r13b
- xorb (%rdi,%r13,1),%al
- rorl $8,%eax
- addb %r9b,%r12b
- leaq 1(%r8),%r10
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%r11d
- movb %r9b,(%rdi,%r12,1)
- cmpq %r10,%r12
- movb %r13b,(%rdi,%r8,1)
+ addb %bl,%dl
+ xorb (%rdi,%rdx,1),%r8b
+ rorl $8,%r8d
+ addb %al,%cl
+ leaq 1(%r10),%rsi
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %sil,%esi
+ movzbl (%rdi,%rsi,1),%ebx
+ movb %al,(%rdi,%rcx,1)
+ cmpq %rsi,%rcx
+ movb %dl,(%rdi,%r10,1)
jne L$cmov2
- movq %r9,%r11
+ movq %rax,%rbx
L$cmov2:
- addb %r9b,%r13b
- xorb (%rdi,%r13,1),%al
- rorl $8,%eax
- addb %r11b,%r12b
- leaq 1(%r10),%r8
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r8b,%r8d
- movzbl (%rdi,%r8,1),%r9d
- movb %r11b,(%rdi,%r12,1)
- cmpq %r8,%r12
- movb %r13b,(%rdi,%r10,1)
+ addb %al,%dl
+ xorb (%rdi,%rdx,1),%r8b
+ rorl $8,%r8d
+ addb %bl,%cl
+ leaq 1(%rsi),%r10
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %r10b,%r10d
+ movzbl (%rdi,%r10,1),%eax
+ movb %bl,(%rdi,%rcx,1)
+ cmpq %r10,%rcx
+ movb %dl,(%rdi,%rsi,1)
jne L$cmov3
- movq %r11,%r9
+ movq %rbx,%rax
L$cmov3:
- addb %r11b,%r13b
- xorb (%rdi,%r13,1),%al
- rorl $8,%eax
- addb %r9b,%r12b
- leaq 1(%r8),%r10
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%r11d
- movb %r9b,(%rdi,%r12,1)
- cmpq %r10,%r12
- movb %r13b,(%rdi,%r8,1)
+ addb %bl,%dl
+ xorb (%rdi,%rdx,1),%r8b
+ rorl $8,%r8d
+ addb %al,%cl
+ leaq 1(%r10),%rsi
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %sil,%esi
+ movzbl (%rdi,%rsi,1),%ebx
+ movb %al,(%rdi,%rcx,1)
+ cmpq %rsi,%rcx
+ movb %dl,(%rdi,%r10,1)
jne L$cmov4
- movq %r9,%r11
+ movq %rax,%rbx
L$cmov4:
- addb %r9b,%r13b
- xorb (%rdi,%r13,1),%bl
- rorl $8,%ebx
- addb %r11b,%r12b
- leaq 1(%r10),%r8
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r8b,%r8d
- movzbl (%rdi,%r8,1),%r9d
- movb %r11b,(%rdi,%r12,1)
- cmpq %r8,%r12
- movb %r13b,(%rdi,%r10,1)
+ addb %al,%dl
+ xorb (%rdi,%rdx,1),%r9b
+ rorl $8,%r9d
+ addb %bl,%cl
+ leaq 1(%rsi),%r10
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %r10b,%r10d
+ movzbl (%rdi,%r10,1),%eax
+ movb %bl,(%rdi,%rcx,1)
+ cmpq %r10,%rcx
+ movb %dl,(%rdi,%rsi,1)
jne L$cmov5
- movq %r11,%r9
+ movq %rbx,%rax
L$cmov5:
- addb %r11b,%r13b
- xorb (%rdi,%r13,1),%bl
- rorl $8,%ebx
- addb %r9b,%r12b
- leaq 1(%r8),%r10
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%r11d
- movb %r9b,(%rdi,%r12,1)
- cmpq %r10,%r12
- movb %r13b,(%rdi,%r8,1)
+ addb %bl,%dl
+ xorb (%rdi,%rdx,1),%r9b
+ rorl $8,%r9d
+ addb %al,%cl
+ leaq 1(%r10),%rsi
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %sil,%esi
+ movzbl (%rdi,%rsi,1),%ebx
+ movb %al,(%rdi,%rcx,1)
+ cmpq %rsi,%rcx
+ movb %dl,(%rdi,%r10,1)
jne L$cmov6
- movq %r9,%r11
+ movq %rax,%rbx
L$cmov6:
- addb %r9b,%r13b
- xorb (%rdi,%r13,1),%bl
- rorl $8,%ebx
- addb %r11b,%r12b
- leaq 1(%r10),%r8
- movzbl (%rdi,%r12,1),%r13d
- movzbl %r8b,%r8d
- movzbl (%rdi,%r8,1),%r9d
- movb %r11b,(%rdi,%r12,1)
- cmpq %r8,%r12
- movb %r13b,(%rdi,%r10,1)
+ addb %al,%dl
+ xorb (%rdi,%rdx,1),%r9b
+ rorl $8,%r9d
+ addb %bl,%cl
+ leaq 1(%rsi),%r10
+ movzbl (%rdi,%rcx,1),%edx
+ movzbl %r10b,%r10d
+ movzbl (%rdi,%r10,1),%eax
+ movb %bl,(%rdi,%rcx,1)
+ cmpq %r10,%rcx
+ movb %dl,(%rdi,%rsi,1)
jne L$cmov7
- movq %r11,%r9
+ movq %rbx,%rax
L$cmov7:
- addb %r11b,%r13b
- xorb (%rdi,%r13,1),%bl
- rorl $8,%ebx
- leaq -8(%rsi),%rsi
- movl %eax,(%rcx)
- leaq 8(%rdx),%rdx
- movl %ebx,4(%rcx)
- leaq 8(%rcx),%rcx
-
- testq $-8,%rsi
+ addb %bl,%dl
+ xorb (%rdi,%rdx,1),%r9b
+ rorl $8,%r9d
+ leaq -8(%r11),%r11
+ movl %r8d,(%r13)
+ leaq 8(%r12),%r12
+ movl %r9d,4(%r13)
+ leaq 8(%r13),%r13
+
+ testq $-8,%r11
jnz L$cloop8
- cmpq $0,%rsi
+ cmpq $0,%r11
jne L$cloop1
jmp L$exit
.p2align 4
L$cloop1:
- addb %r9b,%r12b
- movzbl (%rdi,%r12,1),%r13d
- movb %r9b,(%rdi,%r12,1)
- movb %r13b,(%rdi,%r8,1)
- addb %r9b,%r13b
- addb $1,%r8b
- movzbl %r13b,%r13d
- movzbl %r8b,%r8d
- movzbl (%rdi,%r13,1),%r13d
- movzbl (%rdi,%r8,1),%r9d
- xorb (%rdx),%r13b
- leaq 1(%rdx),%rdx
- movb %r13b,(%rcx)
- leaq 1(%rcx),%rcx
- subq $1,%rsi
+ addb %al,%cl
+ movzbl %cl,%ecx
+ movzbl (%rdi,%rcx,1),%edx
+ movb %al,(%rdi,%rcx,1)
+ movb %dl,(%rdi,%r10,1)
+ addb %al,%dl
+ addb $1,%r10b
+ movzbl %dl,%edx
+ movzbl %r10b,%r10d
+ movzbl (%rdi,%rdx,1),%edx
+ movzbl (%rdi,%r10,1),%eax
+ xorb (%r12),%dl
+ leaq 1(%r12),%r12
+ movb %dl,(%r13)
+ leaq 1(%r13),%r13
+ subq $1,%r11
jnz L$cloop1
jmp L$exit
.p2align 4
L$exit:
- subb $1,%r8b
- movl %r8d,-8(%rdi)
- movl %r12d,-4(%rdi)
+ subb $1,%r10b
+ movl %r10d,-8(%rdi)
+ movl %ecx,-4(%rdi)
movq (%rsp),%r13
movq 8(%rsp),%r12
@@ -330,11 +526,10 @@ L$exit:
L$epilogue:
.byte 0xf3,0xc3
-
-.globl _RC4_set_key
+.globl _private_RC4_set_key
.p2align 4
-_RC4_set_key:
+_private_RC4_set_key:
leaq 8(%rdi),%rdi
leaq (%rdx,%rsi,1),%rdx
negq %rsi
@@ -346,11 +541,8 @@ _RC4_set_key:
movl _OPENSSL_ia32cap_P(%rip),%r8d
btl $20,%r8d
- jnc L$w1stloop
- btl $30,%r8d
- setc %r9b
- movl %r9d,260(%rdi)
- jmp L$c1stloop
+ jc L$c1stloop
+ jmp L$w1stloop
.p2align 4
L$w1stloop:
@@ -413,18 +605,19 @@ _RC4_options:
leaq L$opts(%rip),%rax
movl _OPENSSL_ia32cap_P(%rip),%edx
btl $20,%edx
- jnc L$done
- addq $12,%rax
+ jc L$8xchar
btl $30,%edx
jnc L$done
- addq $13,%rax
+ addq $25,%rax
+ .byte 0xf3,0xc3
+L$8xchar:
+ addq $12,%rax
L$done:
.byte 0xf3,0xc3
.p2align 6
L$opts:
.byte 114,99,52,40,56,120,44,105,110,116,41,0
.byte 114,99,52,40,56,120,44,99,104,97,114,41,0
-.byte 114,99,52,40,49,120,44,99,104,97,114,41,0
+.byte 114,99,52,40,49,54,120,44,105,110,116,41,0
.byte 82,67,52,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.p2align 6
-
diff --git a/deps/openssl/asm/x64-macosx-gas/sha/sha1-x86_64.s b/deps/openssl/asm/x64-macosx-gas/sha/sha1-x86_64.s
index f9dc2568e..9bb9bf0f2 100644
--- a/deps/openssl/asm/x64-macosx-gas/sha/sha1-x86_64.s
+++ b/deps/openssl/asm/x64-macosx-gas/sha/sha1-x86_64.s
@@ -1,12 +1,23 @@
.text
+
+
.globl _sha1_block_data_order
.p2align 4
_sha1_block_data_order:
+ movl _OPENSSL_ia32cap_P+0(%rip),%r9d
+ movl _OPENSSL_ia32cap_P+4(%rip),%r8d
+ testl $512,%r8d
+ jz L$ialu
+ jmp _ssse3_shortcut
+
+.p2align 4
+L$ialu:
pushq %rbx
pushq %rbp
pushq %r12
+ pushq %r13
movq %rsp,%r11
movq %rdi,%r8
subq $72,%rsp
@@ -16,1268 +27,2466 @@ _sha1_block_data_order:
movq %r11,64(%rsp)
L$prologue:
- movl 0(%r8),%edx
- movl 4(%r8),%esi
- movl 8(%r8),%edi
- movl 12(%r8),%ebp
- movl 16(%r8),%r11d
-.p2align 2
+ movl 0(%r8),%esi
+ movl 4(%r8),%edi
+ movl 8(%r8),%r11d
+ movl 12(%r8),%r12d
+ movl 16(%r8),%r13d
+ jmp L$loop
+
+.p2align 4
L$loop:
- movl 0(%r9),%eax
- bswapl %eax
- movl %eax,0(%rsp)
- leal 1518500249(%rax,%r11,1),%r12d
- movl %edi,%ebx
- movl 4(%r9),%eax
- movl %edx,%r11d
- xorl %ebp,%ebx
- bswapl %eax
- roll $5,%r11d
- andl %esi,%ebx
- movl %eax,4(%rsp)
- addl %r11d,%r12d
- xorl %ebp,%ebx
+ movl 0(%r9),%edx
+ bswapl %edx
+ movl %edx,0(%rsp)
+ movl %r11d,%eax
+ movl 4(%r9),%ebp
+ movl %esi,%ecx
+ xorl %r12d,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%r13,1),%r13d
+ andl %edi,%eax
+ movl %ebp,4(%rsp)
+ addl %ecx,%r13d
+ xorl %r12d,%eax
+ roll $30,%edi
+ addl %eax,%r13d
+ movl %edi,%eax
+ movl 8(%r9),%edx
+ movl %r13d,%ecx
+ xorl %r11d,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%r12,1),%r12d
+ andl %esi,%eax
+ movl %edx,8(%rsp)
+ addl %ecx,%r12d
+ xorl %r11d,%eax
roll $30,%esi
- addl %ebx,%r12d
- leal 1518500249(%rax,%rbp,1),%r11d
- movl %esi,%ebx
- movl 8(%r9),%eax
- movl %r12d,%ebp
- xorl %edi,%ebx
- bswapl %eax
- roll $5,%ebp
- andl %edx,%ebx
- movl %eax,8(%rsp)
- addl %ebp,%r11d
- xorl %edi,%ebx
- roll $30,%edx
- addl %ebx,%r11d
- leal 1518500249(%rax,%rdi,1),%ebp
- movl %edx,%ebx
- movl 12(%r9),%eax
- movl %r11d,%edi
- xorl %esi,%ebx
- bswapl %eax
- roll $5,%edi
- andl %r12d,%ebx
- movl %eax,12(%rsp)
- addl %edi,%ebp
- xorl %esi,%ebx
+ addl %eax,%r12d
+ movl %esi,%eax
+ movl 12(%r9),%ebp
+ movl %r12d,%ecx
+ xorl %edi,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%r11,1),%r11d
+ andl %r13d,%eax
+ movl %ebp,12(%rsp)
+ addl %ecx,%r11d
+ xorl %edi,%eax
+ roll $30,%r13d
+ addl %eax,%r11d
+ movl %r13d,%eax
+ movl 16(%r9),%edx
+ movl %r11d,%ecx
+ xorl %esi,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%rdi,1),%edi
+ andl %r12d,%eax
+ movl %edx,16(%rsp)
+ addl %ecx,%edi
+ xorl %esi,%eax
roll $30,%r12d
- addl %ebx,%ebp
- leal 1518500249(%rax,%rsi,1),%edi
- movl %r12d,%ebx
- movl 16(%r9),%eax
- movl %ebp,%esi
- xorl %edx,%ebx
- bswapl %eax
- roll $5,%esi
- andl %r11d,%ebx
- movl %eax,16(%rsp)
- addl %esi,%edi
- xorl %edx,%ebx
+ addl %eax,%edi
+ movl %r12d,%eax
+ movl 20(%r9),%ebp
+ movl %edi,%ecx
+ xorl %r13d,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%rsi,1),%esi
+ andl %r11d,%eax
+ movl %ebp,20(%rsp)
+ addl %ecx,%esi
+ xorl %r13d,%eax
roll $30,%r11d
- addl %ebx,%edi
- leal 1518500249(%rax,%rdx,1),%esi
+ addl %eax,%esi
+ movl %r11d,%eax
+ movl 24(%r9),%edx
+ movl %esi,%ecx
+ xorl %r12d,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%r13,1),%r13d
+ andl %edi,%eax
+ movl %edx,24(%rsp)
+ addl %ecx,%r13d
+ xorl %r12d,%eax
+ roll $30,%edi
+ addl %eax,%r13d
+ movl %edi,%eax
+ movl 28(%r9),%ebp
+ movl %r13d,%ecx
+ xorl %r11d,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%r12,1),%r12d
+ andl %esi,%eax
+ movl %ebp,28(%rsp)
+ addl %ecx,%r12d
+ xorl %r11d,%eax
+ roll $30,%esi
+ addl %eax,%r12d
+ movl %esi,%eax
+ movl 32(%r9),%edx
+ movl %r12d,%ecx
+ xorl %edi,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%r11,1),%r11d
+ andl %r13d,%eax
+ movl %edx,32(%rsp)
+ addl %ecx,%r11d
+ xorl %edi,%eax
+ roll $30,%r13d
+ addl %eax,%r11d
+ movl %r13d,%eax
+ movl 36(%r9),%ebp
+ movl %r11d,%ecx
+ xorl %esi,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%rdi,1),%edi
+ andl %r12d,%eax
+ movl %ebp,36(%rsp)
+ addl %ecx,%edi
+ xorl %esi,%eax
+ roll $30,%r12d
+ addl %eax,%edi
+ movl %r12d,%eax
+ movl 40(%r9),%edx
+ movl %edi,%ecx
+ xorl %r13d,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%rsi,1),%esi
+ andl %r11d,%eax
+ movl %edx,40(%rsp)
+ addl %ecx,%esi
+ xorl %r13d,%eax
+ roll $30,%r11d
+ addl %eax,%esi
+ movl %r11d,%eax
+ movl 44(%r9),%ebp
+ movl %esi,%ecx
+ xorl %r12d,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%r13,1),%r13d
+ andl %edi,%eax
+ movl %ebp,44(%rsp)
+ addl %ecx,%r13d
+ xorl %r12d,%eax
+ roll $30,%edi
+ addl %eax,%r13d
+ movl %edi,%eax
+ movl 48(%r9),%edx
+ movl %r13d,%ecx
+ xorl %r11d,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%r12,1),%r12d
+ andl %esi,%eax
+ movl %edx,48(%rsp)
+ addl %ecx,%r12d
+ xorl %r11d,%eax
+ roll $30,%esi
+ addl %eax,%r12d
+ movl %esi,%eax
+ movl 52(%r9),%ebp
+ movl %r12d,%ecx
+ xorl %edi,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%r11,1),%r11d
+ andl %r13d,%eax
+ movl %ebp,52(%rsp)
+ addl %ecx,%r11d
+ xorl %edi,%eax
+ roll $30,%r13d
+ addl %eax,%r11d
+ movl %r13d,%eax
+ movl 56(%r9),%edx
+ movl %r11d,%ecx
+ xorl %esi,%eax
+ bswapl %edx
+ roll $5,%ecx
+ leal 1518500249(%rbp,%rdi,1),%edi
+ andl %r12d,%eax
+ movl %edx,56(%rsp)
+ addl %ecx,%edi
+ xorl %esi,%eax
+ roll $30,%r12d
+ addl %eax,%edi
+ movl %r12d,%eax
+ movl 60(%r9),%ebp
+ movl %edi,%ecx
+ xorl %r13d,%eax
+ bswapl %ebp
+ roll $5,%ecx
+ leal 1518500249(%rdx,%rsi,1),%esi
+ andl %r11d,%eax
+ movl %ebp,60(%rsp)
+ addl %ecx,%esi
+ xorl %r13d,%eax
+ roll $30,%r11d
+ addl %eax,%esi
+ movl 0(%rsp),%edx
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 8(%rsp),%edx
+ xorl %r12d,%eax
+ roll $5,%ecx
+ xorl 32(%rsp),%edx
+ andl %edi,%eax
+ leal 1518500249(%rbp,%r13,1),%r13d
+ xorl 52(%rsp),%edx
+ xorl %r12d,%eax
+ roll $1,%edx
+ addl %ecx,%r13d
+ roll $30,%edi
+ movl %edx,0(%rsp)
+ addl %eax,%r13d
+ movl 4(%rsp),%ebp
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 12(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $5,%ecx
+ xorl 36(%rsp),%ebp
+ andl %esi,%eax
+ leal 1518500249(%rdx,%r12,1),%r12d
+ xorl 56(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $1,%ebp
+ addl %ecx,%r12d
+ roll $30,%esi
+ movl %ebp,4(%rsp)
+ addl %eax,%r12d
+ movl 8(%rsp),%edx
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 16(%rsp),%edx
+ xorl %edi,%eax
+ roll $5,%ecx
+ xorl 40(%rsp),%edx
+ andl %r13d,%eax
+ leal 1518500249(%rbp,%r11,1),%r11d
+ xorl 60(%rsp),%edx
+ xorl %edi,%eax
+ roll $1,%edx
+ addl %ecx,%r11d
+ roll $30,%r13d
+ movl %edx,8(%rsp)
+ addl %eax,%r11d
+ movl 12(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 20(%rsp),%ebp
+ xorl %esi,%eax
+ roll $5,%ecx
+ xorl 44(%rsp),%ebp
+ andl %r12d,%eax
+ leal 1518500249(%rdx,%rdi,1),%edi
+ xorl 0(%rsp),%ebp
+ xorl %esi,%eax
+ roll $1,%ebp
+ addl %ecx,%edi
+ roll $30,%r12d
+ movl %ebp,12(%rsp)
+ addl %eax,%edi
+ movl 16(%rsp),%edx
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 24(%rsp),%edx
+ xorl %r13d,%eax
+ roll $5,%ecx
+ xorl 48(%rsp),%edx
+ andl %r11d,%eax
+ leal 1518500249(%rbp,%rsi,1),%esi
+ xorl 4(%rsp),%edx
+ xorl %r13d,%eax
+ roll $1,%edx
+ addl %ecx,%esi
+ roll $30,%r11d
+ movl %edx,16(%rsp)
+ addl %eax,%esi
+ movl 20(%rsp),%ebp
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 28(%rsp),%ebp
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r13,1),%r13d
+ xorl 52(%rsp),%ebp
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 8(%rsp),%ebp
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%ebp
+ movl %ebp,20(%rsp)
+ movl 24(%rsp),%edx
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 32(%rsp),%edx
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r12,1),%r12d
+ xorl 56(%rsp),%edx
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 12(%rsp),%edx
+ roll $30,%esi
+ addl %eax,%r12d
+ roll $1,%edx
+ movl %edx,24(%rsp)
+ movl 28(%rsp),%ebp
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 36(%rsp),%ebp
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r11,1),%r11d
+ xorl 60(%rsp),%ebp
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 16(%rsp),%ebp
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%ebp
+ movl %ebp,28(%rsp)
+ movl 32(%rsp),%edx
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 40(%rsp),%edx
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%rdi,1),%edi
+ xorl 0(%rsp),%edx
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 20(%rsp),%edx
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%edx
+ movl %edx,32(%rsp)
+ movl 36(%rsp),%ebp
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 44(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%rsi,1),%esi
+ xorl 4(%rsp),%ebp
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 24(%rsp),%ebp
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%ebp
+ movl %ebp,36(%rsp)
+ movl 40(%rsp),%edx
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 48(%rsp),%edx
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r13,1),%r13d
+ xorl 8(%rsp),%edx
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 28(%rsp),%edx
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%edx
+ movl %edx,40(%rsp)
+ movl 44(%rsp),%ebp
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 52(%rsp),%ebp
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r12,1),%r12d
+ xorl 12(%rsp),%ebp
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 32(%rsp),%ebp
+ roll $30,%esi
+ addl %eax,%r12d
+ roll $1,%ebp
+ movl %ebp,44(%rsp)
+ movl 48(%rsp),%edx
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 56(%rsp),%edx
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r11,1),%r11d
+ xorl 16(%rsp),%edx
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 36(%rsp),%edx
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%edx
+ movl %edx,48(%rsp)
+ movl 52(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 60(%rsp),%ebp
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%rdi,1),%edi
+ xorl 20(%rsp),%ebp
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 40(%rsp),%ebp
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%ebp
+ movl %ebp,52(%rsp)
+ movl 56(%rsp),%edx
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 0(%rsp),%edx
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%rsi,1),%esi
+ xorl 24(%rsp),%edx
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 44(%rsp),%edx
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%edx
+ movl %edx,56(%rsp)
+ movl 60(%rsp),%ebp
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 4(%rsp),%ebp
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r13,1),%r13d
+ xorl 28(%rsp),%ebp
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 48(%rsp),%ebp
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%ebp
+ movl %ebp,60(%rsp)
+ movl 0(%rsp),%edx
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 8(%rsp),%edx
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r12,1),%r12d
+ xorl 32(%rsp),%edx
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 52(%rsp),%edx
+ roll $30,%esi
+ addl %eax,%r12d
+ roll $1,%edx
+ movl %edx,0(%rsp)
+ movl 4(%rsp),%ebp
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 12(%rsp),%ebp
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r11,1),%r11d
+ xorl 36(%rsp),%ebp
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 56(%rsp),%ebp
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%ebp
+ movl %ebp,4(%rsp)
+ movl 8(%rsp),%edx
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 16(%rsp),%edx
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%rdi,1),%edi
+ xorl 40(%rsp),%edx
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 60(%rsp),%edx
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%edx
+ movl %edx,8(%rsp)
+ movl 12(%rsp),%ebp
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 20(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%rsi,1),%esi
+ xorl 44(%rsp),%ebp
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 0(%rsp),%ebp
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%ebp
+ movl %ebp,12(%rsp)
+ movl 16(%rsp),%edx
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 24(%rsp),%edx
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r13,1),%r13d
+ xorl 48(%rsp),%edx
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 4(%rsp),%edx
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%edx
+ movl %edx,16(%rsp)
+ movl 20(%rsp),%ebp
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 28(%rsp),%ebp
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%r12,1),%r12d
+ xorl 52(%rsp),%ebp
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 8(%rsp),%ebp
+ roll $30,%esi
+ addl %eax,%r12d
+ roll $1,%ebp
+ movl %ebp,20(%rsp)
+ movl 24(%rsp),%edx
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 32(%rsp),%edx
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%r11,1),%r11d
+ xorl 56(%rsp),%edx
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 12(%rsp),%edx
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%edx
+ movl %edx,24(%rsp)
+ movl 28(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 36(%rsp),%ebp
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rdx,%rdi,1),%edi
+ xorl 60(%rsp),%ebp
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 16(%rsp),%ebp
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%ebp
+ movl %ebp,28(%rsp)
+ movl 32(%rsp),%edx
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 40(%rsp),%edx
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal 1859775393(%rbp,%rsi,1),%esi
+ xorl 0(%rsp),%edx
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 20(%rsp),%edx
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%edx
+ movl %edx,32(%rsp)
+ movl 36(%rsp),%ebp
+ movl %r11d,%eax
movl %r11d,%ebx
- movl 20(%r9),%eax
- movl %edi,%edx
- xorl %r12d,%ebx
- bswapl %eax
- roll $5,%edx
- andl %ebp,%ebx
- movl %eax,20(%rsp)
- addl %edx,%esi
+ xorl 44(%rsp),%ebp
+ andl %r12d,%eax
+ movl %esi,%ecx
+ xorl 4(%rsp),%ebp
xorl %r12d,%ebx
- roll $30,%ebp
- addl %ebx,%esi
- leal 1518500249(%rax,%r12,1),%edx
- movl %ebp,%ebx
- movl 24(%r9),%eax
- movl %esi,%r12d
- xorl %r11d,%ebx
- bswapl %eax
- roll $5,%r12d
+ leal -1894007588(%rdx,%r13,1),%r13d
+ roll $5,%ecx
+ xorl 24(%rsp),%ebp
+ addl %eax,%r13d
andl %edi,%ebx
- movl %eax,24(%rsp)
- addl %r12d,%edx
- xorl %r11d,%ebx
+ roll $1,%ebp
+ addl %ebx,%r13d
roll $30,%edi
- addl %ebx,%edx
- leal 1518500249(%rax,%r11,1),%r12d
+ movl %ebp,36(%rsp)
+ addl %ecx,%r13d
+ movl 40(%rsp),%edx
+ movl %edi,%eax
movl %edi,%ebx
- movl 28(%r9),%eax
- movl %edx,%r11d
- xorl %ebp,%ebx
- bswapl %eax
- roll $5,%r11d
+ xorl 48(%rsp),%edx
+ andl %r11d,%eax
+ movl %r13d,%ecx
+ xorl 8(%rsp),%edx
+ xorl %r11d,%ebx
+ leal -1894007588(%rbp,%r12,1),%r12d
+ roll $5,%ecx
+ xorl 28(%rsp),%edx
+ addl %eax,%r12d
andl %esi,%ebx
- movl %eax,28(%rsp)
- addl %r11d,%r12d
- xorl %ebp,%ebx
- roll $30,%esi
+ roll $1,%edx
addl %ebx,%r12d
- leal 1518500249(%rax,%rbp,1),%r11d
+ roll $30,%esi
+ movl %edx,40(%rsp)
+ addl %ecx,%r12d
+ movl 44(%rsp),%ebp
+ movl %esi,%eax
movl %esi,%ebx
- movl 32(%r9),%eax
- movl %r12d,%ebp
- xorl %edi,%ebx
- bswapl %eax
- roll $5,%ebp
- andl %edx,%ebx
- movl %eax,32(%rsp)
- addl %ebp,%r11d
+ xorl 52(%rsp),%ebp
+ andl %edi,%eax
+ movl %r12d,%ecx
+ xorl 12(%rsp),%ebp
xorl %edi,%ebx
- roll $30,%edx
+ leal -1894007588(%rdx,%r11,1),%r11d
+ roll $5,%ecx
+ xorl 32(%rsp),%ebp
+ addl %eax,%r11d
+ andl %r13d,%ebx
+ roll $1,%ebp
addl %ebx,%r11d
- leal 1518500249(%rax,%rdi,1),%ebp
- movl %edx,%ebx
- movl 36(%r9),%eax
- movl %r11d,%edi
+ roll $30,%r13d
+ movl %ebp,44(%rsp)
+ addl %ecx,%r11d
+ movl 48(%rsp),%edx
+ movl %r13d,%eax
+ movl %r13d,%ebx
+ xorl 56(%rsp),%edx
+ andl %esi,%eax
+ movl %r11d,%ecx
+ xorl 16(%rsp),%edx
xorl %esi,%ebx
- bswapl %eax
- roll $5,%edi
+ leal -1894007588(%rbp,%rdi,1),%edi
+ roll $5,%ecx
+ xorl 36(%rsp),%edx
+ addl %eax,%edi
andl %r12d,%ebx
- movl %eax,36(%rsp)
- addl %edi,%ebp
- xorl %esi,%ebx
+ roll $1,%edx
+ addl %ebx,%edi
roll $30,%r12d
- addl %ebx,%ebp
- leal 1518500249(%rax,%rsi,1),%edi
+ movl %edx,48(%rsp)
+ addl %ecx,%edi
+ movl 52(%rsp),%ebp
+ movl %r12d,%eax
movl %r12d,%ebx
- movl 40(%r9),%eax
- movl %ebp,%esi
- xorl %edx,%ebx
- bswapl %eax
- roll $5,%esi
+ xorl 60(%rsp),%ebp
+ andl %r13d,%eax
+ movl %edi,%ecx
+ xorl 20(%rsp),%ebp
+ xorl %r13d,%ebx
+ leal -1894007588(%rdx,%rsi,1),%esi
+ roll $5,%ecx
+ xorl 40(%rsp),%ebp
+ addl %eax,%esi
andl %r11d,%ebx
- movl %eax,40(%rsp)
- addl %esi,%edi
- xorl %edx,%ebx
+ roll $1,%ebp
+ addl %ebx,%esi
roll $30,%r11d
- addl %ebx,%edi
- leal 1518500249(%rax,%rdx,1),%esi
+ movl %ebp,52(%rsp)
+ addl %ecx,%esi
+ movl 56(%rsp),%edx
+ movl %r11d,%eax
movl %r11d,%ebx
- movl 44(%r9),%eax
- movl %edi,%edx
- xorl %r12d,%ebx
- bswapl %eax
- roll $5,%edx
- andl %ebp,%ebx
- movl %eax,44(%rsp)
- addl %edx,%esi
+ xorl 0(%rsp),%edx
+ andl %r12d,%eax
+ movl %esi,%ecx
+ xorl 24(%rsp),%edx
xorl %r12d,%ebx
- roll $30,%ebp
- addl %ebx,%esi
- leal 1518500249(%rax,%r12,1),%edx
- movl %ebp,%ebx
- movl 48(%r9),%eax
- movl %esi,%r12d
- xorl %r11d,%ebx
- bswapl %eax
- roll $5,%r12d
+ leal -1894007588(%rbp,%r13,1),%r13d
+ roll $5,%ecx
+ xorl 44(%rsp),%edx
+ addl %eax,%r13d
andl %edi,%ebx
- movl %eax,48(%rsp)
- addl %r12d,%edx
- xorl %r11d,%ebx
+ roll $1,%edx
+ addl %ebx,%r13d
roll $30,%edi
- addl %ebx,%edx
- leal 1518500249(%rax,%r11,1),%r12d
+ movl %edx,56(%rsp)
+ addl %ecx,%r13d
+ movl 60(%rsp),%ebp
+ movl %edi,%eax
movl %edi,%ebx
- movl 52(%r9),%eax
- movl %edx,%r11d
- xorl %ebp,%ebx
- bswapl %eax
- roll $5,%r11d
+ xorl 4(%rsp),%ebp
+ andl %r11d,%eax
+ movl %r13d,%ecx
+ xorl 28(%rsp),%ebp
+ xorl %r11d,%ebx
+ leal -1894007588(%rdx,%r12,1),%r12d
+ roll $5,%ecx
+ xorl 48(%rsp),%ebp
+ addl %eax,%r12d
andl %esi,%ebx
- movl %eax,52(%rsp)
- addl %r11d,%r12d
- xorl %ebp,%ebx
- roll $30,%esi
+ roll $1,%ebp
addl %ebx,%r12d
- leal 1518500249(%rax,%rbp,1),%r11d
+ roll $30,%esi
+ movl %ebp,60(%rsp)
+ addl %ecx,%r12d
+ movl 0(%rsp),%edx
+ movl %esi,%eax
movl %esi,%ebx
- movl 56(%r9),%eax
- movl %r12d,%ebp
- xorl %edi,%ebx
- bswapl %eax
- roll $5,%ebp
- andl %edx,%ebx
- movl %eax,56(%rsp)
- addl %ebp,%r11d
+ xorl 8(%rsp),%edx
+ andl %edi,%eax
+ movl %r12d,%ecx
+ xorl 32(%rsp),%edx
xorl %edi,%ebx
- roll $30,%edx
+ leal -1894007588(%rbp,%r11,1),%r11d
+ roll $5,%ecx
+ xorl 52(%rsp),%edx
+ addl %eax,%r11d
+ andl %r13d,%ebx
+ roll $1,%edx
addl %ebx,%r11d
- leal 1518500249(%rax,%rdi,1),%ebp
- movl %edx,%ebx
- movl 60(%r9),%eax
- movl %r11d,%edi
+ roll $30,%r13d
+ movl %edx,0(%rsp)
+ addl %ecx,%r11d
+ movl 4(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r13d,%ebx
+ xorl 12(%rsp),%ebp
+ andl %esi,%eax
+ movl %r11d,%ecx
+ xorl 36(%rsp),%ebp
xorl %esi,%ebx
- bswapl %eax
- roll $5,%edi
+ leal -1894007588(%rdx,%rdi,1),%edi
+ roll $5,%ecx
+ xorl 56(%rsp),%ebp
+ addl %eax,%edi
andl %r12d,%ebx
- movl %eax,60(%rsp)
- addl %edi,%ebp
- xorl %esi,%ebx
+ roll $1,%ebp
+ addl %ebx,%edi
roll $30,%r12d
- addl %ebx,%ebp
- leal 1518500249(%rax,%rsi,1),%edi
- movl 0(%rsp),%eax
+ movl %ebp,4(%rsp)
+ addl %ecx,%edi
+ movl 8(%rsp),%edx
+ movl %r12d,%eax
movl %r12d,%ebx
- movl %ebp,%esi
- xorl 8(%rsp),%eax
- xorl %edx,%ebx
- roll $5,%esi
- xorl 32(%rsp),%eax
+ xorl 16(%rsp),%edx
+ andl %r13d,%eax
+ movl %edi,%ecx
+ xorl 40(%rsp),%edx
+ xorl %r13d,%ebx
+ leal -1894007588(%rbp,%rsi,1),%esi
+ roll $5,%ecx
+ xorl 60(%rsp),%edx
+ addl %eax,%esi
andl %r11d,%ebx
- addl %esi,%edi
- xorl 52(%rsp),%eax
- xorl %edx,%ebx
+ roll $1,%edx
+ addl %ebx,%esi
roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,0(%rsp)
- leal 1518500249(%rax,%rdx,1),%esi
- movl 4(%rsp),%eax
+ movl %edx,8(%rsp)
+ addl %ecx,%esi
+ movl 12(%rsp),%ebp
+ movl %r11d,%eax
movl %r11d,%ebx
- movl %edi,%edx
- xorl 12(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edx
- xorl 36(%rsp),%eax
- andl %ebp,%ebx
- addl %edx,%esi
- xorl 56(%rsp),%eax
+ xorl 20(%rsp),%ebp
+ andl %r12d,%eax
+ movl %esi,%ecx
+ xorl 44(%rsp),%ebp
xorl %r12d,%ebx
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- movl %eax,4(%rsp)
- leal 1518500249(%rax,%r12,1),%edx
- movl 8(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 16(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%r12d
- xorl 40(%rsp),%eax
+ leal -1894007588(%rdx,%r13,1),%r13d
+ roll $5,%ecx
+ xorl 0(%rsp),%ebp
+ addl %eax,%r13d
andl %edi,%ebx
- addl %r12d,%edx
- xorl 60(%rsp),%eax
- xorl %r11d,%ebx
+ roll $1,%ebp
+ addl %ebx,%r13d
roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,8(%rsp)
- leal 1518500249(%rax,%r11,1),%r12d
- movl 12(%rsp),%eax
+ movl %ebp,12(%rsp)
+ addl %ecx,%r13d
+ movl 16(%rsp),%edx
+ movl %edi,%eax
movl %edi,%ebx
- movl %edx,%r11d
- xorl 20(%rsp),%eax
- xorl %ebp,%ebx
- roll $5,%r11d
- xorl 44(%rsp),%eax
+ xorl 24(%rsp),%edx
+ andl %r11d,%eax
+ movl %r13d,%ecx
+ xorl 48(%rsp),%edx
+ xorl %r11d,%ebx
+ leal -1894007588(%rbp,%r12,1),%r12d
+ roll $5,%ecx
+ xorl 4(%rsp),%edx
+ addl %eax,%r12d
andl %esi,%ebx
- addl %r11d,%r12d
- xorl 0(%rsp),%eax
- xorl %ebp,%ebx
- roll $30,%esi
+ roll $1,%edx
addl %ebx,%r12d
- roll $1,%eax
- movl %eax,12(%rsp)
- leal 1518500249(%rax,%rbp,1),%r11d
- movl 16(%rsp),%eax
+ roll $30,%esi
+ movl %edx,16(%rsp)
+ addl %ecx,%r12d
+ movl 20(%rsp),%ebp
+ movl %esi,%eax
movl %esi,%ebx
- movl %r12d,%ebp
- xorl 24(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%ebp
- xorl 48(%rsp),%eax
- andl %edx,%ebx
- addl %ebp,%r11d
- xorl 4(%rsp),%eax
+ xorl 28(%rsp),%ebp
+ andl %edi,%eax
+ movl %r12d,%ecx
+ xorl 52(%rsp),%ebp
xorl %edi,%ebx
- roll $30,%edx
+ leal -1894007588(%rdx,%r11,1),%r11d
+ roll $5,%ecx
+ xorl 8(%rsp),%ebp
+ addl %eax,%r11d
+ andl %r13d,%ebx
+ roll $1,%ebp
addl %ebx,%r11d
- roll $1,%eax
- movl %eax,16(%rsp)
- leal 1859775393(%rax,%rdi,1),%ebp
- movl 20(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 28(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 52(%rsp),%eax
+ roll $30,%r13d
+ movl %ebp,20(%rsp)
+ addl %ecx,%r11d
+ movl 24(%rsp),%edx
+ movl %r13d,%eax
+ movl %r13d,%ebx
+ xorl 32(%rsp),%edx
+ andl %esi,%eax
+ movl %r11d,%ecx
+ xorl 56(%rsp),%edx
xorl %esi,%ebx
- addl %edi,%ebp
- xorl 8(%rsp),%eax
+ leal -1894007588(%rbp,%rdi,1),%edi
+ roll $5,%ecx
+ xorl 12(%rsp),%edx
+ addl %eax,%edi
+ andl %r12d,%ebx
+ roll $1,%edx
+ addl %ebx,%edi
roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,20(%rsp)
- leal 1859775393(%rax,%rsi,1),%edi
- movl 24(%rsp),%eax
+ movl %edx,24(%rsp)
+ addl %ecx,%edi
+ movl 28(%rsp),%ebp
+ movl %r12d,%eax
movl %r12d,%ebx
- movl %ebp,%esi
- xorl 32(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 56(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 12(%rsp),%eax
+ xorl 36(%rsp),%ebp
+ andl %r13d,%eax
+ movl %edi,%ecx
+ xorl 60(%rsp),%ebp
+ xorl %r13d,%ebx
+ leal -1894007588(%rdx,%rsi,1),%esi
+ roll $5,%ecx
+ xorl 16(%rsp),%ebp
+ addl %eax,%esi
+ andl %r11d,%ebx
+ roll $1,%ebp
+ addl %ebx,%esi
roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,24(%rsp)
- leal 1859775393(%rax,%rdx,1),%esi
- movl 28(%rsp),%eax
+ movl %ebp,28(%rsp)
+ addl %ecx,%esi
+ movl 32(%rsp),%edx
+ movl %r11d,%eax
movl %r11d,%ebx
- movl %edi,%edx
- xorl 36(%rsp),%eax
- xorl %ebp,%ebx
- roll $5,%edx
- xorl 60(%rsp),%eax
+ xorl 40(%rsp),%edx
+ andl %r12d,%eax
+ movl %esi,%ecx
+ xorl 0(%rsp),%edx
xorl %r12d,%ebx
- addl %edx,%esi
- xorl 16(%rsp),%eax
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- movl %eax,28(%rsp)
- leal 1859775393(%rax,%r12,1),%edx
- movl 32(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 40(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 0(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 20(%rsp),%eax
+ leal -1894007588(%rbp,%r13,1),%r13d
+ roll $5,%ecx
+ xorl 20(%rsp),%edx
+ addl %eax,%r13d
+ andl %edi,%ebx
+ roll $1,%edx
+ addl %ebx,%r13d
roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,32(%rsp)
- leal 1859775393(%rax,%r11,1),%r12d
- movl 36(%rsp),%eax
+ movl %edx,32(%rsp)
+ addl %ecx,%r13d
+ movl 36(%rsp),%ebp
+ movl %edi,%eax
movl %edi,%ebx
- movl %edx,%r11d
- xorl 44(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 4(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 24(%rsp),%eax
- roll $30,%esi
+ xorl 44(%rsp),%ebp
+ andl %r11d,%eax
+ movl %r13d,%ecx
+ xorl 4(%rsp),%ebp
+ xorl %r11d,%ebx
+ leal -1894007588(%rdx,%r12,1),%r12d
+ roll $5,%ecx
+ xorl 24(%rsp),%ebp
+ addl %eax,%r12d
+ andl %esi,%ebx
+ roll $1,%ebp
addl %ebx,%r12d
- roll $1,%eax
- movl %eax,36(%rsp)
- leal 1859775393(%rax,%rbp,1),%r11d
- movl 40(%rsp),%eax
+ roll $30,%esi
+ movl %ebp,36(%rsp)
+ addl %ecx,%r12d
+ movl 40(%rsp),%edx
+ movl %esi,%eax
movl %esi,%ebx
- movl %r12d,%ebp
- xorl 48(%rsp),%eax
- xorl %edx,%ebx
- roll $5,%ebp
- xorl 8(%rsp),%eax
+ xorl 48(%rsp),%edx
+ andl %edi,%eax
+ movl %r12d,%ecx
+ xorl 8(%rsp),%edx
xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 28(%rsp),%eax
- roll $30,%edx
+ leal -1894007588(%rbp,%r11,1),%r11d
+ roll $5,%ecx
+ xorl 28(%rsp),%edx
+ addl %eax,%r11d
+ andl %r13d,%ebx
+ roll $1,%edx
addl %ebx,%r11d
- roll $1,%eax
- movl %eax,40(%rsp)
- leal 1859775393(%rax,%rdi,1),%ebp
- movl 44(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 52(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 12(%rsp),%eax
+ roll $30,%r13d
+ movl %edx,40(%rsp)
+ addl %ecx,%r11d
+ movl 44(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r13d,%ebx
+ xorl 52(%rsp),%ebp
+ andl %esi,%eax
+ movl %r11d,%ecx
+ xorl 12(%rsp),%ebp
xorl %esi,%ebx
- addl %edi,%ebp
- xorl 32(%rsp),%eax
+ leal -1894007588(%rdx,%rdi,1),%edi
+ roll $5,%ecx
+ xorl 32(%rsp),%ebp
+ addl %eax,%edi
+ andl %r12d,%ebx
+ roll $1,%ebp
+ addl %ebx,%edi
roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,44(%rsp)
- leal 1859775393(%rax,%rsi,1),%edi
- movl 48(%rsp),%eax
+ movl %ebp,44(%rsp)
+ addl %ecx,%edi
+ movl 48(%rsp),%edx
+ movl %r12d,%eax
movl %r12d,%ebx
- movl %ebp,%esi
- xorl 56(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 16(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 36(%rsp),%eax
- roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,48(%rsp)
- leal 1859775393(%rax,%rdx,1),%esi
- movl 52(%rsp),%eax
- movl %r11d,%ebx
- movl %edi,%edx
- xorl 60(%rsp),%eax
- xorl %ebp,%ebx
- roll $5,%edx
- xorl 20(%rsp),%eax
- xorl %r12d,%ebx
- addl %edx,%esi
- xorl 40(%rsp),%eax
- roll $30,%ebp
+ xorl 56(%rsp),%edx
+ andl %r13d,%eax
+ movl %edi,%ecx
+ xorl 16(%rsp),%edx
+ xorl %r13d,%ebx
+ leal -1894007588(%rbp,%rsi,1),%esi
+ roll $5,%ecx
+ xorl 36(%rsp),%edx
+ addl %eax,%esi
+ andl %r11d,%ebx
+ roll $1,%edx
addl %ebx,%esi
- roll $1,%eax
- movl %eax,52(%rsp)
- leal 1859775393(%rax,%r12,1),%edx
- movl 56(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 0(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 24(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 44(%rsp),%eax
+ roll $30,%r11d
+ movl %edx,48(%rsp)
+ addl %ecx,%esi
+ movl 52(%rsp),%ebp
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 60(%rsp),%ebp
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r13,1),%r13d
+ xorl 20(%rsp),%ebp
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 40(%rsp),%ebp
roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,56(%rsp)
- leal 1859775393(%rax,%r11,1),%r12d
- movl 60(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 4(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 28(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 48(%rsp),%eax
+ addl %eax,%r13d
+ roll $1,%ebp
+ movl %ebp,52(%rsp)
+ movl 56(%rsp),%edx
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 0(%rsp),%edx
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r12,1),%r12d
+ xorl 24(%rsp),%edx
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 44(%rsp),%edx
roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- movl %eax,60(%rsp)
- leal 1859775393(%rax,%rbp,1),%r11d
- movl 0(%rsp),%eax
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl 8(%rsp),%eax
- xorl %edx,%ebx
- roll $5,%ebp
- xorl 32(%rsp),%eax
- xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 52(%rsp),%eax
- roll $30,%edx
- addl %ebx,%r11d
- roll $1,%eax
- movl %eax,0(%rsp)
- leal 1859775393(%rax,%rdi,1),%ebp
- movl 4(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 12(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 36(%rsp),%eax
- xorl %esi,%ebx
- addl %edi,%ebp
- xorl 56(%rsp),%eax
+ addl %eax,%r12d
+ roll $1,%edx
+ movl %edx,56(%rsp)
+ movl 60(%rsp),%ebp
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 4(%rsp),%ebp
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r11,1),%r11d
+ xorl 28(%rsp),%ebp
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 48(%rsp),%ebp
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%ebp
+ movl %ebp,60(%rsp)
+ movl 0(%rsp),%edx
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 8(%rsp),%edx
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%rdi,1),%edi
+ xorl 32(%rsp),%edx
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 52(%rsp),%edx
roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,4(%rsp)
- leal 1859775393(%rax,%rsi,1),%edi
- movl 8(%rsp),%eax
- movl %r12d,%ebx
- movl %ebp,%esi
- xorl 16(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 40(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 60(%rsp),%eax
+ addl %eax,%edi
+ roll $1,%edx
+ movl %edx,0(%rsp)
+ movl 4(%rsp),%ebp
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl 12(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%rsi,1),%esi
+ xorl 36(%rsp),%ebp
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 56(%rsp),%ebp
roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,8(%rsp)
- leal 1859775393(%rax,%rdx,1),%esi
- movl 12(%rsp),%eax
- movl %r11d,%ebx
- movl %edi,%edx
- xorl 20(%rsp),%eax
- xorl %ebp,%ebx
- roll $5,%edx
- xorl 44(%rsp),%eax
- xorl %r12d,%ebx
- addl %edx,%esi
- xorl 0(%rsp),%eax
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- movl %eax,12(%rsp)
- leal 1859775393(%rax,%r12,1),%edx
- movl 16(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 24(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 48(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 4(%rsp),%eax
+ addl %eax,%esi
+ roll $1,%ebp
+ movl %ebp,4(%rsp)
+ movl 8(%rsp),%edx
+ movl %r11d,%eax
+ movl %esi,%ecx
+ xorl 16(%rsp),%edx
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r13,1),%r13d
+ xorl 40(%rsp),%edx
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 60(%rsp),%edx
roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,16(%rsp)
- leal 1859775393(%rax,%r11,1),%r12d
- movl 20(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 28(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 52(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 8(%rsp),%eax
+ addl %eax,%r13d
+ roll $1,%edx
+ movl %edx,8(%rsp)
+ movl 12(%rsp),%ebp
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 20(%rsp),%ebp
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r12,1),%r12d
+ xorl 44(%rsp),%ebp
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 0(%rsp),%ebp
roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- movl %eax,20(%rsp)
- leal 1859775393(%rax,%rbp,1),%r11d
- movl 24(%rsp),%eax
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl 32(%rsp),%eax
- xorl %edx,%ebx
- roll $5,%ebp
- xorl 56(%rsp),%eax
- xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 12(%rsp),%eax
- roll $30,%edx
- addl %ebx,%r11d
- roll $1,%eax
- movl %eax,24(%rsp)
- leal 1859775393(%rax,%rdi,1),%ebp
- movl 28(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 36(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 60(%rsp),%eax
- xorl %esi,%ebx
- addl %edi,%ebp
- xorl 16(%rsp),%eax
+ addl %eax,%r12d
+ roll $1,%ebp
+ movl %ebp,12(%rsp)
+ movl 16(%rsp),%edx
+ movl %esi,%eax
+ movl %r12d,%ecx
+ xorl 24(%rsp),%edx
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r11,1),%r11d
+ xorl 48(%rsp),%edx
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 4(%rsp),%edx
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%edx
+ movl %edx,16(%rsp)
+ movl 20(%rsp),%ebp
+ movl %r13d,%eax
+ movl %r11d,%ecx
+ xorl 28(%rsp),%ebp
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%rdi,1),%edi
+ xorl 52(%rsp),%ebp
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 8(%rsp),%ebp
roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,28(%rsp)
- leal 1859775393(%rax,%rsi,1),%edi
- movl 32(%rsp),%eax
- movl %r12d,%ebx
- movl %ebp,%esi
- xorl 40(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 0(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 20(%rsp),%eax
- roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,32(%rsp)
- leal -1894007588(%rax,%rdx,1),%esi
- movl 36(%rsp),%eax
- movl %ebp,%ebx
- movl %ebp,%ecx
- xorl 44(%rsp),%eax
- movl %edi,%edx
- andl %r11d,%ebx
- xorl 4(%rsp),%eax
- orl %r11d,%ecx
- roll $5,%edx
- xorl 24(%rsp),%eax
- andl %r12d,%ecx
- addl %edx,%esi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%ebp
- movl %eax,36(%rsp)
- addl %ebx,%esi
- leal -1894007588(%rax,%r12,1),%edx
- movl 40(%rsp),%eax
- movl %edi,%ebx
+ addl %eax,%edi
+ roll $1,%ebp
+ movl %ebp,20(%rsp)
+ movl 24(%rsp),%edx
+ movl %r12d,%eax
movl %edi,%ecx
- xorl 48(%rsp),%eax
- movl %esi,%r12d
- andl %ebp,%ebx
- xorl 8(%rsp),%eax
- orl %ebp,%ecx
- roll $5,%r12d
- xorl 28(%rsp),%eax
- andl %r11d,%ecx
- addl %r12d,%edx
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edi
- movl %eax,40(%rsp)
- addl %ebx,%edx
- leal -1894007588(%rax,%r11,1),%r12d
- movl 44(%rsp),%eax
- movl %esi,%ebx
+ xorl 32(%rsp),%edx
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%rsi,1),%esi
+ xorl 56(%rsp),%edx
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 12(%rsp),%edx
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%edx
+ movl %edx,24(%rsp)
+ movl 28(%rsp),%ebp
+ movl %r11d,%eax
movl %esi,%ecx
- xorl 52(%rsp),%eax
- movl %edx,%r11d
- andl %edi,%ebx
- xorl 12(%rsp),%eax
- orl %edi,%ecx
- roll $5,%r11d
- xorl 32(%rsp),%eax
- andl %ebp,%ecx
- addl %r11d,%r12d
- roll $1,%eax
- orl %ecx,%ebx
+ xorl 36(%rsp),%ebp
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r13,1),%r13d
+ xorl 60(%rsp),%ebp
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 16(%rsp),%ebp
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%ebp
+ movl %ebp,28(%rsp)
+ movl 32(%rsp),%edx
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 40(%rsp),%edx
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r12,1),%r12d
+ xorl 0(%rsp),%edx
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 20(%rsp),%edx
roll $30,%esi
- movl %eax,44(%rsp)
- addl %ebx,%r12d
- leal -1894007588(%rax,%rbp,1),%r11d
- movl 48(%rsp),%eax
- movl %edx,%ebx
- movl %edx,%ecx
- xorl 56(%rsp),%eax
- movl %r12d,%ebp
- andl %esi,%ebx
- xorl 16(%rsp),%eax
- orl %esi,%ecx
- roll $5,%ebp
- xorl 36(%rsp),%eax
- andl %edi,%ecx
- addl %ebp,%r11d
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edx
- movl %eax,48(%rsp)
- addl %ebx,%r11d
- leal -1894007588(%rax,%rdi,1),%ebp
- movl 52(%rsp),%eax
- movl %r12d,%ebx
+ addl %eax,%r12d
+ roll $1,%edx
+ movl %edx,32(%rsp)
+ movl 36(%rsp),%ebp
+ movl %esi,%eax
movl %r12d,%ecx
- xorl 60(%rsp),%eax
- movl %r11d,%edi
- andl %edx,%ebx
- xorl 20(%rsp),%eax
- orl %edx,%ecx
- roll $5,%edi
- xorl 40(%rsp),%eax
- andl %esi,%ecx
- addl %edi,%ebp
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%r12d
- movl %eax,52(%rsp)
- addl %ebx,%ebp
- leal -1894007588(%rax,%rsi,1),%edi
- movl 56(%rsp),%eax
- movl %r11d,%ebx
+ xorl 44(%rsp),%ebp
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r11,1),%r11d
+ xorl 4(%rsp),%ebp
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 24(%rsp),%ebp
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%ebp
+ movl %ebp,36(%rsp)
+ movl 40(%rsp),%edx
+ movl %r13d,%eax
movl %r11d,%ecx
- xorl 0(%rsp),%eax
- movl %ebp,%esi
- andl %r12d,%ebx
- xorl 24(%rsp),%eax
- orl %r12d,%ecx
- roll $5,%esi
- xorl 44(%rsp),%eax
- andl %edx,%ecx
- addl %esi,%edi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%r11d
- movl %eax,56(%rsp)
- addl %ebx,%edi
- leal -1894007588(%rax,%rdx,1),%esi
- movl 60(%rsp),%eax
- movl %ebp,%ebx
- movl %ebp,%ecx
- xorl 4(%rsp),%eax
- movl %edi,%edx
- andl %r11d,%ebx
- xorl 28(%rsp),%eax
- orl %r11d,%ecx
- roll $5,%edx
- xorl 48(%rsp),%eax
- andl %r12d,%ecx
- addl %edx,%esi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%ebp
- movl %eax,60(%rsp)
- addl %ebx,%esi
- leal -1894007588(%rax,%r12,1),%edx
- movl 0(%rsp),%eax
- movl %edi,%ebx
+ xorl 48(%rsp),%edx
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%rdi,1),%edi
+ xorl 8(%rsp),%edx
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 28(%rsp),%edx
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%edx
+ movl %edx,40(%rsp)
+ movl 44(%rsp),%ebp
+ movl %r12d,%eax
movl %edi,%ecx
- xorl 8(%rsp),%eax
- movl %esi,%r12d
- andl %ebp,%ebx
- xorl 32(%rsp),%eax
- orl %ebp,%ecx
- roll $5,%r12d
- xorl 52(%rsp),%eax
- andl %r11d,%ecx
- addl %r12d,%edx
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edi
- movl %eax,0(%rsp)
- addl %ebx,%edx
- leal -1894007588(%rax,%r11,1),%r12d
- movl 4(%rsp),%eax
- movl %esi,%ebx
+ xorl 52(%rsp),%ebp
+ xorl %r11d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%rsi,1),%esi
+ xorl 12(%rsp),%ebp
+ xorl %r13d,%eax
+ addl %ecx,%esi
+ xorl 32(%rsp),%ebp
+ roll $30,%r11d
+ addl %eax,%esi
+ roll $1,%ebp
+ movl %ebp,44(%rsp)
+ movl 48(%rsp),%edx
+ movl %r11d,%eax
movl %esi,%ecx
- xorl 12(%rsp),%eax
- movl %edx,%r11d
- andl %edi,%ebx
- xorl 36(%rsp),%eax
- orl %edi,%ecx
- roll $5,%r11d
- xorl 56(%rsp),%eax
- andl %ebp,%ecx
- addl %r11d,%r12d
- roll $1,%eax
- orl %ecx,%ebx
+ xorl 56(%rsp),%edx
+ xorl %edi,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r13,1),%r13d
+ xorl 16(%rsp),%edx
+ xorl %r12d,%eax
+ addl %ecx,%r13d
+ xorl 36(%rsp),%edx
+ roll $30,%edi
+ addl %eax,%r13d
+ roll $1,%edx
+ movl %edx,48(%rsp)
+ movl 52(%rsp),%ebp
+ movl %edi,%eax
+ movl %r13d,%ecx
+ xorl 60(%rsp),%ebp
+ xorl %esi,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%r12,1),%r12d
+ xorl 20(%rsp),%ebp
+ xorl %r11d,%eax
+ addl %ecx,%r12d
+ xorl 40(%rsp),%ebp
roll $30,%esi
- movl %eax,4(%rsp)
- addl %ebx,%r12d
- leal -1894007588(%rax,%rbp,1),%r11d
- movl 8(%rsp),%eax
- movl %edx,%ebx
- movl %edx,%ecx
- xorl 16(%rsp),%eax
- movl %r12d,%ebp
- andl %esi,%ebx
- xorl 40(%rsp),%eax
- orl %esi,%ecx
- roll $5,%ebp
- xorl 60(%rsp),%eax
- andl %edi,%ecx
- addl %ebp,%r11d
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edx
- movl %eax,8(%rsp)
- addl %ebx,%r11d
- leal -1894007588(%rax,%rdi,1),%ebp
- movl 12(%rsp),%eax
- movl %r12d,%ebx
+ addl %eax,%r12d
+ roll $1,%ebp
+ movl 56(%rsp),%edx
+ movl %esi,%eax
movl %r12d,%ecx
- xorl 20(%rsp),%eax
- movl %r11d,%edi
- andl %edx,%ebx
- xorl 44(%rsp),%eax
- orl %edx,%ecx
- roll $5,%edi
- xorl 0(%rsp),%eax
- andl %esi,%ecx
- addl %edi,%ebp
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%r12d
- movl %eax,12(%rsp)
- addl %ebx,%ebp
- leal -1894007588(%rax,%rsi,1),%edi
- movl 16(%rsp),%eax
- movl %r11d,%ebx
+ xorl 0(%rsp),%edx
+ xorl %r13d,%eax
+ roll $5,%ecx
+ leal -899497514(%rbp,%r11,1),%r11d
+ xorl 24(%rsp),%edx
+ xorl %edi,%eax
+ addl %ecx,%r11d
+ xorl 44(%rsp),%edx
+ roll $30,%r13d
+ addl %eax,%r11d
+ roll $1,%edx
+ movl 60(%rsp),%ebp
+ movl %r13d,%eax
movl %r11d,%ecx
- xorl 24(%rsp),%eax
- movl %ebp,%esi
- andl %r12d,%ebx
- xorl 48(%rsp),%eax
- orl %r12d,%ecx
- roll $5,%esi
- xorl 4(%rsp),%eax
- andl %edx,%ecx
- addl %esi,%edi
- roll $1,%eax
- orl %ecx,%ebx
+ xorl 4(%rsp),%ebp
+ xorl %r12d,%eax
+ roll $5,%ecx
+ leal -899497514(%rdx,%rdi,1),%edi
+ xorl 28(%rsp),%ebp
+ xorl %esi,%eax
+ addl %ecx,%edi
+ xorl 48(%rsp),%ebp
+ roll $30,%r12d
+ addl %eax,%edi
+ roll $1,%ebp
+ movl %r12d,%eax
+ movl %edi,%ecx
+ xorl %r11d,%eax
+ leal -899497514(%rbp,%rsi,1),%esi
+ roll $5,%ecx
+ xorl %r13d,%eax
+ addl %ecx,%esi
roll $30,%r11d
- movl %eax,16(%rsp)
- addl %ebx,%edi
- leal -1894007588(%rax,%rdx,1),%esi
- movl 20(%rsp),%eax
- movl %ebp,%ebx
- movl %ebp,%ecx
- xorl 28(%rsp),%eax
- movl %edi,%edx
- andl %r11d,%ebx
- xorl 52(%rsp),%eax
- orl %r11d,%ecx
+ addl %eax,%esi
+ addl 0(%r8),%esi
+ addl 4(%r8),%edi
+ addl 8(%r8),%r11d
+ addl 12(%r8),%r12d
+ addl 16(%r8),%r13d
+ movl %esi,0(%r8)
+ movl %edi,4(%r8)
+ movl %r11d,8(%r8)
+ movl %r12d,12(%r8)
+ movl %r13d,16(%r8)
+
+ subq $1,%r10
+ leaq 64(%r9),%r9
+ jnz L$loop
+
+ movq 64(%rsp),%rsi
+ movq (%rsi),%r13
+ movq 8(%rsi),%r12
+ movq 16(%rsi),%rbp
+ movq 24(%rsi),%rbx
+ leaq 32(%rsi),%rsp
+L$epilogue:
+ .byte 0xf3,0xc3
+
+
+.p2align 4
+sha1_block_data_order_ssse3:
+_ssse3_shortcut:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ leaq -64(%rsp),%rsp
+ movq %rdi,%r8
+ movq %rsi,%r9
+ movq %rdx,%r10
+
+ shlq $6,%r10
+ addq %r9,%r10
+ leaq K_XX_XX(%rip),%r11
+
+ movl 0(%r8),%eax
+ movl 4(%r8),%ebx
+ movl 8(%r8),%ecx
+ movl 12(%r8),%edx
+ movl %ebx,%esi
+ movl 16(%r8),%ebp
+
+ movdqa 64(%r11),%xmm6
+ movdqa 0(%r11),%xmm9
+ movdqu 0(%r9),%xmm0
+ movdqu 16(%r9),%xmm1
+ movdqu 32(%r9),%xmm2
+ movdqu 48(%r9),%xmm3
+.byte 102,15,56,0,198
+ addq $64,%r9
+.byte 102,15,56,0,206
+.byte 102,15,56,0,214
+.byte 102,15,56,0,222
+ paddd %xmm9,%xmm0
+ paddd %xmm9,%xmm1
+ paddd %xmm9,%xmm2
+ movdqa %xmm0,0(%rsp)
+ psubd %xmm9,%xmm0
+ movdqa %xmm1,16(%rsp)
+ psubd %xmm9,%xmm1
+ movdqa %xmm2,32(%rsp)
+ psubd %xmm9,%xmm2
+ jmp L$oop_ssse3
+.p2align 4
+L$oop_ssse3:
+ movdqa %xmm1,%xmm4
+ addl 0(%rsp),%ebp
+ xorl %edx,%ecx
+ movdqa %xmm3,%xmm8
+.byte 102,15,58,15,224,8
+ movl %eax,%edi
+ roll $5,%eax
+ paddd %xmm3,%xmm9
+ andl %ecx,%esi
+ xorl %edx,%ecx
+ psrldq $4,%xmm8
+ xorl %edx,%esi
+ addl %eax,%ebp
+ pxor %xmm0,%xmm4
+ rorl $2,%ebx
+ addl %esi,%ebp
+ pxor %xmm2,%xmm8
+ addl 4(%rsp),%edx
+ xorl %ecx,%ebx
+ movl %ebp,%esi
+ roll $5,%ebp
+ pxor %xmm8,%xmm4
+ andl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa %xmm9,48(%rsp)
+ xorl %ecx,%edi
+ addl %ebp,%edx
+ movdqa %xmm4,%xmm10
+ movdqa %xmm4,%xmm8
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 8(%rsp),%ecx
+ xorl %ebx,%eax
+ pslldq $12,%xmm10
+ paddd %xmm4,%xmm4
+ movl %edx,%edi
roll $5,%edx
- xorl 8(%rsp),%eax
- andl %r12d,%ecx
- addl %edx,%esi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%ebp
- movl %eax,20(%rsp)
- addl %ebx,%esi
- leal -1894007588(%rax,%r12,1),%edx
- movl 24(%rsp),%eax
- movl %edi,%ebx
- movl %edi,%ecx
- xorl 32(%rsp),%eax
- movl %esi,%r12d
- andl %ebp,%ebx
- xorl 56(%rsp),%eax
- orl %ebp,%ecx
- roll $5,%r12d
- xorl 12(%rsp),%eax
- andl %r11d,%ecx
- addl %r12d,%edx
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edi
- movl %eax,24(%rsp)
- addl %ebx,%edx
- leal -1894007588(%rax,%r11,1),%r12d
- movl 28(%rsp),%eax
- movl %esi,%ebx
- movl %esi,%ecx
- xorl 36(%rsp),%eax
- movl %edx,%r11d
- andl %edi,%ebx
- xorl 60(%rsp),%eax
- orl %edi,%ecx
- roll $5,%r11d
- xorl 16(%rsp),%eax
- andl %ebp,%ecx
- addl %r11d,%r12d
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%esi
- movl %eax,28(%rsp)
- addl %ebx,%r12d
- leal -1894007588(%rax,%rbp,1),%r11d
- movl 32(%rsp),%eax
- movl %edx,%ebx
- movl %edx,%ecx
- xorl 40(%rsp),%eax
- movl %r12d,%ebp
- andl %esi,%ebx
- xorl 0(%rsp),%eax
- orl %esi,%ecx
+ andl %eax,%esi
+ xorl %ebx,%eax
+ psrld $31,%xmm8
+ xorl %ebx,%esi
+ addl %edx,%ecx
+ movdqa %xmm10,%xmm9
+ rorl $7,%ebp
+ addl %esi,%ecx
+ psrld $30,%xmm10
+ por %xmm8,%xmm4
+ addl 12(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%esi
+ roll $5,%ecx
+ pslld $2,%xmm9
+ pxor %xmm10,%xmm4
+ andl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa 0(%r11),%xmm10
+ xorl %eax,%edi
+ addl %ecx,%ebx
+ pxor %xmm9,%xmm4
+ rorl $7,%edx
+ addl %edi,%ebx
+ movdqa %xmm2,%xmm5
+ addl 16(%rsp),%eax
+ xorl %ebp,%edx
+ movdqa %xmm4,%xmm9
+.byte 102,15,58,15,233,8
+ movl %ebx,%edi
+ roll $5,%ebx
+ paddd %xmm4,%xmm10
+ andl %edx,%esi
+ xorl %ebp,%edx
+ psrldq $4,%xmm9
+ xorl %ebp,%esi
+ addl %ebx,%eax
+ pxor %xmm1,%xmm5
+ rorl $7,%ecx
+ addl %esi,%eax
+ pxor %xmm3,%xmm9
+ addl 20(%rsp),%ebp
+ xorl %edx,%ecx
+ movl %eax,%esi
+ roll $5,%eax
+ pxor %xmm9,%xmm5
+ andl %ecx,%edi
+ xorl %edx,%ecx
+ movdqa %xmm10,0(%rsp)
+ xorl %edx,%edi
+ addl %eax,%ebp
+ movdqa %xmm5,%xmm8
+ movdqa %xmm5,%xmm9
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 24(%rsp),%edx
+ xorl %ecx,%ebx
+ pslldq $12,%xmm8
+ paddd %xmm5,%xmm5
+ movl %ebp,%edi
roll $5,%ebp
- xorl 20(%rsp),%eax
- andl %edi,%ecx
- addl %ebp,%r11d
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edx
- movl %eax,32(%rsp)
- addl %ebx,%r11d
- leal -1894007588(%rax,%rdi,1),%ebp
- movl 36(%rsp),%eax
- movl %r12d,%ebx
- movl %r12d,%ecx
- xorl 44(%rsp),%eax
- movl %r11d,%edi
- andl %edx,%ebx
- xorl 4(%rsp),%eax
- orl %edx,%ecx
- roll $5,%edi
- xorl 24(%rsp),%eax
- andl %esi,%ecx
+ andl %ebx,%esi
+ xorl %ecx,%ebx
+ psrld $31,%xmm9
+ xorl %ecx,%esi
+ addl %ebp,%edx
+ movdqa %xmm8,%xmm10
+ rorl $7,%eax
+ addl %esi,%edx
+ psrld $30,%xmm8
+ por %xmm9,%xmm5
+ addl 28(%rsp),%ecx
+ xorl %ebx,%eax
+ movl %edx,%esi
+ roll $5,%edx
+ pslld $2,%xmm10
+ pxor %xmm8,%xmm5
+ andl %eax,%edi
+ xorl %ebx,%eax
+ movdqa 16(%r11),%xmm8
+ xorl %ebx,%edi
+ addl %edx,%ecx
+ pxor %xmm10,%xmm5
+ rorl $7,%ebp
+ addl %edi,%ecx
+ movdqa %xmm3,%xmm6
+ addl 32(%rsp),%ebx
+ xorl %eax,%ebp
+ movdqa %xmm5,%xmm10
+.byte 102,15,58,15,242,8
+ movl %ecx,%edi
+ roll $5,%ecx
+ paddd %xmm5,%xmm8
+ andl %ebp,%esi
+ xorl %eax,%ebp
+ psrldq $4,%xmm10
+ xorl %eax,%esi
+ addl %ecx,%ebx
+ pxor %xmm2,%xmm6
+ rorl $7,%edx
+ addl %esi,%ebx
+ pxor %xmm4,%xmm10
+ addl 36(%rsp),%eax
+ xorl %ebp,%edx
+ movl %ebx,%esi
+ roll $5,%ebx
+ pxor %xmm10,%xmm6
+ andl %edx,%edi
+ xorl %ebp,%edx
+ movdqa %xmm8,16(%rsp)
+ xorl %ebp,%edi
+ addl %ebx,%eax
+ movdqa %xmm6,%xmm9
+ movdqa %xmm6,%xmm10
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 40(%rsp),%ebp
+ xorl %edx,%ecx
+ pslldq $12,%xmm9
+ paddd %xmm6,%xmm6
+ movl %eax,%edi
+ roll $5,%eax
+ andl %ecx,%esi
+ xorl %edx,%ecx
+ psrld $31,%xmm10
+ xorl %edx,%esi
+ addl %eax,%ebp
+ movdqa %xmm9,%xmm8
+ rorl $7,%ebx
+ addl %esi,%ebp
+ psrld $30,%xmm9
+ por %xmm10,%xmm6
+ addl 44(%rsp),%edx
+ xorl %ecx,%ebx
+ movl %ebp,%esi
+ roll $5,%ebp
+ pslld $2,%xmm8
+ pxor %xmm9,%xmm6
+ andl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa 16(%r11),%xmm9
+ xorl %ecx,%edi
+ addl %ebp,%edx
+ pxor %xmm8,%xmm6
+ rorl $7,%eax
+ addl %edi,%edx
+ movdqa %xmm4,%xmm7
+ addl 48(%rsp),%ecx
+ xorl %ebx,%eax
+ movdqa %xmm6,%xmm8
+.byte 102,15,58,15,251,8
+ movl %edx,%edi
+ roll $5,%edx
+ paddd %xmm6,%xmm9
+ andl %eax,%esi
+ xorl %ebx,%eax
+ psrldq $4,%xmm8
+ xorl %ebx,%esi
+ addl %edx,%ecx
+ pxor %xmm3,%xmm7
+ rorl $7,%ebp
+ addl %esi,%ecx
+ pxor %xmm5,%xmm8
+ addl 52(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%esi
+ roll $5,%ecx
+ pxor %xmm8,%xmm7
+ andl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa %xmm9,32(%rsp)
+ xorl %eax,%edi
+ addl %ecx,%ebx
+ movdqa %xmm7,%xmm10
+ movdqa %xmm7,%xmm8
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 56(%rsp),%eax
+ xorl %ebp,%edx
+ pslldq $12,%xmm10
+ paddd %xmm7,%xmm7
+ movl %ebx,%edi
+ roll $5,%ebx
+ andl %edx,%esi
+ xorl %ebp,%edx
+ psrld $31,%xmm8
+ xorl %ebp,%esi
+ addl %ebx,%eax
+ movdqa %xmm10,%xmm9
+ rorl $7,%ecx
+ addl %esi,%eax
+ psrld $30,%xmm10
+ por %xmm8,%xmm7
+ addl 60(%rsp),%ebp
+ xorl %edx,%ecx
+ movl %eax,%esi
+ roll $5,%eax
+ pslld $2,%xmm9
+ pxor %xmm10,%xmm7
+ andl %ecx,%edi
+ xorl %edx,%ecx
+ movdqa 16(%r11),%xmm10
+ xorl %edx,%edi
+ addl %eax,%ebp
+ pxor %xmm9,%xmm7
+ rorl $7,%ebx
addl %edi,%ebp
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%r12d
- movl %eax,36(%rsp)
- addl %ebx,%ebp
- leal -1894007588(%rax,%rsi,1),%edi
- movl 40(%rsp),%eax
- movl %r11d,%ebx
- movl %r11d,%ecx
- xorl 48(%rsp),%eax
+ movdqa %xmm7,%xmm9
+ addl 0(%rsp),%edx
+ pxor %xmm4,%xmm0
+.byte 102,68,15,58,15,206,8
+ xorl %ecx,%ebx
+ movl %ebp,%edi
+ roll $5,%ebp
+ pxor %xmm1,%xmm0
+ andl %ebx,%esi
+ xorl %ecx,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm7,%xmm10
+ xorl %ecx,%esi
+ addl %ebp,%edx
+ pxor %xmm9,%xmm0
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 4(%rsp),%ecx
+ xorl %ebx,%eax
+ movdqa %xmm0,%xmm9
+ movdqa %xmm10,48(%rsp)
+ movl %edx,%esi
+ roll $5,%edx
+ andl %eax,%edi
+ xorl %ebx,%eax
+ pslld $2,%xmm0
+ xorl %ebx,%edi
+ addl %edx,%ecx
+ psrld $30,%xmm9
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 8(%rsp),%ebx
+ xorl %eax,%ebp
+ movl %ecx,%edi
+ roll $5,%ecx
+ por %xmm9,%xmm0
+ andl %ebp,%esi
+ xorl %eax,%ebp
+ movdqa %xmm0,%xmm10
+ xorl %eax,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 12(%rsp),%eax
+ xorl %ebp,%edx
+ movl %ebx,%esi
+ roll $5,%ebx
+ andl %edx,%edi
+ xorl %ebp,%edx
+ xorl %ebp,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 16(%rsp),%ebp
+ pxor %xmm5,%xmm1
+.byte 102,68,15,58,15,215,8
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ pxor %xmm2,%xmm1
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ movdqa %xmm8,%xmm9
+ paddd %xmm0,%xmm8
+ rorl $7,%ebx
+ addl %esi,%ebp
+ pxor %xmm10,%xmm1
+ addl 20(%rsp),%edx
+ xorl %ecx,%edi
movl %ebp,%esi
- andl %r12d,%ebx
- xorl 8(%rsp),%eax
- orl %r12d,%ecx
- roll $5,%esi
- xorl 28(%rsp),%eax
- andl %edx,%ecx
- addl %esi,%edi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%r11d
- movl %eax,40(%rsp)
- addl %ebx,%edi
- leal -1894007588(%rax,%rdx,1),%esi
- movl 44(%rsp),%eax
- movl %ebp,%ebx
- movl %ebp,%ecx
- xorl 52(%rsp),%eax
- movl %edi,%edx
- andl %r11d,%ebx
- xorl 12(%rsp),%eax
- orl %r11d,%ecx
+ roll $5,%ebp
+ movdqa %xmm1,%xmm10
+ movdqa %xmm8,0(%rsp)
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ pslld $2,%xmm1
+ addl 24(%rsp),%ecx
+ xorl %ebx,%esi
+ psrld $30,%xmm10
+ movl %edx,%edi
roll $5,%edx
- xorl 32(%rsp),%eax
- andl %r12d,%ecx
- addl %edx,%esi
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%ebp
- movl %eax,44(%rsp)
- addl %ebx,%esi
- leal -1894007588(%rax,%r12,1),%edx
- movl 48(%rsp),%eax
- movl %edi,%ebx
- movl %edi,%ecx
- xorl 56(%rsp),%eax
- movl %esi,%r12d
- andl %ebp,%ebx
- xorl 16(%rsp),%eax
- orl %ebp,%ecx
- roll $5,%r12d
- xorl 36(%rsp),%eax
- andl %r11d,%ecx
- addl %r12d,%edx
- roll $1,%eax
- orl %ecx,%ebx
- roll $30,%edi
- movl %eax,48(%rsp)
- addl %ebx,%edx
- leal -899497514(%rax,%r11,1),%r12d
- movl 52(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 60(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 20(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 40(%rsp),%eax
- roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- movl %eax,52(%rsp)
- leal -899497514(%rax,%rbp,1),%r11d
- movl 56(%rsp),%eax
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl 0(%rsp),%eax
- xorl %edx,%ebx
+ xorl %eax,%esi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ por %xmm10,%xmm1
+ addl 28(%rsp),%ebx
+ xorl %eax,%edi
+ movdqa %xmm1,%xmm8
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 32(%rsp),%eax
+ pxor %xmm6,%xmm2
+.byte 102,68,15,58,15,192,8
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ pxor %xmm3,%xmm2
+ xorl %edx,%esi
+ addl %ebx,%eax
+ movdqa 32(%r11),%xmm10
+ paddd %xmm1,%xmm9
+ rorl $7,%ecx
+ addl %esi,%eax
+ pxor %xmm8,%xmm2
+ addl 36(%rsp),%ebp
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ movdqa %xmm2,%xmm8
+ movdqa %xmm9,16(%rsp)
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ pslld $2,%xmm2
+ addl 40(%rsp),%edx
+ xorl %ecx,%esi
+ psrld $30,%xmm8
+ movl %ebp,%edi
roll $5,%ebp
- xorl 24(%rsp),%eax
- xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 44(%rsp),%eax
- roll $30,%edx
- addl %ebx,%r11d
- roll $1,%eax
- movl %eax,56(%rsp)
- leal -899497514(%rax,%rdi,1),%ebp
- movl 60(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 4(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 28(%rsp),%eax
- xorl %esi,%ebx
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ por %xmm8,%xmm2
+ addl 44(%rsp),%ecx
+ xorl %ebx,%edi
+ movdqa %xmm2,%xmm9
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 48(%rsp),%ebx
+ pxor %xmm7,%xmm3
+.byte 102,68,15,58,15,201,8
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ pxor %xmm4,%xmm3
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm2,%xmm10
+ rorl $7,%edx
+ addl %esi,%ebx
+ pxor %xmm9,%xmm3
+ addl 52(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ movdqa %xmm3,%xmm9
+ movdqa %xmm10,32(%rsp)
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ pslld $2,%xmm3
+ addl 56(%rsp),%ebp
+ xorl %edx,%esi
+ psrld $30,%xmm9
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ por %xmm9,%xmm3
+ addl 60(%rsp),%edx
+ xorl %ecx,%edi
+ movdqa %xmm3,%xmm10
+ movl %ebp,%esi
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 0(%rsp),%ecx
+ pxor %xmm0,%xmm4
+.byte 102,68,15,58,15,210,8
+ xorl %ebx,%esi
+ movl %edx,%edi
+ roll $5,%edx
+ pxor %xmm5,%xmm4
+ xorl %eax,%esi
+ addl %edx,%ecx
+ movdqa %xmm8,%xmm9
+ paddd %xmm3,%xmm8
+ rorl $7,%ebp
+ addl %esi,%ecx
+ pxor %xmm10,%xmm4
+ addl 4(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ movdqa %xmm4,%xmm10
+ movdqa %xmm8,48(%rsp)
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ pslld $2,%xmm4
+ addl 8(%rsp),%eax
+ xorl %ebp,%esi
+ psrld $30,%xmm10
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ por %xmm10,%xmm4
+ addl 12(%rsp),%ebp
+ xorl %edx,%edi
+ movdqa %xmm4,%xmm8
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
addl %edi,%ebp
- xorl 48(%rsp),%eax
- roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,60(%rsp)
- leal -899497514(%rax,%rsi,1),%edi
- movl 0(%rsp),%eax
- movl %r12d,%ebx
+ addl 16(%rsp),%edx
+ pxor %xmm1,%xmm5
+.byte 102,68,15,58,15,195,8
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ pxor %xmm6,%xmm5
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ movdqa %xmm9,%xmm10
+ paddd %xmm4,%xmm9
+ rorl $7,%eax
+ addl %esi,%edx
+ pxor %xmm8,%xmm5
+ addl 20(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ movdqa %xmm5,%xmm8
+ movdqa %xmm9,0(%rsp)
+ xorl %eax,%edi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ pslld $2,%xmm5
+ addl 24(%rsp),%ebx
+ xorl %eax,%esi
+ psrld $30,%xmm8
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ por %xmm8,%xmm5
+ addl 28(%rsp),%eax
+ xorl %ebp,%edi
+ movdqa %xmm5,%xmm9
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ movl %ecx,%edi
+ pxor %xmm2,%xmm6
+.byte 102,68,15,58,15,204,8
+ xorl %edx,%ecx
+ addl 32(%rsp),%ebp
+ andl %edx,%edi
+ pxor %xmm7,%xmm6
+ andl %ecx,%esi
+ rorl $7,%ebx
+ movdqa %xmm10,%xmm8
+ paddd %xmm5,%xmm10
+ addl %edi,%ebp
+ movl %eax,%edi
+ pxor %xmm9,%xmm6
+ roll $5,%eax
+ addl %esi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movdqa %xmm6,%xmm9
+ movdqa %xmm10,16(%rsp)
+ movl %ebx,%esi
+ xorl %ecx,%ebx
+ addl 36(%rsp),%edx
+ andl %ecx,%esi
+ pslld $2,%xmm6
+ andl %ebx,%edi
+ rorl $7,%eax
+ psrld $30,%xmm9
+ addl %esi,%edx
movl %ebp,%esi
- xorl 8(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 32(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 52(%rsp),%eax
- roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,0(%rsp)
- leal -899497514(%rax,%rdx,1),%esi
- movl 4(%rsp),%eax
- movl %r11d,%ebx
- movl %edi,%edx
- xorl 12(%rsp),%eax
- xorl %ebp,%ebx
+ roll $5,%ebp
+ addl %edi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ por %xmm9,%xmm6
+ movl %eax,%edi
+ xorl %ebx,%eax
+ movdqa %xmm6,%xmm10
+ addl 40(%rsp),%ecx
+ andl %ebx,%edi
+ andl %eax,%esi
+ rorl $7,%ebp
+ addl %edi,%ecx
+ movl %edx,%edi
roll $5,%edx
- xorl 36(%rsp),%eax
- xorl %r12d,%ebx
- addl %edx,%esi
- xorl 56(%rsp),%eax
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- movl %eax,4(%rsp)
- leal -899497514(%rax,%r12,1),%edx
- movl 8(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 16(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 40(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 60(%rsp),%eax
- roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,8(%rsp)
- leal -899497514(%rax,%r11,1),%r12d
- movl 12(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 20(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 44(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 0(%rsp),%eax
- roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- movl %eax,12(%rsp)
- leal -899497514(%rax,%rbp,1),%r11d
- movl 16(%rsp),%eax
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl 24(%rsp),%eax
- xorl %edx,%ebx
+ addl %esi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movl %ebp,%esi
+ xorl %eax,%ebp
+ addl 44(%rsp),%ebx
+ andl %eax,%esi
+ andl %ebp,%edi
+ rorl $7,%edx
+ addl %esi,%ebx
+ movl %ecx,%esi
+ roll $5,%ecx
+ addl %edi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movl %edx,%edi
+ pxor %xmm3,%xmm7
+.byte 102,68,15,58,15,213,8
+ xorl %ebp,%edx
+ addl 48(%rsp),%eax
+ andl %ebp,%edi
+ pxor %xmm0,%xmm7
+ andl %edx,%esi
+ rorl $7,%ecx
+ movdqa 48(%r11),%xmm9
+ paddd %xmm6,%xmm8
+ addl %edi,%eax
+ movl %ebx,%edi
+ pxor %xmm10,%xmm7
+ roll $5,%ebx
+ addl %esi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ movdqa %xmm7,%xmm10
+ movdqa %xmm8,32(%rsp)
+ movl %ecx,%esi
+ xorl %edx,%ecx
+ addl 52(%rsp),%ebp
+ andl %edx,%esi
+ pslld $2,%xmm7
+ andl %ecx,%edi
+ rorl $7,%ebx
+ psrld $30,%xmm10
+ addl %esi,%ebp
+ movl %eax,%esi
+ roll $5,%eax
+ addl %edi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ por %xmm10,%xmm7
+ movl %ebx,%edi
+ xorl %ecx,%ebx
+ movdqa %xmm7,%xmm8
+ addl 56(%rsp),%edx
+ andl %ecx,%edi
+ andl %ebx,%esi
+ rorl $7,%eax
+ addl %edi,%edx
+ movl %ebp,%edi
roll $5,%ebp
- xorl 48(%rsp),%eax
- xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 4(%rsp),%eax
- roll $30,%edx
- addl %ebx,%r11d
- roll $1,%eax
- movl %eax,16(%rsp)
- leal -899497514(%rax,%rdi,1),%ebp
- movl 20(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 28(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 52(%rsp),%eax
- xorl %esi,%ebx
+ addl %esi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movl %eax,%esi
+ xorl %ebx,%eax
+ addl 60(%rsp),%ecx
+ andl %ebx,%esi
+ andl %eax,%edi
+ rorl $7,%ebp
+ addl %esi,%ecx
+ movl %edx,%esi
+ roll $5,%edx
+ addl %edi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movl %ebp,%edi
+ pxor %xmm4,%xmm0
+.byte 102,68,15,58,15,198,8
+ xorl %eax,%ebp
+ addl 0(%rsp),%ebx
+ andl %eax,%edi
+ pxor %xmm1,%xmm0
+ andl %ebp,%esi
+ rorl $7,%edx
+ movdqa %xmm9,%xmm10
+ paddd %xmm7,%xmm9
+ addl %edi,%ebx
+ movl %ecx,%edi
+ pxor %xmm8,%xmm0
+ roll $5,%ecx
+ addl %esi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movdqa %xmm0,%xmm8
+ movdqa %xmm9,48(%rsp)
+ movl %edx,%esi
+ xorl %ebp,%edx
+ addl 4(%rsp),%eax
+ andl %ebp,%esi
+ pslld $2,%xmm0
+ andl %edx,%edi
+ rorl $7,%ecx
+ psrld $30,%xmm8
+ addl %esi,%eax
+ movl %ebx,%esi
+ roll $5,%ebx
+ addl %edi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ por %xmm8,%xmm0
+ movl %ecx,%edi
+ xorl %edx,%ecx
+ movdqa %xmm0,%xmm9
+ addl 8(%rsp),%ebp
+ andl %edx,%edi
+ andl %ecx,%esi
+ rorl $7,%ebx
addl %edi,%ebp
- xorl 8(%rsp),%eax
- roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,20(%rsp)
- leal -899497514(%rax,%rsi,1),%edi
- movl 24(%rsp),%eax
- movl %r12d,%ebx
+ movl %eax,%edi
+ roll $5,%eax
+ addl %esi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movl %ebx,%esi
+ xorl %ecx,%ebx
+ addl 12(%rsp),%edx
+ andl %ecx,%esi
+ andl %ebx,%edi
+ rorl $7,%eax
+ addl %esi,%edx
movl %ebp,%esi
- xorl 32(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 56(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 12(%rsp),%eax
- roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,24(%rsp)
- leal -899497514(%rax,%rdx,1),%esi
- movl 28(%rsp),%eax
- movl %r11d,%ebx
- movl %edi,%edx
- xorl 36(%rsp),%eax
- xorl %ebp,%ebx
+ roll $5,%ebp
+ addl %edi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movl %eax,%edi
+ pxor %xmm5,%xmm1
+.byte 102,68,15,58,15,207,8
+ xorl %ebx,%eax
+ addl 16(%rsp),%ecx
+ andl %ebx,%edi
+ pxor %xmm2,%xmm1
+ andl %eax,%esi
+ rorl $7,%ebp
+ movdqa %xmm10,%xmm8
+ paddd %xmm0,%xmm10
+ addl %edi,%ecx
+ movl %edx,%edi
+ pxor %xmm9,%xmm1
roll $5,%edx
- xorl 60(%rsp),%eax
- xorl %r12d,%ebx
- addl %edx,%esi
- xorl 16(%rsp),%eax
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- movl %eax,28(%rsp)
- leal -899497514(%rax,%r12,1),%edx
- movl 32(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 40(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 0(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 20(%rsp),%eax
- roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- movl %eax,32(%rsp)
- leal -899497514(%rax,%r11,1),%r12d
- movl 36(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 44(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 4(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 24(%rsp),%eax
- roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- movl %eax,36(%rsp)
- leal -899497514(%rax,%rbp,1),%r11d
- movl 40(%rsp),%eax
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl 48(%rsp),%eax
- xorl %edx,%ebx
+ addl %esi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ movdqa %xmm1,%xmm9
+ movdqa %xmm10,0(%rsp)
+ movl %ebp,%esi
+ xorl %eax,%ebp
+ addl 20(%rsp),%ebx
+ andl %eax,%esi
+ pslld $2,%xmm1
+ andl %ebp,%edi
+ rorl $7,%edx
+ psrld $30,%xmm9
+ addl %esi,%ebx
+ movl %ecx,%esi
+ roll $5,%ecx
+ addl %edi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ por %xmm9,%xmm1
+ movl %edx,%edi
+ xorl %ebp,%edx
+ movdqa %xmm1,%xmm10
+ addl 24(%rsp),%eax
+ andl %ebp,%edi
+ andl %edx,%esi
+ rorl $7,%ecx
+ addl %edi,%eax
+ movl %ebx,%edi
+ roll $5,%ebx
+ addl %esi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ movl %ecx,%esi
+ xorl %edx,%ecx
+ addl 28(%rsp),%ebp
+ andl %edx,%esi
+ andl %ecx,%edi
+ rorl $7,%ebx
+ addl %esi,%ebp
+ movl %eax,%esi
+ roll $5,%eax
+ addl %edi,%ebp
+ xorl %edx,%ecx
+ addl %eax,%ebp
+ movl %ebx,%edi
+ pxor %xmm6,%xmm2
+.byte 102,68,15,58,15,208,8
+ xorl %ecx,%ebx
+ addl 32(%rsp),%edx
+ andl %ecx,%edi
+ pxor %xmm3,%xmm2
+ andl %ebx,%esi
+ rorl $7,%eax
+ movdqa %xmm8,%xmm9
+ paddd %xmm1,%xmm8
+ addl %edi,%edx
+ movl %ebp,%edi
+ pxor %xmm10,%xmm2
roll $5,%ebp
- xorl 8(%rsp),%eax
- xorl %edi,%ebx
- addl %ebp,%r11d
- xorl 28(%rsp),%eax
- roll $30,%edx
- addl %ebx,%r11d
- roll $1,%eax
- movl %eax,40(%rsp)
- leal -899497514(%rax,%rdi,1),%ebp
- movl 44(%rsp),%eax
- movl %edx,%ebx
- movl %r11d,%edi
- xorl 52(%rsp),%eax
- xorl %r12d,%ebx
- roll $5,%edi
- xorl 12(%rsp),%eax
- xorl %esi,%ebx
+ addl %esi,%edx
+ xorl %ecx,%ebx
+ addl %ebp,%edx
+ movdqa %xmm2,%xmm10
+ movdqa %xmm8,16(%rsp)
+ movl %eax,%esi
+ xorl %ebx,%eax
+ addl 36(%rsp),%ecx
+ andl %ebx,%esi
+ pslld $2,%xmm2
+ andl %eax,%edi
+ rorl $7,%ebp
+ psrld $30,%xmm10
+ addl %esi,%ecx
+ movl %edx,%esi
+ roll $5,%edx
+ addl %edi,%ecx
+ xorl %ebx,%eax
+ addl %edx,%ecx
+ por %xmm10,%xmm2
+ movl %ebp,%edi
+ xorl %eax,%ebp
+ movdqa %xmm2,%xmm8
+ addl 40(%rsp),%ebx
+ andl %eax,%edi
+ andl %ebp,%esi
+ rorl $7,%edx
+ addl %edi,%ebx
+ movl %ecx,%edi
+ roll $5,%ecx
+ addl %esi,%ebx
+ xorl %eax,%ebp
+ addl %ecx,%ebx
+ movl %edx,%esi
+ xorl %ebp,%edx
+ addl 44(%rsp),%eax
+ andl %ebp,%esi
+ andl %edx,%edi
+ rorl $7,%ecx
+ addl %esi,%eax
+ movl %ebx,%esi
+ roll $5,%ebx
+ addl %edi,%eax
+ xorl %ebp,%edx
+ addl %ebx,%eax
+ addl 48(%rsp),%ebp
+ pxor %xmm7,%xmm3
+.byte 102,68,15,58,15,193,8
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ pxor %xmm4,%xmm3
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ movdqa %xmm9,%xmm10
+ paddd %xmm2,%xmm9
+ rorl $7,%ebx
+ addl %esi,%ebp
+ pxor %xmm8,%xmm3
+ addl 52(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ movdqa %xmm3,%xmm8
+ movdqa %xmm9,32(%rsp)
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ pslld $2,%xmm3
+ addl 56(%rsp),%ecx
+ xorl %ebx,%esi
+ psrld $30,%xmm8
+ movl %edx,%edi
+ roll $5,%edx
+ xorl %eax,%esi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ por %xmm8,%xmm3
+ addl 60(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 0(%rsp),%eax
+ paddd %xmm3,%xmm10
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ movdqa %xmm10,48(%rsp)
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 4(%rsp),%ebp
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
addl %edi,%ebp
- xorl 32(%rsp),%eax
- roll $30,%r12d
- addl %ebx,%ebp
- roll $1,%eax
- movl %eax,44(%rsp)
- leal -899497514(%rax,%rsi,1),%edi
- movl 48(%rsp),%eax
- movl %r12d,%ebx
+ addl 8(%rsp),%edx
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 12(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ cmpq %r10,%r9
+ je L$done_ssse3
+ movdqa 64(%r11),%xmm6
+ movdqa 0(%r11),%xmm9
+ movdqu 0(%r9),%xmm0
+ movdqu 16(%r9),%xmm1
+ movdqu 32(%r9),%xmm2
+ movdqu 48(%r9),%xmm3
+.byte 102,15,56,0,198
+ addq $64,%r9
+ addl 16(%rsp),%ebx
+ xorl %eax,%esi
+.byte 102,15,56,0,206
+ movl %ecx,%edi
+ roll $5,%ecx
+ paddd %xmm9,%xmm0
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ movdqa %xmm0,0(%rsp)
+ addl 20(%rsp),%eax
+ xorl %ebp,%edi
+ psubd %xmm9,%xmm0
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 24(%rsp),%ebp
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ addl 28(%rsp),%edx
+ xorl %ecx,%edi
movl %ebp,%esi
- xorl 56(%rsp),%eax
- xorl %r11d,%ebx
- roll $5,%esi
- xorl 16(%rsp),%eax
- xorl %edx,%ebx
- addl %esi,%edi
- xorl 36(%rsp),%eax
- roll $30,%r11d
- addl %ebx,%edi
- roll $1,%eax
- movl %eax,48(%rsp)
- leal -899497514(%rax,%rdx,1),%esi
- movl 52(%rsp),%eax
- movl %r11d,%ebx
- movl %edi,%edx
- xorl 60(%rsp),%eax
- xorl %ebp,%ebx
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 32(%rsp),%ecx
+ xorl %ebx,%esi
+.byte 102,15,56,0,214
+ movl %edx,%edi
roll $5,%edx
- xorl 20(%rsp),%eax
- xorl %r12d,%ebx
- addl %edx,%esi
- xorl 40(%rsp),%eax
- roll $30,%ebp
- addl %ebx,%esi
- roll $1,%eax
- leal -899497514(%rax,%r12,1),%edx
- movl 56(%rsp),%eax
- movl %ebp,%ebx
- movl %esi,%r12d
- xorl 0(%rsp),%eax
- xorl %edi,%ebx
- roll $5,%r12d
- xorl 24(%rsp),%eax
- xorl %r11d,%ebx
- addl %r12d,%edx
- xorl 44(%rsp),%eax
- roll $30,%edi
- addl %ebx,%edx
- roll $1,%eax
- leal -899497514(%rax,%r11,1),%r12d
- movl 60(%rsp),%eax
- movl %edi,%ebx
- movl %edx,%r11d
- xorl 4(%rsp),%eax
- xorl %esi,%ebx
- roll $5,%r11d
- xorl 28(%rsp),%eax
- xorl %ebp,%ebx
- addl %r11d,%r12d
- xorl 48(%rsp),%eax
- roll $30,%esi
- addl %ebx,%r12d
- roll $1,%eax
- leal -899497514(%rax,%rbp,1),%r11d
- movl %esi,%ebx
- movl %r12d,%ebp
- xorl %edx,%ebx
+ paddd %xmm9,%xmm1
+ xorl %eax,%esi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ movdqa %xmm1,16(%rsp)
+ addl 36(%rsp),%ebx
+ xorl %eax,%edi
+ psubd %xmm9,%xmm1
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 40(%rsp),%eax
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 44(%rsp),%ebp
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 48(%rsp),%edx
+ xorl %ecx,%esi
+.byte 102,15,56,0,222
+ movl %ebp,%edi
roll $5,%ebp
- xorl %edi,%ebx
- addl %ebp,%r11d
- roll $30,%edx
- addl %ebx,%r11d
- addl 0(%r8),%r11d
- addl 4(%r8),%r12d
- addl 8(%r8),%edx
- addl 12(%r8),%esi
- addl 16(%r8),%edi
- movl %r11d,0(%r8)
- movl %r12d,4(%r8)
- movl %edx,8(%r8)
- movl %esi,12(%r8)
- movl %edi,16(%r8)
-
- xchgl %r11d,%edx
- xchgl %r12d,%esi
- xchgl %r11d,%edi
- xchgl %r12d,%ebp
+ paddd %xmm9,%xmm2
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ movdqa %xmm2,32(%rsp)
+ addl 52(%rsp),%ecx
+ xorl %ebx,%edi
+ psubd %xmm9,%xmm2
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 56(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 60(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 0(%r8),%eax
+ addl 4(%r8),%esi
+ addl 8(%r8),%ecx
+ addl 12(%r8),%edx
+ movl %eax,0(%r8)
+ addl 16(%r8),%ebp
+ movl %esi,4(%r8)
+ movl %esi,%ebx
+ movl %ecx,8(%r8)
+ movl %edx,12(%r8)
+ movl %ebp,16(%r8)
+ jmp L$oop_ssse3
- leaq 64(%r9),%r9
- subq $1,%r10
- jnz L$loop
- movq 64(%rsp),%rsi
- movq (%rsi),%r12
+.p2align 4
+L$done_ssse3:
+ addl 16(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 20(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 24(%rsp),%ebp
+ xorl %edx,%esi
+ movl %eax,%edi
+ roll $5,%eax
+ xorl %ecx,%esi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %esi,%ebp
+ addl 28(%rsp),%edx
+ xorl %ecx,%edi
+ movl %ebp,%esi
+ roll $5,%ebp
+ xorl %ebx,%edi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %edi,%edx
+ addl 32(%rsp),%ecx
+ xorl %ebx,%esi
+ movl %edx,%edi
+ roll $5,%edx
+ xorl %eax,%esi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %esi,%ecx
+ addl 36(%rsp),%ebx
+ xorl %eax,%edi
+ movl %ecx,%esi
+ roll $5,%ecx
+ xorl %ebp,%edi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %edi,%ebx
+ addl 40(%rsp),%eax
+ xorl %ebp,%esi
+ movl %ebx,%edi
+ roll $5,%ebx
+ xorl %edx,%esi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %esi,%eax
+ addl 44(%rsp),%ebp
+ xorl %edx,%edi
+ movl %eax,%esi
+ roll $5,%eax
+ xorl %ecx,%edi
+ addl %eax,%ebp
+ rorl $7,%ebx
+ addl %edi,%ebp
+ addl 48(%rsp),%edx
+ xorl %ecx,%esi
+ movl %ebp,%edi
+ roll $5,%ebp
+ xorl %ebx,%esi
+ addl %ebp,%edx
+ rorl $7,%eax
+ addl %esi,%edx
+ addl 52(%rsp),%ecx
+ xorl %ebx,%edi
+ movl %edx,%esi
+ roll $5,%edx
+ xorl %eax,%edi
+ addl %edx,%ecx
+ rorl $7,%ebp
+ addl %edi,%ecx
+ addl 56(%rsp),%ebx
+ xorl %eax,%esi
+ movl %ecx,%edi
+ roll $5,%ecx
+ xorl %ebp,%esi
+ addl %ecx,%ebx
+ rorl $7,%edx
+ addl %esi,%ebx
+ addl 60(%rsp),%eax
+ xorl %ebp,%edi
+ movl %ebx,%esi
+ roll $5,%ebx
+ xorl %edx,%edi
+ addl %ebx,%eax
+ rorl $7,%ecx
+ addl %edi,%eax
+ addl 0(%r8),%eax
+ addl 4(%r8),%esi
+ addl 8(%r8),%ecx
+ movl %eax,0(%r8)
+ addl 12(%r8),%edx
+ movl %esi,4(%r8)
+ addl 16(%r8),%ebp
+ movl %ecx,8(%r8)
+ movl %edx,12(%r8)
+ movl %ebp,16(%r8)
+ leaq 64(%rsp),%rsi
+ movq 0(%rsi),%r12
movq 8(%rsi),%rbp
movq 16(%rsi),%rbx
leaq 24(%rsi),%rsp
-L$epilogue:
+L$epilogue_ssse3:
.byte 0xf3,0xc3
+.p2align 6
+K_XX_XX:
+.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999
+
+.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1
+
+.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc
+
+.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6
+
+.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
+
.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-.p2align 4
+.p2align 6
diff --git a/deps/openssl/asm/x64-macosx-gas/sha/sha512-x86_64.s b/deps/openssl/asm/x64-macosx-gas/sha/sha512-x86_64.s
index 73c499030..dda5a96e9 100644
--- a/deps/openssl/asm/x64-macosx-gas/sha/sha512-x86_64.s
+++ b/deps/openssl/asm/x64-macosx-gas/sha/sha512-x86_64.s
@@ -38,1880 +38,1688 @@ L$prologue:
L$loop:
xorq %rdi,%rdi
movl 0(%rsi),%r12d
- bswapl %r12d
movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %eax,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r9d,%r15d
+ movl %r12d,0(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r11d,%r12d
+ xorl %eax,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r8d,%r15d
- movl %r12d,0(%rsp)
+ movl %ebx,%r11d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- addl %r11d,%r12d
-
- movl %eax,%r11d
- addl %r13d,%r12d
+ xorl %ecx,%r11d
+ xorl %eax,%r14d
addl %r15d,%r12d
- movl %eax,%r13d
- movl %eax,%r14d
+ movl %ebx,%r15d
- rorl $2,%r11d
- rorl $13,%r13d
- movl %eax,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %eax,%r11d
+ andl %ecx,%r15d
- xorl %r13d,%r11d
- rorl $9,%r13d
- orl %ecx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r11d
- xorl %r13d,%r11d
- andl %ecx,%r15d
addl %r12d,%edx
-
- andl %ebx,%r14d
addl %r12d,%r11d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r11d
+
movl 4(%rsi),%r12d
- bswapl %r12d
movl %edx,%r13d
- movl %edx,%r14d
+ movl %r11d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r8d,%r15d
+ movl %r12d,4(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r10d,%r12d
+ xorl %r11d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %edx,%r15d
- movl %r12d,4(%rsp)
+ movl %eax,%r10d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- addl %r10d,%r12d
-
- movl %r11d,%r10d
- addl %r13d,%r12d
+ xorl %ebx,%r10d
+ xorl %r11d,%r14d
addl %r15d,%r12d
- movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %eax,%r15d
- rorl $2,%r10d
- rorl $13,%r13d
- movl %r11d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r11d,%r10d
+ andl %ebx,%r15d
- xorl %r13d,%r10d
- rorl $9,%r13d
- orl %ebx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r10d
- xorl %r13d,%r10d
- andl %ebx,%r15d
addl %r12d,%ecx
-
- andl %eax,%r14d
addl %r12d,%r10d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r10d
+
movl 8(%rsi),%r12d
- bswapl %r12d
movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %r10d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %edx,%r15d
+ movl %r12d,8(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r9d,%r12d
+ xorl %r10d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ecx,%r15d
- movl %r12d,8(%rsp)
+ movl %r11d,%r9d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- addl %r9d,%r12d
-
- movl %r10d,%r9d
- addl %r13d,%r12d
+ xorl %eax,%r9d
+ xorl %r10d,%r14d
addl %r15d,%r12d
- movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %r11d,%r15d
- rorl $2,%r9d
- rorl $13,%r13d
- movl %r10d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r10d,%r9d
+ andl %eax,%r15d
- xorl %r13d,%r9d
- rorl $9,%r13d
- orl %eax,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r9d
- xorl %r13d,%r9d
- andl %eax,%r15d
addl %r12d,%ebx
-
- andl %r11d,%r14d
addl %r12d,%r9d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r9d
+
movl 12(%rsi),%r12d
- bswapl %r12d
movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %r9d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %ecx,%r15d
+ movl %r12d,12(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r8d,%r12d
+ xorl %r9d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ebx,%r15d
- movl %r12d,12(%rsp)
+ movl %r10d,%r8d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- addl %r8d,%r12d
-
- movl %r9d,%r8d
- addl %r13d,%r12d
+ xorl %r11d,%r8d
+ xorl %r9d,%r14d
addl %r15d,%r12d
- movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %r10d,%r15d
- rorl $2,%r8d
- rorl $13,%r13d
- movl %r9d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r9d,%r8d
+ andl %r11d,%r15d
- xorl %r13d,%r8d
- rorl $9,%r13d
- orl %r11d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r8d
- xorl %r13d,%r8d
- andl %r11d,%r15d
addl %r12d,%eax
-
- andl %r10d,%r14d
addl %r12d,%r8d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r8d
+
movl 16(%rsi),%r12d
- bswapl %r12d
movl %eax,%r13d
- movl %eax,%r14d
+ movl %r8d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %ebx,%r15d
+ movl %r12d,16(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %edx,%r12d
+ xorl %r8d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %eax,%r15d
- movl %r12d,16(%rsp)
+ movl %r9d,%edx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- addl %edx,%r12d
-
- movl %r8d,%edx
- addl %r13d,%r12d
+ xorl %r10d,%edx
+ xorl %r8d,%r14d
addl %r15d,%r12d
- movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %r9d,%r15d
- rorl $2,%edx
- rorl $13,%r13d
- movl %r8d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r8d,%edx
+ andl %r10d,%r15d
- xorl %r13d,%edx
- rorl $9,%r13d
- orl %r10d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%edx
- xorl %r13d,%edx
- andl %r10d,%r15d
addl %r12d,%r11d
-
- andl %r9d,%r14d
addl %r12d,%edx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%edx
+
movl 20(%rsi),%r12d
- bswapl %r12d
movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %edx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %eax,%r15d
+ movl %r12d,20(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ecx,%r12d
+ xorl %edx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r11d,%r15d
- movl %r12d,20(%rsp)
+ movl %r8d,%ecx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- addl %ecx,%r12d
-
- movl %edx,%ecx
- addl %r13d,%r12d
+ xorl %r9d,%ecx
+ xorl %edx,%r14d
addl %r15d,%r12d
- movl %edx,%r13d
- movl %edx,%r14d
+ movl %r8d,%r15d
- rorl $2,%ecx
- rorl $13,%r13d
- movl %edx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %edx,%ecx
+ andl %r9d,%r15d
- xorl %r13d,%ecx
- rorl $9,%r13d
- orl %r9d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ecx
- xorl %r13d,%ecx
- andl %r9d,%r15d
addl %r12d,%r10d
-
- andl %r8d,%r14d
addl %r12d,%ecx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ecx
+
movl 24(%rsi),%r12d
- bswapl %r12d
movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %ecx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r11d,%r15d
+ movl %r12d,24(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ebx,%r12d
+ xorl %ecx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r10d,%r15d
- movl %r12d,24(%rsp)
+ movl %edx,%ebx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- addl %ebx,%r12d
-
- movl %ecx,%ebx
- addl %r13d,%r12d
+ xorl %r8d,%ebx
+ xorl %ecx,%r14d
addl %r15d,%r12d
- movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %edx,%r15d
- rorl $2,%ebx
- rorl $13,%r13d
- movl %ecx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ecx,%ebx
+ andl %r8d,%r15d
- xorl %r13d,%ebx
- rorl $9,%r13d
- orl %r8d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ebx
- xorl %r13d,%ebx
- andl %r8d,%r15d
addl %r12d,%r9d
-
- andl %edx,%r14d
addl %r12d,%ebx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ebx
+
movl 28(%rsi),%r12d
- bswapl %r12d
movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %ebx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r10d,%r15d
+ movl %r12d,28(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %eax,%r12d
+ xorl %ebx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r9d,%r15d
- movl %r12d,28(%rsp)
+ movl %ecx,%eax
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- addl %eax,%r12d
-
- movl %ebx,%eax
- addl %r13d,%r12d
+ xorl %edx,%eax
+ xorl %ebx,%r14d
addl %r15d,%r12d
- movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %ecx,%r15d
- rorl $2,%eax
- rorl $13,%r13d
- movl %ebx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ebx,%eax
+ andl %edx,%r15d
- xorl %r13d,%eax
- rorl $9,%r13d
- orl %edx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%eax
- xorl %r13d,%eax
- andl %edx,%r15d
addl %r12d,%r8d
-
- andl %ecx,%r14d
addl %r12d,%eax
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%eax
+
movl 32(%rsi),%r12d
- bswapl %r12d
movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %eax,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r9d,%r15d
+ movl %r12d,32(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r11d,%r12d
+ xorl %eax,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r8d,%r15d
- movl %r12d,32(%rsp)
+ movl %ebx,%r11d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- addl %r11d,%r12d
-
- movl %eax,%r11d
- addl %r13d,%r12d
+ xorl %ecx,%r11d
+ xorl %eax,%r14d
addl %r15d,%r12d
- movl %eax,%r13d
- movl %eax,%r14d
+ movl %ebx,%r15d
- rorl $2,%r11d
- rorl $13,%r13d
- movl %eax,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %eax,%r11d
+ andl %ecx,%r15d
- xorl %r13d,%r11d
- rorl $9,%r13d
- orl %ecx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r11d
- xorl %r13d,%r11d
- andl %ecx,%r15d
addl %r12d,%edx
-
- andl %ebx,%r14d
addl %r12d,%r11d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r11d
+
movl 36(%rsi),%r12d
- bswapl %r12d
movl %edx,%r13d
- movl %edx,%r14d
+ movl %r11d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r8d,%r15d
+ movl %r12d,36(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r10d,%r12d
+ xorl %r11d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %edx,%r15d
- movl %r12d,36(%rsp)
+ movl %eax,%r10d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- addl %r10d,%r12d
-
- movl %r11d,%r10d
- addl %r13d,%r12d
+ xorl %ebx,%r10d
+ xorl %r11d,%r14d
addl %r15d,%r12d
- movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %eax,%r15d
- rorl $2,%r10d
- rorl $13,%r13d
- movl %r11d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r11d,%r10d
+ andl %ebx,%r15d
- xorl %r13d,%r10d
- rorl $9,%r13d
- orl %ebx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r10d
- xorl %r13d,%r10d
- andl %ebx,%r15d
addl %r12d,%ecx
-
- andl %eax,%r14d
addl %r12d,%r10d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r10d
+
movl 40(%rsi),%r12d
- bswapl %r12d
movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %r10d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %edx,%r15d
+ movl %r12d,40(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r9d,%r12d
+ xorl %r10d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ecx,%r15d
- movl %r12d,40(%rsp)
+ movl %r11d,%r9d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- addl %r9d,%r12d
-
- movl %r10d,%r9d
- addl %r13d,%r12d
+ xorl %eax,%r9d
+ xorl %r10d,%r14d
addl %r15d,%r12d
- movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %r11d,%r15d
- rorl $2,%r9d
- rorl $13,%r13d
- movl %r10d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r10d,%r9d
+ andl %eax,%r15d
- xorl %r13d,%r9d
- rorl $9,%r13d
- orl %eax,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r9d
- xorl %r13d,%r9d
- andl %eax,%r15d
addl %r12d,%ebx
-
- andl %r11d,%r14d
addl %r12d,%r9d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r9d
+
movl 44(%rsi),%r12d
- bswapl %r12d
movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %r9d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %ecx,%r15d
+ movl %r12d,44(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r8d,%r12d
+ xorl %r9d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ebx,%r15d
- movl %r12d,44(%rsp)
+ movl %r10d,%r8d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- addl %r8d,%r12d
-
- movl %r9d,%r8d
- addl %r13d,%r12d
+ xorl %r11d,%r8d
+ xorl %r9d,%r14d
addl %r15d,%r12d
- movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %r10d,%r15d
- rorl $2,%r8d
- rorl $13,%r13d
- movl %r9d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r9d,%r8d
+ andl %r11d,%r15d
- xorl %r13d,%r8d
- rorl $9,%r13d
- orl %r11d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r8d
- xorl %r13d,%r8d
- andl %r11d,%r15d
addl %r12d,%eax
-
- andl %r10d,%r14d
addl %r12d,%r8d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r8d
+
movl 48(%rsi),%r12d
- bswapl %r12d
movl %eax,%r13d
- movl %eax,%r14d
+ movl %r8d,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %ebx,%r15d
+ movl %r12d,48(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %edx,%r12d
+ xorl %r8d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %eax,%r15d
- movl %r12d,48(%rsp)
+ movl %r9d,%edx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- addl %edx,%r12d
-
- movl %r8d,%edx
- addl %r13d,%r12d
+ xorl %r10d,%edx
+ xorl %r8d,%r14d
addl %r15d,%r12d
- movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %r9d,%r15d
- rorl $2,%edx
- rorl $13,%r13d
- movl %r8d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r8d,%edx
+ andl %r10d,%r15d
- xorl %r13d,%edx
- rorl $9,%r13d
- orl %r10d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%edx
- xorl %r13d,%edx
- andl %r10d,%r15d
addl %r12d,%r11d
-
- andl %r9d,%r14d
addl %r12d,%edx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%edx
+
movl 52(%rsi),%r12d
- bswapl %r12d
movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %edx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %eax,%r15d
+ movl %r12d,52(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ecx,%r12d
+ xorl %edx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r11d,%r15d
- movl %r12d,52(%rsp)
+ movl %r8d,%ecx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- addl %ecx,%r12d
-
- movl %edx,%ecx
- addl %r13d,%r12d
+ xorl %r9d,%ecx
+ xorl %edx,%r14d
addl %r15d,%r12d
- movl %edx,%r13d
- movl %edx,%r14d
+ movl %r8d,%r15d
- rorl $2,%ecx
- rorl $13,%r13d
- movl %edx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %edx,%ecx
+ andl %r9d,%r15d
- xorl %r13d,%ecx
- rorl $9,%r13d
- orl %r9d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ecx
- xorl %r13d,%ecx
- andl %r9d,%r15d
addl %r12d,%r10d
-
- andl %r8d,%r14d
addl %r12d,%ecx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ecx
+
movl 56(%rsi),%r12d
- bswapl %r12d
movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %ecx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r11d,%r15d
+ movl %r12d,56(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ebx,%r12d
+ xorl %ecx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r10d,%r15d
- movl %r12d,56(%rsp)
+ movl %edx,%ebx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- addl %ebx,%r12d
-
- movl %ecx,%ebx
- addl %r13d,%r12d
+ xorl %r8d,%ebx
+ xorl %ecx,%r14d
addl %r15d,%r12d
- movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %edx,%r15d
- rorl $2,%ebx
- rorl $13,%r13d
- movl %ecx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ecx,%ebx
+ andl %r8d,%r15d
- xorl %r13d,%ebx
- rorl $9,%r13d
- orl %r8d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ebx
- xorl %r13d,%ebx
- andl %r8d,%r15d
addl %r12d,%r9d
-
- andl %edx,%r14d
addl %r12d,%ebx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ebx
+
movl 60(%rsi),%r12d
- bswapl %r12d
movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %ebx,%r14d
+ bswapl %r12d
+ rorl $14,%r13d
movl %r10d,%r15d
+ movl %r12d,60(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %eax,%r12d
+ xorl %ebx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r9d,%r15d
- movl %r12d,60(%rsp)
+ movl %ecx,%eax
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- addl %eax,%r12d
-
- movl %ebx,%eax
- addl %r13d,%r12d
+ xorl %edx,%eax
+ xorl %ebx,%r14d
addl %r15d,%r12d
- movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %ecx,%r15d
- rorl $2,%eax
- rorl $13,%r13d
- movl %ebx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ebx,%eax
+ andl %edx,%r15d
- xorl %r13d,%eax
- rorl $9,%r13d
- orl %edx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%eax
- xorl %r13d,%eax
- andl %edx,%r15d
addl %r12d,%r8d
-
- andl %ecx,%r14d
addl %r12d,%eax
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%eax
+
jmp L$rounds_16_xx
.p2align 4
L$rounds_16_xx:
movl 4(%rsp),%r13d
- movl 56(%rsp),%r12d
-
- movl %r13d,%r15d
+ movl 56(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 36(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 36(%rsp),%r12d
+ xorl %r15d,%r14d
addl 0(%rsp),%r12d
movl %r8d,%r13d
- movl %r8d,%r14d
+ addl %r14d,%r12d
+ movl %eax,%r14d
+ rorl $14,%r13d
movl %r9d,%r15d
+ movl %r12d,0(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r11d,%r12d
+ xorl %eax,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r8d,%r15d
- movl %r12d,0(%rsp)
+ movl %ebx,%r11d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- addl %r11d,%r12d
-
- movl %eax,%r11d
- addl %r13d,%r12d
+ xorl %ecx,%r11d
+ xorl %eax,%r14d
addl %r15d,%r12d
- movl %eax,%r13d
- movl %eax,%r14d
+ movl %ebx,%r15d
- rorl $2,%r11d
- rorl $13,%r13d
- movl %eax,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %eax,%r11d
+ andl %ecx,%r15d
- xorl %r13d,%r11d
- rorl $9,%r13d
- orl %ecx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r11d
- xorl %r13d,%r11d
- andl %ecx,%r15d
addl %r12d,%edx
-
- andl %ebx,%r14d
addl %r12d,%r11d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r11d
- movl 8(%rsp),%r13d
- movl 60(%rsp),%r12d
- movl %r13d,%r15d
+ movl 8(%rsp),%r13d
+ movl 60(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 40(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 40(%rsp),%r12d
+ xorl %r15d,%r14d
addl 4(%rsp),%r12d
movl %edx,%r13d
- movl %edx,%r14d
+ addl %r14d,%r12d
+ movl %r11d,%r14d
+ rorl $14,%r13d
movl %r8d,%r15d
+ movl %r12d,4(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r10d,%r12d
+ xorl %r11d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %edx,%r15d
- movl %r12d,4(%rsp)
+ movl %eax,%r10d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- addl %r10d,%r12d
-
- movl %r11d,%r10d
- addl %r13d,%r12d
+ xorl %ebx,%r10d
+ xorl %r11d,%r14d
addl %r15d,%r12d
- movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %eax,%r15d
- rorl $2,%r10d
- rorl $13,%r13d
- movl %r11d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r11d,%r10d
+ andl %ebx,%r15d
- xorl %r13d,%r10d
- rorl $9,%r13d
- orl %ebx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r10d
- xorl %r13d,%r10d
- andl %ebx,%r15d
addl %r12d,%ecx
-
- andl %eax,%r14d
addl %r12d,%r10d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r10d
- movl 12(%rsp),%r13d
- movl 0(%rsp),%r12d
- movl %r13d,%r15d
+ movl 12(%rsp),%r13d
+ movl 0(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 44(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 44(%rsp),%r12d
+ xorl %r15d,%r14d
addl 8(%rsp),%r12d
movl %ecx,%r13d
- movl %ecx,%r14d
+ addl %r14d,%r12d
+ movl %r10d,%r14d
+ rorl $14,%r13d
movl %edx,%r15d
+ movl %r12d,8(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r9d,%r12d
+ xorl %r10d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ecx,%r15d
- movl %r12d,8(%rsp)
+ movl %r11d,%r9d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- addl %r9d,%r12d
-
- movl %r10d,%r9d
- addl %r13d,%r12d
+ xorl %eax,%r9d
+ xorl %r10d,%r14d
addl %r15d,%r12d
- movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %r11d,%r15d
- rorl $2,%r9d
- rorl $13,%r13d
- movl %r10d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r10d,%r9d
+ andl %eax,%r15d
- xorl %r13d,%r9d
- rorl $9,%r13d
- orl %eax,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r9d
- xorl %r13d,%r9d
- andl %eax,%r15d
addl %r12d,%ebx
-
- andl %r11d,%r14d
addl %r12d,%r9d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r9d
- movl 16(%rsp),%r13d
- movl 4(%rsp),%r12d
- movl %r13d,%r15d
+ movl 16(%rsp),%r13d
+ movl 4(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 48(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 48(%rsp),%r12d
+ xorl %r15d,%r14d
addl 12(%rsp),%r12d
movl %ebx,%r13d
- movl %ebx,%r14d
+ addl %r14d,%r12d
+ movl %r9d,%r14d
+ rorl $14,%r13d
movl %ecx,%r15d
+ movl %r12d,12(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r8d,%r12d
+ xorl %r9d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ebx,%r15d
- movl %r12d,12(%rsp)
+ movl %r10d,%r8d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- addl %r8d,%r12d
-
- movl %r9d,%r8d
- addl %r13d,%r12d
+ xorl %r11d,%r8d
+ xorl %r9d,%r14d
addl %r15d,%r12d
- movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %r10d,%r15d
- rorl $2,%r8d
- rorl $13,%r13d
- movl %r9d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r9d,%r8d
+ andl %r11d,%r15d
- xorl %r13d,%r8d
- rorl $9,%r13d
- orl %r11d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r8d
- xorl %r13d,%r8d
- andl %r11d,%r15d
addl %r12d,%eax
-
- andl %r10d,%r14d
addl %r12d,%r8d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r8d
- movl 20(%rsp),%r13d
- movl 8(%rsp),%r12d
- movl %r13d,%r15d
+ movl 20(%rsp),%r13d
+ movl 8(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 52(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 52(%rsp),%r12d
+ xorl %r15d,%r14d
addl 16(%rsp),%r12d
movl %eax,%r13d
- movl %eax,%r14d
+ addl %r14d,%r12d
+ movl %r8d,%r14d
+ rorl $14,%r13d
movl %ebx,%r15d
+ movl %r12d,16(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %edx,%r12d
+ xorl %r8d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %eax,%r15d
- movl %r12d,16(%rsp)
+ movl %r9d,%edx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- addl %edx,%r12d
-
- movl %r8d,%edx
- addl %r13d,%r12d
+ xorl %r10d,%edx
+ xorl %r8d,%r14d
addl %r15d,%r12d
- movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %r9d,%r15d
- rorl $2,%edx
- rorl $13,%r13d
- movl %r8d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r8d,%edx
+ andl %r10d,%r15d
- xorl %r13d,%edx
- rorl $9,%r13d
- orl %r10d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%edx
- xorl %r13d,%edx
- andl %r10d,%r15d
addl %r12d,%r11d
-
- andl %r9d,%r14d
addl %r12d,%edx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%edx
- movl 24(%rsp),%r13d
- movl 12(%rsp),%r12d
- movl %r13d,%r15d
+ movl 24(%rsp),%r13d
+ movl 12(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 56(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 56(%rsp),%r12d
+ xorl %r15d,%r14d
addl 20(%rsp),%r12d
movl %r11d,%r13d
- movl %r11d,%r14d
+ addl %r14d,%r12d
+ movl %edx,%r14d
+ rorl $14,%r13d
movl %eax,%r15d
+ movl %r12d,20(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ecx,%r12d
+ xorl %edx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r11d,%r15d
- movl %r12d,20(%rsp)
+ movl %r8d,%ecx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- addl %ecx,%r12d
-
- movl %edx,%ecx
- addl %r13d,%r12d
+ xorl %r9d,%ecx
+ xorl %edx,%r14d
addl %r15d,%r12d
- movl %edx,%r13d
- movl %edx,%r14d
+ movl %r8d,%r15d
- rorl $2,%ecx
- rorl $13,%r13d
- movl %edx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %edx,%ecx
+ andl %r9d,%r15d
- xorl %r13d,%ecx
- rorl $9,%r13d
- orl %r9d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ecx
- xorl %r13d,%ecx
- andl %r9d,%r15d
addl %r12d,%r10d
-
- andl %r8d,%r14d
addl %r12d,%ecx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ecx
- movl 28(%rsp),%r13d
- movl 16(%rsp),%r12d
- movl %r13d,%r15d
+ movl 28(%rsp),%r13d
+ movl 16(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 60(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 60(%rsp),%r12d
+ xorl %r15d,%r14d
addl 24(%rsp),%r12d
movl %r10d,%r13d
- movl %r10d,%r14d
+ addl %r14d,%r12d
+ movl %ecx,%r14d
+ rorl $14,%r13d
movl %r11d,%r15d
+ movl %r12d,24(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ebx,%r12d
+ xorl %ecx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r10d,%r15d
- movl %r12d,24(%rsp)
+ movl %edx,%ebx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- addl %ebx,%r12d
-
- movl %ecx,%ebx
- addl %r13d,%r12d
+ xorl %r8d,%ebx
+ xorl %ecx,%r14d
addl %r15d,%r12d
- movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %edx,%r15d
- rorl $2,%ebx
- rorl $13,%r13d
- movl %ecx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ecx,%ebx
+ andl %r8d,%r15d
- xorl %r13d,%ebx
- rorl $9,%r13d
- orl %r8d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ebx
- xorl %r13d,%ebx
- andl %r8d,%r15d
addl %r12d,%r9d
-
- andl %edx,%r14d
addl %r12d,%ebx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ebx
- movl 32(%rsp),%r13d
- movl 20(%rsp),%r12d
- movl %r13d,%r15d
+ movl 32(%rsp),%r13d
+ movl 20(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 0(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 0(%rsp),%r12d
+ xorl %r15d,%r14d
addl 28(%rsp),%r12d
movl %r9d,%r13d
- movl %r9d,%r14d
+ addl %r14d,%r12d
+ movl %ebx,%r14d
+ rorl $14,%r13d
movl %r10d,%r15d
+ movl %r12d,28(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %eax,%r12d
+ xorl %ebx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r9d,%r15d
- movl %r12d,28(%rsp)
+ movl %ecx,%eax
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- addl %eax,%r12d
-
- movl %ebx,%eax
- addl %r13d,%r12d
+ xorl %edx,%eax
+ xorl %ebx,%r14d
addl %r15d,%r12d
- movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %ecx,%r15d
- rorl $2,%eax
- rorl $13,%r13d
- movl %ebx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ebx,%eax
+ andl %edx,%r15d
- xorl %r13d,%eax
- rorl $9,%r13d
- orl %edx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%eax
- xorl %r13d,%eax
- andl %edx,%r15d
addl %r12d,%r8d
-
- andl %ecx,%r14d
addl %r12d,%eax
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%eax
- movl 36(%rsp),%r13d
- movl 24(%rsp),%r12d
- movl %r13d,%r15d
+ movl 36(%rsp),%r13d
+ movl 24(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 4(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 4(%rsp),%r12d
+ xorl %r15d,%r14d
addl 32(%rsp),%r12d
movl %r8d,%r13d
- movl %r8d,%r14d
+ addl %r14d,%r12d
+ movl %eax,%r14d
+ rorl $14,%r13d
movl %r9d,%r15d
+ movl %r12d,32(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r11d,%r12d
+ xorl %eax,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r8d,%r15d
- movl %r12d,32(%rsp)
+ movl %ebx,%r11d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r8d,%r13d
xorl %r10d,%r15d
- addl %r11d,%r12d
-
- movl %eax,%r11d
- addl %r13d,%r12d
+ xorl %ecx,%r11d
+ xorl %eax,%r14d
addl %r15d,%r12d
- movl %eax,%r13d
- movl %eax,%r14d
+ movl %ebx,%r15d
- rorl $2,%r11d
- rorl $13,%r13d
- movl %eax,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %eax,%r11d
+ andl %ecx,%r15d
- xorl %r13d,%r11d
- rorl $9,%r13d
- orl %ecx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r11d
- xorl %r13d,%r11d
- andl %ecx,%r15d
addl %r12d,%edx
-
- andl %ebx,%r14d
addl %r12d,%r11d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r11d
- movl 40(%rsp),%r13d
- movl 28(%rsp),%r12d
- movl %r13d,%r15d
+ movl 40(%rsp),%r13d
+ movl 28(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 8(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 8(%rsp),%r12d
+ xorl %r15d,%r14d
addl 36(%rsp),%r12d
movl %edx,%r13d
- movl %edx,%r14d
+ addl %r14d,%r12d
+ movl %r11d,%r14d
+ rorl $14,%r13d
movl %r8d,%r15d
+ movl %r12d,36(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r10d,%r12d
+ xorl %r11d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %edx,%r15d
- movl %r12d,36(%rsp)
+ movl %eax,%r10d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %edx,%r13d
xorl %r9d,%r15d
- addl %r10d,%r12d
-
- movl %r11d,%r10d
- addl %r13d,%r12d
+ xorl %ebx,%r10d
+ xorl %r11d,%r14d
addl %r15d,%r12d
- movl %r11d,%r13d
- movl %r11d,%r14d
+ movl %eax,%r15d
- rorl $2,%r10d
- rorl $13,%r13d
- movl %r11d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r11d,%r10d
+ andl %ebx,%r15d
- xorl %r13d,%r10d
- rorl $9,%r13d
- orl %ebx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r10d
- xorl %r13d,%r10d
- andl %ebx,%r15d
addl %r12d,%ecx
-
- andl %eax,%r14d
addl %r12d,%r10d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r10d
- movl 44(%rsp),%r13d
- movl 32(%rsp),%r12d
- movl %r13d,%r15d
+ movl 44(%rsp),%r13d
+ movl 32(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 12(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 12(%rsp),%r12d
+ xorl %r15d,%r14d
addl 40(%rsp),%r12d
movl %ecx,%r13d
- movl %ecx,%r14d
+ addl %r14d,%r12d
+ movl %r10d,%r14d
+ rorl $14,%r13d
movl %edx,%r15d
+ movl %r12d,40(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r9d,%r12d
+ xorl %r10d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ecx,%r15d
- movl %r12d,40(%rsp)
+ movl %r11d,%r9d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ecx,%r13d
xorl %r8d,%r15d
- addl %r9d,%r12d
-
- movl %r10d,%r9d
- addl %r13d,%r12d
+ xorl %eax,%r9d
+ xorl %r10d,%r14d
addl %r15d,%r12d
- movl %r10d,%r13d
- movl %r10d,%r14d
+ movl %r11d,%r15d
- rorl $2,%r9d
- rorl $13,%r13d
- movl %r10d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r10d,%r9d
+ andl %eax,%r15d
- xorl %r13d,%r9d
- rorl $9,%r13d
- orl %eax,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r9d
- xorl %r13d,%r9d
- andl %eax,%r15d
addl %r12d,%ebx
-
- andl %r11d,%r14d
addl %r12d,%r9d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r9d
- movl 48(%rsp),%r13d
- movl 36(%rsp),%r12d
- movl %r13d,%r15d
+ movl 48(%rsp),%r13d
+ movl 36(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 16(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 16(%rsp),%r12d
+ xorl %r15d,%r14d
addl 44(%rsp),%r12d
movl %ebx,%r13d
- movl %ebx,%r14d
+ addl %r14d,%r12d
+ movl %r9d,%r14d
+ rorl $14,%r13d
movl %ecx,%r15d
+ movl %r12d,44(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %r8d,%r12d
+ xorl %r9d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %ebx,%r15d
- movl %r12d,44(%rsp)
+ movl %r10d,%r8d
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %ebx,%r13d
xorl %edx,%r15d
- addl %r8d,%r12d
-
- movl %r9d,%r8d
- addl %r13d,%r12d
+ xorl %r11d,%r8d
+ xorl %r9d,%r14d
addl %r15d,%r12d
- movl %r9d,%r13d
- movl %r9d,%r14d
+ movl %r10d,%r15d
- rorl $2,%r8d
- rorl $13,%r13d
- movl %r9d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r9d,%r8d
+ andl %r11d,%r15d
- xorl %r13d,%r8d
- rorl $9,%r13d
- orl %r11d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%r8d
- xorl %r13d,%r8d
- andl %r11d,%r15d
addl %r12d,%eax
-
- andl %r10d,%r14d
addl %r12d,%r8d
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%r8d
- movl 52(%rsp),%r13d
- movl 40(%rsp),%r12d
- movl %r13d,%r15d
+ movl 52(%rsp),%r13d
+ movl 40(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 20(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 20(%rsp),%r12d
+ xorl %r15d,%r14d
addl 48(%rsp),%r12d
movl %eax,%r13d
- movl %eax,%r14d
+ addl %r14d,%r12d
+ movl %r8d,%r14d
+ rorl $14,%r13d
movl %ebx,%r15d
+ movl %r12d,48(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %edx,%r12d
+ xorl %r8d,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %eax,%r15d
- movl %r12d,48(%rsp)
+ movl %r9d,%edx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %eax,%r13d
xorl %ecx,%r15d
- addl %edx,%r12d
-
- movl %r8d,%edx
- addl %r13d,%r12d
+ xorl %r10d,%edx
+ xorl %r8d,%r14d
addl %r15d,%r12d
- movl %r8d,%r13d
- movl %r8d,%r14d
+ movl %r9d,%r15d
- rorl $2,%edx
- rorl $13,%r13d
- movl %r8d,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %r8d,%edx
+ andl %r10d,%r15d
- xorl %r13d,%edx
- rorl $9,%r13d
- orl %r10d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%edx
- xorl %r13d,%edx
- andl %r10d,%r15d
addl %r12d,%r11d
-
- andl %r9d,%r14d
addl %r12d,%edx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%edx
- movl 56(%rsp),%r13d
- movl 44(%rsp),%r12d
- movl %r13d,%r15d
+ movl 56(%rsp),%r13d
+ movl 44(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 24(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 24(%rsp),%r12d
+ xorl %r15d,%r14d
addl 52(%rsp),%r12d
movl %r11d,%r13d
- movl %r11d,%r14d
+ addl %r14d,%r12d
+ movl %edx,%r14d
+ rorl $14,%r13d
movl %eax,%r15d
+ movl %r12d,52(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ecx,%r12d
+ xorl %edx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r11d,%r15d
- movl %r12d,52(%rsp)
+ movl %r8d,%ecx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r11d,%r13d
xorl %ebx,%r15d
- addl %ecx,%r12d
-
- movl %edx,%ecx
- addl %r13d,%r12d
+ xorl %r9d,%ecx
+ xorl %edx,%r14d
addl %r15d,%r12d
- movl %edx,%r13d
- movl %edx,%r14d
+ movl %r8d,%r15d
- rorl $2,%ecx
- rorl $13,%r13d
- movl %edx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %edx,%ecx
+ andl %r9d,%r15d
- xorl %r13d,%ecx
- rorl $9,%r13d
- orl %r9d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ecx
- xorl %r13d,%ecx
- andl %r9d,%r15d
addl %r12d,%r10d
-
- andl %r8d,%r14d
addl %r12d,%ecx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ecx
- movl 60(%rsp),%r13d
- movl 48(%rsp),%r12d
- movl %r13d,%r15d
+ movl 60(%rsp),%r13d
+ movl 48(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
- xorl %r15d,%r13d
- movl %r12d,%r14d
-
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 28(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 28(%rsp),%r12d
+ xorl %r15d,%r14d
addl 56(%rsp),%r12d
movl %r10d,%r13d
- movl %r10d,%r14d
+ addl %r14d,%r12d
+ movl %ecx,%r14d
+ rorl $14,%r13d
movl %r11d,%r15d
+ movl %r12d,56(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %ebx,%r12d
+ xorl %ecx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r10d,%r15d
- movl %r12d,56(%rsp)
+ movl %edx,%ebx
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r10d,%r13d
xorl %eax,%r15d
- addl %ebx,%r12d
-
- movl %ecx,%ebx
- addl %r13d,%r12d
+ xorl %r8d,%ebx
+ xorl %ecx,%r14d
addl %r15d,%r12d
- movl %ecx,%r13d
- movl %ecx,%r14d
+ movl %edx,%r15d
- rorl $2,%ebx
- rorl $13,%r13d
- movl %ecx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ecx,%ebx
+ andl %r8d,%r15d
- xorl %r13d,%ebx
- rorl $9,%r13d
- orl %r8d,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%ebx
- xorl %r13d,%ebx
- andl %r8d,%r15d
addl %r12d,%r9d
-
- andl %edx,%r14d
addl %r12d,%ebx
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%ebx
- movl 0(%rsp),%r13d
- movl 52(%rsp),%r12d
- movl %r13d,%r15d
+ movl 0(%rsp),%r13d
+ movl 52(%rsp),%r14d
+ movl %r13d,%r12d
+ movl %r14d,%r15d
+ rorl $11,%r12d
+ xorl %r13d,%r12d
shrl $3,%r13d
- rorl $7,%r15d
-
- xorl %r15d,%r13d
- rorl $11,%r15d
-
- xorl %r15d,%r13d
- movl %r12d,%r14d
- shrl $10,%r12d
- rorl $17,%r14d
-
- xorl %r14d,%r12d
- rorl $2,%r14d
+ rorl $7,%r12d
+ xorl %r12d,%r13d
+ movl 32(%rsp),%r12d
- xorl %r14d,%r12d
+ rorl $2,%r15d
+ xorl %r14d,%r15d
+ shrl $10,%r14d
+ rorl $17,%r15d
addl %r13d,%r12d
-
- addl 32(%rsp),%r12d
+ xorl %r15d,%r14d
addl 60(%rsp),%r12d
movl %r9d,%r13d
- movl %r9d,%r14d
+ addl %r14d,%r12d
+ movl %ebx,%r14d
+ rorl $14,%r13d
movl %r10d,%r15d
+ movl %r12d,60(%rsp)
- rorl $6,%r13d
- rorl $11,%r14d
+ rorl $9,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- xorl %r14d,%r13d
- rorl $14,%r14d
+ rorl $5,%r13d
+ addl %eax,%r12d
+ xorl %ebx,%r14d
+
+ addl (%rbp,%rdi,4),%r12d
andl %r9d,%r15d
- movl %r12d,60(%rsp)
+ movl %ecx,%eax
- xorl %r14d,%r13d
+ rorl $11,%r14d
+ xorl %r9d,%r13d
xorl %r11d,%r15d
- addl %eax,%r12d
-
- movl %ebx,%eax
- addl %r13d,%r12d
+ xorl %edx,%eax
+ xorl %ebx,%r14d
addl %r15d,%r12d
- movl %ebx,%r13d
- movl %ebx,%r14d
+ movl %ecx,%r15d
- rorl $2,%eax
- rorl $13,%r13d
- movl %ebx,%r15d
- addl (%rbp,%rdi,4),%r12d
+ rorl $6,%r13d
+ andl %ebx,%eax
+ andl %edx,%r15d
- xorl %r13d,%eax
- rorl $9,%r13d
- orl %edx,%r14d
+ rorl $2,%r14d
+ addl %r13d,%r12d
+ addl %r15d,%eax
- xorl %r13d,%eax
- andl %edx,%r15d
addl %r12d,%r8d
-
- andl %ecx,%r14d
addl %r12d,%eax
-
- orl %r15d,%r14d
leaq 1(%rdi),%rdi
-
addl %r14d,%eax
+
cmpq $64,%rdi
jb L$rounds_16_xx
diff --git a/deps/openssl/asm/x64-macosx-gas/x86_64cpuid.s b/deps/openssl/asm/x64-macosx-gas/x86_64cpuid.s
index a1670e38e..21e8a8fc2 100644
--- a/deps/openssl/asm/x64-macosx-gas/x86_64cpuid.s
+++ b/deps/openssl/asm/x64-macosx-gas/x86_64cpuid.s
@@ -1,8 +1,12 @@
+.private_extern _OPENSSL_cpuid_setup
.mod_init_func
.p2align 3
.quad _OPENSSL_cpuid_setup
+.private_extern _OPENSSL_ia32cap_P
+.comm _OPENSSL_ia32cap_P,8,2
+
.text
@@ -68,7 +72,15 @@ _OPENSSL_ia32_cpuid:
movl $2147483648,%eax
cpuid
- cmpl $2147483656,%eax
+ cmpl $2147483649,%eax
+ jb L$intel
+ movl %eax,%r10d
+ movl $2147483649,%eax
+ cpuid
+ orl %ecx,%r9d
+ andl $2049,%r9d
+
+ cmpl $2147483656,%r10d
jb L$intel
movl $2147483656,%eax
@@ -79,12 +91,12 @@ _OPENSSL_ia32_cpuid:
movl $1,%eax
cpuid
btl $28,%edx
- jnc L$done
+ jnc L$generic
shrl $16,%ebx
cmpb %r10b,%bl
- ja L$done
+ ja L$generic
andl $4026531839,%edx
- jmp L$done
+ jmp L$generic
L$intel:
cmpl $4,%r11d
@@ -101,30 +113,48 @@ L$intel:
L$nocacheinfo:
movl $1,%eax
cpuid
+ andl $3220176895,%edx
cmpl $0,%r9d
jne L$notintel
- orl $1048576,%edx
+ orl $1073741824,%edx
andb $15,%ah
cmpb $15,%ah
- je L$notintel
- orl $1073741824,%edx
+ jne L$notintel
+ orl $1048576,%edx
L$notintel:
btl $28,%edx
- jnc L$done
+ jnc L$generic
andl $4026531839,%edx
cmpl $0,%r10d
- je L$done
+ je L$generic
orl $268435456,%edx
shrl $16,%ebx
cmpb $1,%bl
- ja L$done
+ ja L$generic
andl $4026531839,%edx
+L$generic:
+ andl $2048,%r9d
+ andl $4294965247,%ecx
+ orl %ecx,%r9d
+
+ movl %edx,%r10d
+ btl $27,%r9d
+ jnc L$clear_avx
+ xorl %ecx,%ecx
+.byte 0x0f,0x01,0xd0
+
+ andl $6,%eax
+ cmpl $6,%eax
+ je L$done
+L$clear_avx:
+ movl $4026525695,%eax
+ andl %eax,%r9d
L$done:
- shlq $32,%rcx
- movl %edx,%eax
+ shlq $32,%r9
+ movl %r10d,%eax
movq %r8,%rbx
- orq %rcx,%rax
+ orq %r9,%rax
.byte 0xf3,0xc3
@@ -193,3 +223,16 @@ _OPENSSL_wipe_cpu:
leaq 8(%rsp),%rax
.byte 0xf3,0xc3
+.globl _OPENSSL_ia32_rdrand
+
+.p2align 4
+_OPENSSL_ia32_rdrand:
+ movl $8,%ecx
+L$oop_rdrand:
+.byte 72,15,199,240
+ jc L$break_rdrand
+ loop L$oop_rdrand
+L$break_rdrand:
+ cmpq $0,%rax
+ cmoveq %rcx,%rax
+ .byte 0xf3,0xc3
diff --git a/deps/openssl/asm/x64-win32-masm/aes/aes-x86_64.asm b/deps/openssl/asm/x64-win32-masm/aes/aes-x86_64.asm
index 2c590b94f..b9f6fd081 100644
--- a/deps/openssl/asm/x64-win32-masm/aes/aes-x86_64.asm
+++ b/deps/openssl/asm/x64-win32-masm/aes/aes-x86_64.asm
@@ -333,6 +333,9 @@ _x86_64_AES_encrypt_compact ENDP
PUBLIC AES_encrypt
ALIGN 16
+PUBLIC asm_AES_encrypt
+
+asm_AES_encrypt::
AES_encrypt PROC PUBLIC
mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
mov QWORD PTR[16+rsp],rsi
@@ -792,6 +795,9 @@ _x86_64_AES_decrypt_compact ENDP
PUBLIC AES_decrypt
ALIGN 16
+PUBLIC asm_AES_decrypt
+
+asm_AES_decrypt::
AES_decrypt PROC PUBLIC
mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
mov QWORD PTR[16+rsp],rsi
@@ -867,14 +873,14 @@ $L$dec_epilogue::
DB 0F3h,0C3h ;repret
$L$SEH_end_AES_decrypt::
AES_decrypt ENDP
-PUBLIC AES_set_encrypt_key
+PUBLIC private_AES_set_encrypt_key
ALIGN 16
-AES_set_encrypt_key PROC PUBLIC
+private_AES_set_encrypt_key PROC PUBLIC
mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
mov QWORD PTR[16+rsp],rsi
mov rax,rsp
-$L$SEH_begin_AES_set_encrypt_key::
+$L$SEH_begin_private_AES_set_encrypt_key::
mov rdi,rcx
mov rsi,rdx
mov rdx,r8
@@ -902,8 +908,8 @@ $L$enc_key_epilogue::
mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
mov rsi,QWORD PTR[16+rsp]
DB 0F3h,0C3h ;repret
-$L$SEH_end_AES_set_encrypt_key::
-AES_set_encrypt_key ENDP
+$L$SEH_end_private_AES_set_encrypt_key::
+private_AES_set_encrypt_key ENDP
ALIGN 16
@@ -1145,14 +1151,14 @@ $L$exit::
DB 0f3h,0c3h
_x86_64_AES_set_encrypt_key ENDP
-PUBLIC AES_set_decrypt_key
+PUBLIC private_AES_set_decrypt_key
ALIGN 16
-AES_set_decrypt_key PROC PUBLIC
+private_AES_set_decrypt_key PROC PUBLIC
mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
mov QWORD PTR[16+rsp],rsi
mov rax,rsp
-$L$SEH_begin_AES_set_decrypt_key::
+$L$SEH_begin_private_AES_set_decrypt_key::
mov rdi,rcx
mov rsi,rdx
mov rdx,r8
@@ -1342,12 +1348,15 @@ $L$dec_key_epilogue::
mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
mov rsi,QWORD PTR[16+rsp]
DB 0F3h,0C3h ;repret
-$L$SEH_end_AES_set_decrypt_key::
-AES_set_decrypt_key ENDP
+$L$SEH_end_private_AES_set_decrypt_key::
+private_AES_set_decrypt_key ENDP
PUBLIC AES_cbc_encrypt
ALIGN 16
EXTERN OPENSSL_ia32cap_P:NEAR
+PUBLIC asm_AES_cbc_encrypt
+
+asm_AES_cbc_encrypt::
AES_cbc_encrypt PROC PUBLIC
mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
mov QWORD PTR[16+rsp],rsi
@@ -2842,13 +2851,13 @@ ALIGN 4
DD imagerel $L$SEH_end_AES_decrypt
DD imagerel $L$SEH_info_AES_decrypt
- DD imagerel $L$SEH_begin_AES_set_encrypt_key
- DD imagerel $L$SEH_end_AES_set_encrypt_key
- DD imagerel $L$SEH_info_AES_set_encrypt_key
+ DD imagerel $L$SEH_begin_private_AES_set_encrypt_key
+ DD imagerel $L$SEH_end_private_AES_set_encrypt_key
+ DD imagerel $L$SEH_info_private_AES_set_encrypt_key
- DD imagerel $L$SEH_begin_AES_set_decrypt_key
- DD imagerel $L$SEH_end_AES_set_decrypt_key
- DD imagerel $L$SEH_info_AES_set_decrypt_key
+ DD imagerel $L$SEH_begin_private_AES_set_decrypt_key
+ DD imagerel $L$SEH_end_private_AES_set_decrypt_key
+ DD imagerel $L$SEH_info_private_AES_set_decrypt_key
DD imagerel $L$SEH_begin_AES_cbc_encrypt
DD imagerel $L$SEH_end_AES_cbc_encrypt
@@ -2867,12 +2876,12 @@ DB 9,0,0,0
DD imagerel block_se_handler
DD imagerel $L$dec_prologue,imagerel $L$dec_epilogue
-$L$SEH_info_AES_set_encrypt_key::
+$L$SEH_info_private_AES_set_encrypt_key::
DB 9,0,0,0
DD imagerel key_se_handler
DD imagerel $L$enc_key_prologue,imagerel $L$enc_key_epilogue
-$L$SEH_info_AES_set_decrypt_key::
+$L$SEH_info_private_AES_set_decrypt_key::
DB 9,0,0,0
DD imagerel key_se_handler
DD imagerel $L$dec_key_prologue,imagerel $L$dec_key_epilogue
diff --git a/deps/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm b/deps/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm
new file mode 100644
index 000000000..3f205a16a
--- /dev/null
+++ b/deps/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm
@@ -0,0 +1,1554 @@
+OPTION DOTNAME
+.text$ SEGMENT ALIGN(64) 'CODE'
+EXTERN OPENSSL_ia32cap_P:NEAR
+
+PUBLIC aesni_cbc_sha1_enc
+
+ALIGN 16
+aesni_cbc_sha1_enc PROC PUBLIC
+
+ mov r10d,DWORD PTR[((OPENSSL_ia32cap_P+0))]
+ mov r11d,DWORD PTR[((OPENSSL_ia32cap_P+4))]
+ jmp aesni_cbc_sha1_enc_ssse3
+ DB 0F3h,0C3h ;repret
+aesni_cbc_sha1_enc ENDP
+
+ALIGN 16
+aesni_cbc_sha1_enc_ssse3 PROC PRIVATE
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_aesni_cbc_sha1_enc_ssse3::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+ mov r9,QWORD PTR[48+rsp]
+
+
+ mov r10,QWORD PTR[56+rsp]
+
+
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ lea rsp,QWORD PTR[((-264))+rsp]
+
+
+ movaps XMMWORD PTR[(96+0)+rsp],xmm6
+ movaps XMMWORD PTR[(96+16)+rsp],xmm7
+ movaps XMMWORD PTR[(96+32)+rsp],xmm8
+ movaps XMMWORD PTR[(96+48)+rsp],xmm9
+ movaps XMMWORD PTR[(96+64)+rsp],xmm10
+ movaps XMMWORD PTR[(96+80)+rsp],xmm11
+ movaps XMMWORD PTR[(96+96)+rsp],xmm12
+ movaps XMMWORD PTR[(96+112)+rsp],xmm13
+ movaps XMMWORD PTR[(96+128)+rsp],xmm14
+ movaps XMMWORD PTR[(96+144)+rsp],xmm15
+$L$prologue_ssse3::
+ mov r12,rdi
+ mov r13,rsi
+ mov r14,rdx
+ mov r15,rcx
+ movdqu xmm11,XMMWORD PTR[r8]
+ mov QWORD PTR[88+rsp],r8
+ shl r14,6
+ sub r13,r12
+ mov r8d,DWORD PTR[240+r15]
+ add r14,r10
+
+ lea r11,QWORD PTR[K_XX_XX]
+ mov eax,DWORD PTR[r9]
+ mov ebx,DWORD PTR[4+r9]
+ mov ecx,DWORD PTR[8+r9]
+ mov edx,DWORD PTR[12+r9]
+ mov esi,ebx
+ mov ebp,DWORD PTR[16+r9]
+
+ movdqa xmm6,XMMWORD PTR[64+r11]
+ movdqa xmm9,XMMWORD PTR[r11]
+ movdqu xmm0,XMMWORD PTR[r10]
+ movdqu xmm1,XMMWORD PTR[16+r10]
+ movdqu xmm2,XMMWORD PTR[32+r10]
+ movdqu xmm3,XMMWORD PTR[48+r10]
+DB 102,15,56,0,198
+ add r10,64
+DB 102,15,56,0,206
+DB 102,15,56,0,214
+DB 102,15,56,0,222
+ paddd xmm0,xmm9
+ paddd xmm1,xmm9
+ paddd xmm2,xmm9
+ movdqa XMMWORD PTR[rsp],xmm0
+ psubd xmm0,xmm9
+ movdqa XMMWORD PTR[16+rsp],xmm1
+ psubd xmm1,xmm9
+ movdqa XMMWORD PTR[32+rsp],xmm2
+ psubd xmm2,xmm9
+ movups xmm13,XMMWORD PTR[r15]
+ movups xmm14,XMMWORD PTR[16+r15]
+ jmp $L$oop_ssse3
+ALIGN 16
+$L$oop_ssse3::
+ movdqa xmm4,xmm1
+ add ebp,DWORD PTR[rsp]
+ movups xmm12,XMMWORD PTR[r12]
+ xorps xmm12,xmm13
+ xorps xmm11,xmm12
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[32+r15]
+ xor ecx,edx
+ movdqa xmm8,xmm3
+DB 102,15,58,15,224,8
+ mov edi,eax
+ rol eax,5
+ paddd xmm9,xmm3
+ and esi,ecx
+ xor ecx,edx
+ psrldq xmm8,4
+ xor esi,edx
+ add ebp,eax
+ pxor xmm4,xmm0
+ ror ebx,2
+ add ebp,esi
+ pxor xmm8,xmm2
+ add edx,DWORD PTR[4+rsp]
+ xor ebx,ecx
+ mov esi,ebp
+ rol ebp,5
+ pxor xmm4,xmm8
+ and edi,ebx
+ xor ebx,ecx
+ movdqa XMMWORD PTR[48+rsp],xmm9
+ xor edi,ecx
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[48+r15]
+ add edx,ebp
+ movdqa xmm10,xmm4
+ movdqa xmm8,xmm4
+ ror eax,7
+ add edx,edi
+ add ecx,DWORD PTR[8+rsp]
+ xor eax,ebx
+ pslldq xmm10,12
+ paddd xmm4,xmm4
+ mov edi,edx
+ rol edx,5
+ and esi,eax
+ xor eax,ebx
+ psrld xmm8,31
+ xor esi,ebx
+ add ecx,edx
+ movdqa xmm9,xmm10
+ ror ebp,7
+ add ecx,esi
+ psrld xmm10,30
+ por xmm4,xmm8
+ add ebx,DWORD PTR[12+rsp]
+ xor ebp,eax
+ mov esi,ecx
+ rol ecx,5
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[64+r15]
+ pslld xmm9,2
+ pxor xmm4,xmm10
+ and edi,ebp
+ xor ebp,eax
+ movdqa xmm10,XMMWORD PTR[r11]
+ xor edi,eax
+ add ebx,ecx
+ pxor xmm4,xmm9
+ ror edx,7
+ add ebx,edi
+ movdqa xmm5,xmm2
+ add eax,DWORD PTR[16+rsp]
+ xor edx,ebp
+ movdqa xmm9,xmm4
+DB 102,15,58,15,233,8
+ mov edi,ebx
+ rol ebx,5
+ paddd xmm10,xmm4
+ and esi,edx
+ xor edx,ebp
+ psrldq xmm9,4
+ xor esi,ebp
+ add eax,ebx
+ pxor xmm5,xmm1
+ ror ecx,7
+ add eax,esi
+ pxor xmm9,xmm3
+ add ebp,DWORD PTR[20+rsp]
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[80+r15]
+ xor ecx,edx
+ mov esi,eax
+ rol eax,5
+ pxor xmm5,xmm9
+ and edi,ecx
+ xor ecx,edx
+ movdqa XMMWORD PTR[rsp],xmm10
+ xor edi,edx
+ add ebp,eax
+ movdqa xmm8,xmm5
+ movdqa xmm9,xmm5
+ ror ebx,7
+ add ebp,edi
+ add edx,DWORD PTR[24+rsp]
+ xor ebx,ecx
+ pslldq xmm8,12
+ paddd xmm5,xmm5
+ mov edi,ebp
+ rol ebp,5
+ and esi,ebx
+ xor ebx,ecx
+ psrld xmm9,31
+ xor esi,ecx
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[96+r15]
+ add edx,ebp
+ movdqa xmm10,xmm8
+ ror eax,7
+ add edx,esi
+ psrld xmm8,30
+ por xmm5,xmm9
+ add ecx,DWORD PTR[28+rsp]
+ xor eax,ebx
+ mov esi,edx
+ rol edx,5
+ pslld xmm10,2
+ pxor xmm5,xmm8
+ and edi,eax
+ xor eax,ebx
+ movdqa xmm8,XMMWORD PTR[16+r11]
+ xor edi,ebx
+ add ecx,edx
+ pxor xmm5,xmm10
+ ror ebp,7
+ add ecx,edi
+ movdqa xmm6,xmm3
+ add ebx,DWORD PTR[32+rsp]
+ xor ebp,eax
+ movdqa xmm10,xmm5
+DB 102,15,58,15,242,8
+ mov edi,ecx
+ rol ecx,5
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[112+r15]
+ paddd xmm8,xmm5
+ and esi,ebp
+ xor ebp,eax
+ psrldq xmm10,4
+ xor esi,eax
+ add ebx,ecx
+ pxor xmm6,xmm2
+ ror edx,7
+ add ebx,esi
+ pxor xmm10,xmm4
+ add eax,DWORD PTR[36+rsp]
+ xor edx,ebp
+ mov esi,ebx
+ rol ebx,5
+ pxor xmm6,xmm10
+ and edi,edx
+ xor edx,ebp
+ movdqa XMMWORD PTR[16+rsp],xmm8
+ xor edi,ebp
+ add eax,ebx
+ movdqa xmm9,xmm6
+ movdqa xmm10,xmm6
+ ror ecx,7
+ add eax,edi
+ add ebp,DWORD PTR[40+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[128+r15]
+ xor ecx,edx
+ pslldq xmm9,12
+ paddd xmm6,xmm6
+ mov edi,eax
+ rol eax,5
+ and esi,ecx
+ xor ecx,edx
+ psrld xmm10,31
+ xor esi,edx
+ add ebp,eax
+ movdqa xmm8,xmm9
+ ror ebx,7
+ add ebp,esi
+ psrld xmm9,30
+ por xmm6,xmm10
+ add edx,DWORD PTR[44+rsp]
+ xor ebx,ecx
+ mov esi,ebp
+ rol ebp,5
+ pslld xmm8,2
+ pxor xmm6,xmm9
+ and edi,ebx
+ xor ebx,ecx
+ movdqa xmm9,XMMWORD PTR[16+r11]
+ xor edi,ecx
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[144+r15]
+ add edx,ebp
+ pxor xmm6,xmm8
+ ror eax,7
+ add edx,edi
+ movdqa xmm7,xmm4
+ add ecx,DWORD PTR[48+rsp]
+ xor eax,ebx
+ movdqa xmm8,xmm6
+DB 102,15,58,15,251,8
+ mov edi,edx
+ rol edx,5
+ paddd xmm9,xmm6
+ and esi,eax
+ xor eax,ebx
+ psrldq xmm8,4
+ xor esi,ebx
+ add ecx,edx
+ pxor xmm7,xmm3
+ ror ebp,7
+ add ecx,esi
+ pxor xmm8,xmm5
+ add ebx,DWORD PTR[52+rsp]
+ xor ebp,eax
+ mov esi,ecx
+ rol ecx,5
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[160+r15]
+ pxor xmm7,xmm8
+ and edi,ebp
+ xor ebp,eax
+ movdqa XMMWORD PTR[32+rsp],xmm9
+ xor edi,eax
+ add ebx,ecx
+ movdqa xmm10,xmm7
+ movdqa xmm8,xmm7
+ ror edx,7
+ add ebx,edi
+ add eax,DWORD PTR[56+rsp]
+ xor edx,ebp
+ pslldq xmm10,12
+ paddd xmm7,xmm7
+ mov edi,ebx
+ rol ebx,5
+ and esi,edx
+ xor edx,ebp
+ psrld xmm8,31
+ xor esi,ebp
+ add eax,ebx
+ movdqa xmm9,xmm10
+ ror ecx,7
+ add eax,esi
+ psrld xmm10,30
+ por xmm7,xmm8
+ add ebp,DWORD PTR[60+rsp]
+ cmp r8d,11
+ jb $L$aesenclast1
+ movups xmm14,XMMWORD PTR[176+r15]
+DB 102,69,15,56,220,223
+ movups xmm15,XMMWORD PTR[192+r15]
+DB 102,69,15,56,220,222
+ je $L$aesenclast1
+ movups xmm14,XMMWORD PTR[208+r15]
+DB 102,69,15,56,220,223
+ movups xmm15,XMMWORD PTR[224+r15]
+DB 102,69,15,56,220,222
+$L$aesenclast1::
+DB 102,69,15,56,221,223
+ movups xmm14,XMMWORD PTR[16+r15]
+ xor ecx,edx
+ mov esi,eax
+ rol eax,5
+ pslld xmm9,2
+ pxor xmm7,xmm10
+ and edi,ecx
+ xor ecx,edx
+ movdqa xmm10,XMMWORD PTR[16+r11]
+ xor edi,edx
+ add ebp,eax
+ pxor xmm7,xmm9
+ ror ebx,7
+ add ebp,edi
+ movdqa xmm9,xmm7
+ add edx,DWORD PTR[rsp]
+ pxor xmm0,xmm4
+DB 102,68,15,58,15,206,8
+ xor ebx,ecx
+ mov edi,ebp
+ rol ebp,5
+ pxor xmm0,xmm1
+ and esi,ebx
+ xor ebx,ecx
+ movdqa xmm8,xmm10
+ paddd xmm10,xmm7
+ xor esi,ecx
+ movups xmm12,XMMWORD PTR[16+r12]
+ xorps xmm12,xmm13
+ movups XMMWORD PTR[r12*1+r13],xmm11
+ xorps xmm11,xmm12
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[32+r15]
+ add edx,ebp
+ pxor xmm0,xmm9
+ ror eax,7
+ add edx,esi
+ add ecx,DWORD PTR[4+rsp]
+ xor eax,ebx
+ movdqa xmm9,xmm0
+ movdqa XMMWORD PTR[48+rsp],xmm10
+ mov esi,edx
+ rol edx,5
+ and edi,eax
+ xor eax,ebx
+ pslld xmm0,2
+ xor edi,ebx
+ add ecx,edx
+ psrld xmm9,30
+ ror ebp,7
+ add ecx,edi
+ add ebx,DWORD PTR[8+rsp]
+ xor ebp,eax
+ mov edi,ecx
+ rol ecx,5
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[48+r15]
+ por xmm0,xmm9
+ and esi,ebp
+ xor ebp,eax
+ movdqa xmm10,xmm0
+ xor esi,eax
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ add eax,DWORD PTR[12+rsp]
+ xor edx,ebp
+ mov esi,ebx
+ rol ebx,5
+ and edi,edx
+ xor edx,ebp
+ xor edi,ebp
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ add ebp,DWORD PTR[16+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[64+r15]
+ pxor xmm1,xmm5
+DB 102,68,15,58,15,215,8
+ xor esi,edx
+ mov edi,eax
+ rol eax,5
+ pxor xmm1,xmm2
+ xor esi,ecx
+ add ebp,eax
+ movdqa xmm9,xmm8
+ paddd xmm8,xmm0
+ ror ebx,7
+ add ebp,esi
+ pxor xmm1,xmm10
+ add edx,DWORD PTR[20+rsp]
+ xor edi,ecx
+ mov esi,ebp
+ rol ebp,5
+ movdqa xmm10,xmm1
+ movdqa XMMWORD PTR[rsp],xmm8
+ xor edi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,edi
+ pslld xmm1,2
+ add ecx,DWORD PTR[24+rsp]
+ xor esi,ebx
+ psrld xmm10,30
+ mov edi,edx
+ rol edx,5
+ xor esi,eax
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[80+r15]
+ add ecx,edx
+ ror ebp,7
+ add ecx,esi
+ por xmm1,xmm10
+ add ebx,DWORD PTR[28+rsp]
+ xor edi,eax
+ movdqa xmm8,xmm1
+ mov esi,ecx
+ rol ecx,5
+ xor edi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,edi
+ add eax,DWORD PTR[32+rsp]
+ pxor xmm2,xmm6
+DB 102,68,15,58,15,192,8
+ xor esi,ebp
+ mov edi,ebx
+ rol ebx,5
+ pxor xmm2,xmm3
+ xor esi,edx
+ add eax,ebx
+ movdqa xmm10,XMMWORD PTR[32+r11]
+ paddd xmm9,xmm1
+ ror ecx,7
+ add eax,esi
+ pxor xmm2,xmm8
+ add ebp,DWORD PTR[36+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[96+r15]
+ xor edi,edx
+ mov esi,eax
+ rol eax,5
+ movdqa xmm8,xmm2
+ movdqa XMMWORD PTR[16+rsp],xmm9
+ xor edi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,edi
+ pslld xmm2,2
+ add edx,DWORD PTR[40+rsp]
+ xor esi,ecx
+ psrld xmm8,30
+ mov edi,ebp
+ rol ebp,5
+ xor esi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,esi
+ por xmm2,xmm8
+ add ecx,DWORD PTR[44+rsp]
+ xor edi,ebx
+ movdqa xmm9,xmm2
+ mov esi,edx
+ rol edx,5
+ xor edi,eax
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[112+r15]
+ add ecx,edx
+ ror ebp,7
+ add ecx,edi
+ add ebx,DWORD PTR[48+rsp]
+ pxor xmm3,xmm7
+DB 102,68,15,58,15,201,8
+ xor esi,eax
+ mov edi,ecx
+ rol ecx,5
+ pxor xmm3,xmm4
+ xor esi,ebp
+ add ebx,ecx
+ movdqa xmm8,xmm10
+ paddd xmm10,xmm2
+ ror edx,7
+ add ebx,esi
+ pxor xmm3,xmm9
+ add eax,DWORD PTR[52+rsp]
+ xor edi,ebp
+ mov esi,ebx
+ rol ebx,5
+ movdqa xmm9,xmm3
+ movdqa XMMWORD PTR[32+rsp],xmm10
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ pslld xmm3,2
+ add ebp,DWORD PTR[56+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[128+r15]
+ xor esi,edx
+ psrld xmm9,30
+ mov edi,eax
+ rol eax,5
+ xor esi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,esi
+ por xmm3,xmm9
+ add edx,DWORD PTR[60+rsp]
+ xor edi,ecx
+ movdqa xmm10,xmm3
+ mov esi,ebp
+ rol ebp,5
+ xor edi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,edi
+ add ecx,DWORD PTR[rsp]
+ pxor xmm4,xmm0
+DB 102,68,15,58,15,210,8
+ xor esi,ebx
+ mov edi,edx
+ rol edx,5
+ pxor xmm4,xmm5
+ xor esi,eax
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[144+r15]
+ add ecx,edx
+ movdqa xmm9,xmm8
+ paddd xmm8,xmm3
+ ror ebp,7
+ add ecx,esi
+ pxor xmm4,xmm10
+ add ebx,DWORD PTR[4+rsp]
+ xor edi,eax
+ mov esi,ecx
+ rol ecx,5
+ movdqa xmm10,xmm4
+ movdqa XMMWORD PTR[48+rsp],xmm8
+ xor edi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,edi
+ pslld xmm4,2
+ add eax,DWORD PTR[8+rsp]
+ xor esi,ebp
+ psrld xmm10,30
+ mov edi,ebx
+ rol ebx,5
+ xor esi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,esi
+ por xmm4,xmm10
+ add ebp,DWORD PTR[12+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[160+r15]
+ xor edi,edx
+ movdqa xmm8,xmm4
+ mov esi,eax
+ rol eax,5
+ xor edi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,edi
+ add edx,DWORD PTR[16+rsp]
+ pxor xmm5,xmm1
+DB 102,68,15,58,15,195,8
+ xor esi,ecx
+ mov edi,ebp
+ rol ebp,5
+ pxor xmm5,xmm6
+ xor esi,ebx
+ add edx,ebp
+ movdqa xmm10,xmm9
+ paddd xmm9,xmm4
+ ror eax,7
+ add edx,esi
+ pxor xmm5,xmm8
+ add ecx,DWORD PTR[20+rsp]
+ xor edi,ebx
+ mov esi,edx
+ rol edx,5
+ movdqa xmm8,xmm5
+ movdqa XMMWORD PTR[rsp],xmm9
+ xor edi,eax
+ cmp r8d,11
+ jb $L$aesenclast2
+ movups xmm14,XMMWORD PTR[176+r15]
+DB 102,69,15,56,220,223
+ movups xmm15,XMMWORD PTR[192+r15]
+DB 102,69,15,56,220,222
+ je $L$aesenclast2
+ movups xmm14,XMMWORD PTR[208+r15]
+DB 102,69,15,56,220,223
+ movups xmm15,XMMWORD PTR[224+r15]
+DB 102,69,15,56,220,222
+$L$aesenclast2::
+DB 102,69,15,56,221,223
+ movups xmm14,XMMWORD PTR[16+r15]
+ add ecx,edx
+ ror ebp,7
+ add ecx,edi
+ pslld xmm5,2
+ add ebx,DWORD PTR[24+rsp]
+ xor esi,eax
+ psrld xmm8,30
+ mov edi,ecx
+ rol ecx,5
+ xor esi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ por xmm5,xmm8
+ add eax,DWORD PTR[28+rsp]
+ xor edi,ebp
+ movdqa xmm9,xmm5
+ mov esi,ebx
+ rol ebx,5
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ mov edi,ecx
+ movups xmm12,XMMWORD PTR[32+r12]
+ xorps xmm12,xmm13
+ movups XMMWORD PTR[16+r12*1+r13],xmm11
+ xorps xmm11,xmm12
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[32+r15]
+ pxor xmm6,xmm2
+DB 102,68,15,58,15,204,8
+ xor ecx,edx
+ add ebp,DWORD PTR[32+rsp]
+ and edi,edx
+ pxor xmm6,xmm7
+ and esi,ecx
+ ror ebx,7
+ movdqa xmm8,xmm10
+ paddd xmm10,xmm5
+ add ebp,edi
+ mov edi,eax
+ pxor xmm6,xmm9
+ rol eax,5
+ add ebp,esi
+ xor ecx,edx
+ add ebp,eax
+ movdqa xmm9,xmm6
+ movdqa XMMWORD PTR[16+rsp],xmm10
+ mov esi,ebx
+ xor ebx,ecx
+ add edx,DWORD PTR[36+rsp]
+ and esi,ecx
+ pslld xmm6,2
+ and edi,ebx
+ ror eax,7
+ psrld xmm9,30
+ add edx,esi
+ mov esi,ebp
+ rol ebp,5
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[48+r15]
+ add edx,edi
+ xor ebx,ecx
+ add edx,ebp
+ por xmm6,xmm9
+ mov edi,eax
+ xor eax,ebx
+ movdqa xmm10,xmm6
+ add ecx,DWORD PTR[40+rsp]
+ and edi,ebx
+ and esi,eax
+ ror ebp,7
+ add ecx,edi
+ mov edi,edx
+ rol edx,5
+ add ecx,esi
+ xor eax,ebx
+ add ecx,edx
+ mov esi,ebp
+ xor ebp,eax
+ add ebx,DWORD PTR[44+rsp]
+ and esi,eax
+ and edi,ebp
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[64+r15]
+ ror edx,7
+ add ebx,esi
+ mov esi,ecx
+ rol ecx,5
+ add ebx,edi
+ xor ebp,eax
+ add ebx,ecx
+ mov edi,edx
+ pxor xmm7,xmm3
+DB 102,68,15,58,15,213,8
+ xor edx,ebp
+ add eax,DWORD PTR[48+rsp]
+ and edi,ebp
+ pxor xmm7,xmm0
+ and esi,edx
+ ror ecx,7
+ movdqa xmm9,XMMWORD PTR[48+r11]
+ paddd xmm8,xmm6
+ add eax,edi
+ mov edi,ebx
+ pxor xmm7,xmm10
+ rol ebx,5
+ add eax,esi
+ xor edx,ebp
+ add eax,ebx
+ movdqa xmm10,xmm7
+ movdqa XMMWORD PTR[32+rsp],xmm8
+ mov esi,ecx
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[80+r15]
+ xor ecx,edx
+ add ebp,DWORD PTR[52+rsp]
+ and esi,edx
+ pslld xmm7,2
+ and edi,ecx
+ ror ebx,7
+ psrld xmm10,30
+ add ebp,esi
+ mov esi,eax
+ rol eax,5
+ add ebp,edi
+ xor ecx,edx
+ add ebp,eax
+ por xmm7,xmm10
+ mov edi,ebx
+ xor ebx,ecx
+ movdqa xmm8,xmm7
+ add edx,DWORD PTR[56+rsp]
+ and edi,ecx
+ and esi,ebx
+ ror eax,7
+ add edx,edi
+ mov edi,ebp
+ rol ebp,5
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[96+r15]
+ add edx,esi
+ xor ebx,ecx
+ add edx,ebp
+ mov esi,eax
+ xor eax,ebx
+ add ecx,DWORD PTR[60+rsp]
+ and esi,ebx
+ and edi,eax
+ ror ebp,7
+ add ecx,esi
+ mov esi,edx
+ rol edx,5
+ add ecx,edi
+ xor eax,ebx
+ add ecx,edx
+ mov edi,ebp
+ pxor xmm0,xmm4
+DB 102,68,15,58,15,198,8
+ xor ebp,eax
+ add ebx,DWORD PTR[rsp]
+ and edi,eax
+ pxor xmm0,xmm1
+ and esi,ebp
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[112+r15]
+ ror edx,7
+ movdqa xmm10,xmm9
+ paddd xmm9,xmm7
+ add ebx,edi
+ mov edi,ecx
+ pxor xmm0,xmm8
+ rol ecx,5
+ add ebx,esi
+ xor ebp,eax
+ add ebx,ecx
+ movdqa xmm8,xmm0
+ movdqa XMMWORD PTR[48+rsp],xmm9
+ mov esi,edx
+ xor edx,ebp
+ add eax,DWORD PTR[4+rsp]
+ and esi,ebp
+ pslld xmm0,2
+ and edi,edx
+ ror ecx,7
+ psrld xmm8,30
+ add eax,esi
+ mov esi,ebx
+ rol ebx,5
+ add eax,edi
+ xor edx,ebp
+ add eax,ebx
+ por xmm0,xmm8
+ mov edi,ecx
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[128+r15]
+ xor ecx,edx
+ movdqa xmm9,xmm0
+ add ebp,DWORD PTR[8+rsp]
+ and edi,edx
+ and esi,ecx
+ ror ebx,7
+ add ebp,edi
+ mov edi,eax
+ rol eax,5
+ add ebp,esi
+ xor ecx,edx
+ add ebp,eax
+ mov esi,ebx
+ xor ebx,ecx
+ add edx,DWORD PTR[12+rsp]
+ and esi,ecx
+ and edi,ebx
+ ror eax,7
+ add edx,esi
+ mov esi,ebp
+ rol ebp,5
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[144+r15]
+ add edx,edi
+ xor ebx,ecx
+ add edx,ebp
+ mov edi,eax
+ pxor xmm1,xmm5
+DB 102,68,15,58,15,207,8
+ xor eax,ebx
+ add ecx,DWORD PTR[16+rsp]
+ and edi,ebx
+ pxor xmm1,xmm2
+ and esi,eax
+ ror ebp,7
+ movdqa xmm8,xmm10
+ paddd xmm10,xmm0
+ add ecx,edi
+ mov edi,edx
+ pxor xmm1,xmm9
+ rol edx,5
+ add ecx,esi
+ xor eax,ebx
+ add ecx,edx
+ movdqa xmm9,xmm1
+ movdqa XMMWORD PTR[rsp],xmm10
+ mov esi,ebp
+ xor ebp,eax
+ add ebx,DWORD PTR[20+rsp]
+ and esi,eax
+ pslld xmm1,2
+ and edi,ebp
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[160+r15]
+ ror edx,7
+ psrld xmm9,30
+ add ebx,esi
+ mov esi,ecx
+ rol ecx,5
+ add ebx,edi
+ xor ebp,eax
+ add ebx,ecx
+ por xmm1,xmm9
+ mov edi,edx
+ xor edx,ebp
+ movdqa xmm10,xmm1
+ add eax,DWORD PTR[24+rsp]
+ and edi,ebp
+ and esi,edx
+ ror ecx,7
+ add eax,edi
+ mov edi,ebx
+ rol ebx,5
+ add eax,esi
+ xor edx,ebp
+ add eax,ebx
+ mov esi,ecx
+ cmp r8d,11
+ jb $L$aesenclast3
+ movups xmm14,XMMWORD PTR[176+r15]
+DB 102,69,15,56,220,223
+ movups xmm15,XMMWORD PTR[192+r15]
+DB 102,69,15,56,220,222
+ je $L$aesenclast3
+ movups xmm14,XMMWORD PTR[208+r15]
+DB 102,69,15,56,220,223
+ movups xmm15,XMMWORD PTR[224+r15]
+DB 102,69,15,56,220,222
+$L$aesenclast3::
+DB 102,69,15,56,221,223
+ movups xmm14,XMMWORD PTR[16+r15]
+ xor ecx,edx
+ add ebp,DWORD PTR[28+rsp]
+ and esi,edx
+ and edi,ecx
+ ror ebx,7
+ add ebp,esi
+ mov esi,eax
+ rol eax,5
+ add ebp,edi
+ xor ecx,edx
+ add ebp,eax
+ mov edi,ebx
+ pxor xmm2,xmm6
+DB 102,68,15,58,15,208,8
+ xor ebx,ecx
+ add edx,DWORD PTR[32+rsp]
+ and edi,ecx
+ pxor xmm2,xmm3
+ and esi,ebx
+ ror eax,7
+ movdqa xmm9,xmm8
+ paddd xmm8,xmm1
+ add edx,edi
+ mov edi,ebp
+ pxor xmm2,xmm10
+ rol ebp,5
+ movups xmm12,XMMWORD PTR[48+r12]
+ xorps xmm12,xmm13
+ movups XMMWORD PTR[32+r12*1+r13],xmm11
+ xorps xmm11,xmm12
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[32+r15]
+ add edx,esi
+ xor ebx,ecx
+ add edx,ebp
+ movdqa xmm10,xmm2
+ movdqa XMMWORD PTR[16+rsp],xmm8
+ mov esi,eax
+ xor eax,ebx
+ add ecx,DWORD PTR[36+rsp]
+ and esi,ebx
+ pslld xmm2,2
+ and edi,eax
+ ror ebp,7
+ psrld xmm10,30
+ add ecx,esi
+ mov esi,edx
+ rol edx,5
+ add ecx,edi
+ xor eax,ebx
+ add ecx,edx
+ por xmm2,xmm10
+ mov edi,ebp
+ xor ebp,eax
+ movdqa xmm8,xmm2
+ add ebx,DWORD PTR[40+rsp]
+ and edi,eax
+ and esi,ebp
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[48+r15]
+ ror edx,7
+ add ebx,edi
+ mov edi,ecx
+ rol ecx,5
+ add ebx,esi
+ xor ebp,eax
+ add ebx,ecx
+ mov esi,edx
+ xor edx,ebp
+ add eax,DWORD PTR[44+rsp]
+ and esi,ebp
+ and edi,edx
+ ror ecx,7
+ add eax,esi
+ mov esi,ebx
+ rol ebx,5
+ add eax,edi
+ xor edx,ebp
+ add eax,ebx
+ add ebp,DWORD PTR[48+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[64+r15]
+ pxor xmm3,xmm7
+DB 102,68,15,58,15,193,8
+ xor esi,edx
+ mov edi,eax
+ rol eax,5
+ pxor xmm3,xmm4
+ xor esi,ecx
+ add ebp,eax
+ movdqa xmm10,xmm9
+ paddd xmm9,xmm2
+ ror ebx,7
+ add ebp,esi
+ pxor xmm3,xmm8
+ add edx,DWORD PTR[52+rsp]
+ xor edi,ecx
+ mov esi,ebp
+ rol ebp,5
+ movdqa xmm8,xmm3
+ movdqa XMMWORD PTR[32+rsp],xmm9
+ xor edi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,edi
+ pslld xmm3,2
+ add ecx,DWORD PTR[56+rsp]
+ xor esi,ebx
+ psrld xmm8,30
+ mov edi,edx
+ rol edx,5
+ xor esi,eax
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[80+r15]
+ add ecx,edx
+ ror ebp,7
+ add ecx,esi
+ por xmm3,xmm8
+ add ebx,DWORD PTR[60+rsp]
+ xor edi,eax
+ mov esi,ecx
+ rol ecx,5
+ xor edi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,edi
+ add eax,DWORD PTR[rsp]
+ paddd xmm10,xmm3
+ xor esi,ebp
+ mov edi,ebx
+ rol ebx,5
+ xor esi,edx
+ movdqa XMMWORD PTR[48+rsp],xmm10
+ add eax,ebx
+ ror ecx,7
+ add eax,esi
+ add ebp,DWORD PTR[4+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[96+r15]
+ xor edi,edx
+ mov esi,eax
+ rol eax,5
+ xor edi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,edi
+ add edx,DWORD PTR[8+rsp]
+ xor esi,ecx
+ mov edi,ebp
+ rol ebp,5
+ xor esi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,esi
+ add ecx,DWORD PTR[12+rsp]
+ xor edi,ebx
+ mov esi,edx
+ rol edx,5
+ xor edi,eax
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[112+r15]
+ add ecx,edx
+ ror ebp,7
+ add ecx,edi
+ cmp r10,r14
+ je $L$done_ssse3
+ movdqa xmm6,XMMWORD PTR[64+r11]
+ movdqa xmm9,XMMWORD PTR[r11]
+ movdqu xmm0,XMMWORD PTR[r10]
+ movdqu xmm1,XMMWORD PTR[16+r10]
+ movdqu xmm2,XMMWORD PTR[32+r10]
+ movdqu xmm3,XMMWORD PTR[48+r10]
+DB 102,15,56,0,198
+ add r10,64
+ add ebx,DWORD PTR[16+rsp]
+ xor esi,eax
+DB 102,15,56,0,206
+ mov edi,ecx
+ rol ecx,5
+ paddd xmm0,xmm9
+ xor esi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ movdqa XMMWORD PTR[rsp],xmm0
+ add eax,DWORD PTR[20+rsp]
+ xor edi,ebp
+ psubd xmm0,xmm9
+ mov esi,ebx
+ rol ebx,5
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ add ebp,DWORD PTR[24+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[128+r15]
+ xor esi,edx
+ mov edi,eax
+ rol eax,5
+ xor esi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,esi
+ add edx,DWORD PTR[28+rsp]
+ xor edi,ecx
+ mov esi,ebp
+ rol ebp,5
+ xor edi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,edi
+ add ecx,DWORD PTR[32+rsp]
+ xor esi,ebx
+DB 102,15,56,0,214
+ mov edi,edx
+ rol edx,5
+ paddd xmm1,xmm9
+ xor esi,eax
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[144+r15]
+ add ecx,edx
+ ror ebp,7
+ add ecx,esi
+ movdqa XMMWORD PTR[16+rsp],xmm1
+ add ebx,DWORD PTR[36+rsp]
+ xor edi,eax
+ psubd xmm1,xmm9
+ mov esi,ecx
+ rol ecx,5
+ xor edi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,edi
+ add eax,DWORD PTR[40+rsp]
+ xor esi,ebp
+ mov edi,ebx
+ rol ebx,5
+ xor esi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,esi
+ add ebp,DWORD PTR[44+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[160+r15]
+ xor edi,edx
+ mov esi,eax
+ rol eax,5
+ xor edi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,edi
+ add edx,DWORD PTR[48+rsp]
+ xor esi,ecx
+DB 102,15,56,0,222
+ mov edi,ebp
+ rol ebp,5
+ paddd xmm2,xmm9
+ xor esi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,esi
+ movdqa XMMWORD PTR[32+rsp],xmm2
+ add ecx,DWORD PTR[52+rsp]
+ xor edi,ebx
+ psubd xmm2,xmm9
+ mov esi,edx
+ rol edx,5
+ xor edi,eax
+ cmp r8d,11
+ jb $L$aesenclast4
+ movups xmm14,XMMWORD PTR[176+r15]
+DB 102,69,15,56,220,223
+ movups xmm15,XMMWORD PTR[192+r15]
+DB 102,69,15,56,220,222
+ je $L$aesenclast4
+ movups xmm14,XMMWORD PTR[208+r15]
+DB 102,69,15,56,220,223
+ movups xmm15,XMMWORD PTR[224+r15]
+DB 102,69,15,56,220,222
+$L$aesenclast4::
+DB 102,69,15,56,221,223
+ movups xmm14,XMMWORD PTR[16+r15]
+ add ecx,edx
+ ror ebp,7
+ add ecx,edi
+ add ebx,DWORD PTR[56+rsp]
+ xor esi,eax
+ mov edi,ecx
+ rol ecx,5
+ xor esi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ add eax,DWORD PTR[60+rsp]
+ xor edi,ebp
+ mov esi,ebx
+ rol ebx,5
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ movups XMMWORD PTR[48+r12*1+r13],xmm11
+ lea r12,QWORD PTR[64+r12]
+
+ add eax,DWORD PTR[r9]
+ add esi,DWORD PTR[4+r9]
+ add ecx,DWORD PTR[8+r9]
+ add edx,DWORD PTR[12+r9]
+ mov DWORD PTR[r9],eax
+ add ebp,DWORD PTR[16+r9]
+ mov DWORD PTR[4+r9],esi
+ mov ebx,esi
+ mov DWORD PTR[8+r9],ecx
+ mov DWORD PTR[12+r9],edx
+ mov DWORD PTR[16+r9],ebp
+ jmp $L$oop_ssse3
+
+ALIGN 16
+$L$done_ssse3::
+ add ebx,DWORD PTR[16+rsp]
+ xor esi,eax
+ mov edi,ecx
+ rol ecx,5
+ xor esi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ add eax,DWORD PTR[20+rsp]
+ xor edi,ebp
+ mov esi,ebx
+ rol ebx,5
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ add ebp,DWORD PTR[24+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[128+r15]
+ xor esi,edx
+ mov edi,eax
+ rol eax,5
+ xor esi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,esi
+ add edx,DWORD PTR[28+rsp]
+ xor edi,ecx
+ mov esi,ebp
+ rol ebp,5
+ xor edi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,edi
+ add ecx,DWORD PTR[32+rsp]
+ xor esi,ebx
+ mov edi,edx
+ rol edx,5
+ xor esi,eax
+DB 102,69,15,56,220,223
+ movups xmm14,XMMWORD PTR[144+r15]
+ add ecx,edx
+ ror ebp,7
+ add ecx,esi
+ add ebx,DWORD PTR[36+rsp]
+ xor edi,eax
+ mov esi,ecx
+ rol ecx,5
+ xor edi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,edi
+ add eax,DWORD PTR[40+rsp]
+ xor esi,ebp
+ mov edi,ebx
+ rol ebx,5
+ xor esi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,esi
+ add ebp,DWORD PTR[44+rsp]
+DB 102,69,15,56,220,222
+ movups xmm15,XMMWORD PTR[160+r15]
+ xor edi,edx
+ mov esi,eax
+ rol eax,5
+ xor edi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,edi
+ add edx,DWORD PTR[48+rsp]
+ xor esi,ecx
+ mov edi,ebp
+ rol ebp,5
+ xor esi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,esi
+ add ecx,DWORD PTR[52+rsp]
+ xor edi,ebx
+ mov esi,edx
+ rol edx,5
+ xor edi,eax
+ cmp r8d,11
+ jb $L$aesenclast5
+ movups xmm14,XMMWORD PTR[176+r15]
+DB 102,69,15,56,220,223
+ movups xmm15,XMMWORD PTR[192+r15]
+DB 102,69,15,56,220,222
+ je $L$aesenclast5
+ movups xmm14,XMMWORD PTR[208+r15]
+DB 102,69,15,56,220,223
+ movups xmm15,XMMWORD PTR[224+r15]
+DB 102,69,15,56,220,222
+$L$aesenclast5::
+DB 102,69,15,56,221,223
+ movups xmm14,XMMWORD PTR[16+r15]
+ add ecx,edx
+ ror ebp,7
+ add ecx,edi
+ add ebx,DWORD PTR[56+rsp]
+ xor esi,eax
+ mov edi,ecx
+ rol ecx,5
+ xor esi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ add eax,DWORD PTR[60+rsp]
+ xor edi,ebp
+ mov esi,ebx
+ rol ebx,5
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ movups XMMWORD PTR[48+r12*1+r13],xmm11
+ mov r8,QWORD PTR[88+rsp]
+
+ add eax,DWORD PTR[r9]
+ add esi,DWORD PTR[4+r9]
+ add ecx,DWORD PTR[8+r9]
+ mov DWORD PTR[r9],eax
+ add edx,DWORD PTR[12+r9]
+ mov DWORD PTR[4+r9],esi
+ add ebp,DWORD PTR[16+r9]
+ mov DWORD PTR[8+r9],ecx
+ mov DWORD PTR[12+r9],edx
+ mov DWORD PTR[16+r9],ebp
+ movups XMMWORD PTR[r8],xmm11
+ movaps xmm6,XMMWORD PTR[((96+0))+rsp]
+ movaps xmm7,XMMWORD PTR[((96+16))+rsp]
+ movaps xmm8,XMMWORD PTR[((96+32))+rsp]
+ movaps xmm9,XMMWORD PTR[((96+48))+rsp]
+ movaps xmm10,XMMWORD PTR[((96+64))+rsp]
+ movaps xmm11,XMMWORD PTR[((96+80))+rsp]
+ movaps xmm12,XMMWORD PTR[((96+96))+rsp]
+ movaps xmm13,XMMWORD PTR[((96+112))+rsp]
+ movaps xmm14,XMMWORD PTR[((96+128))+rsp]
+ movaps xmm15,XMMWORD PTR[((96+144))+rsp]
+ lea rsi,QWORD PTR[264+rsp]
+ mov r15,QWORD PTR[rsi]
+ mov r14,QWORD PTR[8+rsi]
+ mov r13,QWORD PTR[16+rsi]
+ mov r12,QWORD PTR[24+rsi]
+ mov rbp,QWORD PTR[32+rsi]
+ mov rbx,QWORD PTR[40+rsi]
+ lea rsp,QWORD PTR[48+rsi]
+$L$epilogue_ssse3::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_aesni_cbc_sha1_enc_ssse3::
+aesni_cbc_sha1_enc_ssse3 ENDP
+ALIGN 64
+K_XX_XX::
+ DD 05a827999h,05a827999h,05a827999h,05a827999h
+
+ DD 06ed9eba1h,06ed9eba1h,06ed9eba1h,06ed9eba1h
+
+ DD 08f1bbcdch,08f1bbcdch,08f1bbcdch,08f1bbcdch
+
+ DD 0ca62c1d6h,0ca62c1d6h,0ca62c1d6h,0ca62c1d6h
+
+ DD 000010203h,004050607h,008090a0bh,00c0d0e0fh
+
+
+DB 65,69,83,78,73,45,67,66,67,43,83,72,65,49,32,115
+DB 116,105,116,99,104,32,102,111,114,32,120,56,54,95,54,52
+DB 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
+DB 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
+DB 114,103,62,0
+ALIGN 64
+EXTERN __imp_RtlVirtualUnwind:NEAR
+
+ALIGN 16
+ssse3_handler PROC PRIVATE
+ push rsi
+ push rdi
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq
+ sub rsp,64
+
+ mov rax,QWORD PTR[120+r8]
+ mov rbx,QWORD PTR[248+r8]
+
+ mov rsi,QWORD PTR[8+r9]
+ mov r11,QWORD PTR[56+r9]
+
+ mov r10d,DWORD PTR[r11]
+ lea r10,QWORD PTR[r10*1+rsi]
+ cmp rbx,r10
+ jb $L$common_seh_tail
+
+ mov rax,QWORD PTR[152+r8]
+
+ mov r10d,DWORD PTR[4+r11]
+ lea r10,QWORD PTR[r10*1+rsi]
+ cmp rbx,r10
+ jae $L$common_seh_tail
+
+ lea rsi,QWORD PTR[96+rax]
+ lea rdi,QWORD PTR[512+r8]
+ mov ecx,20
+ DD 0a548f3fch
+
+ lea rax,QWORD PTR[264+rax]
+
+ mov r15,QWORD PTR[rax]
+ mov r14,QWORD PTR[8+rax]
+ mov r13,QWORD PTR[16+rax]
+ mov r12,QWORD PTR[24+rax]
+ mov rbp,QWORD PTR[32+rax]
+ mov rbx,QWORD PTR[40+rax]
+ lea rax,QWORD PTR[48+rax]
+ mov QWORD PTR[144+r8],rbx
+ mov QWORD PTR[160+r8],rbp
+ mov QWORD PTR[216+r8],r12
+ mov QWORD PTR[224+r8],r13
+ mov QWORD PTR[232+r8],r14
+ mov QWORD PTR[240+r8],r15
+
+$L$common_seh_tail::
+ mov rdi,QWORD PTR[8+rax]
+ mov rsi,QWORD PTR[16+rax]
+ mov QWORD PTR[152+r8],rax
+ mov QWORD PTR[168+r8],rsi
+ mov QWORD PTR[176+r8],rdi
+
+ mov rdi,QWORD PTR[40+r9]
+ mov rsi,r8
+ mov ecx,154
+ DD 0a548f3fch
+
+
+ mov rsi,r9
+ xor rcx,rcx
+ mov rdx,QWORD PTR[8+rsi]
+ mov r8,QWORD PTR[rsi]
+ mov r9,QWORD PTR[16+rsi]
+ mov r10,QWORD PTR[40+rsi]
+ lea r11,QWORD PTR[56+rsi]
+ lea r12,QWORD PTR[24+rsi]
+ mov QWORD PTR[32+rsp],r10
+ mov QWORD PTR[40+rsp],r11
+ mov QWORD PTR[48+rsp],r12
+ mov QWORD PTR[56+rsp],rcx
+ call QWORD PTR[__imp_RtlVirtualUnwind]
+
+ mov eax,1
+ add rsp,64
+ popfq
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbp
+ pop rbx
+ pop rdi
+ pop rsi
+ DB 0F3h,0C3h ;repret
+ssse3_handler ENDP
+
+.text$ ENDS
+.pdata SEGMENT READONLY ALIGN(4)
+ALIGN 4
+ DD imagerel $L$SEH_begin_aesni_cbc_sha1_enc_ssse3
+ DD imagerel $L$SEH_end_aesni_cbc_sha1_enc_ssse3
+ DD imagerel $L$SEH_info_aesni_cbc_sha1_enc_ssse3
+.pdata ENDS
+.xdata SEGMENT READONLY ALIGN(8)
+ALIGN 8
+$L$SEH_info_aesni_cbc_sha1_enc_ssse3::
+DB 9,0,0,0
+ DD imagerel ssse3_handler
+ DD imagerel $L$prologue_ssse3,imagerel $L$epilogue_ssse3
+
+
+.xdata ENDS
+END
diff --git a/deps/openssl/asm/x64-win32-masm/aes/aesni-x86_64.asm b/deps/openssl/asm/x64-win32-masm/aes/aesni-x86_64.asm
new file mode 100644
index 000000000..9d5a62607
--- /dev/null
+++ b/deps/openssl/asm/x64-win32-masm/aes/aesni-x86_64.asm
@@ -0,0 +1,3062 @@
+OPTION DOTNAME
+.text$ SEGMENT ALIGN(64) 'CODE'
+PUBLIC aesni_encrypt
+
+ALIGN 16
+aesni_encrypt PROC PUBLIC
+ movups xmm2,XMMWORD PTR[rcx]
+ mov eax,DWORD PTR[240+r8]
+ movups xmm0,XMMWORD PTR[r8]
+ movups xmm1,XMMWORD PTR[16+r8]
+ lea r8,QWORD PTR[32+r8]
+ xorps xmm2,xmm0
+$L$oop_enc1_1::
+DB 102,15,56,220,209
+ dec eax
+ movups xmm1,XMMWORD PTR[r8]
+ lea r8,QWORD PTR[16+r8]
+ jnz $L$oop_enc1_1
+
+DB 102,15,56,221,209
+ movups XMMWORD PTR[rdx],xmm2
+ DB 0F3h,0C3h ;repret
+aesni_encrypt ENDP
+
+PUBLIC aesni_decrypt
+
+ALIGN 16
+aesni_decrypt PROC PUBLIC
+ movups xmm2,XMMWORD PTR[rcx]
+ mov eax,DWORD PTR[240+r8]
+ movups xmm0,XMMWORD PTR[r8]
+ movups xmm1,XMMWORD PTR[16+r8]
+ lea r8,QWORD PTR[32+r8]
+ xorps xmm2,xmm0
+$L$oop_dec1_2::
+DB 102,15,56,222,209
+ dec eax
+ movups xmm1,XMMWORD PTR[r8]
+ lea r8,QWORD PTR[16+r8]
+ jnz $L$oop_dec1_2
+
+DB 102,15,56,223,209
+ movups XMMWORD PTR[rdx],xmm2
+ DB 0F3h,0C3h ;repret
+aesni_decrypt ENDP
+
+ALIGN 16
+_aesni_encrypt3 PROC PRIVATE
+ movups xmm0,XMMWORD PTR[rcx]
+ shr eax,1
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+ xorps xmm3,xmm0
+ xorps xmm4,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+
+$L$enc_loop3::
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ dec eax
+DB 102,15,56,220,225
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,220,208
+DB 102,15,56,220,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,220,224
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$enc_loop3
+
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+DB 102,15,56,220,225
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+DB 102,15,56,221,224
+ DB 0F3h,0C3h ;repret
+_aesni_encrypt3 ENDP
+
+ALIGN 16
+_aesni_decrypt3 PROC PRIVATE
+ movups xmm0,XMMWORD PTR[rcx]
+ shr eax,1
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+ xorps xmm3,xmm0
+ xorps xmm4,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+
+$L$dec_loop3::
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+ dec eax
+DB 102,15,56,222,225
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,222,208
+DB 102,15,56,222,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,222,224
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$dec_loop3
+
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+DB 102,15,56,222,225
+DB 102,15,56,223,208
+DB 102,15,56,223,216
+DB 102,15,56,223,224
+ DB 0F3h,0C3h ;repret
+_aesni_decrypt3 ENDP
+
+ALIGN 16
+_aesni_encrypt4 PROC PRIVATE
+ movups xmm0,XMMWORD PTR[rcx]
+ shr eax,1
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+ xorps xmm3,xmm0
+ xorps xmm4,xmm0
+ xorps xmm5,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+
+$L$enc_loop4::
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ dec eax
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,220,208
+DB 102,15,56,220,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,220,224
+DB 102,15,56,220,232
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$enc_loop4
+
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+DB 102,15,56,221,224
+DB 102,15,56,221,232
+ DB 0F3h,0C3h ;repret
+_aesni_encrypt4 ENDP
+
+ALIGN 16
+_aesni_decrypt4 PROC PRIVATE
+ movups xmm0,XMMWORD PTR[rcx]
+ shr eax,1
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+ xorps xmm3,xmm0
+ xorps xmm4,xmm0
+ xorps xmm5,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+
+$L$dec_loop4::
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+ dec eax
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,222,208
+DB 102,15,56,222,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,222,224
+DB 102,15,56,222,232
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$dec_loop4
+
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+DB 102,15,56,223,208
+DB 102,15,56,223,216
+DB 102,15,56,223,224
+DB 102,15,56,223,232
+ DB 0F3h,0C3h ;repret
+_aesni_decrypt4 ENDP
+
+ALIGN 16
+_aesni_encrypt6 PROC PRIVATE
+ movups xmm0,XMMWORD PTR[rcx]
+ shr eax,1
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+ pxor xmm3,xmm0
+DB 102,15,56,220,209
+ pxor xmm4,xmm0
+DB 102,15,56,220,217
+ pxor xmm5,xmm0
+DB 102,15,56,220,225
+ pxor xmm6,xmm0
+DB 102,15,56,220,233
+ pxor xmm7,xmm0
+ dec eax
+DB 102,15,56,220,241
+ movups xmm0,XMMWORD PTR[rcx]
+DB 102,15,56,220,249
+ jmp $L$enc_loop6_enter
+ALIGN 16
+$L$enc_loop6::
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ dec eax
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+$L$enc_loop6_enter::
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,220,208
+DB 102,15,56,220,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,220,224
+DB 102,15,56,220,232
+DB 102,15,56,220,240
+DB 102,15,56,220,248
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$enc_loop6
+
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+DB 102,15,56,221,224
+DB 102,15,56,221,232
+DB 102,15,56,221,240
+DB 102,15,56,221,248
+ DB 0F3h,0C3h ;repret
+_aesni_encrypt6 ENDP
+
+ALIGN 16
+_aesni_decrypt6 PROC PRIVATE
+ movups xmm0,XMMWORD PTR[rcx]
+ shr eax,1
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+ pxor xmm3,xmm0
+DB 102,15,56,222,209
+ pxor xmm4,xmm0
+DB 102,15,56,222,217
+ pxor xmm5,xmm0
+DB 102,15,56,222,225
+ pxor xmm6,xmm0
+DB 102,15,56,222,233
+ pxor xmm7,xmm0
+ dec eax
+DB 102,15,56,222,241
+ movups xmm0,XMMWORD PTR[rcx]
+DB 102,15,56,222,249
+ jmp $L$dec_loop6_enter
+ALIGN 16
+$L$dec_loop6::
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+ dec eax
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+DB 102,15,56,222,241
+DB 102,15,56,222,249
+$L$dec_loop6_enter::
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,222,208
+DB 102,15,56,222,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,222,224
+DB 102,15,56,222,232
+DB 102,15,56,222,240
+DB 102,15,56,222,248
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$dec_loop6
+
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+DB 102,15,56,222,241
+DB 102,15,56,222,249
+DB 102,15,56,223,208
+DB 102,15,56,223,216
+DB 102,15,56,223,224
+DB 102,15,56,223,232
+DB 102,15,56,223,240
+DB 102,15,56,223,248
+ DB 0F3h,0C3h ;repret
+_aesni_decrypt6 ENDP
+
+ALIGN 16
+_aesni_encrypt8 PROC PRIVATE
+ movups xmm0,XMMWORD PTR[rcx]
+ shr eax,1
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+ xorps xmm3,xmm0
+DB 102,15,56,220,209
+ pxor xmm4,xmm0
+DB 102,15,56,220,217
+ pxor xmm5,xmm0
+DB 102,15,56,220,225
+ pxor xmm6,xmm0
+DB 102,15,56,220,233
+ pxor xmm7,xmm0
+ dec eax
+DB 102,15,56,220,241
+ pxor xmm8,xmm0
+DB 102,15,56,220,249
+ pxor xmm9,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+DB 102,68,15,56,220,193
+DB 102,68,15,56,220,201
+ movups xmm1,XMMWORD PTR[16+rcx]
+ jmp $L$enc_loop8_enter
+ALIGN 16
+$L$enc_loop8::
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ dec eax
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+DB 102,68,15,56,220,193
+DB 102,68,15,56,220,201
+ movups xmm1,XMMWORD PTR[16+rcx]
+$L$enc_loop8_enter::
+DB 102,15,56,220,208
+DB 102,15,56,220,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,220,224
+DB 102,15,56,220,232
+DB 102,15,56,220,240
+DB 102,15,56,220,248
+DB 102,68,15,56,220,192
+DB 102,68,15,56,220,200
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$enc_loop8
+
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+DB 102,68,15,56,220,193
+DB 102,68,15,56,220,201
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+DB 102,15,56,221,224
+DB 102,15,56,221,232
+DB 102,15,56,221,240
+DB 102,15,56,221,248
+DB 102,68,15,56,221,192
+DB 102,68,15,56,221,200
+ DB 0F3h,0C3h ;repret
+_aesni_encrypt8 ENDP
+
+ALIGN 16
+_aesni_decrypt8 PROC PRIVATE
+ movups xmm0,XMMWORD PTR[rcx]
+ shr eax,1
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+ xorps xmm3,xmm0
+DB 102,15,56,222,209
+ pxor xmm4,xmm0
+DB 102,15,56,222,217
+ pxor xmm5,xmm0
+DB 102,15,56,222,225
+ pxor xmm6,xmm0
+DB 102,15,56,222,233
+ pxor xmm7,xmm0
+ dec eax
+DB 102,15,56,222,241
+ pxor xmm8,xmm0
+DB 102,15,56,222,249
+ pxor xmm9,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+DB 102,68,15,56,222,193
+DB 102,68,15,56,222,201
+ movups xmm1,XMMWORD PTR[16+rcx]
+ jmp $L$dec_loop8_enter
+ALIGN 16
+$L$dec_loop8::
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+ dec eax
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+DB 102,15,56,222,241
+DB 102,15,56,222,249
+DB 102,68,15,56,222,193
+DB 102,68,15,56,222,201
+ movups xmm1,XMMWORD PTR[16+rcx]
+$L$dec_loop8_enter::
+DB 102,15,56,222,208
+DB 102,15,56,222,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,222,224
+DB 102,15,56,222,232
+DB 102,15,56,222,240
+DB 102,15,56,222,248
+DB 102,68,15,56,222,192
+DB 102,68,15,56,222,200
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$dec_loop8
+
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+DB 102,15,56,222,241
+DB 102,15,56,222,249
+DB 102,68,15,56,222,193
+DB 102,68,15,56,222,201
+DB 102,15,56,223,208
+DB 102,15,56,223,216
+DB 102,15,56,223,224
+DB 102,15,56,223,232
+DB 102,15,56,223,240
+DB 102,15,56,223,248
+DB 102,68,15,56,223,192
+DB 102,68,15,56,223,200
+ DB 0F3h,0C3h ;repret
+_aesni_decrypt8 ENDP
+PUBLIC aesni_ecb_encrypt
+
+ALIGN 16
+aesni_ecb_encrypt PROC PUBLIC
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_aesni_ecb_encrypt::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+
+
+ and rdx,-16
+ jz $L$ecb_ret
+
+ mov eax,DWORD PTR[240+rcx]
+ movups xmm0,XMMWORD PTR[rcx]
+ mov r11,rcx
+ mov r10d,eax
+ test r8d,r8d
+ jz $L$ecb_decrypt
+
+ cmp rdx,080h
+ jb $L$ecb_enc_tail
+
+ movdqu xmm2,XMMWORD PTR[rdi]
+ movdqu xmm3,XMMWORD PTR[16+rdi]
+ movdqu xmm4,XMMWORD PTR[32+rdi]
+ movdqu xmm5,XMMWORD PTR[48+rdi]
+ movdqu xmm6,XMMWORD PTR[64+rdi]
+ movdqu xmm7,XMMWORD PTR[80+rdi]
+ movdqu xmm8,XMMWORD PTR[96+rdi]
+ movdqu xmm9,XMMWORD PTR[112+rdi]
+ lea rdi,QWORD PTR[128+rdi]
+ sub rdx,080h
+ jmp $L$ecb_enc_loop8_enter
+ALIGN 16
+$L$ecb_enc_loop8::
+ movups XMMWORD PTR[rsi],xmm2
+ mov rcx,r11
+ movdqu xmm2,XMMWORD PTR[rdi]
+ mov eax,r10d
+ movups XMMWORD PTR[16+rsi],xmm3
+ movdqu xmm3,XMMWORD PTR[16+rdi]
+ movups XMMWORD PTR[32+rsi],xmm4
+ movdqu xmm4,XMMWORD PTR[32+rdi]
+ movups XMMWORD PTR[48+rsi],xmm5
+ movdqu xmm5,XMMWORD PTR[48+rdi]
+ movups XMMWORD PTR[64+rsi],xmm6
+ movdqu xmm6,XMMWORD PTR[64+rdi]
+ movups XMMWORD PTR[80+rsi],xmm7
+ movdqu xmm7,XMMWORD PTR[80+rdi]
+ movups XMMWORD PTR[96+rsi],xmm8
+ movdqu xmm8,XMMWORD PTR[96+rdi]
+ movups XMMWORD PTR[112+rsi],xmm9
+ lea rsi,QWORD PTR[128+rsi]
+ movdqu xmm9,XMMWORD PTR[112+rdi]
+ lea rdi,QWORD PTR[128+rdi]
+$L$ecb_enc_loop8_enter::
+
+ call _aesni_encrypt8
+
+ sub rdx,080h
+ jnc $L$ecb_enc_loop8
+
+ movups XMMWORD PTR[rsi],xmm2
+ mov rcx,r11
+ movups XMMWORD PTR[16+rsi],xmm3
+ mov eax,r10d
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ movups XMMWORD PTR[64+rsi],xmm6
+ movups XMMWORD PTR[80+rsi],xmm7
+ movups XMMWORD PTR[96+rsi],xmm8
+ movups XMMWORD PTR[112+rsi],xmm9
+ lea rsi,QWORD PTR[128+rsi]
+ add rdx,080h
+ jz $L$ecb_ret
+
+$L$ecb_enc_tail::
+ movups xmm2,XMMWORD PTR[rdi]
+ cmp rdx,020h
+ jb $L$ecb_enc_one
+ movups xmm3,XMMWORD PTR[16+rdi]
+ je $L$ecb_enc_two
+ movups xmm4,XMMWORD PTR[32+rdi]
+ cmp rdx,040h
+ jb $L$ecb_enc_three
+ movups xmm5,XMMWORD PTR[48+rdi]
+ je $L$ecb_enc_four
+ movups xmm6,XMMWORD PTR[64+rdi]
+ cmp rdx,060h
+ jb $L$ecb_enc_five
+ movups xmm7,XMMWORD PTR[80+rdi]
+ je $L$ecb_enc_six
+ movdqu xmm8,XMMWORD PTR[96+rdi]
+ call _aesni_encrypt8
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ movups XMMWORD PTR[64+rsi],xmm6
+ movups XMMWORD PTR[80+rsi],xmm7
+ movups XMMWORD PTR[96+rsi],xmm8
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_enc_one::
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+$L$oop_enc1_3::
+DB 102,15,56,220,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_enc1_3
+
+DB 102,15,56,221,209
+ movups XMMWORD PTR[rsi],xmm2
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_enc_two::
+ xorps xmm4,xmm4
+ call _aesni_encrypt3
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_enc_three::
+ call _aesni_encrypt3
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_enc_four::
+ call _aesni_encrypt4
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_enc_five::
+ xorps xmm7,xmm7
+ call _aesni_encrypt6
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ movups XMMWORD PTR[64+rsi],xmm6
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_enc_six::
+ call _aesni_encrypt6
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ movups XMMWORD PTR[64+rsi],xmm6
+ movups XMMWORD PTR[80+rsi],xmm7
+ jmp $L$ecb_ret
+
+ALIGN 16
+$L$ecb_decrypt::
+ cmp rdx,080h
+ jb $L$ecb_dec_tail
+
+ movdqu xmm2,XMMWORD PTR[rdi]
+ movdqu xmm3,XMMWORD PTR[16+rdi]
+ movdqu xmm4,XMMWORD PTR[32+rdi]
+ movdqu xmm5,XMMWORD PTR[48+rdi]
+ movdqu xmm6,XMMWORD PTR[64+rdi]
+ movdqu xmm7,XMMWORD PTR[80+rdi]
+ movdqu xmm8,XMMWORD PTR[96+rdi]
+ movdqu xmm9,XMMWORD PTR[112+rdi]
+ lea rdi,QWORD PTR[128+rdi]
+ sub rdx,080h
+ jmp $L$ecb_dec_loop8_enter
+ALIGN 16
+$L$ecb_dec_loop8::
+ movups XMMWORD PTR[rsi],xmm2
+ mov rcx,r11
+ movdqu xmm2,XMMWORD PTR[rdi]
+ mov eax,r10d
+ movups XMMWORD PTR[16+rsi],xmm3
+ movdqu xmm3,XMMWORD PTR[16+rdi]
+ movups XMMWORD PTR[32+rsi],xmm4
+ movdqu xmm4,XMMWORD PTR[32+rdi]
+ movups XMMWORD PTR[48+rsi],xmm5
+ movdqu xmm5,XMMWORD PTR[48+rdi]
+ movups XMMWORD PTR[64+rsi],xmm6
+ movdqu xmm6,XMMWORD PTR[64+rdi]
+ movups XMMWORD PTR[80+rsi],xmm7
+ movdqu xmm7,XMMWORD PTR[80+rdi]
+ movups XMMWORD PTR[96+rsi],xmm8
+ movdqu xmm8,XMMWORD PTR[96+rdi]
+ movups XMMWORD PTR[112+rsi],xmm9
+ lea rsi,QWORD PTR[128+rsi]
+ movdqu xmm9,XMMWORD PTR[112+rdi]
+ lea rdi,QWORD PTR[128+rdi]
+$L$ecb_dec_loop8_enter::
+
+ call _aesni_decrypt8
+
+ movups xmm0,XMMWORD PTR[r11]
+ sub rdx,080h
+ jnc $L$ecb_dec_loop8
+
+ movups XMMWORD PTR[rsi],xmm2
+ mov rcx,r11
+ movups XMMWORD PTR[16+rsi],xmm3
+ mov eax,r10d
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ movups XMMWORD PTR[64+rsi],xmm6
+ movups XMMWORD PTR[80+rsi],xmm7
+ movups XMMWORD PTR[96+rsi],xmm8
+ movups XMMWORD PTR[112+rsi],xmm9
+ lea rsi,QWORD PTR[128+rsi]
+ add rdx,080h
+ jz $L$ecb_ret
+
+$L$ecb_dec_tail::
+ movups xmm2,XMMWORD PTR[rdi]
+ cmp rdx,020h
+ jb $L$ecb_dec_one
+ movups xmm3,XMMWORD PTR[16+rdi]
+ je $L$ecb_dec_two
+ movups xmm4,XMMWORD PTR[32+rdi]
+ cmp rdx,040h
+ jb $L$ecb_dec_three
+ movups xmm5,XMMWORD PTR[48+rdi]
+ je $L$ecb_dec_four
+ movups xmm6,XMMWORD PTR[64+rdi]
+ cmp rdx,060h
+ jb $L$ecb_dec_five
+ movups xmm7,XMMWORD PTR[80+rdi]
+ je $L$ecb_dec_six
+ movups xmm8,XMMWORD PTR[96+rdi]
+ movups xmm0,XMMWORD PTR[rcx]
+ call _aesni_decrypt8
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ movups XMMWORD PTR[64+rsi],xmm6
+ movups XMMWORD PTR[80+rsi],xmm7
+ movups XMMWORD PTR[96+rsi],xmm8
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_dec_one::
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+$L$oop_dec1_4::
+DB 102,15,56,222,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_dec1_4
+
+DB 102,15,56,223,209
+ movups XMMWORD PTR[rsi],xmm2
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_dec_two::
+ xorps xmm4,xmm4
+ call _aesni_decrypt3
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_dec_three::
+ call _aesni_decrypt3
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_dec_four::
+ call _aesni_decrypt4
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_dec_five::
+ xorps xmm7,xmm7
+ call _aesni_decrypt6
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ movups XMMWORD PTR[64+rsi],xmm6
+ jmp $L$ecb_ret
+ALIGN 16
+$L$ecb_dec_six::
+ call _aesni_decrypt6
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ movups XMMWORD PTR[64+rsi],xmm6
+ movups XMMWORD PTR[80+rsi],xmm7
+
+$L$ecb_ret::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_aesni_ecb_encrypt::
+aesni_ecb_encrypt ENDP
+PUBLIC aesni_ccm64_encrypt_blocks
+
+ALIGN 16
+aesni_ccm64_encrypt_blocks PROC PUBLIC
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_aesni_ccm64_encrypt_blocks::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+ mov r9,QWORD PTR[48+rsp]
+
+
+ lea rsp,QWORD PTR[((-88))+rsp]
+ movaps XMMWORD PTR[rsp],xmm6
+ movaps XMMWORD PTR[16+rsp],xmm7
+ movaps XMMWORD PTR[32+rsp],xmm8
+ movaps XMMWORD PTR[48+rsp],xmm9
+$L$ccm64_enc_body::
+ mov eax,DWORD PTR[240+rcx]
+ movdqu xmm9,XMMWORD PTR[r8]
+ movdqa xmm6,XMMWORD PTR[$L$increment64]
+ movdqa xmm7,XMMWORD PTR[$L$bswap_mask]
+
+ shr eax,1
+ lea r11,QWORD PTR[rcx]
+ movdqu xmm3,XMMWORD PTR[r9]
+ movdqa xmm2,xmm9
+ mov r10d,eax
+DB 102,68,15,56,0,207
+ jmp $L$ccm64_enc_outer
+ALIGN 16
+$L$ccm64_enc_outer::
+ movups xmm0,XMMWORD PTR[r11]
+ mov eax,r10d
+ movups xmm8,XMMWORD PTR[rdi]
+
+ xorps xmm2,xmm0
+ movups xmm1,XMMWORD PTR[16+r11]
+ xorps xmm0,xmm8
+ lea rcx,QWORD PTR[32+r11]
+ xorps xmm3,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+
+$L$ccm64_enc2_loop::
+DB 102,15,56,220,209
+ dec eax
+DB 102,15,56,220,217
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,220,208
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,220,216
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$ccm64_enc2_loop
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ paddq xmm9,xmm6
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+
+ dec rdx
+ lea rdi,QWORD PTR[16+rdi]
+ xorps xmm8,xmm2
+ movdqa xmm2,xmm9
+ movups XMMWORD PTR[rsi],xmm8
+ lea rsi,QWORD PTR[16+rsi]
+DB 102,15,56,0,215
+ jnz $L$ccm64_enc_outer
+
+ movups XMMWORD PTR[r9],xmm3
+ movaps xmm6,XMMWORD PTR[rsp]
+ movaps xmm7,XMMWORD PTR[16+rsp]
+ movaps xmm8,XMMWORD PTR[32+rsp]
+ movaps xmm9,XMMWORD PTR[48+rsp]
+ lea rsp,QWORD PTR[88+rsp]
+$L$ccm64_enc_ret::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_aesni_ccm64_encrypt_blocks::
+aesni_ccm64_encrypt_blocks ENDP
+PUBLIC aesni_ccm64_decrypt_blocks
+
+ALIGN 16
+aesni_ccm64_decrypt_blocks PROC PUBLIC
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_aesni_ccm64_decrypt_blocks::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+ mov r9,QWORD PTR[48+rsp]
+
+
+ lea rsp,QWORD PTR[((-88))+rsp]
+ movaps XMMWORD PTR[rsp],xmm6
+ movaps XMMWORD PTR[16+rsp],xmm7
+ movaps XMMWORD PTR[32+rsp],xmm8
+ movaps XMMWORD PTR[48+rsp],xmm9
+$L$ccm64_dec_body::
+ mov eax,DWORD PTR[240+rcx]
+ movups xmm9,XMMWORD PTR[r8]
+ movdqu xmm3,XMMWORD PTR[r9]
+ movdqa xmm6,XMMWORD PTR[$L$increment64]
+ movdqa xmm7,XMMWORD PTR[$L$bswap_mask]
+
+ movaps xmm2,xmm9
+ mov r10d,eax
+ mov r11,rcx
+DB 102,68,15,56,0,207
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+$L$oop_enc1_5::
+DB 102,15,56,220,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_enc1_5
+
+DB 102,15,56,221,209
+ movups xmm8,XMMWORD PTR[rdi]
+ paddq xmm9,xmm6
+ lea rdi,QWORD PTR[16+rdi]
+ jmp $L$ccm64_dec_outer
+ALIGN 16
+$L$ccm64_dec_outer::
+ xorps xmm8,xmm2
+ movdqa xmm2,xmm9
+ mov eax,r10d
+ movups XMMWORD PTR[rsi],xmm8
+ lea rsi,QWORD PTR[16+rsi]
+DB 102,15,56,0,215
+
+ sub rdx,1
+ jz $L$ccm64_dec_break
+
+ movups xmm0,XMMWORD PTR[r11]
+ shr eax,1
+ movups xmm1,XMMWORD PTR[16+r11]
+ xorps xmm8,xmm0
+ lea rcx,QWORD PTR[32+r11]
+ xorps xmm2,xmm0
+ xorps xmm3,xmm8
+ movups xmm0,XMMWORD PTR[rcx]
+
+$L$ccm64_dec2_loop::
+DB 102,15,56,220,209
+ dec eax
+DB 102,15,56,220,217
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,220,208
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,220,216
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$ccm64_dec2_loop
+ movups xmm8,XMMWORD PTR[rdi]
+ paddq xmm9,xmm6
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ lea rdi,QWORD PTR[16+rdi]
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+ jmp $L$ccm64_dec_outer
+
+ALIGN 16
+$L$ccm64_dec_break::
+
+ movups xmm0,XMMWORD PTR[r11]
+ movups xmm1,XMMWORD PTR[16+r11]
+ xorps xmm8,xmm0
+ lea r11,QWORD PTR[32+r11]
+ xorps xmm3,xmm8
+$L$oop_enc1_6::
+DB 102,15,56,220,217
+ dec eax
+ movups xmm1,XMMWORD PTR[r11]
+ lea r11,QWORD PTR[16+r11]
+ jnz $L$oop_enc1_6
+
+DB 102,15,56,221,217
+ movups XMMWORD PTR[r9],xmm3
+ movaps xmm6,XMMWORD PTR[rsp]
+ movaps xmm7,XMMWORD PTR[16+rsp]
+ movaps xmm8,XMMWORD PTR[32+rsp]
+ movaps xmm9,XMMWORD PTR[48+rsp]
+ lea rsp,QWORD PTR[88+rsp]
+$L$ccm64_dec_ret::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_aesni_ccm64_decrypt_blocks::
+aesni_ccm64_decrypt_blocks ENDP
+PUBLIC aesni_ctr32_encrypt_blocks
+
+ALIGN 16
+aesni_ctr32_encrypt_blocks PROC PUBLIC
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_aesni_ctr32_encrypt_blocks::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+
+
+ lea rsp,QWORD PTR[((-200))+rsp]
+ movaps XMMWORD PTR[32+rsp],xmm6
+ movaps XMMWORD PTR[48+rsp],xmm7
+ movaps XMMWORD PTR[64+rsp],xmm8
+ movaps XMMWORD PTR[80+rsp],xmm9
+ movaps XMMWORD PTR[96+rsp],xmm10
+ movaps XMMWORD PTR[112+rsp],xmm11
+ movaps XMMWORD PTR[128+rsp],xmm12
+ movaps XMMWORD PTR[144+rsp],xmm13
+ movaps XMMWORD PTR[160+rsp],xmm14
+ movaps XMMWORD PTR[176+rsp],xmm15
+$L$ctr32_body::
+ cmp rdx,1
+ je $L$ctr32_one_shortcut
+
+ movdqu xmm14,XMMWORD PTR[r8]
+ movdqa xmm15,XMMWORD PTR[$L$bswap_mask]
+ xor eax,eax
+DB 102,69,15,58,22,242,3
+DB 102,68,15,58,34,240,3
+
+ mov eax,DWORD PTR[240+rcx]
+ bswap r10d
+ pxor xmm12,xmm12
+ pxor xmm13,xmm13
+DB 102,69,15,58,34,226,0
+ lea r11,QWORD PTR[3+r10]
+DB 102,69,15,58,34,235,0
+ inc r10d
+DB 102,69,15,58,34,226,1
+ inc r11
+DB 102,69,15,58,34,235,1
+ inc r10d
+DB 102,69,15,58,34,226,2
+ inc r11
+DB 102,69,15,58,34,235,2
+ movdqa XMMWORD PTR[rsp],xmm12
+DB 102,69,15,56,0,231
+ movdqa XMMWORD PTR[16+rsp],xmm13
+DB 102,69,15,56,0,239
+
+ pshufd xmm2,xmm12,192
+ pshufd xmm3,xmm12,128
+ pshufd xmm4,xmm12,64
+ cmp rdx,6
+ jb $L$ctr32_tail
+ shr eax,1
+ mov r11,rcx
+ mov r10d,eax
+ sub rdx,6
+ jmp $L$ctr32_loop6
+
+ALIGN 16
+$L$ctr32_loop6::
+ pshufd xmm5,xmm13,192
+ por xmm2,xmm14
+ movups xmm0,XMMWORD PTR[r11]
+ pshufd xmm6,xmm13,128
+ por xmm3,xmm14
+ movups xmm1,XMMWORD PTR[16+r11]
+ pshufd xmm7,xmm13,64
+ por xmm4,xmm14
+ por xmm5,xmm14
+ xorps xmm2,xmm0
+ por xmm6,xmm14
+ por xmm7,xmm14
+
+
+
+
+ pxor xmm3,xmm0
+DB 102,15,56,220,209
+ lea rcx,QWORD PTR[32+r11]
+ pxor xmm4,xmm0
+DB 102,15,56,220,217
+ movdqa xmm13,XMMWORD PTR[$L$increment32]
+ pxor xmm5,xmm0
+DB 102,15,56,220,225
+ movdqa xmm12,XMMWORD PTR[rsp]
+ pxor xmm6,xmm0
+DB 102,15,56,220,233
+ pxor xmm7,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+ dec eax
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+ jmp $L$ctr32_enc_loop6_enter
+ALIGN 16
+$L$ctr32_enc_loop6::
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ dec eax
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+$L$ctr32_enc_loop6_enter::
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,220,208
+DB 102,15,56,220,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,220,224
+DB 102,15,56,220,232
+DB 102,15,56,220,240
+DB 102,15,56,220,248
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$ctr32_enc_loop6
+
+DB 102,15,56,220,209
+ paddd xmm12,xmm13
+DB 102,15,56,220,217
+ paddd xmm13,XMMWORD PTR[16+rsp]
+DB 102,15,56,220,225
+ movdqa XMMWORD PTR[rsp],xmm12
+DB 102,15,56,220,233
+ movdqa XMMWORD PTR[16+rsp],xmm13
+DB 102,15,56,220,241
+DB 102,69,15,56,0,231
+DB 102,15,56,220,249
+DB 102,69,15,56,0,239
+
+DB 102,15,56,221,208
+ movups xmm8,XMMWORD PTR[rdi]
+DB 102,15,56,221,216
+ movups xmm9,XMMWORD PTR[16+rdi]
+DB 102,15,56,221,224
+ movups xmm10,XMMWORD PTR[32+rdi]
+DB 102,15,56,221,232
+ movups xmm11,XMMWORD PTR[48+rdi]
+DB 102,15,56,221,240
+ movups xmm1,XMMWORD PTR[64+rdi]
+DB 102,15,56,221,248
+ movups xmm0,XMMWORD PTR[80+rdi]
+ lea rdi,QWORD PTR[96+rdi]
+
+ xorps xmm8,xmm2
+ pshufd xmm2,xmm12,192
+ xorps xmm9,xmm3
+ pshufd xmm3,xmm12,128
+ movups XMMWORD PTR[rsi],xmm8
+ xorps xmm10,xmm4
+ pshufd xmm4,xmm12,64
+ movups XMMWORD PTR[16+rsi],xmm9
+ xorps xmm11,xmm5
+ movups XMMWORD PTR[32+rsi],xmm10
+ xorps xmm1,xmm6
+ movups XMMWORD PTR[48+rsi],xmm11
+ xorps xmm0,xmm7
+ movups XMMWORD PTR[64+rsi],xmm1
+ movups XMMWORD PTR[80+rsi],xmm0
+ lea rsi,QWORD PTR[96+rsi]
+ mov eax,r10d
+ sub rdx,6
+ jnc $L$ctr32_loop6
+
+ add rdx,6
+ jz $L$ctr32_done
+ mov rcx,r11
+ lea eax,DWORD PTR[1+rax*1+rax]
+
+$L$ctr32_tail::
+ por xmm2,xmm14
+ movups xmm8,XMMWORD PTR[rdi]
+ cmp rdx,2
+ jb $L$ctr32_one
+
+ por xmm3,xmm14
+ movups xmm9,XMMWORD PTR[16+rdi]
+ je $L$ctr32_two
+
+ pshufd xmm5,xmm13,192
+ por xmm4,xmm14
+ movups xmm10,XMMWORD PTR[32+rdi]
+ cmp rdx,4
+ jb $L$ctr32_three
+
+ pshufd xmm6,xmm13,128
+ por xmm5,xmm14
+ movups xmm11,XMMWORD PTR[48+rdi]
+ je $L$ctr32_four
+
+ por xmm6,xmm14
+ xorps xmm7,xmm7
+
+ call _aesni_encrypt6
+
+ movups xmm1,XMMWORD PTR[64+rdi]
+ xorps xmm8,xmm2
+ xorps xmm9,xmm3
+ movups XMMWORD PTR[rsi],xmm8
+ xorps xmm10,xmm4
+ movups XMMWORD PTR[16+rsi],xmm9
+ xorps xmm11,xmm5
+ movups XMMWORD PTR[32+rsi],xmm10
+ xorps xmm1,xmm6
+ movups XMMWORD PTR[48+rsi],xmm11
+ movups XMMWORD PTR[64+rsi],xmm1
+ jmp $L$ctr32_done
+
+ALIGN 16
+$L$ctr32_one_shortcut::
+ movups xmm2,XMMWORD PTR[r8]
+ movups xmm8,XMMWORD PTR[rdi]
+ mov eax,DWORD PTR[240+rcx]
+$L$ctr32_one::
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+$L$oop_enc1_7::
+DB 102,15,56,220,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_enc1_7
+
+DB 102,15,56,221,209
+ xorps xmm8,xmm2
+ movups XMMWORD PTR[rsi],xmm8
+ jmp $L$ctr32_done
+
+ALIGN 16
+$L$ctr32_two::
+ xorps xmm4,xmm4
+ call _aesni_encrypt3
+ xorps xmm8,xmm2
+ xorps xmm9,xmm3
+ movups XMMWORD PTR[rsi],xmm8
+ movups XMMWORD PTR[16+rsi],xmm9
+ jmp $L$ctr32_done
+
+ALIGN 16
+$L$ctr32_three::
+ call _aesni_encrypt3
+ xorps xmm8,xmm2
+ xorps xmm9,xmm3
+ movups XMMWORD PTR[rsi],xmm8
+ xorps xmm10,xmm4
+ movups XMMWORD PTR[16+rsi],xmm9
+ movups XMMWORD PTR[32+rsi],xmm10
+ jmp $L$ctr32_done
+
+ALIGN 16
+$L$ctr32_four::
+ call _aesni_encrypt4
+ xorps xmm8,xmm2
+ xorps xmm9,xmm3
+ movups XMMWORD PTR[rsi],xmm8
+ xorps xmm10,xmm4
+ movups XMMWORD PTR[16+rsi],xmm9
+ xorps xmm11,xmm5
+ movups XMMWORD PTR[32+rsi],xmm10
+ movups XMMWORD PTR[48+rsi],xmm11
+
+$L$ctr32_done::
+ movaps xmm6,XMMWORD PTR[32+rsp]
+ movaps xmm7,XMMWORD PTR[48+rsp]
+ movaps xmm8,XMMWORD PTR[64+rsp]
+ movaps xmm9,XMMWORD PTR[80+rsp]
+ movaps xmm10,XMMWORD PTR[96+rsp]
+ movaps xmm11,XMMWORD PTR[112+rsp]
+ movaps xmm12,XMMWORD PTR[128+rsp]
+ movaps xmm13,XMMWORD PTR[144+rsp]
+ movaps xmm14,XMMWORD PTR[160+rsp]
+ movaps xmm15,XMMWORD PTR[176+rsp]
+ lea rsp,QWORD PTR[200+rsp]
+$L$ctr32_ret::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_aesni_ctr32_encrypt_blocks::
+aesni_ctr32_encrypt_blocks ENDP
+PUBLIC aesni_xts_encrypt
+
+ALIGN 16
+aesni_xts_encrypt PROC PUBLIC
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_aesni_xts_encrypt::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+ mov r9,QWORD PTR[48+rsp]
+
+
+ lea rsp,QWORD PTR[((-264))+rsp]
+ movaps XMMWORD PTR[96+rsp],xmm6
+ movaps XMMWORD PTR[112+rsp],xmm7
+ movaps XMMWORD PTR[128+rsp],xmm8
+ movaps XMMWORD PTR[144+rsp],xmm9
+ movaps XMMWORD PTR[160+rsp],xmm10
+ movaps XMMWORD PTR[176+rsp],xmm11
+ movaps XMMWORD PTR[192+rsp],xmm12
+ movaps XMMWORD PTR[208+rsp],xmm13
+ movaps XMMWORD PTR[224+rsp],xmm14
+ movaps XMMWORD PTR[240+rsp],xmm15
+$L$xts_enc_body::
+ movups xmm15,XMMWORD PTR[r9]
+ mov eax,DWORD PTR[240+r8]
+ mov r10d,DWORD PTR[240+rcx]
+ movups xmm0,XMMWORD PTR[r8]
+ movups xmm1,XMMWORD PTR[16+r8]
+ lea r8,QWORD PTR[32+r8]
+ xorps xmm15,xmm0
+$L$oop_enc1_8::
+DB 102,68,15,56,220,249
+ dec eax
+ movups xmm1,XMMWORD PTR[r8]
+ lea r8,QWORD PTR[16+r8]
+ jnz $L$oop_enc1_8
+
+DB 102,68,15,56,221,249
+ mov r11,rcx
+ mov eax,r10d
+ mov r9,rdx
+ and rdx,-16
+
+ movdqa xmm8,XMMWORD PTR[$L$xts_magic]
+ pxor xmm14,xmm14
+ pcmpgtd xmm14,xmm15
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm10,xmm15
+ paddq xmm15,xmm15
+ pand xmm9,xmm8
+ pcmpgtd xmm14,xmm15
+ pxor xmm15,xmm9
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm11,xmm15
+ paddq xmm15,xmm15
+ pand xmm9,xmm8
+ pcmpgtd xmm14,xmm15
+ pxor xmm15,xmm9
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm12,xmm15
+ paddq xmm15,xmm15
+ pand xmm9,xmm8
+ pcmpgtd xmm14,xmm15
+ pxor xmm15,xmm9
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm13,xmm15
+ paddq xmm15,xmm15
+ pand xmm9,xmm8
+ pcmpgtd xmm14,xmm15
+ pxor xmm15,xmm9
+ sub rdx,16*6
+ jc $L$xts_enc_short
+
+ shr eax,1
+ sub eax,1
+ mov r10d,eax
+ jmp $L$xts_enc_grandloop
+
+ALIGN 16
+$L$xts_enc_grandloop::
+ pshufd xmm9,xmm14,013h
+ movdqa xmm14,xmm15
+ paddq xmm15,xmm15
+ movdqu xmm2,XMMWORD PTR[rdi]
+ pand xmm9,xmm8
+ movdqu xmm3,XMMWORD PTR[16+rdi]
+ pxor xmm15,xmm9
+
+ movdqu xmm4,XMMWORD PTR[32+rdi]
+ pxor xmm2,xmm10
+ movdqu xmm5,XMMWORD PTR[48+rdi]
+ pxor xmm3,xmm11
+ movdqu xmm6,XMMWORD PTR[64+rdi]
+ pxor xmm4,xmm12
+ movdqu xmm7,XMMWORD PTR[80+rdi]
+ lea rdi,QWORD PTR[96+rdi]
+ pxor xmm5,xmm13
+ movups xmm0,XMMWORD PTR[r11]
+ pxor xmm6,xmm14
+ pxor xmm7,xmm15
+
+
+
+ movups xmm1,XMMWORD PTR[16+r11]
+ pxor xmm2,xmm0
+ pxor xmm3,xmm0
+ movdqa XMMWORD PTR[rsp],xmm10
+DB 102,15,56,220,209
+ lea rcx,QWORD PTR[32+r11]
+ pxor xmm4,xmm0
+ movdqa XMMWORD PTR[16+rsp],xmm11
+DB 102,15,56,220,217
+ pxor xmm5,xmm0
+ movdqa XMMWORD PTR[32+rsp],xmm12
+DB 102,15,56,220,225
+ pxor xmm6,xmm0
+ movdqa XMMWORD PTR[48+rsp],xmm13
+DB 102,15,56,220,233
+ pxor xmm7,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+ dec eax
+ movdqa XMMWORD PTR[64+rsp],xmm14
+DB 102,15,56,220,241
+ movdqa XMMWORD PTR[80+rsp],xmm15
+DB 102,15,56,220,249
+ pxor xmm14,xmm14
+ pcmpgtd xmm14,xmm15
+ jmp $L$xts_enc_loop6_enter
+
+ALIGN 16
+$L$xts_enc_loop6::
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ dec eax
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+$L$xts_enc_loop6_enter::
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,220,208
+DB 102,15,56,220,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,220,224
+DB 102,15,56,220,232
+DB 102,15,56,220,240
+DB 102,15,56,220,248
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$xts_enc_loop6
+
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ paddq xmm15,xmm15
+DB 102,15,56,220,209
+ pand xmm9,xmm8
+DB 102,15,56,220,217
+ pcmpgtd xmm14,xmm15
+DB 102,15,56,220,225
+ pxor xmm15,xmm9
+DB 102,15,56,220,233
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+ movups xmm1,XMMWORD PTR[16+rcx]
+
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm10,xmm15
+ paddq xmm15,xmm15
+DB 102,15,56,220,208
+ pand xmm9,xmm8
+DB 102,15,56,220,216
+ pcmpgtd xmm14,xmm15
+DB 102,15,56,220,224
+ pxor xmm15,xmm9
+DB 102,15,56,220,232
+DB 102,15,56,220,240
+DB 102,15,56,220,248
+ movups xmm0,XMMWORD PTR[32+rcx]
+
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm11,xmm15
+ paddq xmm15,xmm15
+DB 102,15,56,220,209
+ pand xmm9,xmm8
+DB 102,15,56,220,217
+ pcmpgtd xmm14,xmm15
+DB 102,15,56,220,225
+ pxor xmm15,xmm9
+DB 102,15,56,220,233
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm12,xmm15
+ paddq xmm15,xmm15
+DB 102,15,56,221,208
+ pand xmm9,xmm8
+DB 102,15,56,221,216
+ pcmpgtd xmm14,xmm15
+DB 102,15,56,221,224
+ pxor xmm15,xmm9
+DB 102,15,56,221,232
+DB 102,15,56,221,240
+DB 102,15,56,221,248
+
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm13,xmm15
+ paddq xmm15,xmm15
+ xorps xmm2,XMMWORD PTR[rsp]
+ pand xmm9,xmm8
+ xorps xmm3,XMMWORD PTR[16+rsp]
+ pcmpgtd xmm14,xmm15
+ pxor xmm15,xmm9
+
+ xorps xmm4,XMMWORD PTR[32+rsp]
+ movups XMMWORD PTR[rsi],xmm2
+ xorps xmm5,XMMWORD PTR[48+rsp]
+ movups XMMWORD PTR[16+rsi],xmm3
+ xorps xmm6,XMMWORD PTR[64+rsp]
+ movups XMMWORD PTR[32+rsi],xmm4
+ xorps xmm7,XMMWORD PTR[80+rsp]
+ movups XMMWORD PTR[48+rsi],xmm5
+ mov eax,r10d
+ movups XMMWORD PTR[64+rsi],xmm6
+ movups XMMWORD PTR[80+rsi],xmm7
+ lea rsi,QWORD PTR[96+rsi]
+ sub rdx,16*6
+ jnc $L$xts_enc_grandloop
+
+ lea eax,DWORD PTR[3+rax*1+rax]
+ mov rcx,r11
+ mov r10d,eax
+
+$L$xts_enc_short::
+ add rdx,16*6
+ jz $L$xts_enc_done
+
+ cmp rdx,020h
+ jb $L$xts_enc_one
+ je $L$xts_enc_two
+
+ cmp rdx,040h
+ jb $L$xts_enc_three
+ je $L$xts_enc_four
+
+ pshufd xmm9,xmm14,013h
+ movdqa xmm14,xmm15
+ paddq xmm15,xmm15
+ movdqu xmm2,XMMWORD PTR[rdi]
+ pand xmm9,xmm8
+ movdqu xmm3,XMMWORD PTR[16+rdi]
+ pxor xmm15,xmm9
+
+ movdqu xmm4,XMMWORD PTR[32+rdi]
+ pxor xmm2,xmm10
+ movdqu xmm5,XMMWORD PTR[48+rdi]
+ pxor xmm3,xmm11
+ movdqu xmm6,XMMWORD PTR[64+rdi]
+ lea rdi,QWORD PTR[80+rdi]
+ pxor xmm4,xmm12
+ pxor xmm5,xmm13
+ pxor xmm6,xmm14
+
+ call _aesni_encrypt6
+
+ xorps xmm2,xmm10
+ movdqa xmm10,xmm15
+ xorps xmm3,xmm11
+ xorps xmm4,xmm12
+ movdqu XMMWORD PTR[rsi],xmm2
+ xorps xmm5,xmm13
+ movdqu XMMWORD PTR[16+rsi],xmm3
+ xorps xmm6,xmm14
+ movdqu XMMWORD PTR[32+rsi],xmm4
+ movdqu XMMWORD PTR[48+rsi],xmm5
+ movdqu XMMWORD PTR[64+rsi],xmm6
+ lea rsi,QWORD PTR[80+rsi]
+ jmp $L$xts_enc_done
+
+ALIGN 16
+$L$xts_enc_one::
+ movups xmm2,XMMWORD PTR[rdi]
+ lea rdi,QWORD PTR[16+rdi]
+ xorps xmm2,xmm10
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+$L$oop_enc1_9::
+DB 102,15,56,220,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_enc1_9
+
+DB 102,15,56,221,209
+ xorps xmm2,xmm10
+ movdqa xmm10,xmm11
+ movups XMMWORD PTR[rsi],xmm2
+ lea rsi,QWORD PTR[16+rsi]
+ jmp $L$xts_enc_done
+
+ALIGN 16
+$L$xts_enc_two::
+ movups xmm2,XMMWORD PTR[rdi]
+ movups xmm3,XMMWORD PTR[16+rdi]
+ lea rdi,QWORD PTR[32+rdi]
+ xorps xmm2,xmm10
+ xorps xmm3,xmm11
+
+ call _aesni_encrypt3
+
+ xorps xmm2,xmm10
+ movdqa xmm10,xmm12
+ xorps xmm3,xmm11
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ lea rsi,QWORD PTR[32+rsi]
+ jmp $L$xts_enc_done
+
+ALIGN 16
+$L$xts_enc_three::
+ movups xmm2,XMMWORD PTR[rdi]
+ movups xmm3,XMMWORD PTR[16+rdi]
+ movups xmm4,XMMWORD PTR[32+rdi]
+ lea rdi,QWORD PTR[48+rdi]
+ xorps xmm2,xmm10
+ xorps xmm3,xmm11
+ xorps xmm4,xmm12
+
+ call _aesni_encrypt3
+
+ xorps xmm2,xmm10
+ movdqa xmm10,xmm13
+ xorps xmm3,xmm11
+ xorps xmm4,xmm12
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ lea rsi,QWORD PTR[48+rsi]
+ jmp $L$xts_enc_done
+
+ALIGN 16
+$L$xts_enc_four::
+ movups xmm2,XMMWORD PTR[rdi]
+ movups xmm3,XMMWORD PTR[16+rdi]
+ movups xmm4,XMMWORD PTR[32+rdi]
+ xorps xmm2,xmm10
+ movups xmm5,XMMWORD PTR[48+rdi]
+ lea rdi,QWORD PTR[64+rdi]
+ xorps xmm3,xmm11
+ xorps xmm4,xmm12
+ xorps xmm5,xmm13
+
+ call _aesni_encrypt4
+
+ xorps xmm2,xmm10
+ movdqa xmm10,xmm15
+ xorps xmm3,xmm11
+ xorps xmm4,xmm12
+ movups XMMWORD PTR[rsi],xmm2
+ xorps xmm5,xmm13
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ lea rsi,QWORD PTR[64+rsi]
+ jmp $L$xts_enc_done
+
+ALIGN 16
+$L$xts_enc_done::
+ and r9,15
+ jz $L$xts_enc_ret
+ mov rdx,r9
+
+$L$xts_enc_steal::
+ movzx eax,BYTE PTR[rdi]
+ movzx ecx,BYTE PTR[((-16))+rsi]
+ lea rdi,QWORD PTR[1+rdi]
+ mov BYTE PTR[((-16))+rsi],al
+ mov BYTE PTR[rsi],cl
+ lea rsi,QWORD PTR[1+rsi]
+ sub rdx,1
+ jnz $L$xts_enc_steal
+
+ sub rsi,r9
+ mov rcx,r11
+ mov eax,r10d
+
+ movups xmm2,XMMWORD PTR[((-16))+rsi]
+ xorps xmm2,xmm10
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+$L$oop_enc1_10::
+DB 102,15,56,220,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_enc1_10
+
+DB 102,15,56,221,209
+ xorps xmm2,xmm10
+ movups XMMWORD PTR[(-16)+rsi],xmm2
+
+$L$xts_enc_ret::
+ movaps xmm6,XMMWORD PTR[96+rsp]
+ movaps xmm7,XMMWORD PTR[112+rsp]
+ movaps xmm8,XMMWORD PTR[128+rsp]
+ movaps xmm9,XMMWORD PTR[144+rsp]
+ movaps xmm10,XMMWORD PTR[160+rsp]
+ movaps xmm11,XMMWORD PTR[176+rsp]
+ movaps xmm12,XMMWORD PTR[192+rsp]
+ movaps xmm13,XMMWORD PTR[208+rsp]
+ movaps xmm14,XMMWORD PTR[224+rsp]
+ movaps xmm15,XMMWORD PTR[240+rsp]
+ lea rsp,QWORD PTR[264+rsp]
+$L$xts_enc_epilogue::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_aesni_xts_encrypt::
+aesni_xts_encrypt ENDP
+PUBLIC aesni_xts_decrypt
+
+ALIGN 16
+aesni_xts_decrypt PROC PUBLIC
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_aesni_xts_decrypt::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+ mov r9,QWORD PTR[48+rsp]
+
+
+ lea rsp,QWORD PTR[((-264))+rsp]
+ movaps XMMWORD PTR[96+rsp],xmm6
+ movaps XMMWORD PTR[112+rsp],xmm7
+ movaps XMMWORD PTR[128+rsp],xmm8
+ movaps XMMWORD PTR[144+rsp],xmm9
+ movaps XMMWORD PTR[160+rsp],xmm10
+ movaps XMMWORD PTR[176+rsp],xmm11
+ movaps XMMWORD PTR[192+rsp],xmm12
+ movaps XMMWORD PTR[208+rsp],xmm13
+ movaps XMMWORD PTR[224+rsp],xmm14
+ movaps XMMWORD PTR[240+rsp],xmm15
+$L$xts_dec_body::
+ movups xmm15,XMMWORD PTR[r9]
+ mov eax,DWORD PTR[240+r8]
+ mov r10d,DWORD PTR[240+rcx]
+ movups xmm0,XMMWORD PTR[r8]
+ movups xmm1,XMMWORD PTR[16+r8]
+ lea r8,QWORD PTR[32+r8]
+ xorps xmm15,xmm0
+$L$oop_enc1_11::
+DB 102,68,15,56,220,249
+ dec eax
+ movups xmm1,XMMWORD PTR[r8]
+ lea r8,QWORD PTR[16+r8]
+ jnz $L$oop_enc1_11
+
+DB 102,68,15,56,221,249
+ xor eax,eax
+ test rdx,15
+ setnz al
+ shl rax,4
+ sub rdx,rax
+
+ mov r11,rcx
+ mov eax,r10d
+ mov r9,rdx
+ and rdx,-16
+
+ movdqa xmm8,XMMWORD PTR[$L$xts_magic]
+ pxor xmm14,xmm14
+ pcmpgtd xmm14,xmm15
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm10,xmm15
+ paddq xmm15,xmm15
+ pand xmm9,xmm8
+ pcmpgtd xmm14,xmm15
+ pxor xmm15,xmm9
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm11,xmm15
+ paddq xmm15,xmm15
+ pand xmm9,xmm8
+ pcmpgtd xmm14,xmm15
+ pxor xmm15,xmm9
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm12,xmm15
+ paddq xmm15,xmm15
+ pand xmm9,xmm8
+ pcmpgtd xmm14,xmm15
+ pxor xmm15,xmm9
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm13,xmm15
+ paddq xmm15,xmm15
+ pand xmm9,xmm8
+ pcmpgtd xmm14,xmm15
+ pxor xmm15,xmm9
+ sub rdx,16*6
+ jc $L$xts_dec_short
+
+ shr eax,1
+ sub eax,1
+ mov r10d,eax
+ jmp $L$xts_dec_grandloop
+
+ALIGN 16
+$L$xts_dec_grandloop::
+ pshufd xmm9,xmm14,013h
+ movdqa xmm14,xmm15
+ paddq xmm15,xmm15
+ movdqu xmm2,XMMWORD PTR[rdi]
+ pand xmm9,xmm8
+ movdqu xmm3,XMMWORD PTR[16+rdi]
+ pxor xmm15,xmm9
+
+ movdqu xmm4,XMMWORD PTR[32+rdi]
+ pxor xmm2,xmm10
+ movdqu xmm5,XMMWORD PTR[48+rdi]
+ pxor xmm3,xmm11
+ movdqu xmm6,XMMWORD PTR[64+rdi]
+ pxor xmm4,xmm12
+ movdqu xmm7,XMMWORD PTR[80+rdi]
+ lea rdi,QWORD PTR[96+rdi]
+ pxor xmm5,xmm13
+ movups xmm0,XMMWORD PTR[r11]
+ pxor xmm6,xmm14
+ pxor xmm7,xmm15
+
+
+
+ movups xmm1,XMMWORD PTR[16+r11]
+ pxor xmm2,xmm0
+ pxor xmm3,xmm0
+ movdqa XMMWORD PTR[rsp],xmm10
+DB 102,15,56,222,209
+ lea rcx,QWORD PTR[32+r11]
+ pxor xmm4,xmm0
+ movdqa XMMWORD PTR[16+rsp],xmm11
+DB 102,15,56,222,217
+ pxor xmm5,xmm0
+ movdqa XMMWORD PTR[32+rsp],xmm12
+DB 102,15,56,222,225
+ pxor xmm6,xmm0
+ movdqa XMMWORD PTR[48+rsp],xmm13
+DB 102,15,56,222,233
+ pxor xmm7,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+ dec eax
+ movdqa XMMWORD PTR[64+rsp],xmm14
+DB 102,15,56,222,241
+ movdqa XMMWORD PTR[80+rsp],xmm15
+DB 102,15,56,222,249
+ pxor xmm14,xmm14
+ pcmpgtd xmm14,xmm15
+ jmp $L$xts_dec_loop6_enter
+
+ALIGN 16
+$L$xts_dec_loop6::
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+ dec eax
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+DB 102,15,56,222,241
+DB 102,15,56,222,249
+$L$xts_dec_loop6_enter::
+ movups xmm1,XMMWORD PTR[16+rcx]
+DB 102,15,56,222,208
+DB 102,15,56,222,216
+ lea rcx,QWORD PTR[32+rcx]
+DB 102,15,56,222,224
+DB 102,15,56,222,232
+DB 102,15,56,222,240
+DB 102,15,56,222,248
+ movups xmm0,XMMWORD PTR[rcx]
+ jnz $L$xts_dec_loop6
+
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ paddq xmm15,xmm15
+DB 102,15,56,222,209
+ pand xmm9,xmm8
+DB 102,15,56,222,217
+ pcmpgtd xmm14,xmm15
+DB 102,15,56,222,225
+ pxor xmm15,xmm9
+DB 102,15,56,222,233
+DB 102,15,56,222,241
+DB 102,15,56,222,249
+ movups xmm1,XMMWORD PTR[16+rcx]
+
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm10,xmm15
+ paddq xmm15,xmm15
+DB 102,15,56,222,208
+ pand xmm9,xmm8
+DB 102,15,56,222,216
+ pcmpgtd xmm14,xmm15
+DB 102,15,56,222,224
+ pxor xmm15,xmm9
+DB 102,15,56,222,232
+DB 102,15,56,222,240
+DB 102,15,56,222,248
+ movups xmm0,XMMWORD PTR[32+rcx]
+
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm11,xmm15
+ paddq xmm15,xmm15
+DB 102,15,56,222,209
+ pand xmm9,xmm8
+DB 102,15,56,222,217
+ pcmpgtd xmm14,xmm15
+DB 102,15,56,222,225
+ pxor xmm15,xmm9
+DB 102,15,56,222,233
+DB 102,15,56,222,241
+DB 102,15,56,222,249
+
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm12,xmm15
+ paddq xmm15,xmm15
+DB 102,15,56,223,208
+ pand xmm9,xmm8
+DB 102,15,56,223,216
+ pcmpgtd xmm14,xmm15
+DB 102,15,56,223,224
+ pxor xmm15,xmm9
+DB 102,15,56,223,232
+DB 102,15,56,223,240
+DB 102,15,56,223,248
+
+ pshufd xmm9,xmm14,013h
+ pxor xmm14,xmm14
+ movdqa xmm13,xmm15
+ paddq xmm15,xmm15
+ xorps xmm2,XMMWORD PTR[rsp]
+ pand xmm9,xmm8
+ xorps xmm3,XMMWORD PTR[16+rsp]
+ pcmpgtd xmm14,xmm15
+ pxor xmm15,xmm9
+
+ xorps xmm4,XMMWORD PTR[32+rsp]
+ movups XMMWORD PTR[rsi],xmm2
+ xorps xmm5,XMMWORD PTR[48+rsp]
+ movups XMMWORD PTR[16+rsi],xmm3
+ xorps xmm6,XMMWORD PTR[64+rsp]
+ movups XMMWORD PTR[32+rsi],xmm4
+ xorps xmm7,XMMWORD PTR[80+rsp]
+ movups XMMWORD PTR[48+rsi],xmm5
+ mov eax,r10d
+ movups XMMWORD PTR[64+rsi],xmm6
+ movups XMMWORD PTR[80+rsi],xmm7
+ lea rsi,QWORD PTR[96+rsi]
+ sub rdx,16*6
+ jnc $L$xts_dec_grandloop
+
+ lea eax,DWORD PTR[3+rax*1+rax]
+ mov rcx,r11
+ mov r10d,eax
+
+$L$xts_dec_short::
+ add rdx,16*6
+ jz $L$xts_dec_done
+
+ cmp rdx,020h
+ jb $L$xts_dec_one
+ je $L$xts_dec_two
+
+ cmp rdx,040h
+ jb $L$xts_dec_three
+ je $L$xts_dec_four
+
+ pshufd xmm9,xmm14,013h
+ movdqa xmm14,xmm15
+ paddq xmm15,xmm15
+ movdqu xmm2,XMMWORD PTR[rdi]
+ pand xmm9,xmm8
+ movdqu xmm3,XMMWORD PTR[16+rdi]
+ pxor xmm15,xmm9
+
+ movdqu xmm4,XMMWORD PTR[32+rdi]
+ pxor xmm2,xmm10
+ movdqu xmm5,XMMWORD PTR[48+rdi]
+ pxor xmm3,xmm11
+ movdqu xmm6,XMMWORD PTR[64+rdi]
+ lea rdi,QWORD PTR[80+rdi]
+ pxor xmm4,xmm12
+ pxor xmm5,xmm13
+ pxor xmm6,xmm14
+
+ call _aesni_decrypt6
+
+ xorps xmm2,xmm10
+ xorps xmm3,xmm11
+ xorps xmm4,xmm12
+ movdqu XMMWORD PTR[rsi],xmm2
+ xorps xmm5,xmm13
+ movdqu XMMWORD PTR[16+rsi],xmm3
+ xorps xmm6,xmm14
+ movdqu XMMWORD PTR[32+rsi],xmm4
+ pxor xmm14,xmm14
+ movdqu XMMWORD PTR[48+rsi],xmm5
+ pcmpgtd xmm14,xmm15
+ movdqu XMMWORD PTR[64+rsi],xmm6
+ lea rsi,QWORD PTR[80+rsi]
+ pshufd xmm11,xmm14,013h
+ and r9,15
+ jz $L$xts_dec_ret
+
+ movdqa xmm10,xmm15
+ paddq xmm15,xmm15
+ pand xmm11,xmm8
+ pxor xmm11,xmm15
+ jmp $L$xts_dec_done2
+
+ALIGN 16
+$L$xts_dec_one::
+ movups xmm2,XMMWORD PTR[rdi]
+ lea rdi,QWORD PTR[16+rdi]
+ xorps xmm2,xmm10
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+$L$oop_dec1_12::
+DB 102,15,56,222,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_dec1_12
+
+DB 102,15,56,223,209
+ xorps xmm2,xmm10
+ movdqa xmm10,xmm11
+ movups XMMWORD PTR[rsi],xmm2
+ movdqa xmm11,xmm12
+ lea rsi,QWORD PTR[16+rsi]
+ jmp $L$xts_dec_done
+
+ALIGN 16
+$L$xts_dec_two::
+ movups xmm2,XMMWORD PTR[rdi]
+ movups xmm3,XMMWORD PTR[16+rdi]
+ lea rdi,QWORD PTR[32+rdi]
+ xorps xmm2,xmm10
+ xorps xmm3,xmm11
+
+ call _aesni_decrypt3
+
+ xorps xmm2,xmm10
+ movdqa xmm10,xmm12
+ xorps xmm3,xmm11
+ movdqa xmm11,xmm13
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ lea rsi,QWORD PTR[32+rsi]
+ jmp $L$xts_dec_done
+
+ALIGN 16
+$L$xts_dec_three::
+ movups xmm2,XMMWORD PTR[rdi]
+ movups xmm3,XMMWORD PTR[16+rdi]
+ movups xmm4,XMMWORD PTR[32+rdi]
+ lea rdi,QWORD PTR[48+rdi]
+ xorps xmm2,xmm10
+ xorps xmm3,xmm11
+ xorps xmm4,xmm12
+
+ call _aesni_decrypt3
+
+ xorps xmm2,xmm10
+ movdqa xmm10,xmm13
+ xorps xmm3,xmm11
+ movdqa xmm11,xmm15
+ xorps xmm4,xmm12
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ lea rsi,QWORD PTR[48+rsi]
+ jmp $L$xts_dec_done
+
+ALIGN 16
+$L$xts_dec_four::
+ pshufd xmm9,xmm14,013h
+ movdqa xmm14,xmm15
+ paddq xmm15,xmm15
+ movups xmm2,XMMWORD PTR[rdi]
+ pand xmm9,xmm8
+ movups xmm3,XMMWORD PTR[16+rdi]
+ pxor xmm15,xmm9
+
+ movups xmm4,XMMWORD PTR[32+rdi]
+ xorps xmm2,xmm10
+ movups xmm5,XMMWORD PTR[48+rdi]
+ lea rdi,QWORD PTR[64+rdi]
+ xorps xmm3,xmm11
+ xorps xmm4,xmm12
+ xorps xmm5,xmm13
+
+ call _aesni_decrypt4
+
+ xorps xmm2,xmm10
+ movdqa xmm10,xmm14
+ xorps xmm3,xmm11
+ movdqa xmm11,xmm15
+ xorps xmm4,xmm12
+ movups XMMWORD PTR[rsi],xmm2
+ xorps xmm5,xmm13
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ lea rsi,QWORD PTR[64+rsi]
+ jmp $L$xts_dec_done
+
+ALIGN 16
+$L$xts_dec_done::
+ and r9,15
+ jz $L$xts_dec_ret
+$L$xts_dec_done2::
+ mov rdx,r9
+ mov rcx,r11
+ mov eax,r10d
+
+ movups xmm2,XMMWORD PTR[rdi]
+ xorps xmm2,xmm11
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+$L$oop_dec1_13::
+DB 102,15,56,222,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_dec1_13
+
+DB 102,15,56,223,209
+ xorps xmm2,xmm11
+ movups XMMWORD PTR[rsi],xmm2
+
+$L$xts_dec_steal::
+ movzx eax,BYTE PTR[16+rdi]
+ movzx ecx,BYTE PTR[rsi]
+ lea rdi,QWORD PTR[1+rdi]
+ mov BYTE PTR[rsi],al
+ mov BYTE PTR[16+rsi],cl
+ lea rsi,QWORD PTR[1+rsi]
+ sub rdx,1
+ jnz $L$xts_dec_steal
+
+ sub rsi,r9
+ mov rcx,r11
+ mov eax,r10d
+
+ movups xmm2,XMMWORD PTR[rsi]
+ xorps xmm2,xmm10
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+$L$oop_dec1_14::
+DB 102,15,56,222,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_dec1_14
+
+DB 102,15,56,223,209
+ xorps xmm2,xmm10
+ movups XMMWORD PTR[rsi],xmm2
+
+$L$xts_dec_ret::
+ movaps xmm6,XMMWORD PTR[96+rsp]
+ movaps xmm7,XMMWORD PTR[112+rsp]
+ movaps xmm8,XMMWORD PTR[128+rsp]
+ movaps xmm9,XMMWORD PTR[144+rsp]
+ movaps xmm10,XMMWORD PTR[160+rsp]
+ movaps xmm11,XMMWORD PTR[176+rsp]
+ movaps xmm12,XMMWORD PTR[192+rsp]
+ movaps xmm13,XMMWORD PTR[208+rsp]
+ movaps xmm14,XMMWORD PTR[224+rsp]
+ movaps xmm15,XMMWORD PTR[240+rsp]
+ lea rsp,QWORD PTR[264+rsp]
+$L$xts_dec_epilogue::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_aesni_xts_decrypt::
+aesni_xts_decrypt ENDP
+PUBLIC aesni_cbc_encrypt
+
+ALIGN 16
+aesni_cbc_encrypt PROC PUBLIC
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_aesni_cbc_encrypt::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+ mov r9,QWORD PTR[48+rsp]
+
+
+ test rdx,rdx
+ jz $L$cbc_ret
+
+ mov r10d,DWORD PTR[240+rcx]
+ mov r11,rcx
+ test r9d,r9d
+ jz $L$cbc_decrypt
+
+ movups xmm2,XMMWORD PTR[r8]
+ mov eax,r10d
+ cmp rdx,16
+ jb $L$cbc_enc_tail
+ sub rdx,16
+ jmp $L$cbc_enc_loop
+ALIGN 16
+$L$cbc_enc_loop::
+ movups xmm3,XMMWORD PTR[rdi]
+ lea rdi,QWORD PTR[16+rdi]
+
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ xorps xmm3,xmm0
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm3
+$L$oop_enc1_15::
+DB 102,15,56,220,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_enc1_15
+
+DB 102,15,56,221,209
+ mov eax,r10d
+ mov rcx,r11
+ movups XMMWORD PTR[rsi],xmm2
+ lea rsi,QWORD PTR[16+rsi]
+ sub rdx,16
+ jnc $L$cbc_enc_loop
+ add rdx,16
+ jnz $L$cbc_enc_tail
+ movups XMMWORD PTR[r8],xmm2
+ jmp $L$cbc_ret
+
+$L$cbc_enc_tail::
+ mov rcx,rdx
+ xchg rsi,rdi
+ DD 09066A4F3h
+
+ mov ecx,16
+ sub rcx,rdx
+ xor eax,eax
+ DD 09066AAF3h
+
+ lea rdi,QWORD PTR[((-16))+rdi]
+ mov eax,r10d
+ mov rsi,rdi
+ mov rcx,r11
+ xor rdx,rdx
+ jmp $L$cbc_enc_loop
+
+
+ALIGN 16
+$L$cbc_decrypt::
+ lea rsp,QWORD PTR[((-88))+rsp]
+ movaps XMMWORD PTR[rsp],xmm6
+ movaps XMMWORD PTR[16+rsp],xmm7
+ movaps XMMWORD PTR[32+rsp],xmm8
+ movaps XMMWORD PTR[48+rsp],xmm9
+$L$cbc_decrypt_body::
+ movups xmm9,XMMWORD PTR[r8]
+ mov eax,r10d
+ cmp rdx,070h
+ jbe $L$cbc_dec_tail
+ shr r10d,1
+ sub rdx,070h
+ mov eax,r10d
+ movaps XMMWORD PTR[64+rsp],xmm9
+ jmp $L$cbc_dec_loop8_enter
+ALIGN 16
+$L$cbc_dec_loop8::
+ movaps XMMWORD PTR[64+rsp],xmm0
+ movups XMMWORD PTR[rsi],xmm9
+ lea rsi,QWORD PTR[16+rsi]
+$L$cbc_dec_loop8_enter::
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm2,XMMWORD PTR[rdi]
+ movups xmm3,XMMWORD PTR[16+rdi]
+ movups xmm1,XMMWORD PTR[16+rcx]
+
+ lea rcx,QWORD PTR[32+rcx]
+ movdqu xmm4,XMMWORD PTR[32+rdi]
+ xorps xmm2,xmm0
+ movdqu xmm5,XMMWORD PTR[48+rdi]
+ xorps xmm3,xmm0
+ movdqu xmm6,XMMWORD PTR[64+rdi]
+DB 102,15,56,222,209
+ pxor xmm4,xmm0
+ movdqu xmm7,XMMWORD PTR[80+rdi]
+DB 102,15,56,222,217
+ pxor xmm5,xmm0
+ movdqu xmm8,XMMWORD PTR[96+rdi]
+DB 102,15,56,222,225
+ pxor xmm6,xmm0
+ movdqu xmm9,XMMWORD PTR[112+rdi]
+DB 102,15,56,222,233
+ pxor xmm7,xmm0
+ dec eax
+DB 102,15,56,222,241
+ pxor xmm8,xmm0
+DB 102,15,56,222,249
+ pxor xmm9,xmm0
+ movups xmm0,XMMWORD PTR[rcx]
+DB 102,68,15,56,222,193
+DB 102,68,15,56,222,201
+ movups xmm1,XMMWORD PTR[16+rcx]
+
+ call $L$dec_loop8_enter
+
+ movups xmm1,XMMWORD PTR[rdi]
+ movups xmm0,XMMWORD PTR[16+rdi]
+ xorps xmm2,XMMWORD PTR[64+rsp]
+ xorps xmm3,xmm1
+ movups xmm1,XMMWORD PTR[32+rdi]
+ xorps xmm4,xmm0
+ movups xmm0,XMMWORD PTR[48+rdi]
+ xorps xmm5,xmm1
+ movups xmm1,XMMWORD PTR[64+rdi]
+ xorps xmm6,xmm0
+ movups xmm0,XMMWORD PTR[80+rdi]
+ xorps xmm7,xmm1
+ movups xmm1,XMMWORD PTR[96+rdi]
+ xorps xmm8,xmm0
+ movups xmm0,XMMWORD PTR[112+rdi]
+ xorps xmm9,xmm1
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ mov eax,r10d
+ movups XMMWORD PTR[64+rsi],xmm6
+ mov rcx,r11
+ movups XMMWORD PTR[80+rsi],xmm7
+ lea rdi,QWORD PTR[128+rdi]
+ movups XMMWORD PTR[96+rsi],xmm8
+ lea rsi,QWORD PTR[112+rsi]
+ sub rdx,080h
+ ja $L$cbc_dec_loop8
+
+ movaps xmm2,xmm9
+ movaps xmm9,xmm0
+ add rdx,070h
+ jle $L$cbc_dec_tail_collected
+ movups XMMWORD PTR[rsi],xmm2
+ lea eax,DWORD PTR[1+r10*1+r10]
+ lea rsi,QWORD PTR[16+rsi]
+$L$cbc_dec_tail::
+ movups xmm2,XMMWORD PTR[rdi]
+ movaps xmm8,xmm2
+ cmp rdx,010h
+ jbe $L$cbc_dec_one
+
+ movups xmm3,XMMWORD PTR[16+rdi]
+ movaps xmm7,xmm3
+ cmp rdx,020h
+ jbe $L$cbc_dec_two
+
+ movups xmm4,XMMWORD PTR[32+rdi]
+ movaps xmm6,xmm4
+ cmp rdx,030h
+ jbe $L$cbc_dec_three
+
+ movups xmm5,XMMWORD PTR[48+rdi]
+ cmp rdx,040h
+ jbe $L$cbc_dec_four
+
+ movups xmm6,XMMWORD PTR[64+rdi]
+ cmp rdx,050h
+ jbe $L$cbc_dec_five
+
+ movups xmm7,XMMWORD PTR[80+rdi]
+ cmp rdx,060h
+ jbe $L$cbc_dec_six
+
+ movups xmm8,XMMWORD PTR[96+rdi]
+ movaps XMMWORD PTR[64+rsp],xmm9
+ call _aesni_decrypt8
+ movups xmm1,XMMWORD PTR[rdi]
+ movups xmm0,XMMWORD PTR[16+rdi]
+ xorps xmm2,XMMWORD PTR[64+rsp]
+ xorps xmm3,xmm1
+ movups xmm1,XMMWORD PTR[32+rdi]
+ xorps xmm4,xmm0
+ movups xmm0,XMMWORD PTR[48+rdi]
+ xorps xmm5,xmm1
+ movups xmm1,XMMWORD PTR[64+rdi]
+ xorps xmm6,xmm0
+ movups xmm0,XMMWORD PTR[80+rdi]
+ xorps xmm7,xmm1
+ movups xmm9,XMMWORD PTR[96+rdi]
+ xorps xmm8,xmm0
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ movups XMMWORD PTR[64+rsi],xmm6
+ movups XMMWORD PTR[80+rsi],xmm7
+ lea rsi,QWORD PTR[96+rsi]
+ movaps xmm2,xmm8
+ sub rdx,070h
+ jmp $L$cbc_dec_tail_collected
+ALIGN 16
+$L$cbc_dec_one::
+ movups xmm0,XMMWORD PTR[rcx]
+ movups xmm1,XMMWORD PTR[16+rcx]
+ lea rcx,QWORD PTR[32+rcx]
+ xorps xmm2,xmm0
+$L$oop_dec1_16::
+DB 102,15,56,222,209
+ dec eax
+ movups xmm1,XMMWORD PTR[rcx]
+ lea rcx,QWORD PTR[16+rcx]
+ jnz $L$oop_dec1_16
+
+DB 102,15,56,223,209
+ xorps xmm2,xmm9
+ movaps xmm9,xmm8
+ sub rdx,010h
+ jmp $L$cbc_dec_tail_collected
+ALIGN 16
+$L$cbc_dec_two::
+ xorps xmm4,xmm4
+ call _aesni_decrypt3
+ xorps xmm2,xmm9
+ xorps xmm3,xmm8
+ movups XMMWORD PTR[rsi],xmm2
+ movaps xmm9,xmm7
+ movaps xmm2,xmm3
+ lea rsi,QWORD PTR[16+rsi]
+ sub rdx,020h
+ jmp $L$cbc_dec_tail_collected
+ALIGN 16
+$L$cbc_dec_three::
+ call _aesni_decrypt3
+ xorps xmm2,xmm9
+ xorps xmm3,xmm8
+ movups XMMWORD PTR[rsi],xmm2
+ xorps xmm4,xmm7
+ movups XMMWORD PTR[16+rsi],xmm3
+ movaps xmm9,xmm6
+ movaps xmm2,xmm4
+ lea rsi,QWORD PTR[32+rsi]
+ sub rdx,030h
+ jmp $L$cbc_dec_tail_collected
+ALIGN 16
+$L$cbc_dec_four::
+ call _aesni_decrypt4
+ xorps xmm2,xmm9
+ movups xmm9,XMMWORD PTR[48+rdi]
+ xorps xmm3,xmm8
+ movups XMMWORD PTR[rsi],xmm2
+ xorps xmm4,xmm7
+ movups XMMWORD PTR[16+rsi],xmm3
+ xorps xmm5,xmm6
+ movups XMMWORD PTR[32+rsi],xmm4
+ movaps xmm2,xmm5
+ lea rsi,QWORD PTR[48+rsi]
+ sub rdx,040h
+ jmp $L$cbc_dec_tail_collected
+ALIGN 16
+$L$cbc_dec_five::
+ xorps xmm7,xmm7
+ call _aesni_decrypt6
+ movups xmm1,XMMWORD PTR[16+rdi]
+ movups xmm0,XMMWORD PTR[32+rdi]
+ xorps xmm2,xmm9
+ xorps xmm3,xmm8
+ xorps xmm4,xmm1
+ movups xmm1,XMMWORD PTR[48+rdi]
+ xorps xmm5,xmm0
+ movups xmm9,XMMWORD PTR[64+rdi]
+ xorps xmm6,xmm1
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ lea rsi,QWORD PTR[64+rsi]
+ movaps xmm2,xmm6
+ sub rdx,050h
+ jmp $L$cbc_dec_tail_collected
+ALIGN 16
+$L$cbc_dec_six::
+ call _aesni_decrypt6
+ movups xmm1,XMMWORD PTR[16+rdi]
+ movups xmm0,XMMWORD PTR[32+rdi]
+ xorps xmm2,xmm9
+ xorps xmm3,xmm8
+ xorps xmm4,xmm1
+ movups xmm1,XMMWORD PTR[48+rdi]
+ xorps xmm5,xmm0
+ movups xmm0,XMMWORD PTR[64+rdi]
+ xorps xmm6,xmm1
+ movups xmm9,XMMWORD PTR[80+rdi]
+ xorps xmm7,xmm0
+ movups XMMWORD PTR[rsi],xmm2
+ movups XMMWORD PTR[16+rsi],xmm3
+ movups XMMWORD PTR[32+rsi],xmm4
+ movups XMMWORD PTR[48+rsi],xmm5
+ movups XMMWORD PTR[64+rsi],xmm6
+ lea rsi,QWORD PTR[80+rsi]
+ movaps xmm2,xmm7
+ sub rdx,060h
+ jmp $L$cbc_dec_tail_collected
+ALIGN 16
+$L$cbc_dec_tail_collected::
+ and rdx,15
+ movups XMMWORD PTR[r8],xmm9
+ jnz $L$cbc_dec_tail_partial
+ movups XMMWORD PTR[rsi],xmm2
+ jmp $L$cbc_dec_ret
+ALIGN 16
+$L$cbc_dec_tail_partial::
+ movaps XMMWORD PTR[64+rsp],xmm2
+ mov rcx,16
+ mov rdi,rsi
+ sub rcx,rdx
+ lea rsi,QWORD PTR[64+rsp]
+ DD 09066A4F3h
+
+
+$L$cbc_dec_ret::
+ movaps xmm6,XMMWORD PTR[rsp]
+ movaps xmm7,XMMWORD PTR[16+rsp]
+ movaps xmm8,XMMWORD PTR[32+rsp]
+ movaps xmm9,XMMWORD PTR[48+rsp]
+ lea rsp,QWORD PTR[88+rsp]
+$L$cbc_ret::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_aesni_cbc_encrypt::
+aesni_cbc_encrypt ENDP
+PUBLIC aesni_set_decrypt_key
+
+ALIGN 16
+aesni_set_decrypt_key PROC PUBLIC
+DB 048h,083h,0ECh,008h
+
+ call __aesni_set_encrypt_key
+ shl edx,4
+ test eax,eax
+ jnz $L$dec_key_ret
+ lea rcx,QWORD PTR[16+rdx*1+r8]
+
+ movups xmm0,XMMWORD PTR[r8]
+ movups xmm1,XMMWORD PTR[rcx]
+ movups XMMWORD PTR[rcx],xmm0
+ movups XMMWORD PTR[r8],xmm1
+ lea r8,QWORD PTR[16+r8]
+ lea rcx,QWORD PTR[((-16))+rcx]
+
+$L$dec_key_inverse::
+ movups xmm0,XMMWORD PTR[r8]
+ movups xmm1,XMMWORD PTR[rcx]
+DB 102,15,56,219,192
+DB 102,15,56,219,201
+ lea r8,QWORD PTR[16+r8]
+ lea rcx,QWORD PTR[((-16))+rcx]
+ movups XMMWORD PTR[16+rcx],xmm0
+ movups XMMWORD PTR[(-16)+r8],xmm1
+ cmp rcx,r8
+ ja $L$dec_key_inverse
+
+ movups xmm0,XMMWORD PTR[r8]
+DB 102,15,56,219,192
+ movups XMMWORD PTR[rcx],xmm0
+$L$dec_key_ret::
+ add rsp,8
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_set_decrypt_key::
+aesni_set_decrypt_key ENDP
+PUBLIC aesni_set_encrypt_key
+
+ALIGN 16
+aesni_set_encrypt_key PROC PUBLIC
+__aesni_set_encrypt_key::
+DB 048h,083h,0ECh,008h
+
+ mov rax,-1
+ test rcx,rcx
+ jz $L$enc_key_ret
+ test r8,r8
+ jz $L$enc_key_ret
+
+ movups xmm0,XMMWORD PTR[rcx]
+ xorps xmm4,xmm4
+ lea rax,QWORD PTR[16+r8]
+ cmp edx,256
+ je $L$14rounds
+ cmp edx,192
+ je $L$12rounds
+ cmp edx,128
+ jne $L$bad_keybits
+
+$L$10rounds::
+ mov edx,9
+ movups XMMWORD PTR[r8],xmm0
+DB 102,15,58,223,200,1
+ call $L$key_expansion_128_cold
+DB 102,15,58,223,200,2
+ call $L$key_expansion_128
+DB 102,15,58,223,200,4
+ call $L$key_expansion_128
+DB 102,15,58,223,200,8
+ call $L$key_expansion_128
+DB 102,15,58,223,200,16
+ call $L$key_expansion_128
+DB 102,15,58,223,200,32
+ call $L$key_expansion_128
+DB 102,15,58,223,200,64
+ call $L$key_expansion_128
+DB 102,15,58,223,200,128
+ call $L$key_expansion_128
+DB 102,15,58,223,200,27
+ call $L$key_expansion_128
+DB 102,15,58,223,200,54
+ call $L$key_expansion_128
+ movups XMMWORD PTR[rax],xmm0
+ mov DWORD PTR[80+rax],edx
+ xor eax,eax
+ jmp $L$enc_key_ret
+
+ALIGN 16
+$L$12rounds::
+ movq xmm2,QWORD PTR[16+rcx]
+ mov edx,11
+ movups XMMWORD PTR[r8],xmm0
+DB 102,15,58,223,202,1
+ call $L$key_expansion_192a_cold
+DB 102,15,58,223,202,2
+ call $L$key_expansion_192b
+DB 102,15,58,223,202,4
+ call $L$key_expansion_192a
+DB 102,15,58,223,202,8
+ call $L$key_expansion_192b
+DB 102,15,58,223,202,16
+ call $L$key_expansion_192a
+DB 102,15,58,223,202,32
+ call $L$key_expansion_192b
+DB 102,15,58,223,202,64
+ call $L$key_expansion_192a
+DB 102,15,58,223,202,128
+ call $L$key_expansion_192b
+ movups XMMWORD PTR[rax],xmm0
+ mov DWORD PTR[48+rax],edx
+ xor rax,rax
+ jmp $L$enc_key_ret
+
+ALIGN 16
+$L$14rounds::
+ movups xmm2,XMMWORD PTR[16+rcx]
+ mov edx,13
+ lea rax,QWORD PTR[16+rax]
+ movups XMMWORD PTR[r8],xmm0
+ movups XMMWORD PTR[16+r8],xmm2
+DB 102,15,58,223,202,1
+ call $L$key_expansion_256a_cold
+DB 102,15,58,223,200,1
+ call $L$key_expansion_256b
+DB 102,15,58,223,202,2
+ call $L$key_expansion_256a
+DB 102,15,58,223,200,2
+ call $L$key_expansion_256b
+DB 102,15,58,223,202,4
+ call $L$key_expansion_256a
+DB 102,15,58,223,200,4
+ call $L$key_expansion_256b
+DB 102,15,58,223,202,8
+ call $L$key_expansion_256a
+DB 102,15,58,223,200,8
+ call $L$key_expansion_256b
+DB 102,15,58,223,202,16
+ call $L$key_expansion_256a
+DB 102,15,58,223,200,16
+ call $L$key_expansion_256b
+DB 102,15,58,223,202,32
+ call $L$key_expansion_256a
+DB 102,15,58,223,200,32
+ call $L$key_expansion_256b
+DB 102,15,58,223,202,64
+ call $L$key_expansion_256a
+ movups XMMWORD PTR[rax],xmm0
+ mov DWORD PTR[16+rax],edx
+ xor rax,rax
+ jmp $L$enc_key_ret
+
+ALIGN 16
+$L$bad_keybits::
+ mov rax,-2
+$L$enc_key_ret::
+ add rsp,8
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_set_encrypt_key::
+
+ALIGN 16
+$L$key_expansion_128::
+ movups XMMWORD PTR[rax],xmm0
+ lea rax,QWORD PTR[16+rax]
+$L$key_expansion_128_cold::
+ shufps xmm4,xmm0,16
+ xorps xmm0,xmm4
+ shufps xmm4,xmm0,140
+ xorps xmm0,xmm4
+ shufps xmm1,xmm1,255
+ xorps xmm0,xmm1
+ DB 0F3h,0C3h ;repret
+
+ALIGN 16
+$L$key_expansion_192a::
+ movups XMMWORD PTR[rax],xmm0
+ lea rax,QWORD PTR[16+rax]
+$L$key_expansion_192a_cold::
+ movaps xmm5,xmm2
+$L$key_expansion_192b_warm::
+ shufps xmm4,xmm0,16
+ movdqa xmm3,xmm2
+ xorps xmm0,xmm4
+ shufps xmm4,xmm0,140
+ pslldq xmm3,4
+ xorps xmm0,xmm4
+ pshufd xmm1,xmm1,85
+ pxor xmm2,xmm3
+ pxor xmm0,xmm1
+ pshufd xmm3,xmm0,255
+ pxor xmm2,xmm3
+ DB 0F3h,0C3h ;repret
+
+ALIGN 16
+$L$key_expansion_192b::
+ movaps xmm3,xmm0
+ shufps xmm5,xmm0,68
+ movups XMMWORD PTR[rax],xmm5
+ shufps xmm3,xmm2,78
+ movups XMMWORD PTR[16+rax],xmm3
+ lea rax,QWORD PTR[32+rax]
+ jmp $L$key_expansion_192b_warm
+
+ALIGN 16
+$L$key_expansion_256a::
+ movups XMMWORD PTR[rax],xmm2
+ lea rax,QWORD PTR[16+rax]
+$L$key_expansion_256a_cold::
+ shufps xmm4,xmm0,16
+ xorps xmm0,xmm4
+ shufps xmm4,xmm0,140
+ xorps xmm0,xmm4
+ shufps xmm1,xmm1,255
+ xorps xmm0,xmm1
+ DB 0F3h,0C3h ;repret
+
+ALIGN 16
+$L$key_expansion_256b::
+ movups XMMWORD PTR[rax],xmm0
+ lea rax,QWORD PTR[16+rax]
+
+ shufps xmm4,xmm2,16
+ xorps xmm2,xmm4
+ shufps xmm4,xmm2,140
+ xorps xmm2,xmm4
+ shufps xmm1,xmm1,170
+ xorps xmm2,xmm1
+ DB 0F3h,0C3h ;repret
+aesni_set_encrypt_key ENDP
+
+ALIGN 64
+$L$bswap_mask::
+DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+$L$increment32::
+ DD 6,6,6,0
+$L$increment64::
+ DD 1,0,0,0
+$L$xts_magic::
+ DD 087h,0,1,0
+
+DB 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69
+DB 83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83
+DB 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
+DB 115,108,46,111,114,103,62,0
+ALIGN 64
+EXTERN __imp_RtlVirtualUnwind:NEAR
+
+ALIGN 16
+ecb_se_handler PROC PRIVATE
+ push rsi
+ push rdi
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq
+ sub rsp,64
+
+ mov rax,QWORD PTR[152+r8]
+
+ jmp $L$common_seh_tail
+ecb_se_handler ENDP
+
+
+ALIGN 16
+ccm64_se_handler PROC PRIVATE
+ push rsi
+ push rdi
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq
+ sub rsp,64
+
+ mov rax,QWORD PTR[120+r8]
+ mov rbx,QWORD PTR[248+r8]
+
+ mov rsi,QWORD PTR[8+r9]
+ mov r11,QWORD PTR[56+r9]
+
+ mov r10d,DWORD PTR[r11]
+ lea r10,QWORD PTR[r10*1+rsi]
+ cmp rbx,r10
+ jb $L$common_seh_tail
+
+ mov rax,QWORD PTR[152+r8]
+
+ mov r10d,DWORD PTR[4+r11]
+ lea r10,QWORD PTR[r10*1+rsi]
+ cmp rbx,r10
+ jae $L$common_seh_tail
+
+ lea rsi,QWORD PTR[rax]
+ lea rdi,QWORD PTR[512+r8]
+ mov ecx,8
+ DD 0a548f3fch
+
+ lea rax,QWORD PTR[88+rax]
+
+ jmp $L$common_seh_tail
+ccm64_se_handler ENDP
+
+
+ALIGN 16
+ctr32_se_handler PROC PRIVATE
+ push rsi
+ push rdi
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq
+ sub rsp,64
+
+ mov rax,QWORD PTR[120+r8]
+ mov rbx,QWORD PTR[248+r8]
+
+ lea r10,QWORD PTR[$L$ctr32_body]
+ cmp rbx,r10
+ jb $L$common_seh_tail
+
+ mov rax,QWORD PTR[152+r8]
+
+ lea r10,QWORD PTR[$L$ctr32_ret]
+ cmp rbx,r10
+ jae $L$common_seh_tail
+
+ lea rsi,QWORD PTR[32+rax]
+ lea rdi,QWORD PTR[512+r8]
+ mov ecx,20
+ DD 0a548f3fch
+
+ lea rax,QWORD PTR[200+rax]
+
+ jmp $L$common_seh_tail
+ctr32_se_handler ENDP
+
+
+ALIGN 16
+xts_se_handler PROC PRIVATE
+ push rsi
+ push rdi
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq
+ sub rsp,64
+
+ mov rax,QWORD PTR[120+r8]
+ mov rbx,QWORD PTR[248+r8]
+
+ mov rsi,QWORD PTR[8+r9]
+ mov r11,QWORD PTR[56+r9]
+
+ mov r10d,DWORD PTR[r11]
+ lea r10,QWORD PTR[r10*1+rsi]
+ cmp rbx,r10
+ jb $L$common_seh_tail
+
+ mov rax,QWORD PTR[152+r8]
+
+ mov r10d,DWORD PTR[4+r11]
+ lea r10,QWORD PTR[r10*1+rsi]
+ cmp rbx,r10
+ jae $L$common_seh_tail
+
+ lea rsi,QWORD PTR[96+rax]
+ lea rdi,QWORD PTR[512+r8]
+ mov ecx,20
+ DD 0a548f3fch
+
+ lea rax,QWORD PTR[((104+160))+rax]
+
+ jmp $L$common_seh_tail
+xts_se_handler ENDP
+
+ALIGN 16
+cbc_se_handler PROC PRIVATE
+ push rsi
+ push rdi
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq
+ sub rsp,64
+
+ mov rax,QWORD PTR[152+r8]
+ mov rbx,QWORD PTR[248+r8]
+
+ lea r10,QWORD PTR[$L$cbc_decrypt]
+ cmp rbx,r10
+ jb $L$common_seh_tail
+
+ lea r10,QWORD PTR[$L$cbc_decrypt_body]
+ cmp rbx,r10
+ jb $L$restore_cbc_rax
+
+ lea r10,QWORD PTR[$L$cbc_ret]
+ cmp rbx,r10
+ jae $L$common_seh_tail
+
+ lea rsi,QWORD PTR[rax]
+ lea rdi,QWORD PTR[512+r8]
+ mov ecx,8
+ DD 0a548f3fch
+
+ lea rax,QWORD PTR[88+rax]
+ jmp $L$common_seh_tail
+
+$L$restore_cbc_rax::
+ mov rax,QWORD PTR[120+r8]
+
+$L$common_seh_tail::
+ mov rdi,QWORD PTR[8+rax]
+ mov rsi,QWORD PTR[16+rax]
+ mov QWORD PTR[152+r8],rax
+ mov QWORD PTR[168+r8],rsi
+ mov QWORD PTR[176+r8],rdi
+
+ mov rdi,QWORD PTR[40+r9]
+ mov rsi,r8
+ mov ecx,154
+ DD 0a548f3fch
+
+
+ mov rsi,r9
+ xor rcx,rcx
+ mov rdx,QWORD PTR[8+rsi]
+ mov r8,QWORD PTR[rsi]
+ mov r9,QWORD PTR[16+rsi]
+ mov r10,QWORD PTR[40+rsi]
+ lea r11,QWORD PTR[56+rsi]
+ lea r12,QWORD PTR[24+rsi]
+ mov QWORD PTR[32+rsp],r10
+ mov QWORD PTR[40+rsp],r11
+ mov QWORD PTR[48+rsp],r12
+ mov QWORD PTR[56+rsp],rcx
+ call QWORD PTR[__imp_RtlVirtualUnwind]
+
+ mov eax,1
+ add rsp,64
+ popfq
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbp
+ pop rbx
+ pop rdi
+ pop rsi
+ DB 0F3h,0C3h ;repret
+cbc_se_handler ENDP
+
+.text$ ENDS
+.pdata SEGMENT READONLY ALIGN(4)
+ALIGN 4
+ DD imagerel $L$SEH_begin_aesni_ecb_encrypt
+ DD imagerel $L$SEH_end_aesni_ecb_encrypt
+ DD imagerel $L$SEH_info_ecb
+
+ DD imagerel $L$SEH_begin_aesni_ccm64_encrypt_blocks
+ DD imagerel $L$SEH_end_aesni_ccm64_encrypt_blocks
+ DD imagerel $L$SEH_info_ccm64_enc
+
+ DD imagerel $L$SEH_begin_aesni_ccm64_decrypt_blocks
+ DD imagerel $L$SEH_end_aesni_ccm64_decrypt_blocks
+ DD imagerel $L$SEH_info_ccm64_dec
+
+ DD imagerel $L$SEH_begin_aesni_ctr32_encrypt_blocks
+ DD imagerel $L$SEH_end_aesni_ctr32_encrypt_blocks
+ DD imagerel $L$SEH_info_ctr32
+
+ DD imagerel $L$SEH_begin_aesni_xts_encrypt
+ DD imagerel $L$SEH_end_aesni_xts_encrypt
+ DD imagerel $L$SEH_info_xts_enc
+
+ DD imagerel $L$SEH_begin_aesni_xts_decrypt
+ DD imagerel $L$SEH_end_aesni_xts_decrypt
+ DD imagerel $L$SEH_info_xts_dec
+ DD imagerel $L$SEH_begin_aesni_cbc_encrypt
+ DD imagerel $L$SEH_end_aesni_cbc_encrypt
+ DD imagerel $L$SEH_info_cbc
+
+ DD imagerel aesni_set_decrypt_key
+ DD imagerel $L$SEH_end_set_decrypt_key
+ DD imagerel $L$SEH_info_key
+
+ DD imagerel aesni_set_encrypt_key
+ DD imagerel $L$SEH_end_set_encrypt_key
+ DD imagerel $L$SEH_info_key
+.pdata ENDS
+.xdata SEGMENT READONLY ALIGN(8)
+ALIGN 8
+$L$SEH_info_ecb::
+DB 9,0,0,0
+ DD imagerel ecb_se_handler
+$L$SEH_info_ccm64_enc::
+DB 9,0,0,0
+ DD imagerel ccm64_se_handler
+ DD imagerel $L$ccm64_enc_body,imagerel $L$ccm64_enc_ret
+
+$L$SEH_info_ccm64_dec::
+DB 9,0,0,0
+ DD imagerel ccm64_se_handler
+ DD imagerel $L$ccm64_dec_body,imagerel $L$ccm64_dec_ret
+
+$L$SEH_info_ctr32::
+DB 9,0,0,0
+ DD imagerel ctr32_se_handler
+$L$SEH_info_xts_enc::
+DB 9,0,0,0
+ DD imagerel xts_se_handler
+ DD imagerel $L$xts_enc_body,imagerel $L$xts_enc_epilogue
+
+$L$SEH_info_xts_dec::
+DB 9,0,0,0
+ DD imagerel xts_se_handler
+ DD imagerel $L$xts_dec_body,imagerel $L$xts_dec_epilogue
+
+$L$SEH_info_cbc::
+DB 9,0,0,0
+ DD imagerel cbc_se_handler
+$L$SEH_info_key::
+DB 001h,004h,001h,000h
+DB 004h,002h,000h,000h
+
+
+.xdata ENDS
+END
diff --git a/deps/openssl/asm/x64-win32-masm/bn/modexp512-x86_64.asm b/deps/openssl/asm/x64-win32-masm/bn/modexp512-x86_64.asm
new file mode 100644
index 000000000..b83aa18d4
--- /dev/null
+++ b/deps/openssl/asm/x64-win32-masm/bn/modexp512-x86_64.asm
@@ -0,0 +1,1890 @@
+OPTION DOTNAME
+.text$ SEGMENT ALIGN(64) 'CODE'
+
+
+ALIGN 16
+MULADD_128x512 PROC PRIVATE
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ mov QWORD PTR[rcx],r8
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov r8,rdx
+ mov rbp,QWORD PTR[8+rdi]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ mov QWORD PTR[8+rcx],r9
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ add r8,rbx
+ adc rdx,0
+ mov r9,rdx
+ DB 0F3h,0C3h ;repret
+MULADD_128x512 ENDP
+
+ALIGN 16
+mont_reduce PROC PRIVATE
+ lea rdi,QWORD PTR[192+rsp]
+ mov rsi,QWORD PTR[32+rsp]
+ add rsi,576
+ lea rcx,QWORD PTR[520+rsp]
+
+ mov rbp,QWORD PTR[96+rcx]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ mov r8,QWORD PTR[rcx]
+ add r8,rax
+ adc rdx,0
+ mov QWORD PTR[rdi],r8
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ mov r9,QWORD PTR[8+rcx]
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ mov r10,QWORD PTR[16+rcx]
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ mov r11,QWORD PTR[24+rcx]
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ mov r12,QWORD PTR[32+rcx]
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ mov r13,QWORD PTR[40+rcx]
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ mov r14,QWORD PTR[48+rcx]
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ mov r15,QWORD PTR[56+rcx]
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov r8,rdx
+ mov rbp,QWORD PTR[104+rcx]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ mov QWORD PTR[8+rdi],r9
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ add r8,rbx
+ adc rdx,0
+ mov r9,rdx
+ mov rbp,QWORD PTR[112+rcx]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ mov QWORD PTR[16+rdi],r10
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ add r8,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov r10,rdx
+ mov rbp,QWORD PTR[120+rcx]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ mov QWORD PTR[24+rdi],r11
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ add r8,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov r11,rdx
+ xor rax,rax
+
+ add r8,QWORD PTR[64+rcx]
+ adc r9,QWORD PTR[72+rcx]
+ adc r10,QWORD PTR[80+rcx]
+ adc r11,QWORD PTR[88+rcx]
+ adc rax,0
+
+
+
+
+ mov QWORD PTR[64+rdi],r8
+ mov QWORD PTR[72+rdi],r9
+ mov rbp,r10
+ mov QWORD PTR[88+rdi],r11
+
+ mov QWORD PTR[384+rsp],rax
+
+ mov r8,QWORD PTR[rdi]
+ mov r9,QWORD PTR[8+rdi]
+ mov r10,QWORD PTR[16+rdi]
+ mov r11,QWORD PTR[24+rdi]
+
+
+
+
+
+
+
+
+ add rdi,8*10
+
+ add rsi,64
+ lea rcx,QWORD PTR[296+rsp]
+
+ call MULADD_128x512
+
+
+ mov rax,QWORD PTR[384+rsp]
+
+
+ add r8,QWORD PTR[((-16))+rdi]
+ adc r9,QWORD PTR[((-8))+rdi]
+ mov QWORD PTR[64+rcx],r8
+ mov QWORD PTR[72+rcx],r9
+
+ adc rax,rax
+ mov QWORD PTR[384+rsp],rax
+
+ lea rdi,QWORD PTR[192+rsp]
+ add rsi,64
+
+
+
+
+
+ mov r8,QWORD PTR[rsi]
+ mov rbx,QWORD PTR[8+rsi]
+
+ mov rax,QWORD PTR[rcx]
+ mul r8
+ mov rbp,rax
+ mov r9,rdx
+
+ mov rax,QWORD PTR[8+rcx]
+ mul r8
+ add r9,rax
+
+ mov rax,QWORD PTR[rcx]
+ mul rbx
+ add r9,rax
+
+ mov QWORD PTR[8+rdi],r9
+
+
+ sub rsi,192
+
+ mov r8,QWORD PTR[rcx]
+ mov r9,QWORD PTR[8+rcx]
+
+ call MULADD_128x512
+
+
+
+
+
+ mov rax,QWORD PTR[rsi]
+ mov rbx,QWORD PTR[8+rsi]
+ mov rdi,QWORD PTR[16+rsi]
+ mov rdx,QWORD PTR[24+rsi]
+
+
+ mov rbp,QWORD PTR[384+rsp]
+
+ add r8,QWORD PTR[64+rcx]
+ adc r9,QWORD PTR[72+rcx]
+
+
+ adc rbp,rbp
+
+
+
+ shl rbp,3
+ mov rcx,QWORD PTR[32+rsp]
+ add rbp,rcx
+
+
+ xor rsi,rsi
+
+ add r10,QWORD PTR[rbp]
+ adc r11,QWORD PTR[64+rbp]
+ adc r12,QWORD PTR[128+rbp]
+ adc r13,QWORD PTR[192+rbp]
+ adc r14,QWORD PTR[256+rbp]
+ adc r15,QWORD PTR[320+rbp]
+ adc r8,QWORD PTR[384+rbp]
+ adc r9,QWORD PTR[448+rbp]
+
+
+
+ sbb rsi,0
+
+
+ and rax,rsi
+ and rbx,rsi
+ and rdi,rsi
+ and rdx,rsi
+
+ mov rbp,1
+ sub r10,rax
+ sbb r11,rbx
+ sbb r12,rdi
+ sbb r13,rdx
+
+
+
+
+ sbb rbp,0
+
+
+
+ add rcx,512
+ mov rax,QWORD PTR[32+rcx]
+ mov rbx,QWORD PTR[40+rcx]
+ mov rdi,QWORD PTR[48+rcx]
+ mov rdx,QWORD PTR[56+rcx]
+
+
+
+ and rax,rsi
+ and rbx,rsi
+ and rdi,rsi
+ and rdx,rsi
+
+
+
+ sub rbp,1
+
+ sbb r14,rax
+ sbb r15,rbx
+ sbb r8,rdi
+ sbb r9,rdx
+
+
+
+ mov rsi,QWORD PTR[144+rsp]
+ mov QWORD PTR[rsi],r10
+ mov QWORD PTR[8+rsi],r11
+ mov QWORD PTR[16+rsi],r12
+ mov QWORD PTR[24+rsi],r13
+ mov QWORD PTR[32+rsi],r14
+ mov QWORD PTR[40+rsi],r15
+ mov QWORD PTR[48+rsi],r8
+ mov QWORD PTR[56+rsi],r9
+
+ DB 0F3h,0C3h ;repret
+mont_reduce ENDP
+
+ALIGN 16
+mont_mul_a3b PROC PRIVATE
+
+
+
+
+ mov rbp,QWORD PTR[rdi]
+
+ mov rax,r10
+ mul rbp
+ mov QWORD PTR[520+rsp],rax
+ mov r10,rdx
+ mov rax,r11
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ mov r11,rdx
+ mov rax,r12
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ mov r12,rdx
+ mov rax,r13
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ mov r13,rdx
+ mov rax,r14
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ mov r14,rdx
+ mov rax,r15
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ mov r15,rdx
+ mov rax,r8
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ mov r8,rdx
+ mov rax,r9
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ mov r9,rdx
+ mov rbp,QWORD PTR[8+rdi]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ mov QWORD PTR[528+rsp],r10
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ add r8,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov r10,rdx
+ mov rbp,QWORD PTR[16+rdi]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ mov QWORD PTR[536+rsp],r11
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ add r8,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov r11,rdx
+ mov rbp,QWORD PTR[24+rdi]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ mov QWORD PTR[544+rsp],r12
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ add r8,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov r12,rdx
+ mov rbp,QWORD PTR[32+rdi]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ mov QWORD PTR[552+rsp],r13
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ add r8,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov r13,rdx
+ mov rbp,QWORD PTR[40+rdi]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ mov QWORD PTR[560+rsp],r14
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ add r8,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov r14,rdx
+ mov rbp,QWORD PTR[48+rdi]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ mov QWORD PTR[568+rsp],r15
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ add r8,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov r15,rdx
+ mov rbp,QWORD PTR[56+rdi]
+ mov rax,QWORD PTR[rsi]
+ mul rbp
+ add r8,rax
+ adc rdx,0
+ mov QWORD PTR[576+rsp],r8
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rsi]
+ mul rbp
+ add r9,rax
+ adc rdx,0
+ add r9,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[16+rsi]
+ mul rbp
+ add r10,rax
+ adc rdx,0
+ add r10,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[24+rsi]
+ mul rbp
+ add r11,rax
+ adc rdx,0
+ add r11,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[32+rsi]
+ mul rbp
+ add r12,rax
+ adc rdx,0
+ add r12,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[40+rsi]
+ mul rbp
+ add r13,rax
+ adc rdx,0
+ add r13,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[48+rsi]
+ mul rbp
+ add r14,rax
+ adc rdx,0
+ add r14,rbx
+ adc rdx,0
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[56+rsi]
+ mul rbp
+ add r15,rax
+ adc rdx,0
+ add r15,rbx
+ adc rdx,0
+ mov r8,rdx
+ mov QWORD PTR[584+rsp],r9
+ mov QWORD PTR[592+rsp],r10
+ mov QWORD PTR[600+rsp],r11
+ mov QWORD PTR[608+rsp],r12
+ mov QWORD PTR[616+rsp],r13
+ mov QWORD PTR[624+rsp],r14
+ mov QWORD PTR[632+rsp],r15
+ mov QWORD PTR[640+rsp],r8
+
+
+
+
+
+ jmp mont_reduce
+
+
+mont_mul_a3b ENDP
+
+ALIGN 16
+sqr_reduce PROC PRIVATE
+ mov rcx,QWORD PTR[16+rsp]
+
+
+
+ mov rbx,r10
+
+ mov rax,r11
+ mul rbx
+ mov QWORD PTR[528+rsp],rax
+ mov r10,rdx
+ mov rax,r12
+ mul rbx
+ add r10,rax
+ adc rdx,0
+ mov r11,rdx
+ mov rax,r13
+ mul rbx
+ add r11,rax
+ adc rdx,0
+ mov r12,rdx
+ mov rax,r14
+ mul rbx
+ add r12,rax
+ adc rdx,0
+ mov r13,rdx
+ mov rax,r15
+ mul rbx
+ add r13,rax
+ adc rdx,0
+ mov r14,rdx
+ mov rax,r8
+ mul rbx
+ add r14,rax
+ adc rdx,0
+ mov r15,rdx
+ mov rax,r9
+ mul rbx
+ add r15,rax
+ adc rdx,0
+ mov rsi,rdx
+
+ mov QWORD PTR[536+rsp],r10
+
+
+
+
+
+ mov rbx,QWORD PTR[8+rcx]
+
+ mov rax,QWORD PTR[16+rcx]
+ mul rbx
+ add r11,rax
+ adc rdx,0
+ mov QWORD PTR[544+rsp],r11
+
+ mov r10,rdx
+ mov rax,QWORD PTR[24+rcx]
+ mul rbx
+ add r12,rax
+ adc rdx,0
+ add r12,r10
+ adc rdx,0
+ mov QWORD PTR[552+rsp],r12
+
+ mov r10,rdx
+ mov rax,QWORD PTR[32+rcx]
+ mul rbx
+ add r13,rax
+ adc rdx,0
+ add r13,r10
+ adc rdx,0
+
+ mov r10,rdx
+ mov rax,QWORD PTR[40+rcx]
+ mul rbx
+ add r14,rax
+ adc rdx,0
+ add r14,r10
+ adc rdx,0
+
+ mov r10,rdx
+ mov rax,r8
+ mul rbx
+ add r15,rax
+ adc rdx,0
+ add r15,r10
+ adc rdx,0
+
+ mov r10,rdx
+ mov rax,r9
+ mul rbx
+ add rsi,rax
+ adc rdx,0
+ add rsi,r10
+ adc rdx,0
+
+ mov r11,rdx
+
+
+
+
+ mov rbx,QWORD PTR[16+rcx]
+
+ mov rax,QWORD PTR[24+rcx]
+ mul rbx
+ add r13,rax
+ adc rdx,0
+ mov QWORD PTR[560+rsp],r13
+
+ mov r10,rdx
+ mov rax,QWORD PTR[32+rcx]
+ mul rbx
+ add r14,rax
+ adc rdx,0
+ add r14,r10
+ adc rdx,0
+ mov QWORD PTR[568+rsp],r14
+
+ mov r10,rdx
+ mov rax,QWORD PTR[40+rcx]
+ mul rbx
+ add r15,rax
+ adc rdx,0
+ add r15,r10
+ adc rdx,0
+
+ mov r10,rdx
+ mov rax,r8
+ mul rbx
+ add rsi,rax
+ adc rdx,0
+ add rsi,r10
+ adc rdx,0
+
+ mov r10,rdx
+ mov rax,r9
+ mul rbx
+ add r11,rax
+ adc rdx,0
+ add r11,r10
+ adc rdx,0
+
+ mov r12,rdx
+
+
+
+
+
+ mov rbx,QWORD PTR[24+rcx]
+
+ mov rax,QWORD PTR[32+rcx]
+ mul rbx
+ add r15,rax
+ adc rdx,0
+ mov QWORD PTR[576+rsp],r15
+
+ mov r10,rdx
+ mov rax,QWORD PTR[40+rcx]
+ mul rbx
+ add rsi,rax
+ adc rdx,0
+ add rsi,r10
+ adc rdx,0
+ mov QWORD PTR[584+rsp],rsi
+
+ mov r10,rdx
+ mov rax,r8
+ mul rbx
+ add r11,rax
+ adc rdx,0
+ add r11,r10
+ adc rdx,0
+
+ mov r10,rdx
+ mov rax,r9
+ mul rbx
+ add r12,rax
+ adc rdx,0
+ add r12,r10
+ adc rdx,0
+
+ mov r15,rdx
+
+
+
+
+ mov rbx,QWORD PTR[32+rcx]
+
+ mov rax,QWORD PTR[40+rcx]
+ mul rbx
+ add r11,rax
+ adc rdx,0
+ mov QWORD PTR[592+rsp],r11
+
+ mov r10,rdx
+ mov rax,r8
+ mul rbx
+ add r12,rax
+ adc rdx,0
+ add r12,r10
+ adc rdx,0
+ mov QWORD PTR[600+rsp],r12
+
+ mov r10,rdx
+ mov rax,r9
+ mul rbx
+ add r15,rax
+ adc rdx,0
+ add r15,r10
+ adc rdx,0
+
+ mov r11,rdx
+
+
+
+
+ mov rbx,QWORD PTR[40+rcx]
+
+ mov rax,r8
+ mul rbx
+ add r15,rax
+ adc rdx,0
+ mov QWORD PTR[608+rsp],r15
+
+ mov r10,rdx
+ mov rax,r9
+ mul rbx
+ add r11,rax
+ adc rdx,0
+ add r11,r10
+ adc rdx,0
+ mov QWORD PTR[616+rsp],r11
+
+ mov r12,rdx
+
+
+
+
+ mov rbx,r8
+
+ mov rax,r9
+ mul rbx
+ add r12,rax
+ adc rdx,0
+ mov QWORD PTR[624+rsp],r12
+
+ mov QWORD PTR[632+rsp],rdx
+
+
+ mov r10,QWORD PTR[528+rsp]
+ mov r11,QWORD PTR[536+rsp]
+ mov r12,QWORD PTR[544+rsp]
+ mov r13,QWORD PTR[552+rsp]
+ mov r14,QWORD PTR[560+rsp]
+ mov r15,QWORD PTR[568+rsp]
+
+ mov rax,QWORD PTR[24+rcx]
+ mul rax
+ mov rdi,rax
+ mov r8,rdx
+
+ add r10,r10
+ adc r11,r11
+ adc r12,r12
+ adc r13,r13
+ adc r14,r14
+ adc r15,r15
+ adc r8,0
+
+ mov rax,QWORD PTR[rcx]
+ mul rax
+ mov QWORD PTR[520+rsp],rax
+ mov rbx,rdx
+
+ mov rax,QWORD PTR[8+rcx]
+ mul rax
+
+ add r10,rbx
+ adc r11,rax
+ adc rdx,0
+
+ mov rbx,rdx
+ mov QWORD PTR[528+rsp],r10
+ mov QWORD PTR[536+rsp],r11
+
+ mov rax,QWORD PTR[16+rcx]
+ mul rax
+
+ add r12,rbx
+ adc r13,rax
+ adc rdx,0
+
+ mov rbx,rdx
+
+ mov QWORD PTR[544+rsp],r12
+ mov QWORD PTR[552+rsp],r13
+
+ xor rbp,rbp
+ add r14,rbx
+ adc r15,rdi
+ adc rbp,0
+
+ mov QWORD PTR[560+rsp],r14
+ mov QWORD PTR[568+rsp],r15
+
+
+
+
+ mov r10,QWORD PTR[576+rsp]
+ mov r11,QWORD PTR[584+rsp]
+ mov r12,QWORD PTR[592+rsp]
+ mov r13,QWORD PTR[600+rsp]
+ mov r14,QWORD PTR[608+rsp]
+ mov r15,QWORD PTR[616+rsp]
+ mov rdi,QWORD PTR[624+rsp]
+ mov rsi,QWORD PTR[632+rsp]
+
+ mov rax,r9
+ mul rax
+ mov r9,rax
+ mov rbx,rdx
+
+ add r10,r10
+ adc r11,r11
+ adc r12,r12
+ adc r13,r13
+ adc r14,r14
+ adc r15,r15
+ adc rdi,rdi
+ adc rsi,rsi
+ adc rbx,0
+
+ add r10,rbp
+
+ mov rax,QWORD PTR[32+rcx]
+ mul rax
+
+ add r10,r8
+ adc r11,rax
+ adc rdx,0
+
+ mov rbp,rdx
+
+ mov QWORD PTR[576+rsp],r10
+ mov QWORD PTR[584+rsp],r11
+
+ mov rax,QWORD PTR[40+rcx]
+ mul rax
+
+ add r12,rbp
+ adc r13,rax
+ adc rdx,0
+
+ mov rbp,rdx
+
+ mov QWORD PTR[592+rsp],r12
+ mov QWORD PTR[600+rsp],r13
+
+ mov rax,QWORD PTR[48+rcx]
+ mul rax
+
+ add r14,rbp
+ adc r15,rax
+ adc rdx,0
+
+ mov QWORD PTR[608+rsp],r14
+ mov QWORD PTR[616+rsp],r15
+
+ add rdi,rdx
+ adc rsi,r9
+ adc rbx,0
+
+ mov QWORD PTR[624+rsp],rdi
+ mov QWORD PTR[632+rsp],rsi
+ mov QWORD PTR[640+rsp],rbx
+
+ jmp mont_reduce
+
+
+sqr_reduce ENDP
+PUBLIC mod_exp_512
+
+mod_exp_512 PROC PUBLIC
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_mod_exp_512::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+
+
+ push rbp
+ push rbx
+ push r12
+ push r13
+ push r14
+ push r15
+
+
+ mov r8,rsp
+ sub rsp,2688
+ and rsp,-64
+
+
+ mov QWORD PTR[rsp],r8
+ mov QWORD PTR[8+rsp],rdi
+ mov QWORD PTR[16+rsp],rsi
+ mov QWORD PTR[24+rsp],rcx
+$L$body::
+
+
+
+ pxor xmm4,xmm4
+ movdqu xmm0,XMMWORD PTR[rsi]
+ movdqu xmm1,XMMWORD PTR[16+rsi]
+ movdqu xmm2,XMMWORD PTR[32+rsi]
+ movdqu xmm3,XMMWORD PTR[48+rsi]
+ movdqa XMMWORD PTR[512+rsp],xmm4
+ movdqa XMMWORD PTR[528+rsp],xmm4
+ movdqa XMMWORD PTR[608+rsp],xmm4
+ movdqa XMMWORD PTR[624+rsp],xmm4
+ movdqa XMMWORD PTR[544+rsp],xmm0
+ movdqa XMMWORD PTR[560+rsp],xmm1
+ movdqa XMMWORD PTR[576+rsp],xmm2
+ movdqa XMMWORD PTR[592+rsp],xmm3
+
+
+ movdqu xmm0,XMMWORD PTR[rdx]
+ movdqu xmm1,XMMWORD PTR[16+rdx]
+ movdqu xmm2,XMMWORD PTR[32+rdx]
+ movdqu xmm3,XMMWORD PTR[48+rdx]
+
+ lea rbx,QWORD PTR[384+rsp]
+ mov QWORD PTR[136+rsp],rbx
+ call mont_reduce
+
+
+ lea rcx,QWORD PTR[448+rsp]
+ xor rax,rax
+ mov QWORD PTR[rcx],rax
+ mov QWORD PTR[8+rcx],rax
+ mov QWORD PTR[24+rcx],rax
+ mov QWORD PTR[32+rcx],rax
+ mov QWORD PTR[40+rcx],rax
+ mov QWORD PTR[48+rcx],rax
+ mov QWORD PTR[56+rcx],rax
+ mov QWORD PTR[128+rsp],rax
+ mov QWORD PTR[16+rcx],1
+
+ lea rbp,QWORD PTR[640+rsp]
+ mov rsi,rcx
+ mov rdi,rbp
+ mov rax,8
+loop_0::
+ mov rbx,QWORD PTR[rcx]
+ mov WORD PTR[rdi],bx
+ shr rbx,16
+ mov WORD PTR[64+rdi],bx
+ shr rbx,16
+ mov WORD PTR[128+rdi],bx
+ shr rbx,16
+ mov WORD PTR[192+rdi],bx
+ lea rcx,QWORD PTR[8+rcx]
+ lea rdi,QWORD PTR[256+rdi]
+ dec rax
+ jnz loop_0
+ mov rax,31
+ mov QWORD PTR[32+rsp],rax
+ mov QWORD PTR[40+rsp],rbp
+
+ mov QWORD PTR[136+rsp],rsi
+ mov r10,QWORD PTR[rsi]
+ mov r11,QWORD PTR[8+rsi]
+ mov r12,QWORD PTR[16+rsi]
+ mov r13,QWORD PTR[24+rsi]
+ mov r14,QWORD PTR[32+rsi]
+ mov r15,QWORD PTR[40+rsi]
+ mov r8,QWORD PTR[48+rsi]
+ mov r9,QWORD PTR[56+rsi]
+init_loop::
+ lea rdi,QWORD PTR[384+rsp]
+ call mont_mul_a3b
+ lea rsi,QWORD PTR[448+rsp]
+ mov rbp,QWORD PTR[40+rsp]
+ add rbp,2
+ mov QWORD PTR[40+rsp],rbp
+ mov rcx,rsi
+ mov rax,8
+loop_1::
+ mov rbx,QWORD PTR[rcx]
+ mov WORD PTR[rbp],bx
+ shr rbx,16
+ mov WORD PTR[64+rbp],bx
+ shr rbx,16
+ mov WORD PTR[128+rbp],bx
+ shr rbx,16
+ mov WORD PTR[192+rbp],bx
+ lea rcx,QWORD PTR[8+rcx]
+ lea rbp,QWORD PTR[256+rbp]
+ dec rax
+ jnz loop_1
+ mov rax,QWORD PTR[32+rsp]
+ sub rax,1
+ mov QWORD PTR[32+rsp],rax
+ jne init_loop
+
+
+
+ movdqa XMMWORD PTR[64+rsp],xmm0
+ movdqa XMMWORD PTR[80+rsp],xmm1
+ movdqa XMMWORD PTR[96+rsp],xmm2
+ movdqa XMMWORD PTR[112+rsp],xmm3
+
+
+
+
+
+ mov eax,DWORD PTR[126+rsp]
+ mov rdx,rax
+ shr rax,11
+ and edx,007FFh
+ mov DWORD PTR[126+rsp],edx
+ lea rsi,QWORD PTR[640+rax*2+rsp]
+ mov rdx,QWORD PTR[8+rsp]
+ mov rbp,4
+loop_2::
+ movzx rbx,WORD PTR[192+rsi]
+ movzx rax,WORD PTR[448+rsi]
+ shl rbx,16
+ shl rax,16
+ mov bx,WORD PTR[128+rsi]
+ mov ax,WORD PTR[384+rsi]
+ shl rbx,16
+ shl rax,16
+ mov bx,WORD PTR[64+rsi]
+ mov ax,WORD PTR[320+rsi]
+ shl rbx,16
+ shl rax,16
+ mov bx,WORD PTR[rsi]
+ mov ax,WORD PTR[256+rsi]
+ mov QWORD PTR[rdx],rbx
+ mov QWORD PTR[8+rdx],rax
+ lea rsi,QWORD PTR[512+rsi]
+ lea rdx,QWORD PTR[16+rdx]
+ sub rbp,1
+ jnz loop_2
+ mov QWORD PTR[48+rsp],505
+
+ mov rcx,QWORD PTR[8+rsp]
+ mov QWORD PTR[136+rsp],rcx
+ mov r10,QWORD PTR[rcx]
+ mov r11,QWORD PTR[8+rcx]
+ mov r12,QWORD PTR[16+rcx]
+ mov r13,QWORD PTR[24+rcx]
+ mov r14,QWORD PTR[32+rcx]
+ mov r15,QWORD PTR[40+rcx]
+ mov r8,QWORD PTR[48+rcx]
+ mov r9,QWORD PTR[56+rcx]
+ jmp sqr_2
+
+main_loop_a3b::
+ call sqr_reduce
+ call sqr_reduce
+ call sqr_reduce
+sqr_2::
+ call sqr_reduce
+ call sqr_reduce
+
+
+
+ mov rcx,QWORD PTR[48+rsp]
+ mov rax,rcx
+ shr rax,4
+ mov edx,DWORD PTR[64+rax*2+rsp]
+ and rcx,15
+ shr rdx,cl
+ and rdx,01Fh
+
+ lea rsi,QWORD PTR[640+rdx*2+rsp]
+ lea rdx,QWORD PTR[448+rsp]
+ mov rdi,rdx
+ mov rbp,4
+loop_3::
+ movzx rbx,WORD PTR[192+rsi]
+ movzx rax,WORD PTR[448+rsi]
+ shl rbx,16
+ shl rax,16
+ mov bx,WORD PTR[128+rsi]
+ mov ax,WORD PTR[384+rsi]
+ shl rbx,16
+ shl rax,16
+ mov bx,WORD PTR[64+rsi]
+ mov ax,WORD PTR[320+rsi]
+ shl rbx,16
+ shl rax,16
+ mov bx,WORD PTR[rsi]
+ mov ax,WORD PTR[256+rsi]
+ mov QWORD PTR[rdx],rbx
+ mov QWORD PTR[8+rdx],rax
+ lea rsi,QWORD PTR[512+rsi]
+ lea rdx,QWORD PTR[16+rdx]
+ sub rbp,1
+ jnz loop_3
+ mov rsi,QWORD PTR[8+rsp]
+ call mont_mul_a3b
+
+
+
+ mov rcx,QWORD PTR[48+rsp]
+ sub rcx,5
+ mov QWORD PTR[48+rsp],rcx
+ jge main_loop_a3b
+
+
+
+end_main_loop_a3b::
+
+
+ mov rdx,QWORD PTR[8+rsp]
+ pxor xmm4,xmm4
+ movdqu xmm0,XMMWORD PTR[rdx]
+ movdqu xmm1,XMMWORD PTR[16+rdx]
+ movdqu xmm2,XMMWORD PTR[32+rdx]
+ movdqu xmm3,XMMWORD PTR[48+rdx]
+ movdqa XMMWORD PTR[576+rsp],xmm4
+ movdqa XMMWORD PTR[592+rsp],xmm4
+ movdqa XMMWORD PTR[608+rsp],xmm4
+ movdqa XMMWORD PTR[624+rsp],xmm4
+ movdqa XMMWORD PTR[512+rsp],xmm0
+ movdqa XMMWORD PTR[528+rsp],xmm1
+ movdqa XMMWORD PTR[544+rsp],xmm2
+ movdqa XMMWORD PTR[560+rsp],xmm3
+ call mont_reduce
+
+
+
+ mov rax,QWORD PTR[8+rsp]
+ mov r8,QWORD PTR[rax]
+ mov r9,QWORD PTR[8+rax]
+ mov r10,QWORD PTR[16+rax]
+ mov r11,QWORD PTR[24+rax]
+ mov r12,QWORD PTR[32+rax]
+ mov r13,QWORD PTR[40+rax]
+ mov r14,QWORD PTR[48+rax]
+ mov r15,QWORD PTR[56+rax]
+
+
+ mov rbx,QWORD PTR[24+rsp]
+ add rbx,512
+
+ sub r8,QWORD PTR[rbx]
+ sbb r9,QWORD PTR[8+rbx]
+ sbb r10,QWORD PTR[16+rbx]
+ sbb r11,QWORD PTR[24+rbx]
+ sbb r12,QWORD PTR[32+rbx]
+ sbb r13,QWORD PTR[40+rbx]
+ sbb r14,QWORD PTR[48+rbx]
+ sbb r15,QWORD PTR[56+rbx]
+
+
+ mov rsi,QWORD PTR[rax]
+ mov rdi,QWORD PTR[8+rax]
+ mov rcx,QWORD PTR[16+rax]
+ mov rdx,QWORD PTR[24+rax]
+ cmovnc rsi,r8
+ cmovnc rdi,r9
+ cmovnc rcx,r10
+ cmovnc rdx,r11
+ mov QWORD PTR[rax],rsi
+ mov QWORD PTR[8+rax],rdi
+ mov QWORD PTR[16+rax],rcx
+ mov QWORD PTR[24+rax],rdx
+
+ mov rsi,QWORD PTR[32+rax]
+ mov rdi,QWORD PTR[40+rax]
+ mov rcx,QWORD PTR[48+rax]
+ mov rdx,QWORD PTR[56+rax]
+ cmovnc rsi,r12
+ cmovnc rdi,r13
+ cmovnc rcx,r14
+ cmovnc rdx,r15
+ mov QWORD PTR[32+rax],rsi
+ mov QWORD PTR[40+rax],rdi
+ mov QWORD PTR[48+rax],rcx
+ mov QWORD PTR[56+rax],rdx
+
+ mov rsi,QWORD PTR[rsp]
+ mov r15,QWORD PTR[rsi]
+ mov r14,QWORD PTR[8+rsi]
+ mov r13,QWORD PTR[16+rsi]
+ mov r12,QWORD PTR[24+rsi]
+ mov rbx,QWORD PTR[32+rsi]
+ mov rbp,QWORD PTR[40+rsi]
+ lea rsp,QWORD PTR[48+rsi]
+$L$epilogue::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_mod_exp_512::
+mod_exp_512 ENDP
+EXTERN __imp_RtlVirtualUnwind:NEAR
+
+ALIGN 16
+mod_exp_512_se_handler PROC PRIVATE
+ push rsi
+ push rdi
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq
+ sub rsp,64
+
+ mov rax,QWORD PTR[120+r8]
+ mov rbx,QWORD PTR[248+r8]
+
+ lea r10,QWORD PTR[$L$body]
+ cmp rbx,r10
+ jb $L$in_prologue
+
+ mov rax,QWORD PTR[152+r8]
+
+ lea r10,QWORD PTR[$L$epilogue]
+ cmp rbx,r10
+ jae $L$in_prologue
+
+ mov rax,QWORD PTR[rax]
+
+ mov rbx,QWORD PTR[32+rax]
+ mov rbp,QWORD PTR[40+rax]
+ mov r12,QWORD PTR[24+rax]
+ mov r13,QWORD PTR[16+rax]
+ mov r14,QWORD PTR[8+rax]
+ mov r15,QWORD PTR[rax]
+ lea rax,QWORD PTR[48+rax]
+ mov QWORD PTR[144+r8],rbx
+ mov QWORD PTR[160+r8],rbp
+ mov QWORD PTR[216+r8],r12
+ mov QWORD PTR[224+r8],r13
+ mov QWORD PTR[232+r8],r14
+ mov QWORD PTR[240+r8],r15
+
+$L$in_prologue::
+ mov rdi,QWORD PTR[8+rax]
+ mov rsi,QWORD PTR[16+rax]
+ mov QWORD PTR[152+r8],rax
+ mov QWORD PTR[168+r8],rsi
+ mov QWORD PTR[176+r8],rdi
+
+ mov rdi,QWORD PTR[40+r9]
+ mov rsi,r8
+ mov ecx,154
+ DD 0a548f3fch
+
+
+ mov rsi,r9
+ xor rcx,rcx
+ mov rdx,QWORD PTR[8+rsi]
+ mov r8,QWORD PTR[rsi]
+ mov r9,QWORD PTR[16+rsi]
+ mov r10,QWORD PTR[40+rsi]
+ lea r11,QWORD PTR[56+rsi]
+ lea r12,QWORD PTR[24+rsi]
+ mov QWORD PTR[32+rsp],r10
+ mov QWORD PTR[40+rsp],r11
+ mov QWORD PTR[48+rsp],r12
+ mov QWORD PTR[56+rsp],rcx
+ call QWORD PTR[__imp_RtlVirtualUnwind]
+
+ mov eax,1
+ add rsp,64
+ popfq
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbp
+ pop rbx
+ pop rdi
+ pop rsi
+ DB 0F3h,0C3h ;repret
+mod_exp_512_se_handler ENDP
+
+.text$ ENDS
+.pdata SEGMENT READONLY ALIGN(4)
+ALIGN 4
+ DD imagerel $L$SEH_begin_mod_exp_512
+ DD imagerel $L$SEH_end_mod_exp_512
+ DD imagerel $L$SEH_info_mod_exp_512
+
+.pdata ENDS
+.xdata SEGMENT READONLY ALIGN(8)
+ALIGN 8
+$L$SEH_info_mod_exp_512::
+DB 9,0,0,0
+ DD imagerel mod_exp_512_se_handler
+
+.xdata ENDS
+END
diff --git a/deps/openssl/asm/x64-win32-masm/bn/x86_64-mont.asm b/deps/openssl/asm/x64-win32-masm/bn/x86_64-mont.asm
index 9e54d8895..f4518aa3b 100644
--- a/deps/openssl/asm/x64-win32-masm/bn/x86_64-mont.asm
+++ b/deps/openssl/asm/x64-win32-masm/bn/x86_64-mont.asm
@@ -17,6 +17,16 @@ $L$SEH_begin_bn_mul_mont::
mov r9,QWORD PTR[48+rsp]
+ test r9d,3
+ jnz $L$mul_enter
+ cmp r9d,8
+ jb $L$mul_enter
+ cmp rdx,rsi
+ jne $L$mul4x_enter
+ jmp $L$sqr4x_enter
+
+ALIGN 16
+$L$mul_enter::
push rbx
push rbp
push r12
@@ -32,48 +42,63 @@ $L$SEH_begin_bn_mul_mont::
and rsp,-1024
mov QWORD PTR[8+r9*8+rsp],r11
-$L$prologue::
+$L$mul_body::
mov r12,rdx
-
mov r8,QWORD PTR[r8]
+ mov rbx,QWORD PTR[r12]
+ mov rax,QWORD PTR[rsi]
xor r14,r14
xor r15,r15
- mov rbx,QWORD PTR[r12]
- mov rax,QWORD PTR[rsi]
+ mov rbp,r8
mul rbx
mov r10,rax
- mov r11,rdx
+ mov rax,QWORD PTR[rcx]
- imul rax,r8
- mov rbp,rax
+ imul rbp,r10
+ mov r11,rdx
- mul QWORD PTR[rcx]
- add rax,r10
+ mul rbp
+ add r10,rax
+ mov rax,QWORD PTR[8+rsi]
adc rdx,0
mov r13,rdx
lea r15,QWORD PTR[1+r15]
+ jmp $L$1st_enter
+
+ALIGN 16
$L$1st::
+ add r13,rax
mov rax,QWORD PTR[r15*8+rsi]
- mul rbx
- add rax,r11
adc rdx,0
- mov r10,rax
+ add r13,r11
+ mov r11,r10
+ adc rdx,0
+ mov QWORD PTR[((-16))+r15*8+rsp],r13
+ mov r13,rdx
+
+$L$1st_enter::
+ mul rbx
+ add r11,rax
mov rax,QWORD PTR[r15*8+rcx]
- mov r11,rdx
+ adc rdx,0
+ lea r15,QWORD PTR[1+r15]
+ mov r10,rdx
mul rbp
- add rax,r13
- lea r15,QWORD PTR[1+r15]
+ cmp r15,r9
+ jne $L$1st
+
+ add r13,rax
+ mov rax,QWORD PTR[rsi]
adc rdx,0
- add rax,r10
+ add r13,r11
adc rdx,0
- mov QWORD PTR[((-16))+r15*8+rsp],rax
- cmp r15,r9
+ mov QWORD PTR[((-16))+r15*8+rsp],r13
mov r13,rdx
- jl $L$1st
+ mov r11,r10
xor rdx,rdx
add r13,r11
@@ -82,50 +107,64 @@ $L$1st::
mov QWORD PTR[r9*8+rsp],rdx
lea r14,QWORD PTR[1+r14]
-ALIGN 4
+ jmp $L$outer
+ALIGN 16
$L$outer::
- xor r15,r15
-
mov rbx,QWORD PTR[r14*8+r12]
- mov rax,QWORD PTR[rsi]
+ xor r15,r15
+ mov rbp,r8
+ mov r10,QWORD PTR[rsp]
mul rbx
- add rax,QWORD PTR[rsp]
+ add r10,rax
+ mov rax,QWORD PTR[rcx]
adc rdx,0
- mov r10,rax
- mov r11,rdx
- imul rax,r8
- mov rbp,rax
+ imul rbp,r10
+ mov r11,rdx
- mul QWORD PTR[r15*8+rcx]
- add rax,r10
- mov r10,QWORD PTR[8+rsp]
+ mul rbp
+ add r10,rax
+ mov rax,QWORD PTR[8+rsi]
adc rdx,0
+ mov r10,QWORD PTR[8+rsp]
mov r13,rdx
lea r15,QWORD PTR[1+r15]
-ALIGN 4
+ jmp $L$inner_enter
+
+ALIGN 16
$L$inner::
+ add r13,rax
mov rax,QWORD PTR[r15*8+rsi]
- mul rbx
- add rax,r11
adc rdx,0
- add r10,rax
+ add r13,r10
+ mov r10,QWORD PTR[r15*8+rsp]
+ adc rdx,0
+ mov QWORD PTR[((-16))+r15*8+rsp],r13
+ mov r13,rdx
+
+$L$inner_enter::
+ mul rbx
+ add r11,rax
mov rax,QWORD PTR[r15*8+rcx]
adc rdx,0
+ add r10,r11
mov r11,rdx
+ adc r11,0
+ lea r15,QWORD PTR[1+r15]
mul rbp
- add rax,r13
- lea r15,QWORD PTR[1+r15]
- adc rdx,0
- add rax,r10
+ cmp r15,r9
+ jne $L$inner
+
+ add r13,rax
+ mov rax,QWORD PTR[rsi]
adc rdx,0
+ add r13,r10
mov r10,QWORD PTR[r15*8+rsp]
- cmp r15,r9
- mov QWORD PTR[((-16))+r15*8+rsp],rax
+ adc rdx,0
+ mov QWORD PTR[((-16))+r15*8+rsp],r13
mov r13,rdx
- jl $L$inner
xor rdx,rdx
add r13,r11
@@ -139,34 +178,35 @@ $L$inner::
cmp r14,r9
jl $L$outer
- lea rsi,QWORD PTR[rsp]
- lea r15,QWORD PTR[((-1))+r9]
-
- mov rax,QWORD PTR[rsi]
xor r14,r14
+ mov rax,QWORD PTR[rsp]
+ lea rsi,QWORD PTR[rsp]
+ mov r15,r9
jmp $L$sub
ALIGN 16
$L$sub:: sbb rax,QWORD PTR[r14*8+rcx]
mov QWORD PTR[r14*8+rdi],rax
- dec r15
mov rax,QWORD PTR[8+r14*8+rsi]
lea r14,QWORD PTR[1+r14]
- jge $L$sub
+ dec r15
+ jnz $L$sub
sbb rax,0
+ xor r14,r14
and rsi,rax
not rax
mov rcx,rdi
and rcx,rax
- lea r15,QWORD PTR[((-1))+r9]
+ mov r15,r9
or rsi,rcx
ALIGN 16
$L$copy::
- mov rax,QWORD PTR[r15*8+rsi]
- mov QWORD PTR[r15*8+rdi],rax
- mov QWORD PTR[r15*8+rsp],r14
- dec r15
- jge $L$copy
+ mov rax,QWORD PTR[r14*8+rsi]
+ mov QWORD PTR[r14*8+rsp],r14
+ mov QWORD PTR[r14*8+rdi],rax
+ lea r14,QWORD PTR[1+r14]
+ sub r15,1
+ jnz $L$copy
mov rsi,QWORD PTR[8+r9*8+rsp]
mov rax,1
@@ -177,12 +217,1205 @@ $L$copy::
mov rbp,QWORD PTR[32+rsi]
mov rbx,QWORD PTR[40+rsi]
lea rsp,QWORD PTR[48+rsi]
-$L$epilogue::
+$L$mul_epilogue::
mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
mov rsi,QWORD PTR[16+rsp]
DB 0F3h,0C3h ;repret
$L$SEH_end_bn_mul_mont::
bn_mul_mont ENDP
+
+ALIGN 16
+bn_mul4x_mont PROC PRIVATE
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_bn_mul4x_mont::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+ mov r9,QWORD PTR[48+rsp]
+
+
+$L$mul4x_enter::
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+
+ mov r9d,r9d
+ lea r10,QWORD PTR[4+r9]
+ mov r11,rsp
+ neg r10
+ lea rsp,QWORD PTR[r10*8+rsp]
+ and rsp,-1024
+
+ mov QWORD PTR[8+r9*8+rsp],r11
+$L$mul4x_body::
+ mov QWORD PTR[16+r9*8+rsp],rdi
+ mov r12,rdx
+ mov r8,QWORD PTR[r8]
+ mov rbx,QWORD PTR[r12]
+ mov rax,QWORD PTR[rsi]
+
+ xor r14,r14
+ xor r15,r15
+
+ mov rbp,r8
+ mul rbx
+ mov r10,rax
+ mov rax,QWORD PTR[rcx]
+
+ imul rbp,r10
+ mov r11,rdx
+
+ mul rbp
+ add r10,rax
+ mov rax,QWORD PTR[8+rsi]
+ adc rdx,0
+ mov rdi,rdx
+
+ mul rbx
+ add r11,rax
+ mov rax,QWORD PTR[8+rcx]
+ adc rdx,0
+ mov r10,rdx
+
+ mul rbp
+ add rdi,rax
+ mov rax,QWORD PTR[16+rsi]
+ adc rdx,0
+ add rdi,r11
+ lea r15,QWORD PTR[4+r15]
+ adc rdx,0
+ mov QWORD PTR[rsp],rdi
+ mov r13,rdx
+ jmp $L$1st4x
+ALIGN 16
+$L$1st4x::
+ mul rbx
+ add r10,rax
+ mov rax,QWORD PTR[((-16))+r15*8+rcx]
+ adc rdx,0
+ mov r11,rdx
+
+ mul rbp
+ add r13,rax
+ mov rax,QWORD PTR[((-8))+r15*8+rsi]
+ adc rdx,0
+ add r13,r10
+ adc rdx,0
+ mov QWORD PTR[((-24))+r15*8+rsp],r13
+ mov rdi,rdx
+
+ mul rbx
+ add r11,rax
+ mov rax,QWORD PTR[((-8))+r15*8+rcx]
+ adc rdx,0
+ mov r10,rdx
+
+ mul rbp
+ add rdi,rax
+ mov rax,QWORD PTR[r15*8+rsi]
+ adc rdx,0
+ add rdi,r11
+ adc rdx,0
+ mov QWORD PTR[((-16))+r15*8+rsp],rdi
+ mov r13,rdx
+
+ mul rbx
+ add r10,rax
+ mov rax,QWORD PTR[r15*8+rcx]
+ adc rdx,0
+ mov r11,rdx
+
+ mul rbp
+ add r13,rax
+ mov rax,QWORD PTR[8+r15*8+rsi]
+ adc rdx,0
+ add r13,r10
+ adc rdx,0
+ mov QWORD PTR[((-8))+r15*8+rsp],r13
+ mov rdi,rdx
+
+ mul rbx
+ add r11,rax
+ mov rax,QWORD PTR[8+r15*8+rcx]
+ adc rdx,0
+ lea r15,QWORD PTR[4+r15]
+ mov r10,rdx
+
+ mul rbp
+ add rdi,rax
+ mov rax,QWORD PTR[((-16))+r15*8+rsi]
+ adc rdx,0
+ add rdi,r11
+ adc rdx,0
+ mov QWORD PTR[((-32))+r15*8+rsp],rdi
+ mov r13,rdx
+ cmp r15,r9
+ jl $L$1st4x
+
+ mul rbx
+ add r10,rax
+ mov rax,QWORD PTR[((-16))+r15*8+rcx]
+ adc rdx,0
+ mov r11,rdx
+
+ mul rbp
+ add r13,rax
+ mov rax,QWORD PTR[((-8))+r15*8+rsi]
+ adc rdx,0
+ add r13,r10
+ adc rdx,0
+ mov QWORD PTR[((-24))+r15*8+rsp],r13
+ mov rdi,rdx
+
+ mul rbx
+ add r11,rax
+ mov rax,QWORD PTR[((-8))+r15*8+rcx]
+ adc rdx,0
+ mov r10,rdx
+
+ mul rbp
+ add rdi,rax
+ mov rax,QWORD PTR[rsi]
+ adc rdx,0
+ add rdi,r11
+ adc rdx,0
+ mov QWORD PTR[((-16))+r15*8+rsp],rdi
+ mov r13,rdx
+
+ xor rdi,rdi
+ add r13,r10
+ adc rdi,0
+ mov QWORD PTR[((-8))+r15*8+rsp],r13
+ mov QWORD PTR[r15*8+rsp],rdi
+
+ lea r14,QWORD PTR[1+r14]
+ALIGN 4
+$L$outer4x::
+ mov rbx,QWORD PTR[r14*8+r12]
+ xor r15,r15
+ mov r10,QWORD PTR[rsp]
+ mov rbp,r8
+ mul rbx
+ add r10,rax
+ mov rax,QWORD PTR[rcx]
+ adc rdx,0
+
+ imul rbp,r10
+ mov r11,rdx
+
+ mul rbp
+ add r10,rax
+ mov rax,QWORD PTR[8+rsi]
+ adc rdx,0
+ mov rdi,rdx
+
+ mul rbx
+ add r11,rax
+ mov rax,QWORD PTR[8+rcx]
+ adc rdx,0
+ add r11,QWORD PTR[8+rsp]
+ adc rdx,0
+ mov r10,rdx
+
+ mul rbp
+ add rdi,rax
+ mov rax,QWORD PTR[16+rsi]
+ adc rdx,0
+ add rdi,r11
+ lea r15,QWORD PTR[4+r15]
+ adc rdx,0
+ mov QWORD PTR[rsp],rdi
+ mov r13,rdx
+ jmp $L$inner4x
+ALIGN 16
+$L$inner4x::
+ mul rbx
+ add r10,rax
+ mov rax,QWORD PTR[((-16))+r15*8+rcx]
+ adc rdx,0
+ add r10,QWORD PTR[((-16))+r15*8+rsp]
+ adc rdx,0
+ mov r11,rdx
+
+ mul rbp
+ add r13,rax
+ mov rax,QWORD PTR[((-8))+r15*8+rsi]
+ adc rdx,0
+ add r13,r10
+ adc rdx,0
+ mov QWORD PTR[((-24))+r15*8+rsp],r13
+ mov rdi,rdx
+
+ mul rbx
+ add r11,rax
+ mov rax,QWORD PTR[((-8))+r15*8+rcx]
+ adc rdx,0
+ add r11,QWORD PTR[((-8))+r15*8+rsp]
+ adc rdx,0
+ mov r10,rdx
+
+ mul rbp
+ add rdi,rax
+ mov rax,QWORD PTR[r15*8+rsi]
+ adc rdx,0
+ add rdi,r11
+ adc rdx,0
+ mov QWORD PTR[((-16))+r15*8+rsp],rdi
+ mov r13,rdx
+
+ mul rbx
+ add r10,rax
+ mov rax,QWORD PTR[r15*8+rcx]
+ adc rdx,0
+ add r10,QWORD PTR[r15*8+rsp]
+ adc rdx,0
+ mov r11,rdx
+
+ mul rbp
+ add r13,rax
+ mov rax,QWORD PTR[8+r15*8+rsi]
+ adc rdx,0
+ add r13,r10
+ adc rdx,0
+ mov QWORD PTR[((-8))+r15*8+rsp],r13
+ mov rdi,rdx
+
+ mul rbx
+ add r11,rax
+ mov rax,QWORD PTR[8+r15*8+rcx]
+ adc rdx,0
+ add r11,QWORD PTR[8+r15*8+rsp]
+ adc rdx,0
+ lea r15,QWORD PTR[4+r15]
+ mov r10,rdx
+
+ mul rbp
+ add rdi,rax
+ mov rax,QWORD PTR[((-16))+r15*8+rsi]
+ adc rdx,0
+ add rdi,r11
+ adc rdx,0
+ mov QWORD PTR[((-32))+r15*8+rsp],rdi
+ mov r13,rdx
+ cmp r15,r9
+ jl $L$inner4x
+
+ mul rbx
+ add r10,rax
+ mov rax,QWORD PTR[((-16))+r15*8+rcx]
+ adc rdx,0
+ add r10,QWORD PTR[((-16))+r15*8+rsp]
+ adc rdx,0
+ mov r11,rdx
+
+ mul rbp
+ add r13,rax
+ mov rax,QWORD PTR[((-8))+r15*8+rsi]
+ adc rdx,0
+ add r13,r10
+ adc rdx,0
+ mov QWORD PTR[((-24))+r15*8+rsp],r13
+ mov rdi,rdx
+
+ mul rbx
+ add r11,rax
+ mov rax,QWORD PTR[((-8))+r15*8+rcx]
+ adc rdx,0
+ add r11,QWORD PTR[((-8))+r15*8+rsp]
+ adc rdx,0
+ lea r14,QWORD PTR[1+r14]
+ mov r10,rdx
+
+ mul rbp
+ add rdi,rax
+ mov rax,QWORD PTR[rsi]
+ adc rdx,0
+ add rdi,r11
+ adc rdx,0
+ mov QWORD PTR[((-16))+r15*8+rsp],rdi
+ mov r13,rdx
+
+ xor rdi,rdi
+ add r13,r10
+ adc rdi,0
+ add r13,QWORD PTR[r9*8+rsp]
+ adc rdi,0
+ mov QWORD PTR[((-8))+r15*8+rsp],r13
+ mov QWORD PTR[r15*8+rsp],rdi
+
+ cmp r14,r9
+ jl $L$outer4x
+ mov rdi,QWORD PTR[16+r9*8+rsp]
+ mov rax,QWORD PTR[rsp]
+ pxor xmm0,xmm0
+ mov rdx,QWORD PTR[8+rsp]
+ shr r9,2
+ lea rsi,QWORD PTR[rsp]
+ xor r14,r14
+
+ sub rax,QWORD PTR[rcx]
+ mov rbx,QWORD PTR[16+rsi]
+ mov rbp,QWORD PTR[24+rsi]
+ sbb rdx,QWORD PTR[8+rcx]
+ lea r15,QWORD PTR[((-1))+r9]
+ jmp $L$sub4x
+ALIGN 16
+$L$sub4x::
+ mov QWORD PTR[r14*8+rdi],rax
+ mov QWORD PTR[8+r14*8+rdi],rdx
+ sbb rbx,QWORD PTR[16+r14*8+rcx]
+ mov rax,QWORD PTR[32+r14*8+rsi]
+ mov rdx,QWORD PTR[40+r14*8+rsi]
+ sbb rbp,QWORD PTR[24+r14*8+rcx]
+ mov QWORD PTR[16+r14*8+rdi],rbx
+ mov QWORD PTR[24+r14*8+rdi],rbp
+ sbb rax,QWORD PTR[32+r14*8+rcx]
+ mov rbx,QWORD PTR[48+r14*8+rsi]
+ mov rbp,QWORD PTR[56+r14*8+rsi]
+ sbb rdx,QWORD PTR[40+r14*8+rcx]
+ lea r14,QWORD PTR[4+r14]
+ dec r15
+ jnz $L$sub4x
+
+ mov QWORD PTR[r14*8+rdi],rax
+ mov rax,QWORD PTR[32+r14*8+rsi]
+ sbb rbx,QWORD PTR[16+r14*8+rcx]
+ mov QWORD PTR[8+r14*8+rdi],rdx
+ sbb rbp,QWORD PTR[24+r14*8+rcx]
+ mov QWORD PTR[16+r14*8+rdi],rbx
+
+ sbb rax,0
+ mov QWORD PTR[24+r14*8+rdi],rbp
+ xor r14,r14
+ and rsi,rax
+ not rax
+ mov rcx,rdi
+ and rcx,rax
+ lea r15,QWORD PTR[((-1))+r9]
+ or rsi,rcx
+
+ movdqu xmm1,XMMWORD PTR[rsi]
+ movdqa XMMWORD PTR[rsp],xmm0
+ movdqu XMMWORD PTR[rdi],xmm1
+ jmp $L$copy4x
+ALIGN 16
+$L$copy4x::
+ movdqu xmm2,XMMWORD PTR[16+r14*1+rsi]
+ movdqu xmm1,XMMWORD PTR[32+r14*1+rsi]
+ movdqa XMMWORD PTR[16+r14*1+rsp],xmm0
+ movdqu XMMWORD PTR[16+r14*1+rdi],xmm2
+ movdqa XMMWORD PTR[32+r14*1+rsp],xmm0
+ movdqu XMMWORD PTR[32+r14*1+rdi],xmm1
+ lea r14,QWORD PTR[32+r14]
+ dec r15
+ jnz $L$copy4x
+
+ shl r9,2
+ movdqu xmm2,XMMWORD PTR[16+r14*1+rsi]
+ movdqa XMMWORD PTR[16+r14*1+rsp],xmm0
+ movdqu XMMWORD PTR[16+r14*1+rdi],xmm2
+ mov rsi,QWORD PTR[8+r9*8+rsp]
+ mov rax,1
+ mov r15,QWORD PTR[rsi]
+ mov r14,QWORD PTR[8+rsi]
+ mov r13,QWORD PTR[16+rsi]
+ mov r12,QWORD PTR[24+rsi]
+ mov rbp,QWORD PTR[32+rsi]
+ mov rbx,QWORD PTR[40+rsi]
+ lea rsp,QWORD PTR[48+rsi]
+$L$mul4x_epilogue::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_bn_mul4x_mont::
+bn_mul4x_mont ENDP
+
+ALIGN 16
+bn_sqr4x_mont PROC PRIVATE
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_bn_sqr4x_mont::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+ mov r9,QWORD PTR[48+rsp]
+
+
+$L$sqr4x_enter::
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+
+ shl r9d,3
+ xor r10,r10
+ mov r11,rsp
+ sub r10,r9
+ mov r8,QWORD PTR[r8]
+ lea rsp,QWORD PTR[((-72))+r10*2+rsp]
+ and rsp,-1024
+
+
+
+
+
+
+
+
+
+
+
+ mov QWORD PTR[32+rsp],rdi
+ mov QWORD PTR[40+rsp],rcx
+ mov QWORD PTR[48+rsp],r8
+ mov QWORD PTR[56+rsp],r11
+$L$sqr4x_body::
+
+
+
+
+
+
+
+ lea rbp,QWORD PTR[32+r10]
+ lea rsi,QWORD PTR[r9*1+rsi]
+
+ mov rcx,r9
+
+
+ mov r14,QWORD PTR[((-32))+rbp*1+rsi]
+ lea rdi,QWORD PTR[64+r9*2+rsp]
+ mov rax,QWORD PTR[((-24))+rbp*1+rsi]
+ lea rdi,QWORD PTR[((-32))+rbp*1+rdi]
+ mov rbx,QWORD PTR[((-16))+rbp*1+rsi]
+ mov r15,rax
+
+ mul r14
+ mov r10,rax
+ mov rax,rbx
+ mov r11,rdx
+ mov QWORD PTR[((-24))+rbp*1+rdi],r10
+
+ xor r10,r10
+ mul r14
+ add r11,rax
+ mov rax,rbx
+ adc r10,rdx
+ mov QWORD PTR[((-16))+rbp*1+rdi],r11
+
+ lea rcx,QWORD PTR[((-16))+rbp]
+
+
+ mov rbx,QWORD PTR[8+rcx*1+rsi]
+ mul r15
+ mov r12,rax
+ mov rax,rbx
+ mov r13,rdx
+
+ xor r11,r11
+ add r10,r12
+ lea rcx,QWORD PTR[16+rcx]
+ adc r11,0
+ mul r14
+ add r10,rax
+ mov rax,rbx
+ adc r11,rdx
+ mov QWORD PTR[((-8))+rcx*1+rdi],r10
+ jmp $L$sqr4x_1st
+
+ALIGN 16
+$L$sqr4x_1st::
+ mov rbx,QWORD PTR[rcx*1+rsi]
+ xor r12,r12
+ mul r15
+ add r13,rax
+ mov rax,rbx
+ adc r12,rdx
+
+ xor r10,r10
+ add r11,r13
+ adc r10,0
+ mul r14
+ add r11,rax
+ mov rax,rbx
+ adc r10,rdx
+ mov QWORD PTR[rcx*1+rdi],r11
+
+
+ mov rbx,QWORD PTR[8+rcx*1+rsi]
+ xor r13,r13
+ mul r15
+ add r12,rax
+ mov rax,rbx
+ adc r13,rdx
+
+ xor r11,r11
+ add r10,r12
+ adc r11,0
+ mul r14
+ add r10,rax
+ mov rax,rbx
+ adc r11,rdx
+ mov QWORD PTR[8+rcx*1+rdi],r10
+
+ mov rbx,QWORD PTR[16+rcx*1+rsi]
+ xor r12,r12
+ mul r15
+ add r13,rax
+ mov rax,rbx
+ adc r12,rdx
+
+ xor r10,r10
+ add r11,r13
+ adc r10,0
+ mul r14
+ add r11,rax
+ mov rax,rbx
+ adc r10,rdx
+ mov QWORD PTR[16+rcx*1+rdi],r11
+
+
+ mov rbx,QWORD PTR[24+rcx*1+rsi]
+ xor r13,r13
+ mul r15
+ add r12,rax
+ mov rax,rbx
+ adc r13,rdx
+
+ xor r11,r11
+ add r10,r12
+ lea rcx,QWORD PTR[32+rcx]
+ adc r11,0
+ mul r14
+ add r10,rax
+ mov rax,rbx
+ adc r11,rdx
+ mov QWORD PTR[((-8))+rcx*1+rdi],r10
+
+ cmp rcx,0
+ jne $L$sqr4x_1st
+
+ xor r12,r12
+ add r13,r11
+ adc r12,0
+ mul r15
+ add r13,rax
+ adc r12,rdx
+
+ mov QWORD PTR[rdi],r13
+ lea rbp,QWORD PTR[16+rbp]
+ mov QWORD PTR[8+rdi],r12
+ jmp $L$sqr4x_outer
+
+ALIGN 16
+$L$sqr4x_outer::
+ mov r14,QWORD PTR[((-32))+rbp*1+rsi]
+ lea rdi,QWORD PTR[64+r9*2+rsp]
+ mov rax,QWORD PTR[((-24))+rbp*1+rsi]
+ lea rdi,QWORD PTR[((-32))+rbp*1+rdi]
+ mov rbx,QWORD PTR[((-16))+rbp*1+rsi]
+ mov r15,rax
+
+ mov r10,QWORD PTR[((-24))+rbp*1+rdi]
+ xor r11,r11
+ mul r14
+ add r10,rax
+ mov rax,rbx
+ adc r11,rdx
+ mov QWORD PTR[((-24))+rbp*1+rdi],r10
+
+ xor r10,r10
+ add r11,QWORD PTR[((-16))+rbp*1+rdi]
+ adc r10,0
+ mul r14
+ add r11,rax
+ mov rax,rbx
+ adc r10,rdx
+ mov QWORD PTR[((-16))+rbp*1+rdi],r11
+
+ lea rcx,QWORD PTR[((-16))+rbp]
+ xor r12,r12
+
+
+ mov rbx,QWORD PTR[8+rcx*1+rsi]
+ xor r13,r13
+ add r12,QWORD PTR[8+rcx*1+rdi]
+ adc r13,0
+ mul r15
+ add r12,rax
+ mov rax,rbx
+ adc r13,rdx
+
+ xor r11,r11
+ add r10,r12
+ adc r11,0
+ mul r14
+ add r10,rax
+ mov rax,rbx
+ adc r11,rdx
+ mov QWORD PTR[8+rcx*1+rdi],r10
+
+ lea rcx,QWORD PTR[16+rcx]
+ jmp $L$sqr4x_inner
+
+ALIGN 16
+$L$sqr4x_inner::
+ mov rbx,QWORD PTR[rcx*1+rsi]
+ xor r12,r12
+ add r13,QWORD PTR[rcx*1+rdi]
+ adc r12,0
+ mul r15
+ add r13,rax
+ mov rax,rbx
+ adc r12,rdx
+
+ xor r10,r10
+ add r11,r13
+ adc r10,0
+ mul r14
+ add r11,rax
+ mov rax,rbx
+ adc r10,rdx
+ mov QWORD PTR[rcx*1+rdi],r11
+
+ mov rbx,QWORD PTR[8+rcx*1+rsi]
+ xor r13,r13
+ add r12,QWORD PTR[8+rcx*1+rdi]
+ adc r13,0
+ mul r15
+ add r12,rax
+ mov rax,rbx
+ adc r13,rdx
+
+ xor r11,r11
+ add r10,r12
+ lea rcx,QWORD PTR[16+rcx]
+ adc r11,0
+ mul r14
+ add r10,rax
+ mov rax,rbx
+ adc r11,rdx
+ mov QWORD PTR[((-8))+rcx*1+rdi],r10
+
+ cmp rcx,0
+ jne $L$sqr4x_inner
+
+ xor r12,r12
+ add r13,r11
+ adc r12,0
+ mul r15
+ add r13,rax
+ adc r12,rdx
+
+ mov QWORD PTR[rdi],r13
+ mov QWORD PTR[8+rdi],r12
+
+ add rbp,16
+ jnz $L$sqr4x_outer
+
+
+ mov r14,QWORD PTR[((-32))+rsi]
+ lea rdi,QWORD PTR[64+r9*2+rsp]
+ mov rax,QWORD PTR[((-24))+rsi]
+ lea rdi,QWORD PTR[((-32))+rbp*1+rdi]
+ mov rbx,QWORD PTR[((-16))+rsi]
+ mov r15,rax
+
+ xor r11,r11
+ mul r14
+ add r10,rax
+ mov rax,rbx
+ adc r11,rdx
+ mov QWORD PTR[((-24))+rdi],r10
+
+ xor r10,r10
+ add r11,r13
+ adc r10,0
+ mul r14
+ add r11,rax
+ mov rax,rbx
+ adc r10,rdx
+ mov QWORD PTR[((-16))+rdi],r11
+
+ mov rbx,QWORD PTR[((-8))+rsi]
+ mul r15
+ add r12,rax
+ mov rax,rbx
+ adc rdx,0
+
+ xor r11,r11
+ add r10,r12
+ mov r13,rdx
+ adc r11,0
+ mul r14
+ add r10,rax
+ mov rax,rbx
+ adc r11,rdx
+ mov QWORD PTR[((-8))+rdi],r10
+
+ xor r12,r12
+ add r13,r11
+ adc r12,0
+ mul r15
+ add r13,rax
+ mov rax,QWORD PTR[((-16))+rsi]
+ adc r12,rdx
+
+ mov QWORD PTR[rdi],r13
+ mov QWORD PTR[8+rdi],r12
+
+ mul rbx
+ add rbp,16
+ xor r14,r14
+ sub rbp,r9
+ xor r15,r15
+
+ add rax,r12
+ adc rdx,0
+ mov QWORD PTR[8+rdi],rax
+ mov QWORD PTR[16+rdi],rdx
+ mov QWORD PTR[24+rdi],r15
+
+ mov rax,QWORD PTR[((-16))+rbp*1+rsi]
+ lea rdi,QWORD PTR[64+r9*2+rsp]
+ xor r10,r10
+ mov r11,QWORD PTR[((-24))+rbp*2+rdi]
+
+ lea r12,QWORD PTR[r10*2+r14]
+ shr r10,63
+ lea r13,QWORD PTR[r11*2+rcx]
+ shr r11,63
+ or r13,r10
+ mov r10,QWORD PTR[((-16))+rbp*2+rdi]
+ mov r14,r11
+ mul rax
+ neg r15
+ mov r11,QWORD PTR[((-8))+rbp*2+rdi]
+ adc r12,rax
+ mov rax,QWORD PTR[((-8))+rbp*1+rsi]
+ mov QWORD PTR[((-32))+rbp*2+rdi],r12
+ adc r13,rdx
+
+ lea rbx,QWORD PTR[r10*2+r14]
+ mov QWORD PTR[((-24))+rbp*2+rdi],r13
+ sbb r15,r15
+ shr r10,63
+ lea r8,QWORD PTR[r11*2+rcx]
+ shr r11,63
+ or r8,r10
+ mov r10,QWORD PTR[rbp*2+rdi]
+ mov r14,r11
+ mul rax
+ neg r15
+ mov r11,QWORD PTR[8+rbp*2+rdi]
+ adc rbx,rax
+ mov rax,QWORD PTR[rbp*1+rsi]
+ mov QWORD PTR[((-16))+rbp*2+rdi],rbx
+ adc r8,rdx
+ lea rbp,QWORD PTR[16+rbp]
+ mov QWORD PTR[((-40))+rbp*2+rdi],r8
+ sbb r15,r15
+ jmp $L$sqr4x_shift_n_add
+
+ALIGN 16
+$L$sqr4x_shift_n_add::
+ lea r12,QWORD PTR[r10*2+r14]
+ shr r10,63
+ lea r13,QWORD PTR[r11*2+rcx]
+ shr r11,63
+ or r13,r10
+ mov r10,QWORD PTR[((-16))+rbp*2+rdi]
+ mov r14,r11
+ mul rax
+ neg r15
+ mov r11,QWORD PTR[((-8))+rbp*2+rdi]
+ adc r12,rax
+ mov rax,QWORD PTR[((-8))+rbp*1+rsi]
+ mov QWORD PTR[((-32))+rbp*2+rdi],r12
+ adc r13,rdx
+
+ lea rbx,QWORD PTR[r10*2+r14]
+ mov QWORD PTR[((-24))+rbp*2+rdi],r13
+ sbb r15,r15
+ shr r10,63
+ lea r8,QWORD PTR[r11*2+rcx]
+ shr r11,63
+ or r8,r10
+ mov r10,QWORD PTR[rbp*2+rdi]
+ mov r14,r11
+ mul rax
+ neg r15
+ mov r11,QWORD PTR[8+rbp*2+rdi]
+ adc rbx,rax
+ mov rax,QWORD PTR[rbp*1+rsi]
+ mov QWORD PTR[((-16))+rbp*2+rdi],rbx
+ adc r8,rdx
+
+ lea r12,QWORD PTR[r10*2+r14]
+ mov QWORD PTR[((-8))+rbp*2+rdi],r8
+ sbb r15,r15
+ shr r10,63
+ lea r13,QWORD PTR[r11*2+rcx]
+ shr r11,63
+ or r13,r10
+ mov r10,QWORD PTR[16+rbp*2+rdi]
+ mov r14,r11
+ mul rax
+ neg r15
+ mov r11,QWORD PTR[24+rbp*2+rdi]
+ adc r12,rax
+ mov rax,QWORD PTR[8+rbp*1+rsi]
+ mov QWORD PTR[rbp*2+rdi],r12
+ adc r13,rdx
+
+ lea rbx,QWORD PTR[r10*2+r14]
+ mov QWORD PTR[8+rbp*2+rdi],r13
+ sbb r15,r15
+ shr r10,63
+ lea r8,QWORD PTR[r11*2+rcx]
+ shr r11,63
+ or r8,r10
+ mov r10,QWORD PTR[32+rbp*2+rdi]
+ mov r14,r11
+ mul rax
+ neg r15
+ mov r11,QWORD PTR[40+rbp*2+rdi]
+ adc rbx,rax
+ mov rax,QWORD PTR[16+rbp*1+rsi]
+ mov QWORD PTR[16+rbp*2+rdi],rbx
+ adc r8,rdx
+ mov QWORD PTR[24+rbp*2+rdi],r8
+ sbb r15,r15
+ add rbp,32
+ jnz $L$sqr4x_shift_n_add
+
+ lea r12,QWORD PTR[r10*2+r14]
+ shr r10,63
+ lea r13,QWORD PTR[r11*2+rcx]
+ shr r11,63
+ or r13,r10
+ mov r10,QWORD PTR[((-16))+rdi]
+ mov r14,r11
+ mul rax
+ neg r15
+ mov r11,QWORD PTR[((-8))+rdi]
+ adc r12,rax
+ mov rax,QWORD PTR[((-8))+rsi]
+ mov QWORD PTR[((-32))+rdi],r12
+ adc r13,rdx
+
+ lea rbx,QWORD PTR[r10*2+r14]
+ mov QWORD PTR[((-24))+rdi],r13
+ sbb r15,r15
+ shr r10,63
+ lea r8,QWORD PTR[r11*2+rcx]
+ shr r11,63
+ or r8,r10
+ mul rax
+ neg r15
+ adc rbx,rax
+ adc r8,rdx
+ mov QWORD PTR[((-16))+rdi],rbx
+ mov QWORD PTR[((-8))+rdi],r8
+ mov rsi,QWORD PTR[40+rsp]
+ mov r8,QWORD PTR[48+rsp]
+ xor rcx,rcx
+ mov QWORD PTR[rsp],r9
+ sub rcx,r9
+ mov r10,QWORD PTR[64+rsp]
+ mov r14,r8
+ lea rax,QWORD PTR[64+r9*2+rsp]
+ lea rdi,QWORD PTR[64+r9*1+rsp]
+ mov QWORD PTR[8+rsp],rax
+ lea rsi,QWORD PTR[r9*1+rsi]
+ xor rbp,rbp
+
+ mov rax,QWORD PTR[rcx*1+rsi]
+ mov r9,QWORD PTR[8+rcx*1+rsi]
+ imul r14,r10
+ mov rbx,rax
+ jmp $L$sqr4x_mont_outer
+
+ALIGN 16
+$L$sqr4x_mont_outer::
+ xor r11,r11
+ mul r14
+ add r10,rax
+ mov rax,r9
+ adc r11,rdx
+ mov r15,r8
+
+ xor r10,r10
+ add r11,QWORD PTR[8+rcx*1+rdi]
+ adc r10,0
+ mul r14
+ add r11,rax
+ mov rax,rbx
+ adc r10,rdx
+
+ imul r15,r11
+
+ mov rbx,QWORD PTR[16+rcx*1+rsi]
+ xor r13,r13
+ add r12,r11
+ adc r13,0
+ mul r15
+ add r12,rax
+ mov rax,rbx
+ adc r13,rdx
+ mov QWORD PTR[8+rcx*1+rdi],r12
+
+ xor r11,r11
+ add r10,QWORD PTR[16+rcx*1+rdi]
+ adc r11,0
+ mul r14
+ add r10,rax
+ mov rax,r9
+ adc r11,rdx
+
+ mov r9,QWORD PTR[24+rcx*1+rsi]
+ xor r12,r12
+ add r13,r10
+ adc r12,0
+ mul r15
+ add r13,rax
+ mov rax,r9
+ adc r12,rdx
+ mov QWORD PTR[16+rcx*1+rdi],r13
+
+ xor r10,r10
+ add r11,QWORD PTR[24+rcx*1+rdi]
+ lea rcx,QWORD PTR[32+rcx]
+ adc r10,0
+ mul r14
+ add r11,rax
+ mov rax,rbx
+ adc r10,rdx
+ jmp $L$sqr4x_mont_inner
+
+ALIGN 16
+$L$sqr4x_mont_inner::
+ mov rbx,QWORD PTR[rcx*1+rsi]
+ xor r13,r13
+ add r12,r11
+ adc r13,0
+ mul r15
+ add r12,rax
+ mov rax,rbx
+ adc r13,rdx
+ mov QWORD PTR[((-8))+rcx*1+rdi],r12
+
+ xor r11,r11
+ add r10,QWORD PTR[rcx*1+rdi]
+ adc r11,0
+ mul r14
+ add r10,rax
+ mov rax,r9
+ adc r11,rdx
+
+ mov r9,QWORD PTR[8+rcx*1+rsi]
+ xor r12,r12
+ add r13,r10
+ adc r12,0
+ mul r15
+ add r13,rax
+ mov rax,r9
+ adc r12,rdx
+ mov QWORD PTR[rcx*1+rdi],r13
+
+ xor r10,r10
+ add r11,QWORD PTR[8+rcx*1+rdi]
+ adc r10,0
+ mul r14
+ add r11,rax
+ mov rax,rbx
+ adc r10,rdx
+
+
+ mov rbx,QWORD PTR[16+rcx*1+rsi]
+ xor r13,r13
+ add r12,r11
+ adc r13,0
+ mul r15
+ add r12,rax
+ mov rax,rbx
+ adc r13,rdx
+ mov QWORD PTR[8+rcx*1+rdi],r12
+
+ xor r11,r11
+ add r10,QWORD PTR[16+rcx*1+rdi]
+ adc r11,0
+ mul r14
+ add r10,rax
+ mov rax,r9
+ adc r11,rdx
+
+ mov r9,QWORD PTR[24+rcx*1+rsi]
+ xor r12,r12
+ add r13,r10
+ adc r12,0
+ mul r15
+ add r13,rax
+ mov rax,r9
+ adc r12,rdx
+ mov QWORD PTR[16+rcx*1+rdi],r13
+
+ xor r10,r10
+ add r11,QWORD PTR[24+rcx*1+rdi]
+ lea rcx,QWORD PTR[32+rcx]
+ adc r10,0
+ mul r14
+ add r11,rax
+ mov rax,rbx
+ adc r10,rdx
+ cmp rcx,0
+ jne $L$sqr4x_mont_inner
+
+ sub rcx,QWORD PTR[rsp]
+ mov r14,r8
+
+ xor r13,r13
+ add r12,r11
+ adc r13,0
+ mul r15
+ add r12,rax
+ mov rax,r9
+ adc r13,rdx
+ mov QWORD PTR[((-8))+rdi],r12
+
+ xor r11,r11
+ add r10,QWORD PTR[rdi]
+ adc r11,0
+ mov rbx,QWORD PTR[rcx*1+rsi]
+ add r10,rbp
+ adc r11,0
+
+ imul r14,QWORD PTR[16+rcx*1+rdi]
+ xor r12,r12
+ mov r9,QWORD PTR[8+rcx*1+rsi]
+ add r13,r10
+ mov r10,QWORD PTR[16+rcx*1+rdi]
+ adc r12,0
+ mul r15
+ add r13,rax
+ mov rax,rbx
+ adc r12,rdx
+ mov QWORD PTR[rdi],r13
+
+ xor rbp,rbp
+ add r12,QWORD PTR[8+rdi]
+ adc rbp,rbp
+ add r12,r11
+ lea rdi,QWORD PTR[16+rdi]
+ adc rbp,0
+ mov QWORD PTR[((-8))+rdi],r12
+ cmp rdi,QWORD PTR[8+rsp]
+ jb $L$sqr4x_mont_outer
+
+ mov r9,QWORD PTR[rsp]
+ mov QWORD PTR[rdi],rbp
+ mov rax,QWORD PTR[64+r9*1+rsp]
+ lea rbx,QWORD PTR[64+r9*1+rsp]
+ mov rsi,QWORD PTR[40+rsp]
+ shr r9,5
+ mov rdx,QWORD PTR[8+rbx]
+ xor rbp,rbp
+
+ mov rdi,QWORD PTR[32+rsp]
+ sub rax,QWORD PTR[rsi]
+ mov r10,QWORD PTR[16+rbx]
+ mov r11,QWORD PTR[24+rbx]
+ sbb rdx,QWORD PTR[8+rsi]
+ lea rcx,QWORD PTR[((-1))+r9]
+ jmp $L$sqr4x_sub
+ALIGN 16
+$L$sqr4x_sub::
+ mov QWORD PTR[rbp*8+rdi],rax
+ mov QWORD PTR[8+rbp*8+rdi],rdx
+ sbb r10,QWORD PTR[16+rbp*8+rsi]
+ mov rax,QWORD PTR[32+rbp*8+rbx]
+ mov rdx,QWORD PTR[40+rbp*8+rbx]
+ sbb r11,QWORD PTR[24+rbp*8+rsi]
+ mov QWORD PTR[16+rbp*8+rdi],r10
+ mov QWORD PTR[24+rbp*8+rdi],r11
+ sbb rax,QWORD PTR[32+rbp*8+rsi]
+ mov r10,QWORD PTR[48+rbp*8+rbx]
+ mov r11,QWORD PTR[56+rbp*8+rbx]
+ sbb rdx,QWORD PTR[40+rbp*8+rsi]
+ lea rbp,QWORD PTR[4+rbp]
+ dec rcx
+ jnz $L$sqr4x_sub
+
+ mov QWORD PTR[rbp*8+rdi],rax
+ mov rax,QWORD PTR[32+rbp*8+rbx]
+ sbb r10,QWORD PTR[16+rbp*8+rsi]
+ mov QWORD PTR[8+rbp*8+rdi],rdx
+ sbb r11,QWORD PTR[24+rbp*8+rsi]
+ mov QWORD PTR[16+rbp*8+rdi],r10
+
+ sbb rax,0
+ mov QWORD PTR[24+rbp*8+rdi],r11
+ xor rbp,rbp
+ and rbx,rax
+ not rax
+ mov rsi,rdi
+ and rsi,rax
+ lea rcx,QWORD PTR[((-1))+r9]
+ or rbx,rsi
+
+ pxor xmm0,xmm0
+ lea rsi,QWORD PTR[64+r9*8+rsp]
+ movdqu xmm1,XMMWORD PTR[rbx]
+ lea rsi,QWORD PTR[r9*8+rsi]
+ movdqa XMMWORD PTR[64+rsp],xmm0
+ movdqa XMMWORD PTR[rsi],xmm0
+ movdqu XMMWORD PTR[rdi],xmm1
+ jmp $L$sqr4x_copy
+ALIGN 16
+$L$sqr4x_copy::
+ movdqu xmm2,XMMWORD PTR[16+rbp*1+rbx]
+ movdqu xmm1,XMMWORD PTR[32+rbp*1+rbx]
+ movdqa XMMWORD PTR[80+rbp*1+rsp],xmm0
+ movdqa XMMWORD PTR[96+rbp*1+rsp],xmm0
+ movdqa XMMWORD PTR[16+rbp*1+rsi],xmm0
+ movdqa XMMWORD PTR[32+rbp*1+rsi],xmm0
+ movdqu XMMWORD PTR[16+rbp*1+rdi],xmm2
+ movdqu XMMWORD PTR[32+rbp*1+rdi],xmm1
+ lea rbp,QWORD PTR[32+rbp]
+ dec rcx
+ jnz $L$sqr4x_copy
+
+ movdqu xmm2,XMMWORD PTR[16+rbp*1+rbx]
+ movdqa XMMWORD PTR[80+rbp*1+rsp],xmm0
+ movdqa XMMWORD PTR[16+rbp*1+rsi],xmm0
+ movdqu XMMWORD PTR[16+rbp*1+rdi],xmm2
+ mov rsi,QWORD PTR[56+rsp]
+ mov rax,1
+ mov r15,QWORD PTR[rsi]
+ mov r14,QWORD PTR[8+rsi]
+ mov r13,QWORD PTR[16+rsi]
+ mov r12,QWORD PTR[24+rsi]
+ mov rbp,QWORD PTR[32+rsi]
+ mov rbx,QWORD PTR[40+rsi]
+ lea rsp,QWORD PTR[48+rsi]
+$L$sqr4x_epilogue::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_bn_sqr4x_mont::
+bn_sqr4x_mont ENDP
DB 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105
DB 112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56
DB 54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83
@@ -192,7 +1425,7 @@ ALIGN 16
EXTERN __imp_RtlVirtualUnwind:NEAR
ALIGN 16
-se_handler PROC PRIVATE
+mul_handler PROC PRIVATE
push rsi
push rdi
push rbx
@@ -207,15 +1440,20 @@ se_handler PROC PRIVATE
mov rax,QWORD PTR[120+r8]
mov rbx,QWORD PTR[248+r8]
- lea r10,QWORD PTR[$L$prologue]
+ mov rsi,QWORD PTR[8+r9]
+ mov r11,QWORD PTR[56+r9]
+
+ mov r10d,DWORD PTR[r11]
+ lea r10,QWORD PTR[r10*1+rsi]
cmp rbx,r10
- jb $L$in_prologue
+ jb $L$common_seh_tail
mov rax,QWORD PTR[152+r8]
- lea r10,QWORD PTR[$L$epilogue]
+ mov r10d,DWORD PTR[4+r11]
+ lea r10,QWORD PTR[r10*1+rsi]
cmp rbx,r10
- jae $L$in_prologue
+ jae $L$common_seh_tail
mov r10,QWORD PTR[192+r8]
mov rax,QWORD PTR[8+r10*8+rax]
@@ -234,7 +1472,53 @@ se_handler PROC PRIVATE
mov QWORD PTR[232+r8],r14
mov QWORD PTR[240+r8],r15
-$L$in_prologue::
+ jmp $L$common_seh_tail
+mul_handler ENDP
+
+
+ALIGN 16
+sqr_handler PROC PRIVATE
+ push rsi
+ push rdi
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq
+ sub rsp,64
+
+ mov rax,QWORD PTR[120+r8]
+ mov rbx,QWORD PTR[248+r8]
+
+ lea r10,QWORD PTR[$L$sqr4x_body]
+ cmp rbx,r10
+ jb $L$common_seh_tail
+
+ mov rax,QWORD PTR[152+r8]
+
+ lea r10,QWORD PTR[$L$sqr4x_epilogue]
+ cmp rbx,r10
+ jae $L$common_seh_tail
+
+ mov rax,QWORD PTR[56+rax]
+ lea rax,QWORD PTR[48+rax]
+
+ mov rbx,QWORD PTR[((-8))+rax]
+ mov rbp,QWORD PTR[((-16))+rax]
+ mov r12,QWORD PTR[((-24))+rax]
+ mov r13,QWORD PTR[((-32))+rax]
+ mov r14,QWORD PTR[((-40))+rax]
+ mov r15,QWORD PTR[((-48))+rax]
+ mov QWORD PTR[144+r8],rbx
+ mov QWORD PTR[160+r8],rbp
+ mov QWORD PTR[216+r8],r12
+ mov QWORD PTR[224+r8],r13
+ mov QWORD PTR[232+r8],r14
+ mov QWORD PTR[240+r8],r15
+
+$L$common_seh_tail::
mov rdi,QWORD PTR[8+rax]
mov rsi,QWORD PTR[16+rax]
mov QWORD PTR[152+r8],rax
@@ -273,7 +1557,7 @@ $L$in_prologue::
pop rdi
pop rsi
DB 0F3h,0C3h ;repret
-se_handler ENDP
+sqr_handler ENDP
.text$ ENDS
.pdata SEGMENT READONLY ALIGN(4)
@@ -282,12 +1566,30 @@ ALIGN 4
DD imagerel $L$SEH_end_bn_mul_mont
DD imagerel $L$SEH_info_bn_mul_mont
+ DD imagerel $L$SEH_begin_bn_mul4x_mont
+ DD imagerel $L$SEH_end_bn_mul4x_mont
+ DD imagerel $L$SEH_info_bn_mul4x_mont
+
+ DD imagerel $L$SEH_begin_bn_sqr4x_mont
+ DD imagerel $L$SEH_end_bn_sqr4x_mont
+ DD imagerel $L$SEH_info_bn_sqr4x_mont
+
.pdata ENDS
.xdata SEGMENT READONLY ALIGN(8)
ALIGN 8
$L$SEH_info_bn_mul_mont::
DB 9,0,0,0
- DD imagerel se_handler
+ DD imagerel mul_handler
+ DD imagerel $L$mul_body,imagerel $L$mul_epilogue
+
+$L$SEH_info_bn_mul4x_mont::
+DB 9,0,0,0
+ DD imagerel mul_handler
+ DD imagerel $L$mul4x_body,imagerel $L$mul4x_epilogue
+
+$L$SEH_info_bn_sqr4x_mont::
+DB 9,0,0,0
+ DD imagerel sqr_handler
.xdata ENDS
END
diff --git a/deps/openssl/asm/x64-win32-masm/camellia/cmll-x86_64.asm b/deps/openssl/asm/x64-win32-masm/camellia/cmll-x86_64.asm
index a5913da92..0ea789b6a 100644
--- a/deps/openssl/asm/x64-win32-masm/camellia/cmll-x86_64.asm
+++ b/deps/openssl/asm/x64-win32-masm/camellia/cmll-x86_64.asm
@@ -250,7 +250,7 @@ $L$eloop::
xor r8d,ecx
xor r9d,ecx
xor r9d,edx
- lea r14,QWORD PTR[((16*4))+r14]
+ lea r14,QWORD PTR[64+r14]
cmp r14,r15
mov edx,DWORD PTR[8+r14]
mov ecx,DWORD PTR[12+r14]
@@ -533,7 +533,7 @@ $L$dloop::
xor r8d,ecx
xor r9d,ecx
xor r9d,edx
- lea r14,QWORD PTR[((-16*4))+r14]
+ lea r14,QWORD PTR[((-64))+r14]
cmp r14,r15
mov edx,DWORD PTR[r14]
mov ecx,DWORD PTR[4+r14]
diff --git a/deps/openssl/asm/x64-win32-masm/md5/md5-x86_64.asm b/deps/openssl/asm/x64-win32-masm/md5/md5-x86_64.asm
index 34305c687..8ddad41c8 100644
--- a/deps/openssl/asm/x64-win32-masm/md5/md5-x86_64.asm
+++ b/deps/openssl/asm/x64-win32-masm/md5/md5-x86_64.asm
@@ -27,10 +27,10 @@ $L$prologue::
mov rbp,rdi
shl rdx,6
lea rdi,QWORD PTR[rdx*1+rsi]
- mov eax,DWORD PTR[((0*4))+rbp]
- mov ebx,DWORD PTR[((1*4))+rbp]
- mov ecx,DWORD PTR[((2*4))+rbp]
- mov edx,DWORD PTR[((3*4))+rbp]
+ mov eax,DWORD PTR[rbp]
+ mov ebx,DWORD PTR[4+rbp]
+ mov ecx,DWORD PTR[8+rbp]
+ mov edx,DWORD PTR[12+rbp]
@@ -48,160 +48,160 @@ $L$loop::
mov r9d,ebx
mov r14d,ecx
mov r15d,edx
- mov r10d,DWORD PTR[((0*4))+rsi]
+ mov r10d,DWORD PTR[rsi]
mov r11d,edx
xor r11d,ecx
- lea eax,DWORD PTR[0d76aa478h+r10*1+rax]
+ lea eax,DWORD PTR[((-680876936))+r10*1+rax]
and r11d,ebx
xor r11d,edx
- mov r10d,DWORD PTR[((1*4))+rsi]
+ mov r10d,DWORD PTR[4+rsi]
add eax,r11d
rol eax,7
mov r11d,ecx
add eax,ebx
xor r11d,ebx
- lea edx,DWORD PTR[0e8c7b756h+r10*1+rdx]
+ lea edx,DWORD PTR[((-389564586))+r10*1+rdx]
and r11d,eax
xor r11d,ecx
- mov r10d,DWORD PTR[((2*4))+rsi]
+ mov r10d,DWORD PTR[8+rsi]
add edx,r11d
rol edx,12
mov r11d,ebx
add edx,eax
xor r11d,eax
- lea ecx,DWORD PTR[0242070dbh+r10*1+rcx]
+ lea ecx,DWORD PTR[606105819+r10*1+rcx]
and r11d,edx
xor r11d,ebx
- mov r10d,DWORD PTR[((3*4))+rsi]
+ mov r10d,DWORD PTR[12+rsi]
add ecx,r11d
rol ecx,17
mov r11d,eax
add ecx,edx
xor r11d,edx
- lea ebx,DWORD PTR[0c1bdceeeh+r10*1+rbx]
+ lea ebx,DWORD PTR[((-1044525330))+r10*1+rbx]
and r11d,ecx
xor r11d,eax
- mov r10d,DWORD PTR[((4*4))+rsi]
+ mov r10d,DWORD PTR[16+rsi]
add ebx,r11d
rol ebx,22
mov r11d,edx
add ebx,ecx
xor r11d,ecx
- lea eax,DWORD PTR[0f57c0fafh+r10*1+rax]
+ lea eax,DWORD PTR[((-176418897))+r10*1+rax]
and r11d,ebx
xor r11d,edx
- mov r10d,DWORD PTR[((5*4))+rsi]
+ mov r10d,DWORD PTR[20+rsi]
add eax,r11d
rol eax,7
mov r11d,ecx
add eax,ebx
xor r11d,ebx
- lea edx,DWORD PTR[04787c62ah+r10*1+rdx]
+ lea edx,DWORD PTR[1200080426+r10*1+rdx]
and r11d,eax
xor r11d,ecx
- mov r10d,DWORD PTR[((6*4))+rsi]
+ mov r10d,DWORD PTR[24+rsi]
add edx,r11d
rol edx,12
mov r11d,ebx
add edx,eax
xor r11d,eax
- lea ecx,DWORD PTR[0a8304613h+r10*1+rcx]
+ lea ecx,DWORD PTR[((-1473231341))+r10*1+rcx]
and r11d,edx
xor r11d,ebx
- mov r10d,DWORD PTR[((7*4))+rsi]
+ mov r10d,DWORD PTR[28+rsi]
add ecx,r11d
rol ecx,17
mov r11d,eax
add ecx,edx
xor r11d,edx
- lea ebx,DWORD PTR[0fd469501h+r10*1+rbx]
+ lea ebx,DWORD PTR[((-45705983))+r10*1+rbx]
and r11d,ecx
xor r11d,eax
- mov r10d,DWORD PTR[((8*4))+rsi]
+ mov r10d,DWORD PTR[32+rsi]
add ebx,r11d
rol ebx,22
mov r11d,edx
add ebx,ecx
xor r11d,ecx
- lea eax,DWORD PTR[0698098d8h+r10*1+rax]
+ lea eax,DWORD PTR[1770035416+r10*1+rax]
and r11d,ebx
xor r11d,edx
- mov r10d,DWORD PTR[((9*4))+rsi]
+ mov r10d,DWORD PTR[36+rsi]
add eax,r11d
rol eax,7
mov r11d,ecx
add eax,ebx
xor r11d,ebx
- lea edx,DWORD PTR[08b44f7afh+r10*1+rdx]
+ lea edx,DWORD PTR[((-1958414417))+r10*1+rdx]
and r11d,eax
xor r11d,ecx
- mov r10d,DWORD PTR[((10*4))+rsi]
+ mov r10d,DWORD PTR[40+rsi]
add edx,r11d
rol edx,12
mov r11d,ebx
add edx,eax
xor r11d,eax
- lea ecx,DWORD PTR[0ffff5bb1h+r10*1+rcx]
+ lea ecx,DWORD PTR[((-42063))+r10*1+rcx]
and r11d,edx
xor r11d,ebx
- mov r10d,DWORD PTR[((11*4))+rsi]
+ mov r10d,DWORD PTR[44+rsi]
add ecx,r11d
rol ecx,17
mov r11d,eax
add ecx,edx
xor r11d,edx
- lea ebx,DWORD PTR[0895cd7beh+r10*1+rbx]
+ lea ebx,DWORD PTR[((-1990404162))+r10*1+rbx]
and r11d,ecx
xor r11d,eax
- mov r10d,DWORD PTR[((12*4))+rsi]
+ mov r10d,DWORD PTR[48+rsi]
add ebx,r11d
rol ebx,22
mov r11d,edx
add ebx,ecx
xor r11d,ecx
- lea eax,DWORD PTR[06b901122h+r10*1+rax]
+ lea eax,DWORD PTR[1804603682+r10*1+rax]
and r11d,ebx
xor r11d,edx
- mov r10d,DWORD PTR[((13*4))+rsi]
+ mov r10d,DWORD PTR[52+rsi]
add eax,r11d
rol eax,7
mov r11d,ecx
add eax,ebx
xor r11d,ebx
- lea edx,DWORD PTR[0fd987193h+r10*1+rdx]
+ lea edx,DWORD PTR[((-40341101))+r10*1+rdx]
and r11d,eax
xor r11d,ecx
- mov r10d,DWORD PTR[((14*4))+rsi]
+ mov r10d,DWORD PTR[56+rsi]
add edx,r11d
rol edx,12
mov r11d,ebx
add edx,eax
xor r11d,eax
- lea ecx,DWORD PTR[0a679438eh+r10*1+rcx]
+ lea ecx,DWORD PTR[((-1502002290))+r10*1+rcx]
and r11d,edx
xor r11d,ebx
- mov r10d,DWORD PTR[((15*4))+rsi]
+ mov r10d,DWORD PTR[60+rsi]
add ecx,r11d
rol ecx,17
mov r11d,eax
add ecx,edx
xor r11d,edx
- lea ebx,DWORD PTR[049b40821h+r10*1+rbx]
+ lea ebx,DWORD PTR[1236535329+r10*1+rbx]
and r11d,ecx
xor r11d,eax
- mov r10d,DWORD PTR[((0*4))+rsi]
+ mov r10d,DWORD PTR[rsi]
add ebx,r11d
rol ebx,22
mov r11d,edx
add ebx,ecx
- mov r10d,DWORD PTR[((1*4))+rsi]
+ mov r10d,DWORD PTR[4+rsi]
mov r11d,edx
mov r12d,edx
not r11d
- lea eax,DWORD PTR[0f61e2562h+r10*1+rax]
+ lea eax,DWORD PTR[((-165796510))+r10*1+rax]
and r12d,ebx
and r11d,ecx
- mov r10d,DWORD PTR[((6*4))+rsi]
+ mov r10d,DWORD PTR[24+rsi]
or r12d,r11d
mov r11d,ecx
add eax,r12d
@@ -209,10 +209,10 @@ $L$loop::
rol eax,5
add eax,ebx
not r11d
- lea edx,DWORD PTR[0c040b340h+r10*1+rdx]
+ lea edx,DWORD PTR[((-1069501632))+r10*1+rdx]
and r12d,eax
and r11d,ebx
- mov r10d,DWORD PTR[((11*4))+rsi]
+ mov r10d,DWORD PTR[44+rsi]
or r12d,r11d
mov r11d,ebx
add edx,r12d
@@ -220,10 +220,10 @@ $L$loop::
rol edx,9
add edx,eax
not r11d
- lea ecx,DWORD PTR[0265e5a51h+r10*1+rcx]
+ lea ecx,DWORD PTR[643717713+r10*1+rcx]
and r12d,edx
and r11d,eax
- mov r10d,DWORD PTR[((0*4))+rsi]
+ mov r10d,DWORD PTR[rsi]
or r12d,r11d
mov r11d,eax
add ecx,r12d
@@ -231,10 +231,10 @@ $L$loop::
rol ecx,14
add ecx,edx
not r11d
- lea ebx,DWORD PTR[0e9b6c7aah+r10*1+rbx]
+ lea ebx,DWORD PTR[((-373897302))+r10*1+rbx]
and r12d,ecx
and r11d,edx
- mov r10d,DWORD PTR[((5*4))+rsi]
+ mov r10d,DWORD PTR[20+rsi]
or r12d,r11d
mov r11d,edx
add ebx,r12d
@@ -242,10 +242,10 @@ $L$loop::
rol ebx,20
add ebx,ecx
not r11d
- lea eax,DWORD PTR[0d62f105dh+r10*1+rax]
+ lea eax,DWORD PTR[((-701558691))+r10*1+rax]
and r12d,ebx
and r11d,ecx
- mov r10d,DWORD PTR[((10*4))+rsi]
+ mov r10d,DWORD PTR[40+rsi]
or r12d,r11d
mov r11d,ecx
add eax,r12d
@@ -253,10 +253,10 @@ $L$loop::
rol eax,5
add eax,ebx
not r11d
- lea edx,DWORD PTR[02441453h+r10*1+rdx]
+ lea edx,DWORD PTR[38016083+r10*1+rdx]
and r12d,eax
and r11d,ebx
- mov r10d,DWORD PTR[((15*4))+rsi]
+ mov r10d,DWORD PTR[60+rsi]
or r12d,r11d
mov r11d,ebx
add edx,r12d
@@ -264,10 +264,10 @@ $L$loop::
rol edx,9
add edx,eax
not r11d
- lea ecx,DWORD PTR[0d8a1e681h+r10*1+rcx]
+ lea ecx,DWORD PTR[((-660478335))+r10*1+rcx]
and r12d,edx
and r11d,eax
- mov r10d,DWORD PTR[((4*4))+rsi]
+ mov r10d,DWORD PTR[16+rsi]
or r12d,r11d
mov r11d,eax
add ecx,r12d
@@ -275,10 +275,10 @@ $L$loop::
rol ecx,14
add ecx,edx
not r11d
- lea ebx,DWORD PTR[0e7d3fbc8h+r10*1+rbx]
+ lea ebx,DWORD PTR[((-405537848))+r10*1+rbx]
and r12d,ecx
and r11d,edx
- mov r10d,DWORD PTR[((9*4))+rsi]
+ mov r10d,DWORD PTR[36+rsi]
or r12d,r11d
mov r11d,edx
add ebx,r12d
@@ -286,10 +286,10 @@ $L$loop::
rol ebx,20
add ebx,ecx
not r11d
- lea eax,DWORD PTR[021e1cde6h+r10*1+rax]
+ lea eax,DWORD PTR[568446438+r10*1+rax]
and r12d,ebx
and r11d,ecx
- mov r10d,DWORD PTR[((14*4))+rsi]
+ mov r10d,DWORD PTR[56+rsi]
or r12d,r11d
mov r11d,ecx
add eax,r12d
@@ -297,10 +297,10 @@ $L$loop::
rol eax,5
add eax,ebx
not r11d
- lea edx,DWORD PTR[0c33707d6h+r10*1+rdx]
+ lea edx,DWORD PTR[((-1019803690))+r10*1+rdx]
and r12d,eax
and r11d,ebx
- mov r10d,DWORD PTR[((3*4))+rsi]
+ mov r10d,DWORD PTR[12+rsi]
or r12d,r11d
mov r11d,ebx
add edx,r12d
@@ -308,10 +308,10 @@ $L$loop::
rol edx,9
add edx,eax
not r11d
- lea ecx,DWORD PTR[0f4d50d87h+r10*1+rcx]
+ lea ecx,DWORD PTR[((-187363961))+r10*1+rcx]
and r12d,edx
and r11d,eax
- mov r10d,DWORD PTR[((8*4))+rsi]
+ mov r10d,DWORD PTR[32+rsi]
or r12d,r11d
mov r11d,eax
add ecx,r12d
@@ -319,10 +319,10 @@ $L$loop::
rol ecx,14
add ecx,edx
not r11d
- lea ebx,DWORD PTR[0455a14edh+r10*1+rbx]
+ lea ebx,DWORD PTR[1163531501+r10*1+rbx]
and r12d,ecx
and r11d,edx
- mov r10d,DWORD PTR[((13*4))+rsi]
+ mov r10d,DWORD PTR[52+rsi]
or r12d,r11d
mov r11d,edx
add ebx,r12d
@@ -330,10 +330,10 @@ $L$loop::
rol ebx,20
add ebx,ecx
not r11d
- lea eax,DWORD PTR[0a9e3e905h+r10*1+rax]
+ lea eax,DWORD PTR[((-1444681467))+r10*1+rax]
and r12d,ebx
and r11d,ecx
- mov r10d,DWORD PTR[((2*4))+rsi]
+ mov r10d,DWORD PTR[8+rsi]
or r12d,r11d
mov r11d,ecx
add eax,r12d
@@ -341,10 +341,10 @@ $L$loop::
rol eax,5
add eax,ebx
not r11d
- lea edx,DWORD PTR[0fcefa3f8h+r10*1+rdx]
+ lea edx,DWORD PTR[((-51403784))+r10*1+rdx]
and r12d,eax
and r11d,ebx
- mov r10d,DWORD PTR[((7*4))+rsi]
+ mov r10d,DWORD PTR[28+rsi]
or r12d,r11d
mov r11d,ebx
add edx,r12d
@@ -352,10 +352,10 @@ $L$loop::
rol edx,9
add edx,eax
not r11d
- lea ecx,DWORD PTR[0676f02d9h+r10*1+rcx]
+ lea ecx,DWORD PTR[1735328473+r10*1+rcx]
and r12d,edx
and r11d,eax
- mov r10d,DWORD PTR[((12*4))+rsi]
+ mov r10d,DWORD PTR[48+rsi]
or r12d,r11d
mov r11d,eax
add ecx,r12d
@@ -363,289 +363,289 @@ $L$loop::
rol ecx,14
add ecx,edx
not r11d
- lea ebx,DWORD PTR[08d2a4c8ah+r10*1+rbx]
+ lea ebx,DWORD PTR[((-1926607734))+r10*1+rbx]
and r12d,ecx
and r11d,edx
- mov r10d,DWORD PTR[((0*4))+rsi]
+ mov r10d,DWORD PTR[rsi]
or r12d,r11d
mov r11d,edx
add ebx,r12d
mov r12d,edx
rol ebx,20
add ebx,ecx
- mov r10d,DWORD PTR[((5*4))+rsi]
+ mov r10d,DWORD PTR[20+rsi]
mov r11d,ecx
- lea eax,DWORD PTR[0fffa3942h+r10*1+rax]
- mov r10d,DWORD PTR[((8*4))+rsi]
+ lea eax,DWORD PTR[((-378558))+r10*1+rax]
+ mov r10d,DWORD PTR[32+rsi]
xor r11d,edx
xor r11d,ebx
add eax,r11d
rol eax,4
mov r11d,ebx
add eax,ebx
- lea edx,DWORD PTR[08771f681h+r10*1+rdx]
- mov r10d,DWORD PTR[((11*4))+rsi]
+ lea edx,DWORD PTR[((-2022574463))+r10*1+rdx]
+ mov r10d,DWORD PTR[44+rsi]
xor r11d,ecx
xor r11d,eax
add edx,r11d
rol edx,11
mov r11d,eax
add edx,eax
- lea ecx,DWORD PTR[06d9d6122h+r10*1+rcx]
- mov r10d,DWORD PTR[((14*4))+rsi]
+ lea ecx,DWORD PTR[1839030562+r10*1+rcx]
+ mov r10d,DWORD PTR[56+rsi]
xor r11d,ebx
xor r11d,edx
add ecx,r11d
rol ecx,16
mov r11d,edx
add ecx,edx
- lea ebx,DWORD PTR[0fde5380ch+r10*1+rbx]
- mov r10d,DWORD PTR[((1*4))+rsi]
+ lea ebx,DWORD PTR[((-35309556))+r10*1+rbx]
+ mov r10d,DWORD PTR[4+rsi]
xor r11d,eax
xor r11d,ecx
add ebx,r11d
rol ebx,23
mov r11d,ecx
add ebx,ecx
- lea eax,DWORD PTR[0a4beea44h+r10*1+rax]
- mov r10d,DWORD PTR[((4*4))+rsi]
+ lea eax,DWORD PTR[((-1530992060))+r10*1+rax]
+ mov r10d,DWORD PTR[16+rsi]
xor r11d,edx
xor r11d,ebx
add eax,r11d
rol eax,4
mov r11d,ebx
add eax,ebx
- lea edx,DWORD PTR[04bdecfa9h+r10*1+rdx]
- mov r10d,DWORD PTR[((7*4))+rsi]
+ lea edx,DWORD PTR[1272893353+r10*1+rdx]
+ mov r10d,DWORD PTR[28+rsi]
xor r11d,ecx
xor r11d,eax
add edx,r11d
rol edx,11
mov r11d,eax
add edx,eax
- lea ecx,DWORD PTR[0f6bb4b60h+r10*1+rcx]
- mov r10d,DWORD PTR[((10*4))+rsi]
+ lea ecx,DWORD PTR[((-155497632))+r10*1+rcx]
+ mov r10d,DWORD PTR[40+rsi]
xor r11d,ebx
xor r11d,edx
add ecx,r11d
rol ecx,16
mov r11d,edx
add ecx,edx
- lea ebx,DWORD PTR[0bebfbc70h+r10*1+rbx]
- mov r10d,DWORD PTR[((13*4))+rsi]
+ lea ebx,DWORD PTR[((-1094730640))+r10*1+rbx]
+ mov r10d,DWORD PTR[52+rsi]
xor r11d,eax
xor r11d,ecx
add ebx,r11d
rol ebx,23
mov r11d,ecx
add ebx,ecx
- lea eax,DWORD PTR[0289b7ec6h+r10*1+rax]
- mov r10d,DWORD PTR[((0*4))+rsi]
+ lea eax,DWORD PTR[681279174+r10*1+rax]
+ mov r10d,DWORD PTR[rsi]
xor r11d,edx
xor r11d,ebx
add eax,r11d
rol eax,4
mov r11d,ebx
add eax,ebx
- lea edx,DWORD PTR[0eaa127fah+r10*1+rdx]
- mov r10d,DWORD PTR[((3*4))+rsi]
+ lea edx,DWORD PTR[((-358537222))+r10*1+rdx]
+ mov r10d,DWORD PTR[12+rsi]
xor r11d,ecx
xor r11d,eax
add edx,r11d
rol edx,11
mov r11d,eax
add edx,eax
- lea ecx,DWORD PTR[0d4ef3085h+r10*1+rcx]
- mov r10d,DWORD PTR[((6*4))+rsi]
+ lea ecx,DWORD PTR[((-722521979))+r10*1+rcx]
+ mov r10d,DWORD PTR[24+rsi]
xor r11d,ebx
xor r11d,edx
add ecx,r11d
rol ecx,16
mov r11d,edx
add ecx,edx
- lea ebx,DWORD PTR[04881d05h+r10*1+rbx]
- mov r10d,DWORD PTR[((9*4))+rsi]
+ lea ebx,DWORD PTR[76029189+r10*1+rbx]
+ mov r10d,DWORD PTR[36+rsi]
xor r11d,eax
xor r11d,ecx
add ebx,r11d
rol ebx,23
mov r11d,ecx
add ebx,ecx
- lea eax,DWORD PTR[0d9d4d039h+r10*1+rax]
- mov r10d,DWORD PTR[((12*4))+rsi]
+ lea eax,DWORD PTR[((-640364487))+r10*1+rax]
+ mov r10d,DWORD PTR[48+rsi]
xor r11d,edx
xor r11d,ebx
add eax,r11d
rol eax,4
mov r11d,ebx
add eax,ebx
- lea edx,DWORD PTR[0e6db99e5h+r10*1+rdx]
- mov r10d,DWORD PTR[((15*4))+rsi]
+ lea edx,DWORD PTR[((-421815835))+r10*1+rdx]
+ mov r10d,DWORD PTR[60+rsi]
xor r11d,ecx
xor r11d,eax
add edx,r11d
rol edx,11
mov r11d,eax
add edx,eax
- lea ecx,DWORD PTR[01fa27cf8h+r10*1+rcx]
- mov r10d,DWORD PTR[((2*4))+rsi]
+ lea ecx,DWORD PTR[530742520+r10*1+rcx]
+ mov r10d,DWORD PTR[8+rsi]
xor r11d,ebx
xor r11d,edx
add ecx,r11d
rol ecx,16
mov r11d,edx
add ecx,edx
- lea ebx,DWORD PTR[0c4ac5665h+r10*1+rbx]
- mov r10d,DWORD PTR[((0*4))+rsi]
+ lea ebx,DWORD PTR[((-995338651))+r10*1+rbx]
+ mov r10d,DWORD PTR[rsi]
xor r11d,eax
xor r11d,ecx
add ebx,r11d
rol ebx,23
mov r11d,ecx
add ebx,ecx
- mov r10d,DWORD PTR[((0*4))+rsi]
+ mov r10d,DWORD PTR[rsi]
mov r11d,0ffffffffh
xor r11d,edx
- lea eax,DWORD PTR[0f4292244h+r10*1+rax]
+ lea eax,DWORD PTR[((-198630844))+r10*1+rax]
or r11d,ebx
xor r11d,ecx
add eax,r11d
- mov r10d,DWORD PTR[((7*4))+rsi]
+ mov r10d,DWORD PTR[28+rsi]
mov r11d,0ffffffffh
rol eax,6
xor r11d,ecx
add eax,ebx
- lea edx,DWORD PTR[0432aff97h+r10*1+rdx]
+ lea edx,DWORD PTR[1126891415+r10*1+rdx]
or r11d,eax
xor r11d,ebx
add edx,r11d
- mov r10d,DWORD PTR[((14*4))+rsi]
+ mov r10d,DWORD PTR[56+rsi]
mov r11d,0ffffffffh
rol edx,10
xor r11d,ebx
add edx,eax
- lea ecx,DWORD PTR[0ab9423a7h+r10*1+rcx]
+ lea ecx,DWORD PTR[((-1416354905))+r10*1+rcx]
or r11d,edx
xor r11d,eax
add ecx,r11d
- mov r10d,DWORD PTR[((5*4))+rsi]
+ mov r10d,DWORD PTR[20+rsi]
mov r11d,0ffffffffh
rol ecx,15
xor r11d,eax
add ecx,edx
- lea ebx,DWORD PTR[0fc93a039h+r10*1+rbx]
+ lea ebx,DWORD PTR[((-57434055))+r10*1+rbx]
or r11d,ecx
xor r11d,edx
add ebx,r11d
- mov r10d,DWORD PTR[((12*4))+rsi]
+ mov r10d,DWORD PTR[48+rsi]
mov r11d,0ffffffffh
rol ebx,21
xor r11d,edx
add ebx,ecx
- lea eax,DWORD PTR[0655b59c3h+r10*1+rax]
+ lea eax,DWORD PTR[1700485571+r10*1+rax]
or r11d,ebx
xor r11d,ecx
add eax,r11d
- mov r10d,DWORD PTR[((3*4))+rsi]
+ mov r10d,DWORD PTR[12+rsi]
mov r11d,0ffffffffh
rol eax,6
xor r11d,ecx
add eax,ebx
- lea edx,DWORD PTR[08f0ccc92h+r10*1+rdx]
+ lea edx,DWORD PTR[((-1894986606))+r10*1+rdx]
or r11d,eax
xor r11d,ebx
add edx,r11d
- mov r10d,DWORD PTR[((10*4))+rsi]
+ mov r10d,DWORD PTR[40+rsi]
mov r11d,0ffffffffh
rol edx,10
xor r11d,ebx
add edx,eax
- lea ecx,DWORD PTR[0ffeff47dh+r10*1+rcx]
+ lea ecx,DWORD PTR[((-1051523))+r10*1+rcx]
or r11d,edx
xor r11d,eax
add ecx,r11d
- mov r10d,DWORD PTR[((1*4))+rsi]
+ mov r10d,DWORD PTR[4+rsi]
mov r11d,0ffffffffh
rol ecx,15
xor r11d,eax
add ecx,edx
- lea ebx,DWORD PTR[085845dd1h+r10*1+rbx]
+ lea ebx,DWORD PTR[((-2054922799))+r10*1+rbx]
or r11d,ecx
xor r11d,edx
add ebx,r11d
- mov r10d,DWORD PTR[((8*4))+rsi]
+ mov r10d,DWORD PTR[32+rsi]
mov r11d,0ffffffffh
rol ebx,21
xor r11d,edx
add ebx,ecx
- lea eax,DWORD PTR[06fa87e4fh+r10*1+rax]
+ lea eax,DWORD PTR[1873313359+r10*1+rax]
or r11d,ebx
xor r11d,ecx
add eax,r11d
- mov r10d,DWORD PTR[((15*4))+rsi]
+ mov r10d,DWORD PTR[60+rsi]
mov r11d,0ffffffffh
rol eax,6
xor r11d,ecx
add eax,ebx
- lea edx,DWORD PTR[0fe2ce6e0h+r10*1+rdx]
+ lea edx,DWORD PTR[((-30611744))+r10*1+rdx]
or r11d,eax
xor r11d,ebx
add edx,r11d
- mov r10d,DWORD PTR[((6*4))+rsi]
+ mov r10d,DWORD PTR[24+rsi]
mov r11d,0ffffffffh
rol edx,10
xor r11d,ebx
add edx,eax
- lea ecx,DWORD PTR[0a3014314h+r10*1+rcx]
+ lea ecx,DWORD PTR[((-1560198380))+r10*1+rcx]
or r11d,edx
xor r11d,eax
add ecx,r11d
- mov r10d,DWORD PTR[((13*4))+rsi]
+ mov r10d,DWORD PTR[52+rsi]
mov r11d,0ffffffffh
rol ecx,15
xor r11d,eax
add ecx,edx
- lea ebx,DWORD PTR[04e0811a1h+r10*1+rbx]
+ lea ebx,DWORD PTR[1309151649+r10*1+rbx]
or r11d,ecx
xor r11d,edx
add ebx,r11d
- mov r10d,DWORD PTR[((4*4))+rsi]
+ mov r10d,DWORD PTR[16+rsi]
mov r11d,0ffffffffh
rol ebx,21
xor r11d,edx
add ebx,ecx
- lea eax,DWORD PTR[0f7537e82h+r10*1+rax]
+ lea eax,DWORD PTR[((-145523070))+r10*1+rax]
or r11d,ebx
xor r11d,ecx
add eax,r11d
- mov r10d,DWORD PTR[((11*4))+rsi]
+ mov r10d,DWORD PTR[44+rsi]
mov r11d,0ffffffffh
rol eax,6
xor r11d,ecx
add eax,ebx
- lea edx,DWORD PTR[0bd3af235h+r10*1+rdx]
+ lea edx,DWORD PTR[((-1120210379))+r10*1+rdx]
or r11d,eax
xor r11d,ebx
add edx,r11d
- mov r10d,DWORD PTR[((2*4))+rsi]
+ mov r10d,DWORD PTR[8+rsi]
mov r11d,0ffffffffh
rol edx,10
xor r11d,ebx
add edx,eax
- lea ecx,DWORD PTR[02ad7d2bbh+r10*1+rcx]
+ lea ecx,DWORD PTR[718787259+r10*1+rcx]
or r11d,edx
xor r11d,eax
add ecx,r11d
- mov r10d,DWORD PTR[((9*4))+rsi]
+ mov r10d,DWORD PTR[36+rsi]
mov r11d,0ffffffffh
rol ecx,15
xor r11d,eax
add ecx,edx
- lea ebx,DWORD PTR[0eb86d391h+r10*1+rbx]
+ lea ebx,DWORD PTR[((-343485551))+r10*1+rbx]
or r11d,ecx
xor r11d,edx
add ebx,r11d
- mov r10d,DWORD PTR[((0*4))+rsi]
+ mov r10d,DWORD PTR[rsi]
mov r11d,0ffffffffh
rol ebx,21
xor r11d,edx
@@ -664,10 +664,10 @@ $L$loop::
$L$end::
- mov DWORD PTR[((0*4))+rbp],eax
- mov DWORD PTR[((1*4))+rbp],ebx
- mov DWORD PTR[((2*4))+rbp],ecx
- mov DWORD PTR[((3*4))+rbp],edx
+ mov DWORD PTR[rbp],eax
+ mov DWORD PTR[4+rbp],ebx
+ mov DWORD PTR[8+rbp],ecx
+ mov DWORD PTR[12+rbp],edx
mov r15,QWORD PTR[rsp]
mov r14,QWORD PTR[8+rsp]
diff --git a/deps/openssl/asm/x64-win32-masm/rc4/rc4-md5-x86_64.asm b/deps/openssl/asm/x64-win32-masm/rc4/rc4-md5-x86_64.asm
new file mode 100644
index 000000000..4af838e3e
--- /dev/null
+++ b/deps/openssl/asm/x64-win32-masm/rc4/rc4-md5-x86_64.asm
@@ -0,0 +1,1375 @@
+OPTION DOTNAME
+.text$ SEGMENT ALIGN(64) 'CODE'
+ALIGN 16
+
+PUBLIC rc4_md5_enc
+
+rc4_md5_enc PROC PUBLIC
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_rc4_md5_enc::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD PTR[40+rsp]
+ mov r9,QWORD PTR[48+rsp]
+
+
+ cmp r9,0
+ je $L$abort
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ sub rsp,40
+$L$body::
+ mov r11,rcx
+ mov r12,r9
+ mov r13,rsi
+ mov r14,rdx
+ mov r15,r8
+ xor rbp,rbp
+ xor rcx,rcx
+
+ lea rdi,QWORD PTR[8+rdi]
+ mov bpl,BYTE PTR[((-8))+rdi]
+ mov cl,BYTE PTR[((-4))+rdi]
+
+ inc bpl
+ sub r14,r13
+ mov eax,DWORD PTR[rbp*4+rdi]
+ add cl,al
+ lea rsi,QWORD PTR[rbp*4+rdi]
+ shl r12,6
+ add r12,r15
+ mov QWORD PTR[16+rsp],r12
+
+ mov QWORD PTR[24+rsp],r11
+ mov r8d,DWORD PTR[r11]
+ mov r9d,DWORD PTR[4+r11]
+ mov r10d,DWORD PTR[8+r11]
+ mov r11d,DWORD PTR[12+r11]
+ jmp $L$oop
+
+ALIGN 16
+$L$oop::
+ mov DWORD PTR[rsp],r8d
+ mov DWORD PTR[4+rsp],r9d
+ mov DWORD PTR[8+rsp],r10d
+ mov r12d,r11d
+ mov DWORD PTR[12+rsp],r11d
+ pxor xmm0,xmm0
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r9d
+ add r8d,DWORD PTR[r15]
+ add al,dl
+ mov ebx,DWORD PTR[4+rsi]
+ add r8d,3614090360
+ xor r12d,r11d
+ movzx eax,al
+ mov DWORD PTR[rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,7
+ mov r12d,r10d
+ movd xmm0,DWORD PTR[rax*4+rdi]
+
+ add r8d,r9d
+ pxor xmm1,xmm1
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r8d
+ add r11d,DWORD PTR[4+r15]
+ add bl,dl
+ mov eax,DWORD PTR[8+rsi]
+ add r11d,3905402710
+ xor r12d,r10d
+ movzx ebx,bl
+ mov DWORD PTR[4+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,12
+ mov r12d,r9d
+ movd xmm1,DWORD PTR[rbx*4+rdi]
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r11d
+ add r10d,DWORD PTR[8+r15]
+ add al,dl
+ mov ebx,DWORD PTR[12+rsi]
+ add r10d,606105819
+ xor r12d,r9d
+ movzx eax,al
+ mov DWORD PTR[8+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,17
+ mov r12d,r8d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],1
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r10d
+ add r9d,DWORD PTR[12+r15]
+ add bl,dl
+ mov eax,DWORD PTR[16+rsi]
+ add r9d,3250441966
+ xor r12d,r8d
+ movzx ebx,bl
+ mov DWORD PTR[12+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,22
+ mov r12d,r11d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],1
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r9d
+ add r8d,DWORD PTR[16+r15]
+ add al,dl
+ mov ebx,DWORD PTR[20+rsi]
+ add r8d,4118548399
+ xor r12d,r11d
+ movzx eax,al
+ mov DWORD PTR[16+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,7
+ mov r12d,r10d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],2
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r8d
+ add r11d,DWORD PTR[20+r15]
+ add bl,dl
+ mov eax,DWORD PTR[24+rsi]
+ add r11d,1200080426
+ xor r12d,r10d
+ movzx ebx,bl
+ mov DWORD PTR[20+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,12
+ mov r12d,r9d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],2
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r11d
+ add r10d,DWORD PTR[24+r15]
+ add al,dl
+ mov ebx,DWORD PTR[28+rsi]
+ add r10d,2821735955
+ xor r12d,r9d
+ movzx eax,al
+ mov DWORD PTR[24+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,17
+ mov r12d,r8d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],3
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r10d
+ add r9d,DWORD PTR[28+r15]
+ add bl,dl
+ mov eax,DWORD PTR[32+rsi]
+ add r9d,4249261313
+ xor r12d,r8d
+ movzx ebx,bl
+ mov DWORD PTR[28+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,22
+ mov r12d,r11d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],3
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r9d
+ add r8d,DWORD PTR[32+r15]
+ add al,dl
+ mov ebx,DWORD PTR[36+rsi]
+ add r8d,1770035416
+ xor r12d,r11d
+ movzx eax,al
+ mov DWORD PTR[32+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,7
+ mov r12d,r10d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],4
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r8d
+ add r11d,DWORD PTR[36+r15]
+ add bl,dl
+ mov eax,DWORD PTR[40+rsi]
+ add r11d,2336552879
+ xor r12d,r10d
+ movzx ebx,bl
+ mov DWORD PTR[36+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,12
+ mov r12d,r9d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],4
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r11d
+ add r10d,DWORD PTR[40+r15]
+ add al,dl
+ mov ebx,DWORD PTR[44+rsi]
+ add r10d,4294925233
+ xor r12d,r9d
+ movzx eax,al
+ mov DWORD PTR[40+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,17
+ mov r12d,r8d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],5
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r10d
+ add r9d,DWORD PTR[44+r15]
+ add bl,dl
+ mov eax,DWORD PTR[48+rsi]
+ add r9d,2304563134
+ xor r12d,r8d
+ movzx ebx,bl
+ mov DWORD PTR[44+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,22
+ mov r12d,r11d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],5
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r9d
+ add r8d,DWORD PTR[48+r15]
+ add al,dl
+ mov ebx,DWORD PTR[52+rsi]
+ add r8d,1804603682
+ xor r12d,r11d
+ movzx eax,al
+ mov DWORD PTR[48+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,7
+ mov r12d,r10d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],6
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r8d
+ add r11d,DWORD PTR[52+r15]
+ add bl,dl
+ mov eax,DWORD PTR[56+rsi]
+ add r11d,4254626195
+ xor r12d,r10d
+ movzx ebx,bl
+ mov DWORD PTR[52+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,12
+ mov r12d,r9d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],6
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r11d
+ add r10d,DWORD PTR[56+r15]
+ add al,dl
+ mov ebx,DWORD PTR[60+rsi]
+ add r10d,2792965006
+ xor r12d,r9d
+ movzx eax,al
+ mov DWORD PTR[56+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,17
+ mov r12d,r8d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],7
+
+ add r10d,r11d
+ movdqu xmm2,XMMWORD PTR[r13]
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r10d
+ add r9d,DWORD PTR[60+r15]
+ add bl,dl
+ mov eax,DWORD PTR[64+rsi]
+ add r9d,1236535329
+ xor r12d,r8d
+ movzx ebx,bl
+ mov DWORD PTR[60+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,22
+ mov r12d,r10d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],7
+
+ add r9d,r10d
+ psllq xmm1,8
+ pxor xmm2,xmm0
+ pxor xmm2,xmm1
+ pxor xmm0,xmm0
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r11d
+ add r8d,DWORD PTR[4+r15]
+ add al,dl
+ mov ebx,DWORD PTR[68+rsi]
+ add r8d,4129170786
+ xor r12d,r10d
+ movzx eax,al
+ mov DWORD PTR[64+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,5
+ mov r12d,r9d
+ movd xmm0,DWORD PTR[rax*4+rdi]
+
+ add r8d,r9d
+ pxor xmm1,xmm1
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r10d
+ add r11d,DWORD PTR[24+r15]
+ add bl,dl
+ mov eax,DWORD PTR[72+rsi]
+ add r11d,3225465664
+ xor r12d,r9d
+ movzx ebx,bl
+ mov DWORD PTR[68+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,9
+ mov r12d,r8d
+ movd xmm1,DWORD PTR[rbx*4+rdi]
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r9d
+ add r10d,DWORD PTR[44+r15]
+ add al,dl
+ mov ebx,DWORD PTR[76+rsi]
+ add r10d,643717713
+ xor r12d,r8d
+ movzx eax,al
+ mov DWORD PTR[72+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,14
+ mov r12d,r11d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],1
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r8d
+ add r9d,DWORD PTR[r15]
+ add bl,dl
+ mov eax,DWORD PTR[80+rsi]
+ add r9d,3921069994
+ xor r12d,r11d
+ movzx ebx,bl
+ mov DWORD PTR[76+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,20
+ mov r12d,r10d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],1
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r11d
+ add r8d,DWORD PTR[20+r15]
+ add al,dl
+ mov ebx,DWORD PTR[84+rsi]
+ add r8d,3593408605
+ xor r12d,r10d
+ movzx eax,al
+ mov DWORD PTR[80+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,5
+ mov r12d,r9d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],2
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r10d
+ add r11d,DWORD PTR[40+r15]
+ add bl,dl
+ mov eax,DWORD PTR[88+rsi]
+ add r11d,38016083
+ xor r12d,r9d
+ movzx ebx,bl
+ mov DWORD PTR[84+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,9
+ mov r12d,r8d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],2
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r9d
+ add r10d,DWORD PTR[60+r15]
+ add al,dl
+ mov ebx,DWORD PTR[92+rsi]
+ add r10d,3634488961
+ xor r12d,r8d
+ movzx eax,al
+ mov DWORD PTR[88+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,14
+ mov r12d,r11d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],3
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r8d
+ add r9d,DWORD PTR[16+r15]
+ add bl,dl
+ mov eax,DWORD PTR[96+rsi]
+ add r9d,3889429448
+ xor r12d,r11d
+ movzx ebx,bl
+ mov DWORD PTR[92+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,20
+ mov r12d,r10d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],3
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r11d
+ add r8d,DWORD PTR[36+r15]
+ add al,dl
+ mov ebx,DWORD PTR[100+rsi]
+ add r8d,568446438
+ xor r12d,r10d
+ movzx eax,al
+ mov DWORD PTR[96+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,5
+ mov r12d,r9d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],4
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r10d
+ add r11d,DWORD PTR[56+r15]
+ add bl,dl
+ mov eax,DWORD PTR[104+rsi]
+ add r11d,3275163606
+ xor r12d,r9d
+ movzx ebx,bl
+ mov DWORD PTR[100+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,9
+ mov r12d,r8d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],4
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r9d
+ add r10d,DWORD PTR[12+r15]
+ add al,dl
+ mov ebx,DWORD PTR[108+rsi]
+ add r10d,4107603335
+ xor r12d,r8d
+ movzx eax,al
+ mov DWORD PTR[104+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,14
+ mov r12d,r11d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],5
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r8d
+ add r9d,DWORD PTR[32+r15]
+ add bl,dl
+ mov eax,DWORD PTR[112+rsi]
+ add r9d,1163531501
+ xor r12d,r11d
+ movzx ebx,bl
+ mov DWORD PTR[108+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,20
+ mov r12d,r10d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],5
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r11d
+ add r8d,DWORD PTR[52+r15]
+ add al,dl
+ mov ebx,DWORD PTR[116+rsi]
+ add r8d,2850285829
+ xor r12d,r10d
+ movzx eax,al
+ mov DWORD PTR[112+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,5
+ mov r12d,r9d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],6
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r10d
+ add r11d,DWORD PTR[8+r15]
+ add bl,dl
+ mov eax,DWORD PTR[120+rsi]
+ add r11d,4243563512
+ xor r12d,r9d
+ movzx ebx,bl
+ mov DWORD PTR[116+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,9
+ mov r12d,r8d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],6
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],eax
+ and r12d,r9d
+ add r10d,DWORD PTR[28+r15]
+ add al,dl
+ mov ebx,DWORD PTR[124+rsi]
+ add r10d,1735328473
+ xor r12d,r8d
+ movzx eax,al
+ mov DWORD PTR[120+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,14
+ mov r12d,r11d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],7
+
+ add r10d,r11d
+ movdqu xmm3,XMMWORD PTR[16+r13]
+ add bpl,32
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ and r12d,r8d
+ add r9d,DWORD PTR[48+r15]
+ add bl,dl
+ mov eax,DWORD PTR[rbp*4+rdi]
+ add r9d,2368359562
+ xor r12d,r11d
+ movzx ebx,bl
+ mov DWORD PTR[124+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,20
+ mov r12d,r11d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],7
+
+ add r9d,r10d
+ mov rsi,rcx
+ xor rcx,rcx
+ mov cl,sil
+ lea rsi,QWORD PTR[rbp*4+rdi]
+ psllq xmm1,8
+ pxor xmm3,xmm0
+ pxor xmm3,xmm1
+ pxor xmm0,xmm0
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],eax
+ xor r12d,r9d
+ add r8d,DWORD PTR[20+r15]
+ add al,dl
+ mov ebx,DWORD PTR[4+rsi]
+ add r8d,4294588738
+ movzx eax,al
+ add r8d,r12d
+ mov DWORD PTR[rsi],edx
+ add cl,bl
+ rol r8d,4
+ mov r12d,r10d
+ movd xmm0,DWORD PTR[rax*4+rdi]
+
+ add r8d,r9d
+ pxor xmm1,xmm1
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ xor r12d,r8d
+ add r11d,DWORD PTR[32+r15]
+ add bl,dl
+ mov eax,DWORD PTR[8+rsi]
+ add r11d,2272392833
+ movzx ebx,bl
+ add r11d,r12d
+ mov DWORD PTR[4+rsi],edx
+ add cl,al
+ rol r11d,11
+ mov r12d,r9d
+ movd xmm1,DWORD PTR[rbx*4+rdi]
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],eax
+ xor r12d,r11d
+ add r10d,DWORD PTR[44+r15]
+ add al,dl
+ mov ebx,DWORD PTR[12+rsi]
+ add r10d,1839030562
+ movzx eax,al
+ add r10d,r12d
+ mov DWORD PTR[8+rsi],edx
+ add cl,bl
+ rol r10d,16
+ mov r12d,r8d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],1
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ xor r12d,r10d
+ add r9d,DWORD PTR[56+r15]
+ add bl,dl
+ mov eax,DWORD PTR[16+rsi]
+ add r9d,4259657740
+ movzx ebx,bl
+ add r9d,r12d
+ mov DWORD PTR[12+rsi],edx
+ add cl,al
+ rol r9d,23
+ mov r12d,r11d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],1
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],eax
+ xor r12d,r9d
+ add r8d,DWORD PTR[4+r15]
+ add al,dl
+ mov ebx,DWORD PTR[20+rsi]
+ add r8d,2763975236
+ movzx eax,al
+ add r8d,r12d
+ mov DWORD PTR[16+rsi],edx
+ add cl,bl
+ rol r8d,4
+ mov r12d,r10d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],2
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ xor r12d,r8d
+ add r11d,DWORD PTR[16+r15]
+ add bl,dl
+ mov eax,DWORD PTR[24+rsi]
+ add r11d,1272893353
+ movzx ebx,bl
+ add r11d,r12d
+ mov DWORD PTR[20+rsi],edx
+ add cl,al
+ rol r11d,11
+ mov r12d,r9d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],2
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],eax
+ xor r12d,r11d
+ add r10d,DWORD PTR[28+r15]
+ add al,dl
+ mov ebx,DWORD PTR[28+rsi]
+ add r10d,4139469664
+ movzx eax,al
+ add r10d,r12d
+ mov DWORD PTR[24+rsi],edx
+ add cl,bl
+ rol r10d,16
+ mov r12d,r8d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],3
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ xor r12d,r10d
+ add r9d,DWORD PTR[40+r15]
+ add bl,dl
+ mov eax,DWORD PTR[32+rsi]
+ add r9d,3200236656
+ movzx ebx,bl
+ add r9d,r12d
+ mov DWORD PTR[28+rsi],edx
+ add cl,al
+ rol r9d,23
+ mov r12d,r11d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],3
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],eax
+ xor r12d,r9d
+ add r8d,DWORD PTR[52+r15]
+ add al,dl
+ mov ebx,DWORD PTR[36+rsi]
+ add r8d,681279174
+ movzx eax,al
+ add r8d,r12d
+ mov DWORD PTR[32+rsi],edx
+ add cl,bl
+ rol r8d,4
+ mov r12d,r10d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],4
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ xor r12d,r8d
+ add r11d,DWORD PTR[r15]
+ add bl,dl
+ mov eax,DWORD PTR[40+rsi]
+ add r11d,3936430074
+ movzx ebx,bl
+ add r11d,r12d
+ mov DWORD PTR[36+rsi],edx
+ add cl,al
+ rol r11d,11
+ mov r12d,r9d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],4
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],eax
+ xor r12d,r11d
+ add r10d,DWORD PTR[12+r15]
+ add al,dl
+ mov ebx,DWORD PTR[44+rsi]
+ add r10d,3572445317
+ movzx eax,al
+ add r10d,r12d
+ mov DWORD PTR[40+rsi],edx
+ add cl,bl
+ rol r10d,16
+ mov r12d,r8d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],5
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ xor r12d,r10d
+ add r9d,DWORD PTR[24+r15]
+ add bl,dl
+ mov eax,DWORD PTR[48+rsi]
+ add r9d,76029189
+ movzx ebx,bl
+ add r9d,r12d
+ mov DWORD PTR[44+rsi],edx
+ add cl,al
+ rol r9d,23
+ mov r12d,r11d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],5
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],eax
+ xor r12d,r9d
+ add r8d,DWORD PTR[36+r15]
+ add al,dl
+ mov ebx,DWORD PTR[52+rsi]
+ add r8d,3654602809
+ movzx eax,al
+ add r8d,r12d
+ mov DWORD PTR[48+rsi],edx
+ add cl,bl
+ rol r8d,4
+ mov r12d,r10d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],6
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ xor r12d,r8d
+ add r11d,DWORD PTR[48+r15]
+ add bl,dl
+ mov eax,DWORD PTR[56+rsi]
+ add r11d,3873151461
+ movzx ebx,bl
+ add r11d,r12d
+ mov DWORD PTR[52+rsi],edx
+ add cl,al
+ rol r11d,11
+ mov r12d,r9d
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],6
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],eax
+ xor r12d,r11d
+ add r10d,DWORD PTR[60+r15]
+ add al,dl
+ mov ebx,DWORD PTR[60+rsi]
+ add r10d,530742520
+ movzx eax,al
+ add r10d,r12d
+ mov DWORD PTR[56+rsi],edx
+ add cl,bl
+ rol r10d,16
+ mov r12d,r8d
+ pinsrw xmm0,WORD PTR[rax*4+rdi],7
+
+ add r10d,r11d
+ movdqu xmm4,XMMWORD PTR[32+r13]
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ xor r12d,r10d
+ add r9d,DWORD PTR[8+r15]
+ add bl,dl
+ mov eax,DWORD PTR[64+rsi]
+ add r9d,3299628645
+ movzx ebx,bl
+ add r9d,r12d
+ mov DWORD PTR[60+rsi],edx
+ add cl,al
+ rol r9d,23
+ mov r12d,-1
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],7
+
+ add r9d,r10d
+ psllq xmm1,8
+ pxor xmm4,xmm0
+ pxor xmm4,xmm1
+ pxor xmm0,xmm0
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],eax
+ or r12d,r9d
+ add r8d,DWORD PTR[r15]
+ add al,dl
+ mov ebx,DWORD PTR[68+rsi]
+ add r8d,4096336452
+ movzx eax,al
+ xor r12d,r10d
+ mov DWORD PTR[64+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,6
+ mov r12d,-1
+ movd xmm0,DWORD PTR[rax*4+rdi]
+
+ add r8d,r9d
+ pxor xmm1,xmm1
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ or r12d,r8d
+ add r11d,DWORD PTR[28+r15]
+ add bl,dl
+ mov eax,DWORD PTR[72+rsi]
+ add r11d,1126891415
+ movzx ebx,bl
+ xor r12d,r9d
+ mov DWORD PTR[68+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,10
+ mov r12d,-1
+ movd xmm1,DWORD PTR[rbx*4+rdi]
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],eax
+ or r12d,r11d
+ add r10d,DWORD PTR[56+r15]
+ add al,dl
+ mov ebx,DWORD PTR[76+rsi]
+ add r10d,2878612391
+ movzx eax,al
+ xor r12d,r8d
+ mov DWORD PTR[72+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,15
+ mov r12d,-1
+ pinsrw xmm0,WORD PTR[rax*4+rdi],1
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ or r12d,r10d
+ add r9d,DWORD PTR[20+r15]
+ add bl,dl
+ mov eax,DWORD PTR[80+rsi]
+ add r9d,4237533241
+ movzx ebx,bl
+ xor r12d,r11d
+ mov DWORD PTR[76+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,21
+ mov r12d,-1
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],1
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],eax
+ or r12d,r9d
+ add r8d,DWORD PTR[48+r15]
+ add al,dl
+ mov ebx,DWORD PTR[84+rsi]
+ add r8d,1700485571
+ movzx eax,al
+ xor r12d,r10d
+ mov DWORD PTR[80+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,6
+ mov r12d,-1
+ pinsrw xmm0,WORD PTR[rax*4+rdi],2
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ or r12d,r8d
+ add r11d,DWORD PTR[12+r15]
+ add bl,dl
+ mov eax,DWORD PTR[88+rsi]
+ add r11d,2399980690
+ movzx ebx,bl
+ xor r12d,r9d
+ mov DWORD PTR[84+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,10
+ mov r12d,-1
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],2
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],eax
+ or r12d,r11d
+ add r10d,DWORD PTR[40+r15]
+ add al,dl
+ mov ebx,DWORD PTR[92+rsi]
+ add r10d,4293915773
+ movzx eax,al
+ xor r12d,r8d
+ mov DWORD PTR[88+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,15
+ mov r12d,-1
+ pinsrw xmm0,WORD PTR[rax*4+rdi],3
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ or r12d,r10d
+ add r9d,DWORD PTR[4+r15]
+ add bl,dl
+ mov eax,DWORD PTR[96+rsi]
+ add r9d,2240044497
+ movzx ebx,bl
+ xor r12d,r11d
+ mov DWORD PTR[92+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,21
+ mov r12d,-1
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],3
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],eax
+ or r12d,r9d
+ add r8d,DWORD PTR[32+r15]
+ add al,dl
+ mov ebx,DWORD PTR[100+rsi]
+ add r8d,1873313359
+ movzx eax,al
+ xor r12d,r10d
+ mov DWORD PTR[96+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,6
+ mov r12d,-1
+ pinsrw xmm0,WORD PTR[rax*4+rdi],4
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ or r12d,r8d
+ add r11d,DWORD PTR[60+r15]
+ add bl,dl
+ mov eax,DWORD PTR[104+rsi]
+ add r11d,4264355552
+ movzx ebx,bl
+ xor r12d,r9d
+ mov DWORD PTR[100+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,10
+ mov r12d,-1
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],4
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],eax
+ or r12d,r11d
+ add r10d,DWORD PTR[24+r15]
+ add al,dl
+ mov ebx,DWORD PTR[108+rsi]
+ add r10d,2734768916
+ movzx eax,al
+ xor r12d,r8d
+ mov DWORD PTR[104+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,15
+ mov r12d,-1
+ pinsrw xmm0,WORD PTR[rax*4+rdi],5
+
+ add r10d,r11d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ or r12d,r10d
+ add r9d,DWORD PTR[52+r15]
+ add bl,dl
+ mov eax,DWORD PTR[112+rsi]
+ add r9d,1309151649
+ movzx ebx,bl
+ xor r12d,r11d
+ mov DWORD PTR[108+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,21
+ mov r12d,-1
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],5
+
+ add r9d,r10d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r11d
+ mov DWORD PTR[rcx*4+rdi],eax
+ or r12d,r9d
+ add r8d,DWORD PTR[16+r15]
+ add al,dl
+ mov ebx,DWORD PTR[116+rsi]
+ add r8d,4149444226
+ movzx eax,al
+ xor r12d,r10d
+ mov DWORD PTR[112+rsi],edx
+ add r8d,r12d
+ add cl,bl
+ rol r8d,6
+ mov r12d,-1
+ pinsrw xmm0,WORD PTR[rax*4+rdi],6
+
+ add r8d,r9d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r10d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ or r12d,r8d
+ add r11d,DWORD PTR[44+r15]
+ add bl,dl
+ mov eax,DWORD PTR[120+rsi]
+ add r11d,3174756917
+ movzx ebx,bl
+ xor r12d,r9d
+ mov DWORD PTR[116+rsi],edx
+ add r11d,r12d
+ add cl,al
+ rol r11d,10
+ mov r12d,-1
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],6
+
+ add r11d,r8d
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r9d
+ mov DWORD PTR[rcx*4+rdi],eax
+ or r12d,r11d
+ add r10d,DWORD PTR[8+r15]
+ add al,dl
+ mov ebx,DWORD PTR[124+rsi]
+ add r10d,718787259
+ movzx eax,al
+ xor r12d,r8d
+ mov DWORD PTR[120+rsi],edx
+ add r10d,r12d
+ add cl,bl
+ rol r10d,15
+ mov r12d,-1
+ pinsrw xmm0,WORD PTR[rax*4+rdi],7
+
+ add r10d,r11d
+ movdqu xmm5,XMMWORD PTR[48+r13]
+ add bpl,32
+ mov edx,DWORD PTR[rcx*4+rdi]
+ xor r12d,r8d
+ mov DWORD PTR[rcx*4+rdi],ebx
+ or r12d,r10d
+ add r9d,DWORD PTR[36+r15]
+ add bl,dl
+ mov eax,DWORD PTR[rbp*4+rdi]
+ add r9d,3951481745
+ movzx ebx,bl
+ xor r12d,r11d
+ mov DWORD PTR[124+rsi],edx
+ add r9d,r12d
+ add cl,al
+ rol r9d,21
+ mov r12d,-1
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],7
+
+ add r9d,r10d
+ mov rsi,rbp
+ xor rbp,rbp
+ mov bpl,sil
+ mov rsi,rcx
+ xor rcx,rcx
+ mov cl,sil
+ lea rsi,QWORD PTR[rbp*4+rdi]
+ psllq xmm1,8
+ pxor xmm5,xmm0
+ pxor xmm5,xmm1
+ add r8d,DWORD PTR[rsp]
+ add r9d,DWORD PTR[4+rsp]
+ add r10d,DWORD PTR[8+rsp]
+ add r11d,DWORD PTR[12+rsp]
+
+ movdqu XMMWORD PTR[r13*1+r14],xmm2
+ movdqu XMMWORD PTR[16+r13*1+r14],xmm3
+ movdqu XMMWORD PTR[32+r13*1+r14],xmm4
+ movdqu XMMWORD PTR[48+r13*1+r14],xmm5
+ lea r15,QWORD PTR[64+r15]
+ lea r13,QWORD PTR[64+r13]
+ cmp r15,QWORD PTR[16+rsp]
+ jb $L$oop
+
+ mov r12,QWORD PTR[24+rsp]
+ sub cl,al
+ mov DWORD PTR[r12],r8d
+ mov DWORD PTR[4+r12],r9d
+ mov DWORD PTR[8+r12],r10d
+ mov DWORD PTR[12+r12],r11d
+ sub bpl,1
+ mov DWORD PTR[((-8))+rdi],ebp
+ mov DWORD PTR[((-4))+rdi],ecx
+
+ mov r15,QWORD PTR[40+rsp]
+ mov r14,QWORD PTR[48+rsp]
+ mov r13,QWORD PTR[56+rsp]
+ mov r12,QWORD PTR[64+rsp]
+ mov rbp,QWORD PTR[72+rsp]
+ mov rbx,QWORD PTR[80+rsp]
+ lea rsp,QWORD PTR[88+rsp]
+$L$epilogue::
+$L$abort::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_rc4_md5_enc::
+rc4_md5_enc ENDP
+EXTERN __imp_RtlVirtualUnwind:NEAR
+
+ALIGN 16
+se_handler PROC PRIVATE
+ push rsi
+ push rdi
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq
+ sub rsp,64
+
+ mov rax,QWORD PTR[120+r8]
+ mov rbx,QWORD PTR[248+r8]
+
+ lea r10,QWORD PTR[$L$body]
+ cmp rbx,r10
+ jb $L$in_prologue
+
+ mov rax,QWORD PTR[152+r8]
+
+ lea r10,QWORD PTR[$L$epilogue]
+ cmp rbx,r10
+ jae $L$in_prologue
+
+ mov r15,QWORD PTR[40+rax]
+ mov r14,QWORD PTR[48+rax]
+ mov r13,QWORD PTR[56+rax]
+ mov r12,QWORD PTR[64+rax]
+ mov rbp,QWORD PTR[72+rax]
+ mov rbx,QWORD PTR[80+rax]
+ lea rax,QWORD PTR[88+rax]
+
+ mov QWORD PTR[144+r8],rbx
+ mov QWORD PTR[160+r8],rbp
+ mov QWORD PTR[216+r8],r12
+ mov QWORD PTR[224+r8],r13
+ mov QWORD PTR[232+r8],r14
+ mov QWORD PTR[240+r8],r15
+
+$L$in_prologue::
+ mov rdi,QWORD PTR[8+rax]
+ mov rsi,QWORD PTR[16+rax]
+ mov QWORD PTR[152+r8],rax
+ mov QWORD PTR[168+r8],rsi
+ mov QWORD PTR[176+r8],rdi
+
+ mov rdi,QWORD PTR[40+r9]
+ mov rsi,r8
+ mov ecx,154
+ DD 0a548f3fch
+
+
+ mov rsi,r9
+ xor rcx,rcx
+ mov rdx,QWORD PTR[8+rsi]
+ mov r8,QWORD PTR[rsi]
+ mov r9,QWORD PTR[16+rsi]
+ mov r10,QWORD PTR[40+rsi]
+ lea r11,QWORD PTR[56+rsi]
+ lea r12,QWORD PTR[24+rsi]
+ mov QWORD PTR[32+rsp],r10
+ mov QWORD PTR[40+rsp],r11
+ mov QWORD PTR[48+rsp],r12
+ mov QWORD PTR[56+rsp],rcx
+ call QWORD PTR[__imp_RtlVirtualUnwind]
+
+ mov eax,1
+ add rsp,64
+ popfq
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbp
+ pop rbx
+ pop rdi
+ pop rsi
+ DB 0F3h,0C3h ;repret
+se_handler ENDP
+
+.text$ ENDS
+.pdata SEGMENT READONLY ALIGN(4)
+ALIGN 4
+ DD imagerel $L$SEH_begin_rc4_md5_enc
+ DD imagerel $L$SEH_end_rc4_md5_enc
+ DD imagerel $L$SEH_info_rc4_md5_enc
+
+.pdata ENDS
+.xdata SEGMENT READONLY ALIGN(8)
+ALIGN 8
+$L$SEH_info_rc4_md5_enc::
+DB 9,0,0,0
+ DD imagerel se_handler
+
+.xdata ENDS
+END
diff --git a/deps/openssl/asm/x64-win32-masm/rc4/rc4-x86_64.asm b/deps/openssl/asm/x64-win32-masm/rc4/rc4-x86_64.asm
index f508fa667..aea304fba 100644
--- a/deps/openssl/asm/x64-win32-masm/rc4/rc4-x86_64.asm
+++ b/deps/openssl/asm/x64-win32-masm/rc4/rc4-x86_64.asm
@@ -1,5 +1,6 @@
OPTION DOTNAME
.text$ SEGMENT ALIGN(64) 'CODE'
+EXTERN OPENSSL_ia32cap_P:NEAR
PUBLIC RC4
@@ -24,316 +25,511 @@ $L$entry::
push r12
push r13
$L$prologue::
+ mov r11,rsi
+ mov r12,rdx
+ mov r13,rcx
+ xor r10,r10
+ xor rcx,rcx
- add rdi,8
- mov r8d,DWORD PTR[((-8))+rdi]
- mov r12d,DWORD PTR[((-4))+rdi]
+ lea rdi,QWORD PTR[8+rdi]
+ mov r10b,BYTE PTR[((-8))+rdi]
+ mov cl,BYTE PTR[((-4))+rdi]
cmp DWORD PTR[256+rdi],-1
je $L$RC4_CHAR
- inc r8b
- mov r9d,DWORD PTR[r8*4+rdi]
- test rsi,-8
- jz $L$loop1
- jmp $L$loop8
-ALIGN 16
-$L$loop8::
- add r12b,r9b
- mov r10,r8
- mov r13d,DWORD PTR[r12*4+rdi]
- ror rax,8
- inc r10b
- mov r11d,DWORD PTR[r10*4+rdi]
- cmp r12,r10
- mov DWORD PTR[r12*4+rdi],r9d
- cmove r11,r9
- mov DWORD PTR[r8*4+rdi],r13d
- add r13b,r9b
- mov al,BYTE PTR[r13*4+rdi]
- add r12b,r11b
- mov r8,r10
- mov r13d,DWORD PTR[r12*4+rdi]
- ror rax,8
- inc r8b
- mov r9d,DWORD PTR[r8*4+rdi]
- cmp r12,r8
- mov DWORD PTR[r12*4+rdi],r11d
- cmove r9,r11
- mov DWORD PTR[r10*4+rdi],r13d
- add r13b,r11b
- mov al,BYTE PTR[r13*4+rdi]
- add r12b,r9b
- mov r10,r8
- mov r13d,DWORD PTR[r12*4+rdi]
- ror rax,8
+ mov r8d,DWORD PTR[OPENSSL_ia32cap_P]
+ xor rbx,rbx
inc r10b
- mov r11d,DWORD PTR[r10*4+rdi]
- cmp r12,r10
- mov DWORD PTR[r12*4+rdi],r9d
- cmove r11,r9
- mov DWORD PTR[r8*4+rdi],r13d
- add r13b,r9b
- mov al,BYTE PTR[r13*4+rdi]
- add r12b,r11b
- mov r8,r10
- mov r13d,DWORD PTR[r12*4+rdi]
- ror rax,8
- inc r8b
- mov r9d,DWORD PTR[r8*4+rdi]
- cmp r12,r8
- mov DWORD PTR[r12*4+rdi],r11d
- cmove r9,r11
- mov DWORD PTR[r10*4+rdi],r13d
- add r13b,r11b
- mov al,BYTE PTR[r13*4+rdi]
- add r12b,r9b
- mov r10,r8
- mov r13d,DWORD PTR[r12*4+rdi]
- ror rax,8
+ sub rbx,r10
+ sub r13,r12
+ mov eax,DWORD PTR[r10*4+rdi]
+ test r11,-16
+ jz $L$loop1
+ bt r8d,30
+ jc $L$intel
+ and rbx,7
+ lea rsi,QWORD PTR[1+r10]
+ jz $L$oop8
+ sub r11,rbx
+$L$oop8_warmup::
+ add cl,al
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ mov DWORD PTR[r10*4+rdi],edx
+ add al,dl
inc r10b
- mov r11d,DWORD PTR[r10*4+rdi]
- cmp r12,r10
- mov DWORD PTR[r12*4+rdi],r9d
- cmove r11,r9
- mov DWORD PTR[r8*4+rdi],r13d
- add r13b,r9b
- mov al,BYTE PTR[r13*4+rdi]
- add r12b,r11b
- mov r8,r10
- mov r13d,DWORD PTR[r12*4+rdi]
- ror rax,8
- inc r8b
- mov r9d,DWORD PTR[r8*4+rdi]
- cmp r12,r8
- mov DWORD PTR[r12*4+rdi],r11d
- cmove r9,r11
- mov DWORD PTR[r10*4+rdi],r13d
- add r13b,r11b
- mov al,BYTE PTR[r13*4+rdi]
- add r12b,r9b
- mov r10,r8
- mov r13d,DWORD PTR[r12*4+rdi]
- ror rax,8
+ mov edx,DWORD PTR[rax*4+rdi]
+ mov eax,DWORD PTR[r10*4+rdi]
+ xor dl,BYTE PTR[r12]
+ mov BYTE PTR[r12*1+r13],dl
+ lea r12,QWORD PTR[1+r12]
+ dec rbx
+ jnz $L$oop8_warmup
+
+ lea rsi,QWORD PTR[1+r10]
+ jmp $L$oop8
+ALIGN 16
+$L$oop8::
+ add cl,al
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ mov ebx,DWORD PTR[rsi*4+rdi]
+ ror r8,8
+ mov DWORD PTR[r10*4+rdi],edx
+ add dl,al
+ mov r8b,BYTE PTR[rdx*4+rdi]
+ add cl,bl
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ mov eax,DWORD PTR[4+rsi*4+rdi]
+ ror r8,8
+ mov DWORD PTR[4+r10*4+rdi],edx
+ add dl,bl
+ mov r8b,BYTE PTR[rdx*4+rdi]
+ add cl,al
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ mov ebx,DWORD PTR[8+rsi*4+rdi]
+ ror r8,8
+ mov DWORD PTR[8+r10*4+rdi],edx
+ add dl,al
+ mov r8b,BYTE PTR[rdx*4+rdi]
+ add cl,bl
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ mov eax,DWORD PTR[12+rsi*4+rdi]
+ ror r8,8
+ mov DWORD PTR[12+r10*4+rdi],edx
+ add dl,bl
+ mov r8b,BYTE PTR[rdx*4+rdi]
+ add cl,al
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ mov ebx,DWORD PTR[16+rsi*4+rdi]
+ ror r8,8
+ mov DWORD PTR[16+r10*4+rdi],edx
+ add dl,al
+ mov r8b,BYTE PTR[rdx*4+rdi]
+ add cl,bl
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ mov eax,DWORD PTR[20+rsi*4+rdi]
+ ror r8,8
+ mov DWORD PTR[20+r10*4+rdi],edx
+ add dl,bl
+ mov r8b,BYTE PTR[rdx*4+rdi]
+ add cl,al
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ mov ebx,DWORD PTR[24+rsi*4+rdi]
+ ror r8,8
+ mov DWORD PTR[24+r10*4+rdi],edx
+ add dl,al
+ mov r8b,BYTE PTR[rdx*4+rdi]
+ add sil,8
+ add cl,bl
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ mov eax,DWORD PTR[((-4))+rsi*4+rdi]
+ ror r8,8
+ mov DWORD PTR[28+r10*4+rdi],edx
+ add dl,bl
+ mov r8b,BYTE PTR[rdx*4+rdi]
+ add r10b,8
+ ror r8,8
+ sub r11,8
+
+ xor r8,QWORD PTR[r12]
+ mov QWORD PTR[r12*1+r13],r8
+ lea r12,QWORD PTR[8+r12]
+
+ test r11,-8
+ jnz $L$oop8
+ cmp r11,0
+ jne $L$loop1
+ jmp $L$exit
+
+ALIGN 16
+$L$intel::
+ test r11,-32
+ jz $L$loop1
+ and rbx,15
+ jz $L$oop16_is_hot
+ sub r11,rbx
+$L$oop16_warmup::
+ add cl,al
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ mov DWORD PTR[r10*4+rdi],edx
+ add al,dl
inc r10b
- mov r11d,DWORD PTR[r10*4+rdi]
- cmp r12,r10
- mov DWORD PTR[r12*4+rdi],r9d
- cmove r11,r9
- mov DWORD PTR[r8*4+rdi],r13d
- add r13b,r9b
- mov al,BYTE PTR[r13*4+rdi]
- add r12b,r11b
- mov r8,r10
- mov r13d,DWORD PTR[r12*4+rdi]
- ror rax,8
- inc r8b
- mov r9d,DWORD PTR[r8*4+rdi]
- cmp r12,r8
- mov DWORD PTR[r12*4+rdi],r11d
- cmove r9,r11
- mov DWORD PTR[r10*4+rdi],r13d
- add r13b,r11b
- mov al,BYTE PTR[r13*4+rdi]
- ror rax,8
- sub rsi,8
-
- xor rax,QWORD PTR[rdx]
- add rdx,8
- mov QWORD PTR[rcx],rax
- add rcx,8
-
- test rsi,-8
- jnz $L$loop8
- cmp rsi,0
+ mov edx,DWORD PTR[rax*4+rdi]
+ mov eax,DWORD PTR[r10*4+rdi]
+ xor dl,BYTE PTR[r12]
+ mov BYTE PTR[r12*1+r13],dl
+ lea r12,QWORD PTR[1+r12]
+ dec rbx
+ jnz $L$oop16_warmup
+
+ mov rbx,rcx
+ xor rcx,rcx
+ mov cl,bl
+
+$L$oop16_is_hot::
+ lea rsi,QWORD PTR[r10*4+rdi]
+ add cl,al
+ mov edx,DWORD PTR[rcx*4+rdi]
+ pxor xmm0,xmm0
+ mov DWORD PTR[rcx*4+rdi],eax
+ add al,dl
+ mov ebx,DWORD PTR[4+rsi]
+ movzx eax,al
+ mov DWORD PTR[rsi],edx
+ add cl,bl
+ pinsrw xmm0,WORD PTR[rax*4+rdi],0
+ jmp $L$oop16_enter
+ALIGN 16
+$L$oop16::
+ add cl,al
+ mov edx,DWORD PTR[rcx*4+rdi]
+ pxor xmm2,xmm0
+ psllq xmm1,8
+ pxor xmm0,xmm0
+ mov DWORD PTR[rcx*4+rdi],eax
+ add al,dl
+ mov ebx,DWORD PTR[4+rsi]
+ movzx eax,al
+ mov DWORD PTR[rsi],edx
+ pxor xmm2,xmm1
+ add cl,bl
+ pinsrw xmm0,WORD PTR[rax*4+rdi],0
+ movdqu XMMWORD PTR[r12*1+r13],xmm2
+ lea r12,QWORD PTR[16+r12]
+$L$oop16_enter::
+ mov edx,DWORD PTR[rcx*4+rdi]
+ pxor xmm1,xmm1
+ mov DWORD PTR[rcx*4+rdi],ebx
+ add bl,dl
+ mov eax,DWORD PTR[8+rsi]
+ movzx ebx,bl
+ mov DWORD PTR[4+rsi],edx
+ add cl,al
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],0
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ add al,dl
+ mov ebx,DWORD PTR[12+rsi]
+ movzx eax,al
+ mov DWORD PTR[8+rsi],edx
+ add cl,bl
+ pinsrw xmm0,WORD PTR[rax*4+rdi],1
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ add bl,dl
+ mov eax,DWORD PTR[16+rsi]
+ movzx ebx,bl
+ mov DWORD PTR[12+rsi],edx
+ add cl,al
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],1
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ add al,dl
+ mov ebx,DWORD PTR[20+rsi]
+ movzx eax,al
+ mov DWORD PTR[16+rsi],edx
+ add cl,bl
+ pinsrw xmm0,WORD PTR[rax*4+rdi],2
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ add bl,dl
+ mov eax,DWORD PTR[24+rsi]
+ movzx ebx,bl
+ mov DWORD PTR[20+rsi],edx
+ add cl,al
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],2
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ add al,dl
+ mov ebx,DWORD PTR[28+rsi]
+ movzx eax,al
+ mov DWORD PTR[24+rsi],edx
+ add cl,bl
+ pinsrw xmm0,WORD PTR[rax*4+rdi],3
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ add bl,dl
+ mov eax,DWORD PTR[32+rsi]
+ movzx ebx,bl
+ mov DWORD PTR[28+rsi],edx
+ add cl,al
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],3
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ add al,dl
+ mov ebx,DWORD PTR[36+rsi]
+ movzx eax,al
+ mov DWORD PTR[32+rsi],edx
+ add cl,bl
+ pinsrw xmm0,WORD PTR[rax*4+rdi],4
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ add bl,dl
+ mov eax,DWORD PTR[40+rsi]
+ movzx ebx,bl
+ mov DWORD PTR[36+rsi],edx
+ add cl,al
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],4
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ add al,dl
+ mov ebx,DWORD PTR[44+rsi]
+ movzx eax,al
+ mov DWORD PTR[40+rsi],edx
+ add cl,bl
+ pinsrw xmm0,WORD PTR[rax*4+rdi],5
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ add bl,dl
+ mov eax,DWORD PTR[48+rsi]
+ movzx ebx,bl
+ mov DWORD PTR[44+rsi],edx
+ add cl,al
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],5
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ add al,dl
+ mov ebx,DWORD PTR[52+rsi]
+ movzx eax,al
+ mov DWORD PTR[48+rsi],edx
+ add cl,bl
+ pinsrw xmm0,WORD PTR[rax*4+rdi],6
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ add bl,dl
+ mov eax,DWORD PTR[56+rsi]
+ movzx ebx,bl
+ mov DWORD PTR[52+rsi],edx
+ add cl,al
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],6
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ add al,dl
+ mov ebx,DWORD PTR[60+rsi]
+ movzx eax,al
+ mov DWORD PTR[56+rsi],edx
+ add cl,bl
+ pinsrw xmm0,WORD PTR[rax*4+rdi],7
+ add r10b,16
+ movdqu xmm2,XMMWORD PTR[r12]
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],ebx
+ add bl,dl
+ movzx ebx,bl
+ mov DWORD PTR[60+rsi],edx
+ lea rsi,QWORD PTR[r10*4+rdi]
+ pinsrw xmm1,WORD PTR[rbx*4+rdi],7
+ mov eax,DWORD PTR[rsi]
+ mov rbx,rcx
+ xor rcx,rcx
+ sub r11,16
+ mov cl,bl
+ test r11,-16
+ jnz $L$oop16
+
+ psllq xmm1,8
+ pxor xmm2,xmm0
+ pxor xmm2,xmm1
+ movdqu XMMWORD PTR[r12*1+r13],xmm2
+ lea r12,QWORD PTR[16+r12]
+
+ cmp r11,0
jne $L$loop1
jmp $L$exit
ALIGN 16
$L$loop1::
- add r12b,r9b
- mov r13d,DWORD PTR[r12*4+rdi]
- mov DWORD PTR[r12*4+rdi],r9d
- mov DWORD PTR[r8*4+rdi],r13d
- add r9b,r13b
- inc r8b
- mov r13d,DWORD PTR[r9*4+rdi]
- mov r9d,DWORD PTR[r8*4+rdi]
- xor r13b,BYTE PTR[rdx]
- inc rdx
- mov BYTE PTR[rcx],r13b
- inc rcx
- dec rsi
+ add cl,al
+ mov edx,DWORD PTR[rcx*4+rdi]
+ mov DWORD PTR[rcx*4+rdi],eax
+ mov DWORD PTR[r10*4+rdi],edx
+ add al,dl
+ inc r10b
+ mov edx,DWORD PTR[rax*4+rdi]
+ mov eax,DWORD PTR[r10*4+rdi]
+ xor dl,BYTE PTR[r12]
+ mov BYTE PTR[r12*1+r13],dl
+ lea r12,QWORD PTR[1+r12]
+ dec r11
jnz $L$loop1
jmp $L$exit
ALIGN 16
$L$RC4_CHAR::
- add r8b,1
- movzx r9d,BYTE PTR[r8*1+rdi]
- test rsi,-8
+ add r10b,1
+ movzx eax,BYTE PTR[r10*1+rdi]
+ test r11,-8
jz $L$cloop1
- cmp DWORD PTR[260+rdi],0
- jnz $L$cloop1
jmp $L$cloop8
ALIGN 16
$L$cloop8::
- mov eax,DWORD PTR[rdx]
- mov ebx,DWORD PTR[4+rdx]
- add r12b,r9b
- lea r10,QWORD PTR[1+r8]
- movzx r13d,BYTE PTR[r12*1+rdi]
- movzx r10d,r10b
- movzx r11d,BYTE PTR[r10*1+rdi]
- mov BYTE PTR[r12*1+rdi],r9b
- cmp r12,r10
- mov BYTE PTR[r8*1+rdi],r13b
+ mov r8d,DWORD PTR[r12]
+ mov r9d,DWORD PTR[4+r12]
+ add cl,al
+ lea rsi,QWORD PTR[1+r10]
+ movzx edx,BYTE PTR[rcx*1+rdi]
+ movzx esi,sil
+ movzx ebx,BYTE PTR[rsi*1+rdi]
+ mov BYTE PTR[rcx*1+rdi],al
+ cmp rcx,rsi
+ mov BYTE PTR[r10*1+rdi],dl
jne $L$cmov0
- mov r11,r9
+ mov rbx,rax
$L$cmov0::
- add r13b,r9b
- xor al,BYTE PTR[r13*1+rdi]
- ror eax,8
- add r12b,r11b
- lea r8,QWORD PTR[1+r10]
- movzx r13d,BYTE PTR[r12*1+rdi]
- movzx r8d,r8b
- movzx r9d,BYTE PTR[r8*1+rdi]
- mov BYTE PTR[r12*1+rdi],r11b
- cmp r12,r8
- mov BYTE PTR[r10*1+rdi],r13b
+ add dl,al
+ xor r8b,BYTE PTR[rdx*1+rdi]
+ ror r8d,8
+ add cl,bl
+ lea r10,QWORD PTR[1+rsi]
+ movzx edx,BYTE PTR[rcx*1+rdi]
+ movzx r10d,r10b
+ movzx eax,BYTE PTR[r10*1+rdi]
+ mov BYTE PTR[rcx*1+rdi],bl
+ cmp rcx,r10
+ mov BYTE PTR[rsi*1+rdi],dl
jne $L$cmov1
- mov r9,r11
+ mov rax,rbx
$L$cmov1::
- add r13b,r11b
- xor al,BYTE PTR[r13*1+rdi]
- ror eax,8
- add r12b,r9b
- lea r10,QWORD PTR[1+r8]
- movzx r13d,BYTE PTR[r12*1+rdi]
- movzx r10d,r10b
- movzx r11d,BYTE PTR[r10*1+rdi]
- mov BYTE PTR[r12*1+rdi],r9b
- cmp r12,r10
- mov BYTE PTR[r8*1+rdi],r13b
+ add dl,bl
+ xor r8b,BYTE PTR[rdx*1+rdi]
+ ror r8d,8
+ add cl,al
+ lea rsi,QWORD PTR[1+r10]
+ movzx edx,BYTE PTR[rcx*1+rdi]
+ movzx esi,sil
+ movzx ebx,BYTE PTR[rsi*1+rdi]
+ mov BYTE PTR[rcx*1+rdi],al
+ cmp rcx,rsi
+ mov BYTE PTR[r10*1+rdi],dl
jne $L$cmov2
- mov r11,r9
+ mov rbx,rax
$L$cmov2::
- add r13b,r9b
- xor al,BYTE PTR[r13*1+rdi]
- ror eax,8
- add r12b,r11b
- lea r8,QWORD PTR[1+r10]
- movzx r13d,BYTE PTR[r12*1+rdi]
- movzx r8d,r8b
- movzx r9d,BYTE PTR[r8*1+rdi]
- mov BYTE PTR[r12*1+rdi],r11b
- cmp r12,r8
- mov BYTE PTR[r10*1+rdi],r13b
+ add dl,al
+ xor r8b,BYTE PTR[rdx*1+rdi]
+ ror r8d,8
+ add cl,bl
+ lea r10,QWORD PTR[1+rsi]
+ movzx edx,BYTE PTR[rcx*1+rdi]
+ movzx r10d,r10b
+ movzx eax,BYTE PTR[r10*1+rdi]
+ mov BYTE PTR[rcx*1+rdi],bl
+ cmp rcx,r10
+ mov BYTE PTR[rsi*1+rdi],dl
jne $L$cmov3
- mov r9,r11
+ mov rax,rbx
$L$cmov3::
- add r13b,r11b
- xor al,BYTE PTR[r13*1+rdi]
- ror eax,8
- add r12b,r9b
- lea r10,QWORD PTR[1+r8]
- movzx r13d,BYTE PTR[r12*1+rdi]
- movzx r10d,r10b
- movzx r11d,BYTE PTR[r10*1+rdi]
- mov BYTE PTR[r12*1+rdi],r9b
- cmp r12,r10
- mov BYTE PTR[r8*1+rdi],r13b
+ add dl,bl
+ xor r8b,BYTE PTR[rdx*1+rdi]
+ ror r8d,8
+ add cl,al
+ lea rsi,QWORD PTR[1+r10]
+ movzx edx,BYTE PTR[rcx*1+rdi]
+ movzx esi,sil
+ movzx ebx,BYTE PTR[rsi*1+rdi]
+ mov BYTE PTR[rcx*1+rdi],al
+ cmp rcx,rsi
+ mov BYTE PTR[r10*1+rdi],dl
jne $L$cmov4
- mov r11,r9
+ mov rbx,rax
$L$cmov4::
- add r13b,r9b
- xor bl,BYTE PTR[r13*1+rdi]
- ror ebx,8
- add r12b,r11b
- lea r8,QWORD PTR[1+r10]
- movzx r13d,BYTE PTR[r12*1+rdi]
- movzx r8d,r8b
- movzx r9d,BYTE PTR[r8*1+rdi]
- mov BYTE PTR[r12*1+rdi],r11b
- cmp r12,r8
- mov BYTE PTR[r10*1+rdi],r13b
+ add dl,al
+ xor r9b,BYTE PTR[rdx*1+rdi]
+ ror r9d,8
+ add cl,bl
+ lea r10,QWORD PTR[1+rsi]
+ movzx edx,BYTE PTR[rcx*1+rdi]
+ movzx r10d,r10b
+ movzx eax,BYTE PTR[r10*1+rdi]
+ mov BYTE PTR[rcx*1+rdi],bl
+ cmp rcx,r10
+ mov BYTE PTR[rsi*1+rdi],dl
jne $L$cmov5
- mov r9,r11
+ mov rax,rbx
$L$cmov5::
- add r13b,r11b
- xor bl,BYTE PTR[r13*1+rdi]
- ror ebx,8
- add r12b,r9b
- lea r10,QWORD PTR[1+r8]
- movzx r13d,BYTE PTR[r12*1+rdi]
- movzx r10d,r10b
- movzx r11d,BYTE PTR[r10*1+rdi]
- mov BYTE PTR[r12*1+rdi],r9b
- cmp r12,r10
- mov BYTE PTR[r8*1+rdi],r13b
+ add dl,bl
+ xor r9b,BYTE PTR[rdx*1+rdi]
+ ror r9d,8
+ add cl,al
+ lea rsi,QWORD PTR[1+r10]
+ movzx edx,BYTE PTR[rcx*1+rdi]
+ movzx esi,sil
+ movzx ebx,BYTE PTR[rsi*1+rdi]
+ mov BYTE PTR[rcx*1+rdi],al
+ cmp rcx,rsi
+ mov BYTE PTR[r10*1+rdi],dl
jne $L$cmov6
- mov r11,r9
+ mov rbx,rax
$L$cmov6::
- add r13b,r9b
- xor bl,BYTE PTR[r13*1+rdi]
- ror ebx,8
- add r12b,r11b
- lea r8,QWORD PTR[1+r10]
- movzx r13d,BYTE PTR[r12*1+rdi]
- movzx r8d,r8b
- movzx r9d,BYTE PTR[r8*1+rdi]
- mov BYTE PTR[r12*1+rdi],r11b
- cmp r12,r8
- mov BYTE PTR[r10*1+rdi],r13b
+ add dl,al
+ xor r9b,BYTE PTR[rdx*1+rdi]
+ ror r9d,8
+ add cl,bl
+ lea r10,QWORD PTR[1+rsi]
+ movzx edx,BYTE PTR[rcx*1+rdi]
+ movzx r10d,r10b
+ movzx eax,BYTE PTR[r10*1+rdi]
+ mov BYTE PTR[rcx*1+rdi],bl
+ cmp rcx,r10
+ mov BYTE PTR[rsi*1+rdi],dl
jne $L$cmov7
- mov r9,r11
+ mov rax,rbx
$L$cmov7::
- add r13b,r11b
- xor bl,BYTE PTR[r13*1+rdi]
- ror ebx,8
- lea rsi,QWORD PTR[((-8))+rsi]
- mov DWORD PTR[rcx],eax
- lea rdx,QWORD PTR[8+rdx]
- mov DWORD PTR[4+rcx],ebx
- lea rcx,QWORD PTR[8+rcx]
-
- test rsi,-8
+ add dl,bl
+ xor r9b,BYTE PTR[rdx*1+rdi]
+ ror r9d,8
+ lea r11,QWORD PTR[((-8))+r11]
+ mov DWORD PTR[r13],r8d
+ lea r12,QWORD PTR[8+r12]
+ mov DWORD PTR[4+r13],r9d
+ lea r13,QWORD PTR[8+r13]
+
+ test r11,-8
jnz $L$cloop8
- cmp rsi,0
+ cmp r11,0
jne $L$cloop1
jmp $L$exit
ALIGN 16
$L$cloop1::
- add r12b,r9b
- movzx r13d,BYTE PTR[r12*1+rdi]
- mov BYTE PTR[r12*1+rdi],r9b
- mov BYTE PTR[r8*1+rdi],r13b
- add r13b,r9b
- add r8b,1
- movzx r13d,r13b
- movzx r8d,r8b
- movzx r13d,BYTE PTR[r13*1+rdi]
- movzx r9d,BYTE PTR[r8*1+rdi]
- xor r13b,BYTE PTR[rdx]
- lea rdx,QWORD PTR[1+rdx]
- mov BYTE PTR[rcx],r13b
- lea rcx,QWORD PTR[1+rcx]
- sub rsi,1
+ add cl,al
+ movzx ecx,cl
+ movzx edx,BYTE PTR[rcx*1+rdi]
+ mov BYTE PTR[rcx*1+rdi],al
+ mov BYTE PTR[r10*1+rdi],dl
+ add dl,al
+ add r10b,1
+ movzx edx,dl
+ movzx r10d,r10b
+ movzx edx,BYTE PTR[rdx*1+rdi]
+ movzx eax,BYTE PTR[r10*1+rdi]
+ xor dl,BYTE PTR[r12]
+ lea r12,QWORD PTR[1+r12]
+ mov BYTE PTR[r13],dl
+ lea r13,QWORD PTR[1+r13]
+ sub r11,1
jnz $L$cloop1
jmp $L$exit
ALIGN 16
$L$exit::
- sub r8b,1
- mov DWORD PTR[((-8))+rdi],r8d
- mov DWORD PTR[((-4))+rdi],r12d
+ sub r10b,1
+ mov DWORD PTR[((-8))+rdi],r10d
+ mov DWORD PTR[((-4))+rdi],ecx
mov r13,QWORD PTR[rsp]
mov r12,QWORD PTR[8+rsp]
@@ -345,15 +541,14 @@ $L$epilogue::
DB 0F3h,0C3h ;repret
$L$SEH_end_RC4::
RC4 ENDP
-EXTERN OPENSSL_ia32cap_P:NEAR
-PUBLIC RC4_set_key
+PUBLIC private_RC4_set_key
ALIGN 16
-RC4_set_key PROC PUBLIC
+private_RC4_set_key PROC PUBLIC
mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
mov QWORD PTR[16+rsp],rsi
mov rax,rsp
-$L$SEH_begin_RC4_set_key::
+$L$SEH_begin_private_RC4_set_key::
mov rdi,rcx
mov rsi,rdx
mov rdx,r8
@@ -370,11 +565,8 @@ $L$SEH_begin_RC4_set_key::
mov r8d,DWORD PTR[OPENSSL_ia32cap_P]
bt r8d,20
- jnc $L$w1stloop
- bt r8d,30
- setc r9b
- mov DWORD PTR[260+rdi],r9d
- jmp $L$c1stloop
+ jc $L$c1stloop
+ jmp $L$w1stloop
ALIGN 16
$L$w1stloop::
@@ -430,8 +622,8 @@ $L$exit_key::
mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
mov rsi,QWORD PTR[16+rsp]
DB 0F3h,0C3h ;repret
-$L$SEH_end_RC4_set_key::
-RC4_set_key ENDP
+$L$SEH_end_private_RC4_set_key::
+private_RC4_set_key ENDP
PUBLIC RC4_options
@@ -440,18 +632,20 @@ RC4_options PROC PUBLIC
lea rax,QWORD PTR[$L$opts]
mov edx,DWORD PTR[OPENSSL_ia32cap_P]
bt edx,20
- jnc $L$done
- add rax,12
+ jc $L$8xchar
bt edx,30
jnc $L$done
- add rax,13
+ add rax,25
+ DB 0F3h,0C3h ;repret
+$L$8xchar::
+ add rax,12
$L$done::
DB 0F3h,0C3h ;repret
ALIGN 64
$L$opts::
DB 114,99,52,40,56,120,44,105,110,116,41,0
DB 114,99,52,40,56,120,44,99,104,97,114,41,0
-DB 114,99,52,40,49,120,44,99,104,97,114,41,0
+DB 114,99,52,40,49,54,120,44,105,110,116,41,0
DB 82,67,52,32,102,111,114,32,120,56,54,95,54,52,44,32
DB 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
DB 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
@@ -568,9 +762,9 @@ ALIGN 4
DD imagerel $L$SEH_end_RC4
DD imagerel $L$SEH_info_RC4
- DD imagerel $L$SEH_begin_RC4_set_key
- DD imagerel $L$SEH_end_RC4_set_key
- DD imagerel $L$SEH_info_RC4_set_key
+ DD imagerel $L$SEH_begin_private_RC4_set_key
+ DD imagerel $L$SEH_end_private_RC4_set_key
+ DD imagerel $L$SEH_info_private_RC4_set_key
.pdata ENDS
.xdata SEGMENT READONLY ALIGN(8)
@@ -578,7 +772,7 @@ ALIGN 8
$L$SEH_info_RC4::
DB 9,0,0,0
DD imagerel stream_se_handler
-$L$SEH_info_RC4_set_key::
+$L$SEH_info_private_RC4_set_key::
DB 9,0,0,0
DD imagerel key_se_handler
diff --git a/deps/openssl/asm/x64-win32-masm/sha/sha1-x86_64.asm b/deps/openssl/asm/x64-win32-masm/sha/sha1-x86_64.asm
index 9323f2b26..9589f7fa0 100644
--- a/deps/openssl/asm/x64-win32-masm/sha/sha1-x86_64.asm
+++ b/deps/openssl/asm/x64-win32-masm/sha/sha1-x86_64.asm
@@ -1,5 +1,7 @@
OPTION DOTNAME
.text$ SEGMENT ALIGN(64) 'CODE'
+EXTERN OPENSSL_ia32cap_P:NEAR
+
PUBLIC sha1_block_data_order
ALIGN 16
@@ -13,9 +15,18 @@ $L$SEH_begin_sha1_block_data_order::
mov rdx,r8
+ mov r9d,DWORD PTR[((OPENSSL_ia32cap_P+0))]
+ mov r8d,DWORD PTR[((OPENSSL_ia32cap_P+4))]
+ test r8d,512
+ jz $L$ialu
+ jmp _ssse3_shortcut
+
+ALIGN 16
+$L$ialu::
push rbx
push rbp
push r12
+ push r13
mov r11,rsp
mov r8,rdi
sub rsp,72
@@ -25,1278 +36,2499 @@ $L$SEH_begin_sha1_block_data_order::
mov QWORD PTR[64+rsp],r11
$L$prologue::
- mov edx,DWORD PTR[r8]
- mov esi,DWORD PTR[4+r8]
- mov edi,DWORD PTR[8+r8]
- mov ebp,DWORD PTR[12+r8]
- mov r11d,DWORD PTR[16+r8]
-ALIGN 4
+ mov esi,DWORD PTR[r8]
+ mov edi,DWORD PTR[4+r8]
+ mov r11d,DWORD PTR[8+r8]
+ mov r12d,DWORD PTR[12+r8]
+ mov r13d,DWORD PTR[16+r8]
+ jmp $L$loop
+
+ALIGN 16
$L$loop::
- mov eax,DWORD PTR[r9]
- bswap eax
- mov DWORD PTR[rsp],eax
- lea r12d,DWORD PTR[05a827999h+r11*1+rax]
- mov ebx,edi
- mov eax,DWORD PTR[4+r9]
- mov r11d,edx
- xor ebx,ebp
- bswap eax
- rol r11d,5
- and ebx,esi
- mov DWORD PTR[4+rsp],eax
- add r12d,r11d
- xor ebx,ebp
+ mov edx,DWORD PTR[r9]
+ bswap edx
+ mov DWORD PTR[rsp],edx
+ mov eax,r11d
+ mov ebp,DWORD PTR[4+r9]
+ mov ecx,esi
+ xor eax,r12d
+ bswap ebp
+ rol ecx,5
+ lea r13d,DWORD PTR[1518500249+r13*1+rdx]
+ and eax,edi
+ mov DWORD PTR[4+rsp],ebp
+ add r13d,ecx
+ xor eax,r12d
+ rol edi,30
+ add r13d,eax
+ mov eax,edi
+ mov edx,DWORD PTR[8+r9]
+ mov ecx,r13d
+ xor eax,r11d
+ bswap edx
+ rol ecx,5
+ lea r12d,DWORD PTR[1518500249+r12*1+rbp]
+ and eax,esi
+ mov DWORD PTR[8+rsp],edx
+ add r12d,ecx
+ xor eax,r11d
rol esi,30
- add r12d,ebx
- lea r11d,DWORD PTR[05a827999h+rbp*1+rax]
- mov ebx,esi
- mov eax,DWORD PTR[8+r9]
- mov ebp,r12d
- xor ebx,edi
- bswap eax
- rol ebp,5
- and ebx,edx
- mov DWORD PTR[8+rsp],eax
- add r11d,ebp
- xor ebx,edi
- rol edx,30
- add r11d,ebx
- lea ebp,DWORD PTR[05a827999h+rdi*1+rax]
- mov ebx,edx
- mov eax,DWORD PTR[12+r9]
- mov edi,r11d
- xor ebx,esi
- bswap eax
- rol edi,5
- and ebx,r12d
- mov DWORD PTR[12+rsp],eax
- add ebp,edi
- xor ebx,esi
+ add r12d,eax
+ mov eax,esi
+ mov ebp,DWORD PTR[12+r9]
+ mov ecx,r12d
+ xor eax,edi
+ bswap ebp
+ rol ecx,5
+ lea r11d,DWORD PTR[1518500249+r11*1+rdx]
+ and eax,r13d
+ mov DWORD PTR[12+rsp],ebp
+ add r11d,ecx
+ xor eax,edi
+ rol r13d,30
+ add r11d,eax
+ mov eax,r13d
+ mov edx,DWORD PTR[16+r9]
+ mov ecx,r11d
+ xor eax,esi
+ bswap edx
+ rol ecx,5
+ lea edi,DWORD PTR[1518500249+rdi*1+rbp]
+ and eax,r12d
+ mov DWORD PTR[16+rsp],edx
+ add edi,ecx
+ xor eax,esi
rol r12d,30
- add ebp,ebx
- lea edi,DWORD PTR[05a827999h+rsi*1+rax]
- mov ebx,r12d
- mov eax,DWORD PTR[16+r9]
- mov esi,ebp
- xor ebx,edx
- bswap eax
- rol esi,5
- and ebx,r11d
- mov DWORD PTR[16+rsp],eax
- add edi,esi
- xor ebx,edx
+ add edi,eax
+ mov eax,r12d
+ mov ebp,DWORD PTR[20+r9]
+ mov ecx,edi
+ xor eax,r13d
+ bswap ebp
+ rol ecx,5
+ lea esi,DWORD PTR[1518500249+rsi*1+rdx]
+ and eax,r11d
+ mov DWORD PTR[20+rsp],ebp
+ add esi,ecx
+ xor eax,r13d
rol r11d,30
- add edi,ebx
- lea esi,DWORD PTR[05a827999h+rdx*1+rax]
+ add esi,eax
+ mov eax,r11d
+ mov edx,DWORD PTR[24+r9]
+ mov ecx,esi
+ xor eax,r12d
+ bswap edx
+ rol ecx,5
+ lea r13d,DWORD PTR[1518500249+r13*1+rbp]
+ and eax,edi
+ mov DWORD PTR[24+rsp],edx
+ add r13d,ecx
+ xor eax,r12d
+ rol edi,30
+ add r13d,eax
+ mov eax,edi
+ mov ebp,DWORD PTR[28+r9]
+ mov ecx,r13d
+ xor eax,r11d
+ bswap ebp
+ rol ecx,5
+ lea r12d,DWORD PTR[1518500249+r12*1+rdx]
+ and eax,esi
+ mov DWORD PTR[28+rsp],ebp
+ add r12d,ecx
+ xor eax,r11d
+ rol esi,30
+ add r12d,eax
+ mov eax,esi
+ mov edx,DWORD PTR[32+r9]
+ mov ecx,r12d
+ xor eax,edi
+ bswap edx
+ rol ecx,5
+ lea r11d,DWORD PTR[1518500249+r11*1+rbp]
+ and eax,r13d
+ mov DWORD PTR[32+rsp],edx
+ add r11d,ecx
+ xor eax,edi
+ rol r13d,30
+ add r11d,eax
+ mov eax,r13d
+ mov ebp,DWORD PTR[36+r9]
+ mov ecx,r11d
+ xor eax,esi
+ bswap ebp
+ rol ecx,5
+ lea edi,DWORD PTR[1518500249+rdi*1+rdx]
+ and eax,r12d
+ mov DWORD PTR[36+rsp],ebp
+ add edi,ecx
+ xor eax,esi
+ rol r12d,30
+ add edi,eax
+ mov eax,r12d
+ mov edx,DWORD PTR[40+r9]
+ mov ecx,edi
+ xor eax,r13d
+ bswap edx
+ rol ecx,5
+ lea esi,DWORD PTR[1518500249+rsi*1+rbp]
+ and eax,r11d
+ mov DWORD PTR[40+rsp],edx
+ add esi,ecx
+ xor eax,r13d
+ rol r11d,30
+ add esi,eax
+ mov eax,r11d
+ mov ebp,DWORD PTR[44+r9]
+ mov ecx,esi
+ xor eax,r12d
+ bswap ebp
+ rol ecx,5
+ lea r13d,DWORD PTR[1518500249+r13*1+rdx]
+ and eax,edi
+ mov DWORD PTR[44+rsp],ebp
+ add r13d,ecx
+ xor eax,r12d
+ rol edi,30
+ add r13d,eax
+ mov eax,edi
+ mov edx,DWORD PTR[48+r9]
+ mov ecx,r13d
+ xor eax,r11d
+ bswap edx
+ rol ecx,5
+ lea r12d,DWORD PTR[1518500249+r12*1+rbp]
+ and eax,esi
+ mov DWORD PTR[48+rsp],edx
+ add r12d,ecx
+ xor eax,r11d
+ rol esi,30
+ add r12d,eax
+ mov eax,esi
+ mov ebp,DWORD PTR[52+r9]
+ mov ecx,r12d
+ xor eax,edi
+ bswap ebp
+ rol ecx,5
+ lea r11d,DWORD PTR[1518500249+r11*1+rdx]
+ and eax,r13d
+ mov DWORD PTR[52+rsp],ebp
+ add r11d,ecx
+ xor eax,edi
+ rol r13d,30
+ add r11d,eax
+ mov eax,r13d
+ mov edx,DWORD PTR[56+r9]
+ mov ecx,r11d
+ xor eax,esi
+ bswap edx
+ rol ecx,5
+ lea edi,DWORD PTR[1518500249+rdi*1+rbp]
+ and eax,r12d
+ mov DWORD PTR[56+rsp],edx
+ add edi,ecx
+ xor eax,esi
+ rol r12d,30
+ add edi,eax
+ mov eax,r12d
+ mov ebp,DWORD PTR[60+r9]
+ mov ecx,edi
+ xor eax,r13d
+ bswap ebp
+ rol ecx,5
+ lea esi,DWORD PTR[1518500249+rsi*1+rdx]
+ and eax,r11d
+ mov DWORD PTR[60+rsp],ebp
+ add esi,ecx
+ xor eax,r13d
+ rol r11d,30
+ add esi,eax
+ mov edx,DWORD PTR[rsp]
+ mov eax,r11d
+ mov ecx,esi
+ xor edx,DWORD PTR[8+rsp]
+ xor eax,r12d
+ rol ecx,5
+ xor edx,DWORD PTR[32+rsp]
+ and eax,edi
+ lea r13d,DWORD PTR[1518500249+r13*1+rbp]
+ xor edx,DWORD PTR[52+rsp]
+ xor eax,r12d
+ rol edx,1
+ add r13d,ecx
+ rol edi,30
+ mov DWORD PTR[rsp],edx
+ add r13d,eax
+ mov ebp,DWORD PTR[4+rsp]
+ mov eax,edi
+ mov ecx,r13d
+ xor ebp,DWORD PTR[12+rsp]
+ xor eax,r11d
+ rol ecx,5
+ xor ebp,DWORD PTR[36+rsp]
+ and eax,esi
+ lea r12d,DWORD PTR[1518500249+r12*1+rdx]
+ xor ebp,DWORD PTR[56+rsp]
+ xor eax,r11d
+ rol ebp,1
+ add r12d,ecx
+ rol esi,30
+ mov DWORD PTR[4+rsp],ebp
+ add r12d,eax
+ mov edx,DWORD PTR[8+rsp]
+ mov eax,esi
+ mov ecx,r12d
+ xor edx,DWORD PTR[16+rsp]
+ xor eax,edi
+ rol ecx,5
+ xor edx,DWORD PTR[40+rsp]
+ and eax,r13d
+ lea r11d,DWORD PTR[1518500249+r11*1+rbp]
+ xor edx,DWORD PTR[60+rsp]
+ xor eax,edi
+ rol edx,1
+ add r11d,ecx
+ rol r13d,30
+ mov DWORD PTR[8+rsp],edx
+ add r11d,eax
+ mov ebp,DWORD PTR[12+rsp]
+ mov eax,r13d
+ mov ecx,r11d
+ xor ebp,DWORD PTR[20+rsp]
+ xor eax,esi
+ rol ecx,5
+ xor ebp,DWORD PTR[44+rsp]
+ and eax,r12d
+ lea edi,DWORD PTR[1518500249+rdi*1+rdx]
+ xor ebp,DWORD PTR[rsp]
+ xor eax,esi
+ rol ebp,1
+ add edi,ecx
+ rol r12d,30
+ mov DWORD PTR[12+rsp],ebp
+ add edi,eax
+ mov edx,DWORD PTR[16+rsp]
+ mov eax,r12d
+ mov ecx,edi
+ xor edx,DWORD PTR[24+rsp]
+ xor eax,r13d
+ rol ecx,5
+ xor edx,DWORD PTR[48+rsp]
+ and eax,r11d
+ lea esi,DWORD PTR[1518500249+rsi*1+rbp]
+ xor edx,DWORD PTR[4+rsp]
+ xor eax,r13d
+ rol edx,1
+ add esi,ecx
+ rol r11d,30
+ mov DWORD PTR[16+rsp],edx
+ add esi,eax
+ mov ebp,DWORD PTR[20+rsp]
+ mov eax,r11d
+ mov ecx,esi
+ xor ebp,DWORD PTR[28+rsp]
+ xor eax,edi
+ rol ecx,5
+ lea r13d,DWORD PTR[1859775393+r13*1+rdx]
+ xor ebp,DWORD PTR[52+rsp]
+ xor eax,r12d
+ add r13d,ecx
+ xor ebp,DWORD PTR[8+rsp]
+ rol edi,30
+ add r13d,eax
+ rol ebp,1
+ mov DWORD PTR[20+rsp],ebp
+ mov edx,DWORD PTR[24+rsp]
+ mov eax,edi
+ mov ecx,r13d
+ xor edx,DWORD PTR[32+rsp]
+ xor eax,esi
+ rol ecx,5
+ lea r12d,DWORD PTR[1859775393+r12*1+rbp]
+ xor edx,DWORD PTR[56+rsp]
+ xor eax,r11d
+ add r12d,ecx
+ xor edx,DWORD PTR[12+rsp]
+ rol esi,30
+ add r12d,eax
+ rol edx,1
+ mov DWORD PTR[24+rsp],edx
+ mov ebp,DWORD PTR[28+rsp]
+ mov eax,esi
+ mov ecx,r12d
+ xor ebp,DWORD PTR[36+rsp]
+ xor eax,r13d
+ rol ecx,5
+ lea r11d,DWORD PTR[1859775393+r11*1+rdx]
+ xor ebp,DWORD PTR[60+rsp]
+ xor eax,edi
+ add r11d,ecx
+ xor ebp,DWORD PTR[16+rsp]
+ rol r13d,30
+ add r11d,eax
+ rol ebp,1
+ mov DWORD PTR[28+rsp],ebp
+ mov edx,DWORD PTR[32+rsp]
+ mov eax,r13d
+ mov ecx,r11d
+ xor edx,DWORD PTR[40+rsp]
+ xor eax,r12d
+ rol ecx,5
+ lea edi,DWORD PTR[1859775393+rdi*1+rbp]
+ xor edx,DWORD PTR[rsp]
+ xor eax,esi
+ add edi,ecx
+ xor edx,DWORD PTR[20+rsp]
+ rol r12d,30
+ add edi,eax
+ rol edx,1
+ mov DWORD PTR[32+rsp],edx
+ mov ebp,DWORD PTR[36+rsp]
+ mov eax,r12d
+ mov ecx,edi
+ xor ebp,DWORD PTR[44+rsp]
+ xor eax,r11d
+ rol ecx,5
+ lea esi,DWORD PTR[1859775393+rsi*1+rdx]
+ xor ebp,DWORD PTR[4+rsp]
+ xor eax,r13d
+ add esi,ecx
+ xor ebp,DWORD PTR[24+rsp]
+ rol r11d,30
+ add esi,eax
+ rol ebp,1
+ mov DWORD PTR[36+rsp],ebp
+ mov edx,DWORD PTR[40+rsp]
+ mov eax,r11d
+ mov ecx,esi
+ xor edx,DWORD PTR[48+rsp]
+ xor eax,edi
+ rol ecx,5
+ lea r13d,DWORD PTR[1859775393+r13*1+rbp]
+ xor edx,DWORD PTR[8+rsp]
+ xor eax,r12d
+ add r13d,ecx
+ xor edx,DWORD PTR[28+rsp]
+ rol edi,30
+ add r13d,eax
+ rol edx,1
+ mov DWORD PTR[40+rsp],edx
+ mov ebp,DWORD PTR[44+rsp]
+ mov eax,edi
+ mov ecx,r13d
+ xor ebp,DWORD PTR[52+rsp]
+ xor eax,esi
+ rol ecx,5
+ lea r12d,DWORD PTR[1859775393+r12*1+rdx]
+ xor ebp,DWORD PTR[12+rsp]
+ xor eax,r11d
+ add r12d,ecx
+ xor ebp,DWORD PTR[32+rsp]
+ rol esi,30
+ add r12d,eax
+ rol ebp,1
+ mov DWORD PTR[44+rsp],ebp
+ mov edx,DWORD PTR[48+rsp]
+ mov eax,esi
+ mov ecx,r12d
+ xor edx,DWORD PTR[56+rsp]
+ xor eax,r13d
+ rol ecx,5
+ lea r11d,DWORD PTR[1859775393+r11*1+rbp]
+ xor edx,DWORD PTR[16+rsp]
+ xor eax,edi
+ add r11d,ecx
+ xor edx,DWORD PTR[36+rsp]
+ rol r13d,30
+ add r11d,eax
+ rol edx,1
+ mov DWORD PTR[48+rsp],edx
+ mov ebp,DWORD PTR[52+rsp]
+ mov eax,r13d
+ mov ecx,r11d
+ xor ebp,DWORD PTR[60+rsp]
+ xor eax,r12d
+ rol ecx,5
+ lea edi,DWORD PTR[1859775393+rdi*1+rdx]
+ xor ebp,DWORD PTR[20+rsp]
+ xor eax,esi
+ add edi,ecx
+ xor ebp,DWORD PTR[40+rsp]
+ rol r12d,30
+ add edi,eax
+ rol ebp,1
+ mov DWORD PTR[52+rsp],ebp
+ mov edx,DWORD PTR[56+rsp]
+ mov eax,r12d
+ mov ecx,edi
+ xor edx,DWORD PTR[rsp]
+ xor eax,r11d
+ rol ecx,5
+ lea esi,DWORD PTR[1859775393+rsi*1+rbp]
+ xor edx,DWORD PTR[24+rsp]
+ xor eax,r13d
+ add esi,ecx
+ xor edx,DWORD PTR[44+rsp]
+ rol r11d,30
+ add esi,eax
+ rol edx,1
+ mov DWORD PTR[56+rsp],edx
+ mov ebp,DWORD PTR[60+rsp]
+ mov eax,r11d
+ mov ecx,esi
+ xor ebp,DWORD PTR[4+rsp]
+ xor eax,edi
+ rol ecx,5
+ lea r13d,DWORD PTR[1859775393+r13*1+rdx]
+ xor ebp,DWORD PTR[28+rsp]
+ xor eax,r12d
+ add r13d,ecx
+ xor ebp,DWORD PTR[48+rsp]
+ rol edi,30
+ add r13d,eax
+ rol ebp,1
+ mov DWORD PTR[60+rsp],ebp
+ mov edx,DWORD PTR[rsp]
+ mov eax,edi
+ mov ecx,r13d
+ xor edx,DWORD PTR[8+rsp]
+ xor eax,esi
+ rol ecx,5
+ lea r12d,DWORD PTR[1859775393+r12*1+rbp]
+ xor edx,DWORD PTR[32+rsp]
+ xor eax,r11d
+ add r12d,ecx
+ xor edx,DWORD PTR[52+rsp]
+ rol esi,30
+ add r12d,eax
+ rol edx,1
+ mov DWORD PTR[rsp],edx
+ mov ebp,DWORD PTR[4+rsp]
+ mov eax,esi
+ mov ecx,r12d
+ xor ebp,DWORD PTR[12+rsp]
+ xor eax,r13d
+ rol ecx,5
+ lea r11d,DWORD PTR[1859775393+r11*1+rdx]
+ xor ebp,DWORD PTR[36+rsp]
+ xor eax,edi
+ add r11d,ecx
+ xor ebp,DWORD PTR[56+rsp]
+ rol r13d,30
+ add r11d,eax
+ rol ebp,1
+ mov DWORD PTR[4+rsp],ebp
+ mov edx,DWORD PTR[8+rsp]
+ mov eax,r13d
+ mov ecx,r11d
+ xor edx,DWORD PTR[16+rsp]
+ xor eax,r12d
+ rol ecx,5
+ lea edi,DWORD PTR[1859775393+rdi*1+rbp]
+ xor edx,DWORD PTR[40+rsp]
+ xor eax,esi
+ add edi,ecx
+ xor edx,DWORD PTR[60+rsp]
+ rol r12d,30
+ add edi,eax
+ rol edx,1
+ mov DWORD PTR[8+rsp],edx
+ mov ebp,DWORD PTR[12+rsp]
+ mov eax,r12d
+ mov ecx,edi
+ xor ebp,DWORD PTR[20+rsp]
+ xor eax,r11d
+ rol ecx,5
+ lea esi,DWORD PTR[1859775393+rsi*1+rdx]
+ xor ebp,DWORD PTR[44+rsp]
+ xor eax,r13d
+ add esi,ecx
+ xor ebp,DWORD PTR[rsp]
+ rol r11d,30
+ add esi,eax
+ rol ebp,1
+ mov DWORD PTR[12+rsp],ebp
+ mov edx,DWORD PTR[16+rsp]
+ mov eax,r11d
+ mov ecx,esi
+ xor edx,DWORD PTR[24+rsp]
+ xor eax,edi
+ rol ecx,5
+ lea r13d,DWORD PTR[1859775393+r13*1+rbp]
+ xor edx,DWORD PTR[48+rsp]
+ xor eax,r12d
+ add r13d,ecx
+ xor edx,DWORD PTR[4+rsp]
+ rol edi,30
+ add r13d,eax
+ rol edx,1
+ mov DWORD PTR[16+rsp],edx
+ mov ebp,DWORD PTR[20+rsp]
+ mov eax,edi
+ mov ecx,r13d
+ xor ebp,DWORD PTR[28+rsp]
+ xor eax,esi
+ rol ecx,5
+ lea r12d,DWORD PTR[1859775393+r12*1+rdx]
+ xor ebp,DWORD PTR[52+rsp]
+ xor eax,r11d
+ add r12d,ecx
+ xor ebp,DWORD PTR[8+rsp]
+ rol esi,30
+ add r12d,eax
+ rol ebp,1
+ mov DWORD PTR[20+rsp],ebp
+ mov edx,DWORD PTR[24+rsp]
+ mov eax,esi
+ mov ecx,r12d
+ xor edx,DWORD PTR[32+rsp]
+ xor eax,r13d
+ rol ecx,5
+ lea r11d,DWORD PTR[1859775393+r11*1+rbp]
+ xor edx,DWORD PTR[56+rsp]
+ xor eax,edi
+ add r11d,ecx
+ xor edx,DWORD PTR[12+rsp]
+ rol r13d,30
+ add r11d,eax
+ rol edx,1
+ mov DWORD PTR[24+rsp],edx
+ mov ebp,DWORD PTR[28+rsp]
+ mov eax,r13d
+ mov ecx,r11d
+ xor ebp,DWORD PTR[36+rsp]
+ xor eax,r12d
+ rol ecx,5
+ lea edi,DWORD PTR[1859775393+rdi*1+rdx]
+ xor ebp,DWORD PTR[60+rsp]
+ xor eax,esi
+ add edi,ecx
+ xor ebp,DWORD PTR[16+rsp]
+ rol r12d,30
+ add edi,eax
+ rol ebp,1
+ mov DWORD PTR[28+rsp],ebp
+ mov edx,DWORD PTR[32+rsp]
+ mov eax,r12d
+ mov ecx,edi
+ xor edx,DWORD PTR[40+rsp]
+ xor eax,r11d
+ rol ecx,5
+ lea esi,DWORD PTR[1859775393+rsi*1+rbp]
+ xor edx,DWORD PTR[rsp]
+ xor eax,r13d
+ add esi,ecx
+ xor edx,DWORD PTR[20+rsp]
+ rol r11d,30
+ add esi,eax
+ rol edx,1
+ mov DWORD PTR[32+rsp],edx
+ mov ebp,DWORD PTR[36+rsp]
+ mov eax,r11d
mov ebx,r11d
- mov eax,DWORD PTR[20+r9]
- mov edx,edi
- xor ebx,r12d
- bswap eax
- rol edx,5
- and ebx,ebp
- mov DWORD PTR[20+rsp],eax
- add esi,edx
+ xor ebp,DWORD PTR[44+rsp]
+ and eax,r12d
+ mov ecx,esi
+ xor ebp,DWORD PTR[4+rsp]
xor ebx,r12d
- rol ebp,30
- add esi,ebx
- lea edx,DWORD PTR[05a827999h+r12*1+rax]
- mov ebx,ebp
- mov eax,DWORD PTR[24+r9]
- mov r12d,esi
- xor ebx,r11d
- bswap eax
- rol r12d,5
+ lea r13d,DWORD PTR[((-1894007588))+r13*1+rdx]
+ rol ecx,5
+ xor ebp,DWORD PTR[24+rsp]
+ add r13d,eax
and ebx,edi
- mov DWORD PTR[24+rsp],eax
- add edx,r12d
- xor ebx,r11d
+ rol ebp,1
+ add r13d,ebx
rol edi,30
- add edx,ebx
- lea r12d,DWORD PTR[05a827999h+r11*1+rax]
+ mov DWORD PTR[36+rsp],ebp
+ add r13d,ecx
+ mov edx,DWORD PTR[40+rsp]
+ mov eax,edi
mov ebx,edi
- mov eax,DWORD PTR[28+r9]
- mov r11d,edx
- xor ebx,ebp
- bswap eax
- rol r11d,5
+ xor edx,DWORD PTR[48+rsp]
+ and eax,r11d
+ mov ecx,r13d
+ xor edx,DWORD PTR[8+rsp]
+ xor ebx,r11d
+ lea r12d,DWORD PTR[((-1894007588))+r12*1+rbp]
+ rol ecx,5
+ xor edx,DWORD PTR[28+rsp]
+ add r12d,eax
and ebx,esi
- mov DWORD PTR[28+rsp],eax
- add r12d,r11d
- xor ebx,ebp
- rol esi,30
+ rol edx,1
add r12d,ebx
- lea r11d,DWORD PTR[05a827999h+rbp*1+rax]
+ rol esi,30
+ mov DWORD PTR[40+rsp],edx
+ add r12d,ecx
+ mov ebp,DWORD PTR[44+rsp]
+ mov eax,esi
mov ebx,esi
- mov eax,DWORD PTR[32+r9]
- mov ebp,r12d
- xor ebx,edi
- bswap eax
- rol ebp,5
- and ebx,edx
- mov DWORD PTR[32+rsp],eax
- add r11d,ebp
+ xor ebp,DWORD PTR[52+rsp]
+ and eax,edi
+ mov ecx,r12d
+ xor ebp,DWORD PTR[12+rsp]
xor ebx,edi
- rol edx,30
+ lea r11d,DWORD PTR[((-1894007588))+r11*1+rdx]
+ rol ecx,5
+ xor ebp,DWORD PTR[32+rsp]
+ add r11d,eax
+ and ebx,r13d
+ rol ebp,1
add r11d,ebx
- lea ebp,DWORD PTR[05a827999h+rdi*1+rax]
- mov ebx,edx
- mov eax,DWORD PTR[36+r9]
- mov edi,r11d
+ rol r13d,30
+ mov DWORD PTR[44+rsp],ebp
+ add r11d,ecx
+ mov edx,DWORD PTR[48+rsp]
+ mov eax,r13d
+ mov ebx,r13d
+ xor edx,DWORD PTR[56+rsp]
+ and eax,esi
+ mov ecx,r11d
+ xor edx,DWORD PTR[16+rsp]
xor ebx,esi
- bswap eax
- rol edi,5
+ lea edi,DWORD PTR[((-1894007588))+rdi*1+rbp]
+ rol ecx,5
+ xor edx,DWORD PTR[36+rsp]
+ add edi,eax
and ebx,r12d
- mov DWORD PTR[36+rsp],eax
- add ebp,edi
- xor ebx,esi
+ rol edx,1
+ add edi,ebx
rol r12d,30
- add ebp,ebx
- lea edi,DWORD PTR[05a827999h+rsi*1+rax]
+ mov DWORD PTR[48+rsp],edx
+ add edi,ecx
+ mov ebp,DWORD PTR[52+rsp]
+ mov eax,r12d
mov ebx,r12d
- mov eax,DWORD PTR[40+r9]
- mov esi,ebp
- xor ebx,edx
- bswap eax
- rol esi,5
+ xor ebp,DWORD PTR[60+rsp]
+ and eax,r13d
+ mov ecx,edi
+ xor ebp,DWORD PTR[20+rsp]
+ xor ebx,r13d
+ lea esi,DWORD PTR[((-1894007588))+rsi*1+rdx]
+ rol ecx,5
+ xor ebp,DWORD PTR[40+rsp]
+ add esi,eax
and ebx,r11d
- mov DWORD PTR[40+rsp],eax
- add edi,esi
- xor ebx,edx
+ rol ebp,1
+ add esi,ebx
rol r11d,30
- add edi,ebx
- lea esi,DWORD PTR[05a827999h+rdx*1+rax]
+ mov DWORD PTR[52+rsp],ebp
+ add esi,ecx
+ mov edx,DWORD PTR[56+rsp]
+ mov eax,r11d
mov ebx,r11d
- mov eax,DWORD PTR[44+r9]
- mov edx,edi
- xor ebx,r12d
- bswap eax
- rol edx,5
- and ebx,ebp
- mov DWORD PTR[44+rsp],eax
- add esi,edx
+ xor edx,DWORD PTR[rsp]
+ and eax,r12d
+ mov ecx,esi
+ xor edx,DWORD PTR[24+rsp]
xor ebx,r12d
- rol ebp,30
- add esi,ebx
- lea edx,DWORD PTR[05a827999h+r12*1+rax]
- mov ebx,ebp
- mov eax,DWORD PTR[48+r9]
- mov r12d,esi
- xor ebx,r11d
- bswap eax
- rol r12d,5
+ lea r13d,DWORD PTR[((-1894007588))+r13*1+rbp]
+ rol ecx,5
+ xor edx,DWORD PTR[44+rsp]
+ add r13d,eax
and ebx,edi
- mov DWORD PTR[48+rsp],eax
- add edx,r12d
- xor ebx,r11d
+ rol edx,1
+ add r13d,ebx
rol edi,30
- add edx,ebx
- lea r12d,DWORD PTR[05a827999h+r11*1+rax]
+ mov DWORD PTR[56+rsp],edx
+ add r13d,ecx
+ mov ebp,DWORD PTR[60+rsp]
+ mov eax,edi
mov ebx,edi
- mov eax,DWORD PTR[52+r9]
- mov r11d,edx
- xor ebx,ebp
- bswap eax
- rol r11d,5
+ xor ebp,DWORD PTR[4+rsp]
+ and eax,r11d
+ mov ecx,r13d
+ xor ebp,DWORD PTR[28+rsp]
+ xor ebx,r11d
+ lea r12d,DWORD PTR[((-1894007588))+r12*1+rdx]
+ rol ecx,5
+ xor ebp,DWORD PTR[48+rsp]
+ add r12d,eax
and ebx,esi
- mov DWORD PTR[52+rsp],eax
- add r12d,r11d
- xor ebx,ebp
- rol esi,30
+ rol ebp,1
add r12d,ebx
- lea r11d,DWORD PTR[05a827999h+rbp*1+rax]
+ rol esi,30
+ mov DWORD PTR[60+rsp],ebp
+ add r12d,ecx
+ mov edx,DWORD PTR[rsp]
+ mov eax,esi
mov ebx,esi
- mov eax,DWORD PTR[56+r9]
- mov ebp,r12d
- xor ebx,edi
- bswap eax
- rol ebp,5
- and ebx,edx
- mov DWORD PTR[56+rsp],eax
- add r11d,ebp
+ xor edx,DWORD PTR[8+rsp]
+ and eax,edi
+ mov ecx,r12d
+ xor edx,DWORD PTR[32+rsp]
xor ebx,edi
- rol edx,30
+ lea r11d,DWORD PTR[((-1894007588))+r11*1+rbp]
+ rol ecx,5
+ xor edx,DWORD PTR[52+rsp]
+ add r11d,eax
+ and ebx,r13d
+ rol edx,1
add r11d,ebx
- lea ebp,DWORD PTR[05a827999h+rdi*1+rax]
- mov ebx,edx
- mov eax,DWORD PTR[60+r9]
- mov edi,r11d
+ rol r13d,30
+ mov DWORD PTR[rsp],edx
+ add r11d,ecx
+ mov ebp,DWORD PTR[4+rsp]
+ mov eax,r13d
+ mov ebx,r13d
+ xor ebp,DWORD PTR[12+rsp]
+ and eax,esi
+ mov ecx,r11d
+ xor ebp,DWORD PTR[36+rsp]
xor ebx,esi
- bswap eax
- rol edi,5
+ lea edi,DWORD PTR[((-1894007588))+rdi*1+rdx]
+ rol ecx,5
+ xor ebp,DWORD PTR[56+rsp]
+ add edi,eax
and ebx,r12d
- mov DWORD PTR[60+rsp],eax
- add ebp,edi
- xor ebx,esi
+ rol ebp,1
+ add edi,ebx
rol r12d,30
- add ebp,ebx
- lea edi,DWORD PTR[05a827999h+rsi*1+rax]
- mov eax,DWORD PTR[rsp]
+ mov DWORD PTR[4+rsp],ebp
+ add edi,ecx
+ mov edx,DWORD PTR[8+rsp]
+ mov eax,r12d
mov ebx,r12d
- mov esi,ebp
- xor eax,DWORD PTR[8+rsp]
- xor ebx,edx
- rol esi,5
- xor eax,DWORD PTR[32+rsp]
+ xor edx,DWORD PTR[16+rsp]
+ and eax,r13d
+ mov ecx,edi
+ xor edx,DWORD PTR[40+rsp]
+ xor ebx,r13d
+ lea esi,DWORD PTR[((-1894007588))+rsi*1+rbp]
+ rol ecx,5
+ xor edx,DWORD PTR[60+rsp]
+ add esi,eax
and ebx,r11d
- add edi,esi
- xor eax,DWORD PTR[52+rsp]
- xor ebx,edx
+ rol edx,1
+ add esi,ebx
rol r11d,30
- add edi,ebx
- rol eax,1
- mov DWORD PTR[rsp],eax
- lea esi,DWORD PTR[05a827999h+rdx*1+rax]
- mov eax,DWORD PTR[4+rsp]
+ mov DWORD PTR[8+rsp],edx
+ add esi,ecx
+ mov ebp,DWORD PTR[12+rsp]
+ mov eax,r11d
mov ebx,r11d
- mov edx,edi
- xor eax,DWORD PTR[12+rsp]
- xor ebx,r12d
- rol edx,5
- xor eax,DWORD PTR[36+rsp]
- and ebx,ebp
- add esi,edx
- xor eax,DWORD PTR[56+rsp]
+ xor ebp,DWORD PTR[20+rsp]
+ and eax,r12d
+ mov ecx,esi
+ xor ebp,DWORD PTR[44+rsp]
xor ebx,r12d
- rol ebp,30
- add esi,ebx
- rol eax,1
- mov DWORD PTR[4+rsp],eax
- lea edx,DWORD PTR[05a827999h+r12*1+rax]
- mov eax,DWORD PTR[8+rsp]
- mov ebx,ebp
- mov r12d,esi
- xor eax,DWORD PTR[16+rsp]
- xor ebx,r11d
- rol r12d,5
- xor eax,DWORD PTR[40+rsp]
+ lea r13d,DWORD PTR[((-1894007588))+r13*1+rdx]
+ rol ecx,5
+ xor ebp,DWORD PTR[rsp]
+ add r13d,eax
and ebx,edi
- add edx,r12d
- xor eax,DWORD PTR[60+rsp]
- xor ebx,r11d
+ rol ebp,1
+ add r13d,ebx
rol edi,30
- add edx,ebx
- rol eax,1
- mov DWORD PTR[8+rsp],eax
- lea r12d,DWORD PTR[05a827999h+r11*1+rax]
- mov eax,DWORD PTR[12+rsp]
+ mov DWORD PTR[12+rsp],ebp
+ add r13d,ecx
+ mov edx,DWORD PTR[16+rsp]
+ mov eax,edi
mov ebx,edi
- mov r11d,edx
- xor eax,DWORD PTR[20+rsp]
- xor ebx,ebp
- rol r11d,5
- xor eax,DWORD PTR[44+rsp]
+ xor edx,DWORD PTR[24+rsp]
+ and eax,r11d
+ mov ecx,r13d
+ xor edx,DWORD PTR[48+rsp]
+ xor ebx,r11d
+ lea r12d,DWORD PTR[((-1894007588))+r12*1+rbp]
+ rol ecx,5
+ xor edx,DWORD PTR[4+rsp]
+ add r12d,eax
and ebx,esi
- add r12d,r11d
- xor eax,DWORD PTR[rsp]
- xor ebx,ebp
- rol esi,30
+ rol edx,1
add r12d,ebx
- rol eax,1
- mov DWORD PTR[12+rsp],eax
- lea r11d,DWORD PTR[05a827999h+rbp*1+rax]
- mov eax,DWORD PTR[16+rsp]
+ rol esi,30
+ mov DWORD PTR[16+rsp],edx
+ add r12d,ecx
+ mov ebp,DWORD PTR[20+rsp]
+ mov eax,esi
mov ebx,esi
- mov ebp,r12d
- xor eax,DWORD PTR[24+rsp]
- xor ebx,edi
- rol ebp,5
- xor eax,DWORD PTR[48+rsp]
- and ebx,edx
- add r11d,ebp
- xor eax,DWORD PTR[4+rsp]
+ xor ebp,DWORD PTR[28+rsp]
+ and eax,edi
+ mov ecx,r12d
+ xor ebp,DWORD PTR[52+rsp]
xor ebx,edi
- rol edx,30
+ lea r11d,DWORD PTR[((-1894007588))+r11*1+rdx]
+ rol ecx,5
+ xor ebp,DWORD PTR[8+rsp]
+ add r11d,eax
+ and ebx,r13d
+ rol ebp,1
add r11d,ebx
- rol eax,1
- mov DWORD PTR[16+rsp],eax
- lea ebp,DWORD PTR[1859775393+rdi*1+rax]
- mov eax,DWORD PTR[20+rsp]
- mov ebx,edx
- mov edi,r11d
- xor eax,DWORD PTR[28+rsp]
- xor ebx,r12d
- rol edi,5
- xor eax,DWORD PTR[52+rsp]
+ rol r13d,30
+ mov DWORD PTR[20+rsp],ebp
+ add r11d,ecx
+ mov edx,DWORD PTR[24+rsp]
+ mov eax,r13d
+ mov ebx,r13d
+ xor edx,DWORD PTR[32+rsp]
+ and eax,esi
+ mov ecx,r11d
+ xor edx,DWORD PTR[56+rsp]
xor ebx,esi
- add ebp,edi
- xor eax,DWORD PTR[8+rsp]
+ lea edi,DWORD PTR[((-1894007588))+rdi*1+rbp]
+ rol ecx,5
+ xor edx,DWORD PTR[12+rsp]
+ add edi,eax
+ and ebx,r12d
+ rol edx,1
+ add edi,ebx
rol r12d,30
- add ebp,ebx
- rol eax,1
- mov DWORD PTR[20+rsp],eax
- lea edi,DWORD PTR[1859775393+rsi*1+rax]
- mov eax,DWORD PTR[24+rsp]
+ mov DWORD PTR[24+rsp],edx
+ add edi,ecx
+ mov ebp,DWORD PTR[28+rsp]
+ mov eax,r12d
mov ebx,r12d
- mov esi,ebp
- xor eax,DWORD PTR[32+rsp]
- xor ebx,r11d
- rol esi,5
- xor eax,DWORD PTR[56+rsp]
- xor ebx,edx
- add edi,esi
- xor eax,DWORD PTR[12+rsp]
+ xor ebp,DWORD PTR[36+rsp]
+ and eax,r13d
+ mov ecx,edi
+ xor ebp,DWORD PTR[60+rsp]
+ xor ebx,r13d
+ lea esi,DWORD PTR[((-1894007588))+rsi*1+rdx]
+ rol ecx,5
+ xor ebp,DWORD PTR[16+rsp]
+ add esi,eax
+ and ebx,r11d
+ rol ebp,1
+ add esi,ebx
rol r11d,30
- add edi,ebx
- rol eax,1
- mov DWORD PTR[24+rsp],eax
- lea esi,DWORD PTR[1859775393+rdx*1+rax]
- mov eax,DWORD PTR[28+rsp]
+ mov DWORD PTR[28+rsp],ebp
+ add esi,ecx
+ mov edx,DWORD PTR[32+rsp]
+ mov eax,r11d
mov ebx,r11d
- mov edx,edi
- xor eax,DWORD PTR[36+rsp]
- xor ebx,ebp
- rol edx,5
- xor eax,DWORD PTR[60+rsp]
+ xor edx,DWORD PTR[40+rsp]
+ and eax,r12d
+ mov ecx,esi
+ xor edx,DWORD PTR[rsp]
xor ebx,r12d
- add esi,edx
- xor eax,DWORD PTR[16+rsp]
- rol ebp,30
- add esi,ebx
- rol eax,1
- mov DWORD PTR[28+rsp],eax
- lea edx,DWORD PTR[1859775393+r12*1+rax]
- mov eax,DWORD PTR[32+rsp]
- mov ebx,ebp
- mov r12d,esi
- xor eax,DWORD PTR[40+rsp]
- xor ebx,edi
- rol r12d,5
- xor eax,DWORD PTR[rsp]
- xor ebx,r11d
- add edx,r12d
- xor eax,DWORD PTR[20+rsp]
+ lea r13d,DWORD PTR[((-1894007588))+r13*1+rbp]
+ rol ecx,5
+ xor edx,DWORD PTR[20+rsp]
+ add r13d,eax
+ and ebx,edi
+ rol edx,1
+ add r13d,ebx
rol edi,30
- add edx,ebx
- rol eax,1
- mov DWORD PTR[32+rsp],eax
- lea r12d,DWORD PTR[1859775393+r11*1+rax]
- mov eax,DWORD PTR[36+rsp]
+ mov DWORD PTR[32+rsp],edx
+ add r13d,ecx
+ mov ebp,DWORD PTR[36+rsp]
+ mov eax,edi
mov ebx,edi
- mov r11d,edx
- xor eax,DWORD PTR[44+rsp]
- xor ebx,esi
- rol r11d,5
- xor eax,DWORD PTR[4+rsp]
- xor ebx,ebp
- add r12d,r11d
- xor eax,DWORD PTR[24+rsp]
- rol esi,30
+ xor ebp,DWORD PTR[44+rsp]
+ and eax,r11d
+ mov ecx,r13d
+ xor ebp,DWORD PTR[4+rsp]
+ xor ebx,r11d
+ lea r12d,DWORD PTR[((-1894007588))+r12*1+rdx]
+ rol ecx,5
+ xor ebp,DWORD PTR[24+rsp]
+ add r12d,eax
+ and ebx,esi
+ rol ebp,1
add r12d,ebx
- rol eax,1
- mov DWORD PTR[36+rsp],eax
- lea r11d,DWORD PTR[1859775393+rbp*1+rax]
- mov eax,DWORD PTR[40+rsp]
+ rol esi,30
+ mov DWORD PTR[36+rsp],ebp
+ add r12d,ecx
+ mov edx,DWORD PTR[40+rsp]
+ mov eax,esi
mov ebx,esi
- mov ebp,r12d
- xor eax,DWORD PTR[48+rsp]
- xor ebx,edx
- rol ebp,5
- xor eax,DWORD PTR[8+rsp]
+ xor edx,DWORD PTR[48+rsp]
+ and eax,edi
+ mov ecx,r12d
+ xor edx,DWORD PTR[8+rsp]
xor ebx,edi
- add r11d,ebp
- xor eax,DWORD PTR[28+rsp]
- rol edx,30
+ lea r11d,DWORD PTR[((-1894007588))+r11*1+rbp]
+ rol ecx,5
+ xor edx,DWORD PTR[28+rsp]
+ add r11d,eax
+ and ebx,r13d
+ rol edx,1
add r11d,ebx
- rol eax,1
- mov DWORD PTR[40+rsp],eax
- lea ebp,DWORD PTR[1859775393+rdi*1+rax]
- mov eax,DWORD PTR[44+rsp]
- mov ebx,edx
- mov edi,r11d
- xor eax,DWORD PTR[52+rsp]
- xor ebx,r12d
- rol edi,5
- xor eax,DWORD PTR[12+rsp]
+ rol r13d,30
+ mov DWORD PTR[40+rsp],edx
+ add r11d,ecx
+ mov ebp,DWORD PTR[44+rsp]
+ mov eax,r13d
+ mov ebx,r13d
+ xor ebp,DWORD PTR[52+rsp]
+ and eax,esi
+ mov ecx,r11d
+ xor ebp,DWORD PTR[12+rsp]
xor ebx,esi
- add ebp,edi
- xor eax,DWORD PTR[32+rsp]
+ lea edi,DWORD PTR[((-1894007588))+rdi*1+rdx]
+ rol ecx,5
+ xor ebp,DWORD PTR[32+rsp]
+ add edi,eax
+ and ebx,r12d
+ rol ebp,1
+ add edi,ebx
rol r12d,30
- add ebp,ebx
- rol eax,1
- mov DWORD PTR[44+rsp],eax
- lea edi,DWORD PTR[1859775393+rsi*1+rax]
- mov eax,DWORD PTR[48+rsp]
+ mov DWORD PTR[44+rsp],ebp
+ add edi,ecx
+ mov edx,DWORD PTR[48+rsp]
+ mov eax,r12d
mov ebx,r12d
- mov esi,ebp
- xor eax,DWORD PTR[56+rsp]
- xor ebx,r11d
- rol esi,5
- xor eax,DWORD PTR[16+rsp]
- xor ebx,edx
- add edi,esi
- xor eax,DWORD PTR[36+rsp]
- rol r11d,30
- add edi,ebx
- rol eax,1
- mov DWORD PTR[48+rsp],eax
- lea esi,DWORD PTR[1859775393+rdx*1+rax]
- mov eax,DWORD PTR[52+rsp]
- mov ebx,r11d
- mov edx,edi
- xor eax,DWORD PTR[60+rsp]
- xor ebx,ebp
- rol edx,5
- xor eax,DWORD PTR[20+rsp]
- xor ebx,r12d
- add esi,edx
- xor eax,DWORD PTR[40+rsp]
- rol ebp,30
+ xor edx,DWORD PTR[56+rsp]
+ and eax,r13d
+ mov ecx,edi
+ xor edx,DWORD PTR[16+rsp]
+ xor ebx,r13d
+ lea esi,DWORD PTR[((-1894007588))+rsi*1+rbp]
+ rol ecx,5
+ xor edx,DWORD PTR[36+rsp]
+ add esi,eax
+ and ebx,r11d
+ rol edx,1
add esi,ebx
- rol eax,1
- mov DWORD PTR[52+rsp],eax
- lea edx,DWORD PTR[1859775393+r12*1+rax]
- mov eax,DWORD PTR[56+rsp]
- mov ebx,ebp
- mov r12d,esi
- xor eax,DWORD PTR[rsp]
- xor ebx,edi
- rol r12d,5
- xor eax,DWORD PTR[24+rsp]
- xor ebx,r11d
- add edx,r12d
- xor eax,DWORD PTR[44+rsp]
+ rol r11d,30
+ mov DWORD PTR[48+rsp],edx
+ add esi,ecx
+ mov ebp,DWORD PTR[52+rsp]
+ mov eax,r11d
+ mov ecx,esi
+ xor ebp,DWORD PTR[60+rsp]
+ xor eax,edi
+ rol ecx,5
+ lea r13d,DWORD PTR[((-899497514))+r13*1+rdx]
+ xor ebp,DWORD PTR[20+rsp]
+ xor eax,r12d
+ add r13d,ecx
+ xor ebp,DWORD PTR[40+rsp]
rol edi,30
- add edx,ebx
- rol eax,1
- mov DWORD PTR[56+rsp],eax
- lea r12d,DWORD PTR[1859775393+r11*1+rax]
- mov eax,DWORD PTR[60+rsp]
- mov ebx,edi
- mov r11d,edx
- xor eax,DWORD PTR[4+rsp]
- xor ebx,esi
- rol r11d,5
- xor eax,DWORD PTR[28+rsp]
- xor ebx,ebp
- add r12d,r11d
- xor eax,DWORD PTR[48+rsp]
+ add r13d,eax
+ rol ebp,1
+ mov DWORD PTR[52+rsp],ebp
+ mov edx,DWORD PTR[56+rsp]
+ mov eax,edi
+ mov ecx,r13d
+ xor edx,DWORD PTR[rsp]
+ xor eax,esi
+ rol ecx,5
+ lea r12d,DWORD PTR[((-899497514))+r12*1+rbp]
+ xor edx,DWORD PTR[24+rsp]
+ xor eax,r11d
+ add r12d,ecx
+ xor edx,DWORD PTR[44+rsp]
rol esi,30
- add r12d,ebx
- rol eax,1
- mov DWORD PTR[60+rsp],eax
- lea r11d,DWORD PTR[1859775393+rbp*1+rax]
- mov eax,DWORD PTR[rsp]
- mov ebx,esi
- mov ebp,r12d
- xor eax,DWORD PTR[8+rsp]
- xor ebx,edx
- rol ebp,5
- xor eax,DWORD PTR[32+rsp]
- xor ebx,edi
- add r11d,ebp
- xor eax,DWORD PTR[52+rsp]
- rol edx,30
- add r11d,ebx
- rol eax,1
- mov DWORD PTR[rsp],eax
- lea ebp,DWORD PTR[1859775393+rdi*1+rax]
- mov eax,DWORD PTR[4+rsp]
- mov ebx,edx
- mov edi,r11d
- xor eax,DWORD PTR[12+rsp]
- xor ebx,r12d
- rol edi,5
- xor eax,DWORD PTR[36+rsp]
- xor ebx,esi
- add ebp,edi
- xor eax,DWORD PTR[56+rsp]
+ add r12d,eax
+ rol edx,1
+ mov DWORD PTR[56+rsp],edx
+ mov ebp,DWORD PTR[60+rsp]
+ mov eax,esi
+ mov ecx,r12d
+ xor ebp,DWORD PTR[4+rsp]
+ xor eax,r13d
+ rol ecx,5
+ lea r11d,DWORD PTR[((-899497514))+r11*1+rdx]
+ xor ebp,DWORD PTR[28+rsp]
+ xor eax,edi
+ add r11d,ecx
+ xor ebp,DWORD PTR[48+rsp]
+ rol r13d,30
+ add r11d,eax
+ rol ebp,1
+ mov DWORD PTR[60+rsp],ebp
+ mov edx,DWORD PTR[rsp]
+ mov eax,r13d
+ mov ecx,r11d
+ xor edx,DWORD PTR[8+rsp]
+ xor eax,r12d
+ rol ecx,5
+ lea edi,DWORD PTR[((-899497514))+rdi*1+rbp]
+ xor edx,DWORD PTR[32+rsp]
+ xor eax,esi
+ add edi,ecx
+ xor edx,DWORD PTR[52+rsp]
rol r12d,30
- add ebp,ebx
- rol eax,1
- mov DWORD PTR[4+rsp],eax
- lea edi,DWORD PTR[1859775393+rsi*1+rax]
- mov eax,DWORD PTR[8+rsp]
- mov ebx,r12d
- mov esi,ebp
- xor eax,DWORD PTR[16+rsp]
- xor ebx,r11d
- rol esi,5
- xor eax,DWORD PTR[40+rsp]
- xor ebx,edx
- add edi,esi
- xor eax,DWORD PTR[60+rsp]
+ add edi,eax
+ rol edx,1
+ mov DWORD PTR[rsp],edx
+ mov ebp,DWORD PTR[4+rsp]
+ mov eax,r12d
+ mov ecx,edi
+ xor ebp,DWORD PTR[12+rsp]
+ xor eax,r11d
+ rol ecx,5
+ lea esi,DWORD PTR[((-899497514))+rsi*1+rdx]
+ xor ebp,DWORD PTR[36+rsp]
+ xor eax,r13d
+ add esi,ecx
+ xor ebp,DWORD PTR[56+rsp]
rol r11d,30
- add edi,ebx
- rol eax,1
- mov DWORD PTR[8+rsp],eax
- lea esi,DWORD PTR[1859775393+rdx*1+rax]
- mov eax,DWORD PTR[12+rsp]
- mov ebx,r11d
- mov edx,edi
- xor eax,DWORD PTR[20+rsp]
- xor ebx,ebp
- rol edx,5
- xor eax,DWORD PTR[44+rsp]
- xor ebx,r12d
- add esi,edx
- xor eax,DWORD PTR[rsp]
- rol ebp,30
- add esi,ebx
- rol eax,1
- mov DWORD PTR[12+rsp],eax
- lea edx,DWORD PTR[1859775393+r12*1+rax]
- mov eax,DWORD PTR[16+rsp]
- mov ebx,ebp
- mov r12d,esi
- xor eax,DWORD PTR[24+rsp]
- xor ebx,edi
- rol r12d,5
- xor eax,DWORD PTR[48+rsp]
- xor ebx,r11d
- add edx,r12d
- xor eax,DWORD PTR[4+rsp]
+ add esi,eax
+ rol ebp,1
+ mov DWORD PTR[4+rsp],ebp
+ mov edx,DWORD PTR[8+rsp]
+ mov eax,r11d
+ mov ecx,esi
+ xor edx,DWORD PTR[16+rsp]
+ xor eax,edi
+ rol ecx,5
+ lea r13d,DWORD PTR[((-899497514))+r13*1+rbp]
+ xor edx,DWORD PTR[40+rsp]
+ xor eax,r12d
+ add r13d,ecx
+ xor edx,DWORD PTR[60+rsp]
rol edi,30
- add edx,ebx
- rol eax,1
- mov DWORD PTR[16+rsp],eax
- lea r12d,DWORD PTR[1859775393+r11*1+rax]
- mov eax,DWORD PTR[20+rsp]
- mov ebx,edi
- mov r11d,edx
- xor eax,DWORD PTR[28+rsp]
- xor ebx,esi
- rol r11d,5
- xor eax,DWORD PTR[52+rsp]
- xor ebx,ebp
- add r12d,r11d
- xor eax,DWORD PTR[8+rsp]
+ add r13d,eax
+ rol edx,1
+ mov DWORD PTR[8+rsp],edx
+ mov ebp,DWORD PTR[12+rsp]
+ mov eax,edi
+ mov ecx,r13d
+ xor ebp,DWORD PTR[20+rsp]
+ xor eax,esi
+ rol ecx,5
+ lea r12d,DWORD PTR[((-899497514))+r12*1+rdx]
+ xor ebp,DWORD PTR[44+rsp]
+ xor eax,r11d
+ add r12d,ecx
+ xor ebp,DWORD PTR[rsp]
rol esi,30
- add r12d,ebx
- rol eax,1
- mov DWORD PTR[20+rsp],eax
- lea r11d,DWORD PTR[1859775393+rbp*1+rax]
- mov eax,DWORD PTR[24+rsp]
- mov ebx,esi
- mov ebp,r12d
- xor eax,DWORD PTR[32+rsp]
- xor ebx,edx
- rol ebp,5
- xor eax,DWORD PTR[56+rsp]
- xor ebx,edi
- add r11d,ebp
- xor eax,DWORD PTR[12+rsp]
- rol edx,30
- add r11d,ebx
- rol eax,1
- mov DWORD PTR[24+rsp],eax
- lea ebp,DWORD PTR[1859775393+rdi*1+rax]
- mov eax,DWORD PTR[28+rsp]
- mov ebx,edx
- mov edi,r11d
- xor eax,DWORD PTR[36+rsp]
- xor ebx,r12d
- rol edi,5
- xor eax,DWORD PTR[60+rsp]
- xor ebx,esi
- add ebp,edi
- xor eax,DWORD PTR[16+rsp]
+ add r12d,eax
+ rol ebp,1
+ mov DWORD PTR[12+rsp],ebp
+ mov edx,DWORD PTR[16+rsp]
+ mov eax,esi
+ mov ecx,r12d
+ xor edx,DWORD PTR[24+rsp]
+ xor eax,r13d
+ rol ecx,5
+ lea r11d,DWORD PTR[((-899497514))+r11*1+rbp]
+ xor edx,DWORD PTR[48+rsp]
+ xor eax,edi
+ add r11d,ecx
+ xor edx,DWORD PTR[4+rsp]
+ rol r13d,30
+ add r11d,eax
+ rol edx,1
+ mov DWORD PTR[16+rsp],edx
+ mov ebp,DWORD PTR[20+rsp]
+ mov eax,r13d
+ mov ecx,r11d
+ xor ebp,DWORD PTR[28+rsp]
+ xor eax,r12d
+ rol ecx,5
+ lea edi,DWORD PTR[((-899497514))+rdi*1+rdx]
+ xor ebp,DWORD PTR[52+rsp]
+ xor eax,esi
+ add edi,ecx
+ xor ebp,DWORD PTR[8+rsp]
rol r12d,30
- add ebp,ebx
- rol eax,1
- mov DWORD PTR[28+rsp],eax
- lea edi,DWORD PTR[1859775393+rsi*1+rax]
- mov eax,DWORD PTR[32+rsp]
- mov ebx,r12d
- mov esi,ebp
- xor eax,DWORD PTR[40+rsp]
- xor ebx,r11d
- rol esi,5
- xor eax,DWORD PTR[rsp]
- xor ebx,edx
- add edi,esi
- xor eax,DWORD PTR[20+rsp]
- rol r11d,30
- add edi,ebx
- rol eax,1
- mov DWORD PTR[32+rsp],eax
- lea esi,DWORD PTR[08f1bbcdch+rdx*1+rax]
- mov eax,DWORD PTR[36+rsp]
- mov ebx,ebp
- mov ecx,ebp
- xor eax,DWORD PTR[44+rsp]
- mov edx,edi
- and ebx,r11d
- xor eax,DWORD PTR[4+rsp]
- or ecx,r11d
- rol edx,5
- xor eax,DWORD PTR[24+rsp]
- and ecx,r12d
- add esi,edx
- rol eax,1
- or ebx,ecx
- rol ebp,30
- mov DWORD PTR[36+rsp],eax
- add esi,ebx
- lea edx,DWORD PTR[08f1bbcdch+r12*1+rax]
- mov eax,DWORD PTR[40+rsp]
- mov ebx,edi
+ add edi,eax
+ rol ebp,1
+ mov DWORD PTR[20+rsp],ebp
+ mov edx,DWORD PTR[24+rsp]
+ mov eax,r12d
mov ecx,edi
- xor eax,DWORD PTR[48+rsp]
- mov r12d,esi
- and ebx,ebp
- xor eax,DWORD PTR[8+rsp]
- or ecx,ebp
- rol r12d,5
- xor eax,DWORD PTR[28+rsp]
- and ecx,r11d
- add edx,r12d
- rol eax,1
- or ebx,ecx
- rol edi,30
- mov DWORD PTR[40+rsp],eax
- add edx,ebx
- lea r12d,DWORD PTR[08f1bbcdch+r11*1+rax]
- mov eax,DWORD PTR[44+rsp]
- mov ebx,esi
+ xor edx,DWORD PTR[32+rsp]
+ xor eax,r11d
+ rol ecx,5
+ lea esi,DWORD PTR[((-899497514))+rsi*1+rbp]
+ xor edx,DWORD PTR[56+rsp]
+ xor eax,r13d
+ add esi,ecx
+ xor edx,DWORD PTR[12+rsp]
+ rol r11d,30
+ add esi,eax
+ rol edx,1
+ mov DWORD PTR[24+rsp],edx
+ mov ebp,DWORD PTR[28+rsp]
+ mov eax,r11d
mov ecx,esi
- xor eax,DWORD PTR[52+rsp]
- mov r11d,edx
- and ebx,edi
- xor eax,DWORD PTR[12+rsp]
- or ecx,edi
- rol r11d,5
- xor eax,DWORD PTR[32+rsp]
- and ecx,ebp
- add r12d,r11d
- rol eax,1
- or ebx,ecx
+ xor ebp,DWORD PTR[36+rsp]
+ xor eax,edi
+ rol ecx,5
+ lea r13d,DWORD PTR[((-899497514))+r13*1+rdx]
+ xor ebp,DWORD PTR[60+rsp]
+ xor eax,r12d
+ add r13d,ecx
+ xor ebp,DWORD PTR[16+rsp]
+ rol edi,30
+ add r13d,eax
+ rol ebp,1
+ mov DWORD PTR[28+rsp],ebp
+ mov edx,DWORD PTR[32+rsp]
+ mov eax,edi
+ mov ecx,r13d
+ xor edx,DWORD PTR[40+rsp]
+ xor eax,esi
+ rol ecx,5
+ lea r12d,DWORD PTR[((-899497514))+r12*1+rbp]
+ xor edx,DWORD PTR[rsp]
+ xor eax,r11d
+ add r12d,ecx
+ xor edx,DWORD PTR[20+rsp]
rol esi,30
- mov DWORD PTR[44+rsp],eax
- add r12d,ebx
- lea r11d,DWORD PTR[08f1bbcdch+rbp*1+rax]
- mov eax,DWORD PTR[48+rsp]
- mov ebx,edx
- mov ecx,edx
- xor eax,DWORD PTR[56+rsp]
- mov ebp,r12d
- and ebx,esi
- xor eax,DWORD PTR[16+rsp]
- or ecx,esi
- rol ebp,5
- xor eax,DWORD PTR[36+rsp]
- and ecx,edi
- add r11d,ebp
- rol eax,1
- or ebx,ecx
- rol edx,30
- mov DWORD PTR[48+rsp],eax
- add r11d,ebx
- lea ebp,DWORD PTR[08f1bbcdch+rdi*1+rax]
- mov eax,DWORD PTR[52+rsp]
- mov ebx,r12d
+ add r12d,eax
+ rol edx,1
+ mov DWORD PTR[32+rsp],edx
+ mov ebp,DWORD PTR[36+rsp]
+ mov eax,esi
mov ecx,r12d
- xor eax,DWORD PTR[60+rsp]
- mov edi,r11d
- and ebx,edx
- xor eax,DWORD PTR[20+rsp]
- or ecx,edx
- rol edi,5
- xor eax,DWORD PTR[40+rsp]
- and ecx,esi
- add ebp,edi
- rol eax,1
- or ebx,ecx
- rol r12d,30
- mov DWORD PTR[52+rsp],eax
- add ebp,ebx
- lea edi,DWORD PTR[08f1bbcdch+rsi*1+rax]
- mov eax,DWORD PTR[56+rsp]
- mov ebx,r11d
+ xor ebp,DWORD PTR[44+rsp]
+ xor eax,r13d
+ rol ecx,5
+ lea r11d,DWORD PTR[((-899497514))+r11*1+rdx]
+ xor ebp,DWORD PTR[4+rsp]
+ xor eax,edi
+ add r11d,ecx
+ xor ebp,DWORD PTR[24+rsp]
+ rol r13d,30
+ add r11d,eax
+ rol ebp,1
+ mov DWORD PTR[36+rsp],ebp
+ mov edx,DWORD PTR[40+rsp]
+ mov eax,r13d
mov ecx,r11d
- xor eax,DWORD PTR[rsp]
- mov esi,ebp
- and ebx,r12d
- xor eax,DWORD PTR[24+rsp]
- or ecx,r12d
- rol esi,5
- xor eax,DWORD PTR[44+rsp]
- and ecx,edx
- add edi,esi
- rol eax,1
- or ebx,ecx
- rol r11d,30
- mov DWORD PTR[56+rsp],eax
- add edi,ebx
- lea esi,DWORD PTR[08f1bbcdch+rdx*1+rax]
- mov eax,DWORD PTR[60+rsp]
- mov ebx,ebp
- mov ecx,ebp
- xor eax,DWORD PTR[4+rsp]
- mov edx,edi
- and ebx,r11d
- xor eax,DWORD PTR[28+rsp]
- or ecx,r11d
- rol edx,5
- xor eax,DWORD PTR[48+rsp]
- and ecx,r12d
- add esi,edx
- rol eax,1
- or ebx,ecx
- rol ebp,30
- mov DWORD PTR[60+rsp],eax
- add esi,ebx
- lea edx,DWORD PTR[08f1bbcdch+r12*1+rax]
- mov eax,DWORD PTR[rsp]
- mov ebx,edi
+ xor edx,DWORD PTR[48+rsp]
+ xor eax,r12d
+ rol ecx,5
+ lea edi,DWORD PTR[((-899497514))+rdi*1+rbp]
+ xor edx,DWORD PTR[8+rsp]
+ xor eax,esi
+ add edi,ecx
+ xor edx,DWORD PTR[28+rsp]
+ rol r12d,30
+ add edi,eax
+ rol edx,1
+ mov DWORD PTR[40+rsp],edx
+ mov ebp,DWORD PTR[44+rsp]
+ mov eax,r12d
mov ecx,edi
- xor eax,DWORD PTR[8+rsp]
- mov r12d,esi
- and ebx,ebp
- xor eax,DWORD PTR[32+rsp]
- or ecx,ebp
- rol r12d,5
- xor eax,DWORD PTR[52+rsp]
- and ecx,r11d
- add edx,r12d
- rol eax,1
- or ebx,ecx
- rol edi,30
- mov DWORD PTR[rsp],eax
- add edx,ebx
- lea r12d,DWORD PTR[08f1bbcdch+r11*1+rax]
- mov eax,DWORD PTR[4+rsp]
- mov ebx,esi
+ xor ebp,DWORD PTR[52+rsp]
+ xor eax,r11d
+ rol ecx,5
+ lea esi,DWORD PTR[((-899497514))+rsi*1+rdx]
+ xor ebp,DWORD PTR[12+rsp]
+ xor eax,r13d
+ add esi,ecx
+ xor ebp,DWORD PTR[32+rsp]
+ rol r11d,30
+ add esi,eax
+ rol ebp,1
+ mov DWORD PTR[44+rsp],ebp
+ mov edx,DWORD PTR[48+rsp]
+ mov eax,r11d
mov ecx,esi
- xor eax,DWORD PTR[12+rsp]
- mov r11d,edx
- and ebx,edi
- xor eax,DWORD PTR[36+rsp]
- or ecx,edi
- rol r11d,5
- xor eax,DWORD PTR[56+rsp]
- and ecx,ebp
- add r12d,r11d
- rol eax,1
- or ebx,ecx
+ xor edx,DWORD PTR[56+rsp]
+ xor eax,edi
+ rol ecx,5
+ lea r13d,DWORD PTR[((-899497514))+r13*1+rbp]
+ xor edx,DWORD PTR[16+rsp]
+ xor eax,r12d
+ add r13d,ecx
+ xor edx,DWORD PTR[36+rsp]
+ rol edi,30
+ add r13d,eax
+ rol edx,1
+ mov DWORD PTR[48+rsp],edx
+ mov ebp,DWORD PTR[52+rsp]
+ mov eax,edi
+ mov ecx,r13d
+ xor ebp,DWORD PTR[60+rsp]
+ xor eax,esi
+ rol ecx,5
+ lea r12d,DWORD PTR[((-899497514))+r12*1+rdx]
+ xor ebp,DWORD PTR[20+rsp]
+ xor eax,r11d
+ add r12d,ecx
+ xor ebp,DWORD PTR[40+rsp]
rol esi,30
- mov DWORD PTR[4+rsp],eax
- add r12d,ebx
- lea r11d,DWORD PTR[08f1bbcdch+rbp*1+rax]
- mov eax,DWORD PTR[8+rsp]
- mov ebx,edx
- mov ecx,edx
- xor eax,DWORD PTR[16+rsp]
- mov ebp,r12d
- and ebx,esi
- xor eax,DWORD PTR[40+rsp]
- or ecx,esi
- rol ebp,5
- xor eax,DWORD PTR[60+rsp]
- and ecx,edi
- add r11d,ebp
- rol eax,1
- or ebx,ecx
- rol edx,30
- mov DWORD PTR[8+rsp],eax
- add r11d,ebx
- lea ebp,DWORD PTR[08f1bbcdch+rdi*1+rax]
- mov eax,DWORD PTR[12+rsp]
- mov ebx,r12d
+ add r12d,eax
+ rol ebp,1
+ mov edx,DWORD PTR[56+rsp]
+ mov eax,esi
mov ecx,r12d
- xor eax,DWORD PTR[20+rsp]
- mov edi,r11d
- and ebx,edx
- xor eax,DWORD PTR[44+rsp]
- or ecx,edx
- rol edi,5
- xor eax,DWORD PTR[rsp]
- and ecx,esi
- add ebp,edi
- rol eax,1
- or ebx,ecx
- rol r12d,30
- mov DWORD PTR[12+rsp],eax
- add ebp,ebx
- lea edi,DWORD PTR[08f1bbcdch+rsi*1+rax]
- mov eax,DWORD PTR[16+rsp]
- mov ebx,r11d
+ xor edx,DWORD PTR[rsp]
+ xor eax,r13d
+ rol ecx,5
+ lea r11d,DWORD PTR[((-899497514))+r11*1+rbp]
+ xor edx,DWORD PTR[24+rsp]
+ xor eax,edi
+ add r11d,ecx
+ xor edx,DWORD PTR[44+rsp]
+ rol r13d,30
+ add r11d,eax
+ rol edx,1
+ mov ebp,DWORD PTR[60+rsp]
+ mov eax,r13d
mov ecx,r11d
- xor eax,DWORD PTR[24+rsp]
- mov esi,ebp
- and ebx,r12d
- xor eax,DWORD PTR[48+rsp]
- or ecx,r12d
- rol esi,5
- xor eax,DWORD PTR[4+rsp]
- and ecx,edx
- add edi,esi
- rol eax,1
- or ebx,ecx
+ xor ebp,DWORD PTR[4+rsp]
+ xor eax,r12d
+ rol ecx,5
+ lea edi,DWORD PTR[((-899497514))+rdi*1+rdx]
+ xor ebp,DWORD PTR[28+rsp]
+ xor eax,esi
+ add edi,ecx
+ xor ebp,DWORD PTR[48+rsp]
+ rol r12d,30
+ add edi,eax
+ rol ebp,1
+ mov eax,r12d
+ mov ecx,edi
+ xor eax,r11d
+ lea esi,DWORD PTR[((-899497514))+rsi*1+rbp]
+ rol ecx,5
+ xor eax,r13d
+ add esi,ecx
rol r11d,30
- mov DWORD PTR[16+rsp],eax
- add edi,ebx
- lea esi,DWORD PTR[08f1bbcdch+rdx*1+rax]
- mov eax,DWORD PTR[20+rsp]
- mov ebx,ebp
- mov ecx,ebp
- xor eax,DWORD PTR[28+rsp]
- mov edx,edi
- and ebx,r11d
- xor eax,DWORD PTR[52+rsp]
- or ecx,r11d
+ add esi,eax
+ add esi,DWORD PTR[r8]
+ add edi,DWORD PTR[4+r8]
+ add r11d,DWORD PTR[8+r8]
+ add r12d,DWORD PTR[12+r8]
+ add r13d,DWORD PTR[16+r8]
+ mov DWORD PTR[r8],esi
+ mov DWORD PTR[4+r8],edi
+ mov DWORD PTR[8+r8],r11d
+ mov DWORD PTR[12+r8],r12d
+ mov DWORD PTR[16+r8],r13d
+
+ sub r10,1
+ lea r9,QWORD PTR[64+r9]
+ jnz $L$loop
+
+ mov rsi,QWORD PTR[64+rsp]
+ mov r13,QWORD PTR[rsi]
+ mov r12,QWORD PTR[8+rsi]
+ mov rbp,QWORD PTR[16+rsi]
+ mov rbx,QWORD PTR[24+rsi]
+ lea rsp,QWORD PTR[32+rsi]
+$L$epilogue::
+ mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD PTR[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_sha1_block_data_order::
+sha1_block_data_order ENDP
+
+ALIGN 16
+sha1_block_data_order_ssse3 PROC PRIVATE
+ mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
+ mov QWORD PTR[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_sha1_block_data_order_ssse3::
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+
+
+_ssse3_shortcut::
+ push rbx
+ push rbp
+ push r12
+ lea rsp,QWORD PTR[((-144))+rsp]
+ movaps XMMWORD PTR[(64+0)+rsp],xmm6
+ movaps XMMWORD PTR[(64+16)+rsp],xmm7
+ movaps XMMWORD PTR[(64+32)+rsp],xmm8
+ movaps XMMWORD PTR[(64+48)+rsp],xmm9
+ movaps XMMWORD PTR[(64+64)+rsp],xmm10
+$L$prologue_ssse3::
+ mov r8,rdi
+ mov r9,rsi
+ mov r10,rdx
+
+ shl r10,6
+ add r10,r9
+ lea r11,QWORD PTR[K_XX_XX]
+
+ mov eax,DWORD PTR[r8]
+ mov ebx,DWORD PTR[4+r8]
+ mov ecx,DWORD PTR[8+r8]
+ mov edx,DWORD PTR[12+r8]
+ mov esi,ebx
+ mov ebp,DWORD PTR[16+r8]
+
+ movdqa xmm6,XMMWORD PTR[64+r11]
+ movdqa xmm9,XMMWORD PTR[r11]
+ movdqu xmm0,XMMWORD PTR[r9]
+ movdqu xmm1,XMMWORD PTR[16+r9]
+ movdqu xmm2,XMMWORD PTR[32+r9]
+ movdqu xmm3,XMMWORD PTR[48+r9]
+DB 102,15,56,0,198
+ add r9,64
+DB 102,15,56,0,206
+DB 102,15,56,0,214
+DB 102,15,56,0,222
+ paddd xmm0,xmm9
+ paddd xmm1,xmm9
+ paddd xmm2,xmm9
+ movdqa XMMWORD PTR[rsp],xmm0
+ psubd xmm0,xmm9
+ movdqa XMMWORD PTR[16+rsp],xmm1
+ psubd xmm1,xmm9
+ movdqa XMMWORD PTR[32+rsp],xmm2
+ psubd xmm2,xmm9
+ jmp $L$oop_ssse3
+ALIGN 16
+$L$oop_ssse3::
+ movdqa xmm4,xmm1
+ add ebp,DWORD PTR[rsp]
+ xor ecx,edx
+ movdqa xmm8,xmm3
+DB 102,15,58,15,224,8
+ mov edi,eax
+ rol eax,5
+ paddd xmm9,xmm3
+ and esi,ecx
+ xor ecx,edx
+ psrldq xmm8,4
+ xor esi,edx
+ add ebp,eax
+ pxor xmm4,xmm0
+ ror ebx,2
+ add ebp,esi
+ pxor xmm8,xmm2
+ add edx,DWORD PTR[4+rsp]
+ xor ebx,ecx
+ mov esi,ebp
+ rol ebp,5
+ pxor xmm4,xmm8
+ and edi,ebx
+ xor ebx,ecx
+ movdqa XMMWORD PTR[48+rsp],xmm9
+ xor edi,ecx
+ add edx,ebp
+ movdqa xmm10,xmm4
+ movdqa xmm8,xmm4
+ ror eax,7
+ add edx,edi
+ add ecx,DWORD PTR[8+rsp]
+ xor eax,ebx
+ pslldq xmm10,12
+ paddd xmm4,xmm4
+ mov edi,edx
rol edx,5
- xor eax,DWORD PTR[8+rsp]
- and ecx,r12d
- add esi,edx
- rol eax,1
- or ebx,ecx
- rol ebp,30
- mov DWORD PTR[20+rsp],eax
- add esi,ebx
- lea edx,DWORD PTR[08f1bbcdch+r12*1+rax]
- mov eax,DWORD PTR[24+rsp]
- mov ebx,edi
- mov ecx,edi
- xor eax,DWORD PTR[32+rsp]
- mov r12d,esi
- and ebx,ebp
- xor eax,DWORD PTR[56+rsp]
- or ecx,ebp
- rol r12d,5
- xor eax,DWORD PTR[12+rsp]
- and ecx,r11d
- add edx,r12d
- rol eax,1
- or ebx,ecx
- rol edi,30
- mov DWORD PTR[24+rsp],eax
- add edx,ebx
- lea r12d,DWORD PTR[08f1bbcdch+r11*1+rax]
- mov eax,DWORD PTR[28+rsp]
- mov ebx,esi
- mov ecx,esi
- xor eax,DWORD PTR[36+rsp]
- mov r11d,edx
- and ebx,edi
- xor eax,DWORD PTR[60+rsp]
- or ecx,edi
- rol r11d,5
- xor eax,DWORD PTR[16+rsp]
- and ecx,ebp
- add r12d,r11d
- rol eax,1
- or ebx,ecx
- rol esi,30
- mov DWORD PTR[28+rsp],eax
- add r12d,ebx
- lea r11d,DWORD PTR[08f1bbcdch+rbp*1+rax]
- mov eax,DWORD PTR[32+rsp]
- mov ebx,edx
- mov ecx,edx
- xor eax,DWORD PTR[40+rsp]
- mov ebp,r12d
- and ebx,esi
- xor eax,DWORD PTR[rsp]
- or ecx,esi
+ and esi,eax
+ xor eax,ebx
+ psrld xmm8,31
+ xor esi,ebx
+ add ecx,edx
+ movdqa xmm9,xmm10
+ ror ebp,7
+ add ecx,esi
+ psrld xmm10,30
+ por xmm4,xmm8
+ add ebx,DWORD PTR[12+rsp]
+ xor ebp,eax
+ mov esi,ecx
+ rol ecx,5
+ pslld xmm9,2
+ pxor xmm4,xmm10
+ and edi,ebp
+ xor ebp,eax
+ movdqa xmm10,XMMWORD PTR[r11]
+ xor edi,eax
+ add ebx,ecx
+ pxor xmm4,xmm9
+ ror edx,7
+ add ebx,edi
+ movdqa xmm5,xmm2
+ add eax,DWORD PTR[16+rsp]
+ xor edx,ebp
+ movdqa xmm9,xmm4
+DB 102,15,58,15,233,8
+ mov edi,ebx
+ rol ebx,5
+ paddd xmm10,xmm4
+ and esi,edx
+ xor edx,ebp
+ psrldq xmm9,4
+ xor esi,ebp
+ add eax,ebx
+ pxor xmm5,xmm1
+ ror ecx,7
+ add eax,esi
+ pxor xmm9,xmm3
+ add ebp,DWORD PTR[20+rsp]
+ xor ecx,edx
+ mov esi,eax
+ rol eax,5
+ pxor xmm5,xmm9
+ and edi,ecx
+ xor ecx,edx
+ movdqa XMMWORD PTR[rsp],xmm10
+ xor edi,edx
+ add ebp,eax
+ movdqa xmm8,xmm5
+ movdqa xmm9,xmm5
+ ror ebx,7
+ add ebp,edi
+ add edx,DWORD PTR[24+rsp]
+ xor ebx,ecx
+ pslldq xmm8,12
+ paddd xmm5,xmm5
+ mov edi,ebp
rol ebp,5
- xor eax,DWORD PTR[20+rsp]
- and ecx,edi
- add r11d,ebp
- rol eax,1
- or ebx,ecx
- rol edx,30
- mov DWORD PTR[32+rsp],eax
- add r11d,ebx
- lea ebp,DWORD PTR[08f1bbcdch+rdi*1+rax]
- mov eax,DWORD PTR[36+rsp]
- mov ebx,r12d
- mov ecx,r12d
- xor eax,DWORD PTR[44+rsp]
- mov edi,r11d
- and ebx,edx
- xor eax,DWORD PTR[4+rsp]
- or ecx,edx
- rol edi,5
- xor eax,DWORD PTR[24+rsp]
- and ecx,esi
+ and esi,ebx
+ xor ebx,ecx
+ psrld xmm9,31
+ xor esi,ecx
+ add edx,ebp
+ movdqa xmm10,xmm8
+ ror eax,7
+ add edx,esi
+ psrld xmm8,30
+ por xmm5,xmm9
+ add ecx,DWORD PTR[28+rsp]
+ xor eax,ebx
+ mov esi,edx
+ rol edx,5
+ pslld xmm10,2
+ pxor xmm5,xmm8
+ and edi,eax
+ xor eax,ebx
+ movdqa xmm8,XMMWORD PTR[16+r11]
+ xor edi,ebx
+ add ecx,edx
+ pxor xmm5,xmm10
+ ror ebp,7
+ add ecx,edi
+ movdqa xmm6,xmm3
+ add ebx,DWORD PTR[32+rsp]
+ xor ebp,eax
+ movdqa xmm10,xmm5
+DB 102,15,58,15,242,8
+ mov edi,ecx
+ rol ecx,5
+ paddd xmm8,xmm5
+ and esi,ebp
+ xor ebp,eax
+ psrldq xmm10,4
+ xor esi,eax
+ add ebx,ecx
+ pxor xmm6,xmm2
+ ror edx,7
+ add ebx,esi
+ pxor xmm10,xmm4
+ add eax,DWORD PTR[36+rsp]
+ xor edx,ebp
+ mov esi,ebx
+ rol ebx,5
+ pxor xmm6,xmm10
+ and edi,edx
+ xor edx,ebp
+ movdqa XMMWORD PTR[16+rsp],xmm8
+ xor edi,ebp
+ add eax,ebx
+ movdqa xmm9,xmm6
+ movdqa xmm10,xmm6
+ ror ecx,7
+ add eax,edi
+ add ebp,DWORD PTR[40+rsp]
+ xor ecx,edx
+ pslldq xmm9,12
+ paddd xmm6,xmm6
+ mov edi,eax
+ rol eax,5
+ and esi,ecx
+ xor ecx,edx
+ psrld xmm10,31
+ xor esi,edx
+ add ebp,eax
+ movdqa xmm8,xmm9
+ ror ebx,7
+ add ebp,esi
+ psrld xmm9,30
+ por xmm6,xmm10
+ add edx,DWORD PTR[44+rsp]
+ xor ebx,ecx
+ mov esi,ebp
+ rol ebp,5
+ pslld xmm8,2
+ pxor xmm6,xmm9
+ and edi,ebx
+ xor ebx,ecx
+ movdqa xmm9,XMMWORD PTR[16+r11]
+ xor edi,ecx
+ add edx,ebp
+ pxor xmm6,xmm8
+ ror eax,7
+ add edx,edi
+ movdqa xmm7,xmm4
+ add ecx,DWORD PTR[48+rsp]
+ xor eax,ebx
+ movdqa xmm8,xmm6
+DB 102,15,58,15,251,8
+ mov edi,edx
+ rol edx,5
+ paddd xmm9,xmm6
+ and esi,eax
+ xor eax,ebx
+ psrldq xmm8,4
+ xor esi,ebx
+ add ecx,edx
+ pxor xmm7,xmm3
+ ror ebp,7
+ add ecx,esi
+ pxor xmm8,xmm5
+ add ebx,DWORD PTR[52+rsp]
+ xor ebp,eax
+ mov esi,ecx
+ rol ecx,5
+ pxor xmm7,xmm8
+ and edi,ebp
+ xor ebp,eax
+ movdqa XMMWORD PTR[32+rsp],xmm9
+ xor edi,eax
+ add ebx,ecx
+ movdqa xmm10,xmm7
+ movdqa xmm8,xmm7
+ ror edx,7
+ add ebx,edi
+ add eax,DWORD PTR[56+rsp]
+ xor edx,ebp
+ pslldq xmm10,12
+ paddd xmm7,xmm7
+ mov edi,ebx
+ rol ebx,5
+ and esi,edx
+ xor edx,ebp
+ psrld xmm8,31
+ xor esi,ebp
+ add eax,ebx
+ movdqa xmm9,xmm10
+ ror ecx,7
+ add eax,esi
+ psrld xmm10,30
+ por xmm7,xmm8
+ add ebp,DWORD PTR[60+rsp]
+ xor ecx,edx
+ mov esi,eax
+ rol eax,5
+ pslld xmm9,2
+ pxor xmm7,xmm10
+ and edi,ecx
+ xor ecx,edx
+ movdqa xmm10,XMMWORD PTR[16+r11]
+ xor edi,edx
+ add ebp,eax
+ pxor xmm7,xmm9
+ ror ebx,7
add ebp,edi
- rol eax,1
- or ebx,ecx
- rol r12d,30
- mov DWORD PTR[36+rsp],eax
- add ebp,ebx
- lea edi,DWORD PTR[08f1bbcdch+rsi*1+rax]
- mov eax,DWORD PTR[40+rsp]
- mov ebx,r11d
- mov ecx,r11d
- xor eax,DWORD PTR[48+rsp]
+ movdqa xmm9,xmm7
+ add edx,DWORD PTR[rsp]
+ pxor xmm0,xmm4
+DB 102,68,15,58,15,206,8
+ xor ebx,ecx
+ mov edi,ebp
+ rol ebp,5
+ pxor xmm0,xmm1
+ and esi,ebx
+ xor ebx,ecx
+ movdqa xmm8,xmm10
+ paddd xmm10,xmm7
+ xor esi,ecx
+ add edx,ebp
+ pxor xmm0,xmm9
+ ror eax,7
+ add edx,esi
+ add ecx,DWORD PTR[4+rsp]
+ xor eax,ebx
+ movdqa xmm9,xmm0
+ movdqa XMMWORD PTR[48+rsp],xmm10
+ mov esi,edx
+ rol edx,5
+ and edi,eax
+ xor eax,ebx
+ pslld xmm0,2
+ xor edi,ebx
+ add ecx,edx
+ psrld xmm9,30
+ ror ebp,7
+ add ecx,edi
+ add ebx,DWORD PTR[8+rsp]
+ xor ebp,eax
+ mov edi,ecx
+ rol ecx,5
+ por xmm0,xmm9
+ and esi,ebp
+ xor ebp,eax
+ movdqa xmm10,xmm0
+ xor esi,eax
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ add eax,DWORD PTR[12+rsp]
+ xor edx,ebp
+ mov esi,ebx
+ rol ebx,5
+ and edi,edx
+ xor edx,ebp
+ xor edi,ebp
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ add ebp,DWORD PTR[16+rsp]
+ pxor xmm1,xmm5
+DB 102,68,15,58,15,215,8
+ xor esi,edx
+ mov edi,eax
+ rol eax,5
+ pxor xmm1,xmm2
+ xor esi,ecx
+ add ebp,eax
+ movdqa xmm9,xmm8
+ paddd xmm8,xmm0
+ ror ebx,7
+ add ebp,esi
+ pxor xmm1,xmm10
+ add edx,DWORD PTR[20+rsp]
+ xor edi,ecx
mov esi,ebp
- and ebx,r12d
- xor eax,DWORD PTR[8+rsp]
- or ecx,r12d
- rol esi,5
- xor eax,DWORD PTR[28+rsp]
- and ecx,edx
- add edi,esi
- rol eax,1
- or ebx,ecx
- rol r11d,30
- mov DWORD PTR[40+rsp],eax
- add edi,ebx
- lea esi,DWORD PTR[08f1bbcdch+rdx*1+rax]
- mov eax,DWORD PTR[44+rsp]
- mov ebx,ebp
- mov ecx,ebp
- xor eax,DWORD PTR[52+rsp]
- mov edx,edi
- and ebx,r11d
- xor eax,DWORD PTR[12+rsp]
- or ecx,r11d
+ rol ebp,5
+ movdqa xmm10,xmm1
+ movdqa XMMWORD PTR[rsp],xmm8
+ xor edi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,edi
+ pslld xmm1,2
+ add ecx,DWORD PTR[24+rsp]
+ xor esi,ebx
+ psrld xmm10,30
+ mov edi,edx
rol edx,5
- xor eax,DWORD PTR[32+rsp]
- and ecx,r12d
- add esi,edx
- rol eax,1
- or ebx,ecx
- rol ebp,30
- mov DWORD PTR[44+rsp],eax
- add esi,ebx
- lea edx,DWORD PTR[08f1bbcdch+r12*1+rax]
- mov eax,DWORD PTR[48+rsp]
- mov ebx,edi
- mov ecx,edi
- xor eax,DWORD PTR[56+rsp]
- mov r12d,esi
- and ebx,ebp
- xor eax,DWORD PTR[16+rsp]
- or ecx,ebp
- rol r12d,5
- xor eax,DWORD PTR[36+rsp]
- and ecx,r11d
- add edx,r12d
- rol eax,1
- or ebx,ecx
- rol edi,30
- mov DWORD PTR[48+rsp],eax
- add edx,ebx
- lea r12d,DWORD PTR[3395469782+r11*1+rax]
- mov eax,DWORD PTR[52+rsp]
- mov ebx,edi
- mov r11d,edx
- xor eax,DWORD PTR[60+rsp]
- xor ebx,esi
- rol r11d,5
- xor eax,DWORD PTR[20+rsp]
- xor ebx,ebp
- add r12d,r11d
- xor eax,DWORD PTR[40+rsp]
- rol esi,30
- add r12d,ebx
- rol eax,1
- mov DWORD PTR[52+rsp],eax
- lea r11d,DWORD PTR[3395469782+rbp*1+rax]
- mov eax,DWORD PTR[56+rsp]
- mov ebx,esi
- mov ebp,r12d
- xor eax,DWORD PTR[rsp]
- xor ebx,edx
+ xor esi,eax
+ add ecx,edx
+ ror ebp,7
+ add ecx,esi
+ por xmm1,xmm10
+ add ebx,DWORD PTR[28+rsp]
+ xor edi,eax
+ movdqa xmm8,xmm1
+ mov esi,ecx
+ rol ecx,5
+ xor edi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,edi
+ add eax,DWORD PTR[32+rsp]
+ pxor xmm2,xmm6
+DB 102,68,15,58,15,192,8
+ xor esi,ebp
+ mov edi,ebx
+ rol ebx,5
+ pxor xmm2,xmm3
+ xor esi,edx
+ add eax,ebx
+ movdqa xmm10,XMMWORD PTR[32+r11]
+ paddd xmm9,xmm1
+ ror ecx,7
+ add eax,esi
+ pxor xmm2,xmm8
+ add ebp,DWORD PTR[36+rsp]
+ xor edi,edx
+ mov esi,eax
+ rol eax,5
+ movdqa xmm8,xmm2
+ movdqa XMMWORD PTR[16+rsp],xmm9
+ xor edi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,edi
+ pslld xmm2,2
+ add edx,DWORD PTR[40+rsp]
+ xor esi,ecx
+ psrld xmm8,30
+ mov edi,ebp
rol ebp,5
- xor eax,DWORD PTR[24+rsp]
- xor ebx,edi
- add r11d,ebp
- xor eax,DWORD PTR[44+rsp]
- rol edx,30
- add r11d,ebx
- rol eax,1
- mov DWORD PTR[56+rsp],eax
- lea ebp,DWORD PTR[3395469782+rdi*1+rax]
- mov eax,DWORD PTR[60+rsp]
- mov ebx,edx
- mov edi,r11d
- xor eax,DWORD PTR[4+rsp]
- xor ebx,r12d
- rol edi,5
- xor eax,DWORD PTR[28+rsp]
- xor ebx,esi
+ xor esi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,esi
+ por xmm2,xmm8
+ add ecx,DWORD PTR[44+rsp]
+ xor edi,ebx
+ movdqa xmm9,xmm2
+ mov esi,edx
+ rol edx,5
+ xor edi,eax
+ add ecx,edx
+ ror ebp,7
+ add ecx,edi
+ add ebx,DWORD PTR[48+rsp]
+ pxor xmm3,xmm7
+DB 102,68,15,58,15,201,8
+ xor esi,eax
+ mov edi,ecx
+ rol ecx,5
+ pxor xmm3,xmm4
+ xor esi,ebp
+ add ebx,ecx
+ movdqa xmm8,xmm10
+ paddd xmm10,xmm2
+ ror edx,7
+ add ebx,esi
+ pxor xmm3,xmm9
+ add eax,DWORD PTR[52+rsp]
+ xor edi,ebp
+ mov esi,ebx
+ rol ebx,5
+ movdqa xmm9,xmm3
+ movdqa XMMWORD PTR[32+rsp],xmm10
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ pslld xmm3,2
+ add ebp,DWORD PTR[56+rsp]
+ xor esi,edx
+ psrld xmm9,30
+ mov edi,eax
+ rol eax,5
+ xor esi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,esi
+ por xmm3,xmm9
+ add edx,DWORD PTR[60+rsp]
+ xor edi,ecx
+ movdqa xmm10,xmm3
+ mov esi,ebp
+ rol ebp,5
+ xor edi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,edi
+ add ecx,DWORD PTR[rsp]
+ pxor xmm4,xmm0
+DB 102,68,15,58,15,210,8
+ xor esi,ebx
+ mov edi,edx
+ rol edx,5
+ pxor xmm4,xmm5
+ xor esi,eax
+ add ecx,edx
+ movdqa xmm9,xmm8
+ paddd xmm8,xmm3
+ ror ebp,7
+ add ecx,esi
+ pxor xmm4,xmm10
+ add ebx,DWORD PTR[4+rsp]
+ xor edi,eax
+ mov esi,ecx
+ rol ecx,5
+ movdqa xmm10,xmm4
+ movdqa XMMWORD PTR[48+rsp],xmm8
+ xor edi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,edi
+ pslld xmm4,2
+ add eax,DWORD PTR[8+rsp]
+ xor esi,ebp
+ psrld xmm10,30
+ mov edi,ebx
+ rol ebx,5
+ xor esi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,esi
+ por xmm4,xmm10
+ add ebp,DWORD PTR[12+rsp]
+ xor edi,edx
+ movdqa xmm8,xmm4
+ mov esi,eax
+ rol eax,5
+ xor edi,ecx
+ add ebp,eax
+ ror ebx,7
add ebp,edi
- xor eax,DWORD PTR[48+rsp]
- rol r12d,30
- add ebp,ebx
- rol eax,1
- mov DWORD PTR[60+rsp],eax
- lea edi,DWORD PTR[3395469782+rsi*1+rax]
- mov eax,DWORD PTR[rsp]
- mov ebx,r12d
+ add edx,DWORD PTR[16+rsp]
+ pxor xmm5,xmm1
+DB 102,68,15,58,15,195,8
+ xor esi,ecx
+ mov edi,ebp
+ rol ebp,5
+ pxor xmm5,xmm6
+ xor esi,ebx
+ add edx,ebp
+ movdqa xmm10,xmm9
+ paddd xmm9,xmm4
+ ror eax,7
+ add edx,esi
+ pxor xmm5,xmm8
+ add ecx,DWORD PTR[20+rsp]
+ xor edi,ebx
+ mov esi,edx
+ rol edx,5
+ movdqa xmm8,xmm5
+ movdqa XMMWORD PTR[rsp],xmm9
+ xor edi,eax
+ add ecx,edx
+ ror ebp,7
+ add ecx,edi
+ pslld xmm5,2
+ add ebx,DWORD PTR[24+rsp]
+ xor esi,eax
+ psrld xmm8,30
+ mov edi,ecx
+ rol ecx,5
+ xor esi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ por xmm5,xmm8
+ add eax,DWORD PTR[28+rsp]
+ xor edi,ebp
+ movdqa xmm9,xmm5
+ mov esi,ebx
+ rol ebx,5
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ mov edi,ecx
+ pxor xmm6,xmm2
+DB 102,68,15,58,15,204,8
+ xor ecx,edx
+ add ebp,DWORD PTR[32+rsp]
+ and edi,edx
+ pxor xmm6,xmm7
+ and esi,ecx
+ ror ebx,7
+ movdqa xmm8,xmm10
+ paddd xmm10,xmm5
+ add ebp,edi
+ mov edi,eax
+ pxor xmm6,xmm9
+ rol eax,5
+ add ebp,esi
+ xor ecx,edx
+ add ebp,eax
+ movdqa xmm9,xmm6
+ movdqa XMMWORD PTR[16+rsp],xmm10
+ mov esi,ebx
+ xor ebx,ecx
+ add edx,DWORD PTR[36+rsp]
+ and esi,ecx
+ pslld xmm6,2
+ and edi,ebx
+ ror eax,7
+ psrld xmm9,30
+ add edx,esi
mov esi,ebp
- xor eax,DWORD PTR[8+rsp]
- xor ebx,r11d
- rol esi,5
- xor eax,DWORD PTR[32+rsp]
- xor ebx,edx
- add edi,esi
- xor eax,DWORD PTR[52+rsp]
- rol r11d,30
- add edi,ebx
- rol eax,1
- mov DWORD PTR[rsp],eax
- lea esi,DWORD PTR[3395469782+rdx*1+rax]
- mov eax,DWORD PTR[4+rsp]
- mov ebx,r11d
- mov edx,edi
- xor eax,DWORD PTR[12+rsp]
- xor ebx,ebp
+ rol ebp,5
+ add edx,edi
+ xor ebx,ecx
+ add edx,ebp
+ por xmm6,xmm9
+ mov edi,eax
+ xor eax,ebx
+ movdqa xmm10,xmm6
+ add ecx,DWORD PTR[40+rsp]
+ and edi,ebx
+ and esi,eax
+ ror ebp,7
+ add ecx,edi
+ mov edi,edx
rol edx,5
- xor eax,DWORD PTR[36+rsp]
- xor ebx,r12d
- add esi,edx
- xor eax,DWORD PTR[56+rsp]
- rol ebp,30
- add esi,ebx
- rol eax,1
- mov DWORD PTR[4+rsp],eax
- lea edx,DWORD PTR[3395469782+r12*1+rax]
- mov eax,DWORD PTR[8+rsp]
- mov ebx,ebp
- mov r12d,esi
- xor eax,DWORD PTR[16+rsp]
- xor ebx,edi
- rol r12d,5
- xor eax,DWORD PTR[40+rsp]
- xor ebx,r11d
- add edx,r12d
- xor eax,DWORD PTR[60+rsp]
- rol edi,30
- add edx,ebx
- rol eax,1
- mov DWORD PTR[8+rsp],eax
- lea r12d,DWORD PTR[3395469782+r11*1+rax]
- mov eax,DWORD PTR[12+rsp]
- mov ebx,edi
- mov r11d,edx
- xor eax,DWORD PTR[20+rsp]
- xor ebx,esi
- rol r11d,5
- xor eax,DWORD PTR[44+rsp]
- xor ebx,ebp
- add r12d,r11d
- xor eax,DWORD PTR[rsp]
- rol esi,30
- add r12d,ebx
- rol eax,1
- mov DWORD PTR[12+rsp],eax
- lea r11d,DWORD PTR[3395469782+rbp*1+rax]
- mov eax,DWORD PTR[16+rsp]
- mov ebx,esi
- mov ebp,r12d
- xor eax,DWORD PTR[24+rsp]
- xor ebx,edx
+ add ecx,esi
+ xor eax,ebx
+ add ecx,edx
+ mov esi,ebp
+ xor ebp,eax
+ add ebx,DWORD PTR[44+rsp]
+ and esi,eax
+ and edi,ebp
+ ror edx,7
+ add ebx,esi
+ mov esi,ecx
+ rol ecx,5
+ add ebx,edi
+ xor ebp,eax
+ add ebx,ecx
+ mov edi,edx
+ pxor xmm7,xmm3
+DB 102,68,15,58,15,213,8
+ xor edx,ebp
+ add eax,DWORD PTR[48+rsp]
+ and edi,ebp
+ pxor xmm7,xmm0
+ and esi,edx
+ ror ecx,7
+ movdqa xmm9,XMMWORD PTR[48+r11]
+ paddd xmm8,xmm6
+ add eax,edi
+ mov edi,ebx
+ pxor xmm7,xmm10
+ rol ebx,5
+ add eax,esi
+ xor edx,ebp
+ add eax,ebx
+ movdqa xmm10,xmm7
+ movdqa XMMWORD PTR[32+rsp],xmm8
+ mov esi,ecx
+ xor ecx,edx
+ add ebp,DWORD PTR[52+rsp]
+ and esi,edx
+ pslld xmm7,2
+ and edi,ecx
+ ror ebx,7
+ psrld xmm10,30
+ add ebp,esi
+ mov esi,eax
+ rol eax,5
+ add ebp,edi
+ xor ecx,edx
+ add ebp,eax
+ por xmm7,xmm10
+ mov edi,ebx
+ xor ebx,ecx
+ movdqa xmm8,xmm7
+ add edx,DWORD PTR[56+rsp]
+ and edi,ecx
+ and esi,ebx
+ ror eax,7
+ add edx,edi
+ mov edi,ebp
rol ebp,5
- xor eax,DWORD PTR[48+rsp]
- xor ebx,edi
- add r11d,ebp
- xor eax,DWORD PTR[4+rsp]
- rol edx,30
- add r11d,ebx
- rol eax,1
- mov DWORD PTR[16+rsp],eax
- lea ebp,DWORD PTR[3395469782+rdi*1+rax]
- mov eax,DWORD PTR[20+rsp]
- mov ebx,edx
- mov edi,r11d
- xor eax,DWORD PTR[28+rsp]
- xor ebx,r12d
- rol edi,5
- xor eax,DWORD PTR[52+rsp]
- xor ebx,esi
+ add edx,esi
+ xor ebx,ecx
+ add edx,ebp
+ mov esi,eax
+ xor eax,ebx
+ add ecx,DWORD PTR[60+rsp]
+ and esi,ebx
+ and edi,eax
+ ror ebp,7
+ add ecx,esi
+ mov esi,edx
+ rol edx,5
+ add ecx,edi
+ xor eax,ebx
+ add ecx,edx
+ mov edi,ebp
+ pxor xmm0,xmm4
+DB 102,68,15,58,15,198,8
+ xor ebp,eax
+ add ebx,DWORD PTR[rsp]
+ and edi,eax
+ pxor xmm0,xmm1
+ and esi,ebp
+ ror edx,7
+ movdqa xmm10,xmm9
+ paddd xmm9,xmm7
+ add ebx,edi
+ mov edi,ecx
+ pxor xmm0,xmm8
+ rol ecx,5
+ add ebx,esi
+ xor ebp,eax
+ add ebx,ecx
+ movdqa xmm8,xmm0
+ movdqa XMMWORD PTR[48+rsp],xmm9
+ mov esi,edx
+ xor edx,ebp
+ add eax,DWORD PTR[4+rsp]
+ and esi,ebp
+ pslld xmm0,2
+ and edi,edx
+ ror ecx,7
+ psrld xmm8,30
+ add eax,esi
+ mov esi,ebx
+ rol ebx,5
+ add eax,edi
+ xor edx,ebp
+ add eax,ebx
+ por xmm0,xmm8
+ mov edi,ecx
+ xor ecx,edx
+ movdqa xmm9,xmm0
+ add ebp,DWORD PTR[8+rsp]
+ and edi,edx
+ and esi,ecx
+ ror ebx,7
add ebp,edi
- xor eax,DWORD PTR[8+rsp]
- rol r12d,30
- add ebp,ebx
- rol eax,1
- mov DWORD PTR[20+rsp],eax
- lea edi,DWORD PTR[3395469782+rsi*1+rax]
- mov eax,DWORD PTR[24+rsp]
- mov ebx,r12d
+ mov edi,eax
+ rol eax,5
+ add ebp,esi
+ xor ecx,edx
+ add ebp,eax
+ mov esi,ebx
+ xor ebx,ecx
+ add edx,DWORD PTR[12+rsp]
+ and esi,ecx
+ and edi,ebx
+ ror eax,7
+ add edx,esi
mov esi,ebp
- xor eax,DWORD PTR[32+rsp]
- xor ebx,r11d
- rol esi,5
- xor eax,DWORD PTR[56+rsp]
- xor ebx,edx
- add edi,esi
- xor eax,DWORD PTR[12+rsp]
- rol r11d,30
- add edi,ebx
- rol eax,1
- mov DWORD PTR[24+rsp],eax
- lea esi,DWORD PTR[3395469782+rdx*1+rax]
- mov eax,DWORD PTR[28+rsp]
- mov ebx,r11d
- mov edx,edi
- xor eax,DWORD PTR[36+rsp]
- xor ebx,ebp
+ rol ebp,5
+ add edx,edi
+ xor ebx,ecx
+ add edx,ebp
+ mov edi,eax
+ pxor xmm1,xmm5
+DB 102,68,15,58,15,207,8
+ xor eax,ebx
+ add ecx,DWORD PTR[16+rsp]
+ and edi,ebx
+ pxor xmm1,xmm2
+ and esi,eax
+ ror ebp,7
+ movdqa xmm8,xmm10
+ paddd xmm10,xmm0
+ add ecx,edi
+ mov edi,edx
+ pxor xmm1,xmm9
rol edx,5
- xor eax,DWORD PTR[60+rsp]
- xor ebx,r12d
- add esi,edx
- xor eax,DWORD PTR[16+rsp]
- rol ebp,30
- add esi,ebx
- rol eax,1
- mov DWORD PTR[28+rsp],eax
- lea edx,DWORD PTR[3395469782+r12*1+rax]
- mov eax,DWORD PTR[32+rsp]
- mov ebx,ebp
- mov r12d,esi
- xor eax,DWORD PTR[40+rsp]
- xor ebx,edi
- rol r12d,5
- xor eax,DWORD PTR[rsp]
- xor ebx,r11d
- add edx,r12d
- xor eax,DWORD PTR[20+rsp]
- rol edi,30
- add edx,ebx
- rol eax,1
- mov DWORD PTR[32+rsp],eax
- lea r12d,DWORD PTR[3395469782+r11*1+rax]
- mov eax,DWORD PTR[36+rsp]
- mov ebx,edi
- mov r11d,edx
- xor eax,DWORD PTR[44+rsp]
- xor ebx,esi
- rol r11d,5
- xor eax,DWORD PTR[4+rsp]
- xor ebx,ebp
- add r12d,r11d
- xor eax,DWORD PTR[24+rsp]
- rol esi,30
- add r12d,ebx
- rol eax,1
- mov DWORD PTR[36+rsp],eax
- lea r11d,DWORD PTR[3395469782+rbp*1+rax]
- mov eax,DWORD PTR[40+rsp]
- mov ebx,esi
- mov ebp,r12d
- xor eax,DWORD PTR[48+rsp]
- xor ebx,edx
+ add ecx,esi
+ xor eax,ebx
+ add ecx,edx
+ movdqa xmm9,xmm1
+ movdqa XMMWORD PTR[rsp],xmm10
+ mov esi,ebp
+ xor ebp,eax
+ add ebx,DWORD PTR[20+rsp]
+ and esi,eax
+ pslld xmm1,2
+ and edi,ebp
+ ror edx,7
+ psrld xmm9,30
+ add ebx,esi
+ mov esi,ecx
+ rol ecx,5
+ add ebx,edi
+ xor ebp,eax
+ add ebx,ecx
+ por xmm1,xmm9
+ mov edi,edx
+ xor edx,ebp
+ movdqa xmm10,xmm1
+ add eax,DWORD PTR[24+rsp]
+ and edi,ebp
+ and esi,edx
+ ror ecx,7
+ add eax,edi
+ mov edi,ebx
+ rol ebx,5
+ add eax,esi
+ xor edx,ebp
+ add eax,ebx
+ mov esi,ecx
+ xor ecx,edx
+ add ebp,DWORD PTR[28+rsp]
+ and esi,edx
+ and edi,ecx
+ ror ebx,7
+ add ebp,esi
+ mov esi,eax
+ rol eax,5
+ add ebp,edi
+ xor ecx,edx
+ add ebp,eax
+ mov edi,ebx
+ pxor xmm2,xmm6
+DB 102,68,15,58,15,208,8
+ xor ebx,ecx
+ add edx,DWORD PTR[32+rsp]
+ and edi,ecx
+ pxor xmm2,xmm3
+ and esi,ebx
+ ror eax,7
+ movdqa xmm9,xmm8
+ paddd xmm8,xmm1
+ add edx,edi
+ mov edi,ebp
+ pxor xmm2,xmm10
rol ebp,5
- xor eax,DWORD PTR[8+rsp]
- xor ebx,edi
- add r11d,ebp
- xor eax,DWORD PTR[28+rsp]
- rol edx,30
- add r11d,ebx
- rol eax,1
- mov DWORD PTR[40+rsp],eax
- lea ebp,DWORD PTR[3395469782+rdi*1+rax]
- mov eax,DWORD PTR[44+rsp]
- mov ebx,edx
- mov edi,r11d
- xor eax,DWORD PTR[52+rsp]
- xor ebx,r12d
- rol edi,5
- xor eax,DWORD PTR[12+rsp]
- xor ebx,esi
+ add edx,esi
+ xor ebx,ecx
+ add edx,ebp
+ movdqa xmm10,xmm2
+ movdqa XMMWORD PTR[16+rsp],xmm8
+ mov esi,eax
+ xor eax,ebx
+ add ecx,DWORD PTR[36+rsp]
+ and esi,ebx
+ pslld xmm2,2
+ and edi,eax
+ ror ebp,7
+ psrld xmm10,30
+ add ecx,esi
+ mov esi,edx
+ rol edx,5
+ add ecx,edi
+ xor eax,ebx
+ add ecx,edx
+ por xmm2,xmm10
+ mov edi,ebp
+ xor ebp,eax
+ movdqa xmm8,xmm2
+ add ebx,DWORD PTR[40+rsp]
+ and edi,eax
+ and esi,ebp
+ ror edx,7
+ add ebx,edi
+ mov edi,ecx
+ rol ecx,5
+ add ebx,esi
+ xor ebp,eax
+ add ebx,ecx
+ mov esi,edx
+ xor edx,ebp
+ add eax,DWORD PTR[44+rsp]
+ and esi,ebp
+ and edi,edx
+ ror ecx,7
+ add eax,esi
+ mov esi,ebx
+ rol ebx,5
+ add eax,edi
+ xor edx,ebp
+ add eax,ebx
+ add ebp,DWORD PTR[48+rsp]
+ pxor xmm3,xmm7
+DB 102,68,15,58,15,193,8
+ xor esi,edx
+ mov edi,eax
+ rol eax,5
+ pxor xmm3,xmm4
+ xor esi,ecx
+ add ebp,eax
+ movdqa xmm10,xmm9
+ paddd xmm9,xmm2
+ ror ebx,7
+ add ebp,esi
+ pxor xmm3,xmm8
+ add edx,DWORD PTR[52+rsp]
+ xor edi,ecx
+ mov esi,ebp
+ rol ebp,5
+ movdqa xmm8,xmm3
+ movdqa XMMWORD PTR[32+rsp],xmm9
+ xor edi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,edi
+ pslld xmm3,2
+ add ecx,DWORD PTR[56+rsp]
+ xor esi,ebx
+ psrld xmm8,30
+ mov edi,edx
+ rol edx,5
+ xor esi,eax
+ add ecx,edx
+ ror ebp,7
+ add ecx,esi
+ por xmm3,xmm8
+ add ebx,DWORD PTR[60+rsp]
+ xor edi,eax
+ mov esi,ecx
+ rol ecx,5
+ xor edi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,edi
+ add eax,DWORD PTR[rsp]
+ paddd xmm10,xmm3
+ xor esi,ebp
+ mov edi,ebx
+ rol ebx,5
+ xor esi,edx
+ movdqa XMMWORD PTR[48+rsp],xmm10
+ add eax,ebx
+ ror ecx,7
+ add eax,esi
+ add ebp,DWORD PTR[4+rsp]
+ xor edi,edx
+ mov esi,eax
+ rol eax,5
+ xor edi,ecx
+ add ebp,eax
+ ror ebx,7
add ebp,edi
- xor eax,DWORD PTR[32+rsp]
- rol r12d,30
- add ebp,ebx
- rol eax,1
- mov DWORD PTR[44+rsp],eax
- lea edi,DWORD PTR[3395469782+rsi*1+rax]
- mov eax,DWORD PTR[48+rsp]
- mov ebx,r12d
+ add edx,DWORD PTR[8+rsp]
+ xor esi,ecx
+ mov edi,ebp
+ rol ebp,5
+ xor esi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,esi
+ add ecx,DWORD PTR[12+rsp]
+ xor edi,ebx
+ mov esi,edx
+ rol edx,5
+ xor edi,eax
+ add ecx,edx
+ ror ebp,7
+ add ecx,edi
+ cmp r9,r10
+ je $L$done_ssse3
+ movdqa xmm6,XMMWORD PTR[64+r11]
+ movdqa xmm9,XMMWORD PTR[r11]
+ movdqu xmm0,XMMWORD PTR[r9]
+ movdqu xmm1,XMMWORD PTR[16+r9]
+ movdqu xmm2,XMMWORD PTR[32+r9]
+ movdqu xmm3,XMMWORD PTR[48+r9]
+DB 102,15,56,0,198
+ add r9,64
+ add ebx,DWORD PTR[16+rsp]
+ xor esi,eax
+DB 102,15,56,0,206
+ mov edi,ecx
+ rol ecx,5
+ paddd xmm0,xmm9
+ xor esi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ movdqa XMMWORD PTR[rsp],xmm0
+ add eax,DWORD PTR[20+rsp]
+ xor edi,ebp
+ psubd xmm0,xmm9
+ mov esi,ebx
+ rol ebx,5
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ add ebp,DWORD PTR[24+rsp]
+ xor esi,edx
+ mov edi,eax
+ rol eax,5
+ xor esi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,esi
+ add edx,DWORD PTR[28+rsp]
+ xor edi,ecx
mov esi,ebp
- xor eax,DWORD PTR[56+rsp]
- xor ebx,r11d
- rol esi,5
- xor eax,DWORD PTR[16+rsp]
- xor ebx,edx
- add edi,esi
- xor eax,DWORD PTR[36+rsp]
- rol r11d,30
- add edi,ebx
- rol eax,1
- mov DWORD PTR[48+rsp],eax
- lea esi,DWORD PTR[3395469782+rdx*1+rax]
- mov eax,DWORD PTR[52+rsp]
- mov ebx,r11d
- mov edx,edi
- xor eax,DWORD PTR[60+rsp]
- xor ebx,ebp
+ rol ebp,5
+ xor edi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,edi
+ add ecx,DWORD PTR[32+rsp]
+ xor esi,ebx
+DB 102,15,56,0,214
+ mov edi,edx
rol edx,5
- xor eax,DWORD PTR[20+rsp]
- xor ebx,r12d
- add esi,edx
- xor eax,DWORD PTR[40+rsp]
- rol ebp,30
- add esi,ebx
- rol eax,1
- lea edx,DWORD PTR[3395469782+r12*1+rax]
- mov eax,DWORD PTR[56+rsp]
- mov ebx,ebp
- mov r12d,esi
- xor eax,DWORD PTR[rsp]
- xor ebx,edi
- rol r12d,5
- xor eax,DWORD PTR[24+rsp]
- xor ebx,r11d
- add edx,r12d
- xor eax,DWORD PTR[44+rsp]
- rol edi,30
- add edx,ebx
- rol eax,1
- lea r12d,DWORD PTR[3395469782+r11*1+rax]
- mov eax,DWORD PTR[60+rsp]
- mov ebx,edi
- mov r11d,edx
- xor eax,DWORD PTR[4+rsp]
- xor ebx,esi
- rol r11d,5
- xor eax,DWORD PTR[28+rsp]
- xor ebx,ebp
- add r12d,r11d
- xor eax,DWORD PTR[48+rsp]
- rol esi,30
- add r12d,ebx
- rol eax,1
- lea r11d,DWORD PTR[3395469782+rbp*1+rax]
- mov ebx,esi
- mov ebp,r12d
- xor ebx,edx
+ paddd xmm1,xmm9
+ xor esi,eax
+ add ecx,edx
+ ror ebp,7
+ add ecx,esi
+ movdqa XMMWORD PTR[16+rsp],xmm1
+ add ebx,DWORD PTR[36+rsp]
+ xor edi,eax
+ psubd xmm1,xmm9
+ mov esi,ecx
+ rol ecx,5
+ xor edi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,edi
+ add eax,DWORD PTR[40+rsp]
+ xor esi,ebp
+ mov edi,ebx
+ rol ebx,5
+ xor esi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,esi
+ add ebp,DWORD PTR[44+rsp]
+ xor edi,edx
+ mov esi,eax
+ rol eax,5
+ xor edi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,edi
+ add edx,DWORD PTR[48+rsp]
+ xor esi,ecx
+DB 102,15,56,0,222
+ mov edi,ebp
rol ebp,5
- xor ebx,edi
- add r11d,ebp
- rol edx,30
- add r11d,ebx
- add r11d,DWORD PTR[r8]
- add r12d,DWORD PTR[4+r8]
- add edx,DWORD PTR[8+r8]
- add esi,DWORD PTR[12+r8]
- add edi,DWORD PTR[16+r8]
- mov DWORD PTR[r8],r11d
- mov DWORD PTR[4+r8],r12d
- mov DWORD PTR[8+r8],edx
- mov DWORD PTR[12+r8],esi
- mov DWORD PTR[16+r8],edi
-
- xchg edx,r11d
- xchg esi,r12d
- xchg edi,r11d
- xchg ebp,r12d
+ paddd xmm2,xmm9
+ xor esi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,esi
+ movdqa XMMWORD PTR[32+rsp],xmm2
+ add ecx,DWORD PTR[52+rsp]
+ xor edi,ebx
+ psubd xmm2,xmm9
+ mov esi,edx
+ rol edx,5
+ xor edi,eax
+ add ecx,edx
+ ror ebp,7
+ add ecx,edi
+ add ebx,DWORD PTR[56+rsp]
+ xor esi,eax
+ mov edi,ecx
+ rol ecx,5
+ xor esi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ add eax,DWORD PTR[60+rsp]
+ xor edi,ebp
+ mov esi,ebx
+ rol ebx,5
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ add eax,DWORD PTR[r8]
+ add esi,DWORD PTR[4+r8]
+ add ecx,DWORD PTR[8+r8]
+ add edx,DWORD PTR[12+r8]
+ mov DWORD PTR[r8],eax
+ add ebp,DWORD PTR[16+r8]
+ mov DWORD PTR[4+r8],esi
+ mov ebx,esi
+ mov DWORD PTR[8+r8],ecx
+ mov DWORD PTR[12+r8],edx
+ mov DWORD PTR[16+r8],ebp
+ jmp $L$oop_ssse3
- lea r9,QWORD PTR[64+r9]
- sub r10,1
- jnz $L$loop
- mov rsi,QWORD PTR[64+rsp]
+ALIGN 16
+$L$done_ssse3::
+ add ebx,DWORD PTR[16+rsp]
+ xor esi,eax
+ mov edi,ecx
+ rol ecx,5
+ xor esi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ add eax,DWORD PTR[20+rsp]
+ xor edi,ebp
+ mov esi,ebx
+ rol ebx,5
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ add ebp,DWORD PTR[24+rsp]
+ xor esi,edx
+ mov edi,eax
+ rol eax,5
+ xor esi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,esi
+ add edx,DWORD PTR[28+rsp]
+ xor edi,ecx
+ mov esi,ebp
+ rol ebp,5
+ xor edi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,edi
+ add ecx,DWORD PTR[32+rsp]
+ xor esi,ebx
+ mov edi,edx
+ rol edx,5
+ xor esi,eax
+ add ecx,edx
+ ror ebp,7
+ add ecx,esi
+ add ebx,DWORD PTR[36+rsp]
+ xor edi,eax
+ mov esi,ecx
+ rol ecx,5
+ xor edi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,edi
+ add eax,DWORD PTR[40+rsp]
+ xor esi,ebp
+ mov edi,ebx
+ rol ebx,5
+ xor esi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,esi
+ add ebp,DWORD PTR[44+rsp]
+ xor edi,edx
+ mov esi,eax
+ rol eax,5
+ xor edi,ecx
+ add ebp,eax
+ ror ebx,7
+ add ebp,edi
+ add edx,DWORD PTR[48+rsp]
+ xor esi,ecx
+ mov edi,ebp
+ rol ebp,5
+ xor esi,ebx
+ add edx,ebp
+ ror eax,7
+ add edx,esi
+ add ecx,DWORD PTR[52+rsp]
+ xor edi,ebx
+ mov esi,edx
+ rol edx,5
+ xor edi,eax
+ add ecx,edx
+ ror ebp,7
+ add ecx,edi
+ add ebx,DWORD PTR[56+rsp]
+ xor esi,eax
+ mov edi,ecx
+ rol ecx,5
+ xor esi,ebp
+ add ebx,ecx
+ ror edx,7
+ add ebx,esi
+ add eax,DWORD PTR[60+rsp]
+ xor edi,ebp
+ mov esi,ebx
+ rol ebx,5
+ xor edi,edx
+ add eax,ebx
+ ror ecx,7
+ add eax,edi
+ add eax,DWORD PTR[r8]
+ add esi,DWORD PTR[4+r8]
+ add ecx,DWORD PTR[8+r8]
+ mov DWORD PTR[r8],eax
+ add edx,DWORD PTR[12+r8]
+ mov DWORD PTR[4+r8],esi
+ add ebp,DWORD PTR[16+r8]
+ mov DWORD PTR[8+r8],ecx
+ mov DWORD PTR[12+r8],edx
+ mov DWORD PTR[16+r8],ebp
+ movaps xmm6,XMMWORD PTR[((64+0))+rsp]
+ movaps xmm7,XMMWORD PTR[((64+16))+rsp]
+ movaps xmm8,XMMWORD PTR[((64+32))+rsp]
+ movaps xmm9,XMMWORD PTR[((64+48))+rsp]
+ movaps xmm10,XMMWORD PTR[((64+64))+rsp]
+ lea rsi,QWORD PTR[144+rsp]
mov r12,QWORD PTR[rsi]
mov rbp,QWORD PTR[8+rsi]
mov rbx,QWORD PTR[16+rsi]
lea rsp,QWORD PTR[24+rsi]
-$L$epilogue::
+$L$epilogue_ssse3::
mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
mov rsi,QWORD PTR[16+rsp]
DB 0F3h,0C3h ;repret
-$L$SEH_end_sha1_block_data_order::
-sha1_block_data_order ENDP
+$L$SEH_end_sha1_block_data_order_ssse3::
+sha1_block_data_order_ssse3 ENDP
+ALIGN 64
+K_XX_XX::
+ DD 05a827999h,05a827999h,05a827999h,05a827999h
+
+ DD 06ed9eba1h,06ed9eba1h,06ed9eba1h,06ed9eba1h
+
+ DD 08f1bbcdch,08f1bbcdch,08f1bbcdch,08f1bbcdch
+
+ DD 0ca62c1d6h,0ca62c1d6h,0ca62c1d6h,0ca62c1d6h
+
+ DD 000010203h,004050607h,008090a0bh,00c0d0e0fh
+
DB 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115
DB 102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44
DB 32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60
DB 97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114
DB 103,62,0
-ALIGN 16
+ALIGN 64
EXTERN __imp_RtlVirtualUnwind:NEAR
ALIGN 16
@@ -1317,16 +2549,67 @@ se_handler PROC PRIVATE
lea r10,QWORD PTR[$L$prologue]
cmp rbx,r10
- jb $L$in_prologue
+ jb $L$common_seh_tail
mov rax,QWORD PTR[152+r8]
lea r10,QWORD PTR[$L$epilogue]
cmp rbx,r10
- jae $L$in_prologue
+ jae $L$common_seh_tail
mov rax,QWORD PTR[64+rax]
- lea rax,QWORD PTR[24+rax]
+ lea rax,QWORD PTR[32+rax]
+
+ mov rbx,QWORD PTR[((-8))+rax]
+ mov rbp,QWORD PTR[((-16))+rax]
+ mov r12,QWORD PTR[((-24))+rax]
+ mov r13,QWORD PTR[((-32))+rax]
+ mov QWORD PTR[144+r8],rbx
+ mov QWORD PTR[160+r8],rbp
+ mov QWORD PTR[216+r8],r12
+ mov QWORD PTR[224+r8],r13
+
+ jmp $L$common_seh_tail
+se_handler ENDP
+
+
+ALIGN 16
+ssse3_handler PROC PRIVATE
+ push rsi
+ push rdi
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq
+ sub rsp,64
+
+ mov rax,QWORD PTR[120+r8]
+ mov rbx,QWORD PTR[248+r8]
+
+ mov rsi,QWORD PTR[8+r9]
+ mov r11,QWORD PTR[56+r9]
+
+ mov r10d,DWORD PTR[r11]
+ lea r10,QWORD PTR[r10*1+rsi]
+ cmp rbx,r10
+ jb $L$common_seh_tail
+
+ mov rax,QWORD PTR[152+r8]
+
+ mov r10d,DWORD PTR[4+r11]
+ lea r10,QWORD PTR[r10*1+rsi]
+ cmp rbx,r10
+ jae $L$common_seh_tail
+
+ lea rsi,QWORD PTR[64+rax]
+ lea rdi,QWORD PTR[512+r8]
+ mov ecx,10
+ DD 0a548f3fch
+
+ lea rax,QWORD PTR[168+rax]
mov rbx,QWORD PTR[((-8))+rax]
mov rbp,QWORD PTR[((-16))+rax]
@@ -1335,7 +2618,7 @@ se_handler PROC PRIVATE
mov QWORD PTR[160+r8],rbp
mov QWORD PTR[216+r8],r12
-$L$in_prologue::
+$L$common_seh_tail::
mov rdi,QWORD PTR[8+rax]
mov rsi,QWORD PTR[16+rax]
mov QWORD PTR[152+r8],rax
@@ -1374,7 +2657,7 @@ $L$in_prologue::
pop rdi
pop rsi
DB 0F3h,0C3h ;repret
-se_handler ENDP
+ssse3_handler ENDP
.text$ ENDS
.pdata SEGMENT READONLY ALIGN(4)
@@ -1382,13 +2665,20 @@ ALIGN 4
DD imagerel $L$SEH_begin_sha1_block_data_order
DD imagerel $L$SEH_end_sha1_block_data_order
DD imagerel $L$SEH_info_sha1_block_data_order
-
+ DD imagerel $L$SEH_begin_sha1_block_data_order_ssse3
+ DD imagerel $L$SEH_end_sha1_block_data_order_ssse3
+ DD imagerel $L$SEH_info_sha1_block_data_order_ssse3
.pdata ENDS
.xdata SEGMENT READONLY ALIGN(8)
ALIGN 8
$L$SEH_info_sha1_block_data_order::
DB 9,0,0,0
DD imagerel se_handler
+$L$SEH_info_sha1_block_data_order_ssse3::
+DB 9,0,0,0
+ DD imagerel ssse3_handler
+ DD imagerel $L$prologue_ssse3,imagerel $L$epilogue_ssse3
+
.xdata ENDS
END
diff --git a/deps/openssl/asm/x64-win32-masm/sha/sha512-x86_64.asm b/deps/openssl/asm/x64-win32-masm/sha/sha512-x86_64.asm
index 5ea4a6327..f685c2fdf 100644
--- a/deps/openssl/asm/x64-win32-masm/sha/sha512-x86_64.asm
+++ b/deps/openssl/asm/x64-win32-masm/sha/sha512-x86_64.asm
@@ -26,1930 +26,1738 @@ $L$SEH_begin_sha256_block_data_order::
sub rsp,16*4+4*8
lea rdx,QWORD PTR[rdx*4+rsi]
and rsp,-64
- mov QWORD PTR[((16*4+0*8))+rsp],rdi
- mov QWORD PTR[((16*4+1*8))+rsp],rsi
- mov QWORD PTR[((16*4+2*8))+rsp],rdx
- mov QWORD PTR[((16*4+3*8))+rsp],r11
+ mov QWORD PTR[((64+0))+rsp],rdi
+ mov QWORD PTR[((64+8))+rsp],rsi
+ mov QWORD PTR[((64+16))+rsp],rdx
+ mov QWORD PTR[((64+24))+rsp],r11
$L$prologue::
lea rbp,QWORD PTR[K256]
- mov eax,DWORD PTR[((4*0))+rdi]
- mov ebx,DWORD PTR[((4*1))+rdi]
- mov ecx,DWORD PTR[((4*2))+rdi]
- mov edx,DWORD PTR[((4*3))+rdi]
- mov r8d,DWORD PTR[((4*4))+rdi]
- mov r9d,DWORD PTR[((4*5))+rdi]
- mov r10d,DWORD PTR[((4*6))+rdi]
- mov r11d,DWORD PTR[((4*7))+rdi]
+ mov eax,DWORD PTR[rdi]
+ mov ebx,DWORD PTR[4+rdi]
+ mov ecx,DWORD PTR[8+rdi]
+ mov edx,DWORD PTR[12+rdi]
+ mov r8d,DWORD PTR[16+rdi]
+ mov r9d,DWORD PTR[20+rdi]
+ mov r10d,DWORD PTR[24+rdi]
+ mov r11d,DWORD PTR[28+rdi]
jmp $L$loop
ALIGN 16
$L$loop::
xor rdi,rdi
- mov r12d,DWORD PTR[((4*0))+rsi]
- bswap r12d
+ mov r12d,DWORD PTR[rsi]
mov r13d,r8d
- mov r14d,r8d
+ mov r14d,eax
+ bswap r12d
+ ror r13d,14
mov r15d,r9d
+ mov DWORD PTR[rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r8d
xor r15d,r10d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r11d
+ xor r14d,eax
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r8d
- mov DWORD PTR[rsp],r12d
+ mov r11d,ebx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r8d
xor r15d,r10d
- add r12d,r11d
-
- mov r11d,eax
- add r12d,r13d
+ xor r11d,ecx
+ xor r14d,eax
add r12d,r15d
- mov r13d,eax
- mov r14d,eax
+ mov r15d,ebx
- ror r11d,2
- ror r13d,13
- mov r15d,eax
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r11d,eax
+ and r15d,ecx
- xor r11d,r13d
- ror r13d,9
- or r14d,ecx
+ ror r14d,2
+ add r12d,r13d
+ add r11d,r15d
- xor r11d,r13d
- and r15d,ecx
add edx,r12d
-
- and r14d,ebx
add r11d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r11d,r14d
- mov r12d,DWORD PTR[((4*1))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[4+rsi]
mov r13d,edx
- mov r14d,edx
+ mov r14d,r11d
+ bswap r12d
+ ror r13d,14
mov r15d,r8d
+ mov DWORD PTR[4+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,edx
xor r15d,r9d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r10d
+ xor r14d,r11d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,edx
- mov DWORD PTR[4+rsp],r12d
+ mov r10d,eax
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,edx
xor r15d,r9d
- add r12d,r10d
-
- mov r10d,r11d
- add r12d,r13d
+ xor r10d,ebx
+ xor r14d,r11d
add r12d,r15d
- mov r13d,r11d
- mov r14d,r11d
+ mov r15d,eax
- ror r10d,2
- ror r13d,13
- mov r15d,r11d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r10d,r11d
+ and r15d,ebx
- xor r10d,r13d
- ror r13d,9
- or r14d,ebx
+ ror r14d,2
+ add r12d,r13d
+ add r10d,r15d
- xor r10d,r13d
- and r15d,ebx
add ecx,r12d
-
- and r14d,eax
add r10d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r10d,r14d
- mov r12d,DWORD PTR[((4*2))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[8+rsi]
mov r13d,ecx
- mov r14d,ecx
+ mov r14d,r10d
+ bswap r12d
+ ror r13d,14
mov r15d,edx
+ mov DWORD PTR[8+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,ecx
xor r15d,r8d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r9d
+ xor r14d,r10d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,ecx
- mov DWORD PTR[8+rsp],r12d
+ mov r9d,r11d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,ecx
xor r15d,r8d
- add r12d,r9d
-
- mov r9d,r10d
- add r12d,r13d
+ xor r9d,eax
+ xor r14d,r10d
add r12d,r15d
- mov r13d,r10d
- mov r14d,r10d
+ mov r15d,r11d
- ror r9d,2
- ror r13d,13
- mov r15d,r10d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r9d,r10d
+ and r15d,eax
- xor r9d,r13d
- ror r13d,9
- or r14d,eax
+ ror r14d,2
+ add r12d,r13d
+ add r9d,r15d
- xor r9d,r13d
- and r15d,eax
add ebx,r12d
-
- and r14d,r11d
add r9d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r9d,r14d
- mov r12d,DWORD PTR[((4*3))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[12+rsi]
mov r13d,ebx
- mov r14d,ebx
+ mov r14d,r9d
+ bswap r12d
+ ror r13d,14
mov r15d,ecx
+ mov DWORD PTR[12+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,ebx
xor r15d,edx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r8d
+ xor r14d,r9d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,ebx
- mov DWORD PTR[12+rsp],r12d
+ mov r8d,r10d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,ebx
xor r15d,edx
- add r12d,r8d
-
- mov r8d,r9d
- add r12d,r13d
+ xor r8d,r11d
+ xor r14d,r9d
add r12d,r15d
- mov r13d,r9d
- mov r14d,r9d
+ mov r15d,r10d
- ror r8d,2
- ror r13d,13
- mov r15d,r9d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r8d,r9d
+ and r15d,r11d
- xor r8d,r13d
- ror r13d,9
- or r14d,r11d
+ ror r14d,2
+ add r12d,r13d
+ add r8d,r15d
- xor r8d,r13d
- and r15d,r11d
add eax,r12d
-
- and r14d,r10d
add r8d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r8d,r14d
- mov r12d,DWORD PTR[((4*4))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[16+rsi]
mov r13d,eax
- mov r14d,eax
+ mov r14d,r8d
+ bswap r12d
+ ror r13d,14
mov r15d,ebx
+ mov DWORD PTR[16+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,eax
xor r15d,ecx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,edx
+ xor r14d,r8d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,eax
- mov DWORD PTR[16+rsp],r12d
+ mov edx,r9d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,eax
xor r15d,ecx
- add r12d,edx
-
- mov edx,r8d
- add r12d,r13d
+ xor edx,r10d
+ xor r14d,r8d
add r12d,r15d
- mov r13d,r8d
- mov r14d,r8d
+ mov r15d,r9d
- ror edx,2
- ror r13d,13
- mov r15d,r8d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and edx,r8d
+ and r15d,r10d
- xor edx,r13d
- ror r13d,9
- or r14d,r10d
+ ror r14d,2
+ add r12d,r13d
+ add edx,r15d
- xor edx,r13d
- and r15d,r10d
add r11d,r12d
-
- and r14d,r9d
add edx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add edx,r14d
- mov r12d,DWORD PTR[((4*5))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[20+rsi]
mov r13d,r11d
- mov r14d,r11d
+ mov r14d,edx
+ bswap r12d
+ ror r13d,14
mov r15d,eax
+ mov DWORD PTR[20+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r11d
xor r15d,ebx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,ecx
+ xor r14d,edx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r11d
- mov DWORD PTR[20+rsp],r12d
+ mov ecx,r8d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r11d
xor r15d,ebx
- add r12d,ecx
-
- mov ecx,edx
- add r12d,r13d
+ xor ecx,r9d
+ xor r14d,edx
add r12d,r15d
- mov r13d,edx
- mov r14d,edx
+ mov r15d,r8d
- ror ecx,2
- ror r13d,13
- mov r15d,edx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and ecx,edx
+ and r15d,r9d
- xor ecx,r13d
- ror r13d,9
- or r14d,r9d
+ ror r14d,2
+ add r12d,r13d
+ add ecx,r15d
- xor ecx,r13d
- and r15d,r9d
add r10d,r12d
-
- and r14d,r8d
add ecx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add ecx,r14d
- mov r12d,DWORD PTR[((4*6))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[24+rsi]
mov r13d,r10d
- mov r14d,r10d
+ mov r14d,ecx
+ bswap r12d
+ ror r13d,14
mov r15d,r11d
+ mov DWORD PTR[24+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r10d
xor r15d,eax
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,ebx
+ xor r14d,ecx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r10d
- mov DWORD PTR[24+rsp],r12d
+ mov ebx,edx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r10d
xor r15d,eax
- add r12d,ebx
-
- mov ebx,ecx
- add r12d,r13d
+ xor ebx,r8d
+ xor r14d,ecx
add r12d,r15d
- mov r13d,ecx
- mov r14d,ecx
+ mov r15d,edx
- ror ebx,2
- ror r13d,13
- mov r15d,ecx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and ebx,ecx
+ and r15d,r8d
- xor ebx,r13d
- ror r13d,9
- or r14d,r8d
+ ror r14d,2
+ add r12d,r13d
+ add ebx,r15d
- xor ebx,r13d
- and r15d,r8d
add r9d,r12d
-
- and r14d,edx
add ebx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add ebx,r14d
- mov r12d,DWORD PTR[((4*7))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[28+rsi]
mov r13d,r9d
- mov r14d,r9d
+ mov r14d,ebx
+ bswap r12d
+ ror r13d,14
mov r15d,r10d
+ mov DWORD PTR[28+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r9d
xor r15d,r11d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,eax
+ xor r14d,ebx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r9d
- mov DWORD PTR[28+rsp],r12d
+ mov eax,ecx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r9d
xor r15d,r11d
- add r12d,eax
-
- mov eax,ebx
- add r12d,r13d
+ xor eax,edx
+ xor r14d,ebx
add r12d,r15d
- mov r13d,ebx
- mov r14d,ebx
+ mov r15d,ecx
- ror eax,2
- ror r13d,13
- mov r15d,ebx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and eax,ebx
+ and r15d,edx
- xor eax,r13d
- ror r13d,9
- or r14d,edx
+ ror r14d,2
+ add r12d,r13d
+ add eax,r15d
- xor eax,r13d
- and r15d,edx
add r8d,r12d
-
- and r14d,ecx
add eax,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add eax,r14d
- mov r12d,DWORD PTR[((4*8))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[32+rsi]
mov r13d,r8d
- mov r14d,r8d
+ mov r14d,eax
+ bswap r12d
+ ror r13d,14
mov r15d,r9d
+ mov DWORD PTR[32+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r8d
xor r15d,r10d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r11d
+ xor r14d,eax
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r8d
- mov DWORD PTR[32+rsp],r12d
+ mov r11d,ebx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r8d
xor r15d,r10d
- add r12d,r11d
-
- mov r11d,eax
- add r12d,r13d
+ xor r11d,ecx
+ xor r14d,eax
add r12d,r15d
- mov r13d,eax
- mov r14d,eax
+ mov r15d,ebx
- ror r11d,2
- ror r13d,13
- mov r15d,eax
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r11d,eax
+ and r15d,ecx
- xor r11d,r13d
- ror r13d,9
- or r14d,ecx
+ ror r14d,2
+ add r12d,r13d
+ add r11d,r15d
- xor r11d,r13d
- and r15d,ecx
add edx,r12d
-
- and r14d,ebx
add r11d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r11d,r14d
- mov r12d,DWORD PTR[((4*9))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[36+rsi]
mov r13d,edx
- mov r14d,edx
+ mov r14d,r11d
+ bswap r12d
+ ror r13d,14
mov r15d,r8d
+ mov DWORD PTR[36+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,edx
xor r15d,r9d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r10d
+ xor r14d,r11d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,edx
- mov DWORD PTR[36+rsp],r12d
+ mov r10d,eax
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,edx
xor r15d,r9d
- add r12d,r10d
-
- mov r10d,r11d
- add r12d,r13d
+ xor r10d,ebx
+ xor r14d,r11d
add r12d,r15d
- mov r13d,r11d
- mov r14d,r11d
+ mov r15d,eax
- ror r10d,2
- ror r13d,13
- mov r15d,r11d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r10d,r11d
+ and r15d,ebx
- xor r10d,r13d
- ror r13d,9
- or r14d,ebx
+ ror r14d,2
+ add r12d,r13d
+ add r10d,r15d
- xor r10d,r13d
- and r15d,ebx
add ecx,r12d
-
- and r14d,eax
add r10d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r10d,r14d
- mov r12d,DWORD PTR[((4*10))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[40+rsi]
mov r13d,ecx
- mov r14d,ecx
+ mov r14d,r10d
+ bswap r12d
+ ror r13d,14
mov r15d,edx
+ mov DWORD PTR[40+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,ecx
xor r15d,r8d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r9d
+ xor r14d,r10d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,ecx
- mov DWORD PTR[40+rsp],r12d
+ mov r9d,r11d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,ecx
xor r15d,r8d
- add r12d,r9d
-
- mov r9d,r10d
- add r12d,r13d
+ xor r9d,eax
+ xor r14d,r10d
add r12d,r15d
- mov r13d,r10d
- mov r14d,r10d
+ mov r15d,r11d
- ror r9d,2
- ror r13d,13
- mov r15d,r10d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r9d,r10d
+ and r15d,eax
- xor r9d,r13d
- ror r13d,9
- or r14d,eax
+ ror r14d,2
+ add r12d,r13d
+ add r9d,r15d
- xor r9d,r13d
- and r15d,eax
add ebx,r12d
-
- and r14d,r11d
add r9d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r9d,r14d
- mov r12d,DWORD PTR[((4*11))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[44+rsi]
mov r13d,ebx
- mov r14d,ebx
+ mov r14d,r9d
+ bswap r12d
+ ror r13d,14
mov r15d,ecx
+ mov DWORD PTR[44+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,ebx
xor r15d,edx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r8d
+ xor r14d,r9d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,ebx
- mov DWORD PTR[44+rsp],r12d
+ mov r8d,r10d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,ebx
xor r15d,edx
- add r12d,r8d
-
- mov r8d,r9d
- add r12d,r13d
+ xor r8d,r11d
+ xor r14d,r9d
add r12d,r15d
- mov r13d,r9d
- mov r14d,r9d
+ mov r15d,r10d
- ror r8d,2
- ror r13d,13
- mov r15d,r9d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r8d,r9d
+ and r15d,r11d
- xor r8d,r13d
- ror r13d,9
- or r14d,r11d
+ ror r14d,2
+ add r12d,r13d
+ add r8d,r15d
- xor r8d,r13d
- and r15d,r11d
add eax,r12d
-
- and r14d,r10d
add r8d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r8d,r14d
- mov r12d,DWORD PTR[((4*12))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[48+rsi]
mov r13d,eax
- mov r14d,eax
+ mov r14d,r8d
+ bswap r12d
+ ror r13d,14
mov r15d,ebx
+ mov DWORD PTR[48+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,eax
xor r15d,ecx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,edx
+ xor r14d,r8d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,eax
- mov DWORD PTR[48+rsp],r12d
+ mov edx,r9d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,eax
xor r15d,ecx
- add r12d,edx
-
- mov edx,r8d
- add r12d,r13d
+ xor edx,r10d
+ xor r14d,r8d
add r12d,r15d
- mov r13d,r8d
- mov r14d,r8d
+ mov r15d,r9d
- ror edx,2
- ror r13d,13
- mov r15d,r8d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and edx,r8d
+ and r15d,r10d
- xor edx,r13d
- ror r13d,9
- or r14d,r10d
+ ror r14d,2
+ add r12d,r13d
+ add edx,r15d
- xor edx,r13d
- and r15d,r10d
add r11d,r12d
-
- and r14d,r9d
add edx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add edx,r14d
- mov r12d,DWORD PTR[((4*13))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[52+rsi]
mov r13d,r11d
- mov r14d,r11d
+ mov r14d,edx
+ bswap r12d
+ ror r13d,14
mov r15d,eax
+ mov DWORD PTR[52+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r11d
xor r15d,ebx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,ecx
+ xor r14d,edx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r11d
- mov DWORD PTR[52+rsp],r12d
+ mov ecx,r8d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r11d
xor r15d,ebx
- add r12d,ecx
-
- mov ecx,edx
- add r12d,r13d
+ xor ecx,r9d
+ xor r14d,edx
add r12d,r15d
- mov r13d,edx
- mov r14d,edx
+ mov r15d,r8d
- ror ecx,2
- ror r13d,13
- mov r15d,edx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and ecx,edx
+ and r15d,r9d
- xor ecx,r13d
- ror r13d,9
- or r14d,r9d
+ ror r14d,2
+ add r12d,r13d
+ add ecx,r15d
- xor ecx,r13d
- and r15d,r9d
add r10d,r12d
-
- and r14d,r8d
add ecx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add ecx,r14d
- mov r12d,DWORD PTR[((4*14))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[56+rsi]
mov r13d,r10d
- mov r14d,r10d
+ mov r14d,ecx
+ bswap r12d
+ ror r13d,14
mov r15d,r11d
+ mov DWORD PTR[56+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r10d
xor r15d,eax
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,ebx
+ xor r14d,ecx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r10d
- mov DWORD PTR[56+rsp],r12d
+ mov ebx,edx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r10d
xor r15d,eax
- add r12d,ebx
-
- mov ebx,ecx
- add r12d,r13d
+ xor ebx,r8d
+ xor r14d,ecx
add r12d,r15d
- mov r13d,ecx
- mov r14d,ecx
+ mov r15d,edx
- ror ebx,2
- ror r13d,13
- mov r15d,ecx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and ebx,ecx
+ and r15d,r8d
- xor ebx,r13d
- ror r13d,9
- or r14d,r8d
+ ror r14d,2
+ add r12d,r13d
+ add ebx,r15d
- xor ebx,r13d
- and r15d,r8d
add r9d,r12d
-
- and r14d,edx
add ebx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add ebx,r14d
- mov r12d,DWORD PTR[((4*15))+rsi]
- bswap r12d
+
+ mov r12d,DWORD PTR[60+rsi]
mov r13d,r9d
- mov r14d,r9d
+ mov r14d,ebx
+ bswap r12d
+ ror r13d,14
mov r15d,r10d
+ mov DWORD PTR[60+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r9d
xor r15d,r11d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,eax
+ xor r14d,ebx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r9d
- mov DWORD PTR[60+rsp],r12d
+ mov eax,ecx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r9d
xor r15d,r11d
- add r12d,eax
-
- mov eax,ebx
- add r12d,r13d
+ xor eax,edx
+ xor r14d,ebx
add r12d,r15d
- mov r13d,ebx
- mov r14d,ebx
+ mov r15d,ecx
- ror eax,2
- ror r13d,13
- mov r15d,ebx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and eax,ebx
+ and r15d,edx
- xor eax,r13d
- ror r13d,9
- or r14d,edx
+ ror r14d,2
+ add r12d,r13d
+ add eax,r15d
- xor eax,r13d
- and r15d,edx
add r8d,r12d
-
- and r14d,ecx
add eax,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add eax,r14d
+
jmp $L$rounds_16_xx
ALIGN 16
$L$rounds_16_xx::
mov r13d,DWORD PTR[4+rsp]
- mov r12d,DWORD PTR[56+rsp]
-
- mov r15d,r13d
+ mov r14d,DWORD PTR[56+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[36+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[36+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[rsp]
mov r13d,r8d
- mov r14d,r8d
+ add r12d,r14d
+ mov r14d,eax
+ ror r13d,14
mov r15d,r9d
+ mov DWORD PTR[rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r8d
xor r15d,r10d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r11d
+ xor r14d,eax
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r8d
- mov DWORD PTR[rsp],r12d
+ mov r11d,ebx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r8d
xor r15d,r10d
- add r12d,r11d
-
- mov r11d,eax
- add r12d,r13d
+ xor r11d,ecx
+ xor r14d,eax
add r12d,r15d
- mov r13d,eax
- mov r14d,eax
+ mov r15d,ebx
- ror r11d,2
- ror r13d,13
- mov r15d,eax
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r11d,eax
+ and r15d,ecx
- xor r11d,r13d
- ror r13d,9
- or r14d,ecx
+ ror r14d,2
+ add r12d,r13d
+ add r11d,r15d
- xor r11d,r13d
- and r15d,ecx
add edx,r12d
-
- and r14d,ebx
add r11d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r11d,r14d
- mov r13d,DWORD PTR[8+rsp]
- mov r12d,DWORD PTR[60+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[8+rsp]
+ mov r14d,DWORD PTR[60+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[40+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[40+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[4+rsp]
mov r13d,edx
- mov r14d,edx
+ add r12d,r14d
+ mov r14d,r11d
+ ror r13d,14
mov r15d,r8d
+ mov DWORD PTR[4+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,edx
xor r15d,r9d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r10d
+ xor r14d,r11d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,edx
- mov DWORD PTR[4+rsp],r12d
+ mov r10d,eax
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,edx
xor r15d,r9d
- add r12d,r10d
-
- mov r10d,r11d
- add r12d,r13d
+ xor r10d,ebx
+ xor r14d,r11d
add r12d,r15d
- mov r13d,r11d
- mov r14d,r11d
+ mov r15d,eax
- ror r10d,2
- ror r13d,13
- mov r15d,r11d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r10d,r11d
+ and r15d,ebx
- xor r10d,r13d
- ror r13d,9
- or r14d,ebx
+ ror r14d,2
+ add r12d,r13d
+ add r10d,r15d
- xor r10d,r13d
- and r15d,ebx
add ecx,r12d
-
- and r14d,eax
add r10d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r10d,r14d
- mov r13d,DWORD PTR[12+rsp]
- mov r12d,DWORD PTR[rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[12+rsp]
+ mov r14d,DWORD PTR[rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[44+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[44+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[8+rsp]
mov r13d,ecx
- mov r14d,ecx
+ add r12d,r14d
+ mov r14d,r10d
+ ror r13d,14
mov r15d,edx
+ mov DWORD PTR[8+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,ecx
xor r15d,r8d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r9d
+ xor r14d,r10d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,ecx
- mov DWORD PTR[8+rsp],r12d
+ mov r9d,r11d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,ecx
xor r15d,r8d
- add r12d,r9d
-
- mov r9d,r10d
- add r12d,r13d
+ xor r9d,eax
+ xor r14d,r10d
add r12d,r15d
- mov r13d,r10d
- mov r14d,r10d
+ mov r15d,r11d
- ror r9d,2
- ror r13d,13
- mov r15d,r10d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r9d,r10d
+ and r15d,eax
- xor r9d,r13d
- ror r13d,9
- or r14d,eax
+ ror r14d,2
+ add r12d,r13d
+ add r9d,r15d
- xor r9d,r13d
- and r15d,eax
add ebx,r12d
-
- and r14d,r11d
add r9d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r9d,r14d
- mov r13d,DWORD PTR[16+rsp]
- mov r12d,DWORD PTR[4+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[16+rsp]
+ mov r14d,DWORD PTR[4+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[48+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[48+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[12+rsp]
mov r13d,ebx
- mov r14d,ebx
+ add r12d,r14d
+ mov r14d,r9d
+ ror r13d,14
mov r15d,ecx
+ mov DWORD PTR[12+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,ebx
xor r15d,edx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r8d
+ xor r14d,r9d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,ebx
- mov DWORD PTR[12+rsp],r12d
+ mov r8d,r10d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,ebx
xor r15d,edx
- add r12d,r8d
-
- mov r8d,r9d
- add r12d,r13d
+ xor r8d,r11d
+ xor r14d,r9d
add r12d,r15d
- mov r13d,r9d
- mov r14d,r9d
+ mov r15d,r10d
- ror r8d,2
- ror r13d,13
- mov r15d,r9d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r8d,r9d
+ and r15d,r11d
- xor r8d,r13d
- ror r13d,9
- or r14d,r11d
+ ror r14d,2
+ add r12d,r13d
+ add r8d,r15d
- xor r8d,r13d
- and r15d,r11d
add eax,r12d
-
- and r14d,r10d
add r8d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r8d,r14d
- mov r13d,DWORD PTR[20+rsp]
- mov r12d,DWORD PTR[8+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[20+rsp]
+ mov r14d,DWORD PTR[8+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[52+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[52+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[16+rsp]
mov r13d,eax
- mov r14d,eax
+ add r12d,r14d
+ mov r14d,r8d
+ ror r13d,14
mov r15d,ebx
+ mov DWORD PTR[16+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,eax
xor r15d,ecx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,edx
+ xor r14d,r8d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,eax
- mov DWORD PTR[16+rsp],r12d
+ mov edx,r9d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,eax
xor r15d,ecx
- add r12d,edx
-
- mov edx,r8d
- add r12d,r13d
+ xor edx,r10d
+ xor r14d,r8d
add r12d,r15d
- mov r13d,r8d
- mov r14d,r8d
+ mov r15d,r9d
- ror edx,2
- ror r13d,13
- mov r15d,r8d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and edx,r8d
+ and r15d,r10d
- xor edx,r13d
- ror r13d,9
- or r14d,r10d
+ ror r14d,2
+ add r12d,r13d
+ add edx,r15d
- xor edx,r13d
- and r15d,r10d
add r11d,r12d
-
- and r14d,r9d
add edx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add edx,r14d
- mov r13d,DWORD PTR[24+rsp]
- mov r12d,DWORD PTR[12+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[24+rsp]
+ mov r14d,DWORD PTR[12+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[56+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[56+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[20+rsp]
mov r13d,r11d
- mov r14d,r11d
+ add r12d,r14d
+ mov r14d,edx
+ ror r13d,14
mov r15d,eax
+ mov DWORD PTR[20+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r11d
xor r15d,ebx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,ecx
+ xor r14d,edx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r11d
- mov DWORD PTR[20+rsp],r12d
+ mov ecx,r8d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r11d
xor r15d,ebx
- add r12d,ecx
-
- mov ecx,edx
- add r12d,r13d
+ xor ecx,r9d
+ xor r14d,edx
add r12d,r15d
- mov r13d,edx
- mov r14d,edx
+ mov r15d,r8d
- ror ecx,2
- ror r13d,13
- mov r15d,edx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and ecx,edx
+ and r15d,r9d
- xor ecx,r13d
- ror r13d,9
- or r14d,r9d
+ ror r14d,2
+ add r12d,r13d
+ add ecx,r15d
- xor ecx,r13d
- and r15d,r9d
add r10d,r12d
-
- and r14d,r8d
add ecx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add ecx,r14d
- mov r13d,DWORD PTR[28+rsp]
- mov r12d,DWORD PTR[16+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[28+rsp]
+ mov r14d,DWORD PTR[16+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[60+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[60+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[24+rsp]
mov r13d,r10d
- mov r14d,r10d
+ add r12d,r14d
+ mov r14d,ecx
+ ror r13d,14
mov r15d,r11d
+ mov DWORD PTR[24+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r10d
xor r15d,eax
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,ebx
+ xor r14d,ecx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r10d
- mov DWORD PTR[24+rsp],r12d
+ mov ebx,edx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r10d
xor r15d,eax
- add r12d,ebx
-
- mov ebx,ecx
- add r12d,r13d
+ xor ebx,r8d
+ xor r14d,ecx
add r12d,r15d
- mov r13d,ecx
- mov r14d,ecx
+ mov r15d,edx
- ror ebx,2
- ror r13d,13
- mov r15d,ecx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and ebx,ecx
+ and r15d,r8d
- xor ebx,r13d
- ror r13d,9
- or r14d,r8d
+ ror r14d,2
+ add r12d,r13d
+ add ebx,r15d
- xor ebx,r13d
- and r15d,r8d
add r9d,r12d
-
- and r14d,edx
add ebx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add ebx,r14d
- mov r13d,DWORD PTR[32+rsp]
- mov r12d,DWORD PTR[20+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[32+rsp]
+ mov r14d,DWORD PTR[20+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[28+rsp]
mov r13d,r9d
- mov r14d,r9d
+ add r12d,r14d
+ mov r14d,ebx
+ ror r13d,14
mov r15d,r10d
+ mov DWORD PTR[28+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r9d
xor r15d,r11d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,eax
+ xor r14d,ebx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r9d
- mov DWORD PTR[28+rsp],r12d
+ mov eax,ecx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r9d
xor r15d,r11d
- add r12d,eax
-
- mov eax,ebx
- add r12d,r13d
+ xor eax,edx
+ xor r14d,ebx
add r12d,r15d
- mov r13d,ebx
- mov r14d,ebx
+ mov r15d,ecx
- ror eax,2
- ror r13d,13
- mov r15d,ebx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and eax,ebx
+ and r15d,edx
- xor eax,r13d
- ror r13d,9
- or r14d,edx
+ ror r14d,2
+ add r12d,r13d
+ add eax,r15d
- xor eax,r13d
- and r15d,edx
add r8d,r12d
-
- and r14d,ecx
add eax,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add eax,r14d
- mov r13d,DWORD PTR[36+rsp]
- mov r12d,DWORD PTR[24+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[36+rsp]
+ mov r14d,DWORD PTR[24+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[4+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[4+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[32+rsp]
mov r13d,r8d
- mov r14d,r8d
+ add r12d,r14d
+ mov r14d,eax
+ ror r13d,14
mov r15d,r9d
+ mov DWORD PTR[32+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r8d
xor r15d,r10d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r11d
+ xor r14d,eax
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r8d
- mov DWORD PTR[32+rsp],r12d
+ mov r11d,ebx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r8d
xor r15d,r10d
- add r12d,r11d
-
- mov r11d,eax
- add r12d,r13d
+ xor r11d,ecx
+ xor r14d,eax
add r12d,r15d
- mov r13d,eax
- mov r14d,eax
+ mov r15d,ebx
- ror r11d,2
- ror r13d,13
- mov r15d,eax
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r11d,eax
+ and r15d,ecx
- xor r11d,r13d
- ror r13d,9
- or r14d,ecx
+ ror r14d,2
+ add r12d,r13d
+ add r11d,r15d
- xor r11d,r13d
- and r15d,ecx
add edx,r12d
-
- and r14d,ebx
add r11d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r11d,r14d
- mov r13d,DWORD PTR[40+rsp]
- mov r12d,DWORD PTR[28+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[40+rsp]
+ mov r14d,DWORD PTR[28+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[8+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[8+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[36+rsp]
mov r13d,edx
- mov r14d,edx
+ add r12d,r14d
+ mov r14d,r11d
+ ror r13d,14
mov r15d,r8d
+ mov DWORD PTR[36+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,edx
xor r15d,r9d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r10d
+ xor r14d,r11d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,edx
- mov DWORD PTR[36+rsp],r12d
+ mov r10d,eax
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,edx
xor r15d,r9d
- add r12d,r10d
-
- mov r10d,r11d
- add r12d,r13d
+ xor r10d,ebx
+ xor r14d,r11d
add r12d,r15d
- mov r13d,r11d
- mov r14d,r11d
+ mov r15d,eax
- ror r10d,2
- ror r13d,13
- mov r15d,r11d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r10d,r11d
+ and r15d,ebx
- xor r10d,r13d
- ror r13d,9
- or r14d,ebx
+ ror r14d,2
+ add r12d,r13d
+ add r10d,r15d
- xor r10d,r13d
- and r15d,ebx
add ecx,r12d
-
- and r14d,eax
add r10d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r10d,r14d
- mov r13d,DWORD PTR[44+rsp]
- mov r12d,DWORD PTR[32+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[44+rsp]
+ mov r14d,DWORD PTR[32+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[12+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[12+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[40+rsp]
mov r13d,ecx
- mov r14d,ecx
+ add r12d,r14d
+ mov r14d,r10d
+ ror r13d,14
mov r15d,edx
+ mov DWORD PTR[40+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,ecx
xor r15d,r8d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r9d
+ xor r14d,r10d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,ecx
- mov DWORD PTR[40+rsp],r12d
+ mov r9d,r11d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,ecx
xor r15d,r8d
- add r12d,r9d
-
- mov r9d,r10d
- add r12d,r13d
+ xor r9d,eax
+ xor r14d,r10d
add r12d,r15d
- mov r13d,r10d
- mov r14d,r10d
+ mov r15d,r11d
- ror r9d,2
- ror r13d,13
- mov r15d,r10d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r9d,r10d
+ and r15d,eax
- xor r9d,r13d
- ror r13d,9
- or r14d,eax
+ ror r14d,2
+ add r12d,r13d
+ add r9d,r15d
- xor r9d,r13d
- and r15d,eax
add ebx,r12d
-
- and r14d,r11d
add r9d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r9d,r14d
- mov r13d,DWORD PTR[48+rsp]
- mov r12d,DWORD PTR[36+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[48+rsp]
+ mov r14d,DWORD PTR[36+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[16+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[16+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[44+rsp]
mov r13d,ebx
- mov r14d,ebx
+ add r12d,r14d
+ mov r14d,r9d
+ ror r13d,14
mov r15d,ecx
+ mov DWORD PTR[44+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,ebx
xor r15d,edx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,r8d
+ xor r14d,r9d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,ebx
- mov DWORD PTR[44+rsp],r12d
+ mov r8d,r10d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,ebx
xor r15d,edx
- add r12d,r8d
-
- mov r8d,r9d
- add r12d,r13d
+ xor r8d,r11d
+ xor r14d,r9d
add r12d,r15d
- mov r13d,r9d
- mov r14d,r9d
+ mov r15d,r10d
- ror r8d,2
- ror r13d,13
- mov r15d,r9d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and r8d,r9d
+ and r15d,r11d
- xor r8d,r13d
- ror r13d,9
- or r14d,r11d
+ ror r14d,2
+ add r12d,r13d
+ add r8d,r15d
- xor r8d,r13d
- and r15d,r11d
add eax,r12d
-
- and r14d,r10d
add r8d,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add r8d,r14d
- mov r13d,DWORD PTR[52+rsp]
- mov r12d,DWORD PTR[40+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[52+rsp]
+ mov r14d,DWORD PTR[40+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[20+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[20+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[48+rsp]
mov r13d,eax
- mov r14d,eax
+ add r12d,r14d
+ mov r14d,r8d
+ ror r13d,14
mov r15d,ebx
+ mov DWORD PTR[48+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,eax
xor r15d,ecx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,edx
+ xor r14d,r8d
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,eax
- mov DWORD PTR[48+rsp],r12d
+ mov edx,r9d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,eax
xor r15d,ecx
- add r12d,edx
-
- mov edx,r8d
- add r12d,r13d
+ xor edx,r10d
+ xor r14d,r8d
add r12d,r15d
- mov r13d,r8d
- mov r14d,r8d
+ mov r15d,r9d
- ror edx,2
- ror r13d,13
- mov r15d,r8d
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and edx,r8d
+ and r15d,r10d
- xor edx,r13d
- ror r13d,9
- or r14d,r10d
+ ror r14d,2
+ add r12d,r13d
+ add edx,r15d
- xor edx,r13d
- and r15d,r10d
add r11d,r12d
-
- and r14d,r9d
add edx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add edx,r14d
- mov r13d,DWORD PTR[56+rsp]
- mov r12d,DWORD PTR[44+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[56+rsp]
+ mov r14d,DWORD PTR[44+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[24+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[24+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[52+rsp]
mov r13d,r11d
- mov r14d,r11d
+ add r12d,r14d
+ mov r14d,edx
+ ror r13d,14
mov r15d,eax
+ mov DWORD PTR[52+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r11d
xor r15d,ebx
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,ecx
+ xor r14d,edx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r11d
- mov DWORD PTR[52+rsp],r12d
+ mov ecx,r8d
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r11d
xor r15d,ebx
- add r12d,ecx
-
- mov ecx,edx
- add r12d,r13d
+ xor ecx,r9d
+ xor r14d,edx
add r12d,r15d
- mov r13d,edx
- mov r14d,edx
+ mov r15d,r8d
- ror ecx,2
- ror r13d,13
- mov r15d,edx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and ecx,edx
+ and r15d,r9d
- xor ecx,r13d
- ror r13d,9
- or r14d,r9d
+ ror r14d,2
+ add r12d,r13d
+ add ecx,r15d
- xor ecx,r13d
- and r15d,r9d
add r10d,r12d
-
- and r14d,r8d
add ecx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add ecx,r14d
- mov r13d,DWORD PTR[60+rsp]
- mov r12d,DWORD PTR[48+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[60+rsp]
+ mov r14d,DWORD PTR[48+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
- xor r13d,r15d
- mov r14d,r12d
-
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[28+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[28+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[56+rsp]
mov r13d,r10d
- mov r14d,r10d
+ add r12d,r14d
+ mov r14d,ecx
+ ror r13d,14
mov r15d,r11d
+ mov DWORD PTR[56+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r10d
xor r15d,eax
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,ebx
+ xor r14d,ecx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r10d
- mov DWORD PTR[56+rsp],r12d
+ mov ebx,edx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r10d
xor r15d,eax
- add r12d,ebx
-
- mov ebx,ecx
- add r12d,r13d
+ xor ebx,r8d
+ xor r14d,ecx
add r12d,r15d
- mov r13d,ecx
- mov r14d,ecx
+ mov r15d,edx
- ror ebx,2
- ror r13d,13
- mov r15d,ecx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and ebx,ecx
+ and r15d,r8d
- xor ebx,r13d
- ror r13d,9
- or r14d,r8d
+ ror r14d,2
+ add r12d,r13d
+ add ebx,r15d
- xor ebx,r13d
- and r15d,r8d
add r9d,r12d
-
- and r14d,edx
add ebx,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add ebx,r14d
- mov r13d,DWORD PTR[rsp]
- mov r12d,DWORD PTR[52+rsp]
- mov r15d,r13d
+ mov r13d,DWORD PTR[rsp]
+ mov r14d,DWORD PTR[52+rsp]
+ mov r12d,r13d
+ mov r15d,r14d
+ ror r12d,11
+ xor r12d,r13d
shr r13d,3
- ror r15d,7
-
- xor r13d,r15d
- ror r15d,11
-
- xor r13d,r15d
- mov r14d,r12d
- shr r12d,10
- ror r14d,17
-
- xor r12d,r14d
- ror r14d,2
+ ror r12d,7
+ xor r13d,r12d
+ mov r12d,DWORD PTR[32+rsp]
- xor r12d,r14d
+ ror r15d,2
+ xor r15d,r14d
+ shr r14d,10
+ ror r15d,17
add r12d,r13d
-
- add r12d,DWORD PTR[32+rsp]
+ xor r14d,r15d
add r12d,DWORD PTR[60+rsp]
mov r13d,r9d
- mov r14d,r9d
+ add r12d,r14d
+ mov r14d,ebx
+ ror r13d,14
mov r15d,r10d
+ mov DWORD PTR[60+rsp],r12d
- ror r13d,6
- ror r14d,11
+ ror r14d,9
+ xor r13d,r9d
xor r15d,r11d
- xor r13d,r14d
- ror r14d,14
+ ror r13d,5
+ add r12d,eax
+ xor r14d,ebx
+
+ add r12d,DWORD PTR[rdi*4+rbp]
and r15d,r9d
- mov DWORD PTR[60+rsp],r12d
+ mov eax,ecx
- xor r13d,r14d
+ ror r14d,11
+ xor r13d,r9d
xor r15d,r11d
- add r12d,eax
-
- mov eax,ebx
- add r12d,r13d
+ xor eax,edx
+ xor r14d,ebx
add r12d,r15d
- mov r13d,ebx
- mov r14d,ebx
+ mov r15d,ecx
- ror eax,2
- ror r13d,13
- mov r15d,ebx
- add r12d,DWORD PTR[rdi*4+rbp]
+ ror r13d,6
+ and eax,ebx
+ and r15d,edx
- xor eax,r13d
- ror r13d,9
- or r14d,edx
+ ror r14d,2
+ add r12d,r13d
+ add eax,r15d
- xor eax,r13d
- and r15d,edx
add r8d,r12d
-
- and r14d,ecx
add eax,r12d
-
- or r14d,r15d
lea rdi,QWORD PTR[1+rdi]
-
add eax,r14d
+
cmp rdi,64
jb $L$rounds_16_xx
- mov rdi,QWORD PTR[((16*4+0*8))+rsp]
- lea rsi,QWORD PTR[((16*4))+rsi]
-
- add eax,DWORD PTR[((4*0))+rdi]
- add ebx,DWORD PTR[((4*1))+rdi]
- add ecx,DWORD PTR[((4*2))+rdi]
- add edx,DWORD PTR[((4*3))+rdi]
- add r8d,DWORD PTR[((4*4))+rdi]
- add r9d,DWORD PTR[((4*5))+rdi]
- add r10d,DWORD PTR[((4*6))+rdi]
- add r11d,DWORD PTR[((4*7))+rdi]
-
- cmp rsi,QWORD PTR[((16*4+2*8))+rsp]
-
- mov DWORD PTR[((4*0))+rdi],eax
- mov DWORD PTR[((4*1))+rdi],ebx
- mov DWORD PTR[((4*2))+rdi],ecx
- mov DWORD PTR[((4*3))+rdi],edx
- mov DWORD PTR[((4*4))+rdi],r8d
- mov DWORD PTR[((4*5))+rdi],r9d
- mov DWORD PTR[((4*6))+rdi],r10d
- mov DWORD PTR[((4*7))+rdi],r11d
+ mov rdi,QWORD PTR[((64+0))+rsp]
+ lea rsi,QWORD PTR[64+rsi]
+
+ add eax,DWORD PTR[rdi]
+ add ebx,DWORD PTR[4+rdi]
+ add ecx,DWORD PTR[8+rdi]
+ add edx,DWORD PTR[12+rdi]
+ add r8d,DWORD PTR[16+rdi]
+ add r9d,DWORD PTR[20+rdi]
+ add r10d,DWORD PTR[24+rdi]
+ add r11d,DWORD PTR[28+rdi]
+
+ cmp rsi,QWORD PTR[((64+16))+rsp]
+
+ mov DWORD PTR[rdi],eax
+ mov DWORD PTR[4+rdi],ebx
+ mov DWORD PTR[8+rdi],ecx
+ mov DWORD PTR[12+rdi],edx
+ mov DWORD PTR[16+rdi],r8d
+ mov DWORD PTR[20+rdi],r9d
+ mov DWORD PTR[24+rdi],r10d
+ mov DWORD PTR[28+rdi],r11d
jb $L$loop
- mov rsi,QWORD PTR[((16*4+3*8))+rsp]
+ mov rsi,QWORD PTR[((64+24))+rsp]
mov r15,QWORD PTR[rsi]
mov r14,QWORD PTR[8+rsi]
mov r13,QWORD PTR[16+rsi]
@@ -2010,7 +1818,7 @@ se_handler PROC PRIVATE
cmp rbx,r10
jae $L$in_prologue
- mov rax,QWORD PTR[((16*4+3*8))+rax]
+ mov rax,QWORD PTR[((64+24))+rax]
lea rax,QWORD PTR[48+rax]
mov rbx,QWORD PTR[((-8))+rax]
diff --git a/deps/openssl/asm/x64-win32-masm/whrlpool/wp-x86_64.asm b/deps/openssl/asm/x64-win32-masm/whrlpool/wp-x86_64.asm
index 25337b244..42b524dc8 100644
--- a/deps/openssl/asm/x64-win32-masm/whrlpool/wp-x86_64.asm
+++ b/deps/openssl/asm/x64-win32-masm/whrlpool/wp-x86_64.asm
@@ -37,39 +37,39 @@ $L$prologue::
xor rcx,rcx
xor rdx,rdx
- mov r8,QWORD PTR[((0*8))+rdi]
- mov r9,QWORD PTR[((1*8))+rdi]
- mov r10,QWORD PTR[((2*8))+rdi]
- mov r11,QWORD PTR[((3*8))+rdi]
- mov r12,QWORD PTR[((4*8))+rdi]
- mov r13,QWORD PTR[((5*8))+rdi]
- mov r14,QWORD PTR[((6*8))+rdi]
- mov r15,QWORD PTR[((7*8))+rdi]
+ mov r8,QWORD PTR[rdi]
+ mov r9,QWORD PTR[8+rdi]
+ mov r10,QWORD PTR[16+rdi]
+ mov r11,QWORD PTR[24+rdi]
+ mov r12,QWORD PTR[32+rdi]
+ mov r13,QWORD PTR[40+rdi]
+ mov r14,QWORD PTR[48+rdi]
+ mov r15,QWORD PTR[56+rdi]
$L$outerloop::
- mov QWORD PTR[((0*8))+rsp],r8
- mov QWORD PTR[((1*8))+rsp],r9
- mov QWORD PTR[((2*8))+rsp],r10
- mov QWORD PTR[((3*8))+rsp],r11
- mov QWORD PTR[((4*8))+rsp],r12
- mov QWORD PTR[((5*8))+rsp],r13
- mov QWORD PTR[((6*8))+rsp],r14
- mov QWORD PTR[((7*8))+rsp],r15
- xor r8,QWORD PTR[((0*8))+rsi]
- xor r9,QWORD PTR[((1*8))+rsi]
- xor r10,QWORD PTR[((2*8))+rsi]
- xor r11,QWORD PTR[((3*8))+rsi]
- xor r12,QWORD PTR[((4*8))+rsi]
- xor r13,QWORD PTR[((5*8))+rsi]
- xor r14,QWORD PTR[((6*8))+rsi]
- xor r15,QWORD PTR[((7*8))+rsi]
- mov QWORD PTR[((64+0*8))+rsp],r8
- mov QWORD PTR[((64+1*8))+rsp],r9
- mov QWORD PTR[((64+2*8))+rsp],r10
- mov QWORD PTR[((64+3*8))+rsp],r11
- mov QWORD PTR[((64+4*8))+rsp],r12
- mov QWORD PTR[((64+5*8))+rsp],r13
- mov QWORD PTR[((64+6*8))+rsp],r14
- mov QWORD PTR[((64+7*8))+rsp],r15
+ mov QWORD PTR[rsp],r8
+ mov QWORD PTR[8+rsp],r9
+ mov QWORD PTR[16+rsp],r10
+ mov QWORD PTR[24+rsp],r11
+ mov QWORD PTR[32+rsp],r12
+ mov QWORD PTR[40+rsp],r13
+ mov QWORD PTR[48+rsp],r14
+ mov QWORD PTR[56+rsp],r15
+ xor r8,QWORD PTR[rsi]
+ xor r9,QWORD PTR[8+rsi]
+ xor r10,QWORD PTR[16+rsi]
+ xor r11,QWORD PTR[24+rsi]
+ xor r12,QWORD PTR[32+rsi]
+ xor r13,QWORD PTR[40+rsi]
+ xor r14,QWORD PTR[48+rsi]
+ xor r15,QWORD PTR[56+rsi]
+ mov QWORD PTR[((64+0))+rsp],r8
+ mov QWORD PTR[((64+8))+rsp],r9
+ mov QWORD PTR[((64+16))+rsp],r10
+ mov QWORD PTR[((64+24))+rsp],r11
+ mov QWORD PTR[((64+32))+rsp],r12
+ mov QWORD PTR[((64+40))+rsp],r13
+ mov QWORD PTR[((64+48))+rsp],r14
+ mov QWORD PTR[((64+56))+rsp],r15
xor rsi,rsi
mov QWORD PTR[24+rbx],rsi
ALIGN 16
@@ -86,7 +86,7 @@ $L$round::
mov r9,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((0*8+8))+rsp]
+ mov eax,DWORD PTR[((0+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
mov r10,QWORD PTR[6+rsi*8+rbp]
@@ -100,7 +100,7 @@ $L$round::
mov r13,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((0*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((0+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
mov r14,QWORD PTR[2+rsi*8+rbp]
@@ -114,7 +114,7 @@ $L$round::
xor r10,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((1*8+8))+rsp]
+ mov eax,DWORD PTR[((8+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r11,QWORD PTR[6+rsi*8+rbp]
@@ -128,7 +128,7 @@ $L$round::
xor r14,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((1*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((8+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r15,QWORD PTR[2+rsi*8+rbp]
@@ -142,7 +142,7 @@ $L$round::
xor r11,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((2*8+8))+rsp]
+ mov eax,DWORD PTR[((16+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r12,QWORD PTR[6+rsi*8+rbp]
@@ -156,7 +156,7 @@ $L$round::
xor r15,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((2*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((16+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r8,QWORD PTR[2+rsi*8+rbp]
@@ -170,7 +170,7 @@ $L$round::
xor r12,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((3*8+8))+rsp]
+ mov eax,DWORD PTR[((24+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r13,QWORD PTR[6+rsi*8+rbp]
@@ -184,7 +184,7 @@ $L$round::
xor r8,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((3*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((24+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r9,QWORD PTR[2+rsi*8+rbp]
@@ -198,7 +198,7 @@ $L$round::
xor r13,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((4*8+8))+rsp]
+ mov eax,DWORD PTR[((32+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r14,QWORD PTR[6+rsi*8+rbp]
@@ -212,7 +212,7 @@ $L$round::
xor r9,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((4*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((32+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r10,QWORD PTR[2+rsi*8+rbp]
@@ -226,7 +226,7 @@ $L$round::
xor r14,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((5*8+8))+rsp]
+ mov eax,DWORD PTR[((40+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r15,QWORD PTR[6+rsi*8+rbp]
@@ -240,7 +240,7 @@ $L$round::
xor r10,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((5*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((40+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r11,QWORD PTR[2+rsi*8+rbp]
@@ -254,7 +254,7 @@ $L$round::
xor r15,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((6*8+8))+rsp]
+ mov eax,DWORD PTR[((48+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r8,QWORD PTR[6+rsi*8+rbp]
@@ -268,7 +268,7 @@ $L$round::
xor r11,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((6*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((48+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r12,QWORD PTR[2+rsi*8+rbp]
@@ -282,7 +282,7 @@ $L$round::
xor r8,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((7*8+8))+rsp]
+ mov eax,DWORD PTR[((56+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r9,QWORD PTR[6+rsi*8+rbp]
@@ -296,19 +296,19 @@ $L$round::
xor r12,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((7*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((56+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r13,QWORD PTR[2+rsi*8+rbp]
xor r14,QWORD PTR[1+rdi*8+rbp]
- mov QWORD PTR[((0*8))+rsp],r8
- mov QWORD PTR[((1*8))+rsp],r9
- mov QWORD PTR[((2*8))+rsp],r10
- mov QWORD PTR[((3*8))+rsp],r11
- mov QWORD PTR[((4*8))+rsp],r12
- mov QWORD PTR[((5*8))+rsp],r13
- mov QWORD PTR[((6*8))+rsp],r14
- mov QWORD PTR[((7*8))+rsp],r15
+ mov QWORD PTR[rsp],r8
+ mov QWORD PTR[8+rsp],r9
+ mov QWORD PTR[16+rsp],r10
+ mov QWORD PTR[24+rsp],r11
+ mov QWORD PTR[32+rsp],r12
+ mov QWORD PTR[40+rsp],r13
+ mov QWORD PTR[48+rsp],r14
+ mov QWORD PTR[56+rsp],r15
mov cl,al
mov dl,ah
lea rsi,QWORD PTR[rcx*1+rcx]
@@ -318,7 +318,7 @@ $L$round::
xor r9,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((64+0*8+8))+rsp]
+ mov eax,DWORD PTR[((64+0+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r10,QWORD PTR[6+rsi*8+rbp]
@@ -332,7 +332,7 @@ $L$round::
xor r13,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((64+0*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((64+0+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r14,QWORD PTR[2+rsi*8+rbp]
@@ -346,7 +346,7 @@ $L$round::
xor r10,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((64+1*8+8))+rsp]
+ mov eax,DWORD PTR[((64+8+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r11,QWORD PTR[6+rsi*8+rbp]
@@ -360,7 +360,7 @@ $L$round::
xor r14,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((64+1*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((64+8+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r15,QWORD PTR[2+rsi*8+rbp]
@@ -374,7 +374,7 @@ $L$round::
xor r11,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((64+2*8+8))+rsp]
+ mov eax,DWORD PTR[((64+16+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r12,QWORD PTR[6+rsi*8+rbp]
@@ -388,7 +388,7 @@ $L$round::
xor r15,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((64+2*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((64+16+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r8,QWORD PTR[2+rsi*8+rbp]
@@ -402,7 +402,7 @@ $L$round::
xor r12,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((64+3*8+8))+rsp]
+ mov eax,DWORD PTR[((64+24+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r13,QWORD PTR[6+rsi*8+rbp]
@@ -416,7 +416,7 @@ $L$round::
xor r8,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((64+3*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((64+24+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r9,QWORD PTR[2+rsi*8+rbp]
@@ -430,7 +430,7 @@ $L$round::
xor r13,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((64+4*8+8))+rsp]
+ mov eax,DWORD PTR[((64+32+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r14,QWORD PTR[6+rsi*8+rbp]
@@ -444,7 +444,7 @@ $L$round::
xor r9,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((64+4*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((64+32+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r10,QWORD PTR[2+rsi*8+rbp]
@@ -458,7 +458,7 @@ $L$round::
xor r14,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((64+5*8+8))+rsp]
+ mov eax,DWORD PTR[((64+40+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r15,QWORD PTR[6+rsi*8+rbp]
@@ -472,7 +472,7 @@ $L$round::
xor r10,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((64+5*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((64+40+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r11,QWORD PTR[2+rsi*8+rbp]
@@ -486,7 +486,7 @@ $L$round::
xor r15,QWORD PTR[7+rdi*8+rbp]
mov cl,al
mov dl,ah
- mov eax,DWORD PTR[((64+6*8+8))+rsp]
+ mov eax,DWORD PTR[((64+48+8))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r8,QWORD PTR[6+rsi*8+rbp]
@@ -500,7 +500,7 @@ $L$round::
xor r11,QWORD PTR[3+rdi*8+rbp]
mov cl,bl
mov dl,bh
- mov ebx,DWORD PTR[((64+6*8+8+4))+rsp]
+ mov ebx,DWORD PTR[((64+48+8+4))+rsp]
lea rsi,QWORD PTR[rcx*1+rcx]
lea rdi,QWORD PTR[rdx*1+rdx]
xor r12,QWORD PTR[2+rsi*8+rbp]
@@ -540,44 +540,44 @@ $L$round::
je $L$roundsdone
mov QWORD PTR[24+rbx],rsi
- mov QWORD PTR[((64+0*8))+rsp],r8
- mov QWORD PTR[((64+1*8))+rsp],r9
- mov QWORD PTR[((64+2*8))+rsp],r10
- mov QWORD PTR[((64+3*8))+rsp],r11
- mov QWORD PTR[((64+4*8))+rsp],r12
- mov QWORD PTR[((64+5*8))+rsp],r13
- mov QWORD PTR[((64+6*8))+rsp],r14
- mov QWORD PTR[((64+7*8))+rsp],r15
+ mov QWORD PTR[((64+0))+rsp],r8
+ mov QWORD PTR[((64+8))+rsp],r9
+ mov QWORD PTR[((64+16))+rsp],r10
+ mov QWORD PTR[((64+24))+rsp],r11
+ mov QWORD PTR[((64+32))+rsp],r12
+ mov QWORD PTR[((64+40))+rsp],r13
+ mov QWORD PTR[((64+48))+rsp],r14
+ mov QWORD PTR[((64+56))+rsp],r15
jmp $L$round
ALIGN 16
$L$roundsdone::
mov rdi,QWORD PTR[rbx]
mov rsi,QWORD PTR[8+rbx]
mov rax,QWORD PTR[16+rbx]
- xor r8,QWORD PTR[((0*8))+rsi]
- xor r9,QWORD PTR[((1*8))+rsi]
- xor r10,QWORD PTR[((2*8))+rsi]
- xor r11,QWORD PTR[((3*8))+rsi]
- xor r12,QWORD PTR[((4*8))+rsi]
- xor r13,QWORD PTR[((5*8))+rsi]
- xor r14,QWORD PTR[((6*8))+rsi]
- xor r15,QWORD PTR[((7*8))+rsi]
- xor r8,QWORD PTR[((0*8))+rdi]
- xor r9,QWORD PTR[((1*8))+rdi]
- xor r10,QWORD PTR[((2*8))+rdi]
- xor r11,QWORD PTR[((3*8))+rdi]
- xor r12,QWORD PTR[((4*8))+rdi]
- xor r13,QWORD PTR[((5*8))+rdi]
- xor r14,QWORD PTR[((6*8))+rdi]
- xor r15,QWORD PTR[((7*8))+rdi]
- mov QWORD PTR[((0*8))+rdi],r8
- mov QWORD PTR[((1*8))+rdi],r9
- mov QWORD PTR[((2*8))+rdi],r10
- mov QWORD PTR[((3*8))+rdi],r11
- mov QWORD PTR[((4*8))+rdi],r12
- mov QWORD PTR[((5*8))+rdi],r13
- mov QWORD PTR[((6*8))+rdi],r14
- mov QWORD PTR[((7*8))+rdi],r15
+ xor r8,QWORD PTR[rsi]
+ xor r9,QWORD PTR[8+rsi]
+ xor r10,QWORD PTR[16+rsi]
+ xor r11,QWORD PTR[24+rsi]
+ xor r12,QWORD PTR[32+rsi]
+ xor r13,QWORD PTR[40+rsi]
+ xor r14,QWORD PTR[48+rsi]
+ xor r15,QWORD PTR[56+rsi]
+ xor r8,QWORD PTR[rdi]
+ xor r9,QWORD PTR[8+rdi]
+ xor r10,QWORD PTR[16+rdi]
+ xor r11,QWORD PTR[24+rdi]
+ xor r12,QWORD PTR[32+rdi]
+ xor r13,QWORD PTR[40+rdi]
+ xor r14,QWORD PTR[48+rdi]
+ xor r15,QWORD PTR[56+rdi]
+ mov QWORD PTR[rdi],r8
+ mov QWORD PTR[8+rdi],r9
+ mov QWORD PTR[16+rdi],r10
+ mov QWORD PTR[24+rdi],r11
+ mov QWORD PTR[32+rdi],r12
+ mov QWORD PTR[40+rdi],r13
+ mov QWORD PTR[48+rdi],r14
+ mov QWORD PTR[56+rdi],r15
lea rsi,QWORD PTR[64+rsi]
sub rax,1
jz $L$alldone
diff --git a/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm b/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm
index cdf7f90ca..497160cbc 100644
--- a/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm
+++ b/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm
@@ -1,9 +1,15 @@
OPTION DOTNAME
EXTERN OPENSSL_cpuid_setup:NEAR
+
.CRT$XCU SEGMENT READONLY ALIGN(8)
DQ OPENSSL_cpuid_setup
+
.CRT$XCU ENDS
+_DATA SEGMENT
+COMM OPENSSL_ia32cap_P:DWORD:2
+
+_DATA ENDS
.text$ SEGMENT ALIGN(64) 'CODE'
PUBLIC OPENSSL_atomic_add
@@ -68,7 +74,15 @@ OPENSSL_ia32_cpuid PROC PUBLIC
mov eax,080000000h
cpuid
- cmp eax,080000008h
+ cmp eax,080000001h
+ jb $L$intel
+ mov r10d,eax
+ mov eax,080000001h
+ cpuid
+ or r9d,ecx
+ and r9d,000000801h
+
+ cmp r10d,080000008h
jb $L$intel
mov eax,080000008h
@@ -79,12 +93,12 @@ OPENSSL_ia32_cpuid PROC PUBLIC
mov eax,1
cpuid
bt edx,28
- jnc $L$done
+ jnc $L$generic
shr ebx,16
cmp bl,r10b
- ja $L$done
+ ja $L$generic
and edx,0efffffffh
- jmp $L$done
+ jmp $L$generic
$L$intel::
cmp r11d,4
@@ -101,30 +115,48 @@ $L$intel::
$L$nocacheinfo::
mov eax,1
cpuid
+ and edx,0bfefffffh
cmp r9d,0
jne $L$notintel
- or edx,000100000h
+ or edx,040000000h
and ah,15
cmp ah,15
- je $L$notintel
- or edx,040000000h
+ jne $L$notintel
+ or edx,000100000h
$L$notintel::
bt edx,28
- jnc $L$done
+ jnc $L$generic
and edx,0efffffffh
cmp r10d,0
- je $L$done
+ je $L$generic
or edx,010000000h
shr ebx,16
cmp bl,1
- ja $L$done
+ ja $L$generic
and edx,0efffffffh
+$L$generic::
+ and r9d,000000800h
+ and ecx,0fffff7ffh
+ or r9d,ecx
+
+ mov r10d,edx
+ bt r9d,27
+ jnc $L$clear_avx
+ xor ecx,ecx
+DB 00fh,001h,0d0h
+
+ and eax,6
+ cmp eax,6
+ je $L$done
+$L$clear_avx::
+ mov eax,0efffe7ffh
+ and r9d,eax
$L$done::
- shl rcx,32
- mov eax,edx
+ shl r9,32
+ mov eax,r10d
mov rbx,r8
- or rax,rcx
+ or rax,r9
DB 0F3h,0C3h ;repret
OPENSSL_ia32_cpuid ENDP
@@ -181,6 +213,20 @@ OPENSSL_wipe_cpu PROC PUBLIC
lea rax,QWORD PTR[8+rsp]
DB 0F3h,0C3h ;repret
OPENSSL_wipe_cpu ENDP
+PUBLIC OPENSSL_ia32_rdrand
+
+ALIGN 16
+OPENSSL_ia32_rdrand PROC PUBLIC
+ mov ecx,8
+$L$oop_rdrand::
+DB 72,15,199,240
+ jc $L$break_rdrand
+ loop $L$oop_rdrand
+$L$break_rdrand::
+ cmp rax,0
+ cmove rax,rcx
+ DB 0F3h,0C3h ;repret
+OPENSSL_ia32_rdrand ENDP
.text$ ENDS
END
diff --git a/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm.orig b/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm.orig
new file mode 100644
index 000000000..cf970738b
--- /dev/null
+++ b/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm.orig
@@ -0,0 +1,235 @@
+OPTION DOTNAME
+EXTERN OPENSSL_cpuid_setup:NEAR
+<<<<<<< HEAD
+=======
+
+>>>>>>> openssl: regenerate asm files for openssl 1.0.1
+.CRT$XCU SEGMENT READONLY ALIGN(8)
+ DQ OPENSSL_cpuid_setup
+
+
+.CRT$XCU ENDS
+_DATA SEGMENT
+COMM OPENSSL_ia32cap_P:DWORD:2
+
+_DATA ENDS
+.text$ SEGMENT ALIGN(64) 'CODE'
+
+PUBLIC OPENSSL_atomic_add
+
+ALIGN 16
+OPENSSL_atomic_add PROC PUBLIC
+ mov eax,DWORD PTR[rcx]
+$L$spin:: lea r8,QWORD PTR[rax*1+rdx]
+DB 0f0h
+
+ cmpxchg DWORD PTR[rcx],r8d
+ jne $L$spin
+ mov eax,r8d
+DB 048h,098h
+
+ DB 0F3h,0C3h ;repret
+OPENSSL_atomic_add ENDP
+
+PUBLIC OPENSSL_rdtsc
+
+ALIGN 16
+OPENSSL_rdtsc PROC PUBLIC
+ rdtsc
+ shl rdx,32
+ or rax,rdx
+ DB 0F3h,0C3h ;repret
+OPENSSL_rdtsc ENDP
+
+PUBLIC OPENSSL_ia32_cpuid
+
+ALIGN 16
+OPENSSL_ia32_cpuid PROC PUBLIC
+ mov r8,rbx
+
+ xor eax,eax
+ cpuid
+ mov r11d,eax
+
+ xor eax,eax
+ cmp ebx,0756e6547h
+ setne al
+ mov r9d,eax
+ cmp edx,049656e69h
+ setne al
+ or r9d,eax
+ cmp ecx,06c65746eh
+ setne al
+ or r9d,eax
+ jz $L$intel
+
+ cmp ebx,068747541h
+ setne al
+ mov r10d,eax
+ cmp edx,069746E65h
+ setne al
+ or r10d,eax
+ cmp ecx,0444D4163h
+ setne al
+ or r10d,eax
+ jnz $L$intel
+
+
+ mov eax,080000000h
+ cpuid
+ cmp eax,080000001h
+ jb $L$intel
+ mov r10d,eax
+ mov eax,080000001h
+ cpuid
+ or r9d,ecx
+ and r9d,000000801h
+
+ cmp r10d,080000008h
+ jb $L$intel
+
+ mov eax,080000008h
+ cpuid
+ movzx r10,cl
+ inc r10
+
+ mov eax,1
+ cpuid
+ bt edx,28
+ jnc $L$generic
+ shr ebx,16
+ cmp bl,r10b
+ ja $L$generic
+ and edx,0efffffffh
+ jmp $L$generic
+
+$L$intel::
+ cmp r11d,4
+ mov r10d,-1
+ jb $L$nocacheinfo
+
+ mov eax,4
+ mov ecx,0
+ cpuid
+ mov r10d,eax
+ shr r10d,14
+ and r10d,0fffh
+
+$L$nocacheinfo::
+ mov eax,1
+ cpuid
+ and edx,0bfefffffh
+ cmp r9d,0
+ jne $L$notintel
+ or edx,040000000h
+ and ah,15
+ cmp ah,15
+ jne $L$notintel
+ or edx,000100000h
+$L$notintel::
+ bt edx,28
+ jnc $L$generic
+ and edx,0efffffffh
+ cmp r10d,0
+ je $L$generic
+
+ or edx,010000000h
+ shr ebx,16
+ cmp bl,1
+ ja $L$generic
+ and edx,0efffffffh
+$L$generic::
+ and r9d,000000800h
+ and ecx,0fffff7ffh
+ or r9d,ecx
+
+ mov r10d,edx
+ bt r9d,27
+ jnc $L$clear_avx
+ xor ecx,ecx
+DB 00fh,001h,0d0h
+
+ and eax,6
+ cmp eax,6
+ je $L$done
+$L$clear_avx::
+ mov eax,0efffe7ffh
+ and r9d,eax
+$L$done::
+ shl r9,32
+ mov eax,r10d
+ mov rbx,r8
+ or rax,r9
+ DB 0F3h,0C3h ;repret
+OPENSSL_ia32_cpuid ENDP
+
+PUBLIC OPENSSL_cleanse
+
+ALIGN 16
+OPENSSL_cleanse PROC PUBLIC
+ xor rax,rax
+ cmp rdx,15
+ jae $L$ot
+ cmp rdx,0
+ je $L$ret
+$L$ittle::
+ mov BYTE PTR[rcx],al
+ sub rdx,1
+ lea rcx,QWORD PTR[1+rcx]
+ jnz $L$ittle
+$L$ret::
+ DB 0F3h,0C3h ;repret
+ALIGN 16
+$L$ot::
+ test rcx,7
+ jz $L$aligned
+ mov BYTE PTR[rcx],al
+ lea rdx,QWORD PTR[((-1))+rdx]
+ lea rcx,QWORD PTR[1+rcx]
+ jmp $L$ot
+$L$aligned::
+ mov QWORD PTR[rcx],rax
+ lea rdx,QWORD PTR[((-8))+rdx]
+ test rdx,-8
+ lea rcx,QWORD PTR[8+rcx]
+ jnz $L$aligned
+ cmp rdx,0
+ jne $L$ittle
+ DB 0F3h,0C3h ;repret
+OPENSSL_cleanse ENDP
+PUBLIC OPENSSL_wipe_cpu
+
+ALIGN 16
+OPENSSL_wipe_cpu PROC PUBLIC
+ pxor xmm0,xmm0
+ pxor xmm1,xmm1
+ pxor xmm2,xmm2
+ pxor xmm3,xmm3
+ pxor xmm4,xmm4
+ pxor xmm5,xmm5
+ xor rcx,rcx
+ xor rdx,rdx
+ xor r8,r8
+ xor r9,r9
+ xor r10,r10
+ xor r11,r11
+ lea rax,QWORD PTR[8+rsp]
+ DB 0F3h,0C3h ;repret
+OPENSSL_wipe_cpu ENDP
+PUBLIC OPENSSL_ia32_rdrand
+
+ALIGN 16
+OPENSSL_ia32_rdrand PROC PUBLIC
+ mov ecx,8
+$L$oop_rdrand::
+DB 72,15,199,240
+ jc $L$break_rdrand
+ loop $L$oop_rdrand
+$L$break_rdrand::
+ cmp rax,0
+ cmove rax,rcx
+ DB 0F3h,0C3h ;repret
+OPENSSL_ia32_rdrand ENDP
+
+.text$ ENDS
+END
diff --git a/deps/openssl/asm/x86-elf-gas/aes/aes-586.s b/deps/openssl/asm/x86-elf-gas/aes/aes-586.s
index 34c90a068..f586d3df6 100644
--- a/deps/openssl/asm/x86-elf-gas/aes/aes-586.s
+++ b/deps/openssl/asm/x86-elf-gas/aes/aes-586.s
@@ -2986,19 +2986,19 @@ _x86_AES_set_encrypt_key:
popl %ebp
ret
.size _x86_AES_set_encrypt_key,.-_x86_AES_set_encrypt_key
-.globl AES_set_encrypt_key
-.type AES_set_encrypt_key,@function
+.globl private_AES_set_encrypt_key
+.type private_AES_set_encrypt_key,@function
.align 16
-AES_set_encrypt_key:
-.L_AES_set_encrypt_key_begin:
+private_AES_set_encrypt_key:
+.L_private_AES_set_encrypt_key_begin:
call _x86_AES_set_encrypt_key
ret
-.size AES_set_encrypt_key,.-.L_AES_set_encrypt_key_begin
-.globl AES_set_decrypt_key
-.type AES_set_decrypt_key,@function
+.size private_AES_set_encrypt_key,.-.L_private_AES_set_encrypt_key_begin
+.globl private_AES_set_decrypt_key
+.type private_AES_set_decrypt_key,@function
.align 16
-AES_set_decrypt_key:
-.L_AES_set_decrypt_key_begin:
+private_AES_set_decrypt_key:
+.L_private_AES_set_decrypt_key_begin:
call _x86_AES_set_encrypt_key
cmpl $0,%eax
je .L054proceed
@@ -3227,8 +3227,8 @@ AES_set_decrypt_key:
popl %ebx
popl %ebp
ret
-.size AES_set_decrypt_key,.-.L_AES_set_decrypt_key_begin
+.size private_AES_set_decrypt_key,.-.L_private_AES_set_decrypt_key_begin
.byte 65,69,83,32,102,111,114,32,120,56,54,44,32,67,82,89
.byte 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
.byte 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-.comm OPENSSL_ia32cap_P,4,4
+.comm OPENSSL_ia32cap_P,8,4
diff --git a/deps/openssl/asm/x86-elf-gas/aes/aesni-x86.s b/deps/openssl/asm/x86-elf-gas/aes/aesni-x86.s
new file mode 100644
index 000000000..d9f268855
--- /dev/null
+++ b/deps/openssl/asm/x86-elf-gas/aes/aesni-x86.s
@@ -0,0 +1,2143 @@
+.file "../openssl/crypto/aes/asm/aesni-x86.s"
+.text
+.globl aesni_encrypt
+.type aesni_encrypt,@function
+.align 16
+aesni_encrypt:
+.L_aesni_encrypt_begin:
+ movl 4(%esp),%eax
+ movl 12(%esp),%edx
+ movups (%eax),%xmm2
+ movl 240(%edx),%ecx
+ movl 8(%esp),%eax
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L000enc1_loop_1:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L000enc1_loop_1
+.byte 102,15,56,221,209
+ movups %xmm2,(%eax)
+ ret
+.size aesni_encrypt,.-.L_aesni_encrypt_begin
+.globl aesni_decrypt
+.type aesni_decrypt,@function
+.align 16
+aesni_decrypt:
+.L_aesni_decrypt_begin:
+ movl 4(%esp),%eax
+ movl 12(%esp),%edx
+ movups (%eax),%xmm2
+ movl 240(%edx),%ecx
+ movl 8(%esp),%eax
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L001dec1_loop_2:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L001dec1_loop_2
+.byte 102,15,56,223,209
+ movups %xmm2,(%eax)
+ ret
+.size aesni_decrypt,.-.L_aesni_decrypt_begin
+.type _aesni_encrypt3,@function
+.align 16
+_aesni_encrypt3:
+ movups (%edx),%xmm0
+ shrl $1,%ecx
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ pxor %xmm0,%xmm4
+ movups (%edx),%xmm0
+.L002enc3_loop:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %ecx
+.byte 102,15,56,220,225
+ movups 16(%edx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leal 32(%edx),%edx
+.byte 102,15,56,220,224
+ movups (%edx),%xmm0
+ jnz .L002enc3_loop
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+ ret
+.size _aesni_encrypt3,.-_aesni_encrypt3
+.type _aesni_decrypt3,@function
+.align 16
+_aesni_decrypt3:
+ movups (%edx),%xmm0
+ shrl $1,%ecx
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ pxor %xmm0,%xmm4
+ movups (%edx),%xmm0
+.L003dec3_loop:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %ecx
+.byte 102,15,56,222,225
+ movups 16(%edx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leal 32(%edx),%edx
+.byte 102,15,56,222,224
+ movups (%edx),%xmm0
+ jnz .L003dec3_loop
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+ ret
+.size _aesni_decrypt3,.-_aesni_decrypt3
+.type _aesni_encrypt4,@function
+.align 16
+_aesni_encrypt4:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ shrl $1,%ecx
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ pxor %xmm0,%xmm4
+ pxor %xmm0,%xmm5
+ movups (%edx),%xmm0
+.L004enc4_loop:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %ecx
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+ movups 16(%edx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leal 32(%edx),%edx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+ movups (%edx),%xmm0
+ jnz .L004enc4_loop
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+.byte 102,15,56,221,232
+ ret
+.size _aesni_encrypt4,.-_aesni_encrypt4
+.type _aesni_decrypt4,@function
+.align 16
+_aesni_decrypt4:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ shrl $1,%ecx
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ pxor %xmm0,%xmm4
+ pxor %xmm0,%xmm5
+ movups (%edx),%xmm0
+.L005dec4_loop:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %ecx
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+ movups 16(%edx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leal 32(%edx),%edx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+ movups (%edx),%xmm0
+ jnz .L005dec4_loop
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+.byte 102,15,56,223,232
+ ret
+.size _aesni_decrypt4,.-_aesni_decrypt4
+.type _aesni_encrypt6,@function
+.align 16
+_aesni_encrypt6:
+ movups (%edx),%xmm0
+ shrl $1,%ecx
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+.byte 102,15,56,220,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,220,217
+ pxor %xmm0,%xmm5
+ decl %ecx
+.byte 102,15,56,220,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+.byte 102,15,56,220,241
+ movups (%edx),%xmm0
+.byte 102,15,56,220,249
+ jmp .L_aesni_encrypt6_enter
+.align 16
+.L006enc6_loop:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %ecx
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.align 16
+.L_aesni_encrypt6_enter:
+ movups 16(%edx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leal 32(%edx),%edx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+ movups (%edx),%xmm0
+ jnz .L006enc6_loop
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+.byte 102,15,56,221,232
+.byte 102,15,56,221,240
+.byte 102,15,56,221,248
+ ret
+.size _aesni_encrypt6,.-_aesni_encrypt6
+.type _aesni_decrypt6,@function
+.align 16
+_aesni_decrypt6:
+ movups (%edx),%xmm0
+ shrl $1,%ecx
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+.byte 102,15,56,222,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,222,217
+ pxor %xmm0,%xmm5
+ decl %ecx
+.byte 102,15,56,222,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+.byte 102,15,56,222,241
+ movups (%edx),%xmm0
+.byte 102,15,56,222,249
+ jmp .L_aesni_decrypt6_enter
+.align 16
+.L007dec6_loop:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %ecx
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.align 16
+.L_aesni_decrypt6_enter:
+ movups 16(%edx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leal 32(%edx),%edx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+.byte 102,15,56,222,240
+.byte 102,15,56,222,248
+ movups (%edx),%xmm0
+ jnz .L007dec6_loop
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+.byte 102,15,56,223,232
+.byte 102,15,56,223,240
+.byte 102,15,56,223,248
+ ret
+.size _aesni_decrypt6,.-_aesni_decrypt6
+.globl aesni_ecb_encrypt
+.type aesni_ecb_encrypt,@function
+.align 16
+aesni_ecb_encrypt:
+.L_aesni_ecb_encrypt_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebx
+ andl $-16,%eax
+ jz .L008ecb_ret
+ movl 240(%edx),%ecx
+ testl %ebx,%ebx
+ jz .L009ecb_decrypt
+ movl %edx,%ebp
+ movl %ecx,%ebx
+ cmpl $96,%eax
+ jb .L010ecb_enc_tail
+ movdqu (%esi),%xmm2
+ movdqu 16(%esi),%xmm3
+ movdqu 32(%esi),%xmm4
+ movdqu 48(%esi),%xmm5
+ movdqu 64(%esi),%xmm6
+ movdqu 80(%esi),%xmm7
+ leal 96(%esi),%esi
+ subl $96,%eax
+ jmp .L011ecb_enc_loop6_enter
+.align 16
+.L012ecb_enc_loop6:
+ movups %xmm2,(%edi)
+ movdqu (%esi),%xmm2
+ movups %xmm3,16(%edi)
+ movdqu 16(%esi),%xmm3
+ movups %xmm4,32(%edi)
+ movdqu 32(%esi),%xmm4
+ movups %xmm5,48(%edi)
+ movdqu 48(%esi),%xmm5
+ movups %xmm6,64(%edi)
+ movdqu 64(%esi),%xmm6
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ movdqu 80(%esi),%xmm7
+ leal 96(%esi),%esi
+.L011ecb_enc_loop6_enter:
+ call _aesni_encrypt6
+ movl %ebp,%edx
+ movl %ebx,%ecx
+ subl $96,%eax
+ jnc .L012ecb_enc_loop6
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ addl $96,%eax
+ jz .L008ecb_ret
+.L010ecb_enc_tail:
+ movups (%esi),%xmm2
+ cmpl $32,%eax
+ jb .L013ecb_enc_one
+ movups 16(%esi),%xmm3
+ je .L014ecb_enc_two
+ movups 32(%esi),%xmm4
+ cmpl $64,%eax
+ jb .L015ecb_enc_three
+ movups 48(%esi),%xmm5
+ je .L016ecb_enc_four
+ movups 64(%esi),%xmm6
+ xorps %xmm7,%xmm7
+ call _aesni_encrypt6
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ jmp .L008ecb_ret
+.align 16
+.L013ecb_enc_one:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L017enc1_loop_3:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L017enc1_loop_3
+.byte 102,15,56,221,209
+ movups %xmm2,(%edi)
+ jmp .L008ecb_ret
+.align 16
+.L014ecb_enc_two:
+ xorps %xmm4,%xmm4
+ call _aesni_encrypt3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ jmp .L008ecb_ret
+.align 16
+.L015ecb_enc_three:
+ call _aesni_encrypt3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ jmp .L008ecb_ret
+.align 16
+.L016ecb_enc_four:
+ call _aesni_encrypt4
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ jmp .L008ecb_ret
+.align 16
+.L009ecb_decrypt:
+ movl %edx,%ebp
+ movl %ecx,%ebx
+ cmpl $96,%eax
+ jb .L018ecb_dec_tail
+ movdqu (%esi),%xmm2
+ movdqu 16(%esi),%xmm3
+ movdqu 32(%esi),%xmm4
+ movdqu 48(%esi),%xmm5
+ movdqu 64(%esi),%xmm6
+ movdqu 80(%esi),%xmm7
+ leal 96(%esi),%esi
+ subl $96,%eax
+ jmp .L019ecb_dec_loop6_enter
+.align 16
+.L020ecb_dec_loop6:
+ movups %xmm2,(%edi)
+ movdqu (%esi),%xmm2
+ movups %xmm3,16(%edi)
+ movdqu 16(%esi),%xmm3
+ movups %xmm4,32(%edi)
+ movdqu 32(%esi),%xmm4
+ movups %xmm5,48(%edi)
+ movdqu 48(%esi),%xmm5
+ movups %xmm6,64(%edi)
+ movdqu 64(%esi),%xmm6
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ movdqu 80(%esi),%xmm7
+ leal 96(%esi),%esi
+.L019ecb_dec_loop6_enter:
+ call _aesni_decrypt6
+ movl %ebp,%edx
+ movl %ebx,%ecx
+ subl $96,%eax
+ jnc .L020ecb_dec_loop6
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ addl $96,%eax
+ jz .L008ecb_ret
+.L018ecb_dec_tail:
+ movups (%esi),%xmm2
+ cmpl $32,%eax
+ jb .L021ecb_dec_one
+ movups 16(%esi),%xmm3
+ je .L022ecb_dec_two
+ movups 32(%esi),%xmm4
+ cmpl $64,%eax
+ jb .L023ecb_dec_three
+ movups 48(%esi),%xmm5
+ je .L024ecb_dec_four
+ movups 64(%esi),%xmm6
+ xorps %xmm7,%xmm7
+ call _aesni_decrypt6
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ jmp .L008ecb_ret
+.align 16
+.L021ecb_dec_one:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L025dec1_loop_4:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L025dec1_loop_4
+.byte 102,15,56,223,209
+ movups %xmm2,(%edi)
+ jmp .L008ecb_ret
+.align 16
+.L022ecb_dec_two:
+ xorps %xmm4,%xmm4
+ call _aesni_decrypt3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ jmp .L008ecb_ret
+.align 16
+.L023ecb_dec_three:
+ call _aesni_decrypt3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ jmp .L008ecb_ret
+.align 16
+.L024ecb_dec_four:
+ call _aesni_decrypt4
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+.L008ecb_ret:
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.size aesni_ecb_encrypt,.-.L_aesni_ecb_encrypt_begin
+.globl aesni_ccm64_encrypt_blocks
+.type aesni_ccm64_encrypt_blocks,@function
+.align 16
+aesni_ccm64_encrypt_blocks:
+.L_aesni_ccm64_encrypt_blocks_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebx
+ movl 40(%esp),%ecx
+ movl %esp,%ebp
+ subl $60,%esp
+ andl $-16,%esp
+ movl %ebp,48(%esp)
+ movdqu (%ebx),%xmm7
+ movdqu (%ecx),%xmm3
+ movl 240(%edx),%ecx
+ movl $202182159,(%esp)
+ movl $134810123,4(%esp)
+ movl $67438087,8(%esp)
+ movl $66051,12(%esp)
+ movl $1,%ebx
+ xorl %ebp,%ebp
+ movl %ebx,16(%esp)
+ movl %ebp,20(%esp)
+ movl %ebp,24(%esp)
+ movl %ebp,28(%esp)
+ shrl $1,%ecx
+ leal (%edx),%ebp
+ movdqa (%esp),%xmm5
+ movdqa %xmm7,%xmm2
+ movl %ecx,%ebx
+.byte 102,15,56,0,253
+.L026ccm64_enc_outer:
+ movups (%ebp),%xmm0
+ movl %ebx,%ecx
+ movups (%esi),%xmm6
+ xorps %xmm0,%xmm2
+ movups 16(%ebp),%xmm1
+ xorps %xmm6,%xmm0
+ leal 32(%ebp),%edx
+ xorps %xmm0,%xmm3
+ movups (%edx),%xmm0
+.L027ccm64_enc2_loop:
+.byte 102,15,56,220,209
+ decl %ecx
+.byte 102,15,56,220,217
+ movups 16(%edx),%xmm1
+.byte 102,15,56,220,208
+ leal 32(%edx),%edx
+.byte 102,15,56,220,216
+ movups (%edx),%xmm0
+ jnz .L027ccm64_enc2_loop
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ paddq 16(%esp),%xmm7
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+ decl %eax
+ leal 16(%esi),%esi
+ xorps %xmm2,%xmm6
+ movdqa %xmm7,%xmm2
+ movups %xmm6,(%edi)
+ leal 16(%edi),%edi
+.byte 102,15,56,0,213
+ jnz .L026ccm64_enc_outer
+ movl 48(%esp),%esp
+ movl 40(%esp),%edi
+ movups %xmm3,(%edi)
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.size aesni_ccm64_encrypt_blocks,.-.L_aesni_ccm64_encrypt_blocks_begin
+.globl aesni_ccm64_decrypt_blocks
+.type aesni_ccm64_decrypt_blocks,@function
+.align 16
+aesni_ccm64_decrypt_blocks:
+.L_aesni_ccm64_decrypt_blocks_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebx
+ movl 40(%esp),%ecx
+ movl %esp,%ebp
+ subl $60,%esp
+ andl $-16,%esp
+ movl %ebp,48(%esp)
+ movdqu (%ebx),%xmm7
+ movdqu (%ecx),%xmm3
+ movl 240(%edx),%ecx
+ movl $202182159,(%esp)
+ movl $134810123,4(%esp)
+ movl $67438087,8(%esp)
+ movl $66051,12(%esp)
+ movl $1,%ebx
+ xorl %ebp,%ebp
+ movl %ebx,16(%esp)
+ movl %ebp,20(%esp)
+ movl %ebp,24(%esp)
+ movl %ebp,28(%esp)
+ movdqa (%esp),%xmm5
+ movdqa %xmm7,%xmm2
+ movl %edx,%ebp
+ movl %ecx,%ebx
+.byte 102,15,56,0,253
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L028enc1_loop_5:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L028enc1_loop_5
+.byte 102,15,56,221,209
+ movups (%esi),%xmm6
+ paddq 16(%esp),%xmm7
+ leal 16(%esi),%esi
+ jmp .L029ccm64_dec_outer
+.align 16
+.L029ccm64_dec_outer:
+ xorps %xmm2,%xmm6
+ movdqa %xmm7,%xmm2
+ movl %ebx,%ecx
+ movups %xmm6,(%edi)
+ leal 16(%edi),%edi
+.byte 102,15,56,0,213
+ subl $1,%eax
+ jz .L030ccm64_dec_break
+ movups (%ebp),%xmm0
+ shrl $1,%ecx
+ movups 16(%ebp),%xmm1
+ xorps %xmm0,%xmm6
+ leal 32(%ebp),%edx
+ xorps %xmm0,%xmm2
+ xorps %xmm6,%xmm3
+ movups (%edx),%xmm0
+.L031ccm64_dec2_loop:
+.byte 102,15,56,220,209
+ decl %ecx
+.byte 102,15,56,220,217
+ movups 16(%edx),%xmm1
+.byte 102,15,56,220,208
+ leal 32(%edx),%edx
+.byte 102,15,56,220,216
+ movups (%edx),%xmm0
+ jnz .L031ccm64_dec2_loop
+ movups (%esi),%xmm6
+ paddq 16(%esp),%xmm7
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ leal 16(%esi),%esi
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+ jmp .L029ccm64_dec_outer
+.align 16
+.L030ccm64_dec_break:
+ movl %ebp,%edx
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ xorps %xmm0,%xmm6
+ leal 32(%edx),%edx
+ xorps %xmm6,%xmm3
+.L032enc1_loop_6:
+.byte 102,15,56,220,217
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L032enc1_loop_6
+.byte 102,15,56,221,217
+ movl 48(%esp),%esp
+ movl 40(%esp),%edi
+ movups %xmm3,(%edi)
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.size aesni_ccm64_decrypt_blocks,.-.L_aesni_ccm64_decrypt_blocks_begin
+.globl aesni_ctr32_encrypt_blocks
+.type aesni_ctr32_encrypt_blocks,@function
+.align 16
+aesni_ctr32_encrypt_blocks:
+.L_aesni_ctr32_encrypt_blocks_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebx
+ movl %esp,%ebp
+ subl $88,%esp
+ andl $-16,%esp
+ movl %ebp,80(%esp)
+ cmpl $1,%eax
+ je .L033ctr32_one_shortcut
+ movdqu (%ebx),%xmm7
+ movl $202182159,(%esp)
+ movl $134810123,4(%esp)
+ movl $67438087,8(%esp)
+ movl $66051,12(%esp)
+ movl $6,%ecx
+ xorl %ebp,%ebp
+ movl %ecx,16(%esp)
+ movl %ecx,20(%esp)
+ movl %ecx,24(%esp)
+ movl %ebp,28(%esp)
+.byte 102,15,58,22,251,3
+.byte 102,15,58,34,253,3
+ movl 240(%edx),%ecx
+ bswap %ebx
+ pxor %xmm1,%xmm1
+ pxor %xmm0,%xmm0
+ movdqa (%esp),%xmm2
+.byte 102,15,58,34,203,0
+ leal 3(%ebx),%ebp
+.byte 102,15,58,34,197,0
+ incl %ebx
+.byte 102,15,58,34,203,1
+ incl %ebp
+.byte 102,15,58,34,197,1
+ incl %ebx
+.byte 102,15,58,34,203,2
+ incl %ebp
+.byte 102,15,58,34,197,2
+ movdqa %xmm1,48(%esp)
+.byte 102,15,56,0,202
+ movdqa %xmm0,64(%esp)
+.byte 102,15,56,0,194
+ pshufd $192,%xmm1,%xmm2
+ pshufd $128,%xmm1,%xmm3
+ cmpl $6,%eax
+ jb .L034ctr32_tail
+ movdqa %xmm7,32(%esp)
+ shrl $1,%ecx
+ movl %edx,%ebp
+ movl %ecx,%ebx
+ subl $6,%eax
+ jmp .L035ctr32_loop6
+.align 16
+.L035ctr32_loop6:
+ pshufd $64,%xmm1,%xmm4
+ movdqa 32(%esp),%xmm1
+ pshufd $192,%xmm0,%xmm5
+ por %xmm1,%xmm2
+ pshufd $128,%xmm0,%xmm6
+ por %xmm1,%xmm3
+ pshufd $64,%xmm0,%xmm7
+ por %xmm1,%xmm4
+ por %xmm1,%xmm5
+ por %xmm1,%xmm6
+ por %xmm1,%xmm7
+ movups (%ebp),%xmm0
+ movups 16(%ebp),%xmm1
+ leal 32(%ebp),%edx
+ decl %ecx
+ pxor %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+.byte 102,15,56,220,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,220,217
+ pxor %xmm0,%xmm5
+.byte 102,15,56,220,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+.byte 102,15,56,220,241
+ movups (%edx),%xmm0
+.byte 102,15,56,220,249
+ call .L_aesni_encrypt6_enter
+ movups (%esi),%xmm1
+ movups 16(%esi),%xmm0
+ xorps %xmm1,%xmm2
+ movups 32(%esi),%xmm1
+ xorps %xmm0,%xmm3
+ movups %xmm2,(%edi)
+ movdqa 16(%esp),%xmm0
+ xorps %xmm1,%xmm4
+ movdqa 48(%esp),%xmm1
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ paddd %xmm0,%xmm1
+ paddd 64(%esp),%xmm0
+ movdqa (%esp),%xmm2
+ movups 48(%esi),%xmm3
+ movups 64(%esi),%xmm4
+ xorps %xmm3,%xmm5
+ movups 80(%esi),%xmm3
+ leal 96(%esi),%esi
+ movdqa %xmm1,48(%esp)
+.byte 102,15,56,0,202
+ xorps %xmm4,%xmm6
+ movups %xmm5,48(%edi)
+ xorps %xmm3,%xmm7
+ movdqa %xmm0,64(%esp)
+.byte 102,15,56,0,194
+ movups %xmm6,64(%edi)
+ pshufd $192,%xmm1,%xmm2
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ movl %ebx,%ecx
+ pshufd $128,%xmm1,%xmm3
+ subl $6,%eax
+ jnc .L035ctr32_loop6
+ addl $6,%eax
+ jz .L036ctr32_ret
+ movl %ebp,%edx
+ leal 1(,%ecx,2),%ecx
+ movdqa 32(%esp),%xmm7
+.L034ctr32_tail:
+ por %xmm7,%xmm2
+ cmpl $2,%eax
+ jb .L037ctr32_one
+ pshufd $64,%xmm1,%xmm4
+ por %xmm7,%xmm3
+ je .L038ctr32_two
+ pshufd $192,%xmm0,%xmm5
+ por %xmm7,%xmm4
+ cmpl $4,%eax
+ jb .L039ctr32_three
+ pshufd $128,%xmm0,%xmm6
+ por %xmm7,%xmm5
+ je .L040ctr32_four
+ por %xmm7,%xmm6
+ call _aesni_encrypt6
+ movups (%esi),%xmm1
+ movups 16(%esi),%xmm0
+ xorps %xmm1,%xmm2
+ movups 32(%esi),%xmm1
+ xorps %xmm0,%xmm3
+ movups 48(%esi),%xmm0
+ xorps %xmm1,%xmm4
+ movups 64(%esi),%xmm1
+ xorps %xmm0,%xmm5
+ movups %xmm2,(%edi)
+ xorps %xmm1,%xmm6
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ jmp .L036ctr32_ret
+.align 16
+.L033ctr32_one_shortcut:
+ movups (%ebx),%xmm2
+ movl 240(%edx),%ecx
+.L037ctr32_one:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L041enc1_loop_7:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L041enc1_loop_7
+.byte 102,15,56,221,209
+ movups (%esi),%xmm6
+ xorps %xmm2,%xmm6
+ movups %xmm6,(%edi)
+ jmp .L036ctr32_ret
+.align 16
+.L038ctr32_two:
+ call _aesni_encrypt3
+ movups (%esi),%xmm5
+ movups 16(%esi),%xmm6
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ jmp .L036ctr32_ret
+.align 16
+.L039ctr32_three:
+ call _aesni_encrypt3
+ movups (%esi),%xmm5
+ movups 16(%esi),%xmm6
+ xorps %xmm5,%xmm2
+ movups 32(%esi),%xmm7
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ xorps %xmm7,%xmm4
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ jmp .L036ctr32_ret
+.align 16
+.L040ctr32_four:
+ call _aesni_encrypt4
+ movups (%esi),%xmm6
+ movups 16(%esi),%xmm7
+ movups 32(%esi),%xmm1
+ xorps %xmm6,%xmm2
+ movups 48(%esi),%xmm0
+ xorps %xmm7,%xmm3
+ movups %xmm2,(%edi)
+ xorps %xmm1,%xmm4
+ movups %xmm3,16(%edi)
+ xorps %xmm0,%xmm5
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+.L036ctr32_ret:
+ movl 80(%esp),%esp
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.size aesni_ctr32_encrypt_blocks,.-.L_aesni_ctr32_encrypt_blocks_begin
+.globl aesni_xts_encrypt
+.type aesni_xts_encrypt,@function
+.align 16
+aesni_xts_encrypt:
+.L_aesni_xts_encrypt_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 36(%esp),%edx
+ movl 40(%esp),%esi
+ movl 240(%edx),%ecx
+ movups (%esi),%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L042enc1_loop_8:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L042enc1_loop_8
+.byte 102,15,56,221,209
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl %esp,%ebp
+ subl $120,%esp
+ movl 240(%edx),%ecx
+ andl $-16,%esp
+ movl $135,96(%esp)
+ movl $0,100(%esp)
+ movl $1,104(%esp)
+ movl $0,108(%esp)
+ movl %eax,112(%esp)
+ movl %ebp,116(%esp)
+ movdqa %xmm2,%xmm1
+ pxor %xmm0,%xmm0
+ movdqa 96(%esp),%xmm3
+ pcmpgtd %xmm1,%xmm0
+ andl $-16,%eax
+ movl %edx,%ebp
+ movl %ecx,%ebx
+ subl $96,%eax
+ jc .L043xts_enc_short
+ shrl $1,%ecx
+ movl %ecx,%ebx
+ jmp .L044xts_enc_loop6
+.align 16
+.L044xts_enc_loop6:
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,16(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,32(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,48(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm7
+ movdqa %xmm1,64(%esp)
+ paddq %xmm1,%xmm1
+ movups (%ebp),%xmm0
+ pand %xmm3,%xmm7
+ movups (%esi),%xmm2
+ pxor %xmm1,%xmm7
+ movdqu 16(%esi),%xmm3
+ xorps %xmm0,%xmm2
+ movdqu 32(%esi),%xmm4
+ pxor %xmm0,%xmm3
+ movdqu 48(%esi),%xmm5
+ pxor %xmm0,%xmm4
+ movdqu 64(%esi),%xmm6
+ pxor %xmm0,%xmm5
+ movdqu 80(%esi),%xmm1
+ pxor %xmm0,%xmm6
+ leal 96(%esi),%esi
+ pxor (%esp),%xmm2
+ movdqa %xmm7,80(%esp)
+ pxor %xmm1,%xmm7
+ movups 16(%ebp),%xmm1
+ leal 32(%ebp),%edx
+ pxor 16(%esp),%xmm3
+.byte 102,15,56,220,209
+ pxor 32(%esp),%xmm4
+.byte 102,15,56,220,217
+ pxor 48(%esp),%xmm5
+ decl %ecx
+.byte 102,15,56,220,225
+ pxor 64(%esp),%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+.byte 102,15,56,220,241
+ movups (%edx),%xmm0
+.byte 102,15,56,220,249
+ call .L_aesni_encrypt6_enter
+ movdqa 80(%esp),%xmm1
+ pxor %xmm0,%xmm0
+ xorps (%esp),%xmm2
+ pcmpgtd %xmm1,%xmm0
+ xorps 16(%esp),%xmm3
+ movups %xmm2,(%edi)
+ xorps 32(%esp),%xmm4
+ movups %xmm3,16(%edi)
+ xorps 48(%esp),%xmm5
+ movups %xmm4,32(%edi)
+ xorps 64(%esp),%xmm6
+ movups %xmm5,48(%edi)
+ xorps %xmm1,%xmm7
+ movups %xmm6,64(%edi)
+ pshufd $19,%xmm0,%xmm2
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ movdqa 96(%esp),%xmm3
+ pxor %xmm0,%xmm0
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ movl %ebx,%ecx
+ pxor %xmm2,%xmm1
+ subl $96,%eax
+ jnc .L044xts_enc_loop6
+ leal 1(,%ecx,2),%ecx
+ movl %ebp,%edx
+ movl %ecx,%ebx
+.L043xts_enc_short:
+ addl $96,%eax
+ jz .L045xts_enc_done6x
+ movdqa %xmm1,%xmm5
+ cmpl $32,%eax
+ jb .L046xts_enc_one
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ je .L047xts_enc_two
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,%xmm6
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ cmpl $64,%eax
+ jb .L048xts_enc_three
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,%xmm7
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ movdqa %xmm5,(%esp)
+ movdqa %xmm6,16(%esp)
+ je .L049xts_enc_four
+ movdqa %xmm7,32(%esp)
+ pshufd $19,%xmm0,%xmm7
+ movdqa %xmm1,48(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm7
+ pxor %xmm1,%xmm7
+ movdqu (%esi),%xmm2
+ movdqu 16(%esi),%xmm3
+ movdqu 32(%esi),%xmm4
+ pxor (%esp),%xmm2
+ movdqu 48(%esi),%xmm5
+ pxor 16(%esp),%xmm3
+ movdqu 64(%esi),%xmm6
+ pxor 32(%esp),%xmm4
+ leal 80(%esi),%esi
+ pxor 48(%esp),%xmm5
+ movdqa %xmm7,64(%esp)
+ pxor %xmm7,%xmm6
+ call _aesni_encrypt6
+ movaps 64(%esp),%xmm1
+ xorps (%esp),%xmm2
+ xorps 16(%esp),%xmm3
+ xorps 32(%esp),%xmm4
+ movups %xmm2,(%edi)
+ xorps 48(%esp),%xmm5
+ movups %xmm3,16(%edi)
+ xorps %xmm1,%xmm6
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ leal 80(%edi),%edi
+ jmp .L050xts_enc_done
+.align 16
+.L046xts_enc_one:
+ movups (%esi),%xmm2
+ leal 16(%esi),%esi
+ xorps %xmm5,%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L051enc1_loop_9:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L051enc1_loop_9
+.byte 102,15,56,221,209
+ xorps %xmm5,%xmm2
+ movups %xmm2,(%edi)
+ leal 16(%edi),%edi
+ movdqa %xmm5,%xmm1
+ jmp .L050xts_enc_done
+.align 16
+.L047xts_enc_two:
+ movaps %xmm1,%xmm6
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ leal 32(%esi),%esi
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm4,%xmm4
+ call _aesni_encrypt3
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ leal 32(%edi),%edi
+ movdqa %xmm6,%xmm1
+ jmp .L050xts_enc_done
+.align 16
+.L048xts_enc_three:
+ movaps %xmm1,%xmm7
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ movups 32(%esi),%xmm4
+ leal 48(%esi),%esi
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm7,%xmm4
+ call _aesni_encrypt3
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm7,%xmm4
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ leal 48(%edi),%edi
+ movdqa %xmm7,%xmm1
+ jmp .L050xts_enc_done
+.align 16
+.L049xts_enc_four:
+ movaps %xmm1,%xmm6
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ movups 32(%esi),%xmm4
+ xorps (%esp),%xmm2
+ movups 48(%esi),%xmm5
+ leal 64(%esi),%esi
+ xorps 16(%esp),%xmm3
+ xorps %xmm7,%xmm4
+ xorps %xmm6,%xmm5
+ call _aesni_encrypt4
+ xorps (%esp),%xmm2
+ xorps 16(%esp),%xmm3
+ xorps %xmm7,%xmm4
+ movups %xmm2,(%edi)
+ xorps %xmm6,%xmm5
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ leal 64(%edi),%edi
+ movdqa %xmm6,%xmm1
+ jmp .L050xts_enc_done
+.align 16
+.L045xts_enc_done6x:
+ movl 112(%esp),%eax
+ andl $15,%eax
+ jz .L052xts_enc_ret
+ movdqa %xmm1,%xmm5
+ movl %eax,112(%esp)
+ jmp .L053xts_enc_steal
+.align 16
+.L050xts_enc_done:
+ movl 112(%esp),%eax
+ pxor %xmm0,%xmm0
+ andl $15,%eax
+ jz .L052xts_enc_ret
+ pcmpgtd %xmm1,%xmm0
+ movl %eax,112(%esp)
+ pshufd $19,%xmm0,%xmm5
+ paddq %xmm1,%xmm1
+ pand 96(%esp),%xmm5
+ pxor %xmm1,%xmm5
+.L053xts_enc_steal:
+ movzbl (%esi),%ecx
+ movzbl -16(%edi),%edx
+ leal 1(%esi),%esi
+ movb %cl,-16(%edi)
+ movb %dl,(%edi)
+ leal 1(%edi),%edi
+ subl $1,%eax
+ jnz .L053xts_enc_steal
+ subl 112(%esp),%edi
+ movl %ebp,%edx
+ movl %ebx,%ecx
+ movups -16(%edi),%xmm2
+ xorps %xmm5,%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L054enc1_loop_10:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L054enc1_loop_10
+.byte 102,15,56,221,209
+ xorps %xmm5,%xmm2
+ movups %xmm2,-16(%edi)
+.L052xts_enc_ret:
+ movl 116(%esp),%esp
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.size aesni_xts_encrypt,.-.L_aesni_xts_encrypt_begin
+.globl aesni_xts_decrypt
+.type aesni_xts_decrypt,@function
+.align 16
+aesni_xts_decrypt:
+.L_aesni_xts_decrypt_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 36(%esp),%edx
+ movl 40(%esp),%esi
+ movl 240(%edx),%ecx
+ movups (%esi),%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L055enc1_loop_11:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L055enc1_loop_11
+.byte 102,15,56,221,209
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl %esp,%ebp
+ subl $120,%esp
+ andl $-16,%esp
+ xorl %ebx,%ebx
+ testl $15,%eax
+ setnz %bl
+ shll $4,%ebx
+ subl %ebx,%eax
+ movl $135,96(%esp)
+ movl $0,100(%esp)
+ movl $1,104(%esp)
+ movl $0,108(%esp)
+ movl %eax,112(%esp)
+ movl %ebp,116(%esp)
+ movl 240(%edx),%ecx
+ movl %edx,%ebp
+ movl %ecx,%ebx
+ movdqa %xmm2,%xmm1
+ pxor %xmm0,%xmm0
+ movdqa 96(%esp),%xmm3
+ pcmpgtd %xmm1,%xmm0
+ andl $-16,%eax
+ subl $96,%eax
+ jc .L056xts_dec_short
+ shrl $1,%ecx
+ movl %ecx,%ebx
+ jmp .L057xts_dec_loop6
+.align 16
+.L057xts_dec_loop6:
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,16(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,32(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,48(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm7
+ movdqa %xmm1,64(%esp)
+ paddq %xmm1,%xmm1
+ movups (%ebp),%xmm0
+ pand %xmm3,%xmm7
+ movups (%esi),%xmm2
+ pxor %xmm1,%xmm7
+ movdqu 16(%esi),%xmm3
+ xorps %xmm0,%xmm2
+ movdqu 32(%esi),%xmm4
+ pxor %xmm0,%xmm3
+ movdqu 48(%esi),%xmm5
+ pxor %xmm0,%xmm4
+ movdqu 64(%esi),%xmm6
+ pxor %xmm0,%xmm5
+ movdqu 80(%esi),%xmm1
+ pxor %xmm0,%xmm6
+ leal 96(%esi),%esi
+ pxor (%esp),%xmm2
+ movdqa %xmm7,80(%esp)
+ pxor %xmm1,%xmm7
+ movups 16(%ebp),%xmm1
+ leal 32(%ebp),%edx
+ pxor 16(%esp),%xmm3
+.byte 102,15,56,222,209
+ pxor 32(%esp),%xmm4
+.byte 102,15,56,222,217
+ pxor 48(%esp),%xmm5
+ decl %ecx
+.byte 102,15,56,222,225
+ pxor 64(%esp),%xmm6
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+.byte 102,15,56,222,241
+ movups (%edx),%xmm0
+.byte 102,15,56,222,249
+ call .L_aesni_decrypt6_enter
+ movdqa 80(%esp),%xmm1
+ pxor %xmm0,%xmm0
+ xorps (%esp),%xmm2
+ pcmpgtd %xmm1,%xmm0
+ xorps 16(%esp),%xmm3
+ movups %xmm2,(%edi)
+ xorps 32(%esp),%xmm4
+ movups %xmm3,16(%edi)
+ xorps 48(%esp),%xmm5
+ movups %xmm4,32(%edi)
+ xorps 64(%esp),%xmm6
+ movups %xmm5,48(%edi)
+ xorps %xmm1,%xmm7
+ movups %xmm6,64(%edi)
+ pshufd $19,%xmm0,%xmm2
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ movdqa 96(%esp),%xmm3
+ pxor %xmm0,%xmm0
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ movl %ebx,%ecx
+ pxor %xmm2,%xmm1
+ subl $96,%eax
+ jnc .L057xts_dec_loop6
+ leal 1(,%ecx,2),%ecx
+ movl %ebp,%edx
+ movl %ecx,%ebx
+.L056xts_dec_short:
+ addl $96,%eax
+ jz .L058xts_dec_done6x
+ movdqa %xmm1,%xmm5
+ cmpl $32,%eax
+ jb .L059xts_dec_one
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ je .L060xts_dec_two
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,%xmm6
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ cmpl $64,%eax
+ jb .L061xts_dec_three
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,%xmm7
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ movdqa %xmm5,(%esp)
+ movdqa %xmm6,16(%esp)
+ je .L062xts_dec_four
+ movdqa %xmm7,32(%esp)
+ pshufd $19,%xmm0,%xmm7
+ movdqa %xmm1,48(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm7
+ pxor %xmm1,%xmm7
+ movdqu (%esi),%xmm2
+ movdqu 16(%esi),%xmm3
+ movdqu 32(%esi),%xmm4
+ pxor (%esp),%xmm2
+ movdqu 48(%esi),%xmm5
+ pxor 16(%esp),%xmm3
+ movdqu 64(%esi),%xmm6
+ pxor 32(%esp),%xmm4
+ leal 80(%esi),%esi
+ pxor 48(%esp),%xmm5
+ movdqa %xmm7,64(%esp)
+ pxor %xmm7,%xmm6
+ call _aesni_decrypt6
+ movaps 64(%esp),%xmm1
+ xorps (%esp),%xmm2
+ xorps 16(%esp),%xmm3
+ xorps 32(%esp),%xmm4
+ movups %xmm2,(%edi)
+ xorps 48(%esp),%xmm5
+ movups %xmm3,16(%edi)
+ xorps %xmm1,%xmm6
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ leal 80(%edi),%edi
+ jmp .L063xts_dec_done
+.align 16
+.L059xts_dec_one:
+ movups (%esi),%xmm2
+ leal 16(%esi),%esi
+ xorps %xmm5,%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L064dec1_loop_12:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L064dec1_loop_12
+.byte 102,15,56,223,209
+ xorps %xmm5,%xmm2
+ movups %xmm2,(%edi)
+ leal 16(%edi),%edi
+ movdqa %xmm5,%xmm1
+ jmp .L063xts_dec_done
+.align 16
+.L060xts_dec_two:
+ movaps %xmm1,%xmm6
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ leal 32(%esi),%esi
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ call _aesni_decrypt3
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ leal 32(%edi),%edi
+ movdqa %xmm6,%xmm1
+ jmp .L063xts_dec_done
+.align 16
+.L061xts_dec_three:
+ movaps %xmm1,%xmm7
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ movups 32(%esi),%xmm4
+ leal 48(%esi),%esi
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm7,%xmm4
+ call _aesni_decrypt3
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm7,%xmm4
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ leal 48(%edi),%edi
+ movdqa %xmm7,%xmm1
+ jmp .L063xts_dec_done
+.align 16
+.L062xts_dec_four:
+ movaps %xmm1,%xmm6
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ movups 32(%esi),%xmm4
+ xorps (%esp),%xmm2
+ movups 48(%esi),%xmm5
+ leal 64(%esi),%esi
+ xorps 16(%esp),%xmm3
+ xorps %xmm7,%xmm4
+ xorps %xmm6,%xmm5
+ call _aesni_decrypt4
+ xorps (%esp),%xmm2
+ xorps 16(%esp),%xmm3
+ xorps %xmm7,%xmm4
+ movups %xmm2,(%edi)
+ xorps %xmm6,%xmm5
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ leal 64(%edi),%edi
+ movdqa %xmm6,%xmm1
+ jmp .L063xts_dec_done
+.align 16
+.L058xts_dec_done6x:
+ movl 112(%esp),%eax
+ andl $15,%eax
+ jz .L065xts_dec_ret
+ movl %eax,112(%esp)
+ jmp .L066xts_dec_only_one_more
+.align 16
+.L063xts_dec_done:
+ movl 112(%esp),%eax
+ pxor %xmm0,%xmm0
+ andl $15,%eax
+ jz .L065xts_dec_ret
+ pcmpgtd %xmm1,%xmm0
+ movl %eax,112(%esp)
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa 96(%esp),%xmm3
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+.L066xts_dec_only_one_more:
+ pshufd $19,%xmm0,%xmm5
+ movdqa %xmm1,%xmm6
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm5
+ pxor %xmm1,%xmm5
+ movl %ebp,%edx
+ movl %ebx,%ecx
+ movups (%esi),%xmm2
+ xorps %xmm5,%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L067dec1_loop_13:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L067dec1_loop_13
+.byte 102,15,56,223,209
+ xorps %xmm5,%xmm2
+ movups %xmm2,(%edi)
+.L068xts_dec_steal:
+ movzbl 16(%esi),%ecx
+ movzbl (%edi),%edx
+ leal 1(%esi),%esi
+ movb %cl,(%edi)
+ movb %dl,16(%edi)
+ leal 1(%edi),%edi
+ subl $1,%eax
+ jnz .L068xts_dec_steal
+ subl 112(%esp),%edi
+ movl %ebp,%edx
+ movl %ebx,%ecx
+ movups (%edi),%xmm2
+ xorps %xmm6,%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L069dec1_loop_14:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L069dec1_loop_14
+.byte 102,15,56,223,209
+ xorps %xmm6,%xmm2
+ movups %xmm2,(%edi)
+.L065xts_dec_ret:
+ movl 116(%esp),%esp
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.size aesni_xts_decrypt,.-.L_aesni_xts_decrypt_begin
+.globl aesni_cbc_encrypt
+.type aesni_cbc_encrypt,@function
+.align 16
+aesni_cbc_encrypt:
+.L_aesni_cbc_encrypt_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 20(%esp),%esi
+ movl %esp,%ebx
+ movl 24(%esp),%edi
+ subl $24,%ebx
+ movl 28(%esp),%eax
+ andl $-16,%ebx
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebp
+ testl %eax,%eax
+ jz .L070cbc_abort
+ cmpl $0,40(%esp)
+ xchgl %esp,%ebx
+ movups (%ebp),%xmm7
+ movl 240(%edx),%ecx
+ movl %edx,%ebp
+ movl %ebx,16(%esp)
+ movl %ecx,%ebx
+ je .L071cbc_decrypt
+ movaps %xmm7,%xmm2
+ cmpl $16,%eax
+ jb .L072cbc_enc_tail
+ subl $16,%eax
+ jmp .L073cbc_enc_loop
+.align 16
+.L073cbc_enc_loop:
+ movups (%esi),%xmm7
+ leal 16(%esi),%esi
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ xorps %xmm0,%xmm7
+ leal 32(%edx),%edx
+ xorps %xmm7,%xmm2
+.L074enc1_loop_15:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L074enc1_loop_15
+.byte 102,15,56,221,209
+ movl %ebx,%ecx
+ movl %ebp,%edx
+ movups %xmm2,(%edi)
+ leal 16(%edi),%edi
+ subl $16,%eax
+ jnc .L073cbc_enc_loop
+ addl $16,%eax
+ jnz .L072cbc_enc_tail
+ movaps %xmm2,%xmm7
+ jmp .L075cbc_ret
+.L072cbc_enc_tail:
+ movl %eax,%ecx
+.long 2767451785
+ movl $16,%ecx
+ subl %eax,%ecx
+ xorl %eax,%eax
+.long 2868115081
+ leal -16(%edi),%edi
+ movl %ebx,%ecx
+ movl %edi,%esi
+ movl %ebp,%edx
+ jmp .L073cbc_enc_loop
+.align 16
+.L071cbc_decrypt:
+ cmpl $80,%eax
+ jbe .L076cbc_dec_tail
+ movaps %xmm7,(%esp)
+ subl $80,%eax
+ jmp .L077cbc_dec_loop6_enter
+.align 16
+.L078cbc_dec_loop6:
+ movaps %xmm0,(%esp)
+ movups %xmm7,(%edi)
+ leal 16(%edi),%edi
+.L077cbc_dec_loop6_enter:
+ movdqu (%esi),%xmm2
+ movdqu 16(%esi),%xmm3
+ movdqu 32(%esi),%xmm4
+ movdqu 48(%esi),%xmm5
+ movdqu 64(%esi),%xmm6
+ movdqu 80(%esi),%xmm7
+ call _aesni_decrypt6
+ movups (%esi),%xmm1
+ movups 16(%esi),%xmm0
+ xorps (%esp),%xmm2
+ xorps %xmm1,%xmm3
+ movups 32(%esi),%xmm1
+ xorps %xmm0,%xmm4
+ movups 48(%esi),%xmm0
+ xorps %xmm1,%xmm5
+ movups 64(%esi),%xmm1
+ xorps %xmm0,%xmm6
+ movups 80(%esi),%xmm0
+ xorps %xmm1,%xmm7
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ leal 96(%esi),%esi
+ movups %xmm4,32(%edi)
+ movl %ebx,%ecx
+ movups %xmm5,48(%edi)
+ movl %ebp,%edx
+ movups %xmm6,64(%edi)
+ leal 80(%edi),%edi
+ subl $96,%eax
+ ja .L078cbc_dec_loop6
+ movaps %xmm7,%xmm2
+ movaps %xmm0,%xmm7
+ addl $80,%eax
+ jle .L079cbc_dec_tail_collected
+ movups %xmm2,(%edi)
+ leal 16(%edi),%edi
+.L076cbc_dec_tail:
+ movups (%esi),%xmm2
+ movaps %xmm2,%xmm6
+ cmpl $16,%eax
+ jbe .L080cbc_dec_one
+ movups 16(%esi),%xmm3
+ movaps %xmm3,%xmm5
+ cmpl $32,%eax
+ jbe .L081cbc_dec_two
+ movups 32(%esi),%xmm4
+ cmpl $48,%eax
+ jbe .L082cbc_dec_three
+ movups 48(%esi),%xmm5
+ cmpl $64,%eax
+ jbe .L083cbc_dec_four
+ movups 64(%esi),%xmm6
+ movaps %xmm7,(%esp)
+ movups (%esi),%xmm2
+ xorps %xmm7,%xmm7
+ call _aesni_decrypt6
+ movups (%esi),%xmm1
+ movups 16(%esi),%xmm0
+ xorps (%esp),%xmm2
+ xorps %xmm1,%xmm3
+ movups 32(%esi),%xmm1
+ xorps %xmm0,%xmm4
+ movups 48(%esi),%xmm0
+ xorps %xmm1,%xmm5
+ movups 64(%esi),%xmm7
+ xorps %xmm0,%xmm6
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ leal 64(%edi),%edi
+ movaps %xmm6,%xmm2
+ subl $80,%eax
+ jmp .L079cbc_dec_tail_collected
+.align 16
+.L080cbc_dec_one:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+.L084dec1_loop_16:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz .L084dec1_loop_16
+.byte 102,15,56,223,209
+ xorps %xmm7,%xmm2
+ movaps %xmm6,%xmm7
+ subl $16,%eax
+ jmp .L079cbc_dec_tail_collected
+.align 16
+.L081cbc_dec_two:
+ xorps %xmm4,%xmm4
+ call _aesni_decrypt3
+ xorps %xmm7,%xmm2
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ movaps %xmm3,%xmm2
+ leal 16(%edi),%edi
+ movaps %xmm5,%xmm7
+ subl $32,%eax
+ jmp .L079cbc_dec_tail_collected
+.align 16
+.L082cbc_dec_three:
+ call _aesni_decrypt3
+ xorps %xmm7,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm5,%xmm4
+ movups %xmm2,(%edi)
+ movaps %xmm4,%xmm2
+ movups %xmm3,16(%edi)
+ leal 32(%edi),%edi
+ movups 32(%esi),%xmm7
+ subl $48,%eax
+ jmp .L079cbc_dec_tail_collected
+.align 16
+.L083cbc_dec_four:
+ call _aesni_decrypt4
+ movups 16(%esi),%xmm1
+ movups 32(%esi),%xmm0
+ xorps %xmm7,%xmm2
+ movups 48(%esi),%xmm7
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ xorps %xmm1,%xmm4
+ movups %xmm3,16(%edi)
+ xorps %xmm0,%xmm5
+ movups %xmm4,32(%edi)
+ leal 48(%edi),%edi
+ movaps %xmm5,%xmm2
+ subl $64,%eax
+.L079cbc_dec_tail_collected:
+ andl $15,%eax
+ jnz .L085cbc_dec_tail_partial
+ movups %xmm2,(%edi)
+ jmp .L075cbc_ret
+.align 16
+.L085cbc_dec_tail_partial:
+ movaps %xmm2,(%esp)
+ movl $16,%ecx
+ movl %esp,%esi
+ subl %eax,%ecx
+.long 2767451785
+.L075cbc_ret:
+ movl 16(%esp),%esp
+ movl 36(%esp),%ebp
+ movups %xmm7,(%ebp)
+.L070cbc_abort:
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.size aesni_cbc_encrypt,.-.L_aesni_cbc_encrypt_begin
+.type _aesni_set_encrypt_key,@function
+.align 16
+_aesni_set_encrypt_key:
+ testl %eax,%eax
+ jz .L086bad_pointer
+ testl %edx,%edx
+ jz .L086bad_pointer
+ movups (%eax),%xmm0
+ xorps %xmm4,%xmm4
+ leal 16(%edx),%edx
+ cmpl $256,%ecx
+ je .L08714rounds
+ cmpl $192,%ecx
+ je .L08812rounds
+ cmpl $128,%ecx
+ jne .L089bad_keybits
+.align 16
+.L09010rounds:
+ movl $9,%ecx
+ movups %xmm0,-16(%edx)
+.byte 102,15,58,223,200,1
+ call .L091key_128_cold
+.byte 102,15,58,223,200,2
+ call .L092key_128
+.byte 102,15,58,223,200,4
+ call .L092key_128
+.byte 102,15,58,223,200,8
+ call .L092key_128
+.byte 102,15,58,223,200,16
+ call .L092key_128
+.byte 102,15,58,223,200,32
+ call .L092key_128
+.byte 102,15,58,223,200,64
+ call .L092key_128
+.byte 102,15,58,223,200,128
+ call .L092key_128
+.byte 102,15,58,223,200,27
+ call .L092key_128
+.byte 102,15,58,223,200,54
+ call .L092key_128
+ movups %xmm0,(%edx)
+ movl %ecx,80(%edx)
+ xorl %eax,%eax
+ ret
+.align 16
+.L092key_128:
+ movups %xmm0,(%edx)
+ leal 16(%edx),%edx
+.L091key_128_cold:
+ shufps $16,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $255,%xmm1,%xmm1
+ xorps %xmm1,%xmm0
+ ret
+.align 16
+.L08812rounds:
+ movq 16(%eax),%xmm2
+ movl $11,%ecx
+ movups %xmm0,-16(%edx)
+.byte 102,15,58,223,202,1
+ call .L093key_192a_cold
+.byte 102,15,58,223,202,2
+ call .L094key_192b
+.byte 102,15,58,223,202,4
+ call .L095key_192a
+.byte 102,15,58,223,202,8
+ call .L094key_192b
+.byte 102,15,58,223,202,16
+ call .L095key_192a
+.byte 102,15,58,223,202,32
+ call .L094key_192b
+.byte 102,15,58,223,202,64
+ call .L095key_192a
+.byte 102,15,58,223,202,128
+ call .L094key_192b
+ movups %xmm0,(%edx)
+ movl %ecx,48(%edx)
+ xorl %eax,%eax
+ ret
+.align 16
+.L095key_192a:
+ movups %xmm0,(%edx)
+ leal 16(%edx),%edx
+.align 16
+.L093key_192a_cold:
+ movaps %xmm2,%xmm5
+.L096key_192b_warm:
+ shufps $16,%xmm0,%xmm4
+ movdqa %xmm2,%xmm3
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ pslldq $4,%xmm3
+ xorps %xmm4,%xmm0
+ pshufd $85,%xmm1,%xmm1
+ pxor %xmm3,%xmm2
+ pxor %xmm1,%xmm0
+ pshufd $255,%xmm0,%xmm3
+ pxor %xmm3,%xmm2
+ ret
+.align 16
+.L094key_192b:
+ movaps %xmm0,%xmm3
+ shufps $68,%xmm0,%xmm5
+ movups %xmm5,(%edx)
+ shufps $78,%xmm2,%xmm3
+ movups %xmm3,16(%edx)
+ leal 32(%edx),%edx
+ jmp .L096key_192b_warm
+.align 16
+.L08714rounds:
+ movups 16(%eax),%xmm2
+ movl $13,%ecx
+ leal 16(%edx),%edx
+ movups %xmm0,-32(%edx)
+ movups %xmm2,-16(%edx)
+.byte 102,15,58,223,202,1
+ call .L097key_256a_cold
+.byte 102,15,58,223,200,1
+ call .L098key_256b
+.byte 102,15,58,223,202,2
+ call .L099key_256a
+.byte 102,15,58,223,200,2
+ call .L098key_256b
+.byte 102,15,58,223,202,4
+ call .L099key_256a
+.byte 102,15,58,223,200,4
+ call .L098key_256b
+.byte 102,15,58,223,202,8
+ call .L099key_256a
+.byte 102,15,58,223,200,8
+ call .L098key_256b
+.byte 102,15,58,223,202,16
+ call .L099key_256a
+.byte 102,15,58,223,200,16
+ call .L098key_256b
+.byte 102,15,58,223,202,32
+ call .L099key_256a
+.byte 102,15,58,223,200,32
+ call .L098key_256b
+.byte 102,15,58,223,202,64
+ call .L099key_256a
+ movups %xmm0,(%edx)
+ movl %ecx,16(%edx)
+ xorl %eax,%eax
+ ret
+.align 16
+.L099key_256a:
+ movups %xmm2,(%edx)
+ leal 16(%edx),%edx
+.L097key_256a_cold:
+ shufps $16,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $255,%xmm1,%xmm1
+ xorps %xmm1,%xmm0
+ ret
+.align 16
+.L098key_256b:
+ movups %xmm0,(%edx)
+ leal 16(%edx),%edx
+ shufps $16,%xmm2,%xmm4
+ xorps %xmm4,%xmm2
+ shufps $140,%xmm2,%xmm4
+ xorps %xmm4,%xmm2
+ shufps $170,%xmm1,%xmm1
+ xorps %xmm1,%xmm2
+ ret
+.align 4
+.L086bad_pointer:
+ movl $-1,%eax
+ ret
+.align 4
+.L089bad_keybits:
+ movl $-2,%eax
+ ret
+.size _aesni_set_encrypt_key,.-_aesni_set_encrypt_key
+.globl aesni_set_encrypt_key
+.type aesni_set_encrypt_key,@function
+.align 16
+aesni_set_encrypt_key:
+.L_aesni_set_encrypt_key_begin:
+ movl 4(%esp),%eax
+ movl 8(%esp),%ecx
+ movl 12(%esp),%edx
+ call _aesni_set_encrypt_key
+ ret
+.size aesni_set_encrypt_key,.-.L_aesni_set_encrypt_key_begin
+.globl aesni_set_decrypt_key
+.type aesni_set_decrypt_key,@function
+.align 16
+aesni_set_decrypt_key:
+.L_aesni_set_decrypt_key_begin:
+ movl 4(%esp),%eax
+ movl 8(%esp),%ecx
+ movl 12(%esp),%edx
+ call _aesni_set_encrypt_key
+ movl 12(%esp),%edx
+ shll $4,%ecx
+ testl %eax,%eax
+ jnz .L100dec_key_ret
+ leal 16(%edx,%ecx,1),%eax
+ movups (%edx),%xmm0
+ movups (%eax),%xmm1
+ movups %xmm0,(%eax)
+ movups %xmm1,(%edx)
+ leal 16(%edx),%edx
+ leal -16(%eax),%eax
+.L101dec_key_inverse:
+ movups (%edx),%xmm0
+ movups (%eax),%xmm1
+.byte 102,15,56,219,192
+.byte 102,15,56,219,201
+ leal 16(%edx),%edx
+ leal -16(%eax),%eax
+ movups %xmm0,16(%eax)
+ movups %xmm1,-16(%edx)
+ cmpl %edx,%eax
+ ja .L101dec_key_inverse
+ movups (%edx),%xmm0
+.byte 102,15,56,219,192
+ movups %xmm0,(%edx)
+ xorl %eax,%eax
+.L100dec_key_ret:
+ ret
+.size aesni_set_decrypt_key,.-.L_aesni_set_decrypt_key_begin
+.byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69
+.byte 83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83
+.byte 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
+.byte 115,108,46,111,114,103,62,0
diff --git a/deps/openssl/asm/x86-elf-gas/camellia/cmll-x86.s b/deps/openssl/asm/x86-elf-gas/camellia/cmll-x86.s
index a896314cf..5c87910e3 100644
--- a/deps/openssl/asm/x86-elf-gas/camellia/cmll-x86.s
+++ b/deps/openssl/asm/x86-elf-gas/camellia/cmll-x86.s
@@ -1537,11 +1537,11 @@ Camellia_Ekeygen:
popl %ebp
ret
.size Camellia_Ekeygen,.-.L_Camellia_Ekeygen_begin
-.globl Camellia_set_key
-.type Camellia_set_key,@function
+.globl private_Camellia_set_key
+.type private_Camellia_set_key,@function
.align 16
-Camellia_set_key:
-.L_Camellia_set_key_begin:
+private_Camellia_set_key:
+.L_private_Camellia_set_key_begin:
pushl %ebx
movl 8(%esp),%ecx
movl 12(%esp),%ebx
@@ -1571,7 +1571,7 @@ Camellia_set_key:
.L014done:
popl %ebx
ret
-.size Camellia_set_key,.-.L_Camellia_set_key_begin
+.size private_Camellia_set_key,.-.L_private_Camellia_set_key_begin
.align 64
.LCamellia_SIGMA:
.long 2694735487,1003262091,3061508184,1286239154,3337565999,3914302142,1426019237,4057165596,283453434,3731369245,2958461122,3018244605,0,0,0,0
diff --git a/deps/openssl/asm/x86-elf-gas/rc4/rc4-586.s b/deps/openssl/asm/x86-elf-gas/rc4/rc4-586.s
index 9ba94e4b1..513ce6a58 100644
--- a/deps/openssl/asm/x86-elf-gas/rc4/rc4-586.s
+++ b/deps/openssl/asm/x86-elf-gas/rc4/rc4-586.s
@@ -29,11 +29,146 @@ RC4:
movl (%edi,%eax,4),%ecx
andl $-4,%edx
jz .L002loop1
- leal -4(%esi,%edx,1),%edx
- movl %edx,28(%esp)
+ testl $-8,%edx
movl %ebp,32(%esp)
+ jz .L003go4loop4
+ leal OPENSSL_ia32cap_P,%ebp
+ btl $26,(%ebp)
+ jnc .L003go4loop4
+ movl 32(%esp),%ebp
+ andl $-8,%edx
+ leal -8(%esi,%edx,1),%edx
+ movl %edx,-4(%edi)
+ addb %cl,%bl
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ movq (%esi),%mm0
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm2
+ jmp .L004loop_mmx_enter
+.align 16
+.L005loop_mmx:
+ addb %cl,%bl
+ psllq $56,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movq (%esi),%mm0
+ movq %mm2,-8(%ebp,%esi,1)
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm2
+.L004loop_mmx_enter:
+ addb %cl,%bl
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm0,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $8,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $16,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $24,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $32,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $40,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $48,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ movl %ebx,%edx
+ xorl %ebx,%ebx
+ movb %dl,%bl
+ cmpl -4(%edi),%esi
+ leal 8(%esi),%esi
+ jb .L005loop_mmx
+ psllq $56,%mm1
+ pxor %mm1,%mm2
+ movq %mm2,-8(%ebp,%esi,1)
+ emms
+ cmpl 24(%esp),%esi
+ je .L006done
+ jmp .L002loop1
.align 16
-.L003loop4:
+.L003go4loop4:
+ leal -4(%esi,%edx,1),%edx
+ movl %edx,28(%esp)
+.L007loop4:
addb %cl,%bl
movl (%edi,%ebx,4),%edx
movl %ecx,(%edi,%ebx,4)
@@ -79,9 +214,9 @@ RC4:
movl %ebp,(%ecx,%esi,1)
leal 4(%esi),%esi
movl (%edi,%eax,4),%ecx
- jb .L003loop4
+ jb .L007loop4
cmpl 24(%esp),%esi
- je .L004done
+ je .L006done
movl 32(%esp),%ebp
.align 16
.L002loop1:
@@ -99,11 +234,11 @@ RC4:
cmpl 24(%esp),%esi
movb %dl,-1(%ebp,%esi,1)
jb .L002loop1
- jmp .L004done
+ jmp .L006done
.align 16
.L001RC4_CHAR:
movzbl (%edi,%eax,1),%ecx
-.L005cloop1:
+.L008cloop1:
addb %cl,%bl
movzbl (%edi,%ebx,1),%edx
movb %cl,(%edi,%ebx,1)
@@ -116,10 +251,10 @@ RC4:
movzbl (%edi,%eax,1),%ecx
cmpl 24(%esp),%esi
movb %dl,-1(%ebp,%esi,1)
- jb .L005cloop1
-.L004done:
+ jb .L008cloop1
+.L006done:
decb %al
- movb %bl,-4(%edi)
+ movl %ebx,-4(%edi)
movb %al,-8(%edi)
.L000abort:
popl %edi
@@ -128,11 +263,11 @@ RC4:
popl %ebp
ret
.size RC4,.-.L_RC4_begin
-.globl RC4_set_key
-.type RC4_set_key,@function
+.globl private_RC4_set_key
+.type private_RC4_set_key,@function
.align 16
-RC4_set_key:
-.L_RC4_set_key_begin:
+private_RC4_set_key:
+.L_private_RC4_set_key_begin:
pushl %ebp
pushl %ebx
pushl %esi
@@ -147,53 +282,53 @@ RC4_set_key:
xorl %eax,%eax
movl %ebp,-4(%edi)
btl $20,(%edx)
- jc .L006c1stloop
+ jc .L009c1stloop
.align 16
-.L007w1stloop:
+.L010w1stloop:
movl %eax,(%edi,%eax,4)
addb $1,%al
- jnc .L007w1stloop
+ jnc .L010w1stloop
xorl %ecx,%ecx
xorl %edx,%edx
.align 16
-.L008w2ndloop:
+.L011w2ndloop:
movl (%edi,%ecx,4),%eax
addb (%esi,%ebp,1),%dl
addb %al,%dl
addl $1,%ebp
movl (%edi,%edx,4),%ebx
- jnz .L009wnowrap
+ jnz .L012wnowrap
movl -4(%edi),%ebp
-.L009wnowrap:
+.L012wnowrap:
movl %eax,(%edi,%edx,4)
movl %ebx,(%edi,%ecx,4)
addb $1,%cl
- jnc .L008w2ndloop
- jmp .L010exit
+ jnc .L011w2ndloop
+ jmp .L013exit
.align 16
-.L006c1stloop:
+.L009c1stloop:
movb %al,(%edi,%eax,1)
addb $1,%al
- jnc .L006c1stloop
+ jnc .L009c1stloop
xorl %ecx,%ecx
xorl %edx,%edx
xorl %ebx,%ebx
.align 16
-.L011c2ndloop:
+.L014c2ndloop:
movb (%edi,%ecx,1),%al
addb (%esi,%ebp,1),%dl
addb %al,%dl
addl $1,%ebp
movb (%edi,%edx,1),%bl
- jnz .L012cnowrap
+ jnz .L015cnowrap
movl -4(%edi),%ebp
-.L012cnowrap:
+.L015cnowrap:
movb %al,(%edi,%edx,1)
movb %bl,(%edi,%ecx,1)
addb $1,%cl
- jnc .L011c2ndloop
+ jnc .L014c2ndloop
movl $-1,256(%edi)
-.L010exit:
+.L013exit:
xorl %eax,%eax
movl %eax,-8(%edi)
movl %eax,-4(%edi)
@@ -202,29 +337,36 @@ RC4_set_key:
popl %ebx
popl %ebp
ret
-.size RC4_set_key,.-.L_RC4_set_key_begin
+.size private_RC4_set_key,.-.L_private_RC4_set_key_begin
.globl RC4_options
.type RC4_options,@function
.align 16
RC4_options:
.L_RC4_options_begin:
- call .L013pic_point
-.L013pic_point:
+ call .L016pic_point
+.L016pic_point:
popl %eax
- leal .L014opts-.L013pic_point(%eax),%eax
+ leal .L017opts-.L016pic_point(%eax),%eax
leal OPENSSL_ia32cap_P,%edx
- btl $20,(%edx)
- jnc .L015skip
+ movl (%edx),%edx
+ btl $20,%edx
+ jc .L0181xchar
+ btl $26,%edx
+ jnc .L019ret
+ addl $25,%eax
+ ret
+.L0181xchar:
addl $12,%eax
-.L015skip:
+.L019ret:
ret
.align 64
-.L014opts:
+.L017opts:
.byte 114,99,52,40,52,120,44,105,110,116,41,0
.byte 114,99,52,40,49,120,44,99,104,97,114,41,0
+.byte 114,99,52,40,56,120,44,109,109,120,41,0
.byte 82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
.byte 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
.byte 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 64
.size RC4_options,.-.L_RC4_options_begin
-.comm OPENSSL_ia32cap_P,4,4
+.comm OPENSSL_ia32cap_P,8,4
diff --git a/deps/openssl/asm/x86-elf-gas/sha/sha1-586.s b/deps/openssl/asm/x86-elf-gas/sha/sha1-586.s
index cccb1aba8..e77f65412 100644
--- a/deps/openssl/asm/x86-elf-gas/sha/sha1-586.s
+++ b/deps/openssl/asm/x86-elf-gas/sha/sha1-586.s
@@ -12,11 +12,12 @@ sha1_block_data_order:
movl 20(%esp),%ebp
movl 24(%esp),%esi
movl 28(%esp),%eax
- subl $64,%esp
+ subl $76,%esp
shll $6,%eax
addl %esi,%eax
- movl %eax,92(%esp)
+ movl %eax,104(%esp)
movl 16(%ebp),%edi
+ jmp .L000loop
.align 16
.L000loop:
movl (%esi),%eax
@@ -67,7 +68,7 @@ sha1_block_data_order:
movl %ebx,52(%esp)
movl %ecx,56(%esp)
movl %edx,60(%esp)
- movl %esi,88(%esp)
+ movl %esi,100(%esp)
movl (%ebp),%eax
movl 4(%ebp),%ebx
movl 8(%ebp),%ecx
@@ -78,10 +79,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %edx,%esi
addl %edi,%ebp
- andl %ebx,%esi
movl (%esp),%edi
- xorl %edx,%esi
+ andl %ebx,%esi
rorl $2,%ebx
+ xorl %edx,%esi
leal 1518500249(%ebp,%edi,1),%ebp
addl %esi,%ebp
@@ -90,10 +91,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %ecx,%edi
addl %edx,%ebp
- andl %eax,%edi
movl 4(%esp),%edx
- xorl %ecx,%edi
+ andl %eax,%edi
rorl $2,%eax
+ xorl %ecx,%edi
leal 1518500249(%ebp,%edx,1),%ebp
addl %edi,%ebp
@@ -102,10 +103,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %ebx,%edx
addl %ecx,%ebp
- andl %esi,%edx
movl 8(%esp),%ecx
- xorl %ebx,%edx
+ andl %esi,%edx
rorl $2,%esi
+ xorl %ebx,%edx
leal 1518500249(%ebp,%ecx,1),%ebp
addl %edx,%ebp
@@ -114,10 +115,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %eax,%ecx
addl %ebx,%ebp
- andl %edi,%ecx
movl 12(%esp),%ebx
- xorl %eax,%ecx
+ andl %edi,%ecx
rorl $2,%edi
+ xorl %eax,%ecx
leal 1518500249(%ebp,%ebx,1),%ebp
addl %ecx,%ebp
@@ -126,10 +127,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %esi,%ebx
addl %eax,%ebp
- andl %edx,%ebx
movl 16(%esp),%eax
- xorl %esi,%ebx
+ andl %edx,%ebx
rorl $2,%edx
+ xorl %esi,%ebx
leal 1518500249(%ebp,%eax,1),%ebp
addl %ebx,%ebp
@@ -138,10 +139,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %edi,%eax
addl %esi,%ebp
- andl %ecx,%eax
movl 20(%esp),%esi
- xorl %edi,%eax
+ andl %ecx,%eax
rorl $2,%ecx
+ xorl %edi,%eax
leal 1518500249(%ebp,%esi,1),%ebp
addl %eax,%ebp
@@ -150,10 +151,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %edx,%esi
addl %edi,%ebp
- andl %ebx,%esi
movl 24(%esp),%edi
- xorl %edx,%esi
+ andl %ebx,%esi
rorl $2,%ebx
+ xorl %edx,%esi
leal 1518500249(%ebp,%edi,1),%ebp
addl %esi,%ebp
@@ -162,10 +163,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %ecx,%edi
addl %edx,%ebp
- andl %eax,%edi
movl 28(%esp),%edx
- xorl %ecx,%edi
+ andl %eax,%edi
rorl $2,%eax
+ xorl %ecx,%edi
leal 1518500249(%ebp,%edx,1),%ebp
addl %edi,%ebp
@@ -174,10 +175,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %ebx,%edx
addl %ecx,%ebp
- andl %esi,%edx
movl 32(%esp),%ecx
- xorl %ebx,%edx
+ andl %esi,%edx
rorl $2,%esi
+ xorl %ebx,%edx
leal 1518500249(%ebp,%ecx,1),%ebp
addl %edx,%ebp
@@ -186,10 +187,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %eax,%ecx
addl %ebx,%ebp
- andl %edi,%ecx
movl 36(%esp),%ebx
- xorl %eax,%ecx
+ andl %edi,%ecx
rorl $2,%edi
+ xorl %eax,%ecx
leal 1518500249(%ebp,%ebx,1),%ebp
addl %ecx,%ebp
@@ -198,10 +199,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %esi,%ebx
addl %eax,%ebp
- andl %edx,%ebx
movl 40(%esp),%eax
- xorl %esi,%ebx
+ andl %edx,%ebx
rorl $2,%edx
+ xorl %esi,%ebx
leal 1518500249(%ebp,%eax,1),%ebp
addl %ebx,%ebp
@@ -210,10 +211,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %edi,%eax
addl %esi,%ebp
- andl %ecx,%eax
movl 44(%esp),%esi
- xorl %edi,%eax
+ andl %ecx,%eax
rorl $2,%ecx
+ xorl %edi,%eax
leal 1518500249(%ebp,%esi,1),%ebp
addl %eax,%ebp
@@ -222,10 +223,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %edx,%esi
addl %edi,%ebp
- andl %ebx,%esi
movl 48(%esp),%edi
- xorl %edx,%esi
+ andl %ebx,%esi
rorl $2,%ebx
+ xorl %edx,%esi
leal 1518500249(%ebp,%edi,1),%ebp
addl %esi,%ebp
@@ -234,10 +235,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %ecx,%edi
addl %edx,%ebp
- andl %eax,%edi
movl 52(%esp),%edx
- xorl %ecx,%edi
+ andl %eax,%edi
rorl $2,%eax
+ xorl %ecx,%edi
leal 1518500249(%ebp,%edx,1),%ebp
addl %edi,%ebp
@@ -246,10 +247,10 @@ sha1_block_data_order:
roll $5,%ebp
xorl %ebx,%edx
addl %ecx,%ebp
- andl %esi,%edx
movl 56(%esp),%ecx
- xorl %ebx,%edx
+ andl %esi,%edx
rorl $2,%esi
+ xorl %ebx,%edx
leal 1518500249(%ebp,%ecx,1),%ebp
addl %edx,%ebp
@@ -258,1162 +259,1099 @@ sha1_block_data_order:
roll $5,%ebp
xorl %eax,%ecx
addl %ebx,%ebp
- andl %edi,%ecx
movl 60(%esp),%ebx
- xorl %eax,%ecx
+ andl %edi,%ecx
rorl $2,%edi
+ xorl %eax,%ecx
leal 1518500249(%ebp,%ebx,1),%ebp
+ movl (%esp),%ebx
addl %ebp,%ecx
- movl (%esp),%ebx
movl %edi,%ebp
xorl 8(%esp),%ebx
xorl %esi,%ebp
xorl 32(%esp),%ebx
andl %edx,%ebp
- rorl $2,%edx
xorl 52(%esp),%ebx
roll $1,%ebx
xorl %esi,%ebp
+ addl %ebp,%eax
+ movl %ecx,%ebp
+ rorl $2,%edx
movl %ebx,(%esp)
+ roll $5,%ebp
leal 1518500249(%ebx,%eax,1),%ebx
- movl %ecx,%eax
- roll $5,%eax
+ movl 4(%esp),%eax
addl %ebp,%ebx
- addl %eax,%ebx
- movl 4(%esp),%eax
movl %edx,%ebp
xorl 12(%esp),%eax
xorl %edi,%ebp
xorl 36(%esp),%eax
andl %ecx,%ebp
- rorl $2,%ecx
xorl 56(%esp),%eax
roll $1,%eax
xorl %edi,%ebp
+ addl %ebp,%esi
+ movl %ebx,%ebp
+ rorl $2,%ecx
movl %eax,4(%esp)
+ roll $5,%ebp
leal 1518500249(%eax,%esi,1),%eax
- movl %ebx,%esi
- roll $5,%esi
+ movl 8(%esp),%esi
addl %ebp,%eax
- addl %esi,%eax
- movl 8(%esp),%esi
movl %ecx,%ebp
xorl 16(%esp),%esi
xorl %edx,%ebp
xorl 40(%esp),%esi
andl %ebx,%ebp
- rorl $2,%ebx
xorl 60(%esp),%esi
roll $1,%esi
xorl %edx,%ebp
+ addl %ebp,%edi
+ movl %eax,%ebp
+ rorl $2,%ebx
movl %esi,8(%esp)
+ roll $5,%ebp
leal 1518500249(%esi,%edi,1),%esi
- movl %eax,%edi
- roll $5,%edi
+ movl 12(%esp),%edi
addl %ebp,%esi
- addl %edi,%esi
- movl 12(%esp),%edi
movl %ebx,%ebp
xorl 20(%esp),%edi
xorl %ecx,%ebp
xorl 44(%esp),%edi
andl %eax,%ebp
- rorl $2,%eax
xorl (%esp),%edi
roll $1,%edi
xorl %ecx,%ebp
+ addl %ebp,%edx
+ movl %esi,%ebp
+ rorl $2,%eax
movl %edi,12(%esp)
+ roll $5,%ebp
leal 1518500249(%edi,%edx,1),%edi
- movl %esi,%edx
- roll $5,%edx
+ movl 16(%esp),%edx
addl %ebp,%edi
- addl %edx,%edi
movl %esi,%ebp
- movl 16(%esp),%edx
- rorl $2,%esi
xorl 24(%esp),%edx
xorl %eax,%ebp
xorl 48(%esp),%edx
xorl %ebx,%ebp
xorl 4(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,16(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 1859775393(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl 20(%esp),%ecx
+ addl %ebp,%edx
movl %edi,%ebp
- movl 20(%esp),%ecx
- rorl $2,%edi
xorl 28(%esp),%ecx
xorl %esi,%ebp
xorl 52(%esp),%ecx
xorl %eax,%ebp
xorl 8(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,20(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 1859775393(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl 24(%esp),%ebx
+ addl %ebp,%ecx
movl %edx,%ebp
- movl 24(%esp),%ebx
- rorl $2,%edx
xorl 32(%esp),%ebx
xorl %edi,%ebp
xorl 56(%esp),%ebx
xorl %esi,%ebp
xorl 12(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,24(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 1859775393(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 1859775393(%ebx,%eax,1),%ebx
+ movl 28(%esp),%eax
+ addl %ebp,%ebx
movl %ecx,%ebp
- movl 28(%esp),%eax
- rorl $2,%ecx
xorl 36(%esp),%eax
xorl %edx,%ebp
xorl 60(%esp),%eax
xorl %edi,%ebp
xorl 16(%esp),%eax
roll $1,%eax
- addl %esi,%ebp
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
movl %eax,28(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 1859775393(%eax,%ebp,1),%eax
- addl %esi,%eax
+ leal 1859775393(%eax,%esi,1),%eax
+ movl 32(%esp),%esi
+ addl %ebp,%eax
movl %ebx,%ebp
- movl 32(%esp),%esi
- rorl $2,%ebx
xorl 40(%esp),%esi
xorl %ecx,%ebp
xorl (%esp),%esi
xorl %edx,%ebp
xorl 20(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,32(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 1859775393(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 1859775393(%esi,%edi,1),%esi
+ movl 36(%esp),%edi
+ addl %ebp,%esi
movl %eax,%ebp
- movl 36(%esp),%edi
- rorl $2,%eax
xorl 44(%esp),%edi
xorl %ebx,%ebp
xorl 4(%esp),%edi
xorl %ecx,%ebp
xorl 24(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,36(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 1859775393(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 1859775393(%edi,%edx,1),%edi
+ movl 40(%esp),%edx
+ addl %ebp,%edi
movl %esi,%ebp
- movl 40(%esp),%edx
- rorl $2,%esi
xorl 48(%esp),%edx
xorl %eax,%ebp
xorl 8(%esp),%edx
xorl %ebx,%ebp
xorl 28(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,40(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 1859775393(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl 44(%esp),%ecx
+ addl %ebp,%edx
movl %edi,%ebp
- movl 44(%esp),%ecx
- rorl $2,%edi
xorl 52(%esp),%ecx
xorl %esi,%ebp
xorl 12(%esp),%ecx
xorl %eax,%ebp
xorl 32(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,44(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 1859775393(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl 48(%esp),%ebx
+ addl %ebp,%ecx
movl %edx,%ebp
- movl 48(%esp),%ebx
- rorl $2,%edx
xorl 56(%esp),%ebx
xorl %edi,%ebp
xorl 16(%esp),%ebx
xorl %esi,%ebp
xorl 36(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,48(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 1859775393(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 1859775393(%ebx,%eax,1),%ebx
+ movl 52(%esp),%eax
+ addl %ebp,%ebx
movl %ecx,%ebp
- movl 52(%esp),%eax
- rorl $2,%ecx
xorl 60(%esp),%eax
xorl %edx,%ebp
xorl 20(%esp),%eax
xorl %edi,%ebp
xorl 40(%esp),%eax
roll $1,%eax
- addl %esi,%ebp
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
movl %eax,52(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 1859775393(%eax,%ebp,1),%eax
- addl %esi,%eax
+ leal 1859775393(%eax,%esi,1),%eax
+ movl 56(%esp),%esi
+ addl %ebp,%eax
movl %ebx,%ebp
- movl 56(%esp),%esi
- rorl $2,%ebx
xorl (%esp),%esi
xorl %ecx,%ebp
xorl 24(%esp),%esi
xorl %edx,%ebp
xorl 44(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,56(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 1859775393(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 1859775393(%esi,%edi,1),%esi
+ movl 60(%esp),%edi
+ addl %ebp,%esi
movl %eax,%ebp
- movl 60(%esp),%edi
- rorl $2,%eax
xorl 4(%esp),%edi
xorl %ebx,%ebp
xorl 28(%esp),%edi
xorl %ecx,%ebp
xorl 48(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,60(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 1859775393(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 1859775393(%edi,%edx,1),%edi
+ movl (%esp),%edx
+ addl %ebp,%edi
movl %esi,%ebp
- movl (%esp),%edx
- rorl $2,%esi
xorl 8(%esp),%edx
xorl %eax,%ebp
xorl 32(%esp),%edx
xorl %ebx,%ebp
xorl 52(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 1859775393(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl 4(%esp),%ecx
+ addl %ebp,%edx
movl %edi,%ebp
- movl 4(%esp),%ecx
- rorl $2,%edi
xorl 12(%esp),%ecx
xorl %esi,%ebp
xorl 36(%esp),%ecx
xorl %eax,%ebp
xorl 56(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,4(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 1859775393(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl 8(%esp),%ebx
+ addl %ebp,%ecx
movl %edx,%ebp
- movl 8(%esp),%ebx
- rorl $2,%edx
xorl 16(%esp),%ebx
xorl %edi,%ebp
xorl 40(%esp),%ebx
xorl %esi,%ebp
xorl 60(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,8(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 1859775393(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 1859775393(%ebx,%eax,1),%ebx
+ movl 12(%esp),%eax
+ addl %ebp,%ebx
movl %ecx,%ebp
- movl 12(%esp),%eax
- rorl $2,%ecx
xorl 20(%esp),%eax
xorl %edx,%ebp
xorl 44(%esp),%eax
xorl %edi,%ebp
xorl (%esp),%eax
roll $1,%eax
- addl %esi,%ebp
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
movl %eax,12(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 1859775393(%eax,%ebp,1),%eax
- addl %esi,%eax
+ leal 1859775393(%eax,%esi,1),%eax
+ movl 16(%esp),%esi
+ addl %ebp,%eax
movl %ebx,%ebp
- movl 16(%esp),%esi
- rorl $2,%ebx
xorl 24(%esp),%esi
xorl %ecx,%ebp
xorl 48(%esp),%esi
xorl %edx,%ebp
xorl 4(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,16(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 1859775393(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 1859775393(%esi,%edi,1),%esi
+ movl 20(%esp),%edi
+ addl %ebp,%esi
movl %eax,%ebp
- movl 20(%esp),%edi
- rorl $2,%eax
xorl 28(%esp),%edi
xorl %ebx,%ebp
xorl 52(%esp),%edi
xorl %ecx,%ebp
xorl 8(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,20(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 1859775393(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 1859775393(%edi,%edx,1),%edi
+ movl 24(%esp),%edx
+ addl %ebp,%edi
movl %esi,%ebp
- movl 24(%esp),%edx
- rorl $2,%esi
xorl 32(%esp),%edx
xorl %eax,%ebp
xorl 56(%esp),%edx
xorl %ebx,%ebp
xorl 12(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,24(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 1859775393(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl 28(%esp),%ecx
+ addl %ebp,%edx
movl %edi,%ebp
- movl 28(%esp),%ecx
- rorl $2,%edi
xorl 36(%esp),%ecx
xorl %esi,%ebp
xorl 60(%esp),%ecx
xorl %eax,%ebp
xorl 16(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,28(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 1859775393(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
-
+ leal 1859775393(%ecx,%ebx,1),%ecx
movl 32(%esp),%ebx
- movl 40(%esp),%ebp
- xorl %ebp,%ebx
- movl (%esp),%ebp
- xorl %ebp,%ebx
- movl 20(%esp),%ebp
- xorl %ebp,%ebx
- movl %edx,%ebp
+ addl %ebp,%ecx
+
+ movl %edi,%ebp
+ xorl 40(%esp),%ebx
+ xorl %esi,%ebp
+ xorl (%esp),%ebx
+ andl %edx,%ebp
+ xorl 20(%esp),%ebx
roll $1,%ebx
- orl %edi,%ebp
- movl %ebx,32(%esp)
- andl %esi,%ebp
- leal 2400959708(%ebx,%eax,1),%ebx
- movl %edx,%eax
+ addl %eax,%ebp
rorl $2,%edx
- andl %edi,%eax
- orl %eax,%ebp
movl %ecx,%eax
roll $5,%eax
- addl %ebp,%ebx
+ movl %ebx,32(%esp)
+ leal 2400959708(%ebx,%ebp,1),%ebx
+ movl %edi,%ebp
addl %eax,%ebx
-
+ andl %esi,%ebp
movl 36(%esp),%eax
- movl 44(%esp),%ebp
- xorl %ebp,%eax
- movl 4(%esp),%ebp
- xorl %ebp,%eax
- movl 24(%esp),%ebp
- xorl %ebp,%eax
- movl %ecx,%ebp
+ addl %ebp,%ebx
+
+ movl %edx,%ebp
+ xorl 44(%esp),%eax
+ xorl %edi,%ebp
+ xorl 4(%esp),%eax
+ andl %ecx,%ebp
+ xorl 24(%esp),%eax
roll $1,%eax
- orl %edx,%ebp
- movl %eax,36(%esp)
- andl %edi,%ebp
- leal 2400959708(%eax,%esi,1),%eax
- movl %ecx,%esi
+ addl %esi,%ebp
rorl $2,%ecx
- andl %edx,%esi
- orl %esi,%ebp
movl %ebx,%esi
roll $5,%esi
- addl %ebp,%eax
+ movl %eax,36(%esp)
+ leal 2400959708(%eax,%ebp,1),%eax
+ movl %edx,%ebp
addl %esi,%eax
-
+ andl %edi,%ebp
movl 40(%esp),%esi
- movl 48(%esp),%ebp
- xorl %ebp,%esi
- movl 8(%esp),%ebp
- xorl %ebp,%esi
- movl 28(%esp),%ebp
- xorl %ebp,%esi
- movl %ebx,%ebp
+ addl %ebp,%eax
+
+ movl %ecx,%ebp
+ xorl 48(%esp),%esi
+ xorl %edx,%ebp
+ xorl 8(%esp),%esi
+ andl %ebx,%ebp
+ xorl 28(%esp),%esi
roll $1,%esi
- orl %ecx,%ebp
- movl %esi,40(%esp)
- andl %edx,%ebp
- leal 2400959708(%esi,%edi,1),%esi
- movl %ebx,%edi
+ addl %edi,%ebp
rorl $2,%ebx
- andl %ecx,%edi
- orl %edi,%ebp
movl %eax,%edi
roll $5,%edi
- addl %ebp,%esi
+ movl %esi,40(%esp)
+ leal 2400959708(%esi,%ebp,1),%esi
+ movl %ecx,%ebp
addl %edi,%esi
-
+ andl %edx,%ebp
movl 44(%esp),%edi
- movl 52(%esp),%ebp
- xorl %ebp,%edi
- movl 12(%esp),%ebp
- xorl %ebp,%edi
- movl 32(%esp),%ebp
- xorl %ebp,%edi
- movl %eax,%ebp
+ addl %ebp,%esi
+
+ movl %ebx,%ebp
+ xorl 52(%esp),%edi
+ xorl %ecx,%ebp
+ xorl 12(%esp),%edi
+ andl %eax,%ebp
+ xorl 32(%esp),%edi
roll $1,%edi
- orl %ebx,%ebp
- movl %edi,44(%esp)
- andl %ecx,%ebp
- leal 2400959708(%edi,%edx,1),%edi
- movl %eax,%edx
+ addl %edx,%ebp
rorl $2,%eax
- andl %ebx,%edx
- orl %edx,%ebp
movl %esi,%edx
roll $5,%edx
- addl %ebp,%edi
+ movl %edi,44(%esp)
+ leal 2400959708(%edi,%ebp,1),%edi
+ movl %ebx,%ebp
addl %edx,%edi
-
+ andl %ecx,%ebp
movl 48(%esp),%edx
- movl 56(%esp),%ebp
- xorl %ebp,%edx
- movl 16(%esp),%ebp
- xorl %ebp,%edx
- movl 36(%esp),%ebp
- xorl %ebp,%edx
- movl %esi,%ebp
+ addl %ebp,%edi
+
+ movl %eax,%ebp
+ xorl 56(%esp),%edx
+ xorl %ebx,%ebp
+ xorl 16(%esp),%edx
+ andl %esi,%ebp
+ xorl 36(%esp),%edx
roll $1,%edx
- orl %eax,%ebp
- movl %edx,48(%esp)
- andl %ebx,%ebp
- leal 2400959708(%edx,%ecx,1),%edx
- movl %esi,%ecx
+ addl %ecx,%ebp
rorl $2,%esi
- andl %eax,%ecx
- orl %ecx,%ebp
movl %edi,%ecx
roll $5,%ecx
- addl %ebp,%edx
+ movl %edx,48(%esp)
+ leal 2400959708(%edx,%ebp,1),%edx
+ movl %eax,%ebp
addl %ecx,%edx
-
+ andl %ebx,%ebp
movl 52(%esp),%ecx
- movl 60(%esp),%ebp
- xorl %ebp,%ecx
- movl 20(%esp),%ebp
- xorl %ebp,%ecx
- movl 40(%esp),%ebp
- xorl %ebp,%ecx
- movl %edi,%ebp
+ addl %ebp,%edx
+
+ movl %esi,%ebp
+ xorl 60(%esp),%ecx
+ xorl %eax,%ebp
+ xorl 20(%esp),%ecx
+ andl %edi,%ebp
+ xorl 40(%esp),%ecx
roll $1,%ecx
- orl %esi,%ebp
- movl %ecx,52(%esp)
- andl %eax,%ebp
- leal 2400959708(%ecx,%ebx,1),%ecx
- movl %edi,%ebx
+ addl %ebx,%ebp
rorl $2,%edi
- andl %esi,%ebx
- orl %ebx,%ebp
movl %edx,%ebx
roll $5,%ebx
- addl %ebp,%ecx
+ movl %ecx,52(%esp)
+ leal 2400959708(%ecx,%ebp,1),%ecx
+ movl %esi,%ebp
addl %ebx,%ecx
-
+ andl %eax,%ebp
movl 56(%esp),%ebx
- movl (%esp),%ebp
- xorl %ebp,%ebx
- movl 24(%esp),%ebp
- xorl %ebp,%ebx
- movl 44(%esp),%ebp
- xorl %ebp,%ebx
- movl %edx,%ebp
+ addl %ebp,%ecx
+
+ movl %edi,%ebp
+ xorl (%esp),%ebx
+ xorl %esi,%ebp
+ xorl 24(%esp),%ebx
+ andl %edx,%ebp
+ xorl 44(%esp),%ebx
roll $1,%ebx
- orl %edi,%ebp
- movl %ebx,56(%esp)
- andl %esi,%ebp
- leal 2400959708(%ebx,%eax,1),%ebx
- movl %edx,%eax
+ addl %eax,%ebp
rorl $2,%edx
- andl %edi,%eax
- orl %eax,%ebp
movl %ecx,%eax
roll $5,%eax
- addl %ebp,%ebx
+ movl %ebx,56(%esp)
+ leal 2400959708(%ebx,%ebp,1),%ebx
+ movl %edi,%ebp
addl %eax,%ebx
-
+ andl %esi,%ebp
movl 60(%esp),%eax
- movl 4(%esp),%ebp
- xorl %ebp,%eax
- movl 28(%esp),%ebp
- xorl %ebp,%eax
- movl 48(%esp),%ebp
- xorl %ebp,%eax
- movl %ecx,%ebp
+ addl %ebp,%ebx
+
+ movl %edx,%ebp
+ xorl 4(%esp),%eax
+ xorl %edi,%ebp
+ xorl 28(%esp),%eax
+ andl %ecx,%ebp
+ xorl 48(%esp),%eax
roll $1,%eax
- orl %edx,%ebp
- movl %eax,60(%esp)
- andl %edi,%ebp
- leal 2400959708(%eax,%esi,1),%eax
- movl %ecx,%esi
+ addl %esi,%ebp
rorl $2,%ecx
- andl %edx,%esi
- orl %esi,%ebp
movl %ebx,%esi
roll $5,%esi
- addl %ebp,%eax
+ movl %eax,60(%esp)
+ leal 2400959708(%eax,%ebp,1),%eax
+ movl %edx,%ebp
addl %esi,%eax
-
+ andl %edi,%ebp
movl (%esp),%esi
- movl 8(%esp),%ebp
- xorl %ebp,%esi
- movl 32(%esp),%ebp
- xorl %ebp,%esi
- movl 52(%esp),%ebp
- xorl %ebp,%esi
- movl %ebx,%ebp
+ addl %ebp,%eax
+
+ movl %ecx,%ebp
+ xorl 8(%esp),%esi
+ xorl %edx,%ebp
+ xorl 32(%esp),%esi
+ andl %ebx,%ebp
+ xorl 52(%esp),%esi
roll $1,%esi
- orl %ecx,%ebp
- movl %esi,(%esp)
- andl %edx,%ebp
- leal 2400959708(%esi,%edi,1),%esi
- movl %ebx,%edi
+ addl %edi,%ebp
rorl $2,%ebx
- andl %ecx,%edi
- orl %edi,%ebp
movl %eax,%edi
roll $5,%edi
- addl %ebp,%esi
+ movl %esi,(%esp)
+ leal 2400959708(%esi,%ebp,1),%esi
+ movl %ecx,%ebp
addl %edi,%esi
-
+ andl %edx,%ebp
movl 4(%esp),%edi
- movl 12(%esp),%ebp
- xorl %ebp,%edi
- movl 36(%esp),%ebp
- xorl %ebp,%edi
- movl 56(%esp),%ebp
- xorl %ebp,%edi
- movl %eax,%ebp
+ addl %ebp,%esi
+
+ movl %ebx,%ebp
+ xorl 12(%esp),%edi
+ xorl %ecx,%ebp
+ xorl 36(%esp),%edi
+ andl %eax,%ebp
+ xorl 56(%esp),%edi
roll $1,%edi
- orl %ebx,%ebp
- movl %edi,4(%esp)
- andl %ecx,%ebp
- leal 2400959708(%edi,%edx,1),%edi
- movl %eax,%edx
+ addl %edx,%ebp
rorl $2,%eax
- andl %ebx,%edx
- orl %edx,%ebp
movl %esi,%edx
roll $5,%edx
- addl %ebp,%edi
+ movl %edi,4(%esp)
+ leal 2400959708(%edi,%ebp,1),%edi
+ movl %ebx,%ebp
addl %edx,%edi
-
+ andl %ecx,%ebp
movl 8(%esp),%edx
- movl 16(%esp),%ebp
- xorl %ebp,%edx
- movl 40(%esp),%ebp
- xorl %ebp,%edx
- movl 60(%esp),%ebp
- xorl %ebp,%edx
- movl %esi,%ebp
+ addl %ebp,%edi
+
+ movl %eax,%ebp
+ xorl 16(%esp),%edx
+ xorl %ebx,%ebp
+ xorl 40(%esp),%edx
+ andl %esi,%ebp
+ xorl 60(%esp),%edx
roll $1,%edx
- orl %eax,%ebp
- movl %edx,8(%esp)
- andl %ebx,%ebp
- leal 2400959708(%edx,%ecx,1),%edx
- movl %esi,%ecx
+ addl %ecx,%ebp
rorl $2,%esi
- andl %eax,%ecx
- orl %ecx,%ebp
movl %edi,%ecx
roll $5,%ecx
- addl %ebp,%edx
+ movl %edx,8(%esp)
+ leal 2400959708(%edx,%ebp,1),%edx
+ movl %eax,%ebp
addl %ecx,%edx
-
+ andl %ebx,%ebp
movl 12(%esp),%ecx
- movl 20(%esp),%ebp
- xorl %ebp,%ecx
- movl 44(%esp),%ebp
- xorl %ebp,%ecx
- movl (%esp),%ebp
- xorl %ebp,%ecx
- movl %edi,%ebp
+ addl %ebp,%edx
+
+ movl %esi,%ebp
+ xorl 20(%esp),%ecx
+ xorl %eax,%ebp
+ xorl 44(%esp),%ecx
+ andl %edi,%ebp
+ xorl (%esp),%ecx
roll $1,%ecx
- orl %esi,%ebp
- movl %ecx,12(%esp)
- andl %eax,%ebp
- leal 2400959708(%ecx,%ebx,1),%ecx
- movl %edi,%ebx
+ addl %ebx,%ebp
rorl $2,%edi
- andl %esi,%ebx
- orl %ebx,%ebp
movl %edx,%ebx
roll $5,%ebx
- addl %ebp,%ecx
+ movl %ecx,12(%esp)
+ leal 2400959708(%ecx,%ebp,1),%ecx
+ movl %esi,%ebp
addl %ebx,%ecx
-
+ andl %eax,%ebp
movl 16(%esp),%ebx
- movl 24(%esp),%ebp
- xorl %ebp,%ebx
- movl 48(%esp),%ebp
- xorl %ebp,%ebx
- movl 4(%esp),%ebp
- xorl %ebp,%ebx
- movl %edx,%ebp
+ addl %ebp,%ecx
+
+ movl %edi,%ebp
+ xorl 24(%esp),%ebx
+ xorl %esi,%ebp
+ xorl 48(%esp),%ebx
+ andl %edx,%ebp
+ xorl 4(%esp),%ebx
roll $1,%ebx
- orl %edi,%ebp
- movl %ebx,16(%esp)
- andl %esi,%ebp
- leal 2400959708(%ebx,%eax,1),%ebx
- movl %edx,%eax
+ addl %eax,%ebp
rorl $2,%edx
- andl %edi,%eax
- orl %eax,%ebp
movl %ecx,%eax
roll $5,%eax
- addl %ebp,%ebx
+ movl %ebx,16(%esp)
+ leal 2400959708(%ebx,%ebp,1),%ebx
+ movl %edi,%ebp
addl %eax,%ebx
-
+ andl %esi,%ebp
movl 20(%esp),%eax
- movl 28(%esp),%ebp
- xorl %ebp,%eax
- movl 52(%esp),%ebp
- xorl %ebp,%eax
- movl 8(%esp),%ebp
- xorl %ebp,%eax
- movl %ecx,%ebp
+ addl %ebp,%ebx
+
+ movl %edx,%ebp
+ xorl 28(%esp),%eax
+ xorl %edi,%ebp
+ xorl 52(%esp),%eax
+ andl %ecx,%ebp
+ xorl 8(%esp),%eax
roll $1,%eax
- orl %edx,%ebp
- movl %eax,20(%esp)
- andl %edi,%ebp
- leal 2400959708(%eax,%esi,1),%eax
- movl %ecx,%esi
+ addl %esi,%ebp
rorl $2,%ecx
- andl %edx,%esi
- orl %esi,%ebp
movl %ebx,%esi
roll $5,%esi
- addl %ebp,%eax
+ movl %eax,20(%esp)
+ leal 2400959708(%eax,%ebp,1),%eax
+ movl %edx,%ebp
addl %esi,%eax
-
+ andl %edi,%ebp
movl 24(%esp),%esi
- movl 32(%esp),%ebp
- xorl %ebp,%esi
- movl 56(%esp),%ebp
- xorl %ebp,%esi
- movl 12(%esp),%ebp
- xorl %ebp,%esi
- movl %ebx,%ebp
+ addl %ebp,%eax
+
+ movl %ecx,%ebp
+ xorl 32(%esp),%esi
+ xorl %edx,%ebp
+ xorl 56(%esp),%esi
+ andl %ebx,%ebp
+ xorl 12(%esp),%esi
roll $1,%esi
- orl %ecx,%ebp
- movl %esi,24(%esp)
- andl %edx,%ebp
- leal 2400959708(%esi,%edi,1),%esi
- movl %ebx,%edi
+ addl %edi,%ebp
rorl $2,%ebx
- andl %ecx,%edi
- orl %edi,%ebp
movl %eax,%edi
roll $5,%edi
- addl %ebp,%esi
+ movl %esi,24(%esp)
+ leal 2400959708(%esi,%ebp,1),%esi
+ movl %ecx,%ebp
addl %edi,%esi
-
+ andl %edx,%ebp
movl 28(%esp),%edi
- movl 36(%esp),%ebp
- xorl %ebp,%edi
- movl 60(%esp),%ebp
- xorl %ebp,%edi
- movl 16(%esp),%ebp
- xorl %ebp,%edi
- movl %eax,%ebp
+ addl %ebp,%esi
+
+ movl %ebx,%ebp
+ xorl 36(%esp),%edi
+ xorl %ecx,%ebp
+ xorl 60(%esp),%edi
+ andl %eax,%ebp
+ xorl 16(%esp),%edi
roll $1,%edi
- orl %ebx,%ebp
- movl %edi,28(%esp)
- andl %ecx,%ebp
- leal 2400959708(%edi,%edx,1),%edi
- movl %eax,%edx
+ addl %edx,%ebp
rorl $2,%eax
- andl %ebx,%edx
- orl %edx,%ebp
movl %esi,%edx
roll $5,%edx
- addl %ebp,%edi
+ movl %edi,28(%esp)
+ leal 2400959708(%edi,%ebp,1),%edi
+ movl %ebx,%ebp
addl %edx,%edi
-
+ andl %ecx,%ebp
movl 32(%esp),%edx
- movl 40(%esp),%ebp
- xorl %ebp,%edx
- movl (%esp),%ebp
- xorl %ebp,%edx
- movl 20(%esp),%ebp
- xorl %ebp,%edx
- movl %esi,%ebp
+ addl %ebp,%edi
+
+ movl %eax,%ebp
+ xorl 40(%esp),%edx
+ xorl %ebx,%ebp
+ xorl (%esp),%edx
+ andl %esi,%ebp
+ xorl 20(%esp),%edx
roll $1,%edx
- orl %eax,%ebp
- movl %edx,32(%esp)
- andl %ebx,%ebp
- leal 2400959708(%edx,%ecx,1),%edx
- movl %esi,%ecx
+ addl %ecx,%ebp
rorl $2,%esi
- andl %eax,%ecx
- orl %ecx,%ebp
movl %edi,%ecx
roll $5,%ecx
- addl %ebp,%edx
+ movl %edx,32(%esp)
+ leal 2400959708(%edx,%ebp,1),%edx
+ movl %eax,%ebp
addl %ecx,%edx
-
+ andl %ebx,%ebp
movl 36(%esp),%ecx
- movl 44(%esp),%ebp
- xorl %ebp,%ecx
- movl 4(%esp),%ebp
- xorl %ebp,%ecx
- movl 24(%esp),%ebp
- xorl %ebp,%ecx
- movl %edi,%ebp
+ addl %ebp,%edx
+
+ movl %esi,%ebp
+ xorl 44(%esp),%ecx
+ xorl %eax,%ebp
+ xorl 4(%esp),%ecx
+ andl %edi,%ebp
+ xorl 24(%esp),%ecx
roll $1,%ecx
- orl %esi,%ebp
- movl %ecx,36(%esp)
- andl %eax,%ebp
- leal 2400959708(%ecx,%ebx,1),%ecx
- movl %edi,%ebx
+ addl %ebx,%ebp
rorl $2,%edi
- andl %esi,%ebx
- orl %ebx,%ebp
movl %edx,%ebx
roll $5,%ebx
- addl %ebp,%ecx
+ movl %ecx,36(%esp)
+ leal 2400959708(%ecx,%ebp,1),%ecx
+ movl %esi,%ebp
addl %ebx,%ecx
-
+ andl %eax,%ebp
movl 40(%esp),%ebx
- movl 48(%esp),%ebp
- xorl %ebp,%ebx
- movl 8(%esp),%ebp
- xorl %ebp,%ebx
- movl 28(%esp),%ebp
- xorl %ebp,%ebx
- movl %edx,%ebp
+ addl %ebp,%ecx
+
+ movl %edi,%ebp
+ xorl 48(%esp),%ebx
+ xorl %esi,%ebp
+ xorl 8(%esp),%ebx
+ andl %edx,%ebp
+ xorl 28(%esp),%ebx
roll $1,%ebx
- orl %edi,%ebp
- movl %ebx,40(%esp)
- andl %esi,%ebp
- leal 2400959708(%ebx,%eax,1),%ebx
- movl %edx,%eax
+ addl %eax,%ebp
rorl $2,%edx
- andl %edi,%eax
- orl %eax,%ebp
movl %ecx,%eax
roll $5,%eax
- addl %ebp,%ebx
+ movl %ebx,40(%esp)
+ leal 2400959708(%ebx,%ebp,1),%ebx
+ movl %edi,%ebp
addl %eax,%ebx
-
+ andl %esi,%ebp
movl 44(%esp),%eax
- movl 52(%esp),%ebp
- xorl %ebp,%eax
- movl 12(%esp),%ebp
- xorl %ebp,%eax
- movl 32(%esp),%ebp
- xorl %ebp,%eax
- movl %ecx,%ebp
+ addl %ebp,%ebx
+
+ movl %edx,%ebp
+ xorl 52(%esp),%eax
+ xorl %edi,%ebp
+ xorl 12(%esp),%eax
+ andl %ecx,%ebp
+ xorl 32(%esp),%eax
roll $1,%eax
- orl %edx,%ebp
- movl %eax,44(%esp)
- andl %edi,%ebp
- leal 2400959708(%eax,%esi,1),%eax
- movl %ecx,%esi
+ addl %esi,%ebp
rorl $2,%ecx
- andl %edx,%esi
- orl %esi,%ebp
movl %ebx,%esi
roll $5,%esi
- addl %ebp,%eax
+ movl %eax,44(%esp)
+ leal 2400959708(%eax,%ebp,1),%eax
+ movl %edx,%ebp
addl %esi,%eax
+ andl %edi,%ebp
+ movl 48(%esp),%esi
+ addl %ebp,%eax
movl %ebx,%ebp
- movl 48(%esp),%esi
- rorl $2,%ebx
xorl 56(%esp),%esi
xorl %ecx,%ebp
xorl 16(%esp),%esi
xorl %edx,%ebp
xorl 36(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,48(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 3395469782(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 3395469782(%esi,%edi,1),%esi
+ movl 52(%esp),%edi
+ addl %ebp,%esi
movl %eax,%ebp
- movl 52(%esp),%edi
- rorl $2,%eax
xorl 60(%esp),%edi
xorl %ebx,%ebp
xorl 20(%esp),%edi
xorl %ecx,%ebp
xorl 40(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,52(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 3395469782(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 3395469782(%edi,%edx,1),%edi
+ movl 56(%esp),%edx
+ addl %ebp,%edi
movl %esi,%ebp
- movl 56(%esp),%edx
- rorl $2,%esi
xorl (%esp),%edx
xorl %eax,%ebp
xorl 24(%esp),%edx
xorl %ebx,%ebp
xorl 44(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,56(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 3395469782(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 3395469782(%edx,%ecx,1),%edx
+ movl 60(%esp),%ecx
+ addl %ebp,%edx
movl %edi,%ebp
- movl 60(%esp),%ecx
- rorl $2,%edi
xorl 4(%esp),%ecx
xorl %esi,%ebp
xorl 28(%esp),%ecx
xorl %eax,%ebp
xorl 48(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,60(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 3395469782(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 3395469782(%ecx,%ebx,1),%ecx
+ movl (%esp),%ebx
+ addl %ebp,%ecx
movl %edx,%ebp
- movl (%esp),%ebx
- rorl $2,%edx
xorl 8(%esp),%ebx
xorl %edi,%ebp
xorl 32(%esp),%ebx
xorl %esi,%ebp
xorl 52(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 3395469782(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 3395469782(%ebx,%eax,1),%ebx
+ movl 4(%esp),%eax
+ addl %ebp,%ebx
movl %ecx,%ebp
- movl 4(%esp),%eax
- rorl $2,%ecx
xorl 12(%esp),%eax
xorl %edx,%ebp
xorl 36(%esp),%eax
xorl %edi,%ebp
xorl 56(%esp),%eax
roll $1,%eax
- addl %esi,%ebp
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
movl %eax,4(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 3395469782(%eax,%ebp,1),%eax
- addl %esi,%eax
+ leal 3395469782(%eax,%esi,1),%eax
+ movl 8(%esp),%esi
+ addl %ebp,%eax
movl %ebx,%ebp
- movl 8(%esp),%esi
- rorl $2,%ebx
xorl 16(%esp),%esi
xorl %ecx,%ebp
xorl 40(%esp),%esi
xorl %edx,%ebp
xorl 60(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,8(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 3395469782(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 3395469782(%esi,%edi,1),%esi
+ movl 12(%esp),%edi
+ addl %ebp,%esi
movl %eax,%ebp
- movl 12(%esp),%edi
- rorl $2,%eax
xorl 20(%esp),%edi
xorl %ebx,%ebp
xorl 44(%esp),%edi
xorl %ecx,%ebp
xorl (%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,12(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 3395469782(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 3395469782(%edi,%edx,1),%edi
+ movl 16(%esp),%edx
+ addl %ebp,%edi
movl %esi,%ebp
- movl 16(%esp),%edx
- rorl $2,%esi
xorl 24(%esp),%edx
xorl %eax,%ebp
xorl 48(%esp),%edx
xorl %ebx,%ebp
xorl 4(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,16(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 3395469782(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 3395469782(%edx,%ecx,1),%edx
+ movl 20(%esp),%ecx
+ addl %ebp,%edx
movl %edi,%ebp
- movl 20(%esp),%ecx
- rorl $2,%edi
xorl 28(%esp),%ecx
xorl %esi,%ebp
xorl 52(%esp),%ecx
xorl %eax,%ebp
xorl 8(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,20(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 3395469782(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 3395469782(%ecx,%ebx,1),%ecx
+ movl 24(%esp),%ebx
+ addl %ebp,%ecx
movl %edx,%ebp
- movl 24(%esp),%ebx
- rorl $2,%edx
xorl 32(%esp),%ebx
xorl %edi,%ebp
xorl 56(%esp),%ebx
xorl %esi,%ebp
xorl 12(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,24(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 3395469782(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 3395469782(%ebx,%eax,1),%ebx
+ movl 28(%esp),%eax
+ addl %ebp,%ebx
movl %ecx,%ebp
- movl 28(%esp),%eax
- rorl $2,%ecx
xorl 36(%esp),%eax
xorl %edx,%ebp
xorl 60(%esp),%eax
xorl %edi,%ebp
xorl 16(%esp),%eax
roll $1,%eax
- addl %esi,%ebp
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
movl %eax,28(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 3395469782(%eax,%ebp,1),%eax
- addl %esi,%eax
+ leal 3395469782(%eax,%esi,1),%eax
+ movl 32(%esp),%esi
+ addl %ebp,%eax
movl %ebx,%ebp
- movl 32(%esp),%esi
- rorl $2,%ebx
xorl 40(%esp),%esi
xorl %ecx,%ebp
xorl (%esp),%esi
xorl %edx,%ebp
xorl 20(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,32(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 3395469782(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 3395469782(%esi,%edi,1),%esi
+ movl 36(%esp),%edi
+ addl %ebp,%esi
movl %eax,%ebp
- movl 36(%esp),%edi
- rorl $2,%eax
xorl 44(%esp),%edi
xorl %ebx,%ebp
xorl 4(%esp),%edi
xorl %ecx,%ebp
xorl 24(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,36(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 3395469782(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 3395469782(%edi,%edx,1),%edi
+ movl 40(%esp),%edx
+ addl %ebp,%edi
movl %esi,%ebp
- movl 40(%esp),%edx
- rorl $2,%esi
xorl 48(%esp),%edx
xorl %eax,%ebp
xorl 8(%esp),%edx
xorl %ebx,%ebp
xorl 28(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,40(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 3395469782(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 3395469782(%edx,%ecx,1),%edx
+ movl 44(%esp),%ecx
+ addl %ebp,%edx
movl %edi,%ebp
- movl 44(%esp),%ecx
- rorl $2,%edi
xorl 52(%esp),%ecx
xorl %esi,%ebp
xorl 12(%esp),%ecx
xorl %eax,%ebp
xorl 32(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,44(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 3395469782(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 3395469782(%ecx,%ebx,1),%ecx
+ movl 48(%esp),%ebx
+ addl %ebp,%ecx
movl %edx,%ebp
- movl 48(%esp),%ebx
- rorl $2,%edx
xorl 56(%esp),%ebx
xorl %edi,%ebp
xorl 16(%esp),%ebx
xorl %esi,%ebp
xorl 36(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,48(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 3395469782(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 3395469782(%ebx,%eax,1),%ebx
+ movl 52(%esp),%eax
+ addl %ebp,%ebx
movl %ecx,%ebp
- movl 52(%esp),%eax
- rorl $2,%ecx
xorl 60(%esp),%eax
xorl %edx,%ebp
xorl 20(%esp),%eax
xorl %edi,%ebp
xorl 40(%esp),%eax
roll $1,%eax
- addl %esi,%ebp
- movl %eax,52(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 3395469782(%eax,%ebp,1),%eax
- addl %esi,%eax
-
+ addl %ebp,%esi
+ rorl $2,%ecx
movl %ebx,%ebp
+ roll $5,%ebp
+ leal 3395469782(%eax,%esi,1),%eax
movl 56(%esp),%esi
- rorl $2,%ebx
+ addl %ebp,%eax
+
+ movl %ebx,%ebp
xorl (%esp),%esi
xorl %ecx,%ebp
xorl 24(%esp),%esi
xorl %edx,%ebp
xorl 44(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
- movl %esi,56(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 3395469782(%esi,%ebp,1),%esi
- addl %edi,%esi
-
+ addl %ebp,%edi
+ rorl $2,%ebx
movl %eax,%ebp
+ roll $5,%ebp
+ leal 3395469782(%esi,%edi,1),%esi
movl 60(%esp),%edi
- rorl $2,%eax
+ addl %ebp,%esi
+
+ movl %eax,%ebp
xorl 4(%esp),%edi
xorl %ebx,%ebp
xorl 28(%esp),%edi
xorl %ecx,%ebp
xorl 48(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
- movl %edi,60(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 3395469782(%edi,%ebp,1),%edi
- addl %edx,%edi
- movl 84(%esp),%ebp
- movl 88(%esp),%edx
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
+ leal 3395469782(%edi,%edx,1),%edi
+ addl %ebp,%edi
+ movl 96(%esp),%ebp
+ movl 100(%esp),%edx
addl (%ebp),%edi
addl 4(%ebp),%esi
addl 8(%ebp),%eax
@@ -1422,14 +1360,14 @@ sha1_block_data_order:
movl %edi,(%ebp)
addl $64,%edx
movl %esi,4(%ebp)
- cmpl 92(%esp),%edx
+ cmpl 104(%esp),%edx
movl %eax,8(%ebp)
movl %ecx,%edi
movl %ebx,12(%ebp)
movl %edx,%esi
movl %ecx,16(%ebp)
jb .L000loop
- addl $64,%esp
+ addl $76,%esp
popl %edi
popl %esi
popl %ebx
diff --git a/deps/openssl/asm/x86-elf-gas/sha/sha256-586.s b/deps/openssl/asm/x86-elf-gas/sha/sha256-586.s
index 973e50d19..77a89514f 100644
--- a/deps/openssl/asm/x86-elf-gas/sha/sha256-586.s
+++ b/deps/openssl/asm/x86-elf-gas/sha/sha256-586.s
@@ -96,31 +96,30 @@ sha256_block_data_order:
.L00300_15:
movl 92(%esp),%ebx
movl %edx,%ecx
- rorl $6,%ecx
- movl %edx,%edi
- rorl $11,%edi
+ rorl $14,%ecx
movl 20(%esp),%esi
- xorl %edi,%ecx
- rorl $14,%edi
- xorl %edi,%ecx
+ xorl %edx,%ecx
+ rorl $5,%ecx
+ xorl %edx,%ecx
+ rorl $6,%ecx
movl 24(%esp),%edi
addl %ecx,%ebx
- movl %edx,16(%esp)
xorl %edi,%esi
+ movl %edx,16(%esp)
movl %eax,%ecx
andl %edx,%esi
movl 12(%esp),%edx
xorl %edi,%esi
movl %eax,%edi
addl %esi,%ebx
- rorl $2,%ecx
+ rorl $9,%ecx
addl 28(%esp),%ebx
- rorl $13,%edi
+ xorl %eax,%ecx
+ rorl $11,%ecx
movl 4(%esp),%esi
- xorl %edi,%ecx
- rorl $9,%edi
+ xorl %eax,%ecx
+ rorl $2,%ecx
addl %ebx,%edx
- xorl %edi,%ecx
movl 8(%esp),%edi
addl %ecx,%ebx
movl %eax,(%esp)
@@ -142,48 +141,46 @@ sha256_block_data_order:
.L00416_63:
movl %ebx,%esi
movl 100(%esp),%ecx
- shrl $3,%ebx
- rorl $7,%esi
- xorl %esi,%ebx
rorl $11,%esi
movl %ecx,%edi
+ xorl %ebx,%esi
+ rorl $7,%esi
+ shrl $3,%ebx
+ rorl $2,%edi
xorl %esi,%ebx
- shrl $10,%ecx
- movl 156(%esp),%esi
+ xorl %ecx,%edi
rorl $17,%edi
- xorl %edi,%ecx
- rorl $2,%edi
- addl %esi,%ebx
+ shrl $10,%ecx
+ addl 156(%esp),%ebx
xorl %ecx,%edi
- addl %edi,%ebx
- movl %edx,%ecx
addl 120(%esp),%ebx
- rorl $6,%ecx
- movl %edx,%edi
- rorl $11,%edi
+ movl %edx,%ecx
+ addl %edi,%ebx
+ rorl $14,%ecx
movl 20(%esp),%esi
- xorl %edi,%ecx
- rorl $14,%edi
+ xorl %edx,%ecx
+ rorl $5,%ecx
movl %ebx,92(%esp)
- xorl %edi,%ecx
+ xorl %edx,%ecx
+ rorl $6,%ecx
movl 24(%esp),%edi
addl %ecx,%ebx
- movl %edx,16(%esp)
xorl %edi,%esi
+ movl %edx,16(%esp)
movl %eax,%ecx
andl %edx,%esi
movl 12(%esp),%edx
xorl %edi,%esi
movl %eax,%edi
addl %esi,%ebx
- rorl $2,%ecx
+ rorl $9,%ecx
addl 28(%esp),%ebx
- rorl $13,%edi
+ xorl %eax,%ecx
+ rorl $11,%ecx
movl 4(%esp),%esi
- xorl %edi,%ecx
- rorl $9,%edi
+ xorl %eax,%ecx
+ rorl $2,%ecx
addl %ebx,%edx
- xorl %edi,%ecx
movl 8(%esp),%edi
addl %ecx,%ebx
movl %eax,(%esp)
diff --git a/deps/openssl/asm/x86-elf-gas/x86cpuid.s b/deps/openssl/asm/x86-elf-gas/x86cpuid.s
index 56a92bfcb..f9cd03805 100644
--- a/deps/openssl/asm/x86-elf-gas/x86cpuid.s
+++ b/deps/openssl/asm/x86-elf-gas/x86cpuid.s
@@ -19,9 +19,9 @@ OPENSSL_ia32_cpuid:
pushfl
popl %eax
xorl %eax,%ecx
- btl $21,%ecx
- jnc .L000done
xorl %eax,%eax
+ btl $21,%ecx
+ jnc .L000nocpuid
.byte 0x0f,0xa2
movl %eax,%edi
xorl %eax,%eax
@@ -47,7 +47,14 @@ OPENSSL_ia32_cpuid:
jnz .L001intel
movl $2147483648,%eax
.byte 0x0f,0xa2
- cmpl $2147483656,%eax
+ cmpl $2147483649,%eax
+ jb .L001intel
+ movl %eax,%esi
+ movl $2147483649,%eax
+ .byte 0x0f,0xa2
+ orl %ecx,%ebp
+ andl $2049,%ebp
+ cmpl $2147483656,%esi
jb .L001intel
movl $2147483656,%eax
.byte 0x0f,0xa2
@@ -56,46 +63,68 @@ OPENSSL_ia32_cpuid:
movl $1,%eax
.byte 0x0f,0xa2
btl $28,%edx
- jnc .L000done
+ jnc .L002generic
shrl $16,%ebx
andl $255,%ebx
cmpl %esi,%ebx
- ja .L000done
+ ja .L002generic
andl $4026531839,%edx
- jmp .L000done
+ jmp .L002generic
.L001intel:
cmpl $4,%edi
movl $-1,%edi
- jb .L002nocacheinfo
+ jb .L003nocacheinfo
movl $4,%eax
movl $0,%ecx
.byte 0x0f,0xa2
movl %eax,%edi
shrl $14,%edi
andl $4095,%edi
-.L002nocacheinfo:
+.L003nocacheinfo:
movl $1,%eax
.byte 0x0f,0xa2
+ andl $3220176895,%edx
cmpl $0,%ebp
- jne .L003notP4
+ jne .L004notintel
+ orl $1073741824,%edx
andb $15,%ah
cmpb $15,%ah
- jne .L003notP4
+ jne .L004notintel
orl $1048576,%edx
-.L003notP4:
+.L004notintel:
btl $28,%edx
- jnc .L000done
+ jnc .L002generic
andl $4026531839,%edx
cmpl $0,%edi
- je .L000done
+ je .L002generic
orl $268435456,%edx
shrl $16,%ebx
cmpb $1,%bl
- ja .L000done
+ ja .L002generic
andl $4026531839,%edx
-.L000done:
- movl %edx,%eax
- movl %ecx,%edx
+.L002generic:
+ andl $2048,%ebp
+ andl $4294965247,%ecx
+ movl %edx,%esi
+ orl %ecx,%ebp
+ btl $27,%ecx
+ jnc .L005clear_avx
+ xorl %ecx,%ecx
+.byte 15,1,208
+ andl $6,%eax
+ cmpl $6,%eax
+ je .L006done
+ cmpl $2,%eax
+ je .L005clear_avx
+.L007clear_xmm:
+ andl $4261412861,%ebp
+ andl $4278190079,%esi
+.L005clear_avx:
+ andl $4026525695,%ebp
+.L006done:
+ movl %esi,%eax
+ movl %ebp,%edx
+.L000nocpuid:
popl %edi
popl %esi
popl %ebx
@@ -111,9 +140,9 @@ OPENSSL_rdtsc:
xorl %edx,%edx
leal OPENSSL_ia32cap_P,%ecx
btl $4,(%ecx)
- jnc .L004notsc
+ jnc .L008notsc
.byte 0x0f,0x31
-.L004notsc:
+.L008notsc:
ret
.size OPENSSL_rdtsc,.-.L_OPENSSL_rdtsc_begin
.globl OPENSSL_instrument_halt
@@ -123,14 +152,14 @@ OPENSSL_instrument_halt:
.L_OPENSSL_instrument_halt_begin:
leal OPENSSL_ia32cap_P,%ecx
btl $4,(%ecx)
- jnc .L005nohalt
+ jnc .L009nohalt
.long 2421723150
andl $3,%eax
- jnz .L005nohalt
+ jnz .L009nohalt
pushfl
popl %eax
btl $9,%eax
- jnc .L005nohalt
+ jnc .L009nohalt
.byte 0x0f,0x31
pushl %edx
pushl %eax
@@ -140,7 +169,7 @@ OPENSSL_instrument_halt:
sbbl 4(%esp),%edx
addl $8,%esp
ret
-.L005nohalt:
+.L009nohalt:
xorl %eax,%eax
xorl %edx,%edx
ret
@@ -153,21 +182,21 @@ OPENSSL_far_spin:
pushfl
popl %eax
btl $9,%eax
- jnc .L006nospin
+ jnc .L010nospin
movl 4(%esp),%eax
movl 8(%esp),%ecx
.long 2430111262
xorl %eax,%eax
movl (%ecx),%edx
- jmp .L007spin
+ jmp .L011spin
.align 16
-.L007spin:
+.L011spin:
incl %eax
cmpl (%ecx),%edx
- je .L007spin
+ je .L011spin
.long 529567888
ret
-.L006nospin:
+.L010nospin:
xorl %eax,%eax
xorl %edx,%edx
ret
@@ -182,9 +211,9 @@ OPENSSL_wipe_cpu:
leal OPENSSL_ia32cap_P,%ecx
movl (%ecx),%ecx
btl $1,(%ecx)
- jnc .L008no_x87
+ jnc .L012no_x87
.long 4007259865,4007259865,4007259865,4007259865,2430851995
-.L008no_x87:
+.L012no_x87:
leal 4(%esp),%eax
ret
.size OPENSSL_wipe_cpu,.-.L_OPENSSL_wipe_cpu_begin
@@ -198,11 +227,11 @@ OPENSSL_atomic_add:
pushl %ebx
nop
movl (%edx),%eax
-.L009spin:
+.L013spin:
leal (%eax,%ecx,1),%ebx
nop
.long 447811568
- jne .L009spin
+ jne .L013spin
movl %ebx,%eax
popl %ebx
ret
@@ -243,37 +272,49 @@ OPENSSL_cleanse:
movl 8(%esp),%ecx
xorl %eax,%eax
cmpl $7,%ecx
- jae .L010lot
+ jae .L014lot
cmpl $0,%ecx
- je .L011ret
-.L012little:
+ je .L015ret
+.L016little:
movb %al,(%edx)
subl $1,%ecx
leal 1(%edx),%edx
- jnz .L012little
-.L011ret:
+ jnz .L016little
+.L015ret:
ret
.align 16
-.L010lot:
+.L014lot:
testl $3,%edx
- jz .L013aligned
+ jz .L017aligned
movb %al,(%edx)
leal -1(%ecx),%ecx
leal 1(%edx),%edx
- jmp .L010lot
-.L013aligned:
+ jmp .L014lot
+.L017aligned:
movl %eax,(%edx)
leal -4(%ecx),%ecx
testl $-4,%ecx
leal 4(%edx),%edx
- jnz .L013aligned
+ jnz .L017aligned
cmpl $0,%ecx
- jne .L012little
+ jne .L016little
ret
.size OPENSSL_cleanse,.-.L_OPENSSL_cleanse_begin
-.comm OPENSSL_ia32cap_P,4,4
+.globl OPENSSL_ia32_rdrand
+.type OPENSSL_ia32_rdrand,@function
+.align 16
+OPENSSL_ia32_rdrand:
+.L_OPENSSL_ia32_rdrand_begin:
+ movl $8,%ecx
+.L018loop:
+.byte 15,199,240
+ jc .L019break
+ loop .L018loop
+.L019break:
+ cmpl $0,%eax
+ cmovel %ecx,%eax
+ ret
+.size OPENSSL_ia32_rdrand,.-.L_OPENSSL_ia32_rdrand_begin
+.comm OPENSSL_ia32cap_P,8,4
.section .init
call OPENSSL_cpuid_setup
- jmp .Linitalign
-.align 16
-.Linitalign:
diff --git a/deps/openssl/asm/x86-macosx-gas/aes/aes-586.s b/deps/openssl/asm/x86-macosx-gas/aes/aes-586.s
index ff56a4bef..a58ea6f76 100644
--- a/deps/openssl/asm/x86-macosx-gas/aes/aes-586.s
+++ b/deps/openssl/asm/x86-macosx-gas/aes/aes-586.s
@@ -975,7 +975,7 @@ L_AES_encrypt_begin:
call L004pic_point
L004pic_point:
popl %ebp
- leal _OPENSSL_ia32cap_P,%eax
+ movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L004pic_point(%ebp),%eax
leal LAES_Te-L004pic_point(%ebp),%ebp
leal 764(%esp),%ebx
subl %ebp,%ebx
@@ -2153,7 +2153,7 @@ L_AES_decrypt_begin:
call L010pic_point
L010pic_point:
popl %ebp
- leal _OPENSSL_ia32cap_P,%eax
+ movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L010pic_point(%ebp),%eax
leal LAES_Td-L010pic_point(%ebp),%ebp
leal 764(%esp),%ebx
subl %ebp,%ebx
@@ -2207,7 +2207,7 @@ L_AES_cbc_encrypt_begin:
call L013pic_point
L013pic_point:
popl %ebp
- leal _OPENSSL_ia32cap_P,%eax
+ movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L013pic_point(%ebp),%eax
cmpl $0,40(%esp)
leal LAES_Te-L013pic_point(%ebp),%ebp
jne L014picked_te
@@ -2950,16 +2950,16 @@ L045exit:
popl %ebx
popl %ebp
ret
-.globl _AES_set_encrypt_key
+.globl _private_AES_set_encrypt_key
.align 4
-_AES_set_encrypt_key:
-L_AES_set_encrypt_key_begin:
+_private_AES_set_encrypt_key:
+L_private_AES_set_encrypt_key_begin:
call __x86_AES_set_encrypt_key
ret
-.globl _AES_set_decrypt_key
+.globl _private_AES_set_decrypt_key
.align 4
-_AES_set_decrypt_key:
-L_AES_set_decrypt_key_begin:
+_private_AES_set_decrypt_key:
+L_private_AES_set_decrypt_key_begin:
call __x86_AES_set_encrypt_key
cmpl $0,%eax
je L054proceed
@@ -3191,4 +3191,8 @@ L056permute:
.byte 65,69,83,32,102,111,114,32,120,56,54,44,32,67,82,89
.byte 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
.byte 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-.comm _OPENSSL_ia32cap_P,4
+.section __IMPORT,__pointers,non_lazy_symbol_pointers
+L_OPENSSL_ia32cap_P$non_lazy_ptr:
+.indirect_symbol _OPENSSL_ia32cap_P
+.long 0
+.comm _OPENSSL_ia32cap_P,8,2
diff --git a/deps/openssl/asm/x86-macosx-gas/aes/aesni-x86.s b/deps/openssl/asm/x86-macosx-gas/aes/aesni-x86.s
new file mode 100644
index 000000000..183ecad29
--- /dev/null
+++ b/deps/openssl/asm/x86-macosx-gas/aes/aesni-x86.s
@@ -0,0 +1,2107 @@
+.file "../openssl/crypto/aes/asm/aesni-x86.s"
+.text
+.globl _aesni_encrypt
+.align 4
+_aesni_encrypt:
+L_aesni_encrypt_begin:
+ movl 4(%esp),%eax
+ movl 12(%esp),%edx
+ movups (%eax),%xmm2
+ movl 240(%edx),%ecx
+ movl 8(%esp),%eax
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L000enc1_loop_1:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L000enc1_loop_1
+.byte 102,15,56,221,209
+ movups %xmm2,(%eax)
+ ret
+.globl _aesni_decrypt
+.align 4
+_aesni_decrypt:
+L_aesni_decrypt_begin:
+ movl 4(%esp),%eax
+ movl 12(%esp),%edx
+ movups (%eax),%xmm2
+ movl 240(%edx),%ecx
+ movl 8(%esp),%eax
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L001dec1_loop_2:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L001dec1_loop_2
+.byte 102,15,56,223,209
+ movups %xmm2,(%eax)
+ ret
+.align 4
+__aesni_encrypt3:
+ movups (%edx),%xmm0
+ shrl $1,%ecx
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ pxor %xmm0,%xmm4
+ movups (%edx),%xmm0
+L002enc3_loop:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %ecx
+.byte 102,15,56,220,225
+ movups 16(%edx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leal 32(%edx),%edx
+.byte 102,15,56,220,224
+ movups (%edx),%xmm0
+ jnz L002enc3_loop
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+ ret
+.align 4
+__aesni_decrypt3:
+ movups (%edx),%xmm0
+ shrl $1,%ecx
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ pxor %xmm0,%xmm4
+ movups (%edx),%xmm0
+L003dec3_loop:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %ecx
+.byte 102,15,56,222,225
+ movups 16(%edx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leal 32(%edx),%edx
+.byte 102,15,56,222,224
+ movups (%edx),%xmm0
+ jnz L003dec3_loop
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+ ret
+.align 4
+__aesni_encrypt4:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ shrl $1,%ecx
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ pxor %xmm0,%xmm4
+ pxor %xmm0,%xmm5
+ movups (%edx),%xmm0
+L004enc4_loop:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %ecx
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+ movups 16(%edx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leal 32(%edx),%edx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+ movups (%edx),%xmm0
+ jnz L004enc4_loop
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+.byte 102,15,56,221,232
+ ret
+.align 4
+__aesni_decrypt4:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ shrl $1,%ecx
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+ pxor %xmm0,%xmm4
+ pxor %xmm0,%xmm5
+ movups (%edx),%xmm0
+L005dec4_loop:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %ecx
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+ movups 16(%edx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leal 32(%edx),%edx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+ movups (%edx),%xmm0
+ jnz L005dec4_loop
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+.byte 102,15,56,223,232
+ ret
+.align 4
+__aesni_encrypt6:
+ movups (%edx),%xmm0
+ shrl $1,%ecx
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+.byte 102,15,56,220,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,220,217
+ pxor %xmm0,%xmm5
+ decl %ecx
+.byte 102,15,56,220,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+.byte 102,15,56,220,241
+ movups (%edx),%xmm0
+.byte 102,15,56,220,249
+ jmp L_aesni_encrypt6_enter
+.align 4,0x90
+L006enc6_loop:
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ decl %ecx
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.align 4,0x90
+L_aesni_encrypt6_enter:
+ movups 16(%edx),%xmm1
+.byte 102,15,56,220,208
+.byte 102,15,56,220,216
+ leal 32(%edx),%edx
+.byte 102,15,56,220,224
+.byte 102,15,56,220,232
+.byte 102,15,56,220,240
+.byte 102,15,56,220,248
+ movups (%edx),%xmm0
+ jnz L006enc6_loop
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+.byte 102,15,56,220,225
+.byte 102,15,56,220,233
+.byte 102,15,56,220,241
+.byte 102,15,56,220,249
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+.byte 102,15,56,221,224
+.byte 102,15,56,221,232
+.byte 102,15,56,221,240
+.byte 102,15,56,221,248
+ ret
+.align 4
+__aesni_decrypt6:
+ movups (%edx),%xmm0
+ shrl $1,%ecx
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+.byte 102,15,56,222,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,222,217
+ pxor %xmm0,%xmm5
+ decl %ecx
+.byte 102,15,56,222,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+.byte 102,15,56,222,241
+ movups (%edx),%xmm0
+.byte 102,15,56,222,249
+ jmp L_aesni_decrypt6_enter
+.align 4,0x90
+L007dec6_loop:
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+ decl %ecx
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.align 4,0x90
+L_aesni_decrypt6_enter:
+ movups 16(%edx),%xmm1
+.byte 102,15,56,222,208
+.byte 102,15,56,222,216
+ leal 32(%edx),%edx
+.byte 102,15,56,222,224
+.byte 102,15,56,222,232
+.byte 102,15,56,222,240
+.byte 102,15,56,222,248
+ movups (%edx),%xmm0
+ jnz L007dec6_loop
+.byte 102,15,56,222,209
+.byte 102,15,56,222,217
+.byte 102,15,56,222,225
+.byte 102,15,56,222,233
+.byte 102,15,56,222,241
+.byte 102,15,56,222,249
+.byte 102,15,56,223,208
+.byte 102,15,56,223,216
+.byte 102,15,56,223,224
+.byte 102,15,56,223,232
+.byte 102,15,56,223,240
+.byte 102,15,56,223,248
+ ret
+.globl _aesni_ecb_encrypt
+.align 4
+_aesni_ecb_encrypt:
+L_aesni_ecb_encrypt_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebx
+ andl $-16,%eax
+ jz L008ecb_ret
+ movl 240(%edx),%ecx
+ testl %ebx,%ebx
+ jz L009ecb_decrypt
+ movl %edx,%ebp
+ movl %ecx,%ebx
+ cmpl $96,%eax
+ jb L010ecb_enc_tail
+ movdqu (%esi),%xmm2
+ movdqu 16(%esi),%xmm3
+ movdqu 32(%esi),%xmm4
+ movdqu 48(%esi),%xmm5
+ movdqu 64(%esi),%xmm6
+ movdqu 80(%esi),%xmm7
+ leal 96(%esi),%esi
+ subl $96,%eax
+ jmp L011ecb_enc_loop6_enter
+.align 4,0x90
+L012ecb_enc_loop6:
+ movups %xmm2,(%edi)
+ movdqu (%esi),%xmm2
+ movups %xmm3,16(%edi)
+ movdqu 16(%esi),%xmm3
+ movups %xmm4,32(%edi)
+ movdqu 32(%esi),%xmm4
+ movups %xmm5,48(%edi)
+ movdqu 48(%esi),%xmm5
+ movups %xmm6,64(%edi)
+ movdqu 64(%esi),%xmm6
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ movdqu 80(%esi),%xmm7
+ leal 96(%esi),%esi
+L011ecb_enc_loop6_enter:
+ call __aesni_encrypt6
+ movl %ebp,%edx
+ movl %ebx,%ecx
+ subl $96,%eax
+ jnc L012ecb_enc_loop6
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ addl $96,%eax
+ jz L008ecb_ret
+L010ecb_enc_tail:
+ movups (%esi),%xmm2
+ cmpl $32,%eax
+ jb L013ecb_enc_one
+ movups 16(%esi),%xmm3
+ je L014ecb_enc_two
+ movups 32(%esi),%xmm4
+ cmpl $64,%eax
+ jb L015ecb_enc_three
+ movups 48(%esi),%xmm5
+ je L016ecb_enc_four
+ movups 64(%esi),%xmm6
+ xorps %xmm7,%xmm7
+ call __aesni_encrypt6
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ jmp L008ecb_ret
+.align 4,0x90
+L013ecb_enc_one:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L017enc1_loop_3:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L017enc1_loop_3
+.byte 102,15,56,221,209
+ movups %xmm2,(%edi)
+ jmp L008ecb_ret
+.align 4,0x90
+L014ecb_enc_two:
+ xorps %xmm4,%xmm4
+ call __aesni_encrypt3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ jmp L008ecb_ret
+.align 4,0x90
+L015ecb_enc_three:
+ call __aesni_encrypt3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ jmp L008ecb_ret
+.align 4,0x90
+L016ecb_enc_four:
+ call __aesni_encrypt4
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ jmp L008ecb_ret
+.align 4,0x90
+L009ecb_decrypt:
+ movl %edx,%ebp
+ movl %ecx,%ebx
+ cmpl $96,%eax
+ jb L018ecb_dec_tail
+ movdqu (%esi),%xmm2
+ movdqu 16(%esi),%xmm3
+ movdqu 32(%esi),%xmm4
+ movdqu 48(%esi),%xmm5
+ movdqu 64(%esi),%xmm6
+ movdqu 80(%esi),%xmm7
+ leal 96(%esi),%esi
+ subl $96,%eax
+ jmp L019ecb_dec_loop6_enter
+.align 4,0x90
+L020ecb_dec_loop6:
+ movups %xmm2,(%edi)
+ movdqu (%esi),%xmm2
+ movups %xmm3,16(%edi)
+ movdqu 16(%esi),%xmm3
+ movups %xmm4,32(%edi)
+ movdqu 32(%esi),%xmm4
+ movups %xmm5,48(%edi)
+ movdqu 48(%esi),%xmm5
+ movups %xmm6,64(%edi)
+ movdqu 64(%esi),%xmm6
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ movdqu 80(%esi),%xmm7
+ leal 96(%esi),%esi
+L019ecb_dec_loop6_enter:
+ call __aesni_decrypt6
+ movl %ebp,%edx
+ movl %ebx,%ecx
+ subl $96,%eax
+ jnc L020ecb_dec_loop6
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ addl $96,%eax
+ jz L008ecb_ret
+L018ecb_dec_tail:
+ movups (%esi),%xmm2
+ cmpl $32,%eax
+ jb L021ecb_dec_one
+ movups 16(%esi),%xmm3
+ je L022ecb_dec_two
+ movups 32(%esi),%xmm4
+ cmpl $64,%eax
+ jb L023ecb_dec_three
+ movups 48(%esi),%xmm5
+ je L024ecb_dec_four
+ movups 64(%esi),%xmm6
+ xorps %xmm7,%xmm7
+ call __aesni_decrypt6
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ jmp L008ecb_ret
+.align 4,0x90
+L021ecb_dec_one:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L025dec1_loop_4:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L025dec1_loop_4
+.byte 102,15,56,223,209
+ movups %xmm2,(%edi)
+ jmp L008ecb_ret
+.align 4,0x90
+L022ecb_dec_two:
+ xorps %xmm4,%xmm4
+ call __aesni_decrypt3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ jmp L008ecb_ret
+.align 4,0x90
+L023ecb_dec_three:
+ call __aesni_decrypt3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ jmp L008ecb_ret
+.align 4,0x90
+L024ecb_dec_four:
+ call __aesni_decrypt4
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+L008ecb_ret:
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.globl _aesni_ccm64_encrypt_blocks
+.align 4
+_aesni_ccm64_encrypt_blocks:
+L_aesni_ccm64_encrypt_blocks_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebx
+ movl 40(%esp),%ecx
+ movl %esp,%ebp
+ subl $60,%esp
+ andl $-16,%esp
+ movl %ebp,48(%esp)
+ movdqu (%ebx),%xmm7
+ movdqu (%ecx),%xmm3
+ movl 240(%edx),%ecx
+ movl $202182159,(%esp)
+ movl $134810123,4(%esp)
+ movl $67438087,8(%esp)
+ movl $66051,12(%esp)
+ movl $1,%ebx
+ xorl %ebp,%ebp
+ movl %ebx,16(%esp)
+ movl %ebp,20(%esp)
+ movl %ebp,24(%esp)
+ movl %ebp,28(%esp)
+ shrl $1,%ecx
+ leal (%edx),%ebp
+ movdqa (%esp),%xmm5
+ movdqa %xmm7,%xmm2
+ movl %ecx,%ebx
+.byte 102,15,56,0,253
+L026ccm64_enc_outer:
+ movups (%ebp),%xmm0
+ movl %ebx,%ecx
+ movups (%esi),%xmm6
+ xorps %xmm0,%xmm2
+ movups 16(%ebp),%xmm1
+ xorps %xmm6,%xmm0
+ leal 32(%ebp),%edx
+ xorps %xmm0,%xmm3
+ movups (%edx),%xmm0
+L027ccm64_enc2_loop:
+.byte 102,15,56,220,209
+ decl %ecx
+.byte 102,15,56,220,217
+ movups 16(%edx),%xmm1
+.byte 102,15,56,220,208
+ leal 32(%edx),%edx
+.byte 102,15,56,220,216
+ movups (%edx),%xmm0
+ jnz L027ccm64_enc2_loop
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ paddq 16(%esp),%xmm7
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+ decl %eax
+ leal 16(%esi),%esi
+ xorps %xmm2,%xmm6
+ movdqa %xmm7,%xmm2
+ movups %xmm6,(%edi)
+ leal 16(%edi),%edi
+.byte 102,15,56,0,213
+ jnz L026ccm64_enc_outer
+ movl 48(%esp),%esp
+ movl 40(%esp),%edi
+ movups %xmm3,(%edi)
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.globl _aesni_ccm64_decrypt_blocks
+.align 4
+_aesni_ccm64_decrypt_blocks:
+L_aesni_ccm64_decrypt_blocks_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebx
+ movl 40(%esp),%ecx
+ movl %esp,%ebp
+ subl $60,%esp
+ andl $-16,%esp
+ movl %ebp,48(%esp)
+ movdqu (%ebx),%xmm7
+ movdqu (%ecx),%xmm3
+ movl 240(%edx),%ecx
+ movl $202182159,(%esp)
+ movl $134810123,4(%esp)
+ movl $67438087,8(%esp)
+ movl $66051,12(%esp)
+ movl $1,%ebx
+ xorl %ebp,%ebp
+ movl %ebx,16(%esp)
+ movl %ebp,20(%esp)
+ movl %ebp,24(%esp)
+ movl %ebp,28(%esp)
+ movdqa (%esp),%xmm5
+ movdqa %xmm7,%xmm2
+ movl %edx,%ebp
+ movl %ecx,%ebx
+.byte 102,15,56,0,253
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L028enc1_loop_5:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L028enc1_loop_5
+.byte 102,15,56,221,209
+ movups (%esi),%xmm6
+ paddq 16(%esp),%xmm7
+ leal 16(%esi),%esi
+ jmp L029ccm64_dec_outer
+.align 4,0x90
+L029ccm64_dec_outer:
+ xorps %xmm2,%xmm6
+ movdqa %xmm7,%xmm2
+ movl %ebx,%ecx
+ movups %xmm6,(%edi)
+ leal 16(%edi),%edi
+.byte 102,15,56,0,213
+ subl $1,%eax
+ jz L030ccm64_dec_break
+ movups (%ebp),%xmm0
+ shrl $1,%ecx
+ movups 16(%ebp),%xmm1
+ xorps %xmm0,%xmm6
+ leal 32(%ebp),%edx
+ xorps %xmm0,%xmm2
+ xorps %xmm6,%xmm3
+ movups (%edx),%xmm0
+L031ccm64_dec2_loop:
+.byte 102,15,56,220,209
+ decl %ecx
+.byte 102,15,56,220,217
+ movups 16(%edx),%xmm1
+.byte 102,15,56,220,208
+ leal 32(%edx),%edx
+.byte 102,15,56,220,216
+ movups (%edx),%xmm0
+ jnz L031ccm64_dec2_loop
+ movups (%esi),%xmm6
+ paddq 16(%esp),%xmm7
+.byte 102,15,56,220,209
+.byte 102,15,56,220,217
+ leal 16(%esi),%esi
+.byte 102,15,56,221,208
+.byte 102,15,56,221,216
+ jmp L029ccm64_dec_outer
+.align 4,0x90
+L030ccm64_dec_break:
+ movl %ebp,%edx
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ xorps %xmm0,%xmm6
+ leal 32(%edx),%edx
+ xorps %xmm6,%xmm3
+L032enc1_loop_6:
+.byte 102,15,56,220,217
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L032enc1_loop_6
+.byte 102,15,56,221,217
+ movl 48(%esp),%esp
+ movl 40(%esp),%edi
+ movups %xmm3,(%edi)
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.globl _aesni_ctr32_encrypt_blocks
+.align 4
+_aesni_ctr32_encrypt_blocks:
+L_aesni_ctr32_encrypt_blocks_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebx
+ movl %esp,%ebp
+ subl $88,%esp
+ andl $-16,%esp
+ movl %ebp,80(%esp)
+ cmpl $1,%eax
+ je L033ctr32_one_shortcut
+ movdqu (%ebx),%xmm7
+ movl $202182159,(%esp)
+ movl $134810123,4(%esp)
+ movl $67438087,8(%esp)
+ movl $66051,12(%esp)
+ movl $6,%ecx
+ xorl %ebp,%ebp
+ movl %ecx,16(%esp)
+ movl %ecx,20(%esp)
+ movl %ecx,24(%esp)
+ movl %ebp,28(%esp)
+.byte 102,15,58,22,251,3
+.byte 102,15,58,34,253,3
+ movl 240(%edx),%ecx
+ bswap %ebx
+ pxor %xmm1,%xmm1
+ pxor %xmm0,%xmm0
+ movdqa (%esp),%xmm2
+.byte 102,15,58,34,203,0
+ leal 3(%ebx),%ebp
+.byte 102,15,58,34,197,0
+ incl %ebx
+.byte 102,15,58,34,203,1
+ incl %ebp
+.byte 102,15,58,34,197,1
+ incl %ebx
+.byte 102,15,58,34,203,2
+ incl %ebp
+.byte 102,15,58,34,197,2
+ movdqa %xmm1,48(%esp)
+.byte 102,15,56,0,202
+ movdqa %xmm0,64(%esp)
+.byte 102,15,56,0,194
+ pshufd $192,%xmm1,%xmm2
+ pshufd $128,%xmm1,%xmm3
+ cmpl $6,%eax
+ jb L034ctr32_tail
+ movdqa %xmm7,32(%esp)
+ shrl $1,%ecx
+ movl %edx,%ebp
+ movl %ecx,%ebx
+ subl $6,%eax
+ jmp L035ctr32_loop6
+.align 4,0x90
+L035ctr32_loop6:
+ pshufd $64,%xmm1,%xmm4
+ movdqa 32(%esp),%xmm1
+ pshufd $192,%xmm0,%xmm5
+ por %xmm1,%xmm2
+ pshufd $128,%xmm0,%xmm6
+ por %xmm1,%xmm3
+ pshufd $64,%xmm0,%xmm7
+ por %xmm1,%xmm4
+ por %xmm1,%xmm5
+ por %xmm1,%xmm6
+ por %xmm1,%xmm7
+ movups (%ebp),%xmm0
+ movups 16(%ebp),%xmm1
+ leal 32(%ebp),%edx
+ decl %ecx
+ pxor %xmm0,%xmm2
+ pxor %xmm0,%xmm3
+.byte 102,15,56,220,209
+ pxor %xmm0,%xmm4
+.byte 102,15,56,220,217
+ pxor %xmm0,%xmm5
+.byte 102,15,56,220,225
+ pxor %xmm0,%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+.byte 102,15,56,220,241
+ movups (%edx),%xmm0
+.byte 102,15,56,220,249
+ call L_aesni_encrypt6_enter
+ movups (%esi),%xmm1
+ movups 16(%esi),%xmm0
+ xorps %xmm1,%xmm2
+ movups 32(%esi),%xmm1
+ xorps %xmm0,%xmm3
+ movups %xmm2,(%edi)
+ movdqa 16(%esp),%xmm0
+ xorps %xmm1,%xmm4
+ movdqa 48(%esp),%xmm1
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ paddd %xmm0,%xmm1
+ paddd 64(%esp),%xmm0
+ movdqa (%esp),%xmm2
+ movups 48(%esi),%xmm3
+ movups 64(%esi),%xmm4
+ xorps %xmm3,%xmm5
+ movups 80(%esi),%xmm3
+ leal 96(%esi),%esi
+ movdqa %xmm1,48(%esp)
+.byte 102,15,56,0,202
+ xorps %xmm4,%xmm6
+ movups %xmm5,48(%edi)
+ xorps %xmm3,%xmm7
+ movdqa %xmm0,64(%esp)
+.byte 102,15,56,0,194
+ movups %xmm6,64(%edi)
+ pshufd $192,%xmm1,%xmm2
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ movl %ebx,%ecx
+ pshufd $128,%xmm1,%xmm3
+ subl $6,%eax
+ jnc L035ctr32_loop6
+ addl $6,%eax
+ jz L036ctr32_ret
+ movl %ebp,%edx
+ leal 1(,%ecx,2),%ecx
+ movdqa 32(%esp),%xmm7
+L034ctr32_tail:
+ por %xmm7,%xmm2
+ cmpl $2,%eax
+ jb L037ctr32_one
+ pshufd $64,%xmm1,%xmm4
+ por %xmm7,%xmm3
+ je L038ctr32_two
+ pshufd $192,%xmm0,%xmm5
+ por %xmm7,%xmm4
+ cmpl $4,%eax
+ jb L039ctr32_three
+ pshufd $128,%xmm0,%xmm6
+ por %xmm7,%xmm5
+ je L040ctr32_four
+ por %xmm7,%xmm6
+ call __aesni_encrypt6
+ movups (%esi),%xmm1
+ movups 16(%esi),%xmm0
+ xorps %xmm1,%xmm2
+ movups 32(%esi),%xmm1
+ xorps %xmm0,%xmm3
+ movups 48(%esi),%xmm0
+ xorps %xmm1,%xmm4
+ movups 64(%esi),%xmm1
+ xorps %xmm0,%xmm5
+ movups %xmm2,(%edi)
+ xorps %xmm1,%xmm6
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ jmp L036ctr32_ret
+.align 4,0x90
+L033ctr32_one_shortcut:
+ movups (%ebx),%xmm2
+ movl 240(%edx),%ecx
+L037ctr32_one:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L041enc1_loop_7:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L041enc1_loop_7
+.byte 102,15,56,221,209
+ movups (%esi),%xmm6
+ xorps %xmm2,%xmm6
+ movups %xmm6,(%edi)
+ jmp L036ctr32_ret
+.align 4,0x90
+L038ctr32_two:
+ call __aesni_encrypt3
+ movups (%esi),%xmm5
+ movups 16(%esi),%xmm6
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ jmp L036ctr32_ret
+.align 4,0x90
+L039ctr32_three:
+ call __aesni_encrypt3
+ movups (%esi),%xmm5
+ movups 16(%esi),%xmm6
+ xorps %xmm5,%xmm2
+ movups 32(%esi),%xmm7
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ xorps %xmm7,%xmm4
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ jmp L036ctr32_ret
+.align 4,0x90
+L040ctr32_four:
+ call __aesni_encrypt4
+ movups (%esi),%xmm6
+ movups 16(%esi),%xmm7
+ movups 32(%esi),%xmm1
+ xorps %xmm6,%xmm2
+ movups 48(%esi),%xmm0
+ xorps %xmm7,%xmm3
+ movups %xmm2,(%edi)
+ xorps %xmm1,%xmm4
+ movups %xmm3,16(%edi)
+ xorps %xmm0,%xmm5
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+L036ctr32_ret:
+ movl 80(%esp),%esp
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.globl _aesni_xts_encrypt
+.align 4
+_aesni_xts_encrypt:
+L_aesni_xts_encrypt_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 36(%esp),%edx
+ movl 40(%esp),%esi
+ movl 240(%edx),%ecx
+ movups (%esi),%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L042enc1_loop_8:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L042enc1_loop_8
+.byte 102,15,56,221,209
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl %esp,%ebp
+ subl $120,%esp
+ movl 240(%edx),%ecx
+ andl $-16,%esp
+ movl $135,96(%esp)
+ movl $0,100(%esp)
+ movl $1,104(%esp)
+ movl $0,108(%esp)
+ movl %eax,112(%esp)
+ movl %ebp,116(%esp)
+ movdqa %xmm2,%xmm1
+ pxor %xmm0,%xmm0
+ movdqa 96(%esp),%xmm3
+ pcmpgtd %xmm1,%xmm0
+ andl $-16,%eax
+ movl %edx,%ebp
+ movl %ecx,%ebx
+ subl $96,%eax
+ jc L043xts_enc_short
+ shrl $1,%ecx
+ movl %ecx,%ebx
+ jmp L044xts_enc_loop6
+.align 4,0x90
+L044xts_enc_loop6:
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,16(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,32(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,48(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm7
+ movdqa %xmm1,64(%esp)
+ paddq %xmm1,%xmm1
+ movups (%ebp),%xmm0
+ pand %xmm3,%xmm7
+ movups (%esi),%xmm2
+ pxor %xmm1,%xmm7
+ movdqu 16(%esi),%xmm3
+ xorps %xmm0,%xmm2
+ movdqu 32(%esi),%xmm4
+ pxor %xmm0,%xmm3
+ movdqu 48(%esi),%xmm5
+ pxor %xmm0,%xmm4
+ movdqu 64(%esi),%xmm6
+ pxor %xmm0,%xmm5
+ movdqu 80(%esi),%xmm1
+ pxor %xmm0,%xmm6
+ leal 96(%esi),%esi
+ pxor (%esp),%xmm2
+ movdqa %xmm7,80(%esp)
+ pxor %xmm1,%xmm7
+ movups 16(%ebp),%xmm1
+ leal 32(%ebp),%edx
+ pxor 16(%esp),%xmm3
+.byte 102,15,56,220,209
+ pxor 32(%esp),%xmm4
+.byte 102,15,56,220,217
+ pxor 48(%esp),%xmm5
+ decl %ecx
+.byte 102,15,56,220,225
+ pxor 64(%esp),%xmm6
+.byte 102,15,56,220,233
+ pxor %xmm0,%xmm7
+.byte 102,15,56,220,241
+ movups (%edx),%xmm0
+.byte 102,15,56,220,249
+ call L_aesni_encrypt6_enter
+ movdqa 80(%esp),%xmm1
+ pxor %xmm0,%xmm0
+ xorps (%esp),%xmm2
+ pcmpgtd %xmm1,%xmm0
+ xorps 16(%esp),%xmm3
+ movups %xmm2,(%edi)
+ xorps 32(%esp),%xmm4
+ movups %xmm3,16(%edi)
+ xorps 48(%esp),%xmm5
+ movups %xmm4,32(%edi)
+ xorps 64(%esp),%xmm6
+ movups %xmm5,48(%edi)
+ xorps %xmm1,%xmm7
+ movups %xmm6,64(%edi)
+ pshufd $19,%xmm0,%xmm2
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ movdqa 96(%esp),%xmm3
+ pxor %xmm0,%xmm0
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ movl %ebx,%ecx
+ pxor %xmm2,%xmm1
+ subl $96,%eax
+ jnc L044xts_enc_loop6
+ leal 1(,%ecx,2),%ecx
+ movl %ebp,%edx
+ movl %ecx,%ebx
+L043xts_enc_short:
+ addl $96,%eax
+ jz L045xts_enc_done6x
+ movdqa %xmm1,%xmm5
+ cmpl $32,%eax
+ jb L046xts_enc_one
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ je L047xts_enc_two
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,%xmm6
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ cmpl $64,%eax
+ jb L048xts_enc_three
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,%xmm7
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ movdqa %xmm5,(%esp)
+ movdqa %xmm6,16(%esp)
+ je L049xts_enc_four
+ movdqa %xmm7,32(%esp)
+ pshufd $19,%xmm0,%xmm7
+ movdqa %xmm1,48(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm7
+ pxor %xmm1,%xmm7
+ movdqu (%esi),%xmm2
+ movdqu 16(%esi),%xmm3
+ movdqu 32(%esi),%xmm4
+ pxor (%esp),%xmm2
+ movdqu 48(%esi),%xmm5
+ pxor 16(%esp),%xmm3
+ movdqu 64(%esi),%xmm6
+ pxor 32(%esp),%xmm4
+ leal 80(%esi),%esi
+ pxor 48(%esp),%xmm5
+ movdqa %xmm7,64(%esp)
+ pxor %xmm7,%xmm6
+ call __aesni_encrypt6
+ movaps 64(%esp),%xmm1
+ xorps (%esp),%xmm2
+ xorps 16(%esp),%xmm3
+ xorps 32(%esp),%xmm4
+ movups %xmm2,(%edi)
+ xorps 48(%esp),%xmm5
+ movups %xmm3,16(%edi)
+ xorps %xmm1,%xmm6
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ leal 80(%edi),%edi
+ jmp L050xts_enc_done
+.align 4,0x90
+L046xts_enc_one:
+ movups (%esi),%xmm2
+ leal 16(%esi),%esi
+ xorps %xmm5,%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L051enc1_loop_9:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L051enc1_loop_9
+.byte 102,15,56,221,209
+ xorps %xmm5,%xmm2
+ movups %xmm2,(%edi)
+ leal 16(%edi),%edi
+ movdqa %xmm5,%xmm1
+ jmp L050xts_enc_done
+.align 4,0x90
+L047xts_enc_two:
+ movaps %xmm1,%xmm6
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ leal 32(%esi),%esi
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm4,%xmm4
+ call __aesni_encrypt3
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ leal 32(%edi),%edi
+ movdqa %xmm6,%xmm1
+ jmp L050xts_enc_done
+.align 4,0x90
+L048xts_enc_three:
+ movaps %xmm1,%xmm7
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ movups 32(%esi),%xmm4
+ leal 48(%esi),%esi
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm7,%xmm4
+ call __aesni_encrypt3
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm7,%xmm4
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ leal 48(%edi),%edi
+ movdqa %xmm7,%xmm1
+ jmp L050xts_enc_done
+.align 4,0x90
+L049xts_enc_four:
+ movaps %xmm1,%xmm6
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ movups 32(%esi),%xmm4
+ xorps (%esp),%xmm2
+ movups 48(%esi),%xmm5
+ leal 64(%esi),%esi
+ xorps 16(%esp),%xmm3
+ xorps %xmm7,%xmm4
+ xorps %xmm6,%xmm5
+ call __aesni_encrypt4
+ xorps (%esp),%xmm2
+ xorps 16(%esp),%xmm3
+ xorps %xmm7,%xmm4
+ movups %xmm2,(%edi)
+ xorps %xmm6,%xmm5
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ leal 64(%edi),%edi
+ movdqa %xmm6,%xmm1
+ jmp L050xts_enc_done
+.align 4,0x90
+L045xts_enc_done6x:
+ movl 112(%esp),%eax
+ andl $15,%eax
+ jz L052xts_enc_ret
+ movdqa %xmm1,%xmm5
+ movl %eax,112(%esp)
+ jmp L053xts_enc_steal
+.align 4,0x90
+L050xts_enc_done:
+ movl 112(%esp),%eax
+ pxor %xmm0,%xmm0
+ andl $15,%eax
+ jz L052xts_enc_ret
+ pcmpgtd %xmm1,%xmm0
+ movl %eax,112(%esp)
+ pshufd $19,%xmm0,%xmm5
+ paddq %xmm1,%xmm1
+ pand 96(%esp),%xmm5
+ pxor %xmm1,%xmm5
+L053xts_enc_steal:
+ movzbl (%esi),%ecx
+ movzbl -16(%edi),%edx
+ leal 1(%esi),%esi
+ movb %cl,-16(%edi)
+ movb %dl,(%edi)
+ leal 1(%edi),%edi
+ subl $1,%eax
+ jnz L053xts_enc_steal
+ subl 112(%esp),%edi
+ movl %ebp,%edx
+ movl %ebx,%ecx
+ movups -16(%edi),%xmm2
+ xorps %xmm5,%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L054enc1_loop_10:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L054enc1_loop_10
+.byte 102,15,56,221,209
+ xorps %xmm5,%xmm2
+ movups %xmm2,-16(%edi)
+L052xts_enc_ret:
+ movl 116(%esp),%esp
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.globl _aesni_xts_decrypt
+.align 4
+_aesni_xts_decrypt:
+L_aesni_xts_decrypt_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 36(%esp),%edx
+ movl 40(%esp),%esi
+ movl 240(%edx),%ecx
+ movups (%esi),%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L055enc1_loop_11:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L055enc1_loop_11
+.byte 102,15,56,221,209
+ movl 20(%esp),%esi
+ movl 24(%esp),%edi
+ movl 28(%esp),%eax
+ movl 32(%esp),%edx
+ movl %esp,%ebp
+ subl $120,%esp
+ andl $-16,%esp
+ xorl %ebx,%ebx
+ testl $15,%eax
+ setnz %bl
+ shll $4,%ebx
+ subl %ebx,%eax
+ movl $135,96(%esp)
+ movl $0,100(%esp)
+ movl $1,104(%esp)
+ movl $0,108(%esp)
+ movl %eax,112(%esp)
+ movl %ebp,116(%esp)
+ movl 240(%edx),%ecx
+ movl %edx,%ebp
+ movl %ecx,%ebx
+ movdqa %xmm2,%xmm1
+ pxor %xmm0,%xmm0
+ movdqa 96(%esp),%xmm3
+ pcmpgtd %xmm1,%xmm0
+ andl $-16,%eax
+ subl $96,%eax
+ jc L056xts_dec_short
+ shrl $1,%ecx
+ movl %ecx,%ebx
+ jmp L057xts_dec_loop6
+.align 4,0x90
+L057xts_dec_loop6:
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,16(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,32(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,48(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ pshufd $19,%xmm0,%xmm7
+ movdqa %xmm1,64(%esp)
+ paddq %xmm1,%xmm1
+ movups (%ebp),%xmm0
+ pand %xmm3,%xmm7
+ movups (%esi),%xmm2
+ pxor %xmm1,%xmm7
+ movdqu 16(%esi),%xmm3
+ xorps %xmm0,%xmm2
+ movdqu 32(%esi),%xmm4
+ pxor %xmm0,%xmm3
+ movdqu 48(%esi),%xmm5
+ pxor %xmm0,%xmm4
+ movdqu 64(%esi),%xmm6
+ pxor %xmm0,%xmm5
+ movdqu 80(%esi),%xmm1
+ pxor %xmm0,%xmm6
+ leal 96(%esi),%esi
+ pxor (%esp),%xmm2
+ movdqa %xmm7,80(%esp)
+ pxor %xmm1,%xmm7
+ movups 16(%ebp),%xmm1
+ leal 32(%ebp),%edx
+ pxor 16(%esp),%xmm3
+.byte 102,15,56,222,209
+ pxor 32(%esp),%xmm4
+.byte 102,15,56,222,217
+ pxor 48(%esp),%xmm5
+ decl %ecx
+.byte 102,15,56,222,225
+ pxor 64(%esp),%xmm6
+.byte 102,15,56,222,233
+ pxor %xmm0,%xmm7
+.byte 102,15,56,222,241
+ movups (%edx),%xmm0
+.byte 102,15,56,222,249
+ call L_aesni_decrypt6_enter
+ movdqa 80(%esp),%xmm1
+ pxor %xmm0,%xmm0
+ xorps (%esp),%xmm2
+ pcmpgtd %xmm1,%xmm0
+ xorps 16(%esp),%xmm3
+ movups %xmm2,(%edi)
+ xorps 32(%esp),%xmm4
+ movups %xmm3,16(%edi)
+ xorps 48(%esp),%xmm5
+ movups %xmm4,32(%edi)
+ xorps 64(%esp),%xmm6
+ movups %xmm5,48(%edi)
+ xorps %xmm1,%xmm7
+ movups %xmm6,64(%edi)
+ pshufd $19,%xmm0,%xmm2
+ movups %xmm7,80(%edi)
+ leal 96(%edi),%edi
+ movdqa 96(%esp),%xmm3
+ pxor %xmm0,%xmm0
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ movl %ebx,%ecx
+ pxor %xmm2,%xmm1
+ subl $96,%eax
+ jnc L057xts_dec_loop6
+ leal 1(,%ecx,2),%ecx
+ movl %ebp,%edx
+ movl %ecx,%ebx
+L056xts_dec_short:
+ addl $96,%eax
+ jz L058xts_dec_done6x
+ movdqa %xmm1,%xmm5
+ cmpl $32,%eax
+ jb L059xts_dec_one
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ je L060xts_dec_two
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,%xmm6
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ cmpl $64,%eax
+ jb L061xts_dec_three
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa %xmm1,%xmm7
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+ movdqa %xmm5,(%esp)
+ movdqa %xmm6,16(%esp)
+ je L062xts_dec_four
+ movdqa %xmm7,32(%esp)
+ pshufd $19,%xmm0,%xmm7
+ movdqa %xmm1,48(%esp)
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm7
+ pxor %xmm1,%xmm7
+ movdqu (%esi),%xmm2
+ movdqu 16(%esi),%xmm3
+ movdqu 32(%esi),%xmm4
+ pxor (%esp),%xmm2
+ movdqu 48(%esi),%xmm5
+ pxor 16(%esp),%xmm3
+ movdqu 64(%esi),%xmm6
+ pxor 32(%esp),%xmm4
+ leal 80(%esi),%esi
+ pxor 48(%esp),%xmm5
+ movdqa %xmm7,64(%esp)
+ pxor %xmm7,%xmm6
+ call __aesni_decrypt6
+ movaps 64(%esp),%xmm1
+ xorps (%esp),%xmm2
+ xorps 16(%esp),%xmm3
+ xorps 32(%esp),%xmm4
+ movups %xmm2,(%edi)
+ xorps 48(%esp),%xmm5
+ movups %xmm3,16(%edi)
+ xorps %xmm1,%xmm6
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ movups %xmm6,64(%edi)
+ leal 80(%edi),%edi
+ jmp L063xts_dec_done
+.align 4,0x90
+L059xts_dec_one:
+ movups (%esi),%xmm2
+ leal 16(%esi),%esi
+ xorps %xmm5,%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L064dec1_loop_12:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L064dec1_loop_12
+.byte 102,15,56,223,209
+ xorps %xmm5,%xmm2
+ movups %xmm2,(%edi)
+ leal 16(%edi),%edi
+ movdqa %xmm5,%xmm1
+ jmp L063xts_dec_done
+.align 4,0x90
+L060xts_dec_two:
+ movaps %xmm1,%xmm6
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ leal 32(%esi),%esi
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ call __aesni_decrypt3
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ leal 32(%edi),%edi
+ movdqa %xmm6,%xmm1
+ jmp L063xts_dec_done
+.align 4,0x90
+L061xts_dec_three:
+ movaps %xmm1,%xmm7
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ movups 32(%esi),%xmm4
+ leal 48(%esi),%esi
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm7,%xmm4
+ call __aesni_decrypt3
+ xorps %xmm5,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm7,%xmm4
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ leal 48(%edi),%edi
+ movdqa %xmm7,%xmm1
+ jmp L063xts_dec_done
+.align 4,0x90
+L062xts_dec_four:
+ movaps %xmm1,%xmm6
+ movups (%esi),%xmm2
+ movups 16(%esi),%xmm3
+ movups 32(%esi),%xmm4
+ xorps (%esp),%xmm2
+ movups 48(%esi),%xmm5
+ leal 64(%esi),%esi
+ xorps 16(%esp),%xmm3
+ xorps %xmm7,%xmm4
+ xorps %xmm6,%xmm5
+ call __aesni_decrypt4
+ xorps (%esp),%xmm2
+ xorps 16(%esp),%xmm3
+ xorps %xmm7,%xmm4
+ movups %xmm2,(%edi)
+ xorps %xmm6,%xmm5
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ leal 64(%edi),%edi
+ movdqa %xmm6,%xmm1
+ jmp L063xts_dec_done
+.align 4,0x90
+L058xts_dec_done6x:
+ movl 112(%esp),%eax
+ andl $15,%eax
+ jz L065xts_dec_ret
+ movl %eax,112(%esp)
+ jmp L066xts_dec_only_one_more
+.align 4,0x90
+L063xts_dec_done:
+ movl 112(%esp),%eax
+ pxor %xmm0,%xmm0
+ andl $15,%eax
+ jz L065xts_dec_ret
+ pcmpgtd %xmm1,%xmm0
+ movl %eax,112(%esp)
+ pshufd $19,%xmm0,%xmm2
+ pxor %xmm0,%xmm0
+ movdqa 96(%esp),%xmm3
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm2
+ pcmpgtd %xmm1,%xmm0
+ pxor %xmm2,%xmm1
+L066xts_dec_only_one_more:
+ pshufd $19,%xmm0,%xmm5
+ movdqa %xmm1,%xmm6
+ paddq %xmm1,%xmm1
+ pand %xmm3,%xmm5
+ pxor %xmm1,%xmm5
+ movl %ebp,%edx
+ movl %ebx,%ecx
+ movups (%esi),%xmm2
+ xorps %xmm5,%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L067dec1_loop_13:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L067dec1_loop_13
+.byte 102,15,56,223,209
+ xorps %xmm5,%xmm2
+ movups %xmm2,(%edi)
+L068xts_dec_steal:
+ movzbl 16(%esi),%ecx
+ movzbl (%edi),%edx
+ leal 1(%esi),%esi
+ movb %cl,(%edi)
+ movb %dl,16(%edi)
+ leal 1(%edi),%edi
+ subl $1,%eax
+ jnz L068xts_dec_steal
+ subl 112(%esp),%edi
+ movl %ebp,%edx
+ movl %ebx,%ecx
+ movups (%edi),%xmm2
+ xorps %xmm6,%xmm2
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L069dec1_loop_14:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L069dec1_loop_14
+.byte 102,15,56,223,209
+ xorps %xmm6,%xmm2
+ movups %xmm2,(%edi)
+L065xts_dec_ret:
+ movl 116(%esp),%esp
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.globl _aesni_cbc_encrypt
+.align 4
+_aesni_cbc_encrypt:
+L_aesni_cbc_encrypt_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 20(%esp),%esi
+ movl %esp,%ebx
+ movl 24(%esp),%edi
+ subl $24,%ebx
+ movl 28(%esp),%eax
+ andl $-16,%ebx
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebp
+ testl %eax,%eax
+ jz L070cbc_abort
+ cmpl $0,40(%esp)
+ xchgl %esp,%ebx
+ movups (%ebp),%xmm7
+ movl 240(%edx),%ecx
+ movl %edx,%ebp
+ movl %ebx,16(%esp)
+ movl %ecx,%ebx
+ je L071cbc_decrypt
+ movaps %xmm7,%xmm2
+ cmpl $16,%eax
+ jb L072cbc_enc_tail
+ subl $16,%eax
+ jmp L073cbc_enc_loop
+.align 4,0x90
+L073cbc_enc_loop:
+ movups (%esi),%xmm7
+ leal 16(%esi),%esi
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ xorps %xmm0,%xmm7
+ leal 32(%edx),%edx
+ xorps %xmm7,%xmm2
+L074enc1_loop_15:
+.byte 102,15,56,220,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L074enc1_loop_15
+.byte 102,15,56,221,209
+ movl %ebx,%ecx
+ movl %ebp,%edx
+ movups %xmm2,(%edi)
+ leal 16(%edi),%edi
+ subl $16,%eax
+ jnc L073cbc_enc_loop
+ addl $16,%eax
+ jnz L072cbc_enc_tail
+ movaps %xmm2,%xmm7
+ jmp L075cbc_ret
+L072cbc_enc_tail:
+ movl %eax,%ecx
+.long 2767451785
+ movl $16,%ecx
+ subl %eax,%ecx
+ xorl %eax,%eax
+.long 2868115081
+ leal -16(%edi),%edi
+ movl %ebx,%ecx
+ movl %edi,%esi
+ movl %ebp,%edx
+ jmp L073cbc_enc_loop
+.align 4,0x90
+L071cbc_decrypt:
+ cmpl $80,%eax
+ jbe L076cbc_dec_tail
+ movaps %xmm7,(%esp)
+ subl $80,%eax
+ jmp L077cbc_dec_loop6_enter
+.align 4,0x90
+L078cbc_dec_loop6:
+ movaps %xmm0,(%esp)
+ movups %xmm7,(%edi)
+ leal 16(%edi),%edi
+L077cbc_dec_loop6_enter:
+ movdqu (%esi),%xmm2
+ movdqu 16(%esi),%xmm3
+ movdqu 32(%esi),%xmm4
+ movdqu 48(%esi),%xmm5
+ movdqu 64(%esi),%xmm6
+ movdqu 80(%esi),%xmm7
+ call __aesni_decrypt6
+ movups (%esi),%xmm1
+ movups 16(%esi),%xmm0
+ xorps (%esp),%xmm2
+ xorps %xmm1,%xmm3
+ movups 32(%esi),%xmm1
+ xorps %xmm0,%xmm4
+ movups 48(%esi),%xmm0
+ xorps %xmm1,%xmm5
+ movups 64(%esi),%xmm1
+ xorps %xmm0,%xmm6
+ movups 80(%esi),%xmm0
+ xorps %xmm1,%xmm7
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ leal 96(%esi),%esi
+ movups %xmm4,32(%edi)
+ movl %ebx,%ecx
+ movups %xmm5,48(%edi)
+ movl %ebp,%edx
+ movups %xmm6,64(%edi)
+ leal 80(%edi),%edi
+ subl $96,%eax
+ ja L078cbc_dec_loop6
+ movaps %xmm7,%xmm2
+ movaps %xmm0,%xmm7
+ addl $80,%eax
+ jle L079cbc_dec_tail_collected
+ movups %xmm2,(%edi)
+ leal 16(%edi),%edi
+L076cbc_dec_tail:
+ movups (%esi),%xmm2
+ movaps %xmm2,%xmm6
+ cmpl $16,%eax
+ jbe L080cbc_dec_one
+ movups 16(%esi),%xmm3
+ movaps %xmm3,%xmm5
+ cmpl $32,%eax
+ jbe L081cbc_dec_two
+ movups 32(%esi),%xmm4
+ cmpl $48,%eax
+ jbe L082cbc_dec_three
+ movups 48(%esi),%xmm5
+ cmpl $64,%eax
+ jbe L083cbc_dec_four
+ movups 64(%esi),%xmm6
+ movaps %xmm7,(%esp)
+ movups (%esi),%xmm2
+ xorps %xmm7,%xmm7
+ call __aesni_decrypt6
+ movups (%esi),%xmm1
+ movups 16(%esi),%xmm0
+ xorps (%esp),%xmm2
+ xorps %xmm1,%xmm3
+ movups 32(%esi),%xmm1
+ xorps %xmm0,%xmm4
+ movups 48(%esi),%xmm0
+ xorps %xmm1,%xmm5
+ movups 64(%esi),%xmm7
+ xorps %xmm0,%xmm6
+ movups %xmm2,(%edi)
+ movups %xmm3,16(%edi)
+ movups %xmm4,32(%edi)
+ movups %xmm5,48(%edi)
+ leal 64(%edi),%edi
+ movaps %xmm6,%xmm2
+ subl $80,%eax
+ jmp L079cbc_dec_tail_collected
+.align 4,0x90
+L080cbc_dec_one:
+ movups (%edx),%xmm0
+ movups 16(%edx),%xmm1
+ leal 32(%edx),%edx
+ xorps %xmm0,%xmm2
+L084dec1_loop_16:
+.byte 102,15,56,222,209
+ decl %ecx
+ movups (%edx),%xmm1
+ leal 16(%edx),%edx
+ jnz L084dec1_loop_16
+.byte 102,15,56,223,209
+ xorps %xmm7,%xmm2
+ movaps %xmm6,%xmm7
+ subl $16,%eax
+ jmp L079cbc_dec_tail_collected
+.align 4,0x90
+L081cbc_dec_two:
+ xorps %xmm4,%xmm4
+ call __aesni_decrypt3
+ xorps %xmm7,%xmm2
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ movaps %xmm3,%xmm2
+ leal 16(%edi),%edi
+ movaps %xmm5,%xmm7
+ subl $32,%eax
+ jmp L079cbc_dec_tail_collected
+.align 4,0x90
+L082cbc_dec_three:
+ call __aesni_decrypt3
+ xorps %xmm7,%xmm2
+ xorps %xmm6,%xmm3
+ xorps %xmm5,%xmm4
+ movups %xmm2,(%edi)
+ movaps %xmm4,%xmm2
+ movups %xmm3,16(%edi)
+ leal 32(%edi),%edi
+ movups 32(%esi),%xmm7
+ subl $48,%eax
+ jmp L079cbc_dec_tail_collected
+.align 4,0x90
+L083cbc_dec_four:
+ call __aesni_decrypt4
+ movups 16(%esi),%xmm1
+ movups 32(%esi),%xmm0
+ xorps %xmm7,%xmm2
+ movups 48(%esi),%xmm7
+ xorps %xmm6,%xmm3
+ movups %xmm2,(%edi)
+ xorps %xmm1,%xmm4
+ movups %xmm3,16(%edi)
+ xorps %xmm0,%xmm5
+ movups %xmm4,32(%edi)
+ leal 48(%edi),%edi
+ movaps %xmm5,%xmm2
+ subl $64,%eax
+L079cbc_dec_tail_collected:
+ andl $15,%eax
+ jnz L085cbc_dec_tail_partial
+ movups %xmm2,(%edi)
+ jmp L075cbc_ret
+.align 4,0x90
+L085cbc_dec_tail_partial:
+ movaps %xmm2,(%esp)
+ movl $16,%ecx
+ movl %esp,%esi
+ subl %eax,%ecx
+.long 2767451785
+L075cbc_ret:
+ movl 16(%esp),%esp
+ movl 36(%esp),%ebp
+ movups %xmm7,(%ebp)
+L070cbc_abort:
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.align 4
+__aesni_set_encrypt_key:
+ testl %eax,%eax
+ jz L086bad_pointer
+ testl %edx,%edx
+ jz L086bad_pointer
+ movups (%eax),%xmm0
+ xorps %xmm4,%xmm4
+ leal 16(%edx),%edx
+ cmpl $256,%ecx
+ je L08714rounds
+ cmpl $192,%ecx
+ je L08812rounds
+ cmpl $128,%ecx
+ jne L089bad_keybits
+.align 4,0x90
+L09010rounds:
+ movl $9,%ecx
+ movups %xmm0,-16(%edx)
+.byte 102,15,58,223,200,1
+ call L091key_128_cold
+.byte 102,15,58,223,200,2
+ call L092key_128
+.byte 102,15,58,223,200,4
+ call L092key_128
+.byte 102,15,58,223,200,8
+ call L092key_128
+.byte 102,15,58,223,200,16
+ call L092key_128
+.byte 102,15,58,223,200,32
+ call L092key_128
+.byte 102,15,58,223,200,64
+ call L092key_128
+.byte 102,15,58,223,200,128
+ call L092key_128
+.byte 102,15,58,223,200,27
+ call L092key_128
+.byte 102,15,58,223,200,54
+ call L092key_128
+ movups %xmm0,(%edx)
+ movl %ecx,80(%edx)
+ xorl %eax,%eax
+ ret
+.align 4,0x90
+L092key_128:
+ movups %xmm0,(%edx)
+ leal 16(%edx),%edx
+L091key_128_cold:
+ shufps $16,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $255,%xmm1,%xmm1
+ xorps %xmm1,%xmm0
+ ret
+.align 4,0x90
+L08812rounds:
+ movq 16(%eax),%xmm2
+ movl $11,%ecx
+ movups %xmm0,-16(%edx)
+.byte 102,15,58,223,202,1
+ call L093key_192a_cold
+.byte 102,15,58,223,202,2
+ call L094key_192b
+.byte 102,15,58,223,202,4
+ call L095key_192a
+.byte 102,15,58,223,202,8
+ call L094key_192b
+.byte 102,15,58,223,202,16
+ call L095key_192a
+.byte 102,15,58,223,202,32
+ call L094key_192b
+.byte 102,15,58,223,202,64
+ call L095key_192a
+.byte 102,15,58,223,202,128
+ call L094key_192b
+ movups %xmm0,(%edx)
+ movl %ecx,48(%edx)
+ xorl %eax,%eax
+ ret
+.align 4,0x90
+L095key_192a:
+ movups %xmm0,(%edx)
+ leal 16(%edx),%edx
+.align 4,0x90
+L093key_192a_cold:
+ movaps %xmm2,%xmm5
+L096key_192b_warm:
+ shufps $16,%xmm0,%xmm4
+ movdqa %xmm2,%xmm3
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ pslldq $4,%xmm3
+ xorps %xmm4,%xmm0
+ pshufd $85,%xmm1,%xmm1
+ pxor %xmm3,%xmm2
+ pxor %xmm1,%xmm0
+ pshufd $255,%xmm0,%xmm3
+ pxor %xmm3,%xmm2
+ ret
+.align 4,0x90
+L094key_192b:
+ movaps %xmm0,%xmm3
+ shufps $68,%xmm0,%xmm5
+ movups %xmm5,(%edx)
+ shufps $78,%xmm2,%xmm3
+ movups %xmm3,16(%edx)
+ leal 32(%edx),%edx
+ jmp L096key_192b_warm
+.align 4,0x90
+L08714rounds:
+ movups 16(%eax),%xmm2
+ movl $13,%ecx
+ leal 16(%edx),%edx
+ movups %xmm0,-32(%edx)
+ movups %xmm2,-16(%edx)
+.byte 102,15,58,223,202,1
+ call L097key_256a_cold
+.byte 102,15,58,223,200,1
+ call L098key_256b
+.byte 102,15,58,223,202,2
+ call L099key_256a
+.byte 102,15,58,223,200,2
+ call L098key_256b
+.byte 102,15,58,223,202,4
+ call L099key_256a
+.byte 102,15,58,223,200,4
+ call L098key_256b
+.byte 102,15,58,223,202,8
+ call L099key_256a
+.byte 102,15,58,223,200,8
+ call L098key_256b
+.byte 102,15,58,223,202,16
+ call L099key_256a
+.byte 102,15,58,223,200,16
+ call L098key_256b
+.byte 102,15,58,223,202,32
+ call L099key_256a
+.byte 102,15,58,223,200,32
+ call L098key_256b
+.byte 102,15,58,223,202,64
+ call L099key_256a
+ movups %xmm0,(%edx)
+ movl %ecx,16(%edx)
+ xorl %eax,%eax
+ ret
+.align 4,0x90
+L099key_256a:
+ movups %xmm2,(%edx)
+ leal 16(%edx),%edx
+L097key_256a_cold:
+ shufps $16,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $140,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps $255,%xmm1,%xmm1
+ xorps %xmm1,%xmm0
+ ret
+.align 4,0x90
+L098key_256b:
+ movups %xmm0,(%edx)
+ leal 16(%edx),%edx
+ shufps $16,%xmm2,%xmm4
+ xorps %xmm4,%xmm2
+ shufps $140,%xmm2,%xmm4
+ xorps %xmm4,%xmm2
+ shufps $170,%xmm1,%xmm1
+ xorps %xmm1,%xmm2
+ ret
+.align 2,0x90
+L086bad_pointer:
+ movl $-1,%eax
+ ret
+.align 2,0x90
+L089bad_keybits:
+ movl $-2,%eax
+ ret
+.globl _aesni_set_encrypt_key
+.align 4
+_aesni_set_encrypt_key:
+L_aesni_set_encrypt_key_begin:
+ movl 4(%esp),%eax
+ movl 8(%esp),%ecx
+ movl 12(%esp),%edx
+ call __aesni_set_encrypt_key
+ ret
+.globl _aesni_set_decrypt_key
+.align 4
+_aesni_set_decrypt_key:
+L_aesni_set_decrypt_key_begin:
+ movl 4(%esp),%eax
+ movl 8(%esp),%ecx
+ movl 12(%esp),%edx
+ call __aesni_set_encrypt_key
+ movl 12(%esp),%edx
+ shll $4,%ecx
+ testl %eax,%eax
+ jnz L100dec_key_ret
+ leal 16(%edx,%ecx,1),%eax
+ movups (%edx),%xmm0
+ movups (%eax),%xmm1
+ movups %xmm0,(%eax)
+ movups %xmm1,(%edx)
+ leal 16(%edx),%edx
+ leal -16(%eax),%eax
+L101dec_key_inverse:
+ movups (%edx),%xmm0
+ movups (%eax),%xmm1
+.byte 102,15,56,219,192
+.byte 102,15,56,219,201
+ leal 16(%edx),%edx
+ leal -16(%eax),%eax
+ movups %xmm0,16(%eax)
+ movups %xmm1,-16(%edx)
+ cmpl %edx,%eax
+ ja L101dec_key_inverse
+ movups (%edx),%xmm0
+.byte 102,15,56,219,192
+ movups %xmm0,(%edx)
+ xorl %eax,%eax
+L100dec_key_ret:
+ ret
+.byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69
+.byte 83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83
+.byte 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
+.byte 115,108,46,111,114,103,62,0
diff --git a/deps/openssl/asm/x86-macosx-gas/camellia/cmll-x86.s b/deps/openssl/asm/x86-macosx-gas/camellia/cmll-x86.s
index 4d61caa68..2367cee78 100644
--- a/deps/openssl/asm/x86-macosx-gas/camellia/cmll-x86.s
+++ b/deps/openssl/asm/x86-macosx-gas/camellia/cmll-x86.s
@@ -1519,10 +1519,10 @@ L013done:
popl %ebx
popl %ebp
ret
-.globl _Camellia_set_key
+.globl _private_Camellia_set_key
.align 4
-_Camellia_set_key:
-L_Camellia_set_key_begin:
+_private_Camellia_set_key:
+L_private_Camellia_set_key_begin:
pushl %ebx
movl 8(%esp),%ecx
movl 12(%esp),%ebx
diff --git a/deps/openssl/asm/x86-macosx-gas/des/crypt586.s b/deps/openssl/asm/x86-macosx-gas/des/crypt586.s
index edb1bb391..7d0074ec2 100644
--- a/deps/openssl/asm/x86-macosx-gas/des/crypt586.s
+++ b/deps/openssl/asm/x86-macosx-gas/des/crypt586.s
@@ -13,11 +13,14 @@ L_fcrypt_body_begin:
xorl %edi,%edi
xorl %esi,%esi
- leal _DES_SPtrans,%edx
+ call L000PIC_me_up
+L000PIC_me_up:
+ popl %edx
+ movl L_DES_SPtrans$non_lazy_ptr-L000PIC_me_up(%edx),%edx
pushl %edx
movl 28(%esp),%ebp
pushl $25
-L000start:
+L001start:
# Round 0
@@ -840,7 +843,7 @@ L000start:
movl %esi,%edi
movl %eax,%esi
movl %ebx,(%esp)
- jnz L000start
+ jnz L001start
# FP
@@ -889,3 +892,7 @@ L000start:
popl %ebx
popl %ebp
ret
+.section __IMPORT,__pointers,non_lazy_symbol_pointers
+L_DES_SPtrans$non_lazy_ptr:
+.indirect_symbol _DES_SPtrans
+.long 0
diff --git a/deps/openssl/asm/x86-macosx-gas/rc4/rc4-586.s b/deps/openssl/asm/x86-macosx-gas/rc4/rc4-586.s
index a821dc950..882a02d74 100644
--- a/deps/openssl/asm/x86-macosx-gas/rc4/rc4-586.s
+++ b/deps/openssl/asm/x86-macosx-gas/rc4/rc4-586.s
@@ -28,11 +28,149 @@ L_RC4_begin:
movl (%edi,%eax,4),%ecx
andl $-4,%edx
jz L002loop1
- leal -4(%esi,%edx,1),%edx
- movl %edx,28(%esp)
+ testl $-8,%edx
movl %ebp,32(%esp)
+ jz L003go4loop4
+ call L004PIC_me_up
+L004PIC_me_up:
+ popl %ebp
+ movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L004PIC_me_up(%ebp),%ebp
+ btl $26,(%ebp)
+ jnc L003go4loop4
+ movl 32(%esp),%ebp
+ andl $-8,%edx
+ leal -8(%esi,%edx,1),%edx
+ movl %edx,-4(%edi)
+ addb %cl,%bl
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ movq (%esi),%mm0
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm2
+ jmp L005loop_mmx_enter
.align 4,0x90
-L003loop4:
+L006loop_mmx:
+ addb %cl,%bl
+ psllq $56,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movq (%esi),%mm0
+ movq %mm2,-8(%ebp,%esi,1)
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm2
+L005loop_mmx_enter:
+ addb %cl,%bl
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm0,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $8,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $16,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $24,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $32,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $40,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ addb %cl,%bl
+ psllq $48,%mm1
+ movl (%edi,%ebx,4),%edx
+ movl %ecx,(%edi,%ebx,4)
+ movl %edx,(%edi,%eax,4)
+ incl %eax
+ addl %ecx,%edx
+ movzbl %al,%eax
+ movzbl %dl,%edx
+ pxor %mm1,%mm2
+ movl (%edi,%eax,4),%ecx
+ movd (%edi,%edx,4),%mm1
+ movl %ebx,%edx
+ xorl %ebx,%ebx
+ movb %dl,%bl
+ cmpl -4(%edi),%esi
+ leal 8(%esi),%esi
+ jb L006loop_mmx
+ psllq $56,%mm1
+ pxor %mm1,%mm2
+ movq %mm2,-8(%ebp,%esi,1)
+ emms
+ cmpl 24(%esp),%esi
+ je L007done
+ jmp L002loop1
+.align 4,0x90
+L003go4loop4:
+ leal -4(%esi,%edx,1),%edx
+ movl %edx,28(%esp)
+L008loop4:
addb %cl,%bl
movl (%edi,%ebx,4),%edx
movl %ecx,(%edi,%ebx,4)
@@ -78,9 +216,9 @@ L003loop4:
movl %ebp,(%ecx,%esi,1)
leal 4(%esi),%esi
movl (%edi,%eax,4),%ecx
- jb L003loop4
+ jb L008loop4
cmpl 24(%esp),%esi
- je L004done
+ je L007done
movl 32(%esp),%ebp
.align 4,0x90
L002loop1:
@@ -98,11 +236,11 @@ L002loop1:
cmpl 24(%esp),%esi
movb %dl,-1(%ebp,%esi,1)
jb L002loop1
- jmp L004done
+ jmp L007done
.align 4,0x90
L001RC4_CHAR:
movzbl (%edi,%eax,1),%ecx
-L005cloop1:
+L009cloop1:
addb %cl,%bl
movzbl (%edi,%ebx,1),%edx
movb %cl,(%edi,%ebx,1)
@@ -115,10 +253,10 @@ L005cloop1:
movzbl (%edi,%eax,1),%ecx
cmpl 24(%esp),%esi
movb %dl,-1(%ebp,%esi,1)
- jb L005cloop1
-L004done:
+ jb L009cloop1
+L007done:
decb %al
- movb %bl,-4(%edi)
+ movl %ebx,-4(%edi)
movb %al,-8(%edi)
L000abort:
popl %edi
@@ -126,10 +264,10 @@ L000abort:
popl %ebx
popl %ebp
ret
-.globl _RC4_set_key
+.globl _private_RC4_set_key
.align 4
-_RC4_set_key:
-L_RC4_set_key_begin:
+_private_RC4_set_key:
+L_private_RC4_set_key_begin:
pushl %ebp
pushl %ebx
pushl %esi
@@ -137,60 +275,63 @@ L_RC4_set_key_begin:
movl 20(%esp),%edi
movl 24(%esp),%ebp
movl 28(%esp),%esi
- leal _OPENSSL_ia32cap_P,%edx
+ call L010PIC_me_up
+L010PIC_me_up:
+ popl %edx
+ movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L010PIC_me_up(%edx),%edx
leal 8(%edi),%edi
leal (%esi,%ebp,1),%esi
negl %ebp
xorl %eax,%eax
movl %ebp,-4(%edi)
btl $20,(%edx)
- jc L006c1stloop
+ jc L011c1stloop
.align 4,0x90
-L007w1stloop:
+L012w1stloop:
movl %eax,(%edi,%eax,4)
addb $1,%al
- jnc L007w1stloop
+ jnc L012w1stloop
xorl %ecx,%ecx
xorl %edx,%edx
.align 4,0x90
-L008w2ndloop:
+L013w2ndloop:
movl (%edi,%ecx,4),%eax
addb (%esi,%ebp,1),%dl
addb %al,%dl
addl $1,%ebp
movl (%edi,%edx,4),%ebx
- jnz L009wnowrap
+ jnz L014wnowrap
movl -4(%edi),%ebp
-L009wnowrap:
+L014wnowrap:
movl %eax,(%edi,%edx,4)
movl %ebx,(%edi,%ecx,4)
addb $1,%cl
- jnc L008w2ndloop
- jmp L010exit
+ jnc L013w2ndloop
+ jmp L015exit
.align 4,0x90
-L006c1stloop:
+L011c1stloop:
movb %al,(%edi,%eax,1)
addb $1,%al
- jnc L006c1stloop
+ jnc L011c1stloop
xorl %ecx,%ecx
xorl %edx,%edx
xorl %ebx,%ebx
.align 4,0x90
-L011c2ndloop:
+L016c2ndloop:
movb (%edi,%ecx,1),%al
addb (%esi,%ebp,1),%dl
addb %al,%dl
addl $1,%ebp
movb (%edi,%edx,1),%bl
- jnz L012cnowrap
+ jnz L017cnowrap
movl -4(%edi),%ebp
-L012cnowrap:
+L017cnowrap:
movb %al,(%edi,%edx,1)
movb %bl,(%edi,%ecx,1)
addb $1,%cl
- jnc L011c2ndloop
+ jnc L016c2ndloop
movl $-1,256(%edi)
-L010exit:
+L015exit:
xorl %eax,%eax
movl %eax,-8(%edi)
movl %eax,-4(%edi)
@@ -203,22 +344,36 @@ L010exit:
.align 4
_RC4_options:
L_RC4_options_begin:
- call L013pic_point
-L013pic_point:
+ call L018pic_point
+L018pic_point:
popl %eax
- leal L014opts-L013pic_point(%eax),%eax
- leal _OPENSSL_ia32cap_P,%edx
- btl $20,(%edx)
- jnc L015skip
+ leal L019opts-L018pic_point(%eax),%eax
+ call L020PIC_me_up
+L020PIC_me_up:
+ popl %edx
+ movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L020PIC_me_up(%edx),%edx
+ movl (%edx),%edx
+ btl $20,%edx
+ jc L0211xchar
+ btl $26,%edx
+ jnc L022ret
+ addl $25,%eax
+ ret
+L0211xchar:
addl $12,%eax
-L015skip:
+L022ret:
ret
.align 6,0x90
-L014opts:
+L019opts:
.byte 114,99,52,40,52,120,44,105,110,116,41,0
.byte 114,99,52,40,49,120,44,99,104,97,114,41,0
+.byte 114,99,52,40,56,120,44,109,109,120,41,0
.byte 82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
.byte 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
.byte 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 6,0x90
-.comm _OPENSSL_ia32cap_P,4
+.section __IMPORT,__pointers,non_lazy_symbol_pointers
+L_OPENSSL_ia32cap_P$non_lazy_ptr:
+.indirect_symbol _OPENSSL_ia32cap_P
+.long 0
+.comm _OPENSSL_ia32cap_P,8,2
diff --git a/deps/openssl/asm/x86-macosx-gas/sha/sha1-586.s b/deps/openssl/asm/x86-macosx-gas/sha/sha1-586.s
index 4f356fe70..28d95721b 100644
--- a/deps/openssl/asm/x86-macosx-gas/sha/sha1-586.s
+++ b/deps/openssl/asm/x86-macosx-gas/sha/sha1-586.s
@@ -11,11 +11,12 @@ L_sha1_block_data_order_begin:
movl 20(%esp),%ebp
movl 24(%esp),%esi
movl 28(%esp),%eax
- subl $64,%esp
+ subl $76,%esp
shll $6,%eax
addl %esi,%eax
- movl %eax,92(%esp)
+ movl %eax,104(%esp)
movl 16(%ebp),%edi
+ jmp L000loop
.align 4,0x90
L000loop:
movl (%esi),%eax
@@ -66,7 +67,7 @@ L000loop:
movl %ebx,52(%esp)
movl %ecx,56(%esp)
movl %edx,60(%esp)
- movl %esi,88(%esp)
+ movl %esi,100(%esp)
movl (%ebp),%eax
movl 4(%ebp),%ebx
movl 8(%ebp),%ecx
@@ -78,10 +79,10 @@ L000loop:
roll $5,%ebp
xorl %edx,%esi
addl %edi,%ebp
- andl %ebx,%esi
movl (%esp),%edi
- xorl %edx,%esi
+ andl %ebx,%esi
rorl $2,%ebx
+ xorl %edx,%esi
leal 1518500249(%ebp,%edi,1),%ebp
addl %esi,%ebp
# 00_15 1
@@ -91,10 +92,10 @@ L000loop:
roll $5,%ebp
xorl %ecx,%edi
addl %edx,%ebp
- andl %eax,%edi
movl 4(%esp),%edx
- xorl %ecx,%edi
+ andl %eax,%edi
rorl $2,%eax
+ xorl %ecx,%edi
leal 1518500249(%ebp,%edx,1),%ebp
addl %edi,%ebp
# 00_15 2
@@ -104,10 +105,10 @@ L000loop:
roll $5,%ebp
xorl %ebx,%edx
addl %ecx,%ebp
- andl %esi,%edx
movl 8(%esp),%ecx
- xorl %ebx,%edx
+ andl %esi,%edx
rorl $2,%esi
+ xorl %ebx,%edx
leal 1518500249(%ebp,%ecx,1),%ebp
addl %edx,%ebp
# 00_15 3
@@ -117,10 +118,10 @@ L000loop:
roll $5,%ebp
xorl %eax,%ecx
addl %ebx,%ebp
- andl %edi,%ecx
movl 12(%esp),%ebx
- xorl %eax,%ecx
+ andl %edi,%ecx
rorl $2,%edi
+ xorl %eax,%ecx
leal 1518500249(%ebp,%ebx,1),%ebp
addl %ecx,%ebp
# 00_15 4
@@ -130,10 +131,10 @@ L000loop:
roll $5,%ebp
xorl %esi,%ebx
addl %eax,%ebp
- andl %edx,%ebx
movl 16(%esp),%eax
- xorl %esi,%ebx
+ andl %edx,%ebx
rorl $2,%edx
+ xorl %esi,%ebx
leal 1518500249(%ebp,%eax,1),%ebp
addl %ebx,%ebp
# 00_15 5
@@ -143,10 +144,10 @@ L000loop:
roll $5,%ebp
xorl %edi,%eax
addl %esi,%ebp
- andl %ecx,%eax
movl 20(%esp),%esi
- xorl %edi,%eax
+ andl %ecx,%eax
rorl $2,%ecx
+ xorl %edi,%eax
leal 1518500249(%ebp,%esi,1),%ebp
addl %eax,%ebp
# 00_15 6
@@ -156,10 +157,10 @@ L000loop:
roll $5,%ebp
xorl %edx,%esi
addl %edi,%ebp
- andl %ebx,%esi
movl 24(%esp),%edi
- xorl %edx,%esi
+ andl %ebx,%esi
rorl $2,%ebx
+ xorl %edx,%esi
leal 1518500249(%ebp,%edi,1),%ebp
addl %esi,%ebp
# 00_15 7
@@ -169,10 +170,10 @@ L000loop:
roll $5,%ebp
xorl %ecx,%edi
addl %edx,%ebp
- andl %eax,%edi
movl 28(%esp),%edx
- xorl %ecx,%edi
+ andl %eax,%edi
rorl $2,%eax
+ xorl %ecx,%edi
leal 1518500249(%ebp,%edx,1),%ebp
addl %edi,%ebp
# 00_15 8
@@ -182,10 +183,10 @@ L000loop:
roll $5,%ebp
xorl %ebx,%edx
addl %ecx,%ebp
- andl %esi,%edx
movl 32(%esp),%ecx
- xorl %ebx,%edx
+ andl %esi,%edx
rorl $2,%esi
+ xorl %ebx,%edx
leal 1518500249(%ebp,%ecx,1),%ebp
addl %edx,%ebp
# 00_15 9
@@ -195,10 +196,10 @@ L000loop:
roll $5,%ebp
xorl %eax,%ecx
addl %ebx,%ebp
- andl %edi,%ecx
movl 36(%esp),%ebx
- xorl %eax,%ecx
+ andl %edi,%ecx
rorl $2,%edi
+ xorl %eax,%ecx
leal 1518500249(%ebp,%ebx,1),%ebp
addl %ecx,%ebp
# 00_15 10
@@ -208,10 +209,10 @@ L000loop:
roll $5,%ebp
xorl %esi,%ebx
addl %eax,%ebp
- andl %edx,%ebx
movl 40(%esp),%eax
- xorl %esi,%ebx
+ andl %edx,%ebx
rorl $2,%edx
+ xorl %esi,%ebx
leal 1518500249(%ebp,%eax,1),%ebp
addl %ebx,%ebp
# 00_15 11
@@ -221,10 +222,10 @@ L000loop:
roll $5,%ebp
xorl %edi,%eax
addl %esi,%ebp
- andl %ecx,%eax
movl 44(%esp),%esi
- xorl %edi,%eax
+ andl %ecx,%eax
rorl $2,%ecx
+ xorl %edi,%eax
leal 1518500249(%ebp,%esi,1),%ebp
addl %eax,%ebp
# 00_15 12
@@ -234,10 +235,10 @@ L000loop:
roll $5,%ebp
xorl %edx,%esi
addl %edi,%ebp
- andl %ebx,%esi
movl 48(%esp),%edi
- xorl %edx,%esi
+ andl %ebx,%esi
rorl $2,%ebx
+ xorl %edx,%esi
leal 1518500249(%ebp,%edi,1),%ebp
addl %esi,%ebp
# 00_15 13
@@ -247,10 +248,10 @@ L000loop:
roll $5,%ebp
xorl %ecx,%edi
addl %edx,%ebp
- andl %eax,%edi
movl 52(%esp),%edx
- xorl %ecx,%edi
+ andl %eax,%edi
rorl $2,%eax
+ xorl %ecx,%edi
leal 1518500249(%ebp,%edx,1),%ebp
addl %edi,%ebp
# 00_15 14
@@ -260,10 +261,10 @@ L000loop:
roll $5,%ebp
xorl %ebx,%edx
addl %ecx,%ebp
- andl %esi,%edx
movl 56(%esp),%ecx
- xorl %ebx,%edx
+ andl %esi,%edx
rorl $2,%esi
+ xorl %ebx,%edx
leal 1518500249(%ebp,%ecx,1),%ebp
addl %edx,%ebp
# 00_15 15
@@ -273,1226 +274,1163 @@ L000loop:
roll $5,%ebp
xorl %eax,%ecx
addl %ebx,%ebp
- andl %edi,%ecx
movl 60(%esp),%ebx
- xorl %eax,%ecx
+ andl %edi,%ecx
rorl $2,%edi
+ xorl %eax,%ecx
leal 1518500249(%ebp,%ebx,1),%ebp
+ movl (%esp),%ebx
addl %ebp,%ecx
# 16_19 16
- movl (%esp),%ebx
movl %edi,%ebp
xorl 8(%esp),%ebx
xorl %esi,%ebp
xorl 32(%esp),%ebx
andl %edx,%ebp
- rorl $2,%edx
xorl 52(%esp),%ebx
roll $1,%ebx
xorl %esi,%ebp
+ addl %ebp,%eax
+ movl %ecx,%ebp
+ rorl $2,%edx
movl %ebx,(%esp)
+ roll $5,%ebp
leal 1518500249(%ebx,%eax,1),%ebx
- movl %ecx,%eax
- roll $5,%eax
+ movl 4(%esp),%eax
addl %ebp,%ebx
- addl %eax,%ebx
# 16_19 17
- movl 4(%esp),%eax
movl %edx,%ebp
xorl 12(%esp),%eax
xorl %edi,%ebp
xorl 36(%esp),%eax
andl %ecx,%ebp
- rorl $2,%ecx
xorl 56(%esp),%eax
roll $1,%eax
xorl %edi,%ebp
+ addl %ebp,%esi
+ movl %ebx,%ebp
+ rorl $2,%ecx
movl %eax,4(%esp)
+ roll $5,%ebp
leal 1518500249(%eax,%esi,1),%eax
- movl %ebx,%esi
- roll $5,%esi
+ movl 8(%esp),%esi
addl %ebp,%eax
- addl %esi,%eax
# 16_19 18
- movl 8(%esp),%esi
movl %ecx,%ebp
xorl 16(%esp),%esi
xorl %edx,%ebp
xorl 40(%esp),%esi
andl %ebx,%ebp
- rorl $2,%ebx
xorl 60(%esp),%esi
roll $1,%esi
xorl %edx,%ebp
+ addl %ebp,%edi
+ movl %eax,%ebp
+ rorl $2,%ebx
movl %esi,8(%esp)
+ roll $5,%ebp
leal 1518500249(%esi,%edi,1),%esi
- movl %eax,%edi
- roll $5,%edi
+ movl 12(%esp),%edi
addl %ebp,%esi
- addl %edi,%esi
# 16_19 19
- movl 12(%esp),%edi
movl %ebx,%ebp
xorl 20(%esp),%edi
xorl %ecx,%ebp
xorl 44(%esp),%edi
andl %eax,%ebp
- rorl $2,%eax
xorl (%esp),%edi
roll $1,%edi
xorl %ecx,%ebp
+ addl %ebp,%edx
+ movl %esi,%ebp
+ rorl $2,%eax
movl %edi,12(%esp)
+ roll $5,%ebp
leal 1518500249(%edi,%edx,1),%edi
- movl %esi,%edx
- roll $5,%edx
+ movl 16(%esp),%edx
addl %ebp,%edi
- addl %edx,%edi
# 20_39 20
movl %esi,%ebp
- movl 16(%esp),%edx
- rorl $2,%esi
xorl 24(%esp),%edx
xorl %eax,%ebp
xorl 48(%esp),%edx
xorl %ebx,%ebp
xorl 4(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,16(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 1859775393(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl 20(%esp),%ecx
+ addl %ebp,%edx
# 20_39 21
movl %edi,%ebp
- movl 20(%esp),%ecx
- rorl $2,%edi
xorl 28(%esp),%ecx
xorl %esi,%ebp
xorl 52(%esp),%ecx
xorl %eax,%ebp
xorl 8(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,20(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 1859775393(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl 24(%esp),%ebx
+ addl %ebp,%ecx
# 20_39 22
movl %edx,%ebp
- movl 24(%esp),%ebx
- rorl $2,%edx
xorl 32(%esp),%ebx
xorl %edi,%ebp
xorl 56(%esp),%ebx
xorl %esi,%ebp
xorl 12(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,24(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 1859775393(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 1859775393(%ebx,%eax,1),%ebx
+ movl 28(%esp),%eax
+ addl %ebp,%ebx
# 20_39 23
movl %ecx,%ebp
- movl 28(%esp),%eax
- rorl $2,%ecx
xorl 36(%esp),%eax
xorl %edx,%ebp
xorl 60(%esp),%eax
xorl %edi,%ebp
xorl 16(%esp),%eax
roll $1,%eax
- addl %esi,%ebp
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
movl %eax,28(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 1859775393(%eax,%ebp,1),%eax
- addl %esi,%eax
+ leal 1859775393(%eax,%esi,1),%eax
+ movl 32(%esp),%esi
+ addl %ebp,%eax
# 20_39 24
movl %ebx,%ebp
- movl 32(%esp),%esi
- rorl $2,%ebx
xorl 40(%esp),%esi
xorl %ecx,%ebp
xorl (%esp),%esi
xorl %edx,%ebp
xorl 20(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,32(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 1859775393(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 1859775393(%esi,%edi,1),%esi
+ movl 36(%esp),%edi
+ addl %ebp,%esi
# 20_39 25
movl %eax,%ebp
- movl 36(%esp),%edi
- rorl $2,%eax
xorl 44(%esp),%edi
xorl %ebx,%ebp
xorl 4(%esp),%edi
xorl %ecx,%ebp
xorl 24(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,36(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 1859775393(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 1859775393(%edi,%edx,1),%edi
+ movl 40(%esp),%edx
+ addl %ebp,%edi
# 20_39 26
movl %esi,%ebp
- movl 40(%esp),%edx
- rorl $2,%esi
xorl 48(%esp),%edx
xorl %eax,%ebp
xorl 8(%esp),%edx
xorl %ebx,%ebp
xorl 28(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,40(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 1859775393(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl 44(%esp),%ecx
+ addl %ebp,%edx
# 20_39 27
movl %edi,%ebp
- movl 44(%esp),%ecx
- rorl $2,%edi
xorl 52(%esp),%ecx
xorl %esi,%ebp
xorl 12(%esp),%ecx
xorl %eax,%ebp
xorl 32(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,44(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 1859775393(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl 48(%esp),%ebx
+ addl %ebp,%ecx
# 20_39 28
movl %edx,%ebp
- movl 48(%esp),%ebx
- rorl $2,%edx
xorl 56(%esp),%ebx
xorl %edi,%ebp
xorl 16(%esp),%ebx
xorl %esi,%ebp
xorl 36(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,48(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 1859775393(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 1859775393(%ebx,%eax,1),%ebx
+ movl 52(%esp),%eax
+ addl %ebp,%ebx
# 20_39 29
movl %ecx,%ebp
- movl 52(%esp),%eax
- rorl $2,%ecx
xorl 60(%esp),%eax
xorl %edx,%ebp
xorl 20(%esp),%eax
xorl %edi,%ebp
xorl 40(%esp),%eax
roll $1,%eax
- addl %esi,%ebp
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
movl %eax,52(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 1859775393(%eax,%ebp,1),%eax
- addl %esi,%eax
+ leal 1859775393(%eax,%esi,1),%eax
+ movl 56(%esp),%esi
+ addl %ebp,%eax
# 20_39 30
movl %ebx,%ebp
- movl 56(%esp),%esi
- rorl $2,%ebx
xorl (%esp),%esi
xorl %ecx,%ebp
xorl 24(%esp),%esi
xorl %edx,%ebp
xorl 44(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,56(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 1859775393(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 1859775393(%esi,%edi,1),%esi
+ movl 60(%esp),%edi
+ addl %ebp,%esi
# 20_39 31
movl %eax,%ebp
- movl 60(%esp),%edi
- rorl $2,%eax
xorl 4(%esp),%edi
xorl %ebx,%ebp
xorl 28(%esp),%edi
xorl %ecx,%ebp
xorl 48(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,60(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 1859775393(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 1859775393(%edi,%edx,1),%edi
+ movl (%esp),%edx
+ addl %ebp,%edi
# 20_39 32
movl %esi,%ebp
- movl (%esp),%edx
- rorl $2,%esi
xorl 8(%esp),%edx
xorl %eax,%ebp
xorl 32(%esp),%edx
xorl %ebx,%ebp
xorl 52(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 1859775393(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl 4(%esp),%ecx
+ addl %ebp,%edx
# 20_39 33
movl %edi,%ebp
- movl 4(%esp),%ecx
- rorl $2,%edi
xorl 12(%esp),%ecx
xorl %esi,%ebp
xorl 36(%esp),%ecx
xorl %eax,%ebp
xorl 56(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,4(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 1859775393(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl 8(%esp),%ebx
+ addl %ebp,%ecx
# 20_39 34
movl %edx,%ebp
- movl 8(%esp),%ebx
- rorl $2,%edx
xorl 16(%esp),%ebx
xorl %edi,%ebp
xorl 40(%esp),%ebx
xorl %esi,%ebp
xorl 60(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,8(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 1859775393(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 1859775393(%ebx,%eax,1),%ebx
+ movl 12(%esp),%eax
+ addl %ebp,%ebx
# 20_39 35
movl %ecx,%ebp
- movl 12(%esp),%eax
- rorl $2,%ecx
xorl 20(%esp),%eax
xorl %edx,%ebp
xorl 44(%esp),%eax
xorl %edi,%ebp
xorl (%esp),%eax
roll $1,%eax
- addl %esi,%ebp
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
movl %eax,12(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 1859775393(%eax,%ebp,1),%eax
- addl %esi,%eax
+ leal 1859775393(%eax,%esi,1),%eax
+ movl 16(%esp),%esi
+ addl %ebp,%eax
# 20_39 36
movl %ebx,%ebp
- movl 16(%esp),%esi
- rorl $2,%ebx
xorl 24(%esp),%esi
xorl %ecx,%ebp
xorl 48(%esp),%esi
xorl %edx,%ebp
xorl 4(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,16(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 1859775393(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 1859775393(%esi,%edi,1),%esi
+ movl 20(%esp),%edi
+ addl %ebp,%esi
# 20_39 37
movl %eax,%ebp
- movl 20(%esp),%edi
- rorl $2,%eax
xorl 28(%esp),%edi
xorl %ebx,%ebp
xorl 52(%esp),%edi
xorl %ecx,%ebp
xorl 8(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,20(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 1859775393(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 1859775393(%edi,%edx,1),%edi
+ movl 24(%esp),%edx
+ addl %ebp,%edi
# 20_39 38
movl %esi,%ebp
- movl 24(%esp),%edx
- rorl $2,%esi
xorl 32(%esp),%edx
xorl %eax,%ebp
xorl 56(%esp),%edx
xorl %ebx,%ebp
xorl 12(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,24(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 1859775393(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl 28(%esp),%ecx
+ addl %ebp,%edx
# 20_39 39
movl %edi,%ebp
- movl 28(%esp),%ecx
- rorl $2,%edi
xorl 36(%esp),%ecx
xorl %esi,%ebp
xorl 60(%esp),%ecx
xorl %eax,%ebp
xorl 16(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,28(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 1859775393(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl 32(%esp),%ebx
+ addl %ebp,%ecx
# 40_59 40
- movl 32(%esp),%ebx
- movl 40(%esp),%ebp
- xorl %ebp,%ebx
- movl (%esp),%ebp
- xorl %ebp,%ebx
- movl 20(%esp),%ebp
- xorl %ebp,%ebx
- movl %edx,%ebp
+ movl %edi,%ebp
+ xorl 40(%esp),%ebx
+ xorl %esi,%ebp
+ xorl (%esp),%ebx
+ andl %edx,%ebp
+ xorl 20(%esp),%ebx
roll $1,%ebx
- orl %edi,%ebp
- movl %ebx,32(%esp)
- andl %esi,%ebp
- leal 2400959708(%ebx,%eax,1),%ebx
- movl %edx,%eax
+ addl %eax,%ebp
rorl $2,%edx
- andl %edi,%eax
- orl %eax,%ebp
movl %ecx,%eax
roll $5,%eax
- addl %ebp,%ebx
+ movl %ebx,32(%esp)
+ leal 2400959708(%ebx,%ebp,1),%ebx
+ movl %edi,%ebp
addl %eax,%ebx
+ andl %esi,%ebp
+ movl 36(%esp),%eax
+ addl %ebp,%ebx
# 40_59 41
- movl 36(%esp),%eax
- movl 44(%esp),%ebp
- xorl %ebp,%eax
- movl 4(%esp),%ebp
- xorl %ebp,%eax
- movl 24(%esp),%ebp
- xorl %ebp,%eax
- movl %ecx,%ebp
+ movl %edx,%ebp
+ xorl 44(%esp),%eax
+ xorl %edi,%ebp
+ xorl 4(%esp),%eax
+ andl %ecx,%ebp
+ xorl 24(%esp),%eax
roll $1,%eax
- orl %edx,%ebp
- movl %eax,36(%esp)
- andl %edi,%ebp
- leal 2400959708(%eax,%esi,1),%eax
- movl %ecx,%esi
+ addl %esi,%ebp
rorl $2,%ecx
- andl %edx,%esi
- orl %esi,%ebp
movl %ebx,%esi
roll $5,%esi
- addl %ebp,%eax
+ movl %eax,36(%esp)
+ leal 2400959708(%eax,%ebp,1),%eax
+ movl %edx,%ebp
addl %esi,%eax
+ andl %edi,%ebp
+ movl 40(%esp),%esi
+ addl %ebp,%eax
# 40_59 42
- movl 40(%esp),%esi
- movl 48(%esp),%ebp
- xorl %ebp,%esi
- movl 8(%esp),%ebp
- xorl %ebp,%esi
- movl 28(%esp),%ebp
- xorl %ebp,%esi
- movl %ebx,%ebp
+ movl %ecx,%ebp
+ xorl 48(%esp),%esi
+ xorl %edx,%ebp
+ xorl 8(%esp),%esi
+ andl %ebx,%ebp
+ xorl 28(%esp),%esi
roll $1,%esi
- orl %ecx,%ebp
- movl %esi,40(%esp)
- andl %edx,%ebp
- leal 2400959708(%esi,%edi,1),%esi
- movl %ebx,%edi
+ addl %edi,%ebp
rorl $2,%ebx
- andl %ecx,%edi
- orl %edi,%ebp
movl %eax,%edi
roll $5,%edi
- addl %ebp,%esi
+ movl %esi,40(%esp)
+ leal 2400959708(%esi,%ebp,1),%esi
+ movl %ecx,%ebp
addl %edi,%esi
+ andl %edx,%ebp
+ movl 44(%esp),%edi
+ addl %ebp,%esi
# 40_59 43
- movl 44(%esp),%edi
- movl 52(%esp),%ebp
- xorl %ebp,%edi
- movl 12(%esp),%ebp
- xorl %ebp,%edi
- movl 32(%esp),%ebp
- xorl %ebp,%edi
- movl %eax,%ebp
+ movl %ebx,%ebp
+ xorl 52(%esp),%edi
+ xorl %ecx,%ebp
+ xorl 12(%esp),%edi
+ andl %eax,%ebp
+ xorl 32(%esp),%edi
roll $1,%edi
- orl %ebx,%ebp
- movl %edi,44(%esp)
- andl %ecx,%ebp
- leal 2400959708(%edi,%edx,1),%edi
- movl %eax,%edx
+ addl %edx,%ebp
rorl $2,%eax
- andl %ebx,%edx
- orl %edx,%ebp
movl %esi,%edx
roll $5,%edx
- addl %ebp,%edi
+ movl %edi,44(%esp)
+ leal 2400959708(%edi,%ebp,1),%edi
+ movl %ebx,%ebp
addl %edx,%edi
+ andl %ecx,%ebp
+ movl 48(%esp),%edx
+ addl %ebp,%edi
# 40_59 44
- movl 48(%esp),%edx
- movl 56(%esp),%ebp
- xorl %ebp,%edx
- movl 16(%esp),%ebp
- xorl %ebp,%edx
- movl 36(%esp),%ebp
- xorl %ebp,%edx
- movl %esi,%ebp
+ movl %eax,%ebp
+ xorl 56(%esp),%edx
+ xorl %ebx,%ebp
+ xorl 16(%esp),%edx
+ andl %esi,%ebp
+ xorl 36(%esp),%edx
roll $1,%edx
- orl %eax,%ebp
- movl %edx,48(%esp)
- andl %ebx,%ebp
- leal 2400959708(%edx,%ecx,1),%edx
- movl %esi,%ecx
+ addl %ecx,%ebp
rorl $2,%esi
- andl %eax,%ecx
- orl %ecx,%ebp
movl %edi,%ecx
roll $5,%ecx
- addl %ebp,%edx
+ movl %edx,48(%esp)
+ leal 2400959708(%edx,%ebp,1),%edx
+ movl %eax,%ebp
addl %ecx,%edx
+ andl %ebx,%ebp
+ movl 52(%esp),%ecx
+ addl %ebp,%edx
# 40_59 45
- movl 52(%esp),%ecx
- movl 60(%esp),%ebp
- xorl %ebp,%ecx
- movl 20(%esp),%ebp
- xorl %ebp,%ecx
- movl 40(%esp),%ebp
- xorl %ebp,%ecx
- movl %edi,%ebp
+ movl %esi,%ebp
+ xorl 60(%esp),%ecx
+ xorl %eax,%ebp
+ xorl 20(%esp),%ecx
+ andl %edi,%ebp
+ xorl 40(%esp),%ecx
roll $1,%ecx
- orl %esi,%ebp
- movl %ecx,52(%esp)
- andl %eax,%ebp
- leal 2400959708(%ecx,%ebx,1),%ecx
- movl %edi,%ebx
+ addl %ebx,%ebp
rorl $2,%edi
- andl %esi,%ebx
- orl %ebx,%ebp
movl %edx,%ebx
roll $5,%ebx
- addl %ebp,%ecx
+ movl %ecx,52(%esp)
+ leal 2400959708(%ecx,%ebp,1),%ecx
+ movl %esi,%ebp
addl %ebx,%ecx
+ andl %eax,%ebp
+ movl 56(%esp),%ebx
+ addl %ebp,%ecx
# 40_59 46
- movl 56(%esp),%ebx
- movl (%esp),%ebp
- xorl %ebp,%ebx
- movl 24(%esp),%ebp
- xorl %ebp,%ebx
- movl 44(%esp),%ebp
- xorl %ebp,%ebx
- movl %edx,%ebp
+ movl %edi,%ebp
+ xorl (%esp),%ebx
+ xorl %esi,%ebp
+ xorl 24(%esp),%ebx
+ andl %edx,%ebp
+ xorl 44(%esp),%ebx
roll $1,%ebx
- orl %edi,%ebp
- movl %ebx,56(%esp)
- andl %esi,%ebp
- leal 2400959708(%ebx,%eax,1),%ebx
- movl %edx,%eax
+ addl %eax,%ebp
rorl $2,%edx
- andl %edi,%eax
- orl %eax,%ebp
movl %ecx,%eax
roll $5,%eax
- addl %ebp,%ebx
+ movl %ebx,56(%esp)
+ leal 2400959708(%ebx,%ebp,1),%ebx
+ movl %edi,%ebp
addl %eax,%ebx
+ andl %esi,%ebp
+ movl 60(%esp),%eax
+ addl %ebp,%ebx
# 40_59 47
- movl 60(%esp),%eax
- movl 4(%esp),%ebp
- xorl %ebp,%eax
- movl 28(%esp),%ebp
- xorl %ebp,%eax
- movl 48(%esp),%ebp
- xorl %ebp,%eax
- movl %ecx,%ebp
+ movl %edx,%ebp
+ xorl 4(%esp),%eax
+ xorl %edi,%ebp
+ xorl 28(%esp),%eax
+ andl %ecx,%ebp
+ xorl 48(%esp),%eax
roll $1,%eax
- orl %edx,%ebp
- movl %eax,60(%esp)
- andl %edi,%ebp
- leal 2400959708(%eax,%esi,1),%eax
- movl %ecx,%esi
+ addl %esi,%ebp
rorl $2,%ecx
- andl %edx,%esi
- orl %esi,%ebp
movl %ebx,%esi
roll $5,%esi
- addl %ebp,%eax
+ movl %eax,60(%esp)
+ leal 2400959708(%eax,%ebp,1),%eax
+ movl %edx,%ebp
addl %esi,%eax
+ andl %edi,%ebp
+ movl (%esp),%esi
+ addl %ebp,%eax
# 40_59 48
- movl (%esp),%esi
- movl 8(%esp),%ebp
- xorl %ebp,%esi
- movl 32(%esp),%ebp
- xorl %ebp,%esi
- movl 52(%esp),%ebp
- xorl %ebp,%esi
- movl %ebx,%ebp
+ movl %ecx,%ebp
+ xorl 8(%esp),%esi
+ xorl %edx,%ebp
+ xorl 32(%esp),%esi
+ andl %ebx,%ebp
+ xorl 52(%esp),%esi
roll $1,%esi
- orl %ecx,%ebp
- movl %esi,(%esp)
- andl %edx,%ebp
- leal 2400959708(%esi,%edi,1),%esi
- movl %ebx,%edi
+ addl %edi,%ebp
rorl $2,%ebx
- andl %ecx,%edi
- orl %edi,%ebp
movl %eax,%edi
roll $5,%edi
- addl %ebp,%esi
+ movl %esi,(%esp)
+ leal 2400959708(%esi,%ebp,1),%esi
+ movl %ecx,%ebp
addl %edi,%esi
+ andl %edx,%ebp
+ movl 4(%esp),%edi
+ addl %ebp,%esi
# 40_59 49
- movl 4(%esp),%edi
- movl 12(%esp),%ebp
- xorl %ebp,%edi
- movl 36(%esp),%ebp
- xorl %ebp,%edi
- movl 56(%esp),%ebp
- xorl %ebp,%edi
- movl %eax,%ebp
+ movl %ebx,%ebp
+ xorl 12(%esp),%edi
+ xorl %ecx,%ebp
+ xorl 36(%esp),%edi
+ andl %eax,%ebp
+ xorl 56(%esp),%edi
roll $1,%edi
- orl %ebx,%ebp
- movl %edi,4(%esp)
- andl %ecx,%ebp
- leal 2400959708(%edi,%edx,1),%edi
- movl %eax,%edx
+ addl %edx,%ebp
rorl $2,%eax
- andl %ebx,%edx
- orl %edx,%ebp
movl %esi,%edx
roll $5,%edx
- addl %ebp,%edi
+ movl %edi,4(%esp)
+ leal 2400959708(%edi,%ebp,1),%edi
+ movl %ebx,%ebp
addl %edx,%edi
+ andl %ecx,%ebp
+ movl 8(%esp),%edx
+ addl %ebp,%edi
# 40_59 50
- movl 8(%esp),%edx
- movl 16(%esp),%ebp
- xorl %ebp,%edx
- movl 40(%esp),%ebp
- xorl %ebp,%edx
- movl 60(%esp),%ebp
- xorl %ebp,%edx
- movl %esi,%ebp
+ movl %eax,%ebp
+ xorl 16(%esp),%edx
+ xorl %ebx,%ebp
+ xorl 40(%esp),%edx
+ andl %esi,%ebp
+ xorl 60(%esp),%edx
roll $1,%edx
- orl %eax,%ebp
- movl %edx,8(%esp)
- andl %ebx,%ebp
- leal 2400959708(%edx,%ecx,1),%edx
- movl %esi,%ecx
+ addl %ecx,%ebp
rorl $2,%esi
- andl %eax,%ecx
- orl %ecx,%ebp
movl %edi,%ecx
roll $5,%ecx
- addl %ebp,%edx
+ movl %edx,8(%esp)
+ leal 2400959708(%edx,%ebp,1),%edx
+ movl %eax,%ebp
addl %ecx,%edx
+ andl %ebx,%ebp
+ movl 12(%esp),%ecx
+ addl %ebp,%edx
# 40_59 51
- movl 12(%esp),%ecx
- movl 20(%esp),%ebp
- xorl %ebp,%ecx
- movl 44(%esp),%ebp
- xorl %ebp,%ecx
- movl (%esp),%ebp
- xorl %ebp,%ecx
- movl %edi,%ebp
+ movl %esi,%ebp
+ xorl 20(%esp),%ecx
+ xorl %eax,%ebp
+ xorl 44(%esp),%ecx
+ andl %edi,%ebp
+ xorl (%esp),%ecx
roll $1,%ecx
- orl %esi,%ebp
- movl %ecx,12(%esp)
- andl %eax,%ebp
- leal 2400959708(%ecx,%ebx,1),%ecx
- movl %edi,%ebx
+ addl %ebx,%ebp
rorl $2,%edi
- andl %esi,%ebx
- orl %ebx,%ebp
movl %edx,%ebx
roll $5,%ebx
- addl %ebp,%ecx
+ movl %ecx,12(%esp)
+ leal 2400959708(%ecx,%ebp,1),%ecx
+ movl %esi,%ebp
addl %ebx,%ecx
+ andl %eax,%ebp
+ movl 16(%esp),%ebx
+ addl %ebp,%ecx
# 40_59 52
- movl 16(%esp),%ebx
- movl 24(%esp),%ebp
- xorl %ebp,%ebx
- movl 48(%esp),%ebp
- xorl %ebp,%ebx
- movl 4(%esp),%ebp
- xorl %ebp,%ebx
- movl %edx,%ebp
+ movl %edi,%ebp
+ xorl 24(%esp),%ebx
+ xorl %esi,%ebp
+ xorl 48(%esp),%ebx
+ andl %edx,%ebp
+ xorl 4(%esp),%ebx
roll $1,%ebx
- orl %edi,%ebp
- movl %ebx,16(%esp)
- andl %esi,%ebp
- leal 2400959708(%ebx,%eax,1),%ebx
- movl %edx,%eax
+ addl %eax,%ebp
rorl $2,%edx
- andl %edi,%eax
- orl %eax,%ebp
movl %ecx,%eax
roll $5,%eax
- addl %ebp,%ebx
+ movl %ebx,16(%esp)
+ leal 2400959708(%ebx,%ebp,1),%ebx
+ movl %edi,%ebp
addl %eax,%ebx
+ andl %esi,%ebp
+ movl 20(%esp),%eax
+ addl %ebp,%ebx
# 40_59 53
- movl 20(%esp),%eax
- movl 28(%esp),%ebp
- xorl %ebp,%eax
- movl 52(%esp),%ebp
- xorl %ebp,%eax
- movl 8(%esp),%ebp
- xorl %ebp,%eax
- movl %ecx,%ebp
+ movl %edx,%ebp
+ xorl 28(%esp),%eax
+ xorl %edi,%ebp
+ xorl 52(%esp),%eax
+ andl %ecx,%ebp
+ xorl 8(%esp),%eax
roll $1,%eax
- orl %edx,%ebp
- movl %eax,20(%esp)
- andl %edi,%ebp
- leal 2400959708(%eax,%esi,1),%eax
- movl %ecx,%esi
+ addl %esi,%ebp
rorl $2,%ecx
- andl %edx,%esi
- orl %esi,%ebp
movl %ebx,%esi
roll $5,%esi
- addl %ebp,%eax
+ movl %eax,20(%esp)
+ leal 2400959708(%eax,%ebp,1),%eax
+ movl %edx,%ebp
addl %esi,%eax
+ andl %edi,%ebp
+ movl 24(%esp),%esi
+ addl %ebp,%eax
# 40_59 54
- movl 24(%esp),%esi
- movl 32(%esp),%ebp
- xorl %ebp,%esi
- movl 56(%esp),%ebp
- xorl %ebp,%esi
- movl 12(%esp),%ebp
- xorl %ebp,%esi
- movl %ebx,%ebp
+ movl %ecx,%ebp
+ xorl 32(%esp),%esi
+ xorl %edx,%ebp
+ xorl 56(%esp),%esi
+ andl %ebx,%ebp
+ xorl 12(%esp),%esi
roll $1,%esi
- orl %ecx,%ebp
- movl %esi,24(%esp)
- andl %edx,%ebp
- leal 2400959708(%esi,%edi,1),%esi
- movl %ebx,%edi
+ addl %edi,%ebp
rorl $2,%ebx
- andl %ecx,%edi
- orl %edi,%ebp
movl %eax,%edi
roll $5,%edi
- addl %ebp,%esi
+ movl %esi,24(%esp)
+ leal 2400959708(%esi,%ebp,1),%esi
+ movl %ecx,%ebp
addl %edi,%esi
+ andl %edx,%ebp
+ movl 28(%esp),%edi
+ addl %ebp,%esi
# 40_59 55
- movl 28(%esp),%edi
- movl 36(%esp),%ebp
- xorl %ebp,%edi
- movl 60(%esp),%ebp
- xorl %ebp,%edi
- movl 16(%esp),%ebp
- xorl %ebp,%edi
- movl %eax,%ebp
+ movl %ebx,%ebp
+ xorl 36(%esp),%edi
+ xorl %ecx,%ebp
+ xorl 60(%esp),%edi
+ andl %eax,%ebp
+ xorl 16(%esp),%edi
roll $1,%edi
- orl %ebx,%ebp
- movl %edi,28(%esp)
- andl %ecx,%ebp
- leal 2400959708(%edi,%edx,1),%edi
- movl %eax,%edx
+ addl %edx,%ebp
rorl $2,%eax
- andl %ebx,%edx
- orl %edx,%ebp
movl %esi,%edx
roll $5,%edx
- addl %ebp,%edi
+ movl %edi,28(%esp)
+ leal 2400959708(%edi,%ebp,1),%edi
+ movl %ebx,%ebp
addl %edx,%edi
+ andl %ecx,%ebp
+ movl 32(%esp),%edx
+ addl %ebp,%edi
# 40_59 56
- movl 32(%esp),%edx
- movl 40(%esp),%ebp
- xorl %ebp,%edx
- movl (%esp),%ebp
- xorl %ebp,%edx
- movl 20(%esp),%ebp
- xorl %ebp,%edx
- movl %esi,%ebp
+ movl %eax,%ebp
+ xorl 40(%esp),%edx
+ xorl %ebx,%ebp
+ xorl (%esp),%edx
+ andl %esi,%ebp
+ xorl 20(%esp),%edx
roll $1,%edx
- orl %eax,%ebp
- movl %edx,32(%esp)
- andl %ebx,%ebp
- leal 2400959708(%edx,%ecx,1),%edx
- movl %esi,%ecx
+ addl %ecx,%ebp
rorl $2,%esi
- andl %eax,%ecx
- orl %ecx,%ebp
movl %edi,%ecx
roll $5,%ecx
- addl %ebp,%edx
+ movl %edx,32(%esp)
+ leal 2400959708(%edx,%ebp,1),%edx
+ movl %eax,%ebp
addl %ecx,%edx
+ andl %ebx,%ebp
+ movl 36(%esp),%ecx
+ addl %ebp,%edx
# 40_59 57
- movl 36(%esp),%ecx
- movl 44(%esp),%ebp
- xorl %ebp,%ecx
- movl 4(%esp),%ebp
- xorl %ebp,%ecx
- movl 24(%esp),%ebp
- xorl %ebp,%ecx
- movl %edi,%ebp
+ movl %esi,%ebp
+ xorl 44(%esp),%ecx
+ xorl %eax,%ebp
+ xorl 4(%esp),%ecx
+ andl %edi,%ebp
+ xorl 24(%esp),%ecx
roll $1,%ecx
- orl %esi,%ebp
- movl %ecx,36(%esp)
- andl %eax,%ebp
- leal 2400959708(%ecx,%ebx,1),%ecx
- movl %edi,%ebx
+ addl %ebx,%ebp
rorl $2,%edi
- andl %esi,%ebx
- orl %ebx,%ebp
movl %edx,%ebx
roll $5,%ebx
- addl %ebp,%ecx
+ movl %ecx,36(%esp)
+ leal 2400959708(%ecx,%ebp,1),%ecx
+ movl %esi,%ebp
addl %ebx,%ecx
+ andl %eax,%ebp
+ movl 40(%esp),%ebx
+ addl %ebp,%ecx
# 40_59 58
- movl 40(%esp),%ebx
- movl 48(%esp),%ebp
- xorl %ebp,%ebx
- movl 8(%esp),%ebp
- xorl %ebp,%ebx
- movl 28(%esp),%ebp
- xorl %ebp,%ebx
- movl %edx,%ebp
+ movl %edi,%ebp
+ xorl 48(%esp),%ebx
+ xorl %esi,%ebp
+ xorl 8(%esp),%ebx
+ andl %edx,%ebp
+ xorl 28(%esp),%ebx
roll $1,%ebx
- orl %edi,%ebp
- movl %ebx,40(%esp)
- andl %esi,%ebp
- leal 2400959708(%ebx,%eax,1),%ebx
- movl %edx,%eax
+ addl %eax,%ebp
rorl $2,%edx
- andl %edi,%eax
- orl %eax,%ebp
movl %ecx,%eax
roll $5,%eax
- addl %ebp,%ebx
+ movl %ebx,40(%esp)
+ leal 2400959708(%ebx,%ebp,1),%ebx
+ movl %edi,%ebp
addl %eax,%ebx
+ andl %esi,%ebp
+ movl 44(%esp),%eax
+ addl %ebp,%ebx
# 40_59 59
- movl 44(%esp),%eax
- movl 52(%esp),%ebp
- xorl %ebp,%eax
- movl 12(%esp),%ebp
- xorl %ebp,%eax
- movl 32(%esp),%ebp
- xorl %ebp,%eax
- movl %ecx,%ebp
+ movl %edx,%ebp
+ xorl 52(%esp),%eax
+ xorl %edi,%ebp
+ xorl 12(%esp),%eax
+ andl %ecx,%ebp
+ xorl 32(%esp),%eax
roll $1,%eax
- orl %edx,%ebp
- movl %eax,44(%esp)
- andl %edi,%ebp
- leal 2400959708(%eax,%esi,1),%eax
- movl %ecx,%esi
+ addl %esi,%ebp
rorl $2,%ecx
- andl %edx,%esi
- orl %esi,%ebp
movl %ebx,%esi
roll $5,%esi
- addl %ebp,%eax
+ movl %eax,44(%esp)
+ leal 2400959708(%eax,%ebp,1),%eax
+ movl %edx,%ebp
addl %esi,%eax
+ andl %edi,%ebp
+ movl 48(%esp),%esi
+ addl %ebp,%eax
# 20_39 60
movl %ebx,%ebp
- movl 48(%esp),%esi
- rorl $2,%ebx
xorl 56(%esp),%esi
xorl %ecx,%ebp
xorl 16(%esp),%esi
xorl %edx,%ebp
xorl 36(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,48(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 3395469782(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 3395469782(%esi,%edi,1),%esi
+ movl 52(%esp),%edi
+ addl %ebp,%esi
# 20_39 61
movl %eax,%ebp
- movl 52(%esp),%edi
- rorl $2,%eax
xorl 60(%esp),%edi
xorl %ebx,%ebp
xorl 20(%esp),%edi
xorl %ecx,%ebp
xorl 40(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,52(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 3395469782(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 3395469782(%edi,%edx,1),%edi
+ movl 56(%esp),%edx
+ addl %ebp,%edi
# 20_39 62
movl %esi,%ebp
- movl 56(%esp),%edx
- rorl $2,%esi
xorl (%esp),%edx
xorl %eax,%ebp
xorl 24(%esp),%edx
xorl %ebx,%ebp
xorl 44(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,56(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 3395469782(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 3395469782(%edx,%ecx,1),%edx
+ movl 60(%esp),%ecx
+ addl %ebp,%edx
# 20_39 63
movl %edi,%ebp
- movl 60(%esp),%ecx
- rorl $2,%edi
xorl 4(%esp),%ecx
xorl %esi,%ebp
xorl 28(%esp),%ecx
xorl %eax,%ebp
xorl 48(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,60(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 3395469782(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 3395469782(%ecx,%ebx,1),%ecx
+ movl (%esp),%ebx
+ addl %ebp,%ecx
# 20_39 64
movl %edx,%ebp
- movl (%esp),%ebx
- rorl $2,%edx
xorl 8(%esp),%ebx
xorl %edi,%ebp
xorl 32(%esp),%ebx
xorl %esi,%ebp
xorl 52(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 3395469782(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 3395469782(%ebx,%eax,1),%ebx
+ movl 4(%esp),%eax
+ addl %ebp,%ebx
# 20_39 65
movl %ecx,%ebp
- movl 4(%esp),%eax
- rorl $2,%ecx
xorl 12(%esp),%eax
xorl %edx,%ebp
xorl 36(%esp),%eax
xorl %edi,%ebp
xorl 56(%esp),%eax
roll $1,%eax
- addl %esi,%ebp
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
movl %eax,4(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 3395469782(%eax,%ebp,1),%eax
- addl %esi,%eax
+ leal 3395469782(%eax,%esi,1),%eax
+ movl 8(%esp),%esi
+ addl %ebp,%eax
# 20_39 66
movl %ebx,%ebp
- movl 8(%esp),%esi
- rorl $2,%ebx
xorl 16(%esp),%esi
xorl %ecx,%ebp
xorl 40(%esp),%esi
xorl %edx,%ebp
xorl 60(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,8(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 3395469782(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 3395469782(%esi,%edi,1),%esi
+ movl 12(%esp),%edi
+ addl %ebp,%esi
# 20_39 67
movl %eax,%ebp
- movl 12(%esp),%edi
- rorl $2,%eax
xorl 20(%esp),%edi
xorl %ebx,%ebp
xorl 44(%esp),%edi
xorl %ecx,%ebp
xorl (%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,12(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 3395469782(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 3395469782(%edi,%edx,1),%edi
+ movl 16(%esp),%edx
+ addl %ebp,%edi
# 20_39 68
movl %esi,%ebp
- movl 16(%esp),%edx
- rorl $2,%esi
xorl 24(%esp),%edx
xorl %eax,%ebp
xorl 48(%esp),%edx
xorl %ebx,%ebp
xorl 4(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,16(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 3395469782(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 3395469782(%edx,%ecx,1),%edx
+ movl 20(%esp),%ecx
+ addl %ebp,%edx
# 20_39 69
movl %edi,%ebp
- movl 20(%esp),%ecx
- rorl $2,%edi
xorl 28(%esp),%ecx
xorl %esi,%ebp
xorl 52(%esp),%ecx
xorl %eax,%ebp
xorl 8(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,20(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 3395469782(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 3395469782(%ecx,%ebx,1),%ecx
+ movl 24(%esp),%ebx
+ addl %ebp,%ecx
# 20_39 70
movl %edx,%ebp
- movl 24(%esp),%ebx
- rorl $2,%edx
xorl 32(%esp),%ebx
xorl %edi,%ebp
xorl 56(%esp),%ebx
xorl %esi,%ebp
xorl 12(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,24(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 3395469782(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 3395469782(%ebx,%eax,1),%ebx
+ movl 28(%esp),%eax
+ addl %ebp,%ebx
# 20_39 71
movl %ecx,%ebp
- movl 28(%esp),%eax
- rorl $2,%ecx
xorl 36(%esp),%eax
xorl %edx,%ebp
xorl 60(%esp),%eax
xorl %edi,%ebp
xorl 16(%esp),%eax
roll $1,%eax
- addl %esi,%ebp
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
movl %eax,28(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 3395469782(%eax,%ebp,1),%eax
- addl %esi,%eax
+ leal 3395469782(%eax,%esi,1),%eax
+ movl 32(%esp),%esi
+ addl %ebp,%eax
# 20_39 72
movl %ebx,%ebp
- movl 32(%esp),%esi
- rorl $2,%ebx
xorl 40(%esp),%esi
xorl %ecx,%ebp
xorl (%esp),%esi
xorl %edx,%ebp
xorl 20(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
movl %esi,32(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 3395469782(%esi,%ebp,1),%esi
- addl %edi,%esi
+ leal 3395469782(%esi,%edi,1),%esi
+ movl 36(%esp),%edi
+ addl %ebp,%esi
# 20_39 73
movl %eax,%ebp
- movl 36(%esp),%edi
- rorl $2,%eax
xorl 44(%esp),%edi
xorl %ebx,%ebp
xorl 4(%esp),%edi
xorl %ecx,%ebp
xorl 24(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
movl %edi,36(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 3395469782(%edi,%ebp,1),%edi
- addl %edx,%edi
+ leal 3395469782(%edi,%edx,1),%edi
+ movl 40(%esp),%edx
+ addl %ebp,%edi
# 20_39 74
movl %esi,%ebp
- movl 40(%esp),%edx
- rorl $2,%esi
xorl 48(%esp),%edx
xorl %eax,%ebp
xorl 8(%esp),%edx
xorl %ebx,%ebp
xorl 28(%esp),%edx
roll $1,%edx
- addl %ecx,%ebp
+ addl %ebp,%ecx
+ rorl $2,%esi
+ movl %edi,%ebp
+ roll $5,%ebp
movl %edx,40(%esp)
- movl %edi,%ecx
- roll $5,%ecx
- leal 3395469782(%edx,%ebp,1),%edx
- addl %ecx,%edx
+ leal 3395469782(%edx,%ecx,1),%edx
+ movl 44(%esp),%ecx
+ addl %ebp,%edx
# 20_39 75
movl %edi,%ebp
- movl 44(%esp),%ecx
- rorl $2,%edi
xorl 52(%esp),%ecx
xorl %esi,%ebp
xorl 12(%esp),%ecx
xorl %eax,%ebp
xorl 32(%esp),%ecx
roll $1,%ecx
- addl %ebx,%ebp
+ addl %ebp,%ebx
+ rorl $2,%edi
+ movl %edx,%ebp
+ roll $5,%ebp
movl %ecx,44(%esp)
- movl %edx,%ebx
- roll $5,%ebx
- leal 3395469782(%ecx,%ebp,1),%ecx
- addl %ebx,%ecx
+ leal 3395469782(%ecx,%ebx,1),%ecx
+ movl 48(%esp),%ebx
+ addl %ebp,%ecx
# 20_39 76
movl %edx,%ebp
- movl 48(%esp),%ebx
- rorl $2,%edx
xorl 56(%esp),%ebx
xorl %edi,%ebp
xorl 16(%esp),%ebx
xorl %esi,%ebp
xorl 36(%esp),%ebx
roll $1,%ebx
- addl %eax,%ebp
+ addl %ebp,%eax
+ rorl $2,%edx
+ movl %ecx,%ebp
+ roll $5,%ebp
movl %ebx,48(%esp)
- movl %ecx,%eax
- roll $5,%eax
- leal 3395469782(%ebx,%ebp,1),%ebx
- addl %eax,%ebx
+ leal 3395469782(%ebx,%eax,1),%ebx
+ movl 52(%esp),%eax
+ addl %ebp,%ebx
# 20_39 77
movl %ecx,%ebp
- movl 52(%esp),%eax
- rorl $2,%ecx
xorl 60(%esp),%eax
xorl %edx,%ebp
xorl 20(%esp),%eax
xorl %edi,%ebp
xorl 40(%esp),%eax
roll $1,%eax
- addl %esi,%ebp
- movl %eax,52(%esp)
- movl %ebx,%esi
- roll $5,%esi
- leal 3395469782(%eax,%ebp,1),%eax
- addl %esi,%eax
+ addl %ebp,%esi
+ rorl $2,%ecx
+ movl %ebx,%ebp
+ roll $5,%ebp
+ leal 3395469782(%eax,%esi,1),%eax
+ movl 56(%esp),%esi
+ addl %ebp,%eax
# 20_39 78
movl %ebx,%ebp
- movl 56(%esp),%esi
- rorl $2,%ebx
xorl (%esp),%esi
xorl %ecx,%ebp
xorl 24(%esp),%esi
xorl %edx,%ebp
xorl 44(%esp),%esi
roll $1,%esi
- addl %edi,%ebp
- movl %esi,56(%esp)
- movl %eax,%edi
- roll $5,%edi
- leal 3395469782(%esi,%ebp,1),%esi
- addl %edi,%esi
+ addl %ebp,%edi
+ rorl $2,%ebx
+ movl %eax,%ebp
+ roll $5,%ebp
+ leal 3395469782(%esi,%edi,1),%esi
+ movl 60(%esp),%edi
+ addl %ebp,%esi
# 20_39 79
movl %eax,%ebp
- movl 60(%esp),%edi
- rorl $2,%eax
xorl 4(%esp),%edi
xorl %ebx,%ebp
xorl 28(%esp),%edi
xorl %ecx,%ebp
xorl 48(%esp),%edi
roll $1,%edi
- addl %edx,%ebp
- movl %edi,60(%esp)
- movl %esi,%edx
- roll $5,%edx
- leal 3395469782(%edi,%ebp,1),%edi
- addl %edx,%edi
- movl 84(%esp),%ebp
- movl 88(%esp),%edx
+ addl %ebp,%edx
+ rorl $2,%eax
+ movl %esi,%ebp
+ roll $5,%ebp
+ leal 3395469782(%edi,%edx,1),%edi
+ addl %ebp,%edi
+ movl 96(%esp),%ebp
+ movl 100(%esp),%edx
addl (%ebp),%edi
addl 4(%ebp),%esi
addl 8(%ebp),%eax
@@ -1501,14 +1439,14 @@ L000loop:
movl %edi,(%ebp)
addl $64,%edx
movl %esi,4(%ebp)
- cmpl 92(%esp),%edx
+ cmpl 104(%esp),%edx
movl %eax,8(%ebp)
movl %ecx,%edi
movl %ebx,12(%ebp)
movl %edx,%esi
movl %ecx,16(%ebp)
jb L000loop
- addl $64,%esp
+ addl $76,%esp
popl %edi
popl %esi
popl %ebx
diff --git a/deps/openssl/asm/x86-macosx-gas/sha/sha256-586.s b/deps/openssl/asm/x86-macosx-gas/sha/sha256-586.s
index 1190be750..67c7a96bc 100644
--- a/deps/openssl/asm/x86-macosx-gas/sha/sha256-586.s
+++ b/deps/openssl/asm/x86-macosx-gas/sha/sha256-586.s
@@ -95,31 +95,30 @@ L002loop:
L00300_15:
movl 92(%esp),%ebx
movl %edx,%ecx
- rorl $6,%ecx
- movl %edx,%edi
- rorl $11,%edi
+ rorl $14,%ecx
movl 20(%esp),%esi
- xorl %edi,%ecx
- rorl $14,%edi
- xorl %edi,%ecx
+ xorl %edx,%ecx
+ rorl $5,%ecx
+ xorl %edx,%ecx
+ rorl $6,%ecx
movl 24(%esp),%edi
addl %ecx,%ebx
- movl %edx,16(%esp)
xorl %edi,%esi
+ movl %edx,16(%esp)
movl %eax,%ecx
andl %edx,%esi
movl 12(%esp),%edx
xorl %edi,%esi
movl %eax,%edi
addl %esi,%ebx
- rorl $2,%ecx
+ rorl $9,%ecx
addl 28(%esp),%ebx
- rorl $13,%edi
+ xorl %eax,%ecx
+ rorl $11,%ecx
movl 4(%esp),%esi
- xorl %edi,%ecx
- rorl $9,%edi
+ xorl %eax,%ecx
+ rorl $2,%ecx
addl %ebx,%edx
- xorl %edi,%ecx
movl 8(%esp),%edi
addl %ecx,%ebx
movl %eax,(%esp)
@@ -141,48 +140,46 @@ L00300_15:
L00416_63:
movl %ebx,%esi
movl 100(%esp),%ecx
- shrl $3,%ebx
- rorl $7,%esi
- xorl %esi,%ebx
rorl $11,%esi
movl %ecx,%edi
+ xorl %ebx,%esi
+ rorl $7,%esi
+ shrl $3,%ebx
+ rorl $2,%edi
xorl %esi,%ebx
- shrl $10,%ecx
- movl 156(%esp),%esi
+ xorl %ecx,%edi
rorl $17,%edi
- xorl %edi,%ecx
- rorl $2,%edi
- addl %esi,%ebx
+ shrl $10,%ecx
+ addl 156(%esp),%ebx
xorl %ecx,%edi
- addl %edi,%ebx
- movl %edx,%ecx
addl 120(%esp),%ebx
- rorl $6,%ecx
- movl %edx,%edi
- rorl $11,%edi
+ movl %edx,%ecx
+ addl %edi,%ebx
+ rorl $14,%ecx
movl 20(%esp),%esi
- xorl %edi,%ecx
- rorl $14,%edi
+ xorl %edx,%ecx
+ rorl $5,%ecx
movl %ebx,92(%esp)
- xorl %edi,%ecx
+ xorl %edx,%ecx
+ rorl $6,%ecx
movl 24(%esp),%edi
addl %ecx,%ebx
- movl %edx,16(%esp)
xorl %edi,%esi
+ movl %edx,16(%esp)
movl %eax,%ecx
andl %edx,%esi
movl 12(%esp),%edx
xorl %edi,%esi
movl %eax,%edi
addl %esi,%ebx
- rorl $2,%ecx
+ rorl $9,%ecx
addl 28(%esp),%ebx
- rorl $13,%edi
+ xorl %eax,%ecx
+ rorl $11,%ecx
movl 4(%esp),%esi
- xorl %edi,%ecx
- rorl $9,%edi
+ xorl %eax,%ecx
+ rorl $2,%ecx
addl %ebx,%edx
- xorl %edi,%ecx
movl 8(%esp),%edi
addl %ecx,%ebx
movl %eax,(%esp)
diff --git a/deps/openssl/asm/x86-macosx-gas/x86cpuid.s b/deps/openssl/asm/x86-macosx-gas/x86cpuid.s
index b5e80f83a..db36e6f50 100644
--- a/deps/openssl/asm/x86-macosx-gas/x86cpuid.s
+++ b/deps/openssl/asm/x86-macosx-gas/x86cpuid.s
@@ -18,9 +18,9 @@ L_OPENSSL_ia32_cpuid_begin:
pushfl
popl %eax
xorl %eax,%ecx
- btl $21,%ecx
- jnc L000done
xorl %eax,%eax
+ btl $21,%ecx
+ jnc L000nocpuid
.byte 0x0f,0xa2
movl %eax,%edi
xorl %eax,%eax
@@ -46,7 +46,14 @@ L_OPENSSL_ia32_cpuid_begin:
jnz L001intel
movl $2147483648,%eax
.byte 0x0f,0xa2
- cmpl $2147483656,%eax
+ cmpl $2147483649,%eax
+ jb L001intel
+ movl %eax,%esi
+ movl $2147483649,%eax
+ .byte 0x0f,0xa2
+ orl %ecx,%ebp
+ andl $2049,%ebp
+ cmpl $2147483656,%esi
jb L001intel
movl $2147483656,%eax
.byte 0x0f,0xa2
@@ -55,46 +62,68 @@ L_OPENSSL_ia32_cpuid_begin:
movl $1,%eax
.byte 0x0f,0xa2
btl $28,%edx
- jnc L000done
+ jnc L002generic
shrl $16,%ebx
andl $255,%ebx
cmpl %esi,%ebx
- ja L000done
+ ja L002generic
andl $4026531839,%edx
- jmp L000done
+ jmp L002generic
L001intel:
cmpl $4,%edi
movl $-1,%edi
- jb L002nocacheinfo
+ jb L003nocacheinfo
movl $4,%eax
movl $0,%ecx
.byte 0x0f,0xa2
movl %eax,%edi
shrl $14,%edi
andl $4095,%edi
-L002nocacheinfo:
+L003nocacheinfo:
movl $1,%eax
.byte 0x0f,0xa2
+ andl $3220176895,%edx
cmpl $0,%ebp
- jne L003notP4
+ jne L004notintel
+ orl $1073741824,%edx
andb $15,%ah
cmpb $15,%ah
- jne L003notP4
+ jne L004notintel
orl $1048576,%edx
-L003notP4:
+L004notintel:
btl $28,%edx
- jnc L000done
+ jnc L002generic
andl $4026531839,%edx
cmpl $0,%edi
- je L000done
+ je L002generic
orl $268435456,%edx
shrl $16,%ebx
cmpb $1,%bl
- ja L000done
+ ja L002generic
andl $4026531839,%edx
-L000done:
- movl %edx,%eax
- movl %ecx,%edx
+L002generic:
+ andl $2048,%ebp
+ andl $4294965247,%ecx
+ movl %edx,%esi
+ orl %ecx,%ebp
+ btl $27,%ecx
+ jnc L005clear_avx
+ xorl %ecx,%ecx
+.byte 15,1,208
+ andl $6,%eax
+ cmpl $6,%eax
+ je L006done
+ cmpl $2,%eax
+ je L005clear_avx
+L007clear_xmm:
+ andl $4261412861,%ebp
+ andl $4278190079,%esi
+L005clear_avx:
+ andl $4026525695,%ebp
+L006done:
+ movl %esi,%eax
+ movl %ebp,%edx
+L000nocpuid:
popl %edi
popl %esi
popl %ebx
@@ -106,26 +135,32 @@ _OPENSSL_rdtsc:
L_OPENSSL_rdtsc_begin:
xorl %eax,%eax
xorl %edx,%edx
- leal _OPENSSL_ia32cap_P,%ecx
+ call L008PIC_me_up
+L008PIC_me_up:
+ popl %ecx
+ movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L008PIC_me_up(%ecx),%ecx
btl $4,(%ecx)
- jnc L004notsc
+ jnc L009notsc
.byte 0x0f,0x31
-L004notsc:
+L009notsc:
ret
.globl _OPENSSL_instrument_halt
.align 4
_OPENSSL_instrument_halt:
L_OPENSSL_instrument_halt_begin:
- leal _OPENSSL_ia32cap_P,%ecx
+ call L010PIC_me_up
+L010PIC_me_up:
+ popl %ecx
+ movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L010PIC_me_up(%ecx),%ecx
btl $4,(%ecx)
- jnc L005nohalt
+ jnc L011nohalt
.long 2421723150
andl $3,%eax
- jnz L005nohalt
+ jnz L011nohalt
pushfl
popl %eax
btl $9,%eax
- jnc L005nohalt
+ jnc L011nohalt
.byte 0x0f,0x31
pushl %edx
pushl %eax
@@ -135,7 +170,7 @@ L_OPENSSL_instrument_halt_begin:
sbbl 4(%esp),%edx
addl $8,%esp
ret
-L005nohalt:
+L011nohalt:
xorl %eax,%eax
xorl %edx,%edx
ret
@@ -146,21 +181,21 @@ L_OPENSSL_far_spin_begin:
pushfl
popl %eax
btl $9,%eax
- jnc L006nospin
+ jnc L012nospin
movl 4(%esp),%eax
movl 8(%esp),%ecx
.long 2430111262
xorl %eax,%eax
movl (%ecx),%edx
- jmp L007spin
+ jmp L013spin
.align 4,0x90
-L007spin:
+L013spin:
incl %eax
cmpl (%ecx),%edx
- je L007spin
+ je L013spin
.long 529567888
ret
-L006nospin:
+L012nospin:
xorl %eax,%eax
xorl %edx,%edx
ret
@@ -170,12 +205,15 @@ _OPENSSL_wipe_cpu:
L_OPENSSL_wipe_cpu_begin:
xorl %eax,%eax
xorl %edx,%edx
- leal _OPENSSL_ia32cap_P,%ecx
+ call L014PIC_me_up
+L014PIC_me_up:
+ popl %ecx
+ movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L014PIC_me_up(%ecx),%ecx
movl (%ecx),%ecx
btl $1,(%ecx)
- jnc L008no_x87
+ jnc L015no_x87
.long 4007259865,4007259865,4007259865,4007259865,2430851995
-L008no_x87:
+L015no_x87:
leal 4(%esp),%eax
ret
.globl _OPENSSL_atomic_add
@@ -187,11 +225,11 @@ L_OPENSSL_atomic_add_begin:
pushl %ebx
nop
movl (%edx),%eax
-L009spin:
+L016spin:
leal (%eax,%ecx,1),%ebx
nop
.long 447811568
- jne L009spin
+ jne L016spin
movl %ebx,%eax
popl %ebx
ret
@@ -228,34 +266,51 @@ L_OPENSSL_cleanse_begin:
movl 8(%esp),%ecx
xorl %eax,%eax
cmpl $7,%ecx
- jae L010lot
+ jae L017lot
cmpl $0,%ecx
- je L011ret
-L012little:
+ je L018ret
+L019little:
movb %al,(%edx)
subl $1,%ecx
leal 1(%edx),%edx
- jnz L012little
-L011ret:
+ jnz L019little
+L018ret:
ret
.align 4,0x90
-L010lot:
+L017lot:
testl $3,%edx
- jz L013aligned
+ jz L020aligned
movb %al,(%edx)
leal -1(%ecx),%ecx
leal 1(%edx),%edx
- jmp L010lot
-L013aligned:
+ jmp L017lot
+L020aligned:
movl %eax,(%edx)
leal -4(%ecx),%ecx
testl $-4,%ecx
leal 4(%edx),%edx
- jnz L013aligned
+ jnz L020aligned
cmpl $0,%ecx
- jne L012little
+ jne L019little
+ ret
+.globl _OPENSSL_ia32_rdrand
+.align 4
+_OPENSSL_ia32_rdrand:
+L_OPENSSL_ia32_rdrand_begin:
+ movl $8,%ecx
+L021loop:
+.byte 15,199,240
+ jc L022break
+ loop L021loop
+L022break:
+ cmpl $0,%eax
+ cmovel %ecx,%eax
ret
-.comm _OPENSSL_ia32cap_P,4
+.section __IMPORT,__pointers,non_lazy_symbol_pointers
+L_OPENSSL_ia32cap_P$non_lazy_ptr:
+.indirect_symbol _OPENSSL_ia32cap_P
+.long 0
+.comm _OPENSSL_ia32cap_P,8,2
.mod_init_func
.align 2
.long _OPENSSL_cpuid_setup
diff --git a/deps/openssl/asm/x86-win32-masm/aes/aes-586.asm b/deps/openssl/asm/x86-win32-masm/aes/aes-586.asm
index 22dd21fbc..e4ac96e64 100644
--- a/deps/openssl/asm/x86-win32-masm/aes/aes-586.asm
+++ b/deps/openssl/asm/x86-win32-masm/aes/aes-586.asm
@@ -2975,14 +2975,14 @@ $L045exit:
ret
__x86_AES_set_encrypt_key ENDP
ALIGN 16
-_AES_set_encrypt_key PROC PUBLIC
-$L_AES_set_encrypt_key_begin::
+_private_AES_set_encrypt_key PROC PUBLIC
+$L_private_AES_set_encrypt_key_begin::
call __x86_AES_set_encrypt_key
ret
-_AES_set_encrypt_key ENDP
+_private_AES_set_encrypt_key ENDP
ALIGN 16
-_AES_set_decrypt_key PROC PUBLIC
-$L_AES_set_decrypt_key_begin::
+_private_AES_set_decrypt_key PROC PUBLIC
+$L_private_AES_set_decrypt_key_begin::
call __x86_AES_set_encrypt_key
cmp eax,0
je $L054proceed
@@ -3211,12 +3211,12 @@ $L056permute:
pop ebx
pop ebp
ret
-_AES_set_decrypt_key ENDP
+_private_AES_set_decrypt_key ENDP
DB 65,69,83,32,102,111,114,32,120,56,54,44,32,67,82,89
DB 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
DB 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.text$ ENDS
.bss SEGMENT 'BSS'
-COMM _OPENSSL_ia32cap_P:DWORD
+COMM _OPENSSL_ia32cap_P:QWORD
.bss ENDS
END
diff --git a/deps/openssl/asm/x86-win32-masm/aes/aesni-x86.asm b/deps/openssl/asm/x86-win32-masm/aes/aesni-x86.asm
new file mode 100644
index 000000000..a1602cc69
--- /dev/null
+++ b/deps/openssl/asm/x86-win32-masm/aes/aesni-x86.asm
@@ -0,0 +1,2133 @@
+TITLE ../openssl/crypto/aes/asm/aesni-x86.asm
+IF @Version LT 800
+ECHO MASM version 8.00 or later is strongly recommended.
+ENDIF
+.686
+.XMM
+IF @Version LT 800
+XMMWORD STRUCT 16
+DQ 2 dup (?)
+XMMWORD ENDS
+ENDIF
+
+.MODEL FLAT
+OPTION DOTNAME
+IF @Version LT 800
+.text$ SEGMENT PAGE 'CODE'
+ELSE
+.text$ SEGMENT ALIGN(64) 'CODE'
+ENDIF
+ALIGN 16
+_aesni_encrypt PROC PUBLIC
+$L_aesni_encrypt_begin::
+ mov eax,DWORD PTR 4[esp]
+ mov edx,DWORD PTR 12[esp]
+ movups xmm2,XMMWORD PTR [eax]
+ mov ecx,DWORD PTR 240[edx]
+ mov eax,DWORD PTR 8[esp]
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L000enc1_loop_1:
+DB 102,15,56,220,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L000enc1_loop_1
+DB 102,15,56,221,209
+ movups XMMWORD PTR [eax],xmm2
+ ret
+_aesni_encrypt ENDP
+ALIGN 16
+_aesni_decrypt PROC PUBLIC
+$L_aesni_decrypt_begin::
+ mov eax,DWORD PTR 4[esp]
+ mov edx,DWORD PTR 12[esp]
+ movups xmm2,XMMWORD PTR [eax]
+ mov ecx,DWORD PTR 240[edx]
+ mov eax,DWORD PTR 8[esp]
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L001dec1_loop_2:
+DB 102,15,56,222,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L001dec1_loop_2
+DB 102,15,56,223,209
+ movups XMMWORD PTR [eax],xmm2
+ ret
+_aesni_decrypt ENDP
+ALIGN 16
+__aesni_encrypt3 PROC PRIVATE
+ movups xmm0,XMMWORD PTR [edx]
+ shr ecx,1
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+ pxor xmm3,xmm0
+ pxor xmm4,xmm0
+ movups xmm0,XMMWORD PTR [edx]
+$L002enc3_loop:
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ dec ecx
+DB 102,15,56,220,225
+ movups xmm1,XMMWORD PTR 16[edx]
+DB 102,15,56,220,208
+DB 102,15,56,220,216
+ lea edx,DWORD PTR 32[edx]
+DB 102,15,56,220,224
+ movups xmm0,XMMWORD PTR [edx]
+ jnz $L002enc3_loop
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+DB 102,15,56,220,225
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+DB 102,15,56,221,224
+ ret
+__aesni_encrypt3 ENDP
+ALIGN 16
+__aesni_decrypt3 PROC PRIVATE
+ movups xmm0,XMMWORD PTR [edx]
+ shr ecx,1
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+ pxor xmm3,xmm0
+ pxor xmm4,xmm0
+ movups xmm0,XMMWORD PTR [edx]
+$L003dec3_loop:
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+ dec ecx
+DB 102,15,56,222,225
+ movups xmm1,XMMWORD PTR 16[edx]
+DB 102,15,56,222,208
+DB 102,15,56,222,216
+ lea edx,DWORD PTR 32[edx]
+DB 102,15,56,222,224
+ movups xmm0,XMMWORD PTR [edx]
+ jnz $L003dec3_loop
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+DB 102,15,56,222,225
+DB 102,15,56,223,208
+DB 102,15,56,223,216
+DB 102,15,56,223,224
+ ret
+__aesni_decrypt3 ENDP
+ALIGN 16
+__aesni_encrypt4 PROC PRIVATE
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ shr ecx,1
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+ pxor xmm3,xmm0
+ pxor xmm4,xmm0
+ pxor xmm5,xmm0
+ movups xmm0,XMMWORD PTR [edx]
+$L004enc4_loop:
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ dec ecx
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+ movups xmm1,XMMWORD PTR 16[edx]
+DB 102,15,56,220,208
+DB 102,15,56,220,216
+ lea edx,DWORD PTR 32[edx]
+DB 102,15,56,220,224
+DB 102,15,56,220,232
+ movups xmm0,XMMWORD PTR [edx]
+ jnz $L004enc4_loop
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+DB 102,15,56,221,224
+DB 102,15,56,221,232
+ ret
+__aesni_encrypt4 ENDP
+ALIGN 16
+__aesni_decrypt4 PROC PRIVATE
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ shr ecx,1
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+ pxor xmm3,xmm0
+ pxor xmm4,xmm0
+ pxor xmm5,xmm0
+ movups xmm0,XMMWORD PTR [edx]
+$L005dec4_loop:
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+ dec ecx
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+ movups xmm1,XMMWORD PTR 16[edx]
+DB 102,15,56,222,208
+DB 102,15,56,222,216
+ lea edx,DWORD PTR 32[edx]
+DB 102,15,56,222,224
+DB 102,15,56,222,232
+ movups xmm0,XMMWORD PTR [edx]
+ jnz $L005dec4_loop
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+DB 102,15,56,223,208
+DB 102,15,56,223,216
+DB 102,15,56,223,224
+DB 102,15,56,223,232
+ ret
+__aesni_decrypt4 ENDP
+ALIGN 16
+__aesni_encrypt6 PROC PRIVATE
+ movups xmm0,XMMWORD PTR [edx]
+ shr ecx,1
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+ pxor xmm3,xmm0
+DB 102,15,56,220,209
+ pxor xmm4,xmm0
+DB 102,15,56,220,217
+ pxor xmm5,xmm0
+ dec ecx
+DB 102,15,56,220,225
+ pxor xmm6,xmm0
+DB 102,15,56,220,233
+ pxor xmm7,xmm0
+DB 102,15,56,220,241
+ movups xmm0,XMMWORD PTR [edx]
+DB 102,15,56,220,249
+ jmp $L_aesni_encrypt6_enter
+ALIGN 16
+$L006enc6_loop:
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ dec ecx
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+ALIGN 16
+$L_aesni_encrypt6_enter::
+ movups xmm1,XMMWORD PTR 16[edx]
+DB 102,15,56,220,208
+DB 102,15,56,220,216
+ lea edx,DWORD PTR 32[edx]
+DB 102,15,56,220,224
+DB 102,15,56,220,232
+DB 102,15,56,220,240
+DB 102,15,56,220,248
+ movups xmm0,XMMWORD PTR [edx]
+ jnz $L006enc6_loop
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+DB 102,15,56,220,225
+DB 102,15,56,220,233
+DB 102,15,56,220,241
+DB 102,15,56,220,249
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+DB 102,15,56,221,224
+DB 102,15,56,221,232
+DB 102,15,56,221,240
+DB 102,15,56,221,248
+ ret
+__aesni_encrypt6 ENDP
+ALIGN 16
+__aesni_decrypt6 PROC PRIVATE
+ movups xmm0,XMMWORD PTR [edx]
+ shr ecx,1
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+ pxor xmm3,xmm0
+DB 102,15,56,222,209
+ pxor xmm4,xmm0
+DB 102,15,56,222,217
+ pxor xmm5,xmm0
+ dec ecx
+DB 102,15,56,222,225
+ pxor xmm6,xmm0
+DB 102,15,56,222,233
+ pxor xmm7,xmm0
+DB 102,15,56,222,241
+ movups xmm0,XMMWORD PTR [edx]
+DB 102,15,56,222,249
+ jmp $L_aesni_decrypt6_enter
+ALIGN 16
+$L007dec6_loop:
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+ dec ecx
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+DB 102,15,56,222,241
+DB 102,15,56,222,249
+ALIGN 16
+$L_aesni_decrypt6_enter::
+ movups xmm1,XMMWORD PTR 16[edx]
+DB 102,15,56,222,208
+DB 102,15,56,222,216
+ lea edx,DWORD PTR 32[edx]
+DB 102,15,56,222,224
+DB 102,15,56,222,232
+DB 102,15,56,222,240
+DB 102,15,56,222,248
+ movups xmm0,XMMWORD PTR [edx]
+ jnz $L007dec6_loop
+DB 102,15,56,222,209
+DB 102,15,56,222,217
+DB 102,15,56,222,225
+DB 102,15,56,222,233
+DB 102,15,56,222,241
+DB 102,15,56,222,249
+DB 102,15,56,223,208
+DB 102,15,56,223,216
+DB 102,15,56,223,224
+DB 102,15,56,223,232
+DB 102,15,56,223,240
+DB 102,15,56,223,248
+ ret
+__aesni_decrypt6 ENDP
+ALIGN 16
+_aesni_ecb_encrypt PROC PUBLIC
+$L_aesni_ecb_encrypt_begin::
+ push ebp
+ push ebx
+ push esi
+ push edi
+ mov esi,DWORD PTR 20[esp]
+ mov edi,DWORD PTR 24[esp]
+ mov eax,DWORD PTR 28[esp]
+ mov edx,DWORD PTR 32[esp]
+ mov ebx,DWORD PTR 36[esp]
+ and eax,-16
+ jz $L008ecb_ret
+ mov ecx,DWORD PTR 240[edx]
+ test ebx,ebx
+ jz $L009ecb_decrypt
+ mov ebp,edx
+ mov ebx,ecx
+ cmp eax,96
+ jb $L010ecb_enc_tail
+ movdqu xmm2,XMMWORD PTR [esi]
+ movdqu xmm3,XMMWORD PTR 16[esi]
+ movdqu xmm4,XMMWORD PTR 32[esi]
+ movdqu xmm5,XMMWORD PTR 48[esi]
+ movdqu xmm6,XMMWORD PTR 64[esi]
+ movdqu xmm7,XMMWORD PTR 80[esi]
+ lea esi,DWORD PTR 96[esi]
+ sub eax,96
+ jmp $L011ecb_enc_loop6_enter
+ALIGN 16
+$L012ecb_enc_loop6:
+ movups XMMWORD PTR [edi],xmm2
+ movdqu xmm2,XMMWORD PTR [esi]
+ movups XMMWORD PTR 16[edi],xmm3
+ movdqu xmm3,XMMWORD PTR 16[esi]
+ movups XMMWORD PTR 32[edi],xmm4
+ movdqu xmm4,XMMWORD PTR 32[esi]
+ movups XMMWORD PTR 48[edi],xmm5
+ movdqu xmm5,XMMWORD PTR 48[esi]
+ movups XMMWORD PTR 64[edi],xmm6
+ movdqu xmm6,XMMWORD PTR 64[esi]
+ movups XMMWORD PTR 80[edi],xmm7
+ lea edi,DWORD PTR 96[edi]
+ movdqu xmm7,XMMWORD PTR 80[esi]
+ lea esi,DWORD PTR 96[esi]
+$L011ecb_enc_loop6_enter:
+ call __aesni_encrypt6
+ mov edx,ebp
+ mov ecx,ebx
+ sub eax,96
+ jnc $L012ecb_enc_loop6
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ movups XMMWORD PTR 64[edi],xmm6
+ movups XMMWORD PTR 80[edi],xmm7
+ lea edi,DWORD PTR 96[edi]
+ add eax,96
+ jz $L008ecb_ret
+$L010ecb_enc_tail:
+ movups xmm2,XMMWORD PTR [esi]
+ cmp eax,32
+ jb $L013ecb_enc_one
+ movups xmm3,XMMWORD PTR 16[esi]
+ je $L014ecb_enc_two
+ movups xmm4,XMMWORD PTR 32[esi]
+ cmp eax,64
+ jb $L015ecb_enc_three
+ movups xmm5,XMMWORD PTR 48[esi]
+ je $L016ecb_enc_four
+ movups xmm6,XMMWORD PTR 64[esi]
+ xorps xmm7,xmm7
+ call __aesni_encrypt6
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ movups XMMWORD PTR 64[edi],xmm6
+ jmp $L008ecb_ret
+ALIGN 16
+$L013ecb_enc_one:
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L017enc1_loop_3:
+DB 102,15,56,220,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L017enc1_loop_3
+DB 102,15,56,221,209
+ movups XMMWORD PTR [edi],xmm2
+ jmp $L008ecb_ret
+ALIGN 16
+$L014ecb_enc_two:
+ xorps xmm4,xmm4
+ call __aesni_encrypt3
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ jmp $L008ecb_ret
+ALIGN 16
+$L015ecb_enc_three:
+ call __aesni_encrypt3
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ jmp $L008ecb_ret
+ALIGN 16
+$L016ecb_enc_four:
+ call __aesni_encrypt4
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ jmp $L008ecb_ret
+ALIGN 16
+$L009ecb_decrypt:
+ mov ebp,edx
+ mov ebx,ecx
+ cmp eax,96
+ jb $L018ecb_dec_tail
+ movdqu xmm2,XMMWORD PTR [esi]
+ movdqu xmm3,XMMWORD PTR 16[esi]
+ movdqu xmm4,XMMWORD PTR 32[esi]
+ movdqu xmm5,XMMWORD PTR 48[esi]
+ movdqu xmm6,XMMWORD PTR 64[esi]
+ movdqu xmm7,XMMWORD PTR 80[esi]
+ lea esi,DWORD PTR 96[esi]
+ sub eax,96
+ jmp $L019ecb_dec_loop6_enter
+ALIGN 16
+$L020ecb_dec_loop6:
+ movups XMMWORD PTR [edi],xmm2
+ movdqu xmm2,XMMWORD PTR [esi]
+ movups XMMWORD PTR 16[edi],xmm3
+ movdqu xmm3,XMMWORD PTR 16[esi]
+ movups XMMWORD PTR 32[edi],xmm4
+ movdqu xmm4,XMMWORD PTR 32[esi]
+ movups XMMWORD PTR 48[edi],xmm5
+ movdqu xmm5,XMMWORD PTR 48[esi]
+ movups XMMWORD PTR 64[edi],xmm6
+ movdqu xmm6,XMMWORD PTR 64[esi]
+ movups XMMWORD PTR 80[edi],xmm7
+ lea edi,DWORD PTR 96[edi]
+ movdqu xmm7,XMMWORD PTR 80[esi]
+ lea esi,DWORD PTR 96[esi]
+$L019ecb_dec_loop6_enter:
+ call __aesni_decrypt6
+ mov edx,ebp
+ mov ecx,ebx
+ sub eax,96
+ jnc $L020ecb_dec_loop6
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ movups XMMWORD PTR 64[edi],xmm6
+ movups XMMWORD PTR 80[edi],xmm7
+ lea edi,DWORD PTR 96[edi]
+ add eax,96
+ jz $L008ecb_ret
+$L018ecb_dec_tail:
+ movups xmm2,XMMWORD PTR [esi]
+ cmp eax,32
+ jb $L021ecb_dec_one
+ movups xmm3,XMMWORD PTR 16[esi]
+ je $L022ecb_dec_two
+ movups xmm4,XMMWORD PTR 32[esi]
+ cmp eax,64
+ jb $L023ecb_dec_three
+ movups xmm5,XMMWORD PTR 48[esi]
+ je $L024ecb_dec_four
+ movups xmm6,XMMWORD PTR 64[esi]
+ xorps xmm7,xmm7
+ call __aesni_decrypt6
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ movups XMMWORD PTR 64[edi],xmm6
+ jmp $L008ecb_ret
+ALIGN 16
+$L021ecb_dec_one:
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L025dec1_loop_4:
+DB 102,15,56,222,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L025dec1_loop_4
+DB 102,15,56,223,209
+ movups XMMWORD PTR [edi],xmm2
+ jmp $L008ecb_ret
+ALIGN 16
+$L022ecb_dec_two:
+ xorps xmm4,xmm4
+ call __aesni_decrypt3
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ jmp $L008ecb_ret
+ALIGN 16
+$L023ecb_dec_three:
+ call __aesni_decrypt3
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ jmp $L008ecb_ret
+ALIGN 16
+$L024ecb_dec_four:
+ call __aesni_decrypt4
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+$L008ecb_ret:
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+_aesni_ecb_encrypt ENDP
+ALIGN 16
+_aesni_ccm64_encrypt_blocks PROC PUBLIC
+$L_aesni_ccm64_encrypt_blocks_begin::
+ push ebp
+ push ebx
+ push esi
+ push edi
+ mov esi,DWORD PTR 20[esp]
+ mov edi,DWORD PTR 24[esp]
+ mov eax,DWORD PTR 28[esp]
+ mov edx,DWORD PTR 32[esp]
+ mov ebx,DWORD PTR 36[esp]
+ mov ecx,DWORD PTR 40[esp]
+ mov ebp,esp
+ sub esp,60
+ and esp,-16
+ mov DWORD PTR 48[esp],ebp
+ movdqu xmm7,XMMWORD PTR [ebx]
+ movdqu xmm3,XMMWORD PTR [ecx]
+ mov ecx,DWORD PTR 240[edx]
+ mov DWORD PTR [esp],202182159
+ mov DWORD PTR 4[esp],134810123
+ mov DWORD PTR 8[esp],67438087
+ mov DWORD PTR 12[esp],66051
+ mov ebx,1
+ xor ebp,ebp
+ mov DWORD PTR 16[esp],ebx
+ mov DWORD PTR 20[esp],ebp
+ mov DWORD PTR 24[esp],ebp
+ mov DWORD PTR 28[esp],ebp
+ shr ecx,1
+ lea ebp,DWORD PTR [edx]
+ movdqa xmm5,XMMWORD PTR [esp]
+ movdqa xmm2,xmm7
+ mov ebx,ecx
+DB 102,15,56,0,253
+$L026ccm64_enc_outer:
+ movups xmm0,XMMWORD PTR [ebp]
+ mov ecx,ebx
+ movups xmm6,XMMWORD PTR [esi]
+ xorps xmm2,xmm0
+ movups xmm1,XMMWORD PTR 16[ebp]
+ xorps xmm0,xmm6
+ lea edx,DWORD PTR 32[ebp]
+ xorps xmm3,xmm0
+ movups xmm0,XMMWORD PTR [edx]
+$L027ccm64_enc2_loop:
+DB 102,15,56,220,209
+ dec ecx
+DB 102,15,56,220,217
+ movups xmm1,XMMWORD PTR 16[edx]
+DB 102,15,56,220,208
+ lea edx,DWORD PTR 32[edx]
+DB 102,15,56,220,216
+ movups xmm0,XMMWORD PTR [edx]
+ jnz $L027ccm64_enc2_loop
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ paddq xmm7,XMMWORD PTR 16[esp]
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+ dec eax
+ lea esi,DWORD PTR 16[esi]
+ xorps xmm6,xmm2
+ movdqa xmm2,xmm7
+ movups XMMWORD PTR [edi],xmm6
+ lea edi,DWORD PTR 16[edi]
+DB 102,15,56,0,213
+ jnz $L026ccm64_enc_outer
+ mov esp,DWORD PTR 48[esp]
+ mov edi,DWORD PTR 40[esp]
+ movups XMMWORD PTR [edi],xmm3
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+_aesni_ccm64_encrypt_blocks ENDP
+ALIGN 16
+_aesni_ccm64_decrypt_blocks PROC PUBLIC
+$L_aesni_ccm64_decrypt_blocks_begin::
+ push ebp
+ push ebx
+ push esi
+ push edi
+ mov esi,DWORD PTR 20[esp]
+ mov edi,DWORD PTR 24[esp]
+ mov eax,DWORD PTR 28[esp]
+ mov edx,DWORD PTR 32[esp]
+ mov ebx,DWORD PTR 36[esp]
+ mov ecx,DWORD PTR 40[esp]
+ mov ebp,esp
+ sub esp,60
+ and esp,-16
+ mov DWORD PTR 48[esp],ebp
+ movdqu xmm7,XMMWORD PTR [ebx]
+ movdqu xmm3,XMMWORD PTR [ecx]
+ mov ecx,DWORD PTR 240[edx]
+ mov DWORD PTR [esp],202182159
+ mov DWORD PTR 4[esp],134810123
+ mov DWORD PTR 8[esp],67438087
+ mov DWORD PTR 12[esp],66051
+ mov ebx,1
+ xor ebp,ebp
+ mov DWORD PTR 16[esp],ebx
+ mov DWORD PTR 20[esp],ebp
+ mov DWORD PTR 24[esp],ebp
+ mov DWORD PTR 28[esp],ebp
+ movdqa xmm5,XMMWORD PTR [esp]
+ movdqa xmm2,xmm7
+ mov ebp,edx
+ mov ebx,ecx
+DB 102,15,56,0,253
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L028enc1_loop_5:
+DB 102,15,56,220,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L028enc1_loop_5
+DB 102,15,56,221,209
+ movups xmm6,XMMWORD PTR [esi]
+ paddq xmm7,XMMWORD PTR 16[esp]
+ lea esi,QWORD PTR 16[esi]
+ jmp $L029ccm64_dec_outer
+ALIGN 16
+$L029ccm64_dec_outer:
+ xorps xmm6,xmm2
+ movdqa xmm2,xmm7
+ mov ecx,ebx
+ movups XMMWORD PTR [edi],xmm6
+ lea edi,DWORD PTR 16[edi]
+DB 102,15,56,0,213
+ sub eax,1
+ jz $L030ccm64_dec_break
+ movups xmm0,XMMWORD PTR [ebp]
+ shr ecx,1
+ movups xmm1,XMMWORD PTR 16[ebp]
+ xorps xmm6,xmm0
+ lea edx,DWORD PTR 32[ebp]
+ xorps xmm2,xmm0
+ xorps xmm3,xmm6
+ movups xmm0,XMMWORD PTR [edx]
+$L031ccm64_dec2_loop:
+DB 102,15,56,220,209
+ dec ecx
+DB 102,15,56,220,217
+ movups xmm1,XMMWORD PTR 16[edx]
+DB 102,15,56,220,208
+ lea edx,DWORD PTR 32[edx]
+DB 102,15,56,220,216
+ movups xmm0,XMMWORD PTR [edx]
+ jnz $L031ccm64_dec2_loop
+ movups xmm6,XMMWORD PTR [esi]
+ paddq xmm7,XMMWORD PTR 16[esp]
+DB 102,15,56,220,209
+DB 102,15,56,220,217
+ lea esi,QWORD PTR 16[esi]
+DB 102,15,56,221,208
+DB 102,15,56,221,216
+ jmp $L029ccm64_dec_outer
+ALIGN 16
+$L030ccm64_dec_break:
+ mov edx,ebp
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ xorps xmm6,xmm0
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm3,xmm6
+$L032enc1_loop_6:
+DB 102,15,56,220,217
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L032enc1_loop_6
+DB 102,15,56,221,217
+ mov esp,DWORD PTR 48[esp]
+ mov edi,DWORD PTR 40[esp]
+ movups XMMWORD PTR [edi],xmm3
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+_aesni_ccm64_decrypt_blocks ENDP
+ALIGN 16
+_aesni_ctr32_encrypt_blocks PROC PUBLIC
+$L_aesni_ctr32_encrypt_blocks_begin::
+ push ebp
+ push ebx
+ push esi
+ push edi
+ mov esi,DWORD PTR 20[esp]
+ mov edi,DWORD PTR 24[esp]
+ mov eax,DWORD PTR 28[esp]
+ mov edx,DWORD PTR 32[esp]
+ mov ebx,DWORD PTR 36[esp]
+ mov ebp,esp
+ sub esp,88
+ and esp,-16
+ mov DWORD PTR 80[esp],ebp
+ cmp eax,1
+ je $L033ctr32_one_shortcut
+ movdqu xmm7,XMMWORD PTR [ebx]
+ mov DWORD PTR [esp],202182159
+ mov DWORD PTR 4[esp],134810123
+ mov DWORD PTR 8[esp],67438087
+ mov DWORD PTR 12[esp],66051
+ mov ecx,6
+ xor ebp,ebp
+ mov DWORD PTR 16[esp],ecx
+ mov DWORD PTR 20[esp],ecx
+ mov DWORD PTR 24[esp],ecx
+ mov DWORD PTR 28[esp],ebp
+DB 102,15,58,22,251,3
+DB 102,15,58,34,253,3
+ mov ecx,DWORD PTR 240[edx]
+ bswap ebx
+ pxor xmm1,xmm1
+ pxor xmm0,xmm0
+ movdqa xmm2,XMMWORD PTR [esp]
+DB 102,15,58,34,203,0
+ lea ebp,DWORD PTR 3[ebx]
+DB 102,15,58,34,197,0
+ inc ebx
+DB 102,15,58,34,203,1
+ inc ebp
+DB 102,15,58,34,197,1
+ inc ebx
+DB 102,15,58,34,203,2
+ inc ebp
+DB 102,15,58,34,197,2
+ movdqa XMMWORD PTR 48[esp],xmm1
+DB 102,15,56,0,202
+ movdqa XMMWORD PTR 64[esp],xmm0
+DB 102,15,56,0,194
+ pshufd xmm2,xmm1,192
+ pshufd xmm3,xmm1,128
+ cmp eax,6
+ jb $L034ctr32_tail
+ movdqa XMMWORD PTR 32[esp],xmm7
+ shr ecx,1
+ mov ebp,edx
+ mov ebx,ecx
+ sub eax,6
+ jmp $L035ctr32_loop6
+ALIGN 16
+$L035ctr32_loop6:
+ pshufd xmm4,xmm1,64
+ movdqa xmm1,XMMWORD PTR 32[esp]
+ pshufd xmm5,xmm0,192
+ por xmm2,xmm1
+ pshufd xmm6,xmm0,128
+ por xmm3,xmm1
+ pshufd xmm7,xmm0,64
+ por xmm4,xmm1
+ por xmm5,xmm1
+ por xmm6,xmm1
+ por xmm7,xmm1
+ movups xmm0,XMMWORD PTR [ebp]
+ movups xmm1,XMMWORD PTR 16[ebp]
+ lea edx,DWORD PTR 32[ebp]
+ dec ecx
+ pxor xmm2,xmm0
+ pxor xmm3,xmm0
+DB 102,15,56,220,209
+ pxor xmm4,xmm0
+DB 102,15,56,220,217
+ pxor xmm5,xmm0
+DB 102,15,56,220,225
+ pxor xmm6,xmm0
+DB 102,15,56,220,233
+ pxor xmm7,xmm0
+DB 102,15,56,220,241
+ movups xmm0,XMMWORD PTR [edx]
+DB 102,15,56,220,249
+ call $L_aesni_encrypt6_enter
+ movups xmm1,XMMWORD PTR [esi]
+ movups xmm0,XMMWORD PTR 16[esi]
+ xorps xmm2,xmm1
+ movups xmm1,XMMWORD PTR 32[esi]
+ xorps xmm3,xmm0
+ movups XMMWORD PTR [edi],xmm2
+ movdqa xmm0,XMMWORD PTR 16[esp]
+ xorps xmm4,xmm1
+ movdqa xmm1,XMMWORD PTR 48[esp]
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ paddd xmm1,xmm0
+ paddd xmm0,XMMWORD PTR 64[esp]
+ movdqa xmm2,XMMWORD PTR [esp]
+ movups xmm3,XMMWORD PTR 48[esi]
+ movups xmm4,XMMWORD PTR 64[esi]
+ xorps xmm5,xmm3
+ movups xmm3,XMMWORD PTR 80[esi]
+ lea esi,DWORD PTR 96[esi]
+ movdqa XMMWORD PTR 48[esp],xmm1
+DB 102,15,56,0,202
+ xorps xmm6,xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ xorps xmm7,xmm3
+ movdqa XMMWORD PTR 64[esp],xmm0
+DB 102,15,56,0,194
+ movups XMMWORD PTR 64[edi],xmm6
+ pshufd xmm2,xmm1,192
+ movups XMMWORD PTR 80[edi],xmm7
+ lea edi,DWORD PTR 96[edi]
+ mov ecx,ebx
+ pshufd xmm3,xmm1,128
+ sub eax,6
+ jnc $L035ctr32_loop6
+ add eax,6
+ jz $L036ctr32_ret
+ mov edx,ebp
+ lea ecx,DWORD PTR 1[ecx*2]
+ movdqa xmm7,XMMWORD PTR 32[esp]
+$L034ctr32_tail:
+ por xmm2,xmm7
+ cmp eax,2
+ jb $L037ctr32_one
+ pshufd xmm4,xmm1,64
+ por xmm3,xmm7
+ je $L038ctr32_two
+ pshufd xmm5,xmm0,192
+ por xmm4,xmm7
+ cmp eax,4
+ jb $L039ctr32_three
+ pshufd xmm6,xmm0,128
+ por xmm5,xmm7
+ je $L040ctr32_four
+ por xmm6,xmm7
+ call __aesni_encrypt6
+ movups xmm1,XMMWORD PTR [esi]
+ movups xmm0,XMMWORD PTR 16[esi]
+ xorps xmm2,xmm1
+ movups xmm1,XMMWORD PTR 32[esi]
+ xorps xmm3,xmm0
+ movups xmm0,XMMWORD PTR 48[esi]
+ xorps xmm4,xmm1
+ movups xmm1,XMMWORD PTR 64[esi]
+ xorps xmm5,xmm0
+ movups XMMWORD PTR [edi],xmm2
+ xorps xmm6,xmm1
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ movups XMMWORD PTR 64[edi],xmm6
+ jmp $L036ctr32_ret
+ALIGN 16
+$L033ctr32_one_shortcut:
+ movups xmm2,XMMWORD PTR [ebx]
+ mov ecx,DWORD PTR 240[edx]
+$L037ctr32_one:
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L041enc1_loop_7:
+DB 102,15,56,220,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L041enc1_loop_7
+DB 102,15,56,221,209
+ movups xmm6,XMMWORD PTR [esi]
+ xorps xmm6,xmm2
+ movups XMMWORD PTR [edi],xmm6
+ jmp $L036ctr32_ret
+ALIGN 16
+$L038ctr32_two:
+ call __aesni_encrypt3
+ movups xmm5,XMMWORD PTR [esi]
+ movups xmm6,XMMWORD PTR 16[esi]
+ xorps xmm2,xmm5
+ xorps xmm3,xmm6
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ jmp $L036ctr32_ret
+ALIGN 16
+$L039ctr32_three:
+ call __aesni_encrypt3
+ movups xmm5,XMMWORD PTR [esi]
+ movups xmm6,XMMWORD PTR 16[esi]
+ xorps xmm2,xmm5
+ movups xmm7,XMMWORD PTR 32[esi]
+ xorps xmm3,xmm6
+ movups XMMWORD PTR [edi],xmm2
+ xorps xmm4,xmm7
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ jmp $L036ctr32_ret
+ALIGN 16
+$L040ctr32_four:
+ call __aesni_encrypt4
+ movups xmm6,XMMWORD PTR [esi]
+ movups xmm7,XMMWORD PTR 16[esi]
+ movups xmm1,XMMWORD PTR 32[esi]
+ xorps xmm2,xmm6
+ movups xmm0,XMMWORD PTR 48[esi]
+ xorps xmm3,xmm7
+ movups XMMWORD PTR [edi],xmm2
+ xorps xmm4,xmm1
+ movups XMMWORD PTR 16[edi],xmm3
+ xorps xmm5,xmm0
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+$L036ctr32_ret:
+ mov esp,DWORD PTR 80[esp]
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+_aesni_ctr32_encrypt_blocks ENDP
+ALIGN 16
+_aesni_xts_encrypt PROC PUBLIC
+$L_aesni_xts_encrypt_begin::
+ push ebp
+ push ebx
+ push esi
+ push edi
+ mov edx,DWORD PTR 36[esp]
+ mov esi,DWORD PTR 40[esp]
+ mov ecx,DWORD PTR 240[edx]
+ movups xmm2,XMMWORD PTR [esi]
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L042enc1_loop_8:
+DB 102,15,56,220,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L042enc1_loop_8
+DB 102,15,56,221,209
+ mov esi,DWORD PTR 20[esp]
+ mov edi,DWORD PTR 24[esp]
+ mov eax,DWORD PTR 28[esp]
+ mov edx,DWORD PTR 32[esp]
+ mov ebp,esp
+ sub esp,120
+ mov ecx,DWORD PTR 240[edx]
+ and esp,-16
+ mov DWORD PTR 96[esp],135
+ mov DWORD PTR 100[esp],0
+ mov DWORD PTR 104[esp],1
+ mov DWORD PTR 108[esp],0
+ mov DWORD PTR 112[esp],eax
+ mov DWORD PTR 116[esp],ebp
+ movdqa xmm1,xmm2
+ pxor xmm0,xmm0
+ movdqa xmm3,XMMWORD PTR 96[esp]
+ pcmpgtd xmm0,xmm1
+ and eax,-16
+ mov ebp,edx
+ mov ebx,ecx
+ sub eax,96
+ jc $L043xts_enc_short
+ shr ecx,1
+ mov ebx,ecx
+ jmp $L044xts_enc_loop6
+ALIGN 16
+$L044xts_enc_loop6:
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa XMMWORD PTR [esp],xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa XMMWORD PTR 16[esp],xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa XMMWORD PTR 32[esp],xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa XMMWORD PTR 48[esp],xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ pshufd xmm7,xmm0,19
+ movdqa XMMWORD PTR 64[esp],xmm1
+ paddq xmm1,xmm1
+ movups xmm0,XMMWORD PTR [ebp]
+ pand xmm7,xmm3
+ movups xmm2,XMMWORD PTR [esi]
+ pxor xmm7,xmm1
+ movdqu xmm3,XMMWORD PTR 16[esi]
+ xorps xmm2,xmm0
+ movdqu xmm4,XMMWORD PTR 32[esi]
+ pxor xmm3,xmm0
+ movdqu xmm5,XMMWORD PTR 48[esi]
+ pxor xmm4,xmm0
+ movdqu xmm6,XMMWORD PTR 64[esi]
+ pxor xmm5,xmm0
+ movdqu xmm1,XMMWORD PTR 80[esi]
+ pxor xmm6,xmm0
+ lea esi,DWORD PTR 96[esi]
+ pxor xmm2,XMMWORD PTR [esp]
+ movdqa XMMWORD PTR 80[esp],xmm7
+ pxor xmm7,xmm1
+ movups xmm1,XMMWORD PTR 16[ebp]
+ lea edx,DWORD PTR 32[ebp]
+ pxor xmm3,XMMWORD PTR 16[esp]
+DB 102,15,56,220,209
+ pxor xmm4,XMMWORD PTR 32[esp]
+DB 102,15,56,220,217
+ pxor xmm5,XMMWORD PTR 48[esp]
+ dec ecx
+DB 102,15,56,220,225
+ pxor xmm6,XMMWORD PTR 64[esp]
+DB 102,15,56,220,233
+ pxor xmm7,xmm0
+DB 102,15,56,220,241
+ movups xmm0,XMMWORD PTR [edx]
+DB 102,15,56,220,249
+ call $L_aesni_encrypt6_enter
+ movdqa xmm1,XMMWORD PTR 80[esp]
+ pxor xmm0,xmm0
+ xorps xmm2,XMMWORD PTR [esp]
+ pcmpgtd xmm0,xmm1
+ xorps xmm3,XMMWORD PTR 16[esp]
+ movups XMMWORD PTR [edi],xmm2
+ xorps xmm4,XMMWORD PTR 32[esp]
+ movups XMMWORD PTR 16[edi],xmm3
+ xorps xmm5,XMMWORD PTR 48[esp]
+ movups XMMWORD PTR 32[edi],xmm4
+ xorps xmm6,XMMWORD PTR 64[esp]
+ movups XMMWORD PTR 48[edi],xmm5
+ xorps xmm7,xmm1
+ movups XMMWORD PTR 64[edi],xmm6
+ pshufd xmm2,xmm0,19
+ movups XMMWORD PTR 80[edi],xmm7
+ lea edi,DWORD PTR 96[edi]
+ movdqa xmm3,XMMWORD PTR 96[esp]
+ pxor xmm0,xmm0
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ mov ecx,ebx
+ pxor xmm1,xmm2
+ sub eax,96
+ jnc $L044xts_enc_loop6
+ lea ecx,DWORD PTR 1[ecx*2]
+ mov edx,ebp
+ mov ebx,ecx
+$L043xts_enc_short:
+ add eax,96
+ jz $L045xts_enc_done6x
+ movdqa xmm5,xmm1
+ cmp eax,32
+ jb $L046xts_enc_one
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ je $L047xts_enc_two
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa xmm6,xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ cmp eax,64
+ jb $L048xts_enc_three
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa xmm7,xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ movdqa XMMWORD PTR [esp],xmm5
+ movdqa XMMWORD PTR 16[esp],xmm6
+ je $L049xts_enc_four
+ movdqa XMMWORD PTR 32[esp],xmm7
+ pshufd xmm7,xmm0,19
+ movdqa XMMWORD PTR 48[esp],xmm1
+ paddq xmm1,xmm1
+ pand xmm7,xmm3
+ pxor xmm7,xmm1
+ movdqu xmm2,XMMWORD PTR [esi]
+ movdqu xmm3,XMMWORD PTR 16[esi]
+ movdqu xmm4,XMMWORD PTR 32[esi]
+ pxor xmm2,XMMWORD PTR [esp]
+ movdqu xmm5,XMMWORD PTR 48[esi]
+ pxor xmm3,XMMWORD PTR 16[esp]
+ movdqu xmm6,XMMWORD PTR 64[esi]
+ pxor xmm4,XMMWORD PTR 32[esp]
+ lea esi,DWORD PTR 80[esi]
+ pxor xmm5,XMMWORD PTR 48[esp]
+ movdqa XMMWORD PTR 64[esp],xmm7
+ pxor xmm6,xmm7
+ call __aesni_encrypt6
+ movaps xmm1,XMMWORD PTR 64[esp]
+ xorps xmm2,XMMWORD PTR [esp]
+ xorps xmm3,XMMWORD PTR 16[esp]
+ xorps xmm4,XMMWORD PTR 32[esp]
+ movups XMMWORD PTR [edi],xmm2
+ xorps xmm5,XMMWORD PTR 48[esp]
+ movups XMMWORD PTR 16[edi],xmm3
+ xorps xmm6,xmm1
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ movups XMMWORD PTR 64[edi],xmm6
+ lea edi,DWORD PTR 80[edi]
+ jmp $L050xts_enc_done
+ALIGN 16
+$L046xts_enc_one:
+ movups xmm2,XMMWORD PTR [esi]
+ lea esi,DWORD PTR 16[esi]
+ xorps xmm2,xmm5
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L051enc1_loop_9:
+DB 102,15,56,220,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L051enc1_loop_9
+DB 102,15,56,221,209
+ xorps xmm2,xmm5
+ movups XMMWORD PTR [edi],xmm2
+ lea edi,DWORD PTR 16[edi]
+ movdqa xmm1,xmm5
+ jmp $L050xts_enc_done
+ALIGN 16
+$L047xts_enc_two:
+ movaps xmm6,xmm1
+ movups xmm2,XMMWORD PTR [esi]
+ movups xmm3,XMMWORD PTR 16[esi]
+ lea esi,DWORD PTR 32[esi]
+ xorps xmm2,xmm5
+ xorps xmm3,xmm6
+ xorps xmm4,xmm4
+ call __aesni_encrypt3
+ xorps xmm2,xmm5
+ xorps xmm3,xmm6
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ lea edi,DWORD PTR 32[edi]
+ movdqa xmm1,xmm6
+ jmp $L050xts_enc_done
+ALIGN 16
+$L048xts_enc_three:
+ movaps xmm7,xmm1
+ movups xmm2,XMMWORD PTR [esi]
+ movups xmm3,XMMWORD PTR 16[esi]
+ movups xmm4,XMMWORD PTR 32[esi]
+ lea esi,DWORD PTR 48[esi]
+ xorps xmm2,xmm5
+ xorps xmm3,xmm6
+ xorps xmm4,xmm7
+ call __aesni_encrypt3
+ xorps xmm2,xmm5
+ xorps xmm3,xmm6
+ xorps xmm4,xmm7
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ lea edi,DWORD PTR 48[edi]
+ movdqa xmm1,xmm7
+ jmp $L050xts_enc_done
+ALIGN 16
+$L049xts_enc_four:
+ movaps xmm6,xmm1
+ movups xmm2,XMMWORD PTR [esi]
+ movups xmm3,XMMWORD PTR 16[esi]
+ movups xmm4,XMMWORD PTR 32[esi]
+ xorps xmm2,XMMWORD PTR [esp]
+ movups xmm5,XMMWORD PTR 48[esi]
+ lea esi,DWORD PTR 64[esi]
+ xorps xmm3,XMMWORD PTR 16[esp]
+ xorps xmm4,xmm7
+ xorps xmm5,xmm6
+ call __aesni_encrypt4
+ xorps xmm2,XMMWORD PTR [esp]
+ xorps xmm3,XMMWORD PTR 16[esp]
+ xorps xmm4,xmm7
+ movups XMMWORD PTR [edi],xmm2
+ xorps xmm5,xmm6
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ lea edi,DWORD PTR 64[edi]
+ movdqa xmm1,xmm6
+ jmp $L050xts_enc_done
+ALIGN 16
+$L045xts_enc_done6x:
+ mov eax,DWORD PTR 112[esp]
+ and eax,15
+ jz $L052xts_enc_ret
+ movdqa xmm5,xmm1
+ mov DWORD PTR 112[esp],eax
+ jmp $L053xts_enc_steal
+ALIGN 16
+$L050xts_enc_done:
+ mov eax,DWORD PTR 112[esp]
+ pxor xmm0,xmm0
+ and eax,15
+ jz $L052xts_enc_ret
+ pcmpgtd xmm0,xmm1
+ mov DWORD PTR 112[esp],eax
+ pshufd xmm5,xmm0,19
+ paddq xmm1,xmm1
+ pand xmm5,XMMWORD PTR 96[esp]
+ pxor xmm5,xmm1
+$L053xts_enc_steal:
+ movzx ecx,BYTE PTR [esi]
+ movzx edx,BYTE PTR [edi-16]
+ lea esi,DWORD PTR 1[esi]
+ mov BYTE PTR [edi-16],cl
+ mov BYTE PTR [edi],dl
+ lea edi,DWORD PTR 1[edi]
+ sub eax,1
+ jnz $L053xts_enc_steal
+ sub edi,DWORD PTR 112[esp]
+ mov edx,ebp
+ mov ecx,ebx
+ movups xmm2,XMMWORD PTR [edi-16]
+ xorps xmm2,xmm5
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L054enc1_loop_10:
+DB 102,15,56,220,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L054enc1_loop_10
+DB 102,15,56,221,209
+ xorps xmm2,xmm5
+ movups XMMWORD PTR [edi-16],xmm2
+$L052xts_enc_ret:
+ mov esp,DWORD PTR 116[esp]
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+_aesni_xts_encrypt ENDP
+ALIGN 16
+_aesni_xts_decrypt PROC PUBLIC
+$L_aesni_xts_decrypt_begin::
+ push ebp
+ push ebx
+ push esi
+ push edi
+ mov edx,DWORD PTR 36[esp]
+ mov esi,DWORD PTR 40[esp]
+ mov ecx,DWORD PTR 240[edx]
+ movups xmm2,XMMWORD PTR [esi]
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L055enc1_loop_11:
+DB 102,15,56,220,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L055enc1_loop_11
+DB 102,15,56,221,209
+ mov esi,DWORD PTR 20[esp]
+ mov edi,DWORD PTR 24[esp]
+ mov eax,DWORD PTR 28[esp]
+ mov edx,DWORD PTR 32[esp]
+ mov ebp,esp
+ sub esp,120
+ and esp,-16
+ xor ebx,ebx
+ test eax,15
+ setnz bl
+ shl ebx,4
+ sub eax,ebx
+ mov DWORD PTR 96[esp],135
+ mov DWORD PTR 100[esp],0
+ mov DWORD PTR 104[esp],1
+ mov DWORD PTR 108[esp],0
+ mov DWORD PTR 112[esp],eax
+ mov DWORD PTR 116[esp],ebp
+ mov ecx,DWORD PTR 240[edx]
+ mov ebp,edx
+ mov ebx,ecx
+ movdqa xmm1,xmm2
+ pxor xmm0,xmm0
+ movdqa xmm3,XMMWORD PTR 96[esp]
+ pcmpgtd xmm0,xmm1
+ and eax,-16
+ sub eax,96
+ jc $L056xts_dec_short
+ shr ecx,1
+ mov ebx,ecx
+ jmp $L057xts_dec_loop6
+ALIGN 16
+$L057xts_dec_loop6:
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa XMMWORD PTR [esp],xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa XMMWORD PTR 16[esp],xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa XMMWORD PTR 32[esp],xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa XMMWORD PTR 48[esp],xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ pshufd xmm7,xmm0,19
+ movdqa XMMWORD PTR 64[esp],xmm1
+ paddq xmm1,xmm1
+ movups xmm0,XMMWORD PTR [ebp]
+ pand xmm7,xmm3
+ movups xmm2,XMMWORD PTR [esi]
+ pxor xmm7,xmm1
+ movdqu xmm3,XMMWORD PTR 16[esi]
+ xorps xmm2,xmm0
+ movdqu xmm4,XMMWORD PTR 32[esi]
+ pxor xmm3,xmm0
+ movdqu xmm5,XMMWORD PTR 48[esi]
+ pxor xmm4,xmm0
+ movdqu xmm6,XMMWORD PTR 64[esi]
+ pxor xmm5,xmm0
+ movdqu xmm1,XMMWORD PTR 80[esi]
+ pxor xmm6,xmm0
+ lea esi,DWORD PTR 96[esi]
+ pxor xmm2,XMMWORD PTR [esp]
+ movdqa XMMWORD PTR 80[esp],xmm7
+ pxor xmm7,xmm1
+ movups xmm1,XMMWORD PTR 16[ebp]
+ lea edx,DWORD PTR 32[ebp]
+ pxor xmm3,XMMWORD PTR 16[esp]
+DB 102,15,56,222,209
+ pxor xmm4,XMMWORD PTR 32[esp]
+DB 102,15,56,222,217
+ pxor xmm5,XMMWORD PTR 48[esp]
+ dec ecx
+DB 102,15,56,222,225
+ pxor xmm6,XMMWORD PTR 64[esp]
+DB 102,15,56,222,233
+ pxor xmm7,xmm0
+DB 102,15,56,222,241
+ movups xmm0,XMMWORD PTR [edx]
+DB 102,15,56,222,249
+ call $L_aesni_decrypt6_enter
+ movdqa xmm1,XMMWORD PTR 80[esp]
+ pxor xmm0,xmm0
+ xorps xmm2,XMMWORD PTR [esp]
+ pcmpgtd xmm0,xmm1
+ xorps xmm3,XMMWORD PTR 16[esp]
+ movups XMMWORD PTR [edi],xmm2
+ xorps xmm4,XMMWORD PTR 32[esp]
+ movups XMMWORD PTR 16[edi],xmm3
+ xorps xmm5,XMMWORD PTR 48[esp]
+ movups XMMWORD PTR 32[edi],xmm4
+ xorps xmm6,XMMWORD PTR 64[esp]
+ movups XMMWORD PTR 48[edi],xmm5
+ xorps xmm7,xmm1
+ movups XMMWORD PTR 64[edi],xmm6
+ pshufd xmm2,xmm0,19
+ movups XMMWORD PTR 80[edi],xmm7
+ lea edi,DWORD PTR 96[edi]
+ movdqa xmm3,XMMWORD PTR 96[esp]
+ pxor xmm0,xmm0
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ mov ecx,ebx
+ pxor xmm1,xmm2
+ sub eax,96
+ jnc $L057xts_dec_loop6
+ lea ecx,DWORD PTR 1[ecx*2]
+ mov edx,ebp
+ mov ebx,ecx
+$L056xts_dec_short:
+ add eax,96
+ jz $L058xts_dec_done6x
+ movdqa xmm5,xmm1
+ cmp eax,32
+ jb $L059xts_dec_one
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ je $L060xts_dec_two
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa xmm6,xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ cmp eax,64
+ jb $L061xts_dec_three
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa xmm7,xmm1
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+ movdqa XMMWORD PTR [esp],xmm5
+ movdqa XMMWORD PTR 16[esp],xmm6
+ je $L062xts_dec_four
+ movdqa XMMWORD PTR 32[esp],xmm7
+ pshufd xmm7,xmm0,19
+ movdqa XMMWORD PTR 48[esp],xmm1
+ paddq xmm1,xmm1
+ pand xmm7,xmm3
+ pxor xmm7,xmm1
+ movdqu xmm2,XMMWORD PTR [esi]
+ movdqu xmm3,XMMWORD PTR 16[esi]
+ movdqu xmm4,XMMWORD PTR 32[esi]
+ pxor xmm2,XMMWORD PTR [esp]
+ movdqu xmm5,XMMWORD PTR 48[esi]
+ pxor xmm3,XMMWORD PTR 16[esp]
+ movdqu xmm6,XMMWORD PTR 64[esi]
+ pxor xmm4,XMMWORD PTR 32[esp]
+ lea esi,DWORD PTR 80[esi]
+ pxor xmm5,XMMWORD PTR 48[esp]
+ movdqa XMMWORD PTR 64[esp],xmm7
+ pxor xmm6,xmm7
+ call __aesni_decrypt6
+ movaps xmm1,XMMWORD PTR 64[esp]
+ xorps xmm2,XMMWORD PTR [esp]
+ xorps xmm3,XMMWORD PTR 16[esp]
+ xorps xmm4,XMMWORD PTR 32[esp]
+ movups XMMWORD PTR [edi],xmm2
+ xorps xmm5,XMMWORD PTR 48[esp]
+ movups XMMWORD PTR 16[edi],xmm3
+ xorps xmm6,xmm1
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ movups XMMWORD PTR 64[edi],xmm6
+ lea edi,DWORD PTR 80[edi]
+ jmp $L063xts_dec_done
+ALIGN 16
+$L059xts_dec_one:
+ movups xmm2,XMMWORD PTR [esi]
+ lea esi,DWORD PTR 16[esi]
+ xorps xmm2,xmm5
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L064dec1_loop_12:
+DB 102,15,56,222,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L064dec1_loop_12
+DB 102,15,56,223,209
+ xorps xmm2,xmm5
+ movups XMMWORD PTR [edi],xmm2
+ lea edi,DWORD PTR 16[edi]
+ movdqa xmm1,xmm5
+ jmp $L063xts_dec_done
+ALIGN 16
+$L060xts_dec_two:
+ movaps xmm6,xmm1
+ movups xmm2,XMMWORD PTR [esi]
+ movups xmm3,XMMWORD PTR 16[esi]
+ lea esi,DWORD PTR 32[esi]
+ xorps xmm2,xmm5
+ xorps xmm3,xmm6
+ call __aesni_decrypt3
+ xorps xmm2,xmm5
+ xorps xmm3,xmm6
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ lea edi,DWORD PTR 32[edi]
+ movdqa xmm1,xmm6
+ jmp $L063xts_dec_done
+ALIGN 16
+$L061xts_dec_three:
+ movaps xmm7,xmm1
+ movups xmm2,XMMWORD PTR [esi]
+ movups xmm3,XMMWORD PTR 16[esi]
+ movups xmm4,XMMWORD PTR 32[esi]
+ lea esi,DWORD PTR 48[esi]
+ xorps xmm2,xmm5
+ xorps xmm3,xmm6
+ xorps xmm4,xmm7
+ call __aesni_decrypt3
+ xorps xmm2,xmm5
+ xorps xmm3,xmm6
+ xorps xmm4,xmm7
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ lea edi,DWORD PTR 48[edi]
+ movdqa xmm1,xmm7
+ jmp $L063xts_dec_done
+ALIGN 16
+$L062xts_dec_four:
+ movaps xmm6,xmm1
+ movups xmm2,XMMWORD PTR [esi]
+ movups xmm3,XMMWORD PTR 16[esi]
+ movups xmm4,XMMWORD PTR 32[esi]
+ xorps xmm2,XMMWORD PTR [esp]
+ movups xmm5,XMMWORD PTR 48[esi]
+ lea esi,DWORD PTR 64[esi]
+ xorps xmm3,XMMWORD PTR 16[esp]
+ xorps xmm4,xmm7
+ xorps xmm5,xmm6
+ call __aesni_decrypt4
+ xorps xmm2,XMMWORD PTR [esp]
+ xorps xmm3,XMMWORD PTR 16[esp]
+ xorps xmm4,xmm7
+ movups XMMWORD PTR [edi],xmm2
+ xorps xmm5,xmm6
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ lea edi,DWORD PTR 64[edi]
+ movdqa xmm1,xmm6
+ jmp $L063xts_dec_done
+ALIGN 16
+$L058xts_dec_done6x:
+ mov eax,DWORD PTR 112[esp]
+ and eax,15
+ jz $L065xts_dec_ret
+ mov DWORD PTR 112[esp],eax
+ jmp $L066xts_dec_only_one_more
+ALIGN 16
+$L063xts_dec_done:
+ mov eax,DWORD PTR 112[esp]
+ pxor xmm0,xmm0
+ and eax,15
+ jz $L065xts_dec_ret
+ pcmpgtd xmm0,xmm1
+ mov DWORD PTR 112[esp],eax
+ pshufd xmm2,xmm0,19
+ pxor xmm0,xmm0
+ movdqa xmm3,XMMWORD PTR 96[esp]
+ paddq xmm1,xmm1
+ pand xmm2,xmm3
+ pcmpgtd xmm0,xmm1
+ pxor xmm1,xmm2
+$L066xts_dec_only_one_more:
+ pshufd xmm5,xmm0,19
+ movdqa xmm6,xmm1
+ paddq xmm1,xmm1
+ pand xmm5,xmm3
+ pxor xmm5,xmm1
+ mov edx,ebp
+ mov ecx,ebx
+ movups xmm2,XMMWORD PTR [esi]
+ xorps xmm2,xmm5
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L067dec1_loop_13:
+DB 102,15,56,222,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L067dec1_loop_13
+DB 102,15,56,223,209
+ xorps xmm2,xmm5
+ movups XMMWORD PTR [edi],xmm2
+$L068xts_dec_steal:
+ movzx ecx,BYTE PTR 16[esi]
+ movzx edx,BYTE PTR [edi]
+ lea esi,DWORD PTR 1[esi]
+ mov BYTE PTR [edi],cl
+ mov BYTE PTR 16[edi],dl
+ lea edi,DWORD PTR 1[edi]
+ sub eax,1
+ jnz $L068xts_dec_steal
+ sub edi,DWORD PTR 112[esp]
+ mov edx,ebp
+ mov ecx,ebx
+ movups xmm2,XMMWORD PTR [edi]
+ xorps xmm2,xmm6
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L069dec1_loop_14:
+DB 102,15,56,222,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L069dec1_loop_14
+DB 102,15,56,223,209
+ xorps xmm2,xmm6
+ movups XMMWORD PTR [edi],xmm2
+$L065xts_dec_ret:
+ mov esp,DWORD PTR 116[esp]
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+_aesni_xts_decrypt ENDP
+ALIGN 16
+_aesni_cbc_encrypt PROC PUBLIC
+$L_aesni_cbc_encrypt_begin::
+ push ebp
+ push ebx
+ push esi
+ push edi
+ mov esi,DWORD PTR 20[esp]
+ mov ebx,esp
+ mov edi,DWORD PTR 24[esp]
+ sub ebx,24
+ mov eax,DWORD PTR 28[esp]
+ and ebx,-16
+ mov edx,DWORD PTR 32[esp]
+ mov ebp,DWORD PTR 36[esp]
+ test eax,eax
+ jz $L070cbc_abort
+ cmp DWORD PTR 40[esp],0
+ xchg ebx,esp
+ movups xmm7,XMMWORD PTR [ebp]
+ mov ecx,DWORD PTR 240[edx]
+ mov ebp,edx
+ mov DWORD PTR 16[esp],ebx
+ mov ebx,ecx
+ je $L071cbc_decrypt
+ movaps xmm2,xmm7
+ cmp eax,16
+ jb $L072cbc_enc_tail
+ sub eax,16
+ jmp $L073cbc_enc_loop
+ALIGN 16
+$L073cbc_enc_loop:
+ movups xmm7,XMMWORD PTR [esi]
+ lea esi,DWORD PTR 16[esi]
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ xorps xmm7,xmm0
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm7
+$L074enc1_loop_15:
+DB 102,15,56,220,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L074enc1_loop_15
+DB 102,15,56,221,209
+ mov ecx,ebx
+ mov edx,ebp
+ movups XMMWORD PTR [edi],xmm2
+ lea edi,DWORD PTR 16[edi]
+ sub eax,16
+ jnc $L073cbc_enc_loop
+ add eax,16
+ jnz $L072cbc_enc_tail
+ movaps xmm7,xmm2
+ jmp $L075cbc_ret
+$L072cbc_enc_tail:
+ mov ecx,eax
+DD 2767451785
+ mov ecx,16
+ sub ecx,eax
+ xor eax,eax
+DD 2868115081
+ lea edi,DWORD PTR [edi-16]
+ mov ecx,ebx
+ mov esi,edi
+ mov edx,ebp
+ jmp $L073cbc_enc_loop
+ALIGN 16
+$L071cbc_decrypt:
+ cmp eax,80
+ jbe $L076cbc_dec_tail
+ movaps XMMWORD PTR [esp],xmm7
+ sub eax,80
+ jmp $L077cbc_dec_loop6_enter
+ALIGN 16
+$L078cbc_dec_loop6:
+ movaps XMMWORD PTR [esp],xmm0
+ movups XMMWORD PTR [edi],xmm7
+ lea edi,DWORD PTR 16[edi]
+$L077cbc_dec_loop6_enter:
+ movdqu xmm2,XMMWORD PTR [esi]
+ movdqu xmm3,XMMWORD PTR 16[esi]
+ movdqu xmm4,XMMWORD PTR 32[esi]
+ movdqu xmm5,XMMWORD PTR 48[esi]
+ movdqu xmm6,XMMWORD PTR 64[esi]
+ movdqu xmm7,XMMWORD PTR 80[esi]
+ call __aesni_decrypt6
+ movups xmm1,XMMWORD PTR [esi]
+ movups xmm0,XMMWORD PTR 16[esi]
+ xorps xmm2,XMMWORD PTR [esp]
+ xorps xmm3,xmm1
+ movups xmm1,XMMWORD PTR 32[esi]
+ xorps xmm4,xmm0
+ movups xmm0,XMMWORD PTR 48[esi]
+ xorps xmm5,xmm1
+ movups xmm1,XMMWORD PTR 64[esi]
+ xorps xmm6,xmm0
+ movups xmm0,XMMWORD PTR 80[esi]
+ xorps xmm7,xmm1
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ lea esi,DWORD PTR 96[esi]
+ movups XMMWORD PTR 32[edi],xmm4
+ mov ecx,ebx
+ movups XMMWORD PTR 48[edi],xmm5
+ mov edx,ebp
+ movups XMMWORD PTR 64[edi],xmm6
+ lea edi,DWORD PTR 80[edi]
+ sub eax,96
+ ja $L078cbc_dec_loop6
+ movaps xmm2,xmm7
+ movaps xmm7,xmm0
+ add eax,80
+ jle $L079cbc_dec_tail_collected
+ movups XMMWORD PTR [edi],xmm2
+ lea edi,DWORD PTR 16[edi]
+$L076cbc_dec_tail:
+ movups xmm2,XMMWORD PTR [esi]
+ movaps xmm6,xmm2
+ cmp eax,16
+ jbe $L080cbc_dec_one
+ movups xmm3,XMMWORD PTR 16[esi]
+ movaps xmm5,xmm3
+ cmp eax,32
+ jbe $L081cbc_dec_two
+ movups xmm4,XMMWORD PTR 32[esi]
+ cmp eax,48
+ jbe $L082cbc_dec_three
+ movups xmm5,XMMWORD PTR 48[esi]
+ cmp eax,64
+ jbe $L083cbc_dec_four
+ movups xmm6,XMMWORD PTR 64[esi]
+ movaps XMMWORD PTR [esp],xmm7
+ movups xmm2,XMMWORD PTR [esi]
+ xorps xmm7,xmm7
+ call __aesni_decrypt6
+ movups xmm1,XMMWORD PTR [esi]
+ movups xmm0,XMMWORD PTR 16[esi]
+ xorps xmm2,XMMWORD PTR [esp]
+ xorps xmm3,xmm1
+ movups xmm1,XMMWORD PTR 32[esi]
+ xorps xmm4,xmm0
+ movups xmm0,XMMWORD PTR 48[esi]
+ xorps xmm5,xmm1
+ movups xmm7,XMMWORD PTR 64[esi]
+ xorps xmm6,xmm0
+ movups XMMWORD PTR [edi],xmm2
+ movups XMMWORD PTR 16[edi],xmm3
+ movups XMMWORD PTR 32[edi],xmm4
+ movups XMMWORD PTR 48[edi],xmm5
+ lea edi,DWORD PTR 64[edi]
+ movaps xmm2,xmm6
+ sub eax,80
+ jmp $L079cbc_dec_tail_collected
+ALIGN 16
+$L080cbc_dec_one:
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR 16[edx]
+ lea edx,DWORD PTR 32[edx]
+ xorps xmm2,xmm0
+$L084dec1_loop_16:
+DB 102,15,56,222,209
+ dec ecx
+ movups xmm1,XMMWORD PTR [edx]
+ lea edx,DWORD PTR 16[edx]
+ jnz $L084dec1_loop_16
+DB 102,15,56,223,209
+ xorps xmm2,xmm7
+ movaps xmm7,xmm6
+ sub eax,16
+ jmp $L079cbc_dec_tail_collected
+ALIGN 16
+$L081cbc_dec_two:
+ xorps xmm4,xmm4
+ call __aesni_decrypt3
+ xorps xmm2,xmm7
+ xorps xmm3,xmm6
+ movups XMMWORD PTR [edi],xmm2
+ movaps xmm2,xmm3
+ lea edi,DWORD PTR 16[edi]
+ movaps xmm7,xmm5
+ sub eax,32
+ jmp $L079cbc_dec_tail_collected
+ALIGN 16
+$L082cbc_dec_three:
+ call __aesni_decrypt3
+ xorps xmm2,xmm7
+ xorps xmm3,xmm6
+ xorps xmm4,xmm5
+ movups XMMWORD PTR [edi],xmm2
+ movaps xmm2,xmm4
+ movups XMMWORD PTR 16[edi],xmm3
+ lea edi,DWORD PTR 32[edi]
+ movups xmm7,XMMWORD PTR 32[esi]
+ sub eax,48
+ jmp $L079cbc_dec_tail_collected
+ALIGN 16
+$L083cbc_dec_four:
+ call __aesni_decrypt4
+ movups xmm1,XMMWORD PTR 16[esi]
+ movups xmm0,XMMWORD PTR 32[esi]
+ xorps xmm2,xmm7
+ movups xmm7,XMMWORD PTR 48[esi]
+ xorps xmm3,xmm6
+ movups XMMWORD PTR [edi],xmm2
+ xorps xmm4,xmm1
+ movups XMMWORD PTR 16[edi],xmm3
+ xorps xmm5,xmm0
+ movups XMMWORD PTR 32[edi],xmm4
+ lea edi,DWORD PTR 48[edi]
+ movaps xmm2,xmm5
+ sub eax,64
+$L079cbc_dec_tail_collected:
+ and eax,15
+ jnz $L085cbc_dec_tail_partial
+ movups XMMWORD PTR [edi],xmm2
+ jmp $L075cbc_ret
+ALIGN 16
+$L085cbc_dec_tail_partial:
+ movaps XMMWORD PTR [esp],xmm2
+ mov ecx,16
+ mov esi,esp
+ sub ecx,eax
+DD 2767451785
+$L075cbc_ret:
+ mov esp,DWORD PTR 16[esp]
+ mov ebp,DWORD PTR 36[esp]
+ movups XMMWORD PTR [ebp],xmm7
+$L070cbc_abort:
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+_aesni_cbc_encrypt ENDP
+ALIGN 16
+__aesni_set_encrypt_key PROC PRIVATE
+ test eax,eax
+ jz $L086bad_pointer
+ test edx,edx
+ jz $L086bad_pointer
+ movups xmm0,XMMWORD PTR [eax]
+ xorps xmm4,xmm4
+ lea edx,DWORD PTR 16[edx]
+ cmp ecx,256
+ je $L08714rounds
+ cmp ecx,192
+ je $L08812rounds
+ cmp ecx,128
+ jne $L089bad_keybits
+ALIGN 16
+$L09010rounds:
+ mov ecx,9
+ movups XMMWORD PTR [edx-16],xmm0
+DB 102,15,58,223,200,1
+ call $L091key_128_cold
+DB 102,15,58,223,200,2
+ call $L092key_128
+DB 102,15,58,223,200,4
+ call $L092key_128
+DB 102,15,58,223,200,8
+ call $L092key_128
+DB 102,15,58,223,200,16
+ call $L092key_128
+DB 102,15,58,223,200,32
+ call $L092key_128
+DB 102,15,58,223,200,64
+ call $L092key_128
+DB 102,15,58,223,200,128
+ call $L092key_128
+DB 102,15,58,223,200,27
+ call $L092key_128
+DB 102,15,58,223,200,54
+ call $L092key_128
+ movups XMMWORD PTR [edx],xmm0
+ mov DWORD PTR 80[edx],ecx
+ xor eax,eax
+ ret
+ALIGN 16
+$L092key_128:
+ movups XMMWORD PTR [edx],xmm0
+ lea edx,DWORD PTR 16[edx]
+$L091key_128_cold:
+ shufps xmm4,xmm0,16
+ xorps xmm0,xmm4
+ shufps xmm4,xmm0,140
+ xorps xmm0,xmm4
+ shufps xmm1,xmm1,255
+ xorps xmm0,xmm1
+ ret
+ALIGN 16
+$L08812rounds:
+ movq xmm2,QWORD PTR 16[eax]
+ mov ecx,11
+ movups XMMWORD PTR [edx-16],xmm0
+DB 102,15,58,223,202,1
+ call $L093key_192a_cold
+DB 102,15,58,223,202,2
+ call $L094key_192b
+DB 102,15,58,223,202,4
+ call $L095key_192a
+DB 102,15,58,223,202,8
+ call $L094key_192b
+DB 102,15,58,223,202,16
+ call $L095key_192a
+DB 102,15,58,223,202,32
+ call $L094key_192b
+DB 102,15,58,223,202,64
+ call $L095key_192a
+DB 102,15,58,223,202,128
+ call $L094key_192b
+ movups XMMWORD PTR [edx],xmm0
+ mov DWORD PTR 48[edx],ecx
+ xor eax,eax
+ ret
+ALIGN 16
+$L095key_192a:
+ movups XMMWORD PTR [edx],xmm0
+ lea edx,DWORD PTR 16[edx]
+ALIGN 16
+$L093key_192a_cold:
+ movaps xmm5,xmm2
+$L096key_192b_warm:
+ shufps xmm4,xmm0,16
+ movdqa xmm3,xmm2
+ xorps xmm0,xmm4
+ shufps xmm4,xmm0,140
+ pslldq xmm3,4
+ xorps xmm0,xmm4
+ pshufd xmm1,xmm1,85
+ pxor xmm2,xmm3
+ pxor xmm0,xmm1
+ pshufd xmm3,xmm0,255
+ pxor xmm2,xmm3
+ ret
+ALIGN 16
+$L094key_192b:
+ movaps xmm3,xmm0
+ shufps xmm5,xmm0,68
+ movups XMMWORD PTR [edx],xmm5
+ shufps xmm3,xmm2,78
+ movups XMMWORD PTR 16[edx],xmm3
+ lea edx,DWORD PTR 32[edx]
+ jmp $L096key_192b_warm
+ALIGN 16
+$L08714rounds:
+ movups xmm2,XMMWORD PTR 16[eax]
+ mov ecx,13
+ lea edx,DWORD PTR 16[edx]
+ movups XMMWORD PTR [edx-32],xmm0
+ movups XMMWORD PTR [edx-16],xmm2
+DB 102,15,58,223,202,1
+ call $L097key_256a_cold
+DB 102,15,58,223,200,1
+ call $L098key_256b
+DB 102,15,58,223,202,2
+ call $L099key_256a
+DB 102,15,58,223,200,2
+ call $L098key_256b
+DB 102,15,58,223,202,4
+ call $L099key_256a
+DB 102,15,58,223,200,4
+ call $L098key_256b
+DB 102,15,58,223,202,8
+ call $L099key_256a
+DB 102,15,58,223,200,8
+ call $L098key_256b
+DB 102,15,58,223,202,16
+ call $L099key_256a
+DB 102,15,58,223,200,16
+ call $L098key_256b
+DB 102,15,58,223,202,32
+ call $L099key_256a
+DB 102,15,58,223,200,32
+ call $L098key_256b
+DB 102,15,58,223,202,64
+ call $L099key_256a
+ movups XMMWORD PTR [edx],xmm0
+ mov DWORD PTR 16[edx],ecx
+ xor eax,eax
+ ret
+ALIGN 16
+$L099key_256a:
+ movups XMMWORD PTR [edx],xmm2
+ lea edx,DWORD PTR 16[edx]
+$L097key_256a_cold:
+ shufps xmm4,xmm0,16
+ xorps xmm0,xmm4
+ shufps xmm4,xmm0,140
+ xorps xmm0,xmm4
+ shufps xmm1,xmm1,255
+ xorps xmm0,xmm1
+ ret
+ALIGN 16
+$L098key_256b:
+ movups XMMWORD PTR [edx],xmm0
+ lea edx,DWORD PTR 16[edx]
+ shufps xmm4,xmm2,16
+ xorps xmm2,xmm4
+ shufps xmm4,xmm2,140
+ xorps xmm2,xmm4
+ shufps xmm1,xmm1,170
+ xorps xmm2,xmm1
+ ret
+ALIGN 4
+$L086bad_pointer:
+ mov eax,-1
+ ret
+ALIGN 4
+$L089bad_keybits:
+ mov eax,-2
+ ret
+__aesni_set_encrypt_key ENDP
+ALIGN 16
+_aesni_set_encrypt_key PROC PUBLIC
+$L_aesni_set_encrypt_key_begin::
+ mov eax,DWORD PTR 4[esp]
+ mov ecx,DWORD PTR 8[esp]
+ mov edx,DWORD PTR 12[esp]
+ call __aesni_set_encrypt_key
+ ret
+_aesni_set_encrypt_key ENDP
+ALIGN 16
+_aesni_set_decrypt_key PROC PUBLIC
+$L_aesni_set_decrypt_key_begin::
+ mov eax,DWORD PTR 4[esp]
+ mov ecx,DWORD PTR 8[esp]
+ mov edx,DWORD PTR 12[esp]
+ call __aesni_set_encrypt_key
+ mov edx,DWORD PTR 12[esp]
+ shl ecx,4
+ test eax,eax
+ jnz $L100dec_key_ret
+ lea eax,DWORD PTR 16[ecx*1+edx]
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR [eax]
+ movups XMMWORD PTR [eax],xmm0
+ movups XMMWORD PTR [edx],xmm1
+ lea edx,DWORD PTR 16[edx]
+ lea eax,DWORD PTR [eax-16]
+$L101dec_key_inverse:
+ movups xmm0,XMMWORD PTR [edx]
+ movups xmm1,XMMWORD PTR [eax]
+DB 102,15,56,219,192
+DB 102,15,56,219,201
+ lea edx,DWORD PTR 16[edx]
+ lea eax,DWORD PTR [eax-16]
+ movups XMMWORD PTR 16[eax],xmm0
+ movups XMMWORD PTR [edx-16],xmm1
+ cmp eax,edx
+ ja $L101dec_key_inverse
+ movups xmm0,XMMWORD PTR [edx]
+DB 102,15,56,219,192
+ movups XMMWORD PTR [edx],xmm0
+ xor eax,eax
+$L100dec_key_ret:
+ ret
+_aesni_set_decrypt_key ENDP
+DB 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69
+DB 83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83
+DB 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
+DB 115,108,46,111,114,103,62,0
+.text$ ENDS
+END
diff --git a/deps/openssl/asm/x86-win32-masm/bf/bf-686.asm b/deps/openssl/asm/x86-win32-masm/bf/bf-686.asm
index a802e7292..288317967 100644
--- a/deps/openssl/asm/x86-win32-masm/bf/bf-686.asm
+++ b/deps/openssl/asm/x86-win32-masm/bf/bf-686.asm
@@ -2,7 +2,7 @@ TITLE bf-686.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
diff --git a/deps/openssl/asm/x86-win32-masm/bn/x86-mont.asm b/deps/openssl/asm/x86-win32-masm/bn/x86-mont.asm
index eaad4a073..031be4e7e 100644
--- a/deps/openssl/asm/x86-win32-masm/bn/x86-mont.asm
+++ b/deps/openssl/asm/x86-win32-masm/bn/x86-mont.asm
@@ -2,7 +2,7 @@ TITLE ../openssl/crypto/bn/asm/x86-mont.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
diff --git a/deps/openssl/asm/x86-win32-masm/bn/x86.asm b/deps/openssl/asm/x86-win32-masm/bn/x86.asm
index d7051fa4e..2e7a0d4aa 100644
--- a/deps/openssl/asm/x86-win32-masm/bn/x86.asm
+++ b/deps/openssl/asm/x86-win32-masm/bn/x86.asm
@@ -2,7 +2,7 @@ TITLE ../openssl/crypto/bn/asm/x86.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
diff --git a/deps/openssl/asm/x86-win32-masm/camellia/cmll-x86.asm b/deps/openssl/asm/x86-win32-masm/camellia/cmll-x86.asm
index acdf6a2f8..e32d28135 100644
--- a/deps/openssl/asm/x86-win32-masm/camellia/cmll-x86.asm
+++ b/deps/openssl/asm/x86-win32-masm/camellia/cmll-x86.asm
@@ -2,7 +2,7 @@ TITLE cmll-586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
@@ -1532,8 +1532,8 @@ $L013done:
ret
_Camellia_Ekeygen ENDP
ALIGN 16
-_Camellia_set_key PROC PUBLIC
-$L_Camellia_set_key_begin::
+_private_Camellia_set_key PROC PUBLIC
+$L_private_Camellia_set_key_begin::
push ebx
mov ecx,DWORD PTR 8[esp]
mov ebx,DWORD PTR 12[esp]
@@ -1563,7 +1563,7 @@ ALIGN 4
$L014done:
pop ebx
ret
-_Camellia_set_key ENDP
+_private_Camellia_set_key ENDP
ALIGN 64
$LCamellia_SIGMA::
DD 2694735487,1003262091,3061508184,1286239154,3337565999,3914302142,1426019237,4057165596,283453434,3731369245,2958461122,3018244605,0,0,0,0
diff --git a/deps/openssl/asm/x86-win32-masm/cast/cast-586.asm b/deps/openssl/asm/x86-win32-masm/cast/cast-586.asm
index 1f2f0708a..6f85c34d2 100644
--- a/deps/openssl/asm/x86-win32-masm/cast/cast-586.asm
+++ b/deps/openssl/asm/x86-win32-masm/cast/cast-586.asm
@@ -2,7 +2,7 @@ TITLE cast-586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
diff --git a/deps/openssl/asm/x86-win32-masm/des/crypt586.asm b/deps/openssl/asm/x86-win32-masm/des/crypt586.asm
index 24e474dfc..4c82c7a26 100644
--- a/deps/openssl/asm/x86-win32-masm/des/crypt586.asm
+++ b/deps/openssl/asm/x86-win32-masm/des/crypt586.asm
@@ -2,7 +2,7 @@ TITLE crypt586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
diff --git a/deps/openssl/asm/x86-win32-masm/des/des-586.asm b/deps/openssl/asm/x86-win32-masm/des/des-586.asm
index 3c630daff..24f19a660 100644
--- a/deps/openssl/asm/x86-win32-masm/des/des-586.asm
+++ b/deps/openssl/asm/x86-win32-masm/des/des-586.asm
@@ -2,7 +2,7 @@ TITLE des-586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
diff --git a/deps/openssl/asm/x86-win32-masm/md5/md5-586.asm b/deps/openssl/asm/x86-win32-masm/md5/md5-586.asm
index c8edae762..8e263de0f 100644
--- a/deps/openssl/asm/x86-win32-masm/md5/md5-586.asm
+++ b/deps/openssl/asm/x86-win32-masm/md5/md5-586.asm
@@ -2,7 +2,7 @@ TITLE ../openssl/crypto/md5/asm/md5-586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
diff --git a/deps/openssl/asm/x86-win32-masm/rc4/rc4-586.asm b/deps/openssl/asm/x86-win32-masm/rc4/rc4-586.asm
index 3eb66f735..d17909091 100644
--- a/deps/openssl/asm/x86-win32-masm/rc4/rc4-586.asm
+++ b/deps/openssl/asm/x86-win32-masm/rc4/rc4-586.asm
@@ -2,7 +2,14 @@ TITLE rc4-586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
+.XMM
+IF @Version LT 800
+XMMWORD STRUCT 16
+DQ 2 dup (?)
+XMMWORD ENDS
+ENDIF
+
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
@@ -10,6 +17,7 @@ IF @Version LT 800
ELSE
.text$ SEGMENT ALIGN(64) 'CODE'
ENDIF
+;EXTERN _OPENSSL_ia32cap_P:NEAR
ALIGN 16
_RC4 PROC PUBLIC
$L_RC4_begin::
@@ -37,11 +45,146 @@ $L_RC4_begin::
mov ecx,DWORD PTR [eax*4+edi]
and edx,-4
jz $L002loop1
- lea edx,DWORD PTR [edx*1+esi-4]
- mov DWORD PTR 28[esp],edx
+ test edx,-8
mov DWORD PTR 32[esp],ebp
+ jz $L003go4loop4
+ lea ebp,DWORD PTR _OPENSSL_ia32cap_P
+ bt DWORD PTR [ebp],26
+ jnc $L003go4loop4
+ mov ebp,DWORD PTR 32[esp]
+ and edx,-8
+ lea edx,DWORD PTR [edx*1+esi-8]
+ mov DWORD PTR [edi-4],edx
+ add bl,cl
+ mov edx,DWORD PTR [ebx*4+edi]
+ mov DWORD PTR [ebx*4+edi],ecx
+ mov DWORD PTR [eax*4+edi],edx
+ inc eax
+ add edx,ecx
+ movzx eax,al
+ movzx edx,dl
+ movq mm0,QWORD PTR [esi]
+ mov ecx,DWORD PTR [eax*4+edi]
+ movd mm2,DWORD PTR [edx*4+edi]
+ jmp $L004loop_mmx_enter
+ALIGN 16
+$L005loop_mmx:
+ add bl,cl
+ psllq mm1,56
+ mov edx,DWORD PTR [ebx*4+edi]
+ mov DWORD PTR [ebx*4+edi],ecx
+ mov DWORD PTR [eax*4+edi],edx
+ inc eax
+ add edx,ecx
+ movzx eax,al
+ movzx edx,dl
+ pxor mm2,mm1
+ movq mm0,QWORD PTR [esi]
+ movq QWORD PTR [esi*1+ebp-8],mm2
+ mov ecx,DWORD PTR [eax*4+edi]
+ movd mm2,DWORD PTR [edx*4+edi]
+$L004loop_mmx_enter:
+ add bl,cl
+ mov edx,DWORD PTR [ebx*4+edi]
+ mov DWORD PTR [ebx*4+edi],ecx
+ mov DWORD PTR [eax*4+edi],edx
+ inc eax
+ add edx,ecx
+ movzx eax,al
+ movzx edx,dl
+ pxor mm2,mm0
+ mov ecx,DWORD PTR [eax*4+edi]
+ movd mm1,DWORD PTR [edx*4+edi]
+ add bl,cl
+ psllq mm1,8
+ mov edx,DWORD PTR [ebx*4+edi]
+ mov DWORD PTR [ebx*4+edi],ecx
+ mov DWORD PTR [eax*4+edi],edx
+ inc eax
+ add edx,ecx
+ movzx eax,al
+ movzx edx,dl
+ pxor mm2,mm1
+ mov ecx,DWORD PTR [eax*4+edi]
+ movd mm1,DWORD PTR [edx*4+edi]
+ add bl,cl
+ psllq mm1,16
+ mov edx,DWORD PTR [ebx*4+edi]
+ mov DWORD PTR [ebx*4+edi],ecx
+ mov DWORD PTR [eax*4+edi],edx
+ inc eax
+ add edx,ecx
+ movzx eax,al
+ movzx edx,dl
+ pxor mm2,mm1
+ mov ecx,DWORD PTR [eax*4+edi]
+ movd mm1,DWORD PTR [edx*4+edi]
+ add bl,cl
+ psllq mm1,24
+ mov edx,DWORD PTR [ebx*4+edi]
+ mov DWORD PTR [ebx*4+edi],ecx
+ mov DWORD PTR [eax*4+edi],edx
+ inc eax
+ add edx,ecx
+ movzx eax,al
+ movzx edx,dl
+ pxor mm2,mm1
+ mov ecx,DWORD PTR [eax*4+edi]
+ movd mm1,DWORD PTR [edx*4+edi]
+ add bl,cl
+ psllq mm1,32
+ mov edx,DWORD PTR [ebx*4+edi]
+ mov DWORD PTR [ebx*4+edi],ecx
+ mov DWORD PTR [eax*4+edi],edx
+ inc eax
+ add edx,ecx
+ movzx eax,al
+ movzx edx,dl
+ pxor mm2,mm1
+ mov ecx,DWORD PTR [eax*4+edi]
+ movd mm1,DWORD PTR [edx*4+edi]
+ add bl,cl
+ psllq mm1,40
+ mov edx,DWORD PTR [ebx*4+edi]
+ mov DWORD PTR [ebx*4+edi],ecx
+ mov DWORD PTR [eax*4+edi],edx
+ inc eax
+ add edx,ecx
+ movzx eax,al
+ movzx edx,dl
+ pxor mm2,mm1
+ mov ecx,DWORD PTR [eax*4+edi]
+ movd mm1,DWORD PTR [edx*4+edi]
+ add bl,cl
+ psllq mm1,48
+ mov edx,DWORD PTR [ebx*4+edi]
+ mov DWORD PTR [ebx*4+edi],ecx
+ mov DWORD PTR [eax*4+edi],edx
+ inc eax
+ add edx,ecx
+ movzx eax,al
+ movzx edx,dl
+ pxor mm2,mm1
+ mov ecx,DWORD PTR [eax*4+edi]
+ movd mm1,DWORD PTR [edx*4+edi]
+ mov edx,ebx
+ xor ebx,ebx
+ mov bl,dl
+ cmp esi,DWORD PTR [edi-4]
+ lea esi,DWORD PTR 8[esi]
+ jb $L005loop_mmx
+ psllq mm1,56
+ pxor mm2,mm1
+ movq QWORD PTR [esi*1+ebp-8],mm2
+ emms
+ cmp esi,DWORD PTR 24[esp]
+ je $L006done
+ jmp $L002loop1
ALIGN 16
-$L003loop4:
+$L003go4loop4:
+ lea edx,DWORD PTR [edx*1+esi-4]
+ mov DWORD PTR 28[esp],edx
+$L007loop4:
add bl,cl
mov edx,DWORD PTR [ebx*4+edi]
mov DWORD PTR [ebx*4+edi],ecx
@@ -87,9 +230,9 @@ $L003loop4:
mov DWORD PTR [esi*1+ecx],ebp
lea esi,DWORD PTR 4[esi]
mov ecx,DWORD PTR [eax*4+edi]
- jb $L003loop4
+ jb $L007loop4
cmp esi,DWORD PTR 24[esp]
- je $L004done
+ je $L006done
mov ebp,DWORD PTR 32[esp]
ALIGN 16
$L002loop1:
@@ -107,11 +250,11 @@ $L002loop1:
cmp esi,DWORD PTR 24[esp]
mov BYTE PTR [esi*1+ebp-1],dl
jb $L002loop1
- jmp $L004done
+ jmp $L006done
ALIGN 16
$L001RC4_CHAR:
movzx ecx,BYTE PTR [eax*1+edi]
-$L005cloop1:
+$L008cloop1:
add bl,cl
movzx edx,BYTE PTR [ebx*1+edi]
mov BYTE PTR [ebx*1+edi],cl
@@ -124,10 +267,10 @@ $L005cloop1:
movzx ecx,BYTE PTR [eax*1+edi]
cmp esi,DWORD PTR 24[esp]
mov BYTE PTR [esi*1+ebp-1],dl
- jb $L005cloop1
-$L004done:
+ jb $L008cloop1
+$L006done:
dec al
- mov BYTE PTR [edi-4],bl
+ mov DWORD PTR [edi-4],ebx
mov BYTE PTR [edi-8],al
$L000abort:
pop edi
@@ -136,10 +279,9 @@ $L000abort:
pop ebp
ret
_RC4 ENDP
-;EXTERN _OPENSSL_ia32cap_P:NEAR
ALIGN 16
-_RC4_set_key PROC PUBLIC
-$L_RC4_set_key_begin::
+_private_RC4_set_key PROC PUBLIC
+$L_private_RC4_set_key_begin::
push ebp
push ebx
push esi
@@ -154,53 +296,53 @@ $L_RC4_set_key_begin::
xor eax,eax
mov DWORD PTR [edi-4],ebp
bt DWORD PTR [edx],20
- jc $L006c1stloop
+ jc $L009c1stloop
ALIGN 16
-$L007w1stloop:
+$L010w1stloop:
mov DWORD PTR [eax*4+edi],eax
add al,1
- jnc $L007w1stloop
+ jnc $L010w1stloop
xor ecx,ecx
xor edx,edx
ALIGN 16
-$L008w2ndloop:
+$L011w2ndloop:
mov eax,DWORD PTR [ecx*4+edi]
add dl,BYTE PTR [ebp*1+esi]
add dl,al
add ebp,1
mov ebx,DWORD PTR [edx*4+edi]
- jnz $L009wnowrap
+ jnz $L012wnowrap
mov ebp,DWORD PTR [edi-4]
-$L009wnowrap:
+$L012wnowrap:
mov DWORD PTR [edx*4+edi],eax
mov DWORD PTR [ecx*4+edi],ebx
add cl,1
- jnc $L008w2ndloop
- jmp $L010exit
+ jnc $L011w2ndloop
+ jmp $L013exit
ALIGN 16
-$L006c1stloop:
+$L009c1stloop:
mov BYTE PTR [eax*1+edi],al
add al,1
- jnc $L006c1stloop
+ jnc $L009c1stloop
xor ecx,ecx
xor edx,edx
xor ebx,ebx
ALIGN 16
-$L011c2ndloop:
+$L014c2ndloop:
mov al,BYTE PTR [ecx*1+edi]
add dl,BYTE PTR [ebp*1+esi]
add dl,al
add ebp,1
mov bl,BYTE PTR [edx*1+edi]
- jnz $L012cnowrap
+ jnz $L015cnowrap
mov ebp,DWORD PTR [edi-4]
-$L012cnowrap:
+$L015cnowrap:
mov BYTE PTR [edx*1+edi],al
mov BYTE PTR [ecx*1+edi],bl
add cl,1
- jnc $L011c2ndloop
+ jnc $L014c2ndloop
mov DWORD PTR 256[edi],-1
-$L010exit:
+$L013exit:
xor eax,eax
mov DWORD PTR [edi-8],eax
mov DWORD PTR [edi-4],eax
@@ -209,24 +351,31 @@ $L010exit:
pop ebx
pop ebp
ret
-_RC4_set_key ENDP
+_private_RC4_set_key ENDP
ALIGN 16
_RC4_options PROC PUBLIC
$L_RC4_options_begin::
- call $L013pic_point
-$L013pic_point:
+ call $L016pic_point
+$L016pic_point:
pop eax
- lea eax,DWORD PTR ($L014opts-$L013pic_point)[eax]
+ lea eax,DWORD PTR ($L017opts-$L016pic_point)[eax]
lea edx,DWORD PTR _OPENSSL_ia32cap_P
- bt DWORD PTR [edx],20
- jnc $L015skip
+ mov edx,DWORD PTR [edx]
+ bt edx,20
+ jc $L0181xchar
+ bt edx,26
+ jnc $L019ret
+ add eax,25
+ ret
+$L0181xchar:
add eax,12
-$L015skip:
+$L019ret:
ret
ALIGN 64
-$L014opts:
+$L017opts:
DB 114,99,52,40,52,120,44,105,110,116,41,0
DB 114,99,52,40,49,120,44,99,104,97,114,41,0
+DB 114,99,52,40,56,120,44,109,109,120,41,0
DB 82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
DB 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
DB 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
@@ -234,6 +383,6 @@ ALIGN 64
_RC4_options ENDP
.text$ ENDS
.bss SEGMENT 'BSS'
-COMM _OPENSSL_ia32cap_P:DWORD
+COMM _OPENSSL_ia32cap_P:QWORD
.bss ENDS
END
diff --git a/deps/openssl/asm/x86-win32-masm/rc5/rc5-586.asm b/deps/openssl/asm/x86-win32-masm/rc5/rc5-586.asm
index e699d9173..7ce74110e 100644
--- a/deps/openssl/asm/x86-win32-masm/rc5/rc5-586.asm
+++ b/deps/openssl/asm/x86-win32-masm/rc5/rc5-586.asm
@@ -2,7 +2,7 @@ TITLE rc5-586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
diff --git a/deps/openssl/asm/x86-win32-masm/ripemd/rmd-586.asm b/deps/openssl/asm/x86-win32-masm/ripemd/rmd-586.asm
index 8fa61f8f9..7f6458cef 100644
--- a/deps/openssl/asm/x86-win32-masm/ripemd/rmd-586.asm
+++ b/deps/openssl/asm/x86-win32-masm/ripemd/rmd-586.asm
@@ -2,7 +2,7 @@ TITLE ../openssl/crypto/ripemd/asm/rmd-586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
diff --git a/deps/openssl/asm/x86-win32-masm/sha/sha1-586.asm b/deps/openssl/asm/x86-win32-masm/sha/sha1-586.asm
index ce9f8d5b4..878b1d3b9 100644
--- a/deps/openssl/asm/x86-win32-masm/sha/sha1-586.asm
+++ b/deps/openssl/asm/x86-win32-masm/sha/sha1-586.asm
@@ -2,7 +2,7 @@ TITLE sha1-586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
@@ -20,11 +20,12 @@ $L_sha1_block_data_order_begin::
mov ebp,DWORD PTR 20[esp]
mov esi,DWORD PTR 24[esp]
mov eax,DWORD PTR 28[esp]
- sub esp,64
+ sub esp,76
shl eax,6
add eax,esi
- mov DWORD PTR 92[esp],eax
+ mov DWORD PTR 104[esp],eax
mov edi,DWORD PTR 16[ebp]
+ jmp $L000loop
ALIGN 16
$L000loop:
mov eax,DWORD PTR [esi]
@@ -75,7 +76,7 @@ $L000loop:
mov DWORD PTR 52[esp],ebx
mov DWORD PTR 56[esp],ecx
mov DWORD PTR 60[esp],edx
- mov DWORD PTR 88[esp],esi
+ mov DWORD PTR 100[esp],esi
mov eax,DWORD PTR [ebp]
mov ebx,DWORD PTR 4[ebp]
mov ecx,DWORD PTR 8[ebp]
@@ -86,10 +87,10 @@ $L000loop:
rol ebp,5
xor esi,edx
add ebp,edi
- and esi,ebx
mov edi,DWORD PTR [esp]
- xor esi,edx
+ and esi,ebx
ror ebx,2
+ xor esi,edx
lea ebp,DWORD PTR 1518500249[edi*1+ebp]
add ebp,esi
; 00_15 1
@@ -98,10 +99,10 @@ $L000loop:
rol ebp,5
xor edi,ecx
add ebp,edx
- and edi,eax
mov edx,DWORD PTR 4[esp]
- xor edi,ecx
+ and edi,eax
ror eax,2
+ xor edi,ecx
lea ebp,DWORD PTR 1518500249[edx*1+ebp]
add ebp,edi
; 00_15 2
@@ -110,10 +111,10 @@ $L000loop:
rol ebp,5
xor edx,ebx
add ebp,ecx
- and edx,esi
mov ecx,DWORD PTR 8[esp]
- xor edx,ebx
+ and edx,esi
ror esi,2
+ xor edx,ebx
lea ebp,DWORD PTR 1518500249[ecx*1+ebp]
add ebp,edx
; 00_15 3
@@ -122,10 +123,10 @@ $L000loop:
rol ebp,5
xor ecx,eax
add ebp,ebx
- and ecx,edi
mov ebx,DWORD PTR 12[esp]
- xor ecx,eax
+ and ecx,edi
ror edi,2
+ xor ecx,eax
lea ebp,DWORD PTR 1518500249[ebx*1+ebp]
add ebp,ecx
; 00_15 4
@@ -134,10 +135,10 @@ $L000loop:
rol ebp,5
xor ebx,esi
add ebp,eax
- and ebx,edx
mov eax,DWORD PTR 16[esp]
- xor ebx,esi
+ and ebx,edx
ror edx,2
+ xor ebx,esi
lea ebp,DWORD PTR 1518500249[eax*1+ebp]
add ebp,ebx
; 00_15 5
@@ -146,10 +147,10 @@ $L000loop:
rol ebp,5
xor eax,edi
add ebp,esi
- and eax,ecx
mov esi,DWORD PTR 20[esp]
- xor eax,edi
+ and eax,ecx
ror ecx,2
+ xor eax,edi
lea ebp,DWORD PTR 1518500249[esi*1+ebp]
add ebp,eax
; 00_15 6
@@ -158,10 +159,10 @@ $L000loop:
rol ebp,5
xor esi,edx
add ebp,edi
- and esi,ebx
mov edi,DWORD PTR 24[esp]
- xor esi,edx
+ and esi,ebx
ror ebx,2
+ xor esi,edx
lea ebp,DWORD PTR 1518500249[edi*1+ebp]
add ebp,esi
; 00_15 7
@@ -170,10 +171,10 @@ $L000loop:
rol ebp,5
xor edi,ecx
add ebp,edx
- and edi,eax
mov edx,DWORD PTR 28[esp]
- xor edi,ecx
+ and edi,eax
ror eax,2
+ xor edi,ecx
lea ebp,DWORD PTR 1518500249[edx*1+ebp]
add ebp,edi
; 00_15 8
@@ -182,10 +183,10 @@ $L000loop:
rol ebp,5
xor edx,ebx
add ebp,ecx
- and edx,esi
mov ecx,DWORD PTR 32[esp]
- xor edx,ebx
+ and edx,esi
ror esi,2
+ xor edx,ebx
lea ebp,DWORD PTR 1518500249[ecx*1+ebp]
add ebp,edx
; 00_15 9
@@ -194,10 +195,10 @@ $L000loop:
rol ebp,5
xor ecx,eax
add ebp,ebx
- and ecx,edi
mov ebx,DWORD PTR 36[esp]
- xor ecx,eax
+ and ecx,edi
ror edi,2
+ xor ecx,eax
lea ebp,DWORD PTR 1518500249[ebx*1+ebp]
add ebp,ecx
; 00_15 10
@@ -206,10 +207,10 @@ $L000loop:
rol ebp,5
xor ebx,esi
add ebp,eax
- and ebx,edx
mov eax,DWORD PTR 40[esp]
- xor ebx,esi
+ and ebx,edx
ror edx,2
+ xor ebx,esi
lea ebp,DWORD PTR 1518500249[eax*1+ebp]
add ebp,ebx
; 00_15 11
@@ -218,10 +219,10 @@ $L000loop:
rol ebp,5
xor eax,edi
add ebp,esi
- and eax,ecx
mov esi,DWORD PTR 44[esp]
- xor eax,edi
+ and eax,ecx
ror ecx,2
+ xor eax,edi
lea ebp,DWORD PTR 1518500249[esi*1+ebp]
add ebp,eax
; 00_15 12
@@ -230,10 +231,10 @@ $L000loop:
rol ebp,5
xor esi,edx
add ebp,edi
- and esi,ebx
mov edi,DWORD PTR 48[esp]
- xor esi,edx
+ and esi,ebx
ror ebx,2
+ xor esi,edx
lea ebp,DWORD PTR 1518500249[edi*1+ebp]
add ebp,esi
; 00_15 13
@@ -242,10 +243,10 @@ $L000loop:
rol ebp,5
xor edi,ecx
add ebp,edx
- and edi,eax
mov edx,DWORD PTR 52[esp]
- xor edi,ecx
+ and edi,eax
ror eax,2
+ xor edi,ecx
lea ebp,DWORD PTR 1518500249[edx*1+ebp]
add ebp,edi
; 00_15 14
@@ -254,10 +255,10 @@ $L000loop:
rol ebp,5
xor edx,ebx
add ebp,ecx
- and edx,esi
mov ecx,DWORD PTR 56[esp]
- xor edx,ebx
+ and edx,esi
ror esi,2
+ xor edx,ebx
lea ebp,DWORD PTR 1518500249[ecx*1+ebp]
add ebp,edx
; 00_15 15
@@ -266,1162 +267,1099 @@ $L000loop:
rol ebp,5
xor ecx,eax
add ebp,ebx
- and ecx,edi
mov ebx,DWORD PTR 60[esp]
- xor ecx,eax
+ and ecx,edi
ror edi,2
+ xor ecx,eax
lea ebp,DWORD PTR 1518500249[ebx*1+ebp]
+ mov ebx,DWORD PTR [esp]
add ecx,ebp
; 16_19 16
- mov ebx,DWORD PTR [esp]
mov ebp,edi
xor ebx,DWORD PTR 8[esp]
xor ebp,esi
xor ebx,DWORD PTR 32[esp]
and ebp,edx
- ror edx,2
xor ebx,DWORD PTR 52[esp]
rol ebx,1
xor ebp,esi
+ add eax,ebp
+ mov ebp,ecx
+ ror edx,2
mov DWORD PTR [esp],ebx
+ rol ebp,5
lea ebx,DWORD PTR 1518500249[eax*1+ebx]
- mov eax,ecx
- rol eax,5
+ mov eax,DWORD PTR 4[esp]
add ebx,ebp
- add ebx,eax
; 16_19 17
- mov eax,DWORD PTR 4[esp]
mov ebp,edx
xor eax,DWORD PTR 12[esp]
xor ebp,edi
xor eax,DWORD PTR 36[esp]
and ebp,ecx
- ror ecx,2
xor eax,DWORD PTR 56[esp]
rol eax,1
xor ebp,edi
+ add esi,ebp
+ mov ebp,ebx
+ ror ecx,2
mov DWORD PTR 4[esp],eax
+ rol ebp,5
lea eax,DWORD PTR 1518500249[esi*1+eax]
- mov esi,ebx
- rol esi,5
+ mov esi,DWORD PTR 8[esp]
add eax,ebp
- add eax,esi
; 16_19 18
- mov esi,DWORD PTR 8[esp]
mov ebp,ecx
xor esi,DWORD PTR 16[esp]
xor ebp,edx
xor esi,DWORD PTR 40[esp]
and ebp,ebx
- ror ebx,2
xor esi,DWORD PTR 60[esp]
rol esi,1
xor ebp,edx
+ add edi,ebp
+ mov ebp,eax
+ ror ebx,2
mov DWORD PTR 8[esp],esi
+ rol ebp,5
lea esi,DWORD PTR 1518500249[edi*1+esi]
- mov edi,eax
- rol edi,5
+ mov edi,DWORD PTR 12[esp]
add esi,ebp
- add esi,edi
; 16_19 19
- mov edi,DWORD PTR 12[esp]
mov ebp,ebx
xor edi,DWORD PTR 20[esp]
xor ebp,ecx
xor edi,DWORD PTR 44[esp]
and ebp,eax
- ror eax,2
xor edi,DWORD PTR [esp]
rol edi,1
xor ebp,ecx
+ add edx,ebp
+ mov ebp,esi
+ ror eax,2
mov DWORD PTR 12[esp],edi
+ rol ebp,5
lea edi,DWORD PTR 1518500249[edx*1+edi]
- mov edx,esi
- rol edx,5
+ mov edx,DWORD PTR 16[esp]
add edi,ebp
- add edi,edx
; 20_39 20
mov ebp,esi
- mov edx,DWORD PTR 16[esp]
- ror esi,2
xor edx,DWORD PTR 24[esp]
xor ebp,eax
xor edx,DWORD PTR 48[esp]
xor ebp,ebx
xor edx,DWORD PTR 4[esp]
rol edx,1
- add ebp,ecx
+ add ecx,ebp
+ ror esi,2
+ mov ebp,edi
+ rol ebp,5
mov DWORD PTR 16[esp],edx
- mov ecx,edi
- rol ecx,5
- lea edx,DWORD PTR 1859775393[ebp*1+edx]
- add edx,ecx
+ lea edx,DWORD PTR 1859775393[ecx*1+edx]
+ mov ecx,DWORD PTR 20[esp]
+ add edx,ebp
; 20_39 21
mov ebp,edi
- mov ecx,DWORD PTR 20[esp]
- ror edi,2
xor ecx,DWORD PTR 28[esp]
xor ebp,esi
xor ecx,DWORD PTR 52[esp]
xor ebp,eax
xor ecx,DWORD PTR 8[esp]
rol ecx,1
- add ebp,ebx
+ add ebx,ebp
+ ror edi,2
+ mov ebp,edx
+ rol ebp,5
mov DWORD PTR 20[esp],ecx
- mov ebx,edx
- rol ebx,5
- lea ecx,DWORD PTR 1859775393[ebp*1+ecx]
- add ecx,ebx
+ lea ecx,DWORD PTR 1859775393[ebx*1+ecx]
+ mov ebx,DWORD PTR 24[esp]
+ add ecx,ebp
; 20_39 22
mov ebp,edx
- mov ebx,DWORD PTR 24[esp]
- ror edx,2
xor ebx,DWORD PTR 32[esp]
xor ebp,edi
xor ebx,DWORD PTR 56[esp]
xor ebp,esi
xor ebx,DWORD PTR 12[esp]
rol ebx,1
- add ebp,eax
+ add eax,ebp
+ ror edx,2
+ mov ebp,ecx
+ rol ebp,5
mov DWORD PTR 24[esp],ebx
- mov eax,ecx
- rol eax,5
- lea ebx,DWORD PTR 1859775393[ebp*1+ebx]
- add ebx,eax
+ lea ebx,DWORD PTR 1859775393[eax*1+ebx]
+ mov eax,DWORD PTR 28[esp]
+ add ebx,ebp
; 20_39 23
mov ebp,ecx
- mov eax,DWORD PTR 28[esp]
- ror ecx,2
xor eax,DWORD PTR 36[esp]
xor ebp,edx
xor eax,DWORD PTR 60[esp]
xor ebp,edi
xor eax,DWORD PTR 16[esp]
rol eax,1
- add ebp,esi
+ add esi,ebp
+ ror ecx,2
+ mov ebp,ebx
+ rol ebp,5
mov DWORD PTR 28[esp],eax
- mov esi,ebx
- rol esi,5
- lea eax,DWORD PTR 1859775393[ebp*1+eax]
- add eax,esi
+ lea eax,DWORD PTR 1859775393[esi*1+eax]
+ mov esi,DWORD PTR 32[esp]
+ add eax,ebp
; 20_39 24
mov ebp,ebx
- mov esi,DWORD PTR 32[esp]
- ror ebx,2
xor esi,DWORD PTR 40[esp]
xor ebp,ecx
xor esi,DWORD PTR [esp]
xor ebp,edx
xor esi,DWORD PTR 20[esp]
rol esi,1
- add ebp,edi
+ add edi,ebp
+ ror ebx,2
+ mov ebp,eax
+ rol ebp,5
mov DWORD PTR 32[esp],esi
- mov edi,eax
- rol edi,5
- lea esi,DWORD PTR 1859775393[ebp*1+esi]
- add esi,edi
+ lea esi,DWORD PTR 1859775393[edi*1+esi]
+ mov edi,DWORD PTR 36[esp]
+ add esi,ebp
; 20_39 25
mov ebp,eax
- mov edi,DWORD PTR 36[esp]
- ror eax,2
xor edi,DWORD PTR 44[esp]
xor ebp,ebx
xor edi,DWORD PTR 4[esp]
xor ebp,ecx
xor edi,DWORD PTR 24[esp]
rol edi,1
- add ebp,edx
+ add edx,ebp
+ ror eax,2
+ mov ebp,esi
+ rol ebp,5
mov DWORD PTR 36[esp],edi
- mov edx,esi
- rol edx,5
- lea edi,DWORD PTR 1859775393[ebp*1+edi]
- add edi,edx
+ lea edi,DWORD PTR 1859775393[edx*1+edi]
+ mov edx,DWORD PTR 40[esp]
+ add edi,ebp
; 20_39 26
mov ebp,esi
- mov edx,DWORD PTR 40[esp]
- ror esi,2
xor edx,DWORD PTR 48[esp]
xor ebp,eax
xor edx,DWORD PTR 8[esp]
xor ebp,ebx
xor edx,DWORD PTR 28[esp]
rol edx,1
- add ebp,ecx
+ add ecx,ebp
+ ror esi,2
+ mov ebp,edi
+ rol ebp,5
mov DWORD PTR 40[esp],edx
- mov ecx,edi
- rol ecx,5
- lea edx,DWORD PTR 1859775393[ebp*1+edx]
- add edx,ecx
+ lea edx,DWORD PTR 1859775393[ecx*1+edx]
+ mov ecx,DWORD PTR 44[esp]
+ add edx,ebp
; 20_39 27
mov ebp,edi
- mov ecx,DWORD PTR 44[esp]
- ror edi,2
xor ecx,DWORD PTR 52[esp]
xor ebp,esi
xor ecx,DWORD PTR 12[esp]
xor ebp,eax
xor ecx,DWORD PTR 32[esp]
rol ecx,1
- add ebp,ebx
+ add ebx,ebp
+ ror edi,2
+ mov ebp,edx
+ rol ebp,5
mov DWORD PTR 44[esp],ecx
- mov ebx,edx
- rol ebx,5
- lea ecx,DWORD PTR 1859775393[ebp*1+ecx]
- add ecx,ebx
+ lea ecx,DWORD PTR 1859775393[ebx*1+ecx]
+ mov ebx,DWORD PTR 48[esp]
+ add ecx,ebp
; 20_39 28
mov ebp,edx
- mov ebx,DWORD PTR 48[esp]
- ror edx,2
xor ebx,DWORD PTR 56[esp]
xor ebp,edi
xor ebx,DWORD PTR 16[esp]
xor ebp,esi
xor ebx,DWORD PTR 36[esp]
rol ebx,1
- add ebp,eax
+ add eax,ebp
+ ror edx,2
+ mov ebp,ecx
+ rol ebp,5
mov DWORD PTR 48[esp],ebx
- mov eax,ecx
- rol eax,5
- lea ebx,DWORD PTR 1859775393[ebp*1+ebx]
- add ebx,eax
+ lea ebx,DWORD PTR 1859775393[eax*1+ebx]
+ mov eax,DWORD PTR 52[esp]
+ add ebx,ebp
; 20_39 29
mov ebp,ecx
- mov eax,DWORD PTR 52[esp]
- ror ecx,2
xor eax,DWORD PTR 60[esp]
xor ebp,edx
xor eax,DWORD PTR 20[esp]
xor ebp,edi
xor eax,DWORD PTR 40[esp]
rol eax,1
- add ebp,esi
+ add esi,ebp
+ ror ecx,2
+ mov ebp,ebx
+ rol ebp,5
mov DWORD PTR 52[esp],eax
- mov esi,ebx
- rol esi,5
- lea eax,DWORD PTR 1859775393[ebp*1+eax]
- add eax,esi
+ lea eax,DWORD PTR 1859775393[esi*1+eax]
+ mov esi,DWORD PTR 56[esp]
+ add eax,ebp
; 20_39 30
mov ebp,ebx
- mov esi,DWORD PTR 56[esp]
- ror ebx,2
xor esi,DWORD PTR [esp]
xor ebp,ecx
xor esi,DWORD PTR 24[esp]
xor ebp,edx
xor esi,DWORD PTR 44[esp]
rol esi,1
- add ebp,edi
+ add edi,ebp
+ ror ebx,2
+ mov ebp,eax
+ rol ebp,5
mov DWORD PTR 56[esp],esi
- mov edi,eax
- rol edi,5
- lea esi,DWORD PTR 1859775393[ebp*1+esi]
- add esi,edi
+ lea esi,DWORD PTR 1859775393[edi*1+esi]
+ mov edi,DWORD PTR 60[esp]
+ add esi,ebp
; 20_39 31
mov ebp,eax
- mov edi,DWORD PTR 60[esp]
- ror eax,2
xor edi,DWORD PTR 4[esp]
xor ebp,ebx
xor edi,DWORD PTR 28[esp]
xor ebp,ecx
xor edi,DWORD PTR 48[esp]
rol edi,1
- add ebp,edx
+ add edx,ebp
+ ror eax,2
+ mov ebp,esi
+ rol ebp,5
mov DWORD PTR 60[esp],edi
- mov edx,esi
- rol edx,5
- lea edi,DWORD PTR 1859775393[ebp*1+edi]
- add edi,edx
+ lea edi,DWORD PTR 1859775393[edx*1+edi]
+ mov edx,DWORD PTR [esp]
+ add edi,ebp
; 20_39 32
mov ebp,esi
- mov edx,DWORD PTR [esp]
- ror esi,2
xor edx,DWORD PTR 8[esp]
xor ebp,eax
xor edx,DWORD PTR 32[esp]
xor ebp,ebx
xor edx,DWORD PTR 52[esp]
rol edx,1
- add ebp,ecx
+ add ecx,ebp
+ ror esi,2
+ mov ebp,edi
+ rol ebp,5
mov DWORD PTR [esp],edx
- mov ecx,edi
- rol ecx,5
- lea edx,DWORD PTR 1859775393[ebp*1+edx]
- add edx,ecx
+ lea edx,DWORD PTR 1859775393[ecx*1+edx]
+ mov ecx,DWORD PTR 4[esp]
+ add edx,ebp
; 20_39 33
mov ebp,edi
- mov ecx,DWORD PTR 4[esp]
- ror edi,2
xor ecx,DWORD PTR 12[esp]
xor ebp,esi
xor ecx,DWORD PTR 36[esp]
xor ebp,eax
xor ecx,DWORD PTR 56[esp]
rol ecx,1
- add ebp,ebx
+ add ebx,ebp
+ ror edi,2
+ mov ebp,edx
+ rol ebp,5
mov DWORD PTR 4[esp],ecx
- mov ebx,edx
- rol ebx,5
- lea ecx,DWORD PTR 1859775393[ebp*1+ecx]
- add ecx,ebx
+ lea ecx,DWORD PTR 1859775393[ebx*1+ecx]
+ mov ebx,DWORD PTR 8[esp]
+ add ecx,ebp
; 20_39 34
mov ebp,edx
- mov ebx,DWORD PTR 8[esp]
- ror edx,2
xor ebx,DWORD PTR 16[esp]
xor ebp,edi
xor ebx,DWORD PTR 40[esp]
xor ebp,esi
xor ebx,DWORD PTR 60[esp]
rol ebx,1
- add ebp,eax
+ add eax,ebp
+ ror edx,2
+ mov ebp,ecx
+ rol ebp,5
mov DWORD PTR 8[esp],ebx
- mov eax,ecx
- rol eax,5
- lea ebx,DWORD PTR 1859775393[ebp*1+ebx]
- add ebx,eax
+ lea ebx,DWORD PTR 1859775393[eax*1+ebx]
+ mov eax,DWORD PTR 12[esp]
+ add ebx,ebp
; 20_39 35
mov ebp,ecx
- mov eax,DWORD PTR 12[esp]
- ror ecx,2
xor eax,DWORD PTR 20[esp]
xor ebp,edx
xor eax,DWORD PTR 44[esp]
xor ebp,edi
xor eax,DWORD PTR [esp]
rol eax,1
- add ebp,esi
+ add esi,ebp
+ ror ecx,2
+ mov ebp,ebx
+ rol ebp,5
mov DWORD PTR 12[esp],eax
- mov esi,ebx
- rol esi,5
- lea eax,DWORD PTR 1859775393[ebp*1+eax]
- add eax,esi
+ lea eax,DWORD PTR 1859775393[esi*1+eax]
+ mov esi,DWORD PTR 16[esp]
+ add eax,ebp
; 20_39 36
mov ebp,ebx
- mov esi,DWORD PTR 16[esp]
- ror ebx,2
xor esi,DWORD PTR 24[esp]
xor ebp,ecx
xor esi,DWORD PTR 48[esp]
xor ebp,edx
xor esi,DWORD PTR 4[esp]
rol esi,1
- add ebp,edi
+ add edi,ebp
+ ror ebx,2
+ mov ebp,eax
+ rol ebp,5
mov DWORD PTR 16[esp],esi
- mov edi,eax
- rol edi,5
- lea esi,DWORD PTR 1859775393[ebp*1+esi]
- add esi,edi
+ lea esi,DWORD PTR 1859775393[edi*1+esi]
+ mov edi,DWORD PTR 20[esp]
+ add esi,ebp
; 20_39 37
mov ebp,eax
- mov edi,DWORD PTR 20[esp]
- ror eax,2
xor edi,DWORD PTR 28[esp]
xor ebp,ebx
xor edi,DWORD PTR 52[esp]
xor ebp,ecx
xor edi,DWORD PTR 8[esp]
rol edi,1
- add ebp,edx
+ add edx,ebp
+ ror eax,2
+ mov ebp,esi
+ rol ebp,5
mov DWORD PTR 20[esp],edi
- mov edx,esi
- rol edx,5
- lea edi,DWORD PTR 1859775393[ebp*1+edi]
- add edi,edx
+ lea edi,DWORD PTR 1859775393[edx*1+edi]
+ mov edx,DWORD PTR 24[esp]
+ add edi,ebp
; 20_39 38
mov ebp,esi
- mov edx,DWORD PTR 24[esp]
- ror esi,2
xor edx,DWORD PTR 32[esp]
xor ebp,eax
xor edx,DWORD PTR 56[esp]
xor ebp,ebx
xor edx,DWORD PTR 12[esp]
rol edx,1
- add ebp,ecx
+ add ecx,ebp
+ ror esi,2
+ mov ebp,edi
+ rol ebp,5
mov DWORD PTR 24[esp],edx
- mov ecx,edi
- rol ecx,5
- lea edx,DWORD PTR 1859775393[ebp*1+edx]
- add edx,ecx
+ lea edx,DWORD PTR 1859775393[ecx*1+edx]
+ mov ecx,DWORD PTR 28[esp]
+ add edx,ebp
; 20_39 39
mov ebp,edi
- mov ecx,DWORD PTR 28[esp]
- ror edi,2
xor ecx,DWORD PTR 36[esp]
xor ebp,esi
xor ecx,DWORD PTR 60[esp]
xor ebp,eax
xor ecx,DWORD PTR 16[esp]
rol ecx,1
- add ebp,ebx
+ add ebx,ebp
+ ror edi,2
+ mov ebp,edx
+ rol ebp,5
mov DWORD PTR 28[esp],ecx
- mov ebx,edx
- rol ebx,5
- lea ecx,DWORD PTR 1859775393[ebp*1+ecx]
- add ecx,ebx
- ; 40_59 40
+ lea ecx,DWORD PTR 1859775393[ebx*1+ecx]
mov ebx,DWORD PTR 32[esp]
- mov ebp,DWORD PTR 40[esp]
- xor ebx,ebp
- mov ebp,DWORD PTR [esp]
- xor ebx,ebp
- mov ebp,DWORD PTR 20[esp]
- xor ebx,ebp
- mov ebp,edx
+ add ecx,ebp
+ ; 40_59 40
+ mov ebp,edi
+ xor ebx,DWORD PTR 40[esp]
+ xor ebp,esi
+ xor ebx,DWORD PTR [esp]
+ and ebp,edx
+ xor ebx,DWORD PTR 20[esp]
rol ebx,1
- or ebp,edi
- mov DWORD PTR 32[esp],ebx
- and ebp,esi
- lea ebx,DWORD PTR 2400959708[eax*1+ebx]
- mov eax,edx
+ add ebp,eax
ror edx,2
- and eax,edi
- or ebp,eax
mov eax,ecx
rol eax,5
- add ebx,ebp
+ mov DWORD PTR 32[esp],ebx
+ lea ebx,DWORD PTR 2400959708[ebp*1+ebx]
+ mov ebp,edi
add ebx,eax
- ; 40_59 41
+ and ebp,esi
mov eax,DWORD PTR 36[esp]
- mov ebp,DWORD PTR 44[esp]
- xor eax,ebp
- mov ebp,DWORD PTR 4[esp]
- xor eax,ebp
- mov ebp,DWORD PTR 24[esp]
- xor eax,ebp
- mov ebp,ecx
+ add ebx,ebp
+ ; 40_59 41
+ mov ebp,edx
+ xor eax,DWORD PTR 44[esp]
+ xor ebp,edi
+ xor eax,DWORD PTR 4[esp]
+ and ebp,ecx
+ xor eax,DWORD PTR 24[esp]
rol eax,1
- or ebp,edx
- mov DWORD PTR 36[esp],eax
- and ebp,edi
- lea eax,DWORD PTR 2400959708[esi*1+eax]
- mov esi,ecx
+ add ebp,esi
ror ecx,2
- and esi,edx
- or ebp,esi
mov esi,ebx
rol esi,5
- add eax,ebp
+ mov DWORD PTR 36[esp],eax
+ lea eax,DWORD PTR 2400959708[ebp*1+eax]
+ mov ebp,edx
add eax,esi
- ; 40_59 42
+ and ebp,edi
mov esi,DWORD PTR 40[esp]
- mov ebp,DWORD PTR 48[esp]
- xor esi,ebp
- mov ebp,DWORD PTR 8[esp]
- xor esi,ebp
- mov ebp,DWORD PTR 28[esp]
- xor esi,ebp
- mov ebp,ebx
+ add eax,ebp
+ ; 40_59 42
+ mov ebp,ecx
+ xor esi,DWORD PTR 48[esp]
+ xor ebp,edx
+ xor esi,DWORD PTR 8[esp]
+ and ebp,ebx
+ xor esi,DWORD PTR 28[esp]
rol esi,1
- or ebp,ecx
- mov DWORD PTR 40[esp],esi
- and ebp,edx
- lea esi,DWORD PTR 2400959708[edi*1+esi]
- mov edi,ebx
+ add ebp,edi
ror ebx,2
- and edi,ecx
- or ebp,edi
mov edi,eax
rol edi,5
- add esi,ebp
+ mov DWORD PTR 40[esp],esi
+ lea esi,DWORD PTR 2400959708[ebp*1+esi]
+ mov ebp,ecx
add esi,edi
- ; 40_59 43
+ and ebp,edx
mov edi,DWORD PTR 44[esp]
- mov ebp,DWORD PTR 52[esp]
- xor edi,ebp
- mov ebp,DWORD PTR 12[esp]
- xor edi,ebp
- mov ebp,DWORD PTR 32[esp]
- xor edi,ebp
- mov ebp,eax
+ add esi,ebp
+ ; 40_59 43
+ mov ebp,ebx
+ xor edi,DWORD PTR 52[esp]
+ xor ebp,ecx
+ xor edi,DWORD PTR 12[esp]
+ and ebp,eax
+ xor edi,DWORD PTR 32[esp]
rol edi,1
- or ebp,ebx
- mov DWORD PTR 44[esp],edi
- and ebp,ecx
- lea edi,DWORD PTR 2400959708[edx*1+edi]
- mov edx,eax
+ add ebp,edx
ror eax,2
- and edx,ebx
- or ebp,edx
mov edx,esi
rol edx,5
- add edi,ebp
+ mov DWORD PTR 44[esp],edi
+ lea edi,DWORD PTR 2400959708[ebp*1+edi]
+ mov ebp,ebx
add edi,edx
- ; 40_59 44
+ and ebp,ecx
mov edx,DWORD PTR 48[esp]
- mov ebp,DWORD PTR 56[esp]
- xor edx,ebp
- mov ebp,DWORD PTR 16[esp]
- xor edx,ebp
- mov ebp,DWORD PTR 36[esp]
- xor edx,ebp
- mov ebp,esi
+ add edi,ebp
+ ; 40_59 44
+ mov ebp,eax
+ xor edx,DWORD PTR 56[esp]
+ xor ebp,ebx
+ xor edx,DWORD PTR 16[esp]
+ and ebp,esi
+ xor edx,DWORD PTR 36[esp]
rol edx,1
- or ebp,eax
- mov DWORD PTR 48[esp],edx
- and ebp,ebx
- lea edx,DWORD PTR 2400959708[ecx*1+edx]
- mov ecx,esi
+ add ebp,ecx
ror esi,2
- and ecx,eax
- or ebp,ecx
mov ecx,edi
rol ecx,5
- add edx,ebp
+ mov DWORD PTR 48[esp],edx
+ lea edx,DWORD PTR 2400959708[ebp*1+edx]
+ mov ebp,eax
add edx,ecx
- ; 40_59 45
+ and ebp,ebx
mov ecx,DWORD PTR 52[esp]
- mov ebp,DWORD PTR 60[esp]
- xor ecx,ebp
- mov ebp,DWORD PTR 20[esp]
- xor ecx,ebp
- mov ebp,DWORD PTR 40[esp]
- xor ecx,ebp
- mov ebp,edi
+ add edx,ebp
+ ; 40_59 45
+ mov ebp,esi
+ xor ecx,DWORD PTR 60[esp]
+ xor ebp,eax
+ xor ecx,DWORD PTR 20[esp]
+ and ebp,edi
+ xor ecx,DWORD PTR 40[esp]
rol ecx,1
- or ebp,esi
- mov DWORD PTR 52[esp],ecx
- and ebp,eax
- lea ecx,DWORD PTR 2400959708[ebx*1+ecx]
- mov ebx,edi
+ add ebp,ebx
ror edi,2
- and ebx,esi
- or ebp,ebx
mov ebx,edx
rol ebx,5
- add ecx,ebp
+ mov DWORD PTR 52[esp],ecx
+ lea ecx,DWORD PTR 2400959708[ebp*1+ecx]
+ mov ebp,esi
add ecx,ebx
- ; 40_59 46
+ and ebp,eax
mov ebx,DWORD PTR 56[esp]
- mov ebp,DWORD PTR [esp]
- xor ebx,ebp
- mov ebp,DWORD PTR 24[esp]
- xor ebx,ebp
- mov ebp,DWORD PTR 44[esp]
- xor ebx,ebp
- mov ebp,edx
+ add ecx,ebp
+ ; 40_59 46
+ mov ebp,edi
+ xor ebx,DWORD PTR [esp]
+ xor ebp,esi
+ xor ebx,DWORD PTR 24[esp]
+ and ebp,edx
+ xor ebx,DWORD PTR 44[esp]
rol ebx,1
- or ebp,edi
- mov DWORD PTR 56[esp],ebx
- and ebp,esi
- lea ebx,DWORD PTR 2400959708[eax*1+ebx]
- mov eax,edx
+ add ebp,eax
ror edx,2
- and eax,edi
- or ebp,eax
mov eax,ecx
rol eax,5
- add ebx,ebp
+ mov DWORD PTR 56[esp],ebx
+ lea ebx,DWORD PTR 2400959708[ebp*1+ebx]
+ mov ebp,edi
add ebx,eax
- ; 40_59 47
+ and ebp,esi
mov eax,DWORD PTR 60[esp]
- mov ebp,DWORD PTR 4[esp]
- xor eax,ebp
- mov ebp,DWORD PTR 28[esp]
- xor eax,ebp
- mov ebp,DWORD PTR 48[esp]
- xor eax,ebp
- mov ebp,ecx
+ add ebx,ebp
+ ; 40_59 47
+ mov ebp,edx
+ xor eax,DWORD PTR 4[esp]
+ xor ebp,edi
+ xor eax,DWORD PTR 28[esp]
+ and ebp,ecx
+ xor eax,DWORD PTR 48[esp]
rol eax,1
- or ebp,edx
- mov DWORD PTR 60[esp],eax
- and ebp,edi
- lea eax,DWORD PTR 2400959708[esi*1+eax]
- mov esi,ecx
+ add ebp,esi
ror ecx,2
- and esi,edx
- or ebp,esi
mov esi,ebx
rol esi,5
- add eax,ebp
+ mov DWORD PTR 60[esp],eax
+ lea eax,DWORD PTR 2400959708[ebp*1+eax]
+ mov ebp,edx
add eax,esi
- ; 40_59 48
+ and ebp,edi
mov esi,DWORD PTR [esp]
- mov ebp,DWORD PTR 8[esp]
- xor esi,ebp
- mov ebp,DWORD PTR 32[esp]
- xor esi,ebp
- mov ebp,DWORD PTR 52[esp]
- xor esi,ebp
- mov ebp,ebx
+ add eax,ebp
+ ; 40_59 48
+ mov ebp,ecx
+ xor esi,DWORD PTR 8[esp]
+ xor ebp,edx
+ xor esi,DWORD PTR 32[esp]
+ and ebp,ebx
+ xor esi,DWORD PTR 52[esp]
rol esi,1
- or ebp,ecx
- mov DWORD PTR [esp],esi
- and ebp,edx
- lea esi,DWORD PTR 2400959708[edi*1+esi]
- mov edi,ebx
+ add ebp,edi
ror ebx,2
- and edi,ecx
- or ebp,edi
mov edi,eax
rol edi,5
- add esi,ebp
+ mov DWORD PTR [esp],esi
+ lea esi,DWORD PTR 2400959708[ebp*1+esi]
+ mov ebp,ecx
add esi,edi
- ; 40_59 49
+ and ebp,edx
mov edi,DWORD PTR 4[esp]
- mov ebp,DWORD PTR 12[esp]
- xor edi,ebp
- mov ebp,DWORD PTR 36[esp]
- xor edi,ebp
- mov ebp,DWORD PTR 56[esp]
- xor edi,ebp
- mov ebp,eax
+ add esi,ebp
+ ; 40_59 49
+ mov ebp,ebx
+ xor edi,DWORD PTR 12[esp]
+ xor ebp,ecx
+ xor edi,DWORD PTR 36[esp]
+ and ebp,eax
+ xor edi,DWORD PTR 56[esp]
rol edi,1
- or ebp,ebx
- mov DWORD PTR 4[esp],edi
- and ebp,ecx
- lea edi,DWORD PTR 2400959708[edx*1+edi]
- mov edx,eax
+ add ebp,edx
ror eax,2
- and edx,ebx
- or ebp,edx
mov edx,esi
rol edx,5
- add edi,ebp
+ mov DWORD PTR 4[esp],edi
+ lea edi,DWORD PTR 2400959708[ebp*1+edi]
+ mov ebp,ebx
add edi,edx
- ; 40_59 50
+ and ebp,ecx
mov edx,DWORD PTR 8[esp]
- mov ebp,DWORD PTR 16[esp]
- xor edx,ebp
- mov ebp,DWORD PTR 40[esp]
- xor edx,ebp
- mov ebp,DWORD PTR 60[esp]
- xor edx,ebp
- mov ebp,esi
+ add edi,ebp
+ ; 40_59 50
+ mov ebp,eax
+ xor edx,DWORD PTR 16[esp]
+ xor ebp,ebx
+ xor edx,DWORD PTR 40[esp]
+ and ebp,esi
+ xor edx,DWORD PTR 60[esp]
rol edx,1
- or ebp,eax
- mov DWORD PTR 8[esp],edx
- and ebp,ebx
- lea edx,DWORD PTR 2400959708[ecx*1+edx]
- mov ecx,esi
+ add ebp,ecx
ror esi,2
- and ecx,eax
- or ebp,ecx
mov ecx,edi
rol ecx,5
- add edx,ebp
+ mov DWORD PTR 8[esp],edx
+ lea edx,DWORD PTR 2400959708[ebp*1+edx]
+ mov ebp,eax
add edx,ecx
- ; 40_59 51
+ and ebp,ebx
mov ecx,DWORD PTR 12[esp]
- mov ebp,DWORD PTR 20[esp]
- xor ecx,ebp
- mov ebp,DWORD PTR 44[esp]
- xor ecx,ebp
- mov ebp,DWORD PTR [esp]
- xor ecx,ebp
- mov ebp,edi
+ add edx,ebp
+ ; 40_59 51
+ mov ebp,esi
+ xor ecx,DWORD PTR 20[esp]
+ xor ebp,eax
+ xor ecx,DWORD PTR 44[esp]
+ and ebp,edi
+ xor ecx,DWORD PTR [esp]
rol ecx,1
- or ebp,esi
- mov DWORD PTR 12[esp],ecx
- and ebp,eax
- lea ecx,DWORD PTR 2400959708[ebx*1+ecx]
- mov ebx,edi
+ add ebp,ebx
ror edi,2
- and ebx,esi
- or ebp,ebx
mov ebx,edx
rol ebx,5
- add ecx,ebp
+ mov DWORD PTR 12[esp],ecx
+ lea ecx,DWORD PTR 2400959708[ebp*1+ecx]
+ mov ebp,esi
add ecx,ebx
- ; 40_59 52
+ and ebp,eax
mov ebx,DWORD PTR 16[esp]
- mov ebp,DWORD PTR 24[esp]
- xor ebx,ebp
- mov ebp,DWORD PTR 48[esp]
- xor ebx,ebp
- mov ebp,DWORD PTR 4[esp]
- xor ebx,ebp
- mov ebp,edx
+ add ecx,ebp
+ ; 40_59 52
+ mov ebp,edi
+ xor ebx,DWORD PTR 24[esp]
+ xor ebp,esi
+ xor ebx,DWORD PTR 48[esp]
+ and ebp,edx
+ xor ebx,DWORD PTR 4[esp]
rol ebx,1
- or ebp,edi
- mov DWORD PTR 16[esp],ebx
- and ebp,esi
- lea ebx,DWORD PTR 2400959708[eax*1+ebx]
- mov eax,edx
+ add ebp,eax
ror edx,2
- and eax,edi
- or ebp,eax
mov eax,ecx
rol eax,5
- add ebx,ebp
+ mov DWORD PTR 16[esp],ebx
+ lea ebx,DWORD PTR 2400959708[ebp*1+ebx]
+ mov ebp,edi
add ebx,eax
- ; 40_59 53
+ and ebp,esi
mov eax,DWORD PTR 20[esp]
- mov ebp,DWORD PTR 28[esp]
- xor eax,ebp
- mov ebp,DWORD PTR 52[esp]
- xor eax,ebp
- mov ebp,DWORD PTR 8[esp]
- xor eax,ebp
- mov ebp,ecx
+ add ebx,ebp
+ ; 40_59 53
+ mov ebp,edx
+ xor eax,DWORD PTR 28[esp]
+ xor ebp,edi
+ xor eax,DWORD PTR 52[esp]
+ and ebp,ecx
+ xor eax,DWORD PTR 8[esp]
rol eax,1
- or ebp,edx
- mov DWORD PTR 20[esp],eax
- and ebp,edi
- lea eax,DWORD PTR 2400959708[esi*1+eax]
- mov esi,ecx
+ add ebp,esi
ror ecx,2
- and esi,edx
- or ebp,esi
mov esi,ebx
rol esi,5
- add eax,ebp
+ mov DWORD PTR 20[esp],eax
+ lea eax,DWORD PTR 2400959708[ebp*1+eax]
+ mov ebp,edx
add eax,esi
- ; 40_59 54
+ and ebp,edi
mov esi,DWORD PTR 24[esp]
- mov ebp,DWORD PTR 32[esp]
- xor esi,ebp
- mov ebp,DWORD PTR 56[esp]
- xor esi,ebp
- mov ebp,DWORD PTR 12[esp]
- xor esi,ebp
- mov ebp,ebx
+ add eax,ebp
+ ; 40_59 54
+ mov ebp,ecx
+ xor esi,DWORD PTR 32[esp]
+ xor ebp,edx
+ xor esi,DWORD PTR 56[esp]
+ and ebp,ebx
+ xor esi,DWORD PTR 12[esp]
rol esi,1
- or ebp,ecx
- mov DWORD PTR 24[esp],esi
- and ebp,edx
- lea esi,DWORD PTR 2400959708[edi*1+esi]
- mov edi,ebx
+ add ebp,edi
ror ebx,2
- and edi,ecx
- or ebp,edi
mov edi,eax
rol edi,5
- add esi,ebp
+ mov DWORD PTR 24[esp],esi
+ lea esi,DWORD PTR 2400959708[ebp*1+esi]
+ mov ebp,ecx
add esi,edi
- ; 40_59 55
+ and ebp,edx
mov edi,DWORD PTR 28[esp]
- mov ebp,DWORD PTR 36[esp]
- xor edi,ebp
- mov ebp,DWORD PTR 60[esp]
- xor edi,ebp
- mov ebp,DWORD PTR 16[esp]
- xor edi,ebp
- mov ebp,eax
+ add esi,ebp
+ ; 40_59 55
+ mov ebp,ebx
+ xor edi,DWORD PTR 36[esp]
+ xor ebp,ecx
+ xor edi,DWORD PTR 60[esp]
+ and ebp,eax
+ xor edi,DWORD PTR 16[esp]
rol edi,1
- or ebp,ebx
- mov DWORD PTR 28[esp],edi
- and ebp,ecx
- lea edi,DWORD PTR 2400959708[edx*1+edi]
- mov edx,eax
+ add ebp,edx
ror eax,2
- and edx,ebx
- or ebp,edx
mov edx,esi
rol edx,5
- add edi,ebp
+ mov DWORD PTR 28[esp],edi
+ lea edi,DWORD PTR 2400959708[ebp*1+edi]
+ mov ebp,ebx
add edi,edx
- ; 40_59 56
+ and ebp,ecx
mov edx,DWORD PTR 32[esp]
- mov ebp,DWORD PTR 40[esp]
- xor edx,ebp
- mov ebp,DWORD PTR [esp]
- xor edx,ebp
- mov ebp,DWORD PTR 20[esp]
- xor edx,ebp
- mov ebp,esi
+ add edi,ebp
+ ; 40_59 56
+ mov ebp,eax
+ xor edx,DWORD PTR 40[esp]
+ xor ebp,ebx
+ xor edx,DWORD PTR [esp]
+ and ebp,esi
+ xor edx,DWORD PTR 20[esp]
rol edx,1
- or ebp,eax
- mov DWORD PTR 32[esp],edx
- and ebp,ebx
- lea edx,DWORD PTR 2400959708[ecx*1+edx]
- mov ecx,esi
+ add ebp,ecx
ror esi,2
- and ecx,eax
- or ebp,ecx
mov ecx,edi
rol ecx,5
- add edx,ebp
+ mov DWORD PTR 32[esp],edx
+ lea edx,DWORD PTR 2400959708[ebp*1+edx]
+ mov ebp,eax
add edx,ecx
- ; 40_59 57
+ and ebp,ebx
mov ecx,DWORD PTR 36[esp]
- mov ebp,DWORD PTR 44[esp]
- xor ecx,ebp
- mov ebp,DWORD PTR 4[esp]
- xor ecx,ebp
- mov ebp,DWORD PTR 24[esp]
- xor ecx,ebp
- mov ebp,edi
+ add edx,ebp
+ ; 40_59 57
+ mov ebp,esi
+ xor ecx,DWORD PTR 44[esp]
+ xor ebp,eax
+ xor ecx,DWORD PTR 4[esp]
+ and ebp,edi
+ xor ecx,DWORD PTR 24[esp]
rol ecx,1
- or ebp,esi
- mov DWORD PTR 36[esp],ecx
- and ebp,eax
- lea ecx,DWORD PTR 2400959708[ebx*1+ecx]
- mov ebx,edi
+ add ebp,ebx
ror edi,2
- and ebx,esi
- or ebp,ebx
mov ebx,edx
rol ebx,5
- add ecx,ebp
+ mov DWORD PTR 36[esp],ecx
+ lea ecx,DWORD PTR 2400959708[ebp*1+ecx]
+ mov ebp,esi
add ecx,ebx
- ; 40_59 58
+ and ebp,eax
mov ebx,DWORD PTR 40[esp]
- mov ebp,DWORD PTR 48[esp]
- xor ebx,ebp
- mov ebp,DWORD PTR 8[esp]
- xor ebx,ebp
- mov ebp,DWORD PTR 28[esp]
- xor ebx,ebp
- mov ebp,edx
+ add ecx,ebp
+ ; 40_59 58
+ mov ebp,edi
+ xor ebx,DWORD PTR 48[esp]
+ xor ebp,esi
+ xor ebx,DWORD PTR 8[esp]
+ and ebp,edx
+ xor ebx,DWORD PTR 28[esp]
rol ebx,1
- or ebp,edi
- mov DWORD PTR 40[esp],ebx
- and ebp,esi
- lea ebx,DWORD PTR 2400959708[eax*1+ebx]
- mov eax,edx
+ add ebp,eax
ror edx,2
- and eax,edi
- or ebp,eax
mov eax,ecx
rol eax,5
- add ebx,ebp
+ mov DWORD PTR 40[esp],ebx
+ lea ebx,DWORD PTR 2400959708[ebp*1+ebx]
+ mov ebp,edi
add ebx,eax
- ; 40_59 59
+ and ebp,esi
mov eax,DWORD PTR 44[esp]
- mov ebp,DWORD PTR 52[esp]
- xor eax,ebp
- mov ebp,DWORD PTR 12[esp]
- xor eax,ebp
- mov ebp,DWORD PTR 32[esp]
- xor eax,ebp
- mov ebp,ecx
+ add ebx,ebp
+ ; 40_59 59
+ mov ebp,edx
+ xor eax,DWORD PTR 52[esp]
+ xor ebp,edi
+ xor eax,DWORD PTR 12[esp]
+ and ebp,ecx
+ xor eax,DWORD PTR 32[esp]
rol eax,1
- or ebp,edx
- mov DWORD PTR 44[esp],eax
- and ebp,edi
- lea eax,DWORD PTR 2400959708[esi*1+eax]
- mov esi,ecx
+ add ebp,esi
ror ecx,2
- and esi,edx
- or ebp,esi
mov esi,ebx
rol esi,5
- add eax,ebp
+ mov DWORD PTR 44[esp],eax
+ lea eax,DWORD PTR 2400959708[ebp*1+eax]
+ mov ebp,edx
add eax,esi
+ and ebp,edi
+ mov esi,DWORD PTR 48[esp]
+ add eax,ebp
; 20_39 60
mov ebp,ebx
- mov esi,DWORD PTR 48[esp]
- ror ebx,2
xor esi,DWORD PTR 56[esp]
xor ebp,ecx
xor esi,DWORD PTR 16[esp]
xor ebp,edx
xor esi,DWORD PTR 36[esp]
rol esi,1
- add ebp,edi
+ add edi,ebp
+ ror ebx,2
+ mov ebp,eax
+ rol ebp,5
mov DWORD PTR 48[esp],esi
- mov edi,eax
- rol edi,5
- lea esi,DWORD PTR 3395469782[ebp*1+esi]
- add esi,edi
+ lea esi,DWORD PTR 3395469782[edi*1+esi]
+ mov edi,DWORD PTR 52[esp]
+ add esi,ebp
; 20_39 61
mov ebp,eax
- mov edi,DWORD PTR 52[esp]
- ror eax,2
xor edi,DWORD PTR 60[esp]
xor ebp,ebx
xor edi,DWORD PTR 20[esp]
xor ebp,ecx
xor edi,DWORD PTR 40[esp]
rol edi,1
- add ebp,edx
+ add edx,ebp
+ ror eax,2
+ mov ebp,esi
+ rol ebp,5
mov DWORD PTR 52[esp],edi
- mov edx,esi
- rol edx,5
- lea edi,DWORD PTR 3395469782[ebp*1+edi]
- add edi,edx
+ lea edi,DWORD PTR 3395469782[edx*1+edi]
+ mov edx,DWORD PTR 56[esp]
+ add edi,ebp
; 20_39 62
mov ebp,esi
- mov edx,DWORD PTR 56[esp]
- ror esi,2
xor edx,DWORD PTR [esp]
xor ebp,eax
xor edx,DWORD PTR 24[esp]
xor ebp,ebx
xor edx,DWORD PTR 44[esp]
rol edx,1
- add ebp,ecx
+ add ecx,ebp
+ ror esi,2
+ mov ebp,edi
+ rol ebp,5
mov DWORD PTR 56[esp],edx
- mov ecx,edi
- rol ecx,5
- lea edx,DWORD PTR 3395469782[ebp*1+edx]
- add edx,ecx
+ lea edx,DWORD PTR 3395469782[ecx*1+edx]
+ mov ecx,DWORD PTR 60[esp]
+ add edx,ebp
; 20_39 63
mov ebp,edi
- mov ecx,DWORD PTR 60[esp]
- ror edi,2
xor ecx,DWORD PTR 4[esp]
xor ebp,esi
xor ecx,DWORD PTR 28[esp]
xor ebp,eax
xor ecx,DWORD PTR 48[esp]
rol ecx,1
- add ebp,ebx
+ add ebx,ebp
+ ror edi,2
+ mov ebp,edx
+ rol ebp,5
mov DWORD PTR 60[esp],ecx
- mov ebx,edx
- rol ebx,5
- lea ecx,DWORD PTR 3395469782[ebp*1+ecx]
- add ecx,ebx
+ lea ecx,DWORD PTR 3395469782[ebx*1+ecx]
+ mov ebx,DWORD PTR [esp]
+ add ecx,ebp
; 20_39 64
mov ebp,edx
- mov ebx,DWORD PTR [esp]
- ror edx,2
xor ebx,DWORD PTR 8[esp]
xor ebp,edi
xor ebx,DWORD PTR 32[esp]
xor ebp,esi
xor ebx,DWORD PTR 52[esp]
rol ebx,1
- add ebp,eax
+ add eax,ebp
+ ror edx,2
+ mov ebp,ecx
+ rol ebp,5
mov DWORD PTR [esp],ebx
- mov eax,ecx
- rol eax,5
- lea ebx,DWORD PTR 3395469782[ebp*1+ebx]
- add ebx,eax
+ lea ebx,DWORD PTR 3395469782[eax*1+ebx]
+ mov eax,DWORD PTR 4[esp]
+ add ebx,ebp
; 20_39 65
mov ebp,ecx
- mov eax,DWORD PTR 4[esp]
- ror ecx,2
xor eax,DWORD PTR 12[esp]
xor ebp,edx
xor eax,DWORD PTR 36[esp]
xor ebp,edi
xor eax,DWORD PTR 56[esp]
rol eax,1
- add ebp,esi
+ add esi,ebp
+ ror ecx,2
+ mov ebp,ebx
+ rol ebp,5
mov DWORD PTR 4[esp],eax
- mov esi,ebx
- rol esi,5
- lea eax,DWORD PTR 3395469782[ebp*1+eax]
- add eax,esi
+ lea eax,DWORD PTR 3395469782[esi*1+eax]
+ mov esi,DWORD PTR 8[esp]
+ add eax,ebp
; 20_39 66
mov ebp,ebx
- mov esi,DWORD PTR 8[esp]
- ror ebx,2
xor esi,DWORD PTR 16[esp]
xor ebp,ecx
xor esi,DWORD PTR 40[esp]
xor ebp,edx
xor esi,DWORD PTR 60[esp]
rol esi,1
- add ebp,edi
+ add edi,ebp
+ ror ebx,2
+ mov ebp,eax
+ rol ebp,5
mov DWORD PTR 8[esp],esi
- mov edi,eax
- rol edi,5
- lea esi,DWORD PTR 3395469782[ebp*1+esi]
- add esi,edi
+ lea esi,DWORD PTR 3395469782[edi*1+esi]
+ mov edi,DWORD PTR 12[esp]
+ add esi,ebp
; 20_39 67
mov ebp,eax
- mov edi,DWORD PTR 12[esp]
- ror eax,2
xor edi,DWORD PTR 20[esp]
xor ebp,ebx
xor edi,DWORD PTR 44[esp]
xor ebp,ecx
xor edi,DWORD PTR [esp]
rol edi,1
- add ebp,edx
+ add edx,ebp
+ ror eax,2
+ mov ebp,esi
+ rol ebp,5
mov DWORD PTR 12[esp],edi
- mov edx,esi
- rol edx,5
- lea edi,DWORD PTR 3395469782[ebp*1+edi]
- add edi,edx
+ lea edi,DWORD PTR 3395469782[edx*1+edi]
+ mov edx,DWORD PTR 16[esp]
+ add edi,ebp
; 20_39 68
mov ebp,esi
- mov edx,DWORD PTR 16[esp]
- ror esi,2
xor edx,DWORD PTR 24[esp]
xor ebp,eax
xor edx,DWORD PTR 48[esp]
xor ebp,ebx
xor edx,DWORD PTR 4[esp]
rol edx,1
- add ebp,ecx
+ add ecx,ebp
+ ror esi,2
+ mov ebp,edi
+ rol ebp,5
mov DWORD PTR 16[esp],edx
- mov ecx,edi
- rol ecx,5
- lea edx,DWORD PTR 3395469782[ebp*1+edx]
- add edx,ecx
+ lea edx,DWORD PTR 3395469782[ecx*1+edx]
+ mov ecx,DWORD PTR 20[esp]
+ add edx,ebp
; 20_39 69
mov ebp,edi
- mov ecx,DWORD PTR 20[esp]
- ror edi,2
xor ecx,DWORD PTR 28[esp]
xor ebp,esi
xor ecx,DWORD PTR 52[esp]
xor ebp,eax
xor ecx,DWORD PTR 8[esp]
rol ecx,1
- add ebp,ebx
+ add ebx,ebp
+ ror edi,2
+ mov ebp,edx
+ rol ebp,5
mov DWORD PTR 20[esp],ecx
- mov ebx,edx
- rol ebx,5
- lea ecx,DWORD PTR 3395469782[ebp*1+ecx]
- add ecx,ebx
+ lea ecx,DWORD PTR 3395469782[ebx*1+ecx]
+ mov ebx,DWORD PTR 24[esp]
+ add ecx,ebp
; 20_39 70
mov ebp,edx
- mov ebx,DWORD PTR 24[esp]
- ror edx,2
xor ebx,DWORD PTR 32[esp]
xor ebp,edi
xor ebx,DWORD PTR 56[esp]
xor ebp,esi
xor ebx,DWORD PTR 12[esp]
rol ebx,1
- add ebp,eax
+ add eax,ebp
+ ror edx,2
+ mov ebp,ecx
+ rol ebp,5
mov DWORD PTR 24[esp],ebx
- mov eax,ecx
- rol eax,5
- lea ebx,DWORD PTR 3395469782[ebp*1+ebx]
- add ebx,eax
+ lea ebx,DWORD PTR 3395469782[eax*1+ebx]
+ mov eax,DWORD PTR 28[esp]
+ add ebx,ebp
; 20_39 71
mov ebp,ecx
- mov eax,DWORD PTR 28[esp]
- ror ecx,2
xor eax,DWORD PTR 36[esp]
xor ebp,edx
xor eax,DWORD PTR 60[esp]
xor ebp,edi
xor eax,DWORD PTR 16[esp]
rol eax,1
- add ebp,esi
+ add esi,ebp
+ ror ecx,2
+ mov ebp,ebx
+ rol ebp,5
mov DWORD PTR 28[esp],eax
- mov esi,ebx
- rol esi,5
- lea eax,DWORD PTR 3395469782[ebp*1+eax]
- add eax,esi
+ lea eax,DWORD PTR 3395469782[esi*1+eax]
+ mov esi,DWORD PTR 32[esp]
+ add eax,ebp
; 20_39 72
mov ebp,ebx
- mov esi,DWORD PTR 32[esp]
- ror ebx,2
xor esi,DWORD PTR 40[esp]
xor ebp,ecx
xor esi,DWORD PTR [esp]
xor ebp,edx
xor esi,DWORD PTR 20[esp]
rol esi,1
- add ebp,edi
+ add edi,ebp
+ ror ebx,2
+ mov ebp,eax
+ rol ebp,5
mov DWORD PTR 32[esp],esi
- mov edi,eax
- rol edi,5
- lea esi,DWORD PTR 3395469782[ebp*1+esi]
- add esi,edi
+ lea esi,DWORD PTR 3395469782[edi*1+esi]
+ mov edi,DWORD PTR 36[esp]
+ add esi,ebp
; 20_39 73
mov ebp,eax
- mov edi,DWORD PTR 36[esp]
- ror eax,2
xor edi,DWORD PTR 44[esp]
xor ebp,ebx
xor edi,DWORD PTR 4[esp]
xor ebp,ecx
xor edi,DWORD PTR 24[esp]
rol edi,1
- add ebp,edx
+ add edx,ebp
+ ror eax,2
+ mov ebp,esi
+ rol ebp,5
mov DWORD PTR 36[esp],edi
- mov edx,esi
- rol edx,5
- lea edi,DWORD PTR 3395469782[ebp*1+edi]
- add edi,edx
+ lea edi,DWORD PTR 3395469782[edx*1+edi]
+ mov edx,DWORD PTR 40[esp]
+ add edi,ebp
; 20_39 74
mov ebp,esi
- mov edx,DWORD PTR 40[esp]
- ror esi,2
xor edx,DWORD PTR 48[esp]
xor ebp,eax
xor edx,DWORD PTR 8[esp]
xor ebp,ebx
xor edx,DWORD PTR 28[esp]
rol edx,1
- add ebp,ecx
+ add ecx,ebp
+ ror esi,2
+ mov ebp,edi
+ rol ebp,5
mov DWORD PTR 40[esp],edx
- mov ecx,edi
- rol ecx,5
- lea edx,DWORD PTR 3395469782[ebp*1+edx]
- add edx,ecx
+ lea edx,DWORD PTR 3395469782[ecx*1+edx]
+ mov ecx,DWORD PTR 44[esp]
+ add edx,ebp
; 20_39 75
mov ebp,edi
- mov ecx,DWORD PTR 44[esp]
- ror edi,2
xor ecx,DWORD PTR 52[esp]
xor ebp,esi
xor ecx,DWORD PTR 12[esp]
xor ebp,eax
xor ecx,DWORD PTR 32[esp]
rol ecx,1
- add ebp,ebx
+ add ebx,ebp
+ ror edi,2
+ mov ebp,edx
+ rol ebp,5
mov DWORD PTR 44[esp],ecx
- mov ebx,edx
- rol ebx,5
- lea ecx,DWORD PTR 3395469782[ebp*1+ecx]
- add ecx,ebx
+ lea ecx,DWORD PTR 3395469782[ebx*1+ecx]
+ mov ebx,DWORD PTR 48[esp]
+ add ecx,ebp
; 20_39 76
mov ebp,edx
- mov ebx,DWORD PTR 48[esp]
- ror edx,2
xor ebx,DWORD PTR 56[esp]
xor ebp,edi
xor ebx,DWORD PTR 16[esp]
xor ebp,esi
xor ebx,DWORD PTR 36[esp]
rol ebx,1
- add ebp,eax
+ add eax,ebp
+ ror edx,2
+ mov ebp,ecx
+ rol ebp,5
mov DWORD PTR 48[esp],ebx
- mov eax,ecx
- rol eax,5
- lea ebx,DWORD PTR 3395469782[ebp*1+ebx]
- add ebx,eax
+ lea ebx,DWORD PTR 3395469782[eax*1+ebx]
+ mov eax,DWORD PTR 52[esp]
+ add ebx,ebp
; 20_39 77
mov ebp,ecx
- mov eax,DWORD PTR 52[esp]
- ror ecx,2
xor eax,DWORD PTR 60[esp]
xor ebp,edx
xor eax,DWORD PTR 20[esp]
xor ebp,edi
xor eax,DWORD PTR 40[esp]
rol eax,1
- add ebp,esi
- mov DWORD PTR 52[esp],eax
- mov esi,ebx
- rol esi,5
- lea eax,DWORD PTR 3395469782[ebp*1+eax]
- add eax,esi
- ; 20_39 78
+ add esi,ebp
+ ror ecx,2
mov ebp,ebx
+ rol ebp,5
+ lea eax,DWORD PTR 3395469782[esi*1+eax]
mov esi,DWORD PTR 56[esp]
- ror ebx,2
+ add eax,ebp
+ ; 20_39 78
+ mov ebp,ebx
xor esi,DWORD PTR [esp]
xor ebp,ecx
xor esi,DWORD PTR 24[esp]
xor ebp,edx
xor esi,DWORD PTR 44[esp]
rol esi,1
- add ebp,edi
- mov DWORD PTR 56[esp],esi
- mov edi,eax
- rol edi,5
- lea esi,DWORD PTR 3395469782[ebp*1+esi]
- add esi,edi
- ; 20_39 79
+ add edi,ebp
+ ror ebx,2
mov ebp,eax
+ rol ebp,5
+ lea esi,DWORD PTR 3395469782[edi*1+esi]
mov edi,DWORD PTR 60[esp]
- ror eax,2
+ add esi,ebp
+ ; 20_39 79
+ mov ebp,eax
xor edi,DWORD PTR 4[esp]
xor ebp,ebx
xor edi,DWORD PTR 28[esp]
xor ebp,ecx
xor edi,DWORD PTR 48[esp]
rol edi,1
- add ebp,edx
- mov DWORD PTR 60[esp],edi
- mov edx,esi
- rol edx,5
- lea edi,DWORD PTR 3395469782[ebp*1+edi]
- add edi,edx
- mov ebp,DWORD PTR 84[esp]
- mov edx,DWORD PTR 88[esp]
+ add edx,ebp
+ ror eax,2
+ mov ebp,esi
+ rol ebp,5
+ lea edi,DWORD PTR 3395469782[edx*1+edi]
+ add edi,ebp
+ mov ebp,DWORD PTR 96[esp]
+ mov edx,DWORD PTR 100[esp]
add edi,DWORD PTR [ebp]
add esi,DWORD PTR 4[ebp]
add eax,DWORD PTR 8[ebp]
@@ -1430,14 +1368,14 @@ $L000loop:
mov DWORD PTR [ebp],edi
add edx,64
mov DWORD PTR 4[ebp],esi
- cmp edx,DWORD PTR 92[esp]
+ cmp edx,DWORD PTR 104[esp]
mov DWORD PTR 8[ebp],eax
mov edi,ecx
mov DWORD PTR 12[ebp],ebx
mov esi,edx
mov DWORD PTR 16[ebp],ecx
jb $L000loop
- add esp,64
+ add esp,76
pop edi
pop esi
pop ebx
diff --git a/deps/openssl/asm/x86-win32-masm/sha/sha256-586.asm b/deps/openssl/asm/x86-win32-masm/sha/sha256-586.asm
index 75b1dc8ac..577c38ffa 100644
--- a/deps/openssl/asm/x86-win32-masm/sha/sha256-586.asm
+++ b/deps/openssl/asm/x86-win32-masm/sha/sha256-586.asm
@@ -2,7 +2,7 @@ TITLE sha512-586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
@@ -104,31 +104,30 @@ ALIGN 16
$L00300_15:
mov ebx,DWORD PTR 92[esp]
mov ecx,edx
- ror ecx,6
- mov edi,edx
- ror edi,11
+ ror ecx,14
mov esi,DWORD PTR 20[esp]
- xor ecx,edi
- ror edi,14
- xor ecx,edi
+ xor ecx,edx
+ ror ecx,5
+ xor ecx,edx
+ ror ecx,6
mov edi,DWORD PTR 24[esp]
add ebx,ecx
- mov DWORD PTR 16[esp],edx
xor esi,edi
+ mov DWORD PTR 16[esp],edx
mov ecx,eax
and esi,edx
mov edx,DWORD PTR 12[esp]
xor esi,edi
mov edi,eax
add ebx,esi
- ror ecx,2
+ ror ecx,9
add ebx,DWORD PTR 28[esp]
- ror edi,13
+ xor ecx,eax
+ ror ecx,11
mov esi,DWORD PTR 4[esp]
- xor ecx,edi
- ror edi,9
+ xor ecx,eax
+ ror ecx,2
add edx,ebx
- xor ecx,edi
mov edi,DWORD PTR 8[esp]
add ebx,ecx
mov DWORD PTR [esp],eax
@@ -150,48 +149,46 @@ ALIGN 16
$L00416_63:
mov esi,ebx
mov ecx,DWORD PTR 100[esp]
- shr ebx,3
- ror esi,7
- xor ebx,esi
ror esi,11
mov edi,ecx
+ xor esi,ebx
+ ror esi,7
+ shr ebx,3
+ ror edi,2
xor ebx,esi
- shr ecx,10
- mov esi,DWORD PTR 156[esp]
+ xor edi,ecx
ror edi,17
- xor ecx,edi
- ror edi,2
- add ebx,esi
+ shr ecx,10
+ add ebx,DWORD PTR 156[esp]
xor edi,ecx
- add ebx,edi
- mov ecx,edx
add ebx,DWORD PTR 120[esp]
- ror ecx,6
- mov edi,edx
- ror edi,11
+ mov ecx,edx
+ add ebx,edi
+ ror ecx,14
mov esi,DWORD PTR 20[esp]
- xor ecx,edi
- ror edi,14
+ xor ecx,edx
+ ror ecx,5
mov DWORD PTR 92[esp],ebx
- xor ecx,edi
+ xor ecx,edx
+ ror ecx,6
mov edi,DWORD PTR 24[esp]
add ebx,ecx
- mov DWORD PTR 16[esp],edx
xor esi,edi
+ mov DWORD PTR 16[esp],edx
mov ecx,eax
and esi,edx
mov edx,DWORD PTR 12[esp]
xor esi,edi
mov edi,eax
add ebx,esi
- ror ecx,2
+ ror ecx,9
add ebx,DWORD PTR 28[esp]
- ror edi,13
+ xor ecx,eax
+ ror ecx,11
mov esi,DWORD PTR 4[esp]
- xor ecx,edi
- ror edi,9
+ xor ecx,eax
+ ror ecx,2
add edx,ebx
- xor ecx,edi
mov edi,DWORD PTR 8[esp]
add ebx,ecx
mov DWORD PTR [esp],eax
diff --git a/deps/openssl/asm/x86-win32-masm/sha/sha512-586.asm b/deps/openssl/asm/x86-win32-masm/sha/sha512-586.asm
index 9f3249762..98c1c070d 100644
--- a/deps/openssl/asm/x86-win32-masm/sha/sha512-586.asm
+++ b/deps/openssl/asm/x86-win32-masm/sha/sha512-586.asm
@@ -2,7 +2,7 @@ TITLE sha512-586.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
diff --git a/deps/openssl/asm/x86-win32-masm/x86cpuid.asm b/deps/openssl/asm/x86-win32-masm/x86cpuid.asm
index 7e663d664..b9b1c2584 100644
--- a/deps/openssl/asm/x86-win32-masm/x86cpuid.asm
+++ b/deps/openssl/asm/x86-win32-masm/x86cpuid.asm
@@ -2,7 +2,7 @@ TITLE x86cpuid.asm
IF @Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF @Version LT 800
@@ -27,9 +27,9 @@ $L_OPENSSL_ia32_cpuid_begin::
pushfd
pop eax
xor ecx,eax
- bt ecx,21
- jnc $L000done
xor eax,eax
+ bt ecx,21
+ jnc $L000nocpuid
cpuid
mov edi,eax
xor eax,eax
@@ -55,7 +55,14 @@ $L_OPENSSL_ia32_cpuid_begin::
jnz $L001intel
mov eax,2147483648
cpuid
- cmp eax,2147483656
+ cmp eax,2147483649
+ jb $L001intel
+ mov esi,eax
+ mov eax,2147483649
+ cpuid
+ or ebp,ecx
+ and ebp,2049
+ cmp esi,2147483656
jb $L001intel
mov eax,2147483656
cpuid
@@ -64,46 +71,68 @@ $L_OPENSSL_ia32_cpuid_begin::
mov eax,1
cpuid
bt edx,28
- jnc $L000done
+ jnc $L002generic
shr ebx,16
and ebx,255
cmp ebx,esi
- ja $L000done
+ ja $L002generic
and edx,4026531839
- jmp $L000done
+ jmp $L002generic
$L001intel:
cmp edi,4
mov edi,-1
- jb $L002nocacheinfo
+ jb $L003nocacheinfo
mov eax,4
mov ecx,0
cpuid
mov edi,eax
shr edi,14
and edi,4095
-$L002nocacheinfo:
+$L003nocacheinfo:
mov eax,1
cpuid
+ and edx,3220176895
cmp ebp,0
- jne $L003notP4
+ jne $L004notintel
+ or edx,1073741824
and ah,15
cmp ah,15
- jne $L003notP4
+ jne $L004notintel
or edx,1048576
-$L003notP4:
+$L004notintel:
bt edx,28
- jnc $L000done
+ jnc $L002generic
and edx,4026531839
cmp edi,0
- je $L000done
+ je $L002generic
or edx,268435456
shr ebx,16
cmp bl,1
- ja $L000done
+ ja $L002generic
and edx,4026531839
-$L000done:
- mov eax,edx
- mov edx,ecx
+$L002generic:
+ and ebp,2048
+ and ecx,4294965247
+ mov esi,edx
+ or ebp,ecx
+ bt ecx,27
+ jnc $L005clear_avx
+ xor ecx,ecx
+DB 15,1,208
+ and eax,6
+ cmp eax,6
+ je $L006done
+ cmp eax,2
+ je $L005clear_avx
+$L007clear_xmm:
+ and ebp,4261412861
+ and esi,4278190079
+$L005clear_avx:
+ and ebp,4026525695
+$L006done:
+ mov eax,esi
+ mov edx,ebp
+$L000nocpuid:
pop edi
pop esi
pop ebx
@@ -118,9 +147,9 @@ $L_OPENSSL_rdtsc_begin::
xor edx,edx
lea ecx,DWORD PTR _OPENSSL_ia32cap_P
bt DWORD PTR [ecx],4
- jnc $L004notsc
+ jnc $L008notsc
rdtsc
-$L004notsc:
+$L008notsc:
ret
_OPENSSL_rdtsc ENDP
ALIGN 16
@@ -128,14 +157,14 @@ _OPENSSL_instrument_halt PROC PUBLIC
$L_OPENSSL_instrument_halt_begin::
lea ecx,DWORD PTR _OPENSSL_ia32cap_P
bt DWORD PTR [ecx],4
- jnc $L005nohalt
+ jnc $L009nohalt
DD 2421723150
and eax,3
- jnz $L005nohalt
+ jnz $L009nohalt
pushfd
pop eax
bt eax,9
- jnc $L005nohalt
+ jnc $L009nohalt
rdtsc
push edx
push eax
@@ -145,7 +174,7 @@ DD 2421723150
sbb edx,DWORD PTR 4[esp]
add esp,8
ret
-$L005nohalt:
+$L009nohalt:
xor eax,eax
xor edx,edx
ret
@@ -156,21 +185,21 @@ $L_OPENSSL_far_spin_begin::
pushfd
pop eax
bt eax,9
- jnc $L006nospin
+ jnc $L010nospin
mov eax,DWORD PTR 4[esp]
mov ecx,DWORD PTR 8[esp]
DD 2430111262
xor eax,eax
mov edx,DWORD PTR [ecx]
- jmp $L007spin
+ jmp $L011spin
ALIGN 16
-$L007spin:
+$L011spin:
inc eax
cmp edx,DWORD PTR [ecx]
- je $L007spin
+ je $L011spin
DD 529567888
ret
-$L006nospin:
+$L010nospin:
xor eax,eax
xor edx,edx
ret
@@ -183,9 +212,9 @@ $L_OPENSSL_wipe_cpu_begin::
lea ecx,DWORD PTR _OPENSSL_ia32cap_P
mov ecx,DWORD PTR [ecx]
bt DWORD PTR [ecx],1
- jnc $L008no_x87
+ jnc $L012no_x87
DD 4007259865,4007259865,4007259865,4007259865,2430851995
-$L008no_x87:
+$L012no_x87:
lea eax,DWORD PTR 4[esp]
ret
_OPENSSL_wipe_cpu ENDP
@@ -197,11 +226,11 @@ $L_OPENSSL_atomic_add_begin::
push ebx
nop
mov eax,DWORD PTR [edx]
-$L009spin:
+$L013spin:
lea ebx,DWORD PTR [ecx*1+eax]
nop
DD 447811568
- jne $L009spin
+ jne $L013spin
mov eax,ebx
pop ebx
ret
@@ -238,37 +267,50 @@ $L_OPENSSL_cleanse_begin::
mov ecx,DWORD PTR 8[esp]
xor eax,eax
cmp ecx,7
- jae $L010lot
+ jae $L014lot
cmp ecx,0
- je $L011ret
-$L012little:
+ je $L015ret
+$L016little:
mov BYTE PTR [edx],al
sub ecx,1
lea edx,DWORD PTR 1[edx]
- jnz $L012little
-$L011ret:
+ jnz $L016little
+$L015ret:
ret
ALIGN 16
-$L010lot:
+$L014lot:
test edx,3
- jz $L013aligned
+ jz $L017aligned
mov BYTE PTR [edx],al
lea ecx,DWORD PTR [ecx-1]
lea edx,DWORD PTR 1[edx]
- jmp $L010lot
-$L013aligned:
+ jmp $L014lot
+$L017aligned:
mov DWORD PTR [edx],eax
lea ecx,DWORD PTR [ecx-4]
test ecx,-4
lea edx,DWORD PTR 4[edx]
- jnz $L013aligned
+ jnz $L017aligned
cmp ecx,0
- jne $L012little
+ jne $L016little
ret
_OPENSSL_cleanse ENDP
+ALIGN 16
+_OPENSSL_ia32_rdrand PROC PUBLIC
+$L_OPENSSL_ia32_rdrand_begin::
+ mov ecx,8
+$L018loop:
+DB 15,199,240
+ jc $L019break
+ loop $L018loop
+$L019break:
+ cmp eax,0
+ cmove eax,ecx
+ ret
+_OPENSSL_ia32_rdrand ENDP
.text$ ENDS
.bss SEGMENT 'BSS'
-COMM _OPENSSL_ia32cap_P:DWORD
+COMM _OPENSSL_ia32cap_P:QWORD
.bss ENDS
.CRT$XCU SEGMENT DWORD PUBLIC 'DATA'
EXTERN _OPENSSL_cpuid_setup:NEAR
diff --git a/deps/openssl/config/android/openssl/opensslconf.h b/deps/openssl/config/android/openssl/opensslconf.h
deleted file mode 100644
index 9280eb286..000000000
--- a/deps/openssl/config/android/openssl/opensslconf.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/* opensslconf.h */
-/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
-
-/* OpenSSL was configured with the following options: */
-#ifndef OPENSSL_DOING_MAKEDEPEND
-
-
-#ifndef OPENSSL_NO_CAMELLIA
-# define OPENSSL_NO_CAMELLIA
-#endif
-#ifndef OPENSSL_NO_GMP
-# define OPENSSL_NO_GMP
-#endif
-#ifndef OPENSSL_NO_IDEA
-# define OPENSSL_NO_IDEA
-#endif
-#ifndef OPENSSL_NO_JPAKE
-# define OPENSSL_NO_JPAKE
-#endif
-#ifndef OPENSSL_NO_KRB5
-# define OPENSSL_NO_KRB5
-#endif
-#ifndef OPENSSL_NO_MDC2
-# define OPENSSL_NO_MDC2
-#endif
-#ifndef OPENSSL_NO_CMS
-# define OPENSSL_NO_CMS
-#endif
-#ifndef OPENSSL_NO_RC5
-# define OPENSSL_NO_RC5
-#endif
-#ifndef OPENSSL_NO_RFC3779
-# define OPENSSL_NO_RFC3779
-#endif
-#ifndef OPENSSL_NO_SEED
-# define OPENSSL_NO_SEED
-#endif
-#ifndef OPENSSL_NO_SHA0
-# define OPENSSL_NO_SHA0
-#endif
-#ifndef OPENSSL_NO_WHRLPOOL
-# define OPENSSL_NO_WHRLPOOL
-#endif
-
-#endif /* OPENSSL_DOING_MAKEDEPEND */
-
-#ifndef OPENSSL_THREADS
-# define OPENSSL_THREADS
-#endif
-#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-# define OPENSSL_NO_DYNAMIC_ENGINE
-#endif
-
-/* The OPENSSL_NO_* macros are also defined as NO_* if the application
- asks for it. This is a transient feature that is provided for those
- who haven't had the time to do the appropriate changes in their
- applications. */
-#ifdef OPENSSL_ALGORITHM_DEFINES
-# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
-# define NO_CAST
-# endif
-# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
-# define NO_GMP
-# endif
-# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
-# define NO_IDEA
-# endif
-# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
-# define NO_JPAKE
-# endif
-# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
-# define NO_KRB5
-# endif
-# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
-# define NO_MD2
-# endif
-# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
-# define NO_RC5
-# endif
-# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
-# define NO_RFC3779
-# endif
-# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
-# define NO_SEED
-# endif
-# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)
-# define NO_SHA0
-# endif
-# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
-# define NO_STORE
-# endif
-# if defined(OPENSSL_NO_WHRLPOOL) && !defined(NO_WHRLPOOL)
-# define NO_WHRLPOOL
-# endif
-# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
-# define NO_MDC2
-# endif
-#endif
-
-/* crypto/opensslconf.h.in */
-
-/* Generate 80386 code? */
-#undef I386_ONLY
-
-#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
-#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-#define ENGINESDIR "/usr/local/ssl/lib/engines"
-#define OPENSSLDIR "/usr/local/ssl"
-#endif
-#endif
-
-#undef OPENSSL_UNISTD
-#define OPENSSL_UNISTD <unistd.h>
-
-#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
-
-#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
-#define IDEA_INT unsigned int
-#endif
-
-#if defined(HEADER_MD2_H) && !defined(MD2_INT)
-#define MD2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC2_H) && !defined(RC2_INT)
-/* I need to put in a mod for the alpha - eay */
-#define RC2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC4_H)
-#if !defined(RC4_INT)
-/* using int types make the structure larger but make the code faster
- * on most boxes I have tested - up to %20 faster. */
-/*
- * I don't know what does "most" mean, but declaring "int" is a must on:
- * - Intel P6 because partial register stalls are very expensive;
- * - elder Alpha because it lacks byte load/store instructions;
- */
-#define RC4_INT unsigned char
-#endif
-#if !defined(RC4_CHUNK)
-/*
- * This enables code handling data aligned at natural CPU word
- * boundary. See crypto/rc4/rc4_enc.c for further details.
- */
-#define RC4_CHUNK unsigned long
-#endif
-#endif
-
-#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
-/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
- * %20 speed up (longs are 8 bytes, int's are 4). */
-#ifndef DES_LONG
-#define DES_LONG unsigned int
-#endif
-#endif
-
-#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
-#define CONFIG_HEADER_BN_H
-#define BN_LLONG
-
-/* Should we define BN_DIV2W here? */
-
-/* Only one for the following should be defined */
-#undef SIXTY_FOUR_BIT_LONG
-#undef SIXTY_FOUR_BIT
-#define THIRTY_TWO_BIT
-#endif
-
-#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
-#define CONFIG_HEADER_RC4_LOCL_H
-/* if this is defined data[i] is used instead of *data, this is a %20
- * speedup on x86 */
-#undef RC4_INDEX
-#endif
-
-#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
-#define CONFIG_HEADER_BF_LOCL_H
-#define BF_PTR
-#endif /* HEADER_BF_LOCL_H */
-
-#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
-#define CONFIG_HEADER_DES_LOCL_H
-#ifndef DES_DEFAULT_OPTIONS
-/* the following is tweaked from a config script, that is why it is a
- * protected undef/define */
-#ifndef DES_PTR
-#undef DES_PTR
-#endif
-
-/* This helps C compiler generate the correct code for multiple functional
- * units. It reduces register dependancies at the expense of 2 more
- * registers */
-#ifndef DES_RISC1
-#undef DES_RISC1
-#endif
-
-#ifndef DES_RISC2
-#undef DES_RISC2
-#endif
-
-#if defined(DES_RISC1) && defined(DES_RISC2)
-YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-#endif
-
-/* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
-#ifndef DES_UNROLL
-#define DES_UNROLL
-#endif
-
-/* These default values were supplied by
- * Peter Gutman <pgut001@cs.auckland.ac.nz>
- * They are only used if nothing else has been defined */
-#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-/* Special defines which change the way the code is built depending on the
- CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
- even newer MIPS CPU's, but at the moment one size fits all for
- optimization options. Older Sparc's work better with only UNROLL, but
- there's no way to tell at compile time what it is you're running on */
-
-#if defined( sun ) /* Newer Sparc's */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#elif defined( __ultrix ) /* Older MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined( __osf1__ ) /* Alpha */
-# define DES_PTR
-# define DES_RISC2
-#elif defined ( _AIX ) /* RS6000 */
- /* Unknown */
-#elif defined( __hpux ) /* HP-PA */
- /* Unknown */
-#elif defined( __aux ) /* 68K */
- /* Unknown */
-#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
-# define DES_UNROLL
-#elif defined( __sgi ) /* Newer MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#endif /* Systems-specific speed defines */
-#endif
-
-#endif /* DES_DEFAULT_OPTIONS */
-#endif /* HEADER_DES_LOCL_H */
diff --git a/deps/openssl/config/k8/openssl/opensslconf-posix.h b/deps/openssl/config/k8/openssl/opensslconf-posix.h
deleted file mode 100644
index 1a6058fe9..000000000
--- a/deps/openssl/config/k8/openssl/opensslconf-posix.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/* opensslconf.h */
-/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
-
-/* OpenSSL was configured with the following options: */
-#ifndef OPENSSL_DOING_MAKEDEPEND
-
-
-#ifndef OPENSSL_NO_CAMELLIA
-# define OPENSSL_NO_CAMELLIA
-#endif
-#ifndef OPENSSL_NO_CAPIENG
-# define OPENSSL_NO_CAPIENG
-#endif
-#ifndef OPENSSL_NO_CMS
-# define OPENSSL_NO_CMS
-#endif
-#ifndef OPENSSL_NO_FIPS
-# define OPENSSL_NO_FIPS
-#endif
-#ifndef OPENSSL_NO_GMP
-# define OPENSSL_NO_GMP
-#endif
-#ifndef OPENSSL_NO_IDEA
-# define OPENSSL_NO_IDEA
-#endif
-#ifndef OPENSSL_NO_JPAKE
-# define OPENSSL_NO_JPAKE
-#endif
-#ifndef OPENSSL_NO_KRB5
-# define OPENSSL_NO_KRB5
-#endif
-#ifndef OPENSSL_NO_MDC2
-# define OPENSSL_NO_MDC2
-#endif
-#ifndef OPENSSL_NO_RC5
-# define OPENSSL_NO_RC5
-#endif
-#ifndef OPENSSL_NO_RFC3779
-# define OPENSSL_NO_RFC3779
-#endif
-#ifndef OPENSSL_NO_SEED
-# define OPENSSL_NO_SEED
-#endif
-
-#endif /* OPENSSL_DOING_MAKEDEPEND */
-
-#ifndef OPENSSL_THREADS
-# define OPENSSL_THREADS
-#endif
-#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-# define OPENSSL_NO_DYNAMIC_ENGINE
-#endif
-
-/* The OPENSSL_NO_* macros are also defined as NO_* if the application
- asks for it. This is a transient feature that is provided for those
- who haven't had the time to do the appropriate changes in their
- applications. */
-#ifdef OPENSSL_ALGORITHM_DEFINES
-# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
-# define NO_CAMELLIA
-# endif
-# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
-# define NO_CAPIENG
-# endif
-# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
-# define NO_CMS
-# endif
-# if defined(OPENSSL_NO_FIPS) && !defined(NO_FIPS)
-# define NO_FIPS
-# endif
-# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
-# define NO_GMP
-# endif
-# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
-# define NO_IDEA
-# endif
-# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
-# define NO_JPAKE
-# endif
-# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
-# define NO_KRB5
-# endif
-# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
-# define NO_MDC2
-# endif
-# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
-# define NO_RC5
-# endif
-# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
-# define NO_RFC3779
-# endif
-# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
-# define NO_SEED
-# endif
-#endif
-
-/* crypto/opensslconf.h.in */
-
-#ifdef OPENSSL_DOING_MAKEDEPEND
-
-/* Include any symbols here that have to be explicitly set to enable a feature
- * that should be visible to makedepend.
- *
- * [Our "make depend" doesn't actually look at this, we use actual build settings
- * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
- */
-
-#ifndef OPENSSL_FIPS
-#define OPENSSL_FIPS
-#endif
-
-#endif
-
-/* Generate 80386 code? */
-#undef I386_ONLY
-
-#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
-#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-#define ENGINESDIR "/usr/local/ssl/lib/engines"
-#define OPENSSLDIR "/usr/local/ssl"
-#endif
-#endif
-
-#undef OPENSSL_UNISTD
-#define OPENSSL_UNISTD <unistd.h>
-#if !defined(SWIG)
-#include <unistd.h>
-#endif
-
-#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
-
-#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
-#define IDEA_INT unsigned int
-#endif
-
-#if defined(HEADER_MD2_H) && !defined(MD2_INT)
-#define MD2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC2_H) && !defined(RC2_INT)
-/* I need to put in a mod for the alpha - eay */
-#define RC2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC4_H)
-#if !defined(RC4_INT)
-/* using int types make the structure larger but make the code faster
- * on most boxes I have tested - up to %20 faster. */
-/*
- * I don't know what does "most" mean, but declaring "int" is a must on:
- * - Intel P6 because partial register stalls are very expensive;
- * - elder Alpha because it lacks byte load/store instructions;
- */
-#define RC4_INT unsigned int
-#endif
-#if !defined(RC4_CHUNK)
-/*
- * This enables code handling data aligned at natural CPU word
- * boundary. See crypto/rc4/rc4_enc.c for further details.
- */
-#define RC4_CHUNK unsigned long
-#endif
-#endif
-
-#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
-/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
- * %20 speed up (longs are 8 bytes, int's are 4). */
-#ifndef DES_LONG
-#define DES_LONG unsigned int
-#endif
-#endif
-
-#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
-#define CONFIG_HEADER_BN_H
-#undef BN_LLONG
-
-/* Should we define BN_DIV2W here? */
-
-/* Only one for the following should be defined */
-/* The prime number generation stuff may not work when
- * EIGHT_BIT but I don't care since I've only used this mode
- * for debuging the bignum libraries */
-#define SIXTY_FOUR_BIT_LONG
-#undef SIXTY_FOUR_BIT
-#undef THIRTY_TWO_BIT
-#undef SIXTEEN_BIT
-#undef EIGHT_BIT
-#endif
-
-#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
-#define CONFIG_HEADER_RC4_LOCL_H
-/* if this is defined data[i] is used instead of *data, this is a %20
- * speedup on x86 */
-#undef RC4_INDEX
-#endif
-
-#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
-#define CONFIG_HEADER_BF_LOCL_H
-#undef BF_PTR
-#endif /* HEADER_BF_LOCL_H */
-
-#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
-#define CONFIG_HEADER_DES_LOCL_H
-#ifndef DES_DEFAULT_OPTIONS
-/* the following is tweaked from a config script, that is why it is a
- * protected undef/define */
-#ifndef DES_PTR
-#undef DES_PTR
-#endif
-
-/* This helps C compiler generate the correct code for multiple functional
- * units. It reduces register dependancies at the expense of 2 more
- * registers */
-#ifndef DES_RISC1
-#undef DES_RISC1
-#endif
-
-#ifndef DES_RISC2
-#undef DES_RISC2
-#endif
-
-#if defined(DES_RISC1) && defined(DES_RISC2)
-YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-#endif
-
-/* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
-#ifndef DES_UNROLL
-#define DES_UNROLL
-#endif
-
-/* These default values were supplied by
- * Peter Gutman <pgut001@cs.auckland.ac.nz>
- * They are only used if nothing else has been defined */
-#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-/* Special defines which change the way the code is built depending on the
- CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
- even newer MIPS CPU's, but at the moment one size fits all for
- optimization options. Older Sparc's work better with only UNROLL, but
- there's no way to tell at compile time what it is you're running on */
-
-#if defined( sun ) /* Newer Sparc's */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#elif defined( __ultrix ) /* Older MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined( __osf1__ ) /* Alpha */
-# define DES_PTR
-# define DES_RISC2
-#elif defined ( _AIX ) /* RS6000 */
- /* Unknown */
-#elif defined( __hpux ) /* HP-PA */
- /* Unknown */
-#elif defined( __aux ) /* 68K */
- /* Unknown */
-#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
-# define DES_UNROLL
-#elif defined( __sgi ) /* Newer MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#endif /* Systems-specific speed defines */
-#endif
-
-#endif /* DES_DEFAULT_OPTIONS */
-#endif /* HEADER_DES_LOCL_H */
diff --git a/deps/openssl/config/k8/openssl/opensslconf-win32.h b/deps/openssl/config/k8/openssl/opensslconf-win32.h
deleted file mode 100644
index 8a37db987..000000000
--- a/deps/openssl/config/k8/openssl/opensslconf-win32.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/* opensslconf.h */
-/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
-
-/* OpenSSL was configured with the following options: */
-#ifndef OPENSSL_SYSNAME_WIN32
-# define OPENSSL_SYSNAME_WIN32
-#endif
-#ifndef OPENSSL_DOING_MAKEDEPEND
-
-
-#ifndef OPENSSL_NO_CAMELLIA
-# define OPENSSL_NO_CAMELLIA
-#endif
-#ifndef OPENSSL_NO_CAPIENG
-# define OPENSSL_NO_CAPIENG
-#endif
-#ifndef OPENSSL_NO_CMS
-# define OPENSSL_NO_CMS
-#endif
-#ifndef OPENSSL_NO_GMP
-# define OPENSSL_NO_GMP
-#endif
-#ifndef OPENSSL_NO_IDEA
-# define OPENSSL_NO_IDEA
-#endif
-#ifndef OPENSSL_NO_JPAKE
-# define OPENSSL_NO_JPAKE
-#endif
-#ifndef OPENSSL_NO_KRB5
-# define OPENSSL_NO_KRB5
-#endif
-#ifndef OPENSSL_NO_MDC2
-# define OPENSSL_NO_MDC2
-#endif
-#ifndef OPENSSL_NO_RC5
-# define OPENSSL_NO_RC5
-#endif
-#ifndef OPENSSL_NO_RFC3779
-# define OPENSSL_NO_RFC3779
-#endif
-#ifndef OPENSSL_NO_SEED
-# define OPENSSL_NO_SEED
-#endif
-
-#endif /* OPENSSL_DOING_MAKEDEPEND */
-
-#ifndef OPENSSL_THREADS
-# define OPENSSL_THREADS
-#endif
-
-/* The OPENSSL_NO_* macros are also defined as NO_* if the application
- asks for it. This is a transient feature that is provided for those
- who haven't had the time to do the appropriate changes in their
- applications. */
-#ifdef OPENSSL_ALGORITHM_DEFINES
-# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
-# define NO_CAMELLIA
-# endif
-# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
-# define NO_CAPIENG
-# endif
-# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
-# define NO_CMS
-# endif
-# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
-# define NO_GMP
-# endif
-# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
-# define NO_JPAKE
-# endif
-# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
-# define NO_KRB5
-# endif
-# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
-# define NO_MDC2
-# endif
-# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
-# define NO_RC5
-# endif
-# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
-# define NO_RFC3779
-# endif
-# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
-# define NO_SEED
-# endif
-#endif
-
-/* crypto/opensslconf.h.in */
-
-#ifdef OPENSSL_DOING_MAKEDEPEND
-
-/* Include any symbols here that have to be explicitly set to enable a feature
- * that should be visible to makedepend.
- *
- * [Our "make depend" doesn't actually look at this, we use actual build settings
- * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
- */
-
-#ifndef OPENSSL_FIPS
-#define OPENSSL_FIPS
-#endif
-
-#endif
-
-/* Generate 80386 code? */
-#undef I386_ONLY
-
-#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
-#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-#define ENGINESDIR "ssl/lib/engines"
-#define OPENSSLDIR "ssl"
-#endif
-#endif
-
-#undef OPENSSL_UNISTD
-#define OPENSSL_UNISTD <unistd.h>
-
-#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
-#define OPENSSL_EXPORT_VAR_AS_FUNCTION
-
-#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
-#define IDEA_INT unsigned int
-#endif
-
-#if defined(HEADER_MD2_H) && !defined(MD2_INT)
-#define MD2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC2_H) && !defined(RC2_INT)
-/* I need to put in a mod for the alpha - eay */
-#define RC2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC4_H)
-#if !defined(RC4_INT)
-/* using int types make the structure larger but make the code faster
- * on most boxes I have tested - up to %20 faster. */
-/*
- * I don't know what does "most" mean, but declaring "int" is a must on:
- * - Intel P6 because partial register stalls are very expensive;
- * - elder Alpha because it lacks byte load/store instructions;
- */
-#define RC4_INT unsigned int
-#endif
-#if !defined(RC4_CHUNK)
-/*
- * This enables code handling data aligned at natural CPU word
- * boundary. See crypto/rc4/rc4_enc.c for further details.
- */
-#define RC4_CHUNK unsigned long long
-#endif
-#endif
-
-#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
-/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
- * %20 speed up (longs are 8 bytes, int's are 4). */
-#ifndef DES_LONG
-#define DES_LONG unsigned int
-#endif
-#endif
-
-#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
-#define CONFIG_HEADER_BN_H
-#undef BN_LLONG
-
-/* Should we define BN_DIV2W here? */
-
-/* Only one for the following should be defined */
-/* The prime number generation stuff may not work when
- * EIGHT_BIT but I don't care since I've only used this mode
- * for debuging the bignum libraries */
-#undef SIXTY_FOUR_BIT_LONG
-#define SIXTY_FOUR_BIT
-#undef THIRTY_TWO_BIT
-#undef SIXTEEN_BIT
-#undef EIGHT_BIT
-#endif
-
-#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
-#define CONFIG_HEADER_RC4_LOCL_H
-/* if this is defined data[i] is used instead of *data, this is a %20
- * speedup on x86 */
-#undef RC4_INDEX
-#endif
-
-#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
-#define CONFIG_HEADER_BF_LOCL_H
-#undef BF_PTR
-#endif /* HEADER_BF_LOCL_H */
-
-#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
-#define CONFIG_HEADER_DES_LOCL_H
-#ifndef DES_DEFAULT_OPTIONS
-/* the following is tweaked from a config script, that is why it is a
- * protected undef/define */
-#ifndef DES_PTR
-#undef DES_PTR
-#endif
-
-/* This helps C compiler generate the correct code for multiple functional
- * units. It reduces register dependancies at the expense of 2 more
- * registers */
-#ifndef DES_RISC1
-#undef DES_RISC1
-#endif
-
-#ifndef DES_RISC2
-#undef DES_RISC2
-#endif
-
-#if defined(DES_RISC1) && defined(DES_RISC2)
-YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-#endif
-
-/* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
-#ifndef DES_UNROLL
-#undef DES_UNROLL
-#endif
-
-/* These default values were supplied by
- * Peter Gutman <pgut001@cs.auckland.ac.nz>
- * They are only used if nothing else has been defined */
-#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-/* Special defines which change the way the code is built depending on the
- CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
- even newer MIPS CPU's, but at the moment one size fits all for
- optimization options. Older Sparc's work better with only UNROLL, but
- there's no way to tell at compile time what it is you're running on */
-
-#if defined( sun ) /* Newer Sparc's */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#elif defined( __ultrix ) /* Older MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined( __osf1__ ) /* Alpha */
-# define DES_PTR
-# define DES_RISC2
-#elif defined ( _AIX ) /* RS6000 */
- /* Unknown */
-#elif defined( __hpux ) /* HP-PA */
- /* Unknown */
-#elif defined( __aux ) /* 68K */
- /* Unknown */
-#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
-# define DES_UNROLL
-#elif defined( __sgi ) /* Newer MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#endif /* Systems-specific speed defines */
-#endif
-
-#endif /* DES_DEFAULT_OPTIONS */
-#endif /* HEADER_DES_LOCL_H */
diff --git a/deps/openssl/config/k8/openssl/opensslconf.h b/deps/openssl/config/k8/openssl/opensslconf.h
deleted file mode 100644
index 0ea58de1b..000000000
--- a/deps/openssl/config/k8/openssl/opensslconf.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifdef WIN32
-#include "opensslconf-win32.h"
-#else
-#include "opensslconf-posix.h"
-#endif
diff --git a/deps/openssl/config/opensslconf.h b/deps/openssl/config/opensslconf.h
new file mode 100644
index 000000000..9bf23692d
--- /dev/null
+++ b/deps/openssl/config/opensslconf.h
@@ -0,0 +1,333 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+/* OpenSSL was configured with the following options: */
+#undef OPENSSL_SYSNAME_WIN32
+#if defined(_WIN32)
+# define OPENSSL_SYSNAME_WIN32
+#endif
+
+#ifndef OPENSSL_DOING_MAKEDEPEND
+# ifndef OPENSSL_NO_CAPIENG
+# define OPENSSL_NO_CAPIENG
+# endif
+# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+# define OPENSSL_NO_EC_NISTP_64_GCC_128
+# endif
+# ifndef OPENSSL_NO_GMP
+# define OPENSSL_NO_GMP
+# endif
+# ifndef OPENSSL_NO_GOST
+# define OPENSSL_NO_GOST
+# endif
+# ifndef OPENSSL_NO_HW_PADLOCK
+# define OPENSSL_NO_HW_PADLOCK
+# endif
+# ifndef OPENSSL_NO_JPAKE
+# define OPENSSL_NO_JPAKE
+# endif
+# ifndef OPENSSL_NO_KRB5
+# define OPENSSL_NO_KRB5
+# endif
+# ifndef OPENSSL_NO_MD2
+# define OPENSSL_NO_MD2
+# endif
+# ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+# endif
+# ifndef OPENSSL_NO_RFC3779
+# define OPENSSL_NO_RFC3779
+# endif
+# ifndef OPENSSL_NO_SCTP
+# define OPENSSL_NO_SCTP
+# endif
+# ifndef OPENSSL_NO_STORE
+# define OPENSSL_NO_STORE
+# endif
+#endif /* OPENSSL_DOING_MAKEDEPEND */
+
+#ifndef OPENSSL_THREADS
+# define OPENSSL_THREADS
+#endif
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define OPENSSL_NO_DYNAMIC_ENGINE
+#endif
+
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application
+ asks for it. This is a transient feature that is provided for those
+ who haven't had the time to do the appropriate changes in their
+ applications. */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
+# define NO_CAMELLIA
+# endif
+# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
+# define NO_CAPIENG
+# endif
+# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
+# define NO_CAST
+# endif
+# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
+# define NO_CMS
+# endif
+# if defined(OPENSSL_NO_FIPS) && !defined(NO_FIPS)
+# define NO_FIPS
+# endif
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
+# define NO_GMP
+# endif
+# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
+# define NO_IDEA
+# endif
+# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
+# define NO_JPAKE
+# endif
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
+# define NO_KRB5
+# endif
+# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
+# define NO_MD2
+# endif
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
+# define NO_MDC2
+# endif
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
+# define NO_RC5
+# endif
+# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
+# define NO_RFC3779
+# endif
+# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
+# define NO_SEED
+# endif
+# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)
+# define NO_SHA0
+# endif
+# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
+# define NO_STORE
+# endif
+# if defined(OPENSSL_NO_WHRLPOOL) && !defined(NO_WHRLPOOL)
+# define NO_WHRLPOOL
+# endif
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
+# define NO_MDC2
+# endif
+#endif
+
+/* crypto/opensslconf.h.in */
+
+#ifdef OPENSSL_DOING_MAKEDEPEND
+ /* Include any symbols here that have to be explicitly set to enable a feature
+ * that should be visible to makedepend.
+ *
+ * [Our "make depend" doesn't actually look at this, we use actual build settings
+ * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
+ */
+# ifndef OPENSSL_FIPS
+# define OPENSSL_FIPS
+# endif
+#endif
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+# if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+# if defined(_WIN32)
+# define ENGINESDIR "ssl/lib/engines"
+# define OPENSSLDIR "ssl"
+# else
+# define ENGINESDIR "/usr/local/ssl/lib/engines"
+# define OPENSSLDIR "/usr/local/ssl"
+# endif
+# endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+#if !defined(_WIN32) && !defined(__arm__) && !defined(__mips__) && !defined(SWIG)
+# include <unistd.h>
+#endif
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+#if defined(_WIN32)
+# define OPENSSL_EXPORT_VAR_AS_FUNCTION
+#endif
+
+#if defined(HEADER_IDEA_H)
+# undef IDEA_INT
+# define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H)
+# undef MD2_INT
+# define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H)
+/* I need to put in a mod for the alpha - eay */
+# undef RC2_INT
+# define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+ /* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+ /*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+# undef RC4_INT
+# if defined(__arm__)
+# define RC4_INT unsigned char
+# else
+# define RC4_INT unsigned int
+# endif
+
+ /*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+# undef RC4_CHUNK
+# if (defined(_M_X64) || defined(__x86_64__)) && defined(_WIN32)
+# define RC4_CHUNK unsigned long long
+# elif (defined(_M_X64) || defined(__x86_64__)) && !defined(_WIN32)
+# define RC4_CHUNK unsigned long
+# elif defined(__arm__)
+# define RC4_CHUNK unsigned long
+# else
+ /* On x86 RC4_CHUNK is not defined */
+# endif
+#endif
+
+#if defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)
+ /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+# undef DES_LONG
+# if defined(_M_X64) || defined(__x86_64__) || defined(__arm__) || defined(__mips__)
+# define DES_LONG unsigned int
+# elif defined(_M_IX86) || defined(__i386__)
+# define DES_LONG unsigned long
+# endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+# define CONFIG_HEADER_BN_H
+
+# undef BL_LLONG
+# if defined(_M_IX86) || defined(__i386__) || defined(__arm__)
+# define BL_LLONG
+# endif
+
+ /* Should we define BN_DIV2W here? */
+
+ /* Only one for the following should be defined */
+ /* The prime number generation stuff may not work when
+ * EIGHT_BIT but I don't care since I've only used this mode
+ * for debuging the bignum libraries */
+# undef SIXTY_FOUR_BIT_LONG
+# undef SIXTY_FOUR_BIT
+# undef THIRTY_TWO_BIT
+# undef SIXTEEN_BIT
+# undef EIGHT_BIT
+# if (defined(_M_X64) || defined(__x86_64__)) && defined(_WIN32)
+# define SIXTY_FOUR_BIT
+# elif (defined(_M_X64) || defined(__x86_64__)) && !defined(_WIN32)
+# define SIXTY_FOUR_BIT_LONG
+# elif defined(_M_IX86) || defined(__i386__) || defined(__arm__) || defined(__mips__)
+# define THIRTY_TWO_BIT
+# endif
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+# define CONFIG_HEADER_RC4_LOCL_H
+ /* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+# undef RC4_INDEX
+# if defined(_M_IX86) || defined(__i386__)
+# define RC4_INDEX
+# endif
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+# define CONFIG_HEADER_BF_LOCL_H
+# undef BF_PTR
+# if defined(__arm__)
+# define BF_PTR
+# endif
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+# define CONFIG_HEADER_DES_LOCL_H
+
+# ifndef DES_DEFAULT_OPTIONS
+ /* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+# undef DES_PTR
+# if !defined(_WIN32) && (defined(_M_IX86) || defined(__i386__))
+# define DES_PTR
+# endif
+
+ /* This helps C compiler generate the correct code for multiple functional
+ * units. It reduces register dependancies at the expense of 2 more
+ * registers */
+# undef DES_RISC1
+# if !defined(_WIN32) && (defined(_M_IX86) || defined(__i386__))
+# define DES_RISC1
+# endif
+
+# undef DES_RISC2
+
+# if defined(DES_RISC1) && defined(DES_RISC2)
+# error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+# endif
+
+ /* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+# undef DES_UNROLL
+# if !defined(_WIN32)
+# define DES_UNROLL
+# endif
+
+ /* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+# if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+ /* Special defines which change the way the code is built depending on the
+ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+ even newer MIPS CPU's, but at the moment one size fits all for
+ optimization options. Older Sparc's work better with only UNROLL, but
+ there's no way to tell at compile time what it is you're running on */
+# if defined( sun ) /* Newer Sparc's */
+# define DES_PTR
+# define DES_RISC1
+# define DES_UNROLL
+# elif defined( __ultrix ) /* Older MIPS */
+# define DES_PTR
+# define DES_RISC2
+# define DES_UNROLL
+# elif defined( __osf1__ ) /* Alpha */
+# define DES_PTR
+# define DES_RISC2
+# elif defined ( _AIX ) /* RS6000 */
+ /* Unknown */
+# elif defined( __hpux ) /* HP-PA */
+ /* Unknown */
+# elif defined( __aux ) /* 68K */
+ /* Unknown */
+# elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
+# define DES_UNROLL
+# elif defined( __sgi ) /* Newer MIPS */
+# define DES_PTR
+# define DES_RISC2
+# define DES_UNROLL
+# elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */
+# define DES_PTR
+# define DES_RISC1
+# define DES_UNROLL
+# endif /* Systems-specific speed defines */
+# endif
+
+# endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
diff --git a/deps/openssl/config/piii/openssl/opensslconf-posix.h b/deps/openssl/config/piii/openssl/opensslconf-posix.h
deleted file mode 100644
index 36e305a2e..000000000
--- a/deps/openssl/config/piii/openssl/opensslconf-posix.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/* opensslconf.h */
-/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
-
-/* OpenSSL was configured with the following options: */
-#ifndef OPENSSL_DOING_MAKEDEPEND
-
-
-#ifndef OPENSSL_NO_CAMELLIA
-# define OPENSSL_NO_CAMELLIA
-#endif
-#ifndef OPENSSL_NO_CAPIENG
-# define OPENSSL_NO_CAPIENG
-#endif
-#ifndef OPENSSL_NO_CMS
-# define OPENSSL_NO_CMS
-#endif
-#ifndef OPENSSL_NO_FIPS
-# define OPENSSL_NO_FIPS
-#endif
-#ifndef OPENSSL_NO_GMP
-# define OPENSSL_NO_GMP
-#endif
-#ifndef OPENSSL_NO_IDEA
-# define OPENSSL_NO_IDEA
-#endif
-#ifndef OPENSSL_NO_JPAKE
-# define OPENSSL_NO_JPAKE
-#endif
-#ifndef OPENSSL_NO_KRB5
-# define OPENSSL_NO_KRB5
-#endif
-#ifndef OPENSSL_NO_MDC2
-# define OPENSSL_NO_MDC2
-#endif
-#ifndef OPENSSL_NO_RC5
-# define OPENSSL_NO_RC5
-#endif
-#ifndef OPENSSL_NO_RFC3779
-# define OPENSSL_NO_RFC3779
-#endif
-#ifndef OPENSSL_NO_SEED
-# define OPENSSL_NO_SEED
-#endif
-
-#endif /* OPENSSL_DOING_MAKEDEPEND */
-
-#ifndef OPENSSL_THREADS
-# define OPENSSL_THREADS
-#endif
-#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-# define OPENSSL_NO_DYNAMIC_ENGINE
-#endif
-
-/* The OPENSSL_NO_* macros are also defined as NO_* if the application
- asks for it. This is a transient feature that is provided for those
- who haven't had the time to do the appropriate changes in their
- applications. */
-#ifdef OPENSSL_ALGORITHM_DEFINES
-# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
-# define NO_CAMELLIA
-# endif
-# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
-# define NO_CAPIENG
-# endif
-# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
-# define NO_CMS
-# endif
-# if defined(OPENSSL_NO_FIPS) && !defined(NO_FIPS)
-# define NO_FIPS
-# endif
-# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
-# define NO_GMP
-# endif
-# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
-# define NO_IDEA
-# endif
-# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
-# define NO_JPAKE
-# endif
-# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
-# define NO_KRB5
-# endif
-# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
-# define NO_MDC2
-# endif
-# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
-# define NO_RC5
-# endif
-# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
-# define NO_RFC3779
-# endif
-# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
-# define NO_SEED
-# endif
-#endif
-
-/* crypto/opensslconf.h.in */
-
-#ifdef OPENSSL_DOING_MAKEDEPEND
-
-/* Include any symbols here that have to be explicitly set to enable a feature
- * that should be visible to makedepend.
- *
- * [Our "make depend" doesn't actually look at this, we use actual build settings
- * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
- */
-
-#ifndef OPENSSL_FIPS
-#define OPENSSL_FIPS
-#endif
-
-#endif
-
-/* Generate 80386 code? */
-#undef I386_ONLY
-
-#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
-#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-#define ENGINESDIR "/usr/local/ssl/lib/engines"
-#define OPENSSLDIR "/usr/local/ssl"
-#endif
-#endif
-
-#undef OPENSSL_UNISTD
-#define OPENSSL_UNISTD <unistd.h>
-#if !defined(SWIG)
-#include <unistd.h>
-#endif
-
-#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
-
-#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
-#define IDEA_INT unsigned int
-#endif
-
-#if defined(HEADER_MD2_H) && !defined(MD2_INT)
-#define MD2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC2_H) && !defined(RC2_INT)
-/* I need to put in a mod for the alpha - eay */
-#define RC2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC4_H)
-#if !defined(RC4_INT)
-/* using int types make the structure larger but make the code faster
- * on most boxes I have tested - up to %20 faster. */
-/*
- * I don't know what does "most" mean, but declaring "int" is a must on:
- * - Intel P6 because partial register stalls are very expensive;
- * - elder Alpha because it lacks byte load/store instructions;
- */
-#define RC4_INT unsigned int
-#endif
-#if !defined(RC4_CHUNK)
-/*
- * This enables code handling data aligned at natural CPU word
- * boundary. See crypto/rc4/rc4_enc.c for further details.
- */
-#undef RC4_CHUNK
-#endif
-#endif
-
-#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
-/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
- * %20 speed up (longs are 8 bytes, int's are 4). */
-#ifndef DES_LONG
-#define DES_LONG unsigned long
-#endif
-#endif
-
-#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
-#define CONFIG_HEADER_BN_H
-#define BN_LLONG
-
-/* Should we define BN_DIV2W here? */
-
-/* Only one for the following should be defined */
-/* The prime number generation stuff may not work when
- * EIGHT_BIT but I don't care since I've only used this mode
- * for debuging the bignum libraries */
-#undef SIXTY_FOUR_BIT_LONG
-#undef SIXTY_FOUR_BIT
-#define THIRTY_TWO_BIT
-#undef SIXTEEN_BIT
-#undef EIGHT_BIT
-#endif
-
-#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
-#define CONFIG_HEADER_RC4_LOCL_H
-/* if this is defined data[i] is used instead of *data, this is a %20
- * speedup on x86 */
-#define RC4_INDEX
-#endif
-
-#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
-#define CONFIG_HEADER_BF_LOCL_H
-#undef BF_PTR
-#endif /* HEADER_BF_LOCL_H */
-
-#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
-#define CONFIG_HEADER_DES_LOCL_H
-#ifndef DES_DEFAULT_OPTIONS
-/* the following is tweaked from a config script, that is why it is a
- * protected undef/define */
-#ifndef DES_PTR
-#define DES_PTR
-#endif
-
-/* This helps C compiler generate the correct code for multiple functional
- * units. It reduces register dependancies at the expense of 2 more
- * registers */
-#ifndef DES_RISC1
-#define DES_RISC1
-#endif
-
-#ifndef DES_RISC2
-#undef DES_RISC2
-#endif
-
-#if defined(DES_RISC1) && defined(DES_RISC2)
-YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-#endif
-
-/* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
-#ifndef DES_UNROLL
-#define DES_UNROLL
-#endif
-
-/* These default values were supplied by
- * Peter Gutman <pgut001@cs.auckland.ac.nz>
- * They are only used if nothing else has been defined */
-#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-/* Special defines which change the way the code is built depending on the
- CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
- even newer MIPS CPU's, but at the moment one size fits all for
- optimization options. Older Sparc's work better with only UNROLL, but
- there's no way to tell at compile time what it is you're running on */
-
-#if defined( sun ) /* Newer Sparc's */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#elif defined( __ultrix ) /* Older MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined( __osf1__ ) /* Alpha */
-# define DES_PTR
-# define DES_RISC2
-#elif defined ( _AIX ) /* RS6000 */
- /* Unknown */
-#elif defined( __hpux ) /* HP-PA */
- /* Unknown */
-#elif defined( __aux ) /* 68K */
- /* Unknown */
-#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
-# define DES_UNROLL
-#elif defined( __sgi ) /* Newer MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#endif /* Systems-specific speed defines */
-#endif
-
-#endif /* DES_DEFAULT_OPTIONS */
-#endif /* HEADER_DES_LOCL_H */
diff --git a/deps/openssl/config/piii/openssl/opensslconf-win32.h b/deps/openssl/config/piii/openssl/opensslconf-win32.h
deleted file mode 100644
index 529aec6fd..000000000
--- a/deps/openssl/config/piii/openssl/opensslconf-win32.h
+++ /dev/null
@@ -1,274 +0,0 @@
-/* opensslconf.h */
-/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
-
-/* OpenSSL was configured with the following options: */
-#ifndef OPENSSL_SYSNAME_WIN32
-# define OPENSSL_SYSNAME_WIN32
-#endif
-#ifndef OPENSSL_DOING_MAKEDEPEND
-
-
-#ifndef OPENSSL_NO_CAMELLIA
-# define OPENSSL_NO_CAMELLIA
-#endif
-#ifndef OPENSSL_NO_CAPIENG
-# define OPENSSL_NO_CAPIENG
-#endif
-#ifndef OPENSSL_NO_CMS
-# define OPENSSL_NO_CMS
-#endif
-#ifndef OPENSSL_NO_FIPS
-# define OPENSSL_NO_FIPS
-#endif
-#ifndef OPENSSL_NO_GMP
-# define OPENSSL_NO_GMP
-#endif
-#ifndef OPENSSL_NO_IDEA
-# define OPENSSL_NO_IDEA
-#endif
-#ifndef OPENSSL_NO_JPAKE
-# define OPENSSL_NO_JPAKE
-#endif
-#ifndef OPENSSL_NO_KRB5
-# define OPENSSL_NO_KRB5
-#endif
-#ifndef OPENSSL_NO_MDC2
-# define OPENSSL_NO_MDC2
-#endif
-#ifndef OPENSSL_NO_RC5
-# define OPENSSL_NO_RC5
-#endif
-#ifndef OPENSSL_NO_RFC3779
-# define OPENSSL_NO_RFC3779
-#endif
-#ifndef OPENSSL_NO_SEED
-# define OPENSSL_NO_SEED
-#endif
-
-#endif /* OPENSSL_DOING_MAKEDEPEND */
-
-#ifndef OPENSSL_THREADS
-# define OPENSSL_THREADS
-#endif
-#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-# define OPENSSL_NO_DYNAMIC_ENGINE
-#endif
-
-/* The OPENSSL_NO_* macros are also defined as NO_* if the application
- asks for it. This is a transient feature that is provided for those
- who haven't had the time to do the appropriate changes in their
- applications. */
-#ifdef OPENSSL_ALGORITHM_DEFINES
-# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
-# define NO_CAMELLIA
-# endif
-# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
-# define NO_CAPIENG
-# endif
-# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
-# define NO_CMS
-# endif
-# if defined(OPENSSL_NO_FIPS) && !defined(NO_FIPS)
-# define NO_FIPS
-# endif
-# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
-# define NO_GMP
-# endif
-# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
-# define NO_IDEA
-# endif
-# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
-# define NO_JPAKE
-# endif
-# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
-# define NO_KRB5
-# endif
-# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
-# define NO_MDC2
-# endif
-# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
-# define NO_RC5
-# endif
-# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
-# define NO_RFC3779
-# endif
-# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
-# define NO_SEED
-# endif
-#endif
-
-/* crypto/opensslconf.h.in */
-
-#ifdef OPENSSL_DOING_MAKEDEPEND
-
-/* Include any symbols here that have to be explicitly set to enable a feature
- * that should be visible to makedepend.
- *
- * [Our "make depend" doesn't actually look at this, we use actual build settings
- * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
- */
-
-#ifndef OPENSSL_FIPS
-#define OPENSSL_FIPS
-#endif
-
-#endif
-
-/* Generate 80386 code? */
-#undef I386_ONLY
-
-#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
-#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-#define ENGINESDIR "ssl/lib/engines"
-#define OPENSSLDIR "ssl"
-#endif
-#endif
-
-#undef OPENSSL_UNISTD
-#define OPENSSL_UNISTD <unistd.h>
-
-#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
-#define OPENSSL_EXPORT_VAR_AS_FUNCTION
-
-#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
-#define IDEA_INT unsigned int
-#endif
-
-#if defined(HEADER_MD2_H) && !defined(MD2_INT)
-#define MD2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC2_H) && !defined(RC2_INT)
-/* I need to put in a mod for the alpha - eay */
-#define RC2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC4_H)
-#if !defined(RC4_INT)
-/* using int types make the structure larger but make the code faster
- * on most boxes I have tested - up to %20 faster. */
-/*
- * I don't know what does "most" mean, but declaring "int" is a must on:
- * - Intel P6 because partial register stalls are very expensive;
- * - elder Alpha because it lacks byte load/store instructions;
- */
-#define RC4_INT unsigned int
-#endif
-#if !defined(RC4_CHUNK)
-/*
- * This enables code handling data aligned at natural CPU word
- * boundary. See crypto/rc4/rc4_enc.c for further details.
- */
-#undef RC4_CHUNK
-#endif
-#endif
-
-#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
-/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
- * %20 speed up (longs are 8 bytes, int's are 4). */
-#ifndef DES_LONG
-#define DES_LONG unsigned long
-#endif
-#endif
-
-#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
-#define CONFIG_HEADER_BN_H
-#define BN_LLONG
-
-/* Should we define BN_DIV2W here? */
-
-/* Only one for the following should be defined */
-/* The prime number generation stuff may not work when
- * EIGHT_BIT but I don't care since I've only used this mode
- * for debuging the bignum libraries */
-#undef SIXTY_FOUR_BIT_LONG
-#undef SIXTY_FOUR_BIT
-#define THIRTY_TWO_BIT
-#undef SIXTEEN_BIT
-#undef EIGHT_BIT
-#endif
-
-#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
-#define CONFIG_HEADER_RC4_LOCL_H
-/* if this is defined data[i] is used instead of *data, this is a %20
- * speedup on x86 */
-#define RC4_INDEX
-#endif
-
-#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
-#define CONFIG_HEADER_BF_LOCL_H
-#undef BF_PTR
-#endif /* HEADER_BF_LOCL_H */
-
-#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
-#define CONFIG_HEADER_DES_LOCL_H
-#ifndef DES_DEFAULT_OPTIONS
-/* the following is tweaked from a config script, that is why it is a
- * protected undef/define */
-#ifndef DES_PTR
-#undef DES_PTR
-#endif
-
-/* This helps C compiler generate the correct code for multiple functional
- * units. It reduces register dependancies at the expense of 2 more
- * registers */
-#ifndef DES_RISC1
-#undef DES_RISC1
-#endif
-
-#ifndef DES_RISC2
-#undef DES_RISC2
-#endif
-
-#if defined(DES_RISC1) && defined(DES_RISC2)
-YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-#endif
-
-/* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
-#ifndef DES_UNROLL
-#undef DES_UNROLL
-#endif
-
-/* These default values were supplied by
- * Peter Gutman <pgut001@cs.auckland.ac.nz>
- * They are only used if nothing else has been defined */
-#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-/* Special defines which change the way the code is built depending on the
- CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
- even newer MIPS CPU's, but at the moment one size fits all for
- optimization options. Older Sparc's work better with only UNROLL, but
- there's no way to tell at compile time what it is you're running on */
-
-#if defined( sun ) /* Newer Sparc's */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#elif defined( __ultrix ) /* Older MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined( __osf1__ ) /* Alpha */
-# define DES_PTR
-# define DES_RISC2
-#elif defined ( _AIX ) /* RS6000 */
- /* Unknown */
-#elif defined( __hpux ) /* HP-PA */
- /* Unknown */
-#elif defined( __aux ) /* 68K */
- /* Unknown */
-#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
-# define DES_UNROLL
-#elif defined( __sgi ) /* Newer MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#endif /* Systems-specific speed defines */
-#endif
-
-#endif /* DES_DEFAULT_OPTIONS */
-#endif /* HEADER_DES_LOCL_H */
diff --git a/deps/openssl/config/piii/openssl/opensslconf.h b/deps/openssl/config/piii/openssl/opensslconf.h
deleted file mode 100644
index 0ea58de1b..000000000
--- a/deps/openssl/config/piii/openssl/opensslconf.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifdef WIN32
-#include "opensslconf-win32.h"
-#else
-#include "opensslconf-posix.h"
-#endif
diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp
index 6ece3ee3f..d3f05e6a8 100644
--- a/deps/openssl/openssl.gyp
+++ b/deps/openssl/openssl.gyp
@@ -3,22 +3,20 @@
# found in the LICENSE file.
{
+ 'variables': {
+ 'is_clang': 0,
+ 'gcc_version': 0,
+ },
+
'targets': [
{
'target_name': 'openssl',
'type': '<(library)',
'defines': [
+ # No clue what these are for.
'L_ENDIAN',
- 'OPENSSL_THREADS',
'PURIFY',
- '_REENTRANT',
- # We do not use TLS over UDP on Chromium so far.
- 'OPENSSL_NO_DTLS1',
- 'OPENSSL_NO_SOCK',
- 'OPENSSL_NO_DGRAM',
- # Work around brain dead SunOS linker.
- 'OPENSSL_NO_GOST',
- 'OPENSSL_NO_HW_PADLOCK',
+ '_REENTRANT'
],
'sources': [
'openssl/ssl/bio_ssl.c',
@@ -28,6 +26,7 @@
'openssl/ssl/d1_lib.c',
'openssl/ssl/d1_meth.c',
'openssl/ssl/d1_pkt.c',
+ 'openssl/ssl/d1_srtp.c',
'openssl/ssl/d1_srvr.c',
'openssl/ssl/kssl.c',
'openssl/ssl/s23_clnt.c',
@@ -48,6 +47,7 @@
'openssl/ssl/s3_meth.c',
'openssl/ssl/s3_pkt.c',
'openssl/ssl/s3_srvr.c',
+ 'openssl/ssl/s3_cbc.c',
'openssl/ssl/ssl_algs.c',
'openssl/ssl/ssl_asn1.c',
'openssl/ssl/ssl_cert.c',
@@ -65,7 +65,7 @@
'openssl/ssl/t1_meth.c',
'openssl/ssl/t1_reneg.c',
'openssl/ssl/t1_srvr.c',
-
+ 'openssl/ssl/tls_srp.c',
'openssl/crypto/aes/aes_cfb.c',
'openssl/crypto/aes/aes_ctr.c',
'openssl/crypto/aes/aes_ecb.c',
@@ -199,19 +199,22 @@
'openssl/crypto/bn/bn_sqr.c',
'openssl/crypto/bn/bn_sqrt.c',
'openssl/crypto/bn/bn_word.c',
+ 'openssl/crypto/bn/bn_x931p.c',
'openssl/crypto/buffer/buf_err.c',
+ 'openssl/crypto/buffer/buf_str.c',
'openssl/crypto/buffer/buffer.c',
- 'openssl/crypto/camellia/camellia.c',
- 'openssl/crypto/camellia/cmll_cbc.c',
'openssl/crypto/camellia/cmll_cfb.c',
'openssl/crypto/camellia/cmll_ctr.c',
'openssl/crypto/camellia/cmll_ecb.c',
- 'openssl/crypto/camellia/cmll_misc.c',
'openssl/crypto/camellia/cmll_ofb.c',
+ 'openssl/crypto/camellia/cmll_utl.c',
'openssl/crypto/cast/c_cfb64.c',
'openssl/crypto/cast/c_ecb.c',
'openssl/crypto/cast/c_ofb64.c',
'openssl/crypto/cast/c_skey.c',
+ 'openssl/crypto/cmac/cm_ameth.c',
+ 'openssl/crypto/cmac/cm_pmeth.c',
+ 'openssl/crypto/cmac/cmac.c',
'openssl/crypto/cms/cms_asn1.c',
'openssl/crypto/cms/cms_att.c',
'openssl/crypto/cms/cms_cd.c',
@@ -222,6 +225,7 @@
'openssl/crypto/cms/cms_ess.c',
'openssl/crypto/cms/cms_io.c',
'openssl/crypto/cms/cms_lib.c',
+ 'openssl/crypto/cms/cms_pwri.c',
'openssl/crypto/cms/cms_sd.c',
'openssl/crypto/cms/cms_smime.c',
'openssl/crypto/comp/c_rle.c',
@@ -285,15 +289,20 @@
'openssl/crypto/dsa/dsa_sign.c',
'openssl/crypto/dsa/dsa_vrf.c',
'openssl/crypto/dso/dso_beos.c',
+ 'openssl/crypto/dso/dso_dl.c',
+ 'openssl/crypto/dso/dso_dlfcn.c',
'openssl/crypto/dso/dso_err.c',
'openssl/crypto/dso/dso_lib.c',
'openssl/crypto/dso/dso_null.c',
'openssl/crypto/dso/dso_openssl.c',
+ 'openssl/crypto/dso/dso_vms.c',
+ 'openssl/crypto/dso/dso_win32.c',
'openssl/crypto/ebcdic.c',
'openssl/crypto/ec/ec2_mult.c',
+ 'openssl/crypto/ec/ec2_oct.c',
'openssl/crypto/ec/ec2_smpl.c',
- 'openssl/crypto/ec/ec_asn1.c',
'openssl/crypto/ec/ec_ameth.c',
+ 'openssl/crypto/ec/ec_asn1.c',
'openssl/crypto/ec/ec_check.c',
'openssl/crypto/ec/ec_curve.c',
'openssl/crypto/ec/ec_cvt.c',
@@ -301,11 +310,17 @@
'openssl/crypto/ec/ec_key.c',
'openssl/crypto/ec/ec_lib.c',
'openssl/crypto/ec/ec_mult.c',
+ 'openssl/crypto/ec/ec_oct.c',
'openssl/crypto/ec/ec_pmeth.c',
'openssl/crypto/ec/ec_print.c',
'openssl/crypto/ec/eck_prn.c',
'openssl/crypto/ec/ecp_mont.c',
'openssl/crypto/ec/ecp_nist.c',
+ 'openssl/crypto/ec/ecp_nistp224.c',
+ 'openssl/crypto/ec/ecp_nistp256.c',
+ 'openssl/crypto/ec/ecp_nistp521.c',
+ 'openssl/crypto/ec/ecp_nistputil.c',
+ 'openssl/crypto/ec/ecp_oct.c',
'openssl/crypto/ec/ecp_smpl.c',
'openssl/crypto/ecdh/ech_err.c',
'openssl/crypto/ecdh/ech_key.c',
@@ -329,6 +344,8 @@
'openssl/crypto/engine/eng_list.c',
'openssl/crypto/engine/eng_openssl.c',
'openssl/crypto/engine/eng_pkey.c',
+ 'openssl/crypto/engine/eng_rdrand.c',
+ 'openssl/crypto/engine/eng_rsax.c',
'openssl/crypto/engine/eng_table.c',
'openssl/crypto/engine/tb_asnmth.c',
'openssl/crypto/engine/tb_cipher.c',
@@ -353,22 +370,27 @@
'openssl/crypto/evp/c_alld.c',
'openssl/crypto/evp/digest.c',
'openssl/crypto/evp/e_aes.c',
+ 'openssl/crypto/evp/e_aes_cbc_hmac_sha1.c',
'openssl/crypto/evp/e_bf.c',
'openssl/crypto/evp/e_camellia.c',
'openssl/crypto/evp/e_cast.c',
'openssl/crypto/evp/e_des.c',
'openssl/crypto/evp/e_des3.c',
+ 'openssl/crypto/evp/e_idea.c',
'openssl/crypto/evp/e_null.c',
'openssl/crypto/evp/e_old.c',
'openssl/crypto/evp/e_rc2.c',
'openssl/crypto/evp/e_rc4.c',
+ 'openssl/crypto/evp/e_rc4_hmac_md5.c',
'openssl/crypto/evp/e_rc5.c',
'openssl/crypto/evp/e_seed.c',
'openssl/crypto/evp/e_xcbc_d.c',
'openssl/crypto/evp/encode.c',
'openssl/crypto/evp/evp_acnf.c',
+ 'openssl/crypto/evp/evp_cnf.c',
'openssl/crypto/evp/evp_enc.c',
'openssl/crypto/evp/evp_err.c',
+ 'openssl/crypto/evp/evp_fips.c',
'openssl/crypto/evp/evp_key.c',
'openssl/crypto/evp/evp_lib.c',
'openssl/crypto/evp/evp_pbe.c',
@@ -400,9 +422,15 @@
'openssl/crypto/evp/pmeth_gn.c',
'openssl/crypto/evp/pmeth_lib.c',
'openssl/crypto/ex_data.c',
+ 'openssl/crypto/fips_ers.c',
'openssl/crypto/hmac/hm_ameth.c',
'openssl/crypto/hmac/hm_pmeth.c',
'openssl/crypto/hmac/hmac.c',
+ 'openssl/crypto/idea/i_cbc.c',
+ 'openssl/crypto/idea/i_cfb64.c',
+ 'openssl/crypto/idea/i_ecb.c',
+ 'openssl/crypto/idea/i_ofb64.c',
+ 'openssl/crypto/idea/i_skey.c',
'openssl/crypto/krb5/krb5_asn.c',
'openssl/crypto/lhash/lh_stats.c',
'openssl/crypto/lhash/lhash.c',
@@ -412,16 +440,21 @@
'openssl/crypto/md4/md4_one.c',
'openssl/crypto/md5/md5_dgst.c',
'openssl/crypto/md5/md5_one.c',
- 'openssl/crypto/mdc2/mdc2dgst.c',
'openssl/crypto/mdc2/mdc2_one.c',
+ 'openssl/crypto/mdc2/mdc2dgst.c',
'openssl/crypto/mem.c',
'openssl/crypto/mem_dbg.c',
'openssl/crypto/modes/cbc128.c',
+ 'openssl/crypto/modes/ccm128.c',
'openssl/crypto/modes/cfb128.c',
'openssl/crypto/modes/ctr128.c',
'openssl/crypto/modes/cts128.c',
+ 'openssl/crypto/modes/gcm128.c',
'openssl/crypto/modes/ofb128.c',
+ 'openssl/crypto/modes/xts128.c',
'openssl/crypto/o_dir.c',
+ 'openssl/crypto/o_fips.c',
+ 'openssl/crypto/o_init.c',
'openssl/crypto/o_str.c',
'openssl/crypto/o_time.c',
'openssl/crypto/objects/o_names.c',
@@ -488,11 +521,13 @@
'openssl/crypto/rc2/rc2_skey.c',
'openssl/crypto/rc2/rc2cfb64.c',
'openssl/crypto/rc2/rc2ofb64.c',
+ 'openssl/crypto/rc4/rc4_utl.c',
'openssl/crypto/ripemd/rmd_dgst.c',
'openssl/crypto/ripemd/rmd_one.c',
'openssl/crypto/rsa/rsa_ameth.c',
'openssl/crypto/rsa/rsa_asn1.c',
'openssl/crypto/rsa/rsa_chk.c',
+ 'openssl/crypto/rsa/rsa_crpt.c',
'openssl/crypto/rsa/rsa_depr.c',
'openssl/crypto/rsa/rsa_eay.c',
'openssl/crypto/rsa/rsa_err.c',
@@ -509,12 +544,19 @@
'openssl/crypto/rsa/rsa_sign.c',
'openssl/crypto/rsa/rsa_ssl.c',
'openssl/crypto/rsa/rsa_x931.c',
+ 'openssl/crypto/seed/seed.c',
+ 'openssl/crypto/seed/seed_cbc.c',
+ 'openssl/crypto/seed/seed_cfb.c',
+ 'openssl/crypto/seed/seed_ecb.c',
+ 'openssl/crypto/seed/seed_ofb.c',
'openssl/crypto/sha/sha1_one.c',
'openssl/crypto/sha/sha1dgst.c',
'openssl/crypto/sha/sha256.c',
'openssl/crypto/sha/sha512.c',
'openssl/crypto/sha/sha_dgst.c',
'openssl/crypto/sha/sha_one.c',
+ 'openssl/crypto/srp/srp_lib.c',
+ 'openssl/crypto/srp/srp_vfy.c',
'openssl/crypto/stack/stack.c',
'openssl/crypto/store/str_err.c',
'openssl/crypto/store/str_lib.c',
@@ -610,25 +652,32 @@
'openssl/engines/e_sureware.c',
'openssl/engines/e_ubsec.c'
],
+ 'sources/': [
+ ['exclude', 'md2/.*$'],
+ ['exclude', 'store/.*$']
+ ],
'conditions': [
['target_arch!="ia32" and target_arch!="x64"', {
# Disable asm
'defines': [
'OPENSSL_NO_ASM'
- ],
+ ],
'sources': [
'openssl/crypto/aes/aes_cbc.c',
'openssl/crypto/aes/aes_core.c',
'openssl/crypto/bf/bf_enc.c',
'openssl/crypto/bn/bn_asm.c',
'openssl/crypto/cast/c_enc.c',
+ 'openssl/crypto/camellia/camellia.c',
+ 'openssl/crypto/camellia/cmll_cbc.c',
+ 'openssl/crypto/camellia/cmll_misc.c',
'openssl/crypto/des/des_enc.c',
'openssl/crypto/des/fcrypt_b.c',
'openssl/crypto/mem_clr.c',
'openssl/crypto/rc4/rc4_enc.c',
'openssl/crypto/rc4/rc4_skey.c',
'openssl/crypto/whrlpool/wp_block.c'
- ]
+ ]
}, {
# Enable asm
'defines': [
@@ -649,6 +698,7 @@
['OS!="win" and OS!="mac" and target_arch=="ia32"', {
'sources': [
'asm/x86-elf-gas/aes/aes-586.s',
+ 'asm/x86-elf-gas/aes/aesni-x86.s',
'asm/x86-elf-gas/bf/bf-686.s',
'asm/x86-elf-gas/bn/x86-mont.s',
'asm/x86-elf-gas/bn/x86.s',
@@ -671,10 +721,14 @@
['OS!="win" and OS!="mac" and target_arch=="x64"', {
'sources': [
'asm/x64-elf-gas/aes/aes-x86_64.s',
+ 'asm/x64-elf-gas/aes/aesni-x86_64.s',
+ 'asm/x64-elf-gas/aes/aesni-sha1-x86_64.s',
+ 'asm/x64-elf-gas/bn/modexp512-x86_64.s',
'asm/x64-elf-gas/bn/x86_64-mont.s',
'asm/x64-elf-gas/camellia/cmll-x86_64.s',
'asm/x64-elf-gas/md5/md5-x86_64.s',
'asm/x64-elf-gas/rc4/rc4-x86_64.s',
+ 'asm/x64-elf-gas/rc4/rc4-md5-x86_64.s',
'asm/x64-elf-gas/sha/sha1-x86_64.s',
'asm/x64-elf-gas/sha/sha512-x86_64.s',
'asm/x64-elf-gas/whrlpool/wp-x86_64.s',
@@ -682,15 +736,17 @@
# Non-generated asm
'openssl/crypto/bn/asm/x86_64-gcc.c',
# No asm available
+ 'openssl/crypto/bf/bf_enc.c',
'openssl/crypto/cast/c_enc.c',
+ 'openssl/crypto/camellia/cmll_misc.c',
'openssl/crypto/des/des_enc.c',
- 'openssl/crypto/bf/bf_enc.c',
'openssl/crypto/des/fcrypt_b.c'
]
}],
['OS=="mac" and target_arch=="ia32"', {
'sources': [
'asm/x86-macosx-gas/aes/aes-586.s',
+ 'asm/x86-macosx-gas/aes/aesni-x86.s',
'asm/x86-macosx-gas/bf/bf-686.s',
'asm/x86-macosx-gas/bn/x86-mont.s',
'asm/x86-macosx-gas/bn/x86.s',
@@ -713,10 +769,14 @@
['OS=="mac" and target_arch=="x64"', {
'sources': [
'asm/x64-macosx-gas/aes/aes-x86_64.s',
+ 'asm/x64-macosx-gas/aes/aesni-x86_64.s',
+ 'asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s',
+ 'asm/x64-macosx-gas/bn/modexp512-x86_64.s',
'asm/x64-macosx-gas/bn/x86_64-mont.s',
'asm/x64-macosx-gas/camellia/cmll-x86_64.s',
'asm/x64-macosx-gas/md5/md5-x86_64.s',
'asm/x64-macosx-gas/rc4/rc4-x86_64.s',
+ 'asm/x64-macosx-gas/rc4/rc4-md5-x86_64.s',
'asm/x64-macosx-gas/sha/sha1-x86_64.s',
'asm/x64-macosx-gas/sha/sha512-x86_64.s',
'asm/x64-macosx-gas/whrlpool/wp-x86_64.s',
@@ -724,15 +784,17 @@
# Non-generated asm
'openssl/crypto/bn/asm/x86_64-gcc.c',
# No asm available
+ 'openssl/crypto/bf/bf_enc.c',
'openssl/crypto/cast/c_enc.c',
+ 'openssl/crypto/camellia/cmll_misc.c',
'openssl/crypto/des/des_enc.c',
- 'openssl/crypto/bf/bf_enc.c',
'openssl/crypto/des/fcrypt_b.c'
]
}],
['OS=="win" and target_arch=="ia32"', {
'sources': [
'asm/x86-win32-masm/aes/aes-586.asm',
+ 'asm/x86-win32-masm/aes/aesni-x86.asm',
'asm/x86-win32-masm/bf/bf-686.asm',
'asm/x86-win32-masm/bn/x86-mont.asm',
'asm/x86-win32-masm/bn/x86.asm',
@@ -773,10 +835,14 @@
['OS=="win" and target_arch=="x64"', {
'sources': [
'asm/x64-win32-masm/aes/aes-x86_64.asm',
+ 'asm/x64-win32-masm/aes/aesni-x86_64.asm',
+ 'asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm',
+ 'asm/x64-win32-masm/bn/modexp512-x86_64.asm',
'asm/x64-win32-masm/bn/x86_64-mont.asm',
'asm/x64-win32-masm/camellia/cmll-x86_64.asm',
'asm/x64-win32-masm/md5/md5-x86_64.asm',
'asm/x64-win32-masm/rc4/rc4-x86_64.asm',
+ 'asm/x64-win32-masm/rc4/rc4-md5-x86_64.asm',
'asm/x64-win32-masm/sha/sha1-x86_64.asm',
'asm/x64-win32-masm/sha/sha512-x86_64.asm',
'asm/x64-win32-masm/whrlpool/wp-x86_64.asm',
@@ -784,9 +850,10 @@
# Non-generated asm
'openssl/crypto/bn/asm/x86_64-win32-masm.asm',
# No asm available
+ 'openssl/crypto/bf/bf_enc.c',
'openssl/crypto/cast/c_enc.c',
+ 'openssl/crypto/camellia/cmll_misc.c',
'openssl/crypto/des/des_enc.c',
- 'openssl/crypto/bf/bf_enc.c',
'openssl/crypto/des/fcrypt_b.c'
],
'rules': [
@@ -813,7 +880,7 @@
['OS=="win"', {
'defines': [
'MK1MF_BUILD',
- 'WIN32_LEAN_AND_MEAN',
+ 'WIN32_LEAN_AND_MEAN'
]
}, {
'defines': [
@@ -824,40 +891,31 @@
'OPENSSLDIR="/etc/ssl"',
'TERMIOS',
],
+ 'cflags': ['-Wno-missing-field-initializers'],
+ }],
+ ['is_clang==1 or gcc_version>=43', {
+ 'cflags': ['-Wno-old-style-declaration'],
}],
['OS=="solaris"', {
'defines': ['__EXTENSIONS__'],
}],
- ['target_arch=="ia32"', {
- 'variables': {'openssl_config_path': 'config/piii'},
- }],
- ['target_arch=="x64"', {
- 'variables': {'openssl_config_path': 'config/k8'},
- }],
['target_arch=="arm"', {
- 'variables': {'openssl_config_path': 'config/android'},
+ 'sources': ['openssl/crypto/armcap.c'],
}],
],
- 'sources/': [
- ['exclude', 'camellia/.*$'],
- ['exclude', 'cms/.*$'],
- ['exclude', 'mdc2/.*$'],
- ],
'include_dirs': [
'.',
'openssl',
'openssl/crypto',
'openssl/crypto/asn1',
'openssl/crypto/evp',
+ 'openssl/crypto/md2',
+ 'openssl/crypto/modes',
'openssl/crypto/store',
'openssl/include',
- '<@(openssl_config_path)',
],
'direct_dependent_settings': {
- 'include_dirs': [
- 'openssl/include',
- '<@(openssl_config_path)',
- ],
+ 'include_dirs': ['openssl/include'],
},
},
],
diff --git a/deps/openssl/openssl/CHANGES b/deps/openssl/openssl/CHANGES
index 03e744a04..ca82ad295 100644
--- a/deps/openssl/openssl/CHANGES
+++ b/deps/openssl/openssl/CHANGES
@@ -2,6 +2,434 @@
OpenSSL CHANGES
_______________
+ Changes between 1.0.1d and 1.0.1e [11 Feb 2013]
+
+ *)
+
+ Changes between 1.0.1c and 1.0.1d [5 Feb 2013]
+
+ *) Make the decoding of SSLv3, TLS and DTLS CBC records constant time.
+
+ This addresses the flaw in CBC record processing discovered by
+ Nadhem Alfardan and Kenny Paterson. Details of this attack can be found
+ at: http://www.isg.rhul.ac.uk/tls/
+
+ Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
+ Security Group at Royal Holloway, University of London
+ (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and
+ Emilia Käsper for the initial patch.
+ (CVE-2013-0169)
+ [Emilia Käsper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson]
+
+ *) Fix flaw in AESNI handling of TLS 1.2 and 1.1 records for CBC mode
+ ciphersuites which can be exploited in a denial of service attack.
+ Thanks go to and to Adam Langley <agl@chromium.org> for discovering
+ and detecting this bug and to Wolfgang Ettlinger
+ <wolfgang.ettlinger@gmail.com> for independently discovering this issue.
+ (CVE-2012-2686)
+ [Adam Langley]
+
+ *) Return an error when checking OCSP signatures when key is NULL.
+ This fixes a DoS attack. (CVE-2013-0166)
+ [Steve Henson]
+
+ *) Make openssl verify return errors.
+ [Chris Palmer <palmer@google.com> and Ben Laurie]
+
+ *) Call OCSP Stapling callback after ciphersuite has been chosen, so
+ the right response is stapled. Also change SSL_get_certificate()
+ so it returns the certificate actually sent.
+ See http://rt.openssl.org/Ticket/Display.html?id=2836.
+ [Rob Stradling <rob.stradling@comodo.com>]
+
+ *) Fix possible deadlock when decoding public keys.
+ [Steve Henson]
+
+ *) Don't use TLS 1.0 record version number in initial client hello
+ if renegotiating.
+ [Steve Henson]
+
+ Changes between 1.0.1b and 1.0.1c [10 May 2012]
+
+ *) Sanity check record length before skipping explicit IV in TLS
+ 1.2, 1.1 and DTLS to fix DoS attack.
+
+ Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic
+ fuzzing as a service testing platform.
+ (CVE-2012-2333)
+ [Steve Henson]
+
+ *) Initialise tkeylen properly when encrypting CMS messages.
+ Thanks to Solar Designer of Openwall for reporting this issue.
+ [Steve Henson]
+
+ *) In FIPS mode don't try to use composite ciphers as they are not
+ approved.
+ [Steve Henson]
+
+ Changes between 1.0.1a and 1.0.1b [26 Apr 2012]
+
+ *) OpenSSL 1.0.0 sets SSL_OP_ALL to 0x80000FFFL and OpenSSL 1.0.1 and
+ 1.0.1a set SSL_OP_NO_TLSv1_1 to 0x00000400L which would unfortunately
+ mean any application compiled against OpenSSL 1.0.0 headers setting
+ SSL_OP_ALL would also set SSL_OP_NO_TLSv1_1, unintentionally disablng
+ TLS 1.1 also. Fix this by changing the value of SSL_OP_NO_TLSv1_1 to
+ 0x10000000L Any application which was previously compiled against
+ OpenSSL 1.0.1 or 1.0.1a headers and which cares about SSL_OP_NO_TLSv1_1
+ will need to be recompiled as a result. Letting be results in
+ inability to disable specifically TLS 1.1 and in client context,
+ in unlike event, limit maximum offered version to TLS 1.0 [see below].
+ [Steve Henson]
+
+ *) In order to ensure interoperabilty SSL_OP_NO_protocolX does not
+ disable just protocol X, but all protocols above X *if* there are
+ protocols *below* X still enabled. In more practical terms it means
+ that if application wants to disable TLS1.0 in favor of TLS1.1 and
+ above, it's not sufficient to pass SSL_OP_NO_TLSv1, one has to pass
+ SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. This applies to
+ client side.
+ [Andy Polyakov]
+
+ Changes between 1.0.1 and 1.0.1a [19 Apr 2012]
+
+ *) Check for potentially exploitable overflows in asn1_d2i_read_bio
+ BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer
+ in CRYPTO_realloc_clean.
+
+ Thanks to Tavis Ormandy, Google Security Team, for discovering this
+ issue and to Adam Langley <agl@chromium.org> for fixing it.
+ (CVE-2012-2110)
+ [Adam Langley (Google), Tavis Ormandy, Google Security Team]
+
+ *) Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections.
+ [Adam Langley]
+
+ *) Workarounds for some broken servers that "hang" if a client hello
+ record length exceeds 255 bytes.
+
+ 1. Do not use record version number > TLS 1.0 in initial client
+ hello: some (but not all) hanging servers will now work.
+ 2. If we set OPENSSL_MAX_TLS1_2_CIPHER_LENGTH this will truncate
+ the number of ciphers sent in the client hello. This should be
+ set to an even number, such as 50, for example by passing:
+ -DOPENSSL_MAX_TLS1_2_CIPHER_LENGTH=50 to config or Configure.
+ Most broken servers should now work.
+ 3. If all else fails setting OPENSSL_NO_TLS1_2_CLIENT will disable
+ TLS 1.2 client support entirely.
+ [Steve Henson]
+
+ *) Fix SEGV in Vector Permutation AES module observed in OpenSSH.
+ [Andy Polyakov]
+
+ Changes between 1.0.0h and 1.0.1 [14 Mar 2012]
+
+ *) Add compatibility with old MDC2 signatures which use an ASN1 OCTET
+ STRING form instead of a DigestInfo.
+ [Steve Henson]
+
+ *) The format used for MDC2 RSA signatures is inconsistent between EVP
+ and the RSA_sign/RSA_verify functions. This was made more apparent when
+ OpenSSL used RSA_sign/RSA_verify for some RSA signatures in particular
+ those which went through EVP_PKEY_METHOD in 1.0.0 and later. Detect
+ the correct format in RSA_verify so both forms transparently work.
+ [Steve Henson]
+
+ *) Some servers which support TLS 1.0 can choke if we initially indicate
+ support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA
+ encrypted premaster secret. As a workaround use the maximum pemitted
+ client version in client hello, this should keep such servers happy
+ and still work with previous versions of OpenSSL.
+ [Steve Henson]
+
+ *) Add support for TLS/DTLS heartbeats.
+ [Robin Seggelmann <seggelmann@fh-muenster.de>]
+
+ *) Add support for SCTP.
+ [Robin Seggelmann <seggelmann@fh-muenster.de>]
+
+ *) Improved PRNG seeding for VOS.
+ [Paul Green <Paul.Green@stratus.com>]
+
+ *) Extensive assembler packs updates, most notably:
+
+ - x86[_64]: AES-NI, PCLMULQDQ, RDRAND support;
+ - x86[_64]: SSSE3 support (SHA1, vector-permutation AES);
+ - x86_64: bit-sliced AES implementation;
+ - ARM: NEON support, contemporary platforms optimizations;
+ - s390x: z196 support;
+ - *: GHASH and GF(2^m) multiplication implementations;
+
+ [Andy Polyakov]
+
+ *) Make TLS-SRP code conformant with RFC 5054 API cleanup
+ (removal of unnecessary code)
+ [Peter Sylvester <peter.sylvester@edelweb.fr>]
+
+ *) Add TLS key material exporter from RFC 5705.
+ [Eric Rescorla]
+
+ *) Add DTLS-SRTP negotiation from RFC 5764.
+ [Eric Rescorla]
+
+ *) Add Next Protocol Negotiation,
+ http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-00. Can be
+ disabled with a no-npn flag to config or Configure. Code donated
+ by Google.
+ [Adam Langley <agl@google.com> and Ben Laurie]
+
+ *) Add optional 64-bit optimized implementations of elliptic curves NIST-P224,
+ NIST-P256, NIST-P521, with constant-time single point multiplication on
+ typical inputs. Compiler support for the nonstandard type __uint128_t is
+ required to use this (present in gcc 4.4 and later, for 64-bit builds).
+ Code made available under Apache License version 2.0.
+
+ Specify "enable-ec_nistp_64_gcc_128" on the Configure (or config) command
+ line to include this in your build of OpenSSL, and run "make depend" (or
+ "make update"). This enables the following EC_METHODs:
+
+ EC_GFp_nistp224_method()
+ EC_GFp_nistp256_method()
+ EC_GFp_nistp521_method()
+
+ EC_GROUP_new_by_curve_name() will automatically use these (while
+ EC_GROUP_new_curve_GFp() currently prefers the more flexible
+ implementations).
+ [Emilia Käsper, Adam Langley, Bodo Moeller (Google)]
+
+ *) Use type ossl_ssize_t instad of ssize_t which isn't available on
+ all platforms. Move ssize_t definition from e_os.h to the public
+ header file e_os2.h as it now appears in public header file cms.h
+ [Steve Henson]
+
+ *) New -sigopt option to the ca, req and x509 utilities. Additional
+ signature parameters can be passed using this option and in
+ particular PSS.
+ [Steve Henson]
+
+ *) Add RSA PSS signing function. This will generate and set the
+ appropriate AlgorithmIdentifiers for PSS based on those in the
+ corresponding EVP_MD_CTX structure. No application support yet.
+ [Steve Henson]
+
+ *) Support for companion algorithm specific ASN1 signing routines.
+ New function ASN1_item_sign_ctx() signs a pre-initialised
+ EVP_MD_CTX structure and sets AlgorithmIdentifiers based on
+ the appropriate parameters.
+ [Steve Henson]
+
+ *) Add new algorithm specific ASN1 verification initialisation function
+ to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1
+ handling will be the same no matter what EVP_PKEY_METHOD is used.
+ Add a PSS handler to support verification of PSS signatures: checked
+ against a number of sample certificates.
+ [Steve Henson]
+
+ *) Add signature printing for PSS. Add PSS OIDs.
+ [Steve Henson, Martin Kaiser <lists@kaiser.cx>]
+
+ *) Add algorithm specific signature printing. An individual ASN1 method
+ can now print out signatures instead of the standard hex dump.
+
+ More complex signatures (e.g. PSS) can print out more meaningful
+ information. Include DSA version that prints out the signature
+ parameters r, s.
+ [Steve Henson]
+
+ *) Password based recipient info support for CMS library: implementing
+ RFC3211.
+ [Steve Henson]
+
+ *) Split password based encryption into PBES2 and PBKDF2 functions. This
+ neatly separates the code into cipher and PBE sections and is required
+ for some algorithms that split PBES2 into separate pieces (such as
+ password based CMS).
+ [Steve Henson]
+
+ *) Session-handling fixes:
+ - Fix handling of connections that are resuming with a session ID,
+ but also support Session Tickets.
+ - Fix a bug that suppressed issuing of a new ticket if the client
+ presented a ticket with an expired session.
+ - Try to set the ticket lifetime hint to something reasonable.
+ - Make tickets shorter by excluding irrelevant information.
+ - On the client side, don't ignore renewed tickets.
+ [Adam Langley, Bodo Moeller (Google)]
+
+ *) Fix PSK session representation.
+ [Bodo Moeller]
+
+ *) Add RC4-MD5 and AESNI-SHA1 "stitched" implementations.
+
+ This work was sponsored by Intel.
+ [Andy Polyakov]
+
+ *) Add GCM support to TLS library. Some custom code is needed to split
+ the IV between the fixed (from PRF) and explicit (from TLS record)
+ portions. This adds all GCM ciphersuites supported by RFC5288 and
+ RFC5289. Generalise some AES* cipherstrings to inlclude GCM and
+ add a special AESGCM string for GCM only.
+ [Steve Henson]
+
+ *) Expand range of ctrls for AES GCM. Permit setting invocation
+ field on decrypt and retrieval of invocation field only on encrypt.
+ [Steve Henson]
+
+ *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support.
+ As required by RFC5289 these ciphersuites cannot be used if for
+ versions of TLS earlier than 1.2.
+ [Steve Henson]
+
+ *) For FIPS capable OpenSSL interpret a NULL default public key method
+ as unset and return the appopriate default but do *not* set the default.
+ This means we can return the appopriate method in applications that
+ swicth between FIPS and non-FIPS modes.
+ [Steve Henson]
+
+ *) Redirect HMAC and CMAC operations to FIPS module in FIPS mode. If an
+ ENGINE is used then we cannot handle that in the FIPS module so we
+ keep original code iff non-FIPS operations are allowed.
+ [Steve Henson]
+
+ *) Add -attime option to openssl utilities.
+ [Peter Eckersley <pde@eff.org>, Ben Laurie and Steve Henson]
+
+ *) Redirect DSA and DH operations to FIPS module in FIPS mode.
+ [Steve Henson]
+
+ *) Redirect ECDSA and ECDH operations to FIPS module in FIPS mode. Also use
+ FIPS EC methods unconditionally for now.
+ [Steve Henson]
+
+ *) New build option no-ec2m to disable characteristic 2 code.
+ [Steve Henson]
+
+ *) Backport libcrypto audit of return value checking from 1.1.0-dev; not
+ all cases can be covered as some introduce binary incompatibilities.
+ [Steve Henson]
+
+ *) Redirect RSA operations to FIPS module including keygen,
+ encrypt, decrypt, sign and verify. Block use of non FIPS RSA methods.
+ [Steve Henson]
+
+ *) Add similar low level API blocking to ciphers.
+ [Steve Henson]
+
+ *) Low level digest APIs are not approved in FIPS mode: any attempt
+ to use these will cause a fatal error. Applications that *really* want
+ to use them can use the private_* version instead.
+ [Steve Henson]
+
+ *) Redirect cipher operations to FIPS module for FIPS builds.
+ [Steve Henson]
+
+ *) Redirect digest operations to FIPS module for FIPS builds.
+ [Steve Henson]
+
+ *) Update build system to add "fips" flag which will link in fipscanister.o
+ for static and shared library builds embedding a signature if needed.
+ [Steve Henson]
+
+ *) Output TLS supported curves in preference order instead of numerical
+ order. This is currently hardcoded for the highest order curves first.
+ This should be configurable so applications can judge speed vs strength.
+ [Steve Henson]
+
+ *) Add TLS v1.2 server support for client authentication.
+ [Steve Henson]
+
+ *) Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers
+ and enable MD5.
+ [Steve Henson]
+
+ *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying
+ FIPS modules versions.
+ [Steve Henson]
+
+ *) Add TLS v1.2 client side support for client authentication. Keep cache
+ of handshake records longer as we don't know the hash algorithm to use
+ until after the certificate request message is received.
+ [Steve Henson]
+
+ *) Initial TLS v1.2 client support. Add a default signature algorithms
+ extension including all the algorithms we support. Parse new signature
+ format in client key exchange. Relax some ECC signing restrictions for
+ TLS v1.2 as indicated in RFC5246.
+ [Steve Henson]
+
+ *) Add server support for TLS v1.2 signature algorithms extension. Switch
+ to new signature format when needed using client digest preference.
+ All server ciphersuites should now work correctly in TLS v1.2. No client
+ support yet and no support for client certificates.
+ [Steve Henson]
+
+ *) Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch
+ to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based
+ ciphersuites. At present only RSA key exchange ciphersuites work with
+ TLS v1.2. Add new option for TLS v1.2 replacing the old and obsolete
+ SSL_OP_PKCS1_CHECK flags with SSL_OP_NO_TLSv1_2. New TLSv1.2 methods
+ and version checking.
+ [Steve Henson]
+
+ *) New option OPENSSL_NO_SSL_INTERN. If an application can be compiled
+ with this defined it will not be affected by any changes to ssl internal
+ structures. Add several utility functions to allow openssl application
+ to work with OPENSSL_NO_SSL_INTERN defined.
+ [Steve Henson]
+
+ *) Add SRP support.
+ [Tom Wu <tjw@cs.stanford.edu> and Ben Laurie]
+
+ *) Add functions to copy EVP_PKEY_METHOD and retrieve flags and id.
+ [Steve Henson]
+
+ *) Permit abbreviated handshakes when renegotiating using the function
+ SSL_renegotiate_abbreviated().
+ [Robin Seggelmann <seggelmann@fh-muenster.de>]
+
+ *) Add call to ENGINE_register_all_complete() to
+ ENGINE_load_builtin_engines(), so some implementations get used
+ automatically instead of needing explicit application support.
+ [Steve Henson]
+
+ *) Add support for TLS key exporter as described in RFC5705.
+ [Robin Seggelmann <seggelmann@fh-muenster.de>, Steve Henson]
+
+ *) Initial TLSv1.1 support. Since TLSv1.1 is very similar to TLS v1.0 only
+ a few changes are required:
+
+ Add SSL_OP_NO_TLSv1_1 flag.
+ Add TLSv1_1 methods.
+ Update version checking logic to handle version 1.1.
+ Add explicit IV handling (ported from DTLS code).
+ Add command line options to s_client/s_server.
+ [Steve Henson]
+
+ Changes between 1.0.0g and 1.0.0h [12 Mar 2012]
+
+ *) Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness
+ in CMS and PKCS7 code. When RSA decryption fails use a random key for
+ content decryption and always return the same error. Note: this attack
+ needs on average 2^20 messages so it only affects automated senders. The
+ old behaviour can be reenabled in the CMS code by setting the
+ CMS_DEBUG_DECRYPT flag: this is useful for debugging and testing where
+ an MMA defence is not necessary.
+ Thanks to Ivan Nestlerode <inestlerode@us.ibm.com> for discovering
+ this issue. (CVE-2012-0884)
+ [Steve Henson]
+
+ *) Fix CVE-2011-4619: make sure we really are receiving a
+ client hello before rejecting multiple SGC restarts. Thanks to
+ Ivan Nestlerode <inestlerode@us.ibm.com> for discovering this bug.
+ [Steve Henson]
+
+ Changes between 1.0.0f and 1.0.0g [18 Jan 2012]
+
+ *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109.
+ Thanks to Antonio Martin, Enterprise Secure Access Research and
+ Development, Cisco Systems, Inc. for discovering this bug and
+ preparing a fix. (CVE-2012-0050)
+ [Antonio Martin]
+
Changes between 1.0.0e and 1.0.0f [4 Jan 2012]
*) Nadhem Alfardan and Kenny Paterson have discovered an extension
@@ -22,7 +450,9 @@
(CVE-2011-4576)
[Adam Langley (Google)]
- *) Only allow one SGC handshake restart for SSL/TLS. (CVE-2011-4619)
+ *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George
+ Kadianakis <desnacked@gmail.com> for discovering this issue and
+ Adam Langley for preparing the fix. (CVE-2011-4619)
[Adam Langley (Google)]
*) Check parameters are not NULL in GOST ENGINE. (CVE-2012-0027)
@@ -963,8 +1393,47 @@
*) Change 'Configure' script to enable Camellia by default.
[NTT]
+
+ Changes between 0.9.8s and 0.9.8t [18 Jan 2012]
+
+ *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109.
+ Thanks to Antonio Martin, Enterprise Secure Access Research and
+ Development, Cisco Systems, Inc. for discovering this bug and
+ preparing a fix. (CVE-2012-0050)
+ [Antonio Martin]
- Changes between 0.9.8r and 0.9.8s [xx XXX xxxx]
+ Changes between 0.9.8r and 0.9.8s [4 Jan 2012]
+
+ *) Nadhem Alfardan and Kenny Paterson have discovered an extension
+ of the Vaudenay padding oracle attack on CBC mode encryption
+ which enables an efficient plaintext recovery attack against
+ the OpenSSL implementation of DTLS. Their attack exploits timing
+ differences arising during decryption processing. A research
+ paper describing this attack can be found at:
+ http://www.isg.rhul.ac.uk/~kp/dtls.pdf
+ Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
+ Security Group at Royal Holloway, University of London
+ (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann
+ <seggelmann@fh-muenster.de> and Michael Tuexen <tuexen@fh-muenster.de>
+ for preparing the fix. (CVE-2011-4108)
+ [Robin Seggelmann, Michael Tuexen]
+
+ *) Stop policy check failure freeing same buffer twice. (CVE-2011-4109)
+ [Ben Laurie, Kasper <ekasper@google.com>]
+
+ *) Clear bytes used for block padding of SSL 3.0 records.
+ (CVE-2011-4576)
+ [Adam Langley (Google)]
+
+ *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George
+ Kadianakis <desnacked@gmail.com> for discovering this issue and
+ Adam Langley for preparing the fix. (CVE-2011-4619)
+ [Adam Langley (Google)]
+
+ *) Prevent malformed RFC3779 data triggering an assertion failure.
+ Thanks to Andrew Chi, BBN Technologies, for discovering the flaw
+ and Rob Austein <sra@hactrn.net> for fixing it. (CVE-2011-4577)
+ [Rob Austein <sra@hactrn.net>]
*) Fix ssl_ciph.c set-up race.
[Adam Langley (Google)]
diff --git a/deps/openssl/openssl/Configure b/deps/openssl/openssl/Configure
index 7941c93f6..9c803dc06 100755
--- a/deps/openssl/openssl/Configure
+++ b/deps/openssl/openssl/Configure
@@ -10,7 +10,7 @@ use strict;
# see INSTALL for instructions.
-my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
+my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
# Options:
#
@@ -56,6 +56,7 @@ my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimenta
# [no-]zlib [don't] compile support for zlib compression.
# zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
# library and will be loaded in run-time by the OpenSSL library.
+# sctp include SCTP support
# 386 generate 80386 code
# no-sse2 disables IA-32 SSE2 code, above option implies no-sse2
# no-<cipher> build without specified algorithm (rsa, idea, rc5, ...)
@@ -123,21 +124,24 @@ my $tlib="-lnsl -lsocket";
my $bits1="THIRTY_TWO_BIT ";
my $bits2="SIXTY_FOUR_BIT ";
-my $x86_asm="x86cpuid.o:bn-586.o co-586.o x86-mont.o:des-586.o crypt586.o:aes-586.o:bf-586.o:md5-586.o:sha1-586.o sha256-586.o sha512-586.o:cast-586.o:rc4-586.o:rmd-586.o:rc5-586.o:wp_block.o wp-mmx.o:cmll-x86.o";
+my $x86_asm="x86cpuid.o:bn-586.o co-586.o x86-mont.o x86-gf2m.o:des-586.o crypt586.o:aes-586.o vpaes-x86.o aesni-x86.o:bf-586.o:md5-586.o:sha1-586.o sha256-586.o sha512-586.o:cast-586.o:rc4-586.o:rmd-586.o:rc5-586.o:wp_block.o wp-mmx.o:cmll-x86.o:ghash-x86.o:";
my $x86_elf_asm="$x86_asm:elf";
-my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o::aes-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o";
-my $ia64_asm="ia64cpuid.o:bn-ia64.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::void";
-my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::void";
-my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::::void";
-my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o::::::::::::void";
-my $mips3_asm=":bn-mips3.o::::::::::::void";
-my $s390x_asm="s390xcap.o s390xcpuid.o:bn-s390x.o s390x-mont.o::aes-s390x.o:::sha1-s390x.o sha256-s390x.o sha512-s390x.o::rc4-s390x.o:::::void";
-my $armv4_asm=":bn_asm.o armv4-mont.o::aes_cbc.o aes-armv4.o:::sha1-armv4-large.o sha256-armv4.o sha512-armv4.o:::::::void";
-my $ppc32_asm="ppccpuid.o:bn-ppc.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o::::::";
-my $ppc64_asm="ppccpuid.o:bn-ppc.o ppc-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o sha512-ppc.o::::::";
-my $no_asm=":::::::::::::void";
+my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o modexp512-x86_64.o::aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o rc4-md5-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:ghash-x86_64.o:";
+my $ia64_asm="ia64cpuid.o:bn-ia64.o ia64-mont.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::ghash-ia64.o::void";
+my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void";
+my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::::::void";
+my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o:::::sha1-alpha.o:::::::ghash-alpha.o::void";
+my $mips32_asm=":bn-mips.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o::::::::";
+my $mips64_asm=":bn-mips.o mips-mont.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o sha512-mips.o::::::::";
+my $s390x_asm="s390xcap.o s390xcpuid.o:bn-s390x.o s390x-mont.o s390x-gf2m.o::aes-s390x.o aes-ctr.o aes-xts.o:::sha1-s390x.o sha256-s390x.o sha512-s390x.o::rc4-s390x.o:::::ghash-s390x.o:";
+my $armv4_asm="armcap.o armv4cpuid.o:bn_asm.o armv4-mont.o armv4-gf2m.o::aes_cbc.o aes-armv4.o:::sha1-armv4-large.o sha256-armv4.o sha512-armv4.o:::::::ghash-armv4.o::void";
+my $parisc11_asm="pariscid.o:bn_asm.o parisc-mont.o::aes_core.o aes_cbc.o aes-parisc.o:::sha1-parisc.o sha256-parisc.o sha512-parisc.o::rc4-parisc.o:::::ghash-parisc.o::32";
+my $parisc20_asm="pariscid.o:pa-risc2W.o parisc-mont.o::aes_core.o aes_cbc.o aes-parisc.o:::sha1-parisc.o sha256-parisc.o sha512-parisc.o::rc4-parisc.o:::::ghash-parisc.o::64";
+my $ppc32_asm="ppccpuid.o ppccap.o:bn-ppc.o ppc-mont.o ppc64-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o::::::::";
+my $ppc64_asm="ppccpuid.o ppccap.o:bn-ppc.o ppc-mont.o ppc64-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o sha512-ppc.o::::::::";
+my $no_asm=":::::::::::::::void";
# As for $BSDthreads. Idea is to maintain "collective" set of flags,
# which would cover all BSD flavors. -pthread applies to them all,
@@ -148,7 +152,7 @@ my $no_asm=":::::::::::::void";
# seems to be sufficient?
my $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
-#config-string $cc : $cflags : $unistd : $thread_cflag : $sys_id : $lflags : $bn_ops : $cpuid_obj : $bn_obj : $des_obj : $aes_obj : $bf_obj : $md5_obj : $sha1_obj : $cast_obj : $rc4_obj : $rmd160_obj : $rc5_obj : $wp_obj : $cmll_obj : $dso_scheme : $shared_target : $shared_cflag : $shared_ldflag : $shared_extension : $ranlib : $arflags : $multilib
+#config-string $cc : $cflags : $unistd : $thread_cflag : $sys_id : $lflags : $bn_ops : $cpuid_obj : $bn_obj : $des_obj : $aes_obj : $bf_obj : $md5_obj : $sha1_obj : $cast_obj : $rc4_obj : $rmd160_obj : $rc5_obj : $wp_obj : $cmll_obj : $modes_obj : $engines_obj : $dso_scheme : $shared_target : $shared_cflag : $shared_ldflag : $shared_extension : $ranlib : $arflags : $multilib
my %table=(
# File 'TABLE' (created by 'make TABLE') contains the data from this list,
@@ -163,32 +167,36 @@ my %table=(
# Our development configs
"purify", "purify gcc:-g -DPURIFY -Wall::(unknown)::-lsocket -lnsl::::",
"debug", "gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -ggdb -g2 -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror::(unknown)::-lefence::::",
-"debug-ben", "gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DDEBUG_UNUSED -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown):::::bn86-elf.o co86-elf.o",
+"debug-ben", "gcc:$gcc_devteam_warn -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DDEBUG_SAFESTACK -O2 -pipe::(unknown):::::",
"debug-ben-openbsd","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
"debug-ben-openbsd-debug","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -g3 -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
"debug-ben-debug", "gcc44:$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O2 -pipe::(unknown)::::::",
+"debug-ben-debug-64", "gcc:$gcc_devteam_warn -Wno-error=overlength-strings -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-ben-macos", "cc:$gcc_devteam_warn -arch i386 -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -O3 -DL_ENDIAN -g3 -pipe::(unknown)::-Wl,-search_paths_first::::",
+"debug-ben-macos-gcc46", "gcc-mp-4.6:$gcc_devteam_warn -Wconversion -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -O3 -DL_ENDIAN -g3 -pipe::(unknown)::::::",
+"debug-ben-darwin64","cc:$gcc_devteam_warn -Wno-language-extension-token -Wno-extended-offsetof -arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-ben-no-opt", "gcc: -Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG -Werror -DL_ENDIAN -DTERMIOS -Wall -g3::(unknown)::::::",
"debug-ben-strict", "gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe::(unknown)::::::",
"debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
-"debug-bodo", "gcc:-DL_ENDIAN -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBIO_PAIR_DEBUG -DPEDANTIC -g -march=i486 -pedantic -Wshadow -Wall -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion::-D_REENTRANT:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
+"debug-bodo", "gcc:$gcc_devteam_warn -DBN_DEBUG -DBN_DEBUG_RAND -DCONF_DEBUG -DBIO_PAIR_DEBUG -m64 -DL_ENDIAN -DTERMIO -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
"debug-ulf", "gcc:-DTERMIOS -DL_ENDIAN -march=i486 -Wall -DBN_DEBUG -DBN_DEBUG_RAND -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -g -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations:::CYGWIN32:::${no_asm}:win32:cygwin-shared:::.dll",
-"debug-steve64", "gcc:$gcc_devteam_warn -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-steve64", "gcc:$gcc_devteam_warn -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -Wno-overlength-strings -g::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-steve32", "gcc:$gcc_devteam_warn -m32 -DL_ENDIAN -DCONF_DEBUG -DDEBUG_SAFESTACK -g -pipe::-D_REENTRANT::-rdynamic -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"debug-steve-opt", "gcc:$gcc_devteam_warn -m64 -O3 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"debug-levitte-linux-elf","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"debug-levitte-linux-noasm","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"debug-levitte-linux-elf-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"debug-levitte-linux-noasm-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"debug-geoff32","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -DMD32_REG_T=int -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:BN_LLONG:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"debug-geoff64","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -DMD32_REG_T=int -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-steve-opt", "gcc:$gcc_devteam_warn -m64 -O3 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-levitte-linux-elf","gcc:-DLEVITTE_DEBUG -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -ggdb -g3 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-levitte-linux-noasm","gcc:-DLEVITTE_DEBUG -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -ggdb -g3 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-levitte-linux-elf-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DTERMIO -DPEDANTIC -ggdb -g3 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-levitte-linux-noasm-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -ggdb -g3 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-geoff32","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:BN_LLONG:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-geoff64","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-linux-pentium","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -mcpu=pentium -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn",
"debug-linux-ppro","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -mcpu=pentiumpro -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn",
"debug-linux-elf","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -march=i486 -Wall::-D_REENTRANT::-lefence -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-linux-elf-noefence","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -march=i486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"debug-linux-ia32-aes", "gcc:-DAES_EXPERIMENTAL -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:x86cpuid.o:bn-586.o co-586.o x86-mont.o:des-586.o crypt586.o:aes_x86core.o aes_cbc.o:bf-586.o:md5-586.o:sha1-586.o sha256-586.o sha512-586.o:cast-586.o:rc4-586.o:rmd-586.o:rc5-586.o:wp_block.o wp-mmx.o::elf:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-linux-ia32-aes", "gcc:-DAES_EXPERIMENTAL -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:x86cpuid.o:bn-586.o co-586.o x86-mont.o:des-586.o crypt586.o:aes_x86core.o aes_cbc.o aesni-x86.o:bf-586.o:md5-586.o:sha1-586.o sha256-586.o sha512-586.o:cast-586.o:rc4-586.o:rmd-586.o:rc5-586.o:wp_block.o wp-mmx.o::ghash-x86.o::elf:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-linux-generic32","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DTERMIO -g -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-linux-generic64","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DTERMIO -g -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"debug-linux-x86_64", "gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -m64 -DL_ENDIAN -DTERMIO -g -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+"debug-linux-x86_64","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -m64 -DL_ENDIAN -DTERMIO -g -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
"dist", "cc:-O::(unknown)::::::",
# Basic configs that should work on any (32 and less bit) box
@@ -214,7 +222,7 @@ my %table=(
# actually recommend to consider using gcc shared build even with vendor
# compiler:-)
# <appro@fy.chalmers.se>
-"solaris64-x86_64-gcc","gcc:-m64 -O3 -Wall -DL_ENDIAN -DMD32_REG_T=int::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-fPIC:-m64 -shared -static-libgcc:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
+"solaris64-x86_64-gcc","gcc:-m64 -O3 -Wall -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-fPIC:-m64 -shared -static-libgcc:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
#### Solaris x86 with Sun C setups
"solaris-x86-cc","cc:-fast -O -Xa::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
@@ -237,7 +245,7 @@ my %table=(
"solaris-sparcv7-cc","cc:-xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris-sparcv8-cc","cc:-xarch=v8 -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris-sparcv9-cc","cc:-xtarget=ultra -xarch=v8plus -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"solaris64-sparcv9-cc","cc:-xtarget=ultra -xarch=v9 -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-xarch=v9 -G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/ccs/bin/ar rs::/64",
+"solaris64-sparcv9-cc","cc:-xtarget=ultra -xarch=v9 -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-xarch=v9 -G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
####
"debug-solaris-sparcv8-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -xarch=v8 -g -O -xstrconst -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-solaris-sparcv9-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -xtarget=ultra -xarch=v8plus -g -O -xstrconst -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
@@ -248,16 +256,16 @@ my %table=(
#### IRIX 5.x configs
# -mips2 flag is added by ./config when appropriate.
-"irix-gcc","gcc:-O3 -DTERMIOS -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK DES_UNROLL DES_RISC2 DES_PTR BF_PTR:${no_asm}:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"irix-cc", "cc:-O2 -use_readonly_const -DTERMIOS -DB_ENDIAN::(unknown):::BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC2 DES_UNROLL BF_PTR:${no_asm}:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"irix-gcc","gcc:-O3 -DTERMIOS -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK DES_UNROLL DES_RISC2 DES_PTR BF_PTR:${mips32_asm}:o32:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"irix-cc", "cc:-O2 -use_readonly_const -DTERMIOS -DB_ENDIAN::(unknown):::BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC2 DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### IRIX 6.x configs
# Only N32 and N64 ABIs are supported. If you need O32 ABI build, invoke
# './Configure irix-cc -o32' manually.
-"irix-mips3-gcc","gcc:-mabi=n32 -O3 -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK_LL DES_UNROLL DES_RISC2 DES_PTR BF_PTR SIXTY_FOUR_BIT:${mips3_asm}:dlfcn:irix-shared::-mabi=n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32",
-"irix-mips3-cc", "cc:-n32 -mips3 -O2 -use_readonly_const -G0 -rdata_shared -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::DES_PTR RC4_CHAR RC4_CHUNK_LL DES_RISC2 DES_UNROLL BF_PTR SIXTY_FOUR_BIT:${mips3_asm}:dlfcn:irix-shared::-n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32",
+"irix-mips3-gcc","gcc:-mabi=n32 -O3 -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK_LL DES_UNROLL DES_RISC2 DES_PTR BF_PTR SIXTY_FOUR_BIT:${mips64_asm}:n32:dlfcn:irix-shared::-mabi=n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32",
+"irix-mips3-cc", "cc:-n32 -mips3 -O2 -use_readonly_const -G0 -rdata_shared -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::DES_PTR RC4_CHAR RC4_CHUNK_LL DES_RISC2 DES_UNROLL BF_PTR SIXTY_FOUR_BIT:${mips64_asm}:n32:dlfcn:irix-shared::-n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32",
# N64 ABI builds.
-"irix64-mips4-gcc","gcc:-mabi=64 -mips4 -O3 -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::RC4_CHAR RC4_CHUNK DES_RISC2 DES_UNROLL SIXTY_FOUR_BIT_LONG:${mips3_asm}:dlfcn:irix-shared::-mabi=64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
-"irix64-mips4-cc", "cc:-64 -mips4 -O2 -use_readonly_const -G0 -rdata_shared -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::RC4_CHAR RC4_CHUNK DES_RISC2 DES_UNROLL SIXTY_FOUR_BIT_LONG:${mips3_asm}:dlfcn:irix-shared::-64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+"irix64-mips4-gcc","gcc:-mabi=64 -mips4 -O3 -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::RC4_CHAR RC4_CHUNK DES_RISC2 DES_UNROLL SIXTY_FOUR_BIT_LONG:${mips64_asm}:64:dlfcn:irix-shared::-mabi=64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+"irix64-mips4-cc", "cc:-64 -mips4 -O2 -use_readonly_const -G0 -rdata_shared -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::RC4_CHAR RC4_CHUNK DES_RISC2 DES_UNROLL SIXTY_FOUR_BIT_LONG:${mips64_asm}:64:dlfcn:irix-shared::-64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
#### Unified HP-UX ANSI C configs.
# Special notes:
@@ -290,17 +298,18 @@ my %table=(
# Since there is mention of this in shlib/hpux10-cc.sh
"hpux-parisc-cc-o4","cc:-Ae +O4 +ESlit -z -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY::-D_REENTRANT::-ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"hpux-parisc-gcc","gcc:-O3 -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-Wl,+s -ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"hpux-parisc2-gcc","gcc:-march=2.0 -O3 -DB_ENDIAN -D_REENTRANT::::-Wl,+s -ldld:SIXTY_FOUR_BIT RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL DES_RISC1::pa-risc2.o::::::::::::void:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"hpux64-parisc2-gcc","gcc:-O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT::pa-risc2W.o::::::::::::void:dlfcn:hpux-shared:-fpic:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_64",
+"hpux-parisc1_1-gcc","gcc:-O3 -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-Wl,+s -ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${parisc11_asm}:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa1.1",
+"hpux-parisc2-gcc","gcc:-march=2.0 -O3 -DB_ENDIAN -D_REENTRANT::::-Wl,+s -ldld:SIXTY_FOUR_BIT RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL DES_RISC1:".eval{my $asm=$parisc20_asm;$asm=~s/2W\./2\./;$asm=~s/:64/:32/;$asm}.":dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_32",
+"hpux64-parisc2-gcc","gcc:-O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT::pa-risc2W.o::::::::::::::void:dlfcn:hpux-shared:-fpic:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_64",
# More attempts at unified 10.X and 11.X targets for HP C compiler.
#
# Chris Ruemmler <ruemmler@cup.hp.com>
# Kevin Steves <ks@hp.se>
"hpux-parisc-cc","cc:+O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY::-D_REENTRANT::-Wl,+s -ldld:MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"hpux-parisc1_0-cc","cc:+DAportable +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY::-D_REENTRANT::-Wl,+s -ldld:MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"hpux-parisc2-cc","cc:+DA2.0 +DS2.0 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY -D_REENTRANT::::-Wl,+s -ldld:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT::pa-risc2.o::::::::::::void:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"hpux64-parisc2-cc","cc:+DD64 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT::pa-risc2W.o::::::::::::void:dlfcn:hpux-shared:+Z:+DD64 -b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_64",
+"hpux-parisc1_1-cc","cc:+DA1.1 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY::-D_REENTRANT::-Wl,+s -ldld:MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${parisc11_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa1.1",
+"hpux-parisc2-cc","cc:+DA2.0 +DS2.0 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY -D_REENTRANT::::-Wl,+s -ldld:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:".eval{my $asm=$parisc20_asm;$asm=~s/2W\./2\./;$asm=~s/:64/:32/;$asm}.":dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_32",
+"hpux64-parisc2-cc","cc:+DD64 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${parisc20_asm}:dlfcn:hpux-shared:+Z:+DD64 -b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_64",
# HP/UX IA-64 targets
"hpux-ia64-cc","cc:-Ae +DD32 +O2 +Olit=all -z -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:+Z:+DD32 -b:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux32",
@@ -351,8 +360,22 @@ my %table=(
"linux-ia64", "gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-ia64-ecc","ecc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-ia64-icc","icc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"linux-x86_64", "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
-"linux-s390x", "gcc:-m64 -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${s390x_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+"linux-x86_64", "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+"linux64-s390x", "gcc:-m64 -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${s390x_asm}:64:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+#### So called "highgprs" target for z/Architecture CPUs
+# "Highgprs" is kernel feature first implemented in Linux 2.6.32, see
+# /proc/cpuinfo. The idea is to preserve most significant bits of
+# general purpose registers not only upon 32-bit process context
+# switch, but even on asynchronous signal delivery to such process.
+# This makes it possible to deploy 64-bit instructions even in legacy
+# application context and achieve better [or should we say adequate]
+# performance. The build is binary compatible with linux-generic32,
+# and the idea is to be able to install the resulting libcrypto.so
+# alongside generic one, e.g. as /lib/highgprs/libcrypto.so.x.y, for
+# ldconfig and run-time linker to autodiscover. Unfortunately it
+# doesn't work just yet, because of couple of bugs in glibc
+# sysdeps/s390/dl-procinfo.c affecting ldconfig and ld.so.1...
+"linux32-s390x", "gcc:-m31 -Wa,-mzarch -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$s390x_asm;$asm=~s/bn\-s390x\.o/bn_asm.o/;$asm}.":31:dlfcn:linux-shared:-fPIC:-m31:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/highgprs",
#### SPARC Linux setups
# Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
# assisted with debugging of following two configs.
@@ -380,6 +403,11 @@ my %table=(
"linux-alpha-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${alpha_asm}",
"linux-alpha+bwx-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${alpha_asm}",
+# Android: linux-* but without -DTERMIO and pointers to headers and libs.
+"android","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"android-x86","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:".eval{my $asm=${x86_elf_asm};$asm=~s/:elf/:android/;$asm}.":dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+
#### *BSD [do see comment about ${BSDthreads} above!]
"BSD-generic32","gcc:-DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"BSD-x86", "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
@@ -393,7 +421,7 @@ my %table=(
# triggered by RIPEMD160 code.
"BSD-sparc64", "gcc:-DB_ENDIAN -DTERMIOS -O3 -DMD32_REG_T=int -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC2 BF_PTR:${sparcv9_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"BSD-ia64", "gcc:-DL_ENDIAN -DTERMIOS -O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"BSD-x86_64", "gcc:-DL_ENDIAN -DTERMIOS -O3 -DMD32_REG_T=int -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"BSD-x86_64", "gcc:-DL_ENDIAN -DTERMIOS -O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"bsdi-elf-gcc", "gcc:-DPERL5 -DL_ENDIAN -fomit-frame-pointer -O3 -march=i486 -Wall::(unknown)::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
@@ -438,8 +466,8 @@ my %table=(
"aix64-gcc","gcc:-maix64 -O -DB_ENDIAN::-pthread:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-maix64 -shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X64",
# Below targets assume AIX 5. Idea is to effectively disregard $OBJECT_MODE
# at build time. $OBJECT_MODE is respected at ./config stage!
-"aix-cc", "cc:-q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-q32 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 32",
-"aix64-cc", "cc:-q64 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-q64 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 64",
+"aix-cc", "cc:-q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-q32 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 32",
+"aix64-cc", "cc:-q64 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-q64 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 64",
#
# Cray T90 and similar (SDSC)
@@ -490,13 +518,13 @@ my %table=(
# Visual C targets
#
# Win64 targets, WIN64I denotes IA-64 and WIN64A - AMD64
-"VC-WIN64I","cl:-W3 -Gs0 -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64I::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:ia64cpuid.o:ia64.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o:::::::ias:win32",
-"VC-WIN64A","cl:-W3 -Gs0 -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64A::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:x86_64cpuid.o:bn_asm.o x86_64-mont.o::aes-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:auto:win32",
-"debug-VC-WIN64I","cl:-W3 -Gs0 -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64I::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:ia64cpuid.o:ia64.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o:::::::ias:win32",
-"debug-VC-WIN64A","cl:-W3 -Gs0 -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64A::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:x86_64cpuid.o:bn_asm.o x86_64-mont.o::aes-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:auto:win32",
+"VC-WIN64I","cl:-W3 -Gs0 -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64I::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:ia64cpuid.o:ia64.o ia64-mont.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o:::::::ghash-ia64.o::ias:win32",
+"VC-WIN64A","cl:-W3 -Gs0 -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64A::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:".eval{my $asm=$x86_64_asm;$asm=~s/x86_64-gcc\.o/bn_asm.o/;$asm}.":auto:win32",
+"debug-VC-WIN64I","cl:-W3 -Gs0 -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64I::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:ia64cpuid.o:ia64.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o:::::::ghash-ia64.o::ias:win32",
+"debug-VC-WIN64A","cl:-W3 -Gs0 -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64A::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:".eval{my $asm=$x86_64_asm;$asm=~s/x86_64-gcc\.o/bn_asm.o/;$asm}.":auto:win32",
# x86 Win32 target defaults to ANSI API, if you want UNICODE, complement
# 'perl Configure VC-WIN32' with '-DUNICODE -D_UNICODE'
-"VC-WIN32","cl:-W3 -WX -Gs0 -GF -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE:::WIN32::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${x86_asm}:win32n:win32",
+"VC-WIN32","cl:-W3 -Gs0 -GF -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE:::WIN32::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${x86_asm}:win32n:win32",
# Unified CE target
"debug-VC-WIN32","cl:-W3 -WX -Gs0 -GF -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE:::WIN32::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${x86_asm}:win32n:win32",
"VC-CE","cl::::WINCE::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${no_asm}:win32",
@@ -551,10 +579,12 @@ my %table=(
"rhapsody-ppc-cc","cc:-O3 -DB_ENDIAN::(unknown):MACOSX_RHAPSODY::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}::",
"darwin-ppc-cc","cc:-arch ppc -O3 -DB_ENDIAN -Wa,-force_cpusubtype_ALL::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"darwin64-ppc-cc","cc:-arch ppc64 -O3 -DB_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc64_asm}:osx64:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
-"darwin-i386-cc","cc:-arch i386 -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"darwin-i386-cc","cc:-arch i386 -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:".eval{my $asm=$x86_asm;$asm=~s/cast\-586\.o//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-darwin-i386-cc","cc:-arch i386 -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
-"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -DMD32_REG_T=int -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+# iPhoneOS/iOS
+"iphoneos-cross","llvm-gcc:-O3 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fomit-frame-pointer -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
##### A/UX
"aux3-gcc","gcc:-O2 -DTERMIO::(unknown):AUX:-lbsd:RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:::",
@@ -569,18 +599,21 @@ my %table=(
"OS2-EMX", "gcc::::::::",
##### VxWorks for various targets
+"vxworks-ppc60x","ccppc:-D_REENTRANT -mrtp -mhard-float -mstrict-align -fno-implicit-fp -DPPC32_fp60x -O2 -fstrength-reduce -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip:::VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/common:::::",
+"vxworks-ppcgen","ccppc:-D_REENTRANT -mrtp -msoft-float -mstrict-align -O1 -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip:::VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/sfcommon:::::",
"vxworks-ppc405","ccppc:-g -msoft-float -mlongcall -DCPU=PPC405 -I\$(WIND_BASE)/target/h:::VXWORKS:-r:::::",
"vxworks-ppc750","ccppc:-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h \$(DEBUG_FLAG):::VXWORKS:-r:::::",
"vxworks-ppc750-debug","ccppc:-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DDEBUG -g:::VXWORKS:-r:::::",
"vxworks-ppc860","ccppc:-nostdinc -msoft-float -DCPU=PPC860 -DNO_STRINGS_H -I\$(WIND_BASE)/target/h:::VXWORKS:-r:::::",
-"vxworks-mipsle","ccmips:-B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -DL_ENDIAN -EL -Wl,-EL -mips2 -mno-branch-likely -G 0 -fno-builtin -msoft-float -DCPU=MIPS32 -DMIPSEL -DNO_STRINGS_H -I\$(WIND_BASE)/target/h:::VXWORKS:-r::${no_asm}::::::ranlibmips:",
+"vxworks-simlinux","ccpentium:-B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DL_ENDIAN -DCPU=SIMLINUX -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/h -I\$(WIND_BASE)/target/h/wrn/coreip -DOPENSSL_NO_HW_PADLOCK:::VXWORKS:-r::${no_asm}::::::ranlibpentium:",
+"vxworks-mips","ccmips:-mrtp -mips2 -O -G 0 -B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DCPU=MIPS32 -msoft-float -mno-branch-likely -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/h/wrn/coreip::-D_REENTRANT:VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/mips/MIPSI32/sfcommon::${mips32_asm}:o32::::::ranlibmips:",
##### Compaq Non-Stop Kernel (Tandem)
"tandem-c89","c89:-Ww -D__TANDEM -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1 -D_TANDEM_SOURCE -DB_ENDIAN::(unknown):::THIRTY_TWO_BIT:::",
# uClinux
-"uClinux-dist","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):BN_LLONG:::::::::::::::$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
-"uClinux-dist64","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):SIXTY_FOUR_BIT_LONG:::::::::::::::$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
+"uClinux-dist","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):BN_LLONG:${no_asm}:$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
+"uClinux-dist64","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):SIXTY_FOUR_BIT_LONG:${no_asm}:$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
);
@@ -612,6 +645,8 @@ my $idx_rmd160_obj = $idx++;
my $idx_rc5_obj = $idx++;
my $idx_wp_obj = $idx++;
my $idx_cmll_obj = $idx++;
+my $idx_modes_obj = $idx++;
+my $idx_engines_obj = $idx++;
my $idx_perlasm_scheme = $idx++;
my $idx_dso_scheme = $idx++;
my $idx_shared_target = $idx++;
@@ -628,6 +663,9 @@ my $openssldir="";
my $exe_ext="";
my $install_prefix= "$ENV{'INSTALL_PREFIX'}";
my $cross_compile_prefix="";
+my $fipsdir="/usr/local/ssl/fips-2.0";
+my $fipslibdir="";
+my $baseaddr="0xFB00000";
my $no_threads=0;
my $threads=0;
my $no_shared=0; # but "no-shared" is default
@@ -662,26 +700,34 @@ my $cmll_enc="camellia.o cmll_misc.o cmll_cbc.o";
my $processor="";
my $default_ranlib;
my $perl;
+my $fips=0;
+if (exists $ENV{FIPSDIR})
+ {
+ $fipsdir = $ENV{FIPSDIR};
+ $fipsdir =~ s/\/$//;
+ }
# All of the following is disabled by default (RC5 was enabled before 0.9.8):
my %disabled = ( # "what" => "comment" [or special keyword "experimental"]
+ "ec_nistp_64_gcc_128" => "default",
"gmp" => "default",
- "jpake" => "experimental",
- "md2" => "default",
- "rc5" => "default",
+ "jpake" => "experimental",
+ "md2" => "default",
+ "rc5" => "default",
"rfc3779" => "default",
- "shared" => "default",
+ "sctp" => "default",
+ "shared" => "default",
"store" => "experimental",
- "zlib" => "default",
- "zlib-dynamic" => "default"
- );
+ "zlib" => "default",
+ "zlib-dynamic" => "default"
+ );
my @experimental = ();
# This is what $depflags will look like with the above defaults
# (we need this to see if we should advise the user to run "make depend"):
-my $default_depflags = " -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_STORE";
+my $default_depflags = " -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_STORE";
# Explicit "no-..." options will be collected in %disabled along with the defaults.
# To remove something from %disabled, use "enable-foo" (unless it's experimental).
@@ -739,6 +785,7 @@ PROCESS_ARGS:
# rewrite some options in "enable-..." form
s /^-?-?shared$/enable-shared/;
+ s /^sctp$/enable-sctp/;
s /^threads$/enable-threads/;
s /^zlib$/enable-zlib/;
s /^zlib-dynamic$/enable-zlib-dynamic/;
@@ -808,6 +855,10 @@ PROCESS_ARGS:
}
elsif (/^386$/)
{ $processor=386; }
+ elsif (/^fips$/)
+ {
+ $fips=1;
+ }
elsif (/^rsaref$/)
{
# No RSAref support any more since it's not needed.
@@ -822,6 +873,7 @@ PROCESS_ARGS:
}
elsif (/^-[^-]/ or /^\+/)
{
+ $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
$flags.=$_." ";
}
elsif (/^--prefix=(.*)$/)
@@ -852,6 +904,18 @@ PROCESS_ARGS:
{
$withargs{"zlib-include"}="-I$1";
}
+ elsif (/^--with-fipsdir=(.*)$/)
+ {
+ $fipsdir="$1";
+ }
+ elsif (/^--with-fipslibdir=(.*)$/)
+ {
+ $fipslibdir="$1";
+ }
+ elsif (/^--with-baseaddr=(.*)$/)
+ {
+ $baseaddr="$1";
+ }
elsif (/^--cross-compile-prefix=(.*)$/)
{
$cross_compile_prefix=$1;
@@ -926,6 +990,17 @@ if (defined($disabled{"md5"}) || defined($disabled{"rsa"}))
$disabled{"ssl2"} = "forced";
}
+if ($fips && $fipslibdir eq "")
+ {
+ $fipslibdir = $fipsdir . "/lib/";
+ }
+
+# RSAX ENGINE sets default non-FIPS RSA method.
+if ($fips)
+ {
+ $disabled{"rsax"} = "forced";
+ }
+
# SSL 3.0 and TLS requires MD5 and SHA and either RSA or DSA+DH
if (defined($disabled{"md5"}) || defined($disabled{"sha"})
|| (defined($disabled{"rsa"})
@@ -946,6 +1021,13 @@ if (defined($disabled{"ec"}) || defined($disabled{"dsa"})
$disabled{"gost"} = "forced";
}
+# SRP and HEARTBEATS require TLSEXT
+if (defined($disabled{"tlsext"}))
+ {
+ $disabled{"srp"} = "forced";
+ $disabled{"heartbeats"} = "forced";
+ }
+
if ($target eq "TABLE") {
foreach $target (sort keys %table) {
print_table_entry($target);
@@ -995,7 +1077,7 @@ foreach (sort (keys %disabled))
else
{
my ($ALGO, $algo);
- ($ALGO = $algo = $_) =~ tr/[a-z]/[A-Z]/;
+ ($ALGO = $algo = $_) =~ tr/[\-a-z]/[_A-Z]/;
if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/)
{
@@ -1015,6 +1097,8 @@ foreach (sort (keys %disabled))
else
{
push @skip, $algo;
+ # fix-up crypto/directory name(s)
+ @skip[$#skip]="whrlpool" if $algo eq "whirlpool";
print " (skip dir)";
$depflags .= " -DOPENSSL_NO_$ALGO";
@@ -1085,6 +1169,8 @@ my $rmd160_obj = $fields[$idx_rmd160_obj];
my $rc5_obj = $fields[$idx_rc5_obj];
my $wp_obj = $fields[$idx_wp_obj];
my $cmll_obj = $fields[$idx_cmll_obj];
+my $modes_obj = $fields[$idx_modes_obj];
+my $engines_obj = $fields[$idx_engines_obj];
my $perlasm_scheme = $fields[$idx_perlasm_scheme];
my $dso_scheme = $fields[$idx_dso_scheme];
my $shared_target = $fields[$idx_shared_target];
@@ -1245,7 +1331,7 @@ if ($no_asm)
{
$cpuid_obj=$bn_obj=
$des_obj=$aes_obj=$bf_obj=$cast_obj=$rc4_obj=$rc5_obj=$cmll_obj=
- $sha1_obj=$md5_obj=$rmd160_obj=$wp_obj="";
+ $modes_obj=$sha1_obj=$md5_obj=$rmd160_obj=$wp_obj=$engines_obj="";
}
if (!$no_shared)
@@ -1309,7 +1395,7 @@ if (!$IsMK1MF)
}
}
-$cpuid_obj.=" uplink.o uplink-cof.o" if ($cflags =~ /\-DOPENSSL_USE_APPLINK/);
+$cpuid_obj.=" uplink.o uplink-x86.o" if ($cflags =~ /\-DOPENSSL_USE_APPLINK/);
#
# Platform fix-ups
@@ -1377,6 +1463,14 @@ $cflags.=" -DOPENSSL_BN_ASM_PART_WORDS" if ($bn_obj =~ /bn-586/);
$cflags.=" -DOPENSSL_IA32_SSE2" if (!$no_sse2 && $bn_obj =~ /86/);
$cflags.=" -DOPENSSL_BN_ASM_MONT" if ($bn_obj =~ /-mont/);
+$cflags.=" -DOPENSSL_BN_ASM_MONT5" if ($bn_obj =~ /-mont5/);
+$cflags.=" -DOPENSSL_BN_ASM_GF2m" if ($bn_obj =~ /-gf2m/);
+
+if ($fips)
+ {
+ $openssl_other_defines.="#define OPENSSL_FIPS\n";
+ $cflags .= " -I\$(FIPSDIR)/include";
+ }
$cpuid_obj="mem_clr.o" unless ($cpuid_obj =~ /\.o$/);
$des_obj=$des_enc unless ($des_obj =~ /\.o$/);
@@ -1410,12 +1504,20 @@ if ($rmd160_obj =~ /\.o$/)
if ($aes_obj =~ /\.o$/)
{
$cflags.=" -DAES_ASM";
+ # aes-ctr.o is not a real file, only indication that assembler
+ # module implements AES_ctr32_encrypt...
+ $cflags.=" -DAES_CTR_ASM" if ($aes_obj =~ s/\s*aes\-ctr\.o//);
+ # aes-xts.o indicates presense of AES_xts_[en|de]crypt...
+ $cflags.=" -DAES_XTS_ASM" if ($aes_obj =~ s/\s*aes\-xts\.o//);
+ $aes_obj =~ s/\s*(vpaes|aesni)\-x86\.o//g if ($no_sse2);
+ $cflags.=" -DVPAES_ASM" if ($aes_obj =~ m/vpaes/);
+ $cflags.=" -DBSAES_ASM" if ($aes_obj =~ m/bsaes/);
}
else {
$aes_obj=$aes_enc;
}
$wp_obj="" if ($wp_obj =~ /mmx/ && $processor eq "386");
-if ($wp_obj =~ /\.o$/)
+if ($wp_obj =~ /\.o$/ && !$disabled{"whirlpool"})
{
$cflags.=" -DWHIRLPOOL_ASM";
}
@@ -1423,6 +1525,10 @@ else {
$wp_obj="wp_block.o";
}
$cmll_obj=$cmll_enc unless ($cmll_obj =~ /.o$/);
+if ($modes_obj =~ /ghash/)
+ {
+ $cflags.=" -DGHASH_ASM";
+ }
# "Stringify" the C flags string. This permits it to be made part of a string
# and works as well on command lines.
@@ -1537,6 +1643,8 @@ while (<IN>)
s/^RMD160_ASM_OBJ=.*$/RMD160_ASM_OBJ= $rmd160_obj/;
s/^WP_ASM_OBJ=.*$/WP_ASM_OBJ= $wp_obj/;
s/^CMLL_ENC=.*$/CMLL_ENC= $cmll_obj/;
+ s/^MODES_ASM_OBJ.=*$/MODES_ASM_OBJ= $modes_obj/;
+ s/^ENGINES_ASM_OBJ.=*$/ENGINES_ASM_OBJ= $engines_obj/;
s/^PERLASM_SCHEME=.*$/PERLASM_SCHEME= $perlasm_scheme/;
s/^PROCESSOR=.*/PROCESSOR= $processor/;
s/^ARFLAGS=.*/ARFLAGS= $arflags/;
@@ -1545,6 +1653,12 @@ while (<IN>)
s/^LIBKRB5=.*/LIBKRB5=$withargs{"krb5-lib"}/;
s/^LIBZLIB=.*/LIBZLIB=$withargs{"zlib-lib"}/;
s/^ZLIB_INCLUDE=.*/ZLIB_INCLUDE=$withargs{"zlib-include"}/;
+
+ s/^FIPSDIR=.*/FIPSDIR=$fipsdir/;
+ s/^FIPSLIBDIR=.*/FIPSLIBDIR=$fipslibdir/;
+ s/^FIPSCANLIB=.*/FIPSCANLIB=libcrypto/ if $fips;
+ s/^BASEADDR=.*/BASEADDR=$baseaddr/;
+
s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/;
s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/;
s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared);
@@ -1588,7 +1702,9 @@ print "RC5_ENC =$rc5_obj\n";
print "MD5_OBJ_ASM =$md5_obj\n";
print "SHA1_OBJ_ASM =$sha1_obj\n";
print "RMD160_OBJ_ASM=$rmd160_obj\n";
-print "CMLL_ENC= =$cmll_obj\n";
+print "CMLL_ENC =$cmll_obj\n";
+print "MODES_OBJ =$modes_obj\n";
+print "ENGINES_OBJ =$engines_obj\n";
print "PROCESSOR =$processor\n";
print "RANLIB =$ranlib\n";
print "ARFLAGS =$arflags\n";
@@ -1981,7 +2097,8 @@ sub print_table_entry
(my $cc,my $cflags,my $unistd,my $thread_cflag,my $sys_id,my $lflags,
my $bn_ops,my $cpuid_obj,my $bn_obj,my $des_obj,my $aes_obj, my $bf_obj,
my $md5_obj,my $sha1_obj,my $cast_obj,my $rc4_obj,my $rmd160_obj,
- my $rc5_obj,my $wp_obj,my $cmll_obj,my $perlasm_scheme,my $dso_scheme,my $shared_target,my $shared_cflag,
+ my $rc5_obj,my $wp_obj,my $cmll_obj,my $modes_obj, my $engines_obj,
+ my $perlasm_scheme,my $dso_scheme,my $shared_target,my $shared_cflag,
my $shared_ldflag,my $shared_extension,my $ranlib,my $arflags,my $multilib)=
split(/\s*:\s*/,$table{$target} . ":" x 30 , -1);
@@ -2008,6 +2125,8 @@ sub print_table_entry
\$rc5_obj = $rc5_obj
\$wp_obj = $wp_obj
\$cmll_obj = $cmll_obj
+\$modes_obj = $modes_obj
+\$engines_obj = $engines_obj
\$perlasm_scheme = $perlasm_scheme
\$dso_scheme = $dso_scheme
\$shared_target= $shared_target
diff --git a/deps/openssl/openssl/FAQ b/deps/openssl/openssl/FAQ
index 3b07cd363..35780f807 100644
--- a/deps/openssl/openssl/FAQ
+++ b/deps/openssl/openssl/FAQ
@@ -10,6 +10,7 @@ OpenSSL - Frequently Asked Questions
* Why aren't tools like 'autoconf' and 'libtool' used?
* What is an 'engine' version?
* How do I check the authenticity of the OpenSSL distribution?
+* How does the versioning scheme work?
[LEGAL] Legal questions
@@ -82,11 +83,11 @@ OpenSSL - Frequently Asked Questions
* Which is the current version of OpenSSL?
The current version is available from <URL: http://www.openssl.org>.
-OpenSSL 1.0.0f was released on Jan 4th, 2012.
+OpenSSL 1.0.1e was released on Feb 11th, 2013.
In addition to the current stable release, you can also access daily
snapshots of the OpenSSL development version at <URL:
-ftp://ftp.openssl.org/snapshot/>, or get it by anonymous CVS access.
+ftp://ftp.openssl.org/snapshot/>, or get it by anonymous Git access.
* Where is the documentation?
@@ -108,7 +109,9 @@ In addition, you can read the most current versions at
<URL: http://www.openssl.org/docs/>. Note that the online documents refer
to the very latest development versions of OpenSSL and may include features
not present in released versions. If in doubt refer to the documentation
-that came with the version of OpenSSL you are using.
+that came with the version of OpenSSL you are using. The pod format
+documentation is included in each OpenSSL distribution under the docs
+directory.
For information on parts of libcrypto that are not yet documented, you
might want to read Ariel Glenn's documentation on SSLeay 0.9, OpenSSL's
@@ -173,6 +176,19 @@ just do:
pgp TARBALL.asc
+* How does the versioning scheme work?
+
+After the release of OpenSSL 1.0.0 the versioning scheme changed. Letter
+releases (e.g. 1.0.1a) can only contain bug and security fixes and no
+new features. Minor releases change the last number (e.g. 1.0.2) and
+can contain new features that retain binary compatibility. Changes to
+the middle number are considered major releases and neither source nor
+binary compatibility is guaranteed.
+
+Therefore the answer to the common question "when will feature X be
+backported to OpenSSL 1.0.0/0.9.8?" is "never" but it could appear
+in the next minor release.
+
[LEGAL] =======================================================================
* Do I need patent licenses to use OpenSSL?
@@ -284,7 +300,7 @@ current directory in this case, but this has changed with 0.9.6a.)
Check out the CA.pl(1) manual page. This provides a simple wrapper round
the 'req', 'verify', 'ca' and 'pkcs12' utilities. For finer control check
out the manual pages for the individual utilities and the certificate
-extensions documentation (currently in doc/openssl.txt).
+extensions documentation (in ca(1), req(1), x509v3_config(5) )
* Why can't I create certificate requests?
diff --git a/deps/openssl/openssl/INSTALL.W32 b/deps/openssl/openssl/INSTALL.W32
index d23c4baf6..80e538273 100644
--- a/deps/openssl/openssl/INSTALL.W32
+++ b/deps/openssl/openssl/INSTALL.W32
@@ -29,7 +29,7 @@
is required if you intend to utilize assembler modules. Note that NASM
is now the only supported assembler.
- If you are compiling from a tarball or a CVS snapshot then the Win32 files
+ If you are compiling from a tarball or a Git snapshot then the Win32 files
may well be not up to date. This may mean that some "tweaking" is required to
get it all to work. See the trouble shooting section later on for if (when?)
it goes wrong.
@@ -257,7 +257,7 @@
then ms\do_XXX should not give a warning any more. However the numbers that
get assigned by this technique may not match those that eventually get
- assigned in the CVS tree: so anything linked against this version of the
+ assigned in the Git tree: so anything linked against this version of the
library may need to be recompiled.
If you get errors about unresolved symbols there are several possible
diff --git a/deps/openssl/openssl/Makefile b/deps/openssl/openssl/Makefile
index 8fe888587..54e354161 100644
--- a/deps/openssl/openssl/Makefile
+++ b/deps/openssl/openssl/Makefile
@@ -4,16 +4,16 @@
## Makefile for OpenSSL
##
-VERSION=1.0.0f
+VERSION=1.0.1e
MAJOR=1
-MINOR=0.0
+MINOR=0.1
SHLIB_VERSION_NUMBER=1.0.0
SHLIB_VERSION_HISTORY=
SHLIB_MAJOR=1
SHLIB_MINOR=0.0
SHLIB_EXT=
PLATFORM=dist
-OPTIONS= no-gmp no-jpake no-krb5 no-md2 no-rc5 no-rfc3779 no-shared no-store no-zlib no-zlib-dynamic static-engine
+OPTIONS= no-ec_nistp_64_gcc_128 no-gmp no-jpake no-krb5 no-md2 no-rc5 no-rfc3779 no-sctp no-shared no-store no-zlib no-zlib-dynamic static-engine
CONFIGURE_ARGS=dist
SHLIB_TARGET=
@@ -61,7 +61,7 @@ OPENSSLDIR=/usr/local/ssl
CC= cc
CFLAG= -O
-DEPFLAG= -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_STORE
+DEPFLAG= -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_STORE
PEX_LIBS=
EX_LIBS=
EXE_EXT=
@@ -71,7 +71,7 @@ RANLIB= /usr/bin/ranlib
NM= nm
PERL= /usr/bin/perl
TAR= tar
-TARFLAGS= --no-recursion
+TARFLAGS= --no-recursion --record-size=10240
MAKEDEPPROG=makedepend
LIBDIR=lib
@@ -101,6 +101,8 @@ SHA1_ASM_OBJ=
RMD160_ASM_OBJ=
WP_ASM_OBJ= wp_block.o
CMLL_ENC= camellia.o cmll_misc.o cmll_cbc.o
+MODES_ASM_OBJ=
+ENGINES_ASM_OBJ=
PERLASM_SCHEME=
# KRB5 stuff
@@ -111,6 +113,30 @@ LIBKRB5=
ZLIB_INCLUDE=
LIBZLIB=
+# TOP level FIPS install directory.
+FIPSDIR=/usr/local/ssl/fips-2.0
+
+# This is the location of fipscanister.o and friends.
+# The FIPS module build will place it $(INSTALLTOP)/lib
+# but since $(INSTALLTOP) can only take the default value
+# when the module is built it will be in /usr/local/ssl/lib
+# $(INSTALLTOP) for this build may be different so hard
+# code the path.
+
+FIPSLIBDIR=
+
+# The location of the library which contains fipscanister.o
+# normally it will be libcrypto unless fipsdso is set in which
+# case it will be libfips. If not compiling in FIPS mode at all
+# this is empty making it a useful test for a FIPS compile.
+
+FIPSCANLIB=
+
+# Shared library base address. Currently only used on Windows.
+#
+
+BASEADDR=0xFB00000
+
DIRS= crypto ssl engines apps test tools
ENGDIRS= ccgost
SHLIBDIRS= crypto ssl
@@ -123,7 +149,7 @@ SDIRS= \
bn ec rsa dsa ecdsa dh ecdh dso engine \
buffer bio stack lhash rand err \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
- cms pqueue ts
+ cms pqueue ts srp cmac
# keep in mind that the above list is adjusted by ./Configure
# according to no-xxx arguments...
@@ -174,7 +200,7 @@ CLEARENV= TOP= && unset TOP $${LIB+LIB} $${LIBS+LIBS} \
$${EXHEADER+EXHEADER} $${HEADER+HEADER} \
$${GENERAL+GENERAL} $${CFLAGS+CFLAGS} \
$${ASFLAGS+ASFLAGS} $${AFLAGS+AFLAGS} \
- $${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS} \
+ $${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS} $${SCRIPTS+SCRIPTS} \
$${SHAREDCMD+SHAREDCMD} $${SHAREDFLAGS+SHAREDFLAGS} \
$${SHARED_LIB+SHARED_LIB} $${LIBEXTRAS+LIBEXTRAS}
@@ -206,7 +232,12 @@ BUILDENV= PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)' \
MD5_ASM_OBJ='$(MD5_ASM_OBJ)' \
RMD160_ASM_OBJ='$(RMD160_ASM_OBJ)' \
WP_ASM_OBJ='$(WP_ASM_OBJ)' \
+ MODES_ASM_OBJ='$(MODES_ASM_OBJ)' \
+ ENGINES_ASM_OBJ='$(ENGINES_ASM_OBJ)' \
PERLASM_SCHEME='$(PERLASM_SCHEME)' \
+ FIPSLIBDIR='${FIPSLIBDIR}' \
+ FIPSDIR='${FIPSDIR}' \
+ FIPSCANLIB="$${FIPSCANLIB:-$(FIPSCANLIB)}" \
THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES=
# MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors,
# which in turn eliminates ambiguities in variable treatment with -e.
@@ -260,9 +291,20 @@ all_testapps: build_libs build_testapps
build_testapps:
@dir=crypto; target=testapps; $(BUILD_ONE_CMD)
-libcrypto$(SHLIB_EXT): libcrypto.a
+fips_premain_dso$(EXE_EXT): libcrypto.a
+ [ -z "$(FIPSCANLIB)" ] || $(CC) $(CFLAG) -Iinclude \
+ -DFINGERPRINT_PREMAIN_DSO_LOAD -o $@ \
+ $(FIPSLIBDIR)fips_premain.c $(FIPSLIBDIR)fipscanister.o \
+ libcrypto.a $(EX_LIBS)
+
+libcrypto$(SHLIB_EXT): libcrypto.a fips_premain_dso$(EXE_EXT)
@if [ "$(SHLIB_TARGET)" != "" ]; then \
- $(MAKE) SHLIBDIRS=crypto build-shared; \
+ if [ "$(FIPSCANLIB)" = "libcrypto" ]; then \
+ FIPSLD_LIBCRYPTO=libcrypto.a ; \
+ FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; \
+ export CC FIPSLD_CC FIPSLD_LIBCRYPTO; \
+ fi; \
+ $(MAKE) -e SHLIBDIRS=crypto build-shared; \
else \
echo "There's no support for shared libraries on this platform" >&2; \
exit 1; \
@@ -324,7 +366,8 @@ libcrypto.pc: Makefile
echo 'Description: OpenSSL cryptography library'; \
echo 'Version: '$(VERSION); \
echo 'Requires: '; \
- echo 'Libs: -L$${libdir} -lcrypto $(EX_LIBS)'; \
+ echo 'Libs: -L$${libdir} -lcrypto'; \
+ echo 'Libs.private: $(EX_LIBS)'; \
echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libcrypto.pc
libssl.pc: Makefile
@@ -337,7 +380,8 @@ libssl.pc: Makefile
echo 'Description: Secure Sockets Layer and cryptography libraries'; \
echo 'Version: '$(VERSION); \
echo 'Requires: '; \
- echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)'; \
+ echo 'Libs: -L$${libdir} -lssl -lcrypto'; \
+ echo 'Libs.private: $(EX_LIBS)'; \
echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libssl.pc
openssl.pc: Makefile
@@ -350,7 +394,8 @@ openssl.pc: Makefile
echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \
echo 'Version: '$(VERSION); \
echo 'Requires: '; \
- echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)'; \
+ echo 'Libs: -L$${libdir} -lssl -lcrypto'; \
+ echo 'Libs.private: $(EX_LIBS)'; \
echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > openssl.pc
Makefile: Makefile.org Configure config
@@ -359,7 +404,7 @@ Makefile: Makefile.org Configure config
@false
libclean:
- rm -f *.map *.so *.so.* *.dll engines/*.so engines/*.dll *.a engines/*.a */lib */*/lib
+ rm -f *.map *.so *.so.* *.dylib *.dll engines/*.so engines/*.dll engines/*.dylib *.a engines/*.a */lib */*/lib
clean: libclean
rm -f shlib/*.o *.o core a.out fluff rehash.time testlog make.log cctest cctest.c
@@ -401,7 +446,7 @@ rehash.time: certs apps
[ -x "apps/openssl.exe" ] && OPENSSL="apps/openssl.exe" || :; \
OPENSSL_DEBUG_MEMORY=on; \
export OPENSSL OPENSSL_DEBUG_MEMORY; \
- $(PERL) tools/c_rehash certs) && \
+ $(PERL) tools/c_rehash certs/demo) && \
touch rehash.time; \
else :; fi
@@ -426,9 +471,9 @@ tags:
find . -name '[^.]*.[ch]' | xargs etags -a
errors:
+ $(PERL) util/ck_errf.pl -strict */*.c */*/*.c
$(PERL) util/mkerr.pl -recurse -write
(cd engines; $(MAKE) PERL=$(PERL) errors)
- $(PERL) util/ck_errf.pl */*.c */*/*.c
stacks:
$(PERL) util/mkstack.pl -write
@@ -511,7 +556,7 @@ install_sw:
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
done;
@set -e; target=install; $(RECURSIVE_BUILD_CMD)
- @set -e; for i in $(LIBS) ;\
+ @set -e; liblist="$(LIBS)"; for i in $$liblist ;\
do \
if [ -f "$$i" ]; then \
( echo installing $$i; \
diff --git a/deps/openssl/openssl/Makefile.org b/deps/openssl/openssl/Makefile.org
index fb0af7ecc..2db31ead6 100644
--- a/deps/openssl/openssl/Makefile.org
+++ b/deps/openssl/openssl/Makefile.org
@@ -69,7 +69,7 @@ RANLIB= ranlib
NM= nm
PERL= perl
TAR= tar
-TARFLAGS= --no-recursion
+TARFLAGS= --no-recursion --record-size=10240
MAKEDEPPROG=makedepend
LIBDIR=lib
@@ -99,6 +99,8 @@ SHA1_ASM_OBJ=
RMD160_ASM_OBJ=
WP_ASM_OBJ=
CMLL_ENC=
+MODES_ASM_OBJ=
+ENGINES_ASM_OBJ=
PERLASM_SCHEME=
# KRB5 stuff
@@ -109,6 +111,30 @@ LIBKRB5=
ZLIB_INCLUDE=
LIBZLIB=
+# TOP level FIPS install directory.
+FIPSDIR=
+
+# This is the location of fipscanister.o and friends.
+# The FIPS module build will place it $(INSTALLTOP)/lib
+# but since $(INSTALLTOP) can only take the default value
+# when the module is built it will be in /usr/local/ssl/lib
+# $(INSTALLTOP) for this build may be different so hard
+# code the path.
+
+FIPSLIBDIR=
+
+# The location of the library which contains fipscanister.o
+# normally it will be libcrypto unless fipsdso is set in which
+# case it will be libfips. If not compiling in FIPS mode at all
+# this is empty making it a useful test for a FIPS compile.
+
+FIPSCANLIB=
+
+# Shared library base address. Currently only used on Windows.
+#
+
+BASEADDR=
+
DIRS= crypto ssl engines apps test tools
ENGDIRS= ccgost
SHLIBDIRS= crypto ssl
@@ -121,7 +147,7 @@ SDIRS= \
bn ec rsa dsa ecdsa dh ecdh dso engine \
buffer bio stack lhash rand err \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
- cms pqueue ts jpake store
+ cms pqueue ts jpake srp store cmac
# keep in mind that the above list is adjusted by ./Configure
# according to no-xxx arguments...
@@ -172,7 +198,7 @@ CLEARENV= TOP= && unset TOP $${LIB+LIB} $${LIBS+LIBS} \
$${EXHEADER+EXHEADER} $${HEADER+HEADER} \
$${GENERAL+GENERAL} $${CFLAGS+CFLAGS} \
$${ASFLAGS+ASFLAGS} $${AFLAGS+AFLAGS} \
- $${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS} \
+ $${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS} $${SCRIPTS+SCRIPTS} \
$${SHAREDCMD+SHAREDCMD} $${SHAREDFLAGS+SHAREDFLAGS} \
$${SHARED_LIB+SHARED_LIB} $${LIBEXTRAS+LIBEXTRAS}
@@ -204,7 +230,12 @@ BUILDENV= PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)' \
MD5_ASM_OBJ='$(MD5_ASM_OBJ)' \
RMD160_ASM_OBJ='$(RMD160_ASM_OBJ)' \
WP_ASM_OBJ='$(WP_ASM_OBJ)' \
+ MODES_ASM_OBJ='$(MODES_ASM_OBJ)' \
+ ENGINES_ASM_OBJ='$(ENGINES_ASM_OBJ)' \
PERLASM_SCHEME='$(PERLASM_SCHEME)' \
+ FIPSLIBDIR='${FIPSLIBDIR}' \
+ FIPSDIR='${FIPSDIR}' \
+ FIPSCANLIB="$${FIPSCANLIB:-$(FIPSCANLIB)}" \
THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES=
# MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors,
# which in turn eliminates ambiguities in variable treatment with -e.
@@ -258,9 +289,20 @@ all_testapps: build_libs build_testapps
build_testapps:
@dir=crypto; target=testapps; $(BUILD_ONE_CMD)
-libcrypto$(SHLIB_EXT): libcrypto.a
+fips_premain_dso$(EXE_EXT): libcrypto.a
+ [ -z "$(FIPSCANLIB)" ] || $(CC) $(CFLAG) -Iinclude \
+ -DFINGERPRINT_PREMAIN_DSO_LOAD -o $@ \
+ $(FIPSLIBDIR)fips_premain.c $(FIPSLIBDIR)fipscanister.o \
+ libcrypto.a $(EX_LIBS)
+
+libcrypto$(SHLIB_EXT): libcrypto.a fips_premain_dso$(EXE_EXT)
@if [ "$(SHLIB_TARGET)" != "" ]; then \
- $(MAKE) SHLIBDIRS=crypto build-shared; \
+ if [ "$(FIPSCANLIB)" = "libcrypto" ]; then \
+ FIPSLD_LIBCRYPTO=libcrypto.a ; \
+ FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; \
+ export CC FIPSLD_CC FIPSLD_LIBCRYPTO; \
+ fi; \
+ $(MAKE) -e SHLIBDIRS=crypto build-shared; \
else \
echo "There's no support for shared libraries on this platform" >&2; \
exit 1; \
@@ -322,7 +364,8 @@ libcrypto.pc: Makefile
echo 'Description: OpenSSL cryptography library'; \
echo 'Version: '$(VERSION); \
echo 'Requires: '; \
- echo 'Libs: -L$${libdir} -lcrypto $(EX_LIBS)'; \
+ echo 'Libs: -L$${libdir} -lcrypto'; \
+ echo 'Libs.private: $(EX_LIBS)'; \
echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libcrypto.pc
libssl.pc: Makefile
@@ -335,7 +378,8 @@ libssl.pc: Makefile
echo 'Description: Secure Sockets Layer and cryptography libraries'; \
echo 'Version: '$(VERSION); \
echo 'Requires: '; \
- echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)'; \
+ echo 'Libs: -L$${libdir} -lssl -lcrypto'; \
+ echo 'Libs.private: $(EX_LIBS)'; \
echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libssl.pc
openssl.pc: Makefile
@@ -348,7 +392,8 @@ openssl.pc: Makefile
echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \
echo 'Version: '$(VERSION); \
echo 'Requires: '; \
- echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)'; \
+ echo 'Libs: -L$${libdir} -lssl -lcrypto'; \
+ echo 'Libs.private: $(EX_LIBS)'; \
echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > openssl.pc
Makefile: Makefile.org Configure config
@@ -357,7 +402,7 @@ Makefile: Makefile.org Configure config
@false
libclean:
- rm -f *.map *.so *.so.* *.dll engines/*.so engines/*.dll *.a engines/*.a */lib */*/lib
+ rm -f *.map *.so *.so.* *.dylib *.dll engines/*.so engines/*.dll engines/*.dylib *.a engines/*.a */lib */*/lib
clean: libclean
rm -f shlib/*.o *.o core a.out fluff rehash.time testlog make.log cctest cctest.c
@@ -399,7 +444,7 @@ rehash.time: certs apps
[ -x "apps/openssl.exe" ] && OPENSSL="apps/openssl.exe" || :; \
OPENSSL_DEBUG_MEMORY=on; \
export OPENSSL OPENSSL_DEBUG_MEMORY; \
- $(PERL) tools/c_rehash certs) && \
+ $(PERL) tools/c_rehash certs/demo) && \
touch rehash.time; \
else :; fi
@@ -424,9 +469,9 @@ tags:
find . -name '[^.]*.[ch]' | xargs etags -a
errors:
+ $(PERL) util/ck_errf.pl -strict */*.c */*/*.c
$(PERL) util/mkerr.pl -recurse -write
(cd engines; $(MAKE) PERL=$(PERL) errors)
- $(PERL) util/ck_errf.pl */*.c */*/*.c
stacks:
$(PERL) util/mkstack.pl -write
@@ -509,7 +554,7 @@ install_sw:
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
done;
@set -e; target=install; $(RECURSIVE_BUILD_CMD)
- @set -e; for i in $(LIBS) ;\
+ @set -e; liblist="$(LIBS)"; for i in $$liblist ;\
do \
if [ -f "$$i" ]; then \
( echo installing $$i; \
diff --git a/deps/openssl/openssl/NEWS b/deps/openssl/openssl/NEWS
index 1fb25c626..0269f2277 100644
--- a/deps/openssl/openssl/NEWS
+++ b/deps/openssl/openssl/NEWS
@@ -5,6 +5,58 @@
This file gives a brief overview of the major changes between each OpenSSL
release. For more details please read the CHANGES file.
+ Major changes between OpenSSL 1.0.1d and OpenSSL 1.0.1e:
+
+ o Corrected fix for CVE-2013-0169
+
+ Major changes between OpenSSL 1.0.1c and OpenSSL 1.0.1d:
+
+ o Fix renegotiation in TLS 1.1, 1.2 by using the correct TLS version.
+ o Include the fips configuration module.
+ o Fix OCSP bad key DoS attack CVE-2013-0166
+ o Fix for SSL/TLS/DTLS CBC plaintext recovery attack CVE-2013-0169
+ o Fix for TLS AESNI record handling flaw CVE-2012-2686
+
+ Major changes between OpenSSL 1.0.1b and OpenSSL 1.0.1c:
+
+ o Fix TLS/DTLS record length checking bug CVE-2012-2333
+ o Don't attempt to use non-FIPS composite ciphers in FIPS mode.
+
+ Major changes between OpenSSL 1.0.1a and OpenSSL 1.0.1b:
+
+ o Fix compilation error on non-x86 platforms.
+ o Make FIPS capable OpenSSL ciphers work in non-FIPS mode.
+ o Fix SSL_OP_NO_TLSv1_1 clash with SSL_OP_ALL in OpenSSL 1.0.0
+
+ Major changes between OpenSSL 1.0.1 and OpenSSL 1.0.1a:
+
+ o Fix for ASN1 overflow bug CVE-2012-2110
+ o Workarounds for some servers that hang on long client hellos.
+ o Fix SEGV in AES code.
+
+ Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.1:
+
+ o TLS/DTLS heartbeat support.
+ o SCTP support.
+ o RFC 5705 TLS key material exporter.
+ o RFC 5764 DTLS-SRTP negotiation.
+ o Next Protocol Negotiation.
+ o PSS signatures in certificates, requests and CRLs.
+ o Support for password based recipient info for CMS.
+ o Support TLS v1.2 and TLS v1.1.
+ o Preliminary FIPS capability for unvalidated 2.0 FIPS module.
+ o SRP support.
+
+ Major changes between OpenSSL 1.0.0g and OpenSSL 1.0.0h:
+
+ o Fix for CMS/PKCS#7 MMA CVE-2012-0884
+ o Corrected fix for CVE-2011-4619
+ o Various DTLS fixes.
+
+ Major changes between OpenSSL 1.0.0f and OpenSSL 1.0.0g:
+
+ o Fix for DTLS DoS issue CVE-2012-0050
+
Major changes between OpenSSL 1.0.0e and OpenSSL 1.0.0f:
o Fix for DTLS plaintext recovery attack CVE-2011-4108
diff --git a/deps/openssl/openssl/PROBLEMS b/deps/openssl/openssl/PROBLEMS
index d247470f0..3eaab01f2 100644
--- a/deps/openssl/openssl/PROBLEMS
+++ b/deps/openssl/openssl/PROBLEMS
@@ -197,3 +197,17 @@ reconfigure with additional no-sse2 [or 386] option passed to ./config.
We don't have framework to associate -ldl with no-dso, therefore the only
way is to edit Makefile right after ./config no-dso and remove -ldl from
EX_LIBS line.
+
+* hpux-parisc2-cc no-asm build fails with SEGV in ECDSA/DH.
+
+Compiler bug, presumably at particular patch level. Remaining
+hpux*-parisc*-cc configurations can be affected too. Drop optimization
+level to +O2 when compiling bn_nist.o.
+
+* solaris64-sparcv9-cc link failure
+
+Solaris 8 ar can fail to maintain symbol table in .a, which results in
+link failures. Apply 109147-09 or later or modify Makefile generated
+by ./Configure solaris64-sparcv9-cc and replace RANLIB assignment with
+
+ RANLIB= /usr/ccs/bin/ar rs
diff --git a/deps/openssl/openssl/README b/deps/openssl/openssl/README
index 50d54d570..ad2d90f0d 100644
--- a/deps/openssl/openssl/README
+++ b/deps/openssl/openssl/README
@@ -1,5 +1,5 @@
- OpenSSL 1.0.0f 4 Jan 2012
+ OpenSSL 1.0.1e 11 Feb 2013
Copyright (c) 1998-2011 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
@@ -190,7 +190,7 @@
reason as to why that feature isn't implemented.
Patches should be as up to date as possible, preferably relative to the
- current CVS or the last snapshot. They should follow the coding style of
+ current Git or the last snapshot. They should follow the coding style of
OpenSSL and compile without warnings. Some of the core team developer targets
can be used for testing purposes, (debug-steve64, debug-geoff etc). OpenSSL
compiles on many varied platforms: try to ensure you only use portable
diff --git a/deps/openssl/openssl/VMS/install-vms.com b/deps/openssl/openssl/VMS/install-vms.com
index 7da8b2153..7da8b2153 100644..100755
--- a/deps/openssl/openssl/VMS/install-vms.com
+++ b/deps/openssl/openssl/VMS/install-vms.com
diff --git a/deps/openssl/openssl/VMS/openssl_startup.com b/deps/openssl/openssl/VMS/openssl_startup.com
index 04bbbde88..04bbbde88 100644..100755
--- a/deps/openssl/openssl/VMS/openssl_startup.com
+++ b/deps/openssl/openssl/VMS/openssl_startup.com
diff --git a/deps/openssl/openssl/VMS/openssl_undo.com b/deps/openssl/openssl/VMS/openssl_undo.com
index d1623a316..d1623a316 100644..100755
--- a/deps/openssl/openssl/VMS/openssl_undo.com
+++ b/deps/openssl/openssl/VMS/openssl_undo.com
diff --git a/deps/openssl/openssl/apps/CA.com b/deps/openssl/openssl/apps/CA.com
new file mode 100644
index 000000000..2c0d46527
--- /dev/null
+++ b/deps/openssl/openssl/apps/CA.com
@@ -0,0 +1,236 @@
+$! CA - wrapper around ca to make it easier to use ... basically ca requires
+$! some setup stuff to be done before you can use it and this makes
+$! things easier between now and when Eric is convinced to fix it :-)
+$!
+$! CA -newca ... will setup the right stuff
+$! CA -newreq ... will generate a certificate request
+$! CA -sign ... will sign the generated request and output
+$!
+$! At the end of that grab newreq.pem and newcert.pem (one has the key
+$! and the other the certificate) and cat them together and that is what
+$! you want/need ... I'll make even this a little cleaner later.
+$!
+$!
+$! 12-Jan-96 tjh Added more things ... including CA -signcert which
+$! converts a certificate to a request and then signs it.
+$! 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG
+$! environment variable so this can be driven from
+$! a script.
+$! 25-Jul-96 eay Cleaned up filenames some more.
+$! 11-Jun-96 eay Fixed a few filename missmatches.
+$! 03-May-96 eay Modified to use 'openssl cmd' instead of 'cmd'.
+$! 18-Apr-96 tjh Original hacking
+$!
+$! Tim Hudson
+$! tjh@cryptsoft.com
+$!
+$!
+$! default ssleay.cnf file has setup as per the following
+$! demoCA ... where everything is stored
+$
+$ IF F$TYPE(SSLEAY_CONFIG) .EQS. "" THEN SSLEAY_CONFIG := SSLLIB:SSLEAY.CNF
+$
+$ DAYS = "-days 365"
+$ REQ = openssl + " req " + SSLEAY_CONFIG
+$ CA = openssl + " ca " + SSLEAY_CONFIG
+$ VERIFY = openssl + " verify"
+$ X509 = openssl + " x509"
+$ PKCS12 = openssl + " pkcs12"
+$ echo = "write sys$Output"
+$ RET = 1
+$!
+$! 2010-12-20 SMS.
+$! Use a concealed logical name to reduce command line lengths, to
+$! avoid DCL errors on VAX:
+$! %DCL-W-TKNOVF, command element is too long - shorten
+$! (Path segments like "openssl-1_0_1-stable-SNAP-20101217" accumulate
+$! quickly.)
+$!
+$ CATOP = F$PARSE( F$ENVIRONMENT( "DEFAULT"), "[]")- "].;"+ ".demoCA.]"
+$ define /translation_attributes = concealed CATOP 'CATOP'
+$!
+$ on error then goto clean_up
+$ on control_y then goto clean_up
+$!
+$ CAKEY = "CATOP:[private]cakey.pem"
+$ CACERT = "CATOP:[000000]cacert.pem"
+$
+$ __INPUT := SYS$COMMAND
+$!
+$ i = 1
+$opt_loop:
+$ if i .gt. 8 then goto opt_loop_end
+$
+$ prog_opt = F$EDIT(P'i',"lowercase")
+$
+$ IF (prog_opt .EQS. "?" .OR. prog_opt .EQS. "-h" .OR. prog_opt .EQS. "-help")
+$ THEN
+$ echo "usage: CA -newcert|-newreq|-newca|-sign|-verify"
+$ goto clean_up
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-input")
+$ THEN
+$ ! Get input from somewhere other than SYS$COMMAND
+$ i = i + 1
+$ __INPUT = P'i'
+$ GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-newcert")
+$ THEN
+$ ! Create a certificate.
+$ DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$ REQ -new -x509 -keyout newreq.pem -out newreq.pem 'DAYS'
+$ RET=$STATUS
+$ echo "Certificate (and private key) is in newreq.pem"
+$ GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-newreq")
+$ THEN
+$ ! Create a certificate request
+$ DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$ REQ -new -keyout newreq.pem -out newreq.pem 'DAYS'
+$ RET=$STATUS
+$ echo "Request (and private key) is in newreq.pem"
+$ GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-newca")
+$ THEN
+$ ! If explicitly asked for or it doesn't exist then setup the directory
+$ ! structure that Eric likes to manage things.
+$ IF F$SEARCH( "CATOP:[000000]serial.") .EQS. ""
+$ THEN
+$ CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[000000]
+$ CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[certs]
+$ CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[crl]
+$ CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[newcerts]
+$ CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[private]
+$
+$ OPEN /WRITE ser_file CATOP:[000000]serial.
+$ WRITE ser_file "01"
+$ CLOSE ser_file
+$ APPEND /NEW_VERSION NL: CATOP:[000000]index.txt
+$
+$ ! The following is to make sure access() doesn't get confused. It
+$ ! really needs one file in the directory to give correct answers...
+$ COPY NLA0: CATOP:[certs].;
+$ COPY NLA0: CATOP:[crl].;
+$ COPY NLA0: CATOP:[newcerts].;
+$ COPY NLA0: CATOP:[private].;
+$ ENDIF
+$!
+$ IF F$SEARCH( CAKEY) .EQS. ""
+$ THEN
+$ READ '__INPUT' FILE -
+ /PROMPT="CA certificate filename (or enter to create): "
+$ IF (FILE .NES. "") .AND. (F$SEARCH(FILE) .NES. "")
+$ THEN
+$ COPY 'FILE' 'CAKEY'
+$ RET=$STATUS
+$ ELSE
+$ echo "Making CA certificate ..."
+$ DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$ REQ -new -x509 -keyout 'CAKEY' -out 'CACERT' 'DAYS'
+$ RET=$STATUS
+$ ENDIF
+$ ENDIF
+$ GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-pkcs12")
+$ THEN
+$ i = i + 1
+$ cname = P'i'
+$ IF cname .EQS. "" THEN cname = "My certificate"
+$ PKCS12 -in newcert.pem -inkey newreq.pem -certfile 'CACERT' -
+ -out newcert.p12 -export -name "''cname'"
+$ RET=$STATUS
+$ goto clean_up
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-xsign")
+$ THEN
+$!
+$ DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$ CA -policy policy_anything -infiles newreq.pem
+$ RET=$STATUS
+$ GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF ((prog_opt .EQS. "-sign") .OR. (prog_opt .EQS. "-signreq"))
+$ THEN
+$!
+$ DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$ CA -policy policy_anything -out newcert.pem -infiles newreq.pem
+$ RET=$STATUS
+$ type newcert.pem
+$ echo "Signed certificate is in newcert.pem"
+$ GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-signcert")
+$ THEN
+$!
+$ echo "Cert passphrase will be requested twice - bug?"
+$ DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$ X509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem
+$ DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$ CA -policy policy_anything -out newcert.pem -infiles tmp.pem
+y
+y
+$ type newcert.pem
+$ echo "Signed certificate is in newcert.pem"
+$ GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-verify")
+$ THEN
+$!
+$ i = i + 1
+$ IF (p'i' .EQS. "")
+$ THEN
+$ DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$ VERIFY "-CAfile" 'CACERT' newcert.pem
+$ ELSE
+$ j = i
+$ verify_opt_loop:
+$ IF j .GT. 8 THEN GOTO verify_opt_loop_end
+$ IF p'j' .NES. ""
+$ THEN
+$ DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$ __tmp = p'j'
+$ VERIFY "-CAfile" 'CACERT' '__tmp'
+$ tmp=$STATUS
+$ IF tmp .NE. 0 THEN RET=tmp
+$ ENDIF
+$ j = j + 1
+$ GOTO verify_opt_loop
+$ verify_opt_loop_end:
+$ ENDIF
+$
+$ GOTO opt_loop_end
+$ ENDIF
+$!
+$ IF (prog_opt .NES. "")
+$ THEN
+$!
+$ echo "Unknown argument ''prog_opt'"
+$ RET = 3
+$ goto clean_up
+$ ENDIF
+$
+$opt_loop_continue:
+$ i = i + 1
+$ GOTO opt_loop
+$
+$opt_loop_end:
+$!
+$clean_up:
+$!
+$ if f$trnlnm( "CATOP", "LNM$PROCESS") .nes. "" then -
+ deassign /process CATOP
+$!
+$ EXIT 'RET'
diff --git a/deps/openssl/openssl/apps/CA.pl b/deps/openssl/openssl/apps/CA.pl
new file mode 100644
index 000000000..a3965ecea
--- /dev/null
+++ b/deps/openssl/openssl/apps/CA.pl
@@ -0,0 +1,189 @@
+#!/usr/bin/perl
+#
+# CA - wrapper around ca to make it easier to use ... basically ca requires
+# some setup stuff to be done before you can use it and this makes
+# things easier between now and when Eric is convinced to fix it :-)
+#
+# CA -newca ... will setup the right stuff
+# CA -newreq[-nodes] ... will generate a certificate request
+# CA -sign ... will sign the generated request and output
+#
+# At the end of that grab newreq.pem and newcert.pem (one has the key
+# and the other the certificate) and cat them together and that is what
+# you want/need ... I'll make even this a little cleaner later.
+#
+#
+# 12-Jan-96 tjh Added more things ... including CA -signcert which
+# converts a certificate to a request and then signs it.
+# 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG
+# environment variable so this can be driven from
+# a script.
+# 25-Jul-96 eay Cleaned up filenames some more.
+# 11-Jun-96 eay Fixed a few filename missmatches.
+# 03-May-96 eay Modified to use 'ssleay cmd' instead of 'cmd'.
+# 18-Apr-96 tjh Original hacking
+#
+# Tim Hudson
+# tjh@cryptsoft.com
+#
+
+# 27-Apr-98 snh Translation into perl, fix existing CA bug.
+#
+#
+# Steve Henson
+# shenson@bigfoot.com
+
+# default openssl.cnf file has setup as per the following
+# demoCA ... where everything is stored
+
+my $openssl;
+if(defined $ENV{OPENSSL}) {
+ $openssl = $ENV{OPENSSL};
+} else {
+ $openssl = "openssl";
+ $ENV{OPENSSL} = $openssl;
+}
+
+$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"};
+$DAYS="-days 365"; # 1 year
+$CADAYS="-days 1095"; # 3 years
+$REQ="$openssl req $SSLEAY_CONFIG";
+$CA="$openssl ca $SSLEAY_CONFIG";
+$VERIFY="$openssl verify";
+$X509="$openssl x509";
+$PKCS12="$openssl pkcs12";
+
+$CATOP="./demoCA";
+$CAKEY="cakey.pem";
+$CAREQ="careq.pem";
+$CACERT="cacert.pem";
+
+$DIRMODE = 0777;
+
+$RET = 0;
+
+foreach (@ARGV) {
+ if ( /^(-\?|-h|-help)$/ ) {
+ print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
+ exit 0;
+ } elsif (/^-newcert$/) {
+ # create a certificate
+ system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS");
+ $RET=$?;
+ print "Certificate is in newcert.pem, private key is in newkey.pem\n"
+ } elsif (/^-newreq$/) {
+ # create a certificate request
+ system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS");
+ $RET=$?;
+ print "Request is in newreq.pem, private key is in newkey.pem\n";
+ } elsif (/^-newreq-nodes$/) {
+ # create a certificate request
+ system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS");
+ $RET=$?;
+ print "Request is in newreq.pem, private key is in newkey.pem\n";
+ } elsif (/^-newca$/) {
+ # if explicitly asked for or it doesn't exist then setup the
+ # directory structure that Eric likes to manage things
+ $NEW="1";
+ if ( "$NEW" || ! -f "${CATOP}/serial" ) {
+ # create the directory hierarchy
+ mkdir $CATOP, $DIRMODE;
+ mkdir "${CATOP}/certs", $DIRMODE;
+ mkdir "${CATOP}/crl", $DIRMODE ;
+ mkdir "${CATOP}/newcerts", $DIRMODE;
+ mkdir "${CATOP}/private", $DIRMODE;
+ open OUT, ">${CATOP}/index.txt";
+ close OUT;
+ open OUT, ">${CATOP}/crlnumber";
+ print OUT "01\n";
+ close OUT;
+ }
+ if ( ! -f "${CATOP}/private/$CAKEY" ) {
+ print "CA certificate filename (or enter to create)\n";
+ $FILE = <STDIN>;
+
+ chop $FILE;
+
+ # ask user for existing CA certificate
+ if ($FILE) {
+ cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE");
+ cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE");
+ $RET=$?;
+ } else {
+ print "Making CA certificate ...\n";
+ system ("$REQ -new -keyout " .
+ "${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ");
+ system ("$CA -create_serial " .
+ "-out ${CATOP}/$CACERT $CADAYS -batch " .
+ "-keyfile ${CATOP}/private/$CAKEY -selfsign " .
+ "-extensions v3_ca " .
+ "-infiles ${CATOP}/$CAREQ ");
+ $RET=$?;
+ }
+ }
+ } elsif (/^-pkcs12$/) {
+ my $cname = $ARGV[1];
+ $cname = "My Certificate" unless defined $cname;
+ system ("$PKCS12 -in newcert.pem -inkey newkey.pem " .
+ "-certfile ${CATOP}/$CACERT -out newcert.p12 " .
+ "-export -name \"$cname\"");
+ $RET=$?;
+ print "PKCS #12 file is in newcert.p12\n";
+ exit $RET;
+ } elsif (/^-xsign$/) {
+ system ("$CA -policy policy_anything -infiles newreq.pem");
+ $RET=$?;
+ } elsif (/^(-sign|-signreq)$/) {
+ system ("$CA -policy policy_anything -out newcert.pem " .
+ "-infiles newreq.pem");
+ $RET=$?;
+ print "Signed certificate is in newcert.pem\n";
+ } elsif (/^(-signCA)$/) {
+ system ("$CA -policy policy_anything -out newcert.pem " .
+ "-extensions v3_ca -infiles newreq.pem");
+ $RET=$?;
+ print "Signed CA certificate is in newcert.pem\n";
+ } elsif (/^-signcert$/) {
+ system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " .
+ "-out tmp.pem");
+ system ("$CA -policy policy_anything -out newcert.pem " .
+ "-infiles tmp.pem");
+ $RET = $?;
+ print "Signed certificate is in newcert.pem\n";
+ } elsif (/^-verify$/) {
+ if (shift) {
+ foreach $j (@ARGV) {
+ system ("$VERIFY -CAfile $CATOP/$CACERT $j");
+ $RET=$? if ($? != 0);
+ }
+ exit $RET;
+ } else {
+ system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem");
+ $RET=$?;
+ exit 0;
+ }
+ } else {
+ print STDERR "Unknown arg $_\n";
+ print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
+ exit 1;
+ }
+}
+
+exit $RET;
+
+sub cp_pem {
+my ($infile, $outfile, $bound) = @_;
+open IN, $infile;
+open OUT, ">$outfile";
+my $flag = 0;
+while (<IN>) {
+ $flag = 1 if (/^-----BEGIN.*$bound/) ;
+ print OUT $_ if ($flag);
+ if (/^-----END.*$bound/) {
+ close IN;
+ close OUT;
+ return;
+ }
+}
+}
+
diff --git a/deps/openssl/openssl/apps/CA.pl.in b/deps/openssl/openssl/apps/CA.pl.in
new file mode 100644
index 000000000..c783a6e6a
--- /dev/null
+++ b/deps/openssl/openssl/apps/CA.pl.in
@@ -0,0 +1,189 @@
+#!/usr/local/bin/perl
+#
+# CA - wrapper around ca to make it easier to use ... basically ca requires
+# some setup stuff to be done before you can use it and this makes
+# things easier between now and when Eric is convinced to fix it :-)
+#
+# CA -newca ... will setup the right stuff
+# CA -newreq[-nodes] ... will generate a certificate request
+# CA -sign ... will sign the generated request and output
+#
+# At the end of that grab newreq.pem and newcert.pem (one has the key
+# and the other the certificate) and cat them together and that is what
+# you want/need ... I'll make even this a little cleaner later.
+#
+#
+# 12-Jan-96 tjh Added more things ... including CA -signcert which
+# converts a certificate to a request and then signs it.
+# 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG
+# environment variable so this can be driven from
+# a script.
+# 25-Jul-96 eay Cleaned up filenames some more.
+# 11-Jun-96 eay Fixed a few filename missmatches.
+# 03-May-96 eay Modified to use 'ssleay cmd' instead of 'cmd'.
+# 18-Apr-96 tjh Original hacking
+#
+# Tim Hudson
+# tjh@cryptsoft.com
+#
+
+# 27-Apr-98 snh Translation into perl, fix existing CA bug.
+#
+#
+# Steve Henson
+# shenson@bigfoot.com
+
+# default openssl.cnf file has setup as per the following
+# demoCA ... where everything is stored
+
+my $openssl;
+if(defined $ENV{OPENSSL}) {
+ $openssl = $ENV{OPENSSL};
+} else {
+ $openssl = "openssl";
+ $ENV{OPENSSL} = $openssl;
+}
+
+$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"};
+$DAYS="-days 365"; # 1 year
+$CADAYS="-days 1095"; # 3 years
+$REQ="$openssl req $SSLEAY_CONFIG";
+$CA="$openssl ca $SSLEAY_CONFIG";
+$VERIFY="$openssl verify";
+$X509="$openssl x509";
+$PKCS12="$openssl pkcs12";
+
+$CATOP="./demoCA";
+$CAKEY="cakey.pem";
+$CAREQ="careq.pem";
+$CACERT="cacert.pem";
+
+$DIRMODE = 0777;
+
+$RET = 0;
+
+foreach (@ARGV) {
+ if ( /^(-\?|-h|-help)$/ ) {
+ print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
+ exit 0;
+ } elsif (/^-newcert$/) {
+ # create a certificate
+ system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS");
+ $RET=$?;
+ print "Certificate is in newcert.pem, private key is in newkey.pem\n"
+ } elsif (/^-newreq$/) {
+ # create a certificate request
+ system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS");
+ $RET=$?;
+ print "Request is in newreq.pem, private key is in newkey.pem\n";
+ } elsif (/^-newreq-nodes$/) {
+ # create a certificate request
+ system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS");
+ $RET=$?;
+ print "Request is in newreq.pem, private key is in newkey.pem\n";
+ } elsif (/^-newca$/) {
+ # if explicitly asked for or it doesn't exist then setup the
+ # directory structure that Eric likes to manage things
+ $NEW="1";
+ if ( "$NEW" || ! -f "${CATOP}/serial" ) {
+ # create the directory hierarchy
+ mkdir $CATOP, $DIRMODE;
+ mkdir "${CATOP}/certs", $DIRMODE;
+ mkdir "${CATOP}/crl", $DIRMODE ;
+ mkdir "${CATOP}/newcerts", $DIRMODE;
+ mkdir "${CATOP}/private", $DIRMODE;
+ open OUT, ">${CATOP}/index.txt";
+ close OUT;
+ open OUT, ">${CATOP}/crlnumber";
+ print OUT "01\n";
+ close OUT;
+ }
+ if ( ! -f "${CATOP}/private/$CAKEY" ) {
+ print "CA certificate filename (or enter to create)\n";
+ $FILE = <STDIN>;
+
+ chop $FILE;
+
+ # ask user for existing CA certificate
+ if ($FILE) {
+ cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE");
+ cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE");
+ $RET=$?;
+ } else {
+ print "Making CA certificate ...\n";
+ system ("$REQ -new -keyout " .
+ "${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ");
+ system ("$CA -create_serial " .
+ "-out ${CATOP}/$CACERT $CADAYS -batch " .
+ "-keyfile ${CATOP}/private/$CAKEY -selfsign " .
+ "-extensions v3_ca " .
+ "-infiles ${CATOP}/$CAREQ ");
+ $RET=$?;
+ }
+ }
+ } elsif (/^-pkcs12$/) {
+ my $cname = $ARGV[1];
+ $cname = "My Certificate" unless defined $cname;
+ system ("$PKCS12 -in newcert.pem -inkey newkey.pem " .
+ "-certfile ${CATOP}/$CACERT -out newcert.p12 " .
+ "-export -name \"$cname\"");
+ $RET=$?;
+ print "PKCS #12 file is in newcert.p12\n";
+ exit $RET;
+ } elsif (/^-xsign$/) {
+ system ("$CA -policy policy_anything -infiles newreq.pem");
+ $RET=$?;
+ } elsif (/^(-sign|-signreq)$/) {
+ system ("$CA -policy policy_anything -out newcert.pem " .
+ "-infiles newreq.pem");
+ $RET=$?;
+ print "Signed certificate is in newcert.pem\n";
+ } elsif (/^(-signCA)$/) {
+ system ("$CA -policy policy_anything -out newcert.pem " .
+ "-extensions v3_ca -infiles newreq.pem");
+ $RET=$?;
+ print "Signed CA certificate is in newcert.pem\n";
+ } elsif (/^-signcert$/) {
+ system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " .
+ "-out tmp.pem");
+ system ("$CA -policy policy_anything -out newcert.pem " .
+ "-infiles tmp.pem");
+ $RET = $?;
+ print "Signed certificate is in newcert.pem\n";
+ } elsif (/^-verify$/) {
+ if (shift) {
+ foreach $j (@ARGV) {
+ system ("$VERIFY -CAfile $CATOP/$CACERT $j");
+ $RET=$? if ($? != 0);
+ }
+ exit $RET;
+ } else {
+ system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem");
+ $RET=$?;
+ exit 0;
+ }
+ } else {
+ print STDERR "Unknown arg $_\n";
+ print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
+ exit 1;
+ }
+}
+
+exit $RET;
+
+sub cp_pem {
+my ($infile, $outfile, $bound) = @_;
+open IN, $infile;
+open OUT, ">$outfile";
+my $flag = 0;
+while (<IN>) {
+ $flag = 1 if (/^-----BEGIN.*$bound/) ;
+ print OUT $_ if ($flag);
+ if (/^-----END.*$bound/) {
+ close IN;
+ close OUT;
+ return;
+ }
+}
+}
+
diff --git a/deps/openssl/openssl/apps/CA.sh b/deps/openssl/openssl/apps/CA.sh
new file mode 100644
index 000000000..7ad6b8c52
--- /dev/null
+++ b/deps/openssl/openssl/apps/CA.sh
@@ -0,0 +1,198 @@
+#!/bin/sh
+#
+# CA - wrapper around ca to make it easier to use ... basically ca requires
+# some setup stuff to be done before you can use it and this makes
+# things easier between now and when Eric is convinced to fix it :-)
+#
+# CA -newca ... will setup the right stuff
+# CA -newreq ... will generate a certificate request
+# CA -sign ... will sign the generated request and output
+#
+# At the end of that grab newreq.pem and newcert.pem (one has the key
+# and the other the certificate) and cat them together and that is what
+# you want/need ... I'll make even this a little cleaner later.
+#
+#
+# 12-Jan-96 tjh Added more things ... including CA -signcert which
+# converts a certificate to a request and then signs it.
+# 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG
+# environment variable so this can be driven from
+# a script.
+# 25-Jul-96 eay Cleaned up filenames some more.
+# 11-Jun-96 eay Fixed a few filename missmatches.
+# 03-May-96 eay Modified to use 'ssleay cmd' instead of 'cmd'.
+# 18-Apr-96 tjh Original hacking
+#
+# Tim Hudson
+# tjh@cryptsoft.com
+#
+
+# default openssl.cnf file has setup as per the following
+# demoCA ... where everything is stored
+cp_pem() {
+ infile=$1
+ outfile=$2
+ bound=$3
+ flag=0
+ exec <$infile;
+ while read line; do
+ if [ $flag -eq 1 ]; then
+ echo $line|grep "^-----END.*$bound" 2>/dev/null 1>/dev/null
+ if [ $? -eq 0 ] ; then
+ echo $line >>$outfile
+ break
+ else
+ echo $line >>$outfile
+ fi
+ fi
+
+ echo $line|grep "^-----BEGIN.*$bound" 2>/dev/null 1>/dev/null
+ if [ $? -eq 0 ]; then
+ echo $line >$outfile
+ flag=1
+ fi
+ done
+}
+
+usage() {
+ echo "usage: $0 -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify" >&2
+}
+
+if [ -z "$OPENSSL" ]; then OPENSSL=openssl; fi
+
+if [ -z "$DAYS" ] ; then DAYS="-days 365" ; fi # 1 year
+CADAYS="-days 1095" # 3 years
+REQ="$OPENSSL req $SSLEAY_CONFIG"
+CA="$OPENSSL ca $SSLEAY_CONFIG"
+VERIFY="$OPENSSL verify"
+X509="$OPENSSL x509"
+PKCS12="openssl pkcs12"
+
+if [ -z "$CATOP" ] ; then CATOP=./demoCA ; fi
+CAKEY=./cakey.pem
+CAREQ=./careq.pem
+CACERT=./cacert.pem
+
+RET=0
+
+while [ "$1" != "" ] ; do
+case $1 in
+-\?|-h|-help)
+ usage
+ exit 0
+ ;;
+-newcert)
+ # create a certificate
+ $REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS
+ RET=$?
+ echo "Certificate is in newcert.pem, private key is in newkey.pem"
+ ;;
+-newreq)
+ # create a certificate request
+ $REQ -new -keyout newkey.pem -out newreq.pem $DAYS
+ RET=$?
+ echo "Request is in newreq.pem, private key is in newkey.pem"
+ ;;
+-newreq-nodes)
+ # create a certificate request
+ $REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS
+ RET=$?
+ echo "Request (and private key) is in newreq.pem"
+ ;;
+-newca)
+ # if explicitly asked for or it doesn't exist then setup the directory
+ # structure that Eric likes to manage things
+ NEW="1"
+ if [ "$NEW" -o ! -f ${CATOP}/serial ]; then
+ # create the directory hierarchy
+ mkdir -p ${CATOP}
+ mkdir -p ${CATOP}/certs
+ mkdir -p ${CATOP}/crl
+ mkdir -p ${CATOP}/newcerts
+ mkdir -p ${CATOP}/private
+ touch ${CATOP}/index.txt
+ fi
+ if [ ! -f ${CATOP}/private/$CAKEY ]; then
+ echo "CA certificate filename (or enter to create)"
+ read FILE
+
+ # ask user for existing CA certificate
+ if [ "$FILE" ]; then
+ cp_pem $FILE ${CATOP}/private/$CAKEY PRIVATE
+ cp_pem $FILE ${CATOP}/$CACERT CERTIFICATE
+ RET=$?
+ if [ ! -f "${CATOP}/serial" ]; then
+ $X509 -in ${CATOP}/$CACERT -noout -next_serial \
+ -out ${CATOP}/serial
+ fi
+ else
+ echo "Making CA certificate ..."
+ $REQ -new -keyout ${CATOP}/private/$CAKEY \
+ -out ${CATOP}/$CAREQ
+ $CA -create_serial -out ${CATOP}/$CACERT $CADAYS -batch \
+ -keyfile ${CATOP}/private/$CAKEY -selfsign \
+ -extensions v3_ca \
+ -infiles ${CATOP}/$CAREQ
+ RET=$?
+ fi
+ fi
+ ;;
+-xsign)
+ $CA -policy policy_anything -infiles newreq.pem
+ RET=$?
+ ;;
+-pkcs12)
+ if [ -z "$2" ] ; then
+ CNAME="My Certificate"
+ else
+ CNAME="$2"
+ fi
+ $PKCS12 -in newcert.pem -inkey newreq.pem -certfile ${CATOP}/$CACERT \
+ -out newcert.p12 -export -name "$CNAME"
+ RET=$?
+ exit $RET
+ ;;
+-sign|-signreq)
+ $CA -policy policy_anything -out newcert.pem -infiles newreq.pem
+ RET=$?
+ cat newcert.pem
+ echo "Signed certificate is in newcert.pem"
+ ;;
+-signCA)
+ $CA -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem
+ RET=$?
+ echo "Signed CA certificate is in newcert.pem"
+ ;;
+-signcert)
+ echo "Cert passphrase will be requested twice - bug?"
+ $X509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem
+ $CA -policy policy_anything -out newcert.pem -infiles tmp.pem
+ RET=$?
+ cat newcert.pem
+ echo "Signed certificate is in newcert.pem"
+ ;;
+-verify)
+ shift
+ if [ -z "$1" ]; then
+ $VERIFY -CAfile $CATOP/$CACERT newcert.pem
+ RET=$?
+ else
+ for j
+ do
+ $VERIFY -CAfile $CATOP/$CACERT $j
+ if [ $? != 0 ]; then
+ RET=$?
+ fi
+ done
+ fi
+ exit $RET
+ ;;
+*)
+ echo "Unknown arg $i" >&2
+ usage
+ exit 1
+ ;;
+esac
+shift
+done
+exit $RET
diff --git a/deps/openssl/openssl/apps/Makefile b/deps/openssl/openssl/apps/Makefile
new file mode 100644
index 000000000..95f499e33
--- /dev/null
+++ b/deps/openssl/openssl/apps/Makefile
@@ -0,0 +1,1055 @@
+#
+# apps/Makefile
+#
+
+DIR= apps
+TOP= ..
+CC= cc
+INCLUDES= -I$(TOP) -I../include $(KRB5_INCLUDES)
+CFLAG= -g -static
+MAKEFILE= Makefile
+PERL= perl
+RM= rm -f
+# KRB5 stuff
+KRB5_INCLUDES=
+LIBKRB5=
+
+PEX_LIBS=
+EX_LIBS=
+EXE_EXT=
+
+SHLIB_TARGET=
+
+CFLAGS= -DMONOLITH $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile makeapps.com install.com
+
+DLIBCRYPTO=../libcrypto.a
+DLIBSSL=../libssl.a
+LIBCRYPTO=-L.. -lcrypto
+LIBSSL=-L.. -lssl
+
+PROGRAM= openssl
+
+SCRIPTS=CA.sh CA.pl tsget
+
+EXE= $(PROGRAM)$(EXE_EXT)
+
+E_EXE= verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
+ ca crl rsa rsautl dsa dsaparam ec ecparam \
+ x509 genrsa gendsa genpkey s_server s_client speed \
+ s_time version pkcs7 cms crl2pkcs7 sess_id ciphers nseq pkcs12 \
+ pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts srp
+
+PROGS= $(PROGRAM).c
+
+A_OBJ=apps.o
+A_SRC=apps.c
+S_OBJ= s_cb.o s_socket.o
+S_SRC= s_cb.c s_socket.c
+RAND_OBJ=app_rand.o
+RAND_SRC=app_rand.c
+
+E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o \
+ ca.o pkcs7.o crl2p7.o crl.o \
+ rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o \
+ x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o \
+ s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
+ ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o \
+ spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o
+
+E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
+ pkcs7.c crl2p7.c crl.c \
+ rsa.c rsautl.c dsa.c dsaparam.c ec.c ecparam.c \
+ x509.c genrsa.c gendsa.c genpkey.c s_server.c s_client.c speed.c \
+ s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
+ ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c pkeyparam.c pkeyutl.c \
+ spkac.c smime.c cms.c rand.c engine.c ocsp.c prime.c ts.c srp.c
+
+SRC=$(E_SRC)
+
+EXHEADER=
+HEADER= apps.h progs.h s_apps.h \
+ testdsa.h testrsa.h \
+ $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ @(cd ..; $(MAKE) DIRS=$(DIR) all)
+
+all: exe
+
+exe: $(EXE)
+
+req: sreq.o $(A_OBJ) $(DLIBCRYPTO)
+ shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
+ shlib_target="$(SHLIB_TARGET)"; \
+ fi; \
+ $(MAKE) -f $(TOP)/Makefile.shared -e \
+ APPNAME=req OBJECTS="sreq.o $(A_OBJ) $(RAND_OBJ)" \
+ LIBDEPS="$(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS)" \
+ link_app.$${shlib_target}
+
+sreq.o: req.c
+ $(CC) -c $(INCLUDES) $(CFLAG) -o sreq.o req.c
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+install:
+ @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+ @set -e; for i in $(EXE); \
+ do \
+ (echo installing $$i; \
+ cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+ chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
+ done;
+ @set -e; for i in $(SCRIPTS); \
+ do \
+ (echo installing $$i; \
+ cp $$i $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
+ chmod 755 $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
+ mv -f $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i ); \
+ done
+ @cp openssl.cnf $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
+ chmod 644 $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
+ mv -f $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+links:
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ @if [ -z "$(THIS)" ]; then \
+ $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
+ else \
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(SRC); \
+ fi
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+ rm -f CA.pl
+
+clean:
+ rm -f *.o *.obj *.dll lib tags core .pure .nfs* *.old *.bak fluff $(EXE)
+ rm -f req
+
+$(DLIBSSL):
+ (cd ..; $(MAKE) DIRS=ssl all)
+
+$(DLIBCRYPTO):
+ (cd ..; $(MAKE) DIRS=crypto all)
+
+$(EXE): progs.h $(E_OBJ) $(PROGRAM).o $(DLIBCRYPTO) $(DLIBSSL)
+ $(RM) $(EXE)
+ shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
+ shlib_target="$(SHLIB_TARGET)"; \
+ elif [ -n "$(FIPSCANLIB)" ]; then \
+ FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; export CC FIPSLD_CC; \
+ fi; \
+ LIBRARIES="$(LIBSSL) $(LIBKRB5) $(LIBCRYPTO)" ; \
+ $(MAKE) -f $(TOP)/Makefile.shared -e \
+ APPNAME=$(EXE) OBJECTS="$(PROGRAM).o $(E_OBJ)" \
+ LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
+ link_app.$${shlib_target}
+ @(cd ..; $(MAKE) rehash)
+
+progs.h: progs.pl
+ $(PERL) progs.pl $(E_EXE) >progs.h
+ $(RM) $(PROGRAM).o
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+app_rand.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+app_rand.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+app_rand.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+app_rand.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+app_rand.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+app_rand.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+app_rand.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+app_rand.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+app_rand.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+app_rand.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+app_rand.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+app_rand.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+app_rand.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+app_rand.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h
+app_rand.o: app_rand.c apps.h
+apps.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+apps.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+apps.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+apps.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+apps.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+apps.o: ../include/openssl/engine.h ../include/openssl/err.h
+apps.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+apps.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+apps.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+apps.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+apps.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+apps.o: ../include/openssl/pkcs12.h ../include/openssl/pkcs7.h
+apps.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+apps.o: ../include/openssl/sha.h ../include/openssl/stack.h
+apps.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+apps.o: ../include/openssl/ui.h ../include/openssl/x509.h
+apps.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.c apps.h
+asn1pars.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+asn1pars.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+asn1pars.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+asn1pars.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+asn1pars.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+asn1pars.o: ../include/openssl/err.h ../include/openssl/evp.h
+asn1pars.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+asn1pars.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+asn1pars.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+asn1pars.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+asn1pars.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+asn1pars.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+asn1pars.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+asn1pars.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+asn1pars.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+asn1pars.o: asn1pars.c
+ca.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ca.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ca.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ca.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ca.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ca.o: ../include/openssl/engine.h ../include/openssl/err.h
+ca.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+ca.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ca.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+ca.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ca.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ca.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+ca.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ca.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+ca.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ca.o: ../include/openssl/x509v3.h apps.h ca.c
+ciphers.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ciphers.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ciphers.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ciphers.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ciphers.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ciphers.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ciphers.o: ../include/openssl/err.h ../include/openssl/evp.h
+ciphers.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ciphers.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ciphers.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+ciphers.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ciphers.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ciphers.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ciphers.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+ciphers.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+ciphers.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ciphers.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ciphers.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ciphers.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+ciphers.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ciphers.o: ../include/openssl/x509v3.h apps.h ciphers.c
+cms.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+cms.o: ../include/openssl/buffer.h ../include/openssl/cms.h
+cms.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+cms.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+cms.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+cms.o: ../include/openssl/engine.h ../include/openssl/err.h
+cms.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+cms.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+cms.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+cms.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+cms.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+cms.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+cms.o: ../include/openssl/sha.h ../include/openssl/stack.h
+cms.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+cms.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+cms.o: ../include/openssl/x509v3.h apps.h cms.c
+crl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+crl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+crl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+crl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+crl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+crl.o: ../include/openssl/err.h ../include/openssl/evp.h
+crl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+crl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+crl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+crl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+crl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+crl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+crl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+crl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+crl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h crl.c
+crl2p7.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+crl2p7.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+crl2p7.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+crl2p7.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+crl2p7.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+crl2p7.o: ../include/openssl/err.h ../include/openssl/evp.h
+crl2p7.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+crl2p7.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+crl2p7.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+crl2p7.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+crl2p7.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+crl2p7.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+crl2p7.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+crl2p7.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+crl2p7.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+crl2p7.o: crl2p7.c
+dgst.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+dgst.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+dgst.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+dgst.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+dgst.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+dgst.o: ../include/openssl/err.h ../include/openssl/evp.h
+dgst.o: ../include/openssl/hmac.h ../include/openssl/lhash.h
+dgst.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+dgst.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+dgst.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+dgst.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+dgst.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+dgst.o: ../include/openssl/sha.h ../include/openssl/stack.h
+dgst.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+dgst.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+dgst.o: ../include/openssl/x509v3.h apps.h dgst.c
+dh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+dh.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+dh.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+dh.o: ../include/openssl/dh.h ../include/openssl/e_os2.h
+dh.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+dh.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+dh.o: ../include/openssl/err.h ../include/openssl/evp.h
+dh.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+dh.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+dh.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+dh.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+dh.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+dh.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+dh.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+dh.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+dh.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dh.c
+dsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+dsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+dsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+dsa.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+dsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+dsa.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+dsa.o: ../include/openssl/err.h ../include/openssl/evp.h
+dsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+dsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+dsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+dsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+dsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+dsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+dsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+dsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+dsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dsa.c
+dsaparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+dsaparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+dsaparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+dsaparam.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+dsaparam.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+dsaparam.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+dsaparam.o: ../include/openssl/engine.h ../include/openssl/err.h
+dsaparam.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+dsaparam.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+dsaparam.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+dsaparam.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+dsaparam.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+dsaparam.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+dsaparam.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+dsaparam.o: ../include/openssl/sha.h ../include/openssl/stack.h
+dsaparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+dsaparam.o: ../include/openssl/ui.h ../include/openssl/x509.h
+dsaparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+dsaparam.o: dsaparam.c
+ec.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ec.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+ec.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+ec.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ec.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ec.o: ../include/openssl/err.h ../include/openssl/evp.h
+ec.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ec.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+ec.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ec.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ec.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ec.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ec.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ec.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+ec.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ec.c
+ecparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ecparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ecparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ecparam.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ecparam.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ecparam.o: ../include/openssl/engine.h ../include/openssl/err.h
+ecparam.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+ecparam.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ecparam.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+ecparam.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ecparam.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ecparam.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+ecparam.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ecparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+ecparam.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ecparam.o: ../include/openssl/x509v3.h apps.h ecparam.c
+enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+enc.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+enc.o: ../include/openssl/engine.h ../include/openssl/err.h
+enc.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+enc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+enc.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+enc.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+enc.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+enc.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h enc.c
+engine.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+engine.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+engine.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+engine.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+engine.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+engine.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+engine.o: ../include/openssl/err.h ../include/openssl/evp.h
+engine.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+engine.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+engine.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+engine.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+engine.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+engine.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+engine.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+engine.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+engine.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+engine.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+engine.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+engine.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+engine.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+engine.o: ../include/openssl/x509v3.h apps.h engine.c
+errstr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+errstr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+errstr.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+errstr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+errstr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+errstr.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+errstr.o: ../include/openssl/err.h ../include/openssl/evp.h
+errstr.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+errstr.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+errstr.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+errstr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+errstr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+errstr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+errstr.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+errstr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+errstr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+errstr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+errstr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+errstr.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+errstr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+errstr.o: ../include/openssl/x509v3.h apps.h errstr.c
+gendh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+gendh.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+gendh.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+gendh.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+gendh.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+gendh.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+gendh.o: ../include/openssl/engine.h ../include/openssl/err.h
+gendh.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+gendh.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+gendh.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+gendh.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+gendh.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+gendh.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+gendh.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+gendh.o: ../include/openssl/sha.h ../include/openssl/stack.h
+gendh.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+gendh.o: ../include/openssl/ui.h ../include/openssl/x509.h
+gendh.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+gendh.o: gendh.c
+gendsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+gendsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+gendsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+gendsa.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+gendsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+gendsa.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+gendsa.o: ../include/openssl/err.h ../include/openssl/evp.h
+gendsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+gendsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+gendsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+gendsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+gendsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+gendsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+gendsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+gendsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+gendsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+gendsa.o: gendsa.c
+genpkey.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+genpkey.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+genpkey.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+genpkey.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+genpkey.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+genpkey.o: ../include/openssl/err.h ../include/openssl/evp.h
+genpkey.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+genpkey.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+genpkey.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+genpkey.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+genpkey.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+genpkey.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+genpkey.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+genpkey.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+genpkey.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+genpkey.o: genpkey.c
+genrsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+genrsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+genrsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+genrsa.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+genrsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+genrsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+genrsa.o: ../include/openssl/engine.h ../include/openssl/err.h
+genrsa.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+genrsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+genrsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+genrsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+genrsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+genrsa.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+genrsa.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+genrsa.o: ../include/openssl/sha.h ../include/openssl/stack.h
+genrsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+genrsa.o: ../include/openssl/ui.h ../include/openssl/x509.h
+genrsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+genrsa.o: genrsa.c
+nseq.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+nseq.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+nseq.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+nseq.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+nseq.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+nseq.o: ../include/openssl/err.h ../include/openssl/evp.h
+nseq.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+nseq.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+nseq.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+nseq.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+nseq.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+nseq.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+nseq.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+nseq.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+nseq.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h nseq.c
+ocsp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ocsp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ocsp.o: ../include/openssl/comp.h ../include/openssl/conf.h
+ocsp.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+ocsp.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ocsp.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ocsp.o: ../include/openssl/engine.h ../include/openssl/err.h
+ocsp.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ocsp.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ocsp.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ocsp.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+ocsp.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ocsp.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ocsp.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+ocsp.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ocsp.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ocsp.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ocsp.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ocsp.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ocsp.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+ocsp.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ocsp.c
+openssl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+openssl.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+openssl.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+openssl.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+openssl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+openssl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+openssl.o: ../include/openssl/err.h ../include/openssl/evp.h
+openssl.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+openssl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+openssl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+openssl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+openssl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+openssl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+openssl.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+openssl.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+openssl.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+openssl.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+openssl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+openssl.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+openssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+openssl.o: ../include/openssl/x509v3.h apps.h openssl.c progs.h s_apps.h
+passwd.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+passwd.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+passwd.o: ../include/openssl/crypto.h ../include/openssl/des.h
+passwd.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
+passwd.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+passwd.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+passwd.o: ../include/openssl/err.h ../include/openssl/evp.h
+passwd.o: ../include/openssl/lhash.h ../include/openssl/md5.h
+passwd.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+passwd.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+passwd.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+passwd.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+passwd.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+passwd.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+passwd.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
+passwd.o: ../include/openssl/ui_compat.h ../include/openssl/x509.h
+passwd.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+passwd.o: passwd.c
+pkcs12.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkcs12.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkcs12.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkcs12.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkcs12.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkcs12.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkcs12.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkcs12.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkcs12.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkcs12.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkcs12.o: ../include/openssl/pem2.h ../include/openssl/pkcs12.h
+pkcs12.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+pkcs12.o: ../include/openssl/sha.h ../include/openssl/stack.h
+pkcs12.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+pkcs12.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+pkcs12.o: ../include/openssl/x509v3.h apps.h pkcs12.c
+pkcs7.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkcs7.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkcs7.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkcs7.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkcs7.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkcs7.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkcs7.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkcs7.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkcs7.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkcs7.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkcs7.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+pkcs7.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+pkcs7.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+pkcs7.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+pkcs7.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+pkcs7.o: pkcs7.c
+pkcs8.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkcs8.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkcs8.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkcs8.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkcs8.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkcs8.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkcs8.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkcs8.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkcs8.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkcs8.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkcs8.o: ../include/openssl/pem2.h ../include/openssl/pkcs12.h
+pkcs8.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+pkcs8.o: ../include/openssl/sha.h ../include/openssl/stack.h
+pkcs8.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+pkcs8.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+pkcs8.o: ../include/openssl/x509v3.h apps.h pkcs8.c
+pkey.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkey.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkey.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkey.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkey.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkey.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkey.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkey.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkey.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkey.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkey.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+pkey.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+pkey.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+pkey.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+pkey.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h pkey.c
+pkeyparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkeyparam.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkeyparam.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkeyparam.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkeyparam.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkeyparam.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkeyparam.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkeyparam.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkeyparam.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkeyparam.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkeyparam.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+pkeyparam.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+pkeyparam.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+pkeyparam.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+pkeyparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+pkeyparam.o: pkeyparam.c
+pkeyutl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkeyutl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkeyutl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkeyutl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkeyutl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkeyutl.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkeyutl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkeyutl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkeyutl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkeyutl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkeyutl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+pkeyutl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+pkeyutl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+pkeyutl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+pkeyutl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+pkeyutl.o: pkeyutl.c
+prime.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+prime.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+prime.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+prime.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+prime.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+prime.o: ../include/openssl/engine.h ../include/openssl/evp.h
+prime.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+prime.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+prime.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+prime.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+prime.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+prime.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+prime.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+prime.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+prime.o: prime.c
+rand.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+rand.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+rand.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+rand.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+rand.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+rand.o: ../include/openssl/err.h ../include/openssl/evp.h
+rand.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+rand.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+rand.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+rand.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+rand.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+rand.o: ../include/openssl/sha.h ../include/openssl/stack.h
+rand.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+rand.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+rand.o: ../include/openssl/x509v3.h apps.h rand.c
+req.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+req.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+req.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+req.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+req.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+req.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+req.o: ../include/openssl/engine.h ../include/openssl/err.h
+req.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+req.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+req.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+req.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+req.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+req.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+req.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+req.o: ../include/openssl/sha.h ../include/openssl/stack.h
+req.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+req.o: ../include/openssl/ui.h ../include/openssl/x509.h
+req.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h req.c
+rsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+rsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+rsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+rsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+rsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+rsa.o: ../include/openssl/engine.h ../include/openssl/err.h
+rsa.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+rsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+rsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+rsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+rsa.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+rsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+rsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+rsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+rsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h rsa.c
+rsautl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+rsautl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+rsautl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+rsautl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+rsautl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+rsautl.o: ../include/openssl/err.h ../include/openssl/evp.h
+rsautl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+rsautl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+rsautl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+rsautl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+rsautl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+rsautl.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+rsautl.o: ../include/openssl/sha.h ../include/openssl/stack.h
+rsautl.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+rsautl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+rsautl.o: ../include/openssl/x509v3.h apps.h rsautl.c
+s_cb.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s_cb.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s_cb.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+s_cb.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s_cb.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s_cb.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+s_cb.o: ../include/openssl/err.h ../include/openssl/evp.h
+s_cb.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s_cb.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+s_cb.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+s_cb.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s_cb.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s_cb.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s_cb.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s_cb.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s_cb.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s_cb.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s_cb.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s_cb.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s_cb.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+s_cb.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+s_cb.o: s_apps.h s_cb.c
+s_client.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s_client.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+s_client.o: ../include/openssl/comp.h ../include/openssl/conf.h
+s_client.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+s_client.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s_client.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s_client.o: ../include/openssl/engine.h ../include/openssl/err.h
+s_client.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s_client.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s_client.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s_client.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+s_client.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+s_client.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+s_client.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+s_client.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+s_client.o: ../include/openssl/sha.h ../include/openssl/srp.h
+s_client.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s_client.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s_client.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s_client.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s_client.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+s_client.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+s_client.o: s_apps.h s_client.c timeouts.h
+s_server.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s_server.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+s_server.o: ../include/openssl/comp.h ../include/openssl/conf.h
+s_server.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+s_server.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+s_server.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s_server.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s_server.o: ../include/openssl/engine.h ../include/openssl/err.h
+s_server.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s_server.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s_server.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s_server.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+s_server.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+s_server.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+s_server.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+s_server.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+s_server.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s_server.o: ../include/openssl/srp.h ../include/openssl/srtp.h
+s_server.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s_server.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s_server.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s_server.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+s_server.o: ../include/openssl/ui.h ../include/openssl/x509.h
+s_server.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+s_server.o: s_apps.h s_server.c timeouts.h
+s_socket.o: ../e_os.h ../e_os2.h ../include/openssl/asn1.h
+s_socket.o: ../include/openssl/bio.h ../include/openssl/buffer.h
+s_socket.o: ../include/openssl/comp.h ../include/openssl/conf.h
+s_socket.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+s_socket.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s_socket.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s_socket.o: ../include/openssl/engine.h ../include/openssl/evp.h
+s_socket.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s_socket.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+s_socket.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+s_socket.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s_socket.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s_socket.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s_socket.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+s_socket.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s_socket.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s_socket.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s_socket.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s_socket.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+s_socket.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+s_socket.o: ../include/openssl/x509v3.h apps.h s_apps.h s_socket.c
+s_time.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s_time.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s_time.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+s_time.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s_time.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s_time.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+s_time.o: ../include/openssl/err.h ../include/openssl/evp.h
+s_time.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s_time.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+s_time.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+s_time.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s_time.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s_time.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s_time.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+s_time.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s_time.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s_time.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s_time.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s_time.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+s_time.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+s_time.o: ../include/openssl/x509v3.h apps.h s_apps.h s_time.c
+sess_id.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+sess_id.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+sess_id.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+sess_id.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+sess_id.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+sess_id.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+sess_id.o: ../include/openssl/err.h ../include/openssl/evp.h
+sess_id.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+sess_id.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+sess_id.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+sess_id.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+sess_id.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+sess_id.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+sess_id.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+sess_id.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+sess_id.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+sess_id.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+sess_id.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+sess_id.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+sess_id.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+sess_id.o: ../include/openssl/x509v3.h apps.h sess_id.c
+smime.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+smime.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+smime.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+smime.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+smime.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+smime.o: ../include/openssl/err.h ../include/openssl/evp.h
+smime.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+smime.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+smime.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+smime.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+smime.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+smime.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+smime.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+smime.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+smime.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+smime.o: smime.c
+speed.o: ../e_os.h ../include/openssl/aes.h ../include/openssl/asn1.h
+speed.o: ../include/openssl/bio.h ../include/openssl/blowfish.h
+speed.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+speed.o: ../include/openssl/camellia.h ../include/openssl/cast.h
+speed.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+speed.o: ../include/openssl/des.h ../include/openssl/des_old.h
+speed.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+speed.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+speed.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+speed.o: ../include/openssl/err.h ../include/openssl/evp.h
+speed.o: ../include/openssl/hmac.h ../include/openssl/idea.h
+speed.o: ../include/openssl/lhash.h ../include/openssl/md4.h
+speed.o: ../include/openssl/md5.h ../include/openssl/mdc2.h
+speed.o: ../include/openssl/modes.h ../include/openssl/obj_mac.h
+speed.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+speed.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+speed.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+speed.o: ../include/openssl/rand.h ../include/openssl/rc2.h
+speed.o: ../include/openssl/rc4.h ../include/openssl/ripemd.h
+speed.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+speed.o: ../include/openssl/seed.h ../include/openssl/sha.h
+speed.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+speed.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
+speed.o: ../include/openssl/ui_compat.h ../include/openssl/whrlpool.h
+speed.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+speed.o: ../include/openssl/x509v3.h apps.h speed.c testdsa.h testrsa.h
+spkac.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+spkac.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+spkac.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+spkac.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+spkac.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+spkac.o: ../include/openssl/err.h ../include/openssl/evp.h
+spkac.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+spkac.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+spkac.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+spkac.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+spkac.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+spkac.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+spkac.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+spkac.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+spkac.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+spkac.o: spkac.c
+srp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+srp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+srp.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+srp.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+srp.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+srp.o: ../include/openssl/engine.h ../include/openssl/err.h
+srp.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+srp.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+srp.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+srp.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+srp.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+srp.o: ../include/openssl/sha.h ../include/openssl/srp.h
+srp.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+srp.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+srp.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h srp.c
+ts.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ts.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ts.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ts.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+ts.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ts.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ts.o: ../include/openssl/engine.h ../include/openssl/err.h
+ts.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+ts.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ts.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+ts.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ts.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ts.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+ts.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ts.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ts.o: ../include/openssl/symhacks.h ../include/openssl/ts.h
+ts.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+ts.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ts.c
+verify.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+verify.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+verify.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+verify.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+verify.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+verify.o: ../include/openssl/err.h ../include/openssl/evp.h
+verify.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+verify.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+verify.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+verify.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+verify.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+verify.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+verify.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+verify.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+verify.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+verify.o: verify.c
+version.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+version.o: ../include/openssl/blowfish.h ../include/openssl/bn.h
+version.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+version.o: ../include/openssl/crypto.h ../include/openssl/des.h
+version.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
+version.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+version.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+version.o: ../include/openssl/evp.h ../include/openssl/idea.h
+version.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+version.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+version.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+version.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+version.o: ../include/openssl/rc4.h ../include/openssl/safestack.h
+version.o: ../include/openssl/sha.h ../include/openssl/stack.h
+version.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+version.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
+version.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+version.o: ../include/openssl/x509v3.h apps.h version.c
+x509.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+x509.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+x509.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+x509.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+x509.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+x509.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+x509.o: ../include/openssl/err.h ../include/openssl/evp.h
+x509.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+x509.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+x509.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+x509.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+x509.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+x509.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+x509.o: ../include/openssl/sha.h ../include/openssl/stack.h
+x509.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+x509.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+x509.o: ../include/openssl/x509v3.h apps.h x509.c
diff --git a/deps/openssl/openssl/apps/app_rand.c b/deps/openssl/openssl/apps/app_rand.c
new file mode 100644
index 000000000..b7b6128c1
--- /dev/null
+++ b/deps/openssl/openssl/apps/app_rand.c
@@ -0,0 +1,218 @@
+/* apps/app_rand.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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).
+ *
+ */
+
+#define NON_MAIN
+#include "apps.h"
+#undef NON_MAIN
+#include <openssl/bio.h>
+#include <openssl/rand.h>
+
+
+static int seeded = 0;
+static int egdsocket = 0;
+
+int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn)
+ {
+ int consider_randfile = (file == NULL);
+ char buffer[200];
+
+#ifdef OPENSSL_SYS_WINDOWS
+ BIO_printf(bio_e,"Loading 'screen' into random state -");
+ BIO_flush(bio_e);
+ RAND_screen();
+ BIO_printf(bio_e," done\n");
+#endif
+
+ if (file == NULL)
+ file = RAND_file_name(buffer, sizeof buffer);
+ else if (RAND_egd(file) > 0)
+ {
+ /* we try if the given filename is an EGD socket.
+ if it is, we don't write anything back to the file. */
+ egdsocket = 1;
+ return 1;
+ }
+ if (file == NULL || !RAND_load_file(file, -1))
+ {
+ if (RAND_status() == 0)
+ {
+ if (!dont_warn)
+ {
+ BIO_printf(bio_e,"unable to load 'random state'\n");
+ BIO_printf(bio_e,"This means that the random number generator has not been seeded\n");
+ BIO_printf(bio_e,"with much random data.\n");
+ if (consider_randfile) /* explanation does not apply when a file is explicitly named */
+ {
+ BIO_printf(bio_e,"Consider setting the RANDFILE environment variable to point at a file that\n");
+ BIO_printf(bio_e,"'random' data can be kept in (the file will be overwritten).\n");
+ }
+ }
+ return 0;
+ }
+ }
+ seeded = 1;
+ return 1;
+ }
+
+long app_RAND_load_files(char *name)
+ {
+ char *p,*n;
+ int last;
+ long tot=0;
+ int egd;
+
+ for (;;)
+ {
+ last=0;
+ for (p=name; ((*p != '\0') && (*p != LIST_SEPARATOR_CHAR)); p++);
+ if (*p == '\0') last=1;
+ *p='\0';
+ n=name;
+ name=p+1;
+ if (*n == '\0') break;
+
+ egd=RAND_egd(n);
+ if (egd > 0)
+ tot+=egd;
+ else
+ tot+=RAND_load_file(n,-1);
+ if (last) break;
+ }
+ if (tot > 512)
+ app_RAND_allow_write_file();
+ return(tot);
+ }
+
+int app_RAND_write_file(const char *file, BIO *bio_e)
+ {
+ char buffer[200];
+
+ if (egdsocket || !seeded)
+ /* If we did not manage to read the seed file,
+ * we should not write a low-entropy seed file back --
+ * it would suppress a crucial warning the next time
+ * we want to use it. */
+ return 0;
+
+ if (file == NULL)
+ file = RAND_file_name(buffer, sizeof buffer);
+ if (file == NULL || !RAND_write_file(file))
+ {
+ BIO_printf(bio_e,"unable to write 'random state'\n");
+ return 0;
+ }
+ return 1;
+ }
+
+void app_RAND_allow_write_file(void)
+ {
+ seeded = 1;
+ }
diff --git a/deps/openssl/openssl/apps/apps.c b/deps/openssl/openssl/apps/apps.c
new file mode 100644
index 000000000..1096eee4c
--- /dev/null
+++ b/deps/openssl/openssl/apps/apps.c
@@ -0,0 +1,3094 @@
+/* apps/apps.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+
+#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
+#define _POSIX_C_SOURCE 2 /* On VMS, you need to define this to get
+ the declaration of fileno(). The value
+ 2 is to make sure no function defined
+ in POSIX-2 is left undefined. */
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(OPENSSL_SYSNAME_WIN32) && !defined(NETWARE_CLIB)
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#include <ctype.h>
+#include <errno.h>
+#include <assert.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include <openssl/ui.h>
+#include <openssl/safestack.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_JPAKE
+#include <openssl/jpake.h>
+#endif
+
+#define NON_MAIN
+#include "apps.h"
+#undef NON_MAIN
+
+#ifdef _WIN32
+static int WIN32_rename(const char *from, const char *to);
+#define rename(from,to) WIN32_rename((from),(to))
+#endif
+
+typedef struct {
+ const char *name;
+ unsigned long flag;
+ unsigned long mask;
+} NAME_EX_TBL;
+
+static UI_METHOD *ui_method = NULL;
+
+static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
+static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
+
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
+/* Looks like this stuff is worth moving into separate function */
+static EVP_PKEY *
+load_netscape_key(BIO *err, BIO *key, const char *file,
+ const char *key_descrip, int format);
+#endif
+
+int app_init(long mesgwin);
+#ifdef undef /* never finished - probably never will be :-) */
+int args_from_file(char *file, int *argc, char **argv[])
+ {
+ FILE *fp;
+ int num,i;
+ unsigned int len;
+ static char *buf=NULL;
+ static char **arg=NULL;
+ char *p;
+
+ fp=fopen(file,"r");
+ if (fp == NULL)
+ return(0);
+
+ if (fseek(fp,0,SEEK_END)==0)
+ len=ftell(fp), rewind(fp);
+ else len=-1;
+ if (len<=0)
+ {
+ fclose(fp);
+ return(0);
+ }
+
+ *argc=0;
+ *argv=NULL;
+
+ if (buf != NULL) OPENSSL_free(buf);
+ buf=(char *)OPENSSL_malloc(len+1);
+ if (buf == NULL) return(0);
+
+ len=fread(buf,1,len,fp);
+ if (len <= 1) return(0);
+ buf[len]='\0';
+
+ i=0;
+ for (p=buf; *p; p++)
+ if (*p == '\n') i++;
+ if (arg != NULL) OPENSSL_free(arg);
+ arg=(char **)OPENSSL_malloc(sizeof(char *)*(i*2));
+
+ *argv=arg;
+ num=0;
+ p=buf;
+ for (;;)
+ {
+ if (!*p) break;
+ if (*p == '#') /* comment line */
+ {
+ while (*p && (*p != '\n')) p++;
+ continue;
+ }
+ /* else we have a line */
+ *(arg++)=p;
+ num++;
+ while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
+ p++;
+ if (!*p) break;
+ if (*p == '\n')
+ {
+ *(p++)='\0';
+ continue;
+ }
+ /* else it is a tab or space */
+ p++;
+ while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
+ p++;
+ if (!*p) break;
+ if (*p == '\n')
+ {
+ p++;
+ continue;
+ }
+ *(arg++)=p++;
+ num++;
+ while (*p && (*p != '\n')) p++;
+ if (!*p) break;
+ /* else *p == '\n' */
+ *(p++)='\0';
+ }
+ *argc=num;
+ return(1);
+ }
+#endif
+
+int str2fmt(char *s)
+ {
+ if (s == NULL)
+ return FORMAT_UNDEF;
+ if ((*s == 'D') || (*s == 'd'))
+ return(FORMAT_ASN1);
+ else if ((*s == 'T') || (*s == 't'))
+ return(FORMAT_TEXT);
+ else if ((*s == 'N') || (*s == 'n'))
+ return(FORMAT_NETSCAPE);
+ else if ((*s == 'S') || (*s == 's'))
+ return(FORMAT_SMIME);
+ else if ((*s == 'M') || (*s == 'm'))
+ return(FORMAT_MSBLOB);
+ else if ((*s == '1')
+ || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
+ || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
+ return(FORMAT_PKCS12);
+ else if ((*s == 'E') || (*s == 'e'))
+ return(FORMAT_ENGINE);
+ else if ((*s == 'P') || (*s == 'p'))
+ {
+ if (s[1] == 'V' || s[1] == 'v')
+ return FORMAT_PVK;
+ else
+ return(FORMAT_PEM);
+ }
+ else
+ return(FORMAT_UNDEF);
+ }
+
+#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE)
+void program_name(char *in, char *out, int size)
+ {
+ int i,n;
+ char *p=NULL;
+
+ n=strlen(in);
+ /* find the last '/', '\' or ':' */
+ for (i=n-1; i>0; i--)
+ {
+ if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':'))
+ {
+ p= &(in[i+1]);
+ break;
+ }
+ }
+ if (p == NULL)
+ p=in;
+ n=strlen(p);
+
+#if defined(OPENSSL_SYS_NETWARE)
+ /* strip off trailing .nlm if present. */
+ if ((n > 4) && (p[n-4] == '.') &&
+ ((p[n-3] == 'n') || (p[n-3] == 'N')) &&
+ ((p[n-2] == 'l') || (p[n-2] == 'L')) &&
+ ((p[n-1] == 'm') || (p[n-1] == 'M')))
+ n-=4;
+#else
+ /* strip off trailing .exe if present. */
+ if ((n > 4) && (p[n-4] == '.') &&
+ ((p[n-3] == 'e') || (p[n-3] == 'E')) &&
+ ((p[n-2] == 'x') || (p[n-2] == 'X')) &&
+ ((p[n-1] == 'e') || (p[n-1] == 'E')))
+ n-=4;
+#endif
+
+ if (n > size-1)
+ n=size-1;
+
+ for (i=0; i<n; i++)
+ {
+ if ((p[i] >= 'A') && (p[i] <= 'Z'))
+ out[i]=p[i]-'A'+'a';
+ else
+ out[i]=p[i];
+ }
+ out[n]='\0';
+ }
+#else
+#ifdef OPENSSL_SYS_VMS
+void program_name(char *in, char *out, int size)
+ {
+ char *p=in, *q;
+ char *chars=":]>";
+
+ while(*chars != '\0')
+ {
+ q=strrchr(p,*chars);
+ if (q > p)
+ p = q + 1;
+ chars++;
+ }
+
+ q=strrchr(p,'.');
+ if (q == NULL)
+ q = p + strlen(p);
+ strncpy(out,p,size-1);
+ if (q-p >= size)
+ {
+ out[size-1]='\0';
+ }
+ else
+ {
+ out[q-p]='\0';
+ }
+ }
+#else
+void program_name(char *in, char *out, int size)
+ {
+ char *p;
+
+ p=strrchr(in,'/');
+ if (p != NULL)
+ p++;
+ else
+ p=in;
+ BUF_strlcpy(out,p,size);
+ }
+#endif
+#endif
+
+int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
+ {
+ int num,i;
+ char *p;
+
+ *argc=0;
+ *argv=NULL;
+
+ i=0;
+ if (arg->count == 0)
+ {
+ arg->count=20;
+ arg->data=(char **)OPENSSL_malloc(sizeof(char *)*arg->count);
+ }
+ for (i=0; i<arg->count; i++)
+ arg->data[i]=NULL;
+
+ num=0;
+ p=buf;
+ for (;;)
+ {
+ /* first scan over white space */
+ if (!*p) break;
+ while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
+ p++;
+ if (!*p) break;
+
+ /* The start of something good :-) */
+ if (num >= arg->count)
+ {
+ char **tmp_p;
+ int tlen = arg->count + 20;
+ tmp_p = (char **)OPENSSL_realloc(arg->data,
+ sizeof(char *)*tlen);
+ if (tmp_p == NULL)
+ return 0;
+ arg->data = tmp_p;
+ arg->count = tlen;
+ /* initialize newly allocated data */
+ for (i = num; i < arg->count; i++)
+ arg->data[i] = NULL;
+ }
+ arg->data[num++]=p;
+
+ /* now look for the end of this */
+ if ((*p == '\'') || (*p == '\"')) /* scan for closing quote */
+ {
+ i= *(p++);
+ arg->data[num-1]++; /* jump over quote */
+ while (*p && (*p != i))
+ p++;
+ *p='\0';
+ }
+ else
+ {
+ while (*p && ((*p != ' ') &&
+ (*p != '\t') && (*p != '\n')))
+ p++;
+
+ if (*p == '\0')
+ p--;
+ else
+ *p='\0';
+ }
+ p++;
+ }
+ *argc=num;
+ *argv=arg->data;
+ return(1);
+ }
+
+#ifndef APP_INIT
+int app_init(long mesgwin)
+ {
+ return(1);
+ }
+#endif
+
+
+int dump_cert_text (BIO *out, X509 *x)
+{
+ char *p;
+
+ p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0);
+ BIO_puts(out,"subject=");
+ BIO_puts(out,p);
+ OPENSSL_free(p);
+
+ p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0);
+ BIO_puts(out,"\nissuer=");
+ BIO_puts(out,p);
+ BIO_puts(out,"\n");
+ OPENSSL_free(p);
+
+ return 0;
+}
+
+static int ui_open(UI *ui)
+ {
+ return UI_method_get_opener(UI_OpenSSL())(ui);
+ }
+static int ui_read(UI *ui, UI_STRING *uis)
+ {
+ if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
+ && UI_get0_user_data(ui))
+ {
+ switch(UI_get_string_type(uis))
+ {
+ case UIT_PROMPT:
+ case UIT_VERIFY:
+ {
+ const char *password =
+ ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
+ if (password && password[0] != '\0')
+ {
+ UI_set_result(ui, uis, password);
+ return 1;
+ }
+ }
+ default:
+ break;
+ }
+ }
+ return UI_method_get_reader(UI_OpenSSL())(ui, uis);
+ }
+static int ui_write(UI *ui, UI_STRING *uis)
+ {
+ if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
+ && UI_get0_user_data(ui))
+ {
+ switch(UI_get_string_type(uis))
+ {
+ case UIT_PROMPT:
+ case UIT_VERIFY:
+ {
+ const char *password =
+ ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
+ if (password && password[0] != '\0')
+ return 1;
+ }
+ default:
+ break;
+ }
+ }
+ return UI_method_get_writer(UI_OpenSSL())(ui, uis);
+ }
+static int ui_close(UI *ui)
+ {
+ return UI_method_get_closer(UI_OpenSSL())(ui);
+ }
+int setup_ui_method(void)
+ {
+ ui_method = UI_create_method("OpenSSL application user interface");
+ UI_method_set_opener(ui_method, ui_open);
+ UI_method_set_reader(ui_method, ui_read);
+ UI_method_set_writer(ui_method, ui_write);
+ UI_method_set_closer(ui_method, ui_close);
+ return 0;
+ }
+void destroy_ui_method(void)
+ {
+ if(ui_method)
+ {
+ UI_destroy_method(ui_method);
+ ui_method = NULL;
+ }
+ }
+int password_callback(char *buf, int bufsiz, int verify,
+ PW_CB_DATA *cb_tmp)
+ {
+ UI *ui = NULL;
+ int res = 0;
+ const char *prompt_info = NULL;
+ const char *password = NULL;
+ PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
+
+ if (cb_data)
+ {
+ if (cb_data->password)
+ password = cb_data->password;
+ if (cb_data->prompt_info)
+ prompt_info = cb_data->prompt_info;
+ }
+
+ if (password)
+ {
+ res = strlen(password);
+ if (res > bufsiz)
+ res = bufsiz;
+ memcpy(buf, password, res);
+ return res;
+ }
+
+ ui = UI_new_method(ui_method);
+ if (ui)
+ {
+ int ok = 0;
+ char *buff = NULL;
+ int ui_flags = 0;
+ char *prompt = NULL;
+
+ prompt = UI_construct_prompt(ui, "pass phrase",
+ prompt_info);
+
+ ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
+ UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
+
+ if (ok >= 0)
+ ok = UI_add_input_string(ui,prompt,ui_flags,buf,
+ PW_MIN_LENGTH,BUFSIZ-1);
+ if (ok >= 0 && verify)
+ {
+ buff = (char *)OPENSSL_malloc(bufsiz);
+ ok = UI_add_verify_string(ui,prompt,ui_flags,buff,
+ PW_MIN_LENGTH,BUFSIZ-1, buf);
+ }
+ if (ok >= 0)
+ do
+ {
+ ok = UI_process(ui);
+ }
+ while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
+
+ if (buff)
+ {
+ OPENSSL_cleanse(buff,(unsigned int)bufsiz);
+ OPENSSL_free(buff);
+ }
+
+ if (ok >= 0)
+ res = strlen(buf);
+ if (ok == -1)
+ {
+ BIO_printf(bio_err, "User interface error\n");
+ ERR_print_errors(bio_err);
+ OPENSSL_cleanse(buf,(unsigned int)bufsiz);
+ res = 0;
+ }
+ if (ok == -2)
+ {
+ BIO_printf(bio_err,"aborted!\n");
+ OPENSSL_cleanse(buf,(unsigned int)bufsiz);
+ res = 0;
+ }
+ UI_free(ui);
+ OPENSSL_free(prompt);
+ }
+ return res;
+ }
+
+static char *app_get_pass(BIO *err, char *arg, int keepbio);
+
+int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
+{
+ int same;
+ if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0;
+ else same = 1;
+ if(arg1) {
+ *pass1 = app_get_pass(err, arg1, same);
+ if(!*pass1) return 0;
+ } else if(pass1) *pass1 = NULL;
+ if(arg2) {
+ *pass2 = app_get_pass(err, arg2, same ? 2 : 0);
+ if(!*pass2) return 0;
+ } else if(pass2) *pass2 = NULL;
+ return 1;
+}
+
+static char *app_get_pass(BIO *err, char *arg, int keepbio)
+{
+ char *tmp, tpass[APP_PASS_LEN];
+ static BIO *pwdbio = NULL;
+ int i;
+ if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5);
+ if(!strncmp(arg, "env:", 4)) {
+ tmp = getenv(arg + 4);
+ if(!tmp) {
+ BIO_printf(err, "Can't read environment variable %s\n", arg + 4);
+ return NULL;
+ }
+ return BUF_strdup(tmp);
+ }
+ if(!keepbio || !pwdbio) {
+ if(!strncmp(arg, "file:", 5)) {
+ pwdbio = BIO_new_file(arg + 5, "r");
+ if(!pwdbio) {
+ BIO_printf(err, "Can't open file %s\n", arg + 5);
+ return NULL;
+ }
+#if !defined(_WIN32)
+ /*
+ * Under _WIN32, which covers even Win64 and CE, file
+ * descriptors referenced by BIO_s_fd are not inherited
+ * by child process and therefore below is not an option.
+ * It could have been an option if bss_fd.c was operating
+ * on real Windows descriptors, such as those obtained
+ * with CreateFile.
+ */
+ } else if(!strncmp(arg, "fd:", 3)) {
+ BIO *btmp;
+ i = atoi(arg + 3);
+ if(i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
+ if((i < 0) || !pwdbio) {
+ BIO_printf(err, "Can't access file descriptor %s\n", arg + 3);
+ return NULL;
+ }
+ /* Can't do BIO_gets on an fd BIO so add a buffering BIO */
+ btmp = BIO_new(BIO_f_buffer());
+ pwdbio = BIO_push(btmp, pwdbio);
+#endif
+ } else if(!strcmp(arg, "stdin")) {
+ pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
+ if(!pwdbio) {
+ BIO_printf(err, "Can't open BIO for stdin\n");
+ return NULL;
+ }
+ } else {
+ BIO_printf(err, "Invalid password argument \"%s\"\n", arg);
+ return NULL;
+ }
+ }
+ i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
+ if(keepbio != 1) {
+ BIO_free_all(pwdbio);
+ pwdbio = NULL;
+ }
+ if(i <= 0) {
+ BIO_printf(err, "Error reading password from BIO\n");
+ return NULL;
+ }
+ tmp = strchr(tpass, '\n');
+ if(tmp) *tmp = 0;
+ return BUF_strdup(tpass);
+}
+
+int add_oid_section(BIO *err, CONF *conf)
+{
+ char *p;
+ STACK_OF(CONF_VALUE) *sktmp;
+ CONF_VALUE *cnf;
+ int i;
+ if(!(p=NCONF_get_string(conf,NULL,"oid_section")))
+ {
+ ERR_clear_error();
+ return 1;
+ }
+ if(!(sktmp = NCONF_get_section(conf, p))) {
+ BIO_printf(err, "problem loading oid section %s\n", p);
+ return 0;
+ }
+ for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+ cnf = sk_CONF_VALUE_value(sktmp, i);
+ if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
+ BIO_printf(err, "problem creating object %s=%s\n",
+ cnf->name, cnf->value);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int load_pkcs12(BIO *err, BIO *in, const char *desc,
+ pem_password_cb *pem_cb, void *cb_data,
+ EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
+ {
+ const char *pass;
+ char tpass[PEM_BUFSIZE];
+ int len, ret = 0;
+ PKCS12 *p12;
+ p12 = d2i_PKCS12_bio(in, NULL);
+ if (p12 == NULL)
+ {
+ BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
+ goto die;
+ }
+ /* See if an empty password will do */
+ if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
+ pass = "";
+ else
+ {
+ if (!pem_cb)
+ pem_cb = (pem_password_cb *)password_callback;
+ len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
+ if (len < 0)
+ {
+ BIO_printf(err, "Passpharse callback error for %s\n",
+ desc);
+ goto die;
+ }
+ if (len < PEM_BUFSIZE)
+ tpass[len] = 0;
+ if (!PKCS12_verify_mac(p12, tpass, len))
+ {
+ BIO_printf(err,
+ "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);
+ goto die;
+ }
+ pass = tpass;
+ }
+ ret = PKCS12_parse(p12, pass, pkey, cert, ca);
+ die:
+ if (p12)
+ PKCS12_free(p12);
+ return ret;
+ }
+
+X509 *load_cert(BIO *err, const char *file, int format,
+ const char *pass, ENGINE *e, const char *cert_descrip)
+ {
+ X509 *x=NULL;
+ BIO *cert;
+
+ if ((cert=BIO_new(BIO_s_file())) == NULL)
+ {
+ ERR_print_errors(err);
+ goto end;
+ }
+
+ if (file == NULL)
+ {
+#ifdef _IONBF
+# ifndef OPENSSL_NO_SETVBUF_IONBF
+ setvbuf(stdin, NULL, _IONBF, 0);
+# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+#endif
+ BIO_set_fp(cert,stdin,BIO_NOCLOSE);
+ }
+ else
+ {
+ if (BIO_read_filename(cert,file) <= 0)
+ {
+ BIO_printf(err, "Error opening %s %s\n",
+ cert_descrip, file);
+ ERR_print_errors(err);
+ goto end;
+ }
+ }
+
+ if (format == FORMAT_ASN1)
+ x=d2i_X509_bio(cert,NULL);
+ else if (format == FORMAT_NETSCAPE)
+ {
+ NETSCAPE_X509 *nx;
+ nx=ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),cert,NULL);
+ if (nx == NULL)
+ goto end;
+
+ if ((strncmp(NETSCAPE_CERT_HDR,(char *)nx->header->data,
+ nx->header->length) != 0))
+ {
+ NETSCAPE_X509_free(nx);
+ BIO_printf(err,"Error reading header on certificate\n");
+ goto end;
+ }
+ x=nx->cert;
+ nx->cert = NULL;
+ NETSCAPE_X509_free(nx);
+ }
+ else if (format == FORMAT_PEM)
+ x=PEM_read_bio_X509_AUX(cert,NULL,
+ (pem_password_cb *)password_callback, NULL);
+ else if (format == FORMAT_PKCS12)
+ {
+ if (!load_pkcs12(err, cert,cert_descrip, NULL, NULL,
+ NULL, &x, NULL))
+ goto end;
+ }
+ else {
+ BIO_printf(err,"bad input format specified for %s\n",
+ cert_descrip);
+ goto end;
+ }
+end:
+ if (x == NULL)
+ {
+ BIO_printf(err,"unable to load certificate\n");
+ ERR_print_errors(err);
+ }
+ if (cert != NULL) BIO_free(cert);
+ return(x);
+ }
+
+EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
+ const char *pass, ENGINE *e, const char *key_descrip)
+ {
+ BIO *key=NULL;
+ EVP_PKEY *pkey=NULL;
+ PW_CB_DATA cb_data;
+
+ cb_data.password = pass;
+ cb_data.prompt_info = file;
+
+ if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
+ {
+ BIO_printf(err,"no keyfile specified\n");
+ goto end;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ if (format == FORMAT_ENGINE)
+ {
+ if (!e)
+ BIO_printf(err,"no engine specified\n");
+ else
+ {
+ pkey = ENGINE_load_private_key(e, file,
+ ui_method, &cb_data);
+ if (!pkey)
+ {
+ BIO_printf(err,"cannot load %s from engine\n",key_descrip);
+ ERR_print_errors(err);
+ }
+ }
+ goto end;
+ }
+#endif
+ key=BIO_new(BIO_s_file());
+ if (key == NULL)
+ {
+ ERR_print_errors(err);
+ goto end;
+ }
+ if (file == NULL && maybe_stdin)
+ {
+#ifdef _IONBF
+# ifndef OPENSSL_NO_SETVBUF_IONBF
+ setvbuf(stdin, NULL, _IONBF, 0);
+# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+#endif
+ BIO_set_fp(key,stdin,BIO_NOCLOSE);
+ }
+ else
+ if (BIO_read_filename(key,file) <= 0)
+ {
+ BIO_printf(err, "Error opening %s %s\n",
+ key_descrip, file);
+ ERR_print_errors(err);
+ goto end;
+ }
+ if (format == FORMAT_ASN1)
+ {
+ pkey=d2i_PrivateKey_bio(key, NULL);
+ }
+ else if (format == FORMAT_PEM)
+ {
+ pkey=PEM_read_bio_PrivateKey(key,NULL,
+ (pem_password_cb *)password_callback, &cb_data);
+ }
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
+ else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
+ pkey = load_netscape_key(err, key, file, key_descrip, format);
+#endif
+ else if (format == FORMAT_PKCS12)
+ {
+ if (!load_pkcs12(err, key, key_descrip,
+ (pem_password_cb *)password_callback, &cb_data,
+ &pkey, NULL, NULL))
+ goto end;
+ }
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
+ else if (format == FORMAT_MSBLOB)
+ pkey = b2i_PrivateKey_bio(key);
+ else if (format == FORMAT_PVK)
+ pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
+ &cb_data);
+#endif
+ else
+ {
+ BIO_printf(err,"bad input format specified for key file\n");
+ goto end;
+ }
+ end:
+ if (key != NULL) BIO_free(key);
+ if (pkey == NULL)
+ {
+ BIO_printf(err,"unable to load %s\n", key_descrip);
+ ERR_print_errors(err);
+ }
+ return(pkey);
+ }
+
+EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
+ const char *pass, ENGINE *e, const char *key_descrip)
+ {
+ BIO *key=NULL;
+ EVP_PKEY *pkey=NULL;
+ PW_CB_DATA cb_data;
+
+ cb_data.password = pass;
+ cb_data.prompt_info = file;
+
+ if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
+ {
+ BIO_printf(err,"no keyfile specified\n");
+ goto end;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ if (format == FORMAT_ENGINE)
+ {
+ if (!e)
+ BIO_printf(bio_err,"no engine specified\n");
+ else
+ pkey = ENGINE_load_public_key(e, file,
+ ui_method, &cb_data);
+ goto end;
+ }
+#endif
+ key=BIO_new(BIO_s_file());
+ if (key == NULL)
+ {
+ ERR_print_errors(err);
+ goto end;
+ }
+ if (file == NULL && maybe_stdin)
+ {
+#ifdef _IONBF
+# ifndef OPENSSL_NO_SETVBUF_IONBF
+ setvbuf(stdin, NULL, _IONBF, 0);
+# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+#endif
+ BIO_set_fp(key,stdin,BIO_NOCLOSE);
+ }
+ else
+ if (BIO_read_filename(key,file) <= 0)
+ {
+ BIO_printf(err, "Error opening %s %s\n",
+ key_descrip, file);
+ ERR_print_errors(err);
+ goto end;
+ }
+ if (format == FORMAT_ASN1)
+ {
+ pkey=d2i_PUBKEY_bio(key, NULL);
+ }
+#ifndef OPENSSL_NO_RSA
+ else if (format == FORMAT_ASN1RSA)
+ {
+ RSA *rsa;
+ rsa = d2i_RSAPublicKey_bio(key, NULL);
+ if (rsa)
+ {
+ pkey = EVP_PKEY_new();
+ if (pkey)
+ EVP_PKEY_set1_RSA(pkey, rsa);
+ RSA_free(rsa);
+ }
+ else
+ pkey = NULL;
+ }
+ else if (format == FORMAT_PEMRSA)
+ {
+ RSA *rsa;
+ rsa = PEM_read_bio_RSAPublicKey(key, NULL,
+ (pem_password_cb *)password_callback, &cb_data);
+ if (rsa)
+ {
+ pkey = EVP_PKEY_new();
+ if (pkey)
+ EVP_PKEY_set1_RSA(pkey, rsa);
+ RSA_free(rsa);
+ }
+ else
+ pkey = NULL;
+ }
+#endif
+ else if (format == FORMAT_PEM)
+ {
+ pkey=PEM_read_bio_PUBKEY(key,NULL,
+ (pem_password_cb *)password_callback, &cb_data);
+ }
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
+ else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
+ pkey = load_netscape_key(err, key, file, key_descrip, format);
+#endif
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
+ else if (format == FORMAT_MSBLOB)
+ pkey = b2i_PublicKey_bio(key);
+#endif
+ else
+ {
+ BIO_printf(err,"bad input format specified for key file\n");
+ goto end;
+ }
+ end:
+ if (key != NULL) BIO_free(key);
+ if (pkey == NULL)
+ BIO_printf(err,"unable to load %s\n", key_descrip);
+ return(pkey);
+ }
+
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
+static EVP_PKEY *
+load_netscape_key(BIO *err, BIO *key, const char *file,
+ const char *key_descrip, int format)
+ {
+ EVP_PKEY *pkey;
+ BUF_MEM *buf;
+ RSA *rsa;
+ const unsigned char *p;
+ int size, i;
+
+ buf=BUF_MEM_new();
+ pkey = EVP_PKEY_new();
+ size = 0;
+ if (buf == NULL || pkey == NULL)
+ goto error;
+ for (;;)
+ {
+ if (!BUF_MEM_grow_clean(buf,size+1024*10))
+ goto error;
+ i = BIO_read(key, &(buf->data[size]), 1024*10);
+ size += i;
+ if (i == 0)
+ break;
+ if (i < 0)
+ {
+ BIO_printf(err, "Error reading %s %s",
+ key_descrip, file);
+ goto error;
+ }
+ }
+ p=(unsigned char *)buf->data;
+ rsa = d2i_RSA_NET(NULL,&p,(long)size,NULL,
+ (format == FORMAT_IISSGC ? 1 : 0));
+ if (rsa == NULL)
+ goto error;
+ BUF_MEM_free(buf);
+ EVP_PKEY_set1_RSA(pkey, rsa);
+ return pkey;
+error:
+ BUF_MEM_free(buf);
+ EVP_PKEY_free(pkey);
+ return NULL;
+ }
+#endif /* ndef OPENSSL_NO_RC4 */
+
+static int load_certs_crls(BIO *err, const char *file, int format,
+ const char *pass, ENGINE *e, const char *desc,
+ STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls)
+ {
+ int i;
+ BIO *bio;
+ STACK_OF(X509_INFO) *xis = NULL;
+ X509_INFO *xi;
+ PW_CB_DATA cb_data;
+ int rv = 0;
+
+ cb_data.password = pass;
+ cb_data.prompt_info = file;
+
+ if (format != FORMAT_PEM)
+ {
+ BIO_printf(err,"bad input format specified for %s\n", desc);
+ return 0;
+ }
+
+ if (file == NULL)
+ bio = BIO_new_fp(stdin,BIO_NOCLOSE);
+ else
+ bio = BIO_new_file(file, "r");
+
+ if (bio == NULL)
+ {
+ BIO_printf(err, "Error opening %s %s\n",
+ desc, file ? file : "stdin");
+ ERR_print_errors(err);
+ return 0;
+ }
+
+ xis = PEM_X509_INFO_read_bio(bio, NULL,
+ (pem_password_cb *)password_callback, &cb_data);
+
+ BIO_free(bio);
+
+ if (pcerts)
+ {
+ *pcerts = sk_X509_new_null();
+ if (!*pcerts)
+ goto end;
+ }
+
+ if (pcrls)
+ {
+ *pcrls = sk_X509_CRL_new_null();
+ if (!*pcrls)
+ goto end;
+ }
+
+ for(i = 0; i < sk_X509_INFO_num(xis); i++)
+ {
+ xi = sk_X509_INFO_value (xis, i);
+ if (xi->x509 && pcerts)
+ {
+ if (!sk_X509_push(*pcerts, xi->x509))
+ goto end;
+ xi->x509 = NULL;
+ }
+ if (xi->crl && pcrls)
+ {
+ if (!sk_X509_CRL_push(*pcrls, xi->crl))
+ goto end;
+ xi->crl = NULL;
+ }
+ }
+
+ if (pcerts && sk_X509_num(*pcerts) > 0)
+ rv = 1;
+
+ if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
+ rv = 1;
+
+ end:
+
+ if (xis)
+ sk_X509_INFO_pop_free(xis, X509_INFO_free);
+
+ if (rv == 0)
+ {
+ if (pcerts)
+ {
+ sk_X509_pop_free(*pcerts, X509_free);
+ *pcerts = NULL;
+ }
+ if (pcrls)
+ {
+ sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
+ *pcrls = NULL;
+ }
+ BIO_printf(err,"unable to load %s\n",
+ pcerts ? "certificates" : "CRLs");
+ ERR_print_errors(err);
+ }
+ return rv;
+ }
+
+STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
+ const char *pass, ENGINE *e, const char *desc)
+ {
+ STACK_OF(X509) *certs;
+ if (!load_certs_crls(err, file, format, pass, e, desc, &certs, NULL))
+ return NULL;
+ return certs;
+ }
+
+STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
+ const char *pass, ENGINE *e, const char *desc)
+ {
+ STACK_OF(X509_CRL) *crls;
+ if (!load_certs_crls(err, file, format, pass, e, desc, NULL, &crls))
+ return NULL;
+ return crls;
+ }
+
+#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
+/* Return error for unknown extensions */
+#define X509V3_EXT_DEFAULT 0
+/* Print error for unknown extensions */
+#define X509V3_EXT_ERROR_UNKNOWN (1L << 16)
+/* ASN1 parse unknown extensions */
+#define X509V3_EXT_PARSE_UNKNOWN (2L << 16)
+/* BIO_dump unknown extensions */
+#define X509V3_EXT_DUMP_UNKNOWN (3L << 16)
+
+#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
+ X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
+
+int set_cert_ex(unsigned long *flags, const char *arg)
+{
+ static const NAME_EX_TBL cert_tbl[] = {
+ { "compatible", X509_FLAG_COMPAT, 0xffffffffl},
+ { "ca_default", X509_FLAG_CA, 0xffffffffl},
+ { "no_header", X509_FLAG_NO_HEADER, 0},
+ { "no_version", X509_FLAG_NO_VERSION, 0},
+ { "no_serial", X509_FLAG_NO_SERIAL, 0},
+ { "no_signame", X509_FLAG_NO_SIGNAME, 0},
+ { "no_validity", X509_FLAG_NO_VALIDITY, 0},
+ { "no_subject", X509_FLAG_NO_SUBJECT, 0},
+ { "no_issuer", X509_FLAG_NO_ISSUER, 0},
+ { "no_pubkey", X509_FLAG_NO_PUBKEY, 0},
+ { "no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
+ { "no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
+ { "no_aux", X509_FLAG_NO_AUX, 0},
+ { "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
+ { "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
+ { "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+ { "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+ { "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+ { NULL, 0, 0}
+ };
+ return set_multi_opts(flags, arg, cert_tbl);
+}
+
+int set_name_ex(unsigned long *flags, const char *arg)
+{
+ static const NAME_EX_TBL ex_tbl[] = {
+ { "esc_2253", ASN1_STRFLGS_ESC_2253, 0},
+ { "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
+ { "esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
+ { "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
+ { "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
+ { "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
+ { "show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
+ { "dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
+ { "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
+ { "dump_der", ASN1_STRFLGS_DUMP_DER, 0},
+ { "compat", XN_FLAG_COMPAT, 0xffffffffL},
+ { "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
+ { "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
+ { "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
+ { "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
+ { "dn_rev", XN_FLAG_DN_REV, 0},
+ { "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
+ { "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
+ { "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
+ { "align", XN_FLAG_FN_ALIGN, 0},
+ { "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
+ { "space_eq", XN_FLAG_SPC_EQ, 0},
+ { "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
+ { "RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
+ { "oneline", XN_FLAG_ONELINE, 0xffffffffL},
+ { "multiline", XN_FLAG_MULTILINE, 0xffffffffL},
+ { "ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
+ { NULL, 0, 0}
+ };
+ return set_multi_opts(flags, arg, ex_tbl);
+}
+
+int set_ext_copy(int *copy_type, const char *arg)
+{
+ if (!strcasecmp(arg, "none"))
+ *copy_type = EXT_COPY_NONE;
+ else if (!strcasecmp(arg, "copy"))
+ *copy_type = EXT_COPY_ADD;
+ else if (!strcasecmp(arg, "copyall"))
+ *copy_type = EXT_COPY_ALL;
+ else
+ return 0;
+ return 1;
+}
+
+int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
+{
+ STACK_OF(X509_EXTENSION) *exts = NULL;
+ X509_EXTENSION *ext, *tmpext;
+ ASN1_OBJECT *obj;
+ int i, idx, ret = 0;
+ if (!x || !req || (copy_type == EXT_COPY_NONE))
+ return 1;
+ exts = X509_REQ_get_extensions(req);
+
+ for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+ ext = sk_X509_EXTENSION_value(exts, i);
+ obj = X509_EXTENSION_get_object(ext);
+ idx = X509_get_ext_by_OBJ(x, obj, -1);
+ /* Does extension exist? */
+ if (idx != -1) {
+ /* If normal copy don't override existing extension */
+ if (copy_type == EXT_COPY_ADD)
+ continue;
+ /* Delete all extensions of same type */
+ do {
+ tmpext = X509_get_ext(x, idx);
+ X509_delete_ext(x, idx);
+ X509_EXTENSION_free(tmpext);
+ idx = X509_get_ext_by_OBJ(x, obj, -1);
+ } while (idx != -1);
+ }
+ if (!X509_add_ext(x, ext, -1))
+ goto end;
+ }
+
+ ret = 1;
+
+ end:
+
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+
+ return ret;
+}
+
+
+
+
+static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
+{
+ STACK_OF(CONF_VALUE) *vals;
+ CONF_VALUE *val;
+ int i, ret = 1;
+ if(!arg) return 0;
+ vals = X509V3_parse_list(arg);
+ for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+ val = sk_CONF_VALUE_value(vals, i);
+ if (!set_table_opts(flags, val->name, in_tbl))
+ ret = 0;
+ }
+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+ return ret;
+}
+
+static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
+{
+ char c;
+ const NAME_EX_TBL *ptbl;
+ c = arg[0];
+
+ if(c == '-') {
+ c = 0;
+ arg++;
+ } else if (c == '+') {
+ c = 1;
+ arg++;
+ } else c = 1;
+
+ for(ptbl = in_tbl; ptbl->name; ptbl++) {
+ if(!strcasecmp(arg, ptbl->name)) {
+ *flags &= ~ptbl->mask;
+ if(c) *flags |= ptbl->flag;
+ else *flags &= ~ptbl->flag;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags)
+{
+ char *buf;
+ char mline = 0;
+ int indent = 0;
+
+ if(title) BIO_puts(out, title);
+ if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+ mline = 1;
+ indent = 4;
+ }
+ if(lflags == XN_FLAG_COMPAT) {
+ buf = X509_NAME_oneline(nm, 0, 0);
+ BIO_puts(out, buf);
+ BIO_puts(out, "\n");
+ OPENSSL_free(buf);
+ } else {
+ if(mline) BIO_puts(out, "\n");
+ X509_NAME_print_ex(out, nm, indent, lflags);
+ BIO_puts(out, "\n");
+ }
+}
+
+X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath)
+{
+ X509_STORE *store;
+ X509_LOOKUP *lookup;
+ if(!(store = X509_STORE_new())) goto end;
+ lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
+ if (lookup == NULL) goto end;
+ if (CAfile) {
+ if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) {
+ BIO_printf(bp, "Error loading file %s\n", CAfile);
+ goto end;
+ }
+ } else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
+
+ lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
+ if (lookup == NULL) goto end;
+ if (CApath) {
+ if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) {
+ BIO_printf(bp, "Error loading directory %s\n", CApath);
+ goto end;
+ }
+ } else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
+
+ ERR_clear_error();
+ return store;
+ end:
+ X509_STORE_free(store);
+ return NULL;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+/* Try to load an engine in a shareable library */
+static ENGINE *try_load_engine(BIO *err, const char *engine, int debug)
+ {
+ ENGINE *e = ENGINE_by_id("dynamic");
+ if (e)
+ {
+ if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
+ || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
+ {
+ ENGINE_free(e);
+ e = NULL;
+ }
+ }
+ return e;
+ }
+
+ENGINE *setup_engine(BIO *err, const char *engine, int debug)
+ {
+ ENGINE *e = NULL;
+
+ if (engine)
+ {
+ if(strcmp(engine, "auto") == 0)
+ {
+ BIO_printf(err,"enabling auto ENGINE support\n");
+ ENGINE_register_all_complete();
+ return NULL;
+ }
+ if((e = ENGINE_by_id(engine)) == NULL
+ && (e = try_load_engine(err, engine, debug)) == NULL)
+ {
+ BIO_printf(err,"invalid engine \"%s\"\n", engine);
+ ERR_print_errors(err);
+ return NULL;
+ }
+ if (debug)
+ {
+ ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM,
+ 0, err, 0);
+ }
+ ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
+ if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
+ {
+ BIO_printf(err,"can't use that engine\n");
+ ERR_print_errors(err);
+ ENGINE_free(e);
+ return NULL;
+ }
+
+ BIO_printf(err,"engine \"%s\" set.\n", ENGINE_get_id(e));
+
+ /* Free our "structural" reference. */
+ ENGINE_free(e);
+ }
+ return e;
+ }
+#endif
+
+int load_config(BIO *err, CONF *cnf)
+ {
+ static int load_config_called = 0;
+ if (load_config_called)
+ return 1;
+ load_config_called = 1;
+ if (!cnf)
+ cnf = config;
+ if (!cnf)
+ return 1;
+
+ OPENSSL_load_builtin_modules();
+
+ if (CONF_modules_load(cnf, NULL, 0) <= 0)
+ {
+ BIO_printf(err, "Error configuring OpenSSL\n");
+ ERR_print_errors(err);
+ return 0;
+ }
+ return 1;
+ }
+
+char *make_config_name()
+ {
+ const char *t=X509_get_default_cert_area();
+ size_t len;
+ char *p;
+
+ len=strlen(t)+strlen(OPENSSL_CONF)+2;
+ p=OPENSSL_malloc(len);
+ BUF_strlcpy(p,t,len);
+#ifndef OPENSSL_SYS_VMS
+ BUF_strlcat(p,"/",len);
+#endif
+ BUF_strlcat(p,OPENSSL_CONF,len);
+
+ return p;
+ }
+
+static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
+ {
+ const char *n;
+
+ n=a[DB_serial];
+ while (*n == '0') n++;
+ return(lh_strhash(n));
+ }
+
+static int index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
+ {
+ const char *aa,*bb;
+
+ for (aa=a[DB_serial]; *aa == '0'; aa++);
+ for (bb=b[DB_serial]; *bb == '0'; bb++);
+ return(strcmp(aa,bb));
+ }
+
+static int index_name_qual(char **a)
+ { return(a[0][0] == 'V'); }
+
+static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
+ { return(lh_strhash(a[DB_name])); }
+
+int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
+ { return(strcmp(a[DB_name], b[DB_name])); }
+
+static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
+
+#undef BSIZE
+#define BSIZE 256
+
+BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
+ {
+ BIO *in=NULL;
+ BIGNUM *ret=NULL;
+ MS_STATIC char buf[1024];
+ ASN1_INTEGER *ai=NULL;
+
+ ai=ASN1_INTEGER_new();
+ if (ai == NULL) goto err;
+
+ if ((in=BIO_new(BIO_s_file())) == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ if (BIO_read_filename(in,serialfile) <= 0)
+ {
+ if (!create)
+ {
+ perror(serialfile);
+ goto err;
+ }
+ else
+ {
+ ret=BN_new();
+ if (ret == NULL || !rand_serial(ret, ai))
+ BIO_printf(bio_err, "Out of memory\n");
+ }
+ }
+ else
+ {
+ if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
+ {
+ BIO_printf(bio_err,"unable to load number from %s\n",
+ serialfile);
+ goto err;
+ }
+ ret=ASN1_INTEGER_to_BN(ai,NULL);
+ if (ret == NULL)
+ {
+ BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
+ goto err;
+ }
+ }
+
+ if (ret && retai)
+ {
+ *retai = ai;
+ ai = NULL;
+ }
+ err:
+ if (in != NULL) BIO_free(in);
+ if (ai != NULL) ASN1_INTEGER_free(ai);
+ return(ret);
+ }
+
+int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai)
+ {
+ char buf[1][BSIZE];
+ BIO *out = NULL;
+ int ret=0;
+ ASN1_INTEGER *ai=NULL;
+ int j;
+
+ if (suffix == NULL)
+ j = strlen(serialfile);
+ else
+ j = strlen(serialfile) + strlen(suffix) + 1;
+ if (j >= BSIZE)
+ {
+ BIO_printf(bio_err,"file name too long\n");
+ goto err;
+ }
+
+ if (suffix == NULL)
+ BUF_strlcpy(buf[0], serialfile, BSIZE);
+ else
+ {
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
+#else
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
+#endif
+ }
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
+#endif
+ out=BIO_new(BIO_s_file());
+ if (out == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ if (BIO_write_filename(out,buf[0]) <= 0)
+ {
+ perror(serialfile);
+ goto err;
+ }
+
+ if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
+ {
+ BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
+ goto err;
+ }
+ i2a_ASN1_INTEGER(out,ai);
+ BIO_puts(out,"\n");
+ ret=1;
+ if (retai)
+ {
+ *retai = ai;
+ ai = NULL;
+ }
+err:
+ if (out != NULL) BIO_free_all(out);
+ if (ai != NULL) ASN1_INTEGER_free(ai);
+ return(ret);
+ }
+
+int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
+ {
+ char buf[5][BSIZE];
+ int i,j;
+
+ i = strlen(serialfile) + strlen(old_suffix);
+ j = strlen(serialfile) + strlen(new_suffix);
+ if (i > j) j = i;
+ if (j + 1 >= BSIZE)
+ {
+ BIO_printf(bio_err,"file name too long\n");
+ goto err;
+ }
+
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
+ serialfile, new_suffix);
+#else
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
+ serialfile, new_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
+ serialfile, old_suffix);
+#else
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
+ serialfile, old_suffix);
+#endif
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ serialfile, buf[1]);
+#endif
+ if (rename(serialfile,buf[1]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+ && errno != ENOTDIR
+#endif
+ ) {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ serialfile, buf[1]);
+ perror("reason");
+ goto err;
+ }
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ buf[0],serialfile);
+#endif
+ if (rename(buf[0],serialfile) < 0)
+ {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ buf[0],serialfile);
+ perror("reason");
+ rename(buf[1],serialfile);
+ goto err;
+ }
+ return 1;
+ err:
+ return 0;
+ }
+
+int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
+ {
+ BIGNUM *btmp;
+ int ret = 0;
+ if (b)
+ btmp = b;
+ else
+ btmp = BN_new();
+
+ if (!btmp)
+ return 0;
+
+ if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
+ goto error;
+ if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
+ goto error;
+
+ ret = 1;
+
+ error:
+
+ if (!b)
+ BN_free(btmp);
+
+ return ret;
+ }
+
+CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
+ {
+ CA_DB *retdb = NULL;
+ TXT_DB *tmpdb = NULL;
+ BIO *in = BIO_new(BIO_s_file());
+ CONF *dbattr_conf = NULL;
+ char buf[1][BSIZE];
+ long errorline= -1;
+
+ if (in == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ if (BIO_read_filename(in,dbfile) <= 0)
+ {
+ perror(dbfile);
+ BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
+ goto err;
+ }
+ if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL)
+ goto err;
+
+#ifndef OPENSSL_SYS_VMS
+ BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
+#else
+ BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
+#endif
+ dbattr_conf = NCONF_new(NULL);
+ if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0)
+ {
+ if (errorline > 0)
+ {
+ BIO_printf(bio_err,
+ "error on line %ld of db attribute file '%s'\n"
+ ,errorline,buf[0]);
+ goto err;
+ }
+ else
+ {
+ NCONF_free(dbattr_conf);
+ dbattr_conf = NULL;
+ }
+ }
+
+ if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL)
+ {
+ fprintf(stderr, "Out of memory\n");
+ goto err;
+ }
+
+ retdb->db = tmpdb;
+ tmpdb = NULL;
+ if (db_attr)
+ retdb->attributes = *db_attr;
+ else
+ {
+ retdb->attributes.unique_subject = 1;
+ }
+
+ if (dbattr_conf)
+ {
+ char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject");
+ if (p)
+ {
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
+#endif
+ retdb->attributes.unique_subject = parse_yesno(p,1);
+ }
+ }
+
+ err:
+ if (dbattr_conf) NCONF_free(dbattr_conf);
+ if (tmpdb) TXT_DB_free(tmpdb);
+ if (in) BIO_free_all(in);
+ return retdb;
+ }
+
+int index_index(CA_DB *db)
+ {
+ if (!TXT_DB_create_index(db->db, DB_serial, NULL,
+ LHASH_HASH_FN(index_serial),
+ LHASH_COMP_FN(index_serial)))
+ {
+ BIO_printf(bio_err,
+ "error creating serial number index:(%ld,%ld,%ld)\n",
+ db->db->error,db->db->arg1,db->db->arg2);
+ return 0;
+ }
+
+ if (db->attributes.unique_subject
+ && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
+ LHASH_HASH_FN(index_name),
+ LHASH_COMP_FN(index_name)))
+ {
+ BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
+ db->db->error,db->db->arg1,db->db->arg2);
+ return 0;
+ }
+ return 1;
+ }
+
+int save_index(const char *dbfile, const char *suffix, CA_DB *db)
+ {
+ char buf[3][BSIZE];
+ BIO *out = BIO_new(BIO_s_file());
+ int j;
+
+ if (out == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ j = strlen(dbfile) + strlen(suffix);
+ if (j + 6 >= BSIZE)
+ {
+ BIO_printf(bio_err,"file name too long\n");
+ goto err;
+ }
+
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
+#else
+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
+#else
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
+#else
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
+#endif
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
+#endif
+ if (BIO_write_filename(out,buf[0]) <= 0)
+ {
+ perror(dbfile);
+ BIO_printf(bio_err,"unable to open '%s'\n", dbfile);
+ goto err;
+ }
+ j=TXT_DB_write(out,db->db);
+ if (j <= 0) goto err;
+
+ BIO_free(out);
+
+ out = BIO_new(BIO_s_file());
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]);
+#endif
+ if (BIO_write_filename(out,buf[1]) <= 0)
+ {
+ perror(buf[2]);
+ BIO_printf(bio_err,"unable to open '%s'\n", buf[2]);
+ goto err;
+ }
+ BIO_printf(out,"unique_subject = %s\n",
+ db->attributes.unique_subject ? "yes" : "no");
+ BIO_free(out);
+
+ return 1;
+ err:
+ return 0;
+ }
+
+int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix)
+ {
+ char buf[5][BSIZE];
+ int i,j;
+
+ i = strlen(dbfile) + strlen(old_suffix);
+ j = strlen(dbfile) + strlen(new_suffix);
+ if (i > j) j = i;
+ if (j + 6 >= BSIZE)
+ {
+ BIO_printf(bio_err,"file name too long\n");
+ goto err;
+ }
+
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
+#else
+ j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s",
+ dbfile, new_suffix);
+#else
+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s",
+ dbfile, new_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
+ dbfile, new_suffix);
+#else
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
+ dbfile, new_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
+ dbfile, old_suffix);
+#else
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
+ dbfile, old_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s",
+ dbfile, old_suffix);
+#else
+ j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s",
+ dbfile, old_suffix);
+#endif
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ dbfile, buf[1]);
+#endif
+ if (rename(dbfile,buf[1]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+ && errno != ENOTDIR
+#endif
+ ) {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ dbfile, buf[1]);
+ perror("reason");
+ goto err;
+ }
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ buf[0],dbfile);
+#endif
+ if (rename(buf[0],dbfile) < 0)
+ {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ buf[0],dbfile);
+ perror("reason");
+ rename(buf[1],dbfile);
+ goto err;
+ }
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ buf[4],buf[3]);
+#endif
+ if (rename(buf[4],buf[3]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+ && errno != ENOTDIR
+#endif
+ ) {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ buf[4], buf[3]);
+ perror("reason");
+ rename(dbfile,buf[0]);
+ rename(buf[1],dbfile);
+ goto err;
+ }
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ buf[2],buf[4]);
+#endif
+ if (rename(buf[2],buf[4]) < 0)
+ {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ buf[2],buf[4]);
+ perror("reason");
+ rename(buf[3],buf[4]);
+ rename(dbfile,buf[0]);
+ rename(buf[1],dbfile);
+ goto err;
+ }
+ return 1;
+ err:
+ return 0;
+ }
+
+void free_index(CA_DB *db)
+ {
+ if (db)
+ {
+ if (db->db) TXT_DB_free(db->db);
+ OPENSSL_free(db);
+ }
+ }
+
+int parse_yesno(const char *str, int def)
+ {
+ int ret = def;
+ if (str)
+ {
+ switch (*str)
+ {
+ case 'f': /* false */
+ case 'F': /* FALSE */
+ case 'n': /* no */
+ case 'N': /* NO */
+ case '0': /* 0 */
+ ret = 0;
+ break;
+ case 't': /* true */
+ case 'T': /* TRUE */
+ case 'y': /* yes */
+ case 'Y': /* YES */
+ case '1': /* 1 */
+ ret = 1;
+ break;
+ default:
+ ret = def;
+ break;
+ }
+ }
+ return ret;
+ }
+
+/*
+ * subject is expected to be in the format /type0=value0/type1=value1/type2=...
+ * where characters may be escaped by \
+ */
+X509_NAME *parse_name(char *subject, long chtype, int multirdn)
+ {
+ size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
+ char *buf = OPENSSL_malloc(buflen);
+ size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
+ char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
+ char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
+ int *mval = OPENSSL_malloc (max_ne * sizeof (int));
+
+ char *sp = subject, *bp = buf;
+ int i, ne_num = 0;
+
+ X509_NAME *n = NULL;
+ int nid;
+
+ if (!buf || !ne_types || !ne_values || !mval)
+ {
+ BIO_printf(bio_err, "malloc error\n");
+ goto error;
+ }
+
+ if (*subject != '/')
+ {
+ BIO_printf(bio_err, "Subject does not start with '/'.\n");
+ goto error;
+ }
+ sp++; /* skip leading / */
+
+ /* no multivalued RDN by default */
+ mval[ne_num] = 0;
+
+ while (*sp)
+ {
+ /* collect type */
+ ne_types[ne_num] = bp;
+ while (*sp)
+ {
+ if (*sp == '\\') /* is there anything to escape in the type...? */
+ {
+ if (*++sp)
+ *bp++ = *sp++;
+ else
+ {
+ BIO_printf(bio_err, "escape character at end of string\n");
+ goto error;
+ }
+ }
+ else if (*sp == '=')
+ {
+ sp++;
+ *bp++ = '\0';
+ break;
+ }
+ else
+ *bp++ = *sp++;
+ }
+ if (!*sp)
+ {
+ BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
+ goto error;
+ }
+ ne_values[ne_num] = bp;
+ while (*sp)
+ {
+ if (*sp == '\\')
+ {
+ if (*++sp)
+ *bp++ = *sp++;
+ else
+ {
+ BIO_printf(bio_err, "escape character at end of string\n");
+ goto error;
+ }
+ }
+ else if (*sp == '/')
+ {
+ sp++;
+ /* no multivalued RDN by default */
+ mval[ne_num+1] = 0;
+ break;
+ }
+ else if (*sp == '+' && multirdn)
+ {
+ /* a not escaped + signals a mutlivalued RDN */
+ sp++;
+ mval[ne_num+1] = -1;
+ break;
+ }
+ else
+ *bp++ = *sp++;
+ }
+ *bp++ = '\0';
+ ne_num++;
+ }
+
+ if (!(n = X509_NAME_new()))
+ goto error;
+
+ for (i = 0; i < ne_num; i++)
+ {
+ if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
+ {
+ BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
+ continue;
+ }
+
+ if (!*ne_values[i])
+ {
+ BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
+ continue;
+ }
+
+ if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,mval[i]))
+ goto error;
+ }
+
+ OPENSSL_free(ne_values);
+ OPENSSL_free(ne_types);
+ OPENSSL_free(buf);
+ OPENSSL_free(mval);
+ return n;
+
+error:
+ X509_NAME_free(n);
+ if (ne_values)
+ OPENSSL_free(ne_values);
+ if (ne_types)
+ OPENSSL_free(ne_types);
+ if (mval)
+ OPENSSL_free(mval);
+ if (buf)
+ OPENSSL_free(buf);
+ return NULL;
+}
+
+int args_verify(char ***pargs, int *pargc,
+ int *badarg, BIO *err, X509_VERIFY_PARAM **pm)
+ {
+ ASN1_OBJECT *otmp = NULL;
+ unsigned long flags = 0;
+ int i;
+ int purpose = 0, depth = -1;
+ char **oldargs = *pargs;
+ char *arg = **pargs, *argn = (*pargs)[1];
+ time_t at_time = 0;
+ if (!strcmp(arg, "-policy"))
+ {
+ if (!argn)
+ *badarg = 1;
+ else
+ {
+ otmp = OBJ_txt2obj(argn, 0);
+ if (!otmp)
+ {
+ BIO_printf(err, "Invalid Policy \"%s\"\n",
+ argn);
+ *badarg = 1;
+ }
+ }
+ (*pargs)++;
+ }
+ else if (strcmp(arg,"-purpose") == 0)
+ {
+ X509_PURPOSE *xptmp;
+ if (!argn)
+ *badarg = 1;
+ else
+ {
+ i = X509_PURPOSE_get_by_sname(argn);
+ if(i < 0)
+ {
+ BIO_printf(err, "unrecognized purpose\n");
+ *badarg = 1;
+ }
+ else
+ {
+ xptmp = X509_PURPOSE_get0(i);
+ purpose = X509_PURPOSE_get_id(xptmp);
+ }
+ }
+ (*pargs)++;
+ }
+ else if (strcmp(arg,"-verify_depth") == 0)
+ {
+ if (!argn)
+ *badarg = 1;
+ else
+ {
+ depth = atoi(argn);
+ if(depth < 0)
+ {
+ BIO_printf(err, "invalid depth\n");
+ *badarg = 1;
+ }
+ }
+ (*pargs)++;
+ }
+ else if (strcmp(arg,"-attime") == 0)
+ {
+ if (!argn)
+ *badarg = 1;
+ else
+ {
+ long timestamp;
+ /* interpret the -attime argument as seconds since
+ * Epoch */
+ if (sscanf(argn, "%li", &timestamp) != 1)
+ {
+ BIO_printf(bio_err,
+ "Error parsing timestamp %s\n",
+ argn);
+ *badarg = 1;
+ }
+ /* on some platforms time_t may be a float */
+ at_time = (time_t) timestamp;
+ }
+ (*pargs)++;
+ }
+ else if (!strcmp(arg, "-ignore_critical"))
+ flags |= X509_V_FLAG_IGNORE_CRITICAL;
+ else if (!strcmp(arg, "-issuer_checks"))
+ flags |= X509_V_FLAG_CB_ISSUER_CHECK;
+ else if (!strcmp(arg, "-crl_check"))
+ flags |= X509_V_FLAG_CRL_CHECK;
+ else if (!strcmp(arg, "-crl_check_all"))
+ flags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
+ else if (!strcmp(arg, "-policy_check"))
+ flags |= X509_V_FLAG_POLICY_CHECK;
+ else if (!strcmp(arg, "-explicit_policy"))
+ flags |= X509_V_FLAG_EXPLICIT_POLICY;
+ else if (!strcmp(arg, "-inhibit_any"))
+ flags |= X509_V_FLAG_INHIBIT_ANY;
+ else if (!strcmp(arg, "-inhibit_map"))
+ flags |= X509_V_FLAG_INHIBIT_MAP;
+ else if (!strcmp(arg, "-x509_strict"))
+ flags |= X509_V_FLAG_X509_STRICT;
+ else if (!strcmp(arg, "-extended_crl"))
+ flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
+ else if (!strcmp(arg, "-use_deltas"))
+ flags |= X509_V_FLAG_USE_DELTAS;
+ else if (!strcmp(arg, "-policy_print"))
+ flags |= X509_V_FLAG_NOTIFY_POLICY;
+ else if (!strcmp(arg, "-check_ss_sig"))
+ flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
+ else
+ return 0;
+
+ if (*badarg)
+ {
+ if (*pm)
+ X509_VERIFY_PARAM_free(*pm);
+ *pm = NULL;
+ goto end;
+ }
+
+ if (!*pm && !(*pm = X509_VERIFY_PARAM_new()))
+ {
+ *badarg = 1;
+ goto end;
+ }
+
+ if (otmp)
+ X509_VERIFY_PARAM_add0_policy(*pm, otmp);
+ if (flags)
+ X509_VERIFY_PARAM_set_flags(*pm, flags);
+
+ if (purpose)
+ X509_VERIFY_PARAM_set_purpose(*pm, purpose);
+
+ if (depth >= 0)
+ X509_VERIFY_PARAM_set_depth(*pm, depth);
+
+ if (at_time)
+ X509_VERIFY_PARAM_set_time(*pm, at_time);
+
+ end:
+
+ (*pargs)++;
+
+ if (pargc)
+ *pargc -= *pargs - oldargs;
+
+ return 1;
+
+ }
+
+/* Read whole contents of a BIO into an allocated memory buffer and
+ * return it.
+ */
+
+int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
+ {
+ BIO *mem;
+ int len, ret;
+ unsigned char tbuf[1024];
+ mem = BIO_new(BIO_s_mem());
+ if (!mem)
+ return -1;
+ for(;;)
+ {
+ if ((maxlen != -1) && maxlen < 1024)
+ len = maxlen;
+ else
+ len = 1024;
+ len = BIO_read(in, tbuf, len);
+ if (len <= 0)
+ break;
+ if (BIO_write(mem, tbuf, len) != len)
+ {
+ BIO_free(mem);
+ return -1;
+ }
+ maxlen -= len;
+
+ if (maxlen == 0)
+ break;
+ }
+ ret = BIO_get_mem_data(mem, (char **)out);
+ BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
+ BIO_free(mem);
+ return ret;
+ }
+
+int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
+ {
+ int rv;
+ char *stmp, *vtmp = NULL;
+ stmp = BUF_strdup(value);
+ if (!stmp)
+ return -1;
+ vtmp = strchr(stmp, ':');
+ if (vtmp)
+ {
+ *vtmp = 0;
+ vtmp++;
+ }
+ rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
+ OPENSSL_free(stmp);
+ return rv;
+ }
+
+static void nodes_print(BIO *out, const char *name,
+ STACK_OF(X509_POLICY_NODE) *nodes)
+ {
+ X509_POLICY_NODE *node;
+ int i;
+ BIO_printf(out, "%s Policies:", name);
+ if (nodes)
+ {
+ BIO_puts(out, "\n");
+ for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++)
+ {
+ node = sk_X509_POLICY_NODE_value(nodes, i);
+ X509_POLICY_NODE_print(out, node, 2);
+ }
+ }
+ else
+ BIO_puts(out, " <empty>\n");
+ }
+
+void policies_print(BIO *out, X509_STORE_CTX *ctx)
+ {
+ X509_POLICY_TREE *tree;
+ int explicit_policy;
+ int free_out = 0;
+ if (out == NULL)
+ {
+ out = BIO_new_fp(stderr, BIO_NOCLOSE);
+ free_out = 1;
+ }
+ tree = X509_STORE_CTX_get0_policy_tree(ctx);
+ explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
+
+ BIO_printf(out, "Require explicit Policy: %s\n",
+ explicit_policy ? "True" : "False");
+
+ nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
+ nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
+ if (free_out)
+ BIO_free(out);
+ }
+
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+
+static JPAKE_CTX *jpake_init(const char *us, const char *them,
+ const char *secret)
+ {
+ BIGNUM *p = NULL;
+ BIGNUM *g = NULL;
+ BIGNUM *q = NULL;
+ BIGNUM *bnsecret = BN_new();
+ JPAKE_CTX *ctx;
+
+ /* Use a safe prime for p (that we found earlier) */
+ BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
+ g = BN_new();
+ BN_set_word(g, 2);
+ q = BN_new();
+ BN_rshift1(q, p);
+
+ BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret);
+
+ ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret);
+ BN_free(bnsecret);
+ BN_free(q);
+ BN_free(g);
+ BN_free(p);
+
+ return ctx;
+ }
+
+static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p)
+ {
+ BN_print(conn, p->gx);
+ BIO_puts(conn, "\n");
+ BN_print(conn, p->zkpx.gr);
+ BIO_puts(conn, "\n");
+ BN_print(conn, p->zkpx.b);
+ BIO_puts(conn, "\n");
+ }
+
+static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx)
+ {
+ JPAKE_STEP1 s1;
+
+ JPAKE_STEP1_init(&s1);
+ JPAKE_STEP1_generate(&s1, ctx);
+ jpake_send_part(bconn, &s1.p1);
+ jpake_send_part(bconn, &s1.p2);
+ (void)BIO_flush(bconn);
+ JPAKE_STEP1_release(&s1);
+ }
+
+static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx)
+ {
+ JPAKE_STEP2 s2;
+
+ JPAKE_STEP2_init(&s2);
+ JPAKE_STEP2_generate(&s2, ctx);
+ jpake_send_part(bconn, &s2);
+ (void)BIO_flush(bconn);
+ JPAKE_STEP2_release(&s2);
+ }
+
+static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx)
+ {
+ JPAKE_STEP3A s3a;
+
+ JPAKE_STEP3A_init(&s3a);
+ JPAKE_STEP3A_generate(&s3a, ctx);
+ BIO_write(bconn, s3a.hhk, sizeof s3a.hhk);
+ (void)BIO_flush(bconn);
+ JPAKE_STEP3A_release(&s3a);
+ }
+
+static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx)
+ {
+ JPAKE_STEP3B s3b;
+
+ JPAKE_STEP3B_init(&s3b);
+ JPAKE_STEP3B_generate(&s3b, ctx);
+ BIO_write(bconn, s3b.hk, sizeof s3b.hk);
+ (void)BIO_flush(bconn);
+ JPAKE_STEP3B_release(&s3b);
+ }
+
+static void readbn(BIGNUM **bn, BIO *bconn)
+ {
+ char buf[10240];
+ int l;
+
+ l = BIO_gets(bconn, buf, sizeof buf);
+ assert(l > 0);
+ assert(buf[l-1] == '\n');
+ buf[l-1] = '\0';
+ BN_hex2bn(bn, buf);
+ }
+
+static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn)
+ {
+ readbn(&p->gx, bconn);
+ readbn(&p->zkpx.gr, bconn);
+ readbn(&p->zkpx.b, bconn);
+ }
+
+static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn)
+ {
+ JPAKE_STEP1 s1;
+
+ JPAKE_STEP1_init(&s1);
+ jpake_receive_part(&s1.p1, bconn);
+ jpake_receive_part(&s1.p2, bconn);
+ if(!JPAKE_STEP1_process(ctx, &s1))
+ {
+ ERR_print_errors(bio_err);
+ exit(1);
+ }
+ JPAKE_STEP1_release(&s1);
+ }
+
+static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn)
+ {
+ JPAKE_STEP2 s2;
+
+ JPAKE_STEP2_init(&s2);
+ jpake_receive_part(&s2, bconn);
+ if(!JPAKE_STEP2_process(ctx, &s2))
+ {
+ ERR_print_errors(bio_err);
+ exit(1);
+ }
+ JPAKE_STEP2_release(&s2);
+ }
+
+static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn)
+ {
+ JPAKE_STEP3A s3a;
+ int l;
+
+ JPAKE_STEP3A_init(&s3a);
+ l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk);
+ assert(l == sizeof s3a.hhk);
+ if(!JPAKE_STEP3A_process(ctx, &s3a))
+ {
+ ERR_print_errors(bio_err);
+ exit(1);
+ }
+ JPAKE_STEP3A_release(&s3a);
+ }
+
+static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn)
+ {
+ JPAKE_STEP3B s3b;
+ int l;
+
+ JPAKE_STEP3B_init(&s3b);
+ l = BIO_read(bconn, s3b.hk, sizeof s3b.hk);
+ assert(l == sizeof s3b.hk);
+ if(!JPAKE_STEP3B_process(ctx, &s3b))
+ {
+ ERR_print_errors(bio_err);
+ exit(1);
+ }
+ JPAKE_STEP3B_release(&s3b);
+ }
+
+void jpake_client_auth(BIO *out, BIO *conn, const char *secret)
+ {
+ JPAKE_CTX *ctx;
+ BIO *bconn;
+
+ BIO_puts(out, "Authenticating with JPAKE\n");
+
+ ctx = jpake_init("client", "server", secret);
+
+ bconn = BIO_new(BIO_f_buffer());
+ BIO_push(bconn, conn);
+
+ jpake_send_step1(bconn, ctx);
+ jpake_receive_step1(ctx, bconn);
+ jpake_send_step2(bconn, ctx);
+ jpake_receive_step2(ctx, bconn);
+ jpake_send_step3a(bconn, ctx);
+ jpake_receive_step3b(ctx, bconn);
+
+ BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
+
+ psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
+
+ BIO_pop(bconn);
+ BIO_free(bconn);
+
+ JPAKE_CTX_free(ctx);
+ }
+
+void jpake_server_auth(BIO *out, BIO *conn, const char *secret)
+ {
+ JPAKE_CTX *ctx;
+ BIO *bconn;
+
+ BIO_puts(out, "Authenticating with JPAKE\n");
+
+ ctx = jpake_init("server", "client", secret);
+
+ bconn = BIO_new(BIO_f_buffer());
+ BIO_push(bconn, conn);
+
+ jpake_receive_step1(ctx, bconn);
+ jpake_send_step1(bconn, ctx);
+ jpake_receive_step2(ctx, bconn);
+ jpake_send_step2(bconn, ctx);
+ jpake_receive_step3a(ctx, bconn);
+ jpake_send_step3b(bconn, ctx);
+
+ BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
+
+ psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
+
+ BIO_pop(bconn);
+ BIO_free(bconn);
+
+ JPAKE_CTX_free(ctx);
+ }
+
+#endif
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+/* next_protos_parse parses a comma separated list of strings into a string
+ * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
+ * outlen: (output) set to the length of the resulting buffer on success.
+ * err: (maybe NULL) on failure, an error message line is written to this BIO.
+ * in: a NUL termianted string like "abc,def,ghi"
+ *
+ * returns: a malloced buffer or NULL on failure.
+ */
+unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
+ {
+ size_t len;
+ unsigned char *out;
+ size_t i, start = 0;
+
+ len = strlen(in);
+ if (len >= 65535)
+ return NULL;
+
+ out = OPENSSL_malloc(strlen(in) + 1);
+ if (!out)
+ return NULL;
+
+ for (i = 0; i <= len; ++i)
+ {
+ if (i == len || in[i] == ',')
+ {
+ if (i - start > 255)
+ {
+ OPENSSL_free(out);
+ return NULL;
+ }
+ out[start] = i - start;
+ start = i + 1;
+ }
+ else
+ out[i+1] = in[i];
+ }
+
+ *outlen = len + 1;
+ return out;
+ }
+#endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
+
+/*
+ * Platform-specific sections
+ */
+#if defined(_WIN32)
+# ifdef fileno
+# undef fileno
+# define fileno(a) (int)_fileno(a)
+# endif
+
+# include <windows.h>
+# include <tchar.h>
+
+static int WIN32_rename(const char *from, const char *to)
+ {
+ TCHAR *tfrom=NULL,*tto;
+ DWORD err;
+ int ret=0;
+
+ if (sizeof(TCHAR) == 1)
+ {
+ tfrom = (TCHAR *)from;
+ tto = (TCHAR *)to;
+ }
+ else /* UNICODE path */
+ {
+ size_t i,flen=strlen(from)+1,tlen=strlen(to)+1;
+ tfrom = (TCHAR *)malloc(sizeof(TCHAR)*(flen+tlen));
+ if (tfrom==NULL) goto err;
+ tto=tfrom+flen;
+#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+ if (!MultiByteToWideChar(CP_ACP,0,from,flen,(WCHAR *)tfrom,flen))
+#endif
+ for (i=0;i<flen;i++) tfrom[i]=(TCHAR)from[i];
+#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+ if (!MultiByteToWideChar(CP_ACP,0,to, tlen,(WCHAR *)tto, tlen))
+#endif
+ for (i=0;i<tlen;i++) tto[i] =(TCHAR)to[i];
+ }
+
+ if (MoveFile(tfrom,tto)) goto ok;
+ err=GetLastError();
+ if (err==ERROR_ALREADY_EXISTS || err==ERROR_FILE_EXISTS)
+ {
+ if (DeleteFile(tto) && MoveFile(tfrom,tto))
+ goto ok;
+ err=GetLastError();
+ }
+ if (err==ERROR_FILE_NOT_FOUND || err==ERROR_PATH_NOT_FOUND)
+ errno = ENOENT;
+ else if (err==ERROR_ACCESS_DENIED)
+ errno = EACCES;
+ else
+ errno = EINVAL; /* we could map more codes... */
+err:
+ ret=-1;
+ok:
+ if (tfrom!=NULL && tfrom!=(TCHAR *)from) free(tfrom);
+ return ret;
+ }
+#endif
+
+/* app_tminterval section */
+#if defined(_WIN32)
+double app_tminterval(int stop,int usertime)
+ {
+ FILETIME now;
+ double ret=0;
+ static ULARGE_INTEGER tmstart;
+ static int warning=1;
+#ifdef _WIN32_WINNT
+ static HANDLE proc=NULL;
+
+ if (proc==NULL)
+ {
+ if (GetVersion() < 0x80000000)
+ proc = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,
+ GetCurrentProcessId());
+ if (proc==NULL) proc = (HANDLE)-1;
+ }
+
+ if (usertime && proc!=(HANDLE)-1)
+ {
+ FILETIME junk;
+ GetProcessTimes(proc,&junk,&junk,&junk,&now);
+ }
+ else
+#endif
+ {
+ SYSTEMTIME systime;
+
+ if (usertime && warning)
+ {
+ BIO_printf(bio_err,"To get meaningful results, run "
+ "this program on idle system.\n");
+ warning=0;
+ }
+ GetSystemTime(&systime);
+ SystemTimeToFileTime(&systime,&now);
+ }
+
+ if (stop==TM_START)
+ {
+ tmstart.u.LowPart = now.dwLowDateTime;
+ tmstart.u.HighPart = now.dwHighDateTime;
+ }
+ else {
+ ULARGE_INTEGER tmstop;
+
+ tmstop.u.LowPart = now.dwLowDateTime;
+ tmstop.u.HighPart = now.dwHighDateTime;
+
+ ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart)*1e-7;
+ }
+
+ return (ret);
+ }
+
+#elif defined(OPENSSL_SYS_NETWARE)
+#include <time.h>
+
+double app_tminterval(int stop,int usertime)
+ {
+ double ret=0;
+ static clock_t tmstart;
+ static int warning=1;
+
+ if (usertime && warning)
+ {
+ BIO_printf(bio_err,"To get meaningful results, run "
+ "this program on idle system.\n");
+ warning=0;
+ }
+
+ if (stop==TM_START) tmstart = clock();
+ else ret = (clock()-tmstart)/(double)CLOCKS_PER_SEC;
+
+ return (ret);
+ }
+
+#elif defined(OPENSSL_SYSTEM_VXWORKS)
+#include <time.h>
+
+double app_tminterval(int stop,int usertime)
+ {
+ double ret=0;
+#ifdef CLOCK_REALTIME
+ static struct timespec tmstart;
+ struct timespec now;
+#else
+ static unsigned long tmstart;
+ unsigned long now;
+#endif
+ static int warning=1;
+
+ if (usertime && warning)
+ {
+ BIO_printf(bio_err,"To get meaningful results, run "
+ "this program on idle system.\n");
+ warning=0;
+ }
+
+#ifdef CLOCK_REALTIME
+ clock_gettime(CLOCK_REALTIME,&now);
+ if (stop==TM_START) tmstart = now;
+ else ret = ( (now.tv_sec+now.tv_nsec*1e-9)
+ - (tmstart.tv_sec+tmstart.tv_nsec*1e-9) );
+#else
+ now = tickGet();
+ if (stop==TM_START) tmstart = now;
+ else ret = (now - tmstart)/(double)sysClkRateGet();
+#endif
+ return (ret);
+ }
+
+#elif defined(OPENSSL_SYSTEM_VMS)
+#include <time.h>
+#include <times.h>
+
+double app_tminterval(int stop,int usertime)
+ {
+ static clock_t tmstart;
+ double ret = 0;
+ clock_t now;
+#ifdef __TMS
+ struct tms rus;
+
+ now = times(&rus);
+ if (usertime) now = rus.tms_utime;
+#else
+ if (usertime)
+ now = clock(); /* sum of user and kernel times */
+ else {
+ struct timeval tv;
+ gettimeofday(&tv,NULL);
+ now = (clock_t)(
+ (unsigned long long)tv.tv_sec*CLK_TCK +
+ (unsigned long long)tv.tv_usec*(1000000/CLK_TCK)
+ );
+ }
+#endif
+ if (stop==TM_START) tmstart = now;
+ else ret = (now - tmstart)/(double)(CLK_TCK);
+
+ return (ret);
+ }
+
+#elif defined(_SC_CLK_TCK) /* by means of unistd.h */
+#include <sys/times.h>
+
+double app_tminterval(int stop,int usertime)
+ {
+ double ret = 0;
+ struct tms rus;
+ clock_t now = times(&rus);
+ static clock_t tmstart;
+
+ if (usertime) now = rus.tms_utime;
+
+ if (stop==TM_START) tmstart = now;
+ else
+ {
+ long int tck = sysconf(_SC_CLK_TCK);
+ ret = (now - tmstart)/(double)tck;
+ }
+
+ return (ret);
+ }
+
+#else
+#include <sys/time.h>
+#include <sys/resource.h>
+
+double app_tminterval(int stop,int usertime)
+ {
+ double ret = 0;
+ struct rusage rus;
+ struct timeval now;
+ static struct timeval tmstart;
+
+ if (usertime) getrusage(RUSAGE_SELF,&rus), now = rus.ru_utime;
+ else gettimeofday(&now,NULL);
+
+ if (stop==TM_START) tmstart = now;
+ else ret = ( (now.tv_sec+now.tv_usec*1e-6)
+ - (tmstart.tv_sec+tmstart.tv_usec*1e-6) );
+
+ return ret;
+ }
+#endif
+
+/* app_isdir section */
+#ifdef _WIN32
+int app_isdir(const char *name)
+ {
+ HANDLE hList;
+ WIN32_FIND_DATA FileData;
+#if defined(UNICODE) || defined(_UNICODE)
+ size_t i, len_0 = strlen(name)+1;
+
+ if (len_0 > sizeof(FileData.cFileName)/sizeof(FileData.cFileName[0]))
+ return -1;
+
+#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+ if (!MultiByteToWideChar(CP_ACP,0,name,len_0,FileData.cFileName,len_0))
+#endif
+ for (i=0;i<len_0;i++)
+ FileData.cFileName[i] = (WCHAR)name[i];
+
+ hList = FindFirstFile(FileData.cFileName,&FileData);
+#else
+ hList = FindFirstFile(name,&FileData);
+#endif
+ if (hList == INVALID_HANDLE_VALUE) return -1;
+ FindClose(hList);
+ return ((FileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0);
+ }
+#else
+#include <sys/stat.h>
+#ifndef S_ISDIR
+# if defined(_S_IFMT) && defined(_S_IFDIR)
+# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR)
+# else
+# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
+# endif
+#endif
+
+int app_isdir(const char *name)
+ {
+#if defined(S_ISDIR)
+ struct stat st;
+
+ if (stat(name,&st)==0) return S_ISDIR(st.st_mode);
+ else return -1;
+#else
+ return -1;
+#endif
+ }
+#endif
+
+/* raw_read|write section */
+#if defined(_WIN32) && defined(STD_INPUT_HANDLE)
+int raw_read_stdin(void *buf,int siz)
+ {
+ DWORD n;
+ if (ReadFile(GetStdHandle(STD_INPUT_HANDLE),buf,siz,&n,NULL))
+ return (n);
+ else return (-1);
+ }
+#else
+int raw_read_stdin(void *buf,int siz)
+ { return read(fileno(stdin),buf,siz); }
+#endif
+
+#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
+int raw_write_stdout(const void *buf,int siz)
+ {
+ DWORD n;
+ if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf,siz,&n,NULL))
+ return (n);
+ else return (-1);
+ }
+#else
+int raw_write_stdout(const void *buf,int siz)
+ { return write(fileno(stdout),buf,siz); }
+#endif
diff --git a/deps/openssl/openssl/apps/apps.h b/deps/openssl/openssl/apps/apps.h
new file mode 100644
index 000000000..c1ca99da1
--- /dev/null
+++ b/deps/openssl/openssl/apps/apps.h
@@ -0,0 +1,373 @@
+/* apps/apps.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+
+#ifndef HEADER_APPS_H
+#define HEADER_APPS_H
+
+#include "e_os.h"
+
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/lhash.h>
+#include <openssl/conf.h>
+#include <openssl/txt_db.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#ifndef OPENSSL_NO_OCSP
+#include <openssl/ocsp.h>
+#endif
+#include <openssl/ossl_typ.h>
+
+int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn);
+int app_RAND_write_file(const char *file, BIO *bio_e);
+/* When `file' is NULL, use defaults.
+ * `bio_e' is for error messages. */
+void app_RAND_allow_write_file(void);
+long app_RAND_load_files(char *file); /* `file' is a list of files to read,
+ * separated by LIST_SEPARATOR_CHAR
+ * (see e_os.h). The string is
+ * destroyed! */
+
+#ifndef MONOLITH
+
+#define MAIN(a,v) main(a,v)
+
+#ifndef NON_MAIN
+CONF *config=NULL;
+BIO *bio_err=NULL;
+#else
+extern CONF *config;
+extern BIO *bio_err;
+#endif
+
+#else
+
+#define MAIN(a,v) PROG(a,v)
+extern CONF *config;
+extern char *default_config_file;
+extern BIO *bio_err;
+
+#endif
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifdef SIGPIPE
+#define do_pipe_sig() signal(SIGPIPE,SIG_IGN)
+#else
+#define do_pipe_sig()
+#endif
+
+#ifdef OPENSSL_NO_COMP
+#define zlib_cleanup()
+#else
+#define zlib_cleanup() COMP_zlib_cleanup()
+#endif
+
+#if defined(MONOLITH) && !defined(OPENSSL_C)
+# define apps_startup() \
+ do_pipe_sig()
+# define apps_shutdown()
+#else
+# ifndef OPENSSL_NO_ENGINE
+# define apps_startup() \
+ do { do_pipe_sig(); CRYPTO_malloc_init(); \
+ ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \
+ ENGINE_load_builtin_engines(); setup_ui_method(); } while(0)
+# define apps_shutdown() \
+ do { CONF_modules_unload(1); destroy_ui_method(); \
+ OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \
+ CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
+ ERR_free_strings(); zlib_cleanup();} while(0)
+# else
+# define apps_startup() \
+ do { do_pipe_sig(); CRYPTO_malloc_init(); \
+ ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \
+ setup_ui_method(); } while(0)
+# define apps_shutdown() \
+ do { CONF_modules_unload(1); destroy_ui_method(); \
+ OBJ_cleanup(); EVP_cleanup(); \
+ CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
+ ERR_free_strings(); zlib_cleanup(); } while(0)
+# endif
+#endif
+
+#ifdef OPENSSL_SYSNAME_WIN32
+# define openssl_fdset(a,b) FD_SET((unsigned int)a, b)
+#else
+# define openssl_fdset(a,b) FD_SET(a, b)
+#endif
+
+
+typedef struct args_st
+ {
+ char **data;
+ int count;
+ } ARGS;
+
+#define PW_MIN_LENGTH 4
+typedef struct pw_cb_data
+ {
+ const void *password;
+ const char *prompt_info;
+ } PW_CB_DATA;
+
+int password_callback(char *buf, int bufsiz, int verify,
+ PW_CB_DATA *cb_data);
+
+int setup_ui_method(void);
+void destroy_ui_method(void);
+
+int should_retry(int i);
+int args_from_file(char *file, int *argc, char **argv[]);
+int str2fmt(char *s);
+void program_name(char *in,char *out,int size);
+int chopup_args(ARGS *arg,char *buf, int *argc, char **argv[]);
+#ifdef HEADER_X509_H
+int dump_cert_text(BIO *out, X509 *x);
+void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags);
+#endif
+int set_cert_ex(unsigned long *flags, const char *arg);
+int set_name_ex(unsigned long *flags, const char *arg);
+int set_ext_copy(int *copy_type, const char *arg);
+int copy_extensions(X509 *x, X509_REQ *req, int copy_type);
+int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
+int add_oid_section(BIO *err, CONF *conf);
+X509 *load_cert(BIO *err, const char *file, int format,
+ const char *pass, ENGINE *e, const char *cert_descrip);
+EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
+ const char *pass, ENGINE *e, const char *key_descrip);
+EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
+ const char *pass, ENGINE *e, const char *key_descrip);
+STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
+ const char *pass, ENGINE *e, const char *cert_descrip);
+STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
+ const char *pass, ENGINE *e, const char *cert_descrip);
+X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
+#ifndef OPENSSL_NO_ENGINE
+ENGINE *setup_engine(BIO *err, const char *engine, int debug);
+#endif
+
+#ifndef OPENSSL_NO_OCSP
+OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
+ char *host, char *path, char *port, int use_ssl,
+ STACK_OF(CONF_VALUE) *headers,
+ int req_timeout);
+#endif
+
+int load_config(BIO *err, CONF *cnf);
+char *make_config_name(void);
+
+/* Functions defined in ca.c and also used in ocsp.c */
+int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
+ ASN1_GENERALIZEDTIME **pinvtm, const char *str);
+
+#define DB_type 0
+#define DB_exp_date 1
+#define DB_rev_date 2
+#define DB_serial 3 /* index - unique */
+#define DB_file 4
+#define DB_name 5 /* index - unique when active and not disabled */
+#define DB_NUMBER 6
+
+#define DB_TYPE_REV 'R'
+#define DB_TYPE_EXP 'E'
+#define DB_TYPE_VAL 'V'
+
+typedef struct db_attr_st
+ {
+ int unique_subject;
+ } DB_ATTR;
+typedef struct ca_db_st
+ {
+ DB_ATTR attributes;
+ TXT_DB *db;
+ } CA_DB;
+
+BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai);
+int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai);
+int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix);
+int rand_serial(BIGNUM *b, ASN1_INTEGER *ai);
+CA_DB *load_index(char *dbfile, DB_ATTR *dbattr);
+int index_index(CA_DB *db);
+int save_index(const char *dbfile, const char *suffix, CA_DB *db);
+int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix);
+void free_index(CA_DB *db);
+#define index_name_cmp_noconst(a, b) \
+ index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
+ (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
+int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
+int parse_yesno(const char *str, int def);
+
+X509_NAME *parse_name(char *str, long chtype, int multirdn);
+int args_verify(char ***pargs, int *pargc,
+ int *badarg, BIO *err, X509_VERIFY_PARAM **pm);
+void policies_print(BIO *out, X509_STORE_CTX *ctx);
+int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
+int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value);
+int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
+ const char *algname, ENGINE *e, int do_param);
+int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
+ STACK_OF(OPENSSL_STRING) *sigopts);
+int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
+ STACK_OF(OPENSSL_STRING) *sigopts);
+int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
+ STACK_OF(OPENSSL_STRING) *sigopts);
+#ifndef OPENSSL_NO_PSK
+extern char *psk_key;
+#endif
+#ifndef OPENSSL_NO_JPAKE
+void jpake_client_auth(BIO *out, BIO *conn, const char *secret);
+void jpake_server_auth(BIO *out, BIO *conn, const char *secret);
+#endif
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+unsigned char *next_protos_parse(unsigned short *outlen, const char *in);
+#endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
+
+#define FORMAT_UNDEF 0
+#define FORMAT_ASN1 1
+#define FORMAT_TEXT 2
+#define FORMAT_PEM 3
+#define FORMAT_NETSCAPE 4
+#define FORMAT_PKCS12 5
+#define FORMAT_SMIME 6
+#define FORMAT_ENGINE 7
+#define FORMAT_IISSGC 8 /* XXX this stupid macro helps us to avoid
+ * adding yet another param to load_*key() */
+#define FORMAT_PEMRSA 9 /* PEM RSAPubicKey format */
+#define FORMAT_ASN1RSA 10 /* DER RSAPubicKey format */
+#define FORMAT_MSBLOB 11 /* MS Key blob format */
+#define FORMAT_PVK 12 /* MS PVK file format */
+
+#define EXT_COPY_NONE 0
+#define EXT_COPY_ADD 1
+#define EXT_COPY_ALL 2
+
+#define NETSCAPE_CERT_HDR "certificate"
+
+#define APP_PASS_LEN 1024
+
+#define SERIAL_RAND_BITS 64
+
+int app_isdir(const char *);
+int raw_read_stdin(void *,int);
+int raw_write_stdout(const void *,int);
+
+#define TM_START 0
+#define TM_STOP 1
+double app_tminterval (int stop,int usertime);
+
+#define OPENSSL_NO_SSL_INTERN
+
+#endif
diff --git a/deps/openssl/openssl/apps/asn1pars.c b/deps/openssl/openssl/apps/asn1pars.c
new file mode 100644
index 000000000..0d6607071
--- /dev/null
+++ b/deps/openssl/openssl/apps/asn1pars.c
@@ -0,0 +1,445 @@
+/* apps/asn1pars.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* A nice addition from Dr Stephen Henson <steve@openssl.org> to
+ * add the -strparse option which parses nested binary structures
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+/* -inform arg - input format - default PEM (DER or PEM)
+ * -in arg - input file - default stdin
+ * -i - indent the details by depth
+ * -offset - where in the file to start
+ * -length - how many bytes to use
+ * -oid file - extra oid description file
+ */
+
+#undef PROG
+#define PROG asn1parse_main
+
+int MAIN(int, char **);
+
+static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf);
+
+int MAIN(int argc, char **argv)
+ {
+ int i,badops=0,offset=0,ret=1,j;
+ unsigned int length=0;
+ long num,tmplen;
+ BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL;
+ int informat,indent=0, noout = 0, dump = 0;
+ char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL;
+ char *genstr=NULL, *genconf=NULL;
+ unsigned char *tmpbuf;
+ const unsigned char *ctmpbuf;
+ BUF_MEM *buf=NULL;
+ STACK_OF(OPENSSL_STRING) *osk=NULL;
+ ASN1_TYPE *at=NULL;
+
+ informat=FORMAT_PEM;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ if ((osk=sk_OPENSSL_STRING_new_null()) == NULL)
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto end;
+ }
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ derfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-i") == 0)
+ {
+ indent=1;
+ }
+ else if (strcmp(*argv,"-noout") == 0) noout = 1;
+ else if (strcmp(*argv,"-oid") == 0)
+ {
+ if (--argc < 1) goto bad;
+ oidfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-offset") == 0)
+ {
+ if (--argc < 1) goto bad;
+ offset= atoi(*(++argv));
+ }
+ else if (strcmp(*argv,"-length") == 0)
+ {
+ if (--argc < 1) goto bad;
+ length= atoi(*(++argv));
+ if (length == 0) goto bad;
+ }
+ else if (strcmp(*argv,"-dump") == 0)
+ {
+ dump= -1;
+ }
+ else if (strcmp(*argv,"-dlimit") == 0)
+ {
+ if (--argc < 1) goto bad;
+ dump= atoi(*(++argv));
+ if (dump <= 0) goto bad;
+ }
+ else if (strcmp(*argv,"-strparse") == 0)
+ {
+ if (--argc < 1) goto bad;
+ sk_OPENSSL_STRING_push(osk,*(++argv));
+ }
+ else if (strcmp(*argv,"-genstr") == 0)
+ {
+ if (--argc < 1) goto bad;
+ genstr= *(++argv);
+ }
+ else if (strcmp(*argv,"-genconf") == 0)
+ {
+ if (--argc < 1) goto bad;
+ genconf= *(++argv);
+ }
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err,"%s [options] <infile\n",prog);
+ BIO_printf(bio_err,"where options are\n");
+ BIO_printf(bio_err," -inform arg input format - one of DER PEM\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -out arg output file (output format is always DER\n");
+ BIO_printf(bio_err," -noout arg don't produce any output\n");
+ BIO_printf(bio_err," -offset arg offset into file\n");
+ BIO_printf(bio_err," -length arg length of section in file\n");
+ BIO_printf(bio_err," -i indent entries\n");
+ BIO_printf(bio_err," -dump dump unknown data in hex form\n");
+ BIO_printf(bio_err," -dlimit arg dump the first arg bytes of unknown data in hex form\n");
+ BIO_printf(bio_err," -oid file file of extra oid definitions\n");
+ BIO_printf(bio_err," -strparse offset\n");
+ BIO_printf(bio_err," a series of these can be used to 'dig' into multiple\n");
+ BIO_printf(bio_err," ASN1 blob wrappings\n");
+ BIO_printf(bio_err," -genstr str string to generate ASN1 structure from\n");
+ BIO_printf(bio_err," -genconf file file to generate ASN1 structure from\n");
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+
+ in=BIO_new(BIO_s_file());
+ out=BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+
+ if (oidfile != NULL)
+ {
+ if (BIO_read_filename(in,oidfile) <= 0)
+ {
+ BIO_printf(bio_err,"problems opening %s\n",oidfile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ OBJ_create_objects(in);
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+
+ if (derfile) {
+ if(!(derout = BIO_new_file(derfile, "wb"))) {
+ BIO_printf(bio_err,"problems opening %s\n",derfile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if ((buf=BUF_MEM_new()) == NULL) goto end;
+ if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */
+
+ if (genstr || genconf)
+ {
+ num = do_generate(bio_err, genstr, genconf, buf);
+ if (num < 0)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ else
+ {
+
+ if (informat == FORMAT_PEM)
+ {
+ BIO *tmp;
+
+ if ((b64=BIO_new(BIO_f_base64())) == NULL)
+ goto end;
+ BIO_push(b64,in);
+ tmp=in;
+ in=b64;
+ b64=tmp;
+ }
+
+ num=0;
+ for (;;)
+ {
+ if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end;
+ i=BIO_read(in,&(buf->data[num]),BUFSIZ);
+ if (i <= 0) break;
+ num+=i;
+ }
+ }
+ str=buf->data;
+
+ /* If any structs to parse go through in sequence */
+
+ if (sk_OPENSSL_STRING_num(osk))
+ {
+ tmpbuf=(unsigned char *)str;
+ tmplen=num;
+ for (i=0; i<sk_OPENSSL_STRING_num(osk); i++)
+ {
+ ASN1_TYPE *atmp;
+ int typ;
+ j=atoi(sk_OPENSSL_STRING_value(osk,i));
+ if (j == 0)
+ {
+ BIO_printf(bio_err,"'%s' is an invalid number\n",sk_OPENSSL_STRING_value(osk,i));
+ continue;
+ }
+ tmpbuf+=j;
+ tmplen-=j;
+ atmp = at;
+ ctmpbuf = tmpbuf;
+ at = d2i_ASN1_TYPE(NULL,&ctmpbuf,tmplen);
+ ASN1_TYPE_free(atmp);
+ if(!at)
+ {
+ BIO_printf(bio_err,"Error parsing structure\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ typ = ASN1_TYPE_get(at);
+ if ((typ == V_ASN1_OBJECT)
+ || (typ == V_ASN1_NULL))
+ {
+ BIO_printf(bio_err, "Can't parse %s type\n",
+ typ == V_ASN1_NULL ? "NULL" : "OBJECT");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ /* hmm... this is a little evil but it works */
+ tmpbuf=at->value.asn1_string->data;
+ tmplen=at->value.asn1_string->length;
+ }
+ str=(char *)tmpbuf;
+ num=tmplen;
+ }
+
+ if (offset >= num)
+ {
+ BIO_printf(bio_err, "Error: offset too large\n");
+ goto end;
+ }
+
+ num -= offset;
+
+ if ((length == 0) || ((long)length > num)) length=(unsigned int)num;
+ if(derout) {
+ if(BIO_write(derout, str + offset, length) != (int)length) {
+ BIO_printf(bio_err, "Error writing output\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ if (!noout &&
+ !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length,
+ indent,dump))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ ret=0;
+end:
+ BIO_free(derout);
+ if (in != NULL) BIO_free(in);
+ if (out != NULL) BIO_free_all(out);
+ if (b64 != NULL) BIO_free(b64);
+ if (ret != 0)
+ ERR_print_errors(bio_err);
+ if (buf != NULL) BUF_MEM_free(buf);
+ if (at != NULL) ASN1_TYPE_free(at);
+ if (osk != NULL) sk_OPENSSL_STRING_free(osk);
+ OBJ_cleanup();
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf)
+ {
+ CONF *cnf = NULL;
+ int len;
+ long errline;
+ unsigned char *p;
+ ASN1_TYPE *atyp = NULL;
+
+ if (genconf)
+ {
+ cnf = NCONF_new(NULL);
+ if (!NCONF_load(cnf, genconf, &errline))
+ goto conferr;
+ if (!genstr)
+ genstr = NCONF_get_string(cnf, "default", "asn1");
+ if (!genstr)
+ {
+ BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf);
+ goto err;
+ }
+ }
+
+ atyp = ASN1_generate_nconf(genstr, cnf);
+ NCONF_free(cnf);
+ cnf = NULL;
+
+ if (!atyp)
+ return -1;
+
+ len = i2d_ASN1_TYPE(atyp, NULL);
+
+ if (len <= 0)
+ goto err;
+
+ if (!BUF_MEM_grow(buf,len))
+ goto err;
+
+ p=(unsigned char *)buf->data;
+
+ i2d_ASN1_TYPE(atyp, &p);
+
+ ASN1_TYPE_free(atyp);
+ return len;
+
+ conferr:
+
+ if (errline > 0)
+ BIO_printf(bio, "Error on line %ld of config file '%s'\n",
+ errline, genconf);
+ else
+ BIO_printf(bio, "Error loading config file '%s'\n", genconf);
+
+ err:
+ NCONF_free(cnf);
+ ASN1_TYPE_free(atyp);
+
+ return -1;
+
+ }
diff --git a/deps/openssl/openssl/apps/ca-cert.srl b/deps/openssl/openssl/apps/ca-cert.srl
new file mode 100644
index 000000000..2c7456e3e
--- /dev/null
+++ b/deps/openssl/openssl/apps/ca-cert.srl
@@ -0,0 +1 @@
+07
diff --git a/deps/openssl/openssl/apps/ca-key.pem b/deps/openssl/openssl/apps/ca-key.pem
new file mode 100644
index 000000000..3a520b238
--- /dev/null
+++ b/deps/openssl/openssl/apps/ca-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCju6PLddelT+nIMm07GQwmYa/eZ2JWbsmt2gotSCqM7asFp425
+gxSK4jqhhT62UPpqDBEwvQ+fYkVv3RV0r9ReuZGv12NoS4fXsQgqO17lHA7Od0Kd
+2yNwJjKh44MxPKDt2o8iQMyZE0zlHnEFNpsP4COLTDNC6ljEEu5bk8uPsQIDAQAB
+AoGAVZmpFZsDZfr0l2S9tLLwpjRWNOlKATQkno6q2WesT0eGLQufTciY+c8ypfU6
+hyio8r5iUl/VhhdjhAtKx1mRpiotftHo/eYf8rtsrnprOnWG0bWjLjtIoMbcxGn2
+J3bN6LJmbJMjDs0eJ3KnTu646F3nDUw2oGAwmpzKXA1KAP0CQQDRvQhxk2D3Pehs
+HvG665u2pB5ipYQngEFlZO7RHJZzJOZEWSLuuMqaF/7pTfA5jiBvWqCgJeCRRInL
+21ru4dlPAkEAx9jj7BgKn5TYnMoBSSe0afjsV9oApVpN1Nacb1YDtCwy+scp3++s
+nFxlv98wxIlSdpwMUn+AUWfjiWR7Tu/G/wJBAJ/KjwZIrFVxewP0x2ILYsTRYLzz
+MS4PDsO7FB+I0i7DbBOifXS2oNSpd3I0CNMwrxFnUHzynpbOStVfN3ZL5w0CQQCa
+pwFahxBRhkJKsxhjoFJBX9yl75JoY4Wvm5Tbo9ih6UJaRx3kqfkN14L2BKYcsZgb
+KY9vmDOYy6iNfjDeWTfJAkBkfPUb8oTJ/nSP5zN6sqGxSY4krc4xLxpRmxoJ8HL2
+XfhqXkTzbU13RX9JJ/NZ8vQN9Vm2NhxRGJocQkmcdVtJ
+-----END RSA PRIVATE KEY-----
diff --git a/deps/openssl/openssl/apps/ca-req.pem b/deps/openssl/openssl/apps/ca-req.pem
new file mode 100644
index 000000000..77bf7ec30
--- /dev/null
+++ b/deps/openssl/openssl/apps/ca-req.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBmTCCAQICAQAwWzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx
+GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDExJUZXN0IENBICgx
+MDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKO7o8t116VP6cgy
+bTsZDCZhr95nYlZuya3aCi1IKoztqwWnjbmDFIriOqGFPrZQ+moMETC9D59iRW/d
+FXSv1F65ka/XY2hLh9exCCo7XuUcDs53Qp3bI3AmMqHjgzE8oO3ajyJAzJkTTOUe
+cQU2mw/gI4tMM0LqWMQS7luTy4+xAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAKlk7
+cxu9gCJN3/iQFyJXQ6YphaiQAT5VBXTx9ftRrQIjA3vxlDzPWGDy+V5Tqa7h8PtR
+5Bn00JShII2zf0hjyjKils6x/UkWmjEiwSiFp4hR70iE8XwSNEHY2P6j6nQEIpgW
+kbfgmmUqk7dl2V+ossTJ80B8SBpEhrn81V/cHxA=
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/openssl/openssl/apps/ca.c b/deps/openssl/openssl/apps/ca.c
new file mode 100644
index 000000000..1cf50e002
--- /dev/null
+++ b/deps/openssl/openssl/apps/ca.c
@@ -0,0 +1,3010 @@
+/* apps/ca.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <openssl/conf.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/txt_db.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include <openssl/ocsp.h>
+#include <openssl/pem.h>
+
+#ifndef W_OK
+# ifdef OPENSSL_SYS_VMS
+# if defined(__DECC)
+# include <unistd.h>
+# else
+# include <unixlib.h>
+# endif
+# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE)
+# include <sys/file.h>
+# endif
+#endif
+
+#include "apps.h"
+
+#ifndef W_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+#undef PROG
+#define PROG ca_main
+
+#define BASE_SECTION "ca"
+#define CONFIG_FILE "openssl.cnf"
+
+#define ENV_DEFAULT_CA "default_ca"
+
+#define STRING_MASK "string_mask"
+#define UTF8_IN "utf8"
+
+#define ENV_DIR "dir"
+#define ENV_CERTS "certs"
+#define ENV_CRL_DIR "crl_dir"
+#define ENV_CA_DB "CA_DB"
+#define ENV_NEW_CERTS_DIR "new_certs_dir"
+#define ENV_CERTIFICATE "certificate"
+#define ENV_SERIAL "serial"
+#define ENV_CRLNUMBER "crlnumber"
+#define ENV_CRL "crl"
+#define ENV_PRIVATE_KEY "private_key"
+#define ENV_RANDFILE "RANDFILE"
+#define ENV_DEFAULT_DAYS "default_days"
+#define ENV_DEFAULT_STARTDATE "default_startdate"
+#define ENV_DEFAULT_ENDDATE "default_enddate"
+#define ENV_DEFAULT_CRL_DAYS "default_crl_days"
+#define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
+#define ENV_DEFAULT_MD "default_md"
+#define ENV_DEFAULT_EMAIL_DN "email_in_dn"
+#define ENV_PRESERVE "preserve"
+#define ENV_POLICY "policy"
+#define ENV_EXTENSIONS "x509_extensions"
+#define ENV_CRLEXT "crl_extensions"
+#define ENV_MSIE_HACK "msie_hack"
+#define ENV_NAMEOPT "name_opt"
+#define ENV_CERTOPT "cert_opt"
+#define ENV_EXTCOPY "copy_extensions"
+#define ENV_UNIQUE_SUBJECT "unique_subject"
+
+#define ENV_DATABASE "database"
+
+/* Additional revocation information types */
+
+#define REV_NONE 0 /* No addditional information */
+#define REV_CRL_REASON 1 /* Value is CRL reason code */
+#define REV_HOLD 2 /* Value is hold instruction */
+#define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
+#define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
+
+static const char *ca_usage[]={
+"usage: ca args\n",
+"\n",
+" -verbose - Talk alot while doing things\n",
+" -config file - A config file\n",
+" -name arg - The particular CA definition to use\n",
+" -gencrl - Generate a new CRL\n",
+" -crldays days - Days is when the next CRL is due\n",
+" -crlhours hours - Hours is when the next CRL is due\n",
+" -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
+" -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
+" -days arg - number of days to certify the certificate for\n",
+" -md arg - md to use, one of md2, md5, sha or sha1\n",
+" -policy arg - The CA 'policy' to support\n",
+" -keyfile arg - private key file\n",
+" -keyform arg - private key file format (PEM or ENGINE)\n",
+" -key arg - key to decode the private key if it is encrypted\n",
+" -cert file - The CA certificate\n",
+" -selfsign - sign a certificate with the key associated with it\n",
+" -in file - The input PEM encoded certificate request(s)\n",
+" -out file - Where to put the output file(s)\n",
+" -outdir dir - Where to put output certificates\n",
+" -infiles .... - The last argument, requests to process\n",
+" -spkac file - File contains DN and signed public key and challenge\n",
+" -ss_cert file - File contains a self signed cert to sign\n",
+" -preserveDN - Don't re-order the DN\n",
+" -noemailDN - Don't add the EMAIL field into certificate' subject\n",
+" -batch - Don't ask questions\n",
+" -msie_hack - msie modifications to handle all those universal strings\n",
+" -revoke file - Revoke a certificate (given in file)\n",
+" -subj arg - Use arg instead of request's subject\n",
+" -utf8 - input characters are UTF8 (default ASCII)\n",
+" -multivalue-rdn - enable support for multivalued RDNs\n",
+" -extensions .. - Extension section (override value in config file)\n",
+" -extfile file - Configuration file with X509v3 extentions to add\n",
+" -crlexts .. - CRL extension section (override value in config file)\n",
+#ifndef OPENSSL_NO_ENGINE
+" -engine e - use engine e, possibly a hardware device.\n",
+#endif
+" -status serial - Shows certificate status given the serial number\n",
+" -updatedb - Updates db for expired certificates\n",
+NULL
+};
+
+#ifdef EFENCE
+extern int EF_PROTECT_FREE;
+extern int EF_PROTECT_BELOW;
+extern int EF_ALIGNMENT;
+#endif
+
+static void lookup_fail(const char *name, const char *tag);
+static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
+ const EVP_MD *dgst,STACK_OF(OPENSSL_STRING) *sigopts,
+ STACK_OF(CONF_VALUE) *policy,CA_DB *db,
+ BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate,
+ char *enddate, long days, int batch, char *ext_sect, CONF *conf,
+ int verbose, unsigned long certopt, unsigned long nameopt,
+ int default_op, int ext_copy, int selfsign);
+static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
+ const EVP_MD *dgst,STACK_OF(OPENSSL_STRING) *sigopts,
+ STACK_OF(CONF_VALUE) *policy,
+ CA_DB *db, BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn,
+ char *startdate, char *enddate, long days, int batch,
+ char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
+ unsigned long nameopt, int default_op, int ext_copy,
+ ENGINE *e);
+static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
+ const EVP_MD *dgst,STACK_OF(OPENSSL_STRING) *sigopts,
+ STACK_OF(CONF_VALUE) *policy,
+ CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn, int email_dn,
+ char *startdate, char *enddate, long days, char *ext_sect,
+ CONF *conf, int verbose, unsigned long certopt,
+ unsigned long nameopt, int default_op, int ext_copy);
+static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
+static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
+ STACK_OF(OPENSSL_STRING) *sigopts,
+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn,
+ int email_dn, char *startdate, char *enddate, long days, int batch,
+ int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
+ unsigned long certopt, unsigned long nameopt, int default_op,
+ int ext_copy, int selfsign);
+static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
+static int get_certificate_status(const char *ser_status, CA_DB *db);
+static int do_updatedb(CA_DB *db);
+static int check_time_format(const char *str);
+char *make_revocation_str(int rev_type, char *rev_arg);
+int make_revoked(X509_REVOKED *rev, const char *str);
+int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
+static CONF *conf=NULL;
+static CONF *extconf=NULL;
+static char *section=NULL;
+
+static int preserve=0;
+static int msie_hack=0;
+
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ char *key=NULL,*passargin=NULL;
+ int create_ser = 0;
+ int free_key = 0;
+ int total=0;
+ int total_done=0;
+ int badops=0;
+ int ret=1;
+ int email_dn=1;
+ int req=0;
+ int verbose=0;
+ int gencrl=0;
+ int dorevoke=0;
+ int doupdatedb=0;
+ long crldays=0;
+ long crlhours=0;
+ long crlsec=0;
+ long errorline= -1;
+ char *configfile=NULL;
+ char *md=NULL;
+ char *policy=NULL;
+ char *keyfile=NULL;
+ char *certfile=NULL;
+ int keyform=FORMAT_PEM;
+ char *infile=NULL;
+ char *spkac_file=NULL;
+ char *ss_cert_file=NULL;
+ char *ser_status=NULL;
+ EVP_PKEY *pkey=NULL;
+ int output_der = 0;
+ char *outfile=NULL;
+ char *outdir=NULL;
+ char *serialfile=NULL;
+ char *crlnumberfile=NULL;
+ char *extensions=NULL;
+ char *extfile=NULL;
+ char *subj=NULL;
+ unsigned long chtype = MBSTRING_ASC;
+ int multirdn = 0;
+ char *tmp_email_dn=NULL;
+ char *crl_ext=NULL;
+ int rev_type = REV_NONE;
+ char *rev_arg = NULL;
+ BIGNUM *serial=NULL;
+ BIGNUM *crlnumber=NULL;
+ char *startdate=NULL;
+ char *enddate=NULL;
+ long days=0;
+ int batch=0;
+ int notext=0;
+ unsigned long nameopt = 0, certopt = 0;
+ int default_op = 1;
+ int ext_copy = EXT_COPY_NONE;
+ int selfsign = 0;
+ X509 *x509=NULL, *x509p = NULL;
+ X509 *x=NULL;
+ BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
+ char *dbfile=NULL;
+ CA_DB *db=NULL;
+ X509_CRL *crl=NULL;
+ X509_REVOKED *r=NULL;
+ ASN1_TIME *tmptm;
+ ASN1_INTEGER *tmpser;
+ char *f;
+ const char *p;
+ char * const *pp;
+ int i,j;
+ const EVP_MD *dgst=NULL;
+ STACK_OF(CONF_VALUE) *attribs=NULL;
+ STACK_OF(X509) *cert_sk=NULL;
+ STACK_OF(OPENSSL_STRING) *sigopts = NULL;
+#undef BSIZE
+#define BSIZE 256
+ MS_STATIC char buf[3][BSIZE];
+ char *randfile=NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine = NULL;
+#endif
+ char *tofree=NULL;
+ DB_ATTR db_attr;
+
+#ifdef EFENCE
+EF_PROTECT_FREE=1;
+EF_PROTECT_BELOW=1;
+EF_ALIGNMENT=0;
+#endif
+
+ apps_startup();
+
+ conf = NULL;
+ key = NULL;
+ section = NULL;
+
+ preserve=0;
+ msie_hack=0;
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-verbose") == 0)
+ verbose=1;
+ else if (strcmp(*argv,"-config") == 0)
+ {
+ if (--argc < 1) goto bad;
+ configfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-name") == 0)
+ {
+ if (--argc < 1) goto bad;
+ section= *(++argv);
+ }
+ else if (strcmp(*argv,"-subj") == 0)
+ {
+ if (--argc < 1) goto bad;
+ subj= *(++argv);
+ /* preserve=1; */
+ }
+ else if (strcmp(*argv,"-utf8") == 0)
+ chtype = MBSTRING_UTF8;
+ else if (strcmp(*argv,"-create_serial") == 0)
+ create_ser = 1;
+ else if (strcmp(*argv,"-multivalue-rdn") == 0)
+ multirdn=1;
+ else if (strcmp(*argv,"-startdate") == 0)
+ {
+ if (--argc < 1) goto bad;
+ startdate= *(++argv);
+ }
+ else if (strcmp(*argv,"-enddate") == 0)
+ {
+ if (--argc < 1) goto bad;
+ enddate= *(++argv);
+ }
+ else if (strcmp(*argv,"-days") == 0)
+ {
+ if (--argc < 1) goto bad;
+ days=atoi(*(++argv));
+ }
+ else if (strcmp(*argv,"-md") == 0)
+ {
+ if (--argc < 1) goto bad;
+ md= *(++argv);
+ }
+ else if (strcmp(*argv,"-policy") == 0)
+ {
+ if (--argc < 1) goto bad;
+ policy= *(++argv);
+ }
+ else if (strcmp(*argv,"-keyfile") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keyfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-keyform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keyform=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-passin") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargin= *(++argv);
+ }
+ else if (strcmp(*argv,"-key") == 0)
+ {
+ if (--argc < 1) goto bad;
+ key= *(++argv);
+ }
+ else if (strcmp(*argv,"-cert") == 0)
+ {
+ if (--argc < 1) goto bad;
+ certfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-selfsign") == 0)
+ selfsign=1;
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ req=1;
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-outdir") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outdir= *(++argv);
+ }
+ else if (strcmp(*argv,"-sigopt") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ if (!sigopts)
+ sigopts = sk_OPENSSL_STRING_new_null();
+ if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+ goto bad;
+ }
+ else if (strcmp(*argv,"-notext") == 0)
+ notext=1;
+ else if (strcmp(*argv,"-batch") == 0)
+ batch=1;
+ else if (strcmp(*argv,"-preserveDN") == 0)
+ preserve=1;
+ else if (strcmp(*argv,"-noemailDN") == 0)
+ email_dn=0;
+ else if (strcmp(*argv,"-gencrl") == 0)
+ gencrl=1;
+ else if (strcmp(*argv,"-msie_hack") == 0)
+ msie_hack=1;
+ else if (strcmp(*argv,"-crldays") == 0)
+ {
+ if (--argc < 1) goto bad;
+ crldays= atol(*(++argv));
+ }
+ else if (strcmp(*argv,"-crlhours") == 0)
+ {
+ if (--argc < 1) goto bad;
+ crlhours= atol(*(++argv));
+ }
+ else if (strcmp(*argv,"-crlsec") == 0)
+ {
+ if (--argc < 1) goto bad;
+ crlsec = atol(*(++argv));
+ }
+ else if (strcmp(*argv,"-infiles") == 0)
+ {
+ argc--;
+ argv++;
+ req=1;
+ break;
+ }
+ else if (strcmp(*argv, "-ss_cert") == 0)
+ {
+ if (--argc < 1) goto bad;
+ ss_cert_file = *(++argv);
+ req=1;
+ }
+ else if (strcmp(*argv, "-spkac") == 0)
+ {
+ if (--argc < 1) goto bad;
+ spkac_file = *(++argv);
+ req=1;
+ }
+ else if (strcmp(*argv,"-revoke") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ dorevoke=1;
+ }
+ else if (strcmp(*argv,"-extensions") == 0)
+ {
+ if (--argc < 1) goto bad;
+ extensions= *(++argv);
+ }
+ else if (strcmp(*argv,"-extfile") == 0)
+ {
+ if (--argc < 1) goto bad;
+ extfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-status") == 0)
+ {
+ if (--argc < 1) goto bad;
+ ser_status= *(++argv);
+ }
+ else if (strcmp(*argv,"-updatedb") == 0)
+ {
+ doupdatedb=1;
+ }
+ else if (strcmp(*argv,"-crlexts") == 0)
+ {
+ if (--argc < 1) goto bad;
+ crl_ext= *(++argv);
+ }
+ else if (strcmp(*argv,"-crl_reason") == 0)
+ {
+ if (--argc < 1) goto bad;
+ rev_arg = *(++argv);
+ rev_type = REV_CRL_REASON;
+ }
+ else if (strcmp(*argv,"-crl_hold") == 0)
+ {
+ if (--argc < 1) goto bad;
+ rev_arg = *(++argv);
+ rev_type = REV_HOLD;
+ }
+ else if (strcmp(*argv,"-crl_compromise") == 0)
+ {
+ if (--argc < 1) goto bad;
+ rev_arg = *(++argv);
+ rev_type = REV_KEY_COMPROMISE;
+ }
+ else if (strcmp(*argv,"-crl_CA_compromise") == 0)
+ {
+ if (--argc < 1) goto bad;
+ rev_arg = *(++argv);
+ rev_type = REV_CA_COMPROMISE;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else
+ {
+bad:
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+ const char **pp2;
+
+ for (pp2=ca_usage; (*pp2 != NULL); pp2++)
+ BIO_printf(bio_err,"%s",*pp2);
+ goto err;
+ }
+
+ ERR_load_crypto_strings();
+
+ /*****************************************************************/
+ tofree=NULL;
+ if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
+ if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
+ if (configfile == NULL)
+ {
+ const char *s=X509_get_default_cert_area();
+ size_t len;
+
+#ifdef OPENSSL_SYS_VMS
+ len = strlen(s)+sizeof(CONFIG_FILE);
+ tofree=OPENSSL_malloc(len);
+ strcpy(tofree,s);
+#else
+ len = strlen(s)+sizeof(CONFIG_FILE)+1;
+ tofree=OPENSSL_malloc(len);
+ BUF_strlcpy(tofree,s,len);
+ BUF_strlcat(tofree,"/",len);
+#endif
+ BUF_strlcat(tofree,CONFIG_FILE,len);
+ configfile=tofree;
+ }
+
+ BIO_printf(bio_err,"Using configuration from %s\n",configfile);
+ conf = NCONF_new(NULL);
+ if (NCONF_load(conf,configfile,&errorline) <= 0)
+ {
+ if (errorline <= 0)
+ BIO_printf(bio_err,"error loading the config file '%s'\n",
+ configfile);
+ else
+ BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
+ ,errorline,configfile);
+ goto err;
+ }
+ if(tofree)
+ {
+ OPENSSL_free(tofree);
+ tofree = NULL;
+ }
+
+ if (!load_config(bio_err, conf))
+ goto err;
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ /* Lets get the config section we are using */
+ if (section == NULL)
+ {
+ section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
+ if (section == NULL)
+ {
+ lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
+ goto err;
+ }
+ }
+
+ if (conf != NULL)
+ {
+ p=NCONF_get_string(conf,NULL,"oid_file");
+ if (p == NULL)
+ ERR_clear_error();
+ if (p != NULL)
+ {
+ BIO *oid_bio;
+
+ oid_bio=BIO_new_file(p,"r");
+ if (oid_bio == NULL)
+ {
+ /*
+ BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
+ ERR_print_errors(bio_err);
+ */
+ ERR_clear_error();
+ }
+ else
+ {
+ OBJ_create_objects(oid_bio);
+ BIO_free(oid_bio);
+ }
+ }
+ if (!add_oid_section(bio_err,conf))
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ }
+
+ randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
+ if (randfile == NULL)
+ ERR_clear_error();
+ app_RAND_load_file(randfile, bio_err, 0);
+
+ f = NCONF_get_string(conf, section, STRING_MASK);
+ if (!f)
+ ERR_clear_error();
+
+ if(f && !ASN1_STRING_set_default_mask_asc(f)) {
+ BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
+ goto err;
+ }
+
+ if (chtype != MBSTRING_UTF8){
+ f = NCONF_get_string(conf, section, UTF8_IN);
+ if (!f)
+ ERR_clear_error();
+ else if (!strcmp(f, "yes"))
+ chtype = MBSTRING_UTF8;
+ }
+
+ db_attr.unique_subject = 1;
+ p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
+ if (p)
+ {
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p);
+#endif
+ db_attr.unique_subject = parse_yesno(p,1);
+ }
+ else
+ ERR_clear_error();
+#ifdef RL_DEBUG
+ if (!p)
+ BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p);
+#endif
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n",
+ db_attr.unique_subject);
+#endif
+
+ in=BIO_new(BIO_s_file());
+ out=BIO_new(BIO_s_file());
+ Sout=BIO_new(BIO_s_file());
+ Cout=BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ /*****************************************************************/
+ /* report status of cert with serial number given on command line */
+ if (ser_status)
+ {
+ if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
+ {
+ lookup_fail(section,ENV_DATABASE);
+ goto err;
+ }
+ db = load_index(dbfile,&db_attr);
+ if (db == NULL) goto err;
+
+ if (!index_index(db)) goto err;
+
+ if (get_certificate_status(ser_status,db) != 1)
+ BIO_printf(bio_err,"Error verifying serial %s!\n",
+ ser_status);
+ goto err;
+ }
+
+ /*****************************************************************/
+ /* we definitely need a private key, so let's get it */
+
+ if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
+ section,ENV_PRIVATE_KEY)) == NULL))
+ {
+ lookup_fail(section,ENV_PRIVATE_KEY);
+ goto err;
+ }
+ if (!key)
+ {
+ free_key = 1;
+ if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
+ {
+ BIO_printf(bio_err,"Error getting password\n");
+ goto err;
+ }
+ }
+ pkey = load_key(bio_err, keyfile, keyform, 0, key, e,
+ "CA private key");
+ if (key) OPENSSL_cleanse(key,strlen(key));
+ if (pkey == NULL)
+ {
+ /* load_key() has already printed an appropriate message */
+ goto err;
+ }
+
+ /*****************************************************************/
+ /* we need a certificate */
+ if (!selfsign || spkac_file || ss_cert_file || gencrl)
+ {
+ if ((certfile == NULL)
+ && ((certfile=NCONF_get_string(conf,
+ section,ENV_CERTIFICATE)) == NULL))
+ {
+ lookup_fail(section,ENV_CERTIFICATE);
+ goto err;
+ }
+ x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
+ "CA certificate");
+ if (x509 == NULL)
+ goto err;
+
+ if (!X509_check_private_key(x509,pkey))
+ {
+ BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
+ goto err;
+ }
+ }
+ if (!selfsign) x509p = x509;
+
+ f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
+ if (f == NULL)
+ ERR_clear_error();
+ if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
+ preserve=1;
+ f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
+ if (f == NULL)
+ ERR_clear_error();
+ if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
+ msie_hack=1;
+
+ f=NCONF_get_string(conf,section,ENV_NAMEOPT);
+
+ if (f)
+ {
+ if (!set_name_ex(&nameopt, f))
+ {
+ BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
+ goto err;
+ }
+ default_op = 0;
+ }
+ else
+ ERR_clear_error();
+
+ f=NCONF_get_string(conf,section,ENV_CERTOPT);
+
+ if (f)
+ {
+ if (!set_cert_ex(&certopt, f))
+ {
+ BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
+ goto err;
+ }
+ default_op = 0;
+ }
+ else
+ ERR_clear_error();
+
+ f=NCONF_get_string(conf,section,ENV_EXTCOPY);
+
+ if (f)
+ {
+ if (!set_ext_copy(&ext_copy, f))
+ {
+ BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
+ goto err;
+ }
+ }
+ else
+ ERR_clear_error();
+
+ /*****************************************************************/
+ /* lookup where to write new certificates */
+ if ((outdir == NULL) && (req))
+ {
+
+ if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
+ == NULL)
+ {
+ BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
+ goto err;
+ }
+#ifndef OPENSSL_SYS_VMS
+ /* outdir is a directory spec, but access() for VMS demands a
+ filename. In any case, stat(), below, will catch the problem
+ if outdir is not a directory spec, and the fopen() or open()
+ will catch an error if there is no write access.
+
+ Presumably, this problem could also be solved by using the DEC
+ C routines to convert the directory syntax to Unixly, and give
+ that to access(). However, time's too short to do that just
+ now.
+ */
+#ifndef _WIN32
+ if (access(outdir,R_OK|W_OK|X_OK) != 0)
+#else
+ if (_access(outdir,R_OK|W_OK|X_OK) != 0)
+#endif
+ {
+ BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
+ perror(outdir);
+ goto err;
+ }
+
+ if (app_isdir(outdir)<=0)
+ {
+ BIO_printf(bio_err,"%s need to be a directory\n",outdir);
+ perror(outdir);
+ goto err;
+ }
+#endif
+ }
+
+ /*****************************************************************/
+ /* we need to load the database file */
+ if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
+ {
+ lookup_fail(section,ENV_DATABASE);
+ goto err;
+ }
+ db = load_index(dbfile, &db_attr);
+ if (db == NULL) goto err;
+
+ /* Lets check some fields */
+ for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
+ {
+ pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
+ if ((pp[DB_type][0] != DB_TYPE_REV) &&
+ (pp[DB_rev_date][0] != '\0'))
+ {
+ BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
+ goto err;
+ }
+ if ((pp[DB_type][0] == DB_TYPE_REV) &&
+ !make_revoked(NULL, pp[DB_rev_date]))
+ {
+ BIO_printf(bio_err," in entry %d\n", i+1);
+ goto err;
+ }
+ if (!check_time_format((char *)pp[DB_exp_date]))
+ {
+ BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
+ goto err;
+ }
+ p=pp[DB_serial];
+ j=strlen(p);
+ if (*p == '-')
+ {
+ p++;
+ j--;
+ }
+ if ((j&1) || (j < 2))
+ {
+ BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
+ goto err;
+ }
+ while (*p)
+ {
+ if (!( ((*p >= '0') && (*p <= '9')) ||
+ ((*p >= 'A') && (*p <= 'F')) ||
+ ((*p >= 'a') && (*p <= 'f'))) )
+ {
+ BIO_printf(bio_err,"entry %d: bad serial number characters, char pos %ld, char is '%c'\n",i+1,(long)(p-pp[DB_serial]),*p);
+ goto err;
+ }
+ p++;
+ }
+ }
+ if (verbose)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ TXT_DB_write(out,db->db);
+ BIO_printf(bio_err,"%d entries loaded from the database\n",
+ sk_OPENSSL_PSTRING_num(db->db->data));
+ BIO_printf(bio_err,"generating index\n");
+ }
+
+ if (!index_index(db)) goto err;
+
+ /*****************************************************************/
+ /* Update the db file for expired certificates */
+ if (doupdatedb)
+ {
+ if (verbose)
+ BIO_printf(bio_err, "Updating %s ...\n",
+ dbfile);
+
+ i = do_updatedb(db);
+ if (i == -1)
+ {
+ BIO_printf(bio_err,"Malloc failure\n");
+ goto err;
+ }
+ else if (i == 0)
+ {
+ if (verbose) BIO_printf(bio_err,
+ "No entries found to mark expired\n");
+ }
+ else
+ {
+ if (!save_index(dbfile,"new",db)) goto err;
+
+ if (!rotate_index(dbfile,"new","old")) goto err;
+
+ if (verbose) BIO_printf(bio_err,
+ "Done. %d entries marked as expired\n",i);
+ }
+ }
+
+ /*****************************************************************/
+ /* Read extentions config file */
+ if (extfile)
+ {
+ extconf = NCONF_new(NULL);
+ if (NCONF_load(extconf,extfile,&errorline) <= 0)
+ {
+ if (errorline <= 0)
+ BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
+ extfile);
+ else
+ BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
+ errorline,extfile);
+ ret = 1;
+ goto err;
+ }
+
+ if (verbose)
+ BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
+
+ /* We can have sections in the ext file */
+ if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
+ extensions = "default";
+ }
+
+ /*****************************************************************/
+ if (req || gencrl)
+ {
+ if (outfile != NULL)
+ {
+ if (BIO_write_filename(Sout,outfile) <= 0)
+ {
+ perror(outfile);
+ goto err;
+ }
+ }
+ else
+ {
+ BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ Sout = BIO_push(tmpbio, Sout);
+ }
+#endif
+ }
+ }
+
+ if ((md == NULL) && ((md=NCONF_get_string(conf,
+ section,ENV_DEFAULT_MD)) == NULL))
+ {
+ lookup_fail(section,ENV_DEFAULT_MD);
+ goto err;
+ }
+
+ if (!strcmp(md, "default"))
+ {
+ int def_nid;
+ if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
+ {
+ BIO_puts(bio_err,"no default digest\n");
+ goto err;
+ }
+ md = (char *)OBJ_nid2sn(def_nid);
+ }
+
+ if ((dgst=EVP_get_digestbyname(md)) == NULL)
+ {
+ BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
+ goto err;
+ }
+
+ if (req)
+ {
+ if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
+ section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
+ {
+ if(strcmp(tmp_email_dn,"no") == 0)
+ email_dn=0;
+ }
+ if (verbose)
+ BIO_printf(bio_err,"message digest is %s\n",
+ OBJ_nid2ln(dgst->type));
+ if ((policy == NULL) && ((policy=NCONF_get_string(conf,
+ section,ENV_POLICY)) == NULL))
+ {
+ lookup_fail(section,ENV_POLICY);
+ goto err;
+ }
+ if (verbose)
+ BIO_printf(bio_err,"policy is %s\n",policy);
+
+ if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
+ == NULL)
+ {
+ lookup_fail(section,ENV_SERIAL);
+ goto err;
+ }
+
+ if (!extconf)
+ {
+ /* no '-extfile' option, so we look for extensions
+ * in the main configuration file */
+ if (!extensions)
+ {
+ extensions=NCONF_get_string(conf,section,
+ ENV_EXTENSIONS);
+ if (!extensions)
+ ERR_clear_error();
+ }
+ if (extensions)
+ {
+ /* Check syntax of file */
+ X509V3_CTX ctx;
+ X509V3_set_ctx_test(&ctx);
+ X509V3_set_nconf(&ctx, conf);
+ if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
+ NULL))
+ {
+ BIO_printf(bio_err,
+ "Error Loading extension section %s\n",
+ extensions);
+ ret = 1;
+ goto err;
+ }
+ }
+ }
+
+ if (startdate == NULL)
+ {
+ startdate=NCONF_get_string(conf,section,
+ ENV_DEFAULT_STARTDATE);
+ if (startdate == NULL)
+ ERR_clear_error();
+ }
+ if (startdate && !ASN1_TIME_set_string(NULL, startdate))
+ {
+ BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
+ goto err;
+ }
+ if (startdate == NULL) startdate="today";
+
+ if (enddate == NULL)
+ {
+ enddate=NCONF_get_string(conf,section,
+ ENV_DEFAULT_ENDDATE);
+ if (enddate == NULL)
+ ERR_clear_error();
+ }
+ if (enddate && !ASN1_TIME_set_string(NULL, enddate))
+ {
+ BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
+ goto err;
+ }
+
+ if (days == 0)
+ {
+ if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
+ days = 0;
+ }
+ if (!enddate && (days == 0))
+ {
+ BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
+ goto err;
+ }
+
+ if ((serial=load_serial(serialfile, create_ser, NULL)) == NULL)
+ {
+ BIO_printf(bio_err,"error while loading serial number\n");
+ goto err;
+ }
+ if (verbose)
+ {
+ if (BN_is_zero(serial))
+ BIO_printf(bio_err,"next serial number is 00\n");
+ else
+ {
+ if ((f=BN_bn2hex(serial)) == NULL) goto err;
+ BIO_printf(bio_err,"next serial number is %s\n",f);
+ OPENSSL_free(f);
+ }
+ }
+
+ if ((attribs=NCONF_get_section(conf,policy)) == NULL)
+ {
+ BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
+ goto err;
+ }
+
+ if ((cert_sk=sk_X509_new_null()) == NULL)
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+ if (spkac_file != NULL)
+ {
+ total++;
+ j=certify_spkac(&x,spkac_file,pkey,x509,dgst,sigopts,
+ attribs,db, serial,subj,chtype,multirdn,
+ email_dn,startdate,enddate,days,extensions,
+ conf,verbose,certopt,nameopt,default_op,ext_copy);
+ if (j < 0) goto err;
+ if (j > 0)
+ {
+ total_done++;
+ BIO_printf(bio_err,"\n");
+ if (!BN_add_word(serial,1)) goto err;
+ if (!sk_X509_push(cert_sk,x))
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+ if (outfile)
+ {
+ output_der = 1;
+ batch = 1;
+ }
+ }
+ }
+ if (ss_cert_file != NULL)
+ {
+ total++;
+ j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,sigopts,
+ attribs,
+ db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
+ extensions,conf,verbose, certopt, nameopt,
+ default_op, ext_copy, e);
+ if (j < 0) goto err;
+ if (j > 0)
+ {
+ total_done++;
+ BIO_printf(bio_err,"\n");
+ if (!BN_add_word(serial,1)) goto err;
+ if (!sk_X509_push(cert_sk,x))
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+ }
+ }
+ if (infile != NULL)
+ {
+ total++;
+ j=certify(&x,infile,pkey,x509p,dgst,sigopts, attribs,db,
+ serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
+ extensions,conf,verbose, certopt, nameopt,
+ default_op, ext_copy, selfsign);
+ if (j < 0) goto err;
+ if (j > 0)
+ {
+ total_done++;
+ BIO_printf(bio_err,"\n");
+ if (!BN_add_word(serial,1)) goto err;
+ if (!sk_X509_push(cert_sk,x))
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+ }
+ }
+ for (i=0; i<argc; i++)
+ {
+ total++;
+ j=certify(&x,argv[i],pkey,x509p,dgst,sigopts,attribs,db,
+ serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
+ extensions,conf,verbose, certopt, nameopt,
+ default_op, ext_copy, selfsign);
+ if (j < 0) goto err;
+ if (j > 0)
+ {
+ total_done++;
+ BIO_printf(bio_err,"\n");
+ if (!BN_add_word(serial,1)) goto err;
+ if (!sk_X509_push(cert_sk,x))
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+ }
+ }
+ /* we have a stack of newly certified certificates
+ * and a data base and serial number that need
+ * updating */
+
+ if (sk_X509_num(cert_sk) > 0)
+ {
+ if (!batch)
+ {
+ BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
+ (void)BIO_flush(bio_err);
+ buf[0][0]='\0';
+ if (!fgets(buf[0],10,stdin))
+ {
+ BIO_printf(bio_err,"CERTIFICATION CANCELED: I/O error\n");
+ ret=0;
+ goto err;
+ }
+ if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
+ {
+ BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
+ ret=0;
+ goto err;
+ }
+ }
+
+ BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
+
+ if (!save_serial(serialfile,"new",serial,NULL)) goto err;
+
+ if (!save_index(dbfile, "new", db)) goto err;
+ }
+
+ if (verbose)
+ BIO_printf(bio_err,"writing new certificates\n");
+ for (i=0; i<sk_X509_num(cert_sk); i++)
+ {
+ int k;
+ char *n;
+
+ x=sk_X509_value(cert_sk,i);
+
+ j=x->cert_info->serialNumber->length;
+ p=(const char *)x->cert_info->serialNumber->data;
+
+ if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
+ {
+ BIO_printf(bio_err,"certificate file name too long\n");
+ goto err;
+ }
+
+ strcpy(buf[2],outdir);
+
+#ifndef OPENSSL_SYS_VMS
+ BUF_strlcat(buf[2],"/",sizeof(buf[2]));
+#endif
+
+ n=(char *)&(buf[2][strlen(buf[2])]);
+ if (j > 0)
+ {
+ for (k=0; k<j; k++)
+ {
+ if (n >= &(buf[2][sizeof(buf[2])]))
+ break;
+ BIO_snprintf(n,
+ &buf[2][0] + sizeof(buf[2]) - n,
+ "%02X",(unsigned char)*(p++));
+ n+=2;
+ }
+ }
+ else
+ {
+ *(n++)='0';
+ *(n++)='0';
+ }
+ *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
+ *n='\0';
+ if (verbose)
+ BIO_printf(bio_err,"writing %s\n",buf[2]);
+
+ if (BIO_write_filename(Cout,buf[2]) <= 0)
+ {
+ perror(buf[2]);
+ goto err;
+ }
+ write_new_certificate(Cout,x, 0, notext);
+ write_new_certificate(Sout,x, output_der, notext);
+ }
+
+ if (sk_X509_num(cert_sk))
+ {
+ /* Rename the database and the serial file */
+ if (!rotate_serial(serialfile,"new","old")) goto err;
+
+ if (!rotate_index(dbfile,"new","old")) goto err;
+
+ BIO_printf(bio_err,"Data Base Updated\n");
+ }
+ }
+
+ /*****************************************************************/
+ if (gencrl)
+ {
+ int crl_v2 = 0;
+ if (!crl_ext)
+ {
+ crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
+ if (!crl_ext)
+ ERR_clear_error();
+ }
+ if (crl_ext)
+ {
+ /* Check syntax of file */
+ X509V3_CTX ctx;
+ X509V3_set_ctx_test(&ctx);
+ X509V3_set_nconf(&ctx, conf);
+ if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
+ {
+ BIO_printf(bio_err,
+ "Error Loading CRL extension section %s\n",
+ crl_ext);
+ ret = 1;
+ goto err;
+ }
+ }
+
+ if ((crlnumberfile=NCONF_get_string(conf,section,ENV_CRLNUMBER))
+ != NULL)
+ if ((crlnumber=load_serial(crlnumberfile,0,NULL)) == NULL)
+ {
+ BIO_printf(bio_err,"error while loading CRL number\n");
+ goto err;
+ }
+
+ if (!crldays && !crlhours && !crlsec)
+ {
+ if (!NCONF_get_number(conf,section,
+ ENV_DEFAULT_CRL_DAYS, &crldays))
+ crldays = 0;
+ if (!NCONF_get_number(conf,section,
+ ENV_DEFAULT_CRL_HOURS, &crlhours))
+ crlhours = 0;
+ ERR_clear_error();
+ }
+ if ((crldays == 0) && (crlhours == 0) && (crlsec == 0))
+ {
+ BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
+ goto err;
+ }
+
+ if (verbose) BIO_printf(bio_err,"making CRL\n");
+ if ((crl=X509_CRL_new()) == NULL) goto err;
+ if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
+
+ tmptm = ASN1_TIME_new();
+ if (!tmptm) goto err;
+ X509_gmtime_adj(tmptm,0);
+ X509_CRL_set_lastUpdate(crl, tmptm);
+ if (!X509_time_adj_ex(tmptm, crldays, crlhours*60*60 + crlsec,
+ NULL))
+ {
+ BIO_puts(bio_err, "error setting CRL nextUpdate\n");
+ goto err;
+ }
+ X509_CRL_set_nextUpdate(crl, tmptm);
+
+ ASN1_TIME_free(tmptm);
+
+ for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
+ {
+ pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
+ if (pp[DB_type][0] == DB_TYPE_REV)
+ {
+ if ((r=X509_REVOKED_new()) == NULL) goto err;
+ j = make_revoked(r, pp[DB_rev_date]);
+ if (!j) goto err;
+ if (j == 2) crl_v2 = 1;
+ if (!BN_hex2bn(&serial, pp[DB_serial]))
+ goto err;
+ tmpser = BN_to_ASN1_INTEGER(serial, NULL);
+ BN_free(serial);
+ serial = NULL;
+ if (!tmpser)
+ goto err;
+ X509_REVOKED_set_serialNumber(r, tmpser);
+ ASN1_INTEGER_free(tmpser);
+ X509_CRL_add0_revoked(crl,r);
+ }
+ }
+
+ /* sort the data so it will be written in serial
+ * number order */
+ X509_CRL_sort(crl);
+
+ /* we now have a CRL */
+ if (verbose) BIO_printf(bio_err,"signing CRL\n");
+
+ /* Add any extensions asked for */
+
+ if (crl_ext || crlnumberfile != NULL)
+ {
+ X509V3_CTX crlctx;
+ X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
+ X509V3_set_nconf(&crlctx, conf);
+
+ if (crl_ext)
+ if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
+ crl_ext, crl)) goto err;
+ if (crlnumberfile != NULL)
+ {
+ tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
+ if (!tmpser) goto err;
+ X509_CRL_add1_ext_i2d(crl,NID_crl_number,tmpser,0,0);
+ ASN1_INTEGER_free(tmpser);
+ crl_v2 = 1;
+ if (!BN_add_word(crlnumber,1)) goto err;
+ }
+ }
+ if (crl_ext || crl_v2)
+ {
+ if (!X509_CRL_set_version(crl, 1))
+ goto err; /* version 2 CRL */
+ }
+
+
+ if (crlnumberfile != NULL) /* we have a CRL number that need updating */
+ if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
+
+ if (crlnumber)
+ {
+ BN_free(crlnumber);
+ crlnumber = NULL;
+ }
+
+ if (!do_X509_CRL_sign(bio_err,crl,pkey,dgst,sigopts)) goto err;
+
+ PEM_write_bio_X509_CRL(Sout,crl);
+
+ if (crlnumberfile != NULL) /* Rename the crlnumber file */
+ if (!rotate_serial(crlnumberfile,"new","old")) goto err;
+
+ }
+ /*****************************************************************/
+ if (dorevoke)
+ {
+ if (infile == NULL)
+ {
+ BIO_printf(bio_err,"no input files\n");
+ goto err;
+ }
+ else
+ {
+ X509 *revcert;
+ revcert=load_cert(bio_err, infile, FORMAT_PEM,
+ NULL, e, infile);
+ if (revcert == NULL)
+ goto err;
+ j=do_revoke(revcert,db, rev_type, rev_arg);
+ if (j <= 0) goto err;
+ X509_free(revcert);
+
+ if (!save_index(dbfile, "new", db)) goto err;
+
+ if (!rotate_index(dbfile, "new", "old")) goto err;
+
+ BIO_printf(bio_err,"Data Base Updated\n");
+ }
+ }
+ /*****************************************************************/
+ ret=0;
+err:
+ if(tofree)
+ OPENSSL_free(tofree);
+ BIO_free_all(Cout);
+ BIO_free_all(Sout);
+ BIO_free_all(out);
+ BIO_free_all(in);
+
+ if (cert_sk)
+ sk_X509_pop_free(cert_sk,X509_free);
+
+ if (ret) ERR_print_errors(bio_err);
+ app_RAND_write_file(randfile, bio_err);
+ if (free_key && key)
+ OPENSSL_free(key);
+ BN_free(serial);
+ BN_free(crlnumber);
+ free_index(db);
+ if (sigopts)
+ sk_OPENSSL_STRING_free(sigopts);
+ EVP_PKEY_free(pkey);
+ if (x509) X509_free(x509);
+ X509_CRL_free(crl);
+ NCONF_free(conf);
+ NCONF_free(extconf);
+ OBJ_cleanup();
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+static void lookup_fail(const char *name, const char *tag)
+ {
+ BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
+ }
+
+static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+ STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+ BIGNUM *serial, char *subj,unsigned long chtype, int multirdn,
+ int email_dn, char *startdate, char *enddate,
+ long days, int batch, char *ext_sect, CONF *lconf, int verbose,
+ unsigned long certopt, unsigned long nameopt, int default_op,
+ int ext_copy, int selfsign)
+ {
+ X509_REQ *req=NULL;
+ BIO *in=NULL;
+ EVP_PKEY *pktmp=NULL;
+ int ok= -1,i;
+
+ in=BIO_new(BIO_s_file());
+
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto err;
+ }
+ if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
+ {
+ BIO_printf(bio_err,"Error reading certificate request in %s\n",
+ infile);
+ goto err;
+ }
+ if (verbose)
+ X509_REQ_print(bio_err,req);
+
+ BIO_printf(bio_err,"Check that the request matches the signature\n");
+
+ if (selfsign && !X509_REQ_check_private_key(req,pkey))
+ {
+ BIO_printf(bio_err,"Certificate request and CA private key do not match\n");
+ ok=0;
+ goto err;
+ }
+ if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
+ {
+ BIO_printf(bio_err,"error unpacking public key\n");
+ goto err;
+ }
+ i=X509_REQ_verify(req,pktmp);
+ EVP_PKEY_free(pktmp);
+ if (i < 0)
+ {
+ ok=0;
+ BIO_printf(bio_err,"Signature verification problems....\n");
+ goto err;
+ }
+ if (i == 0)
+ {
+ ok=0;
+ BIO_printf(bio_err,"Signature did not match the certificate request\n");
+ goto err;
+ }
+ else
+ BIO_printf(bio_err,"Signature ok\n");
+
+ ok=do_body(xret,pkey,x509,dgst,sigopts, policy,db,serial,subj,chtype,
+ multirdn, email_dn,
+ startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
+ certopt, nameopt, default_op, ext_copy, selfsign);
+
+err:
+ if (req != NULL) X509_REQ_free(req);
+ if (in != NULL) BIO_free(in);
+ return(ok);
+ }
+
+static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+ STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+ BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
+ long days, int batch, char *ext_sect, CONF *lconf, int verbose,
+ unsigned long certopt, unsigned long nameopt, int default_op,
+ int ext_copy, ENGINE *e)
+ {
+ X509 *req=NULL;
+ X509_REQ *rreq=NULL;
+ EVP_PKEY *pktmp=NULL;
+ int ok= -1,i;
+
+ if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
+ goto err;
+ if (verbose)
+ X509_print(bio_err,req);
+
+ BIO_printf(bio_err,"Check that the request matches the signature\n");
+
+ if ((pktmp=X509_get_pubkey(req)) == NULL)
+ {
+ BIO_printf(bio_err,"error unpacking public key\n");
+ goto err;
+ }
+ i=X509_verify(req,pktmp);
+ EVP_PKEY_free(pktmp);
+ if (i < 0)
+ {
+ ok=0;
+ BIO_printf(bio_err,"Signature verification problems....\n");
+ goto err;
+ }
+ if (i == 0)
+ {
+ ok=0;
+ BIO_printf(bio_err,"Signature did not match the certificate\n");
+ goto err;
+ }
+ else
+ BIO_printf(bio_err,"Signature ok\n");
+
+ if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
+ goto err;
+
+ ok=do_body(xret,pkey,x509,dgst,sigopts,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
+ days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
+ ext_copy, 0);
+
+err:
+ if (rreq != NULL) X509_REQ_free(rreq);
+ if (req != NULL) X509_free(req);
+ return(ok);
+ }
+
+static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
+ STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy,
+ CA_DB *db, BIGNUM *serial, char *subj,
+ unsigned long chtype, int multirdn,
+ int email_dn, char *startdate, char *enddate, long days, int batch,
+ int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
+ unsigned long certopt, unsigned long nameopt, int default_op,
+ int ext_copy, int selfsign)
+ {
+ X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
+ ASN1_UTCTIME *tm,*tmptm;
+ ASN1_STRING *str,*str2;
+ ASN1_OBJECT *obj;
+ X509 *ret=NULL;
+ X509_CINF *ci;
+ X509_NAME_ENTRY *ne;
+ X509_NAME_ENTRY *tne,*push;
+ EVP_PKEY *pktmp;
+ int ok= -1,i,j,last,nid;
+ const char *p;
+ CONF_VALUE *cv;
+ OPENSSL_STRING row[DB_NUMBER];
+ OPENSSL_STRING *irow=NULL;
+ OPENSSL_STRING *rrow=NULL;
+ char buf[25];
+
+ tmptm=ASN1_UTCTIME_new();
+ if (tmptm == NULL)
+ {
+ BIO_printf(bio_err,"malloc error\n");
+ return(0);
+ }
+
+ for (i=0; i<DB_NUMBER; i++)
+ row[i]=NULL;
+
+ if (subj)
+ {
+ X509_NAME *n = parse_name(subj, chtype, multirdn);
+
+ if (!n)
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ X509_REQ_set_subject_name(req,n);
+ req->req_info->enc.modified = 1;
+ X509_NAME_free(n);
+ }
+
+ if (default_op)
+ BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
+
+ name=X509_REQ_get_subject_name(req);
+ for (i=0; i<X509_NAME_entry_count(name); i++)
+ {
+ ne= X509_NAME_get_entry(name,i);
+ str=X509_NAME_ENTRY_get_data(ne);
+ obj=X509_NAME_ENTRY_get_object(ne);
+
+ if (msie_hack)
+ {
+ /* assume all type should be strings */
+ nid=OBJ_obj2nid(ne->object);
+
+ if (str->type == V_ASN1_UNIVERSALSTRING)
+ ASN1_UNIVERSALSTRING_to_string(str);
+
+ if ((str->type == V_ASN1_IA5STRING) &&
+ (nid != NID_pkcs9_emailAddress))
+ str->type=V_ASN1_T61STRING;
+
+ if ((nid == NID_pkcs9_emailAddress) &&
+ (str->type == V_ASN1_PRINTABLESTRING))
+ str->type=V_ASN1_IA5STRING;
+ }
+
+ /* If no EMAIL is wanted in the subject */
+ if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
+ continue;
+
+ /* check some things */
+ if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
+ (str->type != V_ASN1_IA5STRING))
+ {
+ BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
+ goto err;
+ }
+ if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
+ {
+ j=ASN1_PRINTABLE_type(str->data,str->length);
+ if ( ((j == V_ASN1_T61STRING) &&
+ (str->type != V_ASN1_T61STRING)) ||
+ ((j == V_ASN1_IA5STRING) &&
+ (str->type == V_ASN1_PRINTABLESTRING)))
+ {
+ BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
+ goto err;
+ }
+ }
+
+ if (default_op)
+ old_entry_print(bio_err, obj, str);
+ }
+
+ /* Ok, now we check the 'policy' stuff. */
+ if ((subject=X509_NAME_new()) == NULL)
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+
+ /* take a copy of the issuer name before we mess with it. */
+ if (selfsign)
+ CAname=X509_NAME_dup(name);
+ else
+ CAname=X509_NAME_dup(x509->cert_info->subject);
+ if (CAname == NULL) goto err;
+ str=str2=NULL;
+
+ for (i=0; i<sk_CONF_VALUE_num(policy); i++)
+ {
+ cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
+ if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
+ {
+ BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
+ goto err;
+ }
+ obj=OBJ_nid2obj(j);
+
+ last= -1;
+ for (;;)
+ {
+ /* lookup the object in the supplied name list */
+ j=X509_NAME_get_index_by_OBJ(name,obj,last);
+ if (j < 0)
+ {
+ if (last != -1) break;
+ tne=NULL;
+ }
+ else
+ {
+ tne=X509_NAME_get_entry(name,j);
+ }
+ last=j;
+
+ /* depending on the 'policy', decide what to do. */
+ push=NULL;
+ if (strcmp(cv->value,"optional") == 0)
+ {
+ if (tne != NULL)
+ push=tne;
+ }
+ else if (strcmp(cv->value,"supplied") == 0)
+ {
+ if (tne == NULL)
+ {
+ BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
+ goto err;
+ }
+ else
+ push=tne;
+ }
+ else if (strcmp(cv->value,"match") == 0)
+ {
+ int last2;
+
+ if (tne == NULL)
+ {
+ BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
+ goto err;
+ }
+
+ last2= -1;
+
+again2:
+ j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
+ if ((j < 0) && (last2 == -1))
+ {
+ BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
+ goto err;
+ }
+ if (j >= 0)
+ {
+ push=X509_NAME_get_entry(CAname,j);
+ str=X509_NAME_ENTRY_get_data(tne);
+ str2=X509_NAME_ENTRY_get_data(push);
+ last2=j;
+ if (ASN1_STRING_cmp(str,str2) != 0)
+ goto again2;
+ }
+ if (j < 0)
+ {
+ BIO_printf(bio_err,"The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",cv->name,((str2 == NULL)?"NULL":(char *)str2->data),((str == NULL)?"NULL":(char *)str->data));
+ goto err;
+ }
+ }
+ else
+ {
+ BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
+ goto err;
+ }
+
+ if (push != NULL)
+ {
+ if (!X509_NAME_add_entry(subject,push, -1, 0))
+ {
+ if (push != NULL)
+ X509_NAME_ENTRY_free(push);
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+ }
+ if (j < 0) break;
+ }
+ }
+
+ if (preserve)
+ {
+ X509_NAME_free(subject);
+ /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
+ subject=X509_NAME_dup(name);
+ if (subject == NULL) goto err;
+ }
+
+ if (verbose)
+ BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
+
+ /* Build the correct Subject if no e-mail is wanted in the subject */
+ /* and add it later on because of the method extensions are added (altName) */
+
+ if (email_dn)
+ dn_subject = subject;
+ else
+ {
+ X509_NAME_ENTRY *tmpne;
+ /* Its best to dup the subject DN and then delete any email
+ * addresses because this retains its structure.
+ */
+ if (!(dn_subject = X509_NAME_dup(subject)))
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+ while((i = X509_NAME_get_index_by_NID(dn_subject,
+ NID_pkcs9_emailAddress, -1)) >= 0)
+ {
+ tmpne = X509_NAME_get_entry(dn_subject, i);
+ X509_NAME_delete_entry(dn_subject, i);
+ X509_NAME_ENTRY_free(tmpne);
+ }
+ }
+
+ if (BN_is_zero(serial))
+ row[DB_serial]=BUF_strdup("00");
+ else
+ row[DB_serial]=BN_bn2hex(serial);
+ if (row[DB_serial] == NULL)
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+
+ if (db->attributes.unique_subject)
+ {
+ OPENSSL_STRING *crow=row;
+
+ rrow=TXT_DB_get_by_index(db->db,DB_name,crow);
+ if (rrow != NULL)
+ {
+ BIO_printf(bio_err,
+ "ERROR:There is already a certificate for %s\n",
+ row[DB_name]);
+ }
+ }
+ if (rrow == NULL)
+ {
+ rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
+ if (rrow != NULL)
+ {
+ BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
+ row[DB_serial]);
+ BIO_printf(bio_err," check the database/serial_file for corruption\n");
+ }
+ }
+
+ if (rrow != NULL)
+ {
+ BIO_printf(bio_err,
+ "The matching entry has the following details\n");
+ if (rrow[DB_type][0] == 'E')
+ p="Expired";
+ else if (rrow[DB_type][0] == 'R')
+ p="Revoked";
+ else if (rrow[DB_type][0] == 'V')
+ p="Valid";
+ else
+ p="\ninvalid type, Data base error\n";
+ BIO_printf(bio_err,"Type :%s\n",p);;
+ if (rrow[DB_type][0] == 'R')
+ {
+ p=rrow[DB_exp_date]; if (p == NULL) p="undef";
+ BIO_printf(bio_err,"Was revoked on:%s\n",p);
+ }
+ p=rrow[DB_exp_date]; if (p == NULL) p="undef";
+ BIO_printf(bio_err,"Expires on :%s\n",p);
+ p=rrow[DB_serial]; if (p == NULL) p="undef";
+ BIO_printf(bio_err,"Serial Number :%s\n",p);
+ p=rrow[DB_file]; if (p == NULL) p="undef";
+ BIO_printf(bio_err,"File name :%s\n",p);
+ p=rrow[DB_name]; if (p == NULL) p="undef";
+ BIO_printf(bio_err,"Subject Name :%s\n",p);
+ ok= -1; /* This is now a 'bad' error. */
+ goto err;
+ }
+
+ /* We are now totally happy, lets make and sign the certificate */
+ if (verbose)
+ BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
+
+ if ((ret=X509_new()) == NULL) goto err;
+ ci=ret->cert_info;
+
+#ifdef X509_V3
+ /* Make it an X509 v3 certificate. */
+ if (!X509_set_version(ret,2)) goto err;
+#endif
+
+ if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
+ goto err;
+ if (selfsign)
+ {
+ if (!X509_set_issuer_name(ret,subject))
+ goto err;
+ }
+ else
+ {
+ if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
+ goto err;
+ }
+
+ if (strcmp(startdate,"today") == 0)
+ X509_gmtime_adj(X509_get_notBefore(ret),0);
+ else ASN1_TIME_set_string(X509_get_notBefore(ret),startdate);
+
+ if (enddate == NULL)
+ X509_time_adj_ex(X509_get_notAfter(ret),days, 0, NULL);
+ else ASN1_TIME_set_string(X509_get_notAfter(ret),enddate);
+
+ if (!X509_set_subject_name(ret,subject)) goto err;
+
+ pktmp=X509_REQ_get_pubkey(req);
+ i = X509_set_pubkey(ret,pktmp);
+ EVP_PKEY_free(pktmp);
+ if (!i) goto err;
+
+ /* Lets add the extensions, if there are any */
+ if (ext_sect)
+ {
+ X509V3_CTX ctx;
+ if (ci->version == NULL)
+ if ((ci->version=ASN1_INTEGER_new()) == NULL)
+ goto err;
+ ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
+
+ /* Free the current entries if any, there should not
+ * be any I believe */
+ if (ci->extensions != NULL)
+ sk_X509_EXTENSION_pop_free(ci->extensions,
+ X509_EXTENSION_free);
+
+ ci->extensions = NULL;
+
+ /* Initialize the context structure */
+ if (selfsign)
+ X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
+ else
+ X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
+
+ if (extconf)
+ {
+ if (verbose)
+ BIO_printf(bio_err, "Extra configuration file found\n");
+
+ /* Use the extconf configuration db LHASH */
+ X509V3_set_nconf(&ctx, extconf);
+
+ /* Test the structure (needed?) */
+ /* X509V3_set_ctx_test(&ctx); */
+
+ /* Adds exts contained in the configuration file */
+ if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
+ {
+ BIO_printf(bio_err,
+ "ERROR: adding extensions in section %s\n",
+ ext_sect);
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ if (verbose)
+ BIO_printf(bio_err, "Successfully added extensions from file.\n");
+ }
+ else if (ext_sect)
+ {
+ /* We found extensions to be set from config file */
+ X509V3_set_nconf(&ctx, lconf);
+
+ if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
+ {
+ BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ if (verbose)
+ BIO_printf(bio_err, "Successfully added extensions from config\n");
+ }
+ }
+
+ /* Copy extensions from request (if any) */
+
+ if (!copy_extensions(ret, req, ext_copy))
+ {
+ BIO_printf(bio_err, "ERROR: adding extensions from request\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ /* Set the right value for the noemailDN option */
+ if( email_dn == 0 )
+ {
+ if (!X509_set_subject_name(ret,dn_subject)) goto err;
+ }
+
+ if (!default_op)
+ {
+ BIO_printf(bio_err, "Certificate Details:\n");
+ /* Never print signature details because signature not present */
+ certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
+ X509_print_ex(bio_err, ret, nameopt, certopt);
+ }
+
+ BIO_printf(bio_err,"Certificate is to be certified until ");
+ ASN1_TIME_print(bio_err,X509_get_notAfter(ret));
+ if (days) BIO_printf(bio_err," (%ld days)",days);
+ BIO_printf(bio_err, "\n");
+
+ if (!batch)
+ {
+
+ BIO_printf(bio_err,"Sign the certificate? [y/n]:");
+ (void)BIO_flush(bio_err);
+ buf[0]='\0';
+ if (!fgets(buf,sizeof(buf)-1,stdin))
+ {
+ BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
+ ok=0;
+ goto err;
+ }
+ if (!((buf[0] == 'y') || (buf[0] == 'Y')))
+ {
+ BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
+ ok=0;
+ goto err;
+ }
+ }
+
+ pktmp=X509_get_pubkey(ret);
+ if (EVP_PKEY_missing_parameters(pktmp) &&
+ !EVP_PKEY_missing_parameters(pkey))
+ EVP_PKEY_copy_parameters(pktmp,pkey);
+ EVP_PKEY_free(pktmp);
+
+ if (!do_X509_sign(bio_err, ret,pkey,dgst, sigopts))
+ goto err;
+
+ /* We now just add it to the database */
+ row[DB_type]=(char *)OPENSSL_malloc(2);
+
+ tm=X509_get_notAfter(ret);
+ row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
+ memcpy(row[DB_exp_date],tm->data,tm->length);
+ row[DB_exp_date][tm->length]='\0';
+
+ row[DB_rev_date]=NULL;
+
+ /* row[DB_serial] done already */
+ row[DB_file]=(char *)OPENSSL_malloc(8);
+ row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
+
+ if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
+ (row[DB_file] == NULL) || (row[DB_name] == NULL))
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+ BUF_strlcpy(row[DB_file],"unknown",8);
+ row[DB_type][0]='V';
+ row[DB_type][1]='\0';
+
+ if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+
+ for (i=0; i<DB_NUMBER; i++)
+ {
+ irow[i]=row[i];
+ row[i]=NULL;
+ }
+ irow[DB_NUMBER]=NULL;
+
+ if (!TXT_DB_insert(db->db,irow))
+ {
+ BIO_printf(bio_err,"failed to update database\n");
+ BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
+ goto err;
+ }
+ ok=1;
+err:
+ for (i=0; i<DB_NUMBER; i++)
+ if (row[i] != NULL) OPENSSL_free(row[i]);
+
+ if (CAname != NULL)
+ X509_NAME_free(CAname);
+ if (subject != NULL)
+ X509_NAME_free(subject);
+ if ((dn_subject != NULL) && !email_dn)
+ X509_NAME_free(dn_subject);
+ if (tmptm != NULL)
+ ASN1_UTCTIME_free(tmptm);
+ if (ok <= 0)
+ {
+ if (ret != NULL) X509_free(ret);
+ ret=NULL;
+ }
+ else
+ *xret=ret;
+ return(ok);
+ }
+
+static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
+ {
+
+ if (output_der)
+ {
+ (void)i2d_X509_bio(bp,x);
+ return;
+ }
+#if 0
+ /* ??? Not needed since X509_print prints all this stuff anyway */
+ f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
+ BIO_printf(bp,"issuer :%s\n",f);
+
+ f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
+ BIO_printf(bp,"subject:%s\n",f);
+
+ BIO_puts(bp,"serial :");
+ i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
+ BIO_puts(bp,"\n\n");
+#endif
+ if (!notext)X509_print(bp,x);
+ PEM_write_bio_X509(bp,x);
+ }
+
+static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+ STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+ BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
+ long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
+ unsigned long nameopt, int default_op, int ext_copy)
+ {
+ STACK_OF(CONF_VALUE) *sk=NULL;
+ LHASH_OF(CONF_VALUE) *parms=NULL;
+ X509_REQ *req=NULL;
+ CONF_VALUE *cv=NULL;
+ NETSCAPE_SPKI *spki = NULL;
+ X509_REQ_INFO *ri;
+ char *type,*buf;
+ EVP_PKEY *pktmp=NULL;
+ X509_NAME *n=NULL;
+ X509_NAME_ENTRY *ne=NULL;
+ int ok= -1,i,j;
+ long errline;
+ int nid;
+
+ /*
+ * Load input file into a hash table. (This is just an easy
+ * way to read and parse the file, then put it into a convenient
+ * STACK format).
+ */
+ parms=CONF_load(NULL,infile,&errline);
+ if (parms == NULL)
+ {
+ BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ sk=CONF_get_section(parms, "default");
+ if (sk_CONF_VALUE_num(sk) == 0)
+ {
+ BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
+ CONF_free(parms);
+ goto err;
+ }
+
+ /*
+ * Now create a dummy X509 request structure. We don't actually
+ * have an X509 request, but we have many of the components
+ * (a public key, various DN components). The idea is that we
+ * put these components into the right X509 request structure
+ * and we can use the same code as if you had a real X509 request.
+ */
+ req=X509_REQ_new();
+ if (req == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ /*
+ * Build up the subject name set.
+ */
+ ri=req->req_info;
+ n = ri->subject;
+
+ for (i = 0; ; i++)
+ {
+ if (sk_CONF_VALUE_num(sk) <= i) break;
+
+ cv=sk_CONF_VALUE_value(sk,i);
+ type=cv->name;
+ /* Skip past any leading X. X: X, etc to allow for
+ * multiple instances
+ */
+ for (buf = cv->name; *buf ; buf++)
+ if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
+ {
+ buf++;
+ if (*buf) type = buf;
+ break;
+ }
+
+ buf=cv->value;
+ if ((nid=OBJ_txt2nid(type)) == NID_undef)
+ {
+ if (strcmp(type, "SPKAC") == 0)
+ {
+ spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
+ if (spki == NULL)
+ {
+ BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ }
+ continue;
+ }
+
+ if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
+ (unsigned char *)buf, -1, -1, 0))
+ goto err;
+ }
+ if (spki == NULL)
+ {
+ BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
+ infile);
+ goto err;
+ }
+
+ /*
+ * Now extract the key from the SPKI structure.
+ */
+
+ BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
+
+ if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
+ {
+ BIO_printf(bio_err,"error unpacking SPKAC public key\n");
+ goto err;
+ }
+
+ j = NETSCAPE_SPKI_verify(spki, pktmp);
+ if (j <= 0)
+ {
+ BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
+ goto err;
+ }
+ BIO_printf(bio_err,"Signature ok\n");
+
+ X509_REQ_set_pubkey(req,pktmp);
+ EVP_PKEY_free(pktmp);
+ ok=do_body(xret,pkey,x509,dgst,sigopts,policy,db,serial,subj,chtype,
+ multirdn,email_dn,startdate,enddate, days,1,verbose,req,
+ ext_sect,lconf, certopt, nameopt, default_op, ext_copy, 0);
+err:
+ if (req != NULL) X509_REQ_free(req);
+ if (parms != NULL) CONF_free(parms);
+ if (spki != NULL) NETSCAPE_SPKI_free(spki);
+ if (ne != NULL) X509_NAME_ENTRY_free(ne);
+
+ return(ok);
+ }
+
+static int check_time_format(const char *str)
+ {
+ return ASN1_TIME_set_string(NULL, str);
+ }
+
+static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
+ {
+ ASN1_UTCTIME *tm=NULL;
+ char *row[DB_NUMBER],**rrow,**irow;
+ char *rev_str = NULL;
+ BIGNUM *bn = NULL;
+ int ok=-1,i;
+
+ for (i=0; i<DB_NUMBER; i++)
+ row[i]=NULL;
+ row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
+ bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
+ if (!bn)
+ goto err;
+ if (BN_is_zero(bn))
+ row[DB_serial]=BUF_strdup("00");
+ else
+ row[DB_serial]=BN_bn2hex(bn);
+ BN_free(bn);
+ if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+ /* We have to lookup by serial number because name lookup
+ * skips revoked certs
+ */
+ rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
+ if (rrow == NULL)
+ {
+ BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
+
+ /* We now just add it to the database */
+ row[DB_type]=(char *)OPENSSL_malloc(2);
+
+ tm=X509_get_notAfter(x509);
+ row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
+ memcpy(row[DB_exp_date],tm->data,tm->length);
+ row[DB_exp_date][tm->length]='\0';
+
+ row[DB_rev_date]=NULL;
+
+ /* row[DB_serial] done already */
+ row[DB_file]=(char *)OPENSSL_malloc(8);
+
+ /* row[DB_name] done already */
+
+ if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
+ (row[DB_file] == NULL))
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+ BUF_strlcpy(row[DB_file],"unknown",8);
+ row[DB_type][0]='V';
+ row[DB_type][1]='\0';
+
+ if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto err;
+ }
+
+ for (i=0; i<DB_NUMBER; i++)
+ {
+ irow[i]=row[i];
+ row[i]=NULL;
+ }
+ irow[DB_NUMBER]=NULL;
+
+ if (!TXT_DB_insert(db->db,irow))
+ {
+ BIO_printf(bio_err,"failed to update database\n");
+ BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
+ goto err;
+ }
+
+ /* Revoke Certificate */
+ ok = do_revoke(x509,db, type, value);
+
+ goto err;
+
+ }
+ else if (index_name_cmp_noconst(row, rrow))
+ {
+ BIO_printf(bio_err,"ERROR:name does not match %s\n",
+ row[DB_name]);
+ goto err;
+ }
+ else if (rrow[DB_type][0]=='R')
+ {
+ BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
+ row[DB_serial]);
+ goto err;
+ }
+ else
+ {
+ BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
+ rev_str = make_revocation_str(type, value);
+ if (!rev_str)
+ {
+ BIO_printf(bio_err, "Error in revocation arguments\n");
+ goto err;
+ }
+ rrow[DB_type][0]='R';
+ rrow[DB_type][1]='\0';
+ rrow[DB_rev_date] = rev_str;
+ }
+ ok=1;
+err:
+ for (i=0; i<DB_NUMBER; i++)
+ {
+ if (row[i] != NULL)
+ OPENSSL_free(row[i]);
+ }
+ return(ok);
+ }
+
+static int get_certificate_status(const char *serial, CA_DB *db)
+ {
+ char *row[DB_NUMBER],**rrow;
+ int ok=-1,i;
+
+ /* Free Resources */
+ for (i=0; i<DB_NUMBER; i++)
+ row[i]=NULL;
+
+ /* Malloc needed char spaces */
+ row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
+ if (row[DB_serial] == NULL)
+ {
+ BIO_printf(bio_err,"Malloc failure\n");
+ goto err;
+ }
+
+ if (strlen(serial) % 2)
+ {
+ /* Set the first char to 0 */;
+ row[DB_serial][0]='0';
+
+ /* Copy String from serial to row[DB_serial] */
+ memcpy(row[DB_serial]+1, serial, strlen(serial));
+ row[DB_serial][strlen(serial)+1]='\0';
+ }
+ else
+ {
+ /* Copy String from serial to row[DB_serial] */
+ memcpy(row[DB_serial], serial, strlen(serial));
+ row[DB_serial][strlen(serial)]='\0';
+ }
+
+ /* Make it Upper Case */
+ for (i=0; row[DB_serial][i] != '\0'; i++)
+ row[DB_serial][i] = toupper((unsigned char)row[DB_serial][i]);
+
+
+ ok=1;
+
+ /* Search for the certificate */
+ rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
+ if (rrow == NULL)
+ {
+ BIO_printf(bio_err,"Serial %s not present in db.\n",
+ row[DB_serial]);
+ ok=-1;
+ goto err;
+ }
+ else if (rrow[DB_type][0]=='V')
+ {
+ BIO_printf(bio_err,"%s=Valid (%c)\n",
+ row[DB_serial], rrow[DB_type][0]);
+ goto err;
+ }
+ else if (rrow[DB_type][0]=='R')
+ {
+ BIO_printf(bio_err,"%s=Revoked (%c)\n",
+ row[DB_serial], rrow[DB_type][0]);
+ goto err;
+ }
+ else if (rrow[DB_type][0]=='E')
+ {
+ BIO_printf(bio_err,"%s=Expired (%c)\n",
+ row[DB_serial], rrow[DB_type][0]);
+ goto err;
+ }
+ else if (rrow[DB_type][0]=='S')
+ {
+ BIO_printf(bio_err,"%s=Suspended (%c)\n",
+ row[DB_serial], rrow[DB_type][0]);
+ goto err;
+ }
+ else
+ {
+ BIO_printf(bio_err,"%s=Unknown (%c).\n",
+ row[DB_serial], rrow[DB_type][0]);
+ ok=-1;
+ }
+err:
+ for (i=0; i<DB_NUMBER; i++)
+ {
+ if (row[i] != NULL)
+ OPENSSL_free(row[i]);
+ }
+ return(ok);
+ }
+
+static int do_updatedb (CA_DB *db)
+ {
+ ASN1_UTCTIME *a_tm = NULL;
+ int i, cnt = 0;
+ int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
+ char **rrow, *a_tm_s;
+
+ a_tm = ASN1_UTCTIME_new();
+
+ /* get actual time and make a string */
+ a_tm = X509_gmtime_adj(a_tm, 0);
+ a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
+ if (a_tm_s == NULL)
+ {
+ cnt = -1;
+ goto err;
+ }
+
+ memcpy(a_tm_s, a_tm->data, a_tm->length);
+ a_tm_s[a_tm->length] = '\0';
+
+ if (strncmp(a_tm_s, "49", 2) <= 0)
+ a_y2k = 1;
+ else
+ a_y2k = 0;
+
+ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+ {
+ rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
+
+ if (rrow[DB_type][0] == 'V')
+ {
+ /* ignore entries that are not valid */
+ if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
+ db_y2k = 1;
+ else
+ db_y2k = 0;
+
+ if (db_y2k == a_y2k)
+ {
+ /* all on the same y2k side */
+ if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
+ {
+ rrow[DB_type][0] = 'E';
+ rrow[DB_type][1] = '\0';
+ cnt++;
+
+ BIO_printf(bio_err, "%s=Expired\n",
+ rrow[DB_serial]);
+ }
+ }
+ else if (db_y2k < a_y2k)
+ {
+ rrow[DB_type][0] = 'E';
+ rrow[DB_type][1] = '\0';
+ cnt++;
+
+ BIO_printf(bio_err, "%s=Expired\n",
+ rrow[DB_serial]);
+ }
+
+ }
+ }
+
+err:
+
+ ASN1_UTCTIME_free(a_tm);
+ OPENSSL_free(a_tm_s);
+
+ return (cnt);
+ }
+
+static const char *crl_reasons[] = {
+ /* CRL reason strings */
+ "unspecified",
+ "keyCompromise",
+ "CACompromise",
+ "affiliationChanged",
+ "superseded",
+ "cessationOfOperation",
+ "certificateHold",
+ "removeFromCRL",
+ /* Additional pseudo reasons */
+ "holdInstruction",
+ "keyTime",
+ "CAkeyTime"
+};
+
+#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
+
+/* Given revocation information convert to a DB string.
+ * The format of the string is:
+ * revtime[,reason,extra]. Where 'revtime' is the
+ * revocation time (the current time). 'reason' is the
+ * optional CRL reason and 'extra' is any additional
+ * argument
+ */
+
+char *make_revocation_str(int rev_type, char *rev_arg)
+ {
+ char *other = NULL, *str;
+ const char *reason = NULL;
+ ASN1_OBJECT *otmp;
+ ASN1_UTCTIME *revtm = NULL;
+ int i;
+ switch (rev_type)
+ {
+ case REV_NONE:
+ break;
+
+ case REV_CRL_REASON:
+ for (i = 0; i < 8; i++)
+ {
+ if (!strcasecmp(rev_arg, crl_reasons[i]))
+ {
+ reason = crl_reasons[i];
+ break;
+ }
+ }
+ if (reason == NULL)
+ {
+ BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
+ return NULL;
+ }
+ break;
+
+ case REV_HOLD:
+ /* Argument is an OID */
+
+ otmp = OBJ_txt2obj(rev_arg, 0);
+ ASN1_OBJECT_free(otmp);
+
+ if (otmp == NULL)
+ {
+ BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
+ return NULL;
+ }
+
+ reason = "holdInstruction";
+ other = rev_arg;
+ break;
+
+ case REV_KEY_COMPROMISE:
+ case REV_CA_COMPROMISE:
+
+ /* Argument is the key compromise time */
+ if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
+ {
+ BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
+ return NULL;
+ }
+ other = rev_arg;
+ if (rev_type == REV_KEY_COMPROMISE)
+ reason = "keyTime";
+ else
+ reason = "CAkeyTime";
+
+ break;
+
+ }
+
+ revtm = X509_gmtime_adj(NULL, 0);
+
+ i = revtm->length + 1;
+
+ if (reason) i += strlen(reason) + 1;
+ if (other) i += strlen(other) + 1;
+
+ str = OPENSSL_malloc(i);
+
+ if (!str) return NULL;
+
+ BUF_strlcpy(str, (char *)revtm->data, i);
+ if (reason)
+ {
+ BUF_strlcat(str, ",", i);
+ BUF_strlcat(str, reason, i);
+ }
+ if (other)
+ {
+ BUF_strlcat(str, ",", i);
+ BUF_strlcat(str, other, i);
+ }
+ ASN1_UTCTIME_free(revtm);
+ return str;
+ }
+
+/* Convert revocation field to X509_REVOKED entry
+ * return code:
+ * 0 error
+ * 1 OK
+ * 2 OK and some extensions added (i.e. V2 CRL)
+ */
+
+
+int make_revoked(X509_REVOKED *rev, const char *str)
+ {
+ char *tmp = NULL;
+ int reason_code = -1;
+ int i, ret = 0;
+ ASN1_OBJECT *hold = NULL;
+ ASN1_GENERALIZEDTIME *comp_time = NULL;
+ ASN1_ENUMERATED *rtmp = NULL;
+
+ ASN1_TIME *revDate = NULL;
+
+ i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
+
+ if (i == 0)
+ goto err;
+
+ if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
+ goto err;
+
+ if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
+ {
+ rtmp = ASN1_ENUMERATED_new();
+ if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
+ goto err;
+ if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
+ goto err;
+ }
+
+ if (rev && comp_time)
+ {
+ if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
+ goto err;
+ }
+ if (rev && hold)
+ {
+ if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
+ goto err;
+ }
+
+ if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
+ ret = 2;
+ else ret = 1;
+
+ err:
+
+ if (tmp) OPENSSL_free(tmp);
+ ASN1_OBJECT_free(hold);
+ ASN1_GENERALIZEDTIME_free(comp_time);
+ ASN1_ENUMERATED_free(rtmp);
+ ASN1_TIME_free(revDate);
+
+ return ret;
+ }
+
+int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
+ {
+ char buf[25],*pbuf, *p;
+ int j;
+ j=i2a_ASN1_OBJECT(bp,obj);
+ pbuf=buf;
+ for (j=22-j; j>0; j--)
+ *(pbuf++)=' ';
+ *(pbuf++)=':';
+ *(pbuf++)='\0';
+ BIO_puts(bp,buf);
+
+ if (str->type == V_ASN1_PRINTABLESTRING)
+ BIO_printf(bp,"PRINTABLE:'");
+ else if (str->type == V_ASN1_T61STRING)
+ BIO_printf(bp,"T61STRING:'");
+ else if (str->type == V_ASN1_IA5STRING)
+ BIO_printf(bp,"IA5STRING:'");
+ else if (str->type == V_ASN1_UNIVERSALSTRING)
+ BIO_printf(bp,"UNIVERSALSTRING:'");
+ else
+ BIO_printf(bp,"ASN.1 %2d:'",str->type);
+
+ p=(char *)str->data;
+ for (j=str->length; j>0; j--)
+ {
+ if ((*p >= ' ') && (*p <= '~'))
+ BIO_printf(bp,"%c",*p);
+ else if (*p & 0x80)
+ BIO_printf(bp,"\\0x%02X",*p);
+ else if ((unsigned char)*p == 0xf7)
+ BIO_printf(bp,"^?");
+ else BIO_printf(bp,"^%c",*p+'@');
+ p++;
+ }
+ BIO_printf(bp,"'\n");
+ return 1;
+ }
+
+int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str)
+ {
+ char *tmp = NULL;
+ char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
+ int reason_code = -1;
+ int ret = 0;
+ unsigned int i;
+ ASN1_OBJECT *hold = NULL;
+ ASN1_GENERALIZEDTIME *comp_time = NULL;
+ tmp = BUF_strdup(str);
+
+ p = strchr(tmp, ',');
+
+ rtime_str = tmp;
+
+ if (p)
+ {
+ *p = '\0';
+ p++;
+ reason_str = p;
+ p = strchr(p, ',');
+ if (p)
+ {
+ *p = '\0';
+ arg_str = p + 1;
+ }
+ }
+
+ if (prevtm)
+ {
+ *prevtm = ASN1_UTCTIME_new();
+ if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
+ {
+ BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
+ goto err;
+ }
+ }
+ if (reason_str)
+ {
+ for (i = 0; i < NUM_REASONS; i++)
+ {
+ if(!strcasecmp(reason_str, crl_reasons[i]))
+ {
+ reason_code = i;
+ break;
+ }
+ }
+ if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
+ {
+ BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
+ goto err;
+ }
+
+ if (reason_code == 7)
+ reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
+ else if (reason_code == 8) /* Hold instruction */
+ {
+ if (!arg_str)
+ {
+ BIO_printf(bio_err, "missing hold instruction\n");
+ goto err;
+ }
+ reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
+ hold = OBJ_txt2obj(arg_str, 0);
+
+ if (!hold)
+ {
+ BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
+ goto err;
+ }
+ if (phold) *phold = hold;
+ }
+ else if ((reason_code == 9) || (reason_code == 10))
+ {
+ if (!arg_str)
+ {
+ BIO_printf(bio_err, "missing compromised time\n");
+ goto err;
+ }
+ comp_time = ASN1_GENERALIZEDTIME_new();
+ if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
+ {
+ BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
+ goto err;
+ }
+ if (reason_code == 9)
+ reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
+ else
+ reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
+ }
+ }
+
+ if (preason) *preason = reason_code;
+ if (pinvtm) *pinvtm = comp_time;
+ else ASN1_GENERALIZEDTIME_free(comp_time);
+
+ ret = 1;
+
+ err:
+
+ if (tmp) OPENSSL_free(tmp);
+ if (!phold) ASN1_OBJECT_free(hold);
+ if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
+
+ return ret;
+ }
diff --git a/deps/openssl/openssl/apps/cert.pem b/deps/openssl/openssl/apps/cert.pem
new file mode 100644
index 000000000..de4a77ac6
--- /dev/null
+++ b/deps/openssl/openssl/apps/cert.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBoDCCAUoCAQAwDQYJKoZIhvcNAQEEBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD
+VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw05NzA5MDkwMzQxMjZa
+Fw05NzEwMDkwMzQxMjZaMF4xCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0
+YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFzAVBgNVBAMT
+DkVyaWMgdGhlIFlvdW5nMFEwCQYFKw4DAgwFAANEAAJBALVEqPODnpI4rShlY8S7
+tB713JNvabvn6Gned7zylwLLiXQAo/PAT6mfdWPTyCX9RlId/Aroh1ou893BA32Q
+sggwDQYJKoZIhvcNAQEEBQADQQCU5SSgapJSdRXJoX+CpCvFy+JVh9HpSjCpSNKO
+19raHv98hKAUJuP9HyM+SUsffO6mAIgitUaqW8/wDMePhEC3
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/apps/ciphers.c b/deps/openssl/openssl/apps/ciphers.c
new file mode 100644
index 000000000..5f2b73970
--- /dev/null
+++ b/deps/openssl/openssl/apps/ciphers.c
@@ -0,0 +1,231 @@
+/* apps/ciphers.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+#undef PROG
+#define PROG ciphers_main
+
+static const char *ciphers_usage[]={
+"usage: ciphers args\n",
+" -v - verbose mode, a textual listing of the SSL/TLS ciphers in OpenSSL\n",
+" -V - even more verbose\n",
+" -ssl2 - SSL2 mode\n",
+" -ssl3 - SSL3 mode\n",
+" -tls1 - TLS1 mode\n",
+NULL
+};
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ int ret=1,i;
+ int verbose=0,Verbose=0;
+ const char **pp;
+ const char *p;
+ int badops=0;
+ SSL_CTX *ctx=NULL;
+ SSL *ssl=NULL;
+ char *ciphers=NULL;
+ const SSL_METHOD *meth=NULL;
+ STACK_OF(SSL_CIPHER) *sk;
+ char buf[512];
+ BIO *STDout=NULL;
+
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+ meth=SSLv23_server_method();
+#elif !defined(OPENSSL_NO_SSL3)
+ meth=SSLv3_server_method();
+#elif !defined(OPENSSL_NO_SSL2)
+ meth=SSLv2_server_method();
+#endif
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+ STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ STDout = BIO_push(tmpbio, STDout);
+ }
+#endif
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-v") == 0)
+ verbose=1;
+ else if (strcmp(*argv,"-V") == 0)
+ verbose=Verbose=1;
+#ifndef OPENSSL_NO_SSL2
+ else if (strcmp(*argv,"-ssl2") == 0)
+ meth=SSLv2_client_method();
+#endif
+#ifndef OPENSSL_NO_SSL3
+ else if (strcmp(*argv,"-ssl3") == 0)
+ meth=SSLv3_client_method();
+#endif
+#ifndef OPENSSL_NO_TLS1
+ else if (strcmp(*argv,"-tls1") == 0)
+ meth=TLSv1_client_method();
+#endif
+ else if ((strncmp(*argv,"-h",2) == 0) ||
+ (strcmp(*argv,"-?") == 0))
+ {
+ badops=1;
+ break;
+ }
+ else
+ {
+ ciphers= *argv;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+ for (pp=ciphers_usage; (*pp != NULL); pp++)
+ BIO_printf(bio_err,"%s",*pp);
+ goto end;
+ }
+
+ OpenSSL_add_ssl_algorithms();
+
+ ctx=SSL_CTX_new(meth);
+ if (ctx == NULL) goto err;
+ if (ciphers != NULL) {
+ if(!SSL_CTX_set_cipher_list(ctx,ciphers)) {
+ BIO_printf(bio_err, "Error in cipher list\n");
+ goto err;
+ }
+ }
+ ssl=SSL_new(ctx);
+ if (ssl == NULL) goto err;
+
+
+ if (!verbose)
+ {
+ for (i=0; ; i++)
+ {
+ p=SSL_get_cipher_list(ssl,i);
+ if (p == NULL) break;
+ if (i != 0) BIO_printf(STDout,":");
+ BIO_printf(STDout,"%s",p);
+ }
+ BIO_printf(STDout,"\n");
+ }
+ else /* verbose */
+ {
+ sk=SSL_get_ciphers(ssl);
+
+ for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
+ {
+ SSL_CIPHER *c;
+
+ c = sk_SSL_CIPHER_value(sk,i);
+
+ if (Verbose)
+ {
+ unsigned long id = SSL_CIPHER_get_id(c);
+ int id0 = (int)(id >> 24);
+ int id1 = (int)((id >> 16) & 0xffL);
+ int id2 = (int)((id >> 8) & 0xffL);
+ int id3 = (int)(id & 0xffL);
+
+ if ((id & 0xff000000L) == 0x02000000L)
+ BIO_printf(STDout, " 0x%02X,0x%02X,0x%02X - ", id1, id2, id3); /* SSL2 cipher */
+ else if ((id & 0xff000000L) == 0x03000000L)
+ BIO_printf(STDout, " 0x%02X,0x%02X - ", id2, id3); /* SSL3 cipher */
+ else
+ BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */
+ }
+
+ BIO_puts(STDout,SSL_CIPHER_description(c,buf,sizeof buf));
+ }
+ }
+
+ ret=0;
+ if (0)
+ {
+err:
+ SSL_load_error_strings();
+ ERR_print_errors(bio_err);
+ }
+end:
+ if (ctx != NULL) SSL_CTX_free(ctx);
+ if (ssl != NULL) SSL_free(ssl);
+ if (STDout != NULL) BIO_free_all(STDout);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
diff --git a/deps/openssl/openssl/apps/client.pem b/deps/openssl/openssl/apps/client.pem
new file mode 100644
index 000000000..e7a47a73f
--- /dev/null
+++ b/deps/openssl/openssl/apps/client.pem
@@ -0,0 +1,52 @@
+subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Client Cert
+issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA
+-----BEGIN CERTIFICATE-----
+MIID5zCCAs+gAwIBAgIJALnu1NlVpZ6yMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT
+VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt
+ZWRpYXRlIENBMB4XDTExMTIwODE0MDE0OFoXDTIxMTAxNjE0MDE0OFowZDELMAkG
+A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU
+RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgQ2xpZW50IENlcnQw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0ranbHRLcLVqN+0BzcZpY
++yOLqxzDWT1LD9eW1stC4NzXX9/DCtSIVyN7YIHdGLrIPr64IDdXXaMRzgZ2rOKs
+lmHCAiFpO/ja99gGCJRxH0xwQatqAULfJVHeUhs7OEGOZc2nWifjqKvGfNTilP7D
+nwi69ipQFq9oS19FmhwVHk2wg7KZGHI1qDyG04UrfCZMRitvS9+UVhPpIPjuiBi2
+x3/FZIpL5gXJvvFK6xHY63oq2asyzBATntBgnP4qJFWWcvRx24wF1PnZabxuVoL2
+bPnQ/KvONDrw3IdqkKhYNTul7jEcu3OlcZIMw+7DiaKJLAzKb/bBF5gm/pwW6As9
+AgMBAAGjgY8wgYwwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwLAYJYIZI
+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
+BBSZHKyLoTh7Mb409Zn/mK1ceSDAjDAfBgNVHSMEGDAWgBQ2w2yI55X+sL3szj49
+hqshgYfa2jANBgkqhkiG9w0BAQUFAAOCAQEAD0mL7PtPYgCEuDyOQSbLpeND5hVS
+curxQdGnrJ6Acrhodb7E9ccATokeb0PLx6HBLQUicxhTZIQ9FbO43YkQcOU6C3BB
+IlwskqmtN6+VmrQzNolHCDzvxNZs9lYL2VbGPGqVRyjZeHpoAlf9cQr8PgDb4d4b
+vUx2KAhHQvV2nkmYvKyXcgnRuHggumF87mkxidriGAEFwH4qfOqetUg64WyxP7P2
+QLipm04SyQa7ONtIApfVXgHcE42Py4/f4arzCzMjKe3VyhGkS7nsT55X/fWgTaRm
+CQPkO+H94P958WTvQDt77bQ+D3IvYaVvfil8n6HJMOJfFT0LJuSUbpSXJg==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAtK2p2x0S3C1ajftAc3GaWPsji6scw1k9Sw/XltbLQuDc11/f
+wwrUiFcje2CB3Ri6yD6+uCA3V12jEc4GdqzirJZhwgIhaTv42vfYBgiUcR9McEGr
+agFC3yVR3lIbOzhBjmXNp1on46irxnzU4pT+w58IuvYqUBavaEtfRZocFR5NsIOy
+mRhyNag8htOFK3wmTEYrb0vflFYT6SD47ogYtsd/xWSKS+YFyb7xSusR2Ot6Ktmr
+MswQE57QYJz+KiRVlnL0cduMBdT52Wm8blaC9mz50PyrzjQ68NyHapCoWDU7pe4x
+HLtzpXGSDMPuw4miiSwMym/2wReYJv6cFugLPQIDAQABAoIBAAZOyc9MhIwLSU4L
+p4RgQvM4UVVe8/Id+3XTZ8NsXExJbWxXfIhiqGjaIfL8u4vsgRjcl+v1s/jo2/iT
+KMab4o4D8gXD7UavQVDjtjb/ta79WL3SjRl2Uc9YjjMkyq6WmDNQeo2NKDdafCTB
+1uzSJtLNipB8Z53ELPuHJhxX9QMHrMnuha49riQgXZ7buP9iQrHJFhImBjSzbxJx
+L+TI6rkyLSf9Wi0Pd3L27Ob3QWNfNRYNSeTE+08eSRChkur5W0RuXAcuAICdQlCl
+LBvWO/LmmvbzCqiDcgy/TliSb6CGGwgiNG7LJZmlkYNj8laGwalNlYZs3UrVv6NO
+Br2loAECgYEA2kvCvPGj0Dg/6g7WhXDvAkEbcaL1tSeCxBbNH+6HS2UWMWvyTtCn
+/bbD519QIdkvayy1QjEf32GV/UjUVmlULMLBcDy0DGjtL3+XpIhLKWDNxN1v1/ai
+1oz23ZJCOgnk6K4qtFtlRS1XtynjA+rBetvYvLP9SKeFrnpzCgaA2r0CgYEA0+KX
+1ACXDTNH5ySX3kMjSS9xdINf+OOw4CvPHFwbtc9aqk2HePlEsBTz5I/W3rKwXva3
+NqZ/bRqVVeZB/hHKFywgdUQk2Uc5z/S7Lw70/w1HubNTXGU06Ngb6zOFAo/o/TwZ
+zTP1BMIKSOB6PAZPS3l+aLO4FRIRotfFhgRHOoECgYEAmiZbqt8cJaJDB/5YYDzC
+mp3tSk6gIb936Q6M5VqkMYp9pIKsxhk0N8aDCnTU+kIK6SzWBpr3/d9Ecmqmfyq7
+5SvWO3KyVf0WWK9KH0abhOm2BKm2HBQvI0DB5u8sUx2/hsvOnjPYDISbZ11t0MtK
+u35Zy89yMYcSsIYJjG/ROCUCgYEAgI2P9G5PNxEP5OtMwOsW84Y3Xat/hPAQFlI+
+HES+AzbFGWJkeT8zL2nm95tVkFP1sggZ7Kxjz3w7cpx7GX0NkbWSE9O+T51pNASV
+tN1sQ3p5M+/a+cnlqgfEGJVvc7iAcXQPa3LEi5h2yPR49QYXAgG6cifn3dDSpmwn
+SUI7PQECgYEApGCIIpSRPLAEHTGmP87RBL1smurhwmy2s/pghkvUkWehtxg0sGHh
+kuaqDWcskogv+QC0sVdytiLSz8G0DwcEcsHK1Fkyb8A+ayiw6jWJDo2m9+IF4Fww
+1Te6jFPYDESnbhq7+TLGgHGhtwcu5cnb4vSuYXGXKupZGzoLOBbv1Zw=
+-----END RSA PRIVATE KEY-----
diff --git a/deps/openssl/openssl/apps/cms.c b/deps/openssl/openssl/apps/cms.c
new file mode 100644
index 000000000..5f77f8fbb
--- /dev/null
+++ b/deps/openssl/openssl/apps/cms.c
@@ -0,0 +1,1397 @@
+/* apps/cms.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 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
+ * licensing@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.
+ * ====================================================================
+ */
+
+/* CMS utility function */
+
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+
+#ifndef OPENSSL_NO_CMS
+
+#include <openssl/crypto.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/x509v3.h>
+#include <openssl/cms.h>
+
+#undef PROG
+#define PROG cms_main
+static int save_certs(char *signerfile, STACK_OF(X509) *signers);
+static int cms_cb(int ok, X509_STORE_CTX *ctx);
+static void receipt_request_print(BIO *out, CMS_ContentInfo *cms);
+static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to,
+ int rr_allorfirst,
+ STACK_OF(OPENSSL_STRING) *rr_from);
+
+#define SMIME_OP 0x10
+#define SMIME_IP 0x20
+#define SMIME_SIGNERS 0x40
+#define SMIME_ENCRYPT (1 | SMIME_OP)
+#define SMIME_DECRYPT (2 | SMIME_IP)
+#define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_VERIFY (4 | SMIME_IP)
+#define SMIME_CMSOUT (5 | SMIME_IP | SMIME_OP)
+#define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_DATAOUT (7 | SMIME_IP)
+#define SMIME_DATA_CREATE (8 | SMIME_OP)
+#define SMIME_DIGEST_VERIFY (9 | SMIME_IP)
+#define SMIME_DIGEST_CREATE (10 | SMIME_OP)
+#define SMIME_UNCOMPRESS (11 | SMIME_IP)
+#define SMIME_COMPRESS (12 | SMIME_OP)
+#define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP)
+#define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP)
+#define SMIME_SIGN_RECEIPT (15 | SMIME_IP | SMIME_OP)
+#define SMIME_VERIFY_RECEIPT (16 | SMIME_IP)
+
+int verify_err = 0;
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ int operation = 0;
+ int ret = 0;
+ char **args;
+ const char *inmode = "r", *outmode = "w";
+ char *infile = NULL, *outfile = NULL, *rctfile = NULL;
+ char *signerfile = NULL, *recipfile = NULL;
+ STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
+ char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
+ char *certsoutfile = NULL;
+ const EVP_CIPHER *cipher = NULL;
+ CMS_ContentInfo *cms = NULL, *rcms = NULL;
+ X509_STORE *store = NULL;
+ X509 *cert = NULL, *recip = NULL, *signer = NULL;
+ EVP_PKEY *key = NULL;
+ STACK_OF(X509) *encerts = NULL, *other = NULL;
+ BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
+ int badarg = 0;
+ int flags = CMS_DETACHED, noout = 0, print = 0;
+ int verify_retcode = 0;
+ int rr_print = 0, rr_allorfirst = -1;
+ STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL;
+ CMS_ReceiptRequest *rr = NULL;
+ char *to = NULL, *from = NULL, *subject = NULL;
+ char *CAfile = NULL, *CApath = NULL;
+ char *passargin = NULL, *passin = NULL;
+ char *inrand = NULL;
+ int need_rand = 0;
+ const EVP_MD *sign_md = NULL;
+ int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
+ int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+ unsigned char *secret_key = NULL, *secret_keyid = NULL;
+ unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
+ size_t secret_keylen = 0, secret_keyidlen = 0;
+
+ ASN1_OBJECT *econtent_type = NULL;
+
+ X509_VERIFY_PARAM *vpm = NULL;
+
+ args = argv + 1;
+ ret = 1;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ {
+ if ((bio_err = BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
+ }
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ while (!badarg && *args && *args[0] == '-')
+ {
+ if (!strcmp (*args, "-encrypt"))
+ operation = SMIME_ENCRYPT;
+ else if (!strcmp (*args, "-decrypt"))
+ operation = SMIME_DECRYPT;
+ else if (!strcmp (*args, "-sign"))
+ operation = SMIME_SIGN;
+ else if (!strcmp (*args, "-sign_receipt"))
+ operation = SMIME_SIGN_RECEIPT;
+ else if (!strcmp (*args, "-resign"))
+ operation = SMIME_RESIGN;
+ else if (!strcmp (*args, "-verify"))
+ operation = SMIME_VERIFY;
+ else if (!strcmp (*args, "-verify_retcode"))
+ verify_retcode = 1;
+ else if (!strcmp(*args,"-verify_receipt"))
+ {
+ operation = SMIME_VERIFY_RECEIPT;
+ if (!args[1])
+ goto argerr;
+ args++;
+ rctfile = *args;
+ }
+ else if (!strcmp (*args, "-cmsout"))
+ operation = SMIME_CMSOUT;
+ else if (!strcmp (*args, "-data_out"))
+ operation = SMIME_DATAOUT;
+ else if (!strcmp (*args, "-data_create"))
+ operation = SMIME_DATA_CREATE;
+ else if (!strcmp (*args, "-digest_verify"))
+ operation = SMIME_DIGEST_VERIFY;
+ else if (!strcmp (*args, "-digest_create"))
+ operation = SMIME_DIGEST_CREATE;
+ else if (!strcmp (*args, "-compress"))
+ operation = SMIME_COMPRESS;
+ else if (!strcmp (*args, "-uncompress"))
+ operation = SMIME_UNCOMPRESS;
+ else if (!strcmp (*args, "-EncryptedData_decrypt"))
+ operation = SMIME_ENCRYPTED_DECRYPT;
+ else if (!strcmp (*args, "-EncryptedData_encrypt"))
+ operation = SMIME_ENCRYPTED_ENCRYPT;
+#ifndef OPENSSL_NO_DES
+ else if (!strcmp (*args, "-des3"))
+ cipher = EVP_des_ede3_cbc();
+ else if (!strcmp (*args, "-des"))
+ cipher = EVP_des_cbc();
+#endif
+#ifndef OPENSSL_NO_SEED
+ else if (!strcmp (*args, "-seed"))
+ cipher = EVP_seed_cbc();
+#endif
+#ifndef OPENSSL_NO_RC2
+ else if (!strcmp (*args, "-rc2-40"))
+ cipher = EVP_rc2_40_cbc();
+ else if (!strcmp (*args, "-rc2-128"))
+ cipher = EVP_rc2_cbc();
+ else if (!strcmp (*args, "-rc2-64"))
+ cipher = EVP_rc2_64_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+ else if (!strcmp(*args,"-aes128"))
+ cipher = EVP_aes_128_cbc();
+ else if (!strcmp(*args,"-aes192"))
+ cipher = EVP_aes_192_cbc();
+ else if (!strcmp(*args,"-aes256"))
+ cipher = EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ else if (!strcmp(*args,"-camellia128"))
+ cipher = EVP_camellia_128_cbc();
+ else if (!strcmp(*args,"-camellia192"))
+ cipher = EVP_camellia_192_cbc();
+ else if (!strcmp(*args,"-camellia256"))
+ cipher = EVP_camellia_256_cbc();
+#endif
+ else if (!strcmp (*args, "-debug_decrypt"))
+ flags |= CMS_DEBUG_DECRYPT;
+ else if (!strcmp (*args, "-text"))
+ flags |= CMS_TEXT;
+ else if (!strcmp (*args, "-nointern"))
+ flags |= CMS_NOINTERN;
+ else if (!strcmp (*args, "-noverify")
+ || !strcmp (*args, "-no_signer_cert_verify"))
+ flags |= CMS_NO_SIGNER_CERT_VERIFY;
+ else if (!strcmp (*args, "-nocerts"))
+ flags |= CMS_NOCERTS;
+ else if (!strcmp (*args, "-noattr"))
+ flags |= CMS_NOATTR;
+ else if (!strcmp (*args, "-nodetach"))
+ flags &= ~CMS_DETACHED;
+ else if (!strcmp (*args, "-nosmimecap"))
+ flags |= CMS_NOSMIMECAP;
+ else if (!strcmp (*args, "-binary"))
+ flags |= CMS_BINARY;
+ else if (!strcmp (*args, "-keyid"))
+ flags |= CMS_USE_KEYID;
+ else if (!strcmp (*args, "-nosigs"))
+ flags |= CMS_NOSIGS;
+ else if (!strcmp (*args, "-no_content_verify"))
+ flags |= CMS_NO_CONTENT_VERIFY;
+ else if (!strcmp (*args, "-no_attr_verify"))
+ flags |= CMS_NO_ATTR_VERIFY;
+ else if (!strcmp (*args, "-stream"))
+ flags |= CMS_STREAM;
+ else if (!strcmp (*args, "-indef"))
+ flags |= CMS_STREAM;
+ else if (!strcmp (*args, "-noindef"))
+ flags &= ~CMS_STREAM;
+ else if (!strcmp (*args, "-nooldmime"))
+ flags |= CMS_NOOLDMIMETYPE;
+ else if (!strcmp (*args, "-crlfeol"))
+ flags |= CMS_CRLFEOL;
+ else if (!strcmp (*args, "-noout"))
+ noout = 1;
+ else if (!strcmp (*args, "-receipt_request_print"))
+ rr_print = 1;
+ else if (!strcmp (*args, "-receipt_request_all"))
+ rr_allorfirst = 0;
+ else if (!strcmp (*args, "-receipt_request_first"))
+ rr_allorfirst = 1;
+ else if (!strcmp(*args,"-receipt_request_from"))
+ {
+ if (!args[1])
+ goto argerr;
+ args++;
+ if (!rr_from)
+ rr_from = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(rr_from, *args);
+ }
+ else if (!strcmp(*args,"-receipt_request_to"))
+ {
+ if (!args[1])
+ goto argerr;
+ args++;
+ if (!rr_to)
+ rr_to = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(rr_to, *args);
+ }
+ else if (!strcmp (*args, "-print"))
+ {
+ noout = 1;
+ print = 1;
+ }
+ else if (!strcmp(*args,"-secretkey"))
+ {
+ long ltmp;
+ if (!args[1])
+ goto argerr;
+ args++;
+ secret_key = string_to_hex(*args, &ltmp);
+ if (!secret_key)
+ {
+ BIO_printf(bio_err, "Invalid key %s\n", *args);
+ goto argerr;
+ }
+ secret_keylen = (size_t)ltmp;
+ }
+ else if (!strcmp(*args,"-secretkeyid"))
+ {
+ long ltmp;
+ if (!args[1])
+ goto argerr;
+ args++;
+ secret_keyid = string_to_hex(*args, &ltmp);
+ if (!secret_keyid)
+ {
+ BIO_printf(bio_err, "Invalid id %s\n", *args);
+ goto argerr;
+ }
+ secret_keyidlen = (size_t)ltmp;
+ }
+ else if (!strcmp(*args,"-pwri_password"))
+ {
+ if (!args[1])
+ goto argerr;
+ args++;
+ pwri_pass = (unsigned char *)*args;
+ }
+ else if (!strcmp(*args,"-econtent_type"))
+ {
+ if (!args[1])
+ goto argerr;
+ args++;
+ econtent_type = OBJ_txt2obj(*args, 0);
+ if (!econtent_type)
+ {
+ BIO_printf(bio_err, "Invalid OID %s\n", *args);
+ goto argerr;
+ }
+ }
+ else if (!strcmp(*args,"-rand"))
+ {
+ if (!args[1])
+ goto argerr;
+ args++;
+ inrand = *args;
+ need_rand = 1;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (!strcmp(*args,"-engine"))
+ {
+ if (!args[1])
+ goto argerr;
+ engine = *++args;
+ }
+#endif
+ else if (!strcmp(*args,"-passin"))
+ {
+ if (!args[1])
+ goto argerr;
+ passargin = *++args;
+ }
+ else if (!strcmp (*args, "-to"))
+ {
+ if (!args[1])
+ goto argerr;
+ to = *++args;
+ }
+ else if (!strcmp (*args, "-from"))
+ {
+ if (!args[1])
+ goto argerr;
+ from = *++args;
+ }
+ else if (!strcmp (*args, "-subject"))
+ {
+ if (!args[1])
+ goto argerr;
+ subject = *++args;
+ }
+ else if (!strcmp (*args, "-signer"))
+ {
+ if (!args[1])
+ goto argerr;
+ /* If previous -signer argument add signer to list */
+
+ if (signerfile)
+ {
+ if (!sksigners)
+ sksigners = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(sksigners, signerfile);
+ if (!keyfile)
+ keyfile = signerfile;
+ if (!skkeys)
+ skkeys = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(skkeys, keyfile);
+ keyfile = NULL;
+ }
+ signerfile = *++args;
+ }
+ else if (!strcmp (*args, "-recip"))
+ {
+ if (!args[1])
+ goto argerr;
+ recipfile = *++args;
+ }
+ else if (!strcmp (*args, "-certsout"))
+ {
+ if (!args[1])
+ goto argerr;
+ certsoutfile = *++args;
+ }
+ else if (!strcmp (*args, "-md"))
+ {
+ if (!args[1])
+ goto argerr;
+ sign_md = EVP_get_digestbyname(*++args);
+ if (sign_md == NULL)
+ {
+ BIO_printf(bio_err, "Unknown digest %s\n",
+ *args);
+ goto argerr;
+ }
+ }
+ else if (!strcmp (*args, "-inkey"))
+ {
+ if (!args[1])
+ goto argerr;
+ /* If previous -inkey arument add signer to list */
+ if (keyfile)
+ {
+ if (!signerfile)
+ {
+ BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+ goto argerr;
+ }
+ if (!sksigners)
+ sksigners = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(sksigners, signerfile);
+ signerfile = NULL;
+ if (!skkeys)
+ skkeys = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(skkeys, keyfile);
+ }
+ keyfile = *++args;
+ }
+ else if (!strcmp (*args, "-keyform"))
+ {
+ if (!args[1])
+ goto argerr;
+ keyform = str2fmt(*++args);
+ }
+ else if (!strcmp (*args, "-rctform"))
+ {
+ if (!args[1])
+ goto argerr;
+ rctformat = str2fmt(*++args);
+ }
+ else if (!strcmp (*args, "-certfile"))
+ {
+ if (!args[1])
+ goto argerr;
+ certfile = *++args;
+ }
+ else if (!strcmp (*args, "-CAfile"))
+ {
+ if (!args[1])
+ goto argerr;
+ CAfile = *++args;
+ }
+ else if (!strcmp (*args, "-CApath"))
+ {
+ if (!args[1])
+ goto argerr;
+ CApath = *++args;
+ }
+ else if (!strcmp (*args, "-in"))
+ {
+ if (!args[1])
+ goto argerr;
+ infile = *++args;
+ }
+ else if (!strcmp (*args, "-inform"))
+ {
+ if (!args[1])
+ goto argerr;
+ informat = str2fmt(*++args);
+ }
+ else if (!strcmp (*args, "-outform"))
+ {
+ if (!args[1])
+ goto argerr;
+ outformat = str2fmt(*++args);
+ }
+ else if (!strcmp (*args, "-out"))
+ {
+ if (!args[1])
+ goto argerr;
+ outfile = *++args;
+ }
+ else if (!strcmp (*args, "-content"))
+ {
+ if (!args[1])
+ goto argerr;
+ contfile = *++args;
+ }
+ else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
+ continue;
+ else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
+ badarg = 1;
+ args++;
+ }
+
+ if (((rr_allorfirst != -1) || rr_from) && !rr_to)
+ {
+ BIO_puts(bio_err, "No Signed Receipts Recipients\n");
+ goto argerr;
+ }
+
+ if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from))
+ {
+ BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
+ goto argerr;
+ }
+ if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
+ {
+ BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
+ goto argerr;
+ }
+
+ if (operation & SMIME_SIGNERS)
+ {
+ if (keyfile && !signerfile)
+ {
+ BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+ goto argerr;
+ }
+ /* Check to see if any final signer needs to be appended */
+ if (signerfile)
+ {
+ if (!sksigners)
+ sksigners = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(sksigners, signerfile);
+ if (!skkeys)
+ skkeys = sk_OPENSSL_STRING_new_null();
+ if (!keyfile)
+ keyfile = signerfile;
+ sk_OPENSSL_STRING_push(skkeys, keyfile);
+ }
+ if (!sksigners)
+ {
+ BIO_printf(bio_err, "No signer certificate specified\n");
+ badarg = 1;
+ }
+ signerfile = NULL;
+ keyfile = NULL;
+ need_rand = 1;
+ }
+
+ else if (operation == SMIME_DECRYPT)
+ {
+ if (!recipfile && !keyfile && !secret_key && !pwri_pass)
+ {
+ BIO_printf(bio_err, "No recipient certificate or key specified\n");
+ badarg = 1;
+ }
+ }
+ else if (operation == SMIME_ENCRYPT)
+ {
+ if (!*args && !secret_key && !pwri_pass)
+ {
+ BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
+ badarg = 1;
+ }
+ need_rand = 1;
+ }
+ else if (!operation)
+ badarg = 1;
+
+ if (badarg)
+ {
+ argerr:
+ BIO_printf (bio_err, "Usage cms [options] cert.pem ...\n");
+ BIO_printf (bio_err, "where options are\n");
+ BIO_printf (bio_err, "-encrypt encrypt message\n");
+ BIO_printf (bio_err, "-decrypt decrypt encrypted message\n");
+ BIO_printf (bio_err, "-sign sign message\n");
+ BIO_printf (bio_err, "-verify verify signed message\n");
+ BIO_printf (bio_err, "-cmsout output CMS structure\n");
+#ifndef OPENSSL_NO_DES
+ BIO_printf (bio_err, "-des3 encrypt with triple DES\n");
+ BIO_printf (bio_err, "-des encrypt with DES\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+ BIO_printf (bio_err, "-seed encrypt with SEED\n");
+#endif
+#ifndef OPENSSL_NO_RC2
+ BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n");
+ BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n");
+ BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\n");
+#endif
+#ifndef OPENSSL_NO_AES
+ BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
+ BIO_printf (bio_err, " encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
+ BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n");
+#endif
+ BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n");
+ BIO_printf (bio_err, "-nosigs don't verify message signature\n");
+ BIO_printf (bio_err, "-noverify don't verify signers certificate\n");
+ BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n");
+ BIO_printf (bio_err, "-nodetach use opaque signing\n");
+ BIO_printf (bio_err, "-noattr don't include any signed attributes\n");
+ BIO_printf (bio_err, "-binary don't translate message to text\n");
+ BIO_printf (bio_err, "-certfile file other certificates file\n");
+ BIO_printf (bio_err, "-certsout file certificate output file\n");
+ BIO_printf (bio_err, "-signer file signer certificate file\n");
+ BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n");
+ BIO_printf (bio_err, "-keyid use subject key identifier\n");
+ BIO_printf (bio_err, "-in file input file\n");
+ BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n");
+ BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n");
+ BIO_printf (bio_err, "-keyform arg input private key format (PEM or ENGINE)\n");
+ BIO_printf (bio_err, "-out file output file\n");
+ BIO_printf (bio_err, "-outform arg output format SMIME (default), PEM or DER\n");
+ BIO_printf (bio_err, "-content file supply or override content for detached signature\n");
+ BIO_printf (bio_err, "-to addr to address\n");
+ BIO_printf (bio_err, "-from ad from address\n");
+ BIO_printf (bio_err, "-subject s subject\n");
+ BIO_printf (bio_err, "-text include or delete text MIME headers\n");
+ BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
+ BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
+ BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n");
+ BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf (bio_err, "-passin arg input file pass phrase source\n");
+ BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err, " load the file (or the files in the directory) into\n");
+ BIO_printf(bio_err, " the random number generator\n");
+ BIO_printf (bio_err, "cert.pem recipient certificate(s) for encryption\n");
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+ {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+ if (need_rand)
+ {
+ app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+ }
+
+ ret = 2;
+
+ if (!(operation & SMIME_SIGNERS))
+ flags &= ~CMS_DETACHED;
+
+ if (operation & SMIME_OP)
+ {
+ if (outformat == FORMAT_ASN1)
+ outmode = "wb";
+ }
+ else
+ {
+ if (flags & CMS_BINARY)
+ outmode = "wb";
+ }
+
+ if (operation & SMIME_IP)
+ {
+ if (informat == FORMAT_ASN1)
+ inmode = "rb";
+ }
+ else
+ {
+ if (flags & CMS_BINARY)
+ inmode = "rb";
+ }
+
+ if (operation == SMIME_ENCRYPT)
+ {
+ if (!cipher)
+ {
+#ifndef OPENSSL_NO_DES
+ cipher = EVP_des_ede3_cbc();
+#else
+ BIO_printf(bio_err, "No cipher selected\n");
+ goto end;
+#endif
+ }
+
+ if (secret_key && !secret_keyid)
+ {
+ BIO_printf(bio_err, "No secret key id\n");
+ goto end;
+ }
+
+ if (*args)
+ encerts = sk_X509_new_null();
+ while (*args)
+ {
+ if (!(cert = load_cert(bio_err,*args,FORMAT_PEM,
+ NULL, e, "recipient certificate file")))
+ goto end;
+ sk_X509_push(encerts, cert);
+ cert = NULL;
+ args++;
+ }
+ }
+
+ if (certfile)
+ {
+ if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
+ e, "certificate file")))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (recipfile && (operation == SMIME_DECRYPT))
+ {
+ if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
+ e, "recipient certificate file")))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (operation == SMIME_SIGN_RECEIPT)
+ {
+ if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM,NULL,
+ e, "receipt signer certificate file")))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (operation == SMIME_DECRYPT)
+ {
+ if (!keyfile)
+ keyfile = recipfile;
+ }
+ else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT))
+ {
+ if (!keyfile)
+ keyfile = signerfile;
+ }
+ else keyfile = NULL;
+
+ if (keyfile)
+ {
+ key = load_key(bio_err, keyfile, keyform, 0, passin, e,
+ "signing key file");
+ if (!key)
+ goto end;
+ }
+
+ if (infile)
+ {
+ if (!(in = BIO_new_file(infile, inmode)))
+ {
+ BIO_printf (bio_err,
+ "Can't open input file %s\n", infile);
+ goto end;
+ }
+ }
+ else
+ in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+ if (operation & SMIME_IP)
+ {
+ if (informat == FORMAT_SMIME)
+ cms = SMIME_read_CMS(in, &indata);
+ else if (informat == FORMAT_PEM)
+ cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
+ else if (informat == FORMAT_ASN1)
+ cms = d2i_CMS_bio(in, NULL);
+ else
+ {
+ BIO_printf(bio_err, "Bad input format for CMS file\n");
+ goto end;
+ }
+
+ if (!cms)
+ {
+ BIO_printf(bio_err, "Error reading S/MIME message\n");
+ goto end;
+ }
+ if (contfile)
+ {
+ BIO_free(indata);
+ if (!(indata = BIO_new_file(contfile, "rb")))
+ {
+ BIO_printf(bio_err, "Can't read content file %s\n", contfile);
+ goto end;
+ }
+ }
+ if (certsoutfile)
+ {
+ STACK_OF(X509) *allcerts;
+ allcerts = CMS_get1_certs(cms);
+ if (!save_certs(certsoutfile, allcerts))
+ {
+ BIO_printf(bio_err,
+ "Error writing certs to %s\n",
+ certsoutfile);
+ ret = 5;
+ goto end;
+ }
+ sk_X509_pop_free(allcerts, X509_free);
+ }
+ }
+
+ if (rctfile)
+ {
+ char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
+ if (!(rctin = BIO_new_file(rctfile, rctmode)))
+ {
+ BIO_printf (bio_err,
+ "Can't open receipt file %s\n", rctfile);
+ goto end;
+ }
+
+ if (rctformat == FORMAT_SMIME)
+ rcms = SMIME_read_CMS(rctin, NULL);
+ else if (rctformat == FORMAT_PEM)
+ rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
+ else if (rctformat == FORMAT_ASN1)
+ rcms = d2i_CMS_bio(rctin, NULL);
+ else
+ {
+ BIO_printf(bio_err, "Bad input format for receipt\n");
+ goto end;
+ }
+
+ if (!rcms)
+ {
+ BIO_printf(bio_err, "Error reading receipt\n");
+ goto end;
+ }
+ }
+
+ if (outfile)
+ {
+ if (!(out = BIO_new_file(outfile, outmode)))
+ {
+ BIO_printf (bio_err,
+ "Can't open output file %s\n", outfile);
+ goto end;
+ }
+ }
+ else
+ {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+
+ if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT))
+ {
+ if (!(store = setup_verify(bio_err, CAfile, CApath)))
+ goto end;
+ X509_STORE_set_verify_cb(store, cms_cb);
+ if (vpm)
+ X509_STORE_set1_param(store, vpm);
+ }
+
+
+ ret = 3;
+
+ if (operation == SMIME_DATA_CREATE)
+ {
+ cms = CMS_data_create(in, flags);
+ }
+ else if (operation == SMIME_DIGEST_CREATE)
+ {
+ cms = CMS_digest_create(in, sign_md, flags);
+ }
+ else if (operation == SMIME_COMPRESS)
+ {
+ cms = CMS_compress(in, -1, flags);
+ }
+ else if (operation == SMIME_ENCRYPT)
+ {
+ flags |= CMS_PARTIAL;
+ cms = CMS_encrypt(encerts, in, cipher, flags);
+ if (!cms)
+ goto end;
+ if (secret_key)
+ {
+ if (!CMS_add0_recipient_key(cms, NID_undef,
+ secret_key, secret_keylen,
+ secret_keyid, secret_keyidlen,
+ NULL, NULL, NULL))
+ goto end;
+ /* NULL these because call absorbs them */
+ secret_key = NULL;
+ secret_keyid = NULL;
+ }
+ if (pwri_pass)
+ {
+ pwri_tmp = (unsigned char *)BUF_strdup((char *)pwri_pass);
+ if (!pwri_tmp)
+ goto end;
+ if (!CMS_add0_recipient_password(cms,
+ -1, NID_undef, NID_undef,
+ pwri_tmp, -1, NULL))
+ goto end;
+ pwri_tmp = NULL;
+ }
+ if (!(flags & CMS_STREAM))
+ {
+ if (!CMS_final(cms, in, NULL, flags))
+ goto end;
+ }
+ }
+ else if (operation == SMIME_ENCRYPTED_ENCRYPT)
+ {
+ cms = CMS_EncryptedData_encrypt(in, cipher,
+ secret_key, secret_keylen,
+ flags);
+
+ }
+ else if (operation == SMIME_SIGN_RECEIPT)
+ {
+ CMS_ContentInfo *srcms = NULL;
+ STACK_OF(CMS_SignerInfo) *sis;
+ CMS_SignerInfo *si;
+ sis = CMS_get0_SignerInfos(cms);
+ if (!sis)
+ goto end;
+ si = sk_CMS_SignerInfo_value(sis, 0);
+ srcms = CMS_sign_receipt(si, signer, key, other, flags);
+ if (!srcms)
+ goto end;
+ CMS_ContentInfo_free(cms);
+ cms = srcms;
+ }
+ else if (operation & SMIME_SIGNERS)
+ {
+ int i;
+ /* If detached data content we enable streaming if
+ * S/MIME output format.
+ */
+ if (operation == SMIME_SIGN)
+ {
+
+ if (flags & CMS_DETACHED)
+ {
+ if (outformat == FORMAT_SMIME)
+ flags |= CMS_STREAM;
+ }
+ flags |= CMS_PARTIAL;
+ cms = CMS_sign(NULL, NULL, other, in, flags);
+ if (!cms)
+ goto end;
+ if (econtent_type)
+ CMS_set1_eContentType(cms, econtent_type);
+
+ if (rr_to)
+ {
+ rr = make_receipt_request(rr_to, rr_allorfirst,
+ rr_from);
+ if (!rr)
+ {
+ BIO_puts(bio_err,
+ "Signed Receipt Request Creation Error\n");
+ goto end;
+ }
+ }
+ }
+ else
+ flags |= CMS_REUSE_DIGEST;
+ for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++)
+ {
+ CMS_SignerInfo *si;
+ signerfile = sk_OPENSSL_STRING_value(sksigners, i);
+ keyfile = sk_OPENSSL_STRING_value(skkeys, i);
+ signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
+ e, "signer certificate");
+ if (!signer)
+ goto end;
+ key = load_key(bio_err, keyfile, keyform, 0, passin, e,
+ "signing key file");
+ if (!key)
+ goto end;
+ si = CMS_add1_signer(cms, signer, key, sign_md, flags);
+ if (!si)
+ goto end;
+ if (rr && !CMS_add1_ReceiptRequest(si, rr))
+ goto end;
+ X509_free(signer);
+ signer = NULL;
+ EVP_PKEY_free(key);
+ key = NULL;
+ }
+ /* If not streaming or resigning finalize structure */
+ if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM))
+ {
+ if (!CMS_final(cms, in, NULL, flags))
+ goto end;
+ }
+ }
+
+ if (!cms)
+ {
+ BIO_printf(bio_err, "Error creating CMS structure\n");
+ goto end;
+ }
+
+ ret = 4;
+ if (operation == SMIME_DECRYPT)
+ {
+ if (flags & CMS_DEBUG_DECRYPT)
+ CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
+
+ if (secret_key)
+ {
+ if (!CMS_decrypt_set1_key(cms,
+ secret_key, secret_keylen,
+ secret_keyid, secret_keyidlen))
+ {
+ BIO_puts(bio_err,
+ "Error decrypting CMS using secret key\n");
+ goto end;
+ }
+ }
+
+ if (key)
+ {
+ if (!CMS_decrypt_set1_pkey(cms, key, recip))
+ {
+ BIO_puts(bio_err,
+ "Error decrypting CMS using private key\n");
+ goto end;
+ }
+ }
+
+ if (pwri_pass)
+ {
+ if (!CMS_decrypt_set1_password(cms, pwri_pass, -1))
+ {
+ BIO_puts(bio_err,
+ "Error decrypting CMS using password\n");
+ goto end;
+ }
+ }
+
+ if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags))
+ {
+ BIO_printf(bio_err, "Error decrypting CMS structure\n");
+ goto end;
+ }
+ }
+ else if (operation == SMIME_DATAOUT)
+ {
+ if (!CMS_data(cms, out, flags))
+ goto end;
+ }
+ else if (operation == SMIME_UNCOMPRESS)
+ {
+ if (!CMS_uncompress(cms, indata, out, flags))
+ goto end;
+ }
+ else if (operation == SMIME_DIGEST_VERIFY)
+ {
+ if (CMS_digest_verify(cms, indata, out, flags) > 0)
+ BIO_printf(bio_err, "Verification successful\n");
+ else
+ {
+ BIO_printf(bio_err, "Verification failure\n");
+ goto end;
+ }
+ }
+ else if (operation == SMIME_ENCRYPTED_DECRYPT)
+ {
+ if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
+ indata, out, flags))
+ goto end;
+ }
+ else if (operation == SMIME_VERIFY)
+ {
+ if (CMS_verify(cms, other, store, indata, out, flags) > 0)
+ BIO_printf(bio_err, "Verification successful\n");
+ else
+ {
+ BIO_printf(bio_err, "Verification failure\n");
+ if (verify_retcode)
+ ret = verify_err + 32;
+ goto end;
+ }
+ if (signerfile)
+ {
+ STACK_OF(X509) *signers;
+ signers = CMS_get0_signers(cms);
+ if (!save_certs(signerfile, signers))
+ {
+ BIO_printf(bio_err,
+ "Error writing signers to %s\n",
+ signerfile);
+ ret = 5;
+ goto end;
+ }
+ sk_X509_free(signers);
+ }
+ if (rr_print)
+ receipt_request_print(bio_err, cms);
+
+ }
+ else if (operation == SMIME_VERIFY_RECEIPT)
+ {
+ if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
+ BIO_printf(bio_err, "Verification successful\n");
+ else
+ {
+ BIO_printf(bio_err, "Verification failure\n");
+ goto end;
+ }
+ }
+ else
+ {
+ if (noout)
+ {
+ if (print)
+ CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
+ }
+ else if (outformat == FORMAT_SMIME)
+ {
+ if (to)
+ BIO_printf(out, "To: %s\n", to);
+ if (from)
+ BIO_printf(out, "From: %s\n", from);
+ if (subject)
+ BIO_printf(out, "Subject: %s\n", subject);
+ if (operation == SMIME_RESIGN)
+ ret = SMIME_write_CMS(out, cms, indata, flags);
+ else
+ ret = SMIME_write_CMS(out, cms, in, flags);
+ }
+ else if (outformat == FORMAT_PEM)
+ ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
+ else if (outformat == FORMAT_ASN1)
+ ret = i2d_CMS_bio_stream(out,cms, in, flags);
+ else
+ {
+ BIO_printf(bio_err, "Bad output format for CMS file\n");
+ goto end;
+ }
+ if (ret <= 0)
+ {
+ ret = 6;
+ goto end;
+ }
+ }
+ ret = 0;
+end:
+ if (ret)
+ ERR_print_errors(bio_err);
+ if (need_rand)
+ app_RAND_write_file(NULL, bio_err);
+ sk_X509_pop_free(encerts, X509_free);
+ sk_X509_pop_free(other, X509_free);
+ if (vpm)
+ X509_VERIFY_PARAM_free(vpm);
+ if (sksigners)
+ sk_OPENSSL_STRING_free(sksigners);
+ if (skkeys)
+ sk_OPENSSL_STRING_free(skkeys);
+ if (secret_key)
+ OPENSSL_free(secret_key);
+ if (secret_keyid)
+ OPENSSL_free(secret_keyid);
+ if (pwri_tmp)
+ OPENSSL_free(pwri_tmp);
+ if (econtent_type)
+ ASN1_OBJECT_free(econtent_type);
+ if (rr)
+ CMS_ReceiptRequest_free(rr);
+ if (rr_to)
+ sk_OPENSSL_STRING_free(rr_to);
+ if (rr_from)
+ sk_OPENSSL_STRING_free(rr_from);
+ X509_STORE_free(store);
+ X509_free(cert);
+ X509_free(recip);
+ X509_free(signer);
+ EVP_PKEY_free(key);
+ CMS_ContentInfo_free(cms);
+ CMS_ContentInfo_free(rcms);
+ BIO_free(rctin);
+ BIO_free(in);
+ BIO_free(indata);
+ BIO_free_all(out);
+ if (passin) OPENSSL_free(passin);
+ return (ret);
+}
+
+static int save_certs(char *signerfile, STACK_OF(X509) *signers)
+ {
+ int i;
+ BIO *tmp;
+ if (!signerfile)
+ return 1;
+ tmp = BIO_new_file(signerfile, "w");
+ if (!tmp) return 0;
+ for(i = 0; i < sk_X509_num(signers); i++)
+ PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
+ BIO_free(tmp);
+ return 1;
+ }
+
+
+/* Minimal callback just to output policy info (if any) */
+
+static int cms_cb(int ok, X509_STORE_CTX *ctx)
+ {
+ int error;
+
+ error = X509_STORE_CTX_get_error(ctx);
+
+ verify_err = error;
+
+ if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
+ && ((error != X509_V_OK) || (ok != 2)))
+ return ok;
+
+ policies_print(NULL, ctx);
+
+ return ok;
+
+ }
+
+static void gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns)
+ {
+ STACK_OF(GENERAL_NAME) *gens;
+ GENERAL_NAME *gen;
+ int i, j;
+ for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++)
+ {
+ gens = sk_GENERAL_NAMES_value(gns, i);
+ for (j = 0; j < sk_GENERAL_NAME_num(gens); j++)
+ {
+ gen = sk_GENERAL_NAME_value(gens, j);
+ BIO_puts(out, " ");
+ GENERAL_NAME_print(out, gen);
+ BIO_puts(out, "\n");
+ }
+ }
+ return;
+ }
+
+static void receipt_request_print(BIO *out, CMS_ContentInfo *cms)
+ {
+ STACK_OF(CMS_SignerInfo) *sis;
+ CMS_SignerInfo *si;
+ CMS_ReceiptRequest *rr;
+ int allorfirst;
+ STACK_OF(GENERAL_NAMES) *rto, *rlist;
+ ASN1_STRING *scid;
+ int i, rv;
+ sis = CMS_get0_SignerInfos(cms);
+ for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++)
+ {
+ si = sk_CMS_SignerInfo_value(sis, i);
+ rv = CMS_get1_ReceiptRequest(si, &rr);
+ BIO_printf(bio_err, "Signer %d:\n", i + 1);
+ if (rv == 0)
+ BIO_puts(bio_err, " No Receipt Request\n");
+ else if (rv < 0)
+ {
+ BIO_puts(bio_err, " Receipt Request Parse Error\n");
+ ERR_print_errors(bio_err);
+ }
+ else
+ {
+ char *id;
+ int idlen;
+ CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
+ &rlist, &rto);
+ BIO_puts(out, " Signed Content ID:\n");
+ idlen = ASN1_STRING_length(scid);
+ id = (char *)ASN1_STRING_data(scid);
+ BIO_dump_indent(out, id, idlen, 4);
+ BIO_puts(out, " Receipts From");
+ if (rlist)
+ {
+ BIO_puts(out, " List:\n");
+ gnames_stack_print(out, rlist);
+ }
+ else if (allorfirst == 1)
+ BIO_puts(out, ": First Tier\n");
+ else if (allorfirst == 0)
+ BIO_puts(out, ": All\n");
+ else
+ BIO_printf(out, " Unknown (%d)\n", allorfirst);
+ BIO_puts(out, " Receipts To:\n");
+ gnames_stack_print(out, rto);
+ }
+ if (rr)
+ CMS_ReceiptRequest_free(rr);
+ }
+ }
+
+static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
+ {
+ int i;
+ STACK_OF(GENERAL_NAMES) *ret;
+ GENERAL_NAMES *gens = NULL;
+ GENERAL_NAME *gen = NULL;
+ ret = sk_GENERAL_NAMES_new_null();
+ if (!ret)
+ goto err;
+ for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++)
+ {
+ char *str = sk_OPENSSL_STRING_value(ns, i);
+ gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
+ if (!gen)
+ goto err;
+ gens = GENERAL_NAMES_new();
+ if (!gens)
+ goto err;
+ if (!sk_GENERAL_NAME_push(gens, gen))
+ goto err;
+ gen = NULL;
+ if (!sk_GENERAL_NAMES_push(ret, gens))
+ goto err;
+ gens = NULL;
+ }
+
+ return ret;
+
+ err:
+ if (ret)
+ sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
+ if (gens)
+ GENERAL_NAMES_free(gens);
+ if (gen)
+ GENERAL_NAME_free(gen);
+ return NULL;
+ }
+
+
+static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to,
+ int rr_allorfirst,
+ STACK_OF(OPENSSL_STRING) *rr_from)
+ {
+ STACK_OF(GENERAL_NAMES) *rct_to, *rct_from;
+ CMS_ReceiptRequest *rr;
+ rct_to = make_names_stack(rr_to);
+ if (!rct_to)
+ goto err;
+ if (rr_from)
+ {
+ rct_from = make_names_stack(rr_from);
+ if (!rct_from)
+ goto err;
+ }
+ else
+ rct_from = NULL;
+ rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
+ rct_to);
+ return rr;
+ err:
+ return NULL;
+ }
+
+#endif
diff --git a/deps/openssl/openssl/apps/crl.c b/deps/openssl/openssl/apps/crl.c
new file mode 100644
index 000000000..c395b2afd
--- /dev/null
+++ b/deps/openssl/openssl/apps/crl.c
@@ -0,0 +1,446 @@
+/* apps/crl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG crl_main
+
+#undef POSTFIX
+#define POSTFIX ".rvk"
+
+static const char *crl_usage[]={
+"usage: crl args\n",
+"\n",
+" -inform arg - input format - default PEM (DER or PEM)\n",
+" -outform arg - output format - default PEM\n",
+" -text - print out a text format version\n",
+" -in arg - input file - default stdin\n",
+" -out arg - output file - default stdout\n",
+" -hash - print hash value\n",
+" -fingerprint - print the crl fingerprint\n",
+" -issuer - print issuer DN\n",
+" -lastupdate - lastUpdate field\n",
+" -nextupdate - nextUpdate field\n",
+" -crlnumber - print CRL number\n",
+" -noout - no CRL output\n",
+" -CAfile name - verify CRL using certificates in file \"name\"\n",
+" -CApath dir - verify CRL using certificates in \"dir\"\n",
+" -nameopt arg - various certificate name options\n",
+NULL
+};
+
+static X509_CRL *load_crl(char *file, int format);
+static BIO *bio_out=NULL;
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ unsigned long nmflag = 0;
+ X509_CRL *x=NULL;
+ char *CAfile = NULL, *CApath = NULL;
+ int ret=1,i,num,badops=0;
+ BIO *out=NULL;
+ int informat,outformat;
+ char *infile=NULL,*outfile=NULL;
+ int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
+ int fingerprint = 0, crlnumber = 0;
+ const char **pp;
+ X509_STORE *store = NULL;
+ X509_STORE_CTX ctx;
+ X509_LOOKUP *lookup = NULL;
+ X509_OBJECT xobj;
+ EVP_PKEY *pkey;
+ int do_ver = 0;
+ const EVP_MD *md_alg,*digest=EVP_sha1();
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ if (bio_out == NULL)
+ if ((bio_out=BIO_new(BIO_s_file())) != NULL)
+ {
+ BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ bio_out = BIO_push(tmpbio, bio_out);
+ }
+#endif
+ }
+
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ argc--;
+ argv++;
+ num=0;
+ while (argc >= 1)
+ {
+#ifdef undef
+ if (strcmp(*argv,"-p") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if (!args_from_file(++argv,Nargc,Nargv)) { goto end; }*/
+ }
+#endif
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-CApath") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CApath = *(++argv);
+ do_ver = 1;
+ }
+ else if (strcmp(*argv,"-CAfile") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CAfile = *(++argv);
+ do_ver = 1;
+ }
+ else if (strcmp(*argv,"-verify") == 0)
+ do_ver = 1;
+ else if (strcmp(*argv,"-text") == 0)
+ text = 1;
+ else if (strcmp(*argv,"-hash") == 0)
+ hash= ++num;
+ else if (strcmp(*argv,"-nameopt") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if (!set_name_ex(&nmflag, *(++argv))) goto bad;
+ }
+ else if (strcmp(*argv,"-issuer") == 0)
+ issuer= ++num;
+ else if (strcmp(*argv,"-lastupdate") == 0)
+ lastupdate= ++num;
+ else if (strcmp(*argv,"-nextupdate") == 0)
+ nextupdate= ++num;
+ else if (strcmp(*argv,"-noout") == 0)
+ noout= ++num;
+ else if (strcmp(*argv,"-fingerprint") == 0)
+ fingerprint= ++num;
+ else if (strcmp(*argv,"-crlnumber") == 0)
+ crlnumber= ++num;
+ else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
+ {
+ /* ok */
+ digest=md_alg;
+ }
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ for (pp=crl_usage; (*pp != NULL); pp++)
+ BIO_printf(bio_err,"%s",*pp);
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+ x=load_crl(infile,informat);
+ if (x == NULL) { goto end; }
+
+ if(do_ver) {
+ store = X509_STORE_new();
+ lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
+ if (lookup == NULL) goto end;
+ if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
+ X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
+
+ lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
+ if (lookup == NULL) goto end;
+ if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
+ X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
+ ERR_clear_error();
+
+ if(!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
+ BIO_printf(bio_err,
+ "Error initialising X509 store\n");
+ goto end;
+ }
+
+ i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
+ X509_CRL_get_issuer(x), &xobj);
+ if(i <= 0) {
+ BIO_printf(bio_err,
+ "Error getting CRL issuer certificate\n");
+ goto end;
+ }
+ pkey = X509_get_pubkey(xobj.data.x509);
+ X509_OBJECT_free_contents(&xobj);
+ if(!pkey) {
+ BIO_printf(bio_err,
+ "Error getting CRL issuer public key\n");
+ goto end;
+ }
+ i = X509_CRL_verify(x, pkey);
+ EVP_PKEY_free(pkey);
+ if(i < 0) goto end;
+ if(i == 0) BIO_printf(bio_err, "verify failure\n");
+ else BIO_printf(bio_err, "verify OK\n");
+ }
+
+ if (num)
+ {
+ for (i=1; i<=num; i++)
+ {
+ if (issuer == i)
+ {
+ print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag);
+ }
+ if (crlnumber == i)
+ {
+ ASN1_INTEGER *crlnum;
+ crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number,
+ NULL, NULL);
+ BIO_printf(bio_out,"crlNumber=");
+ if (crlnum)
+ {
+ i2a_ASN1_INTEGER(bio_out, crlnum);
+ ASN1_INTEGER_free(crlnum);
+ }
+ else
+ BIO_puts(bio_out, "<NONE>");
+ BIO_printf(bio_out,"\n");
+ }
+ if (hash == i)
+ {
+ BIO_printf(bio_out,"%08lx\n",
+ X509_NAME_hash(X509_CRL_get_issuer(x)));
+ }
+ if (lastupdate == i)
+ {
+ BIO_printf(bio_out,"lastUpdate=");
+ ASN1_TIME_print(bio_out,
+ X509_CRL_get_lastUpdate(x));
+ BIO_printf(bio_out,"\n");
+ }
+ if (nextupdate == i)
+ {
+ BIO_printf(bio_out,"nextUpdate=");
+ if (X509_CRL_get_nextUpdate(x))
+ ASN1_TIME_print(bio_out,
+ X509_CRL_get_nextUpdate(x));
+ else
+ BIO_printf(bio_out,"NONE");
+ BIO_printf(bio_out,"\n");
+ }
+ if (fingerprint == i)
+ {
+ int j;
+ unsigned int n;
+ unsigned char md[EVP_MAX_MD_SIZE];
+
+ if (!X509_CRL_digest(x,digest,md,&n))
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ goto end;
+ }
+ BIO_printf(bio_out,"%s Fingerprint=",
+ OBJ_nid2sn(EVP_MD_type(digest)));
+ for (j=0; j<(int)n; j++)
+ {
+ BIO_printf(bio_out,"%02X%c",md[j],
+ (j+1 == (int)n)
+ ?'\n':':');
+ }
+ }
+ }
+ }
+
+ out=BIO_new(BIO_s_file());
+ if (out == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ if (text) X509_CRL_print(out, x);
+
+ if (noout)
+ {
+ ret = 0;
+ goto end;
+ }
+
+ if (outformat == FORMAT_ASN1)
+ i=(int)i2d_X509_CRL_bio(out,x);
+ else if (outformat == FORMAT_PEM)
+ i=PEM_write_bio_X509_CRL(out,x);
+ else
+ {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; }
+ ret=0;
+end:
+ BIO_free_all(out);
+ BIO_free_all(bio_out);
+ bio_out=NULL;
+ X509_CRL_free(x);
+ if(store) {
+ X509_STORE_CTX_cleanup(&ctx);
+ X509_STORE_free(store);
+ }
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+static X509_CRL *load_crl(char *infile, int format)
+ {
+ X509_CRL *x=NULL;
+ BIO *in=NULL;
+
+ in=BIO_new(BIO_s_file());
+ if (in == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+ if (format == FORMAT_ASN1)
+ x=d2i_X509_CRL_bio(in,NULL);
+ else if (format == FORMAT_PEM)
+ x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
+ else {
+ BIO_printf(bio_err,"bad input format specified for input crl\n");
+ goto end;
+ }
+ if (x == NULL)
+ {
+ BIO_printf(bio_err,"unable to load CRL\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+end:
+ BIO_free(in);
+ return(x);
+ }
+
diff --git a/deps/openssl/openssl/apps/crl2p7.c b/deps/openssl/openssl/apps/crl2p7.c
new file mode 100644
index 000000000..bbc83774d
--- /dev/null
+++ b/deps/openssl/openssl/apps/crl2p7.c
@@ -0,0 +1,337 @@
+/* apps/crl2p7.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* This was written by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
+ * and donated 'to the cause' along with lots and lots of other fixes to
+ * the library. */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+#include <openssl/objects.h>
+
+static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile);
+#undef PROG
+#define PROG crl2pkcs7_main
+
+/* -inform arg - input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ int i,badops=0;
+ BIO *in=NULL,*out=NULL;
+ int informat,outformat;
+ char *infile,*outfile,*prog,*certfile;
+ PKCS7 *p7 = NULL;
+ PKCS7_SIGNED *p7s = NULL;
+ X509_CRL *crl=NULL;
+ STACK_OF(OPENSSL_STRING) *certflst=NULL;
+ STACK_OF(X509_CRL) *crl_stack=NULL;
+ STACK_OF(X509) *cert_stack=NULL;
+ int ret=1,nocrl=0;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ infile=NULL;
+ outfile=NULL;
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-nocrl") == 0)
+ {
+ nocrl=1;
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-certfile") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if(!certflst) certflst = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(certflst,*(++argv));
+ }
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+ BIO_printf(bio_err,"where options are\n");
+ BIO_printf(bio_err," -inform arg input format - DER or PEM\n");
+ BIO_printf(bio_err," -outform arg output format - DER or PEM\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -out arg output file\n");
+ BIO_printf(bio_err," -certfile arg certificates file of chain to a trusted CA\n");
+ BIO_printf(bio_err," (can be used more than once)\n");
+ BIO_printf(bio_err," -nocrl no crl to load, just certs from '-certfile'\n");
+ ret = 1;
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+
+ in=BIO_new(BIO_s_file());
+ out=BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (!nocrl)
+ {
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+
+ if (informat == FORMAT_ASN1)
+ crl=d2i_X509_CRL_bio(in,NULL);
+ else if (informat == FORMAT_PEM)
+ crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
+ else {
+ BIO_printf(bio_err,"bad input format specified for input crl\n");
+ goto end;
+ }
+ if (crl == NULL)
+ {
+ BIO_printf(bio_err,"unable to load CRL\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if ((p7=PKCS7_new()) == NULL) goto end;
+ if ((p7s=PKCS7_SIGNED_new()) == NULL) goto end;
+ p7->type=OBJ_nid2obj(NID_pkcs7_signed);
+ p7->d.sign=p7s;
+ p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data);
+
+ if (!ASN1_INTEGER_set(p7s->version,1)) goto end;
+ if ((crl_stack=sk_X509_CRL_new_null()) == NULL) goto end;
+ p7s->crl=crl_stack;
+ if (crl != NULL)
+ {
+ sk_X509_CRL_push(crl_stack,crl);
+ crl=NULL; /* now part of p7 for OPENSSL_freeing */
+ }
+
+ if ((cert_stack=sk_X509_new_null()) == NULL) goto end;
+ p7s->cert=cert_stack;
+
+ if(certflst) for(i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) {
+ certfile = sk_OPENSSL_STRING_value(certflst, i);
+ if (add_certs_from_file(cert_stack,certfile) < 0)
+ {
+ BIO_printf(bio_err, "error loading certificates\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ sk_OPENSSL_STRING_free(certflst);
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ if (outformat == FORMAT_ASN1)
+ i=i2d_PKCS7_bio(out,p7);
+ else if (outformat == FORMAT_PEM)
+ i=PEM_write_bio_PKCS7(out,p7);
+ else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (!i)
+ {
+ BIO_printf(bio_err,"unable to write pkcs7 object\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ ret=0;
+end:
+ if (in != NULL) BIO_free(in);
+ if (out != NULL) BIO_free_all(out);
+ if (p7 != NULL) PKCS7_free(p7);
+ if (crl != NULL) X509_CRL_free(crl);
+
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+/*
+ *----------------------------------------------------------------------
+ * int add_certs_from_file
+ *
+ * Read a list of certificates to be checked from a file.
+ *
+ * Results:
+ * number of certs added if successful, -1 if not.
+ *----------------------------------------------------------------------
+ */
+static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
+ {
+ BIO *in=NULL;
+ int count=0;
+ int ret= -1;
+ STACK_OF(X509_INFO) *sk=NULL;
+ X509_INFO *xi;
+
+ in=BIO_new(BIO_s_file());
+ if ((in == NULL) || (BIO_read_filename(in,certfile) <= 0))
+ {
+ BIO_printf(bio_err,"error opening the file, %s\n",certfile);
+ goto end;
+ }
+
+ /* This loads from a file, a stack of x509/crl/pkey sets */
+ sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL);
+ if (sk == NULL) {
+ BIO_printf(bio_err,"error reading the file, %s\n",certfile);
+ goto end;
+ }
+
+ /* scan over it and pull out the CRL's */
+ while (sk_X509_INFO_num(sk))
+ {
+ xi=sk_X509_INFO_shift(sk);
+ if (xi->x509 != NULL)
+ {
+ sk_X509_push(stack,xi->x509);
+ xi->x509=NULL;
+ count++;
+ }
+ X509_INFO_free(xi);
+ }
+
+ ret=count;
+end:
+ /* never need to OPENSSL_free x */
+ if (in != NULL) BIO_free(in);
+ if (sk != NULL) sk_X509_INFO_free(sk);
+ return(ret);
+ }
+
diff --git a/deps/openssl/openssl/apps/demoCA/cacert.pem b/deps/openssl/openssl/apps/demoCA/cacert.pem
new file mode 100644
index 000000000..affbce3bc
--- /dev/null
+++ b/deps/openssl/openssl/apps/demoCA/cacert.pem
@@ -0,0 +1,14 @@
+subject=/C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+-----BEGIN X509 CERTIFICATE-----
+
+MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
+BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
+MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
+RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
+BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
+LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
+/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
+DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
+IMs6ZOZB
+-----END X509 CERTIFICATE-----
diff --git a/deps/openssl/openssl/apps/demoCA/index.txt b/deps/openssl/openssl/apps/demoCA/index.txt
new file mode 100644
index 000000000..2cdd252d6
--- /dev/null
+++ b/deps/openssl/openssl/apps/demoCA/index.txt
@@ -0,0 +1,39 @@
+R 980705233205Z 951009233205Z 01 certs/00000001 /CN=Eric Young
+E 951009233205Z 02 certs/00000002 /CN=Duncan Young
+R 980705233205Z 951201010000Z 03 certs/00000003 /CN=Tim Hudson
+V 980705233205Z 04 certs/00000004 /CN=Eric Young4
+V 980705233205Z 05 certs/00000004 /CN=Eric Young5
+V 980705233205Z 06 certs/00000004 /CN=Eric Young6
+V 980705233205Z 07 certs/00000004 /CN=Eric Young7
+V 980705233205Z 08 certs/00000004 /CN=Eric Young8
+V 980705233205Z 09 certs/00000004 /CN=Eric Young9
+V 980705233205Z 0A certs/00000004 /CN=Eric YoungA
+V 980705233205Z 0B certs/00000004 /CN=Eric YoungB
+V 980705233205Z 0C certs/00000004 /CN=Eric YoungC
+V 980705233205Z 0D certs/00000004 /CN=Eric YoungD
+V 980705233205Z 0E certs/00000004 /CN=Eric YoungE
+V 980705233205Z 0F certs/00000004 /CN=Eric YoungF
+V 980705233205Z 10 certs/00000004 /CN=Eric Young10
+V 980705233205Z 11 certs/00000004 /CN=Eric Young11
+V 980705233205Z 12 certs/00000004 /CN=Eric Young12
+V 980705233205Z 13 certs/00000004 /CN=Eric Young13
+V 980705233205Z 14 certs/00000004 /CN=Eric Young14
+V 980705233205Z 15 certs/00000004 /CN=Eric Young15
+V 980705233205Z 16 certs/00000004 /CN=Eric Young16
+V 980705233205Z 17 certs/00000004 /CN=Eric Young17
+V 961206150305Z 010C unknown /C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=MTR/CN=Eric Young/Email=eay@mincom.oz.au
+V 961206153245Z 010D unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=Eric Young/Email=eay@mincom.oz.au
+V 970322074816Z 010E unknown /CN=Eric Young/Email=eay@mincom.oz.au
+V 970322075152Z 010F unknown /CN=Eric Young
+V 970322075906Z 0110 unknown /CN=Eric Youngg
+V 970324092238Z 0111 unknown /C=AU/SP=Queensland/CN=Eric Young
+V 970324221931Z 0112 unknown /CN=Fred
+V 970324224934Z 0113 unknown /C=AU/CN=eay
+V 971001005237Z 0114 unknown /C=AU/SP=QLD/O=Mincom Pty Ltd/OU=MTR/CN=x509v3 test
+V 971001010331Z 0115 unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test again - x509v3
+V 971001013945Z 0117 unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=x509v3 test
+V 971014225415Z 0118 unknown /C=AU/SP=Queensland/CN=test
+V 971015004448Z 0119 unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test2
+V 971016035001Z 011A unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test64
+V 971016080129Z 011B unknown /C=FR/O=ALCATEL/OU=Alcatel Mobile Phones/CN=bourque/Email=bourque@art.alcatel.fr
+V 971016224000Z 011D unknown /L=Bedford/O=Cranfield University/OU=Computer Centre/CN=Peter R Lister/Email=P.Lister@cranfield.ac.uk
diff --git a/deps/openssl/openssl/apps/demoCA/private/cakey.pem b/deps/openssl/openssl/apps/demoCA/private/cakey.pem
new file mode 100644
index 000000000..48fb18c7d
--- /dev/null
+++ b/deps/openssl/openssl/apps/demoCA/private/cakey.pem
@@ -0,0 +1,24 @@
+issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+subject=/C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+-----BEGIN X509 CERTIFICATE-----
+
+MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
+BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
+MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
+RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
+BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
+LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
+/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
+DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
+IMs6ZOZB
+-----END X509 CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+
+MIIBPAIBAAJBALcsJdxJxa5rQ8UuQcEubZV6OqkDUXhFDyrRWNGI9p+PH9n9pYfe
+Kl0xW+4kZr/AVdv+cMUsOV9an6gI/CEG1U8CAwEAAQJAXJMBZ34ZXHd1vtgL/3hZ
+hexKbVTx/djZO4imXO/dxPGRzG2ylYZpHmG32/T1kaHpZlCHoEPgHoSzmxYXfxjG
+sQIhAPmZ/bQOjmRUHM/VM2X5zrjjM6z18R1P6l3ObFwt9FGdAiEAu943Yh9SqMRw
+tL0xHGxKmM/YJueUw1gB6sLkETN71NsCIQCeT3RhoqXfrpXDoEcEU+gwzjI1bpxq
+agiNTOLfqGoA5QIhAIQFYjgzONxex7FLrsKBm16N2SFl5pXsN9SpRqqL2n63AiEA
+g9VNIQ3xwpw7og3IbONifeku+J9qGMGQJMKwSTwrFtI=
+-----END RSA PRIVATE KEY-----
diff --git a/deps/openssl/openssl/apps/demoCA/serial b/deps/openssl/openssl/apps/demoCA/serial
new file mode 100644
index 000000000..69fa0ffe2
--- /dev/null
+++ b/deps/openssl/openssl/apps/demoCA/serial
@@ -0,0 +1 @@
+011E
diff --git a/deps/openssl/openssl/apps/demoSRP/srp_verifier.txt b/deps/openssl/openssl/apps/demoSRP/srp_verifier.txt
new file mode 100644
index 000000000..ccae62924
--- /dev/null
+++ b/deps/openssl/openssl/apps/demoSRP/srp_verifier.txt
@@ -0,0 +1,6 @@
+# This is a file that will be filled by the openssl srp routine.
+# You can initialize the file with additional groups, these are
+# records starting with a I followed by the g and N values and the id.
+# The exact values ... you have to dig this out from the source of srp.c
+# or srp_vfy.c
+# The last value of an I is used as the default group for new users.
diff --git a/deps/openssl/openssl/apps/demoSRP/srp_verifier.txt.attr b/deps/openssl/openssl/apps/demoSRP/srp_verifier.txt.attr
new file mode 100644
index 000000000..8f7e63a34
--- /dev/null
+++ b/deps/openssl/openssl/apps/demoSRP/srp_verifier.txt.attr
@@ -0,0 +1 @@
+unique_subject = yes
diff --git a/deps/openssl/openssl/apps/dgst.c b/deps/openssl/openssl/apps/dgst.c
new file mode 100644
index 000000000..81bd870f9
--- /dev/null
+++ b/deps/openssl/openssl/apps/dgst.c
@@ -0,0 +1,644 @@
+/* apps/dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/hmac.h>
+
+#undef BUFSIZE
+#define BUFSIZE 1024*8
+
+#undef PROG
+#define PROG dgst_main
+
+int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
+ EVP_PKEY *key, unsigned char *sigin, int siglen,
+ const char *sig_name, const char *md_name,
+ const char *file,BIO *bmd);
+
+static void list_md_fn(const EVP_MD *m,
+ const char *from, const char *to, void *arg)
+ {
+ const char *mname;
+ /* Skip aliases */
+ if (!m)
+ return;
+ mname = OBJ_nid2ln(EVP_MD_type(m));
+ /* Skip shortnames */
+ if (strcmp(from, mname))
+ return;
+ /* Skip clones */
+ if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST)
+ return;
+ if (strchr(mname, ' '))
+ mname= EVP_MD_name(m);
+ BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n",
+ mname, mname);
+ }
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ unsigned char *buf=NULL;
+ int i,err=1;
+ const EVP_MD *md=NULL,*m;
+ BIO *in=NULL,*inp;
+ BIO *bmd=NULL;
+ BIO *out = NULL;
+#define PROG_NAME_SIZE 39
+ char pname[PROG_NAME_SIZE+1];
+ int separator=0;
+ int debug=0;
+ int keyform=FORMAT_PEM;
+ const char *outfile = NULL, *keyfile = NULL;
+ const char *sigfile = NULL, *randfile = NULL;
+ int out_bin = -1, want_pub = 0, do_verify = 0;
+ EVP_PKEY *sigkey = NULL;
+ unsigned char *sigbuf = NULL;
+ int siglen = 0;
+ char *passargin = NULL, *passin = NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+ char *hmac_key=NULL;
+ char *mac_name=NULL;
+ int non_fips_allow = 0;
+ STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
+
+ apps_startup();
+
+ if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL)
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ goto end;
+ }
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ /* first check the program name */
+ program_name(argv[0],pname,sizeof pname);
+
+ md=EVP_get_digestbyname(pname);
+
+ argc--;
+ argv++;
+ while (argc > 0)
+ {
+ if ((*argv)[0] != '-') break;
+ if (strcmp(*argv,"-c") == 0)
+ separator=1;
+ else if (strcmp(*argv,"-r") == 0)
+ separator=2;
+ else if (strcmp(*argv,"-rand") == 0)
+ {
+ if (--argc < 1) break;
+ randfile=*(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) break;
+ outfile=*(++argv);
+ }
+ else if (strcmp(*argv,"-sign") == 0)
+ {
+ if (--argc < 1) break;
+ keyfile=*(++argv);
+ }
+ else if (!strcmp(*argv,"-passin"))
+ {
+ if (--argc < 1)
+ break;
+ passargin=*++argv;
+ }
+ else if (strcmp(*argv,"-verify") == 0)
+ {
+ if (--argc < 1) break;
+ keyfile=*(++argv);
+ want_pub = 1;
+ do_verify = 1;
+ }
+ else if (strcmp(*argv,"-prverify") == 0)
+ {
+ if (--argc < 1) break;
+ keyfile=*(++argv);
+ do_verify = 1;
+ }
+ else if (strcmp(*argv,"-signature") == 0)
+ {
+ if (--argc < 1) break;
+ sigfile=*(++argv);
+ }
+ else if (strcmp(*argv,"-keyform") == 0)
+ {
+ if (--argc < 1) break;
+ keyform=str2fmt(*(++argv));
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) break;
+ engine= *(++argv);
+ e = setup_engine(bio_err, engine, 0);
+ }
+#endif
+ else if (strcmp(*argv,"-hex") == 0)
+ out_bin = 0;
+ else if (strcmp(*argv,"-binary") == 0)
+ out_bin = 1;
+ else if (strcmp(*argv,"-d") == 0)
+ debug=1;
+ else if (!strcmp(*argv,"-fips-fingerprint"))
+ hmac_key = "etaonrishdlcupfm";
+ else if (strcmp(*argv,"-non-fips-allow") == 0)
+ non_fips_allow=1;
+ else if (!strcmp(*argv,"-hmac"))
+ {
+ if (--argc < 1)
+ break;
+ hmac_key=*++argv;
+ }
+ else if (!strcmp(*argv,"-mac"))
+ {
+ if (--argc < 1)
+ break;
+ mac_name=*++argv;
+ }
+ else if (strcmp(*argv,"-sigopt") == 0)
+ {
+ if (--argc < 1)
+ break;
+ if (!sigopts)
+ sigopts = sk_OPENSSL_STRING_new_null();
+ if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+ break;
+ }
+ else if (strcmp(*argv,"-macopt") == 0)
+ {
+ if (--argc < 1)
+ break;
+ if (!macopts)
+ macopts = sk_OPENSSL_STRING_new_null();
+ if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv)))
+ break;
+ }
+ else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
+ md=m;
+ else
+ break;
+ argc--;
+ argv++;
+ }
+
+
+ if(do_verify && !sigfile) {
+ BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
+ goto end;
+ }
+
+ if ((argc > 0) && (argv[0][0] == '-')) /* bad option */
+ {
+ BIO_printf(bio_err,"unknown option '%s'\n",*argv);
+ BIO_printf(bio_err,"options are\n");
+ BIO_printf(bio_err,"-c to output the digest with separating colons\n");
+ BIO_printf(bio_err,"-r to output the digest in coreutils format\n");
+ BIO_printf(bio_err,"-d to output debug info\n");
+ BIO_printf(bio_err,"-hex output as hex dump\n");
+ BIO_printf(bio_err,"-binary output in binary form\n");
+ BIO_printf(bio_err,"-sign file sign digest using private key in file\n");
+ BIO_printf(bio_err,"-verify file verify a signature using public key in file\n");
+ BIO_printf(bio_err,"-prverify file verify a signature using private key in file\n");
+ BIO_printf(bio_err,"-keyform arg key file format (PEM or ENGINE)\n");
+ BIO_printf(bio_err,"-out filename output to filename rather than stdout\n");
+ BIO_printf(bio_err,"-signature file signature to verify\n");
+ BIO_printf(bio_err,"-sigopt nm:v signature parameter\n");
+ BIO_printf(bio_err,"-hmac key create hashed MAC with key\n");
+ BIO_printf(bio_err,"-mac algorithm create MAC (not neccessarily HMAC)\n");
+ BIO_printf(bio_err,"-macopt nm:v MAC algorithm parameters or key\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err,"-engine e use engine e, possibly a hardware device.\n");
+#endif
+
+ EVP_MD_do_all_sorted(list_md_fn, bio_err);
+ goto end;
+ }
+
+ in=BIO_new(BIO_s_file());
+ bmd=BIO_new(BIO_f_md());
+ if (debug)
+ {
+ BIO_set_callback(in,BIO_debug_callback);
+ /* needed for windows 3.1 */
+ BIO_set_callback_arg(in,(char *)bio_err);
+ }
+
+ if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+ {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+ if ((in == NULL) || (bmd == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if(out_bin == -1) {
+ if(keyfile)
+ out_bin = 1;
+ else
+ out_bin = 0;
+ }
+
+ if(randfile)
+ app_RAND_load_file(randfile, bio_err, 0);
+
+ if(outfile) {
+ if(out_bin)
+ out = BIO_new_file(outfile, "wb");
+ else out = BIO_new_file(outfile, "w");
+ } else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+
+ if(!out) {
+ BIO_printf(bio_err, "Error opening output file %s\n",
+ outfile ? outfile : "(stdout)");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if ((!!mac_name + !!keyfile + !!hmac_key) > 1)
+ {
+ BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
+ goto end;
+ }
+
+ if(keyfile)
+ {
+ if (want_pub)
+ sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL,
+ e, "key file");
+ else
+ sigkey = load_key(bio_err, keyfile, keyform, 0, passin,
+ e, "key file");
+ if (!sigkey)
+ {
+ /* load_[pub]key() has already printed an appropriate
+ message */
+ goto end;
+ }
+ }
+
+ if (mac_name)
+ {
+ EVP_PKEY_CTX *mac_ctx = NULL;
+ int r = 0;
+ if (!init_gen_str(bio_err, &mac_ctx, mac_name,e, 0))
+ goto mac_end;
+ if (macopts)
+ {
+ char *macopt;
+ for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++)
+ {
+ macopt = sk_OPENSSL_STRING_value(macopts, i);
+ if (pkey_ctrl_string(mac_ctx, macopt) <= 0)
+ {
+ BIO_printf(bio_err,
+ "MAC parameter error \"%s\"\n",
+ macopt);
+ ERR_print_errors(bio_err);
+ goto mac_end;
+ }
+ }
+ }
+ if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0)
+ {
+ BIO_puts(bio_err, "Error generating key\n");
+ ERR_print_errors(bio_err);
+ goto mac_end;
+ }
+ r = 1;
+ mac_end:
+ if (mac_ctx)
+ EVP_PKEY_CTX_free(mac_ctx);
+ if (r == 0)
+ goto end;
+ }
+
+ if (non_fips_allow)
+ {
+ EVP_MD_CTX *md_ctx;
+ BIO_get_md_ctx(bmd,&md_ctx);
+ EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ }
+
+ if (hmac_key)
+ {
+ sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e,
+ (unsigned char *)hmac_key, -1);
+ if (!sigkey)
+ goto end;
+ }
+
+ if (sigkey)
+ {
+ EVP_MD_CTX *mctx = NULL;
+ EVP_PKEY_CTX *pctx = NULL;
+ int r;
+ if (!BIO_get_md_ctx(bmd, &mctx))
+ {
+ BIO_printf(bio_err, "Error getting context\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (do_verify)
+ r = EVP_DigestVerifyInit(mctx, &pctx, md, e, sigkey);
+ else
+ r = EVP_DigestSignInit(mctx, &pctx, md, e, sigkey);
+ if (!r)
+ {
+ BIO_printf(bio_err, "Error setting context\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (sigopts)
+ {
+ char *sigopt;
+ for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
+ {
+ sigopt = sk_OPENSSL_STRING_value(sigopts, i);
+ if (pkey_ctrl_string(pctx, sigopt) <= 0)
+ {
+ BIO_printf(bio_err,
+ "parameter error \"%s\"\n",
+ sigopt);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ }
+ }
+ /* we use md as a filter, reading from 'in' */
+ else
+ {
+ if (md == NULL)
+ md = EVP_md5();
+ if (!BIO_set_md(bmd,md))
+ {
+ BIO_printf(bio_err, "Error setting digest %s\n", pname);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if(sigfile && sigkey) {
+ BIO *sigbio;
+ sigbio = BIO_new_file(sigfile, "rb");
+ siglen = EVP_PKEY_size(sigkey);
+ sigbuf = OPENSSL_malloc(siglen);
+ if(!sigbio) {
+ BIO_printf(bio_err, "Error opening signature file %s\n",
+ sigfile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ siglen = BIO_read(sigbio, sigbuf, siglen);
+ BIO_free(sigbio);
+ if(siglen <= 0) {
+ BIO_printf(bio_err, "Error reading signature file %s\n",
+ sigfile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ inp=BIO_push(bmd,in);
+
+ if (md == NULL)
+ {
+ EVP_MD_CTX *tctx;
+ BIO_get_md_ctx(bmd, &tctx);
+ md = EVP_MD_CTX_md(tctx);
+ }
+
+ if (argc == 0)
+ {
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf,
+ siglen,NULL,NULL,"stdin",bmd);
+ }
+ else
+ {
+ const char *md_name = NULL, *sig_name = NULL;
+ if(!out_bin)
+ {
+ if (sigkey)
+ {
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ ameth = EVP_PKEY_get0_asn1(sigkey);
+ if (ameth)
+ EVP_PKEY_asn1_get0_info(NULL, NULL,
+ NULL, NULL, &sig_name, ameth);
+ }
+ md_name = EVP_MD_name(md);
+ }
+ err = 0;
+ for (i=0; i<argc; i++)
+ {
+ int r;
+ if (BIO_read_filename(in,argv[i]) <= 0)
+ {
+ perror(argv[i]);
+ err++;
+ continue;
+ }
+ else
+ r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf,
+ siglen,sig_name,md_name, argv[i],bmd);
+ if(r)
+ err=r;
+ (void)BIO_reset(bmd);
+ }
+ }
+end:
+ if (buf != NULL)
+ {
+ OPENSSL_cleanse(buf,BUFSIZE);
+ OPENSSL_free(buf);
+ }
+ if (in != NULL) BIO_free(in);
+ if (passin)
+ OPENSSL_free(passin);
+ BIO_free_all(out);
+ EVP_PKEY_free(sigkey);
+ if (sigopts)
+ sk_OPENSSL_STRING_free(sigopts);
+ if (macopts)
+ sk_OPENSSL_STRING_free(macopts);
+ if(sigbuf) OPENSSL_free(sigbuf);
+ if (bmd != NULL) BIO_free(bmd);
+ apps_shutdown();
+ OPENSSL_EXIT(err);
+ }
+
+int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
+ EVP_PKEY *key, unsigned char *sigin, int siglen,
+ const char *sig_name, const char *md_name,
+ const char *file,BIO *bmd)
+ {
+ size_t len;
+ int i;
+
+ for (;;)
+ {
+ i=BIO_read(bp,(char *)buf,BUFSIZE);
+ if(i < 0)
+ {
+ BIO_printf(bio_err, "Read Error in %s\n",file);
+ ERR_print_errors(bio_err);
+ return 1;
+ }
+ if (i == 0) break;
+ }
+ if(sigin)
+ {
+ EVP_MD_CTX *ctx;
+ BIO_get_md_ctx(bp, &ctx);
+ i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen);
+ if(i > 0)
+ BIO_printf(out, "Verified OK\n");
+ else if(i == 0)
+ {
+ BIO_printf(out, "Verification Failure\n");
+ return 1;
+ }
+ else
+ {
+ BIO_printf(bio_err, "Error Verifying Data\n");
+ ERR_print_errors(bio_err);
+ return 1;
+ }
+ return 0;
+ }
+ if(key)
+ {
+ EVP_MD_CTX *ctx;
+ BIO_get_md_ctx(bp, &ctx);
+ len = BUFSIZE;
+ if(!EVP_DigestSignFinal(ctx, buf, &len))
+ {
+ BIO_printf(bio_err, "Error Signing Data\n");
+ ERR_print_errors(bio_err);
+ return 1;
+ }
+ }
+ else
+ {
+ len=BIO_gets(bp,(char *)buf,BUFSIZE);
+ if ((int)len <0)
+ {
+ ERR_print_errors(bio_err);
+ return 1;
+ }
+ }
+
+ if(binout) BIO_write(out, buf, len);
+ else if (sep == 2)
+ {
+ for (i=0; i<(int)len; i++)
+ BIO_printf(out, "%02x",buf[i]);
+ BIO_printf(out, " *%s\n", file);
+ }
+ else
+ {
+ if (sig_name)
+ BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file);
+ else if (md_name)
+ BIO_printf(out, "%s(%s)= ", md_name, file);
+ else
+ BIO_printf(out, "(%s)= ", file);
+ for (i=0; i<(int)len; i++)
+ {
+ if (sep && (i != 0))
+ BIO_printf(out, ":");
+ BIO_printf(out, "%02x",buf[i]);
+ }
+ BIO_printf(out, "\n");
+ }
+ return 0;
+ }
+
diff --git a/deps/openssl/openssl/apps/dh.c b/deps/openssl/openssl/apps/dh.c
new file mode 100644
index 000000000..dee9c01fc
--- /dev/null
+++ b/deps/openssl/openssl/apps/dh.c
@@ -0,0 +1,355 @@
+/* apps/dh.c */
+/* obsoleted by dhparam.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
+#ifndef OPENSSL_NO_DH
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG dh_main
+
+/* -inform arg - input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ * -check - check the parameters are ok
+ * -noout
+ * -text
+ * -C
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ DH *dh=NULL;
+ int i,badops=0,text=0;
+ BIO *in=NULL,*out=NULL;
+ int informat,outformat,check=0,noout=0,C=0,ret=1;
+ char *infile,*outfile,*prog;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine;
+#endif
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+#ifndef OPENSSL_NO_ENGINE
+ engine=NULL;
+#endif
+ infile=NULL;
+ outfile=NULL;
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-check") == 0)
+ check=1;
+ else if (strcmp(*argv,"-text") == 0)
+ text=1;
+ else if (strcmp(*argv,"-C") == 0)
+ C=1;
+ else if (strcmp(*argv,"-noout") == 0)
+ noout=1;
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+ BIO_printf(bio_err,"where options are\n");
+ BIO_printf(bio_err," -inform arg input format - one of DER PEM\n");
+ BIO_printf(bio_err," -outform arg output format - one of DER PEM\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -out arg output file\n");
+ BIO_printf(bio_err," -check check the DH parameters\n");
+ BIO_printf(bio_err," -text print a text form of the DH parameters\n");
+ BIO_printf(bio_err," -C Output C code\n");
+ BIO_printf(bio_err," -noout no output\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
+#endif
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ in=BIO_new(BIO_s_file());
+ out=BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ if (informat == FORMAT_ASN1)
+ dh=d2i_DHparams_bio(in,NULL);
+ else if (informat == FORMAT_PEM)
+ dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL);
+ else
+ {
+ BIO_printf(bio_err,"bad input format specified\n");
+ goto end;
+ }
+ if (dh == NULL)
+ {
+ BIO_printf(bio_err,"unable to load DH parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+
+
+ if (text)
+ {
+ DHparams_print(out,dh);
+#ifdef undef
+ printf("p=");
+ BN_print(stdout,dh->p);
+ printf("\ng=");
+ BN_print(stdout,dh->g);
+ printf("\n");
+ if (dh->length != 0)
+ printf("recommended private length=%ld\n",dh->length);
+#endif
+ }
+
+ if (check)
+ {
+ if (!DH_check(dh,&i))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (i & DH_CHECK_P_NOT_PRIME)
+ printf("p value is not prime\n");
+ if (i & DH_CHECK_P_NOT_SAFE_PRIME)
+ printf("p value is not a safe prime\n");
+ if (i & DH_UNABLE_TO_CHECK_GENERATOR)
+ printf("unable to check the generator value\n");
+ if (i & DH_NOT_SUITABLE_GENERATOR)
+ printf("the g value is not a generator\n");
+ if (i == 0)
+ printf("DH parameters appear to be ok.\n");
+ }
+ if (C)
+ {
+ unsigned char *data;
+ int len,l,bits;
+
+ len=BN_num_bytes(dh->p);
+ bits=BN_num_bits(dh->p);
+ data=(unsigned char *)OPENSSL_malloc(len);
+ if (data == NULL)
+ {
+ perror("OPENSSL_malloc");
+ goto end;
+ }
+ l=BN_bn2bin(dh->p,data);
+ printf("static unsigned char dh%d_p[]={",bits);
+ for (i=0; i<l; i++)
+ {
+ if ((i%12) == 0) printf("\n\t");
+ printf("0x%02X,",data[i]);
+ }
+ printf("\n\t};\n");
+
+ l=BN_bn2bin(dh->g,data);
+ printf("static unsigned char dh%d_g[]={",bits);
+ for (i=0; i<l; i++)
+ {
+ if ((i%12) == 0) printf("\n\t");
+ printf("0x%02X,",data[i]);
+ }
+ printf("\n\t};\n\n");
+
+ printf("DH *get_dh%d()\n\t{\n",bits);
+ printf("\tDH *dh;\n\n");
+ printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
+ printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
+ bits,bits);
+ printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
+ bits,bits);
+ printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
+ printf("\t\treturn(NULL);\n");
+ printf("\treturn(dh);\n\t}\n");
+ OPENSSL_free(data);
+ }
+
+
+ if (!noout)
+ {
+ if (outformat == FORMAT_ASN1)
+ i=i2d_DHparams_bio(out,dh);
+ else if (outformat == FORMAT_PEM)
+ i=PEM_write_bio_DHparams(out,dh);
+ else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (!i)
+ {
+ BIO_printf(bio_err,"unable to write DH parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ ret=0;
+end:
+ if (in != NULL) BIO_free(in);
+ if (out != NULL) BIO_free_all(out);
+ if (dh != NULL) DH_free(dh);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+#else /* !OPENSSL_NO_DH */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/dh1024.pem b/deps/openssl/openssl/apps/dh1024.pem
new file mode 100644
index 000000000..6eaeca9b8
--- /dev/null
+++ b/deps/openssl/openssl/apps/dh1024.pem
@@ -0,0 +1,10 @@
+-----BEGIN DH PARAMETERS-----
+MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY
+jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6
+ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC
+-----END DH PARAMETERS-----
+
+These are the 1024 bit DH parameters from "Assigned Number for SKIP Protocols"
+(http://www.skip-vpn.org/spec/numbers.html).
+See there for how they were generated.
+Note that g is not a generator, but this is not a problem since p is a safe prime.
diff --git a/deps/openssl/openssl/apps/dh2048.pem b/deps/openssl/openssl/apps/dh2048.pem
new file mode 100644
index 000000000..dcd0b8d01
--- /dev/null
+++ b/deps/openssl/openssl/apps/dh2048.pem
@@ -0,0 +1,12 @@
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV
+89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50
+T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb
+zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX
+Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT
+CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==
+-----END DH PARAMETERS-----
+
+These are the 2048 bit DH parameters from "Assigned Number for SKIP Protocols"
+(http://www.skip-vpn.org/spec/numbers.html).
+See there for how they were generated.
diff --git a/deps/openssl/openssl/apps/dh4096.pem b/deps/openssl/openssl/apps/dh4096.pem
new file mode 100644
index 000000000..1b35ad8e6
--- /dev/null
+++ b/deps/openssl/openssl/apps/dh4096.pem
@@ -0,0 +1,18 @@
+-----BEGIN DH PARAMETERS-----
+MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ
+l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt
+Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS
+Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98
+VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc
+alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM
+sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9
+ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte
+OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH
+AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL
+KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=
+-----END DH PARAMETERS-----
+
+These are the 4096 bit DH parameters from "Assigned Number for SKIP Protocols"
+(http://www.skip-vpn.org/spec/numbers.html).
+See there for how they were generated.
+Note that g is not a generator, but this is not a problem since p is a safe prime.
diff --git a/deps/openssl/openssl/apps/dh512.pem b/deps/openssl/openssl/apps/dh512.pem
new file mode 100644
index 000000000..200d16cd8
--- /dev/null
+++ b/deps/openssl/openssl/apps/dh512.pem
@@ -0,0 +1,9 @@
+-----BEGIN DH PARAMETERS-----
+MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak
+XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC
+-----END DH PARAMETERS-----
+
+These are the 512 bit DH parameters from "Assigned Number for SKIP Protocols"
+(http://www.skip-vpn.org/spec/numbers.html).
+See there for how they were generated.
+Note that g is not a generator, but this is not a problem since p is a safe prime.
diff --git a/deps/openssl/openssl/apps/dhparam.c b/deps/openssl/openssl/apps/dhparam.c
new file mode 100644
index 000000000..1297d6fb5
--- /dev/null
+++ b/deps/openssl/openssl/apps/dhparam.c
@@ -0,0 +1,559 @@
+/* apps/dhparam.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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).
+ *
+ */
+
+#include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
+#ifndef OPENSSL_NO_DH
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#undef PROG
+#define PROG dhparam_main
+
+#define DEFBITS 512
+
+/* -inform arg - input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ * -dsaparam - read or generate DSA parameters, convert to DH
+ * -check - check the parameters are ok
+ * -noout
+ * -text
+ * -C
+ */
+
+static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ DH *dh=NULL;
+ int i,badops=0,text=0;
+#ifndef OPENSSL_NO_DSA
+ int dsaparam=0;
+#endif
+ BIO *in=NULL,*out=NULL;
+ int informat,outformat,check=0,noout=0,C=0,ret=1;
+ char *infile,*outfile,*prog;
+ char *inrand=NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+ int num = 0, g = 0;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ infile=NULL;
+ outfile=NULL;
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-check") == 0)
+ check=1;
+ else if (strcmp(*argv,"-text") == 0)
+ text=1;
+#ifndef OPENSSL_NO_DSA
+ else if (strcmp(*argv,"-dsaparam") == 0)
+ dsaparam=1;
+#endif
+ else if (strcmp(*argv,"-C") == 0)
+ C=1;
+ else if (strcmp(*argv,"-noout") == 0)
+ noout=1;
+ else if (strcmp(*argv,"-2") == 0)
+ g=2;
+ else if (strcmp(*argv,"-5") == 0)
+ g=5;
+ else if (strcmp(*argv,"-rand") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inrand= *(++argv);
+ }
+ else if (((sscanf(*argv,"%d",&num) == 0) || (num <= 0)))
+ goto bad;
+ argv++;
+ argc--;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err,"%s [options] [numbits]\n",prog);
+ BIO_printf(bio_err,"where options are\n");
+ BIO_printf(bio_err," -inform arg input format - one of DER PEM\n");
+ BIO_printf(bio_err," -outform arg output format - one of DER PEM\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -out arg output file\n");
+#ifndef OPENSSL_NO_DSA
+ BIO_printf(bio_err," -dsaparam read or generate DSA parameters, convert to DH\n");
+#endif
+ BIO_printf(bio_err," -check check the DH parameters\n");
+ BIO_printf(bio_err," -text print a text form of the DH parameters\n");
+ BIO_printf(bio_err," -C Output C code\n");
+ BIO_printf(bio_err," -2 generate parameters using 2 as the generator value\n");
+ BIO_printf(bio_err," -5 generate parameters using 5 as the generator value\n");
+ BIO_printf(bio_err," numbits number of bits in to generate (default 512)\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err," - load the file (or the files in the directory) into\n");
+ BIO_printf(bio_err," the random number generator\n");
+ BIO_printf(bio_err," -noout no output\n");
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ if (g && !num)
+ num = DEFBITS;
+
+#ifndef OPENSSL_NO_DSA
+ if (dsaparam)
+ {
+ if (g)
+ {
+ BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n");
+ goto end;
+ }
+ }
+ else
+#endif
+ {
+ /* DH parameters */
+ if (num && !g)
+ g = 2;
+ }
+
+ if(num) {
+
+ BN_GENCB cb;
+ BN_GENCB_set(&cb, dh_cb, bio_err);
+ if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
+ {
+ BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+ }
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+
+#ifndef OPENSSL_NO_DSA
+ if (dsaparam)
+ {
+ DSA *dsa = DSA_new();
+
+ BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
+ if(!dsa || !DSA_generate_parameters_ex(dsa, num,
+ NULL, 0, NULL, NULL, &cb))
+ {
+ if(dsa) DSA_free(dsa);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ dh = DSA_dup_DH(dsa);
+ DSA_free(dsa);
+ if (dh == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ else
+#endif
+ {
+ dh = DH_new();
+ BIO_printf(bio_err,"Generating DH parameters, %d bit long safe prime, generator %d\n",num,g);
+ BIO_printf(bio_err,"This is going to take a long time\n");
+ if(!dh || !DH_generate_parameters_ex(dh, num, g, &cb))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ app_RAND_write_file(NULL, bio_err);
+ } else {
+
+ in=BIO_new(BIO_s_file());
+ if (in == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+
+ if (informat != FORMAT_ASN1 && informat != FORMAT_PEM)
+ {
+ BIO_printf(bio_err,"bad input format specified\n");
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_DSA
+ if (dsaparam)
+ {
+ DSA *dsa;
+
+ if (informat == FORMAT_ASN1)
+ dsa=d2i_DSAparams_bio(in,NULL);
+ else /* informat == FORMAT_PEM */
+ dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
+
+ if (dsa == NULL)
+ {
+ BIO_printf(bio_err,"unable to load DSA parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ dh = DSA_dup_DH(dsa);
+ DSA_free(dsa);
+ if (dh == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ else
+#endif
+ {
+ if (informat == FORMAT_ASN1)
+ dh=d2i_DHparams_bio(in,NULL);
+ else /* informat == FORMAT_PEM */
+ dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL);
+
+ if (dh == NULL)
+ {
+ BIO_printf(bio_err,"unable to load DH parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ /* dh != NULL */
+ }
+
+ out=BIO_new(BIO_s_file());
+ if (out == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+
+ if (text)
+ {
+ DHparams_print(out,dh);
+ }
+
+ if (check)
+ {
+ if (!DH_check(dh,&i))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (i & DH_CHECK_P_NOT_PRIME)
+ printf("p value is not prime\n");
+ if (i & DH_CHECK_P_NOT_SAFE_PRIME)
+ printf("p value is not a safe prime\n");
+ if (i & DH_UNABLE_TO_CHECK_GENERATOR)
+ printf("unable to check the generator value\n");
+ if (i & DH_NOT_SUITABLE_GENERATOR)
+ printf("the g value is not a generator\n");
+ if (i == 0)
+ printf("DH parameters appear to be ok.\n");
+ }
+ if (C)
+ {
+ unsigned char *data;
+ int len,l,bits;
+
+ len=BN_num_bytes(dh->p);
+ bits=BN_num_bits(dh->p);
+ data=(unsigned char *)OPENSSL_malloc(len);
+ if (data == NULL)
+ {
+ perror("OPENSSL_malloc");
+ goto end;
+ }
+ printf("#ifndef HEADER_DH_H\n"
+ "#include <openssl/dh.h>\n"
+ "#endif\n");
+ printf("DH *get_dh%d()\n\t{\n",bits);
+
+ l=BN_bn2bin(dh->p,data);
+ printf("\tstatic unsigned char dh%d_p[]={",bits);
+ for (i=0; i<l; i++)
+ {
+ if ((i%12) == 0) printf("\n\t\t");
+ printf("0x%02X,",data[i]);
+ }
+ printf("\n\t\t};\n");
+
+ l=BN_bn2bin(dh->g,data);
+ printf("\tstatic unsigned char dh%d_g[]={",bits);
+ for (i=0; i<l; i++)
+ {
+ if ((i%12) == 0) printf("\n\t\t");
+ printf("0x%02X,",data[i]);
+ }
+ printf("\n\t\t};\n");
+
+ printf("\tDH *dh;\n\n");
+ printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
+ printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
+ bits,bits);
+ printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
+ bits,bits);
+ printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
+ printf("\t\t{ DH_free(dh); return(NULL); }\n");
+ if (dh->length)
+ printf("\tdh->length = %ld;\n", dh->length);
+ printf("\treturn(dh);\n\t}\n");
+ OPENSSL_free(data);
+ }
+
+
+ if (!noout)
+ {
+ if (outformat == FORMAT_ASN1)
+ i=i2d_DHparams_bio(out,dh);
+ else if (outformat == FORMAT_PEM)
+ i=PEM_write_bio_DHparams(out,dh);
+ else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (!i)
+ {
+ BIO_printf(bio_err,"unable to write DH parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ ret=0;
+end:
+ if (in != NULL) BIO_free(in);
+ if (out != NULL) BIO_free_all(out);
+ if (dh != NULL) DH_free(dh);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+/* dh_cb is identical to dsa_cb in apps/dsaparam.c */
+static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb)
+ {
+ char c='*';
+
+ if (p == 0) c='.';
+ if (p == 1) c='+';
+ if (p == 2) c='*';
+ if (p == 3) c='\n';
+ BIO_write(cb->arg,&c,1);
+ (void)BIO_flush(cb->arg);
+#ifdef LINT
+ p=n;
+#endif
+ return 1;
+ }
+
+#else /* !OPENSSL_NO_DH */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/dsa-ca.pem b/deps/openssl/openssl/apps/dsa-ca.pem
new file mode 100644
index 000000000..cccc14208
--- /dev/null
+++ b/deps/openssl/openssl/apps/dsa-ca.pem
@@ -0,0 +1,40 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBugIBAAKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQ
+PnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtel
+u+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcH
+Me36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLso
+hkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbu
+SXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7Y
+Mu0OArgCgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuHvSLw9YUrJahcBHmbpvt4
+94lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUqAylOVFJJJXuirVJ+o+0T
+tOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u3enxhqnDGQIUB78dhW77
+J6zsFbSEHaQGUmfSeoM=
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE REQUEST-----
+MIICUjCCAhECAQAwUjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
+ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDELMAkGA1UEAxMCQ0Ew
+ggG0MIIBKQYFKw4DAgwwggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaW
+sxXgUy6P4FmCc5A+dTGZR3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5m
+rmuINvvsKNzC16W75Sw5JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHk
+cJVbUM1JAhUA9wcx7fpsBgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVo
+bzDjaeHls12YuyiGSPzemQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqR
+CZ228U2cVA9YBu5JdAfOVX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxB
+F5WS6wG1c6Vqftgy7Q4CuAOBhAACgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuH
+vSLw9YUrJahcBHmbpvt494lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUq
+AylOVFJJJXuirVJ+o+0TtOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u
+3enxhqnDGaAAMAkGBSsOAwIbBQADMAAwLQIVAJGVuFsG/0DBuSZ0jF7ypdU0/G0v
+AhQfeF5BoMMDbX/kidUVpQ6gadPlZA==
+-----END CERTIFICATE REQUEST-----
+-----BEGIN CERTIFICATE-----
+MIIBrjCCAWwCAQswCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
+CgYDVQQDEwNQQ0EwHhcNOTcwNjE1MDIxNDI5WhcNOTcwNzE1MDIxNDI5WjBSMQsw
+CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
+ZXQgV2lkZ2l0cyBQdHkgTHRkMQswCQYDVQQDEwJDQTCBkjAJBgUrDgMCDAUAA4GE
+AAKBgBqmWXqKrP1etkWWTYYJVwH4qKHFacfsi4e9IvD1hSslqFwEeZum+3j3iUXi
+ALnDdY8z69cmh9u6yTgahAQSxA0wNpqHibj25SoDKU5UUkkle6KtUn6j7RO04UMh
+MQCX5hllquJc4Pu105I6X1Esw8Lr51ocpL17ry7d6fGGqcMZMAkGBSsOAwIbBQAD
+MQAwLgIVAJ4wtQsANPxHo7Q4IQZYsL12SKdbAhUAjJ9n38zxT+iai2164xS+LIfa
+C1Q=
+-----END CERTIFICATE-----
+
diff --git a/deps/openssl/openssl/apps/dsa-pca.pem b/deps/openssl/openssl/apps/dsa-pca.pem
new file mode 100644
index 000000000..d23774edd
--- /dev/null
+++ b/deps/openssl/openssl/apps/dsa-pca.pem
@@ -0,0 +1,46 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQ
+PnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtel
+u+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcH
+Me36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLso
+hkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbu
+SXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7Y
+Mu0OArgCgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk
+umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A
+29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUCFQDNvrBz
+6TicfImU7UFRn9h00j0lJQ==
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE REQUEST-----
+MIICVTCCAhMCAQAwUzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
+ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDUENB
+MIIBtTCCASkGBSsOAwIMMIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2G
+lrMV4FMuj+BZgnOQPnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7O
+Zq5riDb77Cjcwtelu+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR
+5HCVW1DNSQIVAPcHMe36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnl
+aG8w42nh5bNdmLsohkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6
+kQmdtvFNnFQPWAbuSXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15Als
+QReVkusBtXOlan7YMu0OArgDgYUAAoGBAKbtuR5AdW+ICjCFe2ixjUiJJzM2IKwe
+6NZEMXg39+HQ1UTPTmfLZLps+rZfolHDXuRKMXbGFdSF0nXYzotPCzi7GauwEJTZ
+yr27ZZjA1C6apGSQ9GzuwNvZ4rCXystVEagAS8OQ4H3D4dWS17Zg31ICb5o4E5r0
+z09o/Uz46u0VoAAwCQYFKw4DAhsFAAMxADAuAhUArRubTxsbIXy3AhtjQ943AbNB
+nSICFQCu+g1iW3jwF+gOcbroD4S/ZcvB3w==
+-----END CERTIFICATE REQUEST-----
+-----BEGIN CERTIFICATE-----
+MIIC0zCCApECAQAwCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
+CgYDVQQDEwNQQ0EwHhcNOTcwNjE0MjI1NDQ1WhcNOTcwNzE0MjI1NDQ1WjBTMQsw
+CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
+ZXQgV2lkZ2l0cyBQdHkgTHRkMQwwCgYDVQQDEwNQQ0EwggG1MIIBKQYFKw4DAgww
+ggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaWsxXgUy6P4FmCc5A+dTGZ
+R3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5mrmuINvvsKNzC16W75Sw5
+JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHkcJVbUM1JAhUA9wcx7fps
+BgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVobzDjaeHls12YuyiGSPze
+mQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqRCZ228U2cVA9YBu5JdAfO
+VX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxBF5WS6wG1c6Vqftgy7Q4C
+uAOBhQACgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk
+umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A
+29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUwCQYFKw4D
+AhsFAAMxADAuAhUAvtv6AkMolix1Jvy3UnVEIUqdCUICFQC+jq8P49mwrY9oJ24n
+5rKUjNBhSg==
+-----END CERTIFICATE-----
+
diff --git a/deps/openssl/openssl/apps/dsa.c b/deps/openssl/openssl/apps/dsa.c
new file mode 100644
index 000000000..5222487ab
--- /dev/null
+++ b/deps/openssl/openssl/apps/dsa.c
@@ -0,0 +1,376 @@
+/* apps/dsa.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DSA
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/dsa.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/bn.h>
+
+#undef PROG
+#define PROG dsa_main
+
+/* -inform arg - input format - default PEM (one of DER, NET or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ * -des - encrypt output if PEM format with DES in cbc mode
+ * -des3 - encrypt output if PEM format
+ * -idea - encrypt output if PEM format
+ * -aes128 - encrypt output if PEM format
+ * -aes192 - encrypt output if PEM format
+ * -aes256 - encrypt output if PEM format
+ * -camellia128 - encrypt output if PEM format
+ * -camellia192 - encrypt output if PEM format
+ * -camellia256 - encrypt output if PEM format
+ * -seed - encrypt output if PEM format
+ * -text - print a text version
+ * -modulus - print the DSA public key
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ int ret=1;
+ DSA *dsa=NULL;
+ int i,badops=0;
+ const EVP_CIPHER *enc=NULL;
+ BIO *in=NULL,*out=NULL;
+ int informat,outformat,text=0,noout=0;
+ int pubin = 0, pubout = 0;
+ char *infile,*outfile,*prog;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine;
+#endif
+ char *passargin = NULL, *passargout = NULL;
+ char *passin = NULL, *passout = NULL;
+ int modulus=0;
+
+ int pvk_encr = 2;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+#ifndef OPENSSL_NO_ENGINE
+ engine=NULL;
+#endif
+ infile=NULL;
+ outfile=NULL;
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-passin") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargin= *(++argv);
+ }
+ else if (strcmp(*argv,"-passout") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargout= *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-pvk-strong") == 0)
+ pvk_encr=2;
+ else if (strcmp(*argv,"-pvk-weak") == 0)
+ pvk_encr=1;
+ else if (strcmp(*argv,"-pvk-none") == 0)
+ pvk_encr=0;
+ else if (strcmp(*argv,"-noout") == 0)
+ noout=1;
+ else if (strcmp(*argv,"-text") == 0)
+ text=1;
+ else if (strcmp(*argv,"-modulus") == 0)
+ modulus=1;
+ else if (strcmp(*argv,"-pubin") == 0)
+ pubin=1;
+ else if (strcmp(*argv,"-pubout") == 0)
+ pubout=1;
+ else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+ BIO_printf(bio_err,"where options are\n");
+ BIO_printf(bio_err," -inform arg input format - DER or PEM\n");
+ BIO_printf(bio_err," -outform arg output format - DER or PEM\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -passin arg input file pass phrase source\n");
+ BIO_printf(bio_err," -out arg output file\n");
+ BIO_printf(bio_err," -passout arg output file pass phrase source\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf(bio_err," -des encrypt PEM output with cbc des\n");
+ BIO_printf(bio_err," -des3 encrypt PEM output with ede cbc des using 168 bit key\n");
+#ifndef OPENSSL_NO_IDEA
+ BIO_printf(bio_err," -idea encrypt PEM output with cbc idea\n");
+#endif
+#ifndef OPENSSL_NO_AES
+ BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
+ BIO_printf(bio_err," encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
+ BIO_printf(bio_err," encrypt PEM output with cbc camellia\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+ BIO_printf(bio_err," -seed encrypt PEM output with cbc seed\n");
+#endif
+ BIO_printf(bio_err," -text print the key in text\n");
+ BIO_printf(bio_err," -noout don't print key out\n");
+ BIO_printf(bio_err," -modulus print the DSA public value\n");
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
+ BIO_printf(bio_err, "Error getting passwords\n");
+ goto end;
+ }
+
+ in=BIO_new(BIO_s_file());
+ out=BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+
+ BIO_printf(bio_err,"read DSA key\n");
+
+ {
+ EVP_PKEY *pkey;
+
+ if (pubin)
+ pkey = load_pubkey(bio_err, infile, informat, 1,
+ passin, e, "Public Key");
+ else
+ pkey = load_key(bio_err, infile, informat, 1,
+ passin, e, "Private Key");
+
+ if (pkey)
+ {
+ dsa = EVP_PKEY_get1_DSA(pkey);
+ EVP_PKEY_free(pkey);
+ }
+ }
+ if (dsa == NULL)
+ {
+ BIO_printf(bio_err,"unable to load Key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ if (text)
+ if (!DSA_print(out,dsa,0))
+ {
+ perror(outfile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (modulus)
+ {
+ fprintf(stdout,"Public Key=");
+ BN_print(out,dsa->pub_key);
+ fprintf(stdout,"\n");
+ }
+
+ if (noout) goto end;
+ BIO_printf(bio_err,"writing DSA key\n");
+ if (outformat == FORMAT_ASN1) {
+ if(pubin || pubout) i=i2d_DSA_PUBKEY_bio(out,dsa);
+ else i=i2d_DSAPrivateKey_bio(out,dsa);
+ } else if (outformat == FORMAT_PEM) {
+ if(pubin || pubout)
+ i=PEM_write_bio_DSA_PUBKEY(out,dsa);
+ else i=PEM_write_bio_DSAPrivateKey(out,dsa,enc,
+ NULL,0,NULL, passout);
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4)
+ } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
+ EVP_PKEY *pk;
+ pk = EVP_PKEY_new();
+ EVP_PKEY_set1_DSA(pk, dsa);
+ if (outformat == FORMAT_PVK)
+ i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
+ else if (pubin || pubout)
+ i = i2b_PublicKey_bio(out, pk);
+ else
+ i = i2b_PrivateKey_bio(out, pk);
+ EVP_PKEY_free(pk);
+#endif
+ } else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (i <= 0)
+ {
+ BIO_printf(bio_err,"unable to write private key\n");
+ ERR_print_errors(bio_err);
+ }
+ else
+ ret=0;
+end:
+ if(in != NULL) BIO_free(in);
+ if(out != NULL) BIO_free_all(out);
+ if(dsa != NULL) DSA_free(dsa);
+ if(passin) OPENSSL_free(passin);
+ if(passout) OPENSSL_free(passout);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+#else /* !OPENSSL_NO_DSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/dsa1024.pem b/deps/openssl/openssl/apps/dsa1024.pem
new file mode 100644
index 000000000..082dec389
--- /dev/null
+++ b/deps/openssl/openssl/apps/dsa1024.pem
@@ -0,0 +1,9 @@
+-----BEGIN DSA PARAMETERS-----
+MIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQPnUx
+mUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtelu+Us
+OSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcHMe36
+bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLsohkj8
+3pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbuSXQH
+zlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7YMu0O
+Arg=
+-----END DSA PARAMETERS-----
diff --git a/deps/openssl/openssl/apps/dsa512.pem b/deps/openssl/openssl/apps/dsa512.pem
new file mode 100644
index 000000000..5f86d1a6e
--- /dev/null
+++ b/deps/openssl/openssl/apps/dsa512.pem
@@ -0,0 +1,6 @@
+-----BEGIN DSA PARAMETERS-----
+MIGdAkEAnRtpjibb8isRcBmG9hnI+BnyGFOURgbQYlAzSwI8UjADizv5X9EkBk97
+TLqqQJv9luQ3M7stWtdaEUBmonZ9MQIVAPtT71C0QJIxVoZTeuiLIppJ+3GPAkEA
+gz6I5cWJc847bAFJv7PHnwrqRJHlMKrZvltftxDXibeOdPvPKR7rqCxUUbgQ3qDO
+L8wka5B33qJoplISogOdIA==
+-----END DSA PARAMETERS-----
diff --git a/deps/openssl/openssl/apps/dsap.pem b/deps/openssl/openssl/apps/dsap.pem
new file mode 100644
index 000000000..d4dfdb305
--- /dev/null
+++ b/deps/openssl/openssl/apps/dsap.pem
@@ -0,0 +1,6 @@
+-----BEGIN DSA PARAMETERS-----
+MIGcAkEA+ZiKEvZmc9MtnaFZh4NiZ3oZS4J1PHvPrm9MXj5ntVheDPkdmBDTncya
+GAJcMjwsyB/GvLDGd6yGCw/8eF+09wIVAK3VagOxGd/Q4Af5NbxR5FB7CXEjAkA2
+t/q7HgVLi0KeKvcDG8BRl3wuy7bCvpjgtWiJc/tpvcuzeuAayH89UofjAGueKjXD
+ADiRffvSdhrNw5dkqdql
+-----END DSA PARAMETERS-----
diff --git a/deps/openssl/openssl/apps/dsaparam.c b/deps/openssl/openssl/apps/dsaparam.c
new file mode 100644
index 000000000..683d51391
--- /dev/null
+++ b/deps/openssl/openssl/apps/dsaparam.c
@@ -0,0 +1,486 @@
+/* apps/dsaparam.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG dsaparam_main
+
+/* -inform arg - input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ * -noout
+ * -text
+ * -C
+ * -noout
+ * -genkey
+ * #ifdef GENCB_TEST
+ * -timebomb n - interrupt keygen after <n> seconds
+ * #endif
+ */
+
+#ifdef GENCB_TEST
+
+static int stop_keygen_flag = 0;
+
+static void timebomb_sigalarm(int foo)
+ {
+ stop_keygen_flag = 1;
+ }
+
+#endif
+
+static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ DSA *dsa=NULL;
+ int i,badops=0,text=0;
+ BIO *in=NULL,*out=NULL;
+ int informat,outformat,noout=0,C=0,ret=1;
+ char *infile,*outfile,*prog,*inrand=NULL;
+ int numbits= -1,num,genkey=0;
+ int need_rand=0;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+#ifdef GENCB_TEST
+ int timebomb=0;
+#endif
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ infile=NULL;
+ outfile=NULL;
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if(strcmp(*argv, "-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine = *(++argv);
+ }
+#endif
+#ifdef GENCB_TEST
+ else if(strcmp(*argv, "-timebomb") == 0)
+ {
+ if (--argc < 1) goto bad;
+ timebomb = atoi(*(++argv));
+ }
+#endif
+ else if (strcmp(*argv,"-text") == 0)
+ text=1;
+ else if (strcmp(*argv,"-C") == 0)
+ C=1;
+ else if (strcmp(*argv,"-genkey") == 0)
+ {
+ genkey=1;
+ need_rand=1;
+ }
+ else if (strcmp(*argv,"-rand") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inrand= *(++argv);
+ need_rand=1;
+ }
+ else if (strcmp(*argv,"-noout") == 0)
+ noout=1;
+ else if (sscanf(*argv,"%d",&num) == 1)
+ {
+ /* generate a key */
+ numbits=num;
+ need_rand=1;
+ }
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err,"%s [options] [bits] <infile >outfile\n",prog);
+ BIO_printf(bio_err,"where options are\n");
+ BIO_printf(bio_err," -inform arg input format - DER or PEM\n");
+ BIO_printf(bio_err," -outform arg output format - DER or PEM\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -out arg output file\n");
+ BIO_printf(bio_err," -text print as text\n");
+ BIO_printf(bio_err," -C Output C code\n");
+ BIO_printf(bio_err," -noout no output\n");
+ BIO_printf(bio_err," -genkey generate a DSA key\n");
+ BIO_printf(bio_err," -rand files to use for random number input\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
+#endif
+#ifdef GENCB_TEST
+ BIO_printf(bio_err," -timebomb n interrupt keygen after <n> seconds\n");
+#endif
+ BIO_printf(bio_err," number number of bits to use for generating private key\n");
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+
+ in=BIO_new(BIO_s_file());
+ out=BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ if (need_rand)
+ {
+ app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+ }
+
+ if (numbits > 0)
+ {
+ BN_GENCB cb;
+ BN_GENCB_set(&cb, dsa_cb, bio_err);
+ assert(need_rand);
+ dsa = DSA_new();
+ if(!dsa)
+ {
+ BIO_printf(bio_err,"Error allocating DSA object\n");
+ goto end;
+ }
+ BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
+ BIO_printf(bio_err,"This could take some time\n");
+#ifdef GENCB_TEST
+ if(timebomb > 0)
+ {
+ struct sigaction act;
+ act.sa_handler = timebomb_sigalarm;
+ act.sa_flags = 0;
+ BIO_printf(bio_err,"(though I'll stop it if not done within %d secs)\n",
+ timebomb);
+ if(sigaction(SIGALRM, &act, NULL) != 0)
+ {
+ BIO_printf(bio_err,"Error, couldn't set SIGALRM handler\n");
+ goto end;
+ }
+ alarm(timebomb);
+ }
+#endif
+ if(!DSA_generate_parameters_ex(dsa,num,NULL,0,NULL,NULL, &cb))
+ {
+#ifdef GENCB_TEST
+ if(stop_keygen_flag)
+ {
+ BIO_printf(bio_err,"DSA key generation time-stopped\n");
+ /* This is an asked-for behaviour! */
+ ret = 0;
+ goto end;
+ }
+#endif
+ ERR_print_errors(bio_err);
+ BIO_printf(bio_err,"Error, DSA key generation failed\n");
+ goto end;
+ }
+ }
+ else if (informat == FORMAT_ASN1)
+ dsa=d2i_DSAparams_bio(in,NULL);
+ else if (informat == FORMAT_PEM)
+ dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
+ else
+ {
+ BIO_printf(bio_err,"bad input format specified\n");
+ goto end;
+ }
+ if (dsa == NULL)
+ {
+ BIO_printf(bio_err,"unable to load DSA parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (text)
+ {
+ DSAparams_print(out,dsa);
+ }
+
+ if (C)
+ {
+ unsigned char *data;
+ int l,len,bits_p;
+
+ len=BN_num_bytes(dsa->p);
+ bits_p=BN_num_bits(dsa->p);
+ data=(unsigned char *)OPENSSL_malloc(len+20);
+ if (data == NULL)
+ {
+ perror("OPENSSL_malloc");
+ goto end;
+ }
+ l=BN_bn2bin(dsa->p,data);
+ printf("static unsigned char dsa%d_p[]={",bits_p);
+ for (i=0; i<l; i++)
+ {
+ if ((i%12) == 0) printf("\n\t");
+ printf("0x%02X,",data[i]);
+ }
+ printf("\n\t};\n");
+
+ l=BN_bn2bin(dsa->q,data);
+ printf("static unsigned char dsa%d_q[]={",bits_p);
+ for (i=0; i<l; i++)
+ {
+ if ((i%12) == 0) printf("\n\t");
+ printf("0x%02X,",data[i]);
+ }
+ printf("\n\t};\n");
+
+ l=BN_bn2bin(dsa->g,data);
+ printf("static unsigned char dsa%d_g[]={",bits_p);
+ for (i=0; i<l; i++)
+ {
+ if ((i%12) == 0) printf("\n\t");
+ printf("0x%02X,",data[i]);
+ }
+ printf("\n\t};\n\n");
+
+ printf("DSA *get_dsa%d()\n\t{\n",bits_p);
+ printf("\tDSA *dsa;\n\n");
+ printf("\tif ((dsa=DSA_new()) == NULL) return(NULL);\n");
+ printf("\tdsa->p=BN_bin2bn(dsa%d_p,sizeof(dsa%d_p),NULL);\n",
+ bits_p,bits_p);
+ printf("\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\n",
+ bits_p,bits_p);
+ printf("\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),NULL);\n",
+ bits_p,bits_p);
+ printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n");
+ printf("\t\t{ DSA_free(dsa); return(NULL); }\n");
+ printf("\treturn(dsa);\n\t}\n");
+ }
+
+
+ if (!noout)
+ {
+ if (outformat == FORMAT_ASN1)
+ i=i2d_DSAparams_bio(out,dsa);
+ else if (outformat == FORMAT_PEM)
+ i=PEM_write_bio_DSAparams(out,dsa);
+ else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (!i)
+ {
+ BIO_printf(bio_err,"unable to write DSA parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ if (genkey)
+ {
+ DSA *dsakey;
+
+ assert(need_rand);
+ if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end;
+ if (!DSA_generate_key(dsakey))
+ {
+ ERR_print_errors(bio_err);
+ DSA_free(dsakey);
+ goto end;
+ }
+ if (outformat == FORMAT_ASN1)
+ i=i2d_DSAPrivateKey_bio(out,dsakey);
+ else if (outformat == FORMAT_PEM)
+ i=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL,NULL);
+ else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ DSA_free(dsakey);
+ goto end;
+ }
+ DSA_free(dsakey);
+ }
+ if (need_rand)
+ app_RAND_write_file(NULL, bio_err);
+ ret=0;
+end:
+ if (in != NULL) BIO_free(in);
+ if (out != NULL) BIO_free_all(out);
+ if (dsa != NULL) DSA_free(dsa);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb)
+ {
+ char c='*';
+
+ if (p == 0) c='.';
+ if (p == 1) c='+';
+ if (p == 2) c='*';
+ if (p == 3) c='\n';
+ BIO_write(cb->arg,&c,1);
+ (void)BIO_flush(cb->arg);
+#ifdef LINT
+ p=n;
+#endif
+#ifdef GENCB_TEST
+ if(stop_keygen_flag)
+ return 0;
+#endif
+ return 1;
+ }
+#else /* !OPENSSL_NO_DSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/ec.c b/deps/openssl/openssl/apps/ec.c
new file mode 100644
index 000000000..896eabc13
--- /dev/null
+++ b/deps/openssl/openssl/apps/ec.c
@@ -0,0 +1,406 @@
+/* apps/ec.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 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).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG ec_main
+
+/* -inform arg - input format - default PEM (one of DER, NET or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ * -des - encrypt output if PEM format with DES in cbc mode
+ * -text - print a text version
+ * -param_out - print the elliptic curve parameters
+ * -conv_form arg - specifies the point encoding form
+ * -param_enc arg - specifies the parameter encoding
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+{
+ int ret = 1;
+ EC_KEY *eckey = NULL;
+ const EC_GROUP *group;
+ int i, badops = 0;
+ const EVP_CIPHER *enc = NULL;
+ BIO *in = NULL, *out = NULL;
+ int informat, outformat, text=0, noout=0;
+ int pubin = 0, pubout = 0, param_out = 0;
+ char *infile, *outfile, *prog, *engine;
+ char *passargin = NULL, *passargout = NULL;
+ char *passin = NULL, *passout = NULL;
+ point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
+ int new_form = 0;
+ int asn1_flag = OPENSSL_EC_NAMED_CURVE;
+ int new_asn1_flag = 0;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ engine = NULL;
+ infile = NULL;
+ outfile = NULL;
+ informat = FORMAT_PEM;
+ outformat = FORMAT_PEM;
+
+ prog = argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-passin") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargin= *(++argv);
+ }
+ else if (strcmp(*argv,"-passout") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargout= *(++argv);
+ }
+ else if (strcmp(*argv, "-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+ else if (strcmp(*argv, "-noout") == 0)
+ noout = 1;
+ else if (strcmp(*argv, "-text") == 0)
+ text = 1;
+ else if (strcmp(*argv, "-conv_form") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ ++argv;
+ new_form = 1;
+ if (strcmp(*argv, "compressed") == 0)
+ form = POINT_CONVERSION_COMPRESSED;
+ else if (strcmp(*argv, "uncompressed") == 0)
+ form = POINT_CONVERSION_UNCOMPRESSED;
+ else if (strcmp(*argv, "hybrid") == 0)
+ form = POINT_CONVERSION_HYBRID;
+ else
+ goto bad;
+ }
+ else if (strcmp(*argv, "-param_enc") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ ++argv;
+ new_asn1_flag = 1;
+ if (strcmp(*argv, "named_curve") == 0)
+ asn1_flag = OPENSSL_EC_NAMED_CURVE;
+ else if (strcmp(*argv, "explicit") == 0)
+ asn1_flag = 0;
+ else
+ goto bad;
+ }
+ else if (strcmp(*argv, "-param_out") == 0)
+ param_out = 1;
+ else if (strcmp(*argv, "-pubin") == 0)
+ pubin=1;
+ else if (strcmp(*argv, "-pubout") == 0)
+ pubout=1;
+ else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
+ {
+ BIO_printf(bio_err, "unknown option %s\n", *argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
+ BIO_printf(bio_err, "where options are\n");
+ BIO_printf(bio_err, " -inform arg input format - "
+ "DER or PEM\n");
+ BIO_printf(bio_err, " -outform arg output format - "
+ "DER or PEM\n");
+ BIO_printf(bio_err, " -in arg input file\n");
+ BIO_printf(bio_err, " -passin arg input file pass "
+ "phrase source\n");
+ BIO_printf(bio_err, " -out arg output file\n");
+ BIO_printf(bio_err, " -passout arg output file pass "
+ "phrase source\n");
+ BIO_printf(bio_err, " -engine e use engine e, "
+ "possibly a hardware device.\n");
+ BIO_printf(bio_err, " -des encrypt PEM output, "
+ "instead of 'des' every other \n"
+ " cipher "
+ "supported by OpenSSL can be used\n");
+ BIO_printf(bio_err, " -text print the key\n");
+ BIO_printf(bio_err, " -noout don't print key out\n");
+ BIO_printf(bio_err, " -param_out print the elliptic "
+ "curve parameters\n");
+ BIO_printf(bio_err, " -conv_form arg specifies the "
+ "point conversion form \n");
+ BIO_printf(bio_err, " possible values:"
+ " compressed\n");
+ BIO_printf(bio_err, " "
+ " uncompressed (default)\n");
+ BIO_printf(bio_err, " "
+ " hybrid\n");
+ BIO_printf(bio_err, " -param_enc arg specifies the way"
+ " the ec parameters are encoded\n");
+ BIO_printf(bio_err, " in the asn1 der "
+ "encoding\n");
+ BIO_printf(bio_err, " possible values:"
+ " named_curve (default)\n");
+ BIO_printf(bio_err," "
+ "explicit\n");
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ if(!app_passwd(bio_err, passargin, passargout, &passin, &passout))
+ {
+ BIO_printf(bio_err, "Error getting passwords\n");
+ goto end;
+ }
+
+ in = BIO_new(BIO_s_file());
+ out = BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in, stdin, BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in, infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+
+ BIO_printf(bio_err, "read EC key\n");
+ if (informat == FORMAT_ASN1)
+ {
+ if (pubin)
+ eckey = d2i_EC_PUBKEY_bio(in, NULL);
+ else
+ eckey = d2i_ECPrivateKey_bio(in, NULL);
+ }
+ else if (informat == FORMAT_PEM)
+ {
+ if (pubin)
+ eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL,
+ NULL);
+ else
+ eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL,
+ passin);
+ }
+ else
+ {
+ BIO_printf(bio_err, "bad input format specified for key\n");
+ goto end;
+ }
+ if (eckey == NULL)
+ {
+ BIO_printf(bio_err,"unable to load Key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out, stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out, outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ group = EC_KEY_get0_group(eckey);
+
+ if (new_form)
+ EC_KEY_set_conv_form(eckey, form);
+
+ if (new_asn1_flag)
+ EC_KEY_set_asn1_flag(eckey, asn1_flag);
+
+ if (text)
+ if (!EC_KEY_print(out, eckey, 0))
+ {
+ perror(outfile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (noout)
+ {
+ ret = 0;
+ goto end;
+ }
+
+ BIO_printf(bio_err, "writing EC key\n");
+ if (outformat == FORMAT_ASN1)
+ {
+ if (param_out)
+ i = i2d_ECPKParameters_bio(out, group);
+ else if (pubin || pubout)
+ i = i2d_EC_PUBKEY_bio(out, eckey);
+ else
+ i = i2d_ECPrivateKey_bio(out, eckey);
+ }
+ else if (outformat == FORMAT_PEM)
+ {
+ if (param_out)
+ i = PEM_write_bio_ECPKParameters(out, group);
+ else if (pubin || pubout)
+ i = PEM_write_bio_EC_PUBKEY(out, eckey);
+ else
+ i = PEM_write_bio_ECPrivateKey(out, eckey, enc,
+ NULL, 0, NULL, passout);
+ }
+ else
+ {
+ BIO_printf(bio_err, "bad output format specified for "
+ "outfile\n");
+ goto end;
+ }
+
+ if (!i)
+ {
+ BIO_printf(bio_err, "unable to write private key\n");
+ ERR_print_errors(bio_err);
+ }
+ else
+ ret=0;
+end:
+ if (in)
+ BIO_free(in);
+ if (out)
+ BIO_free_all(out);
+ if (eckey)
+ EC_KEY_free(eckey);
+ if (passin)
+ OPENSSL_free(passin);
+ if (passout)
+ OPENSSL_free(passout);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+}
+#else /* !OPENSSL_NO_EC */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/ecparam.c b/deps/openssl/openssl/apps/ecparam.c
new file mode 100644
index 000000000..465480bed
--- /dev/null
+++ b/deps/openssl/openssl/apps/ecparam.c
@@ -0,0 +1,731 @@
+/* apps/ecparam.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG ecparam_main
+
+/* -inform arg - input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ * -noout - do not print the ec parameter
+ * -text - print the ec parameters in text form
+ * -check - validate the ec parameters
+ * -C - print a 'C' function creating the parameters
+ * -name arg - use the ec parameters with 'short name' name
+ * -list_curves - prints a list of all currently available curve 'short names'
+ * -conv_form arg - specifies the point conversion form
+ * - possible values: compressed
+ * uncompressed (default)
+ * hybrid
+ * -param_enc arg - specifies the way the ec parameters are encoded
+ * in the asn1 der encoding
+ * possible values: named_curve (default)
+ * explicit
+ * -no_seed - if 'explicit' parameters are choosen do not use the seed
+ * -genkey - generate ec key
+ * -rand file - files to use for random number input
+ * -engine e - use engine e, possibly a hardware device
+ */
+
+
+static int ecparam_print_var(BIO *,BIGNUM *,const char *,int,unsigned char *);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ EC_GROUP *group = NULL;
+ point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
+ int new_form = 0;
+ int asn1_flag = OPENSSL_EC_NAMED_CURVE;
+ int new_asn1_flag = 0;
+ char *curve_name = NULL, *inrand = NULL;
+ int list_curves = 0, no_seed = 0, check = 0,
+ badops = 0, text = 0, i, need_rand = 0, genkey = 0;
+ char *infile = NULL, *outfile = NULL, *prog;
+ BIO *in = NULL, *out = NULL;
+ int informat, outformat, noout = 0, C = 0, ret = 1;
+ char *engine = NULL;
+
+ BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL,
+ *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
+ unsigned char *buffer = NULL;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-text") == 0)
+ text = 1;
+ else if (strcmp(*argv,"-C") == 0)
+ C = 1;
+ else if (strcmp(*argv,"-check") == 0)
+ check = 1;
+ else if (strcmp (*argv, "-name") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ curve_name = *(++argv);
+ }
+ else if (strcmp(*argv, "-list_curves") == 0)
+ list_curves = 1;
+ else if (strcmp(*argv, "-conv_form") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ ++argv;
+ new_form = 1;
+ if (strcmp(*argv, "compressed") == 0)
+ form = POINT_CONVERSION_COMPRESSED;
+ else if (strcmp(*argv, "uncompressed") == 0)
+ form = POINT_CONVERSION_UNCOMPRESSED;
+ else if (strcmp(*argv, "hybrid") == 0)
+ form = POINT_CONVERSION_HYBRID;
+ else
+ goto bad;
+ }
+ else if (strcmp(*argv, "-param_enc") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ ++argv;
+ new_asn1_flag = 1;
+ if (strcmp(*argv, "named_curve") == 0)
+ asn1_flag = OPENSSL_EC_NAMED_CURVE;
+ else if (strcmp(*argv, "explicit") == 0)
+ asn1_flag = 0;
+ else
+ goto bad;
+ }
+ else if (strcmp(*argv, "-no_seed") == 0)
+ no_seed = 1;
+ else if (strcmp(*argv, "-noout") == 0)
+ noout=1;
+ else if (strcmp(*argv,"-genkey") == 0)
+ {
+ genkey=1;
+ need_rand=1;
+ }
+ else if (strcmp(*argv, "-rand") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inrand= *(++argv);
+ need_rand=1;
+ }
+ else if(strcmp(*argv, "-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine = *(++argv);
+ }
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err, "%s [options] <infile >outfile\n",prog);
+ BIO_printf(bio_err, "where options are\n");
+ BIO_printf(bio_err, " -inform arg input format - "
+ "default PEM (DER or PEM)\n");
+ BIO_printf(bio_err, " -outform arg output format - "
+ "default PEM\n");
+ BIO_printf(bio_err, " -in arg input file - "
+ "default stdin\n");
+ BIO_printf(bio_err, " -out arg output file - "
+ "default stdout\n");
+ BIO_printf(bio_err, " -noout do not print the "
+ "ec parameter\n");
+ BIO_printf(bio_err, " -text print the ec "
+ "parameters in text form\n");
+ BIO_printf(bio_err, " -check validate the ec "
+ "parameters\n");
+ BIO_printf(bio_err, " -C print a 'C' "
+ "function creating the parameters\n");
+ BIO_printf(bio_err, " -name arg use the "
+ "ec parameters with 'short name' name\n");
+ BIO_printf(bio_err, " -list_curves prints a list of "
+ "all currently available curve 'short names'\n");
+ BIO_printf(bio_err, " -conv_form arg specifies the "
+ "point conversion form \n");
+ BIO_printf(bio_err, " possible values:"
+ " compressed\n");
+ BIO_printf(bio_err, " "
+ " uncompressed (default)\n");
+ BIO_printf(bio_err, " "
+ " hybrid\n");
+ BIO_printf(bio_err, " -param_enc arg specifies the way"
+ " the ec parameters are encoded\n");
+ BIO_printf(bio_err, " in the asn1 der "
+ "encoding\n");
+ BIO_printf(bio_err, " possible values:"
+ " named_curve (default)\n");
+ BIO_printf(bio_err, " "
+ " explicit\n");
+ BIO_printf(bio_err, " -no_seed if 'explicit'"
+ " parameters are choosen do not"
+ " use the seed\n");
+ BIO_printf(bio_err, " -genkey generate ec"
+ " key\n");
+ BIO_printf(bio_err, " -rand file files to use for"
+ " random number input\n");
+ BIO_printf(bio_err, " -engine e use engine e, "
+ "possibly a hardware device\n");
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+
+ in=BIO_new(BIO_s_file());
+ out=BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ if (list_curves)
+ {
+ EC_builtin_curve *curves = NULL;
+ size_t crv_len = 0;
+ size_t n = 0;
+
+ crv_len = EC_get_builtin_curves(NULL, 0);
+
+ curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len));
+
+ if (curves == NULL)
+ goto end;
+
+ if (!EC_get_builtin_curves(curves, crv_len))
+ {
+ OPENSSL_free(curves);
+ goto end;
+ }
+
+
+ for (n = 0; n < crv_len; n++)
+ {
+ const char *comment;
+ const char *sname;
+ comment = curves[n].comment;
+ sname = OBJ_nid2sn(curves[n].nid);
+ if (comment == NULL)
+ comment = "CURVE DESCRIPTION NOT AVAILABLE";
+ if (sname == NULL)
+ sname = "";
+
+ BIO_printf(out, " %-10s: ", sname);
+ BIO_printf(out, "%s\n", comment);
+ }
+
+ OPENSSL_free(curves);
+ ret = 0;
+ goto end;
+ }
+
+ if (curve_name != NULL)
+ {
+ int nid;
+
+ /* workaround for the SECG curve names secp192r1
+ * and secp256r1 (which are the same as the curves
+ * prime192v1 and prime256v1 defined in X9.62)
+ */
+ if (!strcmp(curve_name, "secp192r1"))
+ {
+ BIO_printf(bio_err, "using curve name prime192v1 "
+ "instead of secp192r1\n");
+ nid = NID_X9_62_prime192v1;
+ }
+ else if (!strcmp(curve_name, "secp256r1"))
+ {
+ BIO_printf(bio_err, "using curve name prime256v1 "
+ "instead of secp256r1\n");
+ nid = NID_X9_62_prime256v1;
+ }
+ else
+ nid = OBJ_sn2nid(curve_name);
+
+ if (nid == 0)
+ {
+ BIO_printf(bio_err, "unknown curve name (%s)\n",
+ curve_name);
+ goto end;
+ }
+
+ group = EC_GROUP_new_by_curve_name(nid);
+ if (group == NULL)
+ {
+ BIO_printf(bio_err, "unable to create curve (%s)\n",
+ curve_name);
+ goto end;
+ }
+ EC_GROUP_set_asn1_flag(group, asn1_flag);
+ EC_GROUP_set_point_conversion_form(group, form);
+ }
+ else if (informat == FORMAT_ASN1)
+ {
+ group = d2i_ECPKParameters_bio(in, NULL);
+ }
+ else if (informat == FORMAT_PEM)
+ {
+ group = PEM_read_bio_ECPKParameters(in,NULL,NULL,NULL);
+ }
+ else
+ {
+ BIO_printf(bio_err, "bad input format specified\n");
+ goto end;
+ }
+
+ if (group == NULL)
+ {
+ BIO_printf(bio_err,
+ "unable to load elliptic curve parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (new_form)
+ EC_GROUP_set_point_conversion_form(group, form);
+
+ if (new_asn1_flag)
+ EC_GROUP_set_asn1_flag(group, asn1_flag);
+
+ if (no_seed)
+ {
+ EC_GROUP_set_seed(group, NULL, 0);
+ }
+
+ if (text)
+ {
+ if (!ECPKParameters_print(out, group, 0))
+ goto end;
+ }
+
+ if (check)
+ {
+ if (group == NULL)
+ BIO_printf(bio_err, "no elliptic curve parameters\n");
+ BIO_printf(bio_err, "checking elliptic curve parameters: ");
+ if (!EC_GROUP_check(group, NULL))
+ {
+ BIO_printf(bio_err, "failed\n");
+ ERR_print_errors(bio_err);
+ }
+ else
+ BIO_printf(bio_err, "ok\n");
+
+ }
+
+ if (C)
+ {
+ size_t buf_len = 0, tmp_len = 0;
+ const EC_POINT *point;
+ int is_prime, len = 0;
+ const EC_METHOD *meth = EC_GROUP_method_of(group);
+
+ if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
+ (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
+ (ec_order = BN_new()) == NULL ||
+ (ec_cofactor = BN_new()) == NULL )
+ {
+ perror("OPENSSL_malloc");
+ goto end;
+ }
+
+ is_prime = (EC_METHOD_get_field_type(meth) ==
+ NID_X9_62_prime_field);
+
+ if (is_prime)
+ {
+ if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
+ ec_b, NULL))
+ goto end;
+ }
+ else
+ {
+ /* TODO */
+ goto end;
+ }
+
+ if ((point = EC_GROUP_get0_generator(group)) == NULL)
+ goto end;
+ if (!EC_POINT_point2bn(group, point,
+ EC_GROUP_get_point_conversion_form(group), ec_gen,
+ NULL))
+ goto end;
+ if (!EC_GROUP_get_order(group, ec_order, NULL))
+ goto end;
+ if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
+ goto end;
+
+ if (!ec_p || !ec_a || !ec_b || !ec_gen ||
+ !ec_order || !ec_cofactor)
+ goto end;
+
+ len = BN_num_bits(ec_order);
+
+ if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len)
+ buf_len = tmp_len;
+ if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len)
+ buf_len = tmp_len;
+ if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len)
+ buf_len = tmp_len;
+ if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len)
+ buf_len = tmp_len;
+ if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len)
+ buf_len = tmp_len;
+ if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len)
+ buf_len = tmp_len;
+
+ buffer = (unsigned char *)OPENSSL_malloc(buf_len);
+
+ if (buffer == NULL)
+ {
+ perror("OPENSSL_malloc");
+ goto end;
+ }
+
+ ecparam_print_var(out, ec_p, "ec_p", len, buffer);
+ ecparam_print_var(out, ec_a, "ec_a", len, buffer);
+ ecparam_print_var(out, ec_b, "ec_b", len, buffer);
+ ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
+ ecparam_print_var(out, ec_order, "ec_order", len, buffer);
+ ecparam_print_var(out, ec_cofactor, "ec_cofactor", len,
+ buffer);
+
+ BIO_printf(out, "\n\n");
+
+ BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
+ BIO_printf(out, "\tint ok=0;\n");
+ BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
+ BIO_printf(out, "\tEC_POINT *point = NULL;\n");
+ BIO_printf(out, "\tBIGNUM *tmp_1 = NULL, *tmp_2 = NULL, "
+ "*tmp_3 = NULL;\n\n");
+ BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
+ "sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
+ "goto err;\n", len, len);
+ BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
+ "sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
+ "goto err;\n", len, len);
+ BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
+ "sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
+ "goto err;\n", len, len);
+ if (is_prime)
+ {
+ BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
+ "GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
+ "\n\t\tgoto err;\n\n");
+ }
+ else
+ {
+ /* TODO */
+ goto end;
+ }
+ BIO_printf(out, "\t/* build generator */\n");
+ BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
+ "sizeof(ec_gen_%d), tmp_1)) == NULL)"
+ "\n\t\tgoto err;\n", len, len);
+ BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
+ "NULL, NULL);\n");
+ BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
+ BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
+ "sizeof(ec_order_%d), tmp_2)) == NULL)"
+ "\n\t\tgoto err;\n", len, len);
+ BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
+ "sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
+ "\n\t\tgoto err;\n", len, len);
+ BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
+ " tmp_2, tmp_3))\n\t\tgoto err;\n");
+ BIO_printf(out, "\n\tok=1;\n");
+ BIO_printf(out, "err:\n");
+ BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
+ BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
+ BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
+ BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
+ BIO_printf(out, "\tif (!ok)\n");
+ BIO_printf(out, "\t\t{\n");
+ BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
+ BIO_printf(out, "\t\tgroup = NULL;\n");
+ BIO_printf(out, "\t\t}\n");
+ BIO_printf(out, "\treturn(group);\n\t}\n");
+ }
+
+ if (!noout)
+ {
+ if (outformat == FORMAT_ASN1)
+ i = i2d_ECPKParameters_bio(out, group);
+ else if (outformat == FORMAT_PEM)
+ i = PEM_write_bio_ECPKParameters(out, group);
+ else
+ {
+ BIO_printf(bio_err,"bad output format specified for"
+ " outfile\n");
+ goto end;
+ }
+ if (!i)
+ {
+ BIO_printf(bio_err, "unable to write elliptic "
+ "curve parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (need_rand)
+ {
+ app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+ }
+
+ if (genkey)
+ {
+ EC_KEY *eckey = EC_KEY_new();
+
+ if (eckey == NULL)
+ goto end;
+
+ assert(need_rand);
+
+ if (EC_KEY_set_group(eckey, group) == 0)
+ goto end;
+
+ if (!EC_KEY_generate_key(eckey))
+ {
+ EC_KEY_free(eckey);
+ goto end;
+ }
+ if (outformat == FORMAT_ASN1)
+ i = i2d_ECPrivateKey_bio(out, eckey);
+ else if (outformat == FORMAT_PEM)
+ i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
+ NULL, 0, NULL, NULL);
+ else
+ {
+ BIO_printf(bio_err, "bad output format specified "
+ "for outfile\n");
+ EC_KEY_free(eckey);
+ goto end;
+ }
+ EC_KEY_free(eckey);
+ }
+
+ if (need_rand)
+ app_RAND_write_file(NULL, bio_err);
+
+ ret=0;
+end:
+ if (ec_p)
+ BN_free(ec_p);
+ if (ec_a)
+ BN_free(ec_a);
+ if (ec_b)
+ BN_free(ec_b);
+ if (ec_gen)
+ BN_free(ec_gen);
+ if (ec_order)
+ BN_free(ec_order);
+ if (ec_cofactor)
+ BN_free(ec_cofactor);
+ if (buffer)
+ OPENSSL_free(buffer);
+ if (in != NULL)
+ BIO_free(in);
+ if (out != NULL)
+ BIO_free_all(out);
+ if (group != NULL)
+ EC_GROUP_free(group);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+}
+
+static int ecparam_print_var(BIO *out, BIGNUM *in, const char *var,
+ int len, unsigned char *buffer)
+ {
+ BIO_printf(out, "static unsigned char %s_%d[] = {", var, len);
+ if (BN_is_zero(in))
+ BIO_printf(out, "\n\t0x00");
+ else
+ {
+ int i, l;
+
+ l = BN_bn2bin(in, buffer);
+ for (i=0; i<l-1; i++)
+ {
+ if ((i%12) == 0)
+ BIO_printf(out, "\n\t");
+ BIO_printf(out, "0x%02X,", buffer[i]);
+ }
+ if ((i%12) == 0)
+ BIO_printf(out, "\n\t");
+ BIO_printf(out, "0x%02X", buffer[i]);
+ }
+ BIO_printf(out, "\n\t};\n\n");
+ return 1;
+ }
+#else /* !OPENSSL_NO_EC */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/enc.c b/deps/openssl/openssl/apps/enc.c
new file mode 100644
index 000000000..719acc325
--- /dev/null
+++ b/deps/openssl/openssl/apps/enc.c
@@ -0,0 +1,732 @@
+/* apps/enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+#include <openssl/pem.h>
+#include <openssl/comp.h>
+#include <ctype.h>
+
+int set_hex(char *in,unsigned char *out,int size);
+#undef SIZE
+#undef BSIZE
+#undef PROG
+
+#define SIZE (512)
+#define BSIZE (8*1024)
+#define PROG enc_main
+
+static void show_ciphers(const OBJ_NAME *name,void *bio_)
+ {
+ BIO *bio=bio_;
+ static int n;
+
+ if(!islower((unsigned char)*name->name))
+ return;
+
+ BIO_printf(bio,"-%-25s",name->name);
+ if(++n == 3)
+ {
+ BIO_printf(bio,"\n");
+ n=0;
+ }
+ else
+ BIO_printf(bio," ");
+ }
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ static const char magic[]="Salted__";
+ char mbuf[sizeof magic-1];
+ char *strbuf=NULL;
+ unsigned char *buff=NULL,*bufsize=NULL;
+ int bsize=BSIZE,verbose=0;
+ int ret=1,inl;
+ int nopad = 0;
+ unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
+ unsigned char salt[PKCS5_SALT_LEN];
+ char *str=NULL, *passarg = NULL, *pass = NULL;
+ char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
+ char *md=NULL;
+ int enc=1,printkey=0,i,base64=0;
+#ifdef ZLIB
+ int do_zlib=0;
+ BIO *bzl = NULL;
+#endif
+ int debug=0,olb64=0,nosalt=0;
+ const EVP_CIPHER *cipher=NULL,*c;
+ EVP_CIPHER_CTX *ctx = NULL;
+ char *inf=NULL,*outf=NULL;
+ BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
+#define PROG_NAME_SIZE 39
+ char pname[PROG_NAME_SIZE+1];
+#ifndef OPENSSL_NO_ENGINE
+ char *engine = NULL;
+#endif
+ const EVP_MD *dgst=NULL;
+ int non_fips_allow = 0;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ /* first check the program name */
+ program_name(argv[0],pname,sizeof pname);
+ if (strcmp(pname,"base64") == 0)
+ base64=1;
+#ifdef ZLIB
+ if (strcmp(pname,"zlib") == 0)
+ do_zlib=1;
+#endif
+
+ cipher=EVP_get_cipherbyname(pname);
+#ifdef ZLIB
+ if (!do_zlib && !base64 && (cipher == NULL)
+ && (strcmp(pname,"enc") != 0))
+#else
+ if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0))
+#endif
+ {
+ BIO_printf(bio_err,"%s is an unknown cipher\n",pname);
+ goto bad;
+ }
+
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-e") == 0)
+ enc=1;
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inf= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outf= *(++argv);
+ }
+ else if (strcmp(*argv,"-pass") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passarg= *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-d") == 0)
+ enc=0;
+ else if (strcmp(*argv,"-p") == 0)
+ printkey=1;
+ else if (strcmp(*argv,"-v") == 0)
+ verbose=1;
+ else if (strcmp(*argv,"-nopad") == 0)
+ nopad=1;
+ else if (strcmp(*argv,"-salt") == 0)
+ nosalt=0;
+ else if (strcmp(*argv,"-nosalt") == 0)
+ nosalt=1;
+ else if (strcmp(*argv,"-debug") == 0)
+ debug=1;
+ else if (strcmp(*argv,"-P") == 0)
+ printkey=2;
+ else if (strcmp(*argv,"-A") == 0)
+ olb64=1;
+ else if (strcmp(*argv,"-a") == 0)
+ base64=1;
+ else if (strcmp(*argv,"-base64") == 0)
+ base64=1;
+#ifdef ZLIB
+ else if (strcmp(*argv,"-z") == 0)
+ do_zlib=1;
+#endif
+ else if (strcmp(*argv,"-bufsize") == 0)
+ {
+ if (--argc < 1) goto bad;
+ bufsize=(unsigned char *)*(++argv);
+ }
+ else if (strcmp(*argv,"-k") == 0)
+ {
+ if (--argc < 1) goto bad;
+ str= *(++argv);
+ }
+ else if (strcmp(*argv,"-kfile") == 0)
+ {
+ static char buf[128];
+ FILE *infile;
+ char *file;
+
+ if (--argc < 1) goto bad;
+ file= *(++argv);
+ infile=fopen(file,"r");
+ if (infile == NULL)
+ {
+ BIO_printf(bio_err,"unable to read key from '%s'\n",
+ file);
+ goto bad;
+ }
+ buf[0]='\0';
+ if (!fgets(buf,sizeof buf,infile))
+ {
+ BIO_printf(bio_err,"unable to read key from '%s'\n",
+ file);
+ goto bad;
+ }
+ fclose(infile);
+ i=strlen(buf);
+ if ((i > 0) &&
+ ((buf[i-1] == '\n') || (buf[i-1] == '\r')))
+ buf[--i]='\0';
+ if ((i > 0) &&
+ ((buf[i-1] == '\n') || (buf[i-1] == '\r')))
+ buf[--i]='\0';
+ if (i < 1)
+ {
+ BIO_printf(bio_err,"zero length password\n");
+ goto bad;
+ }
+ str=buf;
+ }
+ else if (strcmp(*argv,"-K") == 0)
+ {
+ if (--argc < 1) goto bad;
+ hkey= *(++argv);
+ }
+ else if (strcmp(*argv,"-S") == 0)
+ {
+ if (--argc < 1) goto bad;
+ hsalt= *(++argv);
+ }
+ else if (strcmp(*argv,"-iv") == 0)
+ {
+ if (--argc < 1) goto bad;
+ hiv= *(++argv);
+ }
+ else if (strcmp(*argv,"-md") == 0)
+ {
+ if (--argc < 1) goto bad;
+ md= *(++argv);
+ }
+ else if (strcmp(*argv,"-non-fips-allow") == 0)
+ non_fips_allow = 1;
+ else if ((argv[0][0] == '-') &&
+ ((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL))
+ {
+ cipher=c;
+ }
+ else if (strcmp(*argv,"-none") == 0)
+ cipher=NULL;
+ else
+ {
+ BIO_printf(bio_err,"unknown option '%s'\n",*argv);
+bad:
+ BIO_printf(bio_err,"options are\n");
+ BIO_printf(bio_err,"%-14s input file\n","-in <file>");
+ BIO_printf(bio_err,"%-14s output file\n","-out <file>");
+ BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>");
+ BIO_printf(bio_err,"%-14s encrypt\n","-e");
+ BIO_printf(bio_err,"%-14s decrypt\n","-d");
+ BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64");
+ BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k");
+ BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile");
+ BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md");
+ BIO_printf(bio_err,"%-14s from a passphrase. One of md2, md5, sha or sha1\n","");
+ BIO_printf(bio_err,"%-14s salt in hex is the next argument\n","-S");
+ BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv");
+ BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]");
+ BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
+ BIO_printf(bio_err,"%-14s disable standard block padding\n","-nopad");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
+#endif
+
+ BIO_printf(bio_err,"Cipher Types\n");
+ OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
+ show_ciphers,
+ bio_err);
+ BIO_printf(bio_err,"\n");
+
+ goto end;
+ }
+ argc--;
+ argv++;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
+ {
+ BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
+ goto end;
+ }
+
+ if (dgst == NULL)
+ {
+ dgst = EVP_md5();
+ }
+
+ if (bufsize != NULL)
+ {
+ unsigned long n;
+
+ for (n=0; *bufsize; bufsize++)
+ {
+ i= *bufsize;
+ if ((i <= '9') && (i >= '0'))
+ n=n*10+i-'0';
+ else if (i == 'k')
+ {
+ n*=1024;
+ bufsize++;
+ break;
+ }
+ }
+ if (*bufsize != '\0')
+ {
+ BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
+ goto end;
+ }
+
+ /* It must be large enough for a base64 encoded line */
+ if (base64 && n < 80) n=80;
+
+ bsize=(int)n;
+ if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
+ }
+
+ strbuf=OPENSSL_malloc(SIZE);
+ buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
+ if ((buff == NULL) || (strbuf == NULL))
+ {
+ BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize));
+ goto end;
+ }
+
+ in=BIO_new(BIO_s_file());
+ out=BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (debug)
+ {
+ BIO_set_callback(in,BIO_debug_callback);
+ BIO_set_callback(out,BIO_debug_callback);
+ BIO_set_callback_arg(in,(char *)bio_err);
+ BIO_set_callback_arg(out,(char *)bio_err);
+ }
+
+ if (inf == NULL)
+ {
+#ifndef OPENSSL_NO_SETVBUF_IONBF
+ if (bufsize != NULL)
+ setvbuf(stdin, (char *)NULL, _IONBF, 0);
+#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ }
+ else
+ {
+ if (BIO_read_filename(in,inf) <= 0)
+ {
+ perror(inf);
+ goto end;
+ }
+ }
+
+ if(!str && passarg) {
+ if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+ str = pass;
+ }
+
+ if ((str == NULL) && (cipher != NULL) && (hkey == NULL))
+ {
+ for (;;)
+ {
+ char buf[200];
+
+ BIO_snprintf(buf,sizeof buf,"enter %s %s password:",
+ OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
+ (enc)?"encryption":"decryption");
+ strbuf[0]='\0';
+ i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc);
+ if (i == 0)
+ {
+ if (strbuf[0] == '\0')
+ {
+ ret=1;
+ goto end;
+ }
+ str=strbuf;
+ break;
+ }
+ if (i < 0)
+ {
+ BIO_printf(bio_err,"bad password read\n");
+ goto end;
+ }
+ }
+ }
+
+
+ if (outf == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifndef OPENSSL_NO_SETVBUF_IONBF
+ if (bufsize != NULL)
+ setvbuf(stdout, (char *)NULL, _IONBF, 0);
+#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outf) <= 0)
+ {
+ perror(outf);
+ goto end;
+ }
+ }
+
+ rbio=in;
+ wbio=out;
+
+#ifdef ZLIB
+
+ if (do_zlib)
+ {
+ if ((bzl=BIO_new(BIO_f_zlib())) == NULL)
+ goto end;
+ if (enc)
+ wbio=BIO_push(bzl,wbio);
+ else
+ rbio=BIO_push(bzl,rbio);
+ }
+#endif
+
+ if (base64)
+ {
+ if ((b64=BIO_new(BIO_f_base64())) == NULL)
+ goto end;
+ if (debug)
+ {
+ BIO_set_callback(b64,BIO_debug_callback);
+ BIO_set_callback_arg(b64,(char *)bio_err);
+ }
+ if (olb64)
+ BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
+ if (enc)
+ wbio=BIO_push(b64,wbio);
+ else
+ rbio=BIO_push(b64,rbio);
+ }
+
+ if (cipher != NULL)
+ {
+ /* Note that str is NULL if a key was passed on the command
+ * line, so we get no salt in that case. Is this a bug?
+ */
+ if (str != NULL)
+ {
+ /* Salt handling: if encrypting generate a salt and
+ * write to output BIO. If decrypting read salt from
+ * input BIO.
+ */
+ unsigned char *sptr;
+ if(nosalt) sptr = NULL;
+ else {
+ if(enc) {
+ if(hsalt) {
+ if(!set_hex(hsalt,salt,sizeof salt)) {
+ BIO_printf(bio_err,
+ "invalid hex salt value\n");
+ goto end;
+ }
+ } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
+ goto end;
+ /* If -P option then don't bother writing */
+ if((printkey != 2)
+ && (BIO_write(wbio,magic,
+ sizeof magic-1) != sizeof magic-1
+ || BIO_write(wbio,
+ (char *)salt,
+ sizeof salt) != sizeof salt)) {
+ BIO_printf(bio_err,"error writing output file\n");
+ goto end;
+ }
+ } else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf
+ || BIO_read(rbio,
+ (unsigned char *)salt,
+ sizeof salt) != sizeof salt) {
+ BIO_printf(bio_err,"error reading input file\n");
+ goto end;
+ } else if(memcmp(mbuf,magic,sizeof magic-1)) {
+ BIO_printf(bio_err,"bad magic number\n");
+ goto end;
+ }
+
+ sptr = salt;
+ }
+
+ EVP_BytesToKey(cipher,dgst,sptr,
+ (unsigned char *)str,
+ strlen(str),1,key,iv);
+ /* zero the complete buffer or the string
+ * passed from the command line
+ * bug picked up by
+ * Larry J. Hughes Jr. <hughes@indiana.edu> */
+ if (str == strbuf)
+ OPENSSL_cleanse(str,SIZE);
+ else
+ OPENSSL_cleanse(str,strlen(str));
+ }
+ if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv))
+ {
+ BIO_printf(bio_err,"invalid hex iv value\n");
+ goto end;
+ }
+ if ((hiv == NULL) && (str == NULL)
+ && EVP_CIPHER_iv_length(cipher) != 0)
+ {
+ /* No IV was explicitly set and no IV was generated
+ * during EVP_BytesToKey. Hence the IV is undefined,
+ * making correct decryption impossible. */
+ BIO_printf(bio_err, "iv undefined\n");
+ goto end;
+ }
+ if ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
+ {
+ BIO_printf(bio_err,"invalid hex key value\n");
+ goto end;
+ }
+
+ if ((benc=BIO_new(BIO_f_cipher())) == NULL)
+ goto end;
+
+ /* Since we may be changing parameters work on the encryption
+ * context rather than calling BIO_set_cipher().
+ */
+
+ BIO_get_cipher_ctx(benc, &ctx);
+
+ if (non_fips_allow)
+ EVP_CIPHER_CTX_set_flags(ctx,
+ EVP_CIPH_FLAG_NON_FIPS_ALLOW);
+
+ if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
+ {
+ BIO_printf(bio_err, "Error setting cipher %s\n",
+ EVP_CIPHER_name(cipher));
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (nopad)
+ EVP_CIPHER_CTX_set_padding(ctx, 0);
+
+ if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc))
+ {
+ BIO_printf(bio_err, "Error setting cipher %s\n",
+ EVP_CIPHER_name(cipher));
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (debug)
+ {
+ BIO_set_callback(benc,BIO_debug_callback);
+ BIO_set_callback_arg(benc,(char *)bio_err);
+ }
+
+ if (printkey)
+ {
+ if (!nosalt)
+ {
+ printf("salt=");
+ for (i=0; i<(int)sizeof(salt); i++)
+ printf("%02X",salt[i]);
+ printf("\n");
+ }
+ if (cipher->key_len > 0)
+ {
+ printf("key=");
+ for (i=0; i<cipher->key_len; i++)
+ printf("%02X",key[i]);
+ printf("\n");
+ }
+ if (cipher->iv_len > 0)
+ {
+ printf("iv =");
+ for (i=0; i<cipher->iv_len; i++)
+ printf("%02X",iv[i]);
+ printf("\n");
+ }
+ if (printkey == 2)
+ {
+ ret=0;
+ goto end;
+ }
+ }
+ }
+
+ /* Only encrypt/decrypt as we write the file */
+ if (benc != NULL)
+ wbio=BIO_push(benc,wbio);
+
+ for (;;)
+ {
+ inl=BIO_read(rbio,(char *)buff,bsize);
+ if (inl <= 0) break;
+ if (BIO_write(wbio,(char *)buff,inl) != inl)
+ {
+ BIO_printf(bio_err,"error writing output file\n");
+ goto end;
+ }
+ }
+ if (!BIO_flush(wbio))
+ {
+ BIO_printf(bio_err,"bad decrypt\n");
+ goto end;
+ }
+
+ ret=0;
+ if (verbose)
+ {
+ BIO_printf(bio_err,"bytes read :%8ld\n",BIO_number_read(in));
+ BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
+ }
+end:
+ ERR_print_errors(bio_err);
+ if (strbuf != NULL) OPENSSL_free(strbuf);
+ if (buff != NULL) OPENSSL_free(buff);
+ if (in != NULL) BIO_free(in);
+ if (out != NULL) BIO_free_all(out);
+ if (benc != NULL) BIO_free(benc);
+ if (b64 != NULL) BIO_free(b64);
+#ifdef ZLIB
+ if (bzl != NULL) BIO_free(bzl);
+#endif
+ if(pass) OPENSSL_free(pass);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+int set_hex(char *in, unsigned char *out, int size)
+ {
+ int i,n;
+ unsigned char j;
+
+ n=strlen(in);
+ if (n > (size*2))
+ {
+ BIO_printf(bio_err,"hex string is too long\n");
+ return(0);
+ }
+ memset(out,0,size);
+ for (i=0; i<n; i++)
+ {
+ j=(unsigned char)*in;
+ *(in++)='\0';
+ if (j == 0) break;
+ if ((j >= '0') && (j <= '9'))
+ j-='0';
+ else if ((j >= 'A') && (j <= 'F'))
+ j=j-'A'+10;
+ else if ((j >= 'a') && (j <= 'f'))
+ j=j-'a'+10;
+ else
+ {
+ BIO_printf(bio_err,"non-hex digit\n");
+ return(0);
+ }
+ if (i&1)
+ out[i/2]|=j;
+ else
+ out[i/2]=(j<<4);
+ }
+ return(1);
+ }
diff --git a/deps/openssl/openssl/apps/engine.c b/deps/openssl/openssl/apps/engine.c
new file mode 100644
index 000000000..9a0294398
--- /dev/null
+++ b/deps/openssl/openssl/apps/engine.c
@@ -0,0 +1,549 @@
+/* apps/engine.c -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 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
+ * licensing@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).
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include "apps.h"
+#include <openssl/err.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#include <openssl/ssl.h>
+
+#undef PROG
+#define PROG engine_main
+
+static const char *engine_usage[]={
+"usage: engine opts [engine ...]\n",
+" -v[v[v[v]]] - verbose mode, for each engine, list its 'control commands'\n",
+" -vv will additionally display each command's description\n",
+" -vvv will also add the input flags for each command\n",
+" -vvvv will also show internal input flags\n",
+" -c - for each engine, also list the capabilities\n",
+" -t[t] - for each engine, check that they are really available\n",
+" -tt will display error trace for unavailable engines\n",
+" -pre <cmd> - runs command 'cmd' against the ENGINE before any attempts\n",
+" to load it (if -t is used)\n",
+" -post <cmd> - runs command 'cmd' against the ENGINE after loading it\n",
+" (only used if -t is also provided)\n",
+" NB: -pre and -post will be applied to all ENGINEs supplied on the command\n",
+" line, or all supported ENGINEs if none are specified.\n",
+" Eg. '-pre \"SO_PATH:/lib/libdriver.so\"' calls command \"SO_PATH\" with\n",
+" argument \"/lib/libdriver.so\".\n",
+NULL
+};
+
+static void identity(char *ptr)
+ {
+ return;
+ }
+
+static int append_buf(char **buf, const char *s, int *size, int step)
+ {
+ int l = strlen(s);
+
+ if (*buf == NULL)
+ {
+ *size = step;
+ *buf = OPENSSL_malloc(*size);
+ if (*buf == NULL)
+ return 0;
+ **buf = '\0';
+ }
+
+ if (**buf != '\0')
+ l += 2; /* ", " */
+
+ if (strlen(*buf) + strlen(s) >= (unsigned int)*size)
+ {
+ *size += step;
+ *buf = OPENSSL_realloc(*buf, *size);
+ }
+
+ if (*buf == NULL)
+ return 0;
+
+ if (**buf != '\0')
+ BUF_strlcat(*buf, ", ", *size);
+ BUF_strlcat(*buf, s, *size);
+
+ return 1;
+ }
+
+static int util_flags(BIO *bio_out, unsigned int flags, const char *indent)
+ {
+ int started = 0, err = 0;
+ /* Indent before displaying input flags */
+ BIO_printf(bio_out, "%s%s(input flags): ", indent, indent);
+ if(flags == 0)
+ {
+ BIO_printf(bio_out, "<no flags>\n");
+ return 1;
+ }
+ /* If the object is internal, mark it in a way that shows instead of
+ * having it part of all the other flags, even if it really is. */
+ if(flags & ENGINE_CMD_FLAG_INTERNAL)
+ {
+ BIO_printf(bio_out, "[Internal] ");
+ }
+
+ if(flags & ENGINE_CMD_FLAG_NUMERIC)
+ {
+ BIO_printf(bio_out, "NUMERIC");
+ started = 1;
+ }
+ /* Now we check that no combinations of the mutually exclusive NUMERIC,
+ * STRING, and NO_INPUT flags have been used. Future flags that can be
+ * OR'd together with these would need to added after these to preserve
+ * the testing logic. */
+ if(flags & ENGINE_CMD_FLAG_STRING)
+ {
+ if(started)
+ {
+ BIO_printf(bio_out, "|");
+ err = 1;
+ }
+ BIO_printf(bio_out, "STRING");
+ started = 1;
+ }
+ if(flags & ENGINE_CMD_FLAG_NO_INPUT)
+ {
+ if(started)
+ {
+ BIO_printf(bio_out, "|");
+ err = 1;
+ }
+ BIO_printf(bio_out, "NO_INPUT");
+ started = 1;
+ }
+ /* Check for unknown flags */
+ flags = flags & ~ENGINE_CMD_FLAG_NUMERIC &
+ ~ENGINE_CMD_FLAG_STRING &
+ ~ENGINE_CMD_FLAG_NO_INPUT &
+ ~ENGINE_CMD_FLAG_INTERNAL;
+ if(flags)
+ {
+ if(started) BIO_printf(bio_out, "|");
+ BIO_printf(bio_out, "<0x%04X>", flags);
+ }
+ if(err)
+ BIO_printf(bio_out, " <illegal flags!>");
+ BIO_printf(bio_out, "\n");
+ return 1;
+ }
+
+static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, const char *indent)
+ {
+ static const int line_wrap = 78;
+ int num;
+ int ret = 0;
+ char *name = NULL;
+ char *desc = NULL;
+ int flags;
+ int xpos = 0;
+ STACK_OF(OPENSSL_STRING) *cmds = NULL;
+ if(!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) ||
+ ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE,
+ 0, NULL, NULL)) <= 0))
+ {
+#if 0
+ BIO_printf(bio_out, "%s<no control commands>\n", indent);
+#endif
+ return 1;
+ }
+
+ cmds = sk_OPENSSL_STRING_new_null();
+
+ if(!cmds)
+ goto err;
+ do {
+ int len;
+ /* Get the command input flags */
+ if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num,
+ NULL, NULL)) < 0)
+ goto err;
+ if (!(flags & ENGINE_CMD_FLAG_INTERNAL) || verbose >= 4)
+ {
+ /* Get the command name */
+ if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_LEN_FROM_CMD, num,
+ NULL, NULL)) <= 0)
+ goto err;
+ if((name = OPENSSL_malloc(len + 1)) == NULL)
+ goto err;
+ if(ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_FROM_CMD, num, name,
+ NULL) <= 0)
+ goto err;
+ /* Get the command description */
+ if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_LEN_FROM_CMD, num,
+ NULL, NULL)) < 0)
+ goto err;
+ if(len > 0)
+ {
+ if((desc = OPENSSL_malloc(len + 1)) == NULL)
+ goto err;
+ if(ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_FROM_CMD, num, desc,
+ NULL) <= 0)
+ goto err;
+ }
+ /* Now decide on the output */
+ if(xpos == 0)
+ /* Do an indent */
+ xpos = BIO_puts(bio_out, indent);
+ else
+ /* Otherwise prepend a ", " */
+ xpos += BIO_printf(bio_out, ", ");
+ if(verbose == 1)
+ {
+ /* We're just listing names, comma-delimited */
+ if((xpos > (int)strlen(indent)) &&
+ (xpos + (int)strlen(name) > line_wrap))
+ {
+ BIO_printf(bio_out, "\n");
+ xpos = BIO_puts(bio_out, indent);
+ }
+ xpos += BIO_printf(bio_out, "%s", name);
+ }
+ else
+ {
+ /* We're listing names plus descriptions */
+ BIO_printf(bio_out, "%s: %s\n", name,
+ (desc == NULL) ? "<no description>" : desc);
+ /* ... and sometimes input flags */
+ if((verbose >= 3) && !util_flags(bio_out, flags,
+ indent))
+ goto err;
+ xpos = 0;
+ }
+ }
+ OPENSSL_free(name); name = NULL;
+ if(desc) { OPENSSL_free(desc); desc = NULL; }
+ /* Move to the next command */
+ num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE,
+ num, NULL, NULL);
+ } while(num > 0);
+ if(xpos > 0)
+ BIO_printf(bio_out, "\n");
+ ret = 1;
+err:
+ if(cmds) sk_OPENSSL_STRING_pop_free(cmds, identity);
+ if(name) OPENSSL_free(name);
+ if(desc) OPENSSL_free(desc);
+ return ret;
+ }
+
+static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
+ BIO *bio_out, const char *indent)
+ {
+ int loop, res, num = sk_OPENSSL_STRING_num(cmds);
+
+ if(num < 0)
+ {
+ BIO_printf(bio_out, "[Error]: internal stack error\n");
+ return;
+ }
+ for(loop = 0; loop < num; loop++)
+ {
+ char buf[256];
+ const char *cmd, *arg;
+ cmd = sk_OPENSSL_STRING_value(cmds, loop);
+ res = 1; /* assume success */
+ /* Check if this command has no ":arg" */
+ if((arg = strstr(cmd, ":")) == NULL)
+ {
+ if(!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0))
+ res = 0;
+ }
+ else
+ {
+ if((int)(arg - cmd) > 254)
+ {
+ BIO_printf(bio_out,"[Error]: command name too long\n");
+ return;
+ }
+ memcpy(buf, cmd, (int)(arg - cmd));
+ buf[arg-cmd] = '\0';
+ arg++; /* Move past the ":" */
+ /* Call the command with the argument */
+ if(!ENGINE_ctrl_cmd_string(e, buf, arg, 0))
+ res = 0;
+ }
+ if(res)
+ BIO_printf(bio_out, "[Success]: %s\n", cmd);
+ else
+ {
+ BIO_printf(bio_out, "[Failure]: %s\n", cmd);
+ ERR_print_errors(bio_out);
+ }
+ }
+ }
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ int ret=1,i;
+ const char **pp;
+ int verbose=0, list_cap=0, test_avail=0, test_avail_noise = 0;
+ ENGINE *e;
+ STACK_OF(OPENSSL_STRING) *engines = sk_OPENSSL_STRING_new_null();
+ STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
+ STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();
+ int badops=1;
+ BIO *bio_out=NULL;
+ const char *indent = " ";
+
+ apps_startup();
+ SSL_load_error_strings();
+
+ if (bio_err == NULL)
+ bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+ bio_out=BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ bio_out = BIO_push(tmpbio, bio_out);
+ }
+#endif
+
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strncmp(*argv,"-v",2) == 0)
+ {
+ if(strspn(*argv + 1, "v") < strlen(*argv + 1))
+ goto skip_arg_loop;
+ if((verbose=strlen(*argv + 1)) > 4)
+ goto skip_arg_loop;
+ }
+ else if (strcmp(*argv,"-c") == 0)
+ list_cap=1;
+ else if (strncmp(*argv,"-t",2) == 0)
+ {
+ test_avail=1;
+ if(strspn(*argv + 1, "t") < strlen(*argv + 1))
+ goto skip_arg_loop;
+ if((test_avail_noise = strlen(*argv + 1) - 1) > 1)
+ goto skip_arg_loop;
+ }
+ else if (strcmp(*argv,"-pre") == 0)
+ {
+ argc--; argv++;
+ if (argc == 0)
+ goto skip_arg_loop;
+ sk_OPENSSL_STRING_push(pre_cmds,*argv);
+ }
+ else if (strcmp(*argv,"-post") == 0)
+ {
+ argc--; argv++;
+ if (argc == 0)
+ goto skip_arg_loop;
+ sk_OPENSSL_STRING_push(post_cmds,*argv);
+ }
+ else if ((strncmp(*argv,"-h",2) == 0) ||
+ (strcmp(*argv,"-?") == 0))
+ goto skip_arg_loop;
+ else
+ sk_OPENSSL_STRING_push(engines,*argv);
+ argc--;
+ argv++;
+ }
+ /* Looks like everything went OK */
+ badops = 0;
+skip_arg_loop:
+
+ if (badops)
+ {
+ for (pp=engine_usage; (*pp != NULL); pp++)
+ BIO_printf(bio_err,"%s",*pp);
+ goto end;
+ }
+
+ if (sk_OPENSSL_STRING_num(engines) == 0)
+ {
+ for(e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e))
+ {
+ sk_OPENSSL_STRING_push(engines,(char *)ENGINE_get_id(e));
+ }
+ }
+
+ for (i=0; i<sk_OPENSSL_STRING_num(engines); i++)
+ {
+ const char *id = sk_OPENSSL_STRING_value(engines,i);
+ if ((e = ENGINE_by_id(id)) != NULL)
+ {
+ const char *name = ENGINE_get_name(e);
+ /* Do "id" first, then "name". Easier to auto-parse. */
+ BIO_printf(bio_out, "(%s) %s\n", id, name);
+ util_do_cmds(e, pre_cmds, bio_out, indent);
+ if (strcmp(ENGINE_get_id(e), id) != 0)
+ {
+ BIO_printf(bio_out, "Loaded: (%s) %s\n",
+ ENGINE_get_id(e), ENGINE_get_name(e));
+ }
+ if (list_cap)
+ {
+ int cap_size = 256;
+ char *cap_buf = NULL;
+ int k,n;
+ const int *nids;
+ ENGINE_CIPHERS_PTR fn_c;
+ ENGINE_DIGESTS_PTR fn_d;
+ ENGINE_PKEY_METHS_PTR fn_pk;
+
+ if (ENGINE_get_RSA(e) != NULL
+ && !append_buf(&cap_buf, "RSA",
+ &cap_size, 256))
+ goto end;
+ if (ENGINE_get_DSA(e) != NULL
+ && !append_buf(&cap_buf, "DSA",
+ &cap_size, 256))
+ goto end;
+ if (ENGINE_get_DH(e) != NULL
+ && !append_buf(&cap_buf, "DH",
+ &cap_size, 256))
+ goto end;
+ if (ENGINE_get_RAND(e) != NULL
+ && !append_buf(&cap_buf, "RAND",
+ &cap_size, 256))
+ goto end;
+
+ fn_c = ENGINE_get_ciphers(e);
+ if(!fn_c) goto skip_ciphers;
+ n = fn_c(e, NULL, &nids, 0);
+ for(k=0 ; k < n ; ++k)
+ if(!append_buf(&cap_buf,
+ OBJ_nid2sn(nids[k]),
+ &cap_size, 256))
+ goto end;
+
+skip_ciphers:
+ fn_d = ENGINE_get_digests(e);
+ if(!fn_d) goto skip_digests;
+ n = fn_d(e, NULL, &nids, 0);
+ for(k=0 ; k < n ; ++k)
+ if(!append_buf(&cap_buf,
+ OBJ_nid2sn(nids[k]),
+ &cap_size, 256))
+ goto end;
+
+skip_digests:
+ fn_pk = ENGINE_get_pkey_meths(e);
+ if(!fn_pk) goto skip_pmeths;
+ n = fn_pk(e, NULL, &nids, 0);
+ for(k=0 ; k < n ; ++k)
+ if(!append_buf(&cap_buf,
+ OBJ_nid2sn(nids[k]),
+ &cap_size, 256))
+ goto end;
+skip_pmeths:
+ if (cap_buf && (*cap_buf != '\0'))
+ BIO_printf(bio_out, " [%s]\n", cap_buf);
+
+ OPENSSL_free(cap_buf);
+ }
+ if(test_avail)
+ {
+ BIO_printf(bio_out, "%s", indent);
+ if (ENGINE_init(e))
+ {
+ BIO_printf(bio_out, "[ available ]\n");
+ util_do_cmds(e, post_cmds, bio_out, indent);
+ ENGINE_finish(e);
+ }
+ else
+ {
+ BIO_printf(bio_out, "[ unavailable ]\n");
+ if(test_avail_noise)
+ ERR_print_errors_fp(stdout);
+ ERR_clear_error();
+ }
+ }
+ if((verbose > 0) && !util_verbose(e, verbose, bio_out, indent))
+ goto end;
+ ENGINE_free(e);
+ }
+ else
+ ERR_print_errors(bio_err);
+ }
+
+ ret=0;
+end:
+
+ ERR_print_errors(bio_err);
+ sk_OPENSSL_STRING_pop_free(engines, identity);
+ sk_OPENSSL_STRING_pop_free(pre_cmds, identity);
+ sk_OPENSSL_STRING_pop_free(post_cmds, identity);
+ if (bio_out != NULL) BIO_free_all(bio_out);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+#else
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/errstr.c b/deps/openssl/openssl/apps/errstr.c
new file mode 100644
index 000000000..fe3b98077
--- /dev/null
+++ b/deps/openssl/openssl/apps/errstr.c
@@ -0,0 +1,128 @@
+/* apps/errstr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/lhash.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+#undef PROG
+#define PROG errstr_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ int i,ret=0;
+ char buf[256];
+ unsigned long l;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ SSL_load_error_strings();
+
+ if ((argc > 1) && (strcmp(argv[1],"-stats") == 0))
+ {
+ BIO *out=NULL;
+
+ out=BIO_new(BIO_s_file());
+ if ((out != NULL) && BIO_set_fp(out,stdout,BIO_NOCLOSE))
+ {
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ lh_ERR_STRING_DATA_node_stats_bio(
+ ERR_get_string_table(), out);
+ lh_ERR_STRING_DATA_stats_bio(ERR_get_string_table(),
+ out);
+ lh_ERR_STRING_DATA_node_usage_stats_bio(
+ ERR_get_string_table(),out);
+ }
+ if (out != NULL) BIO_free_all(out);
+ argc--;
+ argv++;
+ }
+
+ for (i=1; i<argc; i++)
+ {
+ if (sscanf(argv[i],"%lx",&l))
+ {
+ ERR_error_string_n(l, buf, sizeof buf);
+ printf("%s\n",buf);
+ }
+ else
+ {
+ printf("%s: bad error code\n",argv[i]);
+ printf("usage: errstr [-stats] <errno> ...\n");
+ ret++;
+ }
+ }
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
diff --git a/deps/openssl/openssl/apps/gendh.c b/deps/openssl/openssl/apps/gendh.c
new file mode 100644
index 000000000..4ec776ba9
--- /dev/null
+++ b/deps/openssl/openssl/apps/gendh.c
@@ -0,0 +1,241 @@
+/* apps/gendh.c */
+/* obsoleted by dhparam.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#ifndef OPENSSL_NO_DH
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#define DEFBITS 512
+#undef PROG
+#define PROG gendh_main
+
+static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ BN_GENCB cb;
+ DH *dh=NULL;
+ int ret=1,num=DEFBITS;
+ int g=2;
+ char *outfile=NULL;
+ char *inrand=NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+ BIO *out=NULL;
+
+ apps_startup();
+
+ BN_GENCB_set(&cb, dh_cb, bio_err);
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ argv++;
+ argc--;
+ for (;;)
+ {
+ if (argc <= 0) break;
+ if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-2") == 0)
+ g=2;
+ /* else if (strcmp(*argv,"-3") == 0)
+ g=3; */
+ else if (strcmp(*argv,"-5") == 0)
+ g=5;
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-rand") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inrand= *(++argv);
+ }
+ else
+ break;
+ argv++;
+ argc--;
+ }
+ if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0)))
+ {
+bad:
+ BIO_printf(bio_err,"usage: gendh [args] [numbits]\n");
+ BIO_printf(bio_err," -out file - output the key to 'file\n");
+ BIO_printf(bio_err," -2 - use 2 as the generator value\n");
+ /* BIO_printf(bio_err," -3 - use 3 as the generator value\n"); */
+ BIO_printf(bio_err," -5 - use 5 as the generator value\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err," - load the file (or the files in the directory) into\n");
+ BIO_printf(bio_err," the random number generator\n");
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ out=BIO_new(BIO_s_file());
+ if (out == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
+ {
+ BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+ }
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+
+ BIO_printf(bio_err,"Generating DH parameters, %d bit long safe prime, generator %d\n",num,g);
+ BIO_printf(bio_err,"This is going to take a long time\n");
+
+ if(((dh = DH_new()) == NULL) || !DH_generate_parameters_ex(dh, num, g, &cb))
+ goto end;
+
+ app_RAND_write_file(NULL, bio_err);
+
+ if (!PEM_write_bio_DHparams(out,dh))
+ goto end;
+ ret=0;
+end:
+ if (ret != 0)
+ ERR_print_errors(bio_err);
+ if (out != NULL) BIO_free_all(out);
+ if (dh != NULL) DH_free(dh);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb)
+ {
+ char c='*';
+
+ if (p == 0) c='.';
+ if (p == 1) c='+';
+ if (p == 2) c='*';
+ if (p == 3) c='\n';
+ BIO_write(cb->arg,&c,1);
+ (void)BIO_flush(cb->arg);
+#ifdef LINT
+ p=n;
+#endif
+ return 1;
+ }
+#else /* !OPENSSL_NO_DH */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/gendsa.c b/deps/openssl/openssl/apps/gendsa.c
new file mode 100644
index 000000000..62ea97790
--- /dev/null
+++ b/deps/openssl/openssl/apps/gendsa.c
@@ -0,0 +1,285 @@
+/* apps/gendsa.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DSA
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#define DEFBITS 512
+#undef PROG
+#define PROG gendsa_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ DSA *dsa=NULL;
+ int ret=1;
+ char *outfile=NULL;
+ char *inrand=NULL,*dsaparams=NULL;
+ char *passargout = NULL, *passout = NULL;
+ BIO *out=NULL,*in=NULL;
+ const EVP_CIPHER *enc=NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ argv++;
+ argc--;
+ for (;;)
+ {
+ if (argc <= 0) break;
+ if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-passout") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargout= *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-rand") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inrand= *(++argv);
+ }
+ else if (strcmp(*argv,"-") == 0)
+ goto bad;
+#ifndef OPENSSL_NO_DES
+ else if (strcmp(*argv,"-des") == 0)
+ enc=EVP_des_cbc();
+ else if (strcmp(*argv,"-des3") == 0)
+ enc=EVP_des_ede3_cbc();
+#endif
+#ifndef OPENSSL_NO_IDEA
+ else if (strcmp(*argv,"-idea") == 0)
+ enc=EVP_idea_cbc();
+#endif
+#ifndef OPENSSL_NO_SEED
+ else if (strcmp(*argv,"-seed") == 0)
+ enc=EVP_seed_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+ else if (strcmp(*argv,"-aes128") == 0)
+ enc=EVP_aes_128_cbc();
+ else if (strcmp(*argv,"-aes192") == 0)
+ enc=EVP_aes_192_cbc();
+ else if (strcmp(*argv,"-aes256") == 0)
+ enc=EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ else if (strcmp(*argv,"-camellia128") == 0)
+ enc=EVP_camellia_128_cbc();
+ else if (strcmp(*argv,"-camellia192") == 0)
+ enc=EVP_camellia_192_cbc();
+ else if (strcmp(*argv,"-camellia256") == 0)
+ enc=EVP_camellia_256_cbc();
+#endif
+ else if (**argv != '-' && dsaparams == NULL)
+ {
+ dsaparams = *argv;
+ }
+ else
+ goto bad;
+ argv++;
+ argc--;
+ }
+
+ if (dsaparams == NULL)
+ {
+bad:
+ BIO_printf(bio_err,"usage: gendsa [args] dsaparam-file\n");
+ BIO_printf(bio_err," -out file - output the key to 'file'\n");
+#ifndef OPENSSL_NO_DES
+ BIO_printf(bio_err," -des - encrypt the generated key with DES in cbc mode\n");
+ BIO_printf(bio_err," -des3 - encrypt the generated key with DES in ede cbc mode (168 bit key)\n");
+#endif
+#ifndef OPENSSL_NO_IDEA
+ BIO_printf(bio_err," -idea - encrypt the generated key with IDEA in cbc mode\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+ BIO_printf(bio_err," -seed\n");
+ BIO_printf(bio_err," encrypt PEM output with cbc seed\n");
+#endif
+#ifndef OPENSSL_NO_AES
+ BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
+ BIO_printf(bio_err," encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
+ BIO_printf(bio_err," encrypt PEM output with cbc camellia\n");
+#endif
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err," - load the file (or the files in the directory) into\n");
+ BIO_printf(bio_err," the random number generator\n");
+ BIO_printf(bio_err," dsaparam-file\n");
+ BIO_printf(bio_err," - a DSA parameter file as generated by the dsaparam command\n");
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ if(!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+
+ in=BIO_new(BIO_s_file());
+ if (!(BIO_read_filename(in,dsaparams)))
+ {
+ perror(dsaparams);
+ goto end;
+ }
+
+ if ((dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL)
+ {
+ BIO_printf(bio_err,"unable to load DSA parameter file\n");
+ goto end;
+ }
+ BIO_free(in);
+ in = NULL;
+
+ out=BIO_new(BIO_s_file());
+ if (out == NULL) goto end;
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
+ {
+ BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+ }
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+
+ BIO_printf(bio_err,"Generating DSA key, %d bits\n",
+ BN_num_bits(dsa->p));
+ if (!DSA_generate_key(dsa)) goto end;
+
+ app_RAND_write_file(NULL, bio_err);
+
+ if (!PEM_write_bio_DSAPrivateKey(out,dsa,enc,NULL,0,NULL, passout))
+ goto end;
+ ret=0;
+end:
+ if (ret != 0)
+ ERR_print_errors(bio_err);
+ if (in != NULL) BIO_free(in);
+ if (out != NULL) BIO_free_all(out);
+ if (dsa != NULL) DSA_free(dsa);
+ if(passout) OPENSSL_free(passout);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+#else /* !OPENSSL_NO_DSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/genpkey.c b/deps/openssl/openssl/apps/genpkey.c
new file mode 100644
index 000000000..6dfda08b9
--- /dev/null
+++ b/deps/openssl/openssl/apps/genpkey.c
@@ -0,0 +1,440 @@
+/* apps/genpkey.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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
+ * licensing@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).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
+ const char *file, ENGINE *e);
+static int genpkey_cb(EVP_PKEY_CTX *ctx);
+
+#define PROG genpkey_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ char **args, *outfile = NULL;
+ char *passarg = NULL;
+ BIO *in = NULL, *out = NULL;
+ const EVP_CIPHER *cipher = NULL;
+ int outformat;
+ int text = 0;
+ EVP_PKEY *pkey=NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ char *pass = NULL;
+ int badarg = 0;
+ int ret = 1, rv;
+
+ int do_param = 0;
+
+ if (bio_err == NULL)
+ bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ outformat=FORMAT_PEM;
+
+ ERR_load_crypto_strings();
+ OpenSSL_add_all_algorithms();
+ args = argv + 1;
+ while (!badarg && *args && *args[0] == '-')
+ {
+ if (!strcmp(*args,"-outform"))
+ {
+ if (args[1])
+ {
+ args++;
+ outformat=str2fmt(*args);
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args,"-pass"))
+ {
+ if (!args[1]) goto bad;
+ passarg= *(++args);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*args,"-engine") == 0)
+ {
+ if (!args[1])
+ goto bad;
+ e = setup_engine(bio_err, *(++args), 0);
+ }
+#endif
+ else if (!strcmp (*args, "-paramfile"))
+ {
+ if (!args[1])
+ goto bad;
+ args++;
+ if (do_param == 1)
+ goto bad;
+ if (!init_keygen_file(bio_err, &ctx, *args, e))
+ goto end;
+ }
+ else if (!strcmp (*args, "-out"))
+ {
+ if (args[1])
+ {
+ args++;
+ outfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (strcmp(*args,"-algorithm") == 0)
+ {
+ if (!args[1])
+ goto bad;
+ if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
+ goto end;
+ }
+ else if (strcmp(*args,"-pkeyopt") == 0)
+ {
+ if (!args[1])
+ goto bad;
+ if (!ctx)
+ {
+ BIO_puts(bio_err, "No keytype specified\n");
+ goto bad;
+ }
+ else if (pkey_ctrl_string(ctx, *(++args)) <= 0)
+ {
+ BIO_puts(bio_err, "parameter setting error\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ else if (strcmp(*args,"-genparam") == 0)
+ {
+ if (ctx)
+ goto bad;
+ do_param = 1;
+ }
+ else if (strcmp(*args,"-text") == 0)
+ text=1;
+ else
+ {
+ cipher = EVP_get_cipherbyname(*args + 1);
+ if (!cipher)
+ {
+ BIO_printf(bio_err, "Unknown cipher %s\n",
+ *args + 1);
+ badarg = 1;
+ }
+ if (do_param == 1)
+ badarg = 1;
+ }
+ args++;
+ }
+
+ if (!ctx)
+ badarg = 1;
+
+ if (badarg)
+ {
+ bad:
+ BIO_printf(bio_err, "Usage: genpkey [options]\n");
+ BIO_printf(bio_err, "where options may be\n");
+ BIO_printf(bio_err, "-out file output file\n");
+ BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
+ BIO_printf(bio_err, "-pass arg output file pass phrase source\n");
+ BIO_printf(bio_err, "-<cipher> use cipher <cipher> to encrypt the key\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf(bio_err, "-paramfile file parameters file\n");
+ BIO_printf(bio_err, "-algorithm alg the public key algorithm\n");
+ BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n"
+ " to value <value>\n");
+ BIO_printf(bio_err, "-genparam generate parameters, not key\n");
+ BIO_printf(bio_err, "-text print the in text\n");
+ BIO_printf(bio_err, "NB: options order may be important! See the manual page.\n");
+ goto end;
+ }
+
+ if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
+ {
+ BIO_puts(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+ if (outfile)
+ {
+ if (!(out = BIO_new_file (outfile, "wb")))
+ {
+ BIO_printf(bio_err,
+ "Can't open output file %s\n", outfile);
+ goto end;
+ }
+ }
+ else
+ {
+ out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+
+ EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
+ EVP_PKEY_CTX_set_app_data(ctx, bio_err);
+
+ if (do_param)
+ {
+ if (EVP_PKEY_paramgen(ctx, &pkey) <= 0)
+ {
+ BIO_puts(bio_err, "Error generating parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ else
+ {
+ if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+ {
+ BIO_puts(bio_err, "Error generating key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (do_param)
+ rv = PEM_write_bio_Parameters(out, pkey);
+ else if (outformat == FORMAT_PEM)
+ rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
+ NULL, pass);
+ else if (outformat == FORMAT_ASN1)
+ rv = i2d_PrivateKey_bio(out, pkey);
+ else
+ {
+ BIO_printf(bio_err, "Bad format specified for key\n");
+ goto end;
+ }
+
+ if (rv <= 0)
+ {
+ BIO_puts(bio_err, "Error writing key\n");
+ ERR_print_errors(bio_err);
+ }
+
+ if (text)
+ {
+ if (do_param)
+ rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
+ else
+ rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
+
+ if (rv <= 0)
+ {
+ BIO_puts(bio_err, "Error printing key\n");
+ ERR_print_errors(bio_err);
+ }
+ }
+
+ ret = 0;
+
+ end:
+ if (pkey)
+ EVP_PKEY_free(pkey);
+ if (ctx)
+ EVP_PKEY_CTX_free(ctx);
+ if (out)
+ BIO_free_all(out);
+ BIO_free(in);
+ if (pass)
+ OPENSSL_free(pass);
+
+ return ret;
+ }
+
+static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
+ const char *file, ENGINE *e)
+ {
+ BIO *pbio;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ if (*pctx)
+ {
+ BIO_puts(err, "Parameters already set!\n");
+ return 0;
+ }
+
+ pbio = BIO_new_file(file, "r");
+ if (!pbio)
+ {
+ BIO_printf(err, "Can't open parameter file %s\n", file);
+ return 0;
+ }
+
+ pkey = PEM_read_bio_Parameters(pbio, NULL);
+ BIO_free(pbio);
+
+ if (!pkey)
+ {
+ BIO_printf(bio_err, "Error reading parameter file %s\n", file);
+ return 0;
+ }
+
+ ctx = EVP_PKEY_CTX_new(pkey, e);
+ if (!ctx)
+ goto err;
+ if (EVP_PKEY_keygen_init(ctx) <= 0)
+ goto err;
+ EVP_PKEY_free(pkey);
+ *pctx = ctx;
+ return 1;
+
+ err:
+ BIO_puts(err, "Error initializing context\n");
+ ERR_print_errors(err);
+ if (ctx)
+ EVP_PKEY_CTX_free(ctx);
+ if (pkey)
+ EVP_PKEY_free(pkey);
+ return 0;
+
+ }
+
+int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
+ const char *algname, ENGINE *e, int do_param)
+ {
+ EVP_PKEY_CTX *ctx = NULL;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ ENGINE *tmpeng = NULL;
+ int pkey_id;
+
+ if (*pctx)
+ {
+ BIO_puts(err, "Algorithm already set!\n");
+ return 0;
+ }
+
+ ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
+
+#ifndef OPENSSL_NO_ENGINE
+ if (!ameth && e)
+ ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
+#endif
+
+ if (!ameth)
+ {
+ BIO_printf(bio_err, "Algorithm %s not found\n", algname);
+ return 0;
+ }
+
+ ERR_clear_error();
+
+ EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+#ifndef OPENSSL_NO_ENGINE
+ if (tmpeng)
+ ENGINE_finish(tmpeng);
+#endif
+ ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
+
+ if (!ctx)
+ goto err;
+ if (do_param)
+ {
+ if (EVP_PKEY_paramgen_init(ctx) <= 0)
+ goto err;
+ }
+ else
+ {
+ if (EVP_PKEY_keygen_init(ctx) <= 0)
+ goto err;
+ }
+
+ *pctx = ctx;
+ return 1;
+
+ err:
+ BIO_printf(err, "Error initializing %s context\n", algname);
+ ERR_print_errors(err);
+ if (ctx)
+ EVP_PKEY_CTX_free(ctx);
+ return 0;
+
+ }
+
+static int genpkey_cb(EVP_PKEY_CTX *ctx)
+ {
+ char c='*';
+ BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+ int p;
+ p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+ if (p == 0) c='.';
+ if (p == 1) c='+';
+ if (p == 2) c='*';
+ if (p == 3) c='\n';
+ BIO_write(b,&c,1);
+ (void)BIO_flush(b);
+#ifdef LINT
+ p=n;
+#endif
+ return 1;
+ }
diff --git a/deps/openssl/openssl/apps/genrsa.c b/deps/openssl/openssl/apps/genrsa.c
new file mode 100644
index 000000000..ece114c87
--- /dev/null
+++ b/deps/openssl/openssl/apps/genrsa.c
@@ -0,0 +1,335 @@
+/* apps/genrsa.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#ifndef OPENSSL_NO_RSA
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+
+#define DEFBITS 1024
+#undef PROG
+#define PROG genrsa_main
+
+static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ BN_GENCB cb;
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE *e = NULL;
+#endif
+ int ret=1;
+ int i,num=DEFBITS;
+ long l;
+ const EVP_CIPHER *enc=NULL;
+ unsigned long f4=RSA_F4;
+ char *outfile=NULL;
+ char *passargout = NULL, *passout = NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+ char *inrand=NULL;
+ BIO *out=NULL;
+ BIGNUM *bn = BN_new();
+ RSA *rsa = NULL;
+
+ if(!bn) goto err;
+
+ apps_startup();
+ BN_GENCB_set(&cb, genrsa_cb, bio_err);
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto err;
+ if ((out=BIO_new(BIO_s_file())) == NULL)
+ {
+ BIO_printf(bio_err,"unable to create BIO for output\n");
+ goto err;
+ }
+
+ argv++;
+ argc--;
+ for (;;)
+ {
+ if (argc <= 0) break;
+ if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-3") == 0)
+ f4=3;
+ else if (strcmp(*argv,"-F4") == 0 || strcmp(*argv,"-f4") == 0)
+ f4=RSA_F4;
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-rand") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inrand= *(++argv);
+ }
+#ifndef OPENSSL_NO_DES
+ else if (strcmp(*argv,"-des") == 0)
+ enc=EVP_des_cbc();
+ else if (strcmp(*argv,"-des3") == 0)
+ enc=EVP_des_ede3_cbc();
+#endif
+#ifndef OPENSSL_NO_IDEA
+ else if (strcmp(*argv,"-idea") == 0)
+ enc=EVP_idea_cbc();
+#endif
+#ifndef OPENSSL_NO_SEED
+ else if (strcmp(*argv,"-seed") == 0)
+ enc=EVP_seed_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+ else if (strcmp(*argv,"-aes128") == 0)
+ enc=EVP_aes_128_cbc();
+ else if (strcmp(*argv,"-aes192") == 0)
+ enc=EVP_aes_192_cbc();
+ else if (strcmp(*argv,"-aes256") == 0)
+ enc=EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ else if (strcmp(*argv,"-camellia128") == 0)
+ enc=EVP_camellia_128_cbc();
+ else if (strcmp(*argv,"-camellia192") == 0)
+ enc=EVP_camellia_192_cbc();
+ else if (strcmp(*argv,"-camellia256") == 0)
+ enc=EVP_camellia_256_cbc();
+#endif
+ else if (strcmp(*argv,"-passout") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargout= *(++argv);
+ }
+ else
+ break;
+ argv++;
+ argc--;
+ }
+ if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0)))
+ {
+bad:
+ BIO_printf(bio_err,"usage: genrsa [args] [numbits]\n");
+ BIO_printf(bio_err," -des encrypt the generated key with DES in cbc mode\n");
+ BIO_printf(bio_err," -des3 encrypt the generated key with DES in ede cbc mode (168 bit key)\n");
+#ifndef OPENSSL_NO_IDEA
+ BIO_printf(bio_err," -idea encrypt the generated key with IDEA in cbc mode\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+ BIO_printf(bio_err," -seed\n");
+ BIO_printf(bio_err," encrypt PEM output with cbc seed\n");
+#endif
+#ifndef OPENSSL_NO_AES
+ BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
+ BIO_printf(bio_err," encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
+ BIO_printf(bio_err," encrypt PEM output with cbc camellia\n");
+#endif
+ BIO_printf(bio_err," -out file output the key to 'file\n");
+ BIO_printf(bio_err," -passout arg output file pass phrase source\n");
+ BIO_printf(bio_err," -f4 use F4 (0x10001) for the E value\n");
+ BIO_printf(bio_err," -3 use 3 for the E value\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err," load the file (or the files in the directory) into\n");
+ BIO_printf(bio_err," the random number generator\n");
+ goto err;
+ }
+
+ ERR_load_crypto_strings();
+
+ if(!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto err;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto err;
+ }
+ }
+
+ if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
+ && !RAND_status())
+ {
+ BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+ }
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+
+ BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n",
+ num);
+#ifdef OPENSSL_NO_ENGINE
+ rsa = RSA_new();
+#else
+ rsa = RSA_new_method(e);
+#endif
+ if (!rsa)
+ goto err;
+
+ if(!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb))
+ goto err;
+
+ app_RAND_write_file(NULL, bio_err);
+
+ /* We need to do the following for when the base number size is <
+ * long, esp windows 3.1 :-(. */
+ l=0L;
+ for (i=0; i<rsa->e->top; i++)
+ {
+#ifndef SIXTY_FOUR_BIT
+ l<<=BN_BITS4;
+ l<<=BN_BITS4;
+#endif
+ l+=rsa->e->d[i];
+ }
+ BIO_printf(bio_err,"e is %ld (0x%lX)\n",l,l);
+ {
+ PW_CB_DATA cb_data;
+ cb_data.password = passout;
+ cb_data.prompt_info = outfile;
+ if (!PEM_write_bio_RSAPrivateKey(out,rsa,enc,NULL,0,
+ (pem_password_cb *)password_callback,&cb_data))
+ goto err;
+ }
+
+ ret=0;
+err:
+ if (bn) BN_free(bn);
+ if (rsa) RSA_free(rsa);
+ if (out) BIO_free_all(out);
+ if(passout) OPENSSL_free(passout);
+ if (ret != 0)
+ ERR_print_errors(bio_err);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb)
+ {
+ char c='*';
+
+ if (p == 0) c='.';
+ if (p == 1) c='+';
+ if (p == 2) c='*';
+ if (p == 3) c='\n';
+ BIO_write(cb->arg,&c,1);
+ (void)BIO_flush(cb->arg);
+#ifdef LINT
+ p=n;
+#endif
+ return 1;
+ }
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/install-apps.com b/deps/openssl/openssl/apps/install-apps.com
new file mode 100755
index 000000000..7a553aa12
--- /dev/null
+++ b/deps/openssl/openssl/apps/install-apps.com
@@ -0,0 +1,107 @@
+$! INSTALL.COM -- Installs the files in a given directory tree
+$!
+$! Author: Richard Levitte <richard@levitte.org>
+$! Time of creation: 22-MAY-1998 10:13
+$!
+$! P1 root of the directory tree
+$! P2 "64" for 64-bit pointers.
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+ f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ on error then goto tidy
+$ on control_c then goto tidy
+$!
+$ if (p1 .eqs. "")
+$ then
+$ write sys$output "First argument missing."
+$ write sys$output -
+ "It should be the directory where you want things installed."
+$ exit
+$ endif
+$!
+$ if (f$getsyi("cpu") .lt. 128)
+$ then
+$ arch = "VAX"
+$ else
+$ arch = f$edit( f$getsyi( "arch_name"), "upcase")
+$ if (arch .eqs. "") then arch = "UNK"
+$ endif
+$!
+$ archd = arch
+$!
+$ if (p2 .nes. "")
+$ then
+$ if (p2 .eqs. "64")
+$ then
+$ archd = arch+ "_64"
+$ else
+$ if (p2 .nes. "32")
+$ then
+$ write sys$output "Second argument invalid."
+$ write sys$output "It should be "32", "64", or nothing."
+$ exit
+$ endif
+$ endif
+$ endif
+$!
+$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
+$ root_dev = f$parse(root,,,"device","syntax_only")
+$ root_dir = f$parse(root,,,"directory","syntax_only") - -
+ "[000000." - "][" - "[" - "]"
+$ root = root_dev + "[" + root_dir
+$!
+$ define /nolog wrk_sslroot 'root'.] /trans=conc
+$ define /nolog wrk_sslxexe wrk_sslroot:['archd'_exe]
+$!
+$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
+ create /directory /log wrk_sslroot:[000000]
+$ if f$parse("wrk_sslxexe:") .eqs. "" then -
+ create /directory /log wrk_sslxexe:
+$!
+$ exe := openssl
+$!
+$ exe_dir := [-.'archd'.exe.apps]
+$!
+$! Executables.
+$!
+$ i = 0
+$ loop_exe:
+$ e = f$edit(f$element( i, ",", exe), "trim")
+$ i = i + 1
+$ if e .eqs. "," then goto loop_exe_end
+$ set noon
+$ file = exe_dir+ e+ ".exe"
+$ if f$search( file) .nes. ""
+$ then
+$ copy /protection = w:re 'file' wrk_sslxexe: /log
+$ endif
+$ set on
+$ goto loop_exe
+$ loop_exe_end:
+$!
+$! Miscellaneous.
+$!
+$ set noon
+$ copy /protection = w:re ca.com wrk_sslxexe:ca.com /log
+$ copy /protection = w:re openssl-vms.cnf wrk_sslroot:[000000]openssl.cnf /log
+$ set on
+$!
+$ tidy:
+$!
+$ call deass wrk_sslroot
+$ call deass wrk_sslxexe
+$!
+$ exit
+$!
+$ deass: subroutine
+$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
+$ then
+$ deassign /process 'p1'
+$ endif
+$ endsubroutine
+$!
diff --git a/deps/openssl/openssl/apps/makeapps.com b/deps/openssl/openssl/apps/makeapps.com
new file mode 100644
index 000000000..efc213c8e
--- /dev/null
+++ b/deps/openssl/openssl/apps/makeapps.com
@@ -0,0 +1,1169 @@
+$!
+$! MAKEAPPS.COM
+$! Written By: Robert Byer
+$! Vice-President
+$! A-Com Computing, Inc.
+$! byer@mail.all-net.net
+$!
+$! Changes by Richard Levitte <richard@levitte.org>
+$! Zoltan Arpadffy <zoli@polarhome.com>
+$!
+$! This command files compiles and creates all the various different
+$! "application" programs for the different types of encryption for OpenSSL.
+$! The EXE's are placed in the directory [.xxx.EXE.APPS] where "xxx" denotes
+$! ALPHA, IA64 or VAX, depending on your machine architecture.
+$!
+$! It was written so it would try to determine what "C" compiler to
+$! use or you can specify which "C" compiler to use.
+$!
+$! Specify DEBUG or NODEBUG as P1 to compile with or without debugger
+$! information.
+$!
+$! Specify which compiler at P2 to try to compile under.
+$!
+$! VAXC For VAX C.
+$! DECC For DEC C.
+$! GNUC For GNU C.
+$!
+$! If you don't specify a compiler, it will try to determine which
+$! "C" compiler to use.
+$!
+$! P3, if defined, sets a TCP/IP library to use, through one of the following
+$! keywords:
+$!
+$! UCX for UCX
+$! SOCKETSHR for SOCKETSHR+NETLIB
+$! TCPIP for TCPIP (post UCX)
+$!
+$! P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$! P5, if defined, sets a choice of programs to compile.
+$!
+$! P6, if defined, specifies the C pointer size. Ignored on VAX.
+$! ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
+$! Supported values are:
+$!
+$! "" Compile with default (/NOPOINTER_SIZE)
+$! 32 Compile with /POINTER_SIZE=32 (SHORT)
+$! 64 Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
+$! (Automatically select ARGV if compiler supports it.)
+$! 64= Compile with /POINTER_SIZE=64 (LONG).
+$! 64=ARGV Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
+$!
+$! P7, if defined, specifies a directory where ZLIB files (zlib.h,
+$! libz.olb) may be found. Optionally, a non-default object library
+$! name may be included ("dev:[dir]libz_64.olb", for example).
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+ f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ on control_c then goto exit
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That Is, If We Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$ ZLIB_LIB = ""
+$!
+$! Check What Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$! The Architecture Is VAX.
+$!
+$ ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$ ARCHD = ARCH
+$ LIB32 = "32"
+$ OPT_FILE = ""
+$ POINTER_SIZE = ""
+$!
+$! Define what programs should be compiled
+$!
+$ PROGRAMS := OPENSSL
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Define The CRYPTO Library.
+$!
+$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
+$!
+$! Define The SSL Library.
+$!
+$ SSL_LIB := SYS$DISK:[-.'ARCHD'.EXE.SSL]SSL_LIBSSL'LIB32'.OLB
+$!
+$! Define The OBJ and EXE Directories.
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.APPS]
+$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.APPS]
+$!
+$! Specify the destination directory in any /MAP option.
+$!
+$ if (LINKMAP .eqs. "MAP")
+$ then
+$ LINKMAP = LINKMAP+ "=''EXE_DIR'"
+$ endif
+$!
+$! Add the location prefix to the linker options file name.
+$!
+$ if (OPT_FILE .nes. "")
+$ then
+$ OPT_FILE = EXE_DIR+ OPT_FILE
+$ endif
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
+$!
+$! Check To See If The OBJ Directory Exists.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."")
+$ THEN
+$!
+$! It Dosen't Exist, So Create It.
+$!
+$ CREATE/DIRECTORY 'OBJ_DIR'
+$!
+$! End The OBJ Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The EXE Directory Exists.
+$!
+$ IF (F$PARSE(EXE_DIR).EQS."")
+$ THEN
+$!
+$! It Dosen't Exist, So Create It.
+$!
+$ CREATE/DIRECTORY 'EXE_DIR'
+$!
+$! End The EXE Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define The Application Files.
+$! NOTE: Some might think this list ugly. However, it's made this way to
+$! reflect the E_OBJ variable in Makefile as closely as possible, thereby
+$! making it fairly easy to verify that the lists are the same.
+$!
+$ LIB_OPENSSL = "VERIFY,ASN1PARS,REQ,DGST,DH,DHPARAM,ENC,PASSWD,GENDH,ERRSTR,"+-
+ "CA,PKCS7,CRL2P7,CRL,"+-
+ "RSA,RSAUTL,DSA,DSAPARAM,EC,ECPARAM,"+-
+ "X509,GENRSA,GENDSA,GENPKEY,S_SERVER,S_CLIENT,SPEED,"+-
+ "S_TIME,APPS,S_CB,S_SOCKET,APP_RAND,VERSION,SESS_ID,"+-
+ "CIPHERS,NSEQ,PKCS12,PKCS8,PKEY,PKEYPARAM,PKEYUTL,"+ -
+ "SPKAC,SMIME,CMS,RAND,ENGINE,OCSP,PRIME,TS,SRP"
+$!
+$ LIB_OPENSSL = LIB_OPENSSL+ ",VMS_DECC_INIT"
+$!
+$ TCPIP_PROGRAMS = ",,"
+$ IF COMPILER .EQS. "VAXC" THEN -
+ TCPIP_PROGRAMS = ",OPENSSL,"
+$!
+$! Setup exceptional compilations
+$!
+$ COMPILEWITH_CC2 = ",S_SOCKET,S_SERVER,S_CLIENT,"
+$!
+$ PHASE := LIB
+$!
+$ RESTART:
+$!
+$! Define An App Counter And Set It To "0".
+$!
+$ APP_COUNTER = 0
+$!
+$! Top Of The App Loop.
+$!
+$ NEXT_APP:
+$!
+$! Make The Application File Name
+$!
+$ CURRENT_APP = F$EDIT(F$ELEMENT(APP_COUNTER,",",PROGRAMS),"TRIM")
+$!
+$! Create The Executable File Name.
+$!
+$ EXE_FILE = EXE_DIR + CURRENT_APP + ".EXE"
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (CURRENT_APP.EQS.",")
+$ THEN
+$ IF (PHASE.EQS."LIB")
+$ THEN
+$ PHASE := APP
+$ GOTO RESTART
+$ ELSE
+$ GOTO APP_DONE
+$ ENDIF
+$ ENDIF
+$!
+$! Increment The Counter.
+$!
+$ APP_COUNTER = APP_COUNTER + 1
+$!
+$! Decide if we're building the object files or not.
+$!
+$ IF (PHASE.EQS."LIB")
+$ THEN
+$!
+$! Define A Library File Counter And Set It To "-1".
+$! -1 Means The Application File Name Is To Be Used.
+$!
+$ LIB_COUNTER = -1
+$!
+$! Create a .OPT file for the object files
+$!
+$ OPEN /WRITE OBJECTS 'EXE_DIR''CURRENT_APP'.OPT
+$!
+$! Top Of The File Loop.
+$!
+$ NEXT_LIB:
+$!
+$! O.K, Extract The File Name From The File List.
+$!
+$ IF LIB_COUNTER .GE. 0
+$ THEN
+$ FILE_NAME = F$EDIT(F$ELEMENT(LIB_COUNTER,",",LIB_'CURRENT_APP'),"TRIM")
+$ ELSE
+$ FILE_NAME = CURRENT_APP
+$ ENDIF
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (FILE_NAME.EQS.",")
+$ THEN
+$ CLOSE OBJECTS
+$ GOTO NEXT_APP
+$ ENDIF
+$!
+$! Increment The Counter.
+$!
+$ LIB_COUNTER = LIB_COUNTER + 1
+$!
+$! Create The Source File Name.
+$!
+$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
+$!
+$! Create The Object File Name.
+$!
+$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
+$ ON WARNING THEN GOTO NEXT_LIB
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH(SOURCE_FILE).EQS."")
+$ THEN
+$!
+$! Tell The User That The File Dosen't Exist.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Exit The Build.
+$!
+$ GOTO EXIT
+$!
+$! End The File Exist Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What We Are Building.
+$!
+$ IF (PHASE.EQS."LIB")
+$ THEN
+$ WRITE SYS$OUTPUT "Compiling The ",FILE_NAME,".C File."
+$ ELSE
+$ WRITE SYS$OUTPUT "Building The ",FILE_NAME," Application Program."
+$ ENDIF
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO NEXT_LIB
+$ IF COMPILEWITH_CC2 - FILE_NAME .NES. COMPILEWITH_CC2
+$ THEN
+$ CC2/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ENDIF
+$ WRITE OBJECTS OBJECT_FILE
+$!
+$ GOTO NEXT_LIB
+$ ENDIF
+$!
+$! Check if this program works well without a TCPIP library
+$!
+$ IF TCPIP_LIB .EQS. "" .AND. TCPIP_PROGRAMS - CURRENT_APP .NES. TCPIP_PROGRAMS
+$ THEN
+$ WRITE SYS$OUTPUT CURRENT_APP," needs a TCP/IP library. Can't link. Skipping..."
+$ GOTO NEXT_APP
+$ ENDIF
+$!
+$! Link The Program.
+$!
+$ ON WARNING THEN GOTO NEXT_APP
+$!
+$! Don't Link With The RSAREF Routines And TCP/IP Library.
+$!
+$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXE='EXE_FILE' -
+ 'EXE_DIR''CURRENT_APP'.OPT /OPTIONS, -
+ 'SSL_LIB' /LIBRARY, -
+ 'CRYPTO_LIB' /LIBRARY -
+ 'TCPIP_LIB' -
+ 'ZLIB_LIB' -
+ ,'OPT_FILE' /OPTIONS
+$!
+$! Go Back And Do It Again.
+$!
+$ GOTO NEXT_APP
+$!
+$! All Done With This File.
+$!
+$ APP_DONE:
+$ EXIT:
+$!
+$! All Done, Time To Clean Up And Exit.
+$!
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$! Check To See If We Already Have A VAX C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A VAX C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If We Already Have A GNU C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A GNU C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$! Check To See If We Already Have A DEC C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! Figure Out If We Need An AXP Or A VAX Linker Option File.
+$!
+$ IF ARCH.EQS."VAX"
+$ THEN
+$!
+$! We Need A DEC C Linker Option File For VAX.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Create The non-VAX Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Against
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$! End The DEC C Option File Check.
+$!
+$ ENDIF
+$!
+$! End The Option File Search.
+$!
+$ ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check To See If We Have The Appropiate Libraries.
+$!
+$ LIB_CHECK:
+$!
+$! Look For The Library LIBCRYPTO.OLB.
+$!
+$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
+$ THEN
+$!
+$! Tell The User We Can't Find The LIBCRYPTO.OLB Library.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
+$ WRITE SYS$OUTPUT "We Can't Link Without It."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Since We Can't Link Without It, Exit.
+$!
+$ EXIT
+$!
+$! End The Crypto Library Check.
+$!
+$ ENDIF
+$!
+$! Look For The Library LIBSSL.OLB.
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$! Tell The User We Can't Find The LIBSSL.OLB Library.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
+$ WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Since We Can't Link Without It, Exit.
+$!
+$ EXIT
+$!
+$! End The SSL Library Check.
+$!
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."NODEBUG")
+$ THEN
+$!
+$! P1 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$ DEBUGGER = "NODEBUG"
+$ LINKMAP = "NOMAP"
+$ TRACEBACK = "NOTRACEBACK"
+$ GCC_OPTIMIZE = "OPTIMIZE"
+$ CC_OPTIMIZE = "OPTIMIZE"
+$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Are To Compile With Debugger Information.
+$!
+$ IF (P1.EQS."DEBUG")
+$ THEN
+$!
+$! Compile With Debugger Information.
+$!
+$ DEBUGGER = "DEBUG"
+$ LINKMAP = "MAP"
+$ TRACEBACK = "TRACEBACK"
+$ GCC_OPTIMIZE = "NOOPTIMIZE"
+$ CC_OPTIMIZE = "NOOPTIMIZE"
+$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
+$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check P6 (POINTER_SIZE).
+$!
+$ IF (P6 .NES. "") .AND. (ARCH .NES. "VAX")
+$ THEN
+$!
+$ IF (P6 .EQS. "32")
+$ THEN
+$ POINTER_SIZE = " /POINTER_SIZE=32"
+$ ELSE
+$ POINTER_SIZE = F$EDIT( P6, "COLLAPSE, UPCASE")
+$ IF ((POINTER_SIZE .EQS. "64") .OR. -
+ (POINTER_SIZE .EQS. "64=") .OR. -
+ (POINTER_SIZE .EQS. "64=ARGV"))
+$ THEN
+$ ARCHD = ARCH+ "_64"
+$ LIB32 = ""
+$ IF (F$EXTRACT( 2, 1, POINTER_SIZE) .EQS. "=")
+$ THEN
+$! Explicit user choice: "64" or "64=ARGV".
+$ IF (POINTER_SIZE .EQS. "64=") THEN POINTER_SIZE = "64"
+$ ELSE
+$ SET NOON
+$ DEFINE /USER_MODE SYS$OUTPUT NL:
+$ DEFINE /USER_MODE SYS$ERROR NL:
+$ CC /NOLIST /NOOBJECT /POINTER_SIZE=64=ARGV NL:
+$ IF ($STATUS .AND. %X0FFF0000) .EQ. %X00030000
+$ THEN
+$ ! If we got here, it means DCL complained like this:
+$ ! %DCL-W-NOVALU, value not allowed - remove value specification
+$ ! \64=\
+$ !
+$ ! If the compiler was run, logicals defined in /USER would
+$ ! have been deassigned automatically. However, when DCL
+$ ! complains, they aren't, so we do it here (it might be
+$ ! unnecessary, but just in case there will be another error
+$ ! message further on that we don't want to miss)
+$ DEASSIGN /USER_MODE SYS$ERROR
+$ DEASSIGN /USER_MODE SYS$OUTPUT
+$ ELSE
+$ POINTER_SIZE = POINTER_SIZE + "=ARGV"
+$ ENDIF
+$ SET ON
+$ ENDIF
+$ POINTER_SIZE = " /POINTER_SIZE=''POINTER_SIZE'"
+$!
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ", P6, -
+ " Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT -
+ " """" : Compile with default (short) pointers."
+$ WRITE SYS$OUTPUT -
+ " 32 : Compile with 32-bit (short) pointers."
+$ WRITE SYS$OUTPUT -
+ " 64 : Compile with 64-bit (long) pointers (auto ARGV)."
+$ WRITE SYS$OUTPUT -
+ " 64= : Compile with 64-bit (long) pointers (no ARGV)."
+$ WRITE SYS$OUTPUT -
+ " 64=ARGV : Compile with 64-bit (long) pointers (ARGV)."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$ ENDIF
+$!
+$ ENDIF
+$!
+$! End The P6 (POINTER_SIZE) Check.
+$!
+$ ENDIF
+$!
+$! Set basic C compiler /INCLUDE directories.
+$!
+$ CC_INCLUDES = "SYS$DISK:[-],SYS$DISK:[-.CRYPTO]"
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."")
+$ THEN
+$!
+$! O.K., The User Didn't Specify A Compiler, Let's Try To
+$! Find Out Which One To Use.
+$!
+$! Check To See If We Have GNU C.
+$!
+$ IF (F$TRNLNM("GNU_CC").NES."")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ P2 = "GNUC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Have VAXC Or DECC.
+$!
+$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ P2 = "DECC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ P2 = "VAXC"
+$!
+$! End The VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The DECC & VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P3.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$! Find out what socket library we have available
+$!
+$ IF F$PARSE("SOCKETSHR:") .NES. ""
+$ THEN
+$!
+$! We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$ P3 = "SOCKETSHR"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$! Else, let's look for something else
+$!
+$ ELSE
+$!
+$! Like UCX (the reason to do this before Multinet is that the UCX
+$! emulation is easier to use...)
+$!
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+ .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+ .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$ THEN
+$!
+$! Last resort: a UCX or UCX-compatible library
+$!
+$ P3 = "UCX"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$! That was all...
+$!
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "MONOLITH"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+ CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If We Have A ZLIB Option.
+$!
+$ ZLIB = P7
+$ IF (ZLIB .NES. "")
+$ THEN
+$!
+$! Check for expected ZLIB files.
+$!
+$ err = 0
+$ file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
+$ if (f$search( file1) .eqs. "")
+$ then
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$ WRITE SYS$OUTPUT " Can't find header: ''file1'"
+$ err = 1
+$ endif
+$ file1 = f$parse( "A.;", ZLIB)- "A.;"
+$!
+$ file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
+$ if (f$search( file2) .eqs. "")
+$ then
+$ if (err .eq. 0)
+$ then
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$ endif
+$ WRITE SYS$OUTPUT " Can't find library: ''file2'"
+$ WRITE SYS$OUTPUT ""
+$ err = err+ 2
+$ endif
+$ if (err .eq. 1)
+$ then
+$ WRITE SYS$OUTPUT ""
+$ endif
+$!
+$ if (err .ne. 0)
+$ then
+$ EXIT
+$ endif
+$!
+$ CCDEFS = """ZLIB=1"", "+ CCDEFS
+$ CC_INCLUDES = CC_INCLUDES+ ", "+ file1
+$ ZLIB_LIB = ", ''file2' /library"
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "ZLIB library spec: ", file2
+$!
+$! End The ZLIB Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The User Entered A Valid Parameter.
+$!
+$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If The User Wanted DECC.
+$!
+$ IF (P2.EQS."DECC")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ COMPILER = "DECC"
+$!
+$! Tell The User We Are Using DECC.
+$!
+$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$! Use DECC...
+$!
+$ CC = "CC"
+$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+ THEN CC = "CC/DECC"
+$ CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
+ "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
+ " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "VAX_DECC_OPTIONS.OPT"
+$!
+$! End DECC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use VAXC.
+$!
+$ IF (P2.EQS."VAXC")
+$ THEN
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ COMPILER = "VAXC"
+$!
+$! Tell The User We Are Using VAX C.
+$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$! Compile Using VAXC.
+$!
+$ CC = "CC"
+$ IF ARCH.NES."VAX"
+$ THEN
+$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$ EXIT
+$ ENDIF
+$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
+$ CCDEFS = CCDEFS + ",""VAXC"""
+$!
+$! Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
+$!
+$! End VAXC Check
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use GNU C.
+$!
+$ IF (P2.EQS."GNUC")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ COMPILER = "GNUC"
+$!
+$! Tell The User We Are Using GNUC.
+$!
+$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$! Use GNU C...
+$!
+$ IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
+$ CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Set up default defines
+$!
+$ CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
+$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
+$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$ ENDIF
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
+ .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
+$ THEN
+$!
+$! Check to see if SOCKETSHR was chosen
+$!
+$ IF P3.EQS."SOCKETSHR"
+$ THEN
+$!
+$! Set the library to use SOCKETSHR
+$!
+$ TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
+$!
+$! Done with SOCKETSHR
+$!
+$ ENDIF
+$!
+$! Check to see if MULTINET was chosen
+$!
+$ IF P3.EQS."MULTINET"
+$ THEN
+$!
+$! Set the library to use UCX emulation.
+$!
+$ P3 = "UCX"
+$!
+$! Done with MULTINET
+$!
+$ ENDIF
+$!
+$! Check to see if UCX was chosen
+$!
+$ IF P3.EQS."UCX"
+$ THEN
+$!
+$! Set the library to use UCX.
+$!
+$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$ THEN
+$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
+$ ELSE
+$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
+$ ENDIF
+$!
+$! Done with UCX
+$!
+$ ENDIF
+$!
+$! Check to see if TCPIP (post UCX) was chosen
+$!
+$ IF P3.EQS."TCPIP"
+$ THEN
+$!
+$! Set the library to use TCPIP.
+$!
+$ TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Check to see if NONE was chosen
+$!
+$ IF P3.EQS."NONE"
+$ THEN
+$!
+$! Do not use TCPIP.
+$!
+$ TCPIP_LIB = ""
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Add TCP/IP type to CC definitions.
+$!
+$ CCDEFS = CCDEFS + ",TCPIP_TYPE_''P3'"
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
+$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
+$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Finish up the definition of CC.
+$!
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$ IF CCDISABLEWARNINGS .NES. ""
+$ THEN
+$ CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$ ENDIF
+$ ELSE
+$ CCDISABLEWARNINGS = ""
+$ ENDIF
+$ CC2 = CC + " /DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
+$ CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$! Get The Version Of VMS We Are Using.
+$!
+$ ISSEVEN :=
+$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$! Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$ IF (TMP.GE.71)
+$ THEN
+$!
+$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$ ISSEVEN := ,PTHREAD_USE_D4
+$!
+$! End The VMS Version Check.
+$!
+$ ENDIF
+$!
+$! End The P4 Check.
+$!
+$ ENDIF
+$!
+$! Check if the user wanted to compile just a subset of all the programs.
+$!
+$ IF P5 .NES. ""
+$ THEN
+$ PROGRAMS = P5
+$ ENDIF
+$!
+$! Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "APPS]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL /NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the saved logical name OPENSSL, if it had a value.
+$!
+$ if (f$type( __SAVE_OPENSSL) .nes. "")
+$ then
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$ DEASSIGN OPENSSL
+$ ELSE
+$ DEFINE /NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$ endif
+$!
+$! Close any open files.
+$!
+$ if (f$trnlnm( "objects", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
+ close objects
+$!
+$! Done
+$!
+$ RETURN
+$!
diff --git a/deps/openssl/openssl/apps/md4.c b/deps/openssl/openssl/apps/md4.c
new file mode 100644
index 000000000..141415ad4
--- /dev/null
+++ b/deps/openssl/openssl/apps/md4.c
@@ -0,0 +1,127 @@
+/* crypto/md4/md4.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/md4.h>
+
+#define BUFSIZE 1024*16
+
+void do_fp(FILE *f);
+void pt(unsigned char *md);
+#if !defined(_OSD_POSIX) && !defined(__DJGPP__)
+int read(int, void *, unsigned int);
+#endif
+
+int main(int argc, char **argv)
+ {
+ int i,err=0;
+ FILE *IN;
+
+ if (argc == 1)
+ {
+ do_fp(stdin);
+ }
+ else
+ {
+ for (i=1; i<argc; i++)
+ {
+ IN=fopen(argv[i],"r");
+ if (IN == NULL)
+ {
+ perror(argv[i]);
+ err++;
+ continue;
+ }
+ printf("MD4(%s)= ",argv[i]);
+ do_fp(IN);
+ fclose(IN);
+ }
+ }
+ exit(err);
+ }
+
+void do_fp(FILE *f)
+ {
+ MD4_CTX c;
+ unsigned char md[MD4_DIGEST_LENGTH];
+ int fd;
+ int i;
+ static unsigned char buf[BUFSIZE];
+
+ fd=fileno(f);
+ MD4_Init(&c);
+ for (;;)
+ {
+ i=read(fd,buf,sizeof buf);
+ if (i <= 0) break;
+ MD4_Update(&c,buf,(unsigned long)i);
+ }
+ MD4_Final(&(md[0]),&c);
+ pt(md);
+ }
+
+void pt(unsigned char *md)
+ {
+ int i;
+
+ for (i=0; i<MD4_DIGEST_LENGTH; i++)
+ printf("%02x",md[i]);
+ printf("\n");
+ }
+
diff --git a/deps/openssl/openssl/apps/nseq.c b/deps/openssl/openssl/apps/nseq.c
new file mode 100644
index 000000000..e3c4dba54
--- /dev/null
+++ b/deps/openssl/openssl/apps/nseq.c
@@ -0,0 +1,167 @@
+/* nseq.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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
+ * licensing@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).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+#undef PROG
+#define PROG nseq_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+{
+ char **args, *infile = NULL, *outfile = NULL;
+ BIO *in = NULL, *out = NULL;
+ int toseq = 0;
+ X509 *x509 = NULL;
+ NETSCAPE_CERT_SEQUENCE *seq = NULL;
+ int i, ret = 1;
+ int badarg = 0;
+ if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+ ERR_load_crypto_strings();
+ args = argv + 1;
+ while (!badarg && *args && *args[0] == '-') {
+ if (!strcmp (*args, "-toseq")) toseq = 1;
+ else if (!strcmp (*args, "-in")) {
+ if (args[1]) {
+ args++;
+ infile = *args;
+ } else badarg = 1;
+ } else if (!strcmp (*args, "-out")) {
+ if (args[1]) {
+ args++;
+ outfile = *args;
+ } else badarg = 1;
+ } else badarg = 1;
+ args++;
+ }
+
+ if (badarg) {
+ BIO_printf (bio_err, "Netscape certificate sequence utility\n");
+ BIO_printf (bio_err, "Usage nseq [options]\n");
+ BIO_printf (bio_err, "where options are\n");
+ BIO_printf (bio_err, "-in file input file\n");
+ BIO_printf (bio_err, "-out file output file\n");
+ BIO_printf (bio_err, "-toseq output NS Sequence file\n");
+ OPENSSL_EXIT(1);
+ }
+
+ if (infile) {
+ if (!(in = BIO_new_file (infile, "r"))) {
+ BIO_printf (bio_err,
+ "Can't open input file %s\n", infile);
+ goto end;
+ }
+ } else in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+ if (outfile) {
+ if (!(out = BIO_new_file (outfile, "w"))) {
+ BIO_printf (bio_err,
+ "Can't open output file %s\n", outfile);
+ goto end;
+ }
+ } else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ if (toseq) {
+ seq = NETSCAPE_CERT_SEQUENCE_new();
+ seq->certs = sk_X509_new_null();
+ while((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL)))
+ sk_X509_push(seq->certs,x509);
+
+ if(!sk_X509_num(seq->certs))
+ {
+ BIO_printf (bio_err, "Error reading certs file %s\n", infile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ PEM_write_bio_NETSCAPE_CERT_SEQUENCE(out, seq);
+ ret = 0;
+ goto end;
+ }
+
+ if (!(seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL))) {
+ BIO_printf (bio_err, "Error reading sequence file %s\n", infile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ for(i = 0; i < sk_X509_num(seq->certs); i++) {
+ x509 = sk_X509_value(seq->certs, i);
+ dump_cert_text(out, x509);
+ PEM_write_bio_X509(out, x509);
+ }
+ ret = 0;
+end:
+ BIO_free(in);
+ BIO_free_all(out);
+ NETSCAPE_CERT_SEQUENCE_free(seq);
+
+ OPENSSL_EXIT(ret);
+}
+
diff --git a/deps/openssl/openssl/apps/ocsp.c b/deps/openssl/openssl/apps/ocsp.c
new file mode 100644
index 000000000..83c5a7670
--- /dev/null
+++ b/deps/openssl/openssl/apps/ocsp.c
@@ -0,0 +1,1421 @@
+/* ocsp.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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
+ * licensing@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).
+ *
+ */
+#ifndef OPENSSL_NO_OCSP
+
+#ifdef OPENSSL_SYS_VMS
+#define _XOPEN_SOURCE_EXTENDED /* So fd_set and friends get properly defined
+ on OpenVMS */
+#endif
+
+#define USE_SOCKETS
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h" /* needs to be included before the openssl headers! */
+#include <openssl/e_os2.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+
+#if defined(NETWARE_CLIB)
+# ifdef NETWARE_BSDSOCK
+# include <sys/socket.h>
+# include <sys/bsdskt.h>
+# else
+# include <novsock2.h>
+# endif
+#elif defined(NETWARE_LIBC)
+# ifdef NETWARE_BSDSOCK
+# include <sys/select.h>
+# else
+# include <novsock2.h>
+# endif
+#endif
+
+/* Maximum leeway in validity period: default 5 minutes */
+#define MAX_VALIDITY_PERIOD (5 * 60)
+
+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer,
+ STACK_OF(OCSP_CERTID) *ids);
+static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD * cert_id_md, X509 *issuer,
+ STACK_OF(OCSP_CERTID) *ids);
+static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
+ STACK_OF(OPENSSL_STRING) *names,
+ STACK_OF(OCSP_CERTID) *ids, long nsec,
+ long maxage);
+
+static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
+ X509 *ca, X509 *rcert, EVP_PKEY *rkey,
+ STACK_OF(X509) *rother, unsigned long flags,
+ int nmin, int ndays);
+
+static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
+static BIO *init_responder(char *port);
+static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
+static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
+static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
+ STACK_OF(CONF_VALUE) *headers,
+ OCSP_REQUEST *req, int req_timeout);
+
+#undef PROG
+#define PROG ocsp_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ char **args;
+ char *host = NULL, *port = NULL, *path = "/";
+ char *reqin = NULL, *respin = NULL;
+ char *reqout = NULL, *respout = NULL;
+ char *signfile = NULL, *keyfile = NULL;
+ char *rsignfile = NULL, *rkeyfile = NULL;
+ char *outfile = NULL;
+ int add_nonce = 1, noverify = 0, use_ssl = -1;
+ STACK_OF(CONF_VALUE) *headers = NULL;
+ OCSP_REQUEST *req = NULL;
+ OCSP_RESPONSE *resp = NULL;
+ OCSP_BASICRESP *bs = NULL;
+ X509 *issuer = NULL, *cert = NULL;
+ X509 *signer = NULL, *rsigner = NULL;
+ EVP_PKEY *key = NULL, *rkey = NULL;
+ BIO *acbio = NULL, *cbio = NULL;
+ BIO *derbio = NULL;
+ BIO *out = NULL;
+ int req_timeout = -1;
+ int req_text = 0, resp_text = 0;
+ long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
+ char *CAfile = NULL, *CApath = NULL;
+ X509_STORE *store = NULL;
+ STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
+ char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
+ unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
+ int ret = 1;
+ int accept_count = -1;
+ int badarg = 0;
+ int i;
+ int ignore_err = 0;
+ STACK_OF(OPENSSL_STRING) *reqnames = NULL;
+ STACK_OF(OCSP_CERTID) *ids = NULL;
+
+ X509 *rca_cert = NULL;
+ char *ridx_filename = NULL;
+ char *rca_filename = NULL;
+ CA_DB *rdb = NULL;
+ int nmin = 0, ndays = -1;
+ const EVP_MD *cert_id_md = NULL;
+
+ if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+ SSL_load_error_strings();
+ OpenSSL_add_ssl_algorithms();
+ args = argv + 1;
+ reqnames = sk_OPENSSL_STRING_new_null();
+ ids = sk_OCSP_CERTID_new_null();
+ while (!badarg && *args && *args[0] == '-')
+ {
+ if (!strcmp(*args, "-out"))
+ {
+ if (args[1])
+ {
+ args++;
+ outfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-timeout"))
+ {
+ if (args[1])
+ {
+ args++;
+ req_timeout = atol(*args);
+ if (req_timeout < 0)
+ {
+ BIO_printf(bio_err,
+ "Illegal timeout value %s\n",
+ *args);
+ badarg = 1;
+ }
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-url"))
+ {
+ if (args[1])
+ {
+ args++;
+ if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
+ {
+ BIO_printf(bio_err, "Error parsing URL\n");
+ badarg = 1;
+ }
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-host"))
+ {
+ if (args[1])
+ {
+ args++;
+ host = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-port"))
+ {
+ if (args[1])
+ {
+ args++;
+ port = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-header"))
+ {
+ if (args[1] && args[2])
+ {
+ if (!X509V3_add_value(args[1], args[2], &headers))
+ goto end;
+ args += 2;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-ignore_err"))
+ ignore_err = 1;
+ else if (!strcmp(*args, "-noverify"))
+ noverify = 1;
+ else if (!strcmp(*args, "-nonce"))
+ add_nonce = 2;
+ else if (!strcmp(*args, "-no_nonce"))
+ add_nonce = 0;
+ else if (!strcmp(*args, "-resp_no_certs"))
+ rflags |= OCSP_NOCERTS;
+ else if (!strcmp(*args, "-resp_key_id"))
+ rflags |= OCSP_RESPID_KEY;
+ else if (!strcmp(*args, "-no_certs"))
+ sign_flags |= OCSP_NOCERTS;
+ else if (!strcmp(*args, "-no_signature_verify"))
+ verify_flags |= OCSP_NOSIGS;
+ else if (!strcmp(*args, "-no_cert_verify"))
+ verify_flags |= OCSP_NOVERIFY;
+ else if (!strcmp(*args, "-no_chain"))
+ verify_flags |= OCSP_NOCHAIN;
+ else if (!strcmp(*args, "-no_cert_checks"))
+ verify_flags |= OCSP_NOCHECKS;
+ else if (!strcmp(*args, "-no_explicit"))
+ verify_flags |= OCSP_NOEXPLICIT;
+ else if (!strcmp(*args, "-trust_other"))
+ verify_flags |= OCSP_TRUSTOTHER;
+ else if (!strcmp(*args, "-no_intern"))
+ verify_flags |= OCSP_NOINTERN;
+ else if (!strcmp(*args, "-text"))
+ {
+ req_text = 1;
+ resp_text = 1;
+ }
+ else if (!strcmp(*args, "-req_text"))
+ req_text = 1;
+ else if (!strcmp(*args, "-resp_text"))
+ resp_text = 1;
+ else if (!strcmp(*args, "-reqin"))
+ {
+ if (args[1])
+ {
+ args++;
+ reqin = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-respin"))
+ {
+ if (args[1])
+ {
+ args++;
+ respin = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-signer"))
+ {
+ if (args[1])
+ {
+ args++;
+ signfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-VAfile"))
+ {
+ if (args[1])
+ {
+ args++;
+ verify_certfile = *args;
+ verify_flags |= OCSP_TRUSTOTHER;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-sign_other"))
+ {
+ if (args[1])
+ {
+ args++;
+ sign_certfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-verify_other"))
+ {
+ if (args[1])
+ {
+ args++;
+ verify_certfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-CAfile"))
+ {
+ if (args[1])
+ {
+ args++;
+ CAfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-CApath"))
+ {
+ if (args[1])
+ {
+ args++;
+ CApath = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-validity_period"))
+ {
+ if (args[1])
+ {
+ args++;
+ nsec = atol(*args);
+ if (nsec < 0)
+ {
+ BIO_printf(bio_err,
+ "Illegal validity period %s\n",
+ *args);
+ badarg = 1;
+ }
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-status_age"))
+ {
+ if (args[1])
+ {
+ args++;
+ maxage = atol(*args);
+ if (maxage < 0)
+ {
+ BIO_printf(bio_err,
+ "Illegal validity age %s\n",
+ *args);
+ badarg = 1;
+ }
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-signkey"))
+ {
+ if (args[1])
+ {
+ args++;
+ keyfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-reqout"))
+ {
+ if (args[1])
+ {
+ args++;
+ reqout = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-respout"))
+ {
+ if (args[1])
+ {
+ args++;
+ respout = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-path"))
+ {
+ if (args[1])
+ {
+ args++;
+ path = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-issuer"))
+ {
+ if (args[1])
+ {
+ args++;
+ X509_free(issuer);
+ issuer = load_cert(bio_err, *args, FORMAT_PEM,
+ NULL, e, "issuer certificate");
+ if(!issuer) goto end;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-cert"))
+ {
+ if (args[1])
+ {
+ args++;
+ X509_free(cert);
+ cert = load_cert(bio_err, *args, FORMAT_PEM,
+ NULL, e, "certificate");
+ if(!cert) goto end;
+ if (!cert_id_md) cert_id_md = EVP_sha1();
+ if(!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
+ goto end;
+ if(!sk_OPENSSL_STRING_push(reqnames, *args))
+ goto end;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-serial"))
+ {
+ if (args[1])
+ {
+ args++;
+ if (!cert_id_md) cert_id_md = EVP_sha1();
+ if(!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids))
+ goto end;
+ if(!sk_OPENSSL_STRING_push(reqnames, *args))
+ goto end;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-index"))
+ {
+ if (args[1])
+ {
+ args++;
+ ridx_filename = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-CA"))
+ {
+ if (args[1])
+ {
+ args++;
+ rca_filename = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-nmin"))
+ {
+ if (args[1])
+ {
+ args++;
+ nmin = atol(*args);
+ if (nmin < 0)
+ {
+ BIO_printf(bio_err,
+ "Illegal update period %s\n",
+ *args);
+ badarg = 1;
+ }
+ }
+ if (ndays == -1)
+ ndays = 0;
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-nrequest"))
+ {
+ if (args[1])
+ {
+ args++;
+ accept_count = atol(*args);
+ if (accept_count < 0)
+ {
+ BIO_printf(bio_err,
+ "Illegal accept count %s\n",
+ *args);
+ badarg = 1;
+ }
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-ndays"))
+ {
+ if (args[1])
+ {
+ args++;
+ ndays = atol(*args);
+ if (ndays < 0)
+ {
+ BIO_printf(bio_err,
+ "Illegal update period %s\n",
+ *args);
+ badarg = 1;
+ }
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-rsigner"))
+ {
+ if (args[1])
+ {
+ args++;
+ rsignfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-rkey"))
+ {
+ if (args[1])
+ {
+ args++;
+ rkeyfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args, "-rother"))
+ {
+ if (args[1])
+ {
+ args++;
+ rcertfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if ((cert_id_md = EVP_get_digestbyname((*args)+1))==NULL)
+ {
+ badarg = 1;
+ }
+ args++;
+ }
+
+ /* Have we anything to do? */
+ if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
+
+ if (badarg)
+ {
+ BIO_printf (bio_err, "OCSP utility\n");
+ BIO_printf (bio_err, "Usage ocsp [options]\n");
+ BIO_printf (bio_err, "where options are\n");
+ BIO_printf (bio_err, "-out file output filename\n");
+ BIO_printf (bio_err, "-issuer file issuer certificate\n");
+ BIO_printf (bio_err, "-cert file certificate to check\n");
+ BIO_printf (bio_err, "-serial n serial number to check\n");
+ BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n");
+ BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n");
+ BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n");
+ BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n");
+ BIO_printf (bio_err, "-req_text print text form of request\n");
+ BIO_printf (bio_err, "-resp_text print text form of response\n");
+ BIO_printf (bio_err, "-text print text form of request and response\n");
+ BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n");
+ BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n");
+ BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n");
+ BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n");
+ BIO_printf (bio_err, "-nonce add OCSP nonce to request\n");
+ BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n");
+ BIO_printf (bio_err, "-url URL OCSP responder URL\n");
+ BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n");
+ BIO_printf (bio_err, "-path path to use in OCSP request\n");
+ BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
+ BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
+ BIO_printf (bio_err, "-VAfile file validator certificates file\n");
+ BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
+ BIO_printf (bio_err, "-status_age n maximum status age in seconds\n");
+ BIO_printf (bio_err, "-noverify don't verify response at all\n");
+ BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
+ BIO_printf (bio_err, "-trust_other don't verify additional certificates\n");
+ BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n");
+ BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
+ BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n");
+ BIO_printf (bio_err, "-no_chain don't chain verify response\n");
+ BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n");
+ BIO_printf (bio_err, "-port num port to run responder on\n");
+ BIO_printf (bio_err, "-index file certificate status index file\n");
+ BIO_printf (bio_err, "-CA file CA certificate\n");
+ BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n");
+ BIO_printf (bio_err, "-rkey file responder key to sign responses with\n");
+ BIO_printf (bio_err, "-rother file other certificates to include in response\n");
+ BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n");
+ BIO_printf (bio_err, "-nmin n number of minutes before next update\n");
+ BIO_printf (bio_err, "-ndays n number of days before next update\n");
+ BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n");
+ BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n");
+ BIO_printf (bio_err, "-<dgst alg> use specified digest in the request\n");
+ goto end;
+ }
+
+ if(outfile) out = BIO_new_file(outfile, "w");
+ else out = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+ if(!out)
+ {
+ BIO_printf(bio_err, "Error opening output file\n");
+ goto end;
+ }
+
+ if (!req && (add_nonce != 2)) add_nonce = 0;
+
+ if (!req && reqin)
+ {
+ derbio = BIO_new_file(reqin, "rb");
+ if (!derbio)
+ {
+ BIO_printf(bio_err, "Error Opening OCSP request file\n");
+ goto end;
+ }
+ req = d2i_OCSP_REQUEST_bio(derbio, NULL);
+ BIO_free(derbio);
+ if(!req)
+ {
+ BIO_printf(bio_err, "Error reading OCSP request\n");
+ goto end;
+ }
+ }
+
+ if (!req && port)
+ {
+ acbio = init_responder(port);
+ if (!acbio)
+ goto end;
+ }
+
+ if (rsignfile && !rdb)
+ {
+ if (!rkeyfile) rkeyfile = rsignfile;
+ rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
+ NULL, e, "responder certificate");
+ if (!rsigner)
+ {
+ BIO_printf(bio_err, "Error loading responder certificate\n");
+ goto end;
+ }
+ rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
+ NULL, e, "CA certificate");
+ if (rcertfile)
+ {
+ rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
+ NULL, e, "responder other certificates");
+ if (!rother) goto end;
+ }
+ rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
+ "responder private key");
+ if (!rkey)
+ goto end;
+ }
+ if(acbio)
+ BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
+
+ redo_accept:
+
+ if (acbio)
+ {
+ if (!do_responder(&req, &cbio, acbio, port))
+ goto end;
+ if (!req)
+ {
+ resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
+ send_ocsp_response(cbio, resp);
+ goto done_resp;
+ }
+ }
+
+ if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
+ {
+ BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
+ goto end;
+ }
+
+ if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);
+
+ if (signfile)
+ {
+ if (!keyfile) keyfile = signfile;
+ signer = load_cert(bio_err, signfile, FORMAT_PEM,
+ NULL, e, "signer certificate");
+ if (!signer)
+ {
+ BIO_printf(bio_err, "Error loading signer certificate\n");
+ goto end;
+ }
+ if (sign_certfile)
+ {
+ sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
+ NULL, e, "signer certificates");
+ if (!sign_other) goto end;
+ }
+ key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
+ "signer private key");
+ if (!key)
+ goto end;
+
+ if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags))
+ {
+ BIO_printf(bio_err, "Error signing OCSP request\n");
+ goto end;
+ }
+ }
+
+ if (req_text && req) OCSP_REQUEST_print(out, req, 0);
+
+ if (reqout)
+ {
+ derbio = BIO_new_file(reqout, "wb");
+ if(!derbio)
+ {
+ BIO_printf(bio_err, "Error opening file %s\n", reqout);
+ goto end;
+ }
+ i2d_OCSP_REQUEST_bio(derbio, req);
+ BIO_free(derbio);
+ }
+
+ if (ridx_filename && (!rkey || !rsigner || !rca_cert))
+ {
+ BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
+ goto end;
+ }
+
+ if (ridx_filename && !rdb)
+ {
+ rdb = load_index(ridx_filename, NULL);
+ if (!rdb) goto end;
+ if (!index_index(rdb)) goto end;
+ }
+
+ if (rdb)
+ {
+ i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
+ if (cbio)
+ send_ocsp_response(cbio, resp);
+ }
+ else if (host)
+ {
+#ifndef OPENSSL_NO_SOCK
+ resp = process_responder(bio_err, req, host, path,
+ port, use_ssl, headers, req_timeout);
+ if (!resp)
+ goto end;
+#else
+ BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
+ goto end;
+#endif
+ }
+ else if (respin)
+ {
+ derbio = BIO_new_file(respin, "rb");
+ if (!derbio)
+ {
+ BIO_printf(bio_err, "Error Opening OCSP response file\n");
+ goto end;
+ }
+ resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
+ BIO_free(derbio);
+ if(!resp)
+ {
+ BIO_printf(bio_err, "Error reading OCSP response\n");
+ goto end;
+ }
+
+ }
+ else
+ {
+ ret = 0;
+ goto end;
+ }
+
+ done_resp:
+
+ if (respout)
+ {
+ derbio = BIO_new_file(respout, "wb");
+ if(!derbio)
+ {
+ BIO_printf(bio_err, "Error opening file %s\n", respout);
+ goto end;
+ }
+ i2d_OCSP_RESPONSE_bio(derbio, resp);
+ BIO_free(derbio);
+ }
+
+ i = OCSP_response_status(resp);
+
+ if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
+ {
+ BIO_printf(out, "Responder Error: %s (%d)\n",
+ OCSP_response_status_str(i), i);
+ if (ignore_err)
+ goto redo_accept;
+ ret = 0;
+ goto end;
+ }
+
+ if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
+
+ /* If running as responder don't verify our own response */
+ if (cbio)
+ {
+ if (accept_count > 0)
+ accept_count--;
+ /* Redo if more connections needed */
+ if (accept_count)
+ {
+ BIO_free_all(cbio);
+ cbio = NULL;
+ OCSP_REQUEST_free(req);
+ req = NULL;
+ OCSP_RESPONSE_free(resp);
+ resp = NULL;
+ goto redo_accept;
+ }
+ goto end;
+ }
+
+ if (!store)
+ store = setup_verify(bio_err, CAfile, CApath);
+ if (!store)
+ goto end;
+ if (verify_certfile)
+ {
+ verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
+ NULL, e, "validator certificate");
+ if (!verify_other) goto end;
+ }
+
+ bs = OCSP_response_get1_basic(resp);
+
+ if (!bs)
+ {
+ BIO_printf(bio_err, "Error parsing response\n");
+ goto end;
+ }
+
+ if (!noverify)
+ {
+ if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
+ {
+ if (i == -1)
+ BIO_printf(bio_err, "WARNING: no nonce in response\n");
+ else
+ {
+ BIO_printf(bio_err, "Nonce Verify error\n");
+ goto end;
+ }
+ }
+
+ i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
+ if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);
+
+ if(i <= 0)
+ {
+ BIO_printf(bio_err, "Response Verify Failure\n");
+ ERR_print_errors(bio_err);
+ }
+ else
+ BIO_printf(bio_err, "Response verify OK\n");
+
+ }
+
+ if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
+ goto end;
+
+ ret = 0;
+
+end:
+ ERR_print_errors(bio_err);
+ X509_free(signer);
+ X509_STORE_free(store);
+ EVP_PKEY_free(key);
+ EVP_PKEY_free(rkey);
+ X509_free(issuer);
+ X509_free(cert);
+ X509_free(rsigner);
+ X509_free(rca_cert);
+ free_index(rdb);
+ BIO_free_all(cbio);
+ BIO_free_all(acbio);
+ BIO_free(out);
+ OCSP_REQUEST_free(req);
+ OCSP_RESPONSE_free(resp);
+ OCSP_BASICRESP_free(bs);
+ sk_OPENSSL_STRING_free(reqnames);
+ sk_OCSP_CERTID_free(ids);
+ sk_X509_pop_free(sign_other, X509_free);
+ sk_X509_pop_free(verify_other, X509_free);
+ sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
+
+ if (use_ssl != -1)
+ {
+ OPENSSL_free(host);
+ OPENSSL_free(port);
+ OPENSSL_free(path);
+ }
+
+ OPENSSL_EXIT(ret);
+}
+
+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md,X509 *issuer,
+ STACK_OF(OCSP_CERTID) *ids)
+ {
+ OCSP_CERTID *id;
+ if(!issuer)
+ {
+ BIO_printf(bio_err, "No issuer certificate specified\n");
+ return 0;
+ }
+ if(!*req) *req = OCSP_REQUEST_new();
+ if(!*req) goto err;
+ id = OCSP_cert_to_id(cert_id_md, cert, issuer);
+ if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
+ if(!OCSP_request_add0_id(*req, id)) goto err;
+ return 1;
+
+ err:
+ BIO_printf(bio_err, "Error Creating OCSP request\n");
+ return 0;
+ }
+
+static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,const EVP_MD *cert_id_md, X509 *issuer,
+ STACK_OF(OCSP_CERTID) *ids)
+ {
+ OCSP_CERTID *id;
+ X509_NAME *iname;
+ ASN1_BIT_STRING *ikey;
+ ASN1_INTEGER *sno;
+ if(!issuer)
+ {
+ BIO_printf(bio_err, "No issuer certificate specified\n");
+ return 0;
+ }
+ if(!*req) *req = OCSP_REQUEST_new();
+ if(!*req) goto err;
+ iname = X509_get_subject_name(issuer);
+ ikey = X509_get0_pubkey_bitstr(issuer);
+ sno = s2i_ASN1_INTEGER(NULL, serial);
+ if(!sno)
+ {
+ BIO_printf(bio_err, "Error converting serial number %s\n", serial);
+ return 0;
+ }
+ id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
+ ASN1_INTEGER_free(sno);
+ if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
+ if(!OCSP_request_add0_id(*req, id)) goto err;
+ return 1;
+
+ err:
+ BIO_printf(bio_err, "Error Creating OCSP request\n");
+ return 0;
+ }
+
+static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
+ STACK_OF(OPENSSL_STRING) *names,
+ STACK_OF(OCSP_CERTID) *ids, long nsec,
+ long maxage)
+ {
+ OCSP_CERTID *id;
+ char *name;
+ int i;
+
+ int status, reason;
+
+ ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+
+ if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids))
+ return 1;
+
+ for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
+ {
+ id = sk_OCSP_CERTID_value(ids, i);
+ name = sk_OPENSSL_STRING_value(names, i);
+ BIO_printf(out, "%s: ", name);
+
+ if(!OCSP_resp_find_status(bs, id, &status, &reason,
+ &rev, &thisupd, &nextupd))
+ {
+ BIO_puts(out, "ERROR: No Status found.\n");
+ continue;
+ }
+
+ /* Check validity: if invalid write to output BIO so we
+ * know which response this refers to.
+ */
+ if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage))
+ {
+ BIO_puts(out, "WARNING: Status times invalid.\n");
+ ERR_print_errors(out);
+ }
+ BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
+
+ BIO_puts(out, "\tThis Update: ");
+ ASN1_GENERALIZEDTIME_print(out, thisupd);
+ BIO_puts(out, "\n");
+
+ if(nextupd)
+ {
+ BIO_puts(out, "\tNext Update: ");
+ ASN1_GENERALIZEDTIME_print(out, nextupd);
+ BIO_puts(out, "\n");
+ }
+
+ if (status != V_OCSP_CERTSTATUS_REVOKED)
+ continue;
+
+ if (reason != -1)
+ BIO_printf(out, "\tReason: %s\n",
+ OCSP_crl_reason_str(reason));
+
+ BIO_puts(out, "\tRevocation Time: ");
+ ASN1_GENERALIZEDTIME_print(out, rev);
+ BIO_puts(out, "\n");
+ }
+
+ return 1;
+ }
+
+
+static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
+ X509 *ca, X509 *rcert, EVP_PKEY *rkey,
+ STACK_OF(X509) *rother, unsigned long flags,
+ int nmin, int ndays)
+ {
+ ASN1_TIME *thisupd = NULL, *nextupd = NULL;
+ OCSP_CERTID *cid, *ca_id = NULL;
+ OCSP_BASICRESP *bs = NULL;
+ int i, id_count, ret = 1;
+
+ id_count = OCSP_request_onereq_count(req);
+
+ if (id_count <= 0)
+ {
+ *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
+ goto end;
+ }
+
+
+ bs = OCSP_BASICRESP_new();
+ thisupd = X509_gmtime_adj(NULL, 0);
+ if (ndays != -1)
+ nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 );
+
+ /* Examine each certificate id in the request */
+ for (i = 0; i < id_count; i++)
+ {
+ OCSP_ONEREQ *one;
+ ASN1_INTEGER *serial;
+ char **inf;
+ ASN1_OBJECT *cert_id_md_oid;
+ const EVP_MD *cert_id_md;
+ one = OCSP_request_onereq_get0(req, i);
+ cid = OCSP_onereq_get0_id(one);
+
+ OCSP_id_get0_info(NULL,&cert_id_md_oid, NULL,NULL, cid);
+
+ cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);
+ if (! cert_id_md)
+ {
+ *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
+ NULL);
+ goto end;
+ }
+ if (ca_id) OCSP_CERTID_free(ca_id);
+ ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
+
+ /* Is this request about our CA? */
+ if (OCSP_id_issuer_cmp(ca_id, cid))
+ {
+ OCSP_basic_add1_status(bs, cid,
+ V_OCSP_CERTSTATUS_UNKNOWN,
+ 0, NULL,
+ thisupd, nextupd);
+ continue;
+ }
+ OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
+ inf = lookup_serial(db, serial);
+ if (!inf)
+ OCSP_basic_add1_status(bs, cid,
+ V_OCSP_CERTSTATUS_UNKNOWN,
+ 0, NULL,
+ thisupd, nextupd);
+ else if (inf[DB_type][0] == DB_TYPE_VAL)
+ OCSP_basic_add1_status(bs, cid,
+ V_OCSP_CERTSTATUS_GOOD,
+ 0, NULL,
+ thisupd, nextupd);
+ else if (inf[DB_type][0] == DB_TYPE_REV)
+ {
+ ASN1_OBJECT *inst = NULL;
+ ASN1_TIME *revtm = NULL;
+ ASN1_GENERALIZEDTIME *invtm = NULL;
+ OCSP_SINGLERESP *single;
+ int reason = -1;
+ unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
+ single = OCSP_basic_add1_status(bs, cid,
+ V_OCSP_CERTSTATUS_REVOKED,
+ reason, revtm,
+ thisupd, nextupd);
+ if (invtm)
+ OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
+ else if (inst)
+ OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
+ ASN1_OBJECT_free(inst);
+ ASN1_TIME_free(revtm);
+ ASN1_GENERALIZEDTIME_free(invtm);
+ }
+ }
+
+ OCSP_copy_nonce(bs, req);
+
+ OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags);
+
+ *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
+
+ end:
+ ASN1_TIME_free(thisupd);
+ ASN1_TIME_free(nextupd);
+ OCSP_CERTID_free(ca_id);
+ OCSP_BASICRESP_free(bs);
+ return ret;
+
+ }
+
+static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
+ {
+ int i;
+ BIGNUM *bn = NULL;
+ char *itmp, *row[DB_NUMBER],**rrow;
+ for (i = 0; i < DB_NUMBER; i++) row[i] = NULL;
+ bn = ASN1_INTEGER_to_BN(ser,NULL);
+ OPENSSL_assert(bn); /* FIXME: should report an error at this point and abort */
+ if (BN_is_zero(bn))
+ itmp = BUF_strdup("00");
+ else
+ itmp = BN_bn2hex(bn);
+ row[DB_serial] = itmp;
+ BN_free(bn);
+ rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
+ OPENSSL_free(itmp);
+ return rrow;
+ }
+
+/* Quick and dirty OCSP server: read in and parse input request */
+
+static BIO *init_responder(char *port)
+ {
+ BIO *acbio = NULL, *bufbio = NULL;
+ bufbio = BIO_new(BIO_f_buffer());
+ if (!bufbio)
+ goto err;
+#ifndef OPENSSL_NO_SOCK
+ acbio = BIO_new_accept(port);
+#else
+ BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n");
+#endif
+ if (!acbio)
+ goto err;
+ BIO_set_accept_bios(acbio, bufbio);
+ bufbio = NULL;
+
+ if (BIO_do_accept(acbio) <= 0)
+ {
+ BIO_printf(bio_err, "Error setting up accept BIO\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ return acbio;
+
+ err:
+ BIO_free_all(acbio);
+ BIO_free(bufbio);
+ return NULL;
+ }
+
+static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port)
+ {
+ int have_post = 0, len;
+ OCSP_REQUEST *req = NULL;
+ char inbuf[1024];
+ BIO *cbio = NULL;
+
+ if (BIO_do_accept(acbio) <= 0)
+ {
+ BIO_printf(bio_err, "Error accepting connection\n");
+ ERR_print_errors(bio_err);
+ return 0;
+ }
+
+ cbio = BIO_pop(acbio);
+ *pcbio = cbio;
+
+ for(;;)
+ {
+ len = BIO_gets(cbio, inbuf, sizeof inbuf);
+ if (len <= 0)
+ return 1;
+ /* Look for "POST" signalling start of query */
+ if (!have_post)
+ {
+ if(strncmp(inbuf, "POST", 4))
+ {
+ BIO_printf(bio_err, "Invalid request\n");
+ return 1;
+ }
+ have_post = 1;
+ }
+ /* Look for end of headers */
+ if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
+ break;
+ }
+
+ /* Try to read OCSP request */
+
+ req = d2i_OCSP_REQUEST_bio(cbio, NULL);
+
+ if (!req)
+ {
+ BIO_printf(bio_err, "Error parsing OCSP request\n");
+ ERR_print_errors(bio_err);
+ }
+
+ *preq = req;
+
+ return 1;
+
+ }
+
+static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
+ {
+ char http_resp[] =
+ "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
+ "Content-Length: %d\r\n\r\n";
+ if (!cbio)
+ return 0;
+ BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
+ i2d_OCSP_RESPONSE_bio(cbio, resp);
+ (void)BIO_flush(cbio);
+ return 1;
+ }
+
+static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
+ STACK_OF(CONF_VALUE) *headers,
+ OCSP_REQUEST *req, int req_timeout)
+ {
+ int fd;
+ int rv;
+ int i;
+ OCSP_REQ_CTX *ctx = NULL;
+ OCSP_RESPONSE *rsp = NULL;
+ fd_set confds;
+ struct timeval tv;
+
+ if (req_timeout != -1)
+ BIO_set_nbio(cbio, 1);
+
+ rv = BIO_do_connect(cbio);
+
+ if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio)))
+ {
+ BIO_puts(err, "Error connecting BIO\n");
+ return NULL;
+ }
+
+ if (BIO_get_fd(cbio, &fd) <= 0)
+ {
+ BIO_puts(err, "Can't get connection fd\n");
+ goto err;
+ }
+
+ if (req_timeout != -1 && rv <= 0)
+ {
+ FD_ZERO(&confds);
+ openssl_fdset(fd, &confds);
+ tv.tv_usec = 0;
+ tv.tv_sec = req_timeout;
+ rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
+ if (rv == 0)
+ {
+ BIO_puts(err, "Timeout on connect\n");
+ return NULL;
+ }
+ }
+
+
+ ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
+ if (!ctx)
+ return NULL;
+
+ for (i = 0; i < sk_CONF_VALUE_num(headers); i++)
+ {
+ CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
+ if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
+ goto err;
+ }
+
+ if (!OCSP_REQ_CTX_set1_req(ctx, req))
+ goto err;
+
+ for (;;)
+ {
+ rv = OCSP_sendreq_nbio(&rsp, ctx);
+ if (rv != -1)
+ break;
+ if (req_timeout == -1)
+ continue;
+ FD_ZERO(&confds);
+ openssl_fdset(fd, &confds);
+ tv.tv_usec = 0;
+ tv.tv_sec = req_timeout;
+ if (BIO_should_read(cbio))
+ rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
+ else if (BIO_should_write(cbio))
+ rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
+ else
+ {
+ BIO_puts(err, "Unexpected retry condition\n");
+ goto err;
+ }
+ if (rv == 0)
+ {
+ BIO_puts(err, "Timeout on request\n");
+ break;
+ }
+ if (rv == -1)
+ {
+ BIO_puts(err, "Select error\n");
+ break;
+ }
+
+ }
+ err:
+ if (ctx)
+ OCSP_REQ_CTX_free(ctx);
+
+ return rsp;
+ }
+
+OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
+ char *host, char *path, char *port, int use_ssl,
+ STACK_OF(CONF_VALUE) *headers,
+ int req_timeout)
+ {
+ BIO *cbio = NULL;
+ SSL_CTX *ctx = NULL;
+ OCSP_RESPONSE *resp = NULL;
+ cbio = BIO_new_connect(host);
+ if (!cbio)
+ {
+ BIO_printf(err, "Error creating connect BIO\n");
+ goto end;
+ }
+ if (port) BIO_set_conn_port(cbio, port);
+ if (use_ssl == 1)
+ {
+ BIO *sbio;
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+ ctx = SSL_CTX_new(SSLv23_client_method());
+#elif !defined(OPENSSL_NO_SSL3)
+ ctx = SSL_CTX_new(SSLv3_client_method());
+#elif !defined(OPENSSL_NO_SSL2)
+ ctx = SSL_CTX_new(SSLv2_client_method());
+#else
+ BIO_printf(err, "SSL is disabled\n");
+ goto end;
+#endif
+ if (ctx == NULL)
+ {
+ BIO_printf(err, "Error creating SSL context.\n");
+ goto end;
+ }
+ SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
+ sbio = BIO_new_ssl(ctx, 1);
+ cbio = BIO_push(sbio, cbio);
+ }
+ resp = query_responder(err, cbio, path, headers, req, req_timeout);
+ if (!resp)
+ BIO_printf(bio_err, "Error querying OCSP responsder\n");
+ end:
+ if (cbio)
+ BIO_free_all(cbio);
+ if (ctx)
+ SSL_CTX_free(ctx);
+ return resp;
+ }
+
+#endif
diff --git a/deps/openssl/openssl/apps/oid.cnf b/deps/openssl/openssl/apps/oid.cnf
new file mode 100644
index 000000000..faf425a15
--- /dev/null
+++ b/deps/openssl/openssl/apps/oid.cnf
@@ -0,0 +1,6 @@
+2.99999.1 SET.ex1 SET x509v3 extension 1
+2.99999.2 SET.ex2 SET x509v3 extension 2
+2.99999.3 SET.ex3 SET x509v3 extension 3
+2.99999.4 SET.ex4 SET x509v3 extension 4
+2.99999.5 SET.ex5 SET x509v3 extension 5
+2.99999.6 SET.ex6 SET x509v3 extension 6
diff --git a/deps/openssl/openssl/apps/openssl-vms.cnf b/deps/openssl/openssl/apps/openssl-vms.cnf
new file mode 100644
index 000000000..45e46a0fb
--- /dev/null
+++ b/deps/openssl/openssl/apps/openssl-vms.cnf
@@ -0,0 +1,350 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME = .
+RANDFILE = $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file = $ENV::HOME/.oid
+oid_section = new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions =
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+# Policies used by the TSA examples.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
+####################################################################
+[ ca ]
+default_ca = CA_default # The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir = sys\$disk:[.demoCA # Where everything is kept
+certs = $dir.certs] # Where the issued certs are kept
+crl_dir = $dir.crl] # Where the issued crl are kept
+database = $dir]index.txt # database index file.
+#unique_subject = no # Set to 'no' to allow creation of
+ # several ctificates with same subject.
+new_certs_dir = $dir.newcerts] # default place for new certs.
+
+certificate = $dir]cacert.pem # The CA certificate
+serial = $dir]serial. # The current serial number
+crlnumber = $dir]crlnumber. # the current crl number
+ # must be commented out to leave a V1 CRL
+crl = $dir]crl.pem # The current CRL
+private_key = $dir.private]cakey.pem# The private key
+RANDFILE = $dir.private].rand # private random number file
+
+x509_extensions = usr_cert # The extentions to add to the cert
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt = ca_default # Subject Name options
+cert_opt = ca_default # Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions = crl_ext
+
+default_days = 365 # how long to certify for
+default_crl_days= 30 # how long before next CRL
+default_md = default # use public key default MD
+preserve = no # keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy = policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName = match
+stateOrProvinceName = match
+organizationName = match
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+####################################################################
+[ req ]
+default_bits = 1024
+default_keyfile = privkey.pem
+distinguished_name = req_distinguished_name
+attributes = req_attributes
+x509_extensions = v3_ca # The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options.
+# default: PrintableString, T61String, BMPString.
+# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
+string_mask = utf8only
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = AU
+countryName_min = 2
+countryName_max = 2
+
+stateOrProvinceName = State or Province Name (full name)
+stateOrProvinceName_default = Some-State
+
+localityName = Locality Name (eg, city)
+
+0.organizationName = Organization Name (eg, company)
+0.organizationName_default = Internet Widgits Pty Ltd
+
+# we can do this but it is not needed normally :-)
+#1.organizationName = Second Organization Name (eg, company)
+#1.organizationName_default = World Wide Web Pty Ltd
+
+organizationalUnitName = Organizational Unit Name (eg, section)
+#organizationalUnitName_default =
+
+commonName = Common Name (e.g. server FQDN or YOUR name)
+commonName_max = 64
+
+emailAddress = Email Address
+emailAddress_max = 64
+
+# SET-ex3 = SET extension number 3
+
+[ req_attributes ]
+challengePassword = A challenge password
+challengePassword_min = 4
+challengePassword_max = 20
+
+unstructuredName = An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This is required for TSA certificates.
+# extendedKeyUsage = critical,timeStamping
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+####################################################################
+[ tsa ]
+
+default_tsa = tsa_config1 # the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir = sys\$disk:[.demoCA # TSA root directory
+serial = $dir]tsaserial. # The current serial number (mandatory)
+crypto_device = builtin # OpenSSL engine to use for signing
+signer_cert = $dir/tsacert.pem # The TSA signing certificate
+ # (optional)
+certs = $dir.cacert.pem] # Certificate chain to include in reply
+ # (optional)
+signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
+
+default_policy = tsa_policy1 # Policy if request did not specify it
+ # (optional)
+other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
+digests = md5, sha1 # Acceptable message digests (mandatory)
+accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
+clock_precision_digits = 0 # number of digits after dot. (optional)
+ordering = yes # Is ordering defined for timestamps?
+ # (optional, default: no)
+tsa_name = yes # Must the TSA name be included in the reply?
+ # (optional, default: no)
+ess_cert_id_chain = no # Must the ESS cert id chain be included?
+ # (optional, default: no)
diff --git a/deps/openssl/openssl/apps/openssl.c b/deps/openssl/openssl/apps/openssl.c
new file mode 100644
index 000000000..1c880d90b
--- /dev/null
+++ b/deps/openssl/openssl/apps/openssl.c
@@ -0,0 +1,728 @@
+/* apps/openssl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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).
+ *
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#define OPENSSL_C /* tells apps.h to use complete apps_startup() */
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */
+#include "progs.h"
+#include "s_apps.h"
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
+/* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with the
+ * base prototypes (we cast each variable inside the function to the required
+ * type of "FUNCTION*"). This removes the necessity for macro-generated wrapper
+ * functions. */
+
+static LHASH_OF(FUNCTION) *prog_init(void );
+static int do_cmd(LHASH_OF(FUNCTION) *prog,int argc,char *argv[]);
+static void list_pkey(BIO *out);
+static void list_cipher(BIO *out);
+static void list_md(BIO *out);
+char *default_config_file=NULL;
+
+/* Make sure there is only one when MONOLITH is defined */
+#ifdef MONOLITH
+CONF *config=NULL;
+BIO *bio_err=NULL;
+#endif
+
+
+static void lock_dbg_cb(int mode, int type, const char *file, int line)
+ {
+ static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
+ const char *errstr = NULL;
+ int rw;
+
+ rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
+ if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
+ {
+ errstr = "invalid mode";
+ goto err;
+ }
+
+ if (type < 0 || type >= CRYPTO_NUM_LOCKS)
+ {
+ errstr = "type out of bounds";
+ goto err;
+ }
+
+ if (mode & CRYPTO_LOCK)
+ {
+ if (modes[type])
+ {
+ errstr = "already locked";
+ /* must not happen in a single-threaded program
+ * (would deadlock) */
+ goto err;
+ }
+
+ modes[type] = rw;
+ }
+ else if (mode & CRYPTO_UNLOCK)
+ {
+ if (!modes[type])
+ {
+ errstr = "not locked";
+ goto err;
+ }
+
+ if (modes[type] != rw)
+ {
+ errstr = (rw == CRYPTO_READ) ?
+ "CRYPTO_r_unlock on write lock" :
+ "CRYPTO_w_unlock on read lock";
+ }
+
+ modes[type] = 0;
+ }
+ else
+ {
+ errstr = "invalid mode";
+ goto err;
+ }
+
+ err:
+ if (errstr)
+ {
+ /* we cannot use bio_err here */
+ fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
+ errstr, mode, type, file, line);
+ }
+ }
+
+#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
+# define ARGV _Argv
+#else
+# define ARGV Argv
+#endif
+
+int main(int Argc, char *ARGV[])
+ {
+ ARGS arg;
+#define PROG_NAME_SIZE 39
+ char pname[PROG_NAME_SIZE+1];
+ FUNCTION f,*fp;
+ MS_STATIC const char *prompt;
+ MS_STATIC char buf[1024];
+ char *to_free=NULL;
+ int n,i,ret=0;
+ int argc;
+ char **argv,*p;
+ LHASH_OF(FUNCTION) *prog=NULL;
+ long errline;
+
+#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
+ /* 2011-03-22 SMS.
+ * If we have 32-bit pointers everywhere, then we're safe, and
+ * we bypass this mess, as on non-VMS systems. (See ARGV,
+ * above.)
+ * Problem 1: Compaq/HP C before V7.3 always used 32-bit
+ * pointers for argv[].
+ * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers
+ * everywhere else, we always allocate and use a 64-bit
+ * duplicate of argv[].
+ * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed
+ * to NULL-terminate a 64-bit argv[]. (As this was written, the
+ * compiler ECO was available only on IA64.)
+ * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a
+ * 64-bit argv[argc] for NULL, and, if necessary, use a
+ * (properly) NULL-terminated (64-bit) duplicate of argv[].
+ * The same code is used in either case to duplicate argv[].
+ * Some of these decisions could be handled in preprocessing,
+ * but the code tends to get even uglier, and the penalty for
+ * deciding at compile- or run-time is tiny.
+ */
+ char **Argv = NULL;
+ int free_Argv = 0;
+
+ if ((sizeof( _Argv) < 8) /* 32-bit argv[]. */
+# if !defined( VMS_TRUST_ARGV)
+ || (_Argv[ Argc] != NULL) /* Untrusted argv[argc] not NULL. */
+# endif
+ )
+ {
+ int i;
+ Argv = OPENSSL_malloc( (Argc+ 1)* sizeof( char *));
+ if (Argv == NULL)
+ { ret = -1; goto end; }
+ for(i = 0; i < Argc; i++)
+ Argv[i] = _Argv[i];
+ Argv[ Argc] = NULL; /* Certain NULL termination. */
+ free_Argv = 1;
+ }
+ else
+ {
+ /* Use the known-good 32-bit argv[] (which needs the
+ * type cast to satisfy the compiler), or the trusted or
+ * tested-good 64-bit argv[] as-is. */
+ Argv = (char **)_Argv;
+ }
+#endif /* defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) */
+
+ arg.data=NULL;
+ arg.count=0;
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compiled-in library defaults */
+ {
+ if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))
+ {
+ CRYPTO_malloc_debug_init();
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+ }
+ else
+ {
+ /* OPENSSL_DEBUG_MEMORY=off */
+ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+ }
+ }
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+#if 0
+ if (getenv("OPENSSL_DEBUG_LOCKING") != NULL)
+#endif
+ {
+ CRYPTO_set_locking_callback(lock_dbg_cb);
+ }
+
+ if(getenv("OPENSSL_FIPS")) {
+#ifdef OPENSSL_FIPS
+ if (!FIPS_mode_set(1)) {
+ ERR_load_crypto_strings();
+ ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
+ EXIT(1);
+ }
+#else
+ fprintf(stderr, "FIPS mode not supported.\n");
+ EXIT(1);
+#endif
+ }
+
+ apps_startup();
+
+ /* Lets load up our environment a little */
+ p=getenv("OPENSSL_CONF");
+ if (p == NULL)
+ p=getenv("SSLEAY_CONF");
+ if (p == NULL)
+ p=to_free=make_config_name();
+
+ default_config_file=p;
+
+ config=NCONF_new(NULL);
+ i=NCONF_load(config,p,&errline);
+ if (i == 0)
+ {
+ if (ERR_GET_REASON(ERR_peek_last_error())
+ == CONF_R_NO_SUCH_FILE)
+ {
+ BIO_printf(bio_err,
+ "WARNING: can't open config file: %s\n",p);
+ ERR_clear_error();
+ NCONF_free(config);
+ config = NULL;
+ }
+ else
+ {
+ ERR_print_errors(bio_err);
+ NCONF_free(config);
+ exit(1);
+ }
+ }
+
+ prog=prog_init();
+
+ /* first check the program name */
+ program_name(Argv[0],pname,sizeof pname);
+
+ f.name=pname;
+ fp=lh_FUNCTION_retrieve(prog,&f);
+ if (fp != NULL)
+ {
+ Argv[0]=pname;
+ ret=fp->func(Argc,Argv);
+ goto end;
+ }
+
+ /* ok, now check that there are not arguments, if there are,
+ * run with them, shifting the ssleay off the front */
+ if (Argc != 1)
+ {
+ Argc--;
+ Argv++;
+ ret=do_cmd(prog,Argc,Argv);
+ if (ret < 0) ret=0;
+ goto end;
+ }
+
+ /* ok, lets enter the old 'OpenSSL>' mode */
+
+ for (;;)
+ {
+ ret=0;
+ p=buf;
+ n=sizeof buf;
+ i=0;
+ for (;;)
+ {
+ p[0]='\0';
+ if (i++)
+ prompt=">";
+ else prompt="OpenSSL> ";
+ fputs(prompt,stdout);
+ fflush(stdout);
+ if (!fgets(p,n,stdin))
+ goto end;
+ if (p[0] == '\0') goto end;
+ i=strlen(p);
+ if (i <= 1) break;
+ if (p[i-2] != '\\') break;
+ i-=2;
+ p+=i;
+ n-=i;
+ }
+ if (!chopup_args(&arg,buf,&argc,&argv)) break;
+
+ ret=do_cmd(prog,argc,argv);
+ if (ret < 0)
+ {
+ ret=0;
+ goto end;
+ }
+ if (ret != 0)
+ BIO_printf(bio_err,"error in %s\n",argv[0]);
+ (void)BIO_flush(bio_err);
+ }
+ BIO_printf(bio_err,"bad exit\n");
+ ret=1;
+end:
+ if (to_free)
+ OPENSSL_free(to_free);
+ if (config != NULL)
+ {
+ NCONF_free(config);
+ config=NULL;
+ }
+ if (prog != NULL) lh_FUNCTION_free(prog);
+ if (arg.data != NULL) OPENSSL_free(arg.data);
+
+ apps_shutdown();
+
+ CRYPTO_mem_leaks(bio_err);
+ if (bio_err != NULL)
+ {
+ BIO_free(bio_err);
+ bio_err=NULL;
+ }
+#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
+ /* Free any duplicate Argv[] storage. */
+ if (free_Argv)
+ {
+ OPENSSL_free(Argv);
+ }
+#endif
+ OPENSSL_EXIT(ret);
+ }
+
+#define LIST_STANDARD_COMMANDS "list-standard-commands"
+#define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands"
+#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms"
+#define LIST_CIPHER_COMMANDS "list-cipher-commands"
+#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms"
+#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms"
+
+
+static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
+ {
+ FUNCTION f,*fp;
+ int i,ret=1,tp,nl;
+
+ if ((argc <= 0) || (argv[0] == NULL))
+ { ret=0; goto end; }
+ f.name=argv[0];
+ fp=lh_FUNCTION_retrieve(prog,&f);
+ if (fp == NULL)
+ {
+ if (EVP_get_digestbyname(argv[0]))
+ {
+ f.type = FUNC_TYPE_MD;
+ f.func = dgst_main;
+ fp = &f;
+ }
+ else if (EVP_get_cipherbyname(argv[0]))
+ {
+ f.type = FUNC_TYPE_CIPHER;
+ f.func = enc_main;
+ fp = &f;
+ }
+ }
+ if (fp != NULL)
+ {
+ ret=fp->func(argc,argv);
+ }
+ else if ((strncmp(argv[0],"no-",3)) == 0)
+ {
+ BIO *bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ bio_stdout = BIO_push(tmpbio, bio_stdout);
+ }
+#endif
+ f.name=argv[0]+3;
+ ret = (lh_FUNCTION_retrieve(prog,&f) != NULL);
+ if (!ret)
+ BIO_printf(bio_stdout, "%s\n", argv[0]);
+ else
+ BIO_printf(bio_stdout, "%s\n", argv[0]+3);
+ BIO_free_all(bio_stdout);
+ goto end;
+ }
+ else if ((strcmp(argv[0],"quit") == 0) ||
+ (strcmp(argv[0],"q") == 0) ||
+ (strcmp(argv[0],"exit") == 0) ||
+ (strcmp(argv[0],"bye") == 0))
+ {
+ ret= -1;
+ goto end;
+ }
+ else if ((strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) ||
+ (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) ||
+ (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) ||
+ (strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0) ||
+ (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0) ||
+ (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0))
+ {
+ int list_type;
+ BIO *bio_stdout;
+
+ if (strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0)
+ list_type = FUNC_TYPE_GENERAL;
+ else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0)
+ list_type = FUNC_TYPE_MD;
+ else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0)
+ list_type = FUNC_TYPE_MD_ALG;
+ else if (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0)
+ list_type = FUNC_TYPE_PKEY;
+ else if (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0)
+ list_type = FUNC_TYPE_CIPHER_ALG;
+ else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
+ list_type = FUNC_TYPE_CIPHER;
+ bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ bio_stdout = BIO_push(tmpbio, bio_stdout);
+ }
+#endif
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ if (list_type == FUNC_TYPE_PKEY)
+ list_pkey(bio_stdout);
+ if (list_type == FUNC_TYPE_MD_ALG)
+ list_md(bio_stdout);
+ if (list_type == FUNC_TYPE_CIPHER_ALG)
+ list_cipher(bio_stdout);
+ else
+ {
+ for (fp=functions; fp->name != NULL; fp++)
+ if (fp->type == list_type)
+ BIO_printf(bio_stdout, "%s\n",
+ fp->name);
+ }
+ BIO_free_all(bio_stdout);
+ ret=0;
+ goto end;
+ }
+ else
+ {
+ BIO_printf(bio_err,"openssl:Error: '%s' is an invalid command.\n",
+ argv[0]);
+ BIO_printf(bio_err, "\nStandard commands");
+ i=0;
+ tp=0;
+ for (fp=functions; fp->name != NULL; fp++)
+ {
+ nl=0;
+#ifdef OPENSSL_NO_CAMELLIA
+ if (((i++) % 5) == 0)
+#else
+ if (((i++) % 4) == 0)
+#endif
+ {
+ BIO_printf(bio_err,"\n");
+ nl=1;
+ }
+ if (fp->type != tp)
+ {
+ tp=fp->type;
+ if (!nl) BIO_printf(bio_err,"\n");
+ if (tp == FUNC_TYPE_MD)
+ {
+ i=1;
+ BIO_printf(bio_err,
+ "\nMessage Digest commands (see the `dgst' command for more details)\n");
+ }
+ else if (tp == FUNC_TYPE_CIPHER)
+ {
+ i=1;
+ BIO_printf(bio_err,"\nCipher commands (see the `enc' command for more details)\n");
+ }
+ }
+#ifdef OPENSSL_NO_CAMELLIA
+ BIO_printf(bio_err,"%-15s",fp->name);
+#else
+ BIO_printf(bio_err,"%-18s",fp->name);
+#endif
+ }
+ BIO_printf(bio_err,"\n\n");
+ ret=0;
+ }
+end:
+ return(ret);
+ }
+
+static int SortFnByName(const void *_f1,const void *_f2)
+ {
+ const FUNCTION *f1=_f1;
+ const FUNCTION *f2=_f2;
+
+ if(f1->type != f2->type)
+ return f1->type-f2->type;
+ return strcmp(f1->name,f2->name);
+ }
+
+static void list_pkey(BIO *out)
+ {
+ int i;
+ for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
+ {
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ int pkey_id, pkey_base_id, pkey_flags;
+ const char *pinfo, *pem_str;
+ ameth = EVP_PKEY_asn1_get0(i);
+ EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
+ &pinfo, &pem_str, ameth);
+ if (pkey_flags & ASN1_PKEY_ALIAS)
+ {
+ BIO_printf(out, "Name: %s\n",
+ OBJ_nid2ln(pkey_id));
+ BIO_printf(out, "\tType: Alias to %s\n",
+ OBJ_nid2ln(pkey_base_id));
+ }
+ else
+ {
+ BIO_printf(out, "Name: %s\n", pinfo);
+ BIO_printf(out, "\tType: %s Algorithm\n",
+ pkey_flags & ASN1_PKEY_DYNAMIC ?
+ "External" : "Builtin");
+ BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
+ if (pem_str == NULL)
+ pem_str = "(none)";
+ BIO_printf(out, "\tPEM string: %s\n", pem_str);
+ }
+
+ }
+ }
+
+static void list_cipher_fn(const EVP_CIPHER *c,
+ const char *from, const char *to, void *arg)
+ {
+ if (c)
+ BIO_printf(arg, "%s\n", EVP_CIPHER_name(c));
+ else
+ {
+ if (!from)
+ from = "<undefined>";
+ if (!to)
+ to = "<undefined>";
+ BIO_printf(arg, "%s => %s\n", from, to);
+ }
+ }
+
+static void list_cipher(BIO *out)
+ {
+ EVP_CIPHER_do_all_sorted(list_cipher_fn, out);
+ }
+
+static void list_md_fn(const EVP_MD *m,
+ const char *from, const char *to, void *arg)
+ {
+ if (m)
+ BIO_printf(arg, "%s\n", EVP_MD_name(m));
+ else
+ {
+ if (!from)
+ from = "<undefined>";
+ if (!to)
+ to = "<undefined>";
+ BIO_printf(arg, "%s => %s\n", from, to);
+ }
+ }
+
+static void list_md(BIO *out)
+ {
+ EVP_MD_do_all_sorted(list_md_fn, out);
+ }
+
+static int MS_CALLBACK function_cmp(const FUNCTION *a, const FUNCTION *b)
+ {
+ return strncmp(a->name,b->name,8);
+ }
+static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION)
+
+static unsigned long MS_CALLBACK function_hash(const FUNCTION *a)
+ {
+ return lh_strhash(a->name);
+ }
+static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION)
+
+static LHASH_OF(FUNCTION) *prog_init(void)
+ {
+ LHASH_OF(FUNCTION) *ret;
+ FUNCTION *f;
+ size_t i;
+
+ /* Purely so it looks nice when the user hits ? */
+ for(i=0,f=functions ; f->name != NULL ; ++f,++i)
+ ;
+ qsort(functions,i,sizeof *functions,SortFnByName);
+
+ if ((ret=lh_FUNCTION_new()) == NULL)
+ return(NULL);
+
+ for (f=functions; f->name != NULL; f++)
+ (void)lh_FUNCTION_insert(ret,f);
+ return(ret);
+ }
+
diff --git a/deps/openssl/openssl/apps/openssl.cnf b/deps/openssl/openssl/apps/openssl.cnf
new file mode 100644
index 000000000..18760c6e6
--- /dev/null
+++ b/deps/openssl/openssl/apps/openssl.cnf
@@ -0,0 +1,350 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME = .
+RANDFILE = $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file = $ENV::HOME/.oid
+oid_section = new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions =
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+# Policies used by the TSA examples.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
+####################################################################
+[ ca ]
+default_ca = CA_default # The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir = ./demoCA # Where everything is kept
+certs = $dir/certs # Where the issued certs are kept
+crl_dir = $dir/crl # Where the issued crl are kept
+database = $dir/index.txt # database index file.
+#unique_subject = no # Set to 'no' to allow creation of
+ # several ctificates with same subject.
+new_certs_dir = $dir/newcerts # default place for new certs.
+
+certificate = $dir/cacert.pem # The CA certificate
+serial = $dir/serial # The current serial number
+crlnumber = $dir/crlnumber # the current crl number
+ # must be commented out to leave a V1 CRL
+crl = $dir/crl.pem # The current CRL
+private_key = $dir/private/cakey.pem# The private key
+RANDFILE = $dir/private/.rand # private random number file
+
+x509_extensions = usr_cert # The extentions to add to the cert
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt = ca_default # Subject Name options
+cert_opt = ca_default # Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions = crl_ext
+
+default_days = 365 # how long to certify for
+default_crl_days= 30 # how long before next CRL
+default_md = default # use public key default MD
+preserve = no # keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy = policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName = match
+stateOrProvinceName = match
+organizationName = match
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+####################################################################
+[ req ]
+default_bits = 1024
+default_keyfile = privkey.pem
+distinguished_name = req_distinguished_name
+attributes = req_attributes
+x509_extensions = v3_ca # The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options.
+# default: PrintableString, T61String, BMPString.
+# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
+string_mask = utf8only
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = AU
+countryName_min = 2
+countryName_max = 2
+
+stateOrProvinceName = State or Province Name (full name)
+stateOrProvinceName_default = Some-State
+
+localityName = Locality Name (eg, city)
+
+0.organizationName = Organization Name (eg, company)
+0.organizationName_default = Internet Widgits Pty Ltd
+
+# we can do this but it is not needed normally :-)
+#1.organizationName = Second Organization Name (eg, company)
+#1.organizationName_default = World Wide Web Pty Ltd
+
+organizationalUnitName = Organizational Unit Name (eg, section)
+#organizationalUnitName_default =
+
+commonName = Common Name (e.g. server FQDN or YOUR name)
+commonName_max = 64
+
+emailAddress = Email Address
+emailAddress_max = 64
+
+# SET-ex3 = SET extension number 3
+
+[ req_attributes ]
+challengePassword = A challenge password
+challengePassword_min = 4
+challengePassword_max = 20
+
+unstructuredName = An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This is required for TSA certificates.
+# extendedKeyUsage = critical,timeStamping
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+####################################################################
+[ tsa ]
+
+default_tsa = tsa_config1 # the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir = ./demoCA # TSA root directory
+serial = $dir/tsaserial # The current serial number (mandatory)
+crypto_device = builtin # OpenSSL engine to use for signing
+signer_cert = $dir/tsacert.pem # The TSA signing certificate
+ # (optional)
+certs = $dir/cacert.pem # Certificate chain to include in reply
+ # (optional)
+signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
+
+default_policy = tsa_policy1 # Policy if request did not specify it
+ # (optional)
+other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
+digests = md5, sha1 # Acceptable message digests (mandatory)
+accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
+clock_precision_digits = 0 # number of digits after dot. (optional)
+ordering = yes # Is ordering defined for timestamps?
+ # (optional, default: no)
+tsa_name = yes # Must the TSA name be included in the reply?
+ # (optional, default: no)
+ess_cert_id_chain = no # Must the ESS cert id chain be included?
+ # (optional, default: no)
diff --git a/deps/openssl/openssl/apps/passwd.c b/deps/openssl/openssl/apps/passwd.c
new file mode 100644
index 000000000..9ca25dd1d
--- /dev/null
+++ b/deps/openssl/openssl/apps/passwd.c
@@ -0,0 +1,512 @@
+/* apps/passwd.c */
+
+#if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC
+# define NO_MD5CRYPT_1
+#endif
+
+#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
+
+#include <assert.h>
+#include <string.h>
+
+#include "apps.h"
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_DES
+# include <openssl/des.h>
+#endif
+#ifndef NO_MD5CRYPT_1
+# include <openssl/md5.h>
+#endif
+
+
+#undef PROG
+#define PROG passwd_main
+
+
+static unsigned const char cov_2char[64]={
+ /* from crypto/des/fcrypt.c */
+ 0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
+ 0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
+ 0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
+ 0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
+ 0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
+ 0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
+ 0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
+ 0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
+};
+
+static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
+ char *passwd, BIO *out, int quiet, int table, int reverse,
+ size_t pw_maxlen, int usecrypt, int use1, int useapr1);
+
+/* -crypt - standard Unix password algorithm (default)
+ * -1 - MD5-based password algorithm
+ * -apr1 - MD5-based password algorithm, Apache variant
+ * -salt string - salt
+ * -in file - read passwords from file
+ * -stdin - read passwords from stdin
+ * -noverify - never verify when reading password from terminal
+ * -quiet - no warnings
+ * -table - format output as table
+ * -reverse - switch table columns
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ int ret = 1;
+ char *infile = NULL;
+ int in_stdin = 0;
+ int in_noverify = 0;
+ char *salt = NULL, *passwd = NULL, **passwds = NULL;
+ char *salt_malloc = NULL, *passwd_malloc = NULL;
+ size_t passwd_malloc_size = 0;
+ int pw_source_defined = 0;
+ BIO *in = NULL, *out = NULL;
+ int i, badopt, opt_done;
+ int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
+ int usecrypt = 0, use1 = 0, useapr1 = 0;
+ size_t pw_maxlen = 0;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto err;
+ out = BIO_new(BIO_s_file());
+ if (out == NULL)
+ goto err;
+ BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+
+ badopt = 0, opt_done = 0;
+ i = 0;
+ while (!badopt && !opt_done && argv[++i] != NULL)
+ {
+ if (strcmp(argv[i], "-crypt") == 0)
+ usecrypt = 1;
+ else if (strcmp(argv[i], "-1") == 0)
+ use1 = 1;
+ else if (strcmp(argv[i], "-apr1") == 0)
+ useapr1 = 1;
+ else if (strcmp(argv[i], "-salt") == 0)
+ {
+ if ((argv[i+1] != NULL) && (salt == NULL))
+ {
+ passed_salt = 1;
+ salt = argv[++i];
+ }
+ else
+ badopt = 1;
+ }
+ else if (strcmp(argv[i], "-in") == 0)
+ {
+ if ((argv[i+1] != NULL) && !pw_source_defined)
+ {
+ pw_source_defined = 1;
+ infile = argv[++i];
+ }
+ else
+ badopt = 1;
+ }
+ else if (strcmp(argv[i], "-stdin") == 0)
+ {
+ if (!pw_source_defined)
+ {
+ pw_source_defined = 1;
+ in_stdin = 1;
+ }
+ else
+ badopt = 1;
+ }
+ else if (strcmp(argv[i], "-noverify") == 0)
+ in_noverify = 1;
+ else if (strcmp(argv[i], "-quiet") == 0)
+ quiet = 1;
+ else if (strcmp(argv[i], "-table") == 0)
+ table = 1;
+ else if (strcmp(argv[i], "-reverse") == 0)
+ reverse = 1;
+ else if (argv[i][0] == '-')
+ badopt = 1;
+ else if (!pw_source_defined)
+ /* non-option arguments, use as passwords */
+ {
+ pw_source_defined = 1;
+ passwds = &argv[i];
+ opt_done = 1;
+ }
+ else
+ badopt = 1;
+ }
+
+ if (!usecrypt && !use1 && !useapr1) /* use default */
+ usecrypt = 1;
+ if (usecrypt + use1 + useapr1 > 1) /* conflict */
+ badopt = 1;
+
+ /* reject unsupported algorithms */
+#ifdef OPENSSL_NO_DES
+ if (usecrypt) badopt = 1;
+#endif
+#ifdef NO_MD5CRYPT_1
+ if (use1 || useapr1) badopt = 1;
+#endif
+
+ if (badopt)
+ {
+ BIO_printf(bio_err, "Usage: passwd [options] [passwords]\n");
+ BIO_printf(bio_err, "where options are\n");
+#ifndef OPENSSL_NO_DES
+ BIO_printf(bio_err, "-crypt standard Unix password algorithm (default)\n");
+#endif
+#ifndef NO_MD5CRYPT_1
+ BIO_printf(bio_err, "-1 MD5-based password algorithm\n");
+ BIO_printf(bio_err, "-apr1 MD5-based password algorithm, Apache variant\n");
+#endif
+ BIO_printf(bio_err, "-salt string use provided salt\n");
+ BIO_printf(bio_err, "-in file read passwords from file\n");
+ BIO_printf(bio_err, "-stdin read passwords from stdin\n");
+ BIO_printf(bio_err, "-noverify never verify when reading password from terminal\n");
+ BIO_printf(bio_err, "-quiet no warnings\n");
+ BIO_printf(bio_err, "-table format output as table\n");
+ BIO_printf(bio_err, "-reverse switch table columns\n");
+
+ goto err;
+ }
+
+ if ((infile != NULL) || in_stdin)
+ {
+ in = BIO_new(BIO_s_file());
+ if (in == NULL)
+ goto err;
+ if (infile != NULL)
+ {
+ assert(in_stdin == 0);
+ if (BIO_read_filename(in, infile) <= 0)
+ goto err;
+ }
+ else
+ {
+ assert(in_stdin);
+ BIO_set_fp(in, stdin, BIO_NOCLOSE);
+ }
+ }
+
+ if (usecrypt)
+ pw_maxlen = 8;
+ else if (use1 || useapr1)
+ pw_maxlen = 256; /* arbitrary limit, should be enough for most passwords */
+
+ if (passwds == NULL)
+ {
+ /* no passwords on the command line */
+
+ passwd_malloc_size = pw_maxlen + 2;
+ /* longer than necessary so that we can warn about truncation */
+ passwd = passwd_malloc = OPENSSL_malloc(passwd_malloc_size);
+ if (passwd_malloc == NULL)
+ goto err;
+ }
+
+ if ((in == NULL) && (passwds == NULL))
+ {
+ /* build a null-terminated list */
+ static char *passwds_static[2] = {NULL, NULL};
+
+ passwds = passwds_static;
+ if (in == NULL)
+ if (EVP_read_pw_string(passwd_malloc, passwd_malloc_size, "Password: ", !(passed_salt || in_noverify)) != 0)
+ goto err;
+ passwds[0] = passwd_malloc;
+ }
+
+ if (in == NULL)
+ {
+ assert(passwds != NULL);
+ assert(*passwds != NULL);
+
+ do /* loop over list of passwords */
+ {
+ passwd = *passwds++;
+ if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
+ quiet, table, reverse, pw_maxlen, usecrypt, use1, useapr1))
+ goto err;
+ }
+ while (*passwds != NULL);
+ }
+ else
+ /* in != NULL */
+ {
+ int done;
+
+ assert (passwd != NULL);
+ do
+ {
+ int r = BIO_gets(in, passwd, pw_maxlen + 1);
+ if (r > 0)
+ {
+ char *c = (strchr(passwd, '\n')) ;
+ if (c != NULL)
+ *c = 0; /* truncate at newline */
+ else
+ {
+ /* ignore rest of line */
+ char trash[BUFSIZ];
+ do
+ r = BIO_gets(in, trash, sizeof trash);
+ while ((r > 0) && (!strchr(trash, '\n')));
+ }
+
+ if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
+ quiet, table, reverse, pw_maxlen, usecrypt, use1, useapr1))
+ goto err;
+ }
+ done = (r <= 0);
+ }
+ while (!done);
+ }
+ ret = 0;
+
+err:
+ ERR_print_errors(bio_err);
+ if (salt_malloc)
+ OPENSSL_free(salt_malloc);
+ if (passwd_malloc)
+ OPENSSL_free(passwd_malloc);
+ if (in)
+ BIO_free(in);
+ if (out)
+ BIO_free_all(out);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+
+#ifndef NO_MD5CRYPT_1
+/* MD5-based password algorithm (should probably be available as a library
+ * function; then the static buffer would not be acceptable).
+ * For magic string "1", this should be compatible to the MD5-based BSD
+ * password algorithm.
+ * For 'magic' string "apr1", this is compatible to the MD5-based Apache
+ * password algorithm.
+ * (Apparently, the Apache password algorithm is identical except that the
+ * 'magic' string was changed -- the laziest application of the NIH principle
+ * I've ever encountered.)
+ */
+static char *md5crypt(const char *passwd, const char *magic, const char *salt)
+ {
+ static char out_buf[6 + 9 + 24 + 2]; /* "$apr1$..salt..$.......md5hash..........\0" */
+ unsigned char buf[MD5_DIGEST_LENGTH];
+ char *salt_out;
+ int n;
+ unsigned int i;
+ EVP_MD_CTX md,md2;
+ size_t passwd_len, salt_len;
+
+ passwd_len = strlen(passwd);
+ out_buf[0] = '$';
+ out_buf[1] = 0;
+ assert(strlen(magic) <= 4); /* "1" or "apr1" */
+ strncat(out_buf, magic, 4);
+ strncat(out_buf, "$", 1);
+ strncat(out_buf, salt, 8);
+ assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
+ salt_out = out_buf + 2 + strlen(magic);
+ salt_len = strlen(salt_out);
+ assert(salt_len <= 8);
+
+ EVP_MD_CTX_init(&md);
+ EVP_DigestInit_ex(&md,EVP_md5(), NULL);
+ EVP_DigestUpdate(&md, passwd, passwd_len);
+ EVP_DigestUpdate(&md, "$", 1);
+ EVP_DigestUpdate(&md, magic, strlen(magic));
+ EVP_DigestUpdate(&md, "$", 1);
+ EVP_DigestUpdate(&md, salt_out, salt_len);
+
+ EVP_MD_CTX_init(&md2);
+ EVP_DigestInit_ex(&md2,EVP_md5(), NULL);
+ EVP_DigestUpdate(&md2, passwd, passwd_len);
+ EVP_DigestUpdate(&md2, salt_out, salt_len);
+ EVP_DigestUpdate(&md2, passwd, passwd_len);
+ EVP_DigestFinal_ex(&md2, buf, NULL);
+
+ for (i = passwd_len; i > sizeof buf; i -= sizeof buf)
+ EVP_DigestUpdate(&md, buf, sizeof buf);
+ EVP_DigestUpdate(&md, buf, i);
+
+ n = passwd_len;
+ while (n)
+ {
+ EVP_DigestUpdate(&md, (n & 1) ? "\0" : passwd, 1);
+ n >>= 1;
+ }
+ EVP_DigestFinal_ex(&md, buf, NULL);
+
+ for (i = 0; i < 1000; i++)
+ {
+ EVP_DigestInit_ex(&md2,EVP_md5(), NULL);
+ EVP_DigestUpdate(&md2, (i & 1) ? (unsigned const char *) passwd : buf,
+ (i & 1) ? passwd_len : sizeof buf);
+ if (i % 3)
+ EVP_DigestUpdate(&md2, salt_out, salt_len);
+ if (i % 7)
+ EVP_DigestUpdate(&md2, passwd, passwd_len);
+ EVP_DigestUpdate(&md2, (i & 1) ? buf : (unsigned const char *) passwd,
+ (i & 1) ? sizeof buf : passwd_len);
+ EVP_DigestFinal_ex(&md2, buf, NULL);
+ }
+ EVP_MD_CTX_cleanup(&md2);
+
+ {
+ /* transform buf into output string */
+
+ unsigned char buf_perm[sizeof buf];
+ int dest, source;
+ char *output;
+
+ /* silly output permutation */
+ for (dest = 0, source = 0; dest < 14; dest++, source = (source + 6) % 17)
+ buf_perm[dest] = buf[source];
+ buf_perm[14] = buf[5];
+ buf_perm[15] = buf[11];
+#ifndef PEDANTIC /* Unfortunately, this generates a "no effect" warning */
+ assert(16 == sizeof buf_perm);
+#endif
+
+ output = salt_out + salt_len;
+ assert(output == out_buf + strlen(out_buf));
+
+ *output++ = '$';
+
+ for (i = 0; i < 15; i += 3)
+ {
+ *output++ = cov_2char[buf_perm[i+2] & 0x3f];
+ *output++ = cov_2char[((buf_perm[i+1] & 0xf) << 2) |
+ (buf_perm[i+2] >> 6)];
+ *output++ = cov_2char[((buf_perm[i] & 3) << 4) |
+ (buf_perm[i+1] >> 4)];
+ *output++ = cov_2char[buf_perm[i] >> 2];
+ }
+ assert(i == 15);
+ *output++ = cov_2char[buf_perm[i] & 0x3f];
+ *output++ = cov_2char[buf_perm[i] >> 6];
+ *output = 0;
+ assert(strlen(out_buf) < sizeof(out_buf));
+ }
+ EVP_MD_CTX_cleanup(&md);
+
+ return out_buf;
+ }
+#endif
+
+
+static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
+ char *passwd, BIO *out, int quiet, int table, int reverse,
+ size_t pw_maxlen, int usecrypt, int use1, int useapr1)
+ {
+ char *hash = NULL;
+
+ assert(salt_p != NULL);
+ assert(salt_malloc_p != NULL);
+
+ /* first make sure we have a salt */
+ if (!passed_salt)
+ {
+#ifndef OPENSSL_NO_DES
+ if (usecrypt)
+ {
+ if (*salt_malloc_p == NULL)
+ {
+ *salt_p = *salt_malloc_p = OPENSSL_malloc(3);
+ if (*salt_malloc_p == NULL)
+ goto err;
+ }
+ if (RAND_pseudo_bytes((unsigned char *)*salt_p, 2) < 0)
+ goto err;
+ (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
+ (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
+ (*salt_p)[2] = 0;
+#ifdef CHARSET_EBCDIC
+ ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert
+ * back to ASCII */
+#endif
+ }
+#endif /* !OPENSSL_NO_DES */
+
+#ifndef NO_MD5CRYPT_1
+ if (use1 || useapr1)
+ {
+ int i;
+
+ if (*salt_malloc_p == NULL)
+ {
+ *salt_p = *salt_malloc_p = OPENSSL_malloc(9);
+ if (*salt_malloc_p == NULL)
+ goto err;
+ }
+ if (RAND_pseudo_bytes((unsigned char *)*salt_p, 8) < 0)
+ goto err;
+
+ for (i = 0; i < 8; i++)
+ (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
+ (*salt_p)[8] = 0;
+ }
+#endif /* !NO_MD5CRYPT_1 */
+ }
+
+ assert(*salt_p != NULL);
+
+ /* truncate password if necessary */
+ if ((strlen(passwd) > pw_maxlen))
+ {
+ if (!quiet)
+ /* XXX: really we should know how to print a size_t, not cast it */
+ BIO_printf(bio_err, "Warning: truncating password to %u characters\n", (unsigned)pw_maxlen);
+ passwd[pw_maxlen] = 0;
+ }
+ assert(strlen(passwd) <= pw_maxlen);
+
+ /* now compute password hash */
+#ifndef OPENSSL_NO_DES
+ if (usecrypt)
+ hash = DES_crypt(passwd, *salt_p);
+#endif
+#ifndef NO_MD5CRYPT_1
+ if (use1 || useapr1)
+ hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p);
+#endif
+ assert(hash != NULL);
+
+ if (table && !reverse)
+ BIO_printf(out, "%s\t%s\n", passwd, hash);
+ else if (table && reverse)
+ BIO_printf(out, "%s\t%s\n", hash, passwd);
+ else
+ BIO_printf(out, "%s\n", hash);
+ return 1;
+
+err:
+ return 0;
+ }
+#else
+
+int MAIN(int argc, char **argv)
+ {
+ fputs("Program not available.\n", stderr)
+ OPENSSL_EXIT(1);
+ }
+#endif
diff --git a/deps/openssl/openssl/apps/pca-cert.srl b/deps/openssl/openssl/apps/pca-cert.srl
new file mode 100644
index 000000000..2c7456e3e
--- /dev/null
+++ b/deps/openssl/openssl/apps/pca-cert.srl
@@ -0,0 +1 @@
+07
diff --git a/deps/openssl/openssl/apps/pca-key.pem b/deps/openssl/openssl/apps/pca-key.pem
new file mode 100644
index 000000000..20029ab77
--- /dev/null
+++ b/deps/openssl/openssl/apps/pca-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg
+wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ
+vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB
+AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc
+z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz
+xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7
+HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD
+yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS
+xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj
+7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG
+h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL
+QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q
+hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc=
+-----END RSA PRIVATE KEY-----
diff --git a/deps/openssl/openssl/apps/pca-req.pem b/deps/openssl/openssl/apps/pca-req.pem
new file mode 100644
index 000000000..33f155337
--- /dev/null
+++ b/deps/openssl/openssl/apps/pca-req.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBmjCCAQMCAQAwXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx
+GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAo
+MTAyNCBiaXQpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdoWk/3+WcMlfj
+Irkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPgwgsabJ/wn8TxA1yy3eKJbFl3OiUX
+MRsp22Jp85PmemiDzyUIStwk72qhp1imbANZvlmlCFKiQrjUyuDfu4TABmn+kkt3
+vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAEzz
+IG8NnfpnPTQSCN5zJhOfy6p9AcDyQzuJirYv1HR/qoYWalPh/U2uiK0lAim7qMcv
+wOlK3I7A8B7/4dLqvIqgtUj9b1WT8zIrnwdvJI4osLI2BY+c1pVlp174DHLMol1L
+Cl1e3N5BTm7lCitTYjuUhsw6hiA8IcdNKDo6sktV
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/openssl/openssl/apps/pkcs12.c b/deps/openssl/openssl/apps/pkcs12.c
new file mode 100644
index 000000000..b54c6f84a
--- /dev/null
+++ b/deps/openssl/openssl/apps/pkcs12.c
@@ -0,0 +1,977 @@
+/* pkcs12.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 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
+ * licensing@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).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+
+#define PROG pkcs12_main
+
+const EVP_CIPHER *enc;
+
+
+#define NOKEYS 0x1
+#define NOCERTS 0x2
+#define INFO 0x4
+#define CLCERTS 0x8
+#define CACERTS 0x10
+
+int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain);
+int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass);
+int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass,
+ int passlen, int options, char *pempass);
+int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass);
+int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name);
+void hex_prin(BIO *out, unsigned char *buf, int len);
+int alg_print(BIO *x, X509_ALGOR *alg);
+int cert_load(BIO *in, STACK_OF(X509) *sk);
+static int set_pbe(BIO *err, int *ppbe, const char *str);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+{
+ ENGINE *e = NULL;
+ char *infile=NULL, *outfile=NULL, *keyname = NULL;
+ char *certfile=NULL;
+ BIO *in=NULL, *out = NULL;
+ char **args;
+ char *name = NULL;
+ char *csp_name = NULL;
+ int add_lmk = 0;
+ PKCS12 *p12 = NULL;
+ char pass[50], macpass[50];
+ int export_cert = 0;
+ int options = 0;
+ int chain = 0;
+ int badarg = 0;
+ int iter = PKCS12_DEFAULT_ITER;
+ int maciter = PKCS12_DEFAULT_ITER;
+ int twopass = 0;
+ int keytype = 0;
+ int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
+ int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+ int ret = 1;
+ int macver = 1;
+ int noprompt = 0;
+ STACK_OF(OPENSSL_STRING) *canames = NULL;
+ char *cpass = NULL, *mpass = NULL;
+ char *passargin = NULL, *passargout = NULL, *passarg = NULL;
+ char *passin = NULL, *passout = NULL;
+ char *inrand = NULL;
+ char *macalg = NULL;
+ char *CApath = NULL, *CAfile = NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+
+ apps_startup();
+
+ enc = EVP_des_ede3_cbc();
+ if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ args = argv + 1;
+
+
+ while (*args) {
+ if (*args[0] == '-') {
+ if (!strcmp (*args, "-nokeys")) options |= NOKEYS;
+ else if (!strcmp (*args, "-keyex")) keytype = KEY_EX;
+ else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG;
+ else if (!strcmp (*args, "-nocerts")) options |= NOCERTS;
+ else if (!strcmp (*args, "-clcerts")) options |= CLCERTS;
+ else if (!strcmp (*args, "-cacerts")) options |= CACERTS;
+ else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS);
+ else if (!strcmp (*args, "-info")) options |= INFO;
+ else if (!strcmp (*args, "-chain")) chain = 1;
+ else if (!strcmp (*args, "-twopass")) twopass = 1;
+ else if (!strcmp (*args, "-nomacver")) macver = 0;
+ else if (!strcmp (*args, "-descert"))
+ cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+ else if (!strcmp (*args, "-export")) export_cert = 1;
+ else if (!strcmp (*args, "-des")) enc=EVP_des_cbc();
+ else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
+#ifndef OPENSSL_NO_IDEA
+ else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
+#endif
+#ifndef OPENSSL_NO_SEED
+ else if (!strcmp(*args, "-seed")) enc=EVP_seed_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+ else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
+ else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
+ else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ else if (!strcmp(*args,"-camellia128")) enc=EVP_camellia_128_cbc();
+ else if (!strcmp(*args,"-camellia192")) enc=EVP_camellia_192_cbc();
+ else if (!strcmp(*args,"-camellia256")) enc=EVP_camellia_256_cbc();
+#endif
+ else if (!strcmp (*args, "-noiter")) iter = 1;
+ else if (!strcmp (*args, "-maciter"))
+ maciter = PKCS12_DEFAULT_ITER;
+ else if (!strcmp (*args, "-nomaciter"))
+ maciter = 1;
+ else if (!strcmp (*args, "-nomac"))
+ maciter = -1;
+ else if (!strcmp (*args, "-macalg"))
+ if (args[1]) {
+ args++;
+ macalg = *args;
+ } else badarg = 1;
+ else if (!strcmp (*args, "-nodes")) enc=NULL;
+ else if (!strcmp (*args, "-certpbe")) {
+ if (!set_pbe(bio_err, &cert_pbe, *++args))
+ badarg = 1;
+ } else if (!strcmp (*args, "-keypbe")) {
+ if (!set_pbe(bio_err, &key_pbe, *++args))
+ badarg = 1;
+ } else if (!strcmp (*args, "-rand")) {
+ if (args[1]) {
+ args++;
+ inrand = *args;
+ } else badarg = 1;
+ } else if (!strcmp (*args, "-inkey")) {
+ if (args[1]) {
+ args++;
+ keyname = *args;
+ } else badarg = 1;
+ } else if (!strcmp (*args, "-certfile")) {
+ if (args[1]) {
+ args++;
+ certfile = *args;
+ } else badarg = 1;
+ } else if (!strcmp (*args, "-name")) {
+ if (args[1]) {
+ args++;
+ name = *args;
+ } else badarg = 1;
+ } else if (!strcmp (*args, "-LMK"))
+ add_lmk = 1;
+ else if (!strcmp (*args, "-CSP")) {
+ if (args[1]) {
+ args++;
+ csp_name = *args;
+ } else badarg = 1;
+ } else if (!strcmp (*args, "-caname")) {
+ if (args[1]) {
+ args++;
+ if (!canames) canames = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(canames, *args);
+ } else badarg = 1;
+ } else if (!strcmp (*args, "-in")) {
+ if (args[1]) {
+ args++;
+ infile = *args;
+ } else badarg = 1;
+ } else if (!strcmp (*args, "-out")) {
+ if (args[1]) {
+ args++;
+ outfile = *args;
+ } else badarg = 1;
+ } else if (!strcmp(*args,"-passin")) {
+ if (args[1]) {
+ args++;
+ passargin = *args;
+ } else badarg = 1;
+ } else if (!strcmp(*args,"-passout")) {
+ if (args[1]) {
+ args++;
+ passargout = *args;
+ } else badarg = 1;
+ } else if (!strcmp (*args, "-password")) {
+ if (args[1]) {
+ args++;
+ passarg = *args;
+ noprompt = 1;
+ } else badarg = 1;
+ } else if (!strcmp(*args,"-CApath")) {
+ if (args[1]) {
+ args++;
+ CApath = *args;
+ } else badarg = 1;
+ } else if (!strcmp(*args,"-CAfile")) {
+ if (args[1]) {
+ args++;
+ CAfile = *args;
+ } else badarg = 1;
+#ifndef OPENSSL_NO_ENGINE
+ } else if (!strcmp(*args,"-engine")) {
+ if (args[1]) {
+ args++;
+ engine = *args;
+ } else badarg = 1;
+#endif
+ } else badarg = 1;
+
+ } else badarg = 1;
+ args++;
+ }
+
+ if (badarg) {
+ BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
+ BIO_printf (bio_err, "where options are\n");
+ BIO_printf (bio_err, "-export output PKCS12 file\n");
+ BIO_printf (bio_err, "-chain add certificate chain\n");
+ BIO_printf (bio_err, "-inkey file private key if not infile\n");
+ BIO_printf (bio_err, "-certfile f add all certs in f\n");
+ BIO_printf (bio_err, "-CApath arg - PEM format directory of CA's\n");
+ BIO_printf (bio_err, "-CAfile arg - PEM format file of CA's\n");
+ BIO_printf (bio_err, "-name \"name\" use name as friendly name\n");
+ BIO_printf (bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n");
+ BIO_printf (bio_err, "-in infile input filename\n");
+ BIO_printf (bio_err, "-out outfile output filename\n");
+ BIO_printf (bio_err, "-noout don't output anything, just verify.\n");
+ BIO_printf (bio_err, "-nomacver don't verify MAC.\n");
+ BIO_printf (bio_err, "-nocerts don't output certificates.\n");
+ BIO_printf (bio_err, "-clcerts only output client certificates.\n");
+ BIO_printf (bio_err, "-cacerts only output CA certificates.\n");
+ BIO_printf (bio_err, "-nokeys don't output private keys.\n");
+ BIO_printf (bio_err, "-info give info about PKCS#12 structure.\n");
+ BIO_printf (bio_err, "-des encrypt private keys with DES\n");
+ BIO_printf (bio_err, "-des3 encrypt private keys with triple DES (default)\n");
+#ifndef OPENSSL_NO_IDEA
+ BIO_printf (bio_err, "-idea encrypt private keys with idea\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+ BIO_printf (bio_err, "-seed encrypt private keys with seed\n");
+#endif
+#ifndef OPENSSL_NO_AES
+ BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
+ BIO_printf (bio_err, " encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
+ BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n");
+#endif
+ BIO_printf (bio_err, "-nodes don't encrypt private keys\n");
+ BIO_printf (bio_err, "-noiter don't use encryption iteration\n");
+ BIO_printf (bio_err, "-nomaciter don't use MAC iteration\n");
+ BIO_printf (bio_err, "-maciter use MAC iteration\n");
+ BIO_printf (bio_err, "-nomac don't generate MAC\n");
+ BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n");
+ BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
+ BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n");
+ BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n");
+ BIO_printf (bio_err, "-macalg alg digest algorithm used in MAC (default SHA1)\n");
+ BIO_printf (bio_err, "-keyex set MS key exchange type\n");
+ BIO_printf (bio_err, "-keysig set MS key signature type\n");
+ BIO_printf (bio_err, "-password p set import/export password source\n");
+ BIO_printf (bio_err, "-passin p input file pass phrase source\n");
+ BIO_printf (bio_err, "-passout p output file pass phrase source\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err, " load the file (or the files in the directory) into\n");
+ BIO_printf(bio_err, " the random number generator\n");
+ BIO_printf(bio_err, "-CSP name Microsoft CSP name\n");
+ BIO_printf(bio_err, "-LMK Add local machine keyset attribute to private key\n");
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if(passarg) {
+ if(export_cert) passargout = passarg;
+ else passargin = passarg;
+ }
+
+ if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
+ BIO_printf(bio_err, "Error getting passwords\n");
+ goto end;
+ }
+
+ if(!cpass) {
+ if(export_cert) cpass = passout;
+ else cpass = passin;
+ }
+
+ if(cpass) {
+ mpass = cpass;
+ noprompt = 1;
+ } else {
+ cpass = pass;
+ mpass = macpass;
+ }
+
+ if(export_cert || inrand) {
+ app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+ }
+ ERR_load_crypto_strings();
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_push_info("read files");
+#endif
+
+ if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
+ else in = BIO_new_file(infile, "rb");
+ if (!in) {
+ BIO_printf(bio_err, "Error opening input file %s\n",
+ infile ? infile : "<stdin>");
+ perror (infile);
+ goto end;
+ }
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+ CRYPTO_push_info("write files");
+#endif
+
+ if (!outfile) {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ } else out = BIO_new_file(outfile, "wb");
+ if (!out) {
+ BIO_printf(bio_err, "Error opening output file %s\n",
+ outfile ? outfile : "<stdout>");
+ perror (outfile);
+ goto end;
+ }
+ if (twopass) {
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_push_info("read MAC password");
+#endif
+ if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert))
+ {
+ BIO_printf (bio_err, "Can't read Password\n");
+ goto end;
+ }
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+#endif
+ }
+
+ if (export_cert) {
+ EVP_PKEY *key = NULL;
+ X509 *ucert = NULL, *x = NULL;
+ STACK_OF(X509) *certs=NULL;
+ const EVP_MD *macmd = NULL;
+ unsigned char *catmp = NULL;
+ int i;
+
+ if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS))
+ {
+ BIO_printf(bio_err, "Nothing to do!\n");
+ goto export_end;
+ }
+
+ if (options & NOCERTS)
+ chain = 0;
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_push_info("process -export_cert");
+ CRYPTO_push_info("reading private key");
+#endif
+ if (!(options & NOKEYS))
+ {
+ key = load_key(bio_err, keyname ? keyname : infile,
+ FORMAT_PEM, 1, passin, e, "private key");
+ if (!key)
+ goto export_end;
+ }
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+ CRYPTO_push_info("reading certs from input");
+#endif
+
+ /* Load in all certs in input file */
+ if(!(options & NOCERTS))
+ {
+ certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
+ "certificates");
+ if (!certs)
+ goto export_end;
+
+ if (key)
+ {
+ /* Look for matching private key */
+ for(i = 0; i < sk_X509_num(certs); i++)
+ {
+ x = sk_X509_value(certs, i);
+ if(X509_check_private_key(x, key))
+ {
+ ucert = x;
+ /* Zero keyid and alias */
+ X509_keyid_set1(ucert, NULL, 0);
+ X509_alias_set1(ucert, NULL, 0);
+ /* Remove from list */
+ (void)sk_X509_delete(certs, i);
+ break;
+ }
+ }
+ if (!ucert)
+ {
+ BIO_printf(bio_err, "No certificate matches private key\n");
+ goto export_end;
+ }
+ }
+
+ }
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+ CRYPTO_push_info("reading certs from input 2");
+#endif
+
+ /* Add any more certificates asked for */
+ if(certfile)
+ {
+ STACK_OF(X509) *morecerts=NULL;
+ if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
+ NULL, e,
+ "certificates from certfile")))
+ goto export_end;
+ while(sk_X509_num(morecerts) > 0)
+ sk_X509_push(certs, sk_X509_shift(morecerts));
+ sk_X509_free(morecerts);
+ }
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+ CRYPTO_push_info("reading certs from certfile");
+#endif
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+ CRYPTO_push_info("building chain");
+#endif
+
+ /* If chaining get chain from user cert */
+ if (chain) {
+ int vret;
+ STACK_OF(X509) *chain2;
+ X509_STORE *store = X509_STORE_new();
+ if (!store)
+ {
+ BIO_printf (bio_err, "Memory allocation error\n");
+ goto export_end;
+ }
+ if (!X509_STORE_load_locations(store, CAfile, CApath))
+ X509_STORE_set_default_paths (store);
+
+ vret = get_cert_chain (ucert, store, &chain2);
+ X509_STORE_free(store);
+
+ if (!vret) {
+ /* Exclude verified certificate */
+ for (i = 1; i < sk_X509_num (chain2) ; i++)
+ sk_X509_push(certs, sk_X509_value (chain2, i));
+ /* Free first certificate */
+ X509_free(sk_X509_value(chain2, 0));
+ sk_X509_free(chain2);
+ } else {
+ if (vret >= 0)
+ BIO_printf (bio_err, "Error %s getting chain.\n",
+ X509_verify_cert_error_string(vret));
+ else
+ ERR_print_errors(bio_err);
+ goto export_end;
+ }
+ }
+
+ /* Add any CA names */
+
+ for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++)
+ {
+ catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
+ X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
+ }
+
+ if (csp_name && key)
+ EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
+ MBSTRING_ASC, (unsigned char *)csp_name, -1);
+
+ if (add_lmk && key)
+ EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+ CRYPTO_push_info("reading password");
+#endif
+
+ if(!noprompt &&
+ EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1))
+ {
+ BIO_printf (bio_err, "Can't read Password\n");
+ goto export_end;
+ }
+ if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+ CRYPTO_push_info("creating PKCS#12 structure");
+#endif
+
+ p12 = PKCS12_create(cpass, name, key, ucert, certs,
+ key_pbe, cert_pbe, iter, -1, keytype);
+
+ if (!p12)
+ {
+ ERR_print_errors (bio_err);
+ goto export_end;
+ }
+
+ if (macalg)
+ {
+ macmd = EVP_get_digestbyname(macalg);
+ if (!macmd)
+ {
+ BIO_printf(bio_err, "Unknown digest algorithm %s\n",
+ macalg);
+ }
+ }
+
+ if (maciter != -1)
+ PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+ CRYPTO_push_info("writing pkcs12");
+#endif
+
+ i2d_PKCS12_bio(out, p12);
+
+ ret = 0;
+
+ export_end:
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+ CRYPTO_pop_info();
+ CRYPTO_push_info("process -export_cert: freeing");
+#endif
+
+ if (key) EVP_PKEY_free(key);
+ if (certs) sk_X509_pop_free(certs, X509_free);
+ if (ucert) X509_free(ucert);
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+#endif
+ goto end;
+
+ }
+
+ if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_push_info("read import password");
+#endif
+ if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) {
+ BIO_printf (bio_err, "Can't read Password\n");
+ goto end;
+ }
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+#endif
+
+ if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
+
+ if ((options & INFO) && p12->mac) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
+ if(macver) {
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_push_info("verify MAC");
+#endif
+ /* If we enter empty password try no password first */
+ if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
+ /* If mac and crypto pass the same set it to NULL too */
+ if(!twopass) cpass = NULL;
+ } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
+ BIO_printf (bio_err, "Mac verify error: invalid password?\n");
+ ERR_print_errors (bio_err);
+ goto end;
+ }
+ BIO_printf (bio_err, "MAC verified OK\n");
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+#endif
+ }
+
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_push_info("output keys and certificates");
+#endif
+ if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
+ BIO_printf(bio_err, "Error outputting keys and certificates\n");
+ ERR_print_errors (bio_err);
+ goto end;
+ }
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+#endif
+ ret = 0;
+ end:
+ if (p12) PKCS12_free(p12);
+ if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_remove_all_info();
+#endif
+ BIO_free(in);
+ BIO_free_all(out);
+ if (canames) sk_OPENSSL_STRING_free(canames);
+ if(passin) OPENSSL_free(passin);
+ if(passout) OPENSSL_free(passout);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+}
+
+int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass,
+ int passlen, int options, char *pempass)
+{
+ STACK_OF(PKCS7) *asafes = NULL;
+ STACK_OF(PKCS12_SAFEBAG) *bags;
+ int i, bagnid;
+ int ret = 0;
+ PKCS7 *p7;
+
+ if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0;
+ for (i = 0; i < sk_PKCS7_num (asafes); i++) {
+ p7 = sk_PKCS7_value (asafes, i);
+ bagnid = OBJ_obj2nid (p7->type);
+ if (bagnid == NID_pkcs7_data) {
+ bags = PKCS12_unpack_p7data(p7);
+ if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n");
+ } else if (bagnid == NID_pkcs7_encrypted) {
+ if (options & INFO) {
+ BIO_printf(bio_err, "PKCS7 Encrypted data: ");
+ alg_print(bio_err,
+ p7->d.encrypted->enc_data->algorithm);
+ }
+ bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
+ } else continue;
+ if (!bags) goto err;
+ if (!dump_certs_pkeys_bags (out, bags, pass, passlen,
+ options, pempass)) {
+ sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
+ goto err;
+ }
+ sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
+ bags = NULL;
+ }
+ ret = 1;
+
+ err:
+
+ if (asafes)
+ sk_PKCS7_pop_free (asafes, PKCS7_free);
+ return ret;
+}
+
+int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
+ char *pass, int passlen, int options, char *pempass)
+{
+ int i;
+ for (i = 0; i < sk_PKCS12_SAFEBAG_num (bags); i++) {
+ if (!dump_certs_pkeys_bag (out,
+ sk_PKCS12_SAFEBAG_value (bags, i),
+ pass, passlen,
+ options, pempass))
+ return 0;
+ }
+ return 1;
+}
+
+int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass,
+ int passlen, int options, char *pempass)
+{
+ EVP_PKEY *pkey;
+ PKCS8_PRIV_KEY_INFO *p8;
+ X509 *x509;
+
+ switch (M_PKCS12_bag_type(bag))
+ {
+ case NID_keyBag:
+ if (options & INFO) BIO_printf (bio_err, "Key bag\n");
+ if (options & NOKEYS) return 1;
+ print_attribs (out, bag->attrib, "Bag Attributes");
+ p8 = bag->value.keybag;
+ if (!(pkey = EVP_PKCS82PKEY (p8))) return 0;
+ print_attribs (out, p8->attributes, "Key Attributes");
+ PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
+ EVP_PKEY_free(pkey);
+ break;
+
+ case NID_pkcs8ShroudedKeyBag:
+ if (options & INFO) {
+ BIO_printf (bio_err, "Shrouded Keybag: ");
+ alg_print (bio_err, bag->value.shkeybag->algor);
+ }
+ if (options & NOKEYS) return 1;
+ print_attribs (out, bag->attrib, "Bag Attributes");
+ if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
+ return 0;
+ if (!(pkey = EVP_PKCS82PKEY (p8))) {
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ return 0;
+ }
+ print_attribs (out, p8->attributes, "Key Attributes");
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
+ EVP_PKEY_free(pkey);
+ break;
+
+ case NID_certBag:
+ if (options & INFO) BIO_printf (bio_err, "Certificate bag\n");
+ if (options & NOCERTS) return 1;
+ if (PKCS12_get_attr(bag, NID_localKeyID)) {
+ if (options & CACERTS) return 1;
+ } else if (options & CLCERTS) return 1;
+ print_attribs (out, bag->attrib, "Bag Attributes");
+ if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
+ return 1;
+ if (!(x509 = PKCS12_certbag2x509(bag))) return 0;
+ dump_cert_text (out, x509);
+ PEM_write_bio_X509 (out, x509);
+ X509_free(x509);
+ break;
+
+ case NID_safeContentsBag:
+ if (options & INFO) BIO_printf (bio_err, "Safe Contents bag\n");
+ print_attribs (out, bag->attrib, "Bag Attributes");
+ return dump_certs_pkeys_bags (out, bag->value.safes, pass,
+ passlen, options, pempass);
+
+ default:
+ BIO_printf (bio_err, "Warning unsupported bag type: ");
+ i2a_ASN1_OBJECT (bio_err, bag->type);
+ BIO_printf (bio_err, "\n");
+ return 1;
+ break;
+ }
+ return 1;
+}
+
+/* Given a single certificate return a verified chain or NULL if error */
+
+/* Hope this is OK .... */
+
+int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
+{
+ X509_STORE_CTX store_ctx;
+ STACK_OF(X509) *chn;
+ int i = 0;
+
+ /* FIXME: Should really check the return status of X509_STORE_CTX_init
+ * for an error, but how that fits into the return value of this
+ * function is less obvious. */
+ X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
+ if (X509_verify_cert(&store_ctx) <= 0) {
+ i = X509_STORE_CTX_get_error (&store_ctx);
+ if (i == 0)
+ /* avoid returning 0 if X509_verify_cert() did not
+ * set an appropriate error value in the context */
+ i = -1;
+ chn = NULL;
+ goto err;
+ } else
+ chn = X509_STORE_CTX_get1_chain(&store_ctx);
+err:
+ X509_STORE_CTX_cleanup(&store_ctx);
+ *chain = chn;
+
+ return i;
+}
+
+int alg_print (BIO *x, X509_ALGOR *alg)
+{
+ PBEPARAM *pbe;
+ const unsigned char *p;
+ p = alg->parameter->value.sequence->data;
+ pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
+ if (!pbe)
+ return 1;
+ BIO_printf (bio_err, "%s, Iteration %ld\n",
+ OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
+ ASN1_INTEGER_get(pbe->iter));
+ PBEPARAM_free (pbe);
+ return 1;
+}
+
+/* Load all certificates from a given file */
+
+int cert_load(BIO *in, STACK_OF(X509) *sk)
+{
+ int ret;
+ X509 *cert;
+ ret = 0;
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_push_info("cert_load(): reading one cert");
+#endif
+ while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+#endif
+ ret = 1;
+ sk_X509_push(sk, cert);
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_push_info("cert_load(): reading one cert");
+#endif
+ }
+#ifdef CRYPTO_MDEBUG
+ CRYPTO_pop_info();
+#endif
+ if(ret) ERR_clear_error();
+ return ret;
+}
+
+/* Generalised attribute print: handle PKCS#8 and bag attributes */
+
+int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name)
+{
+ X509_ATTRIBUTE *attr;
+ ASN1_TYPE *av;
+ char *value;
+ int i, attr_nid;
+ if(!attrlst) {
+ BIO_printf(out, "%s: <No Attributes>\n", name);
+ return 1;
+ }
+ if(!sk_X509_ATTRIBUTE_num(attrlst)) {
+ BIO_printf(out, "%s: <Empty Attributes>\n", name);
+ return 1;
+ }
+ BIO_printf(out, "%s\n", name);
+ for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
+ attr = sk_X509_ATTRIBUTE_value(attrlst, i);
+ attr_nid = OBJ_obj2nid(attr->object);
+ BIO_printf(out, " ");
+ if(attr_nid == NID_undef) {
+ i2a_ASN1_OBJECT (out, attr->object);
+ BIO_printf(out, ": ");
+ } else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
+
+ if(sk_ASN1_TYPE_num(attr->value.set)) {
+ av = sk_ASN1_TYPE_value(attr->value.set, 0);
+ switch(av->type) {
+ case V_ASN1_BMPSTRING:
+ value = OPENSSL_uni2asc(av->value.bmpstring->data,
+ av->value.bmpstring->length);
+ BIO_printf(out, "%s\n", value);
+ OPENSSL_free(value);
+ break;
+
+ case V_ASN1_OCTET_STRING:
+ hex_prin(out, av->value.octet_string->data,
+ av->value.octet_string->length);
+ BIO_printf(out, "\n");
+ break;
+
+ case V_ASN1_BIT_STRING:
+ hex_prin(out, av->value.bit_string->data,
+ av->value.bit_string->length);
+ BIO_printf(out, "\n");
+ break;
+
+ default:
+ BIO_printf(out, "<Unsupported tag %d>\n", av->type);
+ break;
+ }
+ } else BIO_printf(out, "<No Values>\n");
+ }
+ return 1;
+}
+
+void hex_prin(BIO *out, unsigned char *buf, int len)
+{
+ int i;
+ for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]);
+}
+
+static int set_pbe(BIO *err, int *ppbe, const char *str)
+ {
+ if (!str)
+ return 0;
+ if (!strcmp(str, "NONE"))
+ {
+ *ppbe = -1;
+ return 1;
+ }
+ *ppbe=OBJ_txt2nid(str);
+ if (*ppbe == NID_undef)
+ {
+ BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
+ return 0;
+ }
+ return 1;
+ }
+
+#endif
diff --git a/deps/openssl/openssl/apps/pkcs7.c b/deps/openssl/openssl/apps/pkcs7.c
new file mode 100644
index 000000000..ae6cd33f7
--- /dev/null
+++ b/deps/openssl/openssl/apps/pkcs7.c
@@ -0,0 +1,320 @@
+/* apps/pkcs7.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG pkcs7_main
+
+/* -inform arg - input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ * -print_certs
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ PKCS7 *p7=NULL;
+ int i,badops=0;
+ BIO *in=NULL,*out=NULL;
+ int informat,outformat;
+ char *infile,*outfile,*prog;
+ int print_certs=0,text=0,noout=0,p7_print=0;
+ int ret=1;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ infile=NULL;
+ outfile=NULL;
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-noout") == 0)
+ noout=1;
+ else if (strcmp(*argv,"-text") == 0)
+ text=1;
+ else if (strcmp(*argv,"-print") == 0)
+ p7_print=1;
+ else if (strcmp(*argv,"-print_certs") == 0)
+ print_certs=1;
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+ BIO_printf(bio_err,"where options are\n");
+ BIO_printf(bio_err," -inform arg input format - DER or PEM\n");
+ BIO_printf(bio_err," -outform arg output format - DER or PEM\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -out arg output file\n");
+ BIO_printf(bio_err," -print_certs print any certs or crl in the input\n");
+ BIO_printf(bio_err," -text print full details of certificates\n");
+ BIO_printf(bio_err," -noout don't output encoded data\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
+#endif
+ ret = 1;
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ in=BIO_new(BIO_s_file());
+ out=BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ if (in == NULL)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+
+ if (informat == FORMAT_ASN1)
+ p7=d2i_PKCS7_bio(in,NULL);
+ else if (informat == FORMAT_PEM)
+ p7=PEM_read_bio_PKCS7(in,NULL,NULL,NULL);
+ else
+ {
+ BIO_printf(bio_err,"bad input format specified for pkcs7 object\n");
+ goto end;
+ }
+ if (p7 == NULL)
+ {
+ BIO_printf(bio_err,"unable to load PKCS7 object\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ if (p7_print)
+ PKCS7_print_ctx(out, p7, 0, NULL);
+
+ if (print_certs)
+ {
+ STACK_OF(X509) *certs=NULL;
+ STACK_OF(X509_CRL) *crls=NULL;
+
+ i=OBJ_obj2nid(p7->type);
+ switch (i)
+ {
+ case NID_pkcs7_signed:
+ certs=p7->d.sign->cert;
+ crls=p7->d.sign->crl;
+ break;
+ case NID_pkcs7_signedAndEnveloped:
+ certs=p7->d.signed_and_enveloped->cert;
+ crls=p7->d.signed_and_enveloped->crl;
+ break;
+ default:
+ break;
+ }
+
+ if (certs != NULL)
+ {
+ X509 *x;
+
+ for (i=0; i<sk_X509_num(certs); i++)
+ {
+ x=sk_X509_value(certs,i);
+ if(text) X509_print(out, x);
+ else dump_cert_text(out, x);
+
+ if(!noout) PEM_write_bio_X509(out,x);
+ BIO_puts(out,"\n");
+ }
+ }
+ if (crls != NULL)
+ {
+ X509_CRL *crl;
+
+ for (i=0; i<sk_X509_CRL_num(crls); i++)
+ {
+ crl=sk_X509_CRL_value(crls,i);
+
+ X509_CRL_print(out, crl);
+
+ if(!noout)PEM_write_bio_X509_CRL(out,crl);
+ BIO_puts(out,"\n");
+ }
+ }
+
+ ret=0;
+ goto end;
+ }
+
+ if(!noout) {
+ if (outformat == FORMAT_ASN1)
+ i=i2d_PKCS7_bio(out,p7);
+ else if (outformat == FORMAT_PEM)
+ i=PEM_write_bio_PKCS7(out,p7);
+ else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+
+ if (!i)
+ {
+ BIO_printf(bio_err,"unable to write pkcs7 object\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ ret=0;
+end:
+ if (p7 != NULL) PKCS7_free(p7);
+ if (in != NULL) BIO_free(in);
+ if (out != NULL) BIO_free_all(out);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
diff --git a/deps/openssl/openssl/apps/pkcs8.c b/deps/openssl/openssl/apps/pkcs8.c
new file mode 100644
index 000000000..7edeb179d
--- /dev/null
+++ b/deps/openssl/openssl/apps/pkcs8.c
@@ -0,0 +1,439 @@
+/* pkcs8.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999-2004.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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
+ * licensing@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).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+
+#define PROG pkcs8_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ char **args, *infile = NULL, *outfile = NULL;
+ char *passargin = NULL, *passargout = NULL;
+ BIO *in = NULL, *out = NULL;
+ int topk8 = 0;
+ int pbe_nid = -1;
+ const EVP_CIPHER *cipher = NULL;
+ int iter = PKCS12_DEFAULT_ITER;
+ int informat, outformat;
+ int p8_broken = PKCS8_OK;
+ int nocrypt = 0;
+ X509_SIG *p8 = NULL;
+ PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+ EVP_PKEY *pkey=NULL;
+ char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
+ int badarg = 0;
+ int ret = 1;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+
+ if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ ERR_load_crypto_strings();
+ OpenSSL_add_all_algorithms();
+ args = argv + 1;
+ while (!badarg && *args && *args[0] == '-')
+ {
+ if (!strcmp(*args,"-v2"))
+ {
+ if (args[1])
+ {
+ args++;
+ cipher=EVP_get_cipherbyname(*args);
+ if (!cipher)
+ {
+ BIO_printf(bio_err,
+ "Unknown cipher %s\n", *args);
+ badarg = 1;
+ }
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args,"-v1"))
+ {
+ if (args[1])
+ {
+ args++;
+ pbe_nid=OBJ_txt2nid(*args);
+ if (pbe_nid == NID_undef)
+ {
+ BIO_printf(bio_err,
+ "Unknown PBE algorithm %s\n", *args);
+ badarg = 1;
+ }
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args,"-inform"))
+ {
+ if (args[1])
+ {
+ args++;
+ informat=str2fmt(*args);
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args,"-outform"))
+ {
+ if (args[1])
+ {
+ args++;
+ outformat=str2fmt(*args);
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-topk8"))
+ topk8 = 1;
+ else if (!strcmp (*args, "-noiter"))
+ iter = 1;
+ else if (!strcmp (*args, "-nocrypt"))
+ nocrypt = 1;
+ else if (!strcmp (*args, "-nooct"))
+ p8_broken = PKCS8_NO_OCTET;
+ else if (!strcmp (*args, "-nsdb"))
+ p8_broken = PKCS8_NS_DB;
+ else if (!strcmp (*args, "-embed"))
+ p8_broken = PKCS8_EMBEDDED_PARAM;
+ else if (!strcmp(*args,"-passin"))
+ {
+ if (!args[1]) goto bad;
+ passargin= *(++args);
+ }
+ else if (!strcmp(*args,"-passout"))
+ {
+ if (!args[1]) goto bad;
+ passargout= *(++args);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*args,"-engine") == 0)
+ {
+ if (!args[1]) goto bad;
+ engine= *(++args);
+ }
+#endif
+ else if (!strcmp (*args, "-in"))
+ {
+ if (args[1])
+ {
+ args++;
+ infile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-out"))
+ {
+ if (args[1])
+ {
+ args++;
+ outfile = *args;
+ }
+ else badarg = 1;
+ }
+ else badarg = 1;
+ args++;
+ }
+
+ if (badarg)
+ {
+ bad:
+ BIO_printf(bio_err, "Usage pkcs8 [options]\n");
+ BIO_printf(bio_err, "where options are\n");
+ BIO_printf(bio_err, "-in file input file\n");
+ BIO_printf(bio_err, "-inform X input format (DER or PEM)\n");
+ BIO_printf(bio_err, "-passin arg input file pass phrase source\n");
+ BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
+ BIO_printf(bio_err, "-out file output file\n");
+ BIO_printf(bio_err, "-passout arg output file pass phrase source\n");
+ BIO_printf(bio_err, "-topk8 output PKCS8 file\n");
+ BIO_printf(bio_err, "-nooct use (nonstandard) no octet format\n");
+ BIO_printf(bio_err, "-embed use (nonstandard) embedded DSA parameters format\n");
+ BIO_printf(bio_err, "-nsdb use (nonstandard) DSA Netscape DB format\n");
+ BIO_printf(bio_err, "-noiter use 1 as iteration count\n");
+ BIO_printf(bio_err, "-nocrypt use or expect unencrypted private key\n");
+ BIO_printf(bio_err, "-v2 alg use PKCS#5 v2.0 and cipher \"alg\"\n");
+ BIO_printf(bio_err, "-v1 obj use PKCS#5 v1.5 and cipher \"alg\"\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
+#endif
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
+ {
+ BIO_printf(bio_err, "Error getting passwords\n");
+ goto end;
+ }
+
+ if ((pbe_nid == -1) && !cipher)
+ pbe_nid = NID_pbeWithMD5AndDES_CBC;
+
+ if (infile)
+ {
+ if (!(in = BIO_new_file(infile, "rb")))
+ {
+ BIO_printf(bio_err,
+ "Can't open input file %s\n", infile);
+ goto end;
+ }
+ }
+ else
+ in = BIO_new_fp (stdin, BIO_NOCLOSE);
+
+ if (outfile)
+ {
+ if (!(out = BIO_new_file (outfile, "wb")))
+ {
+ BIO_printf(bio_err,
+ "Can't open output file %s\n", outfile);
+ goto end;
+ }
+ }
+ else
+ {
+ out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ if (topk8)
+ {
+ pkey = load_key(bio_err, infile, informat, 1,
+ passin, e, "key");
+ if (!pkey)
+ goto end;
+ if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken)))
+ {
+ BIO_printf(bio_err, "Error converting key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (nocrypt)
+ {
+ if (outformat == FORMAT_PEM)
+ PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
+ else if (outformat == FORMAT_ASN1)
+ i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
+ else
+ {
+ BIO_printf(bio_err, "Bad format specified for key\n");
+ goto end;
+ }
+ }
+ else
+ {
+ if (passout)
+ p8pass = passout;
+ else
+ {
+ p8pass = pass;
+ if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1))
+ goto end;
+ }
+ app_RAND_load_file(NULL, bio_err, 0);
+ if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
+ p8pass, strlen(p8pass),
+ NULL, 0, iter, p8inf)))
+ {
+ BIO_printf(bio_err, "Error encrypting key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ app_RAND_write_file(NULL, bio_err);
+ if (outformat == FORMAT_PEM)
+ PEM_write_bio_PKCS8(out, p8);
+ else if (outformat == FORMAT_ASN1)
+ i2d_PKCS8_bio(out, p8);
+ else
+ {
+ BIO_printf(bio_err, "Bad format specified for key\n");
+ goto end;
+ }
+ }
+
+ ret = 0;
+ goto end;
+ }
+
+ if (nocrypt)
+ {
+ if (informat == FORMAT_PEM)
+ p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL);
+ else if (informat == FORMAT_ASN1)
+ p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
+ else
+ {
+ BIO_printf(bio_err, "Bad format specified for key\n");
+ goto end;
+ }
+ }
+ else
+ {
+ if (informat == FORMAT_PEM)
+ p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
+ else if (informat == FORMAT_ASN1)
+ p8 = d2i_PKCS8_bio(in, NULL);
+ else
+ {
+ BIO_printf(bio_err, "Bad format specified for key\n");
+ goto end;
+ }
+
+ if (!p8)
+ {
+ BIO_printf (bio_err, "Error reading key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (passin)
+ p8pass = passin;
+ else
+ {
+ p8pass = pass;
+ EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0);
+ }
+ p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
+ }
+
+ if (!p8inf)
+ {
+ BIO_printf(bio_err, "Error decrypting key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (!(pkey = EVP_PKCS82PKEY(p8inf)))
+ {
+ BIO_printf(bio_err, "Error converting key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (p8inf->broken)
+ {
+ BIO_printf(bio_err, "Warning: broken key encoding: ");
+ switch (p8inf->broken)
+ {
+ case PKCS8_NO_OCTET:
+ BIO_printf(bio_err, "No Octet String in PrivateKey\n");
+ break;
+
+ case PKCS8_EMBEDDED_PARAM:
+ BIO_printf(bio_err, "DSA parameters included in PrivateKey\n");
+ break;
+
+ case PKCS8_NS_DB:
+ BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
+ break;
+
+ case PKCS8_NEG_PRIVKEY:
+ BIO_printf(bio_err, "DSA private key value is negative\n");
+ break;
+
+ default:
+ BIO_printf(bio_err, "Unknown broken type\n");
+ break;
+ }
+ }
+
+ if (outformat == FORMAT_PEM)
+ PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
+ else if (outformat == FORMAT_ASN1)
+ i2d_PrivateKey_bio(out, pkey);
+ else
+ {
+ BIO_printf(bio_err, "Bad format specified for key\n");
+ goto end;
+ }
+ ret = 0;
+
+ end:
+ X509_SIG_free(p8);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ EVP_PKEY_free(pkey);
+ BIO_free_all(out);
+ BIO_free(in);
+ if (passin)
+ OPENSSL_free(passin);
+ if (passout)
+ OPENSSL_free(passout);
+
+ return ret;
+ }
diff --git a/deps/openssl/openssl/apps/pkey.c b/deps/openssl/openssl/apps/pkey.c
new file mode 100644
index 000000000..17e6702fb
--- /dev/null
+++ b/deps/openssl/openssl/apps/pkey.c
@@ -0,0 +1,284 @@
+/* apps/pkey.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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
+ * licensing@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).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#define PROG pkey_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ char **args, *infile = NULL, *outfile = NULL;
+ char *passargin = NULL, *passargout = NULL;
+ BIO *in = NULL, *out = NULL;
+ const EVP_CIPHER *cipher = NULL;
+ int informat, outformat;
+ int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0;
+ EVP_PKEY *pkey=NULL;
+ char *passin = NULL, *passout = NULL;
+ int badarg = 0;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+ int ret = 1;
+
+ if (bio_err == NULL)
+ bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ ERR_load_crypto_strings();
+ OpenSSL_add_all_algorithms();
+ args = argv + 1;
+ while (!badarg && *args && *args[0] == '-')
+ {
+ if (!strcmp(*args,"-inform"))
+ {
+ if (args[1])
+ {
+ args++;
+ informat=str2fmt(*args);
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args,"-outform"))
+ {
+ if (args[1])
+ {
+ args++;
+ outformat=str2fmt(*args);
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp(*args,"-passin"))
+ {
+ if (!args[1]) goto bad;
+ passargin= *(++args);
+ }
+ else if (!strcmp(*args,"-passout"))
+ {
+ if (!args[1]) goto bad;
+ passargout= *(++args);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*args,"-engine") == 0)
+ {
+ if (!args[1]) goto bad;
+ engine= *(++args);
+ }
+#endif
+ else if (!strcmp (*args, "-in"))
+ {
+ if (args[1])
+ {
+ args++;
+ infile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-out"))
+ {
+ if (args[1])
+ {
+ args++;
+ outfile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (strcmp(*args,"-pubin") == 0)
+ {
+ pubin=1;
+ pubout=1;
+ pubtext=1;
+ }
+ else if (strcmp(*args,"-pubout") == 0)
+ pubout=1;
+ else if (strcmp(*args,"-text_pub") == 0)
+ {
+ pubtext=1;
+ text=1;
+ }
+ else if (strcmp(*args,"-text") == 0)
+ text=1;
+ else if (strcmp(*args,"-noout") == 0)
+ noout=1;
+ else
+ {
+ cipher = EVP_get_cipherbyname(*args + 1);
+ if (!cipher)
+ {
+ BIO_printf(bio_err, "Unknown cipher %s\n",
+ *args + 1);
+ badarg = 1;
+ }
+ }
+ args++;
+ }
+
+ if (badarg)
+ {
+ bad:
+ BIO_printf(bio_err, "Usage pkey [options]\n");
+ BIO_printf(bio_err, "where options are\n");
+ BIO_printf(bio_err, "-in file input file\n");
+ BIO_printf(bio_err, "-inform X input format (DER or PEM)\n");
+ BIO_printf(bio_err, "-passin arg input file pass phrase source\n");
+ BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
+ BIO_printf(bio_err, "-out file output file\n");
+ BIO_printf(bio_err, "-passout arg output file pass phrase source\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
+#endif
+ return 1;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
+ {
+ BIO_printf(bio_err, "Error getting passwords\n");
+ goto end;
+ }
+
+ if (outfile)
+ {
+ if (!(out = BIO_new_file (outfile, "wb")))
+ {
+ BIO_printf(bio_err,
+ "Can't open output file %s\n", outfile);
+ goto end;
+ }
+ }
+ else
+ {
+ out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+
+ if (pubin)
+ pkey = load_pubkey(bio_err, infile, informat, 1,
+ passin, e, "Public Key");
+ else
+ pkey = load_key(bio_err, infile, informat, 1,
+ passin, e, "key");
+ if (!pkey)
+ goto end;
+
+ if (!noout)
+ {
+ if (outformat == FORMAT_PEM)
+ {
+ if (pubout)
+ PEM_write_bio_PUBKEY(out,pkey);
+ else
+ PEM_write_bio_PrivateKey(out, pkey, cipher,
+ NULL, 0, NULL, passout);
+ }
+ else if (outformat == FORMAT_ASN1)
+ {
+ if (pubout)
+ i2d_PUBKEY_bio(out, pkey);
+ else
+ i2d_PrivateKey_bio(out, pkey);
+ }
+ else
+ {
+ BIO_printf(bio_err, "Bad format specified for key\n");
+ goto end;
+ }
+
+ }
+
+ if (text)
+ {
+ if (pubtext)
+ EVP_PKEY_print_public(out, pkey, 0, NULL);
+ else
+ EVP_PKEY_print_private(out, pkey, 0, NULL);
+ }
+
+ ret = 0;
+
+ end:
+ EVP_PKEY_free(pkey);
+ BIO_free_all(out);
+ BIO_free(in);
+ if (passin)
+ OPENSSL_free(passin);
+ if (passout)
+ OPENSSL_free(passout);
+
+ return ret;
+ }
diff --git a/deps/openssl/openssl/apps/pkeyparam.c b/deps/openssl/openssl/apps/pkeyparam.c
new file mode 100644
index 000000000..6f7a357a3
--- /dev/null
+++ b/deps/openssl/openssl/apps/pkeyparam.c
@@ -0,0 +1,200 @@
+/* apps/pkeyparam.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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
+ * licensing@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).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#define PROG pkeyparam_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ char **args, *infile = NULL, *outfile = NULL;
+ BIO *in = NULL, *out = NULL;
+ int text = 0, noout = 0;
+ EVP_PKEY *pkey=NULL;
+ int badarg = 0;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+ int ret = 1;
+
+ if (bio_err == NULL)
+ bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ ERR_load_crypto_strings();
+ OpenSSL_add_all_algorithms();
+ args = argv + 1;
+ while (!badarg && *args && *args[0] == '-')
+ {
+ if (!strcmp (*args, "-in"))
+ {
+ if (args[1])
+ {
+ args++;
+ infile = *args;
+ }
+ else badarg = 1;
+ }
+ else if (!strcmp (*args, "-out"))
+ {
+ if (args[1])
+ {
+ args++;
+ outfile = *args;
+ }
+ else badarg = 1;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*args,"-engine") == 0)
+ {
+ if (!args[1]) goto bad;
+ engine= *(++args);
+ }
+#endif
+
+ else if (strcmp(*args,"-text") == 0)
+ text=1;
+ else if (strcmp(*args,"-noout") == 0)
+ noout=1;
+ args++;
+ }
+
+ if (badarg)
+ {
+#ifndef OPENSSL_NO_ENGINE
+ bad:
+#endif
+ BIO_printf(bio_err, "Usage pkeyparam [options]\n");
+ BIO_printf(bio_err, "where options are\n");
+ BIO_printf(bio_err, "-in file input file\n");
+ BIO_printf(bio_err, "-out file output file\n");
+ BIO_printf(bio_err, "-text print parameters as text\n");
+ BIO_printf(bio_err, "-noout don't output encoded parameters\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
+#endif
+ return 1;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ if (infile)
+ {
+ if (!(in = BIO_new_file (infile, "r")))
+ {
+ BIO_printf(bio_err,
+ "Can't open input file %s\n", infile);
+ goto end;
+ }
+ }
+ else
+ in = BIO_new_fp (stdin, BIO_NOCLOSE);
+
+ if (outfile)
+ {
+ if (!(out = BIO_new_file (outfile, "w")))
+ {
+ BIO_printf(bio_err,
+ "Can't open output file %s\n", outfile);
+ goto end;
+ }
+ }
+ else
+ {
+ out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+
+ pkey = PEM_read_bio_Parameters(in, NULL);
+ if (!pkey)
+ {
+ BIO_printf(bio_err, "Error reading parameters\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (!noout)
+ PEM_write_bio_Parameters(out,pkey);
+
+ if (text)
+ EVP_PKEY_print_params(out, pkey, 0, NULL);
+
+ ret = 0;
+
+ end:
+ EVP_PKEY_free(pkey);
+ BIO_free_all(out);
+ BIO_free(in);
+
+ return ret;
+ }
diff --git a/deps/openssl/openssl/apps/pkeyutl.c b/deps/openssl/openssl/apps/pkeyutl.c
new file mode 100644
index 000000000..7eb3f5c54
--- /dev/null
+++ b/deps/openssl/openssl/apps/pkeyutl.c
@@ -0,0 +1,570 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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
+ * licensing@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).
+ *
+ */
+
+
+#include "apps.h"
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+
+#define KEY_PRIVKEY 1
+#define KEY_PUBKEY 2
+#define KEY_CERT 3
+
+static void usage(void);
+
+#undef PROG
+
+#define PROG pkeyutl_main
+
+static EVP_PKEY_CTX *init_ctx(int *pkeysize,
+ char *keyfile, int keyform, int key_type,
+ char *passargin, int pkey_op, ENGINE *e);
+
+static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
+ const char *file);
+
+static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
+ unsigned char *out, size_t *poutlen,
+ unsigned char *in, size_t inlen);
+
+int MAIN(int argc, char **);
+
+int MAIN(int argc, char **argv)
+{
+ BIO *in = NULL, *out = NULL;
+ char *infile = NULL, *outfile = NULL, *sigfile = NULL;
+ ENGINE *e = NULL;
+ int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
+ int keyform = FORMAT_PEM, peerform = FORMAT_PEM;
+ char badarg = 0, rev = 0;
+ char hexdump = 0, asn1parse = 0;
+ EVP_PKEY_CTX *ctx = NULL;
+ char *passargin = NULL;
+ int keysize = -1;
+
+ unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
+ size_t buf_outlen;
+ int buf_inlen = 0, siglen = -1;
+
+ int ret = 1, rv = -1;
+
+ argc--;
+ argv++;
+
+ if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+ ERR_load_crypto_strings();
+ OpenSSL_add_all_algorithms();
+
+ while(argc >= 1)
+ {
+ if (!strcmp(*argv,"-in"))
+ {
+ if (--argc < 1) badarg = 1;
+ else infile= *(++argv);
+ }
+ else if (!strcmp(*argv,"-out"))
+ {
+ if (--argc < 1) badarg = 1;
+ else outfile= *(++argv);
+ }
+ else if (!strcmp(*argv,"-sigfile"))
+ {
+ if (--argc < 1) badarg = 1;
+ else sigfile= *(++argv);
+ }
+ else if(!strcmp(*argv, "-inkey"))
+ {
+ if (--argc < 1)
+ badarg = 1;
+ else
+ {
+ ctx = init_ctx(&keysize,
+ *(++argv), keyform, key_type,
+ passargin, pkey_op, e);
+ if (!ctx)
+ {
+ BIO_puts(bio_err,
+ "Error initializing context\n");
+ ERR_print_errors(bio_err);
+ badarg = 1;
+ }
+ }
+ }
+ else if (!strcmp(*argv,"-peerkey"))
+ {
+ if (--argc < 1)
+ badarg = 1;
+ else if (!setup_peer(bio_err, ctx, peerform, *(++argv)))
+ badarg = 1;
+ }
+ else if (!strcmp(*argv,"-passin"))
+ {
+ if (--argc < 1) badarg = 1;
+ else passargin= *(++argv);
+ }
+ else if (strcmp(*argv,"-peerform") == 0)
+ {
+ if (--argc < 1) badarg = 1;
+ else peerform=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-keyform") == 0)
+ {
+ if (--argc < 1) badarg = 1;
+ else keyform=str2fmt(*(++argv));
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if(!strcmp(*argv, "-engine"))
+ {
+ if (--argc < 1)
+ badarg = 1;
+ else
+ e = setup_engine(bio_err, *(++argv), 0);
+ }
+#endif
+ else if(!strcmp(*argv, "-pubin"))
+ key_type = KEY_PUBKEY;
+ else if(!strcmp(*argv, "-certin"))
+ key_type = KEY_CERT;
+ else if(!strcmp(*argv, "-asn1parse"))
+ asn1parse = 1;
+ else if(!strcmp(*argv, "-hexdump"))
+ hexdump = 1;
+ else if(!strcmp(*argv, "-sign"))
+ pkey_op = EVP_PKEY_OP_SIGN;
+ else if(!strcmp(*argv, "-verify"))
+ pkey_op = EVP_PKEY_OP_VERIFY;
+ else if(!strcmp(*argv, "-verifyrecover"))
+ pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
+ else if(!strcmp(*argv, "-rev"))
+ rev = 1;
+ else if(!strcmp(*argv, "-encrypt"))
+ pkey_op = EVP_PKEY_OP_ENCRYPT;
+ else if(!strcmp(*argv, "-decrypt"))
+ pkey_op = EVP_PKEY_OP_DECRYPT;
+ else if(!strcmp(*argv, "-derive"))
+ pkey_op = EVP_PKEY_OP_DERIVE;
+ else if (strcmp(*argv,"-pkeyopt") == 0)
+ {
+ if (--argc < 1)
+ badarg = 1;
+ else if (!ctx)
+ {
+ BIO_puts(bio_err,
+ "-pkeyopt command before -inkey\n");
+ badarg = 1;
+ }
+ else if (pkey_ctrl_string(ctx, *(++argv)) <= 0)
+ {
+ BIO_puts(bio_err, "parameter setting error\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ else badarg = 1;
+ if(badarg)
+ {
+ usage();
+ goto end;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (!ctx)
+ {
+ usage();
+ goto end;
+ }
+
+ if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY))
+ {
+ BIO_puts(bio_err, "Signature file specified for non verify\n");
+ goto end;
+ }
+
+ if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY))
+ {
+ BIO_puts(bio_err, "No signature file specified for verify\n");
+ goto end;
+ }
+
+/* FIXME: seed PRNG only if needed */
+ app_RAND_load_file(NULL, bio_err, 0);
+
+ if (pkey_op != EVP_PKEY_OP_DERIVE)
+ {
+ if(infile)
+ {
+ if(!(in = BIO_new_file(infile, "rb")))
+ {
+ BIO_puts(bio_err,
+ "Error Opening Input File\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ else
+ in = BIO_new_fp(stdin, BIO_NOCLOSE);
+ }
+
+ if(outfile)
+ {
+ if(!(out = BIO_new_file(outfile, "wb")))
+ {
+ BIO_printf(bio_err, "Error Creating Output File\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ else
+ {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+
+ if (sigfile)
+ {
+ BIO *sigbio = BIO_new_file(sigfile, "rb");
+ if (!sigbio)
+ {
+ BIO_printf(bio_err, "Can't open signature file %s\n",
+ sigfile);
+ goto end;
+ }
+ siglen = bio_to_mem(&sig, keysize * 10, sigbio);
+ BIO_free(sigbio);
+ if (siglen <= 0)
+ {
+ BIO_printf(bio_err, "Error reading signature data\n");
+ goto end;
+ }
+ }
+
+ if (in)
+ {
+ /* Read the input data */
+ buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
+ if(buf_inlen <= 0)
+ {
+ BIO_printf(bio_err, "Error reading input Data\n");
+ exit(1);
+ }
+ if(rev)
+ {
+ size_t i;
+ unsigned char ctmp;
+ size_t l = (size_t)buf_inlen;
+ for(i = 0; i < l/2; i++)
+ {
+ ctmp = buf_in[i];
+ buf_in[i] = buf_in[l - 1 - i];
+ buf_in[l - 1 - i] = ctmp;
+ }
+ }
+ }
+
+ if(pkey_op == EVP_PKEY_OP_VERIFY)
+ {
+ rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
+ buf_in, (size_t)buf_inlen);
+ if (rv == 0)
+ BIO_puts(out, "Signature Verification Failure\n");
+ else if (rv == 1)
+ BIO_puts(out, "Signature Verified Successfully\n");
+ if (rv >= 0)
+ goto end;
+ }
+ else
+ {
+ rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
+ buf_in, (size_t)buf_inlen);
+ if (rv > 0)
+ {
+ buf_out = OPENSSL_malloc(buf_outlen);
+ if (!buf_out)
+ rv = -1;
+ else
+ rv = do_keyop(ctx, pkey_op,
+ buf_out, (size_t *)&buf_outlen,
+ buf_in, (size_t)buf_inlen);
+ }
+ }
+
+ if(rv <= 0)
+ {
+ BIO_printf(bio_err, "Public Key operation error\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ ret = 0;
+ if(asn1parse)
+ {
+ if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
+ ERR_print_errors(bio_err);
+ }
+ else if(hexdump)
+ BIO_dump(out, (char *)buf_out, buf_outlen);
+ else
+ BIO_write(out, buf_out, buf_outlen);
+
+ end:
+ if (ctx)
+ EVP_PKEY_CTX_free(ctx);
+ BIO_free(in);
+ BIO_free_all(out);
+ if (buf_in)
+ OPENSSL_free(buf_in);
+ if (buf_out)
+ OPENSSL_free(buf_out);
+ if (sig)
+ OPENSSL_free(sig);
+ return ret;
+}
+
+static void usage()
+{
+ BIO_printf(bio_err, "Usage: pkeyutl [options]\n");
+ BIO_printf(bio_err, "-in file input file\n");
+ BIO_printf(bio_err, "-out file output file\n");
+ BIO_printf(bio_err, "-sigfile file signature file (verify operation only)\n");
+ BIO_printf(bio_err, "-inkey file input key\n");
+ BIO_printf(bio_err, "-keyform arg private key format - default PEM\n");
+ BIO_printf(bio_err, "-pubin input is a public key\n");
+ BIO_printf(bio_err, "-certin input is a certificate carrying a public key\n");
+ BIO_printf(bio_err, "-pkeyopt X:Y public key options\n");
+ BIO_printf(bio_err, "-sign sign with private key\n");
+ BIO_printf(bio_err, "-verify verify with public key\n");
+ BIO_printf(bio_err, "-verifyrecover verify with public key, recover original data\n");
+ BIO_printf(bio_err, "-encrypt encrypt with public key\n");
+ BIO_printf(bio_err, "-decrypt decrypt with private key\n");
+ BIO_printf(bio_err, "-derive derive shared secret\n");
+ BIO_printf(bio_err, "-hexdump hex dump output\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf(bio_err, "-passin arg pass phrase source\n");
+
+}
+
+static EVP_PKEY_CTX *init_ctx(int *pkeysize,
+ char *keyfile, int keyform, int key_type,
+ char *passargin, int pkey_op, ENGINE *e)
+ {
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ char *passin = NULL;
+ int rv = -1;
+ X509 *x;
+ if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT)
+ || (pkey_op == EVP_PKEY_OP_DERIVE))
+ && (key_type != KEY_PRIVKEY))
+ {
+ BIO_printf(bio_err, "A private key is needed for this operation\n");
+ goto end;
+ }
+ if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+ {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+ switch(key_type)
+ {
+ case KEY_PRIVKEY:
+ pkey = load_key(bio_err, keyfile, keyform, 0,
+ passin, e, "Private Key");
+ break;
+
+ case KEY_PUBKEY:
+ pkey = load_pubkey(bio_err, keyfile, keyform, 0,
+ NULL, e, "Public Key");
+ break;
+
+ case KEY_CERT:
+ x = load_cert(bio_err, keyfile, keyform,
+ NULL, e, "Certificate");
+ if(x)
+ {
+ pkey = X509_get_pubkey(x);
+ X509_free(x);
+ }
+ break;
+
+ }
+
+ *pkeysize = EVP_PKEY_size(pkey);
+
+ if (!pkey)
+ goto end;
+
+ ctx = EVP_PKEY_CTX_new(pkey, e);
+
+ EVP_PKEY_free(pkey);
+
+ if (!ctx)
+ goto end;
+
+ switch(pkey_op)
+ {
+ case EVP_PKEY_OP_SIGN:
+ rv = EVP_PKEY_sign_init(ctx);
+ break;
+
+ case EVP_PKEY_OP_VERIFY:
+ rv = EVP_PKEY_verify_init(ctx);
+ break;
+
+ case EVP_PKEY_OP_VERIFYRECOVER:
+ rv = EVP_PKEY_verify_recover_init(ctx);
+ break;
+
+ case EVP_PKEY_OP_ENCRYPT:
+ rv = EVP_PKEY_encrypt_init(ctx);
+ break;
+
+ case EVP_PKEY_OP_DECRYPT:
+ rv = EVP_PKEY_decrypt_init(ctx);
+ break;
+
+ case EVP_PKEY_OP_DERIVE:
+ rv = EVP_PKEY_derive_init(ctx);
+ break;
+ }
+
+ if (rv <= 0)
+ {
+ EVP_PKEY_CTX_free(ctx);
+ ctx = NULL;
+ }
+
+ end:
+
+ if (passin)
+ OPENSSL_free(passin);
+
+ return ctx;
+
+
+ }
+
+static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
+ const char *file)
+ {
+ EVP_PKEY *peer = NULL;
+ int ret;
+ if (!ctx)
+ {
+ BIO_puts(err, "-peerkey command before -inkey\n");
+ return 0;
+ }
+
+ peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key");
+
+ if (!peer)
+ {
+ BIO_printf(bio_err, "Error reading peer key %s\n", file);
+ ERR_print_errors(err);
+ return 0;
+ }
+
+ ret = EVP_PKEY_derive_set_peer(ctx, peer);
+
+ EVP_PKEY_free(peer);
+ if (ret <= 0)
+ ERR_print_errors(err);
+ return ret;
+ }
+
+static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
+ unsigned char *out, size_t *poutlen,
+ unsigned char *in, size_t inlen)
+ {
+ int rv = 0;
+ switch(pkey_op)
+ {
+ case EVP_PKEY_OP_VERIFYRECOVER:
+ rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
+ break;
+
+ case EVP_PKEY_OP_SIGN:
+ rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
+ break;
+
+ case EVP_PKEY_OP_ENCRYPT:
+ rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
+ break;
+
+ case EVP_PKEY_OP_DECRYPT:
+ rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
+ break;
+
+ case EVP_PKEY_OP_DERIVE:
+ rv = EVP_PKEY_derive(ctx, out, poutlen);
+ break;
+
+ }
+ return rv;
+ }
diff --git a/deps/openssl/openssl/apps/prime.c b/deps/openssl/openssl/apps/prime.c
new file mode 100644
index 000000000..f1aaef872
--- /dev/null
+++ b/deps/openssl/openssl/apps/prime.c
@@ -0,0 +1,160 @@
+/* ====================================================================
+ * Copyright (c) 2004 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.
+ *
+ */
+
+#include <string.h>
+
+#include "apps.h"
+#include <openssl/bn.h>
+
+
+#undef PROG
+#define PROG prime_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ int hex=0;
+ int checks=20;
+ int generate=0;
+ int bits=0;
+ int safe=0;
+ BIGNUM *bn=NULL;
+ BIO *bio_out;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ --argc;
+ ++argv;
+ while (argc >= 1 && **argv == '-')
+ {
+ if(!strcmp(*argv,"-hex"))
+ hex=1;
+ else if(!strcmp(*argv,"-generate"))
+ generate=1;
+ else if(!strcmp(*argv,"-bits"))
+ if(--argc < 1)
+ goto bad;
+ else
+ bits=atoi(*++argv);
+ else if(!strcmp(*argv,"-safe"))
+ safe=1;
+ else if(!strcmp(*argv,"-checks"))
+ if(--argc < 1)
+ goto bad;
+ else
+ checks=atoi(*++argv);
+ else
+ {
+ BIO_printf(bio_err,"Unknown option '%s'\n",*argv);
+ goto bad;
+ }
+ --argc;
+ ++argv;
+ }
+
+ if (argv[0] == NULL && !generate)
+ {
+ BIO_printf(bio_err,"No prime specified\n");
+ goto bad;
+ }
+
+ if ((bio_out=BIO_new(BIO_s_file())) != NULL)
+ {
+ BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ bio_out = BIO_push(tmpbio, bio_out);
+ }
+#endif
+ }
+
+ if(generate)
+ {
+ char *s;
+
+ if(!bits)
+ {
+ BIO_printf(bio_err,"Specifiy the number of bits.\n");
+ return 1;
+ }
+ bn=BN_new();
+ BN_generate_prime_ex(bn,bits,safe,NULL,NULL,NULL);
+ s=hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
+ BIO_printf(bio_out,"%s\n",s);
+ OPENSSL_free(s);
+ }
+ else
+ {
+ if(hex)
+ BN_hex2bn(&bn,argv[0]);
+ else
+ BN_dec2bn(&bn,argv[0]);
+
+ BN_print(bio_out,bn);
+ BIO_printf(bio_out," is %sprime\n",
+ BN_is_prime_ex(bn,checks,NULL,NULL) ? "" : "not ");
+ }
+
+ BN_free(bn);
+ BIO_free_all(bio_out);
+
+ return 0;
+
+ bad:
+ BIO_printf(bio_err,"options are\n");
+ BIO_printf(bio_err,"%-14s hex\n","-hex");
+ BIO_printf(bio_err,"%-14s number of checks\n","-checks <n>");
+ return 1;
+ }
diff --git a/deps/openssl/openssl/apps/privkey.pem b/deps/openssl/openssl/apps/privkey.pem
new file mode 100644
index 000000000..0af46474a
--- /dev/null
+++ b/deps/openssl/openssl/apps/privkey.pem
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,BA26229A1653B7FF
+
+6nhWG8PKhTPO/s3ZvjUa6226NlKdvPDZFsNXOOoSUs9ejxpb/aj5huhs6qRYzsz9
+Year47uaAZYhGD0vAagnNiBnYmjWEpN9G/wQxG7pgZThK1ZxDi63qn8aQ8UjuGHo
+F6RpnnBQIAnWTWqr/Qsybtc5EoNkrj/Cpx0OfbSr6gZsFBCxwX1R1hT3/mhJ45f3
+XMofY32Vdfx9/vtw1O7HmlHXQnXaqnbd9/nn1EpvFJG9+UjPoW7gV4jCOLuR4deE
+jS8hm+cpkwXmFtk3VGjT9tQXPpMv3JpYfBqgGQoMAJ5Toq0DWcHi6Wg08PsD8lgy
+vmTioPsRg+JGkJkJ8GnusgLpQdlQJbjzd7wGE6ElUFLfOxLo8bLlRHoriHNdWYhh
+JjY0LyeTkovcmWxVjImc6ZyBz5Ly4t0BYf1gq3OkjsV91Q1taBxnhiavfizqMCAf
+PPB3sLQnlXG77TOXkNxpqbZfEYrVZW2Nsqqdn8s07Uj4IMONZyq2odYKWFPMJBiM
+POYwXjMAOcmFMTHYsVlhcUJuV6LOuipw/FEbTtPH/MYMxLe4zx65dYo1rb4iLKLS
+gMtB0o/Wl4Xno3ZXh1ucicYnV2J7NpVcjVq+3SFiCRu2SrSkZHZ23EPS13Ec6fcz
+8X/YGA2vTJ8MAOozAzQUwHQYvLk7bIoQVekqDq4p0AZQbhdspHpArCk0Ifqqzg/v
+Uyky/zZiQYanzDenTSRVI/8wac3olxpU8QvbySxYqmbkgq6bTpXJfYFQfnAttEsC
+dA4S5UFgyOPZluxCAM4yaJF3Ft6neutNwftuJQMbgCUi9vYg2tGdSw==
+-----END RSA PRIVATE KEY-----
diff --git a/deps/openssl/openssl/apps/progs.h b/deps/openssl/openssl/apps/progs.h
new file mode 100644
index 000000000..949e78066
--- /dev/null
+++ b/deps/openssl/openssl/apps/progs.h
@@ -0,0 +1,366 @@
+/* apps/progs.h */
+/* automatically generated by progs.pl for openssl.c */
+
+extern int verify_main(int argc,char *argv[]);
+extern int asn1parse_main(int argc,char *argv[]);
+extern int req_main(int argc,char *argv[]);
+extern int dgst_main(int argc,char *argv[]);
+extern int dh_main(int argc,char *argv[]);
+extern int dhparam_main(int argc,char *argv[]);
+extern int enc_main(int argc,char *argv[]);
+extern int passwd_main(int argc,char *argv[]);
+extern int gendh_main(int argc,char *argv[]);
+extern int errstr_main(int argc,char *argv[]);
+extern int ca_main(int argc,char *argv[]);
+extern int crl_main(int argc,char *argv[]);
+extern int rsa_main(int argc,char *argv[]);
+extern int rsautl_main(int argc,char *argv[]);
+extern int dsa_main(int argc,char *argv[]);
+extern int dsaparam_main(int argc,char *argv[]);
+extern int ec_main(int argc,char *argv[]);
+extern int ecparam_main(int argc,char *argv[]);
+extern int x509_main(int argc,char *argv[]);
+extern int genrsa_main(int argc,char *argv[]);
+extern int gendsa_main(int argc,char *argv[]);
+extern int genpkey_main(int argc,char *argv[]);
+extern int s_server_main(int argc,char *argv[]);
+extern int s_client_main(int argc,char *argv[]);
+extern int speed_main(int argc,char *argv[]);
+extern int s_time_main(int argc,char *argv[]);
+extern int version_main(int argc,char *argv[]);
+extern int pkcs7_main(int argc,char *argv[]);
+extern int cms_main(int argc,char *argv[]);
+extern int crl2pkcs7_main(int argc,char *argv[]);
+extern int sess_id_main(int argc,char *argv[]);
+extern int ciphers_main(int argc,char *argv[]);
+extern int nseq_main(int argc,char *argv[]);
+extern int pkcs12_main(int argc,char *argv[]);
+extern int pkcs8_main(int argc,char *argv[]);
+extern int pkey_main(int argc,char *argv[]);
+extern int pkeyparam_main(int argc,char *argv[]);
+extern int pkeyutl_main(int argc,char *argv[]);
+extern int spkac_main(int argc,char *argv[]);
+extern int smime_main(int argc,char *argv[]);
+extern int rand_main(int argc,char *argv[]);
+extern int engine_main(int argc,char *argv[]);
+extern int ocsp_main(int argc,char *argv[]);
+extern int prime_main(int argc,char *argv[]);
+extern int ts_main(int argc,char *argv[]);
+extern int srp_main(int argc,char *argv[]);
+
+#define FUNC_TYPE_GENERAL 1
+#define FUNC_TYPE_MD 2
+#define FUNC_TYPE_CIPHER 3
+#define FUNC_TYPE_PKEY 4
+#define FUNC_TYPE_MD_ALG 5
+#define FUNC_TYPE_CIPHER_ALG 6
+
+typedef struct {
+ int type;
+ const char *name;
+ int (*func)(int argc,char *argv[]);
+ } FUNCTION;
+DECLARE_LHASH_OF(FUNCTION);
+
+FUNCTION functions[] = {
+ {FUNC_TYPE_GENERAL,"verify",verify_main},
+ {FUNC_TYPE_GENERAL,"asn1parse",asn1parse_main},
+ {FUNC_TYPE_GENERAL,"req",req_main},
+ {FUNC_TYPE_GENERAL,"dgst",dgst_main},
+#ifndef OPENSSL_NO_DH
+ {FUNC_TYPE_GENERAL,"dh",dh_main},
+#endif
+#ifndef OPENSSL_NO_DH
+ {FUNC_TYPE_GENERAL,"dhparam",dhparam_main},
+#endif
+ {FUNC_TYPE_GENERAL,"enc",enc_main},
+ {FUNC_TYPE_GENERAL,"passwd",passwd_main},
+#ifndef OPENSSL_NO_DH
+ {FUNC_TYPE_GENERAL,"gendh",gendh_main},
+#endif
+ {FUNC_TYPE_GENERAL,"errstr",errstr_main},
+ {FUNC_TYPE_GENERAL,"ca",ca_main},
+ {FUNC_TYPE_GENERAL,"crl",crl_main},
+#ifndef OPENSSL_NO_RSA
+ {FUNC_TYPE_GENERAL,"rsa",rsa_main},
+#endif
+#ifndef OPENSSL_NO_RSA
+ {FUNC_TYPE_GENERAL,"rsautl",rsautl_main},
+#endif
+#ifndef OPENSSL_NO_DSA
+ {FUNC_TYPE_GENERAL,"dsa",dsa_main},
+#endif
+#ifndef OPENSSL_NO_DSA
+ {FUNC_TYPE_GENERAL,"dsaparam",dsaparam_main},
+#endif
+#ifndef OPENSSL_NO_EC
+ {FUNC_TYPE_GENERAL,"ec",ec_main},
+#endif
+#ifndef OPENSSL_NO_EC
+ {FUNC_TYPE_GENERAL,"ecparam",ecparam_main},
+#endif
+ {FUNC_TYPE_GENERAL,"x509",x509_main},
+#ifndef OPENSSL_NO_RSA
+ {FUNC_TYPE_GENERAL,"genrsa",genrsa_main},
+#endif
+#ifndef OPENSSL_NO_DSA
+ {FUNC_TYPE_GENERAL,"gendsa",gendsa_main},
+#endif
+ {FUNC_TYPE_GENERAL,"genpkey",genpkey_main},
+#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
+ {FUNC_TYPE_GENERAL,"s_server",s_server_main},
+#endif
+#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
+ {FUNC_TYPE_GENERAL,"s_client",s_client_main},
+#endif
+#ifndef OPENSSL_NO_SPEED
+ {FUNC_TYPE_GENERAL,"speed",speed_main},
+#endif
+#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
+ {FUNC_TYPE_GENERAL,"s_time",s_time_main},
+#endif
+ {FUNC_TYPE_GENERAL,"version",version_main},
+ {FUNC_TYPE_GENERAL,"pkcs7",pkcs7_main},
+#ifndef OPENSSL_NO_CMS
+ {FUNC_TYPE_GENERAL,"cms",cms_main},
+#endif
+ {FUNC_TYPE_GENERAL,"crl2pkcs7",crl2pkcs7_main},
+ {FUNC_TYPE_GENERAL,"sess_id",sess_id_main},
+#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
+ {FUNC_TYPE_GENERAL,"ciphers",ciphers_main},
+#endif
+ {FUNC_TYPE_GENERAL,"nseq",nseq_main},
+#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
+ {FUNC_TYPE_GENERAL,"pkcs12",pkcs12_main},
+#endif
+ {FUNC_TYPE_GENERAL,"pkcs8",pkcs8_main},
+ {FUNC_TYPE_GENERAL,"pkey",pkey_main},
+ {FUNC_TYPE_GENERAL,"pkeyparam",pkeyparam_main},
+ {FUNC_TYPE_GENERAL,"pkeyutl",pkeyutl_main},
+ {FUNC_TYPE_GENERAL,"spkac",spkac_main},
+ {FUNC_TYPE_GENERAL,"smime",smime_main},
+ {FUNC_TYPE_GENERAL,"rand",rand_main},
+#ifndef OPENSSL_NO_ENGINE
+ {FUNC_TYPE_GENERAL,"engine",engine_main},
+#endif
+#ifndef OPENSSL_NO_OCSP
+ {FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
+#endif
+ {FUNC_TYPE_GENERAL,"prime",prime_main},
+ {FUNC_TYPE_GENERAL,"ts",ts_main},
+#ifndef OPENSSL_NO_SRP
+ {FUNC_TYPE_GENERAL,"srp",srp_main},
+#endif
+#ifndef OPENSSL_NO_MD2
+ {FUNC_TYPE_MD,"md2",dgst_main},
+#endif
+#ifndef OPENSSL_NO_MD4
+ {FUNC_TYPE_MD,"md4",dgst_main},
+#endif
+#ifndef OPENSSL_NO_MD5
+ {FUNC_TYPE_MD,"md5",dgst_main},
+#endif
+#ifndef OPENSSL_NO_SHA
+ {FUNC_TYPE_MD,"sha",dgst_main},
+#endif
+#ifndef OPENSSL_NO_SHA1
+ {FUNC_TYPE_MD,"sha1",dgst_main},
+#endif
+#ifndef OPENSSL_NO_MDC2
+ {FUNC_TYPE_MD,"mdc2",dgst_main},
+#endif
+#ifndef OPENSSL_NO_RMD160
+ {FUNC_TYPE_MD,"rmd160",dgst_main},
+#endif
+#ifndef OPENSSL_NO_AES
+ {FUNC_TYPE_CIPHER,"aes-128-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_AES
+ {FUNC_TYPE_CIPHER,"aes-128-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_AES
+ {FUNC_TYPE_CIPHER,"aes-192-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_AES
+ {FUNC_TYPE_CIPHER,"aes-192-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_AES
+ {FUNC_TYPE_CIPHER,"aes-256-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_AES
+ {FUNC_TYPE_CIPHER,"aes-256-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ {FUNC_TYPE_CIPHER,"camellia-128-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ {FUNC_TYPE_CIPHER,"camellia-128-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ {FUNC_TYPE_CIPHER,"camellia-192-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ {FUNC_TYPE_CIPHER,"camellia-192-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ {FUNC_TYPE_CIPHER,"camellia-256-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ {FUNC_TYPE_CIPHER,"camellia-256-ecb",enc_main},
+#endif
+ {FUNC_TYPE_CIPHER,"base64",enc_main},
+#ifdef ZLIB
+ {FUNC_TYPE_CIPHER,"zlib",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des3",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"desx",enc_main},
+#endif
+#ifndef OPENSSL_NO_IDEA
+ {FUNC_TYPE_CIPHER,"idea",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+ {FUNC_TYPE_CIPHER,"seed",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC4
+ {FUNC_TYPE_CIPHER,"rc4",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC4
+ {FUNC_TYPE_CIPHER,"rc4-40",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+ {FUNC_TYPE_CIPHER,"rc2",enc_main},
+#endif
+#ifndef OPENSSL_NO_BF
+ {FUNC_TYPE_CIPHER,"bf",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+ {FUNC_TYPE_CIPHER,"cast",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC5
+ {FUNC_TYPE_CIPHER,"rc5",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-ede",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-ede3",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-ede-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-ede3-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-ede-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-ede3-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-ede-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+ {FUNC_TYPE_CIPHER,"des-ede3-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_IDEA
+ {FUNC_TYPE_CIPHER,"idea-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_IDEA
+ {FUNC_TYPE_CIPHER,"idea-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_IDEA
+ {FUNC_TYPE_CIPHER,"idea-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_IDEA
+ {FUNC_TYPE_CIPHER,"idea-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+ {FUNC_TYPE_CIPHER,"seed-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+ {FUNC_TYPE_CIPHER,"seed-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+ {FUNC_TYPE_CIPHER,"seed-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+ {FUNC_TYPE_CIPHER,"seed-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+ {FUNC_TYPE_CIPHER,"rc2-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+ {FUNC_TYPE_CIPHER,"rc2-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+ {FUNC_TYPE_CIPHER,"rc2-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+ {FUNC_TYPE_CIPHER,"rc2-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+ {FUNC_TYPE_CIPHER,"rc2-64-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+ {FUNC_TYPE_CIPHER,"rc2-40-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_BF
+ {FUNC_TYPE_CIPHER,"bf-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_BF
+ {FUNC_TYPE_CIPHER,"bf-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_BF
+ {FUNC_TYPE_CIPHER,"bf-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_BF
+ {FUNC_TYPE_CIPHER,"bf-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+ {FUNC_TYPE_CIPHER,"cast5-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+ {FUNC_TYPE_CIPHER,"cast5-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+ {FUNC_TYPE_CIPHER,"cast5-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+ {FUNC_TYPE_CIPHER,"cast5-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+ {FUNC_TYPE_CIPHER,"cast-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC5
+ {FUNC_TYPE_CIPHER,"rc5-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC5
+ {FUNC_TYPE_CIPHER,"rc5-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC5
+ {FUNC_TYPE_CIPHER,"rc5-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC5
+ {FUNC_TYPE_CIPHER,"rc5-ofb",enc_main},
+#endif
+ {0,NULL,NULL}
+ };
diff --git a/deps/openssl/openssl/apps/progs.pl b/deps/openssl/openssl/apps/progs.pl
new file mode 100644
index 000000000..39ca8f71f
--- /dev/null
+++ b/deps/openssl/openssl/apps/progs.pl
@@ -0,0 +1,104 @@
+#!/usr/local/bin/perl
+
+print "/* apps/progs.h */\n";
+print "/* automatically generated by progs.pl for openssl.c */\n\n";
+
+grep(s/^asn1pars$/asn1parse/,@ARGV);
+
+foreach (@ARGV)
+ { printf "extern int %s_main(int argc,char *argv[]);\n",$_; }
+
+print <<'EOF';
+
+#define FUNC_TYPE_GENERAL 1
+#define FUNC_TYPE_MD 2
+#define FUNC_TYPE_CIPHER 3
+#define FUNC_TYPE_PKEY 4
+#define FUNC_TYPE_MD_ALG 5
+#define FUNC_TYPE_CIPHER_ALG 6
+
+typedef struct {
+ int type;
+ const char *name;
+ int (*func)(int argc,char *argv[]);
+ } FUNCTION;
+DECLARE_LHASH_OF(FUNCTION);
+
+FUNCTION functions[] = {
+EOF
+
+foreach (@ARGV)
+ {
+ push(@files,$_);
+ $str="\t{FUNC_TYPE_GENERAL,\"$_\",${_}_main},\n";
+ if (($_ =~ /^s_/) || ($_ =~ /^ciphers$/))
+ { print "#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))\n${str}#endif\n"; }
+ elsif ( ($_ =~ /^speed$/))
+ { print "#ifndef OPENSSL_NO_SPEED\n${str}#endif\n"; }
+ elsif ( ($_ =~ /^engine$/))
+ { print "#ifndef OPENSSL_NO_ENGINE\n${str}#endif\n"; }
+ elsif ( ($_ =~ /^rsa$/) || ($_ =~ /^genrsa$/) || ($_ =~ /^rsautl$/))
+ { print "#ifndef OPENSSL_NO_RSA\n${str}#endif\n"; }
+ elsif ( ($_ =~ /^dsa$/) || ($_ =~ /^gendsa$/) || ($_ =~ /^dsaparam$/))
+ { print "#ifndef OPENSSL_NO_DSA\n${str}#endif\n"; }
+ elsif ( ($_ =~ /^ec$/) || ($_ =~ /^ecparam$/))
+ { print "#ifndef OPENSSL_NO_EC\n${str}#endif\n";}
+ elsif ( ($_ =~ /^dh$/) || ($_ =~ /^gendh$/) || ($_ =~ /^dhparam$/))
+ { print "#ifndef OPENSSL_NO_DH\n${str}#endif\n"; }
+ elsif ( ($_ =~ /^pkcs12$/))
+ { print "#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)\n${str}#endif\n"; }
+ elsif ( ($_ =~ /^cms$/))
+ { print "#ifndef OPENSSL_NO_CMS\n${str}#endif\n"; }
+ elsif ( ($_ =~ /^ocsp$/))
+ { print "#ifndef OPENSSL_NO_OCSP\n${str}#endif\n"; }
+ elsif ( ($_ =~ /^srp$/))
+ { print "#ifndef OPENSSL_NO_SRP\n${str}#endif\n"; }
+ else
+ { print $str; }
+ }
+
+foreach ("md2","md4","md5","sha","sha1","mdc2","rmd160")
+ {
+ push(@files,$_);
+ printf "#ifndef OPENSSL_NO_".uc($_)."\n\t{FUNC_TYPE_MD,\"".$_."\",dgst_main},\n#endif\n";
+ }
+
+foreach (
+ "aes-128-cbc", "aes-128-ecb",
+ "aes-192-cbc", "aes-192-ecb",
+ "aes-256-cbc", "aes-256-ecb",
+ "camellia-128-cbc", "camellia-128-ecb",
+ "camellia-192-cbc", "camellia-192-ecb",
+ "camellia-256-cbc", "camellia-256-ecb",
+ "base64", "zlib",
+ "des", "des3", "desx", "idea", "seed", "rc4", "rc4-40",
+ "rc2", "bf", "cast", "rc5",
+ "des-ecb", "des-ede", "des-ede3",
+ "des-cbc", "des-ede-cbc","des-ede3-cbc",
+ "des-cfb", "des-ede-cfb","des-ede3-cfb",
+ "des-ofb", "des-ede-ofb","des-ede3-ofb",
+ "idea-cbc","idea-ecb", "idea-cfb", "idea-ofb",
+ "seed-cbc","seed-ecb", "seed-cfb", "seed-ofb",
+ "rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc",
+ "bf-cbc", "bf-ecb", "bf-cfb", "bf-ofb",
+ "cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb",
+ "cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb")
+ {
+ push(@files,$_);
+
+ $t=sprintf("\t{FUNC_TYPE_CIPHER,\"%s\",enc_main},\n",$_);
+ if ($_ =~ /des/) { $t="#ifndef OPENSSL_NO_DES\n${t}#endif\n"; }
+ elsif ($_ =~ /aes/) { $t="#ifndef OPENSSL_NO_AES\n${t}#endif\n"; }
+ elsif ($_ =~ /camellia/) { $t="#ifndef OPENSSL_NO_CAMELLIA\n${t}#endif\n"; }
+ elsif ($_ =~ /idea/) { $t="#ifndef OPENSSL_NO_IDEA\n${t}#endif\n"; }
+ elsif ($_ =~ /seed/) { $t="#ifndef OPENSSL_NO_SEED\n${t}#endif\n"; }
+ elsif ($_ =~ /rc4/) { $t="#ifndef OPENSSL_NO_RC4\n${t}#endif\n"; }
+ elsif ($_ =~ /rc2/) { $t="#ifndef OPENSSL_NO_RC2\n${t}#endif\n"; }
+ elsif ($_ =~ /bf/) { $t="#ifndef OPENSSL_NO_BF\n${t}#endif\n"; }
+ elsif ($_ =~ /cast/) { $t="#ifndef OPENSSL_NO_CAST\n${t}#endif\n"; }
+ elsif ($_ =~ /rc5/) { $t="#ifndef OPENSSL_NO_RC5\n${t}#endif\n"; }
+ elsif ($_ =~ /zlib/) { $t="#ifdef ZLIB\n${t}#endif\n"; }
+ print $t;
+ }
+
+print "\t{0,NULL,NULL}\n\t};\n";
diff --git a/deps/openssl/openssl/apps/rand.c b/deps/openssl/openssl/apps/rand.c
new file mode 100644
index 000000000..790e79592
--- /dev/null
+++ b/deps/openssl/openssl/apps/rand.c
@@ -0,0 +1,245 @@
+/* apps/rand.c */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+
+#include "apps.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#undef PROG
+#define PROG rand_main
+
+/* -out file - write to file
+ * -rand file:file - PRNG seed files
+ * -base64 - base64 encode output
+ * -hex - hex encode output
+ * num - write 'num' bytes
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ int i, r, ret = 1;
+ int badopt;
+ char *outfile = NULL;
+ char *inrand = NULL;
+ int base64 = 0;
+ int hex = 0;
+ BIO *out = NULL;
+ int num = -1;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err = BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto err;
+
+ badopt = 0;
+ i = 0;
+ while (!badopt && argv[++i] != NULL)
+ {
+ if (strcmp(argv[i], "-out") == 0)
+ {
+ if ((argv[i+1] != NULL) && (outfile == NULL))
+ outfile = argv[++i];
+ else
+ badopt = 1;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(argv[i], "-engine") == 0)
+ {
+ if ((argv[i+1] != NULL) && (engine == NULL))
+ engine = argv[++i];
+ else
+ badopt = 1;
+ }
+#endif
+ else if (strcmp(argv[i], "-rand") == 0)
+ {
+ if ((argv[i+1] != NULL) && (inrand == NULL))
+ inrand = argv[++i];
+ else
+ badopt = 1;
+ }
+ else if (strcmp(argv[i], "-base64") == 0)
+ {
+ if (!base64)
+ base64 = 1;
+ else
+ badopt = 1;
+ }
+ else if (strcmp(argv[i], "-hex") == 0)
+ {
+ if (!hex)
+ hex = 1;
+ else
+ badopt = 1;
+ }
+ else if (isdigit((unsigned char)argv[i][0]))
+ {
+ if (num < 0)
+ {
+ r = sscanf(argv[i], "%d", &num);
+ if (r == 0 || num < 0)
+ badopt = 1;
+ }
+ else
+ badopt = 1;
+ }
+ else
+ badopt = 1;
+ }
+
+ if (hex && base64)
+ badopt = 1;
+
+ if (num < 0)
+ badopt = 1;
+
+ if (badopt)
+ {
+ BIO_printf(bio_err, "Usage: rand [options] num\n");
+ BIO_printf(bio_err, "where options are\n");
+ BIO_printf(bio_err, "-out file - write to file\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err, "-engine e - use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err, "-base64 - base64 encode output\n");
+ BIO_printf(bio_err, "-hex - hex encode output\n");
+ goto err;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+
+ out = BIO_new(BIO_s_file());
+ if (out == NULL)
+ goto err;
+ if (outfile != NULL)
+ r = BIO_write_filename(out, outfile);
+ else
+ {
+ r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ if (r <= 0)
+ goto err;
+
+ if (base64)
+ {
+ BIO *b64 = BIO_new(BIO_f_base64());
+ if (b64 == NULL)
+ goto err;
+ out = BIO_push(b64, out);
+ }
+
+ while (num > 0)
+ {
+ unsigned char buf[4096];
+ int chunk;
+
+ chunk = num;
+ if (chunk > (int)sizeof(buf))
+ chunk = sizeof buf;
+ r = RAND_bytes(buf, chunk);
+ if (r <= 0)
+ goto err;
+ if (!hex)
+ BIO_write(out, buf, chunk);
+ else
+ {
+ for (i = 0; i < chunk; i++)
+ BIO_printf(out, "%02x", buf[i]);
+ }
+ num -= chunk;
+ }
+ if (hex)
+ BIO_puts(out, "\n");
+ (void)BIO_flush(out);
+
+ app_RAND_write_file(NULL, bio_err);
+ ret = 0;
+
+err:
+ ERR_print_errors(bio_err);
+ if (out)
+ BIO_free_all(out);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
diff --git a/deps/openssl/openssl/apps/req.c b/deps/openssl/openssl/apps/req.c
new file mode 100644
index 000000000..85526581c
--- /dev/null
+++ b/deps/openssl/openssl/apps/req.c
@@ -0,0 +1,1836 @@
+/* apps/req.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#define SECTION "req"
+
+#define BITS "default_bits"
+#define KEYFILE "default_keyfile"
+#define PROMPT "prompt"
+#define DISTINGUISHED_NAME "distinguished_name"
+#define ATTRIBUTES "attributes"
+#define V3_EXTENSIONS "x509_extensions"
+#define REQ_EXTENSIONS "req_extensions"
+#define STRING_MASK "string_mask"
+#define UTF8_IN "utf8"
+
+#define DEFAULT_KEY_LENGTH 512
+#define MIN_KEY_LENGTH 384
+
+#undef PROG
+#define PROG req_main
+
+/* -inform arg - input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ * -verify - check request signature
+ * -noout - don't print stuff out.
+ * -text - print out human readable text.
+ * -nodes - no des encryption
+ * -config file - Load configuration file.
+ * -key file - make a request using key in file (or use it for verification).
+ * -keyform arg - key file format.
+ * -rand file(s) - load the file(s) into the PRNG.
+ * -newkey - make a key and a request.
+ * -modulus - print RSA modulus.
+ * -pubkey - output Public Key.
+ * -x509 - output a self signed X509 structure instead.
+ * -asn1-kludge - output new certificate request in a format that some CA's
+ * require. This format is wrong
+ */
+
+static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,char *dn,int mutlirdn,
+ int attribs,unsigned long chtype);
+static int build_subject(X509_REQ *req, char *subj, unsigned long chtype,
+ int multirdn);
+static int prompt_info(X509_REQ *req,
+ STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
+ STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs,
+ unsigned long chtype);
+static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk,
+ STACK_OF(CONF_VALUE) *attr, int attribs,
+ unsigned long chtype);
+static int add_attribute_object(X509_REQ *req, char *text, const char *def,
+ char *value, int nid, int n_min,
+ int n_max, unsigned long chtype);
+static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
+ int nid,int n_min,int n_max, unsigned long chtype, int mval);
+static int genpkey_cb(EVP_PKEY_CTX *ctx);
+static int req_check_len(int len,int n_min,int n_max);
+static int check_end(const char *str, const char *end);
+static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
+ long *pkeylen, char **palgnam,
+ ENGINE *keygen_engine);
+#ifndef MONOLITH
+static char *default_config_file=NULL;
+#endif
+static CONF *req_conf=NULL;
+static int batch=0;
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL, *gen_eng = NULL;
+ unsigned long nmflag = 0, reqflag = 0;
+ int ex=1,x509=0,days=30;
+ X509 *x509ss=NULL;
+ X509_REQ *req=NULL;
+ EVP_PKEY_CTX *genctx = NULL;
+ const char *keyalg = NULL;
+ char *keyalgstr = NULL;
+ STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
+ EVP_PKEY *pkey=NULL;
+ int i=0,badops=0,newreq=0,verbose=0,pkey_type=-1;
+ long newkey = -1;
+ BIO *in=NULL,*out=NULL;
+ int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM;
+ int nodes=0,kludge=0,newhdr=0,subject=0,pubkey=0;
+ char *infile,*outfile,*prog,*keyfile=NULL,*template=NULL,*keyout=NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+ char *extensions = NULL;
+ char *req_exts = NULL;
+ const EVP_CIPHER *cipher=NULL;
+ ASN1_INTEGER *serial = NULL;
+ int modulus=0;
+ char *inrand=NULL;
+ char *passargin = NULL, *passargout = NULL;
+ char *passin = NULL, *passout = NULL;
+ char *p;
+ char *subj = NULL;
+ int multirdn = 0;
+ const EVP_MD *md_alg=NULL,*digest=NULL;
+ unsigned long chtype = MBSTRING_ASC;
+#ifndef MONOLITH
+ char *to_free;
+ long errline;
+#endif
+
+ req_conf = NULL;
+#ifndef OPENSSL_NO_DES
+ cipher=EVP_des_ede3_cbc();
+#endif
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ infile=NULL;
+ outfile=NULL;
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+ else if (strcmp(*argv,"-keygen_engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ gen_eng = ENGINE_by_id(*(++argv));
+ if (gen_eng == NULL)
+ {
+ BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv);
+ goto end;
+ }
+ }
+#endif
+ else if (strcmp(*argv,"-key") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keyfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-pubkey") == 0)
+ {
+ pubkey=1;
+ }
+ else if (strcmp(*argv,"-new") == 0)
+ {
+ newreq=1;
+ }
+ else if (strcmp(*argv,"-config") == 0)
+ {
+ if (--argc < 1) goto bad;
+ template= *(++argv);
+ }
+ else if (strcmp(*argv,"-keyform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keyform=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-keyout") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keyout= *(++argv);
+ }
+ else if (strcmp(*argv,"-passin") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargin= *(++argv);
+ }
+ else if (strcmp(*argv,"-passout") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargout= *(++argv);
+ }
+ else if (strcmp(*argv,"-rand") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inrand= *(++argv);
+ }
+ else if (strcmp(*argv,"-newkey") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ keyalg = *(++argv);
+ newreq=1;
+ }
+ else if (strcmp(*argv,"-pkeyopt") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ if (!pkeyopts)
+ pkeyopts = sk_OPENSSL_STRING_new_null();
+ if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv)))
+ goto bad;
+ }
+ else if (strcmp(*argv,"-sigopt") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ if (!sigopts)
+ sigopts = sk_OPENSSL_STRING_new_null();
+ if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+ goto bad;
+ }
+ else if (strcmp(*argv,"-batch") == 0)
+ batch=1;
+ else if (strcmp(*argv,"-newhdr") == 0)
+ newhdr=1;
+ else if (strcmp(*argv,"-modulus") == 0)
+ modulus=1;
+ else if (strcmp(*argv,"-verify") == 0)
+ verify=1;
+ else if (strcmp(*argv,"-nodes") == 0)
+ nodes=1;
+ else if (strcmp(*argv,"-noout") == 0)
+ noout=1;
+ else if (strcmp(*argv,"-verbose") == 0)
+ verbose=1;
+ else if (strcmp(*argv,"-utf8") == 0)
+ chtype = MBSTRING_UTF8;
+ else if (strcmp(*argv,"-nameopt") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if (!set_name_ex(&nmflag, *(++argv))) goto bad;
+ }
+ else if (strcmp(*argv,"-reqopt") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if (!set_cert_ex(&reqflag, *(++argv))) goto bad;
+ }
+ else if (strcmp(*argv,"-subject") == 0)
+ subject=1;
+ else if (strcmp(*argv,"-text") == 0)
+ text=1;
+ else if (strcmp(*argv,"-x509") == 0)
+ x509=1;
+ else if (strcmp(*argv,"-asn1-kludge") == 0)
+ kludge=1;
+ else if (strcmp(*argv,"-no-asn1-kludge") == 0)
+ kludge=0;
+ else if (strcmp(*argv,"-subj") == 0)
+ {
+ if (--argc < 1) goto bad;
+ subj= *(++argv);
+ }
+ else if (strcmp(*argv,"-multivalue-rdn") == 0)
+ multirdn=1;
+ else if (strcmp(*argv,"-days") == 0)
+ {
+ if (--argc < 1) goto bad;
+ days= atoi(*(++argv));
+ if (days == 0) days=30;
+ }
+ else if (strcmp(*argv,"-set_serial") == 0)
+ {
+ if (--argc < 1) goto bad;
+ serial = s2i_ASN1_INTEGER(NULL, *(++argv));
+ if (!serial) goto bad;
+ }
+ else if (strcmp(*argv,"-extensions") == 0)
+ {
+ if (--argc < 1) goto bad;
+ extensions = *(++argv);
+ }
+ else if (strcmp(*argv,"-reqexts") == 0)
+ {
+ if (--argc < 1) goto bad;
+ req_exts = *(++argv);
+ }
+ else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
+ {
+ /* ok */
+ digest=md_alg;
+ }
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+ BIO_printf(bio_err,"where options are\n");
+ BIO_printf(bio_err," -inform arg input format - DER or PEM\n");
+ BIO_printf(bio_err," -outform arg output format - DER or PEM\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -out arg output file\n");
+ BIO_printf(bio_err," -text text form of request\n");
+ BIO_printf(bio_err," -pubkey output public key\n");
+ BIO_printf(bio_err," -noout do not output REQ\n");
+ BIO_printf(bio_err," -verify verify signature on REQ\n");
+ BIO_printf(bio_err," -modulus RSA modulus\n");
+ BIO_printf(bio_err," -nodes don't encrypt the output key\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device\n");
+#endif
+ BIO_printf(bio_err," -subject output the request's subject\n");
+ BIO_printf(bio_err," -passin private key password source\n");
+ BIO_printf(bio_err," -key file use the private key contained in file\n");
+ BIO_printf(bio_err," -keyform arg key file format\n");
+ BIO_printf(bio_err," -keyout arg file to send the key to\n");
+ BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err," load the file (or the files in the directory) into\n");
+ BIO_printf(bio_err," the random number generator\n");
+ BIO_printf(bio_err," -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
+ BIO_printf(bio_err," -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
+#ifndef OPENSSL_NO_ECDSA
+ BIO_printf(bio_err," -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
+#endif
+ BIO_printf(bio_err," -[digest] Digest to sign with (md5, sha1, md2, mdc2, md4)\n");
+ BIO_printf(bio_err," -config file request template file.\n");
+ BIO_printf(bio_err," -subj arg set or modify request subject\n");
+ BIO_printf(bio_err," -multivalue-rdn enable support for multivalued RDNs\n");
+ BIO_printf(bio_err," -new new request.\n");
+ BIO_printf(bio_err," -batch do not ask anything during request generation\n");
+ BIO_printf(bio_err," -x509 output a x509 structure instead of a cert. req.\n");
+ BIO_printf(bio_err," -days number of days a certificate generated by -x509 is valid for.\n");
+ BIO_printf(bio_err," -set_serial serial number to use for a certificate generated by -x509.\n");
+ BIO_printf(bio_err," -newhdr output \"NEW\" in the header lines\n");
+ BIO_printf(bio_err," -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n");
+ BIO_printf(bio_err," have been reported as requiring\n");
+ BIO_printf(bio_err," -extensions .. specify certificate extension section (override value in config file)\n");
+ BIO_printf(bio_err," -reqexts .. specify request extension section (override value in config file)\n");
+ BIO_printf(bio_err," -utf8 input characters are UTF8 (default ASCII)\n");
+ BIO_printf(bio_err," -nameopt arg - various certificate name options\n");
+ BIO_printf(bio_err," -reqopt arg - various request text options\n\n");
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+ if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
+ BIO_printf(bio_err, "Error getting passwords\n");
+ goto end;
+ }
+
+#ifndef MONOLITH /* else this has happened in openssl.c (global `config') */
+ /* Lets load up our environment a little */
+ p=getenv("OPENSSL_CONF");
+ if (p == NULL)
+ p=getenv("SSLEAY_CONF");
+ if (p == NULL)
+ p=to_free=make_config_name();
+ default_config_file=p;
+ config=NCONF_new(NULL);
+ i=NCONF_load(config, p, &errline);
+#endif
+
+ if (template != NULL)
+ {
+ long errline = -1;
+
+ if( verbose )
+ BIO_printf(bio_err,"Using configuration from %s\n",template);
+ req_conf=NCONF_new(NULL);
+ i=NCONF_load(req_conf,template,&errline);
+ if (i == 0)
+ {
+ BIO_printf(bio_err,"error on line %ld of %s\n",errline,template);
+ goto end;
+ }
+ }
+ else
+ {
+ req_conf=config;
+
+ if (req_conf == NULL)
+ {
+ BIO_printf(bio_err,"Unable to load config info from %s\n", default_config_file);
+ if (newreq)
+ goto end;
+ }
+ else if( verbose )
+ BIO_printf(bio_err,"Using configuration from %s\n",
+ default_config_file);
+ }
+
+ if (req_conf != NULL)
+ {
+ if (!load_config(bio_err, req_conf))
+ goto end;
+ p=NCONF_get_string(req_conf,NULL,"oid_file");
+ if (p == NULL)
+ ERR_clear_error();
+ if (p != NULL)
+ {
+ BIO *oid_bio;
+
+ oid_bio=BIO_new_file(p,"r");
+ if (oid_bio == NULL)
+ {
+ /*
+ BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
+ ERR_print_errors(bio_err);
+ */
+ }
+ else
+ {
+ OBJ_create_objects(oid_bio);
+ BIO_free(oid_bio);
+ }
+ }
+ }
+ if(!add_oid_section(bio_err, req_conf)) goto end;
+
+ if (md_alg == NULL)
+ {
+ p=NCONF_get_string(req_conf,SECTION,"default_md");
+ if (p == NULL)
+ ERR_clear_error();
+ if (p != NULL)
+ {
+ if ((md_alg=EVP_get_digestbyname(p)) != NULL)
+ digest=md_alg;
+ }
+ }
+
+ if (!extensions)
+ {
+ extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
+ if (!extensions)
+ ERR_clear_error();
+ }
+ if (extensions) {
+ /* Check syntax of file */
+ X509V3_CTX ctx;
+ X509V3_set_ctx_test(&ctx);
+ X509V3_set_nconf(&ctx, req_conf);
+ if(!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
+ BIO_printf(bio_err,
+ "Error Loading extension section %s\n", extensions);
+ goto end;
+ }
+ }
+
+ if(!passin)
+ {
+ passin = NCONF_get_string(req_conf, SECTION, "input_password");
+ if (!passin)
+ ERR_clear_error();
+ }
+
+ if(!passout)
+ {
+ passout = NCONF_get_string(req_conf, SECTION, "output_password");
+ if (!passout)
+ ERR_clear_error();
+ }
+
+ p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
+ if (!p)
+ ERR_clear_error();
+
+ if(p && !ASN1_STRING_set_default_mask_asc(p)) {
+ BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
+ goto end;
+ }
+
+ if (chtype != MBSTRING_UTF8)
+ {
+ p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
+ if (!p)
+ ERR_clear_error();
+ else if (!strcmp(p, "yes"))
+ chtype = MBSTRING_UTF8;
+ }
+
+
+ if(!req_exts)
+ {
+ req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
+ if (!req_exts)
+ ERR_clear_error();
+ }
+ if(req_exts) {
+ /* Check syntax of file */
+ X509V3_CTX ctx;
+ X509V3_set_ctx_test(&ctx);
+ X509V3_set_nconf(&ctx, req_conf);
+ if(!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
+ BIO_printf(bio_err,
+ "Error Loading request extension section %s\n",
+ req_exts);
+ goto end;
+ }
+ }
+
+ in=BIO_new(BIO_s_file());
+ out=BIO_new(BIO_s_file());
+ if ((in == NULL) || (out == NULL))
+ goto end;
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if (keyfile != NULL)
+ {
+ pkey = load_key(bio_err, keyfile, keyform, 0, passin, e,
+ "Private Key");
+ if (!pkey)
+ {
+ /* load_key() has already printed an appropriate
+ message */
+ goto end;
+ }
+ else
+ {
+ char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE");
+ if (randfile == NULL)
+ ERR_clear_error();
+ app_RAND_load_file(randfile, bio_err, 0);
+ }
+ }
+
+ if (newreq && (pkey == NULL))
+ {
+ char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE");
+ if (randfile == NULL)
+ ERR_clear_error();
+ app_RAND_load_file(randfile, bio_err, 0);
+ if (inrand)
+ app_RAND_load_files(inrand);
+
+ if (keyalg)
+ {
+ genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
+ &keyalgstr, gen_eng);
+ if (!genctx)
+ goto end;
+ }
+
+ if (newkey <= 0)
+ {
+ if (!NCONF_get_number(req_conf,SECTION,BITS, &newkey))
+ newkey=DEFAULT_KEY_LENGTH;
+ }
+
+ if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA))
+ {
+ BIO_printf(bio_err,"private key length is too short,\n");
+ BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey);
+ goto end;
+ }
+
+ if (!genctx)
+ {
+ genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey,
+ &keyalgstr, gen_eng);
+ if (!genctx)
+ goto end;
+ }
+
+ if (pkeyopts)
+ {
+ char *genopt;
+ for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++)
+ {
+ genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
+ if (pkey_ctrl_string(genctx, genopt) <= 0)
+ {
+ BIO_printf(bio_err,
+ "parameter error \"%s\"\n",
+ genopt);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ }
+
+ BIO_printf(bio_err,"Generating a %ld bit %s private key\n",
+ newkey, keyalgstr);
+
+ EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
+ EVP_PKEY_CTX_set_app_data(genctx, bio_err);
+
+ if (EVP_PKEY_keygen(genctx, &pkey) <= 0)
+ {
+ BIO_puts(bio_err, "Error Generating Key\n");
+ goto end;
+ }
+
+ EVP_PKEY_CTX_free(genctx);
+ genctx = NULL;
+
+ app_RAND_write_file(randfile, bio_err);
+
+ if (keyout == NULL)
+ {
+ keyout=NCONF_get_string(req_conf,SECTION,KEYFILE);
+ if (keyout == NULL)
+ ERR_clear_error();
+ }
+
+ if (keyout == NULL)
+ {
+ BIO_printf(bio_err,"writing new private key to stdout\n");
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ BIO_printf(bio_err,"writing new private key to '%s'\n",keyout);
+ if (BIO_write_filename(out,keyout) <= 0)
+ {
+ perror(keyout);
+ goto end;
+ }
+ }
+
+ p=NCONF_get_string(req_conf,SECTION,"encrypt_rsa_key");
+ if (p == NULL)
+ {
+ ERR_clear_error();
+ p=NCONF_get_string(req_conf,SECTION,"encrypt_key");
+ if (p == NULL)
+ ERR_clear_error();
+ }
+ if ((p != NULL) && (strcmp(p,"no") == 0))
+ cipher=NULL;
+ if (nodes) cipher=NULL;
+
+ i=0;
+loop:
+ if (!PEM_write_bio_PrivateKey(out,pkey,cipher,
+ NULL,0,NULL,passout))
+ {
+ if ((ERR_GET_REASON(ERR_peek_error()) ==
+ PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3))
+ {
+ ERR_clear_error();
+ i++;
+ goto loop;
+ }
+ goto end;
+ }
+ BIO_printf(bio_err,"-----\n");
+ }
+
+ if (!newreq)
+ {
+ /* Since we are using a pre-existing certificate
+ * request, the kludge 'format' info should not be
+ * changed. */
+ kludge= -1;
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+
+ if (informat == FORMAT_ASN1)
+ req=d2i_X509_REQ_bio(in,NULL);
+ else if (informat == FORMAT_PEM)
+ req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
+ else
+ {
+ BIO_printf(bio_err,"bad input format specified for X509 request\n");
+ goto end;
+ }
+ if (req == NULL)
+ {
+ BIO_printf(bio_err,"unable to load X509 request\n");
+ goto end;
+ }
+ }
+
+ if (newreq || x509)
+ {
+ if (pkey == NULL)
+ {
+ BIO_printf(bio_err,"you need to specify a private key\n");
+ goto end;
+ }
+
+ if (req == NULL)
+ {
+ req=X509_REQ_new();
+ if (req == NULL)
+ {
+ goto end;
+ }
+
+ i=make_REQ(req,pkey,subj,multirdn,!x509, chtype);
+ subj=NULL; /* done processing '-subj' option */
+ if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes))
+ {
+ sk_X509_ATTRIBUTE_free(req->req_info->attributes);
+ req->req_info->attributes = NULL;
+ }
+ if (!i)
+ {
+ BIO_printf(bio_err,"problems making Certificate Request\n");
+ goto end;
+ }
+ }
+ if (x509)
+ {
+ EVP_PKEY *tmppkey;
+ X509V3_CTX ext_ctx;
+ if ((x509ss=X509_new()) == NULL) goto end;
+
+ /* Set version to V3 */
+ if(extensions && !X509_set_version(x509ss, 2)) goto end;
+ if (serial)
+ {
+ if (!X509_set_serialNumber(x509ss, serial)) goto end;
+ }
+ else
+ {
+ if (!rand_serial(NULL,
+ X509_get_serialNumber(x509ss)))
+ goto end;
+ }
+
+ if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
+ if (!X509_gmtime_adj(X509_get_notBefore(x509ss),0)) goto end;
+ if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL)) goto end;
+ if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
+ tmppkey = X509_REQ_get_pubkey(req);
+ if (!tmppkey || !X509_set_pubkey(x509ss,tmppkey)) goto end;
+ EVP_PKEY_free(tmppkey);
+
+ /* Set up V3 context struct */
+
+ X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
+ X509V3_set_nconf(&ext_ctx, req_conf);
+
+ /* Add extensions */
+ if(extensions && !X509V3_EXT_add_nconf(req_conf,
+ &ext_ctx, extensions, x509ss))
+ {
+ BIO_printf(bio_err,
+ "Error Loading extension section %s\n",
+ extensions);
+ goto end;
+ }
+
+ i=do_X509_sign(bio_err, x509ss, pkey, digest, sigopts);
+ if (!i)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ else
+ {
+ X509V3_CTX ext_ctx;
+
+ /* Set up V3 context struct */
+
+ X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
+ X509V3_set_nconf(&ext_ctx, req_conf);
+
+ /* Add extensions */
+ if(req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
+ &ext_ctx, req_exts, req))
+ {
+ BIO_printf(bio_err,
+ "Error Loading extension section %s\n",
+ req_exts);
+ goto end;
+ }
+ i=do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts);
+ if (!i)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ }
+
+ if (subj && x509)
+ {
+ BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
+ goto end;
+ }
+
+ if (subj && !x509)
+ {
+ if (verbose)
+ {
+ BIO_printf(bio_err, "Modifying Request's Subject\n");
+ print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), nmflag);
+ }
+
+ if (build_subject(req, subj, chtype, multirdn) == 0)
+ {
+ BIO_printf(bio_err, "ERROR: cannot modify subject\n");
+ ex=1;
+ goto end;
+ }
+
+ req->req_info->enc.modified = 1;
+
+ if (verbose)
+ {
+ print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), nmflag);
+ }
+ }
+
+ if (verify && !x509)
+ {
+ int tmp=0;
+
+ if (pkey == NULL)
+ {
+ pkey=X509_REQ_get_pubkey(req);
+ tmp=1;
+ if (pkey == NULL) goto end;
+ }
+
+ i=X509_REQ_verify(req,pkey);
+ if (tmp) {
+ EVP_PKEY_free(pkey);
+ pkey=NULL;
+ }
+
+ if (i < 0)
+ {
+ goto end;
+ }
+ else if (i == 0)
+ {
+ BIO_printf(bio_err,"verify failure\n");
+ ERR_print_errors(bio_err);
+ }
+ else /* if (i > 0) */
+ BIO_printf(bio_err,"verify OK\n");
+ }
+
+ if (noout && !text && !modulus && !subject && !pubkey)
+ {
+ ex=0;
+ goto end;
+ }
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if ((keyout != NULL) && (strcmp(outfile,keyout) == 0))
+ i=(int)BIO_append_filename(out,outfile);
+ else
+ i=(int)BIO_write_filename(out,outfile);
+ if (!i)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ if (pubkey)
+ {
+ EVP_PKEY *tpubkey;
+ tpubkey=X509_REQ_get_pubkey(req);
+ if (tpubkey == NULL)
+ {
+ BIO_printf(bio_err,"Error getting public key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ PEM_write_bio_PUBKEY(out, tpubkey);
+ EVP_PKEY_free(tpubkey);
+ }
+
+ if (text)
+ {
+ if (x509)
+ X509_print_ex(out, x509ss, nmflag, reqflag);
+ else
+ X509_REQ_print_ex(out, req, nmflag, reqflag);
+ }
+
+ if(subject)
+ {
+ if(x509)
+ print_name(out, "subject=", X509_get_subject_name(x509ss), nmflag);
+ else
+ print_name(out, "subject=", X509_REQ_get_subject_name(req), nmflag);
+ }
+
+ if (modulus)
+ {
+ EVP_PKEY *tpubkey;
+
+ if (x509)
+ tpubkey=X509_get_pubkey(x509ss);
+ else
+ tpubkey=X509_REQ_get_pubkey(req);
+ if (tpubkey == NULL)
+ {
+ fprintf(stdout,"Modulus=unavailable\n");
+ goto end;
+ }
+ fprintf(stdout,"Modulus=");
+#ifndef OPENSSL_NO_RSA
+ if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA)
+ BN_print(out,tpubkey->pkey.rsa->n);
+ else
+#endif
+ fprintf(stdout,"Wrong Algorithm type");
+ EVP_PKEY_free(tpubkey);
+ fprintf(stdout,"\n");
+ }
+
+ if (!noout && !x509)
+ {
+ if (outformat == FORMAT_ASN1)
+ i=i2d_X509_REQ_bio(out,req);
+ else if (outformat == FORMAT_PEM) {
+ if(newhdr) i=PEM_write_bio_X509_REQ_NEW(out,req);
+ else i=PEM_write_bio_X509_REQ(out,req);
+ } else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (!i)
+ {
+ BIO_printf(bio_err,"unable to write X509 request\n");
+ goto end;
+ }
+ }
+ if (!noout && x509 && (x509ss != NULL))
+ {
+ if (outformat == FORMAT_ASN1)
+ i=i2d_X509_bio(out,x509ss);
+ else if (outformat == FORMAT_PEM)
+ i=PEM_write_bio_X509(out,x509ss);
+ else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (!i)
+ {
+ BIO_printf(bio_err,"unable to write X509 certificate\n");
+ goto end;
+ }
+ }
+ ex=0;
+end:
+#ifndef MONOLITH
+ if(to_free)
+ OPENSSL_free(to_free);
+#endif
+ if (ex)
+ {
+ ERR_print_errors(bio_err);
+ }
+ if ((req_conf != NULL) && (req_conf != config)) NCONF_free(req_conf);
+ BIO_free(in);
+ BIO_free_all(out);
+ EVP_PKEY_free(pkey);
+ if (genctx)
+ EVP_PKEY_CTX_free(genctx);
+ if (pkeyopts)
+ sk_OPENSSL_STRING_free(pkeyopts);
+ if (sigopts)
+ sk_OPENSSL_STRING_free(sigopts);
+#ifndef OPENSSL_NO_ENGINE
+ if (gen_eng)
+ ENGINE_free(gen_eng);
+#endif
+ if (keyalgstr)
+ OPENSSL_free(keyalgstr);
+ X509_REQ_free(req);
+ X509_free(x509ss);
+ ASN1_INTEGER_free(serial);
+ if(passargin && passin) OPENSSL_free(passin);
+ if(passargout && passout) OPENSSL_free(passout);
+ OBJ_cleanup();
+ apps_shutdown();
+ OPENSSL_EXIT(ex);
+ }
+
+static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
+ int attribs, unsigned long chtype)
+ {
+ int ret=0,i;
+ char no_prompt = 0;
+ STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
+ char *tmp, *dn_sect,*attr_sect;
+
+ tmp=NCONF_get_string(req_conf,SECTION,PROMPT);
+ if (tmp == NULL)
+ ERR_clear_error();
+ if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1;
+
+ dn_sect=NCONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME);
+ if (dn_sect == NULL)
+ {
+ BIO_printf(bio_err,"unable to find '%s' in config\n",
+ DISTINGUISHED_NAME);
+ goto err;
+ }
+ dn_sk=NCONF_get_section(req_conf,dn_sect);
+ if (dn_sk == NULL)
+ {
+ BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect);
+ goto err;
+ }
+
+ attr_sect=NCONF_get_string(req_conf,SECTION,ATTRIBUTES);
+ if (attr_sect == NULL)
+ {
+ ERR_clear_error();
+ attr_sk=NULL;
+ }
+ else
+ {
+ attr_sk=NCONF_get_section(req_conf,attr_sect);
+ if (attr_sk == NULL)
+ {
+ BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect);
+ goto err;
+ }
+ }
+
+ /* setup version number */
+ if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */
+
+ if (no_prompt)
+ i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
+ else
+ {
+ if (subj)
+ i = build_subject(req, subj, chtype, multirdn);
+ else
+ i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
+ }
+ if(!i) goto err;
+
+ if (!X509_REQ_set_pubkey(req,pkey)) goto err;
+
+ ret=1;
+err:
+ return(ret);
+ }
+
+/*
+ * subject is expected to be in the format /type0=value0/type1=value1/type2=...
+ * where characters may be escaped by \
+ */
+static int build_subject(X509_REQ *req, char *subject, unsigned long chtype, int multirdn)
+ {
+ X509_NAME *n;
+
+ if (!(n = parse_name(subject, chtype, multirdn)))
+ return 0;
+
+ if (!X509_REQ_set_subject_name(req, n))
+ {
+ X509_NAME_free(n);
+ return 0;
+ }
+ X509_NAME_free(n);
+ return 1;
+}
+
+
+static int prompt_info(X509_REQ *req,
+ STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
+ STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs,
+ unsigned long chtype)
+ {
+ int i;
+ char *p,*q;
+ char buf[100];
+ int nid, mval;
+ long n_min,n_max;
+ char *type, *value;
+ const char *def;
+ CONF_VALUE *v;
+ X509_NAME *subj;
+ subj = X509_REQ_get_subject_name(req);
+
+ if(!batch)
+ {
+ BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n");
+ BIO_printf(bio_err,"into your certificate request.\n");
+ BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n");
+ BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n");
+ BIO_printf(bio_err,"For some fields there will be a default value,\n");
+ BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n");
+ BIO_printf(bio_err,"-----\n");
+ }
+
+
+ if (sk_CONF_VALUE_num(dn_sk))
+ {
+ i= -1;
+start: for (;;)
+ {
+ i++;
+ if (sk_CONF_VALUE_num(dn_sk) <= i) break;
+
+ v=sk_CONF_VALUE_value(dn_sk,i);
+ p=q=NULL;
+ type=v->name;
+ if(!check_end(type,"_min") || !check_end(type,"_max") ||
+ !check_end(type,"_default") ||
+ !check_end(type,"_value")) continue;
+ /* Skip past any leading X. X: X, etc to allow for
+ * multiple instances
+ */
+ for(p = v->name; *p ; p++)
+ if ((*p == ':') || (*p == ',') ||
+ (*p == '.')) {
+ p++;
+ if(*p) type = p;
+ break;
+ }
+ if (*type == '+')
+ {
+ mval = -1;
+ type++;
+ }
+ else
+ mval = 0;
+ /* If OBJ not recognised ignore it */
+ if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start;
+ if (BIO_snprintf(buf,sizeof buf,"%s_default",v->name)
+ >= (int)sizeof(buf))
+ {
+ BIO_printf(bio_err,"Name '%s' too long\n",v->name);
+ return 0;
+ }
+
+ if ((def=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
+ {
+ ERR_clear_error();
+ def="";
+ }
+
+ BIO_snprintf(buf,sizeof buf,"%s_value",v->name);
+ if ((value=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
+ {
+ ERR_clear_error();
+ value=NULL;
+ }
+
+ BIO_snprintf(buf,sizeof buf,"%s_min",v->name);
+ if (!NCONF_get_number(req_conf,dn_sect,buf, &n_min))
+ {
+ ERR_clear_error();
+ n_min = -1;
+ }
+
+ BIO_snprintf(buf,sizeof buf,"%s_max",v->name);
+ if (!NCONF_get_number(req_conf,dn_sect,buf, &n_max))
+ {
+ ERR_clear_error();
+ n_max = -1;
+ }
+
+ if (!add_DN_object(subj,v->value,def,value,nid,
+ n_min,n_max, chtype, mval))
+ return 0;
+ }
+ if (X509_NAME_entry_count(subj) == 0)
+ {
+ BIO_printf(bio_err,"error, no objects specified in config file\n");
+ return 0;
+ }
+
+ if (attribs)
+ {
+ if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && (!batch))
+ {
+ BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n");
+ BIO_printf(bio_err,"to be sent with your certificate request\n");
+ }
+
+ i= -1;
+start2: for (;;)
+ {
+ i++;
+ if ((attr_sk == NULL) ||
+ (sk_CONF_VALUE_num(attr_sk) <= i))
+ break;
+
+ v=sk_CONF_VALUE_value(attr_sk,i);
+ type=v->name;
+ if ((nid=OBJ_txt2nid(type)) == NID_undef)
+ goto start2;
+
+ if (BIO_snprintf(buf,sizeof buf,"%s_default",type)
+ >= (int)sizeof(buf))
+ {
+ BIO_printf(bio_err,"Name '%s' too long\n",v->name);
+ return 0;
+ }
+
+ if ((def=NCONF_get_string(req_conf,attr_sect,buf))
+ == NULL)
+ {
+ ERR_clear_error();
+ def="";
+ }
+
+
+ BIO_snprintf(buf,sizeof buf,"%s_value",type);
+ if ((value=NCONF_get_string(req_conf,attr_sect,buf))
+ == NULL)
+ {
+ ERR_clear_error();
+ value=NULL;
+ }
+
+ BIO_snprintf(buf,sizeof buf,"%s_min",type);
+ if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min))
+ {
+ ERR_clear_error();
+ n_min = -1;
+ }
+
+ BIO_snprintf(buf,sizeof buf,"%s_max",type);
+ if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max))
+ {
+ ERR_clear_error();
+ n_max = -1;
+ }
+
+ if (!add_attribute_object(req,
+ v->value,def,value,nid,n_min,n_max, chtype))
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ BIO_printf(bio_err,"No template, please set one up.\n");
+ return 0;
+ }
+
+ return 1;
+
+ }
+
+static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
+ STACK_OF(CONF_VALUE) *attr_sk, int attribs, unsigned long chtype)
+ {
+ int i;
+ char *p,*q;
+ char *type;
+ CONF_VALUE *v;
+ X509_NAME *subj;
+
+ subj = X509_REQ_get_subject_name(req);
+
+ for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
+ {
+ int mval;
+ v=sk_CONF_VALUE_value(dn_sk,i);
+ p=q=NULL;
+ type=v->name;
+ /* Skip past any leading X. X: X, etc to allow for
+ * multiple instances
+ */
+ for(p = v->name; *p ; p++)
+#ifndef CHARSET_EBCDIC
+ if ((*p == ':') || (*p == ',') || (*p == '.')) {
+#else
+ if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.'])) {
+#endif
+ p++;
+ if(*p) type = p;
+ break;
+ }
+#ifndef CHARSET_EBCDIC
+ if (*p == '+')
+#else
+ if (*p == os_toascii['+'])
+#endif
+ {
+ p++;
+ mval = -1;
+ }
+ else
+ mval = 0;
+ if (!X509_NAME_add_entry_by_txt(subj,type, chtype,
+ (unsigned char *) v->value,-1,-1,mval)) return 0;
+
+ }
+
+ if (!X509_NAME_entry_count(subj))
+ {
+ BIO_printf(bio_err,"error, no objects specified in config file\n");
+ return 0;
+ }
+ if (attribs)
+ {
+ for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++)
+ {
+ v=sk_CONF_VALUE_value(attr_sk,i);
+ if(!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
+ (unsigned char *)v->value, -1)) return 0;
+ }
+ }
+ return 1;
+ }
+
+
+static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
+ int nid, int n_min, int n_max, unsigned long chtype, int mval)
+ {
+ int i,ret=0;
+ MS_STATIC char buf[1024];
+start:
+ if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
+ (void)BIO_flush(bio_err);
+ if(value != NULL)
+ {
+ BUF_strlcpy(buf,value,sizeof buf);
+ BUF_strlcat(buf,"\n",sizeof buf);
+ BIO_printf(bio_err,"%s\n",value);
+ }
+ else
+ {
+ buf[0]='\0';
+ if (!batch)
+ {
+ if (!fgets(buf,sizeof buf,stdin))
+ return 0;
+ }
+ else
+ {
+ buf[0] = '\n';
+ buf[1] = '\0';
+ }
+ }
+
+ if (buf[0] == '\0') return(0);
+ else if (buf[0] == '\n')
+ {
+ if ((def == NULL) || (def[0] == '\0'))
+ return(1);
+ BUF_strlcpy(buf,def,sizeof buf);
+ BUF_strlcat(buf,"\n",sizeof buf);
+ }
+ else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
+
+ i=strlen(buf);
+ if (buf[i-1] != '\n')
+ {
+ BIO_printf(bio_err,"weird input :-(\n");
+ return(0);
+ }
+ buf[--i]='\0';
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(buf, buf, i);
+#endif
+ if(!req_check_len(i, n_min, n_max)) goto start;
+ if (!X509_NAME_add_entry_by_NID(n,nid, chtype,
+ (unsigned char *) buf, -1,-1,mval)) goto err;
+ ret=1;
+err:
+ return(ret);
+ }
+
+static int add_attribute_object(X509_REQ *req, char *text, const char *def,
+ char *value, int nid, int n_min,
+ int n_max, unsigned long chtype)
+ {
+ int i;
+ static char buf[1024];
+
+start:
+ if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
+ (void)BIO_flush(bio_err);
+ if (value != NULL)
+ {
+ BUF_strlcpy(buf,value,sizeof buf);
+ BUF_strlcat(buf,"\n",sizeof buf);
+ BIO_printf(bio_err,"%s\n",value);
+ }
+ else
+ {
+ buf[0]='\0';
+ if (!batch)
+ {
+ if (!fgets(buf,sizeof buf,stdin))
+ return 0;
+ }
+ else
+ {
+ buf[0] = '\n';
+ buf[1] = '\0';
+ }
+ }
+
+ if (buf[0] == '\0') return(0);
+ else if (buf[0] == '\n')
+ {
+ if ((def == NULL) || (def[0] == '\0'))
+ return(1);
+ BUF_strlcpy(buf,def,sizeof buf);
+ BUF_strlcat(buf,"\n",sizeof buf);
+ }
+ else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
+
+ i=strlen(buf);
+ if (buf[i-1] != '\n')
+ {
+ BIO_printf(bio_err,"weird input :-(\n");
+ return(0);
+ }
+ buf[--i]='\0';
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(buf, buf, i);
+#endif
+ if(!req_check_len(i, n_min, n_max)) goto start;
+
+ if(!X509_REQ_add1_attr_by_NID(req, nid, chtype,
+ (unsigned char *)buf, -1)) {
+ BIO_printf(bio_err, "Error adding attribute\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ return(1);
+err:
+ return(0);
+ }
+
+static int req_check_len(int len, int n_min, int n_max)
+ {
+ if ((n_min > 0) && (len < n_min))
+ {
+ BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",n_min);
+ return(0);
+ }
+ if ((n_max >= 0) && (len > n_max))
+ {
+ BIO_printf(bio_err,"string is too long, it needs to be less than %d bytes long\n",n_max);
+ return(0);
+ }
+ return(1);
+ }
+
+/* Check if the end of a string matches 'end' */
+static int check_end(const char *str, const char *end)
+{
+ int elen, slen;
+ const char *tmp;
+ elen = strlen(end);
+ slen = strlen(str);
+ if(elen > slen) return 1;
+ tmp = str + slen - elen;
+ return strcmp(tmp, end);
+}
+
+static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
+ long *pkeylen, char **palgnam,
+ ENGINE *keygen_engine)
+ {
+ EVP_PKEY_CTX *gctx = NULL;
+ EVP_PKEY *param = NULL;
+ long keylen = -1;
+ BIO *pbio = NULL;
+ const char *paramfile = NULL;
+
+ if (gstr == NULL)
+ {
+ *pkey_type = EVP_PKEY_RSA;
+ keylen = *pkeylen;
+ }
+ else if (gstr[0] >= '0' && gstr[0] <= '9')
+ {
+ *pkey_type = EVP_PKEY_RSA;
+ keylen = atol(gstr);
+ *pkeylen = keylen;
+ }
+ else if (!strncmp(gstr, "param:", 6))
+ paramfile = gstr + 6;
+ else
+ {
+ const char *p = strchr(gstr, ':');
+ int len;
+ ENGINE *tmpeng;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+
+ if (p)
+ len = p - gstr;
+ else
+ len = strlen(gstr);
+ /* The lookup of a the string will cover all engines so
+ * keep a note of the implementation.
+ */
+
+ ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
+
+ if (!ameth)
+ {
+ BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
+ return NULL;
+ }
+
+ EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL,
+ ameth);
+#ifndef OPENSSL_NO_ENGINE
+ if (tmpeng)
+ ENGINE_finish(tmpeng);
+#endif
+ if (*pkey_type == EVP_PKEY_RSA)
+ {
+ if (p)
+ {
+ keylen = atol(p + 1);
+ *pkeylen = keylen;
+ }
+ }
+ else if (p)
+ paramfile = p + 1;
+ }
+
+ if (paramfile)
+ {
+ pbio = BIO_new_file(paramfile, "r");
+ if (!pbio)
+ {
+ BIO_printf(err, "Can't open parameter file %s\n",
+ paramfile);
+ return NULL;
+ }
+ param = PEM_read_bio_Parameters(pbio, NULL);
+
+ if (!param)
+ {
+ X509 *x;
+ (void)BIO_reset(pbio);
+ x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
+ if (x)
+ {
+ param = X509_get_pubkey(x);
+ X509_free(x);
+ }
+ }
+
+ BIO_free(pbio);
+
+ if (!param)
+ {
+ BIO_printf(err, "Error reading parameter file %s\n",
+ paramfile);
+ return NULL;
+ }
+ if (*pkey_type == -1)
+ *pkey_type = EVP_PKEY_id(param);
+ else if (*pkey_type != EVP_PKEY_base_id(param))
+ {
+ BIO_printf(err, "Key Type does not match parameters\n");
+ EVP_PKEY_free(param);
+ return NULL;
+ }
+ }
+
+ if (palgnam)
+ {
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ ENGINE *tmpeng;
+ const char *anam;
+ ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
+ if (!ameth)
+ {
+ BIO_puts(err, "Internal error: can't find key algorithm\n");
+ return NULL;
+ }
+ EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
+ *palgnam = BUF_strdup(anam);
+#ifndef OPENSSL_NO_ENGINE
+ if (tmpeng)
+ ENGINE_finish(tmpeng);
+#endif
+ }
+
+ if (param)
+ {
+ gctx = EVP_PKEY_CTX_new(param, keygen_engine);
+ *pkeylen = EVP_PKEY_bits(param);
+ EVP_PKEY_free(param);
+ }
+ else
+ gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
+
+ if (!gctx)
+ {
+ BIO_puts(err, "Error allocating keygen context\n");
+ ERR_print_errors(err);
+ return NULL;
+ }
+
+ if (EVP_PKEY_keygen_init(gctx) <= 0)
+ {
+ BIO_puts(err, "Error initializing keygen context\n");
+ ERR_print_errors(err);
+ return NULL;
+ }
+#ifndef OPENSSL_NO_RSA
+ if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1))
+ {
+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0)
+ {
+ BIO_puts(err, "Error setting RSA keysize\n");
+ ERR_print_errors(err);
+ EVP_PKEY_CTX_free(gctx);
+ return NULL;
+ }
+ }
+#endif
+
+ return gctx;
+ }
+
+static int genpkey_cb(EVP_PKEY_CTX *ctx)
+ {
+ char c='*';
+ BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+ int p;
+ p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+ if (p == 0) c='.';
+ if (p == 1) c='+';
+ if (p == 2) c='*';
+ if (p == 3) c='\n';
+ BIO_write(b,&c,1);
+ (void)BIO_flush(b);
+#ifdef LINT
+ p=n;
+#endif
+ return 1;
+ }
+
+static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
+ const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
+ {
+ EVP_PKEY_CTX *pkctx = NULL;
+ int i;
+ EVP_MD_CTX_init(ctx);
+ if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
+ return 0;
+ for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
+ {
+ char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
+ if (pkey_ctrl_string(pkctx, sigopt) <= 0)
+ {
+ BIO_printf(err, "parameter error \"%s\"\n", sigopt);
+ ERR_print_errors(bio_err);
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
+ STACK_OF(OPENSSL_STRING) *sigopts)
+ {
+ int rv;
+ EVP_MD_CTX mctx;
+ EVP_MD_CTX_init(&mctx);
+ rv = do_sign_init(err, &mctx, pkey, md, sigopts);
+ if (rv > 0)
+ rv = X509_sign_ctx(x, &mctx);
+ EVP_MD_CTX_cleanup(&mctx);
+ return rv > 0 ? 1 : 0;
+ }
+
+
+int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
+ STACK_OF(OPENSSL_STRING) *sigopts)
+ {
+ int rv;
+ EVP_MD_CTX mctx;
+ EVP_MD_CTX_init(&mctx);
+ rv = do_sign_init(err, &mctx, pkey, md, sigopts);
+ if (rv > 0)
+ rv = X509_REQ_sign_ctx(x, &mctx);
+ EVP_MD_CTX_cleanup(&mctx);
+ return rv > 0 ? 1 : 0;
+ }
+
+
+
+int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
+ STACK_OF(OPENSSL_STRING) *sigopts)
+ {
+ int rv;
+ EVP_MD_CTX mctx;
+ EVP_MD_CTX_init(&mctx);
+ rv = do_sign_init(err, &mctx, pkey, md, sigopts);
+ if (rv > 0)
+ rv = X509_CRL_sign_ctx(x, &mctx);
+ EVP_MD_CTX_cleanup(&mctx);
+ return rv > 0 ? 1 : 0;
+ }
+
+
diff --git a/deps/openssl/openssl/apps/req.pem b/deps/openssl/openssl/apps/req.pem
new file mode 100644
index 000000000..5537df601
--- /dev/null
+++ b/deps/openssl/openssl/apps/req.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBlzCCAVcCAQAwXjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
+ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMORXJp
+YyB0aGUgWW91bmcwge8wgaYGBSsOAwIMMIGcAkEA+ZiKEvZmc9MtnaFZh4NiZ3oZ
+S4J1PHvPrm9MXj5ntVheDPkdmBDTncyaGAJcMjwsyB/GvLDGd6yGCw/8eF+09wIV
+AK3VagOxGd/Q4Af5NbxR5FB7CXEjAkA2t/q7HgVLi0KeKvcDG8BRl3wuy7bCvpjg
+tWiJc/tpvcuzeuAayH89UofjAGueKjXDADiRffvSdhrNw5dkqdqlA0QAAkEAtUSo
+84OekjitKGVjxLu0HvXck29pu+foad53vPKXAsuJdACj88BPqZ91Y9PIJf1GUh38
+CuiHWi7z3cEDfZCyCKAAMAkGBSsOAwIbBQADLwAwLAIUTg8amKVBE9oqC5B75dDQ
+Chy3LdQCFHKodGEj3LjuTzdm/RTe2KZL9Uzf
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/openssl/openssl/apps/rsa.c b/deps/openssl/openssl/apps/rsa.c
new file mode 100644
index 000000000..a17708fe9
--- /dev/null
+++ b/deps/openssl/openssl/apps/rsa.c
@@ -0,0 +1,450 @@
+/* apps/rsa.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_RSA
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/bn.h>
+
+#undef PROG
+#define PROG rsa_main
+
+/* -inform arg - input format - default PEM (one of DER, NET or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ * -des - encrypt output if PEM format with DES in cbc mode
+ * -des3 - encrypt output if PEM format
+ * -idea - encrypt output if PEM format
+ * -seed - encrypt output if PEM format
+ * -aes128 - encrypt output if PEM format
+ * -aes192 - encrypt output if PEM format
+ * -aes256 - encrypt output if PEM format
+ * -camellia128 - encrypt output if PEM format
+ * -camellia192 - encrypt output if PEM format
+ * -camellia256 - encrypt output if PEM format
+ * -text - print a text version
+ * -modulus - print the RSA key modulus
+ * -check - verify key consistency
+ * -pubin - Expect a public key in input file.
+ * -pubout - Output a public key.
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ int ret=1;
+ RSA *rsa=NULL;
+ int i,badops=0, sgckey=0;
+ const EVP_CIPHER *enc=NULL;
+ BIO *out=NULL;
+ int informat,outformat,text=0,check=0,noout=0;
+ int pubin = 0, pubout = 0;
+ char *infile,*outfile,*prog;
+ char *passargin = NULL, *passargout = NULL;
+ char *passin = NULL, *passout = NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+ int modulus=0;
+
+ int pvk_encr = 2;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ infile=NULL;
+ outfile=NULL;
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-passin") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargin= *(++argv);
+ }
+ else if (strcmp(*argv,"-passout") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargout= *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-sgckey") == 0)
+ sgckey=1;
+ else if (strcmp(*argv,"-pubin") == 0)
+ pubin=1;
+ else if (strcmp(*argv,"-pubout") == 0)
+ pubout=1;
+ else if (strcmp(*argv,"-RSAPublicKey_in") == 0)
+ pubin = 2;
+ else if (strcmp(*argv,"-RSAPublicKey_out") == 0)
+ pubout = 2;
+ else if (strcmp(*argv,"-pvk-strong") == 0)
+ pvk_encr=2;
+ else if (strcmp(*argv,"-pvk-weak") == 0)
+ pvk_encr=1;
+ else if (strcmp(*argv,"-pvk-none") == 0)
+ pvk_encr=0;
+ else if (strcmp(*argv,"-noout") == 0)
+ noout=1;
+ else if (strcmp(*argv,"-text") == 0)
+ text=1;
+ else if (strcmp(*argv,"-modulus") == 0)
+ modulus=1;
+ else if (strcmp(*argv,"-check") == 0)
+ check=1;
+ else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+ BIO_printf(bio_err,"where options are\n");
+ BIO_printf(bio_err," -inform arg input format - one of DER NET PEM\n");
+ BIO_printf(bio_err," -outform arg output format - one of DER NET PEM\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -sgckey Use IIS SGC key format\n");
+ BIO_printf(bio_err," -passin arg input file pass phrase source\n");
+ BIO_printf(bio_err," -out arg output file\n");
+ BIO_printf(bio_err," -passout arg output file pass phrase source\n");
+ BIO_printf(bio_err," -des encrypt PEM output with cbc des\n");
+ BIO_printf(bio_err," -des3 encrypt PEM output with ede cbc des using 168 bit key\n");
+#ifndef OPENSSL_NO_IDEA
+ BIO_printf(bio_err," -idea encrypt PEM output with cbc idea\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+ BIO_printf(bio_err," -seed encrypt PEM output with cbc seed\n");
+#endif
+#ifndef OPENSSL_NO_AES
+ BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
+ BIO_printf(bio_err," encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
+ BIO_printf(bio_err," encrypt PEM output with cbc camellia\n");
+#endif
+ BIO_printf(bio_err," -text print the key in text\n");
+ BIO_printf(bio_err," -noout don't print key out\n");
+ BIO_printf(bio_err," -modulus print the RSA key modulus\n");
+ BIO_printf(bio_err," -check verify key consistency\n");
+ BIO_printf(bio_err," -pubin expect a public key in input file\n");
+ BIO_printf(bio_err," -pubout output a public key\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
+#endif
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
+ BIO_printf(bio_err, "Error getting passwords\n");
+ goto end;
+ }
+
+ if(check && pubin) {
+ BIO_printf(bio_err, "Only private keys can be checked\n");
+ goto end;
+ }
+
+ out=BIO_new(BIO_s_file());
+
+ {
+ EVP_PKEY *pkey;
+
+ if (pubin)
+ {
+ int tmpformat=-1;
+ if (pubin == 2)
+ {
+ if (informat == FORMAT_PEM)
+ tmpformat = FORMAT_PEMRSA;
+ else if (informat == FORMAT_ASN1)
+ tmpformat = FORMAT_ASN1RSA;
+ }
+ else if (informat == FORMAT_NETSCAPE && sgckey)
+ tmpformat = FORMAT_IISSGC;
+ else
+ tmpformat = informat;
+
+ pkey = load_pubkey(bio_err, infile, tmpformat, 1,
+ passin, e, "Public Key");
+ }
+ else
+ pkey = load_key(bio_err, infile,
+ (informat == FORMAT_NETSCAPE && sgckey ?
+ FORMAT_IISSGC : informat), 1,
+ passin, e, "Private Key");
+
+ if (pkey != NULL)
+ rsa = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ }
+
+ if (rsa == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ if (text)
+ if (!RSA_print(out,rsa,0))
+ {
+ perror(outfile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (modulus)
+ {
+ BIO_printf(out,"Modulus=");
+ BN_print(out,rsa->n);
+ BIO_printf(out,"\n");
+ }
+
+ if (check)
+ {
+ int r = RSA_check_key(rsa);
+
+ if (r == 1)
+ BIO_printf(out,"RSA key ok\n");
+ else if (r == 0)
+ {
+ unsigned long err;
+
+ while ((err = ERR_peek_error()) != 0 &&
+ ERR_GET_LIB(err) == ERR_LIB_RSA &&
+ ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&
+ ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE)
+ {
+ BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err));
+ ERR_get_error(); /* remove e from error stack */
+ }
+ }
+
+ if (r == -1 || ERR_peek_error() != 0) /* should happen only if r == -1 */
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (noout)
+ {
+ ret = 0;
+ goto end;
+ }
+ BIO_printf(bio_err,"writing RSA key\n");
+ if (outformat == FORMAT_ASN1) {
+ if(pubout || pubin)
+ {
+ if (pubout == 2)
+ i=i2d_RSAPublicKey_bio(out,rsa);
+ else
+ i=i2d_RSA_PUBKEY_bio(out,rsa);
+ }
+ else i=i2d_RSAPrivateKey_bio(out,rsa);
+ }
+#ifndef OPENSSL_NO_RC4
+ else if (outformat == FORMAT_NETSCAPE)
+ {
+ unsigned char *p,*pp;
+ int size;
+
+ i=1;
+ size=i2d_RSA_NET(rsa,NULL,NULL, sgckey);
+ if ((p=(unsigned char *)OPENSSL_malloc(size)) == NULL)
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ goto end;
+ }
+ pp=p;
+ i2d_RSA_NET(rsa,&p,NULL, sgckey);
+ BIO_write(out,(char *)pp,size);
+ OPENSSL_free(pp);
+ }
+#endif
+ else if (outformat == FORMAT_PEM) {
+ if(pubout || pubin)
+ {
+ if (pubout == 2)
+ i=PEM_write_bio_RSAPublicKey(out,rsa);
+ else
+ i=PEM_write_bio_RSA_PUBKEY(out,rsa);
+ }
+ else i=PEM_write_bio_RSAPrivateKey(out,rsa,
+ enc,NULL,0,NULL,passout);
+#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
+ } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
+ EVP_PKEY *pk;
+ pk = EVP_PKEY_new();
+ EVP_PKEY_set1_RSA(pk, rsa);
+ if (outformat == FORMAT_PVK)
+ i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
+ else if (pubin || pubout)
+ i = i2b_PublicKey_bio(out, pk);
+ else
+ i = i2b_PrivateKey_bio(out, pk);
+ EVP_PKEY_free(pk);
+#endif
+ } else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (i <= 0)
+ {
+ BIO_printf(bio_err,"unable to write key\n");
+ ERR_print_errors(bio_err);
+ }
+ else
+ ret=0;
+end:
+ if(out != NULL) BIO_free_all(out);
+ if(rsa != NULL) RSA_free(rsa);
+ if(passin) OPENSSL_free(passin);
+ if(passout) OPENSSL_free(passout);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/rsa8192.pem b/deps/openssl/openssl/apps/rsa8192.pem
new file mode 100644
index 000000000..946a6e543
--- /dev/null
+++ b/deps/openssl/openssl/apps/rsa8192.pem
@@ -0,0 +1,101 @@
+-----BEGIN RSA PRIVATE KEY-----
+
+MIISKAIBAAKCBAEAiQ2f1X6Bte1DKD0OoCBKEikzPW+5w3oXk3WwnE97Wxzy6wJZ
+ebbZC3CZKKBnJeBMrysPf+lK+9+fP6Vm8bp1wvbcSIA59BDrX6irFSuM/bdnkbuF
+MFlDjt+uVrxwoyqfPi2IPot1HQg3l5mdyBqcTWvbOnU2L9HZxJfPUCjfzdTMPrMY
+55/A20XL7tlV2opEfwhy3uVlveQBM0DnZ3MUQfrk+lRRNWv7yE4ScbOfER9fjvOm
+yJc3ZbOa3e+AMGGU9OqJ/fyOl0SGYyP2k23omy/idBV4uOs8QWdnAvq8UOzDdua3
+tuf5Tn17XBurPJ8juwyPBNispkwwn8BjxAZVPhwUIcxFBg339IxJ9cW0WdVy4nNA
+LWo/8Ahlf+kZNnFNGCPFytU9gGMLMhab9w/rLrwa9qNe4L8Fmu1JxONn1WfhMOKE
+aFmycf2olJsYLgUIGYZrjnYu0p/7P3yhTOv8JIhmK+SzmA/I0xiQoF84rpaQzH2d
+PvxICOA9oQSowou0gLuBSZWm6LiXirg1DZCziU46v33ErQlWM1dSyNaUSzihcV59
+mVD0nmzboXH75lGiyiZlp8cLbozzoCwvk9rYqpUGSBzbAy0ECCpabGpzO2Ug+oDi
+71e5z4WMpeoR4IS8MaOG/GsJnwaXhiB/gNYfK+8pRADVk5StEAZDE2alSuCbDs0z
+d9zYr4/em5T9VZsLetxRE7pm/Es9yELuViz8/Tm0/8MVdmNYc/xZU1t6qYYFdyQ2
+wlGDTiNPsjR8yXCkmBjKwqnuleu1X6LaZu3VPhEkXGcyFAquQUkSiMv0Yu74qAe0
+bQ2v+jjZzP6AM9LUo89cW4Kd8SGD96BdNlAVPNMXoBcIOsZBwsOtETBd4KAyvkXE
+Ob17u+PLl4UPnSxm9ypKZunUNFRPxtKUyjySYnvlGL+kTjAXrIrZwKJqIn0uhnfa
+Ck3o7bU6yVMK22ODxy2/Vi3E0P6k5JLwnrF0VIOBqGhts66qo6mWDP8l6MZHARFd
+pU+nofssVmr8tLKmMmjYGMM5GmKIXRNBs0ksTwFnKRs9AmpE5owC8tTSVdTAkGuS
+os7QwLvyvNzq7BGJiVr0Iy3Dhsl1vzR35acNOrCsDl3DcCQONKJ2sVXV4pD3dBah
+mG3sR/jHgjasffJJ35uiGoAua9dbT7HG/+D0z1SHYaVqH8zO4VZSOnGJh/P9rtxx
+cckFDbiag/JMWig2lbnCjebTtp/BcUsK3TNaDOb7vb0LvbAeRJadd1EFu6PSlH3K
+LykSUPm4UedvUU3cWjqkSY5lITFJkVaIYOv/EljYtK7p7kFZFTaEwMAWxgsXU3pQ
+tTzVmq1gZ4vXPwcUq0zK50Frq0F7SQc21ZsunwIDAQABAoIEADuQAkDEpBausJsS
+PgL1RXuzECPJJJCBxTE+2qx0FoY4hJICCWTORHGmU8nGPE3Ht0wBiNDsULw6KXl9
+psmzYW6D3qRbpdQebky6fu/KZ5H0XTyGpJGomaXELH5hkwo2gdKB805LSXB+m7p0
+9o96kSdMkpBLVGtf5iZ8W4rY2LsZmlI9f7taQHSLVt/M8HTz1mTnBRU92QO3zZW6
+xVa+OrWaFl18u3ZeIaSh2X40tBK68cqstXVD0r2OWuXNKobcQeJW8/XABzBShZ0c
+ihL0lzyqiN4uXrLu+Nbr22b+FU2OODy6dGk3U6/69NvI4piMCPlHsfhHOnFjd1ZW
+RIVywyUlCtLNdcn11CchuRro+0J3c2Ba+i9Cl9r3qzT11xFEGF8/XLyUBBCB+uGf
+1dR/xJQhCA7cXWWLXyI/semxcvTaGpImP6kiIl1MAjHjXZTSdvyw4JmfXyYGhSjI
+P0mw3Xn7FXxJ/os9gOfNKz2nZHjr0q4sgWRYO+4vllkeL0GteZrg4oVaVpmZb7LH
+77afhodLylhijlEtV5skfkPujbBLQk6E5Ez3U/huEt2NLg6guADmwxMxfBRliZO4
+4Ex/td4cuggpEj3FGJV74qRvdvj/MF/uF7IxC/3WapPIsFBFH4zrJsUYt6u3L68I
+/KC/bfioDeUR/8ANw1DNh+UsnPV3GJIwDkIJKdppi2uXPahJyJQQ8Inps53nn8Gg
+GifS+HnOXNgMoKOJnZ9IDGjXpfjIs8dJNrGfDHF0mH30N2WARq2v/a3cNUC+f8Bq
+HSKQ9YrZopktMunsut8u7ZYbTmjIqJpXCaM0CCrSlzSMTDHFSj2tzLk6+qnxeGxB
+ZwIdShbdeK+0ETG91lE1e9RPQs/uXQP9+uCHJV0YpqQcA6pkCLYJfYpoSMu/Bafy
+AgfVZz6l5tyEnV0wCcbopsQShc1k9xtTbYNF1h9AQHknj6zeDW4iZMvmVeh3RovT
+52OA2R8oLyauF+QaG6x2wUjEx13SJlaBarJZ4seZIOJ+a8+oNzKsbgokXc2cyC9p
+5FAZz1OsOb68o93qD1Xvl7bY97fq2q55L7G1XHPPLtZE5lGiLGDtnAuwY8UPrdpr
+7Mv2yIxB7xVGurXyHb5PvusR88XED6HMPfLBG/55ENHTal7G5mRix+IWSBAIkxA5
+KZ0j8r5Ng4+wELZhqFQai39799bIAyiV6CEz4kyDXlo0kSSexp8o4iz5sPq5vp6h
+cCb7rdRw7uRnbXrHmXahxoB+ibXaurgV/6B2yurrU/UFoxEp2sHp8LXZGfF6ztY1
+dMhSQAACK2vGy5yNagbkTHLgVaHicG5zavJBqzCE+lbPlCqhOUQPdOIwvjHNjdS/
+DL3WV/ECggIBAMbW65wPk/i43nSyeZeYwcHtR1SUJqDXavYfBPC0VRhKz+7DVMFw
+Nwnocn6gITABc445W1yl7U3uww+LGuDlSlFnd8WuiXpVYud9/jeNu6Mu4wvNsnWr
+f4f4ua8CcS03GmqmcbROD2Z6by1AblCZ2UL1kv9cUX1FLVjPP1ESAGKoePt3BmZQ
+J1uJfK8HilNT8dcUlj/5CBi2uHxttDhoG0sxXE/SVsG9OD/Pjme0mj7gdzc6Ztd+
+TALuvpNQR4pRzfo5XWDZBcEYntcEE3PxYJB1+vnZ8509ew5/yLHTbLjFxIcx71zY
+fhH0gM36Sz7mz37r0+E/QkRkc5bVIDC4LDnWmjpAde6QUx0d218ShNx6sJo4kt5c
+Dd7tEVx8nuX8AIZYgwsOb382anLyFRkkmEdK3gRvwQ6SWR36Ez5L7/mHWODpLAX5
+mVBKSG4/ccFbc633/g0xHw0Nwajir/klckdakuYPlwF0yAxJSKDLhmNctDhRmxjC
+YP+fISkl5oTvFRzJH6HEyNu8M3ybRvmpPIjM5J5JpnB2IYbohYBR+T6/97C1DKrd
+mzL5PjlrWm0c1/d7LlDoP65fOShDMmj2zCiBAHHOM0Alokx+v5LmMd8NJumZIwGJ
+Rt5OpeMOhowz6j1AjYxYgV7PmJL6Ovpfb775od/aLaUbbwHz2uWIvfF7AoICAQCw
+c7NaO7oJVLJClhYw6OCvjT6oqtgNVWaennnDiJgzY9lv5HEgV0MAG0eYuB3hvj+w
+Y1P9DJxP1D+R+cshYrAFg8yU/3kaYVNI0Bl3ygX0eW1b/0HZTdocs+8kM/9PZQDR
+WrKQoU5lHvqRt99dXlD4NWGI2YQtzdZ8iet9QLqnjwRZabgE96mF01qKisMnFcsh
+KjT7ieheU4J15TZj/mdZRNK126d7e3q/rNj73e5EJ9tkYLcolSr4gpknUMJULSEi
+JH1/Qx7C/mTAMRsN5SkOthnGq0djCNWfPv/3JV0H67Uf5krFlnwLebrgfTYoPPdo
+yO7iBUNJzv6Qh22malLp4P8gzACkD7DGlSTnoB5cLwcjmDGg+i9WrUBbOiVTeQfZ
+kOj1o+Tz35ndpq/DDUVlqliB9krcxva+QHeJPH53EGI+YVg1nD+s/vUDZ3mQMGX9
+DQou2L8uU6RnWNv/BihGcL8QvS4Ty6QyPOUPpD3zc70JQAEcQk9BxQNaELgJX0IN
+22cYn22tYvElew9G41OpDqzBRcfbdJmKXQ2HcroShutYJQRGUpAXHk24fy6JVkIU
+ojF5U6cwextMja1ZIIZgh9eugIRUeIE7319nQNDzuXWjRCcoBLA25P7wnpHWDRpz
+D9ovXCIvdja74lL5psqobV6L5+fbLPkSgXoImKR0LQKCAgAIC9Jk8kxumCyIVGCP
+PeM5Uby9M3GMuKrfYsn0Y5e97+kSJF1dpojTodBgR2KQar6eVrvXt+8uZCcIjfx8
+dUrYmHNEUJfHl4T1ESgkX1vkcpVFeQFruZDjk7EP3+1sgvpSroGTZkVBRFsTXbQZ
+FuCv0Pgt1TKG+zGmklxhj3TsiRy8MEjWAxBUp++ftZJnZNI4feDGnfEx7tLwVhAg
+6DWSiWDO6hgQpvOLwX5lu+0x9itc1MQsnDO/OqIDnBAJDN5k7cVVkfKlqbVjxgpz
+eqUJs3yAd81f44kDQTCB4ahYocgeIGsrOqd/WoGL1EEPPo/O9wQP7VtlIRt8UwuG
+bS18+a4sBUfAa56xYu/pnPo7YcubsgZfcSIujzFQqMpVTClJRnOnEuJ4J1+PXzRz
+XAO9fs4VJ+CMEmgAyonUz4Xadxulnknlw//sO9VKgM69oFHCDHL/XamAAbqAdwvf
+7R/+uy+Ol7romC0wMhb6SsIZazrvvH2mNtduAKZ638nAP1x/WbQp+6iVG7yJok7w
+82Q7tO7baOePTXh12Rrt4mNPor0HLYxhra4GFgfqkumJ2Mz0esuZAozxJXFOq8ly
+beo9CVtXP5zbT6qNpeNismX6PLICaev8t+1iOZSE56WSLtefuuj/cOVrTMNDz1Rr
+pUkEVV2zjUSjlcScM538A9iL2QKCAgBLbBk0r6T0ihRsK9UucMxhnYEz/Vq+UEu9
+70Vi1AciqEJv9nh4d3Q3HnH7EHANZxG4Jqzm1DYYVUQa9GfkTFeq88xFv/GW2hUM
+YY8RSfRDrIeXNEOETCe37x2AHw25dRXlZtw+wARPau91y9+Y/FCl18NqCHfcUEin
+ERjsf/eI2bPlODAlR2tZvZ7M60VBdqpN8cmV3zvI3e88z43xLfQlDyr1+v7a5Evy
+lEJnXlSTI2o+vKxtl103vjMSwA1gh63K90gBVsJWXQDZueOzi8mB9UqNRfcMmOEe
+4YHttTXPxeu0x+4cCRfam9zKShsVFgI28vRQ/ijl6qmbQ5gV8wqf18GV1j1L4z0P
+lP6iVynDA4MMrug/w9DqPsHsfK0pwekeETfSj4y0xVXyjWZBfHG2ZBrS6mDTf+RG
+LC4sJgR0hjdILLnUqIX7PzuhieBHRrjBcopwvcryVWRHnI7kslAS0+yHjiWc5oW3
+x5mtlum4HzelNYuD9cAE/95P6CeSMfp9CyIE/KSX4VvsRm6gQVkoQRKMxnQIFQ3w
+O5gl1l88vhjoo2HxYScgCp70BsDwiUNTqIR3NM+ZBHYFweVf3Gwz5LzHZT2rEZtD
+6VXRP75Q/2wOLnqCO4bK4BUs6sqxcQZmOldruPkPynrY0oPfHHExjxZDvQu4/r80
+Ls3n0L8yvQKCAgEAnYWS6EikwaQNpJEfiUnOlglgFz4EE1eVkrDbBY4J3oPU+doz
+DrqmsvgpSZIAfd2MUbkN4pOMsMTjbeIYWDnZDa1RoctKs3FhwFPHwAjQpznab4mn
+Bp81FMHM40qyb0NaNuFRwghdXvoQvBBX1p8oEnFzDRvTiuS/vTPTA8KDY8IeRp8R
+oGzKHpfziNwq/URpqj7pwi9odNjGZvR2IwYw9jCLPIqaEbMoSOdI0mg4MoYyqP4q
+nm7d4wqSDwrYxiXZ6f3nYpkhEY1lb0Wbksp1ig8sKSF4nDZRGK1RSfE+6gjBp94H
+X/Wog6Zb6NC9ZpusTiDLvuIUXcyUJvmHiWjSNqiTv8jurlwEsgSwhziEQfqLrtdV
+QI3PRMolBkD1iCk+HFE53r05LMf1bp3r4MS+naaQrLbIrl1kgDNGwVdgS+SCM7Bg
+TwEgE67iOb2iIoUpon/NyP4LesMzvdpsu2JFlfz13PmmQ34mFI7tWvOb3NA5DP3c
+46C6SaWI0TD9B11nJbHGTYN3Si9n0EBgoDJEXUKeh3km9O47dgvkSug4WzhYsvrE
+rMlMLtKfp2w8HlMZpsUlToNCx6CI+tJrohzcs3BAVAbjFAXRKWGijB1rxwyDdHPv
+I+/wJTNaRNPQ1M0SwtEL/zJd21y3KSPn4eL+GP3efhlDSjtlDvZqkdAUsU8=
+-----END RSA PRIVATE KEY-----
+
diff --git a/deps/openssl/openssl/apps/rsautl.c b/deps/openssl/openssl/apps/rsautl.c
new file mode 100644
index 000000000..b01f004eb
--- /dev/null
+++ b/deps/openssl/openssl/apps/rsautl.c
@@ -0,0 +1,351 @@
+/* rsautl.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 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
+ * licensing@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).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_RSA
+
+#include "apps.h"
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+
+#define RSA_SIGN 1
+#define RSA_VERIFY 2
+#define RSA_ENCRYPT 3
+#define RSA_DECRYPT 4
+
+#define KEY_PRIVKEY 1
+#define KEY_PUBKEY 2
+#define KEY_CERT 3
+
+static void usage(void);
+
+#undef PROG
+
+#define PROG rsautl_main
+
+int MAIN(int argc, char **);
+
+int MAIN(int argc, char **argv)
+{
+ ENGINE *e = NULL;
+ BIO *in = NULL, *out = NULL;
+ char *infile = NULL, *outfile = NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine = NULL;
+#endif
+ char *keyfile = NULL;
+ char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
+ int keyform = FORMAT_PEM;
+ char need_priv = 0, badarg = 0, rev = 0;
+ char hexdump = 0, asn1parse = 0;
+ X509 *x;
+ EVP_PKEY *pkey = NULL;
+ RSA *rsa = NULL;
+ unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
+ char *passargin = NULL, *passin = NULL;
+ int rsa_inlen, rsa_outlen = 0;
+ int keysize;
+
+ int ret = 1;
+
+ argc--;
+ argv++;
+
+ if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+ ERR_load_crypto_strings();
+ OpenSSL_add_all_algorithms();
+ pad = RSA_PKCS1_PADDING;
+
+ while(argc >= 1)
+ {
+ if (!strcmp(*argv,"-in")) {
+ if (--argc < 1)
+ badarg = 1;
+ else
+ infile= *(++argv);
+ } else if (!strcmp(*argv,"-out")) {
+ if (--argc < 1)
+ badarg = 1;
+ else
+ outfile= *(++argv);
+ } else if(!strcmp(*argv, "-inkey")) {
+ if (--argc < 1)
+ badarg = 1;
+ else
+ keyfile = *(++argv);
+ } else if (!strcmp(*argv,"-passin")) {
+ if (--argc < 1)
+ badarg = 1;
+ else
+ passargin= *(++argv);
+ } else if (strcmp(*argv,"-keyform") == 0) {
+ if (--argc < 1)
+ badarg = 1;
+ else
+ keyform=str2fmt(*(++argv));
+#ifndef OPENSSL_NO_ENGINE
+ } else if(!strcmp(*argv, "-engine")) {
+ if (--argc < 1)
+ badarg = 1;
+ else
+ engine = *(++argv);
+#endif
+ } else if(!strcmp(*argv, "-pubin")) {
+ key_type = KEY_PUBKEY;
+ } else if(!strcmp(*argv, "-certin")) {
+ key_type = KEY_CERT;
+ }
+ else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1;
+ else if(!strcmp(*argv, "-hexdump")) hexdump = 1;
+ else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING;
+ else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING;
+ else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING;
+ else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING;
+ else if(!strcmp(*argv, "-x931")) pad = RSA_X931_PADDING;
+ else if(!strcmp(*argv, "-sign")) {
+ rsa_mode = RSA_SIGN;
+ need_priv = 1;
+ } else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY;
+ else if(!strcmp(*argv, "-rev")) rev = 1;
+ else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT;
+ else if(!strcmp(*argv, "-decrypt")) {
+ rsa_mode = RSA_DECRYPT;
+ need_priv = 1;
+ } else badarg = 1;
+ if(badarg) {
+ usage();
+ goto end;
+ }
+ argc--;
+ argv++;
+ }
+
+ if(need_priv && (key_type != KEY_PRIVKEY)) {
+ BIO_printf(bio_err, "A private key is needed for this operation\n");
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+ if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+/* FIXME: seed PRNG only if needed */
+ app_RAND_load_file(NULL, bio_err, 0);
+
+ switch(key_type) {
+ case KEY_PRIVKEY:
+ pkey = load_key(bio_err, keyfile, keyform, 0,
+ passin, e, "Private Key");
+ break;
+
+ case KEY_PUBKEY:
+ pkey = load_pubkey(bio_err, keyfile, keyform, 0,
+ NULL, e, "Public Key");
+ break;
+
+ case KEY_CERT:
+ x = load_cert(bio_err, keyfile, keyform,
+ NULL, e, "Certificate");
+ if(x) {
+ pkey = X509_get_pubkey(x);
+ X509_free(x);
+ }
+ break;
+ }
+
+ if(!pkey) {
+ return 1;
+ }
+
+ rsa = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+
+ if(!rsa) {
+ BIO_printf(bio_err, "Error getting RSA key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+
+ if(infile) {
+ if(!(in = BIO_new_file(infile, "rb"))) {
+ BIO_printf(bio_err, "Error Reading Input File\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ } else in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+ if(outfile) {
+ if(!(out = BIO_new_file(outfile, "wb"))) {
+ BIO_printf(bio_err, "Error Reading Output File\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ } else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+
+ keysize = RSA_size(rsa);
+
+ rsa_in = OPENSSL_malloc(keysize * 2);
+ rsa_out = OPENSSL_malloc(keysize);
+
+ /* Read the input data */
+ rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
+ if(rsa_inlen <= 0) {
+ BIO_printf(bio_err, "Error reading input Data\n");
+ exit(1);
+ }
+ if(rev) {
+ int i;
+ unsigned char ctmp;
+ for(i = 0; i < rsa_inlen/2; i++) {
+ ctmp = rsa_in[i];
+ rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
+ rsa_in[rsa_inlen - 1 - i] = ctmp;
+ }
+ }
+ switch(rsa_mode) {
+
+ case RSA_VERIFY:
+ rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+ break;
+
+ case RSA_SIGN:
+ rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+ break;
+
+ case RSA_ENCRYPT:
+ rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+ break;
+
+ case RSA_DECRYPT:
+ rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+ break;
+
+ }
+
+ if(rsa_outlen <= 0) {
+ BIO_printf(bio_err, "RSA operation error\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ ret = 0;
+ if(asn1parse) {
+ if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
+ ERR_print_errors(bio_err);
+ }
+ } else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen);
+ else BIO_write(out, rsa_out, rsa_outlen);
+ end:
+ RSA_free(rsa);
+ BIO_free(in);
+ BIO_free_all(out);
+ if(rsa_in) OPENSSL_free(rsa_in);
+ if(rsa_out) OPENSSL_free(rsa_out);
+ if(passin) OPENSSL_free(passin);
+ return ret;
+}
+
+static void usage()
+{
+ BIO_printf(bio_err, "Usage: rsautl [options]\n");
+ BIO_printf(bio_err, "-in file input file\n");
+ BIO_printf(bio_err, "-out file output file\n");
+ BIO_printf(bio_err, "-inkey file input key\n");
+ BIO_printf(bio_err, "-keyform arg private key format - default PEM\n");
+ BIO_printf(bio_err, "-pubin input is an RSA public\n");
+ BIO_printf(bio_err, "-certin input is a certificate carrying an RSA public key\n");
+ BIO_printf(bio_err, "-ssl use SSL v2 padding\n");
+ BIO_printf(bio_err, "-raw use no padding\n");
+ BIO_printf(bio_err, "-pkcs use PKCS#1 v1.5 padding (default)\n");
+ BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n");
+ BIO_printf(bio_err, "-sign sign with private key\n");
+ BIO_printf(bio_err, "-verify verify with public key\n");
+ BIO_printf(bio_err, "-encrypt encrypt with public key\n");
+ BIO_printf(bio_err, "-decrypt decrypt with private key\n");
+ BIO_printf(bio_err, "-hexdump hex dump output\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
+ BIO_printf (bio_err, "-passin arg pass phrase source\n");
+#endif
+
+}
+
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/deps/openssl/openssl/apps/s1024key.pem b/deps/openssl/openssl/apps/s1024key.pem
new file mode 100644
index 000000000..19e040357
--- /dev/null
+++ b/deps/openssl/openssl/apps/s1024key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQCzEfU8E+ZGTGtHXV5XhvM2Lg32fXUIjydXb34BGVPX6oN7+aNV
+S9eWayvW/+9/vUb0aCqilJrpFesgItV2T8VhhjOE++XUz46uNpcMU7wHMEAXUufP
+pztpFm8ZEk2tFKvadkSSoN8lb11juvZVkSkPlB65pFhSe4QKSp6J4HrkYwIDAQAB
+AoGBAKy8jvb0Lzby8q11yNLf7+78wCVdYi7ugMHcYA1JVFK8+zb1WfSm44FLQo/0
+dSChAjgz36TTexeLODPYxleJndjVcOMVzsLJjSM8dLpXsTS4FCeMbhw2s2u+xqKY
+bbPWfk+HOTyJjfnkcC5Nbg44eOmruq0gSmBeUXVM5UntlTnxAkEA7TGCA3h7kx5E
+Bl4zl2pc3gPAGt+dyfk5Po9mGJUUXhF5p2zueGmYWW74TmOWB1kzt4QRdYMzFePq
+zfDNXEa1CwJBAMFErdY0xp0UJ13WwBbUTk8rujqQdHtjw0klhpbuKkjxu2hN0wwM
+6p0D9qxF7JHaghqVRI0fAW/EE0OzdHMR9QkCQQDNR26dMFXKsoPu+vItljj/UEGf
+QG7gERiQ4yxaFBPHgdpGo0kT31eh9x9hQGDkxTe0GNG/YSgCRvm8+C3TMcKXAkBD
+dhGn36wkUFCddMSAM4NSJ1VN8/Z0y5HzCmI8dM3VwGtGMUQlxKxwOl30LEQzdS5M
+0SWojNYXiT2gOBfBwtbhAkEAhafl5QEOIgUz+XazS/IlZ8goNKdDVfYgK3mHHjvv
+nY5G+AuGebdNkXJr4KSWxDcN+C2i47zuj4QXA16MAOandA==
+-----END RSA PRIVATE KEY-----
diff --git a/deps/openssl/openssl/apps/s1024req.pem b/deps/openssl/openssl/apps/s1024req.pem
new file mode 100644
index 000000000..bb75e7eeb
--- /dev/null
+++ b/deps/openssl/openssl/apps/s1024req.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBojCCAQsCAQAwZDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx
+GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSQwIgYDVQQDExtTZXJ2ZXIgdGVz
+dCBjZXJ0ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALMR
+9TwT5kZMa0ddXleG8zYuDfZ9dQiPJ1dvfgEZU9fqg3v5o1VL15ZrK9b/73+9RvRo
+KqKUmukV6yAi1XZPxWGGM4T75dTPjq42lwxTvAcwQBdS58+nO2kWbxkSTa0Uq9p2
+RJKg3yVvXWO69lWRKQ+UHrmkWFJ7hApKnongeuRjAgMBAAEwDQYJKoZIhvcNAQEE
+BQADgYEAStHlk4pBbwiNeQ2/PKTPPXzITYC8Gn0XMbrU94e/6JIKiO7aArq9Espq
+nrBSvC14dHcNl6NNvnkEKdQ7hAkcACfBbnOXA/oQvMBd4GD78cH3k0jVDoVUEjil
+frLfWlckW6WzpTktt0ZPDdAjJCmKVh0ABHimi7Bo9FC3wIGIe5M=
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/openssl/openssl/apps/s512-key.pem b/deps/openssl/openssl/apps/s512-key.pem
new file mode 100644
index 000000000..0e3ff2d37
--- /dev/null
+++ b/deps/openssl/openssl/apps/s512-key.pem
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD
+TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu
+OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj
+gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz
+rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b
+PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA
+vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU=
+-----END RSA PRIVATE KEY-----
diff --git a/deps/openssl/openssl/apps/s512-req.pem b/deps/openssl/openssl/apps/s512-req.pem
new file mode 100644
index 000000000..ea314be55
--- /dev/null
+++ b/deps/openssl/openssl/apps/s512-req.pem
@@ -0,0 +1,8 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBGzCBxgIBADBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEa
+MBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0
+IGNlcnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8S
+MVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8E
+y2//Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAANBAAB+uQi+qwn6qRSHB8EUTvsm
+5TNTHzYDeN39nyIbZNX2s0se3Srn2Bxft5YCwD3moFZ9QoyDHxE0h6qLX5yjD+8=
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/openssl/openssl/apps/s_apps.h b/deps/openssl/openssl/apps/s_apps.h
new file mode 100644
index 000000000..820e5c581
--- /dev/null
+++ b/deps/openssl/openssl/apps/s_apps.h
@@ -0,0 +1,176 @@
+/* apps/s_apps.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+#if !defined(OPENSSL_SYS_NETWARE) /* conflicts with winsock2 stuff on netware */
+#include <sys/types.h>
+#endif
+#include <openssl/opensslconf.h>
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+#include <conio.h>
+#endif
+
+#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
+#define _kbhit kbhit
+#endif
+
+#if defined(OPENSSL_SYS_VMS) && !defined(FD_SET)
+/* VAX C does not defined fd_set and friends, but it's actually quite simple */
+/* These definitions are borrowed from SOCKETSHR. /Richard Levitte */
+#define MAX_NOFILE 32
+#define NBBY 8 /* number of bits in a byte */
+
+#ifndef FD_SETSIZE
+#define FD_SETSIZE MAX_NOFILE
+#endif /* FD_SETSIZE */
+
+/* How many things we'll allow select to use. 0 if unlimited */
+#define MAXSELFD MAX_NOFILE
+typedef int fd_mask; /* int here! VMS prototypes int, not long */
+#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask (power of 2!)*/
+#define NFDSHIFT 5 /* Shift based on above */
+
+typedef fd_mask fd_set;
+#define FD_SET(n, p) (*(p) |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) (*(p) &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) (*(p) & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) memset((char *)(p), 0, sizeof(*(p)))
+#endif
+
+#define PORT 4433
+#define PORT_STR "4433"
+#define PROTOCOL "tcp"
+
+int do_server(int port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context);
+#ifdef HEADER_X509_H
+int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
+#endif
+#ifdef HEADER_SSL_H
+int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
+int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key);
+#endif
+int init_client(int *sock, char *server, int port, int type);
+int should_retry(int i);
+int extract_port(char *str, short *port_ptr);
+int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p);
+
+long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
+ int argi, long argl, long ret);
+
+#ifdef HEADER_SSL_H
+void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret);
+void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
+void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
+ unsigned char *data, int len,
+ void *arg);
+#endif
+
+int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len);
+int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len);
diff --git a/deps/openssl/openssl/apps/s_cb.c b/deps/openssl/openssl/apps/s_cb.c
new file mode 100644
index 000000000..84c3b447c
--- /dev/null
+++ b/deps/openssl/openssl/apps/s_cb.c
@@ -0,0 +1,930 @@
+/* apps/s_cb.c - callback functions used by s_client, s_server, and s_time */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#define USE_SOCKETS
+#define NON_MAIN
+#include "apps.h"
+#undef NON_MAIN
+#undef USE_SOCKETS
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include "s_apps.h"
+
+#define COOKIE_SECRET_LENGTH 16
+
+int verify_depth=0;
+int verify_error=X509_V_OK;
+int verify_return_error=0;
+unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
+int cookie_initialized=0;
+
+int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
+ {
+ X509 *err_cert;
+ int err,depth;
+
+ err_cert=X509_STORE_CTX_get_current_cert(ctx);
+ err= X509_STORE_CTX_get_error(ctx);
+ depth= X509_STORE_CTX_get_error_depth(ctx);
+
+ BIO_printf(bio_err,"depth=%d ",depth);
+ if (err_cert)
+ {
+ X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
+ 0, XN_FLAG_ONELINE);
+ BIO_puts(bio_err, "\n");
+ }
+ else
+ BIO_puts(bio_err, "<no cert>\n");
+ if (!ok)
+ {
+ BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
+ X509_verify_cert_error_string(err));
+ if (verify_depth >= depth)
+ {
+ if (!verify_return_error)
+ ok=1;
+ verify_error=X509_V_OK;
+ }
+ else
+ {
+ ok=0;
+ verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ }
+ }
+ switch (err)
+ {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ BIO_puts(bio_err,"issuer= ");
+ X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
+ 0, XN_FLAG_ONELINE);
+ BIO_puts(bio_err, "\n");
+ break;
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ BIO_printf(bio_err,"notBefore=");
+ ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert));
+ BIO_printf(bio_err,"\n");
+ break;
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ BIO_printf(bio_err,"notAfter=");
+ ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert));
+ BIO_printf(bio_err,"\n");
+ break;
+ case X509_V_ERR_NO_EXPLICIT_POLICY:
+ policies_print(bio_err, ctx);
+ break;
+ }
+ if (err == X509_V_OK && ok == 2)
+ policies_print(bio_err, ctx);
+
+ BIO_printf(bio_err,"verify return:%d\n",ok);
+ return(ok);
+ }
+
+int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
+ {
+ if (cert_file != NULL)
+ {
+ /*
+ SSL *ssl;
+ X509 *x509;
+ */
+
+ if (SSL_CTX_use_certificate_file(ctx,cert_file,
+ SSL_FILETYPE_PEM) <= 0)
+ {
+ BIO_printf(bio_err,"unable to get certificate from '%s'\n",cert_file);
+ ERR_print_errors(bio_err);
+ return(0);
+ }
+ if (key_file == NULL) key_file=cert_file;
+ if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
+ SSL_FILETYPE_PEM) <= 0)
+ {
+ BIO_printf(bio_err,"unable to get private key from '%s'\n",key_file);
+ ERR_print_errors(bio_err);
+ return(0);
+ }
+
+ /*
+ In theory this is no longer needed
+ ssl=SSL_new(ctx);
+ x509=SSL_get_certificate(ssl);
+
+ if (x509 != NULL) {
+ EVP_PKEY *pktmp;
+ pktmp = X509_get_pubkey(x509);
+ EVP_PKEY_copy_parameters(pktmp,
+ SSL_get_privatekey(ssl));
+ EVP_PKEY_free(pktmp);
+ }
+ SSL_free(ssl);
+ */
+
+ /* If we are using DSA, we can copy the parameters from
+ * the private key */
+
+
+ /* Now we know that a key and cert have been set against
+ * the SSL context */
+ if (!SSL_CTX_check_private_key(ctx))
+ {
+ BIO_printf(bio_err,"Private key does not match the certificate public key\n");
+ return(0);
+ }
+ }
+ return(1);
+ }
+
+int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key)
+ {
+ if (cert == NULL)
+ return 1;
+ if (SSL_CTX_use_certificate(ctx,cert) <= 0)
+ {
+ BIO_printf(bio_err,"error setting certificate\n");
+ ERR_print_errors(bio_err);
+ return 0;
+ }
+ if (SSL_CTX_use_PrivateKey(ctx,key) <= 0)
+ {
+ BIO_printf(bio_err,"error setting private key\n");
+ ERR_print_errors(bio_err);
+ return 0;
+ }
+
+
+ /* Now we know that a key and cert have been set against
+ * the SSL context */
+ if (!SSL_CTX_check_private_key(ctx))
+ {
+ BIO_printf(bio_err,"Private key does not match the certificate public key\n");
+ return 0;
+ }
+ return 1;
+ }
+
+long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
+ int argi, long argl, long ret)
+ {
+ BIO *out;
+
+ out=(BIO *)BIO_get_callback_arg(bio);
+ if (out == NULL) return(ret);
+
+ if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
+ {
+ BIO_printf(out,"read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
+ (void *)bio,argp,(unsigned long)argi,ret,ret);
+ BIO_dump(out,argp,(int)ret);
+ return(ret);
+ }
+ else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
+ {
+ BIO_printf(out,"write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
+ (void *)bio,argp,(unsigned long)argi,ret,ret);
+ BIO_dump(out,argp,(int)ret);
+ }
+ return(ret);
+ }
+
+void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret)
+ {
+ const char *str;
+ int w;
+
+ w=where& ~SSL_ST_MASK;
+
+ if (w & SSL_ST_CONNECT) str="SSL_connect";
+ else if (w & SSL_ST_ACCEPT) str="SSL_accept";
+ else str="undefined";
+
+ if (where & SSL_CB_LOOP)
+ {
+ BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s));
+ }
+ else if (where & SSL_CB_ALERT)
+ {
+ str=(where & SSL_CB_READ)?"read":"write";
+ BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n",
+ str,
+ SSL_alert_type_string_long(ret),
+ SSL_alert_desc_string_long(ret));
+ }
+ else if (where & SSL_CB_EXIT)
+ {
+ if (ret == 0)
+ BIO_printf(bio_err,"%s:failed in %s\n",
+ str,SSL_state_string_long(s));
+ else if (ret < 0)
+ {
+ BIO_printf(bio_err,"%s:error in %s\n",
+ str,SSL_state_string_long(s));
+ }
+ }
+ }
+
+
+void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
+ {
+ BIO *bio = arg;
+ const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= "";
+
+ str_write_p = write_p ? ">>>" : "<<<";
+
+ switch (version)
+ {
+ case SSL2_VERSION:
+ str_version = "SSL 2.0";
+ break;
+ case SSL3_VERSION:
+ str_version = "SSL 3.0 ";
+ break;
+ case TLS1_VERSION:
+ str_version = "TLS 1.0 ";
+ break;
+ case TLS1_1_VERSION:
+ str_version = "TLS 1.1 ";
+ break;
+ case TLS1_2_VERSION:
+ str_version = "TLS 1.2 ";
+ break;
+ case DTLS1_VERSION:
+ str_version = "DTLS 1.0 ";
+ break;
+ case DTLS1_BAD_VER:
+ str_version = "DTLS 1.0 (bad) ";
+ break;
+ default:
+ str_version = "???";
+ }
+
+ if (version == SSL2_VERSION)
+ {
+ str_details1 = "???";
+
+ if (len > 0)
+ {
+ switch (((const unsigned char*)buf)[0])
+ {
+ case 0:
+ str_details1 = ", ERROR:";
+ str_details2 = " ???";
+ if (len >= 3)
+ {
+ unsigned err = (((const unsigned char*)buf)[1]<<8) + ((const unsigned char*)buf)[2];
+
+ switch (err)
+ {
+ case 0x0001:
+ str_details2 = " NO-CIPHER-ERROR";
+ break;
+ case 0x0002:
+ str_details2 = " NO-CERTIFICATE-ERROR";
+ break;
+ case 0x0004:
+ str_details2 = " BAD-CERTIFICATE-ERROR";
+ break;
+ case 0x0006:
+ str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR";
+ break;
+ }
+ }
+
+ break;
+ case 1:
+ str_details1 = ", CLIENT-HELLO";
+ break;
+ case 2:
+ str_details1 = ", CLIENT-MASTER-KEY";
+ break;
+ case 3:
+ str_details1 = ", CLIENT-FINISHED";
+ break;
+ case 4:
+ str_details1 = ", SERVER-HELLO";
+ break;
+ case 5:
+ str_details1 = ", SERVER-VERIFY";
+ break;
+ case 6:
+ str_details1 = ", SERVER-FINISHED";
+ break;
+ case 7:
+ str_details1 = ", REQUEST-CERTIFICATE";
+ break;
+ case 8:
+ str_details1 = ", CLIENT-CERTIFICATE";
+ break;
+ }
+ }
+ }
+
+ if (version == SSL3_VERSION ||
+ version == TLS1_VERSION ||
+ version == TLS1_1_VERSION ||
+ version == TLS1_2_VERSION ||
+ version == DTLS1_VERSION ||
+ version == DTLS1_BAD_VER)
+ {
+ switch (content_type)
+ {
+ case 20:
+ str_content_type = "ChangeCipherSpec";
+ break;
+ case 21:
+ str_content_type = "Alert";
+ break;
+ case 22:
+ str_content_type = "Handshake";
+ break;
+ }
+
+ if (content_type == 21) /* Alert */
+ {
+ str_details1 = ", ???";
+
+ if (len == 2)
+ {
+ switch (((const unsigned char*)buf)[0])
+ {
+ case 1:
+ str_details1 = ", warning";
+ break;
+ case 2:
+ str_details1 = ", fatal";
+ break;
+ }
+
+ str_details2 = " ???";
+ switch (((const unsigned char*)buf)[1])
+ {
+ case 0:
+ str_details2 = " close_notify";
+ break;
+ case 10:
+ str_details2 = " unexpected_message";
+ break;
+ case 20:
+ str_details2 = " bad_record_mac";
+ break;
+ case 21:
+ str_details2 = " decryption_failed";
+ break;
+ case 22:
+ str_details2 = " record_overflow";
+ break;
+ case 30:
+ str_details2 = " decompression_failure";
+ break;
+ case 40:
+ str_details2 = " handshake_failure";
+ break;
+ case 42:
+ str_details2 = " bad_certificate";
+ break;
+ case 43:
+ str_details2 = " unsupported_certificate";
+ break;
+ case 44:
+ str_details2 = " certificate_revoked";
+ break;
+ case 45:
+ str_details2 = " certificate_expired";
+ break;
+ case 46:
+ str_details2 = " certificate_unknown";
+ break;
+ case 47:
+ str_details2 = " illegal_parameter";
+ break;
+ case 48:
+ str_details2 = " unknown_ca";
+ break;
+ case 49:
+ str_details2 = " access_denied";
+ break;
+ case 50:
+ str_details2 = " decode_error";
+ break;
+ case 51:
+ str_details2 = " decrypt_error";
+ break;
+ case 60:
+ str_details2 = " export_restriction";
+ break;
+ case 70:
+ str_details2 = " protocol_version";
+ break;
+ case 71:
+ str_details2 = " insufficient_security";
+ break;
+ case 80:
+ str_details2 = " internal_error";
+ break;
+ case 90:
+ str_details2 = " user_canceled";
+ break;
+ case 100:
+ str_details2 = " no_renegotiation";
+ break;
+ case 110:
+ str_details2 = " unsupported_extension";
+ break;
+ case 111:
+ str_details2 = " certificate_unobtainable";
+ break;
+ case 112:
+ str_details2 = " unrecognized_name";
+ break;
+ case 113:
+ str_details2 = " bad_certificate_status_response";
+ break;
+ case 114:
+ str_details2 = " bad_certificate_hash_value";
+ break;
+ case 115:
+ str_details2 = " unknown_psk_identity";
+ break;
+ }
+ }
+ }
+
+ if (content_type == 22) /* Handshake */
+ {
+ str_details1 = "???";
+
+ if (len > 0)
+ {
+ switch (((const unsigned char*)buf)[0])
+ {
+ case 0:
+ str_details1 = ", HelloRequest";
+ break;
+ case 1:
+ str_details1 = ", ClientHello";
+ break;
+ case 2:
+ str_details1 = ", ServerHello";
+ break;
+ case 3:
+ str_details1 = ", HelloVerifyRequest";
+ break;
+ case 11:
+ str_details1 = ", Certificate";
+ break;
+ case 12:
+ str_details1 = ", ServerKeyExchange";
+ break;
+ case 13:
+ str_details1 = ", CertificateRequest";
+ break;
+ case 14:
+ str_details1 = ", ServerHelloDone";
+ break;
+ case 15:
+ str_details1 = ", CertificateVerify";
+ break;
+ case 16:
+ str_details1 = ", ClientKeyExchange";
+ break;
+ case 20:
+ str_details1 = ", Finished";
+ break;
+ }
+ }
+ }
+
+#ifndef OPENSSL_NO_HEARTBEATS
+ if (content_type == 24) /* Heartbeat */
+ {
+ str_details1 = ", Heartbeat";
+
+ if (len > 0)
+ {
+ switch (((const unsigned char*)buf)[0])
+ {
+ case 1:
+ str_details1 = ", HeartbeatRequest";
+ break;
+ case 2:
+ str_details1 = ", HeartbeatResponse";
+ break;
+ }
+ }
+ }
+#endif
+ }
+
+ BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, str_content_type, (unsigned long)len, str_details1, str_details2);
+
+ if (len > 0)
+ {
+ size_t num, i;
+
+ BIO_printf(bio, " ");
+ num = len;
+#if 0
+ if (num > 16)
+ num = 16;
+#endif
+ for (i = 0; i < num; i++)
+ {
+ if (i % 16 == 0 && i > 0)
+ BIO_printf(bio, "\n ");
+ BIO_printf(bio, " %02x", ((const unsigned char*)buf)[i]);
+ }
+ if (i < len)
+ BIO_printf(bio, " ...");
+ BIO_printf(bio, "\n");
+ }
+ (void)BIO_flush(bio);
+ }
+
+void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
+ unsigned char *data, int len,
+ void *arg)
+ {
+ BIO *bio = arg;
+ char *extname;
+
+ switch(type)
+ {
+ case TLSEXT_TYPE_server_name:
+ extname = "server name";
+ break;
+
+ case TLSEXT_TYPE_max_fragment_length:
+ extname = "max fragment length";
+ break;
+
+ case TLSEXT_TYPE_client_certificate_url:
+ extname = "client certificate URL";
+ break;
+
+ case TLSEXT_TYPE_trusted_ca_keys:
+ extname = "trusted CA keys";
+ break;
+
+ case TLSEXT_TYPE_truncated_hmac:
+ extname = "truncated HMAC";
+ break;
+
+ case TLSEXT_TYPE_status_request:
+ extname = "status request";
+ break;
+
+ case TLSEXT_TYPE_user_mapping:
+ extname = "user mapping";
+ break;
+
+ case TLSEXT_TYPE_client_authz:
+ extname = "client authz";
+ break;
+
+ case TLSEXT_TYPE_server_authz:
+ extname = "server authz";
+ break;
+
+ case TLSEXT_TYPE_cert_type:
+ extname = "cert type";
+ break;
+
+ case TLSEXT_TYPE_elliptic_curves:
+ extname = "elliptic curves";
+ break;
+
+ case TLSEXT_TYPE_ec_point_formats:
+ extname = "EC point formats";
+ break;
+
+ case TLSEXT_TYPE_srp:
+ extname = "SRP";
+ break;
+
+ case TLSEXT_TYPE_signature_algorithms:
+ extname = "signature algorithms";
+ break;
+
+ case TLSEXT_TYPE_use_srtp:
+ extname = "use SRTP";
+ break;
+
+ case TLSEXT_TYPE_heartbeat:
+ extname = "heartbeat";
+ break;
+
+ case TLSEXT_TYPE_session_ticket:
+ extname = "session ticket";
+ break;
+
+ case TLSEXT_TYPE_renegotiate:
+ extname = "renegotiation info";
+ break;
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ case TLSEXT_TYPE_opaque_prf_input:
+ extname = "opaque PRF input";
+ break;
+#endif
+#ifdef TLSEXT_TYPE_next_proto_neg
+ case TLSEXT_TYPE_next_proto_neg:
+ extname = "next protocol";
+ break;
+#endif
+
+ default:
+ extname = "unknown";
+ break;
+
+ }
+
+ BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
+ client_server ? "server": "client",
+ extname, type, len);
+ BIO_dump(bio, (char *)data, len);
+ (void)BIO_flush(bio);
+ }
+
+int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
+ {
+ unsigned char *buffer, result[EVP_MAX_MD_SIZE];
+ unsigned int length, resultlength;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in s4;
+#if OPENSSL_USE_IPV6
+ struct sockaddr_in6 s6;
+#endif
+ } peer;
+
+ /* Initialize a random secret */
+ if (!cookie_initialized)
+ {
+ if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH))
+ {
+ BIO_printf(bio_err,"error setting random cookie secret\n");
+ return 0;
+ }
+ cookie_initialized = 1;
+ }
+
+ /* Read peer information */
+ (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
+
+ /* Create buffer with peer's address and port */
+ length = 0;
+ switch (peer.sa.sa_family)
+ {
+ case AF_INET:
+ length += sizeof(struct in_addr);
+ length += sizeof(peer.s4.sin_port);
+ break;
+#if OPENSSL_USE_IPV6
+ case AF_INET6:
+ length += sizeof(struct in6_addr);
+ length += sizeof(peer.s6.sin6_port);
+ break;
+#endif
+ default:
+ OPENSSL_assert(0);
+ break;
+ }
+ buffer = OPENSSL_malloc(length);
+
+ if (buffer == NULL)
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ return 0;
+ }
+
+ switch (peer.sa.sa_family)
+ {
+ case AF_INET:
+ memcpy(buffer,
+ &peer.s4.sin_port,
+ sizeof(peer.s4.sin_port));
+ memcpy(buffer + sizeof(peer.s4.sin_port),
+ &peer.s4.sin_addr,
+ sizeof(struct in_addr));
+ break;
+#if OPENSSL_USE_IPV6
+ case AF_INET6:
+ memcpy(buffer,
+ &peer.s6.sin6_port,
+ sizeof(peer.s6.sin6_port));
+ memcpy(buffer + sizeof(peer.s6.sin6_port),
+ &peer.s6.sin6_addr,
+ sizeof(struct in6_addr));
+ break;
+#endif
+ default:
+ OPENSSL_assert(0);
+ break;
+ }
+
+ /* Calculate HMAC of buffer using the secret */
+ HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
+ buffer, length, result, &resultlength);
+ OPENSSL_free(buffer);
+
+ memcpy(cookie, result, resultlength);
+ *cookie_len = resultlength;
+
+ return 1;
+ }
+
+int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)
+ {
+ unsigned char *buffer, result[EVP_MAX_MD_SIZE];
+ unsigned int length, resultlength;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in s4;
+#if OPENSSL_USE_IPV6
+ struct sockaddr_in6 s6;
+#endif
+ } peer;
+
+ /* If secret isn't initialized yet, the cookie can't be valid */
+ if (!cookie_initialized)
+ return 0;
+
+ /* Read peer information */
+ (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
+
+ /* Create buffer with peer's address and port */
+ length = 0;
+ switch (peer.sa.sa_family)
+ {
+ case AF_INET:
+ length += sizeof(struct in_addr);
+ length += sizeof(peer.s4.sin_port);
+ break;
+#if OPENSSL_USE_IPV6
+ case AF_INET6:
+ length += sizeof(struct in6_addr);
+ length += sizeof(peer.s6.sin6_port);
+ break;
+#endif
+ default:
+ OPENSSL_assert(0);
+ break;
+ }
+ buffer = OPENSSL_malloc(length);
+
+ if (buffer == NULL)
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ return 0;
+ }
+
+ switch (peer.sa.sa_family)
+ {
+ case AF_INET:
+ memcpy(buffer,
+ &peer.s4.sin_port,
+ sizeof(peer.s4.sin_port));
+ memcpy(buffer + sizeof(peer.s4.sin_port),
+ &peer.s4.sin_addr,
+ sizeof(struct in_addr));
+ break;
+#if OPENSSL_USE_IPV6
+ case AF_INET6:
+ memcpy(buffer,
+ &peer.s6.sin6_port,
+ sizeof(peer.s6.sin6_port));
+ memcpy(buffer + sizeof(peer.s6.sin6_port),
+ &peer.s6.sin6_addr,
+ sizeof(struct in6_addr));
+ break;
+#endif
+ default:
+ OPENSSL_assert(0);
+ break;
+ }
+
+ /* Calculate HMAC of buffer using the secret */
+ HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
+ buffer, length, result, &resultlength);
+ OPENSSL_free(buffer);
+
+ if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0)
+ return 1;
+
+ return 0;
+ }
diff --git a/deps/openssl/openssl/apps/s_client.c b/deps/openssl/openssl/apps/s_client.c
new file mode 100644
index 000000000..3ba660560
--- /dev/null
+++ b/deps/openssl/openssl/apps/s_client.c
@@ -0,0 +1,2151 @@
+/* apps/s_client.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/e_os2.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+
+/* With IPv6, it looks like Digital has mixed up the proper order of
+ recursive header file inclusion, resulting in the compiler complaining
+ that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
+ is needed to have fileno() declared correctly... So let's define u_int */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
+#define __U_INT
+typedef unsigned int u_int;
+#endif
+
+#define USE_SOCKETS
+#include "apps.h"
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/ocsp.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_SRP
+#include <openssl/srp.h>
+#endif
+#include "s_apps.h"
+#include "timeouts.h"
+
+#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
+/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
+#undef FIONBIO
+#endif
+
+#if defined(OPENSSL_SYS_BEOS_R5)
+#include <fcntl.h>
+#endif
+
+#undef PROG
+#define PROG s_client_main
+
+/*#define SSL_HOST_NAME "www.netscape.com" */
+/*#define SSL_HOST_NAME "193.118.187.102" */
+#define SSL_HOST_NAME "localhost"
+
+/*#define TEST_CERT "client.pem" */ /* no default cert. */
+
+#undef BUFSIZZ
+#define BUFSIZZ 1024*8
+
+extern int verify_depth;
+extern int verify_error;
+extern int verify_return_error;
+
+#ifdef FIONBIO
+static int c_nbio=0;
+#endif
+static int c_Pause=0;
+static int c_debug=0;
+#ifndef OPENSSL_NO_TLSEXT
+static int c_tlsextdebug=0;
+static int c_status_req=0;
+#endif
+static int c_msg=0;
+static int c_showcerts=0;
+
+static char *keymatexportlabel=NULL;
+static int keymatexportlen=20;
+
+static void sc_usage(void);
+static void print_stuff(BIO *berr,SSL *con,int full);
+#ifndef OPENSSL_NO_TLSEXT
+static int ocsp_resp_cb(SSL *s, void *arg);
+#endif
+static BIO *bio_c_out=NULL;
+static int c_quiet=0;
+static int c_ign_eof=0;
+
+#ifndef OPENSSL_NO_PSK
+/* Default PSK identity and key */
+static char *psk_identity="Client_identity";
+/*char *psk_key=NULL; by default PSK is not used */
+
+static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
+ unsigned int max_identity_len, unsigned char *psk,
+ unsigned int max_psk_len)
+ {
+ unsigned int psk_len = 0;
+ int ret;
+ BIGNUM *bn=NULL;
+
+ if (c_debug)
+ BIO_printf(bio_c_out, "psk_client_cb\n");
+ if (!hint)
+ {
+ /* no ServerKeyExchange message*/
+ if (c_debug)
+ BIO_printf(bio_c_out,"NULL received PSK identity hint, continuing anyway\n");
+ }
+ else if (c_debug)
+ BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint);
+
+ /* lookup PSK identity and PSK key based on the given identity hint here */
+ ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity);
+ if (ret < 0 || (unsigned int)ret > max_identity_len)
+ goto out_err;
+ if (c_debug)
+ BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity, ret);
+ ret=BN_hex2bn(&bn, psk_key);
+ if (!ret)
+ {
+ BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key);
+ if (bn)
+ BN_free(bn);
+ return 0;
+ }
+
+ if ((unsigned int)BN_num_bytes(bn) > max_psk_len)
+ {
+ BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
+ max_psk_len, BN_num_bytes(bn));
+ BN_free(bn);
+ return 0;
+ }
+
+ psk_len=BN_bn2bin(bn, psk);
+ BN_free(bn);
+ if (psk_len == 0)
+ goto out_err;
+
+ if (c_debug)
+ BIO_printf(bio_c_out, "created PSK len=%d\n", psk_len);
+
+ return psk_len;
+ out_err:
+ if (c_debug)
+ BIO_printf(bio_err, "Error in PSK client callback\n");
+ return 0;
+ }
+#endif
+
+static void sc_usage(void)
+ {
+ BIO_printf(bio_err,"usage: s_client args\n");
+ BIO_printf(bio_err,"\n");
+ BIO_printf(bio_err," -host host - use -connect instead\n");
+ BIO_printf(bio_err," -port port - use -connect instead\n");
+ BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
+
+ BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n");
+ BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n");
+ BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
+ BIO_printf(bio_err," -key arg - Private key file to use, in cert file if\n");
+ BIO_printf(bio_err," not specified but cert file is.\n");
+ BIO_printf(bio_err," -keyform arg - key format (PEM or DER) PEM default\n");
+ BIO_printf(bio_err," -pass arg - private key file pass phrase source\n");
+ BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n");
+ BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n");
+ BIO_printf(bio_err," -reconnect - Drop and re-make the connection with the same Session-ID\n");
+ BIO_printf(bio_err," -pause - sleep(1) after each read(2) and write(2) system call\n");
+ BIO_printf(bio_err," -showcerts - show all certificates in the chain\n");
+ BIO_printf(bio_err," -debug - extra output\n");
+#ifdef WATT32
+ BIO_printf(bio_err," -wdebug - WATT-32 tcp debugging\n");
+#endif
+ BIO_printf(bio_err," -msg - Show protocol messages\n");
+ BIO_printf(bio_err," -nbio_test - more ssl protocol testing\n");
+ BIO_printf(bio_err," -state - print the 'ssl' states\n");
+#ifdef FIONBIO
+ BIO_printf(bio_err," -nbio - Run with non-blocking IO\n");
+#endif
+ BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n");
+ BIO_printf(bio_err," -quiet - no s_client output\n");
+ BIO_printf(bio_err," -ign_eof - ignore input eof (default when -quiet)\n");
+ BIO_printf(bio_err," -no_ign_eof - don't ignore input eof\n");
+#ifndef OPENSSL_NO_PSK
+ BIO_printf(bio_err," -psk_identity arg - PSK identity\n");
+ BIO_printf(bio_err," -psk arg - PSK in hex (without 0x)\n");
+# ifndef OPENSSL_NO_JPAKE
+ BIO_printf(bio_err," -jpake arg - JPAKE secret to use\n");
+# endif
+#endif
+#ifndef OPENSSL_NO_SRP
+ BIO_printf(bio_err," -srpuser user - SRP authentification for 'user'\n");
+ BIO_printf(bio_err," -srppass arg - password for 'user'\n");
+ BIO_printf(bio_err," -srp_lateuser - SRP username into second ClientHello message\n");
+ BIO_printf(bio_err," -srp_moregroups - Tolerate other than the known g N values.\n");
+ BIO_printf(bio_err," -srp_strength int - minimal mength in bits for N (default %d).\n",SRP_MINIMAL_N);
+#endif
+ BIO_printf(bio_err," -ssl2 - just use SSLv2\n");
+ BIO_printf(bio_err," -ssl3 - just use SSLv3\n");
+ BIO_printf(bio_err," -tls1_2 - just use TLSv1.2\n");
+ BIO_printf(bio_err," -tls1_1 - just use TLSv1.1\n");
+ BIO_printf(bio_err," -tls1 - just use TLSv1\n");
+ BIO_printf(bio_err," -dtls1 - just use DTLSv1\n");
+ BIO_printf(bio_err," -mtu - set the link layer MTU\n");
+ BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
+ BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n");
+ BIO_printf(bio_err," -serverpref - Use server's cipher preferences (only SSLv2)\n");
+ BIO_printf(bio_err," -cipher - preferred cipher to use, use the 'openssl ciphers'\n");
+ BIO_printf(bio_err," command to see what is available\n");
+ BIO_printf(bio_err," -starttls prot - use the STARTTLS command before starting TLS\n");
+ BIO_printf(bio_err," for those protocols that support it, where\n");
+ BIO_printf(bio_err," 'prot' defines which one to assume. Currently,\n");
+ BIO_printf(bio_err," only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n");
+ BIO_printf(bio_err," are supported.\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n");
+#endif
+ BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err," -sess_out arg - file to write SSL session to\n");
+ BIO_printf(bio_err," -sess_in arg - file to read SSL session from\n");
+#ifndef OPENSSL_NO_TLSEXT
+ BIO_printf(bio_err," -servername host - Set TLS extension servername in ClientHello\n");
+ BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
+ BIO_printf(bio_err," -status - request certificate status from server\n");
+ BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
+# ifndef OPENSSL_NO_NEXTPROTONEG
+ BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
+# endif
+#endif
+ BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
+#ifndef OPENSSL_NO_SRTP
+ BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
+#endif
+ BIO_printf(bio_err," -keymatexport label - Export keying material using label\n");
+ BIO_printf(bio_err," -keymatexportlen len - Export len bytes of keying material (default 20)\n");
+ }
+
+#ifndef OPENSSL_NO_TLSEXT
+
+/* This is a context that we pass to callbacks */
+typedef struct tlsextctx_st {
+ BIO * biodebug;
+ int ack;
+} tlsextctx;
+
+
+static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
+ {
+ tlsextctx * p = (tlsextctx *) arg;
+ const char * hn= SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+ if (SSL_get_servername_type(s) != -1)
+ p->ack = !SSL_session_reused(s) && hn != NULL;
+ else
+ BIO_printf(bio_err,"Can't use SSL_get_servername\n");
+
+ return SSL_TLSEXT_ERR_OK;
+ }
+
+#ifndef OPENSSL_NO_SRP
+
+/* This is a context that we pass to all callbacks */
+typedef struct srp_arg_st
+ {
+ char *srppassin;
+ char *srplogin;
+ int msg; /* copy from c_msg */
+ int debug; /* copy from c_debug */
+ int amp; /* allow more groups */
+ int strength /* minimal size for N */ ;
+ } SRP_ARG;
+
+#define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
+
+static int srp_Verify_N_and_g(BIGNUM *N, BIGNUM *g)
+ {
+ BN_CTX *bn_ctx = BN_CTX_new();
+ BIGNUM *p = BN_new();
+ BIGNUM *r = BN_new();
+ int ret =
+ g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
+ BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
+ p != NULL && BN_rshift1(p, N) &&
+
+ /* p = (N-1)/2 */
+ BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
+ r != NULL &&
+
+ /* verify g^((N-1)/2) == -1 (mod N) */
+ BN_mod_exp(r, g, p, N, bn_ctx) &&
+ BN_add_word(r, 1) &&
+ BN_cmp(r, N) == 0;
+
+ if(r)
+ BN_free(r);
+ if(p)
+ BN_free(p);
+ if(bn_ctx)
+ BN_CTX_free(bn_ctx);
+ return ret;
+ }
+
+/* This callback is used here for two purposes:
+ - extended debugging
+ - making some primality tests for unknown groups
+ The callback is only called for a non default group.
+
+ An application does not need the call back at all if
+ only the stanard groups are used. In real life situations,
+ client and server already share well known groups,
+ thus there is no need to verify them.
+ Furthermore, in case that a server actually proposes a group that
+ is not one of those defined in RFC 5054, it is more appropriate
+ to add the group to a static list and then compare since
+ primality tests are rather cpu consuming.
+*/
+
+static int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg)
+ {
+ SRP_ARG *srp_arg = (SRP_ARG *)arg;
+ BIGNUM *N = NULL, *g = NULL;
+ if (!(N = SSL_get_srp_N(s)) || !(g = SSL_get_srp_g(s)))
+ return 0;
+ if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1)
+ {
+ BIO_printf(bio_err, "SRP parameters:\n");
+ BIO_printf(bio_err,"\tN="); BN_print(bio_err,N);
+ BIO_printf(bio_err,"\n\tg="); BN_print(bio_err,g);
+ BIO_printf(bio_err,"\n");
+ }
+
+ if (SRP_check_known_gN_param(g,N))
+ return 1;
+
+ if (srp_arg->amp == 1)
+ {
+ if (srp_arg->debug)
+ BIO_printf(bio_err, "SRP param N and g are not known params, going to check deeper.\n");
+
+/* The srp_moregroups is a real debugging feature.
+ Implementors should rather add the value to the known ones.
+ The minimal size has already been tested.
+*/
+ if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N,g))
+ return 1;
+ }
+ BIO_printf(bio_err, "SRP param N and g rejected.\n");
+ return 0;
+ }
+
+#define PWD_STRLEN 1024
+
+static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
+ {
+ SRP_ARG *srp_arg = (SRP_ARG *)arg;
+ char *pass = (char *)OPENSSL_malloc(PWD_STRLEN+1);
+ PW_CB_DATA cb_tmp;
+ int l;
+
+ cb_tmp.password = (char *)srp_arg->srppassin;
+ cb_tmp.prompt_info = "SRP user";
+ if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp))<0)
+ {
+ BIO_printf (bio_err, "Can't read Password\n");
+ OPENSSL_free(pass);
+ return NULL;
+ }
+ *(pass+l)= '\0';
+
+ return pass;
+ }
+
+#endif
+#ifndef OPENSSL_NO_SRTP
+ char *srtp_profiles = NULL;
+#endif
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+/* This the context that we pass to next_proto_cb */
+typedef struct tlsextnextprotoctx_st {
+ unsigned char *data;
+ unsigned short len;
+ int status;
+} tlsextnextprotoctx;
+
+static tlsextnextprotoctx next_proto;
+
+static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
+ {
+ tlsextnextprotoctx *ctx = arg;
+
+ if (!c_quiet)
+ {
+ /* We can assume that |in| is syntactically valid. */
+ unsigned i;
+ BIO_printf(bio_c_out, "Protocols advertised by server: ");
+ for (i = 0; i < inlen; )
+ {
+ if (i)
+ BIO_write(bio_c_out, ", ", 2);
+ BIO_write(bio_c_out, &in[i + 1], in[i]);
+ i += in[i] + 1;
+ }
+ BIO_write(bio_c_out, "\n", 1);
+ }
+
+ ctx->status = SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
+ return SSL_TLSEXT_ERR_OK;
+ }
+# endif /* ndef OPENSSL_NO_NEXTPROTONEG */
+#endif
+
+enum
+{
+ PROTO_OFF = 0,
+ PROTO_SMTP,
+ PROTO_POP3,
+ PROTO_IMAP,
+ PROTO_FTP,
+ PROTO_XMPP
+};
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ unsigned int off=0, clr=0;
+ SSL *con=NULL;
+#ifndef OPENSSL_NO_KRB5
+ KSSL_CTX *kctx;
+#endif
+ int s,k,width,state=0;
+ char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
+ int cbuf_len,cbuf_off;
+ int sbuf_len,sbuf_off;
+ fd_set readfds,writefds;
+ short port=PORT;
+ int full_log=1;
+ char *host=SSL_HOST_NAME;
+ char *cert_file=NULL,*key_file=NULL;
+ int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
+ char *passarg = NULL, *pass = NULL;
+ X509 *cert = NULL;
+ EVP_PKEY *key = NULL;
+ char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
+ int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
+ int crlf=0;
+ int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
+ SSL_CTX *ctx=NULL;
+ int ret=1,in_init=1,i,nbio_test=0;
+ int starttls_proto = PROTO_OFF;
+ int prexit = 0;
+ X509_VERIFY_PARAM *vpm = NULL;
+ int badarg = 0;
+ const SSL_METHOD *meth=NULL;
+ int socket_type=SOCK_STREAM;
+ BIO *sbio;
+ char *inrand=NULL;
+ int mbuf_len=0;
+ struct timeval timeout, *timeoutp;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine_id=NULL;
+ char *ssl_client_engine_id=NULL;
+ ENGINE *ssl_client_engine=NULL;
+#endif
+ ENGINE *e=NULL;
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
+ struct timeval tv;
+#if defined(OPENSSL_SYS_BEOS_R5)
+ int stdin_set = 0;
+#endif
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+ char *servername = NULL;
+ tlsextctx tlsextcbp =
+ {NULL,0};
+# ifndef OPENSSL_NO_NEXTPROTONEG
+ const char *next_proto_neg_in = NULL;
+# endif
+#endif
+ char *sess_in = NULL;
+ char *sess_out = NULL;
+ struct sockaddr peer;
+ int peerlen = sizeof(peer);
+ int enable_timeouts = 0 ;
+ long socket_mtu = 0;
+#ifndef OPENSSL_NO_JPAKE
+ char *jpake_secret = NULL;
+#endif
+#ifndef OPENSSL_NO_SRP
+ char * srppass = NULL;
+ int srp_lateuser = 0;
+ SRP_ARG srp_arg = {NULL,NULL,0,0,0,1024};
+#endif
+
+ meth=SSLv23_client_method();
+
+ apps_startup();
+ c_Pause=0;
+ c_quiet=0;
+ c_ign_eof=0;
+ c_debug=0;
+ c_msg=0;
+ c_showcerts=0;
+
+ if (bio_err == NULL)
+ bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ if ( ((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
+ ((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
+ ((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ goto end;
+ }
+
+ verify_depth=0;
+ verify_error=X509_V_OK;
+#ifdef FIONBIO
+ c_nbio=0;
+#endif
+
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-host") == 0)
+ {
+ if (--argc < 1) goto bad;
+ host= *(++argv);
+ }
+ else if (strcmp(*argv,"-port") == 0)
+ {
+ if (--argc < 1) goto bad;
+ port=atoi(*(++argv));
+ if (port == 0) goto bad;
+ }
+ else if (strcmp(*argv,"-connect") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if (!extract_host_port(*(++argv),&host,NULL,&port))
+ goto bad;
+ }
+ else if (strcmp(*argv,"-verify") == 0)
+ {
+ verify=SSL_VERIFY_PEER;
+ if (--argc < 1) goto bad;
+ verify_depth=atoi(*(++argv));
+ BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
+ }
+ else if (strcmp(*argv,"-cert") == 0)
+ {
+ if (--argc < 1) goto bad;
+ cert_file= *(++argv);
+ }
+ else if (strcmp(*argv,"-sess_out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ sess_out = *(++argv);
+ }
+ else if (strcmp(*argv,"-sess_in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ sess_in = *(++argv);
+ }
+ else if (strcmp(*argv,"-certform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ cert_format = str2fmt(*(++argv));
+ }
+ else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
+ {
+ if (badarg)
+ goto bad;
+ continue;
+ }
+ else if (strcmp(*argv,"-verify_return_error") == 0)
+ verify_return_error = 1;
+ else if (strcmp(*argv,"-prexit") == 0)
+ prexit=1;
+ else if (strcmp(*argv,"-crlf") == 0)
+ crlf=1;
+ else if (strcmp(*argv,"-quiet") == 0)
+ {
+ c_quiet=1;
+ c_ign_eof=1;
+ }
+ else if (strcmp(*argv,"-ign_eof") == 0)
+ c_ign_eof=1;
+ else if (strcmp(*argv,"-no_ign_eof") == 0)
+ c_ign_eof=0;
+ else if (strcmp(*argv,"-pause") == 0)
+ c_Pause=1;
+ else if (strcmp(*argv,"-debug") == 0)
+ c_debug=1;
+#ifndef OPENSSL_NO_TLSEXT
+ else if (strcmp(*argv,"-tlsextdebug") == 0)
+ c_tlsextdebug=1;
+ else if (strcmp(*argv,"-status") == 0)
+ c_status_req=1;
+#endif
+#ifdef WATT32
+ else if (strcmp(*argv,"-wdebug") == 0)
+ dbug_init();
+#endif
+ else if (strcmp(*argv,"-msg") == 0)
+ c_msg=1;
+ else if (strcmp(*argv,"-showcerts") == 0)
+ c_showcerts=1;
+ else if (strcmp(*argv,"-nbio_test") == 0)
+ nbio_test=1;
+ else if (strcmp(*argv,"-state") == 0)
+ state=1;
+#ifndef OPENSSL_NO_PSK
+ else if (strcmp(*argv,"-psk_identity") == 0)
+ {
+ if (--argc < 1) goto bad;
+ psk_identity=*(++argv);
+ }
+ else if (strcmp(*argv,"-psk") == 0)
+ {
+ size_t j;
+
+ if (--argc < 1) goto bad;
+ psk_key=*(++argv);
+ for (j = 0; j < strlen(psk_key); j++)
+ {
+ if (isxdigit((unsigned char)psk_key[j]))
+ continue;
+ BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
+ goto bad;
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_SRP
+ else if (strcmp(*argv,"-srpuser") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srp_arg.srplogin= *(++argv);
+ meth=TLSv1_client_method();
+ }
+ else if (strcmp(*argv,"-srppass") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srppass= *(++argv);
+ meth=TLSv1_client_method();
+ }
+ else if (strcmp(*argv,"-srp_strength") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srp_arg.strength=atoi(*(++argv));
+ BIO_printf(bio_err,"SRP minimal length for N is %d\n",srp_arg.strength);
+ meth=TLSv1_client_method();
+ }
+ else if (strcmp(*argv,"-srp_lateuser") == 0)
+ {
+ srp_lateuser= 1;
+ meth=TLSv1_client_method();
+ }
+ else if (strcmp(*argv,"-srp_moregroups") == 0)
+ {
+ srp_arg.amp=1;
+ meth=TLSv1_client_method();
+ }
+#endif
+#ifndef OPENSSL_NO_SSL2
+ else if (strcmp(*argv,"-ssl2") == 0)
+ meth=SSLv2_client_method();
+#endif
+#ifndef OPENSSL_NO_SSL3
+ else if (strcmp(*argv,"-ssl3") == 0)
+ meth=SSLv3_client_method();
+#endif
+#ifndef OPENSSL_NO_TLS1
+ else if (strcmp(*argv,"-tls1_2") == 0)
+ meth=TLSv1_2_client_method();
+ else if (strcmp(*argv,"-tls1_1") == 0)
+ meth=TLSv1_1_client_method();
+ else if (strcmp(*argv,"-tls1") == 0)
+ meth=TLSv1_client_method();
+#endif
+#ifndef OPENSSL_NO_DTLS1
+ else if (strcmp(*argv,"-dtls1") == 0)
+ {
+ meth=DTLSv1_client_method();
+ socket_type=SOCK_DGRAM;
+ }
+ else if (strcmp(*argv,"-timeout") == 0)
+ enable_timeouts=1;
+ else if (strcmp(*argv,"-mtu") == 0)
+ {
+ if (--argc < 1) goto bad;
+ socket_mtu = atol(*(++argv));
+ }
+#endif
+ else if (strcmp(*argv,"-bugs") == 0)
+ bugs=1;
+ else if (strcmp(*argv,"-keyform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ key_format = str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-pass") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passarg = *(++argv);
+ }
+ else if (strcmp(*argv,"-key") == 0)
+ {
+ if (--argc < 1) goto bad;
+ key_file= *(++argv);
+ }
+ else if (strcmp(*argv,"-reconnect") == 0)
+ {
+ reconnect=5;
+ }
+ else if (strcmp(*argv,"-CApath") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CApath= *(++argv);
+ }
+ else if (strcmp(*argv,"-CAfile") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CAfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-no_tls1_2") == 0)
+ off|=SSL_OP_NO_TLSv1_2;
+ else if (strcmp(*argv,"-no_tls1_1") == 0)
+ off|=SSL_OP_NO_TLSv1_1;
+ else if (strcmp(*argv,"-no_tls1") == 0)
+ off|=SSL_OP_NO_TLSv1;
+ else if (strcmp(*argv,"-no_ssl3") == 0)
+ off|=SSL_OP_NO_SSLv3;
+ else if (strcmp(*argv,"-no_ssl2") == 0)
+ off|=SSL_OP_NO_SSLv2;
+ else if (strcmp(*argv,"-no_comp") == 0)
+ { off|=SSL_OP_NO_COMPRESSION; }
+#ifndef OPENSSL_NO_TLSEXT
+ else if (strcmp(*argv,"-no_ticket") == 0)
+ { off|=SSL_OP_NO_TICKET; }
+# ifndef OPENSSL_NO_NEXTPROTONEG
+ else if (strcmp(*argv,"-nextprotoneg") == 0)
+ {
+ if (--argc < 1) goto bad;
+ next_proto_neg_in = *(++argv);
+ }
+# endif
+#endif
+ else if (strcmp(*argv,"-serverpref") == 0)
+ off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
+ else if (strcmp(*argv,"-legacy_renegotiation") == 0)
+ off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
+ else if (strcmp(*argv,"-legacy_server_connect") == 0)
+ { off|=SSL_OP_LEGACY_SERVER_CONNECT; }
+ else if (strcmp(*argv,"-no_legacy_server_connect") == 0)
+ { clr|=SSL_OP_LEGACY_SERVER_CONNECT; }
+ else if (strcmp(*argv,"-cipher") == 0)
+ {
+ if (--argc < 1) goto bad;
+ cipher= *(++argv);
+ }
+#ifdef FIONBIO
+ else if (strcmp(*argv,"-nbio") == 0)
+ { c_nbio=1; }
+#endif
+ else if (strcmp(*argv,"-starttls") == 0)
+ {
+ if (--argc < 1) goto bad;
+ ++argv;
+ if (strcmp(*argv,"smtp") == 0)
+ starttls_proto = PROTO_SMTP;
+ else if (strcmp(*argv,"pop3") == 0)
+ starttls_proto = PROTO_POP3;
+ else if (strcmp(*argv,"imap") == 0)
+ starttls_proto = PROTO_IMAP;
+ else if (strcmp(*argv,"ftp") == 0)
+ starttls_proto = PROTO_FTP;
+ else if (strcmp(*argv, "xmpp") == 0)
+ starttls_proto = PROTO_XMPP;
+ else
+ goto bad;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine_id = *(++argv);
+ }
+ else if (strcmp(*argv,"-ssl_client_engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ ssl_client_engine_id = *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-rand") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inrand= *(++argv);
+ }
+#ifndef OPENSSL_NO_TLSEXT
+ else if (strcmp(*argv,"-servername") == 0)
+ {
+ if (--argc < 1) goto bad;
+ servername= *(++argv);
+ /* meth=TLSv1_client_method(); */
+ }
+#endif
+#ifndef OPENSSL_NO_JPAKE
+ else if (strcmp(*argv,"-jpake") == 0)
+ {
+ if (--argc < 1) goto bad;
+ jpake_secret = *++argv;
+ }
+#endif
+#ifndef OPENSSL_NO_SRTP
+ else if (strcmp(*argv,"-use_srtp") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srtp_profiles = *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-keymatexport") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keymatexportlabel= *(++argv);
+ }
+ else if (strcmp(*argv,"-keymatexportlen") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keymatexportlen=atoi(*(++argv));
+ if (keymatexportlen == 0) goto bad;
+ }
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badop=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+ if (badop)
+ {
+bad:
+ sc_usage();
+ goto end;
+ }
+
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+ if (jpake_secret)
+ {
+ if (psk_key)
+ {
+ BIO_printf(bio_err,
+ "Can't use JPAKE and PSK together\n");
+ goto end;
+ }
+ psk_identity = "JPAKE";
+ if (cipher)
+ {
+ BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
+ goto end;
+ }
+ cipher = "PSK";
+ }
+#endif
+
+ OpenSSL_add_ssl_algorithms();
+ SSL_load_error_strings();
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ next_proto.status = -1;
+ if (next_proto_neg_in)
+ {
+ next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);
+ if (next_proto.data == NULL)
+ {
+ BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
+ goto end;
+ }
+ }
+ else
+ next_proto.data = NULL;
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine_id, 1);
+ if (ssl_client_engine_id)
+ {
+ ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
+ if (!ssl_client_engine)
+ {
+ BIO_printf(bio_err,
+ "Error getting client auth engine\n");
+ goto end;
+ }
+ }
+
+#endif
+ if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
+ {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+ if (key_file == NULL)
+ key_file = cert_file;
+
+
+ if (key_file)
+
+ {
+
+ key = load_key(bio_err, key_file, key_format, 0, pass, e,
+ "client certificate private key file");
+ if (!key)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ }
+
+ if (cert_file)
+
+ {
+ cert = load_cert(bio_err,cert_file,cert_format,
+ NULL, e, "client certificate file");
+
+ if (!cert)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
+ && !RAND_status())
+ {
+ BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+ }
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+
+ if (bio_c_out == NULL)
+ {
+ if (c_quiet && !c_debug && !c_msg)
+ {
+ bio_c_out=BIO_new(BIO_s_null());
+ }
+ else
+ {
+ if (bio_c_out == NULL)
+ bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
+ }
+ }
+
+#ifndef OPENSSL_NO_SRP
+ if(!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL))
+ {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+#endif
+
+ ctx=SSL_CTX_new(meth);
+ if (ctx == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (vpm)
+ SSL_CTX_set1_param(ctx, vpm);
+
+#ifndef OPENSSL_NO_ENGINE
+ if (ssl_client_engine)
+ {
+ if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
+ {
+ BIO_puts(bio_err, "Error setting client auth engine\n");
+ ERR_print_errors(bio_err);
+ ENGINE_free(ssl_client_engine);
+ goto end;
+ }
+ ENGINE_free(ssl_client_engine);
+ }
+#endif
+
+#ifndef OPENSSL_NO_PSK
+#ifdef OPENSSL_NO_JPAKE
+ if (psk_key != NULL)
+#else
+ if (psk_key != NULL || jpake_secret)
+#endif
+ {
+ if (c_debug)
+ BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n");
+ SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
+ }
+#endif
+#ifndef OPENSSL_NO_SRTP
+ if (srtp_profiles != NULL)
+ SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
+#endif
+ if (bugs)
+ SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
+ else
+ SSL_CTX_set_options(ctx,off);
+
+ if (clr)
+ SSL_CTX_clear_options(ctx, clr);
+ /* DTLS: partial reads end up discarding unread UDP bytes :-(
+ * Setting read ahead solves this problem.
+ */
+ if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ if (next_proto.data)
+ SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
+#endif
+
+ if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
+ if (cipher != NULL)
+ if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
+ BIO_printf(bio_err,"error setting cipher list\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+#if 0
+ else
+ SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
+#endif
+
+ SSL_CTX_set_verify(ctx,verify,verify_callback);
+ if (!set_cert_key_stuff(ctx,cert,key))
+ goto end;
+
+ if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
+ (!SSL_CTX_set_default_verify_paths(ctx)))
+ {
+ /* BIO_printf(bio_err,"error setting default verify locations\n"); */
+ ERR_print_errors(bio_err);
+ /* goto end; */
+ }
+
+#ifndef OPENSSL_NO_TLSEXT
+ if (servername != NULL)
+ {
+ tlsextcbp.biodebug = bio_err;
+ SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+ SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
+ }
+#ifndef OPENSSL_NO_SRP
+ if (srp_arg.srplogin)
+ {
+ if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin))
+ {
+ BIO_printf(bio_err,"Unable to set SRP username\n");
+ goto end;
+ }
+ srp_arg.msg = c_msg;
+ srp_arg.debug = c_debug ;
+ SSL_CTX_set_srp_cb_arg(ctx,&srp_arg);
+ SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
+ SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
+ if (c_msg || c_debug || srp_arg.amp == 0)
+ SSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb);
+ }
+
+#endif
+#endif
+
+ con=SSL_new(ctx);
+ if (sess_in)
+ {
+ SSL_SESSION *sess;
+ BIO *stmp = BIO_new_file(sess_in, "r");
+ if (!stmp)
+ {
+ BIO_printf(bio_err, "Can't open session file %s\n",
+ sess_in);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
+ BIO_free(stmp);
+ if (!sess)
+ {
+ BIO_printf(bio_err, "Can't open session file %s\n",
+ sess_in);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ SSL_set_session(con, sess);
+ SSL_SESSION_free(sess);
+ }
+#ifndef OPENSSL_NO_TLSEXT
+ if (servername != NULL)
+ {
+ if (!SSL_set_tlsext_host_name(con,servername))
+ {
+ BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_KRB5
+ if (con && (kctx = kssl_ctx_new()) != NULL)
+ {
+ SSL_set0_kssl_ctx(con, kctx);
+ kssl_ctx_setstring(kctx, KSSL_SERVER, host);
+ }
+#endif /* OPENSSL_NO_KRB5 */
+/* SSL_set_cipher_list(con,"RC4-MD5"); */
+#if 0
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ SSL_set_tlsext_opaque_prf_input(con, "Test client", 11);
+#endif
+#endif
+
+re_start:
+
+ if (init_client(&s,host,port,socket_type) == 0)
+ {
+ BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
+ SHUTDOWN(s);
+ goto end;
+ }
+ BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
+
+#ifdef FIONBIO
+ if (c_nbio)
+ {
+ unsigned long l=1;
+ BIO_printf(bio_c_out,"turning on non blocking io\n");
+ if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+#endif
+ if (c_Pause & 0x01) SSL_set_debug(con, 1);
+
+ if ( SSL_version(con) == DTLS1_VERSION)
+ {
+
+ sbio=BIO_new_dgram(s,BIO_NOCLOSE);
+ if (getsockname(s, &peer, (void *)&peerlen) < 0)
+ {
+ BIO_printf(bio_err, "getsockname:errno=%d\n",
+ get_last_socket_error());
+ SHUTDOWN(s);
+ goto end;
+ }
+
+ (void)BIO_ctrl_set_connected(sbio, 1, &peer);
+
+ if (enable_timeouts)
+ {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = DGRAM_RCV_TIMEOUT;
+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = DGRAM_SND_TIMEOUT;
+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
+ }
+
+ if (socket_mtu > 28)
+ {
+ SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
+ SSL_set_mtu(con, socket_mtu - 28);
+ }
+ else
+ /* want to do MTU discovery */
+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
+ }
+ else
+ sbio=BIO_new_socket(s,BIO_NOCLOSE);
+
+ if (nbio_test)
+ {
+ BIO *test;
+
+ test=BIO_new(BIO_f_nbio_test());
+ sbio=BIO_push(test,sbio);
+ }
+
+ if (c_debug)
+ {
+ SSL_set_debug(con, 1);
+ BIO_set_callback(sbio,bio_dump_callback);
+ BIO_set_callback_arg(sbio,(char *)bio_c_out);
+ }
+ if (c_msg)
+ {
+ SSL_set_msg_callback(con, msg_cb);
+ SSL_set_msg_callback_arg(con, bio_c_out);
+ }
+#ifndef OPENSSL_NO_TLSEXT
+ if (c_tlsextdebug)
+ {
+ SSL_set_tlsext_debug_callback(con, tlsext_cb);
+ SSL_set_tlsext_debug_arg(con, bio_c_out);
+ }
+ if (c_status_req)
+ {
+ SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
+ SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
+ SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
+#if 0
+{
+STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
+OCSP_RESPID *id = OCSP_RESPID_new();
+id->value.byKey = ASN1_OCTET_STRING_new();
+id->type = V_OCSP_RESPID_KEY;
+ASN1_STRING_set(id->value.byKey, "Hello World", -1);
+sk_OCSP_RESPID_push(ids, id);
+SSL_set_tlsext_status_ids(con, ids);
+}
+#endif
+ }
+#endif
+#ifndef OPENSSL_NO_JPAKE
+ if (jpake_secret)
+ jpake_client_auth(bio_c_out, sbio, jpake_secret);
+#endif
+
+ SSL_set_bio(con,sbio,sbio);
+ SSL_set_connect_state(con);
+
+ /* ok, lets connect */
+ width=SSL_get_fd(con)+1;
+
+ read_tty=1;
+ write_tty=0;
+ tty_on=0;
+ read_ssl=1;
+ write_ssl=1;
+
+ cbuf_len=0;
+ cbuf_off=0;
+ sbuf_len=0;
+ sbuf_off=0;
+
+ /* This is an ugly hack that does a lot of assumptions */
+ /* We do have to handle multi-line responses which may come
+ in a single packet or not. We therefore have to use
+ BIO_gets() which does need a buffering BIO. So during
+ the initial chitchat we do push a buffering BIO into the
+ chain that is removed again later on to not disturb the
+ rest of the s_client operation. */
+ if (starttls_proto == PROTO_SMTP)
+ {
+ int foundit=0;
+ BIO *fbio = BIO_new(BIO_f_buffer());
+ BIO_push(fbio, sbio);
+ /* wait for multi-line response to end from SMTP */
+ do
+ {
+ mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+ }
+ while (mbuf_len>3 && mbuf[3]=='-');
+ /* STARTTLS command requires EHLO... */
+ BIO_printf(fbio,"EHLO openssl.client.net\r\n");
+ (void)BIO_flush(fbio);
+ /* wait for multi-line response to end EHLO SMTP response */
+ do
+ {
+ mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+ if (strstr(mbuf,"STARTTLS"))
+ foundit=1;
+ }
+ while (mbuf_len>3 && mbuf[3]=='-');
+ (void)BIO_flush(fbio);
+ BIO_pop(fbio);
+ BIO_free(fbio);
+ if (!foundit)
+ BIO_printf(bio_err,
+ "didn't found starttls in server response,"
+ " try anyway...\n");
+ BIO_printf(sbio,"STARTTLS\r\n");
+ BIO_read(sbio,sbuf,BUFSIZZ);
+ }
+ else if (starttls_proto == PROTO_POP3)
+ {
+ BIO_read(sbio,mbuf,BUFSIZZ);
+ BIO_printf(sbio,"STLS\r\n");
+ BIO_read(sbio,sbuf,BUFSIZZ);
+ }
+ else if (starttls_proto == PROTO_IMAP)
+ {
+ int foundit=0;
+ BIO *fbio = BIO_new(BIO_f_buffer());
+ BIO_push(fbio, sbio);
+ BIO_gets(fbio,mbuf,BUFSIZZ);
+ /* STARTTLS command requires CAPABILITY... */
+ BIO_printf(fbio,". CAPABILITY\r\n");
+ (void)BIO_flush(fbio);
+ /* wait for multi-line CAPABILITY response */
+ do
+ {
+ mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+ if (strstr(mbuf,"STARTTLS"))
+ foundit=1;
+ }
+ while (mbuf_len>3 && mbuf[0]!='.');
+ (void)BIO_flush(fbio);
+ BIO_pop(fbio);
+ BIO_free(fbio);
+ if (!foundit)
+ BIO_printf(bio_err,
+ "didn't found STARTTLS in server response,"
+ " try anyway...\n");
+ BIO_printf(sbio,". STARTTLS\r\n");
+ BIO_read(sbio,sbuf,BUFSIZZ);
+ }
+ else if (starttls_proto == PROTO_FTP)
+ {
+ BIO *fbio = BIO_new(BIO_f_buffer());
+ BIO_push(fbio, sbio);
+ /* wait for multi-line response to end from FTP */
+ do
+ {
+ mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+ }
+ while (mbuf_len>3 && mbuf[3]=='-');
+ (void)BIO_flush(fbio);
+ BIO_pop(fbio);
+ BIO_free(fbio);
+ BIO_printf(sbio,"AUTH TLS\r\n");
+ BIO_read(sbio,sbuf,BUFSIZZ);
+ }
+ if (starttls_proto == PROTO_XMPP)
+ {
+ int seen = 0;
+ BIO_printf(sbio,"<stream:stream "
+ "xmlns:stream='http://etherx.jabber.org/streams' "
+ "xmlns='jabber:client' to='%s' version='1.0'>", host);
+ seen = BIO_read(sbio,mbuf,BUFSIZZ);
+ mbuf[seen] = 0;
+ while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
+ {
+ if (strstr(mbuf, "/stream:features>"))
+ goto shut;
+ seen = BIO_read(sbio,mbuf,BUFSIZZ);
+ mbuf[seen] = 0;
+ }
+ BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+ seen = BIO_read(sbio,sbuf,BUFSIZZ);
+ sbuf[seen] = 0;
+ if (!strstr(sbuf, "<proceed"))
+ goto shut;
+ mbuf[0] = 0;
+ }
+
+ for (;;)
+ {
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+
+ if ((SSL_version(con) == DTLS1_VERSION) &&
+ DTLSv1_get_timeout(con, &timeout))
+ timeoutp = &timeout;
+ else
+ timeoutp = NULL;
+
+ if (SSL_in_init(con) && !SSL_total_renegotiations(con))
+ {
+ in_init=1;
+ tty_on=0;
+ }
+ else
+ {
+ tty_on=1;
+ if (in_init)
+ {
+ in_init=0;
+#if 0 /* This test doesn't really work as intended (needs to be fixed) */
+#ifndef OPENSSL_NO_TLSEXT
+ if (servername != NULL && !SSL_session_reused(con))
+ {
+ BIO_printf(bio_c_out,"Server did %sacknowledge servername extension.\n",tlsextcbp.ack?"":"not ");
+ }
+#endif
+#endif
+ if (sess_out)
+ {
+ BIO *stmp = BIO_new_file(sess_out, "w");
+ if (stmp)
+ {
+ PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
+ BIO_free(stmp);
+ }
+ else
+ BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
+ }
+ print_stuff(bio_c_out,con,full_log);
+ if (full_log > 0) full_log--;
+
+ if (starttls_proto)
+ {
+ BIO_printf(bio_err,"%s",mbuf);
+ /* We don't need to know any more */
+ starttls_proto = PROTO_OFF;
+ }
+
+ if (reconnect)
+ {
+ reconnect--;
+ BIO_printf(bio_c_out,"drop connection and then reconnect\n");
+ SSL_shutdown(con);
+ SSL_set_connect_state(con);
+ SHUTDOWN(SSL_get_fd(con));
+ goto re_start;
+ }
+ }
+ }
+
+ ssl_pending = read_ssl && SSL_pending(con);
+
+ if (!ssl_pending)
+ {
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
+ if (tty_on)
+ {
+ if (read_tty) openssl_fdset(fileno(stdin),&readfds);
+ if (write_tty) openssl_fdset(fileno(stdout),&writefds);
+ }
+ if (read_ssl)
+ openssl_fdset(SSL_get_fd(con),&readfds);
+ if (write_ssl)
+ openssl_fdset(SSL_get_fd(con),&writefds);
+#else
+ if(!tty_on || !write_tty) {
+ if (read_ssl)
+ openssl_fdset(SSL_get_fd(con),&readfds);
+ if (write_ssl)
+ openssl_fdset(SSL_get_fd(con),&writefds);
+ }
+#endif
+/* printf("mode tty(%d %d%d) ssl(%d%d)\n",
+ tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
+
+ /* Note: under VMS with SOCKETSHR the second parameter
+ * is currently of type (int *) whereas under other
+ * systems it is (void *) if you don't have a cast it
+ * will choke the compiler: if you do have a cast then
+ * you can either go for (int *) or (void *).
+ */
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+ /* Under Windows/DOS we make the assumption that we can
+ * always write to the tty: therefore if we need to
+ * write to the tty we just fall through. Otherwise
+ * we timeout the select every second and see if there
+ * are any keypresses. Note: this is a hack, in a proper
+ * Windows application we wouldn't do this.
+ */
+ i=0;
+ if(!write_tty) {
+ if(read_tty) {
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ i=select(width,(void *)&readfds,(void *)&writefds,
+ NULL,&tv);
+#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
+ if(!i && (!_kbhit() || !read_tty) ) continue;
+#else
+ if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
+#endif
+ } else i=select(width,(void *)&readfds,(void *)&writefds,
+ NULL,timeoutp);
+ }
+#elif defined(OPENSSL_SYS_NETWARE)
+ if(!write_tty) {
+ if(read_tty) {
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ i=select(width,(void *)&readfds,(void *)&writefds,
+ NULL,&tv);
+ } else i=select(width,(void *)&readfds,(void *)&writefds,
+ NULL,timeoutp);
+ }
+#elif defined(OPENSSL_SYS_BEOS_R5)
+ /* Under BeOS-R5 the situation is similar to DOS */
+ i=0;
+ stdin_set = 0;
+ (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+ if(!write_tty) {
+ if(read_tty) {
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ i=select(width,(void *)&readfds,(void *)&writefds,
+ NULL,&tv);
+ if (read(fileno(stdin), sbuf, 0) >= 0)
+ stdin_set = 1;
+ if (!i && (stdin_set != 1 || !read_tty))
+ continue;
+ } else i=select(width,(void *)&readfds,(void *)&writefds,
+ NULL,timeoutp);
+ }
+ (void)fcntl(fileno(stdin), F_SETFL, 0);
+#else
+ i=select(width,(void *)&readfds,(void *)&writefds,
+ NULL,timeoutp);
+#endif
+ if ( i < 0)
+ {
+ BIO_printf(bio_err,"bad select %d\n",
+ get_last_socket_error());
+ goto shut;
+ /* goto end; */
+ }
+ }
+
+ if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
+ {
+ BIO_printf(bio_err,"TIMEOUT occured\n");
+ }
+
+ if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
+ {
+ k=SSL_write(con,&(cbuf[cbuf_off]),
+ (unsigned int)cbuf_len);
+ switch (SSL_get_error(con,k))
+ {
+ case SSL_ERROR_NONE:
+ cbuf_off+=k;
+ cbuf_len-=k;
+ if (k <= 0) goto end;
+ /* we have done a write(con,NULL,0); */
+ if (cbuf_len <= 0)
+ {
+ read_tty=1;
+ write_ssl=0;
+ }
+ else /* if (cbuf_len > 0) */
+ {
+ read_tty=0;
+ write_ssl=1;
+ }
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ BIO_printf(bio_c_out,"write W BLOCK\n");
+ write_ssl=1;
+ read_tty=0;
+ break;
+ case SSL_ERROR_WANT_READ:
+ BIO_printf(bio_c_out,"write R BLOCK\n");
+ write_tty=0;
+ read_ssl=1;
+ write_ssl=0;
+ break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ BIO_printf(bio_c_out,"write X BLOCK\n");
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ if (cbuf_len != 0)
+ {
+ BIO_printf(bio_c_out,"shutdown\n");
+ ret = 0;
+ goto shut;
+ }
+ else
+ {
+ read_tty=1;
+ write_ssl=0;
+ break;
+ }
+
+ case SSL_ERROR_SYSCALL:
+ if ((k != 0) || (cbuf_len != 0))
+ {
+ BIO_printf(bio_err,"write:errno=%d\n",
+ get_last_socket_error());
+ goto shut;
+ }
+ else
+ {
+ read_tty=1;
+ write_ssl=0;
+ }
+ break;
+ case SSL_ERROR_SSL:
+ ERR_print_errors(bio_err);
+ goto shut;
+ }
+ }
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
+ /* Assume Windows/DOS/BeOS can always write */
+ else if (!ssl_pending && write_tty)
+#else
+ else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
+#endif
+ {
+#ifdef CHARSET_EBCDIC
+ ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
+#endif
+ i=raw_write_stdout(&(sbuf[sbuf_off]),sbuf_len);
+
+ if (i <= 0)
+ {
+ BIO_printf(bio_c_out,"DONE\n");
+ ret = 0;
+ goto shut;
+ /* goto end; */
+ }
+
+ sbuf_len-=i;;
+ sbuf_off+=i;
+ if (sbuf_len <= 0)
+ {
+ read_ssl=1;
+ write_tty=0;
+ }
+ }
+ else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
+ {
+#ifdef RENEG
+{ static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
+#endif
+#if 1
+ k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
+#else
+/* Demo for pending and peek :-) */
+ k=SSL_read(con,sbuf,16);
+{ char zbuf[10240];
+printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
+}
+#endif
+
+ switch (SSL_get_error(con,k))
+ {
+ case SSL_ERROR_NONE:
+ if (k <= 0)
+ goto end;
+ sbuf_off=0;
+ sbuf_len=k;
+
+ read_ssl=0;
+ write_tty=1;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ BIO_printf(bio_c_out,"read W BLOCK\n");
+ write_ssl=1;
+ read_tty=0;
+ break;
+ case SSL_ERROR_WANT_READ:
+ BIO_printf(bio_c_out,"read R BLOCK\n");
+ write_tty=0;
+ read_ssl=1;
+ if ((read_tty == 0) && (write_ssl == 0))
+ write_ssl=1;
+ break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ BIO_printf(bio_c_out,"read X BLOCK\n");
+ break;
+ case SSL_ERROR_SYSCALL:
+ ret=get_last_socket_error();
+ BIO_printf(bio_err,"read:errno=%d\n",ret);
+ goto shut;
+ case SSL_ERROR_ZERO_RETURN:
+ BIO_printf(bio_c_out,"closed\n");
+ ret=0;
+ goto shut;
+ case SSL_ERROR_SSL:
+ ERR_print_errors(bio_err);
+ goto shut;
+ /* break; */
+ }
+ }
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
+ else if (_kbhit())
+#else
+ else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
+#endif
+#elif defined (OPENSSL_SYS_NETWARE)
+ else if (_kbhit())
+#elif defined(OPENSSL_SYS_BEOS_R5)
+ else if (stdin_set)
+#else
+ else if (FD_ISSET(fileno(stdin),&readfds))
+#endif
+ {
+ if (crlf)
+ {
+ int j, lf_num;
+
+ i=raw_read_stdin(cbuf,BUFSIZZ/2);
+ lf_num = 0;
+ /* both loops are skipped when i <= 0 */
+ for (j = 0; j < i; j++)
+ if (cbuf[j] == '\n')
+ lf_num++;
+ for (j = i-1; j >= 0; j--)
+ {
+ cbuf[j+lf_num] = cbuf[j];
+ if (cbuf[j] == '\n')
+ {
+ lf_num--;
+ i++;
+ cbuf[j+lf_num] = '\r';
+ }
+ }
+ assert(lf_num == 0);
+ }
+ else
+ i=raw_read_stdin(cbuf,BUFSIZZ);
+
+ if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
+ {
+ BIO_printf(bio_err,"DONE\n");
+ ret=0;
+ goto shut;
+ }
+
+ if ((!c_ign_eof) && (cbuf[0] == 'R'))
+ {
+ BIO_printf(bio_err,"RENEGOTIATING\n");
+ SSL_renegotiate(con);
+ cbuf_len=0;
+ }
+#ifndef OPENSSL_NO_HEARTBEATS
+ else if ((!c_ign_eof) && (cbuf[0] == 'B'))
+ {
+ BIO_printf(bio_err,"HEARTBEATING\n");
+ SSL_heartbeat(con);
+ cbuf_len=0;
+ }
+#endif
+ else
+ {
+ cbuf_len=i;
+ cbuf_off=0;
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(cbuf, cbuf, i);
+#endif
+ }
+
+ write_ssl=1;
+ read_tty=0;
+ }
+ }
+
+ ret=0;
+shut:
+ if (in_init)
+ print_stuff(bio_c_out,con,full_log);
+ SSL_shutdown(con);
+ SHUTDOWN(SSL_get_fd(con));
+end:
+ if (con != NULL)
+ {
+ if (prexit != 0)
+ print_stuff(bio_c_out,con,1);
+ SSL_free(con);
+ }
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ if (next_proto.data)
+ OPENSSL_free(next_proto.data);
+#endif
+ if (ctx != NULL) SSL_CTX_free(ctx);
+ if (cert)
+ X509_free(cert);
+ if (key)
+ EVP_PKEY_free(key);
+ if (pass)
+ OPENSSL_free(pass);
+ if (vpm)
+ X509_VERIFY_PARAM_free(vpm);
+ if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
+ if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
+ if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
+ if (bio_c_out != NULL)
+ {
+ BIO_free(bio_c_out);
+ bio_c_out=NULL;
+ }
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+
+static void print_stuff(BIO *bio, SSL *s, int full)
+ {
+ X509 *peer=NULL;
+ char *p;
+ static const char *space=" ";
+ char buf[BUFSIZ];
+ STACK_OF(X509) *sk;
+ STACK_OF(X509_NAME) *sk2;
+ const SSL_CIPHER *c;
+ X509_NAME *xn;
+ int j,i;
+#ifndef OPENSSL_NO_COMP
+ const COMP_METHOD *comp, *expansion;
+#endif
+ unsigned char *exportedkeymat;
+
+ if (full)
+ {
+ int got_a_chain = 0;
+
+ sk=SSL_get_peer_cert_chain(s);
+ if (sk != NULL)
+ {
+ got_a_chain = 1; /* we don't have it for SSL2 (yet) */
+
+ BIO_printf(bio,"---\nCertificate chain\n");
+ for (i=0; i<sk_X509_num(sk); i++)
+ {
+ X509_NAME_oneline(X509_get_subject_name(
+ sk_X509_value(sk,i)),buf,sizeof buf);
+ BIO_printf(bio,"%2d s:%s\n",i,buf);
+ X509_NAME_oneline(X509_get_issuer_name(
+ sk_X509_value(sk,i)),buf,sizeof buf);
+ BIO_printf(bio," i:%s\n",buf);
+ if (c_showcerts)
+ PEM_write_bio_X509(bio,sk_X509_value(sk,i));
+ }
+ }
+
+ BIO_printf(bio,"---\n");
+ peer=SSL_get_peer_certificate(s);
+ if (peer != NULL)
+ {
+ BIO_printf(bio,"Server certificate\n");
+ if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
+ PEM_write_bio_X509(bio,peer);
+ X509_NAME_oneline(X509_get_subject_name(peer),
+ buf,sizeof buf);
+ BIO_printf(bio,"subject=%s\n",buf);
+ X509_NAME_oneline(X509_get_issuer_name(peer),
+ buf,sizeof buf);
+ BIO_printf(bio,"issuer=%s\n",buf);
+ }
+ else
+ BIO_printf(bio,"no peer certificate available\n");
+
+ sk2=SSL_get_client_CA_list(s);
+ if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
+ {
+ BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
+ for (i=0; i<sk_X509_NAME_num(sk2); i++)
+ {
+ xn=sk_X509_NAME_value(sk2,i);
+ X509_NAME_oneline(xn,buf,sizeof(buf));
+ BIO_write(bio,buf,strlen(buf));
+ BIO_write(bio,"\n",1);
+ }
+ }
+ else
+ {
+ BIO_printf(bio,"---\nNo client certificate CA names sent\n");
+ }
+ p=SSL_get_shared_ciphers(s,buf,sizeof buf);
+ if (p != NULL)
+ {
+ /* This works only for SSL 2. In later protocol
+ * versions, the client does not know what other
+ * ciphers (in addition to the one to be used
+ * in the current connection) the server supports. */
+
+ BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
+ j=i=0;
+ while (*p)
+ {
+ if (*p == ':')
+ {
+ BIO_write(bio,space,15-j%25);
+ i++;
+ j=0;
+ BIO_write(bio,((i%3)?" ":"\n"),1);
+ }
+ else
+ {
+ BIO_write(bio,p,1);
+ j++;
+ }
+ p++;
+ }
+ BIO_write(bio,"\n",1);
+ }
+
+ BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
+ BIO_number_read(SSL_get_rbio(s)),
+ BIO_number_written(SSL_get_wbio(s)));
+ }
+ BIO_printf(bio,(SSL_cache_hit(s)?"---\nReused, ":"---\nNew, "));
+ c=SSL_get_current_cipher(s);
+ BIO_printf(bio,"%s, Cipher is %s\n",
+ SSL_CIPHER_get_version(c),
+ SSL_CIPHER_get_name(c));
+ if (peer != NULL) {
+ EVP_PKEY *pktmp;
+ pktmp = X509_get_pubkey(peer);
+ BIO_printf(bio,"Server public key is %d bit\n",
+ EVP_PKEY_bits(pktmp));
+ EVP_PKEY_free(pktmp);
+ }
+ BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
+ SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
+#ifndef OPENSSL_NO_COMP
+ comp=SSL_get_current_compression(s);
+ expansion=SSL_get_current_expansion(s);
+ BIO_printf(bio,"Compression: %s\n",
+ comp ? SSL_COMP_get_name(comp) : "NONE");
+ BIO_printf(bio,"Expansion: %s\n",
+ expansion ? SSL_COMP_get_name(expansion) : "NONE");
+#endif
+
+#ifdef SSL_DEBUG
+ {
+ /* Print out local port of connection: useful for debugging */
+ int sock;
+ struct sockaddr_in ladd;
+ socklen_t ladd_size = sizeof(ladd);
+ sock = SSL_get_fd(s);
+ getsockname(sock, (struct sockaddr *)&ladd, &ladd_size);
+ BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port));
+ }
+#endif
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ if (next_proto.status != -1) {
+ const unsigned char *proto;
+ unsigned int proto_len;
+ SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
+ BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
+ BIO_write(bio, proto, proto_len);
+ BIO_write(bio, "\n", 1);
+ }
+#endif
+
+#ifndef OPENSSL_NO_SRTP
+ {
+ SRTP_PROTECTION_PROFILE *srtp_profile=SSL_get_selected_srtp_profile(s);
+
+ if(srtp_profile)
+ BIO_printf(bio,"SRTP Extension negotiated, profile=%s\n",
+ srtp_profile->name);
+ }
+#endif
+
+ SSL_SESSION_print(bio,SSL_get_session(s));
+ if (keymatexportlabel != NULL)
+ {
+ BIO_printf(bio, "Keying material exporter:\n");
+ BIO_printf(bio, " Label: '%s'\n", keymatexportlabel);
+ BIO_printf(bio, " Length: %i bytes\n", keymatexportlen);
+ exportedkeymat = OPENSSL_malloc(keymatexportlen);
+ if (exportedkeymat != NULL)
+ {
+ if (!SSL_export_keying_material(s, exportedkeymat,
+ keymatexportlen,
+ keymatexportlabel,
+ strlen(keymatexportlabel),
+ NULL, 0, 0))
+ {
+ BIO_printf(bio, " Error\n");
+ }
+ else
+ {
+ BIO_printf(bio, " Keying material: ");
+ for (i=0; i<keymatexportlen; i++)
+ BIO_printf(bio, "%02X",
+ exportedkeymat[i]);
+ BIO_printf(bio, "\n");
+ }
+ OPENSSL_free(exportedkeymat);
+ }
+ }
+ BIO_printf(bio,"---\n");
+ if (peer != NULL)
+ X509_free(peer);
+ /* flush, or debugging output gets mixed with http response */
+ (void)BIO_flush(bio);
+ }
+
+#ifndef OPENSSL_NO_TLSEXT
+
+static int ocsp_resp_cb(SSL *s, void *arg)
+ {
+ const unsigned char *p;
+ int len;
+ OCSP_RESPONSE *rsp;
+ len = SSL_get_tlsext_status_ocsp_resp(s, &p);
+ BIO_puts(arg, "OCSP response: ");
+ if (!p)
+ {
+ BIO_puts(arg, "no response sent\n");
+ return 1;
+ }
+ rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
+ if (!rsp)
+ {
+ BIO_puts(arg, "response parse error\n");
+ BIO_dump_indent(arg, (char *)p, len, 4);
+ return 0;
+ }
+ BIO_puts(arg, "\n======================================\n");
+ OCSP_RESPONSE_print(arg, rsp, 0);
+ BIO_puts(arg, "======================================\n");
+ OCSP_RESPONSE_free(rsp);
+ return 1;
+ }
+
+#endif
diff --git a/deps/openssl/openssl/apps/s_server.c b/deps/openssl/openssl/apps/s_server.c
new file mode 100644
index 000000000..8198d7f06
--- /dev/null
+++ b/deps/openssl/openssl/apps/s_server.c
@@ -0,0 +1,3011 @@
+/* apps/s_server.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/e_os2.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+
+#if !defined(OPENSSL_SYS_NETWARE) /* conflicts with winsock2 stuff on netware */
+#include <sys/types.h>
+#endif
+
+/* With IPv6, it looks like Digital has mixed up the proper order of
+ recursive header file inclusion, resulting in the compiler complaining
+ that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
+ is needed to have fileno() declared correctly... So let's define u_int */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
+#define __U_INT
+typedef unsigned int u_int;
+#endif
+
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#define USE_SOCKETS
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/rand.h>
+#include <openssl/ocsp.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_SRP
+#include <openssl/srp.h>
+#endif
+#include "s_apps.h"
+#include "timeouts.h"
+
+#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
+/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
+#undef FIONBIO
+#endif
+
+#if defined(OPENSSL_SYS_BEOS_R5)
+#include <fcntl.h>
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
+#endif
+static int sv_body(char *hostname, int s, unsigned char *context);
+static int www_body(char *hostname, int s, unsigned char *context);
+static void close_accept_socket(void );
+static void sv_usage(void);
+static int init_ssl_connection(SSL *s);
+static void print_stats(BIO *bp,SSL_CTX *ctx);
+static int generate_session_id(const SSL *ssl, unsigned char *id,
+ unsigned int *id_len);
+#ifndef OPENSSL_NO_DH
+static DH *load_dh_param(const char *dhfile);
+static DH *get_dh512(void);
+#endif
+
+#ifdef MONOLITH
+static void s_server_init(void);
+#endif
+
+#ifndef OPENSSL_NO_DH
+static unsigned char dh512_p[]={
+ 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
+ 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
+ 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
+ 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
+ 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
+ 0x47,0x74,0xE8,0x33,
+ };
+static unsigned char dh512_g[]={
+ 0x02,
+ };
+
+static DH *get_dh512(void)
+ {
+ DH *dh=NULL;
+
+ if ((dh=DH_new()) == NULL) return(NULL);
+ dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
+ dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
+ if ((dh->p == NULL) || (dh->g == NULL))
+ return(NULL);
+ return(dh);
+ }
+#endif
+
+
+/* static int load_CA(SSL_CTX *ctx, char *file);*/
+
+#undef BUFSIZZ
+#define BUFSIZZ 16*1024
+static int bufsize=BUFSIZZ;
+static int accept_socket= -1;
+
+#define TEST_CERT "server.pem"
+#ifndef OPENSSL_NO_TLSEXT
+#define TEST_CERT2 "server2.pem"
+#endif
+#undef PROG
+#define PROG s_server_main
+
+extern int verify_depth, verify_return_error;
+
+static char *cipher=NULL;
+static int s_server_verify=SSL_VERIFY_NONE;
+static int s_server_session_id_context = 1; /* anything will do */
+static const char *s_cert_file=TEST_CERT,*s_key_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+static const char *s_cert_file2=TEST_CERT2,*s_key_file2=NULL;
+#endif
+static char *s_dcert_file=NULL,*s_dkey_file=NULL;
+#ifdef FIONBIO
+static int s_nbio=0;
+#endif
+static int s_nbio_test=0;
+int s_crlf=0;
+static SSL_CTX *ctx=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+static SSL_CTX *ctx2=NULL;
+#endif
+static int www=0;
+
+static BIO *bio_s_out=NULL;
+static int s_debug=0;
+#ifndef OPENSSL_NO_TLSEXT
+static int s_tlsextdebug=0;
+static int s_tlsextstatus=0;
+static int cert_status_cb(SSL *s, void *arg);
+#endif
+static int s_msg=0;
+static int s_quiet=0;
+
+static char *keymatexportlabel=NULL;
+static int keymatexportlen=20;
+
+static int hack=0;
+#ifndef OPENSSL_NO_ENGINE
+static char *engine_id=NULL;
+#endif
+static const char *session_id_prefix=NULL;
+
+static int enable_timeouts = 0;
+static long socket_mtu;
+#ifndef OPENSSL_NO_DTLS1
+static int cert_chain = 0;
+#endif
+
+
+#ifndef OPENSSL_NO_PSK
+static char *psk_identity="Client_identity";
+char *psk_key=NULL; /* by default PSK is not used */
+
+static unsigned int psk_server_cb(SSL *ssl, const char *identity,
+ unsigned char *psk, unsigned int max_psk_len)
+ {
+ unsigned int psk_len = 0;
+ int ret;
+ BIGNUM *bn = NULL;
+
+ if (s_debug)
+ BIO_printf(bio_s_out,"psk_server_cb\n");
+ if (!identity)
+ {
+ BIO_printf(bio_err,"Error: client did not send PSK identity\n");
+ goto out_err;
+ }
+ if (s_debug)
+ BIO_printf(bio_s_out,"identity_len=%d identity=%s\n",
+ identity ? (int)strlen(identity) : 0, identity);
+
+ /* here we could lookup the given identity e.g. from a database */
+ if (strcmp(identity, psk_identity) != 0)
+ {
+ BIO_printf(bio_s_out, "PSK error: client identity not found"
+ " (got '%s' expected '%s')\n", identity,
+ psk_identity);
+ goto out_err;
+ }
+ if (s_debug)
+ BIO_printf(bio_s_out, "PSK client identity found\n");
+
+ /* convert the PSK key to binary */
+ ret = BN_hex2bn(&bn, psk_key);
+ if (!ret)
+ {
+ BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key);
+ if (bn)
+ BN_free(bn);
+ return 0;
+ }
+ if (BN_num_bytes(bn) > (int)max_psk_len)
+ {
+ BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
+ max_psk_len, BN_num_bytes(bn));
+ BN_free(bn);
+ return 0;
+ }
+
+ ret = BN_bn2bin(bn, psk);
+ BN_free(bn);
+
+ if (ret < 0)
+ goto out_err;
+ psk_len = (unsigned int)ret;
+
+ if (s_debug)
+ BIO_printf(bio_s_out, "fetched PSK len=%d\n", psk_len);
+ return psk_len;
+ out_err:
+ if (s_debug)
+ BIO_printf(bio_err, "Error in PSK server callback\n");
+ return 0;
+ }
+#endif
+
+#ifndef OPENSSL_NO_SRP
+/* This is a context that we pass to callbacks */
+typedef struct srpsrvparm_st
+ {
+ char *login;
+ SRP_VBASE *vb;
+ SRP_user_pwd *user;
+ } srpsrvparm;
+
+/* This callback pretends to require some asynchronous logic in order to obtain
+ a verifier. When the callback is called for a new connection we return
+ with a negative value. This will provoke the accept etc to return with
+ an LOOKUP_X509. The main logic of the reinvokes the suspended call
+ (which would normally occur after a worker has finished) and we
+ set the user parameters.
+*/
+static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
+ {
+ srpsrvparm *p = (srpsrvparm *)arg;
+ if (p->login == NULL && p->user == NULL )
+ {
+ p->login = SSL_get_srp_username(s);
+ BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
+ return (-1) ;
+ }
+
+ if (p->user == NULL)
+ {
+ BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
+ return SSL3_AL_FATAL;
+ }
+ if (SSL_set_srp_server_param(s, p->user->N, p->user->g, p->user->s, p->user->v,
+ p->user->info) < 0)
+ {
+ *ad = SSL_AD_INTERNAL_ERROR;
+ return SSL3_AL_FATAL;
+ }
+ BIO_printf(bio_err, "SRP parameters set: username = \"%s\" info=\"%s\" \n", p->login,p->user->info);
+ /* need to check whether there are memory leaks */
+ p->user = NULL;
+ p->login = NULL;
+ return SSL_ERROR_NONE;
+ }
+
+#endif
+
+#ifdef MONOLITH
+static void s_server_init(void)
+ {
+ accept_socket=-1;
+ cipher=NULL;
+ s_server_verify=SSL_VERIFY_NONE;
+ s_dcert_file=NULL;
+ s_dkey_file=NULL;
+ s_cert_file=TEST_CERT;
+ s_key_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+ s_cert_file2=TEST_CERT2;
+ s_key_file2=NULL;
+ ctx2=NULL;
+#endif
+#ifdef FIONBIO
+ s_nbio=0;
+#endif
+ s_nbio_test=0;
+ ctx=NULL;
+ www=0;
+
+ bio_s_out=NULL;
+ s_debug=0;
+ s_msg=0;
+ s_quiet=0;
+ hack=0;
+#ifndef OPENSSL_NO_ENGINE
+ engine_id=NULL;
+#endif
+ }
+#endif
+
+static void sv_usage(void)
+ {
+ BIO_printf(bio_err,"usage: s_server [args ...]\n");
+ BIO_printf(bio_err,"\n");
+ BIO_printf(bio_err," -accept arg - port to accept on (default is %d)\n",PORT);
+ BIO_printf(bio_err," -context arg - set session ID context\n");
+ BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n");
+ BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n");
+ BIO_printf(bio_err," -cert arg - certificate file to use\n");
+ BIO_printf(bio_err," (default is %s)\n",TEST_CERT);
+ BIO_printf(bio_err," -crl_check - check the peer certificate has not been revoked by its CA.\n" \
+ " The CRL(s) are appended to the certificate file\n");
+ BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \
+ " or any other CRL in the CA chain. CRL(s) are appened to the\n" \
+ " the certificate file.\n");
+ BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
+ BIO_printf(bio_err," -key arg - Private Key file to use, in cert file if\n");
+ BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT);
+ BIO_printf(bio_err," -keyform arg - key format (PEM, DER or ENGINE) PEM default\n");
+ BIO_printf(bio_err," -pass arg - private key file pass phrase source\n");
+ BIO_printf(bio_err," -dcert arg - second certificate file to use (usually for DSA)\n");
+ BIO_printf(bio_err," -dcertform x - second certificate format (PEM or DER) PEM default\n");
+ BIO_printf(bio_err," -dkey arg - second private key file to use (usually for DSA)\n");
+ BIO_printf(bio_err," -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n");
+ BIO_printf(bio_err," -dpass arg - second private key file pass phrase source\n");
+ BIO_printf(bio_err," -dhparam arg - DH parameter file to use, in cert file if not specified\n");
+ BIO_printf(bio_err," or a default set of parameters is used\n");
+#ifndef OPENSSL_NO_ECDH
+ BIO_printf(bio_err," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \
+ " Use \"openssl ecparam -list_curves\" for all names\n" \
+ " (default is nistp256).\n");
+#endif
+#ifdef FIONBIO
+ BIO_printf(bio_err," -nbio - Run with non-blocking IO\n");
+#endif
+ BIO_printf(bio_err," -nbio_test - test with the non-blocking test bio\n");
+ BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n");
+ BIO_printf(bio_err," -debug - Print more output\n");
+ BIO_printf(bio_err," -msg - Show protocol messages\n");
+ BIO_printf(bio_err," -state - Print the SSL states\n");
+ BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n");
+ BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n");
+ BIO_printf(bio_err," -nocert - Don't use any certificates (Anon-DH)\n");
+ BIO_printf(bio_err," -cipher arg - play with 'openssl ciphers' to see what goes here\n");
+ BIO_printf(bio_err," -serverpref - Use server's cipher preferences\n");
+ BIO_printf(bio_err," -quiet - No server output\n");
+ BIO_printf(bio_err," -no_tmp_rsa - Do not generate a tmp RSA key\n");
+#ifndef OPENSSL_NO_PSK
+ BIO_printf(bio_err," -psk_hint arg - PSK identity hint to use\n");
+ BIO_printf(bio_err," -psk arg - PSK in hex (without 0x)\n");
+# ifndef OPENSSL_NO_JPAKE
+ BIO_printf(bio_err," -jpake arg - JPAKE secret to use\n");
+# endif
+#endif
+#ifndef OPENSSL_NO_SRP
+ BIO_printf(bio_err," -srpvfile file - The verifier file for SRP\n");
+ BIO_printf(bio_err," -srpuserseed string - A seed string for a default user salt.\n");
+#endif
+ BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n");
+ BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n");
+ BIO_printf(bio_err," -tls1_2 - Just talk TLSv1.2\n");
+ BIO_printf(bio_err," -tls1_1 - Just talk TLSv1.1\n");
+ BIO_printf(bio_err," -tls1 - Just talk TLSv1\n");
+ BIO_printf(bio_err," -dtls1 - Just talk DTLSv1\n");
+ BIO_printf(bio_err," -timeout - Enable timeouts\n");
+ BIO_printf(bio_err," -mtu - Set link layer MTU\n");
+ BIO_printf(bio_err," -chain - Read a certificate chain\n");
+ BIO_printf(bio_err," -no_ssl2 - Just disable SSLv2\n");
+ BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n");
+ BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n");
+ BIO_printf(bio_err," -no_tls1_1 - Just disable TLSv1.1\n");
+ BIO_printf(bio_err," -no_tls1_2 - Just disable TLSv1.2\n");
+#ifndef OPENSSL_NO_DH
+ BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\n");
+#endif
+#ifndef OPENSSL_NO_ECDH
+ BIO_printf(bio_err," -no_ecdhe - Disable ephemeral ECDH\n");
+#endif
+ BIO_printf(bio_err," -bugs - Turn on SSL bug compatibility\n");
+ BIO_printf(bio_err," -www - Respond to a 'GET /' with a status page\n");
+ BIO_printf(bio_err," -WWW - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
+ BIO_printf(bio_err," -HTTP - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
+ BIO_printf(bio_err," with the assumption it contains a complete HTTP response.\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n");
+#endif
+ BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
+ BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+#ifndef OPENSSL_NO_TLSEXT
+ BIO_printf(bio_err," -servername host - servername for HostName TLS extension\n");
+ BIO_printf(bio_err," -servername_fatal - on mismatch send fatal alert (default warning alert)\n");
+ BIO_printf(bio_err," -cert2 arg - certificate file to use for servername\n");
+ BIO_printf(bio_err," (default is %s)\n",TEST_CERT2);
+ BIO_printf(bio_err," -key2 arg - Private Key file to use for servername, in cert file if\n");
+ BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT2);
+ BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
+ BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
+ BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
+# ifndef OPENSSL_NO_NEXTPROTONEG
+ BIO_printf(bio_err," -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
+# endif
+# ifndef OPENSSL_NO_SRTP
+ BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
+# endif
+#endif
+ BIO_printf(bio_err," -keymatexport label - Export keying material using label\n");
+ BIO_printf(bio_err," -keymatexportlen len - Export len bytes of keying material (default 20)\n");
+ }
+
+static int local_argc=0;
+static char **local_argv;
+
+#ifdef CHARSET_EBCDIC
+static int ebcdic_new(BIO *bi);
+static int ebcdic_free(BIO *a);
+static int ebcdic_read(BIO *b, char *out, int outl);
+static int ebcdic_write(BIO *b, const char *in, int inl);
+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
+static int ebcdic_gets(BIO *bp, char *buf, int size);
+static int ebcdic_puts(BIO *bp, const char *str);
+
+#define BIO_TYPE_EBCDIC_FILTER (18|0x0200)
+static BIO_METHOD methods_ebcdic=
+ {
+ BIO_TYPE_EBCDIC_FILTER,
+ "EBCDIC/ASCII filter",
+ ebcdic_write,
+ ebcdic_read,
+ ebcdic_puts,
+ ebcdic_gets,
+ ebcdic_ctrl,
+ ebcdic_new,
+ ebcdic_free,
+ };
+
+typedef struct
+{
+ size_t alloced;
+ char buff[1];
+} EBCDIC_OUTBUFF;
+
+BIO_METHOD *BIO_f_ebcdic_filter()
+{
+ return(&methods_ebcdic);
+}
+
+static int ebcdic_new(BIO *bi)
+{
+ EBCDIC_OUTBUFF *wbuf;
+
+ wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
+ wbuf->alloced = 1024;
+ wbuf->buff[0] = '\0';
+
+ bi->ptr=(char *)wbuf;
+ bi->init=1;
+ bi->flags=0;
+ return(1);
+}
+
+static int ebcdic_free(BIO *a)
+{
+ if (a == NULL) return(0);
+ if (a->ptr != NULL)
+ OPENSSL_free(a->ptr);
+ a->ptr=NULL;
+ a->init=0;
+ a->flags=0;
+ return(1);
+}
+
+static int ebcdic_read(BIO *b, char *out, int outl)
+{
+ int ret=0;
+
+ if (out == NULL || outl == 0) return(0);
+ if (b->next_bio == NULL) return(0);
+
+ ret=BIO_read(b->next_bio,out,outl);
+ if (ret > 0)
+ ascii2ebcdic(out,out,ret);
+ return(ret);
+}
+
+static int ebcdic_write(BIO *b, const char *in, int inl)
+{
+ EBCDIC_OUTBUFF *wbuf;
+ int ret=0;
+ int num;
+ unsigned char n;
+
+ if ((in == NULL) || (inl <= 0)) return(0);
+ if (b->next_bio == NULL) return(0);
+
+ wbuf=(EBCDIC_OUTBUFF *)b->ptr;
+
+ if (inl > (num = wbuf->alloced))
+ {
+ num = num + num; /* double the size */
+ if (num < inl)
+ num = inl;
+ OPENSSL_free(wbuf);
+ wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
+
+ wbuf->alloced = num;
+ wbuf->buff[0] = '\0';
+
+ b->ptr=(char *)wbuf;
+ }
+
+ ebcdic2ascii(wbuf->buff, in, inl);
+
+ ret=BIO_write(b->next_bio, wbuf->buff, inl);
+
+ return(ret);
+}
+
+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret;
+
+ if (b->next_bio == NULL) return(0);
+ switch (cmd)
+ {
+ case BIO_CTRL_DUP:
+ ret=0L;
+ break;
+ default:
+ ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+ break;
+ }
+ return(ret);
+}
+
+static int ebcdic_gets(BIO *bp, char *buf, int size)
+{
+ int i, ret=0;
+ if (bp->next_bio == NULL) return(0);
+/* return(BIO_gets(bp->next_bio,buf,size));*/
+ for (i=0; i<size-1; ++i)
+ {
+ ret = ebcdic_read(bp,&buf[i],1);
+ if (ret <= 0)
+ break;
+ else if (buf[i] == '\n')
+ {
+ ++i;
+ break;
+ }
+ }
+ if (i < size)
+ buf[i] = '\0';
+ return (ret < 0 && i == 0) ? ret : i;
+}
+
+static int ebcdic_puts(BIO *bp, const char *str)
+{
+ if (bp->next_bio == NULL) return(0);
+ return ebcdic_write(bp, str, strlen(str));
+}
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT
+
+/* This is a context that we pass to callbacks */
+typedef struct tlsextctx_st {
+ char * servername;
+ BIO * biodebug;
+ int extension_error;
+} tlsextctx;
+
+
+static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
+ {
+ tlsextctx * p = (tlsextctx *) arg;
+ const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+ if (servername && p->biodebug)
+ BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername);
+
+ if (!p->servername)
+ return SSL_TLSEXT_ERR_NOACK;
+
+ if (servername)
+ {
+ if (strcmp(servername,p->servername))
+ return p->extension_error;
+ if (ctx2)
+ {
+ BIO_printf(p->biodebug,"Switching server context.\n");
+ SSL_set_SSL_CTX(s,ctx2);
+ }
+ }
+ return SSL_TLSEXT_ERR_OK;
+}
+
+/* Structure passed to cert status callback */
+
+typedef struct tlsextstatusctx_st {
+ /* Default responder to use */
+ char *host, *path, *port;
+ int use_ssl;
+ int timeout;
+ BIO *err;
+ int verbose;
+} tlsextstatusctx;
+
+static tlsextstatusctx tlscstatp = {NULL, NULL, NULL, 0, -1, NULL, 0};
+
+/* Certificate Status callback. This is called when a client includes a
+ * certificate status request extension.
+ *
+ * This is a simplified version. It examines certificates each time and
+ * makes one OCSP responder query for each request.
+ *
+ * A full version would store details such as the OCSP certificate IDs and
+ * minimise the number of OCSP responses by caching them until they were
+ * considered "expired".
+ */
+
+static int cert_status_cb(SSL *s, void *arg)
+ {
+ tlsextstatusctx *srctx = arg;
+ BIO *err = srctx->err;
+ char *host, *port, *path;
+ int use_ssl;
+ unsigned char *rspder = NULL;
+ int rspderlen;
+ STACK_OF(OPENSSL_STRING) *aia = NULL;
+ X509 *x = NULL;
+ X509_STORE_CTX inctx;
+ X509_OBJECT obj;
+ OCSP_REQUEST *req = NULL;
+ OCSP_RESPONSE *resp = NULL;
+ OCSP_CERTID *id = NULL;
+ STACK_OF(X509_EXTENSION) *exts;
+ int ret = SSL_TLSEXT_ERR_NOACK;
+ int i;
+#if 0
+STACK_OF(OCSP_RESPID) *ids;
+SSL_get_tlsext_status_ids(s, &ids);
+BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids));
+#endif
+ if (srctx->verbose)
+ BIO_puts(err, "cert_status: callback called\n");
+ /* Build up OCSP query from server certificate */
+ x = SSL_get_certificate(s);
+ aia = X509_get1_ocsp(x);
+ if (aia)
+ {
+ if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
+ &host, &port, &path, &use_ssl))
+ {
+ BIO_puts(err, "cert_status: can't parse AIA URL\n");
+ goto err;
+ }
+ if (srctx->verbose)
+ BIO_printf(err, "cert_status: AIA URL: %s\n",
+ sk_OPENSSL_STRING_value(aia, 0));
+ }
+ else
+ {
+ if (!srctx->host)
+ {
+ BIO_puts(srctx->err, "cert_status: no AIA and no default responder URL\n");
+ goto done;
+ }
+ host = srctx->host;
+ path = srctx->path;
+ port = srctx->port;
+ use_ssl = srctx->use_ssl;
+ }
+
+ if (!X509_STORE_CTX_init(&inctx,
+ SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
+ NULL, NULL))
+ goto err;
+ if (X509_STORE_get_by_subject(&inctx,X509_LU_X509,
+ X509_get_issuer_name(x),&obj) <= 0)
+ {
+ BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n");
+ X509_STORE_CTX_cleanup(&inctx);
+ goto done;
+ }
+ req = OCSP_REQUEST_new();
+ if (!req)
+ goto err;
+ id = OCSP_cert_to_id(NULL, x, obj.data.x509);
+ X509_free(obj.data.x509);
+ X509_STORE_CTX_cleanup(&inctx);
+ if (!id)
+ goto err;
+ if (!OCSP_request_add0_id(req, id))
+ goto err;
+ id = NULL;
+ /* Add any extensions to the request */
+ SSL_get_tlsext_status_exts(s, &exts);
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++)
+ {
+ X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+ if (!OCSP_REQUEST_add_ext(req, ext, -1))
+ goto err;
+ }
+ resp = process_responder(err, req, host, path, port, use_ssl, NULL,
+ srctx->timeout);
+ if (!resp)
+ {
+ BIO_puts(err, "cert_status: error querying responder\n");
+ goto done;
+ }
+ rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
+ if (rspderlen <= 0)
+ goto err;
+ SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
+ if (srctx->verbose)
+ {
+ BIO_puts(err, "cert_status: ocsp response sent:\n");
+ OCSP_RESPONSE_print(err, resp, 2);
+ }
+ ret = SSL_TLSEXT_ERR_OK;
+ done:
+ if (ret != SSL_TLSEXT_ERR_OK)
+ ERR_print_errors(err);
+ if (aia)
+ {
+ OPENSSL_free(host);
+ OPENSSL_free(path);
+ OPENSSL_free(port);
+ X509_email_free(aia);
+ }
+ if (id)
+ OCSP_CERTID_free(id);
+ if (req)
+ OCSP_REQUEST_free(req);
+ if (resp)
+ OCSP_RESPONSE_free(resp);
+ return ret;
+ err:
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ goto done;
+ }
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+/* This is the context that we pass to next_proto_cb */
+typedef struct tlsextnextprotoctx_st {
+ unsigned char *data;
+ unsigned int len;
+} tlsextnextprotoctx;
+
+static int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len, void *arg)
+ {
+ tlsextnextprotoctx *next_proto = arg;
+
+ *data = next_proto->data;
+ *len = next_proto->len;
+
+ return SSL_TLSEXT_ERR_OK;
+ }
+# endif /* ndef OPENSSL_NO_NEXTPROTONEG */
+
+
+#endif
+
+int MAIN(int, char **);
+
+#ifndef OPENSSL_NO_JPAKE
+static char *jpake_secret = NULL;
+#endif
+#ifndef OPENSSL_NO_SRP
+ static srpsrvparm srp_callback_parm;
+#endif
+#ifndef OPENSSL_NO_SRTP
+static char *srtp_profiles = NULL;
+#endif
+
+int MAIN(int argc, char *argv[])
+ {
+ X509_VERIFY_PARAM *vpm = NULL;
+ int badarg = 0;
+ short port=PORT;
+ char *CApath=NULL,*CAfile=NULL;
+ unsigned char *context = NULL;
+ char *dhfile = NULL;
+#ifndef OPENSSL_NO_ECDH
+ char *named_curve = NULL;
+#endif
+ int badop=0,bugs=0;
+ int ret=1;
+ int off=0;
+ int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
+ int state=0;
+ const SSL_METHOD *meth=NULL;
+ int socket_type=SOCK_STREAM;
+ ENGINE *e=NULL;
+ char *inrand=NULL;
+ int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
+ char *passarg = NULL, *pass = NULL;
+ char *dpassarg = NULL, *dpass = NULL;
+ int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
+ X509 *s_cert = NULL, *s_dcert = NULL;
+ EVP_PKEY *s_key = NULL, *s_dkey = NULL;
+ int no_cache = 0;
+#ifndef OPENSSL_NO_TLSEXT
+ EVP_PKEY *s_key2 = NULL;
+ X509 *s_cert2 = NULL;
+ tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
+# ifndef OPENSSL_NO_NEXTPROTONEG
+ const char *next_proto_neg_in = NULL;
+ tlsextnextprotoctx next_proto;
+# endif
+#endif
+#ifndef OPENSSL_NO_PSK
+ /* by default do not send a PSK identity hint */
+ static char *psk_identity_hint=NULL;
+#endif
+#ifndef OPENSSL_NO_SRP
+ char *srpuserseed = NULL;
+ char *srp_verifier_file = NULL;
+#endif
+ meth=SSLv23_server_method();
+
+ local_argc=argc;
+ local_argv=argv;
+
+ apps_startup();
+#ifdef MONOLITH
+ s_server_init();
+#endif
+
+ if (bio_err == NULL)
+ bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ verify_depth=0;
+#ifdef FIONBIO
+ s_nbio=0;
+#endif
+ s_nbio_test=0;
+
+ argc--;
+ argv++;
+
+ while (argc >= 1)
+ {
+ if ((strcmp(*argv,"-port") == 0) ||
+ (strcmp(*argv,"-accept") == 0))
+ {
+ if (--argc < 1) goto bad;
+ if (!extract_port(*(++argv),&port))
+ goto bad;
+ }
+ else if (strcmp(*argv,"-verify") == 0)
+ {
+ s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
+ if (--argc < 1) goto bad;
+ verify_depth=atoi(*(++argv));
+ BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
+ }
+ else if (strcmp(*argv,"-Verify") == 0)
+ {
+ s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
+ SSL_VERIFY_CLIENT_ONCE;
+ if (--argc < 1) goto bad;
+ verify_depth=atoi(*(++argv));
+ BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth);
+ }
+ else if (strcmp(*argv,"-context") == 0)
+ {
+ if (--argc < 1) goto bad;
+ context= (unsigned char *)*(++argv);
+ }
+ else if (strcmp(*argv,"-cert") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_cert_file= *(++argv);
+ }
+ else if (strcmp(*argv,"-certform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_cert_format = str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-key") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_key_file= *(++argv);
+ }
+ else if (strcmp(*argv,"-keyform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_key_format = str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-pass") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passarg = *(++argv);
+ }
+ else if (strcmp(*argv,"-dhparam") == 0)
+ {
+ if (--argc < 1) goto bad;
+ dhfile = *(++argv);
+ }
+#ifndef OPENSSL_NO_ECDH
+ else if (strcmp(*argv,"-named_curve") == 0)
+ {
+ if (--argc < 1) goto bad;
+ named_curve = *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-dcertform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_dcert_format = str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-dcert") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_dcert_file= *(++argv);
+ }
+ else if (strcmp(*argv,"-dkeyform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_dkey_format = str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-dpass") == 0)
+ {
+ if (--argc < 1) goto bad;
+ dpassarg = *(++argv);
+ }
+ else if (strcmp(*argv,"-dkey") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_dkey_file= *(++argv);
+ }
+ else if (strcmp(*argv,"-nocert") == 0)
+ {
+ nocert=1;
+ }
+ else if (strcmp(*argv,"-CApath") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CApath= *(++argv);
+ }
+ else if (strcmp(*argv,"-no_cache") == 0)
+ no_cache = 1;
+ else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
+ {
+ if (badarg)
+ goto bad;
+ continue;
+ }
+ else if (strcmp(*argv,"-verify_return_error") == 0)
+ verify_return_error = 1;
+ else if (strcmp(*argv,"-serverpref") == 0)
+ { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
+ else if (strcmp(*argv,"-legacy_renegotiation") == 0)
+ off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
+ else if (strcmp(*argv,"-cipher") == 0)
+ {
+ if (--argc < 1) goto bad;
+ cipher= *(++argv);
+ }
+ else if (strcmp(*argv,"-CAfile") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CAfile= *(++argv);
+ }
+#ifdef FIONBIO
+ else if (strcmp(*argv,"-nbio") == 0)
+ { s_nbio=1; }
+#endif
+ else if (strcmp(*argv,"-nbio_test") == 0)
+ {
+#ifdef FIONBIO
+ s_nbio=1;
+#endif
+ s_nbio_test=1;
+ }
+ else if (strcmp(*argv,"-debug") == 0)
+ { s_debug=1; }
+#ifndef OPENSSL_NO_TLSEXT
+ else if (strcmp(*argv,"-tlsextdebug") == 0)
+ s_tlsextdebug=1;
+ else if (strcmp(*argv,"-status") == 0)
+ s_tlsextstatus=1;
+ else if (strcmp(*argv,"-status_verbose") == 0)
+ {
+ s_tlsextstatus=1;
+ tlscstatp.verbose = 1;
+ }
+ else if (!strcmp(*argv, "-status_timeout"))
+ {
+ s_tlsextstatus=1;
+ if (--argc < 1) goto bad;
+ tlscstatp.timeout = atoi(*(++argv));
+ }
+ else if (!strcmp(*argv, "-status_url"))
+ {
+ s_tlsextstatus=1;
+ if (--argc < 1) goto bad;
+ if (!OCSP_parse_url(*(++argv),
+ &tlscstatp.host,
+ &tlscstatp.port,
+ &tlscstatp.path,
+ &tlscstatp.use_ssl))
+ {
+ BIO_printf(bio_err, "Error parsing URL\n");
+ goto bad;
+ }
+ }
+#endif
+ else if (strcmp(*argv,"-msg") == 0)
+ { s_msg=1; }
+ else if (strcmp(*argv,"-hack") == 0)
+ { hack=1; }
+ else if (strcmp(*argv,"-state") == 0)
+ { state=1; }
+ else if (strcmp(*argv,"-crlf") == 0)
+ { s_crlf=1; }
+ else if (strcmp(*argv,"-quiet") == 0)
+ { s_quiet=1; }
+ else if (strcmp(*argv,"-bugs") == 0)
+ { bugs=1; }
+ else if (strcmp(*argv,"-no_tmp_rsa") == 0)
+ { no_tmp_rsa=1; }
+ else if (strcmp(*argv,"-no_dhe") == 0)
+ { no_dhe=1; }
+ else if (strcmp(*argv,"-no_ecdhe") == 0)
+ { no_ecdhe=1; }
+#ifndef OPENSSL_NO_PSK
+ else if (strcmp(*argv,"-psk_hint") == 0)
+ {
+ if (--argc < 1) goto bad;
+ psk_identity_hint= *(++argv);
+ }
+ else if (strcmp(*argv,"-psk") == 0)
+ {
+ size_t i;
+
+ if (--argc < 1) goto bad;
+ psk_key=*(++argv);
+ for (i=0; i<strlen(psk_key); i++)
+ {
+ if (isxdigit((unsigned char)psk_key[i]))
+ continue;
+ BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
+ goto bad;
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_SRP
+ else if (strcmp(*argv, "-srpvfile") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srp_verifier_file = *(++argv);
+ meth = TLSv1_server_method();
+ }
+ else if (strcmp(*argv, "-srpuserseed") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srpuserseed = *(++argv);
+ meth = TLSv1_server_method();
+ }
+#endif
+ else if (strcmp(*argv,"-www") == 0)
+ { www=1; }
+ else if (strcmp(*argv,"-WWW") == 0)
+ { www=2; }
+ else if (strcmp(*argv,"-HTTP") == 0)
+ { www=3; }
+ else if (strcmp(*argv,"-no_ssl2") == 0)
+ { off|=SSL_OP_NO_SSLv2; }
+ else if (strcmp(*argv,"-no_ssl3") == 0)
+ { off|=SSL_OP_NO_SSLv3; }
+ else if (strcmp(*argv,"-no_tls1") == 0)
+ { off|=SSL_OP_NO_TLSv1; }
+ else if (strcmp(*argv,"-no_tls1_1") == 0)
+ { off|=SSL_OP_NO_TLSv1_1; }
+ else if (strcmp(*argv,"-no_tls1_2") == 0)
+ { off|=SSL_OP_NO_TLSv1_2; }
+ else if (strcmp(*argv,"-no_comp") == 0)
+ { off|=SSL_OP_NO_COMPRESSION; }
+#ifndef OPENSSL_NO_TLSEXT
+ else if (strcmp(*argv,"-no_ticket") == 0)
+ { off|=SSL_OP_NO_TICKET; }
+#endif
+#ifndef OPENSSL_NO_SSL2
+ else if (strcmp(*argv,"-ssl2") == 0)
+ { meth=SSLv2_server_method(); }
+#endif
+#ifndef OPENSSL_NO_SSL3
+ else if (strcmp(*argv,"-ssl3") == 0)
+ { meth=SSLv3_server_method(); }
+#endif
+#ifndef OPENSSL_NO_TLS1
+ else if (strcmp(*argv,"-tls1") == 0)
+ { meth=TLSv1_server_method(); }
+ else if (strcmp(*argv,"-tls1_1") == 0)
+ { meth=TLSv1_1_server_method(); }
+ else if (strcmp(*argv,"-tls1_2") == 0)
+ { meth=TLSv1_2_server_method(); }
+#endif
+#ifndef OPENSSL_NO_DTLS1
+ else if (strcmp(*argv,"-dtls1") == 0)
+ {
+ meth=DTLSv1_server_method();
+ socket_type = SOCK_DGRAM;
+ }
+ else if (strcmp(*argv,"-timeout") == 0)
+ enable_timeouts = 1;
+ else if (strcmp(*argv,"-mtu") == 0)
+ {
+ if (--argc < 1) goto bad;
+ socket_mtu = atol(*(++argv));
+ }
+ else if (strcmp(*argv, "-chain") == 0)
+ cert_chain = 1;
+#endif
+ else if (strcmp(*argv, "-id_prefix") == 0)
+ {
+ if (--argc < 1) goto bad;
+ session_id_prefix = *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine_id= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-rand") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inrand= *(++argv);
+ }
+#ifndef OPENSSL_NO_TLSEXT
+ else if (strcmp(*argv,"-servername") == 0)
+ {
+ if (--argc < 1) goto bad;
+ tlsextcbp.servername= *(++argv);
+ }
+ else if (strcmp(*argv,"-servername_fatal") == 0)
+ { tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; }
+ else if (strcmp(*argv,"-cert2") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_cert_file2= *(++argv);
+ }
+ else if (strcmp(*argv,"-key2") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_key_file2= *(++argv);
+ }
+# ifndef OPENSSL_NO_NEXTPROTONEG
+ else if (strcmp(*argv,"-nextprotoneg") == 0)
+ {
+ if (--argc < 1) goto bad;
+ next_proto_neg_in = *(++argv);
+ }
+# endif
+#endif
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+ else if (strcmp(*argv,"-jpake") == 0)
+ {
+ if (--argc < 1) goto bad;
+ jpake_secret = *(++argv);
+ }
+#endif
+#ifndef OPENSSL_NO_SRTP
+ else if (strcmp(*argv,"-use_srtp") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srtp_profiles = *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-keymatexport") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keymatexportlabel= *(++argv);
+ }
+ else if (strcmp(*argv,"-keymatexportlen") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keymatexportlen=atoi(*(++argv));
+ if (keymatexportlen == 0) goto bad;
+ }
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badop=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+ if (badop)
+ {
+bad:
+ sv_usage();
+ goto end;
+ }
+
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+ if (jpake_secret)
+ {
+ if (psk_key)
+ {
+ BIO_printf(bio_err,
+ "Can't use JPAKE and PSK together\n");
+ goto end;
+ }
+ psk_identity = "JPAKE";
+ if (cipher)
+ {
+ BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
+ goto end;
+ }
+ cipher = "PSK";
+ }
+
+#endif
+
+ SSL_load_error_strings();
+ OpenSSL_add_ssl_algorithms();
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine_id, 1);
+#endif
+
+ if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass))
+ {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+
+ if (s_key_file == NULL)
+ s_key_file = s_cert_file;
+#ifndef OPENSSL_NO_TLSEXT
+ if (s_key_file2 == NULL)
+ s_key_file2 = s_cert_file2;
+#endif
+
+ if (nocert == 0)
+ {
+ s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
+ "server certificate private key file");
+ if (!s_key)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ s_cert = load_cert(bio_err,s_cert_file,s_cert_format,
+ NULL, e, "server certificate file");
+
+ if (!s_cert)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_TLSEXT
+ if (tlsextcbp.servername)
+ {
+ s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e,
+ "second server certificate private key file");
+ if (!s_key2)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ s_cert2 = load_cert(bio_err,s_cert_file2,s_cert_format,
+ NULL, e, "second server certificate file");
+
+ if (!s_cert2)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+#endif
+ }
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ if (next_proto_neg_in)
+ {
+ unsigned short len;
+ next_proto.data = next_protos_parse(&len, next_proto_neg_in);
+ if (next_proto.data == NULL)
+ goto end;
+ next_proto.len = len;
+ }
+ else
+ {
+ next_proto.data = NULL;
+ }
+#endif
+
+
+ if (s_dcert_file)
+ {
+
+ if (s_dkey_file == NULL)
+ s_dkey_file = s_dcert_file;
+
+ s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
+ 0, dpass, e,
+ "second certificate private key file");
+ if (!s_dkey)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ s_dcert = load_cert(bio_err,s_dcert_file,s_dcert_format,
+ NULL, e, "second server certificate file");
+
+ if (!s_dcert)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ }
+
+ if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
+ && !RAND_status())
+ {
+ BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+ }
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+
+ if (bio_s_out == NULL)
+ {
+ if (s_quiet && !s_debug && !s_msg)
+ {
+ bio_s_out=BIO_new(BIO_s_null());
+ }
+ else
+ {
+ if (bio_s_out == NULL)
+ bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE);
+ }
+ }
+
+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
+ if (nocert)
+#endif
+ {
+ s_cert_file=NULL;
+ s_key_file=NULL;
+ s_dcert_file=NULL;
+ s_dkey_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+ s_cert_file2=NULL;
+ s_key_file2=NULL;
+#endif
+ }
+
+ ctx=SSL_CTX_new(meth);
+ if (ctx == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (session_id_prefix)
+ {
+ if(strlen(session_id_prefix) >= 32)
+ BIO_printf(bio_err,
+"warning: id_prefix is too long, only one new session will be possible\n");
+ else if(strlen(session_id_prefix) >= 16)
+ BIO_printf(bio_err,
+"warning: id_prefix is too long if you use SSLv2\n");
+ if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id))
+ {
+ BIO_printf(bio_err,"error setting 'id_prefix'\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
+ }
+ SSL_CTX_set_quiet_shutdown(ctx,1);
+ if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
+ if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
+ SSL_CTX_set_options(ctx,off);
+ /* DTLS: partial reads end up discarding unread UDP bytes :-(
+ * Setting read ahead solves this problem.
+ */
+ if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
+
+ if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
+ if (no_cache)
+ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
+ else
+ SSL_CTX_sess_set_cache_size(ctx,128);
+
+#ifndef OPENSSL_NO_SRTP
+ if (srtp_profiles != NULL)
+ SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
+#endif
+
+#if 0
+ if (cipher == NULL) cipher=getenv("SSL_CIPHER");
+#endif
+
+#if 0
+ if (s_cert_file == NULL)
+ {
+ BIO_printf(bio_err,"You must specify a certificate file for the server to use\n");
+ goto end;
+ }
+#endif
+
+ if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
+ (!SSL_CTX_set_default_verify_paths(ctx)))
+ {
+ /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
+ ERR_print_errors(bio_err);
+ /* goto end; */
+ }
+ if (vpm)
+ SSL_CTX_set1_param(ctx, vpm);
+
+#ifndef OPENSSL_NO_TLSEXT
+ if (s_cert2)
+ {
+ ctx2=SSL_CTX_new(meth);
+ if (ctx2 == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (ctx2)
+ {
+ BIO_printf(bio_s_out,"Setting secondary ctx parameters\n");
+
+ if (session_id_prefix)
+ {
+ if(strlen(session_id_prefix) >= 32)
+ BIO_printf(bio_err,
+ "warning: id_prefix is too long, only one new session will be possible\n");
+ else if(strlen(session_id_prefix) >= 16)
+ BIO_printf(bio_err,
+ "warning: id_prefix is too long if you use SSLv2\n");
+ if(!SSL_CTX_set_generate_session_id(ctx2, generate_session_id))
+ {
+ BIO_printf(bio_err,"error setting 'id_prefix'\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
+ }
+ SSL_CTX_set_quiet_shutdown(ctx2,1);
+ if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL);
+ if (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
+ SSL_CTX_set_options(ctx2,off);
+ /* DTLS: partial reads end up discarding unread UDP bytes :-(
+ * Setting read ahead solves this problem.
+ */
+ if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1);
+
+ if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
+
+ if (no_cache)
+ SSL_CTX_set_session_cache_mode(ctx2,SSL_SESS_CACHE_OFF);
+ else
+ SSL_CTX_sess_set_cache_size(ctx2,128);
+
+ if ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) ||
+ (!SSL_CTX_set_default_verify_paths(ctx2)))
+ {
+ ERR_print_errors(bio_err);
+ }
+ if (vpm)
+ SSL_CTX_set1_param(ctx2, vpm);
+ }
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+ if (next_proto.data)
+ SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto);
+# endif
+#endif
+
+#ifndef OPENSSL_NO_DH
+ if (!no_dhe)
+ {
+ DH *dh=NULL;
+
+ if (dhfile)
+ dh = load_dh_param(dhfile);
+ else if (s_cert_file)
+ dh = load_dh_param(s_cert_file);
+
+ if (dh != NULL)
+ {
+ BIO_printf(bio_s_out,"Setting temp DH parameters\n");
+ }
+ else
+ {
+ BIO_printf(bio_s_out,"Using default temp DH parameters\n");
+ dh=get_dh512();
+ }
+ (void)BIO_flush(bio_s_out);
+
+ SSL_CTX_set_tmp_dh(ctx,dh);
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ {
+ if (!dhfile)
+ {
+ DH *dh2=load_dh_param(s_cert_file2);
+ if (dh2 != NULL)
+ {
+ BIO_printf(bio_s_out,"Setting temp DH parameters\n");
+ (void)BIO_flush(bio_s_out);
+
+ DH_free(dh);
+ dh = dh2;
+ }
+ }
+ SSL_CTX_set_tmp_dh(ctx2,dh);
+ }
+#endif
+ DH_free(dh);
+ }
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+ if (!no_ecdhe)
+ {
+ EC_KEY *ecdh=NULL;
+
+ if (named_curve)
+ {
+ int nid = OBJ_sn2nid(named_curve);
+
+ if (nid == 0)
+ {
+ BIO_printf(bio_err, "unknown curve name (%s)\n",
+ named_curve);
+ goto end;
+ }
+ ecdh = EC_KEY_new_by_curve_name(nid);
+ if (ecdh == NULL)
+ {
+ BIO_printf(bio_err, "unable to create curve (%s)\n",
+ named_curve);
+ goto end;
+ }
+ }
+
+ if (ecdh != NULL)
+ {
+ BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");
+ }
+ else
+ {
+ BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
+ ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+ if (ecdh == NULL)
+ {
+ BIO_printf(bio_err, "unable to create curve (nistp256)\n");
+ goto end;
+ }
+ }
+ (void)BIO_flush(bio_s_out);
+
+ SSL_CTX_set_tmp_ecdh(ctx,ecdh);
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ SSL_CTX_set_tmp_ecdh(ctx2,ecdh);
+#endif
+ EC_KEY_free(ecdh);
+ }
+#endif
+
+ if (!set_cert_key_stuff(ctx, s_cert, s_key))
+ goto end;
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2))
+ goto end;
+#endif
+ if (s_dcert != NULL)
+ {
+ if (!set_cert_key_stuff(ctx, s_dcert, s_dkey))
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_RSA
+#if 1
+ if (!no_tmp_rsa)
+ {
+ SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ SSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb);
+#endif
+ }
+#else
+ if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
+ {
+ RSA *rsa;
+
+ BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");
+ BIO_flush(bio_s_out);
+
+ rsa=RSA_generate_key(512,RSA_F4,NULL);
+
+ if (!SSL_CTX_set_tmp_rsa(ctx,rsa))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ {
+ if (!SSL_CTX_set_tmp_rsa(ctx2,rsa))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+#endif
+ RSA_free(rsa);
+ BIO_printf(bio_s_out,"\n");
+ }
+#endif
+#endif
+
+#ifndef OPENSSL_NO_PSK
+#ifdef OPENSSL_NO_JPAKE
+ if (psk_key != NULL)
+#else
+ if (psk_key != NULL || jpake_secret)
+#endif
+ {
+ if (s_debug)
+ BIO_printf(bio_s_out, "PSK key given or JPAKE in use, setting server callback\n");
+ SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
+ }
+
+ if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint))
+ {
+ BIO_printf(bio_err,"error setting PSK identity hint to context\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+#endif
+
+ if (cipher != NULL)
+ {
+ if(!SSL_CTX_set_cipher_list(ctx,cipher))
+ {
+ BIO_printf(bio_err,"error setting cipher list\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher))
+ {
+ BIO_printf(bio_err,"error setting cipher list\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+#endif
+ }
+ SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
+ SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
+ sizeof s_server_session_id_context);
+
+ /* Set DTLS cookie generation and verification callbacks */
+ SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
+ SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
+
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ {
+ SSL_CTX_set_verify(ctx2,s_server_verify,verify_callback);
+ SSL_CTX_set_session_id_context(ctx2,(void*)&s_server_session_id_context,
+ sizeof s_server_session_id_context);
+
+ tlsextcbp.biodebug = bio_s_out;
+ SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
+ SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
+ SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+ SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
+ }
+#endif
+
+#ifndef OPENSSL_NO_SRP
+ if (srp_verifier_file != NULL)
+ {
+ srp_callback_parm.vb = SRP_VBASE_new(srpuserseed);
+ srp_callback_parm.user = NULL;
+ srp_callback_parm.login = NULL;
+ if ((ret = SRP_VBASE_init(srp_callback_parm.vb, srp_verifier_file)) != SRP_NO_ERROR)
+ {
+ BIO_printf(bio_err,
+ "Cannot initialize SRP verifier file \"%s\":ret=%d\n",
+ srp_verifier_file, ret);
+ goto end;
+ }
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE,verify_callback);
+ SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm);
+ SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
+ }
+ else
+#endif
+ if (CAfile != NULL)
+ {
+ SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile));
+#endif
+ }
+
+ BIO_printf(bio_s_out,"ACCEPT\n");
+ (void)BIO_flush(bio_s_out);
+ if (www)
+ do_server(port,socket_type,&accept_socket,www_body, context);
+ else
+ do_server(port,socket_type,&accept_socket,sv_body, context);
+ print_stats(bio_s_out,ctx);
+ ret=0;
+end:
+ if (ctx != NULL) SSL_CTX_free(ctx);
+ if (s_cert)
+ X509_free(s_cert);
+ if (s_dcert)
+ X509_free(s_dcert);
+ if (s_key)
+ EVP_PKEY_free(s_key);
+ if (s_dkey)
+ EVP_PKEY_free(s_dkey);
+ if (pass)
+ OPENSSL_free(pass);
+ if (dpass)
+ OPENSSL_free(dpass);
+ if (vpm)
+ X509_VERIFY_PARAM_free(vpm);
+#ifndef OPENSSL_NO_TLSEXT
+ if (tlscstatp.host)
+ OPENSSL_free(tlscstatp.host);
+ if (tlscstatp.port)
+ OPENSSL_free(tlscstatp.port);
+ if (tlscstatp.path)
+ OPENSSL_free(tlscstatp.path);
+ if (ctx2 != NULL) SSL_CTX_free(ctx2);
+ if (s_cert2)
+ X509_free(s_cert2);
+ if (s_key2)
+ EVP_PKEY_free(s_key2);
+#endif
+ if (bio_s_out != NULL)
+ {
+ BIO_free(bio_s_out);
+ bio_s_out=NULL;
+ }
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
+ {
+ BIO_printf(bio,"%4ld items in the session cache\n",
+ SSL_CTX_sess_number(ssl_ctx));
+ BIO_printf(bio,"%4ld client connects (SSL_connect())\n",
+ SSL_CTX_sess_connect(ssl_ctx));
+ BIO_printf(bio,"%4ld client renegotiates (SSL_connect())\n",
+ SSL_CTX_sess_connect_renegotiate(ssl_ctx));
+ BIO_printf(bio,"%4ld client connects that finished\n",
+ SSL_CTX_sess_connect_good(ssl_ctx));
+ BIO_printf(bio,"%4ld server accepts (SSL_accept())\n",
+ SSL_CTX_sess_accept(ssl_ctx));
+ BIO_printf(bio,"%4ld server renegotiates (SSL_accept())\n",
+ SSL_CTX_sess_accept_renegotiate(ssl_ctx));
+ BIO_printf(bio,"%4ld server accepts that finished\n",
+ SSL_CTX_sess_accept_good(ssl_ctx));
+ BIO_printf(bio,"%4ld session cache hits\n",SSL_CTX_sess_hits(ssl_ctx));
+ BIO_printf(bio,"%4ld session cache misses\n",SSL_CTX_sess_misses(ssl_ctx));
+ BIO_printf(bio,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx));
+ BIO_printf(bio,"%4ld callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx));
+ BIO_printf(bio,"%4ld cache full overflows (%ld allowed)\n",
+ SSL_CTX_sess_cache_full(ssl_ctx),
+ SSL_CTX_sess_get_cache_size(ssl_ctx));
+ }
+
+static int sv_body(char *hostname, int s, unsigned char *context)
+ {
+ char *buf=NULL;
+ fd_set readfds;
+ int ret=1,width;
+ int k,i;
+ unsigned long l;
+ SSL *con=NULL;
+ BIO *sbio;
+#ifndef OPENSSL_NO_KRB5
+ KSSL_CTX *kctx;
+#endif
+ struct timeval timeout;
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
+ struct timeval tv;
+#else
+ struct timeval *timeoutp;
+#endif
+
+ if ((buf=OPENSSL_malloc(bufsize)) == NULL)
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ goto err;
+ }
+#ifdef FIONBIO
+ if (s_nbio)
+ {
+ unsigned long sl=1;
+
+ if (!s_quiet)
+ BIO_printf(bio_err,"turning on non blocking io\n");
+ if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
+ ERR_print_errors(bio_err);
+ }
+#endif
+
+ if (con == NULL) {
+ con=SSL_new(ctx);
+#ifndef OPENSSL_NO_TLSEXT
+ if (s_tlsextdebug)
+ {
+ SSL_set_tlsext_debug_callback(con, tlsext_cb);
+ SSL_set_tlsext_debug_arg(con, bio_s_out);
+ }
+ if (s_tlsextstatus)
+ {
+ SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
+ tlscstatp.err = bio_err;
+ SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp);
+ }
+#endif
+#ifndef OPENSSL_NO_KRB5
+ if ((kctx = kssl_ctx_new()) != NULL)
+ {
+ SSL_set0_kssl_ctx(con, kctx);
+ kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
+ kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
+ }
+#endif /* OPENSSL_NO_KRB5 */
+ if(context)
+ SSL_set_session_id_context(con, context,
+ strlen((char *)context));
+ }
+ SSL_clear(con);
+#if 0
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ SSL_set_tlsext_opaque_prf_input(con, "Test server", 11);
+#endif
+#endif
+
+ if (SSL_version(con) == DTLS1_VERSION)
+ {
+
+ sbio=BIO_new_dgram(s,BIO_NOCLOSE);
+
+ if (enable_timeouts)
+ {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = DGRAM_RCV_TIMEOUT;
+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = DGRAM_SND_TIMEOUT;
+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
+ }
+
+ if (socket_mtu > 28)
+ {
+ SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
+ SSL_set_mtu(con, socket_mtu - 28);
+ }
+ else
+ /* want to do MTU discovery */
+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
+
+ /* turn on cookie exchange */
+ SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
+ }
+ else
+ sbio=BIO_new_socket(s,BIO_NOCLOSE);
+
+ if (s_nbio_test)
+ {
+ BIO *test;
+
+ test=BIO_new(BIO_f_nbio_test());
+ sbio=BIO_push(test,sbio);
+ }
+#ifndef OPENSSL_NO_JPAKE
+ if(jpake_secret)
+ jpake_server_auth(bio_s_out, sbio, jpake_secret);
+#endif
+
+ SSL_set_bio(con,sbio,sbio);
+ SSL_set_accept_state(con);
+ /* SSL_set_fd(con,s); */
+
+ if (s_debug)
+ {
+ SSL_set_debug(con, 1);
+ BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
+ BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out);
+ }
+ if (s_msg)
+ {
+ SSL_set_msg_callback(con, msg_cb);
+ SSL_set_msg_callback_arg(con, bio_s_out);
+ }
+#ifndef OPENSSL_NO_TLSEXT
+ if (s_tlsextdebug)
+ {
+ SSL_set_tlsext_debug_callback(con, tlsext_cb);
+ SSL_set_tlsext_debug_arg(con, bio_s_out);
+ }
+#endif
+
+ width=s+1;
+ for (;;)
+ {
+ int read_from_terminal;
+ int read_from_sslcon;
+
+ read_from_terminal = 0;
+ read_from_sslcon = SSL_pending(con);
+
+ if (!read_from_sslcon)
+ {
+ FD_ZERO(&readfds);
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5)
+ openssl_fdset(fileno(stdin),&readfds);
+#endif
+ openssl_fdset(s,&readfds);
+ /* Note: under VMS with SOCKETSHR the second parameter is
+ * currently of type (int *) whereas under other systems
+ * it is (void *) if you don't have a cast it will choke
+ * the compiler: if you do have a cast then you can either
+ * go for (int *) or (void *).
+ */
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
+ /* Under DOS (non-djgpp) and Windows we can't select on stdin: only
+ * on sockets. As a workaround we timeout the select every
+ * second and check for any keypress. In a proper Windows
+ * application we wouldn't do this because it is inefficient.
+ */
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ i=select(width,(void *)&readfds,NULL,NULL,&tv);
+ if((i < 0) || (!i && !_kbhit() ) )continue;
+ if(_kbhit())
+ read_from_terminal = 1;
+#elif defined(OPENSSL_SYS_BEOS_R5)
+ /* Under BeOS-R5 the situation is similar to DOS */
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+ i=select(width,(void *)&readfds,NULL,NULL,&tv);
+ if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0))
+ continue;
+ if (read(fileno(stdin), buf, 0) >= 0)
+ read_from_terminal = 1;
+ (void)fcntl(fileno(stdin), F_SETFL, 0);
+#else
+ if ((SSL_version(con) == DTLS1_VERSION) &&
+ DTLSv1_get_timeout(con, &timeout))
+ timeoutp = &timeout;
+ else
+ timeoutp = NULL;
+
+ i=select(width,(void *)&readfds,NULL,NULL,timeoutp);
+
+ if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
+ {
+ BIO_printf(bio_err,"TIMEOUT occured\n");
+ }
+
+ if (i <= 0) continue;
+ if (FD_ISSET(fileno(stdin),&readfds))
+ read_from_terminal = 1;
+#endif
+ if (FD_ISSET(s,&readfds))
+ read_from_sslcon = 1;
+ }
+ if (read_from_terminal)
+ {
+ if (s_crlf)
+ {
+ int j, lf_num;
+
+ i=raw_read_stdin(buf, bufsize/2);
+ lf_num = 0;
+ /* both loops are skipped when i <= 0 */
+ for (j = 0; j < i; j++)
+ if (buf[j] == '\n')
+ lf_num++;
+ for (j = i-1; j >= 0; j--)
+ {
+ buf[j+lf_num] = buf[j];
+ if (buf[j] == '\n')
+ {
+ lf_num--;
+ i++;
+ buf[j+lf_num] = '\r';
+ }
+ }
+ assert(lf_num == 0);
+ }
+ else
+ i=raw_read_stdin(buf,bufsize);
+ if (!s_quiet)
+ {
+ if ((i <= 0) || (buf[0] == 'Q'))
+ {
+ BIO_printf(bio_s_out,"DONE\n");
+ SHUTDOWN(s);
+ close_accept_socket();
+ ret= -11;
+ goto err;
+ }
+ if ((i <= 0) || (buf[0] == 'q'))
+ {
+ BIO_printf(bio_s_out,"DONE\n");
+ if (SSL_version(con) != DTLS1_VERSION)
+ SHUTDOWN(s);
+ /* close_accept_socket();
+ ret= -11;*/
+ goto err;
+ }
+
+#ifndef OPENSSL_NO_HEARTBEATS
+ if ((buf[0] == 'B') &&
+ ((buf[1] == '\n') || (buf[1] == '\r')))
+ {
+ BIO_printf(bio_err,"HEARTBEATING\n");
+ SSL_heartbeat(con);
+ i=0;
+ continue;
+ }
+#endif
+ if ((buf[0] == 'r') &&
+ ((buf[1] == '\n') || (buf[1] == '\r')))
+ {
+ SSL_renegotiate(con);
+ i=SSL_do_handshake(con);
+ printf("SSL_do_handshake -> %d\n",i);
+ i=0; /*13; */
+ continue;
+ /* strcpy(buf,"server side RE-NEGOTIATE\n"); */
+ }
+ if ((buf[0] == 'R') &&
+ ((buf[1] == '\n') || (buf[1] == '\r')))
+ {
+ SSL_set_verify(con,
+ SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL);
+ SSL_renegotiate(con);
+ i=SSL_do_handshake(con);
+ printf("SSL_do_handshake -> %d\n",i);
+ i=0; /* 13; */
+ continue;
+ /* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */
+ }
+ if (buf[0] == 'P')
+ {
+ static const char *str="Lets print some clear text\n";
+ BIO_write(SSL_get_wbio(con),str,strlen(str));
+ }
+ if (buf[0] == 'S')
+ {
+ print_stats(bio_s_out,SSL_get_SSL_CTX(con));
+ }
+ }
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(buf,buf,i);
+#endif
+ l=k=0;
+ for (;;)
+ {
+ /* should do a select for the write */
+#ifdef RENEG
+{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
+#endif
+ k=SSL_write(con,&(buf[l]),(unsigned int)i);
+#ifndef OPENSSL_NO_SRP
+ while (SSL_get_error(con,k) == SSL_ERROR_WANT_X509_LOOKUP)
+ {
+ BIO_printf(bio_s_out,"LOOKUP renego during write\n");
+ srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out,"LOOKUP not successful\n");
+ k=SSL_write(con,&(buf[l]),(unsigned int)i);
+ }
+#endif
+ switch (SSL_get_error(con,k))
+ {
+ case SSL_ERROR_NONE:
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ BIO_printf(bio_s_out,"Write BLOCK\n");
+ break;
+ case SSL_ERROR_SYSCALL:
+ case SSL_ERROR_SSL:
+ BIO_printf(bio_s_out,"ERROR\n");
+ ERR_print_errors(bio_err);
+ ret=1;
+ goto err;
+ /* break; */
+ case SSL_ERROR_ZERO_RETURN:
+ BIO_printf(bio_s_out,"DONE\n");
+ ret=1;
+ goto err;
+ }
+ l+=k;
+ i-=k;
+ if (i <= 0) break;
+ }
+ }
+ if (read_from_sslcon)
+ {
+ if (!SSL_is_init_finished(con))
+ {
+ i=init_ssl_connection(con);
+
+ if (i < 0)
+ {
+ ret=0;
+ goto err;
+ }
+ else if (i == 0)
+ {
+ ret=1;
+ goto err;
+ }
+ }
+ else
+ {
+again:
+ i=SSL_read(con,(char *)buf,bufsize);
+#ifndef OPENSSL_NO_SRP
+ while (SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
+ {
+ BIO_printf(bio_s_out,"LOOKUP renego during read\n");
+ srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out,"LOOKUP not successful\n");
+ i=SSL_read(con,(char *)buf,bufsize);
+ }
+#endif
+ switch (SSL_get_error(con,i))
+ {
+ case SSL_ERROR_NONE:
+#ifdef CHARSET_EBCDIC
+ ascii2ebcdic(buf,buf,i);
+#endif
+ raw_write_stdout(buf,
+ (unsigned int)i);
+ if (SSL_pending(con)) goto again;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ BIO_printf(bio_s_out,"Read BLOCK\n");
+ break;
+ case SSL_ERROR_SYSCALL:
+ case SSL_ERROR_SSL:
+ BIO_printf(bio_s_out,"ERROR\n");
+ ERR_print_errors(bio_err);
+ ret=1;
+ goto err;
+ case SSL_ERROR_ZERO_RETURN:
+ BIO_printf(bio_s_out,"DONE\n");
+ ret=1;
+ goto err;
+ }
+ }
+ }
+ }
+err:
+ if (con != NULL)
+ {
+ BIO_printf(bio_s_out,"shutting down SSL\n");
+#if 1
+ SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+#else
+ SSL_shutdown(con);
+#endif
+ SSL_free(con);
+ }
+ BIO_printf(bio_s_out,"CONNECTION CLOSED\n");
+ if (buf != NULL)
+ {
+ OPENSSL_cleanse(buf,bufsize);
+ OPENSSL_free(buf);
+ }
+ if (ret >= 0)
+ BIO_printf(bio_s_out,"ACCEPT\n");
+ return(ret);
+ }
+
+static void close_accept_socket(void)
+ {
+ BIO_printf(bio_err,"shutdown accept socket\n");
+ if (accept_socket >= 0)
+ {
+ SHUTDOWN2(accept_socket);
+ }
+ }
+
+static int init_ssl_connection(SSL *con)
+ {
+ int i;
+ const char *str;
+ X509 *peer;
+ long verify_error;
+ MS_STATIC char buf[BUFSIZ];
+#ifndef OPENSSL_NO_KRB5
+ char *client_princ;
+#endif
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ const unsigned char *next_proto_neg;
+ unsigned next_proto_neg_len;
+#endif
+ unsigned char *exportedkeymat;
+
+
+ i=SSL_accept(con);
+#ifndef OPENSSL_NO_SRP
+ while (i <= 0 && SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
+ {
+ BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
+ srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out,"LOOKUP not successful\n");
+ i=SSL_accept(con);
+ }
+#endif
+ if (i <= 0)
+ {
+ if (BIO_sock_should_retry(i))
+ {
+ BIO_printf(bio_s_out,"DELAY\n");
+ return(1);
+ }
+
+ BIO_printf(bio_err,"ERROR\n");
+ verify_error=SSL_get_verify_result(con);
+ if (verify_error != X509_V_OK)
+ {
+ BIO_printf(bio_err,"verify error:%s\n",
+ X509_verify_cert_error_string(verify_error));
+ }
+ else
+ ERR_print_errors(bio_err);
+ return(0);
+ }
+
+ PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con));
+
+ peer=SSL_get_peer_certificate(con);
+ if (peer != NULL)
+ {
+ BIO_printf(bio_s_out,"Client certificate\n");
+ PEM_write_bio_X509(bio_s_out,peer);
+ X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf);
+ BIO_printf(bio_s_out,"subject=%s\n",buf);
+ X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf);
+ BIO_printf(bio_s_out,"issuer=%s\n",buf);
+ X509_free(peer);
+ }
+
+ if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL)
+ BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
+ str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
+ BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
+ if (next_proto_neg)
+ {
+ BIO_printf(bio_s_out,"NEXTPROTO is ");
+ BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len);
+ BIO_printf(bio_s_out, "\n");
+ }
+#endif
+#ifndef OPENSSL_NO_SRTP
+ {
+ SRTP_PROTECTION_PROFILE *srtp_profile
+ = SSL_get_selected_srtp_profile(con);
+
+ if(srtp_profile)
+ BIO_printf(bio_s_out,"SRTP Extension negotiated, profile=%s\n",
+ srtp_profile->name);
+ }
+#endif
+ if (SSL_cache_hit(con)) BIO_printf(bio_s_out,"Reused session-id\n");
+ if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
+ TLS1_FLAGS_TLS_PADDING_BUG)
+ BIO_printf(bio_s_out,
+ "Peer has incorrect TLSv1 block padding\n");
+#ifndef OPENSSL_NO_KRB5
+ client_princ = kssl_ctx_get0_client_princ(SSL_get0_kssl_ctx(con));
+ if (client_princ != NULL)
+ {
+ BIO_printf(bio_s_out,"Kerberos peer principal is %s\n",
+ client_princ);
+ }
+#endif /* OPENSSL_NO_KRB5 */
+ BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
+ SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
+ if (keymatexportlabel != NULL)
+ {
+ BIO_printf(bio_s_out, "Keying material exporter:\n");
+ BIO_printf(bio_s_out, " Label: '%s'\n", keymatexportlabel);
+ BIO_printf(bio_s_out, " Length: %i bytes\n",
+ keymatexportlen);
+ exportedkeymat = OPENSSL_malloc(keymatexportlen);
+ if (exportedkeymat != NULL)
+ {
+ if (!SSL_export_keying_material(con, exportedkeymat,
+ keymatexportlen,
+ keymatexportlabel,
+ strlen(keymatexportlabel),
+ NULL, 0, 0))
+ {
+ BIO_printf(bio_s_out, " Error\n");
+ }
+ else
+ {
+ BIO_printf(bio_s_out, " Keying material: ");
+ for (i=0; i<keymatexportlen; i++)
+ BIO_printf(bio_s_out, "%02X",
+ exportedkeymat[i]);
+ BIO_printf(bio_s_out, "\n");
+ }
+ OPENSSL_free(exportedkeymat);
+ }
+ }
+
+ return(1);
+ }
+
+#ifndef OPENSSL_NO_DH
+static DH *load_dh_param(const char *dhfile)
+ {
+ DH *ret=NULL;
+ BIO *bio;
+
+ if ((bio=BIO_new_file(dhfile,"r")) == NULL)
+ goto err;
+ ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
+err:
+ if (bio != NULL) BIO_free(bio);
+ return(ret);
+ }
+#endif
+#ifndef OPENSSL_NO_KRB5
+ char *client_princ;
+#endif
+
+#if 0
+static int load_CA(SSL_CTX *ctx, char *file)
+ {
+ FILE *in;
+ X509 *x=NULL;
+
+ if ((in=fopen(file,"r")) == NULL)
+ return(0);
+
+ for (;;)
+ {
+ if (PEM_read_X509(in,&x,NULL) == NULL)
+ break;
+ SSL_CTX_add_client_CA(ctx,x);
+ }
+ if (x != NULL) X509_free(x);
+ fclose(in);
+ return(1);
+ }
+#endif
+
+static int www_body(char *hostname, int s, unsigned char *context)
+ {
+ char *buf=NULL;
+ int ret=1;
+ int i,j,k,dot;
+ SSL *con;
+ const SSL_CIPHER *c;
+ BIO *io,*ssl_bio,*sbio;
+#ifndef OPENSSL_NO_KRB5
+ KSSL_CTX *kctx;
+#endif
+
+ buf=OPENSSL_malloc(bufsize);
+ if (buf == NULL) return(0);
+ io=BIO_new(BIO_f_buffer());
+ ssl_bio=BIO_new(BIO_f_ssl());
+ if ((io == NULL) || (ssl_bio == NULL)) goto err;
+
+#ifdef FIONBIO
+ if (s_nbio)
+ {
+ unsigned long sl=1;
+
+ if (!s_quiet)
+ BIO_printf(bio_err,"turning on non blocking io\n");
+ if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
+ ERR_print_errors(bio_err);
+ }
+#endif
+
+ /* lets make the output buffer a reasonable size */
+ if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
+
+ if ((con=SSL_new(ctx)) == NULL) goto err;
+#ifndef OPENSSL_NO_TLSEXT
+ if (s_tlsextdebug)
+ {
+ SSL_set_tlsext_debug_callback(con, tlsext_cb);
+ SSL_set_tlsext_debug_arg(con, bio_s_out);
+ }
+#endif
+#ifndef OPENSSL_NO_KRB5
+ if ((kctx = kssl_ctx_new()) != NULL)
+ {
+ kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
+ kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
+ }
+#endif /* OPENSSL_NO_KRB5 */
+ if(context) SSL_set_session_id_context(con, context,
+ strlen((char *)context));
+
+ sbio=BIO_new_socket(s,BIO_NOCLOSE);
+ if (s_nbio_test)
+ {
+ BIO *test;
+
+ test=BIO_new(BIO_f_nbio_test());
+ sbio=BIO_push(test,sbio);
+ }
+ SSL_set_bio(con,sbio,sbio);
+ SSL_set_accept_state(con);
+
+ /* SSL_set_fd(con,s); */
+ BIO_set_ssl(ssl_bio,con,BIO_CLOSE);
+ BIO_push(io,ssl_bio);
+#ifdef CHARSET_EBCDIC
+ io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io);
+#endif
+
+ if (s_debug)
+ {
+ SSL_set_debug(con, 1);
+ BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
+ BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out);
+ }
+ if (s_msg)
+ {
+ SSL_set_msg_callback(con, msg_cb);
+ SSL_set_msg_callback_arg(con, bio_s_out);
+ }
+
+ for (;;)
+ {
+ if (hack)
+ {
+ i=SSL_accept(con);
+#ifndef OPENSSL_NO_SRP
+ while (i <= 0 && SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
+ {
+ BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
+ srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out,"LOOKUP not successful\n");
+ i=SSL_accept(con);
+ }
+#endif
+ switch (SSL_get_error(con,i))
+ {
+ case SSL_ERROR_NONE:
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ continue;
+ case SSL_ERROR_SYSCALL:
+ case SSL_ERROR_SSL:
+ case SSL_ERROR_ZERO_RETURN:
+ ret=1;
+ goto err;
+ /* break; */
+ }
+
+ SSL_renegotiate(con);
+ SSL_write(con,NULL,0);
+ }
+
+ i=BIO_gets(io,buf,bufsize-1);
+ if (i < 0) /* error */
+ {
+ if (!BIO_should_retry(io))
+ {
+ if (!s_quiet)
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ else
+ {
+ BIO_printf(bio_s_out,"read R BLOCK\n");
+#if defined(OPENSSL_SYS_NETWARE)
+ delay(1000);
+#elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
+ sleep(1);
+#endif
+ continue;
+ }
+ }
+ else if (i == 0) /* end of input */
+ {
+ ret=1;
+ goto end;
+ }
+
+ /* else we have data */
+ if ( ((www == 1) && (strncmp("GET ",buf,4) == 0)) ||
+ ((www == 2) && (strncmp("GET /stats ",buf,10) == 0)))
+ {
+ char *p;
+ X509 *peer;
+ STACK_OF(SSL_CIPHER) *sk;
+ static const char *space=" ";
+
+ BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
+ BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n");
+ BIO_puts(io,"<pre>\n");
+/* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
+ BIO_puts(io,"\n");
+ for (i=0; i<local_argc; i++)
+ {
+ BIO_puts(io,local_argv[i]);
+ BIO_write(io," ",1);
+ }
+ BIO_puts(io,"\n");
+
+ BIO_printf(io,
+ "Secure Renegotiation IS%s supported\n",
+ SSL_get_secure_renegotiation_support(con) ?
+ "" : " NOT");
+
+ /* The following is evil and should not really
+ * be done */
+ BIO_printf(io,"Ciphers supported in s_server binary\n");
+ sk=SSL_get_ciphers(con);
+ j=sk_SSL_CIPHER_num(sk);
+ for (i=0; i<j; i++)
+ {
+ c=sk_SSL_CIPHER_value(sk,i);
+ BIO_printf(io,"%-11s:%-25s",
+ SSL_CIPHER_get_version(c),
+ SSL_CIPHER_get_name(c));
+ if ((((i+1)%2) == 0) && (i+1 != j))
+ BIO_puts(io,"\n");
+ }
+ BIO_puts(io,"\n");
+ p=SSL_get_shared_ciphers(con,buf,bufsize);
+ if (p != NULL)
+ {
+ BIO_printf(io,"---\nCiphers common between both SSL end points:\n");
+ j=i=0;
+ while (*p)
+ {
+ if (*p == ':')
+ {
+ BIO_write(io,space,26-j);
+ i++;
+ j=0;
+ BIO_write(io,((i%3)?" ":"\n"),1);
+ }
+ else
+ {
+ BIO_write(io,p,1);
+ j++;
+ }
+ p++;
+ }
+ BIO_puts(io,"\n");
+ }
+ BIO_printf(io,(SSL_cache_hit(con)
+ ?"---\nReused, "
+ :"---\nNew, "));
+ c=SSL_get_current_cipher(con);
+ BIO_printf(io,"%s, Cipher is %s\n",
+ SSL_CIPHER_get_version(c),
+ SSL_CIPHER_get_name(c));
+ SSL_SESSION_print(io,SSL_get_session(con));
+ BIO_printf(io,"---\n");
+ print_stats(io,SSL_get_SSL_CTX(con));
+ BIO_printf(io,"---\n");
+ peer=SSL_get_peer_certificate(con);
+ if (peer != NULL)
+ {
+ BIO_printf(io,"Client certificate\n");
+ X509_print(io,peer);
+ PEM_write_bio_X509(io,peer);
+ }
+ else
+ BIO_puts(io,"no client certificate available\n");
+ BIO_puts(io,"</BODY></HTML>\r\n\r\n");
+ break;
+ }
+ else if ((www == 2 || www == 3)
+ && (strncmp("GET /",buf,5) == 0))
+ {
+ BIO *file;
+ char *p,*e;
+ static const char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
+
+ /* skip the '/' */
+ p= &(buf[5]);
+
+ dot = 1;
+ for (e=p; *e != '\0'; e++)
+ {
+ if (e[0] == ' ')
+ break;
+
+ switch (dot)
+ {
+ case 1:
+ dot = (e[0] == '.') ? 2 : 0;
+ break;
+ case 2:
+ dot = (e[0] == '.') ? 3 : 0;
+ break;
+ case 3:
+ dot = (e[0] == '/') ? -1 : 0;
+ break;
+ }
+ if (dot == 0)
+ dot = (e[0] == '/') ? 1 : 0;
+ }
+ dot = (dot == 3) || (dot == -1); /* filename contains ".." component */
+
+ if (*e == '\0')
+ {
+ BIO_puts(io,text);
+ BIO_printf(io,"'%s' is an invalid file name\r\n",p);
+ break;
+ }
+ *e='\0';
+
+ if (dot)
+ {
+ BIO_puts(io,text);
+ BIO_printf(io,"'%s' contains '..' reference\r\n",p);
+ break;
+ }
+
+ if (*p == '/')
+ {
+ BIO_puts(io,text);
+ BIO_printf(io,"'%s' is an invalid path\r\n",p);
+ break;
+ }
+
+#if 0
+ /* append if a directory lookup */
+ if (e[-1] == '/')
+ strcat(p,"index.html");
+#endif
+
+ /* if a directory, do the index thang */
+ if (app_isdir(p)>0)
+ {
+#if 0 /* must check buffer size */
+ strcat(p,"/index.html");
+#else
+ BIO_puts(io,text);
+ BIO_printf(io,"'%s' is a directory\r\n",p);
+ break;
+#endif
+ }
+
+ if ((file=BIO_new_file(p,"r")) == NULL)
+ {
+ BIO_puts(io,text);
+ BIO_printf(io,"Error opening '%s'\r\n",p);
+ ERR_print_errors(io);
+ break;
+ }
+
+ if (!s_quiet)
+ BIO_printf(bio_err,"FILE:%s\n",p);
+
+ if (www == 2)
+ {
+ i=strlen(p);
+ if ( ((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) ||
+ ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) ||
+ ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0)))
+ BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
+ else
+ BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
+ }
+ /* send the file */
+ for (;;)
+ {
+ i=BIO_read(file,buf,bufsize);
+ if (i <= 0) break;
+
+#ifdef RENEG
+ total_bytes+=i;
+ fprintf(stderr,"%d\n",i);
+ if (total_bytes > 3*1024)
+ {
+ total_bytes=0;
+ fprintf(stderr,"RENEGOTIATE\n");
+ SSL_renegotiate(con);
+ }
+#endif
+
+ for (j=0; j<i; )
+ {
+#ifdef RENEG
+{ static count=0; if (++count == 13) { SSL_renegotiate(con); } }
+#endif
+ k=BIO_write(io,&(buf[j]),i-j);
+ if (k <= 0)
+ {
+ if (!BIO_should_retry(io))
+ goto write_error;
+ else
+ {
+ BIO_printf(bio_s_out,"rwrite W BLOCK\n");
+ }
+ }
+ else
+ {
+ j+=k;
+ }
+ }
+ }
+write_error:
+ BIO_free(file);
+ break;
+ }
+ }
+
+ for (;;)
+ {
+ i=(int)BIO_flush(io);
+ if (i <= 0)
+ {
+ if (!BIO_should_retry(io))
+ break;
+ }
+ else
+ break;
+ }
+end:
+#if 1
+ /* make sure we re-use sessions */
+ SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+#else
+ /* This kills performance */
+/* SSL_shutdown(con); A shutdown gets sent in the
+ * BIO_free_all(io) procession */
+#endif
+
+err:
+
+ if (ret >= 0)
+ BIO_printf(bio_s_out,"ACCEPT\n");
+
+ if (buf != NULL) OPENSSL_free(buf);
+ if (io != NULL) BIO_free_all(io);
+/* if (ssl_bio != NULL) BIO_free(ssl_bio);*/
+ return(ret);
+ }
+
+#ifndef OPENSSL_NO_RSA
+static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
+ {
+ BIGNUM *bn = NULL;
+ static RSA *rsa_tmp=NULL;
+
+ if (!rsa_tmp && ((bn = BN_new()) == NULL))
+ BIO_printf(bio_err,"Allocation error in generating RSA key\n");
+ if (!rsa_tmp && bn)
+ {
+ if (!s_quiet)
+ {
+ BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
+ (void)BIO_flush(bio_err);
+ }
+ if(!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
+ !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
+ {
+ if(rsa_tmp) RSA_free(rsa_tmp);
+ rsa_tmp = NULL;
+ }
+ if (!s_quiet)
+ {
+ BIO_printf(bio_err,"\n");
+ (void)BIO_flush(bio_err);
+ }
+ BN_free(bn);
+ }
+ return(rsa_tmp);
+ }
+#endif
+
+#define MAX_SESSION_ID_ATTEMPTS 10
+static int generate_session_id(const SSL *ssl, unsigned char *id,
+ unsigned int *id_len)
+ {
+ unsigned int count = 0;
+ do {
+ RAND_pseudo_bytes(id, *id_len);
+ /* Prefix the session_id with the required prefix. NB: If our
+ * prefix is too long, clip it - but there will be worse effects
+ * anyway, eg. the server could only possibly create 1 session
+ * ID (ie. the prefix!) so all future session negotiations will
+ * fail due to conflicts. */
+ memcpy(id, session_id_prefix,
+ (strlen(session_id_prefix) < *id_len) ?
+ strlen(session_id_prefix) : *id_len);
+ }
+ while(SSL_has_matching_session_id(ssl, id, *id_len) &&
+ (++count < MAX_SESSION_ID_ATTEMPTS));
+ if(count >= MAX_SESSION_ID_ATTEMPTS)
+ return 0;
+ return 1;
+ }
diff --git a/deps/openssl/openssl/apps/s_socket.c b/deps/openssl/openssl/apps/s_socket.c
new file mode 100644
index 000000000..380efdb1b
--- /dev/null
+++ b/deps/openssl/openssl/apps/s_socket.c
@@ -0,0 +1,619 @@
+/* apps/s_socket.c - socket-related functions used by s_client and s_server */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+
+#ifdef FLAT_INC
+#include "e_os2.h"
+#else
+#include "../e_os2.h"
+#endif
+
+/* With IPv6, it looks like Digital has mixed up the proper order of
+ recursive header file inclusion, resulting in the compiler complaining
+ that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
+ is needed to have fileno() declared correctly... So let's define u_int */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
+#define __U_INT
+typedef unsigned int u_int;
+#endif
+
+#define USE_SOCKETS
+#define NON_MAIN
+#include "apps.h"
+#undef USE_SOCKETS
+#undef NON_MAIN
+#include "s_apps.h"
+#include <openssl/ssl.h>
+
+#ifdef FLAT_INC
+#include "e_os.h"
+#else
+#include "../e_os.h"
+#endif
+
+#ifndef OPENSSL_NO_SOCK
+
+#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
+#include "netdb.h"
+#endif
+
+static struct hostent *GetHostByName(char *name);
+#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
+static void ssl_sock_cleanup(void);
+#endif
+static int ssl_sock_init(void);
+static int init_client_ip(int *sock,unsigned char ip[4], int port, int type);
+static int init_server(int *sock, int port, int type);
+static int init_server_long(int *sock, int port,char *ip, int type);
+static int do_accept(int acc_sock, int *sock, char **host);
+static int host_ip(char *str, unsigned char ip[4]);
+
+#ifdef OPENSSL_SYS_WIN16
+#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
+#else
+#define SOCKET_PROTOCOL IPPROTO_TCP
+#endif
+
+#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
+static int wsa_init_done=0;
+#endif
+
+#ifdef OPENSSL_SYS_WINDOWS
+static struct WSAData wsa_state;
+static int wsa_init_done=0;
+
+#ifdef OPENSSL_SYS_WIN16
+static HWND topWnd=0;
+static FARPROC lpTopWndProc=NULL;
+static FARPROC lpTopHookProc=NULL;
+extern HINSTANCE _hInstance; /* nice global CRT provides */
+
+static LONG FAR PASCAL topHookProc(HWND hwnd, UINT message, WPARAM wParam,
+ LPARAM lParam)
+ {
+ if (hwnd == topWnd)
+ {
+ switch(message)
+ {
+ case WM_DESTROY:
+ case WM_CLOSE:
+ SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopWndProc);
+ ssl_sock_cleanup();
+ break;
+ }
+ }
+ return CallWindowProc(lpTopWndProc,hwnd,message,wParam,lParam);
+ }
+
+static BOOL CALLBACK enumproc(HWND hwnd,LPARAM lParam)
+ {
+ topWnd=hwnd;
+ return(FALSE);
+ }
+
+#endif /* OPENSSL_SYS_WIN32 */
+#endif /* OPENSSL_SYS_WINDOWS */
+
+#ifdef OPENSSL_SYS_WINDOWS
+static void ssl_sock_cleanup(void)
+ {
+ if (wsa_init_done)
+ {
+ wsa_init_done=0;
+#ifndef OPENSSL_SYS_WINCE
+ WSACancelBlockingCall();
+#endif
+ WSACleanup();
+ }
+ }
+#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
+static void sock_cleanup(void)
+ {
+ if (wsa_init_done)
+ {
+ wsa_init_done=0;
+ WSACleanup();
+ }
+ }
+#endif
+
+static int ssl_sock_init(void)
+ {
+#ifdef WATT32
+ extern int _watt_do_exit;
+ _watt_do_exit = 0;
+ if (sock_init())
+ return (0);
+#elif defined(OPENSSL_SYS_WINDOWS)
+ if (!wsa_init_done)
+ {
+ int err;
+
+#ifdef SIGINT
+ signal(SIGINT,(void (*)(int))ssl_sock_cleanup);
+#endif
+ wsa_init_done=1;
+ memset(&wsa_state,0,sizeof(wsa_state));
+ if (WSAStartup(0x0101,&wsa_state)!=0)
+ {
+ err=WSAGetLastError();
+ BIO_printf(bio_err,"unable to start WINSOCK, error code=%d\n",err);
+ return(0);
+ }
+
+#ifdef OPENSSL_SYS_WIN16
+ EnumTaskWindows(GetCurrentTask(),enumproc,0L);
+ lpTopWndProc=(FARPROC)GetWindowLong(topWnd,GWL_WNDPROC);
+ lpTopHookProc=MakeProcInstance((FARPROC)topHookProc,_hInstance);
+
+ SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopHookProc);
+#endif /* OPENSSL_SYS_WIN16 */
+ }
+#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
+ WORD wVerReq;
+ WSADATA wsaData;
+ int err;
+
+ if (!wsa_init_done)
+ {
+
+# ifdef SIGINT
+ signal(SIGINT,(void (*)(int))sock_cleanup);
+# endif
+
+ wsa_init_done=1;
+ wVerReq = MAKEWORD( 2, 0 );
+ err = WSAStartup(wVerReq,&wsaData);
+ if (err != 0)
+ {
+ BIO_printf(bio_err,"unable to start WINSOCK2, error code=%d\n",err);
+ return(0);
+ }
+ }
+#endif /* OPENSSL_SYS_WINDOWS */
+ return(1);
+ }
+
+int init_client(int *sock, char *host, int port, int type)
+ {
+ unsigned char ip[4];
+
+ memset(ip, '\0', sizeof ip);
+ if (!host_ip(host,&(ip[0])))
+ return 0;
+ return init_client_ip(sock,ip,port,type);
+ }
+
+static int init_client_ip(int *sock, unsigned char ip[4], int port, int type)
+ {
+ unsigned long addr;
+ struct sockaddr_in them;
+ int s,i;
+
+ if (!ssl_sock_init()) return(0);
+
+ memset((char *)&them,0,sizeof(them));
+ them.sin_family=AF_INET;
+ them.sin_port=htons((unsigned short)port);
+ addr=(unsigned long)
+ ((unsigned long)ip[0]<<24L)|
+ ((unsigned long)ip[1]<<16L)|
+ ((unsigned long)ip[2]<< 8L)|
+ ((unsigned long)ip[3]);
+ them.sin_addr.s_addr=htonl(addr);
+
+ if (type == SOCK_STREAM)
+ s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
+ else /* ( type == SOCK_DGRAM) */
+ s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
+
+ if (s == INVALID_SOCKET) { perror("socket"); return(0); }
+
+#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
+ if (type == SOCK_STREAM)
+ {
+ i=0;
+ i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
+ if (i < 0) { perror("keepalive"); return(0); }
+ }
+#endif
+
+ if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1)
+ { closesocket(s); perror("connect"); return(0); }
+ *sock=s;
+ return(1);
+ }
+
+int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context)
+ {
+ int sock;
+ char *name = NULL;
+ int accept_socket = 0;
+ int i;
+
+ if (!init_server(&accept_socket,port,type)) return(0);
+
+ if (ret != NULL)
+ {
+ *ret=accept_socket;
+ /* return(1);*/
+ }
+ for (;;)
+ {
+ if (type==SOCK_STREAM)
+ {
+ if (do_accept(accept_socket,&sock,&name) == 0)
+ {
+ SHUTDOWN(accept_socket);
+ return(0);
+ }
+ }
+ else
+ sock = accept_socket;
+ i=(*cb)(name,sock, context);
+ if (name != NULL) OPENSSL_free(name);
+ if (type==SOCK_STREAM)
+ SHUTDOWN2(sock);
+ if (i < 0)
+ {
+ SHUTDOWN2(accept_socket);
+ return(i);
+ }
+ }
+ }
+
+static int init_server_long(int *sock, int port, char *ip, int type)
+ {
+ int ret=0;
+ struct sockaddr_in server;
+ int s= -1;
+
+ if (!ssl_sock_init()) return(0);
+
+ memset((char *)&server,0,sizeof(server));
+ server.sin_family=AF_INET;
+ server.sin_port=htons((unsigned short)port);
+ if (ip == NULL)
+ server.sin_addr.s_addr=INADDR_ANY;
+ else
+/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */
+#ifndef BIT_FIELD_LIMITS
+ memcpy(&server.sin_addr.s_addr,ip,4);
+#else
+ memcpy(&server.sin_addr,ip,4);
+#endif
+
+ if (type == SOCK_STREAM)
+ s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
+ else /* type == SOCK_DGRAM */
+ s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
+
+ if (s == INVALID_SOCKET) goto err;
+#if defined SOL_SOCKET && defined SO_REUSEADDR
+ {
+ int j = 1;
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+ (void *) &j, sizeof j);
+ }
+#endif
+ if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
+ {
+#ifndef OPENSSL_SYS_WINDOWS
+ perror("bind");
+#endif
+ goto err;
+ }
+ /* Make it 128 for linux */
+ if (type==SOCK_STREAM && listen(s,128) == -1) goto err;
+ *sock=s;
+ ret=1;
+err:
+ if ((ret == 0) && (s != -1))
+ {
+ SHUTDOWN(s);
+ }
+ return(ret);
+ }
+
+static int init_server(int *sock, int port, int type)
+ {
+ return(init_server_long(sock, port, NULL, type));
+ }
+
+static int do_accept(int acc_sock, int *sock, char **host)
+ {
+ int ret;
+ struct hostent *h1,*h2;
+ static struct sockaddr_in from;
+ int len;
+/* struct linger ling; */
+
+ if (!ssl_sock_init()) return(0);
+
+#ifndef OPENSSL_SYS_WINDOWS
+redoit:
+#endif
+
+ memset((char *)&from,0,sizeof(from));
+ len=sizeof(from);
+ /* Note: under VMS with SOCKETSHR the fourth parameter is currently
+ * of type (int *) whereas under other systems it is (void *) if
+ * you don't have a cast it will choke the compiler: if you do
+ * have a cast then you can either go for (int *) or (void *).
+ */
+ ret=accept(acc_sock,(struct sockaddr *)&from,(void *)&len);
+ if (ret == INVALID_SOCKET)
+ {
+#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
+ int i;
+ i=WSAGetLastError();
+ BIO_printf(bio_err,"accept error %d\n",i);
+#else
+ if (errno == EINTR)
+ {
+ /*check_timeout(); */
+ goto redoit;
+ }
+ fprintf(stderr,"errno=%d ",errno);
+ perror("accept");
+#endif
+ return(0);
+ }
+
+/*
+ ling.l_onoff=1;
+ ling.l_linger=0;
+ i=setsockopt(ret,SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling));
+ if (i < 0) { perror("linger"); return(0); }
+ i=0;
+ i=setsockopt(ret,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
+ if (i < 0) { perror("keepalive"); return(0); }
+*/
+
+ if (host == NULL) goto end;
+#ifndef BIT_FIELD_LIMITS
+ /* I should use WSAAsyncGetHostByName() under windows */
+ h1=gethostbyaddr((char *)&from.sin_addr.s_addr,
+ sizeof(from.sin_addr.s_addr),AF_INET);
+#else
+ h1=gethostbyaddr((char *)&from.sin_addr,
+ sizeof(struct in_addr),AF_INET);
+#endif
+ if (h1 == NULL)
+ {
+ BIO_printf(bio_err,"bad gethostbyaddr\n");
+ *host=NULL;
+ /* return(0); */
+ }
+ else
+ {
+ if ((*host=(char *)OPENSSL_malloc(strlen(h1->h_name)+1)) == NULL)
+ {
+ perror("OPENSSL_malloc");
+ return(0);
+ }
+ BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1);
+
+ h2=GetHostByName(*host);
+ if (h2 == NULL)
+ {
+ BIO_printf(bio_err,"gethostbyname failure\n");
+ return(0);
+ }
+ if (h2->h_addrtype != AF_INET)
+ {
+ BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
+ return(0);
+ }
+ }
+end:
+ *sock=ret;
+ return(1);
+ }
+
+int extract_host_port(char *str, char **host_ptr, unsigned char *ip,
+ short *port_ptr)
+ {
+ char *h,*p;
+
+ h=str;
+ p=strchr(str,':');
+ if (p == NULL)
+ {
+ BIO_printf(bio_err,"no port defined\n");
+ return(0);
+ }
+ *(p++)='\0';
+
+ if ((ip != NULL) && !host_ip(str,ip))
+ goto err;
+ if (host_ptr != NULL) *host_ptr=h;
+
+ if (!extract_port(p,port_ptr))
+ goto err;
+ return(1);
+err:
+ return(0);
+ }
+
+static int host_ip(char *str, unsigned char ip[4])
+ {
+ unsigned int in[4];
+ int i;
+
+ if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4)
+ {
+ for (i=0; i<4; i++)
+ if (in[i] > 255)
+ {
+ BIO_printf(bio_err,"invalid IP address\n");
+ goto err;
+ }
+ ip[0]=in[0];
+ ip[1]=in[1];
+ ip[2]=in[2];
+ ip[3]=in[3];
+ }
+ else
+ { /* do a gethostbyname */
+ struct hostent *he;
+
+ if (!ssl_sock_init()) return(0);
+
+ he=GetHostByName(str);
+ if (he == NULL)
+ {
+ BIO_printf(bio_err,"gethostbyname failure\n");
+ goto err;
+ }
+ /* cast to short because of win16 winsock definition */
+ if ((short)he->h_addrtype != AF_INET)
+ {
+ BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
+ return(0);
+ }
+ ip[0]=he->h_addr_list[0][0];
+ ip[1]=he->h_addr_list[0][1];
+ ip[2]=he->h_addr_list[0][2];
+ ip[3]=he->h_addr_list[0][3];
+ }
+ return(1);
+err:
+ return(0);
+ }
+
+int extract_port(char *str, short *port_ptr)
+ {
+ int i;
+ struct servent *s;
+
+ i=atoi(str);
+ if (i != 0)
+ *port_ptr=(unsigned short)i;
+ else
+ {
+ s=getservbyname(str,"tcp");
+ if (s == NULL)
+ {
+ BIO_printf(bio_err,"getservbyname failure for %s\n",str);
+ return(0);
+ }
+ *port_ptr=ntohs((unsigned short)s->s_port);
+ }
+ return(1);
+ }
+
+#define GHBN_NUM 4
+static struct ghbn_cache_st
+ {
+ char name[128];
+ struct hostent ent;
+ unsigned long order;
+ } ghbn_cache[GHBN_NUM];
+
+static unsigned long ghbn_hits=0L;
+static unsigned long ghbn_miss=0L;
+
+static struct hostent *GetHostByName(char *name)
+ {
+ struct hostent *ret;
+ int i,lowi=0;
+ unsigned long low= (unsigned long)-1;
+
+ for (i=0; i<GHBN_NUM; i++)
+ {
+ if (low > ghbn_cache[i].order)
+ {
+ low=ghbn_cache[i].order;
+ lowi=i;
+ }
+ if (ghbn_cache[i].order > 0)
+ {
+ if (strncmp(name,ghbn_cache[i].name,128) == 0)
+ break;
+ }
+ }
+ if (i == GHBN_NUM) /* no hit*/
+ {
+ ghbn_miss++;
+ ret=gethostbyname(name);
+ if (ret == NULL) return(NULL);
+ /* else add to cache */
+ if(strlen(name) < sizeof ghbn_cache[0].name)
+ {
+ strcpy(ghbn_cache[lowi].name,name);
+ memcpy((char *)&(ghbn_cache[lowi].ent),ret,sizeof(struct hostent));
+ ghbn_cache[lowi].order=ghbn_miss+ghbn_hits;
+ }
+ return(ret);
+ }
+ else
+ {
+ ghbn_hits++;
+ ret= &(ghbn_cache[i].ent);
+ ghbn_cache[i].order=ghbn_miss+ghbn_hits;
+ return(ret);
+ }
+ }
+
+#endif
diff --git a/deps/openssl/openssl/apps/s_time.c b/deps/openssl/openssl/apps/s_time.c
new file mode 100644
index 000000000..b823c33c5
--- /dev/null
+++ b/deps/openssl/openssl/apps/s_time.c
@@ -0,0 +1,632 @@
+/* apps/s_time.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define NO_SHUTDOWN
+
+/*-----------------------------------------
+ s_time - SSL client connection timer program
+ Written and donated by Larry Streepy <streepy@healthcare.com>
+ -----------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define USE_SOCKETS
+#include "apps.h"
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/pem.h>
+#include "s_apps.h"
+#include <openssl/err.h>
+#ifdef WIN32_STUFF
+#include "winmain.h"
+#include "wintext.h"
+#endif
+#if !defined(OPENSSL_SYS_MSDOS)
+#include OPENSSL_UNISTD
+#endif
+
+#undef PROG
+#define PROG s_time_main
+
+#undef ioctl
+#define ioctl ioctlsocket
+
+#define SSL_CONNECT_NAME "localhost:4433"
+
+/*#define TEST_CERT "client.pem" */ /* no default cert. */
+
+#undef BUFSIZZ
+#define BUFSIZZ 1024*10
+
+#define MYBUFSIZ 1024*8
+
+#undef min
+#undef max
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+#undef SECONDS
+#define SECONDS 30
+extern int verify_depth;
+extern int verify_error;
+
+static void s_time_usage(void);
+static int parseArgs( int argc, char **argv );
+static SSL *doConnection( SSL *scon );
+static void s_time_init(void);
+
+/***********************************************************************
+ * Static data declarations
+ */
+
+/* static char *port=PORT_STR;*/
+static char *host=SSL_CONNECT_NAME;
+static char *t_cert_file=NULL;
+static char *t_key_file=NULL;
+static char *CApath=NULL;
+static char *CAfile=NULL;
+static char *tm_cipher=NULL;
+static int tm_verify = SSL_VERIFY_NONE;
+static int maxTime = SECONDS;
+static SSL_CTX *tm_ctx=NULL;
+static const SSL_METHOD *s_time_meth=NULL;
+static char *s_www_path=NULL;
+static long bytes_read=0;
+static int st_bugs=0;
+static int perform=0;
+#ifdef FIONBIO
+static int t_nbio=0;
+#endif
+#ifdef OPENSSL_SYS_WIN32
+static int exitNow = 0; /* Set when it's time to exit main */
+#endif
+
+static void s_time_init(void)
+ {
+ host=SSL_CONNECT_NAME;
+ t_cert_file=NULL;
+ t_key_file=NULL;
+ CApath=NULL;
+ CAfile=NULL;
+ tm_cipher=NULL;
+ tm_verify = SSL_VERIFY_NONE;
+ maxTime = SECONDS;
+ tm_ctx=NULL;
+ s_time_meth=NULL;
+ s_www_path=NULL;
+ bytes_read=0;
+ st_bugs=0;
+ perform=0;
+
+#ifdef FIONBIO
+ t_nbio=0;
+#endif
+#ifdef OPENSSL_SYS_WIN32
+ exitNow = 0; /* Set when it's time to exit main */
+#endif
+ }
+
+/***********************************************************************
+ * usage - display usage message
+ */
+static void s_time_usage(void)
+{
+ static char umsg[] = "\
+-time arg - max number of seconds to collect data, default %d\n\
+-verify arg - turn on peer certificate verification, arg == depth\n\
+-cert arg - certificate file to use, PEM format assumed\n\
+-key arg - RSA file to use, PEM format assumed, key is in cert file\n\
+ file if not specified by this option\n\
+-CApath arg - PEM format directory of CA's\n\
+-CAfile arg - PEM format file of CA's\n\
+-cipher - preferred cipher to use, play with 'openssl ciphers'\n\n";
+
+ printf( "usage: s_time <args>\n\n" );
+
+ printf("-connect host:port - host:port to connect to (default is %s)\n",SSL_CONNECT_NAME);
+#ifdef FIONBIO
+ printf("-nbio - Run with non-blocking IO\n");
+ printf("-ssl2 - Just use SSLv2\n");
+ printf("-ssl3 - Just use SSLv3\n");
+ printf("-bugs - Turn on SSL bug compatibility\n");
+ printf("-new - Just time new connections\n");
+ printf("-reuse - Just time connection reuse\n");
+ printf("-www page - Retrieve 'page' from the site\n");
+#endif
+ printf( umsg,SECONDS );
+}
+
+/***********************************************************************
+ * parseArgs - Parse command line arguments and initialize data
+ *
+ * Returns 0 if ok, -1 on bad args
+ */
+static int parseArgs(int argc, char **argv)
+{
+ int badop = 0;
+
+ verify_depth=0;
+ verify_error=X509_V_OK;
+
+ argc--;
+ argv++;
+
+ while (argc >= 1) {
+ if (strcmp(*argv,"-connect") == 0)
+ {
+ if (--argc < 1) goto bad;
+ host= *(++argv);
+ }
+#if 0
+ else if( strcmp(*argv,"-host") == 0)
+ {
+ if (--argc < 1) goto bad;
+ host= *(++argv);
+ }
+ else if( strcmp(*argv,"-port") == 0)
+ {
+ if (--argc < 1) goto bad;
+ port= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-reuse") == 0)
+ perform=2;
+ else if (strcmp(*argv,"-new") == 0)
+ perform=1;
+ else if( strcmp(*argv,"-verify") == 0) {
+
+ tm_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
+ if (--argc < 1) goto bad;
+ verify_depth=atoi(*(++argv));
+ BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
+
+ } else if( strcmp(*argv,"-cert") == 0) {
+
+ if (--argc < 1) goto bad;
+ t_cert_file= *(++argv);
+
+ } else if( strcmp(*argv,"-key") == 0) {
+
+ if (--argc < 1) goto bad;
+ t_key_file= *(++argv);
+
+ } else if( strcmp(*argv,"-CApath") == 0) {
+
+ if (--argc < 1) goto bad;
+ CApath= *(++argv);
+
+ } else if( strcmp(*argv,"-CAfile") == 0) {
+
+ if (--argc < 1) goto bad;
+ CAfile= *(++argv);
+
+ } else if( strcmp(*argv,"-cipher") == 0) {
+
+ if (--argc < 1) goto bad;
+ tm_cipher= *(++argv);
+ }
+#ifdef FIONBIO
+ else if(strcmp(*argv,"-nbio") == 0) {
+ t_nbio=1;
+ }
+#endif
+ else if(strcmp(*argv,"-www") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_www_path= *(++argv);
+ if(strlen(s_www_path) > MYBUFSIZ-100)
+ {
+ BIO_printf(bio_err,"-www option too long\n");
+ badop=1;
+ }
+ }
+ else if(strcmp(*argv,"-bugs") == 0)
+ st_bugs=1;
+#ifndef OPENSSL_NO_SSL2
+ else if(strcmp(*argv,"-ssl2") == 0)
+ s_time_meth=SSLv2_client_method();
+#endif
+#ifndef OPENSSL_NO_SSL3
+ else if(strcmp(*argv,"-ssl3") == 0)
+ s_time_meth=SSLv3_client_method();
+#endif
+ else if( strcmp(*argv,"-time") == 0) {
+
+ if (--argc < 1) goto bad;
+ maxTime= atoi(*(++argv));
+ }
+ else {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badop=1;
+ break;
+ }
+
+ argc--;
+ argv++;
+ }
+
+ if (perform == 0) perform=3;
+
+ if(badop) {
+bad:
+ s_time_usage();
+ return -1;
+ }
+
+ return 0; /* Valid args */
+}
+
+/***********************************************************************
+ * TIME - time functions
+ */
+#define START 0
+#define STOP 1
+
+static double tm_Time_F(int s)
+ {
+ return app_tminterval(s,1);
+ }
+
+/***********************************************************************
+ * MAIN - main processing area for client
+ * real name depends on MONOLITH
+ */
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ double totalTime = 0.0;
+ int nConn = 0;
+ SSL *scon=NULL;
+ long finishtime=0;
+ int ret=1,i;
+ MS_STATIC char buf[1024*8];
+ int ver;
+
+ apps_startup();
+ s_time_init();
+
+ if (bio_err == NULL)
+ bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+ s_time_meth=SSLv23_client_method();
+#elif !defined(OPENSSL_NO_SSL3)
+ s_time_meth=SSLv3_client_method();
+#elif !defined(OPENSSL_NO_SSL2)
+ s_time_meth=SSLv2_client_method();
+#endif
+
+ /* parse the command line arguments */
+ if( parseArgs( argc, argv ) < 0 )
+ goto end;
+
+ OpenSSL_add_ssl_algorithms();
+ if ((tm_ctx=SSL_CTX_new(s_time_meth)) == NULL) return(1);
+
+ SSL_CTX_set_quiet_shutdown(tm_ctx,1);
+
+ if (st_bugs) SSL_CTX_set_options(tm_ctx,SSL_OP_ALL);
+ SSL_CTX_set_cipher_list(tm_ctx,tm_cipher);
+ if(!set_cert_stuff(tm_ctx,t_cert_file,t_key_file))
+ goto end;
+
+ SSL_load_error_strings();
+
+ if ((!SSL_CTX_load_verify_locations(tm_ctx,CAfile,CApath)) ||
+ (!SSL_CTX_set_default_verify_paths(tm_ctx)))
+ {
+ /* BIO_printf(bio_err,"error setting default verify locations\n"); */
+ ERR_print_errors(bio_err);
+ /* goto end; */
+ }
+
+ if (tm_cipher == NULL)
+ tm_cipher = getenv("SSL_CIPHER");
+
+ if (tm_cipher == NULL ) {
+ fprintf( stderr, "No CIPHER specified\n" );
+ }
+
+ if (!(perform & 1)) goto next;
+ printf( "Collecting connection statistics for %d seconds\n", maxTime );
+
+ /* Loop and time how long it takes to make connections */
+
+ bytes_read=0;
+ finishtime=(long)time(NULL)+maxTime;
+ tm_Time_F(START);
+ for (;;)
+ {
+ if (finishtime < (long)time(NULL)) break;
+#ifdef WIN32_STUFF
+
+ if( flushWinMsgs(0) == -1 )
+ goto end;
+
+ if( waitingToDie || exitNow ) /* we're dead */
+ goto end;
+#endif
+
+ if( (scon = doConnection( NULL )) == NULL )
+ goto end;
+
+ if (s_www_path != NULL)
+ {
+ BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
+ SSL_write(scon,buf,strlen(buf));
+ while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
+ bytes_read+=i;
+ }
+
+#ifdef NO_SHUTDOWN
+ SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+#else
+ SSL_shutdown(scon);
+#endif
+ SHUTDOWN2(SSL_get_fd(scon));
+
+ nConn += 1;
+ if (SSL_session_reused(scon))
+ ver='r';
+ else
+ {
+ ver=SSL_version(scon);
+ if (ver == TLS1_VERSION)
+ ver='t';
+ else if (ver == SSL3_VERSION)
+ ver='3';
+ else if (ver == SSL2_VERSION)
+ ver='2';
+ else
+ ver='*';
+ }
+ fputc(ver,stdout);
+ fflush(stdout);
+
+ SSL_free( scon );
+ scon=NULL;
+ }
+ totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
+
+ i=(int)((long)time(NULL)-finishtime+maxTime);
+ printf( "\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn/totalTime),bytes_read);
+ printf( "%d connections in %ld real seconds, %ld bytes read per connection\n",nConn,(long)time(NULL)-finishtime+maxTime,bytes_read/nConn);
+
+ /* Now loop and time connections using the same session id over and over */
+
+next:
+ if (!(perform & 2)) goto end;
+ printf( "\n\nNow timing with session id reuse.\n" );
+
+ /* Get an SSL object so we can reuse the session id */
+ if( (scon = doConnection( NULL )) == NULL )
+ {
+ fprintf( stderr, "Unable to get connection\n" );
+ goto end;
+ }
+
+ if (s_www_path != NULL)
+ {
+ BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
+ SSL_write(scon,buf,strlen(buf));
+ while (SSL_read(scon,buf,sizeof(buf)) > 0)
+ ;
+ }
+#ifdef NO_SHUTDOWN
+ SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+#else
+ SSL_shutdown(scon);
+#endif
+ SHUTDOWN2(SSL_get_fd(scon));
+
+ nConn = 0;
+ totalTime = 0.0;
+
+ finishtime=(long)time(NULL)+maxTime;
+
+ printf( "starting\n" );
+ bytes_read=0;
+ tm_Time_F(START);
+
+ for (;;)
+ {
+ if (finishtime < (long)time(NULL)) break;
+
+#ifdef WIN32_STUFF
+ if( flushWinMsgs(0) == -1 )
+ goto end;
+
+ if( waitingToDie || exitNow ) /* we're dead */
+ goto end;
+#endif
+
+ if( (doConnection( scon )) == NULL )
+ goto end;
+
+ if (s_www_path)
+ {
+ BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
+ SSL_write(scon,buf,strlen(buf));
+ while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
+ bytes_read+=i;
+ }
+
+#ifdef NO_SHUTDOWN
+ SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+#else
+ SSL_shutdown(scon);
+#endif
+ SHUTDOWN2(SSL_get_fd(scon));
+
+ nConn += 1;
+ if (SSL_session_reused(scon))
+ ver='r';
+ else
+ {
+ ver=SSL_version(scon);
+ if (ver == TLS1_VERSION)
+ ver='t';
+ else if (ver == SSL3_VERSION)
+ ver='3';
+ else if (ver == SSL2_VERSION)
+ ver='2';
+ else
+ ver='*';
+ }
+ fputc(ver,stdout);
+ fflush(stdout);
+ }
+ totalTime += tm_Time_F(STOP); /* Add the time for this iteration*/
+
+
+ printf( "\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn/totalTime),bytes_read);
+ printf( "%d connections in %ld real seconds, %ld bytes read per connection\n",nConn,(long)time(NULL)-finishtime+maxTime,bytes_read/nConn);
+
+ ret=0;
+end:
+ if (scon != NULL) SSL_free(scon);
+
+ if (tm_ctx != NULL)
+ {
+ SSL_CTX_free(tm_ctx);
+ tm_ctx=NULL;
+ }
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+/***********************************************************************
+ * doConnection - make a connection
+ * Args:
+ * scon = earlier ssl connection for session id, or NULL
+ * Returns:
+ * SSL * = the connection pointer.
+ */
+static SSL *doConnection(SSL *scon)
+ {
+ BIO *conn;
+ SSL *serverCon;
+ int width, i;
+ fd_set readfds;
+
+ if ((conn=BIO_new(BIO_s_connect())) == NULL)
+ return(NULL);
+
+/* BIO_set_conn_port(conn,port);*/
+ BIO_set_conn_hostname(conn,host);
+
+ if (scon == NULL)
+ serverCon=SSL_new(tm_ctx);
+ else
+ {
+ serverCon=scon;
+ SSL_set_connect_state(serverCon);
+ }
+
+ SSL_set_bio(serverCon,conn,conn);
+
+#if 0
+ if( scon != NULL )
+ SSL_set_session(serverCon,SSL_get_session(scon));
+#endif
+
+ /* ok, lets connect */
+ for(;;) {
+ i=SSL_connect(serverCon);
+ if (BIO_sock_should_retry(i))
+ {
+ BIO_printf(bio_err,"DELAY\n");
+
+ i=SSL_get_fd(serverCon);
+ width=i+1;
+ FD_ZERO(&readfds);
+ openssl_fdset(i,&readfds);
+ /* Note: under VMS with SOCKETSHR the 2nd parameter
+ * is currently of type (int *) whereas under other
+ * systems it is (void *) if you don't have a cast it
+ * will choke the compiler: if you do have a cast then
+ * you can either go for (int *) or (void *).
+ */
+ select(width,(void *)&readfds,NULL,NULL,NULL);
+ continue;
+ }
+ break;
+ }
+ if(i <= 0)
+ {
+ BIO_printf(bio_err,"ERROR\n");
+ if (verify_error != X509_V_OK)
+ BIO_printf(bio_err,"verify error:%s\n",
+ X509_verify_cert_error_string(verify_error));
+ else
+ ERR_print_errors(bio_err);
+ if (scon == NULL)
+ SSL_free(serverCon);
+ return NULL;
+ }
+
+ return serverCon;
+ }
+
+
diff --git a/deps/openssl/openssl/apps/server.pem b/deps/openssl/openssl/apps/server.pem
new file mode 100644
index 000000000..d0fc265f0
--- /dev/null
+++ b/deps/openssl/openssl/apps/server.pem
@@ -0,0 +1,52 @@
+subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Server Cert
+issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA
+-----BEGIN CERTIFICATE-----
+MIID5zCCAs+gAwIBAgIJALnu1NlVpZ6zMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT
+VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt
+ZWRpYXRlIENBMB4XDTExMTIwODE0MDE0OFoXDTIxMTAxNjE0MDE0OFowZDELMAkG
+A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU
+RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgU2VydmVyIENlcnQw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDzhPOSNtyyRspmeuUpxfNJ
+KCLTuf7g3uQ4zu4iHOmRO5TQci+HhVlLZrHF9XqFXcIP0y4pWDbMSGuiorUmzmfi
+R7bfSdI/+qIQt8KXRH6HNG1t8ou0VSvWId5TS5Dq/er5ODUr9OaaDva7EquHIcMv
+vPQGuI+OEAcnleVCy9HVEIySrO4P3CNIicnGkwwiAud05yUAq/gPXBC1hTtmlPD7
+TVcGVSEiJdvzqqlgv02qedGrkki6GY4S7GjZxrrf7Foc2EP+51LJzwLQx3/JfrCU
+41NEWAsu/Sl0tQabXESN+zJ1pDqoZ3uHMgpQjeGiE0olr+YcsSW/tJmiU9OiAr8R
+AgMBAAGjgY8wgYwwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwLAYJYIZI
+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
+BBSCvM8AABPR9zklmifnr9LvIBturDAfBgNVHSMEGDAWgBQ2w2yI55X+sL3szj49
+hqshgYfa2jANBgkqhkiG9w0BAQUFAAOCAQEAqb1NV0B0/pbpK9Z4/bNjzPQLTRLK
+WnSNm/Jh5v0GEUOE/Beg7GNjNrmeNmqxAlpqWz9qoeoFZax+QBpIZYjROU3TS3fp
+yLsrnlr0CDQ5R7kCCDGa8dkXxemmpZZLbUCpW2Uoy8sAA4JjN9OtsZY7dvUXFgJ7
+vVNTRnI01ghknbtD+2SxSQd3CWF6QhcRMAzZJ1z1cbbwGDDzfvGFPzJ+Sq+zEPds
+xoVLLSetCiBc+40ZcDS5dV98h9XD7JMTQfxzA7mNGv73JoZJA6nFgj+ADSlJsY/t
+JBv+z1iQRueoh9Qeee+ZbRifPouCB8FDx+AltvHTANdAq0t/K3o+pplMVA==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA84TzkjbcskbKZnrlKcXzSSgi07n+4N7kOM7uIhzpkTuU0HIv
+h4VZS2axxfV6hV3CD9MuKVg2zEhroqK1Js5n4ke230nSP/qiELfCl0R+hzRtbfKL
+tFUr1iHeU0uQ6v3q+Tg1K/Tmmg72uxKrhyHDL7z0BriPjhAHJ5XlQsvR1RCMkqzu
+D9wjSInJxpMMIgLndOclAKv4D1wQtYU7ZpTw+01XBlUhIiXb86qpYL9NqnnRq5JI
+uhmOEuxo2ca63+xaHNhD/udSyc8C0Md/yX6wlONTRFgLLv0pdLUGm1xEjfsydaQ6
+qGd7hzIKUI3hohNKJa/mHLElv7SZolPTogK/EQIDAQABAoIBAADq9FwNtuE5IRQn
+zGtO4q7Y5uCzZ8GDNYr9RKp+P2cbuWDbvVAecYq2NV9QoIiWJOAYZKklOvekIju3
+r0UZLA0PRiIrTg6NrESx3JrjWDK8QNlUO7CPTZ39/K+FrmMkV9lem9yxjJjyC34D
+AQB+YRTx+l14HppjdxNwHjAVQpIx/uO2F5xAMuk32+3K+pq9CZUtrofe1q4Agj9R
+5s8mSy9pbRo9kW9wl5xdEotz1LivFOEiqPUJTUq5J5PeMKao3vdK726XI4Z455Nm
+W2/MA0YV0ug2FYinHcZdvKM6dimH8GLfa3X8xKRfzjGjTiMSwsdjgMa4awY3tEHH
+674jhAECgYEA/zqMrc0zsbNk83sjgaYIug5kzEpN4ic020rSZsmQxSCerJTgNhmg
+utKSCt0Re09Jt3LqG48msahX8ycqDsHNvlEGPQSbMu9IYeO3Wr3fAm75GEtFWePY
+BhM73I7gkRt4s8bUiUepMG/wY45c5tRF23xi8foReHFFe9MDzh8fJFECgYEA9EFX
+4qAik1pOJGNei9BMwmx0I0gfVEIgu0tzeVqT45vcxbxr7RkTEaDoAG6PlbWP6D9a
+WQNLp4gsgRM90ZXOJ4up5DsAWDluvaF4/omabMA+MJJ5kGZ0gCj5rbZbKqUws7x8
+bp+6iBfUPJUbcqNqFmi/08Yt7vrDnMnyMw2A/sECgYEAiiuRMxnuzVm34hQcsbhH
+6ymVqf7j0PW2qK0F4H1ocT9qhzWFd+RB3kHWrCjnqODQoI6GbGr/4JepHUpre1ex
+4UEN5oSS3G0ru0rC3U4C59dZ5KwDHFm7ffZ1pr52ljfQDUsrjjIMRtuiwNK2OoRa
+WSsqiaL+SDzSB+nBmpnAizECgYBdt/y6rerWUx4MhDwwtTnel7JwHyo2MDFS6/5g
+n8qC2Lj6/fMDRE22w+CA2esp7EJNQJGv+b27iFpbJEDh+/Lf5YzIT4MwVskQ5bYB
+JFcmRxUVmf4e09D7o705U/DjCgMH09iCsbLmqQ38ONIRSHZaJtMDtNTHD1yi+jF+
+OT43gQKBgQC/2OHZoko6iRlNOAQ/tMVFNq7fL81GivoQ9F1U0Qr+DH3ZfaH8eIkX
+xT0ToMPJUzWAn8pZv0snA0um6SIgvkCuxO84OkANCVbttzXImIsL7pFzfcwV/ERK
+UM6j0ZuSMFOCr/lGPAoOQU0fskidGEHi1/kW+suSr28TqsyYZpwBDQ==
+-----END RSA PRIVATE KEY-----
diff --git a/deps/openssl/openssl/apps/server.srl b/deps/openssl/openssl/apps/server.srl
new file mode 100644
index 000000000..8a0f05e16
--- /dev/null
+++ b/deps/openssl/openssl/apps/server.srl
@@ -0,0 +1 @@
+01
diff --git a/deps/openssl/openssl/apps/server2.pem b/deps/openssl/openssl/apps/server2.pem
new file mode 100644
index 000000000..a3927cf78
--- /dev/null
+++ b/deps/openssl/openssl/apps/server2.pem
@@ -0,0 +1,52 @@
+subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Server Cert #2
+issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA
+-----BEGIN CERTIFICATE-----
+MIID6jCCAtKgAwIBAgIJALnu1NlVpZ60MA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT
+VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt
+ZWRpYXRlIENBMB4XDTExMTIwODE0MDE0OFoXDTIxMTAxNjE0MDE0OFowZzELMAkG
+A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU
+RVNUSU5HIFBVUlBPU0VTIE9OTFkxHDAaBgNVBAMME1Rlc3QgU2VydmVyIENlcnQg
+IzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDrdi7j9yctG+L4EjBy
+gjPmEqZzOJEQba26MoQGzglU7e5Xf59Rb/hgVQuKAoiZe7/R8rK4zJ4W7iXdXw0L
+qBpyG8B5aGKeI32w+A9TcBApoXXL2CrYQEQjZwUIpLlYBIi2NkJj3nVkq5dgl1gO
+ALiQ+W8jg3kzg5Ec9rimp9r93N8wsSL3awsafurmYCvOf7leHaMP1WJ/zDRGUNHG
+/WtDjXc8ZUG1+6EXU9Jc2Fs+2Omf7fcN0l00AK/wPg8OaNS0rKyGq9JdIT9FRGV1
+bXe/rx58FaE5CItdwCSYhJvF/O95LWQoxJXye5bCFLmvDTEyVq9FMSCptfsmbXjE
+ZGsXAgMBAAGjgY8wgYwwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwLAYJ
+YIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1Ud
+DgQWBBR52UaWWTKzZGDH/X4mWNcuqeQVazAfBgNVHSMEGDAWgBQ2w2yI55X+sL3s
+zj49hqshgYfa2jANBgkqhkiG9w0BAQUFAAOCAQEANBW+XYLlHBqVY/31ie+3gRlS
+LPfy4SIqn0t3RJjagT29MXprblBO2cbMO8VGjkQdKGpmMXjxbht2arOOUXRHX4n/
+XTyn/QHEf0bcwIITMReO3DZUPAEw8hSjn9xEOM0IRVOCP+mH5fi74QzzQaZVCyYg
+5VtLKdww/+sc0nCbKl2KWgDluriH0nfVx95qgW3mg9dhXRr0zmf1w2zkBHYpARYL
+Dew6Z8EE4tS3HJu8/qM6meWzNtrfonQ3eiiMxjZBxzV46jchBwa2z9XYhP6AmpPb
+oeTSzcQNbWsxaGYzWo46oLDUZmJOwSBawbS31bZNMCoPIY6ukoesCzFSsUKZww==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA63Yu4/cnLRvi+BIwcoIz5hKmcziREG2tujKEBs4JVO3uV3+f
+UW/4YFULigKImXu/0fKyuMyeFu4l3V8NC6gachvAeWhiniN9sPgPU3AQKaF1y9gq
+2EBEI2cFCKS5WASItjZCY951ZKuXYJdYDgC4kPlvI4N5M4ORHPa4pqfa/dzfMLEi
+92sLGn7q5mArzn+5Xh2jD9Vif8w0RlDRxv1rQ413PGVBtfuhF1PSXNhbPtjpn+33
+DdJdNACv8D4PDmjUtKyshqvSXSE/RURldW13v68efBWhOQiLXcAkmISbxfzveS1k
+KMSV8nuWwhS5rw0xMlavRTEgqbX7Jm14xGRrFwIDAQABAoIBAHLsTPihIfLnYIE5
+x4GsQQ5zXeBw5ITDM37ktwHnQDC+rIzyUl1aLD1AZRBoKinXd4lOTqLZ4/NHKx4A
+DYr58mZtWyUmqLOMmQVuHXTZBlp7XtYuXMMNovQwjQlp9LicBeoBU6gQ5PVMtubD
+F4xGF89Sn0cTHW3iMkqTtQ5KcR1j57OcJO0FEb1vPvk2MXI5ZyAatUYE7YacbEzd
+rg02uIwx3FqNSkuSI79uz4hMdV5TPtuhxx9nTwj9aLUhXFeZ0mn2PVgVzEnnMoJb
++znlsZDgzDlJqdaD744YGWh8Z3OEssB35KfzFcdOeO6yH8lmv2Zfznk7pNPT7LTb
+Lae9VgkCgYEA92p1qnAB3NtJtNcaW53i0S5WJgS1hxWKvUDx3lTB9s8X9fHpqL1a
+E94fDfWzp/hax6FefUKIvBOukPLQ6bYjTMiFoOHzVirghAIuIUoMI5VtLhwD1hKs
+Lr7l/dptMgKb1nZHyXoKHRBthsy3K4+udsPi8TzMvYElgEqyQIe/Rk0CgYEA86GL
+8HC6zLszzKERDPBxrboRmoFvVUCTQDhsfj1M8aR3nQ8V5LkdIJc7Wqm/Ggfk9QRf
+rJ8M2WUMlU5CNnCn/KCrKzCNZIReze3fV+HnKdbcXGLvgbHPrhnz8yYehUFG+RGq
+bVyDWRU94T38izy2s5qMYrMJWZEYyXncSPbfcPMCgYAtaXfxcZ+V5xYPQFARMtiX
+5nZfggvDoJuXgx0h3tK/N2HBfcaSdzbaYLG4gTmZggc/jwnl2dl5E++9oSPhUdIG
+3ONSFUbxsOsGr9PBvnKd8WZZyUCXAVRjPBzAzF+whzQNWCZy/5htnz9LN7YDI9s0
+5113Q96cheDZPFydZY0hHQKBgQDVbEhNukM5xCiNcu+f2SaMnLp9EjQ4h5g3IvaP
+5B16daw/Dw8LzcohWboqIxeAsze0GD/D1ZUJAEd0qBjC3g+a9BjefervCjKOzXng
+38mEUm+6EwVjJSQcjSmycEs+Sr/kwr/8i5WYvU32+jk4tFgMoC+o6tQe/Uesf68k
+z/dPVwKBgGbF7Vv1/3SmhlOy+zYyvJ0CrWtKxH9QP6tLIEgEpd8x7YTSuCH94yok
+kToMXYA3sWNPt22GbRDZ+rcp4c7HkDx6I6vpdP9aQEwJTp0EPy0sgWr2XwYmreIQ
+NFmkk8Itn9EY2R9VBaP7GLv5kvwxDdLAnmwGmzVtbmaVdxCaBwUk
+-----END RSA PRIVATE KEY-----
diff --git a/deps/openssl/openssl/apps/sess_id.c b/deps/openssl/openssl/apps/sess_id.c
new file mode 100644
index 000000000..b16686c26
--- /dev/null
+++ b/deps/openssl/openssl/apps/sess_id.c
@@ -0,0 +1,322 @@
+/* apps/sess_id.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+
+#undef PROG
+#define PROG sess_id_main
+
+static const char *sess_id_usage[]={
+"usage: sess_id args\n",
+"\n",
+" -inform arg - input format - default PEM (DER or PEM)\n",
+" -outform arg - output format - default PEM\n",
+" -in arg - input file - default stdin\n",
+" -out arg - output file - default stdout\n",
+" -text - print ssl session id details\n",
+" -cert - output certificate \n",
+" -noout - no CRL output\n",
+" -context arg - set the session ID context\n",
+NULL
+};
+
+static SSL_SESSION *load_sess_id(char *file, int format);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ SSL_SESSION *x=NULL;
+ X509 *peer = NULL;
+ int ret=1,i,num,badops=0;
+ BIO *out=NULL;
+ int informat,outformat;
+ char *infile=NULL,*outfile=NULL,*context=NULL;
+ int cert=0,noout=0,text=0;
+ const char **pp;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+
+ argc--;
+ argv++;
+ num=0;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-text") == 0)
+ text= ++num;
+ else if (strcmp(*argv,"-cert") == 0)
+ cert= ++num;
+ else if (strcmp(*argv,"-noout") == 0)
+ noout= ++num;
+ else if (strcmp(*argv,"-context") == 0)
+ {
+ if(--argc < 1) goto bad;
+ context=*++argv;
+ }
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ for (pp=sess_id_usage; (*pp != NULL); pp++)
+ BIO_printf(bio_err,"%s",*pp);
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+ x=load_sess_id(infile,informat);
+ if (x == NULL) { goto end; }
+ peer = SSL_SESSION_get0_peer(x);
+
+ if(context)
+ {
+ size_t ctx_len = strlen(context);
+ if(ctx_len > SSL_MAX_SID_CTX_LENGTH)
+ {
+ BIO_printf(bio_err,"Context too long\n");
+ goto end;
+ }
+ SSL_SESSION_set1_id_context(x, (unsigned char *)context, ctx_len);
+ }
+
+#ifdef undef
+ /* just testing for memory leaks :-) */
+ {
+ SSL_SESSION *s;
+ char buf[1024*10],*p;
+ int i;
+
+ s=SSL_SESSION_new();
+
+ p= &buf;
+ i=i2d_SSL_SESSION(x,&p);
+ p= &buf;
+ d2i_SSL_SESSION(&s,&p,(long)i);
+ p= &buf;
+ d2i_SSL_SESSION(&s,&p,(long)i);
+ p= &buf;
+ d2i_SSL_SESSION(&s,&p,(long)i);
+ SSL_SESSION_free(s);
+ }
+#endif
+
+ if (!noout || text)
+ {
+ out=BIO_new(BIO_s_file());
+ if (out == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+ }
+
+ if (text)
+ {
+ SSL_SESSION_print(out,x);
+
+ if (cert)
+ {
+ if (peer == NULL)
+ BIO_puts(out,"No certificate present\n");
+ else
+ X509_print(out,peer);
+ }
+ }
+
+ if (!noout && !cert)
+ {
+ if (outformat == FORMAT_ASN1)
+ i=i2d_SSL_SESSION_bio(out,x);
+ else if (outformat == FORMAT_PEM)
+ i=PEM_write_bio_SSL_SESSION(out,x);
+ else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (!i) {
+ BIO_printf(bio_err,"unable to write SSL_SESSION\n");
+ goto end;
+ }
+ }
+ else if (!noout && (peer != NULL)) /* just print the certificate */
+ {
+ if (outformat == FORMAT_ASN1)
+ i=(int)i2d_X509_bio(out,peer);
+ else if (outformat == FORMAT_PEM)
+ i=PEM_write_bio_X509(out,peer);
+ else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (!i) {
+ BIO_printf(bio_err,"unable to write X509\n");
+ goto end;
+ }
+ }
+ ret=0;
+end:
+ if (out != NULL) BIO_free_all(out);
+ if (x != NULL) SSL_SESSION_free(x);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+static SSL_SESSION *load_sess_id(char *infile, int format)
+ {
+ SSL_SESSION *x=NULL;
+ BIO *in=NULL;
+
+ in=BIO_new(BIO_s_file());
+ if (in == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ goto end;
+ }
+ }
+ if (format == FORMAT_ASN1)
+ x=d2i_SSL_SESSION_bio(in,NULL);
+ else if (format == FORMAT_PEM)
+ x=PEM_read_bio_SSL_SESSION(in,NULL,NULL,NULL);
+ else {
+ BIO_printf(bio_err,"bad input format specified for input crl\n");
+ goto end;
+ }
+ if (x == NULL)
+ {
+ BIO_printf(bio_err,"unable to load SSL_SESSION\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+end:
+ if (in != NULL) BIO_free(in);
+ return(x);
+ }
+
diff --git a/deps/openssl/openssl/apps/set/set-g-ca.pem b/deps/openssl/openssl/apps/set/set-g-ca.pem
new file mode 100644
index 000000000..78499f057
--- /dev/null
+++ b/deps/openssl/openssl/apps/set/set-g-ca.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDeDCCAuGgAwIBAgIgYCYUeg8NJ9kO1q3z6vGCkAmPRfu5+Nur0FyGF79MADMw
+DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0JDQTEwMTcx
+MTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjIw
+MDAwMDBaFw05NjExMjEyMzU5NTlaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtQ
+Q0ExMDIxMTgyODEgMB4GA1UEAxMXQnJhbmQgTmFtZTpQcm9kdWN0IFR5cGUwgZ8w
+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJyi5V7l1HohY6hN/2N9x6mvWeMy8rD1
+6lfXjgmiuGmhpaszWYaalesMcS2OGuG8Lq3PkaSzpVzqASKfIOjxLMsdpYyYJRub
+vRPDWi3xd8wlp9xUwWHKqn+ki8mPo0yN4eONwZZ4rcZr6K+tWd+5EJZSjuENJoQ/
+SRRmGRzdcS7XAgMBAAGjggFXMIIBUzBUBgNVHSMETTBLoSekJTAjMQswCQYDVQQG
+EwJVUzEUMBIGA1UEChMLUkNBMTAxMTE4MjmCIGApUs14Ad7t9VTGq2PpV8DylPQ7
+aATM2mor7lc1fWvZMA4GA1UdDwEB/wQEAwIBBjAuBgNVHRABAf8EJDAigA8xOTk2
+MTAyMjAxMjIwMFqBDzE5OTYxMTIxMjM1OTU5WjAbBgNVHSABAf8EETAPMA0GC2CG
+SAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYBAf8CAQAwDwYEho1vAwEB/wQEAwICBDB5
+BgSGjW8HAQH/BG4wbDAkAgEAMAkGBSsOAwIaBQAEFDJmNzRiMWFmNGZjYzA2MGY3
+Njc2Ew90ZXJzZSBzdGF0ZW1lbnSAF2h0dHA6Ly93d3cudmVyaXNpZ24uY29tgRpn
+ZXRzZXQtY2VudGVyQHZlcmlzaWduLmNvbTANBgkqhkiG9w0BAQUFAAOBgQBn19R2
+AgGvpJDmfXrHTDdCoYyMkaP2MPzw0hFRwh+wqnw0/pqUXa7MrLXMqtD3rUyOWaNR
+9fYpJZd0Bh/1OeIc2+U+VNfUovLLuZ8nNemdxyq2KMYnHtnh7UdO7atZ+PFLVu8x
+a+J2Mtj8MGy12CJNTJcjLSrJ/1f3AuVrwELjlQ==
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/apps/set/set-m-ca.pem b/deps/openssl/openssl/apps/set/set-m-ca.pem
new file mode 100644
index 000000000..0e74caff6
--- /dev/null
+++ b/deps/openssl/openssl/apps/set/set-m-ca.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDeDCCAuGgAwIBAgIgEGvcf5aUnufALdVMa/dmPdflq1CoORGeK5DUwbqhVYcw
+DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0JDQTEwMTcx
+MTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjIw
+MDAwMDBaFw05NjExMjEyMzU5NTlaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtN
+Q0ExMDIxMTgyNzEgMB4GA1UEAxMXQnJhbmQgTmFtZTpQcm9kdWN0IFR5cGUwgZ8w
+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALuWwr63YrT1GIZpYKfIeiVFHESG/FZO
+7RAJKml/p12ZyZ7D5YPP4BBXVsa1H8e8arR1LKC4rdCArrtKKlBeBiMo9+NB+u35
+FnLnTmfzM4iZ2Syw35DXY8+Xn/LM7RJ1RG+vMNcTqpoUg7QPye7flq2Pt7vVROPn
+SZxPyVxmILe3AgMBAAGjggFXMIIBUzBUBgNVHSMETTBLoSekJTAjMQswCQYDVQQG
+EwJVUzEUMBIGA1UEChMLUkNBMTAxMTE4MjmCIGApUs14Ad7t9VTGq2PpV8DylPQ7
+aATM2mor7lc1fWvZMA4GA1UdDwEB/wQEAwIBBjAuBgNVHRABAf8EJDAigA8xOTk2
+MTAyMjAxMjEwMFqBDzE5OTYxMTIxMjM1OTU5WjAbBgNVHSABAf8EETAPMA0GC2CG
+SAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYBAf8CAQAwDwYEho1vAwEB/wQEAwIDCDB5
+BgSGjW8HAQH/BG4wbDAkAgEAMAkGBSsOAwIaBQAEFDJmNzRiMWFmNGZjYzA2MGY3
+Njc2Ew90ZXJzZSBzdGF0ZW1lbnSAF2h0dHA6Ly93d3cudmVyaXNpZ24uY29tgRpn
+ZXRzZXQtY2VudGVyQHZlcmlzaWduLmNvbTANBgkqhkiG9w0BAQUFAAOBgQApaj0W
+GgyR47URZEZ7z83yivvnVErqtodub/nR1fMgJ4bDC0ofjA0SzXBP1/3eDq9VkPuS
+EKUw9BpM2XrSUKhJ6F1CbBjWpM0M7GC1nTSxMxmV+XL+Ab/Gn2SwozUApWtht29/
+x9VLB8qsi6wN2aOsVdQMl5iVCjGQYfEkyuoIgA==
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/apps/set/set_b_ca.pem b/deps/openssl/openssl/apps/set/set_b_ca.pem
new file mode 100644
index 000000000..eba7d5cf5
--- /dev/null
+++ b/deps/openssl/openssl/apps/set/set_b_ca.pem
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID1zCCAr+gAwIBAgIgYClSzXgB3u31VMarY+lXwPKU9DtoBMzaaivuVzV9a9kw
+DQYJKoZIhvcNAQEFBQAwIzELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1JDQTEwMTEx
+ODI5MB4XDTk2MTAxNzAwMDAwMFoXDTk2MTExNjIzNTk1OVowRTELMAkGA1UEBhMC
+VVMxFDASBgNVBAoTC0JDQTEwMTcxMTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlBy
+b2R1Y3QgVHlwZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApPewvR0BwV02
+9E12ic48pMY/aMB6SkMEWPDx2hURr0DKYGJ6qMvzZn2pSfaVH1BqDtK6oK4Ye5Mj
+ItywwQIdXXO9Ut8+TLnvtzq9ByCJ0YThjZJBc7ZcpJxSV7QAoBON/lzxZuAVq3+L
+3uc39MgRwmBpRllZEpWrkojxs6166X0CAwEAAaOCAVcwggFTMFQGA1UdIwRNMEuh
+J6QlMCMxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtSQ0ExMDExMTgyOYIgVqenwCYv
+mmxUIvi9gUMCa+uJGJ60mZecw9HrISXnLaYwDgYDVR0PAQH/BAQDAgEGMC4GA1Ud
+EAEB/wQkMCKADzE5OTYxMDE3MTc1NzAwWoEPMTk5NjExMTYyMzU5NTlaMBsGA1Ud
+IAEB/wQRMA8wDQYLYIZIAYb4RQEHAQEwEgYDVR0TAQH/BAgwBgEB/wIBATAPBgSG
+jW8DAQH/BAQDAgABMHkGBIaNbwcBAf8EbjBsMCQCAQAwCQYFKw4DAhoFAAQUMmY3
+NGIxYWY0ZmNjMDYwZjc2NzYTD3RlcnNlIHN0YXRlbWVudIAXaHR0cDovL3d3dy52
+ZXJpc2lnbi5jb22BGmdldHNldC1jZW50ZXJAdmVyaXNpZ24uY29tMA0GCSqGSIb3
+DQEBBQUAA4IBAQAWoMS8Aj2sO0LDxRoMcnWTKY8nd8Jw2vl2Mgsm+0qCvcndICM5
+43N0y9uHlP8WeCZULbFz95gTL8mfP/QTu4EctMUkQgRHJnx80f0XSF3HE/X6zBbI
+9rit/bF6yP1mhkdss/vGanReDpki7q8pLx+VIIcxWst/366HP3dW1Fb7ECW/WmVV
+VMN93f/xqk9I4sXchVZcVKQT3W4tzv+qQvugrEi1dSEkbAy1CITEAEGiaFhGUyCe
+WPox3guRXaEHoINNeajGrISe6d//alsz5EEroBoLnM2ryqWfLAtRsf4rjNzTgklw
+lbiz0fw7bNkXKp5ZVr0wlnOjQnoSM6dTI0AV
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/apps/set/set_c_ca.pem b/deps/openssl/openssl/apps/set/set_c_ca.pem
new file mode 100644
index 000000000..48b2cbdc7
--- /dev/null
+++ b/deps/openssl/openssl/apps/set/set_c_ca.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDeDCCAuGgAwIBAgIgOnl8J6lAYNDdTWtIojWCGnloNf4ufHjOZ4Fkxwg5xOsw
+DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0JDQTEwMTcx
+MTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjIw
+MDAwMDBaFw05NjExMjEyMzU5NTlaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtD
+Q0ExMDIxMTYxNjEgMB4GA1UEAxMXQnJhbmQgTmFtZTpQcm9kdWN0IFR5cGUwgZ8w
+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANA3a9+U8oXU3Dv1wJf8g0A7HjCRZAXc
+Y8E4OLOdye5aUssxifCE05qTPVqHMXo6cnCYcfroMdURhjQlswyTGtjQybgUnXjp
+pchw+V4D1DkN0ThErrMCh9ZFSykC0lUhQTRLESvbIb4Gal/HMAFAF5sj0GoOFi2H
+RRj7gpzBIU3xAgMBAAGjggFXMIIBUzBUBgNVHSMETTBLoSekJTAjMQswCQYDVQQG
+EwJVUzEUMBIGA1UEChMLUkNBMTAxMTE4MjmCIGApUs14Ad7t9VTGq2PpV8DylPQ7
+aATM2mor7lc1fWvZMA4GA1UdDwEB/wQEAwIBBjAuBgNVHRABAf8EJDAigA8xOTk2
+MTAyMjAxMTAwMFqBDzE5OTYxMTIxMjM1OTU5WjAbBgNVHSABAf8EETAPMA0GC2CG
+SAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYBAf8CAQAwDwYEho1vAwEB/wQEAwIEEDB5
+BgSGjW8HAQH/BG4wbDAkAgEAMAkGBSsOAwIaBQAEFDJmNzRiMWFmNGZjYzA2MGY3
+Njc2Ew90ZXJzZSBzdGF0ZW1lbnSAF2h0dHA6Ly93d3cudmVyaXNpZ24uY29tgRpn
+ZXRzZXQtY2VudGVyQHZlcmlzaWduLmNvbTANBgkqhkiG9w0BAQUFAAOBgQBteLaZ
+u/TASC64UWPfhxYAUdys9DQ1pG/J1qPWNTkjOmpXFvW+7l/3nkxyRPgUoFNwx1e7
+XVVPr6zhy8LaaXppwfIZvVryzAUdbtijiUf/MO0hvV3w7e9NlCVProdU5H9EvCXr
++IV8rH8fdEkirIVyw0JGHkuWhkmtS1HEwai9vg==
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/apps/set/set_d_ct.pem b/deps/openssl/openssl/apps/set/set_d_ct.pem
new file mode 100644
index 000000000..9f8c7d8b0
--- /dev/null
+++ b/deps/openssl/openssl/apps/set/set_d_ct.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDdjCCAt+gAwIBAgIgRU5t24v72xVDpZ4iHpyoOAQaQmfio1yhTZAOkBfT2uUw
+DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0NDQTEwMjEx
+NjE2MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjQw
+MDAwMDBaFw05NjExMjMyMzU5NTlaMG4xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdC
+cmFuZElEMSYwJAYDVQQLEx1Jc3N1aW5nIEZpbmFuY2lhbCBJbnN0aXR1dGlvbjEl
+MCMGA1UEAxMcR2lYb0t0VjViN1V0MHZKa2hkSG5RYmNzc2JrPTBcMA0GCSqGSIb3
+DQEBAQUAA0sAMEgCQQDIUxgpNB1aoSW585WErtN8WInCRWCqDj3RGT2mJye0F4SM
+/iT5ywdWMasmw18vpEpDlMypfZnRkUAdfyHcRABVAgMBAAGjggFwMIIBbDB2BgNV
+HSMEbzBtoUmkRzBFMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLQkNBMTAxNzExMDQx
+IDAeBgNVBAMTF0JyYW5kIE5hbWU6UHJvZHVjdCBUeXBlgiA6eXwnqUBg0N1Na0ii
+NYIaeWg1/i58eM5ngWTHCDnE6zAOBgNVHQ8BAf8EBAMCB4AwLgYDVR0QAQH/BCQw
+IoAPMTk5NjEwMjQwMTA0MDBagQ8xOTk2MTEyMzIzNTk1OVowGAYDVR0gBBEwDzAN
+BgtghkgBhvhFAQcBATAMBgNVHRMBAf8EAjAAMA8GBIaNbwMBAf8EBAMCB4AweQYE
+ho1vBwEB/wRuMGwwJAIBADAJBgUrDgMCGgUABBQzOTgyMzk4NzIzNzg5MTM0OTc4
+MhMPdGVyc2Ugc3RhdGVtZW50gBdodHRwOi8vd3d3LnZlcmlzaWduLmNvbYEaZ2V0
+c2V0LWNlbnRlckB2ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEAVHCjhxeD
+mIFSkm3DpQAq7pGfcAFPWvSM9I9bK8qeFT1M5YQ+5fbPqaWlNcQlGKIe3cHd4+0P
+ndL5lb6UBhhA0kTzEYA38+HtBxPe/lokCv0bYfyWY9asUmvfbUrTYta0yjN7ixnV
+UqvxxHQHOAwhf6bcc7xNHapOxloWzGUU0RQ=
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/apps/set/set_root.pem b/deps/openssl/openssl/apps/set/set_root.pem
new file mode 100644
index 000000000..8dd104f05
--- /dev/null
+++ b/deps/openssl/openssl/apps/set/set_root.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDZzCCAk+gAwIBAgIgVqenwCYvmmxUIvi9gUMCa+uJGJ60mZecw9HrISXnLaYw
+DQYJKoZIhvcNAQEFBQAwIzELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1JDQTEwMTEx
+ODI5MB4XDTk2MTAxMjAwMDAwMFoXDTk2MTExMTIzNTk1OVowIzELMAkGA1UEBhMC
+VVMxFDASBgNVBAoTC1JDQTEwMTExODI5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAukca0PVUGFIYX7EyrShi+dVi9GTNzG0V2Wtdw6DqFzKfedba/KpE
+zqnRDV/wRZlBn3oXPS6kNCFiBPRV9mEFXI7y2W+q8/vPurjRDIXMsqQ+dAhKwf4q
+rofJBTiET4NUN0YTtpx6aYuoVubjiOgKdbqnUArxAWWP2Dkco17ipEYyUtd4sTAe
+/xKR02AHpbYGYPSHjMDS/nzUJ7uX4d51phs0rt7If48ExJSnDV/KoHMfm42mdmH2
+g23005qdHKY3UXeh10tZmb3QtGTSvF6OqpRZ+e9/ALklu7ZcIjqbb944ci4QWemb
+ZNWiDFrWWUoO1k942BI/iZ8Fh8pETYSDBQIDAQABo4GGMIGDMA4GA1UdDwEB/wQE
+AwIBBjAuBgNVHRABAf8EJDAigA8xOTk2MTAxMjAxMzQwMFqBDzE5OTYxMTExMjM1
+OTU5WjAbBgNVHSABAf8EETAPMA0GC2CGSAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYB
+Af8CAQIwEAYEho1vAwEB/wQFAwMHAIAwDQYJKoZIhvcNAQEFBQADggEBAK4tntea
+y+ws7PdULwfqAS5osaoNvw73uBn5lROTpx91uhQbJyf0oZ3XG9GUuHZBpqG9qmr9
+vIL40RsvRpNMYgaNHKTxF716yx6rZmruAYZsrE3SpV63tQJCckKLPSge2E5uDhSQ
+O8UjusG+IRT9fKMXUHLv4OmZPOQVOSl1qTCN2XoJFqEPtC3Y9P4YR4xHL0P2jb1l
+DLdIbruuh+6omH+0XUZd5fKnQZTTi6gjl0iunj3wGnkcqGZtwr3j87ONiB/8tDwY
+vz8ceII4YYdX12PrNzn+fu3R5rChvPW4/ah/SaYQ2VQ0AupaIF4xrNJ/gLYYw0YO
+bxCrVJLd8tu9WgA=
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/apps/smime.c b/deps/openssl/openssl/apps/smime.c
new file mode 100644
index 000000000..c583f8a0e
--- /dev/null
+++ b/deps/openssl/openssl/apps/smime.c
@@ -0,0 +1,857 @@
+/* smime.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 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
+ * licensing@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).
+ *
+ */
+
+/* S/MIME utility function */
+
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/crypto.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/x509v3.h>
+
+#undef PROG
+#define PROG smime_main
+static int save_certs(char *signerfile, STACK_OF(X509) *signers);
+static int smime_cb(int ok, X509_STORE_CTX *ctx);
+
+#define SMIME_OP 0x10
+#define SMIME_IP 0x20
+#define SMIME_SIGNERS 0x40
+#define SMIME_ENCRYPT (1 | SMIME_OP)
+#define SMIME_DECRYPT (2 | SMIME_IP)
+#define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_VERIFY (4 | SMIME_IP)
+#define SMIME_PK7OUT (5 | SMIME_IP | SMIME_OP)
+#define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ int operation = 0;
+ int ret = 0;
+ char **args;
+ const char *inmode = "r", *outmode = "w";
+ char *infile = NULL, *outfile = NULL;
+ char *signerfile = NULL, *recipfile = NULL;
+ STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
+ char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
+ const EVP_CIPHER *cipher = NULL;
+ PKCS7 *p7 = NULL;
+ X509_STORE *store = NULL;
+ X509 *cert = NULL, *recip = NULL, *signer = NULL;
+ EVP_PKEY *key = NULL;
+ STACK_OF(X509) *encerts = NULL, *other = NULL;
+ BIO *in = NULL, *out = NULL, *indata = NULL;
+ int badarg = 0;
+ int flags = PKCS7_DETACHED;
+ char *to = NULL, *from = NULL, *subject = NULL;
+ char *CAfile = NULL, *CApath = NULL;
+ char *passargin = NULL, *passin = NULL;
+ char *inrand = NULL;
+ int need_rand = 0;
+ int indef = 0;
+ const EVP_MD *sign_md = NULL;
+ int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
+ int keyform = FORMAT_PEM;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+
+ X509_VERIFY_PARAM *vpm = NULL;
+
+ args = argv + 1;
+ ret = 1;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ {
+ if ((bio_err = BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
+ }
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ while (!badarg && *args && *args[0] == '-')
+ {
+ if (!strcmp (*args, "-encrypt"))
+ operation = SMIME_ENCRYPT;
+ else if (!strcmp (*args, "-decrypt"))
+ operation = SMIME_DECRYPT;
+ else if (!strcmp (*args, "-sign"))
+ operation = SMIME_SIGN;
+ else if (!strcmp (*args, "-resign"))
+ operation = SMIME_RESIGN;
+ else if (!strcmp (*args, "-verify"))
+ operation = SMIME_VERIFY;
+ else if (!strcmp (*args, "-pk7out"))
+ operation = SMIME_PK7OUT;
+#ifndef OPENSSL_NO_DES
+ else if (!strcmp (*args, "-des3"))
+ cipher = EVP_des_ede3_cbc();
+ else if (!strcmp (*args, "-des"))
+ cipher = EVP_des_cbc();
+#endif
+#ifndef OPENSSL_NO_SEED
+ else if (!strcmp (*args, "-seed"))
+ cipher = EVP_seed_cbc();
+#endif
+#ifndef OPENSSL_NO_RC2
+ else if (!strcmp (*args, "-rc2-40"))
+ cipher = EVP_rc2_40_cbc();
+ else if (!strcmp (*args, "-rc2-128"))
+ cipher = EVP_rc2_cbc();
+ else if (!strcmp (*args, "-rc2-64"))
+ cipher = EVP_rc2_64_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+ else if (!strcmp(*args,"-aes128"))
+ cipher = EVP_aes_128_cbc();
+ else if (!strcmp(*args,"-aes192"))
+ cipher = EVP_aes_192_cbc();
+ else if (!strcmp(*args,"-aes256"))
+ cipher = EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ else if (!strcmp(*args,"-camellia128"))
+ cipher = EVP_camellia_128_cbc();
+ else if (!strcmp(*args,"-camellia192"))
+ cipher = EVP_camellia_192_cbc();
+ else if (!strcmp(*args,"-camellia256"))
+ cipher = EVP_camellia_256_cbc();
+#endif
+ else if (!strcmp (*args, "-text"))
+ flags |= PKCS7_TEXT;
+ else if (!strcmp (*args, "-nointern"))
+ flags |= PKCS7_NOINTERN;
+ else if (!strcmp (*args, "-noverify"))
+ flags |= PKCS7_NOVERIFY;
+ else if (!strcmp (*args, "-nochain"))
+ flags |= PKCS7_NOCHAIN;
+ else if (!strcmp (*args, "-nocerts"))
+ flags |= PKCS7_NOCERTS;
+ else if (!strcmp (*args, "-noattr"))
+ flags |= PKCS7_NOATTR;
+ else if (!strcmp (*args, "-nodetach"))
+ flags &= ~PKCS7_DETACHED;
+ else if (!strcmp (*args, "-nosmimecap"))
+ flags |= PKCS7_NOSMIMECAP;
+ else if (!strcmp (*args, "-binary"))
+ flags |= PKCS7_BINARY;
+ else if (!strcmp (*args, "-nosigs"))
+ flags |= PKCS7_NOSIGS;
+ else if (!strcmp (*args, "-stream"))
+ indef = 1;
+ else if (!strcmp (*args, "-indef"))
+ indef = 1;
+ else if (!strcmp (*args, "-noindef"))
+ indef = 0;
+ else if (!strcmp (*args, "-nooldmime"))
+ flags |= PKCS7_NOOLDMIMETYPE;
+ else if (!strcmp (*args, "-crlfeol"))
+ flags |= PKCS7_CRLFEOL;
+ else if (!strcmp(*args,"-rand"))
+ {
+ if (!args[1])
+ goto argerr;
+ args++;
+ inrand = *args;
+ need_rand = 1;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (!strcmp(*args,"-engine"))
+ {
+ if (!args[1])
+ goto argerr;
+ engine = *++args;
+ }
+#endif
+ else if (!strcmp(*args,"-passin"))
+ {
+ if (!args[1])
+ goto argerr;
+ passargin = *++args;
+ }
+ else if (!strcmp (*args, "-to"))
+ {
+ if (!args[1])
+ goto argerr;
+ to = *++args;
+ }
+ else if (!strcmp (*args, "-from"))
+ {
+ if (!args[1])
+ goto argerr;
+ from = *++args;
+ }
+ else if (!strcmp (*args, "-subject"))
+ {
+ if (!args[1])
+ goto argerr;
+ subject = *++args;
+ }
+ else if (!strcmp (*args, "-signer"))
+ {
+ if (!args[1])
+ goto argerr;
+ /* If previous -signer argument add signer to list */
+
+ if (signerfile)
+ {
+ if (!sksigners)
+ sksigners = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(sksigners, signerfile);
+ if (!keyfile)
+ keyfile = signerfile;
+ if (!skkeys)
+ skkeys = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(skkeys, keyfile);
+ keyfile = NULL;
+ }
+ signerfile = *++args;
+ }
+ else if (!strcmp (*args, "-recip"))
+ {
+ if (!args[1])
+ goto argerr;
+ recipfile = *++args;
+ }
+ else if (!strcmp (*args, "-md"))
+ {
+ if (!args[1])
+ goto argerr;
+ sign_md = EVP_get_digestbyname(*++args);
+ if (sign_md == NULL)
+ {
+ BIO_printf(bio_err, "Unknown digest %s\n",
+ *args);
+ goto argerr;
+ }
+ }
+ else if (!strcmp (*args, "-inkey"))
+ {
+ if (!args[1])
+ goto argerr;
+ /* If previous -inkey arument add signer to list */
+ if (keyfile)
+ {
+ if (!signerfile)
+ {
+ BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+ goto argerr;
+ }
+ if (!sksigners)
+ sksigners = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(sksigners, signerfile);
+ signerfile = NULL;
+ if (!skkeys)
+ skkeys = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(skkeys, keyfile);
+ }
+ keyfile = *++args;
+ }
+ else if (!strcmp (*args, "-keyform"))
+ {
+ if (!args[1])
+ goto argerr;
+ keyform = str2fmt(*++args);
+ }
+ else if (!strcmp (*args, "-certfile"))
+ {
+ if (!args[1])
+ goto argerr;
+ certfile = *++args;
+ }
+ else if (!strcmp (*args, "-CAfile"))
+ {
+ if (!args[1])
+ goto argerr;
+ CAfile = *++args;
+ }
+ else if (!strcmp (*args, "-CApath"))
+ {
+ if (!args[1])
+ goto argerr;
+ CApath = *++args;
+ }
+ else if (!strcmp (*args, "-in"))
+ {
+ if (!args[1])
+ goto argerr;
+ infile = *++args;
+ }
+ else if (!strcmp (*args, "-inform"))
+ {
+ if (!args[1])
+ goto argerr;
+ informat = str2fmt(*++args);
+ }
+ else if (!strcmp (*args, "-outform"))
+ {
+ if (!args[1])
+ goto argerr;
+ outformat = str2fmt(*++args);
+ }
+ else if (!strcmp (*args, "-out"))
+ {
+ if (!args[1])
+ goto argerr;
+ outfile = *++args;
+ }
+ else if (!strcmp (*args, "-content"))
+ {
+ if (!args[1])
+ goto argerr;
+ contfile = *++args;
+ }
+ else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
+ continue;
+ else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
+ badarg = 1;
+ args++;
+ }
+
+ if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
+ {
+ BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
+ goto argerr;
+ }
+
+ if (operation & SMIME_SIGNERS)
+ {
+ /* Check to see if any final signer needs to be appended */
+ if (keyfile && !signerfile)
+ {
+ BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+ goto argerr;
+ }
+ if (signerfile)
+ {
+ if (!sksigners)
+ sksigners = sk_OPENSSL_STRING_new_null();
+ sk_OPENSSL_STRING_push(sksigners, signerfile);
+ if (!skkeys)
+ skkeys = sk_OPENSSL_STRING_new_null();
+ if (!keyfile)
+ keyfile = signerfile;
+ sk_OPENSSL_STRING_push(skkeys, keyfile);
+ }
+ if (!sksigners)
+ {
+ BIO_printf(bio_err, "No signer certificate specified\n");
+ badarg = 1;
+ }
+ signerfile = NULL;
+ keyfile = NULL;
+ need_rand = 1;
+ }
+ else if (operation == SMIME_DECRYPT)
+ {
+ if (!recipfile && !keyfile)
+ {
+ BIO_printf(bio_err, "No recipient certificate or key specified\n");
+ badarg = 1;
+ }
+ }
+ else if (operation == SMIME_ENCRYPT)
+ {
+ if (!*args)
+ {
+ BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
+ badarg = 1;
+ }
+ need_rand = 1;
+ }
+ else if (!operation)
+ badarg = 1;
+
+ if (badarg)
+ {
+ argerr:
+ BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n");
+ BIO_printf (bio_err, "where options are\n");
+ BIO_printf (bio_err, "-encrypt encrypt message\n");
+ BIO_printf (bio_err, "-decrypt decrypt encrypted message\n");
+ BIO_printf (bio_err, "-sign sign message\n");
+ BIO_printf (bio_err, "-verify verify signed message\n");
+ BIO_printf (bio_err, "-pk7out output PKCS#7 structure\n");
+#ifndef OPENSSL_NO_DES
+ BIO_printf (bio_err, "-des3 encrypt with triple DES\n");
+ BIO_printf (bio_err, "-des encrypt with DES\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+ BIO_printf (bio_err, "-seed encrypt with SEED\n");
+#endif
+#ifndef OPENSSL_NO_RC2
+ BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n");
+ BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n");
+ BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\n");
+#endif
+#ifndef OPENSSL_NO_AES
+ BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
+ BIO_printf (bio_err, " encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
+ BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n");
+#endif
+ BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n");
+ BIO_printf (bio_err, "-nosigs don't verify message signature\n");
+ BIO_printf (bio_err, "-noverify don't verify signers certificate\n");
+ BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n");
+ BIO_printf (bio_err, "-nodetach use opaque signing\n");
+ BIO_printf (bio_err, "-noattr don't include any signed attributes\n");
+ BIO_printf (bio_err, "-binary don't translate message to text\n");
+ BIO_printf (bio_err, "-certfile file other certificates file\n");
+ BIO_printf (bio_err, "-signer file signer certificate file\n");
+ BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n");
+ BIO_printf (bio_err, "-in file input file\n");
+ BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n");
+ BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n");
+ BIO_printf (bio_err, "-keyform arg input private key format (PEM or ENGINE)\n");
+ BIO_printf (bio_err, "-out file output file\n");
+ BIO_printf (bio_err, "-outform arg output format SMIME (default), PEM or DER\n");
+ BIO_printf (bio_err, "-content file supply or override content for detached signature\n");
+ BIO_printf (bio_err, "-to addr to address\n");
+ BIO_printf (bio_err, "-from ad from address\n");
+ BIO_printf (bio_err, "-subject s subject\n");
+ BIO_printf (bio_err, "-text include or delete text MIME headers\n");
+ BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
+ BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
+ BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n");
+ BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf (bio_err, "-passin arg input file pass phrase source\n");
+ BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err, " load the file (or the files in the directory) into\n");
+ BIO_printf(bio_err, " the random number generator\n");
+ BIO_printf (bio_err, "cert.pem recipient certificate(s) for encryption\n");
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+ {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+ if (need_rand)
+ {
+ app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
+ }
+
+ ret = 2;
+
+ if (!(operation & SMIME_SIGNERS))
+ flags &= ~PKCS7_DETACHED;
+
+ if (operation & SMIME_OP)
+ {
+ if (outformat == FORMAT_ASN1)
+ outmode = "wb";
+ }
+ else
+ {
+ if (flags & PKCS7_BINARY)
+ outmode = "wb";
+ }
+
+ if (operation & SMIME_IP)
+ {
+ if (informat == FORMAT_ASN1)
+ inmode = "rb";
+ }
+ else
+ {
+ if (flags & PKCS7_BINARY)
+ inmode = "rb";
+ }
+
+ if (operation == SMIME_ENCRYPT)
+ {
+ if (!cipher)
+ {
+#ifndef OPENSSL_NO_RC2
+ cipher = EVP_rc2_40_cbc();
+#else
+ BIO_printf(bio_err, "No cipher selected\n");
+ goto end;
+#endif
+ }
+ encerts = sk_X509_new_null();
+ while (*args)
+ {
+ if (!(cert = load_cert(bio_err,*args,FORMAT_PEM,
+ NULL, e, "recipient certificate file")))
+ {
+#if 0 /* An appropriate message is already printed */
+ BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args);
+#endif
+ goto end;
+ }
+ sk_X509_push(encerts, cert);
+ cert = NULL;
+ args++;
+ }
+ }
+
+ if (certfile)
+ {
+ if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
+ e, "certificate file")))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (recipfile && (operation == SMIME_DECRYPT))
+ {
+ if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
+ e, "recipient certificate file")))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (operation == SMIME_DECRYPT)
+ {
+ if (!keyfile)
+ keyfile = recipfile;
+ }
+ else if (operation == SMIME_SIGN)
+ {
+ if (!keyfile)
+ keyfile = signerfile;
+ }
+ else keyfile = NULL;
+
+ if (keyfile)
+ {
+ key = load_key(bio_err, keyfile, keyform, 0, passin, e,
+ "signing key file");
+ if (!key)
+ goto end;
+ }
+
+ if (infile)
+ {
+ if (!(in = BIO_new_file(infile, inmode)))
+ {
+ BIO_printf (bio_err,
+ "Can't open input file %s\n", infile);
+ goto end;
+ }
+ }
+ else
+ in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+ if (operation & SMIME_IP)
+ {
+ if (informat == FORMAT_SMIME)
+ p7 = SMIME_read_PKCS7(in, &indata);
+ else if (informat == FORMAT_PEM)
+ p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
+ else if (informat == FORMAT_ASN1)
+ p7 = d2i_PKCS7_bio(in, NULL);
+ else
+ {
+ BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
+ goto end;
+ }
+
+ if (!p7)
+ {
+ BIO_printf(bio_err, "Error reading S/MIME message\n");
+ goto end;
+ }
+ if (contfile)
+ {
+ BIO_free(indata);
+ if (!(indata = BIO_new_file(contfile, "rb")))
+ {
+ BIO_printf(bio_err, "Can't read content file %s\n", contfile);
+ goto end;
+ }
+ }
+ }
+
+ if (outfile)
+ {
+ if (!(out = BIO_new_file(outfile, outmode)))
+ {
+ BIO_printf (bio_err,
+ "Can't open output file %s\n", outfile);
+ goto end;
+ }
+ }
+ else
+ {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+
+ if (operation == SMIME_VERIFY)
+ {
+ if (!(store = setup_verify(bio_err, CAfile, CApath)))
+ goto end;
+ X509_STORE_set_verify_cb(store, smime_cb);
+ if (vpm)
+ X509_STORE_set1_param(store, vpm);
+ }
+
+
+ ret = 3;
+
+ if (operation == SMIME_ENCRYPT)
+ {
+ if (indef)
+ flags |= PKCS7_STREAM;
+ p7 = PKCS7_encrypt(encerts, in, cipher, flags);
+ }
+ else if (operation & SMIME_SIGNERS)
+ {
+ int i;
+ /* If detached data content we only enable streaming if
+ * S/MIME output format.
+ */
+ if (operation == SMIME_SIGN)
+ {
+ if (flags & PKCS7_DETACHED)
+ {
+ if (outformat == FORMAT_SMIME)
+ flags |= PKCS7_STREAM;
+ }
+ else if (indef)
+ flags |= PKCS7_STREAM;
+ flags |= PKCS7_PARTIAL;
+ p7 = PKCS7_sign(NULL, NULL, other, in, flags);
+ if (!p7)
+ goto end;
+ }
+ else
+ flags |= PKCS7_REUSE_DIGEST;
+ for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++)
+ {
+ signerfile = sk_OPENSSL_STRING_value(sksigners, i);
+ keyfile = sk_OPENSSL_STRING_value(skkeys, i);
+ signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
+ e, "signer certificate");
+ if (!signer)
+ goto end;
+ key = load_key(bio_err, keyfile, keyform, 0, passin, e,
+ "signing key file");
+ if (!key)
+ goto end;
+ if (!PKCS7_sign_add_signer(p7, signer, key,
+ sign_md, flags))
+ goto end;
+ X509_free(signer);
+ signer = NULL;
+ EVP_PKEY_free(key);
+ key = NULL;
+ }
+ /* If not streaming or resigning finalize structure */
+ if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM))
+ {
+ if (!PKCS7_final(p7, in, flags))
+ goto end;
+ }
+ }
+
+ if (!p7)
+ {
+ BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
+ goto end;
+ }
+
+ ret = 4;
+ if (operation == SMIME_DECRYPT)
+ {
+ if (!PKCS7_decrypt(p7, key, recip, out, flags))
+ {
+ BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
+ goto end;
+ }
+ }
+ else if (operation == SMIME_VERIFY)
+ {
+ STACK_OF(X509) *signers;
+ if (PKCS7_verify(p7, other, store, indata, out, flags))
+ BIO_printf(bio_err, "Verification successful\n");
+ else
+ {
+ BIO_printf(bio_err, "Verification failure\n");
+ goto end;
+ }
+ signers = PKCS7_get0_signers(p7, other, flags);
+ if (!save_certs(signerfile, signers))
+ {
+ BIO_printf(bio_err, "Error writing signers to %s\n",
+ signerfile);
+ ret = 5;
+ goto end;
+ }
+ sk_X509_free(signers);
+ }
+ else if (operation == SMIME_PK7OUT)
+ PEM_write_bio_PKCS7(out, p7);
+ else
+ {
+ if (to)
+ BIO_printf(out, "To: %s\n", to);
+ if (from)
+ BIO_printf(out, "From: %s\n", from);
+ if (subject)
+ BIO_printf(out, "Subject: %s\n", subject);
+ if (outformat == FORMAT_SMIME)
+ {
+ if (operation == SMIME_RESIGN)
+ SMIME_write_PKCS7(out, p7, indata, flags);
+ else
+ SMIME_write_PKCS7(out, p7, in, flags);
+ }
+ else if (outformat == FORMAT_PEM)
+ PEM_write_bio_PKCS7_stream(out, p7, in, flags);
+ else if (outformat == FORMAT_ASN1)
+ i2d_PKCS7_bio_stream(out,p7, in, flags);
+ else
+ {
+ BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
+ goto end;
+ }
+ }
+ ret = 0;
+end:
+ if (need_rand)
+ app_RAND_write_file(NULL, bio_err);
+ if (ret) ERR_print_errors(bio_err);
+ sk_X509_pop_free(encerts, X509_free);
+ sk_X509_pop_free(other, X509_free);
+ if (vpm)
+ X509_VERIFY_PARAM_free(vpm);
+ if (sksigners)
+ sk_OPENSSL_STRING_free(sksigners);
+ if (skkeys)
+ sk_OPENSSL_STRING_free(skkeys);
+ X509_STORE_free(store);
+ X509_free(cert);
+ X509_free(recip);
+ X509_free(signer);
+ EVP_PKEY_free(key);
+ PKCS7_free(p7);
+ BIO_free(in);
+ BIO_free(indata);
+ BIO_free_all(out);
+ if (passin) OPENSSL_free(passin);
+ return (ret);
+}
+
+static int save_certs(char *signerfile, STACK_OF(X509) *signers)
+ {
+ int i;
+ BIO *tmp;
+ if (!signerfile)
+ return 1;
+ tmp = BIO_new_file(signerfile, "w");
+ if (!tmp) return 0;
+ for(i = 0; i < sk_X509_num(signers); i++)
+ PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
+ BIO_free(tmp);
+ return 1;
+ }
+
+
+/* Minimal callback just to output policy info (if any) */
+
+static int smime_cb(int ok, X509_STORE_CTX *ctx)
+ {
+ int error;
+
+ error = X509_STORE_CTX_get_error(ctx);
+
+ if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
+ && ((error != X509_V_OK) || (ok != 2)))
+ return ok;
+
+ policies_print(NULL, ctx);
+
+ return ok;
+
+ }
diff --git a/deps/openssl/openssl/apps/speed.c b/deps/openssl/openssl/apps/speed.c
new file mode 100644
index 000000000..9886ca376
--- /dev/null
+++ b/deps/openssl/openssl/apps/speed.c
@@ -0,0 +1,2842 @@
+/* apps/speed.c -*- mode:C; c-file-style: "eay" -*- */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The ECDH and ECDSA speed test software is originally written by
+ * Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+
+/* most of this code has been pilfered from my libdes speed.c program */
+
+#ifndef OPENSSL_NO_SPEED
+
+#undef SECONDS
+#define SECONDS 3
+#define RSA_SECONDS 10
+#define DSA_SECONDS 10
+#define ECDSA_SECONDS 10
+#define ECDH_SECONDS 10
+
+/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */
+
+#undef PROG
+#define PROG speed_main
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <string.h>
+#include <math.h>
+#include "apps.h"
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#if !defined(OPENSSL_SYS_MSDOS)
+#include OPENSSL_UNISTD
+#endif
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+#include <windows.h>
+# if defined(__CYGWIN__) && !defined(_WIN32)
+ /* <windows.h> should define _WIN32, which normally is mutually
+ * exclusive with __CYGWIN__, but if it didn't... */
+# define _WIN32
+ /* this is done because Cygwin alarm() fails sometimes. */
+# endif
+#endif
+
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DES
+#include <openssl/des.h>
+#endif
+#ifndef OPENSSL_NO_AES
+#include <openssl/aes.h>
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+#include <openssl/camellia.h>
+#endif
+#ifndef OPENSSL_NO_MD2
+#include <openssl/md2.h>
+#endif
+#ifndef OPENSSL_NO_MDC2
+#include <openssl/mdc2.h>
+#endif
+#ifndef OPENSSL_NO_MD4
+#include <openssl/md4.h>
+#endif
+#ifndef OPENSSL_NO_MD5
+#include <openssl/md5.h>
+#endif
+#ifndef OPENSSL_NO_HMAC
+#include <openssl/hmac.h>
+#endif
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_SHA
+#include <openssl/sha.h>
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+#include <openssl/ripemd.h>
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+#include <openssl/whrlpool.h>
+#endif
+#ifndef OPENSSL_NO_RC4
+#include <openssl/rc4.h>
+#endif
+#ifndef OPENSSL_NO_RC5
+#include <openssl/rc5.h>
+#endif
+#ifndef OPENSSL_NO_RC2
+#include <openssl/rc2.h>
+#endif
+#ifndef OPENSSL_NO_IDEA
+#include <openssl/idea.h>
+#endif
+#ifndef OPENSSL_NO_SEED
+#include <openssl/seed.h>
+#endif
+#ifndef OPENSSL_NO_BF
+#include <openssl/blowfish.h>
+#endif
+#ifndef OPENSSL_NO_CAST
+#include <openssl/cast.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#include "./testrsa.h"
+#endif
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#include "./testdsa.h"
+#endif
+#ifndef OPENSSL_NO_ECDSA
+#include <openssl/ecdsa.h>
+#endif
+#ifndef OPENSSL_NO_ECDH
+#include <openssl/ecdh.h>
+#endif
+#include <openssl/modes.h>
+
+#ifdef OPENSSL_FIPS
+#ifdef OPENSSL_DOING_MAKEDEPEND
+#undef AES_set_encrypt_key
+#undef AES_set_decrypt_key
+#undef DES_set_key_unchecked
+#endif
+#define BF_set_key private_BF_set_key
+#define CAST_set_key private_CAST_set_key
+#define idea_set_encrypt_key private_idea_set_encrypt_key
+#define SEED_set_key private_SEED_set_key
+#define RC2_set_key private_RC2_set_key
+#define RC4_set_key private_RC4_set_key
+#define DES_set_key_unchecked private_DES_set_key_unchecked
+#define AES_set_encrypt_key private_AES_set_encrypt_key
+#define AES_set_decrypt_key private_AES_set_decrypt_key
+#define Camellia_set_key private_Camellia_set_key
+#endif
+
+#ifndef HAVE_FORK
+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE)
+# define HAVE_FORK 0
+# else
+# define HAVE_FORK 1
+# endif
+#endif
+
+#if HAVE_FORK
+#undef NO_FORK
+#else
+#define NO_FORK
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE ((long)1024*8+1)
+int run=0;
+
+static int mr=0;
+static int usertime=1;
+
+static double Time_F(int s);
+static void print_message(const char *s,long num,int length);
+static void pkey_print_message(const char *str, const char *str2,
+ long num, int bits, int sec);
+static void print_result(int alg,int run_no,int count,double time_used);
+#ifndef NO_FORK
+static int do_multi(int multi);
+#endif
+
+#define ALGOR_NUM 30
+#define SIZE_NUM 5
+#define RSA_NUM 4
+#define DSA_NUM 3
+
+#define EC_NUM 16
+#define MAX_ECDH_SIZE 256
+
+static const char *names[ALGOR_NUM]={
+ "md2","mdc2","md4","md5","hmac(md5)","sha1","rmd160","rc4",
+ "des cbc","des ede3","idea cbc","seed cbc",
+ "rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc",
+ "aes-128 cbc","aes-192 cbc","aes-256 cbc",
+ "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc",
+ "evp","sha256","sha512","whirlpool",
+ "aes-128 ige","aes-192 ige","aes-256 ige","ghash" };
+static double results[ALGOR_NUM][SIZE_NUM];
+static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
+#ifndef OPENSSL_NO_RSA
+static double rsa_results[RSA_NUM][2];
+#endif
+#ifndef OPENSSL_NO_DSA
+static double dsa_results[DSA_NUM][2];
+#endif
+#ifndef OPENSSL_NO_ECDSA
+static double ecdsa_results[EC_NUM][2];
+#endif
+#ifndef OPENSSL_NO_ECDH
+static double ecdh_results[EC_NUM][1];
+#endif
+
+#if defined(OPENSSL_NO_DSA) && !(defined(OPENSSL_NO_ECDSA) && defined(OPENSSL_NO_ECDH))
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+static int rnd_fake = 0;
+#endif
+
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+static SIGRETTYPE sig_done(int sig);
+static SIGRETTYPE sig_done(int sig)
+ {
+ signal(SIGALRM,sig_done);
+ run=0;
+#ifdef LINT
+ sig=sig;
+#endif
+ }
+#endif
+
+#define START 0
+#define STOP 1
+
+#if defined(_WIN32)
+
+#if !defined(SIGALRM)
+# define SIGALRM
+#endif
+static unsigned int lapse,schlock;
+static void alarm_win32(unsigned int secs) { lapse = secs*1000; }
+#define alarm alarm_win32
+
+static DWORD WINAPI sleepy(VOID *arg)
+ {
+ schlock = 1;
+ Sleep(lapse);
+ run = 0;
+ return 0;
+ }
+
+static double Time_F(int s)
+ {
+ if (s == START)
+ {
+ HANDLE thr;
+ schlock = 0;
+ thr = CreateThread(NULL,4096,sleepy,NULL,0,NULL);
+ if (thr==NULL)
+ {
+ DWORD ret=GetLastError();
+ BIO_printf(bio_err,"unable to CreateThread (%d)",ret);
+ ExitProcess(ret);
+ }
+ CloseHandle(thr); /* detach the thread */
+ while (!schlock) Sleep(0); /* scheduler spinlock */
+ }
+
+ return app_tminterval(s,usertime);
+ }
+#else
+
+static double Time_F(int s)
+ {
+ return app_tminterval(s,usertime);
+ }
+#endif
+
+
+#ifndef OPENSSL_NO_ECDH
+static const int KDF1_SHA1_len = 20;
+static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
+ {
+#ifndef OPENSSL_NO_SHA
+ if (*outlen < SHA_DIGEST_LENGTH)
+ return NULL;
+ else
+ *outlen = SHA_DIGEST_LENGTH;
+ return SHA1(in, inlen, out);
+#else
+ return NULL;
+#endif /* OPENSSL_NO_SHA */
+ }
+#endif /* OPENSSL_NO_ECDH */
+
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ unsigned char *buf=NULL,*buf2=NULL;
+ int mret=1;
+ long count=0,save_count=0;
+ int i,j,k;
+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA)
+ long rsa_count;
+#endif
+#ifndef OPENSSL_NO_RSA
+ unsigned rsa_num;
+#endif
+ unsigned char md[EVP_MAX_MD_SIZE];
+#ifndef OPENSSL_NO_MD2
+ unsigned char md2[MD2_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_MDC2
+ unsigned char mdc2[MDC2_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_MD4
+ unsigned char md4[MD4_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_MD5
+ unsigned char md5[MD5_DIGEST_LENGTH];
+ unsigned char hmac[MD5_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_SHA
+ unsigned char sha[SHA_DIGEST_LENGTH];
+#ifndef OPENSSL_NO_SHA256
+ unsigned char sha256[SHA256_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_SHA512
+ unsigned char sha512[SHA512_DIGEST_LENGTH];
+#endif
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+ unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+ unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_RC4
+ RC4_KEY rc4_ks;
+#endif
+#ifndef OPENSSL_NO_RC5
+ RC5_32_KEY rc5_ks;
+#endif
+#ifndef OPENSSL_NO_RC2
+ RC2_KEY rc2_ks;
+#endif
+#ifndef OPENSSL_NO_IDEA
+ IDEA_KEY_SCHEDULE idea_ks;
+#endif
+#ifndef OPENSSL_NO_SEED
+ SEED_KEY_SCHEDULE seed_ks;
+#endif
+#ifndef OPENSSL_NO_BF
+ BF_KEY bf_ks;
+#endif
+#ifndef OPENSSL_NO_CAST
+ CAST_KEY cast_ks;
+#endif
+ static const unsigned char key16[16]=
+ {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+ 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
+#ifndef OPENSSL_NO_AES
+ static const unsigned char key24[24]=
+ {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+ 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
+ 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+ static const unsigned char key32[32]=
+ {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+ 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
+ 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,
+ 0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56};
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ static const unsigned char ckey24[24]=
+ {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+ 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
+ 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+ static const unsigned char ckey32[32]=
+ {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+ 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
+ 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,
+ 0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56};
+#endif
+#ifndef OPENSSL_NO_AES
+#define MAX_BLOCK_SIZE 128
+#else
+#define MAX_BLOCK_SIZE 64
+#endif
+ unsigned char DES_iv[8];
+ unsigned char iv[2*MAX_BLOCK_SIZE/8];
+#ifndef OPENSSL_NO_DES
+ static DES_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
+ static DES_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
+ static DES_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+ DES_key_schedule sch;
+ DES_key_schedule sch2;
+ DES_key_schedule sch3;
+#endif
+#ifndef OPENSSL_NO_AES
+ AES_KEY aes_ks1, aes_ks2, aes_ks3;
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3;
+#endif
+#define D_MD2 0
+#define D_MDC2 1
+#define D_MD4 2
+#define D_MD5 3
+#define D_HMAC 4
+#define D_SHA1 5
+#define D_RMD160 6
+#define D_RC4 7
+#define D_CBC_DES 8
+#define D_EDE3_DES 9
+#define D_CBC_IDEA 10
+#define D_CBC_SEED 11
+#define D_CBC_RC2 12
+#define D_CBC_RC5 13
+#define D_CBC_BF 14
+#define D_CBC_CAST 15
+#define D_CBC_128_AES 16
+#define D_CBC_192_AES 17
+#define D_CBC_256_AES 18
+#define D_CBC_128_CML 19
+#define D_CBC_192_CML 20
+#define D_CBC_256_CML 21
+#define D_EVP 22
+#define D_SHA256 23
+#define D_SHA512 24
+#define D_WHIRLPOOL 25
+#define D_IGE_128_AES 26
+#define D_IGE_192_AES 27
+#define D_IGE_256_AES 28
+#define D_GHASH 29
+ double d=0.0;
+ long c[ALGOR_NUM][SIZE_NUM];
+#define R_DSA_512 0
+#define R_DSA_1024 1
+#define R_DSA_2048 2
+#define R_RSA_512 0
+#define R_RSA_1024 1
+#define R_RSA_2048 2
+#define R_RSA_4096 3
+
+#define R_EC_P160 0
+#define R_EC_P192 1
+#define R_EC_P224 2
+#define R_EC_P256 3
+#define R_EC_P384 4
+#define R_EC_P521 5
+#define R_EC_K163 6
+#define R_EC_K233 7
+#define R_EC_K283 8
+#define R_EC_K409 9
+#define R_EC_K571 10
+#define R_EC_B163 11
+#define R_EC_B233 12
+#define R_EC_B283 13
+#define R_EC_B409 14
+#define R_EC_B571 15
+
+#ifndef OPENSSL_NO_RSA
+ RSA *rsa_key[RSA_NUM];
+ long rsa_c[RSA_NUM][2];
+ static unsigned int rsa_bits[RSA_NUM]={512,1024,2048,4096};
+ static unsigned char *rsa_data[RSA_NUM]=
+ {test512,test1024,test2048,test4096};
+ static int rsa_data_length[RSA_NUM]={
+ sizeof(test512),sizeof(test1024),
+ sizeof(test2048),sizeof(test4096)};
+#endif
+#ifndef OPENSSL_NO_DSA
+ DSA *dsa_key[DSA_NUM];
+ long dsa_c[DSA_NUM][2];
+ static unsigned int dsa_bits[DSA_NUM]={512,1024,2048};
+#endif
+#ifndef OPENSSL_NO_EC
+ /* We only test over the following curves as they are representative,
+ * To add tests over more curves, simply add the curve NID
+ * and curve name to the following arrays and increase the
+ * EC_NUM value accordingly.
+ */
+ static unsigned int test_curves[EC_NUM] =
+ {
+ /* Prime Curves */
+ NID_secp160r1,
+ NID_X9_62_prime192v1,
+ NID_secp224r1,
+ NID_X9_62_prime256v1,
+ NID_secp384r1,
+ NID_secp521r1,
+ /* Binary Curves */
+ NID_sect163k1,
+ NID_sect233k1,
+ NID_sect283k1,
+ NID_sect409k1,
+ NID_sect571k1,
+ NID_sect163r2,
+ NID_sect233r1,
+ NID_sect283r1,
+ NID_sect409r1,
+ NID_sect571r1
+ };
+ static const char * test_curves_names[EC_NUM] =
+ {
+ /* Prime Curves */
+ "secp160r1",
+ "nistp192",
+ "nistp224",
+ "nistp256",
+ "nistp384",
+ "nistp521",
+ /* Binary Curves */
+ "nistk163",
+ "nistk233",
+ "nistk283",
+ "nistk409",
+ "nistk571",
+ "nistb163",
+ "nistb233",
+ "nistb283",
+ "nistb409",
+ "nistb571"
+ };
+ static int test_curves_bits[EC_NUM] =
+ {
+ 160, 192, 224, 256, 384, 521,
+ 163, 233, 283, 409, 571,
+ 163, 233, 283, 409, 571
+ };
+
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+ unsigned char ecdsasig[256];
+ unsigned int ecdsasiglen;
+ EC_KEY *ecdsa[EC_NUM];
+ long ecdsa_c[EC_NUM][2];
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+ EC_KEY *ecdh_a[EC_NUM], *ecdh_b[EC_NUM];
+ unsigned char secret_a[MAX_ECDH_SIZE], secret_b[MAX_ECDH_SIZE];
+ int secret_size_a, secret_size_b;
+ int ecdh_checks = 0;
+ int secret_idx = 0;
+ long ecdh_c[EC_NUM][2];
+#endif
+
+ int rsa_doit[RSA_NUM];
+ int dsa_doit[DSA_NUM];
+#ifndef OPENSSL_NO_ECDSA
+ int ecdsa_doit[EC_NUM];
+#endif
+#ifndef OPENSSL_NO_ECDH
+ int ecdh_doit[EC_NUM];
+#endif
+ int doit[ALGOR_NUM];
+ int pr_header=0;
+ const EVP_CIPHER *evp_cipher=NULL;
+ const EVP_MD *evp_md=NULL;
+ int decrypt=0;
+#ifndef NO_FORK
+ int multi=0;
+#endif
+
+#ifndef TIMES
+ usertime=-1;
+#endif
+
+ apps_startup();
+ memset(results, 0, sizeof(results));
+#ifndef OPENSSL_NO_DSA
+ memset(dsa_key,0,sizeof(dsa_key));
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ for (i=0; i<EC_NUM; i++) ecdsa[i] = NULL;
+#endif
+#ifndef OPENSSL_NO_ECDH
+ for (i=0; i<EC_NUM; i++)
+ {
+ ecdh_a[i] = NULL;
+ ecdh_b[i] = NULL;
+ }
+#endif
+
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+#ifndef OPENSSL_NO_RSA
+ memset(rsa_key,0,sizeof(rsa_key));
+ for (i=0; i<RSA_NUM; i++)
+ rsa_key[i]=NULL;
+#endif
+
+ if ((buf=(unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL)
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ goto end;
+ }
+ if ((buf2=(unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL)
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ goto end;
+ }
+
+ memset(c,0,sizeof(c));
+ memset(DES_iv,0,sizeof(DES_iv));
+ memset(iv,0,sizeof(iv));
+
+ for (i=0; i<ALGOR_NUM; i++)
+ doit[i]=0;
+ for (i=0; i<RSA_NUM; i++)
+ rsa_doit[i]=0;
+ for (i=0; i<DSA_NUM; i++)
+ dsa_doit[i]=0;
+#ifndef OPENSSL_NO_ECDSA
+ for (i=0; i<EC_NUM; i++)
+ ecdsa_doit[i]=0;
+#endif
+#ifndef OPENSSL_NO_ECDH
+ for (i=0; i<EC_NUM; i++)
+ ecdh_doit[i]=0;
+#endif
+
+
+ j=0;
+ argc--;
+ argv++;
+ while (argc)
+ {
+ if ((argc > 0) && (strcmp(*argv,"-elapsed") == 0))
+ {
+ usertime = 0;
+ j--; /* Otherwise, -elapsed gets confused with
+ an algorithm. */
+ }
+ else if ((argc > 0) && (strcmp(*argv,"-evp") == 0))
+ {
+ argc--;
+ argv++;
+ if(argc == 0)
+ {
+ BIO_printf(bio_err,"no EVP given\n");
+ goto end;
+ }
+ evp_cipher=EVP_get_cipherbyname(*argv);
+ if(!evp_cipher)
+ {
+ evp_md=EVP_get_digestbyname(*argv);
+ }
+ if(!evp_cipher && !evp_md)
+ {
+ BIO_printf(bio_err,"%s is an unknown cipher or digest\n",*argv);
+ goto end;
+ }
+ doit[D_EVP]=1;
+ }
+ else if (argc > 0 && !strcmp(*argv,"-decrypt"))
+ {
+ decrypt=1;
+ j--; /* Otherwise, -elapsed gets confused with
+ an algorithm. */
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if ((argc > 0) && (strcmp(*argv,"-engine") == 0))
+ {
+ argc--;
+ argv++;
+ if(argc == 0)
+ {
+ BIO_printf(bio_err,"no engine given\n");
+ goto end;
+ }
+ setup_engine(bio_err, *argv, 0);
+ /* j will be increased again further down. We just
+ don't want speed to confuse an engine with an
+ algorithm, especially when none is given (which
+ means all of them should be run) */
+ j--;
+ }
+#endif
+#ifndef NO_FORK
+ else if ((argc > 0) && (strcmp(*argv,"-multi") == 0))
+ {
+ argc--;
+ argv++;
+ if(argc == 0)
+ {
+ BIO_printf(bio_err,"no multi count given\n");
+ goto end;
+ }
+ multi=atoi(argv[0]);
+ if(multi <= 0)
+ {
+ BIO_printf(bio_err,"bad multi count\n");
+ goto end;
+ }
+ j--; /* Otherwise, -mr gets confused with
+ an algorithm. */
+ }
+#endif
+ else if (argc > 0 && !strcmp(*argv,"-mr"))
+ {
+ mr=1;
+ j--; /* Otherwise, -mr gets confused with
+ an algorithm. */
+ }
+ else
+#ifndef OPENSSL_NO_MD2
+ if (strcmp(*argv,"md2") == 0) doit[D_MD2]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_MDC2
+ if (strcmp(*argv,"mdc2") == 0) doit[D_MDC2]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_MD4
+ if (strcmp(*argv,"md4") == 0) doit[D_MD4]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_MD5
+ if (strcmp(*argv,"md5") == 0) doit[D_MD5]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_MD5
+ if (strcmp(*argv,"hmac") == 0) doit[D_HMAC]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_SHA
+ if (strcmp(*argv,"sha1") == 0) doit[D_SHA1]=1;
+ else
+ if (strcmp(*argv,"sha") == 0) doit[D_SHA1]=1,
+ doit[D_SHA256]=1,
+ doit[D_SHA512]=1;
+ else
+#ifndef OPENSSL_NO_SHA256
+ if (strcmp(*argv,"sha256") == 0) doit[D_SHA256]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_SHA512
+ if (strcmp(*argv,"sha512") == 0) doit[D_SHA512]=1;
+ else
+#endif
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+ if (strcmp(*argv,"whirlpool") == 0) doit[D_WHIRLPOOL]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+ if (strcmp(*argv,"ripemd") == 0) doit[D_RMD160]=1;
+ else
+ if (strcmp(*argv,"rmd160") == 0) doit[D_RMD160]=1;
+ else
+ if (strcmp(*argv,"ripemd160") == 0) doit[D_RMD160]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_RC4
+ if (strcmp(*argv,"rc4") == 0) doit[D_RC4]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_DES
+ if (strcmp(*argv,"des-cbc") == 0) doit[D_CBC_DES]=1;
+ else if (strcmp(*argv,"des-ede3") == 0) doit[D_EDE3_DES]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_AES
+ if (strcmp(*argv,"aes-128-cbc") == 0) doit[D_CBC_128_AES]=1;
+ else if (strcmp(*argv,"aes-192-cbc") == 0) doit[D_CBC_192_AES]=1;
+ else if (strcmp(*argv,"aes-256-cbc") == 0) doit[D_CBC_256_AES]=1;
+ else if (strcmp(*argv,"aes-128-ige") == 0) doit[D_IGE_128_AES]=1;
+ else if (strcmp(*argv,"aes-192-ige") == 0) doit[D_IGE_192_AES]=1;
+ else if (strcmp(*argv,"aes-256-ige") == 0) doit[D_IGE_256_AES]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ if (strcmp(*argv,"camellia-128-cbc") == 0) doit[D_CBC_128_CML]=1;
+ else if (strcmp(*argv,"camellia-192-cbc") == 0) doit[D_CBC_192_CML]=1;
+ else if (strcmp(*argv,"camellia-256-cbc") == 0) doit[D_CBC_256_CML]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_RSA
+#if 0 /* was: #ifdef RSAref */
+ if (strcmp(*argv,"rsaref") == 0)
+ {
+ RSA_set_default_openssl_method(RSA_PKCS1_RSAref());
+ j--;
+ }
+ else
+#endif
+#ifndef RSA_NULL
+ if (strcmp(*argv,"openssl") == 0)
+ {
+ RSA_set_default_method(RSA_PKCS1_SSLeay());
+ j--;
+ }
+ else
+#endif
+#endif /* !OPENSSL_NO_RSA */
+ if (strcmp(*argv,"dsa512") == 0) dsa_doit[R_DSA_512]=2;
+ else if (strcmp(*argv,"dsa1024") == 0) dsa_doit[R_DSA_1024]=2;
+ else if (strcmp(*argv,"dsa2048") == 0) dsa_doit[R_DSA_2048]=2;
+ else if (strcmp(*argv,"rsa512") == 0) rsa_doit[R_RSA_512]=2;
+ else if (strcmp(*argv,"rsa1024") == 0) rsa_doit[R_RSA_1024]=2;
+ else if (strcmp(*argv,"rsa2048") == 0) rsa_doit[R_RSA_2048]=2;
+ else if (strcmp(*argv,"rsa4096") == 0) rsa_doit[R_RSA_4096]=2;
+ else
+#ifndef OPENSSL_NO_RC2
+ if (strcmp(*argv,"rc2-cbc") == 0) doit[D_CBC_RC2]=1;
+ else if (strcmp(*argv,"rc2") == 0) doit[D_CBC_RC2]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_RC5
+ if (strcmp(*argv,"rc5-cbc") == 0) doit[D_CBC_RC5]=1;
+ else if (strcmp(*argv,"rc5") == 0) doit[D_CBC_RC5]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_IDEA
+ if (strcmp(*argv,"idea-cbc") == 0) doit[D_CBC_IDEA]=1;
+ else if (strcmp(*argv,"idea") == 0) doit[D_CBC_IDEA]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_SEED
+ if (strcmp(*argv,"seed-cbc") == 0) doit[D_CBC_SEED]=1;
+ else if (strcmp(*argv,"seed") == 0) doit[D_CBC_SEED]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_BF
+ if (strcmp(*argv,"bf-cbc") == 0) doit[D_CBC_BF]=1;
+ else if (strcmp(*argv,"blowfish") == 0) doit[D_CBC_BF]=1;
+ else if (strcmp(*argv,"bf") == 0) doit[D_CBC_BF]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_CAST
+ if (strcmp(*argv,"cast-cbc") == 0) doit[D_CBC_CAST]=1;
+ else if (strcmp(*argv,"cast") == 0) doit[D_CBC_CAST]=1;
+ else if (strcmp(*argv,"cast5") == 0) doit[D_CBC_CAST]=1;
+ else
+#endif
+#ifndef OPENSSL_NO_DES
+ if (strcmp(*argv,"des") == 0)
+ {
+ doit[D_CBC_DES]=1;
+ doit[D_EDE3_DES]=1;
+ }
+ else
+#endif
+#ifndef OPENSSL_NO_AES
+ if (strcmp(*argv,"aes") == 0)
+ {
+ doit[D_CBC_128_AES]=1;
+ doit[D_CBC_192_AES]=1;
+ doit[D_CBC_256_AES]=1;
+ }
+ else if (strcmp(*argv,"ghash") == 0)
+ {
+ doit[D_GHASH]=1;
+ }
+ else
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ if (strcmp(*argv,"camellia") == 0)
+ {
+ doit[D_CBC_128_CML]=1;
+ doit[D_CBC_192_CML]=1;
+ doit[D_CBC_256_CML]=1;
+ }
+ else
+#endif
+#ifndef OPENSSL_NO_RSA
+ if (strcmp(*argv,"rsa") == 0)
+ {
+ rsa_doit[R_RSA_512]=1;
+ rsa_doit[R_RSA_1024]=1;
+ rsa_doit[R_RSA_2048]=1;
+ rsa_doit[R_RSA_4096]=1;
+ }
+ else
+#endif
+#ifndef OPENSSL_NO_DSA
+ if (strcmp(*argv,"dsa") == 0)
+ {
+ dsa_doit[R_DSA_512]=1;
+ dsa_doit[R_DSA_1024]=1;
+ dsa_doit[R_DSA_2048]=1;
+ }
+ else
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ if (strcmp(*argv,"ecdsap160") == 0) ecdsa_doit[R_EC_P160]=2;
+ else if (strcmp(*argv,"ecdsap192") == 0) ecdsa_doit[R_EC_P192]=2;
+ else if (strcmp(*argv,"ecdsap224") == 0) ecdsa_doit[R_EC_P224]=2;
+ else if (strcmp(*argv,"ecdsap256") == 0) ecdsa_doit[R_EC_P256]=2;
+ else if (strcmp(*argv,"ecdsap384") == 0) ecdsa_doit[R_EC_P384]=2;
+ else if (strcmp(*argv,"ecdsap521") == 0) ecdsa_doit[R_EC_P521]=2;
+ else if (strcmp(*argv,"ecdsak163") == 0) ecdsa_doit[R_EC_K163]=2;
+ else if (strcmp(*argv,"ecdsak233") == 0) ecdsa_doit[R_EC_K233]=2;
+ else if (strcmp(*argv,"ecdsak283") == 0) ecdsa_doit[R_EC_K283]=2;
+ else if (strcmp(*argv,"ecdsak409") == 0) ecdsa_doit[R_EC_K409]=2;
+ else if (strcmp(*argv,"ecdsak571") == 0) ecdsa_doit[R_EC_K571]=2;
+ else if (strcmp(*argv,"ecdsab163") == 0) ecdsa_doit[R_EC_B163]=2;
+ else if (strcmp(*argv,"ecdsab233") == 0) ecdsa_doit[R_EC_B233]=2;
+ else if (strcmp(*argv,"ecdsab283") == 0) ecdsa_doit[R_EC_B283]=2;
+ else if (strcmp(*argv,"ecdsab409") == 0) ecdsa_doit[R_EC_B409]=2;
+ else if (strcmp(*argv,"ecdsab571") == 0) ecdsa_doit[R_EC_B571]=2;
+ else if (strcmp(*argv,"ecdsa") == 0)
+ {
+ for (i=0; i < EC_NUM; i++)
+ ecdsa_doit[i]=1;
+ }
+ else
+#endif
+#ifndef OPENSSL_NO_ECDH
+ if (strcmp(*argv,"ecdhp160") == 0) ecdh_doit[R_EC_P160]=2;
+ else if (strcmp(*argv,"ecdhp192") == 0) ecdh_doit[R_EC_P192]=2;
+ else if (strcmp(*argv,"ecdhp224") == 0) ecdh_doit[R_EC_P224]=2;
+ else if (strcmp(*argv,"ecdhp256") == 0) ecdh_doit[R_EC_P256]=2;
+ else if (strcmp(*argv,"ecdhp384") == 0) ecdh_doit[R_EC_P384]=2;
+ else if (strcmp(*argv,"ecdhp521") == 0) ecdh_doit[R_EC_P521]=2;
+ else if (strcmp(*argv,"ecdhk163") == 0) ecdh_doit[R_EC_K163]=2;
+ else if (strcmp(*argv,"ecdhk233") == 0) ecdh_doit[R_EC_K233]=2;
+ else if (strcmp(*argv,"ecdhk283") == 0) ecdh_doit[R_EC_K283]=2;
+ else if (strcmp(*argv,"ecdhk409") == 0) ecdh_doit[R_EC_K409]=2;
+ else if (strcmp(*argv,"ecdhk571") == 0) ecdh_doit[R_EC_K571]=2;
+ else if (strcmp(*argv,"ecdhb163") == 0) ecdh_doit[R_EC_B163]=2;
+ else if (strcmp(*argv,"ecdhb233") == 0) ecdh_doit[R_EC_B233]=2;
+ else if (strcmp(*argv,"ecdhb283") == 0) ecdh_doit[R_EC_B283]=2;
+ else if (strcmp(*argv,"ecdhb409") == 0) ecdh_doit[R_EC_B409]=2;
+ else if (strcmp(*argv,"ecdhb571") == 0) ecdh_doit[R_EC_B571]=2;
+ else if (strcmp(*argv,"ecdh") == 0)
+ {
+ for (i=0; i < EC_NUM; i++)
+ ecdh_doit[i]=1;
+ }
+ else
+#endif
+ {
+ BIO_printf(bio_err,"Error: bad option or value\n");
+ BIO_printf(bio_err,"\n");
+ BIO_printf(bio_err,"Available values:\n");
+#ifndef OPENSSL_NO_MD2
+ BIO_printf(bio_err,"md2 ");
+#endif
+#ifndef OPENSSL_NO_MDC2
+ BIO_printf(bio_err,"mdc2 ");
+#endif
+#ifndef OPENSSL_NO_MD4
+ BIO_printf(bio_err,"md4 ");
+#endif
+#ifndef OPENSSL_NO_MD5
+ BIO_printf(bio_err,"md5 ");
+#ifndef OPENSSL_NO_HMAC
+ BIO_printf(bio_err,"hmac ");
+#endif
+#endif
+#ifndef OPENSSL_NO_SHA1
+ BIO_printf(bio_err,"sha1 ");
+#endif
+#ifndef OPENSSL_NO_SHA256
+ BIO_printf(bio_err,"sha256 ");
+#endif
+#ifndef OPENSSL_NO_SHA512
+ BIO_printf(bio_err,"sha512 ");
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+ BIO_printf(bio_err,"whirlpool");
+#endif
+#ifndef OPENSSL_NO_RIPEMD160
+ BIO_printf(bio_err,"rmd160");
+#endif
+#if !defined(OPENSSL_NO_MD2) || !defined(OPENSSL_NO_MDC2) || \
+ !defined(OPENSSL_NO_MD4) || !defined(OPENSSL_NO_MD5) || \
+ !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160) || \
+ !defined(OPENSSL_NO_WHIRLPOOL)
+ BIO_printf(bio_err,"\n");
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+ BIO_printf(bio_err,"idea-cbc ");
+#endif
+#ifndef OPENSSL_NO_SEED
+ BIO_printf(bio_err,"seed-cbc ");
+#endif
+#ifndef OPENSSL_NO_RC2
+ BIO_printf(bio_err,"rc2-cbc ");
+#endif
+#ifndef OPENSSL_NO_RC5
+ BIO_printf(bio_err,"rc5-cbc ");
+#endif
+#ifndef OPENSSL_NO_BF
+ BIO_printf(bio_err,"bf-cbc");
+#endif
+#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || !defined(OPENSSL_NO_RC2) || \
+ !defined(OPENSSL_NO_BF) || !defined(OPENSSL_NO_RC5)
+ BIO_printf(bio_err,"\n");
+#endif
+#ifndef OPENSSL_NO_DES
+ BIO_printf(bio_err,"des-cbc des-ede3 ");
+#endif
+#ifndef OPENSSL_NO_AES
+ BIO_printf(bio_err,"aes-128-cbc aes-192-cbc aes-256-cbc ");
+ BIO_printf(bio_err,"aes-128-ige aes-192-ige aes-256-ige ");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ BIO_printf(bio_err,"\n");
+ BIO_printf(bio_err,"camellia-128-cbc camellia-192-cbc camellia-256-cbc ");
+#endif
+#ifndef OPENSSL_NO_RC4
+ BIO_printf(bio_err,"rc4");
+#endif
+ BIO_printf(bio_err,"\n");
+
+#ifndef OPENSSL_NO_RSA
+ BIO_printf(bio_err,"rsa512 rsa1024 rsa2048 rsa4096\n");
+#endif
+
+#ifndef OPENSSL_NO_DSA
+ BIO_printf(bio_err,"dsa512 dsa1024 dsa2048\n");
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ BIO_printf(bio_err,"ecdsap160 ecdsap192 ecdsap224 ecdsap256 ecdsap384 ecdsap521\n");
+ BIO_printf(bio_err,"ecdsak163 ecdsak233 ecdsak283 ecdsak409 ecdsak571\n");
+ BIO_printf(bio_err,"ecdsab163 ecdsab233 ecdsab283 ecdsab409 ecdsab571\n");
+ BIO_printf(bio_err,"ecdsa\n");
+#endif
+#ifndef OPENSSL_NO_ECDH
+ BIO_printf(bio_err,"ecdhp160 ecdhp192 ecdhp224 ecdhp256 ecdhp384 ecdhp521\n");
+ BIO_printf(bio_err,"ecdhk163 ecdhk233 ecdhk283 ecdhk409 ecdhk571\n");
+ BIO_printf(bio_err,"ecdhb163 ecdhb233 ecdhb283 ecdhb409 ecdhb571\n");
+ BIO_printf(bio_err,"ecdh\n");
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+ BIO_printf(bio_err,"idea ");
+#endif
+#ifndef OPENSSL_NO_SEED
+ BIO_printf(bio_err,"seed ");
+#endif
+#ifndef OPENSSL_NO_RC2
+ BIO_printf(bio_err,"rc2 ");
+#endif
+#ifndef OPENSSL_NO_DES
+ BIO_printf(bio_err,"des ");
+#endif
+#ifndef OPENSSL_NO_AES
+ BIO_printf(bio_err,"aes ");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ BIO_printf(bio_err,"camellia ");
+#endif
+#ifndef OPENSSL_NO_RSA
+ BIO_printf(bio_err,"rsa ");
+#endif
+#ifndef OPENSSL_NO_BF
+ BIO_printf(bio_err,"blowfish");
+#endif
+#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || \
+ !defined(OPENSSL_NO_RC2) || !defined(OPENSSL_NO_DES) || \
+ !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_BF) || \
+ !defined(OPENSSL_NO_AES) || !defined(OPENSSL_NO_CAMELLIA)
+ BIO_printf(bio_err,"\n");
+#endif
+
+ BIO_printf(bio_err,"\n");
+ BIO_printf(bio_err,"Available options:\n");
+#if defined(TIMES) || defined(USE_TOD)
+ BIO_printf(bio_err,"-elapsed measure time in real time instead of CPU user time.\n");
+#endif
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err,"-engine e use engine e, possibly a hardware device.\n");
+#endif
+ BIO_printf(bio_err,"-evp e use EVP e.\n");
+ BIO_printf(bio_err,"-decrypt time decryption instead of encryption (only EVP).\n");
+ BIO_printf(bio_err,"-mr produce machine readable output.\n");
+#ifndef NO_FORK
+ BIO_printf(bio_err,"-multi n run n benchmarks in parallel.\n");
+#endif
+ goto end;
+ }
+ argc--;
+ argv++;
+ j++;
+ }
+
+#ifndef NO_FORK
+ if(multi && do_multi(multi))
+ goto show_res;
+#endif
+
+ if (j == 0)
+ {
+ for (i=0; i<ALGOR_NUM; i++)
+ {
+ if (i != D_EVP)
+ doit[i]=1;
+ }
+ for (i=0; i<RSA_NUM; i++)
+ rsa_doit[i]=1;
+ for (i=0; i<DSA_NUM; i++)
+ dsa_doit[i]=1;
+#ifndef OPENSSL_NO_ECDSA
+ for (i=0; i<EC_NUM; i++)
+ ecdsa_doit[i]=1;
+#endif
+#ifndef OPENSSL_NO_ECDH
+ for (i=0; i<EC_NUM; i++)
+ ecdh_doit[i]=1;
+#endif
+ }
+ for (i=0; i<ALGOR_NUM; i++)
+ if (doit[i]) pr_header++;
+
+ if (usertime == 0 && !mr)
+ BIO_printf(bio_err,"You have chosen to measure elapsed time instead of user CPU time.\n");
+
+#ifndef OPENSSL_NO_RSA
+ for (i=0; i<RSA_NUM; i++)
+ {
+ const unsigned char *p;
+
+ p=rsa_data[i];
+ rsa_key[i]=d2i_RSAPrivateKey(NULL,&p,rsa_data_length[i]);
+ if (rsa_key[i] == NULL)
+ {
+ BIO_printf(bio_err,"internal error loading RSA key number %d\n",i);
+ goto end;
+ }
+#if 0
+ else
+ {
+ BIO_printf(bio_err,mr ? "+RK:%d:"
+ : "Loaded RSA key, %d bit modulus and e= 0x",
+ BN_num_bits(rsa_key[i]->n));
+ BN_print(bio_err,rsa_key[i]->e);
+ BIO_printf(bio_err,"\n");
+ }
+#endif
+ }
+#endif
+
+#ifndef OPENSSL_NO_DSA
+ dsa_key[0]=get_dsa512();
+ dsa_key[1]=get_dsa1024();
+ dsa_key[2]=get_dsa2048();
+#endif
+
+#ifndef OPENSSL_NO_DES
+ DES_set_key_unchecked(&key,&sch);
+ DES_set_key_unchecked(&key2,&sch2);
+ DES_set_key_unchecked(&key3,&sch3);
+#endif
+#ifndef OPENSSL_NO_AES
+ AES_set_encrypt_key(key16,128,&aes_ks1);
+ AES_set_encrypt_key(key24,192,&aes_ks2);
+ AES_set_encrypt_key(key32,256,&aes_ks3);
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ Camellia_set_key(key16,128,&camellia_ks1);
+ Camellia_set_key(ckey24,192,&camellia_ks2);
+ Camellia_set_key(ckey32,256,&camellia_ks3);
+#endif
+#ifndef OPENSSL_NO_IDEA
+ idea_set_encrypt_key(key16,&idea_ks);
+#endif
+#ifndef OPENSSL_NO_SEED
+ SEED_set_key(key16,&seed_ks);
+#endif
+#ifndef OPENSSL_NO_RC4
+ RC4_set_key(&rc4_ks,16,key16);
+#endif
+#ifndef OPENSSL_NO_RC2
+ RC2_set_key(&rc2_ks,16,key16,128);
+#endif
+#ifndef OPENSSL_NO_RC5
+ RC5_32_set_key(&rc5_ks,16,key16,12);
+#endif
+#ifndef OPENSSL_NO_BF
+ BF_set_key(&bf_ks,16,key16);
+#endif
+#ifndef OPENSSL_NO_CAST
+ CAST_set_key(&cast_ks,16,key16);
+#endif
+#ifndef OPENSSL_NO_RSA
+ memset(rsa_c,0,sizeof(rsa_c));
+#endif
+#ifndef SIGALRM
+#ifndef OPENSSL_NO_DES
+ BIO_printf(bio_err,"First we calculate the approximate speed ...\n");
+ count=10;
+ do {
+ long it;
+ count*=2;
+ Time_F(START);
+ for (it=count; it; it--)
+ DES_ecb_encrypt((DES_cblock *)buf,
+ (DES_cblock *)buf,
+ &sch,DES_ENCRYPT);
+ d=Time_F(STOP);
+ } while (d <3);
+ save_count=count;
+ c[D_MD2][0]=count/10;
+ c[D_MDC2][0]=count/10;
+ c[D_MD4][0]=count;
+ c[D_MD5][0]=count;
+ c[D_HMAC][0]=count;
+ c[D_SHA1][0]=count;
+ c[D_RMD160][0]=count;
+ c[D_RC4][0]=count*5;
+ c[D_CBC_DES][0]=count;
+ c[D_EDE3_DES][0]=count/3;
+ c[D_CBC_IDEA][0]=count;
+ c[D_CBC_SEED][0]=count;
+ c[D_CBC_RC2][0]=count;
+ c[D_CBC_RC5][0]=count;
+ c[D_CBC_BF][0]=count;
+ c[D_CBC_CAST][0]=count;
+ c[D_CBC_128_AES][0]=count;
+ c[D_CBC_192_AES][0]=count;
+ c[D_CBC_256_AES][0]=count;
+ c[D_CBC_128_CML][0]=count;
+ c[D_CBC_192_CML][0]=count;
+ c[D_CBC_256_CML][0]=count;
+ c[D_SHA256][0]=count;
+ c[D_SHA512][0]=count;
+ c[D_WHIRLPOOL][0]=count;
+ c[D_IGE_128_AES][0]=count;
+ c[D_IGE_192_AES][0]=count;
+ c[D_IGE_256_AES][0]=count;
+ c[D_GHASH][0]=count;
+
+ for (i=1; i<SIZE_NUM; i++)
+ {
+ c[D_MD2][i]=c[D_MD2][0]*4*lengths[0]/lengths[i];
+ c[D_MDC2][i]=c[D_MDC2][0]*4*lengths[0]/lengths[i];
+ c[D_MD4][i]=c[D_MD4][0]*4*lengths[0]/lengths[i];
+ c[D_MD5][i]=c[D_MD5][0]*4*lengths[0]/lengths[i];
+ c[D_HMAC][i]=c[D_HMAC][0]*4*lengths[0]/lengths[i];
+ c[D_SHA1][i]=c[D_SHA1][0]*4*lengths[0]/lengths[i];
+ c[D_RMD160][i]=c[D_RMD160][0]*4*lengths[0]/lengths[i];
+ c[D_SHA256][i]=c[D_SHA256][0]*4*lengths[0]/lengths[i];
+ c[D_SHA512][i]=c[D_SHA512][0]*4*lengths[0]/lengths[i];
+ c[D_WHIRLPOOL][i]=c[D_WHIRLPOOL][0]*4*lengths[0]/lengths[i];
+ }
+ for (i=1; i<SIZE_NUM; i++)
+ {
+ long l0,l1;
+
+ l0=(long)lengths[i-1];
+ l1=(long)lengths[i];
+ c[D_RC4][i]=c[D_RC4][i-1]*l0/l1;
+ c[D_CBC_DES][i]=c[D_CBC_DES][i-1]*l0/l1;
+ c[D_EDE3_DES][i]=c[D_EDE3_DES][i-1]*l0/l1;
+ c[D_CBC_IDEA][i]=c[D_CBC_IDEA][i-1]*l0/l1;
+ c[D_CBC_SEED][i]=c[D_CBC_SEED][i-1]*l0/l1;
+ c[D_CBC_RC2][i]=c[D_CBC_RC2][i-1]*l0/l1;
+ c[D_CBC_RC5][i]=c[D_CBC_RC5][i-1]*l0/l1;
+ c[D_CBC_BF][i]=c[D_CBC_BF][i-1]*l0/l1;
+ c[D_CBC_CAST][i]=c[D_CBC_CAST][i-1]*l0/l1;
+ c[D_CBC_128_AES][i]=c[D_CBC_128_AES][i-1]*l0/l1;
+ c[D_CBC_192_AES][i]=c[D_CBC_192_AES][i-1]*l0/l1;
+ c[D_CBC_256_AES][i]=c[D_CBC_256_AES][i-1]*l0/l1;
+ c[D_CBC_128_CML][i]=c[D_CBC_128_CML][i-1]*l0/l1;
+ c[D_CBC_192_CML][i]=c[D_CBC_192_CML][i-1]*l0/l1;
+ c[D_CBC_256_CML][i]=c[D_CBC_256_CML][i-1]*l0/l1;
+ c[D_IGE_128_AES][i]=c[D_IGE_128_AES][i-1]*l0/l1;
+ c[D_IGE_192_AES][i]=c[D_IGE_192_AES][i-1]*l0/l1;
+ c[D_IGE_256_AES][i]=c[D_IGE_256_AES][i-1]*l0/l1;
+ }
+#ifndef OPENSSL_NO_RSA
+ rsa_c[R_RSA_512][0]=count/2000;
+ rsa_c[R_RSA_512][1]=count/400;
+ for (i=1; i<RSA_NUM; i++)
+ {
+ rsa_c[i][0]=rsa_c[i-1][0]/8;
+ rsa_c[i][1]=rsa_c[i-1][1]/4;
+ if ((rsa_doit[i] <= 1) && (rsa_c[i][0] == 0))
+ rsa_doit[i]=0;
+ else
+ {
+ if (rsa_c[i][0] == 0)
+ {
+ rsa_c[i][0]=1;
+ rsa_c[i][1]=20;
+ }
+ }
+ }
+#endif
+
+#ifndef OPENSSL_NO_DSA
+ dsa_c[R_DSA_512][0]=count/1000;
+ dsa_c[R_DSA_512][1]=count/1000/2;
+ for (i=1; i<DSA_NUM; i++)
+ {
+ dsa_c[i][0]=dsa_c[i-1][0]/4;
+ dsa_c[i][1]=dsa_c[i-1][1]/4;
+ if ((dsa_doit[i] <= 1) && (dsa_c[i][0] == 0))
+ dsa_doit[i]=0;
+ else
+ {
+ if (dsa_c[i] == 0)
+ {
+ dsa_c[i][0]=1;
+ dsa_c[i][1]=1;
+ }
+ }
+ }
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+ ecdsa_c[R_EC_P160][0]=count/1000;
+ ecdsa_c[R_EC_P160][1]=count/1000/2;
+ for (i=R_EC_P192; i<=R_EC_P521; i++)
+ {
+ ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
+ ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
+ if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
+ ecdsa_doit[i]=0;
+ else
+ {
+ if (ecdsa_c[i] == 0)
+ {
+ ecdsa_c[i][0]=1;
+ ecdsa_c[i][1]=1;
+ }
+ }
+ }
+ ecdsa_c[R_EC_K163][0]=count/1000;
+ ecdsa_c[R_EC_K163][1]=count/1000/2;
+ for (i=R_EC_K233; i<=R_EC_K571; i++)
+ {
+ ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
+ ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
+ if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
+ ecdsa_doit[i]=0;
+ else
+ {
+ if (ecdsa_c[i] == 0)
+ {
+ ecdsa_c[i][0]=1;
+ ecdsa_c[i][1]=1;
+ }
+ }
+ }
+ ecdsa_c[R_EC_B163][0]=count/1000;
+ ecdsa_c[R_EC_B163][1]=count/1000/2;
+ for (i=R_EC_B233; i<=R_EC_B571; i++)
+ {
+ ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
+ ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
+ if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
+ ecdsa_doit[i]=0;
+ else
+ {
+ if (ecdsa_c[i] == 0)
+ {
+ ecdsa_c[i][0]=1;
+ ecdsa_c[i][1]=1;
+ }
+ }
+ }
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+ ecdh_c[R_EC_P160][0]=count/1000;
+ ecdh_c[R_EC_P160][1]=count/1000;
+ for (i=R_EC_P192; i<=R_EC_P521; i++)
+ {
+ ecdh_c[i][0]=ecdh_c[i-1][0]/2;
+ ecdh_c[i][1]=ecdh_c[i-1][1]/2;
+ if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
+ ecdh_doit[i]=0;
+ else
+ {
+ if (ecdh_c[i] == 0)
+ {
+ ecdh_c[i][0]=1;
+ ecdh_c[i][1]=1;
+ }
+ }
+ }
+ ecdh_c[R_EC_K163][0]=count/1000;
+ ecdh_c[R_EC_K163][1]=count/1000;
+ for (i=R_EC_K233; i<=R_EC_K571; i++)
+ {
+ ecdh_c[i][0]=ecdh_c[i-1][0]/2;
+ ecdh_c[i][1]=ecdh_c[i-1][1]/2;
+ if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
+ ecdh_doit[i]=0;
+ else
+ {
+ if (ecdh_c[i] == 0)
+ {
+ ecdh_c[i][0]=1;
+ ecdh_c[i][1]=1;
+ }
+ }
+ }
+ ecdh_c[R_EC_B163][0]=count/1000;
+ ecdh_c[R_EC_B163][1]=count/1000;
+ for (i=R_EC_B233; i<=R_EC_B571; i++)
+ {
+ ecdh_c[i][0]=ecdh_c[i-1][0]/2;
+ ecdh_c[i][1]=ecdh_c[i-1][1]/2;
+ if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
+ ecdh_doit[i]=0;
+ else
+ {
+ if (ecdh_c[i] == 0)
+ {
+ ecdh_c[i][0]=1;
+ ecdh_c[i][1]=1;
+ }
+ }
+ }
+#endif
+
+#define COND(d) (count < (d))
+#define COUNT(d) (d)
+#else
+/* not worth fixing */
+# error "You cannot disable DES on systems without SIGALRM."
+#endif /* OPENSSL_NO_DES */
+#else
+#define COND(c) (run && count<0x7fffffff)
+#define COUNT(d) (count)
+#ifndef _WIN32
+ signal(SIGALRM,sig_done);
+#endif
+#endif /* SIGALRM */
+
+#ifndef OPENSSL_NO_MD2
+ if (doit[D_MD2])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_MD2],c[D_MD2][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_MD2][j]); count++)
+ EVP_Digest(buf,(unsigned long)lengths[j],&(md2[0]),NULL,EVP_md2(),NULL);
+ d=Time_F(STOP);
+ print_result(D_MD2,j,count,d);
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_MDC2
+ if (doit[D_MDC2])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_MDC2],c[D_MDC2][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_MDC2][j]); count++)
+ EVP_Digest(buf,(unsigned long)lengths[j],&(mdc2[0]),NULL,EVP_mdc2(),NULL);
+ d=Time_F(STOP);
+ print_result(D_MDC2,j,count,d);
+ }
+ }
+#endif
+
+#ifndef OPENSSL_NO_MD4
+ if (doit[D_MD4])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_MD4],c[D_MD4][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_MD4][j]); count++)
+ EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md4[0]),NULL,EVP_md4(),NULL);
+ d=Time_F(STOP);
+ print_result(D_MD4,j,count,d);
+ }
+ }
+#endif
+
+#ifndef OPENSSL_NO_MD5
+ if (doit[D_MD5])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_MD5],c[D_MD5][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_MD5][j]); count++)
+ EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md5[0]),NULL,EVP_get_digestbyname("md5"),NULL);
+ d=Time_F(STOP);
+ print_result(D_MD5,j,count,d);
+ }
+ }
+#endif
+
+#if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_HMAC)
+ if (doit[D_HMAC])
+ {
+ HMAC_CTX hctx;
+
+ HMAC_CTX_init(&hctx);
+ HMAC_Init_ex(&hctx,(unsigned char *)"This is a key...",
+ 16,EVP_md5(), NULL);
+
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_HMAC],c[D_HMAC][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_HMAC][j]); count++)
+ {
+ HMAC_Init_ex(&hctx,NULL,0,NULL,NULL);
+ HMAC_Update(&hctx,buf,lengths[j]);
+ HMAC_Final(&hctx,&(hmac[0]),NULL);
+ }
+ d=Time_F(STOP);
+ print_result(D_HMAC,j,count,d);
+ }
+ HMAC_CTX_cleanup(&hctx);
+ }
+#endif
+#ifndef OPENSSL_NO_SHA
+ if (doit[D_SHA1])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_SHA1],c[D_SHA1][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_SHA1][j]); count++)
+ EVP_Digest(buf,(unsigned long)lengths[j],&(sha[0]),NULL,EVP_sha1(),NULL);
+ d=Time_F(STOP);
+ print_result(D_SHA1,j,count,d);
+ }
+ }
+
+#ifndef OPENSSL_NO_SHA256
+ if (doit[D_SHA256])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_SHA256],c[D_SHA256][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_SHA256][j]); count++)
+ SHA256(buf,lengths[j],sha256);
+ d=Time_F(STOP);
+ print_result(D_SHA256,j,count,d);
+ }
+ }
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+ if (doit[D_SHA512])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_SHA512],c[D_SHA512][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_SHA512][j]); count++)
+ SHA512(buf,lengths[j],sha512);
+ d=Time_F(STOP);
+ print_result(D_SHA512,j,count,d);
+ }
+ }
+#endif
+#endif
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+ if (doit[D_WHIRLPOOL])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_WHIRLPOOL],c[D_WHIRLPOOL][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_WHIRLPOOL][j]); count++)
+ WHIRLPOOL(buf,lengths[j],whirlpool);
+ d=Time_F(STOP);
+ print_result(D_WHIRLPOOL,j,count,d);
+ }
+ }
+#endif
+
+#ifndef OPENSSL_NO_RIPEMD
+ if (doit[D_RMD160])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_RMD160],c[D_RMD160][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_RMD160][j]); count++)
+ EVP_Digest(buf,(unsigned long)lengths[j],&(rmd160[0]),NULL,EVP_ripemd160(),NULL);
+ d=Time_F(STOP);
+ print_result(D_RMD160,j,count,d);
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_RC4
+ if (doit[D_RC4])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_RC4],c[D_RC4][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_RC4][j]); count++)
+ RC4(&rc4_ks,(unsigned int)lengths[j],
+ buf,buf);
+ d=Time_F(STOP);
+ print_result(D_RC4,j,count,d);
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_DES
+ if (doit[D_CBC_DES])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_DES],c[D_CBC_DES][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_DES][j]); count++)
+ DES_ncbc_encrypt(buf,buf,lengths[j],&sch,
+ &DES_iv,DES_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_DES,j,count,d);
+ }
+ }
+
+ if (doit[D_EDE3_DES])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_EDE3_DES],c[D_EDE3_DES][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_EDE3_DES][j]); count++)
+ DES_ede3_cbc_encrypt(buf,buf,lengths[j],
+ &sch,&sch2,&sch3,
+ &DES_iv,DES_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_EDE3_DES,j,count,d);
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_AES
+ if (doit[D_CBC_128_AES])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_128_AES],c[D_CBC_128_AES][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_128_AES][j]); count++)
+ AES_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&aes_ks1,
+ iv,AES_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_128_AES,j,count,d);
+ }
+ }
+ if (doit[D_CBC_192_AES])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_192_AES],c[D_CBC_192_AES][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_192_AES][j]); count++)
+ AES_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&aes_ks2,
+ iv,AES_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_192_AES,j,count,d);
+ }
+ }
+ if (doit[D_CBC_256_AES])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_256_AES],c[D_CBC_256_AES][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_256_AES][j]); count++)
+ AES_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&aes_ks3,
+ iv,AES_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_256_AES,j,count,d);
+ }
+ }
+
+ if (doit[D_IGE_128_AES])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_IGE_128_AES],c[D_IGE_128_AES][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_IGE_128_AES][j]); count++)
+ AES_ige_encrypt(buf,buf2,
+ (unsigned long)lengths[j],&aes_ks1,
+ iv,AES_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_IGE_128_AES,j,count,d);
+ }
+ }
+ if (doit[D_IGE_192_AES])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_IGE_192_AES],c[D_IGE_192_AES][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_IGE_192_AES][j]); count++)
+ AES_ige_encrypt(buf,buf2,
+ (unsigned long)lengths[j],&aes_ks2,
+ iv,AES_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_IGE_192_AES,j,count,d);
+ }
+ }
+ if (doit[D_IGE_256_AES])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_IGE_256_AES],c[D_IGE_256_AES][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_IGE_256_AES][j]); count++)
+ AES_ige_encrypt(buf,buf2,
+ (unsigned long)lengths[j],&aes_ks3,
+ iv,AES_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_IGE_256_AES,j,count,d);
+ }
+ }
+ if (doit[D_GHASH])
+ {
+ GCM128_CONTEXT *ctx = CRYPTO_gcm128_new(&aes_ks1,(block128_f)AES_encrypt);
+ CRYPTO_gcm128_setiv (ctx,(unsigned char *)"0123456789ab",12);
+
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_GHASH],c[D_GHASH][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_GHASH][j]); count++)
+ CRYPTO_gcm128_aad(ctx,buf,lengths[j]);
+ d=Time_F(STOP);
+ print_result(D_GHASH,j,count,d);
+ }
+ CRYPTO_gcm128_release(ctx);
+ }
+
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ if (doit[D_CBC_128_CML])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_128_CML],c[D_CBC_128_CML][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_128_CML][j]); count++)
+ Camellia_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&camellia_ks1,
+ iv,CAMELLIA_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_128_CML,j,count,d);
+ }
+ }
+ if (doit[D_CBC_192_CML])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_192_CML],c[D_CBC_192_CML][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_192_CML][j]); count++)
+ Camellia_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&camellia_ks2,
+ iv,CAMELLIA_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_192_CML,j,count,d);
+ }
+ }
+ if (doit[D_CBC_256_CML])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_256_CML],c[D_CBC_256_CML][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_256_CML][j]); count++)
+ Camellia_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&camellia_ks3,
+ iv,CAMELLIA_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_256_CML,j,count,d);
+ }
+ }
+
+#endif
+#ifndef OPENSSL_NO_IDEA
+ if (doit[D_CBC_IDEA])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_IDEA],c[D_CBC_IDEA][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_IDEA][j]); count++)
+ idea_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&idea_ks,
+ iv,IDEA_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_IDEA,j,count,d);
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_SEED
+ if (doit[D_CBC_SEED])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_SEED],c[D_CBC_SEED][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_SEED][j]); count++)
+ SEED_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&seed_ks,iv,1);
+ d=Time_F(STOP);
+ print_result(D_CBC_SEED,j,count,d);
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_RC2
+ if (doit[D_CBC_RC2])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_RC2],c[D_CBC_RC2][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_RC2][j]); count++)
+ RC2_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&rc2_ks,
+ iv,RC2_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_RC2,j,count,d);
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_RC5
+ if (doit[D_CBC_RC5])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_RC5],c[D_CBC_RC5][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_RC5][j]); count++)
+ RC5_32_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&rc5_ks,
+ iv,RC5_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_RC5,j,count,d);
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_BF
+ if (doit[D_CBC_BF])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_BF],c[D_CBC_BF][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_BF][j]); count++)
+ BF_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&bf_ks,
+ iv,BF_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_BF,j,count,d);
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_CAST
+ if (doit[D_CBC_CAST])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ print_message(names[D_CBC_CAST],c[D_CBC_CAST][j],lengths[j]);
+ Time_F(START);
+ for (count=0,run=1; COND(c[D_CBC_CAST][j]); count++)
+ CAST_cbc_encrypt(buf,buf,
+ (unsigned long)lengths[j],&cast_ks,
+ iv,CAST_ENCRYPT);
+ d=Time_F(STOP);
+ print_result(D_CBC_CAST,j,count,d);
+ }
+ }
+#endif
+
+ if (doit[D_EVP])
+ {
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ if (evp_cipher)
+ {
+ EVP_CIPHER_CTX ctx;
+ int outl;
+
+ names[D_EVP]=OBJ_nid2ln(evp_cipher->nid);
+ /* -O3 -fschedule-insns messes up an
+ * optimization here! names[D_EVP]
+ * somehow becomes NULL */
+ print_message(names[D_EVP],save_count,
+ lengths[j]);
+
+ EVP_CIPHER_CTX_init(&ctx);
+ if(decrypt)
+ EVP_DecryptInit_ex(&ctx,evp_cipher,NULL,key16,iv);
+ else
+ EVP_EncryptInit_ex(&ctx,evp_cipher,NULL,key16,iv);
+ EVP_CIPHER_CTX_set_padding(&ctx, 0);
+
+ Time_F(START);
+ if(decrypt)
+ for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
+ EVP_DecryptUpdate(&ctx,buf,&outl,buf,lengths[j]);
+ else
+ for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
+ EVP_EncryptUpdate(&ctx,buf,&outl,buf,lengths[j]);
+ if(decrypt)
+ EVP_DecryptFinal_ex(&ctx,buf,&outl);
+ else
+ EVP_EncryptFinal_ex(&ctx,buf,&outl);
+ d=Time_F(STOP);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ }
+ if (evp_md)
+ {
+ names[D_EVP]=OBJ_nid2ln(evp_md->type);
+ print_message(names[D_EVP],save_count,
+ lengths[j]);
+
+ Time_F(START);
+ for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
+ EVP_Digest(buf,lengths[j],&(md[0]),NULL,evp_md,NULL);
+
+ d=Time_F(STOP);
+ }
+ print_result(D_EVP,j,count,d);
+ }
+ }
+
+ RAND_pseudo_bytes(buf,36);
+#ifndef OPENSSL_NO_RSA
+ for (j=0; j<RSA_NUM; j++)
+ {
+ int ret;
+ if (!rsa_doit[j]) continue;
+ ret=RSA_sign(NID_md5_sha1, buf,36, buf2, &rsa_num, rsa_key[j]);
+ if (ret == 0)
+ {
+ BIO_printf(bio_err,"RSA sign failure. No RSA sign will be done.\n");
+ ERR_print_errors(bio_err);
+ rsa_count=1;
+ }
+ else
+ {
+ pkey_print_message("private","rsa",
+ rsa_c[j][0],rsa_bits[j],
+ RSA_SECONDS);
+/* RSA_blinding_on(rsa_key[j],NULL); */
+ Time_F(START);
+ for (count=0,run=1; COND(rsa_c[j][0]); count++)
+ {
+ ret=RSA_sign(NID_md5_sha1, buf,36, buf2,
+ &rsa_num, rsa_key[j]);
+ if (ret == 0)
+ {
+ BIO_printf(bio_err,
+ "RSA sign failure\n");
+ ERR_print_errors(bio_err);
+ count=1;
+ break;
+ }
+ }
+ d=Time_F(STOP);
+ BIO_printf(bio_err,mr ? "+R1:%ld:%d:%.2f\n"
+ : "%ld %d bit private RSA's in %.2fs\n",
+ count,rsa_bits[j],d);
+ rsa_results[j][0]=d/(double)count;
+ rsa_count=count;
+ }
+
+#if 1
+ ret=RSA_verify(NID_md5_sha1, buf,36, buf2, rsa_num, rsa_key[j]);
+ if (ret <= 0)
+ {
+ BIO_printf(bio_err,"RSA verify failure. No RSA verify will be done.\n");
+ ERR_print_errors(bio_err);
+ rsa_doit[j] = 0;
+ }
+ else
+ {
+ pkey_print_message("public","rsa",
+ rsa_c[j][1],rsa_bits[j],
+ RSA_SECONDS);
+ Time_F(START);
+ for (count=0,run=1; COND(rsa_c[j][1]); count++)
+ {
+ ret=RSA_verify(NID_md5_sha1, buf,36, buf2,
+ rsa_num, rsa_key[j]);
+ if (ret <= 0)
+ {
+ BIO_printf(bio_err,
+ "RSA verify failure\n");
+ ERR_print_errors(bio_err);
+ count=1;
+ break;
+ }
+ }
+ d=Time_F(STOP);
+ BIO_printf(bio_err,mr ? "+R2:%ld:%d:%.2f\n"
+ : "%ld %d bit public RSA's in %.2fs\n",
+ count,rsa_bits[j],d);
+ rsa_results[j][1]=d/(double)count;
+ }
+#endif
+
+ if (rsa_count <= 1)
+ {
+ /* if longer than 10s, don't do any more */
+ for (j++; j<RSA_NUM; j++)
+ rsa_doit[j]=0;
+ }
+ }
+#endif
+
+ RAND_pseudo_bytes(buf,20);
+#ifndef OPENSSL_NO_DSA
+ if (RAND_status() != 1)
+ {
+ RAND_seed(rnd_seed, sizeof rnd_seed);
+ rnd_fake = 1;
+ }
+ for (j=0; j<DSA_NUM; j++)
+ {
+ unsigned int kk;
+ int ret;
+
+ if (!dsa_doit[j]) continue;
+/* DSA_generate_key(dsa_key[j]); */
+/* DSA_sign_setup(dsa_key[j],NULL); */
+ ret=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
+ &kk,dsa_key[j]);
+ if (ret == 0)
+ {
+ BIO_printf(bio_err,"DSA sign failure. No DSA sign will be done.\n");
+ ERR_print_errors(bio_err);
+ rsa_count=1;
+ }
+ else
+ {
+ pkey_print_message("sign","dsa",
+ dsa_c[j][0],dsa_bits[j],
+ DSA_SECONDS);
+ Time_F(START);
+ for (count=0,run=1; COND(dsa_c[j][0]); count++)
+ {
+ ret=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
+ &kk,dsa_key[j]);
+ if (ret == 0)
+ {
+ BIO_printf(bio_err,
+ "DSA sign failure\n");
+ ERR_print_errors(bio_err);
+ count=1;
+ break;
+ }
+ }
+ d=Time_F(STOP);
+ BIO_printf(bio_err,mr ? "+R3:%ld:%d:%.2f\n"
+ : "%ld %d bit DSA signs in %.2fs\n",
+ count,dsa_bits[j],d);
+ dsa_results[j][0]=d/(double)count;
+ rsa_count=count;
+ }
+
+ ret=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
+ kk,dsa_key[j]);
+ if (ret <= 0)
+ {
+ BIO_printf(bio_err,"DSA verify failure. No DSA verify will be done.\n");
+ ERR_print_errors(bio_err);
+ dsa_doit[j] = 0;
+ }
+ else
+ {
+ pkey_print_message("verify","dsa",
+ dsa_c[j][1],dsa_bits[j],
+ DSA_SECONDS);
+ Time_F(START);
+ for (count=0,run=1; COND(dsa_c[j][1]); count++)
+ {
+ ret=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
+ kk,dsa_key[j]);
+ if (ret <= 0)
+ {
+ BIO_printf(bio_err,
+ "DSA verify failure\n");
+ ERR_print_errors(bio_err);
+ count=1;
+ break;
+ }
+ }
+ d=Time_F(STOP);
+ BIO_printf(bio_err,mr ? "+R4:%ld:%d:%.2f\n"
+ : "%ld %d bit DSA verify in %.2fs\n",
+ count,dsa_bits[j],d);
+ dsa_results[j][1]=d/(double)count;
+ }
+
+ if (rsa_count <= 1)
+ {
+ /* if longer than 10s, don't do any more */
+ for (j++; j<DSA_NUM; j++)
+ dsa_doit[j]=0;
+ }
+ }
+ if (rnd_fake) RAND_cleanup();
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+ if (RAND_status() != 1)
+ {
+ RAND_seed(rnd_seed, sizeof rnd_seed);
+ rnd_fake = 1;
+ }
+ for (j=0; j<EC_NUM; j++)
+ {
+ int ret;
+
+ if (!ecdsa_doit[j]) continue; /* Ignore Curve */
+ ecdsa[j] = EC_KEY_new_by_curve_name(test_curves[j]);
+ if (ecdsa[j] == NULL)
+ {
+ BIO_printf(bio_err,"ECDSA failure.\n");
+ ERR_print_errors(bio_err);
+ rsa_count=1;
+ }
+ else
+ {
+#if 1
+ EC_KEY_precompute_mult(ecdsa[j], NULL);
+#endif
+ /* Perform ECDSA signature test */
+ EC_KEY_generate_key(ecdsa[j]);
+ ret = ECDSA_sign(0, buf, 20, ecdsasig,
+ &ecdsasiglen, ecdsa[j]);
+ if (ret == 0)
+ {
+ BIO_printf(bio_err,"ECDSA sign failure. No ECDSA sign will be done.\n");
+ ERR_print_errors(bio_err);
+ rsa_count=1;
+ }
+ else
+ {
+ pkey_print_message("sign","ecdsa",
+ ecdsa_c[j][0],
+ test_curves_bits[j],
+ ECDSA_SECONDS);
+
+ Time_F(START);
+ for (count=0,run=1; COND(ecdsa_c[j][0]);
+ count++)
+ {
+ ret=ECDSA_sign(0, buf, 20,
+ ecdsasig, &ecdsasiglen,
+ ecdsa[j]);
+ if (ret == 0)
+ {
+ BIO_printf(bio_err, "ECDSA sign failure\n");
+ ERR_print_errors(bio_err);
+ count=1;
+ break;
+ }
+ }
+ d=Time_F(STOP);
+
+ BIO_printf(bio_err, mr ? "+R5:%ld:%d:%.2f\n" :
+ "%ld %d bit ECDSA signs in %.2fs \n",
+ count, test_curves_bits[j], d);
+ ecdsa_results[j][0]=d/(double)count;
+ rsa_count=count;
+ }
+
+ /* Perform ECDSA verification test */
+ ret=ECDSA_verify(0, buf, 20, ecdsasig,
+ ecdsasiglen, ecdsa[j]);
+ if (ret != 1)
+ {
+ BIO_printf(bio_err,"ECDSA verify failure. No ECDSA verify will be done.\n");
+ ERR_print_errors(bio_err);
+ ecdsa_doit[j] = 0;
+ }
+ else
+ {
+ pkey_print_message("verify","ecdsa",
+ ecdsa_c[j][1],
+ test_curves_bits[j],
+ ECDSA_SECONDS);
+ Time_F(START);
+ for (count=0,run=1; COND(ecdsa_c[j][1]); count++)
+ {
+ ret=ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]);
+ if (ret != 1)
+ {
+ BIO_printf(bio_err, "ECDSA verify failure\n");
+ ERR_print_errors(bio_err);
+ count=1;
+ break;
+ }
+ }
+ d=Time_F(STOP);
+ BIO_printf(bio_err, mr? "+R6:%ld:%d:%.2f\n"
+ : "%ld %d bit ECDSA verify in %.2fs\n",
+ count, test_curves_bits[j], d);
+ ecdsa_results[j][1]=d/(double)count;
+ }
+
+ if (rsa_count <= 1)
+ {
+ /* if longer than 10s, don't do any more */
+ for (j++; j<EC_NUM; j++)
+ ecdsa_doit[j]=0;
+ }
+ }
+ }
+ if (rnd_fake) RAND_cleanup();
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+ if (RAND_status() != 1)
+ {
+ RAND_seed(rnd_seed, sizeof rnd_seed);
+ rnd_fake = 1;
+ }
+ for (j=0; j<EC_NUM; j++)
+ {
+ if (!ecdh_doit[j]) continue;
+ ecdh_a[j] = EC_KEY_new_by_curve_name(test_curves[j]);
+ ecdh_b[j] = EC_KEY_new_by_curve_name(test_curves[j]);
+ if ((ecdh_a[j] == NULL) || (ecdh_b[j] == NULL))
+ {
+ BIO_printf(bio_err,"ECDH failure.\n");
+ ERR_print_errors(bio_err);
+ rsa_count=1;
+ }
+ else
+ {
+ /* generate two ECDH key pairs */
+ if (!EC_KEY_generate_key(ecdh_a[j]) ||
+ !EC_KEY_generate_key(ecdh_b[j]))
+ {
+ BIO_printf(bio_err,"ECDH key generation failure.\n");
+ ERR_print_errors(bio_err);
+ rsa_count=1;
+ }
+ else
+ {
+ /* If field size is not more than 24 octets, then use SHA-1 hash of result;
+ * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt).
+ */
+ int field_size, outlen;
+ void *(*kdf)(const void *in, size_t inlen, void *out, size_t *xoutlen);
+ field_size = EC_GROUP_get_degree(EC_KEY_get0_group(ecdh_a[j]));
+ if (field_size <= 24 * 8)
+ {
+ outlen = KDF1_SHA1_len;
+ kdf = KDF1_SHA1;
+ }
+ else
+ {
+ outlen = (field_size+7)/8;
+ kdf = NULL;
+ }
+ secret_size_a = ECDH_compute_key(secret_a, outlen,
+ EC_KEY_get0_public_key(ecdh_b[j]),
+ ecdh_a[j], kdf);
+ secret_size_b = ECDH_compute_key(secret_b, outlen,
+ EC_KEY_get0_public_key(ecdh_a[j]),
+ ecdh_b[j], kdf);
+ if (secret_size_a != secret_size_b)
+ ecdh_checks = 0;
+ else
+ ecdh_checks = 1;
+
+ for (secret_idx = 0;
+ (secret_idx < secret_size_a)
+ && (ecdh_checks == 1);
+ secret_idx++)
+ {
+ if (secret_a[secret_idx] != secret_b[secret_idx])
+ ecdh_checks = 0;
+ }
+
+ if (ecdh_checks == 0)
+ {
+ BIO_printf(bio_err,"ECDH computations don't match.\n");
+ ERR_print_errors(bio_err);
+ rsa_count=1;
+ }
+
+ pkey_print_message("","ecdh",
+ ecdh_c[j][0],
+ test_curves_bits[j],
+ ECDH_SECONDS);
+ Time_F(START);
+ for (count=0,run=1; COND(ecdh_c[j][0]); count++)
+ {
+ ECDH_compute_key(secret_a, outlen,
+ EC_KEY_get0_public_key(ecdh_b[j]),
+ ecdh_a[j], kdf);
+ }
+ d=Time_F(STOP);
+ BIO_printf(bio_err, mr ? "+R7:%ld:%d:%.2f\n" :"%ld %d-bit ECDH ops in %.2fs\n",
+ count, test_curves_bits[j], d);
+ ecdh_results[j][0]=d/(double)count;
+ rsa_count=count;
+ }
+ }
+
+
+ if (rsa_count <= 1)
+ {
+ /* if longer than 10s, don't do any more */
+ for (j++; j<EC_NUM; j++)
+ ecdh_doit[j]=0;
+ }
+ }
+ if (rnd_fake) RAND_cleanup();
+#endif
+#ifndef NO_FORK
+show_res:
+#endif
+ if(!mr)
+ {
+ fprintf(stdout,"%s\n",SSLeay_version(SSLEAY_VERSION));
+ fprintf(stdout,"%s\n",SSLeay_version(SSLEAY_BUILT_ON));
+ printf("options:");
+ printf("%s ",BN_options());
+#ifndef OPENSSL_NO_MD2
+ printf("%s ",MD2_options());
+#endif
+#ifndef OPENSSL_NO_RC4
+ printf("%s ",RC4_options());
+#endif
+#ifndef OPENSSL_NO_DES
+ printf("%s ",DES_options());
+#endif
+#ifndef OPENSSL_NO_AES
+ printf("%s ",AES_options());
+#endif
+#ifndef OPENSSL_NO_IDEA
+ printf("%s ",idea_options());
+#endif
+#ifndef OPENSSL_NO_BF
+ printf("%s ",BF_options());
+#endif
+ fprintf(stdout,"\n%s\n",SSLeay_version(SSLEAY_CFLAGS));
+ }
+
+ if (pr_header)
+ {
+ if(mr)
+ fprintf(stdout,"+H");
+ else
+ {
+ fprintf(stdout,"The 'numbers' are in 1000s of bytes per second processed.\n");
+ fprintf(stdout,"type ");
+ }
+ for (j=0; j<SIZE_NUM; j++)
+ fprintf(stdout,mr ? ":%d" : "%7d bytes",lengths[j]);
+ fprintf(stdout,"\n");
+ }
+
+ for (k=0; k<ALGOR_NUM; k++)
+ {
+ if (!doit[k]) continue;
+ if(mr)
+ fprintf(stdout,"+F:%d:%s",k,names[k]);
+ else
+ fprintf(stdout,"%-13s",names[k]);
+ for (j=0; j<SIZE_NUM; j++)
+ {
+ if (results[k][j] > 10000 && !mr)
+ fprintf(stdout," %11.2fk",results[k][j]/1e3);
+ else
+ fprintf(stdout,mr ? ":%.2f" : " %11.2f ",results[k][j]);
+ }
+ fprintf(stdout,"\n");
+ }
+#ifndef OPENSSL_NO_RSA
+ j=1;
+ for (k=0; k<RSA_NUM; k++)
+ {
+ if (!rsa_doit[k]) continue;
+ if (j && !mr)
+ {
+ printf("%18ssign verify sign/s verify/s\n"," ");
+ j=0;
+ }
+ if(mr)
+ fprintf(stdout,"+F2:%u:%u:%f:%f\n",
+ k,rsa_bits[k],rsa_results[k][0],
+ rsa_results[k][1]);
+ else
+ fprintf(stdout,"rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
+ rsa_bits[k],rsa_results[k][0],rsa_results[k][1],
+ 1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
+ }
+#endif
+#ifndef OPENSSL_NO_DSA
+ j=1;
+ for (k=0; k<DSA_NUM; k++)
+ {
+ if (!dsa_doit[k]) continue;
+ if (j && !mr)
+ {
+ printf("%18ssign verify sign/s verify/s\n"," ");
+ j=0;
+ }
+ if(mr)
+ fprintf(stdout,"+F3:%u:%u:%f:%f\n",
+ k,dsa_bits[k],dsa_results[k][0],dsa_results[k][1]);
+ else
+ fprintf(stdout,"dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
+ dsa_bits[k],dsa_results[k][0],dsa_results[k][1],
+ 1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
+ }
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ j=1;
+ for (k=0; k<EC_NUM; k++)
+ {
+ if (!ecdsa_doit[k]) continue;
+ if (j && !mr)
+ {
+ printf("%30ssign verify sign/s verify/s\n"," ");
+ j=0;
+ }
+
+ if (mr)
+ fprintf(stdout,"+F4:%u:%u:%f:%f\n",
+ k, test_curves_bits[k],
+ ecdsa_results[k][0],ecdsa_results[k][1]);
+ else
+ fprintf(stdout,
+ "%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
+ test_curves_bits[k],
+ test_curves_names[k],
+ ecdsa_results[k][0],ecdsa_results[k][1],
+ 1.0/ecdsa_results[k][0],1.0/ecdsa_results[k][1]);
+ }
+#endif
+
+
+#ifndef OPENSSL_NO_ECDH
+ j=1;
+ for (k=0; k<EC_NUM; k++)
+ {
+ if (!ecdh_doit[k]) continue;
+ if (j && !mr)
+ {
+ printf("%30sop op/s\n"," ");
+ j=0;
+ }
+ if (mr)
+ fprintf(stdout,"+F5:%u:%u:%f:%f\n",
+ k, test_curves_bits[k],
+ ecdh_results[k][0], 1.0/ecdh_results[k][0]);
+
+ else
+ fprintf(stdout,"%4u bit ecdh (%s) %8.4fs %8.1f\n",
+ test_curves_bits[k],
+ test_curves_names[k],
+ ecdh_results[k][0], 1.0/ecdh_results[k][0]);
+ }
+#endif
+
+ mret=0;
+
+end:
+ ERR_print_errors(bio_err);
+ if (buf != NULL) OPENSSL_free(buf);
+ if (buf2 != NULL) OPENSSL_free(buf2);
+#ifndef OPENSSL_NO_RSA
+ for (i=0; i<RSA_NUM; i++)
+ if (rsa_key[i] != NULL)
+ RSA_free(rsa_key[i]);
+#endif
+#ifndef OPENSSL_NO_DSA
+ for (i=0; i<DSA_NUM; i++)
+ if (dsa_key[i] != NULL)
+ DSA_free(dsa_key[i]);
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+ for (i=0; i<EC_NUM; i++)
+ if (ecdsa[i] != NULL)
+ EC_KEY_free(ecdsa[i]);
+#endif
+#ifndef OPENSSL_NO_ECDH
+ for (i=0; i<EC_NUM; i++)
+ {
+ if (ecdh_a[i] != NULL)
+ EC_KEY_free(ecdh_a[i]);
+ if (ecdh_b[i] != NULL)
+ EC_KEY_free(ecdh_b[i]);
+ }
+#endif
+
+ apps_shutdown();
+ OPENSSL_EXIT(mret);
+ }
+
+static void print_message(const char *s, long num, int length)
+ {
+#ifdef SIGALRM
+ BIO_printf(bio_err,mr ? "+DT:%s:%d:%d\n"
+ : "Doing %s for %ds on %d size blocks: ",s,SECONDS,length);
+ (void)BIO_flush(bio_err);
+ alarm(SECONDS);
+#else
+ BIO_printf(bio_err,mr ? "+DN:%s:%ld:%d\n"
+ : "Doing %s %ld times on %d size blocks: ",s,num,length);
+ (void)BIO_flush(bio_err);
+#endif
+#ifdef LINT
+ num=num;
+#endif
+ }
+
+static void pkey_print_message(const char *str, const char *str2, long num,
+ int bits, int tm)
+ {
+#ifdef SIGALRM
+ BIO_printf(bio_err,mr ? "+DTP:%d:%s:%s:%d\n"
+ : "Doing %d bit %s %s's for %ds: ",bits,str,str2,tm);
+ (void)BIO_flush(bio_err);
+ alarm(tm);
+#else
+ BIO_printf(bio_err,mr ? "+DNP:%ld:%d:%s:%s\n"
+ : "Doing %ld %d bit %s %s's: ",num,bits,str,str2);
+ (void)BIO_flush(bio_err);
+#endif
+#ifdef LINT
+ num=num;
+#endif
+ }
+
+static void print_result(int alg,int run_no,int count,double time_used)
+ {
+ BIO_printf(bio_err,mr ? "+R:%d:%s:%f\n"
+ : "%d %s's in %.2fs\n",count,names[alg],time_used);
+ results[alg][run_no]=((double)count)/time_used*lengths[run_no];
+ }
+
+#ifndef NO_FORK
+static char *sstrsep(char **string, const char *delim)
+ {
+ char isdelim[256];
+ char *token = *string;
+
+ if (**string == 0)
+ return NULL;
+
+ memset(isdelim, 0, sizeof isdelim);
+ isdelim[0] = 1;
+
+ while (*delim)
+ {
+ isdelim[(unsigned char)(*delim)] = 1;
+ delim++;
+ }
+
+ while (!isdelim[(unsigned char)(**string)])
+ {
+ (*string)++;
+ }
+
+ if (**string)
+ {
+ **string = 0;
+ (*string)++;
+ }
+
+ return token;
+ }
+
+static int do_multi(int multi)
+ {
+ int n;
+ int fd[2];
+ int *fds;
+ static char sep[]=":";
+
+ fds=malloc(multi*sizeof *fds);
+ for(n=0 ; n < multi ; ++n)
+ {
+ if (pipe(fd) == -1)
+ {
+ fprintf(stderr, "pipe failure\n");
+ exit(1);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ if(fork())
+ {
+ close(fd[1]);
+ fds[n]=fd[0];
+ }
+ else
+ {
+ close(fd[0]);
+ close(1);
+ if (dup(fd[1]) == -1)
+ {
+ fprintf(stderr, "dup failed\n");
+ exit(1);
+ }
+ close(fd[1]);
+ mr=1;
+ usertime=0;
+ free(fds);
+ return 0;
+ }
+ printf("Forked child %d\n",n);
+ }
+
+ /* for now, assume the pipe is long enough to take all the output */
+ for(n=0 ; n < multi ; ++n)
+ {
+ FILE *f;
+ char buf[1024];
+ char *p;
+
+ f=fdopen(fds[n],"r");
+ while(fgets(buf,sizeof buf,f))
+ {
+ p=strchr(buf,'\n');
+ if(p)
+ *p='\0';
+ if(buf[0] != '+')
+ {
+ fprintf(stderr,"Don't understand line '%s' from child %d\n",
+ buf,n);
+ continue;
+ }
+ printf("Got: %s from %d\n",buf,n);
+ if(!strncmp(buf,"+F:",3))
+ {
+ int alg;
+ int j;
+
+ p=buf+3;
+ alg=atoi(sstrsep(&p,sep));
+ sstrsep(&p,sep);
+ for(j=0 ; j < SIZE_NUM ; ++j)
+ results[alg][j]+=atof(sstrsep(&p,sep));
+ }
+ else if(!strncmp(buf,"+F2:",4))
+ {
+ int k;
+ double d;
+
+ p=buf+4;
+ k=atoi(sstrsep(&p,sep));
+ sstrsep(&p,sep);
+
+ d=atof(sstrsep(&p,sep));
+ if(n)
+ rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
+ else
+ rsa_results[k][0]=d;
+
+ d=atof(sstrsep(&p,sep));
+ if(n)
+ rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
+ else
+ rsa_results[k][1]=d;
+ }
+ else if(!strncmp(buf,"+F2:",4))
+ {
+ int k;
+ double d;
+
+ p=buf+4;
+ k=atoi(sstrsep(&p,sep));
+ sstrsep(&p,sep);
+
+ d=atof(sstrsep(&p,sep));
+ if(n)
+ rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
+ else
+ rsa_results[k][0]=d;
+
+ d=atof(sstrsep(&p,sep));
+ if(n)
+ rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
+ else
+ rsa_results[k][1]=d;
+ }
+#ifndef OPENSSL_NO_DSA
+ else if(!strncmp(buf,"+F3:",4))
+ {
+ int k;
+ double d;
+
+ p=buf+4;
+ k=atoi(sstrsep(&p,sep));
+ sstrsep(&p,sep);
+
+ d=atof(sstrsep(&p,sep));
+ if(n)
+ dsa_results[k][0]=1/(1/dsa_results[k][0]+1/d);
+ else
+ dsa_results[k][0]=d;
+
+ d=atof(sstrsep(&p,sep));
+ if(n)
+ dsa_results[k][1]=1/(1/dsa_results[k][1]+1/d);
+ else
+ dsa_results[k][1]=d;
+ }
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ else if(!strncmp(buf,"+F4:",4))
+ {
+ int k;
+ double d;
+
+ p=buf+4;
+ k=atoi(sstrsep(&p,sep));
+ sstrsep(&p,sep);
+
+ d=atof(sstrsep(&p,sep));
+ if(n)
+ ecdsa_results[k][0]=1/(1/ecdsa_results[k][0]+1/d);
+ else
+ ecdsa_results[k][0]=d;
+
+ d=atof(sstrsep(&p,sep));
+ if(n)
+ ecdsa_results[k][1]=1/(1/ecdsa_results[k][1]+1/d);
+ else
+ ecdsa_results[k][1]=d;
+ }
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+ else if(!strncmp(buf,"+F5:",4))
+ {
+ int k;
+ double d;
+
+ p=buf+4;
+ k=atoi(sstrsep(&p,sep));
+ sstrsep(&p,sep);
+
+ d=atof(sstrsep(&p,sep));
+ if(n)
+ ecdh_results[k][0]=1/(1/ecdh_results[k][0]+1/d);
+ else
+ ecdh_results[k][0]=d;
+
+ }
+#endif
+
+ else if(!strncmp(buf,"+H:",3))
+ {
+ }
+ else
+ fprintf(stderr,"Unknown type '%s' from child %d\n",buf,n);
+ }
+
+ fclose(f);
+ }
+ free(fds);
+ return 1;
+ }
+#endif
+#endif
diff --git a/deps/openssl/openssl/apps/spkac.c b/deps/openssl/openssl/apps/spkac.c
new file mode 100644
index 000000000..0e01ea994
--- /dev/null
+++ b/deps/openssl/openssl/apps/spkac.c
@@ -0,0 +1,308 @@
+/* apps/spkac.c */
+
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999. Based on an original idea by Massimiliano Pala
+ * (madwolf@openca.org).
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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
+ * licensing@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).
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/lhash.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG spkac_main
+
+/* -in arg - input file - default stdin
+ * -out arg - output file - default stdout
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ int i,badops=0, ret = 1;
+ BIO *in = NULL,*out = NULL;
+ int verify=0,noout=0,pubkey=0;
+ char *infile = NULL,*outfile = NULL,*prog;
+ char *passargin = NULL, *passin = NULL;
+ const char *spkac = "SPKAC", *spksect = "default";
+ char *spkstr = NULL;
+ char *challenge = NULL, *keyfile = NULL;
+ CONF *conf = NULL;
+ NETSCAPE_SPKI *spki = NULL;
+ EVP_PKEY *pkey = NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+
+ apps_startup();
+
+ if (!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ prog=argv[0];
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-passin") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargin= *(++argv);
+ }
+ else if (strcmp(*argv,"-key") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keyfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-challenge") == 0)
+ {
+ if (--argc < 1) goto bad;
+ challenge= *(++argv);
+ }
+ else if (strcmp(*argv,"-spkac") == 0)
+ {
+ if (--argc < 1) goto bad;
+ spkac= *(++argv);
+ }
+ else if (strcmp(*argv,"-spksect") == 0)
+ {
+ if (--argc < 1) goto bad;
+ spksect= *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-noout") == 0)
+ noout=1;
+ else if (strcmp(*argv,"-pubkey") == 0)
+ pubkey=1;
+ else if (strcmp(*argv,"-verify") == 0)
+ verify=1;
+ else badops = 1;
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ BIO_printf(bio_err,"%s [options]\n",prog);
+ BIO_printf(bio_err,"where options are\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -out arg output file\n");
+ BIO_printf(bio_err," -key arg create SPKAC using private key\n");
+ BIO_printf(bio_err," -passin arg input file pass phrase source\n");
+ BIO_printf(bio_err," -challenge arg challenge string\n");
+ BIO_printf(bio_err," -spkac arg alternative SPKAC name\n");
+ BIO_printf(bio_err," -noout don't print SPKAC\n");
+ BIO_printf(bio_err," -pubkey output public key\n");
+ BIO_printf(bio_err," -verify verify SPKAC signature\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
+#endif
+ goto end;
+ }
+
+ ERR_load_crypto_strings();
+ if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if(keyfile) {
+ pkey = load_key(bio_err,
+ strcmp(keyfile, "-") ? keyfile : NULL,
+ FORMAT_PEM, 1, passin, e, "private key");
+ if(!pkey) {
+ goto end;
+ }
+ spki = NETSCAPE_SPKI_new();
+ if(challenge) ASN1_STRING_set(spki->spkac->challenge,
+ challenge, (int)strlen(challenge));
+ NETSCAPE_SPKI_set_pubkey(spki, pkey);
+ NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
+ spkstr = NETSCAPE_SPKI_b64_encode(spki);
+
+ if (outfile) out = BIO_new_file(outfile, "w");
+ else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+
+ if(!out) {
+ BIO_printf(bio_err, "Error opening output file\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ BIO_printf(out, "SPKAC=%s\n", spkstr);
+ OPENSSL_free(spkstr);
+ ret = 0;
+ goto end;
+ }
+
+
+
+ if (infile) in = BIO_new_file(infile, "r");
+ else in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+ if(!in) {
+ BIO_printf(bio_err, "Error opening input file\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ conf = NCONF_new(NULL);
+ i = NCONF_load_bio(conf, in, NULL);
+
+ if(!i) {
+ BIO_printf(bio_err, "Error parsing config file\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ spkstr = NCONF_get_string(conf, spksect, spkac);
+
+ if(!spkstr) {
+ BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
+
+ if(!spki) {
+ BIO_printf(bio_err, "Error loading SPKAC\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (outfile) out = BIO_new_file(outfile, "w");
+ else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+
+ if(!out) {
+ BIO_printf(bio_err, "Error opening output file\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if(!noout) NETSCAPE_SPKI_print(out, spki);
+ pkey = NETSCAPE_SPKI_get_pubkey(spki);
+ if(verify) {
+ i = NETSCAPE_SPKI_verify(spki, pkey);
+ if (i > 0) BIO_printf(bio_err, "Signature OK\n");
+ else {
+ BIO_printf(bio_err, "Signature Failure\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ if(pubkey) PEM_write_bio_PUBKEY(out, pkey);
+
+ ret = 0;
+
+end:
+ NCONF_free(conf);
+ NETSCAPE_SPKI_free(spki);
+ BIO_free(in);
+ BIO_free_all(out);
+ EVP_PKEY_free(pkey);
+ if(passin) OPENSSL_free(passin);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
diff --git a/deps/openssl/openssl/apps/srp.c b/deps/openssl/openssl/apps/srp.c
new file mode 100644
index 000000000..9c7ae184d
--- /dev/null
+++ b/deps/openssl/openssl/apps/srp.c
@@ -0,0 +1,756 @@
+/* apps/srp.c */
+/* Written by Peter Sylvester (peter.sylvester@edelweb.fr)
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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
+ * licensing@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).
+ *
+ */
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_SRP
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/conf.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/txt_db.h>
+#include <openssl/buffer.h>
+#include <openssl/srp.h>
+
+#include "apps.h"
+
+#undef PROG
+#define PROG srp_main
+
+#define BASE_SECTION "srp"
+#define CONFIG_FILE "openssl.cnf"
+
+#define ENV_RANDFILE "RANDFILE"
+
+#define ENV_DATABASE "srpvfile"
+#define ENV_DEFAULT_SRP "default_srp"
+
+static char *srp_usage[]={
+"usage: srp [args] [user] \n",
+"\n",
+" -verbose Talk alot while doing things\n",
+" -config file A config file\n",
+" -name arg The particular srp definition to use\n",
+" -srpvfile arg The srp verifier file name\n",
+" -add add an user and srp verifier\n",
+" -modify modify the srp verifier of an existing user\n",
+" -delete delete user from verifier file\n",
+" -list list user\n",
+" -gn arg g and N values to be used for new verifier\n",
+" -userinfo arg additional info to be set for user\n",
+" -passin arg input file pass phrase source\n",
+" -passout arg output file pass phrase source\n",
+#ifndef OPENSSL_NO_ENGINE
+" -engine e - use engine e, possibly a hardware device.\n",
+#endif
+NULL
+};
+
+#ifdef EFENCE
+extern int EF_PROTECT_FREE;
+extern int EF_PROTECT_BELOW;
+extern int EF_ALIGNMENT;
+#endif
+
+static CONF *conf=NULL;
+static char *section=NULL;
+
+#define VERBOSE if (verbose)
+#define VVERBOSE if (verbose>1)
+
+
+int MAIN(int, char **);
+
+static int get_index(CA_DB *db, char* id, char type)
+ {
+ char ** pp;
+ int i;
+ if (id == NULL) return -1;
+ if (type == DB_SRP_INDEX)
+ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+ {
+ pp = sk_OPENSSL_PSTRING_value(db->db->data,i);
+ if (pp[DB_srptype][0] == DB_SRP_INDEX && !strcmp(id,pp[DB_srpid]))
+ return i;
+ }
+ else for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+ {
+ pp = sk_OPENSSL_PSTRING_value(db->db->data,i);
+
+ if (pp[DB_srptype][0] != DB_SRP_INDEX && !strcmp(id,pp[DB_srpid]))
+ return i;
+ }
+
+ return -1 ;
+ }
+
+static void print_entry(CA_DB *db, BIO *bio, int indx, int verbose, char *s)
+ {
+ if (indx >= 0 && verbose)
+ {
+ int j;
+ char **pp = sk_OPENSSL_PSTRING_value(db->db->data, indx);
+ BIO_printf(bio, "%s \"%s\"\n", s, pp[DB_srpid]);
+ for (j = 0; j < DB_NUMBER; j++)
+ {
+ BIO_printf(bio_err," %d = \"%s\"\n", j, pp[j]);
+ }
+ }
+ }
+
+static void print_index(CA_DB *db, BIO *bio, int indexindex, int verbose)
+ {
+ print_entry(db, bio, indexindex, verbose, "g N entry") ;
+ }
+
+static void print_user(CA_DB *db, BIO *bio, int userindex, int verbose)
+ {
+ if (verbose > 0)
+ {
+ char **pp = sk_OPENSSL_PSTRING_value(db->db->data,userindex);
+
+ if (pp[DB_srptype][0] != 'I')
+ {
+ print_entry(db, bio, userindex, verbose, "User entry");
+ print_entry(db, bio, get_index(db, pp[DB_srpgN], 'I'), verbose, "g N entry");
+ }
+
+ }
+ }
+
+static int update_index(CA_DB *db, BIO *bio, char **row)
+ {
+ char ** irow;
+ int i;
+
+ if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
+ {
+ BIO_printf(bio_err,"Memory allocation failure\n");
+ return 0;
+ }
+
+ for (i=0; i<DB_NUMBER; i++)
+ {
+ irow[i]=row[i];
+ row[i]=NULL;
+ }
+ irow[DB_NUMBER]=NULL;
+
+ if (!TXT_DB_insert(db->db,irow))
+ {
+ BIO_printf(bio,"failed to update srpvfile\n");
+ BIO_printf(bio,"TXT_DB error number %ld\n",db->db->error);
+ OPENSSL_free(irow);
+ return 0;
+ }
+ return 1;
+ }
+
+static void lookup_fail(const char *name, char *tag)
+ {
+ BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
+ }
+
+
+static char *srp_verify_user(const char *user, const char *srp_verifier,
+ char *srp_usersalt, const char *g, const char *N,
+ const char *passin, BIO *bio, int verbose)
+ {
+ char password[1024];
+ PW_CB_DATA cb_tmp;
+ char *verifier = NULL;
+ char *gNid = NULL;
+
+ cb_tmp.prompt_info = user;
+ cb_tmp.password = passin;
+
+ if (password_callback(password, 1024, 0, &cb_tmp) >0)
+ {
+ VERBOSE BIO_printf(bio,"Validating\n user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,srp_verifier,srp_usersalt, g, N);
+ BIO_printf(bio, "Pass %s\n", password);
+
+ if (!(gNid=SRP_create_verifier(user, password, &srp_usersalt, &verifier, N, g)))
+ {
+ BIO_printf(bio, "Internal error validating SRP verifier\n");
+ }
+ else
+ {
+ if (strcmp(verifier, srp_verifier))
+ gNid = NULL;
+ OPENSSL_free(verifier);
+ }
+ }
+ return gNid;
+ }
+
+static char *srp_create_user(char *user, char **srp_verifier,
+ char **srp_usersalt, char *g, char *N,
+ char *passout, BIO *bio, int verbose)
+ {
+ char password[1024];
+ PW_CB_DATA cb_tmp;
+ char *gNid = NULL;
+ char *salt = NULL;
+ cb_tmp.prompt_info = user;
+ cb_tmp.password = passout;
+
+ if (password_callback(password,1024,1,&cb_tmp) >0)
+ {
+ VERBOSE BIO_printf(bio,"Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,g,N);
+ if (!(gNid =SRP_create_verifier(user, password, &salt, srp_verifier, N, g)))
+ {
+ BIO_printf(bio,"Internal error creating SRP verifier\n");
+ }
+ else
+ *srp_usersalt = salt;
+ VVERBOSE BIO_printf(bio,"gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid,salt, *srp_verifier);
+
+ }
+ return gNid;
+ }
+
+int MAIN(int argc, char **argv)
+ {
+ int add_user = 0;
+ int list_user= 0;
+ int delete_user= 0;
+ int modify_user= 0;
+ char * user = NULL;
+
+ char *passargin = NULL, *passargout = NULL;
+ char *passin = NULL, *passout = NULL;
+ char * gN = NULL;
+ int gNindex = -1;
+ char ** gNrow = NULL;
+ int maxgN = -1;
+
+ char * userinfo = NULL;
+
+ int badops=0;
+ int ret=1;
+ int errors=0;
+ int verbose=0;
+ int doupdatedb=0;
+ char *configfile=NULL;
+ char *dbfile=NULL;
+ CA_DB *db=NULL;
+ char **pp ;
+ int i;
+ long errorline = -1;
+ char *randfile=NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine = NULL;
+#endif
+ char *tofree=NULL;
+ DB_ATTR db_attr;
+
+#ifdef EFENCE
+EF_PROTECT_FREE=1;
+EF_PROTECT_BELOW=1;
+EF_ALIGNMENT=0;
+#endif
+
+ apps_startup();
+
+ conf = NULL;
+ section = NULL;
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ argc--;
+ argv++;
+ while (argc >= 1 && badops == 0)
+ {
+ if (strcmp(*argv,"-verbose") == 0)
+ verbose++;
+ else if (strcmp(*argv,"-config") == 0)
+ {
+ if (--argc < 1) goto bad;
+ configfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-name") == 0)
+ {
+ if (--argc < 1) goto bad;
+ section= *(++argv);
+ }
+ else if (strcmp(*argv,"-srpvfile") == 0)
+ {
+ if (--argc < 1) goto bad;
+ dbfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-add") == 0)
+ add_user=1;
+ else if (strcmp(*argv,"-delete") == 0)
+ delete_user=1;
+ else if (strcmp(*argv,"-modify") == 0)
+ modify_user=1;
+ else if (strcmp(*argv,"-list") == 0)
+ list_user=1;
+ else if (strcmp(*argv,"-gn") == 0)
+ {
+ if (--argc < 1) goto bad;
+ gN= *(++argv);
+ }
+ else if (strcmp(*argv,"-userinfo") == 0)
+ {
+ if (--argc < 1) goto bad;
+ userinfo= *(++argv);
+ }
+ else if (strcmp(*argv,"-passin") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargin= *(++argv);
+ }
+ else if (strcmp(*argv,"-passout") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargout= *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+
+ else if (**argv == '-')
+ {
+bad:
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ else
+ break;
+
+ argc--;
+ argv++;
+ }
+
+ if (dbfile && configfile)
+ {
+ BIO_printf(bio_err,"-dbfile and -configfile cannot be specified together.\n");
+ badops = 1;
+ }
+ if (add_user+delete_user+modify_user+list_user != 1)
+ {
+ BIO_printf(bio_err,"Exactly one of the options -add, -delete, -modify -list must be specified.\n");
+ badops = 1;
+ }
+ if (delete_user+modify_user+delete_user== 1 && argc <= 0)
+ {
+ BIO_printf(bio_err,"Need at least one user for options -add, -delete, -modify. \n");
+ badops = 1;
+ }
+ if ((passin || passout) && argc != 1 )
+ {
+ BIO_printf(bio_err,"-passin, -passout arguments only valid with one user.\n");
+ badops = 1;
+ }
+
+ if (badops)
+ {
+ for (pp=srp_usage; (*pp != NULL); pp++)
+ BIO_printf(bio_err,"%s",*pp);
+
+ BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err," load the file (or the files in the directory) into\n");
+ BIO_printf(bio_err," the random number generator\n");
+ goto err;
+ }
+
+ ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+ setup_engine(bio_err, engine, 0);
+#endif
+
+ if(!app_passwd(bio_err, passargin, passargout, &passin, &passout))
+ {
+ BIO_printf(bio_err, "Error getting passwords\n");
+ goto err;
+ }
+
+ if (!dbfile)
+ {
+
+
+ /*****************************************************************/
+ tofree=NULL;
+ if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
+ if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
+ if (configfile == NULL)
+ {
+ const char *s=X509_get_default_cert_area();
+ size_t len;
+
+#ifdef OPENSSL_SYS_VMS
+ len = strlen(s)+sizeof(CONFIG_FILE);
+ tofree=OPENSSL_malloc(len);
+ strcpy(tofree,s);
+#else
+ len = strlen(s)+sizeof(CONFIG_FILE)+1;
+ tofree=OPENSSL_malloc(len);
+ BUF_strlcpy(tofree,s,len);
+ BUF_strlcat(tofree,"/",len);
+#endif
+ BUF_strlcat(tofree,CONFIG_FILE,len);
+ configfile=tofree;
+ }
+
+ VERBOSE BIO_printf(bio_err,"Using configuration from %s\n",configfile);
+ conf = NCONF_new(NULL);
+ if (NCONF_load(conf,configfile,&errorline) <= 0)
+ {
+ if (errorline <= 0)
+ BIO_printf(bio_err,"error loading the config file '%s'\n",
+ configfile);
+ else
+ BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
+ ,errorline,configfile);
+ goto err;
+ }
+ if(tofree)
+ {
+ OPENSSL_free(tofree);
+ tofree = NULL;
+ }
+
+ if (!load_config(bio_err, conf))
+ goto err;
+
+ /* Lets get the config section we are using */
+ if (section == NULL)
+ {
+ VERBOSE BIO_printf(bio_err,"trying to read " ENV_DEFAULT_SRP " in \" BASE_SECTION \"\n");
+
+ section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_SRP);
+ if (section == NULL)
+ {
+ lookup_fail(BASE_SECTION,ENV_DEFAULT_SRP);
+ goto err;
+ }
+ }
+
+ if (randfile == NULL && conf)
+ randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
+
+
+ VERBOSE BIO_printf(bio_err,"trying to read " ENV_DATABASE " in section \"%s\"\n",section);
+
+ if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
+ {
+ lookup_fail(section,ENV_DATABASE);
+ goto err;
+ }
+
+ }
+ if (randfile == NULL)
+ ERR_clear_error();
+ else
+ app_RAND_load_file(randfile, bio_err, 0);
+
+ VERBOSE BIO_printf(bio_err,"Trying to read SRP verifier file \"%s\"\n",dbfile);
+
+ db = load_index(dbfile, &db_attr);
+ if (db == NULL) goto err;
+
+ /* Lets check some fields */
+ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+ {
+ pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
+
+ if (pp[DB_srptype][0] == DB_SRP_INDEX)
+ {
+ maxgN = i;
+ if (gNindex < 0 && gN != NULL && !strcmp(gN, pp[DB_srpid]))
+ gNindex = i;
+
+ print_index(db, bio_err, i, verbose > 1);
+ }
+ }
+
+ VERBOSE BIO_printf(bio_err, "Database initialised\n");
+
+ if (gNindex >= 0)
+ {
+ gNrow = sk_OPENSSL_PSTRING_value(db->db->data,gNindex);
+ print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N");
+ }
+ else if (maxgN > 0 && !SRP_get_default_gN(gN))
+ {
+ BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN);
+ goto err;
+ }
+ else
+ {
+ VERBOSE BIO_printf(bio_err, "Database has no g N information.\n");
+ gNrow = NULL;
+ }
+
+
+ VVERBOSE BIO_printf(bio_err,"Starting user processing\n");
+
+ if (argc > 0)
+ user = *(argv++) ;
+
+ while (list_user || user)
+ {
+ int userindex = -1;
+ if (user)
+ VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n", user);
+ if ((userindex = get_index(db, user, 'U')) >= 0)
+ {
+ print_user(db, bio_err, userindex, (verbose > 0) || list_user);
+ }
+
+ if (list_user)
+ {
+ if (user == NULL)
+ {
+ BIO_printf(bio_err,"List all users\n");
+
+ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+ {
+ print_user(db,bio_err, i, 1);
+ }
+ list_user = 0;
+ }
+ else if (userindex < 0)
+ {
+ BIO_printf(bio_err, "user \"%s\" does not exist, ignored. t\n",
+ user);
+ errors++;
+ }
+ }
+ else if (add_user)
+ {
+ if (userindex >= 0)
+ {
+ /* reactivation of a new user */
+ char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+ BIO_printf(bio_err, "user \"%s\" reactivated.\n", user);
+ row[DB_srptype][0] = 'V';
+
+ doupdatedb = 1;
+ }
+ else
+ {
+ char *row[DB_NUMBER] ; char *gNid;
+ row[DB_srpverifier] = NULL;
+ row[DB_srpsalt] = NULL;
+ row[DB_srpinfo] = NULL;
+ if (!(gNid = srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:gN,gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
+ {
+ BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned .\n", user);
+ errors++;
+ goto err;
+ }
+ row[DB_srpid] = BUF_strdup(user);
+ row[DB_srptype] = BUF_strdup("v");
+ row[DB_srpgN] = BUF_strdup(gNid);
+
+ if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
+ (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))) ||
+ !update_index(db, bio_err, row))
+ {
+ if (row[DB_srpid]) OPENSSL_free(row[DB_srpid]);
+ if (row[DB_srpgN]) OPENSSL_free(row[DB_srpgN]);
+ if (row[DB_srpinfo]) OPENSSL_free(row[DB_srpinfo]);
+ if (row[DB_srptype]) OPENSSL_free(row[DB_srptype]);
+ if (row[DB_srpverifier]) OPENSSL_free(row[DB_srpverifier]);
+ if (row[DB_srpsalt]) OPENSSL_free(row[DB_srpsalt]);
+ goto err;
+ }
+ doupdatedb = 1;
+ }
+ }
+ else if (modify_user)
+ {
+ if (userindex < 0)
+ {
+ BIO_printf(bio_err,"user \"%s\" does not exist, operation ignored.\n",user);
+ errors++;
+ }
+ else
+ {
+
+ char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+ char type = row[DB_srptype][0];
+ if (type == 'v')
+ {
+ BIO_printf(bio_err,"user \"%s\" already updated, operation ignored.\n",user);
+ errors++;
+ }
+ else
+ {
+ char *gNid;
+
+ if (row[DB_srptype][0] == 'V')
+ {
+ int user_gN;
+ char **irow = NULL;
+ VERBOSE BIO_printf(bio_err,"Verifying password for user \"%s\"\n",user);
+ if ( (user_gN = get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0)
+ irow = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+
+ if (!srp_verify_user(user, row[DB_srpverifier], row[DB_srpsalt], irow ? irow[DB_srpsalt] : row[DB_srpgN], irow ? irow[DB_srpverifier] : NULL, passin, bio_err, verbose))
+ {
+ BIO_printf(bio_err, "Invalid password for user \"%s\", operation abandoned.\n", user);
+ errors++;
+ goto err;
+ }
+ }
+ VERBOSE BIO_printf(bio_err,"Password for user \"%s\" ok.\n",user);
+
+ if (!(gNid=srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:NULL, gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
+ {
+ BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned.\n", user);
+ errors++;
+ goto err;
+ }
+
+ row[DB_srptype][0] = 'v';
+ row[DB_srpgN] = BUF_strdup(gNid);
+
+ if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
+ (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))))
+ goto err;
+
+ doupdatedb = 1;
+ }
+ }
+ }
+ else if (delete_user)
+ {
+ if (userindex < 0)
+ {
+ BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored. t\n", user);
+ errors++;
+ }
+ else
+ {
+ char **xpp = sk_OPENSSL_PSTRING_value(db->db->data,userindex);
+ BIO_printf(bio_err, "user \"%s\" revoked. t\n", user);
+
+ xpp[DB_srptype][0] = 'R';
+
+ doupdatedb = 1;
+ }
+ }
+ if (--argc > 0)
+ user = *(argv++) ;
+ else
+ {
+ user = NULL;
+ list_user = 0;
+ }
+ }
+
+ VERBOSE BIO_printf(bio_err,"User procession done.\n");
+
+
+ if (doupdatedb)
+ {
+ /* Lets check some fields */
+ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+ {
+ pp = sk_OPENSSL_PSTRING_value(db->db->data,i);
+
+ if (pp[DB_srptype][0] == 'v')
+ {
+ pp[DB_srptype][0] = 'V';
+ print_user(db, bio_err, i, verbose);
+ }
+ }
+
+ VERBOSE BIO_printf(bio_err, "Trying to update srpvfile.\n");
+ if (!save_index(dbfile, "new", db)) goto err;
+
+ VERBOSE BIO_printf(bio_err, "Temporary srpvfile created.\n");
+ if (!rotate_index(dbfile, "new", "old")) goto err;
+
+ VERBOSE BIO_printf(bio_err, "srpvfile updated.\n");
+ }
+
+ ret = (errors != 0);
+err:
+ if (errors != 0)
+ VERBOSE BIO_printf(bio_err,"User errors %d.\n",errors);
+
+ VERBOSE BIO_printf(bio_err,"SRP terminating with code %d.\n",ret);
+ if(tofree)
+ OPENSSL_free(tofree);
+ if (ret) ERR_print_errors(bio_err);
+ if (randfile) app_RAND_write_file(randfile, bio_err);
+ if (conf) NCONF_free(conf);
+ if (db) free_index(db);
+
+ OBJ_cleanup();
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+
+
+#endif
+
diff --git a/deps/openssl/openssl/apps/testCA.pem b/deps/openssl/openssl/apps/testCA.pem
new file mode 100644
index 000000000..dcb710aa9
--- /dev/null
+++ b/deps/openssl/openssl/apps/testCA.pem
@@ -0,0 +1,8 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBBzCBsgIBADBNMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEX
+MBUGA1UEChMOTWluY29tIFB0eSBMdGQxEDAOBgNVBAMTB1RFU1QgQ0EwXDANBgkq
+hkiG9w0BAQEFAANLADBIAkEAzW9brgA8efT2ODB+NrsflJZj3KKqKsm4OrXTRqfL
+VETj1ws/zCXl42XJAxdWQMCP0liKfc9Ut4xi1qCVI7N07wIDAQABoAAwDQYJKoZI
+hvcNAQEEBQADQQBjZZ42Det9Uw0AFwJy4ufUEy5Cv74pxBp5SZnljgHY+Az0Hs2S
+uNkIegr2ITX5azKi9nOkg9ZmsmGG13FIjiC/
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/openssl/openssl/apps/testdsa.h b/deps/openssl/openssl/apps/testdsa.h
new file mode 100644
index 000000000..9e84e31c9
--- /dev/null
+++ b/deps/openssl/openssl/apps/testdsa.h
@@ -0,0 +1,217 @@
+/* NOCW */
+/* used by apps/speed.c */
+DSA *get_dsa512(void );
+DSA *get_dsa1024(void );
+DSA *get_dsa2048(void );
+static unsigned char dsa512_priv[] = {
+ 0x65,0xe5,0xc7,0x38,0x60,0x24,0xb5,0x89,0xd4,0x9c,0xeb,0x4c,
+ 0x9c,0x1d,0x7a,0x22,0xbd,0xd1,0xc2,0xd2,
+ };
+static unsigned char dsa512_pub[] = {
+ 0x00,0x95,0xa7,0x0d,0xec,0x93,0x68,0xba,0x5f,0xf7,0x5f,0x07,
+ 0xf2,0x3b,0xad,0x6b,0x01,0xdc,0xbe,0xec,0xde,0x04,0x7a,0x3a,
+ 0x27,0xb3,0xec,0x49,0xfd,0x08,0x43,0x3d,0x7e,0xa8,0x2c,0x5e,
+ 0x7b,0xbb,0xfc,0xf4,0x6e,0xeb,0x6c,0xb0,0x6e,0xf8,0x02,0x12,
+ 0x8c,0x38,0x5d,0x83,0x56,0x7d,0xee,0x53,0x05,0x3e,0x24,0x84,
+ 0xbe,0xba,0x0a,0x6b,0xc8,
+ };
+static unsigned char dsa512_p[]={
+ 0x9D,0x1B,0x69,0x8E,0x26,0xDB,0xF2,0x2B,0x11,0x70,0x19,0x86,
+ 0xF6,0x19,0xC8,0xF8,0x19,0xF2,0x18,0x53,0x94,0x46,0x06,0xD0,
+ 0x62,0x50,0x33,0x4B,0x02,0x3C,0x52,0x30,0x03,0x8B,0x3B,0xF9,
+ 0x5F,0xD1,0x24,0x06,0x4F,0x7B,0x4C,0xBA,0xAA,0x40,0x9B,0xFD,
+ 0x96,0xE4,0x37,0x33,0xBB,0x2D,0x5A,0xD7,0x5A,0x11,0x40,0x66,
+ 0xA2,0x76,0x7D,0x31,
+ };
+static unsigned char dsa512_q[]={
+ 0xFB,0x53,0xEF,0x50,0xB4,0x40,0x92,0x31,0x56,0x86,0x53,0x7A,
+ 0xE8,0x8B,0x22,0x9A,0x49,0xFB,0x71,0x8F,
+ };
+static unsigned char dsa512_g[]={
+ 0x83,0x3E,0x88,0xE5,0xC5,0x89,0x73,0xCE,0x3B,0x6C,0x01,0x49,
+ 0xBF,0xB3,0xC7,0x9F,0x0A,0xEA,0x44,0x91,0xE5,0x30,0xAA,0xD9,
+ 0xBE,0x5B,0x5F,0xB7,0x10,0xD7,0x89,0xB7,0x8E,0x74,0xFB,0xCF,
+ 0x29,0x1E,0xEB,0xA8,0x2C,0x54,0x51,0xB8,0x10,0xDE,0xA0,0xCE,
+ 0x2F,0xCC,0x24,0x6B,0x90,0x77,0xDE,0xA2,0x68,0xA6,0x52,0x12,
+ 0xA2,0x03,0x9D,0x20,
+ };
+
+DSA *get_dsa512()
+ {
+ DSA *dsa;
+
+ if ((dsa=DSA_new()) == NULL) return(NULL);
+ dsa->priv_key=BN_bin2bn(dsa512_priv,sizeof(dsa512_priv),NULL);
+ dsa->pub_key=BN_bin2bn(dsa512_pub,sizeof(dsa512_pub),NULL);
+ dsa->p=BN_bin2bn(dsa512_p,sizeof(dsa512_p),NULL);
+ dsa->q=BN_bin2bn(dsa512_q,sizeof(dsa512_q),NULL);
+ dsa->g=BN_bin2bn(dsa512_g,sizeof(dsa512_g),NULL);
+ if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) ||
+ (dsa->q == NULL) || (dsa->g == NULL))
+ return(NULL);
+ return(dsa);
+ }
+
+static unsigned char dsa1024_priv[]={
+ 0x7d,0x21,0xda,0xbb,0x62,0x15,0x47,0x36,0x07,0x67,0x12,0xe8,
+ 0x8c,0xaa,0x1c,0xcd,0x38,0x12,0x61,0x18,
+ };
+static unsigned char dsa1024_pub[]={
+ 0x3c,0x4e,0x9c,0x2a,0x7f,0x16,0xc1,0x25,0xeb,0xac,0x78,0x63,
+ 0x90,0x14,0x8c,0x8b,0xf4,0x68,0x43,0x3c,0x2d,0xee,0x65,0x50,
+ 0x7d,0x9c,0x8f,0x8c,0x8a,0x51,0xd6,0x11,0x2b,0x99,0xaf,0x1e,
+ 0x90,0x97,0xb5,0xd3,0xa6,0x20,0x25,0xd6,0xfe,0x43,0x02,0xd5,
+ 0x91,0x7d,0xa7,0x8c,0xdb,0xc9,0x85,0xa3,0x36,0x48,0xf7,0x68,
+ 0xaa,0x60,0xb1,0xf7,0x05,0x68,0x3a,0xa3,0x3f,0xd3,0x19,0x82,
+ 0xd8,0x82,0x7a,0x77,0xfb,0xef,0xf4,0x15,0x0a,0xeb,0x06,0x04,
+ 0x7f,0x53,0x07,0x0c,0xbc,0xcb,0x2d,0x83,0xdb,0x3e,0xd1,0x28,
+ 0xa5,0xa1,0x31,0xe0,0x67,0xfa,0x50,0xde,0x9b,0x07,0x83,0x7e,
+ 0x2c,0x0b,0xc3,0x13,0x50,0x61,0xe5,0xad,0xbd,0x36,0xb8,0x97,
+ 0x4e,0x40,0x7d,0xe8,0x83,0x0d,0xbc,0x4b
+ };
+static unsigned char dsa1024_p[]={
+ 0xA7,0x3F,0x6E,0x85,0xBF,0x41,0x6A,0x29,0x7D,0xF0,0x9F,0x47,
+ 0x19,0x30,0x90,0x9A,0x09,0x1D,0xDA,0x6A,0x33,0x1E,0xC5,0x3D,
+ 0x86,0x96,0xB3,0x15,0xE0,0x53,0x2E,0x8F,0xE0,0x59,0x82,0x73,
+ 0x90,0x3E,0x75,0x31,0x99,0x47,0x7A,0x52,0xFB,0x85,0xE4,0xD9,
+ 0xA6,0x7B,0x38,0x9B,0x68,0x8A,0x84,0x9B,0x87,0xC6,0x1E,0xB5,
+ 0x7E,0x86,0x4B,0x53,0x5B,0x59,0xCF,0x71,0x65,0x19,0x88,0x6E,
+ 0xCE,0x66,0xAE,0x6B,0x88,0x36,0xFB,0xEC,0x28,0xDC,0xC2,0xD7,
+ 0xA5,0xBB,0xE5,0x2C,0x39,0x26,0x4B,0xDA,0x9A,0x70,0x18,0x95,
+ 0x37,0x95,0x10,0x56,0x23,0xF6,0x15,0xED,0xBA,0x04,0x5E,0xDE,
+ 0x39,0x4F,0xFD,0xB7,0x43,0x1F,0xB5,0xA4,0x65,0x6F,0xCD,0x80,
+ 0x11,0xE4,0x70,0x95,0x5B,0x50,0xCD,0x49,
+ };
+static unsigned char dsa1024_q[]={
+ 0xF7,0x07,0x31,0xED,0xFA,0x6C,0x06,0x03,0xD5,0x85,0x8A,0x1C,
+ 0xAC,0x9C,0x65,0xE7,0x50,0x66,0x65,0x6F,
+ };
+static unsigned char dsa1024_g[]={
+ 0x4D,0xDF,0x4C,0x03,0xA6,0x91,0x8A,0xF5,0x19,0x6F,0x50,0x46,
+ 0x25,0x99,0xE5,0x68,0x6F,0x30,0xE3,0x69,0xE1,0xE5,0xB3,0x5D,
+ 0x98,0xBB,0x28,0x86,0x48,0xFC,0xDE,0x99,0x04,0x3F,0x5F,0x88,
+ 0x0C,0x9C,0x73,0x24,0x0D,0x20,0x5D,0xB9,0x2A,0x9A,0x3F,0x18,
+ 0x96,0x27,0xE4,0x62,0x87,0xC1,0x7B,0x74,0x62,0x53,0xFC,0x61,
+ 0x27,0xA8,0x7A,0x91,0x09,0x9D,0xB6,0xF1,0x4D,0x9C,0x54,0x0F,
+ 0x58,0x06,0xEE,0x49,0x74,0x07,0xCE,0x55,0x7E,0x23,0xCE,0x16,
+ 0xF6,0xCA,0xDC,0x5A,0x61,0x01,0x7E,0xC9,0x71,0xB5,0x4D,0xF6,
+ 0xDC,0x34,0x29,0x87,0x68,0xF6,0x5E,0x20,0x93,0xB3,0xDB,0xF5,
+ 0xE4,0x09,0x6C,0x41,0x17,0x95,0x92,0xEB,0x01,0xB5,0x73,0xA5,
+ 0x6A,0x7E,0xD8,0x32,0xED,0x0E,0x02,0xB8,
+ };
+
+DSA *get_dsa1024()
+ {
+ DSA *dsa;
+
+ if ((dsa=DSA_new()) == NULL) return(NULL);
+ dsa->priv_key=BN_bin2bn(dsa1024_priv,sizeof(dsa1024_priv),NULL);
+ dsa->pub_key=BN_bin2bn(dsa1024_pub,sizeof(dsa1024_pub),NULL);
+ dsa->p=BN_bin2bn(dsa1024_p,sizeof(dsa1024_p),NULL);
+ dsa->q=BN_bin2bn(dsa1024_q,sizeof(dsa1024_q),NULL);
+ dsa->g=BN_bin2bn(dsa1024_g,sizeof(dsa1024_g),NULL);
+ if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) ||
+ (dsa->q == NULL) || (dsa->g == NULL))
+ return(NULL);
+ return(dsa);
+ }
+
+static unsigned char dsa2048_priv[]={
+ 0x32,0x67,0x92,0xf6,0xc4,0xe2,0xe2,0xe8,0xa0,0x8b,0x6b,0x45,
+ 0x0c,0x8a,0x76,0xb0,0xee,0xcf,0x91,0xa7,
+ };
+static unsigned char dsa2048_pub[]={
+ 0x17,0x8f,0xa8,0x11,0x84,0x92,0xec,0x83,0x47,0xc7,0x6a,0xb0,
+ 0x92,0xaf,0x5a,0x20,0x37,0xa3,0x64,0x79,0xd2,0xd0,0x3d,0xcd,
+ 0xe0,0x61,0x88,0x88,0x21,0xcc,0x74,0x5d,0xce,0x4c,0x51,0x47,
+ 0xf0,0xc5,0x5c,0x4c,0x82,0x7a,0xaf,0x72,0xad,0xb9,0xe0,0x53,
+ 0xf2,0x78,0xb7,0xf0,0xb5,0x48,0x7f,0x8a,0x3a,0x18,0xd1,0x9f,
+ 0x8b,0x7d,0xa5,0x47,0xb7,0x95,0xab,0x98,0xf8,0x7b,0x74,0x50,
+ 0x56,0x8e,0x57,0xf0,0xee,0xf5,0xb7,0xba,0xab,0x85,0x86,0xf9,
+ 0x2b,0xef,0x41,0x56,0xa0,0xa4,0x9f,0xb7,0x38,0x00,0x46,0x0a,
+ 0xa6,0xf1,0xfc,0x1f,0xd8,0x4e,0x85,0x44,0x92,0x43,0x21,0x5d,
+ 0x6e,0xcc,0xc2,0xcb,0x26,0x31,0x0d,0x21,0xc4,0xbd,0x8d,0x24,
+ 0xbc,0xd9,0x18,0x19,0xd7,0xdc,0xf1,0xe7,0x93,0x50,0x48,0x03,
+ 0x2c,0xae,0x2e,0xe7,0x49,0x88,0x5f,0x93,0x57,0x27,0x99,0x36,
+ 0xb4,0x20,0xab,0xfc,0xa7,0x2b,0xf2,0xd9,0x98,0xd7,0xd4,0x34,
+ 0x9d,0x96,0x50,0x58,0x9a,0xea,0x54,0xf3,0xee,0xf5,0x63,0x14,
+ 0xee,0x85,0x83,0x74,0x76,0xe1,0x52,0x95,0xc3,0xf7,0xeb,0x04,
+ 0x04,0x7b,0xa7,0x28,0x1b,0xcc,0xea,0x4a,0x4e,0x84,0xda,0xd8,
+ 0x9c,0x79,0xd8,0x9b,0x66,0x89,0x2f,0xcf,0xac,0xd7,0x79,0xf9,
+ 0xa9,0xd8,0x45,0x13,0x78,0xb9,0x00,0x14,0xc9,0x7e,0x22,0x51,
+ 0x86,0x67,0xb0,0x9f,0x26,0x11,0x23,0xc8,0x38,0xd7,0x70,0x1d,
+ 0x15,0x8e,0x4d,0x4f,0x95,0x97,0x40,0xa1,0xc2,0x7e,0x01,0x18,
+ 0x72,0xf4,0x10,0xe6,0x8d,0x52,0x16,0x7f,0xf2,0xc9,0xf8,0x33,
+ 0x8b,0x33,0xb7,0xce,
+ };
+static unsigned char dsa2048_p[]={
+ 0xA0,0x25,0xFA,0xAD,0xF4,0x8E,0xB9,0xE5,0x99,0xF3,0x5D,0x6F,
+ 0x4F,0x83,0x34,0xE2,0x7E,0xCF,0x6F,0xBF,0x30,0xAF,0x6F,0x81,
+ 0xEB,0xF8,0xC4,0x13,0xD9,0xA0,0x5D,0x8B,0x5C,0x8E,0xDC,0xC2,
+ 0x1D,0x0B,0x41,0x32,0xB0,0x1F,0xFE,0xEF,0x0C,0xC2,0xA2,0x7E,
+ 0x68,0x5C,0x28,0x21,0xE9,0xF5,0xB1,0x58,0x12,0x63,0x4C,0x19,
+ 0x4E,0xFF,0x02,0x4B,0x92,0xED,0xD2,0x07,0x11,0x4D,0x8C,0x58,
+ 0x16,0x5C,0x55,0x8E,0xAD,0xA3,0x67,0x7D,0xB9,0x86,0x6E,0x0B,
+ 0xE6,0x54,0x6F,0x40,0xAE,0x0E,0x67,0x4C,0xF9,0x12,0x5B,0x3C,
+ 0x08,0x7A,0xF7,0xFC,0x67,0x86,0x69,0xE7,0x0A,0x94,0x40,0xBF,
+ 0x8B,0x76,0xFE,0x26,0xD1,0xF2,0xA1,0x1A,0x84,0xA1,0x43,0x56,
+ 0x28,0xBC,0x9A,0x5F,0xD7,0x3B,0x69,0x89,0x8A,0x36,0x2C,0x51,
+ 0xDF,0x12,0x77,0x2F,0x57,0x7B,0xA0,0xAA,0xDD,0x7F,0xA1,0x62,
+ 0x3B,0x40,0x7B,0x68,0x1A,0x8F,0x0D,0x38,0xBB,0x21,0x5D,0x18,
+ 0xFC,0x0F,0x46,0xF7,0xA3,0xB0,0x1D,0x23,0xC3,0xD2,0xC7,0x72,
+ 0x51,0x18,0xDF,0x46,0x95,0x79,0xD9,0xBD,0xB5,0x19,0x02,0x2C,
+ 0x87,0xDC,0xE7,0x57,0x82,0x7E,0xF1,0x8B,0x06,0x3D,0x00,0xA5,
+ 0x7B,0x6B,0x26,0x27,0x91,0x0F,0x6A,0x77,0xE4,0xD5,0x04,0xE4,
+ 0x12,0x2C,0x42,0xFF,0xD2,0x88,0xBB,0xD3,0x92,0xA0,0xF9,0xC8,
+ 0x51,0x64,0x14,0x5C,0xD8,0xF9,0x6C,0x47,0x82,0xB4,0x1C,0x7F,
+ 0x09,0xB8,0xF0,0x25,0x83,0x1D,0x3F,0x3F,0x05,0xB3,0x21,0x0A,
+ 0x5D,0xA7,0xD8,0x54,0xC3,0x65,0x7D,0xC3,0xB0,0x1D,0xBF,0xAE,
+ 0xF8,0x68,0xCF,0x9B,
+ };
+static unsigned char dsa2048_q[]={
+ 0x97,0xE7,0x33,0x4D,0xD3,0x94,0x3E,0x0B,0xDB,0x62,0x74,0xC6,
+ 0xA1,0x08,0xDD,0x19,0xA3,0x75,0x17,0x1B,
+ };
+static unsigned char dsa2048_g[]={
+ 0x2C,0x78,0x16,0x59,0x34,0x63,0xF4,0xF3,0x92,0xFC,0xB5,0xA5,
+ 0x4F,0x13,0xDE,0x2F,0x1C,0xA4,0x3C,0xAE,0xAD,0x38,0x3F,0x7E,
+ 0x90,0xBF,0x96,0xA6,0xAE,0x25,0x90,0x72,0xF5,0x8E,0x80,0x0C,
+ 0x39,0x1C,0xD9,0xEC,0xBA,0x90,0x5B,0x3A,0xE8,0x58,0x6C,0x9E,
+ 0x30,0x42,0x37,0x02,0x31,0x82,0xBC,0x6A,0xDF,0x6A,0x09,0x29,
+ 0xE3,0xC0,0x46,0xD1,0xCB,0x85,0xEC,0x0C,0x30,0x5E,0xEA,0xC8,
+ 0x39,0x8E,0x22,0x9F,0x22,0x10,0xD2,0x34,0x61,0x68,0x37,0x3D,
+ 0x2E,0x4A,0x5B,0x9A,0xF5,0xC1,0x48,0xC6,0xF6,0xDC,0x63,0x1A,
+ 0xD3,0x96,0x64,0xBA,0x34,0xC9,0xD1,0xA0,0xD1,0xAE,0x6C,0x2F,
+ 0x48,0x17,0x93,0x14,0x43,0xED,0xF0,0x21,0x30,0x19,0xC3,0x1B,
+ 0x5F,0xDE,0xA3,0xF0,0x70,0x78,0x18,0xE1,0xA8,0xE4,0xEE,0x2E,
+ 0x00,0xA5,0xE4,0xB3,0x17,0xC8,0x0C,0x7D,0x6E,0x42,0xDC,0xB7,
+ 0x46,0x00,0x36,0x4D,0xD4,0x46,0xAA,0x3D,0x3C,0x46,0x89,0x40,
+ 0xBF,0x1D,0x84,0x77,0x0A,0x75,0xF3,0x87,0x1D,0x08,0x4C,0xA6,
+ 0xD1,0xA9,0x1C,0x1E,0x12,0x1E,0xE1,0xC7,0x30,0x28,0x76,0xA5,
+ 0x7F,0x6C,0x85,0x96,0x2B,0x6F,0xDB,0x80,0x66,0x26,0xAE,0xF5,
+ 0x93,0xC7,0x8E,0xAE,0x9A,0xED,0xE4,0xCA,0x04,0xEA,0x3B,0x72,
+ 0xEF,0xDC,0x87,0xED,0x0D,0xA5,0x4C,0x4A,0xDD,0x71,0x22,0x64,
+ 0x59,0x69,0x4E,0x8E,0xBF,0x43,0xDC,0xAB,0x8E,0x66,0xBB,0x01,
+ 0xB6,0xF4,0xE7,0xFD,0xD2,0xAD,0x9F,0x36,0xC1,0xA0,0x29,0x99,
+ 0xD1,0x96,0x70,0x59,0x06,0x78,0x35,0xBD,0x65,0x55,0x52,0x9E,
+ 0xF8,0xB2,0xE5,0x38,
+ };
+
+DSA *get_dsa2048()
+ {
+ DSA *dsa;
+
+ if ((dsa=DSA_new()) == NULL) return(NULL);
+ dsa->priv_key=BN_bin2bn(dsa2048_priv,sizeof(dsa2048_priv),NULL);
+ dsa->pub_key=BN_bin2bn(dsa2048_pub,sizeof(dsa2048_pub),NULL);
+ dsa->p=BN_bin2bn(dsa2048_p,sizeof(dsa2048_p),NULL);
+ dsa->q=BN_bin2bn(dsa2048_q,sizeof(dsa2048_q),NULL);
+ dsa->g=BN_bin2bn(dsa2048_g,sizeof(dsa2048_g),NULL);
+ if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) ||
+ (dsa->q == NULL) || (dsa->g == NULL))
+ return(NULL);
+ return(dsa);
+ }
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+static int rnd_fake = 0;
diff --git a/deps/openssl/openssl/apps/testrsa.h b/deps/openssl/openssl/apps/testrsa.h
new file mode 100644
index 000000000..3007d792b
--- /dev/null
+++ b/deps/openssl/openssl/apps/testrsa.h
@@ -0,0 +1,518 @@
+/* apps/testrsa.h */
+/* used by apps/speed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+static unsigned char test512[]={
+ 0x30,0x82,0x01,0x3a,0x02,0x01,0x00,0x02,0x41,0x00,
+ 0xd6,0x33,0xb9,0xc8,0xfb,0x4f,0x3c,0x7d,0xc0,0x01,
+ 0x86,0xd0,0xe7,0xa0,0x55,0xf2,0x95,0x93,0xcc,0x4f,
+ 0xb7,0x5b,0x67,0x5b,0x94,0x68,0xc9,0x34,0x15,0xde,
+ 0xa5,0x2e,0x1c,0x33,0xc2,0x6e,0xfc,0x34,0x5e,0x71,
+ 0x13,0xb7,0xd6,0xee,0xd8,0xa5,0x65,0x05,0x72,0x87,
+ 0xa8,0xb0,0x77,0xfe,0x57,0xf5,0xfc,0x5f,0x55,0x83,
+ 0x87,0xdd,0x57,0x49,0x02,0x03,0x01,0x00,0x01,0x02,
+ 0x41,0x00,0xa7,0xf7,0x91,0xc5,0x0f,0x84,0x57,0xdc,
+ 0x07,0xf7,0x6a,0x7f,0x60,0x52,0xb3,0x72,0xf1,0x66,
+ 0x1f,0x7d,0x97,0x3b,0x9e,0xb6,0x0a,0x8f,0x8c,0xcf,
+ 0x42,0x23,0x00,0x04,0xd4,0x28,0x0e,0x1c,0x90,0xc4,
+ 0x11,0x25,0x25,0xa5,0x93,0xa5,0x2f,0x70,0x02,0xdf,
+ 0x81,0x9c,0x49,0x03,0xa0,0xf8,0x6d,0x54,0x2e,0x26,
+ 0xde,0xaa,0x85,0x59,0xa8,0x31,0x02,0x21,0x00,0xeb,
+ 0x47,0xd7,0x3b,0xf6,0xc3,0xdd,0x5a,0x46,0xc5,0xb9,
+ 0x2b,0x9a,0xa0,0x09,0x8f,0xa6,0xfb,0xf3,0x78,0x7a,
+ 0x33,0x70,0x9d,0x0f,0x42,0x6b,0x13,0x68,0x24,0xd3,
+ 0x15,0x02,0x21,0x00,0xe9,0x10,0xb0,0xb3,0x0d,0xe2,
+ 0x82,0x68,0x77,0x8a,0x6e,0x7c,0xda,0xbc,0x3e,0x53,
+ 0x83,0xfb,0xd6,0x22,0xe7,0xb5,0xae,0x6e,0x80,0xda,
+ 0x00,0x55,0x97,0xc1,0xd0,0x65,0x02,0x20,0x4c,0xf8,
+ 0x73,0xb1,0x6a,0x49,0x29,0x61,0x1f,0x46,0x10,0x0d,
+ 0xf3,0xc7,0xe7,0x58,0xd7,0x88,0x15,0x5e,0x94,0x9b,
+ 0xbf,0x7b,0xa2,0x42,0x58,0x45,0x41,0x0c,0xcb,0x01,
+ 0x02,0x20,0x12,0x11,0xba,0x31,0x57,0x9d,0x3d,0x11,
+ 0x0e,0x5b,0x8c,0x2f,0x5f,0xe2,0x02,0x4f,0x05,0x47,
+ 0x8c,0x15,0x8e,0xb3,0x56,0x3f,0xb8,0xfb,0xad,0xd4,
+ 0xf4,0xfc,0x10,0xc5,0x02,0x20,0x18,0xa1,0x29,0x99,
+ 0x5b,0xd9,0xc8,0xd4,0xfc,0x49,0x7a,0x2a,0x21,0x2c,
+ 0x49,0xe4,0x4f,0xeb,0xef,0x51,0xf1,0xab,0x6d,0xfb,
+ 0x4b,0x14,0xe9,0x4b,0x52,0xb5,0x82,0x2c,
+ };
+
+static unsigned char test1024[]={
+ 0x30,0x82,0x02,0x5c,0x02,0x01,0x00,0x02,0x81,0x81,
+ 0x00,0xdc,0x98,0x43,0xe8,0x3d,0x43,0x5b,0xe4,0x05,
+ 0xcd,0xd0,0xa9,0x3e,0xcb,0x83,0x75,0xf6,0xb5,0xa5,
+ 0x9f,0x6b,0xe9,0x34,0x41,0x29,0x18,0xfa,0x6a,0x55,
+ 0x4d,0x70,0xfc,0xec,0xae,0x87,0x38,0x0a,0x20,0xa9,
+ 0xc0,0x45,0x77,0x6e,0x57,0x60,0x57,0xf4,0xed,0x96,
+ 0x22,0xcb,0x8f,0xe1,0x33,0x3a,0x17,0x1f,0xed,0x37,
+ 0xa5,0x6f,0xeb,0xa6,0xbc,0x12,0x80,0x1d,0x53,0xbd,
+ 0x70,0xeb,0x21,0x76,0x3e,0xc9,0x2f,0x1a,0x45,0x24,
+ 0x82,0xff,0xcd,0x59,0x32,0x06,0x2e,0x12,0x3b,0x23,
+ 0x78,0xed,0x12,0x3d,0xe0,0x8d,0xf9,0x67,0x4f,0x37,
+ 0x4e,0x47,0x02,0x4c,0x2d,0xc0,0x4f,0x1f,0xb3,0x94,
+ 0xe1,0x41,0x2e,0x2d,0x90,0x10,0xfc,0x82,0x91,0x8b,
+ 0x0f,0x22,0xd4,0xf2,0xfc,0x2c,0xab,0x53,0x55,0x02,
+ 0x03,0x01,0x00,0x01,0x02,0x81,0x80,0x2b,0xcc,0x3f,
+ 0x8f,0x58,0xba,0x8b,0x00,0x16,0xf6,0xea,0x3a,0xf0,
+ 0x30,0xd0,0x05,0x17,0xda,0xb0,0xeb,0x9a,0x2d,0x4f,
+ 0x26,0xb0,0xd6,0x38,0xc1,0xeb,0xf5,0xd8,0x3d,0x1f,
+ 0x70,0xf7,0x7f,0xf4,0xe2,0xcf,0x51,0x51,0x79,0x88,
+ 0xfa,0xe8,0x32,0x0e,0x7b,0x2d,0x97,0xf2,0xfa,0xba,
+ 0x27,0xc5,0x9c,0xd9,0xc5,0xeb,0x8a,0x79,0x52,0x3c,
+ 0x64,0x34,0x7d,0xc2,0xcf,0x28,0xc7,0x4e,0xd5,0x43,
+ 0x0b,0xd1,0xa6,0xca,0x6d,0x03,0x2d,0x72,0x23,0xbc,
+ 0x6d,0x05,0xfa,0x16,0x09,0x2f,0x2e,0x5c,0xb6,0xee,
+ 0x74,0xdd,0xd2,0x48,0x8e,0x36,0x0c,0x06,0x3d,0x4d,
+ 0xe5,0x10,0x82,0xeb,0x6a,0xf3,0x4b,0x9f,0xd6,0xed,
+ 0x11,0xb1,0x6e,0xec,0xf4,0xfe,0x8e,0x75,0x94,0x20,
+ 0x2f,0xcb,0xac,0x46,0xf1,0x02,0x41,0x00,0xf9,0x8c,
+ 0xa3,0x85,0xb1,0xdd,0x29,0xaf,0x65,0xc1,0x33,0xf3,
+ 0x95,0xc5,0x52,0x68,0x0b,0xd4,0xf1,0xe5,0x0e,0x02,
+ 0x9f,0x4f,0xfa,0x77,0xdc,0x46,0x9e,0xc7,0xa6,0xe4,
+ 0x16,0x29,0xda,0xb0,0x07,0xcf,0x5b,0xa9,0x12,0x8a,
+ 0xdd,0x63,0x0a,0xde,0x2e,0x8c,0x66,0x8b,0x8c,0xdc,
+ 0x19,0xa3,0x7e,0xf4,0x3b,0xd0,0x1a,0x8c,0xa4,0xc2,
+ 0xe1,0xd3,0x02,0x41,0x00,0xe2,0x4c,0x05,0xf2,0x04,
+ 0x86,0x4e,0x61,0x43,0xdb,0xb0,0xb9,0x96,0x86,0x52,
+ 0x2c,0xca,0x8d,0x7b,0xab,0x0b,0x13,0x0d,0x7e,0x38,
+ 0x5b,0xe2,0x2e,0x7b,0x0e,0xe7,0x19,0x99,0x38,0xe7,
+ 0xf2,0x21,0xbd,0x85,0x85,0xe3,0xfd,0x28,0x77,0x20,
+ 0x31,0x71,0x2c,0xd0,0xff,0xfb,0x2e,0xaf,0x85,0xb4,
+ 0x86,0xca,0xf3,0xbb,0xca,0xaa,0x0f,0x95,0x37,0x02,
+ 0x40,0x0e,0x41,0x9a,0x95,0xe8,0xb3,0x59,0xce,0x4b,
+ 0x61,0xde,0x35,0xec,0x38,0x79,0x9c,0xb8,0x10,0x52,
+ 0x41,0x63,0xab,0x82,0xae,0x6f,0x00,0xa9,0xf4,0xde,
+ 0xdd,0x49,0x0b,0x7e,0xb8,0xa5,0x65,0xa9,0x0c,0x8f,
+ 0x8f,0xf9,0x1f,0x35,0xc6,0x92,0xb8,0x5e,0xb0,0x66,
+ 0xab,0x52,0x40,0xc0,0xb6,0x36,0x6a,0x7d,0x80,0x46,
+ 0x04,0x02,0xe5,0x9f,0x41,0x02,0x41,0x00,0xc0,0xad,
+ 0xcc,0x4e,0x21,0xee,0x1d,0x24,0x91,0xfb,0xa7,0x80,
+ 0x8d,0x9a,0xb6,0xb3,0x2e,0x8f,0xc2,0xe1,0x82,0xdf,
+ 0x69,0x18,0xb4,0x71,0xff,0xa6,0x65,0xde,0xed,0x84,
+ 0x8d,0x42,0xb7,0xb3,0x21,0x69,0x56,0x1c,0x07,0x60,
+ 0x51,0x29,0x04,0xff,0x34,0x06,0xdd,0xb9,0x67,0x2c,
+ 0x7c,0x04,0x93,0x0e,0x46,0x15,0xbb,0x2a,0xb7,0x1b,
+ 0xe7,0x87,0x02,0x40,0x78,0xda,0x5d,0x07,0x51,0x0c,
+ 0x16,0x7a,0x9f,0x29,0x20,0x84,0x0d,0x42,0xfa,0xd7,
+ 0x00,0xd8,0x77,0x7e,0xb0,0xb0,0x6b,0xd6,0x5b,0x53,
+ 0xb8,0x9b,0x7a,0xcd,0xc7,0x2b,0xb8,0x6a,0x63,0xa9,
+ 0xfb,0x6f,0xa4,0x72,0xbf,0x4c,0x5d,0x00,0x14,0xba,
+ 0xfa,0x59,0x88,0xed,0xe4,0xe0,0x8c,0xa2,0xec,0x14,
+ 0x7e,0x2d,0xe2,0xf0,0x46,0x49,0x95,0x45,
+ };
+
+static unsigned char test2048[]={
+ 0x30,0x82,0x04,0xa3,0x02,0x01,0x00,0x02,0x82,0x01,
+ 0x01,0x00,0xc0,0xc0,0xce,0x3e,0x3c,0x53,0x67,0x3f,
+ 0x4f,0xc5,0x2f,0xa4,0xc2,0x5a,0x2f,0x58,0xfd,0x27,
+ 0x52,0x6a,0xe8,0xcf,0x4a,0x73,0x47,0x8d,0x25,0x0f,
+ 0x5f,0x03,0x26,0x78,0xef,0xf0,0x22,0x12,0xd3,0xde,
+ 0x47,0xb2,0x1c,0x0b,0x38,0x63,0x1a,0x6c,0x85,0x7a,
+ 0x80,0xc6,0x8f,0xa0,0x41,0xaf,0x62,0xc4,0x67,0x32,
+ 0x88,0xf8,0xa6,0x9c,0xf5,0x23,0x1d,0xe4,0xac,0x3f,
+ 0x29,0xf9,0xec,0xe1,0x8b,0x26,0x03,0x2c,0xb2,0xab,
+ 0xf3,0x7d,0xb5,0xca,0x49,0xc0,0x8f,0x1c,0xdf,0x33,
+ 0x3a,0x60,0xda,0x3c,0xb0,0x16,0xf8,0xa9,0x12,0x8f,
+ 0x64,0xac,0x23,0x0c,0x69,0x64,0x97,0x5d,0x99,0xd4,
+ 0x09,0x83,0x9b,0x61,0xd3,0xac,0xf0,0xde,0xdd,0x5e,
+ 0x9f,0x44,0x94,0xdb,0x3a,0x4d,0x97,0xe8,0x52,0x29,
+ 0xf7,0xdb,0x94,0x07,0x45,0x90,0x78,0x1e,0x31,0x0b,
+ 0x80,0xf7,0x57,0xad,0x1c,0x79,0xc5,0xcb,0x32,0xb0,
+ 0xce,0xcd,0x74,0xb3,0xe2,0x94,0xc5,0x78,0x2f,0x34,
+ 0x1a,0x45,0xf7,0x8c,0x52,0xa5,0xbc,0x8d,0xec,0xd1,
+ 0x2f,0x31,0x3b,0xf0,0x49,0x59,0x5e,0x88,0x9d,0x15,
+ 0x92,0x35,0x32,0xc1,0xe7,0x61,0xec,0x50,0x48,0x7c,
+ 0xba,0x05,0xf9,0xf8,0xf8,0xa7,0x8c,0x83,0xe8,0x66,
+ 0x5b,0xeb,0xfe,0xd8,0x4f,0xdd,0x6d,0x36,0xc0,0xb2,
+ 0x90,0x0f,0xb8,0x52,0xf9,0x04,0x9b,0x40,0x2c,0x27,
+ 0xd6,0x36,0x8e,0xc2,0x1b,0x44,0xf3,0x92,0xd5,0x15,
+ 0x9e,0x9a,0xbc,0xf3,0x7d,0x03,0xd7,0x02,0x14,0x20,
+ 0xe9,0x10,0x92,0xfd,0xf9,0xfc,0x8f,0xe5,0x18,0xe1,
+ 0x95,0xcc,0x9e,0x60,0xa6,0xfa,0x38,0x4d,0x02,0x03,
+ 0x01,0x00,0x01,0x02,0x82,0x01,0x00,0x00,0xc3,0xc3,
+ 0x0d,0xb4,0x27,0x90,0x8d,0x4b,0xbf,0xb8,0x84,0xaa,
+ 0xd0,0xb8,0xc7,0x5d,0x99,0xbe,0x55,0xf6,0x3e,0x7c,
+ 0x49,0x20,0xcb,0x8a,0x8e,0x19,0x0e,0x66,0x24,0xac,
+ 0xaf,0x03,0x33,0x97,0xeb,0x95,0xd5,0x3b,0x0f,0x40,
+ 0x56,0x04,0x50,0xd1,0xe6,0xbe,0x84,0x0b,0x25,0xd3,
+ 0x9c,0xe2,0x83,0x6c,0xf5,0x62,0x5d,0xba,0x2b,0x7d,
+ 0x3d,0x7a,0x6c,0xe1,0xd2,0x0e,0x54,0x93,0x80,0x01,
+ 0x91,0x51,0x09,0xe8,0x5b,0x8e,0x47,0xbd,0x64,0xe4,
+ 0x0e,0x03,0x83,0x55,0xcf,0x5a,0x37,0xf0,0x25,0xb5,
+ 0x7d,0x21,0xd7,0x69,0xdf,0x6f,0xc2,0xcf,0x10,0xc9,
+ 0x8a,0x40,0x9f,0x7a,0x70,0xc0,0xe8,0xe8,0xc0,0xe6,
+ 0x9a,0x15,0x0a,0x8d,0x4e,0x46,0xcb,0x7a,0xdb,0xb3,
+ 0xcb,0x83,0x02,0xc4,0xf0,0xab,0xeb,0x02,0x01,0x0e,
+ 0x23,0xfc,0x1d,0xc4,0xbd,0xd4,0xaa,0x5d,0x31,0x46,
+ 0x99,0xce,0x9e,0xf8,0x04,0x75,0x10,0x67,0xc4,0x53,
+ 0x47,0x44,0xfa,0xc2,0x25,0x73,0x7e,0xd0,0x8e,0x59,
+ 0xd1,0xb2,0x5a,0xf4,0xc7,0x18,0x92,0x2f,0x39,0xab,
+ 0xcd,0xa3,0xb5,0xc2,0xb9,0xc7,0xb9,0x1b,0x9f,0x48,
+ 0xfa,0x13,0xc6,0x98,0x4d,0xca,0x84,0x9c,0x06,0xca,
+ 0xe7,0x89,0x01,0x04,0xc4,0x6c,0xfd,0x29,0x59,0x35,
+ 0xe7,0xf3,0xdd,0xce,0x64,0x59,0xbf,0x21,0x13,0xa9,
+ 0x9f,0x0e,0xc5,0xff,0xbd,0x33,0x00,0xec,0xac,0x6b,
+ 0x11,0xef,0x51,0x5e,0xad,0x07,0x15,0xde,0xb8,0x5f,
+ 0xc6,0xb9,0xa3,0x22,0x65,0x46,0x83,0x14,0xdf,0xd0,
+ 0xf1,0x44,0x8a,0xe1,0x9c,0x23,0x33,0xb4,0x97,0x33,
+ 0xe6,0x6b,0x81,0x02,0x81,0x81,0x00,0xec,0x12,0xa7,
+ 0x59,0x74,0x6a,0xde,0x3e,0xad,0xd8,0x36,0x80,0x50,
+ 0xa2,0xd5,0x21,0x81,0x07,0xf1,0xd0,0x91,0xf2,0x6c,
+ 0x12,0x2f,0x9d,0x1a,0x26,0xf8,0x30,0x65,0xdf,0xe8,
+ 0xc0,0x9b,0x6a,0x30,0x98,0x82,0x87,0xec,0xa2,0x56,
+ 0x87,0x62,0x6f,0xe7,0x9f,0xf6,0x56,0xe6,0x71,0x8f,
+ 0x49,0x86,0x93,0x5a,0x4d,0x34,0x58,0xfe,0xd9,0x04,
+ 0x13,0xaf,0x79,0xb7,0xad,0x11,0xd1,0x30,0x9a,0x14,
+ 0x06,0xa0,0xfa,0xb7,0x55,0xdc,0x6c,0x5a,0x4c,0x2c,
+ 0x59,0x56,0xf6,0xe8,0x9d,0xaf,0x0a,0x78,0x99,0x06,
+ 0x06,0x9e,0xe7,0x9c,0x51,0x55,0x43,0xfc,0x3b,0x6c,
+ 0x0b,0xbf,0x2d,0x41,0xa7,0xaf,0xb7,0xe0,0xe8,0x28,
+ 0x18,0xb4,0x13,0xd1,0xe6,0x97,0xd0,0x9f,0x6a,0x80,
+ 0xca,0xdd,0x1a,0x7e,0x15,0x02,0x81,0x81,0x00,0xd1,
+ 0x06,0x0c,0x1f,0xe3,0xd0,0xab,0xd6,0xca,0x7c,0xbc,
+ 0x7d,0x13,0x35,0xce,0x27,0xcd,0xd8,0x49,0x51,0x63,
+ 0x64,0x0f,0xca,0x06,0x12,0xfc,0x07,0x3e,0xaf,0x61,
+ 0x6d,0xe2,0x53,0x39,0x27,0xae,0xc3,0x11,0x9e,0x94,
+ 0x01,0x4f,0xe3,0xf3,0x67,0xf9,0x77,0xf9,0xe7,0x95,
+ 0x3a,0x6f,0xe2,0x20,0x73,0x3e,0xa4,0x7a,0x28,0xd4,
+ 0x61,0x97,0xf6,0x17,0xa0,0x23,0x10,0x2b,0xce,0x84,
+ 0x57,0x7e,0x25,0x1f,0xf4,0xa8,0x54,0xd2,0x65,0x94,
+ 0xcc,0x95,0x0a,0xab,0x30,0xc1,0x59,0x1f,0x61,0x8e,
+ 0xb9,0x6b,0xd7,0x4e,0xb9,0x83,0x43,0x79,0x85,0x11,
+ 0xbc,0x0f,0xae,0x25,0x20,0x05,0xbc,0xd2,0x48,0xa1,
+ 0x68,0x09,0x84,0xf6,0x12,0x9a,0x66,0xb9,0x2b,0xbb,
+ 0x76,0x03,0x17,0x46,0x4e,0x97,0x59,0x02,0x81,0x80,
+ 0x09,0x4c,0xfa,0xd6,0xe5,0x65,0x48,0x78,0x43,0xb5,
+ 0x1f,0x00,0x93,0x2c,0xb7,0x24,0xe8,0xc6,0x7d,0x5a,
+ 0x70,0x45,0x92,0xc8,0x6c,0xa3,0xcd,0xe1,0xf7,0x29,
+ 0x40,0xfa,0x3f,0x5b,0x47,0x44,0x39,0xc1,0xe8,0x72,
+ 0x9e,0x7a,0x0e,0xda,0xaa,0xa0,0x2a,0x09,0xfd,0x54,
+ 0x93,0x23,0xaa,0x37,0x85,0x5b,0xcc,0xd4,0xf9,0xd8,
+ 0xff,0xc1,0x61,0x0d,0xbd,0x7e,0x18,0x24,0x73,0x6d,
+ 0x40,0x72,0xf1,0x93,0x09,0x48,0x97,0x6c,0x84,0x90,
+ 0xa8,0x46,0x14,0x01,0x39,0x11,0xe5,0x3c,0x41,0x27,
+ 0x32,0x75,0x24,0xed,0xa1,0xd9,0x12,0x29,0x8a,0x28,
+ 0x71,0x89,0x8d,0xca,0x30,0xb0,0x01,0xc4,0x2f,0x82,
+ 0x19,0x14,0x4c,0x70,0x1c,0xb8,0x23,0x2e,0xe8,0x90,
+ 0x49,0x97,0x92,0x97,0x6b,0x7a,0x9d,0xb9,0x02,0x81,
+ 0x80,0x0f,0x0e,0xa1,0x76,0xf6,0xa1,0x44,0x8f,0xaf,
+ 0x7c,0x76,0xd3,0x87,0xbb,0xbb,0x83,0x10,0x88,0x01,
+ 0x18,0x14,0xd1,0xd3,0x75,0x59,0x24,0xaa,0xf5,0x16,
+ 0xa5,0xe9,0x9d,0xd1,0xcc,0xee,0xf4,0x15,0xd9,0xc5,
+ 0x7e,0x27,0xe9,0x44,0x49,0x06,0x72,0xb9,0xfc,0xd3,
+ 0x8a,0xc4,0x2c,0x36,0x7d,0x12,0x9b,0x5a,0xaa,0xdc,
+ 0x85,0xee,0x6e,0xad,0x54,0xb3,0xf4,0xfc,0x31,0xa1,
+ 0x06,0x3a,0x70,0x57,0x0c,0xf3,0x95,0x5b,0x3e,0xe8,
+ 0xfd,0x1a,0x4f,0xf6,0x78,0x93,0x46,0x6a,0xd7,0x31,
+ 0xb4,0x84,0x64,0x85,0x09,0x38,0x89,0x92,0x94,0x1c,
+ 0xbf,0xe2,0x3c,0x2a,0xe0,0xff,0x99,0xa3,0xf0,0x2b,
+ 0x31,0xc2,0x36,0xcd,0x60,0xbf,0x9d,0x2d,0x74,0x32,
+ 0xe8,0x9c,0x93,0x6e,0xbb,0x91,0x7b,0xfd,0xd9,0x02,
+ 0x81,0x81,0x00,0xa2,0x71,0x25,0x38,0xeb,0x2a,0xe9,
+ 0x37,0xcd,0xfe,0x44,0xce,0x90,0x3f,0x52,0x87,0x84,
+ 0x52,0x1b,0xae,0x8d,0x22,0x94,0xce,0x38,0xe6,0x04,
+ 0x88,0x76,0x85,0x9a,0xd3,0x14,0x09,0xe5,0x69,0x9a,
+ 0xff,0x58,0x92,0x02,0x6a,0x7d,0x7c,0x1e,0x2c,0xfd,
+ 0xa8,0xca,0x32,0x14,0x4f,0x0d,0x84,0x0d,0x37,0x43,
+ 0xbf,0xe4,0x5d,0x12,0xc8,0x24,0x91,0x27,0x8d,0x46,
+ 0xd9,0x54,0x53,0xe7,0x62,0x71,0xa8,0x2b,0x71,0x41,
+ 0x8d,0x75,0xf8,0x3a,0xa0,0x61,0x29,0x46,0xa6,0xe5,
+ 0x82,0xfa,0x3a,0xd9,0x08,0xfa,0xfc,0x63,0xfd,0x6b,
+ 0x30,0xbc,0xf4,0x4e,0x9e,0x8c,0x25,0x0c,0xb6,0x55,
+ 0xe7,0x3c,0xd4,0x4e,0x0b,0xfd,0x8b,0xc3,0x0e,0x1d,
+ 0x9c,0x44,0x57,0x8f,0x1f,0x86,0xf7,0xd5,0x1b,0xe4,
+ 0x95,
+ };
+
+static unsigned char test4096[]={
+ 0x30,0x82,0x09,0x29,0x02,0x01,0x00,0x02,0x82,0x02,
+ 0x01,0x00,0xc0,0x71,0xac,0x1a,0x13,0x88,0x82,0x43,
+ 0x3b,0x51,0x57,0x71,0x8d,0xb6,0x2b,0x82,0x65,0x21,
+ 0x53,0x5f,0x28,0x29,0x4f,0x8d,0x7c,0x8a,0xb9,0x44,
+ 0xb3,0x28,0x41,0x4f,0xd3,0xfa,0x6a,0xf8,0xb9,0x28,
+ 0x50,0x39,0x67,0x53,0x2c,0x3c,0xd7,0xcb,0x96,0x41,
+ 0x40,0x32,0xbb,0xeb,0x70,0xae,0x1f,0xb0,0x65,0xf7,
+ 0x3a,0xd9,0x22,0xfd,0x10,0xae,0xbd,0x02,0xe2,0xdd,
+ 0xf3,0xc2,0x79,0x3c,0xc6,0xfc,0x75,0xbb,0xaf,0x4e,
+ 0x3a,0x36,0xc2,0x4f,0xea,0x25,0xdf,0x13,0x16,0x4b,
+ 0x20,0xfe,0x4b,0x69,0x16,0xc4,0x7f,0x1a,0x43,0xa6,
+ 0x17,0x1b,0xb9,0x0a,0xf3,0x09,0x86,0x28,0x89,0xcf,
+ 0x2c,0xd0,0xd4,0x81,0xaf,0xc6,0x6d,0xe6,0x21,0x8d,
+ 0xee,0xef,0xea,0xdc,0xb7,0xc6,0x3b,0x63,0x9f,0x0e,
+ 0xad,0x89,0x78,0x23,0x18,0xbf,0x70,0x7e,0x84,0xe0,
+ 0x37,0xec,0xdb,0x8e,0x9c,0x3e,0x6a,0x19,0xcc,0x99,
+ 0x72,0xe6,0xb5,0x7d,0x6d,0xfa,0xe5,0xd3,0xe4,0x90,
+ 0xb5,0xb2,0xb2,0x12,0x70,0x4e,0xca,0xf8,0x10,0xf8,
+ 0xa3,0x14,0xc2,0x48,0x19,0xeb,0x60,0x99,0xbb,0x2a,
+ 0x1f,0xb1,0x7a,0xb1,0x3d,0x24,0xfb,0xa0,0x29,0xda,
+ 0xbd,0x1b,0xd7,0xa4,0xbf,0xef,0x60,0x2d,0x22,0xca,
+ 0x65,0x98,0xf1,0xc4,0xe1,0xc9,0x02,0x6b,0x16,0x28,
+ 0x2f,0xa1,0xaa,0x79,0x00,0xda,0xdc,0x7c,0x43,0xf7,
+ 0x42,0x3c,0xa0,0xef,0x68,0xf7,0xdf,0xb9,0x69,0xfb,
+ 0x8e,0x01,0xed,0x01,0x42,0xb5,0x4e,0x57,0xa6,0x26,
+ 0xb8,0xd0,0x7b,0x56,0x6d,0x03,0xc6,0x40,0x8c,0x8c,
+ 0x2a,0x55,0xd7,0x9c,0x35,0x00,0x94,0x93,0xec,0x03,
+ 0xeb,0x22,0xef,0x77,0xbb,0x79,0x13,0x3f,0x15,0xa1,
+ 0x8f,0xca,0xdf,0xfd,0xd3,0xb8,0xe1,0xd4,0xcc,0x09,
+ 0x3f,0x3c,0x2c,0xdb,0xd1,0x49,0x7f,0x38,0x07,0x83,
+ 0x6d,0xeb,0x08,0x66,0xe9,0x06,0x44,0x12,0xac,0x95,
+ 0x22,0x90,0x23,0x67,0xd4,0x08,0xcc,0xf4,0xb7,0xdc,
+ 0xcc,0x87,0xd4,0xac,0x69,0x35,0x4c,0xb5,0x39,0x36,
+ 0xcd,0xa4,0xd2,0x95,0xca,0x0d,0xc5,0xda,0xc2,0xc5,
+ 0x22,0x32,0x28,0x08,0xe3,0xd2,0x8b,0x38,0x30,0xdc,
+ 0x8c,0x75,0x4f,0x6a,0xec,0x7a,0xac,0x16,0x3e,0xa8,
+ 0xd4,0x6a,0x45,0xe1,0xa8,0x4f,0x2e,0x80,0x34,0xaa,
+ 0x54,0x1b,0x02,0x95,0x7d,0x8a,0x6d,0xcc,0x79,0xca,
+ 0xf2,0xa4,0x2e,0x8d,0xfb,0xfe,0x15,0x51,0x10,0x0e,
+ 0x4d,0x88,0xb1,0xc7,0xf4,0x79,0xdb,0xf0,0xb4,0x56,
+ 0x44,0x37,0xca,0x5a,0xc1,0x8c,0x48,0xac,0xae,0x48,
+ 0x80,0x83,0x01,0x3f,0xde,0xd9,0xd3,0x2c,0x51,0x46,
+ 0xb1,0x41,0xb6,0xc6,0x91,0x72,0xf9,0x83,0x55,0x1b,
+ 0x8c,0xba,0xf3,0x73,0xe5,0x2c,0x74,0x50,0x3a,0xbe,
+ 0xc5,0x2f,0xa7,0xb2,0x6d,0x8c,0x9e,0x13,0x77,0xa3,
+ 0x13,0xcd,0x6d,0x8c,0x45,0xe1,0xfc,0x0b,0xb7,0x69,
+ 0xe9,0x27,0xbc,0x65,0xc3,0xfa,0x9b,0xd0,0xef,0xfe,
+ 0xe8,0x1f,0xb3,0x5e,0x34,0xf4,0x8c,0xea,0xfc,0xd3,
+ 0x81,0xbf,0x3d,0x30,0xb2,0xb4,0x01,0xe8,0x43,0x0f,
+ 0xba,0x02,0x23,0x42,0x76,0x82,0x31,0x73,0x91,0xed,
+ 0x07,0x46,0x61,0x0d,0x39,0x83,0x40,0xce,0x7a,0xd4,
+ 0xdb,0x80,0x2c,0x1f,0x0d,0xd1,0x34,0xd4,0x92,0xe3,
+ 0xd4,0xf1,0xc2,0x01,0x02,0x03,0x01,0x00,0x01,0x02,
+ 0x82,0x02,0x01,0x00,0x97,0x6c,0xda,0x6e,0xea,0x4f,
+ 0xcf,0xaf,0xf7,0x4c,0xd9,0xf1,0x90,0x00,0x77,0xdb,
+ 0xf2,0x97,0x76,0x72,0xb9,0xb7,0x47,0xd1,0x9c,0xdd,
+ 0xcb,0x4a,0x33,0x6e,0xc9,0x75,0x76,0xe6,0xe4,0xa5,
+ 0x31,0x8c,0x77,0x13,0xb4,0x29,0xcd,0xf5,0x52,0x17,
+ 0xef,0xf3,0x08,0x00,0xe3,0xbd,0x2e,0xbc,0xd4,0x52,
+ 0x88,0xe9,0x30,0x75,0x0b,0x02,0xf5,0xcd,0x89,0x0c,
+ 0x6c,0x57,0x19,0x27,0x3d,0x1e,0x85,0xb4,0xc1,0x2f,
+ 0x1d,0x92,0x00,0x5c,0x76,0x29,0x4b,0xa4,0xe1,0x12,
+ 0xb3,0xc8,0x09,0xfe,0x0e,0x78,0x72,0x61,0xcb,0x61,
+ 0x6f,0x39,0x91,0x95,0x4e,0xd5,0x3e,0xc7,0x8f,0xb8,
+ 0xf6,0x36,0xfe,0x9c,0x93,0x9a,0x38,0x25,0x7a,0xf4,
+ 0x4a,0x12,0xd4,0xa0,0x13,0xbd,0xf9,0x1d,0x12,0x3e,
+ 0x21,0x39,0xfb,0x72,0xe0,0x05,0x3d,0xc3,0xe5,0x50,
+ 0xa8,0x5d,0x85,0xa3,0xea,0x5f,0x1c,0xb2,0x3f,0xea,
+ 0x6d,0x03,0x91,0x55,0xd8,0x19,0x0a,0x21,0x12,0x16,
+ 0xd9,0x12,0xc4,0xe6,0x07,0x18,0x5b,0x26,0xa4,0xae,
+ 0xed,0x2b,0xb7,0xa6,0xed,0xf8,0xad,0xec,0x77,0xe6,
+ 0x7f,0x4f,0x76,0x00,0xc0,0xfa,0x15,0x92,0xb4,0x2c,
+ 0x22,0xc2,0xeb,0x6a,0xad,0x14,0x05,0xb2,0xe5,0x8a,
+ 0x9e,0x85,0x83,0xcc,0x04,0xf1,0x56,0x78,0x44,0x5e,
+ 0xde,0xe0,0x60,0x1a,0x65,0x79,0x31,0x23,0x05,0xbb,
+ 0x01,0xff,0xdd,0x2e,0xb7,0xb3,0xaa,0x74,0xe0,0xa5,
+ 0x94,0xaf,0x4b,0xde,0x58,0x0f,0x55,0xde,0x33,0xf6,
+ 0xe3,0xd6,0x34,0x36,0x57,0xd6,0x79,0x91,0x2e,0xbe,
+ 0x3b,0xd9,0x4e,0xb6,0x9d,0x21,0x5c,0xd3,0x48,0x14,
+ 0x7f,0x4a,0xc4,0x60,0xa9,0x29,0xf8,0x53,0x7f,0x88,
+ 0x11,0x2d,0xb5,0xc5,0x2d,0x6f,0xee,0x85,0x0b,0xf7,
+ 0x8d,0x9a,0xbe,0xb0,0x42,0xf2,0x2e,0x71,0xaf,0x19,
+ 0x31,0x6d,0xec,0xcd,0x6f,0x2b,0x23,0xdf,0xb4,0x40,
+ 0xaf,0x2c,0x0a,0xc3,0x1b,0x7d,0x7d,0x03,0x1d,0x4b,
+ 0xf3,0xb5,0xe0,0x85,0xd8,0xdf,0x91,0x6b,0x0a,0x69,
+ 0xf7,0xf2,0x69,0x66,0x5b,0xf1,0xcf,0x46,0x7d,0xe9,
+ 0x70,0xfa,0x6d,0x7e,0x75,0x4e,0xa9,0x77,0xe6,0x8c,
+ 0x02,0xf7,0x14,0x4d,0xa5,0x41,0x8f,0x3f,0xc1,0x62,
+ 0x1e,0x71,0x5e,0x38,0xb4,0xd6,0xe6,0xe1,0x4b,0xc2,
+ 0x2c,0x30,0x83,0x81,0x6f,0x49,0x2e,0x96,0xe6,0xc9,
+ 0x9a,0xf7,0x5d,0x09,0xa0,0x55,0x02,0xa5,0x3a,0x25,
+ 0x23,0xd0,0x92,0xc3,0xa3,0xe3,0x0e,0x12,0x2f,0x4d,
+ 0xef,0xf3,0x55,0x5a,0xbe,0xe6,0x19,0x86,0x31,0xab,
+ 0x75,0x9a,0xd3,0xf0,0x2c,0xc5,0x41,0x92,0xd9,0x1f,
+ 0x5f,0x11,0x8c,0x75,0x1c,0x63,0xd0,0x02,0x80,0x2c,
+ 0x68,0xcb,0x93,0xfb,0x51,0x73,0x49,0xb4,0x60,0xda,
+ 0xe2,0x26,0xaf,0xa9,0x46,0x12,0xb8,0xec,0x50,0xdd,
+ 0x12,0x06,0x5f,0xce,0x59,0xe6,0xf6,0x1c,0xe0,0x54,
+ 0x10,0xad,0xf6,0xcd,0x98,0xcc,0x0f,0xfb,0xcb,0x41,
+ 0x14,0x9d,0xed,0xe4,0xb4,0x74,0x5f,0x09,0x60,0xc7,
+ 0x12,0xf6,0x7b,0x3c,0x8f,0xa7,0x20,0xbc,0xe4,0xb1,
+ 0xef,0xeb,0xa4,0x93,0xc5,0x06,0xca,0x9a,0x27,0x9d,
+ 0x87,0xf3,0xde,0xca,0xe5,0xe7,0xf6,0x1c,0x01,0x65,
+ 0x5b,0xfb,0x19,0x79,0x6e,0x08,0x26,0xc5,0xc8,0x28,
+ 0x0e,0xb6,0x3b,0x07,0x08,0xc1,0x02,0x82,0x01,0x01,
+ 0x00,0xe8,0x1c,0x73,0xa6,0xb8,0xe0,0x0e,0x6d,0x8d,
+ 0x1b,0xb9,0x53,0xed,0x58,0x94,0xe6,0x1d,0x60,0x14,
+ 0x5c,0x76,0x43,0xc4,0x58,0x19,0xc4,0x24,0xe8,0xbc,
+ 0x1b,0x3b,0x0b,0x13,0x24,0x45,0x54,0x0e,0xcc,0x37,
+ 0xf0,0xe0,0x63,0x7d,0xc3,0xf7,0xfb,0x81,0x74,0x81,
+ 0xc4,0x0f,0x1a,0x21,0x48,0xaf,0xce,0xc1,0xc4,0x94,
+ 0x18,0x06,0x44,0x8d,0xd3,0xd2,0x22,0x2d,0x2d,0x3e,
+ 0x5a,0x31,0xdc,0x95,0x8e,0xf4,0x41,0xfc,0x58,0xc9,
+ 0x40,0x92,0x17,0x5f,0xe3,0xda,0xac,0x9e,0x3f,0x1c,
+ 0x2a,0x6b,0x58,0x5f,0x48,0x78,0x20,0xb1,0xaf,0x24,
+ 0x9b,0x3c,0x20,0x8b,0x93,0x25,0x9e,0xe6,0x6b,0xbc,
+ 0x13,0x42,0x14,0x6c,0x36,0x31,0xff,0x7a,0xd1,0xc1,
+ 0x1a,0x26,0x14,0x7f,0xa9,0x76,0xa7,0x0c,0xf8,0xcc,
+ 0xed,0x07,0x6a,0xd2,0xdf,0x62,0xee,0x0a,0x7c,0x84,
+ 0xcb,0x49,0x90,0xb2,0x03,0x0d,0xa2,0x82,0x06,0x77,
+ 0xf1,0xcd,0x67,0xf2,0x47,0x21,0x02,0x3f,0x43,0x21,
+ 0xf0,0x46,0x30,0x62,0x51,0x72,0xb1,0xe7,0x48,0xc6,
+ 0x67,0x12,0xcd,0x9e,0xd6,0x15,0xe5,0x21,0xed,0xfa,
+ 0x8f,0x30,0xa6,0x41,0xfe,0xb6,0xfa,0x8f,0x34,0x14,
+ 0x19,0xe8,0x11,0xf7,0xa5,0x77,0x3e,0xb7,0xf9,0x39,
+ 0x07,0x8c,0x67,0x2a,0xab,0x7b,0x08,0xf8,0xb0,0x06,
+ 0xa8,0xea,0x2f,0x8f,0xfa,0xcc,0xcc,0x40,0xce,0xf3,
+ 0x70,0x4f,0x3f,0x7f,0xe2,0x0c,0xea,0x76,0x4a,0x35,
+ 0x4e,0x47,0xad,0x2b,0xa7,0x97,0x5d,0x74,0x43,0x97,
+ 0x90,0xd2,0xfb,0xd9,0xf9,0x96,0x01,0x33,0x05,0xed,
+ 0x7b,0x03,0x05,0xad,0xf8,0x49,0x03,0x02,0x82,0x01,
+ 0x01,0x00,0xd4,0x40,0x17,0x66,0x10,0x92,0x95,0xc8,
+ 0xec,0x62,0xa9,0x7a,0xcb,0x93,0x8e,0xe6,0x53,0xd4,
+ 0x80,0x48,0x27,0x4b,0x41,0xce,0x61,0xdf,0xbf,0x94,
+ 0xa4,0x3d,0x71,0x03,0x0b,0xed,0x25,0x71,0x98,0xa4,
+ 0xd6,0xd5,0x4a,0x57,0xf5,0x6c,0x1b,0xda,0x21,0x7d,
+ 0x35,0x45,0xb3,0xf3,0x6a,0xd9,0xd3,0x43,0xe8,0x5c,
+ 0x54,0x1c,0x83,0x1b,0xb4,0x5f,0xf2,0x97,0x24,0x2e,
+ 0xdc,0x40,0xde,0x92,0x23,0x59,0x8e,0xbc,0xd2,0xa1,
+ 0xf2,0xe0,0x4c,0xdd,0x0b,0xd1,0xe7,0xae,0x65,0xbc,
+ 0xb5,0xf5,0x5b,0x98,0xe9,0xd7,0xc2,0xb7,0x0e,0x55,
+ 0x71,0x0e,0x3c,0x0a,0x24,0x6b,0xa6,0xe6,0x14,0x61,
+ 0x11,0xfd,0x33,0x42,0x99,0x2b,0x84,0x77,0x74,0x92,
+ 0x91,0xf5,0x79,0x79,0xcf,0xad,0x8e,0x04,0xef,0x80,
+ 0x1e,0x57,0xf4,0x14,0xf5,0x35,0x09,0x74,0xb2,0x13,
+ 0x71,0x58,0x6b,0xea,0x32,0x5d,0xf3,0xd3,0x76,0x48,
+ 0x39,0x10,0x23,0x84,0x9d,0xbe,0x92,0x77,0x4a,0xed,
+ 0x70,0x3e,0x1a,0xa2,0x6c,0xb3,0x81,0x00,0xc3,0xc9,
+ 0xe4,0x52,0xc8,0x24,0x88,0x0c,0x41,0xad,0x87,0x5a,
+ 0xea,0xa3,0x7a,0x85,0x1c,0x5e,0x31,0x7f,0xc3,0x35,
+ 0xc6,0xfa,0x10,0xc8,0x75,0x10,0xc4,0x96,0x99,0xe7,
+ 0xfe,0x01,0xb4,0x74,0xdb,0xb4,0x11,0xc3,0xc8,0x8c,
+ 0xf6,0xf7,0x3b,0x66,0x50,0xfc,0xdb,0xeb,0xca,0x47,
+ 0x85,0x89,0xe1,0x65,0xd9,0x62,0x34,0x3c,0x70,0xd8,
+ 0x2e,0xb4,0x2f,0x65,0x3c,0x4a,0xa6,0x2a,0xe7,0xc7,
+ 0xd8,0x41,0x8f,0x8a,0x43,0xbf,0x42,0xf2,0x4d,0xbc,
+ 0xfc,0x9e,0x27,0x95,0xfb,0x75,0xff,0xab,0x02,0x82,
+ 0x01,0x00,0x41,0x2f,0x44,0x57,0x6d,0x12,0x17,0x5b,
+ 0x32,0xc6,0xb7,0x6c,0x57,0x7a,0x8a,0x0e,0x79,0xef,
+ 0x72,0xa8,0x68,0xda,0x2d,0x38,0xe4,0xbb,0x8d,0xf6,
+ 0x02,0x65,0xcf,0x56,0x13,0xe1,0x1a,0xcb,0x39,0x80,
+ 0xa6,0xb1,0x32,0x03,0x1e,0xdd,0xbb,0x35,0xd9,0xac,
+ 0x43,0x89,0x31,0x08,0x90,0x92,0x5e,0x35,0x3d,0x7b,
+ 0x9c,0x6f,0x86,0xcb,0x17,0xdd,0x85,0xe4,0xed,0x35,
+ 0x08,0x8e,0xc1,0xf4,0x05,0xd8,0x68,0xc6,0x63,0x3c,
+ 0xf7,0xff,0xf7,0x47,0x33,0x39,0xc5,0x3e,0xb7,0x0e,
+ 0x58,0x35,0x9d,0x81,0xea,0xf8,0x6a,0x2c,0x1c,0x5a,
+ 0x68,0x78,0x64,0x11,0x6b,0xc1,0x3e,0x4e,0x7a,0xbd,
+ 0x84,0xcb,0x0f,0xc2,0xb6,0x85,0x1d,0xd3,0x76,0xc5,
+ 0x93,0x6a,0x69,0x89,0x56,0x34,0xdc,0x4a,0x9b,0xbc,
+ 0xff,0xa8,0x0d,0x6e,0x35,0x9c,0x60,0xa7,0x23,0x30,
+ 0xc7,0x06,0x64,0x39,0x8b,0x94,0x89,0xee,0xba,0x7f,
+ 0x60,0x8d,0xfa,0xb6,0x97,0x76,0xdc,0x51,0x4a,0x3c,
+ 0xeb,0x3a,0x14,0x2c,0x20,0x60,0x69,0x4a,0x86,0xfe,
+ 0x8c,0x21,0x84,0x49,0x54,0xb3,0x20,0xe1,0x01,0x7f,
+ 0x58,0xdf,0x7f,0xb5,0x21,0x51,0x8c,0x47,0x9f,0x91,
+ 0xeb,0x97,0x3e,0xf2,0x54,0xcf,0x16,0x46,0xf9,0xd9,
+ 0xb6,0xe7,0x64,0xc9,0xd0,0x54,0xea,0x2f,0xa1,0xcf,
+ 0xa5,0x7f,0x28,0x8d,0x84,0xec,0xd5,0x39,0x03,0x76,
+ 0x5b,0x2d,0x8e,0x43,0xf2,0x01,0x24,0xc9,0x6f,0xc0,
+ 0xf5,0x69,0x6f,0x7d,0xb5,0x85,0xd2,0x5f,0x7f,0x78,
+ 0x40,0x07,0x7f,0x09,0x15,0xb5,0x1f,0x28,0x65,0x10,
+ 0xe4,0x19,0xa8,0xc6,0x9e,0x8d,0xdc,0xcb,0x02,0x82,
+ 0x01,0x00,0x13,0x01,0xee,0x56,0x80,0x93,0x70,0x00,
+ 0x7f,0x52,0xd2,0x94,0xa1,0x98,0x84,0x4a,0x92,0x25,
+ 0x4c,0x9b,0xa9,0x91,0x2e,0xc2,0x79,0xb7,0x5c,0xe3,
+ 0xc5,0xd5,0x8e,0xc2,0x54,0x16,0x17,0xad,0x55,0x9b,
+ 0x25,0x76,0x12,0x63,0x50,0x22,0x2f,0x58,0x58,0x79,
+ 0x6b,0x04,0xe3,0xf9,0x9f,0x8f,0x04,0x41,0x67,0x94,
+ 0xa5,0x1f,0xac,0x8a,0x15,0x9c,0x26,0x10,0x6c,0xf8,
+ 0x19,0x57,0x61,0xd7,0x3a,0x7d,0x31,0xb0,0x2d,0x38,
+ 0xbd,0x94,0x62,0xad,0xc4,0xfa,0x36,0x42,0x42,0xf0,
+ 0x24,0x67,0x65,0x9d,0x8b,0x0b,0x7c,0x6f,0x82,0x44,
+ 0x1a,0x8c,0xc8,0xc9,0xab,0xbb,0x4c,0x45,0xfc,0x7b,
+ 0x38,0xee,0x30,0xe1,0xfc,0xef,0x8d,0xbc,0x58,0xdf,
+ 0x2b,0x5d,0x0d,0x54,0xe0,0x49,0x4d,0x97,0x99,0x8f,
+ 0x22,0xa8,0x83,0xbe,0x40,0xbb,0x50,0x2e,0x78,0x28,
+ 0x0f,0x95,0x78,0x8c,0x8f,0x98,0x24,0x56,0xc2,0x97,
+ 0xf3,0x2c,0x43,0xd2,0x03,0x82,0x66,0x81,0x72,0x5f,
+ 0x53,0x16,0xec,0xb1,0xb1,0x04,0x5e,0x40,0x20,0x48,
+ 0x7b,0x3f,0x02,0x97,0x6a,0xeb,0x96,0x12,0x21,0x35,
+ 0xfe,0x1f,0x47,0xc0,0x95,0xea,0xc5,0x8a,0x08,0x84,
+ 0x4f,0x5e,0x63,0x94,0x60,0x0f,0x71,0x5b,0x7f,0x4a,
+ 0xec,0x4f,0x60,0xc6,0xba,0x4a,0x24,0xf1,0x20,0x8b,
+ 0xa7,0x2e,0x3a,0xce,0x8d,0xe0,0x27,0x1d,0xb5,0x8e,
+ 0xb4,0x21,0xc5,0xe2,0xa6,0x16,0x0a,0x51,0x83,0x55,
+ 0x88,0xd1,0x30,0x11,0x63,0xd5,0xd7,0x8d,0xae,0x16,
+ 0x12,0x82,0xc4,0x85,0x00,0x4e,0x27,0x83,0xa5,0x7c,
+ 0x90,0x2e,0xe5,0xa2,0xa3,0xd3,0x4c,0x63,0x02,0x82,
+ 0x01,0x01,0x00,0x86,0x08,0x98,0x98,0xa5,0x00,0x05,
+ 0x39,0x77,0xd9,0x66,0xb3,0xcf,0xca,0xa0,0x71,0xb3,
+ 0x50,0xce,0x3d,0xb1,0x93,0x95,0x35,0xc4,0xd4,0x2e,
+ 0x90,0xdf,0x0f,0xfc,0x60,0xc1,0x94,0x68,0x61,0x43,
+ 0xca,0x9a,0x23,0x4a,0x1e,0x45,0x72,0x99,0xb5,0x1e,
+ 0x61,0x8d,0x77,0x0f,0xa0,0xbb,0xd7,0x77,0xb4,0x2a,
+ 0x15,0x11,0x88,0x2d,0xb3,0x56,0x61,0x5e,0x6a,0xed,
+ 0xa4,0x46,0x4a,0x3f,0x50,0x11,0xd6,0xba,0xb6,0xd7,
+ 0x95,0x65,0x53,0xc3,0xa1,0x8f,0xe0,0xa3,0xf5,0x1c,
+ 0xfd,0xaf,0x6e,0x43,0xd7,0x17,0xa7,0xd3,0x81,0x1b,
+ 0xa4,0xdf,0xe0,0x97,0x8a,0x46,0x03,0xd3,0x46,0x0e,
+ 0x83,0x48,0x4e,0xd2,0x02,0xcb,0xc0,0xad,0x79,0x95,
+ 0x8c,0x96,0xba,0x40,0x34,0x11,0x71,0x5e,0xe9,0x11,
+ 0xf9,0xc5,0x4a,0x5e,0x91,0x9d,0xf5,0x92,0x4f,0xeb,
+ 0xc6,0x70,0x02,0x2d,0x3d,0x04,0xaa,0xe9,0x3a,0x8e,
+ 0xd5,0xa8,0xad,0xf7,0xce,0x0d,0x16,0xb2,0xec,0x0a,
+ 0x9c,0xf5,0x94,0x39,0xb9,0x8a,0xfc,0x1e,0xf9,0xcc,
+ 0xf2,0x5f,0x21,0x31,0x74,0x72,0x6b,0x64,0xae,0x35,
+ 0x61,0x8d,0x0d,0xcb,0xe7,0xda,0x39,0xca,0xf3,0x21,
+ 0x66,0x0b,0x95,0xd7,0x0a,0x7c,0xca,0xa1,0xa9,0x5a,
+ 0xe8,0xac,0xe0,0x71,0x54,0xaf,0x28,0xcf,0xd5,0x70,
+ 0x89,0xe0,0xf3,0x9e,0x43,0x6c,0x8d,0x7b,0x99,0x01,
+ 0x68,0x4d,0xa1,0x45,0x46,0x0c,0x43,0xbc,0xcc,0x2c,
+ 0xdd,0xc5,0x46,0xc8,0x4e,0x0e,0xbe,0xed,0xb9,0x26,
+ 0xab,0x2e,0xdb,0xeb,0x8f,0xff,0xdb,0xb0,0xc6,0x55,
+ 0xaf,0xf8,0x2a,0x91,0x9d,0x50,0x44,0x21,0x17,
+ };
diff --git a/deps/openssl/openssl/apps/timeouts.h b/deps/openssl/openssl/apps/timeouts.h
new file mode 100644
index 000000000..89b5dc76f
--- /dev/null
+++ b/deps/openssl/openssl/apps/timeouts.h
@@ -0,0 +1,67 @@
+/* apps/timeouts.h */
+/*
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 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).
+ *
+ */
+
+#ifndef INCLUDED_TIMEOUTS_H
+#define INCLUDED_TIMEOUTS_H
+
+/* numbers in us */
+#define DGRAM_RCV_TIMEOUT 250000
+#define DGRAM_SND_TIMEOUT 250000
+
+#endif /* ! INCLUDED_TIMEOUTS_H */
diff --git a/deps/openssl/openssl/apps/ts.c b/deps/openssl/openssl/apps/ts.c
new file mode 100644
index 000000000..5fa9f7fda
--- /dev/null
+++ b/deps/openssl/openssl/apps/ts.c
@@ -0,0 +1,1147 @@
+/* apps/ts.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 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
+ * licensing@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).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/ts.h>
+#include <openssl/bn.h>
+
+#undef PROG
+#define PROG ts_main
+
+/* Length of the nonce of the request in bits (must be a multiple of 8). */
+#define NONCE_LENGTH 64
+
+/* Macro definitions for the configuration file. */
+#define ENV_OID_FILE "oid_file"
+
+/* Local function declarations. */
+
+static ASN1_OBJECT *txt2obj(const char *oid);
+static CONF *load_config_file(const char *configfile);
+
+/* Query related functions. */
+static int query_command(const char *data, char *digest,
+ const EVP_MD *md, const char *policy, int no_nonce,
+ int cert, const char *in, const char *out, int text);
+static BIO *BIO_open_with_default(const char *file, const char *mode,
+ FILE *default_fp);
+static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
+ const char *policy, int no_nonce, int cert);
+static int create_digest(BIO *input, char *digest,
+ const EVP_MD *md, unsigned char **md_value);
+static ASN1_INTEGER *create_nonce(int bits);
+
+/* Reply related functions. */
+static int reply_command(CONF *conf, char *section, char *engine,
+ char *queryfile, char *passin, char *inkey,
+ char *signer, char *chain, const char *policy,
+ char *in, int token_in, char *out, int token_out,
+ int text);
+static TS_RESP *read_PKCS7(BIO *in_bio);
+static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
+ char *queryfile, char *passin, char *inkey,
+ char *signer, char *chain, const char *policy);
+static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data);
+static ASN1_INTEGER *next_serial(const char *serialfile);
+static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
+
+/* Verify related functions. */
+static int verify_command(char *data, char *digest, char *queryfile,
+ char *in, int token_in,
+ char *ca_path, char *ca_file, char *untrusted);
+static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
+ char *queryfile,
+ char *ca_path, char *ca_file,
+ char *untrusted);
+static X509_STORE *create_cert_store(char *ca_path, char *ca_file);
+static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx);
+
+/* Main function definition. */
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ int ret = 1;
+ char *configfile = NULL;
+ char *section = NULL;
+ CONF *conf = NULL;
+ enum mode {
+ CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY
+ } mode = CMD_NONE;
+ char *data = NULL;
+ char *digest = NULL;
+ const EVP_MD *md = NULL;
+ char *rnd = NULL;
+ char *policy = NULL;
+ int no_nonce = 0;
+ int cert = 0;
+ char *in = NULL;
+ char *out = NULL;
+ int text = 0;
+ char *queryfile = NULL;
+ char *passin = NULL; /* Password source. */
+ char *password =NULL; /* Password itself. */
+ char *inkey = NULL;
+ char *signer = NULL;
+ char *chain = NULL;
+ char *ca_path = NULL;
+ char *ca_file = NULL;
+ char *untrusted = NULL;
+ char *engine = NULL;
+ /* Input is ContentInfo instead of TimeStampResp. */
+ int token_in = 0;
+ /* Output is ContentInfo instead of TimeStampResp. */
+ int token_out = 0;
+ int free_bio_err = 0;
+
+ ERR_load_crypto_strings();
+ apps_startup();
+
+ if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL)
+ {
+ free_bio_err = 1;
+ BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+ }
+
+ if (!load_config(bio_err, NULL))
+ goto cleanup;
+
+ for (argc--, argv++; argc > 0; argc--, argv++)
+ {
+ if (strcmp(*argv, "-config") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ configfile = *++argv;
+ }
+ else if (strcmp(*argv, "-section") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ section = *++argv;
+ }
+ else if (strcmp(*argv, "-query") == 0)
+ {
+ if (mode != CMD_NONE) goto usage;
+ mode = CMD_QUERY;
+ }
+ else if (strcmp(*argv, "-data") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ data = *++argv;
+ }
+ else if (strcmp(*argv, "-digest") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ digest = *++argv;
+ }
+ else if (strcmp(*argv, "-rand") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ rnd = *++argv;
+ }
+ else if (strcmp(*argv, "-policy") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ policy = *++argv;
+ }
+ else if (strcmp(*argv, "-no_nonce") == 0)
+ {
+ no_nonce = 1;
+ }
+ else if (strcmp(*argv, "-cert") == 0)
+ {
+ cert = 1;
+ }
+ else if (strcmp(*argv, "-in") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ in = *++argv;
+ }
+ else if (strcmp(*argv, "-token_in") == 0)
+ {
+ token_in = 1;
+ }
+ else if (strcmp(*argv, "-out") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ out = *++argv;
+ }
+ else if (strcmp(*argv, "-token_out") == 0)
+ {
+ token_out = 1;
+ }
+ else if (strcmp(*argv, "-text") == 0)
+ {
+ text = 1;
+ }
+ else if (strcmp(*argv, "-reply") == 0)
+ {
+ if (mode != CMD_NONE) goto usage;
+ mode = CMD_REPLY;
+ }
+ else if (strcmp(*argv, "-queryfile") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ queryfile = *++argv;
+ }
+ else if (strcmp(*argv, "-passin") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ passin = *++argv;
+ }
+ else if (strcmp(*argv, "-inkey") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ inkey = *++argv;
+ }
+ else if (strcmp(*argv, "-signer") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ signer = *++argv;
+ }
+ else if (strcmp(*argv, "-chain") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ chain = *++argv;
+ }
+ else if (strcmp(*argv, "-verify") == 0)
+ {
+ if (mode != CMD_NONE) goto usage;
+ mode = CMD_VERIFY;
+ }
+ else if (strcmp(*argv, "-CApath") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ ca_path = *++argv;
+ }
+ else if (strcmp(*argv, "-CAfile") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ ca_file = *++argv;
+ }
+ else if (strcmp(*argv, "-untrusted") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ untrusted = *++argv;
+ }
+ else if (strcmp(*argv, "-engine") == 0)
+ {
+ if (argc-- < 1) goto usage;
+ engine = *++argv;
+ }
+ else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL)
+ {
+ /* empty. */
+ }
+ else
+ goto usage;
+ }
+
+ /* Seed the random number generator if it is going to be used. */
+ if (mode == CMD_QUERY && !no_nonce)
+ {
+ if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL)
+ BIO_printf(bio_err, "warning, not much extra random "
+ "data, consider using the -rand option\n");
+ if (rnd != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(rnd));
+ }
+
+ /* Get the password if required. */
+ if(mode == CMD_REPLY && passin &&
+ !app_passwd(bio_err, passin, NULL, &password, NULL))
+ {
+ BIO_printf(bio_err,"Error getting password.\n");
+ goto cleanup;
+ }
+
+ /* Check consistency of parameters and execute
+ the appropriate function. */
+ switch (mode)
+ {
+ case CMD_NONE:
+ goto usage;
+ case CMD_QUERY:
+ /* Data file and message imprint cannot be specified
+ at the same time. */
+ ret = data != NULL && digest != NULL;
+ if (ret) goto usage;
+ /* Load the config file for possible policy OIDs. */
+ conf = load_config_file(configfile);
+ ret = !query_command(data, digest, md, policy, no_nonce, cert,
+ in, out, text);
+ break;
+ case CMD_REPLY:
+ conf = load_config_file(configfile);
+ if (in == NULL)
+ {
+ ret = !(queryfile != NULL && conf != NULL && !token_in);
+ if (ret) goto usage;
+ }
+ else
+ {
+ /* 'in' and 'queryfile' are exclusive. */
+ ret = !(queryfile == NULL);
+ if (ret) goto usage;
+ }
+
+ ret = !reply_command(conf, section, engine, queryfile,
+ password, inkey, signer, chain, policy,
+ in, token_in, out, token_out, text);
+ break;
+ case CMD_VERIFY:
+ ret = !(((queryfile && !data && !digest)
+ || (!queryfile && data && !digest)
+ || (!queryfile && !data && digest))
+ && in != NULL);
+ if (ret) goto usage;
+
+ ret = !verify_command(data, digest, queryfile, in, token_in,
+ ca_path, ca_file, untrusted);
+ }
+
+ goto cleanup;
+
+ usage:
+ BIO_printf(bio_err, "usage:\n"
+ "ts -query [-rand file%cfile%c...] [-config configfile] "
+ "[-data file_to_hash] [-digest digest_bytes]"
+ "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] "
+ "[-policy object_id] [-no_nonce] [-cert] "
+ "[-in request.tsq] [-out request.tsq] [-text]\n",
+ LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err, "or\n"
+ "ts -reply [-config configfile] [-section tsa_section] "
+ "[-queryfile request.tsq] [-passin password] "
+ "[-signer tsa_cert.pem] [-inkey private_key.pem] "
+ "[-chain certs_file.pem] [-policy object_id] "
+ "[-in response.tsr] [-token_in] "
+ "[-out response.tsr] [-token_out] [-text] [-engine id]\n");
+ BIO_printf(bio_err, "or\n"
+ "ts -verify [-data file_to_hash] [-digest digest_bytes] "
+ "[-queryfile request.tsq] "
+ "-in response.tsr [-token_in] "
+ "-CApath ca_path -CAfile ca_file.pem "
+ "-untrusted cert_file.pem\n");
+ cleanup:
+ /* Clean up. */
+ app_RAND_write_file(NULL, bio_err);
+ NCONF_free(conf);
+ OPENSSL_free(password);
+ OBJ_cleanup();
+ if (free_bio_err)
+ {
+ BIO_free_all(bio_err);
+ bio_err = NULL;
+ }
+
+ OPENSSL_EXIT(ret);
+ }
+
+/*
+ * Configuration file-related function definitions.
+ */
+
+static ASN1_OBJECT *txt2obj(const char *oid)
+ {
+ ASN1_OBJECT *oid_obj = NULL;
+
+ if (!(oid_obj = OBJ_txt2obj(oid, 0)))
+ BIO_printf(bio_err, "cannot convert %s to OID\n", oid);
+
+ return oid_obj;
+ }
+
+static CONF *load_config_file(const char *configfile)
+ {
+ CONF *conf = NULL;
+ long errorline = -1;
+
+ if (!configfile) configfile = getenv("OPENSSL_CONF");
+ if (!configfile) configfile = getenv("SSLEAY_CONF");
+
+ if (configfile &&
+ (!(conf = NCONF_new(NULL)) ||
+ NCONF_load(conf, configfile, &errorline) <= 0))
+ {
+ if (errorline <= 0)
+ BIO_printf(bio_err, "error loading the config file "
+ "'%s'\n", configfile);
+ else
+ BIO_printf(bio_err, "error on line %ld of config file "
+ "'%s'\n", errorline, configfile);
+ }
+
+ if (conf != NULL)
+ {
+ const char *p;
+
+ BIO_printf(bio_err,"Using configuration from %s\n", configfile);
+ p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
+ if (p != NULL)
+ {
+ BIO *oid_bio = BIO_new_file(p, "r");
+ if (!oid_bio)
+ ERR_print_errors(bio_err);
+ else
+ {
+ OBJ_create_objects(oid_bio);
+ BIO_free_all(oid_bio);
+ }
+ }
+ else
+ ERR_clear_error();
+ if(!add_oid_section(bio_err, conf))
+ ERR_print_errors(bio_err);
+ }
+ return conf;
+ }
+
+/*
+ * Query-related method definitions.
+ */
+
+static int query_command(const char *data, char *digest, const EVP_MD *md,
+ const char *policy, int no_nonce,
+ int cert, const char *in, const char *out, int text)
+ {
+ int ret = 0;
+ TS_REQ *query = NULL;
+ BIO *in_bio = NULL;
+ BIO *data_bio = NULL;
+ BIO *out_bio = NULL;
+
+ /* Build query object either from file or from scratch. */
+ if (in != NULL)
+ {
+ if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
+ query = d2i_TS_REQ_bio(in_bio, NULL);
+ }
+ else
+ {
+ /* Open the file if no explicit digest bytes were specified. */
+ if (!digest
+ && !(data_bio = BIO_open_with_default(data, "rb", stdin)))
+ goto end;
+ /* Creating the query object. */
+ query = create_query(data_bio, digest, md,
+ policy, no_nonce, cert);
+ /* Saving the random number generator state. */
+ }
+ if (query == NULL) goto end;
+
+ /* Write query either in ASN.1 or in text format. */
+ if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
+ goto end;
+ if (text)
+ {
+ /* Text output. */
+ if (!TS_REQ_print_bio(out_bio, query))
+ goto end;
+ }
+ else
+ {
+ /* ASN.1 output. */
+ if (!i2d_TS_REQ_bio(out_bio, query))
+ goto end;
+ }
+
+ ret = 1;
+
+ end:
+ ERR_print_errors(bio_err);
+
+ /* Clean up. */
+ BIO_free_all(in_bio);
+ BIO_free_all(data_bio);
+ BIO_free_all(out_bio);
+ TS_REQ_free(query);
+
+ return ret;
+ }
+
+static BIO *BIO_open_with_default(const char *file, const char *mode,
+ FILE *default_fp)
+ {
+ return file == NULL ?
+ BIO_new_fp(default_fp, BIO_NOCLOSE)
+ : BIO_new_file(file, mode);
+ }
+
+static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
+ const char *policy, int no_nonce, int cert)
+ {
+ int ret = 0;
+ TS_REQ *ts_req = NULL;
+ int len;
+ TS_MSG_IMPRINT *msg_imprint = NULL;
+ X509_ALGOR *algo = NULL;
+ unsigned char *data = NULL;
+ ASN1_OBJECT *policy_obj = NULL;
+ ASN1_INTEGER *nonce_asn1 = NULL;
+
+ /* Setting default message digest. */
+ if (!md && !(md = EVP_get_digestbyname("sha1"))) goto err;
+
+ /* Creating request object. */
+ if (!(ts_req = TS_REQ_new())) goto err;
+
+ /* Setting version. */
+ if (!TS_REQ_set_version(ts_req, 1)) goto err;
+
+ /* Creating and adding MSG_IMPRINT object. */
+ if (!(msg_imprint = TS_MSG_IMPRINT_new())) goto err;
+
+ /* Adding algorithm. */
+ if (!(algo = X509_ALGOR_new())) goto err;
+ if (!(algo->algorithm = OBJ_nid2obj(EVP_MD_type(md)))) goto err;
+ if (!(algo->parameter = ASN1_TYPE_new())) goto err;
+ algo->parameter->type = V_ASN1_NULL;
+ if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err;
+
+ /* Adding message digest. */
+ if ((len = create_digest(data_bio, digest, md, &data)) == 0)
+ goto err;
+ if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) goto err;
+
+ if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err;
+
+ /* Setting policy if requested. */
+ if (policy && !(policy_obj = txt2obj(policy))) goto err;
+ if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err;
+
+ /* Setting nonce if requested. */
+ if (!no_nonce && !(nonce_asn1 = create_nonce(NONCE_LENGTH))) goto err;
+ if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err;
+
+ /* Setting certificate request flag if requested. */
+ if (!TS_REQ_set_cert_req(ts_req, cert)) goto err;
+
+ ret = 1;
+ err:
+ if (!ret)
+ {
+ TS_REQ_free(ts_req);
+ ts_req = NULL;
+ BIO_printf(bio_err, "could not create query\n");
+ }
+ TS_MSG_IMPRINT_free(msg_imprint);
+ X509_ALGOR_free(algo);
+ OPENSSL_free(data);
+ ASN1_OBJECT_free(policy_obj);
+ ASN1_INTEGER_free(nonce_asn1);
+ return ts_req;
+ }
+
+static int create_digest(BIO *input, char *digest, const EVP_MD *md,
+ unsigned char **md_value)
+ {
+ int md_value_len;
+
+ md_value_len = EVP_MD_size(md);
+ if (md_value_len < 0)
+ goto err;
+ if (input)
+ {
+ /* Digest must be computed from an input file. */
+ EVP_MD_CTX md_ctx;
+ unsigned char buffer[4096];
+ int length;
+
+ *md_value = OPENSSL_malloc(md_value_len);
+ if (*md_value == 0) goto err;
+
+ EVP_DigestInit(&md_ctx, md);
+ while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0)
+ {
+ EVP_DigestUpdate(&md_ctx, buffer, length);
+ }
+ EVP_DigestFinal(&md_ctx, *md_value, NULL);
+ }
+ else
+ {
+ /* Digest bytes are specified with digest. */
+ long digest_len;
+ *md_value = string_to_hex(digest, &digest_len);
+ if (!*md_value || md_value_len != digest_len)
+ {
+ OPENSSL_free(*md_value);
+ *md_value = NULL;
+ BIO_printf(bio_err, "bad digest, %d bytes "
+ "must be specified\n", md_value_len);
+ goto err;
+ }
+ }
+
+ return md_value_len;
+ err:
+ return 0;
+ }
+
+static ASN1_INTEGER *create_nonce(int bits)
+ {
+ unsigned char buf[20];
+ ASN1_INTEGER *nonce = NULL;
+ int len = (bits - 1) / 8 + 1;
+ int i;
+
+ /* Generating random byte sequence. */
+ if (len > (int)sizeof(buf)) goto err;
+ if (RAND_bytes(buf, len) <= 0) goto err;
+
+ /* Find the first non-zero byte and creating ASN1_INTEGER object. */
+ for (i = 0; i < len && !buf[i]; ++i);
+ if (!(nonce = ASN1_INTEGER_new())) goto err;
+ OPENSSL_free(nonce->data);
+ /* Allocate at least one byte. */
+ nonce->length = len - i;
+ if (!(nonce->data = OPENSSL_malloc(nonce->length + 1))) goto err;
+ memcpy(nonce->data, buf + i, nonce->length);
+
+ return nonce;
+ err:
+ BIO_printf(bio_err, "could not create nonce\n");
+ ASN1_INTEGER_free(nonce);
+ return NULL;
+ }
+/*
+ * Reply-related method definitions.
+ */
+
+static int reply_command(CONF *conf, char *section, char *engine,
+ char *queryfile, char *passin, char *inkey,
+ char *signer, char *chain, const char *policy,
+ char *in, int token_in,
+ char *out, int token_out, int text)
+ {
+ int ret = 0;
+ TS_RESP *response = NULL;
+ BIO *in_bio = NULL;
+ BIO *query_bio = NULL;
+ BIO *inkey_bio = NULL;
+ BIO *signer_bio = NULL;
+ BIO *out_bio = NULL;
+
+ /* Build response object either from response or query. */
+ if (in != NULL)
+ {
+ if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
+ if (token_in)
+ {
+ /* We have a ContentInfo (PKCS7) object, add
+ 'granted' status info around it. */
+ response = read_PKCS7(in_bio);
+ }
+ else
+ {
+ /* We have a ready-made TS_RESP object. */
+ response = d2i_TS_RESP_bio(in_bio, NULL);
+ }
+ }
+ else
+ {
+ response = create_response(conf, section, engine, queryfile,
+ passin, inkey, signer, chain,
+ policy);
+ if (response)
+ BIO_printf(bio_err, "Response has been generated.\n");
+ else
+ BIO_printf(bio_err, "Response is not generated.\n");
+ }
+ if (response == NULL) goto end;
+
+ /* Write response either in ASN.1 or text format. */
+ if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
+ goto end;
+ if (text)
+ {
+ /* Text output. */
+ if (token_out)
+ {
+ TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
+ if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end;
+ }
+ else
+ {
+ if (!TS_RESP_print_bio(out_bio, response)) goto end;
+ }
+ }
+ else
+ {
+ /* ASN.1 DER output. */
+ if (token_out)
+ {
+ PKCS7 *token = TS_RESP_get_token(response);
+ if (!i2d_PKCS7_bio(out_bio, token)) goto end;
+ }
+ else
+ {
+ if (!i2d_TS_RESP_bio(out_bio, response)) goto end;
+ }
+ }
+
+ ret = 1;
+
+ end:
+ ERR_print_errors(bio_err);
+
+ /* Clean up. */
+ BIO_free_all(in_bio);
+ BIO_free_all(query_bio);
+ BIO_free_all(inkey_bio);
+ BIO_free_all(signer_bio);
+ BIO_free_all(out_bio);
+ TS_RESP_free(response);
+
+ return ret;
+ }
+
+/* Reads a PKCS7 token and adds default 'granted' status info to it. */
+static TS_RESP *read_PKCS7(BIO *in_bio)
+ {
+ int ret = 0;
+ PKCS7 *token = NULL;
+ TS_TST_INFO *tst_info = NULL;
+ TS_RESP *resp = NULL;
+ TS_STATUS_INFO *si = NULL;
+
+ /* Read PKCS7 object and extract the signed time stamp info. */
+ if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end;
+ if (!(tst_info = PKCS7_to_TS_TST_INFO(token))) goto end;
+
+ /* Creating response object. */
+ if (!(resp = TS_RESP_new())) goto end;
+
+ /* Create granted status info. */
+ if (!(si = TS_STATUS_INFO_new())) goto end;
+ if (!(ASN1_INTEGER_set(si->status, TS_STATUS_GRANTED))) goto end;
+ if (!TS_RESP_set_status_info(resp, si)) goto end;
+
+ /* Setting encapsulated token. */
+ TS_RESP_set_tst_info(resp, token, tst_info);
+ token = NULL; /* Ownership is lost. */
+ tst_info = NULL; /* Ownership is lost. */
+
+ ret = 1;
+ end:
+ PKCS7_free(token);
+ TS_TST_INFO_free(tst_info);
+ if (!ret)
+ {
+ TS_RESP_free(resp);
+ resp = NULL;
+ }
+ TS_STATUS_INFO_free(si);
+ return resp;
+ }
+
+static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
+ char *queryfile, char *passin, char *inkey,
+ char *signer, char *chain, const char *policy)
+ {
+ int ret = 0;
+ TS_RESP *response = NULL;
+ BIO *query_bio = NULL;
+ TS_RESP_CTX *resp_ctx = NULL;
+
+ if (!(query_bio = BIO_new_file(queryfile, "rb")))
+ goto end;
+
+ /* Getting TSA configuration section. */
+ if (!(section = TS_CONF_get_tsa_section(conf, section)))
+ goto end;
+
+ /* Setting up response generation context. */
+ if (!(resp_ctx = TS_RESP_CTX_new())) goto end;
+
+ /* Setting serial number provider callback. */
+ if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) goto end;
+#ifndef OPENSSL_NO_ENGINE
+ /* Setting default OpenSSL engine. */
+ if (!TS_CONF_set_crypto_device(conf, section, engine)) goto end;
+#endif
+
+ /* Setting TSA signer certificate. */
+ if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) goto end;
+
+ /* Setting TSA signer certificate chain. */
+ if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end;
+
+ /* Setting TSA signer private key. */
+ if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
+ goto end;
+
+ /* Setting default policy OID. */
+ if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end;
+
+ /* Setting acceptable policy OIDs. */
+ if (!TS_CONF_set_policies(conf, section, resp_ctx)) goto end;
+
+ /* Setting the acceptable one-way hash algorithms. */
+ if (!TS_CONF_set_digests(conf, section, resp_ctx)) goto end;
+
+ /* Setting guaranteed time stamp accuracy. */
+ if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) goto end;
+
+ /* Setting the precision of the time. */
+ if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx))
+ goto end;
+
+ /* Setting the ordering flaf if requested. */
+ if (!TS_CONF_set_ordering(conf, section, resp_ctx)) goto end;
+
+ /* Setting the TSA name required flag if requested. */
+ if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) goto end;
+
+ /* Setting the ESS cert id chain flag if requested. */
+ if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) goto end;
+
+ /* Creating the response. */
+ if (!(response = TS_RESP_create_response(resp_ctx, query_bio)))
+ goto end;
+
+ ret = 1;
+ end:
+ if (!ret)
+ {
+ TS_RESP_free(response);
+ response = NULL;
+ }
+ TS_RESP_CTX_free(resp_ctx);
+ BIO_free_all(query_bio);
+
+ return response;
+ }
+
+static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data)
+ {
+ const char *serial_file = (const char *) data;
+ ASN1_INTEGER *serial = next_serial(serial_file);
+
+ if (!serial)
+ {
+ TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+ "Error during serial number "
+ "generation.");
+ TS_RESP_CTX_add_failure_info(ctx,
+ TS_INFO_ADD_INFO_NOT_AVAILABLE);
+ }
+ else
+ save_ts_serial(serial_file, serial);
+
+ return serial;
+ }
+
+static ASN1_INTEGER *next_serial(const char *serialfile)
+ {
+ int ret = 0;
+ BIO *in = NULL;
+ ASN1_INTEGER *serial = NULL;
+ BIGNUM *bn = NULL;
+
+ if (!(serial = ASN1_INTEGER_new())) goto err;
+
+ if (!(in = BIO_new_file(serialfile, "r")))
+ {
+ ERR_clear_error();
+ BIO_printf(bio_err, "Warning: could not open file %s for "
+ "reading, using serial number: 1\n", serialfile);
+ if (!ASN1_INTEGER_set(serial, 1)) goto err;
+ }
+ else
+ {
+ char buf[1024];
+ if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf)))
+ {
+ BIO_printf(bio_err, "unable to load number from %s\n",
+ serialfile);
+ goto err;
+ }
+ if (!(bn = ASN1_INTEGER_to_BN(serial, NULL))) goto err;
+ ASN1_INTEGER_free(serial);
+ serial = NULL;
+ if (!BN_add_word(bn, 1)) goto err;
+ if (!(serial = BN_to_ASN1_INTEGER(bn, NULL))) goto err;
+ }
+ ret = 1;
+ err:
+ if (!ret)
+ {
+ ASN1_INTEGER_free(serial);
+ serial = NULL;
+ }
+ BIO_free_all(in);
+ BN_free(bn);
+ return serial;
+ }
+
+static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial)
+ {
+ int ret = 0;
+ BIO *out = NULL;
+
+ if (!(out = BIO_new_file(serialfile, "w"))) goto err;
+ if (i2a_ASN1_INTEGER(out, serial) <= 0) goto err;
+ if (BIO_puts(out, "\n") <= 0) goto err;
+ ret = 1;
+ err:
+ if (!ret)
+ BIO_printf(bio_err, "could not save serial number to %s\n",
+ serialfile);
+ BIO_free_all(out);
+ return ret;
+ }
+
+/*
+ * Verify-related method definitions.
+ */
+
+static int verify_command(char *data, char *digest, char *queryfile,
+ char *in, int token_in,
+ char *ca_path, char *ca_file, char *untrusted)
+ {
+ BIO *in_bio = NULL;
+ PKCS7 *token = NULL;
+ TS_RESP *response = NULL;
+ TS_VERIFY_CTX *verify_ctx = NULL;
+ int ret = 0;
+
+ /* Decode the token (PKCS7) or response (TS_RESP) files. */
+ if (!(in_bio = BIO_new_file(in, "rb"))) goto end;
+ if (token_in)
+ {
+ if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end;
+ }
+ else
+ {
+ if (!(response = d2i_TS_RESP_bio(in_bio, NULL))) goto end;
+ }
+
+ if (!(verify_ctx = create_verify_ctx(data, digest, queryfile,
+ ca_path, ca_file, untrusted)))
+ goto end;
+
+ /* Checking the token or response against the request. */
+ ret = token_in ?
+ TS_RESP_verify_token(verify_ctx, token) :
+ TS_RESP_verify_response(verify_ctx, response);
+
+ end:
+ printf("Verification: ");
+ if (ret)
+ printf("OK\n");
+ else
+ {
+ printf("FAILED\n");
+ /* Print errors, if there are any. */
+ ERR_print_errors(bio_err);
+ }
+
+ /* Clean up. */
+ BIO_free_all(in_bio);
+ PKCS7_free(token);
+ TS_RESP_free(response);
+ TS_VERIFY_CTX_free(verify_ctx);
+ return ret;
+ }
+
+static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
+ char *queryfile,
+ char *ca_path, char *ca_file,
+ char *untrusted)
+ {
+ TS_VERIFY_CTX *ctx = NULL;
+ BIO *input = NULL;
+ TS_REQ *request = NULL;
+ int ret = 0;
+
+ if (data != NULL || digest != NULL)
+ {
+ if (!(ctx = TS_VERIFY_CTX_new())) goto err;
+ ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER;
+ if (data != NULL)
+ {
+ ctx->flags |= TS_VFY_DATA;
+ if (!(ctx->data = BIO_new_file(data, "rb"))) goto err;
+ }
+ else if (digest != NULL)
+ {
+ long imprint_len;
+ ctx->flags |= TS_VFY_IMPRINT;
+ if (!(ctx->imprint = string_to_hex(digest,
+ &imprint_len)))
+ {
+ BIO_printf(bio_err, "invalid digest string\n");
+ goto err;
+ }
+ ctx->imprint_len = imprint_len;
+ }
+
+ }
+ else if (queryfile != NULL)
+ {
+ /* The request has just to be read, decoded and converted to
+ a verify context object. */
+ if (!(input = BIO_new_file(queryfile, "rb"))) goto err;
+ if (!(request = d2i_TS_REQ_bio(input, NULL))) goto err;
+ if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL))) goto err;
+ }
+ else
+ return NULL;
+
+ /* Add the signature verification flag and arguments. */
+ ctx->flags |= TS_VFY_SIGNATURE;
+
+ /* Initialising the X509_STORE object. */
+ if (!(ctx->store = create_cert_store(ca_path, ca_file))) goto err;
+
+ /* Loading untrusted certificates. */
+ if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted)))
+ goto err;
+
+ ret = 1;
+ err:
+ if (!ret)
+ {
+ TS_VERIFY_CTX_free(ctx);
+ ctx = NULL;
+ }
+ BIO_free_all(input);
+ TS_REQ_free(request);
+ return ctx;
+ }
+
+static X509_STORE *create_cert_store(char *ca_path, char *ca_file)
+ {
+ X509_STORE *cert_ctx = NULL;
+ X509_LOOKUP *lookup = NULL;
+ int i;
+
+ /* Creating the X509_STORE object. */
+ cert_ctx = X509_STORE_new();
+
+ /* Setting the callback for certificate chain verification. */
+ X509_STORE_set_verify_cb(cert_ctx, verify_cb);
+
+ /* Adding a trusted certificate directory source. */
+ if (ca_path)
+ {
+ lookup = X509_STORE_add_lookup(cert_ctx,
+ X509_LOOKUP_hash_dir());
+ if (lookup == NULL)
+ {
+ BIO_printf(bio_err, "memory allocation failure\n");
+ goto err;
+ }
+ i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM);
+ if (!i)
+ {
+ BIO_printf(bio_err, "Error loading directory %s\n",
+ ca_path);
+ goto err;
+ }
+ }
+
+ /* Adding a trusted certificate file source. */
+ if (ca_file)
+ {
+ lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
+ if (lookup == NULL)
+ {
+ BIO_printf(bio_err, "memory allocation failure\n");
+ goto err;
+ }
+ i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM);
+ if (!i)
+ {
+ BIO_printf(bio_err, "Error loading file %s\n", ca_file);
+ goto err;
+ }
+ }
+
+ return cert_ctx;
+ err:
+ X509_STORE_free(cert_ctx);
+ return NULL;
+ }
+
+static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx)
+ {
+ /*
+ char buf[256];
+
+ if (!ok)
+ {
+ X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
+ buf, sizeof(buf));
+ printf("%s\n", buf);
+ printf("error %d at %d depth lookup: %s\n",
+ ctx->error, ctx->error_depth,
+ X509_verify_cert_error_string(ctx->error));
+ }
+ */
+
+ return ok;
+ }
diff --git a/deps/openssl/openssl/apps/tsget b/deps/openssl/openssl/apps/tsget
new file mode 100644
index 000000000..0d54e9fc9
--- /dev/null
+++ b/deps/openssl/openssl/apps/tsget
@@ -0,0 +1,196 @@
+#!/usr/bin/perl -w
+# Written by Zoltan Glozik <zglozik@stones.com>.
+# Copyright (c) 2002 The OpenTSA Project. All rights reserved.
+$::version = '$Id: tsget,v 1.1.2.2 2009/09/07 17:57:02 steve Exp $';
+
+use strict;
+use IO::Handle;
+use Getopt::Std;
+use File::Basename;
+use WWW::Curl::Easy;
+
+use vars qw(%options);
+
+# Callback for reading the body.
+sub read_body {
+ my ($maxlength, $state) = @_;
+ my $return_data = "";
+ my $data_len = length ${$state->{data}};
+ if ($state->{bytes} < $data_len) {
+ $data_len = $data_len - $state->{bytes};
+ $data_len = $maxlength if $data_len > $maxlength;
+ $return_data = substr ${$state->{data}}, $state->{bytes}, $data_len;
+ $state->{bytes} += $data_len;
+ }
+ return $return_data;
+}
+
+# Callback for writing the body into a variable.
+sub write_body {
+ my ($data, $pointer) = @_;
+ ${$pointer} .= $data;
+ return length($data);
+}
+
+# Initialise a new Curl object.
+sub create_curl {
+ my $url = shift;
+
+ # Create Curl object.
+ my $curl = WWW::Curl::Easy::new();
+
+ # Error-handling related options.
+ $curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
+ $curl->setopt(CURLOPT_FAILONERROR, 1);
+ $curl->setopt(CURLOPT_USERAGENT, "OpenTSA tsget.pl/" . (split / /, $::version)[2]);
+
+ # Options for POST method.
+ $curl->setopt(CURLOPT_UPLOAD, 1);
+ $curl->setopt(CURLOPT_CUSTOMREQUEST, "POST");
+ $curl->setopt(CURLOPT_HTTPHEADER,
+ ["Content-Type: application/timestamp-query",
+ "Accept: application/timestamp-reply,application/timestamp-response"]);
+ $curl->setopt(CURLOPT_READFUNCTION, \&read_body);
+ $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($_[0]); });
+
+ # Options for getting the result.
+ $curl->setopt(CURLOPT_WRITEFUNCTION, \&write_body);
+
+ # SSL related options.
+ $curl->setopt(CURLOPT_SSLKEYTYPE, "PEM");
+ $curl->setopt(CURLOPT_SSL_VERIFYPEER, 1); # Verify server's certificate.
+ $curl->setopt(CURLOPT_SSL_VERIFYHOST, 2); # Check server's CN.
+ $curl->setopt(CURLOPT_SSLKEY, $options{k}) if defined($options{k});
+ $curl->setopt(CURLOPT_SSLKEYPASSWD, $options{p}) if defined($options{p});
+ $curl->setopt(CURLOPT_SSLCERT, $options{c}) if defined($options{c});
+ $curl->setopt(CURLOPT_CAINFO, $options{C}) if defined($options{C});
+ $curl->setopt(CURLOPT_CAPATH, $options{P}) if defined($options{P});
+ $curl->setopt(CURLOPT_RANDOM_FILE, $options{r}) if defined($options{r});
+ $curl->setopt(CURLOPT_EGDSOCKET, $options{g}) if defined($options{g});
+
+ # Setting destination.
+ $curl->setopt(CURLOPT_URL, $url);
+
+ return $curl;
+}
+
+# Send a request and returns the body back.
+sub get_timestamp {
+ my $curl = shift;
+ my $body = shift;
+ my $ts_body;
+ local $::error_buf;
+
+ # Error-handling related options.
+ $curl->setopt(CURLOPT_ERRORBUFFER, "::error_buf");
+
+ # Options for POST method.
+ $curl->setopt(CURLOPT_INFILE, {data => $body, bytes => 0});
+ $curl->setopt(CURLOPT_INFILESIZE, length(${$body}));
+
+ # Options for getting the result.
+ $curl->setopt(CURLOPT_FILE, \$ts_body);
+
+ # Send the request...
+ my $error_code = $curl->perform();
+ my $error_string;
+ if ($error_code != 0) {
+ my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE);
+ $error_string = "could not get timestamp";
+ $error_string .= ", http code: $http_code" unless $http_code == 0;
+ $error_string .= ", curl code: $error_code";
+ $error_string .= " ($::error_buf)" if defined($::error_buf);
+ } else {
+ my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE);
+ if (lc($ct) ne "application/timestamp-reply"
+ && lc($ct) ne "application/timestamp-response") {
+ $error_string = "unexpected content type returned: $ct";
+ }
+ }
+ return ($ts_body, $error_string);
+
+}
+
+# Print usage information and exists.
+sub usage {
+
+ print STDERR "usage: $0 -h <server_url> [-e <extension>] [-o <output>] ";
+ print STDERR "[-v] [-d] [-k <private_key.pem>] [-p <key_password>] ";
+ print STDERR "[-c <client_cert.pem>] [-C <CA_certs.pem>] [-P <CA_path>] ";
+ print STDERR "[-r <file:file...>] [-g <EGD_socket>] [<request>]...\n";
+ exit 1;
+}
+
+# ----------------------------------------------------------------------
+# Main program
+# ----------------------------------------------------------------------
+
+# Getting command-line options (default comes from TSGET environment variable).
+my $getopt_arg = "h:e:o:vdk:p:c:C:P:r:g:";
+if (exists $ENV{TSGET}) {
+ my @old_argv = @ARGV;
+ @ARGV = split /\s+/, $ENV{TSGET};
+ getopts($getopt_arg, \%options) or usage;
+ @ARGV = @old_argv;
+}
+getopts($getopt_arg, \%options) or usage;
+
+# Checking argument consistency.
+if (!exists($options{h}) || (@ARGV == 0 && !exists($options{o}))
+ || (@ARGV > 1 && exists($options{o}))) {
+ print STDERR "Inconsistent command line options.\n";
+ usage;
+}
+# Setting defaults.
+@ARGV = ("-") unless @ARGV != 0;
+$options{e} = ".tsr" unless defined($options{e});
+
+# Processing requests.
+my $curl = create_curl $options{h};
+undef $/; # For reading whole files.
+REQUEST: foreach (@ARGV) {
+ my $input = $_;
+ my ($base, $path) = fileparse($input, '\.[^.]*');
+ my $output_base = $base . $options{e};
+ my $output = defined($options{o}) ? $options{o} : $path . $output_base;
+
+ STDERR->printflush("$input: ") if $options{v};
+ # Read request.
+ my $body;
+ if ($input eq "-") {
+ # Read the request from STDIN;
+ $body = <STDIN>;
+ } else {
+ # Read the request from file.
+ open INPUT, "<" . $input
+ or warn("$input: could not open input file: $!\n"), next REQUEST;
+ $body = <INPUT>;
+ close INPUT
+ or warn("$input: could not close input file: $!\n"), next REQUEST;
+ }
+
+ # Send request.
+ STDERR->printflush("sending request") if $options{v};
+
+ my ($ts_body, $error) = get_timestamp $curl, \$body;
+ if (defined($error)) {
+ die "$input: fatal error: $error\n";
+ }
+ STDERR->printflush(", reply received") if $options{v};
+
+ # Write response.
+ if ($output eq "-") {
+ # Write to STDOUT.
+ print $ts_body;
+ } else {
+ # Write to file.
+ open OUTPUT, ">", $output
+ or warn("$output: could not open output file: $!\n"), next REQUEST;
+ print OUTPUT $ts_body;
+ close OUTPUT
+ or warn("$output: could not close output file: $!\n"), next REQUEST;
+ }
+ STDERR->printflush(", $output written.\n") if $options{v};
+}
+$curl->cleanup();
+WWW::Curl::Easy::global_cleanup();
diff --git a/deps/openssl/openssl/apps/verify.c b/deps/openssl/openssl/apps/verify.c
new file mode 100644
index 000000000..893670ff4
--- /dev/null
+++ b/deps/openssl/openssl/apps/verify.c
@@ -0,0 +1,362 @@
+/* apps/verify.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG verify_main
+
+static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx);
+static int check(X509_STORE *ctx, char *file,
+ STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
+ STACK_OF(X509_CRL) *crls, ENGINE *e);
+static int v_verbose=0, vflags = 0;
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ int i,ret=1, badarg = 0;
+ char *CApath=NULL,*CAfile=NULL;
+ char *untfile = NULL, *trustfile = NULL, *crlfile = NULL;
+ STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
+ STACK_OF(X509_CRL) *crls = NULL;
+ X509_STORE *cert_ctx=NULL;
+ X509_LOOKUP *lookup=NULL;
+ X509_VERIFY_PARAM *vpm = NULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+
+ cert_ctx=X509_STORE_new();
+ if (cert_ctx == NULL) goto end;
+ X509_STORE_set_verify_cb(cert_ctx,cb);
+
+ ERR_load_crypto_strings();
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+
+ argc--;
+ argv++;
+ for (;;)
+ {
+ if (argc >= 1)
+ {
+ if (strcmp(*argv,"-CApath") == 0)
+ {
+ if (argc-- < 1) goto end;
+ CApath= *(++argv);
+ }
+ else if (strcmp(*argv,"-CAfile") == 0)
+ {
+ if (argc-- < 1) goto end;
+ CAfile= *(++argv);
+ }
+ else if (args_verify(&argv, &argc, &badarg, bio_err,
+ &vpm))
+ {
+ if (badarg)
+ goto end;
+ continue;
+ }
+ else if (strcmp(*argv,"-untrusted") == 0)
+ {
+ if (argc-- < 1) goto end;
+ untfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-trusted") == 0)
+ {
+ if (argc-- < 1) goto end;
+ trustfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-CRLfile") == 0)
+ {
+ if (argc-- < 1) goto end;
+ crlfile= *(++argv);
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto end;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-help") == 0)
+ goto end;
+ else if (strcmp(*argv,"-verbose") == 0)
+ v_verbose=1;
+ else if (argv[0][0] == '-')
+ goto end;
+ else
+ break;
+ argc--;
+ argv++;
+ }
+ else
+ break;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if (vpm)
+ X509_STORE_set1_param(cert_ctx, vpm);
+
+ lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_file());
+ if (lookup == NULL) abort();
+ if (CAfile) {
+ i=X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM);
+ if(!i) {
+ BIO_printf(bio_err, "Error loading file %s\n", CAfile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ } else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
+
+ lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_hash_dir());
+ if (lookup == NULL) abort();
+ if (CApath) {
+ i=X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM);
+ if(!i) {
+ BIO_printf(bio_err, "Error loading directory %s\n", CApath);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ } else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
+
+ ERR_clear_error();
+
+ if(untfile)
+ {
+ untrusted = load_certs(bio_err, untfile, FORMAT_PEM,
+ NULL, e, "untrusted certificates");
+ if(!untrusted)
+ goto end;
+ }
+
+ if(trustfile)
+ {
+ trusted = load_certs(bio_err, trustfile, FORMAT_PEM,
+ NULL, e, "trusted certificates");
+ if(!trusted)
+ goto end;
+ }
+
+ if(crlfile)
+ {
+ crls = load_crls(bio_err, crlfile, FORMAT_PEM,
+ NULL, e, "other CRLs");
+ if(!crls)
+ goto end;
+ }
+
+ ret = 0;
+ if (argc < 1)
+ {
+ if (1 != check(cert_ctx, NULL, untrusted, trusted, crls, e))
+ ret = -1;
+ }
+ else
+ {
+ for (i=0; i<argc; i++)
+ if (1 != check(cert_ctx,argv[i], untrusted, trusted, crls, e))
+ ret = -1;
+ }
+
+end:
+ if (ret == 1) {
+ BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]");
+ BIO_printf(bio_err," [-attime timestamp]");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err," [-engine e]");
+#endif
+ BIO_printf(bio_err," cert1 cert2 ...\n");
+
+ BIO_printf(bio_err,"recognized usages:\n");
+ for(i = 0; i < X509_PURPOSE_get_count(); i++)
+ {
+ X509_PURPOSE *ptmp;
+ ptmp = X509_PURPOSE_get0(i);
+ BIO_printf(bio_err, "\t%-10s\t%s\n",
+ X509_PURPOSE_get0_sname(ptmp),
+ X509_PURPOSE_get0_name(ptmp));
+ }
+ }
+ if (vpm) X509_VERIFY_PARAM_free(vpm);
+ if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
+ sk_X509_pop_free(untrusted, X509_free);
+ sk_X509_pop_free(trusted, X509_free);
+ sk_X509_CRL_pop_free(crls, X509_CRL_free);
+ apps_shutdown();
+ OPENSSL_EXIT(ret < 0 ? 2 : ret);
+ }
+
+static int check(X509_STORE *ctx, char *file,
+ STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
+ STACK_OF(X509_CRL) *crls, ENGINE *e)
+ {
+ X509 *x=NULL;
+ int i=0,ret=0;
+ X509_STORE_CTX *csc;
+
+ x = load_cert(bio_err, file, FORMAT_PEM, NULL, e, "certificate file");
+ if (x == NULL)
+ goto end;
+ fprintf(stdout,"%s: ",(file == NULL)?"stdin":file);
+
+ csc = X509_STORE_CTX_new();
+ if (csc == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ X509_STORE_set_flags(ctx, vflags);
+ if(!X509_STORE_CTX_init(csc,ctx,x,uchain))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain);
+ if (crls)
+ X509_STORE_CTX_set0_crls(csc, crls);
+ i=X509_verify_cert(csc);
+ X509_STORE_CTX_free(csc);
+
+ ret=0;
+end:
+ if (i > 0)
+ {
+ fprintf(stdout,"OK\n");
+ ret=1;
+ }
+ else
+ ERR_print_errors(bio_err);
+ if (x != NULL) X509_free(x);
+
+ return(ret);
+ }
+
+static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
+ {
+ int cert_error = X509_STORE_CTX_get_error(ctx);
+ X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
+
+ if (!ok)
+ {
+ if (current_cert)
+ {
+ X509_NAME_print_ex_fp(stdout,
+ X509_get_subject_name(current_cert),
+ 0, XN_FLAG_ONELINE);
+ printf("\n");
+ }
+ printf("%serror %d at %d depth lookup:%s\n",
+ X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
+ cert_error,
+ X509_STORE_CTX_get_error_depth(ctx),
+ X509_verify_cert_error_string(cert_error));
+ switch(cert_error)
+ {
+ case X509_V_ERR_NO_EXPLICIT_POLICY:
+ policies_print(NULL, ctx);
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+
+ /* since we are just checking the certificates, it is
+ * ok if they are self signed. But we should still warn
+ * the user.
+ */
+
+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ /* Continue after extension errors too */
+ case X509_V_ERR_INVALID_CA:
+ case X509_V_ERR_INVALID_NON_CA:
+ case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+ case X509_V_ERR_INVALID_PURPOSE:
+ case X509_V_ERR_CRL_HAS_EXPIRED:
+ case X509_V_ERR_CRL_NOT_YET_VALID:
+ case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+ ok = 1;
+
+ }
+
+ return ok;
+
+ }
+ if (cert_error == X509_V_OK && ok == 2)
+ policies_print(NULL, ctx);
+ if (!v_verbose)
+ ERR_clear_error();
+ return(ok);
+ }
diff --git a/deps/openssl/openssl/apps/version.c b/deps/openssl/openssl/apps/version.c
new file mode 100644
index 000000000..e9555cbde
--- /dev/null
+++ b/deps/openssl/openssl/apps/version.c
@@ -0,0 +1,217 @@
+/* apps/version.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/evp.h>
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_MD2
+# include <openssl/md2.h>
+#endif
+#ifndef OPENSSL_NO_RC4
+# include <openssl/rc4.h>
+#endif
+#ifndef OPENSSL_NO_DES
+# include <openssl/des.h>
+#endif
+#ifndef OPENSSL_NO_IDEA
+# include <openssl/idea.h>
+#endif
+#ifndef OPENSSL_NO_BF
+# include <openssl/blowfish.h>
+#endif
+
+#undef PROG
+#define PROG version_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ int i,ret=0;
+ int cflags=0,version=0,date=0,options=0,platform=0,dir=0;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ if (argc == 1) version=1;
+ for (i=1; i<argc; i++)
+ {
+ if (strcmp(argv[i],"-v") == 0)
+ version=1;
+ else if (strcmp(argv[i],"-b") == 0)
+ date=1;
+ else if (strcmp(argv[i],"-f") == 0)
+ cflags=1;
+ else if (strcmp(argv[i],"-o") == 0)
+ options=1;
+ else if (strcmp(argv[i],"-p") == 0)
+ platform=1;
+ else if (strcmp(argv[i],"-d") == 0)
+ dir=1;
+ else if (strcmp(argv[i],"-a") == 0)
+ date=version=cflags=options=platform=dir=1;
+ else
+ {
+ BIO_printf(bio_err,"usage:version -[avbofpd]\n");
+ ret=1;
+ goto end;
+ }
+ }
+
+ if (version)
+ {
+ if (SSLeay() == SSLEAY_VERSION_NUMBER)
+ {
+ printf("%s\n",SSLeay_version(SSLEAY_VERSION));
+ }
+ else
+ {
+ printf("%s (Library: %s)\n",
+ OPENSSL_VERSION_TEXT,
+ SSLeay_version(SSLEAY_VERSION));
+ }
+ }
+ if (date) printf("%s\n",SSLeay_version(SSLEAY_BUILT_ON));
+ if (platform) printf("%s\n",SSLeay_version(SSLEAY_PLATFORM));
+ if (options)
+ {
+ printf("options: ");
+ printf("%s ",BN_options());
+#ifndef OPENSSL_NO_MD2
+ printf("%s ",MD2_options());
+#endif
+#ifndef OPENSSL_NO_RC4
+ printf("%s ",RC4_options());
+#endif
+#ifndef OPENSSL_NO_DES
+ printf("%s ",DES_options());
+#endif
+#ifndef OPENSSL_NO_IDEA
+ printf("%s ",idea_options());
+#endif
+#ifndef OPENSSL_NO_BF
+ printf("%s ",BF_options());
+#endif
+ printf("\n");
+ }
+ if (cflags) printf("%s\n",SSLeay_version(SSLEAY_CFLAGS));
+ if (dir) printf("%s\n",SSLeay_version(SSLEAY_DIR));
+end:
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
diff --git a/deps/openssl/openssl/apps/vms_decc_init.c b/deps/openssl/openssl/apps/vms_decc_init.c
new file mode 100755
index 000000000..f512c8f1b
--- /dev/null
+++ b/deps/openssl/openssl/apps/vms_decc_init.c
@@ -0,0 +1,188 @@
+#if defined( __VMS) && !defined( OPENSSL_NO_DECC_INIT) && \
+ defined( __DECC) && !defined( __VAX) && (__CRTL_VER >= 70301000)
+# define USE_DECC_INIT 1
+#endif
+
+#ifdef USE_DECC_INIT
+
+/*
+ * 2010-04-26 SMS.
+ *
+ *----------------------------------------------------------------------
+ *
+ * decc_init()
+ *
+ * On non-VAX systems, uses LIB$INITIALIZE to set a collection of C
+ * RTL features without using the DECC$* logical name method.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unixlib.h>
+
+
+/* Global storage. */
+
+/* Flag to sense if decc_init() was called. */
+
+int decc_init_done = -1;
+
+
+/* Structure to hold a DECC$* feature name and its desired value. */
+
+typedef struct
+{
+ char *name;
+ int value;
+} decc_feat_t;
+
+
+/* Array of DECC$* feature names and their desired values.
+ * Note: DECC$ARGV_PARSE_STYLE is the urgent one.
+ */
+
+decc_feat_t decc_feat_array[] =
+{
+ /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
+ { "DECC$ARGV_PARSE_STYLE", 1 },
+
+ /* Preserve case for file names on ODS5 disks. */
+ { "DECC$EFS_CASE_PRESERVE", 1 },
+
+ /* Enable multiple dots (and most characters) in ODS5 file names,
+ * while preserving VMS-ness of ";version".
+ */
+ { "DECC$EFS_CHARSET", 1 },
+
+ /* List terminator. */
+ { (char *)NULL, 0 }
+};
+
+
+/* LIB$INITIALIZE initialization function. */
+
+static void decc_init( void)
+{
+ char *openssl_debug_decc_init;
+ int verbose = 0;
+ int feat_index;
+ int feat_value;
+ int feat_value_max;
+ int feat_value_min;
+ int i;
+ int sts;
+
+ /* Get debug option. */
+ openssl_debug_decc_init = getenv( "OPENSSL_DEBUG_DECC_INIT");
+ if (openssl_debug_decc_init != NULL)
+ {
+ verbose = strtol( openssl_debug_decc_init, NULL, 10);
+ if (verbose <= 0)
+ {
+ verbose = 1;
+ }
+ }
+
+ /* Set the global flag to indicate that LIB$INITIALIZE worked. */
+ decc_init_done = 1;
+
+ /* Loop through all items in the decc_feat_array[]. */
+
+ for (i = 0; decc_feat_array[ i].name != NULL; i++)
+ {
+ /* Get the feature index. */
+ feat_index = decc$feature_get_index( decc_feat_array[ i].name);
+ if (feat_index >= 0)
+ {
+ /* Valid item. Collect its properties. */
+ feat_value = decc$feature_get_value( feat_index, 1);
+ feat_value_min = decc$feature_get_value( feat_index, 2);
+ feat_value_max = decc$feature_get_value( feat_index, 3);
+
+ /* Check the validity of our desired value. */
+ if ((decc_feat_array[ i].value >= feat_value_min) &&
+ (decc_feat_array[ i].value <= feat_value_max))
+ {
+ /* Valid value. Set it if necessary. */
+ if (feat_value != decc_feat_array[ i].value)
+ {
+ sts = decc$feature_set_value( feat_index,
+ 1,
+ decc_feat_array[ i].value);
+
+ if (verbose > 1)
+ {
+ fprintf( stderr, " %s = %d, sts = %d.\n",
+ decc_feat_array[ i].name,
+ decc_feat_array[ i].value,
+ sts);
+ }
+ }
+ }
+ else
+ {
+ /* Invalid DECC feature value. */
+ fprintf( stderr,
+ " INVALID DECC$FEATURE VALUE, %d: %d <= %s <= %d.\n",
+ feat_value,
+ feat_value_min, decc_feat_array[ i].name, feat_value_max);
+ }
+ }
+ else
+ {
+ /* Invalid DECC feature name. */
+ fprintf( stderr,
+ " UNKNOWN DECC$FEATURE: %s.\n", decc_feat_array[ i].name);
+ }
+ }
+
+ if (verbose > 0)
+ {
+ fprintf( stderr, " DECC_INIT complete.\n");
+ }
+}
+
+/* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
+
+#pragma nostandard
+
+/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and
+ * other attributes. Note that "nopic" is significant only on VAX.
+ */
+#pragma extern_model save
+
+#if __INITIAL_POINTER_SIZE == 64
+# define PSECT_ALIGN 3
+#else
+# define PSECT_ALIGN 2
+#endif
+
+#pragma extern_model strict_refdef "LIB$INITIALIZ" PSECT_ALIGN, nopic, nowrt
+const int spare[ 8] = { 0 };
+
+#pragma extern_model strict_refdef "LIB$INITIALIZE" PSECT_ALIGN, nopic, nowrt
+void (*const x_decc_init)() = decc_init;
+
+#pragma extern_model restore
+
+/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
+
+#pragma extern_model save
+
+int LIB$INITIALIZE( void);
+
+#pragma extern_model strict_refdef
+int dmy_lib$initialize = (int) LIB$INITIALIZE;
+
+#pragma extern_model restore
+
+#pragma standard
+
+#else /* def USE_DECC_INIT */
+
+/* Dummy code to avoid a %CC-W-EMPTYFILE complaint. */
+int decc_init_dummy( void);
+
+#endif /* def USE_DECC_INIT */
diff --git a/deps/openssl/openssl/apps/winrand.c b/deps/openssl/openssl/apps/winrand.c
new file mode 100644
index 000000000..59bede3d7
--- /dev/null
+++ b/deps/openssl/openssl/apps/winrand.c
@@ -0,0 +1,148 @@
+/* apps/winrand.c */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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).
+ *
+ */
+
+/* Usage: winrand [filename]
+ *
+ * Collects entropy from mouse movements and other events and writes
+ * random data to filename or .rnd
+ */
+
+#include <windows.h>
+#include <openssl/opensslv.h>
+#include <openssl/rand.h>
+
+LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+const char *filename;
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ PSTR cmdline, int iCmdShow)
+ {
+ static char appname[] = "OpenSSL";
+ HWND hwnd;
+ MSG msg;
+ WNDCLASSEX wndclass;
+ char buffer[200];
+
+ if (cmdline[0] == '\0')
+ filename = RAND_file_name(buffer, sizeof buffer);
+ else
+ filename = cmdline;
+
+ RAND_load_file(filename, -1);
+
+ wndclass.cbSize = sizeof(wndclass);
+ wndclass.style = CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInstance;
+ wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = appname;
+ wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
+ RegisterClassEx(&wndclass);
+
+ hwnd = CreateWindow(appname, OPENSSL_VERSION_TEXT,
+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
+
+ ShowWindow(hwnd, iCmdShow);
+ UpdateWindow(hwnd);
+
+
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return msg.wParam;
+ }
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+ {
+ HDC hdc;
+ PAINTSTRUCT ps;
+ RECT rect;
+ static int seeded = 0;
+
+ switch (iMsg)
+ {
+ case WM_PAINT:
+ hdc = BeginPaint(hwnd, &ps);
+ GetClientRect(hwnd, &rect);
+ DrawText(hdc, "Seeding the PRNG. Please move the mouse!", -1,
+ &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ EndPaint(hwnd, &ps);
+ return 0;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ return 0;
+ }
+
+ if (RAND_event(iMsg, wParam, lParam) == 1 && seeded == 0)
+ {
+ seeded = 1;
+ if (RAND_write_file(filename) <= 0)
+ MessageBox(hwnd, "Couldn't write random file!",
+ "OpenSSL", MB_OK | MB_ICONERROR);
+ PostQuitMessage(0);
+ }
+
+ return DefWindowProc(hwnd, iMsg, wParam, lParam);
+ }
diff --git a/deps/openssl/openssl/apps/x509.c b/deps/openssl/openssl/apps/x509.c
new file mode 100644
index 000000000..3863ab968
--- /dev/null
+++ b/deps/openssl/openssl/apps/x509.c
@@ -0,0 +1,1310 @@
+/* apps/x509.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#undef PROG
+#define PROG x509_main
+
+#undef POSTFIX
+#define POSTFIX ".srl"
+#define DEF_DAYS 30
+
+static const char *x509_usage[]={
+"usage: x509 args\n",
+" -inform arg - input format - default PEM (one of DER, NET or PEM)\n",
+" -outform arg - output format - default PEM (one of DER, NET or PEM)\n",
+" -keyform arg - private key format - default PEM\n",
+" -CAform arg - CA format - default PEM\n",
+" -CAkeyform arg - CA key format - default PEM\n",
+" -in arg - input file - default stdin\n",
+" -out arg - output file - default stdout\n",
+" -passin arg - private key password source\n",
+" -serial - print serial number value\n",
+" -subject_hash - print subject hash value\n",
+#ifndef OPENSSL_NO_MD5
+" -subject_hash_old - print old-style (MD5) subject hash value\n",
+#endif
+" -issuer_hash - print issuer hash value\n",
+#ifndef OPENSSL_NO_MD5
+" -issuer_hash_old - print old-style (MD5) issuer hash value\n",
+#endif
+" -hash - synonym for -subject_hash\n",
+" -subject - print subject DN\n",
+" -issuer - print issuer DN\n",
+" -email - print email address(es)\n",
+" -startdate - notBefore field\n",
+" -enddate - notAfter field\n",
+" -purpose - print out certificate purposes\n",
+" -dates - both Before and After dates\n",
+" -modulus - print the RSA key modulus\n",
+" -pubkey - output the public key\n",
+" -fingerprint - print the certificate fingerprint\n",
+" -alias - output certificate alias\n",
+" -noout - no certificate output\n",
+" -ocspid - print OCSP hash values for the subject name and public key\n",
+" -ocsp_uri - print OCSP Responder URL(s)\n",
+" -trustout - output a \"trusted\" certificate\n",
+" -clrtrust - clear all trusted purposes\n",
+" -clrreject - clear all rejected purposes\n",
+" -addtrust arg - trust certificate for a given purpose\n",
+" -addreject arg - reject certificate for a given purpose\n",
+" -setalias arg - set certificate alias\n",
+" -days arg - How long till expiry of a signed certificate - def 30 days\n",
+" -checkend arg - check whether the cert expires in the next arg seconds\n",
+" exit 1 if so, 0 if not\n",
+" -signkey arg - self sign cert with arg\n",
+" -x509toreq - output a certification request object\n",
+" -req - input is a certificate request, sign and output.\n",
+" -CA arg - set the CA certificate, must be PEM format.\n",
+" -CAkey arg - set the CA key, must be PEM format\n",
+" missing, it is assumed to be in the CA file.\n",
+" -CAcreateserial - create serial number file if it does not exist\n",
+" -CAserial arg - serial file\n",
+" -set_serial - serial number to use\n",
+" -text - print the certificate in text form\n",
+" -C - print out C code forms\n",
+" -md2/-md5/-sha1/-mdc2 - digest to use\n",
+" -extfile - configuration file with X509V3 extensions to add\n",
+" -extensions - section from config file with X509V3 extensions to add\n",
+" -clrext - delete extensions before signing and input certificate\n",
+" -nameopt arg - various certificate name options\n",
+#ifndef OPENSSL_NO_ENGINE
+" -engine e - use engine e, possibly a hardware device.\n",
+#endif
+" -certopt arg - various certificate text options\n",
+NULL
+};
+
+static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
+static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest,
+ CONF *conf, char *section);
+static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
+ X509 *x,X509 *xca,EVP_PKEY *pkey,
+ STACK_OF(OPENSSL_STRING) *sigopts,
+ char *serial, int create ,int days, int clrext,
+ CONF *conf, char *section, ASN1_INTEGER *sno);
+static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
+static int reqfile=0;
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+ {
+ ENGINE *e = NULL;
+ int ret=1;
+ X509_REQ *req=NULL;
+ X509 *x=NULL,*xca=NULL;
+ ASN1_OBJECT *objtmp;
+ STACK_OF(OPENSSL_STRING) *sigopts = NULL;
+ EVP_PKEY *Upkey=NULL,*CApkey=NULL;
+ ASN1_INTEGER *sno = NULL;
+ int i,num,badops=0;
+ BIO *out=NULL;
+ BIO *STDout=NULL;
+ STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
+ int informat,outformat,keyformat,CAformat,CAkeyformat;
+ char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
+ char *CAkeyfile=NULL,*CAserial=NULL;
+ char *alias=NULL;
+ int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
+ int next_serial=0;
+ int subject_hash=0,issuer_hash=0,ocspid=0;
+#ifndef OPENSSL_NO_MD5
+ int subject_hash_old=0,issuer_hash_old=0;
+#endif
+ int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
+ int ocsp_uri=0;
+ int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
+ int C=0;
+ int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
+ int pprint = 0;
+ const char **pp;
+ X509_STORE *ctx=NULL;
+ X509_REQ *rq=NULL;
+ int fingerprint=0;
+ char buf[256];
+ const EVP_MD *md_alg,*digest=NULL;
+ CONF *extconf = NULL;
+ char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
+ int need_rand = 0;
+ int checkend=0,checkoffset=0;
+ unsigned long nmflag = 0, certflag = 0;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=NULL;
+#endif
+
+ reqfile=0;
+
+ apps_startup();
+
+ if (bio_err == NULL)
+ bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+ STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ STDout = BIO_push(tmpbio, STDout);
+ }
+#endif
+
+ informat=FORMAT_PEM;
+ outformat=FORMAT_PEM;
+ keyformat=FORMAT_PEM;
+ CAformat=FORMAT_PEM;
+ CAkeyformat=FORMAT_PEM;
+
+ ctx=X509_STORE_new();
+ if (ctx == NULL) goto end;
+ X509_STORE_set_verify_cb(ctx,callb);
+
+ argc--;
+ argv++;
+ num=0;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-inform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ informat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-outform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-keyform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keyformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-req") == 0)
+ {
+ reqfile=1;
+ need_rand = 1;
+ }
+ else if (strcmp(*argv,"-CAform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CAformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-CAkeyform") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CAkeyformat=str2fmt(*(++argv));
+ }
+ else if (strcmp(*argv,"-sigopt") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ if (!sigopts)
+ sigopts = sk_OPENSSL_STRING_new_null();
+ if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+ goto bad;
+ }
+ else if (strcmp(*argv,"-days") == 0)
+ {
+ if (--argc < 1) goto bad;
+ days=atoi(*(++argv));
+ if (days == 0)
+ {
+ BIO_printf(bio_err,"bad number of days\n");
+ goto bad;
+ }
+ }
+ else if (strcmp(*argv,"-passin") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passargin= *(++argv);
+ }
+ else if (strcmp(*argv,"-extfile") == 0)
+ {
+ if (--argc < 1) goto bad;
+ extfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-extensions") == 0)
+ {
+ if (--argc < 1) goto bad;
+ extsect= *(++argv);
+ }
+ else if (strcmp(*argv,"-in") == 0)
+ {
+ if (--argc < 1) goto bad;
+ infile= *(++argv);
+ }
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) goto bad;
+ outfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-signkey") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keyfile= *(++argv);
+ sign_flag= ++num;
+ need_rand = 1;
+ }
+ else if (strcmp(*argv,"-CA") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CAfile= *(++argv);
+ CA_flag= ++num;
+ need_rand = 1;
+ }
+ else if (strcmp(*argv,"-CAkey") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CAkeyfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-CAserial") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CAserial= *(++argv);
+ }
+ else if (strcmp(*argv,"-set_serial") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
+ goto bad;
+ }
+ else if (strcmp(*argv,"-addtrust") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
+ {
+ BIO_printf(bio_err,
+ "Invalid trust object value %s\n", *argv);
+ goto bad;
+ }
+ if (!trust) trust = sk_ASN1_OBJECT_new_null();
+ sk_ASN1_OBJECT_push(trust, objtmp);
+ trustout = 1;
+ }
+ else if (strcmp(*argv,"-addreject") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
+ {
+ BIO_printf(bio_err,
+ "Invalid reject object value %s\n", *argv);
+ goto bad;
+ }
+ if (!reject) reject = sk_ASN1_OBJECT_new_null();
+ sk_ASN1_OBJECT_push(reject, objtmp);
+ trustout = 1;
+ }
+ else if (strcmp(*argv,"-setalias") == 0)
+ {
+ if (--argc < 1) goto bad;
+ alias= *(++argv);
+ trustout = 1;
+ }
+ else if (strcmp(*argv,"-certopt") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if (!set_cert_ex(&certflag, *(++argv))) goto bad;
+ }
+ else if (strcmp(*argv,"-nameopt") == 0)
+ {
+ if (--argc < 1) goto bad;
+ if (!set_name_ex(&nmflag, *(++argv))) goto bad;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
+#endif
+ else if (strcmp(*argv,"-C") == 0)
+ C= ++num;
+ else if (strcmp(*argv,"-email") == 0)
+ email= ++num;
+ else if (strcmp(*argv,"-ocsp_uri") == 0)
+ ocsp_uri= ++num;
+ else if (strcmp(*argv,"-serial") == 0)
+ serial= ++num;
+ else if (strcmp(*argv,"-next_serial") == 0)
+ next_serial= ++num;
+ else if (strcmp(*argv,"-modulus") == 0)
+ modulus= ++num;
+ else if (strcmp(*argv,"-pubkey") == 0)
+ pubkey= ++num;
+ else if (strcmp(*argv,"-x509toreq") == 0)
+ x509req= ++num;
+ else if (strcmp(*argv,"-text") == 0)
+ text= ++num;
+ else if (strcmp(*argv,"-hash") == 0
+ || strcmp(*argv,"-subject_hash") == 0)
+ subject_hash= ++num;
+#ifndef OPENSSL_NO_MD5
+ else if (strcmp(*argv,"-subject_hash_old") == 0)
+ subject_hash_old= ++num;
+#endif
+ else if (strcmp(*argv,"-issuer_hash") == 0)
+ issuer_hash= ++num;
+#ifndef OPENSSL_NO_MD5
+ else if (strcmp(*argv,"-issuer_hash_old") == 0)
+ issuer_hash_old= ++num;
+#endif
+ else if (strcmp(*argv,"-subject") == 0)
+ subject= ++num;
+ else if (strcmp(*argv,"-issuer") == 0)
+ issuer= ++num;
+ else if (strcmp(*argv,"-fingerprint") == 0)
+ fingerprint= ++num;
+ else if (strcmp(*argv,"-dates") == 0)
+ {
+ startdate= ++num;
+ enddate= ++num;
+ }
+ else if (strcmp(*argv,"-purpose") == 0)
+ pprint= ++num;
+ else if (strcmp(*argv,"-startdate") == 0)
+ startdate= ++num;
+ else if (strcmp(*argv,"-enddate") == 0)
+ enddate= ++num;
+ else if (strcmp(*argv,"-checkend") == 0)
+ {
+ if (--argc < 1) goto bad;
+ checkoffset=atoi(*(++argv));
+ checkend=1;
+ }
+ else if (strcmp(*argv,"-noout") == 0)
+ noout= ++num;
+ else if (strcmp(*argv,"-trustout") == 0)
+ trustout= 1;
+ else if (strcmp(*argv,"-clrtrust") == 0)
+ clrtrust= ++num;
+ else if (strcmp(*argv,"-clrreject") == 0)
+ clrreject= ++num;
+ else if (strcmp(*argv,"-alias") == 0)
+ aliasout= ++num;
+ else if (strcmp(*argv,"-CAcreateserial") == 0)
+ CA_createserial= ++num;
+ else if (strcmp(*argv,"-clrext") == 0)
+ clrext = 1;
+#if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */
+ else if (strcmp(*argv,"-crlext") == 0)
+ {
+ BIO_printf(bio_err,"use -clrext instead of -crlext\n");
+ clrext = 1;
+ }
+#endif
+ else if (strcmp(*argv,"-ocspid") == 0)
+ ocspid= ++num;
+ else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
+ {
+ /* ok */
+ digest=md_alg;
+ }
+ else
+ {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops)
+ {
+bad:
+ for (pp=x509_usage; (*pp != NULL); pp++)
+ BIO_printf(bio_err,"%s",*pp);
+ goto end;
+ }
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);
+#endif
+
+ if (need_rand)
+ app_RAND_load_file(NULL, bio_err, 0);
+
+ ERR_load_crypto_strings();
+
+ if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+ {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+ if (!X509_STORE_set_default_paths(ctx))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM))
+ { CAkeyfile=CAfile; }
+ else if ((CA_flag) && (CAkeyfile == NULL))
+ {
+ BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n");
+ goto end;
+ }
+
+ if (extfile)
+ {
+ long errorline = -1;
+ X509V3_CTX ctx2;
+ extconf = NCONF_new(NULL);
+ if (!NCONF_load(extconf, extfile,&errorline))
+ {
+ if (errorline <= 0)
+ BIO_printf(bio_err,
+ "error loading the config file '%s'\n",
+ extfile);
+ else
+ BIO_printf(bio_err,
+ "error on line %ld of config file '%s'\n"
+ ,errorline,extfile);
+ goto end;
+ }
+ if (!extsect)
+ {
+ extsect = NCONF_get_string(extconf, "default", "extensions");
+ if (!extsect)
+ {
+ ERR_clear_error();
+ extsect = "default";
+ }
+ }
+ X509V3_set_ctx_test(&ctx2);
+ X509V3_set_nconf(&ctx2, extconf);
+ if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL))
+ {
+ BIO_printf(bio_err,
+ "Error Loading extension section %s\n",
+ extsect);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+
+ if (reqfile)
+ {
+ EVP_PKEY *pkey;
+ BIO *in;
+
+ if (!sign_flag && !CA_flag)
+ {
+ BIO_printf(bio_err,"We need a private key to sign with\n");
+ goto end;
+ }
+ in=BIO_new(BIO_s_file());
+ if (in == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
+ else
+ {
+ if (BIO_read_filename(in,infile) <= 0)
+ {
+ perror(infile);
+ BIO_free(in);
+ goto end;
+ }
+ }
+ req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
+ BIO_free(in);
+
+ if (req == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if ( (req->req_info == NULL) ||
+ (req->req_info->pubkey == NULL) ||
+ (req->req_info->pubkey->public_key == NULL) ||
+ (req->req_info->pubkey->public_key->data == NULL))
+ {
+ BIO_printf(bio_err,"The certificate request appears to corrupted\n");
+ BIO_printf(bio_err,"It does not contain a public key\n");
+ goto end;
+ }
+ if ((pkey=X509_REQ_get_pubkey(req)) == NULL)
+ {
+ BIO_printf(bio_err,"error unpacking public key\n");
+ goto end;
+ }
+ i=X509_REQ_verify(req,pkey);
+ EVP_PKEY_free(pkey);
+ if (i < 0)
+ {
+ BIO_printf(bio_err,"Signature verification error\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (i == 0)
+ {
+ BIO_printf(bio_err,"Signature did not match the certificate request\n");
+ goto end;
+ }
+ else
+ BIO_printf(bio_err,"Signature ok\n");
+
+ print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);
+
+ if ((x=X509_new()) == NULL) goto end;
+
+ if (sno == NULL)
+ {
+ sno = ASN1_INTEGER_new();
+ if (!sno || !rand_serial(NULL, sno))
+ goto end;
+ if (!X509_set_serialNumber(x, sno))
+ goto end;
+ ASN1_INTEGER_free(sno);
+ sno = NULL;
+ }
+ else if (!X509_set_serialNumber(x, sno))
+ goto end;
+
+ if (!X509_set_issuer_name(x,req->req_info->subject)) goto end;
+ if (!X509_set_subject_name(x,req->req_info->subject)) goto end;
+
+ X509_gmtime_adj(X509_get_notBefore(x),0);
+ X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL);
+
+ pkey = X509_REQ_get_pubkey(req);
+ X509_set_pubkey(x,pkey);
+ EVP_PKEY_free(pkey);
+ }
+ else
+ x=load_cert(bio_err,infile,informat,NULL,e,"Certificate");
+
+ if (x == NULL) goto end;
+ if (CA_flag)
+ {
+ xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate");
+ if (xca == NULL) goto end;
+ }
+
+ if (!noout || text || next_serial)
+ {
+ OBJ_create("2.99999.3",
+ "SET.ex3","SET x509v3 extension 3");
+
+ out=BIO_new(BIO_s_file());
+ if (out == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
+ else
+ {
+ if (BIO_write_filename(out,outfile) <= 0)
+ {
+ perror(outfile);
+ goto end;
+ }
+ }
+ }
+
+ if (alias) X509_alias_set1(x, (unsigned char *)alias, -1);
+
+ if (clrtrust) X509_trust_clear(x);
+ if (clrreject) X509_reject_clear(x);
+
+ if (trust)
+ {
+ for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++)
+ {
+ objtmp = sk_ASN1_OBJECT_value(trust, i);
+ X509_add1_trust_object(x, objtmp);
+ }
+ }
+
+ if (reject)
+ {
+ for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++)
+ {
+ objtmp = sk_ASN1_OBJECT_value(reject, i);
+ X509_add1_reject_object(x, objtmp);
+ }
+ }
+
+ if (num)
+ {
+ for (i=1; i<=num; i++)
+ {
+ if (issuer == i)
+ {
+ print_name(STDout, "issuer= ",
+ X509_get_issuer_name(x), nmflag);
+ }
+ else if (subject == i)
+ {
+ print_name(STDout, "subject= ",
+ X509_get_subject_name(x), nmflag);
+ }
+ else if (serial == i)
+ {
+ BIO_printf(STDout,"serial=");
+ i2a_ASN1_INTEGER(STDout,
+ X509_get_serialNumber(x));
+ BIO_printf(STDout,"\n");
+ }
+ else if (next_serial == i)
+ {
+ BIGNUM *bnser;
+ ASN1_INTEGER *ser;
+ ser = X509_get_serialNumber(x);
+ bnser = ASN1_INTEGER_to_BN(ser, NULL);
+ if (!bnser)
+ goto end;
+ if (!BN_add_word(bnser, 1))
+ goto end;
+ ser = BN_to_ASN1_INTEGER(bnser, NULL);
+ if (!ser)
+ goto end;
+ BN_free(bnser);
+ i2a_ASN1_INTEGER(out, ser);
+ ASN1_INTEGER_free(ser);
+ BIO_puts(out, "\n");
+ }
+ else if ((email == i) || (ocsp_uri == i))
+ {
+ int j;
+ STACK_OF(OPENSSL_STRING) *emlst;
+ if (email == i)
+ emlst = X509_get1_email(x);
+ else
+ emlst = X509_get1_ocsp(x);
+ for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
+ BIO_printf(STDout, "%s\n",
+ sk_OPENSSL_STRING_value(emlst, j));
+ X509_email_free(emlst);
+ }
+ else if (aliasout == i)
+ {
+ unsigned char *alstr;
+ alstr = X509_alias_get0(x, NULL);
+ if (alstr) BIO_printf(STDout,"%s\n", alstr);
+ else BIO_puts(STDout,"<No Alias>\n");
+ }
+ else if (subject_hash == i)
+ {
+ BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
+ }
+#ifndef OPENSSL_NO_MD5
+ else if (subject_hash_old == i)
+ {
+ BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x));
+ }
+#endif
+ else if (issuer_hash == i)
+ {
+ BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x));
+ }
+#ifndef OPENSSL_NO_MD5
+ else if (issuer_hash_old == i)
+ {
+ BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x));
+ }
+#endif
+ else if (pprint == i)
+ {
+ X509_PURPOSE *ptmp;
+ int j;
+ BIO_printf(STDout, "Certificate purposes:\n");
+ for (j = 0; j < X509_PURPOSE_get_count(); j++)
+ {
+ ptmp = X509_PURPOSE_get0(j);
+ purpose_print(STDout, x, ptmp);
+ }
+ }
+ else
+ if (modulus == i)
+ {
+ EVP_PKEY *pkey;
+
+ pkey=X509_get_pubkey(x);
+ if (pkey == NULL)
+ {
+ BIO_printf(bio_err,"Modulus=unavailable\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ BIO_printf(STDout,"Modulus=");
+#ifndef OPENSSL_NO_RSA
+ if (pkey->type == EVP_PKEY_RSA)
+ BN_print(STDout,pkey->pkey.rsa->n);
+ else
+#endif
+#ifndef OPENSSL_NO_DSA
+ if (pkey->type == EVP_PKEY_DSA)
+ BN_print(STDout,pkey->pkey.dsa->pub_key);
+ else
+#endif
+ BIO_printf(STDout,"Wrong Algorithm type");
+ BIO_printf(STDout,"\n");
+ EVP_PKEY_free(pkey);
+ }
+ else
+ if (pubkey == i)
+ {
+ EVP_PKEY *pkey;
+
+ pkey=X509_get_pubkey(x);
+ if (pkey == NULL)
+ {
+ BIO_printf(bio_err,"Error getting public key\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ PEM_write_bio_PUBKEY(STDout, pkey);
+ EVP_PKEY_free(pkey);
+ }
+ else
+ if (C == i)
+ {
+ unsigned char *d;
+ char *m;
+ int y,z;
+
+ X509_NAME_oneline(X509_get_subject_name(x),
+ buf,sizeof buf);
+ BIO_printf(STDout,"/* subject:%s */\n",buf);
+ m=X509_NAME_oneline(
+ X509_get_issuer_name(x),buf,
+ sizeof buf);
+ BIO_printf(STDout,"/* issuer :%s */\n",buf);
+
+ z=i2d_X509(x,NULL);
+ m=OPENSSL_malloc(z);
+
+ d=(unsigned char *)m;
+ z=i2d_X509_NAME(X509_get_subject_name(x),&d);
+ BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z);
+ d=(unsigned char *)m;
+ for (y=0; y<z; y++)
+ {
+ BIO_printf(STDout,"0x%02X,",d[y]);
+ if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n");
+ }
+ if (y%16 != 0) BIO_printf(STDout,"\n");
+ BIO_printf(STDout,"};\n");
+
+ z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d);
+ BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z);
+ d=(unsigned char *)m;
+ for (y=0; y<z; y++)
+ {
+ BIO_printf(STDout,"0x%02X,",d[y]);
+ if ((y & 0x0f) == 0x0f)
+ BIO_printf(STDout,"\n");
+ }
+ if (y%16 != 0) BIO_printf(STDout,"\n");
+ BIO_printf(STDout,"};\n");
+
+ z=i2d_X509(x,&d);
+ BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z);
+ d=(unsigned char *)m;
+ for (y=0; y<z; y++)
+ {
+ BIO_printf(STDout,"0x%02X,",d[y]);
+ if ((y & 0x0f) == 0x0f)
+ BIO_printf(STDout,"\n");
+ }
+ if (y%16 != 0) BIO_printf(STDout,"\n");
+ BIO_printf(STDout,"};\n");
+
+ OPENSSL_free(m);
+ }
+ else if (text == i)
+ {
+ X509_print_ex(STDout,x,nmflag, certflag);
+ }
+ else if (startdate == i)
+ {
+ BIO_puts(STDout,"notBefore=");
+ ASN1_TIME_print(STDout,X509_get_notBefore(x));
+ BIO_puts(STDout,"\n");
+ }
+ else if (enddate == i)
+ {
+ BIO_puts(STDout,"notAfter=");
+ ASN1_TIME_print(STDout,X509_get_notAfter(x));
+ BIO_puts(STDout,"\n");
+ }
+ else if (fingerprint == i)
+ {
+ int j;
+ unsigned int n;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ const EVP_MD *fdig = digest;
+
+ if (!fdig)
+ fdig = EVP_sha1();
+
+ if (!X509_digest(x,fdig,md,&n))
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ goto end;
+ }
+ BIO_printf(STDout,"%s Fingerprint=",
+ OBJ_nid2sn(EVP_MD_type(fdig)));
+ for (j=0; j<(int)n; j++)
+ {
+ BIO_printf(STDout,"%02X%c",md[j],
+ (j+1 == (int)n)
+ ?'\n':':');
+ }
+ }
+
+ /* should be in the library */
+ else if ((sign_flag == i) && (x509req == 0))
+ {
+ BIO_printf(bio_err,"Getting Private key\n");
+ if (Upkey == NULL)
+ {
+ Upkey=load_key(bio_err,
+ keyfile, keyformat, 0,
+ passin, e, "Private key");
+ if (Upkey == NULL) goto end;
+ }
+
+ assert(need_rand);
+ if (!sign(x,Upkey,days,clrext,digest,
+ extconf, extsect)) goto end;
+ }
+ else if (CA_flag == i)
+ {
+ BIO_printf(bio_err,"Getting CA Private Key\n");
+ if (CAkeyfile != NULL)
+ {
+ CApkey=load_key(bio_err,
+ CAkeyfile, CAkeyformat,
+ 0, passin, e,
+ "CA Private Key");
+ if (CApkey == NULL) goto end;
+ }
+
+ assert(need_rand);
+ if (!x509_certify(ctx,CAfile,digest,x,xca,
+ CApkey, sigopts,
+ CAserial,CA_createserial,days, clrext,
+ extconf, extsect, sno))
+ goto end;
+ }
+ else if (x509req == i)
+ {
+ EVP_PKEY *pk;
+
+ BIO_printf(bio_err,"Getting request Private Key\n");
+ if (keyfile == NULL)
+ {
+ BIO_printf(bio_err,"no request key file specified\n");
+ goto end;
+ }
+ else
+ {
+ pk=load_key(bio_err,
+ keyfile, keyformat, 0,
+ passin, e, "request key");
+ if (pk == NULL) goto end;
+ }
+
+ BIO_printf(bio_err,"Generating certificate request\n");
+
+ rq=X509_to_X509_REQ(x,pk,digest);
+ EVP_PKEY_free(pk);
+ if (rq == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ if (!noout)
+ {
+ X509_REQ_print(out,rq);
+ PEM_write_bio_X509_REQ(out,rq);
+ }
+ noout=1;
+ }
+ else if (ocspid == i)
+ {
+ X509_ocspid_print(out, x);
+ }
+ }
+ }
+
+ if (checkend)
+ {
+ time_t tcheck=time(NULL) + checkoffset;
+
+ if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0)
+ {
+ BIO_printf(out,"Certificate will expire\n");
+ ret=1;
+ }
+ else
+ {
+ BIO_printf(out,"Certificate will not expire\n");
+ ret=0;
+ }
+ goto end;
+ }
+
+ if (noout)
+ {
+ ret=0;
+ goto end;
+ }
+
+ if (outformat == FORMAT_ASN1)
+ i=i2d_X509_bio(out,x);
+ else if (outformat == FORMAT_PEM)
+ {
+ if (trustout) i=PEM_write_bio_X509_AUX(out,x);
+ else i=PEM_write_bio_X509(out,x);
+ }
+ else if (outformat == FORMAT_NETSCAPE)
+ {
+ NETSCAPE_X509 nx;
+ ASN1_OCTET_STRING hdr;
+
+ hdr.data=(unsigned char *)NETSCAPE_CERT_HDR;
+ hdr.length=strlen(NETSCAPE_CERT_HDR);
+ nx.header= &hdr;
+ nx.cert=x;
+
+ i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx);
+ }
+ else {
+ BIO_printf(bio_err,"bad output format specified for outfile\n");
+ goto end;
+ }
+ if (!i)
+ {
+ BIO_printf(bio_err,"unable to write certificate\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ ret=0;
+end:
+ if (need_rand)
+ app_RAND_write_file(NULL, bio_err);
+ OBJ_cleanup();
+ NCONF_free(extconf);
+ BIO_free_all(out);
+ BIO_free_all(STDout);
+ X509_STORE_free(ctx);
+ X509_REQ_free(req);
+ X509_free(x);
+ X509_free(xca);
+ EVP_PKEY_free(Upkey);
+ EVP_PKEY_free(CApkey);
+ if (sigopts)
+ sk_OPENSSL_STRING_free(sigopts);
+ X509_REQ_free(rq);
+ ASN1_INTEGER_free(sno);
+ sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
+ sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
+ if (passin) OPENSSL_free(passin);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+ }
+
+static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create)
+ {
+ char *buf = NULL, *p;
+ ASN1_INTEGER *bs = NULL;
+ BIGNUM *serial = NULL;
+ size_t len;
+
+ len = ((serialfile == NULL)
+ ?(strlen(CAfile)+strlen(POSTFIX)+1)
+ :(strlen(serialfile)))+1;
+ buf=OPENSSL_malloc(len);
+ if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; }
+ if (serialfile == NULL)
+ {
+ BUF_strlcpy(buf,CAfile,len);
+ for (p=buf; *p; p++)
+ if (*p == '.')
+ {
+ *p='\0';
+ break;
+ }
+ BUF_strlcat(buf,POSTFIX,len);
+ }
+ else
+ BUF_strlcpy(buf,serialfile,len);
+
+ serial = load_serial(buf, create, NULL);
+ if (serial == NULL) goto end;
+
+ if (!BN_add_word(serial,1))
+ { BIO_printf(bio_err,"add_word failure\n"); goto end; }
+
+ if (!save_serial(buf, NULL, serial, &bs)) goto end;
+
+ end:
+ if (buf) OPENSSL_free(buf);
+ BN_free(serial);
+ return bs;
+ }
+
+static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
+ X509 *x, X509 *xca, EVP_PKEY *pkey,
+ STACK_OF(OPENSSL_STRING) *sigopts,
+ char *serialfile, int create,
+ int days, int clrext, CONF *conf, char *section,
+ ASN1_INTEGER *sno)
+ {
+ int ret=0;
+ ASN1_INTEGER *bs=NULL;
+ X509_STORE_CTX xsc;
+ EVP_PKEY *upkey;
+
+ upkey = X509_get_pubkey(xca);
+ EVP_PKEY_copy_parameters(upkey,pkey);
+ EVP_PKEY_free(upkey);
+
+ if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL))
+ {
+ BIO_printf(bio_err,"Error initialising X509 store\n");
+ goto end;
+ }
+ if (sno) bs = sno;
+ else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
+ goto end;
+
+/* if (!X509_STORE_add_cert(ctx,x)) goto end;*/
+
+ /* NOTE: this certificate can/should be self signed, unless it was
+ * a certificate request in which case it is not. */
+ X509_STORE_CTX_set_cert(&xsc,x);
+ X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
+ if (!reqfile && X509_verify_cert(&xsc) <= 0)
+ goto end;
+
+ if (!X509_check_private_key(xca,pkey))
+ {
+ BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
+ goto end;
+ }
+
+ if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end;
+ if (!X509_set_serialNumber(x,bs)) goto end;
+
+ if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL)
+ goto end;
+
+ /* hardwired expired */
+ if (X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL) == NULL)
+ goto end;
+
+ if (clrext)
+ {
+ while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
+ }
+
+ if (conf)
+ {
+ X509V3_CTX ctx2;
+ X509_set_version(x,2); /* version 3 certificate */
+ X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
+ X509V3_set_nconf(&ctx2, conf);
+ if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end;
+ }
+
+ if (!do_X509_sign(bio_err, x, pkey, digest, sigopts))
+ goto end;
+ ret=1;
+end:
+ X509_STORE_CTX_cleanup(&xsc);
+ if (!ret)
+ ERR_print_errors(bio_err);
+ if (!sno) ASN1_INTEGER_free(bs);
+ return ret;
+ }
+
+static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
+ {
+ int err;
+ X509 *err_cert;
+
+ /* it is ok to use a self signed certificate
+ * This case will catch both the initial ok == 0 and the
+ * final ok == 1 calls to this function */
+ err=X509_STORE_CTX_get_error(ctx);
+ if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
+ return 1;
+
+ /* BAD we should have gotten an error. Normally if everything
+ * worked X509_STORE_CTX_get_error(ctx) will still be set to
+ * DEPTH_ZERO_SELF_.... */
+ if (ok)
+ {
+ BIO_printf(bio_err,"error with certificate to be certified - should be self signed\n");
+ return 0;
+ }
+ else
+ {
+ err_cert=X509_STORE_CTX_get_current_cert(ctx);
+ print_name(bio_err, NULL, X509_get_subject_name(err_cert),0);
+ BIO_printf(bio_err,"error with certificate - error %d at depth %d\n%s\n",
+ err,X509_STORE_CTX_get_error_depth(ctx),
+ X509_verify_cert_error_string(err));
+ return 1;
+ }
+ }
+
+/* self sign */
+static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest,
+ CONF *conf, char *section)
+ {
+
+ EVP_PKEY *pktmp;
+
+ pktmp = X509_get_pubkey(x);
+ EVP_PKEY_copy_parameters(pktmp,pkey);
+ EVP_PKEY_save_parameters(pktmp,1);
+ EVP_PKEY_free(pktmp);
+
+ if (!X509_set_issuer_name(x,X509_get_subject_name(x))) goto err;
+ if (X509_gmtime_adj(X509_get_notBefore(x),0) == NULL) goto err;
+
+ /* Lets just make it 12:00am GMT, Jan 1 1970 */
+ /* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
+ /* 28 days to be certified */
+
+ if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
+ goto err;
+
+ if (!X509_set_pubkey(x,pkey)) goto err;
+ if (clrext)
+ {
+ while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
+ }
+ if (conf)
+ {
+ X509V3_CTX ctx;
+ X509_set_version(x,2); /* version 3 certificate */
+ X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
+ X509V3_set_nconf(&ctx, conf);
+ if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err;
+ }
+ if (!X509_sign(x,pkey,digest)) goto err;
+ return 1;
+err:
+ ERR_print_errors(bio_err);
+ return 0;
+ }
+
+static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
+{
+ int id, i, idret;
+ char *pname;
+ id = X509_PURPOSE_get_id(pt);
+ pname = X509_PURPOSE_get0_name(pt);
+ for (i = 0; i < 2; i++)
+ {
+ idret = X509_check_purpose(cert, id, i);
+ BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
+ if (idret == 1) BIO_printf(bio, "Yes\n");
+ else if (idret == 0) BIO_printf(bio, "No\n");
+ else BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
+ }
+ return 1;
+}
diff --git a/deps/openssl/openssl/config b/deps/openssl/openssl/config
index cf64ec563..88b9bc69d 100755
--- a/deps/openssl/openssl/config
+++ b/deps/openssl/openssl/config
@@ -370,6 +370,10 @@ case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in
NONSTOP_KERNEL*)
echo "nsr-tandem-nsk"; exit 0;
;;
+
+ vxworks*)
+ echo "${MACHINE}-whatever-vxworks"; exit 0;
+ ;;
esac
#
@@ -407,23 +411,18 @@ exit 0
# this is where the translation occurs into SSLeay terms
# ---------------------------------------------------------------------------
-GCCVER=`(gcc -dumpversion) 2>/dev/null`
-if [ "$GCCVER" != "" ]; then
- # then strip off whatever prefix egcs prepends the number with...
- # Hopefully, this will work for any future prefixes as well.
- GCCVER=`echo $GCCVER | LC_ALL=C sed 's/^[a-zA-Z]*\-//'`
- # Since gcc 3.1 gcc --version behaviour has changed. gcc -dumpversion
- # does give us what we want though, so we use that. We just just the
- # major and minor version numbers.
- # peak single digit before and after first dot, e.g. 2.95.1 gives 29
- GCCVER=`echo $GCCVER | sed 's/\([0-9]\)\.\([0-9]\).*/\1\2/'`
-fi
-
# Only set CC if not supplied already
-if [ -z "$CC" ]; then
-# figure out if gcc is available and if so we use it otherwise
-# we fallback to whatever cc does on the system
+if [ -z "$CROSS_COMPILE$CC" ]; then
+ GCCVER=`sh -c "gcc -dumpversion" 2>/dev/null`
if [ "$GCCVER" != "" ]; then
+ # then strip off whatever prefix egcs prepends the number with...
+ # Hopefully, this will work for any future prefixes as well.
+ GCCVER=`echo $GCCVER | LC_ALL=C sed 's/^[a-zA-Z]*\-//'`
+ # Since gcc 3.1 gcc --version behaviour has changed. gcc -dumpversion
+ # does give us what we want though, so we use that. We just just the
+ # major and minor version numbers.
+ # peak single digit before and after first dot, e.g. 2.95.1 gives 29
+ GCCVER=`echo $GCCVER | sed 's/\([0-9]\)\.\([0-9]\).*/\1\2/'`
CC=gcc
else
CC=cc
@@ -539,7 +538,7 @@ case "$GUESSOS" in
ppc-apple-rhapsody) OUT="rhapsody-ppc-cc" ;;
ppc-apple-darwin*)
ISA64=`(sysctl -n hw.optional.64bitops) 2>/dev/null`
- if [ "$ISA64" = "1" ]; then
+ if [ "$ISA64" = "1" -a -z "$KERNEL_BITS" ]; then
echo "WARNING! If you wish to build 64-bit library, then you have to"
echo " invoke './Configure darwin64-ppc-cc' *manually*."
if [ "$TEST" = "false" -a -t 1 ]; then
@@ -547,10 +546,14 @@ case "$GUESSOS" in
(trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
fi
fi
- OUT="darwin-ppc-cc" ;;
+ if [ "$ISA64" = "1" -a "$KERNEL_BITS" = "64" ]; then
+ OUT="darwin64-ppc-cc"
+ else
+ OUT="darwin-ppc-cc"
+ fi ;;
i?86-apple-darwin*)
ISA64=`(sysctl -n hw.optional.x86_64) 2>/dev/null`
- if [ "$ISA64" = "1" ]; then
+ if [ "$ISA64" = "1" -a -z "$KERNEL_BITS" ]; then
echo "WARNING! If you wish to build 64-bit library, then you have to"
echo " invoke './Configure darwin64-x86_64-cc' *manually*."
if [ "$TEST" = "false" -a -t 1 ]; then
@@ -558,7 +561,17 @@ case "$GUESSOS" in
(trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
fi
fi
- OUT="darwin-i386-cc" ;;
+ if [ "$ISA64" = "1" -a "$KERNEL_BITS" = "64" ]; then
+ OUT="darwin64-x86_64-cc"
+ else
+ OUT="darwin-i386-cc"
+ fi ;;
+ armv6+7-*-iphoneos)
+ options="$options -arch%20armv6 -arch%20armv7"
+ OUT="iphoneos-cross" ;;
+ *-*-iphoneos)
+ options="$options -arch%20${MACHINE}"
+ OUT="iphoneos-cross" ;;
alpha-*-linux2)
ISA=`awk '/cpu model/{print$4;exit(0);}' /proc/cpuinfo`
case ${ISA:-generic} in
@@ -583,6 +596,11 @@ case "$GUESSOS" in
OUT="linux-ppc"
;;
ppc-*-linux2) OUT="linux-ppc" ;;
+ ppc60x-*-vxworks*) OUT="vxworks-ppc60x" ;;
+ ppcgen-*-vxworks*) OUT="vxworks-ppcgen" ;;
+ pentium-*-vxworks*) OUT="vxworks-pentium" ;;
+ simlinux-*-vxworks*) OUT="vxworks-simlinux" ;;
+ mips-*-vxworks*) OUT="vxworks-mips";;
ia64-*-linux?) OUT="linux-ia64" ;;
sparc64-*-linux2)
echo "WARNING! If you *know* that your GNU C supports 64-bit/V9 ABI"
@@ -624,12 +642,24 @@ case "$GUESSOS" in
options="$options -DB_ENDIAN -mschedule=$CPUSCHEDULE -march=$CPUARCH"
OUT="linux-generic32" ;;
armv[1-3]*-*-linux2) OUT="linux-generic32" ;;
+ armv[7-9]*-*-linux2) OUT="linux-armv4"; options="$options -march=armv7-a" ;;
arm*-*-linux2) OUT="linux-armv4" ;;
sh*b-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
sh*-*-linux2) OUT="linux-generic32"; options="$options -DL_ENDIAN" ;;
m68k*-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
s390-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
- s390x-*-linux2) OUT="linux-s390x" ;;
+ s390x-*-linux2)
+ # To be uncommented when glibc bug is fixed, see Configure...
+ #if egrep -e '^features.* highgprs' /proc/cpuinfo >/dev/null ; then
+ # echo "WARNING! If you wish to build \"highgprs\" 32-bit library, then you"
+ # echo " have to invoke './Configure linux32-s390x' *manually*."
+ # if [ "$TEST" = "false" -a -t -1 ]; then
+ # echo " You have about 5 seconds to press Ctrl-C to abort."
+ # (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+ # fi
+ #fi
+ OUT="linux64-s390x"
+ ;;
x86_64-*-linux?) OUT="linux-x86_64" ;;
*86-*-linux2) OUT="linux-elf"
if [ "$GCCVER" -gt 28 ]; then
@@ -648,7 +678,7 @@ case "$GUESSOS" in
sun4[uv]*-*-solaris2)
OUT="solaris-sparcv9-$CC"
ISA64=`(isalist) 2>/dev/null | grep sparcv9`
- if [ "$ISA64" != "" ]; then
+ if [ "$ISA64" != "" -a "$KERNEL_BITS" = "" ]; then
if [ "$CC" = "cc" -a $CCVER -ge 50 ]; then
echo "WARNING! If you wish to build 64-bit library, then you have to"
echo " invoke './Configure solaris64-sparcv9-cc' *manually*."
@@ -678,13 +708,16 @@ case "$GUESSOS" in
fi
fi
fi
+ if [ "$ISA64" != "" -a "$KERNEL_BITS" = "64" ]; then
+ OUT="solaris64-sparcv9-$CC"
+ fi
;;
sun4m-*-solaris2) OUT="solaris-sparcv8-$CC" ;;
sun4d-*-solaris2) OUT="solaris-sparcv8-$CC" ;;
sun4*-*-solaris2) OUT="solaris-sparcv7-$CC" ;;
*86*-*-solaris2)
ISA64=`(isalist) 2>/dev/null | grep amd64`
- if [ "$ISA64" != "" ]; then
+ if [ "$ISA64" != "" -a ${KERNEL_BITS:-64} -eq 64 ]; then
OUT="solaris64-x86_64-$CC"
else
OUT="solaris-x86-$CC"
@@ -736,20 +769,17 @@ case "$GUESSOS" in
if [ $CC = "gcc" -a $GCC_BITS = "64" ]; then
OUT="hpux64-parisc2-gcc"
fi
- KERNEL_BITS=`(getconf KERNEL_BITS) 2>/dev/null`
+ [ "$KERNEL_BITS" ] || KERNEL_BITS=`(getconf KERNEL_BITS) 2>/dev/null`
KERNEL_BITS=${KERNEL_BITS:-32}
CPU_VERSION=`(getconf CPU_VERSION) 2>/dev/null`
CPU_VERSION=${CPU_VERSION:-0}
# See <sys/unistd.h> for further info on CPU_VERSION.
if [ $CPU_VERSION -ge 768 ]; then # IA-64 CPU
- echo "WARNING! 64-bit ABI is the default configured ABI on HP-UXi."
- echo " If you wish to build 32-bit library, the you have to"
- echo " invoke './Configure hpux-ia64-cc' *manually*."
- if [ "$TEST" = "false" -a -t 1 ]; then
- echo " You have about 5 seconds to press Ctrl-C to abort."
- (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
- fi
- OUT="hpux64-ia64-cc"
+ if [ $KERNEL_BITS -eq 64 -a "$CC" = "cc" ]; then
+ OUT="hpux64-ia64-cc"
+ else
+ OUT="hpux-ia64-cc"
+ fi
elif [ $CPU_VERSION -ge 532 ]; then # PA-RISC 2.x CPU
OUT=${OUT:-"hpux-parisc2-${CC}"}
if [ $KERNEL_BITS -eq 64 -a "$CC" = "cc" ]; then
@@ -770,7 +800,7 @@ case "$GUESSOS" in
options="$options -D_REENTRANT" ;;
*-hpux) OUT="hpux-parisc-$CC" ;;
*-aix)
- KERNEL_BITS=`(getconf KERNEL_BITMODE) 2>/dev/null`
+ [ "$KERNEL_BITS" ] || KERNEL_BITS=`(getconf KERNEL_BITMODE) 2>/dev/null`
KERNEL_BITS=${KERNEL_BITS:-32}
OBJECT_MODE=${OBJECT_MODE:-32}
if [ "$CC" = "gcc" ]; then
@@ -810,6 +840,8 @@ case "$GUESSOS" in
beos-*) OUT="$GUESSOS" ;;
x86pc-*-qnx6) OUT="QNX6-i386" ;;
*-*-qnx6) OUT="QNX6" ;;
+ x86-*-android|i?86-*-android) OUT="android-x86" ;;
+ armv[7-9]*-*-android) OUT="android-armv7" ;;
*) OUT=`echo $GUESSOS | awk -F- '{print $3}'`;;
esac
@@ -825,9 +857,11 @@ esac
# options="$options -DATALLA"
#fi
-($CC -Wa,--help -c -o /dev/null -x assembler /dev/null 2>&1 | \
- grep \\--noexecstack) 2>&1 > /dev/null && \
+if expr "$options" : '.*no\-asm' > /dev/null; then :; else
+ sh -c "$CROSS_COMPILE${CC:-gcc} -Wa,--help -c -o /tmp/null.$$.o -x assembler /dev/null && rm /tmp/null.$$.o" 2>&1 | \
+ grep \\--noexecstack >/dev/null && \
options="$options -Wa,--noexecstack"
+fi
# gcc < 2.8 does not support -march=ultrasparc
if [ "$OUT" = solaris-sparcv9-gcc -a $GCCVER -lt 28 ]
diff --git a/deps/openssl/openssl/crypto/Makefile b/deps/openssl/openssl/crypto/Makefile
index 85d9f249c..947dd5d44 100644
--- a/deps/openssl/openssl/crypto/Makefile
+++ b/deps/openssl/openssl/crypto/Makefile
@@ -7,7 +7,7 @@ TOP= ..
CC= cc
INCLUDE= -I. -I$(TOP) -I../include $(ZLIB_INCLUDE)
# INCLUDES targets sudbirs!
-INCLUDES= -I.. -I../.. -I../asn1 -I../evp -I../../include $(ZLIB_INCLUDE)
+INCLUDES= -I.. -I../.. -I../modes -I../asn1 -I../evp -I../../include $(ZLIB_INCLUDE)
CFLAG= -g
MAKEDEPPROG= makedepend
MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
@@ -34,8 +34,10 @@ GENERAL=Makefile README crypto-lib.com install.com
LIB= $(TOP)/libcrypto.a
SHARED_LIB= libcrypto$(SHLIB_EXT)
-LIBSRC= cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c ebcdic.c uid.c o_time.c o_str.c o_dir.c
-LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o uid.o o_time.o o_str.o o_dir.o $(CPUID_OBJ)
+LIBSRC= cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c \
+ ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c
+LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o \
+ uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o $(CPUID_OBJ)
SRC= $(LIBSRC)
@@ -67,14 +69,13 @@ applink.o: $(TOP)/ms/applink.c
uplink.o: $(TOP)/ms/uplink.c applink.o
$(CC) $(CFLAGS) -c -o $@ $(TOP)/ms/uplink.c
-uplink-cof.s: $(TOP)/ms/uplink.pl
- $(PERL) $(TOP)/ms/uplink.pl coff > $@
+uplink-x86.s: $(TOP)/ms/uplink-x86.pl
+ $(PERL) $(TOP)/ms/uplink-x86.pl $(PERLASM_SCHEME) > $@
-x86_64cpuid.s: x86_64cpuid.pl
- $(PERL) x86_64cpuid.pl $(PERLASM_SCHEME) > $@
-ia64cpuid.s: ia64cpuid.S
- $(CC) $(CFLAGS) -E ia64cpuid.S > $@
+x86_64cpuid.s: x86_64cpuid.pl; $(PERL) x86_64cpuid.pl $(PERLASM_SCHEME) > $@
+ia64cpuid.s: ia64cpuid.S; $(CC) $(CFLAGS) -E ia64cpuid.S > $@
ppccpuid.s: ppccpuid.pl; $(PERL) ppccpuid.pl $(PERLASM_SCHEME) $@
+pariscid.s: pariscid.pl; $(PERL) pariscid.pl $(PERLASM_SCHEME) $@
alphacpuid.s: alphacpuid.pl
$(PERL) $< | $(CC) -E - | tee $@ > /dev/null
@@ -102,6 +103,7 @@ lib: $(LIB)
@touch lib
$(LIB): $(LIBOBJ)
$(AR) $(LIB) $(LIBOBJ)
+ [ -z "$(FIPSLIBDIR)" ] || $(AR) $(LIB) $(FIPSLIBDIR)fipscanister.o
$(RANLIB) $(LIB) || echo Never mind.
shared: buildinf.h lib subdirs
@@ -171,6 +173,7 @@ ex_data.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
ex_data.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
ex_data.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
ex_data.o: ex_data.c
+fips_ers.o: ../include/openssl/opensslconf.h fips_ers.c
mem.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
mem.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
mem.o: ../include/openssl/err.h ../include/openssl/lhash.h
@@ -191,6 +194,19 @@ mem_dbg.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
mem_dbg.o: mem_dbg.c
o_dir.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
o_dir.o: LPdir_unix.c o_dir.c o_dir.h
+o_fips.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
+o_fips.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+o_fips.o: ../include/openssl/err.h ../include/openssl/lhash.h
+o_fips.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+o_fips.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+o_fips.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
+o_fips.o: o_fips.c
+o_init.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/crypto.h
+o_init.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+o_init.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
+o_init.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+o_init.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+o_init.o: ../include/openssl/symhacks.h o_init.c
o_str.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
o_str.o: o_str.c o_str.h
o_time.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h o_time.c
diff --git a/deps/openssl/openssl/crypto/aes/Makefile b/deps/openssl/openssl/crypto/aes/Makefile
index c501a43a8..45ede0a0b 100644
--- a/deps/openssl/openssl/crypto/aes/Makefile
+++ b/deps/openssl/openssl/crypto/aes/Makefile
@@ -50,9 +50,21 @@ aes-ia64.s: asm/aes-ia64.S
aes-586.s: asm/aes-586.pl ../perlasm/x86asm.pl
$(PERL) asm/aes-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+vpaes-x86.s: asm/vpaes-x86.pl ../perlasm/x86asm.pl
+ $(PERL) asm/vpaes-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+aesni-x86.s: asm/aesni-x86.pl ../perlasm/x86asm.pl
+ $(PERL) asm/aesni-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
aes-x86_64.s: asm/aes-x86_64.pl
$(PERL) asm/aes-x86_64.pl $(PERLASM_SCHEME) > $@
+vpaes-x86_64.s: asm/vpaes-x86_64.pl
+ $(PERL) asm/vpaes-x86_64.pl $(PERLASM_SCHEME) > $@
+bsaes-x86_64.s: asm/bsaes-x86_64.pl
+ $(PERL) asm/bsaes-x86_64.pl $(PERLASM_SCHEME) > $@
+aesni-x86_64.s: asm/aesni-x86_64.pl
+ $(PERL) asm/aesni-x86_64.pl $(PERLASM_SCHEME) > $@
+aesni-sha1-x86_64.s: asm/aesni-sha1-x86_64.pl
+ $(PERL) asm/aesni-sha1-x86_64.pl $(PERLASM_SCHEME) > $@
aes-sparcv9.s: asm/aes-sparcv9.pl
$(PERL) asm/aes-sparcv9.pl $(CFLAGS) > $@
@@ -60,8 +72,15 @@ aes-sparcv9.s: asm/aes-sparcv9.pl
aes-ppc.s: asm/aes-ppc.pl
$(PERL) asm/aes-ppc.pl $(PERLASM_SCHEME) $@
+aes-parisc.s: asm/aes-parisc.pl
+ $(PERL) asm/aes-parisc.pl $(PERLASM_SCHEME) $@
+
+aes-mips.S: asm/aes-mips.pl
+ $(PERL) asm/aes-mips.pl $(PERLASM_SCHEME) $@
+
# GNU make "catch all"
-aes-%.s: asm/aes-%.pl; $(PERL) $< $(CFLAGS) > $@
+aes-%.S: asm/aes-%.pl; $(PERL) $< $(PERLASM_SCHEME) > $@
+aes-armv4.o: aes-armv4.S
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
@@ -117,9 +136,11 @@ aes_ige.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
aes_ige.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
aes_ige.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
aes_ige.o: ../../include/openssl/symhacks.h ../cryptlib.h aes_ige.c aes_locl.h
-aes_misc.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
-aes_misc.o: ../../include/openssl/opensslconf.h
-aes_misc.o: ../../include/openssl/opensslv.h aes_locl.h aes_misc.c
+aes_misc.o: ../../include/openssl/aes.h ../../include/openssl/crypto.h
+aes_misc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+aes_misc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+aes_misc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+aes_misc.o: ../../include/openssl/symhacks.h aes_locl.h aes_misc.c
aes_ofb.o: ../../include/openssl/aes.h ../../include/openssl/modes.h
aes_ofb.o: ../../include/openssl/opensslconf.h aes_ofb.c
aes_wrap.o: ../../e_os.h ../../include/openssl/aes.h
diff --git a/deps/openssl/openssl/crypto/aes/aes.h b/deps/openssl/openssl/crypto/aes/aes.h
index d2c99730f..031abf01b 100644
--- a/deps/openssl/openssl/crypto/aes/aes.h
+++ b/deps/openssl/openssl/crypto/aes/aes.h
@@ -90,6 +90,11 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
+int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+
void AES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_decrypt(const unsigned char *in, unsigned char *out,
diff --git a/deps/openssl/openssl/crypto/aes/aes_core.c b/deps/openssl/openssl/crypto/aes/aes_core.c
index a7ec54f4d..8f5210ac7 100644
--- a/deps/openssl/openssl/crypto/aes/aes_core.c
+++ b/deps/openssl/openssl/crypto/aes/aes_core.c
@@ -625,7 +625,7 @@ static const u32 rcon[] = {
/**
* Expand the cipher key into the encryption key schedule.
*/
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key) {
u32 *rk;
@@ -726,7 +726,7 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
/**
* Expand the cipher key into the decryption key schedule.
*/
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key) {
u32 *rk;
@@ -734,7 +734,7 @@ int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
u32 temp;
/* first, start with an encryption schedule */
- status = AES_set_encrypt_key(userKey, bits, key);
+ status = private_AES_set_encrypt_key(userKey, bits, key);
if (status < 0)
return status;
@@ -1201,7 +1201,7 @@ static const u32 rcon[] = {
/**
* Expand the cipher key into the encryption key schedule.
*/
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key) {
u32 *rk;
int i = 0;
@@ -1301,7 +1301,7 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
/**
* Expand the cipher key into the decryption key schedule.
*/
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key) {
u32 *rk;
@@ -1309,7 +1309,7 @@ int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
u32 temp;
/* first, start with an encryption schedule */
- status = AES_set_encrypt_key(userKey, bits, key);
+ status = private_AES_set_encrypt_key(userKey, bits, key);
if (status < 0)
return status;
diff --git a/deps/openssl/openssl/crypto/aes/aes_misc.c b/deps/openssl/openssl/crypto/aes/aes_misc.c
index 4fead1b4c..f083488ec 100644
--- a/deps/openssl/openssl/crypto/aes/aes_misc.c
+++ b/deps/openssl/openssl/crypto/aes/aes_misc.c
@@ -50,6 +50,7 @@
*/
#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
#include <openssl/aes.h>
#include "aes_locl.h"
@@ -62,3 +63,23 @@ const char *AES_options(void) {
return "aes(partial)";
#endif
}
+
+/* FIPS wrapper functions to block low level AES calls in FIPS mode */
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key)
+ {
+#ifdef OPENSSL_FIPS
+ fips_cipher_abort(AES);
+#endif
+ return private_AES_set_encrypt_key(userKey, bits, key);
+ }
+
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key)
+ {
+#ifdef OPENSSL_FIPS
+ fips_cipher_abort(AES);
+#endif
+ return private_AES_set_decrypt_key(userKey, bits, key);
+ }
diff --git a/deps/openssl/openssl/crypto/aes/asm/aes-586.pl b/deps/openssl/openssl/crypto/aes/asm/aes-586.pl
index fed3150f8..6eb479035 100755
--- a/deps/openssl/openssl/crypto/aes/asm/aes-586.pl
+++ b/deps/openssl/openssl/crypto/aes/asm/aes-586.pl
@@ -39,7 +39,7 @@
# but exhibits up to 10% improvement on other cores.
#
# Second version is "monolithic" replacement for aes_core.c, which in
-# addition to AES_[de|en]crypt implements AES_set_[de|en]cryption_key.
+# addition to AES_[de|en]crypt implements private_AES_set_[de|en]cryption_key.
# This made it possible to implement little-endian variant of the
# algorithm without modifying the base C code. Motivating factor for
# the undertaken effort was that it appeared that in tight IA-32
@@ -2854,12 +2854,12 @@ sub enckey()
&set_label("exit");
&function_end("_x86_AES_set_encrypt_key");
-# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+# int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
# AES_KEY *key)
-&function_begin_B("AES_set_encrypt_key");
+&function_begin_B("private_AES_set_encrypt_key");
&call ("_x86_AES_set_encrypt_key");
&ret ();
-&function_end_B("AES_set_encrypt_key");
+&function_end_B("private_AES_set_encrypt_key");
sub deckey()
{ my ($i,$key,$tp1,$tp2,$tp4,$tp8) = @_;
@@ -2916,9 +2916,9 @@ sub deckey()
&mov (&DWP(4*$i,$key),$tp1);
}
-# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+# int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
# AES_KEY *key)
-&function_begin_B("AES_set_decrypt_key");
+&function_begin_B("private_AES_set_decrypt_key");
&call ("_x86_AES_set_encrypt_key");
&cmp ("eax",0);
&je (&label("proceed"));
@@ -2974,7 +2974,7 @@ sub deckey()
&jb (&label("permute"));
&xor ("eax","eax"); # return success
-&function_end("AES_set_decrypt_key");
+&function_end("private_AES_set_decrypt_key");
&asciz("AES for x86, CRYPTOGAMS by <appro\@openssl.org>");
&asm_finish();
diff --git a/deps/openssl/openssl/crypto/aes/asm/aes-armv4.pl b/deps/openssl/openssl/crypto/aes/asm/aes-armv4.pl
index c51ee1fbf..86b86c4a0 100644
--- a/deps/openssl/openssl/crypto/aes/asm/aes-armv4.pl
+++ b/deps/openssl/openssl/crypto/aes/asm/aes-armv4.pl
@@ -27,6 +27,11 @@
# Rescheduling for dual-issue pipeline resulted in 12% improvement on
# Cortex A8 core and ~25 cycles per byte processed with 128-bit key.
+# February 2011.
+#
+# Profiler-assisted and platform-specific optimization resulted in 16%
+# improvement on Cortex A8 core and ~21.5 cycles per byte.
+
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
@@ -46,6 +51,7 @@ $key="r11";
$rounds="r12";
$code=<<___;
+#include "arm_arch.h"
.text
.code 32
@@ -166,7 +172,7 @@ AES_encrypt:
mov $rounds,r0 @ inp
mov $key,r2
sub $tbl,r3,#AES_encrypt-AES_Te @ Te
-
+#if __ARM_ARCH__<7
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
ldrb $t1,[$rounds,#2] @ manner...
ldrb $t2,[$rounds,#1]
@@ -195,10 +201,33 @@ AES_encrypt:
orr $s3,$s3,$t1,lsl#8
orr $s3,$s3,$t2,lsl#16
orr $s3,$s3,$t3,lsl#24
-
+#else
+ ldr $s0,[$rounds,#0]
+ ldr $s1,[$rounds,#4]
+ ldr $s2,[$rounds,#8]
+ ldr $s3,[$rounds,#12]
+#ifdef __ARMEL__
+ rev $s0,$s0
+ rev $s1,$s1
+ rev $s2,$s2
+ rev $s3,$s3
+#endif
+#endif
bl _armv4_AES_encrypt
ldr $rounds,[sp],#4 @ pop out
+#if __ARM_ARCH__>=7
+#ifdef __ARMEL__
+ rev $s0,$s0
+ rev $s1,$s1
+ rev $s2,$s2
+ rev $s3,$s3
+#endif
+ str $s0,[$rounds,#0]
+ str $s1,[$rounds,#4]
+ str $s2,[$rounds,#8]
+ str $s3,[$rounds,#12]
+#else
mov $t1,$s0,lsr#24 @ write output in endian-neutral
mov $t2,$s0,lsr#16 @ manner...
mov $t3,$s0,lsr#8
@@ -227,11 +256,15 @@ AES_encrypt:
strb $t2,[$rounds,#13]
strb $t3,[$rounds,#14]
strb $s3,[$rounds,#15]
-
+#endif
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r12,pc}
+#else
ldmia sp!,{r4-r12,lr}
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
bx lr @ interoperable with Thumb ISA:-)
+#endif
.size AES_encrypt,.-AES_encrypt
.type _armv4_AES_encrypt,%function
@@ -271,11 +304,11 @@ _armv4_AES_encrypt:
and $i2,lr,$s2,lsr#16 @ i1
eor $t3,$t3,$i3,ror#8
and $i3,lr,$s2
- eor $s1,$s1,$t1,ror#24
ldr $i1,[$tbl,$i1,lsl#2] @ Te2[s2>>8]
+ eor $s1,$s1,$t1,ror#24
+ ldr $i2,[$tbl,$i2,lsl#2] @ Te1[s2>>16]
mov $s2,$s2,lsr#24
- ldr $i2,[$tbl,$i2,lsl#2] @ Te1[s2>>16]
ldr $i3,[$tbl,$i3,lsl#2] @ Te3[s2>>0]
eor $s0,$s0,$i1,ror#16
ldr $s2,[$tbl,$s2,lsl#2] @ Te0[s2>>24]
@@ -284,16 +317,16 @@ _armv4_AES_encrypt:
and $i2,lr,$s3,lsr#8 @ i1
eor $t3,$t3,$i3,ror#16
and $i3,lr,$s3,lsr#16 @ i2
- eor $s2,$s2,$t2,ror#16
ldr $i1,[$tbl,$i1,lsl#2] @ Te3[s3>>0]
+ eor $s2,$s2,$t2,ror#16
+ ldr $i2,[$tbl,$i2,lsl#2] @ Te2[s3>>8]
mov $s3,$s3,lsr#24
- ldr $i2,[$tbl,$i2,lsl#2] @ Te2[s3>>8]
ldr $i3,[$tbl,$i3,lsl#2] @ Te1[s3>>16]
eor $s0,$s0,$i1,ror#24
- ldr $s3,[$tbl,$s3,lsl#2] @ Te0[s3>>24]
- eor $s1,$s1,$i2,ror#16
ldr $i1,[$key],#16
+ eor $s1,$s1,$i2,ror#16
+ ldr $s3,[$tbl,$s3,lsl#2] @ Te0[s3>>24]
eor $s2,$s2,$i3,ror#8
ldr $t1,[$key,#-12]
eor $s3,$s3,$t3,ror#8
@@ -333,11 +366,11 @@ _armv4_AES_encrypt:
and $i2,lr,$s2,lsr#16 @ i1
eor $t3,$i3,$t3,lsl#8
and $i3,lr,$s2
- eor $s1,$t1,$s1,lsl#24
ldrb $i1,[$tbl,$i1,lsl#2] @ Te4[s2>>8]
+ eor $s1,$t1,$s1,lsl#24
+ ldrb $i2,[$tbl,$i2,lsl#2] @ Te4[s2>>16]
mov $s2,$s2,lsr#24
- ldrb $i2,[$tbl,$i2,lsl#2] @ Te4[s2>>16]
ldrb $i3,[$tbl,$i3,lsl#2] @ Te4[s2>>0]
eor $s0,$i1,$s0,lsl#8
ldrb $s2,[$tbl,$s2,lsl#2] @ Te4[s2>>24]
@@ -346,15 +379,15 @@ _armv4_AES_encrypt:
and $i2,lr,$s3,lsr#8 @ i1
eor $t3,$i3,$t3,lsl#8
and $i3,lr,$s3,lsr#16 @ i2
- eor $s2,$t2,$s2,lsl#24
ldrb $i1,[$tbl,$i1,lsl#2] @ Te4[s3>>0]
+ eor $s2,$t2,$s2,lsl#24
+ ldrb $i2,[$tbl,$i2,lsl#2] @ Te4[s3>>8]
mov $s3,$s3,lsr#24
- ldrb $i2,[$tbl,$i2,lsl#2] @ Te4[s3>>8]
ldrb $i3,[$tbl,$i3,lsl#2] @ Te4[s3>>16]
eor $s0,$i1,$s0,lsl#8
- ldrb $s3,[$tbl,$s3,lsl#2] @ Te4[s3>>24]
ldr $i1,[$key,#0]
+ ldrb $s3,[$tbl,$s3,lsl#2] @ Te4[s3>>24]
eor $s1,$s1,$i2,lsl#8
ldr $t1,[$key,#4]
eor $s2,$s2,$i3,lsl#16
@@ -371,10 +404,11 @@ _armv4_AES_encrypt:
ldr pc,[sp],#4 @ pop and return
.size _armv4_AES_encrypt,.-_armv4_AES_encrypt
-.global AES_set_encrypt_key
-.type AES_set_encrypt_key,%function
+.global private_AES_set_encrypt_key
+.type private_AES_set_encrypt_key,%function
.align 5
-AES_set_encrypt_key:
+private_AES_set_encrypt_key:
+_armv4_AES_set_encrypt_key:
sub r3,pc,#8 @ AES_set_encrypt_key
teq r0,#0
moveq r0,#-1
@@ -392,12 +426,13 @@ AES_set_encrypt_key:
bne .Labrt
.Lok: stmdb sp!,{r4-r12,lr}
- sub $tbl,r3,#AES_set_encrypt_key-AES_Te-1024 @ Te4
+ sub $tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024 @ Te4
mov $rounds,r0 @ inp
mov lr,r1 @ bits
mov $key,r2 @ key
+#if __ARM_ARCH__<7
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
ldrb $t1,[$rounds,#2] @ manner...
ldrb $t2,[$rounds,#1]
@@ -430,6 +465,22 @@ AES_set_encrypt_key:
orr $s3,$s3,$t3,lsl#24
str $s2,[$key,#-8]
str $s3,[$key,#-4]
+#else
+ ldr $s0,[$rounds,#0]
+ ldr $s1,[$rounds,#4]
+ ldr $s2,[$rounds,#8]
+ ldr $s3,[$rounds,#12]
+#ifdef __ARMEL__
+ rev $s0,$s0
+ rev $s1,$s1
+ rev $s2,$s2
+ rev $s3,$s3
+#endif
+ str $s0,[$key],#16
+ str $s1,[$key,#-12]
+ str $s2,[$key,#-8]
+ str $s3,[$key,#-4]
+#endif
teq lr,#128
bne .Lnot128
@@ -466,6 +517,7 @@ AES_set_encrypt_key:
b .Ldone
.Lnot128:
+#if __ARM_ARCH__<7
ldrb $i2,[$rounds,#19]
ldrb $t1,[$rounds,#18]
ldrb $t2,[$rounds,#17]
@@ -482,6 +534,16 @@ AES_set_encrypt_key:
str $i2,[$key],#8
orr $i3,$i3,$t3,lsl#24
str $i3,[$key,#-4]
+#else
+ ldr $i2,[$rounds,#16]
+ ldr $i3,[$rounds,#20]
+#ifdef __ARMEL__
+ rev $i2,$i2
+ rev $i3,$i3
+#endif
+ str $i2,[$key],#8
+ str $i3,[$key,#-4]
+#endif
teq lr,#192
bne .Lnot192
@@ -526,6 +588,7 @@ AES_set_encrypt_key:
b .L192_loop
.Lnot192:
+#if __ARM_ARCH__<7
ldrb $i2,[$rounds,#27]
ldrb $t1,[$rounds,#26]
ldrb $t2,[$rounds,#25]
@@ -542,6 +605,16 @@ AES_set_encrypt_key:
str $i2,[$key],#8
orr $i3,$i3,$t3,lsl#24
str $i3,[$key,#-4]
+#else
+ ldr $i2,[$rounds,#24]
+ ldr $i3,[$rounds,#28]
+#ifdef __ARMEL__
+ rev $i2,$i2
+ rev $i3,$i3
+#endif
+ str $i2,[$key],#8
+ str $i3,[$key,#-4]
+#endif
mov $rounds,#14
str $rounds,[$key,#240-32]
@@ -606,14 +679,14 @@ AES_set_encrypt_key:
.Labrt: tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
bx lr @ interoperable with Thumb ISA:-)
-.size AES_set_encrypt_key,.-AES_set_encrypt_key
+.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
-.global AES_set_decrypt_key
-.type AES_set_decrypt_key,%function
+.global private_AES_set_decrypt_key
+.type private_AES_set_decrypt_key,%function
.align 5
-AES_set_decrypt_key:
+private_AES_set_decrypt_key:
str lr,[sp,#-4]! @ push lr
- bl AES_set_encrypt_key
+ bl _armv4_AES_set_encrypt_key
teq r0,#0
ldrne lr,[sp],#4 @ pop lr
bne .Labrt
@@ -692,11 +765,15 @@ $code.=<<___;
bne .Lmix
mov r0,#0
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r12,pc}
+#else
ldmia sp!,{r4-r12,lr}
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
bx lr @ interoperable with Thumb ISA:-)
-.size AES_set_decrypt_key,.-AES_set_decrypt_key
+#endif
+.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
.type AES_Td,%object
.align 5
@@ -811,7 +888,7 @@ AES_decrypt:
mov $rounds,r0 @ inp
mov $key,r2
sub $tbl,r3,#AES_decrypt-AES_Td @ Td
-
+#if __ARM_ARCH__<7
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
ldrb $t1,[$rounds,#2] @ manner...
ldrb $t2,[$rounds,#1]
@@ -840,10 +917,33 @@ AES_decrypt:
orr $s3,$s3,$t1,lsl#8
orr $s3,$s3,$t2,lsl#16
orr $s3,$s3,$t3,lsl#24
-
+#else
+ ldr $s0,[$rounds,#0]
+ ldr $s1,[$rounds,#4]
+ ldr $s2,[$rounds,#8]
+ ldr $s3,[$rounds,#12]
+#ifdef __ARMEL__
+ rev $s0,$s0
+ rev $s1,$s1
+ rev $s2,$s2
+ rev $s3,$s3
+#endif
+#endif
bl _armv4_AES_decrypt
ldr $rounds,[sp],#4 @ pop out
+#if __ARM_ARCH__>=7
+#ifdef __ARMEL__
+ rev $s0,$s0
+ rev $s1,$s1
+ rev $s2,$s2
+ rev $s3,$s3
+#endif
+ str $s0,[$rounds,#0]
+ str $s1,[$rounds,#4]
+ str $s2,[$rounds,#8]
+ str $s3,[$rounds,#12]
+#else
mov $t1,$s0,lsr#24 @ write output in endian-neutral
mov $t2,$s0,lsr#16 @ manner...
mov $t3,$s0,lsr#8
@@ -872,11 +972,15 @@ AES_decrypt:
strb $t2,[$rounds,#13]
strb $t3,[$rounds,#14]
strb $s3,[$rounds,#15]
-
+#endif
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r12,pc}
+#else
ldmia sp!,{r4-r12,lr}
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
bx lr @ interoperable with Thumb ISA:-)
+#endif
.size AES_decrypt,.-AES_decrypt
.type _armv4_AES_decrypt,%function
@@ -916,11 +1020,11 @@ _armv4_AES_decrypt:
and $i2,lr,$s2 @ i1
eor $t3,$i3,$t3,ror#8
and $i3,lr,$s2,lsr#16
- eor $s1,$s1,$t1,ror#8
ldr $i1,[$tbl,$i1,lsl#2] @ Td2[s2>>8]
+ eor $s1,$s1,$t1,ror#8
+ ldr $i2,[$tbl,$i2,lsl#2] @ Td3[s2>>0]
mov $s2,$s2,lsr#24
- ldr $i2,[$tbl,$i2,lsl#2] @ Td3[s2>>0]
ldr $i3,[$tbl,$i3,lsl#2] @ Td1[s2>>16]
eor $s0,$s0,$i1,ror#16
ldr $s2,[$tbl,$s2,lsl#2] @ Td0[s2>>24]
@@ -929,22 +1033,22 @@ _armv4_AES_decrypt:
and $i2,lr,$s3,lsr#8 @ i1
eor $t3,$i3,$t3,ror#8
and $i3,lr,$s3 @ i2
- eor $s2,$s2,$t2,ror#8
ldr $i1,[$tbl,$i1,lsl#2] @ Td1[s3>>16]
+ eor $s2,$s2,$t2,ror#8
+ ldr $i2,[$tbl,$i2,lsl#2] @ Td2[s3>>8]
mov $s3,$s3,lsr#24
- ldr $i2,[$tbl,$i2,lsl#2] @ Td2[s3>>8]
ldr $i3,[$tbl,$i3,lsl#2] @ Td3[s3>>0]
eor $s0,$s0,$i1,ror#8
- ldr $s3,[$tbl,$s3,lsl#2] @ Td0[s3>>24]
+ ldr $i1,[$key],#16
eor $s1,$s1,$i2,ror#16
+ ldr $s3,[$tbl,$s3,lsl#2] @ Td0[s3>>24]
eor $s2,$s2,$i3,ror#24
- ldr $i1,[$key],#16
- eor $s3,$s3,$t3,ror#8
ldr $t1,[$key,#-12]
- ldr $t2,[$key,#-8]
eor $s0,$s0,$i1
+ ldr $t2,[$key,#-8]
+ eor $s3,$s3,$t3,ror#8
ldr $t3,[$key,#-4]
and $i1,lr,$s0,lsr#16
eor $s1,$s1,$t1
@@ -985,11 +1089,11 @@ _armv4_AES_decrypt:
and $i1,lr,$s2,lsr#8 @ i0
eor $t2,$t2,$i2,lsl#8
and $i2,lr,$s2 @ i1
- eor $t3,$t3,$i3,lsl#8
ldrb $i1,[$tbl,$i1] @ Td4[s2>>8]
+ eor $t3,$t3,$i3,lsl#8
+ ldrb $i2,[$tbl,$i2] @ Td4[s2>>0]
and $i3,lr,$s2,lsr#16
- ldrb $i2,[$tbl,$i2] @ Td4[s2>>0]
ldrb $s2,[$tbl,$s2,lsr#24] @ Td4[s2>>24]
eor $s0,$s0,$i1,lsl#8
ldrb $i3,[$tbl,$i3] @ Td4[s2>>16]
@@ -997,11 +1101,11 @@ _armv4_AES_decrypt:
and $i1,lr,$s3,lsr#16 @ i0
eor $s2,$t2,$s2,lsl#16
and $i2,lr,$s3,lsr#8 @ i1
- eor $t3,$t3,$i3,lsl#16
ldrb $i1,[$tbl,$i1] @ Td4[s3>>16]
+ eor $t3,$t3,$i3,lsl#16
+ ldrb $i2,[$tbl,$i2] @ Td4[s3>>8]
and $i3,lr,$s3 @ i2
- ldrb $i2,[$tbl,$i2] @ Td4[s3>>8]
ldrb $i3,[$tbl,$i3] @ Td4[s3>>0]
ldrb $s3,[$tbl,$s3,lsr#24] @ Td4[s3>>24]
eor $s0,$s0,$i1,lsl#16
diff --git a/deps/openssl/openssl/crypto/aes/asm/aes-mips.pl b/deps/openssl/openssl/crypto/aes/asm/aes-mips.pl
new file mode 100644
index 000000000..e52395421
--- /dev/null
+++ b/deps/openssl/openssl/crypto/aes/asm/aes-mips.pl
@@ -0,0 +1,1611 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# AES for MIPS
+
+# October 2010
+#
+# Code uses 1K[+256B] S-box and on single-issue core [such as R5000]
+# spends ~68 cycles per byte processed with 128-bit key. This is ~16%
+# faster than gcc-generated code, which is not very impressive. But
+# recall that compressed S-box requires extra processing, namely
+# additional rotations. Rotations are implemented with lwl/lwr pairs,
+# which is normally used for loading unaligned data. Another cool
+# thing about this module is its endian neutrality, which means that
+# it processes data without ever changing byte order...
+
+######################################################################
+# There is a number of MIPS ABI in use, O32 and N32/64 are most
+# widely used. Then there is a new contender: NUBI. It appears that if
+# one picks the latter, it's possible to arrange code in ABI neutral
+# manner. Therefore let's stick to NUBI register layout:
+#
+($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
+($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
+#
+# The return value is placed in $a0. Following coding rules facilitate
+# interoperability:
+#
+# - never ever touch $tp, "thread pointer", former $gp;
+# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
+# old code];
+# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
+#
+# For reference here is register layout for N32/64 MIPS ABIs:
+#
+# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
+# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
+# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
+# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
+# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
+#
+$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
+
+if ($flavour =~ /64|n32/i) {
+ $PTR_ADD="dadd"; # incidentally works even on n32
+ $PTR_SUB="dsub"; # incidentally works even on n32
+ $REG_S="sd";
+ $REG_L="ld";
+ $PTR_SLL="dsll"; # incidentally works even on n32
+ $SZREG=8;
+} else {
+ $PTR_ADD="add";
+ $PTR_SUB="sub";
+ $REG_S="sw";
+ $REG_L="lw";
+ $PTR_SLL="sll";
+ $SZREG=4;
+}
+$pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
+#
+# <appro@openssl.org>
+#
+######################################################################
+
+$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0;
+
+for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); }
+open STDOUT,">$output";
+
+if (!defined($big_endian))
+{ $big_endian=(unpack('L',pack('N',1))==1); }
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+my ($MSB,$LSB)=(0,3); # automatically converted to little-endian
+
+$code.=<<___;
+.text
+#ifdef OPENSSL_FIPSCANISTER
+# include <openssl/fipssyms.h>
+#endif
+
+#if !defined(__vxworks) || defined(__pic__)
+.option pic2
+#endif
+.set noat
+___
+
+{{{
+my $FRAMESIZE=16*$SZREG;
+my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000;
+
+my ($inp,$out,$key,$Tbl,$s0,$s1,$s2,$s3)=($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7);
+my ($i0,$i1,$i2,$i3)=($at,$t0,$t1,$t2);
+my ($t0,$t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$t9,$t10,$t11) = map("\$$_",(12..23));
+my ($key0,$cnt)=($gp,$fp);
+
+# instuction ordering is "stolen" from output from MIPSpro assembler
+# invoked with -mips3 -O3 arguments...
+$code.=<<___;
+.align 5
+.ent _mips_AES_encrypt
+_mips_AES_encrypt:
+ .frame $sp,0,$ra
+ .set reorder
+ lw $t0,0($key)
+ lw $t1,4($key)
+ lw $t2,8($key)
+ lw $t3,12($key)
+ lw $cnt,240($key)
+ $PTR_ADD $key0,$key,16
+
+ xor $s0,$t0
+ xor $s1,$t1
+ xor $s2,$t2
+ xor $s3,$t3
+
+ sub $cnt,1
+ _xtr $i0,$s1,16-2
+.Loop_enc:
+ _xtr $i1,$s2,16-2
+ _xtr $i2,$s3,16-2
+ _xtr $i3,$s0,16-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lwl $t0,3($i0) # Te1[s1>>16]
+ lwl $t1,3($i1) # Te1[s2>>16]
+ lwl $t2,3($i2) # Te1[s3>>16]
+ lwl $t3,3($i3) # Te1[s0>>16]
+ lwr $t0,2($i0) # Te1[s1>>16]
+ lwr $t1,2($i1) # Te1[s2>>16]
+ lwr $t2,2($i2) # Te1[s3>>16]
+ lwr $t3,2($i3) # Te1[s0>>16]
+
+ _xtr $i0,$s2,8-2
+ _xtr $i1,$s3,8-2
+ _xtr $i2,$s0,8-2
+ _xtr $i3,$s1,8-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lwl $t4,2($i0) # Te2[s2>>8]
+ lwl $t5,2($i1) # Te2[s3>>8]
+ lwl $t6,2($i2) # Te2[s0>>8]
+ lwl $t7,2($i3) # Te2[s1>>8]
+ lwr $t4,1($i0) # Te2[s2>>8]
+ lwr $t5,1($i1) # Te2[s3>>8]
+ lwr $t6,1($i2) # Te2[s0>>8]
+ lwr $t7,1($i3) # Te2[s1>>8]
+
+ _xtr $i0,$s3,0-2
+ _xtr $i1,$s0,0-2
+ _xtr $i2,$s1,0-2
+ _xtr $i3,$s2,0-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lwl $t8,1($i0) # Te3[s3]
+ lwl $t9,1($i1) # Te3[s0]
+ lwl $t10,1($i2) # Te3[s1]
+ lwl $t11,1($i3) # Te3[s2]
+ lwr $t8,0($i0) # Te3[s3]
+ lwr $t9,0($i1) # Te3[s0]
+ lwr $t10,0($i2) # Te3[s1]
+ lwr $t11,0($i3) # Te3[s2]
+
+ _xtr $i0,$s0,24-2
+ _xtr $i1,$s1,24-2
+ _xtr $i2,$s2,24-2
+ _xtr $i3,$s3,24-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ xor $t0,$t4
+ xor $t1,$t5
+ xor $t2,$t6
+ xor $t3,$t7
+ lw $t4,0($i0) # Te0[s0>>24]
+ lw $t5,0($i1) # Te0[s1>>24]
+ lw $t6,0($i2) # Te0[s2>>24]
+ lw $t7,0($i3) # Te0[s3>>24]
+
+ lw $s0,0($key0)
+ lw $s1,4($key0)
+ lw $s2,8($key0)
+ lw $s3,12($key0)
+
+ xor $t0,$t8
+ xor $t1,$t9
+ xor $t2,$t10
+ xor $t3,$t11
+
+ xor $t0,$t4
+ xor $t1,$t5
+ xor $t2,$t6
+ xor $t3,$t7
+
+ sub $cnt,1
+ $PTR_ADD $key0,16
+ xor $s0,$t0
+ xor $s1,$t1
+ xor $s2,$t2
+ xor $s3,$t3
+ .set noreorder
+ bnez $cnt,.Loop_enc
+ _xtr $i0,$s1,16-2
+
+ .set reorder
+ _xtr $i1,$s2,16-2
+ _xtr $i2,$s3,16-2
+ _xtr $i3,$s0,16-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $t0,2($i0) # Te4[s1>>16]
+ lbu $t1,2($i1) # Te4[s2>>16]
+ lbu $t2,2($i2) # Te4[s3>>16]
+ lbu $t3,2($i3) # Te4[s0>>16]
+
+ _xtr $i0,$s2,8-2
+ _xtr $i1,$s3,8-2
+ _xtr $i2,$s0,8-2
+ _xtr $i3,$s1,8-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $t4,2($i0) # Te4[s2>>8]
+ lbu $t5,2($i1) # Te4[s3>>8]
+ lbu $t6,2($i2) # Te4[s0>>8]
+ lbu $t7,2($i3) # Te4[s1>>8]
+
+ _xtr $i0,$s0,24-2
+ _xtr $i1,$s1,24-2
+ _xtr $i2,$s2,24-2
+ _xtr $i3,$s3,24-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $t8,2($i0) # Te4[s0>>24]
+ lbu $t9,2($i1) # Te4[s1>>24]
+ lbu $t10,2($i2) # Te4[s2>>24]
+ lbu $t11,2($i3) # Te4[s3>>24]
+
+ _xtr $i0,$s3,0-2
+ _xtr $i1,$s0,0-2
+ _xtr $i2,$s1,0-2
+ _xtr $i3,$s2,0-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+
+ _ins $t0,16
+ _ins $t1,16
+ _ins $t2,16
+ _ins $t3,16
+
+ _ins $t4,8
+ _ins $t5,8
+ _ins $t6,8
+ _ins $t7,8
+
+ xor $t0,$t4
+ xor $t1,$t5
+ xor $t2,$t6
+ xor $t3,$t7
+
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $t4,2($i0) # Te4[s3]
+ lbu $t5,2($i1) # Te4[s0]
+ lbu $t6,2($i2) # Te4[s1]
+ lbu $t7,2($i3) # Te4[s2]
+
+ _ins $t8,24
+ _ins $t9,24
+ _ins $t10,24
+ _ins $t11,24
+
+ lw $s0,0($key0)
+ lw $s1,4($key0)
+ lw $s2,8($key0)
+ lw $s3,12($key0)
+
+ xor $t0,$t8
+ xor $t1,$t9
+ xor $t2,$t10
+ xor $t3,$t11
+
+ _ins $t4,0
+ _ins $t5,0
+ _ins $t6,0
+ _ins $t7,0
+
+ xor $t0,$t4
+ xor $t1,$t5
+ xor $t2,$t6
+ xor $t3,$t7
+
+ xor $s0,$t0
+ xor $s1,$t1
+ xor $s2,$t2
+ xor $s3,$t3
+
+ jr $ra
+.end _mips_AES_encrypt
+
+.align 5
+.globl AES_encrypt
+.ent AES_encrypt
+AES_encrypt:
+ .frame $sp,$FRAMESIZE,$ra
+ .mask $SAVED_REGS_MASK,-$SZREG
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /o32/i); # o32 PIC-ification
+ .cpload $pf
+___
+$code.=<<___;
+ $PTR_SUB $sp,$FRAMESIZE
+ $REG_S $ra,$FRAMESIZE-1*$SZREG($sp)
+ $REG_S $fp,$FRAMESIZE-2*$SZREG($sp)
+ $REG_S $s11,$FRAMESIZE-3*$SZREG($sp)
+ $REG_S $s10,$FRAMESIZE-4*$SZREG($sp)
+ $REG_S $s9,$FRAMESIZE-5*$SZREG($sp)
+ $REG_S $s8,$FRAMESIZE-6*$SZREG($sp)
+ $REG_S $s7,$FRAMESIZE-7*$SZREG($sp)
+ $REG_S $s6,$FRAMESIZE-8*$SZREG($sp)
+ $REG_S $s5,$FRAMESIZE-9*$SZREG($sp)
+ $REG_S $s4,$FRAMESIZE-10*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue
+ $REG_S \$15,$FRAMESIZE-11*$SZREG($sp)
+ $REG_S \$14,$FRAMESIZE-12*$SZREG($sp)
+ $REG_S \$13,$FRAMESIZE-13*$SZREG($sp)
+ $REG_S \$12,$FRAMESIZE-14*$SZREG($sp)
+ $REG_S $gp,$FRAMESIZE-15*$SZREG($sp)
+___
+$code.=<<___ if ($flavour !~ /o32/i); # non-o32 PIC-ification
+ .cplocal $Tbl
+ .cpsetup $pf,$zero,AES_encrypt
+___
+$code.=<<___;
+ .set reorder
+ la $Tbl,AES_Te # PIC-ified 'load address'
+
+ lwl $s0,0+$MSB($inp)
+ lwl $s1,4+$MSB($inp)
+ lwl $s2,8+$MSB($inp)
+ lwl $s3,12+$MSB($inp)
+ lwr $s0,0+$LSB($inp)
+ lwr $s1,4+$LSB($inp)
+ lwr $s2,8+$LSB($inp)
+ lwr $s3,12+$LSB($inp)
+
+ bal _mips_AES_encrypt
+
+ swr $s0,0+$LSB($out)
+ swr $s1,4+$LSB($out)
+ swr $s2,8+$LSB($out)
+ swr $s3,12+$LSB($out)
+ swl $s0,0+$MSB($out)
+ swl $s1,4+$MSB($out)
+ swl $s2,8+$MSB($out)
+ swl $s3,12+$MSB($out)
+
+ .set noreorder
+ $REG_L $ra,$FRAMESIZE-1*$SZREG($sp)
+ $REG_L $fp,$FRAMESIZE-2*$SZREG($sp)
+ $REG_L $s11,$FRAMESIZE-3*$SZREG($sp)
+ $REG_L $s10,$FRAMESIZE-4*$SZREG($sp)
+ $REG_L $s9,$FRAMESIZE-5*$SZREG($sp)
+ $REG_L $s8,$FRAMESIZE-6*$SZREG($sp)
+ $REG_L $s7,$FRAMESIZE-7*$SZREG($sp)
+ $REG_L $s6,$FRAMESIZE-8*$SZREG($sp)
+ $REG_L $s5,$FRAMESIZE-9*$SZREG($sp)
+ $REG_L $s4,$FRAMESIZE-10*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L \$15,$FRAMESIZE-11*$SZREG($sp)
+ $REG_L \$14,$FRAMESIZE-12*$SZREG($sp)
+ $REG_L \$13,$FRAMESIZE-13*$SZREG($sp)
+ $REG_L \$12,$FRAMESIZE-14*$SZREG($sp)
+ $REG_L $gp,$FRAMESIZE-15*$SZREG($sp)
+___
+$code.=<<___;
+ jr $ra
+ $PTR_ADD $sp,$FRAMESIZE
+.end AES_encrypt
+___
+
+$code.=<<___;
+.align 5
+.ent _mips_AES_decrypt
+_mips_AES_decrypt:
+ .frame $sp,0,$ra
+ .set reorder
+ lw $t0,0($key)
+ lw $t1,4($key)
+ lw $t2,8($key)
+ lw $t3,12($key)
+ lw $cnt,240($key)
+ $PTR_ADD $key0,$key,16
+
+ xor $s0,$t0
+ xor $s1,$t1
+ xor $s2,$t2
+ xor $s3,$t3
+
+ sub $cnt,1
+ _xtr $i0,$s3,16-2
+.Loop_dec:
+ _xtr $i1,$s0,16-2
+ _xtr $i2,$s1,16-2
+ _xtr $i3,$s2,16-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lwl $t0,3($i0) # Td1[s3>>16]
+ lwl $t1,3($i1) # Td1[s0>>16]
+ lwl $t2,3($i2) # Td1[s1>>16]
+ lwl $t3,3($i3) # Td1[s2>>16]
+ lwr $t0,2($i0) # Td1[s3>>16]
+ lwr $t1,2($i1) # Td1[s0>>16]
+ lwr $t2,2($i2) # Td1[s1>>16]
+ lwr $t3,2($i3) # Td1[s2>>16]
+
+ _xtr $i0,$s2,8-2
+ _xtr $i1,$s3,8-2
+ _xtr $i2,$s0,8-2
+ _xtr $i3,$s1,8-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lwl $t4,2($i0) # Td2[s2>>8]
+ lwl $t5,2($i1) # Td2[s3>>8]
+ lwl $t6,2($i2) # Td2[s0>>8]
+ lwl $t7,2($i3) # Td2[s1>>8]
+ lwr $t4,1($i0) # Td2[s2>>8]
+ lwr $t5,1($i1) # Td2[s3>>8]
+ lwr $t6,1($i2) # Td2[s0>>8]
+ lwr $t7,1($i3) # Td2[s1>>8]
+
+ _xtr $i0,$s1,0-2
+ _xtr $i1,$s2,0-2
+ _xtr $i2,$s3,0-2
+ _xtr $i3,$s0,0-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lwl $t8,1($i0) # Td3[s1]
+ lwl $t9,1($i1) # Td3[s2]
+ lwl $t10,1($i2) # Td3[s3]
+ lwl $t11,1($i3) # Td3[s0]
+ lwr $t8,0($i0) # Td3[s1]
+ lwr $t9,0($i1) # Td3[s2]
+ lwr $t10,0($i2) # Td3[s3]
+ lwr $t11,0($i3) # Td3[s0]
+
+ _xtr $i0,$s0,24-2
+ _xtr $i1,$s1,24-2
+ _xtr $i2,$s2,24-2
+ _xtr $i3,$s3,24-2
+ and $i0,0x3fc
+ and $i1,0x3fc
+ and $i2,0x3fc
+ and $i3,0x3fc
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+
+ xor $t0,$t4
+ xor $t1,$t5
+ xor $t2,$t6
+ xor $t3,$t7
+
+
+ lw $t4,0($i0) # Td0[s0>>24]
+ lw $t5,0($i1) # Td0[s1>>24]
+ lw $t6,0($i2) # Td0[s2>>24]
+ lw $t7,0($i3) # Td0[s3>>24]
+
+ lw $s0,0($key0)
+ lw $s1,4($key0)
+ lw $s2,8($key0)
+ lw $s3,12($key0)
+
+ xor $t0,$t8
+ xor $t1,$t9
+ xor $t2,$t10
+ xor $t3,$t11
+
+ xor $t0,$t4
+ xor $t1,$t5
+ xor $t2,$t6
+ xor $t3,$t7
+
+ sub $cnt,1
+ $PTR_ADD $key0,16
+ xor $s0,$t0
+ xor $s1,$t1
+ xor $s2,$t2
+ xor $s3,$t3
+ .set noreorder
+ bnez $cnt,.Loop_dec
+ _xtr $i0,$s3,16-2
+
+ .set reorder
+ lw $t4,1024($Tbl) # prefetch Td4
+ lw $t5,1024+32($Tbl)
+ lw $t6,1024+64($Tbl)
+ lw $t7,1024+96($Tbl)
+ lw $t8,1024+128($Tbl)
+ lw $t9,1024+160($Tbl)
+ lw $t10,1024+192($Tbl)
+ lw $t11,1024+224($Tbl)
+
+ _xtr $i0,$s3,16
+ _xtr $i1,$s0,16
+ _xtr $i2,$s1,16
+ _xtr $i3,$s2,16
+ and $i0,0xff
+ and $i1,0xff
+ and $i2,0xff
+ and $i3,0xff
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $t0,1024($i0) # Td4[s3>>16]
+ lbu $t1,1024($i1) # Td4[s0>>16]
+ lbu $t2,1024($i2) # Td4[s1>>16]
+ lbu $t3,1024($i3) # Td4[s2>>16]
+
+ _xtr $i0,$s2,8
+ _xtr $i1,$s3,8
+ _xtr $i2,$s0,8
+ _xtr $i3,$s1,8
+ and $i0,0xff
+ and $i1,0xff
+ and $i2,0xff
+ and $i3,0xff
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $t4,1024($i0) # Td4[s2>>8]
+ lbu $t5,1024($i1) # Td4[s3>>8]
+ lbu $t6,1024($i2) # Td4[s0>>8]
+ lbu $t7,1024($i3) # Td4[s1>>8]
+
+ _xtr $i0,$s0,24
+ _xtr $i1,$s1,24
+ _xtr $i2,$s2,24
+ _xtr $i3,$s3,24
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $t8,1024($i0) # Td4[s0>>24]
+ lbu $t9,1024($i1) # Td4[s1>>24]
+ lbu $t10,1024($i2) # Td4[s2>>24]
+ lbu $t11,1024($i3) # Td4[s3>>24]
+
+ _xtr $i0,$s1,0
+ _xtr $i1,$s2,0
+ _xtr $i2,$s3,0
+ _xtr $i3,$s0,0
+
+ _ins $t0,16
+ _ins $t1,16
+ _ins $t2,16
+ _ins $t3,16
+
+ _ins $t4,8
+ _ins $t5,8
+ _ins $t6,8
+ _ins $t7,8
+
+ xor $t0,$t4
+ xor $t1,$t5
+ xor $t2,$t6
+ xor $t3,$t7
+
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $t4,1024($i0) # Td4[s1]
+ lbu $t5,1024($i1) # Td4[s2]
+ lbu $t6,1024($i2) # Td4[s3]
+ lbu $t7,1024($i3) # Td4[s0]
+
+ _ins $t8,24
+ _ins $t9,24
+ _ins $t10,24
+ _ins $t11,24
+
+ lw $s0,0($key0)
+ lw $s1,4($key0)
+ lw $s2,8($key0)
+ lw $s3,12($key0)
+
+ _ins $t4,0
+ _ins $t5,0
+ _ins $t6,0
+ _ins $t7,0
+
+
+ xor $t0,$t8
+ xor $t1,$t9
+ xor $t2,$t10
+ xor $t3,$t11
+
+ xor $t0,$t4
+ xor $t1,$t5
+ xor $t2,$t6
+ xor $t3,$t7
+
+ xor $s0,$t0
+ xor $s1,$t1
+ xor $s2,$t2
+ xor $s3,$t3
+
+ jr $ra
+.end _mips_AES_decrypt
+
+.align 5
+.globl AES_decrypt
+.ent AES_decrypt
+AES_decrypt:
+ .frame $sp,$FRAMESIZE,$ra
+ .mask $SAVED_REGS_MASK,-$SZREG
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /o32/i); # o32 PIC-ification
+ .cpload $pf
+___
+$code.=<<___;
+ $PTR_SUB $sp,$FRAMESIZE
+ $REG_S $ra,$FRAMESIZE-1*$SZREG($sp)
+ $REG_S $fp,$FRAMESIZE-2*$SZREG($sp)
+ $REG_S $s11,$FRAMESIZE-3*$SZREG($sp)
+ $REG_S $s10,$FRAMESIZE-4*$SZREG($sp)
+ $REG_S $s9,$FRAMESIZE-5*$SZREG($sp)
+ $REG_S $s8,$FRAMESIZE-6*$SZREG($sp)
+ $REG_S $s7,$FRAMESIZE-7*$SZREG($sp)
+ $REG_S $s6,$FRAMESIZE-8*$SZREG($sp)
+ $REG_S $s5,$FRAMESIZE-9*$SZREG($sp)
+ $REG_S $s4,$FRAMESIZE-10*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue
+ $REG_S \$15,$FRAMESIZE-11*$SZREG($sp)
+ $REG_S \$14,$FRAMESIZE-12*$SZREG($sp)
+ $REG_S \$13,$FRAMESIZE-13*$SZREG($sp)
+ $REG_S \$12,$FRAMESIZE-14*$SZREG($sp)
+ $REG_S $gp,$FRAMESIZE-15*$SZREG($sp)
+___
+$code.=<<___ if ($flavour !~ /o32/i); # non-o32 PIC-ification
+ .cplocal $Tbl
+ .cpsetup $pf,$zero,AES_decrypt
+___
+$code.=<<___;
+ .set reorder
+ la $Tbl,AES_Td # PIC-ified 'load address'
+
+ lwl $s0,0+$MSB($inp)
+ lwl $s1,4+$MSB($inp)
+ lwl $s2,8+$MSB($inp)
+ lwl $s3,12+$MSB($inp)
+ lwr $s0,0+$LSB($inp)
+ lwr $s1,4+$LSB($inp)
+ lwr $s2,8+$LSB($inp)
+ lwr $s3,12+$LSB($inp)
+
+ bal _mips_AES_decrypt
+
+ swr $s0,0+$LSB($out)
+ swr $s1,4+$LSB($out)
+ swr $s2,8+$LSB($out)
+ swr $s3,12+$LSB($out)
+ swl $s0,0+$MSB($out)
+ swl $s1,4+$MSB($out)
+ swl $s2,8+$MSB($out)
+ swl $s3,12+$MSB($out)
+
+ .set noreorder
+ $REG_L $ra,$FRAMESIZE-1*$SZREG($sp)
+ $REG_L $fp,$FRAMESIZE-2*$SZREG($sp)
+ $REG_L $s11,$FRAMESIZE-3*$SZREG($sp)
+ $REG_L $s10,$FRAMESIZE-4*$SZREG($sp)
+ $REG_L $s9,$FRAMESIZE-5*$SZREG($sp)
+ $REG_L $s8,$FRAMESIZE-6*$SZREG($sp)
+ $REG_L $s7,$FRAMESIZE-7*$SZREG($sp)
+ $REG_L $s6,$FRAMESIZE-8*$SZREG($sp)
+ $REG_L $s5,$FRAMESIZE-9*$SZREG($sp)
+ $REG_L $s4,$FRAMESIZE-10*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L \$15,$FRAMESIZE-11*$SZREG($sp)
+ $REG_L \$14,$FRAMESIZE-12*$SZREG($sp)
+ $REG_L \$13,$FRAMESIZE-13*$SZREG($sp)
+ $REG_L \$12,$FRAMESIZE-14*$SZREG($sp)
+ $REG_L $gp,$FRAMESIZE-15*$SZREG($sp)
+___
+$code.=<<___;
+ jr $ra
+ $PTR_ADD $sp,$FRAMESIZE
+.end AES_decrypt
+___
+}}}
+
+{{{
+my $FRAMESIZE=8*$SZREG;
+my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc000f008 : 0xc0000000;
+
+my ($inp,$bits,$key,$Tbl)=($a0,$a1,$a2,$a3);
+my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7)=($a4,$a5,$a6,$a7,$s0,$s1,$s2,$s3);
+my ($i0,$i1,$i2,$i3)=($at,$t0,$t1,$t2);
+my ($rcon,$cnt)=($gp,$fp);
+
+$code.=<<___;
+.align 5
+.ent _mips_AES_set_encrypt_key
+_mips_AES_set_encrypt_key:
+ .frame $sp,0,$ra
+ .set noreorder
+ beqz $inp,.Lekey_done
+ li $t0,-1
+ beqz $key,.Lekey_done
+ $PTR_ADD $rcon,$Tbl,1024+256
+
+ .set reorder
+ lwl $rk0,0+$MSB($inp) # load 128 bits
+ lwl $rk1,4+$MSB($inp)
+ lwl $rk2,8+$MSB($inp)
+ lwl $rk3,12+$MSB($inp)
+ li $at,128
+ lwr $rk0,0+$LSB($inp)
+ lwr $rk1,4+$LSB($inp)
+ lwr $rk2,8+$LSB($inp)
+ lwr $rk3,12+$LSB($inp)
+ .set noreorder
+ beq $bits,$at,.L128bits
+ li $cnt,10
+
+ .set reorder
+ lwl $rk4,16+$MSB($inp) # load 192 bits
+ lwl $rk5,20+$MSB($inp)
+ li $at,192
+ lwr $rk4,16+$LSB($inp)
+ lwr $rk5,20+$LSB($inp)
+ .set noreorder
+ beq $bits,$at,.L192bits
+ li $cnt,8
+
+ .set reorder
+ lwl $rk6,24+$MSB($inp) # load 256 bits
+ lwl $rk7,28+$MSB($inp)
+ li $at,256
+ lwr $rk6,24+$LSB($inp)
+ lwr $rk7,28+$LSB($inp)
+ .set noreorder
+ beq $bits,$at,.L256bits
+ li $cnt,7
+
+ b .Lekey_done
+ li $t0,-2
+
+.align 4
+.L128bits:
+ .set reorder
+ srl $i0,$rk3,16
+ srl $i1,$rk3,8
+ and $i0,0xff
+ and $i1,0xff
+ and $i2,$rk3,0xff
+ srl $i3,$rk3,24
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $i0,1024($i0)
+ lbu $i1,1024($i1)
+ lbu $i2,1024($i2)
+ lbu $i3,1024($i3)
+
+ sw $rk0,0($key)
+ sw $rk1,4($key)
+ sw $rk2,8($key)
+ sw $rk3,12($key)
+ sub $cnt,1
+ $PTR_ADD $key,16
+
+ _bias $i0,24
+ _bias $i1,16
+ _bias $i2,8
+ _bias $i3,0
+
+ xor $rk0,$i0
+ lw $i0,0($rcon)
+ xor $rk0,$i1
+ xor $rk0,$i2
+ xor $rk0,$i3
+ xor $rk0,$i0
+
+ xor $rk1,$rk0
+ xor $rk2,$rk1
+ xor $rk3,$rk2
+
+ .set noreorder
+ bnez $cnt,.L128bits
+ $PTR_ADD $rcon,4
+
+ sw $rk0,0($key)
+ sw $rk1,4($key)
+ sw $rk2,8($key)
+ li $cnt,10
+ sw $rk3,12($key)
+ li $t0,0
+ sw $cnt,80($key)
+ b .Lekey_done
+ $PTR_SUB $key,10*16
+
+.align 4
+.L192bits:
+ .set reorder
+ srl $i0,$rk5,16
+ srl $i1,$rk5,8
+ and $i0,0xff
+ and $i1,0xff
+ and $i2,$rk5,0xff
+ srl $i3,$rk5,24
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $i0,1024($i0)
+ lbu $i1,1024($i1)
+ lbu $i2,1024($i2)
+ lbu $i3,1024($i3)
+
+ sw $rk0,0($key)
+ sw $rk1,4($key)
+ sw $rk2,8($key)
+ sw $rk3,12($key)
+ sw $rk4,16($key)
+ sw $rk5,20($key)
+ sub $cnt,1
+ $PTR_ADD $key,24
+
+ _bias $i0,24
+ _bias $i1,16
+ _bias $i2,8
+ _bias $i3,0
+
+ xor $rk0,$i0
+ lw $i0,0($rcon)
+ xor $rk0,$i1
+ xor $rk0,$i2
+ xor $rk0,$i3
+ xor $rk0,$i0
+
+ xor $rk1,$rk0
+ xor $rk2,$rk1
+ xor $rk3,$rk2
+ xor $rk4,$rk3
+ xor $rk5,$rk4
+
+ .set noreorder
+ bnez $cnt,.L192bits
+ $PTR_ADD $rcon,4
+
+ sw $rk0,0($key)
+ sw $rk1,4($key)
+ sw $rk2,8($key)
+ li $cnt,12
+ sw $rk3,12($key)
+ li $t0,0
+ sw $cnt,48($key)
+ b .Lekey_done
+ $PTR_SUB $key,12*16
+
+.align 4
+.L256bits:
+ .set reorder
+ srl $i0,$rk7,16
+ srl $i1,$rk7,8
+ and $i0,0xff
+ and $i1,0xff
+ and $i2,$rk7,0xff
+ srl $i3,$rk7,24
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $i0,1024($i0)
+ lbu $i1,1024($i1)
+ lbu $i2,1024($i2)
+ lbu $i3,1024($i3)
+
+ sw $rk0,0($key)
+ sw $rk1,4($key)
+ sw $rk2,8($key)
+ sw $rk3,12($key)
+ sw $rk4,16($key)
+ sw $rk5,20($key)
+ sw $rk6,24($key)
+ sw $rk7,28($key)
+ sub $cnt,1
+
+ _bias $i0,24
+ _bias $i1,16
+ _bias $i2,8
+ _bias $i3,0
+
+ xor $rk0,$i0
+ lw $i0,0($rcon)
+ xor $rk0,$i1
+ xor $rk0,$i2
+ xor $rk0,$i3
+ xor $rk0,$i0
+
+ xor $rk1,$rk0
+ xor $rk2,$rk1
+ xor $rk3,$rk2
+ beqz $cnt,.L256bits_done
+
+ srl $i0,$rk3,24
+ srl $i1,$rk3,16
+ srl $i2,$rk3,8
+ and $i3,$rk3,0xff
+ and $i1,0xff
+ and $i2,0xff
+ $PTR_ADD $i0,$Tbl
+ $PTR_ADD $i1,$Tbl
+ $PTR_ADD $i2,$Tbl
+ $PTR_ADD $i3,$Tbl
+ lbu $i0,1024($i0)
+ lbu $i1,1024($i1)
+ lbu $i2,1024($i2)
+ lbu $i3,1024($i3)
+ sll $i0,24
+ sll $i1,16
+ sll $i2,8
+
+ xor $rk4,$i0
+ xor $rk4,$i1
+ xor $rk4,$i2
+ xor $rk4,$i3
+
+ xor $rk5,$rk4
+ xor $rk6,$rk5
+ xor $rk7,$rk6
+
+ $PTR_ADD $key,32
+ .set noreorder
+ b .L256bits
+ $PTR_ADD $rcon,4
+
+.L256bits_done:
+ sw $rk0,32($key)
+ sw $rk1,36($key)
+ sw $rk2,40($key)
+ li $cnt,14
+ sw $rk3,44($key)
+ li $t0,0
+ sw $cnt,48($key)
+ $PTR_SUB $key,12*16
+
+.Lekey_done:
+ jr $ra
+ nop
+.end _mips_AES_set_encrypt_key
+
+.globl private_AES_set_encrypt_key
+.ent private_AES_set_encrypt_key
+private_AES_set_encrypt_key:
+ .frame $sp,$FRAMESIZE,$ra
+ .mask $SAVED_REGS_MASK,-$SZREG
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /o32/i); # o32 PIC-ification
+ .cpload $pf
+___
+$code.=<<___;
+ $PTR_SUB $sp,$FRAMESIZE
+ $REG_S $ra,$FRAMESIZE-1*$SZREG($sp)
+ $REG_S $fp,$FRAMESIZE-2*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue
+ $REG_S $s3,$FRAMESIZE-3*$SZREG($sp)
+ $REG_S $s2,$FRAMESIZE-4*$SZREG($sp)
+ $REG_S $s1,$FRAMESIZE-5*$SZREG($sp)
+ $REG_S $s0,$FRAMESIZE-6*$SZREG($sp)
+ $REG_S $gp,$FRAMESIZE-7*$SZREG($sp)
+___
+$code.=<<___ if ($flavour !~ /o32/i); # non-o32 PIC-ification
+ .cplocal $Tbl
+ .cpsetup $pf,$zero,private_AES_set_encrypt_key
+___
+$code.=<<___;
+ .set reorder
+ la $Tbl,AES_Te # PIC-ified 'load address'
+
+ bal _mips_AES_set_encrypt_key
+
+ .set noreorder
+ move $a0,$t0
+ $REG_L $ra,$FRAMESIZE-1*$SZREG($sp)
+ $REG_L $fp,$FRAMESIZE-2*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $s3,$FRAMESIZE-11*$SZREG($sp)
+ $REG_L $s2,$FRAMESIZE-12*$SZREG($sp)
+ $REG_L $s1,$FRAMESIZE-13*$SZREG($sp)
+ $REG_L $s0,$FRAMESIZE-14*$SZREG($sp)
+ $REG_L $gp,$FRAMESIZE-15*$SZREG($sp)
+___
+$code.=<<___;
+ jr $ra
+ $PTR_ADD $sp,$FRAMESIZE
+.end private_AES_set_encrypt_key
+___
+
+my ($head,$tail)=($inp,$bits);
+my ($tp1,$tp2,$tp4,$tp8,$tp9,$tpb,$tpd,$tpe)=($a4,$a5,$a6,$a7,$s0,$s1,$s2,$s3);
+my ($m,$x80808080,$x7f7f7f7f,$x1b1b1b1b)=($at,$t0,$t1,$t2);
+$code.=<<___;
+.align 5
+.globl private_AES_set_decrypt_key
+.ent private_AES_set_decrypt_key
+private_AES_set_decrypt_key:
+ .frame $sp,$FRAMESIZE,$ra
+ .mask $SAVED_REGS_MASK,-$SZREG
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /o32/i); # o32 PIC-ification
+ .cpload $pf
+___
+$code.=<<___;
+ $PTR_SUB $sp,$FRAMESIZE
+ $REG_S $ra,$FRAMESIZE-1*$SZREG($sp)
+ $REG_S $fp,$FRAMESIZE-2*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue
+ $REG_S $s3,$FRAMESIZE-3*$SZREG($sp)
+ $REG_S $s2,$FRAMESIZE-4*$SZREG($sp)
+ $REG_S $s1,$FRAMESIZE-5*$SZREG($sp)
+ $REG_S $s0,$FRAMESIZE-6*$SZREG($sp)
+ $REG_S $gp,$FRAMESIZE-7*$SZREG($sp)
+___
+$code.=<<___ if ($flavour !~ /o32/i); # non-o32 PIC-ification
+ .cplocal $Tbl
+ .cpsetup $pf,$zero,private_AES_set_decrypt_key
+___
+$code.=<<___;
+ .set reorder
+ la $Tbl,AES_Te # PIC-ified 'load address'
+
+ bal _mips_AES_set_encrypt_key
+
+ bltz $t0,.Ldkey_done
+
+ sll $at,$cnt,4
+ $PTR_ADD $head,$key,0
+ $PTR_ADD $tail,$key,$at
+.align 4
+.Lswap:
+ lw $rk0,0($head)
+ lw $rk1,4($head)
+ lw $rk2,8($head)
+ lw $rk3,12($head)
+ lw $rk4,0($tail)
+ lw $rk5,4($tail)
+ lw $rk6,8($tail)
+ lw $rk7,12($tail)
+ sw $rk0,0($tail)
+ sw $rk1,4($tail)
+ sw $rk2,8($tail)
+ sw $rk3,12($tail)
+ $PTR_ADD $head,16
+ $PTR_SUB $tail,16
+ sw $rk4,-16($head)
+ sw $rk5,-12($head)
+ sw $rk6,-8($head)
+ sw $rk7,-4($head)
+ bne $head,$tail,.Lswap
+
+ lw $tp1,16($key) # modulo-scheduled
+ lui $x80808080,0x8080
+ sub $cnt,1
+ or $x80808080,0x8080
+ sll $cnt,2
+ $PTR_ADD $key,16
+ lui $x1b1b1b1b,0x1b1b
+ nor $x7f7f7f7f,$zero,$x80808080
+ or $x1b1b1b1b,0x1b1b
+.align 4
+.Lmix:
+ and $m,$tp1,$x80808080
+ and $tp2,$tp1,$x7f7f7f7f
+ srl $tp4,$m,7
+ addu $tp2,$tp2 # tp2<<1
+ subu $m,$tp4
+ and $m,$x1b1b1b1b
+ xor $tp2,$m
+
+ and $m,$tp2,$x80808080
+ and $tp4,$tp2,$x7f7f7f7f
+ srl $tp8,$m,7
+ addu $tp4,$tp4 # tp4<<1
+ subu $m,$tp8
+ and $m,$x1b1b1b1b
+ xor $tp4,$m
+
+ and $m,$tp4,$x80808080
+ and $tp8,$tp4,$x7f7f7f7f
+ srl $tp9,$m,7
+ addu $tp8,$tp8 # tp8<<1
+ subu $m,$tp9
+ and $m,$x1b1b1b1b
+ xor $tp8,$m
+
+ xor $tp9,$tp8,$tp1
+ xor $tpe,$tp8,$tp4
+ xor $tpb,$tp9,$tp2
+ xor $tpd,$tp9,$tp4
+
+ _ror $tp1,$tpd,16
+ xor $tpe,$tp2
+ _ror $tp2,$tpd,-16
+ xor $tpe,$tp1
+ _ror $tp1,$tp9,8
+ xor $tpe,$tp2
+ _ror $tp2,$tp9,-24
+ xor $tpe,$tp1
+ _ror $tp1,$tpb,24
+ xor $tpe,$tp2
+ _ror $tp2,$tpb,-8
+ xor $tpe,$tp1
+ lw $tp1,4($key) # modulo-scheduled
+ xor $tpe,$tp2
+ sub $cnt,1
+ sw $tpe,0($key)
+ $PTR_ADD $key,4
+ bnez $cnt,.Lmix
+
+ li $t0,0
+.Ldkey_done:
+ .set noreorder
+ move $a0,$t0
+ $REG_L $ra,$FRAMESIZE-1*$SZREG($sp)
+ $REG_L $fp,$FRAMESIZE-2*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $s3,$FRAMESIZE-11*$SZREG($sp)
+ $REG_L $s2,$FRAMESIZE-12*$SZREG($sp)
+ $REG_L $s1,$FRAMESIZE-13*$SZREG($sp)
+ $REG_L $s0,$FRAMESIZE-14*$SZREG($sp)
+ $REG_L $gp,$FRAMESIZE-15*$SZREG($sp)
+___
+$code.=<<___;
+ jr $ra
+ $PTR_ADD $sp,$FRAMESIZE
+.end private_AES_set_decrypt_key
+___
+}}}
+
+######################################################################
+# Tables are kept in endian-neutral manner
+$code.=<<___;
+.rdata
+.align 6
+AES_Te:
+.byte 0xc6,0x63,0x63,0xa5, 0xf8,0x7c,0x7c,0x84 # Te0
+.byte 0xee,0x77,0x77,0x99, 0xf6,0x7b,0x7b,0x8d
+.byte 0xff,0xf2,0xf2,0x0d, 0xd6,0x6b,0x6b,0xbd
+.byte 0xde,0x6f,0x6f,0xb1, 0x91,0xc5,0xc5,0x54
+.byte 0x60,0x30,0x30,0x50, 0x02,0x01,0x01,0x03
+.byte 0xce,0x67,0x67,0xa9, 0x56,0x2b,0x2b,0x7d
+.byte 0xe7,0xfe,0xfe,0x19, 0xb5,0xd7,0xd7,0x62
+.byte 0x4d,0xab,0xab,0xe6, 0xec,0x76,0x76,0x9a
+.byte 0x8f,0xca,0xca,0x45, 0x1f,0x82,0x82,0x9d
+.byte 0x89,0xc9,0xc9,0x40, 0xfa,0x7d,0x7d,0x87
+.byte 0xef,0xfa,0xfa,0x15, 0xb2,0x59,0x59,0xeb
+.byte 0x8e,0x47,0x47,0xc9, 0xfb,0xf0,0xf0,0x0b
+.byte 0x41,0xad,0xad,0xec, 0xb3,0xd4,0xd4,0x67
+.byte 0x5f,0xa2,0xa2,0xfd, 0x45,0xaf,0xaf,0xea
+.byte 0x23,0x9c,0x9c,0xbf, 0x53,0xa4,0xa4,0xf7
+.byte 0xe4,0x72,0x72,0x96, 0x9b,0xc0,0xc0,0x5b
+.byte 0x75,0xb7,0xb7,0xc2, 0xe1,0xfd,0xfd,0x1c
+.byte 0x3d,0x93,0x93,0xae, 0x4c,0x26,0x26,0x6a
+.byte 0x6c,0x36,0x36,0x5a, 0x7e,0x3f,0x3f,0x41
+.byte 0xf5,0xf7,0xf7,0x02, 0x83,0xcc,0xcc,0x4f
+.byte 0x68,0x34,0x34,0x5c, 0x51,0xa5,0xa5,0xf4
+.byte 0xd1,0xe5,0xe5,0x34, 0xf9,0xf1,0xf1,0x08
+.byte 0xe2,0x71,0x71,0x93, 0xab,0xd8,0xd8,0x73
+.byte 0x62,0x31,0x31,0x53, 0x2a,0x15,0x15,0x3f
+.byte 0x08,0x04,0x04,0x0c, 0x95,0xc7,0xc7,0x52
+.byte 0x46,0x23,0x23,0x65, 0x9d,0xc3,0xc3,0x5e
+.byte 0x30,0x18,0x18,0x28, 0x37,0x96,0x96,0xa1
+.byte 0x0a,0x05,0x05,0x0f, 0x2f,0x9a,0x9a,0xb5
+.byte 0x0e,0x07,0x07,0x09, 0x24,0x12,0x12,0x36
+.byte 0x1b,0x80,0x80,0x9b, 0xdf,0xe2,0xe2,0x3d
+.byte 0xcd,0xeb,0xeb,0x26, 0x4e,0x27,0x27,0x69
+.byte 0x7f,0xb2,0xb2,0xcd, 0xea,0x75,0x75,0x9f
+.byte 0x12,0x09,0x09,0x1b, 0x1d,0x83,0x83,0x9e
+.byte 0x58,0x2c,0x2c,0x74, 0x34,0x1a,0x1a,0x2e
+.byte 0x36,0x1b,0x1b,0x2d, 0xdc,0x6e,0x6e,0xb2
+.byte 0xb4,0x5a,0x5a,0xee, 0x5b,0xa0,0xa0,0xfb
+.byte 0xa4,0x52,0x52,0xf6, 0x76,0x3b,0x3b,0x4d
+.byte 0xb7,0xd6,0xd6,0x61, 0x7d,0xb3,0xb3,0xce
+.byte 0x52,0x29,0x29,0x7b, 0xdd,0xe3,0xe3,0x3e
+.byte 0x5e,0x2f,0x2f,0x71, 0x13,0x84,0x84,0x97
+.byte 0xa6,0x53,0x53,0xf5, 0xb9,0xd1,0xd1,0x68
+.byte 0x00,0x00,0x00,0x00, 0xc1,0xed,0xed,0x2c
+.byte 0x40,0x20,0x20,0x60, 0xe3,0xfc,0xfc,0x1f
+.byte 0x79,0xb1,0xb1,0xc8, 0xb6,0x5b,0x5b,0xed
+.byte 0xd4,0x6a,0x6a,0xbe, 0x8d,0xcb,0xcb,0x46
+.byte 0x67,0xbe,0xbe,0xd9, 0x72,0x39,0x39,0x4b
+.byte 0x94,0x4a,0x4a,0xde, 0x98,0x4c,0x4c,0xd4
+.byte 0xb0,0x58,0x58,0xe8, 0x85,0xcf,0xcf,0x4a
+.byte 0xbb,0xd0,0xd0,0x6b, 0xc5,0xef,0xef,0x2a
+.byte 0x4f,0xaa,0xaa,0xe5, 0xed,0xfb,0xfb,0x16
+.byte 0x86,0x43,0x43,0xc5, 0x9a,0x4d,0x4d,0xd7
+.byte 0x66,0x33,0x33,0x55, 0x11,0x85,0x85,0x94
+.byte 0x8a,0x45,0x45,0xcf, 0xe9,0xf9,0xf9,0x10
+.byte 0x04,0x02,0x02,0x06, 0xfe,0x7f,0x7f,0x81
+.byte 0xa0,0x50,0x50,0xf0, 0x78,0x3c,0x3c,0x44
+.byte 0x25,0x9f,0x9f,0xba, 0x4b,0xa8,0xa8,0xe3
+.byte 0xa2,0x51,0x51,0xf3, 0x5d,0xa3,0xa3,0xfe
+.byte 0x80,0x40,0x40,0xc0, 0x05,0x8f,0x8f,0x8a
+.byte 0x3f,0x92,0x92,0xad, 0x21,0x9d,0x9d,0xbc
+.byte 0x70,0x38,0x38,0x48, 0xf1,0xf5,0xf5,0x04
+.byte 0x63,0xbc,0xbc,0xdf, 0x77,0xb6,0xb6,0xc1
+.byte 0xaf,0xda,0xda,0x75, 0x42,0x21,0x21,0x63
+.byte 0x20,0x10,0x10,0x30, 0xe5,0xff,0xff,0x1a
+.byte 0xfd,0xf3,0xf3,0x0e, 0xbf,0xd2,0xd2,0x6d
+.byte 0x81,0xcd,0xcd,0x4c, 0x18,0x0c,0x0c,0x14
+.byte 0x26,0x13,0x13,0x35, 0xc3,0xec,0xec,0x2f
+.byte 0xbe,0x5f,0x5f,0xe1, 0x35,0x97,0x97,0xa2
+.byte 0x88,0x44,0x44,0xcc, 0x2e,0x17,0x17,0x39
+.byte 0x93,0xc4,0xc4,0x57, 0x55,0xa7,0xa7,0xf2
+.byte 0xfc,0x7e,0x7e,0x82, 0x7a,0x3d,0x3d,0x47
+.byte 0xc8,0x64,0x64,0xac, 0xba,0x5d,0x5d,0xe7
+.byte 0x32,0x19,0x19,0x2b, 0xe6,0x73,0x73,0x95
+.byte 0xc0,0x60,0x60,0xa0, 0x19,0x81,0x81,0x98
+.byte 0x9e,0x4f,0x4f,0xd1, 0xa3,0xdc,0xdc,0x7f
+.byte 0x44,0x22,0x22,0x66, 0x54,0x2a,0x2a,0x7e
+.byte 0x3b,0x90,0x90,0xab, 0x0b,0x88,0x88,0x83
+.byte 0x8c,0x46,0x46,0xca, 0xc7,0xee,0xee,0x29
+.byte 0x6b,0xb8,0xb8,0xd3, 0x28,0x14,0x14,0x3c
+.byte 0xa7,0xde,0xde,0x79, 0xbc,0x5e,0x5e,0xe2
+.byte 0x16,0x0b,0x0b,0x1d, 0xad,0xdb,0xdb,0x76
+.byte 0xdb,0xe0,0xe0,0x3b, 0x64,0x32,0x32,0x56
+.byte 0x74,0x3a,0x3a,0x4e, 0x14,0x0a,0x0a,0x1e
+.byte 0x92,0x49,0x49,0xdb, 0x0c,0x06,0x06,0x0a
+.byte 0x48,0x24,0x24,0x6c, 0xb8,0x5c,0x5c,0xe4
+.byte 0x9f,0xc2,0xc2,0x5d, 0xbd,0xd3,0xd3,0x6e
+.byte 0x43,0xac,0xac,0xef, 0xc4,0x62,0x62,0xa6
+.byte 0x39,0x91,0x91,0xa8, 0x31,0x95,0x95,0xa4
+.byte 0xd3,0xe4,0xe4,0x37, 0xf2,0x79,0x79,0x8b
+.byte 0xd5,0xe7,0xe7,0x32, 0x8b,0xc8,0xc8,0x43
+.byte 0x6e,0x37,0x37,0x59, 0xda,0x6d,0x6d,0xb7
+.byte 0x01,0x8d,0x8d,0x8c, 0xb1,0xd5,0xd5,0x64
+.byte 0x9c,0x4e,0x4e,0xd2, 0x49,0xa9,0xa9,0xe0
+.byte 0xd8,0x6c,0x6c,0xb4, 0xac,0x56,0x56,0xfa
+.byte 0xf3,0xf4,0xf4,0x07, 0xcf,0xea,0xea,0x25
+.byte 0xca,0x65,0x65,0xaf, 0xf4,0x7a,0x7a,0x8e
+.byte 0x47,0xae,0xae,0xe9, 0x10,0x08,0x08,0x18
+.byte 0x6f,0xba,0xba,0xd5, 0xf0,0x78,0x78,0x88
+.byte 0x4a,0x25,0x25,0x6f, 0x5c,0x2e,0x2e,0x72
+.byte 0x38,0x1c,0x1c,0x24, 0x57,0xa6,0xa6,0xf1
+.byte 0x73,0xb4,0xb4,0xc7, 0x97,0xc6,0xc6,0x51
+.byte 0xcb,0xe8,0xe8,0x23, 0xa1,0xdd,0xdd,0x7c
+.byte 0xe8,0x74,0x74,0x9c, 0x3e,0x1f,0x1f,0x21
+.byte 0x96,0x4b,0x4b,0xdd, 0x61,0xbd,0xbd,0xdc
+.byte 0x0d,0x8b,0x8b,0x86, 0x0f,0x8a,0x8a,0x85
+.byte 0xe0,0x70,0x70,0x90, 0x7c,0x3e,0x3e,0x42
+.byte 0x71,0xb5,0xb5,0xc4, 0xcc,0x66,0x66,0xaa
+.byte 0x90,0x48,0x48,0xd8, 0x06,0x03,0x03,0x05
+.byte 0xf7,0xf6,0xf6,0x01, 0x1c,0x0e,0x0e,0x12
+.byte 0xc2,0x61,0x61,0xa3, 0x6a,0x35,0x35,0x5f
+.byte 0xae,0x57,0x57,0xf9, 0x69,0xb9,0xb9,0xd0
+.byte 0x17,0x86,0x86,0x91, 0x99,0xc1,0xc1,0x58
+.byte 0x3a,0x1d,0x1d,0x27, 0x27,0x9e,0x9e,0xb9
+.byte 0xd9,0xe1,0xe1,0x38, 0xeb,0xf8,0xf8,0x13
+.byte 0x2b,0x98,0x98,0xb3, 0x22,0x11,0x11,0x33
+.byte 0xd2,0x69,0x69,0xbb, 0xa9,0xd9,0xd9,0x70
+.byte 0x07,0x8e,0x8e,0x89, 0x33,0x94,0x94,0xa7
+.byte 0x2d,0x9b,0x9b,0xb6, 0x3c,0x1e,0x1e,0x22
+.byte 0x15,0x87,0x87,0x92, 0xc9,0xe9,0xe9,0x20
+.byte 0x87,0xce,0xce,0x49, 0xaa,0x55,0x55,0xff
+.byte 0x50,0x28,0x28,0x78, 0xa5,0xdf,0xdf,0x7a
+.byte 0x03,0x8c,0x8c,0x8f, 0x59,0xa1,0xa1,0xf8
+.byte 0x09,0x89,0x89,0x80, 0x1a,0x0d,0x0d,0x17
+.byte 0x65,0xbf,0xbf,0xda, 0xd7,0xe6,0xe6,0x31
+.byte 0x84,0x42,0x42,0xc6, 0xd0,0x68,0x68,0xb8
+.byte 0x82,0x41,0x41,0xc3, 0x29,0x99,0x99,0xb0
+.byte 0x5a,0x2d,0x2d,0x77, 0x1e,0x0f,0x0f,0x11
+.byte 0x7b,0xb0,0xb0,0xcb, 0xa8,0x54,0x54,0xfc
+.byte 0x6d,0xbb,0xbb,0xd6, 0x2c,0x16,0x16,0x3a
+
+.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 # Te4
+.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+
+.byte 0x01,0x00,0x00,0x00, 0x02,0x00,0x00,0x00 # rcon
+.byte 0x04,0x00,0x00,0x00, 0x08,0x00,0x00,0x00
+.byte 0x10,0x00,0x00,0x00, 0x20,0x00,0x00,0x00
+.byte 0x40,0x00,0x00,0x00, 0x80,0x00,0x00,0x00
+.byte 0x1B,0x00,0x00,0x00, 0x36,0x00,0x00,0x00
+
+.align 6
+AES_Td:
+.byte 0x51,0xf4,0xa7,0x50, 0x7e,0x41,0x65,0x53 # Td0
+.byte 0x1a,0x17,0xa4,0xc3, 0x3a,0x27,0x5e,0x96
+.byte 0x3b,0xab,0x6b,0xcb, 0x1f,0x9d,0x45,0xf1
+.byte 0xac,0xfa,0x58,0xab, 0x4b,0xe3,0x03,0x93
+.byte 0x20,0x30,0xfa,0x55, 0xad,0x76,0x6d,0xf6
+.byte 0x88,0xcc,0x76,0x91, 0xf5,0x02,0x4c,0x25
+.byte 0x4f,0xe5,0xd7,0xfc, 0xc5,0x2a,0xcb,0xd7
+.byte 0x26,0x35,0x44,0x80, 0xb5,0x62,0xa3,0x8f
+.byte 0xde,0xb1,0x5a,0x49, 0x25,0xba,0x1b,0x67
+.byte 0x45,0xea,0x0e,0x98, 0x5d,0xfe,0xc0,0xe1
+.byte 0xc3,0x2f,0x75,0x02, 0x81,0x4c,0xf0,0x12
+.byte 0x8d,0x46,0x97,0xa3, 0x6b,0xd3,0xf9,0xc6
+.byte 0x03,0x8f,0x5f,0xe7, 0x15,0x92,0x9c,0x95
+.byte 0xbf,0x6d,0x7a,0xeb, 0x95,0x52,0x59,0xda
+.byte 0xd4,0xbe,0x83,0x2d, 0x58,0x74,0x21,0xd3
+.byte 0x49,0xe0,0x69,0x29, 0x8e,0xc9,0xc8,0x44
+.byte 0x75,0xc2,0x89,0x6a, 0xf4,0x8e,0x79,0x78
+.byte 0x99,0x58,0x3e,0x6b, 0x27,0xb9,0x71,0xdd
+.byte 0xbe,0xe1,0x4f,0xb6, 0xf0,0x88,0xad,0x17
+.byte 0xc9,0x20,0xac,0x66, 0x7d,0xce,0x3a,0xb4
+.byte 0x63,0xdf,0x4a,0x18, 0xe5,0x1a,0x31,0x82
+.byte 0x97,0x51,0x33,0x60, 0x62,0x53,0x7f,0x45
+.byte 0xb1,0x64,0x77,0xe0, 0xbb,0x6b,0xae,0x84
+.byte 0xfe,0x81,0xa0,0x1c, 0xf9,0x08,0x2b,0x94
+.byte 0x70,0x48,0x68,0x58, 0x8f,0x45,0xfd,0x19
+.byte 0x94,0xde,0x6c,0x87, 0x52,0x7b,0xf8,0xb7
+.byte 0xab,0x73,0xd3,0x23, 0x72,0x4b,0x02,0xe2
+.byte 0xe3,0x1f,0x8f,0x57, 0x66,0x55,0xab,0x2a
+.byte 0xb2,0xeb,0x28,0x07, 0x2f,0xb5,0xc2,0x03
+.byte 0x86,0xc5,0x7b,0x9a, 0xd3,0x37,0x08,0xa5
+.byte 0x30,0x28,0x87,0xf2, 0x23,0xbf,0xa5,0xb2
+.byte 0x02,0x03,0x6a,0xba, 0xed,0x16,0x82,0x5c
+.byte 0x8a,0xcf,0x1c,0x2b, 0xa7,0x79,0xb4,0x92
+.byte 0xf3,0x07,0xf2,0xf0, 0x4e,0x69,0xe2,0xa1
+.byte 0x65,0xda,0xf4,0xcd, 0x06,0x05,0xbe,0xd5
+.byte 0xd1,0x34,0x62,0x1f, 0xc4,0xa6,0xfe,0x8a
+.byte 0x34,0x2e,0x53,0x9d, 0xa2,0xf3,0x55,0xa0
+.byte 0x05,0x8a,0xe1,0x32, 0xa4,0xf6,0xeb,0x75
+.byte 0x0b,0x83,0xec,0x39, 0x40,0x60,0xef,0xaa
+.byte 0x5e,0x71,0x9f,0x06, 0xbd,0x6e,0x10,0x51
+.byte 0x3e,0x21,0x8a,0xf9, 0x96,0xdd,0x06,0x3d
+.byte 0xdd,0x3e,0x05,0xae, 0x4d,0xe6,0xbd,0x46
+.byte 0x91,0x54,0x8d,0xb5, 0x71,0xc4,0x5d,0x05
+.byte 0x04,0x06,0xd4,0x6f, 0x60,0x50,0x15,0xff
+.byte 0x19,0x98,0xfb,0x24, 0xd6,0xbd,0xe9,0x97
+.byte 0x89,0x40,0x43,0xcc, 0x67,0xd9,0x9e,0x77
+.byte 0xb0,0xe8,0x42,0xbd, 0x07,0x89,0x8b,0x88
+.byte 0xe7,0x19,0x5b,0x38, 0x79,0xc8,0xee,0xdb
+.byte 0xa1,0x7c,0x0a,0x47, 0x7c,0x42,0x0f,0xe9
+.byte 0xf8,0x84,0x1e,0xc9, 0x00,0x00,0x00,0x00
+.byte 0x09,0x80,0x86,0x83, 0x32,0x2b,0xed,0x48
+.byte 0x1e,0x11,0x70,0xac, 0x6c,0x5a,0x72,0x4e
+.byte 0xfd,0x0e,0xff,0xfb, 0x0f,0x85,0x38,0x56
+.byte 0x3d,0xae,0xd5,0x1e, 0x36,0x2d,0x39,0x27
+.byte 0x0a,0x0f,0xd9,0x64, 0x68,0x5c,0xa6,0x21
+.byte 0x9b,0x5b,0x54,0xd1, 0x24,0x36,0x2e,0x3a
+.byte 0x0c,0x0a,0x67,0xb1, 0x93,0x57,0xe7,0x0f
+.byte 0xb4,0xee,0x96,0xd2, 0x1b,0x9b,0x91,0x9e
+.byte 0x80,0xc0,0xc5,0x4f, 0x61,0xdc,0x20,0xa2
+.byte 0x5a,0x77,0x4b,0x69, 0x1c,0x12,0x1a,0x16
+.byte 0xe2,0x93,0xba,0x0a, 0xc0,0xa0,0x2a,0xe5
+.byte 0x3c,0x22,0xe0,0x43, 0x12,0x1b,0x17,0x1d
+.byte 0x0e,0x09,0x0d,0x0b, 0xf2,0x8b,0xc7,0xad
+.byte 0x2d,0xb6,0xa8,0xb9, 0x14,0x1e,0xa9,0xc8
+.byte 0x57,0xf1,0x19,0x85, 0xaf,0x75,0x07,0x4c
+.byte 0xee,0x99,0xdd,0xbb, 0xa3,0x7f,0x60,0xfd
+.byte 0xf7,0x01,0x26,0x9f, 0x5c,0x72,0xf5,0xbc
+.byte 0x44,0x66,0x3b,0xc5, 0x5b,0xfb,0x7e,0x34
+.byte 0x8b,0x43,0x29,0x76, 0xcb,0x23,0xc6,0xdc
+.byte 0xb6,0xed,0xfc,0x68, 0xb8,0xe4,0xf1,0x63
+.byte 0xd7,0x31,0xdc,0xca, 0x42,0x63,0x85,0x10
+.byte 0x13,0x97,0x22,0x40, 0x84,0xc6,0x11,0x20
+.byte 0x85,0x4a,0x24,0x7d, 0xd2,0xbb,0x3d,0xf8
+.byte 0xae,0xf9,0x32,0x11, 0xc7,0x29,0xa1,0x6d
+.byte 0x1d,0x9e,0x2f,0x4b, 0xdc,0xb2,0x30,0xf3
+.byte 0x0d,0x86,0x52,0xec, 0x77,0xc1,0xe3,0xd0
+.byte 0x2b,0xb3,0x16,0x6c, 0xa9,0x70,0xb9,0x99
+.byte 0x11,0x94,0x48,0xfa, 0x47,0xe9,0x64,0x22
+.byte 0xa8,0xfc,0x8c,0xc4, 0xa0,0xf0,0x3f,0x1a
+.byte 0x56,0x7d,0x2c,0xd8, 0x22,0x33,0x90,0xef
+.byte 0x87,0x49,0x4e,0xc7, 0xd9,0x38,0xd1,0xc1
+.byte 0x8c,0xca,0xa2,0xfe, 0x98,0xd4,0x0b,0x36
+.byte 0xa6,0xf5,0x81,0xcf, 0xa5,0x7a,0xde,0x28
+.byte 0xda,0xb7,0x8e,0x26, 0x3f,0xad,0xbf,0xa4
+.byte 0x2c,0x3a,0x9d,0xe4, 0x50,0x78,0x92,0x0d
+.byte 0x6a,0x5f,0xcc,0x9b, 0x54,0x7e,0x46,0x62
+.byte 0xf6,0x8d,0x13,0xc2, 0x90,0xd8,0xb8,0xe8
+.byte 0x2e,0x39,0xf7,0x5e, 0x82,0xc3,0xaf,0xf5
+.byte 0x9f,0x5d,0x80,0xbe, 0x69,0xd0,0x93,0x7c
+.byte 0x6f,0xd5,0x2d,0xa9, 0xcf,0x25,0x12,0xb3
+.byte 0xc8,0xac,0x99,0x3b, 0x10,0x18,0x7d,0xa7
+.byte 0xe8,0x9c,0x63,0x6e, 0xdb,0x3b,0xbb,0x7b
+.byte 0xcd,0x26,0x78,0x09, 0x6e,0x59,0x18,0xf4
+.byte 0xec,0x9a,0xb7,0x01, 0x83,0x4f,0x9a,0xa8
+.byte 0xe6,0x95,0x6e,0x65, 0xaa,0xff,0xe6,0x7e
+.byte 0x21,0xbc,0xcf,0x08, 0xef,0x15,0xe8,0xe6
+.byte 0xba,0xe7,0x9b,0xd9, 0x4a,0x6f,0x36,0xce
+.byte 0xea,0x9f,0x09,0xd4, 0x29,0xb0,0x7c,0xd6
+.byte 0x31,0xa4,0xb2,0xaf, 0x2a,0x3f,0x23,0x31
+.byte 0xc6,0xa5,0x94,0x30, 0x35,0xa2,0x66,0xc0
+.byte 0x74,0x4e,0xbc,0x37, 0xfc,0x82,0xca,0xa6
+.byte 0xe0,0x90,0xd0,0xb0, 0x33,0xa7,0xd8,0x15
+.byte 0xf1,0x04,0x98,0x4a, 0x41,0xec,0xda,0xf7
+.byte 0x7f,0xcd,0x50,0x0e, 0x17,0x91,0xf6,0x2f
+.byte 0x76,0x4d,0xd6,0x8d, 0x43,0xef,0xb0,0x4d
+.byte 0xcc,0xaa,0x4d,0x54, 0xe4,0x96,0x04,0xdf
+.byte 0x9e,0xd1,0xb5,0xe3, 0x4c,0x6a,0x88,0x1b
+.byte 0xc1,0x2c,0x1f,0xb8, 0x46,0x65,0x51,0x7f
+.byte 0x9d,0x5e,0xea,0x04, 0x01,0x8c,0x35,0x5d
+.byte 0xfa,0x87,0x74,0x73, 0xfb,0x0b,0x41,0x2e
+.byte 0xb3,0x67,0x1d,0x5a, 0x92,0xdb,0xd2,0x52
+.byte 0xe9,0x10,0x56,0x33, 0x6d,0xd6,0x47,0x13
+.byte 0x9a,0xd7,0x61,0x8c, 0x37,0xa1,0x0c,0x7a
+.byte 0x59,0xf8,0x14,0x8e, 0xeb,0x13,0x3c,0x89
+.byte 0xce,0xa9,0x27,0xee, 0xb7,0x61,0xc9,0x35
+.byte 0xe1,0x1c,0xe5,0xed, 0x7a,0x47,0xb1,0x3c
+.byte 0x9c,0xd2,0xdf,0x59, 0x55,0xf2,0x73,0x3f
+.byte 0x18,0x14,0xce,0x79, 0x73,0xc7,0x37,0xbf
+.byte 0x53,0xf7,0xcd,0xea, 0x5f,0xfd,0xaa,0x5b
+.byte 0xdf,0x3d,0x6f,0x14, 0x78,0x44,0xdb,0x86
+.byte 0xca,0xaf,0xf3,0x81, 0xb9,0x68,0xc4,0x3e
+.byte 0x38,0x24,0x34,0x2c, 0xc2,0xa3,0x40,0x5f
+.byte 0x16,0x1d,0xc3,0x72, 0xbc,0xe2,0x25,0x0c
+.byte 0x28,0x3c,0x49,0x8b, 0xff,0x0d,0x95,0x41
+.byte 0x39,0xa8,0x01,0x71, 0x08,0x0c,0xb3,0xde
+.byte 0xd8,0xb4,0xe4,0x9c, 0x64,0x56,0xc1,0x90
+.byte 0x7b,0xcb,0x84,0x61, 0xd5,0x32,0xb6,0x70
+.byte 0x48,0x6c,0x5c,0x74, 0xd0,0xb8,0x57,0x42
+
+.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 # Td4
+.byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+___
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/ge;
+
+ # made-up _instructions, _xtr, _ins, _ror and _bias, cope
+ # with byte order dependencies...
+ if (/^\s+_/) {
+ s/(_[a-z]+\s+)(\$[0-9]+),([^,]+)(#.*)*$/$1$2,$2,$3/;
+
+ s/_xtr\s+(\$[0-9]+),(\$[0-9]+),([0-9]+(\-2)*)/
+ sprintf("srl\t$1,$2,%d",$big_endian ? eval($3)
+ : eval("24-$3"))/e or
+ s/_ins\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/
+ sprintf("sll\t$1,$2,%d",$big_endian ? eval($3)
+ : eval("24-$3"))/e or
+ s/_ror\s+(\$[0-9]+),(\$[0-9]+),(\-?[0-9]+)/
+ sprintf("srl\t$1,$2,%d",$big_endian ? eval($3)
+ : eval("$3*-1"))/e or
+ s/_bias\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/
+ sprintf("sll\t$1,$2,%d",$big_endian ? eval($3)
+ : eval("($3-16)&31"))/e;
+
+ s/srl\s+(\$[0-9]+),(\$[0-9]+),\-([0-9]+)/
+ sprintf("sll\t$1,$2,$3")/e or
+ s/srl\s+(\$[0-9]+),(\$[0-9]+),0/
+ sprintf("and\t$1,$2,0xff")/e or
+ s/(sll\s+\$[0-9]+,\$[0-9]+,0)/#$1/;
+ }
+
+ # convert lwl/lwr and swr/swl to little-endian order
+ if (!$big_endian && /^\s+[sl]w[lr]\s+/) {
+ s/([sl]wl.*)([0-9]+)\((\$[0-9]+)\)/
+ sprintf("$1%d($3)",eval("$2-$2%4+($2%4-1)&3"))/e or
+ s/([sl]wr.*)([0-9]+)\((\$[0-9]+)\)/
+ sprintf("$1%d($3)",eval("$2-$2%4+($2%4+1)&3"))/e;
+ }
+
+ print $_,"\n";
+}
+
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/aes/asm/aes-parisc.pl b/deps/openssl/openssl/crypto/aes/asm/aes-parisc.pl
new file mode 100644
index 000000000..c36b6a227
--- /dev/null
+++ b/deps/openssl/openssl/crypto/aes/asm/aes-parisc.pl
@@ -0,0 +1,1021 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# AES for PA-RISC.
+#
+# June 2009.
+#
+# The module is mechanical transliteration of aes-sparcv9.pl, but with
+# a twist: S-boxes are compressed even further down to 1K+256B. On
+# PA-7100LC performance is ~40% better than gcc 3.2 generated code and
+# is about 33 cycles per byte processed with 128-bit key. Newer CPUs
+# perform at 16 cycles per byte. It's not faster than code generated
+# by vendor compiler, but recall that it has compressed S-boxes, which
+# requires extra processing.
+#
+# Special thanks to polarhome.com for providing HP-UX account.
+
+$flavour = shift;
+$output = shift;
+open STDOUT,">$output";
+
+if ($flavour =~ /64/) {
+ $LEVEL ="2.0W";
+ $SIZE_T =8;
+ $FRAME_MARKER =80;
+ $SAVED_RP =16;
+ $PUSH ="std";
+ $PUSHMA ="std,ma";
+ $POP ="ldd";
+ $POPMB ="ldd,mb";
+} else {
+ $LEVEL ="1.0";
+ $SIZE_T =4;
+ $FRAME_MARKER =48;
+ $SAVED_RP =20;
+ $PUSH ="stw";
+ $PUSHMA ="stwm";
+ $POP ="ldw";
+ $POPMB ="ldwm";
+}
+
+$FRAME=16*$SIZE_T+$FRAME_MARKER;# 16 saved regs + frame marker
+ # [+ argument transfer]
+$inp="%r26"; # arg0
+$out="%r25"; # arg1
+$key="%r24"; # arg2
+
+($s0,$s1,$s2,$s3) = ("%r1","%r2","%r3","%r4");
+($t0,$t1,$t2,$t3) = ("%r5","%r6","%r7","%r8");
+
+($acc0, $acc1, $acc2, $acc3, $acc4, $acc5, $acc6, $acc7,
+ $acc8, $acc9,$acc10,$acc11,$acc12,$acc13,$acc14,$acc15) =
+("%r9","%r10","%r11","%r12","%r13","%r14","%r15","%r16",
+"%r17","%r18","%r19","%r20","%r21","%r22","%r23","%r26");
+
+$tbl="%r28";
+$rounds="%r29";
+
+$code=<<___;
+ .LEVEL $LEVEL
+ .SPACE \$TEXT\$
+ .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
+
+ .EXPORT AES_encrypt,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
+ .ALIGN 64
+AES_encrypt
+ .PROC
+ .CALLINFO FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18
+ .ENTRY
+ $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue
+ $PUSHMA %r3,$FRAME(%sp)
+ $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp)
+ $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp)
+ $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp)
+ $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp)
+ $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp)
+ $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp)
+ $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp)
+ $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp)
+ $PUSH %r12,`-$FRAME+9*$SIZE_T`(%sp)
+ $PUSH %r13,`-$FRAME+10*$SIZE_T`(%sp)
+ $PUSH %r14,`-$FRAME+11*$SIZE_T`(%sp)
+ $PUSH %r15,`-$FRAME+12*$SIZE_T`(%sp)
+ $PUSH %r16,`-$FRAME+13*$SIZE_T`(%sp)
+ $PUSH %r17,`-$FRAME+14*$SIZE_T`(%sp)
+ $PUSH %r18,`-$FRAME+15*$SIZE_T`(%sp)
+
+ blr %r0,$tbl
+ ldi 3,$t0
+L\$enc_pic
+ andcm $tbl,$t0,$tbl
+ ldo L\$AES_Te-L\$enc_pic($tbl),$tbl
+
+ and $inp,$t0,$t0
+ sub $inp,$t0,$inp
+ ldw 0($inp),$s0
+ ldw 4($inp),$s1
+ ldw 8($inp),$s2
+ comib,= 0,$t0,L\$enc_inp_aligned
+ ldw 12($inp),$s3
+
+ sh3addl $t0,%r0,$t0
+ subi 32,$t0,$t0
+ mtctl $t0,%cr11
+ ldw 16($inp),$t1
+ vshd $s0,$s1,$s0
+ vshd $s1,$s2,$s1
+ vshd $s2,$s3,$s2
+ vshd $s3,$t1,$s3
+
+L\$enc_inp_aligned
+ bl _parisc_AES_encrypt,%r31
+ nop
+
+ extru,<> $out,31,2,%r0
+ b L\$enc_out_aligned
+ nop
+
+ _srm $s0,24,$acc0
+ _srm $s0,16,$acc1
+ stb $acc0,0($out)
+ _srm $s0,8,$acc2
+ stb $acc1,1($out)
+ _srm $s1,24,$acc4
+ stb $acc2,2($out)
+ _srm $s1,16,$acc5
+ stb $s0,3($out)
+ _srm $s1,8,$acc6
+ stb $acc4,4($out)
+ _srm $s2,24,$acc0
+ stb $acc5,5($out)
+ _srm $s2,16,$acc1
+ stb $acc6,6($out)
+ _srm $s2,8,$acc2
+ stb $s1,7($out)
+ _srm $s3,24,$acc4
+ stb $acc0,8($out)
+ _srm $s3,16,$acc5
+ stb $acc1,9($out)
+ _srm $s3,8,$acc6
+ stb $acc2,10($out)
+ stb $s2,11($out)
+ stb $acc4,12($out)
+ stb $acc5,13($out)
+ stb $acc6,14($out)
+ b L\$enc_done
+ stb $s3,15($out)
+
+L\$enc_out_aligned
+ stw $s0,0($out)
+ stw $s1,4($out)
+ stw $s2,8($out)
+ stw $s3,12($out)
+
+L\$enc_done
+ $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue
+ $POP `-$FRAME+1*$SIZE_T`(%sp),%r4
+ $POP `-$FRAME+2*$SIZE_T`(%sp),%r5
+ $POP `-$FRAME+3*$SIZE_T`(%sp),%r6
+ $POP `-$FRAME+4*$SIZE_T`(%sp),%r7
+ $POP `-$FRAME+5*$SIZE_T`(%sp),%r8
+ $POP `-$FRAME+6*$SIZE_T`(%sp),%r9
+ $POP `-$FRAME+7*$SIZE_T`(%sp),%r10
+ $POP `-$FRAME+8*$SIZE_T`(%sp),%r11
+ $POP `-$FRAME+9*$SIZE_T`(%sp),%r12
+ $POP `-$FRAME+10*$SIZE_T`(%sp),%r13
+ $POP `-$FRAME+11*$SIZE_T`(%sp),%r14
+ $POP `-$FRAME+12*$SIZE_T`(%sp),%r15
+ $POP `-$FRAME+13*$SIZE_T`(%sp),%r16
+ $POP `-$FRAME+14*$SIZE_T`(%sp),%r17
+ $POP `-$FRAME+15*$SIZE_T`(%sp),%r18
+ bv (%r2)
+ .EXIT
+ $POPMB -$FRAME(%sp),%r3
+ .PROCEND
+
+ .ALIGN 16
+_parisc_AES_encrypt
+ .PROC
+ .CALLINFO MILLICODE
+ .ENTRY
+ ldw 240($key),$rounds
+ ldw 0($key),$t0
+ ldw 4($key),$t1
+ ldw 8($key),$t2
+ _srm $rounds,1,$rounds
+ xor $t0,$s0,$s0
+ ldw 12($key),$t3
+ _srm $s0,24,$acc0
+ xor $t1,$s1,$s1
+ ldw 16($key),$t0
+ _srm $s1,16,$acc1
+ xor $t2,$s2,$s2
+ ldw 20($key),$t1
+ xor $t3,$s3,$s3
+ ldw 24($key),$t2
+ ldw 28($key),$t3
+L\$enc_loop
+ _srm $s2,8,$acc2
+ ldwx,s $acc0($tbl),$acc0
+ _srm $s3,0,$acc3
+ ldwx,s $acc1($tbl),$acc1
+ _srm $s1,24,$acc4
+ ldwx,s $acc2($tbl),$acc2
+ _srm $s2,16,$acc5
+ ldwx,s $acc3($tbl),$acc3
+ _srm $s3,8,$acc6
+ ldwx,s $acc4($tbl),$acc4
+ _srm $s0,0,$acc7
+ ldwx,s $acc5($tbl),$acc5
+ _srm $s2,24,$acc8
+ ldwx,s $acc6($tbl),$acc6
+ _srm $s3,16,$acc9
+ ldwx,s $acc7($tbl),$acc7
+ _srm $s0,8,$acc10
+ ldwx,s $acc8($tbl),$acc8
+ _srm $s1,0,$acc11
+ ldwx,s $acc9($tbl),$acc9
+ _srm $s3,24,$acc12
+ ldwx,s $acc10($tbl),$acc10
+ _srm $s0,16,$acc13
+ ldwx,s $acc11($tbl),$acc11
+ _srm $s1,8,$acc14
+ ldwx,s $acc12($tbl),$acc12
+ _srm $s2,0,$acc15
+ ldwx,s $acc13($tbl),$acc13
+ ldwx,s $acc14($tbl),$acc14
+ ldwx,s $acc15($tbl),$acc15
+ addib,= -1,$rounds,L\$enc_last
+ ldo 32($key),$key
+
+ _ror $acc1,8,$acc1
+ xor $acc0,$t0,$t0
+ ldw 0($key),$s0
+ _ror $acc2,16,$acc2
+ xor $acc1,$t0,$t0
+ ldw 4($key),$s1
+ _ror $acc3,24,$acc3
+ xor $acc2,$t0,$t0
+ ldw 8($key),$s2
+ _ror $acc5,8,$acc5
+ xor $acc3,$t0,$t0
+ ldw 12($key),$s3
+ _ror $acc6,16,$acc6
+ xor $acc4,$t1,$t1
+ _ror $acc7,24,$acc7
+ xor $acc5,$t1,$t1
+ _ror $acc9,8,$acc9
+ xor $acc6,$t1,$t1
+ _ror $acc10,16,$acc10
+ xor $acc7,$t1,$t1
+ _ror $acc11,24,$acc11
+ xor $acc8,$t2,$t2
+ _ror $acc13,8,$acc13
+ xor $acc9,$t2,$t2
+ _ror $acc14,16,$acc14
+ xor $acc10,$t2,$t2
+ _ror $acc15,24,$acc15
+ xor $acc11,$t2,$t2
+ xor $acc12,$acc14,$acc14
+ xor $acc13,$t3,$t3
+ _srm $t0,24,$acc0
+ xor $acc14,$t3,$t3
+ _srm $t1,16,$acc1
+ xor $acc15,$t3,$t3
+
+ _srm $t2,8,$acc2
+ ldwx,s $acc0($tbl),$acc0
+ _srm $t3,0,$acc3
+ ldwx,s $acc1($tbl),$acc1
+ _srm $t1,24,$acc4
+ ldwx,s $acc2($tbl),$acc2
+ _srm $t2,16,$acc5
+ ldwx,s $acc3($tbl),$acc3
+ _srm $t3,8,$acc6
+ ldwx,s $acc4($tbl),$acc4
+ _srm $t0,0,$acc7
+ ldwx,s $acc5($tbl),$acc5
+ _srm $t2,24,$acc8
+ ldwx,s $acc6($tbl),$acc6
+ _srm $t3,16,$acc9
+ ldwx,s $acc7($tbl),$acc7
+ _srm $t0,8,$acc10
+ ldwx,s $acc8($tbl),$acc8
+ _srm $t1,0,$acc11
+ ldwx,s $acc9($tbl),$acc9
+ _srm $t3,24,$acc12
+ ldwx,s $acc10($tbl),$acc10
+ _srm $t0,16,$acc13
+ ldwx,s $acc11($tbl),$acc11
+ _srm $t1,8,$acc14
+ ldwx,s $acc12($tbl),$acc12
+ _srm $t2,0,$acc15
+ ldwx,s $acc13($tbl),$acc13
+ _ror $acc1,8,$acc1
+ ldwx,s $acc14($tbl),$acc14
+
+ _ror $acc2,16,$acc2
+ xor $acc0,$s0,$s0
+ ldwx,s $acc15($tbl),$acc15
+ _ror $acc3,24,$acc3
+ xor $acc1,$s0,$s0
+ ldw 16($key),$t0
+ _ror $acc5,8,$acc5
+ xor $acc2,$s0,$s0
+ ldw 20($key),$t1
+ _ror $acc6,16,$acc6
+ xor $acc3,$s0,$s0
+ ldw 24($key),$t2
+ _ror $acc7,24,$acc7
+ xor $acc4,$s1,$s1
+ ldw 28($key),$t3
+ _ror $acc9,8,$acc9
+ xor $acc5,$s1,$s1
+ ldw 1024+0($tbl),%r0 ; prefetch te4
+ _ror $acc10,16,$acc10
+ xor $acc6,$s1,$s1
+ ldw 1024+32($tbl),%r0 ; prefetch te4
+ _ror $acc11,24,$acc11
+ xor $acc7,$s1,$s1
+ ldw 1024+64($tbl),%r0 ; prefetch te4
+ _ror $acc13,8,$acc13
+ xor $acc8,$s2,$s2
+ ldw 1024+96($tbl),%r0 ; prefetch te4
+ _ror $acc14,16,$acc14
+ xor $acc9,$s2,$s2
+ ldw 1024+128($tbl),%r0 ; prefetch te4
+ _ror $acc15,24,$acc15
+ xor $acc10,$s2,$s2
+ ldw 1024+160($tbl),%r0 ; prefetch te4
+ _srm $s0,24,$acc0
+ xor $acc11,$s2,$s2
+ ldw 1024+192($tbl),%r0 ; prefetch te4
+ xor $acc12,$acc14,$acc14
+ xor $acc13,$s3,$s3
+ ldw 1024+224($tbl),%r0 ; prefetch te4
+ _srm $s1,16,$acc1
+ xor $acc14,$s3,$s3
+ b L\$enc_loop
+ xor $acc15,$s3,$s3
+
+ .ALIGN 16
+L\$enc_last
+ ldo 1024($tbl),$rounds
+ _ror $acc1,8,$acc1
+ xor $acc0,$t0,$t0
+ ldw 0($key),$s0
+ _ror $acc2,16,$acc2
+ xor $acc1,$t0,$t0
+ ldw 4($key),$s1
+ _ror $acc3,24,$acc3
+ xor $acc2,$t0,$t0
+ ldw 8($key),$s2
+ _ror $acc5,8,$acc5
+ xor $acc3,$t0,$t0
+ ldw 12($key),$s3
+ _ror $acc6,16,$acc6
+ xor $acc4,$t1,$t1
+ _ror $acc7,24,$acc7
+ xor $acc5,$t1,$t1
+ _ror $acc9,8,$acc9
+ xor $acc6,$t1,$t1
+ _ror $acc10,16,$acc10
+ xor $acc7,$t1,$t1
+ _ror $acc11,24,$acc11
+ xor $acc8,$t2,$t2
+ _ror $acc13,8,$acc13
+ xor $acc9,$t2,$t2
+ _ror $acc14,16,$acc14
+ xor $acc10,$t2,$t2
+ _ror $acc15,24,$acc15
+ xor $acc11,$t2,$t2
+ xor $acc12,$acc14,$acc14
+ xor $acc13,$t3,$t3
+ _srm $t0,24,$acc0
+ xor $acc14,$t3,$t3
+ _srm $t1,16,$acc1
+ xor $acc15,$t3,$t3
+
+ _srm $t2,8,$acc2
+ ldbx $acc0($rounds),$acc0
+ _srm $t1,24,$acc4
+ ldbx $acc1($rounds),$acc1
+ _srm $t2,16,$acc5
+ _srm $t3,0,$acc3
+ ldbx $acc2($rounds),$acc2
+ ldbx $acc3($rounds),$acc3
+ _srm $t3,8,$acc6
+ ldbx $acc4($rounds),$acc4
+ _srm $t2,24,$acc8
+ ldbx $acc5($rounds),$acc5
+ _srm $t3,16,$acc9
+ _srm $t0,0,$acc7
+ ldbx $acc6($rounds),$acc6
+ ldbx $acc7($rounds),$acc7
+ _srm $t0,8,$acc10
+ ldbx $acc8($rounds),$acc8
+ _srm $t3,24,$acc12
+ ldbx $acc9($rounds),$acc9
+ _srm $t0,16,$acc13
+ _srm $t1,0,$acc11
+ ldbx $acc10($rounds),$acc10
+ _srm $t1,8,$acc14
+ ldbx $acc11($rounds),$acc11
+ ldbx $acc12($rounds),$acc12
+ ldbx $acc13($rounds),$acc13
+ _srm $t2,0,$acc15
+ ldbx $acc14($rounds),$acc14
+
+ dep $acc0,7,8,$acc3
+ ldbx $acc15($rounds),$acc15
+ dep $acc4,7,8,$acc7
+ dep $acc1,15,8,$acc3
+ dep $acc5,15,8,$acc7
+ dep $acc2,23,8,$acc3
+ dep $acc6,23,8,$acc7
+ xor $acc3,$s0,$s0
+ xor $acc7,$s1,$s1
+ dep $acc8,7,8,$acc11
+ dep $acc12,7,8,$acc15
+ dep $acc9,15,8,$acc11
+ dep $acc13,15,8,$acc15
+ dep $acc10,23,8,$acc11
+ dep $acc14,23,8,$acc15
+ xor $acc11,$s2,$s2
+
+ bv (%r31)
+ .EXIT
+ xor $acc15,$s3,$s3
+ .PROCEND
+
+ .ALIGN 64
+L\$AES_Te
+ .WORD 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
+ .WORD 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
+ .WORD 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
+ .WORD 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
+ .WORD 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
+ .WORD 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
+ .WORD 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
+ .WORD 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
+ .WORD 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
+ .WORD 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
+ .WORD 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
+ .WORD 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
+ .WORD 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
+ .WORD 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
+ .WORD 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
+ .WORD 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
+ .WORD 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
+ .WORD 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
+ .WORD 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
+ .WORD 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
+ .WORD 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
+ .WORD 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
+ .WORD 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
+ .WORD 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
+ .WORD 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
+ .WORD 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
+ .WORD 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
+ .WORD 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
+ .WORD 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
+ .WORD 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
+ .WORD 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
+ .WORD 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
+ .WORD 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
+ .WORD 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
+ .WORD 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
+ .WORD 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
+ .WORD 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
+ .WORD 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
+ .WORD 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
+ .WORD 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
+ .WORD 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
+ .WORD 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
+ .WORD 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
+ .WORD 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
+ .WORD 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
+ .WORD 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
+ .WORD 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
+ .WORD 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
+ .WORD 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
+ .WORD 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
+ .WORD 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
+ .WORD 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
+ .WORD 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
+ .WORD 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
+ .WORD 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
+ .WORD 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
+ .WORD 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
+ .WORD 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
+ .WORD 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
+ .WORD 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
+ .WORD 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
+ .WORD 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
+ .WORD 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
+ .WORD 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
+ .BYTE 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+ .BYTE 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+ .BYTE 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+ .BYTE 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+ .BYTE 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+ .BYTE 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+ .BYTE 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+ .BYTE 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+ .BYTE 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+ .BYTE 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+ .BYTE 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+ .BYTE 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+ .BYTE 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+ .BYTE 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+ .BYTE 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+ .BYTE 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+ .BYTE 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+ .BYTE 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+ .BYTE 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+ .BYTE 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+ .BYTE 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+ .BYTE 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+ .BYTE 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+ .BYTE 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+ .BYTE 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+ .BYTE 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+ .BYTE 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+ .BYTE 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+ .BYTE 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+ .BYTE 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+ .BYTE 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+ .BYTE 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+___
+
+$code.=<<___;
+ .EXPORT AES_decrypt,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
+ .ALIGN 16
+AES_decrypt
+ .PROC
+ .CALLINFO FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18
+ .ENTRY
+ $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue
+ $PUSHMA %r3,$FRAME(%sp)
+ $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp)
+ $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp)
+ $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp)
+ $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp)
+ $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp)
+ $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp)
+ $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp)
+ $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp)
+ $PUSH %r12,`-$FRAME+9*$SIZE_T`(%sp)
+ $PUSH %r13,`-$FRAME+10*$SIZE_T`(%sp)
+ $PUSH %r14,`-$FRAME+11*$SIZE_T`(%sp)
+ $PUSH %r15,`-$FRAME+12*$SIZE_T`(%sp)
+ $PUSH %r16,`-$FRAME+13*$SIZE_T`(%sp)
+ $PUSH %r17,`-$FRAME+14*$SIZE_T`(%sp)
+ $PUSH %r18,`-$FRAME+15*$SIZE_T`(%sp)
+
+ blr %r0,$tbl
+ ldi 3,$t0
+L\$dec_pic
+ andcm $tbl,$t0,$tbl
+ ldo L\$AES_Td-L\$dec_pic($tbl),$tbl
+
+ and $inp,$t0,$t0
+ sub $inp,$t0,$inp
+ ldw 0($inp),$s0
+ ldw 4($inp),$s1
+ ldw 8($inp),$s2
+ comib,= 0,$t0,L\$dec_inp_aligned
+ ldw 12($inp),$s3
+
+ sh3addl $t0,%r0,$t0
+ subi 32,$t0,$t0
+ mtctl $t0,%cr11
+ ldw 16($inp),$t1
+ vshd $s0,$s1,$s0
+ vshd $s1,$s2,$s1
+ vshd $s2,$s3,$s2
+ vshd $s3,$t1,$s3
+
+L\$dec_inp_aligned
+ bl _parisc_AES_decrypt,%r31
+ nop
+
+ extru,<> $out,31,2,%r0
+ b L\$dec_out_aligned
+ nop
+
+ _srm $s0,24,$acc0
+ _srm $s0,16,$acc1
+ stb $acc0,0($out)
+ _srm $s0,8,$acc2
+ stb $acc1,1($out)
+ _srm $s1,24,$acc4
+ stb $acc2,2($out)
+ _srm $s1,16,$acc5
+ stb $s0,3($out)
+ _srm $s1,8,$acc6
+ stb $acc4,4($out)
+ _srm $s2,24,$acc0
+ stb $acc5,5($out)
+ _srm $s2,16,$acc1
+ stb $acc6,6($out)
+ _srm $s2,8,$acc2
+ stb $s1,7($out)
+ _srm $s3,24,$acc4
+ stb $acc0,8($out)
+ _srm $s3,16,$acc5
+ stb $acc1,9($out)
+ _srm $s3,8,$acc6
+ stb $acc2,10($out)
+ stb $s2,11($out)
+ stb $acc4,12($out)
+ stb $acc5,13($out)
+ stb $acc6,14($out)
+ b L\$dec_done
+ stb $s3,15($out)
+
+L\$dec_out_aligned
+ stw $s0,0($out)
+ stw $s1,4($out)
+ stw $s2,8($out)
+ stw $s3,12($out)
+
+L\$dec_done
+ $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue
+ $POP `-$FRAME+1*$SIZE_T`(%sp),%r4
+ $POP `-$FRAME+2*$SIZE_T`(%sp),%r5
+ $POP `-$FRAME+3*$SIZE_T`(%sp),%r6
+ $POP `-$FRAME+4*$SIZE_T`(%sp),%r7
+ $POP `-$FRAME+5*$SIZE_T`(%sp),%r8
+ $POP `-$FRAME+6*$SIZE_T`(%sp),%r9
+ $POP `-$FRAME+7*$SIZE_T`(%sp),%r10
+ $POP `-$FRAME+8*$SIZE_T`(%sp),%r11
+ $POP `-$FRAME+9*$SIZE_T`(%sp),%r12
+ $POP `-$FRAME+10*$SIZE_T`(%sp),%r13
+ $POP `-$FRAME+11*$SIZE_T`(%sp),%r14
+ $POP `-$FRAME+12*$SIZE_T`(%sp),%r15
+ $POP `-$FRAME+13*$SIZE_T`(%sp),%r16
+ $POP `-$FRAME+14*$SIZE_T`(%sp),%r17
+ $POP `-$FRAME+15*$SIZE_T`(%sp),%r18
+ bv (%r2)
+ .EXIT
+ $POPMB -$FRAME(%sp),%r3
+ .PROCEND
+
+ .ALIGN 16
+_parisc_AES_decrypt
+ .PROC
+ .CALLINFO MILLICODE
+ .ENTRY
+ ldw 240($key),$rounds
+ ldw 0($key),$t0
+ ldw 4($key),$t1
+ ldw 8($key),$t2
+ ldw 12($key),$t3
+ _srm $rounds,1,$rounds
+ xor $t0,$s0,$s0
+ ldw 16($key),$t0
+ xor $t1,$s1,$s1
+ ldw 20($key),$t1
+ _srm $s0,24,$acc0
+ xor $t2,$s2,$s2
+ ldw 24($key),$t2
+ xor $t3,$s3,$s3
+ ldw 28($key),$t3
+ _srm $s3,16,$acc1
+L\$dec_loop
+ _srm $s2,8,$acc2
+ ldwx,s $acc0($tbl),$acc0
+ _srm $s1,0,$acc3
+ ldwx,s $acc1($tbl),$acc1
+ _srm $s1,24,$acc4
+ ldwx,s $acc2($tbl),$acc2
+ _srm $s0,16,$acc5
+ ldwx,s $acc3($tbl),$acc3
+ _srm $s3,8,$acc6
+ ldwx,s $acc4($tbl),$acc4
+ _srm $s2,0,$acc7
+ ldwx,s $acc5($tbl),$acc5
+ _srm $s2,24,$acc8
+ ldwx,s $acc6($tbl),$acc6
+ _srm $s1,16,$acc9
+ ldwx,s $acc7($tbl),$acc7
+ _srm $s0,8,$acc10
+ ldwx,s $acc8($tbl),$acc8
+ _srm $s3,0,$acc11
+ ldwx,s $acc9($tbl),$acc9
+ _srm $s3,24,$acc12
+ ldwx,s $acc10($tbl),$acc10
+ _srm $s2,16,$acc13
+ ldwx,s $acc11($tbl),$acc11
+ _srm $s1,8,$acc14
+ ldwx,s $acc12($tbl),$acc12
+ _srm $s0,0,$acc15
+ ldwx,s $acc13($tbl),$acc13
+ ldwx,s $acc14($tbl),$acc14
+ ldwx,s $acc15($tbl),$acc15
+ addib,= -1,$rounds,L\$dec_last
+ ldo 32($key),$key
+
+ _ror $acc1,8,$acc1
+ xor $acc0,$t0,$t0
+ ldw 0($key),$s0
+ _ror $acc2,16,$acc2
+ xor $acc1,$t0,$t0
+ ldw 4($key),$s1
+ _ror $acc3,24,$acc3
+ xor $acc2,$t0,$t0
+ ldw 8($key),$s2
+ _ror $acc5,8,$acc5
+ xor $acc3,$t0,$t0
+ ldw 12($key),$s3
+ _ror $acc6,16,$acc6
+ xor $acc4,$t1,$t1
+ _ror $acc7,24,$acc7
+ xor $acc5,$t1,$t1
+ _ror $acc9,8,$acc9
+ xor $acc6,$t1,$t1
+ _ror $acc10,16,$acc10
+ xor $acc7,$t1,$t1
+ _ror $acc11,24,$acc11
+ xor $acc8,$t2,$t2
+ _ror $acc13,8,$acc13
+ xor $acc9,$t2,$t2
+ _ror $acc14,16,$acc14
+ xor $acc10,$t2,$t2
+ _ror $acc15,24,$acc15
+ xor $acc11,$t2,$t2
+ xor $acc12,$acc14,$acc14
+ xor $acc13,$t3,$t3
+ _srm $t0,24,$acc0
+ xor $acc14,$t3,$t3
+ xor $acc15,$t3,$t3
+ _srm $t3,16,$acc1
+
+ _srm $t2,8,$acc2
+ ldwx,s $acc0($tbl),$acc0
+ _srm $t1,0,$acc3
+ ldwx,s $acc1($tbl),$acc1
+ _srm $t1,24,$acc4
+ ldwx,s $acc2($tbl),$acc2
+ _srm $t0,16,$acc5
+ ldwx,s $acc3($tbl),$acc3
+ _srm $t3,8,$acc6
+ ldwx,s $acc4($tbl),$acc4
+ _srm $t2,0,$acc7
+ ldwx,s $acc5($tbl),$acc5
+ _srm $t2,24,$acc8
+ ldwx,s $acc6($tbl),$acc6
+ _srm $t1,16,$acc9
+ ldwx,s $acc7($tbl),$acc7
+ _srm $t0,8,$acc10
+ ldwx,s $acc8($tbl),$acc8
+ _srm $t3,0,$acc11
+ ldwx,s $acc9($tbl),$acc9
+ _srm $t3,24,$acc12
+ ldwx,s $acc10($tbl),$acc10
+ _srm $t2,16,$acc13
+ ldwx,s $acc11($tbl),$acc11
+ _srm $t1,8,$acc14
+ ldwx,s $acc12($tbl),$acc12
+ _srm $t0,0,$acc15
+ ldwx,s $acc13($tbl),$acc13
+ _ror $acc1,8,$acc1
+ ldwx,s $acc14($tbl),$acc14
+
+ _ror $acc2,16,$acc2
+ xor $acc0,$s0,$s0
+ ldwx,s $acc15($tbl),$acc15
+ _ror $acc3,24,$acc3
+ xor $acc1,$s0,$s0
+ ldw 16($key),$t0
+ _ror $acc5,8,$acc5
+ xor $acc2,$s0,$s0
+ ldw 20($key),$t1
+ _ror $acc6,16,$acc6
+ xor $acc3,$s0,$s0
+ ldw 24($key),$t2
+ _ror $acc7,24,$acc7
+ xor $acc4,$s1,$s1
+ ldw 28($key),$t3
+ _ror $acc9,8,$acc9
+ xor $acc5,$s1,$s1
+ ldw 1024+0($tbl),%r0 ; prefetch td4
+ _ror $acc10,16,$acc10
+ xor $acc6,$s1,$s1
+ ldw 1024+32($tbl),%r0 ; prefetch td4
+ _ror $acc11,24,$acc11
+ xor $acc7,$s1,$s1
+ ldw 1024+64($tbl),%r0 ; prefetch td4
+ _ror $acc13,8,$acc13
+ xor $acc8,$s2,$s2
+ ldw 1024+96($tbl),%r0 ; prefetch td4
+ _ror $acc14,16,$acc14
+ xor $acc9,$s2,$s2
+ ldw 1024+128($tbl),%r0 ; prefetch td4
+ _ror $acc15,24,$acc15
+ xor $acc10,$s2,$s2
+ ldw 1024+160($tbl),%r0 ; prefetch td4
+ _srm $s0,24,$acc0
+ xor $acc11,$s2,$s2
+ ldw 1024+192($tbl),%r0 ; prefetch td4
+ xor $acc12,$acc14,$acc14
+ xor $acc13,$s3,$s3
+ ldw 1024+224($tbl),%r0 ; prefetch td4
+ xor $acc14,$s3,$s3
+ xor $acc15,$s3,$s3
+ b L\$dec_loop
+ _srm $s3,16,$acc1
+
+ .ALIGN 16
+L\$dec_last
+ ldo 1024($tbl),$rounds
+ _ror $acc1,8,$acc1
+ xor $acc0,$t0,$t0
+ ldw 0($key),$s0
+ _ror $acc2,16,$acc2
+ xor $acc1,$t0,$t0
+ ldw 4($key),$s1
+ _ror $acc3,24,$acc3
+ xor $acc2,$t0,$t0
+ ldw 8($key),$s2
+ _ror $acc5,8,$acc5
+ xor $acc3,$t0,$t0
+ ldw 12($key),$s3
+ _ror $acc6,16,$acc6
+ xor $acc4,$t1,$t1
+ _ror $acc7,24,$acc7
+ xor $acc5,$t1,$t1
+ _ror $acc9,8,$acc9
+ xor $acc6,$t1,$t1
+ _ror $acc10,16,$acc10
+ xor $acc7,$t1,$t1
+ _ror $acc11,24,$acc11
+ xor $acc8,$t2,$t2
+ _ror $acc13,8,$acc13
+ xor $acc9,$t2,$t2
+ _ror $acc14,16,$acc14
+ xor $acc10,$t2,$t2
+ _ror $acc15,24,$acc15
+ xor $acc11,$t2,$t2
+ xor $acc12,$acc14,$acc14
+ xor $acc13,$t3,$t3
+ _srm $t0,24,$acc0
+ xor $acc14,$t3,$t3
+ xor $acc15,$t3,$t3
+ _srm $t3,16,$acc1
+
+ _srm $t2,8,$acc2
+ ldbx $acc0($rounds),$acc0
+ _srm $t1,24,$acc4
+ ldbx $acc1($rounds),$acc1
+ _srm $t0,16,$acc5
+ _srm $t1,0,$acc3
+ ldbx $acc2($rounds),$acc2
+ ldbx $acc3($rounds),$acc3
+ _srm $t3,8,$acc6
+ ldbx $acc4($rounds),$acc4
+ _srm $t2,24,$acc8
+ ldbx $acc5($rounds),$acc5
+ _srm $t1,16,$acc9
+ _srm $t2,0,$acc7
+ ldbx $acc6($rounds),$acc6
+ ldbx $acc7($rounds),$acc7
+ _srm $t0,8,$acc10
+ ldbx $acc8($rounds),$acc8
+ _srm $t3,24,$acc12
+ ldbx $acc9($rounds),$acc9
+ _srm $t2,16,$acc13
+ _srm $t3,0,$acc11
+ ldbx $acc10($rounds),$acc10
+ _srm $t1,8,$acc14
+ ldbx $acc11($rounds),$acc11
+ ldbx $acc12($rounds),$acc12
+ ldbx $acc13($rounds),$acc13
+ _srm $t0,0,$acc15
+ ldbx $acc14($rounds),$acc14
+
+ dep $acc0,7,8,$acc3
+ ldbx $acc15($rounds),$acc15
+ dep $acc4,7,8,$acc7
+ dep $acc1,15,8,$acc3
+ dep $acc5,15,8,$acc7
+ dep $acc2,23,8,$acc3
+ dep $acc6,23,8,$acc7
+ xor $acc3,$s0,$s0
+ xor $acc7,$s1,$s1
+ dep $acc8,7,8,$acc11
+ dep $acc12,7,8,$acc15
+ dep $acc9,15,8,$acc11
+ dep $acc13,15,8,$acc15
+ dep $acc10,23,8,$acc11
+ dep $acc14,23,8,$acc15
+ xor $acc11,$s2,$s2
+
+ bv (%r31)
+ .EXIT
+ xor $acc15,$s3,$s3
+ .PROCEND
+
+ .ALIGN 64
+L\$AES_Td
+ .WORD 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
+ .WORD 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
+ .WORD 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
+ .WORD 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
+ .WORD 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
+ .WORD 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
+ .WORD 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
+ .WORD 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
+ .WORD 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
+ .WORD 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
+ .WORD 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
+ .WORD 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
+ .WORD 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
+ .WORD 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
+ .WORD 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
+ .WORD 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
+ .WORD 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
+ .WORD 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
+ .WORD 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
+ .WORD 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
+ .WORD 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
+ .WORD 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
+ .WORD 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
+ .WORD 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
+ .WORD 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
+ .WORD 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
+ .WORD 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
+ .WORD 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
+ .WORD 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
+ .WORD 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
+ .WORD 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
+ .WORD 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
+ .WORD 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
+ .WORD 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
+ .WORD 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
+ .WORD 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
+ .WORD 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
+ .WORD 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
+ .WORD 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
+ .WORD 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
+ .WORD 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
+ .WORD 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
+ .WORD 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
+ .WORD 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
+ .WORD 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
+ .WORD 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
+ .WORD 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
+ .WORD 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
+ .WORD 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
+ .WORD 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
+ .WORD 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
+ .WORD 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
+ .WORD 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
+ .WORD 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
+ .WORD 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
+ .WORD 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
+ .WORD 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
+ .WORD 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
+ .WORD 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
+ .WORD 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
+ .WORD 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
+ .WORD 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
+ .WORD 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
+ .WORD 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
+ .BYTE 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+ .BYTE 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+ .BYTE 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+ .BYTE 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+ .BYTE 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+ .BYTE 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+ .BYTE 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+ .BYTE 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+ .BYTE 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+ .BYTE 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+ .BYTE 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+ .BYTE 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+ .BYTE 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+ .BYTE 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+ .BYTE 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+ .BYTE 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+ .BYTE 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+ .BYTE 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+ .BYTE 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+ .BYTE 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+ .BYTE 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+ .BYTE 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+ .BYTE 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+ .BYTE 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+ .BYTE 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+ .BYTE 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+ .BYTE 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+ .BYTE 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+ .BYTE 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+ .BYTE 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+ .BYTE 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+ .BYTE 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+ .STRINGZ "AES for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/ge;
+
+ # translate made up instructons: _ror, _srm
+ s/_ror(\s+)(%r[0-9]+),/shd$1$2,$2,/ or
+
+ s/_srm(\s+%r[0-9]+),([0-9]+),/
+ $SIZE_T==4 ? sprintf("extru%s,%d,8,",$1,31-$2)
+ : sprintf("extrd,u%s,%d,8,",$1,63-$2)/e;
+
+ s/,\*/,/ if ($SIZE_T==4);
+ print $_,"\n";
+}
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/aes/asm/aes-ppc.pl b/deps/openssl/openssl/crypto/aes/asm/aes-ppc.pl
index f82c5e181..7c52cbe5f 100644
--- a/deps/openssl/openssl/crypto/aes/asm/aes-ppc.pl
+++ b/deps/openssl/openssl/crypto/aes/asm/aes-ppc.pl
@@ -7,7 +7,7 @@
# details see http://www.openssl.org/~appro/cryptogams/.
# ====================================================================
-# Needs more work: key setup, page boundaries, CBC routine...
+# Needs more work: key setup, CBC routine...
#
# ppc_AES_[en|de]crypt perform at 18 cycles per byte processed with
# 128-bit key, which is ~40% better than 64-bit code generated by gcc
@@ -18,7 +18,7 @@
# February 2010
#
-# Rescheduling instructions to favour Power6 pipeline gives 10%
+# Rescheduling instructions to favour Power6 pipeline gave 10%
# performance improvement on the platfrom in question (and marginal
# improvement even on others). It should be noted that Power6 fails
# to process byte in 18 cycles, only in 23, because it fails to issue
@@ -33,11 +33,13 @@ $flavour = shift;
if ($flavour =~ /64/) {
$SIZE_T =8;
+ $LRSAVE =2*$SIZE_T;
$STU ="stdu";
$POP ="ld";
$PUSH ="std";
} elsif ($flavour =~ /32/) {
$SIZE_T =4;
+ $LRSAVE =$SIZE_T;
$STU ="stwu";
$POP ="lwz";
$PUSH ="stw";
@@ -116,15 +118,19 @@ LAES_Te:
addi $Tbl0,$Tbl0,`128-8`
mtlr r0
blr
- .space `32-24`
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
+ .space `64-9*4`
LAES_Td:
mflr r0
bcl 20,31,\$+4
mflr $Tbl0 ; vvvvvvvv "distance" between . and 1st data entry
- addi $Tbl0,$Tbl0,`128-8-32+2048+256`
+ addi $Tbl0,$Tbl0,`128-64-8+2048+256`
mtlr r0
blr
- .space `128-32-24`
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
+ .space `128-64-9*4`
___
&_data_word(
0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
@@ -328,10 +334,9 @@ $code.=<<___;
.globl .AES_encrypt
.align 7
.AES_encrypt:
- mflr r0
$STU $sp,-$FRAME($sp)
+ mflr r0
- $PUSH r0,`$FRAME-$SIZE_T*21`($sp)
$PUSH $toc,`$FRAME-$SIZE_T*20`($sp)
$PUSH r13,`$FRAME-$SIZE_T*19`($sp)
$PUSH r14,`$FRAME-$SIZE_T*18`($sp)
@@ -352,7 +357,14 @@ $code.=<<___;
$PUSH r29,`$FRAME-$SIZE_T*3`($sp)
$PUSH r30,`$FRAME-$SIZE_T*2`($sp)
$PUSH r31,`$FRAME-$SIZE_T*1`($sp)
+ $PUSH r0,`$FRAME+$LRSAVE`($sp)
+
+ andi. $t0,$inp,3
+ andi. $t1,$out,3
+ or. $t0,$t0,$t1
+ bne Lenc_unaligned
+Lenc_unaligned_ok:
lwz $s0,0($inp)
lwz $s1,4($inp)
lwz $s2,8($inp)
@@ -363,8 +375,80 @@ $code.=<<___;
stw $s1,4($out)
stw $s2,8($out)
stw $s3,12($out)
+ b Lenc_done
+
+Lenc_unaligned:
+ subfic $t0,$inp,4096
+ subfic $t1,$out,4096
+ andi. $t0,$t0,4096-16
+ beq Lenc_xpage
+ andi. $t1,$t1,4096-16
+ bne Lenc_unaligned_ok
+
+Lenc_xpage:
+ lbz $acc00,0($inp)
+ lbz $acc01,1($inp)
+ lbz $acc02,2($inp)
+ lbz $s0,3($inp)
+ lbz $acc04,4($inp)
+ lbz $acc05,5($inp)
+ lbz $acc06,6($inp)
+ lbz $s1,7($inp)
+ lbz $acc08,8($inp)
+ lbz $acc09,9($inp)
+ lbz $acc10,10($inp)
+ insrwi $s0,$acc00,8,0
+ lbz $s2,11($inp)
+ insrwi $s1,$acc04,8,0
+ lbz $acc12,12($inp)
+ insrwi $s0,$acc01,8,8
+ lbz $acc13,13($inp)
+ insrwi $s1,$acc05,8,8
+ lbz $acc14,14($inp)
+ insrwi $s0,$acc02,8,16
+ lbz $s3,15($inp)
+ insrwi $s1,$acc06,8,16
+ insrwi $s2,$acc08,8,0
+ insrwi $s3,$acc12,8,0
+ insrwi $s2,$acc09,8,8
+ insrwi $s3,$acc13,8,8
+ insrwi $s2,$acc10,8,16
+ insrwi $s3,$acc14,8,16
+
+ bl LAES_Te
+ bl Lppc_AES_encrypt_compact
+
+ extrwi $acc00,$s0,8,0
+ extrwi $acc01,$s0,8,8
+ stb $acc00,0($out)
+ extrwi $acc02,$s0,8,16
+ stb $acc01,1($out)
+ stb $acc02,2($out)
+ extrwi $acc04,$s1,8,0
+ stb $s0,3($out)
+ extrwi $acc05,$s1,8,8
+ stb $acc04,4($out)
+ extrwi $acc06,$s1,8,16
+ stb $acc05,5($out)
+ stb $acc06,6($out)
+ extrwi $acc08,$s2,8,0
+ stb $s1,7($out)
+ extrwi $acc09,$s2,8,8
+ stb $acc08,8($out)
+ extrwi $acc10,$s2,8,16
+ stb $acc09,9($out)
+ stb $acc10,10($out)
+ extrwi $acc12,$s3,8,0
+ stb $s2,11($out)
+ extrwi $acc13,$s3,8,8
+ stb $acc12,12($out)
+ extrwi $acc14,$s3,8,16
+ stb $acc13,13($out)
+ stb $acc14,14($out)
+ stb $s3,15($out)
- $POP r0,`$FRAME-$SIZE_T*21`($sp)
+Lenc_done:
+ $POP r0,`$FRAME+$LRSAVE`($sp)
$POP $toc,`$FRAME-$SIZE_T*20`($sp)
$POP r13,`$FRAME-$SIZE_T*19`($sp)
$POP r14,`$FRAME-$SIZE_T*18`($sp)
@@ -388,18 +472,21 @@ $code.=<<___;
mtlr r0
addi $sp,$sp,$FRAME
blr
+ .long 0
+ .byte 0,12,4,1,0x80,18,3,0
+ .long 0
.align 5
Lppc_AES_encrypt:
lwz $acc00,240($key)
- lwz $t0,0($key)
- lwz $t1,4($key)
- lwz $t2,8($key)
- lwz $t3,12($key)
addi $Tbl1,$Tbl0,3
+ lwz $t0,0($key)
addi $Tbl2,$Tbl0,2
+ lwz $t1,4($key)
addi $Tbl3,$Tbl0,1
+ lwz $t2,8($key)
addi $acc00,$acc00,-1
+ lwz $t3,12($key)
addi $key,$key,16
xor $s0,$s0,$t0
xor $s1,$s1,$t1
@@ -413,44 +500,44 @@ Lenc_loop:
rlwinm $acc02,$s2,`32-24+3`,21,28
rlwinm $acc03,$s3,`32-24+3`,21,28
lwz $t0,0($key)
- lwz $t1,4($key)
rlwinm $acc04,$s1,`32-16+3`,21,28
+ lwz $t1,4($key)
rlwinm $acc05,$s2,`32-16+3`,21,28
lwz $t2,8($key)
- lwz $t3,12($key)
rlwinm $acc06,$s3,`32-16+3`,21,28
+ lwz $t3,12($key)
rlwinm $acc07,$s0,`32-16+3`,21,28
lwzx $acc00,$Tbl0,$acc00
- lwzx $acc01,$Tbl0,$acc01
rlwinm $acc08,$s2,`32-8+3`,21,28
+ lwzx $acc01,$Tbl0,$acc01
rlwinm $acc09,$s3,`32-8+3`,21,28
lwzx $acc02,$Tbl0,$acc02
- lwzx $acc03,$Tbl0,$acc03
rlwinm $acc10,$s0,`32-8+3`,21,28
+ lwzx $acc03,$Tbl0,$acc03
rlwinm $acc11,$s1,`32-8+3`,21,28
lwzx $acc04,$Tbl1,$acc04
- lwzx $acc05,$Tbl1,$acc05
rlwinm $acc12,$s3,`0+3`,21,28
+ lwzx $acc05,$Tbl1,$acc05
rlwinm $acc13,$s0,`0+3`,21,28
lwzx $acc06,$Tbl1,$acc06
- lwzx $acc07,$Tbl1,$acc07
rlwinm $acc14,$s1,`0+3`,21,28
+ lwzx $acc07,$Tbl1,$acc07
rlwinm $acc15,$s2,`0+3`,21,28
lwzx $acc08,$Tbl2,$acc08
- lwzx $acc09,$Tbl2,$acc09
xor $t0,$t0,$acc00
+ lwzx $acc09,$Tbl2,$acc09
xor $t1,$t1,$acc01
lwzx $acc10,$Tbl2,$acc10
- lwzx $acc11,$Tbl2,$acc11
xor $t2,$t2,$acc02
+ lwzx $acc11,$Tbl2,$acc11
xor $t3,$t3,$acc03
lwzx $acc12,$Tbl3,$acc12
- lwzx $acc13,$Tbl3,$acc13
xor $t0,$t0,$acc04
+ lwzx $acc13,$Tbl3,$acc13
xor $t1,$t1,$acc05
lwzx $acc14,$Tbl3,$acc14
- lwzx $acc15,$Tbl3,$acc15
xor $t2,$t2,$acc06
+ lwzx $acc15,$Tbl3,$acc15
xor $t3,$t3,$acc07
xor $t0,$t0,$acc08
xor $t1,$t1,$acc09
@@ -466,60 +553,60 @@ Lenc_loop:
addi $Tbl2,$Tbl0,2048
nop
lwz $t0,0($key)
- lwz $t1,4($key)
rlwinm $acc00,$s0,`32-24`,24,31
+ lwz $t1,4($key)
rlwinm $acc01,$s1,`32-24`,24,31
lwz $t2,8($key)
- lwz $t3,12($key)
rlwinm $acc02,$s2,`32-24`,24,31
+ lwz $t3,12($key)
rlwinm $acc03,$s3,`32-24`,24,31
lwz $acc08,`2048+0`($Tbl0) ! prefetch Te4
- lwz $acc09,`2048+32`($Tbl0)
rlwinm $acc04,$s1,`32-16`,24,31
+ lwz $acc09,`2048+32`($Tbl0)
rlwinm $acc05,$s2,`32-16`,24,31
lwz $acc10,`2048+64`($Tbl0)
- lwz $acc11,`2048+96`($Tbl0)
rlwinm $acc06,$s3,`32-16`,24,31
+ lwz $acc11,`2048+96`($Tbl0)
rlwinm $acc07,$s0,`32-16`,24,31
lwz $acc12,`2048+128`($Tbl0)
- lwz $acc13,`2048+160`($Tbl0)
rlwinm $acc08,$s2,`32-8`,24,31
+ lwz $acc13,`2048+160`($Tbl0)
rlwinm $acc09,$s3,`32-8`,24,31
lwz $acc14,`2048+192`($Tbl0)
- lwz $acc15,`2048+224`($Tbl0)
rlwinm $acc10,$s0,`32-8`,24,31
+ lwz $acc15,`2048+224`($Tbl0)
rlwinm $acc11,$s1,`32-8`,24,31
lbzx $acc00,$Tbl2,$acc00
- lbzx $acc01,$Tbl2,$acc01
rlwinm $acc12,$s3,`0`,24,31
+ lbzx $acc01,$Tbl2,$acc01
rlwinm $acc13,$s0,`0`,24,31
lbzx $acc02,$Tbl2,$acc02
- lbzx $acc03,$Tbl2,$acc03
rlwinm $acc14,$s1,`0`,24,31
+ lbzx $acc03,$Tbl2,$acc03
rlwinm $acc15,$s2,`0`,24,31
lbzx $acc04,$Tbl2,$acc04
- lbzx $acc05,$Tbl2,$acc05
rlwinm $s0,$acc00,24,0,7
+ lbzx $acc05,$Tbl2,$acc05
rlwinm $s1,$acc01,24,0,7
lbzx $acc06,$Tbl2,$acc06
- lbzx $acc07,$Tbl2,$acc07
rlwinm $s2,$acc02,24,0,7
+ lbzx $acc07,$Tbl2,$acc07
rlwinm $s3,$acc03,24,0,7
lbzx $acc08,$Tbl2,$acc08
- lbzx $acc09,$Tbl2,$acc09
rlwimi $s0,$acc04,16,8,15
+ lbzx $acc09,$Tbl2,$acc09
rlwimi $s1,$acc05,16,8,15
lbzx $acc10,$Tbl2,$acc10
- lbzx $acc11,$Tbl2,$acc11
rlwimi $s2,$acc06,16,8,15
+ lbzx $acc11,$Tbl2,$acc11
rlwimi $s3,$acc07,16,8,15
lbzx $acc12,$Tbl2,$acc12
- lbzx $acc13,$Tbl2,$acc13
rlwimi $s0,$acc08,8,16,23
+ lbzx $acc13,$Tbl2,$acc13
rlwimi $s1,$acc09,8,16,23
lbzx $acc14,$Tbl2,$acc14
- lbzx $acc15,$Tbl2,$acc15
rlwimi $s2,$acc10,8,16,23
+ lbzx $acc15,$Tbl2,$acc15
rlwimi $s3,$acc11,8,16,23
or $s0,$s0,$acc12
or $s1,$s1,$acc13
@@ -530,29 +617,31 @@ Lenc_loop:
xor $s2,$s2,$t2
xor $s3,$s3,$t3
blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
.align 4
Lppc_AES_encrypt_compact:
lwz $acc00,240($key)
- lwz $t0,0($key)
- lwz $t1,4($key)
- lwz $t2,8($key)
- lwz $t3,12($key)
addi $Tbl1,$Tbl0,2048
+ lwz $t0,0($key)
lis $mask80,0x8080
+ lwz $t1,4($key)
lis $mask1b,0x1b1b
- addi $key,$key,16
+ lwz $t2,8($key)
ori $mask80,$mask80,0x8080
+ lwz $t3,12($key)
ori $mask1b,$mask1b,0x1b1b
+ addi $key,$key,16
mtctr $acc00
.align 4
Lenc_compact_loop:
xor $s0,$s0,$t0
xor $s1,$s1,$t1
- xor $s2,$s2,$t2
- xor $s3,$s3,$t3
rlwinm $acc00,$s0,`32-24`,24,31
+ xor $s2,$s2,$t2
rlwinm $acc01,$s1,`32-24`,24,31
+ xor $s3,$s3,$t3
rlwinm $acc02,$s2,`32-24`,24,31
rlwinm $acc03,$s3,`32-24`,24,31
rlwinm $acc04,$s1,`32-16`,24,31
@@ -560,48 +649,48 @@ Lenc_compact_loop:
rlwinm $acc06,$s3,`32-16`,24,31
rlwinm $acc07,$s0,`32-16`,24,31
lbzx $acc00,$Tbl1,$acc00
- lbzx $acc01,$Tbl1,$acc01
rlwinm $acc08,$s2,`32-8`,24,31
+ lbzx $acc01,$Tbl1,$acc01
rlwinm $acc09,$s3,`32-8`,24,31
lbzx $acc02,$Tbl1,$acc02
- lbzx $acc03,$Tbl1,$acc03
rlwinm $acc10,$s0,`32-8`,24,31
+ lbzx $acc03,$Tbl1,$acc03
rlwinm $acc11,$s1,`32-8`,24,31
lbzx $acc04,$Tbl1,$acc04
- lbzx $acc05,$Tbl1,$acc05
rlwinm $acc12,$s3,`0`,24,31
+ lbzx $acc05,$Tbl1,$acc05
rlwinm $acc13,$s0,`0`,24,31
lbzx $acc06,$Tbl1,$acc06
- lbzx $acc07,$Tbl1,$acc07
rlwinm $acc14,$s1,`0`,24,31
+ lbzx $acc07,$Tbl1,$acc07
rlwinm $acc15,$s2,`0`,24,31
lbzx $acc08,$Tbl1,$acc08
- lbzx $acc09,$Tbl1,$acc09
rlwinm $s0,$acc00,24,0,7
+ lbzx $acc09,$Tbl1,$acc09
rlwinm $s1,$acc01,24,0,7
lbzx $acc10,$Tbl1,$acc10
- lbzx $acc11,$Tbl1,$acc11
rlwinm $s2,$acc02,24,0,7
+ lbzx $acc11,$Tbl1,$acc11
rlwinm $s3,$acc03,24,0,7
lbzx $acc12,$Tbl1,$acc12
- lbzx $acc13,$Tbl1,$acc13
rlwimi $s0,$acc04,16,8,15
+ lbzx $acc13,$Tbl1,$acc13
rlwimi $s1,$acc05,16,8,15
lbzx $acc14,$Tbl1,$acc14
- lbzx $acc15,$Tbl1,$acc15
rlwimi $s2,$acc06,16,8,15
+ lbzx $acc15,$Tbl1,$acc15
rlwimi $s3,$acc07,16,8,15
rlwimi $s0,$acc08,8,16,23
rlwimi $s1,$acc09,8,16,23
rlwimi $s2,$acc10,8,16,23
rlwimi $s3,$acc11,8,16,23
lwz $t0,0($key)
- lwz $t1,4($key)
or $s0,$s0,$acc12
+ lwz $t1,4($key)
or $s1,$s1,$acc13
lwz $t2,8($key)
- lwz $t3,12($key)
or $s2,$s2,$acc14
+ lwz $t3,12($key)
or $s3,$s3,$acc15
addi $key,$key,16
@@ -612,12 +701,12 @@ Lenc_compact_loop:
and $acc02,$s2,$mask80
and $acc03,$s3,$mask80
srwi $acc04,$acc00,7 # r1>>7
- srwi $acc05,$acc01,7
- srwi $acc06,$acc02,7
- srwi $acc07,$acc03,7
andc $acc08,$s0,$mask80 # r0&0x7f7f7f7f
+ srwi $acc05,$acc01,7
andc $acc09,$s1,$mask80
+ srwi $acc06,$acc02,7
andc $acc10,$s2,$mask80
+ srwi $acc07,$acc03,7
andc $acc11,$s3,$mask80
sub $acc00,$acc00,$acc04 # r1-(r1>>7)
sub $acc01,$acc01,$acc05
@@ -633,32 +722,32 @@ Lenc_compact_loop:
and $acc03,$acc03,$mask1b
xor $acc00,$acc00,$acc08 # r2
xor $acc01,$acc01,$acc09
+ rotlwi $acc12,$s0,16 # ROTATE(r0,16)
xor $acc02,$acc02,$acc10
+ rotlwi $acc13,$s1,16
xor $acc03,$acc03,$acc11
+ rotlwi $acc14,$s2,16
- rotlwi $acc12,$s0,16 # ROTATE(r0,16)
- rotlwi $acc13,$s1,16
- rotlwi $acc14,$s2,16
- rotlwi $acc15,$s3,16
xor $s0,$s0,$acc00 # r0^r2
+ rotlwi $acc15,$s3,16
xor $s1,$s1,$acc01
- xor $s2,$s2,$acc02
- xor $s3,$s3,$acc03
rotrwi $s0,$s0,24 # ROTATE(r2^r0,24)
+ xor $s2,$s2,$acc02
rotrwi $s1,$s1,24
+ xor $s3,$s3,$acc03
rotrwi $s2,$s2,24
- rotrwi $s3,$s3,24
xor $s0,$s0,$acc00 # ROTATE(r2^r0,24)^r2
+ rotrwi $s3,$s3,24
xor $s1,$s1,$acc01
xor $s2,$s2,$acc02
xor $s3,$s3,$acc03
rotlwi $acc08,$acc12,8 # ROTATE(r0,24)
- rotlwi $acc09,$acc13,8
- rotlwi $acc10,$acc14,8
- rotlwi $acc11,$acc15,8
xor $s0,$s0,$acc12 #
+ rotlwi $acc09,$acc13,8
xor $s1,$s1,$acc13
+ rotlwi $acc10,$acc14,8
xor $s2,$s2,$acc14
+ rotlwi $acc11,$acc15,8
xor $s3,$s3,$acc15
xor $s0,$s0,$acc08 #
xor $s1,$s1,$acc09
@@ -673,14 +762,15 @@ Lenc_compact_done:
xor $s2,$s2,$t2
xor $s3,$s3,$t3
blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
.globl .AES_decrypt
.align 7
.AES_decrypt:
- mflr r0
$STU $sp,-$FRAME($sp)
+ mflr r0
- $PUSH r0,`$FRAME-$SIZE_T*21`($sp)
$PUSH $toc,`$FRAME-$SIZE_T*20`($sp)
$PUSH r13,`$FRAME-$SIZE_T*19`($sp)
$PUSH r14,`$FRAME-$SIZE_T*18`($sp)
@@ -701,7 +791,14 @@ Lenc_compact_done:
$PUSH r29,`$FRAME-$SIZE_T*3`($sp)
$PUSH r30,`$FRAME-$SIZE_T*2`($sp)
$PUSH r31,`$FRAME-$SIZE_T*1`($sp)
+ $PUSH r0,`$FRAME+$LRSAVE`($sp)
+ andi. $t0,$inp,3
+ andi. $t1,$out,3
+ or. $t0,$t0,$t1
+ bne Ldec_unaligned
+
+Ldec_unaligned_ok:
lwz $s0,0($inp)
lwz $s1,4($inp)
lwz $s2,8($inp)
@@ -712,8 +809,80 @@ Lenc_compact_done:
stw $s1,4($out)
stw $s2,8($out)
stw $s3,12($out)
+ b Ldec_done
+
+Ldec_unaligned:
+ subfic $t0,$inp,4096
+ subfic $t1,$out,4096
+ andi. $t0,$t0,4096-16
+ beq Ldec_xpage
+ andi. $t1,$t1,4096-16
+ bne Ldec_unaligned_ok
+
+Ldec_xpage:
+ lbz $acc00,0($inp)
+ lbz $acc01,1($inp)
+ lbz $acc02,2($inp)
+ lbz $s0,3($inp)
+ lbz $acc04,4($inp)
+ lbz $acc05,5($inp)
+ lbz $acc06,6($inp)
+ lbz $s1,7($inp)
+ lbz $acc08,8($inp)
+ lbz $acc09,9($inp)
+ lbz $acc10,10($inp)
+ insrwi $s0,$acc00,8,0
+ lbz $s2,11($inp)
+ insrwi $s1,$acc04,8,0
+ lbz $acc12,12($inp)
+ insrwi $s0,$acc01,8,8
+ lbz $acc13,13($inp)
+ insrwi $s1,$acc05,8,8
+ lbz $acc14,14($inp)
+ insrwi $s0,$acc02,8,16
+ lbz $s3,15($inp)
+ insrwi $s1,$acc06,8,16
+ insrwi $s2,$acc08,8,0
+ insrwi $s3,$acc12,8,0
+ insrwi $s2,$acc09,8,8
+ insrwi $s3,$acc13,8,8
+ insrwi $s2,$acc10,8,16
+ insrwi $s3,$acc14,8,16
+
+ bl LAES_Td
+ bl Lppc_AES_decrypt_compact
- $POP r0,`$FRAME-$SIZE_T*21`($sp)
+ extrwi $acc00,$s0,8,0
+ extrwi $acc01,$s0,8,8
+ stb $acc00,0($out)
+ extrwi $acc02,$s0,8,16
+ stb $acc01,1($out)
+ stb $acc02,2($out)
+ extrwi $acc04,$s1,8,0
+ stb $s0,3($out)
+ extrwi $acc05,$s1,8,8
+ stb $acc04,4($out)
+ extrwi $acc06,$s1,8,16
+ stb $acc05,5($out)
+ stb $acc06,6($out)
+ extrwi $acc08,$s2,8,0
+ stb $s1,7($out)
+ extrwi $acc09,$s2,8,8
+ stb $acc08,8($out)
+ extrwi $acc10,$s2,8,16
+ stb $acc09,9($out)
+ stb $acc10,10($out)
+ extrwi $acc12,$s3,8,0
+ stb $s2,11($out)
+ extrwi $acc13,$s3,8,8
+ stb $acc12,12($out)
+ extrwi $acc14,$s3,8,16
+ stb $acc13,13($out)
+ stb $acc14,14($out)
+ stb $s3,15($out)
+
+Ldec_done:
+ $POP r0,`$FRAME+$LRSAVE`($sp)
$POP $toc,`$FRAME-$SIZE_T*20`($sp)
$POP r13,`$FRAME-$SIZE_T*19`($sp)
$POP r14,`$FRAME-$SIZE_T*18`($sp)
@@ -737,18 +906,21 @@ Lenc_compact_done:
mtlr r0
addi $sp,$sp,$FRAME
blr
+ .long 0
+ .byte 0,12,4,1,0x80,18,3,0
+ .long 0
.align 5
Lppc_AES_decrypt:
lwz $acc00,240($key)
- lwz $t0,0($key)
- lwz $t1,4($key)
- lwz $t2,8($key)
- lwz $t3,12($key)
addi $Tbl1,$Tbl0,3
+ lwz $t0,0($key)
addi $Tbl2,$Tbl0,2
+ lwz $t1,4($key)
addi $Tbl3,$Tbl0,1
+ lwz $t2,8($key)
addi $acc00,$acc00,-1
+ lwz $t3,12($key)
addi $key,$key,16
xor $s0,$s0,$t0
xor $s1,$s1,$t1
@@ -762,44 +934,44 @@ Ldec_loop:
rlwinm $acc02,$s2,`32-24+3`,21,28
rlwinm $acc03,$s3,`32-24+3`,21,28
lwz $t0,0($key)
- lwz $t1,4($key)
rlwinm $acc04,$s3,`32-16+3`,21,28
+ lwz $t1,4($key)
rlwinm $acc05,$s0,`32-16+3`,21,28
lwz $t2,8($key)
- lwz $t3,12($key)
rlwinm $acc06,$s1,`32-16+3`,21,28
+ lwz $t3,12($key)
rlwinm $acc07,$s2,`32-16+3`,21,28
lwzx $acc00,$Tbl0,$acc00
- lwzx $acc01,$Tbl0,$acc01
rlwinm $acc08,$s2,`32-8+3`,21,28
+ lwzx $acc01,$Tbl0,$acc01
rlwinm $acc09,$s3,`32-8+3`,21,28
lwzx $acc02,$Tbl0,$acc02
- lwzx $acc03,$Tbl0,$acc03
rlwinm $acc10,$s0,`32-8+3`,21,28
+ lwzx $acc03,$Tbl0,$acc03
rlwinm $acc11,$s1,`32-8+3`,21,28
lwzx $acc04,$Tbl1,$acc04
- lwzx $acc05,$Tbl1,$acc05
rlwinm $acc12,$s1,`0+3`,21,28
+ lwzx $acc05,$Tbl1,$acc05
rlwinm $acc13,$s2,`0+3`,21,28
lwzx $acc06,$Tbl1,$acc06
- lwzx $acc07,$Tbl1,$acc07
rlwinm $acc14,$s3,`0+3`,21,28
+ lwzx $acc07,$Tbl1,$acc07
rlwinm $acc15,$s0,`0+3`,21,28
lwzx $acc08,$Tbl2,$acc08
- lwzx $acc09,$Tbl2,$acc09
xor $t0,$t0,$acc00
+ lwzx $acc09,$Tbl2,$acc09
xor $t1,$t1,$acc01
lwzx $acc10,$Tbl2,$acc10
- lwzx $acc11,$Tbl2,$acc11
xor $t2,$t2,$acc02
+ lwzx $acc11,$Tbl2,$acc11
xor $t3,$t3,$acc03
lwzx $acc12,$Tbl3,$acc12
- lwzx $acc13,$Tbl3,$acc13
xor $t0,$t0,$acc04
+ lwzx $acc13,$Tbl3,$acc13
xor $t1,$t1,$acc05
lwzx $acc14,$Tbl3,$acc14
- lwzx $acc15,$Tbl3,$acc15
xor $t2,$t2,$acc06
+ lwzx $acc15,$Tbl3,$acc15
xor $t3,$t3,$acc07
xor $t0,$t0,$acc08
xor $t1,$t1,$acc09
@@ -815,56 +987,56 @@ Ldec_loop:
addi $Tbl2,$Tbl0,2048
nop
lwz $t0,0($key)
- lwz $t1,4($key)
rlwinm $acc00,$s0,`32-24`,24,31
+ lwz $t1,4($key)
rlwinm $acc01,$s1,`32-24`,24,31
lwz $t2,8($key)
- lwz $t3,12($key)
rlwinm $acc02,$s2,`32-24`,24,31
+ lwz $t3,12($key)
rlwinm $acc03,$s3,`32-24`,24,31
lwz $acc08,`2048+0`($Tbl0) ! prefetch Td4
- lwz $acc09,`2048+32`($Tbl0)
rlwinm $acc04,$s3,`32-16`,24,31
+ lwz $acc09,`2048+32`($Tbl0)
rlwinm $acc05,$s0,`32-16`,24,31
lwz $acc10,`2048+64`($Tbl0)
- lwz $acc11,`2048+96`($Tbl0)
lbzx $acc00,$Tbl2,$acc00
+ lwz $acc11,`2048+96`($Tbl0)
lbzx $acc01,$Tbl2,$acc01
lwz $acc12,`2048+128`($Tbl0)
- lwz $acc13,`2048+160`($Tbl0)
rlwinm $acc06,$s1,`32-16`,24,31
+ lwz $acc13,`2048+160`($Tbl0)
rlwinm $acc07,$s2,`32-16`,24,31
lwz $acc14,`2048+192`($Tbl0)
- lwz $acc15,`2048+224`($Tbl0)
rlwinm $acc08,$s2,`32-8`,24,31
+ lwz $acc15,`2048+224`($Tbl0)
rlwinm $acc09,$s3,`32-8`,24,31
lbzx $acc02,$Tbl2,$acc02
- lbzx $acc03,$Tbl2,$acc03
rlwinm $acc10,$s0,`32-8`,24,31
+ lbzx $acc03,$Tbl2,$acc03
rlwinm $acc11,$s1,`32-8`,24,31
lbzx $acc04,$Tbl2,$acc04
- lbzx $acc05,$Tbl2,$acc05
rlwinm $acc12,$s1,`0`,24,31
+ lbzx $acc05,$Tbl2,$acc05
rlwinm $acc13,$s2,`0`,24,31
lbzx $acc06,$Tbl2,$acc06
- lbzx $acc07,$Tbl2,$acc07
rlwinm $acc14,$s3,`0`,24,31
+ lbzx $acc07,$Tbl2,$acc07
rlwinm $acc15,$s0,`0`,24,31
lbzx $acc08,$Tbl2,$acc08
- lbzx $acc09,$Tbl2,$acc09
rlwinm $s0,$acc00,24,0,7
+ lbzx $acc09,$Tbl2,$acc09
rlwinm $s1,$acc01,24,0,7
lbzx $acc10,$Tbl2,$acc10
- lbzx $acc11,$Tbl2,$acc11
rlwinm $s2,$acc02,24,0,7
+ lbzx $acc11,$Tbl2,$acc11
rlwinm $s3,$acc03,24,0,7
lbzx $acc12,$Tbl2,$acc12
- lbzx $acc13,$Tbl2,$acc13
rlwimi $s0,$acc04,16,8,15
+ lbzx $acc13,$Tbl2,$acc13
rlwimi $s1,$acc05,16,8,15
lbzx $acc14,$Tbl2,$acc14
- lbzx $acc15,$Tbl2,$acc15
rlwimi $s2,$acc06,16,8,15
+ lbzx $acc15,$Tbl2,$acc15
rlwimi $s3,$acc07,16,8,15
rlwimi $s0,$acc08,8,16,23
rlwimi $s1,$acc09,8,16,23
@@ -879,20 +1051,22 @@ Ldec_loop:
xor $s2,$s2,$t2
xor $s3,$s3,$t3
blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
.align 4
Lppc_AES_decrypt_compact:
lwz $acc00,240($key)
- lwz $t0,0($key)
- lwz $t1,4($key)
- lwz $t2,8($key)
- lwz $t3,12($key)
addi $Tbl1,$Tbl0,2048
+ lwz $t0,0($key)
lis $mask80,0x8080
+ lwz $t1,4($key)
lis $mask1b,0x1b1b
- addi $key,$key,16
+ lwz $t2,8($key)
ori $mask80,$mask80,0x8080
+ lwz $t3,12($key)
ori $mask1b,$mask1b,0x1b1b
+ addi $key,$key,16
___
$code.=<<___ if ($SIZE_T==8);
insrdi $mask80,$mask80,32,0
@@ -904,10 +1078,10 @@ $code.=<<___;
Ldec_compact_loop:
xor $s0,$s0,$t0
xor $s1,$s1,$t1
- xor $s2,$s2,$t2
- xor $s3,$s3,$t3
rlwinm $acc00,$s0,`32-24`,24,31
+ xor $s2,$s2,$t2
rlwinm $acc01,$s1,`32-24`,24,31
+ xor $s3,$s3,$t3
rlwinm $acc02,$s2,`32-24`,24,31
rlwinm $acc03,$s3,`32-24`,24,31
rlwinm $acc04,$s3,`32-16`,24,31
@@ -915,48 +1089,48 @@ Ldec_compact_loop:
rlwinm $acc06,$s1,`32-16`,24,31
rlwinm $acc07,$s2,`32-16`,24,31
lbzx $acc00,$Tbl1,$acc00
- lbzx $acc01,$Tbl1,$acc01
rlwinm $acc08,$s2,`32-8`,24,31
+ lbzx $acc01,$Tbl1,$acc01
rlwinm $acc09,$s3,`32-8`,24,31
lbzx $acc02,$Tbl1,$acc02
- lbzx $acc03,$Tbl1,$acc03
rlwinm $acc10,$s0,`32-8`,24,31
+ lbzx $acc03,$Tbl1,$acc03
rlwinm $acc11,$s1,`32-8`,24,31
lbzx $acc04,$Tbl1,$acc04
- lbzx $acc05,$Tbl1,$acc05
rlwinm $acc12,$s1,`0`,24,31
+ lbzx $acc05,$Tbl1,$acc05
rlwinm $acc13,$s2,`0`,24,31
lbzx $acc06,$Tbl1,$acc06
- lbzx $acc07,$Tbl1,$acc07
rlwinm $acc14,$s3,`0`,24,31
+ lbzx $acc07,$Tbl1,$acc07
rlwinm $acc15,$s0,`0`,24,31
lbzx $acc08,$Tbl1,$acc08
- lbzx $acc09,$Tbl1,$acc09
rlwinm $s0,$acc00,24,0,7
+ lbzx $acc09,$Tbl1,$acc09
rlwinm $s1,$acc01,24,0,7
lbzx $acc10,$Tbl1,$acc10
- lbzx $acc11,$Tbl1,$acc11
rlwinm $s2,$acc02,24,0,7
+ lbzx $acc11,$Tbl1,$acc11
rlwinm $s3,$acc03,24,0,7
lbzx $acc12,$Tbl1,$acc12
- lbzx $acc13,$Tbl1,$acc13
rlwimi $s0,$acc04,16,8,15
+ lbzx $acc13,$Tbl1,$acc13
rlwimi $s1,$acc05,16,8,15
lbzx $acc14,$Tbl1,$acc14
- lbzx $acc15,$Tbl1,$acc15
rlwimi $s2,$acc06,16,8,15
+ lbzx $acc15,$Tbl1,$acc15
rlwimi $s3,$acc07,16,8,15
rlwimi $s0,$acc08,8,16,23
rlwimi $s1,$acc09,8,16,23
rlwimi $s2,$acc10,8,16,23
rlwimi $s3,$acc11,8,16,23
lwz $t0,0($key)
- lwz $t1,4($key)
or $s0,$s0,$acc12
+ lwz $t1,4($key)
or $s1,$s1,$acc13
lwz $t2,8($key)
- lwz $t3,12($key)
or $s2,$s2,$acc14
+ lwz $t3,12($key)
or $s3,$s3,$acc15
addi $key,$key,16
@@ -1030,12 +1204,12 @@ $code.=<<___ if ($SIZE_T==4);
and $acc02,$s2,$mask80
and $acc03,$s3,$mask80
srwi $acc04,$acc00,7 # r1>>7
- srwi $acc05,$acc01,7
- srwi $acc06,$acc02,7
- srwi $acc07,$acc03,7
andc $acc08,$s0,$mask80 # r0&0x7f7f7f7f
+ srwi $acc05,$acc01,7
andc $acc09,$s1,$mask80
+ srwi $acc06,$acc02,7
andc $acc10,$s2,$mask80
+ srwi $acc07,$acc03,7
andc $acc11,$s3,$mask80
sub $acc00,$acc00,$acc04 # r1-(r1>>7)
sub $acc01,$acc01,$acc05
@@ -1059,12 +1233,12 @@ $code.=<<___ if ($SIZE_T==4);
and $acc06,$acc02,$mask80
and $acc07,$acc03,$mask80
srwi $acc08,$acc04,7 # r1>>7
- srwi $acc09,$acc05,7
- srwi $acc10,$acc06,7
- srwi $acc11,$acc07,7
andc $acc12,$acc00,$mask80 # r2&0x7f7f7f7f
+ srwi $acc09,$acc05,7
andc $acc13,$acc01,$mask80
+ srwi $acc10,$acc06,7
andc $acc14,$acc02,$mask80
+ srwi $acc11,$acc07,7
andc $acc15,$acc03,$mask80
sub $acc04,$acc04,$acc08 # r1-(r1>>7)
sub $acc05,$acc05,$acc09
@@ -1085,13 +1259,13 @@ $code.=<<___ if ($SIZE_T==4);
and $acc08,$acc04,$mask80 # r1=r4&0x80808080
and $acc09,$acc05,$mask80
- and $acc10,$acc06,$mask80
- and $acc11,$acc07,$mask80
srwi $acc12,$acc08,7 # r1>>7
+ and $acc10,$acc06,$mask80
srwi $acc13,$acc09,7
+ and $acc11,$acc07,$mask80
srwi $acc14,$acc10,7
- srwi $acc15,$acc11,7
sub $acc08,$acc08,$acc12 # r1-(r1>>7)
+ srwi $acc15,$acc11,7
sub $acc09,$acc09,$acc13
sub $acc10,$acc10,$acc14
sub $acc11,$acc11,$acc15
@@ -1124,10 +1298,10 @@ ___
$code.=<<___;
rotrwi $s0,$s0,8 # = ROTATE(r0,8)
rotrwi $s1,$s1,8
- rotrwi $s2,$s2,8
- rotrwi $s3,$s3,8
xor $s0,$s0,$acc00 # ^= r2^r0
+ rotrwi $s2,$s2,8
xor $s1,$s1,$acc01
+ rotrwi $s3,$s3,8
xor $s2,$s2,$acc02
xor $s3,$s3,$acc03
xor $acc00,$acc00,$acc08
@@ -1135,32 +1309,32 @@ $code.=<<___;
xor $acc02,$acc02,$acc10
xor $acc03,$acc03,$acc11
xor $s0,$s0,$acc04 # ^= r4^r0
- xor $s1,$s1,$acc05
- xor $s2,$s2,$acc06
- xor $s3,$s3,$acc07
rotrwi $acc00,$acc00,24
+ xor $s1,$s1,$acc05
rotrwi $acc01,$acc01,24
+ xor $s2,$s2,$acc06
rotrwi $acc02,$acc02,24
+ xor $s3,$s3,$acc07
rotrwi $acc03,$acc03,24
xor $acc04,$acc04,$acc08
xor $acc05,$acc05,$acc09
xor $acc06,$acc06,$acc10
xor $acc07,$acc07,$acc11
xor $s0,$s0,$acc08 # ^= r8 [^((r4^r0)^(r2^r0)=r4^r2)]
- xor $s1,$s1,$acc09
- xor $s2,$s2,$acc10
- xor $s3,$s3,$acc11
rotrwi $acc04,$acc04,16
+ xor $s1,$s1,$acc09
rotrwi $acc05,$acc05,16
+ xor $s2,$s2,$acc10
rotrwi $acc06,$acc06,16
+ xor $s3,$s3,$acc11
rotrwi $acc07,$acc07,16
xor $s0,$s0,$acc00 # ^= ROTATE(r8^r2^r0,24)
- xor $s1,$s1,$acc01
- xor $s2,$s2,$acc02
- xor $s3,$s3,$acc03
rotrwi $acc08,$acc08,8
+ xor $s1,$s1,$acc01
rotrwi $acc09,$acc09,8
+ xor $s2,$s2,$acc02
rotrwi $acc10,$acc10,8
+ xor $s3,$s3,$acc03
rotrwi $acc11,$acc11,8
xor $s0,$s0,$acc04 # ^= ROTATE(r8^r4^r0,16)
xor $s1,$s1,$acc05
@@ -1179,7 +1353,9 @@ Ldec_compact_done:
xor $s2,$s2,$t2
xor $s3,$s3,$t3
blr
-.long 0
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
+
.asciz "AES for PPC, CRYPTOGAMS by <appro\@openssl.org>"
.align 7
___
diff --git a/deps/openssl/openssl/crypto/aes/asm/aes-s390x.pl b/deps/openssl/openssl/crypto/aes/asm/aes-s390x.pl
index 7e0188929..e75dcd031 100644
--- a/deps/openssl/openssl/crypto/aes/asm/aes-s390x.pl
+++ b/deps/openssl/openssl/crypto/aes/asm/aes-s390x.pl
@@ -44,12 +44,57 @@
# Unlike previous version hardware support detection takes place only
# at the moment of key schedule setup, which is denoted in key->rounds.
# This is done, because deferred key setup can't be made MT-safe, not
-# for key lengthes longer than 128 bits.
+# for keys longer than 128 bits.
#
# Add AES_cbc_encrypt, which gives incredible performance improvement,
# it was measured to be ~6.6x. It's less than previously mentioned 8x,
# because software implementation was optimized.
+# May 2010.
+#
+# Add AES_ctr32_encrypt. If hardware-assisted, it provides up to 4.3x
+# performance improvement over "generic" counter mode routine relying
+# on single-block, also hardware-assisted, AES_encrypt. "Up to" refers
+# to the fact that exact throughput value depends on current stack
+# frame alignment within 4KB page. In worst case you get ~75% of the
+# maximum, but *on average* it would be as much as ~98%. Meaning that
+# worst case is unlike, it's like hitting ravine on plateau.
+
+# November 2010.
+#
+# Adapt for -m31 build. If kernel supports what's called "highgprs"
+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
+# instructions and achieve "64-bit" performance even in 31-bit legacy
+# application context. The feature is not specific to any particular
+# processor, as long as it's "z-CPU". Latter implies that the code
+# remains z/Architecture specific. On z990 it was measured to perform
+# 2x better than code generated by gcc 4.3.
+
+# December 2010.
+#
+# Add support for z196 "cipher message with counter" instruction.
+# Note however that it's disengaged, because it was measured to
+# perform ~12% worse than vanilla km-based code...
+
+# February 2011.
+#
+# Add AES_xts_[en|de]crypt. This includes support for z196 km-xts-aes
+# instructions, which deliver ~70% improvement at 8KB block size over
+# vanilla km-based code, 37% - at most like 512-bytes block size.
+
+$flavour = shift;
+
+if ($flavour =~ /3[12]/) {
+ $SIZE_T=4;
+ $g="";
+} else {
+ $SIZE_T=8;
+ $g="g";
+}
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
$softonly=0; # allow hardware support
$t0="%r0"; $mask="%r0";
@@ -69,6 +114,8 @@ $rounds="%r13";
$ra="%r14";
$sp="%r15";
+$stdframe=16*$SIZE_T+4*8;
+
sub _data_word()
{ my $i;
while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
@@ -210,7 +257,7 @@ $code.=<<___ if (!$softonly);
.Lesoft:
___
$code.=<<___;
- stmg %r3,$ra,24($sp)
+ stm${g} %r3,$ra,3*$SIZE_T($sp)
llgf $s0,0($inp)
llgf $s1,4($inp)
@@ -220,20 +267,20 @@ $code.=<<___;
larl $tbl,AES_Te
bras $ra,_s390x_AES_encrypt
- lg $out,24($sp)
+ l${g} $out,3*$SIZE_T($sp)
st $s0,0($out)
st $s1,4($out)
st $s2,8($out)
st $s3,12($out)
- lmg %r6,$ra,48($sp)
+ lm${g} %r6,$ra,6*$SIZE_T($sp)
br $ra
.size AES_encrypt,.-AES_encrypt
.type _s390x_AES_encrypt,\@function
.align 16
_s390x_AES_encrypt:
- stg $ra,152($sp)
+ st${g} $ra,15*$SIZE_T($sp)
x $s0,0($key)
x $s1,4($key)
x $s2,8($key)
@@ -397,7 +444,7 @@ _s390x_AES_encrypt:
or $s2,$i3
or $s3,$t3
- lg $ra,152($sp)
+ l${g} $ra,15*$SIZE_T($sp)
xr $s0,$t0
xr $s1,$t2
x $s2,24($key)
@@ -536,7 +583,7 @@ $code.=<<___ if (!$softonly);
.Ldsoft:
___
$code.=<<___;
- stmg %r3,$ra,24($sp)
+ stm${g} %r3,$ra,3*$SIZE_T($sp)
llgf $s0,0($inp)
llgf $s1,4($inp)
@@ -546,20 +593,20 @@ $code.=<<___;
larl $tbl,AES_Td
bras $ra,_s390x_AES_decrypt
- lg $out,24($sp)
+ l${g} $out,3*$SIZE_T($sp)
st $s0,0($out)
st $s1,4($out)
st $s2,8($out)
st $s3,12($out)
- lmg %r6,$ra,48($sp)
+ lm${g} %r6,$ra,6*$SIZE_T($sp)
br $ra
.size AES_decrypt,.-AES_decrypt
.type _s390x_AES_decrypt,\@function
.align 16
_s390x_AES_decrypt:
- stg $ra,152($sp)
+ st${g} $ra,15*$SIZE_T($sp)
x $s0,0($key)
x $s1,4($key)
x $s2,8($key)
@@ -703,7 +750,7 @@ _s390x_AES_decrypt:
nr $i1,$mask
nr $i2,$mask
- lg $ra,152($sp)
+ l${g} $ra,15*$SIZE_T($sp)
or $s1,$t1
l $t0,16($key)
l $t1,20($key)
@@ -732,14 +779,15 @@ ___
$code.=<<___;
# void AES_set_encrypt_key(const unsigned char *in, int bits,
# AES_KEY *key) {
-.globl AES_set_encrypt_key
-.type AES_set_encrypt_key,\@function
+.globl private_AES_set_encrypt_key
+.type private_AES_set_encrypt_key,\@function
.align 16
-AES_set_encrypt_key:
+private_AES_set_encrypt_key:
+_s390x_AES_set_encrypt_key:
lghi $t0,0
- clgr $inp,$t0
+ cl${g}r $inp,$t0
je .Lminus1
- clgr $key,$t0
+ cl${g}r $key,$t0
je .Lminus1
lghi $t0,128
@@ -789,7 +837,8 @@ $code.=<<___ if (!$softonly);
je 1f
lg %r1,24($inp)
stg %r1,24($key)
-1: st $bits,236($key) # save bits
+1: st $bits,236($key) # save bits [for debugging purposes]
+ lgr $t0,%r5
st %r5,240($key) # save km code
lghi %r2,0
br %r14
@@ -797,7 +846,7 @@ ___
$code.=<<___;
.align 16
.Lekey_internal:
- stmg %r6,%r13,48($sp) # all non-volatile regs
+ stm${g} %r4,%r13,4*$SIZE_T($sp) # all non-volatile regs and $key
larl $tbl,AES_Te+2048
@@ -857,8 +906,9 @@ $code.=<<___;
la $key,16($key) # key+=4
la $t3,4($t3) # i++
brct $rounds,.L128_loop
+ lghi $t0,10
lghi %r2,0
- lmg %r6,%r13,48($sp)
+ lm${g} %r4,%r13,4*$SIZE_T($sp)
br $ra
.align 16
@@ -905,8 +955,9 @@ $code.=<<___;
st $s2,32($key)
st $s3,36($key)
brct $rounds,.L192_continue
+ lghi $t0,12
lghi %r2,0
- lmg %r6,%r13,48($sp)
+ lm${g} %r4,%r13,4*$SIZE_T($sp)
br $ra
.align 16
@@ -967,8 +1018,9 @@ $code.=<<___;
st $s2,40($key)
st $s3,44($key)
brct $rounds,.L256_continue
+ lghi $t0,14
lghi %r2,0
- lmg %r6,%r13,48($sp)
+ lm${g} %r4,%r13,4*$SIZE_T($sp)
br $ra
.align 16
@@ -1011,42 +1063,34 @@ $code.=<<___;
.Lminus1:
lghi %r2,-1
br $ra
-.size AES_set_encrypt_key,.-AES_set_encrypt_key
+.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
# void AES_set_decrypt_key(const unsigned char *in, int bits,
# AES_KEY *key) {
-.globl AES_set_decrypt_key
-.type AES_set_decrypt_key,\@function
+.globl private_AES_set_decrypt_key
+.type private_AES_set_decrypt_key,\@function
.align 16
-AES_set_decrypt_key:
- stg $key,32($sp) # I rely on AES_set_encrypt_key to
- stg $ra,112($sp) # save non-volatile registers!
- bras $ra,AES_set_encrypt_key
- lg $key,32($sp)
- lg $ra,112($sp)
+private_AES_set_decrypt_key:
+ #st${g} $key,4*$SIZE_T($sp) # I rely on AES_set_encrypt_key to
+ st${g} $ra,14*$SIZE_T($sp) # save non-volatile registers and $key!
+ bras $ra,_s390x_AES_set_encrypt_key
+ #l${g} $key,4*$SIZE_T($sp)
+ l${g} $ra,14*$SIZE_T($sp)
ltgr %r2,%r2
bnzr $ra
___
$code.=<<___ if (!$softonly);
- l $t0,240($key)
+ #l $t0,240($key)
lhi $t1,16
cr $t0,$t1
jl .Lgo
oill $t0,0x80 # set "decrypt" bit
st $t0,240($key)
br $ra
-
-.align 16
-.Ldkey_internal:
- stg $key,32($sp)
- stg $ra,40($sp)
- bras $ra,.Lekey_internal
- lg $key,32($sp)
- lg $ra,40($sp)
___
$code.=<<___;
-
-.Lgo: llgf $rounds,240($key)
+.align 16
+.Lgo: lgr $rounds,$t0 #llgf $rounds,240($key)
la $i1,0($key)
sllg $i2,$rounds,4
la $i2,0($i2,$key)
@@ -1123,13 +1167,14 @@ $code.=<<___;
la $key,4($key)
brct $rounds,.Lmix
- lmg %r6,%r13,48($sp)# as was saved by AES_set_encrypt_key!
+ lm${g} %r6,%r13,6*$SIZE_T($sp)# as was saved by AES_set_encrypt_key!
lghi %r2,0
br $ra
-.size AES_set_decrypt_key,.-AES_set_decrypt_key
+.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
___
-#void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+########################################################################
+# void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
# size_t length, const AES_KEY *key,
# unsigned char *ivec, const int enc)
{
@@ -1163,7 +1208,7 @@ $code.=<<___ if (!$softonly);
l %r0,240($key) # load kmc code
lghi $key,15 # res=len%16, len-=res;
ngr $key,$len
- slgr $len,$key
+ sl${g}r $len,$key
la %r1,16($sp) # parameter block - ivec || key
jz .Lkmc_truncated
.long 0xb92f0042 # kmc %r4,%r2
@@ -1181,34 +1226,34 @@ $code.=<<___ if (!$softonly);
tmll %r0,0x80
jnz .Lkmc_truncated_dec
lghi %r1,0
- stg %r1,128($sp)
- stg %r1,136($sp)
+ stg %r1,16*$SIZE_T($sp)
+ stg %r1,16*$SIZE_T+8($sp)
bras %r1,1f
- mvc 128(1,$sp),0($inp)
+ mvc 16*$SIZE_T(1,$sp),0($inp)
1: ex $key,0(%r1)
la %r1,16($sp) # restore parameter block
- la $inp,128($sp)
+ la $inp,16*$SIZE_T($sp)
lghi $len,16
.long 0xb92f0042 # kmc %r4,%r2
j .Lkmc_done
.align 16
.Lkmc_truncated_dec:
- stg $out,64($sp)
- la $out,128($sp)
+ st${g} $out,4*$SIZE_T($sp)
+ la $out,16*$SIZE_T($sp)
lghi $len,16
.long 0xb92f0042 # kmc %r4,%r2
- lg $out,64($sp)
+ l${g} $out,4*$SIZE_T($sp)
bras %r1,2f
- mvc 0(1,$out),128($sp)
+ mvc 0(1,$out),16*$SIZE_T($sp)
2: ex $key,0(%r1)
j .Lkmc_done
.align 16
.Lcbc_software:
___
$code.=<<___;
- stmg $key,$ra,40($sp)
+ stm${g} $key,$ra,5*$SIZE_T($sp)
lhi %r0,0
- cl %r0,164($sp)
+ cl %r0,`$stdframe+$SIZE_T-4`($sp)
je .Lcbc_decrypt
larl $tbl,AES_Te
@@ -1219,10 +1264,10 @@ $code.=<<___;
llgf $s3,12($ivp)
lghi $t0,16
- slgr $len,$t0
+ sl${g}r $len,$t0
brc 4,.Lcbc_enc_tail # if borrow
.Lcbc_enc_loop:
- stmg $inp,$out,16($sp)
+ stm${g} $inp,$out,2*$SIZE_T($sp)
x $s0,0($inp)
x $s1,4($inp)
x $s2,8($inp)
@@ -1231,7 +1276,7 @@ $code.=<<___;
bras $ra,_s390x_AES_encrypt
- lmg $inp,$key,16($sp)
+ lm${g} $inp,$key,2*$SIZE_T($sp)
st $s0,0($out)
st $s1,4($out)
st $s2,8($out)
@@ -1240,33 +1285,33 @@ $code.=<<___;
la $inp,16($inp)
la $out,16($out)
lghi $t0,16
- ltgr $len,$len
+ lt${g}r $len,$len
jz .Lcbc_enc_done
- slgr $len,$t0
+ sl${g}r $len,$t0
brc 4,.Lcbc_enc_tail # if borrow
j .Lcbc_enc_loop
.align 16
.Lcbc_enc_done:
- lg $ivp,48($sp)
+ l${g} $ivp,6*$SIZE_T($sp)
st $s0,0($ivp)
st $s1,4($ivp)
st $s2,8($ivp)
st $s3,12($ivp)
- lmg %r7,$ra,56($sp)
+ lm${g} %r7,$ra,7*$SIZE_T($sp)
br $ra
.align 16
.Lcbc_enc_tail:
aghi $len,15
lghi $t0,0
- stg $t0,128($sp)
- stg $t0,136($sp)
+ stg $t0,16*$SIZE_T($sp)
+ stg $t0,16*$SIZE_T+8($sp)
bras $t1,3f
- mvc 128(1,$sp),0($inp)
+ mvc 16*$SIZE_T(1,$sp),0($inp)
3: ex $len,0($t1)
lghi $len,0
- la $inp,128($sp)
+ la $inp,16*$SIZE_T($sp)
j .Lcbc_enc_loop
.align 16
@@ -1275,10 +1320,10 @@ $code.=<<___;
lg $t0,0($ivp)
lg $t1,8($ivp)
- stmg $t0,$t1,128($sp)
+ stmg $t0,$t1,16*$SIZE_T($sp)
.Lcbc_dec_loop:
- stmg $inp,$out,16($sp)
+ stm${g} $inp,$out,2*$SIZE_T($sp)
llgf $s0,0($inp)
llgf $s1,4($inp)
llgf $s2,8($inp)
@@ -1287,7 +1332,7 @@ $code.=<<___;
bras $ra,_s390x_AES_decrypt
- lmg $inp,$key,16($sp)
+ lm${g} $inp,$key,2*$SIZE_T($sp)
sllg $s0,$s0,32
sllg $s2,$s2,32
lr $s0,$s1
@@ -1295,15 +1340,15 @@ $code.=<<___;
lg $t0,0($inp)
lg $t1,8($inp)
- xg $s0,128($sp)
- xg $s2,136($sp)
+ xg $s0,16*$SIZE_T($sp)
+ xg $s2,16*$SIZE_T+8($sp)
lghi $s1,16
- slgr $len,$s1
+ sl${g}r $len,$s1
brc 4,.Lcbc_dec_tail # if borrow
brc 2,.Lcbc_dec_done # if zero
stg $s0,0($out)
stg $s2,8($out)
- stmg $t0,$t1,128($sp)
+ stmg $t0,$t1,16*$SIZE_T($sp)
la $inp,16($inp)
la $out,16($out)
@@ -1313,7 +1358,7 @@ $code.=<<___;
stg $s0,0($out)
stg $s2,8($out)
.Lcbc_dec_exit:
- lmg $ivp,$ra,48($sp)
+ lm${g} %r6,$ra,6*$SIZE_T($sp)
stmg $t0,$t1,0($ivp)
br $ra
@@ -1321,19 +1366,872 @@ $code.=<<___;
.align 16
.Lcbc_dec_tail:
aghi $len,15
- stg $s0,128($sp)
- stg $s2,136($sp)
+ stg $s0,16*$SIZE_T($sp)
+ stg $s2,16*$SIZE_T+8($sp)
bras $s1,4f
- mvc 0(1,$out),128($sp)
+ mvc 0(1,$out),16*$SIZE_T($sp)
4: ex $len,0($s1)
j .Lcbc_dec_exit
.size AES_cbc_encrypt,.-AES_cbc_encrypt
-.comm OPENSSL_s390xcap_P,8,8
+___
+}
+########################################################################
+# void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+# size_t blocks, const AES_KEY *key,
+# const unsigned char *ivec)
+{
+my $inp="%r2";
+my $out="%r4"; # blocks and out are swapped
+my $len="%r3";
+my $key="%r5"; my $iv0="%r5";
+my $ivp="%r6";
+my $fp ="%r7";
+
+$code.=<<___;
+.globl AES_ctr32_encrypt
+.type AES_ctr32_encrypt,\@function
+.align 16
+AES_ctr32_encrypt:
+ xgr %r3,%r4 # flip %r3 and %r4, $out and $len
+ xgr %r4,%r3
+ xgr %r3,%r4
+ llgfr $len,$len # safe in ctr32 subroutine even in 64-bit case
+___
+$code.=<<___ if (!$softonly);
+ l %r0,240($key)
+ lhi %r1,16
+ clr %r0,%r1
+ jl .Lctr32_software
+
+ stm${g} %r6,$s3,6*$SIZE_T($sp)
+
+ slgr $out,$inp
+ la %r1,0($key) # %r1 is permanent copy of $key
+ lg $iv0,0($ivp) # load ivec
+ lg $ivp,8($ivp)
+
+ # prepare and allocate stack frame at the top of 4K page
+ # with 1K reserved for eventual signal handling
+ lghi $s0,-1024-256-16# guarantee at least 256-bytes buffer
+ lghi $s1,-4096
+ algr $s0,$sp
+ lgr $fp,$sp
+ ngr $s0,$s1 # align at page boundary
+ slgr $fp,$s0 # total buffer size
+ lgr $s2,$sp
+ lghi $s1,1024+16 # sl[g]fi is extended-immediate facility
+ slgr $fp,$s1 # deduct reservation to get usable buffer size
+ # buffer size is at lest 256 and at most 3072+256-16
+
+ la $sp,1024($s0) # alloca
+ srlg $fp,$fp,4 # convert bytes to blocks, minimum 16
+ st${g} $s2,0($sp) # back-chain
+ st${g} $fp,$SIZE_T($sp)
+
+ slgr $len,$fp
+ brc 1,.Lctr32_hw_switch # not zero, no borrow
+ algr $fp,$len # input is shorter than allocated buffer
+ lghi $len,0
+ st${g} $fp,$SIZE_T($sp)
+
+.Lctr32_hw_switch:
+___
+$code.=<<___ if (0); ######### kmctr code was measured to be ~12% slower
+ larl $s0,OPENSSL_s390xcap_P
+ lg $s0,8($s0)
+ tmhh $s0,0x0004 # check for message_security-assist-4
+ jz .Lctr32_km_loop
+
+ llgfr $s0,%r0
+ lgr $s1,%r1
+ lghi %r0,0
+ la %r1,16($sp)
+ .long 0xb92d2042 # kmctr %r4,%r2,%r2
+
+ llihh %r0,0x8000 # check if kmctr supports the function code
+ srlg %r0,%r0,0($s0)
+ ng %r0,16($sp)
+ lgr %r0,$s0
+ lgr %r1,$s1
+ jz .Lctr32_km_loop
+
+####### kmctr code
+ algr $out,$inp # restore $out
+ lgr $s1,$len # $s1 undertakes $len
+ j .Lctr32_kmctr_loop
+.align 16
+.Lctr32_kmctr_loop:
+ la $s2,16($sp)
+ lgr $s3,$fp
+.Lctr32_kmctr_prepare:
+ stg $iv0,0($s2)
+ stg $ivp,8($s2)
+ la $s2,16($s2)
+ ahi $ivp,1 # 32-bit increment, preserves upper half
+ brct $s3,.Lctr32_kmctr_prepare
+
+ #la $inp,0($inp) # inp
+ sllg $len,$fp,4 # len
+ #la $out,0($out) # out
+ la $s2,16($sp) # iv
+ .long 0xb92da042 # kmctr $out,$s2,$inp
+ brc 1,.-4 # pay attention to "partial completion"
+
+ slgr $s1,$fp
+ brc 1,.Lctr32_kmctr_loop # not zero, no borrow
+ algr $fp,$s1
+ lghi $s1,0
+ brc 4+1,.Lctr32_kmctr_loop # not zero
+
+ l${g} $sp,0($sp)
+ lm${g} %r6,$s3,6*$SIZE_T($sp)
+ br $ra
+.align 16
+___
+$code.=<<___;
+.Lctr32_km_loop:
+ la $s2,16($sp)
+ lgr $s3,$fp
+.Lctr32_km_prepare:
+ stg $iv0,0($s2)
+ stg $ivp,8($s2)
+ la $s2,16($s2)
+ ahi $ivp,1 # 32-bit increment, preserves upper half
+ brct $s3,.Lctr32_km_prepare
+
+ la $s0,16($sp) # inp
+ sllg $s1,$fp,4 # len
+ la $s2,16($sp) # out
+ .long 0xb92e00a8 # km %r10,%r8
+ brc 1,.-4 # pay attention to "partial completion"
+
+ la $s2,16($sp)
+ lgr $s3,$fp
+ slgr $s2,$inp
+.Lctr32_km_xor:
+ lg $s0,0($inp)
+ lg $s1,8($inp)
+ xg $s0,0($s2,$inp)
+ xg $s1,8($s2,$inp)
+ stg $s0,0($out,$inp)
+ stg $s1,8($out,$inp)
+ la $inp,16($inp)
+ brct $s3,.Lctr32_km_xor
+
+ slgr $len,$fp
+ brc 1,.Lctr32_km_loop # not zero, no borrow
+ algr $fp,$len
+ lghi $len,0
+ brc 4+1,.Lctr32_km_loop # not zero
+
+ l${g} $s0,0($sp)
+ l${g} $s1,$SIZE_T($sp)
+ la $s2,16($sp)
+.Lctr32_km_zap:
+ stg $s0,0($s2)
+ stg $s0,8($s2)
+ la $s2,16($s2)
+ brct $s1,.Lctr32_km_zap
+
+ la $sp,0($s0)
+ lm${g} %r6,$s3,6*$SIZE_T($sp)
+ br $ra
+.align 16
+.Lctr32_software:
+___
+$code.=<<___;
+ stm${g} $key,$ra,5*$SIZE_T($sp)
+ sl${g}r $inp,$out
+ larl $tbl,AES_Te
+ llgf $t1,12($ivp)
+
+.Lctr32_loop:
+ stm${g} $inp,$out,2*$SIZE_T($sp)
+ llgf $s0,0($ivp)
+ llgf $s1,4($ivp)
+ llgf $s2,8($ivp)
+ lgr $s3,$t1
+ st $t1,16*$SIZE_T($sp)
+ lgr %r4,$key
+
+ bras $ra,_s390x_AES_encrypt
+
+ lm${g} $inp,$ivp,2*$SIZE_T($sp)
+ llgf $t1,16*$SIZE_T($sp)
+ x $s0,0($inp,$out)
+ x $s1,4($inp,$out)
+ x $s2,8($inp,$out)
+ x $s3,12($inp,$out)
+ stm $s0,$s3,0($out)
+
+ la $out,16($out)
+ ahi $t1,1 # 32-bit increment
+ brct $len,.Lctr32_loop
+
+ lm${g} %r6,$ra,6*$SIZE_T($sp)
+ br $ra
+.size AES_ctr32_encrypt,.-AES_ctr32_encrypt
+___
+}
+
+########################################################################
+# void AES_xts_encrypt(const char *inp,char *out,size_t len,
+# const AES_KEY *key1, const AES_KEY *key2,
+# const unsigned char iv[16]);
+#
+{
+my $inp="%r2";
+my $out="%r4"; # len and out are swapped
+my $len="%r3";
+my $key1="%r5"; # $i1
+my $key2="%r6"; # $i2
+my $fp="%r7"; # $i3
+my $tweak=16*$SIZE_T+16; # or $stdframe-16, bottom of the frame...
+
+$code.=<<___;
+.type _s390x_xts_km,\@function
+.align 16
+_s390x_xts_km:
+___
+$code.=<<___ if(1);
+ llgfr $s0,%r0 # put aside the function code
+ lghi $s1,0x7f
+ nr $s1,%r0
+ lghi %r0,0 # query capability vector
+ la %r1,$tweak-16($sp)
+ .long 0xb92e0042 # km %r4,%r2
+ llihh %r1,0x8000
+ srlg %r1,%r1,32($s1) # check for 32+function code
+ ng %r1,$tweak-16($sp)
+ lgr %r0,$s0 # restore the function code
+ la %r1,0($key1) # restore $key1
+ jz .Lxts_km_vanilla
+
+ lmg $i2,$i3,$tweak($sp) # put aside the tweak value
+ algr $out,$inp
+
+ oill %r0,32 # switch to xts function code
+ aghi $s1,-18 #
+ sllg $s1,$s1,3 # (function code - 18)*8, 0 or 16
+ la %r1,$tweak-16($sp)
+ slgr %r1,$s1 # parameter block position
+ lmg $s0,$s3,0($key1) # load 256 bits of key material,
+ stmg $s0,$s3,0(%r1) # and copy it to parameter block.
+ # yes, it contains junk and overlaps
+ # with the tweak in 128-bit case.
+ # it's done to avoid conditional
+ # branch.
+ stmg $i2,$i3,$tweak($sp) # "re-seat" the tweak value
+
+ .long 0xb92e0042 # km %r4,%r2
+ brc 1,.-4 # pay attention to "partial completion"
+
+ lrvg $s0,$tweak+0($sp) # load the last tweak
+ lrvg $s1,$tweak+8($sp)
+ stmg %r0,%r3,$tweak-32($sp) # wipe copy of the key
+
+ nill %r0,0xffdf # switch back to original function code
+ la %r1,0($key1) # restore pointer to $key1
+ slgr $out,$inp
+
+ llgc $len,2*$SIZE_T-1($sp)
+ nill $len,0x0f # $len%=16
+ br $ra
+
+.align 16
+.Lxts_km_vanilla:
+___
+$code.=<<___;
+ # prepare and allocate stack frame at the top of 4K page
+ # with 1K reserved for eventual signal handling
+ lghi $s0,-1024-256-16# guarantee at least 256-bytes buffer
+ lghi $s1,-4096
+ algr $s0,$sp
+ lgr $fp,$sp
+ ngr $s0,$s1 # align at page boundary
+ slgr $fp,$s0 # total buffer size
+ lgr $s2,$sp
+ lghi $s1,1024+16 # sl[g]fi is extended-immediate facility
+ slgr $fp,$s1 # deduct reservation to get usable buffer size
+ # buffer size is at lest 256 and at most 3072+256-16
+
+ la $sp,1024($s0) # alloca
+ nill $fp,0xfff0 # round to 16*n
+ st${g} $s2,0($sp) # back-chain
+ nill $len,0xfff0 # redundant
+ st${g} $fp,$SIZE_T($sp)
+
+ slgr $len,$fp
+ brc 1,.Lxts_km_go # not zero, no borrow
+ algr $fp,$len # input is shorter than allocated buffer
+ lghi $len,0
+ st${g} $fp,$SIZE_T($sp)
+
+.Lxts_km_go:
+ lrvg $s0,$tweak+0($s2) # load the tweak value in little-endian
+ lrvg $s1,$tweak+8($s2)
+
+ la $s2,16($sp) # vector of ascending tweak values
+ slgr $s2,$inp
+ srlg $s3,$fp,4
+ j .Lxts_km_start
+
+.Lxts_km_loop:
+ la $s2,16($sp)
+ slgr $s2,$inp
+ srlg $s3,$fp,4
+.Lxts_km_prepare:
+ lghi $i1,0x87
+ srag $i2,$s1,63 # broadcast upper bit
+ ngr $i1,$i2 # rem
+ algr $s0,$s0
+ alcgr $s1,$s1
+ xgr $s0,$i1
+.Lxts_km_start:
+ lrvgr $i1,$s0 # flip byte order
+ lrvgr $i2,$s1
+ stg $i1,0($s2,$inp)
+ stg $i2,8($s2,$inp)
+ xg $i1,0($inp)
+ xg $i2,8($inp)
+ stg $i1,0($out,$inp)
+ stg $i2,8($out,$inp)
+ la $inp,16($inp)
+ brct $s3,.Lxts_km_prepare
+
+ slgr $inp,$fp # rewind $inp
+ la $s2,0($out,$inp)
+ lgr $s3,$fp
+ .long 0xb92e00aa # km $s2,$s2
+ brc 1,.-4 # pay attention to "partial completion"
+
+ la $s2,16($sp)
+ slgr $s2,$inp
+ srlg $s3,$fp,4
+.Lxts_km_xor:
+ lg $i1,0($out,$inp)
+ lg $i2,8($out,$inp)
+ xg $i1,0($s2,$inp)
+ xg $i2,8($s2,$inp)
+ stg $i1,0($out,$inp)
+ stg $i2,8($out,$inp)
+ la $inp,16($inp)
+ brct $s3,.Lxts_km_xor
+
+ slgr $len,$fp
+ brc 1,.Lxts_km_loop # not zero, no borrow
+ algr $fp,$len
+ lghi $len,0
+ brc 4+1,.Lxts_km_loop # not zero
+
+ l${g} $i1,0($sp) # back-chain
+ llgf $fp,`2*$SIZE_T-4`($sp) # bytes used
+ la $i2,16($sp)
+ srlg $fp,$fp,4
+.Lxts_km_zap:
+ stg $i1,0($i2)
+ stg $i1,8($i2)
+ la $i2,16($i2)
+ brct $fp,.Lxts_km_zap
+
+ la $sp,0($i1)
+ llgc $len,2*$SIZE_T-1($i1)
+ nill $len,0x0f # $len%=16
+ bzr $ra
+
+ # generate one more tweak...
+ lghi $i1,0x87
+ srag $i2,$s1,63 # broadcast upper bit
+ ngr $i1,$i2 # rem
+ algr $s0,$s0
+ alcgr $s1,$s1
+ xgr $s0,$i1
+
+ ltr $len,$len # clear zero flag
+ br $ra
+.size _s390x_xts_km,.-_s390x_xts_km
+
+.globl AES_xts_encrypt
+.type AES_xts_encrypt,\@function
+.align 16
+AES_xts_encrypt:
+ xgr %r3,%r4 # flip %r3 and %r4, $out and $len
+ xgr %r4,%r3
+ xgr %r3,%r4
+___
+$code.=<<___ if ($SIZE_T==4);
+ llgfr $len,$len
+___
+$code.=<<___;
+ st${g} $len,1*$SIZE_T($sp) # save copy of $len
+ srag $len,$len,4 # formally wrong, because it expands
+ # sign byte, but who can afford asking
+ # to process more than 2^63-1 bytes?
+ # I use it, because it sets condition
+ # code...
+ bcr 8,$ra # abort if zero (i.e. less than 16)
+___
+$code.=<<___ if (!$softonly);
+ llgf %r0,240($key2)
+ lhi %r1,16
+ clr %r0,%r1
+ jl .Lxts_enc_software
+
+ st${g} $ra,5*$SIZE_T($sp)
+ stm${g} %r6,$s3,6*$SIZE_T($sp)
+
+ sllg $len,$len,4 # $len&=~15
+ slgr $out,$inp
+
+ # generate the tweak value
+ l${g} $s3,$stdframe($sp) # pointer to iv
+ la $s2,$tweak($sp)
+ lmg $s0,$s1,0($s3)
+ lghi $s3,16
+ stmg $s0,$s1,0($s2)
+ la %r1,0($key2) # $key2 is not needed anymore
+ .long 0xb92e00aa # km $s2,$s2, generate the tweak
+ brc 1,.-4 # can this happen?
+
+ l %r0,240($key1)
+ la %r1,0($key1) # $key1 is not needed anymore
+ bras $ra,_s390x_xts_km
+ jz .Lxts_enc_km_done
+
+ aghi $inp,-16 # take one step back
+ la $i3,0($out,$inp) # put aside real $out
+.Lxts_enc_km_steal:
+ llgc $i1,16($inp)
+ llgc $i2,0($out,$inp)
+ stc $i1,0($out,$inp)
+ stc $i2,16($out,$inp)
+ la $inp,1($inp)
+ brct $len,.Lxts_enc_km_steal
+
+ la $s2,0($i3)
+ lghi $s3,16
+ lrvgr $i1,$s0 # flip byte order
+ lrvgr $i2,$s1
+ xg $i1,0($s2)
+ xg $i2,8($s2)
+ stg $i1,0($s2)
+ stg $i2,8($s2)
+ .long 0xb92e00aa # km $s2,$s2
+ brc 1,.-4 # can this happen?
+ lrvgr $i1,$s0 # flip byte order
+ lrvgr $i2,$s1
+ xg $i1,0($i3)
+ xg $i2,8($i3)
+ stg $i1,0($i3)
+ stg $i2,8($i3)
+
+.Lxts_enc_km_done:
+ stg $sp,$tweak+0($sp) # wipe tweak
+ stg $sp,$tweak+8($sp)
+ l${g} $ra,5*$SIZE_T($sp)
+ lm${g} %r6,$s3,6*$SIZE_T($sp)
+ br $ra
+.align 16
+.Lxts_enc_software:
+___
+$code.=<<___;
+ stm${g} %r6,$ra,6*$SIZE_T($sp)
+
+ slgr $out,$inp
+
+ l${g} $s3,$stdframe($sp) # ivp
+ llgf $s0,0($s3) # load iv
+ llgf $s1,4($s3)
+ llgf $s2,8($s3)
+ llgf $s3,12($s3)
+ stm${g} %r2,%r5,2*$SIZE_T($sp)
+ la $key,0($key2)
+ larl $tbl,AES_Te
+ bras $ra,_s390x_AES_encrypt # generate the tweak
+ lm${g} %r2,%r5,2*$SIZE_T($sp)
+ stm $s0,$s3,$tweak($sp) # save the tweak
+ j .Lxts_enc_enter
+
+.align 16
+.Lxts_enc_loop:
+ lrvg $s1,$tweak+0($sp) # load the tweak in little-endian
+ lrvg $s3,$tweak+8($sp)
+ lghi %r1,0x87
+ srag %r0,$s3,63 # broadcast upper bit
+ ngr %r1,%r0 # rem
+ algr $s1,$s1
+ alcgr $s3,$s3
+ xgr $s1,%r1
+ lrvgr $s1,$s1 # flip byte order
+ lrvgr $s3,$s3
+ srlg $s0,$s1,32 # smash the tweak to 4x32-bits
+ stg $s1,$tweak+0($sp) # save the tweak
+ llgfr $s1,$s1
+ srlg $s2,$s3,32
+ stg $s3,$tweak+8($sp)
+ llgfr $s3,$s3
+ la $inp,16($inp) # $inp+=16
+.Lxts_enc_enter:
+ x $s0,0($inp) # ^=*($inp)
+ x $s1,4($inp)
+ x $s2,8($inp)
+ x $s3,12($inp)
+ stm${g} %r2,%r3,2*$SIZE_T($sp) # only two registers are changing
+ la $key,0($key1)
+ bras $ra,_s390x_AES_encrypt
+ lm${g} %r2,%r5,2*$SIZE_T($sp)
+ x $s0,$tweak+0($sp) # ^=tweak
+ x $s1,$tweak+4($sp)
+ x $s2,$tweak+8($sp)
+ x $s3,$tweak+12($sp)
+ st $s0,0($out,$inp)
+ st $s1,4($out,$inp)
+ st $s2,8($out,$inp)
+ st $s3,12($out,$inp)
+ brct${g} $len,.Lxts_enc_loop
+
+ llgc $len,`2*$SIZE_T-1`($sp)
+ nill $len,0x0f # $len%16
+ jz .Lxts_enc_done
+
+ la $i3,0($inp,$out) # put aside real $out
+.Lxts_enc_steal:
+ llgc %r0,16($inp)
+ llgc %r1,0($out,$inp)
+ stc %r0,0($out,$inp)
+ stc %r1,16($out,$inp)
+ la $inp,1($inp)
+ brct $len,.Lxts_enc_steal
+ la $out,0($i3) # restore real $out
+
+ # generate last tweak...
+ lrvg $s1,$tweak+0($sp) # load the tweak in little-endian
+ lrvg $s3,$tweak+8($sp)
+ lghi %r1,0x87
+ srag %r0,$s3,63 # broadcast upper bit
+ ngr %r1,%r0 # rem
+ algr $s1,$s1
+ alcgr $s3,$s3
+ xgr $s1,%r1
+ lrvgr $s1,$s1 # flip byte order
+ lrvgr $s3,$s3
+ srlg $s0,$s1,32 # smash the tweak to 4x32-bits
+ stg $s1,$tweak+0($sp) # save the tweak
+ llgfr $s1,$s1
+ srlg $s2,$s3,32
+ stg $s3,$tweak+8($sp)
+ llgfr $s3,$s3
+
+ x $s0,0($out) # ^=*(inp)|stolen cipther-text
+ x $s1,4($out)
+ x $s2,8($out)
+ x $s3,12($out)
+ st${g} $out,4*$SIZE_T($sp)
+ la $key,0($key1)
+ bras $ra,_s390x_AES_encrypt
+ l${g} $out,4*$SIZE_T($sp)
+ x $s0,`$tweak+0`($sp) # ^=tweak
+ x $s1,`$tweak+4`($sp)
+ x $s2,`$tweak+8`($sp)
+ x $s3,`$tweak+12`($sp)
+ st $s0,0($out)
+ st $s1,4($out)
+ st $s2,8($out)
+ st $s3,12($out)
+
+.Lxts_enc_done:
+ stg $sp,$tweak+0($sp) # wipe tweak
+ stg $sp,$twesk+8($sp)
+ lm${g} %r6,$ra,6*$SIZE_T($sp)
+ br $ra
+.size AES_xts_encrypt,.-AES_xts_encrypt
+___
+# void AES_xts_decrypt(const char *inp,char *out,size_t len,
+# const AES_KEY *key1, const AES_KEY *key2,
+# const unsigned char iv[16]);
+#
+$code.=<<___;
+.globl AES_xts_decrypt
+.type AES_xts_decrypt,\@function
+.align 16
+AES_xts_decrypt:
+ xgr %r3,%r4 # flip %r3 and %r4, $out and $len
+ xgr %r4,%r3
+ xgr %r3,%r4
+___
+$code.=<<___ if ($SIZE_T==4);
+ llgfr $len,$len
+___
+$code.=<<___;
+ st${g} $len,1*$SIZE_T($sp) # save copy of $len
+ aghi $len,-16
+ bcr 4,$ra # abort if less than zero. formally
+ # wrong, because $len is unsigned,
+ # but who can afford asking to
+ # process more than 2^63-1 bytes?
+ tmll $len,0x0f
+ jnz .Lxts_dec_proceed
+ aghi $len,16
+.Lxts_dec_proceed:
+___
+$code.=<<___ if (!$softonly);
+ llgf %r0,240($key2)
+ lhi %r1,16
+ clr %r0,%r1
+ jl .Lxts_dec_software
+
+ st${g} $ra,5*$SIZE_T($sp)
+ stm${g} %r6,$s3,6*$SIZE_T($sp)
+
+ nill $len,0xfff0 # $len&=~15
+ slgr $out,$inp
+
+ # generate the tweak value
+ l${g} $s3,$stdframe($sp) # pointer to iv
+ la $s2,$tweak($sp)
+ lmg $s0,$s1,0($s3)
+ lghi $s3,16
+ stmg $s0,$s1,0($s2)
+ la %r1,0($key2) # $key2 is not needed past this point
+ .long 0xb92e00aa # km $s2,$s2, generate the tweak
+ brc 1,.-4 # can this happen?
+
+ l %r0,240($key1)
+ la %r1,0($key1) # $key1 is not needed anymore
+
+ ltgr $len,$len
+ jz .Lxts_dec_km_short
+ bras $ra,_s390x_xts_km
+ jz .Lxts_dec_km_done
+
+ lrvgr $s2,$s0 # make copy in reverse byte order
+ lrvgr $s3,$s1
+ j .Lxts_dec_km_2ndtweak
+
+.Lxts_dec_km_short:
+ llgc $len,`2*$SIZE_T-1`($sp)
+ nill $len,0x0f # $len%=16
+ lrvg $s0,$tweak+0($sp) # load the tweak
+ lrvg $s1,$tweak+8($sp)
+ lrvgr $s2,$s0 # make copy in reverse byte order
+ lrvgr $s3,$s1
+
+.Lxts_dec_km_2ndtweak:
+ lghi $i1,0x87
+ srag $i2,$s1,63 # broadcast upper bit
+ ngr $i1,$i2 # rem
+ algr $s0,$s0
+ alcgr $s1,$s1
+ xgr $s0,$i1
+ lrvgr $i1,$s0 # flip byte order
+ lrvgr $i2,$s1
+
+ xg $i1,0($inp)
+ xg $i2,8($inp)
+ stg $i1,0($out,$inp)
+ stg $i2,8($out,$inp)
+ la $i2,0($out,$inp)
+ lghi $i3,16
+ .long 0xb92e0066 # km $i2,$i2
+ brc 1,.-4 # can this happen?
+ lrvgr $i1,$s0
+ lrvgr $i2,$s1
+ xg $i1,0($out,$inp)
+ xg $i2,8($out,$inp)
+ stg $i1,0($out,$inp)
+ stg $i2,8($out,$inp)
+
+ la $i3,0($out,$inp) # put aside real $out
+.Lxts_dec_km_steal:
+ llgc $i1,16($inp)
+ llgc $i2,0($out,$inp)
+ stc $i1,0($out,$inp)
+ stc $i2,16($out,$inp)
+ la $inp,1($inp)
+ brct $len,.Lxts_dec_km_steal
+
+ lgr $s0,$s2
+ lgr $s1,$s3
+ xg $s0,0($i3)
+ xg $s1,8($i3)
+ stg $s0,0($i3)
+ stg $s1,8($i3)
+ la $s0,0($i3)
+ lghi $s1,16
+ .long 0xb92e0088 # km $s0,$s0
+ brc 1,.-4 # can this happen?
+ xg $s2,0($i3)
+ xg $s3,8($i3)
+ stg $s2,0($i3)
+ stg $s3,8($i3)
+.Lxts_dec_km_done:
+ stg $sp,$tweak+0($sp) # wipe tweak
+ stg $sp,$tweak+8($sp)
+ l${g} $ra,5*$SIZE_T($sp)
+ lm${g} %r6,$s3,6*$SIZE_T($sp)
+ br $ra
+.align 16
+.Lxts_dec_software:
+___
+$code.=<<___;
+ stm${g} %r6,$ra,6*$SIZE_T($sp)
+
+ srlg $len,$len,4
+ slgr $out,$inp
+
+ l${g} $s3,$stdframe($sp) # ivp
+ llgf $s0,0($s3) # load iv
+ llgf $s1,4($s3)
+ llgf $s2,8($s3)
+ llgf $s3,12($s3)
+ stm${g} %r2,%r5,2*$SIZE_T($sp)
+ la $key,0($key2)
+ larl $tbl,AES_Te
+ bras $ra,_s390x_AES_encrypt # generate the tweak
+ lm${g} %r2,%r5,2*$SIZE_T($sp)
+ larl $tbl,AES_Td
+ lt${g}r $len,$len
+ stm $s0,$s3,$tweak($sp) # save the tweak
+ jz .Lxts_dec_short
+ j .Lxts_dec_enter
+
+.align 16
+.Lxts_dec_loop:
+ lrvg $s1,$tweak+0($sp) # load the tweak in little-endian
+ lrvg $s3,$tweak+8($sp)
+ lghi %r1,0x87
+ srag %r0,$s3,63 # broadcast upper bit
+ ngr %r1,%r0 # rem
+ algr $s1,$s1
+ alcgr $s3,$s3
+ xgr $s1,%r1
+ lrvgr $s1,$s1 # flip byte order
+ lrvgr $s3,$s3
+ srlg $s0,$s1,32 # smash the tweak to 4x32-bits
+ stg $s1,$tweak+0($sp) # save the tweak
+ llgfr $s1,$s1
+ srlg $s2,$s3,32
+ stg $s3,$tweak+8($sp)
+ llgfr $s3,$s3
+.Lxts_dec_enter:
+ x $s0,0($inp) # tweak^=*(inp)
+ x $s1,4($inp)
+ x $s2,8($inp)
+ x $s3,12($inp)
+ stm${g} %r2,%r3,2*$SIZE_T($sp) # only two registers are changing
+ la $key,0($key1)
+ bras $ra,_s390x_AES_decrypt
+ lm${g} %r2,%r5,2*$SIZE_T($sp)
+ x $s0,$tweak+0($sp) # ^=tweak
+ x $s1,$tweak+4($sp)
+ x $s2,$tweak+8($sp)
+ x $s3,$tweak+12($sp)
+ st $s0,0($out,$inp)
+ st $s1,4($out,$inp)
+ st $s2,8($out,$inp)
+ st $s3,12($out,$inp)
+ la $inp,16($inp)
+ brct${g} $len,.Lxts_dec_loop
+
+ llgc $len,`2*$SIZE_T-1`($sp)
+ nill $len,0x0f # $len%16
+ jz .Lxts_dec_done
+
+ # generate pair of tweaks...
+ lrvg $s1,$tweak+0($sp) # load the tweak in little-endian
+ lrvg $s3,$tweak+8($sp)
+ lghi %r1,0x87
+ srag %r0,$s3,63 # broadcast upper bit
+ ngr %r1,%r0 # rem
+ algr $s1,$s1
+ alcgr $s3,$s3
+ xgr $s1,%r1
+ lrvgr $i2,$s1 # flip byte order
+ lrvgr $i3,$s3
+ stmg $i2,$i3,$tweak($sp) # save the 1st tweak
+ j .Lxts_dec_2ndtweak
+
+.align 16
+.Lxts_dec_short:
+ llgc $len,`2*$SIZE_T-1`($sp)
+ nill $len,0x0f # $len%16
+ lrvg $s1,$tweak+0($sp) # load the tweak in little-endian
+ lrvg $s3,$tweak+8($sp)
+.Lxts_dec_2ndtweak:
+ lghi %r1,0x87
+ srag %r0,$s3,63 # broadcast upper bit
+ ngr %r1,%r0 # rem
+ algr $s1,$s1
+ alcgr $s3,$s3
+ xgr $s1,%r1
+ lrvgr $s1,$s1 # flip byte order
+ lrvgr $s3,$s3
+ srlg $s0,$s1,32 # smash the tweak to 4x32-bits
+ stg $s1,$tweak-16+0($sp) # save the 2nd tweak
+ llgfr $s1,$s1
+ srlg $s2,$s3,32
+ stg $s3,$tweak-16+8($sp)
+ llgfr $s3,$s3
+
+ x $s0,0($inp) # tweak_the_2nd^=*(inp)
+ x $s1,4($inp)
+ x $s2,8($inp)
+ x $s3,12($inp)
+ stm${g} %r2,%r3,2*$SIZE_T($sp)
+ la $key,0($key1)
+ bras $ra,_s390x_AES_decrypt
+ lm${g} %r2,%r5,2*$SIZE_T($sp)
+ x $s0,$tweak-16+0($sp) # ^=tweak_the_2nd
+ x $s1,$tweak-16+4($sp)
+ x $s2,$tweak-16+8($sp)
+ x $s3,$tweak-16+12($sp)
+ st $s0,0($out,$inp)
+ st $s1,4($out,$inp)
+ st $s2,8($out,$inp)
+ st $s3,12($out,$inp)
+
+ la $i3,0($out,$inp) # put aside real $out
+.Lxts_dec_steal:
+ llgc %r0,16($inp)
+ llgc %r1,0($out,$inp)
+ stc %r0,0($out,$inp)
+ stc %r1,16($out,$inp)
+ la $inp,1($inp)
+ brct $len,.Lxts_dec_steal
+ la $out,0($i3) # restore real $out
+
+ lm $s0,$s3,$tweak($sp) # load the 1st tweak
+ x $s0,0($out) # tweak^=*(inp)|stolen cipher-text
+ x $s1,4($out)
+ x $s2,8($out)
+ x $s3,12($out)
+ st${g} $out,4*$SIZE_T($sp)
+ la $key,0($key1)
+ bras $ra,_s390x_AES_decrypt
+ l${g} $out,4*$SIZE_T($sp)
+ x $s0,$tweak+0($sp) # ^=tweak
+ x $s1,$tweak+4($sp)
+ x $s2,$tweak+8($sp)
+ x $s3,$tweak+12($sp)
+ st $s0,0($out)
+ st $s1,4($out)
+ st $s2,8($out)
+ st $s3,12($out)
+ stg $sp,$tweak-16+0($sp) # wipe 2nd tweak
+ stg $sp,$tweak-16+8($sp)
+.Lxts_dec_done:
+ stg $sp,$tweak+0($sp) # wipe tweak
+ stg $sp,$twesk+8($sp)
+ lm${g} %r6,$ra,6*$SIZE_T($sp)
+ br $ra
+.size AES_xts_decrypt,.-AES_xts_decrypt
___
}
$code.=<<___;
.string "AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+.comm OPENSSL_s390xcap_P,16,8
___
$code =~ s/\`([^\`]*)\`/eval $1/gem;
print $code;
+close STDOUT; # force flush
diff --git a/deps/openssl/openssl/crypto/aes/asm/aes-sparcv9.pl b/deps/openssl/openssl/crypto/aes/asm/aes-sparcv9.pl
index c57b3a2d6..403c4d129 100644..100755
--- a/deps/openssl/openssl/crypto/aes/asm/aes-sparcv9.pl
+++ b/deps/openssl/openssl/crypto/aes/asm/aes-sparcv9.pl
@@ -1176,6 +1176,7 @@ ___
# As UltraSPARC T1, a.k.a. Niagara, has shared FPU, FP nops can have
# undesired effect, so just omit them and sacrifice some portion of
# percent in performance...
-$code =~ s/fmovs.*$//gem;
+$code =~ s/fmovs.*$//gm;
print $code;
+close STDOUT; # ensure flush
diff --git a/deps/openssl/openssl/crypto/aes/asm/aes-x86_64.pl b/deps/openssl/openssl/crypto/aes/asm/aes-x86_64.pl
index 83aad2354..9fa4ff5a6 100755
--- a/deps/openssl/openssl/crypto/aes/asm/aes-x86_64.pl
+++ b/deps/openssl/openssl/crypto/aes/asm/aes-x86_64.pl
@@ -36,7 +36,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
$verticalspin=1; # unlike 32-bit version $verticalspin performs
# ~15% better on both AMD and Intel cores
@@ -588,6 +589,9 @@ $code.=<<___;
.globl AES_encrypt
.type AES_encrypt,\@function,3
.align 16
+.globl asm_AES_encrypt
+.hidden asm_AES_encrypt
+asm_AES_encrypt:
AES_encrypt:
push %rbx
push %rbp
@@ -1184,6 +1188,9 @@ $code.=<<___;
.globl AES_decrypt
.type AES_decrypt,\@function,3
.align 16
+.globl asm_AES_decrypt
+.hidden asm_AES_decrypt
+asm_AES_decrypt:
AES_decrypt:
push %rbx
push %rbp
@@ -1277,13 +1284,13 @@ $code.=<<___;
___
}
-# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+# int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
# AES_KEY *key)
$code.=<<___;
-.globl AES_set_encrypt_key
-.type AES_set_encrypt_key,\@function,3
+.globl private_AES_set_encrypt_key
+.type private_AES_set_encrypt_key,\@function,3
.align 16
-AES_set_encrypt_key:
+private_AES_set_encrypt_key:
push %rbx
push %rbp
push %r12 # redundant, but allows to share
@@ -1304,7 +1311,7 @@ AES_set_encrypt_key:
add \$56,%rsp
.Lenc_key_epilogue:
ret
-.size AES_set_encrypt_key,.-AES_set_encrypt_key
+.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
.type _x86_64_AES_set_encrypt_key,\@abi-omnipotent
.align 16
@@ -1547,13 +1554,13 @@ $code.=<<___;
___
}
-# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+# int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
# AES_KEY *key)
$code.=<<___;
-.globl AES_set_decrypt_key
-.type AES_set_decrypt_key,\@function,3
+.globl private_AES_set_decrypt_key
+.type private_AES_set_decrypt_key,\@function,3
.align 16
-AES_set_decrypt_key:
+private_AES_set_decrypt_key:
push %rbx
push %rbp
push %r12
@@ -1622,7 +1629,7 @@ $code.=<<___;
add \$56,%rsp
.Ldec_key_epilogue:
ret
-.size AES_set_decrypt_key,.-AES_set_decrypt_key
+.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
___
# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
@@ -1648,6 +1655,9 @@ $code.=<<___;
.type AES_cbc_encrypt,\@function,6
.align 16
.extern OPENSSL_ia32cap_P
+.globl asm_AES_cbc_encrypt
+.hidden asm_AES_cbc_encrypt
+asm_AES_cbc_encrypt:
AES_cbc_encrypt:
cmp \$0,%rdx # check length
je .Lcbc_epilogue
@@ -2766,13 +2776,13 @@ cbc_se_handler:
.rva .LSEH_end_AES_decrypt
.rva .LSEH_info_AES_decrypt
- .rva .LSEH_begin_AES_set_encrypt_key
- .rva .LSEH_end_AES_set_encrypt_key
- .rva .LSEH_info_AES_set_encrypt_key
+ .rva .LSEH_begin_private_AES_set_encrypt_key
+ .rva .LSEH_end_private_AES_set_encrypt_key
+ .rva .LSEH_info_private_AES_set_encrypt_key
- .rva .LSEH_begin_AES_set_decrypt_key
- .rva .LSEH_end_AES_set_decrypt_key
- .rva .LSEH_info_AES_set_decrypt_key
+ .rva .LSEH_begin_private_AES_set_decrypt_key
+ .rva .LSEH_end_private_AES_set_decrypt_key
+ .rva .LSEH_info_private_AES_set_decrypt_key
.rva .LSEH_begin_AES_cbc_encrypt
.rva .LSEH_end_AES_cbc_encrypt
@@ -2788,11 +2798,11 @@ cbc_se_handler:
.byte 9,0,0,0
.rva block_se_handler
.rva .Ldec_prologue,.Ldec_epilogue # HandlerData[]
-.LSEH_info_AES_set_encrypt_key:
+.LSEH_info_private_AES_set_encrypt_key:
.byte 9,0,0,0
.rva key_se_handler
.rva .Lenc_key_prologue,.Lenc_key_epilogue # HandlerData[]
-.LSEH_info_AES_set_decrypt_key:
+.LSEH_info_private_AES_set_decrypt_key:
.byte 9,0,0,0
.rva key_se_handler
.rva .Ldec_key_prologue,.Ldec_key_epilogue # HandlerData[]
diff --git a/deps/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl b/deps/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
new file mode 100644
index 000000000..3c8f6c19e
--- /dev/null
+++ b/deps/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
@@ -0,0 +1,1250 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# June 2011
+#
+# This is AESNI-CBC+SHA1 "stitch" implementation. The idea, as spelled
+# in http://download.intel.com/design/intarch/papers/323686.pdf, is
+# that since AESNI-CBC encrypt exhibit *very* low instruction-level
+# parallelism, interleaving it with another algorithm would allow to
+# utilize processor resources better and achieve better performance.
+# SHA1 instruction sequences(*) are taken from sha1-x86_64.pl and
+# AESNI code is weaved into it. Below are performance numbers in
+# cycles per processed byte, less is better, for standalone AESNI-CBC
+# encrypt, sum of the latter and standalone SHA1, and "stitched"
+# subroutine:
+#
+# AES-128-CBC +SHA1 stitch gain
+# Westmere 3.77[+5.6] 9.37 6.65 +41%
+# Sandy Bridge 5.05[+5.2(6.3)] 10.25(11.35) 6.16(7.08) +67%(+60%)
+#
+# AES-192-CBC
+# Westmere 4.51 10.11 6.97 +45%
+# Sandy Bridge 6.05 11.25(12.35) 6.34(7.27) +77%(+70%)
+#
+# AES-256-CBC
+# Westmere 5.25 10.85 7.25 +50%
+# Sandy Bridge 7.05 12.25(13.35) 7.06(7.70) +74%(+73%)
+#
+# (*) There are two code paths: SSSE3 and AVX. See sha1-568.pl for
+# background information. Above numbers in parentheses are SSSE3
+# results collected on AVX-capable CPU, i.e. apply on OSes that
+# don't support AVX.
+#
+# Needless to mention that it makes no sense to implement "stitched"
+# *decrypt* subroutine. Because *both* AESNI-CBC decrypt and SHA1
+# fully utilize parallelism, so stitching would not give any gain
+# anyway. Well, there might be some, e.g. because of better cache
+# locality... For reference, here are performance results for
+# standalone AESNI-CBC decrypt:
+#
+# AES-128-CBC AES-192-CBC AES-256-CBC
+# Westmere 1.31 1.55 1.80
+# Sandy Bridge 0.93 1.06 1.22
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+$avx=1 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
+ =~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
+ $1>=2.19);
+$avx=1 if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
+ `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
+ $1>=2.09);
+$avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
+ `ml64 2>&1` =~ /Version ([0-9]+)\./ &&
+ $1>=10);
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+# void aesni_cbc_sha1_enc(const void *inp,
+# void *out,
+# size_t length,
+# const AES_KEY *key,
+# unsigned char *iv,
+# SHA_CTX *ctx,
+# const void *in0);
+
+$code.=<<___;
+.text
+.extern OPENSSL_ia32cap_P
+
+.globl aesni_cbc_sha1_enc
+.type aesni_cbc_sha1_enc,\@abi-omnipotent
+.align 16
+aesni_cbc_sha1_enc:
+ # caller should check for SSSE3 and AES-NI bits
+ mov OPENSSL_ia32cap_P+0(%rip),%r10d
+ mov OPENSSL_ia32cap_P+4(%rip),%r11d
+___
+$code.=<<___ if ($avx);
+ and \$`1<<28`,%r11d # mask AVX bit
+ and \$`1<<30`,%r10d # mask "Intel CPU" bit
+ or %r11d,%r10d
+ cmp \$`1<<28|1<<30`,%r10d
+ je aesni_cbc_sha1_enc_avx
+___
+$code.=<<___;
+ jmp aesni_cbc_sha1_enc_ssse3
+ ret
+.size aesni_cbc_sha1_enc,.-aesni_cbc_sha1_enc
+___
+
+my ($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
+
+my $Xi=4;
+my @X=map("%xmm$_",(4..7,0..3));
+my @Tx=map("%xmm$_",(8..10));
+my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp"); # size optimization
+my @T=("%esi","%edi");
+my $j=0; my $jj=0; my $r=0; my $sn=0;
+my $K_XX_XX="%r11";
+my ($iv,$in,$rndkey0)=map("%xmm$_",(11..13));
+my @rndkey=("%xmm14","%xmm15");
+
+sub AUTOLOAD() # thunk [simplified] 32-bit style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
+ my $arg = pop;
+ $arg = "\$$arg" if ($arg*1 eq $arg);
+ $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
+}
+
+my $_rol=sub { &rol(@_) };
+my $_ror=sub { &ror(@_) };
+
+$code.=<<___;
+.type aesni_cbc_sha1_enc_ssse3,\@function,6
+.align 16
+aesni_cbc_sha1_enc_ssse3:
+ mov `($win64?56:8)`(%rsp),$inp # load 7th argument
+ #shr \$6,$len # debugging artefact
+ #jz .Lepilogue_ssse3 # debugging artefact
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ lea `-104-($win64?10*16:0)`(%rsp),%rsp
+ #mov $in0,$inp # debugging artefact
+ #lea 64(%rsp),$ctx # debugging artefact
+___
+$code.=<<___ if ($win64);
+ movaps %xmm6,96+0(%rsp)
+ movaps %xmm7,96+16(%rsp)
+ movaps %xmm8,96+32(%rsp)
+ movaps %xmm9,96+48(%rsp)
+ movaps %xmm10,96+64(%rsp)
+ movaps %xmm11,96+80(%rsp)
+ movaps %xmm12,96+96(%rsp)
+ movaps %xmm13,96+112(%rsp)
+ movaps %xmm14,96+128(%rsp)
+ movaps %xmm15,96+144(%rsp)
+.Lprologue_ssse3:
+___
+$code.=<<___;
+ mov $in0,%r12 # reassign arguments
+ mov $out,%r13
+ mov $len,%r14
+ mov $key,%r15
+ movdqu ($ivp),$iv # load IV
+ mov $ivp,88(%rsp) # save $ivp
+___
+my ($in0,$out,$len,$key)=map("%r$_",(12..15)); # reassign arguments
+my $rounds="${ivp}d";
+$code.=<<___;
+ shl \$6,$len
+ sub $in0,$out
+ mov 240($key),$rounds
+ add $inp,$len # end of input
+
+ lea K_XX_XX(%rip),$K_XX_XX
+ mov 0($ctx),$A # load context
+ mov 4($ctx),$B
+ mov 8($ctx),$C
+ mov 12($ctx),$D
+ mov $B,@T[0] # magic seed
+ mov 16($ctx),$E
+
+ movdqa 64($K_XX_XX),@X[2] # pbswap mask
+ movdqa 0($K_XX_XX),@Tx[1] # K_00_19
+ movdqu 0($inp),@X[-4&7] # load input to %xmm[0-3]
+ movdqu 16($inp),@X[-3&7]
+ movdqu 32($inp),@X[-2&7]
+ movdqu 48($inp),@X[-1&7]
+ pshufb @X[2],@X[-4&7] # byte swap
+ add \$64,$inp
+ pshufb @X[2],@X[-3&7]
+ pshufb @X[2],@X[-2&7]
+ pshufb @X[2],@X[-1&7]
+ paddd @Tx[1],@X[-4&7] # add K_00_19
+ paddd @Tx[1],@X[-3&7]
+ paddd @Tx[1],@X[-2&7]
+ movdqa @X[-4&7],0(%rsp) # X[]+K xfer to IALU
+ psubd @Tx[1],@X[-4&7] # restore X[]
+ movdqa @X[-3&7],16(%rsp)
+ psubd @Tx[1],@X[-3&7]
+ movdqa @X[-2&7],32(%rsp)
+ psubd @Tx[1],@X[-2&7]
+ movups ($key),$rndkey0 # $key[0]
+ movups 16($key),$rndkey[0] # forward reference
+ jmp .Loop_ssse3
+___
+
+my $aesenc=sub {
+ use integer;
+ my ($n,$k)=($r/10,$r%10);
+ if ($k==0) {
+ $code.=<<___;
+ movups `16*$n`($in0),$in # load input
+ xorps $rndkey0,$in
+___
+ $code.=<<___ if ($n);
+ movups $iv,`16*($n-1)`($out,$in0) # write output
+___
+ $code.=<<___;
+ xorps $in,$iv
+ aesenc $rndkey[0],$iv
+ movups `32+16*$k`($key),$rndkey[1]
+___
+ } elsif ($k==9) {
+ $sn++;
+ $code.=<<___;
+ cmp \$11,$rounds
+ jb .Laesenclast$sn
+ movups `32+16*($k+0)`($key),$rndkey[1]
+ aesenc $rndkey[0],$iv
+ movups `32+16*($k+1)`($key),$rndkey[0]
+ aesenc $rndkey[1],$iv
+ je .Laesenclast$sn
+ movups `32+16*($k+2)`($key),$rndkey[1]
+ aesenc $rndkey[0],$iv
+ movups `32+16*($k+3)`($key),$rndkey[0]
+ aesenc $rndkey[1],$iv
+.Laesenclast$sn:
+ aesenclast $rndkey[0],$iv
+ movups 16($key),$rndkey[1] # forward reference
+___
+ } else {
+ $code.=<<___;
+ aesenc $rndkey[0],$iv
+ movups `32+16*$k`($key),$rndkey[1]
+___
+ }
+ $r++; unshift(@rndkey,pop(@rndkey));
+};
+
+sub Xupdate_ssse3_16_31() # recall that $Xi starts wtih 4
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 40 instructions
+ my ($a,$b,$c,$d,$e);
+
+ &movdqa (@X[0],@X[-3&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (@Tx[0],@X[-1&7]);
+ &palignr(@X[0],@X[-4&7],8); # compose "X[-14]" in "X[0]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &paddd (@Tx[1],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &psrldq (@Tx[0],4); # "X[-3]", 3 dwords
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &pxor (@X[0],@X[-4&7]); # "X[0]"^="X[-16]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pxor (@Tx[0],@X[-2&7]); # "X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pxor (@X[0],@Tx[0]); # "X[0]"^="X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &movdqa (@Tx[2],@X[0]);
+ &movdqa (@Tx[0],@X[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pslldq (@Tx[2],12); # "X[0]"<<96, extract one dword
+ &paddd (@X[0],@X[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &psrld (@Tx[0],31);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (@Tx[1],@Tx[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &psrld (@Tx[2],30);
+ &por (@X[0],@Tx[0]); # "X[0]"<<<=1
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pslld (@Tx[1],2);
+ &pxor (@X[0],@Tx[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)"); # K_XX_XX
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pxor (@X[0],@Tx[1]); # "X[0]"^=("X[0]">>96)<<<2
+
+ foreach (@insns) { eval; } # remaining instructions [if any]
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+ push(@Tx,shift(@Tx));
+}
+
+sub Xupdate_ssse3_32_79()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions
+ my ($a,$b,$c,$d,$e);
+
+ &movdqa (@Tx[0],@X[-1&7]) if ($Xi==8);
+ eval(shift(@insns)); # body_20_39
+ &pxor (@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]"
+ &palignr(@Tx[0],@X[-2&7],8); # compose "X[-6]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &pxor (@X[0],@X[-7&7]); # "X[0]"^="X[-28]"
+ eval(shift(@insns));
+ eval(shift(@insns)) if (@insns[0] !~ /&ro[rl]/);
+ if ($Xi%5) {
+ &movdqa (@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX...
+ } else { # ... or load next one
+ &movdqa (@Tx[2],eval(16*($Xi/5))."($K_XX_XX)");
+ }
+ &paddd (@Tx[1],@X[-1&7]);
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &pxor (@X[0],@Tx[0]); # "X[0]"^="X[-6]"
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &movdqa (@Tx[0],@X[0]);
+ &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &pslld (@X[0],2);
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ &psrld (@Tx[0],30);
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &por (@X[0],@Tx[0]); # "X[0]"<<<=2
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ &movdqa (@Tx[1],@X[0]) if ($Xi<19);
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+ push(@Tx,shift(@Tx));
+}
+
+sub Xuplast_ssse3_80()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ &paddd (@Tx[1],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer IALU
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ &cmp ($inp,$len);
+ &je (".Ldone_ssse3");
+
+ unshift(@Tx,pop(@Tx));
+
+ &movdqa (@X[2],"64($K_XX_XX)"); # pbswap mask
+ &movdqa (@Tx[1],"0($K_XX_XX)"); # K_00_19
+ &movdqu (@X[-4&7],"0($inp)"); # load input
+ &movdqu (@X[-3&7],"16($inp)");
+ &movdqu (@X[-2&7],"32($inp)");
+ &movdqu (@X[-1&7],"48($inp)");
+ &pshufb (@X[-4&7],@X[2]); # byte swap
+ &add ($inp,64);
+
+ $Xi=0;
+}
+
+sub Xloop_ssse3()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &pshufb (@X[($Xi-3)&7],@X[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &paddd (@X[($Xi-4)&7],@Tx[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (eval(16*$Xi)."(%rsp)",@X[($Xi-4)&7]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &psubd (@X[($Xi-4)&7],@Tx[1]);
+
+ foreach (@insns) { eval; }
+ $Xi++;
+}
+
+sub Xtail_ssse3()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ foreach (@insns) { eval; }
+}
+
+sub body_00_19 () {
+ use integer;
+ my ($k,$n);
+ my @r=(
+ '($a,$b,$c,$d,$e)=@V;'.
+ '&add ($e,eval(4*($j&15))."(%rsp)");', # X[]+K xfer
+ '&xor ($c,$d);',
+ '&mov (@T[1],$a);', # $b in next round
+ '&$_rol ($a,5);',
+ '&and (@T[0],$c);', # ($b&($c^$d))
+ '&xor ($c,$d);', # restore $c
+ '&xor (@T[0],$d);',
+ '&add ($e,$a);',
+ '&$_ror ($b,$j?7:2);', # $b>>>2
+ '&add ($e,@T[0]);' .'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+ );
+ $n = scalar(@r);
+ $k = (($jj+1)*12/20)*20*$n/12; # 12 aesencs per these 20 rounds
+ @r[$k%$n].='&$aesenc();' if ($jj==$k/$n);
+ $jj++;
+ return @r;
+}
+
+sub body_20_39 () {
+ use integer;
+ my ($k,$n);
+ my @r=(
+ '($a,$b,$c,$d,$e)=@V;'.
+ '&add ($e,eval(4*($j++&15))."(%rsp)");', # X[]+K xfer
+ '&xor (@T[0],$d);', # ($b^$d)
+ '&mov (@T[1],$a);', # $b in next round
+ '&$_rol ($a,5);',
+ '&xor (@T[0],$c);', # ($b^$d^$c)
+ '&add ($e,$a);',
+ '&$_ror ($b,7);', # $b>>>2
+ '&add ($e,@T[0]);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+ );
+ $n = scalar(@r);
+ $k = (($jj+1)*8/20)*20*$n/8; # 8 aesencs per these 20 rounds
+ @r[$k%$n].='&$aesenc();' if ($jj==$k/$n);
+ $jj++;
+ return @r;
+}
+
+sub body_40_59 () {
+ use integer;
+ my ($k,$n);
+ my @r=(
+ '($a,$b,$c,$d,$e)=@V;'.
+ '&mov (@T[1],$c);',
+ '&xor ($c,$d);',
+ '&add ($e,eval(4*($j++&15))."(%rsp)");', # X[]+K xfer
+ '&and (@T[1],$d);',
+ '&and (@T[0],$c);', # ($b&($c^$d))
+ '&$_ror ($b,7);', # $b>>>2
+ '&add ($e,@T[1]);',
+ '&mov (@T[1],$a);', # $b in next round
+ '&$_rol ($a,5);',
+ '&add ($e,@T[0]);',
+ '&xor ($c,$d);', # restore $c
+ '&add ($e,$a);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+ );
+ $n = scalar(@r);
+ $k=(($jj+1)*12/20)*20*$n/12; # 12 aesencs per these 20 rounds
+ @r[$k%$n].='&$aesenc();' if ($jj==$k/$n);
+ $jj++;
+ return @r;
+}
+$code.=<<___;
+.align 16
+.Loop_ssse3:
+___
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_32_79(\&body_00_19);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xuplast_ssse3_80(\&body_20_39); # can jump to "done"
+
+ $saved_j=$j; @saved_V=@V;
+ $saved_r=$r; @saved_rndkey=@rndkey;
+
+ &Xloop_ssse3(\&body_20_39);
+ &Xloop_ssse3(\&body_20_39);
+ &Xloop_ssse3(\&body_20_39);
+
+$code.=<<___;
+ movups $iv,48($out,$in0) # write output
+ lea 64($in0),$in0
+
+ add 0($ctx),$A # update context
+ add 4($ctx),@T[0]
+ add 8($ctx),$C
+ add 12($ctx),$D
+ mov $A,0($ctx)
+ add 16($ctx),$E
+ mov @T[0],4($ctx)
+ mov @T[0],$B # magic seed
+ mov $C,8($ctx)
+ mov $D,12($ctx)
+ mov $E,16($ctx)
+ jmp .Loop_ssse3
+
+.align 16
+.Ldone_ssse3:
+___
+ $jj=$j=$saved_j; @V=@saved_V;
+ $r=$saved_r; @rndkey=@saved_rndkey;
+
+ &Xtail_ssse3(\&body_20_39);
+ &Xtail_ssse3(\&body_20_39);
+ &Xtail_ssse3(\&body_20_39);
+
+$code.=<<___;
+ movups $iv,48($out,$in0) # write output
+ mov 88(%rsp),$ivp # restore $ivp
+
+ add 0($ctx),$A # update context
+ add 4($ctx),@T[0]
+ add 8($ctx),$C
+ mov $A,0($ctx)
+ add 12($ctx),$D
+ mov @T[0],4($ctx)
+ add 16($ctx),$E
+ mov $C,8($ctx)
+ mov $D,12($ctx)
+ mov $E,16($ctx)
+ movups $iv,($ivp) # write IV
+___
+$code.=<<___ if ($win64);
+ movaps 96+0(%rsp),%xmm6
+ movaps 96+16(%rsp),%xmm7
+ movaps 96+32(%rsp),%xmm8
+ movaps 96+48(%rsp),%xmm9
+ movaps 96+64(%rsp),%xmm10
+ movaps 96+80(%rsp),%xmm11
+ movaps 96+96(%rsp),%xmm12
+ movaps 96+112(%rsp),%xmm13
+ movaps 96+128(%rsp),%xmm14
+ movaps 96+144(%rsp),%xmm15
+___
+$code.=<<___;
+ lea `104+($win64?10*16:0)`(%rsp),%rsi
+ mov 0(%rsi),%r15
+ mov 8(%rsi),%r14
+ mov 16(%rsi),%r13
+ mov 24(%rsi),%r12
+ mov 32(%rsi),%rbp
+ mov 40(%rsi),%rbx
+ lea 48(%rsi),%rsp
+.Lepilogue_ssse3:
+ ret
+.size aesni_cbc_sha1_enc_ssse3,.-aesni_cbc_sha1_enc_ssse3
+___
+
+$j=$jj=$r=$sn=0;
+
+if ($avx) {
+my ($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
+
+my $Xi=4;
+my @X=map("%xmm$_",(4..7,0..3));
+my @Tx=map("%xmm$_",(8..10));
+my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp"); # size optimization
+my @T=("%esi","%edi");
+
+my $_rol=sub { &shld(@_[0],@_) };
+my $_ror=sub { &shrd(@_[0],@_) };
+
+$code.=<<___;
+.type aesni_cbc_sha1_enc_avx,\@function,6
+.align 16
+aesni_cbc_sha1_enc_avx:
+ mov `($win64?56:8)`(%rsp),$inp # load 7th argument
+ #shr \$6,$len # debugging artefact
+ #jz .Lepilogue_avx # debugging artefact
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ lea `-104-($win64?10*16:0)`(%rsp),%rsp
+ #mov $in0,$inp # debugging artefact
+ #lea 64(%rsp),$ctx # debugging artefact
+___
+$code.=<<___ if ($win64);
+ movaps %xmm6,96+0(%rsp)
+ movaps %xmm7,96+16(%rsp)
+ movaps %xmm8,96+32(%rsp)
+ movaps %xmm9,96+48(%rsp)
+ movaps %xmm10,96+64(%rsp)
+ movaps %xmm11,96+80(%rsp)
+ movaps %xmm12,96+96(%rsp)
+ movaps %xmm13,96+112(%rsp)
+ movaps %xmm14,96+128(%rsp)
+ movaps %xmm15,96+144(%rsp)
+.Lprologue_avx:
+___
+$code.=<<___;
+ vzeroall
+ mov $in0,%r12 # reassign arguments
+ mov $out,%r13
+ mov $len,%r14
+ mov $key,%r15
+ vmovdqu ($ivp),$iv # load IV
+ mov $ivp,88(%rsp) # save $ivp
+___
+my ($in0,$out,$len,$key)=map("%r$_",(12..15)); # reassign arguments
+my $rounds="${ivp}d";
+$code.=<<___;
+ shl \$6,$len
+ sub $in0,$out
+ mov 240($key),$rounds
+ add \$112,$key # size optimization
+ add $inp,$len # end of input
+
+ lea K_XX_XX(%rip),$K_XX_XX
+ mov 0($ctx),$A # load context
+ mov 4($ctx),$B
+ mov 8($ctx),$C
+ mov 12($ctx),$D
+ mov $B,@T[0] # magic seed
+ mov 16($ctx),$E
+
+ vmovdqa 64($K_XX_XX),@X[2] # pbswap mask
+ vmovdqa 0($K_XX_XX),@Tx[1] # K_00_19
+ vmovdqu 0($inp),@X[-4&7] # load input to %xmm[0-3]
+ vmovdqu 16($inp),@X[-3&7]
+ vmovdqu 32($inp),@X[-2&7]
+ vmovdqu 48($inp),@X[-1&7]
+ vpshufb @X[2],@X[-4&7],@X[-4&7] # byte swap
+ add \$64,$inp
+ vpshufb @X[2],@X[-3&7],@X[-3&7]
+ vpshufb @X[2],@X[-2&7],@X[-2&7]
+ vpshufb @X[2],@X[-1&7],@X[-1&7]
+ vpaddd @Tx[1],@X[-4&7],@X[0] # add K_00_19
+ vpaddd @Tx[1],@X[-3&7],@X[1]
+ vpaddd @Tx[1],@X[-2&7],@X[2]
+ vmovdqa @X[0],0(%rsp) # X[]+K xfer to IALU
+ vmovdqa @X[1],16(%rsp)
+ vmovdqa @X[2],32(%rsp)
+ vmovups -112($key),$rndkey0 # $key[0]
+ vmovups 16-112($key),$rndkey[0] # forward reference
+ jmp .Loop_avx
+___
+
+my $aesenc=sub {
+ use integer;
+ my ($n,$k)=($r/10,$r%10);
+ if ($k==0) {
+ $code.=<<___;
+ vmovups `16*$n`($in0),$in # load input
+ vxorps $rndkey0,$in,$in
+___
+ $code.=<<___ if ($n);
+ vmovups $iv,`16*($n-1)`($out,$in0) # write output
+___
+ $code.=<<___;
+ vxorps $in,$iv,$iv
+ vaesenc $rndkey[0],$iv,$iv
+ vmovups `32+16*$k-112`($key),$rndkey[1]
+___
+ } elsif ($k==9) {
+ $sn++;
+ $code.=<<___;
+ cmp \$11,$rounds
+ jb .Lvaesenclast$sn
+ vaesenc $rndkey[0],$iv,$iv
+ vmovups `32+16*($k+0)-112`($key),$rndkey[1]
+ vaesenc $rndkey[1],$iv,$iv
+ vmovups `32+16*($k+1)-112`($key),$rndkey[0]
+ je .Lvaesenclast$sn
+ vaesenc $rndkey[0],$iv,$iv
+ vmovups `32+16*($k+2)-112`($key),$rndkey[1]
+ vaesenc $rndkey[1],$iv,$iv
+ vmovups `32+16*($k+3)-112`($key),$rndkey[0]
+.Lvaesenclast$sn:
+ vaesenclast $rndkey[0],$iv,$iv
+ vmovups 16-112($key),$rndkey[1] # forward reference
+___
+ } else {
+ $code.=<<___;
+ vaesenc $rndkey[0],$iv,$iv
+ vmovups `32+16*$k-112`($key),$rndkey[1]
+___
+ }
+ $r++; unshift(@rndkey,pop(@rndkey));
+};
+
+sub Xupdate_avx_16_31() # recall that $Xi starts wtih 4
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 40 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpalignr(@X[0],@X[-3&7],@X[-4&7],8); # compose "X[-14]" in "X[0]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpaddd (@Tx[1],@Tx[1],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpsrldq(@Tx[0],@X[-1&7],4); # "X[-3]", 3 dwords
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"^="X[-16]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpxor (@Tx[0],@Tx[0],@X[-2&7]); # "X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpxor (@X[0],@X[0],@Tx[0]); # "X[0]"^="X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vmovdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpsrld (@Tx[0],@X[0],31);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpslldq(@Tx[2],@X[0],12); # "X[0]"<<96, extract one dword
+ &vpaddd (@X[0],@X[0],@X[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpsrld (@Tx[1],@Tx[2],30);
+ &vpor (@X[0],@X[0],@Tx[0]); # "X[0]"<<<=1
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpslld (@Tx[2],@Tx[2],2);
+ &vpxor (@X[0],@X[0],@Tx[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpxor (@X[0],@X[0],@Tx[2]); # "X[0]"^=("X[0]">>96)<<<2
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vmovdqa (@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)"); # K_XX_XX
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+
+ foreach (@insns) { eval; } # remaining instructions [if any]
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+ push(@Tx,shift(@Tx));
+}
+
+sub Xupdate_avx_32_79()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions
+ my ($a,$b,$c,$d,$e);
+
+ &vpalignr(@Tx[0],@X[-1&7],@X[-2&7],8); # compose "X[-6]"
+ &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]"
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &vpxor (@X[0],@X[0],@X[-7&7]); # "X[0]"^="X[-28]"
+ eval(shift(@insns));
+ eval(shift(@insns)) if (@insns[0] !~ /&ro[rl]/);
+ if ($Xi%5) {
+ &vmovdqa (@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX...
+ } else { # ... or load next one
+ &vmovdqa (@Tx[2],eval(16*($Xi/5))."($K_XX_XX)");
+ }
+ &vpaddd (@Tx[1],@Tx[1],@X[-1&7]);
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &vpxor (@X[0],@X[0],@Tx[0]); # "X[0]"^="X[-6]"
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &vpsrld (@Tx[0],@X[0],30);
+ &vmovdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &vpslld (@X[0],@X[0],2);
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &vpor (@X[0],@X[0],@Tx[0]); # "X[0]"<<<=2
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ &vmovdqa (@Tx[1],@X[0]) if ($Xi<19);
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+ push(@Tx,shift(@Tx));
+}
+
+sub Xuplast_avx_80()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ &vpaddd (@Tx[1],@Tx[1],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer IALU
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ &cmp ($inp,$len);
+ &je (".Ldone_avx");
+
+ unshift(@Tx,pop(@Tx));
+
+ &vmovdqa(@X[2],"64($K_XX_XX)"); # pbswap mask
+ &vmovdqa(@Tx[1],"0($K_XX_XX)"); # K_00_19
+ &vmovdqu(@X[-4&7],"0($inp)"); # load input
+ &vmovdqu(@X[-3&7],"16($inp)");
+ &vmovdqu(@X[-2&7],"32($inp)");
+ &vmovdqu(@X[-1&7],"48($inp)");
+ &vpshufb(@X[-4&7],@X[-4&7],@X[2]); # byte swap
+ &add ($inp,64);
+
+ $Xi=0;
+}
+
+sub Xloop_avx()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpshufb(@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpaddd (@X[$Xi&7],@X[($Xi-4)&7],@Tx[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vmovdqa(eval(16*$Xi)."(%rsp)",@X[$Xi&7]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; }
+ $Xi++;
+}
+
+sub Xtail_avx()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ foreach (@insns) { eval; }
+}
+
+$code.=<<___;
+.align 16
+.Loop_avx:
+___
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_32_79(\&body_00_19);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xuplast_avx_80(\&body_20_39); # can jump to "done"
+
+ $saved_j=$j; @saved_V=@V;
+ $saved_r=$r; @saved_rndkey=@rndkey;
+
+ &Xloop_avx(\&body_20_39);
+ &Xloop_avx(\&body_20_39);
+ &Xloop_avx(\&body_20_39);
+
+$code.=<<___;
+ vmovups $iv,48($out,$in0) # write output
+ lea 64($in0),$in0
+
+ add 0($ctx),$A # update context
+ add 4($ctx),@T[0]
+ add 8($ctx),$C
+ add 12($ctx),$D
+ mov $A,0($ctx)
+ add 16($ctx),$E
+ mov @T[0],4($ctx)
+ mov @T[0],$B # magic seed
+ mov $C,8($ctx)
+ mov $D,12($ctx)
+ mov $E,16($ctx)
+ jmp .Loop_avx
+
+.align 16
+.Ldone_avx:
+___
+ $jj=$j=$saved_j; @V=@saved_V;
+ $r=$saved_r; @rndkey=@saved_rndkey;
+
+ &Xtail_avx(\&body_20_39);
+ &Xtail_avx(\&body_20_39);
+ &Xtail_avx(\&body_20_39);
+
+$code.=<<___;
+ vmovups $iv,48($out,$in0) # write output
+ mov 88(%rsp),$ivp # restore $ivp
+
+ add 0($ctx),$A # update context
+ add 4($ctx),@T[0]
+ add 8($ctx),$C
+ mov $A,0($ctx)
+ add 12($ctx),$D
+ mov @T[0],4($ctx)
+ add 16($ctx),$E
+ mov $C,8($ctx)
+ mov $D,12($ctx)
+ mov $E,16($ctx)
+ vmovups $iv,($ivp) # write IV
+ vzeroall
+___
+$code.=<<___ if ($win64);
+ movaps 96+0(%rsp),%xmm6
+ movaps 96+16(%rsp),%xmm7
+ movaps 96+32(%rsp),%xmm8
+ movaps 96+48(%rsp),%xmm9
+ movaps 96+64(%rsp),%xmm10
+ movaps 96+80(%rsp),%xmm11
+ movaps 96+96(%rsp),%xmm12
+ movaps 96+112(%rsp),%xmm13
+ movaps 96+128(%rsp),%xmm14
+ movaps 96+144(%rsp),%xmm15
+___
+$code.=<<___;
+ lea `104+($win64?10*16:0)`(%rsp),%rsi
+ mov 0(%rsi),%r15
+ mov 8(%rsi),%r14
+ mov 16(%rsi),%r13
+ mov 24(%rsi),%r12
+ mov 32(%rsi),%rbp
+ mov 40(%rsi),%rbx
+ lea 48(%rsi),%rsp
+.Lepilogue_avx:
+ ret
+.size aesni_cbc_sha1_enc_avx,.-aesni_cbc_sha1_enc_avx
+___
+}
+$code.=<<___;
+.align 64
+K_XX_XX:
+.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 # K_00_19
+.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 # K_20_39
+.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc # K_40_59
+.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 # K_60_79
+.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f # pbswap mask
+
+.asciz "AESNI-CBC+SHA1 stitch for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align 64
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+.type ssse3_handler,\@abi-omnipotent
+.align 16
+ssse3_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # prologue label
+ cmp %r10,%rbx # context->Rip<prologue label
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lcommon_seh_tail
+
+ lea 96(%rax),%rsi
+ lea 512($context),%rdi # &context.Xmm6
+ mov \$20,%ecx
+ .long 0xa548f3fc # cld; rep movsq
+ lea `104+10*16`(%rax),%rax # adjust stack pointer
+
+ mov 0(%rax),%r15
+ mov 8(%rax),%r14
+ mov 16(%rax),%r13
+ mov 24(%rax),%r12
+ mov 32(%rax),%rbp
+ mov 40(%rax),%rbx
+ lea 48(%rax),%rax
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R13
+ mov %r14,232($context) # restore context->R14
+ mov %r15,240($context) # restore context->R15
+
+.Lcommon_seh_tail:
+ mov 8(%rax),%rdi
+ mov 16(%rax),%rsi
+ mov %rax,152($context) # restore context->Rsp
+ mov %rsi,168($context) # restore context->Rsi
+ mov %rdi,176($context) # restore context->Rdi
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$154,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size ssse3_handler,.-ssse3_handler
+
+.section .pdata
+.align 4
+ .rva .LSEH_begin_aesni_cbc_sha1_enc_ssse3
+ .rva .LSEH_end_aesni_cbc_sha1_enc_ssse3
+ .rva .LSEH_info_aesni_cbc_sha1_enc_ssse3
+___
+$code.=<<___ if ($avx);
+ .rva .LSEH_begin_aesni_cbc_sha1_enc_avx
+ .rva .LSEH_end_aesni_cbc_sha1_enc_avx
+ .rva .LSEH_info_aesni_cbc_sha1_enc_avx
+___
+$code.=<<___;
+.section .xdata
+.align 8
+.LSEH_info_aesni_cbc_sha1_enc_ssse3:
+ .byte 9,0,0,0
+ .rva ssse3_handler
+ .rva .Lprologue_ssse3,.Lepilogue_ssse3 # HandlerData[]
+___
+$code.=<<___ if ($avx);
+.LSEH_info_aesni_cbc_sha1_enc_avx:
+ .byte 9,0,0,0
+ .rva ssse3_handler
+ .rva .Lprologue_avx,.Lepilogue_avx # HandlerData[]
+___
+}
+
+####################################################################
+sub rex {
+ local *opcode=shift;
+ my ($dst,$src)=@_;
+ my $rex=0;
+
+ $rex|=0x04 if($dst>=8);
+ $rex|=0x01 if($src>=8);
+ push @opcode,$rex|0x40 if($rex);
+}
+
+sub aesni {
+ my $line=shift;
+ my @opcode=(0x66);
+
+ if ($line=~/(aes[a-z]+)\s+%xmm([0-9]+),\s*%xmm([0-9]+)/) {
+ my %opcodelet = (
+ "aesenc" => 0xdc, "aesenclast" => 0xdd
+ );
+ return undef if (!defined($opcodelet{$1}));
+ rex(\@opcode,$3,$2);
+ push @opcode,0x0f,0x38,$opcodelet{$1};
+ push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M
+ return ".byte\t".join(',',@opcode);
+ }
+ return $line;
+}
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+$code =~ s/\b(aes.*%xmm[0-9]+).*$/aesni($1)/gem;
+
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/aes/asm/aesni-x86.pl b/deps/openssl/openssl/crypto/aes/asm/aesni-x86.pl
new file mode 100644
index 000000000..3dc345b58
--- /dev/null
+++ b/deps/openssl/openssl/crypto/aes/asm/aesni-x86.pl
@@ -0,0 +1,2189 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# This module implements support for Intel AES-NI extension. In
+# OpenSSL context it's used with Intel engine, but can also be used as
+# drop-in replacement for crypto/aes/asm/aes-586.pl [see below for
+# details].
+#
+# Performance.
+#
+# To start with see corresponding paragraph in aesni-x86_64.pl...
+# Instead of filling table similar to one found there I've chosen to
+# summarize *comparison* results for raw ECB, CTR and CBC benchmarks.
+# The simplified table below represents 32-bit performance relative
+# to 64-bit one in every given point. Ratios vary for different
+# encryption modes, therefore interval values.
+#
+# 16-byte 64-byte 256-byte 1-KB 8-KB
+# 53-67% 67-84% 91-94% 95-98% 97-99.5%
+#
+# Lower ratios for smaller block sizes are perfectly understandable,
+# because function call overhead is higher in 32-bit mode. Largest
+# 8-KB block performance is virtually same: 32-bit code is less than
+# 1% slower for ECB, CBC and CCM, and ~3% slower otherwise.
+
+# January 2011
+#
+# See aesni-x86_64.pl for details. Unlike x86_64 version this module
+# interleaves at most 6 aes[enc|dec] instructions, because there are
+# not enough registers for 8x interleave [which should be optimal for
+# Sandy Bridge]. Actually, performance results for 6x interleave
+# factor presented in aesni-x86_64.pl (except for CTR) are for this
+# module.
+
+# April 2011
+#
+# Add aesni_xts_[en|de]crypt. Westmere spends 1.50 cycles processing
+# one byte out of 8KB with 128-bit key, Sandy Bridge - 1.09.
+
+$PREFIX="aesni"; # if $PREFIX is set to "AES", the script
+ # generates drop-in replacement for
+ # crypto/aes/asm/aes-586.pl:-)
+$inline=1; # inline _aesni_[en|de]crypt
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],$0);
+
+if ($PREFIX eq "aesni") { $movekey=*movups; }
+else { $movekey=*movups; }
+
+$len="eax";
+$rounds="ecx";
+$key="edx";
+$inp="esi";
+$out="edi";
+$rounds_="ebx"; # backup copy for $rounds
+$key_="ebp"; # backup copy for $key
+
+$rndkey0="xmm0";
+$rndkey1="xmm1";
+$inout0="xmm2";
+$inout1="xmm3";
+$inout2="xmm4";
+$inout3="xmm5"; $in1="xmm5";
+$inout4="xmm6"; $in0="xmm6";
+$inout5="xmm7"; $ivec="xmm7";
+
+# AESNI extenstion
+sub aeskeygenassist
+{ my($dst,$src,$imm)=@_;
+ if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
+ { &data_byte(0x66,0x0f,0x3a,0xdf,0xc0|($1<<3)|$2,$imm); }
+}
+sub aescommon
+{ my($opcodelet,$dst,$src)=@_;
+ if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
+ { &data_byte(0x66,0x0f,0x38,$opcodelet,0xc0|($1<<3)|$2);}
+}
+sub aesimc { aescommon(0xdb,@_); }
+sub aesenc { aescommon(0xdc,@_); }
+sub aesenclast { aescommon(0xdd,@_); }
+sub aesdec { aescommon(0xde,@_); }
+sub aesdeclast { aescommon(0xdf,@_); }
+
+# Inline version of internal aesni_[en|de]crypt1
+{ my $sn;
+sub aesni_inline_generate1
+{ my ($p,$inout,$ivec)=@_; $inout=$inout0 if (!defined($inout));
+ $sn++;
+
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &$movekey ($rndkey1,&QWP(16,$key));
+ &xorps ($ivec,$rndkey0) if (defined($ivec));
+ &lea ($key,&DWP(32,$key));
+ &xorps ($inout,$ivec) if (defined($ivec));
+ &xorps ($inout,$rndkey0) if (!defined($ivec));
+ &set_label("${p}1_loop_$sn");
+ eval"&aes${p} ($inout,$rndkey1)";
+ &dec ($rounds);
+ &$movekey ($rndkey1,&QWP(0,$key));
+ &lea ($key,&DWP(16,$key));
+ &jnz (&label("${p}1_loop_$sn"));
+ eval"&aes${p}last ($inout,$rndkey1)";
+}}
+
+sub aesni_generate1 # fully unrolled loop
+{ my ($p,$inout)=@_; $inout=$inout0 if (!defined($inout));
+
+ &function_begin_B("_aesni_${p}rypt1");
+ &movups ($rndkey0,&QWP(0,$key));
+ &$movekey ($rndkey1,&QWP(0x10,$key));
+ &xorps ($inout,$rndkey0);
+ &$movekey ($rndkey0,&QWP(0x20,$key));
+ &lea ($key,&DWP(0x30,$key));
+ &cmp ($rounds,11);
+ &jb (&label("${p}128"));
+ &lea ($key,&DWP(0x20,$key));
+ &je (&label("${p}192"));
+ &lea ($key,&DWP(0x20,$key));
+ eval"&aes${p} ($inout,$rndkey1)";
+ &$movekey ($rndkey1,&QWP(-0x40,$key));
+ eval"&aes${p} ($inout,$rndkey0)";
+ &$movekey ($rndkey0,&QWP(-0x30,$key));
+ &set_label("${p}192");
+ eval"&aes${p} ($inout,$rndkey1)";
+ &$movekey ($rndkey1,&QWP(-0x20,$key));
+ eval"&aes${p} ($inout,$rndkey0)";
+ &$movekey ($rndkey0,&QWP(-0x10,$key));
+ &set_label("${p}128");
+ eval"&aes${p} ($inout,$rndkey1)";
+ &$movekey ($rndkey1,&QWP(0,$key));
+ eval"&aes${p} ($inout,$rndkey0)";
+ &$movekey ($rndkey0,&QWP(0x10,$key));
+ eval"&aes${p} ($inout,$rndkey1)";
+ &$movekey ($rndkey1,&QWP(0x20,$key));
+ eval"&aes${p} ($inout,$rndkey0)";
+ &$movekey ($rndkey0,&QWP(0x30,$key));
+ eval"&aes${p} ($inout,$rndkey1)";
+ &$movekey ($rndkey1,&QWP(0x40,$key));
+ eval"&aes${p} ($inout,$rndkey0)";
+ &$movekey ($rndkey0,&QWP(0x50,$key));
+ eval"&aes${p} ($inout,$rndkey1)";
+ &$movekey ($rndkey1,&QWP(0x60,$key));
+ eval"&aes${p} ($inout,$rndkey0)";
+ &$movekey ($rndkey0,&QWP(0x70,$key));
+ eval"&aes${p} ($inout,$rndkey1)";
+ eval"&aes${p}last ($inout,$rndkey0)";
+ &ret();
+ &function_end_B("_aesni_${p}rypt1");
+}
+
+# void $PREFIX_encrypt (const void *inp,void *out,const AES_KEY *key);
+&aesni_generate1("enc") if (!$inline);
+&function_begin_B("${PREFIX}_encrypt");
+ &mov ("eax",&wparam(0));
+ &mov ($key,&wparam(2));
+ &movups ($inout0,&QWP(0,"eax"));
+ &mov ($rounds,&DWP(240,$key));
+ &mov ("eax",&wparam(1));
+ if ($inline)
+ { &aesni_inline_generate1("enc"); }
+ else
+ { &call ("_aesni_encrypt1"); }
+ &movups (&QWP(0,"eax"),$inout0);
+ &ret ();
+&function_end_B("${PREFIX}_encrypt");
+
+# void $PREFIX_decrypt (const void *inp,void *out,const AES_KEY *key);
+&aesni_generate1("dec") if(!$inline);
+&function_begin_B("${PREFIX}_decrypt");
+ &mov ("eax",&wparam(0));
+ &mov ($key,&wparam(2));
+ &movups ($inout0,&QWP(0,"eax"));
+ &mov ($rounds,&DWP(240,$key));
+ &mov ("eax",&wparam(1));
+ if ($inline)
+ { &aesni_inline_generate1("dec"); }
+ else
+ { &call ("_aesni_decrypt1"); }
+ &movups (&QWP(0,"eax"),$inout0);
+ &ret ();
+&function_end_B("${PREFIX}_decrypt");
+
+# _aesni_[en|de]cryptN are private interfaces, N denotes interleave
+# factor. Why 3x subroutine were originally used in loops? Even though
+# aes[enc|dec] latency was originally 6, it could be scheduled only
+# every *2nd* cycle. Thus 3x interleave was the one providing optimal
+# utilization, i.e. when subroutine's throughput is virtually same as
+# of non-interleaved subroutine [for number of input blocks up to 3].
+# This is why it makes no sense to implement 2x subroutine.
+# aes[enc|dec] latency in next processor generation is 8, but the
+# instructions can be scheduled every cycle. Optimal interleave for
+# new processor is therefore 8x, but it's unfeasible to accommodate it
+# in XMM registers addreassable in 32-bit mode and therefore 6x is
+# used instead...
+
+sub aesni_generate3
+{ my $p=shift;
+
+ &function_begin_B("_aesni_${p}rypt3");
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &shr ($rounds,1);
+ &$movekey ($rndkey1,&QWP(16,$key));
+ &lea ($key,&DWP(32,$key));
+ &xorps ($inout0,$rndkey0);
+ &pxor ($inout1,$rndkey0);
+ &pxor ($inout2,$rndkey0);
+ &$movekey ($rndkey0,&QWP(0,$key));
+
+ &set_label("${p}3_loop");
+ eval"&aes${p} ($inout0,$rndkey1)";
+ eval"&aes${p} ($inout1,$rndkey1)";
+ &dec ($rounds);
+ eval"&aes${p} ($inout2,$rndkey1)";
+ &$movekey ($rndkey1,&QWP(16,$key));
+ eval"&aes${p} ($inout0,$rndkey0)";
+ eval"&aes${p} ($inout1,$rndkey0)";
+ &lea ($key,&DWP(32,$key));
+ eval"&aes${p} ($inout2,$rndkey0)";
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &jnz (&label("${p}3_loop"));
+ eval"&aes${p} ($inout0,$rndkey1)";
+ eval"&aes${p} ($inout1,$rndkey1)";
+ eval"&aes${p} ($inout2,$rndkey1)";
+ eval"&aes${p}last ($inout0,$rndkey0)";
+ eval"&aes${p}last ($inout1,$rndkey0)";
+ eval"&aes${p}last ($inout2,$rndkey0)";
+ &ret();
+ &function_end_B("_aesni_${p}rypt3");
+}
+
+# 4x interleave is implemented to improve small block performance,
+# most notably [and naturally] 4 block by ~30%. One can argue that one
+# should have implemented 5x as well, but improvement would be <20%,
+# so it's not worth it...
+sub aesni_generate4
+{ my $p=shift;
+
+ &function_begin_B("_aesni_${p}rypt4");
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &$movekey ($rndkey1,&QWP(16,$key));
+ &shr ($rounds,1);
+ &lea ($key,&DWP(32,$key));
+ &xorps ($inout0,$rndkey0);
+ &pxor ($inout1,$rndkey0);
+ &pxor ($inout2,$rndkey0);
+ &pxor ($inout3,$rndkey0);
+ &$movekey ($rndkey0,&QWP(0,$key));
+
+ &set_label("${p}4_loop");
+ eval"&aes${p} ($inout0,$rndkey1)";
+ eval"&aes${p} ($inout1,$rndkey1)";
+ &dec ($rounds);
+ eval"&aes${p} ($inout2,$rndkey1)";
+ eval"&aes${p} ($inout3,$rndkey1)";
+ &$movekey ($rndkey1,&QWP(16,$key));
+ eval"&aes${p} ($inout0,$rndkey0)";
+ eval"&aes${p} ($inout1,$rndkey0)";
+ &lea ($key,&DWP(32,$key));
+ eval"&aes${p} ($inout2,$rndkey0)";
+ eval"&aes${p} ($inout3,$rndkey0)";
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &jnz (&label("${p}4_loop"));
+
+ eval"&aes${p} ($inout0,$rndkey1)";
+ eval"&aes${p} ($inout1,$rndkey1)";
+ eval"&aes${p} ($inout2,$rndkey1)";
+ eval"&aes${p} ($inout3,$rndkey1)";
+ eval"&aes${p}last ($inout0,$rndkey0)";
+ eval"&aes${p}last ($inout1,$rndkey0)";
+ eval"&aes${p}last ($inout2,$rndkey0)";
+ eval"&aes${p}last ($inout3,$rndkey0)";
+ &ret();
+ &function_end_B("_aesni_${p}rypt4");
+}
+
+sub aesni_generate6
+{ my $p=shift;
+
+ &function_begin_B("_aesni_${p}rypt6");
+ &static_label("_aesni_${p}rypt6_enter");
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &shr ($rounds,1);
+ &$movekey ($rndkey1,&QWP(16,$key));
+ &lea ($key,&DWP(32,$key));
+ &xorps ($inout0,$rndkey0);
+ &pxor ($inout1,$rndkey0); # pxor does better here
+ eval"&aes${p} ($inout0,$rndkey1)";
+ &pxor ($inout2,$rndkey0);
+ eval"&aes${p} ($inout1,$rndkey1)";
+ &pxor ($inout3,$rndkey0);
+ &dec ($rounds);
+ eval"&aes${p} ($inout2,$rndkey1)";
+ &pxor ($inout4,$rndkey0);
+ eval"&aes${p} ($inout3,$rndkey1)";
+ &pxor ($inout5,$rndkey0);
+ eval"&aes${p} ($inout4,$rndkey1)";
+ &$movekey ($rndkey0,&QWP(0,$key));
+ eval"&aes${p} ($inout5,$rndkey1)";
+ &jmp (&label("_aesni_${p}rypt6_enter"));
+
+ &set_label("${p}6_loop",16);
+ eval"&aes${p} ($inout0,$rndkey1)";
+ eval"&aes${p} ($inout1,$rndkey1)";
+ &dec ($rounds);
+ eval"&aes${p} ($inout2,$rndkey1)";
+ eval"&aes${p} ($inout3,$rndkey1)";
+ eval"&aes${p} ($inout4,$rndkey1)";
+ eval"&aes${p} ($inout5,$rndkey1)";
+ &set_label("_aesni_${p}rypt6_enter",16);
+ &$movekey ($rndkey1,&QWP(16,$key));
+ eval"&aes${p} ($inout0,$rndkey0)";
+ eval"&aes${p} ($inout1,$rndkey0)";
+ &lea ($key,&DWP(32,$key));
+ eval"&aes${p} ($inout2,$rndkey0)";
+ eval"&aes${p} ($inout3,$rndkey0)";
+ eval"&aes${p} ($inout4,$rndkey0)";
+ eval"&aes${p} ($inout5,$rndkey0)";
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &jnz (&label("${p}6_loop"));
+
+ eval"&aes${p} ($inout0,$rndkey1)";
+ eval"&aes${p} ($inout1,$rndkey1)";
+ eval"&aes${p} ($inout2,$rndkey1)";
+ eval"&aes${p} ($inout3,$rndkey1)";
+ eval"&aes${p} ($inout4,$rndkey1)";
+ eval"&aes${p} ($inout5,$rndkey1)";
+ eval"&aes${p}last ($inout0,$rndkey0)";
+ eval"&aes${p}last ($inout1,$rndkey0)";
+ eval"&aes${p}last ($inout2,$rndkey0)";
+ eval"&aes${p}last ($inout3,$rndkey0)";
+ eval"&aes${p}last ($inout4,$rndkey0)";
+ eval"&aes${p}last ($inout5,$rndkey0)";
+ &ret();
+ &function_end_B("_aesni_${p}rypt6");
+}
+&aesni_generate3("enc") if ($PREFIX eq "aesni");
+&aesni_generate3("dec");
+&aesni_generate4("enc") if ($PREFIX eq "aesni");
+&aesni_generate4("dec");
+&aesni_generate6("enc") if ($PREFIX eq "aesni");
+&aesni_generate6("dec");
+
+if ($PREFIX eq "aesni") {
+######################################################################
+# void aesni_ecb_encrypt (const void *in, void *out,
+# size_t length, const AES_KEY *key,
+# int enc);
+&function_begin("aesni_ecb_encrypt");
+ &mov ($inp,&wparam(0));
+ &mov ($out,&wparam(1));
+ &mov ($len,&wparam(2));
+ &mov ($key,&wparam(3));
+ &mov ($rounds_,&wparam(4));
+ &and ($len,-16);
+ &jz (&label("ecb_ret"));
+ &mov ($rounds,&DWP(240,$key));
+ &test ($rounds_,$rounds_);
+ &jz (&label("ecb_decrypt"));
+
+ &mov ($key_,$key); # backup $key
+ &mov ($rounds_,$rounds); # backup $rounds
+ &cmp ($len,0x60);
+ &jb (&label("ecb_enc_tail"));
+
+ &movdqu ($inout0,&QWP(0,$inp));
+ &movdqu ($inout1,&QWP(0x10,$inp));
+ &movdqu ($inout2,&QWP(0x20,$inp));
+ &movdqu ($inout3,&QWP(0x30,$inp));
+ &movdqu ($inout4,&QWP(0x40,$inp));
+ &movdqu ($inout5,&QWP(0x50,$inp));
+ &lea ($inp,&DWP(0x60,$inp));
+ &sub ($len,0x60);
+ &jmp (&label("ecb_enc_loop6_enter"));
+
+&set_label("ecb_enc_loop6",16);
+ &movups (&QWP(0,$out),$inout0);
+ &movdqu ($inout0,&QWP(0,$inp));
+ &movups (&QWP(0x10,$out),$inout1);
+ &movdqu ($inout1,&QWP(0x10,$inp));
+ &movups (&QWP(0x20,$out),$inout2);
+ &movdqu ($inout2,&QWP(0x20,$inp));
+ &movups (&QWP(0x30,$out),$inout3);
+ &movdqu ($inout3,&QWP(0x30,$inp));
+ &movups (&QWP(0x40,$out),$inout4);
+ &movdqu ($inout4,&QWP(0x40,$inp));
+ &movups (&QWP(0x50,$out),$inout5);
+ &lea ($out,&DWP(0x60,$out));
+ &movdqu ($inout5,&QWP(0x50,$inp));
+ &lea ($inp,&DWP(0x60,$inp));
+&set_label("ecb_enc_loop6_enter");
+
+ &call ("_aesni_encrypt6");
+
+ &mov ($key,$key_); # restore $key
+ &mov ($rounds,$rounds_); # restore $rounds
+ &sub ($len,0x60);
+ &jnc (&label("ecb_enc_loop6"));
+
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &movups (&QWP(0x30,$out),$inout3);
+ &movups (&QWP(0x40,$out),$inout4);
+ &movups (&QWP(0x50,$out),$inout5);
+ &lea ($out,&DWP(0x60,$out));
+ &add ($len,0x60);
+ &jz (&label("ecb_ret"));
+
+&set_label("ecb_enc_tail");
+ &movups ($inout0,&QWP(0,$inp));
+ &cmp ($len,0x20);
+ &jb (&label("ecb_enc_one"));
+ &movups ($inout1,&QWP(0x10,$inp));
+ &je (&label("ecb_enc_two"));
+ &movups ($inout2,&QWP(0x20,$inp));
+ &cmp ($len,0x40);
+ &jb (&label("ecb_enc_three"));
+ &movups ($inout3,&QWP(0x30,$inp));
+ &je (&label("ecb_enc_four"));
+ &movups ($inout4,&QWP(0x40,$inp));
+ &xorps ($inout5,$inout5);
+ &call ("_aesni_encrypt6");
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &movups (&QWP(0x30,$out),$inout3);
+ &movups (&QWP(0x40,$out),$inout4);
+ jmp (&label("ecb_ret"));
+
+&set_label("ecb_enc_one",16);
+ if ($inline)
+ { &aesni_inline_generate1("enc"); }
+ else
+ { &call ("_aesni_encrypt1"); }
+ &movups (&QWP(0,$out),$inout0);
+ &jmp (&label("ecb_ret"));
+
+&set_label("ecb_enc_two",16);
+ &xorps ($inout2,$inout2);
+ &call ("_aesni_encrypt3");
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &jmp (&label("ecb_ret"));
+
+&set_label("ecb_enc_three",16);
+ &call ("_aesni_encrypt3");
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &jmp (&label("ecb_ret"));
+
+&set_label("ecb_enc_four",16);
+ &call ("_aesni_encrypt4");
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &movups (&QWP(0x30,$out),$inout3);
+ &jmp (&label("ecb_ret"));
+######################################################################
+&set_label("ecb_decrypt",16);
+ &mov ($key_,$key); # backup $key
+ &mov ($rounds_,$rounds); # backup $rounds
+ &cmp ($len,0x60);
+ &jb (&label("ecb_dec_tail"));
+
+ &movdqu ($inout0,&QWP(0,$inp));
+ &movdqu ($inout1,&QWP(0x10,$inp));
+ &movdqu ($inout2,&QWP(0x20,$inp));
+ &movdqu ($inout3,&QWP(0x30,$inp));
+ &movdqu ($inout4,&QWP(0x40,$inp));
+ &movdqu ($inout5,&QWP(0x50,$inp));
+ &lea ($inp,&DWP(0x60,$inp));
+ &sub ($len,0x60);
+ &jmp (&label("ecb_dec_loop6_enter"));
+
+&set_label("ecb_dec_loop6",16);
+ &movups (&QWP(0,$out),$inout0);
+ &movdqu ($inout0,&QWP(0,$inp));
+ &movups (&QWP(0x10,$out),$inout1);
+ &movdqu ($inout1,&QWP(0x10,$inp));
+ &movups (&QWP(0x20,$out),$inout2);
+ &movdqu ($inout2,&QWP(0x20,$inp));
+ &movups (&QWP(0x30,$out),$inout3);
+ &movdqu ($inout3,&QWP(0x30,$inp));
+ &movups (&QWP(0x40,$out),$inout4);
+ &movdqu ($inout4,&QWP(0x40,$inp));
+ &movups (&QWP(0x50,$out),$inout5);
+ &lea ($out,&DWP(0x60,$out));
+ &movdqu ($inout5,&QWP(0x50,$inp));
+ &lea ($inp,&DWP(0x60,$inp));
+&set_label("ecb_dec_loop6_enter");
+
+ &call ("_aesni_decrypt6");
+
+ &mov ($key,$key_); # restore $key
+ &mov ($rounds,$rounds_); # restore $rounds
+ &sub ($len,0x60);
+ &jnc (&label("ecb_dec_loop6"));
+
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &movups (&QWP(0x30,$out),$inout3);
+ &movups (&QWP(0x40,$out),$inout4);
+ &movups (&QWP(0x50,$out),$inout5);
+ &lea ($out,&DWP(0x60,$out));
+ &add ($len,0x60);
+ &jz (&label("ecb_ret"));
+
+&set_label("ecb_dec_tail");
+ &movups ($inout0,&QWP(0,$inp));
+ &cmp ($len,0x20);
+ &jb (&label("ecb_dec_one"));
+ &movups ($inout1,&QWP(0x10,$inp));
+ &je (&label("ecb_dec_two"));
+ &movups ($inout2,&QWP(0x20,$inp));
+ &cmp ($len,0x40);
+ &jb (&label("ecb_dec_three"));
+ &movups ($inout3,&QWP(0x30,$inp));
+ &je (&label("ecb_dec_four"));
+ &movups ($inout4,&QWP(0x40,$inp));
+ &xorps ($inout5,$inout5);
+ &call ("_aesni_decrypt6");
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &movups (&QWP(0x30,$out),$inout3);
+ &movups (&QWP(0x40,$out),$inout4);
+ &jmp (&label("ecb_ret"));
+
+&set_label("ecb_dec_one",16);
+ if ($inline)
+ { &aesni_inline_generate1("dec"); }
+ else
+ { &call ("_aesni_decrypt1"); }
+ &movups (&QWP(0,$out),$inout0);
+ &jmp (&label("ecb_ret"));
+
+&set_label("ecb_dec_two",16);
+ &xorps ($inout2,$inout2);
+ &call ("_aesni_decrypt3");
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &jmp (&label("ecb_ret"));
+
+&set_label("ecb_dec_three",16);
+ &call ("_aesni_decrypt3");
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &jmp (&label("ecb_ret"));
+
+&set_label("ecb_dec_four",16);
+ &call ("_aesni_decrypt4");
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &movups (&QWP(0x30,$out),$inout3);
+
+&set_label("ecb_ret");
+&function_end("aesni_ecb_encrypt");
+
+######################################################################
+# void aesni_ccm64_[en|de]crypt_blocks (const void *in, void *out,
+# size_t blocks, const AES_KEY *key,
+# const char *ivec,char *cmac);
+#
+# Handles only complete blocks, operates on 64-bit counter and
+# does not update *ivec! Nor does it finalize CMAC value
+# (see engine/eng_aesni.c for details)
+#
+{ my $cmac=$inout1;
+&function_begin("aesni_ccm64_encrypt_blocks");
+ &mov ($inp,&wparam(0));
+ &mov ($out,&wparam(1));
+ &mov ($len,&wparam(2));
+ &mov ($key,&wparam(3));
+ &mov ($rounds_,&wparam(4));
+ &mov ($rounds,&wparam(5));
+ &mov ($key_,"esp");
+ &sub ("esp",60);
+ &and ("esp",-16); # align stack
+ &mov (&DWP(48,"esp"),$key_);
+
+ &movdqu ($ivec,&QWP(0,$rounds_)); # load ivec
+ &movdqu ($cmac,&QWP(0,$rounds)); # load cmac
+ &mov ($rounds,&DWP(240,$key));
+
+ # compose byte-swap control mask for pshufb on stack
+ &mov (&DWP(0,"esp"),0x0c0d0e0f);
+ &mov (&DWP(4,"esp"),0x08090a0b);
+ &mov (&DWP(8,"esp"),0x04050607);
+ &mov (&DWP(12,"esp"),0x00010203);
+
+ # compose counter increment vector on stack
+ &mov ($rounds_,1);
+ &xor ($key_,$key_);
+ &mov (&DWP(16,"esp"),$rounds_);
+ &mov (&DWP(20,"esp"),$key_);
+ &mov (&DWP(24,"esp"),$key_);
+ &mov (&DWP(28,"esp"),$key_);
+
+ &shr ($rounds,1);
+ &lea ($key_,&DWP(0,$key));
+ &movdqa ($inout3,&QWP(0,"esp"));
+ &movdqa ($inout0,$ivec);
+ &mov ($rounds_,$rounds);
+ &pshufb ($ivec,$inout3);
+
+&set_label("ccm64_enc_outer");
+ &$movekey ($rndkey0,&QWP(0,$key_));
+ &mov ($rounds,$rounds_);
+ &movups ($in0,&QWP(0,$inp));
+
+ &xorps ($inout0,$rndkey0);
+ &$movekey ($rndkey1,&QWP(16,$key_));
+ &xorps ($rndkey0,$in0);
+ &lea ($key,&DWP(32,$key_));
+ &xorps ($cmac,$rndkey0); # cmac^=inp
+ &$movekey ($rndkey0,&QWP(0,$key));
+
+&set_label("ccm64_enc2_loop");
+ &aesenc ($inout0,$rndkey1);
+ &dec ($rounds);
+ &aesenc ($cmac,$rndkey1);
+ &$movekey ($rndkey1,&QWP(16,$key));
+ &aesenc ($inout0,$rndkey0);
+ &lea ($key,&DWP(32,$key));
+ &aesenc ($cmac,$rndkey0);
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &jnz (&label("ccm64_enc2_loop"));
+ &aesenc ($inout0,$rndkey1);
+ &aesenc ($cmac,$rndkey1);
+ &paddq ($ivec,&QWP(16,"esp"));
+ &aesenclast ($inout0,$rndkey0);
+ &aesenclast ($cmac,$rndkey0);
+
+ &dec ($len);
+ &lea ($inp,&DWP(16,$inp));
+ &xorps ($in0,$inout0); # inp^=E(ivec)
+ &movdqa ($inout0,$ivec);
+ &movups (&QWP(0,$out),$in0); # save output
+ &lea ($out,&DWP(16,$out));
+ &pshufb ($inout0,$inout3);
+ &jnz (&label("ccm64_enc_outer"));
+
+ &mov ("esp",&DWP(48,"esp"));
+ &mov ($out,&wparam(5));
+ &movups (&QWP(0,$out),$cmac);
+&function_end("aesni_ccm64_encrypt_blocks");
+
+&function_begin("aesni_ccm64_decrypt_blocks");
+ &mov ($inp,&wparam(0));
+ &mov ($out,&wparam(1));
+ &mov ($len,&wparam(2));
+ &mov ($key,&wparam(3));
+ &mov ($rounds_,&wparam(4));
+ &mov ($rounds,&wparam(5));
+ &mov ($key_,"esp");
+ &sub ("esp",60);
+ &and ("esp",-16); # align stack
+ &mov (&DWP(48,"esp"),$key_);
+
+ &movdqu ($ivec,&QWP(0,$rounds_)); # load ivec
+ &movdqu ($cmac,&QWP(0,$rounds)); # load cmac
+ &mov ($rounds,&DWP(240,$key));
+
+ # compose byte-swap control mask for pshufb on stack
+ &mov (&DWP(0,"esp"),0x0c0d0e0f);
+ &mov (&DWP(4,"esp"),0x08090a0b);
+ &mov (&DWP(8,"esp"),0x04050607);
+ &mov (&DWP(12,"esp"),0x00010203);
+
+ # compose counter increment vector on stack
+ &mov ($rounds_,1);
+ &xor ($key_,$key_);
+ &mov (&DWP(16,"esp"),$rounds_);
+ &mov (&DWP(20,"esp"),$key_);
+ &mov (&DWP(24,"esp"),$key_);
+ &mov (&DWP(28,"esp"),$key_);
+
+ &movdqa ($inout3,&QWP(0,"esp")); # bswap mask
+ &movdqa ($inout0,$ivec);
+
+ &mov ($key_,$key);
+ &mov ($rounds_,$rounds);
+
+ &pshufb ($ivec,$inout3);
+ if ($inline)
+ { &aesni_inline_generate1("enc"); }
+ else
+ { &call ("_aesni_encrypt1"); }
+ &movups ($in0,&QWP(0,$inp)); # load inp
+ &paddq ($ivec,&QWP(16,"esp"));
+ &lea ($inp,&QWP(16,$inp));
+ &jmp (&label("ccm64_dec_outer"));
+
+&set_label("ccm64_dec_outer",16);
+ &xorps ($in0,$inout0); # inp ^= E(ivec)
+ &movdqa ($inout0,$ivec);
+ &mov ($rounds,$rounds_);
+ &movups (&QWP(0,$out),$in0); # save output
+ &lea ($out,&DWP(16,$out));
+ &pshufb ($inout0,$inout3);
+
+ &sub ($len,1);
+ &jz (&label("ccm64_dec_break"));
+
+ &$movekey ($rndkey0,&QWP(0,$key_));
+ &shr ($rounds,1);
+ &$movekey ($rndkey1,&QWP(16,$key_));
+ &xorps ($in0,$rndkey0);
+ &lea ($key,&DWP(32,$key_));
+ &xorps ($inout0,$rndkey0);
+ &xorps ($cmac,$in0); # cmac^=out
+ &$movekey ($rndkey0,&QWP(0,$key));
+
+&set_label("ccm64_dec2_loop");
+ &aesenc ($inout0,$rndkey1);
+ &dec ($rounds);
+ &aesenc ($cmac,$rndkey1);
+ &$movekey ($rndkey1,&QWP(16,$key));
+ &aesenc ($inout0,$rndkey0);
+ &lea ($key,&DWP(32,$key));
+ &aesenc ($cmac,$rndkey0);
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &jnz (&label("ccm64_dec2_loop"));
+ &movups ($in0,&QWP(0,$inp)); # load inp
+ &paddq ($ivec,&QWP(16,"esp"));
+ &aesenc ($inout0,$rndkey1);
+ &aesenc ($cmac,$rndkey1);
+ &lea ($inp,&QWP(16,$inp));
+ &aesenclast ($inout0,$rndkey0);
+ &aesenclast ($cmac,$rndkey0);
+ &jmp (&label("ccm64_dec_outer"));
+
+&set_label("ccm64_dec_break",16);
+ &mov ($key,$key_);
+ if ($inline)
+ { &aesni_inline_generate1("enc",$cmac,$in0); }
+ else
+ { &call ("_aesni_encrypt1",$cmac); }
+
+ &mov ("esp",&DWP(48,"esp"));
+ &mov ($out,&wparam(5));
+ &movups (&QWP(0,$out),$cmac);
+&function_end("aesni_ccm64_decrypt_blocks");
+}
+
+######################################################################
+# void aesni_ctr32_encrypt_blocks (const void *in, void *out,
+# size_t blocks, const AES_KEY *key,
+# const char *ivec);
+#
+# Handles only complete blocks, operates on 32-bit counter and
+# does not update *ivec! (see engine/eng_aesni.c for details)
+#
+# stack layout:
+# 0 pshufb mask
+# 16 vector addend: 0,6,6,6
+# 32 counter-less ivec
+# 48 1st triplet of counter vector
+# 64 2nd triplet of counter vector
+# 80 saved %esp
+
+&function_begin("aesni_ctr32_encrypt_blocks");
+ &mov ($inp,&wparam(0));
+ &mov ($out,&wparam(1));
+ &mov ($len,&wparam(2));
+ &mov ($key,&wparam(3));
+ &mov ($rounds_,&wparam(4));
+ &mov ($key_,"esp");
+ &sub ("esp",88);
+ &and ("esp",-16); # align stack
+ &mov (&DWP(80,"esp"),$key_);
+
+ &cmp ($len,1);
+ &je (&label("ctr32_one_shortcut"));
+
+ &movdqu ($inout5,&QWP(0,$rounds_)); # load ivec
+
+ # compose byte-swap control mask for pshufb on stack
+ &mov (&DWP(0,"esp"),0x0c0d0e0f);
+ &mov (&DWP(4,"esp"),0x08090a0b);
+ &mov (&DWP(8,"esp"),0x04050607);
+ &mov (&DWP(12,"esp"),0x00010203);
+
+ # compose counter increment vector on stack
+ &mov ($rounds,6);
+ &xor ($key_,$key_);
+ &mov (&DWP(16,"esp"),$rounds);
+ &mov (&DWP(20,"esp"),$rounds);
+ &mov (&DWP(24,"esp"),$rounds);
+ &mov (&DWP(28,"esp"),$key_);
+
+ &pextrd ($rounds_,$inout5,3); # pull 32-bit counter
+ &pinsrd ($inout5,$key_,3); # wipe 32-bit counter
+
+ &mov ($rounds,&DWP(240,$key)); # key->rounds
+
+ # compose 2 vectors of 3x32-bit counters
+ &bswap ($rounds_);
+ &pxor ($rndkey1,$rndkey1);
+ &pxor ($rndkey0,$rndkey0);
+ &movdqa ($inout0,&QWP(0,"esp")); # load byte-swap mask
+ &pinsrd ($rndkey1,$rounds_,0);
+ &lea ($key_,&DWP(3,$rounds_));
+ &pinsrd ($rndkey0,$key_,0);
+ &inc ($rounds_);
+ &pinsrd ($rndkey1,$rounds_,1);
+ &inc ($key_);
+ &pinsrd ($rndkey0,$key_,1);
+ &inc ($rounds_);
+ &pinsrd ($rndkey1,$rounds_,2);
+ &inc ($key_);
+ &pinsrd ($rndkey0,$key_,2);
+ &movdqa (&QWP(48,"esp"),$rndkey1); # save 1st triplet
+ &pshufb ($rndkey1,$inout0); # byte swap
+ &movdqa (&QWP(64,"esp"),$rndkey0); # save 2nd triplet
+ &pshufb ($rndkey0,$inout0); # byte swap
+
+ &pshufd ($inout0,$rndkey1,3<<6); # place counter to upper dword
+ &pshufd ($inout1,$rndkey1,2<<6);
+ &cmp ($len,6);
+ &jb (&label("ctr32_tail"));
+ &movdqa (&QWP(32,"esp"),$inout5); # save counter-less ivec
+ &shr ($rounds,1);
+ &mov ($key_,$key); # backup $key
+ &mov ($rounds_,$rounds); # backup $rounds
+ &sub ($len,6);
+ &jmp (&label("ctr32_loop6"));
+
+&set_label("ctr32_loop6",16);
+ &pshufd ($inout2,$rndkey1,1<<6);
+ &movdqa ($rndkey1,&QWP(32,"esp")); # pull counter-less ivec
+ &pshufd ($inout3,$rndkey0,3<<6);
+ &por ($inout0,$rndkey1); # merge counter-less ivec
+ &pshufd ($inout4,$rndkey0,2<<6);
+ &por ($inout1,$rndkey1);
+ &pshufd ($inout5,$rndkey0,1<<6);
+ &por ($inout2,$rndkey1);
+ &por ($inout3,$rndkey1);
+ &por ($inout4,$rndkey1);
+ &por ($inout5,$rndkey1);
+
+ # inlining _aesni_encrypt6's prologue gives ~4% improvement...
+ &$movekey ($rndkey0,&QWP(0,$key_));
+ &$movekey ($rndkey1,&QWP(16,$key_));
+ &lea ($key,&DWP(32,$key_));
+ &dec ($rounds);
+ &pxor ($inout0,$rndkey0);
+ &pxor ($inout1,$rndkey0);
+ &aesenc ($inout0,$rndkey1);
+ &pxor ($inout2,$rndkey0);
+ &aesenc ($inout1,$rndkey1);
+ &pxor ($inout3,$rndkey0);
+ &aesenc ($inout2,$rndkey1);
+ &pxor ($inout4,$rndkey0);
+ &aesenc ($inout3,$rndkey1);
+ &pxor ($inout5,$rndkey0);
+ &aesenc ($inout4,$rndkey1);
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &aesenc ($inout5,$rndkey1);
+
+ &call (&label("_aesni_encrypt6_enter"));
+
+ &movups ($rndkey1,&QWP(0,$inp));
+ &movups ($rndkey0,&QWP(0x10,$inp));
+ &xorps ($inout0,$rndkey1);
+ &movups ($rndkey1,&QWP(0x20,$inp));
+ &xorps ($inout1,$rndkey0);
+ &movups (&QWP(0,$out),$inout0);
+ &movdqa ($rndkey0,&QWP(16,"esp")); # load increment
+ &xorps ($inout2,$rndkey1);
+ &movdqa ($rndkey1,&QWP(48,"esp")); # load 1st triplet
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+
+ &paddd ($rndkey1,$rndkey0); # 1st triplet increment
+ &paddd ($rndkey0,&QWP(64,"esp")); # 2nd triplet increment
+ &movdqa ($inout0,&QWP(0,"esp")); # load byte swap mask
+
+ &movups ($inout1,&QWP(0x30,$inp));
+ &movups ($inout2,&QWP(0x40,$inp));
+ &xorps ($inout3,$inout1);
+ &movups ($inout1,&QWP(0x50,$inp));
+ &lea ($inp,&DWP(0x60,$inp));
+ &movdqa (&QWP(48,"esp"),$rndkey1); # save 1st triplet
+ &pshufb ($rndkey1,$inout0); # byte swap
+ &xorps ($inout4,$inout2);
+ &movups (&QWP(0x30,$out),$inout3);
+ &xorps ($inout5,$inout1);
+ &movdqa (&QWP(64,"esp"),$rndkey0); # save 2nd triplet
+ &pshufb ($rndkey0,$inout0); # byte swap
+ &movups (&QWP(0x40,$out),$inout4);
+ &pshufd ($inout0,$rndkey1,3<<6);
+ &movups (&QWP(0x50,$out),$inout5);
+ &lea ($out,&DWP(0x60,$out));
+
+ &mov ($rounds,$rounds_);
+ &pshufd ($inout1,$rndkey1,2<<6);
+ &sub ($len,6);
+ &jnc (&label("ctr32_loop6"));
+
+ &add ($len,6);
+ &jz (&label("ctr32_ret"));
+ &mov ($key,$key_);
+ &lea ($rounds,&DWP(1,"",$rounds,2)); # restore $rounds
+ &movdqa ($inout5,&QWP(32,"esp")); # pull count-less ivec
+
+&set_label("ctr32_tail");
+ &por ($inout0,$inout5);
+ &cmp ($len,2);
+ &jb (&label("ctr32_one"));
+
+ &pshufd ($inout2,$rndkey1,1<<6);
+ &por ($inout1,$inout5);
+ &je (&label("ctr32_two"));
+
+ &pshufd ($inout3,$rndkey0,3<<6);
+ &por ($inout2,$inout5);
+ &cmp ($len,4);
+ &jb (&label("ctr32_three"));
+
+ &pshufd ($inout4,$rndkey0,2<<6);
+ &por ($inout3,$inout5);
+ &je (&label("ctr32_four"));
+
+ &por ($inout4,$inout5);
+ &call ("_aesni_encrypt6");
+ &movups ($rndkey1,&QWP(0,$inp));
+ &movups ($rndkey0,&QWP(0x10,$inp));
+ &xorps ($inout0,$rndkey1);
+ &movups ($rndkey1,&QWP(0x20,$inp));
+ &xorps ($inout1,$rndkey0);
+ &movups ($rndkey0,&QWP(0x30,$inp));
+ &xorps ($inout2,$rndkey1);
+ &movups ($rndkey1,&QWP(0x40,$inp));
+ &xorps ($inout3,$rndkey0);
+ &movups (&QWP(0,$out),$inout0);
+ &xorps ($inout4,$rndkey1);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &movups (&QWP(0x30,$out),$inout3);
+ &movups (&QWP(0x40,$out),$inout4);
+ &jmp (&label("ctr32_ret"));
+
+&set_label("ctr32_one_shortcut",16);
+ &movups ($inout0,&QWP(0,$rounds_)); # load ivec
+ &mov ($rounds,&DWP(240,$key));
+
+&set_label("ctr32_one");
+ if ($inline)
+ { &aesni_inline_generate1("enc"); }
+ else
+ { &call ("_aesni_encrypt1"); }
+ &movups ($in0,&QWP(0,$inp));
+ &xorps ($in0,$inout0);
+ &movups (&QWP(0,$out),$in0);
+ &jmp (&label("ctr32_ret"));
+
+&set_label("ctr32_two",16);
+ &call ("_aesni_encrypt3");
+ &movups ($inout3,&QWP(0,$inp));
+ &movups ($inout4,&QWP(0x10,$inp));
+ &xorps ($inout0,$inout3);
+ &xorps ($inout1,$inout4);
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &jmp (&label("ctr32_ret"));
+
+&set_label("ctr32_three",16);
+ &call ("_aesni_encrypt3");
+ &movups ($inout3,&QWP(0,$inp));
+ &movups ($inout4,&QWP(0x10,$inp));
+ &xorps ($inout0,$inout3);
+ &movups ($inout5,&QWP(0x20,$inp));
+ &xorps ($inout1,$inout4);
+ &movups (&QWP(0,$out),$inout0);
+ &xorps ($inout2,$inout5);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &jmp (&label("ctr32_ret"));
+
+&set_label("ctr32_four",16);
+ &call ("_aesni_encrypt4");
+ &movups ($inout4,&QWP(0,$inp));
+ &movups ($inout5,&QWP(0x10,$inp));
+ &movups ($rndkey1,&QWP(0x20,$inp));
+ &xorps ($inout0,$inout4);
+ &movups ($rndkey0,&QWP(0x30,$inp));
+ &xorps ($inout1,$inout5);
+ &movups (&QWP(0,$out),$inout0);
+ &xorps ($inout2,$rndkey1);
+ &movups (&QWP(0x10,$out),$inout1);
+ &xorps ($inout3,$rndkey0);
+ &movups (&QWP(0x20,$out),$inout2);
+ &movups (&QWP(0x30,$out),$inout3);
+
+&set_label("ctr32_ret");
+ &mov ("esp",&DWP(80,"esp"));
+&function_end("aesni_ctr32_encrypt_blocks");
+
+######################################################################
+# void aesni_xts_[en|de]crypt(const char *inp,char *out,size_t len,
+# const AES_KEY *key1, const AES_KEY *key2
+# const unsigned char iv[16]);
+#
+{ my ($tweak,$twtmp,$twres,$twmask)=($rndkey1,$rndkey0,$inout0,$inout1);
+
+&function_begin("aesni_xts_encrypt");
+ &mov ($key,&wparam(4)); # key2
+ &mov ($inp,&wparam(5)); # clear-text tweak
+
+ &mov ($rounds,&DWP(240,$key)); # key2->rounds
+ &movups ($inout0,&QWP(0,$inp));
+ if ($inline)
+ { &aesni_inline_generate1("enc"); }
+ else
+ { &call ("_aesni_encrypt1"); }
+
+ &mov ($inp,&wparam(0));
+ &mov ($out,&wparam(1));
+ &mov ($len,&wparam(2));
+ &mov ($key,&wparam(3)); # key1
+
+ &mov ($key_,"esp");
+ &sub ("esp",16*7+8);
+ &mov ($rounds,&DWP(240,$key)); # key1->rounds
+ &and ("esp",-16); # align stack
+
+ &mov (&DWP(16*6+0,"esp"),0x87); # compose the magic constant
+ &mov (&DWP(16*6+4,"esp"),0);
+ &mov (&DWP(16*6+8,"esp"),1);
+ &mov (&DWP(16*6+12,"esp"),0);
+ &mov (&DWP(16*7+0,"esp"),$len); # save original $len
+ &mov (&DWP(16*7+4,"esp"),$key_); # save original %esp
+
+ &movdqa ($tweak,$inout0);
+ &pxor ($twtmp,$twtmp);
+ &movdqa ($twmask,&QWP(6*16,"esp")); # 0x0...010...87
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+
+ &and ($len,-16);
+ &mov ($key_,$key); # backup $key
+ &mov ($rounds_,$rounds); # backup $rounds
+ &sub ($len,16*6);
+ &jc (&label("xts_enc_short"));
+
+ &shr ($rounds,1);
+ &mov ($rounds_,$rounds);
+ &jmp (&label("xts_enc_loop6"));
+
+&set_label("xts_enc_loop6",16);
+ for ($i=0;$i<4;$i++) {
+ &pshufd ($twres,$twtmp,0x13);
+ &pxor ($twtmp,$twtmp);
+ &movdqa (&QWP(16*$i,"esp"),$tweak);
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd ($twtmp,$tweak); # broadcast upper bits
+ &pxor ($tweak,$twres);
+ }
+ &pshufd ($inout5,$twtmp,0x13);
+ &movdqa (&QWP(16*$i++,"esp"),$tweak);
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &$movekey ($rndkey0,&QWP(0,$key_));
+ &pand ($inout5,$twmask); # isolate carry and residue
+ &movups ($inout0,&QWP(0,$inp)); # load input
+ &pxor ($inout5,$tweak);
+
+ # inline _aesni_encrypt6 prologue and flip xor with tweak and key[0]
+ &movdqu ($inout1,&QWP(16*1,$inp));
+ &xorps ($inout0,$rndkey0); # input^=rndkey[0]
+ &movdqu ($inout2,&QWP(16*2,$inp));
+ &pxor ($inout1,$rndkey0);
+ &movdqu ($inout3,&QWP(16*3,$inp));
+ &pxor ($inout2,$rndkey0);
+ &movdqu ($inout4,&QWP(16*4,$inp));
+ &pxor ($inout3,$rndkey0);
+ &movdqu ($rndkey1,&QWP(16*5,$inp));
+ &pxor ($inout4,$rndkey0);
+ &lea ($inp,&DWP(16*6,$inp));
+ &pxor ($inout0,&QWP(16*0,"esp")); # input^=tweak
+ &movdqa (&QWP(16*$i,"esp"),$inout5); # save last tweak
+ &pxor ($inout5,$rndkey1);
+
+ &$movekey ($rndkey1,&QWP(16,$key_));
+ &lea ($key,&DWP(32,$key_));
+ &pxor ($inout1,&QWP(16*1,"esp"));
+ &aesenc ($inout0,$rndkey1);
+ &pxor ($inout2,&QWP(16*2,"esp"));
+ &aesenc ($inout1,$rndkey1);
+ &pxor ($inout3,&QWP(16*3,"esp"));
+ &dec ($rounds);
+ &aesenc ($inout2,$rndkey1);
+ &pxor ($inout4,&QWP(16*4,"esp"));
+ &aesenc ($inout3,$rndkey1);
+ &pxor ($inout5,$rndkey0);
+ &aesenc ($inout4,$rndkey1);
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &aesenc ($inout5,$rndkey1);
+ &call (&label("_aesni_encrypt6_enter"));
+
+ &movdqa ($tweak,&QWP(16*5,"esp")); # last tweak
+ &pxor ($twtmp,$twtmp);
+ &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak
+ &pcmpgtd ($twtmp,$tweak); # broadcast upper bits
+ &xorps ($inout1,&QWP(16*1,"esp"));
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &xorps ($inout2,&QWP(16*2,"esp"));
+ &movups (&QWP(16*1,$out),$inout1);
+ &xorps ($inout3,&QWP(16*3,"esp"));
+ &movups (&QWP(16*2,$out),$inout2);
+ &xorps ($inout4,&QWP(16*4,"esp"));
+ &movups (&QWP(16*3,$out),$inout3);
+ &xorps ($inout5,$tweak);
+ &movups (&QWP(16*4,$out),$inout4);
+ &pshufd ($twres,$twtmp,0x13);
+ &movups (&QWP(16*5,$out),$inout5);
+ &lea ($out,&DWP(16*6,$out));
+ &movdqa ($twmask,&QWP(16*6,"esp")); # 0x0...010...87
+
+ &pxor ($twtmp,$twtmp);
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &mov ($rounds,$rounds_); # restore $rounds
+ &pxor ($tweak,$twres);
+
+ &sub ($len,16*6);
+ &jnc (&label("xts_enc_loop6"));
+
+ &lea ($rounds,&DWP(1,"",$rounds,2)); # restore $rounds
+ &mov ($key,$key_); # restore $key
+ &mov ($rounds_,$rounds);
+
+&set_label("xts_enc_short");
+ &add ($len,16*6);
+ &jz (&label("xts_enc_done6x"));
+
+ &movdqa ($inout3,$tweak); # put aside previous tweak
+ &cmp ($len,0x20);
+ &jb (&label("xts_enc_one"));
+
+ &pshufd ($twres,$twtmp,0x13);
+ &pxor ($twtmp,$twtmp);
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &pxor ($tweak,$twres);
+ &je (&label("xts_enc_two"));
+
+ &pshufd ($twres,$twtmp,0x13);
+ &pxor ($twtmp,$twtmp);
+ &movdqa ($inout4,$tweak); # put aside previous tweak
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &pxor ($tweak,$twres);
+ &cmp ($len,0x40);
+ &jb (&label("xts_enc_three"));
+
+ &pshufd ($twres,$twtmp,0x13);
+ &pxor ($twtmp,$twtmp);
+ &movdqa ($inout5,$tweak); # put aside previous tweak
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &pxor ($tweak,$twres);
+ &movdqa (&QWP(16*0,"esp"),$inout3);
+ &movdqa (&QWP(16*1,"esp"),$inout4);
+ &je (&label("xts_enc_four"));
+
+ &movdqa (&QWP(16*2,"esp"),$inout5);
+ &pshufd ($inout5,$twtmp,0x13);
+ &movdqa (&QWP(16*3,"esp"),$tweak);
+ &paddq ($tweak,$tweak); # &psllq($inout0,1);
+ &pand ($inout5,$twmask); # isolate carry and residue
+ &pxor ($inout5,$tweak);
+
+ &movdqu ($inout0,&QWP(16*0,$inp)); # load input
+ &movdqu ($inout1,&QWP(16*1,$inp));
+ &movdqu ($inout2,&QWP(16*2,$inp));
+ &pxor ($inout0,&QWP(16*0,"esp")); # input^=tweak
+ &movdqu ($inout3,&QWP(16*3,$inp));
+ &pxor ($inout1,&QWP(16*1,"esp"));
+ &movdqu ($inout4,&QWP(16*4,$inp));
+ &pxor ($inout2,&QWP(16*2,"esp"));
+ &lea ($inp,&DWP(16*5,$inp));
+ &pxor ($inout3,&QWP(16*3,"esp"));
+ &movdqa (&QWP(16*4,"esp"),$inout5); # save last tweak
+ &pxor ($inout4,$inout5);
+
+ &call ("_aesni_encrypt6");
+
+ &movaps ($tweak,&QWP(16*4,"esp")); # last tweak
+ &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak
+ &xorps ($inout1,&QWP(16*1,"esp"));
+ &xorps ($inout2,&QWP(16*2,"esp"));
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &xorps ($inout3,&QWP(16*3,"esp"));
+ &movups (&QWP(16*1,$out),$inout1);
+ &xorps ($inout4,$tweak);
+ &movups (&QWP(16*2,$out),$inout2);
+ &movups (&QWP(16*3,$out),$inout3);
+ &movups (&QWP(16*4,$out),$inout4);
+ &lea ($out,&DWP(16*5,$out));
+ &jmp (&label("xts_enc_done"));
+
+&set_label("xts_enc_one",16);
+ &movups ($inout0,&QWP(16*0,$inp)); # load input
+ &lea ($inp,&DWP(16*1,$inp));
+ &xorps ($inout0,$inout3); # input^=tweak
+ if ($inline)
+ { &aesni_inline_generate1("enc"); }
+ else
+ { &call ("_aesni_encrypt1"); }
+ &xorps ($inout0,$inout3); # output^=tweak
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &lea ($out,&DWP(16*1,$out));
+
+ &movdqa ($tweak,$inout3); # last tweak
+ &jmp (&label("xts_enc_done"));
+
+&set_label("xts_enc_two",16);
+ &movaps ($inout4,$tweak); # put aside last tweak
+
+ &movups ($inout0,&QWP(16*0,$inp)); # load input
+ &movups ($inout1,&QWP(16*1,$inp));
+ &lea ($inp,&DWP(16*2,$inp));
+ &xorps ($inout0,$inout3); # input^=tweak
+ &xorps ($inout1,$inout4);
+ &xorps ($inout2,$inout2);
+
+ &call ("_aesni_encrypt3");
+
+ &xorps ($inout0,$inout3); # output^=tweak
+ &xorps ($inout1,$inout4);
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &movups (&QWP(16*1,$out),$inout1);
+ &lea ($out,&DWP(16*2,$out));
+
+ &movdqa ($tweak,$inout4); # last tweak
+ &jmp (&label("xts_enc_done"));
+
+&set_label("xts_enc_three",16);
+ &movaps ($inout5,$tweak); # put aside last tweak
+ &movups ($inout0,&QWP(16*0,$inp)); # load input
+ &movups ($inout1,&QWP(16*1,$inp));
+ &movups ($inout2,&QWP(16*2,$inp));
+ &lea ($inp,&DWP(16*3,$inp));
+ &xorps ($inout0,$inout3); # input^=tweak
+ &xorps ($inout1,$inout4);
+ &xorps ($inout2,$inout5);
+
+ &call ("_aesni_encrypt3");
+
+ &xorps ($inout0,$inout3); # output^=tweak
+ &xorps ($inout1,$inout4);
+ &xorps ($inout2,$inout5);
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &movups (&QWP(16*1,$out),$inout1);
+ &movups (&QWP(16*2,$out),$inout2);
+ &lea ($out,&DWP(16*3,$out));
+
+ &movdqa ($tweak,$inout5); # last tweak
+ &jmp (&label("xts_enc_done"));
+
+&set_label("xts_enc_four",16);
+ &movaps ($inout4,$tweak); # put aside last tweak
+
+ &movups ($inout0,&QWP(16*0,$inp)); # load input
+ &movups ($inout1,&QWP(16*1,$inp));
+ &movups ($inout2,&QWP(16*2,$inp));
+ &xorps ($inout0,&QWP(16*0,"esp")); # input^=tweak
+ &movups ($inout3,&QWP(16*3,$inp));
+ &lea ($inp,&DWP(16*4,$inp));
+ &xorps ($inout1,&QWP(16*1,"esp"));
+ &xorps ($inout2,$inout5);
+ &xorps ($inout3,$inout4);
+
+ &call ("_aesni_encrypt4");
+
+ &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak
+ &xorps ($inout1,&QWP(16*1,"esp"));
+ &xorps ($inout2,$inout5);
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &xorps ($inout3,$inout4);
+ &movups (&QWP(16*1,$out),$inout1);
+ &movups (&QWP(16*2,$out),$inout2);
+ &movups (&QWP(16*3,$out),$inout3);
+ &lea ($out,&DWP(16*4,$out));
+
+ &movdqa ($tweak,$inout4); # last tweak
+ &jmp (&label("xts_enc_done"));
+
+&set_label("xts_enc_done6x",16); # $tweak is pre-calculated
+ &mov ($len,&DWP(16*7+0,"esp")); # restore original $len
+ &and ($len,15);
+ &jz (&label("xts_enc_ret"));
+ &movdqa ($inout3,$tweak);
+ &mov (&DWP(16*7+0,"esp"),$len); # save $len%16
+ &jmp (&label("xts_enc_steal"));
+
+&set_label("xts_enc_done",16);
+ &mov ($len,&DWP(16*7+0,"esp")); # restore original $len
+ &pxor ($twtmp,$twtmp);
+ &and ($len,15);
+ &jz (&label("xts_enc_ret"));
+
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &mov (&DWP(16*7+0,"esp"),$len); # save $len%16
+ &pshufd ($inout3,$twtmp,0x13);
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($inout3,&QWP(16*6,"esp")); # isolate carry and residue
+ &pxor ($inout3,$tweak);
+
+&set_label("xts_enc_steal");
+ &movz ($rounds,&BP(0,$inp));
+ &movz ($key,&BP(-16,$out));
+ &lea ($inp,&DWP(1,$inp));
+ &mov (&BP(-16,$out),&LB($rounds));
+ &mov (&BP(0,$out),&LB($key));
+ &lea ($out,&DWP(1,$out));
+ &sub ($len,1);
+ &jnz (&label("xts_enc_steal"));
+
+ &sub ($out,&DWP(16*7+0,"esp")); # rewind $out
+ &mov ($key,$key_); # restore $key
+ &mov ($rounds,$rounds_); # restore $rounds
+
+ &movups ($inout0,&QWP(-16,$out)); # load input
+ &xorps ($inout0,$inout3); # input^=tweak
+ if ($inline)
+ { &aesni_inline_generate1("enc"); }
+ else
+ { &call ("_aesni_encrypt1"); }
+ &xorps ($inout0,$inout3); # output^=tweak
+ &movups (&QWP(-16,$out),$inout0); # write output
+
+&set_label("xts_enc_ret");
+ &mov ("esp",&DWP(16*7+4,"esp")); # restore %esp
+&function_end("aesni_xts_encrypt");
+
+&function_begin("aesni_xts_decrypt");
+ &mov ($key,&wparam(4)); # key2
+ &mov ($inp,&wparam(5)); # clear-text tweak
+
+ &mov ($rounds,&DWP(240,$key)); # key2->rounds
+ &movups ($inout0,&QWP(0,$inp));
+ if ($inline)
+ { &aesni_inline_generate1("enc"); }
+ else
+ { &call ("_aesni_encrypt1"); }
+
+ &mov ($inp,&wparam(0));
+ &mov ($out,&wparam(1));
+ &mov ($len,&wparam(2));
+ &mov ($key,&wparam(3)); # key1
+
+ &mov ($key_,"esp");
+ &sub ("esp",16*7+8);
+ &and ("esp",-16); # align stack
+
+ &xor ($rounds_,$rounds_); # if(len%16) len-=16;
+ &test ($len,15);
+ &setnz (&LB($rounds_));
+ &shl ($rounds_,4);
+ &sub ($len,$rounds_);
+
+ &mov (&DWP(16*6+0,"esp"),0x87); # compose the magic constant
+ &mov (&DWP(16*6+4,"esp"),0);
+ &mov (&DWP(16*6+8,"esp"),1);
+ &mov (&DWP(16*6+12,"esp"),0);
+ &mov (&DWP(16*7+0,"esp"),$len); # save original $len
+ &mov (&DWP(16*7+4,"esp"),$key_); # save original %esp
+
+ &mov ($rounds,&DWP(240,$key)); # key1->rounds
+ &mov ($key_,$key); # backup $key
+ &mov ($rounds_,$rounds); # backup $rounds
+
+ &movdqa ($tweak,$inout0);
+ &pxor ($twtmp,$twtmp);
+ &movdqa ($twmask,&QWP(6*16,"esp")); # 0x0...010...87
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+
+ &and ($len,-16);
+ &sub ($len,16*6);
+ &jc (&label("xts_dec_short"));
+
+ &shr ($rounds,1);
+ &mov ($rounds_,$rounds);
+ &jmp (&label("xts_dec_loop6"));
+
+&set_label("xts_dec_loop6",16);
+ for ($i=0;$i<4;$i++) {
+ &pshufd ($twres,$twtmp,0x13);
+ &pxor ($twtmp,$twtmp);
+ &movdqa (&QWP(16*$i,"esp"),$tweak);
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd ($twtmp,$tweak); # broadcast upper bits
+ &pxor ($tweak,$twres);
+ }
+ &pshufd ($inout5,$twtmp,0x13);
+ &movdqa (&QWP(16*$i++,"esp"),$tweak);
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &$movekey ($rndkey0,&QWP(0,$key_));
+ &pand ($inout5,$twmask); # isolate carry and residue
+ &movups ($inout0,&QWP(0,$inp)); # load input
+ &pxor ($inout5,$tweak);
+
+ # inline _aesni_encrypt6 prologue and flip xor with tweak and key[0]
+ &movdqu ($inout1,&QWP(16*1,$inp));
+ &xorps ($inout0,$rndkey0); # input^=rndkey[0]
+ &movdqu ($inout2,&QWP(16*2,$inp));
+ &pxor ($inout1,$rndkey0);
+ &movdqu ($inout3,&QWP(16*3,$inp));
+ &pxor ($inout2,$rndkey0);
+ &movdqu ($inout4,&QWP(16*4,$inp));
+ &pxor ($inout3,$rndkey0);
+ &movdqu ($rndkey1,&QWP(16*5,$inp));
+ &pxor ($inout4,$rndkey0);
+ &lea ($inp,&DWP(16*6,$inp));
+ &pxor ($inout0,&QWP(16*0,"esp")); # input^=tweak
+ &movdqa (&QWP(16*$i,"esp"),$inout5); # save last tweak
+ &pxor ($inout5,$rndkey1);
+
+ &$movekey ($rndkey1,&QWP(16,$key_));
+ &lea ($key,&DWP(32,$key_));
+ &pxor ($inout1,&QWP(16*1,"esp"));
+ &aesdec ($inout0,$rndkey1);
+ &pxor ($inout2,&QWP(16*2,"esp"));
+ &aesdec ($inout1,$rndkey1);
+ &pxor ($inout3,&QWP(16*3,"esp"));
+ &dec ($rounds);
+ &aesdec ($inout2,$rndkey1);
+ &pxor ($inout4,&QWP(16*4,"esp"));
+ &aesdec ($inout3,$rndkey1);
+ &pxor ($inout5,$rndkey0);
+ &aesdec ($inout4,$rndkey1);
+ &$movekey ($rndkey0,&QWP(0,$key));
+ &aesdec ($inout5,$rndkey1);
+ &call (&label("_aesni_decrypt6_enter"));
+
+ &movdqa ($tweak,&QWP(16*5,"esp")); # last tweak
+ &pxor ($twtmp,$twtmp);
+ &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak
+ &pcmpgtd ($twtmp,$tweak); # broadcast upper bits
+ &xorps ($inout1,&QWP(16*1,"esp"));
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &xorps ($inout2,&QWP(16*2,"esp"));
+ &movups (&QWP(16*1,$out),$inout1);
+ &xorps ($inout3,&QWP(16*3,"esp"));
+ &movups (&QWP(16*2,$out),$inout2);
+ &xorps ($inout4,&QWP(16*4,"esp"));
+ &movups (&QWP(16*3,$out),$inout3);
+ &xorps ($inout5,$tweak);
+ &movups (&QWP(16*4,$out),$inout4);
+ &pshufd ($twres,$twtmp,0x13);
+ &movups (&QWP(16*5,$out),$inout5);
+ &lea ($out,&DWP(16*6,$out));
+ &movdqa ($twmask,&QWP(16*6,"esp")); # 0x0...010...87
+
+ &pxor ($twtmp,$twtmp);
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &mov ($rounds,$rounds_); # restore $rounds
+ &pxor ($tweak,$twres);
+
+ &sub ($len,16*6);
+ &jnc (&label("xts_dec_loop6"));
+
+ &lea ($rounds,&DWP(1,"",$rounds,2)); # restore $rounds
+ &mov ($key,$key_); # restore $key
+ &mov ($rounds_,$rounds);
+
+&set_label("xts_dec_short");
+ &add ($len,16*6);
+ &jz (&label("xts_dec_done6x"));
+
+ &movdqa ($inout3,$tweak); # put aside previous tweak
+ &cmp ($len,0x20);
+ &jb (&label("xts_dec_one"));
+
+ &pshufd ($twres,$twtmp,0x13);
+ &pxor ($twtmp,$twtmp);
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &pxor ($tweak,$twres);
+ &je (&label("xts_dec_two"));
+
+ &pshufd ($twres,$twtmp,0x13);
+ &pxor ($twtmp,$twtmp);
+ &movdqa ($inout4,$tweak); # put aside previous tweak
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &pxor ($tweak,$twres);
+ &cmp ($len,0x40);
+ &jb (&label("xts_dec_three"));
+
+ &pshufd ($twres,$twtmp,0x13);
+ &pxor ($twtmp,$twtmp);
+ &movdqa ($inout5,$tweak); # put aside previous tweak
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &pxor ($tweak,$twres);
+ &movdqa (&QWP(16*0,"esp"),$inout3);
+ &movdqa (&QWP(16*1,"esp"),$inout4);
+ &je (&label("xts_dec_four"));
+
+ &movdqa (&QWP(16*2,"esp"),$inout5);
+ &pshufd ($inout5,$twtmp,0x13);
+ &movdqa (&QWP(16*3,"esp"),$tweak);
+ &paddq ($tweak,$tweak); # &psllq($inout0,1);
+ &pand ($inout5,$twmask); # isolate carry and residue
+ &pxor ($inout5,$tweak);
+
+ &movdqu ($inout0,&QWP(16*0,$inp)); # load input
+ &movdqu ($inout1,&QWP(16*1,$inp));
+ &movdqu ($inout2,&QWP(16*2,$inp));
+ &pxor ($inout0,&QWP(16*0,"esp")); # input^=tweak
+ &movdqu ($inout3,&QWP(16*3,$inp));
+ &pxor ($inout1,&QWP(16*1,"esp"));
+ &movdqu ($inout4,&QWP(16*4,$inp));
+ &pxor ($inout2,&QWP(16*2,"esp"));
+ &lea ($inp,&DWP(16*5,$inp));
+ &pxor ($inout3,&QWP(16*3,"esp"));
+ &movdqa (&QWP(16*4,"esp"),$inout5); # save last tweak
+ &pxor ($inout4,$inout5);
+
+ &call ("_aesni_decrypt6");
+
+ &movaps ($tweak,&QWP(16*4,"esp")); # last tweak
+ &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak
+ &xorps ($inout1,&QWP(16*1,"esp"));
+ &xorps ($inout2,&QWP(16*2,"esp"));
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &xorps ($inout3,&QWP(16*3,"esp"));
+ &movups (&QWP(16*1,$out),$inout1);
+ &xorps ($inout4,$tweak);
+ &movups (&QWP(16*2,$out),$inout2);
+ &movups (&QWP(16*3,$out),$inout3);
+ &movups (&QWP(16*4,$out),$inout4);
+ &lea ($out,&DWP(16*5,$out));
+ &jmp (&label("xts_dec_done"));
+
+&set_label("xts_dec_one",16);
+ &movups ($inout0,&QWP(16*0,$inp)); # load input
+ &lea ($inp,&DWP(16*1,$inp));
+ &xorps ($inout0,$inout3); # input^=tweak
+ if ($inline)
+ { &aesni_inline_generate1("dec"); }
+ else
+ { &call ("_aesni_decrypt1"); }
+ &xorps ($inout0,$inout3); # output^=tweak
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &lea ($out,&DWP(16*1,$out));
+
+ &movdqa ($tweak,$inout3); # last tweak
+ &jmp (&label("xts_dec_done"));
+
+&set_label("xts_dec_two",16);
+ &movaps ($inout4,$tweak); # put aside last tweak
+
+ &movups ($inout0,&QWP(16*0,$inp)); # load input
+ &movups ($inout1,&QWP(16*1,$inp));
+ &lea ($inp,&DWP(16*2,$inp));
+ &xorps ($inout0,$inout3); # input^=tweak
+ &xorps ($inout1,$inout4);
+
+ &call ("_aesni_decrypt3");
+
+ &xorps ($inout0,$inout3); # output^=tweak
+ &xorps ($inout1,$inout4);
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &movups (&QWP(16*1,$out),$inout1);
+ &lea ($out,&DWP(16*2,$out));
+
+ &movdqa ($tweak,$inout4); # last tweak
+ &jmp (&label("xts_dec_done"));
+
+&set_label("xts_dec_three",16);
+ &movaps ($inout5,$tweak); # put aside last tweak
+ &movups ($inout0,&QWP(16*0,$inp)); # load input
+ &movups ($inout1,&QWP(16*1,$inp));
+ &movups ($inout2,&QWP(16*2,$inp));
+ &lea ($inp,&DWP(16*3,$inp));
+ &xorps ($inout0,$inout3); # input^=tweak
+ &xorps ($inout1,$inout4);
+ &xorps ($inout2,$inout5);
+
+ &call ("_aesni_decrypt3");
+
+ &xorps ($inout0,$inout3); # output^=tweak
+ &xorps ($inout1,$inout4);
+ &xorps ($inout2,$inout5);
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &movups (&QWP(16*1,$out),$inout1);
+ &movups (&QWP(16*2,$out),$inout2);
+ &lea ($out,&DWP(16*3,$out));
+
+ &movdqa ($tweak,$inout5); # last tweak
+ &jmp (&label("xts_dec_done"));
+
+&set_label("xts_dec_four",16);
+ &movaps ($inout4,$tweak); # put aside last tweak
+
+ &movups ($inout0,&QWP(16*0,$inp)); # load input
+ &movups ($inout1,&QWP(16*1,$inp));
+ &movups ($inout2,&QWP(16*2,$inp));
+ &xorps ($inout0,&QWP(16*0,"esp")); # input^=tweak
+ &movups ($inout3,&QWP(16*3,$inp));
+ &lea ($inp,&DWP(16*4,$inp));
+ &xorps ($inout1,&QWP(16*1,"esp"));
+ &xorps ($inout2,$inout5);
+ &xorps ($inout3,$inout4);
+
+ &call ("_aesni_decrypt4");
+
+ &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak
+ &xorps ($inout1,&QWP(16*1,"esp"));
+ &xorps ($inout2,$inout5);
+ &movups (&QWP(16*0,$out),$inout0); # write output
+ &xorps ($inout3,$inout4);
+ &movups (&QWP(16*1,$out),$inout1);
+ &movups (&QWP(16*2,$out),$inout2);
+ &movups (&QWP(16*3,$out),$inout3);
+ &lea ($out,&DWP(16*4,$out));
+
+ &movdqa ($tweak,$inout4); # last tweak
+ &jmp (&label("xts_dec_done"));
+
+&set_label("xts_dec_done6x",16); # $tweak is pre-calculated
+ &mov ($len,&DWP(16*7+0,"esp")); # restore original $len
+ &and ($len,15);
+ &jz (&label("xts_dec_ret"));
+ &mov (&DWP(16*7+0,"esp"),$len); # save $len%16
+ &jmp (&label("xts_dec_only_one_more"));
+
+&set_label("xts_dec_done",16);
+ &mov ($len,&DWP(16*7+0,"esp")); # restore original $len
+ &pxor ($twtmp,$twtmp);
+ &and ($len,15);
+ &jz (&label("xts_dec_ret"));
+
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &mov (&DWP(16*7+0,"esp"),$len); # save $len%16
+ &pshufd ($twres,$twtmp,0x13);
+ &pxor ($twtmp,$twtmp);
+ &movdqa ($twmask,&QWP(16*6,"esp"));
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($twres,$twmask); # isolate carry and residue
+ &pcmpgtd($twtmp,$tweak); # broadcast upper bits
+ &pxor ($tweak,$twres);
+
+&set_label("xts_dec_only_one_more");
+ &pshufd ($inout3,$twtmp,0x13);
+ &movdqa ($inout4,$tweak); # put aside previous tweak
+ &paddq ($tweak,$tweak); # &psllq($tweak,1);
+ &pand ($inout3,$twmask); # isolate carry and residue
+ &pxor ($inout3,$tweak);
+
+ &mov ($key,$key_); # restore $key
+ &mov ($rounds,$rounds_); # restore $rounds
+
+ &movups ($inout0,&QWP(0,$inp)); # load input
+ &xorps ($inout0,$inout3); # input^=tweak
+ if ($inline)
+ { &aesni_inline_generate1("dec"); }
+ else
+ { &call ("_aesni_decrypt1"); }
+ &xorps ($inout0,$inout3); # output^=tweak
+ &movups (&QWP(0,$out),$inout0); # write output
+
+&set_label("xts_dec_steal");
+ &movz ($rounds,&BP(16,$inp));
+ &movz ($key,&BP(0,$out));
+ &lea ($inp,&DWP(1,$inp));
+ &mov (&BP(0,$out),&LB($rounds));
+ &mov (&BP(16,$out),&LB($key));
+ &lea ($out,&DWP(1,$out));
+ &sub ($len,1);
+ &jnz (&label("xts_dec_steal"));
+
+ &sub ($out,&DWP(16*7+0,"esp")); # rewind $out
+ &mov ($key,$key_); # restore $key
+ &mov ($rounds,$rounds_); # restore $rounds
+
+ &movups ($inout0,&QWP(0,$out)); # load input
+ &xorps ($inout0,$inout4); # input^=tweak
+ if ($inline)
+ { &aesni_inline_generate1("dec"); }
+ else
+ { &call ("_aesni_decrypt1"); }
+ &xorps ($inout0,$inout4); # output^=tweak
+ &movups (&QWP(0,$out),$inout0); # write output
+
+&set_label("xts_dec_ret");
+ &mov ("esp",&DWP(16*7+4,"esp")); # restore %esp
+&function_end("aesni_xts_decrypt");
+}
+}
+
+######################################################################
+# void $PREFIX_cbc_encrypt (const void *inp, void *out,
+# size_t length, const AES_KEY *key,
+# unsigned char *ivp,const int enc);
+&function_begin("${PREFIX}_cbc_encrypt");
+ &mov ($inp,&wparam(0));
+ &mov ($rounds_,"esp");
+ &mov ($out,&wparam(1));
+ &sub ($rounds_,24);
+ &mov ($len,&wparam(2));
+ &and ($rounds_,-16);
+ &mov ($key,&wparam(3));
+ &mov ($key_,&wparam(4));
+ &test ($len,$len);
+ &jz (&label("cbc_abort"));
+
+ &cmp (&wparam(5),0);
+ &xchg ($rounds_,"esp"); # alloca
+ &movups ($ivec,&QWP(0,$key_)); # load IV
+ &mov ($rounds,&DWP(240,$key));
+ &mov ($key_,$key); # backup $key
+ &mov (&DWP(16,"esp"),$rounds_); # save original %esp
+ &mov ($rounds_,$rounds); # backup $rounds
+ &je (&label("cbc_decrypt"));
+
+ &movaps ($inout0,$ivec);
+ &cmp ($len,16);
+ &jb (&label("cbc_enc_tail"));
+ &sub ($len,16);
+ &jmp (&label("cbc_enc_loop"));
+
+&set_label("cbc_enc_loop",16);
+ &movups ($ivec,&QWP(0,$inp)); # input actually
+ &lea ($inp,&DWP(16,$inp));
+ if ($inline)
+ { &aesni_inline_generate1("enc",$inout0,$ivec); }
+ else
+ { &xorps($inout0,$ivec); &call("_aesni_encrypt1"); }
+ &mov ($rounds,$rounds_); # restore $rounds
+ &mov ($key,$key_); # restore $key
+ &movups (&QWP(0,$out),$inout0); # store output
+ &lea ($out,&DWP(16,$out));
+ &sub ($len,16);
+ &jnc (&label("cbc_enc_loop"));
+ &add ($len,16);
+ &jnz (&label("cbc_enc_tail"));
+ &movaps ($ivec,$inout0);
+ &jmp (&label("cbc_ret"));
+
+&set_label("cbc_enc_tail");
+ &mov ("ecx",$len); # zaps $rounds
+ &data_word(0xA4F3F689); # rep movsb
+ &mov ("ecx",16); # zero tail
+ &sub ("ecx",$len);
+ &xor ("eax","eax"); # zaps $len
+ &data_word(0xAAF3F689); # rep stosb
+ &lea ($out,&DWP(-16,$out)); # rewind $out by 1 block
+ &mov ($rounds,$rounds_); # restore $rounds
+ &mov ($inp,$out); # $inp and $out are the same
+ &mov ($key,$key_); # restore $key
+ &jmp (&label("cbc_enc_loop"));
+######################################################################
+&set_label("cbc_decrypt",16);
+ &cmp ($len,0x50);
+ &jbe (&label("cbc_dec_tail"));
+ &movaps (&QWP(0,"esp"),$ivec); # save IV
+ &sub ($len,0x50);
+ &jmp (&label("cbc_dec_loop6_enter"));
+
+&set_label("cbc_dec_loop6",16);
+ &movaps (&QWP(0,"esp"),$rndkey0); # save IV
+ &movups (&QWP(0,$out),$inout5);
+ &lea ($out,&DWP(0x10,$out));
+&set_label("cbc_dec_loop6_enter");
+ &movdqu ($inout0,&QWP(0,$inp));
+ &movdqu ($inout1,&QWP(0x10,$inp));
+ &movdqu ($inout2,&QWP(0x20,$inp));
+ &movdqu ($inout3,&QWP(0x30,$inp));
+ &movdqu ($inout4,&QWP(0x40,$inp));
+ &movdqu ($inout5,&QWP(0x50,$inp));
+
+ &call ("_aesni_decrypt6");
+
+ &movups ($rndkey1,&QWP(0,$inp));
+ &movups ($rndkey0,&QWP(0x10,$inp));
+ &xorps ($inout0,&QWP(0,"esp")); # ^=IV
+ &xorps ($inout1,$rndkey1);
+ &movups ($rndkey1,&QWP(0x20,$inp));
+ &xorps ($inout2,$rndkey0);
+ &movups ($rndkey0,&QWP(0x30,$inp));
+ &xorps ($inout3,$rndkey1);
+ &movups ($rndkey1,&QWP(0x40,$inp));
+ &xorps ($inout4,$rndkey0);
+ &movups ($rndkey0,&QWP(0x50,$inp)); # IV
+ &xorps ($inout5,$rndkey1);
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &lea ($inp,&DWP(0x60,$inp));
+ &movups (&QWP(0x20,$out),$inout2);
+ &mov ($rounds,$rounds_) # restore $rounds
+ &movups (&QWP(0x30,$out),$inout3);
+ &mov ($key,$key_); # restore $key
+ &movups (&QWP(0x40,$out),$inout4);
+ &lea ($out,&DWP(0x50,$out));
+ &sub ($len,0x60);
+ &ja (&label("cbc_dec_loop6"));
+
+ &movaps ($inout0,$inout5);
+ &movaps ($ivec,$rndkey0);
+ &add ($len,0x50);
+ &jle (&label("cbc_dec_tail_collected"));
+ &movups (&QWP(0,$out),$inout0);
+ &lea ($out,&DWP(0x10,$out));
+&set_label("cbc_dec_tail");
+ &movups ($inout0,&QWP(0,$inp));
+ &movaps ($in0,$inout0);
+ &cmp ($len,0x10);
+ &jbe (&label("cbc_dec_one"));
+
+ &movups ($inout1,&QWP(0x10,$inp));
+ &movaps ($in1,$inout1);
+ &cmp ($len,0x20);
+ &jbe (&label("cbc_dec_two"));
+
+ &movups ($inout2,&QWP(0x20,$inp));
+ &cmp ($len,0x30);
+ &jbe (&label("cbc_dec_three"));
+
+ &movups ($inout3,&QWP(0x30,$inp));
+ &cmp ($len,0x40);
+ &jbe (&label("cbc_dec_four"));
+
+ &movups ($inout4,&QWP(0x40,$inp));
+ &movaps (&QWP(0,"esp"),$ivec); # save IV
+ &movups ($inout0,&QWP(0,$inp));
+ &xorps ($inout5,$inout5);
+ &call ("_aesni_decrypt6");
+ &movups ($rndkey1,&QWP(0,$inp));
+ &movups ($rndkey0,&QWP(0x10,$inp));
+ &xorps ($inout0,&QWP(0,"esp")); # ^= IV
+ &xorps ($inout1,$rndkey1);
+ &movups ($rndkey1,&QWP(0x20,$inp));
+ &xorps ($inout2,$rndkey0);
+ &movups ($rndkey0,&QWP(0x30,$inp));
+ &xorps ($inout3,$rndkey1);
+ &movups ($ivec,&QWP(0x40,$inp)); # IV
+ &xorps ($inout4,$rndkey0);
+ &movups (&QWP(0,$out),$inout0);
+ &movups (&QWP(0x10,$out),$inout1);
+ &movups (&QWP(0x20,$out),$inout2);
+ &movups (&QWP(0x30,$out),$inout3);
+ &lea ($out,&DWP(0x40,$out));
+ &movaps ($inout0,$inout4);
+ &sub ($len,0x50);
+ &jmp (&label("cbc_dec_tail_collected"));
+
+&set_label("cbc_dec_one",16);
+ if ($inline)
+ { &aesni_inline_generate1("dec"); }
+ else
+ { &call ("_aesni_decrypt1"); }
+ &xorps ($inout0,$ivec);
+ &movaps ($ivec,$in0);
+ &sub ($len,0x10);
+ &jmp (&label("cbc_dec_tail_collected"));
+
+&set_label("cbc_dec_two",16);
+ &xorps ($inout2,$inout2);
+ &call ("_aesni_decrypt3");
+ &xorps ($inout0,$ivec);
+ &xorps ($inout1,$in0);
+ &movups (&QWP(0,$out),$inout0);
+ &movaps ($inout0,$inout1);
+ &lea ($out,&DWP(0x10,$out));
+ &movaps ($ivec,$in1);
+ &sub ($len,0x20);
+ &jmp (&label("cbc_dec_tail_collected"));
+
+&set_label("cbc_dec_three",16);
+ &call ("_aesni_decrypt3");
+ &xorps ($inout0,$ivec);
+ &xorps ($inout1,$in0);
+ &xorps ($inout2,$in1);
+ &movups (&QWP(0,$out),$inout0);
+ &movaps ($inout0,$inout2);
+ &movups (&QWP(0x10,$out),$inout1);
+ &lea ($out,&DWP(0x20,$out));
+ &movups ($ivec,&QWP(0x20,$inp));
+ &sub ($len,0x30);
+ &jmp (&label("cbc_dec_tail_collected"));
+
+&set_label("cbc_dec_four",16);
+ &call ("_aesni_decrypt4");
+ &movups ($rndkey1,&QWP(0x10,$inp));
+ &movups ($rndkey0,&QWP(0x20,$inp));
+ &xorps ($inout0,$ivec);
+ &movups ($ivec,&QWP(0x30,$inp));
+ &xorps ($inout1,$in0);
+ &movups (&QWP(0,$out),$inout0);
+ &xorps ($inout2,$rndkey1);
+ &movups (&QWP(0x10,$out),$inout1);
+ &xorps ($inout3,$rndkey0);
+ &movups (&QWP(0x20,$out),$inout2);
+ &lea ($out,&DWP(0x30,$out));
+ &movaps ($inout0,$inout3);
+ &sub ($len,0x40);
+
+&set_label("cbc_dec_tail_collected");
+ &and ($len,15);
+ &jnz (&label("cbc_dec_tail_partial"));
+ &movups (&QWP(0,$out),$inout0);
+ &jmp (&label("cbc_ret"));
+
+&set_label("cbc_dec_tail_partial",16);
+ &movaps (&QWP(0,"esp"),$inout0);
+ &mov ("ecx",16);
+ &mov ($inp,"esp");
+ &sub ("ecx",$len);
+ &data_word(0xA4F3F689); # rep movsb
+
+&set_label("cbc_ret");
+ &mov ("esp",&DWP(16,"esp")); # pull original %esp
+ &mov ($key_,&wparam(4));
+ &movups (&QWP(0,$key_),$ivec); # output IV
+&set_label("cbc_abort");
+&function_end("${PREFIX}_cbc_encrypt");
+
+######################################################################
+# Mechanical port from aesni-x86_64.pl.
+#
+# _aesni_set_encrypt_key is private interface,
+# input:
+# "eax" const unsigned char *userKey
+# $rounds int bits
+# $key AES_KEY *key
+# output:
+# "eax" return code
+# $round rounds
+
+&function_begin_B("_aesni_set_encrypt_key");
+ &test ("eax","eax");
+ &jz (&label("bad_pointer"));
+ &test ($key,$key);
+ &jz (&label("bad_pointer"));
+
+ &movups ("xmm0",&QWP(0,"eax")); # pull first 128 bits of *userKey
+ &xorps ("xmm4","xmm4"); # low dword of xmm4 is assumed 0
+ &lea ($key,&DWP(16,$key));
+ &cmp ($rounds,256);
+ &je (&label("14rounds"));
+ &cmp ($rounds,192);
+ &je (&label("12rounds"));
+ &cmp ($rounds,128);
+ &jne (&label("bad_keybits"));
+
+&set_label("10rounds",16);
+ &mov ($rounds,9);
+ &$movekey (&QWP(-16,$key),"xmm0"); # round 0
+ &aeskeygenassist("xmm1","xmm0",0x01); # round 1
+ &call (&label("key_128_cold"));
+ &aeskeygenassist("xmm1","xmm0",0x2); # round 2
+ &call (&label("key_128"));
+ &aeskeygenassist("xmm1","xmm0",0x04); # round 3
+ &call (&label("key_128"));
+ &aeskeygenassist("xmm1","xmm0",0x08); # round 4
+ &call (&label("key_128"));
+ &aeskeygenassist("xmm1","xmm0",0x10); # round 5
+ &call (&label("key_128"));
+ &aeskeygenassist("xmm1","xmm0",0x20); # round 6
+ &call (&label("key_128"));
+ &aeskeygenassist("xmm1","xmm0",0x40); # round 7
+ &call (&label("key_128"));
+ &aeskeygenassist("xmm1","xmm0",0x80); # round 8
+ &call (&label("key_128"));
+ &aeskeygenassist("xmm1","xmm0",0x1b); # round 9
+ &call (&label("key_128"));
+ &aeskeygenassist("xmm1","xmm0",0x36); # round 10
+ &call (&label("key_128"));
+ &$movekey (&QWP(0,$key),"xmm0");
+ &mov (&DWP(80,$key),$rounds);
+ &xor ("eax","eax");
+ &ret();
+
+&set_label("key_128",16);
+ &$movekey (&QWP(0,$key),"xmm0");
+ &lea ($key,&DWP(16,$key));
+&set_label("key_128_cold");
+ &shufps ("xmm4","xmm0",0b00010000);
+ &xorps ("xmm0","xmm4");
+ &shufps ("xmm4","xmm0",0b10001100);
+ &xorps ("xmm0","xmm4");
+ &shufps ("xmm1","xmm1",0b11111111); # critical path
+ &xorps ("xmm0","xmm1");
+ &ret();
+
+&set_label("12rounds",16);
+ &movq ("xmm2",&QWP(16,"eax")); # remaining 1/3 of *userKey
+ &mov ($rounds,11);
+ &$movekey (&QWP(-16,$key),"xmm0") # round 0
+ &aeskeygenassist("xmm1","xmm2",0x01); # round 1,2
+ &call (&label("key_192a_cold"));
+ &aeskeygenassist("xmm1","xmm2",0x02); # round 2,3
+ &call (&label("key_192b"));
+ &aeskeygenassist("xmm1","xmm2",0x04); # round 4,5
+ &call (&label("key_192a"));
+ &aeskeygenassist("xmm1","xmm2",0x08); # round 5,6
+ &call (&label("key_192b"));
+ &aeskeygenassist("xmm1","xmm2",0x10); # round 7,8
+ &call (&label("key_192a"));
+ &aeskeygenassist("xmm1","xmm2",0x20); # round 8,9
+ &call (&label("key_192b"));
+ &aeskeygenassist("xmm1","xmm2",0x40); # round 10,11
+ &call (&label("key_192a"));
+ &aeskeygenassist("xmm1","xmm2",0x80); # round 11,12
+ &call (&label("key_192b"));
+ &$movekey (&QWP(0,$key),"xmm0");
+ &mov (&DWP(48,$key),$rounds);
+ &xor ("eax","eax");
+ &ret();
+
+&set_label("key_192a",16);
+ &$movekey (&QWP(0,$key),"xmm0");
+ &lea ($key,&DWP(16,$key));
+&set_label("key_192a_cold",16);
+ &movaps ("xmm5","xmm2");
+&set_label("key_192b_warm");
+ &shufps ("xmm4","xmm0",0b00010000);
+ &movdqa ("xmm3","xmm2");
+ &xorps ("xmm0","xmm4");
+ &shufps ("xmm4","xmm0",0b10001100);
+ &pslldq ("xmm3",4);
+ &xorps ("xmm0","xmm4");
+ &pshufd ("xmm1","xmm1",0b01010101); # critical path
+ &pxor ("xmm2","xmm3");
+ &pxor ("xmm0","xmm1");
+ &pshufd ("xmm3","xmm0",0b11111111);
+ &pxor ("xmm2","xmm3");
+ &ret();
+
+&set_label("key_192b",16);
+ &movaps ("xmm3","xmm0");
+ &shufps ("xmm5","xmm0",0b01000100);
+ &$movekey (&QWP(0,$key),"xmm5");
+ &shufps ("xmm3","xmm2",0b01001110);
+ &$movekey (&QWP(16,$key),"xmm3");
+ &lea ($key,&DWP(32,$key));
+ &jmp (&label("key_192b_warm"));
+
+&set_label("14rounds",16);
+ &movups ("xmm2",&QWP(16,"eax")); # remaining half of *userKey
+ &mov ($rounds,13);
+ &lea ($key,&DWP(16,$key));
+ &$movekey (&QWP(-32,$key),"xmm0"); # round 0
+ &$movekey (&QWP(-16,$key),"xmm2"); # round 1
+ &aeskeygenassist("xmm1","xmm2",0x01); # round 2
+ &call (&label("key_256a_cold"));
+ &aeskeygenassist("xmm1","xmm0",0x01); # round 3
+ &call (&label("key_256b"));
+ &aeskeygenassist("xmm1","xmm2",0x02); # round 4
+ &call (&label("key_256a"));
+ &aeskeygenassist("xmm1","xmm0",0x02); # round 5
+ &call (&label("key_256b"));
+ &aeskeygenassist("xmm1","xmm2",0x04); # round 6
+ &call (&label("key_256a"));
+ &aeskeygenassist("xmm1","xmm0",0x04); # round 7
+ &call (&label("key_256b"));
+ &aeskeygenassist("xmm1","xmm2",0x08); # round 8
+ &call (&label("key_256a"));
+ &aeskeygenassist("xmm1","xmm0",0x08); # round 9
+ &call (&label("key_256b"));
+ &aeskeygenassist("xmm1","xmm2",0x10); # round 10
+ &call (&label("key_256a"));
+ &aeskeygenassist("xmm1","xmm0",0x10); # round 11
+ &call (&label("key_256b"));
+ &aeskeygenassist("xmm1","xmm2",0x20); # round 12
+ &call (&label("key_256a"));
+ &aeskeygenassist("xmm1","xmm0",0x20); # round 13
+ &call (&label("key_256b"));
+ &aeskeygenassist("xmm1","xmm2",0x40); # round 14
+ &call (&label("key_256a"));
+ &$movekey (&QWP(0,$key),"xmm0");
+ &mov (&DWP(16,$key),$rounds);
+ &xor ("eax","eax");
+ &ret();
+
+&set_label("key_256a",16);
+ &$movekey (&QWP(0,$key),"xmm2");
+ &lea ($key,&DWP(16,$key));
+&set_label("key_256a_cold");
+ &shufps ("xmm4","xmm0",0b00010000);
+ &xorps ("xmm0","xmm4");
+ &shufps ("xmm4","xmm0",0b10001100);
+ &xorps ("xmm0","xmm4");
+ &shufps ("xmm1","xmm1",0b11111111); # critical path
+ &xorps ("xmm0","xmm1");
+ &ret();
+
+&set_label("key_256b",16);
+ &$movekey (&QWP(0,$key),"xmm0");
+ &lea ($key,&DWP(16,$key));
+
+ &shufps ("xmm4","xmm2",0b00010000);
+ &xorps ("xmm2","xmm4");
+ &shufps ("xmm4","xmm2",0b10001100);
+ &xorps ("xmm2","xmm4");
+ &shufps ("xmm1","xmm1",0b10101010); # critical path
+ &xorps ("xmm2","xmm1");
+ &ret();
+
+&set_label("bad_pointer",4);
+ &mov ("eax",-1);
+ &ret ();
+&set_label("bad_keybits",4);
+ &mov ("eax",-2);
+ &ret ();
+&function_end_B("_aesni_set_encrypt_key");
+
+# int $PREFIX_set_encrypt_key (const unsigned char *userKey, int bits,
+# AES_KEY *key)
+&function_begin_B("${PREFIX}_set_encrypt_key");
+ &mov ("eax",&wparam(0));
+ &mov ($rounds,&wparam(1));
+ &mov ($key,&wparam(2));
+ &call ("_aesni_set_encrypt_key");
+ &ret ();
+&function_end_B("${PREFIX}_set_encrypt_key");
+
+# int $PREFIX_set_decrypt_key (const unsigned char *userKey, int bits,
+# AES_KEY *key)
+&function_begin_B("${PREFIX}_set_decrypt_key");
+ &mov ("eax",&wparam(0));
+ &mov ($rounds,&wparam(1));
+ &mov ($key,&wparam(2));
+ &call ("_aesni_set_encrypt_key");
+ &mov ($key,&wparam(2));
+ &shl ($rounds,4) # rounds-1 after _aesni_set_encrypt_key
+ &test ("eax","eax");
+ &jnz (&label("dec_key_ret"));
+ &lea ("eax",&DWP(16,$key,$rounds)); # end of key schedule
+
+ &$movekey ("xmm0",&QWP(0,$key)); # just swap
+ &$movekey ("xmm1",&QWP(0,"eax"));
+ &$movekey (&QWP(0,"eax"),"xmm0");
+ &$movekey (&QWP(0,$key),"xmm1");
+ &lea ($key,&DWP(16,$key));
+ &lea ("eax",&DWP(-16,"eax"));
+
+&set_label("dec_key_inverse");
+ &$movekey ("xmm0",&QWP(0,$key)); # swap and inverse
+ &$movekey ("xmm1",&QWP(0,"eax"));
+ &aesimc ("xmm0","xmm0");
+ &aesimc ("xmm1","xmm1");
+ &lea ($key,&DWP(16,$key));
+ &lea ("eax",&DWP(-16,"eax"));
+ &$movekey (&QWP(16,"eax"),"xmm0");
+ &$movekey (&QWP(-16,$key),"xmm1");
+ &cmp ("eax",$key);
+ &ja (&label("dec_key_inverse"));
+
+ &$movekey ("xmm0",&QWP(0,$key)); # inverse middle
+ &aesimc ("xmm0","xmm0");
+ &$movekey (&QWP(0,$key),"xmm0");
+
+ &xor ("eax","eax"); # return success
+&set_label("dec_key_ret");
+ &ret ();
+&function_end_B("${PREFIX}_set_decrypt_key");
+&asciz("AES for Intel AES-NI, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/deps/openssl/openssl/crypto/aes/asm/aesni-x86_64.pl b/deps/openssl/openssl/crypto/aes/asm/aesni-x86_64.pl
new file mode 100644
index 000000000..0dbb194b8
--- /dev/null
+++ b/deps/openssl/openssl/crypto/aes/asm/aesni-x86_64.pl
@@ -0,0 +1,3069 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# This module implements support for Intel AES-NI extension. In
+# OpenSSL context it's used with Intel engine, but can also be used as
+# drop-in replacement for crypto/aes/asm/aes-x86_64.pl [see below for
+# details].
+#
+# Performance.
+#
+# Given aes(enc|dec) instructions' latency asymptotic performance for
+# non-parallelizable modes such as CBC encrypt is 3.75 cycles per byte
+# processed with 128-bit key. And given their throughput asymptotic
+# performance for parallelizable modes is 1.25 cycles per byte. Being
+# asymptotic limit it's not something you commonly achieve in reality,
+# but how close does one get? Below are results collected for
+# different modes and block sized. Pairs of numbers are for en-/
+# decryption.
+#
+# 16-byte 64-byte 256-byte 1-KB 8-KB
+# ECB 4.25/4.25 1.38/1.38 1.28/1.28 1.26/1.26 1.26/1.26
+# CTR 5.42/5.42 1.92/1.92 1.44/1.44 1.28/1.28 1.26/1.26
+# CBC 4.38/4.43 4.15/1.43 4.07/1.32 4.07/1.29 4.06/1.28
+# CCM 5.66/9.42 4.42/5.41 4.16/4.40 4.09/4.15 4.06/4.07
+# OFB 5.42/5.42 4.64/4.64 4.44/4.44 4.39/4.39 4.38/4.38
+# CFB 5.73/5.85 5.56/5.62 5.48/5.56 5.47/5.55 5.47/5.55
+#
+# ECB, CTR, CBC and CCM results are free from EVP overhead. This means
+# that otherwise used 'openssl speed -evp aes-128-??? -engine aesni
+# [-decrypt]' will exhibit 10-15% worse results for smaller blocks.
+# The results were collected with specially crafted speed.c benchmark
+# in order to compare them with results reported in "Intel Advanced
+# Encryption Standard (AES) New Instruction Set" White Paper Revision
+# 3.0 dated May 2010. All above results are consistently better. This
+# module also provides better performance for block sizes smaller than
+# 128 bytes in points *not* represented in the above table.
+#
+# Looking at the results for 8-KB buffer.
+#
+# CFB and OFB results are far from the limit, because implementation
+# uses "generic" CRYPTO_[c|o]fb128_encrypt interfaces relying on
+# single-block aesni_encrypt, which is not the most optimal way to go.
+# CBC encrypt result is unexpectedly high and there is no documented
+# explanation for it. Seemingly there is a small penalty for feeding
+# the result back to AES unit the way it's done in CBC mode. There is
+# nothing one can do and the result appears optimal. CCM result is
+# identical to CBC, because CBC-MAC is essentially CBC encrypt without
+# saving output. CCM CTR "stays invisible," because it's neatly
+# interleaved wih CBC-MAC. This provides ~30% improvement over
+# "straghtforward" CCM implementation with CTR and CBC-MAC performed
+# disjointly. Parallelizable modes practically achieve the theoretical
+# limit.
+#
+# Looking at how results vary with buffer size.
+#
+# Curves are practically saturated at 1-KB buffer size. In most cases
+# "256-byte" performance is >95%, and "64-byte" is ~90% of "8-KB" one.
+# CTR curve doesn't follow this pattern and is "slowest" changing one
+# with "256-byte" result being 87% of "8-KB." This is because overhead
+# in CTR mode is most computationally intensive. Small-block CCM
+# decrypt is slower than encrypt, because first CTR and last CBC-MAC
+# iterations can't be interleaved.
+#
+# Results for 192- and 256-bit keys.
+#
+# EVP-free results were observed to scale perfectly with number of
+# rounds for larger block sizes, i.e. 192-bit result being 10/12 times
+# lower and 256-bit one - 10/14. Well, in CBC encrypt case differences
+# are a tad smaller, because the above mentioned penalty biases all
+# results by same constant value. In similar way function call
+# overhead affects small-block performance, as well as OFB and CFB
+# results. Differences are not large, most common coefficients are
+# 10/11.7 and 10/13.4 (as opposite to 10/12.0 and 10/14.0), but one
+# observe even 10/11.2 and 10/12.4 (CTR, OFB, CFB)...
+
+# January 2011
+#
+# While Westmere processor features 6 cycles latency for aes[enc|dec]
+# instructions, which can be scheduled every second cycle, Sandy
+# Bridge spends 8 cycles per instruction, but it can schedule them
+# every cycle. This means that code targeting Westmere would perform
+# suboptimally on Sandy Bridge. Therefore this update.
+#
+# In addition, non-parallelizable CBC encrypt (as well as CCM) is
+# optimized. Relative improvement might appear modest, 8% on Westmere,
+# but in absolute terms it's 3.77 cycles per byte encrypted with
+# 128-bit key on Westmere, and 5.07 - on Sandy Bridge. These numbers
+# should be compared to asymptotic limits of 3.75 for Westmere and
+# 5.00 for Sandy Bridge. Actually, the fact that they get this close
+# to asymptotic limits is quite amazing. Indeed, the limit is
+# calculated as latency times number of rounds, 10 for 128-bit key,
+# and divided by 16, the number of bytes in block, or in other words
+# it accounts *solely* for aesenc instructions. But there are extra
+# instructions, and numbers so close to the asymptotic limits mean
+# that it's as if it takes as little as *one* additional cycle to
+# execute all of them. How is it possible? It is possible thanks to
+# out-of-order execution logic, which manages to overlap post-
+# processing of previous block, things like saving the output, with
+# actual encryption of current block, as well as pre-processing of
+# current block, things like fetching input and xor-ing it with
+# 0-round element of the key schedule, with actual encryption of
+# previous block. Keep this in mind...
+#
+# For parallelizable modes, such as ECB, CBC decrypt, CTR, higher
+# performance is achieved by interleaving instructions working on
+# independent blocks. In which case asymptotic limit for such modes
+# can be obtained by dividing above mentioned numbers by AES
+# instructions' interleave factor. Westmere can execute at most 3
+# instructions at a time, meaning that optimal interleave factor is 3,
+# and that's where the "magic" number of 1.25 come from. "Optimal
+# interleave factor" means that increase of interleave factor does
+# not improve performance. The formula has proven to reflect reality
+# pretty well on Westmere... Sandy Bridge on the other hand can
+# execute up to 8 AES instructions at a time, so how does varying
+# interleave factor affect the performance? Here is table for ECB
+# (numbers are cycles per byte processed with 128-bit key):
+#
+# instruction interleave factor 3x 6x 8x
+# theoretical asymptotic limit 1.67 0.83 0.625
+# measured performance for 8KB block 1.05 0.86 0.84
+#
+# "as if" interleave factor 4.7x 5.8x 6.0x
+#
+# Further data for other parallelizable modes:
+#
+# CBC decrypt 1.16 0.93 0.93
+# CTR 1.14 0.91 n/a
+#
+# Well, given 3x column it's probably inappropriate to call the limit
+# asymptotic, if it can be surpassed, isn't it? What happens there?
+# Rewind to CBC paragraph for the answer. Yes, out-of-order execution
+# magic is responsible for this. Processor overlaps not only the
+# additional instructions with AES ones, but even AES instuctions
+# processing adjacent triplets of independent blocks. In the 6x case
+# additional instructions still claim disproportionally small amount
+# of additional cycles, but in 8x case number of instructions must be
+# a tad too high for out-of-order logic to cope with, and AES unit
+# remains underutilized... As you can see 8x interleave is hardly
+# justifiable, so there no need to feel bad that 32-bit aesni-x86.pl
+# utilizies 6x interleave because of limited register bank capacity.
+#
+# Higher interleave factors do have negative impact on Westmere
+# performance. While for ECB mode it's negligible ~1.5%, other
+# parallelizables perform ~5% worse, which is outweighed by ~25%
+# improvement on Sandy Bridge. To balance regression on Westmere
+# CTR mode was implemented with 6x aesenc interleave factor.
+
+# April 2011
+#
+# Add aesni_xts_[en|de]crypt. Westmere spends 1.33 cycles processing
+# one byte out of 8KB with 128-bit key, Sandy Bridge - 0.97. Just like
+# in CTR mode AES instruction interleave factor was chosen to be 6x.
+
+$PREFIX="aesni"; # if $PREFIX is set to "AES", the script
+ # generates drop-in replacement for
+ # crypto/aes/asm/aes-x86_64.pl:-)
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+$movkey = $PREFIX eq "aesni" ? "movups" : "movups";
+@_4args=$win64? ("%rcx","%rdx","%r8", "%r9") : # Win64 order
+ ("%rdi","%rsi","%rdx","%rcx"); # Unix order
+
+$code=".text\n";
+
+$rounds="%eax"; # input to and changed by aesni_[en|de]cryptN !!!
+# this is natural Unix argument order for public $PREFIX_[ecb|cbc]_encrypt ...
+$inp="%rdi";
+$out="%rsi";
+$len="%rdx";
+$key="%rcx"; # input to and changed by aesni_[en|de]cryptN !!!
+$ivp="%r8"; # cbc, ctr, ...
+
+$rnds_="%r10d"; # backup copy for $rounds
+$key_="%r11"; # backup copy for $key
+
+# %xmm register layout
+$rndkey0="%xmm0"; $rndkey1="%xmm1";
+$inout0="%xmm2"; $inout1="%xmm3";
+$inout2="%xmm4"; $inout3="%xmm5";
+$inout4="%xmm6"; $inout5="%xmm7";
+$inout6="%xmm8"; $inout7="%xmm9";
+
+$in2="%xmm6"; $in1="%xmm7"; # used in CBC decrypt, CTR, ...
+$in0="%xmm8"; $iv="%xmm9";
+
+# Inline version of internal aesni_[en|de]crypt1.
+#
+# Why folded loop? Because aes[enc|dec] is slow enough to accommodate
+# cycles which take care of loop variables...
+{ my $sn;
+sub aesni_generate1 {
+my ($p,$key,$rounds,$inout,$ivec)=@_; $inout=$inout0 if (!defined($inout));
+++$sn;
+$code.=<<___;
+ $movkey ($key),$rndkey0
+ $movkey 16($key),$rndkey1
+___
+$code.=<<___ if (defined($ivec));
+ xorps $rndkey0,$ivec
+ lea 32($key),$key
+ xorps $ivec,$inout
+___
+$code.=<<___ if (!defined($ivec));
+ lea 32($key),$key
+ xorps $rndkey0,$inout
+___
+$code.=<<___;
+.Loop_${p}1_$sn:
+ aes${p} $rndkey1,$inout
+ dec $rounds
+ $movkey ($key),$rndkey1
+ lea 16($key),$key
+ jnz .Loop_${p}1_$sn # loop body is 16 bytes
+ aes${p}last $rndkey1,$inout
+___
+}}
+# void $PREFIX_[en|de]crypt (const void *inp,void *out,const AES_KEY *key);
+#
+{ my ($inp,$out,$key) = @_4args;
+
+$code.=<<___;
+.globl ${PREFIX}_encrypt
+.type ${PREFIX}_encrypt,\@abi-omnipotent
+.align 16
+${PREFIX}_encrypt:
+ movups ($inp),$inout0 # load input
+ mov 240($key),$rounds # key->rounds
+___
+ &aesni_generate1("enc",$key,$rounds);
+$code.=<<___;
+ movups $inout0,($out) # output
+ ret
+.size ${PREFIX}_encrypt,.-${PREFIX}_encrypt
+
+.globl ${PREFIX}_decrypt
+.type ${PREFIX}_decrypt,\@abi-omnipotent
+.align 16
+${PREFIX}_decrypt:
+ movups ($inp),$inout0 # load input
+ mov 240($key),$rounds # key->rounds
+___
+ &aesni_generate1("dec",$key,$rounds);
+$code.=<<___;
+ movups $inout0,($out) # output
+ ret
+.size ${PREFIX}_decrypt, .-${PREFIX}_decrypt
+___
+}
+
+# _aesni_[en|de]cryptN are private interfaces, N denotes interleave
+# factor. Why 3x subroutine were originally used in loops? Even though
+# aes[enc|dec] latency was originally 6, it could be scheduled only
+# every *2nd* cycle. Thus 3x interleave was the one providing optimal
+# utilization, i.e. when subroutine's throughput is virtually same as
+# of non-interleaved subroutine [for number of input blocks up to 3].
+# This is why it makes no sense to implement 2x subroutine.
+# aes[enc|dec] latency in next processor generation is 8, but the
+# instructions can be scheduled every cycle. Optimal interleave for
+# new processor is therefore 8x...
+sub aesni_generate3 {
+my $dir=shift;
+# As already mentioned it takes in $key and $rounds, which are *not*
+# preserved. $inout[0-2] is cipher/clear text...
+$code.=<<___;
+.type _aesni_${dir}rypt3,\@abi-omnipotent
+.align 16
+_aesni_${dir}rypt3:
+ $movkey ($key),$rndkey0
+ shr \$1,$rounds
+ $movkey 16($key),$rndkey1
+ lea 32($key),$key
+ xorps $rndkey0,$inout0
+ xorps $rndkey0,$inout1
+ xorps $rndkey0,$inout2
+ $movkey ($key),$rndkey0
+
+.L${dir}_loop3:
+ aes${dir} $rndkey1,$inout0
+ aes${dir} $rndkey1,$inout1
+ dec $rounds
+ aes${dir} $rndkey1,$inout2
+ $movkey 16($key),$rndkey1
+ aes${dir} $rndkey0,$inout0
+ aes${dir} $rndkey0,$inout1
+ lea 32($key),$key
+ aes${dir} $rndkey0,$inout2
+ $movkey ($key),$rndkey0
+ jnz .L${dir}_loop3
+
+ aes${dir} $rndkey1,$inout0
+ aes${dir} $rndkey1,$inout1
+ aes${dir} $rndkey1,$inout2
+ aes${dir}last $rndkey0,$inout0
+ aes${dir}last $rndkey0,$inout1
+ aes${dir}last $rndkey0,$inout2
+ ret
+.size _aesni_${dir}rypt3,.-_aesni_${dir}rypt3
+___
+}
+# 4x interleave is implemented to improve small block performance,
+# most notably [and naturally] 4 block by ~30%. One can argue that one
+# should have implemented 5x as well, but improvement would be <20%,
+# so it's not worth it...
+sub aesni_generate4 {
+my $dir=shift;
+# As already mentioned it takes in $key and $rounds, which are *not*
+# preserved. $inout[0-3] is cipher/clear text...
+$code.=<<___;
+.type _aesni_${dir}rypt4,\@abi-omnipotent
+.align 16
+_aesni_${dir}rypt4:
+ $movkey ($key),$rndkey0
+ shr \$1,$rounds
+ $movkey 16($key),$rndkey1
+ lea 32($key),$key
+ xorps $rndkey0,$inout0
+ xorps $rndkey0,$inout1
+ xorps $rndkey0,$inout2
+ xorps $rndkey0,$inout3
+ $movkey ($key),$rndkey0
+
+.L${dir}_loop4:
+ aes${dir} $rndkey1,$inout0
+ aes${dir} $rndkey1,$inout1
+ dec $rounds
+ aes${dir} $rndkey1,$inout2
+ aes${dir} $rndkey1,$inout3
+ $movkey 16($key),$rndkey1
+ aes${dir} $rndkey0,$inout0
+ aes${dir} $rndkey0,$inout1
+ lea 32($key),$key
+ aes${dir} $rndkey0,$inout2
+ aes${dir} $rndkey0,$inout3
+ $movkey ($key),$rndkey0
+ jnz .L${dir}_loop4
+
+ aes${dir} $rndkey1,$inout0
+ aes${dir} $rndkey1,$inout1
+ aes${dir} $rndkey1,$inout2
+ aes${dir} $rndkey1,$inout3
+ aes${dir}last $rndkey0,$inout0
+ aes${dir}last $rndkey0,$inout1
+ aes${dir}last $rndkey0,$inout2
+ aes${dir}last $rndkey0,$inout3
+ ret
+.size _aesni_${dir}rypt4,.-_aesni_${dir}rypt4
+___
+}
+sub aesni_generate6 {
+my $dir=shift;
+# As already mentioned it takes in $key and $rounds, which are *not*
+# preserved. $inout[0-5] is cipher/clear text...
+$code.=<<___;
+.type _aesni_${dir}rypt6,\@abi-omnipotent
+.align 16
+_aesni_${dir}rypt6:
+ $movkey ($key),$rndkey0
+ shr \$1,$rounds
+ $movkey 16($key),$rndkey1
+ lea 32($key),$key
+ xorps $rndkey0,$inout0
+ pxor $rndkey0,$inout1
+ aes${dir} $rndkey1,$inout0
+ pxor $rndkey0,$inout2
+ aes${dir} $rndkey1,$inout1
+ pxor $rndkey0,$inout3
+ aes${dir} $rndkey1,$inout2
+ pxor $rndkey0,$inout4
+ aes${dir} $rndkey1,$inout3
+ pxor $rndkey0,$inout5
+ dec $rounds
+ aes${dir} $rndkey1,$inout4
+ $movkey ($key),$rndkey0
+ aes${dir} $rndkey1,$inout5
+ jmp .L${dir}_loop6_enter
+.align 16
+.L${dir}_loop6:
+ aes${dir} $rndkey1,$inout0
+ aes${dir} $rndkey1,$inout1
+ dec $rounds
+ aes${dir} $rndkey1,$inout2
+ aes${dir} $rndkey1,$inout3
+ aes${dir} $rndkey1,$inout4
+ aes${dir} $rndkey1,$inout5
+.L${dir}_loop6_enter: # happens to be 16-byte aligned
+ $movkey 16($key),$rndkey1
+ aes${dir} $rndkey0,$inout0
+ aes${dir} $rndkey0,$inout1
+ lea 32($key),$key
+ aes${dir} $rndkey0,$inout2
+ aes${dir} $rndkey0,$inout3
+ aes${dir} $rndkey0,$inout4
+ aes${dir} $rndkey0,$inout5
+ $movkey ($key),$rndkey0
+ jnz .L${dir}_loop6
+
+ aes${dir} $rndkey1,$inout0
+ aes${dir} $rndkey1,$inout1
+ aes${dir} $rndkey1,$inout2
+ aes${dir} $rndkey1,$inout3
+ aes${dir} $rndkey1,$inout4
+ aes${dir} $rndkey1,$inout5
+ aes${dir}last $rndkey0,$inout0
+ aes${dir}last $rndkey0,$inout1
+ aes${dir}last $rndkey0,$inout2
+ aes${dir}last $rndkey0,$inout3
+ aes${dir}last $rndkey0,$inout4
+ aes${dir}last $rndkey0,$inout5
+ ret
+.size _aesni_${dir}rypt6,.-_aesni_${dir}rypt6
+___
+}
+sub aesni_generate8 {
+my $dir=shift;
+# As already mentioned it takes in $key and $rounds, which are *not*
+# preserved. $inout[0-7] is cipher/clear text...
+$code.=<<___;
+.type _aesni_${dir}rypt8,\@abi-omnipotent
+.align 16
+_aesni_${dir}rypt8:
+ $movkey ($key),$rndkey0
+ shr \$1,$rounds
+ $movkey 16($key),$rndkey1
+ lea 32($key),$key
+ xorps $rndkey0,$inout0
+ xorps $rndkey0,$inout1
+ aes${dir} $rndkey1,$inout0
+ pxor $rndkey0,$inout2
+ aes${dir} $rndkey1,$inout1
+ pxor $rndkey0,$inout3
+ aes${dir} $rndkey1,$inout2
+ pxor $rndkey0,$inout4
+ aes${dir} $rndkey1,$inout3
+ pxor $rndkey0,$inout5
+ dec $rounds
+ aes${dir} $rndkey1,$inout4
+ pxor $rndkey0,$inout6
+ aes${dir} $rndkey1,$inout5
+ pxor $rndkey0,$inout7
+ $movkey ($key),$rndkey0
+ aes${dir} $rndkey1,$inout6
+ aes${dir} $rndkey1,$inout7
+ $movkey 16($key),$rndkey1
+ jmp .L${dir}_loop8_enter
+.align 16
+.L${dir}_loop8:
+ aes${dir} $rndkey1,$inout0
+ aes${dir} $rndkey1,$inout1
+ dec $rounds
+ aes${dir} $rndkey1,$inout2
+ aes${dir} $rndkey1,$inout3
+ aes${dir} $rndkey1,$inout4
+ aes${dir} $rndkey1,$inout5
+ aes${dir} $rndkey1,$inout6
+ aes${dir} $rndkey1,$inout7
+ $movkey 16($key),$rndkey1
+.L${dir}_loop8_enter: # happens to be 16-byte aligned
+ aes${dir} $rndkey0,$inout0
+ aes${dir} $rndkey0,$inout1
+ lea 32($key),$key
+ aes${dir} $rndkey0,$inout2
+ aes${dir} $rndkey0,$inout3
+ aes${dir} $rndkey0,$inout4
+ aes${dir} $rndkey0,$inout5
+ aes${dir} $rndkey0,$inout6
+ aes${dir} $rndkey0,$inout7
+ $movkey ($key),$rndkey0
+ jnz .L${dir}_loop8
+
+ aes${dir} $rndkey1,$inout0
+ aes${dir} $rndkey1,$inout1
+ aes${dir} $rndkey1,$inout2
+ aes${dir} $rndkey1,$inout3
+ aes${dir} $rndkey1,$inout4
+ aes${dir} $rndkey1,$inout5
+ aes${dir} $rndkey1,$inout6
+ aes${dir} $rndkey1,$inout7
+ aes${dir}last $rndkey0,$inout0
+ aes${dir}last $rndkey0,$inout1
+ aes${dir}last $rndkey0,$inout2
+ aes${dir}last $rndkey0,$inout3
+ aes${dir}last $rndkey0,$inout4
+ aes${dir}last $rndkey0,$inout5
+ aes${dir}last $rndkey0,$inout6
+ aes${dir}last $rndkey0,$inout7
+ ret
+.size _aesni_${dir}rypt8,.-_aesni_${dir}rypt8
+___
+}
+&aesni_generate3("enc") if ($PREFIX eq "aesni");
+&aesni_generate3("dec");
+&aesni_generate4("enc") if ($PREFIX eq "aesni");
+&aesni_generate4("dec");
+&aesni_generate6("enc") if ($PREFIX eq "aesni");
+&aesni_generate6("dec");
+&aesni_generate8("enc") if ($PREFIX eq "aesni");
+&aesni_generate8("dec");
+
+if ($PREFIX eq "aesni") {
+########################################################################
+# void aesni_ecb_encrypt (const void *in, void *out,
+# size_t length, const AES_KEY *key,
+# int enc);
+$code.=<<___;
+.globl aesni_ecb_encrypt
+.type aesni_ecb_encrypt,\@function,5
+.align 16
+aesni_ecb_encrypt:
+ and \$-16,$len
+ jz .Lecb_ret
+
+ mov 240($key),$rounds # key->rounds
+ $movkey ($key),$rndkey0
+ mov $key,$key_ # backup $key
+ mov $rounds,$rnds_ # backup $rounds
+ test %r8d,%r8d # 5th argument
+ jz .Lecb_decrypt
+#--------------------------- ECB ENCRYPT ------------------------------#
+ cmp \$0x80,$len
+ jb .Lecb_enc_tail
+
+ movdqu ($inp),$inout0
+ movdqu 0x10($inp),$inout1
+ movdqu 0x20($inp),$inout2
+ movdqu 0x30($inp),$inout3
+ movdqu 0x40($inp),$inout4
+ movdqu 0x50($inp),$inout5
+ movdqu 0x60($inp),$inout6
+ movdqu 0x70($inp),$inout7
+ lea 0x80($inp),$inp
+ sub \$0x80,$len
+ jmp .Lecb_enc_loop8_enter
+.align 16
+.Lecb_enc_loop8:
+ movups $inout0,($out)
+ mov $key_,$key # restore $key
+ movdqu ($inp),$inout0
+ mov $rnds_,$rounds # restore $rounds
+ movups $inout1,0x10($out)
+ movdqu 0x10($inp),$inout1
+ movups $inout2,0x20($out)
+ movdqu 0x20($inp),$inout2
+ movups $inout3,0x30($out)
+ movdqu 0x30($inp),$inout3
+ movups $inout4,0x40($out)
+ movdqu 0x40($inp),$inout4
+ movups $inout5,0x50($out)
+ movdqu 0x50($inp),$inout5
+ movups $inout6,0x60($out)
+ movdqu 0x60($inp),$inout6
+ movups $inout7,0x70($out)
+ lea 0x80($out),$out
+ movdqu 0x70($inp),$inout7
+ lea 0x80($inp),$inp
+.Lecb_enc_loop8_enter:
+
+ call _aesni_encrypt8
+
+ sub \$0x80,$len
+ jnc .Lecb_enc_loop8
+
+ movups $inout0,($out)
+ mov $key_,$key # restore $key
+ movups $inout1,0x10($out)
+ mov $rnds_,$rounds # restore $rounds
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ movups $inout4,0x40($out)
+ movups $inout5,0x50($out)
+ movups $inout6,0x60($out)
+ movups $inout7,0x70($out)
+ lea 0x80($out),$out
+ add \$0x80,$len
+ jz .Lecb_ret
+
+.Lecb_enc_tail:
+ movups ($inp),$inout0
+ cmp \$0x20,$len
+ jb .Lecb_enc_one
+ movups 0x10($inp),$inout1
+ je .Lecb_enc_two
+ movups 0x20($inp),$inout2
+ cmp \$0x40,$len
+ jb .Lecb_enc_three
+ movups 0x30($inp),$inout3
+ je .Lecb_enc_four
+ movups 0x40($inp),$inout4
+ cmp \$0x60,$len
+ jb .Lecb_enc_five
+ movups 0x50($inp),$inout5
+ je .Lecb_enc_six
+ movdqu 0x60($inp),$inout6
+ call _aesni_encrypt8
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ movups $inout4,0x40($out)
+ movups $inout5,0x50($out)
+ movups $inout6,0x60($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_one:
+___
+ &aesni_generate1("enc",$key,$rounds);
+$code.=<<___;
+ movups $inout0,($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_two:
+ xorps $inout2,$inout2
+ call _aesni_encrypt3
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_three:
+ call _aesni_encrypt3
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_four:
+ call _aesni_encrypt4
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_five:
+ xorps $inout5,$inout5
+ call _aesni_encrypt6
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ movups $inout4,0x40($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_enc_six:
+ call _aesni_encrypt6
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ movups $inout4,0x40($out)
+ movups $inout5,0x50($out)
+ jmp .Lecb_ret
+ #--------------------------- ECB DECRYPT ------------------------------#
+.align 16
+.Lecb_decrypt:
+ cmp \$0x80,$len
+ jb .Lecb_dec_tail
+
+ movdqu ($inp),$inout0
+ movdqu 0x10($inp),$inout1
+ movdqu 0x20($inp),$inout2
+ movdqu 0x30($inp),$inout3
+ movdqu 0x40($inp),$inout4
+ movdqu 0x50($inp),$inout5
+ movdqu 0x60($inp),$inout6
+ movdqu 0x70($inp),$inout7
+ lea 0x80($inp),$inp
+ sub \$0x80,$len
+ jmp .Lecb_dec_loop8_enter
+.align 16
+.Lecb_dec_loop8:
+ movups $inout0,($out)
+ mov $key_,$key # restore $key
+ movdqu ($inp),$inout0
+ mov $rnds_,$rounds # restore $rounds
+ movups $inout1,0x10($out)
+ movdqu 0x10($inp),$inout1
+ movups $inout2,0x20($out)
+ movdqu 0x20($inp),$inout2
+ movups $inout3,0x30($out)
+ movdqu 0x30($inp),$inout3
+ movups $inout4,0x40($out)
+ movdqu 0x40($inp),$inout4
+ movups $inout5,0x50($out)
+ movdqu 0x50($inp),$inout5
+ movups $inout6,0x60($out)
+ movdqu 0x60($inp),$inout6
+ movups $inout7,0x70($out)
+ lea 0x80($out),$out
+ movdqu 0x70($inp),$inout7
+ lea 0x80($inp),$inp
+.Lecb_dec_loop8_enter:
+
+ call _aesni_decrypt8
+
+ $movkey ($key_),$rndkey0
+ sub \$0x80,$len
+ jnc .Lecb_dec_loop8
+
+ movups $inout0,($out)
+ mov $key_,$key # restore $key
+ movups $inout1,0x10($out)
+ mov $rnds_,$rounds # restore $rounds
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ movups $inout4,0x40($out)
+ movups $inout5,0x50($out)
+ movups $inout6,0x60($out)
+ movups $inout7,0x70($out)
+ lea 0x80($out),$out
+ add \$0x80,$len
+ jz .Lecb_ret
+
+.Lecb_dec_tail:
+ movups ($inp),$inout0
+ cmp \$0x20,$len
+ jb .Lecb_dec_one
+ movups 0x10($inp),$inout1
+ je .Lecb_dec_two
+ movups 0x20($inp),$inout2
+ cmp \$0x40,$len
+ jb .Lecb_dec_three
+ movups 0x30($inp),$inout3
+ je .Lecb_dec_four
+ movups 0x40($inp),$inout4
+ cmp \$0x60,$len
+ jb .Lecb_dec_five
+ movups 0x50($inp),$inout5
+ je .Lecb_dec_six
+ movups 0x60($inp),$inout6
+ $movkey ($key),$rndkey0
+ call _aesni_decrypt8
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ movups $inout4,0x40($out)
+ movups $inout5,0x50($out)
+ movups $inout6,0x60($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_one:
+___
+ &aesni_generate1("dec",$key,$rounds);
+$code.=<<___;
+ movups $inout0,($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_two:
+ xorps $inout2,$inout2
+ call _aesni_decrypt3
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_three:
+ call _aesni_decrypt3
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_four:
+ call _aesni_decrypt4
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_five:
+ xorps $inout5,$inout5
+ call _aesni_decrypt6
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ movups $inout4,0x40($out)
+ jmp .Lecb_ret
+.align 16
+.Lecb_dec_six:
+ call _aesni_decrypt6
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ movups $inout4,0x40($out)
+ movups $inout5,0x50($out)
+
+.Lecb_ret:
+ ret
+.size aesni_ecb_encrypt,.-aesni_ecb_encrypt
+___
+
+{
+######################################################################
+# void aesni_ccm64_[en|de]crypt_blocks (const void *in, void *out,
+# size_t blocks, const AES_KEY *key,
+# const char *ivec,char *cmac);
+#
+# Handles only complete blocks, operates on 64-bit counter and
+# does not update *ivec! Nor does it finalize CMAC value
+# (see engine/eng_aesni.c for details)
+#
+{
+my $cmac="%r9"; # 6th argument
+
+my $increment="%xmm6";
+my $bswap_mask="%xmm7";
+
+$code.=<<___;
+.globl aesni_ccm64_encrypt_blocks
+.type aesni_ccm64_encrypt_blocks,\@function,6
+.align 16
+aesni_ccm64_encrypt_blocks:
+___
+$code.=<<___ if ($win64);
+ lea -0x58(%rsp),%rsp
+ movaps %xmm6,(%rsp)
+ movaps %xmm7,0x10(%rsp)
+ movaps %xmm8,0x20(%rsp)
+ movaps %xmm9,0x30(%rsp)
+.Lccm64_enc_body:
+___
+$code.=<<___;
+ mov 240($key),$rounds # key->rounds
+ movdqu ($ivp),$iv
+ movdqa .Lincrement64(%rip),$increment
+ movdqa .Lbswap_mask(%rip),$bswap_mask
+
+ shr \$1,$rounds
+ lea 0($key),$key_
+ movdqu ($cmac),$inout1
+ movdqa $iv,$inout0
+ mov $rounds,$rnds_
+ pshufb $bswap_mask,$iv
+ jmp .Lccm64_enc_outer
+.align 16
+.Lccm64_enc_outer:
+ $movkey ($key_),$rndkey0
+ mov $rnds_,$rounds
+ movups ($inp),$in0 # load inp
+
+ xorps $rndkey0,$inout0 # counter
+ $movkey 16($key_),$rndkey1
+ xorps $in0,$rndkey0
+ lea 32($key_),$key
+ xorps $rndkey0,$inout1 # cmac^=inp
+ $movkey ($key),$rndkey0
+
+.Lccm64_enc2_loop:
+ aesenc $rndkey1,$inout0
+ dec $rounds
+ aesenc $rndkey1,$inout1
+ $movkey 16($key),$rndkey1
+ aesenc $rndkey0,$inout0
+ lea 32($key),$key
+ aesenc $rndkey0,$inout1
+ $movkey 0($key),$rndkey0
+ jnz .Lccm64_enc2_loop
+ aesenc $rndkey1,$inout0
+ aesenc $rndkey1,$inout1
+ paddq $increment,$iv
+ aesenclast $rndkey0,$inout0
+ aesenclast $rndkey0,$inout1
+
+ dec $len
+ lea 16($inp),$inp
+ xorps $inout0,$in0 # inp ^= E(iv)
+ movdqa $iv,$inout0
+ movups $in0,($out) # save output
+ lea 16($out),$out
+ pshufb $bswap_mask,$inout0
+ jnz .Lccm64_enc_outer
+
+ movups $inout1,($cmac)
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp),%xmm6
+ movaps 0x10(%rsp),%xmm7
+ movaps 0x20(%rsp),%xmm8
+ movaps 0x30(%rsp),%xmm9
+ lea 0x58(%rsp),%rsp
+.Lccm64_enc_ret:
+___
+$code.=<<___;
+ ret
+.size aesni_ccm64_encrypt_blocks,.-aesni_ccm64_encrypt_blocks
+___
+######################################################################
+$code.=<<___;
+.globl aesni_ccm64_decrypt_blocks
+.type aesni_ccm64_decrypt_blocks,\@function,6
+.align 16
+aesni_ccm64_decrypt_blocks:
+___
+$code.=<<___ if ($win64);
+ lea -0x58(%rsp),%rsp
+ movaps %xmm6,(%rsp)
+ movaps %xmm7,0x10(%rsp)
+ movaps %xmm8,0x20(%rsp)
+ movaps %xmm9,0x30(%rsp)
+.Lccm64_dec_body:
+___
+$code.=<<___;
+ mov 240($key),$rounds # key->rounds
+ movups ($ivp),$iv
+ movdqu ($cmac),$inout1
+ movdqa .Lincrement64(%rip),$increment
+ movdqa .Lbswap_mask(%rip),$bswap_mask
+
+ movaps $iv,$inout0
+ mov $rounds,$rnds_
+ mov $key,$key_
+ pshufb $bswap_mask,$iv
+___
+ &aesni_generate1("enc",$key,$rounds);
+$code.=<<___;
+ movups ($inp),$in0 # load inp
+ paddq $increment,$iv
+ lea 16($inp),$inp
+ jmp .Lccm64_dec_outer
+.align 16
+.Lccm64_dec_outer:
+ xorps $inout0,$in0 # inp ^= E(iv)
+ movdqa $iv,$inout0
+ mov $rnds_,$rounds
+ movups $in0,($out) # save output
+ lea 16($out),$out
+ pshufb $bswap_mask,$inout0
+
+ sub \$1,$len
+ jz .Lccm64_dec_break
+
+ $movkey ($key_),$rndkey0
+ shr \$1,$rounds
+ $movkey 16($key_),$rndkey1
+ xorps $rndkey0,$in0
+ lea 32($key_),$key
+ xorps $rndkey0,$inout0
+ xorps $in0,$inout1 # cmac^=out
+ $movkey ($key),$rndkey0
+
+.Lccm64_dec2_loop:
+ aesenc $rndkey1,$inout0
+ dec $rounds
+ aesenc $rndkey1,$inout1
+ $movkey 16($key),$rndkey1
+ aesenc $rndkey0,$inout0
+ lea 32($key),$key
+ aesenc $rndkey0,$inout1
+ $movkey 0($key),$rndkey0
+ jnz .Lccm64_dec2_loop
+ movups ($inp),$in0 # load inp
+ paddq $increment,$iv
+ aesenc $rndkey1,$inout0
+ aesenc $rndkey1,$inout1
+ lea 16($inp),$inp
+ aesenclast $rndkey0,$inout0
+ aesenclast $rndkey0,$inout1
+ jmp .Lccm64_dec_outer
+
+.align 16
+.Lccm64_dec_break:
+ #xorps $in0,$inout1 # cmac^=out
+___
+ &aesni_generate1("enc",$key_,$rounds,$inout1,$in0);
+$code.=<<___;
+ movups $inout1,($cmac)
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp),%xmm6
+ movaps 0x10(%rsp),%xmm7
+ movaps 0x20(%rsp),%xmm8
+ movaps 0x30(%rsp),%xmm9
+ lea 0x58(%rsp),%rsp
+.Lccm64_dec_ret:
+___
+$code.=<<___;
+ ret
+.size aesni_ccm64_decrypt_blocks,.-aesni_ccm64_decrypt_blocks
+___
+}
+######################################################################
+# void aesni_ctr32_encrypt_blocks (const void *in, void *out,
+# size_t blocks, const AES_KEY *key,
+# const char *ivec);
+#
+# Handles only complete blocks, operates on 32-bit counter and
+# does not update *ivec! (see engine/eng_aesni.c for details)
+#
+{
+my $reserved = $win64?0:-0x28;
+my ($in0,$in1,$in2,$in3)=map("%xmm$_",(8..11));
+my ($iv0,$iv1,$ivec)=("%xmm12","%xmm13","%xmm14");
+my $bswap_mask="%xmm15";
+
+$code.=<<___;
+.globl aesni_ctr32_encrypt_blocks
+.type aesni_ctr32_encrypt_blocks,\@function,5
+.align 16
+aesni_ctr32_encrypt_blocks:
+___
+$code.=<<___ if ($win64);
+ lea -0xc8(%rsp),%rsp
+ movaps %xmm6,0x20(%rsp)
+ movaps %xmm7,0x30(%rsp)
+ movaps %xmm8,0x40(%rsp)
+ movaps %xmm9,0x50(%rsp)
+ movaps %xmm10,0x60(%rsp)
+ movaps %xmm11,0x70(%rsp)
+ movaps %xmm12,0x80(%rsp)
+ movaps %xmm13,0x90(%rsp)
+ movaps %xmm14,0xa0(%rsp)
+ movaps %xmm15,0xb0(%rsp)
+.Lctr32_body:
+___
+$code.=<<___;
+ cmp \$1,$len
+ je .Lctr32_one_shortcut
+
+ movdqu ($ivp),$ivec
+ movdqa .Lbswap_mask(%rip),$bswap_mask
+ xor $rounds,$rounds
+ pextrd \$3,$ivec,$rnds_ # pull 32-bit counter
+ pinsrd \$3,$rounds,$ivec # wipe 32-bit counter
+
+ mov 240($key),$rounds # key->rounds
+ bswap $rnds_
+ pxor $iv0,$iv0 # vector of 3 32-bit counters
+ pxor $iv1,$iv1 # vector of 3 32-bit counters
+ pinsrd \$0,$rnds_,$iv0
+ lea 3($rnds_),$key_
+ pinsrd \$0,$key_,$iv1
+ inc $rnds_
+ pinsrd \$1,$rnds_,$iv0
+ inc $key_
+ pinsrd \$1,$key_,$iv1
+ inc $rnds_
+ pinsrd \$2,$rnds_,$iv0
+ inc $key_
+ pinsrd \$2,$key_,$iv1
+ movdqa $iv0,$reserved(%rsp)
+ pshufb $bswap_mask,$iv0
+ movdqa $iv1,`$reserved+0x10`(%rsp)
+ pshufb $bswap_mask,$iv1
+
+ pshufd \$`3<<6`,$iv0,$inout0 # place counter to upper dword
+ pshufd \$`2<<6`,$iv0,$inout1
+ pshufd \$`1<<6`,$iv0,$inout2
+ cmp \$6,$len
+ jb .Lctr32_tail
+ shr \$1,$rounds
+ mov $key,$key_ # backup $key
+ mov $rounds,$rnds_ # backup $rounds
+ sub \$6,$len
+ jmp .Lctr32_loop6
+
+.align 16
+.Lctr32_loop6:
+ pshufd \$`3<<6`,$iv1,$inout3
+ por $ivec,$inout0 # merge counter-less ivec
+ $movkey ($key_),$rndkey0
+ pshufd \$`2<<6`,$iv1,$inout4
+ por $ivec,$inout1
+ $movkey 16($key_),$rndkey1
+ pshufd \$`1<<6`,$iv1,$inout5
+ por $ivec,$inout2
+ por $ivec,$inout3
+ xorps $rndkey0,$inout0
+ por $ivec,$inout4
+ por $ivec,$inout5
+
+ # inline _aesni_encrypt6 and interleave last rounds
+ # with own code...
+
+ pxor $rndkey0,$inout1
+ aesenc $rndkey1,$inout0
+ lea 32($key_),$key
+ pxor $rndkey0,$inout2
+ aesenc $rndkey1,$inout1
+ movdqa .Lincrement32(%rip),$iv1
+ pxor $rndkey0,$inout3
+ aesenc $rndkey1,$inout2
+ movdqa $reserved(%rsp),$iv0
+ pxor $rndkey0,$inout4
+ aesenc $rndkey1,$inout3
+ pxor $rndkey0,$inout5
+ $movkey ($key),$rndkey0
+ dec $rounds
+ aesenc $rndkey1,$inout4
+ aesenc $rndkey1,$inout5
+ jmp .Lctr32_enc_loop6_enter
+.align 16
+.Lctr32_enc_loop6:
+ aesenc $rndkey1,$inout0
+ aesenc $rndkey1,$inout1
+ dec $rounds
+ aesenc $rndkey1,$inout2
+ aesenc $rndkey1,$inout3
+ aesenc $rndkey1,$inout4
+ aesenc $rndkey1,$inout5
+.Lctr32_enc_loop6_enter:
+ $movkey 16($key),$rndkey1
+ aesenc $rndkey0,$inout0
+ aesenc $rndkey0,$inout1
+ lea 32($key),$key
+ aesenc $rndkey0,$inout2
+ aesenc $rndkey0,$inout3
+ aesenc $rndkey0,$inout4
+ aesenc $rndkey0,$inout5
+ $movkey ($key),$rndkey0
+ jnz .Lctr32_enc_loop6
+
+ aesenc $rndkey1,$inout0
+ paddd $iv1,$iv0 # increment counter vector
+ aesenc $rndkey1,$inout1
+ paddd `$reserved+0x10`(%rsp),$iv1
+ aesenc $rndkey1,$inout2
+ movdqa $iv0,$reserved(%rsp) # save counter vector
+ aesenc $rndkey1,$inout3
+ movdqa $iv1,`$reserved+0x10`(%rsp)
+ aesenc $rndkey1,$inout4
+ pshufb $bswap_mask,$iv0 # byte swap
+ aesenc $rndkey1,$inout5
+ pshufb $bswap_mask,$iv1
+
+ aesenclast $rndkey0,$inout0
+ movups ($inp),$in0 # load input
+ aesenclast $rndkey0,$inout1
+ movups 0x10($inp),$in1
+ aesenclast $rndkey0,$inout2
+ movups 0x20($inp),$in2
+ aesenclast $rndkey0,$inout3
+ movups 0x30($inp),$in3
+ aesenclast $rndkey0,$inout4
+ movups 0x40($inp),$rndkey1
+ aesenclast $rndkey0,$inout5
+ movups 0x50($inp),$rndkey0
+ lea 0x60($inp),$inp
+
+ xorps $inout0,$in0 # xor
+ pshufd \$`3<<6`,$iv0,$inout0
+ xorps $inout1,$in1
+ pshufd \$`2<<6`,$iv0,$inout1
+ movups $in0,($out) # store output
+ xorps $inout2,$in2
+ pshufd \$`1<<6`,$iv0,$inout2
+ movups $in1,0x10($out)
+ xorps $inout3,$in3
+ movups $in2,0x20($out)
+ xorps $inout4,$rndkey1
+ movups $in3,0x30($out)
+ xorps $inout5,$rndkey0
+ movups $rndkey1,0x40($out)
+ movups $rndkey0,0x50($out)
+ lea 0x60($out),$out
+ mov $rnds_,$rounds
+ sub \$6,$len
+ jnc .Lctr32_loop6
+
+ add \$6,$len
+ jz .Lctr32_done
+ mov $key_,$key # restore $key
+ lea 1($rounds,$rounds),$rounds # restore original value
+
+.Lctr32_tail:
+ por $ivec,$inout0
+ movups ($inp),$in0
+ cmp \$2,$len
+ jb .Lctr32_one
+
+ por $ivec,$inout1
+ movups 0x10($inp),$in1
+ je .Lctr32_two
+
+ pshufd \$`3<<6`,$iv1,$inout3
+ por $ivec,$inout2
+ movups 0x20($inp),$in2
+ cmp \$4,$len
+ jb .Lctr32_three
+
+ pshufd \$`2<<6`,$iv1,$inout4
+ por $ivec,$inout3
+ movups 0x30($inp),$in3
+ je .Lctr32_four
+
+ por $ivec,$inout4
+ xorps $inout5,$inout5
+
+ call _aesni_encrypt6
+
+ movups 0x40($inp),$rndkey1
+ xorps $inout0,$in0
+ xorps $inout1,$in1
+ movups $in0,($out)
+ xorps $inout2,$in2
+ movups $in1,0x10($out)
+ xorps $inout3,$in3
+ movups $in2,0x20($out)
+ xorps $inout4,$rndkey1
+ movups $in3,0x30($out)
+ movups $rndkey1,0x40($out)
+ jmp .Lctr32_done
+
+.align 16
+.Lctr32_one_shortcut:
+ movups ($ivp),$inout0
+ movups ($inp),$in0
+ mov 240($key),$rounds # key->rounds
+.Lctr32_one:
+___
+ &aesni_generate1("enc",$key,$rounds);
+$code.=<<___;
+ xorps $inout0,$in0
+ movups $in0,($out)
+ jmp .Lctr32_done
+
+.align 16
+.Lctr32_two:
+ xorps $inout2,$inout2
+ call _aesni_encrypt3
+ xorps $inout0,$in0
+ xorps $inout1,$in1
+ movups $in0,($out)
+ movups $in1,0x10($out)
+ jmp .Lctr32_done
+
+.align 16
+.Lctr32_three:
+ call _aesni_encrypt3
+ xorps $inout0,$in0
+ xorps $inout1,$in1
+ movups $in0,($out)
+ xorps $inout2,$in2
+ movups $in1,0x10($out)
+ movups $in2,0x20($out)
+ jmp .Lctr32_done
+
+.align 16
+.Lctr32_four:
+ call _aesni_encrypt4
+ xorps $inout0,$in0
+ xorps $inout1,$in1
+ movups $in0,($out)
+ xorps $inout2,$in2
+ movups $in1,0x10($out)
+ xorps $inout3,$in3
+ movups $in2,0x20($out)
+ movups $in3,0x30($out)
+
+.Lctr32_done:
+___
+$code.=<<___ if ($win64);
+ movaps 0x20(%rsp),%xmm6
+ movaps 0x30(%rsp),%xmm7
+ movaps 0x40(%rsp),%xmm8
+ movaps 0x50(%rsp),%xmm9
+ movaps 0x60(%rsp),%xmm10
+ movaps 0x70(%rsp),%xmm11
+ movaps 0x80(%rsp),%xmm12
+ movaps 0x90(%rsp),%xmm13
+ movaps 0xa0(%rsp),%xmm14
+ movaps 0xb0(%rsp),%xmm15
+ lea 0xc8(%rsp),%rsp
+.Lctr32_ret:
+___
+$code.=<<___;
+ ret
+.size aesni_ctr32_encrypt_blocks,.-aesni_ctr32_encrypt_blocks
+___
+}
+
+######################################################################
+# void aesni_xts_[en|de]crypt(const char *inp,char *out,size_t len,
+# const AES_KEY *key1, const AES_KEY *key2
+# const unsigned char iv[16]);
+#
+{
+my @tweak=map("%xmm$_",(10..15));
+my ($twmask,$twres,$twtmp)=("%xmm8","%xmm9",@tweak[4]);
+my ($key2,$ivp,$len_)=("%r8","%r9","%r9");
+my $frame_size = 0x68 + ($win64?160:0);
+
+$code.=<<___;
+.globl aesni_xts_encrypt
+.type aesni_xts_encrypt,\@function,6
+.align 16
+aesni_xts_encrypt:
+ lea -$frame_size(%rsp),%rsp
+___
+$code.=<<___ if ($win64);
+ movaps %xmm6,0x60(%rsp)
+ movaps %xmm7,0x70(%rsp)
+ movaps %xmm8,0x80(%rsp)
+ movaps %xmm9,0x90(%rsp)
+ movaps %xmm10,0xa0(%rsp)
+ movaps %xmm11,0xb0(%rsp)
+ movaps %xmm12,0xc0(%rsp)
+ movaps %xmm13,0xd0(%rsp)
+ movaps %xmm14,0xe0(%rsp)
+ movaps %xmm15,0xf0(%rsp)
+.Lxts_enc_body:
+___
+$code.=<<___;
+ movups ($ivp),@tweak[5] # load clear-text tweak
+ mov 240(%r8),$rounds # key2->rounds
+ mov 240($key),$rnds_ # key1->rounds
+___
+ # generate the tweak
+ &aesni_generate1("enc",$key2,$rounds,@tweak[5]);
+$code.=<<___;
+ mov $key,$key_ # backup $key
+ mov $rnds_,$rounds # backup $rounds
+ mov $len,$len_ # backup $len
+ and \$-16,$len
+
+ movdqa .Lxts_magic(%rip),$twmask
+ pxor $twtmp,$twtmp
+ pcmpgtd @tweak[5],$twtmp # broadcast upper bits
+___
+ for ($i=0;$i<4;$i++) {
+ $code.=<<___;
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ movdqa @tweak[5],@tweak[$i]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ pand $twmask,$twres # isolate carry and residue
+ pcmpgtd @tweak[5],$twtmp # broadcat upper bits
+ pxor $twres,@tweak[5]
+___
+ }
+$code.=<<___;
+ sub \$16*6,$len
+ jc .Lxts_enc_short
+
+ shr \$1,$rounds
+ sub \$1,$rounds
+ mov $rounds,$rnds_
+ jmp .Lxts_enc_grandloop
+
+.align 16
+.Lxts_enc_grandloop:
+ pshufd \$0x13,$twtmp,$twres
+ movdqa @tweak[5],@tweak[4]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ movdqu `16*0`($inp),$inout0 # load input
+ pand $twmask,$twres # isolate carry and residue
+ movdqu `16*1`($inp),$inout1
+ pxor $twres,@tweak[5]
+
+ movdqu `16*2`($inp),$inout2
+ pxor @tweak[0],$inout0 # input^=tweak
+ movdqu `16*3`($inp),$inout3
+ pxor @tweak[1],$inout1
+ movdqu `16*4`($inp),$inout4
+ pxor @tweak[2],$inout2
+ movdqu `16*5`($inp),$inout5
+ lea `16*6`($inp),$inp
+ pxor @tweak[3],$inout3
+ $movkey ($key_),$rndkey0
+ pxor @tweak[4],$inout4
+ pxor @tweak[5],$inout5
+
+ # inline _aesni_encrypt6 and interleave first and last rounds
+ # with own code...
+ $movkey 16($key_),$rndkey1
+ pxor $rndkey0,$inout0
+ pxor $rndkey0,$inout1
+ movdqa @tweak[0],`16*0`(%rsp) # put aside tweaks
+ aesenc $rndkey1,$inout0
+ lea 32($key_),$key
+ pxor $rndkey0,$inout2
+ movdqa @tweak[1],`16*1`(%rsp)
+ aesenc $rndkey1,$inout1
+ pxor $rndkey0,$inout3
+ movdqa @tweak[2],`16*2`(%rsp)
+ aesenc $rndkey1,$inout2
+ pxor $rndkey0,$inout4
+ movdqa @tweak[3],`16*3`(%rsp)
+ aesenc $rndkey1,$inout3
+ pxor $rndkey0,$inout5
+ $movkey ($key),$rndkey0
+ dec $rounds
+ movdqa @tweak[4],`16*4`(%rsp)
+ aesenc $rndkey1,$inout4
+ movdqa @tweak[5],`16*5`(%rsp)
+ aesenc $rndkey1,$inout5
+ pxor $twtmp,$twtmp
+ pcmpgtd @tweak[5],$twtmp
+ jmp .Lxts_enc_loop6_enter
+
+.align 16
+.Lxts_enc_loop6:
+ aesenc $rndkey1,$inout0
+ aesenc $rndkey1,$inout1
+ dec $rounds
+ aesenc $rndkey1,$inout2
+ aesenc $rndkey1,$inout3
+ aesenc $rndkey1,$inout4
+ aesenc $rndkey1,$inout5
+.Lxts_enc_loop6_enter:
+ $movkey 16($key),$rndkey1
+ aesenc $rndkey0,$inout0
+ aesenc $rndkey0,$inout1
+ lea 32($key),$key
+ aesenc $rndkey0,$inout2
+ aesenc $rndkey0,$inout3
+ aesenc $rndkey0,$inout4
+ aesenc $rndkey0,$inout5
+ $movkey ($key),$rndkey0
+ jnz .Lxts_enc_loop6
+
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ aesenc $rndkey1,$inout0
+ pand $twmask,$twres # isolate carry and residue
+ aesenc $rndkey1,$inout1
+ pcmpgtd @tweak[5],$twtmp # broadcast upper bits
+ aesenc $rndkey1,$inout2
+ pxor $twres,@tweak[5]
+ aesenc $rndkey1,$inout3
+ aesenc $rndkey1,$inout4
+ aesenc $rndkey1,$inout5
+ $movkey 16($key),$rndkey1
+
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ movdqa @tweak[5],@tweak[0]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ aesenc $rndkey0,$inout0
+ pand $twmask,$twres # isolate carry and residue
+ aesenc $rndkey0,$inout1
+ pcmpgtd @tweak[5],$twtmp # broadcat upper bits
+ aesenc $rndkey0,$inout2
+ pxor $twres,@tweak[5]
+ aesenc $rndkey0,$inout3
+ aesenc $rndkey0,$inout4
+ aesenc $rndkey0,$inout5
+ $movkey 32($key),$rndkey0
+
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ movdqa @tweak[5],@tweak[1]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ aesenc $rndkey1,$inout0
+ pand $twmask,$twres # isolate carry and residue
+ aesenc $rndkey1,$inout1
+ pcmpgtd @tweak[5],$twtmp # broadcat upper bits
+ aesenc $rndkey1,$inout2
+ pxor $twres,@tweak[5]
+ aesenc $rndkey1,$inout3
+ aesenc $rndkey1,$inout4
+ aesenc $rndkey1,$inout5
+
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ movdqa @tweak[5],@tweak[2]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ aesenclast $rndkey0,$inout0
+ pand $twmask,$twres # isolate carry and residue
+ aesenclast $rndkey0,$inout1
+ pcmpgtd @tweak[5],$twtmp # broadcat upper bits
+ aesenclast $rndkey0,$inout2
+ pxor $twres,@tweak[5]
+ aesenclast $rndkey0,$inout3
+ aesenclast $rndkey0,$inout4
+ aesenclast $rndkey0,$inout5
+
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ movdqa @tweak[5],@tweak[3]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ xorps `16*0`(%rsp),$inout0 # output^=tweak
+ pand $twmask,$twres # isolate carry and residue
+ xorps `16*1`(%rsp),$inout1
+ pcmpgtd @tweak[5],$twtmp # broadcat upper bits
+ pxor $twres,@tweak[5]
+
+ xorps `16*2`(%rsp),$inout2
+ movups $inout0,`16*0`($out) # write output
+ xorps `16*3`(%rsp),$inout3
+ movups $inout1,`16*1`($out)
+ xorps `16*4`(%rsp),$inout4
+ movups $inout2,`16*2`($out)
+ xorps `16*5`(%rsp),$inout5
+ movups $inout3,`16*3`($out)
+ mov $rnds_,$rounds # restore $rounds
+ movups $inout4,`16*4`($out)
+ movups $inout5,`16*5`($out)
+ lea `16*6`($out),$out
+ sub \$16*6,$len
+ jnc .Lxts_enc_grandloop
+
+ lea 3($rounds,$rounds),$rounds # restore original value
+ mov $key_,$key # restore $key
+ mov $rounds,$rnds_ # backup $rounds
+
+.Lxts_enc_short:
+ add \$16*6,$len
+ jz .Lxts_enc_done
+
+ cmp \$0x20,$len
+ jb .Lxts_enc_one
+ je .Lxts_enc_two
+
+ cmp \$0x40,$len
+ jb .Lxts_enc_three
+ je .Lxts_enc_four
+
+ pshufd \$0x13,$twtmp,$twres
+ movdqa @tweak[5],@tweak[4]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ movdqu ($inp),$inout0
+ pand $twmask,$twres # isolate carry and residue
+ movdqu 16*1($inp),$inout1
+ pxor $twres,@tweak[5]
+
+ movdqu 16*2($inp),$inout2
+ pxor @tweak[0],$inout0
+ movdqu 16*3($inp),$inout3
+ pxor @tweak[1],$inout1
+ movdqu 16*4($inp),$inout4
+ lea 16*5($inp),$inp
+ pxor @tweak[2],$inout2
+ pxor @tweak[3],$inout3
+ pxor @tweak[4],$inout4
+
+ call _aesni_encrypt6
+
+ xorps @tweak[0],$inout0
+ movdqa @tweak[5],@tweak[0]
+ xorps @tweak[1],$inout1
+ xorps @tweak[2],$inout2
+ movdqu $inout0,($out)
+ xorps @tweak[3],$inout3
+ movdqu $inout1,16*1($out)
+ xorps @tweak[4],$inout4
+ movdqu $inout2,16*2($out)
+ movdqu $inout3,16*3($out)
+ movdqu $inout4,16*4($out)
+ lea 16*5($out),$out
+ jmp .Lxts_enc_done
+
+.align 16
+.Lxts_enc_one:
+ movups ($inp),$inout0
+ lea 16*1($inp),$inp
+ xorps @tweak[0],$inout0
+___
+ &aesni_generate1("enc",$key,$rounds);
+$code.=<<___;
+ xorps @tweak[0],$inout0
+ movdqa @tweak[1],@tweak[0]
+ movups $inout0,($out)
+ lea 16*1($out),$out
+ jmp .Lxts_enc_done
+
+.align 16
+.Lxts_enc_two:
+ movups ($inp),$inout0
+ movups 16($inp),$inout1
+ lea 32($inp),$inp
+ xorps @tweak[0],$inout0
+ xorps @tweak[1],$inout1
+
+ call _aesni_encrypt3
+
+ xorps @tweak[0],$inout0
+ movdqa @tweak[2],@tweak[0]
+ xorps @tweak[1],$inout1
+ movups $inout0,($out)
+ movups $inout1,16*1($out)
+ lea 16*2($out),$out
+ jmp .Lxts_enc_done
+
+.align 16
+.Lxts_enc_three:
+ movups ($inp),$inout0
+ movups 16*1($inp),$inout1
+ movups 16*2($inp),$inout2
+ lea 16*3($inp),$inp
+ xorps @tweak[0],$inout0
+ xorps @tweak[1],$inout1
+ xorps @tweak[2],$inout2
+
+ call _aesni_encrypt3
+
+ xorps @tweak[0],$inout0
+ movdqa @tweak[3],@tweak[0]
+ xorps @tweak[1],$inout1
+ xorps @tweak[2],$inout2
+ movups $inout0,($out)
+ movups $inout1,16*1($out)
+ movups $inout2,16*2($out)
+ lea 16*3($out),$out
+ jmp .Lxts_enc_done
+
+.align 16
+.Lxts_enc_four:
+ movups ($inp),$inout0
+ movups 16*1($inp),$inout1
+ movups 16*2($inp),$inout2
+ xorps @tweak[0],$inout0
+ movups 16*3($inp),$inout3
+ lea 16*4($inp),$inp
+ xorps @tweak[1],$inout1
+ xorps @tweak[2],$inout2
+ xorps @tweak[3],$inout3
+
+ call _aesni_encrypt4
+
+ xorps @tweak[0],$inout0
+ movdqa @tweak[5],@tweak[0]
+ xorps @tweak[1],$inout1
+ xorps @tweak[2],$inout2
+ movups $inout0,($out)
+ xorps @tweak[3],$inout3
+ movups $inout1,16*1($out)
+ movups $inout2,16*2($out)
+ movups $inout3,16*3($out)
+ lea 16*4($out),$out
+ jmp .Lxts_enc_done
+
+.align 16
+.Lxts_enc_done:
+ and \$15,$len_
+ jz .Lxts_enc_ret
+ mov $len_,$len
+
+.Lxts_enc_steal:
+ movzb ($inp),%eax # borrow $rounds ...
+ movzb -16($out),%ecx # ... and $key
+ lea 1($inp),$inp
+ mov %al,-16($out)
+ mov %cl,0($out)
+ lea 1($out),$out
+ sub \$1,$len
+ jnz .Lxts_enc_steal
+
+ sub $len_,$out # rewind $out
+ mov $key_,$key # restore $key
+ mov $rnds_,$rounds # restore $rounds
+
+ movups -16($out),$inout0
+ xorps @tweak[0],$inout0
+___
+ &aesni_generate1("enc",$key,$rounds);
+$code.=<<___;
+ xorps @tweak[0],$inout0
+ movups $inout0,-16($out)
+
+.Lxts_enc_ret:
+___
+$code.=<<___ if ($win64);
+ movaps 0x60(%rsp),%xmm6
+ movaps 0x70(%rsp),%xmm7
+ movaps 0x80(%rsp),%xmm8
+ movaps 0x90(%rsp),%xmm9
+ movaps 0xa0(%rsp),%xmm10
+ movaps 0xb0(%rsp),%xmm11
+ movaps 0xc0(%rsp),%xmm12
+ movaps 0xd0(%rsp),%xmm13
+ movaps 0xe0(%rsp),%xmm14
+ movaps 0xf0(%rsp),%xmm15
+___
+$code.=<<___;
+ lea $frame_size(%rsp),%rsp
+.Lxts_enc_epilogue:
+ ret
+.size aesni_xts_encrypt,.-aesni_xts_encrypt
+___
+
+$code.=<<___;
+.globl aesni_xts_decrypt
+.type aesni_xts_decrypt,\@function,6
+.align 16
+aesni_xts_decrypt:
+ lea -$frame_size(%rsp),%rsp
+___
+$code.=<<___ if ($win64);
+ movaps %xmm6,0x60(%rsp)
+ movaps %xmm7,0x70(%rsp)
+ movaps %xmm8,0x80(%rsp)
+ movaps %xmm9,0x90(%rsp)
+ movaps %xmm10,0xa0(%rsp)
+ movaps %xmm11,0xb0(%rsp)
+ movaps %xmm12,0xc0(%rsp)
+ movaps %xmm13,0xd0(%rsp)
+ movaps %xmm14,0xe0(%rsp)
+ movaps %xmm15,0xf0(%rsp)
+.Lxts_dec_body:
+___
+$code.=<<___;
+ movups ($ivp),@tweak[5] # load clear-text tweak
+ mov 240($key2),$rounds # key2->rounds
+ mov 240($key),$rnds_ # key1->rounds
+___
+ # generate the tweak
+ &aesni_generate1("enc",$key2,$rounds,@tweak[5]);
+$code.=<<___;
+ xor %eax,%eax # if ($len%16) len-=16;
+ test \$15,$len
+ setnz %al
+ shl \$4,%rax
+ sub %rax,$len
+
+ mov $key,$key_ # backup $key
+ mov $rnds_,$rounds # backup $rounds
+ mov $len,$len_ # backup $len
+ and \$-16,$len
+
+ movdqa .Lxts_magic(%rip),$twmask
+ pxor $twtmp,$twtmp
+ pcmpgtd @tweak[5],$twtmp # broadcast upper bits
+___
+ for ($i=0;$i<4;$i++) {
+ $code.=<<___;
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ movdqa @tweak[5],@tweak[$i]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ pand $twmask,$twres # isolate carry and residue
+ pcmpgtd @tweak[5],$twtmp # broadcat upper bits
+ pxor $twres,@tweak[5]
+___
+ }
+$code.=<<___;
+ sub \$16*6,$len
+ jc .Lxts_dec_short
+
+ shr \$1,$rounds
+ sub \$1,$rounds
+ mov $rounds,$rnds_
+ jmp .Lxts_dec_grandloop
+
+.align 16
+.Lxts_dec_grandloop:
+ pshufd \$0x13,$twtmp,$twres
+ movdqa @tweak[5],@tweak[4]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ movdqu `16*0`($inp),$inout0 # load input
+ pand $twmask,$twres # isolate carry and residue
+ movdqu `16*1`($inp),$inout1
+ pxor $twres,@tweak[5]
+
+ movdqu `16*2`($inp),$inout2
+ pxor @tweak[0],$inout0 # input^=tweak
+ movdqu `16*3`($inp),$inout3
+ pxor @tweak[1],$inout1
+ movdqu `16*4`($inp),$inout4
+ pxor @tweak[2],$inout2
+ movdqu `16*5`($inp),$inout5
+ lea `16*6`($inp),$inp
+ pxor @tweak[3],$inout3
+ $movkey ($key_),$rndkey0
+ pxor @tweak[4],$inout4
+ pxor @tweak[5],$inout5
+
+ # inline _aesni_decrypt6 and interleave first and last rounds
+ # with own code...
+ $movkey 16($key_),$rndkey1
+ pxor $rndkey0,$inout0
+ pxor $rndkey0,$inout1
+ movdqa @tweak[0],`16*0`(%rsp) # put aside tweaks
+ aesdec $rndkey1,$inout0
+ lea 32($key_),$key
+ pxor $rndkey0,$inout2
+ movdqa @tweak[1],`16*1`(%rsp)
+ aesdec $rndkey1,$inout1
+ pxor $rndkey0,$inout3
+ movdqa @tweak[2],`16*2`(%rsp)
+ aesdec $rndkey1,$inout2
+ pxor $rndkey0,$inout4
+ movdqa @tweak[3],`16*3`(%rsp)
+ aesdec $rndkey1,$inout3
+ pxor $rndkey0,$inout5
+ $movkey ($key),$rndkey0
+ dec $rounds
+ movdqa @tweak[4],`16*4`(%rsp)
+ aesdec $rndkey1,$inout4
+ movdqa @tweak[5],`16*5`(%rsp)
+ aesdec $rndkey1,$inout5
+ pxor $twtmp,$twtmp
+ pcmpgtd @tweak[5],$twtmp
+ jmp .Lxts_dec_loop6_enter
+
+.align 16
+.Lxts_dec_loop6:
+ aesdec $rndkey1,$inout0
+ aesdec $rndkey1,$inout1
+ dec $rounds
+ aesdec $rndkey1,$inout2
+ aesdec $rndkey1,$inout3
+ aesdec $rndkey1,$inout4
+ aesdec $rndkey1,$inout5
+.Lxts_dec_loop6_enter:
+ $movkey 16($key),$rndkey1
+ aesdec $rndkey0,$inout0
+ aesdec $rndkey0,$inout1
+ lea 32($key),$key
+ aesdec $rndkey0,$inout2
+ aesdec $rndkey0,$inout3
+ aesdec $rndkey0,$inout4
+ aesdec $rndkey0,$inout5
+ $movkey ($key),$rndkey0
+ jnz .Lxts_dec_loop6
+
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ aesdec $rndkey1,$inout0
+ pand $twmask,$twres # isolate carry and residue
+ aesdec $rndkey1,$inout1
+ pcmpgtd @tweak[5],$twtmp # broadcast upper bits
+ aesdec $rndkey1,$inout2
+ pxor $twres,@tweak[5]
+ aesdec $rndkey1,$inout3
+ aesdec $rndkey1,$inout4
+ aesdec $rndkey1,$inout5
+ $movkey 16($key),$rndkey1
+
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ movdqa @tweak[5],@tweak[0]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ aesdec $rndkey0,$inout0
+ pand $twmask,$twres # isolate carry and residue
+ aesdec $rndkey0,$inout1
+ pcmpgtd @tweak[5],$twtmp # broadcat upper bits
+ aesdec $rndkey0,$inout2
+ pxor $twres,@tweak[5]
+ aesdec $rndkey0,$inout3
+ aesdec $rndkey0,$inout4
+ aesdec $rndkey0,$inout5
+ $movkey 32($key),$rndkey0
+
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ movdqa @tweak[5],@tweak[1]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ aesdec $rndkey1,$inout0
+ pand $twmask,$twres # isolate carry and residue
+ aesdec $rndkey1,$inout1
+ pcmpgtd @tweak[5],$twtmp # broadcat upper bits
+ aesdec $rndkey1,$inout2
+ pxor $twres,@tweak[5]
+ aesdec $rndkey1,$inout3
+ aesdec $rndkey1,$inout4
+ aesdec $rndkey1,$inout5
+
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ movdqa @tweak[5],@tweak[2]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ aesdeclast $rndkey0,$inout0
+ pand $twmask,$twres # isolate carry and residue
+ aesdeclast $rndkey0,$inout1
+ pcmpgtd @tweak[5],$twtmp # broadcat upper bits
+ aesdeclast $rndkey0,$inout2
+ pxor $twres,@tweak[5]
+ aesdeclast $rndkey0,$inout3
+ aesdeclast $rndkey0,$inout4
+ aesdeclast $rndkey0,$inout5
+
+ pshufd \$0x13,$twtmp,$twres
+ pxor $twtmp,$twtmp
+ movdqa @tweak[5],@tweak[3]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ xorps `16*0`(%rsp),$inout0 # output^=tweak
+ pand $twmask,$twres # isolate carry and residue
+ xorps `16*1`(%rsp),$inout1
+ pcmpgtd @tweak[5],$twtmp # broadcat upper bits
+ pxor $twres,@tweak[5]
+
+ xorps `16*2`(%rsp),$inout2
+ movups $inout0,`16*0`($out) # write output
+ xorps `16*3`(%rsp),$inout3
+ movups $inout1,`16*1`($out)
+ xorps `16*4`(%rsp),$inout4
+ movups $inout2,`16*2`($out)
+ xorps `16*5`(%rsp),$inout5
+ movups $inout3,`16*3`($out)
+ mov $rnds_,$rounds # restore $rounds
+ movups $inout4,`16*4`($out)
+ movups $inout5,`16*5`($out)
+ lea `16*6`($out),$out
+ sub \$16*6,$len
+ jnc .Lxts_dec_grandloop
+
+ lea 3($rounds,$rounds),$rounds # restore original value
+ mov $key_,$key # restore $key
+ mov $rounds,$rnds_ # backup $rounds
+
+.Lxts_dec_short:
+ add \$16*6,$len
+ jz .Lxts_dec_done
+
+ cmp \$0x20,$len
+ jb .Lxts_dec_one
+ je .Lxts_dec_two
+
+ cmp \$0x40,$len
+ jb .Lxts_dec_three
+ je .Lxts_dec_four
+
+ pshufd \$0x13,$twtmp,$twres
+ movdqa @tweak[5],@tweak[4]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ movdqu ($inp),$inout0
+ pand $twmask,$twres # isolate carry and residue
+ movdqu 16*1($inp),$inout1
+ pxor $twres,@tweak[5]
+
+ movdqu 16*2($inp),$inout2
+ pxor @tweak[0],$inout0
+ movdqu 16*3($inp),$inout3
+ pxor @tweak[1],$inout1
+ movdqu 16*4($inp),$inout4
+ lea 16*5($inp),$inp
+ pxor @tweak[2],$inout2
+ pxor @tweak[3],$inout3
+ pxor @tweak[4],$inout4
+
+ call _aesni_decrypt6
+
+ xorps @tweak[0],$inout0
+ xorps @tweak[1],$inout1
+ xorps @tweak[2],$inout2
+ movdqu $inout0,($out)
+ xorps @tweak[3],$inout3
+ movdqu $inout1,16*1($out)
+ xorps @tweak[4],$inout4
+ movdqu $inout2,16*2($out)
+ pxor $twtmp,$twtmp
+ movdqu $inout3,16*3($out)
+ pcmpgtd @tweak[5],$twtmp
+ movdqu $inout4,16*4($out)
+ lea 16*5($out),$out
+ pshufd \$0x13,$twtmp,@tweak[1] # $twres
+ and \$15,$len_
+ jz .Lxts_dec_ret
+
+ movdqa @tweak[5],@tweak[0]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ pand $twmask,@tweak[1] # isolate carry and residue
+ pxor @tweak[5],@tweak[1]
+ jmp .Lxts_dec_done2
+
+.align 16
+.Lxts_dec_one:
+ movups ($inp),$inout0
+ lea 16*1($inp),$inp
+ xorps @tweak[0],$inout0
+___
+ &aesni_generate1("dec",$key,$rounds);
+$code.=<<___;
+ xorps @tweak[0],$inout0
+ movdqa @tweak[1],@tweak[0]
+ movups $inout0,($out)
+ movdqa @tweak[2],@tweak[1]
+ lea 16*1($out),$out
+ jmp .Lxts_dec_done
+
+.align 16
+.Lxts_dec_two:
+ movups ($inp),$inout0
+ movups 16($inp),$inout1
+ lea 32($inp),$inp
+ xorps @tweak[0],$inout0
+ xorps @tweak[1],$inout1
+
+ call _aesni_decrypt3
+
+ xorps @tweak[0],$inout0
+ movdqa @tweak[2],@tweak[0]
+ xorps @tweak[1],$inout1
+ movdqa @tweak[3],@tweak[1]
+ movups $inout0,($out)
+ movups $inout1,16*1($out)
+ lea 16*2($out),$out
+ jmp .Lxts_dec_done
+
+.align 16
+.Lxts_dec_three:
+ movups ($inp),$inout0
+ movups 16*1($inp),$inout1
+ movups 16*2($inp),$inout2
+ lea 16*3($inp),$inp
+ xorps @tweak[0],$inout0
+ xorps @tweak[1],$inout1
+ xorps @tweak[2],$inout2
+
+ call _aesni_decrypt3
+
+ xorps @tweak[0],$inout0
+ movdqa @tweak[3],@tweak[0]
+ xorps @tweak[1],$inout1
+ movdqa @tweak[5],@tweak[1]
+ xorps @tweak[2],$inout2
+ movups $inout0,($out)
+ movups $inout1,16*1($out)
+ movups $inout2,16*2($out)
+ lea 16*3($out),$out
+ jmp .Lxts_dec_done
+
+.align 16
+.Lxts_dec_four:
+ pshufd \$0x13,$twtmp,$twres
+ movdqa @tweak[5],@tweak[4]
+ paddq @tweak[5],@tweak[5] # psllq 1,$tweak
+ movups ($inp),$inout0
+ pand $twmask,$twres # isolate carry and residue
+ movups 16*1($inp),$inout1
+ pxor $twres,@tweak[5]
+
+ movups 16*2($inp),$inout2
+ xorps @tweak[0],$inout0
+ movups 16*3($inp),$inout3
+ lea 16*4($inp),$inp
+ xorps @tweak[1],$inout1
+ xorps @tweak[2],$inout2
+ xorps @tweak[3],$inout3
+
+ call _aesni_decrypt4
+
+ xorps @tweak[0],$inout0
+ movdqa @tweak[4],@tweak[0]
+ xorps @tweak[1],$inout1
+ movdqa @tweak[5],@tweak[1]
+ xorps @tweak[2],$inout2
+ movups $inout0,($out)
+ xorps @tweak[3],$inout3
+ movups $inout1,16*1($out)
+ movups $inout2,16*2($out)
+ movups $inout3,16*3($out)
+ lea 16*4($out),$out
+ jmp .Lxts_dec_done
+
+.align 16
+.Lxts_dec_done:
+ and \$15,$len_
+ jz .Lxts_dec_ret
+.Lxts_dec_done2:
+ mov $len_,$len
+ mov $key_,$key # restore $key
+ mov $rnds_,$rounds # restore $rounds
+
+ movups ($inp),$inout0
+ xorps @tweak[1],$inout0
+___
+ &aesni_generate1("dec",$key,$rounds);
+$code.=<<___;
+ xorps @tweak[1],$inout0
+ movups $inout0,($out)
+
+.Lxts_dec_steal:
+ movzb 16($inp),%eax # borrow $rounds ...
+ movzb ($out),%ecx # ... and $key
+ lea 1($inp),$inp
+ mov %al,($out)
+ mov %cl,16($out)
+ lea 1($out),$out
+ sub \$1,$len
+ jnz .Lxts_dec_steal
+
+ sub $len_,$out # rewind $out
+ mov $key_,$key # restore $key
+ mov $rnds_,$rounds # restore $rounds
+
+ movups ($out),$inout0
+ xorps @tweak[0],$inout0
+___
+ &aesni_generate1("dec",$key,$rounds);
+$code.=<<___;
+ xorps @tweak[0],$inout0
+ movups $inout0,($out)
+
+.Lxts_dec_ret:
+___
+$code.=<<___ if ($win64);
+ movaps 0x60(%rsp),%xmm6
+ movaps 0x70(%rsp),%xmm7
+ movaps 0x80(%rsp),%xmm8
+ movaps 0x90(%rsp),%xmm9
+ movaps 0xa0(%rsp),%xmm10
+ movaps 0xb0(%rsp),%xmm11
+ movaps 0xc0(%rsp),%xmm12
+ movaps 0xd0(%rsp),%xmm13
+ movaps 0xe0(%rsp),%xmm14
+ movaps 0xf0(%rsp),%xmm15
+___
+$code.=<<___;
+ lea $frame_size(%rsp),%rsp
+.Lxts_dec_epilogue:
+ ret
+.size aesni_xts_decrypt,.-aesni_xts_decrypt
+___
+} }}
+
+########################################################################
+# void $PREFIX_cbc_encrypt (const void *inp, void *out,
+# size_t length, const AES_KEY *key,
+# unsigned char *ivp,const int enc);
+{
+my $reserved = $win64?0x40:-0x18; # used in decrypt
+$code.=<<___;
+.globl ${PREFIX}_cbc_encrypt
+.type ${PREFIX}_cbc_encrypt,\@function,6
+.align 16
+${PREFIX}_cbc_encrypt:
+ test $len,$len # check length
+ jz .Lcbc_ret
+
+ mov 240($key),$rnds_ # key->rounds
+ mov $key,$key_ # backup $key
+ test %r9d,%r9d # 6th argument
+ jz .Lcbc_decrypt
+#--------------------------- CBC ENCRYPT ------------------------------#
+ movups ($ivp),$inout0 # load iv as initial state
+ mov $rnds_,$rounds
+ cmp \$16,$len
+ jb .Lcbc_enc_tail
+ sub \$16,$len
+ jmp .Lcbc_enc_loop
+.align 16
+.Lcbc_enc_loop:
+ movups ($inp),$inout1 # load input
+ lea 16($inp),$inp
+ #xorps $inout1,$inout0
+___
+ &aesni_generate1("enc",$key,$rounds,$inout0,$inout1);
+$code.=<<___;
+ mov $rnds_,$rounds # restore $rounds
+ mov $key_,$key # restore $key
+ movups $inout0,0($out) # store output
+ lea 16($out),$out
+ sub \$16,$len
+ jnc .Lcbc_enc_loop
+ add \$16,$len
+ jnz .Lcbc_enc_tail
+ movups $inout0,($ivp)
+ jmp .Lcbc_ret
+
+.Lcbc_enc_tail:
+ mov $len,%rcx # zaps $key
+ xchg $inp,$out # $inp is %rsi and $out is %rdi now
+ .long 0x9066A4F3 # rep movsb
+ mov \$16,%ecx # zero tail
+ sub $len,%rcx
+ xor %eax,%eax
+ .long 0x9066AAF3 # rep stosb
+ lea -16(%rdi),%rdi # rewind $out by 1 block
+ mov $rnds_,$rounds # restore $rounds
+ mov %rdi,%rsi # $inp and $out are the same
+ mov $key_,$key # restore $key
+ xor $len,$len # len=16
+ jmp .Lcbc_enc_loop # one more spin
+ #--------------------------- CBC DECRYPT ------------------------------#
+.align 16
+.Lcbc_decrypt:
+___
+$code.=<<___ if ($win64);
+ lea -0x58(%rsp),%rsp
+ movaps %xmm6,(%rsp)
+ movaps %xmm7,0x10(%rsp)
+ movaps %xmm8,0x20(%rsp)
+ movaps %xmm9,0x30(%rsp)
+.Lcbc_decrypt_body:
+___
+$code.=<<___;
+ movups ($ivp),$iv
+ mov $rnds_,$rounds
+ cmp \$0x70,$len
+ jbe .Lcbc_dec_tail
+ shr \$1,$rnds_
+ sub \$0x70,$len
+ mov $rnds_,$rounds
+ movaps $iv,$reserved(%rsp)
+ jmp .Lcbc_dec_loop8_enter
+.align 16
+.Lcbc_dec_loop8:
+ movaps $rndkey0,$reserved(%rsp) # save IV
+ movups $inout7,($out)
+ lea 0x10($out),$out
+.Lcbc_dec_loop8_enter:
+ $movkey ($key),$rndkey0
+ movups ($inp),$inout0 # load input
+ movups 0x10($inp),$inout1
+ $movkey 16($key),$rndkey1
+
+ lea 32($key),$key
+ movdqu 0x20($inp),$inout2
+ xorps $rndkey0,$inout0
+ movdqu 0x30($inp),$inout3
+ xorps $rndkey0,$inout1
+ movdqu 0x40($inp),$inout4
+ aesdec $rndkey1,$inout0
+ pxor $rndkey0,$inout2
+ movdqu 0x50($inp),$inout5
+ aesdec $rndkey1,$inout1
+ pxor $rndkey0,$inout3
+ movdqu 0x60($inp),$inout6
+ aesdec $rndkey1,$inout2
+ pxor $rndkey0,$inout4
+ movdqu 0x70($inp),$inout7
+ aesdec $rndkey1,$inout3
+ pxor $rndkey0,$inout5
+ dec $rounds
+ aesdec $rndkey1,$inout4
+ pxor $rndkey0,$inout6
+ aesdec $rndkey1,$inout5
+ pxor $rndkey0,$inout7
+ $movkey ($key),$rndkey0
+ aesdec $rndkey1,$inout6
+ aesdec $rndkey1,$inout7
+ $movkey 16($key),$rndkey1
+
+ call .Ldec_loop8_enter
+
+ movups ($inp),$rndkey1 # re-load input
+ movups 0x10($inp),$rndkey0
+ xorps $reserved(%rsp),$inout0 # ^= IV
+ xorps $rndkey1,$inout1
+ movups 0x20($inp),$rndkey1
+ xorps $rndkey0,$inout2
+ movups 0x30($inp),$rndkey0
+ xorps $rndkey1,$inout3
+ movups 0x40($inp),$rndkey1
+ xorps $rndkey0,$inout4
+ movups 0x50($inp),$rndkey0
+ xorps $rndkey1,$inout5
+ movups 0x60($inp),$rndkey1
+ xorps $rndkey0,$inout6
+ movups 0x70($inp),$rndkey0 # IV
+ xorps $rndkey1,$inout7
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ mov $rnds_,$rounds # restore $rounds
+ movups $inout4,0x40($out)
+ mov $key_,$key # restore $key
+ movups $inout5,0x50($out)
+ lea 0x80($inp),$inp
+ movups $inout6,0x60($out)
+ lea 0x70($out),$out
+ sub \$0x80,$len
+ ja .Lcbc_dec_loop8
+
+ movaps $inout7,$inout0
+ movaps $rndkey0,$iv
+ add \$0x70,$len
+ jle .Lcbc_dec_tail_collected
+ movups $inout0,($out)
+ lea 1($rnds_,$rnds_),$rounds
+ lea 0x10($out),$out
+.Lcbc_dec_tail:
+ movups ($inp),$inout0
+ movaps $inout0,$in0
+ cmp \$0x10,$len
+ jbe .Lcbc_dec_one
+
+ movups 0x10($inp),$inout1
+ movaps $inout1,$in1
+ cmp \$0x20,$len
+ jbe .Lcbc_dec_two
+
+ movups 0x20($inp),$inout2
+ movaps $inout2,$in2
+ cmp \$0x30,$len
+ jbe .Lcbc_dec_three
+
+ movups 0x30($inp),$inout3
+ cmp \$0x40,$len
+ jbe .Lcbc_dec_four
+
+ movups 0x40($inp),$inout4
+ cmp \$0x50,$len
+ jbe .Lcbc_dec_five
+
+ movups 0x50($inp),$inout5
+ cmp \$0x60,$len
+ jbe .Lcbc_dec_six
+
+ movups 0x60($inp),$inout6
+ movaps $iv,$reserved(%rsp) # save IV
+ call _aesni_decrypt8
+ movups ($inp),$rndkey1
+ movups 0x10($inp),$rndkey0
+ xorps $reserved(%rsp),$inout0 # ^= IV
+ xorps $rndkey1,$inout1
+ movups 0x20($inp),$rndkey1
+ xorps $rndkey0,$inout2
+ movups 0x30($inp),$rndkey0
+ xorps $rndkey1,$inout3
+ movups 0x40($inp),$rndkey1
+ xorps $rndkey0,$inout4
+ movups 0x50($inp),$rndkey0
+ xorps $rndkey1,$inout5
+ movups 0x60($inp),$iv # IV
+ xorps $rndkey0,$inout6
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ movups $inout4,0x40($out)
+ movups $inout5,0x50($out)
+ lea 0x60($out),$out
+ movaps $inout6,$inout0
+ sub \$0x70,$len
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_one:
+___
+ &aesni_generate1("dec",$key,$rounds);
+$code.=<<___;
+ xorps $iv,$inout0
+ movaps $in0,$iv
+ sub \$0x10,$len
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_two:
+ xorps $inout2,$inout2
+ call _aesni_decrypt3
+ xorps $iv,$inout0
+ xorps $in0,$inout1
+ movups $inout0,($out)
+ movaps $in1,$iv
+ movaps $inout1,$inout0
+ lea 0x10($out),$out
+ sub \$0x20,$len
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_three:
+ call _aesni_decrypt3
+ xorps $iv,$inout0
+ xorps $in0,$inout1
+ movups $inout0,($out)
+ xorps $in1,$inout2
+ movups $inout1,0x10($out)
+ movaps $in2,$iv
+ movaps $inout2,$inout0
+ lea 0x20($out),$out
+ sub \$0x30,$len
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_four:
+ call _aesni_decrypt4
+ xorps $iv,$inout0
+ movups 0x30($inp),$iv
+ xorps $in0,$inout1
+ movups $inout0,($out)
+ xorps $in1,$inout2
+ movups $inout1,0x10($out)
+ xorps $in2,$inout3
+ movups $inout2,0x20($out)
+ movaps $inout3,$inout0
+ lea 0x30($out),$out
+ sub \$0x40,$len
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_five:
+ xorps $inout5,$inout5
+ call _aesni_decrypt6
+ movups 0x10($inp),$rndkey1
+ movups 0x20($inp),$rndkey0
+ xorps $iv,$inout0
+ xorps $in0,$inout1
+ xorps $rndkey1,$inout2
+ movups 0x30($inp),$rndkey1
+ xorps $rndkey0,$inout3
+ movups 0x40($inp),$iv
+ xorps $rndkey1,$inout4
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ lea 0x40($out),$out
+ movaps $inout4,$inout0
+ sub \$0x50,$len
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_six:
+ call _aesni_decrypt6
+ movups 0x10($inp),$rndkey1
+ movups 0x20($inp),$rndkey0
+ xorps $iv,$inout0
+ xorps $in0,$inout1
+ xorps $rndkey1,$inout2
+ movups 0x30($inp),$rndkey1
+ xorps $rndkey0,$inout3
+ movups 0x40($inp),$rndkey0
+ xorps $rndkey1,$inout4
+ movups 0x50($inp),$iv
+ xorps $rndkey0,$inout5
+ movups $inout0,($out)
+ movups $inout1,0x10($out)
+ movups $inout2,0x20($out)
+ movups $inout3,0x30($out)
+ movups $inout4,0x40($out)
+ lea 0x50($out),$out
+ movaps $inout5,$inout0
+ sub \$0x60,$len
+ jmp .Lcbc_dec_tail_collected
+.align 16
+.Lcbc_dec_tail_collected:
+ and \$15,$len
+ movups $iv,($ivp)
+ jnz .Lcbc_dec_tail_partial
+ movups $inout0,($out)
+ jmp .Lcbc_dec_ret
+.align 16
+.Lcbc_dec_tail_partial:
+ movaps $inout0,$reserved(%rsp)
+ mov \$16,%rcx
+ mov $out,%rdi
+ sub $len,%rcx
+ lea $reserved(%rsp),%rsi
+ .long 0x9066A4F3 # rep movsb
+
+.Lcbc_dec_ret:
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp),%xmm6
+ movaps 0x10(%rsp),%xmm7
+ movaps 0x20(%rsp),%xmm8
+ movaps 0x30(%rsp),%xmm9
+ lea 0x58(%rsp),%rsp
+___
+$code.=<<___;
+.Lcbc_ret:
+ ret
+.size ${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt
+___
+}
+# int $PREFIX_set_[en|de]crypt_key (const unsigned char *userKey,
+# int bits, AES_KEY *key)
+{ my ($inp,$bits,$key) = @_4args;
+ $bits =~ s/%r/%e/;
+
+$code.=<<___;
+.globl ${PREFIX}_set_decrypt_key
+.type ${PREFIX}_set_decrypt_key,\@abi-omnipotent
+.align 16
+${PREFIX}_set_decrypt_key:
+ .byte 0x48,0x83,0xEC,0x08 # sub rsp,8
+ call __aesni_set_encrypt_key
+ shl \$4,$bits # rounds-1 after _aesni_set_encrypt_key
+ test %eax,%eax
+ jnz .Ldec_key_ret
+ lea 16($key,$bits),$inp # points at the end of key schedule
+
+ $movkey ($key),%xmm0 # just swap
+ $movkey ($inp),%xmm1
+ $movkey %xmm0,($inp)
+ $movkey %xmm1,($key)
+ lea 16($key),$key
+ lea -16($inp),$inp
+
+.Ldec_key_inverse:
+ $movkey ($key),%xmm0 # swap and inverse
+ $movkey ($inp),%xmm1
+ aesimc %xmm0,%xmm0
+ aesimc %xmm1,%xmm1
+ lea 16($key),$key
+ lea -16($inp),$inp
+ $movkey %xmm0,16($inp)
+ $movkey %xmm1,-16($key)
+ cmp $key,$inp
+ ja .Ldec_key_inverse
+
+ $movkey ($key),%xmm0 # inverse middle
+ aesimc %xmm0,%xmm0
+ $movkey %xmm0,($inp)
+.Ldec_key_ret:
+ add \$8,%rsp
+ ret
+.LSEH_end_set_decrypt_key:
+.size ${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key
+___
+
+# This is based on submission by
+#
+# Huang Ying <ying.huang@intel.com>
+# Vinodh Gopal <vinodh.gopal@intel.com>
+# Kahraman Akdemir
+#
+# Agressively optimized in respect to aeskeygenassist's critical path
+# and is contained in %xmm0-5 to meet Win64 ABI requirement.
+#
+$code.=<<___;
+.globl ${PREFIX}_set_encrypt_key
+.type ${PREFIX}_set_encrypt_key,\@abi-omnipotent
+.align 16
+${PREFIX}_set_encrypt_key:
+__aesni_set_encrypt_key:
+ .byte 0x48,0x83,0xEC,0x08 # sub rsp,8
+ mov \$-1,%rax
+ test $inp,$inp
+ jz .Lenc_key_ret
+ test $key,$key
+ jz .Lenc_key_ret
+
+ movups ($inp),%xmm0 # pull first 128 bits of *userKey
+ xorps %xmm4,%xmm4 # low dword of xmm4 is assumed 0
+ lea 16($key),%rax
+ cmp \$256,$bits
+ je .L14rounds
+ cmp \$192,$bits
+ je .L12rounds
+ cmp \$128,$bits
+ jne .Lbad_keybits
+
+.L10rounds:
+ mov \$9,$bits # 10 rounds for 128-bit key
+ $movkey %xmm0,($key) # round 0
+ aeskeygenassist \$0x1,%xmm0,%xmm1 # round 1
+ call .Lkey_expansion_128_cold
+ aeskeygenassist \$0x2,%xmm0,%xmm1 # round 2
+ call .Lkey_expansion_128
+ aeskeygenassist \$0x4,%xmm0,%xmm1 # round 3
+ call .Lkey_expansion_128
+ aeskeygenassist \$0x8,%xmm0,%xmm1 # round 4
+ call .Lkey_expansion_128
+ aeskeygenassist \$0x10,%xmm0,%xmm1 # round 5
+ call .Lkey_expansion_128
+ aeskeygenassist \$0x20,%xmm0,%xmm1 # round 6
+ call .Lkey_expansion_128
+ aeskeygenassist \$0x40,%xmm0,%xmm1 # round 7
+ call .Lkey_expansion_128
+ aeskeygenassist \$0x80,%xmm0,%xmm1 # round 8
+ call .Lkey_expansion_128
+ aeskeygenassist \$0x1b,%xmm0,%xmm1 # round 9
+ call .Lkey_expansion_128
+ aeskeygenassist \$0x36,%xmm0,%xmm1 # round 10
+ call .Lkey_expansion_128
+ $movkey %xmm0,(%rax)
+ mov $bits,80(%rax) # 240(%rdx)
+ xor %eax,%eax
+ jmp .Lenc_key_ret
+
+.align 16
+.L12rounds:
+ movq 16($inp),%xmm2 # remaining 1/3 of *userKey
+ mov \$11,$bits # 12 rounds for 192
+ $movkey %xmm0,($key) # round 0
+ aeskeygenassist \$0x1,%xmm2,%xmm1 # round 1,2
+ call .Lkey_expansion_192a_cold
+ aeskeygenassist \$0x2,%xmm2,%xmm1 # round 2,3
+ call .Lkey_expansion_192b
+ aeskeygenassist \$0x4,%xmm2,%xmm1 # round 4,5
+ call .Lkey_expansion_192a
+ aeskeygenassist \$0x8,%xmm2,%xmm1 # round 5,6
+ call .Lkey_expansion_192b
+ aeskeygenassist \$0x10,%xmm2,%xmm1 # round 7,8
+ call .Lkey_expansion_192a
+ aeskeygenassist \$0x20,%xmm2,%xmm1 # round 8,9
+ call .Lkey_expansion_192b
+ aeskeygenassist \$0x40,%xmm2,%xmm1 # round 10,11
+ call .Lkey_expansion_192a
+ aeskeygenassist \$0x80,%xmm2,%xmm1 # round 11,12
+ call .Lkey_expansion_192b
+ $movkey %xmm0,(%rax)
+ mov $bits,48(%rax) # 240(%rdx)
+ xor %rax, %rax
+ jmp .Lenc_key_ret
+
+.align 16
+.L14rounds:
+ movups 16($inp),%xmm2 # remaning half of *userKey
+ mov \$13,$bits # 14 rounds for 256
+ lea 16(%rax),%rax
+ $movkey %xmm0,($key) # round 0
+ $movkey %xmm2,16($key) # round 1
+ aeskeygenassist \$0x1,%xmm2,%xmm1 # round 2
+ call .Lkey_expansion_256a_cold
+ aeskeygenassist \$0x1,%xmm0,%xmm1 # round 3
+ call .Lkey_expansion_256b
+ aeskeygenassist \$0x2,%xmm2,%xmm1 # round 4
+ call .Lkey_expansion_256a
+ aeskeygenassist \$0x2,%xmm0,%xmm1 # round 5
+ call .Lkey_expansion_256b
+ aeskeygenassist \$0x4,%xmm2,%xmm1 # round 6
+ call .Lkey_expansion_256a
+ aeskeygenassist \$0x4,%xmm0,%xmm1 # round 7
+ call .Lkey_expansion_256b
+ aeskeygenassist \$0x8,%xmm2,%xmm1 # round 8
+ call .Lkey_expansion_256a
+ aeskeygenassist \$0x8,%xmm0,%xmm1 # round 9
+ call .Lkey_expansion_256b
+ aeskeygenassist \$0x10,%xmm2,%xmm1 # round 10
+ call .Lkey_expansion_256a
+ aeskeygenassist \$0x10,%xmm0,%xmm1 # round 11
+ call .Lkey_expansion_256b
+ aeskeygenassist \$0x20,%xmm2,%xmm1 # round 12
+ call .Lkey_expansion_256a
+ aeskeygenassist \$0x20,%xmm0,%xmm1 # round 13
+ call .Lkey_expansion_256b
+ aeskeygenassist \$0x40,%xmm2,%xmm1 # round 14
+ call .Lkey_expansion_256a
+ $movkey %xmm0,(%rax)
+ mov $bits,16(%rax) # 240(%rdx)
+ xor %rax,%rax
+ jmp .Lenc_key_ret
+
+.align 16
+.Lbad_keybits:
+ mov \$-2,%rax
+.Lenc_key_ret:
+ add \$8,%rsp
+ ret
+.LSEH_end_set_encrypt_key:
+
+.align 16
+.Lkey_expansion_128:
+ $movkey %xmm0,(%rax)
+ lea 16(%rax),%rax
+.Lkey_expansion_128_cold:
+ shufps \$0b00010000,%xmm0,%xmm4
+ xorps %xmm4, %xmm0
+ shufps \$0b10001100,%xmm0,%xmm4
+ xorps %xmm4, %xmm0
+ shufps \$0b11111111,%xmm1,%xmm1 # critical path
+ xorps %xmm1,%xmm0
+ ret
+
+.align 16
+.Lkey_expansion_192a:
+ $movkey %xmm0,(%rax)
+ lea 16(%rax),%rax
+.Lkey_expansion_192a_cold:
+ movaps %xmm2, %xmm5
+.Lkey_expansion_192b_warm:
+ shufps \$0b00010000,%xmm0,%xmm4
+ movdqa %xmm2,%xmm3
+ xorps %xmm4,%xmm0
+ shufps \$0b10001100,%xmm0,%xmm4
+ pslldq \$4,%xmm3
+ xorps %xmm4,%xmm0
+ pshufd \$0b01010101,%xmm1,%xmm1 # critical path
+ pxor %xmm3,%xmm2
+ pxor %xmm1,%xmm0
+ pshufd \$0b11111111,%xmm0,%xmm3
+ pxor %xmm3,%xmm2
+ ret
+
+.align 16
+.Lkey_expansion_192b:
+ movaps %xmm0,%xmm3
+ shufps \$0b01000100,%xmm0,%xmm5
+ $movkey %xmm5,(%rax)
+ shufps \$0b01001110,%xmm2,%xmm3
+ $movkey %xmm3,16(%rax)
+ lea 32(%rax),%rax
+ jmp .Lkey_expansion_192b_warm
+
+.align 16
+.Lkey_expansion_256a:
+ $movkey %xmm2,(%rax)
+ lea 16(%rax),%rax
+.Lkey_expansion_256a_cold:
+ shufps \$0b00010000,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps \$0b10001100,%xmm0,%xmm4
+ xorps %xmm4,%xmm0
+ shufps \$0b11111111,%xmm1,%xmm1 # critical path
+ xorps %xmm1,%xmm0
+ ret
+
+.align 16
+.Lkey_expansion_256b:
+ $movkey %xmm0,(%rax)
+ lea 16(%rax),%rax
+
+ shufps \$0b00010000,%xmm2,%xmm4
+ xorps %xmm4,%xmm2
+ shufps \$0b10001100,%xmm2,%xmm4
+ xorps %xmm4,%xmm2
+ shufps \$0b10101010,%xmm1,%xmm1 # critical path
+ xorps %xmm1,%xmm2
+ ret
+.size ${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key
+.size __aesni_set_encrypt_key,.-__aesni_set_encrypt_key
+___
+}
+
+$code.=<<___;
+.align 64
+.Lbswap_mask:
+ .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+.Lincrement32:
+ .long 6,6,6,0
+.Lincrement64:
+ .long 1,0,0,0
+.Lxts_magic:
+ .long 0x87,0,1,0
+
+.asciz "AES for Intel AES-NI, CRYPTOGAMS by <appro\@openssl.org>"
+.align 64
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+___
+$code.=<<___ if ($PREFIX eq "aesni");
+.type ecb_se_handler,\@abi-omnipotent
+.align 16
+ecb_se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 152($context),%rax # pull context->Rsp
+
+ jmp .Lcommon_seh_tail
+.size ecb_se_handler,.-ecb_se_handler
+
+.type ccm64_se_handler,\@abi-omnipotent
+.align 16
+ccm64_se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # prologue label
+ cmp %r10,%rbx # context->Rip<prologue label
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lcommon_seh_tail
+
+ lea 0(%rax),%rsi # %xmm save area
+ lea 512($context),%rdi # &context.Xmm6
+ mov \$8,%ecx # 4*sizeof(%xmm0)/sizeof(%rax)
+ .long 0xa548f3fc # cld; rep movsq
+ lea 0x58(%rax),%rax # adjust stack pointer
+
+ jmp .Lcommon_seh_tail
+.size ccm64_se_handler,.-ccm64_se_handler
+
+.type ctr32_se_handler,\@abi-omnipotent
+.align 16
+ctr32_se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ lea .Lctr32_body(%rip),%r10
+ cmp %r10,%rbx # context->Rip<"prologue" label
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ lea .Lctr32_ret(%rip),%r10
+ cmp %r10,%rbx
+ jae .Lcommon_seh_tail
+
+ lea 0x20(%rax),%rsi # %xmm save area
+ lea 512($context),%rdi # &context.Xmm6
+ mov \$20,%ecx # 10*sizeof(%xmm0)/sizeof(%rax)
+ .long 0xa548f3fc # cld; rep movsq
+ lea 0xc8(%rax),%rax # adjust stack pointer
+
+ jmp .Lcommon_seh_tail
+.size ctr32_se_handler,.-ctr32_se_handler
+
+.type xts_se_handler,\@abi-omnipotent
+.align 16
+xts_se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # prologue lable
+ cmp %r10,%rbx # context->Rip<prologue label
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lcommon_seh_tail
+
+ lea 0x60(%rax),%rsi # %xmm save area
+ lea 512($context),%rdi # & context.Xmm6
+ mov \$20,%ecx # 10*sizeof(%xmm0)/sizeof(%rax)
+ .long 0xa548f3fc # cld; rep movsq
+ lea 0x68+160(%rax),%rax # adjust stack pointer
+
+ jmp .Lcommon_seh_tail
+.size xts_se_handler,.-xts_se_handler
+___
+$code.=<<___;
+.type cbc_se_handler,\@abi-omnipotent
+.align 16
+cbc_se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 152($context),%rax # pull context->Rsp
+ mov 248($context),%rbx # pull context->Rip
+
+ lea .Lcbc_decrypt(%rip),%r10
+ cmp %r10,%rbx # context->Rip<"prologue" label
+ jb .Lcommon_seh_tail
+
+ lea .Lcbc_decrypt_body(%rip),%r10
+ cmp %r10,%rbx # context->Rip<cbc_decrypt_body
+ jb .Lrestore_cbc_rax
+
+ lea .Lcbc_ret(%rip),%r10
+ cmp %r10,%rbx # context->Rip>="epilogue" label
+ jae .Lcommon_seh_tail
+
+ lea 0(%rax),%rsi # top of stack
+ lea 512($context),%rdi # &context.Xmm6
+ mov \$8,%ecx # 4*sizeof(%xmm0)/sizeof(%rax)
+ .long 0xa548f3fc # cld; rep movsq
+ lea 0x58(%rax),%rax # adjust stack pointer
+ jmp .Lcommon_seh_tail
+
+.Lrestore_cbc_rax:
+ mov 120($context),%rax
+
+.Lcommon_seh_tail:
+ mov 8(%rax),%rdi
+ mov 16(%rax),%rsi
+ mov %rax,152($context) # restore context->Rsp
+ mov %rsi,168($context) # restore context->Rsi
+ mov %rdi,176($context) # restore context->Rdi
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$154,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size cbc_se_handler,.-cbc_se_handler
+
+.section .pdata
+.align 4
+___
+$code.=<<___ if ($PREFIX eq "aesni");
+ .rva .LSEH_begin_aesni_ecb_encrypt
+ .rva .LSEH_end_aesni_ecb_encrypt
+ .rva .LSEH_info_ecb
+
+ .rva .LSEH_begin_aesni_ccm64_encrypt_blocks
+ .rva .LSEH_end_aesni_ccm64_encrypt_blocks
+ .rva .LSEH_info_ccm64_enc
+
+ .rva .LSEH_begin_aesni_ccm64_decrypt_blocks
+ .rva .LSEH_end_aesni_ccm64_decrypt_blocks
+ .rva .LSEH_info_ccm64_dec
+
+ .rva .LSEH_begin_aesni_ctr32_encrypt_blocks
+ .rva .LSEH_end_aesni_ctr32_encrypt_blocks
+ .rva .LSEH_info_ctr32
+
+ .rva .LSEH_begin_aesni_xts_encrypt
+ .rva .LSEH_end_aesni_xts_encrypt
+ .rva .LSEH_info_xts_enc
+
+ .rva .LSEH_begin_aesni_xts_decrypt
+ .rva .LSEH_end_aesni_xts_decrypt
+ .rva .LSEH_info_xts_dec
+___
+$code.=<<___;
+ .rva .LSEH_begin_${PREFIX}_cbc_encrypt
+ .rva .LSEH_end_${PREFIX}_cbc_encrypt
+ .rva .LSEH_info_cbc
+
+ .rva ${PREFIX}_set_decrypt_key
+ .rva .LSEH_end_set_decrypt_key
+ .rva .LSEH_info_key
+
+ .rva ${PREFIX}_set_encrypt_key
+ .rva .LSEH_end_set_encrypt_key
+ .rva .LSEH_info_key
+.section .xdata
+.align 8
+___
+$code.=<<___ if ($PREFIX eq "aesni");
+.LSEH_info_ecb:
+ .byte 9,0,0,0
+ .rva ecb_se_handler
+.LSEH_info_ccm64_enc:
+ .byte 9,0,0,0
+ .rva ccm64_se_handler
+ .rva .Lccm64_enc_body,.Lccm64_enc_ret # HandlerData[]
+.LSEH_info_ccm64_dec:
+ .byte 9,0,0,0
+ .rva ccm64_se_handler
+ .rva .Lccm64_dec_body,.Lccm64_dec_ret # HandlerData[]
+.LSEH_info_ctr32:
+ .byte 9,0,0,0
+ .rva ctr32_se_handler
+.LSEH_info_xts_enc:
+ .byte 9,0,0,0
+ .rva xts_se_handler
+ .rva .Lxts_enc_body,.Lxts_enc_epilogue # HandlerData[]
+.LSEH_info_xts_dec:
+ .byte 9,0,0,0
+ .rva xts_se_handler
+ .rva .Lxts_dec_body,.Lxts_dec_epilogue # HandlerData[]
+___
+$code.=<<___;
+.LSEH_info_cbc:
+ .byte 9,0,0,0
+ .rva cbc_se_handler
+.LSEH_info_key:
+ .byte 0x01,0x04,0x01,0x00
+ .byte 0x04,0x02,0x00,0x00 # sub rsp,8
+___
+}
+
+sub rex {
+ local *opcode=shift;
+ my ($dst,$src)=@_;
+ my $rex=0;
+
+ $rex|=0x04 if($dst>=8);
+ $rex|=0x01 if($src>=8);
+ push @opcode,$rex|0x40 if($rex);
+}
+
+sub aesni {
+ my $line=shift;
+ my @opcode=(0x66);
+
+ if ($line=~/(aeskeygenassist)\s+\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
+ rex(\@opcode,$4,$3);
+ push @opcode,0x0f,0x3a,0xdf;
+ push @opcode,0xc0|($3&7)|(($4&7)<<3); # ModR/M
+ my $c=$2;
+ push @opcode,$c=~/^0/?oct($c):$c;
+ return ".byte\t".join(',',@opcode);
+ }
+ elsif ($line=~/(aes[a-z]+)\s+%xmm([0-9]+),\s*%xmm([0-9]+)/) {
+ my %opcodelet = (
+ "aesimc" => 0xdb,
+ "aesenc" => 0xdc, "aesenclast" => 0xdd,
+ "aesdec" => 0xde, "aesdeclast" => 0xdf
+ );
+ return undef if (!defined($opcodelet{$1}));
+ rex(\@opcode,$3,$2);
+ push @opcode,0x0f,0x38,$opcodelet{$1};
+ push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M
+ return ".byte\t".join(',',@opcode);
+ }
+ return $line;
+}
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+$code =~ s/\b(aes.*%xmm[0-9]+).*$/aesni($1)/gem;
+
+print $code;
+
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/aes/asm/bsaes-x86_64.pl b/deps/openssl/openssl/crypto/aes/asm/bsaes-x86_64.pl
new file mode 100644
index 000000000..ceb02b50d
--- /dev/null
+++ b/deps/openssl/openssl/crypto/aes/asm/bsaes-x86_64.pl
@@ -0,0 +1,3045 @@
+#!/usr/bin/env perl
+
+###################################################################
+### AES-128 [originally in CTR mode] ###
+### bitsliced implementation for Intel Core 2 processors ###
+### requires support of SSE extensions up to SSSE3 ###
+### Author: Emilia Käsper and Peter Schwabe ###
+### Date: 2009-03-19 ###
+### Public domain ###
+### ###
+### See http://homes.esat.kuleuven.be/~ekasper/#software for ###
+### further information. ###
+###################################################################
+#
+# September 2011.
+#
+# Started as transliteration to "perlasm" the original code has
+# undergone following changes:
+#
+# - code was made position-independent;
+# - rounds were folded into a loop resulting in >5x size reduction
+# from 12.5KB to 2.2KB;
+# - above was possibile thanks to mixcolumns() modification that
+# allowed to feed its output back to aesenc[last], this was
+# achieved at cost of two additional inter-registers moves;
+# - some instruction reordering and interleaving;
+# - this module doesn't implement key setup subroutine, instead it
+# relies on conversion of "conventional" key schedule as returned
+# by AES_set_encrypt_key (see discussion below);
+# - first and last round keys are treated differently, which allowed
+# to skip one shiftrows(), reduce bit-sliced key schedule and
+# speed-up conversion by 22%;
+# - support for 192- and 256-bit keys was added;
+#
+# Resulting performance in CPU cycles spent to encrypt one byte out
+# of 4096-byte buffer with 128-bit key is:
+#
+# Emilia's this(*) difference
+#
+# Core 2 9.30 8.69 +7%
+# Nehalem(**) 7.63 6.98 +9%
+# Atom 17.1 17.4 -2%(***)
+#
+# (*) Comparison is not completely fair, because "this" is ECB,
+# i.e. no extra processing such as counter values calculation
+# and xor-ing input as in Emilia's CTR implementation is
+# performed. However, the CTR calculations stand for not more
+# than 1% of total time, so comparison is *rather* fair.
+#
+# (**) Results were collected on Westmere, which is considered to
+# be equivalent to Nehalem for this code.
+#
+# (***) Slowdown on Atom is rather strange per se, because original
+# implementation has a number of 9+-bytes instructions, which
+# are bad for Atom front-end, and which I eliminated completely.
+# In attempt to address deterioration sbox() was tested in FP
+# SIMD "domain" (movaps instead of movdqa, xorps instead of
+# pxor, etc.). While it resulted in nominal 4% improvement on
+# Atom, it hurted Westmere by more than 2x factor.
+#
+# As for key schedule conversion subroutine. Interface to OpenSSL
+# relies on per-invocation on-the-fly conversion. This naturally
+# has impact on performance, especially for short inputs. Conversion
+# time in CPU cycles and its ratio to CPU cycles spent in 8x block
+# function is:
+#
+# conversion conversion/8x block
+# Core 2 240 0.22
+# Nehalem 180 0.20
+# Atom 430 0.19
+#
+# The ratio values mean that 128-byte blocks will be processed
+# 16-18% slower, 256-byte blocks - 9-10%, 384-byte blocks - 6-7%,
+# etc. Then keep in mind that input sizes not divisible by 128 are
+# *effectively* slower, especially shortest ones, e.g. consecutive
+# 144-byte blocks are processed 44% slower than one would expect,
+# 272 - 29%, 400 - 22%, etc. Yet, despite all these "shortcomings"
+# it's still faster than ["hyper-threading-safe" code path in]
+# aes-x86_64.pl on all lengths above 64 bytes...
+#
+# October 2011.
+#
+# Add decryption procedure. Performance in CPU cycles spent to decrypt
+# one byte out of 4096-byte buffer with 128-bit key is:
+#
+# Core 2 11.0
+# Nehalem 9.16
+# Atom 20.9
+#
+# November 2011.
+#
+# Add bsaes_xts_[en|de]crypt. Less-than-80-bytes-block performance is
+# suboptimal, but XTS is meant to be used with larger blocks...
+#
+# <appro@openssl.org>
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+my ($inp,$out,$len,$key,$ivp)=("%rdi","%rsi","%rdx","%rcx");
+my @XMM=map("%xmm$_",(15,0..14)); # best on Atom, +10% over (0..15)
+my $ecb=0; # suppress unreferenced ECB subroutines, spare some space...
+
+{
+my ($key,$rounds,$const)=("%rax","%r10d","%r11");
+
+sub Sbox {
+# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
+# output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb
+my @b=@_[0..7];
+my @t=@_[8..11];
+my @s=@_[12..15];
+ &InBasisChange (@b);
+ &Inv_GF256 (@b[6,5,0,3,7,1,4,2],@t,@s);
+ &OutBasisChange (@b[7,1,4,2,6,5,0,3]);
+}
+
+sub InBasisChange {
+# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
+# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb
+my @b=@_[0..7];
+$code.=<<___;
+ pxor @b[6], @b[5]
+ pxor @b[1], @b[2]
+ pxor @b[0], @b[3]
+ pxor @b[2], @b[6]
+ pxor @b[0], @b[5]
+
+ pxor @b[3], @b[6]
+ pxor @b[7], @b[3]
+ pxor @b[5], @b[7]
+ pxor @b[4], @b[3]
+ pxor @b[5], @b[4]
+ pxor @b[1], @b[3]
+
+ pxor @b[7], @b[2]
+ pxor @b[5], @b[1]
+___
+}
+
+sub OutBasisChange {
+# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
+# output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb
+my @b=@_[0..7];
+$code.=<<___;
+ pxor @b[6], @b[0]
+ pxor @b[4], @b[1]
+ pxor @b[0], @b[2]
+ pxor @b[6], @b[4]
+ pxor @b[1], @b[6]
+
+ pxor @b[5], @b[1]
+ pxor @b[3], @b[5]
+ pxor @b[7], @b[3]
+ pxor @b[5], @b[7]
+ pxor @b[5], @b[2]
+
+ pxor @b[7], @b[4]
+___
+}
+
+sub InvSbox {
+# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
+# output in lsb > [b0, b1, b6, b4, b2, b7, b3, b5] < msb
+my @b=@_[0..7];
+my @t=@_[8..11];
+my @s=@_[12..15];
+ &InvInBasisChange (@b);
+ &Inv_GF256 (@b[5,1,2,6,3,7,0,4],@t,@s);
+ &InvOutBasisChange (@b[3,7,0,4,5,1,2,6]);
+}
+
+sub InvInBasisChange { # OutBasisChange in reverse
+my @b=@_[5,1,2,6,3,7,0,4];
+$code.=<<___
+ pxor @b[7], @b[4]
+
+ pxor @b[5], @b[7]
+ pxor @b[5], @b[2]
+ pxor @b[7], @b[3]
+ pxor @b[3], @b[5]
+ pxor @b[5], @b[1]
+
+ pxor @b[1], @b[6]
+ pxor @b[0], @b[2]
+ pxor @b[6], @b[4]
+ pxor @b[6], @b[0]
+ pxor @b[4], @b[1]
+___
+}
+
+sub InvOutBasisChange { # InBasisChange in reverse
+my @b=@_[2,5,7,3,6,1,0,4];
+$code.=<<___;
+ pxor @b[5], @b[1]
+ pxor @b[7], @b[2]
+
+ pxor @b[1], @b[3]
+ pxor @b[5], @b[4]
+ pxor @b[5], @b[7]
+ pxor @b[4], @b[3]
+ pxor @b[0], @b[5]
+ pxor @b[7], @b[3]
+ pxor @b[2], @b[6]
+ pxor @b[1], @b[2]
+ pxor @b[3], @b[6]
+
+ pxor @b[0], @b[3]
+ pxor @b[6], @b[5]
+___
+}
+
+sub Mul_GF4 {
+#;*************************************************************
+#;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) *
+#;*************************************************************
+my ($x0,$x1,$y0,$y1,$t0)=@_;
+$code.=<<___;
+ movdqa $y0, $t0
+ pxor $y1, $t0
+ pand $x0, $t0
+ pxor $x1, $x0
+ pand $y0, $x1
+ pand $y1, $x0
+ pxor $x1, $x0
+ pxor $t0, $x1
+___
+}
+
+sub Mul_GF4_N { # not used, see next subroutine
+# multiply and scale by N
+my ($x0,$x1,$y0,$y1,$t0)=@_;
+$code.=<<___;
+ movdqa $y0, $t0
+ pxor $y1, $t0
+ pand $x0, $t0
+ pxor $x1, $x0
+ pand $y0, $x1
+ pand $y1, $x0
+ pxor $x0, $x1
+ pxor $t0, $x0
+___
+}
+
+sub Mul_GF4_N_GF4 {
+# interleaved Mul_GF4_N and Mul_GF4
+my ($x0,$x1,$y0,$y1,$t0,
+ $x2,$x3,$y2,$y3,$t1)=@_;
+$code.=<<___;
+ movdqa $y0, $t0
+ movdqa $y2, $t1
+ pxor $y1, $t0
+ pxor $y3, $t1
+ pand $x0, $t0
+ pand $x2, $t1
+ pxor $x1, $x0
+ pxor $x3, $x2
+ pand $y0, $x1
+ pand $y2, $x3
+ pand $y1, $x0
+ pand $y3, $x2
+ pxor $x0, $x1
+ pxor $x3, $x2
+ pxor $t0, $x0
+ pxor $t1, $x3
+___
+}
+sub Mul_GF16_2 {
+my @x=@_[0..7];
+my @y=@_[8..11];
+my @t=@_[12..15];
+$code.=<<___;
+ movdqa @x[0], @t[0]
+ movdqa @x[1], @t[1]
+___
+ &Mul_GF4 (@x[0], @x[1], @y[0], @y[1], @t[2]);
+$code.=<<___;
+ pxor @x[2], @t[0]
+ pxor @x[3], @t[1]
+ pxor @y[2], @y[0]
+ pxor @y[3], @y[1]
+___
+ Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3],
+ @x[2], @x[3], @y[2], @y[3], @t[2]);
+$code.=<<___;
+ pxor @t[0], @x[0]
+ pxor @t[0], @x[2]
+ pxor @t[1], @x[1]
+ pxor @t[1], @x[3]
+
+ movdqa @x[4], @t[0]
+ movdqa @x[5], @t[1]
+ pxor @x[6], @t[0]
+ pxor @x[7], @t[1]
+___
+ &Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3],
+ @x[6], @x[7], @y[2], @y[3], @t[2]);
+$code.=<<___;
+ pxor @y[2], @y[0]
+ pxor @y[3], @y[1]
+___
+ &Mul_GF4 (@x[4], @x[5], @y[0], @y[1], @t[3]);
+$code.=<<___;
+ pxor @t[0], @x[4]
+ pxor @t[0], @x[6]
+ pxor @t[1], @x[5]
+ pxor @t[1], @x[7]
+___
+}
+sub Inv_GF256 {
+#;********************************************************************
+#;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144) *
+#;********************************************************************
+my @x=@_[0..7];
+my @t=@_[8..11];
+my @s=@_[12..15];
+# direct optimizations from hardware
+$code.=<<___;
+ movdqa @x[4], @t[3]
+ movdqa @x[5], @t[2]
+ movdqa @x[1], @t[1]
+ movdqa @x[7], @s[1]
+ movdqa @x[0], @s[0]
+
+ pxor @x[6], @t[3]
+ pxor @x[7], @t[2]
+ pxor @x[3], @t[1]
+ movdqa @t[3], @s[2]
+ pxor @x[6], @s[1]
+ movdqa @t[2], @t[0]
+ pxor @x[2], @s[0]
+ movdqa @t[3], @s[3]
+
+ por @t[1], @t[2]
+ por @s[0], @t[3]
+ pxor @t[0], @s[3]
+ pand @s[0], @s[2]
+ pxor @t[1], @s[0]
+ pand @t[1], @t[0]
+ pand @s[0], @s[3]
+ movdqa @x[3], @s[0]
+ pxor @x[2], @s[0]
+ pand @s[0], @s[1]
+ pxor @s[1], @t[3]
+ pxor @s[1], @t[2]
+ movdqa @x[4], @s[1]
+ movdqa @x[1], @s[0]
+ pxor @x[5], @s[1]
+ pxor @x[0], @s[0]
+ movdqa @s[1], @t[1]
+ pand @s[0], @s[1]
+ por @s[0], @t[1]
+ pxor @s[1], @t[0]
+ pxor @s[3], @t[3]
+ pxor @s[2], @t[2]
+ pxor @s[3], @t[1]
+ movdqa @x[7], @s[0]
+ pxor @s[2], @t[0]
+ movdqa @x[6], @s[1]
+ pxor @s[2], @t[1]
+ movdqa @x[5], @s[2]
+ pand @x[3], @s[0]
+ movdqa @x[4], @s[3]
+ pand @x[2], @s[1]
+ pand @x[1], @s[2]
+ por @x[0], @s[3]
+ pxor @s[0], @t[3]
+ pxor @s[1], @t[2]
+ pxor @s[2], @t[1]
+ pxor @s[3], @t[0]
+
+ #Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
+
+ # new smaller inversion
+
+ movdqa @t[3], @s[0]
+ pand @t[1], @t[3]
+ pxor @t[2], @s[0]
+
+ movdqa @t[0], @s[2]
+ movdqa @s[0], @s[3]
+ pxor @t[3], @s[2]
+ pand @s[2], @s[3]
+
+ movdqa @t[1], @s[1]
+ pxor @t[2], @s[3]
+ pxor @t[0], @s[1]
+
+ pxor @t[2], @t[3]
+
+ pand @t[3], @s[1]
+
+ movdqa @s[2], @t[2]
+ pxor @t[0], @s[1]
+
+ pxor @s[1], @t[2]
+ pxor @s[1], @t[1]
+
+ pand @t[0], @t[2]
+
+ pxor @t[2], @s[2]
+ pxor @t[2], @t[1]
+
+ pand @s[3], @s[2]
+
+ pxor @s[0], @s[2]
+___
+# output in s3, s2, s1, t1
+
+# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3
+
+# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
+ &Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]);
+
+### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb
+}
+
+# AES linear components
+
+sub ShiftRows {
+my @x=@_[0..7];
+my $mask=pop;
+$code.=<<___;
+ pxor 0x00($key),@x[0]
+ pxor 0x10($key),@x[1]
+ pshufb $mask,@x[0]
+ pxor 0x20($key),@x[2]
+ pshufb $mask,@x[1]
+ pxor 0x30($key),@x[3]
+ pshufb $mask,@x[2]
+ pxor 0x40($key),@x[4]
+ pshufb $mask,@x[3]
+ pxor 0x50($key),@x[5]
+ pshufb $mask,@x[4]
+ pxor 0x60($key),@x[6]
+ pshufb $mask,@x[5]
+ pxor 0x70($key),@x[7]
+ pshufb $mask,@x[6]
+ lea 0x80($key),$key
+ pshufb $mask,@x[7]
+___
+}
+
+sub MixColumns {
+# modified to emit output in order suitable for feeding back to aesenc[last]
+my @x=@_[0..7];
+my @t=@_[8..15];
+$code.=<<___;
+ pshufd \$0x93, @x[0], @t[0] # x0 <<< 32
+ pshufd \$0x93, @x[1], @t[1]
+ pxor @t[0], @x[0] # x0 ^ (x0 <<< 32)
+ pshufd \$0x93, @x[2], @t[2]
+ pxor @t[1], @x[1]
+ pshufd \$0x93, @x[3], @t[3]
+ pxor @t[2], @x[2]
+ pshufd \$0x93, @x[4], @t[4]
+ pxor @t[3], @x[3]
+ pshufd \$0x93, @x[5], @t[5]
+ pxor @t[4], @x[4]
+ pshufd \$0x93, @x[6], @t[6]
+ pxor @t[5], @x[5]
+ pshufd \$0x93, @x[7], @t[7]
+ pxor @t[6], @x[6]
+ pxor @t[7], @x[7]
+
+ pxor @x[0], @t[1]
+ pxor @x[7], @t[0]
+ pxor @x[7], @t[1]
+ pshufd \$0x4E, @x[0], @x[0] # (x0 ^ (x0 <<< 32)) <<< 64)
+ pxor @x[1], @t[2]
+ pshufd \$0x4E, @x[1], @x[1]
+ pxor @x[4], @t[5]
+ pxor @t[0], @x[0]
+ pxor @x[5], @t[6]
+ pxor @t[1], @x[1]
+ pxor @x[3], @t[4]
+ pshufd \$0x4E, @x[4], @t[0]
+ pxor @x[6], @t[7]
+ pshufd \$0x4E, @x[5], @t[1]
+ pxor @x[2], @t[3]
+ pshufd \$0x4E, @x[3], @x[4]
+ pxor @x[7], @t[3]
+ pshufd \$0x4E, @x[7], @x[5]
+ pxor @x[7], @t[4]
+ pshufd \$0x4E, @x[6], @x[3]
+ pxor @t[4], @t[0]
+ pshufd \$0x4E, @x[2], @x[6]
+ pxor @t[5], @t[1]
+
+ pxor @t[3], @x[4]
+ pxor @t[7], @x[5]
+ pxor @t[6], @x[3]
+ movdqa @t[0], @x[2]
+ pxor @t[2], @x[6]
+ movdqa @t[1], @x[7]
+___
+}
+
+sub InvMixColumns {
+my @x=@_[0..7];
+my @t=@_[8..15];
+
+$code.=<<___;
+ # multiplication by 0x0e
+ pshufd \$0x93, @x[7], @t[7]
+ movdqa @x[2], @t[2]
+ pxor @x[5], @x[7] # 7 5
+ pxor @x[5], @x[2] # 2 5
+ pshufd \$0x93, @x[0], @t[0]
+ movdqa @x[5], @t[5]
+ pxor @x[0], @x[5] # 5 0 [1]
+ pxor @x[1], @x[0] # 0 1
+ pshufd \$0x93, @x[1], @t[1]
+ pxor @x[2], @x[1] # 1 25
+ pxor @x[6], @x[0] # 01 6 [2]
+ pxor @x[3], @x[1] # 125 3 [4]
+ pshufd \$0x93, @x[3], @t[3]
+ pxor @x[0], @x[2] # 25 016 [3]
+ pxor @x[7], @x[3] # 3 75
+ pxor @x[6], @x[7] # 75 6 [0]
+ pshufd \$0x93, @x[6], @t[6]
+ movdqa @x[4], @t[4]
+ pxor @x[4], @x[6] # 6 4
+ pxor @x[3], @x[4] # 4 375 [6]
+ pxor @x[7], @x[3] # 375 756=36
+ pxor @t[5], @x[6] # 64 5 [7]
+ pxor @t[2], @x[3] # 36 2
+ pxor @t[4], @x[3] # 362 4 [5]
+ pshufd \$0x93, @t[5], @t[5]
+___
+ my @y = @x[7,5,0,2,1,3,4,6];
+$code.=<<___;
+ # multiplication by 0x0b
+ pxor @y[0], @y[1]
+ pxor @t[0], @y[0]
+ pxor @t[1], @y[1]
+ pshufd \$0x93, @t[2], @t[2]
+ pxor @t[5], @y[0]
+ pxor @t[6], @y[1]
+ pxor @t[7], @y[0]
+ pshufd \$0x93, @t[4], @t[4]
+ pxor @t[6], @t[7] # clobber t[7]
+ pxor @y[0], @y[1]
+
+ pxor @t[0], @y[3]
+ pshufd \$0x93, @t[0], @t[0]
+ pxor @t[1], @y[2]
+ pxor @t[1], @y[4]
+ pxor @t[2], @y[2]
+ pshufd \$0x93, @t[1], @t[1]
+ pxor @t[2], @y[3]
+ pxor @t[2], @y[5]
+ pxor @t[7], @y[2]
+ pshufd \$0x93, @t[2], @t[2]
+ pxor @t[3], @y[3]
+ pxor @t[3], @y[6]
+ pxor @t[3], @y[4]
+ pshufd \$0x93, @t[3], @t[3]
+ pxor @t[4], @y[7]
+ pxor @t[4], @y[5]
+ pxor @t[7], @y[7]
+ pxor @t[5], @y[3]
+ pxor @t[4], @y[4]
+ pxor @t[5], @t[7] # clobber t[7] even more
+
+ pxor @t[7], @y[5]
+ pshufd \$0x93, @t[4], @t[4]
+ pxor @t[7], @y[6]
+ pxor @t[7], @y[4]
+
+ pxor @t[5], @t[7]
+ pshufd \$0x93, @t[5], @t[5]
+ pxor @t[6], @t[7] # restore t[7]
+
+ # multiplication by 0x0d
+ pxor @y[7], @y[4]
+ pxor @t[4], @y[7]
+ pshufd \$0x93, @t[6], @t[6]
+ pxor @t[0], @y[2]
+ pxor @t[5], @y[7]
+ pxor @t[2], @y[2]
+ pshufd \$0x93, @t[7], @t[7]
+
+ pxor @y[1], @y[3]
+ pxor @t[1], @y[1]
+ pxor @t[0], @y[0]
+ pxor @t[0], @y[3]
+ pxor @t[5], @y[1]
+ pxor @t[5], @y[0]
+ pxor @t[7], @y[1]
+ pshufd \$0x93, @t[0], @t[0]
+ pxor @t[6], @y[0]
+ pxor @y[1], @y[3]
+ pxor @t[1], @y[4]
+ pshufd \$0x93, @t[1], @t[1]
+
+ pxor @t[7], @y[7]
+ pxor @t[2], @y[4]
+ pxor @t[2], @y[5]
+ pshufd \$0x93, @t[2], @t[2]
+ pxor @t[6], @y[2]
+ pxor @t[3], @t[6] # clobber t[6]
+ pxor @y[7], @y[4]
+ pxor @t[6], @y[3]
+
+ pxor @t[6], @y[6]
+ pxor @t[5], @y[5]
+ pxor @t[4], @y[6]
+ pshufd \$0x93, @t[4], @t[4]
+ pxor @t[6], @y[5]
+ pxor @t[7], @y[6]
+ pxor @t[3], @t[6] # restore t[6]
+
+ pshufd \$0x93, @t[5], @t[5]
+ pshufd \$0x93, @t[6], @t[6]
+ pshufd \$0x93, @t[7], @t[7]
+ pshufd \$0x93, @t[3], @t[3]
+
+ # multiplication by 0x09
+ pxor @y[1], @y[4]
+ pxor @y[1], @t[1] # t[1]=y[1]
+ pxor @t[5], @t[0] # clobber t[0]
+ pxor @t[5], @t[1]
+ pxor @t[0], @y[3]
+ pxor @y[0], @t[0] # t[0]=y[0]
+ pxor @t[6], @t[1]
+ pxor @t[7], @t[6] # clobber t[6]
+ pxor @t[1], @y[4]
+ pxor @t[4], @y[7]
+ pxor @y[4], @t[4] # t[4]=y[4]
+ pxor @t[3], @y[6]
+ pxor @y[3], @t[3] # t[3]=y[3]
+ pxor @t[2], @y[5]
+ pxor @y[2], @t[2] # t[2]=y[2]
+ pxor @t[7], @t[3]
+ pxor @y[5], @t[5] # t[5]=y[5]
+ pxor @t[6], @t[2]
+ pxor @t[6], @t[5]
+ pxor @y[6], @t[6] # t[6]=y[6]
+ pxor @y[7], @t[7] # t[7]=y[7]
+
+ movdqa @t[0],@XMM[0]
+ movdqa @t[1],@XMM[1]
+ movdqa @t[2],@XMM[2]
+ movdqa @t[3],@XMM[3]
+ movdqa @t[4],@XMM[4]
+ movdqa @t[5],@XMM[5]
+ movdqa @t[6],@XMM[6]
+ movdqa @t[7],@XMM[7]
+___
+}
+
+sub aesenc { # not used
+my @b=@_[0..7];
+my @t=@_[8..15];
+$code.=<<___;
+ movdqa 0x30($const),@t[0] # .LSR
+___
+ &ShiftRows (@b,@t[0]);
+ &Sbox (@b,@t);
+ &MixColumns (@b[0,1,4,6,3,7,2,5],@t);
+}
+
+sub aesenclast { # not used
+my @b=@_[0..7];
+my @t=@_[8..15];
+$code.=<<___;
+ movdqa 0x40($const),@t[0] # .LSRM0
+___
+ &ShiftRows (@b,@t[0]);
+ &Sbox (@b,@t);
+$code.=<<___
+ pxor 0x00($key),@b[0]
+ pxor 0x10($key),@b[1]
+ pxor 0x20($key),@b[4]
+ pxor 0x30($key),@b[6]
+ pxor 0x40($key),@b[3]
+ pxor 0x50($key),@b[7]
+ pxor 0x60($key),@b[2]
+ pxor 0x70($key),@b[5]
+___
+}
+
+sub swapmove {
+my ($a,$b,$n,$mask,$t)=@_;
+$code.=<<___;
+ movdqa $b,$t
+ psrlq \$$n,$b
+ pxor $a,$b
+ pand $mask,$b
+ pxor $b,$a
+ psllq \$$n,$b
+ pxor $t,$b
+___
+}
+sub swapmove2x {
+my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_;
+$code.=<<___;
+ movdqa $b0,$t0
+ psrlq \$$n,$b0
+ movdqa $b1,$t1
+ psrlq \$$n,$b1
+ pxor $a0,$b0
+ pxor $a1,$b1
+ pand $mask,$b0
+ pand $mask,$b1
+ pxor $b0,$a0
+ psllq \$$n,$b0
+ pxor $b1,$a1
+ psllq \$$n,$b1
+ pxor $t0,$b0
+ pxor $t1,$b1
+___
+}
+
+sub bitslice {
+my @x=reverse(@_[0..7]);
+my ($t0,$t1,$t2,$t3)=@_[8..11];
+$code.=<<___;
+ movdqa 0x00($const),$t0 # .LBS0
+ movdqa 0x10($const),$t1 # .LBS1
+___
+ &swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3);
+ &swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
+$code.=<<___;
+ movdqa 0x20($const),$t0 # .LBS2
+___
+ &swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3);
+ &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
+
+ &swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3);
+ &swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3);
+}
+
+$code.=<<___;
+.text
+
+.extern asm_AES_encrypt
+.extern asm_AES_decrypt
+
+.type _bsaes_encrypt8,\@abi-omnipotent
+.align 64
+_bsaes_encrypt8:
+ lea .LBS0(%rip), $const # constants table
+
+ movdqa ($key), @XMM[9] # round 0 key
+ lea 0x10($key), $key
+ movdqa 0x50($const), @XMM[8] # .LM0SR
+ pxor @XMM[9], @XMM[0] # xor with round0 key
+ pxor @XMM[9], @XMM[1]
+ pshufb @XMM[8], @XMM[0]
+ pxor @XMM[9], @XMM[2]
+ pshufb @XMM[8], @XMM[1]
+ pxor @XMM[9], @XMM[3]
+ pshufb @XMM[8], @XMM[2]
+ pxor @XMM[9], @XMM[4]
+ pshufb @XMM[8], @XMM[3]
+ pxor @XMM[9], @XMM[5]
+ pshufb @XMM[8], @XMM[4]
+ pxor @XMM[9], @XMM[6]
+ pshufb @XMM[8], @XMM[5]
+ pxor @XMM[9], @XMM[7]
+ pshufb @XMM[8], @XMM[6]
+ pshufb @XMM[8], @XMM[7]
+_bsaes_encrypt8_bitslice:
+___
+ &bitslice (@XMM[0..7, 8..11]);
+$code.=<<___;
+ dec $rounds
+ jmp .Lenc_sbox
+.align 16
+.Lenc_loop:
+___
+ &ShiftRows (@XMM[0..7, 8]);
+$code.=".Lenc_sbox:\n";
+ &Sbox (@XMM[0..7, 8..15]);
+$code.=<<___;
+ dec $rounds
+ jl .Lenc_done
+___
+ &MixColumns (@XMM[0,1,4,6,3,7,2,5, 8..15]);
+$code.=<<___;
+ movdqa 0x30($const), @XMM[8] # .LSR
+ jnz .Lenc_loop
+ movdqa 0x40($const), @XMM[8] # .LSRM0
+ jmp .Lenc_loop
+.align 16
+.Lenc_done:
+___
+ # output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb
+ &bitslice (@XMM[0,1,4,6,3,7,2,5, 8..11]);
+$code.=<<___;
+ movdqa ($key), @XMM[8] # last round key
+ pxor @XMM[8], @XMM[4]
+ pxor @XMM[8], @XMM[6]
+ pxor @XMM[8], @XMM[3]
+ pxor @XMM[8], @XMM[7]
+ pxor @XMM[8], @XMM[2]
+ pxor @XMM[8], @XMM[5]
+ pxor @XMM[8], @XMM[0]
+ pxor @XMM[8], @XMM[1]
+ ret
+.size _bsaes_encrypt8,.-_bsaes_encrypt8
+
+.type _bsaes_decrypt8,\@abi-omnipotent
+.align 64
+_bsaes_decrypt8:
+ lea .LBS0(%rip), $const # constants table
+
+ movdqa ($key), @XMM[9] # round 0 key
+ lea 0x10($key), $key
+ movdqa -0x30($const), @XMM[8] # .LM0ISR
+ pxor @XMM[9], @XMM[0] # xor with round0 key
+ pxor @XMM[9], @XMM[1]
+ pshufb @XMM[8], @XMM[0]
+ pxor @XMM[9], @XMM[2]
+ pshufb @XMM[8], @XMM[1]
+ pxor @XMM[9], @XMM[3]
+ pshufb @XMM[8], @XMM[2]
+ pxor @XMM[9], @XMM[4]
+ pshufb @XMM[8], @XMM[3]
+ pxor @XMM[9], @XMM[5]
+ pshufb @XMM[8], @XMM[4]
+ pxor @XMM[9], @XMM[6]
+ pshufb @XMM[8], @XMM[5]
+ pxor @XMM[9], @XMM[7]
+ pshufb @XMM[8], @XMM[6]
+ pshufb @XMM[8], @XMM[7]
+___
+ &bitslice (@XMM[0..7, 8..11]);
+$code.=<<___;
+ dec $rounds
+ jmp .Ldec_sbox
+.align 16
+.Ldec_loop:
+___
+ &ShiftRows (@XMM[0..7, 8]);
+$code.=".Ldec_sbox:\n";
+ &InvSbox (@XMM[0..7, 8..15]);
+$code.=<<___;
+ dec $rounds
+ jl .Ldec_done
+___
+ &InvMixColumns (@XMM[0,1,6,4,2,7,3,5, 8..15]);
+$code.=<<___;
+ movdqa -0x10($const), @XMM[8] # .LISR
+ jnz .Ldec_loop
+ movdqa -0x20($const), @XMM[8] # .LISRM0
+ jmp .Ldec_loop
+.align 16
+.Ldec_done:
+___
+ &bitslice (@XMM[0,1,6,4,2,7,3,5, 8..11]);
+$code.=<<___;
+ movdqa ($key), @XMM[8] # last round key
+ pxor @XMM[8], @XMM[6]
+ pxor @XMM[8], @XMM[4]
+ pxor @XMM[8], @XMM[2]
+ pxor @XMM[8], @XMM[7]
+ pxor @XMM[8], @XMM[3]
+ pxor @XMM[8], @XMM[5]
+ pxor @XMM[8], @XMM[0]
+ pxor @XMM[8], @XMM[1]
+ ret
+.size _bsaes_decrypt8,.-_bsaes_decrypt8
+___
+}
+{
+my ($out,$inp,$rounds,$const)=("%rax","%rcx","%r10d","%r11");
+
+sub bitslice_key {
+my @x=reverse(@_[0..7]);
+my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12];
+
+ &swapmove (@x[0,1],1,$bs0,$t2,$t3);
+$code.=<<___;
+ #&swapmove(@x[2,3],1,$t0,$t2,$t3);
+ movdqa @x[0], @x[2]
+ movdqa @x[1], @x[3]
+___
+ #&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
+
+ &swapmove2x (@x[0,2,1,3],2,$bs1,$t2,$t3);
+$code.=<<___;
+ #&swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
+ movdqa @x[0], @x[4]
+ movdqa @x[2], @x[6]
+ movdqa @x[1], @x[5]
+ movdqa @x[3], @x[7]
+___
+ &swapmove2x (@x[0,4,1,5],4,$bs2,$t2,$t3);
+ &swapmove2x (@x[2,6,3,7],4,$bs2,$t2,$t3);
+}
+
+$code.=<<___;
+.type _bsaes_key_convert,\@abi-omnipotent
+.align 16
+_bsaes_key_convert:
+ lea .Lmasks(%rip), $const
+ movdqu ($inp), %xmm7 # load round 0 key
+ lea 0x10($inp), $inp
+ movdqa 0x00($const), %xmm0 # 0x01...
+ movdqa 0x10($const), %xmm1 # 0x02...
+ movdqa 0x20($const), %xmm2 # 0x04...
+ movdqa 0x30($const), %xmm3 # 0x08...
+ movdqa 0x40($const), %xmm4 # .LM0
+ pcmpeqd %xmm5, %xmm5 # .LNOT
+
+ movdqu ($inp), %xmm6 # load round 1 key
+ movdqa %xmm7, ($out) # save round 0 key
+ lea 0x10($out), $out
+ dec $rounds
+ jmp .Lkey_loop
+.align 16
+.Lkey_loop:
+ pshufb %xmm4, %xmm6 # .LM0
+
+ movdqa %xmm0, %xmm8
+ movdqa %xmm1, %xmm9
+
+ pand %xmm6, %xmm8
+ pand %xmm6, %xmm9
+ movdqa %xmm2, %xmm10
+ pcmpeqb %xmm0, %xmm8
+ psllq \$4, %xmm0 # 0x10...
+ movdqa %xmm3, %xmm11
+ pcmpeqb %xmm1, %xmm9
+ psllq \$4, %xmm1 # 0x20...
+
+ pand %xmm6, %xmm10
+ pand %xmm6, %xmm11
+ movdqa %xmm0, %xmm12
+ pcmpeqb %xmm2, %xmm10
+ psllq \$4, %xmm2 # 0x40...
+ movdqa %xmm1, %xmm13
+ pcmpeqb %xmm3, %xmm11
+ psllq \$4, %xmm3 # 0x80...
+
+ movdqa %xmm2, %xmm14
+ movdqa %xmm3, %xmm15
+ pxor %xmm5, %xmm8 # "pnot"
+ pxor %xmm5, %xmm9
+
+ pand %xmm6, %xmm12
+ pand %xmm6, %xmm13
+ movdqa %xmm8, 0x00($out) # write bit-sliced round key
+ pcmpeqb %xmm0, %xmm12
+ psrlq \$4, %xmm0 # 0x01...
+ movdqa %xmm9, 0x10($out)
+ pcmpeqb %xmm1, %xmm13
+ psrlq \$4, %xmm1 # 0x02...
+ lea 0x10($inp), $inp
+
+ pand %xmm6, %xmm14
+ pand %xmm6, %xmm15
+ movdqa %xmm10, 0x20($out)
+ pcmpeqb %xmm2, %xmm14
+ psrlq \$4, %xmm2 # 0x04...
+ movdqa %xmm11, 0x30($out)
+ pcmpeqb %xmm3, %xmm15
+ psrlq \$4, %xmm3 # 0x08...
+ movdqu ($inp), %xmm6 # load next round key
+
+ pxor %xmm5, %xmm13 # "pnot"
+ pxor %xmm5, %xmm14
+ movdqa %xmm12, 0x40($out)
+ movdqa %xmm13, 0x50($out)
+ movdqa %xmm14, 0x60($out)
+ movdqa %xmm15, 0x70($out)
+ lea 0x80($out),$out
+ dec $rounds
+ jnz .Lkey_loop
+
+ movdqa 0x50($const), %xmm7 # .L63
+ #movdqa %xmm6, ($out) # don't save last round key
+ ret
+.size _bsaes_key_convert,.-_bsaes_key_convert
+___
+}
+
+if (0 && !$win64) { # following four functions are unsupported interface
+ # used for benchmarking...
+$code.=<<___;
+.globl bsaes_enc_key_convert
+.type bsaes_enc_key_convert,\@function,2
+.align 16
+bsaes_enc_key_convert:
+ mov 240($inp),%r10d # pass rounds
+ mov $inp,%rcx # pass key
+ mov $out,%rax # pass key schedule
+ call _bsaes_key_convert
+ pxor %xmm6,%xmm7 # fix up last round key
+ movdqa %xmm7,(%rax) # save last round key
+ ret
+.size bsaes_enc_key_convert,.-bsaes_enc_key_convert
+
+.globl bsaes_encrypt_128
+.type bsaes_encrypt_128,\@function,4
+.align 16
+bsaes_encrypt_128:
+.Lenc128_loop:
+ movdqu 0x00($inp), @XMM[0] # load input
+ movdqu 0x10($inp), @XMM[1]
+ movdqu 0x20($inp), @XMM[2]
+ movdqu 0x30($inp), @XMM[3]
+ movdqu 0x40($inp), @XMM[4]
+ movdqu 0x50($inp), @XMM[5]
+ movdqu 0x60($inp), @XMM[6]
+ movdqu 0x70($inp), @XMM[7]
+ mov $key, %rax # pass the $key
+ lea 0x80($inp), $inp
+ mov \$10,%r10d
+
+ call _bsaes_encrypt8
+
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[4], 0x20($out)
+ movdqu @XMM[6], 0x30($out)
+ movdqu @XMM[3], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ movdqu @XMM[2], 0x60($out)
+ movdqu @XMM[5], 0x70($out)
+ lea 0x80($out), $out
+ sub \$0x80,$len
+ ja .Lenc128_loop
+ ret
+.size bsaes_encrypt_128,.-bsaes_encrypt_128
+
+.globl bsaes_dec_key_convert
+.type bsaes_dec_key_convert,\@function,2
+.align 16
+bsaes_dec_key_convert:
+ mov 240($inp),%r10d # pass rounds
+ mov $inp,%rcx # pass key
+ mov $out,%rax # pass key schedule
+ call _bsaes_key_convert
+ pxor ($out),%xmm7 # fix up round 0 key
+ movdqa %xmm6,(%rax) # save last round key
+ movdqa %xmm7,($out)
+ ret
+.size bsaes_dec_key_convert,.-bsaes_dec_key_convert
+
+.globl bsaes_decrypt_128
+.type bsaes_decrypt_128,\@function,4
+.align 16
+bsaes_decrypt_128:
+.Ldec128_loop:
+ movdqu 0x00($inp), @XMM[0] # load input
+ movdqu 0x10($inp), @XMM[1]
+ movdqu 0x20($inp), @XMM[2]
+ movdqu 0x30($inp), @XMM[3]
+ movdqu 0x40($inp), @XMM[4]
+ movdqu 0x50($inp), @XMM[5]
+ movdqu 0x60($inp), @XMM[6]
+ movdqu 0x70($inp), @XMM[7]
+ mov $key, %rax # pass the $key
+ lea 0x80($inp), $inp
+ mov \$10,%r10d
+
+ call _bsaes_decrypt8
+
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ movdqu @XMM[2], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ movdqu @XMM[3], 0x60($out)
+ movdqu @XMM[5], 0x70($out)
+ lea 0x80($out), $out
+ sub \$0x80,$len
+ ja .Ldec128_loop
+ ret
+.size bsaes_decrypt_128,.-bsaes_decrypt_128
+___
+}
+{
+######################################################################
+#
+# OpenSSL interface
+#
+my ($arg1,$arg2,$arg3,$arg4,$arg5,$arg6)=$win64 ? ("%rcx","%rdx","%r8","%r9","%r10","%r11d")
+ : ("%rdi","%rsi","%rdx","%rcx","%r8","%r9d");
+my ($inp,$out,$len,$key)=("%r12","%r13","%r14","%r15");
+
+if ($ecb) {
+$code.=<<___;
+.globl bsaes_ecb_encrypt_blocks
+.type bsaes_ecb_encrypt_blocks,\@abi-omnipotent
+.align 16
+bsaes_ecb_encrypt_blocks:
+ mov %rsp, %rax
+.Lecb_enc_prologue:
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ lea -0x48(%rsp),%rsp
+___
+$code.=<<___ if ($win64);
+ lea -0xa0(%rsp), %rsp
+ movaps %xmm6, 0x40(%rsp)
+ movaps %xmm7, 0x50(%rsp)
+ movaps %xmm8, 0x60(%rsp)
+ movaps %xmm9, 0x70(%rsp)
+ movaps %xmm10, 0x80(%rsp)
+ movaps %xmm11, 0x90(%rsp)
+ movaps %xmm12, 0xa0(%rsp)
+ movaps %xmm13, 0xb0(%rsp)
+ movaps %xmm14, 0xc0(%rsp)
+ movaps %xmm15, 0xd0(%rsp)
+.Lecb_enc_body:
+___
+$code.=<<___;
+ mov %rsp,%rbp # backup %rsp
+ mov 240($arg4),%eax # rounds
+ mov $arg1,$inp # backup arguments
+ mov $arg2,$out
+ mov $arg3,$len
+ mov $arg4,$key
+ cmp \$8,$arg3
+ jb .Lecb_enc_short
+
+ mov %eax,%ebx # backup rounds
+ shl \$7,%rax # 128 bytes per inner round key
+ sub \$`128-32`,%rax # size of bit-sliced key schedule
+ sub %rax,%rsp
+ mov %rsp,%rax # pass key schedule
+ mov $key,%rcx # pass key
+ mov %ebx,%r10d # pass rounds
+ call _bsaes_key_convert
+ pxor %xmm6,%xmm7 # fix up last round key
+ movdqa %xmm7,(%rax) # save last round key
+
+ sub \$8,$len
+.Lecb_enc_loop:
+ movdqu 0x00($inp), @XMM[0] # load input
+ movdqu 0x10($inp), @XMM[1]
+ movdqu 0x20($inp), @XMM[2]
+ movdqu 0x30($inp), @XMM[3]
+ movdqu 0x40($inp), @XMM[4]
+ movdqu 0x50($inp), @XMM[5]
+ mov %rsp, %rax # pass key schedule
+ movdqu 0x60($inp), @XMM[6]
+ mov %ebx,%r10d # pass rounds
+ movdqu 0x70($inp), @XMM[7]
+ lea 0x80($inp), $inp
+
+ call _bsaes_encrypt8
+
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[4], 0x20($out)
+ movdqu @XMM[6], 0x30($out)
+ movdqu @XMM[3], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ movdqu @XMM[2], 0x60($out)
+ movdqu @XMM[5], 0x70($out)
+ lea 0x80($out), $out
+ sub \$8,$len
+ jnc .Lecb_enc_loop
+
+ add \$8,$len
+ jz .Lecb_enc_done
+
+ movdqu 0x00($inp), @XMM[0] # load input
+ mov %rsp, %rax # pass key schedule
+ mov %ebx,%r10d # pass rounds
+ cmp \$2,$len
+ jb .Lecb_enc_one
+ movdqu 0x10($inp), @XMM[1]
+ je .Lecb_enc_two
+ movdqu 0x20($inp), @XMM[2]
+ cmp \$4,$len
+ jb .Lecb_enc_three
+ movdqu 0x30($inp), @XMM[3]
+ je .Lecb_enc_four
+ movdqu 0x40($inp), @XMM[4]
+ cmp \$6,$len
+ jb .Lecb_enc_five
+ movdqu 0x50($inp), @XMM[5]
+ je .Lecb_enc_six
+ movdqu 0x60($inp), @XMM[6]
+ call _bsaes_encrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[4], 0x20($out)
+ movdqu @XMM[6], 0x30($out)
+ movdqu @XMM[3], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ movdqu @XMM[2], 0x60($out)
+ jmp .Lecb_enc_done
+.align 16
+.Lecb_enc_six:
+ call _bsaes_encrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[4], 0x20($out)
+ movdqu @XMM[6], 0x30($out)
+ movdqu @XMM[3], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ jmp .Lecb_enc_done
+.align 16
+.Lecb_enc_five:
+ call _bsaes_encrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[4], 0x20($out)
+ movdqu @XMM[6], 0x30($out)
+ movdqu @XMM[3], 0x40($out)
+ jmp .Lecb_enc_done
+.align 16
+.Lecb_enc_four:
+ call _bsaes_encrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[4], 0x20($out)
+ movdqu @XMM[6], 0x30($out)
+ jmp .Lecb_enc_done
+.align 16
+.Lecb_enc_three:
+ call _bsaes_encrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[4], 0x20($out)
+ jmp .Lecb_enc_done
+.align 16
+.Lecb_enc_two:
+ call _bsaes_encrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ jmp .Lecb_enc_done
+.align 16
+.Lecb_enc_one:
+ call _bsaes_encrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ jmp .Lecb_enc_done
+.align 16
+.Lecb_enc_short:
+ lea ($inp), $arg1
+ lea ($out), $arg2
+ lea ($key), $arg3
+ call asm_AES_encrypt
+ lea 16($inp), $inp
+ lea 16($out), $out
+ dec $len
+ jnz .Lecb_enc_short
+
+.Lecb_enc_done:
+ lea (%rsp),%rax
+ pxor %xmm0, %xmm0
+.Lecb_enc_bzero: # wipe key schedule [if any]
+ movdqa %xmm0, 0x00(%rax)
+ movdqa %xmm0, 0x10(%rax)
+ lea 0x20(%rax), %rax
+ cmp %rax, %rbp
+ jb .Lecb_enc_bzero
+
+ lea (%rbp),%rsp # restore %rsp
+___
+$code.=<<___ if ($win64);
+ movaps 0x40(%rbp), %xmm6
+ movaps 0x50(%rbp), %xmm7
+ movaps 0x60(%rbp), %xmm8
+ movaps 0x70(%rbp), %xmm9
+ movaps 0x80(%rbp), %xmm10
+ movaps 0x90(%rbp), %xmm11
+ movaps 0xa0(%rbp), %xmm12
+ movaps 0xb0(%rbp), %xmm13
+ movaps 0xc0(%rbp), %xmm14
+ movaps 0xd0(%rbp), %xmm15
+ lea 0xa0(%rbp), %rsp
+___
+$code.=<<___;
+ mov 0x48(%rsp), %r15
+ mov 0x50(%rsp), %r14
+ mov 0x58(%rsp), %r13
+ mov 0x60(%rsp), %r12
+ mov 0x68(%rsp), %rbx
+ mov 0x70(%rsp), %rax
+ lea 0x78(%rsp), %rsp
+ mov %rax, %rbp
+.Lecb_enc_epilogue:
+ ret
+.size bsaes_ecb_encrypt_blocks,.-bsaes_ecb_encrypt_blocks
+
+.globl bsaes_ecb_decrypt_blocks
+.type bsaes_ecb_decrypt_blocks,\@abi-omnipotent
+.align 16
+bsaes_ecb_decrypt_blocks:
+ mov %rsp, %rax
+.Lecb_dec_prologue:
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ lea -0x48(%rsp),%rsp
+___
+$code.=<<___ if ($win64);
+ lea -0xa0(%rsp), %rsp
+ movaps %xmm6, 0x40(%rsp)
+ movaps %xmm7, 0x50(%rsp)
+ movaps %xmm8, 0x60(%rsp)
+ movaps %xmm9, 0x70(%rsp)
+ movaps %xmm10, 0x80(%rsp)
+ movaps %xmm11, 0x90(%rsp)
+ movaps %xmm12, 0xa0(%rsp)
+ movaps %xmm13, 0xb0(%rsp)
+ movaps %xmm14, 0xc0(%rsp)
+ movaps %xmm15, 0xd0(%rsp)
+.Lecb_dec_body:
+___
+$code.=<<___;
+ mov %rsp,%rbp # backup %rsp
+ mov 240($arg4),%eax # rounds
+ mov $arg1,$inp # backup arguments
+ mov $arg2,$out
+ mov $arg3,$len
+ mov $arg4,$key
+ cmp \$8,$arg3
+ jb .Lecb_dec_short
+
+ mov %eax,%ebx # backup rounds
+ shl \$7,%rax # 128 bytes per inner round key
+ sub \$`128-32`,%rax # size of bit-sliced key schedule
+ sub %rax,%rsp
+ mov %rsp,%rax # pass key schedule
+ mov $key,%rcx # pass key
+ mov %ebx,%r10d # pass rounds
+ call _bsaes_key_convert
+ pxor (%rsp),%xmm7 # fix up 0 round key
+ movdqa %xmm6,(%rax) # save last round key
+ movdqa %xmm7,(%rsp)
+
+ sub \$8,$len
+.Lecb_dec_loop:
+ movdqu 0x00($inp), @XMM[0] # load input
+ movdqu 0x10($inp), @XMM[1]
+ movdqu 0x20($inp), @XMM[2]
+ movdqu 0x30($inp), @XMM[3]
+ movdqu 0x40($inp), @XMM[4]
+ movdqu 0x50($inp), @XMM[5]
+ mov %rsp, %rax # pass key schedule
+ movdqu 0x60($inp), @XMM[6]
+ mov %ebx,%r10d # pass rounds
+ movdqu 0x70($inp), @XMM[7]
+ lea 0x80($inp), $inp
+
+ call _bsaes_decrypt8
+
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ movdqu @XMM[2], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ movdqu @XMM[3], 0x60($out)
+ movdqu @XMM[5], 0x70($out)
+ lea 0x80($out), $out
+ sub \$8,$len
+ jnc .Lecb_dec_loop
+
+ add \$8,$len
+ jz .Lecb_dec_done
+
+ movdqu 0x00($inp), @XMM[0] # load input
+ mov %rsp, %rax # pass key schedule
+ mov %ebx,%r10d # pass rounds
+ cmp \$2,$len
+ jb .Lecb_dec_one
+ movdqu 0x10($inp), @XMM[1]
+ je .Lecb_dec_two
+ movdqu 0x20($inp), @XMM[2]
+ cmp \$4,$len
+ jb .Lecb_dec_three
+ movdqu 0x30($inp), @XMM[3]
+ je .Lecb_dec_four
+ movdqu 0x40($inp), @XMM[4]
+ cmp \$6,$len
+ jb .Lecb_dec_five
+ movdqu 0x50($inp), @XMM[5]
+ je .Lecb_dec_six
+ movdqu 0x60($inp), @XMM[6]
+ call _bsaes_decrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ movdqu @XMM[2], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ movdqu @XMM[3], 0x60($out)
+ jmp .Lecb_dec_done
+.align 16
+.Lecb_dec_six:
+ call _bsaes_decrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ movdqu @XMM[2], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ jmp .Lecb_dec_done
+.align 16
+.Lecb_dec_five:
+ call _bsaes_decrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ movdqu @XMM[2], 0x40($out)
+ jmp .Lecb_dec_done
+.align 16
+.Lecb_dec_four:
+ call _bsaes_decrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ jmp .Lecb_dec_done
+.align 16
+.Lecb_dec_three:
+ call _bsaes_decrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ jmp .Lecb_dec_done
+.align 16
+.Lecb_dec_two:
+ call _bsaes_decrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ jmp .Lecb_dec_done
+.align 16
+.Lecb_dec_one:
+ call _bsaes_decrypt8
+ movdqu @XMM[0], 0x00($out) # write output
+ jmp .Lecb_dec_done
+.align 16
+.Lecb_dec_short:
+ lea ($inp), $arg1
+ lea ($out), $arg2
+ lea ($key), $arg3
+ call asm_AES_decrypt
+ lea 16($inp), $inp
+ lea 16($out), $out
+ dec $len
+ jnz .Lecb_dec_short
+
+.Lecb_dec_done:
+ lea (%rsp),%rax
+ pxor %xmm0, %xmm0
+.Lecb_dec_bzero: # wipe key schedule [if any]
+ movdqa %xmm0, 0x00(%rax)
+ movdqa %xmm0, 0x10(%rax)
+ lea 0x20(%rax), %rax
+ cmp %rax, %rbp
+ jb .Lecb_dec_bzero
+
+ lea (%rbp),%rsp # restore %rsp
+___
+$code.=<<___ if ($win64);
+ movaps 0x40(%rbp), %xmm6
+ movaps 0x50(%rbp), %xmm7
+ movaps 0x60(%rbp), %xmm8
+ movaps 0x70(%rbp), %xmm9
+ movaps 0x80(%rbp), %xmm10
+ movaps 0x90(%rbp), %xmm11
+ movaps 0xa0(%rbp), %xmm12
+ movaps 0xb0(%rbp), %xmm13
+ movaps 0xc0(%rbp), %xmm14
+ movaps 0xd0(%rbp), %xmm15
+ lea 0xa0(%rbp), %rsp
+___
+$code.=<<___;
+ mov 0x48(%rsp), %r15
+ mov 0x50(%rsp), %r14
+ mov 0x58(%rsp), %r13
+ mov 0x60(%rsp), %r12
+ mov 0x68(%rsp), %rbx
+ mov 0x70(%rsp), %rax
+ lea 0x78(%rsp), %rsp
+ mov %rax, %rbp
+.Lecb_dec_epilogue:
+ ret
+.size bsaes_ecb_decrypt_blocks,.-bsaes_ecb_decrypt_blocks
+___
+}
+$code.=<<___;
+.extern asm_AES_cbc_encrypt
+.globl bsaes_cbc_encrypt
+.type bsaes_cbc_encrypt,\@abi-omnipotent
+.align 16
+bsaes_cbc_encrypt:
+___
+$code.=<<___ if ($win64);
+ mov 48(%rsp),$arg6 # pull direction flag
+___
+$code.=<<___;
+ cmp \$0,$arg6
+ jne asm_AES_cbc_encrypt
+ cmp \$128,$arg3
+ jb asm_AES_cbc_encrypt
+
+ mov %rsp, %rax
+.Lcbc_dec_prologue:
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ lea -0x48(%rsp), %rsp
+___
+$code.=<<___ if ($win64);
+ mov 0xa0(%rsp),$arg5 # pull ivp
+ lea -0xa0(%rsp), %rsp
+ movaps %xmm6, 0x40(%rsp)
+ movaps %xmm7, 0x50(%rsp)
+ movaps %xmm8, 0x60(%rsp)
+ movaps %xmm9, 0x70(%rsp)
+ movaps %xmm10, 0x80(%rsp)
+ movaps %xmm11, 0x90(%rsp)
+ movaps %xmm12, 0xa0(%rsp)
+ movaps %xmm13, 0xb0(%rsp)
+ movaps %xmm14, 0xc0(%rsp)
+ movaps %xmm15, 0xd0(%rsp)
+.Lcbc_dec_body:
+___
+$code.=<<___;
+ mov %rsp, %rbp # backup %rsp
+ mov 240($arg4), %eax # rounds
+ mov $arg1, $inp # backup arguments
+ mov $arg2, $out
+ mov $arg3, $len
+ mov $arg4, $key
+ mov $arg5, %rbx
+ shr \$4, $len # bytes to blocks
+
+ mov %eax, %edx # rounds
+ shl \$7, %rax # 128 bytes per inner round key
+ sub \$`128-32`, %rax # size of bit-sliced key schedule
+ sub %rax, %rsp
+
+ mov %rsp, %rax # pass key schedule
+ mov $key, %rcx # pass key
+ mov %edx, %r10d # pass rounds
+ call _bsaes_key_convert
+ pxor (%rsp),%xmm7 # fix up 0 round key
+ movdqa %xmm6,(%rax) # save last round key
+ movdqa %xmm7,(%rsp)
+
+ movdqu (%rbx), @XMM[15] # load IV
+ sub \$8,$len
+.Lcbc_dec_loop:
+ movdqu 0x00($inp), @XMM[0] # load input
+ movdqu 0x10($inp), @XMM[1]
+ movdqu 0x20($inp), @XMM[2]
+ movdqu 0x30($inp), @XMM[3]
+ movdqu 0x40($inp), @XMM[4]
+ movdqu 0x50($inp), @XMM[5]
+ mov %rsp, %rax # pass key schedule
+ movdqu 0x60($inp), @XMM[6]
+ mov %edx,%r10d # pass rounds
+ movdqu 0x70($inp), @XMM[7]
+ movdqa @XMM[15], 0x20(%rbp) # put aside IV
+
+ call _bsaes_decrypt8
+
+ pxor 0x20(%rbp), @XMM[0] # ^= IV
+ movdqu 0x00($inp), @XMM[8] # re-load input
+ movdqu 0x10($inp), @XMM[9]
+ pxor @XMM[8], @XMM[1]
+ movdqu 0x20($inp), @XMM[10]
+ pxor @XMM[9], @XMM[6]
+ movdqu 0x30($inp), @XMM[11]
+ pxor @XMM[10], @XMM[4]
+ movdqu 0x40($inp), @XMM[12]
+ pxor @XMM[11], @XMM[2]
+ movdqu 0x50($inp), @XMM[13]
+ pxor @XMM[12], @XMM[7]
+ movdqu 0x60($inp), @XMM[14]
+ pxor @XMM[13], @XMM[3]
+ movdqu 0x70($inp), @XMM[15] # IV
+ pxor @XMM[14], @XMM[5]
+ movdqu @XMM[0], 0x00($out) # write output
+ lea 0x80($inp), $inp
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ movdqu @XMM[2], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ movdqu @XMM[3], 0x60($out)
+ movdqu @XMM[5], 0x70($out)
+ lea 0x80($out), $out
+ sub \$8,$len
+ jnc .Lcbc_dec_loop
+
+ add \$8,$len
+ jz .Lcbc_dec_done
+
+ movdqu 0x00($inp), @XMM[0] # load input
+ mov %rsp, %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+ cmp \$2,$len
+ jb .Lcbc_dec_one
+ movdqu 0x10($inp), @XMM[1]
+ je .Lcbc_dec_two
+ movdqu 0x20($inp), @XMM[2]
+ cmp \$4,$len
+ jb .Lcbc_dec_three
+ movdqu 0x30($inp), @XMM[3]
+ je .Lcbc_dec_four
+ movdqu 0x40($inp), @XMM[4]
+ cmp \$6,$len
+ jb .Lcbc_dec_five
+ movdqu 0x50($inp), @XMM[5]
+ je .Lcbc_dec_six
+ movdqu 0x60($inp), @XMM[6]
+ movdqa @XMM[15], 0x20(%rbp) # put aside IV
+ call _bsaes_decrypt8
+ pxor 0x20(%rbp), @XMM[0] # ^= IV
+ movdqu 0x00($inp), @XMM[8] # re-load input
+ movdqu 0x10($inp), @XMM[9]
+ pxor @XMM[8], @XMM[1]
+ movdqu 0x20($inp), @XMM[10]
+ pxor @XMM[9], @XMM[6]
+ movdqu 0x30($inp), @XMM[11]
+ pxor @XMM[10], @XMM[4]
+ movdqu 0x40($inp), @XMM[12]
+ pxor @XMM[11], @XMM[2]
+ movdqu 0x50($inp), @XMM[13]
+ pxor @XMM[12], @XMM[7]
+ movdqu 0x60($inp), @XMM[15] # IV
+ pxor @XMM[13], @XMM[3]
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ movdqu @XMM[2], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ movdqu @XMM[3], 0x60($out)
+ jmp .Lcbc_dec_done
+.align 16
+.Lcbc_dec_six:
+ movdqa @XMM[15], 0x20(%rbp) # put aside IV
+ call _bsaes_decrypt8
+ pxor 0x20(%rbp), @XMM[0] # ^= IV
+ movdqu 0x00($inp), @XMM[8] # re-load input
+ movdqu 0x10($inp), @XMM[9]
+ pxor @XMM[8], @XMM[1]
+ movdqu 0x20($inp), @XMM[10]
+ pxor @XMM[9], @XMM[6]
+ movdqu 0x30($inp), @XMM[11]
+ pxor @XMM[10], @XMM[4]
+ movdqu 0x40($inp), @XMM[12]
+ pxor @XMM[11], @XMM[2]
+ movdqu 0x50($inp), @XMM[15] # IV
+ pxor @XMM[12], @XMM[7]
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ movdqu @XMM[2], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ jmp .Lcbc_dec_done
+.align 16
+.Lcbc_dec_five:
+ movdqa @XMM[15], 0x20(%rbp) # put aside IV
+ call _bsaes_decrypt8
+ pxor 0x20(%rbp), @XMM[0] # ^= IV
+ movdqu 0x00($inp), @XMM[8] # re-load input
+ movdqu 0x10($inp), @XMM[9]
+ pxor @XMM[8], @XMM[1]
+ movdqu 0x20($inp), @XMM[10]
+ pxor @XMM[9], @XMM[6]
+ movdqu 0x30($inp), @XMM[11]
+ pxor @XMM[10], @XMM[4]
+ movdqu 0x40($inp), @XMM[15] # IV
+ pxor @XMM[11], @XMM[2]
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ movdqu @XMM[2], 0x40($out)
+ jmp .Lcbc_dec_done
+.align 16
+.Lcbc_dec_four:
+ movdqa @XMM[15], 0x20(%rbp) # put aside IV
+ call _bsaes_decrypt8
+ pxor 0x20(%rbp), @XMM[0] # ^= IV
+ movdqu 0x00($inp), @XMM[8] # re-load input
+ movdqu 0x10($inp), @XMM[9]
+ pxor @XMM[8], @XMM[1]
+ movdqu 0x20($inp), @XMM[10]
+ pxor @XMM[9], @XMM[6]
+ movdqu 0x30($inp), @XMM[15] # IV
+ pxor @XMM[10], @XMM[4]
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ jmp .Lcbc_dec_done
+.align 16
+.Lcbc_dec_three:
+ movdqa @XMM[15], 0x20(%rbp) # put aside IV
+ call _bsaes_decrypt8
+ pxor 0x20(%rbp), @XMM[0] # ^= IV
+ movdqu 0x00($inp), @XMM[8] # re-load input
+ movdqu 0x10($inp), @XMM[9]
+ pxor @XMM[8], @XMM[1]
+ movdqu 0x20($inp), @XMM[15] # IV
+ pxor @XMM[9], @XMM[6]
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ jmp .Lcbc_dec_done
+.align 16
+.Lcbc_dec_two:
+ movdqa @XMM[15], 0x20(%rbp) # put aside IV
+ call _bsaes_decrypt8
+ pxor 0x20(%rbp), @XMM[0] # ^= IV
+ movdqu 0x00($inp), @XMM[8] # re-load input
+ movdqu 0x10($inp), @XMM[15] # IV
+ pxor @XMM[8], @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ jmp .Lcbc_dec_done
+.align 16
+.Lcbc_dec_one:
+ lea ($inp), $arg1
+ lea 0x20(%rbp), $arg2 # buffer output
+ lea ($key), $arg3
+ call asm_AES_decrypt # doesn't touch %xmm
+ pxor 0x20(%rbp), @XMM[15] # ^= IV
+ movdqu @XMM[15], ($out) # write output
+ movdqa @XMM[0], @XMM[15] # IV
+
+.Lcbc_dec_done:
+ movdqu @XMM[15], (%rbx) # return IV
+ lea (%rsp), %rax
+ pxor %xmm0, %xmm0
+.Lcbc_dec_bzero: # wipe key schedule [if any]
+ movdqa %xmm0, 0x00(%rax)
+ movdqa %xmm0, 0x10(%rax)
+ lea 0x20(%rax), %rax
+ cmp %rax, %rbp
+ ja .Lcbc_dec_bzero
+
+ lea (%rbp),%rsp # restore %rsp
+___
+$code.=<<___ if ($win64);
+ movaps 0x40(%rbp), %xmm6
+ movaps 0x50(%rbp), %xmm7
+ movaps 0x60(%rbp), %xmm8
+ movaps 0x70(%rbp), %xmm9
+ movaps 0x80(%rbp), %xmm10
+ movaps 0x90(%rbp), %xmm11
+ movaps 0xa0(%rbp), %xmm12
+ movaps 0xb0(%rbp), %xmm13
+ movaps 0xc0(%rbp), %xmm14
+ movaps 0xd0(%rbp), %xmm15
+ lea 0xa0(%rbp), %rsp
+___
+$code.=<<___;
+ mov 0x48(%rsp), %r15
+ mov 0x50(%rsp), %r14
+ mov 0x58(%rsp), %r13
+ mov 0x60(%rsp), %r12
+ mov 0x68(%rsp), %rbx
+ mov 0x70(%rsp), %rax
+ lea 0x78(%rsp), %rsp
+ mov %rax, %rbp
+.Lcbc_dec_epilogue:
+ ret
+.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
+
+.globl bsaes_ctr32_encrypt_blocks
+.type bsaes_ctr32_encrypt_blocks,\@abi-omnipotent
+.align 16
+bsaes_ctr32_encrypt_blocks:
+ mov %rsp, %rax
+.Lctr_enc_prologue:
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ lea -0x48(%rsp), %rsp
+___
+$code.=<<___ if ($win64);
+ mov 0xa0(%rsp),$arg5 # pull ivp
+ lea -0xa0(%rsp), %rsp
+ movaps %xmm6, 0x40(%rsp)
+ movaps %xmm7, 0x50(%rsp)
+ movaps %xmm8, 0x60(%rsp)
+ movaps %xmm9, 0x70(%rsp)
+ movaps %xmm10, 0x80(%rsp)
+ movaps %xmm11, 0x90(%rsp)
+ movaps %xmm12, 0xa0(%rsp)
+ movaps %xmm13, 0xb0(%rsp)
+ movaps %xmm14, 0xc0(%rsp)
+ movaps %xmm15, 0xd0(%rsp)
+.Lctr_enc_body:
+___
+$code.=<<___;
+ mov %rsp, %rbp # backup %rsp
+ movdqu ($arg5), %xmm0 # load counter
+ mov 240($arg4), %eax # rounds
+ mov $arg1, $inp # backup arguments
+ mov $arg2, $out
+ mov $arg3, $len
+ mov $arg4, $key
+ movdqa %xmm0, 0x20(%rbp) # copy counter
+ cmp \$8, $arg3
+ jb .Lctr_enc_short
+
+ mov %eax, %ebx # rounds
+ shl \$7, %rax # 128 bytes per inner round key
+ sub \$`128-32`, %rax # size of bit-sliced key schedule
+ sub %rax, %rsp
+
+ mov %rsp, %rax # pass key schedule
+ mov $key, %rcx # pass key
+ mov %ebx, %r10d # pass rounds
+ call _bsaes_key_convert
+ pxor %xmm6,%xmm7 # fix up last round key
+ movdqa %xmm7,(%rax) # save last round key
+
+ movdqa (%rsp), @XMM[9] # load round0 key
+ lea .LADD1(%rip), %r11
+ movdqa 0x20(%rbp), @XMM[0] # counter copy
+ movdqa -0x20(%r11), @XMM[8] # .LSWPUP
+ pshufb @XMM[8], @XMM[9] # byte swap upper part
+ pshufb @XMM[8], @XMM[0]
+ movdqa @XMM[9], (%rsp) # save adjusted round0 key
+ jmp .Lctr_enc_loop
+.align 16
+.Lctr_enc_loop:
+ movdqa @XMM[0], 0x20(%rbp) # save counter
+ movdqa @XMM[0], @XMM[1] # prepare 8 counter values
+ movdqa @XMM[0], @XMM[2]
+ paddd 0x00(%r11), @XMM[1] # .LADD1
+ movdqa @XMM[0], @XMM[3]
+ paddd 0x10(%r11), @XMM[2] # .LADD2
+ movdqa @XMM[0], @XMM[4]
+ paddd 0x20(%r11), @XMM[3] # .LADD3
+ movdqa @XMM[0], @XMM[5]
+ paddd 0x30(%r11), @XMM[4] # .LADD4
+ movdqa @XMM[0], @XMM[6]
+ paddd 0x40(%r11), @XMM[5] # .LADD5
+ movdqa @XMM[0], @XMM[7]
+ paddd 0x50(%r11), @XMM[6] # .LADD6
+ paddd 0x60(%r11), @XMM[7] # .LADD7
+
+ # Borrow prologue from _bsaes_encrypt8 to use the opportunity
+ # to flip byte order in 32-bit counter
+ movdqa (%rsp), @XMM[9] # round 0 key
+ lea 0x10(%rsp), %rax # pass key schedule
+ movdqa -0x10(%r11), @XMM[8] # .LSWPUPM0SR
+ pxor @XMM[9], @XMM[0] # xor with round0 key
+ pxor @XMM[9], @XMM[1]
+ pshufb @XMM[8], @XMM[0]
+ pxor @XMM[9], @XMM[2]
+ pshufb @XMM[8], @XMM[1]
+ pxor @XMM[9], @XMM[3]
+ pshufb @XMM[8], @XMM[2]
+ pxor @XMM[9], @XMM[4]
+ pshufb @XMM[8], @XMM[3]
+ pxor @XMM[9], @XMM[5]
+ pshufb @XMM[8], @XMM[4]
+ pxor @XMM[9], @XMM[6]
+ pshufb @XMM[8], @XMM[5]
+ pxor @XMM[9], @XMM[7]
+ pshufb @XMM[8], @XMM[6]
+ lea .LBS0(%rip), %r11 # constants table
+ pshufb @XMM[8], @XMM[7]
+ mov %ebx,%r10d # pass rounds
+
+ call _bsaes_encrypt8_bitslice
+
+ sub \$8,$len
+ jc .Lctr_enc_loop_done
+
+ movdqu 0x00($inp), @XMM[8] # load input
+ movdqu 0x10($inp), @XMM[9]
+ movdqu 0x20($inp), @XMM[10]
+ movdqu 0x30($inp), @XMM[11]
+ movdqu 0x40($inp), @XMM[12]
+ movdqu 0x50($inp), @XMM[13]
+ movdqu 0x60($inp), @XMM[14]
+ movdqu 0x70($inp), @XMM[15]
+ lea 0x80($inp),$inp
+ pxor @XMM[0], @XMM[8]
+ movdqa 0x20(%rbp), @XMM[0] # load counter
+ pxor @XMM[9], @XMM[1]
+ movdqu @XMM[8], 0x00($out) # write output
+ pxor @XMM[10], @XMM[4]
+ movdqu @XMM[1], 0x10($out)
+ pxor @XMM[11], @XMM[6]
+ movdqu @XMM[4], 0x20($out)
+ pxor @XMM[12], @XMM[3]
+ movdqu @XMM[6], 0x30($out)
+ pxor @XMM[13], @XMM[7]
+ movdqu @XMM[3], 0x40($out)
+ pxor @XMM[14], @XMM[2]
+ movdqu @XMM[7], 0x50($out)
+ pxor @XMM[15], @XMM[5]
+ movdqu @XMM[2], 0x60($out)
+ lea .LADD1(%rip), %r11
+ movdqu @XMM[5], 0x70($out)
+ lea 0x80($out), $out
+ paddd 0x70(%r11), @XMM[0] # .LADD8
+ jnz .Lctr_enc_loop
+
+ jmp .Lctr_enc_done
+.align 16
+.Lctr_enc_loop_done:
+ add \$8, $len
+ movdqu 0x00($inp), @XMM[8] # load input
+ pxor @XMM[8], @XMM[0]
+ movdqu @XMM[0], 0x00($out) # write output
+ cmp \$2,$len
+ jb .Lctr_enc_done
+ movdqu 0x10($inp), @XMM[9]
+ pxor @XMM[9], @XMM[1]
+ movdqu @XMM[1], 0x10($out)
+ je .Lctr_enc_done
+ movdqu 0x20($inp), @XMM[10]
+ pxor @XMM[10], @XMM[4]
+ movdqu @XMM[4], 0x20($out)
+ cmp \$4,$len
+ jb .Lctr_enc_done
+ movdqu 0x30($inp), @XMM[11]
+ pxor @XMM[11], @XMM[6]
+ movdqu @XMM[6], 0x30($out)
+ je .Lctr_enc_done
+ movdqu 0x40($inp), @XMM[12]
+ pxor @XMM[12], @XMM[3]
+ movdqu @XMM[3], 0x40($out)
+ cmp \$6,$len
+ jb .Lctr_enc_done
+ movdqu 0x50($inp), @XMM[13]
+ pxor @XMM[13], @XMM[7]
+ movdqu @XMM[7], 0x50($out)
+ je .Lctr_enc_done
+ movdqu 0x60($inp), @XMM[14]
+ pxor @XMM[14], @XMM[2]
+ movdqu @XMM[2], 0x60($out)
+ jmp .Lctr_enc_done
+
+.align 16
+.Lctr_enc_short:
+ lea 0x20(%rbp), $arg1
+ lea 0x30(%rbp), $arg2
+ lea ($key), $arg3
+ call asm_AES_encrypt
+ movdqu ($inp), @XMM[1]
+ lea 16($inp), $inp
+ mov 0x2c(%rbp), %eax # load 32-bit counter
+ bswap %eax
+ pxor 0x30(%rbp), @XMM[1]
+ inc %eax # increment
+ movdqu @XMM[1], ($out)
+ bswap %eax
+ lea 16($out), $out
+ mov %eax, 0x2c(%rsp) # save 32-bit counter
+ dec $len
+ jnz .Lctr_enc_short
+
+.Lctr_enc_done:
+ lea (%rsp), %rax
+ pxor %xmm0, %xmm0
+.Lctr_enc_bzero: # wipe key schedule [if any]
+ movdqa %xmm0, 0x00(%rax)
+ movdqa %xmm0, 0x10(%rax)
+ lea 0x20(%rax), %rax
+ cmp %rax, %rbp
+ ja .Lctr_enc_bzero
+
+ lea (%rbp),%rsp # restore %rsp
+___
+$code.=<<___ if ($win64);
+ movaps 0x40(%rbp), %xmm6
+ movaps 0x50(%rbp), %xmm7
+ movaps 0x60(%rbp), %xmm8
+ movaps 0x70(%rbp), %xmm9
+ movaps 0x80(%rbp), %xmm10
+ movaps 0x90(%rbp), %xmm11
+ movaps 0xa0(%rbp), %xmm12
+ movaps 0xb0(%rbp), %xmm13
+ movaps 0xc0(%rbp), %xmm14
+ movaps 0xd0(%rbp), %xmm15
+ lea 0xa0(%rbp), %rsp
+___
+$code.=<<___;
+ mov 0x48(%rsp), %r15
+ mov 0x50(%rsp), %r14
+ mov 0x58(%rsp), %r13
+ mov 0x60(%rsp), %r12
+ mov 0x68(%rsp), %rbx
+ mov 0x70(%rsp), %rax
+ lea 0x78(%rsp), %rsp
+ mov %rax, %rbp
+.Lctr_enc_epilogue:
+ ret
+.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
+___
+######################################################################
+# void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len,
+# const AES_KEY *key1, const AES_KEY *key2,
+# const unsigned char iv[16]);
+#
+my ($twmask,$twres,$twtmp)=@XMM[13..15];
+$code.=<<___;
+.globl bsaes_xts_encrypt
+.type bsaes_xts_encrypt,\@abi-omnipotent
+.align 16
+bsaes_xts_encrypt:
+ mov %rsp, %rax
+.Lxts_enc_prologue:
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ lea -0x48(%rsp), %rsp
+___
+$code.=<<___ if ($win64);
+ mov 0xa0(%rsp),$arg5 # pull key2
+ mov 0xa8(%rsp),$arg6 # pull ivp
+ lea -0xa0(%rsp), %rsp
+ movaps %xmm6, 0x40(%rsp)
+ movaps %xmm7, 0x50(%rsp)
+ movaps %xmm8, 0x60(%rsp)
+ movaps %xmm9, 0x70(%rsp)
+ movaps %xmm10, 0x80(%rsp)
+ movaps %xmm11, 0x90(%rsp)
+ movaps %xmm12, 0xa0(%rsp)
+ movaps %xmm13, 0xb0(%rsp)
+ movaps %xmm14, 0xc0(%rsp)
+ movaps %xmm15, 0xd0(%rsp)
+.Lxts_enc_body:
+___
+$code.=<<___;
+ mov %rsp, %rbp # backup %rsp
+ mov $arg1, $inp # backup arguments
+ mov $arg2, $out
+ mov $arg3, $len
+ mov $arg4, $key
+
+ lea ($arg6), $arg1
+ lea 0x20(%rbp), $arg2
+ lea ($arg5), $arg3
+ call asm_AES_encrypt # generate initial tweak
+
+ mov 240($key), %eax # rounds
+ mov $len, %rbx # backup $len
+
+ mov %eax, %edx # rounds
+ shl \$7, %rax # 128 bytes per inner round key
+ sub \$`128-32`, %rax # size of bit-sliced key schedule
+ sub %rax, %rsp
+
+ mov %rsp, %rax # pass key schedule
+ mov $key, %rcx # pass key
+ mov %edx, %r10d # pass rounds
+ call _bsaes_key_convert
+ pxor %xmm6, %xmm7 # fix up last round key
+ movdqa %xmm7, (%rax) # save last round key
+
+ and \$-16, $len
+ sub \$0x80, %rsp # place for tweak[8]
+ movdqa 0x20(%rbp), @XMM[7] # initial tweak
+
+ pxor $twtmp, $twtmp
+ movdqa .Lxts_magic(%rip), $twmask
+ pcmpgtd @XMM[7], $twtmp # broadcast upper bits
+
+ sub \$0x80, $len
+ jc .Lxts_enc_short
+ jmp .Lxts_enc_loop
+
+.align 16
+.Lxts_enc_loop:
+___
+ for ($i=0;$i<7;$i++) {
+ $code.=<<___;
+ pshufd \$0x13, $twtmp, $twres
+ pxor $twtmp, $twtmp
+ movdqa @XMM[7], @XMM[$i]
+ movdqa @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
+ paddq @XMM[7], @XMM[7] # psllq 1,$tweak
+ pand $twmask, $twres # isolate carry and residue
+ pcmpgtd @XMM[7], $twtmp # broadcast upper bits
+ pxor $twres, @XMM[7]
+___
+ $code.=<<___ if ($i>=1);
+ movdqu `0x10*($i-1)`($inp), @XMM[8+$i-1]
+___
+ $code.=<<___ if ($i>=2);
+ pxor @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
+___
+ }
+$code.=<<___;
+ movdqu 0x60($inp), @XMM[8+6]
+ pxor @XMM[8+5], @XMM[5]
+ movdqu 0x70($inp), @XMM[8+7]
+ lea 0x80($inp), $inp
+ movdqa @XMM[7], 0x70(%rsp)
+ pxor @XMM[8+6], @XMM[6]
+ lea 0x80(%rsp), %rax # pass key schedule
+ pxor @XMM[8+7], @XMM[7]
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_encrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[4]
+ movdqu @XMM[1], 0x10($out)
+ pxor 0x30(%rsp), @XMM[6]
+ movdqu @XMM[4], 0x20($out)
+ pxor 0x40(%rsp), @XMM[3]
+ movdqu @XMM[6], 0x30($out)
+ pxor 0x50(%rsp), @XMM[7]
+ movdqu @XMM[3], 0x40($out)
+ pxor 0x60(%rsp), @XMM[2]
+ movdqu @XMM[7], 0x50($out)
+ pxor 0x70(%rsp), @XMM[5]
+ movdqu @XMM[2], 0x60($out)
+ movdqu @XMM[5], 0x70($out)
+ lea 0x80($out), $out
+
+ movdqa 0x70(%rsp), @XMM[7] # prepare next iteration tweak
+ pxor $twtmp, $twtmp
+ movdqa .Lxts_magic(%rip), $twmask
+ pcmpgtd @XMM[7], $twtmp
+ pshufd \$0x13, $twtmp, $twres
+ pxor $twtmp, $twtmp
+ paddq @XMM[7], @XMM[7] # psllq 1,$tweak
+ pand $twmask, $twres # isolate carry and residue
+ pcmpgtd @XMM[7], $twtmp # broadcast upper bits
+ pxor $twres, @XMM[7]
+
+ sub \$0x80,$len
+ jnc .Lxts_enc_loop
+
+.Lxts_enc_short:
+ add \$0x80, $len
+ jz .Lxts_enc_done
+___
+ for ($i=0;$i<7;$i++) {
+ $code.=<<___;
+ pshufd \$0x13, $twtmp, $twres
+ pxor $twtmp, $twtmp
+ movdqa @XMM[7], @XMM[$i]
+ movdqa @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
+ paddq @XMM[7], @XMM[7] # psllq 1,$tweak
+ pand $twmask, $twres # isolate carry and residue
+ pcmpgtd @XMM[7], $twtmp # broadcast upper bits
+ pxor $twres, @XMM[7]
+___
+ $code.=<<___ if ($i>=1);
+ movdqu `0x10*($i-1)`($inp), @XMM[8+$i-1]
+ cmp \$`0x10*$i`,$len
+ je .Lxts_enc_$i
+___
+ $code.=<<___ if ($i>=2);
+ pxor @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
+___
+ }
+$code.=<<___;
+ movdqu 0x60($inp), @XMM[8+6]
+ pxor @XMM[8+5], @XMM[5]
+ movdqa @XMM[7], 0x70(%rsp)
+ lea 0x70($inp), $inp
+ pxor @XMM[8+6], @XMM[6]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_encrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[4]
+ movdqu @XMM[1], 0x10($out)
+ pxor 0x30(%rsp), @XMM[6]
+ movdqu @XMM[4], 0x20($out)
+ pxor 0x40(%rsp), @XMM[3]
+ movdqu @XMM[6], 0x30($out)
+ pxor 0x50(%rsp), @XMM[7]
+ movdqu @XMM[3], 0x40($out)
+ pxor 0x60(%rsp), @XMM[2]
+ movdqu @XMM[7], 0x50($out)
+ movdqu @XMM[2], 0x60($out)
+ lea 0x70($out), $out
+
+ movdqa 0x70(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_enc_done
+.align 16
+.Lxts_enc_6:
+ pxor @XMM[8+4], @XMM[4]
+ lea 0x60($inp), $inp
+ pxor @XMM[8+5], @XMM[5]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_encrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[4]
+ movdqu @XMM[1], 0x10($out)
+ pxor 0x30(%rsp), @XMM[6]
+ movdqu @XMM[4], 0x20($out)
+ pxor 0x40(%rsp), @XMM[3]
+ movdqu @XMM[6], 0x30($out)
+ pxor 0x50(%rsp), @XMM[7]
+ movdqu @XMM[3], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ lea 0x60($out), $out
+
+ movdqa 0x60(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_enc_done
+.align 16
+.Lxts_enc_5:
+ pxor @XMM[8+3], @XMM[3]
+ lea 0x50($inp), $inp
+ pxor @XMM[8+4], @XMM[4]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_encrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[4]
+ movdqu @XMM[1], 0x10($out)
+ pxor 0x30(%rsp), @XMM[6]
+ movdqu @XMM[4], 0x20($out)
+ pxor 0x40(%rsp), @XMM[3]
+ movdqu @XMM[6], 0x30($out)
+ movdqu @XMM[3], 0x40($out)
+ lea 0x50($out), $out
+
+ movdqa 0x50(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_enc_done
+.align 16
+.Lxts_enc_4:
+ pxor @XMM[8+2], @XMM[2]
+ lea 0x40($inp), $inp
+ pxor @XMM[8+3], @XMM[3]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_encrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[4]
+ movdqu @XMM[1], 0x10($out)
+ pxor 0x30(%rsp), @XMM[6]
+ movdqu @XMM[4], 0x20($out)
+ movdqu @XMM[6], 0x30($out)
+ lea 0x40($out), $out
+
+ movdqa 0x40(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_enc_done
+.align 16
+.Lxts_enc_3:
+ pxor @XMM[8+1], @XMM[1]
+ lea 0x30($inp), $inp
+ pxor @XMM[8+2], @XMM[2]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_encrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[4]
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[4], 0x20($out)
+ lea 0x30($out), $out
+
+ movdqa 0x30(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_enc_done
+.align 16
+.Lxts_enc_2:
+ pxor @XMM[8+0], @XMM[0]
+ lea 0x20($inp), $inp
+ pxor @XMM[8+1], @XMM[1]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_encrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ lea 0x20($out), $out
+
+ movdqa 0x20(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_enc_done
+.align 16
+.Lxts_enc_1:
+ pxor @XMM[0], @XMM[8]
+ lea 0x10($inp), $inp
+ movdqa @XMM[8], 0x20(%rbp)
+ lea 0x20(%rbp), $arg1
+ lea 0x20(%rbp), $arg2
+ lea ($key), $arg3
+ call asm_AES_encrypt # doesn't touch %xmm
+ pxor 0x20(%rbp), @XMM[0] # ^= tweak[]
+ #pxor @XMM[8], @XMM[0]
+ #lea 0x80(%rsp), %rax # pass key schedule
+ #mov %edx, %r10d # pass rounds
+ #call _bsaes_encrypt8
+ #pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ movdqu @XMM[0], 0x00($out) # write output
+ lea 0x10($out), $out
+
+ movdqa 0x10(%rsp), @XMM[7] # next iteration tweak
+
+.Lxts_enc_done:
+ and \$15, %ebx
+ jz .Lxts_enc_ret
+ mov $out, %rdx
+
+.Lxts_enc_steal:
+ movzb ($inp), %eax
+ movzb -16(%rdx), %ecx
+ lea 1($inp), $inp
+ mov %al, -16(%rdx)
+ mov %cl, 0(%rdx)
+ lea 1(%rdx), %rdx
+ sub \$1,%ebx
+ jnz .Lxts_enc_steal
+
+ movdqu -16($out), @XMM[0]
+ lea 0x20(%rbp), $arg1
+ pxor @XMM[7], @XMM[0]
+ lea 0x20(%rbp), $arg2
+ movdqa @XMM[0], 0x20(%rbp)
+ lea ($key), $arg3
+ call asm_AES_encrypt # doesn't touch %xmm
+ pxor 0x20(%rbp), @XMM[7]
+ movdqu @XMM[7], -16($out)
+
+.Lxts_enc_ret:
+ lea (%rsp), %rax
+ pxor %xmm0, %xmm0
+.Lxts_enc_bzero: # wipe key schedule [if any]
+ movdqa %xmm0, 0x00(%rax)
+ movdqa %xmm0, 0x10(%rax)
+ lea 0x20(%rax), %rax
+ cmp %rax, %rbp
+ ja .Lxts_enc_bzero
+
+ lea (%rbp),%rsp # restore %rsp
+___
+$code.=<<___ if ($win64);
+ movaps 0x40(%rbp), %xmm6
+ movaps 0x50(%rbp), %xmm7
+ movaps 0x60(%rbp), %xmm8
+ movaps 0x70(%rbp), %xmm9
+ movaps 0x80(%rbp), %xmm10
+ movaps 0x90(%rbp), %xmm11
+ movaps 0xa0(%rbp), %xmm12
+ movaps 0xb0(%rbp), %xmm13
+ movaps 0xc0(%rbp), %xmm14
+ movaps 0xd0(%rbp), %xmm15
+ lea 0xa0(%rbp), %rsp
+___
+$code.=<<___;
+ mov 0x48(%rsp), %r15
+ mov 0x50(%rsp), %r14
+ mov 0x58(%rsp), %r13
+ mov 0x60(%rsp), %r12
+ mov 0x68(%rsp), %rbx
+ mov 0x70(%rsp), %rax
+ lea 0x78(%rsp), %rsp
+ mov %rax, %rbp
+.Lxts_enc_epilogue:
+ ret
+.size bsaes_xts_encrypt,.-bsaes_xts_encrypt
+
+.globl bsaes_xts_decrypt
+.type bsaes_xts_decrypt,\@abi-omnipotent
+.align 16
+bsaes_xts_decrypt:
+ mov %rsp, %rax
+.Lxts_dec_prologue:
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ lea -0x48(%rsp), %rsp
+___
+$code.=<<___ if ($win64);
+ mov 0xa0(%rsp),$arg5 # pull key2
+ mov 0xa8(%rsp),$arg6 # pull ivp
+ lea -0xa0(%rsp), %rsp
+ movaps %xmm6, 0x40(%rsp)
+ movaps %xmm7, 0x50(%rsp)
+ movaps %xmm8, 0x60(%rsp)
+ movaps %xmm9, 0x70(%rsp)
+ movaps %xmm10, 0x80(%rsp)
+ movaps %xmm11, 0x90(%rsp)
+ movaps %xmm12, 0xa0(%rsp)
+ movaps %xmm13, 0xb0(%rsp)
+ movaps %xmm14, 0xc0(%rsp)
+ movaps %xmm15, 0xd0(%rsp)
+.Lxts_dec_body:
+___
+$code.=<<___;
+ mov %rsp, %rbp # backup %rsp
+ mov $arg1, $inp # backup arguments
+ mov $arg2, $out
+ mov $arg3, $len
+ mov $arg4, $key
+
+ lea ($arg6), $arg1
+ lea 0x20(%rbp), $arg2
+ lea ($arg5), $arg3
+ call asm_AES_encrypt # generate initial tweak
+
+ mov 240($key), %eax # rounds
+ mov $len, %rbx # backup $len
+
+ mov %eax, %edx # rounds
+ shl \$7, %rax # 128 bytes per inner round key
+ sub \$`128-32`, %rax # size of bit-sliced key schedule
+ sub %rax, %rsp
+
+ mov %rsp, %rax # pass key schedule
+ mov $key, %rcx # pass key
+ mov %edx, %r10d # pass rounds
+ call _bsaes_key_convert
+ pxor (%rsp), %xmm7 # fix up round 0 key
+ movdqa %xmm6, (%rax) # save last round key
+ movdqa %xmm7, (%rsp)
+
+ xor %eax, %eax # if ($len%16) len-=16;
+ and \$-16, $len
+ test \$15, %ebx
+ setnz %al
+ shl \$4, %rax
+ sub %rax, $len
+
+ sub \$0x80, %rsp # place for tweak[8]
+ movdqa 0x20(%rbp), @XMM[7] # initial tweak
+
+ pxor $twtmp, $twtmp
+ movdqa .Lxts_magic(%rip), $twmask
+ pcmpgtd @XMM[7], $twtmp # broadcast upper bits
+
+ sub \$0x80, $len
+ jc .Lxts_dec_short
+ jmp .Lxts_dec_loop
+
+.align 16
+.Lxts_dec_loop:
+___
+ for ($i=0;$i<7;$i++) {
+ $code.=<<___;
+ pshufd \$0x13, $twtmp, $twres
+ pxor $twtmp, $twtmp
+ movdqa @XMM[7], @XMM[$i]
+ movdqa @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
+ paddq @XMM[7], @XMM[7] # psllq 1,$tweak
+ pand $twmask, $twres # isolate carry and residue
+ pcmpgtd @XMM[7], $twtmp # broadcast upper bits
+ pxor $twres, @XMM[7]
+___
+ $code.=<<___ if ($i>=1);
+ movdqu `0x10*($i-1)`($inp), @XMM[8+$i-1]
+___
+ $code.=<<___ if ($i>=2);
+ pxor @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
+___
+ }
+$code.=<<___;
+ movdqu 0x60($inp), @XMM[8+6]
+ pxor @XMM[8+5], @XMM[5]
+ movdqu 0x70($inp), @XMM[8+7]
+ lea 0x80($inp), $inp
+ movdqa @XMM[7], 0x70(%rsp)
+ pxor @XMM[8+6], @XMM[6]
+ lea 0x80(%rsp), %rax # pass key schedule
+ pxor @XMM[8+7], @XMM[7]
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_decrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[6]
+ movdqu @XMM[1], 0x10($out)
+ pxor 0x30(%rsp), @XMM[4]
+ movdqu @XMM[6], 0x20($out)
+ pxor 0x40(%rsp), @XMM[2]
+ movdqu @XMM[4], 0x30($out)
+ pxor 0x50(%rsp), @XMM[7]
+ movdqu @XMM[2], 0x40($out)
+ pxor 0x60(%rsp), @XMM[3]
+ movdqu @XMM[7], 0x50($out)
+ pxor 0x70(%rsp), @XMM[5]
+ movdqu @XMM[3], 0x60($out)
+ movdqu @XMM[5], 0x70($out)
+ lea 0x80($out), $out
+
+ movdqa 0x70(%rsp), @XMM[7] # prepare next iteration tweak
+ pxor $twtmp, $twtmp
+ movdqa .Lxts_magic(%rip), $twmask
+ pcmpgtd @XMM[7], $twtmp
+ pshufd \$0x13, $twtmp, $twres
+ pxor $twtmp, $twtmp
+ paddq @XMM[7], @XMM[7] # psllq 1,$tweak
+ pand $twmask, $twres # isolate carry and residue
+ pcmpgtd @XMM[7], $twtmp # broadcast upper bits
+ pxor $twres, @XMM[7]
+
+ sub \$0x80,$len
+ jnc .Lxts_dec_loop
+
+.Lxts_dec_short:
+ add \$0x80, $len
+ jz .Lxts_dec_done
+___
+ for ($i=0;$i<7;$i++) {
+ $code.=<<___;
+ pshufd \$0x13, $twtmp, $twres
+ pxor $twtmp, $twtmp
+ movdqa @XMM[7], @XMM[$i]
+ movdqa @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
+ paddq @XMM[7], @XMM[7] # psllq 1,$tweak
+ pand $twmask, $twres # isolate carry and residue
+ pcmpgtd @XMM[7], $twtmp # broadcast upper bits
+ pxor $twres, @XMM[7]
+___
+ $code.=<<___ if ($i>=1);
+ movdqu `0x10*($i-1)`($inp), @XMM[8+$i-1]
+ cmp \$`0x10*$i`,$len
+ je .Lxts_dec_$i
+___
+ $code.=<<___ if ($i>=2);
+ pxor @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
+___
+ }
+$code.=<<___;
+ movdqu 0x60($inp), @XMM[8+6]
+ pxor @XMM[8+5], @XMM[5]
+ movdqa @XMM[7], 0x70(%rsp)
+ lea 0x70($inp), $inp
+ pxor @XMM[8+6], @XMM[6]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_decrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[6]
+ movdqu @XMM[1], 0x10($out)
+ pxor 0x30(%rsp), @XMM[4]
+ movdqu @XMM[6], 0x20($out)
+ pxor 0x40(%rsp), @XMM[2]
+ movdqu @XMM[4], 0x30($out)
+ pxor 0x50(%rsp), @XMM[7]
+ movdqu @XMM[2], 0x40($out)
+ pxor 0x60(%rsp), @XMM[3]
+ movdqu @XMM[7], 0x50($out)
+ movdqu @XMM[3], 0x60($out)
+ lea 0x70($out), $out
+
+ movdqa 0x70(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_dec_done
+.align 16
+.Lxts_dec_6:
+ pxor @XMM[8+4], @XMM[4]
+ lea 0x60($inp), $inp
+ pxor @XMM[8+5], @XMM[5]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_decrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[6]
+ movdqu @XMM[1], 0x10($out)
+ pxor 0x30(%rsp), @XMM[4]
+ movdqu @XMM[6], 0x20($out)
+ pxor 0x40(%rsp), @XMM[2]
+ movdqu @XMM[4], 0x30($out)
+ pxor 0x50(%rsp), @XMM[7]
+ movdqu @XMM[2], 0x40($out)
+ movdqu @XMM[7], 0x50($out)
+ lea 0x60($out), $out
+
+ movdqa 0x60(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_dec_done
+.align 16
+.Lxts_dec_5:
+ pxor @XMM[8+3], @XMM[3]
+ lea 0x50($inp), $inp
+ pxor @XMM[8+4], @XMM[4]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_decrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[6]
+ movdqu @XMM[1], 0x10($out)
+ pxor 0x30(%rsp), @XMM[4]
+ movdqu @XMM[6], 0x20($out)
+ pxor 0x40(%rsp), @XMM[2]
+ movdqu @XMM[4], 0x30($out)
+ movdqu @XMM[2], 0x40($out)
+ lea 0x50($out), $out
+
+ movdqa 0x50(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_dec_done
+.align 16
+.Lxts_dec_4:
+ pxor @XMM[8+2], @XMM[2]
+ lea 0x40($inp), $inp
+ pxor @XMM[8+3], @XMM[3]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_decrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[6]
+ movdqu @XMM[1], 0x10($out)
+ pxor 0x30(%rsp), @XMM[4]
+ movdqu @XMM[6], 0x20($out)
+ movdqu @XMM[4], 0x30($out)
+ lea 0x40($out), $out
+
+ movdqa 0x40(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_dec_done
+.align 16
+.Lxts_dec_3:
+ pxor @XMM[8+1], @XMM[1]
+ lea 0x30($inp), $inp
+ pxor @XMM[8+2], @XMM[2]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_decrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ pxor 0x20(%rsp), @XMM[6]
+ movdqu @XMM[1], 0x10($out)
+ movdqu @XMM[6], 0x20($out)
+ lea 0x30($out), $out
+
+ movdqa 0x30(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_dec_done
+.align 16
+.Lxts_dec_2:
+ pxor @XMM[8+0], @XMM[0]
+ lea 0x20($inp), $inp
+ pxor @XMM[8+1], @XMM[1]
+ lea 0x80(%rsp), %rax # pass key schedule
+ mov %edx, %r10d # pass rounds
+
+ call _bsaes_decrypt8
+
+ pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ pxor 0x10(%rsp), @XMM[1]
+ movdqu @XMM[0], 0x00($out) # write output
+ movdqu @XMM[1], 0x10($out)
+ lea 0x20($out), $out
+
+ movdqa 0x20(%rsp), @XMM[7] # next iteration tweak
+ jmp .Lxts_dec_done
+.align 16
+.Lxts_dec_1:
+ pxor @XMM[0], @XMM[8]
+ lea 0x10($inp), $inp
+ movdqa @XMM[8], 0x20(%rbp)
+ lea 0x20(%rbp), $arg1
+ lea 0x20(%rbp), $arg2
+ lea ($key), $arg3
+ call asm_AES_decrypt # doesn't touch %xmm
+ pxor 0x20(%rbp), @XMM[0] # ^= tweak[]
+ #pxor @XMM[8], @XMM[0]
+ #lea 0x80(%rsp), %rax # pass key schedule
+ #mov %edx, %r10d # pass rounds
+ #call _bsaes_decrypt8
+ #pxor 0x00(%rsp), @XMM[0] # ^= tweak[]
+ movdqu @XMM[0], 0x00($out) # write output
+ lea 0x10($out), $out
+
+ movdqa 0x10(%rsp), @XMM[7] # next iteration tweak
+
+.Lxts_dec_done:
+ and \$15, %ebx
+ jz .Lxts_dec_ret
+
+ pxor $twtmp, $twtmp
+ movdqa .Lxts_magic(%rip), $twmask
+ pcmpgtd @XMM[7], $twtmp
+ pshufd \$0x13, $twtmp, $twres
+ movdqa @XMM[7], @XMM[6]
+ paddq @XMM[7], @XMM[7] # psllq 1,$tweak
+ pand $twmask, $twres # isolate carry and residue
+ movdqu ($inp), @XMM[0]
+ pxor $twres, @XMM[7]
+
+ lea 0x20(%rbp), $arg1
+ pxor @XMM[7], @XMM[0]
+ lea 0x20(%rbp), $arg2
+ movdqa @XMM[0], 0x20(%rbp)
+ lea ($key), $arg3
+ call asm_AES_decrypt # doesn't touch %xmm
+ pxor 0x20(%rbp), @XMM[7]
+ mov $out, %rdx
+ movdqu @XMM[7], ($out)
+
+.Lxts_dec_steal:
+ movzb 16($inp), %eax
+ movzb (%rdx), %ecx
+ lea 1($inp), $inp
+ mov %al, (%rdx)
+ mov %cl, 16(%rdx)
+ lea 1(%rdx), %rdx
+ sub \$1,%ebx
+ jnz .Lxts_dec_steal
+
+ movdqu ($out), @XMM[0]
+ lea 0x20(%rbp), $arg1
+ pxor @XMM[6], @XMM[0]
+ lea 0x20(%rbp), $arg2
+ movdqa @XMM[0], 0x20(%rbp)
+ lea ($key), $arg3
+ call asm_AES_decrypt # doesn't touch %xmm
+ pxor 0x20(%rbp), @XMM[6]
+ movdqu @XMM[6], ($out)
+
+.Lxts_dec_ret:
+ lea (%rsp), %rax
+ pxor %xmm0, %xmm0
+.Lxts_dec_bzero: # wipe key schedule [if any]
+ movdqa %xmm0, 0x00(%rax)
+ movdqa %xmm0, 0x10(%rax)
+ lea 0x20(%rax), %rax
+ cmp %rax, %rbp
+ ja .Lxts_dec_bzero
+
+ lea (%rbp),%rsp # restore %rsp
+___
+$code.=<<___ if ($win64);
+ movaps 0x40(%rbp), %xmm6
+ movaps 0x50(%rbp), %xmm7
+ movaps 0x60(%rbp), %xmm8
+ movaps 0x70(%rbp), %xmm9
+ movaps 0x80(%rbp), %xmm10
+ movaps 0x90(%rbp), %xmm11
+ movaps 0xa0(%rbp), %xmm12
+ movaps 0xb0(%rbp), %xmm13
+ movaps 0xc0(%rbp), %xmm14
+ movaps 0xd0(%rbp), %xmm15
+ lea 0xa0(%rbp), %rsp
+___
+$code.=<<___;
+ mov 0x48(%rsp), %r15
+ mov 0x50(%rsp), %r14
+ mov 0x58(%rsp), %r13
+ mov 0x60(%rsp), %r12
+ mov 0x68(%rsp), %rbx
+ mov 0x70(%rsp), %rax
+ lea 0x78(%rsp), %rsp
+ mov %rax, %rbp
+.Lxts_dec_epilogue:
+ ret
+.size bsaes_xts_decrypt,.-bsaes_xts_decrypt
+___
+}
+$code.=<<___;
+.type _bsaes_const,\@object
+.align 64
+_bsaes_const:
+.LM0ISR: # InvShiftRows constants
+ .quad 0x0a0e0206070b0f03, 0x0004080c0d010509
+.LISRM0:
+ .quad 0x01040b0e0205080f, 0x0306090c00070a0d
+.LISR:
+ .quad 0x0504070602010003, 0x0f0e0d0c080b0a09
+.LBS0: # bit-slice constants
+ .quad 0x5555555555555555, 0x5555555555555555
+.LBS1:
+ .quad 0x3333333333333333, 0x3333333333333333
+.LBS2:
+ .quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f
+.LSR: # shiftrows constants
+ .quad 0x0504070600030201, 0x0f0e0d0c0a09080b
+.LSRM0:
+ .quad 0x0304090e00050a0f, 0x01060b0c0207080d
+.LM0SR:
+ .quad 0x0a0e02060f03070b, 0x0004080c05090d01
+.LSWPUP: # byte-swap upper dword
+ .quad 0x0706050403020100, 0x0c0d0e0f0b0a0908
+.LSWPUPM0SR:
+ .quad 0x0a0d02060c03070b, 0x0004080f05090e01
+.LADD1: # counter increment constants
+ .quad 0x0000000000000000, 0x0000000100000000
+.LADD2:
+ .quad 0x0000000000000000, 0x0000000200000000
+.LADD3:
+ .quad 0x0000000000000000, 0x0000000300000000
+.LADD4:
+ .quad 0x0000000000000000, 0x0000000400000000
+.LADD5:
+ .quad 0x0000000000000000, 0x0000000500000000
+.LADD6:
+ .quad 0x0000000000000000, 0x0000000600000000
+.LADD7:
+ .quad 0x0000000000000000, 0x0000000700000000
+.LADD8:
+ .quad 0x0000000000000000, 0x0000000800000000
+.Lxts_magic:
+ .long 0x87,0,1,0
+.Lmasks:
+ .quad 0x0101010101010101, 0x0101010101010101
+ .quad 0x0202020202020202, 0x0202020202020202
+ .quad 0x0404040404040404, 0x0404040404040404
+ .quad 0x0808080808080808, 0x0808080808080808
+.LM0:
+ .quad 0x02060a0e03070b0f, 0x0004080c0105090d
+.L63:
+ .quad 0x6363636363636363, 0x6363636363636363
+.asciz "Bit-sliced AES for x86_64/SSSE3, Emilia Käsper, Peter Schwabe, Andy Polyakov"
+.align 64
+.size _bsaes_const,.-_bsaes_const
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+.type se_handler,\@abi-omnipotent
+.align 16
+se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # prologue label
+ cmp %r10,%rbx # context->Rip<prologue label
+ jb .Lin_prologue
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lin_prologue
+
+ mov 160($context),%rax # pull context->Rbp
+
+ lea 0x40(%rax),%rsi # %xmm save area
+ lea 512($context),%rdi # &context.Xmm6
+ mov \$20,%ecx # 10*sizeof(%xmm0)/sizeof(%rax)
+ .long 0xa548f3fc # cld; rep movsq
+ lea 0xa0(%rax),%rax # adjust stack pointer
+
+ mov 0x70(%rax),%rbp
+ mov 0x68(%rax),%rbx
+ mov 0x60(%rax),%r12
+ mov 0x58(%rax),%r13
+ mov 0x50(%rax),%r14
+ mov 0x48(%rax),%r15
+ lea 0x78(%rax),%rax # adjust stack pointer
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R13
+ mov %r14,232($context) # restore context->R14
+ mov %r15,240($context) # restore context->R15
+
+.Lin_prologue:
+ mov %rax,152($context) # restore context->Rsp
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$`1232/8`,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size se_handler,.-se_handler
+
+.section .pdata
+.align 4
+___
+$code.=<<___ if ($ecb);
+ .rva .Lecb_enc_prologue
+ .rva .Lecb_enc_epilogue
+ .rva .Lecb_enc_info
+
+ .rva .Lecb_dec_prologue
+ .rva .Lecb_dec_epilogue
+ .rva .Lecb_dec_info
+___
+$code.=<<___;
+ .rva .Lcbc_dec_prologue
+ .rva .Lcbc_dec_epilogue
+ .rva .Lcbc_dec_info
+
+ .rva .Lctr_enc_prologue
+ .rva .Lctr_enc_epilogue
+ .rva .Lctr_enc_info
+
+ .rva .Lxts_enc_prologue
+ .rva .Lxts_enc_epilogue
+ .rva .Lxts_enc_info
+
+ .rva .Lxts_dec_prologue
+ .rva .Lxts_dec_epilogue
+ .rva .Lxts_dec_info
+
+.section .xdata
+.align 8
+___
+$code.=<<___ if ($ecb);
+.Lecb_enc_info:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lecb_enc_body,.Lecb_enc_epilogue # HandlerData[]
+.Lecb_dec_info:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lecb_dec_body,.Lecb_dec_epilogue # HandlerData[]
+___
+$code.=<<___;
+.Lcbc_dec_info:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lcbc_dec_body,.Lcbc_dec_epilogue # HandlerData[]
+.Lctr_enc_info:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lctr_enc_body,.Lctr_enc_epilogue # HandlerData[]
+.Lxts_enc_info:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lxts_enc_body,.Lxts_enc_epilogue # HandlerData[]
+.Lxts_dec_info:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lxts_dec_body,.Lxts_dec_epilogue # HandlerData[]
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+
+print $code;
+
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/aes/asm/vpaes-x86.pl b/deps/openssl/openssl/crypto/aes/asm/vpaes-x86.pl
new file mode 100644
index 000000000..1533e2c30
--- /dev/null
+++ b/deps/openssl/openssl/crypto/aes/asm/vpaes-x86.pl
@@ -0,0 +1,903 @@
+#!/usr/bin/env perl
+
+######################################################################
+## Constant-time SSSE3 AES core implementation.
+## version 0.1
+##
+## By Mike Hamburg (Stanford University), 2009
+## Public domain.
+##
+## For details see http://shiftleft.org/papers/vector_aes/ and
+## http://crypto.stanford.edu/vpaes/.
+
+######################################################################
+# September 2011.
+#
+# Port vpaes-x86_64.pl as 32-bit "almost" drop-in replacement for
+# aes-586.pl. "Almost" refers to the fact that AES_cbc_encrypt
+# doesn't handle partial vectors (doesn't have to if called from
+# EVP only). "Drop-in" implies that this module doesn't share key
+# schedule structure with the original nor does it make assumption
+# about its alignment...
+#
+# Performance summary. aes-586.pl column lists large-block CBC
+# encrypt/decrypt/with-hyper-threading-off(*) results in cycles per
+# byte processed with 128-bit key, and vpaes-x86.pl column - [also
+# large-block CBC] encrypt/decrypt.
+#
+# aes-586.pl vpaes-x86.pl
+#
+# Core 2(**) 29.1/42.3/18.3 22.0/25.6(***)
+# Nehalem 27.9/40.4/18.1 10.3/12.0
+# Atom 102./119./60.1 64.5/85.3(***)
+#
+# (*) "Hyper-threading" in the context refers rather to cache shared
+# among multiple cores, than to specifically Intel HTT. As vast
+# majority of contemporary cores share cache, slower code path
+# is common place. In other words "with-hyper-threading-off"
+# results are presented mostly for reference purposes.
+#
+# (**) "Core 2" refers to initial 65nm design, a.k.a. Conroe.
+#
+# (***) Less impressive improvement on Core 2 and Atom is due to slow
+# pshufb, yet it's respectable +32%/65% improvement on Core 2
+# and +58%/40% on Atom (as implied, over "hyper-threading-safe"
+# code path).
+#
+# <appro@openssl.org>
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"vpaes-x86.pl",$x86only = $ARGV[$#ARGV] eq "386");
+
+$PREFIX="vpaes";
+
+my ($round, $base, $magic, $key, $const, $inp, $out)=
+ ("eax", "ebx", "ecx", "edx","ebp", "esi","edi");
+
+&static_label("_vpaes_consts");
+&static_label("_vpaes_schedule_low_round");
+
+&set_label("_vpaes_consts",64);
+$k_inv=-0x30; # inv, inva
+ &data_word(0x0D080180,0x0E05060F,0x0A0B0C02,0x04070309);
+ &data_word(0x0F0B0780,0x01040A06,0x02050809,0x030D0E0C);
+
+$k_s0F=-0x10; # s0F
+ &data_word(0x0F0F0F0F,0x0F0F0F0F,0x0F0F0F0F,0x0F0F0F0F);
+
+$k_ipt=0x00; # input transform (lo, hi)
+ &data_word(0x5A2A7000,0xC2B2E898,0x52227808,0xCABAE090);
+ &data_word(0x317C4D00,0x4C01307D,0xB0FDCC81,0xCD80B1FC);
+
+$k_sb1=0x20; # sb1u, sb1t
+ &data_word(0xCB503E00,0xB19BE18F,0x142AF544,0xA5DF7A6E);
+ &data_word(0xFAE22300,0x3618D415,0x0D2ED9EF,0x3BF7CCC1);
+$k_sb2=0x40; # sb2u, sb2t
+ &data_word(0x0B712400,0xE27A93C6,0xBC982FCD,0x5EB7E955);
+ &data_word(0x0AE12900,0x69EB8840,0xAB82234A,0xC2A163C8);
+$k_sbo=0x60; # sbou, sbot
+ &data_word(0x6FBDC700,0xD0D26D17,0xC502A878,0x15AABF7A);
+ &data_word(0x5FBB6A00,0xCFE474A5,0x412B35FA,0x8E1E90D1);
+
+$k_mc_forward=0x80; # mc_forward
+ &data_word(0x00030201,0x04070605,0x080B0A09,0x0C0F0E0D);
+ &data_word(0x04070605,0x080B0A09,0x0C0F0E0D,0x00030201);
+ &data_word(0x080B0A09,0x0C0F0E0D,0x00030201,0x04070605);
+ &data_word(0x0C0F0E0D,0x00030201,0x04070605,0x080B0A09);
+
+$k_mc_backward=0xc0; # mc_backward
+ &data_word(0x02010003,0x06050407,0x0A09080B,0x0E0D0C0F);
+ &data_word(0x0E0D0C0F,0x02010003,0x06050407,0x0A09080B);
+ &data_word(0x0A09080B,0x0E0D0C0F,0x02010003,0x06050407);
+ &data_word(0x06050407,0x0A09080B,0x0E0D0C0F,0x02010003);
+
+$k_sr=0x100; # sr
+ &data_word(0x03020100,0x07060504,0x0B0A0908,0x0F0E0D0C);
+ &data_word(0x0F0A0500,0x030E0904,0x07020D08,0x0B06010C);
+ &data_word(0x0B020900,0x0F060D04,0x030A0108,0x070E050C);
+ &data_word(0x070A0D00,0x0B0E0104,0x0F020508,0x0306090C);
+
+$k_rcon=0x140; # rcon
+ &data_word(0xAF9DEEB6,0x1F8391B9,0x4D7C7D81,0x702A9808);
+
+$k_s63=0x150; # s63: all equal to 0x63 transformed
+ &data_word(0x5B5B5B5B,0x5B5B5B5B,0x5B5B5B5B,0x5B5B5B5B);
+
+$k_opt=0x160; # output transform
+ &data_word(0xD6B66000,0xFF9F4929,0xDEBE6808,0xF7974121);
+ &data_word(0x50BCEC00,0x01EDBD51,0xB05C0CE0,0xE10D5DB1);
+
+$k_deskew=0x180; # deskew tables: inverts the sbox's "skew"
+ &data_word(0x47A4E300,0x07E4A340,0x5DBEF91A,0x1DFEB95A);
+ &data_word(0x83EA6900,0x5F36B5DC,0xF49D1E77,0x2841C2AB);
+##
+## Decryption stuff
+## Key schedule constants
+##
+$k_dksd=0x1a0; # decryption key schedule: invskew x*D
+ &data_word(0xA3E44700,0xFEB91A5D,0x5A1DBEF9,0x0740E3A4);
+ &data_word(0xB5368300,0x41C277F4,0xAB289D1E,0x5FDC69EA);
+$k_dksb=0x1c0; # decryption key schedule: invskew x*B
+ &data_word(0x8550D500,0x9A4FCA1F,0x1CC94C99,0x03D65386);
+ &data_word(0xB6FC4A00,0x115BEDA7,0x7E3482C8,0xD993256F);
+$k_dkse=0x1e0; # decryption key schedule: invskew x*E + 0x63
+ &data_word(0x1FC9D600,0xD5031CCA,0x994F5086,0x53859A4C);
+ &data_word(0x4FDC7BE8,0xA2319605,0x20B31487,0xCD5EF96A);
+$k_dks9=0x200; # decryption key schedule: invskew x*9
+ &data_word(0x7ED9A700,0xB6116FC8,0x82255BFC,0x4AED9334);
+ &data_word(0x27143300,0x45765162,0xE9DAFDCE,0x8BB89FAC);
+
+##
+## Decryption stuff
+## Round function constants
+##
+$k_dipt=0x220; # decryption input transform
+ &data_word(0x0B545F00,0x0F505B04,0x114E451A,0x154A411E);
+ &data_word(0x60056500,0x86E383E6,0xF491F194,0x12771772);
+
+$k_dsb9=0x240; # decryption sbox output *9*u, *9*t
+ &data_word(0x9A86D600,0x851C0353,0x4F994CC9,0xCAD51F50);
+ &data_word(0xECD74900,0xC03B1789,0xB2FBA565,0x725E2C9E);
+$k_dsbd=0x260; # decryption sbox output *D*u, *D*t
+ &data_word(0xE6B1A200,0x7D57CCDF,0x882A4439,0xF56E9B13);
+ &data_word(0x24C6CB00,0x3CE2FAF7,0x15DEEFD3,0x2931180D);
+$k_dsbb=0x280; # decryption sbox output *B*u, *B*t
+ &data_word(0x96B44200,0xD0226492,0xB0F2D404,0x602646F6);
+ &data_word(0xCD596700,0xC19498A6,0x3255AA6B,0xF3FF0C3E);
+$k_dsbe=0x2a0; # decryption sbox output *E*u, *E*t
+ &data_word(0x26D4D000,0x46F29296,0x64B4F6B0,0x22426004);
+ &data_word(0xFFAAC100,0x0C55A6CD,0x98593E32,0x9467F36B);
+$k_dsbo=0x2c0; # decryption sbox final output
+ &data_word(0x7EF94000,0x1387EA53,0xD4943E2D,0xC7AA6DB9);
+ &data_word(0x93441D00,0x12D7560F,0xD8C58E9C,0xCA4B8159);
+&asciz ("Vector Permutation AES for x86/SSSE3, Mike Hamburg (Stanford University)");
+&align (64);
+
+&function_begin_B("_vpaes_preheat");
+ &add ($const,&DWP(0,"esp"));
+ &movdqa ("xmm7",&QWP($k_inv,$const));
+ &movdqa ("xmm6",&QWP($k_s0F,$const));
+ &ret ();
+&function_end_B("_vpaes_preheat");
+
+##
+## _aes_encrypt_core
+##
+## AES-encrypt %xmm0.
+##
+## Inputs:
+## %xmm0 = input
+## %xmm6-%xmm7 as in _vpaes_preheat
+## (%edx) = scheduled keys
+##
+## Output in %xmm0
+## Clobbers %xmm1-%xmm5, %eax, %ebx, %ecx, %edx
+##
+##
+&function_begin_B("_vpaes_encrypt_core");
+ &mov ($magic,16);
+ &mov ($round,&DWP(240,$key));
+ &movdqa ("xmm1","xmm6")
+ &movdqa ("xmm2",&QWP($k_ipt,$const));
+ &pandn ("xmm1","xmm0");
+ &movdqu ("xmm5",&QWP(0,$key));
+ &psrld ("xmm1",4);
+ &pand ("xmm0","xmm6");
+ &pshufb ("xmm2","xmm0");
+ &movdqa ("xmm0",&QWP($k_ipt+16,$const));
+ &pshufb ("xmm0","xmm1");
+ &pxor ("xmm2","xmm5");
+ &pxor ("xmm0","xmm2");
+ &add ($key,16);
+ &lea ($base,&DWP($k_mc_backward,$const));
+ &jmp (&label("enc_entry"));
+
+
+&set_label("enc_loop",16);
+ # middle of middle round
+ &movdqa ("xmm4",&QWP($k_sb1,$const)); # 4 : sb1u
+ &pshufb ("xmm4","xmm2"); # 4 = sb1u
+ &pxor ("xmm4","xmm5"); # 4 = sb1u + k
+ &movdqa ("xmm0",&QWP($k_sb1+16,$const));# 0 : sb1t
+ &pshufb ("xmm0","xmm3"); # 0 = sb1t
+ &pxor ("xmm0","xmm4"); # 0 = A
+ &movdqa ("xmm5",&QWP($k_sb2,$const)); # 4 : sb2u
+ &pshufb ("xmm5","xmm2"); # 4 = sb2u
+ &movdqa ("xmm1",&QWP(-0x40,$base,$magic));# .Lk_mc_forward[]
+ &movdqa ("xmm2",&QWP($k_sb2+16,$const));# 2 : sb2t
+ &pshufb ("xmm2","xmm3"); # 2 = sb2t
+ &pxor ("xmm2","xmm5"); # 2 = 2A
+ &movdqa ("xmm4",&QWP(0,$base,$magic)); # .Lk_mc_backward[]
+ &movdqa ("xmm3","xmm0"); # 3 = A
+ &pshufb ("xmm0","xmm1"); # 0 = B
+ &add ($key,16); # next key
+ &pxor ("xmm0","xmm2"); # 0 = 2A+B
+ &pshufb ("xmm3","xmm4"); # 3 = D
+ &add ($magic,16); # next mc
+ &pxor ("xmm3","xmm0"); # 3 = 2A+B+D
+ &pshufb ("xmm0","xmm1"); # 0 = 2B+C
+ &and ($magic,0x30); # ... mod 4
+ &pxor ("xmm0","xmm3"); # 0 = 2A+3B+C+D
+ &sub ($round,1); # nr--
+
+&set_label("enc_entry");
+ # top of round
+ &movdqa ("xmm1","xmm6"); # 1 : i
+ &pandn ("xmm1","xmm0"); # 1 = i<<4
+ &psrld ("xmm1",4); # 1 = i
+ &pand ("xmm0","xmm6"); # 0 = k
+ &movdqa ("xmm5",&QWP($k_inv+16,$const));# 2 : a/k
+ &pshufb ("xmm5","xmm0"); # 2 = a/k
+ &pxor ("xmm0","xmm1"); # 0 = j
+ &movdqa ("xmm3","xmm7"); # 3 : 1/i
+ &pshufb ("xmm3","xmm1"); # 3 = 1/i
+ &pxor ("xmm3","xmm5"); # 3 = iak = 1/i + a/k
+ &movdqa ("xmm4","xmm7"); # 4 : 1/j
+ &pshufb ("xmm4","xmm0"); # 4 = 1/j
+ &pxor ("xmm4","xmm5"); # 4 = jak = 1/j + a/k
+ &movdqa ("xmm2","xmm7"); # 2 : 1/iak
+ &pshufb ("xmm2","xmm3"); # 2 = 1/iak
+ &pxor ("xmm2","xmm0"); # 2 = io
+ &movdqa ("xmm3","xmm7"); # 3 : 1/jak
+ &movdqu ("xmm5",&QWP(0,$key));
+ &pshufb ("xmm3","xmm4"); # 3 = 1/jak
+ &pxor ("xmm3","xmm1"); # 3 = jo
+ &jnz (&label("enc_loop"));
+
+ # middle of last round
+ &movdqa ("xmm4",&QWP($k_sbo,$const)); # 3 : sbou .Lk_sbo
+ &movdqa ("xmm0",&QWP($k_sbo+16,$const));# 3 : sbot .Lk_sbo+16
+ &pshufb ("xmm4","xmm2"); # 4 = sbou
+ &pxor ("xmm4","xmm5"); # 4 = sb1u + k
+ &pshufb ("xmm0","xmm3"); # 0 = sb1t
+ &movdqa ("xmm1",&QWP(0x40,$base,$magic));# .Lk_sr[]
+ &pxor ("xmm0","xmm4"); # 0 = A
+ &pshufb ("xmm0","xmm1");
+ &ret ();
+&function_end_B("_vpaes_encrypt_core");
+
+##
+## Decryption core
+##
+## Same API as encryption core.
+##
+&function_begin_B("_vpaes_decrypt_core");
+ &mov ($round,&DWP(240,$key));
+ &lea ($base,&DWP($k_dsbd,$const));
+ &movdqa ("xmm1","xmm6");
+ &movdqa ("xmm2",&QWP($k_dipt-$k_dsbd,$base));
+ &pandn ("xmm1","xmm0");
+ &mov ($magic,$round);
+ &psrld ("xmm1",4)
+ &movdqu ("xmm5",&QWP(0,$key));
+ &shl ($magic,4);
+ &pand ("xmm0","xmm6");
+ &pshufb ("xmm2","xmm0");
+ &movdqa ("xmm0",&QWP($k_dipt-$k_dsbd+16,$base));
+ &xor ($magic,0x30);
+ &pshufb ("xmm0","xmm1");
+ &and ($magic,0x30);
+ &pxor ("xmm2","xmm5");
+ &movdqa ("xmm5",&QWP($k_mc_forward+48,$const));
+ &pxor ("xmm0","xmm2");
+ &add ($key,16);
+ &lea ($magic,&DWP($k_sr-$k_dsbd,$base,$magic));
+ &jmp (&label("dec_entry"));
+
+&set_label("dec_loop",16);
+##
+## Inverse mix columns
+##
+ &movdqa ("xmm4",&QWP(-0x20,$base)); # 4 : sb9u
+ &pshufb ("xmm4","xmm2"); # 4 = sb9u
+ &pxor ("xmm4","xmm0");
+ &movdqa ("xmm0",&QWP(-0x10,$base)); # 0 : sb9t
+ &pshufb ("xmm0","xmm3"); # 0 = sb9t
+ &pxor ("xmm0","xmm4"); # 0 = ch
+ &add ($key,16); # next round key
+
+ &pshufb ("xmm0","xmm5"); # MC ch
+ &movdqa ("xmm4",&QWP(0,$base)); # 4 : sbdu
+ &pshufb ("xmm4","xmm2"); # 4 = sbdu
+ &pxor ("xmm4","xmm0"); # 4 = ch
+ &movdqa ("xmm0",&QWP(0x10,$base)); # 0 : sbdt
+ &pshufb ("xmm0","xmm3"); # 0 = sbdt
+ &pxor ("xmm0","xmm4"); # 0 = ch
+ &sub ($round,1); # nr--
+
+ &pshufb ("xmm0","xmm5"); # MC ch
+ &movdqa ("xmm4",&QWP(0x20,$base)); # 4 : sbbu
+ &pshufb ("xmm4","xmm2"); # 4 = sbbu
+ &pxor ("xmm4","xmm0"); # 4 = ch
+ &movdqa ("xmm0",&QWP(0x30,$base)); # 0 : sbbt
+ &pshufb ("xmm0","xmm3"); # 0 = sbbt
+ &pxor ("xmm0","xmm4"); # 0 = ch
+
+ &pshufb ("xmm0","xmm5"); # MC ch
+ &movdqa ("xmm4",&QWP(0x40,$base)); # 4 : sbeu
+ &pshufb ("xmm4","xmm2"); # 4 = sbeu
+ &pxor ("xmm4","xmm0"); # 4 = ch
+ &movdqa ("xmm0",&QWP(0x50,$base)); # 0 : sbet
+ &pshufb ("xmm0","xmm3"); # 0 = sbet
+ &pxor ("xmm0","xmm4"); # 0 = ch
+
+ &palignr("xmm5","xmm5",12);
+
+&set_label("dec_entry");
+ # top of round
+ &movdqa ("xmm1","xmm6"); # 1 : i
+ &pandn ("xmm1","xmm0"); # 1 = i<<4
+ &psrld ("xmm1",4); # 1 = i
+ &pand ("xmm0","xmm6"); # 0 = k
+ &movdqa ("xmm2",&QWP($k_inv+16,$const));# 2 : a/k
+ &pshufb ("xmm2","xmm0"); # 2 = a/k
+ &pxor ("xmm0","xmm1"); # 0 = j
+ &movdqa ("xmm3","xmm7"); # 3 : 1/i
+ &pshufb ("xmm3","xmm1"); # 3 = 1/i
+ &pxor ("xmm3","xmm2"); # 3 = iak = 1/i + a/k
+ &movdqa ("xmm4","xmm7"); # 4 : 1/j
+ &pshufb ("xmm4","xmm0"); # 4 = 1/j
+ &pxor ("xmm4","xmm2"); # 4 = jak = 1/j + a/k
+ &movdqa ("xmm2","xmm7"); # 2 : 1/iak
+ &pshufb ("xmm2","xmm3"); # 2 = 1/iak
+ &pxor ("xmm2","xmm0"); # 2 = io
+ &movdqa ("xmm3","xmm7"); # 3 : 1/jak
+ &pshufb ("xmm3","xmm4"); # 3 = 1/jak
+ &pxor ("xmm3","xmm1"); # 3 = jo
+ &movdqu ("xmm0",&QWP(0,$key));
+ &jnz (&label("dec_loop"));
+
+ # middle of last round
+ &movdqa ("xmm4",&QWP(0x60,$base)); # 3 : sbou
+ &pshufb ("xmm4","xmm2"); # 4 = sbou
+ &pxor ("xmm4","xmm0"); # 4 = sb1u + k
+ &movdqa ("xmm0",&QWP(0x70,$base)); # 0 : sbot
+ &movdqa ("xmm2",&QWP(0,$magic));
+ &pshufb ("xmm0","xmm3"); # 0 = sb1t
+ &pxor ("xmm0","xmm4"); # 0 = A
+ &pshufb ("xmm0","xmm2");
+ &ret ();
+&function_end_B("_vpaes_decrypt_core");
+
+########################################################
+## ##
+## AES key schedule ##
+## ##
+########################################################
+&function_begin_B("_vpaes_schedule_core");
+ &add ($const,&DWP(0,"esp"));
+ &movdqu ("xmm0",&QWP(0,$inp)); # load key (unaligned)
+ &movdqa ("xmm2",&QWP($k_rcon,$const)); # load rcon
+
+ # input transform
+ &movdqa ("xmm3","xmm0");
+ &lea ($base,&DWP($k_ipt,$const));
+ &movdqa (&QWP(4,"esp"),"xmm2"); # xmm8
+ &call ("_vpaes_schedule_transform");
+ &movdqa ("xmm7","xmm0");
+
+ &test ($out,$out);
+ &jnz (&label("schedule_am_decrypting"));
+
+ # encrypting, output zeroth round key after transform
+ &movdqu (&QWP(0,$key),"xmm0");
+ &jmp (&label("schedule_go"));
+
+&set_label("schedule_am_decrypting");
+ # decrypting, output zeroth round key after shiftrows
+ &movdqa ("xmm1",&QWP($k_sr,$const,$magic));
+ &pshufb ("xmm3","xmm1");
+ &movdqu (&QWP(0,$key),"xmm3");
+ &xor ($magic,0x30);
+
+&set_label("schedule_go");
+ &cmp ($round,192);
+ &ja (&label("schedule_256"));
+ &je (&label("schedule_192"));
+ # 128: fall though
+
+##
+## .schedule_128
+##
+## 128-bit specific part of key schedule.
+##
+## This schedule is really simple, because all its parts
+## are accomplished by the subroutines.
+##
+&set_label("schedule_128");
+ &mov ($round,10);
+
+&set_label("loop_schedule_128");
+ &call ("_vpaes_schedule_round");
+ &dec ($round);
+ &jz (&label("schedule_mangle_last"));
+ &call ("_vpaes_schedule_mangle"); # write output
+ &jmp (&label("loop_schedule_128"));
+
+##
+## .aes_schedule_192
+##
+## 192-bit specific part of key schedule.
+##
+## The main body of this schedule is the same as the 128-bit
+## schedule, but with more smearing. The long, high side is
+## stored in %xmm7 as before, and the short, low side is in
+## the high bits of %xmm6.
+##
+## This schedule is somewhat nastier, however, because each
+## round produces 192 bits of key material, or 1.5 round keys.
+## Therefore, on each cycle we do 2 rounds and produce 3 round
+## keys.
+##
+&set_label("schedule_192",16);
+ &movdqu ("xmm0",&QWP(8,$inp)); # load key part 2 (very unaligned)
+ &call ("_vpaes_schedule_transform"); # input transform
+ &movdqa ("xmm6","xmm0"); # save short part
+ &pxor ("xmm4","xmm4"); # clear 4
+ &movhlps("xmm6","xmm4"); # clobber low side with zeros
+ &mov ($round,4);
+
+&set_label("loop_schedule_192");
+ &call ("_vpaes_schedule_round");
+ &palignr("xmm0","xmm6",8);
+ &call ("_vpaes_schedule_mangle"); # save key n
+ &call ("_vpaes_schedule_192_smear");
+ &call ("_vpaes_schedule_mangle"); # save key n+1
+ &call ("_vpaes_schedule_round");
+ &dec ($round);
+ &jz (&label("schedule_mangle_last"));
+ &call ("_vpaes_schedule_mangle"); # save key n+2
+ &call ("_vpaes_schedule_192_smear");
+ &jmp (&label("loop_schedule_192"));
+
+##
+## .aes_schedule_256
+##
+## 256-bit specific part of key schedule.
+##
+## The structure here is very similar to the 128-bit
+## schedule, but with an additional "low side" in
+## %xmm6. The low side's rounds are the same as the
+## high side's, except no rcon and no rotation.
+##
+&set_label("schedule_256",16);
+ &movdqu ("xmm0",&QWP(16,$inp)); # load key part 2 (unaligned)
+ &call ("_vpaes_schedule_transform"); # input transform
+ &mov ($round,7);
+
+&set_label("loop_schedule_256");
+ &call ("_vpaes_schedule_mangle"); # output low result
+ &movdqa ("xmm6","xmm0"); # save cur_lo in xmm6
+
+ # high round
+ &call ("_vpaes_schedule_round");
+ &dec ($round);
+ &jz (&label("schedule_mangle_last"));
+ &call ("_vpaes_schedule_mangle");
+
+ # low round. swap xmm7 and xmm6
+ &pshufd ("xmm0","xmm0",0xFF);
+ &movdqa (&QWP(20,"esp"),"xmm7");
+ &movdqa ("xmm7","xmm6");
+ &call ("_vpaes_schedule_low_round");
+ &movdqa ("xmm7",&QWP(20,"esp"));
+
+ &jmp (&label("loop_schedule_256"));
+
+##
+## .aes_schedule_mangle_last
+##
+## Mangler for last round of key schedule
+## Mangles %xmm0
+## when encrypting, outputs out(%xmm0) ^ 63
+## when decrypting, outputs unskew(%xmm0)
+##
+## Always called right before return... jumps to cleanup and exits
+##
+&set_label("schedule_mangle_last",16);
+ # schedule last round key from xmm0
+ &lea ($base,&DWP($k_deskew,$const));
+ &test ($out,$out);
+ &jnz (&label("schedule_mangle_last_dec"));
+
+ # encrypting
+ &movdqa ("xmm1",&QWP($k_sr,$const,$magic));
+ &pshufb ("xmm0","xmm1"); # output permute
+ &lea ($base,&DWP($k_opt,$const)); # prepare to output transform
+ &add ($key,32);
+
+&set_label("schedule_mangle_last_dec");
+ &add ($key,-16);
+ &pxor ("xmm0",&QWP($k_s63,$const));
+ &call ("_vpaes_schedule_transform"); # output transform
+ &movdqu (&QWP(0,$key),"xmm0"); # save last key
+
+ # cleanup
+ &pxor ("xmm0","xmm0");
+ &pxor ("xmm1","xmm1");
+ &pxor ("xmm2","xmm2");
+ &pxor ("xmm3","xmm3");
+ &pxor ("xmm4","xmm4");
+ &pxor ("xmm5","xmm5");
+ &pxor ("xmm6","xmm6");
+ &pxor ("xmm7","xmm7");
+ &ret ();
+&function_end_B("_vpaes_schedule_core");
+
+##
+## .aes_schedule_192_smear
+##
+## Smear the short, low side in the 192-bit key schedule.
+##
+## Inputs:
+## %xmm7: high side, b a x y
+## %xmm6: low side, d c 0 0
+## %xmm13: 0
+##
+## Outputs:
+## %xmm6: b+c+d b+c 0 0
+## %xmm0: b+c+d b+c b a
+##
+&function_begin_B("_vpaes_schedule_192_smear");
+ &pshufd ("xmm0","xmm6",0x80); # d c 0 0 -> c 0 0 0
+ &pxor ("xmm6","xmm0"); # -> c+d c 0 0
+ &pshufd ("xmm0","xmm7",0xFE); # b a _ _ -> b b b a
+ &pxor ("xmm6","xmm0"); # -> b+c+d b+c b a
+ &movdqa ("xmm0","xmm6");
+ &pxor ("xmm1","xmm1");
+ &movhlps("xmm6","xmm1"); # clobber low side with zeros
+ &ret ();
+&function_end_B("_vpaes_schedule_192_smear");
+
+##
+## .aes_schedule_round
+##
+## Runs one main round of the key schedule on %xmm0, %xmm7
+##
+## Specifically, runs subbytes on the high dword of %xmm0
+## then rotates it by one byte and xors into the low dword of
+## %xmm7.
+##
+## Adds rcon from low byte of %xmm8, then rotates %xmm8 for
+## next rcon.
+##
+## Smears the dwords of %xmm7 by xoring the low into the
+## second low, result into third, result into highest.
+##
+## Returns results in %xmm7 = %xmm0.
+## Clobbers %xmm1-%xmm5.
+##
+&function_begin_B("_vpaes_schedule_round");
+ # extract rcon from xmm8
+ &movdqa ("xmm2",&QWP(8,"esp")); # xmm8
+ &pxor ("xmm1","xmm1");
+ &palignr("xmm1","xmm2",15);
+ &palignr("xmm2","xmm2",15);
+ &pxor ("xmm7","xmm1");
+
+ # rotate
+ &pshufd ("xmm0","xmm0",0xFF);
+ &palignr("xmm0","xmm0",1);
+
+ # fall through...
+ &movdqa (&QWP(8,"esp"),"xmm2"); # xmm8
+
+ # low round: same as high round, but no rotation and no rcon.
+&set_label("_vpaes_schedule_low_round");
+ # smear xmm7
+ &movdqa ("xmm1","xmm7");
+ &pslldq ("xmm7",4);
+ &pxor ("xmm7","xmm1");
+ &movdqa ("xmm1","xmm7");
+ &pslldq ("xmm7",8);
+ &pxor ("xmm7","xmm1");
+ &pxor ("xmm7",&QWP($k_s63,$const));
+
+ # subbyte
+ &movdqa ("xmm4",&QWP($k_s0F,$const));
+ &movdqa ("xmm5",&QWP($k_inv,$const)); # 4 : 1/j
+ &movdqa ("xmm1","xmm4");
+ &pandn ("xmm1","xmm0");
+ &psrld ("xmm1",4); # 1 = i
+ &pand ("xmm0","xmm4"); # 0 = k
+ &movdqa ("xmm2",&QWP($k_inv+16,$const));# 2 : a/k
+ &pshufb ("xmm2","xmm0"); # 2 = a/k
+ &pxor ("xmm0","xmm1"); # 0 = j
+ &movdqa ("xmm3","xmm5"); # 3 : 1/i
+ &pshufb ("xmm3","xmm1"); # 3 = 1/i
+ &pxor ("xmm3","xmm2"); # 3 = iak = 1/i + a/k
+ &movdqa ("xmm4","xmm5"); # 4 : 1/j
+ &pshufb ("xmm4","xmm0"); # 4 = 1/j
+ &pxor ("xmm4","xmm2"); # 4 = jak = 1/j + a/k
+ &movdqa ("xmm2","xmm5"); # 2 : 1/iak
+ &pshufb ("xmm2","xmm3"); # 2 = 1/iak
+ &pxor ("xmm2","xmm0"); # 2 = io
+ &movdqa ("xmm3","xmm5"); # 3 : 1/jak
+ &pshufb ("xmm3","xmm4"); # 3 = 1/jak
+ &pxor ("xmm3","xmm1"); # 3 = jo
+ &movdqa ("xmm4",&QWP($k_sb1,$const)); # 4 : sbou
+ &pshufb ("xmm4","xmm2"); # 4 = sbou
+ &movdqa ("xmm0",&QWP($k_sb1+16,$const));# 0 : sbot
+ &pshufb ("xmm0","xmm3"); # 0 = sb1t
+ &pxor ("xmm0","xmm4"); # 0 = sbox output
+
+ # add in smeared stuff
+ &pxor ("xmm0","xmm7");
+ &movdqa ("xmm7","xmm0");
+ &ret ();
+&function_end_B("_vpaes_schedule_round");
+
+##
+## .aes_schedule_transform
+##
+## Linear-transform %xmm0 according to tables at (%ebx)
+##
+## Output in %xmm0
+## Clobbers %xmm1, %xmm2
+##
+&function_begin_B("_vpaes_schedule_transform");
+ &movdqa ("xmm2",&QWP($k_s0F,$const));
+ &movdqa ("xmm1","xmm2");
+ &pandn ("xmm1","xmm0");
+ &psrld ("xmm1",4);
+ &pand ("xmm0","xmm2");
+ &movdqa ("xmm2",&QWP(0,$base));
+ &pshufb ("xmm2","xmm0");
+ &movdqa ("xmm0",&QWP(16,$base));
+ &pshufb ("xmm0","xmm1");
+ &pxor ("xmm0","xmm2");
+ &ret ();
+&function_end_B("_vpaes_schedule_transform");
+
+##
+## .aes_schedule_mangle
+##
+## Mangle xmm0 from (basis-transformed) standard version
+## to our version.
+##
+## On encrypt,
+## xor with 0x63
+## multiply by circulant 0,1,1,1
+## apply shiftrows transform
+##
+## On decrypt,
+## xor with 0x63
+## multiply by "inverse mixcolumns" circulant E,B,D,9
+## deskew
+## apply shiftrows transform
+##
+##
+## Writes out to (%edx), and increments or decrements it
+## Keeps track of round number mod 4 in %ecx
+## Preserves xmm0
+## Clobbers xmm1-xmm5
+##
+&function_begin_B("_vpaes_schedule_mangle");
+ &movdqa ("xmm4","xmm0"); # save xmm0 for later
+ &movdqa ("xmm5",&QWP($k_mc_forward,$const));
+ &test ($out,$out);
+ &jnz (&label("schedule_mangle_dec"));
+
+ # encrypting
+ &add ($key,16);
+ &pxor ("xmm4",&QWP($k_s63,$const));
+ &pshufb ("xmm4","xmm5");
+ &movdqa ("xmm3","xmm4");
+ &pshufb ("xmm4","xmm5");
+ &pxor ("xmm3","xmm4");
+ &pshufb ("xmm4","xmm5");
+ &pxor ("xmm3","xmm4");
+
+ &jmp (&label("schedule_mangle_both"));
+
+&set_label("schedule_mangle_dec",16);
+ # inverse mix columns
+ &movdqa ("xmm2",&QWP($k_s0F,$const));
+ &lea ($inp,&DWP($k_dksd,$const));
+ &movdqa ("xmm1","xmm2");
+ &pandn ("xmm1","xmm4");
+ &psrld ("xmm1",4); # 1 = hi
+ &pand ("xmm4","xmm2"); # 4 = lo
+
+ &movdqa ("xmm2",&QWP(0,$inp));
+ &pshufb ("xmm2","xmm4");
+ &movdqa ("xmm3",&QWP(0x10,$inp));
+ &pshufb ("xmm3","xmm1");
+ &pxor ("xmm3","xmm2");
+ &pshufb ("xmm3","xmm5");
+
+ &movdqa ("xmm2",&QWP(0x20,$inp));
+ &pshufb ("xmm2","xmm4");
+ &pxor ("xmm2","xmm3");
+ &movdqa ("xmm3",&QWP(0x30,$inp));
+ &pshufb ("xmm3","xmm1");
+ &pxor ("xmm3","xmm2");
+ &pshufb ("xmm3","xmm5");
+
+ &movdqa ("xmm2",&QWP(0x40,$inp));
+ &pshufb ("xmm2","xmm4");
+ &pxor ("xmm2","xmm3");
+ &movdqa ("xmm3",&QWP(0x50,$inp));
+ &pshufb ("xmm3","xmm1");
+ &pxor ("xmm3","xmm2");
+ &pshufb ("xmm3","xmm5");
+
+ &movdqa ("xmm2",&QWP(0x60,$inp));
+ &pshufb ("xmm2","xmm4");
+ &pxor ("xmm2","xmm3");
+ &movdqa ("xmm3",&QWP(0x70,$inp));
+ &pshufb ("xmm3","xmm1");
+ &pxor ("xmm3","xmm2");
+
+ &add ($key,-16);
+
+&set_label("schedule_mangle_both");
+ &movdqa ("xmm1",&QWP($k_sr,$const,$magic));
+ &pshufb ("xmm3","xmm1");
+ &add ($magic,-16);
+ &and ($magic,0x30);
+ &movdqu (&QWP(0,$key),"xmm3");
+ &ret ();
+&function_end_B("_vpaes_schedule_mangle");
+
+#
+# Interface to OpenSSL
+#
+&function_begin("${PREFIX}_set_encrypt_key");
+ &mov ($inp,&wparam(0)); # inp
+ &lea ($base,&DWP(-56,"esp"));
+ &mov ($round,&wparam(1)); # bits
+ &and ($base,-16);
+ &mov ($key,&wparam(2)); # key
+ &xchg ($base,"esp"); # alloca
+ &mov (&DWP(48,"esp"),$base);
+
+ &mov ($base,$round);
+ &shr ($base,5);
+ &add ($base,5);
+ &mov (&DWP(240,$key),$base); # AES_KEY->rounds = nbits/32+5;
+ &mov ($magic,0x30);
+ &mov ($out,0);
+
+ &lea ($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
+ &call ("_vpaes_schedule_core");
+&set_label("pic_point");
+
+ &mov ("esp",&DWP(48,"esp"));
+ &xor ("eax","eax");
+&function_end("${PREFIX}_set_encrypt_key");
+
+&function_begin("${PREFIX}_set_decrypt_key");
+ &mov ($inp,&wparam(0)); # inp
+ &lea ($base,&DWP(-56,"esp"));
+ &mov ($round,&wparam(1)); # bits
+ &and ($base,-16);
+ &mov ($key,&wparam(2)); # key
+ &xchg ($base,"esp"); # alloca
+ &mov (&DWP(48,"esp"),$base);
+
+ &mov ($base,$round);
+ &shr ($base,5);
+ &add ($base,5);
+ &mov (&DWP(240,$key),$base); # AES_KEY->rounds = nbits/32+5;
+ &shl ($base,4);
+ &lea ($key,&DWP(16,$key,$base));
+
+ &mov ($out,1);
+ &mov ($magic,$round);
+ &shr ($magic,1);
+ &and ($magic,32);
+ &xor ($magic,32); # nbist==192?0:32;
+
+ &lea ($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
+ &call ("_vpaes_schedule_core");
+&set_label("pic_point");
+
+ &mov ("esp",&DWP(48,"esp"));
+ &xor ("eax","eax");
+&function_end("${PREFIX}_set_decrypt_key");
+
+&function_begin("${PREFIX}_encrypt");
+ &lea ($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
+ &call ("_vpaes_preheat");
+&set_label("pic_point");
+ &mov ($inp,&wparam(0)); # inp
+ &lea ($base,&DWP(-56,"esp"));
+ &mov ($out,&wparam(1)); # out
+ &and ($base,-16);
+ &mov ($key,&wparam(2)); # key
+ &xchg ($base,"esp"); # alloca
+ &mov (&DWP(48,"esp"),$base);
+
+ &movdqu ("xmm0",&QWP(0,$inp));
+ &call ("_vpaes_encrypt_core");
+ &movdqu (&QWP(0,$out),"xmm0");
+
+ &mov ("esp",&DWP(48,"esp"));
+&function_end("${PREFIX}_encrypt");
+
+&function_begin("${PREFIX}_decrypt");
+ &lea ($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
+ &call ("_vpaes_preheat");
+&set_label("pic_point");
+ &mov ($inp,&wparam(0)); # inp
+ &lea ($base,&DWP(-56,"esp"));
+ &mov ($out,&wparam(1)); # out
+ &and ($base,-16);
+ &mov ($key,&wparam(2)); # key
+ &xchg ($base,"esp"); # alloca
+ &mov (&DWP(48,"esp"),$base);
+
+ &movdqu ("xmm0",&QWP(0,$inp));
+ &call ("_vpaes_decrypt_core");
+ &movdqu (&QWP(0,$out),"xmm0");
+
+ &mov ("esp",&DWP(48,"esp"));
+&function_end("${PREFIX}_decrypt");
+
+&function_begin("${PREFIX}_cbc_encrypt");
+ &mov ($inp,&wparam(0)); # inp
+ &mov ($out,&wparam(1)); # out
+ &mov ($round,&wparam(2)); # len
+ &mov ($key,&wparam(3)); # key
+ &sub ($round,16);
+ &jc (&label("cbc_abort"));
+ &lea ($base,&DWP(-56,"esp"));
+ &mov ($const,&wparam(4)); # ivp
+ &and ($base,-16);
+ &mov ($magic,&wparam(5)); # enc
+ &xchg ($base,"esp"); # alloca
+ &movdqu ("xmm1",&QWP(0,$const)); # load IV
+ &sub ($out,$inp);
+ &mov (&DWP(48,"esp"),$base);
+
+ &mov (&DWP(0,"esp"),$out); # save out
+ &mov (&DWP(4,"esp"),$key) # save key
+ &mov (&DWP(8,"esp"),$const); # save ivp
+ &mov ($out,$round); # $out works as $len
+
+ &lea ($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
+ &call ("_vpaes_preheat");
+&set_label("pic_point");
+ &cmp ($magic,0);
+ &je (&label("cbc_dec_loop"));
+ &jmp (&label("cbc_enc_loop"));
+
+&set_label("cbc_enc_loop",16);
+ &movdqu ("xmm0",&QWP(0,$inp)); # load input
+ &pxor ("xmm0","xmm1"); # inp^=iv
+ &call ("_vpaes_encrypt_core");
+ &mov ($base,&DWP(0,"esp")); # restore out
+ &mov ($key,&DWP(4,"esp")); # restore key
+ &movdqa ("xmm1","xmm0");
+ &movdqu (&QWP(0,$base,$inp),"xmm0"); # write output
+ &lea ($inp,&DWP(16,$inp));
+ &sub ($out,16);
+ &jnc (&label("cbc_enc_loop"));
+ &jmp (&label("cbc_done"));
+
+&set_label("cbc_dec_loop",16);
+ &movdqu ("xmm0",&QWP(0,$inp)); # load input
+ &movdqa (&QWP(16,"esp"),"xmm1"); # save IV
+ &movdqa (&QWP(32,"esp"),"xmm0"); # save future IV
+ &call ("_vpaes_decrypt_core");
+ &mov ($base,&DWP(0,"esp")); # restore out
+ &mov ($key,&DWP(4,"esp")); # restore key
+ &pxor ("xmm0",&QWP(16,"esp")); # out^=iv
+ &movdqa ("xmm1",&QWP(32,"esp")); # load next IV
+ &movdqu (&QWP(0,$base,$inp),"xmm0"); # write output
+ &lea ($inp,&DWP(16,$inp));
+ &sub ($out,16);
+ &jnc (&label("cbc_dec_loop"));
+
+&set_label("cbc_done");
+ &mov ($base,&DWP(8,"esp")); # restore ivp
+ &mov ("esp",&DWP(48,"esp"));
+ &movdqu (&QWP(0,$base),"xmm1"); # write IV
+&set_label("cbc_abort");
+&function_end("${PREFIX}_cbc_encrypt");
+
+&asm_finish();
diff --git a/deps/openssl/openssl/crypto/aes/asm/vpaes-x86_64.pl b/deps/openssl/openssl/crypto/aes/asm/vpaes-x86_64.pl
new file mode 100644
index 000000000..41f2e46f6
--- /dev/null
+++ b/deps/openssl/openssl/crypto/aes/asm/vpaes-x86_64.pl
@@ -0,0 +1,1207 @@
+#!/usr/bin/env perl
+
+######################################################################
+## Constant-time SSSE3 AES core implementation.
+## version 0.1
+##
+## By Mike Hamburg (Stanford University), 2009
+## Public domain.
+##
+## For details see http://shiftleft.org/papers/vector_aes/ and
+## http://crypto.stanford.edu/vpaes/.
+
+######################################################################
+# September 2011.
+#
+# Interface to OpenSSL as "almost" drop-in replacement for
+# aes-x86_64.pl. "Almost" refers to the fact that AES_cbc_encrypt
+# doesn't handle partial vectors (doesn't have to if called from
+# EVP only). "Drop-in" implies that this module doesn't share key
+# schedule structure with the original nor does it make assumption
+# about its alignment...
+#
+# Performance summary. aes-x86_64.pl column lists large-block CBC
+# encrypt/decrypt/with-hyper-threading-off(*) results in cycles per
+# byte processed with 128-bit key, and vpaes-x86_64.pl column -
+# [also large-block CBC] encrypt/decrypt.
+#
+# aes-x86_64.pl vpaes-x86_64.pl
+#
+# Core 2(**) 30.5/43.7/14.3 21.8/25.7(***)
+# Nehalem 30.5/42.2/14.6 9.8/11.8
+# Atom 63.9/79.0/32.1 64.0/84.8(***)
+#
+# (*) "Hyper-threading" in the context refers rather to cache shared
+# among multiple cores, than to specifically Intel HTT. As vast
+# majority of contemporary cores share cache, slower code path
+# is common place. In other words "with-hyper-threading-off"
+# results are presented mostly for reference purposes.
+#
+# (**) "Core 2" refers to initial 65nm design, a.k.a. Conroe.
+#
+# (***) Less impressive improvement on Core 2 and Atom is due to slow
+# pshufb, yet it's respectable +40%/78% improvement on Core 2
+# (as implied, over "hyper-threading-safe" code path).
+#
+# <appro@openssl.org>
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+$PREFIX="vpaes";
+
+$code.=<<___;
+.text
+
+##
+## _aes_encrypt_core
+##
+## AES-encrypt %xmm0.
+##
+## Inputs:
+## %xmm0 = input
+## %xmm9-%xmm15 as in _vpaes_preheat
+## (%rdx) = scheduled keys
+##
+## Output in %xmm0
+## Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax
+## Preserves %xmm6 - %xmm8 so you get some local vectors
+##
+##
+.type _vpaes_encrypt_core,\@abi-omnipotent
+.align 16
+_vpaes_encrypt_core:
+ mov %rdx, %r9
+ mov \$16, %r11
+ mov 240(%rdx),%eax
+ movdqa %xmm9, %xmm1
+ movdqa .Lk_ipt(%rip), %xmm2 # iptlo
+ pandn %xmm0, %xmm1
+ movdqu (%r9), %xmm5 # round0 key
+ psrld \$4, %xmm1
+ pand %xmm9, %xmm0
+ pshufb %xmm0, %xmm2
+ movdqa .Lk_ipt+16(%rip), %xmm0 # ipthi
+ pshufb %xmm1, %xmm0
+ pxor %xmm5, %xmm2
+ pxor %xmm2, %xmm0
+ add \$16, %r9
+ lea .Lk_mc_backward(%rip),%r10
+ jmp .Lenc_entry
+
+.align 16
+.Lenc_loop:
+ # middle of middle round
+ movdqa %xmm13, %xmm4 # 4 : sb1u
+ pshufb %xmm2, %xmm4 # 4 = sb1u
+ pxor %xmm5, %xmm4 # 4 = sb1u + k
+ movdqa %xmm12, %xmm0 # 0 : sb1t
+ pshufb %xmm3, %xmm0 # 0 = sb1t
+ pxor %xmm4, %xmm0 # 0 = A
+ movdqa %xmm15, %xmm5 # 4 : sb2u
+ pshufb %xmm2, %xmm5 # 4 = sb2u
+ movdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[]
+ movdqa %xmm14, %xmm2 # 2 : sb2t
+ pshufb %xmm3, %xmm2 # 2 = sb2t
+ pxor %xmm5, %xmm2 # 2 = 2A
+ movdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[]
+ movdqa %xmm0, %xmm3 # 3 = A
+ pshufb %xmm1, %xmm0 # 0 = B
+ add \$16, %r9 # next key
+ pxor %xmm2, %xmm0 # 0 = 2A+B
+ pshufb %xmm4, %xmm3 # 3 = D
+ add \$16, %r11 # next mc
+ pxor %xmm0, %xmm3 # 3 = 2A+B+D
+ pshufb %xmm1, %xmm0 # 0 = 2B+C
+ and \$0x30, %r11 # ... mod 4
+ pxor %xmm3, %xmm0 # 0 = 2A+3B+C+D
+ sub \$1,%rax # nr--
+
+.Lenc_entry:
+ # top of round
+ movdqa %xmm9, %xmm1 # 1 : i
+ pandn %xmm0, %xmm1 # 1 = i<<4
+ psrld \$4, %xmm1 # 1 = i
+ pand %xmm9, %xmm0 # 0 = k
+ movdqa %xmm11, %xmm5 # 2 : a/k
+ pshufb %xmm0, %xmm5 # 2 = a/k
+ pxor %xmm1, %xmm0 # 0 = j
+ movdqa %xmm10, %xmm3 # 3 : 1/i
+ pshufb %xmm1, %xmm3 # 3 = 1/i
+ pxor %xmm5, %xmm3 # 3 = iak = 1/i + a/k
+ movdqa %xmm10, %xmm4 # 4 : 1/j
+ pshufb %xmm0, %xmm4 # 4 = 1/j
+ pxor %xmm5, %xmm4 # 4 = jak = 1/j + a/k
+ movdqa %xmm10, %xmm2 # 2 : 1/iak
+ pshufb %xmm3, %xmm2 # 2 = 1/iak
+ pxor %xmm0, %xmm2 # 2 = io
+ movdqa %xmm10, %xmm3 # 3 : 1/jak
+ movdqu (%r9), %xmm5
+ pshufb %xmm4, %xmm3 # 3 = 1/jak
+ pxor %xmm1, %xmm3 # 3 = jo
+ jnz .Lenc_loop
+
+ # middle of last round
+ movdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo
+ movdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16
+ pshufb %xmm2, %xmm4 # 4 = sbou
+ pxor %xmm5, %xmm4 # 4 = sb1u + k
+ pshufb %xmm3, %xmm0 # 0 = sb1t
+ movdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[]
+ pxor %xmm4, %xmm0 # 0 = A
+ pshufb %xmm1, %xmm0
+ ret
+.size _vpaes_encrypt_core,.-_vpaes_encrypt_core
+
+##
+## Decryption core
+##
+## Same API as encryption core.
+##
+.type _vpaes_decrypt_core,\@abi-omnipotent
+.align 16
+_vpaes_decrypt_core:
+ mov %rdx, %r9 # load key
+ mov 240(%rdx),%eax
+ movdqa %xmm9, %xmm1
+ movdqa .Lk_dipt(%rip), %xmm2 # iptlo
+ pandn %xmm0, %xmm1
+ mov %rax, %r11
+ psrld \$4, %xmm1
+ movdqu (%r9), %xmm5 # round0 key
+ shl \$4, %r11
+ pand %xmm9, %xmm0
+ pshufb %xmm0, %xmm2
+ movdqa .Lk_dipt+16(%rip), %xmm0 # ipthi
+ xor \$0x30, %r11
+ lea .Lk_dsbd(%rip),%r10
+ pshufb %xmm1, %xmm0
+ and \$0x30, %r11
+ pxor %xmm5, %xmm2
+ movdqa .Lk_mc_forward+48(%rip), %xmm5
+ pxor %xmm2, %xmm0
+ add \$16, %r9
+ add %r10, %r11
+ jmp .Ldec_entry
+
+.align 16
+.Ldec_loop:
+##
+## Inverse mix columns
+##
+ movdqa -0x20(%r10),%xmm4 # 4 : sb9u
+ pshufb %xmm2, %xmm4 # 4 = sb9u
+ pxor %xmm0, %xmm4
+ movdqa -0x10(%r10),%xmm0 # 0 : sb9t
+ pshufb %xmm3, %xmm0 # 0 = sb9t
+ pxor %xmm4, %xmm0 # 0 = ch
+ add \$16, %r9 # next round key
+
+ pshufb %xmm5, %xmm0 # MC ch
+ movdqa 0x00(%r10),%xmm4 # 4 : sbdu
+ pshufb %xmm2, %xmm4 # 4 = sbdu
+ pxor %xmm0, %xmm4 # 4 = ch
+ movdqa 0x10(%r10),%xmm0 # 0 : sbdt
+ pshufb %xmm3, %xmm0 # 0 = sbdt
+ pxor %xmm4, %xmm0 # 0 = ch
+ sub \$1,%rax # nr--
+
+ pshufb %xmm5, %xmm0 # MC ch
+ movdqa 0x20(%r10),%xmm4 # 4 : sbbu
+ pshufb %xmm2, %xmm4 # 4 = sbbu
+ pxor %xmm0, %xmm4 # 4 = ch
+ movdqa 0x30(%r10),%xmm0 # 0 : sbbt
+ pshufb %xmm3, %xmm0 # 0 = sbbt
+ pxor %xmm4, %xmm0 # 0 = ch
+
+ pshufb %xmm5, %xmm0 # MC ch
+ movdqa 0x40(%r10),%xmm4 # 4 : sbeu
+ pshufb %xmm2, %xmm4 # 4 = sbeu
+ pxor %xmm0, %xmm4 # 4 = ch
+ movdqa 0x50(%r10),%xmm0 # 0 : sbet
+ pshufb %xmm3, %xmm0 # 0 = sbet
+ pxor %xmm4, %xmm0 # 0 = ch
+
+ palignr \$12, %xmm5, %xmm5
+
+.Ldec_entry:
+ # top of round
+ movdqa %xmm9, %xmm1 # 1 : i
+ pandn %xmm0, %xmm1 # 1 = i<<4
+ psrld \$4, %xmm1 # 1 = i
+ pand %xmm9, %xmm0 # 0 = k
+ movdqa %xmm11, %xmm2 # 2 : a/k
+ pshufb %xmm0, %xmm2 # 2 = a/k
+ pxor %xmm1, %xmm0 # 0 = j
+ movdqa %xmm10, %xmm3 # 3 : 1/i
+ pshufb %xmm1, %xmm3 # 3 = 1/i
+ pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k
+ movdqa %xmm10, %xmm4 # 4 : 1/j
+ pshufb %xmm0, %xmm4 # 4 = 1/j
+ pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k
+ movdqa %xmm10, %xmm2 # 2 : 1/iak
+ pshufb %xmm3, %xmm2 # 2 = 1/iak
+ pxor %xmm0, %xmm2 # 2 = io
+ movdqa %xmm10, %xmm3 # 3 : 1/jak
+ pshufb %xmm4, %xmm3 # 3 = 1/jak
+ pxor %xmm1, %xmm3 # 3 = jo
+ movdqu (%r9), %xmm0
+ jnz .Ldec_loop
+
+ # middle of last round
+ movdqa 0x60(%r10), %xmm4 # 3 : sbou
+ pshufb %xmm2, %xmm4 # 4 = sbou
+ pxor %xmm0, %xmm4 # 4 = sb1u + k
+ movdqa 0x70(%r10), %xmm0 # 0 : sbot
+ movdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160
+ pshufb %xmm3, %xmm0 # 0 = sb1t
+ pxor %xmm4, %xmm0 # 0 = A
+ pshufb %xmm2, %xmm0
+ ret
+.size _vpaes_decrypt_core,.-_vpaes_decrypt_core
+
+########################################################
+## ##
+## AES key schedule ##
+## ##
+########################################################
+.type _vpaes_schedule_core,\@abi-omnipotent
+.align 16
+_vpaes_schedule_core:
+ # rdi = key
+ # rsi = size in bits
+ # rdx = buffer
+ # rcx = direction. 0=encrypt, 1=decrypt
+
+ call _vpaes_preheat # load the tables
+ movdqa .Lk_rcon(%rip), %xmm8 # load rcon
+ movdqu (%rdi), %xmm0 # load key (unaligned)
+
+ # input transform
+ movdqa %xmm0, %xmm3
+ lea .Lk_ipt(%rip), %r11
+ call _vpaes_schedule_transform
+ movdqa %xmm0, %xmm7
+
+ lea .Lk_sr(%rip),%r10
+ test %rcx, %rcx
+ jnz .Lschedule_am_decrypting
+
+ # encrypting, output zeroth round key after transform
+ movdqu %xmm0, (%rdx)
+ jmp .Lschedule_go
+
+.Lschedule_am_decrypting:
+ # decrypting, output zeroth round key after shiftrows
+ movdqa (%r8,%r10),%xmm1
+ pshufb %xmm1, %xmm3
+ movdqu %xmm3, (%rdx)
+ xor \$0x30, %r8
+
+.Lschedule_go:
+ cmp \$192, %esi
+ ja .Lschedule_256
+ je .Lschedule_192
+ # 128: fall though
+
+##
+## .schedule_128
+##
+## 128-bit specific part of key schedule.
+##
+## This schedule is really simple, because all its parts
+## are accomplished by the subroutines.
+##
+.Lschedule_128:
+ mov \$10, %esi
+
+.Loop_schedule_128:
+ call _vpaes_schedule_round
+ dec %rsi
+ jz .Lschedule_mangle_last
+ call _vpaes_schedule_mangle # write output
+ jmp .Loop_schedule_128
+
+##
+## .aes_schedule_192
+##
+## 192-bit specific part of key schedule.
+##
+## The main body of this schedule is the same as the 128-bit
+## schedule, but with more smearing. The long, high side is
+## stored in %xmm7 as before, and the short, low side is in
+## the high bits of %xmm6.
+##
+## This schedule is somewhat nastier, however, because each
+## round produces 192 bits of key material, or 1.5 round keys.
+## Therefore, on each cycle we do 2 rounds and produce 3 round
+## keys.
+##
+.align 16
+.Lschedule_192:
+ movdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned)
+ call _vpaes_schedule_transform # input transform
+ movdqa %xmm0, %xmm6 # save short part
+ pxor %xmm4, %xmm4 # clear 4
+ movhlps %xmm4, %xmm6 # clobber low side with zeros
+ mov \$4, %esi
+
+.Loop_schedule_192:
+ call _vpaes_schedule_round
+ palignr \$8,%xmm6,%xmm0
+ call _vpaes_schedule_mangle # save key n
+ call _vpaes_schedule_192_smear
+ call _vpaes_schedule_mangle # save key n+1
+ call _vpaes_schedule_round
+ dec %rsi
+ jz .Lschedule_mangle_last
+ call _vpaes_schedule_mangle # save key n+2
+ call _vpaes_schedule_192_smear
+ jmp .Loop_schedule_192
+
+##
+## .aes_schedule_256
+##
+## 256-bit specific part of key schedule.
+##
+## The structure here is very similar to the 128-bit
+## schedule, but with an additional "low side" in
+## %xmm6. The low side's rounds are the same as the
+## high side's, except no rcon and no rotation.
+##
+.align 16
+.Lschedule_256:
+ movdqu 16(%rdi),%xmm0 # load key part 2 (unaligned)
+ call _vpaes_schedule_transform # input transform
+ mov \$7, %esi
+
+.Loop_schedule_256:
+ call _vpaes_schedule_mangle # output low result
+ movdqa %xmm0, %xmm6 # save cur_lo in xmm6
+
+ # high round
+ call _vpaes_schedule_round
+ dec %rsi
+ jz .Lschedule_mangle_last
+ call _vpaes_schedule_mangle
+
+ # low round. swap xmm7 and xmm6
+ pshufd \$0xFF, %xmm0, %xmm0
+ movdqa %xmm7, %xmm5
+ movdqa %xmm6, %xmm7
+ call _vpaes_schedule_low_round
+ movdqa %xmm5, %xmm7
+
+ jmp .Loop_schedule_256
+
+
+##
+## .aes_schedule_mangle_last
+##
+## Mangler for last round of key schedule
+## Mangles %xmm0
+## when encrypting, outputs out(%xmm0) ^ 63
+## when decrypting, outputs unskew(%xmm0)
+##
+## Always called right before return... jumps to cleanup and exits
+##
+.align 16
+.Lschedule_mangle_last:
+ # schedule last round key from xmm0
+ lea .Lk_deskew(%rip),%r11 # prepare to deskew
+ test %rcx, %rcx
+ jnz .Lschedule_mangle_last_dec
+
+ # encrypting
+ movdqa (%r8,%r10),%xmm1
+ pshufb %xmm1, %xmm0 # output permute
+ lea .Lk_opt(%rip), %r11 # prepare to output transform
+ add \$32, %rdx
+
+.Lschedule_mangle_last_dec:
+ add \$-16, %rdx
+ pxor .Lk_s63(%rip), %xmm0
+ call _vpaes_schedule_transform # output transform
+ movdqu %xmm0, (%rdx) # save last key
+
+ # cleanup
+ pxor %xmm0, %xmm0
+ pxor %xmm1, %xmm1
+ pxor %xmm2, %xmm2
+ pxor %xmm3, %xmm3
+ pxor %xmm4, %xmm4
+ pxor %xmm5, %xmm5
+ pxor %xmm6, %xmm6
+ pxor %xmm7, %xmm7
+ ret
+.size _vpaes_schedule_core,.-_vpaes_schedule_core
+
+##
+## .aes_schedule_192_smear
+##
+## Smear the short, low side in the 192-bit key schedule.
+##
+## Inputs:
+## %xmm7: high side, b a x y
+## %xmm6: low side, d c 0 0
+## %xmm13: 0
+##
+## Outputs:
+## %xmm6: b+c+d b+c 0 0
+## %xmm0: b+c+d b+c b a
+##
+.type _vpaes_schedule_192_smear,\@abi-omnipotent
+.align 16
+_vpaes_schedule_192_smear:
+ pshufd \$0x80, %xmm6, %xmm0 # d c 0 0 -> c 0 0 0
+ pxor %xmm0, %xmm6 # -> c+d c 0 0
+ pshufd \$0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a
+ pxor %xmm0, %xmm6 # -> b+c+d b+c b a
+ movdqa %xmm6, %xmm0
+ pxor %xmm1, %xmm1
+ movhlps %xmm1, %xmm6 # clobber low side with zeros
+ ret
+.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
+
+##
+## .aes_schedule_round
+##
+## Runs one main round of the key schedule on %xmm0, %xmm7
+##
+## Specifically, runs subbytes on the high dword of %xmm0
+## then rotates it by one byte and xors into the low dword of
+## %xmm7.
+##
+## Adds rcon from low byte of %xmm8, then rotates %xmm8 for
+## next rcon.
+##
+## Smears the dwords of %xmm7 by xoring the low into the
+## second low, result into third, result into highest.
+##
+## Returns results in %xmm7 = %xmm0.
+## Clobbers %xmm1-%xmm4, %r11.
+##
+.type _vpaes_schedule_round,\@abi-omnipotent
+.align 16
+_vpaes_schedule_round:
+ # extract rcon from xmm8
+ pxor %xmm1, %xmm1
+ palignr \$15, %xmm8, %xmm1
+ palignr \$15, %xmm8, %xmm8
+ pxor %xmm1, %xmm7
+
+ # rotate
+ pshufd \$0xFF, %xmm0, %xmm0
+ palignr \$1, %xmm0, %xmm0
+
+ # fall through...
+
+ # low round: same as high round, but no rotation and no rcon.
+_vpaes_schedule_low_round:
+ # smear xmm7
+ movdqa %xmm7, %xmm1
+ pslldq \$4, %xmm7
+ pxor %xmm1, %xmm7
+ movdqa %xmm7, %xmm1
+ pslldq \$8, %xmm7
+ pxor %xmm1, %xmm7
+ pxor .Lk_s63(%rip), %xmm7
+
+ # subbytes
+ movdqa %xmm9, %xmm1
+ pandn %xmm0, %xmm1
+ psrld \$4, %xmm1 # 1 = i
+ pand %xmm9, %xmm0 # 0 = k
+ movdqa %xmm11, %xmm2 # 2 : a/k
+ pshufb %xmm0, %xmm2 # 2 = a/k
+ pxor %xmm1, %xmm0 # 0 = j
+ movdqa %xmm10, %xmm3 # 3 : 1/i
+ pshufb %xmm1, %xmm3 # 3 = 1/i
+ pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k
+ movdqa %xmm10, %xmm4 # 4 : 1/j
+ pshufb %xmm0, %xmm4 # 4 = 1/j
+ pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k
+ movdqa %xmm10, %xmm2 # 2 : 1/iak
+ pshufb %xmm3, %xmm2 # 2 = 1/iak
+ pxor %xmm0, %xmm2 # 2 = io
+ movdqa %xmm10, %xmm3 # 3 : 1/jak
+ pshufb %xmm4, %xmm3 # 3 = 1/jak
+ pxor %xmm1, %xmm3 # 3 = jo
+ movdqa %xmm13, %xmm4 # 4 : sbou
+ pshufb %xmm2, %xmm4 # 4 = sbou
+ movdqa %xmm12, %xmm0 # 0 : sbot
+ pshufb %xmm3, %xmm0 # 0 = sb1t
+ pxor %xmm4, %xmm0 # 0 = sbox output
+
+ # add in smeared stuff
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, %xmm7
+ ret
+.size _vpaes_schedule_round,.-_vpaes_schedule_round
+
+##
+## .aes_schedule_transform
+##
+## Linear-transform %xmm0 according to tables at (%r11)
+##
+## Requires that %xmm9 = 0x0F0F... as in preheat
+## Output in %xmm0
+## Clobbers %xmm1, %xmm2
+##
+.type _vpaes_schedule_transform,\@abi-omnipotent
+.align 16
+_vpaes_schedule_transform:
+ movdqa %xmm9, %xmm1
+ pandn %xmm0, %xmm1
+ psrld \$4, %xmm1
+ pand %xmm9, %xmm0
+ movdqa (%r11), %xmm2 # lo
+ pshufb %xmm0, %xmm2
+ movdqa 16(%r11), %xmm0 # hi
+ pshufb %xmm1, %xmm0
+ pxor %xmm2, %xmm0
+ ret
+.size _vpaes_schedule_transform,.-_vpaes_schedule_transform
+
+##
+## .aes_schedule_mangle
+##
+## Mangle xmm0 from (basis-transformed) standard version
+## to our version.
+##
+## On encrypt,
+## xor with 0x63
+## multiply by circulant 0,1,1,1
+## apply shiftrows transform
+##
+## On decrypt,
+## xor with 0x63
+## multiply by "inverse mixcolumns" circulant E,B,D,9
+## deskew
+## apply shiftrows transform
+##
+##
+## Writes out to (%rdx), and increments or decrements it
+## Keeps track of round number mod 4 in %r8
+## Preserves xmm0
+## Clobbers xmm1-xmm5
+##
+.type _vpaes_schedule_mangle,\@abi-omnipotent
+.align 16
+_vpaes_schedule_mangle:
+ movdqa %xmm0, %xmm4 # save xmm0 for later
+ movdqa .Lk_mc_forward(%rip),%xmm5
+ test %rcx, %rcx
+ jnz .Lschedule_mangle_dec
+
+ # encrypting
+ add \$16, %rdx
+ pxor .Lk_s63(%rip),%xmm4
+ pshufb %xmm5, %xmm4
+ movdqa %xmm4, %xmm3
+ pshufb %xmm5, %xmm4
+ pxor %xmm4, %xmm3
+ pshufb %xmm5, %xmm4
+ pxor %xmm4, %xmm3
+
+ jmp .Lschedule_mangle_both
+.align 16
+.Lschedule_mangle_dec:
+ # inverse mix columns
+ lea .Lk_dksd(%rip),%r11
+ movdqa %xmm9, %xmm1
+ pandn %xmm4, %xmm1
+ psrld \$4, %xmm1 # 1 = hi
+ pand %xmm9, %xmm4 # 4 = lo
+
+ movdqa 0x00(%r11), %xmm2
+ pshufb %xmm4, %xmm2
+ movdqa 0x10(%r11), %xmm3
+ pshufb %xmm1, %xmm3
+ pxor %xmm2, %xmm3
+ pshufb %xmm5, %xmm3
+
+ movdqa 0x20(%r11), %xmm2
+ pshufb %xmm4, %xmm2
+ pxor %xmm3, %xmm2
+ movdqa 0x30(%r11), %xmm3
+ pshufb %xmm1, %xmm3
+ pxor %xmm2, %xmm3
+ pshufb %xmm5, %xmm3
+
+ movdqa 0x40(%r11), %xmm2
+ pshufb %xmm4, %xmm2
+ pxor %xmm3, %xmm2
+ movdqa 0x50(%r11), %xmm3
+ pshufb %xmm1, %xmm3
+ pxor %xmm2, %xmm3
+ pshufb %xmm5, %xmm3
+
+ movdqa 0x60(%r11), %xmm2
+ pshufb %xmm4, %xmm2
+ pxor %xmm3, %xmm2
+ movdqa 0x70(%r11), %xmm3
+ pshufb %xmm1, %xmm3
+ pxor %xmm2, %xmm3
+
+ add \$-16, %rdx
+
+.Lschedule_mangle_both:
+ movdqa (%r8,%r10),%xmm1
+ pshufb %xmm1,%xmm3
+ add \$-16, %r8
+ and \$0x30, %r8
+ movdqu %xmm3, (%rdx)
+ ret
+.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle
+
+#
+# Interface to OpenSSL
+#
+.globl ${PREFIX}_set_encrypt_key
+.type ${PREFIX}_set_encrypt_key,\@function,3
+.align 16
+${PREFIX}_set_encrypt_key:
+___
+$code.=<<___ if ($win64);
+ lea -0xb8(%rsp),%rsp
+ movaps %xmm6,0x10(%rsp)
+ movaps %xmm7,0x20(%rsp)
+ movaps %xmm8,0x30(%rsp)
+ movaps %xmm9,0x40(%rsp)
+ movaps %xmm10,0x50(%rsp)
+ movaps %xmm11,0x60(%rsp)
+ movaps %xmm12,0x70(%rsp)
+ movaps %xmm13,0x80(%rsp)
+ movaps %xmm14,0x90(%rsp)
+ movaps %xmm15,0xa0(%rsp)
+.Lenc_key_body:
+___
+$code.=<<___;
+ mov %esi,%eax
+ shr \$5,%eax
+ add \$5,%eax
+ mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5;
+
+ mov \$0,%ecx
+ mov \$0x30,%r8d
+ call _vpaes_schedule_core
+___
+$code.=<<___ if ($win64);
+ movaps 0x10(%rsp),%xmm6
+ movaps 0x20(%rsp),%xmm7
+ movaps 0x30(%rsp),%xmm8
+ movaps 0x40(%rsp),%xmm9
+ movaps 0x50(%rsp),%xmm10
+ movaps 0x60(%rsp),%xmm11
+ movaps 0x70(%rsp),%xmm12
+ movaps 0x80(%rsp),%xmm13
+ movaps 0x90(%rsp),%xmm14
+ movaps 0xa0(%rsp),%xmm15
+ lea 0xb8(%rsp),%rsp
+.Lenc_key_epilogue:
+___
+$code.=<<___;
+ xor %eax,%eax
+ ret
+.size ${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key
+
+.globl ${PREFIX}_set_decrypt_key
+.type ${PREFIX}_set_decrypt_key,\@function,3
+.align 16
+${PREFIX}_set_decrypt_key:
+___
+$code.=<<___ if ($win64);
+ lea -0xb8(%rsp),%rsp
+ movaps %xmm6,0x10(%rsp)
+ movaps %xmm7,0x20(%rsp)
+ movaps %xmm8,0x30(%rsp)
+ movaps %xmm9,0x40(%rsp)
+ movaps %xmm10,0x50(%rsp)
+ movaps %xmm11,0x60(%rsp)
+ movaps %xmm12,0x70(%rsp)
+ movaps %xmm13,0x80(%rsp)
+ movaps %xmm14,0x90(%rsp)
+ movaps %xmm15,0xa0(%rsp)
+.Ldec_key_body:
+___
+$code.=<<___;
+ mov %esi,%eax
+ shr \$5,%eax
+ add \$5,%eax
+ mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5;
+ shl \$4,%eax
+ lea 16(%rdx,%rax),%rdx
+
+ mov \$1,%ecx
+ mov %esi,%r8d
+ shr \$1,%r8d
+ and \$32,%r8d
+ xor \$32,%r8d # nbits==192?0:32
+ call _vpaes_schedule_core
+___
+$code.=<<___ if ($win64);
+ movaps 0x10(%rsp),%xmm6
+ movaps 0x20(%rsp),%xmm7
+ movaps 0x30(%rsp),%xmm8
+ movaps 0x40(%rsp),%xmm9
+ movaps 0x50(%rsp),%xmm10
+ movaps 0x60(%rsp),%xmm11
+ movaps 0x70(%rsp),%xmm12
+ movaps 0x80(%rsp),%xmm13
+ movaps 0x90(%rsp),%xmm14
+ movaps 0xa0(%rsp),%xmm15
+ lea 0xb8(%rsp),%rsp
+.Ldec_key_epilogue:
+___
+$code.=<<___;
+ xor %eax,%eax
+ ret
+.size ${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key
+
+.globl ${PREFIX}_encrypt
+.type ${PREFIX}_encrypt,\@function,3
+.align 16
+${PREFIX}_encrypt:
+___
+$code.=<<___ if ($win64);
+ lea -0xb8(%rsp),%rsp
+ movaps %xmm6,0x10(%rsp)
+ movaps %xmm7,0x20(%rsp)
+ movaps %xmm8,0x30(%rsp)
+ movaps %xmm9,0x40(%rsp)
+ movaps %xmm10,0x50(%rsp)
+ movaps %xmm11,0x60(%rsp)
+ movaps %xmm12,0x70(%rsp)
+ movaps %xmm13,0x80(%rsp)
+ movaps %xmm14,0x90(%rsp)
+ movaps %xmm15,0xa0(%rsp)
+.Lenc_body:
+___
+$code.=<<___;
+ movdqu (%rdi),%xmm0
+ call _vpaes_preheat
+ call _vpaes_encrypt_core
+ movdqu %xmm0,(%rsi)
+___
+$code.=<<___ if ($win64);
+ movaps 0x10(%rsp),%xmm6
+ movaps 0x20(%rsp),%xmm7
+ movaps 0x30(%rsp),%xmm8
+ movaps 0x40(%rsp),%xmm9
+ movaps 0x50(%rsp),%xmm10
+ movaps 0x60(%rsp),%xmm11
+ movaps 0x70(%rsp),%xmm12
+ movaps 0x80(%rsp),%xmm13
+ movaps 0x90(%rsp),%xmm14
+ movaps 0xa0(%rsp),%xmm15
+ lea 0xb8(%rsp),%rsp
+.Lenc_epilogue:
+___
+$code.=<<___;
+ ret
+.size ${PREFIX}_encrypt,.-${PREFIX}_encrypt
+
+.globl ${PREFIX}_decrypt
+.type ${PREFIX}_decrypt,\@function,3
+.align 16
+${PREFIX}_decrypt:
+___
+$code.=<<___ if ($win64);
+ lea -0xb8(%rsp),%rsp
+ movaps %xmm6,0x10(%rsp)
+ movaps %xmm7,0x20(%rsp)
+ movaps %xmm8,0x30(%rsp)
+ movaps %xmm9,0x40(%rsp)
+ movaps %xmm10,0x50(%rsp)
+ movaps %xmm11,0x60(%rsp)
+ movaps %xmm12,0x70(%rsp)
+ movaps %xmm13,0x80(%rsp)
+ movaps %xmm14,0x90(%rsp)
+ movaps %xmm15,0xa0(%rsp)
+.Ldec_body:
+___
+$code.=<<___;
+ movdqu (%rdi),%xmm0
+ call _vpaes_preheat
+ call _vpaes_decrypt_core
+ movdqu %xmm0,(%rsi)
+___
+$code.=<<___ if ($win64);
+ movaps 0x10(%rsp),%xmm6
+ movaps 0x20(%rsp),%xmm7
+ movaps 0x30(%rsp),%xmm8
+ movaps 0x40(%rsp),%xmm9
+ movaps 0x50(%rsp),%xmm10
+ movaps 0x60(%rsp),%xmm11
+ movaps 0x70(%rsp),%xmm12
+ movaps 0x80(%rsp),%xmm13
+ movaps 0x90(%rsp),%xmm14
+ movaps 0xa0(%rsp),%xmm15
+ lea 0xb8(%rsp),%rsp
+.Ldec_epilogue:
+___
+$code.=<<___;
+ ret
+.size ${PREFIX}_decrypt,.-${PREFIX}_decrypt
+___
+{
+my ($inp,$out,$len,$key,$ivp,$enc)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9");
+# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
+# size_t length, const AES_KEY *key,
+# unsigned char *ivp,const int enc);
+$code.=<<___;
+.globl ${PREFIX}_cbc_encrypt
+.type ${PREFIX}_cbc_encrypt,\@function,6
+.align 16
+${PREFIX}_cbc_encrypt:
+ xchg $key,$len
+___
+($len,$key)=($key,$len);
+$code.=<<___;
+ sub \$16,$len
+ jc .Lcbc_abort
+___
+$code.=<<___ if ($win64);
+ lea -0xb8(%rsp),%rsp
+ movaps %xmm6,0x10(%rsp)
+ movaps %xmm7,0x20(%rsp)
+ movaps %xmm8,0x30(%rsp)
+ movaps %xmm9,0x40(%rsp)
+ movaps %xmm10,0x50(%rsp)
+ movaps %xmm11,0x60(%rsp)
+ movaps %xmm12,0x70(%rsp)
+ movaps %xmm13,0x80(%rsp)
+ movaps %xmm14,0x90(%rsp)
+ movaps %xmm15,0xa0(%rsp)
+.Lcbc_body:
+___
+$code.=<<___;
+ movdqu ($ivp),%xmm6 # load IV
+ sub $inp,$out
+ call _vpaes_preheat
+ cmp \$0,${enc}d
+ je .Lcbc_dec_loop
+ jmp .Lcbc_enc_loop
+.align 16
+.Lcbc_enc_loop:
+ movdqu ($inp),%xmm0
+ pxor %xmm6,%xmm0
+ call _vpaes_encrypt_core
+ movdqa %xmm0,%xmm6
+ movdqu %xmm0,($out,$inp)
+ lea 16($inp),$inp
+ sub \$16,$len
+ jnc .Lcbc_enc_loop
+ jmp .Lcbc_done
+.align 16
+.Lcbc_dec_loop:
+ movdqu ($inp),%xmm0
+ movdqa %xmm0,%xmm7
+ call _vpaes_decrypt_core
+ pxor %xmm6,%xmm0
+ movdqa %xmm7,%xmm6
+ movdqu %xmm0,($out,$inp)
+ lea 16($inp),$inp
+ sub \$16,$len
+ jnc .Lcbc_dec_loop
+.Lcbc_done:
+ movdqu %xmm6,($ivp) # save IV
+___
+$code.=<<___ if ($win64);
+ movaps 0x10(%rsp),%xmm6
+ movaps 0x20(%rsp),%xmm7
+ movaps 0x30(%rsp),%xmm8
+ movaps 0x40(%rsp),%xmm9
+ movaps 0x50(%rsp),%xmm10
+ movaps 0x60(%rsp),%xmm11
+ movaps 0x70(%rsp),%xmm12
+ movaps 0x80(%rsp),%xmm13
+ movaps 0x90(%rsp),%xmm14
+ movaps 0xa0(%rsp),%xmm15
+ lea 0xb8(%rsp),%rsp
+.Lcbc_epilogue:
+___
+$code.=<<___;
+.Lcbc_abort:
+ ret
+.size ${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt
+___
+}
+$code.=<<___;
+##
+## _aes_preheat
+##
+## Fills register %r10 -> .aes_consts (so you can -fPIC)
+## and %xmm9-%xmm15 as specified below.
+##
+.type _vpaes_preheat,\@abi-omnipotent
+.align 16
+_vpaes_preheat:
+ lea .Lk_s0F(%rip), %r10
+ movdqa -0x20(%r10), %xmm10 # .Lk_inv
+ movdqa -0x10(%r10), %xmm11 # .Lk_inv+16
+ movdqa 0x00(%r10), %xmm9 # .Lk_s0F
+ movdqa 0x30(%r10), %xmm13 # .Lk_sb1
+ movdqa 0x40(%r10), %xmm12 # .Lk_sb1+16
+ movdqa 0x50(%r10), %xmm15 # .Lk_sb2
+ movdqa 0x60(%r10), %xmm14 # .Lk_sb2+16
+ ret
+.size _vpaes_preheat,.-_vpaes_preheat
+########################################################
+## ##
+## Constants ##
+## ##
+########################################################
+.type _vpaes_consts,\@object
+.align 64
+_vpaes_consts:
+.Lk_inv: # inv, inva
+ .quad 0x0E05060F0D080180, 0x040703090A0B0C02
+ .quad 0x01040A060F0B0780, 0x030D0E0C02050809
+
+.Lk_s0F: # s0F
+ .quad 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F
+
+.Lk_ipt: # input transform (lo, hi)
+ .quad 0xC2B2E8985A2A7000, 0xCABAE09052227808
+ .quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
+
+.Lk_sb1: # sb1u, sb1t
+ .quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
+ .quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
+.Lk_sb2: # sb2u, sb2t
+ .quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD
+ .quad 0x69EB88400AE12900, 0xC2A163C8AB82234A
+.Lk_sbo: # sbou, sbot
+ .quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878
+ .quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
+
+.Lk_mc_forward: # mc_forward
+ .quad 0x0407060500030201, 0x0C0F0E0D080B0A09
+ .quad 0x080B0A0904070605, 0x000302010C0F0E0D
+ .quad 0x0C0F0E0D080B0A09, 0x0407060500030201
+ .quad 0x000302010C0F0E0D, 0x080B0A0904070605
+
+.Lk_mc_backward:# mc_backward
+ .quad 0x0605040702010003, 0x0E0D0C0F0A09080B
+ .quad 0x020100030E0D0C0F, 0x0A09080B06050407
+ .quad 0x0E0D0C0F0A09080B, 0x0605040702010003
+ .quad 0x0A09080B06050407, 0x020100030E0D0C0F
+
+.Lk_sr: # sr
+ .quad 0x0706050403020100, 0x0F0E0D0C0B0A0908
+ .quad 0x030E09040F0A0500, 0x0B06010C07020D08
+ .quad 0x0F060D040B020900, 0x070E050C030A0108
+ .quad 0x0B0E0104070A0D00, 0x0306090C0F020508
+
+.Lk_rcon: # rcon
+ .quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
+
+.Lk_s63: # s63: all equal to 0x63 transformed
+ .quad 0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B
+
+.Lk_opt: # output transform
+ .quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808
+ .quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
+
+.Lk_deskew: # deskew tables: inverts the sbox's "skew"
+ .quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
+ .quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
+
+##
+## Decryption stuff
+## Key schedule constants
+##
+.Lk_dksd: # decryption key schedule: invskew x*D
+ .quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
+ .quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E
+.Lk_dksb: # decryption key schedule: invskew x*B
+ .quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99
+ .quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
+.Lk_dkse: # decryption key schedule: invskew x*E + 0x63
+ .quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086
+ .quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487
+.Lk_dks9: # decryption key schedule: invskew x*9
+ .quad 0xB6116FC87ED9A700, 0x4AED933482255BFC
+ .quad 0x4576516227143300, 0x8BB89FACE9DAFDCE
+
+##
+## Decryption stuff
+## Round function constants
+##
+.Lk_dipt: # decryption input transform
+ .quad 0x0F505B040B545F00, 0x154A411E114E451A
+ .quad 0x86E383E660056500, 0x12771772F491F194
+
+.Lk_dsb9: # decryption sbox output *9*u, *9*t
+ .quad 0x851C03539A86D600, 0xCAD51F504F994CC9
+ .quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565
+.Lk_dsbd: # decryption sbox output *D*u, *D*t
+ .quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
+ .quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
+.Lk_dsbb: # decryption sbox output *B*u, *B*t
+ .quad 0xD022649296B44200, 0x602646F6B0F2D404
+ .quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
+.Lk_dsbe: # decryption sbox output *E*u, *E*t
+ .quad 0x46F2929626D4D000, 0x2242600464B4F6B0
+ .quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32
+.Lk_dsbo: # decryption sbox final output
+ .quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
+ .quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C
+.asciz "Vector Permutaion AES for x86_64/SSSE3, Mike Hamburg (Stanford University)"
+.align 64
+.size _vpaes_consts,.-_vpaes_consts
+___
+
+if ($win64) {
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+.type se_handler,\@abi-omnipotent
+.align 16
+se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # prologue label
+ cmp %r10,%rbx # context->Rip<prologue label
+ jb .Lin_prologue
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lin_prologue
+
+ lea 16(%rax),%rsi # %xmm save area
+ lea 512($context),%rdi # &context.Xmm6
+ mov \$20,%ecx # 10*sizeof(%xmm0)/sizeof(%rax)
+ .long 0xa548f3fc # cld; rep movsq
+ lea 0xb8(%rax),%rax # adjust stack pointer
+
+.Lin_prologue:
+ mov 8(%rax),%rdi
+ mov 16(%rax),%rsi
+ mov %rax,152($context) # restore context->Rsp
+ mov %rsi,168($context) # restore context->Rsi
+ mov %rdi,176($context) # restore context->Rdi
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$`1232/8`,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size se_handler,.-se_handler
+
+.section .pdata
+.align 4
+ .rva .LSEH_begin_${PREFIX}_set_encrypt_key
+ .rva .LSEH_end_${PREFIX}_set_encrypt_key
+ .rva .LSEH_info_${PREFIX}_set_encrypt_key
+
+ .rva .LSEH_begin_${PREFIX}_set_decrypt_key
+ .rva .LSEH_end_${PREFIX}_set_decrypt_key
+ .rva .LSEH_info_${PREFIX}_set_decrypt_key
+
+ .rva .LSEH_begin_${PREFIX}_encrypt
+ .rva .LSEH_end_${PREFIX}_encrypt
+ .rva .LSEH_info_${PREFIX}_encrypt
+
+ .rva .LSEH_begin_${PREFIX}_decrypt
+ .rva .LSEH_end_${PREFIX}_decrypt
+ .rva .LSEH_info_${PREFIX}_decrypt
+
+ .rva .LSEH_begin_${PREFIX}_cbc_encrypt
+ .rva .LSEH_end_${PREFIX}_cbc_encrypt
+ .rva .LSEH_info_${PREFIX}_cbc_encrypt
+
+.section .xdata
+.align 8
+.LSEH_info_${PREFIX}_set_encrypt_key:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lenc_key_body,.Lenc_key_epilogue # HandlerData[]
+.LSEH_info_${PREFIX}_set_decrypt_key:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Ldec_key_body,.Ldec_key_epilogue # HandlerData[]
+.LSEH_info_${PREFIX}_encrypt:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lenc_body,.Lenc_epilogue # HandlerData[]
+.LSEH_info_${PREFIX}_decrypt:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Ldec_body,.Ldec_epilogue # HandlerData[]
+.LSEH_info_${PREFIX}_cbc_encrypt:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lcbc_body,.Lcbc_epilogue # HandlerData[]
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+
+print $code;
+
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/arm_arch.h b/deps/openssl/openssl/crypto/arm_arch.h
new file mode 100644
index 000000000..5a8310768
--- /dev/null
+++ b/deps/openssl/openssl/crypto/arm_arch.h
@@ -0,0 +1,51 @@
+#ifndef __ARM_ARCH_H__
+#define __ARM_ARCH_H__
+
+#if !defined(__ARM_ARCH__)
+# if defined(__CC_ARM)
+# define __ARM_ARCH__ __TARGET_ARCH_ARM
+# if defined(__BIG_ENDIAN)
+# define __ARMEB__
+# else
+# define __ARMEL__
+# endif
+# elif defined(__GNUC__)
+ /*
+ * Why doesn't gcc define __ARM_ARCH__? Instead it defines
+ * bunch of below macros. See all_architectires[] table in
+ * gcc/config/arm/arm.c. On a side note it defines
+ * __ARMEL__/__ARMEB__ for little-/big-endian.
+ */
+# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
+ defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
+ defined(__ARM_ARCH_7EM__)
+# define __ARM_ARCH__ 7
+# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
+ defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \
+ defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \
+ defined(__ARM_ARCH_6T2__)
+# define __ARM_ARCH__ 6
+# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \
+ defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \
+ defined(__ARM_ARCH_5TEJ__)
+# define __ARM_ARCH__ 5
+# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
+# define __ARM_ARCH__ 4
+# else
+# error "unsupported ARM architecture"
+# endif
+# endif
+#endif
+
+#ifdef OPENSSL_FIPSCANISTER
+#include <openssl/fipssyms.h>
+#endif
+
+#if !__ASSEMBLER__
+extern unsigned int OPENSSL_armcap_P;
+
+#define ARMV7_NEON (1<<0)
+#define ARMV7_TICK (1<<1)
+#endif
+
+#endif
diff --git a/deps/openssl/openssl/crypto/armcap.c b/deps/openssl/openssl/crypto/armcap.c
new file mode 100644
index 000000000..5258d2fbd
--- /dev/null
+++ b/deps/openssl/openssl/crypto/armcap.c
@@ -0,0 +1,80 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <crypto.h>
+
+#include "arm_arch.h"
+
+unsigned int OPENSSL_armcap_P;
+
+static sigset_t all_masked;
+
+static sigjmp_buf ill_jmp;
+static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
+
+/*
+ * Following subroutines could have been inlined, but it's not all
+ * ARM compilers support inline assembler...
+ */
+void _armv7_neon_probe(void);
+unsigned int _armv7_tick(void);
+
+unsigned int OPENSSL_rdtsc(void)
+ {
+ if (OPENSSL_armcap_P|ARMV7_TICK)
+ return _armv7_tick();
+ else
+ return 0;
+ }
+
+#if defined(__GNUC__) && __GNUC__>=2
+void OPENSSL_cpuid_setup(void) __attribute__((constructor));
+#endif
+void OPENSSL_cpuid_setup(void)
+ {
+ char *e;
+ struct sigaction ill_oact,ill_act;
+ sigset_t oset;
+ static int trigger=0;
+
+ if (trigger) return;
+ trigger=1;
+
+ if ((e=getenv("OPENSSL_armcap")))
+ {
+ OPENSSL_armcap_P=strtoul(e,NULL,0);
+ return;
+ }
+
+ sigfillset(&all_masked);
+ sigdelset(&all_masked,SIGILL);
+ sigdelset(&all_masked,SIGTRAP);
+ sigdelset(&all_masked,SIGFPE);
+ sigdelset(&all_masked,SIGBUS);
+ sigdelset(&all_masked,SIGSEGV);
+
+ OPENSSL_armcap_P = 0;
+
+ memset(&ill_act,0,sizeof(ill_act));
+ ill_act.sa_handler = ill_handler;
+ ill_act.sa_mask = all_masked;
+
+ sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
+ sigaction(SIGILL,&ill_act,&ill_oact);
+
+ if (sigsetjmp(ill_jmp,1) == 0)
+ {
+ _armv7_neon_probe();
+ OPENSSL_armcap_P |= ARMV7_NEON;
+ }
+ if (sigsetjmp(ill_jmp,1) == 0)
+ {
+ _armv7_tick();
+ OPENSSL_armcap_P |= ARMV7_TICK;
+ }
+
+ sigaction (SIGILL,&ill_oact,NULL);
+ sigprocmask(SIG_SETMASK,&oset,NULL);
+ }
diff --git a/deps/openssl/openssl/crypto/armv4cpuid.S b/deps/openssl/openssl/crypto/armv4cpuid.S
new file mode 100644
index 000000000..2d618deaa
--- /dev/null
+++ b/deps/openssl/openssl/crypto/armv4cpuid.S
@@ -0,0 +1,154 @@
+#include "arm_arch.h"
+
+.text
+.code 32
+
+.align 5
+.global _armv7_neon_probe
+.type _armv7_neon_probe,%function
+_armv7_neon_probe:
+ .word 0xf26ee1fe @ vorr q15,q15,q15
+ .word 0xe12fff1e @ bx lr
+.size _armv7_neon_probe,.-_armv7_neon_probe
+
+.global _armv7_tick
+.type _armv7_tick,%function
+_armv7_tick:
+ mrc p15,0,r0,c9,c13,0
+ .word 0xe12fff1e @ bx lr
+.size _armv7_tick,.-_armv7_tick
+
+.global OPENSSL_atomic_add
+.type OPENSSL_atomic_add,%function
+OPENSSL_atomic_add:
+#if __ARM_ARCH__>=6
+.Ladd: ldrex r2,[r0]
+ add r3,r2,r1
+ strex r2,r3,[r0]
+ cmp r2,#0
+ bne .Ladd
+ mov r0,r3
+ .word 0xe12fff1e @ bx lr
+#else
+ stmdb sp!,{r4-r6,lr}
+ ldr r2,.Lspinlock
+ adr r3,.Lspinlock
+ mov r4,r0
+ mov r5,r1
+ add r6,r3,r2 @ &spinlock
+ b .+8
+.Lspin: bl sched_yield
+ mov r0,#-1
+ swp r0,r0,[r6]
+ cmp r0,#0
+ bne .Lspin
+
+ ldr r2,[r4]
+ add r2,r2,r5
+ str r2,[r4]
+ str r0,[r6] @ release spinlock
+ ldmia sp!,{r4-r6,lr}
+ tst lr,#1
+ moveq pc,lr
+ .word 0xe12fff1e @ bx lr
+#endif
+.size OPENSSL_atomic_add,.-OPENSSL_atomic_add
+
+.global OPENSSL_cleanse
+.type OPENSSL_cleanse,%function
+OPENSSL_cleanse:
+ eor ip,ip,ip
+ cmp r1,#7
+ subhs r1,r1,#4
+ bhs .Lot
+ cmp r1,#0
+ beq .Lcleanse_done
+.Little:
+ strb ip,[r0],#1
+ subs r1,r1,#1
+ bhi .Little
+ b .Lcleanse_done
+
+.Lot: tst r0,#3
+ beq .Laligned
+ strb ip,[r0],#1
+ sub r1,r1,#1
+ b .Lot
+.Laligned:
+ str ip,[r0],#4
+ subs r1,r1,#4
+ bhs .Laligned
+ adds r1,r1,#4
+ bne .Little
+.Lcleanse_done:
+ tst lr,#1
+ moveq pc,lr
+ .word 0xe12fff1e @ bx lr
+.size OPENSSL_cleanse,.-OPENSSL_cleanse
+
+.global OPENSSL_wipe_cpu
+.type OPENSSL_wipe_cpu,%function
+OPENSSL_wipe_cpu:
+ ldr r0,.LOPENSSL_armcap
+ adr r1,.LOPENSSL_armcap
+ ldr r0,[r1,r0]
+ eor r2,r2,r2
+ eor r3,r3,r3
+ eor ip,ip,ip
+ tst r0,#1
+ beq .Lwipe_done
+ .word 0xf3000150 @ veor q0, q0, q0
+ .word 0xf3022152 @ veor q1, q1, q1
+ .word 0xf3044154 @ veor q2, q2, q2
+ .word 0xf3066156 @ veor q3, q3, q3
+ .word 0xf34001f0 @ veor q8, q8, q8
+ .word 0xf34221f2 @ veor q9, q9, q9
+ .word 0xf34441f4 @ veor q10, q10, q10
+ .word 0xf34661f6 @ veor q11, q11, q11
+ .word 0xf34881f8 @ veor q12, q12, q12
+ .word 0xf34aa1fa @ veor q13, q13, q13
+ .word 0xf34cc1fc @ veor q14, q14, q14
+ .word 0xf34ee1fe @ veor q15, q15, q15
+.Lwipe_done:
+ mov r0,sp
+ tst lr,#1
+ moveq pc,lr
+ .word 0xe12fff1e @ bx lr
+.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
+
+.global OPENSSL_instrument_bus
+.type OPENSSL_instrument_bus,%function
+OPENSSL_instrument_bus:
+ eor r0,r0,r0
+ tst lr,#1
+ moveq pc,lr
+ .word 0xe12fff1e @ bx lr
+.size OPENSSL_instrument_bus,.-OPENSSL_instrument_bus
+
+.global OPENSSL_instrument_bus2
+.type OPENSSL_instrument_bus2,%function
+OPENSSL_instrument_bus2:
+ eor r0,r0,r0
+ tst lr,#1
+ moveq pc,lr
+ .word 0xe12fff1e @ bx lr
+.size OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2
+
+.align 5
+.LOPENSSL_armcap:
+.word OPENSSL_armcap_P-.LOPENSSL_armcap
+#if __ARM_ARCH__>=6
+.align 5
+#else
+.Lspinlock:
+.word atomic_add_spinlock-.Lspinlock
+.align 5
+
+.data
+.align 2
+atomic_add_spinlock:
+.word 0
+#endif
+
+.comm OPENSSL_armcap_P,4,4
+.hidden OPENSSL_armcap_P
diff --git a/deps/openssl/openssl/crypto/asn1/Makefile b/deps/openssl/openssl/crypto/asn1/Makefile
index 160544eed..f7787005d 100644
--- a/deps/openssl/openssl/crypto/asn1/Makefile
+++ b/deps/openssl/openssl/crypto/asn1/Makefile
@@ -639,7 +639,7 @@ t_x509.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
t_x509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
t_x509.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
t_x509.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-t_x509.o: ../cryptlib.h t_x509.c
+t_x509.o: ../cryptlib.h asn1_locl.h t_x509.c
t_x509a.o: ../../e_os.h ../../include/openssl/asn1.h
t_x509a.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
t_x509a.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
diff --git a/deps/openssl/openssl/crypto/asn1/a_digest.c b/deps/openssl/openssl/crypto/asn1/a_digest.c
index d00d9e22b..cbdeea6ac 100644
--- a/deps/openssl/openssl/crypto/asn1/a_digest.c
+++ b/deps/openssl/openssl/crypto/asn1/a_digest.c
@@ -87,7 +87,8 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
p=str;
i2d(data,&p);
- EVP_Digest(str, i, md, len, type, NULL);
+ if (!EVP_Digest(str, i, md, len, type, NULL))
+ return 0;
OPENSSL_free(str);
return(1);
}
@@ -104,7 +105,8 @@ int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
i=ASN1_item_i2d(asn,&str, it);
if (!str) return(0);
- EVP_Digest(str, i, md, len, type, NULL);
+ if (!EVP_Digest(str, i, md, len, type, NULL))
+ return 0;
OPENSSL_free(str);
return(1);
}
diff --git a/deps/openssl/openssl/crypto/asn1/a_int.c b/deps/openssl/openssl/crypto/asn1/a_int.c
index 3348b8762..ad0d2506f 100644
--- a/deps/openssl/openssl/crypto/asn1/a_int.c
+++ b/deps/openssl/openssl/crypto/asn1/a_int.c
@@ -386,8 +386,8 @@ long ASN1_INTEGER_get(const ASN1_INTEGER *a)
if (a->length > (int)sizeof(long))
{
- /* hmm... a bit ugly */
- return(0xffffffffL);
+ /* hmm... a bit ugly, return all ones */
+ return -1;
}
if (a->data == NULL)
return 0;
diff --git a/deps/openssl/openssl/crypto/asn1/a_sign.c b/deps/openssl/openssl/crypto/asn1/a_sign.c
index ff63bfc7b..7b4a193d6 100644
--- a/deps/openssl/openssl/crypto/asn1/a_sign.c
+++ b/deps/openssl/openssl/crypto/asn1/a_sign.c
@@ -184,9 +184,9 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
p=buf_in;
i2d(data,&p);
- EVP_SignInit_ex(&ctx,type, NULL);
- EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
- if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
+ if (!EVP_SignInit_ex(&ctx,type, NULL)
+ || !EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl)
+ || !EVP_SignFinal(&ctx,(unsigned char *)buf_out,
(unsigned int *)&outl,pkey))
{
outl=0;
@@ -218,65 +218,100 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
const EVP_MD *type)
{
EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+ if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey))
+ {
+ EVP_MD_CTX_cleanup(&ctx);
+ return 0;
+ }
+ return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
+ }
+
+
+int ASN1_item_sign_ctx(const ASN1_ITEM *it,
+ X509_ALGOR *algor1, X509_ALGOR *algor2,
+ ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
+ {
+ const EVP_MD *type;
+ EVP_PKEY *pkey;
unsigned char *buf_in=NULL,*buf_out=NULL;
- int inl=0,outl=0,outll=0;
+ size_t inl=0,outl=0,outll=0;
int signid, paramtype;
+ int rv;
+
+ type = EVP_MD_CTX_md(ctx);
+ pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
- if (type == NULL)
+ if (!type || !pkey)
{
- int def_nid;
- if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
- type = EVP_get_digestbynid(def_nid);
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
+ return 0;
}
- if (type == NULL)
+ if (pkey->ameth->item_sign)
{
- ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST);
- return 0;
+ rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2,
+ signature);
+ if (rv == 1)
+ outl = signature->length;
+ /* Return value meanings:
+ * <=0: error.
+ * 1: method does everything.
+ * 2: carry on as normal.
+ * 3: ASN1 method sets algorithm identifiers: just sign.
+ */
+ if (rv <= 0)
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+ if (rv <= 1)
+ goto err;
}
+ else
+ rv = 2;
- if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+ if (rv == 2)
{
- if (!pkey->ameth ||
- !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type),
- pkey->ameth->pkey_id))
+ if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
{
- ASN1err(ASN1_F_ASN1_ITEM_SIGN,
- ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
- return 0;
+ if (!pkey->ameth ||
+ !OBJ_find_sigid_by_algs(&signid,
+ EVP_MD_nid(type),
+ pkey->ameth->pkey_id))
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
+ ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+ return 0;
+ }
}
- }
- else
- signid = type->pkey_type;
+ else
+ signid = type->pkey_type;
- if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
- paramtype = V_ASN1_NULL;
- else
- paramtype = V_ASN1_UNDEF;
+ if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
+ paramtype = V_ASN1_NULL;
+ else
+ paramtype = V_ASN1_UNDEF;
- if (algor1)
- X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
- if (algor2)
- X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+ if (algor1)
+ X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
+ if (algor2)
+ X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+
+ }
- EVP_MD_CTX_init(&ctx);
inl=ASN1_item_i2d(asn,&buf_in, it);
outll=outl=EVP_PKEY_size(pkey);
- buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
+ buf_out=OPENSSL_malloc((unsigned int)outl);
if ((buf_in == NULL) || (buf_out == NULL))
{
outl=0;
- ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_MALLOC_FAILURE);
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_MALLOC_FAILURE);
goto err;
}
- EVP_SignInit_ex(&ctx,type, NULL);
- EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
- if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
- (unsigned int *)&outl,pkey))
+ if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
+ || !EVP_DigestSignFinal(ctx, buf_out, &outl))
{
outl=0;
- ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB);
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_EVP_LIB);
goto err;
}
if (signature->data != NULL) OPENSSL_free(signature->data);
@@ -289,7 +324,7 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
err:
- EVP_MD_CTX_cleanup(&ctx);
+ EVP_MD_CTX_cleanup(ctx);
if (buf_in != NULL)
{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
if (buf_out != NULL)
diff --git a/deps/openssl/openssl/crypto/asn1/a_strex.c b/deps/openssl/openssl/crypto/asn1/a_strex.c
index 8a467abd7..bf63330f0 100644
--- a/deps/openssl/openssl/crypto/asn1/a_strex.c
+++ b/deps/openssl/openssl/crypto/asn1/a_strex.c
@@ -568,6 +568,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
mbflag |= MBSTRING_FLAG;
memset(&stmp, 0, sizeof(stmp));
stmp.data = NULL;
+ stmp.length = 0;
ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
if(ret < 0) return ret;
*out = stmp.data;
diff --git a/deps/openssl/openssl/crypto/asn1/a_verify.c b/deps/openssl/openssl/crypto/asn1/a_verify.c
index cecdb13c7..fc84cd3d1 100644
--- a/deps/openssl/openssl/crypto/asn1/a_verify.c
+++ b/deps/openssl/openssl/crypto/asn1/a_verify.c
@@ -101,8 +101,13 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
p=buf_in;
i2d(data,&p);
- EVP_VerifyInit_ex(&ctx,type, NULL);
- EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl);
+ if (!EVP_VerifyInit_ex(&ctx,type, NULL)
+ || !EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl))
+ {
+ ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
+ ret=0;
+ goto err;
+ }
OPENSSL_cleanse(buf_in,(unsigned int)inl);
OPENSSL_free(buf_in);
@@ -126,16 +131,21 @@ err:
#endif
-int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature,
- void *asn, EVP_PKEY *pkey)
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
+ ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
{
EVP_MD_CTX ctx;
- const EVP_MD *type = NULL;
unsigned char *buf_in=NULL;
int ret= -1,inl;
int mdnid, pknid;
+ if (!pkey)
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+
EVP_MD_CTX_init(&ctx);
/* Convert signature OID into digest and public key OIDs */
@@ -144,25 +154,47 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
goto err;
}
- type=EVP_get_digestbynid(mdnid);
- if (type == NULL)
+ if (mdnid == NID_undef)
{
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
- goto err;
+ if (!pkey->ameth || !pkey->ameth->item_verify)
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ goto err;
+ }
+ ret = pkey->ameth->item_verify(&ctx, it, asn, a,
+ signature, pkey);
+ /* Return value of 2 means carry on, anything else means we
+ * exit straight away: either a fatal error of the underlying
+ * verification routine handles all verification.
+ */
+ if (ret != 2)
+ goto err;
+ ret = -1;
}
-
- /* Check public key OID matches public key type */
- if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id)
+ else
{
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
- goto err;
- }
+ const EVP_MD *type;
+ type=EVP_get_digestbynid(mdnid);
+ if (type == NULL)
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ goto err;
+ }
+
+ /* Check public key OID matches public key type */
+ if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id)
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+ goto err;
+ }
+
+ if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey))
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
+ ret=0;
+ goto err;
+ }
- if (!EVP_VerifyInit_ex(&ctx,type, NULL))
- {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
- ret=0;
- goto err;
}
inl = ASN1_item_i2d(asn, &buf_in, it);
@@ -173,13 +205,18 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
goto err;
}
- EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl);
+ if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl))
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
+ ret=0;
+ goto err;
+ }
OPENSSL_cleanse(buf_in,(unsigned int)inl);
OPENSSL_free(buf_in);
- if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data,
- (unsigned int)signature->length,pkey) <= 0)
+ if (EVP_DigestVerifyFinal(&ctx,signature->data,
+ (size_t)signature->length) <= 0)
{
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
ret=0;
diff --git a/deps/openssl/openssl/crypto/asn1/ameth_lib.c b/deps/openssl/openssl/crypto/asn1/ameth_lib.c
index 5a581b90e..a19e058fc 100644
--- a/deps/openssl/openssl/crypto/asn1/ameth_lib.c
+++ b/deps/openssl/openssl/crypto/asn1/ameth_lib.c
@@ -69,6 +69,7 @@ extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
/* Keep this sorted in type order !! */
static const EVP_PKEY_ASN1_METHOD *standard_methods[] =
@@ -90,7 +91,8 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] =
#ifndef OPENSSL_NO_EC
&eckey_asn1_meth,
#endif
- &hmac_asn1_meth
+ &hmac_asn1_meth,
+ &cmac_asn1_meth
};
typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
@@ -291,6 +293,8 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
if (!ameth)
return NULL;
+ memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD));
+
ameth->pkey_id = id;
ameth->pkey_base_id = id;
ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
@@ -325,6 +329,9 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
ameth->old_priv_encode = 0;
ameth->old_priv_decode = 0;
+ ameth->item_verify = 0;
+ ameth->item_sign = 0;
+
ameth->pkey_size = 0;
ameth->pkey_bits = 0;
@@ -376,6 +383,9 @@ void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
dst->pkey_free = src->pkey_free;
dst->pkey_ctrl = src->pkey_ctrl;
+ dst->item_sign = src->item_sign;
+ dst->item_verify = src->item_verify;
+
}
void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
diff --git a/deps/openssl/openssl/crypto/asn1/asn1.h b/deps/openssl/openssl/crypto/asn1/asn1.h
index 59540e4e7..220a0c8c6 100644
--- a/deps/openssl/openssl/crypto/asn1/asn1.h
+++ b/deps/openssl/openssl/crypto/asn1/asn1.h
@@ -235,7 +235,7 @@ typedef struct asn1_object_st
*/
#define ASN1_STRING_FLAG_MSTRING 0x040
/* This is the base type that holds just about everything :-) */
-typedef struct asn1_string_st
+struct asn1_string_st
{
int length;
int type;
@@ -245,7 +245,7 @@ typedef struct asn1_string_st
* input data has a non-zero 'unused bits' value, it will be
* handled correctly */
long flags;
- } ASN1_STRING;
+ };
/* ASN1_ENCODING structure: this is used to save the received
* encoding of an ASN1 type. This is useful to get round
@@ -293,7 +293,6 @@ DECLARE_STACK_OF(ASN1_STRING_TABLE)
* see asn1t.h
*/
typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
-typedef struct ASN1_ITEM_st ASN1_ITEM;
typedef struct ASN1_TLC_st ASN1_TLC;
/* This is just an opaque pointer */
typedef struct ASN1_VALUE_st ASN1_VALUE;
@@ -1194,6 +1193,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_F_ASN1_ITEM_I2D_FP 193
#define ASN1_F_ASN1_ITEM_PACK 198
#define ASN1_F_ASN1_ITEM_SIGN 195
+#define ASN1_F_ASN1_ITEM_SIGN_CTX 220
#define ASN1_F_ASN1_ITEM_UNPACK 199
#define ASN1_F_ASN1_ITEM_VERIFY 197
#define ASN1_F_ASN1_MBSTRING_NCOPY 122
@@ -1266,6 +1266,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_F_PKCS5_PBE2_SET_IV 167
#define ASN1_F_PKCS5_PBE_SET 202
#define ASN1_F_PKCS5_PBE_SET0_ALGOR 215
+#define ASN1_F_PKCS5_PBKDF2_SET 219
#define ASN1_F_SMIME_READ_ASN1 212
#define ASN1_F_SMIME_TEXT 213
#define ASN1_F_X509_CINF_NEW 168
@@ -1291,6 +1292,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
#define ASN1_R_BUFFER_TOO_SMALL 107
#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108
+#define ASN1_R_CONTEXT_NOT_INITIALISED 217
#define ASN1_R_DATA_IS_WRONG 109
#define ASN1_R_DECODE_ERROR 110
#define ASN1_R_DECODING_ERROR 111
diff --git a/deps/openssl/openssl/crypto/asn1/asn1_err.c b/deps/openssl/openssl/crypto/asn1/asn1_err.c
index 6e04d08f3..1a30bf119 100644
--- a/deps/openssl/openssl/crypto/asn1/asn1_err.c
+++ b/deps/openssl/openssl/crypto/asn1/asn1_err.c
@@ -1,6 +1,6 @@
/* crypto/asn1/asn1_err.c */
/* ====================================================================
- * Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -107,6 +107,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
@@ -179,6 +180,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"},
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"},
+{ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"},
{ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"},
{ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"},
{ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"},
@@ -207,6 +209,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH),"boolean is wrong length"},
{ERR_REASON(ASN1_R_BUFFER_TOO_SMALL) ,"buffer too small"},
{ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
+{ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED),"context not initialised"},
{ERR_REASON(ASN1_R_DATA_IS_WRONG) ,"data is wrong"},
{ERR_REASON(ASN1_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(ASN1_R_DECODING_ERROR) ,"decoding error"},
diff --git a/deps/openssl/openssl/crypto/asn1/asn1_locl.h b/deps/openssl/openssl/crypto/asn1/asn1_locl.h
index 5aa65e28f..9fcf0d953 100644
--- a/deps/openssl/openssl/crypto/asn1/asn1_locl.h
+++ b/deps/openssl/openssl/crypto/asn1/asn1_locl.h
@@ -102,6 +102,10 @@ struct evp_pkey_asn1_method_st
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx);
+ int (*sig_print)(BIO *out,
+ const X509_ALGOR *sigalg, const ASN1_STRING *sig,
+ int indent, ASN1_PCTX *pctx);
+
void (*pkey_free)(EVP_PKEY *pkey);
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
@@ -111,6 +115,13 @@ struct evp_pkey_asn1_method_st
int (*old_priv_decode)(EVP_PKEY *pkey,
const unsigned char **pder, int derlen);
int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+ /* Custom ASN1 signature verification */
+ int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *a, ASN1_BIT_STRING *sig,
+ EVP_PKEY *pkey);
+ int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *alg1, X509_ALGOR *alg2,
+ ASN1_BIT_STRING *sig);
} /* EVP_PKEY_ASN1_METHOD */;
diff --git a/deps/openssl/openssl/crypto/asn1/asn_mime.c b/deps/openssl/openssl/crypto/asn1/asn_mime.c
index c1d1b1229..54a704a96 100644
--- a/deps/openssl/openssl/crypto/asn1/asn_mime.c
+++ b/deps/openssl/openssl/crypto/asn1/asn_mime.c
@@ -377,8 +377,12 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
BIO *tmpbio;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
+ int rv = 1;
- if (!(flags & SMIME_DETACHED))
+ /* If data is not deteched or resigning then the output BIO is
+ * already set up to finalise when it is written through.
+ */
+ if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST))
{
SMIME_crlf_copy(data, out, flags);
return 1;
@@ -405,7 +409,7 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
/* Finalize structure */
if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
- return 0;
+ rv = 0;
/* Now remove any digests prepended to the BIO */
@@ -416,7 +420,7 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
sarg.ndef_bio = tmpbio;
}
- return 1;
+ return rv;
}
@@ -486,9 +490,9 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
strcmp(hdr->value, "application/pkcs7-signature")) {
- sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_SIG_INVALID_MIME_TYPE);
ERR_add_error_data(2, "type: ", hdr->value);
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
sk_BIO_pop_free(parts, BIO_vfree);
return NULL;
}
@@ -801,7 +805,7 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
if(name) {
if(!(tmpname = BUF_strdup(name))) return NULL;
for(p = tmpname ; *p; p++) {
- c = *p;
+ c = (unsigned char)*p;
if(isupper(c)) {
c = tolower(c);
*p = c;
@@ -811,7 +815,7 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
if(value) {
if(!(tmpval = BUF_strdup(value))) return NULL;
for(p = tmpval ; *p; p++) {
- c = *p;
+ c = (unsigned char)*p;
if(isupper(c)) {
c = tolower(c);
*p = c;
@@ -835,7 +839,7 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
tmpname = BUF_strdup(name);
if(!tmpname) return 0;
for(p = tmpname ; *p; p++) {
- c = *p;
+ c = (unsigned char)*p;
if(isupper(c)) {
c = tolower(c);
*p = c;
@@ -858,12 +862,17 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
static int mime_hdr_cmp(const MIME_HEADER * const *a,
const MIME_HEADER * const *b)
{
+ if (!(*a)->name || !(*b)->name)
+ return !!(*a)->name - !!(*b)->name;
+
return(strcmp((*a)->name, (*b)->name));
}
static int mime_param_cmp(const MIME_PARAM * const *a,
const MIME_PARAM * const *b)
{
+ if (!(*a)->param_name || !(*b)->param_name)
+ return !!(*a)->param_name - !!(*b)->param_name;
return(strcmp((*a)->param_name, (*b)->param_name));
}
diff --git a/deps/openssl/openssl/crypto/asn1/n_pkey.c b/deps/openssl/openssl/crypto/asn1/n_pkey.c
index e7d043906..e25173993 100644
--- a/deps/openssl/openssl/crypto/asn1/n_pkey.c
+++ b/deps/openssl/openssl/crypto/asn1/n_pkey.c
@@ -129,6 +129,7 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp,
unsigned char buf[256],*zz;
unsigned char key[EVP_MAX_KEY_LENGTH];
EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
if (a == NULL) return(0);
@@ -206,24 +207,28 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp,
i = strlen((char *)buf);
/* If the key is used for SGC the algorithm is modified a little. */
if(sgckey) {
- EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL);
+ if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
+ goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
}
- EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL);
+ if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
+ goto err;
OPENSSL_cleanse(buf,256);
/* Encrypt private key in place */
zz = enckey->enckey->digest->data;
- EVP_CIPHER_CTX_init(&ctx);
- EVP_EncryptInit_ex(&ctx,EVP_rc4(),NULL,key,NULL);
- EVP_EncryptUpdate(&ctx,zz,&i,zz,pkeylen);
- EVP_EncryptFinal_ex(&ctx,zz + i,&j);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ if (!EVP_EncryptInit_ex(&ctx,EVP_rc4(),NULL,key,NULL))
+ goto err;
+ if (!EVP_EncryptUpdate(&ctx,zz,&i,zz,pkeylen))
+ goto err;
+ if (!EVP_EncryptFinal_ex(&ctx,zz + i,&j))
+ goto err;
ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
NETSCAPE_PKEY_free(pkey);
return(ret);
@@ -288,6 +293,7 @@ static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
const unsigned char *zz;
unsigned char key[EVP_MAX_KEY_LENGTH];
EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
i=cb((char *)buf,256,"Enter Private Key password:",0);
if (i != 0)
@@ -298,19 +304,22 @@ static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
i = strlen((char *)buf);
if(sgckey){
- EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL);
+ if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
+ goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
}
- EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL);
+ if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
+ goto err;
OPENSSL_cleanse(buf,256);
- EVP_CIPHER_CTX_init(&ctx);
- EVP_DecryptInit_ex(&ctx,EVP_rc4(),NULL, key,NULL);
- EVP_DecryptUpdate(&ctx,os->data,&i,os->data,os->length);
- EVP_DecryptFinal_ex(&ctx,&(os->data[i]),&j);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ if (!EVP_DecryptInit_ex(&ctx,EVP_rc4(),NULL, key,NULL))
+ goto err;
+ if (!EVP_DecryptUpdate(&ctx,os->data,&i,os->data,os->length))
+ goto err;
+ if (!EVP_DecryptFinal_ex(&ctx,&(os->data[i]),&j))
+ goto err;
os->length=i+j;
zz=os->data;
@@ -328,6 +337,7 @@ static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
goto err;
}
err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
NETSCAPE_PKEY_free(pkey);
return(ret);
}
diff --git a/deps/openssl/openssl/crypto/asn1/p5_pbev2.c b/deps/openssl/openssl/crypto/asn1/p5_pbev2.c
index cb49b6651..4ea683036 100644
--- a/deps/openssl/openssl/crypto/asn1/p5_pbev2.c
+++ b/deps/openssl/openssl/crypto/asn1/p5_pbev2.c
@@ -91,12 +91,10 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
unsigned char *aiv, int prf_nid)
{
X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
- int alg_nid;
+ int alg_nid, keylen;
EVP_CIPHER_CTX ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
- PBKDF2PARAM *kdf = NULL;
PBE2PARAM *pbe2 = NULL;
- ASN1_OCTET_STRING *osalt = NULL;
ASN1_OBJECT *obj;
alg_nid = EVP_CIPHER_type(cipher);
@@ -127,7 +125,8 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
EVP_CIPHER_CTX_init(&ctx);
/* Dummy cipherinit to just setup the IV, and PRF */
- EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
+ if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
+ goto err;
if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
@@ -145,55 +144,21 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
}
EVP_CIPHER_CTX_cleanup(&ctx);
- if(!(kdf = PBKDF2PARAM_new())) goto merr;
- if(!(osalt = M_ASN1_OCTET_STRING_new())) goto merr;
-
- if (!saltlen) saltlen = PKCS5_SALT_LEN;
- if (!(osalt->data = OPENSSL_malloc (saltlen))) goto merr;
- osalt->length = saltlen;
- if (salt) memcpy (osalt->data, salt, saltlen);
- else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0) goto merr;
-
- if(iter <= 0) iter = PKCS5_DEFAULT_ITER;
- if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr;
-
- /* Now include salt in kdf structure */
- kdf->salt->value.octet_string = osalt;
- kdf->salt->type = V_ASN1_OCTET_STRING;
- osalt = NULL;
-
/* If its RC2 then we'd better setup the key length */
- if(alg_nid == NID_rc2_cbc) {
- if(!(kdf->keylength = M_ASN1_INTEGER_new())) goto merr;
- if(!ASN1_INTEGER_set (kdf->keylength,
- EVP_CIPHER_key_length(cipher))) goto merr;
- }
-
- /* prf can stay NULL if we are using hmacWithSHA1 */
- if (prf_nid != NID_hmacWithSHA1)
- {
- kdf->prf = X509_ALGOR_new();
- if (!kdf->prf)
- goto merr;
- X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
- V_ASN1_NULL, NULL);
- }
-
- /* Now setup the PBE2PARAM keyfunc structure */
+ if(alg_nid == NID_rc2_cbc)
+ keylen = EVP_CIPHER_key_length(cipher);
+ else
+ keylen = -1;
- pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
+ /* Setup keyfunc */
- /* Encode PBKDF2PARAM into parameter of pbe2 */
+ X509_ALGOR_free(pbe2->keyfunc);
- if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr;
+ pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
- if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
- &pbe2->keyfunc->parameter->value.sequence)) goto merr;
- pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;
-
- PBKDF2PARAM_free(kdf);
- kdf = NULL;
+ if (!pbe2->keyfunc)
+ goto merr;
/* Now set up top level AlgorithmIdentifier */
@@ -219,8 +184,6 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
err:
PBE2PARAM_free(pbe2);
/* Note 'scheme' is freed as part of pbe2 */
- M_ASN1_OCTET_STRING_free(osalt);
- PBKDF2PARAM_free(kdf);
X509_ALGOR_free(kalg);
X509_ALGOR_free(ret);
@@ -233,3 +196,85 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
{
return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
}
+
+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+ int prf_nid, int keylen)
+ {
+ X509_ALGOR *keyfunc = NULL;
+ PBKDF2PARAM *kdf = NULL;
+ ASN1_OCTET_STRING *osalt = NULL;
+
+ if(!(kdf = PBKDF2PARAM_new()))
+ goto merr;
+ if(!(osalt = M_ASN1_OCTET_STRING_new()))
+ goto merr;
+
+ kdf->salt->value.octet_string = osalt;
+ kdf->salt->type = V_ASN1_OCTET_STRING;
+
+ if (!saltlen)
+ saltlen = PKCS5_SALT_LEN;
+ if (!(osalt->data = OPENSSL_malloc (saltlen)))
+ goto merr;
+
+ osalt->length = saltlen;
+
+ if (salt)
+ memcpy (osalt->data, salt, saltlen);
+ else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0)
+ goto merr;
+
+ if(iter <= 0)
+ iter = PKCS5_DEFAULT_ITER;
+
+ if(!ASN1_INTEGER_set(kdf->iter, iter))
+ goto merr;
+
+ /* If have a key len set it up */
+
+ if(keylen > 0)
+ {
+ if(!(kdf->keylength = M_ASN1_INTEGER_new()))
+ goto merr;
+ if(!ASN1_INTEGER_set (kdf->keylength, keylen))
+ goto merr;
+ }
+
+ /* prf can stay NULL if we are using hmacWithSHA1 */
+ if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1)
+ {
+ kdf->prf = X509_ALGOR_new();
+ if (!kdf->prf)
+ goto merr;
+ X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
+ V_ASN1_NULL, NULL);
+ }
+
+ /* Finally setup the keyfunc structure */
+
+ keyfunc = X509_ALGOR_new();
+ if (!keyfunc)
+ goto merr;
+
+ keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
+
+ /* Encode PBKDF2PARAM into parameter of pbe2 */
+
+ if(!(keyfunc->parameter = ASN1_TYPE_new()))
+ goto merr;
+
+ if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
+ &keyfunc->parameter->value.sequence))
+ goto merr;
+ keyfunc->parameter->type = V_ASN1_SEQUENCE;
+
+ PBKDF2PARAM_free(kdf);
+ return keyfunc;
+
+ merr:
+ ASN1err(ASN1_F_PKCS5_PBKDF2_SET,ERR_R_MALLOC_FAILURE);
+ PBKDF2PARAM_free(kdf);
+ X509_ALGOR_free(keyfunc);
+ return NULL;
+ }
+
diff --git a/deps/openssl/openssl/crypto/asn1/t_crl.c b/deps/openssl/openssl/crypto/asn1/t_crl.c
index ee5a687ce..c61169208 100644
--- a/deps/openssl/openssl/crypto/asn1/t_crl.c
+++ b/deps/openssl/openssl/crypto/asn1/t_crl.c
@@ -94,8 +94,7 @@ int X509_CRL_print(BIO *out, X509_CRL *x)
l = X509_CRL_get_version(x);
BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l);
i = OBJ_obj2nid(x->sig_alg->algorithm);
- BIO_printf(out, "%8sSignature Algorithm: %s\n", "",
- (i == NID_undef) ? "NONE" : OBJ_nid2ln(i));
+ X509_signature_print(out, x->sig_alg, NULL);
p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0);
BIO_printf(out,"%8sIssuer: %s\n","",p);
OPENSSL_free(p);
diff --git a/deps/openssl/openssl/crypto/asn1/t_x509.c b/deps/openssl/openssl/crypto/asn1/t_x509.c
index e061f2ffa..edbb39a02 100644
--- a/deps/openssl/openssl/crypto/asn1/t_x509.c
+++ b/deps/openssl/openssl/crypto/asn1/t_x509.c
@@ -72,6 +72,7 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+#include "asn1_locl.h"
#ifndef OPENSSL_NO_FP_API
int X509_print_fp(FILE *fp, X509 *x)
@@ -137,10 +138,10 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
if (BIO_write(bp," Serial Number:",22) <= 0) goto err;
bs=X509_get_serialNumber(x);
- if (bs->length <= 4)
+ if (bs->length <= (int)sizeof(long))
{
l=ASN1_INTEGER_get(bs);
- if (l < 0)
+ if (bs->type == V_ASN1_NEG_INTEGER)
{
l= -l;
neg="-";
@@ -167,12 +168,16 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
if(!(cflag & X509_FLAG_NO_SIGNAME))
{
+ if(X509_signature_print(bp, x->sig_alg, NULL) <= 0)
+ goto err;
+#if 0
if (BIO_printf(bp,"%8sSignature Algorithm: ","") <= 0)
goto err;
if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
goto err;
if (BIO_puts(bp, "\n") <= 0)
goto err;
+#endif
}
if(!(cflag & X509_FLAG_NO_ISSUER))
@@ -255,7 +260,8 @@ int X509_ocspid_print (BIO *bp, X509 *x)
goto err;
i2d_X509_NAME(x->cert_info->subject, &dertmp);
- EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL);
+ if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
+ goto err;
for (i=0; i < SHA_DIGEST_LENGTH; i++)
{
if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0) goto err;
@@ -268,8 +274,10 @@ int X509_ocspid_print (BIO *bp, X509 *x)
if (BIO_printf(bp,"\n Public key OCSP hash: ") <= 0)
goto err;
- EVP_Digest(x->cert_info->key->public_key->data,
- x->cert_info->key->public_key->length, SHA1md, NULL, EVP_sha1(), NULL);
+ if (!EVP_Digest(x->cert_info->key->public_key->data,
+ x->cert_info->key->public_key->length,
+ SHA1md, NULL, EVP_sha1(), NULL))
+ goto err;
for (i=0; i < SHA_DIGEST_LENGTH; i++)
{
if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0)
@@ -283,23 +291,50 @@ err:
return(0);
}
-int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
{
- unsigned char *s;
+ const unsigned char *s;
int i, n;
- if (BIO_puts(bp," Signature Algorithm: ") <= 0) return 0;
- if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
n=sig->length;
s=sig->data;
for (i=0; i<n; i++)
{
if ((i%18) == 0)
- if (BIO_write(bp,"\n ",9) <= 0) return 0;
+ {
+ if (BIO_write(bp,"\n",1) <= 0) return 0;
+ if (BIO_indent(bp, indent, indent) <= 0) return 0;
+ }
if (BIO_printf(bp,"%02x%s",s[i],
((i+1) == n)?"":":") <= 0) return 0;
}
if (BIO_write(bp,"\n",1) != 1) return 0;
+
+ return 1;
+}
+
+int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
+{
+ int sig_nid;
+ if (BIO_puts(bp," Signature Algorithm: ") <= 0) return 0;
+ if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
+
+ sig_nid = OBJ_obj2nid(sigalg->algorithm);
+ if (sig_nid != NID_undef)
+ {
+ int pkey_nid, dig_nid;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid))
+ {
+ ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
+ if (ameth && ameth->sig_print)
+ return ameth->sig_print(bp, sigalg, sig, 9, 0);
+ }
+ }
+ if (sig)
+ return X509_signature_dump(bp, sig, 9);
+ else if (BIO_puts(bp, "\n") <= 0)
+ return 0;
return 1;
}
diff --git a/deps/openssl/openssl/crypto/asn1/tasn_prn.c b/deps/openssl/openssl/crypto/asn1/tasn_prn.c
index 453698012..542a091a6 100644
--- a/deps/openssl/openssl/crypto/asn1/tasn_prn.c
+++ b/deps/openssl/openssl/crypto/asn1/tasn_prn.c
@@ -446,11 +446,11 @@ static int asn1_print_fsname(BIO *out, int indent,
return 1;
}
-static int asn1_print_boolean_ctx(BIO *out, const int bool,
+static int asn1_print_boolean_ctx(BIO *out, int boolval,
const ASN1_PCTX *pctx)
{
const char *str;
- switch (bool)
+ switch (boolval)
{
case -1:
str = "BOOL ABSENT";
@@ -574,10 +574,10 @@ static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
{
case V_ASN1_BOOLEAN:
{
- int bool = *(int *)fld;
- if (bool == -1)
- bool = it->size;
- ret = asn1_print_boolean_ctx(out, bool, pctx);
+ int boolval = *(int *)fld;
+ if (boolval == -1)
+ boolval = it->size;
+ ret = asn1_print_boolean_ctx(out, boolval, pctx);
}
break;
diff --git a/deps/openssl/openssl/crypto/asn1/x_algor.c b/deps/openssl/openssl/crypto/asn1/x_algor.c
index 99e53429b..274e456c7 100644
--- a/deps/openssl/openssl/crypto/asn1/x_algor.c
+++ b/deps/openssl/openssl/crypto/asn1/x_algor.c
@@ -128,3 +128,17 @@ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
}
}
+/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
+
+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
+ {
+ int param_type;
+
+ if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
+ param_type = V_ASN1_UNDEF;
+ else
+ param_type = V_ASN1_NULL;
+
+ X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+
+ }
diff --git a/deps/openssl/openssl/crypto/asn1/x_name.c b/deps/openssl/openssl/crypto/asn1/x_name.c
index 49be08b4d..d7c231869 100644
--- a/deps/openssl/openssl/crypto/asn1/x_name.c
+++ b/deps/openssl/openssl/crypto/asn1/x_name.c
@@ -399,8 +399,7 @@ static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
/* If type not in bitmask just copy string across */
if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
{
- out->type = in->type;
- if (!ASN1_STRING_set(out, in->data, in->length))
+ if (!ASN1_STRING_copy(out, in))
return 0;
return 1;
}
diff --git a/deps/openssl/openssl/crypto/asn1/x_pubkey.c b/deps/openssl/openssl/crypto/asn1/x_pubkey.c
index d42b6a2c5..b649e1fcf 100644
--- a/deps/openssl/openssl/crypto/asn1/x_pubkey.c
+++ b/deps/openssl/openssl/crypto/asn1/x_pubkey.c
@@ -171,7 +171,19 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
goto error;
}
- key->pkey = ret;
+ /* Check to see if another thread set key->pkey first */
+ CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
+ if (key->pkey)
+ {
+ CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+ EVP_PKEY_free(ret);
+ ret = key->pkey;
+ }
+ else
+ {
+ key->pkey = ret;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+ }
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
return ret;
diff --git a/deps/openssl/openssl/crypto/bf/Makefile b/deps/openssl/openssl/crypto/bf/Makefile
index dd2c2c708..d01bfaa31 100644
--- a/deps/openssl/openssl/crypto/bf/Makefile
+++ b/deps/openssl/openssl/crypto/bf/Makefile
@@ -94,5 +94,8 @@ bf_enc.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
bf_enc.o: ../../include/openssl/opensslconf.h bf_enc.c bf_locl.h
bf_ofb64.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
bf_ofb64.o: ../../include/openssl/opensslconf.h bf_locl.h bf_ofb64.c
-bf_skey.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
-bf_skey.o: ../../include/openssl/opensslconf.h bf_locl.h bf_pi.h bf_skey.c
+bf_skey.o: ../../include/openssl/blowfish.h ../../include/openssl/crypto.h
+bf_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+bf_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bf_skey.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bf_skey.o: ../../include/openssl/symhacks.h bf_locl.h bf_pi.h bf_skey.c
diff --git a/deps/openssl/openssl/crypto/bf/bf_skey.c b/deps/openssl/openssl/crypto/bf/bf_skey.c
index 3673cdee6..3b0bca41a 100644
--- a/deps/openssl/openssl/crypto/bf/bf_skey.c
+++ b/deps/openssl/openssl/crypto/bf/bf_skey.c
@@ -58,11 +58,19 @@
#include <stdio.h>
#include <string.h>
+#include <openssl/crypto.h>
#include <openssl/blowfish.h>
#include "bf_locl.h"
#include "bf_pi.h"
void BF_set_key(BF_KEY *key, int len, const unsigned char *data)
+#ifdef OPENSSL_FIPS
+ {
+ fips_cipher_abort(BLOWFISH);
+ private_BF_set_key(key, len, data);
+ }
+void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data)
+#endif
{
int i;
BF_LONG *p,ri,in[2];
diff --git a/deps/openssl/openssl/crypto/bf/blowfish.h b/deps/openssl/openssl/crypto/bf/blowfish.h
index b97e76f9a..4b6c8920a 100644
--- a/deps/openssl/openssl/crypto/bf/blowfish.h
+++ b/deps/openssl/openssl/crypto/bf/blowfish.h
@@ -104,7 +104,9 @@ typedef struct bf_key_st
BF_LONG S[4*256];
} BF_KEY;
-
+#ifdef OPENSSL_FIPS
+void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data);
+#endif
void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
void BF_encrypt(BF_LONG *data,const BF_KEY *key);
diff --git a/deps/openssl/openssl/crypto/bio/bio.h b/deps/openssl/openssl/crypto/bio/bio.h
index ab47abcf1..05699ab21 100644
--- a/deps/openssl/openssl/crypto/bio/bio.h
+++ b/deps/openssl/openssl/crypto/bio/bio.h
@@ -68,6 +68,14 @@
#include <openssl/crypto.h>
+#ifndef OPENSSL_NO_SCTP
+# ifndef OPENSSL_SYS_VMS
+# include <stdint.h>
+# else
+# include <inttypes.h>
+# endif
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -95,6 +103,9 @@ extern "C" {
#define BIO_TYPE_BIO (19|0x0400) /* (half a) BIO pair */
#define BIO_TYPE_LINEBUFFER (20|0x0200) /* filter */
#define BIO_TYPE_DGRAM (21|0x0400|0x0100)
+#ifndef OPENSSL_NO_SCTP
+#define BIO_TYPE_DGRAM_SCTP (24|0x0400|0x0100)
+#endif
#define BIO_TYPE_ASN1 (22|0x0200) /* filter */
#define BIO_TYPE_COMP (23|0x0200) /* filter */
@@ -146,6 +157,7 @@ extern "C" {
/* #endif */
#define BIO_CTRL_DGRAM_QUERY_MTU 40 /* as kernel for current MTU */
+#define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47
#define BIO_CTRL_DGRAM_GET_MTU 41 /* get cached value for MTU */
#define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for
* MTU. want to use this
@@ -161,7 +173,22 @@ extern "C" {
#define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */
#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to
- * adjust socket timeouts */
+ * adjust socket timeouts */
+
+#ifndef OPENSSL_NO_SCTP
+/* SCTP stuff */
+#define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50
+#define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51
+#define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52
+#define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53
+#define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60
+#define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61
+#define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62
+#define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63
+#define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64
+#define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65
+#define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70
+#endif
/* modifiers */
#define BIO_FP_READ 0x02
@@ -331,6 +358,34 @@ typedef struct bio_f_buffer_ctx_struct
/* Prefix and suffix callback in ASN1 BIO */
typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+#ifndef OPENSSL_NO_SCTP
+/* SCTP parameter structs */
+struct bio_dgram_sctp_sndinfo
+ {
+ uint16_t snd_sid;
+ uint16_t snd_flags;
+ uint32_t snd_ppid;
+ uint32_t snd_context;
+ };
+
+struct bio_dgram_sctp_rcvinfo
+ {
+ uint16_t rcv_sid;
+ uint16_t rcv_ssn;
+ uint16_t rcv_flags;
+ uint32_t rcv_ppid;
+ uint32_t rcv_tsn;
+ uint32_t rcv_cumtsn;
+ uint32_t rcv_context;
+ };
+
+struct bio_dgram_sctp_prinfo
+ {
+ uint16_t pr_policy;
+ uint32_t pr_value;
+ };
+#endif
+
/* connect BIO stuff */
#define BIO_CONN_S_BEFORE 1
#define BIO_CONN_S_GET_IP 2
@@ -628,6 +683,9 @@ BIO_METHOD *BIO_f_linebuffer(void);
BIO_METHOD *BIO_f_nbio_test(void);
#ifndef OPENSSL_NO_DGRAM
BIO_METHOD *BIO_s_datagram(void);
+#ifndef OPENSSL_NO_SCTP
+BIO_METHOD *BIO_s_datagram_sctp(void);
+#endif
#endif
/* BIO_METHOD *BIO_f_ber(void); */
@@ -670,6 +728,15 @@ int BIO_set_tcp_ndelay(int sock,int turn_on);
BIO *BIO_new_socket(int sock, int close_flag);
BIO *BIO_new_dgram(int fd, int close_flag);
+#ifndef OPENSSL_NO_SCTP
+BIO *BIO_new_dgram_sctp(int fd, int close_flag);
+int BIO_dgram_is_sctp(BIO *bio);
+int BIO_dgram_sctp_notification_cb(BIO *b,
+ void (*handle_notifications)(BIO *bio, void *context, void *buf),
+ void *context);
+int BIO_dgram_sctp_wait_for_dry(BIO *b);
+int BIO_dgram_sctp_msg_waiting(BIO *b);
+#endif
BIO *BIO_new_fd(int fd, int close_flag);
BIO *BIO_new_connect(char *host_port);
BIO *BIO_new_accept(char *host_port);
@@ -734,6 +801,7 @@ void ERR_load_BIO_strings(void);
#define BIO_F_BUFFER_CTRL 114
#define BIO_F_CONN_CTRL 127
#define BIO_F_CONN_STATE 115
+#define BIO_F_DGRAM_SCTP_READ 132
#define BIO_F_FILE_CTRL 116
#define BIO_F_FILE_READ 130
#define BIO_F_LINEBUFFER_CTRL 129
diff --git a/deps/openssl/openssl/crypto/bio/bio_err.c b/deps/openssl/openssl/crypto/bio/bio_err.c
index a224edd5a..0dbfbd80d 100644
--- a/deps/openssl/openssl/crypto/bio/bio_err.c
+++ b/deps/openssl/openssl/crypto/bio/bio_err.c
@@ -1,6 +1,6 @@
/* crypto/bio/bio_err.c */
/* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -95,6 +95,7 @@ static ERR_STRING_DATA BIO_str_functs[]=
{ERR_FUNC(BIO_F_BUFFER_CTRL), "BUFFER_CTRL"},
{ERR_FUNC(BIO_F_CONN_CTRL), "CONN_CTRL"},
{ERR_FUNC(BIO_F_CONN_STATE), "CONN_STATE"},
+{ERR_FUNC(BIO_F_DGRAM_SCTP_READ), "DGRAM_SCTP_READ"},
{ERR_FUNC(BIO_F_FILE_CTRL), "FILE_CTRL"},
{ERR_FUNC(BIO_F_FILE_READ), "FILE_READ"},
{ERR_FUNC(BIO_F_LINEBUFFER_CTRL), "LINEBUFFER_CTRL"},
diff --git a/deps/openssl/openssl/crypto/bio/bio_lib.c b/deps/openssl/openssl/crypto/bio/bio_lib.c
index e12bc3a2c..9c9646afa 100644
--- a/deps/openssl/openssl/crypto/bio/bio_lib.c
+++ b/deps/openssl/openssl/crypto/bio/bio_lib.c
@@ -521,40 +521,40 @@ void BIO_free_all(BIO *bio)
BIO *BIO_dup_chain(BIO *in)
{
- BIO *ret=NULL,*eoc=NULL,*bio,*new;
+ BIO *ret=NULL,*eoc=NULL,*bio,*new_bio;
for (bio=in; bio != NULL; bio=bio->next_bio)
{
- if ((new=BIO_new(bio->method)) == NULL) goto err;
- new->callback=bio->callback;
- new->cb_arg=bio->cb_arg;
- new->init=bio->init;
- new->shutdown=bio->shutdown;
- new->flags=bio->flags;
+ if ((new_bio=BIO_new(bio->method)) == NULL) goto err;
+ new_bio->callback=bio->callback;
+ new_bio->cb_arg=bio->cb_arg;
+ new_bio->init=bio->init;
+ new_bio->shutdown=bio->shutdown;
+ new_bio->flags=bio->flags;
/* This will let SSL_s_sock() work with stdin/stdout */
- new->num=bio->num;
+ new_bio->num=bio->num;
- if (!BIO_dup_state(bio,(char *)new))
+ if (!BIO_dup_state(bio,(char *)new_bio))
{
- BIO_free(new);
+ BIO_free(new_bio);
goto err;
}
/* copy app data */
- if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new->ex_data,
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
&bio->ex_data))
goto err;
if (ret == NULL)
{
- eoc=new;
+ eoc=new_bio;
ret=eoc;
}
else
{
- BIO_push(eoc,new);
- eoc=new;
+ BIO_push(eoc,new_bio);
+ eoc=new_bio;
}
}
return(ret);
diff --git a/deps/openssl/openssl/crypto/bio/bss_bio.c b/deps/openssl/openssl/crypto/bio/bss_bio.c
index 76bd48e76..52ef0ebcb 100644
--- a/deps/openssl/openssl/crypto/bio/bss_bio.c
+++ b/deps/openssl/openssl/crypto/bio/bss_bio.c
@@ -277,10 +277,10 @@ static int bio_read(BIO *bio, char *buf, int size_)
*/
/* WARNING: The non-copying interface is largely untested as of yet
* and may contain bugs. */
-static ssize_t bio_nread0(BIO *bio, char **buf)
+static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
{
struct bio_bio_st *b, *peer_b;
- ssize_t num;
+ ossl_ssize_t num;
BIO_clear_retry_flags(bio);
@@ -315,15 +315,15 @@ static ssize_t bio_nread0(BIO *bio, char **buf)
return num;
}
-static ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
+static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
{
struct bio_bio_st *b, *peer_b;
- ssize_t num, available;
+ ossl_ssize_t num, available;
if (num_ > SSIZE_MAX)
num = SSIZE_MAX;
else
- num = (ssize_t)num_;
+ num = (ossl_ssize_t)num_;
available = bio_nread0(bio, buf);
if (num > available)
@@ -428,7 +428,7 @@ static int bio_write(BIO *bio, const char *buf, int num_)
* (example usage: bio_nwrite0(), write to buffer, bio_nwrite()
* or just bio_nwrite(), write to buffer)
*/
-static ssize_t bio_nwrite0(BIO *bio, char **buf)
+static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
{
struct bio_bio_st *b;
size_t num;
@@ -476,15 +476,15 @@ static ssize_t bio_nwrite0(BIO *bio, char **buf)
return num;
}
-static ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
+static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
{
struct bio_bio_st *b;
- ssize_t num, space;
+ ossl_ssize_t num, space;
if (num_ > SSIZE_MAX)
num = SSIZE_MAX;
else
- num = (ssize_t)num_;
+ num = (ossl_ssize_t)num_;
space = bio_nwrite0(bio, buf);
if (num > space)
diff --git a/deps/openssl/openssl/crypto/bio/bss_dgram.c b/deps/openssl/openssl/crypto/bio/bss_dgram.c
index 71ebe987b..899090997 100644
--- a/deps/openssl/openssl/crypto/bio/bss_dgram.c
+++ b/deps/openssl/openssl/crypto/bio/bss_dgram.c
@@ -70,10 +70,27 @@
#include <sys/timeb.h>
#endif
-#ifdef OPENSSL_SYS_LINUX
+#ifndef OPENSSL_NO_SCTP
+#include <netinet/sctp.h>
+#include <fcntl.h>
+#define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00
+#define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
+#endif
+
+#if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
#define IP_MTU 14 /* linux is lame */
#endif
+#if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
+/* Standard definition causes type-punning problems. */
+#undef IN6_IS_ADDR_V4MAPPED
+#define s6_addr32 __u6_addr.__u6_addr32
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == htonl(0x0000ffff)))
+#endif
+
#ifdef WATT32
#define sock_write SockWrite /* Watt-32 uses same names */
#define sock_read SockRead
@@ -88,6 +105,18 @@ static int dgram_new(BIO *h);
static int dgram_free(BIO *data);
static int dgram_clear(BIO *bio);
+#ifndef OPENSSL_NO_SCTP
+static int dgram_sctp_write(BIO *h, const char *buf, int num);
+static int dgram_sctp_read(BIO *h, char *buf, int size);
+static int dgram_sctp_puts(BIO *h, const char *str);
+static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int dgram_sctp_new(BIO *h);
+static int dgram_sctp_free(BIO *data);
+#ifdef SCTP_AUTHENTICATION_EVENT
+static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp);
+#endif
+#endif
+
static int BIO_dgram_should_retry(int s);
static void get_current_time(struct timeval *t);
@@ -106,6 +135,22 @@ static BIO_METHOD methods_dgramp=
NULL,
};
+#ifndef OPENSSL_NO_SCTP
+static BIO_METHOD methods_dgramp_sctp=
+ {
+ BIO_TYPE_DGRAM_SCTP,
+ "datagram sctp socket",
+ dgram_sctp_write,
+ dgram_sctp_read,
+ dgram_sctp_puts,
+ NULL, /* dgram_gets, */
+ dgram_sctp_ctrl,
+ dgram_sctp_new,
+ dgram_sctp_free,
+ NULL,
+ };
+#endif
+
typedef struct bio_dgram_data_st
{
union {
@@ -122,6 +167,40 @@ typedef struct bio_dgram_data_st
struct timeval socket_timeout;
} bio_dgram_data;
+#ifndef OPENSSL_NO_SCTP
+typedef struct bio_dgram_sctp_save_message_st
+ {
+ BIO *bio;
+ char *data;
+ int length;
+ } bio_dgram_sctp_save_message;
+
+typedef struct bio_dgram_sctp_data_st
+ {
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+ struct sockaddr_in6 sa_in6;
+#endif
+ } peer;
+ unsigned int connected;
+ unsigned int _errno;
+ unsigned int mtu;
+ struct bio_dgram_sctp_sndinfo sndinfo;
+ struct bio_dgram_sctp_rcvinfo rcvinfo;
+ struct bio_dgram_sctp_prinfo prinfo;
+ void (*handle_notifications)(BIO *bio, void *context, void *buf);
+ void* notification_context;
+ int in_handshake;
+ int ccs_rcvd;
+ int ccs_sent;
+ int save_shutdown;
+ int peer_auth_tested;
+ bio_dgram_sctp_save_message saved_message;
+ } bio_dgram_sctp_data;
+#endif
+
BIO_METHOD *BIO_s_datagram(void)
{
return(&methods_dgramp);
@@ -186,7 +265,7 @@ static void dgram_adjust_rcv_timeout(BIO *b)
{
#if defined(SO_RCVTIMEO)
bio_dgram_data *data = (bio_dgram_data *)b->ptr;
- int sz = sizeof(int);
+ union { size_t s; int i; } sz = {0};
/* Is a timer active? */
if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
@@ -196,8 +275,10 @@ static void dgram_adjust_rcv_timeout(BIO *b)
/* Read current socket timeout */
#ifdef OPENSSL_SYS_WINDOWS
int timeout;
+
+ sz.i = sizeof(timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void*)&timeout, &sz) < 0)
+ (void*)&timeout, &sz.i) < 0)
{ perror("getsockopt"); }
else
{
@@ -205,9 +286,12 @@ static void dgram_adjust_rcv_timeout(BIO *b)
data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
}
#else
+ sz.i = sizeof(data->socket_timeout);
if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
&(data->socket_timeout), (void *)&sz) < 0)
{ perror("getsockopt"); }
+ else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
+ OPENSSL_assert(sz.s<=sizeof(data->socket_timeout));
#endif
/* Get current time */
@@ -376,11 +460,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
int *ip;
struct sockaddr *to = NULL;
bio_dgram_data *data = NULL;
-#if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
- long sockopt_val = 0;
- unsigned int sockopt_len = 0;
-#endif
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
+ int sockopt_val = 0;
+ socklen_t sockopt_len; /* assume that system supporting IP_MTU is
+ * modern enough to define socklen_t */
socklen_t addr_len;
union {
struct sockaddr sa;
@@ -462,7 +545,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
/* (Linux)kernel sets DF bit on outgoing IP packets */
case BIO_CTRL_DGRAM_MTU_DISCOVER:
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
addr_len = (socklen_t)sizeof(addr);
memset((void *)&addr, 0, sizeof(addr));
if (getsockname(b->num, &addr.sa, &addr_len) < 0)
@@ -470,7 +553,6 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 0;
break;
}
- sockopt_len = sizeof(sockopt_val);
switch (addr.sa.sa_family)
{
case AF_INET:
@@ -479,7 +561,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
&sockopt_val, sizeof(sockopt_val))) < 0)
perror("setsockopt");
break;
-#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER)
+#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
case AF_INET6:
sockopt_val = IPV6_PMTUDISC_DO;
if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
@@ -496,7 +578,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
#endif
case BIO_CTRL_DGRAM_QUERY_MTU:
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
addr_len = (socklen_t)sizeof(addr);
memset((void *)&addr, 0, sizeof(addr));
if (getsockname(b->num, &addr.sa, &addr_len) < 0)
@@ -547,6 +629,27 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 0;
#endif
break;
+ case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
+ switch (data->peer.sa.sa_family)
+ {
+ case AF_INET:
+ ret = 576 - 20 - 8;
+ break;
+#if OPENSSL_USE_IPV6
+ case AF_INET6:
+#ifdef IN6_IS_ADDR_V4MAPPED
+ if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
+ ret = 576 - 20 - 8;
+ else
+#endif
+ ret = 1280 - 40 - 8;
+ break;
+#endif
+ default:
+ ret = 576 - 20 - 8;
+ break;
+ }
+ break;
case BIO_CTRL_DGRAM_GET_MTU:
return data->mtu;
break;
@@ -637,12 +740,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
#endif
break;
case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
-#ifdef OPENSSL_SYS_WINDOWS
{
- int timeout, sz = sizeof(timeout);
+ union { size_t s; int i; } sz = {0};
+#ifdef OPENSSL_SYS_WINDOWS
+ int timeout;
struct timeval *tv = (struct timeval *)ptr;
+
+ sz.i = sizeof(timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void*)&timeout, &sz) < 0)
+ (void*)&timeout, &sz.i) < 0)
{ perror("getsockopt"); ret = -1; }
else
{
@@ -650,12 +756,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
tv->tv_usec = (timeout % 1000) * 1000;
ret = sizeof(*tv);
}
- }
#else
+ sz.i = sizeof(struct timeval);
if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- ptr, (void *)&ret) < 0)
+ ptr, (void *)&sz) < 0)
{ perror("getsockopt"); ret = -1; }
+ else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
+ {
+ OPENSSL_assert(sz.s<=sizeof(struct timeval));
+ ret = (int)sz.s;
+ }
+ else
+ ret = sz.i;
#endif
+ }
break;
#endif
#if defined(SO_SNDTIMEO)
@@ -675,12 +789,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
#endif
break;
case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
-#ifdef OPENSSL_SYS_WINDOWS
{
- int timeout, sz = sizeof(timeout);
+ union { size_t s; int i; } sz = {0};
+#ifdef OPENSSL_SYS_WINDOWS
+ int timeout;
struct timeval *tv = (struct timeval *)ptr;
+
+ sz.i = sizeof(timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
- (void*)&timeout, &sz) < 0)
+ (void*)&timeout, &sz.i) < 0)
{ perror("getsockopt"); ret = -1; }
else
{
@@ -688,12 +805,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
tv->tv_usec = (timeout % 1000) * 1000;
ret = sizeof(*tv);
}
- }
#else
+ sz.i = sizeof(struct timeval);
if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
- ptr, (void *)&ret) < 0)
+ ptr, (void *)&sz) < 0)
{ perror("getsockopt"); ret = -1; }
+ else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
+ {
+ OPENSSL_assert(sz.s<=sizeof(struct timeval));
+ ret = (int)sz.s;
+ }
+ else
+ ret = sz.i;
#endif
+ }
break;
#endif
case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
@@ -738,6 +863,910 @@ static int dgram_puts(BIO *bp, const char *str)
return(ret);
}
+#ifndef OPENSSL_NO_SCTP
+BIO_METHOD *BIO_s_datagram_sctp(void)
+ {
+ return(&methods_dgramp_sctp);
+ }
+
+BIO *BIO_new_dgram_sctp(int fd, int close_flag)
+ {
+ BIO *bio;
+ int ret, optval = 20000;
+ int auth_data = 0, auth_forward = 0;
+ unsigned char *p;
+ struct sctp_authchunk auth;
+ struct sctp_authchunks *authchunks;
+ socklen_t sockopt_len;
+#ifdef SCTP_AUTHENTICATION_EVENT
+#ifdef SCTP_EVENT
+ struct sctp_event event;
+#else
+ struct sctp_event_subscribe event;
+#endif
+#endif
+
+ bio=BIO_new(BIO_s_datagram_sctp());
+ if (bio == NULL) return(NULL);
+ BIO_set_fd(bio,fd,close_flag);
+
+ /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
+ auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
+ ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk));
+ OPENSSL_assert(ret >= 0);
+ auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
+ ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk));
+ OPENSSL_assert(ret >= 0);
+
+ /* Test if activation was successful. When using accept(),
+ * SCTP-AUTH has to be activated for the listening socket
+ * already, otherwise the connected socket won't use it. */
+ sockopt_len = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
+ authchunks = OPENSSL_malloc(sockopt_len);
+ memset(authchunks, 0, sizeof(sockopt_len));
+ ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, &sockopt_len);
+ OPENSSL_assert(ret >= 0);
+
+ for (p = (unsigned char*) authchunks + sizeof(sctp_assoc_t);
+ p < (unsigned char*) authchunks + sockopt_len;
+ p += sizeof(uint8_t))
+ {
+ if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
+ if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
+ }
+
+ OPENSSL_free(authchunks);
+
+ OPENSSL_assert(auth_data);
+ OPENSSL_assert(auth_forward);
+
+#ifdef SCTP_AUTHENTICATION_EVENT
+#ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(struct sctp_event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_AUTHENTICATION_EVENT;
+ event.se_on = 1;
+ ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
+ OPENSSL_assert(ret >= 0);
+#else
+ sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
+ ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
+ OPENSSL_assert(ret >= 0);
+
+ event.sctp_authentication_event = 1;
+
+ ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
+ OPENSSL_assert(ret >= 0);
+#endif
+#endif
+
+ /* Disable partial delivery by setting the min size
+ * larger than the max record size of 2^14 + 2048 + 13
+ */
+ ret = setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, sizeof(optval));
+ OPENSSL_assert(ret >= 0);
+
+ return(bio);
+ }
+
+int BIO_dgram_is_sctp(BIO *bio)
+ {
+ return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
+ }
+
+static int dgram_sctp_new(BIO *bi)
+ {
+ bio_dgram_sctp_data *data = NULL;
+
+ bi->init=0;
+ bi->num=0;
+ data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data));
+ if (data == NULL)
+ return 0;
+ memset(data, 0x00, sizeof(bio_dgram_sctp_data));
+#ifdef SCTP_PR_SCTP_NONE
+ data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
+#endif
+ bi->ptr = data;
+
+ bi->flags=0;
+ return(1);
+ }
+
+static int dgram_sctp_free(BIO *a)
+ {
+ bio_dgram_sctp_data *data;
+
+ if (a == NULL) return(0);
+ if ( ! dgram_clear(a))
+ return 0;
+
+ data = (bio_dgram_sctp_data *)a->ptr;
+ if(data != NULL) OPENSSL_free(data);
+
+ return(1);
+ }
+
+#ifdef SCTP_AUTHENTICATION_EVENT
+void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
+ {
+ int ret;
+ struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event;
+
+ if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY)
+ {
+ struct sctp_authkeyid authkeyid;
+
+ /* delete key */
+ authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ }
+ }
+#endif
+
+static int dgram_sctp_read(BIO *b, char *out, int outl)
+ {
+ int ret = 0, n = 0, i, optval;
+ socklen_t optlen;
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
+ union sctp_notification *snp;
+ struct msghdr msg;
+ struct iovec iov;
+ struct cmsghdr *cmsg;
+ char cmsgbuf[512];
+
+ if (out != NULL)
+ {
+ clear_socket_error();
+
+ do
+ {
+ memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo));
+ iov.iov_base = out;
+ iov.iov_len = outl;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = 512;
+ msg.msg_flags = 0;
+ n = recvmsg(b->num, &msg, 0);
+
+ if (msg.msg_controllen > 0)
+ {
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
+ {
+ if (cmsg->cmsg_level != IPPROTO_SCTP)
+ continue;
+#ifdef SCTP_RCVINFO
+ if (cmsg->cmsg_type == SCTP_RCVINFO)
+ {
+ struct sctp_rcvinfo *rcvinfo;
+
+ rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
+ data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
+ data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
+ data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
+ data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
+ data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
+ data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
+ data->rcvinfo.rcv_context = rcvinfo->rcv_context;
+ }
+#endif
+#ifdef SCTP_SNDRCV
+ if (cmsg->cmsg_type == SCTP_SNDRCV)
+ {
+ struct sctp_sndrcvinfo *sndrcvinfo;
+
+ sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
+ data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
+ data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
+ data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
+ data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
+ data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
+ data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
+ }
+#endif
+ }
+ }
+
+ if (n <= 0)
+ {
+ if (n < 0)
+ ret = n;
+ break;
+ }
+
+ if (msg.msg_flags & MSG_NOTIFICATION)
+ {
+ snp = (union sctp_notification*) out;
+ if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
+ {
+#ifdef SCTP_EVENT
+ struct sctp_event event;
+#else
+ struct sctp_event_subscribe event;
+ socklen_t eventsize;
+#endif
+ /* If a message has been delayed until the socket
+ * is dry, it can be sent now.
+ */
+ if (data->saved_message.length > 0)
+ {
+ dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
+ data->saved_message.length);
+ OPENSSL_free(data->saved_message.data);
+ data->saved_message.length = 0;
+ }
+
+ /* disable sender dry event */
+#ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(struct sctp_event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_SENDER_DRY_EVENT;
+ event.se_on = 0;
+ i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
+ OPENSSL_assert(i >= 0);
+#else
+ eventsize = sizeof(struct sctp_event_subscribe);
+ i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
+ OPENSSL_assert(i >= 0);
+
+ event.sctp_sender_dry_event = 0;
+
+ i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
+ OPENSSL_assert(i >= 0);
+#endif
+ }
+
+#ifdef SCTP_AUTHENTICATION_EVENT
+ if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+ dgram_sctp_handle_auth_free_key_event(b, snp);
+#endif
+
+ if (data->handle_notifications != NULL)
+ data->handle_notifications(b, data->notification_context, (void*) out);
+
+ memset(out, 0, outl);
+ }
+ else
+ ret += n;
+ }
+ while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl));
+
+ if (ret > 0 && !(msg.msg_flags & MSG_EOR))
+ {
+ /* Partial message read, this should never happen! */
+
+ /* The buffer was too small, this means the peer sent
+ * a message that was larger than allowed. */
+ if (ret == outl)
+ return -1;
+
+ /* Test if socket buffer can handle max record
+ * size (2^14 + 2048 + 13)
+ */
+ optlen = (socklen_t) sizeof(int);
+ ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
+ OPENSSL_assert(ret >= 0);
+ OPENSSL_assert(optval >= 18445);
+
+ /* Test if SCTP doesn't partially deliver below
+ * max record size (2^14 + 2048 + 13)
+ */
+ optlen = (socklen_t) sizeof(int);
+ ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
+ &optval, &optlen);
+ OPENSSL_assert(ret >= 0);
+ OPENSSL_assert(optval >= 18445);
+
+ /* Partially delivered notification??? Probably a bug.... */
+ OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
+
+ /* Everything seems ok till now, so it's most likely
+ * a message dropped by PR-SCTP.
+ */
+ memset(out, 0, outl);
+ BIO_set_retry_read(b);
+ return -1;
+ }
+
+ BIO_clear_retry_flags(b);
+ if (ret < 0)
+ {
+ if (BIO_dgram_should_retry(ret))
+ {
+ BIO_set_retry_read(b);
+ data->_errno = get_last_socket_error();
+ }
+ }
+
+ /* Test if peer uses SCTP-AUTH before continuing */
+ if (!data->peer_auth_tested)
+ {
+ int ii, auth_data = 0, auth_forward = 0;
+ unsigned char *p;
+ struct sctp_authchunks *authchunks;
+
+ optlen = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
+ authchunks = OPENSSL_malloc(optlen);
+ memset(authchunks, 0, sizeof(optlen));
+ ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen);
+ OPENSSL_assert(ii >= 0);
+
+ for (p = (unsigned char*) authchunks + sizeof(sctp_assoc_t);
+ p < (unsigned char*) authchunks + optlen;
+ p += sizeof(uint8_t))
+ {
+ if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
+ if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
+ }
+
+ OPENSSL_free(authchunks);
+
+ if (!auth_data || !auth_forward)
+ {
+ BIOerr(BIO_F_DGRAM_SCTP_READ,BIO_R_CONNECT_ERROR);
+ return -1;
+ }
+
+ data->peer_auth_tested = 1;
+ }
+ }
+ return(ret);
+ }
+
+static int dgram_sctp_write(BIO *b, const char *in, int inl)
+ {
+ int ret;
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
+ struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
+ struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
+ struct bio_dgram_sctp_sndinfo handshake_sinfo;
+ struct iovec iov[1];
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
+ char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + CMSG_SPACE(sizeof(struct sctp_prinfo))];
+ struct sctp_sndinfo *sndinfo;
+ struct sctp_prinfo *prinfo;
+#else
+ char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct sctp_sndrcvinfo *sndrcvinfo;
+#endif
+
+ clear_socket_error();
+
+ /* If we're send anything else than application data,
+ * disable all user parameters and flags.
+ */
+ if (in[0] != 23) {
+ memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo));
+#ifdef SCTP_SACK_IMMEDIATELY
+ handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
+#endif
+ sinfo = &handshake_sinfo;
+ }
+
+ /* If we have to send a shutdown alert message and the
+ * socket is not dry yet, we have to save it and send it
+ * as soon as the socket gets dry.
+ */
+ if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b))
+ {
+ data->saved_message.bio = b;
+ data->saved_message.length = inl;
+ data->saved_message.data = OPENSSL_malloc(inl);
+ memcpy(data->saved_message.data, in, inl);
+ return inl;
+ }
+
+ iov[0].iov_base = (char *)in;
+ iov[0].iov_len = inl;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (caddr_t)cmsgbuf;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
+ cmsg = (struct cmsghdr *)cmsgbuf;
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
+ sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
+ memset(sndinfo, 0, sizeof(struct sctp_sndinfo));
+ sndinfo->snd_sid = sinfo->snd_sid;
+ sndinfo->snd_flags = sinfo->snd_flags;
+ sndinfo->snd_ppid = sinfo->snd_ppid;
+ sndinfo->snd_context = sinfo->snd_context;
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
+
+ cmsg = (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_PRINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
+ prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
+ memset(prinfo, 0, sizeof(struct sctp_prinfo));
+ prinfo->pr_policy = pinfo->pr_policy;
+ prinfo->pr_value = pinfo->pr_value;
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
+#else
+ cmsg = (struct cmsghdr *)cmsgbuf;
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
+ sndrcvinfo->sinfo_stream = sinfo->snd_sid;
+ sndrcvinfo->sinfo_flags = sinfo->snd_flags;
+#ifdef __FreeBSD__
+ sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
+#endif
+ sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
+ sndrcvinfo->sinfo_context = sinfo->snd_context;
+ sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
+#endif
+
+ ret = sendmsg(b->num, &msg, 0);
+
+ BIO_clear_retry_flags(b);
+ if (ret <= 0)
+ {
+ if (BIO_dgram_should_retry(ret))
+ {
+ BIO_set_retry_write(b);
+ data->_errno = get_last_socket_error();
+ }
+ }
+ return(ret);
+ }
+
+static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
+ {
+ long ret=1;
+ bio_dgram_sctp_data *data = NULL;
+ socklen_t sockopt_len = 0;
+ struct sctp_authkeyid authkeyid;
+ struct sctp_authkey *authkey;
+
+ data = (bio_dgram_sctp_data *)b->ptr;
+
+ switch (cmd)
+ {
+ case BIO_CTRL_DGRAM_QUERY_MTU:
+ /* Set to maximum (2^14)
+ * and ignore user input to enable transport
+ * protocol fragmentation.
+ * Returns always 2^14.
+ */
+ data->mtu = 16384;
+ ret = data->mtu;
+ break;
+ case BIO_CTRL_DGRAM_SET_MTU:
+ /* Set to maximum (2^14)
+ * and ignore input to enable transport
+ * protocol fragmentation.
+ * Returns always 2^14.
+ */
+ data->mtu = 16384;
+ ret = data->mtu;
+ break;
+ case BIO_CTRL_DGRAM_SET_CONNECTED:
+ case BIO_CTRL_DGRAM_CONNECT:
+ /* Returns always -1. */
+ ret = -1;
+ break;
+ case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+ /* SCTP doesn't need the DTLS timer
+ * Returns always 1.
+ */
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
+ if (num > 0)
+ data->in_handshake = 1;
+ else
+ data->in_handshake = 0;
+
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, &data->in_handshake, sizeof(int));
+ break;
+ case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
+ /* New shared key for SCTP AUTH.
+ * Returns 0 on success, -1 otherwise.
+ */
+
+ /* Get active key */
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
+ if (ret < 0) break;
+
+ /* Add new key */
+ sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
+ authkey = OPENSSL_malloc(sockopt_len);
+ memset(authkey, 0x00, sockopt_len);
+ authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
+#ifndef __FreeBSD__
+ /* This field is missing in FreeBSD 8.2 and earlier,
+ * and FreeBSD 8.3 and higher work without it.
+ */
+ authkey->sca_keylength = 64;
+#endif
+ memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
+
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len);
+ if (ret < 0) break;
+
+ /* Reset active key */
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ if (ret < 0) break;
+
+ break;
+ case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
+ /* Returns 0 on success, -1 otherwise. */
+
+ /* Get active key */
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
+ if (ret < 0) break;
+
+ /* Set active key */
+ authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ if (ret < 0) break;
+
+ /* CCS has been sent, so remember that and fall through
+ * to check if we need to deactivate an old key
+ */
+ data->ccs_sent = 1;
+
+ case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
+ /* Returns 0 on success, -1 otherwise. */
+
+ /* Has this command really been called or is this just a fall-through? */
+ if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
+ data->ccs_rcvd = 1;
+
+ /* CSS has been both, received and sent, so deactivate an old key */
+ if (data->ccs_rcvd == 1 && data->ccs_sent == 1)
+ {
+ /* Get active key */
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
+ if (ret < 0) break;
+
+ /* Deactivate key or delete second last key if
+ * SCTP_AUTHENTICATION_EVENT is not available.
+ */
+ authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
+#ifdef SCTP_AUTH_DEACTIVATE_KEY
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
+ &authkeyid, sockopt_len);
+ if (ret < 0) break;
+#endif
+#ifndef SCTP_AUTHENTICATION_EVENT
+ if (authkeyid.scact_keynumber > 0)
+ {
+ authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ if (ret < 0) break;
+ }
+#endif
+
+ data->ccs_rcvd = 0;
+ data->ccs_sent = 0;
+ }
+ break;
+ case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
+ num = sizeof(struct bio_dgram_sctp_sndinfo);
+
+ memcpy(ptr, &(data->sndinfo), num);
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
+ num = sizeof(struct bio_dgram_sctp_sndinfo);
+
+ memcpy(&(data->sndinfo), ptr, num);
+ break;
+ case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
+ num = sizeof(struct bio_dgram_sctp_rcvinfo);
+
+ memcpy(ptr, &data->rcvinfo, num);
+
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
+ num = sizeof(struct bio_dgram_sctp_rcvinfo);
+
+ memcpy(&(data->rcvinfo), ptr, num);
+ break;
+ case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
+ num = sizeof(struct bio_dgram_sctp_prinfo);
+
+ memcpy(ptr, &(data->prinfo), num);
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
+ num = sizeof(struct bio_dgram_sctp_prinfo);
+
+ memcpy(&(data->prinfo), ptr, num);
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
+ /* Returns always 1. */
+ if (num > 0)
+ data->save_shutdown = 1;
+ else
+ data->save_shutdown = 0;
+ break;
+
+ default:
+ /* Pass to default ctrl function to
+ * process SCTP unspecific commands
+ */
+ ret=dgram_ctrl(b, cmd, num, ptr);
+ break;
+ }
+ return(ret);
+ }
+
+int BIO_dgram_sctp_notification_cb(BIO *b,
+ void (*handle_notifications)(BIO *bio, void *context, void *buf),
+ void *context)
+ {
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+
+ if (handle_notifications != NULL)
+ {
+ data->handle_notifications = handle_notifications;
+ data->notification_context = context;
+ }
+ else
+ return -1;
+
+ return 0;
+ }
+
+int BIO_dgram_sctp_wait_for_dry(BIO *b)
+{
+ int is_dry = 0;
+ int n, sockflags, ret;
+ union sctp_notification snp;
+ struct msghdr msg;
+ struct iovec iov;
+#ifdef SCTP_EVENT
+ struct sctp_event event;
+#else
+ struct sctp_event_subscribe event;
+ socklen_t eventsize;
+#endif
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
+
+ /* set sender dry event */
+#ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(struct sctp_event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_SENDER_DRY_EVENT;
+ event.se_on = 1;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
+#else
+ eventsize = sizeof(struct sctp_event_subscribe);
+ ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
+ if (ret < 0)
+ return -1;
+
+ event.sctp_sender_dry_event = 1;
+
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
+#endif
+ if (ret < 0)
+ return -1;
+
+ /* peek for notification */
+ memset(&snp, 0x00, sizeof(union sctp_notification));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ n = recvmsg(b->num, &msg, MSG_PEEK);
+ if (n <= 0)
+ {
+ if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
+ return -1;
+ else
+ return 0;
+ }
+
+ /* if we find a notification, process it and try again if necessary */
+ while (msg.msg_flags & MSG_NOTIFICATION)
+ {
+ memset(&snp, 0x00, sizeof(union sctp_notification));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ n = recvmsg(b->num, &msg, 0);
+ if (n <= 0)
+ {
+ if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
+ return -1;
+ else
+ return is_dry;
+ }
+
+ if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
+ {
+ is_dry = 1;
+
+ /* disable sender dry event */
+#ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(struct sctp_event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_SENDER_DRY_EVENT;
+ event.se_on = 0;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
+#else
+ eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
+ ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
+ if (ret < 0)
+ return -1;
+
+ event.sctp_sender_dry_event = 0;
+
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
+#endif
+ if (ret < 0)
+ return -1;
+ }
+
+#ifdef SCTP_AUTHENTICATION_EVENT
+ if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+ dgram_sctp_handle_auth_free_key_event(b, &snp);
+#endif
+
+ if (data->handle_notifications != NULL)
+ data->handle_notifications(b, data->notification_context, (void*) &snp);
+
+ /* found notification, peek again */
+ memset(&snp, 0x00, sizeof(union sctp_notification));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ /* if we have seen the dry already, don't wait */
+ if (is_dry)
+ {
+ sockflags = fcntl(b->num, F_GETFL, 0);
+ fcntl(b->num, F_SETFL, O_NONBLOCK);
+ }
+
+ n = recvmsg(b->num, &msg, MSG_PEEK);
+
+ if (is_dry)
+ {
+ fcntl(b->num, F_SETFL, sockflags);
+ }
+
+ if (n <= 0)
+ {
+ if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
+ return -1;
+ else
+ return is_dry;
+ }
+ }
+
+ /* read anything else */
+ return is_dry;
+}
+
+int BIO_dgram_sctp_msg_waiting(BIO *b)
+ {
+ int n, sockflags;
+ union sctp_notification snp;
+ struct msghdr msg;
+ struct iovec iov;
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
+
+ /* Check if there are any messages waiting to be read */
+ do
+ {
+ memset(&snp, 0x00, sizeof(union sctp_notification));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ sockflags = fcntl(b->num, F_GETFL, 0);
+ fcntl(b->num, F_SETFL, O_NONBLOCK);
+ n = recvmsg(b->num, &msg, MSG_PEEK);
+ fcntl(b->num, F_SETFL, sockflags);
+
+ /* if notification, process and try again */
+ if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION))
+ {
+#ifdef SCTP_AUTHENTICATION_EVENT
+ if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+ dgram_sctp_handle_auth_free_key_event(b, &snp);
+#endif
+
+ memset(&snp, 0x00, sizeof(union sctp_notification));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+ n = recvmsg(b->num, &msg, 0);
+
+ if (data->handle_notifications != NULL)
+ data->handle_notifications(b, data->notification_context, (void*) &snp);
+ }
+
+ } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
+
+ /* Return 1 if there is a message to be read, return 0 otherwise. */
+ if (n > 0)
+ return 1;
+ else
+ return 0;
+ }
+
+static int dgram_sctp_puts(BIO *bp, const char *str)
+ {
+ int n,ret;
+
+ n=strlen(str);
+ ret=dgram_sctp_write(bp,str,n);
+ return(ret);
+ }
+#endif
+
static int BIO_dgram_should_retry(int i)
{
int err;
diff --git a/deps/openssl/openssl/crypto/bn/Makefile b/deps/openssl/openssl/crypto/bn/Makefile
index aabc4f56b..672773454 100644
--- a/deps/openssl/openssl/crypto/bn/Makefile
+++ b/deps/openssl/openssl/crypto/bn/Makefile
@@ -26,13 +26,13 @@ LIBSRC= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \
bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c \
bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
- bn_depr.c bn_const.c
+ bn_depr.c bn_const.c bn_x931p.c
LIBOBJ= bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o bn_mod.o \
bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \
bn_kron.o bn_sqrt.o bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) \
bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_gf2m.o bn_nist.o \
- bn_depr.o bn_const.o
+ bn_depr.o bn_const.o bn_x931p.o
SRC= $(LIBSRC)
@@ -66,6 +66,8 @@ co-586.s: asm/co-586.pl ../perlasm/x86asm.pl
$(PERL) asm/co-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
x86-mont.s: asm/x86-mont.pl ../perlasm/x86asm.pl
$(PERL) asm/x86-mont.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+x86-gf2m.s: asm/x86-gf2m.pl ../perlasm/x86asm.pl
+ $(PERL) asm/x86-gf2m.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
sparcv8.o: asm/sparcv8.S
$(CC) $(CFLAGS) -c asm/sparcv8.S
@@ -82,16 +84,31 @@ bn-mips3.o: asm/mips3.s
as -$$ABI -O -o $@ asm/mips3.s; \
else $(CC) -c $(CFLAGS) -o $@ asm/mips3.s; fi
+bn-mips.s: asm/mips.pl
+ $(PERL) asm/mips.pl $(PERLASM_SCHEME) $@
+mips-mont.s: asm/mips-mont.pl
+ $(PERL) asm/mips-mont.pl $(PERLASM_SCHEME) $@
+
bn-s390x.o: asm/s390x.S
$(CC) $(CFLAGS) -c -o $@ asm/s390x.S
+s390x-gf2m.s: asm/s390x-gf2m.pl
+ $(PERL) asm/s390x-gf2m.pl $(PERLASM_SCHEME) $@
x86_64-gcc.o: asm/x86_64-gcc.c
$(CC) $(CFLAGS) -c -o $@ asm/x86_64-gcc.c
x86_64-mont.s: asm/x86_64-mont.pl
$(PERL) asm/x86_64-mont.pl $(PERLASM_SCHEME) > $@
+x86_64-mont5.s: asm/x86_64-mont5.pl
+ $(PERL) asm/x86_64-mont5.pl $(PERLASM_SCHEME) > $@
+x86_64-gf2m.s: asm/x86_64-gf2m.pl
+ $(PERL) asm/x86_64-gf2m.pl $(PERLASM_SCHEME) > $@
+modexp512-x86_64.s: asm/modexp512-x86_64.pl
+ $(PERL) asm/modexp512-x86_64.pl $(PERLASM_SCHEME) > $@
bn-ia64.s: asm/ia64.S
$(CC) $(CFLAGS) -E asm/ia64.S > $@
+ia64-mont.s: asm/ia64-mont.pl
+ $(PERL) asm/ia64-mont.pl $@ $(CFLAGS)
# GNU assembler fails to compile PA-RISC2 modules, insist on calling
# vendor assembler...
@@ -99,16 +116,22 @@ pa-risc2W.o: asm/pa-risc2W.s
/usr/ccs/bin/as -o pa-risc2W.o asm/pa-risc2W.s
pa-risc2.o: asm/pa-risc2.s
/usr/ccs/bin/as -o pa-risc2.o asm/pa-risc2.s
+parisc-mont.s: asm/parisc-mont.pl
+ $(PERL) asm/parisc-mont.pl $(PERLASM_SCHEME) $@
# ppc - AIX, Linux, MacOS X...
bn-ppc.s: asm/ppc.pl; $(PERL) asm/ppc.pl $(PERLASM_SCHEME) $@
ppc-mont.s: asm/ppc-mont.pl;$(PERL) asm/ppc-mont.pl $(PERLASM_SCHEME) $@
+ppc64-mont.s: asm/ppc64-mont.pl;$(PERL) asm/ppc64-mont.pl $(PERLASM_SCHEME) $@
alpha-mont.s: asm/alpha-mont.pl
$(PERL) $< | $(CC) -E - | tee $@ > /dev/null
# GNU make "catch all"
-%-mont.s: asm/%-mont.pl; $(PERL) $< $(CFLAGS) > $@
+%-mont.s: asm/%-mont.pl; $(PERL) $< $(PERLASM_SCHEME) $@
+%-gf2m.S: asm/%-gf2m.pl; $(PERL) $< $(PERLASM_SCHEME) $@
+
+armv4-gf2m.o: armv4-gf2m.S
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
@@ -345,3 +368,8 @@ bn_word.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
bn_word.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
bn_word.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
bn_word.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_word.c
+bn_x931p.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+bn_x931p.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+bn_x931p.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_x931p.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_x931p.o: ../../include/openssl/symhacks.h bn_x931p.c
diff --git a/deps/openssl/openssl/crypto/bn/asm/armv4-gf2m.pl b/deps/openssl/openssl/crypto/bn/asm/armv4-gf2m.pl
new file mode 100644
index 000000000..c52e0b75b
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/asm/armv4-gf2m.pl
@@ -0,0 +1,278 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# May 2011
+#
+# The module implements bn_GF2m_mul_2x2 polynomial multiplication
+# used in bn_gf2m.c. It's kind of low-hanging mechanical port from
+# C for the time being... Except that it has two code paths: pure
+# integer code suitable for any ARMv4 and later CPU and NEON code
+# suitable for ARMv7. Pure integer 1x1 multiplication subroutine runs
+# in ~45 cycles on dual-issue core such as Cortex A8, which is ~50%
+# faster than compiler-generated code. For ECDH and ECDSA verify (but
+# not for ECDSA sign) it means 25%-45% improvement depending on key
+# length, more for longer keys. Even though NEON 1x1 multiplication
+# runs in even less cycles, ~30, improvement is measurable only on
+# longer keys. One has to optimize code elsewhere to get NEON glow...
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+sub Dlo() { shift=~m|q([1]?[0-9])|?"d".($1*2):""; }
+sub Dhi() { shift=~m|q([1]?[0-9])|?"d".($1*2+1):""; }
+sub Q() { shift=~m|d([1-3]?[02468])|?"q".($1/2):""; }
+
+$code=<<___;
+#include "arm_arch.h"
+
+.text
+.code 32
+
+#if __ARM_ARCH__>=7
+.fpu neon
+
+.type mul_1x1_neon,%function
+.align 5
+mul_1x1_neon:
+ vshl.u64 `&Dlo("q1")`,d16,#8 @ q1-q3 are slided $a
+ vmull.p8 `&Q("d0")`,d16,d17 @ a·bb
+ vshl.u64 `&Dlo("q2")`,d16,#16
+ vmull.p8 q1,`&Dlo("q1")`,d17 @ a<<8·bb
+ vshl.u64 `&Dlo("q3")`,d16,#24
+ vmull.p8 q2,`&Dlo("q2")`,d17 @ a<<16·bb
+ vshr.u64 `&Dlo("q1")`,#8
+ vmull.p8 q3,`&Dlo("q3")`,d17 @ a<<24·bb
+ vshl.u64 `&Dhi("q1")`,#24
+ veor d0,`&Dlo("q1")`
+ vshr.u64 `&Dlo("q2")`,#16
+ veor d0,`&Dhi("q1")`
+ vshl.u64 `&Dhi("q2")`,#16
+ veor d0,`&Dlo("q2")`
+ vshr.u64 `&Dlo("q3")`,#24
+ veor d0,`&Dhi("q2")`
+ vshl.u64 `&Dhi("q3")`,#8
+ veor d0,`&Dlo("q3")`
+ veor d0,`&Dhi("q3")`
+ bx lr
+.size mul_1x1_neon,.-mul_1x1_neon
+#endif
+___
+################
+# private interface to mul_1x1_ialu
+#
+$a="r1";
+$b="r0";
+
+($a0,$a1,$a2,$a12,$a4,$a14)=
+($hi,$lo,$t0,$t1, $i0,$i1 )=map("r$_",(4..9),12);
+
+$mask="r12";
+
+$code.=<<___;
+.type mul_1x1_ialu,%function
+.align 5
+mul_1x1_ialu:
+ mov $a0,#0
+ bic $a1,$a,#3<<30 @ a1=a&0x3fffffff
+ str $a0,[sp,#0] @ tab[0]=0
+ add $a2,$a1,$a1 @ a2=a1<<1
+ str $a1,[sp,#4] @ tab[1]=a1
+ eor $a12,$a1,$a2 @ a1^a2
+ str $a2,[sp,#8] @ tab[2]=a2
+ mov $a4,$a1,lsl#2 @ a4=a1<<2
+ str $a12,[sp,#12] @ tab[3]=a1^a2
+ eor $a14,$a1,$a4 @ a1^a4
+ str $a4,[sp,#16] @ tab[4]=a4
+ eor $a0,$a2,$a4 @ a2^a4
+ str $a14,[sp,#20] @ tab[5]=a1^a4
+ eor $a12,$a12,$a4 @ a1^a2^a4
+ str $a0,[sp,#24] @ tab[6]=a2^a4
+ and $i0,$mask,$b,lsl#2
+ str $a12,[sp,#28] @ tab[7]=a1^a2^a4
+
+ and $i1,$mask,$b,lsr#1
+ ldr $lo,[sp,$i0] @ tab[b & 0x7]
+ and $i0,$mask,$b,lsr#4
+ ldr $t1,[sp,$i1] @ tab[b >> 3 & 0x7]
+ and $i1,$mask,$b,lsr#7
+ ldr $t0,[sp,$i0] @ tab[b >> 6 & 0x7]
+ eor $lo,$lo,$t1,lsl#3 @ stall
+ mov $hi,$t1,lsr#29
+ ldr $t1,[sp,$i1] @ tab[b >> 9 & 0x7]
+
+ and $i0,$mask,$b,lsr#10
+ eor $lo,$lo,$t0,lsl#6
+ eor $hi,$hi,$t0,lsr#26
+ ldr $t0,[sp,$i0] @ tab[b >> 12 & 0x7]
+
+ and $i1,$mask,$b,lsr#13
+ eor $lo,$lo,$t1,lsl#9
+ eor $hi,$hi,$t1,lsr#23
+ ldr $t1,[sp,$i1] @ tab[b >> 15 & 0x7]
+
+ and $i0,$mask,$b,lsr#16
+ eor $lo,$lo,$t0,lsl#12
+ eor $hi,$hi,$t0,lsr#20
+ ldr $t0,[sp,$i0] @ tab[b >> 18 & 0x7]
+
+ and $i1,$mask,$b,lsr#19
+ eor $lo,$lo,$t1,lsl#15
+ eor $hi,$hi,$t1,lsr#17
+ ldr $t1,[sp,$i1] @ tab[b >> 21 & 0x7]
+
+ and $i0,$mask,$b,lsr#22
+ eor $lo,$lo,$t0,lsl#18
+ eor $hi,$hi,$t0,lsr#14
+ ldr $t0,[sp,$i0] @ tab[b >> 24 & 0x7]
+
+ and $i1,$mask,$b,lsr#25
+ eor $lo,$lo,$t1,lsl#21
+ eor $hi,$hi,$t1,lsr#11
+ ldr $t1,[sp,$i1] @ tab[b >> 27 & 0x7]
+
+ tst $a,#1<<30
+ and $i0,$mask,$b,lsr#28
+ eor $lo,$lo,$t0,lsl#24
+ eor $hi,$hi,$t0,lsr#8
+ ldr $t0,[sp,$i0] @ tab[b >> 30 ]
+
+ eorne $lo,$lo,$b,lsl#30
+ eorne $hi,$hi,$b,lsr#2
+ tst $a,#1<<31
+ eor $lo,$lo,$t1,lsl#27
+ eor $hi,$hi,$t1,lsr#5
+ eorne $lo,$lo,$b,lsl#31
+ eorne $hi,$hi,$b,lsr#1
+ eor $lo,$lo,$t0,lsl#30
+ eor $hi,$hi,$t0,lsr#2
+
+ mov pc,lr
+.size mul_1x1_ialu,.-mul_1x1_ialu
+___
+################
+# void bn_GF2m_mul_2x2(BN_ULONG *r,
+# BN_ULONG a1,BN_ULONG a0,
+# BN_ULONG b1,BN_ULONG b0); # r[3..0]=a1a0·b1b0
+
+($A1,$B1,$A0,$B0,$A1B1,$A0B0)=map("d$_",(18..23));
+
+$code.=<<___;
+.global bn_GF2m_mul_2x2
+.type bn_GF2m_mul_2x2,%function
+.align 5
+bn_GF2m_mul_2x2:
+#if __ARM_ARCH__>=7
+ ldr r12,.LOPENSSL_armcap
+.Lpic: ldr r12,[pc,r12]
+ tst r12,#1
+ beq .Lialu
+
+ veor $A1,$A1
+ vmov.32 $B1,r3,r3 @ two copies of b1
+ vmov.32 ${A1}[0],r1 @ a1
+
+ veor $A0,$A0
+ vld1.32 ${B0}[],[sp,:32] @ two copies of b0
+ vmov.32 ${A0}[0],r2 @ a0
+ mov r12,lr
+
+ vmov d16,$A1
+ vmov d17,$B1
+ bl mul_1x1_neon @ a1·b1
+ vmov $A1B1,d0
+
+ vmov d16,$A0
+ vmov d17,$B0
+ bl mul_1x1_neon @ a0·b0
+ vmov $A0B0,d0
+
+ veor d16,$A0,$A1
+ veor d17,$B0,$B1
+ veor $A0,$A0B0,$A1B1
+ bl mul_1x1_neon @ (a0+a1)·(b0+b1)
+
+ veor d0,$A0 @ (a0+a1)·(b0+b1)-a0·b0-a1·b1
+ vshl.u64 d1,d0,#32
+ vshr.u64 d0,d0,#32
+ veor $A0B0,d1
+ veor $A1B1,d0
+ vst1.32 {${A0B0}[0]},[r0,:32]!
+ vst1.32 {${A0B0}[1]},[r0,:32]!
+ vst1.32 {${A1B1}[0]},[r0,:32]!
+ vst1.32 {${A1B1}[1]},[r0,:32]
+ bx r12
+.align 4
+.Lialu:
+#endif
+___
+$ret="r10"; # reassigned 1st argument
+$code.=<<___;
+ stmdb sp!,{r4-r10,lr}
+ mov $ret,r0 @ reassign 1st argument
+ mov $b,r3 @ $b=b1
+ ldr r3,[sp,#32] @ load b0
+ mov $mask,#7<<2
+ sub sp,sp,#32 @ allocate tab[8]
+
+ bl mul_1x1_ialu @ a1·b1
+ str $lo,[$ret,#8]
+ str $hi,[$ret,#12]
+
+ eor $b,$b,r3 @ flip b0 and b1
+ eor $a,$a,r2 @ flip a0 and a1
+ eor r3,r3,$b
+ eor r2,r2,$a
+ eor $b,$b,r3
+ eor $a,$a,r2
+ bl mul_1x1_ialu @ a0·b0
+ str $lo,[$ret]
+ str $hi,[$ret,#4]
+
+ eor $a,$a,r2
+ eor $b,$b,r3
+ bl mul_1x1_ialu @ (a1+a0)·(b1+b0)
+___
+@r=map("r$_",(6..9));
+$code.=<<___;
+ ldmia $ret,{@r[0]-@r[3]}
+ eor $lo,$lo,$hi
+ eor $hi,$hi,@r[1]
+ eor $lo,$lo,@r[0]
+ eor $hi,$hi,@r[2]
+ eor $lo,$lo,@r[3]
+ eor $hi,$hi,@r[3]
+ str $hi,[$ret,#8]
+ eor $lo,$lo,$hi
+ add sp,sp,#32 @ destroy tab[8]
+ str $lo,[$ret,#4]
+
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r10,pc}
+#else
+ ldmia sp!,{r4-r10,lr}
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ bx lr @ interoperable with Thumb ISA:-)
+#endif
+.size bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
+#if __ARM_ARCH__>=7
+.align 5
+.LOPENSSL_armcap:
+.word OPENSSL_armcap_P-(.Lpic+8)
+#endif
+.asciz "GF(2^m) Multiplication for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
+.align 5
+
+.comm OPENSSL_armcap_P,4,4
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
+print $code;
+close STDOUT; # enforce flush
diff --git a/deps/openssl/openssl/crypto/bn/asm/armv4-mont.pl b/deps/openssl/openssl/crypto/bn/asm/armv4-mont.pl
index 14e0d2d1d..f78a8b5f0 100644
--- a/deps/openssl/openssl/crypto/bn/asm/armv4-mont.pl
+++ b/deps/openssl/openssl/crypto/bn/asm/armv4-mont.pl
@@ -23,6 +23,9 @@
# than 1/2KB. Windows CE port would be trivial, as it's exclusively
# about decorations, ABI and instruction syntax are identical.
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
$num="r0"; # starts as num argument, but holds &tp[num-1]
$ap="r1";
$bp="r2"; $bi="r2"; $rp="r2";
@@ -89,9 +92,9 @@ bn_mul_mont:
.L1st:
ldr $aj,[$ap],#4 @ ap[j],ap++
mov $alo,$ahi
+ ldr $nj,[$np],#4 @ np[j],np++
mov $ahi,#0
umlal $alo,$ahi,$aj,$bi @ ap[j]*bp[0]
- ldr $nj,[$np],#4 @ np[j],np++
mov $nhi,#0
umlal $nlo,$nhi,$nj,$n0 @ np[j]*n0
adds $nlo,$nlo,$alo
@@ -101,21 +104,21 @@ bn_mul_mont:
bne .L1st
adds $nlo,$nlo,$ahi
+ ldr $tp,[$_bp] @ restore bp
mov $nhi,#0
+ ldr $n0,[$_n0] @ restore n0
adc $nhi,$nhi,#0
- ldr $tp,[$_bp] @ restore bp
str $nlo,[$num] @ tp[num-1]=
- ldr $n0,[$_n0] @ restore n0
str $nhi,[$num,#4] @ tp[num]=
.Louter:
sub $tj,$num,sp @ "original" $num-1 value
sub $ap,$ap,$tj @ "rewind" ap to &ap[1]
- sub $np,$np,$tj @ "rewind" np to &np[1]
ldr $bi,[$tp,#4]! @ *(++bp)
+ sub $np,$np,$tj @ "rewind" np to &np[1]
ldr $aj,[$ap,#-4] @ ap[0]
- ldr $nj,[$np,#-4] @ np[0]
ldr $alo,[sp] @ tp[0]
+ ldr $nj,[$np,#-4] @ np[0]
ldr $tj,[sp,#4] @ tp[1]
mov $ahi,#0
@@ -129,13 +132,13 @@ bn_mul_mont:
.Linner:
ldr $aj,[$ap],#4 @ ap[j],ap++
adds $alo,$ahi,$tj @ +=tp[j]
+ ldr $nj,[$np],#4 @ np[j],np++
mov $ahi,#0
umlal $alo,$ahi,$aj,$bi @ ap[j]*bp[i]
- ldr $nj,[$np],#4 @ np[j],np++
mov $nhi,#0
umlal $nlo,$nhi,$nj,$n0 @ np[j]*n0
- ldr $tj,[$tp,#8] @ tp[j+1]
adc $ahi,$ahi,#0
+ ldr $tj,[$tp,#8] @ tp[j+1]
adds $nlo,$nlo,$alo
str $nlo,[$tp],#4 @ tp[j-1]=,tp++
adc $nlo,$nhi,#0
@@ -144,13 +147,13 @@ bn_mul_mont:
adds $nlo,$nlo,$ahi
mov $nhi,#0
+ ldr $tp,[$_bp] @ restore bp
adc $nhi,$nhi,#0
+ ldr $n0,[$_n0] @ restore n0
adds $nlo,$nlo,$tj
- adc $nhi,$nhi,#0
- ldr $tp,[$_bp] @ restore bp
ldr $tj,[$_bpend] @ restore &bp[num]
+ adc $nhi,$nhi,#0
str $nlo,[$num] @ tp[num-1]=
- ldr $n0,[$_n0] @ restore n0
str $nhi,[$num,#4] @ tp[num]=
cmp $tp,$tj
diff --git a/deps/openssl/openssl/crypto/bn/asm/ia64-mont.pl b/deps/openssl/openssl/crypto/bn/asm/ia64-mont.pl
new file mode 100644
index 000000000..e25865842
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/asm/ia64-mont.pl
@@ -0,0 +1,851 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# January 2010
+#
+# "Teaser" Montgomery multiplication module for IA-64. There are
+# several possibilities for improvement:
+#
+# - modulo-scheduling outer loop would eliminate quite a number of
+# stalls after ldf8, xma and getf.sig outside inner loop and
+# improve shorter key performance;
+# - shorter vector support [with input vectors being fetched only
+# once] should be added;
+# - 2x unroll with help of n0[1] would make the code scalable on
+# "wider" IA-64, "wider" than Itanium 2 that is, which is not of
+# acute interest, because upcoming Tukwila's individual cores are
+# reportedly based on Itanium 2 design;
+# - dedicated squaring procedure(?);
+#
+# January 2010
+#
+# Shorter vector support is implemented by zero-padding ap and np
+# vectors up to 8 elements, or 512 bits. This means that 256-bit
+# inputs will be processed only 2 times faster than 512-bit inputs,
+# not 4 [as one would expect, because algorithm complexity is n^2].
+# The reason for padding is that inputs shorter than 512 bits won't
+# be processed faster anyway, because minimal critical path of the
+# core loop happens to match 512-bit timing. Either way, it resulted
+# in >100% improvement of 512-bit RSA sign benchmark and 50% - of
+# 1024-bit one [in comparison to original version of *this* module].
+#
+# So far 'openssl speed rsa dsa' output on 900MHz Itanium 2 *with*
+# this module is:
+# sign verify sign/s verify/s
+# rsa 512 bits 0.000290s 0.000024s 3452.8 42031.4
+# rsa 1024 bits 0.000793s 0.000058s 1261.7 17172.0
+# rsa 2048 bits 0.005908s 0.000148s 169.3 6754.0
+# rsa 4096 bits 0.033456s 0.000469s 29.9 2133.6
+# dsa 512 bits 0.000253s 0.000198s 3949.9 5057.0
+# dsa 1024 bits 0.000585s 0.000607s 1708.4 1647.4
+# dsa 2048 bits 0.001453s 0.001703s 688.1 587.4
+#
+# ... and *without* (but still with ia64.S):
+#
+# rsa 512 bits 0.000670s 0.000041s 1491.8 24145.5
+# rsa 1024 bits 0.001988s 0.000080s 502.9 12499.3
+# rsa 2048 bits 0.008702s 0.000189s 114.9 5293.9
+# rsa 4096 bits 0.043860s 0.000533s 22.8 1875.9
+# dsa 512 bits 0.000441s 0.000427s 2265.3 2340.6
+# dsa 1024 bits 0.000823s 0.000867s 1215.6 1153.2
+# dsa 2048 bits 0.001894s 0.002179s 528.1 458.9
+#
+# As it can be seen, RSA sign performance improves by 130-30%,
+# hereafter less for longer keys, while verify - by 74-13%.
+# DSA performance improves by 115-30%.
+
+if ($^O eq "hpux") {
+ $ADDP="addp4";
+ for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
+} else { $ADDP="add"; }
+
+$code=<<___;
+.explicit
+.text
+
+// int bn_mul_mont (BN_ULONG *rp,const BN_ULONG *ap,
+// const BN_ULONG *bp,const BN_ULONG *np,
+// const BN_ULONG *n0p,int num);
+.align 64
+.global bn_mul_mont#
+.proc bn_mul_mont#
+bn_mul_mont:
+ .prologue
+ .body
+{ .mmi; cmp4.le p6,p7=2,r37;;
+(p6) cmp4.lt.unc p8,p9=8,r37
+ mov ret0=r0 };;
+{ .bbb;
+(p9) br.cond.dptk.many bn_mul_mont_8
+(p8) br.cond.dpnt.many bn_mul_mont_general
+(p7) br.ret.spnt.many b0 };;
+.endp bn_mul_mont#
+
+prevfs=r2; prevpr=r3; prevlc=r10; prevsp=r11;
+
+rptr=r8; aptr=r9; bptr=r14; nptr=r15;
+tptr=r16; // &tp[0]
+tp_1=r17; // &tp[-1]
+num=r18; len=r19; lc=r20;
+topbit=r21; // carry bit from tmp[num]
+
+n0=f6;
+m0=f7;
+bi=f8;
+
+.align 64
+.local bn_mul_mont_general#
+.proc bn_mul_mont_general#
+bn_mul_mont_general:
+ .prologue
+{ .mmi; .save ar.pfs,prevfs
+ alloc prevfs=ar.pfs,6,2,0,8
+ $ADDP aptr=0,in1
+ .save ar.lc,prevlc
+ mov prevlc=ar.lc }
+{ .mmi; .vframe prevsp
+ mov prevsp=sp
+ $ADDP bptr=0,in2
+ .save pr,prevpr
+ mov prevpr=pr };;
+
+ .body
+ .rotf alo[6],nlo[4],ahi[8],nhi[6]
+ .rotr a[3],n[3],t[2]
+
+{ .mmi; ldf8 bi=[bptr],8 // (*bp++)
+ ldf8 alo[4]=[aptr],16 // ap[0]
+ $ADDP r30=8,in1 };;
+{ .mmi; ldf8 alo[3]=[r30],16 // ap[1]
+ ldf8 alo[2]=[aptr],16 // ap[2]
+ $ADDP in4=0,in4 };;
+{ .mmi; ldf8 alo[1]=[r30] // ap[3]
+ ldf8 n0=[in4] // n0
+ $ADDP rptr=0,in0 }
+{ .mmi; $ADDP nptr=0,in3
+ mov r31=16
+ zxt4 num=in5 };;
+{ .mmi; ldf8 nlo[2]=[nptr],8 // np[0]
+ shladd len=num,3,r0
+ shladd r31=num,3,r31 };;
+{ .mmi; ldf8 nlo[1]=[nptr],8 // np[1]
+ add lc=-5,num
+ sub r31=sp,r31 };;
+{ .mfb; and sp=-16,r31 // alloca
+ xmpy.hu ahi[2]=alo[4],bi // ap[0]*bp[0]
+ nop.b 0 }
+{ .mfb; nop.m 0
+ xmpy.lu alo[4]=alo[4],bi
+ brp.loop.imp .L1st_ctop,.L1st_cend-16
+ };;
+{ .mfi; nop.m 0
+ xma.hu ahi[1]=alo[3],bi,ahi[2] // ap[1]*bp[0]
+ add tp_1=8,sp }
+{ .mfi; nop.m 0
+ xma.lu alo[3]=alo[3],bi,ahi[2]
+ mov pr.rot=0x20001f<<16
+ // ------^----- (p40) at first (p23)
+ // ----------^^ p[16:20]=1
+ };;
+{ .mfi; nop.m 0
+ xmpy.lu m0=alo[4],n0 // (ap[0]*bp[0])*n0
+ mov ar.lc=lc }
+{ .mfi; nop.m 0
+ fcvt.fxu.s1 nhi[1]=f0
+ mov ar.ec=8 };;
+
+.align 32
+.L1st_ctop:
+.pred.rel "mutex",p40,p42
+{ .mfi; (p16) ldf8 alo[0]=[aptr],8 // *(aptr++)
+ (p18) xma.hu ahi[0]=alo[2],bi,ahi[1]
+ (p40) add n[2]=n[2],a[2] } // (p23) }
+{ .mfi; (p18) ldf8 nlo[0]=[nptr],8 // *(nptr++)(p16)
+ (p18) xma.lu alo[2]=alo[2],bi,ahi[1]
+ (p42) add n[2]=n[2],a[2],1 };; // (p23)
+{ .mfi; (p21) getf.sig a[0]=alo[5]
+ (p20) xma.hu nhi[0]=nlo[2],m0,nhi[1]
+ (p42) cmp.leu p41,p39=n[2],a[2] } // (p23)
+{ .mfi; (p23) st8 [tp_1]=n[2],8
+ (p20) xma.lu nlo[2]=nlo[2],m0,nhi[1]
+ (p40) cmp.ltu p41,p39=n[2],a[2] } // (p23)
+{ .mmb; (p21) getf.sig n[0]=nlo[3]
+ (p16) nop.m 0
+ br.ctop.sptk .L1st_ctop };;
+.L1st_cend:
+
+{ .mmi; getf.sig a[0]=ahi[6] // (p24)
+ getf.sig n[0]=nhi[4]
+ add num=-1,num };; // num--
+{ .mmi; .pred.rel "mutex",p40,p42
+(p40) add n[0]=n[0],a[0]
+(p42) add n[0]=n[0],a[0],1
+ sub aptr=aptr,len };; // rewind
+{ .mmi; .pred.rel "mutex",p40,p42
+(p40) cmp.ltu p41,p39=n[0],a[0]
+(p42) cmp.leu p41,p39=n[0],a[0]
+ sub nptr=nptr,len };;
+{ .mmi; .pred.rel "mutex",p39,p41
+(p39) add topbit=r0,r0
+(p41) add topbit=r0,r0,1
+ nop.i 0 }
+{ .mmi; st8 [tp_1]=n[0]
+ add tptr=16,sp
+ add tp_1=8,sp };;
+
+.Louter:
+{ .mmi; ldf8 bi=[bptr],8 // (*bp++)
+ ldf8 ahi[3]=[tptr] // tp[0]
+ add r30=8,aptr };;
+{ .mmi; ldf8 alo[4]=[aptr],16 // ap[0]
+ ldf8 alo[3]=[r30],16 // ap[1]
+ add r31=8,nptr };;
+{ .mfb; ldf8 alo[2]=[aptr],16 // ap[2]
+ xma.hu ahi[2]=alo[4],bi,ahi[3] // ap[0]*bp[i]+tp[0]
+ brp.loop.imp .Linner_ctop,.Linner_cend-16
+ }
+{ .mfb; ldf8 alo[1]=[r30] // ap[3]
+ xma.lu alo[4]=alo[4],bi,ahi[3]
+ clrrrb.pr };;
+{ .mfi; ldf8 nlo[2]=[nptr],16 // np[0]
+ xma.hu ahi[1]=alo[3],bi,ahi[2] // ap[1]*bp[i]
+ nop.i 0 }
+{ .mfi; ldf8 nlo[1]=[r31] // np[1]
+ xma.lu alo[3]=alo[3],bi,ahi[2]
+ mov pr.rot=0x20101f<<16
+ // ------^----- (p40) at first (p23)
+ // --------^--- (p30) at first (p22)
+ // ----------^^ p[16:20]=1
+ };;
+{ .mfi; st8 [tptr]=r0 // tp[0] is already accounted
+ xmpy.lu m0=alo[4],n0 // (ap[0]*bp[i]+tp[0])*n0
+ mov ar.lc=lc }
+{ .mfi;
+ fcvt.fxu.s1 nhi[1]=f0
+ mov ar.ec=8 };;
+
+// This loop spins in 4*(n+7) ticks on Itanium 2 and should spin in
+// 7*(n+7) ticks on Itanium (the one codenamed Merced). Factor of 7
+// in latter case accounts for two-tick pipeline stall, which means
+// that its performance would be ~20% lower than optimal one. No
+// attempt was made to address this, because original Itanium is
+// hardly represented out in the wild...
+.align 32
+.Linner_ctop:
+.pred.rel "mutex",p40,p42
+.pred.rel "mutex",p30,p32
+{ .mfi; (p16) ldf8 alo[0]=[aptr],8 // *(aptr++)
+ (p18) xma.hu ahi[0]=alo[2],bi,ahi[1]
+ (p40) add n[2]=n[2],a[2] } // (p23)
+{ .mfi; (p16) nop.m 0
+ (p18) xma.lu alo[2]=alo[2],bi,ahi[1]
+ (p42) add n[2]=n[2],a[2],1 };; // (p23)
+{ .mfi; (p21) getf.sig a[0]=alo[5]
+ (p16) nop.f 0
+ (p40) cmp.ltu p41,p39=n[2],a[2] } // (p23)
+{ .mfi; (p21) ld8 t[0]=[tptr],8
+ (p16) nop.f 0
+ (p42) cmp.leu p41,p39=n[2],a[2] };; // (p23)
+{ .mfi; (p18) ldf8 nlo[0]=[nptr],8 // *(nptr++)
+ (p20) xma.hu nhi[0]=nlo[2],m0,nhi[1]
+ (p30) add a[1]=a[1],t[1] } // (p22)
+{ .mfi; (p16) nop.m 0
+ (p20) xma.lu nlo[2]=nlo[2],m0,nhi[1]
+ (p32) add a[1]=a[1],t[1],1 };; // (p22)
+{ .mmi; (p21) getf.sig n[0]=nlo[3]
+ (p16) nop.m 0
+ (p30) cmp.ltu p31,p29=a[1],t[1] } // (p22)
+{ .mmb; (p23) st8 [tp_1]=n[2],8
+ (p32) cmp.leu p31,p29=a[1],t[1] // (p22)
+ br.ctop.sptk .Linner_ctop };;
+.Linner_cend:
+
+{ .mmi; getf.sig a[0]=ahi[6] // (p24)
+ getf.sig n[0]=nhi[4]
+ nop.i 0 };;
+
+{ .mmi; .pred.rel "mutex",p31,p33
+(p31) add a[0]=a[0],topbit
+(p33) add a[0]=a[0],topbit,1
+ mov topbit=r0 };;
+{ .mfi; .pred.rel "mutex",p31,p33
+(p31) cmp.ltu p32,p30=a[0],topbit
+(p33) cmp.leu p32,p30=a[0],topbit
+ }
+{ .mfi; .pred.rel "mutex",p40,p42
+(p40) add n[0]=n[0],a[0]
+(p42) add n[0]=n[0],a[0],1
+ };;
+{ .mmi; .pred.rel "mutex",p44,p46
+(p40) cmp.ltu p41,p39=n[0],a[0]
+(p42) cmp.leu p41,p39=n[0],a[0]
+(p32) add topbit=r0,r0,1 }
+
+{ .mmi; st8 [tp_1]=n[0],8
+ cmp4.ne p6,p0=1,num
+ sub aptr=aptr,len };; // rewind
+{ .mmi; sub nptr=nptr,len
+(p41) add topbit=r0,r0,1
+ add tptr=16,sp }
+{ .mmb; add tp_1=8,sp
+ add num=-1,num // num--
+(p6) br.cond.sptk.many .Louter };;
+
+{ .mbb; add lc=4,lc
+ brp.loop.imp .Lsub_ctop,.Lsub_cend-16
+ clrrrb.pr };;
+{ .mii; nop.m 0
+ mov pr.rot=0x10001<<16
+ // ------^---- (p33) at first (p17)
+ mov ar.lc=lc }
+{ .mii; nop.m 0
+ mov ar.ec=3
+ nop.i 0 };;
+
+.Lsub_ctop:
+.pred.rel "mutex",p33,p35
+{ .mfi; (p16) ld8 t[0]=[tptr],8 // t=*(tp++)
+ (p16) nop.f 0
+ (p33) sub n[1]=t[1],n[1] } // (p17)
+{ .mfi; (p16) ld8 n[0]=[nptr],8 // n=*(np++)
+ (p16) nop.f 0
+ (p35) sub n[1]=t[1],n[1],1 };; // (p17)
+{ .mib; (p18) st8 [rptr]=n[2],8 // *(rp++)=r
+ (p33) cmp.gtu p34,p32=n[1],t[1] // (p17)
+ (p18) nop.b 0 }
+{ .mib; (p18) nop.m 0
+ (p35) cmp.geu p34,p32=n[1],t[1] // (p17)
+ br.ctop.sptk .Lsub_ctop };;
+.Lsub_cend:
+
+{ .mmb; .pred.rel "mutex",p34,p36
+(p34) sub topbit=topbit,r0 // (p19)
+(p36) sub topbit=topbit,r0,1
+ brp.loop.imp .Lcopy_ctop,.Lcopy_cend-16
+ }
+{ .mmb; sub rptr=rptr,len // rewind
+ sub tptr=tptr,len
+ clrrrb.pr };;
+{ .mmi; and aptr=tptr,topbit
+ andcm bptr=rptr,topbit
+ mov pr.rot=1<<16 };;
+{ .mii; or nptr=aptr,bptr
+ mov ar.lc=lc
+ mov ar.ec=3 };;
+
+.Lcopy_ctop:
+{ .mmb; (p16) ld8 n[0]=[nptr],8
+ (p18) st8 [tptr]=r0,8
+ (p16) nop.b 0 }
+{ .mmb; (p16) nop.m 0
+ (p18) st8 [rptr]=n[2],8
+ br.ctop.sptk .Lcopy_ctop };;
+.Lcopy_cend:
+
+{ .mmi; mov ret0=1 // signal "handled"
+ rum 1<<5 // clear um.mfh
+ mov ar.lc=prevlc }
+{ .mib; .restore sp
+ mov sp=prevsp
+ mov pr=prevpr,0x1ffff
+ br.ret.sptk.many b0 };;
+.endp bn_mul_mont_general#
+
+a1=r16; a2=r17; a3=r18; a4=r19; a5=r20; a6=r21; a7=r22; a8=r23;
+n1=r24; n2=r25; n3=r26; n4=r27; n5=r28; n6=r29; n7=r30; n8=r31;
+t0=r15;
+
+ai0=f8; ai1=f9; ai2=f10; ai3=f11; ai4=f12; ai5=f13; ai6=f14; ai7=f15;
+ni0=f16; ni1=f17; ni2=f18; ni3=f19; ni4=f20; ni5=f21; ni6=f22; ni7=f23;
+
+.align 64
+.skip 48 // aligns loop body
+.local bn_mul_mont_8#
+.proc bn_mul_mont_8#
+bn_mul_mont_8:
+ .prologue
+{ .mmi; .save ar.pfs,prevfs
+ alloc prevfs=ar.pfs,6,2,0,8
+ .vframe prevsp
+ mov prevsp=sp
+ .save ar.lc,prevlc
+ mov prevlc=ar.lc }
+{ .mmi; add r17=-6*16,sp
+ add sp=-7*16,sp
+ .save pr,prevpr
+ mov prevpr=pr };;
+
+{ .mmi; .save.gf 0,0x10
+ stf.spill [sp]=f16,-16
+ .save.gf 0,0x20
+ stf.spill [r17]=f17,32
+ add r16=-5*16,prevsp};;
+{ .mmi; .save.gf 0,0x40
+ stf.spill [r16]=f18,32
+ .save.gf 0,0x80
+ stf.spill [r17]=f19,32
+ $ADDP aptr=0,in1 };;
+{ .mmi; .save.gf 0,0x100
+ stf.spill [r16]=f20,32
+ .save.gf 0,0x200
+ stf.spill [r17]=f21,32
+ $ADDP r29=8,in1 };;
+{ .mmi; .save.gf 0,0x400
+ stf.spill [r16]=f22
+ .save.gf 0,0x800
+ stf.spill [r17]=f23
+ $ADDP rptr=0,in0 };;
+
+ .body
+ .rotf bj[8],mj[2],tf[2],alo[10],ahi[10],nlo[10],nhi[10]
+ .rotr t[8]
+
+// load input vectors padding them to 8 elements
+{ .mmi; ldf8 ai0=[aptr],16 // ap[0]
+ ldf8 ai1=[r29],16 // ap[1]
+ $ADDP bptr=0,in2 }
+{ .mmi; $ADDP r30=8,in2
+ $ADDP nptr=0,in3
+ $ADDP r31=8,in3 };;
+{ .mmi; ldf8 bj[7]=[bptr],16 // bp[0]
+ ldf8 bj[6]=[r30],16 // bp[1]
+ cmp4.le p4,p5=3,in5 }
+{ .mmi; ldf8 ni0=[nptr],16 // np[0]
+ ldf8 ni1=[r31],16 // np[1]
+ cmp4.le p6,p7=4,in5 };;
+
+{ .mfi; (p4)ldf8 ai2=[aptr],16 // ap[2]
+ (p5)fcvt.fxu ai2=f0
+ cmp4.le p8,p9=5,in5 }
+{ .mfi; (p6)ldf8 ai3=[r29],16 // ap[3]
+ (p7)fcvt.fxu ai3=f0
+ cmp4.le p10,p11=6,in5 }
+{ .mfi; (p4)ldf8 bj[5]=[bptr],16 // bp[2]
+ (p5)fcvt.fxu bj[5]=f0
+ cmp4.le p12,p13=7,in5 }
+{ .mfi; (p6)ldf8 bj[4]=[r30],16 // bp[3]
+ (p7)fcvt.fxu bj[4]=f0
+ cmp4.le p14,p15=8,in5 }
+{ .mfi; (p4)ldf8 ni2=[nptr],16 // np[2]
+ (p5)fcvt.fxu ni2=f0
+ addp4 r28=-1,in5 }
+{ .mfi; (p6)ldf8 ni3=[r31],16 // np[3]
+ (p7)fcvt.fxu ni3=f0
+ $ADDP in4=0,in4 };;
+
+{ .mfi; ldf8 n0=[in4]
+ fcvt.fxu tf[1]=f0
+ nop.i 0 }
+
+{ .mfi; (p8)ldf8 ai4=[aptr],16 // ap[4]
+ (p9)fcvt.fxu ai4=f0
+ mov t[0]=r0 }
+{ .mfi; (p10)ldf8 ai5=[r29],16 // ap[5]
+ (p11)fcvt.fxu ai5=f0
+ mov t[1]=r0 }
+{ .mfi; (p8)ldf8 bj[3]=[bptr],16 // bp[4]
+ (p9)fcvt.fxu bj[3]=f0
+ mov t[2]=r0 }
+{ .mfi; (p10)ldf8 bj[2]=[r30],16 // bp[5]
+ (p11)fcvt.fxu bj[2]=f0
+ mov t[3]=r0 }
+{ .mfi; (p8)ldf8 ni4=[nptr],16 // np[4]
+ (p9)fcvt.fxu ni4=f0
+ mov t[4]=r0 }
+{ .mfi; (p10)ldf8 ni5=[r31],16 // np[5]
+ (p11)fcvt.fxu ni5=f0
+ mov t[5]=r0 };;
+
+{ .mfi; (p12)ldf8 ai6=[aptr],16 // ap[6]
+ (p13)fcvt.fxu ai6=f0
+ mov t[6]=r0 }
+{ .mfi; (p14)ldf8 ai7=[r29],16 // ap[7]
+ (p15)fcvt.fxu ai7=f0
+ mov t[7]=r0 }
+{ .mfi; (p12)ldf8 bj[1]=[bptr],16 // bp[6]
+ (p13)fcvt.fxu bj[1]=f0
+ mov ar.lc=r28 }
+{ .mfi; (p14)ldf8 bj[0]=[r30],16 // bp[7]
+ (p15)fcvt.fxu bj[0]=f0
+ mov ar.ec=1 }
+{ .mfi; (p12)ldf8 ni6=[nptr],16 // np[6]
+ (p13)fcvt.fxu ni6=f0
+ mov pr.rot=1<<16 }
+{ .mfb; (p14)ldf8 ni7=[r31],16 // np[7]
+ (p15)fcvt.fxu ni7=f0
+ brp.loop.imp .Louter_8_ctop,.Louter_8_cend-16
+ };;
+
+// The loop is scheduled for 32*n ticks on Itanium 2. Actual attempt
+// to measure with help of Interval Time Counter indicated that the
+// factor is a tad higher: 33 or 34, if not 35. Exact measurement and
+// addressing the issue is problematic, because I don't have access
+// to platform-specific instruction-level profiler. On Itanium it
+// should run in 56*n ticks, because of higher xma latency...
+.Louter_8_ctop:
+ .pred.rel "mutex",p40,p42
+ .pred.rel "mutex",p48,p50
+{ .mfi; (p16) nop.m 0 // 0:
+ (p16) xma.hu ahi[0]=ai0,bj[7],tf[1] // ap[0]*b[i]+t[0]
+ (p40) add a3=a3,n3 } // (p17) a3+=n3
+{ .mfi; (p42) add a3=a3,n3,1
+ (p16) xma.lu alo[0]=ai0,bj[7],tf[1]
+ (p16) nop.i 0 };;
+{ .mii; (p17) getf.sig a7=alo[8] // 1:
+ (p48) add t[6]=t[6],a3 // (p17) t[6]+=a3
+ (p50) add t[6]=t[6],a3,1 };;
+{ .mfi; (p17) getf.sig a8=ahi[8] // 2:
+ (p17) xma.hu nhi[7]=ni6,mj[1],nhi[6] // np[6]*m0
+ (p40) cmp.ltu p43,p41=a3,n3 }
+{ .mfi; (p42) cmp.leu p43,p41=a3,n3
+ (p17) xma.lu nlo[7]=ni6,mj[1],nhi[6]
+ (p16) nop.i 0 };;
+{ .mii; (p17) getf.sig n5=nlo[6] // 3:
+ (p48) cmp.ltu p51,p49=t[6],a3
+ (p50) cmp.leu p51,p49=t[6],a3 };;
+ .pred.rel "mutex",p41,p43
+ .pred.rel "mutex",p49,p51
+{ .mfi; (p16) nop.m 0 // 4:
+ (p16) xma.hu ahi[1]=ai1,bj[7],ahi[0] // ap[1]*b[i]
+ (p41) add a4=a4,n4 } // (p17) a4+=n4
+{ .mfi; (p43) add a4=a4,n4,1
+ (p16) xma.lu alo[1]=ai1,bj[7],ahi[0]
+ (p16) nop.i 0 };;
+{ .mfi; (p49) add t[5]=t[5],a4 // 5: (p17) t[5]+=a4
+ (p16) xmpy.lu mj[0]=alo[0],n0 // (ap[0]*b[i]+t[0])*n0
+ (p51) add t[5]=t[5],a4,1 };;
+{ .mfi; (p16) nop.m 0 // 6:
+ (p17) xma.hu nhi[8]=ni7,mj[1],nhi[7] // np[7]*m0
+ (p41) cmp.ltu p42,p40=a4,n4 }
+{ .mfi; (p43) cmp.leu p42,p40=a4,n4
+ (p17) xma.lu nlo[8]=ni7,mj[1],nhi[7]
+ (p16) nop.i 0 };;
+{ .mii; (p17) getf.sig n6=nlo[7] // 7:
+ (p49) cmp.ltu p50,p48=t[5],a4
+ (p51) cmp.leu p50,p48=t[5],a4 };;
+ .pred.rel "mutex",p40,p42
+ .pred.rel "mutex",p48,p50
+{ .mfi; (p16) nop.m 0 // 8:
+ (p16) xma.hu ahi[2]=ai2,bj[7],ahi[1] // ap[2]*b[i]
+ (p40) add a5=a5,n5 } // (p17) a5+=n5
+{ .mfi; (p42) add a5=a5,n5,1
+ (p16) xma.lu alo[2]=ai2,bj[7],ahi[1]
+ (p16) nop.i 0 };;
+{ .mii; (p16) getf.sig a1=alo[1] // 9:
+ (p48) add t[4]=t[4],a5 // p(17) t[4]+=a5
+ (p50) add t[4]=t[4],a5,1 };;
+{ .mfi; (p16) nop.m 0 // 10:
+ (p16) xma.hu nhi[0]=ni0,mj[0],alo[0] // np[0]*m0
+ (p40) cmp.ltu p43,p41=a5,n5 }
+{ .mfi; (p42) cmp.leu p43,p41=a5,n5
+ (p16) xma.lu nlo[0]=ni0,mj[0],alo[0]
+ (p16) nop.i 0 };;
+{ .mii; (p17) getf.sig n7=nlo[8] // 11:
+ (p48) cmp.ltu p51,p49=t[4],a5
+ (p50) cmp.leu p51,p49=t[4],a5 };;
+ .pred.rel "mutex",p41,p43
+ .pred.rel "mutex",p49,p51
+{ .mfi; (p17) getf.sig n8=nhi[8] // 12:
+ (p16) xma.hu ahi[3]=ai3,bj[7],ahi[2] // ap[3]*b[i]
+ (p41) add a6=a6,n6 } // (p17) a6+=n6
+{ .mfi; (p43) add a6=a6,n6,1
+ (p16) xma.lu alo[3]=ai3,bj[7],ahi[2]
+ (p16) nop.i 0 };;
+{ .mii; (p16) getf.sig a2=alo[2] // 13:
+ (p49) add t[3]=t[3],a6 // (p17) t[3]+=a6
+ (p51) add t[3]=t[3],a6,1 };;
+{ .mfi; (p16) nop.m 0 // 14:
+ (p16) xma.hu nhi[1]=ni1,mj[0],nhi[0] // np[1]*m0
+ (p41) cmp.ltu p42,p40=a6,n6 }
+{ .mfi; (p43) cmp.leu p42,p40=a6,n6
+ (p16) xma.lu nlo[1]=ni1,mj[0],nhi[0]
+ (p16) nop.i 0 };;
+{ .mii; (p16) nop.m 0 // 15:
+ (p49) cmp.ltu p50,p48=t[3],a6
+ (p51) cmp.leu p50,p48=t[3],a6 };;
+ .pred.rel "mutex",p40,p42
+ .pred.rel "mutex",p48,p50
+{ .mfi; (p16) nop.m 0 // 16:
+ (p16) xma.hu ahi[4]=ai4,bj[7],ahi[3] // ap[4]*b[i]
+ (p40) add a7=a7,n7 } // (p17) a7+=n7
+{ .mfi; (p42) add a7=a7,n7,1
+ (p16) xma.lu alo[4]=ai4,bj[7],ahi[3]
+ (p16) nop.i 0 };;
+{ .mii; (p16) getf.sig a3=alo[3] // 17:
+ (p48) add t[2]=t[2],a7 // (p17) t[2]+=a7
+ (p50) add t[2]=t[2],a7,1 };;
+{ .mfi; (p16) nop.m 0 // 18:
+ (p16) xma.hu nhi[2]=ni2,mj[0],nhi[1] // np[2]*m0
+ (p40) cmp.ltu p43,p41=a7,n7 }
+{ .mfi; (p42) cmp.leu p43,p41=a7,n7
+ (p16) xma.lu nlo[2]=ni2,mj[0],nhi[1]
+ (p16) nop.i 0 };;
+{ .mii; (p16) getf.sig n1=nlo[1] // 19:
+ (p48) cmp.ltu p51,p49=t[2],a7
+ (p50) cmp.leu p51,p49=t[2],a7 };;
+ .pred.rel "mutex",p41,p43
+ .pred.rel "mutex",p49,p51
+{ .mfi; (p16) nop.m 0 // 20:
+ (p16) xma.hu ahi[5]=ai5,bj[7],ahi[4] // ap[5]*b[i]
+ (p41) add a8=a8,n8 } // (p17) a8+=n8
+{ .mfi; (p43) add a8=a8,n8,1
+ (p16) xma.lu alo[5]=ai5,bj[7],ahi[4]
+ (p16) nop.i 0 };;
+{ .mii; (p16) getf.sig a4=alo[4] // 21:
+ (p49) add t[1]=t[1],a8 // (p17) t[1]+=a8
+ (p51) add t[1]=t[1],a8,1 };;
+{ .mfi; (p16) nop.m 0 // 22:
+ (p16) xma.hu nhi[3]=ni3,mj[0],nhi[2] // np[3]*m0
+ (p41) cmp.ltu p42,p40=a8,n8 }
+{ .mfi; (p43) cmp.leu p42,p40=a8,n8
+ (p16) xma.lu nlo[3]=ni3,mj[0],nhi[2]
+ (p16) nop.i 0 };;
+{ .mii; (p16) getf.sig n2=nlo[2] // 23:
+ (p49) cmp.ltu p50,p48=t[1],a8
+ (p51) cmp.leu p50,p48=t[1],a8 };;
+{ .mfi; (p16) nop.m 0 // 24:
+ (p16) xma.hu ahi[6]=ai6,bj[7],ahi[5] // ap[6]*b[i]
+ (p16) add a1=a1,n1 } // (p16) a1+=n1
+{ .mfi; (p16) nop.m 0
+ (p16) xma.lu alo[6]=ai6,bj[7],ahi[5]
+ (p17) mov t[0]=r0 };;
+{ .mii; (p16) getf.sig a5=alo[5] // 25:
+ (p16) add t0=t[7],a1 // (p16) t[7]+=a1
+ (p42) add t[0]=t[0],r0,1 };;
+{ .mfi; (p16) setf.sig tf[0]=t0 // 26:
+ (p16) xma.hu nhi[4]=ni4,mj[0],nhi[3] // np[4]*m0
+ (p50) add t[0]=t[0],r0,1 }
+{ .mfi; (p16) cmp.ltu.unc p42,p40=a1,n1
+ (p16) xma.lu nlo[4]=ni4,mj[0],nhi[3]
+ (p16) nop.i 0 };;
+{ .mii; (p16) getf.sig n3=nlo[3] // 27:
+ (p16) cmp.ltu.unc p50,p48=t0,a1
+ (p16) nop.i 0 };;
+ .pred.rel "mutex",p40,p42
+ .pred.rel "mutex",p48,p50
+{ .mfi; (p16) nop.m 0 // 28:
+ (p16) xma.hu ahi[7]=ai7,bj[7],ahi[6] // ap[7]*b[i]
+ (p40) add a2=a2,n2 } // (p16) a2+=n2
+{ .mfi; (p42) add a2=a2,n2,1
+ (p16) xma.lu alo[7]=ai7,bj[7],ahi[6]
+ (p16) nop.i 0 };;
+{ .mii; (p16) getf.sig a6=alo[6] // 29:
+ (p48) add t[6]=t[6],a2 // (p16) t[6]+=a2
+ (p50) add t[6]=t[6],a2,1 };;
+{ .mfi; (p16) nop.m 0 // 30:
+ (p16) xma.hu nhi[5]=ni5,mj[0],nhi[4] // np[5]*m0
+ (p40) cmp.ltu p41,p39=a2,n2 }
+{ .mfi; (p42) cmp.leu p41,p39=a2,n2
+ (p16) xma.lu nlo[5]=ni5,mj[0],nhi[4]
+ (p16) nop.i 0 };;
+{ .mfi; (p16) getf.sig n4=nlo[4] // 31:
+ (p16) nop.f 0
+ (p48) cmp.ltu p49,p47=t[6],a2 }
+{ .mfb; (p50) cmp.leu p49,p47=t[6],a2
+ (p16) nop.f 0
+ br.ctop.sptk.many .Louter_8_ctop };;
+.Louter_8_cend:
+
+// above loop has to execute one more time, without (p16), which is
+// replaced with merged move of np[8] to GPR bank
+ .pred.rel "mutex",p40,p42
+ .pred.rel "mutex",p48,p50
+{ .mmi; (p0) getf.sig n1=ni0 // 0:
+ (p40) add a3=a3,n3 // (p17) a3+=n3
+ (p42) add a3=a3,n3,1 };;
+{ .mii; (p17) getf.sig a7=alo[8] // 1:
+ (p48) add t[6]=t[6],a3 // (p17) t[6]+=a3
+ (p50) add t[6]=t[6],a3,1 };;
+{ .mfi; (p17) getf.sig a8=ahi[8] // 2:
+ (p17) xma.hu nhi[7]=ni6,mj[1],nhi[6] // np[6]*m0
+ (p40) cmp.ltu p43,p41=a3,n3 }
+{ .mfi; (p42) cmp.leu p43,p41=a3,n3
+ (p17) xma.lu nlo[7]=ni6,mj[1],nhi[6]
+ (p0) nop.i 0 };;
+{ .mii; (p17) getf.sig n5=nlo[6] // 3:
+ (p48) cmp.ltu p51,p49=t[6],a3
+ (p50) cmp.leu p51,p49=t[6],a3 };;
+ .pred.rel "mutex",p41,p43
+ .pred.rel "mutex",p49,p51
+{ .mmi; (p0) getf.sig n2=ni1 // 4:
+ (p41) add a4=a4,n4 // (p17) a4+=n4
+ (p43) add a4=a4,n4,1 };;
+{ .mfi; (p49) add t[5]=t[5],a4 // 5: (p17) t[5]+=a4
+ (p0) nop.f 0
+ (p51) add t[5]=t[5],a4,1 };;
+{ .mfi; (p0) getf.sig n3=ni2 // 6:
+ (p17) xma.hu nhi[8]=ni7,mj[1],nhi[7] // np[7]*m0
+ (p41) cmp.ltu p42,p40=a4,n4 }
+{ .mfi; (p43) cmp.leu p42,p40=a4,n4
+ (p17) xma.lu nlo[8]=ni7,mj[1],nhi[7]
+ (p0) nop.i 0 };;
+{ .mii; (p17) getf.sig n6=nlo[7] // 7:
+ (p49) cmp.ltu p50,p48=t[5],a4
+ (p51) cmp.leu p50,p48=t[5],a4 };;
+ .pred.rel "mutex",p40,p42
+ .pred.rel "mutex",p48,p50
+{ .mii; (p0) getf.sig n4=ni3 // 8:
+ (p40) add a5=a5,n5 // (p17) a5+=n5
+ (p42) add a5=a5,n5,1 };;
+{ .mii; (p0) nop.m 0 // 9:
+ (p48) add t[4]=t[4],a5 // p(17) t[4]+=a5
+ (p50) add t[4]=t[4],a5,1 };;
+{ .mii; (p0) nop.m 0 // 10:
+ (p40) cmp.ltu p43,p41=a5,n5
+ (p42) cmp.leu p43,p41=a5,n5 };;
+{ .mii; (p17) getf.sig n7=nlo[8] // 11:
+ (p48) cmp.ltu p51,p49=t[4],a5
+ (p50) cmp.leu p51,p49=t[4],a5 };;
+ .pred.rel "mutex",p41,p43
+ .pred.rel "mutex",p49,p51
+{ .mii; (p17) getf.sig n8=nhi[8] // 12:
+ (p41) add a6=a6,n6 // (p17) a6+=n6
+ (p43) add a6=a6,n6,1 };;
+{ .mii; (p0) getf.sig n5=ni4 // 13:
+ (p49) add t[3]=t[3],a6 // (p17) t[3]+=a6
+ (p51) add t[3]=t[3],a6,1 };;
+{ .mii; (p0) nop.m 0 // 14:
+ (p41) cmp.ltu p42,p40=a6,n6
+ (p43) cmp.leu p42,p40=a6,n6 };;
+{ .mii; (p0) getf.sig n6=ni5 // 15:
+ (p49) cmp.ltu p50,p48=t[3],a6
+ (p51) cmp.leu p50,p48=t[3],a6 };;
+ .pred.rel "mutex",p40,p42
+ .pred.rel "mutex",p48,p50
+{ .mii; (p0) nop.m 0 // 16:
+ (p40) add a7=a7,n7 // (p17) a7+=n7
+ (p42) add a7=a7,n7,1 };;
+{ .mii; (p0) nop.m 0 // 17:
+ (p48) add t[2]=t[2],a7 // (p17) t[2]+=a7
+ (p50) add t[2]=t[2],a7,1 };;
+{ .mii; (p0) nop.m 0 // 18:
+ (p40) cmp.ltu p43,p41=a7,n7
+ (p42) cmp.leu p43,p41=a7,n7 };;
+{ .mii; (p0) getf.sig n7=ni6 // 19:
+ (p48) cmp.ltu p51,p49=t[2],a7
+ (p50) cmp.leu p51,p49=t[2],a7 };;
+ .pred.rel "mutex",p41,p43
+ .pred.rel "mutex",p49,p51
+{ .mii; (p0) nop.m 0 // 20:
+ (p41) add a8=a8,n8 // (p17) a8+=n8
+ (p43) add a8=a8,n8,1 };;
+{ .mmi; (p0) nop.m 0 // 21:
+ (p49) add t[1]=t[1],a8 // (p17) t[1]+=a8
+ (p51) add t[1]=t[1],a8,1 }
+{ .mmi; (p17) mov t[0]=r0
+ (p41) cmp.ltu p42,p40=a8,n8
+ (p43) cmp.leu p42,p40=a8,n8 };;
+{ .mmi; (p0) getf.sig n8=ni7 // 22:
+ (p49) cmp.ltu p50,p48=t[1],a8
+ (p51) cmp.leu p50,p48=t[1],a8 }
+{ .mmi; (p42) add t[0]=t[0],r0,1
+ (p0) add r16=-7*16,prevsp
+ (p0) add r17=-6*16,prevsp };;
+
+// subtract np[8] from carrybit|tmp[8]
+// carrybit|tmp[8] layout upon exit from above loop is:
+// t[0]|t[1]|t[2]|t[3]|t[4]|t[5]|t[6]|t[7]|t0 (least significant)
+{ .mmi; (p50)add t[0]=t[0],r0,1
+ add r18=-5*16,prevsp
+ sub n1=t0,n1 };;
+{ .mmi; cmp.gtu p34,p32=n1,t0;;
+ .pred.rel "mutex",p32,p34
+ (p32)sub n2=t[7],n2
+ (p34)sub n2=t[7],n2,1 };;
+{ .mii; (p32)cmp.gtu p35,p33=n2,t[7]
+ (p34)cmp.geu p35,p33=n2,t[7];;
+ .pred.rel "mutex",p33,p35
+ (p33)sub n3=t[6],n3 }
+{ .mmi; (p35)sub n3=t[6],n3,1;;
+ (p33)cmp.gtu p34,p32=n3,t[6]
+ (p35)cmp.geu p34,p32=n3,t[6] };;
+ .pred.rel "mutex",p32,p34
+{ .mii; (p32)sub n4=t[5],n4
+ (p34)sub n4=t[5],n4,1;;
+ (p32)cmp.gtu p35,p33=n4,t[5] }
+{ .mmi; (p34)cmp.geu p35,p33=n4,t[5];;
+ .pred.rel "mutex",p33,p35
+ (p33)sub n5=t[4],n5
+ (p35)sub n5=t[4],n5,1 };;
+{ .mii; (p33)cmp.gtu p34,p32=n5,t[4]
+ (p35)cmp.geu p34,p32=n5,t[4];;
+ .pred.rel "mutex",p32,p34
+ (p32)sub n6=t[3],n6 }
+{ .mmi; (p34)sub n6=t[3],n6,1;;
+ (p32)cmp.gtu p35,p33=n6,t[3]
+ (p34)cmp.geu p35,p33=n6,t[3] };;
+ .pred.rel "mutex",p33,p35
+{ .mii; (p33)sub n7=t[2],n7
+ (p35)sub n7=t[2],n7,1;;
+ (p33)cmp.gtu p34,p32=n7,t[2] }
+{ .mmi; (p35)cmp.geu p34,p32=n7,t[2];;
+ .pred.rel "mutex",p32,p34
+ (p32)sub n8=t[1],n8
+ (p34)sub n8=t[1],n8,1 };;
+{ .mii; (p32)cmp.gtu p35,p33=n8,t[1]
+ (p34)cmp.geu p35,p33=n8,t[1];;
+ .pred.rel "mutex",p33,p35
+ (p33)sub a8=t[0],r0 }
+{ .mmi; (p35)sub a8=t[0],r0,1;;
+ (p33)cmp.gtu p34,p32=a8,t[0]
+ (p35)cmp.geu p34,p32=a8,t[0] };;
+
+// save the result, either tmp[num] or tmp[num]-np[num]
+ .pred.rel "mutex",p32,p34
+{ .mmi; (p32)st8 [rptr]=n1,8
+ (p34)st8 [rptr]=t0,8
+ add r19=-4*16,prevsp};;
+{ .mmb; (p32)st8 [rptr]=n2,8
+ (p34)st8 [rptr]=t[7],8
+ (p5)br.cond.dpnt.few .Ldone };;
+{ .mmb; (p32)st8 [rptr]=n3,8
+ (p34)st8 [rptr]=t[6],8
+ (p7)br.cond.dpnt.few .Ldone };;
+{ .mmb; (p32)st8 [rptr]=n4,8
+ (p34)st8 [rptr]=t[5],8
+ (p9)br.cond.dpnt.few .Ldone };;
+{ .mmb; (p32)st8 [rptr]=n5,8
+ (p34)st8 [rptr]=t[4],8
+ (p11)br.cond.dpnt.few .Ldone };;
+{ .mmb; (p32)st8 [rptr]=n6,8
+ (p34)st8 [rptr]=t[3],8
+ (p13)br.cond.dpnt.few .Ldone };;
+{ .mmb; (p32)st8 [rptr]=n7,8
+ (p34)st8 [rptr]=t[2],8
+ (p15)br.cond.dpnt.few .Ldone };;
+{ .mmb; (p32)st8 [rptr]=n8,8
+ (p34)st8 [rptr]=t[1],8
+ nop.b 0 };;
+.Ldone: // epilogue
+{ .mmi; ldf.fill f16=[r16],64
+ ldf.fill f17=[r17],64
+ nop.i 0 }
+{ .mmi; ldf.fill f18=[r18],64
+ ldf.fill f19=[r19],64
+ mov pr=prevpr,0x1ffff };;
+{ .mmi; ldf.fill f20=[r16]
+ ldf.fill f21=[r17]
+ mov ar.lc=prevlc }
+{ .mmi; ldf.fill f22=[r18]
+ ldf.fill f23=[r19]
+ mov ret0=1 } // signal "handled"
+{ .mib; rum 1<<5
+ .restore sp
+ mov sp=prevsp
+ br.ret.sptk.many b0 };;
+.endp bn_mul_mont_8#
+
+.type copyright#,\@object
+copyright:
+stringz "Montgomery multiplication for IA-64, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$output=shift and open STDOUT,">$output";
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/bn/asm/mips-mont.pl b/deps/openssl/openssl/crypto/bn/asm/mips-mont.pl
new file mode 100644
index 000000000..b944a12b8
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/asm/mips-mont.pl
@@ -0,0 +1,426 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# This module doesn't present direct interest for OpenSSL, because it
+# doesn't provide better performance for longer keys, at least not on
+# in-order-execution cores. While 512-bit RSA sign operations can be
+# 65% faster in 64-bit mode, 1024-bit ones are only 15% faster, and
+# 4096-bit ones are up to 15% slower. In 32-bit mode it varies from
+# 16% improvement for 512-bit RSA sign to -33% for 4096-bit RSA
+# verify:-( All comparisons are against bn_mul_mont-free assembler.
+# The module might be of interest to embedded system developers, as
+# the code is smaller than 1KB, yet offers >3x improvement on MIPS64
+# and 75-30% [less for longer keys] on MIPS32 over compiler-generated
+# code.
+
+######################################################################
+# There is a number of MIPS ABI in use, O32 and N32/64 are most
+# widely used. Then there is a new contender: NUBI. It appears that if
+# one picks the latter, it's possible to arrange code in ABI neutral
+# manner. Therefore let's stick to NUBI register layout:
+#
+($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
+($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
+#
+# The return value is placed in $a0. Following coding rules facilitate
+# interoperability:
+#
+# - never ever touch $tp, "thread pointer", former $gp;
+# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
+# old code];
+# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
+#
+# For reference here is register layout for N32/64 MIPS ABIs:
+#
+# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
+# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
+# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
+# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
+# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
+#
+$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
+
+if ($flavour =~ /64|n32/i) {
+ $PTR_ADD="dadd"; # incidentally works even on n32
+ $PTR_SUB="dsub"; # incidentally works even on n32
+ $REG_S="sd";
+ $REG_L="ld";
+ $SZREG=8;
+} else {
+ $PTR_ADD="add";
+ $PTR_SUB="sub";
+ $REG_S="sw";
+ $REG_L="lw";
+ $SZREG=4;
+}
+$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0x00fff000 : 0x00ff0000;
+#
+# <appro@openssl.org>
+#
+######################################################################
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+if ($flavour =~ /64|n32/i) {
+ $LD="ld";
+ $ST="sd";
+ $MULTU="dmultu";
+ $ADDU="daddu";
+ $SUBU="dsubu";
+ $BNSZ=8;
+} else {
+ $LD="lw";
+ $ST="sw";
+ $MULTU="multu";
+ $ADDU="addu";
+ $SUBU="subu";
+ $BNSZ=4;
+}
+
+# int bn_mul_mont(
+$rp=$a0; # BN_ULONG *rp,
+$ap=$a1; # const BN_ULONG *ap,
+$bp=$a2; # const BN_ULONG *bp,
+$np=$a3; # const BN_ULONG *np,
+$n0=$a4; # const BN_ULONG *n0,
+$num=$a5; # int num);
+
+$lo0=$a6;
+$hi0=$a7;
+$lo1=$t1;
+$hi1=$t2;
+$aj=$s0;
+$bi=$s1;
+$nj=$s2;
+$tp=$s3;
+$alo=$s4;
+$ahi=$s5;
+$nlo=$s6;
+$nhi=$s7;
+$tj=$s8;
+$i=$s9;
+$j=$s10;
+$m1=$s11;
+
+$FRAMESIZE=14;
+
+$code=<<___;
+.text
+
+.set noat
+.set noreorder
+
+.align 5
+.globl bn_mul_mont
+.ent bn_mul_mont
+bn_mul_mont:
+___
+$code.=<<___ if ($flavour =~ /o32/i);
+ lw $n0,16($sp)
+ lw $num,20($sp)
+___
+$code.=<<___;
+ slt $at,$num,4
+ bnez $at,1f
+ li $t0,0
+ slt $at,$num,17 # on in-order CPU
+ bnezl $at,bn_mul_mont_internal
+ nop
+1: jr $ra
+ li $a0,0
+.end bn_mul_mont
+
+.align 5
+.ent bn_mul_mont_internal
+bn_mul_mont_internal:
+ .frame $fp,$FRAMESIZE*$SZREG,$ra
+ .mask 0x40000000|$SAVED_REGS_MASK,-$SZREG
+ $PTR_SUB $sp,$FRAMESIZE*$SZREG
+ $REG_S $fp,($FRAMESIZE-1)*$SZREG($sp)
+ $REG_S $s11,($FRAMESIZE-2)*$SZREG($sp)
+ $REG_S $s10,($FRAMESIZE-3)*$SZREG($sp)
+ $REG_S $s9,($FRAMESIZE-4)*$SZREG($sp)
+ $REG_S $s8,($FRAMESIZE-5)*$SZREG($sp)
+ $REG_S $s7,($FRAMESIZE-6)*$SZREG($sp)
+ $REG_S $s6,($FRAMESIZE-7)*$SZREG($sp)
+ $REG_S $s5,($FRAMESIZE-8)*$SZREG($sp)
+ $REG_S $s4,($FRAMESIZE-9)*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_S $s3,($FRAMESIZE-10)*$SZREG($sp)
+ $REG_S $s2,($FRAMESIZE-11)*$SZREG($sp)
+ $REG_S $s1,($FRAMESIZE-12)*$SZREG($sp)
+ $REG_S $s0,($FRAMESIZE-13)*$SZREG($sp)
+___
+$code.=<<___;
+ move $fp,$sp
+
+ .set reorder
+ $LD $n0,0($n0)
+ $LD $bi,0($bp) # bp[0]
+ $LD $aj,0($ap) # ap[0]
+ $LD $nj,0($np) # np[0]
+
+ $PTR_SUB $sp,2*$BNSZ # place for two extra words
+ sll $num,`log($BNSZ)/log(2)`
+ li $at,-4096
+ $PTR_SUB $sp,$num
+ and $sp,$at
+
+ $MULTU $aj,$bi
+ $LD $alo,$BNSZ($ap)
+ $LD $nlo,$BNSZ($np)
+ mflo $lo0
+ mfhi $hi0
+ $MULTU $lo0,$n0
+ mflo $m1
+
+ $MULTU $alo,$bi
+ mflo $alo
+ mfhi $ahi
+
+ $MULTU $nj,$m1
+ mflo $lo1
+ mfhi $hi1
+ $MULTU $nlo,$m1
+ $ADDU $lo1,$lo0
+ sltu $at,$lo1,$lo0
+ $ADDU $hi1,$at
+ mflo $nlo
+ mfhi $nhi
+
+ move $tp,$sp
+ li $j,2*$BNSZ
+.align 4
+.L1st:
+ .set noreorder
+ $PTR_ADD $aj,$ap,$j
+ $PTR_ADD $nj,$np,$j
+ $LD $aj,($aj)
+ $LD $nj,($nj)
+
+ $MULTU $aj,$bi
+ $ADDU $lo0,$alo,$hi0
+ $ADDU $lo1,$nlo,$hi1
+ sltu $at,$lo0,$hi0
+ sltu $t0,$lo1,$hi1
+ $ADDU $hi0,$ahi,$at
+ $ADDU $hi1,$nhi,$t0
+ mflo $alo
+ mfhi $ahi
+
+ $ADDU $lo1,$lo0
+ sltu $at,$lo1,$lo0
+ $MULTU $nj,$m1
+ $ADDU $hi1,$at
+ addu $j,$BNSZ
+ $ST $lo1,($tp)
+ sltu $t0,$j,$num
+ mflo $nlo
+ mfhi $nhi
+
+ bnez $t0,.L1st
+ $PTR_ADD $tp,$BNSZ
+ .set reorder
+
+ $ADDU $lo0,$alo,$hi0
+ sltu $at,$lo0,$hi0
+ $ADDU $hi0,$ahi,$at
+
+ $ADDU $lo1,$nlo,$hi1
+ sltu $t0,$lo1,$hi1
+ $ADDU $hi1,$nhi,$t0
+ $ADDU $lo1,$lo0
+ sltu $at,$lo1,$lo0
+ $ADDU $hi1,$at
+
+ $ST $lo1,($tp)
+
+ $ADDU $hi1,$hi0
+ sltu $at,$hi1,$hi0
+ $ST $hi1,$BNSZ($tp)
+ $ST $at,2*$BNSZ($tp)
+
+ li $i,$BNSZ
+.align 4
+.Louter:
+ $PTR_ADD $bi,$bp,$i
+ $LD $bi,($bi)
+ $LD $aj,($ap)
+ $LD $alo,$BNSZ($ap)
+ $LD $tj,($sp)
+
+ $MULTU $aj,$bi
+ $LD $nj,($np)
+ $LD $nlo,$BNSZ($np)
+ mflo $lo0
+ mfhi $hi0
+ $ADDU $lo0,$tj
+ $MULTU $lo0,$n0
+ sltu $at,$lo0,$tj
+ $ADDU $hi0,$at
+ mflo $m1
+
+ $MULTU $alo,$bi
+ mflo $alo
+ mfhi $ahi
+
+ $MULTU $nj,$m1
+ mflo $lo1
+ mfhi $hi1
+
+ $MULTU $nlo,$m1
+ $ADDU $lo1,$lo0
+ sltu $at,$lo1,$lo0
+ $ADDU $hi1,$at
+ mflo $nlo
+ mfhi $nhi
+
+ move $tp,$sp
+ li $j,2*$BNSZ
+ $LD $tj,$BNSZ($tp)
+.align 4
+.Linner:
+ .set noreorder
+ $PTR_ADD $aj,$ap,$j
+ $PTR_ADD $nj,$np,$j
+ $LD $aj,($aj)
+ $LD $nj,($nj)
+
+ $MULTU $aj,$bi
+ $ADDU $lo0,$alo,$hi0
+ $ADDU $lo1,$nlo,$hi1
+ sltu $at,$lo0,$hi0
+ sltu $t0,$lo1,$hi1
+ $ADDU $hi0,$ahi,$at
+ $ADDU $hi1,$nhi,$t0
+ mflo $alo
+ mfhi $ahi
+
+ $ADDU $lo0,$tj
+ addu $j,$BNSZ
+ $MULTU $nj,$m1
+ sltu $at,$lo0,$tj
+ $ADDU $lo1,$lo0
+ $ADDU $hi0,$at
+ sltu $t0,$lo1,$lo0
+ $LD $tj,2*$BNSZ($tp)
+ $ADDU $hi1,$t0
+ sltu $at,$j,$num
+ mflo $nlo
+ mfhi $nhi
+ $ST $lo1,($tp)
+ bnez $at,.Linner
+ $PTR_ADD $tp,$BNSZ
+ .set reorder
+
+ $ADDU $lo0,$alo,$hi0
+ sltu $at,$lo0,$hi0
+ $ADDU $hi0,$ahi,$at
+ $ADDU $lo0,$tj
+ sltu $t0,$lo0,$tj
+ $ADDU $hi0,$t0
+
+ $LD $tj,2*$BNSZ($tp)
+ $ADDU $lo1,$nlo,$hi1
+ sltu $at,$lo1,$hi1
+ $ADDU $hi1,$nhi,$at
+ $ADDU $lo1,$lo0
+ sltu $t0,$lo1,$lo0
+ $ADDU $hi1,$t0
+ $ST $lo1,($tp)
+
+ $ADDU $lo1,$hi1,$hi0
+ sltu $hi1,$lo1,$hi0
+ $ADDU $lo1,$tj
+ sltu $at,$lo1,$tj
+ $ADDU $hi1,$at
+ $ST $lo1,$BNSZ($tp)
+ $ST $hi1,2*$BNSZ($tp)
+
+ addu $i,$BNSZ
+ sltu $t0,$i,$num
+ bnez $t0,.Louter
+
+ .set noreorder
+ $PTR_ADD $tj,$sp,$num # &tp[num]
+ move $tp,$sp
+ move $ap,$sp
+ li $hi0,0 # clear borrow bit
+
+.align 4
+.Lsub: $LD $lo0,($tp)
+ $LD $lo1,($np)
+ $PTR_ADD $tp,$BNSZ
+ $PTR_ADD $np,$BNSZ
+ $SUBU $lo1,$lo0,$lo1 # tp[i]-np[i]
+ sgtu $at,$lo1,$lo0
+ $SUBU $lo0,$lo1,$hi0
+ sgtu $hi0,$lo0,$lo1
+ $ST $lo0,($rp)
+ or $hi0,$at
+ sltu $at,$tp,$tj
+ bnez $at,.Lsub
+ $PTR_ADD $rp,$BNSZ
+
+ $SUBU $hi0,$hi1,$hi0 # handle upmost overflow bit
+ move $tp,$sp
+ $PTR_SUB $rp,$num # restore rp
+ not $hi1,$hi0
+
+ and $ap,$hi0,$sp
+ and $bp,$hi1,$rp
+ or $ap,$ap,$bp # ap=borrow?tp:rp
+
+.align 4
+.Lcopy: $LD $aj,($ap)
+ $PTR_ADD $ap,$BNSZ
+ $ST $zero,($tp)
+ $PTR_ADD $tp,$BNSZ
+ sltu $at,$tp,$tj
+ $ST $aj,($rp)
+ bnez $at,.Lcopy
+ $PTR_ADD $rp,$BNSZ
+
+ li $a0,1
+ li $t0,1
+
+ .set noreorder
+ move $sp,$fp
+ $REG_L $fp,($FRAMESIZE-1)*$SZREG($sp)
+ $REG_L $s11,($FRAMESIZE-2)*$SZREG($sp)
+ $REG_L $s10,($FRAMESIZE-3)*$SZREG($sp)
+ $REG_L $s9,($FRAMESIZE-4)*$SZREG($sp)
+ $REG_L $s8,($FRAMESIZE-5)*$SZREG($sp)
+ $REG_L $s7,($FRAMESIZE-6)*$SZREG($sp)
+ $REG_L $s6,($FRAMESIZE-7)*$SZREG($sp)
+ $REG_L $s5,($FRAMESIZE-8)*$SZREG($sp)
+ $REG_L $s4,($FRAMESIZE-9)*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $s3,($FRAMESIZE-10)*$SZREG($sp)
+ $REG_L $s2,($FRAMESIZE-11)*$SZREG($sp)
+ $REG_L $s1,($FRAMESIZE-12)*$SZREG($sp)
+ $REG_L $s0,($FRAMESIZE-13)*$SZREG($sp)
+___
+$code.=<<___;
+ jr $ra
+ $PTR_ADD $sp,$FRAMESIZE*$SZREG
+.end bn_mul_mont_internal
+.rdata
+.asciiz "Montgomery Multiplication for MIPS, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/bn/asm/mips.pl b/deps/openssl/openssl/crypto/bn/asm/mips.pl
new file mode 100644
index 000000000..38b51645f
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/asm/mips.pl
@@ -0,0 +1,2585 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project.
+#
+# Rights for redistribution and usage in source and binary forms are
+# granted according to the OpenSSL license. Warranty of any kind is
+# disclaimed.
+# ====================================================================
+
+
+# July 1999
+#
+# This is drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c.
+#
+# The module is designed to work with either of the "new" MIPS ABI(5),
+# namely N32 or N64, offered by IRIX 6.x. It's not ment to work under
+# IRIX 5.x not only because it doesn't support new ABIs but also
+# because 5.x kernels put R4x00 CPU into 32-bit mode and all those
+# 64-bit instructions (daddu, dmultu, etc.) found below gonna only
+# cause illegal instruction exception:-(
+#
+# In addition the code depends on preprocessor flags set up by MIPSpro
+# compiler driver (either as or cc) and therefore (probably?) can't be
+# compiled by the GNU assembler. GNU C driver manages fine though...
+# I mean as long as -mmips-as is specified or is the default option,
+# because then it simply invokes /usr/bin/as which in turn takes
+# perfect care of the preprocessor definitions. Another neat feature
+# offered by the MIPSpro assembler is an optimization pass. This gave
+# me the opportunity to have the code looking more regular as all those
+# architecture dependent instruction rescheduling details were left to
+# the assembler. Cool, huh?
+#
+# Performance improvement is astonishing! 'apps/openssl speed rsa dsa'
+# goes way over 3 times faster!
+#
+# <appro@fy.chalmers.se>
+
+# October 2010
+#
+# Adapt the module even for 32-bit ABIs and other OSes. The former was
+# achieved by mechanical replacement of 64-bit arithmetic instructions
+# such as dmultu, daddu, etc. with their 32-bit counterparts and
+# adjusting offsets denoting multiples of BN_ULONG. Above mentioned
+# >3x performance improvement naturally does not apply to 32-bit code
+# [because there is no instruction 32-bit compiler can't use], one
+# has to content with 40-85% improvement depending on benchmark and
+# key length, more for longer keys.
+
+$flavour = shift;
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+if ($flavour =~ /64|n32/i) {
+ $LD="ld";
+ $ST="sd";
+ $MULTU="dmultu";
+ $DIVU="ddivu";
+ $ADDU="daddu";
+ $SUBU="dsubu";
+ $SRL="dsrl";
+ $SLL="dsll";
+ $BNSZ=8;
+ $PTR_ADD="daddu";
+ $PTR_SUB="dsubu";
+ $SZREG=8;
+ $REG_S="sd";
+ $REG_L="ld";
+} else {
+ $LD="lw";
+ $ST="sw";
+ $MULTU="multu";
+ $DIVU="divu";
+ $ADDU="addu";
+ $SUBU="subu";
+ $SRL="srl";
+ $SLL="sll";
+ $BNSZ=4;
+ $PTR_ADD="addu";
+ $PTR_SUB="subu";
+ $SZREG=4;
+ $REG_S="sw";
+ $REG_L="lw";
+ $code=".set mips2\n";
+}
+
+# Below is N32/64 register layout used in the original module.
+#
+($zero,$at,$v0,$v1)=map("\$$_",(0..3));
+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
+($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
+($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
+($ta0,$ta1,$ta2,$ta3)=($a4,$a5,$a6,$a7);
+#
+# No special adaptation is required for O32. NUBI on the other hand
+# is treated by saving/restoring ($v1,$t0..$t3).
+
+$gp=$v1 if ($flavour =~ /nubi/i);
+
+$minus4=$v1;
+
+$code.=<<___;
+.rdata
+.asciiz "mips3.s, Version 1.2"
+.asciiz "MIPS II/III/IV ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>"
+
+.text
+.set noat
+
+.align 5
+.globl bn_mul_add_words
+.ent bn_mul_add_words
+bn_mul_add_words:
+ .set noreorder
+ bgtz $a2,bn_mul_add_words_internal
+ move $v0,$zero
+ jr $ra
+ move $a0,$v0
+.end bn_mul_add_words
+
+.align 5
+.ent bn_mul_add_words_internal
+bn_mul_add_words_internal:
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x8000f008,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $ra,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___;
+ .set reorder
+ li $minus4,-4
+ and $ta0,$a2,$minus4
+ $LD $t0,0($a1)
+ beqz $ta0,.L_bn_mul_add_words_tail
+
+.L_bn_mul_add_words_loop:
+ $MULTU $t0,$a3
+ $LD $t1,0($a0)
+ $LD $t2,$BNSZ($a1)
+ $LD $t3,$BNSZ($a0)
+ $LD $ta0,2*$BNSZ($a1)
+ $LD $ta1,2*$BNSZ($a0)
+ $ADDU $t1,$v0
+ sltu $v0,$t1,$v0 # All manuals say it "compares 32-bit
+ # values", but it seems to work fine
+ # even on 64-bit registers.
+ mflo $at
+ mfhi $t0
+ $ADDU $t1,$at
+ $ADDU $v0,$t0
+ $MULTU $t2,$a3
+ sltu $at,$t1,$at
+ $ST $t1,0($a0)
+ $ADDU $v0,$at
+
+ $LD $ta2,3*$BNSZ($a1)
+ $LD $ta3,3*$BNSZ($a0)
+ $ADDU $t3,$v0
+ sltu $v0,$t3,$v0
+ mflo $at
+ mfhi $t2
+ $ADDU $t3,$at
+ $ADDU $v0,$t2
+ $MULTU $ta0,$a3
+ sltu $at,$t3,$at
+ $ST $t3,$BNSZ($a0)
+ $ADDU $v0,$at
+
+ subu $a2,4
+ $PTR_ADD $a0,4*$BNSZ
+ $PTR_ADD $a1,4*$BNSZ
+ $ADDU $ta1,$v0
+ sltu $v0,$ta1,$v0
+ mflo $at
+ mfhi $ta0
+ $ADDU $ta1,$at
+ $ADDU $v0,$ta0
+ $MULTU $ta2,$a3
+ sltu $at,$ta1,$at
+ $ST $ta1,-2*$BNSZ($a0)
+ $ADDU $v0,$at
+
+
+ and $ta0,$a2,$minus4
+ $ADDU $ta3,$v0
+ sltu $v0,$ta3,$v0
+ mflo $at
+ mfhi $ta2
+ $ADDU $ta3,$at
+ $ADDU $v0,$ta2
+ sltu $at,$ta3,$at
+ $ST $ta3,-$BNSZ($a0)
+ $ADDU $v0,$at
+ .set noreorder
+ bgtzl $ta0,.L_bn_mul_add_words_loop
+ $LD $t0,0($a1)
+
+ beqz $a2,.L_bn_mul_add_words_return
+ nop
+
+.L_bn_mul_add_words_tail:
+ .set reorder
+ $LD $t0,0($a1)
+ $MULTU $t0,$a3
+ $LD $t1,0($a0)
+ subu $a2,1
+ $ADDU $t1,$v0
+ sltu $v0,$t1,$v0
+ mflo $at
+ mfhi $t0
+ $ADDU $t1,$at
+ $ADDU $v0,$t0
+ sltu $at,$t1,$at
+ $ST $t1,0($a0)
+ $ADDU $v0,$at
+ beqz $a2,.L_bn_mul_add_words_return
+
+ $LD $t0,$BNSZ($a1)
+ $MULTU $t0,$a3
+ $LD $t1,$BNSZ($a0)
+ subu $a2,1
+ $ADDU $t1,$v0
+ sltu $v0,$t1,$v0
+ mflo $at
+ mfhi $t0
+ $ADDU $t1,$at
+ $ADDU $v0,$t0
+ sltu $at,$t1,$at
+ $ST $t1,$BNSZ($a0)
+ $ADDU $v0,$at
+ beqz $a2,.L_bn_mul_add_words_return
+
+ $LD $t0,2*$BNSZ($a1)
+ $MULTU $t0,$a3
+ $LD $t1,2*$BNSZ($a0)
+ $ADDU $t1,$v0
+ sltu $v0,$t1,$v0
+ mflo $at
+ mfhi $t0
+ $ADDU $t1,$at
+ $ADDU $v0,$t0
+ sltu $at,$t1,$at
+ $ST $t1,2*$BNSZ($a0)
+ $ADDU $v0,$at
+
+.L_bn_mul_add_words_return:
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+ jr $ra
+ move $a0,$v0
+.end bn_mul_add_words_internal
+
+.align 5
+.globl bn_mul_words
+.ent bn_mul_words
+bn_mul_words:
+ .set noreorder
+ bgtz $a2,bn_mul_words_internal
+ move $v0,$zero
+ jr $ra
+ move $a0,$v0
+.end bn_mul_words
+
+.align 5
+.ent bn_mul_words_internal
+bn_mul_words_internal:
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x8000f008,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $ra,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___;
+ .set reorder
+ li $minus4,-4
+ and $ta0,$a2,$minus4
+ $LD $t0,0($a1)
+ beqz $ta0,.L_bn_mul_words_tail
+
+.L_bn_mul_words_loop:
+ $MULTU $t0,$a3
+ $LD $t2,$BNSZ($a1)
+ $LD $ta0,2*$BNSZ($a1)
+ $LD $ta2,3*$BNSZ($a1)
+ mflo $at
+ mfhi $t0
+ $ADDU $v0,$at
+ sltu $t1,$v0,$at
+ $MULTU $t2,$a3
+ $ST $v0,0($a0)
+ $ADDU $v0,$t1,$t0
+
+ subu $a2,4
+ $PTR_ADD $a0,4*$BNSZ
+ $PTR_ADD $a1,4*$BNSZ
+ mflo $at
+ mfhi $t2
+ $ADDU $v0,$at
+ sltu $t3,$v0,$at
+ $MULTU $ta0,$a3
+ $ST $v0,-3*$BNSZ($a0)
+ $ADDU $v0,$t3,$t2
+
+ mflo $at
+ mfhi $ta0
+ $ADDU $v0,$at
+ sltu $ta1,$v0,$at
+ $MULTU $ta2,$a3
+ $ST $v0,-2*$BNSZ($a0)
+ $ADDU $v0,$ta1,$ta0
+
+ and $ta0,$a2,$minus4
+ mflo $at
+ mfhi $ta2
+ $ADDU $v0,$at
+ sltu $ta3,$v0,$at
+ $ST $v0,-$BNSZ($a0)
+ $ADDU $v0,$ta3,$ta2
+ .set noreorder
+ bgtzl $ta0,.L_bn_mul_words_loop
+ $LD $t0,0($a1)
+
+ beqz $a2,.L_bn_mul_words_return
+ nop
+
+.L_bn_mul_words_tail:
+ .set reorder
+ $LD $t0,0($a1)
+ $MULTU $t0,$a3
+ subu $a2,1
+ mflo $at
+ mfhi $t0
+ $ADDU $v0,$at
+ sltu $t1,$v0,$at
+ $ST $v0,0($a0)
+ $ADDU $v0,$t1,$t0
+ beqz $a2,.L_bn_mul_words_return
+
+ $LD $t0,$BNSZ($a1)
+ $MULTU $t0,$a3
+ subu $a2,1
+ mflo $at
+ mfhi $t0
+ $ADDU $v0,$at
+ sltu $t1,$v0,$at
+ $ST $v0,$BNSZ($a0)
+ $ADDU $v0,$t1,$t0
+ beqz $a2,.L_bn_mul_words_return
+
+ $LD $t0,2*$BNSZ($a1)
+ $MULTU $t0,$a3
+ mflo $at
+ mfhi $t0
+ $ADDU $v0,$at
+ sltu $t1,$v0,$at
+ $ST $v0,2*$BNSZ($a0)
+ $ADDU $v0,$t1,$t0
+
+.L_bn_mul_words_return:
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+ jr $ra
+ move $a0,$v0
+.end bn_mul_words_internal
+
+.align 5
+.globl bn_sqr_words
+.ent bn_sqr_words
+bn_sqr_words:
+ .set noreorder
+ bgtz $a2,bn_sqr_words_internal
+ move $v0,$zero
+ jr $ra
+ move $a0,$v0
+.end bn_sqr_words
+
+.align 5
+.ent bn_sqr_words_internal
+bn_sqr_words_internal:
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x8000f008,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $ra,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___;
+ .set reorder
+ li $minus4,-4
+ and $ta0,$a2,$minus4
+ $LD $t0,0($a1)
+ beqz $ta0,.L_bn_sqr_words_tail
+
+.L_bn_sqr_words_loop:
+ $MULTU $t0,$t0
+ $LD $t2,$BNSZ($a1)
+ $LD $ta0,2*$BNSZ($a1)
+ $LD $ta2,3*$BNSZ($a1)
+ mflo $t1
+ mfhi $t0
+ $ST $t1,0($a0)
+ $ST $t0,$BNSZ($a0)
+
+ $MULTU $t2,$t2
+ subu $a2,4
+ $PTR_ADD $a0,8*$BNSZ
+ $PTR_ADD $a1,4*$BNSZ
+ mflo $t3
+ mfhi $t2
+ $ST $t3,-6*$BNSZ($a0)
+ $ST $t2,-5*$BNSZ($a0)
+
+ $MULTU $ta0,$ta0
+ mflo $ta1
+ mfhi $ta0
+ $ST $ta1,-4*$BNSZ($a0)
+ $ST $ta0,-3*$BNSZ($a0)
+
+
+ $MULTU $ta2,$ta2
+ and $ta0,$a2,$minus4
+ mflo $ta3
+ mfhi $ta2
+ $ST $ta3,-2*$BNSZ($a0)
+ $ST $ta2,-$BNSZ($a0)
+
+ .set noreorder
+ bgtzl $ta0,.L_bn_sqr_words_loop
+ $LD $t0,0($a1)
+
+ beqz $a2,.L_bn_sqr_words_return
+ nop
+
+.L_bn_sqr_words_tail:
+ .set reorder
+ $LD $t0,0($a1)
+ $MULTU $t0,$t0
+ subu $a2,1
+ mflo $t1
+ mfhi $t0
+ $ST $t1,0($a0)
+ $ST $t0,$BNSZ($a0)
+ beqz $a2,.L_bn_sqr_words_return
+
+ $LD $t0,$BNSZ($a1)
+ $MULTU $t0,$t0
+ subu $a2,1
+ mflo $t1
+ mfhi $t0
+ $ST $t1,2*$BNSZ($a0)
+ $ST $t0,3*$BNSZ($a0)
+ beqz $a2,.L_bn_sqr_words_return
+
+ $LD $t0,2*$BNSZ($a1)
+ $MULTU $t0,$t0
+ mflo $t1
+ mfhi $t0
+ $ST $t1,4*$BNSZ($a0)
+ $ST $t0,5*$BNSZ($a0)
+
+.L_bn_sqr_words_return:
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+ jr $ra
+ move $a0,$v0
+
+.end bn_sqr_words_internal
+
+.align 5
+.globl bn_add_words
+.ent bn_add_words
+bn_add_words:
+ .set noreorder
+ bgtz $a3,bn_add_words_internal
+ move $v0,$zero
+ jr $ra
+ move $a0,$v0
+.end bn_add_words
+
+.align 5
+.ent bn_add_words_internal
+bn_add_words_internal:
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x8000f008,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $ra,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___;
+ .set reorder
+ li $minus4,-4
+ and $at,$a3,$minus4
+ $LD $t0,0($a1)
+ beqz $at,.L_bn_add_words_tail
+
+.L_bn_add_words_loop:
+ $LD $ta0,0($a2)
+ subu $a3,4
+ $LD $t1,$BNSZ($a1)
+ and $at,$a3,$minus4
+ $LD $t2,2*$BNSZ($a1)
+ $PTR_ADD $a2,4*$BNSZ
+ $LD $t3,3*$BNSZ($a1)
+ $PTR_ADD $a0,4*$BNSZ
+ $LD $ta1,-3*$BNSZ($a2)
+ $PTR_ADD $a1,4*$BNSZ
+ $LD $ta2,-2*$BNSZ($a2)
+ $LD $ta3,-$BNSZ($a2)
+ $ADDU $ta0,$t0
+ sltu $t8,$ta0,$t0
+ $ADDU $t0,$ta0,$v0
+ sltu $v0,$t0,$ta0
+ $ST $t0,-4*$BNSZ($a0)
+ $ADDU $v0,$t8
+
+ $ADDU $ta1,$t1
+ sltu $t9,$ta1,$t1
+ $ADDU $t1,$ta1,$v0
+ sltu $v0,$t1,$ta1
+ $ST $t1,-3*$BNSZ($a0)
+ $ADDU $v0,$t9
+
+ $ADDU $ta2,$t2
+ sltu $t8,$ta2,$t2
+ $ADDU $t2,$ta2,$v0
+ sltu $v0,$t2,$ta2
+ $ST $t2,-2*$BNSZ($a0)
+ $ADDU $v0,$t8
+
+ $ADDU $ta3,$t3
+ sltu $t9,$ta3,$t3
+ $ADDU $t3,$ta3,$v0
+ sltu $v0,$t3,$ta3
+ $ST $t3,-$BNSZ($a0)
+ $ADDU $v0,$t9
+
+ .set noreorder
+ bgtzl $at,.L_bn_add_words_loop
+ $LD $t0,0($a1)
+
+ beqz $a3,.L_bn_add_words_return
+ nop
+
+.L_bn_add_words_tail:
+ .set reorder
+ $LD $t0,0($a1)
+ $LD $ta0,0($a2)
+ $ADDU $ta0,$t0
+ subu $a3,1
+ sltu $t8,$ta0,$t0
+ $ADDU $t0,$ta0,$v0
+ sltu $v0,$t0,$ta0
+ $ST $t0,0($a0)
+ $ADDU $v0,$t8
+ beqz $a3,.L_bn_add_words_return
+
+ $LD $t1,$BNSZ($a1)
+ $LD $ta1,$BNSZ($a2)
+ $ADDU $ta1,$t1
+ subu $a3,1
+ sltu $t9,$ta1,$t1
+ $ADDU $t1,$ta1,$v0
+ sltu $v0,$t1,$ta1
+ $ST $t1,$BNSZ($a0)
+ $ADDU $v0,$t9
+ beqz $a3,.L_bn_add_words_return
+
+ $LD $t2,2*$BNSZ($a1)
+ $LD $ta2,2*$BNSZ($a2)
+ $ADDU $ta2,$t2
+ sltu $t8,$ta2,$t2
+ $ADDU $t2,$ta2,$v0
+ sltu $v0,$t2,$ta2
+ $ST $t2,2*$BNSZ($a0)
+ $ADDU $v0,$t8
+
+.L_bn_add_words_return:
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+ jr $ra
+ move $a0,$v0
+
+.end bn_add_words_internal
+
+.align 5
+.globl bn_sub_words
+.ent bn_sub_words
+bn_sub_words:
+ .set noreorder
+ bgtz $a3,bn_sub_words_internal
+ move $v0,$zero
+ jr $ra
+ move $a0,$zero
+.end bn_sub_words
+
+.align 5
+.ent bn_sub_words_internal
+bn_sub_words_internal:
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x8000f008,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $ra,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___;
+ .set reorder
+ li $minus4,-4
+ and $at,$a3,$minus4
+ $LD $t0,0($a1)
+ beqz $at,.L_bn_sub_words_tail
+
+.L_bn_sub_words_loop:
+ $LD $ta0,0($a2)
+ subu $a3,4
+ $LD $t1,$BNSZ($a1)
+ and $at,$a3,$minus4
+ $LD $t2,2*$BNSZ($a1)
+ $PTR_ADD $a2,4*$BNSZ
+ $LD $t3,3*$BNSZ($a1)
+ $PTR_ADD $a0,4*$BNSZ
+ $LD $ta1,-3*$BNSZ($a2)
+ $PTR_ADD $a1,4*$BNSZ
+ $LD $ta2,-2*$BNSZ($a2)
+ $LD $ta3,-$BNSZ($a2)
+ sltu $t8,$t0,$ta0
+ $SUBU $ta0,$t0,$ta0
+ $SUBU $t0,$ta0,$v0
+ sgtu $v0,$t0,$ta0
+ $ST $t0,-4*$BNSZ($a0)
+ $ADDU $v0,$t8
+
+ sltu $t9,$t1,$ta1
+ $SUBU $ta1,$t1,$ta1
+ $SUBU $t1,$ta1,$v0
+ sgtu $v0,$t1,$ta1
+ $ST $t1,-3*$BNSZ($a0)
+ $ADDU $v0,$t9
+
+
+ sltu $t8,$t2,$ta2
+ $SUBU $ta2,$t2,$ta2
+ $SUBU $t2,$ta2,$v0
+ sgtu $v0,$t2,$ta2
+ $ST $t2,-2*$BNSZ($a0)
+ $ADDU $v0,$t8
+
+ sltu $t9,$t3,$ta3
+ $SUBU $ta3,$t3,$ta3
+ $SUBU $t3,$ta3,$v0
+ sgtu $v0,$t3,$ta3
+ $ST $t3,-$BNSZ($a0)
+ $ADDU $v0,$t9
+
+ .set noreorder
+ bgtzl $at,.L_bn_sub_words_loop
+ $LD $t0,0($a1)
+
+ beqz $a3,.L_bn_sub_words_return
+ nop
+
+.L_bn_sub_words_tail:
+ .set reorder
+ $LD $t0,0($a1)
+ $LD $ta0,0($a2)
+ subu $a3,1
+ sltu $t8,$t0,$ta0
+ $SUBU $ta0,$t0,$ta0
+ $SUBU $t0,$ta0,$v0
+ sgtu $v0,$t0,$ta0
+ $ST $t0,0($a0)
+ $ADDU $v0,$t8
+ beqz $a3,.L_bn_sub_words_return
+
+ $LD $t1,$BNSZ($a1)
+ subu $a3,1
+ $LD $ta1,$BNSZ($a2)
+ sltu $t9,$t1,$ta1
+ $SUBU $ta1,$t1,$ta1
+ $SUBU $t1,$ta1,$v0
+ sgtu $v0,$t1,$ta1
+ $ST $t1,$BNSZ($a0)
+ $ADDU $v0,$t9
+ beqz $a3,.L_bn_sub_words_return
+
+ $LD $t2,2*$BNSZ($a1)
+ $LD $ta2,2*$BNSZ($a2)
+ sltu $t8,$t2,$ta2
+ $SUBU $ta2,$t2,$ta2
+ $SUBU $t2,$ta2,$v0
+ sgtu $v0,$t2,$ta2
+ $ST $t2,2*$BNSZ($a0)
+ $ADDU $v0,$t8
+
+.L_bn_sub_words_return:
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+ jr $ra
+ move $a0,$v0
+.end bn_sub_words_internal
+
+.align 5
+.globl bn_div_3_words
+.ent bn_div_3_words
+bn_div_3_words:
+ .set noreorder
+ move $a3,$a0 # we know that bn_div_words does not
+ # touch $a3, $ta2, $ta3 and preserves $a2
+ # so that we can save two arguments
+ # and return address in registers
+ # instead of stack:-)
+
+ $LD $a0,($a3)
+ move $ta2,$a1
+ bne $a0,$a2,bn_div_3_words_internal
+ $LD $a1,-$BNSZ($a3)
+ li $v0,-1
+ jr $ra
+ move $a0,$v0
+.end bn_div_3_words
+
+.align 5
+.ent bn_div_3_words_internal
+bn_div_3_words_internal:
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x8000f008,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $ra,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___;
+ .set reorder
+ move $ta3,$ra
+ bal bn_div_words_internal
+ move $ra,$ta3
+ $MULTU $ta2,$v0
+ $LD $t2,-2*$BNSZ($a3)
+ move $ta0,$zero
+ mfhi $t1
+ mflo $t0
+ sltu $t8,$t1,$a1
+.L_bn_div_3_words_inner_loop:
+ bnez $t8,.L_bn_div_3_words_inner_loop_done
+ sgeu $at,$t2,$t0
+ seq $t9,$t1,$a1
+ and $at,$t9
+ sltu $t3,$t0,$ta2
+ $ADDU $a1,$a2
+ $SUBU $t1,$t3
+ $SUBU $t0,$ta2
+ sltu $t8,$t1,$a1
+ sltu $ta0,$a1,$a2
+ or $t8,$ta0
+ .set noreorder
+ beqzl $at,.L_bn_div_3_words_inner_loop
+ $SUBU $v0,1
+ .set reorder
+.L_bn_div_3_words_inner_loop_done:
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+ jr $ra
+ move $a0,$v0
+.end bn_div_3_words_internal
+
+.align 5
+.globl bn_div_words
+.ent bn_div_words
+bn_div_words:
+ .set noreorder
+ bnez $a2,bn_div_words_internal
+ li $v0,-1 # I would rather signal div-by-zero
+ # which can be done with 'break 7'
+ jr $ra
+ move $a0,$v0
+.end bn_div_words
+
+.align 5
+.ent bn_div_words_internal
+bn_div_words_internal:
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x8000f008,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $ra,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___;
+ move $v1,$zero
+ bltz $a2,.L_bn_div_words_body
+ move $t9,$v1
+ $SLL $a2,1
+ bgtz $a2,.-4
+ addu $t9,1
+
+ .set reorder
+ negu $t1,$t9
+ li $t2,-1
+ $SLL $t2,$t1
+ and $t2,$a0
+ $SRL $at,$a1,$t1
+ .set noreorder
+ bnezl $t2,.+8
+ break 6 # signal overflow
+ .set reorder
+ $SLL $a0,$t9
+ $SLL $a1,$t9
+ or $a0,$at
+___
+$QT=$ta0;
+$HH=$ta1;
+$DH=$v1;
+$code.=<<___;
+.L_bn_div_words_body:
+ $SRL $DH,$a2,4*$BNSZ # bits
+ sgeu $at,$a0,$a2
+ .set noreorder
+ bnezl $at,.+8
+ $SUBU $a0,$a2
+ .set reorder
+
+ li $QT,-1
+ $SRL $HH,$a0,4*$BNSZ # bits
+ $SRL $QT,4*$BNSZ # q=0xffffffff
+ beq $DH,$HH,.L_bn_div_words_skip_div1
+ $DIVU $zero,$a0,$DH
+ mflo $QT
+.L_bn_div_words_skip_div1:
+ $MULTU $a2,$QT
+ $SLL $t3,$a0,4*$BNSZ # bits
+ $SRL $at,$a1,4*$BNSZ # bits
+ or $t3,$at
+ mflo $t0
+ mfhi $t1
+.L_bn_div_words_inner_loop1:
+ sltu $t2,$t3,$t0
+ seq $t8,$HH,$t1
+ sltu $at,$HH,$t1
+ and $t2,$t8
+ sltu $v0,$t0,$a2
+ or $at,$t2
+ .set noreorder
+ beqz $at,.L_bn_div_words_inner_loop1_done
+ $SUBU $t1,$v0
+ $SUBU $t0,$a2
+ b .L_bn_div_words_inner_loop1
+ $SUBU $QT,1
+ .set reorder
+.L_bn_div_words_inner_loop1_done:
+
+ $SLL $a1,4*$BNSZ # bits
+ $SUBU $a0,$t3,$t0
+ $SLL $v0,$QT,4*$BNSZ # bits
+
+ li $QT,-1
+ $SRL $HH,$a0,4*$BNSZ # bits
+ $SRL $QT,4*$BNSZ # q=0xffffffff
+ beq $DH,$HH,.L_bn_div_words_skip_div2
+ $DIVU $zero,$a0,$DH
+ mflo $QT
+.L_bn_div_words_skip_div2:
+ $MULTU $a2,$QT
+ $SLL $t3,$a0,4*$BNSZ # bits
+ $SRL $at,$a1,4*$BNSZ # bits
+ or $t3,$at
+ mflo $t0
+ mfhi $t1
+.L_bn_div_words_inner_loop2:
+ sltu $t2,$t3,$t0
+ seq $t8,$HH,$t1
+ sltu $at,$HH,$t1
+ and $t2,$t8
+ sltu $v1,$t0,$a2
+ or $at,$t2
+ .set noreorder
+ beqz $at,.L_bn_div_words_inner_loop2_done
+ $SUBU $t1,$v1
+ $SUBU $t0,$a2
+ b .L_bn_div_words_inner_loop2
+ $SUBU $QT,1
+ .set reorder
+.L_bn_div_words_inner_loop2_done:
+
+ $SUBU $a0,$t3,$t0
+ or $v0,$QT
+ $SRL $v1,$a0,$t9 # $v1 contains remainder if anybody wants it
+ $SRL $a2,$t9 # restore $a2
+
+ .set noreorder
+ move $a1,$v1
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+ jr $ra
+ move $a0,$v0
+.end bn_div_words_internal
+___
+undef $HH; undef $QT; undef $DH;
+
+($a_0,$a_1,$a_2,$a_3)=($t0,$t1,$t2,$t3);
+($b_0,$b_1,$b_2,$b_3)=($ta0,$ta1,$ta2,$ta3);
+
+($a_4,$a_5,$a_6,$a_7)=($s0,$s2,$s4,$a1); # once we load a[7], no use for $a1
+($b_4,$b_5,$b_6,$b_7)=($s1,$s3,$s5,$a2); # once we load b[7], no use for $a2
+
+($t_1,$t_2,$c_1,$c_2,$c_3)=($t8,$t9,$v0,$v1,$a3);
+
+$code.=<<___;
+
+.align 5
+.globl bn_mul_comba8
+.ent bn_mul_comba8
+bn_mul_comba8:
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,12*$SZREG,$ra
+ .mask 0x803ff008,-$SZREG
+ $PTR_SUB $sp,12*$SZREG
+ $REG_S $ra,11*$SZREG($sp)
+ $REG_S $s5,10*$SZREG($sp)
+ $REG_S $s4,9*$SZREG($sp)
+ $REG_S $s3,8*$SZREG($sp)
+ $REG_S $s2,7*$SZREG($sp)
+ $REG_S $s1,6*$SZREG($sp)
+ $REG_S $s0,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___ if ($flavour !~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x003f0000,-$SZREG
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $s5,5*$SZREG($sp)
+ $REG_S $s4,4*$SZREG($sp)
+ $REG_S $s3,3*$SZREG($sp)
+ $REG_S $s2,2*$SZREG($sp)
+ $REG_S $s1,1*$SZREG($sp)
+ $REG_S $s0,0*$SZREG($sp)
+___
+$code.=<<___;
+
+ .set reorder
+ $LD $a_0,0($a1) # If compiled with -mips3 option on
+ # R5000 box assembler barks on this
+ # 1ine with "should not have mult/div
+ # as last instruction in bb (R10K
+ # bug)" warning. If anybody out there
+ # has a clue about how to circumvent
+ # this do send me a note.
+ # <appro\@fy.chalmers.se>
+
+ $LD $b_0,0($a2)
+ $LD $a_1,$BNSZ($a1)
+ $LD $a_2,2*$BNSZ($a1)
+ $MULTU $a_0,$b_0 # mul_add_c(a[0],b[0],c1,c2,c3);
+ $LD $a_3,3*$BNSZ($a1)
+ $LD $b_1,$BNSZ($a2)
+ $LD $b_2,2*$BNSZ($a2)
+ $LD $b_3,3*$BNSZ($a2)
+ mflo $c_1
+ mfhi $c_2
+
+ $LD $a_4,4*$BNSZ($a1)
+ $LD $a_5,5*$BNSZ($a1)
+ $MULTU $a_0,$b_1 # mul_add_c(a[0],b[1],c2,c3,c1);
+ $LD $a_6,6*$BNSZ($a1)
+ $LD $a_7,7*$BNSZ($a1)
+ $LD $b_4,4*$BNSZ($a2)
+ $LD $b_5,5*$BNSZ($a2)
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_1,$b_0 # mul_add_c(a[1],b[0],c2,c3,c1);
+ $ADDU $c_3,$t_2,$at
+ $LD $b_6,6*$BNSZ($a2)
+ $LD $b_7,7*$BNSZ($a2)
+ $ST $c_1,0($a0) # r[0]=c1;
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_2,$b_0 # mul_add_c(a[2],b[0],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $c_1,$c_3,$t_2
+ $ST $c_2,$BNSZ($a0) # r[1]=c2;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_1,$b_1 # mul_add_c(a[1],b[1],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_0,$b_2 # mul_add_c(a[0],b[2],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $c_2,$c_1,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_0,$b_3 # mul_add_c(a[0],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,2*$BNSZ($a0) # r[2]=c3;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_1,$b_2 # mul_add_c(a[1],b[2],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $c_3,$c_2,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_2,$b_1 # mul_add_c(a[2],b[1],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_3,$b_0 # mul_add_c(a[3],b[0],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_4,$b_0 # mul_add_c(a[4],b[0],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,3*$BNSZ($a0) # r[3]=c1;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_3,$b_1 # mul_add_c(a[3],b[1],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $c_1,$c_3,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_2,$b_2 # mul_add_c(a[2],b[2],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_1,$b_3 # mul_add_c(a[1],b[3],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_0,$b_4 # mul_add_c(a[0],b[4],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_0,$b_5 # mul_add_c(a[0],b[5],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,4*$BNSZ($a0) # r[4]=c2;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_1,$b_4 # mul_add_c(a[1],b[4],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $c_2,$c_1,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_2,$b_3 # mul_add_c(a[2],b[3],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_3,$b_2 # mul_add_c(a[3],b[2],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_4,$b_1 # mul_add_c(a[4],b[1],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_5,$b_0 # mul_add_c(a[5],b[0],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_6,$b_0 # mul_add_c(a[6],b[0],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,5*$BNSZ($a0) # r[5]=c3;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_5,$b_1 # mul_add_c(a[5],b[1],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $c_3,$c_2,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_4,$b_2 # mul_add_c(a[4],b[2],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_3,$b_3 # mul_add_c(a[3],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_2,$b_4 # mul_add_c(a[2],b[4],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_1,$b_5 # mul_add_c(a[1],b[5],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_0,$b_6 # mul_add_c(a[0],b[6],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_0,$b_7 # mul_add_c(a[0],b[7],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,6*$BNSZ($a0) # r[6]=c1;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_1,$b_6 # mul_add_c(a[1],b[6],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $c_1,$c_3,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_2,$b_5 # mul_add_c(a[2],b[5],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_3,$b_4 # mul_add_c(a[3],b[4],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_4,$b_3 # mul_add_c(a[4],b[3],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_5,$b_2 # mul_add_c(a[5],b[2],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_6,$b_1 # mul_add_c(a[6],b[1],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_7,$b_0 # mul_add_c(a[7],b[0],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_7,$b_1 # mul_add_c(a[7],b[1],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,7*$BNSZ($a0) # r[7]=c2;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_6,$b_2 # mul_add_c(a[6],b[2],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $c_2,$c_1,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_5,$b_3 # mul_add_c(a[5],b[3],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_4,$b_4 # mul_add_c(a[4],b[4],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_3,$b_5 # mul_add_c(a[3],b[5],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_2,$b_6 # mul_add_c(a[2],b[6],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_1,$b_7 # mul_add_c(a[1],b[7],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_2,$b_7 # mul_add_c(a[2],b[7],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,8*$BNSZ($a0) # r[8]=c3;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_3,$b_6 # mul_add_c(a[3],b[6],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $c_3,$c_2,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_4,$b_5 # mul_add_c(a[4],b[5],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_5,$b_4 # mul_add_c(a[5],b[4],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_6,$b_3 # mul_add_c(a[6],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_7,$b_2 # mul_add_c(a[7],b[2],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_7,$b_3 # mul_add_c(a[7],b[3],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,9*$BNSZ($a0) # r[9]=c1;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_6,$b_4 # mul_add_c(a[6],b[4],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $c_1,$c_3,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_5,$b_5 # mul_add_c(a[5],b[5],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_4,$b_6 # mul_add_c(a[4],b[6],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_3,$b_7 # mul_add_c(a[3],b[7],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_4,$b_7 # mul_add_c(a[4],b[7],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,10*$BNSZ($a0) # r[10]=c2;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_5,$b_6 # mul_add_c(a[5],b[6],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $c_2,$c_1,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_6,$b_5 # mul_add_c(a[6],b[5],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_7,$b_4 # mul_add_c(a[7],b[4],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_7,$b_5 # mul_add_c(a[7],b[5],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,11*$BNSZ($a0) # r[11]=c3;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_6,$b_6 # mul_add_c(a[6],b[6],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $c_3,$c_2,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_5,$b_7 # mul_add_c(a[5],b[7],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_6,$b_7 # mul_add_c(a[6],b[7],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,12*$BNSZ($a0) # r[12]=c1;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_7,$b_6 # mul_add_c(a[7],b[6],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $c_1,$c_3,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_7,$b_7 # mul_add_c(a[7],b[7],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,13*$BNSZ($a0) # r[13]=c2;
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ $ST $c_3,14*$BNSZ($a0) # r[14]=c3;
+ $ST $c_1,15*$BNSZ($a0) # r[15]=c1;
+
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $s5,10*$SZREG($sp)
+ $REG_L $s4,9*$SZREG($sp)
+ $REG_L $s3,8*$SZREG($sp)
+ $REG_L $s2,7*$SZREG($sp)
+ $REG_L $s1,6*$SZREG($sp)
+ $REG_L $s0,5*$SZREG($sp)
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ jr $ra
+ $PTR_ADD $sp,12*$SZREG
+___
+$code.=<<___ if ($flavour !~ /nubi/i);
+ $REG_L $s5,5*$SZREG($sp)
+ $REG_L $s4,4*$SZREG($sp)
+ $REG_L $s3,3*$SZREG($sp)
+ $REG_L $s2,2*$SZREG($sp)
+ $REG_L $s1,1*$SZREG($sp)
+ $REG_L $s0,0*$SZREG($sp)
+ jr $ra
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+.end bn_mul_comba8
+
+.align 5
+.globl bn_mul_comba4
+.ent bn_mul_comba4
+bn_mul_comba4:
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x8000f008,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $ra,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___;
+ .set reorder
+ $LD $a_0,0($a1)
+ $LD $b_0,0($a2)
+ $LD $a_1,$BNSZ($a1)
+ $LD $a_2,2*$BNSZ($a1)
+ $MULTU $a_0,$b_0 # mul_add_c(a[0],b[0],c1,c2,c3);
+ $LD $a_3,3*$BNSZ($a1)
+ $LD $b_1,$BNSZ($a2)
+ $LD $b_2,2*$BNSZ($a2)
+ $LD $b_3,3*$BNSZ($a2)
+ mflo $c_1
+ mfhi $c_2
+ $ST $c_1,0($a0)
+
+ $MULTU $a_0,$b_1 # mul_add_c(a[0],b[1],c2,c3,c1);
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_1,$b_0 # mul_add_c(a[1],b[0],c2,c3,c1);
+ $ADDU $c_3,$t_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_2,$b_0 # mul_add_c(a[2],b[0],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $c_1,$c_3,$t_2
+ $ST $c_2,$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_1,$b_1 # mul_add_c(a[1],b[1],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_0,$b_2 # mul_add_c(a[0],b[2],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $c_2,$c_1,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_0,$b_3 # mul_add_c(a[0],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,2*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_1,$b_2 # mul_add_c(a[1],b[2],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $c_3,$c_2,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_2,$b_1 # mul_add_c(a[2],b[1],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_3,$b_0 # mul_add_c(a[3],b[0],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_3,$b_1 # mul_add_c(a[3],b[1],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,3*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_2,$b_2 # mul_add_c(a[2],b[2],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $c_1,$c_3,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_1,$b_3 # mul_add_c(a[1],b[3],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_2,$b_3 # mul_add_c(a[2],b[3],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,4*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_3,$b_2 # mul_add_c(a[3],b[2],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $c_2,$c_1,$t_2
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_3,$b_3 # mul_add_c(a[3],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,5*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ $ST $c_1,6*$BNSZ($a0)
+ $ST $c_2,7*$BNSZ($a0)
+
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+ jr $ra
+ nop
+.end bn_mul_comba4
+___
+
+($a_4,$a_5,$a_6,$a_7)=($b_0,$b_1,$b_2,$b_3);
+
+$code.=<<___;
+
+.align 5
+.globl bn_sqr_comba8
+.ent bn_sqr_comba8
+bn_sqr_comba8:
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x8000f008,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $ra,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___;
+ .set reorder
+ $LD $a_0,0($a1)
+ $LD $a_1,$BNSZ($a1)
+ $LD $a_2,2*$BNSZ($a1)
+ $LD $a_3,3*$BNSZ($a1)
+
+ $MULTU $a_0,$a_0 # mul_add_c(a[0],b[0],c1,c2,c3);
+ $LD $a_4,4*$BNSZ($a1)
+ $LD $a_5,5*$BNSZ($a1)
+ $LD $a_6,6*$BNSZ($a1)
+ $LD $a_7,7*$BNSZ($a1)
+ mflo $c_1
+ mfhi $c_2
+ $ST $c_1,0($a0)
+
+ $MULTU $a_0,$a_1 # mul_add_c2(a[0],b[1],c2,c3,c1);
+ mflo $t_1
+ mfhi $t_2
+ slt $c_1,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_2,$a_0 # mul_add_c2(a[2],b[0],c3,c1,c2);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $c_3,$t_2,$at
+ $ST $c_2,$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_2,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_1,$a_1 # mul_add_c(a[1],b[1],c3,c1,c2);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_0,$a_3 # mul_add_c2(a[0],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,2*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_3,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_1,$a_2 # mul_add_c2(a[1],b[2],c1,c2,c3);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_3,$at
+ $MULTU $a_4,$a_0 # mul_add_c2(a[4],b[0],c2,c3,c1);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,3*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_1,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_3,$a_1 # mul_add_c2(a[3],b[1],c2,c3,c1);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_1,$at
+ $MULTU $a_2,$a_2 # mul_add_c(a[2],b[2],c2,c3,c1);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_0,$a_5 # mul_add_c2(a[0],b[5],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,4*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_2,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_1,$a_4 # mul_add_c2(a[1],b[4],c3,c1,c2);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_2,$at
+ $MULTU $a_2,$a_3 # mul_add_c2(a[2],b[3],c3,c1,c2);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $MULTU $a_6,$a_0 # mul_add_c2(a[6],b[0],c1,c2,c3);
+ $ADDU $c_2,$at
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,5*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_3,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_5,$a_1 # mul_add_c2(a[5],b[1],c1,c2,c3);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_3,$at
+ $MULTU $a_4,$a_2 # mul_add_c2(a[4],b[2],c1,c2,c3);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_3,$at
+ $MULTU $a_3,$a_3 # mul_add_c(a[3],b[3],c1,c2,c3);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_0,$a_7 # mul_add_c2(a[0],b[7],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,6*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_1,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_1,$a_6 # mul_add_c2(a[1],b[6],c2,c3,c1);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_1,$at
+ $MULTU $a_2,$a_5 # mul_add_c2(a[2],b[5],c2,c3,c1);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_1,$at
+ $MULTU $a_3,$a_4 # mul_add_c2(a[3],b[4],c2,c3,c1);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_1,$at
+ $MULTU $a_7,$a_1 # mul_add_c2(a[7],b[1],c3,c1,c2);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,7*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_2,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_6,$a_2 # mul_add_c2(a[6],b[2],c3,c1,c2);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_2,$at
+ $MULTU $a_5,$a_3 # mul_add_c2(a[5],b[3],c3,c1,c2);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_2,$at
+ $MULTU $a_4,$a_4 # mul_add_c(a[4],b[4],c3,c1,c2);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_2,$a_7 # mul_add_c2(a[2],b[7],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,8*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_3,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_3,$a_6 # mul_add_c2(a[3],b[6],c1,c2,c3);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_3,$at
+ $MULTU $a_4,$a_5 # mul_add_c2(a[4],b[5],c1,c2,c3);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_3,$at
+ $MULTU $a_7,$a_3 # mul_add_c2(a[7],b[3],c2,c3,c1);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,9*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_1,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_6,$a_4 # mul_add_c2(a[6],b[4],c2,c3,c1);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_1,$at
+ $MULTU $a_5,$a_5 # mul_add_c(a[5],b[5],c2,c3,c1);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_4,$a_7 # mul_add_c2(a[4],b[7],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,10*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_2,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_5,$a_6 # mul_add_c2(a[5],b[6],c3,c1,c2);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_2,$at
+ $MULTU $a_7,$a_5 # mul_add_c2(a[7],b[5],c1,c2,c3);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,11*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_3,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_6,$a_6 # mul_add_c(a[6],b[6],c1,c2,c3);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $MULTU $a_6,$a_7 # mul_add_c2(a[6],b[7],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,12*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_1,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_7,$a_7 # mul_add_c(a[7],b[7],c3,c1,c2);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,13*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ $ST $c_3,14*$BNSZ($a0)
+ $ST $c_1,15*$BNSZ($a0)
+
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+ jr $ra
+ nop
+.end bn_sqr_comba8
+
+.align 5
+.globl bn_sqr_comba4
+.ent bn_sqr_comba4
+bn_sqr_comba4:
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ .frame $sp,6*$SZREG,$ra
+ .mask 0x8000f008,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,6*$SZREG
+ $REG_S $ra,5*$SZREG($sp)
+ $REG_S $t3,4*$SZREG($sp)
+ $REG_S $t2,3*$SZREG($sp)
+ $REG_S $t1,2*$SZREG($sp)
+ $REG_S $t0,1*$SZREG($sp)
+ $REG_S $gp,0*$SZREG($sp)
+___
+$code.=<<___;
+ .set reorder
+ $LD $a_0,0($a1)
+ $LD $a_1,$BNSZ($a1)
+ $MULTU $a_0,$a_0 # mul_add_c(a[0],b[0],c1,c2,c3);
+ $LD $a_2,2*$BNSZ($a1)
+ $LD $a_3,3*$BNSZ($a1)
+ mflo $c_1
+ mfhi $c_2
+ $ST $c_1,0($a0)
+
+ $MULTU $a_0,$a_1 # mul_add_c2(a[0],b[1],c2,c3,c1);
+ mflo $t_1
+ mfhi $t_2
+ slt $c_1,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_2,$a_0 # mul_add_c2(a[2],b[0],c3,c1,c2);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $c_3,$t_2,$at
+ $ST $c_2,$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_2,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_1,$a_1 # mul_add_c(a[1],b[1],c3,c1,c2);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $MULTU $a_0,$a_3 # mul_add_c2(a[0],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,2*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_3,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_1,$a_2 # mul_add_c(a2[1],b[2],c1,c2,c3);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ mflo $t_1
+ mfhi $t_2
+ slt $at,$t_2,$zero
+ $ADDU $c_3,$at
+ $MULTU $a_3,$a_1 # mul_add_c2(a[3],b[1],c2,c3,c1);
+ $SLL $t_2,1
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,3*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_1,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_2,$a_2 # mul_add_c(a[2],b[2],c2,c3,c1);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+ $MULTU $a_2,$a_3 # mul_add_c2(a[2],b[3],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,4*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ slt $c_2,$t_2,$zero
+ $SLL $t_2,1
+ $MULTU $a_3,$a_3 # mul_add_c(a[3],b[3],c1,c2,c3);
+ slt $a2,$t_1,$zero
+ $ADDU $t_2,$a2
+ $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,5*$BNSZ($a0)
+
+ mflo $t_1
+ mfhi $t_2
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+ $ST $c_1,6*$BNSZ($a0)
+ $ST $c_2,7*$BNSZ($a0)
+
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $t3,4*$SZREG($sp)
+ $REG_L $t2,3*$SZREG($sp)
+ $REG_L $t1,2*$SZREG($sp)
+ $REG_L $t0,1*$SZREG($sp)
+ $REG_L $gp,0*$SZREG($sp)
+ $PTR_ADD $sp,6*$SZREG
+___
+$code.=<<___;
+ jr $ra
+ nop
+.end bn_sqr_comba4
+___
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/bn/asm/modexp512-x86_64.pl b/deps/openssl/openssl/crypto/bn/asm/modexp512-x86_64.pl
new file mode 100644
index 000000000..bfd6e9754
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/asm/modexp512-x86_64.pl
@@ -0,0 +1,1497 @@
+#!/usr/bin/env perl
+#
+# Copyright (c) 2010-2011 Intel Corp.
+# Author: Vinodh.Gopal@intel.com
+# Jim Guilford
+# Erdinc.Ozturk@intel.com
+# Maxim.Perminov@intel.com
+#
+# More information about algorithm used can be found at:
+# http://www.cse.buffalo.edu/srds2009/escs2009_submission_Gopal.pdf
+#
+# ====================================================================
+# Copyright (c) 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
+# licensing@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.
+# ====================================================================
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+use strict;
+my $code=".text\n\n";
+my $m=0;
+
+#
+# Define x512 macros
+#
+
+#MULSTEP_512_ADD MACRO x7, x6, x5, x4, x3, x2, x1, x0, dst, src1, src2, add_src, tmp1, tmp2
+#
+# uses rax, rdx, and args
+sub MULSTEP_512_ADD
+{
+ my ($x, $DST, $SRC2, $ASRC, $OP, $TMP)=@_;
+ my @X=@$x; # make a copy
+$code.=<<___;
+ mov (+8*0)($SRC2), %rax
+ mul $OP # rdx:rax = %OP * [0]
+ mov ($ASRC), $X[0]
+ add %rax, $X[0]
+ adc \$0, %rdx
+ mov $X[0], $DST
+___
+for(my $i=1;$i<8;$i++) {
+$code.=<<___;
+ mov %rdx, $TMP
+
+ mov (+8*$i)($SRC2), %rax
+ mul $OP # rdx:rax = %OP * [$i]
+ mov (+8*$i)($ASRC), $X[$i]
+ add %rax, $X[$i]
+ adc \$0, %rdx
+ add $TMP, $X[$i]
+ adc \$0, %rdx
+___
+}
+$code.=<<___;
+ mov %rdx, $X[0]
+___
+}
+
+#MULSTEP_512 MACRO x7, x6, x5, x4, x3, x2, x1, x0, dst, src2, src1_val, tmp
+#
+# uses rax, rdx, and args
+sub MULSTEP_512
+{
+ my ($x, $DST, $SRC2, $OP, $TMP)=@_;
+ my @X=@$x; # make a copy
+$code.=<<___;
+ mov (+8*0)($SRC2), %rax
+ mul $OP # rdx:rax = %OP * [0]
+ add %rax, $X[0]
+ adc \$0, %rdx
+ mov $X[0], $DST
+___
+for(my $i=1;$i<8;$i++) {
+$code.=<<___;
+ mov %rdx, $TMP
+
+ mov (+8*$i)($SRC2), %rax
+ mul $OP # rdx:rax = %OP * [$i]
+ add %rax, $X[$i]
+ adc \$0, %rdx
+ add $TMP, $X[$i]
+ adc \$0, %rdx
+___
+}
+$code.=<<___;
+ mov %rdx, $X[0]
+___
+}
+
+#
+# Swizzle Macros
+#
+
+# macro to copy data from flat space to swizzled table
+#MACRO swizzle pDst, pSrc, tmp1, tmp2
+# pDst and pSrc are modified
+sub swizzle
+{
+ my ($pDst, $pSrc, $cnt, $d0)=@_;
+$code.=<<___;
+ mov \$8, $cnt
+loop_$m:
+ mov ($pSrc), $d0
+ mov $d0#w, ($pDst)
+ shr \$16, $d0
+ mov $d0#w, (+64*1)($pDst)
+ shr \$16, $d0
+ mov $d0#w, (+64*2)($pDst)
+ shr \$16, $d0
+ mov $d0#w, (+64*3)($pDst)
+ lea 8($pSrc), $pSrc
+ lea 64*4($pDst), $pDst
+ dec $cnt
+ jnz loop_$m
+___
+
+ $m++;
+}
+
+# macro to copy data from swizzled table to flat space
+#MACRO unswizzle pDst, pSrc, tmp*3
+sub unswizzle
+{
+ my ($pDst, $pSrc, $cnt, $d0, $d1)=@_;
+$code.=<<___;
+ mov \$4, $cnt
+loop_$m:
+ movzxw (+64*3+256*0)($pSrc), $d0
+ movzxw (+64*3+256*1)($pSrc), $d1
+ shl \$16, $d0
+ shl \$16, $d1
+ mov (+64*2+256*0)($pSrc), $d0#w
+ mov (+64*2+256*1)($pSrc), $d1#w
+ shl \$16, $d0
+ shl \$16, $d1
+ mov (+64*1+256*0)($pSrc), $d0#w
+ mov (+64*1+256*1)($pSrc), $d1#w
+ shl \$16, $d0
+ shl \$16, $d1
+ mov (+64*0+256*0)($pSrc), $d0#w
+ mov (+64*0+256*1)($pSrc), $d1#w
+ mov $d0, (+8*0)($pDst)
+ mov $d1, (+8*1)($pDst)
+ lea 256*2($pSrc), $pSrc
+ lea 8*2($pDst), $pDst
+ sub \$1, $cnt
+ jnz loop_$m
+___
+
+ $m++;
+}
+
+#
+# Data Structures
+#
+
+# Reduce Data
+#
+#
+# Offset Value
+# 0C0 Carries
+# 0B8 X2[10]
+# 0B0 X2[9]
+# 0A8 X2[8]
+# 0A0 X2[7]
+# 098 X2[6]
+# 090 X2[5]
+# 088 X2[4]
+# 080 X2[3]
+# 078 X2[2]
+# 070 X2[1]
+# 068 X2[0]
+# 060 X1[12] P[10]
+# 058 X1[11] P[9] Z[8]
+# 050 X1[10] P[8] Z[7]
+# 048 X1[9] P[7] Z[6]
+# 040 X1[8] P[6] Z[5]
+# 038 X1[7] P[5] Z[4]
+# 030 X1[6] P[4] Z[3]
+# 028 X1[5] P[3] Z[2]
+# 020 X1[4] P[2] Z[1]
+# 018 X1[3] P[1] Z[0]
+# 010 X1[2] P[0] Y[2]
+# 008 X1[1] Q[1] Y[1]
+# 000 X1[0] Q[0] Y[0]
+
+my $X1_offset = 0; # 13 qwords
+my $X2_offset = $X1_offset + 13*8; # 11 qwords
+my $Carries_offset = $X2_offset + 11*8; # 1 qword
+my $Q_offset = 0; # 2 qwords
+my $P_offset = $Q_offset + 2*8; # 11 qwords
+my $Y_offset = 0; # 3 qwords
+my $Z_offset = $Y_offset + 3*8; # 9 qwords
+
+my $Red_Data_Size = $Carries_offset + 1*8; # (25 qwords)
+
+#
+# Stack Frame
+#
+#
+# offset value
+# ... <old stack contents>
+# ...
+# 280 Garray
+
+# 278 tmp16[15]
+# ... ...
+# 200 tmp16[0]
+
+# 1F8 tmp[7]
+# ... ...
+# 1C0 tmp[0]
+
+# 1B8 GT[7]
+# ... ...
+# 180 GT[0]
+
+# 178 Reduce Data
+# ... ...
+# 0B8 Reduce Data
+# 0B0 reserved
+# 0A8 reserved
+# 0A0 reserved
+# 098 reserved
+# 090 reserved
+# 088 reduce result addr
+# 080 exp[8]
+
+# ...
+# 048 exp[1]
+# 040 exp[0]
+
+# 038 reserved
+# 030 loop_idx
+# 028 pg
+# 020 i
+# 018 pData ; arg 4
+# 010 pG ; arg 2
+# 008 pResult ; arg 1
+# 000 rsp ; stack pointer before subtract
+
+my $rsp_offset = 0;
+my $pResult_offset = 8*1 + $rsp_offset;
+my $pG_offset = 8*1 + $pResult_offset;
+my $pData_offset = 8*1 + $pG_offset;
+my $i_offset = 8*1 + $pData_offset;
+my $pg_offset = 8*1 + $i_offset;
+my $loop_idx_offset = 8*1 + $pg_offset;
+my $reserved1_offset = 8*1 + $loop_idx_offset;
+my $exp_offset = 8*1 + $reserved1_offset;
+my $red_result_addr_offset= 8*9 + $exp_offset;
+my $reserved2_offset = 8*1 + $red_result_addr_offset;
+my $Reduce_Data_offset = 8*5 + $reserved2_offset;
+my $GT_offset = $Red_Data_Size + $Reduce_Data_offset;
+my $tmp_offset = 8*8 + $GT_offset;
+my $tmp16_offset = 8*8 + $tmp_offset;
+my $garray_offset = 8*16 + $tmp16_offset;
+my $mem_size = 8*8*32 + $garray_offset;
+
+#
+# Offsets within Reduce Data
+#
+#
+# struct MODF_2FOLD_MONT_512_C1_DATA {
+# UINT64 t[8][8];
+# UINT64 m[8];
+# UINT64 m1[8]; /* 2^768 % m */
+# UINT64 m2[8]; /* 2^640 % m */
+# UINT64 k1[2]; /* (- 1/m) % 2^128 */
+# };
+
+my $T = 0;
+my $M = 512; # = 8 * 8 * 8
+my $M1 = 576; # = 8 * 8 * 9 /* += 8 * 8 */
+my $M2 = 640; # = 8 * 8 * 10 /* += 8 * 8 */
+my $K1 = 704; # = 8 * 8 * 11 /* += 8 * 8 */
+
+#
+# FUNCTIONS
+#
+
+{{{
+#
+# MULADD_128x512 : Function to multiply 128-bits (2 qwords) by 512-bits (8 qwords)
+# and add 512-bits (8 qwords)
+# to get 640 bits (10 qwords)
+# Input: 128-bit mul source: [rdi+8*1], rbp
+# 512-bit mul source: [rsi+8*n]
+# 512-bit add source: r15, r14, ..., r9, r8
+# Output: r9, r8, r15, r14, r13, r12, r11, r10, [rcx+8*1], [rcx+8*0]
+# Clobbers all regs except: rcx, rsi, rdi
+$code.=<<___;
+.type MULADD_128x512,\@abi-omnipotent
+.align 16
+MULADD_128x512:
+___
+ &MULSTEP_512([map("%r$_",(8..15))], "(+8*0)(%rcx)", "%rsi", "%rbp", "%rbx");
+$code.=<<___;
+ mov (+8*1)(%rdi), %rbp
+___
+ &MULSTEP_512([map("%r$_",(9..15,8))], "(+8*1)(%rcx)", "%rsi", "%rbp", "%rbx");
+$code.=<<___;
+ ret
+.size MULADD_128x512,.-MULADD_128x512
+___
+}}}
+
+{{{
+#MULADD_256x512 MACRO pDst, pA, pB, OP, TMP, X7, X6, X5, X4, X3, X2, X1, X0
+#
+# Inputs: pDst: Destination (768 bits, 12 qwords)
+# pA: Multiplicand (1024 bits, 16 qwords)
+# pB: Multiplicand (512 bits, 8 qwords)
+# Dst = Ah * B + Al
+# where Ah is (in qwords) A[15:12] (256 bits) and Al is A[7:0] (512 bits)
+# Results in X3 X2 X1 X0 X7 X6 X5 X4 Dst[3:0]
+# Uses registers: arguments, RAX, RDX
+sub MULADD_256x512
+{
+ my ($pDst, $pA, $pB, $OP, $TMP, $X)=@_;
+$code.=<<___;
+ mov (+8*12)($pA), $OP
+___
+ &MULSTEP_512_ADD($X, "(+8*0)($pDst)", $pB, $pA, $OP, $TMP);
+ push(@$X,shift(@$X));
+
+$code.=<<___;
+ mov (+8*13)($pA), $OP
+___
+ &MULSTEP_512($X, "(+8*1)($pDst)", $pB, $OP, $TMP);
+ push(@$X,shift(@$X));
+
+$code.=<<___;
+ mov (+8*14)($pA), $OP
+___
+ &MULSTEP_512($X, "(+8*2)($pDst)", $pB, $OP, $TMP);
+ push(@$X,shift(@$X));
+
+$code.=<<___;
+ mov (+8*15)($pA), $OP
+___
+ &MULSTEP_512($X, "(+8*3)($pDst)", $pB, $OP, $TMP);
+ push(@$X,shift(@$X));
+}
+
+#
+# mont_reduce(UINT64 *x, /* 1024 bits, 16 qwords */
+# UINT64 *m, /* 512 bits, 8 qwords */
+# MODF_2FOLD_MONT_512_C1_DATA *data,
+# UINT64 *r) /* 512 bits, 8 qwords */
+# Input: x (number to be reduced): tmp16 (Implicit)
+# m (modulus): [pM] (Implicit)
+# data (reduce data): [pData] (Implicit)
+# Output: r (result): Address in [red_res_addr]
+# result also in: r9, r8, r15, r14, r13, r12, r11, r10
+
+my @X=map("%r$_",(8..15));
+
+$code.=<<___;
+.type mont_reduce,\@abi-omnipotent
+.align 16
+mont_reduce:
+___
+
+my $STACK_DEPTH = 8;
+ #
+ # X1 = Xh * M1 + Xl
+$code.=<<___;
+ lea (+$Reduce_Data_offset+$X1_offset+$STACK_DEPTH)(%rsp), %rdi # pX1 (Dst) 769 bits, 13 qwords
+ mov (+$pData_offset+$STACK_DEPTH)(%rsp), %rsi # pM1 (Bsrc) 512 bits, 8 qwords
+ add \$$M1, %rsi
+ lea (+$tmp16_offset+$STACK_DEPTH)(%rsp), %rcx # X (Asrc) 1024 bits, 16 qwords
+
+___
+
+ &MULADD_256x512("%rdi", "%rcx", "%rsi", "%rbp", "%rbx", \@X); # rotates @X 4 times
+ # results in r11, r10, r9, r8, r15, r14, r13, r12, X1[3:0]
+
+$code.=<<___;
+ xor %rax, %rax
+ # X1 += xl
+ add (+8*8)(%rcx), $X[4]
+ adc (+8*9)(%rcx), $X[5]
+ adc (+8*10)(%rcx), $X[6]
+ adc (+8*11)(%rcx), $X[7]
+ adc \$0, %rax
+ # X1 is now rax, r11-r8, r15-r12, tmp16[3:0]
+
+ #
+ # check for carry ;; carry stored in rax
+ mov $X[4], (+8*8)(%rdi) # rdi points to X1
+ mov $X[5], (+8*9)(%rdi)
+ mov $X[6], %rbp
+ mov $X[7], (+8*11)(%rdi)
+
+ mov %rax, (+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp)
+
+ mov (+8*0)(%rdi), $X[4]
+ mov (+8*1)(%rdi), $X[5]
+ mov (+8*2)(%rdi), $X[6]
+ mov (+8*3)(%rdi), $X[7]
+
+ # X1 is now stored in: X1[11], rbp, X1[9:8], r15-r8
+ # rdi -> X1
+ # rsi -> M1
+
+ #
+ # X2 = Xh * M2 + Xl
+ # do first part (X2 = Xh * M2)
+ add \$8*10, %rdi # rdi -> pXh ; 128 bits, 2 qwords
+ # Xh is actually { [rdi+8*1], rbp }
+ add \$`$M2-$M1`, %rsi # rsi -> M2
+ lea (+$Reduce_Data_offset+$X2_offset+$STACK_DEPTH)(%rsp), %rcx # rcx -> pX2 ; 641 bits, 11 qwords
+___
+ unshift(@X,pop(@X)); unshift(@X,pop(@X));
+$code.=<<___;
+
+ call MULADD_128x512 # args in rcx, rdi / rbp, rsi, r15-r8
+ # result in r9, r8, r15, r14, r13, r12, r11, r10, X2[1:0]
+ mov (+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp), %rax
+
+ # X2 += Xl
+ add (+8*8-8*10)(%rdi), $X[6] # (-8*10) is to adjust rdi -> Xh to Xl
+ adc (+8*9-8*10)(%rdi), $X[7]
+ mov $X[6], (+8*8)(%rcx)
+ mov $X[7], (+8*9)(%rcx)
+
+ adc %rax, %rax
+ mov %rax, (+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp)
+
+ lea (+$Reduce_Data_offset+$Q_offset+$STACK_DEPTH)(%rsp), %rdi # rdi -> pQ ; 128 bits, 2 qwords
+ add \$`$K1-$M2`, %rsi # rsi -> pK1 ; 128 bits, 2 qwords
+
+ # MUL_128x128t128 rdi, rcx, rsi ; Q = X2 * K1 (bottom half)
+ # B1:B0 = rsi[1:0] = K1[1:0]
+ # A1:A0 = rcx[1:0] = X2[1:0]
+ # Result = rdi[1],rbp = Q[1],rbp
+ mov (%rsi), %r8 # B0
+ mov (+8*1)(%rsi), %rbx # B1
+
+ mov (%rcx), %rax # A0
+ mul %r8 # B0
+ mov %rax, %rbp
+ mov %rdx, %r9
+
+ mov (+8*1)(%rcx), %rax # A1
+ mul %r8 # B0
+ add %rax, %r9
+
+ mov (%rcx), %rax # A0
+ mul %rbx # B1
+ add %rax, %r9
+
+ mov %r9, (+8*1)(%rdi)
+ # end MUL_128x128t128
+
+ sub \$`$K1-$M`, %rsi
+
+ mov (%rcx), $X[6]
+ mov (+8*1)(%rcx), $X[7] # r9:r8 = X2[1:0]
+
+ call MULADD_128x512 # args in rcx, rdi / rbp, rsi, r15-r8
+ # result in r9, r8, r15, r14, r13, r12, r11, r10, X2[1:0]
+
+ # load first half of m to rdx, rdi, rbx, rax
+ # moved this here for efficiency
+ mov (+8*0)(%rsi), %rax
+ mov (+8*1)(%rsi), %rbx
+ mov (+8*2)(%rsi), %rdi
+ mov (+8*3)(%rsi), %rdx
+
+ # continue with reduction
+ mov (+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp), %rbp
+
+ add (+8*8)(%rcx), $X[6]
+ adc (+8*9)(%rcx), $X[7]
+
+ #accumulate the final carry to rbp
+ adc %rbp, %rbp
+
+ # Add in overflow corrections: R = (X2>>128) += T[overflow]
+ # R = {r9, r8, r15, r14, ..., r10}
+ shl \$3, %rbp
+ mov (+$pData_offset+$STACK_DEPTH)(%rsp), %rcx # rsi -> Data (and points to T)
+ add %rcx, %rbp # pT ; 512 bits, 8 qwords, spread out
+
+ # rsi will be used to generate a mask after the addition
+ xor %rsi, %rsi
+
+ add (+8*8*0)(%rbp), $X[0]
+ adc (+8*8*1)(%rbp), $X[1]
+ adc (+8*8*2)(%rbp), $X[2]
+ adc (+8*8*3)(%rbp), $X[3]
+ adc (+8*8*4)(%rbp), $X[4]
+ adc (+8*8*5)(%rbp), $X[5]
+ adc (+8*8*6)(%rbp), $X[6]
+ adc (+8*8*7)(%rbp), $X[7]
+
+ # if there is a carry: rsi = 0xFFFFFFFFFFFFFFFF
+ # if carry is clear: rsi = 0x0000000000000000
+ sbb \$0, %rsi
+
+ # if carry is clear, subtract 0. Otherwise, subtract 256 bits of m
+ and %rsi, %rax
+ and %rsi, %rbx
+ and %rsi, %rdi
+ and %rsi, %rdx
+
+ mov \$1, %rbp
+ sub %rax, $X[0]
+ sbb %rbx, $X[1]
+ sbb %rdi, $X[2]
+ sbb %rdx, $X[3]
+
+ # if there is a borrow: rbp = 0
+ # if there is no borrow: rbp = 1
+ # this is used to save the borrows in between the first half and the 2nd half of the subtraction of m
+ sbb \$0, %rbp
+
+ #load second half of m to rdx, rdi, rbx, rax
+
+ add \$$M, %rcx
+ mov (+8*4)(%rcx), %rax
+ mov (+8*5)(%rcx), %rbx
+ mov (+8*6)(%rcx), %rdi
+ mov (+8*7)(%rcx), %rdx
+
+ # use the rsi mask as before
+ # if carry is clear, subtract 0. Otherwise, subtract 256 bits of m
+ and %rsi, %rax
+ and %rsi, %rbx
+ and %rsi, %rdi
+ and %rsi, %rdx
+
+ # if rbp = 0, there was a borrow before, it is moved to the carry flag
+ # if rbp = 1, there was not a borrow before, carry flag is cleared
+ sub \$1, %rbp
+
+ sbb %rax, $X[4]
+ sbb %rbx, $X[5]
+ sbb %rdi, $X[6]
+ sbb %rdx, $X[7]
+
+ # write R back to memory
+
+ mov (+$red_result_addr_offset+$STACK_DEPTH)(%rsp), %rsi
+ mov $X[0], (+8*0)(%rsi)
+ mov $X[1], (+8*1)(%rsi)
+ mov $X[2], (+8*2)(%rsi)
+ mov $X[3], (+8*3)(%rsi)
+ mov $X[4], (+8*4)(%rsi)
+ mov $X[5], (+8*5)(%rsi)
+ mov $X[6], (+8*6)(%rsi)
+ mov $X[7], (+8*7)(%rsi)
+
+ ret
+.size mont_reduce,.-mont_reduce
+___
+}}}
+
+{{{
+#MUL_512x512 MACRO pDst, pA, pB, x7, x6, x5, x4, x3, x2, x1, x0, tmp*2
+#
+# Inputs: pDst: Destination (1024 bits, 16 qwords)
+# pA: Multiplicand (512 bits, 8 qwords)
+# pB: Multiplicand (512 bits, 8 qwords)
+# Uses registers rax, rdx, args
+# B operand in [pB] and also in x7...x0
+sub MUL_512x512
+{
+ my ($pDst, $pA, $pB, $x, $OP, $TMP, $pDst_o)=@_;
+ my ($pDst, $pDst_o) = ($pDst =~ m/([^+]*)\+?(.*)?/);
+ my @X=@$x; # make a copy
+
+$code.=<<___;
+ mov (+8*0)($pA), $OP
+
+ mov $X[0], %rax
+ mul $OP # rdx:rax = %OP * [0]
+ mov %rax, (+$pDst_o+8*0)($pDst)
+ mov %rdx, $X[0]
+___
+for(my $i=1;$i<8;$i++) {
+$code.=<<___;
+ mov $X[$i], %rax
+ mul $OP # rdx:rax = %OP * [$i]
+ add %rax, $X[$i-1]
+ adc \$0, %rdx
+ mov %rdx, $X[$i]
+___
+}
+
+for(my $i=1;$i<8;$i++) {
+$code.=<<___;
+ mov (+8*$i)($pA), $OP
+___
+
+ &MULSTEP_512(\@X, "(+$pDst_o+8*$i)($pDst)", $pB, $OP, $TMP);
+ push(@X,shift(@X));
+}
+
+$code.=<<___;
+ mov $X[0], (+$pDst_o+8*8)($pDst)
+ mov $X[1], (+$pDst_o+8*9)($pDst)
+ mov $X[2], (+$pDst_o+8*10)($pDst)
+ mov $X[3], (+$pDst_o+8*11)($pDst)
+ mov $X[4], (+$pDst_o+8*12)($pDst)
+ mov $X[5], (+$pDst_o+8*13)($pDst)
+ mov $X[6], (+$pDst_o+8*14)($pDst)
+ mov $X[7], (+$pDst_o+8*15)($pDst)
+___
+}
+
+#
+# mont_mul_a3b : subroutine to compute (Src1 * Src2) % M (all 512-bits)
+# Input: src1: Address of source 1: rdi
+# src2: Address of source 2: rsi
+# Output: dst: Address of destination: [red_res_addr]
+# src2 and result also in: r9, r8, r15, r14, r13, r12, r11, r10
+# Temp: Clobbers [tmp16], all registers
+$code.=<<___;
+.type mont_mul_a3b,\@abi-omnipotent
+.align 16
+mont_mul_a3b:
+ #
+ # multiply tmp = src1 * src2
+ # For multiply: dst = rcx, src1 = rdi, src2 = rsi
+ # stack depth is extra 8 from call
+___
+ &MUL_512x512("%rsp+$tmp16_offset+8", "%rdi", "%rsi", [map("%r$_",(10..15,8..9))], "%rbp", "%rbx");
+$code.=<<___;
+ #
+ # Dst = tmp % m
+ # Call reduce(tmp, m, data, dst)
+
+ # tail recursion optimization: jmp to mont_reduce and return from there
+ jmp mont_reduce
+ # call mont_reduce
+ # ret
+.size mont_mul_a3b,.-mont_mul_a3b
+___
+}}}
+
+{{{
+#SQR_512 MACRO pDest, pA, x7, x6, x5, x4, x3, x2, x1, x0, tmp*4
+#
+# Input in memory [pA] and also in x7...x0
+# Uses all argument registers plus rax and rdx
+#
+# This version computes all of the off-diagonal terms into memory,
+# and then it adds in the diagonal terms
+
+sub SQR_512
+{
+ my ($pDst, $pA, $x, $A, $tmp, $x7, $x6, $pDst_o)=@_;
+ my ($pDst, $pDst_o) = ($pDst =~ m/([^+]*)\+?(.*)?/);
+ my @X=@$x; # make a copy
+$code.=<<___;
+ # ------------------
+ # first pass 01...07
+ # ------------------
+ mov $X[0], $A
+
+ mov $X[1],%rax
+ mul $A
+ mov %rax, (+$pDst_o+8*1)($pDst)
+___
+for(my $i=2;$i<8;$i++) {
+$code.=<<___;
+ mov %rdx, $X[$i-2]
+ mov $X[$i],%rax
+ mul $A
+ add %rax, $X[$i-2]
+ adc \$0, %rdx
+___
+}
+$code.=<<___;
+ mov %rdx, $x7
+
+ mov $X[0], (+$pDst_o+8*2)($pDst)
+
+ # ------------------
+ # second pass 12...17
+ # ------------------
+
+ mov (+8*1)($pA), $A
+
+ mov (+8*2)($pA),%rax
+ mul $A
+ add %rax, $X[1]
+ adc \$0, %rdx
+ mov $X[1], (+$pDst_o+8*3)($pDst)
+
+ mov %rdx, $X[0]
+ mov (+8*3)($pA),%rax
+ mul $A
+ add %rax, $X[2]
+ adc \$0, %rdx
+ add $X[0], $X[2]
+ adc \$0, %rdx
+ mov $X[2], (+$pDst_o+8*4)($pDst)
+
+ mov %rdx, $X[0]
+ mov (+8*4)($pA),%rax
+ mul $A
+ add %rax, $X[3]
+ adc \$0, %rdx
+ add $X[0], $X[3]
+ adc \$0, %rdx
+
+ mov %rdx, $X[0]
+ mov (+8*5)($pA),%rax
+ mul $A
+ add %rax, $X[4]
+ adc \$0, %rdx
+ add $X[0], $X[4]
+ adc \$0, %rdx
+
+ mov %rdx, $X[0]
+ mov $X[6],%rax
+ mul $A
+ add %rax, $X[5]
+ adc \$0, %rdx
+ add $X[0], $X[5]
+ adc \$0, %rdx
+
+ mov %rdx, $X[0]
+ mov $X[7],%rax
+ mul $A
+ add %rax, $x7
+ adc \$0, %rdx
+ add $X[0], $x7
+ adc \$0, %rdx
+
+ mov %rdx, $X[1]
+
+ # ------------------
+ # third pass 23...27
+ # ------------------
+ mov (+8*2)($pA), $A
+
+ mov (+8*3)($pA),%rax
+ mul $A
+ add %rax, $X[3]
+ adc \$0, %rdx
+ mov $X[3], (+$pDst_o+8*5)($pDst)
+
+ mov %rdx, $X[0]
+ mov (+8*4)($pA),%rax
+ mul $A
+ add %rax, $X[4]
+ adc \$0, %rdx
+ add $X[0], $X[4]
+ adc \$0, %rdx
+ mov $X[4], (+$pDst_o+8*6)($pDst)
+
+ mov %rdx, $X[0]
+ mov (+8*5)($pA),%rax
+ mul $A
+ add %rax, $X[5]
+ adc \$0, %rdx
+ add $X[0], $X[5]
+ adc \$0, %rdx
+
+ mov %rdx, $X[0]
+ mov $X[6],%rax
+ mul $A
+ add %rax, $x7
+ adc \$0, %rdx
+ add $X[0], $x7
+ adc \$0, %rdx
+
+ mov %rdx, $X[0]
+ mov $X[7],%rax
+ mul $A
+ add %rax, $X[1]
+ adc \$0, %rdx
+ add $X[0], $X[1]
+ adc \$0, %rdx
+
+ mov %rdx, $X[2]
+
+ # ------------------
+ # fourth pass 34...37
+ # ------------------
+
+ mov (+8*3)($pA), $A
+
+ mov (+8*4)($pA),%rax
+ mul $A
+ add %rax, $X[5]
+ adc \$0, %rdx
+ mov $X[5], (+$pDst_o+8*7)($pDst)
+
+ mov %rdx, $X[0]
+ mov (+8*5)($pA),%rax
+ mul $A
+ add %rax, $x7
+ adc \$0, %rdx
+ add $X[0], $x7
+ adc \$0, %rdx
+ mov $x7, (+$pDst_o+8*8)($pDst)
+
+ mov %rdx, $X[0]
+ mov $X[6],%rax
+ mul $A
+ add %rax, $X[1]
+ adc \$0, %rdx
+ add $X[0], $X[1]
+ adc \$0, %rdx
+
+ mov %rdx, $X[0]
+ mov $X[7],%rax
+ mul $A
+ add %rax, $X[2]
+ adc \$0, %rdx
+ add $X[0], $X[2]
+ adc \$0, %rdx
+
+ mov %rdx, $X[5]
+
+ # ------------------
+ # fifth pass 45...47
+ # ------------------
+ mov (+8*4)($pA), $A
+
+ mov (+8*5)($pA),%rax
+ mul $A
+ add %rax, $X[1]
+ adc \$0, %rdx
+ mov $X[1], (+$pDst_o+8*9)($pDst)
+
+ mov %rdx, $X[0]
+ mov $X[6],%rax
+ mul $A
+ add %rax, $X[2]
+ adc \$0, %rdx
+ add $X[0], $X[2]
+ adc \$0, %rdx
+ mov $X[2], (+$pDst_o+8*10)($pDst)
+
+ mov %rdx, $X[0]
+ mov $X[7],%rax
+ mul $A
+ add %rax, $X[5]
+ adc \$0, %rdx
+ add $X[0], $X[5]
+ adc \$0, %rdx
+
+ mov %rdx, $X[1]
+
+ # ------------------
+ # sixth pass 56...57
+ # ------------------
+ mov (+8*5)($pA), $A
+
+ mov $X[6],%rax
+ mul $A
+ add %rax, $X[5]
+ adc \$0, %rdx
+ mov $X[5], (+$pDst_o+8*11)($pDst)
+
+ mov %rdx, $X[0]
+ mov $X[7],%rax
+ mul $A
+ add %rax, $X[1]
+ adc \$0, %rdx
+ add $X[0], $X[1]
+ adc \$0, %rdx
+ mov $X[1], (+$pDst_o+8*12)($pDst)
+
+ mov %rdx, $X[2]
+
+ # ------------------
+ # seventh pass 67
+ # ------------------
+ mov $X[6], $A
+
+ mov $X[7],%rax
+ mul $A
+ add %rax, $X[2]
+ adc \$0, %rdx
+ mov $X[2], (+$pDst_o+8*13)($pDst)
+
+ mov %rdx, (+$pDst_o+8*14)($pDst)
+
+ # start finalize (add in squares, and double off-terms)
+ mov (+$pDst_o+8*1)($pDst), $X[0]
+ mov (+$pDst_o+8*2)($pDst), $X[1]
+ mov (+$pDst_o+8*3)($pDst), $X[2]
+ mov (+$pDst_o+8*4)($pDst), $X[3]
+ mov (+$pDst_o+8*5)($pDst), $X[4]
+ mov (+$pDst_o+8*6)($pDst), $X[5]
+
+ mov (+8*3)($pA), %rax
+ mul %rax
+ mov %rax, $x6
+ mov %rdx, $X[6]
+
+ add $X[0], $X[0]
+ adc $X[1], $X[1]
+ adc $X[2], $X[2]
+ adc $X[3], $X[3]
+ adc $X[4], $X[4]
+ adc $X[5], $X[5]
+ adc \$0, $X[6]
+
+ mov (+8*0)($pA), %rax
+ mul %rax
+ mov %rax, (+$pDst_o+8*0)($pDst)
+ mov %rdx, $A
+
+ mov (+8*1)($pA), %rax
+ mul %rax
+
+ add $A, $X[0]
+ adc %rax, $X[1]
+ adc \$0, %rdx
+
+ mov %rdx, $A
+ mov $X[0], (+$pDst_o+8*1)($pDst)
+ mov $X[1], (+$pDst_o+8*2)($pDst)
+
+ mov (+8*2)($pA), %rax
+ mul %rax
+
+ add $A, $X[2]
+ adc %rax, $X[3]
+ adc \$0, %rdx
+
+ mov %rdx, $A
+
+ mov $X[2], (+$pDst_o+8*3)($pDst)
+ mov $X[3], (+$pDst_o+8*4)($pDst)
+
+ xor $tmp, $tmp
+ add $A, $X[4]
+ adc $x6, $X[5]
+ adc \$0, $tmp
+
+ mov $X[4], (+$pDst_o+8*5)($pDst)
+ mov $X[5], (+$pDst_o+8*6)($pDst)
+
+ # %%tmp has 0/1 in column 7
+ # %%A6 has a full value in column 7
+
+ mov (+$pDst_o+8*7)($pDst), $X[0]
+ mov (+$pDst_o+8*8)($pDst), $X[1]
+ mov (+$pDst_o+8*9)($pDst), $X[2]
+ mov (+$pDst_o+8*10)($pDst), $X[3]
+ mov (+$pDst_o+8*11)($pDst), $X[4]
+ mov (+$pDst_o+8*12)($pDst), $X[5]
+ mov (+$pDst_o+8*13)($pDst), $x6
+ mov (+$pDst_o+8*14)($pDst), $x7
+
+ mov $X[7], %rax
+ mul %rax
+ mov %rax, $X[7]
+ mov %rdx, $A
+
+ add $X[0], $X[0]
+ adc $X[1], $X[1]
+ adc $X[2], $X[2]
+ adc $X[3], $X[3]
+ adc $X[4], $X[4]
+ adc $X[5], $X[5]
+ adc $x6, $x6
+ adc $x7, $x7
+ adc \$0, $A
+
+ add $tmp, $X[0]
+
+ mov (+8*4)($pA), %rax
+ mul %rax
+
+ add $X[6], $X[0]
+ adc %rax, $X[1]
+ adc \$0, %rdx
+
+ mov %rdx, $tmp
+
+ mov $X[0], (+$pDst_o+8*7)($pDst)
+ mov $X[1], (+$pDst_o+8*8)($pDst)
+
+ mov (+8*5)($pA), %rax
+ mul %rax
+
+ add $tmp, $X[2]
+ adc %rax, $X[3]
+ adc \$0, %rdx
+
+ mov %rdx, $tmp
+
+ mov $X[2], (+$pDst_o+8*9)($pDst)
+ mov $X[3], (+$pDst_o+8*10)($pDst)
+
+ mov (+8*6)($pA), %rax
+ mul %rax
+
+ add $tmp, $X[4]
+ adc %rax, $X[5]
+ adc \$0, %rdx
+
+ mov $X[4], (+$pDst_o+8*11)($pDst)
+ mov $X[5], (+$pDst_o+8*12)($pDst)
+
+ add %rdx, $x6
+ adc $X[7], $x7
+ adc \$0, $A
+
+ mov $x6, (+$pDst_o+8*13)($pDst)
+ mov $x7, (+$pDst_o+8*14)($pDst)
+ mov $A, (+$pDst_o+8*15)($pDst)
+___
+}
+
+#
+# sqr_reduce: subroutine to compute Result = reduce(Result * Result)
+#
+# input and result also in: r9, r8, r15, r14, r13, r12, r11, r10
+#
+$code.=<<___;
+.type sqr_reduce,\@abi-omnipotent
+.align 16
+sqr_reduce:
+ mov (+$pResult_offset+8)(%rsp), %rcx
+___
+ &SQR_512("%rsp+$tmp16_offset+8", "%rcx", [map("%r$_",(10..15,8..9))], "%rbx", "%rbp", "%rsi", "%rdi");
+$code.=<<___;
+ # tail recursion optimization: jmp to mont_reduce and return from there
+ jmp mont_reduce
+ # call mont_reduce
+ # ret
+.size sqr_reduce,.-sqr_reduce
+___
+}}}
+
+#
+# MAIN FUNCTION
+#
+
+#mod_exp_512(UINT64 *result, /* 512 bits, 8 qwords */
+# UINT64 *g, /* 512 bits, 8 qwords */
+# UINT64 *exp, /* 512 bits, 8 qwords */
+# struct mod_ctx_512 *data)
+
+# window size = 5
+# table size = 2^5 = 32
+#table_entries equ 32
+#table_size equ table_entries * 8
+$code.=<<___;
+.globl mod_exp_512
+.type mod_exp_512,\@function,4
+mod_exp_512:
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ # adjust stack down and then align it with cache boundary
+ mov %rsp, %r8
+ sub \$$mem_size, %rsp
+ and \$-64, %rsp
+
+ # store previous stack pointer and arguments
+ mov %r8, (+$rsp_offset)(%rsp)
+ mov %rdi, (+$pResult_offset)(%rsp)
+ mov %rsi, (+$pG_offset)(%rsp)
+ mov %rcx, (+$pData_offset)(%rsp)
+.Lbody:
+ # transform g into montgomery space
+ # GT = reduce(g * C2) = reduce(g * (2^256))
+ # reduce expects to have the input in [tmp16]
+ pxor %xmm4, %xmm4
+ movdqu (+16*0)(%rsi), %xmm0
+ movdqu (+16*1)(%rsi), %xmm1
+ movdqu (+16*2)(%rsi), %xmm2
+ movdqu (+16*3)(%rsi), %xmm3
+ movdqa %xmm4, (+$tmp16_offset+16*0)(%rsp)
+ movdqa %xmm4, (+$tmp16_offset+16*1)(%rsp)
+ movdqa %xmm4, (+$tmp16_offset+16*6)(%rsp)
+ movdqa %xmm4, (+$tmp16_offset+16*7)(%rsp)
+ movdqa %xmm0, (+$tmp16_offset+16*2)(%rsp)
+ movdqa %xmm1, (+$tmp16_offset+16*3)(%rsp)
+ movdqa %xmm2, (+$tmp16_offset+16*4)(%rsp)
+ movdqa %xmm3, (+$tmp16_offset+16*5)(%rsp)
+
+ # load pExp before rdx gets blown away
+ movdqu (+16*0)(%rdx), %xmm0
+ movdqu (+16*1)(%rdx), %xmm1
+ movdqu (+16*2)(%rdx), %xmm2
+ movdqu (+16*3)(%rdx), %xmm3
+
+ lea (+$GT_offset)(%rsp), %rbx
+ mov %rbx, (+$red_result_addr_offset)(%rsp)
+ call mont_reduce
+
+ # Initialize tmp = C
+ lea (+$tmp_offset)(%rsp), %rcx
+ xor %rax, %rax
+ mov %rax, (+8*0)(%rcx)
+ mov %rax, (+8*1)(%rcx)
+ mov %rax, (+8*3)(%rcx)
+ mov %rax, (+8*4)(%rcx)
+ mov %rax, (+8*5)(%rcx)
+ mov %rax, (+8*6)(%rcx)
+ mov %rax, (+8*7)(%rcx)
+ mov %rax, (+$exp_offset+8*8)(%rsp)
+ movq \$1, (+8*2)(%rcx)
+
+ lea (+$garray_offset)(%rsp), %rbp
+ mov %rcx, %rsi # pTmp
+ mov %rbp, %rdi # Garray[][0]
+___
+
+ &swizzle("%rdi", "%rcx", "%rax", "%rbx");
+
+ # for (rax = 31; rax != 0; rax--) {
+ # tmp = reduce(tmp * G)
+ # swizzle(pg, tmp);
+ # pg += 2; }
+$code.=<<___;
+ mov \$31, %rax
+ mov %rax, (+$i_offset)(%rsp)
+ mov %rbp, (+$pg_offset)(%rsp)
+ # rsi -> pTmp
+ mov %rsi, (+$red_result_addr_offset)(%rsp)
+ mov (+8*0)(%rsi), %r10
+ mov (+8*1)(%rsi), %r11
+ mov (+8*2)(%rsi), %r12
+ mov (+8*3)(%rsi), %r13
+ mov (+8*4)(%rsi), %r14
+ mov (+8*5)(%rsi), %r15
+ mov (+8*6)(%rsi), %r8
+ mov (+8*7)(%rsi), %r9
+init_loop:
+ lea (+$GT_offset)(%rsp), %rdi
+ call mont_mul_a3b
+ lea (+$tmp_offset)(%rsp), %rsi
+ mov (+$pg_offset)(%rsp), %rbp
+ add \$2, %rbp
+ mov %rbp, (+$pg_offset)(%rsp)
+ mov %rsi, %rcx # rcx = rsi = addr of tmp
+___
+
+ &swizzle("%rbp", "%rcx", "%rax", "%rbx");
+$code.=<<___;
+ mov (+$i_offset)(%rsp), %rax
+ sub \$1, %rax
+ mov %rax, (+$i_offset)(%rsp)
+ jne init_loop
+
+ #
+ # Copy exponent onto stack
+ movdqa %xmm0, (+$exp_offset+16*0)(%rsp)
+ movdqa %xmm1, (+$exp_offset+16*1)(%rsp)
+ movdqa %xmm2, (+$exp_offset+16*2)(%rsp)
+ movdqa %xmm3, (+$exp_offset+16*3)(%rsp)
+
+
+ #
+ # Do exponentiation
+ # Initialize result to G[exp{511:507}]
+ mov (+$exp_offset+62)(%rsp), %eax
+ mov %rax, %rdx
+ shr \$11, %rax
+ and \$0x07FF, %edx
+ mov %edx, (+$exp_offset+62)(%rsp)
+ lea (+$garray_offset)(%rsp,%rax,2), %rsi
+ mov (+$pResult_offset)(%rsp), %rdx
+___
+
+ &unswizzle("%rdx", "%rsi", "%rbp", "%rbx", "%rax");
+
+ #
+ # Loop variables
+ # rcx = [loop_idx] = index: 510-5 to 0 by 5
+$code.=<<___;
+ movq \$505, (+$loop_idx_offset)(%rsp)
+
+ mov (+$pResult_offset)(%rsp), %rcx
+ mov %rcx, (+$red_result_addr_offset)(%rsp)
+ mov (+8*0)(%rcx), %r10
+ mov (+8*1)(%rcx), %r11
+ mov (+8*2)(%rcx), %r12
+ mov (+8*3)(%rcx), %r13
+ mov (+8*4)(%rcx), %r14
+ mov (+8*5)(%rcx), %r15
+ mov (+8*6)(%rcx), %r8
+ mov (+8*7)(%rcx), %r9
+ jmp sqr_2
+
+main_loop_a3b:
+ call sqr_reduce
+ call sqr_reduce
+ call sqr_reduce
+sqr_2:
+ call sqr_reduce
+ call sqr_reduce
+
+ #
+ # Do multiply, first look up proper value in Garray
+ mov (+$loop_idx_offset)(%rsp), %rcx # bit index
+ mov %rcx, %rax
+ shr \$4, %rax # rax is word pointer
+ mov (+$exp_offset)(%rsp,%rax,2), %edx
+ and \$15, %rcx
+ shrq %cl, %rdx
+ and \$0x1F, %rdx
+
+ lea (+$garray_offset)(%rsp,%rdx,2), %rsi
+ lea (+$tmp_offset)(%rsp), %rdx
+ mov %rdx, %rdi
+___
+
+ &unswizzle("%rdx", "%rsi", "%rbp", "%rbx", "%rax");
+ # rdi = tmp = pG
+
+ #
+ # Call mod_mul_a1(pDst, pSrc1, pSrc2, pM, pData)
+ # result result pG M Data
+$code.=<<___;
+ mov (+$pResult_offset)(%rsp), %rsi
+ call mont_mul_a3b
+
+ #
+ # finish loop
+ mov (+$loop_idx_offset)(%rsp), %rcx
+ sub \$5, %rcx
+ mov %rcx, (+$loop_idx_offset)(%rsp)
+ jge main_loop_a3b
+
+ #
+
+end_main_loop_a3b:
+ # transform result out of Montgomery space
+ # result = reduce(result)
+ mov (+$pResult_offset)(%rsp), %rdx
+ pxor %xmm4, %xmm4
+ movdqu (+16*0)(%rdx), %xmm0
+ movdqu (+16*1)(%rdx), %xmm1
+ movdqu (+16*2)(%rdx), %xmm2
+ movdqu (+16*3)(%rdx), %xmm3
+ movdqa %xmm4, (+$tmp16_offset+16*4)(%rsp)
+ movdqa %xmm4, (+$tmp16_offset+16*5)(%rsp)
+ movdqa %xmm4, (+$tmp16_offset+16*6)(%rsp)
+ movdqa %xmm4, (+$tmp16_offset+16*7)(%rsp)
+ movdqa %xmm0, (+$tmp16_offset+16*0)(%rsp)
+ movdqa %xmm1, (+$tmp16_offset+16*1)(%rsp)
+ movdqa %xmm2, (+$tmp16_offset+16*2)(%rsp)
+ movdqa %xmm3, (+$tmp16_offset+16*3)(%rsp)
+ call mont_reduce
+
+ # If result > m, subract m
+ # load result into r15:r8
+ mov (+$pResult_offset)(%rsp), %rax
+ mov (+8*0)(%rax), %r8
+ mov (+8*1)(%rax), %r9
+ mov (+8*2)(%rax), %r10
+ mov (+8*3)(%rax), %r11
+ mov (+8*4)(%rax), %r12
+ mov (+8*5)(%rax), %r13
+ mov (+8*6)(%rax), %r14
+ mov (+8*7)(%rax), %r15
+
+ # subtract m
+ mov (+$pData_offset)(%rsp), %rbx
+ add \$$M, %rbx
+
+ sub (+8*0)(%rbx), %r8
+ sbb (+8*1)(%rbx), %r9
+ sbb (+8*2)(%rbx), %r10
+ sbb (+8*3)(%rbx), %r11
+ sbb (+8*4)(%rbx), %r12
+ sbb (+8*5)(%rbx), %r13
+ sbb (+8*6)(%rbx), %r14
+ sbb (+8*7)(%rbx), %r15
+
+ # if Carry is clear, replace result with difference
+ mov (+8*0)(%rax), %rsi
+ mov (+8*1)(%rax), %rdi
+ mov (+8*2)(%rax), %rcx
+ mov (+8*3)(%rax), %rdx
+ cmovnc %r8, %rsi
+ cmovnc %r9, %rdi
+ cmovnc %r10, %rcx
+ cmovnc %r11, %rdx
+ mov %rsi, (+8*0)(%rax)
+ mov %rdi, (+8*1)(%rax)
+ mov %rcx, (+8*2)(%rax)
+ mov %rdx, (+8*3)(%rax)
+
+ mov (+8*4)(%rax), %rsi
+ mov (+8*5)(%rax), %rdi
+ mov (+8*6)(%rax), %rcx
+ mov (+8*7)(%rax), %rdx
+ cmovnc %r12, %rsi
+ cmovnc %r13, %rdi
+ cmovnc %r14, %rcx
+ cmovnc %r15, %rdx
+ mov %rsi, (+8*4)(%rax)
+ mov %rdi, (+8*5)(%rax)
+ mov %rcx, (+8*6)(%rax)
+ mov %rdx, (+8*7)(%rax)
+
+ mov (+$rsp_offset)(%rsp), %rsi
+ mov 0(%rsi),%r15
+ mov 8(%rsi),%r14
+ mov 16(%rsi),%r13
+ mov 24(%rsi),%r12
+ mov 32(%rsi),%rbx
+ mov 40(%rsi),%rbp
+ lea 48(%rsi),%rsp
+.Lepilogue:
+ ret
+.size mod_exp_512, . - mod_exp_512
+___
+
+if ($win64) {
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+my $rec="%rcx";
+my $frame="%rdx";
+my $context="%r8";
+my $disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+.type mod_exp_512_se_handler,\@abi-omnipotent
+.align 16
+mod_exp_512_se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ lea .Lbody(%rip),%r10
+ cmp %r10,%rbx # context->Rip<prologue label
+ jb .Lin_prologue
+
+ mov 152($context),%rax # pull context->Rsp
+
+ lea .Lepilogue(%rip),%r10
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lin_prologue
+
+ mov $rsp_offset(%rax),%rax # pull saved Rsp
+
+ mov 32(%rax),%rbx
+ mov 40(%rax),%rbp
+ mov 24(%rax),%r12
+ mov 16(%rax),%r13
+ mov 8(%rax),%r14
+ mov 0(%rax),%r15
+ lea 48(%rax),%rax
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R13
+ mov %r14,232($context) # restore context->R14
+ mov %r15,240($context) # restore context->R15
+
+.Lin_prologue:
+ mov 8(%rax),%rdi
+ mov 16(%rax),%rsi
+ mov %rax,152($context) # restore context->Rsp
+ mov %rsi,168($context) # restore context->Rsi
+ mov %rdi,176($context) # restore context->Rdi
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$154,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size mod_exp_512_se_handler,.-mod_exp_512_se_handler
+
+.section .pdata
+.align 4
+ .rva .LSEH_begin_mod_exp_512
+ .rva .LSEH_end_mod_exp_512
+ .rva .LSEH_info_mod_exp_512
+
+.section .xdata
+.align 8
+.LSEH_info_mod_exp_512:
+ .byte 9,0,0,0
+ .rva mod_exp_512_se_handler
+___
+}
+
+sub reg_part {
+my ($reg,$conv)=@_;
+ if ($reg =~ /%r[0-9]+/) { $reg .= $conv; }
+ elsif ($conv eq "b") { $reg =~ s/%[er]([^x]+)x?/%$1l/; }
+ elsif ($conv eq "w") { $reg =~ s/%[er](.+)/%$1/; }
+ elsif ($conv eq "d") { $reg =~ s/%[er](.+)/%e$1/; }
+ return $reg;
+}
+
+$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/(\(\+[^)]+\))/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/bn/asm/parisc-mont.pl b/deps/openssl/openssl/crypto/bn/asm/parisc-mont.pl
new file mode 100644
index 000000000..4a766a87f
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/asm/parisc-mont.pl
@@ -0,0 +1,993 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# On PA-7100LC this module performs ~90-50% better, less for longer
+# keys, than code generated by gcc 3.2 for PA-RISC 1.1. Latter means
+# that compiler utilized xmpyu instruction to perform 32x32=64-bit
+# multiplication, which in turn means that "baseline" performance was
+# optimal in respect to instruction set capabilities. Fair comparison
+# with vendor compiler is problematic, because OpenSSL doesn't define
+# BN_LLONG [presumably] for historical reasons, which drives compiler
+# toward 4 times 16x16=32-bit multiplicatons [plus complementary
+# shifts and additions] instead. This means that you should observe
+# several times improvement over code generated by vendor compiler
+# for PA-RISC 1.1, but the "baseline" is far from optimal. The actual
+# improvement coefficient was never collected on PA-7100LC, or any
+# other 1.1 CPU, because I don't have access to such machine with
+# vendor compiler. But to give you a taste, PA-RISC 1.1 code path
+# reportedly outperformed code generated by cc +DA1.1 +O3 by factor
+# of ~5x on PA-8600.
+#
+# On PA-RISC 2.0 it has to compete with pa-risc2[W].s, which is
+# reportedly ~2x faster than vendor compiler generated code [according
+# to comment in pa-risc2[W].s]. Here comes a catch. Execution core of
+# this implementation is actually 32-bit one, in the sense that it
+# operates on 32-bit values. But pa-risc2[W].s operates on arrays of
+# 64-bit BN_LONGs... How do they interoperate then? No problem. This
+# module picks halves of 64-bit values in reverse order and pretends
+# they were 32-bit BN_LONGs. But can 32-bit core compete with "pure"
+# 64-bit code such as pa-risc2[W].s then? Well, the thing is that
+# 32x32=64-bit multiplication is the best even PA-RISC 2.0 can do,
+# i.e. there is no "wider" multiplication like on most other 64-bit
+# platforms. This means that even being effectively 32-bit, this
+# implementation performs "64-bit" computational task in same amount
+# of arithmetic operations, most notably multiplications. It requires
+# more memory references, most notably to tp[num], but this doesn't
+# seem to exhaust memory port capacity. And indeed, dedicated PA-RISC
+# 2.0 code path, provides virtually same performance as pa-risc2[W].s:
+# it's ~10% better for shortest key length and ~10% worse for longest
+# one.
+#
+# In case it wasn't clear. The module has two distinct code paths:
+# PA-RISC 1.1 and PA-RISC 2.0 ones. Latter features carry-free 64-bit
+# additions and 64-bit integer loads, not to mention specific
+# instruction scheduling. In 64-bit build naturally only 2.0 code path
+# is assembled. In 32-bit application context both code paths are
+# assembled, PA-RISC 2.0 CPU is detected at run-time and proper path
+# is taken automatically. Also, in 32-bit build the module imposes
+# couple of limitations: vector lengths has to be even and vector
+# addresses has to be 64-bit aligned. Normally neither is a problem:
+# most common key lengths are even and vectors are commonly malloc-ed,
+# which ensures alignment.
+#
+# Special thanks to polarhome.com for providing HP-UX account on
+# PA-RISC 1.1 machine, and to correspondent who chose to remain
+# anonymous for testing the code on PA-RISC 2.0 machine.
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+
+$flavour = shift;
+$output = shift;
+
+open STDOUT,">$output";
+
+if ($flavour =~ /64/) {
+ $LEVEL ="2.0W";
+ $SIZE_T =8;
+ $FRAME_MARKER =80;
+ $SAVED_RP =16;
+ $PUSH ="std";
+ $PUSHMA ="std,ma";
+ $POP ="ldd";
+ $POPMB ="ldd,mb";
+ $BN_SZ =$SIZE_T;
+} else {
+ $LEVEL ="1.1"; #$LEVEL.="\n\t.ALLOW\t2.0";
+ $SIZE_T =4;
+ $FRAME_MARKER =48;
+ $SAVED_RP =20;
+ $PUSH ="stw";
+ $PUSHMA ="stwm";
+ $POP ="ldw";
+ $POPMB ="ldwm";
+ $BN_SZ =$SIZE_T;
+ if (open CONF,"<${dir}../../opensslconf.h") {
+ while(<CONF>) {
+ if (m/#\s*define\s+SIXTY_FOUR_BIT/) {
+ $BN_SZ=8;
+ $LEVEL="2.0";
+ last;
+ }
+ }
+ close CONF;
+ }
+}
+
+$FRAME=8*$SIZE_T+$FRAME_MARKER; # 8 saved regs + frame marker
+ # [+ argument transfer]
+$LOCALS=$FRAME-$FRAME_MARKER;
+$FRAME+=32; # local variables
+
+$tp="%r31";
+$ti1="%r29";
+$ti0="%r28";
+
+$rp="%r26";
+$ap="%r25";
+$bp="%r24";
+$np="%r23";
+$n0="%r22"; # passed through stack in 32-bit
+$num="%r21"; # passed through stack in 32-bit
+$idx="%r20";
+$arrsz="%r19";
+
+$nm1="%r7";
+$nm0="%r6";
+$ab1="%r5";
+$ab0="%r4";
+
+$fp="%r3";
+$hi1="%r2";
+$hi0="%r1";
+
+$xfer=$n0; # accomodates [-16..15] offset in fld[dw]s
+
+$fm0="%fr4"; $fti=$fm0;
+$fbi="%fr5L";
+$fn0="%fr5R";
+$fai="%fr6"; $fab0="%fr7"; $fab1="%fr8";
+$fni="%fr9"; $fnm0="%fr10"; $fnm1="%fr11";
+
+$code=<<___;
+ .LEVEL $LEVEL
+ .SPACE \$TEXT\$
+ .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
+
+ .EXPORT bn_mul_mont,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ .ALIGN 64
+bn_mul_mont
+ .PROC
+ .CALLINFO FRAME=`$FRAME-8*$SIZE_T`,NO_CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=6
+ .ENTRY
+ $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue
+ $PUSHMA %r3,$FRAME(%sp)
+ $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp)
+ $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp)
+ $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp)
+ $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp)
+ $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp)
+ $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp)
+ $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp)
+ ldo -$FRAME(%sp),$fp
+___
+$code.=<<___ if ($SIZE_T==4);
+ ldw `-$FRAME_MARKER-4`($fp),$n0
+ ldw `-$FRAME_MARKER-8`($fp),$num
+ nop
+ nop ; alignment
+___
+$code.=<<___ if ($BN_SZ==4);
+ comiclr,<= 6,$num,%r0 ; are vectors long enough?
+ b L\$abort
+ ldi 0,%r28 ; signal "unhandled"
+ add,ev %r0,$num,$num ; is $num even?
+ b L\$abort
+ nop
+ or $ap,$np,$ti1
+ extru,= $ti1,31,3,%r0 ; are ap and np 64-bit aligned?
+ b L\$abort
+ nop
+ nop ; alignment
+ nop
+
+ fldws 0($n0),${fn0}
+ fldws,ma 4($bp),${fbi} ; bp[0]
+___
+$code.=<<___ if ($BN_SZ==8);
+ comib,> 3,$num,L\$abort ; are vectors long enough?
+ ldi 0,%r28 ; signal "unhandled"
+ addl $num,$num,$num ; I operate on 32-bit values
+
+ fldws 4($n0),${fn0} ; only low part of n0
+ fldws 4($bp),${fbi} ; bp[0] in flipped word order
+___
+$code.=<<___;
+ fldds 0($ap),${fai} ; ap[0,1]
+ fldds 0($np),${fni} ; np[0,1]
+
+ sh2addl $num,%r0,$arrsz
+ ldi 31,$hi0
+ ldo 36($arrsz),$hi1 ; space for tp[num+1]
+ andcm $hi1,$hi0,$hi1 ; align
+ addl $hi1,%sp,%sp
+ $PUSH $fp,-$SIZE_T(%sp)
+
+ ldo `$LOCALS+16`($fp),$xfer
+ ldo `$LOCALS+32+4`($fp),$tp
+
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[0]*bp[0]
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[1]*bp[0]
+ xmpyu ${fn0},${fab0}R,${fm0}
+
+ addl $arrsz,$ap,$ap ; point at the end
+ addl $arrsz,$np,$np
+ subi 0,$arrsz,$idx ; j=0
+ ldo 8($idx),$idx ; j++++
+
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[0]*m
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[1]*m
+ fstds ${fab0},-16($xfer)
+ fstds ${fnm0},-8($xfer)
+ fstds ${fab1},0($xfer)
+ fstds ${fnm1},8($xfer)
+ flddx $idx($ap),${fai} ; ap[2,3]
+ flddx $idx($np),${fni} ; np[2,3]
+___
+$code.=<<___ if ($BN_SZ==4);
+ mtctl $hi0,%cr11 ; $hi0 still holds 31
+ extrd,u,*= $hi0,%sar,1,$hi0 ; executes on PA-RISC 1.0
+ b L\$parisc11
+ nop
+___
+$code.=<<___; # PA-RISC 2.0 code-path
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[0]
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m
+ ldd -16($xfer),$ab0
+ fstds ${fab0},-16($xfer)
+
+ extrd,u $ab0,31,32,$hi0
+ extrd,u $ab0,63,32,$ab0
+ ldd -8($xfer),$nm0
+ fstds ${fnm0},-8($xfer)
+ ldo 8($idx),$idx ; j++++
+ addl $ab0,$nm0,$nm0 ; low part is discarded
+ extrd,u $nm0,31,32,$hi1
+
+L\$1st
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[j+1]*bp[0]
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j+1]*m
+ ldd 0($xfer),$ab1
+ fstds ${fab1},0($xfer)
+ addl $hi0,$ab1,$ab1
+ extrd,u $ab1,31,32,$hi0
+ ldd 8($xfer),$nm1
+ fstds ${fnm1},8($xfer)
+ extrd,u $ab1,63,32,$ab1
+ addl $hi1,$nm1,$nm1
+ flddx $idx($ap),${fai} ; ap[j,j+1]
+ flddx $idx($np),${fni} ; np[j,j+1]
+ addl $ab1,$nm1,$nm1
+ extrd,u $nm1,31,32,$hi1
+
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[0]
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m
+ ldd -16($xfer),$ab0
+ fstds ${fab0},-16($xfer)
+ addl $hi0,$ab0,$ab0
+ extrd,u $ab0,31,32,$hi0
+ ldd -8($xfer),$nm0
+ fstds ${fnm0},-8($xfer)
+ extrd,u $ab0,63,32,$ab0
+ addl $hi1,$nm0,$nm0
+ stw $nm1,-4($tp) ; tp[j-1]
+ addl $ab0,$nm0,$nm0
+ stw,ma $nm0,8($tp) ; tp[j-1]
+ addib,<> 8,$idx,L\$1st ; j++++
+ extrd,u $nm0,31,32,$hi1
+
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[j]*bp[0]
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j]*m
+ ldd 0($xfer),$ab1
+ fstds ${fab1},0($xfer)
+ addl $hi0,$ab1,$ab1
+ extrd,u $ab1,31,32,$hi0
+ ldd 8($xfer),$nm1
+ fstds ${fnm1},8($xfer)
+ extrd,u $ab1,63,32,$ab1
+ addl $hi1,$nm1,$nm1
+ ldd -16($xfer),$ab0
+ addl $ab1,$nm1,$nm1
+ ldd -8($xfer),$nm0
+ extrd,u $nm1,31,32,$hi1
+
+ addl $hi0,$ab0,$ab0
+ extrd,u $ab0,31,32,$hi0
+ stw $nm1,-4($tp) ; tp[j-1]
+ extrd,u $ab0,63,32,$ab0
+ addl $hi1,$nm0,$nm0
+ ldd 0($xfer),$ab1
+ addl $ab0,$nm0,$nm0
+ ldd,mb 8($xfer),$nm1
+ extrd,u $nm0,31,32,$hi1
+ stw,ma $nm0,8($tp) ; tp[j-1]
+
+ ldo -1($num),$num ; i--
+ subi 0,$arrsz,$idx ; j=0
+___
+$code.=<<___ if ($BN_SZ==4);
+ fldws,ma 4($bp),${fbi} ; bp[1]
+___
+$code.=<<___ if ($BN_SZ==8);
+ fldws 0($bp),${fbi} ; bp[1] in flipped word order
+___
+$code.=<<___;
+ flddx $idx($ap),${fai} ; ap[0,1]
+ flddx $idx($np),${fni} ; np[0,1]
+ fldws 8($xfer),${fti}R ; tp[0]
+ addl $hi0,$ab1,$ab1
+ extrd,u $ab1,31,32,$hi0
+ extrd,u $ab1,63,32,$ab1
+ ldo 8($idx),$idx ; j++++
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[0]*bp[1]
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[1]*bp[1]
+ addl $hi1,$nm1,$nm1
+ addl $ab1,$nm1,$nm1
+ extrd,u $nm1,31,32,$hi1
+ fstws,mb ${fab0}L,-8($xfer) ; save high part
+ stw $nm1,-4($tp) ; tp[j-1]
+
+ fcpy,sgl %fr0,${fti}L ; zero high part
+ fcpy,sgl %fr0,${fab0}L
+ addl $hi1,$hi0,$hi0
+ extrd,u $hi0,31,32,$hi1
+ fcnvxf,dbl,dbl ${fti},${fti} ; 32-bit unsigned int -> double
+ fcnvxf,dbl,dbl ${fab0},${fab0}
+ stw $hi0,0($tp)
+ stw $hi1,4($tp)
+
+ fadd,dbl ${fti},${fab0},${fab0} ; add tp[0]
+ fcnvfx,dbl,dbl ${fab0},${fab0} ; double -> 33-bit unsigned int
+ xmpyu ${fn0},${fab0}R,${fm0}
+ ldo `$LOCALS+32+4`($fp),$tp
+L\$outer
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[0]*m
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[1]*m
+ fstds ${fab0},-16($xfer) ; 33-bit value
+ fstds ${fnm0},-8($xfer)
+ flddx $idx($ap),${fai} ; ap[2]
+ flddx $idx($np),${fni} ; np[2]
+ ldo 8($idx),$idx ; j++++
+ ldd -16($xfer),$ab0 ; 33-bit value
+ ldd -8($xfer),$nm0
+ ldw 0($xfer),$hi0 ; high part
+
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[i]
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m
+ extrd,u $ab0,31,32,$ti0 ; carry bit
+ extrd,u $ab0,63,32,$ab0
+ fstds ${fab1},0($xfer)
+ addl $ti0,$hi0,$hi0 ; account carry bit
+ fstds ${fnm1},8($xfer)
+ addl $ab0,$nm0,$nm0 ; low part is discarded
+ ldw 0($tp),$ti1 ; tp[1]
+ extrd,u $nm0,31,32,$hi1
+ fstds ${fab0},-16($xfer)
+ fstds ${fnm0},-8($xfer)
+
+L\$inner
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[j+1]*bp[i]
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j+1]*m
+ ldd 0($xfer),$ab1
+ fstds ${fab1},0($xfer)
+ addl $hi0,$ti1,$ti1
+ addl $ti1,$ab1,$ab1
+ ldd 8($xfer),$nm1
+ fstds ${fnm1},8($xfer)
+ extrd,u $ab1,31,32,$hi0
+ extrd,u $ab1,63,32,$ab1
+ flddx $idx($ap),${fai} ; ap[j,j+1]
+ flddx $idx($np),${fni} ; np[j,j+1]
+ addl $hi1,$nm1,$nm1
+ addl $ab1,$nm1,$nm1
+ ldw 4($tp),$ti0 ; tp[j]
+ stw $nm1,-4($tp) ; tp[j-1]
+
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[i]
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m
+ ldd -16($xfer),$ab0
+ fstds ${fab0},-16($xfer)
+ addl $hi0,$ti0,$ti0
+ addl $ti0,$ab0,$ab0
+ ldd -8($xfer),$nm0
+ fstds ${fnm0},-8($xfer)
+ extrd,u $ab0,31,32,$hi0
+ extrd,u $nm1,31,32,$hi1
+ ldw 8($tp),$ti1 ; tp[j]
+ extrd,u $ab0,63,32,$ab0
+ addl $hi1,$nm0,$nm0
+ addl $ab0,$nm0,$nm0
+ stw,ma $nm0,8($tp) ; tp[j-1]
+ addib,<> 8,$idx,L\$inner ; j++++
+ extrd,u $nm0,31,32,$hi1
+
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[j]*bp[i]
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j]*m
+ ldd 0($xfer),$ab1
+ fstds ${fab1},0($xfer)
+ addl $hi0,$ti1,$ti1
+ addl $ti1,$ab1,$ab1
+ ldd 8($xfer),$nm1
+ fstds ${fnm1},8($xfer)
+ extrd,u $ab1,31,32,$hi0
+ extrd,u $ab1,63,32,$ab1
+ ldw 4($tp),$ti0 ; tp[j]
+ addl $hi1,$nm1,$nm1
+ addl $ab1,$nm1,$nm1
+ ldd -16($xfer),$ab0
+ ldd -8($xfer),$nm0
+ extrd,u $nm1,31,32,$hi1
+
+ addl $hi0,$ab0,$ab0
+ addl $ti0,$ab0,$ab0
+ stw $nm1,-4($tp) ; tp[j-1]
+ extrd,u $ab0,31,32,$hi0
+ ldw 8($tp),$ti1 ; tp[j]
+ extrd,u $ab0,63,32,$ab0
+ addl $hi1,$nm0,$nm0
+ ldd 0($xfer),$ab1
+ addl $ab0,$nm0,$nm0
+ ldd,mb 8($xfer),$nm1
+ extrd,u $nm0,31,32,$hi1
+ stw,ma $nm0,8($tp) ; tp[j-1]
+
+ addib,= -1,$num,L\$outerdone ; i--
+ subi 0,$arrsz,$idx ; j=0
+___
+$code.=<<___ if ($BN_SZ==4);
+ fldws,ma 4($bp),${fbi} ; bp[i]
+___
+$code.=<<___ if ($BN_SZ==8);
+ ldi 12,$ti0 ; bp[i] in flipped word order
+ addl,ev %r0,$num,$num
+ ldi -4,$ti0
+ addl $ti0,$bp,$bp
+ fldws 0($bp),${fbi}
+___
+$code.=<<___;
+ flddx $idx($ap),${fai} ; ap[0]
+ addl $hi0,$ab1,$ab1
+ flddx $idx($np),${fni} ; np[0]
+ fldws 8($xfer),${fti}R ; tp[0]
+ addl $ti1,$ab1,$ab1
+ extrd,u $ab1,31,32,$hi0
+ extrd,u $ab1,63,32,$ab1
+
+ ldo 8($idx),$idx ; j++++
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[0]*bp[i]
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[1]*bp[i]
+ ldw 4($tp),$ti0 ; tp[j]
+
+ addl $hi1,$nm1,$nm1
+ fstws,mb ${fab0}L,-8($xfer) ; save high part
+ addl $ab1,$nm1,$nm1
+ extrd,u $nm1,31,32,$hi1
+ fcpy,sgl %fr0,${fti}L ; zero high part
+ fcpy,sgl %fr0,${fab0}L
+ stw $nm1,-4($tp) ; tp[j-1]
+
+ fcnvxf,dbl,dbl ${fti},${fti} ; 32-bit unsigned int -> double
+ fcnvxf,dbl,dbl ${fab0},${fab0}
+ addl $hi1,$hi0,$hi0
+ fadd,dbl ${fti},${fab0},${fab0} ; add tp[0]
+ addl $ti0,$hi0,$hi0
+ extrd,u $hi0,31,32,$hi1
+ fcnvfx,dbl,dbl ${fab0},${fab0} ; double -> 33-bit unsigned int
+ stw $hi0,0($tp)
+ stw $hi1,4($tp)
+ xmpyu ${fn0},${fab0}R,${fm0}
+
+ b L\$outer
+ ldo `$LOCALS+32+4`($fp),$tp
+
+L\$outerdone
+ addl $hi0,$ab1,$ab1
+ addl $ti1,$ab1,$ab1
+ extrd,u $ab1,31,32,$hi0
+ extrd,u $ab1,63,32,$ab1
+
+ ldw 4($tp),$ti0 ; tp[j]
+
+ addl $hi1,$nm1,$nm1
+ addl $ab1,$nm1,$nm1
+ extrd,u $nm1,31,32,$hi1
+ stw $nm1,-4($tp) ; tp[j-1]
+
+ addl $hi1,$hi0,$hi0
+ addl $ti0,$hi0,$hi0
+ extrd,u $hi0,31,32,$hi1
+ stw $hi0,0($tp)
+ stw $hi1,4($tp)
+
+ ldo `$LOCALS+32`($fp),$tp
+ sub %r0,%r0,%r0 ; clear borrow
+___
+$code.=<<___ if ($BN_SZ==4);
+ ldws,ma 4($tp),$ti0
+ extru,= $rp,31,3,%r0 ; is rp 64-bit aligned?
+ b L\$sub_pa11
+ addl $tp,$arrsz,$tp
+L\$sub
+ ldwx $idx($np),$hi0
+ subb $ti0,$hi0,$hi1
+ ldwx $idx($tp),$ti0
+ addib,<> 4,$idx,L\$sub
+ stws,ma $hi1,4($rp)
+
+ subb $ti0,%r0,$hi1
+ ldo -4($tp),$tp
+___
+$code.=<<___ if ($BN_SZ==8);
+ ldd,ma 8($tp),$ti0
+L\$sub
+ ldd $idx($np),$hi0
+ shrpd $ti0,$ti0,32,$ti0 ; flip word order
+ std $ti0,-8($tp) ; save flipped value
+ sub,db $ti0,$hi0,$hi1
+ ldd,ma 8($tp),$ti0
+ addib,<> 8,$idx,L\$sub
+ std,ma $hi1,8($rp)
+
+ extrd,u $ti0,31,32,$ti0 ; carry in flipped word order
+ sub,db $ti0,%r0,$hi1
+ ldo -8($tp),$tp
+___
+$code.=<<___;
+ and $tp,$hi1,$ap
+ andcm $rp,$hi1,$bp
+ or $ap,$bp,$np
+
+ sub $rp,$arrsz,$rp ; rewind rp
+ subi 0,$arrsz,$idx
+ ldo `$LOCALS+32`($fp),$tp
+L\$copy
+ ldd $idx($np),$hi0
+ std,ma %r0,8($tp)
+ addib,<> 8,$idx,.-8 ; L\$copy
+ std,ma $hi0,8($rp)
+___
+
+if ($BN_SZ==4) { # PA-RISC 1.1 code-path
+$ablo=$ab0;
+$abhi=$ab1;
+$nmlo0=$nm0;
+$nmhi0=$nm1;
+$nmlo1="%r9";
+$nmhi1="%r8";
+
+$code.=<<___;
+ b L\$done
+ nop
+
+ .ALIGN 8
+L\$parisc11
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[0]
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m
+ ldw -12($xfer),$ablo
+ ldw -16($xfer),$hi0
+ ldw -4($xfer),$nmlo0
+ ldw -8($xfer),$nmhi0
+ fstds ${fab0},-16($xfer)
+ fstds ${fnm0},-8($xfer)
+
+ ldo 8($idx),$idx ; j++++
+ add $ablo,$nmlo0,$nmlo0 ; discarded
+ addc %r0,$nmhi0,$hi1
+ ldw 4($xfer),$ablo
+ ldw 0($xfer),$abhi
+ nop
+
+L\$1st_pa11
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[j+1]*bp[0]
+ flddx $idx($ap),${fai} ; ap[j,j+1]
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j+1]*m
+ flddx $idx($np),${fni} ; np[j,j+1]
+ add $hi0,$ablo,$ablo
+ ldw 12($xfer),$nmlo1
+ addc %r0,$abhi,$hi0
+ ldw 8($xfer),$nmhi1
+ add $ablo,$nmlo1,$nmlo1
+ fstds ${fab1},0($xfer)
+ addc %r0,$nmhi1,$nmhi1
+ fstds ${fnm1},8($xfer)
+ add $hi1,$nmlo1,$nmlo1
+ ldw -12($xfer),$ablo
+ addc %r0,$nmhi1,$hi1
+ ldw -16($xfer),$abhi
+
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[0]
+ ldw -4($xfer),$nmlo0
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m
+ ldw -8($xfer),$nmhi0
+ add $hi0,$ablo,$ablo
+ stw $nmlo1,-4($tp) ; tp[j-1]
+ addc %r0,$abhi,$hi0
+ fstds ${fab0},-16($xfer)
+ add $ablo,$nmlo0,$nmlo0
+ fstds ${fnm0},-8($xfer)
+ addc %r0,$nmhi0,$nmhi0
+ ldw 0($xfer),$abhi
+ add $hi1,$nmlo0,$nmlo0
+ ldw 4($xfer),$ablo
+ stws,ma $nmlo0,8($tp) ; tp[j-1]
+ addib,<> 8,$idx,L\$1st_pa11 ; j++++
+ addc %r0,$nmhi0,$hi1
+
+ ldw 8($xfer),$nmhi1
+ ldw 12($xfer),$nmlo1
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[j]*bp[0]
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j]*m
+ add $hi0,$ablo,$ablo
+ fstds ${fab1},0($xfer)
+ addc %r0,$abhi,$hi0
+ fstds ${fnm1},8($xfer)
+ add $ablo,$nmlo1,$nmlo1
+ ldw -16($xfer),$abhi
+ addc %r0,$nmhi1,$nmhi1
+ ldw -12($xfer),$ablo
+ add $hi1,$nmlo1,$nmlo1
+ ldw -8($xfer),$nmhi0
+ addc %r0,$nmhi1,$hi1
+ ldw -4($xfer),$nmlo0
+
+ add $hi0,$ablo,$ablo
+ stw $nmlo1,-4($tp) ; tp[j-1]
+ addc %r0,$abhi,$hi0
+ ldw 0($xfer),$abhi
+ add $ablo,$nmlo0,$nmlo0
+ ldw 4($xfer),$ablo
+ addc %r0,$nmhi0,$nmhi0
+ ldws,mb 8($xfer),$nmhi1
+ add $hi1,$nmlo0,$nmlo0
+ ldw 4($xfer),$nmlo1
+ addc %r0,$nmhi0,$hi1
+ stws,ma $nmlo0,8($tp) ; tp[j-1]
+
+ ldo -1($num),$num ; i--
+ subi 0,$arrsz,$idx ; j=0
+
+ fldws,ma 4($bp),${fbi} ; bp[1]
+ flddx $idx($ap),${fai} ; ap[0,1]
+ flddx $idx($np),${fni} ; np[0,1]
+ fldws 8($xfer),${fti}R ; tp[0]
+ add $hi0,$ablo,$ablo
+ addc %r0,$abhi,$hi0
+ ldo 8($idx),$idx ; j++++
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[0]*bp[1]
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[1]*bp[1]
+ add $hi1,$nmlo1,$nmlo1
+ addc %r0,$nmhi1,$nmhi1
+ add $ablo,$nmlo1,$nmlo1
+ addc %r0,$nmhi1,$hi1
+ fstws,mb ${fab0}L,-8($xfer) ; save high part
+ stw $nmlo1,-4($tp) ; tp[j-1]
+
+ fcpy,sgl %fr0,${fti}L ; zero high part
+ fcpy,sgl %fr0,${fab0}L
+ add $hi1,$hi0,$hi0
+ addc %r0,%r0,$hi1
+ fcnvxf,dbl,dbl ${fti},${fti} ; 32-bit unsigned int -> double
+ fcnvxf,dbl,dbl ${fab0},${fab0}
+ stw $hi0,0($tp)
+ stw $hi1,4($tp)
+
+ fadd,dbl ${fti},${fab0},${fab0} ; add tp[0]
+ fcnvfx,dbl,dbl ${fab0},${fab0} ; double -> 33-bit unsigned int
+ xmpyu ${fn0},${fab0}R,${fm0}
+ ldo `$LOCALS+32+4`($fp),$tp
+L\$outer_pa11
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[0]*m
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[1]*m
+ fstds ${fab0},-16($xfer) ; 33-bit value
+ fstds ${fnm0},-8($xfer)
+ flddx $idx($ap),${fai} ; ap[2,3]
+ flddx $idx($np),${fni} ; np[2,3]
+ ldw -16($xfer),$abhi ; carry bit actually
+ ldo 8($idx),$idx ; j++++
+ ldw -12($xfer),$ablo
+ ldw -8($xfer),$nmhi0
+ ldw -4($xfer),$nmlo0
+ ldw 0($xfer),$hi0 ; high part
+
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[i]
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m
+ fstds ${fab1},0($xfer)
+ addl $abhi,$hi0,$hi0 ; account carry bit
+ fstds ${fnm1},8($xfer)
+ add $ablo,$nmlo0,$nmlo0 ; discarded
+ ldw 0($tp),$ti1 ; tp[1]
+ addc %r0,$nmhi0,$hi1
+ fstds ${fab0},-16($xfer)
+ fstds ${fnm0},-8($xfer)
+ ldw 4($xfer),$ablo
+ ldw 0($xfer),$abhi
+
+L\$inner_pa11
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[j+1]*bp[i]
+ flddx $idx($ap),${fai} ; ap[j,j+1]
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j+1]*m
+ flddx $idx($np),${fni} ; np[j,j+1]
+ add $hi0,$ablo,$ablo
+ ldw 4($tp),$ti0 ; tp[j]
+ addc %r0,$abhi,$abhi
+ ldw 12($xfer),$nmlo1
+ add $ti1,$ablo,$ablo
+ ldw 8($xfer),$nmhi1
+ addc %r0,$abhi,$hi0
+ fstds ${fab1},0($xfer)
+ add $ablo,$nmlo1,$nmlo1
+ fstds ${fnm1},8($xfer)
+ addc %r0,$nmhi1,$nmhi1
+ ldw -12($xfer),$ablo
+ add $hi1,$nmlo1,$nmlo1
+ ldw -16($xfer),$abhi
+ addc %r0,$nmhi1,$hi1
+
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[i]
+ ldw 8($tp),$ti1 ; tp[j]
+ xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m
+ ldw -4($xfer),$nmlo0
+ add $hi0,$ablo,$ablo
+ ldw -8($xfer),$nmhi0
+ addc %r0,$abhi,$abhi
+ stw $nmlo1,-4($tp) ; tp[j-1]
+ add $ti0,$ablo,$ablo
+ fstds ${fab0},-16($xfer)
+ addc %r0,$abhi,$hi0
+ fstds ${fnm0},-8($xfer)
+ add $ablo,$nmlo0,$nmlo0
+ ldw 4($xfer),$ablo
+ addc %r0,$nmhi0,$nmhi0
+ ldw 0($xfer),$abhi
+ add $hi1,$nmlo0,$nmlo0
+ stws,ma $nmlo0,8($tp) ; tp[j-1]
+ addib,<> 8,$idx,L\$inner_pa11 ; j++++
+ addc %r0,$nmhi0,$hi1
+
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[j]*bp[i]
+ ldw 12($xfer),$nmlo1
+ xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j]*m
+ ldw 8($xfer),$nmhi1
+ add $hi0,$ablo,$ablo
+ ldw 4($tp),$ti0 ; tp[j]
+ addc %r0,$abhi,$abhi
+ fstds ${fab1},0($xfer)
+ add $ti1,$ablo,$ablo
+ fstds ${fnm1},8($xfer)
+ addc %r0,$abhi,$hi0
+ ldw -16($xfer),$abhi
+ add $ablo,$nmlo1,$nmlo1
+ ldw -12($xfer),$ablo
+ addc %r0,$nmhi1,$nmhi1
+ ldw -8($xfer),$nmhi0
+ add $hi1,$nmlo1,$nmlo1
+ ldw -4($xfer),$nmlo0
+ addc %r0,$nmhi1,$hi1
+
+ add $hi0,$ablo,$ablo
+ stw $nmlo1,-4($tp) ; tp[j-1]
+ addc %r0,$abhi,$abhi
+ add $ti0,$ablo,$ablo
+ ldw 8($tp),$ti1 ; tp[j]
+ addc %r0,$abhi,$hi0
+ ldw 0($xfer),$abhi
+ add $ablo,$nmlo0,$nmlo0
+ ldw 4($xfer),$ablo
+ addc %r0,$nmhi0,$nmhi0
+ ldws,mb 8($xfer),$nmhi1
+ add $hi1,$nmlo0,$nmlo0
+ ldw 4($xfer),$nmlo1
+ addc %r0,$nmhi0,$hi1
+ stws,ma $nmlo0,8($tp) ; tp[j-1]
+
+ addib,= -1,$num,L\$outerdone_pa11; i--
+ subi 0,$arrsz,$idx ; j=0
+
+ fldws,ma 4($bp),${fbi} ; bp[i]
+ flddx $idx($ap),${fai} ; ap[0]
+ add $hi0,$ablo,$ablo
+ addc %r0,$abhi,$abhi
+ flddx $idx($np),${fni} ; np[0]
+ fldws 8($xfer),${fti}R ; tp[0]
+ add $ti1,$ablo,$ablo
+ addc %r0,$abhi,$hi0
+
+ ldo 8($idx),$idx ; j++++
+ xmpyu ${fai}L,${fbi},${fab0} ; ap[0]*bp[i]
+ xmpyu ${fai}R,${fbi},${fab1} ; ap[1]*bp[i]
+ ldw 4($tp),$ti0 ; tp[j]
+
+ add $hi1,$nmlo1,$nmlo1
+ addc %r0,$nmhi1,$nmhi1
+ fstws,mb ${fab0}L,-8($xfer) ; save high part
+ add $ablo,$nmlo1,$nmlo1
+ addc %r0,$nmhi1,$hi1
+ fcpy,sgl %fr0,${fti}L ; zero high part
+ fcpy,sgl %fr0,${fab0}L
+ stw $nmlo1,-4($tp) ; tp[j-1]
+
+ fcnvxf,dbl,dbl ${fti},${fti} ; 32-bit unsigned int -> double
+ fcnvxf,dbl,dbl ${fab0},${fab0}
+ add $hi1,$hi0,$hi0
+ addc %r0,%r0,$hi1
+ fadd,dbl ${fti},${fab0},${fab0} ; add tp[0]
+ add $ti0,$hi0,$hi0
+ addc %r0,$hi1,$hi1
+ fcnvfx,dbl,dbl ${fab0},${fab0} ; double -> 33-bit unsigned int
+ stw $hi0,0($tp)
+ stw $hi1,4($tp)
+ xmpyu ${fn0},${fab0}R,${fm0}
+
+ b L\$outer_pa11
+ ldo `$LOCALS+32+4`($fp),$tp
+
+L\$outerdone_pa11
+ add $hi0,$ablo,$ablo
+ addc %r0,$abhi,$abhi
+ add $ti1,$ablo,$ablo
+ addc %r0,$abhi,$hi0
+
+ ldw 4($tp),$ti0 ; tp[j]
+
+ add $hi1,$nmlo1,$nmlo1
+ addc %r0,$nmhi1,$nmhi1
+ add $ablo,$nmlo1,$nmlo1
+ addc %r0,$nmhi1,$hi1
+ stw $nmlo1,-4($tp) ; tp[j-1]
+
+ add $hi1,$hi0,$hi0
+ addc %r0,%r0,$hi1
+ add $ti0,$hi0,$hi0
+ addc %r0,$hi1,$hi1
+ stw $hi0,0($tp)
+ stw $hi1,4($tp)
+
+ ldo `$LOCALS+32+4`($fp),$tp
+ sub %r0,%r0,%r0 ; clear borrow
+ ldw -4($tp),$ti0
+ addl $tp,$arrsz,$tp
+L\$sub_pa11
+ ldwx $idx($np),$hi0
+ subb $ti0,$hi0,$hi1
+ ldwx $idx($tp),$ti0
+ addib,<> 4,$idx,L\$sub_pa11
+ stws,ma $hi1,4($rp)
+
+ subb $ti0,%r0,$hi1
+ ldo -4($tp),$tp
+ and $tp,$hi1,$ap
+ andcm $rp,$hi1,$bp
+ or $ap,$bp,$np
+
+ sub $rp,$arrsz,$rp ; rewind rp
+ subi 0,$arrsz,$idx
+ ldo `$LOCALS+32`($fp),$tp
+L\$copy_pa11
+ ldwx $idx($np),$hi0
+ stws,ma %r0,4($tp)
+ addib,<> 4,$idx,L\$copy_pa11
+ stws,ma $hi0,4($rp)
+
+ nop ; alignment
+L\$done
+___
+}
+
+$code.=<<___;
+ ldi 1,%r28 ; signal "handled"
+ ldo $FRAME($fp),%sp ; destroy tp[num+1]
+
+ $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue
+ $POP `-$FRAME+1*$SIZE_T`(%sp),%r4
+ $POP `-$FRAME+2*$SIZE_T`(%sp),%r5
+ $POP `-$FRAME+3*$SIZE_T`(%sp),%r6
+ $POP `-$FRAME+4*$SIZE_T`(%sp),%r7
+ $POP `-$FRAME+5*$SIZE_T`(%sp),%r8
+ $POP `-$FRAME+6*$SIZE_T`(%sp),%r9
+ $POP `-$FRAME+7*$SIZE_T`(%sp),%r10
+L\$abort
+ bv (%r2)
+ .EXIT
+ $POPMB -$FRAME(%sp),%r3
+ .PROCEND
+ .STRINGZ "Montgomery Multiplication for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+# Explicitly encode PA-RISC 2.0 instructions used in this module, so
+# that it can be compiled with .LEVEL 1.0. It should be noted that I
+# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0
+# directive...
+
+my $ldd = sub {
+ my ($mod,$args) = @_;
+ my $orig = "ldd$mod\t$args";
+
+ if ($args =~ /%r([0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 4
+ { my $opcode=(0x03<<26)|($2<<21)|($1<<16)|(3<<6)|$3;
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ elsif ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 5
+ { my $opcode=(0x03<<26)|($2<<21)|(1<<12)|(3<<6)|$3;
+ $opcode|=(($1&0xF)<<17)|(($1&0x10)<<12); # encode offset
+ $opcode|=(1<<5) if ($mod =~ /^,m/);
+ $opcode|=(1<<13) if ($mod =~ /^,mb/);
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $std = sub {
+ my ($mod,$args) = @_;
+ my $orig = "std$mod\t$args";
+
+ if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/) # format 6
+ { my $opcode=(0x03<<26)|($3<<21)|($1<<16)|(1<<12)|(0xB<<6);
+ $opcode|=(($2&0xF)<<1)|(($2&0x10)>>4); # encode offset
+ $opcode|=(1<<5) if ($mod =~ /^,m/);
+ $opcode|=(1<<13) if ($mod =~ /^,mb/);
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $extrd = sub {
+ my ($mod,$args) = @_;
+ my $orig = "extrd$mod\t$args";
+
+ # I only have ",u" completer, it's implicitly encoded...
+ if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/) # format 15
+ { my $opcode=(0x36<<26)|($1<<21)|($4<<16);
+ my $len=32-$3;
+ $opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5); # encode pos
+ $opcode |= (($len&0x20)<<7)|($len&0x1f); # encode len
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/) # format 12
+ { my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9);
+ my $len=32-$2;
+ $opcode |= (($len&0x20)<<3)|($len&0x1f); # encode len
+ $opcode |= (1<<13) if ($mod =~ /,\**=/);
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $shrpd = sub {
+ my ($mod,$args) = @_;
+ my $orig = "shrpd$mod\t$args";
+
+ if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/) # format 14
+ { my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4;
+ my $cpos=63-$3;
+ $opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5); # encode sa
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $sub = sub {
+ my ($mod,$args) = @_;
+ my $orig = "sub$mod\t$args";
+
+ if ($mod eq ",db" && $args =~ /%r([0-9]+),%r([0-9]+),%r([0-9]+)/) {
+ my $opcode=(0x02<<26)|($2<<21)|($1<<16)|$3;
+ $opcode|=(1<<10); # e1
+ $opcode|=(1<<8); # e2
+ $opcode|=(1<<5); # d
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig
+ }
+ else { "\t".$orig; }
+};
+
+sub assemble {
+ my ($mnemonic,$mod,$args)=@_;
+ my $opcode = eval("\$$mnemonic");
+
+ ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args";
+}
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/ge;
+ # flip word order in 64-bit mode...
+ s/(xmpyu\s+)($fai|$fni)([LR])/$1.$2.($3 eq "L"?"R":"L")/e if ($BN_SZ==8);
+ # assemble 2.0 instructions in 32-bit mode...
+ s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e if ($BN_SZ==4);
+
+ print $_,"\n";
+}
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/bn/asm/ppc-mont.pl b/deps/openssl/openssl/crypto/bn/asm/ppc-mont.pl
index 7849eae95..f9b6992cc 100644
--- a/deps/openssl/openssl/crypto/bn/asm/ppc-mont.pl
+++ b/deps/openssl/openssl/crypto/bn/asm/ppc-mont.pl
@@ -31,7 +31,6 @@ if ($flavour =~ /32/) {
$BNSZ= $BITS/8;
$SIZE_T=4;
$RZONE= 224;
- $FRAME= $SIZE_T*16;
$LD= "lwz"; # load
$LDU= "lwzu"; # load and update
@@ -51,7 +50,6 @@ if ($flavour =~ /32/) {
$BNSZ= $BITS/8;
$SIZE_T=8;
$RZONE= 288;
- $FRAME= $SIZE_T*16;
# same as above, but 64-bit mnemonics...
$LD= "ld"; # load
@@ -69,6 +67,9 @@ if ($flavour =~ /32/) {
$POP= $LD;
} else { die "nonsense $flavour"; }
+$FRAME=8*$SIZE_T+$RZONE;
+$LOCALS=8*$SIZE_T;
+
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
@@ -89,18 +90,18 @@ $aj="r10";
$nj="r11";
$tj="r12";
# non-volatile registers
-$i="r14";
-$j="r15";
-$tp="r16";
-$m0="r17";
-$m1="r18";
-$lo0="r19";
-$hi0="r20";
-$lo1="r21";
-$hi1="r22";
-$alo="r23";
-$ahi="r24";
-$nlo="r25";
+$i="r20";
+$j="r21";
+$tp="r22";
+$m0="r23";
+$m1="r24";
+$lo0="r25";
+$hi0="r26";
+$lo1="r27";
+$hi1="r28";
+$alo="r29";
+$ahi="r30";
+$nlo="r31";
#
$nhi="r0";
@@ -108,42 +109,48 @@ $code=<<___;
.machine "any"
.text
-.globl .bn_mul_mont
+.globl .bn_mul_mont_int
.align 4
-.bn_mul_mont:
+.bn_mul_mont_int:
cmpwi $num,4
mr $rp,r3 ; $rp is reassigned
li r3,0
bltlr
-
+___
+$code.=<<___ if ($BNSZ==4);
+ cmpwi $num,32 ; longer key performance is not better
+ bgelr
+___
+$code.=<<___;
slwi $num,$num,`log($BNSZ)/log(2)`
li $tj,-4096
- addi $ovf,$num,`$FRAME+$RZONE`
+ addi $ovf,$num,$FRAME
subf $ovf,$ovf,$sp ; $sp-$ovf
and $ovf,$ovf,$tj ; minimize TLB usage
subf $ovf,$sp,$ovf ; $ovf-$sp
+ mr $tj,$sp
srwi $num,$num,`log($BNSZ)/log(2)`
$STUX $sp,$sp,$ovf
- $PUSH r14,`4*$SIZE_T`($sp)
- $PUSH r15,`5*$SIZE_T`($sp)
- $PUSH r16,`6*$SIZE_T`($sp)
- $PUSH r17,`7*$SIZE_T`($sp)
- $PUSH r18,`8*$SIZE_T`($sp)
- $PUSH r19,`9*$SIZE_T`($sp)
- $PUSH r20,`10*$SIZE_T`($sp)
- $PUSH r21,`11*$SIZE_T`($sp)
- $PUSH r22,`12*$SIZE_T`($sp)
- $PUSH r23,`13*$SIZE_T`($sp)
- $PUSH r24,`14*$SIZE_T`($sp)
- $PUSH r25,`15*$SIZE_T`($sp)
+ $PUSH r20,`-12*$SIZE_T`($tj)
+ $PUSH r21,`-11*$SIZE_T`($tj)
+ $PUSH r22,`-10*$SIZE_T`($tj)
+ $PUSH r23,`-9*$SIZE_T`($tj)
+ $PUSH r24,`-8*$SIZE_T`($tj)
+ $PUSH r25,`-7*$SIZE_T`($tj)
+ $PUSH r26,`-6*$SIZE_T`($tj)
+ $PUSH r27,`-5*$SIZE_T`($tj)
+ $PUSH r28,`-4*$SIZE_T`($tj)
+ $PUSH r29,`-3*$SIZE_T`($tj)
+ $PUSH r30,`-2*$SIZE_T`($tj)
+ $PUSH r31,`-1*$SIZE_T`($tj)
$LD $n0,0($n0) ; pull n0[0] value
addi $num,$num,-2 ; adjust $num for counter register
$LD $m0,0($bp) ; m0=bp[0]
$LD $aj,0($ap) ; ap[0]
- addi $tp,$sp,$FRAME
+ addi $tp,$sp,$LOCALS
$UMULL $lo0,$aj,$m0 ; ap[0]*bp[0]
$UMULH $hi0,$aj,$m0
@@ -205,8 +212,8 @@ L1st:
Louter:
$LDX $m0,$bp,$i ; m0=bp[i]
$LD $aj,0($ap) ; ap[0]
- addi $tp,$sp,$FRAME
- $LD $tj,$FRAME($sp) ; tp[0]
+ addi $tp,$sp,$LOCALS
+ $LD $tj,$LOCALS($sp); tp[0]
$UMULL $lo0,$aj,$m0 ; ap[0]*bp[i]
$UMULH $hi0,$aj,$m0
$LD $aj,$BNSZ($ap) ; ap[1]
@@ -273,7 +280,7 @@ Linner:
addi $num,$num,2 ; restore $num
subfc $j,$j,$j ; j=0 and "clear" XER[CA]
- addi $tp,$sp,$FRAME
+ addi $tp,$sp,$LOCALS
mtctr $num
.align 4
@@ -299,23 +306,27 @@ Lcopy: ; copy or in-place refresh
addi $j,$j,$BNSZ
bdnz- Lcopy
- $POP r14,`4*$SIZE_T`($sp)
- $POP r15,`5*$SIZE_T`($sp)
- $POP r16,`6*$SIZE_T`($sp)
- $POP r17,`7*$SIZE_T`($sp)
- $POP r18,`8*$SIZE_T`($sp)
- $POP r19,`9*$SIZE_T`($sp)
- $POP r20,`10*$SIZE_T`($sp)
- $POP r21,`11*$SIZE_T`($sp)
- $POP r22,`12*$SIZE_T`($sp)
- $POP r23,`13*$SIZE_T`($sp)
- $POP r24,`14*$SIZE_T`($sp)
- $POP r25,`15*$SIZE_T`($sp)
- $POP $sp,0($sp)
+ $POP $tj,0($sp)
li r3,1
+ $POP r20,`-12*$SIZE_T`($tj)
+ $POP r21,`-11*$SIZE_T`($tj)
+ $POP r22,`-10*$SIZE_T`($tj)
+ $POP r23,`-9*$SIZE_T`($tj)
+ $POP r24,`-8*$SIZE_T`($tj)
+ $POP r25,`-7*$SIZE_T`($tj)
+ $POP r26,`-6*$SIZE_T`($tj)
+ $POP r27,`-5*$SIZE_T`($tj)
+ $POP r28,`-4*$SIZE_T`($tj)
+ $POP r29,`-3*$SIZE_T`($tj)
+ $POP r30,`-2*$SIZE_T`($tj)
+ $POP r31,`-1*$SIZE_T`($tj)
+ mr $sp,$tj
blr
.long 0
-.asciz "Montgomery Multiplication for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
+ .byte 0,12,4,0,0x80,12,6,0
+ .long 0
+
+.asciz "Montgomery Multiplication for PPC, CRYPTOGAMS by <appro\@openssl.org>"
___
$code =~ s/\`([^\`]*)\`/eval $1/gem;
diff --git a/deps/openssl/openssl/crypto/bn/asm/ppc.pl b/deps/openssl/openssl/crypto/bn/asm/ppc.pl
index f4093177e..1249ce229 100644
--- a/deps/openssl/openssl/crypto/bn/asm/ppc.pl
+++ b/deps/openssl/openssl/crypto/bn/asm/ppc.pl
@@ -389,7 +389,9 @@ $data=<<EOF;
$ST r9,`6*$BNSZ`(r3) #r[6]=c1
$ST r10,`7*$BNSZ`(r3) #r[7]=c2
blr
- .long 0x00000000
+ .long 0
+ .byte 0,12,0x14,0,0,0,2,0
+ .long 0
#
# NOTE: The following label name should be changed to
@@ -814,8 +816,9 @@ $data=<<EOF;
blr
-
- .long 0x00000000
+ .long 0
+ .byte 0,12,0x14,0,0,0,2,0
+ .long 0
#
# NOTE: The following label name should be changed to
@@ -966,7 +969,9 @@ $data=<<EOF;
$ST r10,`6*$BNSZ`(r3) #r[6]=c1
$ST r11,`7*$BNSZ`(r3) #r[7]=c2
blr
- .long 0x00000000
+ .long 0
+ .byte 0,12,0x14,0,0,0,3,0
+ .long 0
#
# NOTE: The following label name should be changed to
@@ -1502,7 +1507,9 @@ $data=<<EOF;
$ST r12,`14*$BNSZ`(r3) #r[14]=c3;
$ST r10,`15*$BNSZ`(r3) #r[15]=c1;
blr
- .long 0x00000000
+ .long 0
+ .byte 0,12,0x14,0,0,0,3,0
+ .long 0
#
# NOTE: The following label name should be changed to
@@ -1550,8 +1557,9 @@ Lppcasm_sub_adios:
subfze r3,r0 # if carry bit is set then r3 = 0 else -1
andi. r3,r3,1 # keep only last bit.
blr
- .long 0x00000000
-
+ .long 0
+ .byte 0,12,0x14,0,0,0,4,0
+ .long 0
#
# NOTE: The following label name should be changed to
@@ -1594,7 +1602,9 @@ Lppcasm_add_mainloop:
Lppcasm_add_adios:
addze r3,r0 #return carry bit.
blr
- .long 0x00000000
+ .long 0
+ .byte 0,12,0x14,0,0,0,4,0
+ .long 0
#
# NOTE: The following label name should be changed to
@@ -1707,7 +1717,9 @@ Lppcasm_div8:
Lppcasm_div9:
or r3,r8,r0
blr
- .long 0x00000000
+ .long 0
+ .byte 0,12,0x14,0,0,0,3,0
+ .long 0
#
# NOTE: The following label name should be changed to
@@ -1746,8 +1758,9 @@ Lppcasm_sqr_mainloop:
bdnz- Lppcasm_sqr_mainloop
Lppcasm_sqr_adios:
blr
- .long 0x00000000
-
+ .long 0
+ .byte 0,12,0x14,0,0,0,3,0
+ .long 0
#
# NOTE: The following label name should be changed to
@@ -1850,7 +1863,9 @@ Lppcasm_mw_REM:
Lppcasm_mw_OVER:
addi r3,r12,0
blr
- .long 0x00000000
+ .long 0
+ .byte 0,12,0x14,0,0,0,4,0
+ .long 0
#
# NOTE: The following label name should be changed to
@@ -1973,7 +1988,9 @@ Lppcasm_maw_leftover:
Lppcasm_maw_adios:
addi r3,r12,0
blr
- .long 0x00000000
+ .long 0
+ .byte 0,12,0x14,0,0,0,4,0
+ .long 0
.align 4
EOF
$data =~ s/\`([^\`]*)\`/eval $1/gem;
diff --git a/deps/openssl/openssl/crypto/bn/asm/ppc64-mont.pl b/deps/openssl/openssl/crypto/bn/asm/ppc64-mont.pl
index 3449b3585..a14e769ad 100644
--- a/deps/openssl/openssl/crypto/bn/asm/ppc64-mont.pl
+++ b/deps/openssl/openssl/crypto/bn/asm/ppc64-mont.pl
@@ -45,23 +45,40 @@
# on 1.8GHz PPC970, it's only 5-55% faster. Still far from impressive
# in absolute terms, but it's apparently the way Power 6 is...
+# December 2009
+
+# Adapted for 32-bit build this module delivers 25-120%, yes, more
+# than *twice* for longer keys, performance improvement over 32-bit
+# ppc-mont.pl on 1.8GHz PPC970. However! This implementation utilizes
+# even 64-bit integer operations and the trouble is that most PPC
+# operating systems don't preserve upper halves of general purpose
+# registers upon 32-bit signal delivery. They do preserve them upon
+# context switch, but not signalling:-( This means that asynchronous
+# signals have to be blocked upon entry to this subroutine. Signal
+# masking (and of course complementary unmasking) has quite an impact
+# on performance, naturally larger for shorter keys. It's so severe
+# that 512-bit key performance can be as low as 1/3 of expected one.
+# This is why this routine can be engaged for longer key operations
+# only on these OSes, see crypto/ppccap.c for further details. MacOS X
+# is an exception from this and doesn't require signal masking, and
+# that's where above improvement coefficients were collected. For
+# others alternative would be to break dependence on upper halves of
+# GPRs by sticking to 32-bit integer operations...
+
$flavour = shift;
if ($flavour =~ /32/) {
$SIZE_T=4;
$RZONE= 224;
- $FRAME= $SIZE_T*12+8*12;
- $fname= "bn_mul_mont_ppc64";
+ $fname= "bn_mul_mont_fpu64";
$STUX= "stwux"; # store indexed and update
$PUSH= "stw";
$POP= "lwz";
- die "not implemented yet";
} elsif ($flavour =~ /64/) {
$SIZE_T=8;
$RZONE= 288;
- $FRAME= $SIZE_T*12+8*12;
- $fname= "bn_mul_mont";
+ $fname= "bn_mul_mont_fpu64";
# same as above, but 64-bit mnemonics...
$STUX= "stdux"; # store indexed and update
@@ -76,7 +93,7 @@ die "can't locate ppc-xlate.pl";
open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-$FRAME=($FRAME+63)&~63;
+$FRAME=64; # padded frame header
$TRANSFER=16*8;
$carry="r0";
@@ -93,16 +110,16 @@ $tp="r10";
$j="r11";
$i="r12";
# non-volatile registers
-$nap_d="r14"; # interleaved ap and np in double format
-$a0="r15"; # ap[0]
-$t0="r16"; # temporary registers
-$t1="r17";
-$t2="r18";
-$t3="r19";
-$t4="r20";
-$t5="r21";
-$t6="r22";
-$t7="r23";
+$nap_d="r22"; # interleaved ap and np in double format
+$a0="r23"; # ap[0]
+$t0="r24"; # temporary registers
+$t1="r25";
+$t2="r26";
+$t3="r27";
+$t4="r28";
+$t5="r29";
+$t6="r30";
+$t7="r31";
# PPC offers enough register bank capacity to unroll inner loops twice
#
@@ -132,28 +149,17 @@ $ba="f0"; $bb="f1"; $bc="f2"; $bd="f3";
$na="f4"; $nb="f5"; $nc="f6"; $nd="f7";
$dota="f8"; $dotb="f9";
$A0="f10"; $A1="f11"; $A2="f12"; $A3="f13";
-$N0="f14"; $N1="f15"; $N2="f16"; $N3="f17";
-$T0a="f18"; $T0b="f19";
-$T1a="f20"; $T1b="f21";
-$T2a="f22"; $T2b="f23";
-$T3a="f24"; $T3b="f25";
+$N0="f20"; $N1="f21"; $N2="f22"; $N3="f23";
+$T0a="f24"; $T0b="f25";
+$T1a="f26"; $T1b="f27";
+$T2a="f28"; $T2b="f29";
+$T3a="f30"; $T3b="f31";
# sp----------->+-------------------------------+
# | saved sp |
# +-------------------------------+
-# | |
-# +-------------------------------+
-# | 10 saved gpr, r14-r23 |
-# . .
-# . .
-# +12*size_t +-------------------------------+
-# | 12 saved fpr, f14-f25 |
# . .
-# . .
-# +12*8 +-------------------------------+
-# | padding to 64 byte boundary |
-# . .
-# +X +-------------------------------+
+# +64 +-------------------------------+
# | 16 gpr<->fpr transfer zone |
# . .
# . .
@@ -173,6 +179,16 @@ $T3a="f24"; $T3b="f25";
# . .
# . .
# +-------------------------------+
+# . .
+# -12*size_t +-------------------------------+
+# | 10 saved gpr, r22-r31 |
+# . .
+# . .
+# -12*8 +-------------------------------+
+# | 12 saved fpr, f20-f31 |
+# . .
+# . .
+# +-------------------------------+
$code=<<___;
.machine "any"
@@ -181,14 +197,14 @@ $code=<<___;
.globl .$fname
.align 5
.$fname:
- cmpwi $num,4
+ cmpwi $num,`3*8/$SIZE_T`
mr $rp,r3 ; $rp is reassigned
li r3,0 ; possible "not handled" return code
bltlr-
- andi. r0,$num,1 ; $num has to be even
+ andi. r0,$num,`16/$SIZE_T-1` ; $num has to be "even"
bnelr-
- slwi $num,$num,3 ; num*=8
+ slwi $num,$num,`log($SIZE_T)/log(2)` ; num*=sizeof(BN_LONG)
li $i,-4096
slwi $tp,$num,2 ; place for {an}p_{lh}[num], i.e. 4*num
add $tp,$tp,$num ; place for tp[num+1]
@@ -196,35 +212,50 @@ $code=<<___;
subf $tp,$tp,$sp ; $sp-$tp
and $tp,$tp,$i ; minimize TLB usage
subf $tp,$sp,$tp ; $tp-$sp
+ mr $i,$sp
$STUX $sp,$sp,$tp ; alloca
- $PUSH r14,`2*$SIZE_T`($sp)
- $PUSH r15,`3*$SIZE_T`($sp)
- $PUSH r16,`4*$SIZE_T`($sp)
- $PUSH r17,`5*$SIZE_T`($sp)
- $PUSH r18,`6*$SIZE_T`($sp)
- $PUSH r19,`7*$SIZE_T`($sp)
- $PUSH r20,`8*$SIZE_T`($sp)
- $PUSH r21,`9*$SIZE_T`($sp)
- $PUSH r22,`10*$SIZE_T`($sp)
- $PUSH r23,`11*$SIZE_T`($sp)
- stfd f14,`12*$SIZE_T+0`($sp)
- stfd f15,`12*$SIZE_T+8`($sp)
- stfd f16,`12*$SIZE_T+16`($sp)
- stfd f17,`12*$SIZE_T+24`($sp)
- stfd f18,`12*$SIZE_T+32`($sp)
- stfd f19,`12*$SIZE_T+40`($sp)
- stfd f20,`12*$SIZE_T+48`($sp)
- stfd f21,`12*$SIZE_T+56`($sp)
- stfd f22,`12*$SIZE_T+64`($sp)
- stfd f23,`12*$SIZE_T+72`($sp)
- stfd f24,`12*$SIZE_T+80`($sp)
- stfd f25,`12*$SIZE_T+88`($sp)
-
+ $PUSH r22,`-12*8-10*$SIZE_T`($i)
+ $PUSH r23,`-12*8-9*$SIZE_T`($i)
+ $PUSH r24,`-12*8-8*$SIZE_T`($i)
+ $PUSH r25,`-12*8-7*$SIZE_T`($i)
+ $PUSH r26,`-12*8-6*$SIZE_T`($i)
+ $PUSH r27,`-12*8-5*$SIZE_T`($i)
+ $PUSH r28,`-12*8-4*$SIZE_T`($i)
+ $PUSH r29,`-12*8-3*$SIZE_T`($i)
+ $PUSH r30,`-12*8-2*$SIZE_T`($i)
+ $PUSH r31,`-12*8-1*$SIZE_T`($i)
+ stfd f20,`-12*8`($i)
+ stfd f21,`-11*8`($i)
+ stfd f22,`-10*8`($i)
+ stfd f23,`-9*8`($i)
+ stfd f24,`-8*8`($i)
+ stfd f25,`-7*8`($i)
+ stfd f26,`-6*8`($i)
+ stfd f27,`-5*8`($i)
+ stfd f28,`-4*8`($i)
+ stfd f29,`-3*8`($i)
+ stfd f30,`-2*8`($i)
+ stfd f31,`-1*8`($i)
+___
+$code.=<<___ if ($SIZE_T==8);
ld $a0,0($ap) ; pull ap[0] value
ld $n0,0($n0) ; pull n0[0] value
ld $t3,0($bp) ; bp[0]
-
+___
+$code.=<<___ if ($SIZE_T==4);
+ mr $t1,$n0
+ lwz $a0,0($ap) ; pull ap[0,1] value
+ lwz $t0,4($ap)
+ lwz $n0,0($t1) ; pull n0[0,1] value
+ lwz $t1,4($t1)
+ lwz $t3,0($bp) ; bp[0,1]
+ lwz $t2,4($bp)
+ insrdi $a0,$t0,32,0
+ insrdi $n0,$t1,32,0
+ insrdi $t3,$t2,32,0
+___
+$code.=<<___;
addi $tp,$sp,`$FRAME+$TRANSFER+8+64`
li $i,-64
add $nap_d,$tp,$num
@@ -258,6 +289,8 @@ $code=<<___;
std $t5,`$FRAME+40`($sp)
std $t6,`$FRAME+48`($sp)
std $t7,`$FRAME+56`($sp)
+___
+$code.=<<___ if ($SIZE_T==8);
lwz $t0,4($ap) ; load a[j] as 32-bit word pair
lwz $t1,0($ap)
lwz $t2,12($ap) ; load a[j+1] as 32-bit word pair
@@ -266,6 +299,18 @@ $code=<<___;
lwz $t5,0($np)
lwz $t6,12($np) ; load n[j+1] as 32-bit word pair
lwz $t7,8($np)
+___
+$code.=<<___ if ($SIZE_T==4);
+ lwz $t0,0($ap) ; load a[j..j+3] as 32-bit word pairs
+ lwz $t1,4($ap)
+ lwz $t2,8($ap)
+ lwz $t3,12($ap)
+ lwz $t4,0($np) ; load n[j..j+3] as 32-bit word pairs
+ lwz $t5,4($np)
+ lwz $t6,8($np)
+ lwz $t7,12($np)
+___
+$code.=<<___;
lfd $ba,`$FRAME+0`($sp)
lfd $bb,`$FRAME+8`($sp)
lfd $bc,`$FRAME+16`($sp)
@@ -374,6 +419,8 @@ $code=<<___;
.align 5
L1st:
+___
+$code.=<<___ if ($SIZE_T==8);
lwz $t0,4($ap) ; load a[j] as 32-bit word pair
lwz $t1,0($ap)
lwz $t2,12($ap) ; load a[j+1] as 32-bit word pair
@@ -382,6 +429,18 @@ L1st:
lwz $t5,0($np)
lwz $t6,12($np) ; load n[j+1] as 32-bit word pair
lwz $t7,8($np)
+___
+$code.=<<___ if ($SIZE_T==4);
+ lwz $t0,0($ap) ; load a[j..j+3] as 32-bit word pairs
+ lwz $t1,4($ap)
+ lwz $t2,8($ap)
+ lwz $t3,12($ap)
+ lwz $t4,0($np) ; load n[j..j+3] as 32-bit word pairs
+ lwz $t5,4($np)
+ lwz $t6,8($np)
+ lwz $t7,12($np)
+___
+$code.=<<___;
std $t0,`$FRAME+64`($sp)
std $t1,`$FRAME+72`($sp)
std $t2,`$FRAME+80`($sp)
@@ -559,7 +618,17 @@ L1st:
li $i,8 ; i=1
.align 5
Louter:
+___
+$code.=<<___ if ($SIZE_T==8);
ldx $t3,$bp,$i ; bp[i]
+___
+$code.=<<___ if ($SIZE_T==4);
+ add $t0,$bp,$i
+ lwz $t3,0($t0) ; bp[i,i+1]
+ lwz $t0,4($t0)
+ insrdi $t3,$t0,32,0
+___
+$code.=<<___;
ld $t6,`$FRAME+$TRANSFER+8`($sp) ; tp[0]
mulld $t7,$a0,$t3 ; ap[0]*bp[i]
@@ -761,6 +830,13 @@ Linner:
stfd $T0b,`$FRAME+8`($sp)
add $t7,$t7,$carry
addc $t3,$t0,$t1
+___
+$code.=<<___ if ($SIZE_T==4); # adjust XER[CA]
+ extrdi $t0,$t0,32,0
+ extrdi $t1,$t1,32,0
+ adde $t0,$t0,$t1
+___
+$code.=<<___;
stfd $T1a,`$FRAME+16`($sp)
stfd $T1b,`$FRAME+24`($sp)
insrdi $t4,$t7,16,0 ; 64..127 bits
@@ -768,6 +844,13 @@ Linner:
stfd $T2a,`$FRAME+32`($sp)
stfd $T2b,`$FRAME+40`($sp)
adde $t5,$t4,$t2
+___
+$code.=<<___ if ($SIZE_T==4); # adjust XER[CA]
+ extrdi $t4,$t4,32,0
+ extrdi $t2,$t2,32,0
+ adde $t4,$t4,$t2
+___
+$code.=<<___;
stfd $T3a,`$FRAME+48`($sp)
stfd $T3b,`$FRAME+56`($sp)
addze $carry,$carry
@@ -816,7 +899,21 @@ Linner:
ld $t7,`$FRAME+72`($sp)
addc $t3,$t0,$t1
+___
+$code.=<<___ if ($SIZE_T==4); # adjust XER[CA]
+ extrdi $t0,$t0,32,0
+ extrdi $t1,$t1,32,0
+ adde $t0,$t0,$t1
+___
+$code.=<<___;
adde $t5,$t4,$t2
+___
+$code.=<<___ if ($SIZE_T==4); # adjust XER[CA]
+ extrdi $t4,$t4,32,0
+ extrdi $t2,$t2,32,0
+ adde $t4,$t4,$t2
+___
+$code.=<<___;
addze $carry,$carry
std $t3,-16($tp) ; tp[j-1]
@@ -835,7 +932,9 @@ Linner:
subf $nap_d,$t7,$nap_d ; rewind pointer
cmpw $i,$num
blt- Louter
+___
+$code.=<<___ if ($SIZE_T==8);
subf $np,$num,$np ; rewind np
addi $j,$j,1 ; restore counter
subfc $i,$i,$i ; j=0 and "clear" XER[CA]
@@ -883,34 +982,105 @@ Lcopy: ; copy or in-place refresh
stdx $i,$t4,$i
addi $i,$i,16
bdnz- Lcopy
+___
+$code.=<<___ if ($SIZE_T==4);
+ subf $np,$num,$np ; rewind np
+ addi $j,$j,1 ; restore counter
+ subfc $i,$i,$i ; j=0 and "clear" XER[CA]
+ addi $tp,$sp,`$FRAME+$TRANSFER`
+ addi $np,$np,-4
+ addi $rp,$rp,-4
+ addi $ap,$sp,`$FRAME+$TRANSFER+4`
+ mtctr $j
+
+.align 4
+Lsub: ld $t0,8($tp) ; load tp[j..j+3] in 64-bit word order
+ ldu $t2,16($tp)
+ lwz $t4,4($np) ; load np[j..j+3] in 32-bit word order
+ lwz $t5,8($np)
+ lwz $t6,12($np)
+ lwzu $t7,16($np)
+ extrdi $t1,$t0,32,0
+ extrdi $t3,$t2,32,0
+ subfe $t4,$t4,$t0 ; tp[j]-np[j]
+ stw $t0,4($ap) ; save tp[j..j+3] in 32-bit word order
+ subfe $t5,$t5,$t1 ; tp[j+1]-np[j+1]
+ stw $t1,8($ap)
+ subfe $t6,$t6,$t2 ; tp[j+2]-np[j+2]
+ stw $t2,12($ap)
+ subfe $t7,$t7,$t3 ; tp[j+3]-np[j+3]
+ stwu $t3,16($ap)
+ stw $t4,4($rp)
+ stw $t5,8($rp)
+ stw $t6,12($rp)
+ stwu $t7,16($rp)
+ bdnz- Lsub
+
+ li $i,0
+ subfe $ovf,$i,$ovf ; handle upmost overflow bit
+ addi $tp,$sp,`$FRAME+$TRANSFER+4`
+ subf $rp,$num,$rp ; rewind rp
+ and $ap,$tp,$ovf
+ andc $np,$rp,$ovf
+ or $ap,$ap,$np ; ap=borrow?tp:rp
+ addi $tp,$sp,`$FRAME+$TRANSFER`
+ mtctr $j
+
+.align 4
+Lcopy: ; copy or in-place refresh
+ lwz $t0,4($ap)
+ lwz $t1,8($ap)
+ lwz $t2,12($ap)
+ lwzu $t3,16($ap)
+ std $i,8($nap_d) ; zap nap_d
+ std $i,16($nap_d)
+ std $i,24($nap_d)
+ std $i,32($nap_d)
+ std $i,40($nap_d)
+ std $i,48($nap_d)
+ std $i,56($nap_d)
+ stdu $i,64($nap_d)
+ stw $t0,4($rp)
+ stw $t1,8($rp)
+ stw $t2,12($rp)
+ stwu $t3,16($rp)
+ std $i,8($tp) ; zap tp at once
+ stdu $i,16($tp)
+ bdnz- Lcopy
+___
- $POP r14,`2*$SIZE_T`($sp)
- $POP r15,`3*$SIZE_T`($sp)
- $POP r16,`4*$SIZE_T`($sp)
- $POP r17,`5*$SIZE_T`($sp)
- $POP r18,`6*$SIZE_T`($sp)
- $POP r19,`7*$SIZE_T`($sp)
- $POP r20,`8*$SIZE_T`($sp)
- $POP r21,`9*$SIZE_T`($sp)
- $POP r22,`10*$SIZE_T`($sp)
- $POP r23,`11*$SIZE_T`($sp)
- lfd f14,`12*$SIZE_T+0`($sp)
- lfd f15,`12*$SIZE_T+8`($sp)
- lfd f16,`12*$SIZE_T+16`($sp)
- lfd f17,`12*$SIZE_T+24`($sp)
- lfd f18,`12*$SIZE_T+32`($sp)
- lfd f19,`12*$SIZE_T+40`($sp)
- lfd f20,`12*$SIZE_T+48`($sp)
- lfd f21,`12*$SIZE_T+56`($sp)
- lfd f22,`12*$SIZE_T+64`($sp)
- lfd f23,`12*$SIZE_T+72`($sp)
- lfd f24,`12*$SIZE_T+80`($sp)
- lfd f25,`12*$SIZE_T+88`($sp)
- $POP $sp,0($sp)
+$code.=<<___;
+ $POP $i,0($sp)
li r3,1 ; signal "handled"
+ $POP r22,`-12*8-10*$SIZE_T`($i)
+ $POP r23,`-12*8-9*$SIZE_T`($i)
+ $POP r24,`-12*8-8*$SIZE_T`($i)
+ $POP r25,`-12*8-7*$SIZE_T`($i)
+ $POP r26,`-12*8-6*$SIZE_T`($i)
+ $POP r27,`-12*8-5*$SIZE_T`($i)
+ $POP r28,`-12*8-4*$SIZE_T`($i)
+ $POP r29,`-12*8-3*$SIZE_T`($i)
+ $POP r30,`-12*8-2*$SIZE_T`($i)
+ $POP r31,`-12*8-1*$SIZE_T`($i)
+ lfd f20,`-12*8`($i)
+ lfd f21,`-11*8`($i)
+ lfd f22,`-10*8`($i)
+ lfd f23,`-9*8`($i)
+ lfd f24,`-8*8`($i)
+ lfd f25,`-7*8`($i)
+ lfd f26,`-6*8`($i)
+ lfd f27,`-5*8`($i)
+ lfd f28,`-4*8`($i)
+ lfd f29,`-3*8`($i)
+ lfd f30,`-2*8`($i)
+ lfd f31,`-1*8`($i)
+ mr $sp,$i
blr
.long 0
-.asciz "Montgomery Multiplication for PPC64, CRYPTOGAMS by <appro\@fy.chalmers.se>"
+ .byte 0,12,4,0,0x8c,10,6,0
+ .long 0
+
+.asciz "Montgomery Multiplication for PPC64, CRYPTOGAMS by <appro\@openssl.org>"
___
$code =~ s/\`([^\`]*)\`/eval $1/gem;
diff --git a/deps/openssl/openssl/crypto/bn/asm/s390x-gf2m.pl b/deps/openssl/openssl/crypto/bn/asm/s390x-gf2m.pl
new file mode 100644
index 000000000..cd9f13eca
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/asm/s390x-gf2m.pl
@@ -0,0 +1,221 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# May 2011
+#
+# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
+# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
+# the time being... gcc 4.3 appeared to generate poor code, therefore
+# the effort. And indeed, the module delivers 55%-90%(*) improvement
+# on haviest ECDSA verify and ECDH benchmarks for 163- and 571-bit
+# key lengths on z990, 30%-55%(*) - on z10, and 70%-110%(*) - on z196.
+# This is for 64-bit build. In 32-bit "highgprs" case improvement is
+# even higher, for example on z990 it was measured 80%-150%. ECDSA
+# sign is modest 9%-12% faster. Keep in mind that these coefficients
+# are not ones for bn_GF2m_mul_2x2 itself, as not all CPU time is
+# burnt in it...
+#
+# (*) gcc 4.1 was observed to deliver better results than gcc 4.3,
+# so that improvement coefficients can vary from one specific
+# setup to another.
+
+$flavour = shift;
+
+if ($flavour =~ /3[12]/) {
+ $SIZE_T=4;
+ $g="";
+} else {
+ $SIZE_T=8;
+ $g="g";
+}
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$stdframe=16*$SIZE_T+4*8;
+
+$rp="%r2";
+$a1="%r3";
+$a0="%r4";
+$b1="%r5";
+$b0="%r6";
+
+$ra="%r14";
+$sp="%r15";
+
+@T=("%r0","%r1");
+@i=("%r12","%r13");
+
+($a1,$a2,$a4,$a8,$a12,$a48)=map("%r$_",(6..11));
+($lo,$hi,$b)=map("%r$_",(3..5)); $a=$lo; $mask=$a8;
+
+$code.=<<___;
+.text
+
+.type _mul_1x1,\@function
+.align 16
+_mul_1x1:
+ lgr $a1,$a
+ sllg $a2,$a,1
+ sllg $a4,$a,2
+ sllg $a8,$a,3
+
+ srag $lo,$a1,63 # broadcast 63rd bit
+ nihh $a1,0x1fff
+ srag @i[0],$a2,63 # broadcast 62nd bit
+ nihh $a2,0x3fff
+ srag @i[1],$a4,63 # broadcast 61st bit
+ nihh $a4,0x7fff
+ ngr $lo,$b
+ ngr @i[0],$b
+ ngr @i[1],$b
+
+ lghi @T[0],0
+ lgr $a12,$a1
+ stg @T[0],`$stdframe+0*8`($sp) # tab[0]=0
+ xgr $a12,$a2
+ stg $a1,`$stdframe+1*8`($sp) # tab[1]=a1
+ lgr $a48,$a4
+ stg $a2,`$stdframe+2*8`($sp) # tab[2]=a2
+ xgr $a48,$a8
+ stg $a12,`$stdframe+3*8`($sp) # tab[3]=a1^a2
+ xgr $a1,$a4
+
+ stg $a4,`$stdframe+4*8`($sp) # tab[4]=a4
+ xgr $a2,$a4
+ stg $a1,`$stdframe+5*8`($sp) # tab[5]=a1^a4
+ xgr $a12,$a4
+ stg $a2,`$stdframe+6*8`($sp) # tab[6]=a2^a4
+ xgr $a1,$a48
+ stg $a12,`$stdframe+7*8`($sp) # tab[7]=a1^a2^a4
+ xgr $a2,$a48
+
+ stg $a8,`$stdframe+8*8`($sp) # tab[8]=a8
+ xgr $a12,$a48
+ stg $a1,`$stdframe+9*8`($sp) # tab[9]=a1^a8
+ xgr $a1,$a4
+ stg $a2,`$stdframe+10*8`($sp) # tab[10]=a2^a8
+ xgr $a2,$a4
+ stg $a12,`$stdframe+11*8`($sp) # tab[11]=a1^a2^a8
+
+ xgr $a12,$a4
+ stg $a48,`$stdframe+12*8`($sp) # tab[12]=a4^a8
+ srlg $hi,$lo,1
+ stg $a1,`$stdframe+13*8`($sp) # tab[13]=a1^a4^a8
+ sllg $lo,$lo,63
+ stg $a2,`$stdframe+14*8`($sp) # tab[14]=a2^a4^a8
+ srlg @T[0],@i[0],2
+ stg $a12,`$stdframe+15*8`($sp) # tab[15]=a1^a2^a4^a8
+
+ lghi $mask,`0xf<<3`
+ sllg $a1,@i[0],62
+ sllg @i[0],$b,3
+ srlg @T[1],@i[1],3
+ ngr @i[0],$mask
+ sllg $a2,@i[1],61
+ srlg @i[1],$b,4-3
+ xgr $hi,@T[0]
+ ngr @i[1],$mask
+ xgr $lo,$a1
+ xgr $hi,@T[1]
+ xgr $lo,$a2
+
+ xg $lo,$stdframe(@i[0],$sp)
+ srlg @i[0],$b,8-3
+ ngr @i[0],$mask
+___
+for($n=1;$n<14;$n++) {
+$code.=<<___;
+ lg @T[1],$stdframe(@i[1],$sp)
+ srlg @i[1],$b,`($n+2)*4`-3
+ sllg @T[0],@T[1],`$n*4`
+ ngr @i[1],$mask
+ srlg @T[1],@T[1],`64-$n*4`
+ xgr $lo,@T[0]
+ xgr $hi,@T[1]
+___
+ push(@i,shift(@i)); push(@T,shift(@T));
+}
+$code.=<<___;
+ lg @T[1],$stdframe(@i[1],$sp)
+ sllg @T[0],@T[1],`$n*4`
+ srlg @T[1],@T[1],`64-$n*4`
+ xgr $lo,@T[0]
+ xgr $hi,@T[1]
+
+ lg @T[0],$stdframe(@i[0],$sp)
+ sllg @T[1],@T[0],`($n+1)*4`
+ srlg @T[0],@T[0],`64-($n+1)*4`
+ xgr $lo,@T[1]
+ xgr $hi,@T[0]
+
+ br $ra
+.size _mul_1x1,.-_mul_1x1
+
+.globl bn_GF2m_mul_2x2
+.type bn_GF2m_mul_2x2,\@function
+.align 16
+bn_GF2m_mul_2x2:
+ stm${g} %r3,%r15,3*$SIZE_T($sp)
+
+ lghi %r1,-$stdframe-128
+ la %r0,0($sp)
+ la $sp,0(%r1,$sp) # alloca
+ st${g} %r0,0($sp) # back chain
+___
+if ($SIZE_T==8) {
+my @r=map("%r$_",(6..9));
+$code.=<<___;
+ bras $ra,_mul_1x1 # a1·b1
+ stmg $lo,$hi,16($rp)
+
+ lg $a,`$stdframe+128+4*$SIZE_T`($sp)
+ lg $b,`$stdframe+128+6*$SIZE_T`($sp)
+ bras $ra,_mul_1x1 # a0·b0
+ stmg $lo,$hi,0($rp)
+
+ lg $a,`$stdframe+128+3*$SIZE_T`($sp)
+ lg $b,`$stdframe+128+5*$SIZE_T`($sp)
+ xg $a,`$stdframe+128+4*$SIZE_T`($sp)
+ xg $b,`$stdframe+128+6*$SIZE_T`($sp)
+ bras $ra,_mul_1x1 # (a0+a1)·(b0+b1)
+ lmg @r[0],@r[3],0($rp)
+
+ xgr $lo,$hi
+ xgr $hi,@r[1]
+ xgr $lo,@r[0]
+ xgr $hi,@r[2]
+ xgr $lo,@r[3]
+ xgr $hi,@r[3]
+ xgr $lo,$hi
+ stg $hi,16($rp)
+ stg $lo,8($rp)
+___
+} else {
+$code.=<<___;
+ sllg %r3,%r3,32
+ sllg %r5,%r5,32
+ or %r3,%r4
+ or %r5,%r6
+ bras $ra,_mul_1x1
+ rllg $lo,$lo,32
+ rllg $hi,$hi,32
+ stmg $lo,$hi,0($rp)
+___
+}
+$code.=<<___;
+ lm${g} %r6,%r15,`$stdframe+128+6*$SIZE_T`($sp)
+ br $ra
+.size bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
+.string "GF(2^m) Multiplication for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/bn/asm/s390x-mont.pl b/deps/openssl/openssl/crypto/bn/asm/s390x-mont.pl
index f61246f5b..9fd64e81e 100644
--- a/deps/openssl/openssl/crypto/bn/asm/s390x-mont.pl
+++ b/deps/openssl/openssl/crypto/bn/asm/s390x-mont.pl
@@ -32,6 +32,33 @@
# Reschedule to minimize/avoid Address Generation Interlock hazard,
# make inner loops counter-based.
+# November 2010.
+#
+# Adapt for -m31 build. If kernel supports what's called "highgprs"
+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
+# instructions and achieve "64-bit" performance even in 31-bit legacy
+# application context. The feature is not specific to any particular
+# processor, as long as it's "z-CPU". Latter implies that the code
+# remains z/Architecture specific. Compatibility with 32-bit BN_ULONG
+# is achieved by swapping words after 64-bit loads, follow _dswap-s.
+# On z990 it was measured to perform 2.6-2.2 times better than
+# compiler-generated code, less for longer keys...
+
+$flavour = shift;
+
+if ($flavour =~ /3[12]/) {
+ $SIZE_T=4;
+ $g="";
+} else {
+ $SIZE_T=8;
+ $g="g";
+}
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$stdframe=16*$SIZE_T+4*8;
+
$mn0="%r0";
$num="%r1";
@@ -60,34 +87,44 @@ $code.=<<___;
.globl bn_mul_mont
.type bn_mul_mont,\@function
bn_mul_mont:
- lgf $num,164($sp) # pull $num
- sla $num,3 # $num to enumerate bytes
+ lgf $num,`$stdframe+$SIZE_T-4`($sp) # pull $num
+ sla $num,`log($SIZE_T)/log(2)` # $num to enumerate bytes
la $bp,0($num,$bp)
- stg %r2,16($sp)
+ st${g} %r2,2*$SIZE_T($sp)
cghi $num,16 #
lghi %r2,0 #
blr %r14 # if($num<16) return 0;
+___
+$code.=<<___ if ($flavour =~ /3[12]/);
+ tmll $num,4
+ bnzr %r14 # if ($num&1) return 0;
+___
+$code.=<<___ if ($flavour !~ /3[12]/);
cghi $num,96 #
bhr %r14 # if($num>96) return 0;
+___
+$code.=<<___;
+ stm${g} %r3,%r15,3*$SIZE_T($sp)
- stmg %r3,%r15,24($sp)
-
- lghi $rp,-160-8 # leave room for carry bit
+ lghi $rp,-$stdframe-8 # leave room for carry bit
lcgr $j,$num # -$num
lgr %r0,$sp
la $rp,0($rp,$sp)
la $sp,0($j,$rp) # alloca
- stg %r0,0($sp) # back chain
+ st${g} %r0,0($sp) # back chain
sra $num,3 # restore $num
la $bp,0($j,$bp) # restore $bp
ahi $num,-1 # adjust $num for inner loop
lg $n0,0($n0) # pull n0
+ _dswap $n0
lg $bi,0($bp)
+ _dswap $bi
lg $alo,0($ap)
+ _dswap $alo
mlgr $ahi,$bi # ap[0]*bp[0]
lgr $AHI,$ahi
@@ -95,6 +132,7 @@ bn_mul_mont:
msgr $mn0,$n0
lg $nlo,0($np) #
+ _dswap $nlo
mlgr $nhi,$mn0 # np[0]*m1
algr $nlo,$alo # +="tp[0]"
lghi $NHI,0
@@ -106,12 +144,14 @@ bn_mul_mont:
.align 16
.L1st:
lg $alo,0($j,$ap)
+ _dswap $alo
mlgr $ahi,$bi # ap[j]*bp[0]
algr $alo,$AHI
lghi $AHI,0
alcgr $AHI,$ahi
lg $nlo,0($j,$np)
+ _dswap $nlo
mlgr $nhi,$mn0 # np[j]*m1
algr $nlo,$NHI
lghi $NHI,0
@@ -119,22 +159,24 @@ bn_mul_mont:
algr $nlo,$alo
alcgr $NHI,$nhi
- stg $nlo,160-8($j,$sp) # tp[j-1]=
+ stg $nlo,$stdframe-8($j,$sp) # tp[j-1]=
la $j,8($j) # j++
brct $count,.L1st
algr $NHI,$AHI
lghi $AHI,0
alcgr $AHI,$AHI # upmost overflow bit
- stg $NHI,160-8($j,$sp)
- stg $AHI,160($j,$sp)
+ stg $NHI,$stdframe-8($j,$sp)
+ stg $AHI,$stdframe($j,$sp)
la $bp,8($bp) # bp++
.Louter:
lg $bi,0($bp) # bp[i]
+ _dswap $bi
lg $alo,0($ap)
+ _dswap $alo
mlgr $ahi,$bi # ap[0]*bp[i]
- alg $alo,160($sp) # +=tp[0]
+ alg $alo,$stdframe($sp) # +=tp[0]
lghi $AHI,0
alcgr $AHI,$ahi
@@ -142,6 +184,7 @@ bn_mul_mont:
msgr $mn0,$n0 # tp[0]*n0
lg $nlo,0($np) # np[0]
+ _dswap $nlo
mlgr $nhi,$mn0 # np[0]*m1
algr $nlo,$alo # +="tp[0]"
lghi $NHI,0
@@ -153,14 +196,16 @@ bn_mul_mont:
.align 16
.Linner:
lg $alo,0($j,$ap)
+ _dswap $alo
mlgr $ahi,$bi # ap[j]*bp[i]
algr $alo,$AHI
lghi $AHI,0
alcgr $ahi,$AHI
- alg $alo,160($j,$sp)# +=tp[j]
+ alg $alo,$stdframe($j,$sp)# +=tp[j]
alcgr $AHI,$ahi
lg $nlo,0($j,$np)
+ _dswap $nlo
mlgr $nhi,$mn0 # np[j]*m1
algr $nlo,$NHI
lghi $NHI,0
@@ -168,31 +213,33 @@ bn_mul_mont:
algr $nlo,$alo # +="tp[j]"
alcgr $NHI,$nhi
- stg $nlo,160-8($j,$sp) # tp[j-1]=
+ stg $nlo,$stdframe-8($j,$sp) # tp[j-1]=
la $j,8($j) # j++
brct $count,.Linner
algr $NHI,$AHI
lghi $AHI,0
alcgr $AHI,$AHI
- alg $NHI,160($j,$sp)# accumulate previous upmost overflow bit
+ alg $NHI,$stdframe($j,$sp)# accumulate previous upmost overflow bit
lghi $ahi,0
alcgr $AHI,$ahi # new upmost overflow bit
- stg $NHI,160-8($j,$sp)
- stg $AHI,160($j,$sp)
+ stg $NHI,$stdframe-8($j,$sp)
+ stg $AHI,$stdframe($j,$sp)
la $bp,8($bp) # bp++
- clg $bp,160+8+32($j,$sp) # compare to &bp[num]
+ cl${g} $bp,`$stdframe+8+4*$SIZE_T`($j,$sp) # compare to &bp[num]
jne .Louter
- lg $rp,160+8+16($j,$sp) # reincarnate rp
- la $ap,160($sp)
+ l${g} $rp,`$stdframe+8+2*$SIZE_T`($j,$sp) # reincarnate rp
+ la $ap,$stdframe($sp)
ahi $num,1 # restore $num, incidentally clears "borrow"
la $j,0(%r0)
lr $count,$num
.Lsub: lg $alo,0($j,$ap)
- slbg $alo,0($j,$np)
+ lg $nlo,0($j,$np)
+ _dswap $nlo
+ slbgr $alo,$nlo
stg $alo,0($j,$rp)
la $j,8($j)
brct $count,.Lsub
@@ -207,19 +254,24 @@ bn_mul_mont:
la $j,0(%r0)
lgr $count,$num
-.Lcopy: lg $alo,0($j,$ap) # copy or in-place refresh
- stg $j,160($j,$sp) # zap tp
+.Lcopy: lg $alo,0($j,$ap) # copy or in-place refresh
+ _dswap $alo
+ stg $j,$stdframe($j,$sp) # zap tp
stg $alo,0($j,$rp)
la $j,8($j)
brct $count,.Lcopy
- la %r1,160+8+48($j,$sp)
- lmg %r6,%r15,0(%r1)
+ la %r1,`$stdframe+8+6*$SIZE_T`($j,$sp)
+ lm${g} %r6,%r15,0(%r1)
lghi %r2,1 # signal "processed"
br %r14
.size bn_mul_mont,.-bn_mul_mont
.string "Montgomery Multiplication for s390x, CRYPTOGAMS by <appro\@openssl.org>"
___
-print $code;
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/ge;
+ s/_dswap\s+(%r[0-9]+)/sprintf("rllg\t%s,%s,32",$1,$1) if($SIZE_T==4)/e;
+ print $_,"\n";
+}
close STDOUT;
diff --git a/deps/openssl/openssl/crypto/bn/asm/s390x.S b/deps/openssl/openssl/crypto/bn/asm/s390x.S
index 43fcb79bc..43fcb79bc 100644..100755
--- a/deps/openssl/openssl/crypto/bn/asm/s390x.S
+++ b/deps/openssl/openssl/crypto/bn/asm/s390x.S
diff --git a/deps/openssl/openssl/crypto/bn/asm/sparcv9a-mont.pl b/deps/openssl/openssl/crypto/bn/asm/sparcv9a-mont.pl
index a14205f2f..a14205f2f 100644..100755
--- a/deps/openssl/openssl/crypto/bn/asm/sparcv9a-mont.pl
+++ b/deps/openssl/openssl/crypto/bn/asm/sparcv9a-mont.pl
diff --git a/deps/openssl/openssl/crypto/bn/asm/x86-gf2m.pl b/deps/openssl/openssl/crypto/bn/asm/x86-gf2m.pl
new file mode 100644
index 000000000..808a1e596
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/asm/x86-gf2m.pl
@@ -0,0 +1,313 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# May 2011
+#
+# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
+# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
+# the time being... Except that it has three code paths: pure integer
+# code suitable for any x86 CPU, MMX code suitable for PIII and later
+# and PCLMULQDQ suitable for Westmere and later. Improvement varies
+# from one benchmark and µ-arch to another. Below are interval values
+# for 163- and 571-bit ECDH benchmarks relative to compiler-generated
+# code:
+#
+# PIII 16%-30%
+# P4 12%-12%
+# Opteron 18%-40%
+# Core2 19%-44%
+# Atom 38%-64%
+# Westmere 53%-121%(PCLMULQDQ)/20%-32%(MMX)
+# Sandy Bridge 72%-127%(PCLMULQDQ)/27%-23%(MMX)
+#
+# Note that above improvement coefficients are not coefficients for
+# bn_GF2m_mul_2x2 itself. For example 120% ECDH improvement is result
+# of bn_GF2m_mul_2x2 being >4x faster. As it gets faster, benchmark
+# is more and more dominated by other subroutines, most notably by
+# BN_GF2m_mod[_mul]_arr...
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],$0,$x86only = $ARGV[$#ARGV] eq "386");
+
+$sse2=0;
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+&external_label("OPENSSL_ia32cap_P") if ($sse2);
+
+$a="eax";
+$b="ebx";
+($a1,$a2,$a4)=("ecx","edx","ebp");
+
+$R="mm0";
+@T=("mm1","mm2");
+($A,$B,$B30,$B31)=("mm2","mm3","mm4","mm5");
+@i=("esi","edi");
+
+ if (!$x86only) {
+&function_begin_B("_mul_1x1_mmx");
+ &sub ("esp",32+4);
+ &mov ($a1,$a);
+ &lea ($a2,&DWP(0,$a,$a));
+ &and ($a1,0x3fffffff);
+ &lea ($a4,&DWP(0,$a2,$a2));
+ &mov (&DWP(0*4,"esp"),0);
+ &and ($a2,0x7fffffff);
+ &movd ($A,$a);
+ &movd ($B,$b);
+ &mov (&DWP(1*4,"esp"),$a1); # a1
+ &xor ($a1,$a2); # a1^a2
+ &pxor ($B31,$B31);
+ &pxor ($B30,$B30);
+ &mov (&DWP(2*4,"esp"),$a2); # a2
+ &xor ($a2,$a4); # a2^a4
+ &mov (&DWP(3*4,"esp"),$a1); # a1^a2
+ &pcmpgtd($B31,$A); # broadcast 31st bit
+ &paddd ($A,$A); # $A<<=1
+ &xor ($a1,$a2); # a1^a4=a1^a2^a2^a4
+ &mov (&DWP(4*4,"esp"),$a4); # a4
+ &xor ($a4,$a2); # a2=a4^a2^a4
+ &pand ($B31,$B);
+ &pcmpgtd($B30,$A); # broadcast 30th bit
+ &mov (&DWP(5*4,"esp"),$a1); # a1^a4
+ &xor ($a4,$a1); # a1^a2^a4
+ &psllq ($B31,31);
+ &pand ($B30,$B);
+ &mov (&DWP(6*4,"esp"),$a2); # a2^a4
+ &mov (@i[0],0x7);
+ &mov (&DWP(7*4,"esp"),$a4); # a1^a2^a4
+ &mov ($a4,@i[0]);
+ &and (@i[0],$b);
+ &shr ($b,3);
+ &mov (@i[1],$a4);
+ &psllq ($B30,30);
+ &and (@i[1],$b);
+ &shr ($b,3);
+ &movd ($R,&DWP(0,"esp",@i[0],4));
+ &mov (@i[0],$a4);
+ &and (@i[0],$b);
+ &shr ($b,3);
+ for($n=1;$n<9;$n++) {
+ &movd (@T[1],&DWP(0,"esp",@i[1],4));
+ &mov (@i[1],$a4);
+ &psllq (@T[1],3*$n);
+ &and (@i[1],$b);
+ &shr ($b,3);
+ &pxor ($R,@T[1]);
+
+ push(@i,shift(@i)); push(@T,shift(@T));
+ }
+ &movd (@T[1],&DWP(0,"esp",@i[1],4));
+ &pxor ($R,$B30);
+ &psllq (@T[1],3*$n++);
+ &pxor ($R,@T[1]);
+
+ &movd (@T[0],&DWP(0,"esp",@i[0],4));
+ &pxor ($R,$B31);
+ &psllq (@T[0],3*$n);
+ &add ("esp",32+4);
+ &pxor ($R,@T[0]);
+ &ret ();
+&function_end_B("_mul_1x1_mmx");
+ }
+
+($lo,$hi)=("eax","edx");
+@T=("ecx","ebp");
+
+&function_begin_B("_mul_1x1_ialu");
+ &sub ("esp",32+4);
+ &mov ($a1,$a);
+ &lea ($a2,&DWP(0,$a,$a));
+ &lea ($a4,&DWP(0,"",$a,4));
+ &and ($a1,0x3fffffff);
+ &lea (@i[1],&DWP(0,$lo,$lo));
+ &sar ($lo,31); # broadcast 31st bit
+ &mov (&DWP(0*4,"esp"),0);
+ &and ($a2,0x7fffffff);
+ &mov (&DWP(1*4,"esp"),$a1); # a1
+ &xor ($a1,$a2); # a1^a2
+ &mov (&DWP(2*4,"esp"),$a2); # a2
+ &xor ($a2,$a4); # a2^a4
+ &mov (&DWP(3*4,"esp"),$a1); # a1^a2
+ &xor ($a1,$a2); # a1^a4=a1^a2^a2^a4
+ &mov (&DWP(4*4,"esp"),$a4); # a4
+ &xor ($a4,$a2); # a2=a4^a2^a4
+ &mov (&DWP(5*4,"esp"),$a1); # a1^a4
+ &xor ($a4,$a1); # a1^a2^a4
+ &sar (@i[1],31); # broardcast 30th bit
+ &and ($lo,$b);
+ &mov (&DWP(6*4,"esp"),$a2); # a2^a4
+ &and (@i[1],$b);
+ &mov (&DWP(7*4,"esp"),$a4); # a1^a2^a4
+ &mov ($hi,$lo);
+ &shl ($lo,31);
+ &mov (@T[0],@i[1]);
+ &shr ($hi,1);
+
+ &mov (@i[0],0x7);
+ &shl (@i[1],30);
+ &and (@i[0],$b);
+ &shr (@T[0],2);
+ &xor ($lo,@i[1]);
+
+ &shr ($b,3);
+ &mov (@i[1],0x7); # 5-byte instruction!?
+ &and (@i[1],$b);
+ &shr ($b,3);
+ &xor ($hi,@T[0]);
+ &xor ($lo,&DWP(0,"esp",@i[0],4));
+ &mov (@i[0],0x7);
+ &and (@i[0],$b);
+ &shr ($b,3);
+ for($n=1;$n<9;$n++) {
+ &mov (@T[1],&DWP(0,"esp",@i[1],4));
+ &mov (@i[1],0x7);
+ &mov (@T[0],@T[1]);
+ &shl (@T[1],3*$n);
+ &and (@i[1],$b);
+ &shr (@T[0],32-3*$n);
+ &xor ($lo,@T[1]);
+ &shr ($b,3);
+ &xor ($hi,@T[0]);
+
+ push(@i,shift(@i)); push(@T,shift(@T));
+ }
+ &mov (@T[1],&DWP(0,"esp",@i[1],4));
+ &mov (@T[0],@T[1]);
+ &shl (@T[1],3*$n);
+ &mov (@i[1],&DWP(0,"esp",@i[0],4));
+ &shr (@T[0],32-3*$n); $n++;
+ &mov (@i[0],@i[1]);
+ &xor ($lo,@T[1]);
+ &shl (@i[1],3*$n);
+ &xor ($hi,@T[0]);
+ &shr (@i[0],32-3*$n);
+ &xor ($lo,@i[1]);
+ &xor ($hi,@i[0]);
+
+ &add ("esp",32+4);
+ &ret ();
+&function_end_B("_mul_1x1_ialu");
+
+# void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, BN_ULONG b0);
+&function_begin_B("bn_GF2m_mul_2x2");
+if (!$x86only) {
+ &picmeup("edx","OPENSSL_ia32cap_P");
+ &mov ("eax",&DWP(0,"edx"));
+ &mov ("edx",&DWP(4,"edx"));
+ &test ("eax",1<<23); # check MMX bit
+ &jz (&label("ialu"));
+if ($sse2) {
+ &test ("eax",1<<24); # check FXSR bit
+ &jz (&label("mmx"));
+ &test ("edx",1<<1); # check PCLMULQDQ bit
+ &jz (&label("mmx"));
+
+ &movups ("xmm0",&QWP(8,"esp"));
+ &shufps ("xmm0","xmm0",0b10110001);
+ &pclmulqdq ("xmm0","xmm0",1);
+ &mov ("eax",&DWP(4,"esp"));
+ &movups (&QWP(0,"eax"),"xmm0");
+ &ret ();
+
+&set_label("mmx",16);
+}
+ &push ("ebp");
+ &push ("ebx");
+ &push ("esi");
+ &push ("edi");
+ &mov ($a,&wparam(1));
+ &mov ($b,&wparam(3));
+ &call ("_mul_1x1_mmx"); # a1·b1
+ &movq ("mm7",$R);
+
+ &mov ($a,&wparam(2));
+ &mov ($b,&wparam(4));
+ &call ("_mul_1x1_mmx"); # a0·b0
+ &movq ("mm6",$R);
+
+ &mov ($a,&wparam(1));
+ &mov ($b,&wparam(3));
+ &xor ($a,&wparam(2));
+ &xor ($b,&wparam(4));
+ &call ("_mul_1x1_mmx"); # (a0+a1)·(b0+b1)
+ &pxor ($R,"mm7");
+ &mov ($a,&wparam(0));
+ &pxor ($R,"mm6"); # (a0+a1)·(b0+b1)-a1·b1-a0·b0
+
+ &movq ($A,$R);
+ &psllq ($R,32);
+ &pop ("edi");
+ &psrlq ($A,32);
+ &pop ("esi");
+ &pxor ($R,"mm6");
+ &pop ("ebx");
+ &pxor ($A,"mm7");
+ &movq (&QWP(0,$a),$R);
+ &pop ("ebp");
+ &movq (&QWP(8,$a),$A);
+ &emms ();
+ &ret ();
+&set_label("ialu",16);
+}
+ &push ("ebp");
+ &push ("ebx");
+ &push ("esi");
+ &push ("edi");
+ &stack_push(4+1);
+
+ &mov ($a,&wparam(1));
+ &mov ($b,&wparam(3));
+ &call ("_mul_1x1_ialu"); # a1·b1
+ &mov (&DWP(8,"esp"),$lo);
+ &mov (&DWP(12,"esp"),$hi);
+
+ &mov ($a,&wparam(2));
+ &mov ($b,&wparam(4));
+ &call ("_mul_1x1_ialu"); # a0·b0
+ &mov (&DWP(0,"esp"),$lo);
+ &mov (&DWP(4,"esp"),$hi);
+
+ &mov ($a,&wparam(1));
+ &mov ($b,&wparam(3));
+ &xor ($a,&wparam(2));
+ &xor ($b,&wparam(4));
+ &call ("_mul_1x1_ialu"); # (a0+a1)·(b0+b1)
+
+ &mov ("ebp",&wparam(0));
+ @r=("ebx","ecx","edi","esi");
+ &mov (@r[0],&DWP(0,"esp"));
+ &mov (@r[1],&DWP(4,"esp"));
+ &mov (@r[2],&DWP(8,"esp"));
+ &mov (@r[3],&DWP(12,"esp"));
+
+ &xor ($lo,$hi);
+ &xor ($hi,@r[1]);
+ &xor ($lo,@r[0]);
+ &mov (&DWP(0,"ebp"),@r[0]);
+ &xor ($hi,@r[2]);
+ &mov (&DWP(12,"ebp"),@r[3]);
+ &xor ($lo,@r[3]);
+ &stack_pop(4+1);
+ &xor ($hi,@r[3]);
+ &pop ("edi");
+ &xor ($lo,$hi);
+ &pop ("esi");
+ &mov (&DWP(8,"ebp"),$hi);
+ &pop ("ebx");
+ &mov (&DWP(4,"ebp"),$lo);
+ &pop ("ebp");
+ &ret ();
+&function_end_B("bn_GF2m_mul_2x2");
+
+&asciz ("GF(2^m) Multiplication for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/deps/openssl/openssl/crypto/bn/asm/x86-mont.pl b/deps/openssl/openssl/crypto/bn/asm/x86-mont.pl
index e8f6b0508..e8f6b0508 100644..100755
--- a/deps/openssl/openssl/crypto/bn/asm/x86-mont.pl
+++ b/deps/openssl/openssl/crypto/bn/asm/x86-mont.pl
diff --git a/deps/openssl/openssl/crypto/bn/asm/x86_64-gf2m.pl b/deps/openssl/openssl/crypto/bn/asm/x86_64-gf2m.pl
new file mode 100644
index 000000000..a30d4ef02
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/asm/x86_64-gf2m.pl
@@ -0,0 +1,389 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# May 2011
+#
+# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
+# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
+# the time being... Except that it has two code paths: code suitable
+# for any x86_64 CPU and PCLMULQDQ one suitable for Westmere and
+# later. Improvement varies from one benchmark and µ-arch to another.
+# Vanilla code path is at most 20% faster than compiler-generated code
+# [not very impressive], while PCLMULQDQ - whole 85%-160% better on
+# 163- and 571-bit ECDH benchmarks on Intel CPUs. Keep in mind that
+# these coefficients are not ones for bn_GF2m_mul_2x2 itself, as not
+# all CPU time is burnt in it...
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open STDOUT,"| \"$^X\" $xlate $flavour $output";
+
+($lo,$hi)=("%rax","%rdx"); $a=$lo;
+($i0,$i1)=("%rsi","%rdi");
+($t0,$t1)=("%rbx","%rcx");
+($b,$mask)=("%rbp","%r8");
+($a1,$a2,$a4,$a8,$a12,$a48)=map("%r$_",(9..15));
+($R,$Tx)=("%xmm0","%xmm1");
+
+$code.=<<___;
+.text
+
+.type _mul_1x1,\@abi-omnipotent
+.align 16
+_mul_1x1:
+ sub \$128+8,%rsp
+ mov \$-1,$a1
+ lea ($a,$a),$i0
+ shr \$3,$a1
+ lea (,$a,4),$i1
+ and $a,$a1 # a1=a&0x1fffffffffffffff
+ lea (,$a,8),$a8
+ sar \$63,$a # broadcast 63rd bit
+ lea ($a1,$a1),$a2
+ sar \$63,$i0 # broadcast 62nd bit
+ lea (,$a1,4),$a4
+ and $b,$a
+ sar \$63,$i1 # boardcast 61st bit
+ mov $a,$hi # $a is $lo
+ shl \$63,$lo
+ and $b,$i0
+ shr \$1,$hi
+ mov $i0,$t1
+ shl \$62,$i0
+ and $b,$i1
+ shr \$2,$t1
+ xor $i0,$lo
+ mov $i1,$t0
+ shl \$61,$i1
+ xor $t1,$hi
+ shr \$3,$t0
+ xor $i1,$lo
+ xor $t0,$hi
+
+ mov $a1,$a12
+ movq \$0,0(%rsp) # tab[0]=0
+ xor $a2,$a12 # a1^a2
+ mov $a1,8(%rsp) # tab[1]=a1
+ mov $a4,$a48
+ mov $a2,16(%rsp) # tab[2]=a2
+ xor $a8,$a48 # a4^a8
+ mov $a12,24(%rsp) # tab[3]=a1^a2
+
+ xor $a4,$a1
+ mov $a4,32(%rsp) # tab[4]=a4
+ xor $a4,$a2
+ mov $a1,40(%rsp) # tab[5]=a1^a4
+ xor $a4,$a12
+ mov $a2,48(%rsp) # tab[6]=a2^a4
+ xor $a48,$a1 # a1^a4^a4^a8=a1^a8
+ mov $a12,56(%rsp) # tab[7]=a1^a2^a4
+ xor $a48,$a2 # a2^a4^a4^a8=a1^a8
+
+ mov $a8,64(%rsp) # tab[8]=a8
+ xor $a48,$a12 # a1^a2^a4^a4^a8=a1^a2^a8
+ mov $a1,72(%rsp) # tab[9]=a1^a8
+ xor $a4,$a1 # a1^a8^a4
+ mov $a2,80(%rsp) # tab[10]=a2^a8
+ xor $a4,$a2 # a2^a8^a4
+ mov $a12,88(%rsp) # tab[11]=a1^a2^a8
+
+ xor $a4,$a12 # a1^a2^a8^a4
+ mov $a48,96(%rsp) # tab[12]=a4^a8
+ mov $mask,$i0
+ mov $a1,104(%rsp) # tab[13]=a1^a4^a8
+ and $b,$i0
+ mov $a2,112(%rsp) # tab[14]=a2^a4^a8
+ shr \$4,$b
+ mov $a12,120(%rsp) # tab[15]=a1^a2^a4^a8
+ mov $mask,$i1
+ and $b,$i1
+ shr \$4,$b
+
+ movq (%rsp,$i0,8),$R # half of calculations is done in SSE2
+ mov $mask,$i0
+ and $b,$i0
+ shr \$4,$b
+___
+ for ($n=1;$n<8;$n++) {
+ $code.=<<___;
+ mov (%rsp,$i1,8),$t1
+ mov $mask,$i1
+ mov $t1,$t0
+ shl \$`8*$n-4`,$t1
+ and $b,$i1
+ movq (%rsp,$i0,8),$Tx
+ shr \$`64-(8*$n-4)`,$t0
+ xor $t1,$lo
+ pslldq \$$n,$Tx
+ mov $mask,$i0
+ shr \$4,$b
+ xor $t0,$hi
+ and $b,$i0
+ shr \$4,$b
+ pxor $Tx,$R
+___
+ }
+$code.=<<___;
+ mov (%rsp,$i1,8),$t1
+ mov $t1,$t0
+ shl \$`8*$n-4`,$t1
+ movq $R,$i0
+ shr \$`64-(8*$n-4)`,$t0
+ xor $t1,$lo
+ psrldq \$8,$R
+ xor $t0,$hi
+ movq $R,$i1
+ xor $i0,$lo
+ xor $i1,$hi
+
+ add \$128+8,%rsp
+ ret
+.Lend_mul_1x1:
+.size _mul_1x1,.-_mul_1x1
+___
+
+($rp,$a1,$a0,$b1,$b0) = $win64? ("%rcx","%rdx","%r8", "%r9","%r10") : # Win64 order
+ ("%rdi","%rsi","%rdx","%rcx","%r8"); # Unix order
+
+$code.=<<___;
+.extern OPENSSL_ia32cap_P
+.globl bn_GF2m_mul_2x2
+.type bn_GF2m_mul_2x2,\@abi-omnipotent
+.align 16
+bn_GF2m_mul_2x2:
+ mov OPENSSL_ia32cap_P(%rip),%rax
+ bt \$33,%rax
+ jnc .Lvanilla_mul_2x2
+
+ movq $a1,%xmm0
+ movq $b1,%xmm1
+ movq $a0,%xmm2
+___
+$code.=<<___ if ($win64);
+ movq 40(%rsp),%xmm3
+___
+$code.=<<___ if (!$win64);
+ movq $b0,%xmm3
+___
+$code.=<<___;
+ movdqa %xmm0,%xmm4
+ movdqa %xmm1,%xmm5
+ pclmulqdq \$0,%xmm1,%xmm0 # a1·b1
+ pxor %xmm2,%xmm4
+ pxor %xmm3,%xmm5
+ pclmulqdq \$0,%xmm3,%xmm2 # a0·b0
+ pclmulqdq \$0,%xmm5,%xmm4 # (a0+a1)·(b0+b1)
+ xorps %xmm0,%xmm4
+ xorps %xmm2,%xmm4 # (a0+a1)·(b0+b1)-a0·b0-a1·b1
+ movdqa %xmm4,%xmm5
+ pslldq \$8,%xmm4
+ psrldq \$8,%xmm5
+ pxor %xmm4,%xmm2
+ pxor %xmm5,%xmm0
+ movdqu %xmm2,0($rp)
+ movdqu %xmm0,16($rp)
+ ret
+
+.align 16
+.Lvanilla_mul_2x2:
+ lea -8*17(%rsp),%rsp
+___
+$code.=<<___ if ($win64);
+ mov `8*17+40`(%rsp),$b0
+ mov %rdi,8*15(%rsp)
+ mov %rsi,8*16(%rsp)
+___
+$code.=<<___;
+ mov %r14,8*10(%rsp)
+ mov %r13,8*11(%rsp)
+ mov %r12,8*12(%rsp)
+ mov %rbp,8*13(%rsp)
+ mov %rbx,8*14(%rsp)
+.Lbody_mul_2x2:
+ mov $rp,32(%rsp) # save the arguments
+ mov $a1,40(%rsp)
+ mov $a0,48(%rsp)
+ mov $b1,56(%rsp)
+ mov $b0,64(%rsp)
+
+ mov \$0xf,$mask
+ mov $a1,$a
+ mov $b1,$b
+ call _mul_1x1 # a1·b1
+ mov $lo,16(%rsp)
+ mov $hi,24(%rsp)
+
+ mov 48(%rsp),$a
+ mov 64(%rsp),$b
+ call _mul_1x1 # a0·b0
+ mov $lo,0(%rsp)
+ mov $hi,8(%rsp)
+
+ mov 40(%rsp),$a
+ mov 56(%rsp),$b
+ xor 48(%rsp),$a
+ xor 64(%rsp),$b
+ call _mul_1x1 # (a0+a1)·(b0+b1)
+___
+ @r=("%rbx","%rcx","%rdi","%rsi");
+$code.=<<___;
+ mov 0(%rsp),@r[0]
+ mov 8(%rsp),@r[1]
+ mov 16(%rsp),@r[2]
+ mov 24(%rsp),@r[3]
+ mov 32(%rsp),%rbp
+
+ xor $hi,$lo
+ xor @r[1],$hi
+ xor @r[0],$lo
+ mov @r[0],0(%rbp)
+ xor @r[2],$hi
+ mov @r[3],24(%rbp)
+ xor @r[3],$lo
+ xor @r[3],$hi
+ xor $hi,$lo
+ mov $hi,16(%rbp)
+ mov $lo,8(%rbp)
+
+ mov 8*10(%rsp),%r14
+ mov 8*11(%rsp),%r13
+ mov 8*12(%rsp),%r12
+ mov 8*13(%rsp),%rbp
+ mov 8*14(%rsp),%rbx
+___
+$code.=<<___ if ($win64);
+ mov 8*15(%rsp),%rdi
+ mov 8*16(%rsp),%rsi
+___
+$code.=<<___;
+ lea 8*17(%rsp),%rsp
+ ret
+.Lend_mul_2x2:
+.size bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
+.asciz "GF(2^m) Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align 16
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+
+.type se_handler,\@abi-omnipotent
+.align 16
+se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 152($context),%rax # pull context->Rsp
+ mov 248($context),%rbx # pull context->Rip
+
+ lea .Lbody_mul_2x2(%rip),%r10
+ cmp %r10,%rbx # context->Rip<"prologue" label
+ jb .Lin_prologue
+
+ mov 8*10(%rax),%r14 # mimic epilogue
+ mov 8*11(%rax),%r13
+ mov 8*12(%rax),%r12
+ mov 8*13(%rax),%rbp
+ mov 8*14(%rax),%rbx
+ mov 8*15(%rax),%rdi
+ mov 8*16(%rax),%rsi
+
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %rsi,168($context) # restore context->Rsi
+ mov %rdi,176($context) # restore context->Rdi
+ mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R13
+ mov %r14,232($context) # restore context->R14
+
+.Lin_prologue:
+ lea 8*17(%rax),%rax
+ mov %rax,152($context) # restore context->Rsp
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$154,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size se_handler,.-se_handler
+
+.section .pdata
+.align 4
+ .rva _mul_1x1
+ .rva .Lend_mul_1x1
+ .rva .LSEH_info_1x1
+
+ .rva .Lvanilla_mul_2x2
+ .rva .Lend_mul_2x2
+ .rva .LSEH_info_2x2
+.section .xdata
+.align 8
+.LSEH_info_1x1:
+ .byte 0x01,0x07,0x02,0x00
+ .byte 0x07,0x01,0x11,0x00 # sub rsp,128+8
+.LSEH_info_2x2:
+ .byte 9,0,0,0
+ .rva se_handler
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/bn/asm/x86_64-mont.pl b/deps/openssl/openssl/crypto/bn/asm/x86_64-mont.pl
index 3b7a6f243..17fb94c84 100755
--- a/deps/openssl/openssl/crypto/bn/asm/x86_64-mont.pl
+++ b/deps/openssl/openssl/crypto/bn/asm/x86_64-mont.pl
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
# project. The module is, however, dual licensed under OpenSSL and
# CRYPTOGAMS licenses depending on where you obtain it. For further
# details see http://www.openssl.org/~appro/cryptogams/.
@@ -15,6 +15,20 @@
# respectful 50%. It remains to be seen if loop unrolling and
# dedicated squaring routine can provide further improvement...
+# July 2011.
+#
+# Add dedicated squaring procedure. Performance improvement varies
+# from platform to platform, but in average it's ~5%/15%/25%/33%
+# for 512-/1024-/2048-/4096-bit RSA *sign* benchmarks respectively.
+
+# August 2011.
+#
+# Unroll and modulo-schedule inner loops in such manner that they
+# are "fallen through" for input lengths of 8, which is critical for
+# 1024-bit RSA *sign*. Average performance improvement in comparison
+# to *initial* version of this module from 2005 is ~0%/30%/40%/45%
+# for 512-/1024-/2048-/4096-bit RSA *sign* benchmarks respectively.
+
$flavour = shift;
$output = shift;
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
@@ -26,7 +40,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
# int bn_mul_mont(
$rp="%rdi"; # BN_ULONG *rp,
@@ -37,7 +52,6 @@ $n0="%r8"; # const BN_ULONG *n0,
$num="%r9"; # int num);
$lo0="%r10";
$hi0="%r11";
-$bp="%r12"; # reassign $bp
$hi1="%r13";
$i="%r14";
$j="%r15";
@@ -51,6 +65,16 @@ $code=<<___;
.type bn_mul_mont,\@function,6
.align 16
bn_mul_mont:
+ test \$3,${num}d
+ jnz .Lmul_enter
+ cmp \$8,${num}d
+ jb .Lmul_enter
+ cmp $ap,$bp
+ jne .Lmul4x_enter
+ jmp .Lsqr4x_enter
+
+.align 16
+.Lmul_enter:
push %rbx
push %rbp
push %r12
@@ -66,48 +90,66 @@ bn_mul_mont:
and \$-1024,%rsp # minimize TLB usage
mov %r11,8(%rsp,$num,8) # tp[num+1]=%rsp
-.Lprologue:
- mov %rdx,$bp # $bp reassigned, remember?
-
+.Lmul_body:
+ mov $bp,%r12 # reassign $bp
+___
+ $bp="%r12";
+$code.=<<___;
mov ($n0),$n0 # pull n0[0] value
+ mov ($bp),$m0 # m0=bp[0]
+ mov ($ap),%rax
xor $i,$i # i=0
xor $j,$j # j=0
- mov ($bp),$m0 # m0=bp[0]
- mov ($ap),%rax
+ mov $n0,$m1
mulq $m0 # ap[0]*bp[0]
mov %rax,$lo0
- mov %rdx,$hi0
+ mov ($np),%rax
- imulq $n0,%rax # "tp[0]"*n0
- mov %rax,$m1
+ imulq $lo0,$m1 # "tp[0]"*n0
+ mov %rdx,$hi0
- mulq ($np) # np[0]*m1
- add $lo0,%rax # discarded
+ mulq $m1 # np[0]*m1
+ add %rax,$lo0 # discarded
+ mov 8($ap),%rax
adc \$0,%rdx
mov %rdx,$hi1
lea 1($j),$j # j++
+ jmp .L1st_enter
+
+.align 16
.L1st:
+ add %rax,$hi1
mov ($ap,$j,8),%rax
- mulq $m0 # ap[j]*bp[0]
- add $hi0,%rax
adc \$0,%rdx
- mov %rax,$lo0
+ add $hi0,$hi1 # np[j]*m1+ap[j]*bp[0]
+ mov $lo0,$hi0
+ adc \$0,%rdx
+ mov $hi1,-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$hi1
+
+.L1st_enter:
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$hi0
mov ($np,$j,8),%rax
- mov %rdx,$hi0
+ adc \$0,%rdx
+ lea 1($j),$j # j++
+ mov %rdx,$lo0
mulq $m1 # np[j]*m1
- add $hi1,%rax
- lea 1($j),$j # j++
+ cmp $num,$j
+ jne .L1st
+
+ add %rax,$hi1
+ mov ($ap),%rax # ap[0]
adc \$0,%rdx
- add $lo0,%rax # np[j]*m1+ap[j]*bp[0]
+ add $hi0,$hi1 # np[j]*m1+ap[j]*bp[0]
adc \$0,%rdx
- mov %rax,-16(%rsp,$j,8) # tp[j-1]
- cmp $num,$j
+ mov $hi1,-16(%rsp,$j,8) # tp[j-1]
mov %rdx,$hi1
- jl .L1st
+ mov $lo0,$hi0
xor %rdx,%rdx
add $hi0,$hi1
@@ -116,50 +158,64 @@ bn_mul_mont:
mov %rdx,(%rsp,$num,8) # store upmost overflow bit
lea 1($i),$i # i++
-.align 4
+ jmp .Louter
+.align 16
.Louter:
- xor $j,$j # j=0
-
mov ($bp,$i,8),$m0 # m0=bp[i]
- mov ($ap),%rax # ap[0]
+ xor $j,$j # j=0
+ mov $n0,$m1
+ mov (%rsp),$lo0
mulq $m0 # ap[0]*bp[i]
- add (%rsp),%rax # ap[0]*bp[i]+tp[0]
+ add %rax,$lo0 # ap[0]*bp[i]+tp[0]
+ mov ($np),%rax
adc \$0,%rdx
- mov %rax,$lo0
- mov %rdx,$hi0
- imulq $n0,%rax # tp[0]*n0
- mov %rax,$m1
+ imulq $lo0,$m1 # tp[0]*n0
+ mov %rdx,$hi0
- mulq ($np,$j,8) # np[0]*m1
- add $lo0,%rax # discarded
- mov 8(%rsp),$lo0 # tp[1]
+ mulq $m1 # np[0]*m1
+ add %rax,$lo0 # discarded
+ mov 8($ap),%rax
adc \$0,%rdx
+ mov 8(%rsp),$lo0 # tp[1]
mov %rdx,$hi1
lea 1($j),$j # j++
-.align 4
+ jmp .Linner_enter
+
+.align 16
.Linner:
+ add %rax,$hi1
mov ($ap,$j,8),%rax
- mulq $m0 # ap[j]*bp[i]
- add $hi0,%rax
adc \$0,%rdx
- add %rax,$lo0 # ap[j]*bp[i]+tp[j]
+ add $lo0,$hi1 # np[j]*m1+ap[j]*bp[i]+tp[j]
+ mov (%rsp,$j,8),$lo0
+ adc \$0,%rdx
+ mov $hi1,-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$hi1
+
+.Linner_enter:
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$hi0
mov ($np,$j,8),%rax
adc \$0,%rdx
+ add $hi0,$lo0 # ap[j]*bp[i]+tp[j]
mov %rdx,$hi0
+ adc \$0,$hi0
+ lea 1($j),$j # j++
mulq $m1 # np[j]*m1
- add $hi1,%rax
- lea 1($j),$j # j++
- adc \$0,%rdx
- add $lo0,%rax # np[j]*m1+ap[j]*bp[i]+tp[j]
+ cmp $num,$j
+ jne .Linner
+
+ add %rax,$hi1
+ mov ($ap),%rax # ap[0]
adc \$0,%rdx
+ add $lo0,$hi1 # np[j]*m1+ap[j]*bp[i]+tp[j]
mov (%rsp,$j,8),$lo0
- cmp $num,$j
- mov %rax,-16(%rsp,$j,8) # tp[j-1]
+ adc \$0,%rdx
+ mov $hi1,-16(%rsp,$j,8) # tp[j-1]
mov %rdx,$hi1
- jl .Linner
xor %rdx,%rdx
add $hi0,$hi1
@@ -173,35 +229,449 @@ bn_mul_mont:
cmp $num,$i
jl .Louter
- lea (%rsp),$ap # borrow ap for tp
- lea -1($num),$j # j=num-1
-
- mov ($ap),%rax # tp[0]
xor $i,$i # i=0 and clear CF!
+ mov (%rsp),%rax # tp[0]
+ lea (%rsp),$ap # borrow ap for tp
+ mov $num,$j # j=num
jmp .Lsub
.align 16
.Lsub: sbb ($np,$i,8),%rax
mov %rax,($rp,$i,8) # rp[i]=tp[i]-np[i]
- dec $j # doesn't affect CF!
mov 8($ap,$i,8),%rax # tp[i+1]
lea 1($i),$i # i++
- jge .Lsub
+ dec $j # doesnn't affect CF!
+ jnz .Lsub
sbb \$0,%rax # handle upmost overflow bit
+ xor $i,$i
and %rax,$ap
not %rax
mov $rp,$np
and %rax,$np
- lea -1($num),$j
+ mov $num,$j # j=num
or $np,$ap # ap=borrow?tp:rp
.align 16
.Lcopy: # copy or in-place refresh
+ mov ($ap,$i,8),%rax
+ mov $i,(%rsp,$i,8) # zap temporary vector
+ mov %rax,($rp,$i,8) # rp[i]=tp[i]
+ lea 1($i),$i
+ sub \$1,$j
+ jnz .Lcopy
+
+ mov 8(%rsp,$num,8),%rsi # restore %rsp
+ mov \$1,%rax
+ mov (%rsi),%r15
+ mov 8(%rsi),%r14
+ mov 16(%rsi),%r13
+ mov 24(%rsi),%r12
+ mov 32(%rsi),%rbp
+ mov 40(%rsi),%rbx
+ lea 48(%rsi),%rsp
+.Lmul_epilogue:
+ ret
+.size bn_mul_mont,.-bn_mul_mont
+___
+{{{
+my @A=("%r10","%r11");
+my @N=("%r13","%rdi");
+$code.=<<___;
+.type bn_mul4x_mont,\@function,6
+.align 16
+bn_mul4x_mont:
+.Lmul4x_enter:
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov ${num}d,${num}d
+ lea 4($num),%r10
+ mov %rsp,%r11
+ neg %r10
+ lea (%rsp,%r10,8),%rsp # tp=alloca(8*(num+4))
+ and \$-1024,%rsp # minimize TLB usage
+
+ mov %r11,8(%rsp,$num,8) # tp[num+1]=%rsp
+.Lmul4x_body:
+ mov $rp,16(%rsp,$num,8) # tp[num+2]=$rp
+ mov %rdx,%r12 # reassign $bp
+___
+ $bp="%r12";
+$code.=<<___;
+ mov ($n0),$n0 # pull n0[0] value
+ mov ($bp),$m0 # m0=bp[0]
+ mov ($ap),%rax
+
+ xor $i,$i # i=0
+ xor $j,$j # j=0
+
+ mov $n0,$m1
+ mulq $m0 # ap[0]*bp[0]
+ mov %rax,$A[0]
+ mov ($np),%rax
+
+ imulq $A[0],$m1 # "tp[0]"*n0
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[0]*m1
+ add %rax,$A[0] # discarded
+ mov 8($ap),%rax
+ adc \$0,%rdx
+ mov %rdx,$N[1]
+
+ mulq $m0
+ add %rax,$A[1]
+ mov 8($np),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[0]
+
+ mulq $m1
+ add %rax,$N[1]
+ mov 16($ap),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1]
+ lea 4($j),$j # j++
+ adc \$0,%rdx
+ mov $N[1],(%rsp)
+ mov %rdx,$N[0]
+ jmp .L1st4x
+.align 16
+.L1st4x:
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[0]
+ mov -16($np,$j,8),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov -8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[0],-24(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[1]
+ mov -8($np,$j,8),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
mov ($ap,$j,8),%rax
- mov %rax,($rp,$j,8) # rp[i]=tp[i]
- mov $i,(%rsp,$j,8) # zap temporary vector
+ adc \$0,%rdx
+ add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[1],-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[0]
+ mov ($np,$j,8),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov 8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[0],-8(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[1]
+ mov 8($np,$j,8),%rax
+ adc \$0,%rdx
+ lea 4($j),$j # j++
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov -16($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[1],-32(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+ cmp $num,$j
+ jl .L1st4x
+
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[0]
+ mov -16($np,$j,8),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov -8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[0],-24(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[1]
+ mov -8($np,$j,8),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov ($ap),%rax # ap[0]
+ adc \$0,%rdx
+ add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[1],-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+
+ xor $N[1],$N[1]
+ add $A[0],$N[0]
+ adc \$0,$N[1]
+ mov $N[0],-8(%rsp,$j,8)
+ mov $N[1],(%rsp,$j,8) # store upmost overflow bit
+
+ lea 1($i),$i # i++
+.align 4
+.Louter4x:
+ mov ($bp,$i,8),$m0 # m0=bp[i]
+ xor $j,$j # j=0
+ mov (%rsp),$A[0]
+ mov $n0,$m1
+ mulq $m0 # ap[0]*bp[i]
+ add %rax,$A[0] # ap[0]*bp[i]+tp[0]
+ mov ($np),%rax
+ adc \$0,%rdx
+
+ imulq $A[0],$m1 # tp[0]*n0
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[0]*m1
+ add %rax,$A[0] # "$N[0]", discarded
+ mov 8($ap),%rax
+ adc \$0,%rdx
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[1]
+ mov 8($np),%rax
+ adc \$0,%rdx
+ add 8(%rsp),$A[1] # +tp[1]
+ adc \$0,%rdx
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov 16($ap),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1] # np[j]*m1+ap[j]*bp[i]+tp[j]
+ lea 4($j),$j # j+=2
+ adc \$0,%rdx
+ mov $N[1],(%rsp) # tp[j-1]
+ mov %rdx,$N[0]
+ jmp .Linner4x
+.align 16
+.Linner4x:
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[0]
+ mov -16($np,$j,8),%rax
+ adc \$0,%rdx
+ add -16(%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j]
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov -8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0]
+ adc \$0,%rdx
+ mov $N[0],-24(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[1]
+ mov -8($np,$j,8),%rax
+ adc \$0,%rdx
+ add -8(%rsp,$j,8),$A[1]
+ adc \$0,%rdx
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov ($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1]
+ adc \$0,%rdx
+ mov $N[1],-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[0]
+ mov ($np,$j,8),%rax
+ adc \$0,%rdx
+ add (%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j]
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov 8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0]
+ adc \$0,%rdx
+ mov $N[0],-8(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[1]
+ mov 8($np,$j,8),%rax
+ adc \$0,%rdx
+ add 8(%rsp,$j,8),$A[1]
+ adc \$0,%rdx
+ lea 4($j),$j # j++
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov -16($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1]
+ adc \$0,%rdx
+ mov $N[1],-32(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+ cmp $num,$j
+ jl .Linner4x
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[0]
+ mov -16($np,$j,8),%rax
+ adc \$0,%rdx
+ add -16(%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j]
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov -8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0]
+ adc \$0,%rdx
+ mov $N[0],-24(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[1]
+ mov -8($np,$j,8),%rax
+ adc \$0,%rdx
+ add -8(%rsp,$j,8),$A[1]
+ adc \$0,%rdx
+ lea 1($i),$i # i++
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov ($ap),%rax # ap[0]
+ adc \$0,%rdx
+ add $A[1],$N[1]
+ adc \$0,%rdx
+ mov $N[1],-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+
+ xor $N[1],$N[1]
+ add $A[0],$N[0]
+ adc \$0,$N[1]
+ add (%rsp,$num,8),$N[0] # pull upmost overflow bit
+ adc \$0,$N[1]
+ mov $N[0],-8(%rsp,$j,8)
+ mov $N[1],(%rsp,$j,8) # store upmost overflow bit
+
+ cmp $num,$i
+ jl .Louter4x
+___
+{
+my @ri=("%rax","%rdx",$m0,$m1);
+$code.=<<___;
+ mov 16(%rsp,$num,8),$rp # restore $rp
+ mov 0(%rsp),@ri[0] # tp[0]
+ pxor %xmm0,%xmm0
+ mov 8(%rsp),@ri[1] # tp[1]
+ shr \$2,$num # num/=4
+ lea (%rsp),$ap # borrow ap for tp
+ xor $i,$i # i=0 and clear CF!
+
+ sub 0($np),@ri[0]
+ mov 16($ap),@ri[2] # tp[2]
+ mov 24($ap),@ri[3] # tp[3]
+ sbb 8($np),@ri[1]
+ lea -1($num),$j # j=num/4-1
+ jmp .Lsub4x
+.align 16
+.Lsub4x:
+ mov @ri[0],0($rp,$i,8) # rp[i]=tp[i]-np[i]
+ mov @ri[1],8($rp,$i,8) # rp[i]=tp[i]-np[i]
+ sbb 16($np,$i,8),@ri[2]
+ mov 32($ap,$i,8),@ri[0] # tp[i+1]
+ mov 40($ap,$i,8),@ri[1]
+ sbb 24($np,$i,8),@ri[3]
+ mov @ri[2],16($rp,$i,8) # rp[i]=tp[i]-np[i]
+ mov @ri[3],24($rp,$i,8) # rp[i]=tp[i]-np[i]
+ sbb 32($np,$i,8),@ri[0]
+ mov 48($ap,$i,8),@ri[2]
+ mov 56($ap,$i,8),@ri[3]
+ sbb 40($np,$i,8),@ri[1]
+ lea 4($i),$i # i++
+ dec $j # doesnn't affect CF!
+ jnz .Lsub4x
+
+ mov @ri[0],0($rp,$i,8) # rp[i]=tp[i]-np[i]
+ mov 32($ap,$i,8),@ri[0] # load overflow bit
+ sbb 16($np,$i,8),@ri[2]
+ mov @ri[1],8($rp,$i,8) # rp[i]=tp[i]-np[i]
+ sbb 24($np,$i,8),@ri[3]
+ mov @ri[2],16($rp,$i,8) # rp[i]=tp[i]-np[i]
+
+ sbb \$0,@ri[0] # handle upmost overflow bit
+ mov @ri[3],24($rp,$i,8) # rp[i]=tp[i]-np[i]
+ xor $i,$i # i=0
+ and @ri[0],$ap
+ not @ri[0]
+ mov $rp,$np
+ and @ri[0],$np
+ lea -1($num),$j
+ or $np,$ap # ap=borrow?tp:rp
+
+ movdqu ($ap),%xmm1
+ movdqa %xmm0,(%rsp)
+ movdqu %xmm1,($rp)
+ jmp .Lcopy4x
+.align 16
+.Lcopy4x: # copy or in-place refresh
+ movdqu 16($ap,$i),%xmm2
+ movdqu 32($ap,$i),%xmm1
+ movdqa %xmm0,16(%rsp,$i)
+ movdqu %xmm2,16($rp,$i)
+ movdqa %xmm0,32(%rsp,$i)
+ movdqu %xmm1,32($rp,$i)
+ lea 32($i),$i
dec $j
- jge .Lcopy
+ jnz .Lcopy4x
+ shl \$2,$num
+ movdqu 16($ap,$i),%xmm2
+ movdqa %xmm0,16(%rsp,$i)
+ movdqu %xmm2,16($rp,$i)
+___
+}
+$code.=<<___;
mov 8(%rsp,$num,8),%rsi # restore %rsp
mov \$1,%rax
mov (%rsi),%r15
@@ -211,9 +681,823 @@ bn_mul_mont:
mov 32(%rsi),%rbp
mov 40(%rsi),%rbx
lea 48(%rsi),%rsp
-.Lepilogue:
+.Lmul4x_epilogue:
ret
-.size bn_mul_mont,.-bn_mul_mont
+.size bn_mul4x_mont,.-bn_mul4x_mont
+___
+}}}
+ {{{
+######################################################################
+# void bn_sqr4x_mont(
+my $rptr="%rdi"; # const BN_ULONG *rptr,
+my $aptr="%rsi"; # const BN_ULONG *aptr,
+my $bptr="%rdx"; # not used
+my $nptr="%rcx"; # const BN_ULONG *nptr,
+my $n0 ="%r8"; # const BN_ULONG *n0);
+my $num ="%r9"; # int num, has to be divisible by 4 and
+ # not less than 8
+
+my ($i,$j,$tptr)=("%rbp","%rcx",$rptr);
+my @A0=("%r10","%r11");
+my @A1=("%r12","%r13");
+my ($a0,$a1,$ai)=("%r14","%r15","%rbx");
+
+$code.=<<___;
+.type bn_sqr4x_mont,\@function,6
+.align 16
+bn_sqr4x_mont:
+.Lsqr4x_enter:
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ shl \$3,${num}d # convert $num to bytes
+ xor %r10,%r10
+ mov %rsp,%r11 # put aside %rsp
+ sub $num,%r10 # -$num
+ mov ($n0),$n0 # *n0
+ lea -72(%rsp,%r10,2),%rsp # alloca(frame+2*$num)
+ and \$-1024,%rsp # minimize TLB usage
+ ##############################################################
+ # Stack layout
+ #
+ # +0 saved $num, used in reduction section
+ # +8 &t[2*$num], used in reduction section
+ # +32 saved $rptr
+ # +40 saved $nptr
+ # +48 saved *n0
+ # +56 saved %rsp
+ # +64 t[2*$num]
+ #
+ mov $rptr,32(%rsp) # save $rptr
+ mov $nptr,40(%rsp)
+ mov $n0, 48(%rsp)
+ mov %r11, 56(%rsp) # save original %rsp
+.Lsqr4x_body:
+ ##############################################################
+ # Squaring part:
+ #
+ # a) multiply-n-add everything but a[i]*a[i];
+ # b) shift result of a) by 1 to the left and accumulate
+ # a[i]*a[i] products;
+ #
+ lea 32(%r10),$i # $i=-($num-32)
+ lea ($aptr,$num),$aptr # end of a[] buffer, ($aptr,$i)=&ap[2]
+
+ mov $num,$j # $j=$num
+
+ # comments apply to $num==8 case
+ mov -32($aptr,$i),$a0 # a[0]
+ lea 64(%rsp,$num,2),$tptr # end of tp[] buffer, &tp[2*$num]
+ mov -24($aptr,$i),%rax # a[1]
+ lea -32($tptr,$i),$tptr # end of tp[] window, &tp[2*$num-"$i"]
+ mov -16($aptr,$i),$ai # a[2]
+ mov %rax,$a1
+
+ mul $a0 # a[1]*a[0]
+ mov %rax,$A0[0] # a[1]*a[0]
+ mov $ai,%rax # a[2]
+ mov %rdx,$A0[1]
+ mov $A0[0],-24($tptr,$i) # t[1]
+
+ xor $A0[0],$A0[0]
+ mul $a0 # a[2]*a[0]
+ add %rax,$A0[1]
+ mov $ai,%rax
+ adc %rdx,$A0[0]
+ mov $A0[1],-16($tptr,$i) # t[2]
+
+ lea -16($i),$j # j=-16
+
+
+ mov 8($aptr,$j),$ai # a[3]
+ mul $a1 # a[2]*a[1]
+ mov %rax,$A1[0] # a[2]*a[1]+t[3]
+ mov $ai,%rax
+ mov %rdx,$A1[1]
+
+ xor $A0[1],$A0[1]
+ add $A1[0],$A0[0]
+ lea 16($j),$j
+ adc \$0,$A0[1]
+ mul $a0 # a[3]*a[0]
+ add %rax,$A0[0] # a[3]*a[0]+a[2]*a[1]+t[3]
+ mov $ai,%rax
+ adc %rdx,$A0[1]
+ mov $A0[0],-8($tptr,$j) # t[3]
+ jmp .Lsqr4x_1st
+
+.align 16
+.Lsqr4x_1st:
+ mov ($aptr,$j),$ai # a[4]
+ xor $A1[0],$A1[0]
+ mul $a1 # a[3]*a[1]
+ add %rax,$A1[1] # a[3]*a[1]+t[4]
+ mov $ai,%rax
+ adc %rdx,$A1[0]
+
+ xor $A0[0],$A0[0]
+ add $A1[1],$A0[1]
+ adc \$0,$A0[0]
+ mul $a0 # a[4]*a[0]
+ add %rax,$A0[1] # a[4]*a[0]+a[3]*a[1]+t[4]
+ mov $ai,%rax # a[3]
+ adc %rdx,$A0[0]
+ mov $A0[1],($tptr,$j) # t[4]
+
+
+ mov 8($aptr,$j),$ai # a[5]
+ xor $A1[1],$A1[1]
+ mul $a1 # a[4]*a[3]
+ add %rax,$A1[0] # a[4]*a[3]+t[5]
+ mov $ai,%rax
+ adc %rdx,$A1[1]
+
+ xor $A0[1],$A0[1]
+ add $A1[0],$A0[0]
+ adc \$0,$A0[1]
+ mul $a0 # a[5]*a[2]
+ add %rax,$A0[0] # a[5]*a[2]+a[4]*a[3]+t[5]
+ mov $ai,%rax
+ adc %rdx,$A0[1]
+ mov $A0[0],8($tptr,$j) # t[5]
+
+ mov 16($aptr,$j),$ai # a[6]
+ xor $A1[0],$A1[0]
+ mul $a1 # a[5]*a[3]
+ add %rax,$A1[1] # a[5]*a[3]+t[6]
+ mov $ai,%rax
+ adc %rdx,$A1[0]
+
+ xor $A0[0],$A0[0]
+ add $A1[1],$A0[1]
+ adc \$0,$A0[0]
+ mul $a0 # a[6]*a[2]
+ add %rax,$A0[1] # a[6]*a[2]+a[5]*a[3]+t[6]
+ mov $ai,%rax # a[3]
+ adc %rdx,$A0[0]
+ mov $A0[1],16($tptr,$j) # t[6]
+
+
+ mov 24($aptr,$j),$ai # a[7]
+ xor $A1[1],$A1[1]
+ mul $a1 # a[6]*a[5]
+ add %rax,$A1[0] # a[6]*a[5]+t[7]
+ mov $ai,%rax
+ adc %rdx,$A1[1]
+
+ xor $A0[1],$A0[1]
+ add $A1[0],$A0[0]
+ lea 32($j),$j
+ adc \$0,$A0[1]
+ mul $a0 # a[7]*a[4]
+ add %rax,$A0[0] # a[7]*a[4]+a[6]*a[5]+t[6]
+ mov $ai,%rax
+ adc %rdx,$A0[1]
+ mov $A0[0],-8($tptr,$j) # t[7]
+
+ cmp \$0,$j
+ jne .Lsqr4x_1st
+
+ xor $A1[0],$A1[0]
+ add $A0[1],$A1[1]
+ adc \$0,$A1[0]
+ mul $a1 # a[7]*a[5]
+ add %rax,$A1[1]
+ adc %rdx,$A1[0]
+
+ mov $A1[1],($tptr) # t[8]
+ lea 16($i),$i
+ mov $A1[0],8($tptr) # t[9]
+ jmp .Lsqr4x_outer
+
+.align 16
+.Lsqr4x_outer: # comments apply to $num==6 case
+ mov -32($aptr,$i),$a0 # a[0]
+ lea 64(%rsp,$num,2),$tptr # end of tp[] buffer, &tp[2*$num]
+ mov -24($aptr,$i),%rax # a[1]
+ lea -32($tptr,$i),$tptr # end of tp[] window, &tp[2*$num-"$i"]
+ mov -16($aptr,$i),$ai # a[2]
+ mov %rax,$a1
+
+ mov -24($tptr,$i),$A0[0] # t[1]
+ xor $A0[1],$A0[1]
+ mul $a0 # a[1]*a[0]
+ add %rax,$A0[0] # a[1]*a[0]+t[1]
+ mov $ai,%rax # a[2]
+ adc %rdx,$A0[1]
+ mov $A0[0],-24($tptr,$i) # t[1]
+
+ xor $A0[0],$A0[0]
+ add -16($tptr,$i),$A0[1] # a[2]*a[0]+t[2]
+ adc \$0,$A0[0]
+ mul $a0 # a[2]*a[0]
+ add %rax,$A0[1]
+ mov $ai,%rax
+ adc %rdx,$A0[0]
+ mov $A0[1],-16($tptr,$i) # t[2]
+
+ lea -16($i),$j # j=-16
+ xor $A1[0],$A1[0]
+
+
+ mov 8($aptr,$j),$ai # a[3]
+ xor $A1[1],$A1[1]
+ add 8($tptr,$j),$A1[0]
+ adc \$0,$A1[1]
+ mul $a1 # a[2]*a[1]
+ add %rax,$A1[0] # a[2]*a[1]+t[3]
+ mov $ai,%rax
+ adc %rdx,$A1[1]
+
+ xor $A0[1],$A0[1]
+ add $A1[0],$A0[0]
+ adc \$0,$A0[1]
+ mul $a0 # a[3]*a[0]
+ add %rax,$A0[0] # a[3]*a[0]+a[2]*a[1]+t[3]
+ mov $ai,%rax
+ adc %rdx,$A0[1]
+ mov $A0[0],8($tptr,$j) # t[3]
+
+ lea 16($j),$j
+ jmp .Lsqr4x_inner
+
+.align 16
+.Lsqr4x_inner:
+ mov ($aptr,$j),$ai # a[4]
+ xor $A1[0],$A1[0]
+ add ($tptr,$j),$A1[1]
+ adc \$0,$A1[0]
+ mul $a1 # a[3]*a[1]
+ add %rax,$A1[1] # a[3]*a[1]+t[4]
+ mov $ai,%rax
+ adc %rdx,$A1[0]
+
+ xor $A0[0],$A0[0]
+ add $A1[1],$A0[1]
+ adc \$0,$A0[0]
+ mul $a0 # a[4]*a[0]
+ add %rax,$A0[1] # a[4]*a[0]+a[3]*a[1]+t[4]
+ mov $ai,%rax # a[3]
+ adc %rdx,$A0[0]
+ mov $A0[1],($tptr,$j) # t[4]
+
+ mov 8($aptr,$j),$ai # a[5]
+ xor $A1[1],$A1[1]
+ add 8($tptr,$j),$A1[0]
+ adc \$0,$A1[1]
+ mul $a1 # a[4]*a[3]
+ add %rax,$A1[0] # a[4]*a[3]+t[5]
+ mov $ai,%rax
+ adc %rdx,$A1[1]
+
+ xor $A0[1],$A0[1]
+ add $A1[0],$A0[0]
+ lea 16($j),$j # j++
+ adc \$0,$A0[1]
+ mul $a0 # a[5]*a[2]
+ add %rax,$A0[0] # a[5]*a[2]+a[4]*a[3]+t[5]
+ mov $ai,%rax
+ adc %rdx,$A0[1]
+ mov $A0[0],-8($tptr,$j) # t[5], "preloaded t[1]" below
+
+ cmp \$0,$j
+ jne .Lsqr4x_inner
+
+ xor $A1[0],$A1[0]
+ add $A0[1],$A1[1]
+ adc \$0,$A1[0]
+ mul $a1 # a[5]*a[3]
+ add %rax,$A1[1]
+ adc %rdx,$A1[0]
+
+ mov $A1[1],($tptr) # t[6], "preloaded t[2]" below
+ mov $A1[0],8($tptr) # t[7], "preloaded t[3]" below
+
+ add \$16,$i
+ jnz .Lsqr4x_outer
+
+ # comments apply to $num==4 case
+ mov -32($aptr),$a0 # a[0]
+ lea 64(%rsp,$num,2),$tptr # end of tp[] buffer, &tp[2*$num]
+ mov -24($aptr),%rax # a[1]
+ lea -32($tptr,$i),$tptr # end of tp[] window, &tp[2*$num-"$i"]
+ mov -16($aptr),$ai # a[2]
+ mov %rax,$a1
+
+ xor $A0[1],$A0[1]
+ mul $a0 # a[1]*a[0]
+ add %rax,$A0[0] # a[1]*a[0]+t[1], preloaded t[1]
+ mov $ai,%rax # a[2]
+ adc %rdx,$A0[1]
+ mov $A0[0],-24($tptr) # t[1]
+
+ xor $A0[0],$A0[0]
+ add $A1[1],$A0[1] # a[2]*a[0]+t[2], preloaded t[2]
+ adc \$0,$A0[0]
+ mul $a0 # a[2]*a[0]
+ add %rax,$A0[1]
+ mov $ai,%rax
+ adc %rdx,$A0[0]
+ mov $A0[1],-16($tptr) # t[2]
+
+ mov -8($aptr),$ai # a[3]
+ mul $a1 # a[2]*a[1]
+ add %rax,$A1[0] # a[2]*a[1]+t[3], preloaded t[3]
+ mov $ai,%rax
+ adc \$0,%rdx
+
+ xor $A0[1],$A0[1]
+ add $A1[0],$A0[0]
+ mov %rdx,$A1[1]
+ adc \$0,$A0[1]
+ mul $a0 # a[3]*a[0]
+ add %rax,$A0[0] # a[3]*a[0]+a[2]*a[1]+t[3]
+ mov $ai,%rax
+ adc %rdx,$A0[1]
+ mov $A0[0],-8($tptr) # t[3]
+
+ xor $A1[0],$A1[0]
+ add $A0[1],$A1[1]
+ adc \$0,$A1[0]
+ mul $a1 # a[3]*a[1]
+ add %rax,$A1[1]
+ mov -16($aptr),%rax # a[2]
+ adc %rdx,$A1[0]
+
+ mov $A1[1],($tptr) # t[4]
+ mov $A1[0],8($tptr) # t[5]
+
+ mul $ai # a[2]*a[3]
+___
+{
+my ($shift,$carry)=($a0,$a1);
+my @S=(@A1,$ai,$n0);
+$code.=<<___;
+ add \$16,$i
+ xor $shift,$shift
+ sub $num,$i # $i=16-$num
+ xor $carry,$carry
+
+ add $A1[0],%rax # t[5]
+ adc \$0,%rdx
+ mov %rax,8($tptr) # t[5]
+ mov %rdx,16($tptr) # t[6]
+ mov $carry,24($tptr) # t[7]
+
+ mov -16($aptr,$i),%rax # a[0]
+ lea 64(%rsp,$num,2),$tptr
+ xor $A0[0],$A0[0] # t[0]
+ mov -24($tptr,$i,2),$A0[1] # t[1]
+
+ lea ($shift,$A0[0],2),$S[0] # t[2*i]<<1 | shift
+ shr \$63,$A0[0]
+ lea ($j,$A0[1],2),$S[1] # t[2*i+1]<<1 |
+ shr \$63,$A0[1]
+ or $A0[0],$S[1] # | t[2*i]>>63
+ mov -16($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch
+ mov $A0[1],$shift # shift=t[2*i+1]>>63
+ mul %rax # a[i]*a[i]
+ neg $carry # mov $carry,cf
+ mov -8($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch
+ adc %rax,$S[0]
+ mov -8($aptr,$i),%rax # a[i+1] # prefetch
+ mov $S[0],-32($tptr,$i,2)
+ adc %rdx,$S[1]
+
+ lea ($shift,$A0[0],2),$S[2] # t[2*i]<<1 | shift
+ mov $S[1],-24($tptr,$i,2)
+ sbb $carry,$carry # mov cf,$carry
+ shr \$63,$A0[0]
+ lea ($j,$A0[1],2),$S[3] # t[2*i+1]<<1 |
+ shr \$63,$A0[1]
+ or $A0[0],$S[3] # | t[2*i]>>63
+ mov 0($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch
+ mov $A0[1],$shift # shift=t[2*i+1]>>63
+ mul %rax # a[i]*a[i]
+ neg $carry # mov $carry,cf
+ mov 8($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch
+ adc %rax,$S[2]
+ mov 0($aptr,$i),%rax # a[i+1] # prefetch
+ mov $S[2],-16($tptr,$i,2)
+ adc %rdx,$S[3]
+ lea 16($i),$i
+ mov $S[3],-40($tptr,$i,2)
+ sbb $carry,$carry # mov cf,$carry
+ jmp .Lsqr4x_shift_n_add
+
+.align 16
+.Lsqr4x_shift_n_add:
+ lea ($shift,$A0[0],2),$S[0] # t[2*i]<<1 | shift
+ shr \$63,$A0[0]
+ lea ($j,$A0[1],2),$S[1] # t[2*i+1]<<1 |
+ shr \$63,$A0[1]
+ or $A0[0],$S[1] # | t[2*i]>>63
+ mov -16($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch
+ mov $A0[1],$shift # shift=t[2*i+1]>>63
+ mul %rax # a[i]*a[i]
+ neg $carry # mov $carry,cf
+ mov -8($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch
+ adc %rax,$S[0]
+ mov -8($aptr,$i),%rax # a[i+1] # prefetch
+ mov $S[0],-32($tptr,$i,2)
+ adc %rdx,$S[1]
+
+ lea ($shift,$A0[0],2),$S[2] # t[2*i]<<1 | shift
+ mov $S[1],-24($tptr,$i,2)
+ sbb $carry,$carry # mov cf,$carry
+ shr \$63,$A0[0]
+ lea ($j,$A0[1],2),$S[3] # t[2*i+1]<<1 |
+ shr \$63,$A0[1]
+ or $A0[0],$S[3] # | t[2*i]>>63
+ mov 0($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch
+ mov $A0[1],$shift # shift=t[2*i+1]>>63
+ mul %rax # a[i]*a[i]
+ neg $carry # mov $carry,cf
+ mov 8($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch
+ adc %rax,$S[2]
+ mov 0($aptr,$i),%rax # a[i+1] # prefetch
+ mov $S[2],-16($tptr,$i,2)
+ adc %rdx,$S[3]
+
+ lea ($shift,$A0[0],2),$S[0] # t[2*i]<<1 | shift
+ mov $S[3],-8($tptr,$i,2)
+ sbb $carry,$carry # mov cf,$carry
+ shr \$63,$A0[0]
+ lea ($j,$A0[1],2),$S[1] # t[2*i+1]<<1 |
+ shr \$63,$A0[1]
+ or $A0[0],$S[1] # | t[2*i]>>63
+ mov 16($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch
+ mov $A0[1],$shift # shift=t[2*i+1]>>63
+ mul %rax # a[i]*a[i]
+ neg $carry # mov $carry,cf
+ mov 24($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch
+ adc %rax,$S[0]
+ mov 8($aptr,$i),%rax # a[i+1] # prefetch
+ mov $S[0],0($tptr,$i,2)
+ adc %rdx,$S[1]
+
+ lea ($shift,$A0[0],2),$S[2] # t[2*i]<<1 | shift
+ mov $S[1],8($tptr,$i,2)
+ sbb $carry,$carry # mov cf,$carry
+ shr \$63,$A0[0]
+ lea ($j,$A0[1],2),$S[3] # t[2*i+1]<<1 |
+ shr \$63,$A0[1]
+ or $A0[0],$S[3] # | t[2*i]>>63
+ mov 32($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch
+ mov $A0[1],$shift # shift=t[2*i+1]>>63
+ mul %rax # a[i]*a[i]
+ neg $carry # mov $carry,cf
+ mov 40($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch
+ adc %rax,$S[2]
+ mov 16($aptr,$i),%rax # a[i+1] # prefetch
+ mov $S[2],16($tptr,$i,2)
+ adc %rdx,$S[3]
+ mov $S[3],24($tptr,$i,2)
+ sbb $carry,$carry # mov cf,$carry
+ add \$32,$i
+ jnz .Lsqr4x_shift_n_add
+
+ lea ($shift,$A0[0],2),$S[0] # t[2*i]<<1 | shift
+ shr \$63,$A0[0]
+ lea ($j,$A0[1],2),$S[1] # t[2*i+1]<<1 |
+ shr \$63,$A0[1]
+ or $A0[0],$S[1] # | t[2*i]>>63
+ mov -16($tptr),$A0[0] # t[2*i+2] # prefetch
+ mov $A0[1],$shift # shift=t[2*i+1]>>63
+ mul %rax # a[i]*a[i]
+ neg $carry # mov $carry,cf
+ mov -8($tptr),$A0[1] # t[2*i+2+1] # prefetch
+ adc %rax,$S[0]
+ mov -8($aptr),%rax # a[i+1] # prefetch
+ mov $S[0],-32($tptr)
+ adc %rdx,$S[1]
+
+ lea ($shift,$A0[0],2),$S[2] # t[2*i]<<1|shift
+ mov $S[1],-24($tptr)
+ sbb $carry,$carry # mov cf,$carry
+ shr \$63,$A0[0]
+ lea ($j,$A0[1],2),$S[3] # t[2*i+1]<<1 |
+ shr \$63,$A0[1]
+ or $A0[0],$S[3] # | t[2*i]>>63
+ mul %rax # a[i]*a[i]
+ neg $carry # mov $carry,cf
+ adc %rax,$S[2]
+ adc %rdx,$S[3]
+ mov $S[2],-16($tptr)
+ mov $S[3],-8($tptr)
+___
+}
+##############################################################
+# Montgomery reduction part, "word-by-word" algorithm.
+#
+{
+my ($topbit,$nptr)=("%rbp",$aptr);
+my ($m0,$m1)=($a0,$a1);
+my @Ni=("%rbx","%r9");
+$code.=<<___;
+ mov 40(%rsp),$nptr # restore $nptr
+ mov 48(%rsp),$n0 # restore *n0
+ xor $j,$j
+ mov $num,0(%rsp) # save $num
+ sub $num,$j # $j=-$num
+ mov 64(%rsp),$A0[0] # t[0] # modsched #
+ mov $n0,$m0 # # modsched #
+ lea 64(%rsp,$num,2),%rax # end of t[] buffer
+ lea 64(%rsp,$num),$tptr # end of t[] window
+ mov %rax,8(%rsp) # save end of t[] buffer
+ lea ($nptr,$num),$nptr # end of n[] buffer
+ xor $topbit,$topbit # $topbit=0
+
+ mov 0($nptr,$j),%rax # n[0] # modsched #
+ mov 8($nptr,$j),$Ni[1] # n[1] # modsched #
+ imulq $A0[0],$m0 # m0=t[0]*n0 # modsched #
+ mov %rax,$Ni[0] # # modsched #
+ jmp .Lsqr4x_mont_outer
+
+.align 16
+.Lsqr4x_mont_outer:
+ xor $A0[1],$A0[1]
+ mul $m0 # n[0]*m0
+ add %rax,$A0[0] # n[0]*m0+t[0]
+ mov $Ni[1],%rax
+ adc %rdx,$A0[1]
+ mov $n0,$m1
+
+ xor $A0[0],$A0[0]
+ add 8($tptr,$j),$A0[1]
+ adc \$0,$A0[0]
+ mul $m0 # n[1]*m0
+ add %rax,$A0[1] # n[1]*m0+t[1]
+ mov $Ni[0],%rax
+ adc %rdx,$A0[0]
+
+ imulq $A0[1],$m1
+
+ mov 16($nptr,$j),$Ni[0] # n[2]
+ xor $A1[1],$A1[1]
+ add $A0[1],$A1[0]
+ adc \$0,$A1[1]
+ mul $m1 # n[0]*m1
+ add %rax,$A1[0] # n[0]*m1+"t[1]"
+ mov $Ni[0],%rax
+ adc %rdx,$A1[1]
+ mov $A1[0],8($tptr,$j) # "t[1]"
+
+ xor $A0[1],$A0[1]
+ add 16($tptr,$j),$A0[0]
+ adc \$0,$A0[1]
+ mul $m0 # n[2]*m0
+ add %rax,$A0[0] # n[2]*m0+t[2]
+ mov $Ni[1],%rax
+ adc %rdx,$A0[1]
+
+ mov 24($nptr,$j),$Ni[1] # n[3]
+ xor $A1[0],$A1[0]
+ add $A0[0],$A1[1]
+ adc \$0,$A1[0]
+ mul $m1 # n[1]*m1
+ add %rax,$A1[1] # n[1]*m1+"t[2]"
+ mov $Ni[1],%rax
+ adc %rdx,$A1[0]
+ mov $A1[1],16($tptr,$j) # "t[2]"
+
+ xor $A0[0],$A0[0]
+ add 24($tptr,$j),$A0[1]
+ lea 32($j),$j
+ adc \$0,$A0[0]
+ mul $m0 # n[3]*m0
+ add %rax,$A0[1] # n[3]*m0+t[3]
+ mov $Ni[0],%rax
+ adc %rdx,$A0[0]
+ jmp .Lsqr4x_mont_inner
+
+.align 16
+.Lsqr4x_mont_inner:
+ mov ($nptr,$j),$Ni[0] # n[4]
+ xor $A1[1],$A1[1]
+ add $A0[1],$A1[0]
+ adc \$0,$A1[1]
+ mul $m1 # n[2]*m1
+ add %rax,$A1[0] # n[2]*m1+"t[3]"
+ mov $Ni[0],%rax
+ adc %rdx,$A1[1]
+ mov $A1[0],-8($tptr,$j) # "t[3]"
+
+ xor $A0[1],$A0[1]
+ add ($tptr,$j),$A0[0]
+ adc \$0,$A0[1]
+ mul $m0 # n[4]*m0
+ add %rax,$A0[0] # n[4]*m0+t[4]
+ mov $Ni[1],%rax
+ adc %rdx,$A0[1]
+
+ mov 8($nptr,$j),$Ni[1] # n[5]
+ xor $A1[0],$A1[0]
+ add $A0[0],$A1[1]
+ adc \$0,$A1[0]
+ mul $m1 # n[3]*m1
+ add %rax,$A1[1] # n[3]*m1+"t[4]"
+ mov $Ni[1],%rax
+ adc %rdx,$A1[0]
+ mov $A1[1],($tptr,$j) # "t[4]"
+
+ xor $A0[0],$A0[0]
+ add 8($tptr,$j),$A0[1]
+ adc \$0,$A0[0]
+ mul $m0 # n[5]*m0
+ add %rax,$A0[1] # n[5]*m0+t[5]
+ mov $Ni[0],%rax
+ adc %rdx,$A0[0]
+
+
+ mov 16($nptr,$j),$Ni[0] # n[6]
+ xor $A1[1],$A1[1]
+ add $A0[1],$A1[0]
+ adc \$0,$A1[1]
+ mul $m1 # n[4]*m1
+ add %rax,$A1[0] # n[4]*m1+"t[5]"
+ mov $Ni[0],%rax
+ adc %rdx,$A1[1]
+ mov $A1[0],8($tptr,$j) # "t[5]"
+
+ xor $A0[1],$A0[1]
+ add 16($tptr,$j),$A0[0]
+ adc \$0,$A0[1]
+ mul $m0 # n[6]*m0
+ add %rax,$A0[0] # n[6]*m0+t[6]
+ mov $Ni[1],%rax
+ adc %rdx,$A0[1]
+
+ mov 24($nptr,$j),$Ni[1] # n[7]
+ xor $A1[0],$A1[0]
+ add $A0[0],$A1[1]
+ adc \$0,$A1[0]
+ mul $m1 # n[5]*m1
+ add %rax,$A1[1] # n[5]*m1+"t[6]"
+ mov $Ni[1],%rax
+ adc %rdx,$A1[0]
+ mov $A1[1],16($tptr,$j) # "t[6]"
+
+ xor $A0[0],$A0[0]
+ add 24($tptr,$j),$A0[1]
+ lea 32($j),$j
+ adc \$0,$A0[0]
+ mul $m0 # n[7]*m0
+ add %rax,$A0[1] # n[7]*m0+t[7]
+ mov $Ni[0],%rax
+ adc %rdx,$A0[0]
+ cmp \$0,$j
+ jne .Lsqr4x_mont_inner
+
+ sub 0(%rsp),$j # $j=-$num # modsched #
+ mov $n0,$m0 # # modsched #
+
+ xor $A1[1],$A1[1]
+ add $A0[1],$A1[0]
+ adc \$0,$A1[1]
+ mul $m1 # n[6]*m1
+ add %rax,$A1[0] # n[6]*m1+"t[7]"
+ mov $Ni[1],%rax
+ adc %rdx,$A1[1]
+ mov $A1[0],-8($tptr) # "t[7]"
+
+ xor $A0[1],$A0[1]
+ add ($tptr),$A0[0] # +t[8]
+ adc \$0,$A0[1]
+ mov 0($nptr,$j),$Ni[0] # n[0] # modsched #
+ add $topbit,$A0[0]
+ adc \$0,$A0[1]
+
+ imulq 16($tptr,$j),$m0 # m0=t[0]*n0 # modsched #
+ xor $A1[0],$A1[0]
+ mov 8($nptr,$j),$Ni[1] # n[1] # modsched #
+ add $A0[0],$A1[1]
+ mov 16($tptr,$j),$A0[0] # t[0] # modsched #
+ adc \$0,$A1[0]
+ mul $m1 # n[7]*m1
+ add %rax,$A1[1] # n[7]*m1+"t[8]"
+ mov $Ni[0],%rax # # modsched #
+ adc %rdx,$A1[0]
+ mov $A1[1],($tptr) # "t[8]"
+
+ xor $topbit,$topbit
+ add 8($tptr),$A1[0] # +t[9]
+ adc $topbit,$topbit
+ add $A0[1],$A1[0]
+ lea 16($tptr),$tptr # "t[$num]>>128"
+ adc \$0,$topbit
+ mov $A1[0],-8($tptr) # "t[9]"
+ cmp 8(%rsp),$tptr # are we done?
+ jb .Lsqr4x_mont_outer
+
+ mov 0(%rsp),$num # restore $num
+ mov $topbit,($tptr) # save $topbit
+___
+}
+##############################################################
+# Post-condition, 4x unrolled copy from bn_mul_mont
+#
+{
+my ($tptr,$nptr)=("%rbx",$aptr);
+my @ri=("%rax","%rdx","%r10","%r11");
+$code.=<<___;
+ mov 64(%rsp,$num),@ri[0] # tp[0]
+ lea 64(%rsp,$num),$tptr # upper half of t[2*$num] holds result
+ mov 40(%rsp),$nptr # restore $nptr
+ shr \$5,$num # num/4
+ mov 8($tptr),@ri[1] # t[1]
+ xor $i,$i # i=0 and clear CF!
+
+ mov 32(%rsp),$rptr # restore $rptr
+ sub 0($nptr),@ri[0]
+ mov 16($tptr),@ri[2] # t[2]
+ mov 24($tptr),@ri[3] # t[3]
+ sbb 8($nptr),@ri[1]
+ lea -1($num),$j # j=num/4-1
+ jmp .Lsqr4x_sub
+.align 16
+.Lsqr4x_sub:
+ mov @ri[0],0($rptr,$i,8) # rp[i]=tp[i]-np[i]
+ mov @ri[1],8($rptr,$i,8) # rp[i]=tp[i]-np[i]
+ sbb 16($nptr,$i,8),@ri[2]
+ mov 32($tptr,$i,8),@ri[0] # tp[i+1]
+ mov 40($tptr,$i,8),@ri[1]
+ sbb 24($nptr,$i,8),@ri[3]
+ mov @ri[2],16($rptr,$i,8) # rp[i]=tp[i]-np[i]
+ mov @ri[3],24($rptr,$i,8) # rp[i]=tp[i]-np[i]
+ sbb 32($nptr,$i,8),@ri[0]
+ mov 48($tptr,$i,8),@ri[2]
+ mov 56($tptr,$i,8),@ri[3]
+ sbb 40($nptr,$i,8),@ri[1]
+ lea 4($i),$i # i++
+ dec $j # doesn't affect CF!
+ jnz .Lsqr4x_sub
+
+ mov @ri[0],0($rptr,$i,8) # rp[i]=tp[i]-np[i]
+ mov 32($tptr,$i,8),@ri[0] # load overflow bit
+ sbb 16($nptr,$i,8),@ri[2]
+ mov @ri[1],8($rptr,$i,8) # rp[i]=tp[i]-np[i]
+ sbb 24($nptr,$i,8),@ri[3]
+ mov @ri[2],16($rptr,$i,8) # rp[i]=tp[i]-np[i]
+
+ sbb \$0,@ri[0] # handle upmost overflow bit
+ mov @ri[3],24($rptr,$i,8) # rp[i]=tp[i]-np[i]
+ xor $i,$i # i=0
+ and @ri[0],$tptr
+ not @ri[0]
+ mov $rptr,$nptr
+ and @ri[0],$nptr
+ lea -1($num),$j
+ or $nptr,$tptr # tp=borrow?tp:rp
+
+ pxor %xmm0,%xmm0
+ lea 64(%rsp,$num,8),$nptr
+ movdqu ($tptr),%xmm1
+ lea ($nptr,$num,8),$nptr
+ movdqa %xmm0,64(%rsp) # zap lower half of temporary vector
+ movdqa %xmm0,($nptr) # zap upper half of temporary vector
+ movdqu %xmm1,($rptr)
+ jmp .Lsqr4x_copy
+.align 16
+.Lsqr4x_copy: # copy or in-place refresh
+ movdqu 16($tptr,$i),%xmm2
+ movdqu 32($tptr,$i),%xmm1
+ movdqa %xmm0,80(%rsp,$i) # zap lower half of temporary vector
+ movdqa %xmm0,96(%rsp,$i) # zap lower half of temporary vector
+ movdqa %xmm0,16($nptr,$i) # zap upper half of temporary vector
+ movdqa %xmm0,32($nptr,$i) # zap upper half of temporary vector
+ movdqu %xmm2,16($rptr,$i)
+ movdqu %xmm1,32($rptr,$i)
+ lea 32($i),$i
+ dec $j
+ jnz .Lsqr4x_copy
+
+ movdqu 16($tptr,$i),%xmm2
+ movdqa %xmm0,80(%rsp,$i) # zap lower half of temporary vector
+ movdqa %xmm0,16($nptr,$i) # zap upper half of temporary vector
+ movdqu %xmm2,16($rptr,$i)
+___
+}
+$code.=<<___;
+ mov 56(%rsp),%rsi # restore %rsp
+ mov \$1,%rax
+ mov 0(%rsi),%r15
+ mov 8(%rsi),%r14
+ mov 16(%rsi),%r13
+ mov 24(%rsi),%r12
+ mov 32(%rsi),%rbp
+ mov 40(%rsi),%rbx
+ lea 48(%rsi),%rsp
+.Lsqr4x_epilogue:
+ ret
+.size bn_sqr4x_mont,.-bn_sqr4x_mont
+___
+}}}
+$code.=<<___;
.asciz "Montgomery Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
.align 16
___
@@ -228,9 +1512,9 @@ $disp="%r9";
$code.=<<___;
.extern __imp_RtlVirtualUnwind
-.type se_handler,\@abi-omnipotent
+.type mul_handler,\@abi-omnipotent
.align 16
-se_handler:
+mul_handler:
push %rsi
push %rdi
push %rbx
@@ -245,15 +1529,20 @@ se_handler:
mov 120($context),%rax # pull context->Rax
mov 248($context),%rbx # pull context->Rip
- lea .Lprologue(%rip),%r10
- cmp %r10,%rbx # context->Rip<.Lprologue
- jb .Lin_prologue
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # end of prologue label
+ cmp %r10,%rbx # context->Rip<end of prologue label
+ jb .Lcommon_seh_tail
mov 152($context),%rax # pull context->Rsp
- lea .Lepilogue(%rip),%r10
- cmp %r10,%rbx # context->Rip>=.Lepilogue
- jae .Lin_prologue
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lcommon_seh_tail
mov 192($context),%r10 # pull $num
mov 8(%rax,%r10,8),%rax # pull saved stack pointer
@@ -272,7 +1561,53 @@ se_handler:
mov %r14,232($context) # restore context->R14
mov %r15,240($context) # restore context->R15
-.Lin_prologue:
+ jmp .Lcommon_seh_tail
+.size mul_handler,.-mul_handler
+
+.type sqr_handler,\@abi-omnipotent
+.align 16
+sqr_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ lea .Lsqr4x_body(%rip),%r10
+ cmp %r10,%rbx # context->Rip<.Lsqr_body
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ lea .Lsqr4x_epilogue(%rip),%r10
+ cmp %r10,%rbx # context->Rip>=.Lsqr_epilogue
+ jae .Lcommon_seh_tail
+
+ mov 56(%rax),%rax # pull saved stack pointer
+ lea 48(%rax),%rax
+
+ mov -8(%rax),%rbx
+ mov -16(%rax),%rbp
+ mov -24(%rax),%r12
+ mov -32(%rax),%r13
+ mov -40(%rax),%r14
+ mov -48(%rax),%r15
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R13
+ mov %r14,232($context) # restore context->R14
+ mov %r15,240($context) # restore context->R15
+
+.Lcommon_seh_tail:
mov 8(%rax),%rdi
mov 16(%rax),%rsi
mov %rax,152($context) # restore context->Rsp
@@ -310,7 +1645,7 @@ se_handler:
pop %rdi
pop %rsi
ret
-.size se_handler,.-se_handler
+.size sqr_handler,.-sqr_handler
.section .pdata
.align 4
@@ -318,11 +1653,27 @@ se_handler:
.rva .LSEH_end_bn_mul_mont
.rva .LSEH_info_bn_mul_mont
+ .rva .LSEH_begin_bn_mul4x_mont
+ .rva .LSEH_end_bn_mul4x_mont
+ .rva .LSEH_info_bn_mul4x_mont
+
+ .rva .LSEH_begin_bn_sqr4x_mont
+ .rva .LSEH_end_bn_sqr4x_mont
+ .rva .LSEH_info_bn_sqr4x_mont
+
.section .xdata
.align 8
.LSEH_info_bn_mul_mont:
.byte 9,0,0,0
- .rva se_handler
+ .rva mul_handler
+ .rva .Lmul_body,.Lmul_epilogue # HandlerData[]
+.LSEH_info_bn_mul4x_mont:
+ .byte 9,0,0,0
+ .rva mul_handler
+ .rva .Lmul4x_body,.Lmul4x_epilogue # HandlerData[]
+.LSEH_info_bn_sqr4x_mont:
+ .byte 9,0,0,0
+ .rva sqr_handler
___
}
diff --git a/deps/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl b/deps/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl
new file mode 100755
index 000000000..8f8dc5a59
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl
@@ -0,0 +1,1071 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# August 2011.
+#
+# Companion to x86_64-mont.pl that optimizes cache-timing attack
+# countermeasures. The subroutines are produced by replacing bp[i]
+# references in their x86_64-mont.pl counterparts with cache-neutral
+# references to powers table computed in BN_mod_exp_mont_consttime.
+# In addition subroutine that scatters elements of the powers table
+# is implemented, so that scatter-/gathering can be tuned without
+# bn_exp.c modifications.
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+# int bn_mul_mont_gather5(
+$rp="%rdi"; # BN_ULONG *rp,
+$ap="%rsi"; # const BN_ULONG *ap,
+$bp="%rdx"; # const BN_ULONG *bp,
+$np="%rcx"; # const BN_ULONG *np,
+$n0="%r8"; # const BN_ULONG *n0,
+$num="%r9"; # int num,
+ # int idx); # 0 to 2^5-1, "index" in $bp holding
+ # pre-computed powers of a', interlaced
+ # in such manner that b[0] is $bp[idx],
+ # b[1] is [2^5+idx], etc.
+$lo0="%r10";
+$hi0="%r11";
+$hi1="%r13";
+$i="%r14";
+$j="%r15";
+$m0="%rbx";
+$m1="%rbp";
+
+$code=<<___;
+.text
+
+.globl bn_mul_mont_gather5
+.type bn_mul_mont_gather5,\@function,6
+.align 64
+bn_mul_mont_gather5:
+ test \$3,${num}d
+ jnz .Lmul_enter
+ cmp \$8,${num}d
+ jb .Lmul_enter
+ jmp .Lmul4x_enter
+
+.align 16
+.Lmul_enter:
+ mov ${num}d,${num}d
+ mov `($win64?56:8)`(%rsp),%r10d # load 7th argument
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+___
+$code.=<<___ if ($win64);
+ lea -0x28(%rsp),%rsp
+ movaps %xmm6,(%rsp)
+ movaps %xmm7,0x10(%rsp)
+.Lmul_alloca:
+___
+$code.=<<___;
+ mov %rsp,%rax
+ lea 2($num),%r11
+ neg %r11
+ lea (%rsp,%r11,8),%rsp # tp=alloca(8*(num+2))
+ and \$-1024,%rsp # minimize TLB usage
+
+ mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp
+.Lmul_body:
+ mov $bp,%r12 # reassign $bp
+___
+ $bp="%r12";
+ $STRIDE=2**5*8; # 5 is "window size"
+ $N=$STRIDE/4; # should match cache line size
+$code.=<<___;
+ mov %r10,%r11
+ shr \$`log($N/8)/log(2)`,%r10
+ and \$`$N/8-1`,%r11
+ not %r10
+ lea .Lmagic_masks(%rip),%rax
+ and \$`2**5/($N/8)-1`,%r10 # 5 is "window size"
+ lea 96($bp,%r11,8),$bp # pointer within 1st cache line
+ movq 0(%rax,%r10,8),%xmm4 # set of masks denoting which
+ movq 8(%rax,%r10,8),%xmm5 # cache line contains element
+ movq 16(%rax,%r10,8),%xmm6 # denoted by 7th argument
+ movq 24(%rax,%r10,8),%xmm7
+
+ movq `0*$STRIDE/4-96`($bp),%xmm0
+ movq `1*$STRIDE/4-96`($bp),%xmm1
+ pand %xmm4,%xmm0
+ movq `2*$STRIDE/4-96`($bp),%xmm2
+ pand %xmm5,%xmm1
+ movq `3*$STRIDE/4-96`($bp),%xmm3
+ pand %xmm6,%xmm2
+ por %xmm1,%xmm0
+ pand %xmm7,%xmm3
+ por %xmm2,%xmm0
+ lea $STRIDE($bp),$bp
+ por %xmm3,%xmm0
+
+ movq %xmm0,$m0 # m0=bp[0]
+
+ mov ($n0),$n0 # pull n0[0] value
+ mov ($ap),%rax
+
+ xor $i,$i # i=0
+ xor $j,$j # j=0
+
+ movq `0*$STRIDE/4-96`($bp),%xmm0
+ movq `1*$STRIDE/4-96`($bp),%xmm1
+ pand %xmm4,%xmm0
+ movq `2*$STRIDE/4-96`($bp),%xmm2
+ pand %xmm5,%xmm1
+
+ mov $n0,$m1
+ mulq $m0 # ap[0]*bp[0]
+ mov %rax,$lo0
+ mov ($np),%rax
+
+ movq `3*$STRIDE/4-96`($bp),%xmm3
+ pand %xmm6,%xmm2
+ por %xmm1,%xmm0
+ pand %xmm7,%xmm3
+
+ imulq $lo0,$m1 # "tp[0]"*n0
+ mov %rdx,$hi0
+
+ por %xmm2,%xmm0
+ lea $STRIDE($bp),$bp
+ por %xmm3,%xmm0
+
+ mulq $m1 # np[0]*m1
+ add %rax,$lo0 # discarded
+ mov 8($ap),%rax
+ adc \$0,%rdx
+ mov %rdx,$hi1
+
+ lea 1($j),$j # j++
+ jmp .L1st_enter
+
+.align 16
+.L1st:
+ add %rax,$hi1
+ mov ($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $hi0,$hi1 # np[j]*m1+ap[j]*bp[0]
+ mov $lo0,$hi0
+ adc \$0,%rdx
+ mov $hi1,-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$hi1
+
+.L1st_enter:
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$hi0
+ mov ($np,$j,8),%rax
+ adc \$0,%rdx
+ lea 1($j),$j # j++
+ mov %rdx,$lo0
+
+ mulq $m1 # np[j]*m1
+ cmp $num,$j
+ jne .L1st
+
+ movq %xmm0,$m0 # bp[1]
+
+ add %rax,$hi1
+ mov ($ap),%rax # ap[0]
+ adc \$0,%rdx
+ add $hi0,$hi1 # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $hi1,-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$hi1
+ mov $lo0,$hi0
+
+ xor %rdx,%rdx
+ add $hi0,$hi1
+ adc \$0,%rdx
+ mov $hi1,-8(%rsp,$num,8)
+ mov %rdx,(%rsp,$num,8) # store upmost overflow bit
+
+ lea 1($i),$i # i++
+ jmp .Louter
+.align 16
+.Louter:
+ xor $j,$j # j=0
+ mov $n0,$m1
+ mov (%rsp),$lo0
+
+ movq `0*$STRIDE/4-96`($bp),%xmm0
+ movq `1*$STRIDE/4-96`($bp),%xmm1
+ pand %xmm4,%xmm0
+ movq `2*$STRIDE/4-96`($bp),%xmm2
+ pand %xmm5,%xmm1
+
+ mulq $m0 # ap[0]*bp[i]
+ add %rax,$lo0 # ap[0]*bp[i]+tp[0]
+ mov ($np),%rax
+ adc \$0,%rdx
+
+ movq `3*$STRIDE/4-96`($bp),%xmm3
+ pand %xmm6,%xmm2
+ por %xmm1,%xmm0
+ pand %xmm7,%xmm3
+
+ imulq $lo0,$m1 # tp[0]*n0
+ mov %rdx,$hi0
+
+ por %xmm2,%xmm0
+ lea $STRIDE($bp),$bp
+ por %xmm3,%xmm0
+
+ mulq $m1 # np[0]*m1
+ add %rax,$lo0 # discarded
+ mov 8($ap),%rax
+ adc \$0,%rdx
+ mov 8(%rsp),$lo0 # tp[1]
+ mov %rdx,$hi1
+
+ lea 1($j),$j # j++
+ jmp .Linner_enter
+
+.align 16
+.Linner:
+ add %rax,$hi1
+ mov ($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $lo0,$hi1 # np[j]*m1+ap[j]*bp[i]+tp[j]
+ mov (%rsp,$j,8),$lo0
+ adc \$0,%rdx
+ mov $hi1,-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$hi1
+
+.Linner_enter:
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$hi0
+ mov ($np,$j,8),%rax
+ adc \$0,%rdx
+ add $hi0,$lo0 # ap[j]*bp[i]+tp[j]
+ mov %rdx,$hi0
+ adc \$0,$hi0
+ lea 1($j),$j # j++
+
+ mulq $m1 # np[j]*m1
+ cmp $num,$j
+ jne .Linner
+
+ movq %xmm0,$m0 # bp[i+1]
+
+ add %rax,$hi1
+ mov ($ap),%rax # ap[0]
+ adc \$0,%rdx
+ add $lo0,$hi1 # np[j]*m1+ap[j]*bp[i]+tp[j]
+ mov (%rsp,$j,8),$lo0
+ adc \$0,%rdx
+ mov $hi1,-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$hi1
+
+ xor %rdx,%rdx
+ add $hi0,$hi1
+ adc \$0,%rdx
+ add $lo0,$hi1 # pull upmost overflow bit
+ adc \$0,%rdx
+ mov $hi1,-8(%rsp,$num,8)
+ mov %rdx,(%rsp,$num,8) # store upmost overflow bit
+
+ lea 1($i),$i # i++
+ cmp $num,$i
+ jl .Louter
+
+ xor $i,$i # i=0 and clear CF!
+ mov (%rsp),%rax # tp[0]
+ lea (%rsp),$ap # borrow ap for tp
+ mov $num,$j # j=num
+ jmp .Lsub
+.align 16
+.Lsub: sbb ($np,$i,8),%rax
+ mov %rax,($rp,$i,8) # rp[i]=tp[i]-np[i]
+ mov 8($ap,$i,8),%rax # tp[i+1]
+ lea 1($i),$i # i++
+ dec $j # doesnn't affect CF!
+ jnz .Lsub
+
+ sbb \$0,%rax # handle upmost overflow bit
+ xor $i,$i
+ and %rax,$ap
+ not %rax
+ mov $rp,$np
+ and %rax,$np
+ mov $num,$j # j=num
+ or $np,$ap # ap=borrow?tp:rp
+.align 16
+.Lcopy: # copy or in-place refresh
+ mov ($ap,$i,8),%rax
+ mov $i,(%rsp,$i,8) # zap temporary vector
+ mov %rax,($rp,$i,8) # rp[i]=tp[i]
+ lea 1($i),$i
+ sub \$1,$j
+ jnz .Lcopy
+
+ mov 8(%rsp,$num,8),%rsi # restore %rsp
+ mov \$1,%rax
+___
+$code.=<<___ if ($win64);
+ movaps (%rsi),%xmm6
+ movaps 0x10(%rsi),%xmm7
+ lea 0x28(%rsi),%rsi
+___
+$code.=<<___;
+ mov (%rsi),%r15
+ mov 8(%rsi),%r14
+ mov 16(%rsi),%r13
+ mov 24(%rsi),%r12
+ mov 32(%rsi),%rbp
+ mov 40(%rsi),%rbx
+ lea 48(%rsi),%rsp
+.Lmul_epilogue:
+ ret
+.size bn_mul_mont_gather5,.-bn_mul_mont_gather5
+___
+{{{
+my @A=("%r10","%r11");
+my @N=("%r13","%rdi");
+$code.=<<___;
+.type bn_mul4x_mont_gather5,\@function,6
+.align 16
+bn_mul4x_mont_gather5:
+.Lmul4x_enter:
+ mov ${num}d,${num}d
+ mov `($win64?56:8)`(%rsp),%r10d # load 7th argument
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+___
+$code.=<<___ if ($win64);
+ lea -0x28(%rsp),%rsp
+ movaps %xmm6,(%rsp)
+ movaps %xmm7,0x10(%rsp)
+.Lmul4x_alloca:
+___
+$code.=<<___;
+ mov %rsp,%rax
+ lea 4($num),%r11
+ neg %r11
+ lea (%rsp,%r11,8),%rsp # tp=alloca(8*(num+4))
+ and \$-1024,%rsp # minimize TLB usage
+
+ mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp
+.Lmul4x_body:
+ mov $rp,16(%rsp,$num,8) # tp[num+2]=$rp
+ mov %rdx,%r12 # reassign $bp
+___
+ $bp="%r12";
+ $STRIDE=2**5*8; # 5 is "window size"
+ $N=$STRIDE/4; # should match cache line size
+$code.=<<___;
+ mov %r10,%r11
+ shr \$`log($N/8)/log(2)`,%r10
+ and \$`$N/8-1`,%r11
+ not %r10
+ lea .Lmagic_masks(%rip),%rax
+ and \$`2**5/($N/8)-1`,%r10 # 5 is "window size"
+ lea 96($bp,%r11,8),$bp # pointer within 1st cache line
+ movq 0(%rax,%r10,8),%xmm4 # set of masks denoting which
+ movq 8(%rax,%r10,8),%xmm5 # cache line contains element
+ movq 16(%rax,%r10,8),%xmm6 # denoted by 7th argument
+ movq 24(%rax,%r10,8),%xmm7
+
+ movq `0*$STRIDE/4-96`($bp),%xmm0
+ movq `1*$STRIDE/4-96`($bp),%xmm1
+ pand %xmm4,%xmm0
+ movq `2*$STRIDE/4-96`($bp),%xmm2
+ pand %xmm5,%xmm1
+ movq `3*$STRIDE/4-96`($bp),%xmm3
+ pand %xmm6,%xmm2
+ por %xmm1,%xmm0
+ pand %xmm7,%xmm3
+ por %xmm2,%xmm0
+ lea $STRIDE($bp),$bp
+ por %xmm3,%xmm0
+
+ movq %xmm0,$m0 # m0=bp[0]
+ mov ($n0),$n0 # pull n0[0] value
+ mov ($ap),%rax
+
+ xor $i,$i # i=0
+ xor $j,$j # j=0
+
+ movq `0*$STRIDE/4-96`($bp),%xmm0
+ movq `1*$STRIDE/4-96`($bp),%xmm1
+ pand %xmm4,%xmm0
+ movq `2*$STRIDE/4-96`($bp),%xmm2
+ pand %xmm5,%xmm1
+
+ mov $n0,$m1
+ mulq $m0 # ap[0]*bp[0]
+ mov %rax,$A[0]
+ mov ($np),%rax
+
+ movq `3*$STRIDE/4-96`($bp),%xmm3
+ pand %xmm6,%xmm2
+ por %xmm1,%xmm0
+ pand %xmm7,%xmm3
+
+ imulq $A[0],$m1 # "tp[0]"*n0
+ mov %rdx,$A[1]
+
+ por %xmm2,%xmm0
+ lea $STRIDE($bp),$bp
+ por %xmm3,%xmm0
+
+ mulq $m1 # np[0]*m1
+ add %rax,$A[0] # discarded
+ mov 8($ap),%rax
+ adc \$0,%rdx
+ mov %rdx,$N[1]
+
+ mulq $m0
+ add %rax,$A[1]
+ mov 8($np),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[0]
+
+ mulq $m1
+ add %rax,$N[1]
+ mov 16($ap),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1]
+ lea 4($j),$j # j++
+ adc \$0,%rdx
+ mov $N[1],(%rsp)
+ mov %rdx,$N[0]
+ jmp .L1st4x
+.align 16
+.L1st4x:
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[0]
+ mov -16($np,$j,8),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov -8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[0],-24(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[1]
+ mov -8($np,$j,8),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov ($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[1],-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[0]
+ mov ($np,$j,8),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov 8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[0],-8(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[1]
+ mov 8($np,$j,8),%rax
+ adc \$0,%rdx
+ lea 4($j),$j # j++
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov -16($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[1],-32(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+ cmp $num,$j
+ jl .L1st4x
+
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[0]
+ mov -16($np,$j,8),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov -8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[0],-24(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[0]
+ add %rax,$A[1]
+ mov -8($np,$j,8),%rax
+ adc \$0,%rdx
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov ($ap),%rax # ap[0]
+ adc \$0,%rdx
+ add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0]
+ adc \$0,%rdx
+ mov $N[1],-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+
+ movq %xmm0,$m0 # bp[1]
+
+ xor $N[1],$N[1]
+ add $A[0],$N[0]
+ adc \$0,$N[1]
+ mov $N[0],-8(%rsp,$j,8)
+ mov $N[1],(%rsp,$j,8) # store upmost overflow bit
+
+ lea 1($i),$i # i++
+.align 4
+.Louter4x:
+ xor $j,$j # j=0
+ movq `0*$STRIDE/4-96`($bp),%xmm0
+ movq `1*$STRIDE/4-96`($bp),%xmm1
+ pand %xmm4,%xmm0
+ movq `2*$STRIDE/4-96`($bp),%xmm2
+ pand %xmm5,%xmm1
+
+ mov (%rsp),$A[0]
+ mov $n0,$m1
+ mulq $m0 # ap[0]*bp[i]
+ add %rax,$A[0] # ap[0]*bp[i]+tp[0]
+ mov ($np),%rax
+ adc \$0,%rdx
+
+ movq `3*$STRIDE/4-96`($bp),%xmm3
+ pand %xmm6,%xmm2
+ por %xmm1,%xmm0
+ pand %xmm7,%xmm3
+
+ imulq $A[0],$m1 # tp[0]*n0
+ mov %rdx,$A[1]
+
+ por %xmm2,%xmm0
+ lea $STRIDE($bp),$bp
+ por %xmm3,%xmm0
+
+ mulq $m1 # np[0]*m1
+ add %rax,$A[0] # "$N[0]", discarded
+ mov 8($ap),%rax
+ adc \$0,%rdx
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[1]
+ mov 8($np),%rax
+ adc \$0,%rdx
+ add 8(%rsp),$A[1] # +tp[1]
+ adc \$0,%rdx
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov 16($ap),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1] # np[j]*m1+ap[j]*bp[i]+tp[j]
+ lea 4($j),$j # j+=2
+ adc \$0,%rdx
+ mov %rdx,$N[0]
+ jmp .Linner4x
+.align 16
+.Linner4x:
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[0]
+ mov -16($np,$j,8),%rax
+ adc \$0,%rdx
+ add -16(%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j]
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov -8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0]
+ adc \$0,%rdx
+ mov $N[1],-32(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[1]
+ mov -8($np,$j,8),%rax
+ adc \$0,%rdx
+ add -8(%rsp,$j,8),$A[1]
+ adc \$0,%rdx
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov ($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1]
+ adc \$0,%rdx
+ mov $N[0],-24(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[0]
+ mov ($np,$j,8),%rax
+ adc \$0,%rdx
+ add (%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j]
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov 8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0]
+ adc \$0,%rdx
+ mov $N[1],-16(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[1]
+ mov 8($np,$j,8),%rax
+ adc \$0,%rdx
+ add 8(%rsp,$j,8),$A[1]
+ adc \$0,%rdx
+ lea 4($j),$j # j++
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov -16($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[1],$N[1]
+ adc \$0,%rdx
+ mov $N[0],-40(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+ cmp $num,$j
+ jl .Linner4x
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[0]
+ mov -16($np,$j,8),%rax
+ adc \$0,%rdx
+ add -16(%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j]
+ adc \$0,%rdx
+ mov %rdx,$A[1]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[0]
+ mov -8($ap,$j,8),%rax
+ adc \$0,%rdx
+ add $A[0],$N[0]
+ adc \$0,%rdx
+ mov $N[1],-32(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[1]
+
+ mulq $m0 # ap[j]*bp[i]
+ add %rax,$A[1]
+ mov -8($np,$j,8),%rax
+ adc \$0,%rdx
+ add -8(%rsp,$j,8),$A[1]
+ adc \$0,%rdx
+ lea 1($i),$i # i++
+ mov %rdx,$A[0]
+
+ mulq $m1 # np[j]*m1
+ add %rax,$N[1]
+ mov ($ap),%rax # ap[0]
+ adc \$0,%rdx
+ add $A[1],$N[1]
+ adc \$0,%rdx
+ mov $N[0],-24(%rsp,$j,8) # tp[j-1]
+ mov %rdx,$N[0]
+
+ movq %xmm0,$m0 # bp[i+1]
+ mov $N[1],-16(%rsp,$j,8) # tp[j-1]
+
+ xor $N[1],$N[1]
+ add $A[0],$N[0]
+ adc \$0,$N[1]
+ add (%rsp,$num,8),$N[0] # pull upmost overflow bit
+ adc \$0,$N[1]
+ mov $N[0],-8(%rsp,$j,8)
+ mov $N[1],(%rsp,$j,8) # store upmost overflow bit
+
+ cmp $num,$i
+ jl .Louter4x
+___
+{
+my @ri=("%rax","%rdx",$m0,$m1);
+$code.=<<___;
+ mov 16(%rsp,$num,8),$rp # restore $rp
+ mov 0(%rsp),@ri[0] # tp[0]
+ pxor %xmm0,%xmm0
+ mov 8(%rsp),@ri[1] # tp[1]
+ shr \$2,$num # num/=4
+ lea (%rsp),$ap # borrow ap for tp
+ xor $i,$i # i=0 and clear CF!
+
+ sub 0($np),@ri[0]
+ mov 16($ap),@ri[2] # tp[2]
+ mov 24($ap),@ri[3] # tp[3]
+ sbb 8($np),@ri[1]
+ lea -1($num),$j # j=num/4-1
+ jmp .Lsub4x
+.align 16
+.Lsub4x:
+ mov @ri[0],0($rp,$i,8) # rp[i]=tp[i]-np[i]
+ mov @ri[1],8($rp,$i,8) # rp[i]=tp[i]-np[i]
+ sbb 16($np,$i,8),@ri[2]
+ mov 32($ap,$i,8),@ri[0] # tp[i+1]
+ mov 40($ap,$i,8),@ri[1]
+ sbb 24($np,$i,8),@ri[3]
+ mov @ri[2],16($rp,$i,8) # rp[i]=tp[i]-np[i]
+ mov @ri[3],24($rp,$i,8) # rp[i]=tp[i]-np[i]
+ sbb 32($np,$i,8),@ri[0]
+ mov 48($ap,$i,8),@ri[2]
+ mov 56($ap,$i,8),@ri[3]
+ sbb 40($np,$i,8),@ri[1]
+ lea 4($i),$i # i++
+ dec $j # doesnn't affect CF!
+ jnz .Lsub4x
+
+ mov @ri[0],0($rp,$i,8) # rp[i]=tp[i]-np[i]
+ mov 32($ap,$i,8),@ri[0] # load overflow bit
+ sbb 16($np,$i,8),@ri[2]
+ mov @ri[1],8($rp,$i,8) # rp[i]=tp[i]-np[i]
+ sbb 24($np,$i,8),@ri[3]
+ mov @ri[2],16($rp,$i,8) # rp[i]=tp[i]-np[i]
+
+ sbb \$0,@ri[0] # handle upmost overflow bit
+ mov @ri[3],24($rp,$i,8) # rp[i]=tp[i]-np[i]
+ xor $i,$i # i=0
+ and @ri[0],$ap
+ not @ri[0]
+ mov $rp,$np
+ and @ri[0],$np
+ lea -1($num),$j
+ or $np,$ap # ap=borrow?tp:rp
+
+ movdqu ($ap),%xmm1
+ movdqa %xmm0,(%rsp)
+ movdqu %xmm1,($rp)
+ jmp .Lcopy4x
+.align 16
+.Lcopy4x: # copy or in-place refresh
+ movdqu 16($ap,$i),%xmm2
+ movdqu 32($ap,$i),%xmm1
+ movdqa %xmm0,16(%rsp,$i)
+ movdqu %xmm2,16($rp,$i)
+ movdqa %xmm0,32(%rsp,$i)
+ movdqu %xmm1,32($rp,$i)
+ lea 32($i),$i
+ dec $j
+ jnz .Lcopy4x
+
+ shl \$2,$num
+ movdqu 16($ap,$i),%xmm2
+ movdqa %xmm0,16(%rsp,$i)
+ movdqu %xmm2,16($rp,$i)
+___
+}
+$code.=<<___;
+ mov 8(%rsp,$num,8),%rsi # restore %rsp
+ mov \$1,%rax
+___
+$code.=<<___ if ($win64);
+ movaps (%rsi),%xmm6
+ movaps 0x10(%rsi),%xmm7
+ lea 0x28(%rsi),%rsi
+___
+$code.=<<___;
+ mov (%rsi),%r15
+ mov 8(%rsi),%r14
+ mov 16(%rsi),%r13
+ mov 24(%rsi),%r12
+ mov 32(%rsi),%rbp
+ mov 40(%rsi),%rbx
+ lea 48(%rsi),%rsp
+.Lmul4x_epilogue:
+ ret
+.size bn_mul4x_mont_gather5,.-bn_mul4x_mont_gather5
+___
+}}}
+
+{
+my ($inp,$num,$tbl,$idx)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order
+ ("%rdi","%rsi","%rdx","%rcx"); # Unix order
+my $out=$inp;
+my $STRIDE=2**5*8;
+my $N=$STRIDE/4;
+
+$code.=<<___;
+.globl bn_scatter5
+.type bn_scatter5,\@abi-omnipotent
+.align 16
+bn_scatter5:
+ cmp \$0, $num
+ jz .Lscatter_epilogue
+ lea ($tbl,$idx,8),$tbl
+.Lscatter:
+ mov ($inp),%rax
+ lea 8($inp),$inp
+ mov %rax,($tbl)
+ lea 32*8($tbl),$tbl
+ sub \$1,$num
+ jnz .Lscatter
+.Lscatter_epilogue:
+ ret
+.size bn_scatter5,.-bn_scatter5
+
+.globl bn_gather5
+.type bn_gather5,\@abi-omnipotent
+.align 16
+bn_gather5:
+___
+$code.=<<___ if ($win64);
+.LSEH_begin_bn_gather5:
+ # I can't trust assembler to use specific encoding:-(
+ .byte 0x48,0x83,0xec,0x28 #sub \$0x28,%rsp
+ .byte 0x0f,0x29,0x34,0x24 #movaps %xmm6,(%rsp)
+ .byte 0x0f,0x29,0x7c,0x24,0x10 #movdqa %xmm7,0x10(%rsp)
+___
+$code.=<<___;
+ mov $idx,%r11
+ shr \$`log($N/8)/log(2)`,$idx
+ and \$`$N/8-1`,%r11
+ not $idx
+ lea .Lmagic_masks(%rip),%rax
+ and \$`2**5/($N/8)-1`,$idx # 5 is "window size"
+ lea 96($tbl,%r11,8),$tbl # pointer within 1st cache line
+ movq 0(%rax,$idx,8),%xmm4 # set of masks denoting which
+ movq 8(%rax,$idx,8),%xmm5 # cache line contains element
+ movq 16(%rax,$idx,8),%xmm6 # denoted by 7th argument
+ movq 24(%rax,$idx,8),%xmm7
+ jmp .Lgather
+.align 16
+.Lgather:
+ movq `0*$STRIDE/4-96`($tbl),%xmm0
+ movq `1*$STRIDE/4-96`($tbl),%xmm1
+ pand %xmm4,%xmm0
+ movq `2*$STRIDE/4-96`($tbl),%xmm2
+ pand %xmm5,%xmm1
+ movq `3*$STRIDE/4-96`($tbl),%xmm3
+ pand %xmm6,%xmm2
+ por %xmm1,%xmm0
+ pand %xmm7,%xmm3
+ por %xmm2,%xmm0
+ lea $STRIDE($tbl),$tbl
+ por %xmm3,%xmm0
+
+ movq %xmm0,($out) # m0=bp[0]
+ lea 8($out),$out
+ sub \$1,$num
+ jnz .Lgather
+___
+$code.=<<___ if ($win64);
+ movaps %xmm6,(%rsp)
+ movaps %xmm7,0x10(%rsp)
+ lea 0x28(%rsp),%rsp
+___
+$code.=<<___;
+ ret
+.LSEH_end_bn_gather5:
+.size bn_gather5,.-bn_gather5
+___
+}
+$code.=<<___;
+.align 64
+.Lmagic_masks:
+ .long 0,0, 0,0, 0,0, -1,-1
+ .long 0,0, 0,0, 0,0, 0,0
+.asciz "Montgomery Multiplication with scatter/gather for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+.type mul_handler,\@abi-omnipotent
+.align 16
+mul_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # end of prologue label
+ cmp %r10,%rbx # context->Rip<end of prologue label
+ jb .Lcommon_seh_tail
+
+ lea `40+48`(%rax),%rax
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # end of alloca label
+ cmp %r10,%rbx # context->Rip<end of alloca label
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 8(%r11),%r10d # HandlerData[2]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lcommon_seh_tail
+
+ mov 192($context),%r10 # pull $num
+ mov 8(%rax,%r10,8),%rax # pull saved stack pointer
+
+ movaps (%rax),%xmm0
+ movaps 16(%rax),%xmm1
+ lea `40+48`(%rax),%rax
+
+ mov -8(%rax),%rbx
+ mov -16(%rax),%rbp
+ mov -24(%rax),%r12
+ mov -32(%rax),%r13
+ mov -40(%rax),%r14
+ mov -48(%rax),%r15
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R13
+ mov %r14,232($context) # restore context->R14
+ mov %r15,240($context) # restore context->R15
+ movups %xmm0,512($context) # restore context->Xmm6
+ movups %xmm1,528($context) # restore context->Xmm7
+
+.Lcommon_seh_tail:
+ mov 8(%rax),%rdi
+ mov 16(%rax),%rsi
+ mov %rax,152($context) # restore context->Rsp
+ mov %rsi,168($context) # restore context->Rsi
+ mov %rdi,176($context) # restore context->Rdi
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$154,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size mul_handler,.-mul_handler
+
+.section .pdata
+.align 4
+ .rva .LSEH_begin_bn_mul_mont_gather5
+ .rva .LSEH_end_bn_mul_mont_gather5
+ .rva .LSEH_info_bn_mul_mont_gather5
+
+ .rva .LSEH_begin_bn_mul4x_mont_gather5
+ .rva .LSEH_end_bn_mul4x_mont_gather5
+ .rva .LSEH_info_bn_mul4x_mont_gather5
+
+ .rva .LSEH_begin_bn_gather5
+ .rva .LSEH_end_bn_gather5
+ .rva .LSEH_info_bn_gather5
+
+.section .xdata
+.align 8
+.LSEH_info_bn_mul_mont_gather5:
+ .byte 9,0,0,0
+ .rva mul_handler
+ .rva .Lmul_alloca,.Lmul_body,.Lmul_epilogue # HandlerData[]
+.align 8
+.LSEH_info_bn_mul4x_mont_gather5:
+ .byte 9,0,0,0
+ .rva mul_handler
+ .rva .Lmul4x_alloca,.Lmul4x_body,.Lmul4x_epilogue # HandlerData[]
+.align 8
+.LSEH_info_bn_gather5:
+ .byte 0x01,0x0d,0x05,0x00
+ .byte 0x0d,0x78,0x01,0x00 #movaps 0x10(rsp),xmm7
+ .byte 0x08,0x68,0x00,0x00 #movaps (rsp),xmm6
+ .byte 0x04,0x42,0x00,0x00 #sub rsp,0x28
+.align 8
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/bn/bn.h b/deps/openssl/openssl/crypto/bn/bn.h
index a0bc47837..f34248ec4 100644
--- a/deps/openssl/openssl/crypto/bn/bn.h
+++ b/deps/openssl/openssl/crypto/bn/bn.h
@@ -558,6 +558,17 @@ int BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb);
int BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx,
int do_trial_division, BN_GENCB *cb);
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx);
+
+int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
+ const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb);
+int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ BIGNUM *Xp1, BIGNUM *Xp2,
+ const BIGNUM *Xp,
+ const BIGNUM *e, BN_CTX *ctx,
+ BN_GENCB *cb);
+
BN_MONT_CTX *BN_MONT_CTX_new(void );
void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
@@ -612,6 +623,8 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
BN_RECP_CTX *recp, BN_CTX *ctx);
+#ifndef OPENSSL_NO_EC2M
+
/* Functions for arithmetic over binary polynomials represented by BIGNUMs.
*
* The BIGNUM::neg property of BIGNUMs representing binary polynomials is
@@ -663,6 +676,8 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
int BN_GF2m_arr2poly(const int p[], BIGNUM *a);
+#endif
+
/* faster mod functions for the 'NIST primes'
* 0 <= a < p^2 */
int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
diff --git a/deps/openssl/openssl/crypto/bn/bn_div.c b/deps/openssl/openssl/crypto/bn/bn_div.c
index 802a43d64..7b2403185 100644
--- a/deps/openssl/openssl/crypto/bn/bn_div.c
+++ b/deps/openssl/openssl/crypto/bn/bn_div.c
@@ -141,6 +141,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
*
* <appro@fy.chalmers.se>
*/
+#undef bn_div_words
# define bn_div_words(n0,n1,d0) \
({ asm volatile ( \
"divl %4" \
@@ -155,6 +156,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
* Same story here, but it's 128-bit by 64-bit division. Wow!
* <appro@fy.chalmers.se>
*/
+# undef bn_div_words
# define bn_div_words(n0,n1,d0) \
({ asm volatile ( \
"divq %4" \
@@ -169,15 +171,13 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
#endif /* OPENSSL_NO_ASM */
-/* BN_div[_no_branch] computes dv := num / divisor, rounding towards
+/* BN_div computes dv := num / divisor, rounding towards
* zero, and sets up rm such that dv*divisor + rm = num holds.
* Thus:
* dv->neg == num->neg ^ divisor->neg (unless the result is zero)
* rm->neg == num->neg (unless the remainder is zero)
* If 'dv' or 'rm' is NULL, the respective value is not returned.
*/
-static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
- const BIGNUM *divisor, BN_CTX *ctx);
int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
BN_CTX *ctx)
{
@@ -186,6 +186,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
BN_ULONG *resp,*wnump;
BN_ULONG d0,d1;
int num_n,div_n;
+ int no_branch=0;
/* Invalid zero-padding would have particularly bad consequences
* in the case of 'num', so don't just rely on bn_check_top() for this one
@@ -200,7 +201,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0))
{
- return BN_div_no_branch(dv, rm, num, divisor, ctx);
+ no_branch=1;
}
bn_check_top(dv);
@@ -214,7 +215,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
return(0);
}
- if (BN_ucmp(num,divisor) < 0)
+ if (!no_branch && BN_ucmp(num,divisor) < 0)
{
if (rm != NULL)
{ if (BN_copy(rm,num) == NULL) return(0); }
@@ -239,242 +240,25 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
norm_shift+=BN_BITS2;
if (!(BN_lshift(snum,num,norm_shift))) goto err;
snum->neg=0;
- div_n=sdiv->top;
- num_n=snum->top;
- loop=num_n-div_n;
- /* Lets setup a 'window' into snum
- * This is the part that corresponds to the current
- * 'area' being divided */
- wnum.neg = 0;
- wnum.d = &(snum->d[loop]);
- wnum.top = div_n;
- /* only needed when BN_ucmp messes up the values between top and max */
- wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
-
- /* Get the top 2 words of sdiv */
- /* div_n=sdiv->top; */
- d0=sdiv->d[div_n-1];
- d1=(div_n == 1)?0:sdiv->d[div_n-2];
-
- /* pointer to the 'top' of snum */
- wnump= &(snum->d[num_n-1]);
-
- /* Setup to 'res' */
- res->neg= (num->neg^divisor->neg);
- if (!bn_wexpand(res,(loop+1))) goto err;
- res->top=loop;
- resp= &(res->d[loop-1]);
-
- /* space for temp */
- if (!bn_wexpand(tmp,(div_n+1))) goto err;
- if (BN_ucmp(&wnum,sdiv) >= 0)
+ if (no_branch)
{
- /* If BN_DEBUG_RAND is defined BN_ucmp changes (via
- * bn_pollute) the const bignum arguments =>
- * clean the values between top and max again */
- bn_clear_top2max(&wnum);
- bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
- *resp=1;
- }
- else
- res->top--;
- /* if res->top == 0 then clear the neg value otherwise decrease
- * the resp pointer */
- if (res->top == 0)
- res->neg = 0;
- else
- resp--;
-
- for (i=0; i<loop-1; i++, wnump--, resp--)
- {
- BN_ULONG q,l0;
- /* the first part of the loop uses the top two words of
- * snum and sdiv to calculate a BN_ULONG q such that
- * | wnum - sdiv * q | < sdiv */
-#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
- BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
- q=bn_div_3_words(wnump,d1,d0);
-#else
- BN_ULONG n0,n1,rem=0;
-
- n0=wnump[0];
- n1=wnump[-1];
- if (n0 == d0)
- q=BN_MASK2;
- else /* n0 < d0 */
- {
-#ifdef BN_LLONG
- BN_ULLONG t2;
-
-#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
- q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
-#else
- q=bn_div_words(n0,n1,d0);
-#ifdef BN_DEBUG_LEVITTE
- fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
-X) -> 0x%08X\n",
- n0, n1, d0, q);
-#endif
-#endif
-
-#ifndef REMAINDER_IS_ALREADY_CALCULATED
- /*
- * rem doesn't have to be BN_ULLONG. The least we
- * know it's less that d0, isn't it?
- */
- rem=(n1-q*d0)&BN_MASK2;
-#endif
- t2=(BN_ULLONG)d1*q;
-
- for (;;)
- {
- if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
- break;
- q--;
- rem += d0;
- if (rem < d0) break; /* don't let rem overflow */
- t2 -= d1;
- }
-#else /* !BN_LLONG */
- BN_ULONG t2l,t2h;
-
- q=bn_div_words(n0,n1,d0);
-#ifdef BN_DEBUG_LEVITTE
- fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
-X) -> 0x%08X\n",
- n0, n1, d0, q);
-#endif
-#ifndef REMAINDER_IS_ALREADY_CALCULATED
- rem=(n1-q*d0)&BN_MASK2;
-#endif
-
-#if defined(BN_UMULT_LOHI)
- BN_UMULT_LOHI(t2l,t2h,d1,q);
-#elif defined(BN_UMULT_HIGH)
- t2l = d1 * q;
- t2h = BN_UMULT_HIGH(d1,q);
-#else
+ /* Since we don't know whether snum is larger than sdiv,
+ * we pad snum with enough zeroes without changing its
+ * value.
+ */
+ if (snum->top <= sdiv->top+1)
{
- BN_ULONG ql, qh;
- t2l=LBITS(d1); t2h=HBITS(d1);
- ql =LBITS(q); qh =HBITS(q);
- mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+ if (bn_wexpand(snum, sdiv->top + 2) == NULL) goto err;
+ for (i = snum->top; i < sdiv->top + 2; i++) snum->d[i] = 0;
+ snum->top = sdiv->top + 2;
}
-#endif
-
- for (;;)
- {
- if ((t2h < rem) ||
- ((t2h == rem) && (t2l <= wnump[-2])))
- break;
- q--;
- rem += d0;
- if (rem < d0) break; /* don't let rem overflow */
- if (t2l < d1) t2h--; t2l -= d1;
- }
-#endif /* !BN_LLONG */
- }
-#endif /* !BN_DIV3W */
-
- l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
- tmp->d[div_n]=l0;
- wnum.d--;
- /* ingore top values of the bignums just sub the two
- * BN_ULONG arrays with bn_sub_words */
- if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n+1))
+ else
{
- /* Note: As we have considered only the leading
- * two BN_ULONGs in the calculation of q, sdiv * q
- * might be greater than wnum (but then (q-1) * sdiv
- * is less or equal than wnum)
- */
- q--;
- if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
- /* we can't have an overflow here (assuming
- * that q != 0, but if q == 0 then tmp is
- * zero anyway) */
- (*wnump)++;
+ if (bn_wexpand(snum, snum->top + 1) == NULL) goto err;
+ snum->d[snum->top] = 0;
+ snum->top ++;
}
- /* store part of the result */
- *resp = q;
- }
- bn_correct_top(snum);
- if (rm != NULL)
- {
- /* Keep a copy of the neg flag in num because if rm==num
- * BN_rshift() will overwrite it.
- */
- int neg = num->neg;
- BN_rshift(rm,snum,norm_shift);
- if (!BN_is_zero(rm))
- rm->neg = neg;
- bn_check_top(rm);
- }
- BN_CTX_end(ctx);
- return(1);
-err:
- bn_check_top(rm);
- BN_CTX_end(ctx);
- return(0);
- }
-
-
-/* BN_div_no_branch is a special version of BN_div. It does not contain
- * branches that may leak sensitive information.
- */
-static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
- const BIGNUM *divisor, BN_CTX *ctx)
- {
- int norm_shift,i,loop;
- BIGNUM *tmp,wnum,*snum,*sdiv,*res;
- BN_ULONG *resp,*wnump;
- BN_ULONG d0,d1;
- int num_n,div_n;
-
- bn_check_top(dv);
- bn_check_top(rm);
- /* bn_check_top(num); */ /* 'num' has been checked in BN_div() */
- bn_check_top(divisor);
-
- if (BN_is_zero(divisor))
- {
- BNerr(BN_F_BN_DIV_NO_BRANCH,BN_R_DIV_BY_ZERO);
- return(0);
- }
-
- BN_CTX_start(ctx);
- tmp=BN_CTX_get(ctx);
- snum=BN_CTX_get(ctx);
- sdiv=BN_CTX_get(ctx);
- if (dv == NULL)
- res=BN_CTX_get(ctx);
- else res=dv;
- if (sdiv == NULL || res == NULL) goto err;
-
- /* First we normalise the numbers */
- norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
- if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err;
- sdiv->neg=0;
- norm_shift+=BN_BITS2;
- if (!(BN_lshift(snum,num,norm_shift))) goto err;
- snum->neg=0;
-
- /* Since we don't know whether snum is larger than sdiv,
- * we pad snum with enough zeroes without changing its
- * value.
- */
- if (snum->top <= sdiv->top+1)
- {
- if (bn_wexpand(snum, sdiv->top + 2) == NULL) goto err;
- for (i = snum->top; i < sdiv->top + 2; i++) snum->d[i] = 0;
- snum->top = sdiv->top + 2;
- }
- else
- {
- if (bn_wexpand(snum, snum->top + 1) == NULL) goto err;
- snum->d[snum->top] = 0;
- snum->top ++;
}
div_n=sdiv->top;
@@ -500,12 +284,27 @@ static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
/* Setup to 'res' */
res->neg= (num->neg^divisor->neg);
if (!bn_wexpand(res,(loop+1))) goto err;
- res->top=loop-1;
+ res->top=loop-no_branch;
resp= &(res->d[loop-1]);
/* space for temp */
if (!bn_wexpand(tmp,(div_n+1))) goto err;
+ if (!no_branch)
+ {
+ if (BN_ucmp(&wnum,sdiv) >= 0)
+ {
+ /* If BN_DEBUG_RAND is defined BN_ucmp changes (via
+ * bn_pollute) the const bignum arguments =>
+ * clean the values between top and max again */
+ bn_clear_top2max(&wnum);
+ bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
+ *resp=1;
+ }
+ else
+ res->top--;
+ }
+
/* if res->top == 0 then clear the neg value otherwise decrease
* the resp pointer */
if (res->top == 0)
@@ -638,7 +437,7 @@ X) -> 0x%08X\n",
rm->neg = neg;
bn_check_top(rm);
}
- bn_correct_top(res);
+ if (no_branch) bn_correct_top(res);
BN_CTX_end(ctx);
return(1);
err:
@@ -646,5 +445,4 @@ err:
BN_CTX_end(ctx);
return(0);
}
-
#endif
diff --git a/deps/openssl/openssl/crypto/bn/bn_exp.c b/deps/openssl/openssl/crypto/bn/bn_exp.c
index d9b6c737f..2abf6fd67 100644
--- a/deps/openssl/openssl/crypto/bn/bn_exp.c
+++ b/deps/openssl/openssl/crypto/bn/bn_exp.c
@@ -113,6 +113,18 @@
#include "cryptlib.h"
#include "bn_lcl.h"
+#include <stdlib.h>
+#ifdef _WIN32
+# include <malloc.h>
+# ifndef alloca
+# define alloca _alloca
+# endif
+#elif defined(__GNUC__)
+# ifndef alloca
+# define alloca(s) __builtin_alloca((s))
+# endif
+#endif
+
/* maximum precomputation table size for *variable* sliding windows */
#define TABLE_SIZE 32
@@ -522,23 +534,17 @@ err:
* as cache lines are concerned. The following functions are used to transfer a BIGNUM
* from/to that table. */
-static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width)
+static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf, int idx, int width)
{
size_t i, j;
- if (bn_wexpand(b, top) == NULL)
- return 0;
- while (b->top < top)
- {
- b->d[b->top++] = 0;
- }
-
+ if (top > b->top)
+ top = b->top; /* this works because 'buf' is explicitly zeroed */
for (i = 0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
{
buf[j] = ((unsigned char*)b->d)[i];
}
- bn_correct_top(b);
return 1;
}
@@ -561,7 +567,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf
/* Given a pointer value, compute the next address that is a cache line multiple. */
#define MOD_EXP_CTIME_ALIGN(x_) \
- ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((BN_ULONG)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
+ ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
/* This variant of BN_mod_exp_mont() uses fixed windows and the special
* precomputation memory layout to limit data-dependency to a minimum
@@ -572,17 +578,15 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf
int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
{
- int i,bits,ret=0,idx,window,wvalue;
+ int i,bits,ret=0,window,wvalue;
int top;
- BIGNUM *r;
- const BIGNUM *aa;
BN_MONT_CTX *mont=NULL;
int numPowers;
unsigned char *powerbufFree=NULL;
int powerbufLen = 0;
unsigned char *powerbuf=NULL;
- BIGNUM *computeTemp=NULL, *am=NULL;
+ BIGNUM tmp, am;
bn_check_top(a);
bn_check_top(p);
@@ -602,10 +606,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
return ret;
}
- /* Initialize BIGNUM context and allocate intermediate result */
BN_CTX_start(ctx);
- r = BN_CTX_get(ctx);
- if (r == NULL) goto err;
/* Allocate a montgomery context if it was not supplied by the caller.
* If this is not done, things will break in the montgomery part.
@@ -620,40 +621,154 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* Get the window size to use with size of p. */
window = BN_window_bits_for_ctime_exponent_size(bits);
+#if defined(OPENSSL_BN_ASM_MONT5)
+ if (window==6 && bits<=1024) window=5; /* ~5% improvement of 2048-bit RSA sign */
+#endif
/* Allocate a buffer large enough to hold all of the pre-computed
- * powers of a.
+ * powers of am, am itself and tmp.
*/
numPowers = 1 << window;
- powerbufLen = sizeof(m->d[0])*top*numPowers;
+ powerbufLen = sizeof(m->d[0])*(top*numPowers +
+ ((2*top)>numPowers?(2*top):numPowers));
+#ifdef alloca
+ if (powerbufLen < 3072)
+ powerbufFree = alloca(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
+ else
+#endif
if ((powerbufFree=(unsigned char*)OPENSSL_malloc(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
goto err;
powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
memset(powerbuf, 0, powerbufLen);
- /* Initialize the intermediate result. Do this early to save double conversion,
- * once each for a^0 and intermediate result.
- */
- if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
- if (!MOD_EXP_CTIME_COPY_TO_PREBUF(r, top, powerbuf, 0, numPowers)) goto err;
+#ifdef alloca
+ if (powerbufLen < 3072)
+ powerbufFree = NULL;
+#endif
- /* Initialize computeTemp as a^1 with montgomery precalcs */
- computeTemp = BN_CTX_get(ctx);
- am = BN_CTX_get(ctx);
- if (computeTemp==NULL || am==NULL) goto err;
+ /* lay down tmp and am right after powers table */
+ tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0])*top*numPowers);
+ am.d = tmp.d + top;
+ tmp.top = am.top = 0;
+ tmp.dmax = am.dmax = top;
+ tmp.neg = am.neg = 0;
+ tmp.flags = am.flags = BN_FLG_STATIC_DATA;
+
+ /* prepare a^0 in Montgomery domain */
+#if 1
+ if (!BN_to_montgomery(&tmp,BN_value_one(),mont,ctx)) goto err;
+#else
+ tmp.d[0] = (0-m->d[0])&BN_MASK2; /* 2^(top*BN_BITS2) - m */
+ for (i=1;i<top;i++)
+ tmp.d[i] = (~m->d[i])&BN_MASK2;
+ tmp.top = top;
+#endif
+ /* prepare a^1 in Montgomery domain */
if (a->neg || BN_ucmp(a,m) >= 0)
{
- if (!BN_mod(am,a,m,ctx))
- goto err;
- aa= am;
+ if (!BN_mod(&am,a,m,ctx)) goto err;
+ if (!BN_to_montgomery(&am,&am,mont,ctx)) goto err;
}
- else
- aa=a;
- if (!BN_to_montgomery(am,aa,mont,ctx)) goto err;
- if (!BN_copy(computeTemp, am)) goto err;
- if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, numPowers)) goto err;
+ else if (!BN_to_montgomery(&am,a,mont,ctx)) goto err;
+
+#if defined(OPENSSL_BN_ASM_MONT5)
+ /* This optimization uses ideas from http://eprint.iacr.org/2011/239,
+ * specifically optimization of cache-timing attack countermeasures
+ * and pre-computation optimization. */
+
+ /* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
+ * 512-bit RSA is hardly relevant, we omit it to spare size... */
+ if (window==5)
+ {
+ void bn_mul_mont_gather5(BN_ULONG *rp,const BN_ULONG *ap,
+ const void *table,const BN_ULONG *np,
+ const BN_ULONG *n0,int num,int power);
+ void bn_scatter5(const BN_ULONG *inp,size_t num,
+ void *table,size_t power);
+ void bn_gather5(BN_ULONG *out,size_t num,
+ void *table,size_t power);
+
+ BN_ULONG *np=mont->N.d, *n0=mont->n0;
+
+ /* BN_to_montgomery can contaminate words above .top
+ * [in BN_DEBUG[_DEBUG] build]... */
+ for (i=am.top; i<top; i++) am.d[i]=0;
+ for (i=tmp.top; i<top; i++) tmp.d[i]=0;
+
+ bn_scatter5(tmp.d,top,powerbuf,0);
+ bn_scatter5(am.d,am.top,powerbuf,1);
+ bn_mul_mont(tmp.d,am.d,am.d,np,n0,top);
+ bn_scatter5(tmp.d,top,powerbuf,2);
+
+#if 0
+ for (i=3; i<32; i++)
+ {
+ /* Calculate a^i = a^(i-1) * a */
+ bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1);
+ bn_scatter5(tmp.d,top,powerbuf,i);
+ }
+#else
+ /* same as above, but uses squaring for 1/2 of operations */
+ for (i=4; i<32; i*=2)
+ {
+ bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
+ bn_scatter5(tmp.d,top,powerbuf,i);
+ }
+ for (i=3; i<8; i+=2)
+ {
+ int j;
+ bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1);
+ bn_scatter5(tmp.d,top,powerbuf,i);
+ for (j=2*i; j<32; j*=2)
+ {
+ bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
+ bn_scatter5(tmp.d,top,powerbuf,j);
+ }
+ }
+ for (; i<16; i+=2)
+ {
+ bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1);
+ bn_scatter5(tmp.d,top,powerbuf,i);
+ bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
+ bn_scatter5(tmp.d,top,powerbuf,2*i);
+ }
+ for (; i<32; i+=2)
+ {
+ bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1);
+ bn_scatter5(tmp.d,top,powerbuf,i);
+ }
+#endif
+ bits--;
+ for (wvalue=0, i=bits%5; i>=0; i--,bits--)
+ wvalue = (wvalue<<1)+BN_is_bit_set(p,bits);
+ bn_gather5(tmp.d,top,powerbuf,wvalue);
+
+ /* Scan the exponent one window at a time starting from the most
+ * significant bits.
+ */
+ while (bits >= 0)
+ {
+ for (wvalue=0, i=0; i<5; i++,bits--)
+ wvalue = (wvalue<<1)+BN_is_bit_set(p,bits);
+
+ bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
+ bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
+ bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
+ bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
+ bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
+ bn_mul_mont_gather5(tmp.d,tmp.d,powerbuf,np,n0,top,wvalue);
+ }
+
+ tmp.top=top;
+ bn_correct_top(&tmp);
+ }
+ else
+#endif
+ {
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, numPowers)) goto err;
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, numPowers)) goto err;
/* If the window size is greater than 1, then calculate
* val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1)
@@ -662,62 +777,54 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
*/
if (window > 1)
{
- for (i=2; i<numPowers; i++)
+ if (!BN_mod_mul_montgomery(&tmp,&am,&am,mont,ctx)) goto err;
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2, numPowers)) goto err;
+ for (i=3; i<numPowers; i++)
{
/* Calculate a^i = a^(i-1) * a */
- if (!BN_mod_mul_montgomery(computeTemp,am,computeTemp,mont,ctx))
+ if (!BN_mod_mul_montgomery(&tmp,&am,&tmp,mont,ctx))
goto err;
- if (!MOD_EXP_CTIME_COPY_TO_PREBUF(computeTemp, top, powerbuf, i, numPowers)) goto err;
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i, numPowers)) goto err;
}
}
- /* Adjust the number of bits up to a multiple of the window size.
- * If the exponent length is not a multiple of the window size, then
- * this pads the most significant bits with zeros to normalize the
- * scanning loop to there's no special cases.
- *
- * * NOTE: Making the window size a power of two less than the native
- * * word size ensures that the padded bits won't go past the last
- * * word in the internal BIGNUM structure. Going past the end will
- * * still produce the correct result, but causes a different branch
- * * to be taken in the BN_is_bit_set function.
- */
- bits = ((bits+window-1)/window)*window;
- idx=bits-1; /* The top bit of the window */
-
- /* Scan the exponent one window at a time starting from the most
- * significant bits.
- */
- while (idx >= 0)
+ bits--;
+ for (wvalue=0, i=bits%window; i>=0; i--,bits--)
+ wvalue = (wvalue<<1)+BN_is_bit_set(p,bits);
+ if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp,top,powerbuf,wvalue,numPowers)) goto err;
+
+ /* Scan the exponent one window at a time starting from the most
+ * significant bits.
+ */
+ while (bits >= 0)
{
wvalue=0; /* The 'value' of the window */
/* Scan the window, squaring the result as we go */
- for (i=0; i<window; i++,idx--)
+ for (i=0; i<window; i++,bits--)
{
- if (!BN_mod_mul_montgomery(r,r,r,mont,ctx)) goto err;
- wvalue = (wvalue<<1)+BN_is_bit_set(p,idx);
+ if (!BN_mod_mul_montgomery(&tmp,&tmp,&tmp,mont,ctx)) goto err;
+ wvalue = (wvalue<<1)+BN_is_bit_set(p,bits);
}
/* Fetch the appropriate pre-computed value from the pre-buf */
- if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(computeTemp, top, powerbuf, wvalue, numPowers)) goto err;
+ if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue, numPowers)) goto err;
/* Multiply the result into the intermediate result */
- if (!BN_mod_mul_montgomery(r,r,computeTemp,mont,ctx)) goto err;
+ if (!BN_mod_mul_montgomery(&tmp,&tmp,&am,mont,ctx)) goto err;
}
+ }
/* Convert the final result from montgomery to standard format */
- if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
+ if (!BN_from_montgomery(rr,&tmp,mont,ctx)) goto err;
ret=1;
err:
if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
if (powerbuf!=NULL)
{
OPENSSL_cleanse(powerbuf,powerbufLen);
- OPENSSL_free(powerbufFree);
+ if (powerbufFree) OPENSSL_free(powerbufFree);
}
- if (am!=NULL) BN_clear(am);
- if (computeTemp!=NULL) BN_clear(computeTemp);
BN_CTX_end(ctx);
return(ret);
}
@@ -988,4 +1095,3 @@ err:
bn_check_top(r);
return(ret);
}
-
diff --git a/deps/openssl/openssl/crypto/bn/bn_gcd.c b/deps/openssl/openssl/crypto/bn/bn_gcd.c
index 4a352119b..a808f5317 100644
--- a/deps/openssl/openssl/crypto/bn/bn_gcd.c
+++ b/deps/openssl/openssl/crypto/bn/bn_gcd.c
@@ -205,6 +205,7 @@ err:
/* solves ax == 1 (mod n) */
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+
BIGNUM *BN_mod_inverse(BIGNUM *in,
const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
{
diff --git a/deps/openssl/openssl/crypto/bn/bn_gf2m.c b/deps/openssl/openssl/crypto/bn/bn_gf2m.c
index 432a3aa33..8a4dc20ad 100644
--- a/deps/openssl/openssl/crypto/bn/bn_gf2m.c
+++ b/deps/openssl/openssl/crypto/bn/bn_gf2m.c
@@ -94,6 +94,8 @@
#include "cryptlib.h"
#include "bn_lcl.h"
+#ifndef OPENSSL_NO_EC2M
+
/* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */
#define MAX_ITERATIONS 50
@@ -122,6 +124,7 @@ static const BN_ULONG SQR_tb[16] =
SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
#endif
+#if !defined(OPENSSL_BN_ASM_GF2m)
/* Product of two polynomials a, b each with degree < BN_BITS2 - 1,
* result is a polynomial r with degree < 2 * BN_BITS - 1
* The caller MUST ensure that the variables have the right amount
@@ -216,7 +219,9 @@ static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, c
r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */
r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */
}
-
+#else
+void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, BN_ULONG b0);
+#endif
/* Add polynomials a and b and store result in r; r could be a or b, a and b
* could be equal; r is the bitwise XOR of a and b.
@@ -360,21 +365,17 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
{
int ret = 0;
- const int max = BN_num_bits(p) + 1;
- int *arr=NULL;
+ int arr[6];
bn_check_top(a);
bn_check_top(p);
- if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
- ret = BN_GF2m_poly2arr(p, arr, max);
- if (!ret || ret > max)
+ ret = BN_GF2m_poly2arr(p, arr, sizeof(arr)/sizeof(arr[0]));
+ if (!ret || ret > (int)(sizeof(arr)/sizeof(arr[0])))
{
BNerr(BN_F_BN_GF2M_MOD,BN_R_INVALID_LENGTH);
- goto err;
+ return 0;
}
ret = BN_GF2m_mod_arr(r, a, arr);
bn_check_top(r);
-err:
- if (arr) OPENSSL_free(arr);
return ret;
}
@@ -521,7 +522,7 @@ err:
*/
int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
{
- BIGNUM *b, *c, *u, *v, *tmp;
+ BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp;
int ret = 0;
bn_check_top(a);
@@ -529,18 +530,18 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
BN_CTX_start(ctx);
- b = BN_CTX_get(ctx);
- c = BN_CTX_get(ctx);
- u = BN_CTX_get(ctx);
- v = BN_CTX_get(ctx);
- if (v == NULL) goto err;
+ if ((b = BN_CTX_get(ctx))==NULL) goto err;
+ if ((c = BN_CTX_get(ctx))==NULL) goto err;
+ if ((u = BN_CTX_get(ctx))==NULL) goto err;
+ if ((v = BN_CTX_get(ctx))==NULL) goto err;
- if (!BN_one(b)) goto err;
if (!BN_GF2m_mod(u, a, p)) goto err;
- if (!BN_copy(v, p)) goto err;
-
if (BN_is_zero(u)) goto err;
+ if (!BN_copy(v, p)) goto err;
+#if 0
+ if (!BN_one(b)) goto err;
+
while (1)
{
while (!BN_is_odd(u))
@@ -565,13 +566,89 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
if (!BN_GF2m_add(u, u, v)) goto err;
if (!BN_GF2m_add(b, b, c)) goto err;
}
+#else
+ {
+ int i, ubits = BN_num_bits(u),
+ vbits = BN_num_bits(v), /* v is copy of p */
+ top = p->top;
+ BN_ULONG *udp,*bdp,*vdp,*cdp;
+
+ bn_wexpand(u,top); udp = u->d;
+ for (i=u->top;i<top;i++) udp[i] = 0;
+ u->top = top;
+ bn_wexpand(b,top); bdp = b->d;
+ bdp[0] = 1;
+ for (i=1;i<top;i++) bdp[i] = 0;
+ b->top = top;
+ bn_wexpand(c,top); cdp = c->d;
+ for (i=0;i<top;i++) cdp[i] = 0;
+ c->top = top;
+ vdp = v->d; /* It pays off to "cache" *->d pointers, because
+ * it allows optimizer to be more aggressive.
+ * But we don't have to "cache" p->d, because *p
+ * is declared 'const'... */
+ while (1)
+ {
+ while (ubits && !(udp[0]&1))
+ {
+ BN_ULONG u0,u1,b0,b1,mask;
+
+ u0 = udp[0];
+ b0 = bdp[0];
+ mask = (BN_ULONG)0-(b0&1);
+ b0 ^= p->d[0]&mask;
+ for (i=0;i<top-1;i++)
+ {
+ u1 = udp[i+1];
+ udp[i] = ((u0>>1)|(u1<<(BN_BITS2-1)))&BN_MASK2;
+ u0 = u1;
+ b1 = bdp[i+1]^(p->d[i+1]&mask);
+ bdp[i] = ((b0>>1)|(b1<<(BN_BITS2-1)))&BN_MASK2;
+ b0 = b1;
+ }
+ udp[i] = u0>>1;
+ bdp[i] = b0>>1;
+ ubits--;
+ }
+ if (ubits<=BN_BITS2 && udp[0]==1) break;
+
+ if (ubits<vbits)
+ {
+ i = ubits; ubits = vbits; vbits = i;
+ tmp = u; u = v; v = tmp;
+ tmp = b; b = c; c = tmp;
+ udp = vdp; vdp = v->d;
+ bdp = cdp; cdp = c->d;
+ }
+ for(i=0;i<top;i++)
+ {
+ udp[i] ^= vdp[i];
+ bdp[i] ^= cdp[i];
+ }
+ if (ubits==vbits)
+ {
+ BN_ULONG ul;
+ int utop = (ubits-1)/BN_BITS2;
+
+ while ((ul=udp[utop])==0 && utop) utop--;
+ ubits = utop*BN_BITS2 + BN_num_bits_word(ul);
+ }
+ }
+ bn_correct_top(b);
+ }
+#endif
if (!BN_copy(r, b)) goto err;
bn_check_top(r);
ret = 1;
err:
+#ifdef BN_DEBUG /* BN_CTX_end would complain about the expanded form */
+ bn_correct_top(c);
+ bn_correct_top(u);
+ bn_correct_top(v);
+#endif
BN_CTX_end(ctx);
return ret;
}
@@ -1033,3 +1110,4 @@ int BN_GF2m_arr2poly(const int p[], BIGNUM *a)
return 1;
}
+#endif
diff --git a/deps/openssl/openssl/crypto/bn/bn_lcl.h b/deps/openssl/openssl/crypto/bn/bn_lcl.h
index 8e5e98e3f..817c773b6 100644
--- a/deps/openssl/openssl/crypto/bn/bn_lcl.h
+++ b/deps/openssl/openssl/crypto/bn/bn_lcl.h
@@ -238,7 +238,7 @@ extern "C" {
# if defined(__DECC)
# include <c_asm.h>
# define BN_UMULT_HIGH(a,b) (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
-# elif defined(__GNUC__)
+# elif defined(__GNUC__) && __GNUC__>=2
# define BN_UMULT_HIGH(a,b) ({ \
register BN_ULONG ret; \
asm ("umulh %1,%2,%0" \
@@ -247,7 +247,7 @@ extern "C" {
ret; })
# endif /* compiler */
# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
-# if defined(__GNUC__)
+# if defined(__GNUC__) && __GNUC__>=2
# define BN_UMULT_HIGH(a,b) ({ \
register BN_ULONG ret; \
asm ("mulhdu %0,%1,%2" \
@@ -257,7 +257,7 @@ extern "C" {
# endif /* compiler */
# elif (defined(__x86_64) || defined(__x86_64__)) && \
(defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
-# if defined(__GNUC__)
+# if defined(__GNUC__) && __GNUC__>=2
# define BN_UMULT_HIGH(a,b) ({ \
register BN_ULONG ret,discard; \
asm ("mulq %3" \
@@ -280,6 +280,26 @@ extern "C" {
# define BN_UMULT_HIGH(a,b) __umulh((a),(b))
# define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high)))
# endif
+# elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
+# if defined(__GNUC__) && __GNUC__>=2
+# if __GNUC__>=4 && __GNUC_MINOR__>=4 /* "h" constraint is no more since 4.4 */
+# define BN_UMULT_HIGH(a,b) (((__uint128_t)(a)*(b))>>64)
+# define BN_UMULT_LOHI(low,high,a,b) ({ \
+ __uint128_t ret=(__uint128_t)(a)*(b); \
+ (high)=ret>>64; (low)=ret; })
+# else
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret; \
+ asm ("dmultu %1,%2" \
+ : "=h"(ret) \
+ : "r"(a), "r"(b) : "l"); \
+ ret; })
+# define BN_UMULT_LOHI(low,high,a,b)\
+ asm ("dmultu %2,%3" \
+ : "=l"(low),"=h"(high) \
+ : "r"(a), "r"(b));
+# endif
+# endif
# endif /* cpu */
#endif /* OPENSSL_NO_ASM */
@@ -459,6 +479,10 @@ extern "C" {
}
#endif /* !BN_LLONG */
+#if defined(OPENSSL_DOING_MAKEDEPEND) && defined(OPENSSL_FIPS)
+#undef bn_div_words
+#endif
+
void bn_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
void bn_mul_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
void bn_mul_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
diff --git a/deps/openssl/openssl/crypto/bn/bn_lib.c b/deps/openssl/openssl/crypto/bn/bn_lib.c
index 5470fbe6e..7a5676de6 100644
--- a/deps/openssl/openssl/crypto/bn/bn_lib.c
+++ b/deps/openssl/openssl/crypto/bn/bn_lib.c
@@ -139,25 +139,6 @@ const BIGNUM *BN_value_one(void)
return(&const_one);
}
-char *BN_options(void)
- {
- static int init=0;
- static char data[16];
-
- if (!init)
- {
- init++;
-#ifdef BN_LLONG
- BIO_snprintf(data,sizeof data,"bn(%d,%d)",
- (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
-#else
- BIO_snprintf(data,sizeof data,"bn(%d,%d)",
- (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
-#endif
- }
- return(data);
- }
-
int BN_num_bits_word(BN_ULONG l)
{
static const unsigned char bits[256]={
diff --git a/deps/openssl/openssl/crypto/bn/bn_mont.c b/deps/openssl/openssl/crypto/bn/bn_mont.c
index 1a866880f..427b5cf4d 100644
--- a/deps/openssl/openssl/crypto/bn/bn_mont.c
+++ b/deps/openssl/openssl/crypto/bn/bn_mont.c
@@ -177,31 +177,26 @@ err:
static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
{
BIGNUM *n;
- BN_ULONG *ap,*np,*rp,n0,v,*nrp;
- int al,nl,max,i,x,ri;
+ BN_ULONG *ap,*np,*rp,n0,v,carry;
+ int nl,max,i;
n= &(mont->N);
- /* mont->ri is the size of mont->N in bits (rounded up
- to the word size) */
- al=ri=mont->ri/BN_BITS2;
-
nl=n->top;
- if ((al == 0) || (nl == 0)) { ret->top=0; return(1); }
+ if (nl == 0) { ret->top=0; return(1); }
- max=(nl+al+1); /* allow for overflow (no?) XXX */
+ max=(2*nl); /* carry is stored separately */
if (bn_wexpand(r,max) == NULL) return(0);
r->neg^=n->neg;
np=n->d;
rp=r->d;
- nrp= &(r->d[nl]);
/* clear the top words of T */
#if 1
for (i=r->top; i<max; i++) /* memset? XXX */
- r->d[i]=0;
+ rp[i]=0;
#else
- memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG));
+ memset(&(rp[r->top]),0,(max-r->top)*sizeof(BN_ULONG));
#endif
r->top=max;
@@ -210,7 +205,7 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
#ifdef BN_COUNT
fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl);
#endif
- for (i=0; i<nl; i++)
+ for (carry=0, i=0; i<nl; i++, rp++)
{
#ifdef __TANDEM
{
@@ -228,61 +223,33 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
#else
v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
#endif
- nrp++;
- rp++;
- if (((nrp[-1]+=v)&BN_MASK2) >= v)
- continue;
- else
- {
- if (((++nrp[0])&BN_MASK2) != 0) continue;
- if (((++nrp[1])&BN_MASK2) != 0) continue;
- for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
- }
- }
- bn_correct_top(r);
-
- /* mont->ri will be a multiple of the word size and below code
- * is kind of BN_rshift(ret,r,mont->ri) equivalent */
- if (r->top <= ri)
- {
- ret->top=0;
- return(1);
+ v = (v+carry+rp[nl])&BN_MASK2;
+ carry |= (v != rp[nl]);
+ carry &= (v <= rp[nl]);
+ rp[nl]=v;
}
- al=r->top-ri;
-#define BRANCH_FREE 1
-#if BRANCH_FREE
- if (bn_wexpand(ret,ri) == NULL) return(0);
- x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
- ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */
+ if (bn_wexpand(ret,nl) == NULL) return(0);
+ ret->top=nl;
ret->neg=r->neg;
rp=ret->d;
- ap=&(r->d[ri]);
+ ap=&(r->d[nl]);
+#define BRANCH_FREE 1
+#if BRANCH_FREE
{
- size_t m1,m2;
-
- v=bn_sub_words(rp,ap,np,ri);
- /* this ----------------^^ works even in al<ri case
- * thanks to zealous zeroing of top of the vector in the
- * beginning. */
+ BN_ULONG *nrp;
+ size_t m;
- /* if (al==ri && !v) || al>ri) nrp=rp; else nrp=ap; */
- /* in other words if subtraction result is real, then
+ v=bn_sub_words(rp,ap,np,nl)-carry;
+ /* if subtraction result is real, then
* trick unconditional memcpy below to perform in-place
* "refresh" instead of actual copy. */
- m1=0-(size_t)(((al-ri)>>(sizeof(al)*8-1))&1); /* al<ri */
- m2=0-(size_t)(((ri-al)>>(sizeof(al)*8-1))&1); /* al>ri */
- m1|=m2; /* (al!=ri) */
- m1|=(0-(size_t)v); /* (al!=ri || v) */
- m1&=~m2; /* (al!=ri || v) && !al>ri */
- nrp=(BN_ULONG *)(((PTR_SIZE_INT)rp&~m1)|((PTR_SIZE_INT)ap&m1));
- }
+ m=(0-(size_t)v);
+ nrp=(BN_ULONG *)(((PTR_SIZE_INT)rp&~m)|((PTR_SIZE_INT)ap&m));
- /* 'i<ri' is chosen to eliminate dependency on input data, even
- * though it results in redundant copy in al<ri case. */
- for (i=0,ri-=4; i<ri; i+=4)
+ for (i=0,nl-=4; i<nl; i+=4)
{
BN_ULONG t1,t2,t3,t4;
@@ -295,40 +262,15 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
rp[i+2]=t3;
rp[i+3]=t4;
}
- for (ri+=4; i<ri; i++)
+ for (nl+=4; i<nl; i++)
rp[i]=nrp[i], ap[i]=0;
- bn_correct_top(r);
- bn_correct_top(ret);
+ }
#else
- if (bn_wexpand(ret,al) == NULL) return(0);
- ret->top=al;
- ret->neg=r->neg;
-
- rp=ret->d;
- ap=&(r->d[ri]);
- al-=4;
- for (i=0; i<al; i+=4)
- {
- BN_ULONG t1,t2,t3,t4;
-
- t1=ap[i+0];
- t2=ap[i+1];
- t3=ap[i+2];
- t4=ap[i+3];
- rp[i+0]=t1;
- rp[i+1]=t2;
- rp[i+2]=t3;
- rp[i+3]=t4;
- }
- al+=4;
- for (; i<al; i++)
- rp[i]=ap[i];
-
- if (BN_ucmp(ret, &(mont->N)) >= 0)
- {
- if (!BN_usub(ret,ret,&(mont->N))) return(0);
- }
+ if (bn_sub_words (rp,ap,np,nl)-carry)
+ memcpy(rp,ap,nl*sizeof(BN_ULONG));
#endif
+ bn_correct_top(r);
+ bn_correct_top(ret);
bn_check_top(ret);
return(1);
diff --git a/deps/openssl/openssl/crypto/bn/bn_nist.c b/deps/openssl/openssl/crypto/bn/bn_nist.c
index c6de03269..43caee477 100644
--- a/deps/openssl/openssl/crypto/bn/bn_nist.c
+++ b/deps/openssl/openssl/crypto/bn/bn_nist.c
@@ -319,6 +319,13 @@ static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top)
:(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
#define bn_32_set_0(to, n) (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
#define bn_cp_32(to,n,from,m) ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
+# if defined(L_ENDIAN)
+# if defined(__arch64__)
+# define NIST_INT64 long
+# else
+# define NIST_INT64 long long
+# endif
+# endif
#else
#define bn_cp_64(to, n, from, m) \
{ \
@@ -330,13 +337,15 @@ static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top)
bn_32_set_0(to, (n)*2); \
bn_32_set_0(to, (n)*2+1); \
}
-#if BN_BITS2 == 32
#define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0;
#define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0;
-#endif
+# if defined(_WIN32) && !defined(__GNUC__)
+# define NIST_INT64 __int64
+# elif defined(BN_LLONG)
+# define NIST_INT64 long long
+# endif
#endif /* BN_BITS2 != 64 */
-
#define nist_set_192(to, from, a1, a2, a3) \
{ \
bn_cp_64(to, 0, from, (a3) - 3) \
@@ -350,9 +359,11 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
int top = a->top, i;
int carry;
register BN_ULONG *r_d, *a_d = a->d;
- BN_ULONG t_d[BN_NIST_192_TOP],
- buf[BN_NIST_192_TOP],
- c_d[BN_NIST_192_TOP],
+ union {
+ BN_ULONG bn[BN_NIST_192_TOP];
+ unsigned int ui[BN_NIST_192_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_192_TOP],
*res;
PTR_SIZE_INT mask;
static const BIGNUM _bignum_nist_p_192_sqr = {
@@ -385,15 +396,48 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
else
r_d = a_d;
- nist_cp_bn_0(buf, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, BN_NIST_192_TOP);
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, BN_NIST_192_TOP);
+
+#if defined(NIST_INT64)
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp=(unsigned int *)r_d;
+ const unsigned int *bp=(const unsigned int *)buf.ui;
+
+ acc = rp[0]; acc += bp[3*2-6];
+ acc += bp[5*2-6]; rp[0] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[1]; acc += bp[3*2-5];
+ acc += bp[5*2-5]; rp[1] = (unsigned int)acc; acc >>= 32;
- nist_set_192(t_d, buf, 0, 3, 3);
+ acc += rp[2]; acc += bp[3*2-6];
+ acc += bp[4*2-6];
+ acc += bp[5*2-6]; rp[2] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[3]; acc += bp[3*2-5];
+ acc += bp[4*2-5];
+ acc += bp[5*2-5]; rp[3] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[4]; acc += bp[4*2-6];
+ acc += bp[5*2-6]; rp[4] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[5]; acc += bp[4*2-5];
+ acc += bp[5*2-5]; rp[5] = (unsigned int)acc;
+
+ carry = (int)(acc>>32);
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_192_TOP];
+
+ nist_set_192(t_d, buf.bn, 0, 3, 3);
carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
- nist_set_192(t_d, buf, 4, 4, 0);
+ nist_set_192(t_d, buf.bn, 4, 4, 0);
carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
- nist_set_192(t_d, buf, 5, 5, 5)
+ nist_set_192(t_d, buf.bn, 5, 5, 5)
carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
-
+ }
+#endif
if (carry > 0)
carry = (int)bn_sub_words(r_d,r_d,_nist_p_192[carry-1],BN_NIST_192_TOP);
else
@@ -435,8 +479,7 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
int top = a->top, i;
int carry;
BN_ULONG *r_d, *a_d = a->d;
- BN_ULONG t_d[BN_NIST_224_TOP],
- buf[BN_NIST_224_TOP],
+ BN_ULONG buf[BN_NIST_224_TOP],
c_d[BN_NIST_224_TOP],
*res;
PTR_SIZE_INT mask;
@@ -474,14 +517,54 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
#if BN_BITS2==64
/* copy upper 256 bits of 448 bit number ... */
- nist_cp_bn_0(t_d, a_d + (BN_NIST_224_TOP-1), top - (BN_NIST_224_TOP-1), BN_NIST_224_TOP);
+ nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP-1), top - (BN_NIST_224_TOP-1), BN_NIST_224_TOP);
/* ... and right shift by 32 to obtain upper 224 bits */
- nist_set_224(buf, t_d, 14, 13, 12, 11, 10, 9, 8);
+ nist_set_224(buf, c_d, 14, 13, 12, 11, 10, 9, 8);
/* truncate lower part to 224 bits too */
r_d[BN_NIST_224_TOP-1] &= BN_MASK2l;
#else
nist_cp_bn_0(buf, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, BN_NIST_224_TOP);
#endif
+
+#if defined(NIST_INT64) && BN_BITS2!=64
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp=(unsigned int *)r_d;
+ const unsigned int *bp=(const unsigned int *)buf;
+
+ acc = rp[0]; acc -= bp[7-7];
+ acc -= bp[11-7]; rp[0] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[1]; acc -= bp[8-7];
+ acc -= bp[12-7]; rp[1] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[2]; acc -= bp[9-7];
+ acc -= bp[13-7]; rp[2] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[3]; acc += bp[7-7];
+ acc += bp[11-7];
+ acc -= bp[10-7]; rp[3] = (unsigned int)acc; acc>>= 32;
+
+ acc += rp[4]; acc += bp[8-7];
+ acc += bp[12-7];
+ acc -= bp[11-7]; rp[4] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[5]; acc += bp[9-7];
+ acc += bp[13-7];
+ acc -= bp[12-7]; rp[5] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[6]; acc += bp[10-7];
+ acc -= bp[13-7]; rp[6] = (unsigned int)acc;
+
+ carry = (int)(acc>>32);
+# if BN_BITS2==64
+ rp[7] = carry;
+# endif
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_224_TOP];
+
nist_set_224(t_d, buf, 10, 9, 8, 7, 0, 0, 0);
carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
nist_set_224(t_d, buf, 0, 13, 12, 11, 0, 0, 0);
@@ -494,6 +577,8 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
#if BN_BITS2==64
carry = (int)(r_d[BN_NIST_224_TOP-1]>>32);
#endif
+ }
+#endif
u.f = bn_sub_words;
if (carry > 0)
{
@@ -548,9 +633,11 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
int i, top = a->top;
int carry = 0;
register BN_ULONG *a_d = a->d, *r_d;
- BN_ULONG t_d[BN_NIST_256_TOP],
- buf[BN_NIST_256_TOP],
- c_d[BN_NIST_256_TOP],
+ union {
+ BN_ULONG bn[BN_NIST_256_TOP];
+ unsigned int ui[BN_NIST_256_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_256_TOP],
*res;
PTR_SIZE_INT mask;
union { bn_addsub_f f; PTR_SIZE_INT p; } u;
@@ -584,12 +671,87 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
else
r_d = a_d;
- nist_cp_bn_0(buf, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, BN_NIST_256_TOP);
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, BN_NIST_256_TOP);
+
+#if defined(NIST_INT64)
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp=(unsigned int *)r_d;
+ const unsigned int *bp=(const unsigned int *)buf.ui;
+
+ acc = rp[0]; acc += bp[8-8];
+ acc += bp[9-8];
+ acc -= bp[11-8];
+ acc -= bp[12-8];
+ acc -= bp[13-8];
+ acc -= bp[14-8]; rp[0] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[1]; acc += bp[9-8];
+ acc += bp[10-8];
+ acc -= bp[12-8];
+ acc -= bp[13-8];
+ acc -= bp[14-8];
+ acc -= bp[15-8]; rp[1] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[2]; acc += bp[10-8];
+ acc += bp[11-8];
+ acc -= bp[13-8];
+ acc -= bp[14-8];
+ acc -= bp[15-8]; rp[2] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[3]; acc += bp[11-8];
+ acc += bp[11-8];
+ acc += bp[12-8];
+ acc += bp[12-8];
+ acc += bp[13-8];
+ acc -= bp[15-8];
+ acc -= bp[8-8];
+ acc -= bp[9-8]; rp[3] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[4]; acc += bp[12-8];
+ acc += bp[12-8];
+ acc += bp[13-8];
+ acc += bp[13-8];
+ acc += bp[14-8];
+ acc -= bp[9-8];
+ acc -= bp[10-8]; rp[4] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[5]; acc += bp[13-8];
+ acc += bp[13-8];
+ acc += bp[14-8];
+ acc += bp[14-8];
+ acc += bp[15-8];
+ acc -= bp[10-8];
+ acc -= bp[11-8]; rp[5] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[6]; acc += bp[14-8];
+ acc += bp[14-8];
+ acc += bp[15-8];
+ acc += bp[15-8];
+ acc += bp[14-8];
+ acc += bp[13-8];
+ acc -= bp[8-8];
+ acc -= bp[9-8]; rp[6] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[7]; acc += bp[15-8];
+ acc += bp[15-8];
+ acc += bp[15-8];
+ acc += bp[8 -8];
+ acc -= bp[10-8];
+ acc -= bp[11-8];
+ acc -= bp[12-8];
+ acc -= bp[13-8]; rp[7] = (unsigned int)acc;
+
+ carry = (int)(acc>>32);
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_256_TOP];
/*S1*/
- nist_set_256(t_d, buf, 15, 14, 13, 12, 11, 0, 0, 0);
+ nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0);
/*S2*/
- nist_set_256(c_d, buf, 0, 15, 14, 13, 12, 0, 0, 0);
+ nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0);
carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
/* left shift */
{
@@ -607,24 +769,26 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
}
carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
/*S3*/
- nist_set_256(t_d, buf, 15, 14, 0, 0, 0, 10, 9, 8);
+ nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8);
carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
/*S4*/
- nist_set_256(t_d, buf, 8, 13, 15, 14, 13, 11, 10, 9);
+ nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9);
carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
/*D1*/
- nist_set_256(t_d, buf, 10, 8, 0, 0, 0, 13, 12, 11);
+ nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11);
carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
/*D2*/
- nist_set_256(t_d, buf, 11, 9, 0, 0, 15, 14, 13, 12);
+ nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12);
carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
/*D3*/
- nist_set_256(t_d, buf, 12, 0, 10, 9, 8, 15, 14, 13);
+ nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13);
carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
/*D4*/
- nist_set_256(t_d, buf, 13, 0, 11, 10, 9, 0, 15, 14);
+ nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14);
carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ }
+#endif
/* see BN_nist_mod_224 for explanation */
u.f = bn_sub_words;
if (carry > 0)
@@ -672,9 +836,11 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
int i, top = a->top;
int carry = 0;
register BN_ULONG *r_d, *a_d = a->d;
- BN_ULONG t_d[BN_NIST_384_TOP],
- buf[BN_NIST_384_TOP],
- c_d[BN_NIST_384_TOP],
+ union {
+ BN_ULONG bn[BN_NIST_384_TOP];
+ unsigned int ui[BN_NIST_384_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_384_TOP],
*res;
PTR_SIZE_INT mask;
union { bn_addsub_f f; PTR_SIZE_INT p; } u;
@@ -709,10 +875,100 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
else
r_d = a_d;
- nist_cp_bn_0(buf, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, BN_NIST_384_TOP);
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, BN_NIST_384_TOP);
+
+#if defined(NIST_INT64)
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp=(unsigned int *)r_d;
+ const unsigned int *bp=(const unsigned int *)buf.ui;
+
+ acc = rp[0]; acc += bp[12-12];
+ acc += bp[21-12];
+ acc += bp[20-12];
+ acc -= bp[23-12]; rp[0] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[1]; acc += bp[13-12];
+ acc += bp[22-12];
+ acc += bp[23-12];
+ acc -= bp[12-12];
+ acc -= bp[20-12]; rp[1] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[2]; acc += bp[14-12];
+ acc += bp[23-12];
+ acc -= bp[13-12];
+ acc -= bp[21-12]; rp[2] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[3]; acc += bp[15-12];
+ acc += bp[12-12];
+ acc += bp[20-12];
+ acc += bp[21-12];
+ acc -= bp[14-12];
+ acc -= bp[22-12];
+ acc -= bp[23-12]; rp[3] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[4]; acc += bp[21-12];
+ acc += bp[21-12];
+ acc += bp[16-12];
+ acc += bp[13-12];
+ acc += bp[12-12];
+ acc += bp[20-12];
+ acc += bp[22-12];
+ acc -= bp[15-12];
+ acc -= bp[23-12];
+ acc -= bp[23-12]; rp[4] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[5]; acc += bp[22-12];
+ acc += bp[22-12];
+ acc += bp[17-12];
+ acc += bp[14-12];
+ acc += bp[13-12];
+ acc += bp[21-12];
+ acc += bp[23-12];
+ acc -= bp[16-12]; rp[5] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[6]; acc += bp[23-12];
+ acc += bp[23-12];
+ acc += bp[18-12];
+ acc += bp[15-12];
+ acc += bp[14-12];
+ acc += bp[22-12];
+ acc -= bp[17-12]; rp[6] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[7]; acc += bp[19-12];
+ acc += bp[16-12];
+ acc += bp[15-12];
+ acc += bp[23-12];
+ acc -= bp[18-12]; rp[7] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[8]; acc += bp[20-12];
+ acc += bp[17-12];
+ acc += bp[16-12];
+ acc -= bp[19-12]; rp[8] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[9]; acc += bp[21-12];
+ acc += bp[18-12];
+ acc += bp[17-12];
+ acc -= bp[20-12]; rp[9] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[10]; acc += bp[22-12];
+ acc += bp[19-12];
+ acc += bp[18-12];
+ acc -= bp[21-12]; rp[10] = (unsigned int)acc; acc >>= 32;
+
+ acc += rp[11]; acc += bp[23-12];
+ acc += bp[20-12];
+ acc += bp[19-12];
+ acc -= bp[22-12]; rp[11] = (unsigned int)acc;
+
+ carry = (int)(acc>>32);
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_384_TOP];
/*S1*/
- nist_set_256(t_d, buf, 0, 0, 0, 0, 0, 23-4, 22-4, 21-4);
+ nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23-4, 22-4, 21-4);
/* left shift */
{
register BN_ULONG *ap,t,c;
@@ -729,29 +985,31 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
carry = (int)bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2),
t_d, BN_NIST_256_TOP);
/*S2 */
- carry += (int)bn_add_words(r_d, r_d, buf, BN_NIST_384_TOP);
+ carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP);
/*S3*/
- nist_set_384(t_d,buf,20,19,18,17,16,15,14,13,12,23,22,21);
+ nist_set_384(t_d,buf.bn,20,19,18,17,16,15,14,13,12,23,22,21);
carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
/*S4*/
- nist_set_384(t_d,buf,19,18,17,16,15,14,13,12,20,0,23,0);
+ nist_set_384(t_d,buf.bn,19,18,17,16,15,14,13,12,20,0,23,0);
carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
/*S5*/
- nist_set_384(t_d, buf,0,0,0,0,23,22,21,20,0,0,0,0);
+ nist_set_384(t_d, buf.bn,0,0,0,0,23,22,21,20,0,0,0,0);
carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
/*S6*/
- nist_set_384(t_d,buf,0,0,0,0,0,0,23,22,21,0,0,20);
+ nist_set_384(t_d,buf.bn,0,0,0,0,0,0,23,22,21,0,0,20);
carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
/*D1*/
- nist_set_384(t_d,buf,22,21,20,19,18,17,16,15,14,13,12,23);
+ nist_set_384(t_d,buf.bn,22,21,20,19,18,17,16,15,14,13,12,23);
carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
/*D2*/
- nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,22,21,20,0);
+ nist_set_384(t_d,buf.bn,0,0,0,0,0,0,0,23,22,21,20,0);
carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
/*D3*/
- nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,23,0,0,0);
+ nist_set_384(t_d,buf.bn,0,0,0,0,0,0,0,23,23,0,0,0);
carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ }
+#endif
/* see BN_nist_mod_224 for explanation */
u.f = bn_sub_words;
if (carry > 0)
diff --git a/deps/openssl/openssl/crypto/bn/bn_print.c b/deps/openssl/openssl/crypto/bn/bn_print.c
index bebb466d0..1743b6a7e 100644
--- a/deps/openssl/openssl/crypto/bn/bn_print.c
+++ b/deps/openssl/openssl/crypto/bn/bn_print.c
@@ -357,3 +357,22 @@ end:
return(ret);
}
#endif
+
+char *BN_options(void)
+ {
+ static int init=0;
+ static char data[16];
+
+ if (!init)
+ {
+ init++;
+#ifdef BN_LLONG
+ BIO_snprintf(data,sizeof data,"bn(%d,%d)",
+ (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
+#else
+ BIO_snprintf(data,sizeof data,"bn(%d,%d)",
+ (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
+#endif
+ }
+ return(data);
+ }
diff --git a/deps/openssl/openssl/crypto/bn/bn_shift.c b/deps/openssl/openssl/crypto/bn/bn_shift.c
index c4d301afc..a6fca2c42 100644
--- a/deps/openssl/openssl/crypto/bn/bn_shift.c
+++ b/deps/openssl/openssl/crypto/bn/bn_shift.c
@@ -99,7 +99,7 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a)
int BN_rshift1(BIGNUM *r, const BIGNUM *a)
{
BN_ULONG *ap,*rp,t,c;
- int i;
+ int i,j;
bn_check_top(r);
bn_check_top(a);
@@ -109,22 +109,25 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a)
BN_zero(r);
return(1);
}
+ i = a->top;
+ ap= a->d;
+ j = i-(ap[i-1]==1);
if (a != r)
{
- if (bn_wexpand(r,a->top) == NULL) return(0);
- r->top=a->top;
+ if (bn_wexpand(r,j) == NULL) return(0);
r->neg=a->neg;
}
- ap=a->d;
rp=r->d;
- c=0;
- for (i=a->top-1; i>=0; i--)
+ t=ap[--i];
+ c=(t&1)?BN_TBIT:0;
+ if (t>>=1) rp[i]=t;
+ while (i>0)
{
- t=ap[i];
+ t=ap[--i];
rp[i]=((t>>1)&BN_MASK2)|c;
c=(t&1)?BN_TBIT:0;
}
- bn_correct_top(r);
+ r->top=j;
bn_check_top(r);
return(1);
}
@@ -182,10 +185,11 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
BN_zero(r);
return(1);
}
+ i = (BN_num_bits(a)-n+(BN_BITS2-1))/BN_BITS2;
if (r != a)
{
r->neg=a->neg;
- if (bn_wexpand(r,a->top-nw+1) == NULL) return(0);
+ if (bn_wexpand(r,i) == NULL) return(0);
}
else
{
@@ -196,7 +200,7 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
f= &(a->d[nw]);
t=r->d;
j=a->top-nw;
- r->top=j;
+ r->top=i;
if (rb == 0)
{
@@ -212,9 +216,8 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
l= *(f++);
*(t++) =(tmp|(l<<lb))&BN_MASK2;
}
- *(t++) =(l>>rb)&BN_MASK2;
+ if ((l = (l>>rb)&BN_MASK2)) *(t) = l;
}
- bn_correct_top(r);
bn_check_top(r);
return(1);
}
diff --git a/deps/openssl/openssl/crypto/bn/bn_word.c b/deps/openssl/openssl/crypto/bn/bn_word.c
index ee7b87c45..de83a15b9 100644
--- a/deps/openssl/openssl/crypto/bn/bn_word.c
+++ b/deps/openssl/openssl/crypto/bn/bn_word.c
@@ -144,26 +144,17 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
a->neg=!(a->neg);
return(i);
}
- /* Only expand (and risk failing) if it's possibly necessary */
- if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) &&
- (bn_wexpand(a,a->top+1) == NULL))
- return(0);
- i=0;
- for (;;)
+ for (i=0;w!=0 && i<a->top;i++)
{
- if (i >= a->top)
- l=w;
- else
- l=(a->d[i]+w)&BN_MASK2;
- a->d[i]=l;
- if (w > l)
- w=1;
- else
- break;
- i++;
+ a->d[i] = l = (a->d[i]+w)&BN_MASK2;
+ w = (w>l)?1:0;
}
- if (i >= a->top)
+ if (w && i==a->top)
+ {
+ if (bn_wexpand(a,a->top+1) == NULL) return 0;
a->top++;
+ a->d[i]=w;
+ }
bn_check_top(a);
return(1);
}
diff --git a/deps/openssl/openssl/crypto/bn/bn_x931p.c b/deps/openssl/openssl/crypto/bn/bn_x931p.c
new file mode 100644
index 000000000..04c5c874e
--- /dev/null
+++ b/deps/openssl/openssl/crypto/bn/bn_x931p.c
@@ -0,0 +1,272 @@
+/* bn_x931p.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 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
+ * licensing@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).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+
+/* X9.31 routines for prime derivation */
+
+/* X9.31 prime derivation. This is used to generate the primes pi
+ * (p1, p2, q1, q2) from a parameter Xpi by checking successive odd
+ * integers.
+ */
+
+static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx,
+ BN_GENCB *cb)
+ {
+ int i = 0;
+ if (!BN_copy(pi, Xpi))
+ return 0;
+ if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
+ return 0;
+ for(;;)
+ {
+ i++;
+ BN_GENCB_call(cb, 0, i);
+ /* NB 27 MR is specificed in X9.31 */
+ if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb))
+ break;
+ if (!BN_add_word(pi, 2))
+ return 0;
+ }
+ BN_GENCB_call(cb, 2, i);
+ return 1;
+ }
+
+/* This is the main X9.31 prime derivation function. From parameters
+ * Xp1, Xp2 and Xp derive the prime p. If the parameters p1 or p2 are
+ * not NULL they will be returned too: this is needed for testing.
+ */
+
+int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
+ const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
+ {
+ int ret = 0;
+
+ BIGNUM *t, *p1p2, *pm1;
+
+ /* Only even e supported */
+ if (!BN_is_odd(e))
+ return 0;
+
+ BN_CTX_start(ctx);
+ if (!p1)
+ p1 = BN_CTX_get(ctx);
+
+ if (!p2)
+ p2 = BN_CTX_get(ctx);
+
+ t = BN_CTX_get(ctx);
+
+ p1p2 = BN_CTX_get(ctx);
+
+ pm1 = BN_CTX_get(ctx);
+
+ if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
+ goto err;
+
+ if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
+ goto err;
+
+ if (!BN_mul(p1p2, p1, p2, ctx))
+ goto err;
+
+ /* First set p to value of Rp */
+
+ if (!BN_mod_inverse(p, p2, p1, ctx))
+ goto err;
+
+ if (!BN_mul(p, p, p2, ctx))
+ goto err;
+
+ if (!BN_mod_inverse(t, p1, p2, ctx))
+ goto err;
+
+ if (!BN_mul(t, t, p1, ctx))
+ goto err;
+
+ if (!BN_sub(p, p, t))
+ goto err;
+
+ if (p->neg && !BN_add(p, p, p1p2))
+ goto err;
+
+ /* p now equals Rp */
+
+ if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
+ goto err;
+
+ if (!BN_add(p, p, Xp))
+ goto err;
+
+ /* p now equals Yp0 */
+
+ for (;;)
+ {
+ int i = 1;
+ BN_GENCB_call(cb, 0, i++);
+ if (!BN_copy(pm1, p))
+ goto err;
+ if (!BN_sub_word(pm1, 1))
+ goto err;
+ if (!BN_gcd(t, pm1, e, ctx))
+ goto err;
+ if (BN_is_one(t)
+ /* X9.31 specifies 8 MR and 1 Lucas test or any prime test
+ * offering similar or better guarantees 50 MR is considerably
+ * better.
+ */
+ && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb))
+ break;
+ if (!BN_add(p, p, p1p2))
+ goto err;
+ }
+
+ BN_GENCB_call(cb, 3, 0);
+
+ ret = 1;
+
+ err:
+
+ BN_CTX_end(ctx);
+
+ return ret;
+ }
+
+/* Generate pair of paramters Xp, Xq for X9.31 prime generation.
+ * Note: nbits paramter is sum of number of bits in both.
+ */
+
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
+ {
+ BIGNUM *t;
+ int i;
+ /* Number of bits for each prime is of the form
+ * 512+128s for s = 0, 1, ...
+ */
+ if ((nbits < 1024) || (nbits & 0xff))
+ return 0;
+ nbits >>= 1;
+ /* The random value Xp must be between sqrt(2) * 2^(nbits-1) and
+ * 2^nbits - 1. By setting the top two bits we ensure that the lower
+ * bound is exceeded.
+ */
+ if (!BN_rand(Xp, nbits, 1, 0))
+ return 0;
+
+ BN_CTX_start(ctx);
+ t = BN_CTX_get(ctx);
+
+ for (i = 0; i < 1000; i++)
+ {
+ if (!BN_rand(Xq, nbits, 1, 0))
+ return 0;
+ /* Check that |Xp - Xq| > 2^(nbits - 100) */
+ BN_sub(t, Xp, Xq);
+ if (BN_num_bits(t) > (nbits - 100))
+ break;
+ }
+
+ BN_CTX_end(ctx);
+
+ if (i < 1000)
+ return 1;
+
+ return 0;
+
+ }
+
+/* Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1
+ * and Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL
+ * the relevant parameter will be stored in it.
+ *
+ * Due to the fact that |Xp - Xq| > 2^(nbits - 100) must be satisfied Xp and Xq
+ * are generated using the previous function and supplied as input.
+ */
+
+int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ BIGNUM *Xp1, BIGNUM *Xp2,
+ const BIGNUM *Xp,
+ const BIGNUM *e, BN_CTX *ctx,
+ BN_GENCB *cb)
+ {
+ int ret = 0;
+
+ BN_CTX_start(ctx);
+ if (!Xp1)
+ Xp1 = BN_CTX_get(ctx);
+ if (!Xp2)
+ Xp2 = BN_CTX_get(ctx);
+
+ if (!BN_rand(Xp1, 101, 0, 0))
+ goto error;
+ if (!BN_rand(Xp2, 101, 0, 0))
+ goto error;
+ if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb))
+ goto error;
+
+ ret = 1;
+
+ error:
+ BN_CTX_end(ctx);
+
+ return ret;
+
+ }
+
diff --git a/deps/openssl/openssl/crypto/bn/bntest.c b/deps/openssl/openssl/crypto/bn/bntest.c
index 0cd99c5b4..06f5954ac 100644
--- a/deps/openssl/openssl/crypto/bn/bntest.c
+++ b/deps/openssl/openssl/crypto/bn/bntest.c
@@ -262,7 +262,7 @@ int main(int argc, char *argv[])
message(out,"BN_mod_sqrt");
if (!test_sqrt(out,ctx)) goto err;
(void)BIO_flush(out);
-
+#ifndef OPENSSL_NO_EC2M
message(out,"BN_GF2m_add");
if (!test_gf2m_add(out)) goto err;
(void)BIO_flush(out);
@@ -298,7 +298,7 @@ int main(int argc, char *argv[])
message(out,"BN_GF2m_mod_solve_quad");
if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
(void)BIO_flush(out);
-
+#endif
BN_CTX_free(ctx);
BIO_free(out);
@@ -1061,7 +1061,7 @@ int test_exp(BIO *bp, BN_CTX *ctx)
BN_free(one);
return(1);
}
-
+#ifndef OPENSSL_NO_EC2M
int test_gf2m_add(BIO *bp)
{
BIGNUM a,b,c;
@@ -1636,7 +1636,7 @@ int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
BN_free(e);
return ret;
}
-
+#endif
static int genprime_cb(int p, int n, BN_GENCB *arg)
{
char c='*';
diff --git a/deps/openssl/openssl/crypto/buffer/Makefile b/deps/openssl/openssl/crypto/buffer/Makefile
index 9f3a88d2d..2efba47f0 100644
--- a/deps/openssl/openssl/crypto/buffer/Makefile
+++ b/deps/openssl/openssl/crypto/buffer/Makefile
@@ -17,8 +17,8 @@ TEST=
APPS=
LIB=$(TOP)/libcrypto.a
-LIBSRC= buffer.c buf_err.c
-LIBOBJ= buffer.o buf_err.o
+LIBSRC= buffer.c buf_str.c buf_err.c
+LIBOBJ= buffer.o buf_str.o buf_err.o
SRC= $(LIBSRC)
@@ -81,6 +81,13 @@ buf_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
buf_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
buf_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
buf_err.o: buf_err.c
+buf_str.o: ../../e_os.h ../../include/openssl/bio.h
+buf_str.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+buf_str.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+buf_str.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+buf_str.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+buf_str.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+buf_str.o: ../../include/openssl/symhacks.h ../cryptlib.h buf_str.c
buffer.o: ../../e_os.h ../../include/openssl/bio.h
buffer.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
buffer.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
diff --git a/deps/openssl/openssl/crypto/buffer/buf_str.c b/deps/openssl/openssl/crypto/buffer/buf_str.c
new file mode 100644
index 000000000..151f5ea97
--- /dev/null
+++ b/deps/openssl/openssl/crypto/buffer/buf_str.c
@@ -0,0 +1,119 @@
+/* crypto/buffer/buffer.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+
+char *BUF_strdup(const char *str)
+ {
+ if (str == NULL) return(NULL);
+ return BUF_strndup(str, strlen(str));
+ }
+
+char *BUF_strndup(const char *str, size_t siz)
+ {
+ char *ret;
+
+ if (str == NULL) return(NULL);
+
+ ret=OPENSSL_malloc(siz+1);
+ if (ret == NULL)
+ {
+ BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+ BUF_strlcpy(ret,str,siz+1);
+ return(ret);
+ }
+
+void *BUF_memdup(const void *data, size_t siz)
+ {
+ void *ret;
+
+ if (data == NULL) return(NULL);
+
+ ret=OPENSSL_malloc(siz);
+ if (ret == NULL)
+ {
+ BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+ return memcpy(ret, data, siz);
+ }
+
+size_t BUF_strlcpy(char *dst, const char *src, size_t size)
+ {
+ size_t l = 0;
+ for(; size > 1 && *src; size--)
+ {
+ *dst++ = *src++;
+ l++;
+ }
+ if (size)
+ *dst = '\0';
+ return l + strlen(src);
+ }
+
+size_t BUF_strlcat(char *dst, const char *src, size_t size)
+ {
+ size_t l = 0;
+ for(; size > 0 && *dst; size--, dst++)
+ l++;
+ return l + BUF_strlcpy(dst, src, size);
+ }
diff --git a/deps/openssl/openssl/crypto/buffer/buffer.c b/deps/openssl/openssl/crypto/buffer/buffer.c
index 40361f966..d7aa79ad7 100644
--- a/deps/openssl/openssl/crypto/buffer/buffer.c
+++ b/deps/openssl/openssl/crypto/buffer/buffer.c
@@ -179,64 +179,6 @@ int BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
return(len);
}
-char *BUF_strdup(const char *str)
- {
- if (str == NULL) return(NULL);
- return BUF_strndup(str, strlen(str));
- }
-
-char *BUF_strndup(const char *str, size_t siz)
- {
- char *ret;
-
- if (str == NULL) return(NULL);
-
- ret=OPENSSL_malloc(siz+1);
- if (ret == NULL)
- {
- BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE);
- return(NULL);
- }
- BUF_strlcpy(ret,str,siz+1);
- return(ret);
- }
-
-void *BUF_memdup(const void *data, size_t siz)
- {
- void *ret;
-
- if (data == NULL) return(NULL);
-
- ret=OPENSSL_malloc(siz);
- if (ret == NULL)
- {
- BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE);
- return(NULL);
- }
- return memcpy(ret, data, siz);
- }
-
-size_t BUF_strlcpy(char *dst, const char *src, size_t size)
- {
- size_t l = 0;
- for(; size > 1 && *src; size--)
- {
- *dst++ = *src++;
- l++;
- }
- if (size)
- *dst = '\0';
- return l + strlen(src);
- }
-
-size_t BUF_strlcat(char *dst, const char *src, size_t size)
- {
- size_t l = 0;
- for(; size > 0 && *dst; size--, dst++)
- l++;
- return l + BUF_strlcpy(dst, src, size);
- }
-
void BUF_reverse(unsigned char *out, unsigned char *in, size_t size)
{
size_t i;
diff --git a/deps/openssl/openssl/crypto/camellia/Makefile b/deps/openssl/openssl/crypto/camellia/Makefile
index ff5fe4a01..6ce6fc99c 100644
--- a/deps/openssl/openssl/crypto/camellia/Makefile
+++ b/deps/openssl/openssl/crypto/camellia/Makefile
@@ -23,9 +23,9 @@ APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC=camellia.c cmll_misc.c cmll_ecb.c cmll_cbc.c cmll_ofb.c \
- cmll_cfb.c cmll_ctr.c
+ cmll_cfb.c cmll_ctr.c cmll_utl.c
-LIBOBJ= cmll_ecb.o cmll_ofb.o cmll_cfb.o cmll_ctr.o $(CMLL_ENC)
+LIBOBJ= cmll_ecb.o cmll_ofb.o cmll_cfb.o cmll_ctr.o cmll_utl.o $(CMLL_ENC)
SRC= $(LIBSRC)
@@ -96,8 +96,15 @@ cmll_ctr.o: ../../include/openssl/camellia.h ../../include/openssl/modes.h
cmll_ctr.o: ../../include/openssl/opensslconf.h cmll_ctr.c
cmll_ecb.o: ../../include/openssl/camellia.h
cmll_ecb.o: ../../include/openssl/opensslconf.h cmll_ecb.c cmll_locl.h
-cmll_misc.o: ../../include/openssl/camellia.h
-cmll_misc.o: ../../include/openssl/opensslconf.h
-cmll_misc.o: ../../include/openssl/opensslv.h cmll_locl.h cmll_misc.c
+cmll_misc.o: ../../include/openssl/camellia.h ../../include/openssl/crypto.h
+cmll_misc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+cmll_misc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cmll_misc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+cmll_misc.o: ../../include/openssl/symhacks.h cmll_locl.h cmll_misc.c
cmll_ofb.o: ../../include/openssl/camellia.h ../../include/openssl/modes.h
cmll_ofb.o: ../../include/openssl/opensslconf.h cmll_ofb.c
+cmll_utl.o: ../../include/openssl/camellia.h ../../include/openssl/crypto.h
+cmll_utl.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+cmll_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cmll_utl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+cmll_utl.o: ../../include/openssl/symhacks.h cmll_locl.h cmll_utl.c
diff --git a/deps/openssl/openssl/crypto/camellia/asm/cmll-x86.pl b/deps/openssl/openssl/crypto/camellia/asm/cmll-x86.pl
index 027302ac8..c314d6231 100644
--- a/deps/openssl/openssl/crypto/camellia/asm/cmll-x86.pl
+++ b/deps/openssl/openssl/crypto/camellia/asm/cmll-x86.pl
@@ -723,11 +723,11 @@ my $bias=int(@T[0])?shift(@T):0;
&function_end("Camellia_Ekeygen");
if ($OPENSSL) {
-# int Camellia_set_key (
+# int private_Camellia_set_key (
# const unsigned char *userKey,
# int bits,
# CAMELLIA_KEY *key)
-&function_begin_B("Camellia_set_key");
+&function_begin_B("private_Camellia_set_key");
&push ("ebx");
&mov ("ecx",&wparam(0)); # pull arguments
&mov ("ebx",&wparam(1));
@@ -760,7 +760,7 @@ if ($OPENSSL) {
&set_label("done",4);
&pop ("ebx");
&ret ();
-&function_end_B("Camellia_set_key");
+&function_end_B("private_Camellia_set_key");
}
@SBOX=(
diff --git a/deps/openssl/openssl/crypto/camellia/asm/cmll-x86_64.pl b/deps/openssl/openssl/crypto/camellia/asm/cmll-x86_64.pl
index 76955e472..9f4b82fa4 100644
--- a/deps/openssl/openssl/crypto/camellia/asm/cmll-x86_64.pl
+++ b/deps/openssl/openssl/crypto/camellia/asm/cmll-x86_64.pl
@@ -40,7 +40,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; }
sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
diff --git a/deps/openssl/openssl/crypto/camellia/camellia.h b/deps/openssl/openssl/crypto/camellia/camellia.h
index cf0457dd9..67911e0ad 100644
--- a/deps/openssl/openssl/crypto/camellia/camellia.h
+++ b/deps/openssl/openssl/crypto/camellia/camellia.h
@@ -88,6 +88,10 @@ struct camellia_key_st
};
typedef struct camellia_key_st CAMELLIA_KEY;
+#ifdef OPENSSL_FIPS
+int private_Camellia_set_key(const unsigned char *userKey, const int bits,
+ CAMELLIA_KEY *key);
+#endif
int Camellia_set_key(const unsigned char *userKey, const int bits,
CAMELLIA_KEY *key);
diff --git a/deps/openssl/openssl/crypto/camellia/cmll_locl.h b/deps/openssl/openssl/crypto/camellia/cmll_locl.h
index 4a4d880d1..246b6ce1d 100644
--- a/deps/openssl/openssl/crypto/camellia/cmll_locl.h
+++ b/deps/openssl/openssl/crypto/camellia/cmll_locl.h
@@ -71,7 +71,8 @@
typedef unsigned int u32;
typedef unsigned char u8;
-int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE keyTable);
+int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey,
+ KEY_TABLE_TYPE keyTable);
void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[],
const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[],
@@ -80,4 +81,6 @@ void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[],
const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[],
const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
+int private_Camellia_set_key(const unsigned char *userKey, const int bits,
+ CAMELLIA_KEY *key);
#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */
diff --git a/deps/openssl/openssl/crypto/camellia/cmll_misc.c b/deps/openssl/openssl/crypto/camellia/cmll_misc.c
index f44689124..f44d48564 100644
--- a/deps/openssl/openssl/crypto/camellia/cmll_misc.c
+++ b/deps/openssl/openssl/crypto/camellia/cmll_misc.c
@@ -50,12 +50,13 @@
*/
#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
#include <openssl/camellia.h>
#include "cmll_locl.h"
const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT;
-int Camellia_set_key(const unsigned char *userKey, const int bits,
+int private_Camellia_set_key(const unsigned char *userKey, const int bits,
CAMELLIA_KEY *key)
{
if(!userKey || !key)
diff --git a/deps/openssl/openssl/crypto/camellia/cmll_utl.c b/deps/openssl/openssl/crypto/camellia/cmll_utl.c
new file mode 100644
index 000000000..7a35711ec
--- /dev/null
+++ b/deps/openssl/openssl/crypto/camellia/cmll_utl.c
@@ -0,0 +1,64 @@
+/* crypto/camellia/cmll_utl.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 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.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include <openssl/camellia.h>
+#include "cmll_locl.h"
+
+int Camellia_set_key(const unsigned char *userKey, const int bits,
+ CAMELLIA_KEY *key)
+ {
+#ifdef OPENSSL_FIPS
+ fips_cipher_abort(Camellia);
+#endif
+ return private_Camellia_set_key(userKey, bits, key);
+ }
diff --git a/deps/openssl/openssl/crypto/cast/Makefile b/deps/openssl/openssl/crypto/cast/Makefile
index 0acc38f28..f3f485988 100644
--- a/deps/openssl/openssl/crypto/cast/Makefile
+++ b/deps/openssl/openssl/crypto/cast/Makefile
@@ -95,5 +95,8 @@ c_ofb64.o: ../../e_os.h ../../include/openssl/cast.h
c_ofb64.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
c_ofb64.o: c_ofb64.c cast_lcl.h
c_skey.o: ../../e_os.h ../../include/openssl/cast.h
-c_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+c_skey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+c_skey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+c_skey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+c_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
c_skey.o: c_skey.c cast_lcl.h cast_s.h
diff --git a/deps/openssl/openssl/crypto/cast/c_skey.c b/deps/openssl/openssl/crypto/cast/c_skey.c
index 76e40005c..cb6bf9fee 100644
--- a/deps/openssl/openssl/crypto/cast/c_skey.c
+++ b/deps/openssl/openssl/crypto/cast/c_skey.c
@@ -56,6 +56,7 @@
* [including the GNU Public Licence.]
*/
+#include <openssl/crypto.h>
#include <openssl/cast.h>
#include "cast_lcl.h"
#include "cast_s.h"
@@ -71,8 +72,14 @@
#define S5 CAST_S_table5
#define S6 CAST_S_table6
#define S7 CAST_S_table7
-
void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data)
+#ifdef OPENSSL_FIPS
+ {
+ fips_cipher_abort(CAST);
+ private_CAST_set_key(key, len, data);
+ }
+void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data)
+#endif
{
CAST_LONG x[16];
CAST_LONG z[16];
diff --git a/deps/openssl/openssl/crypto/cast/cast.h b/deps/openssl/openssl/crypto/cast/cast.h
index 1a264f814..203922ea2 100644
--- a/deps/openssl/openssl/crypto/cast/cast.h
+++ b/deps/openssl/openssl/crypto/cast/cast.h
@@ -83,7 +83,9 @@ typedef struct cast_key_st
int short_key; /* Use reduced rounds for short key */
} CAST_KEY;
-
+#ifdef OPENSSL_FIPS
+void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
+#endif
void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAST_KEY *key,
int enc);
diff --git a/deps/openssl/openssl/crypto/cmac/Makefile b/deps/openssl/openssl/crypto/cmac/Makefile
new file mode 100644
index 000000000..54e7cc39d
--- /dev/null
+++ b/deps/openssl/openssl/crypto/cmac/Makefile
@@ -0,0 +1,111 @@
+#
+# OpenSSL/crypto/cmac/Makefile
+#
+
+DIR= cmac
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE= Makefile
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=cmac.c cm_ameth.c cm_pmeth.c
+LIBOBJ=cmac.o cm_ameth.o cm_pmeth.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= cmac.h
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ $(AR) $(LIB) $(LIBOBJ)
+ $(RANLIB) $(LIB) || echo Never mind.
+ @touch lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+ @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+ @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done;
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+cm_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
+cm_ameth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+cm_ameth.o: ../../include/openssl/cmac.h ../../include/openssl/crypto.h
+cm_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+cm_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+cm_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+cm_ameth.o: ../../include/openssl/opensslconf.h
+cm_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cm_ameth.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+cm_ameth.o: ../../include/openssl/symhacks.h ../asn1/asn1_locl.h ../cryptlib.h
+cm_ameth.o: cm_ameth.c
+cm_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
+cm_pmeth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+cm_pmeth.o: ../../include/openssl/cmac.h ../../include/openssl/conf.h
+cm_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cm_pmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+cm_pmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+cm_pmeth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+cm_pmeth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+cm_pmeth.o: ../../include/openssl/opensslconf.h
+cm_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cm_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+cm_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+cm_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+cm_pmeth.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+cm_pmeth.o: ../cryptlib.h ../evp/evp_locl.h cm_pmeth.c
+cmac.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+cmac.o: ../../include/openssl/buffer.h ../../include/openssl/cmac.h
+cmac.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cmac.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+cmac.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+cmac.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+cmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+cmac.o: ../../include/openssl/symhacks.h ../cryptlib.h cmac.c
diff --git a/deps/openssl/openssl/crypto/cmac/cm_ameth.c b/deps/openssl/openssl/crypto/cmac/cm_ameth.c
new file mode 100644
index 000000000..0b8e5670b
--- /dev/null
+++ b/deps/openssl/openssl/crypto/cmac/cm_ameth.c
@@ -0,0 +1,97 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2010.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 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
+ * licensing@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.
+ * ====================================================================
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/cmac.h>
+#include "asn1_locl.h"
+
+/* CMAC "ASN1" method. This is just here to indicate the
+ * maximum CMAC output length and to free up a CMAC
+ * key.
+ */
+
+static int cmac_size(const EVP_PKEY *pkey)
+ {
+ return EVP_MAX_BLOCK_LENGTH;
+ }
+
+static void cmac_key_free(EVP_PKEY *pkey)
+ {
+ CMAC_CTX *cmctx = (CMAC_CTX *)pkey->pkey.ptr;
+ if (cmctx)
+ CMAC_CTX_free(cmctx);
+ }
+
+const EVP_PKEY_ASN1_METHOD cmac_asn1_meth =
+ {
+ EVP_PKEY_CMAC,
+ EVP_PKEY_CMAC,
+ 0,
+
+ "CMAC",
+ "OpenSSL CMAC method",
+
+ 0,0,0,0,
+
+ 0,0,0,
+
+ cmac_size,
+ 0,
+ 0,0,0,0,0,0,0,
+
+ cmac_key_free,
+ 0,
+ 0,0
+ };
+
diff --git a/deps/openssl/openssl/crypto/cmac/cm_pmeth.c b/deps/openssl/openssl/crypto/cmac/cm_pmeth.c
new file mode 100644
index 000000000..072228ec7
--- /dev/null
+++ b/deps/openssl/openssl/crypto/cmac/cm_pmeth.c
@@ -0,0 +1,224 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2010.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 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
+ * licensing@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.
+ * ====================================================================
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/evp.h>
+#include <openssl/cmac.h>
+#include "evp_locl.h"
+
+/* The context structure and "key" is simply a CMAC_CTX */
+
+static int pkey_cmac_init(EVP_PKEY_CTX *ctx)
+ {
+ ctx->data = CMAC_CTX_new();
+ if (!ctx->data)
+ return 0;
+ ctx->keygen_info_count = 0;
+ return 1;
+ }
+
+static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+ {
+ if (!pkey_cmac_init(dst))
+ return 0;
+ if (!CMAC_CTX_copy(dst->data, src->data))
+ return 0;
+ return 1;
+ }
+
+static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx)
+ {
+ CMAC_CTX_free(ctx->data);
+ }
+
+static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+ {
+ CMAC_CTX *cmkey = CMAC_CTX_new();
+ CMAC_CTX *cmctx = ctx->data;
+ if (!cmkey)
+ return 0;
+ if (!CMAC_CTX_copy(cmkey, cmctx))
+ {
+ CMAC_CTX_free(cmkey);
+ return 0;
+ }
+ EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey);
+
+ return 1;
+ }
+
+static int int_update(EVP_MD_CTX *ctx,const void *data,size_t count)
+ {
+ if (!CMAC_Update(ctx->pctx->data, data, count))
+ return 0;
+ return 1;
+ }
+
+static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+ {
+ EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
+ mctx->update = int_update;
+ return 1;
+ }
+
+static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ EVP_MD_CTX *mctx)
+ {
+ return CMAC_Final(ctx->data, sig, siglen);
+ }
+
+static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+ {
+ CMAC_CTX *cmctx = ctx->data;
+ switch (type)
+ {
+
+ case EVP_PKEY_CTRL_SET_MAC_KEY:
+ if (!p2 || p1 < 0)
+ return 0;
+ if (!CMAC_Init(cmctx, p2, p1, NULL, NULL))
+ return 0;
+ break;
+
+ case EVP_PKEY_CTRL_CIPHER:
+ if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine))
+ return 0;
+ break;
+
+ case EVP_PKEY_CTRL_MD:
+ if (ctx->pkey && !CMAC_CTX_copy(ctx->data,
+ (CMAC_CTX *)ctx->pkey->pkey.ptr))
+ return 0;
+ if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL))
+ return 0;
+ break;
+
+ default:
+ return -2;
+
+ }
+ return 1;
+ }
+
+static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx,
+ const char *type, const char *value)
+ {
+ if (!value)
+ {
+ return 0;
+ }
+ if (!strcmp(type, "key"))
+ {
+ void *p = (void *)value;
+ return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
+ strlen(p), p);
+ }
+ if (!strcmp(type, "cipher"))
+ {
+ const EVP_CIPHER *c;
+ c = EVP_get_cipherbyname(value);
+ if (!c)
+ return 0;
+ return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c);
+ }
+ if (!strcmp(type, "hexkey"))
+ {
+ unsigned char *key;
+ int r;
+ long keylen;
+ key = string_to_hex(value, &keylen);
+ if (!key)
+ return 0;
+ r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
+ OPENSSL_free(key);
+ return r;
+ }
+ return -2;
+ }
+
+const EVP_PKEY_METHOD cmac_pkey_meth =
+ {
+ EVP_PKEY_CMAC,
+ EVP_PKEY_FLAG_SIGCTX_CUSTOM,
+ pkey_cmac_init,
+ pkey_cmac_copy,
+ pkey_cmac_cleanup,
+
+ 0, 0,
+
+ 0,
+ pkey_cmac_keygen,
+
+ 0, 0,
+
+ 0, 0,
+
+ 0,0,
+
+ cmac_signctx_init,
+ cmac_signctx,
+
+ 0,0,
+
+ 0,0,
+
+ 0,0,
+
+ 0,0,
+
+ pkey_cmac_ctrl,
+ pkey_cmac_ctrl_str
+
+ };
diff --git a/deps/openssl/openssl/crypto/cmac/cmac.c b/deps/openssl/openssl/crypto/cmac/cmac.c
new file mode 100644
index 000000000..8b72b0968
--- /dev/null
+++ b/deps/openssl/openssl/crypto/cmac/cmac.c
@@ -0,0 +1,308 @@
+/* crypto/cmac/cmac.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 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
+ * licensing@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.
+ * ====================================================================
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/cmac.h>
+
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
+struct CMAC_CTX_st
+ {
+ /* Cipher context to use */
+ EVP_CIPHER_CTX cctx;
+ /* Keys k1 and k2 */
+ unsigned char k1[EVP_MAX_BLOCK_LENGTH];
+ unsigned char k2[EVP_MAX_BLOCK_LENGTH];
+ /* Temporary block */
+ unsigned char tbl[EVP_MAX_BLOCK_LENGTH];
+ /* Last (possibly partial) block */
+ unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
+ /* Number of bytes in last block: -1 means context not initialised */
+ int nlast_block;
+ };
+
+
+/* Make temporary keys K1 and K2 */
+
+static void make_kn(unsigned char *k1, unsigned char *l, int bl)
+ {
+ int i;
+ /* Shift block to left, including carry */
+ for (i = 0; i < bl; i++)
+ {
+ k1[i] = l[i] << 1;
+ if (i < bl - 1 && l[i + 1] & 0x80)
+ k1[i] |= 1;
+ }
+ /* If MSB set fixup with R */
+ if (l[0] & 0x80)
+ k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b;
+ }
+
+CMAC_CTX *CMAC_CTX_new(void)
+ {
+ CMAC_CTX *ctx;
+ ctx = OPENSSL_malloc(sizeof(CMAC_CTX));
+ if (!ctx)
+ return NULL;
+ EVP_CIPHER_CTX_init(&ctx->cctx);
+ ctx->nlast_block = -1;
+ return ctx;
+ }
+
+void CMAC_CTX_cleanup(CMAC_CTX *ctx)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->cctx.engine)
+ {
+ FIPS_cmac_ctx_cleanup(ctx);
+ return;
+ }
+#endif
+ EVP_CIPHER_CTX_cleanup(&ctx->cctx);
+ OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
+ OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
+ OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH);
+ OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
+ ctx->nlast_block = -1;
+ }
+
+EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
+ {
+ return &ctx->cctx;
+ }
+
+void CMAC_CTX_free(CMAC_CTX *ctx)
+ {
+ CMAC_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+ }
+
+int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
+ {
+ int bl;
+ if (in->nlast_block == -1)
+ return 0;
+ if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx))
+ return 0;
+ bl = EVP_CIPHER_CTX_block_size(&in->cctx);
+ memcpy(out->k1, in->k1, bl);
+ memcpy(out->k2, in->k2, bl);
+ memcpy(out->tbl, in->tbl, bl);
+ memcpy(out->last_block, in->last_block, bl);
+ out->nlast_block = in->nlast_block;
+ return 1;
+ }
+
+int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
+ const EVP_CIPHER *cipher, ENGINE *impl)
+ {
+ static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ {
+ /* If we have an ENGINE need to allow non FIPS */
+ if ((impl || ctx->cctx.engine)
+ && !(ctx->cctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW))
+
+ {
+ EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS);
+ return 0;
+ }
+ /* Other algorithm blocking will be done in FIPS_cmac_init,
+ * via FIPS_cipherinit().
+ */
+ if (!impl && !ctx->cctx.engine)
+ return FIPS_cmac_init(ctx, key, keylen, cipher, NULL);
+ }
+#endif
+ /* All zeros means restart */
+ if (!key && !cipher && !impl && keylen == 0)
+ {
+ /* Not initialised */
+ if (ctx->nlast_block == -1)
+ return 0;
+ if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
+ return 0;
+ memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx));
+ ctx->nlast_block = 0;
+ return 1;
+ }
+ /* Initialiase context */
+ if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL))
+ return 0;
+ /* Non-NULL key means initialisation complete */
+ if (key)
+ {
+ int bl;
+ if (!EVP_CIPHER_CTX_cipher(&ctx->cctx))
+ return 0;
+ if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen))
+ return 0;
+ if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv))
+ return 0;
+ bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
+ if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl))
+ return 0;
+ make_kn(ctx->k1, ctx->tbl, bl);
+ make_kn(ctx->k2, ctx->k1, bl);
+ OPENSSL_cleanse(ctx->tbl, bl);
+ /* Reset context again ready for first data block */
+ if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
+ return 0;
+ /* Zero tbl so resume works */
+ memset(ctx->tbl, 0, bl);
+ ctx->nlast_block = 0;
+ }
+ return 1;
+ }
+
+int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
+ {
+ const unsigned char *data = in;
+ size_t bl;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->cctx.engine)
+ return FIPS_cmac_update(ctx, in, dlen);
+#endif
+ if (ctx->nlast_block == -1)
+ return 0;
+ if (dlen == 0)
+ return 1;
+ bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
+ /* Copy into partial block if we need to */
+ if (ctx->nlast_block > 0)
+ {
+ size_t nleft;
+ nleft = bl - ctx->nlast_block;
+ if (dlen < nleft)
+ nleft = dlen;
+ memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
+ dlen -= nleft;
+ ctx->nlast_block += nleft;
+ /* If no more to process return */
+ if (dlen == 0)
+ return 1;
+ data += nleft;
+ /* Else not final block so encrypt it */
+ if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block,bl))
+ return 0;
+ }
+ /* Encrypt all but one of the complete blocks left */
+ while(dlen > bl)
+ {
+ if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl))
+ return 0;
+ dlen -= bl;
+ data += bl;
+ }
+ /* Copy any data left to last block buffer */
+ memcpy(ctx->last_block, data, dlen);
+ ctx->nlast_block = dlen;
+ return 1;
+
+ }
+
+int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
+ {
+ int i, bl, lb;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->cctx.engine)
+ return FIPS_cmac_final(ctx, out, poutlen);
+#endif
+ if (ctx->nlast_block == -1)
+ return 0;
+ bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
+ *poutlen = (size_t)bl;
+ if (!out)
+ return 1;
+ lb = ctx->nlast_block;
+ /* Is last block complete? */
+ if (lb == bl)
+ {
+ for (i = 0; i < bl; i++)
+ out[i] = ctx->last_block[i] ^ ctx->k1[i];
+ }
+ else
+ {
+ ctx->last_block[lb] = 0x80;
+ if (bl - lb > 1)
+ memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
+ for (i = 0; i < bl; i++)
+ out[i] = ctx->last_block[i] ^ ctx->k2[i];
+ }
+ if (!EVP_Cipher(&ctx->cctx, out, out, bl))
+ {
+ OPENSSL_cleanse(out, bl);
+ return 0;
+ }
+ return 1;
+ }
+
+int CMAC_resume(CMAC_CTX *ctx)
+ {
+ if (ctx->nlast_block == -1)
+ return 0;
+ /* The buffer "tbl" containes the last fully encrypted block
+ * which is the last IV (or all zeroes if no last encrypted block).
+ * The last block has not been modified since CMAC_final().
+ * So reinitliasing using the last decrypted block will allow
+ * CMAC to continue after calling CMAC_Final().
+ */
+ return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl);
+ }
diff --git a/deps/openssl/openssl/crypto/cmac/cmac.h b/deps/openssl/openssl/crypto/cmac/cmac.h
new file mode 100644
index 000000000..712e92dce
--- /dev/null
+++ b/deps/openssl/openssl/crypto/cmac/cmac.h
@@ -0,0 +1,82 @@
+/* crypto/cmac/cmac.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 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
+ * licensing@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.
+ * ====================================================================
+ */
+
+
+#ifndef HEADER_CMAC_H
+#define HEADER_CMAC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/evp.h>
+
+/* Opaque */
+typedef struct CMAC_CTX_st CMAC_CTX;
+
+CMAC_CTX *CMAC_CTX_new(void);
+void CMAC_CTX_cleanup(CMAC_CTX *ctx);
+void CMAC_CTX_free(CMAC_CTX *ctx);
+EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx);
+int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in);
+
+int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
+ const EVP_CIPHER *cipher, ENGINE *impl);
+int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen);
+int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen);
+int CMAC_resume(CMAC_CTX *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/deps/openssl/openssl/crypto/cms/Makefile b/deps/openssl/openssl/crypto/cms/Makefile
index 583704972..9820adb21 100644
--- a/deps/openssl/openssl/crypto/cms/Makefile
+++ b/deps/openssl/openssl/crypto/cms/Makefile
@@ -18,9 +18,11 @@ APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \
- cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c
+ cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c \
+ cms_pwri.c
LIBOBJ= cms_lib.o cms_asn1.o cms_att.o cms_io.o cms_smime.o cms_err.o \
- cms_sd.o cms_dd.o cms_cd.o cms_env.o cms_enc.o cms_ess.o
+ cms_sd.o cms_dd.o cms_cd.o cms_env.o cms_enc.o cms_ess.o \
+ cms_pwri.o
SRC= $(LIBSRC)
@@ -230,6 +232,24 @@ cms_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
cms_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
cms_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h cms.h
cms_lib.o: cms_lcl.h cms_lib.c
+cms_pwri.o: ../../e_os.h ../../include/openssl/aes.h
+cms_pwri.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+cms_pwri.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+cms_pwri.o: ../../include/openssl/cms.h ../../include/openssl/conf.h
+cms_pwri.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cms_pwri.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+cms_pwri.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+cms_pwri.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+cms_pwri.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+cms_pwri.o: ../../include/openssl/opensslconf.h
+cms_pwri.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cms_pwri.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+cms_pwri.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+cms_pwri.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+cms_pwri.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cms_pwri.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+cms_pwri.o: ../../include/openssl/x509v3.h ../asn1/asn1_locl.h ../cryptlib.h
+cms_pwri.o: cms_lcl.h cms_pwri.c
cms_sd.o: ../../e_os.h ../../include/openssl/asn1.h
cms_sd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
cms_sd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
diff --git a/deps/openssl/openssl/crypto/cms/cms.h b/deps/openssl/openssl/crypto/cms/cms.h
index 09c45d041..36994fa6a 100644
--- a/deps/openssl/openssl/crypto/cms/cms.h
+++ b/deps/openssl/openssl/crypto/cms/cms.h
@@ -111,6 +111,7 @@ DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
#define CMS_PARTIAL 0x4000
#define CMS_REUSE_DIGEST 0x8000
#define CMS_USE_KEYID 0x10000
+#define CMS_DEBUG_DECRYPT 0x20000
const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
@@ -184,6 +185,8 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
unsigned char *key, size_t keylen,
unsigned char *id, size_t idlen);
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
+ unsigned char *pass, ossl_ssize_t passlen);
STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
@@ -219,6 +222,16 @@ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
const unsigned char *id, size_t idlen);
+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
+ unsigned char *pass,
+ ossl_ssize_t passlen);
+
+CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
+ int iter, int wrap_nid, int pbe_nid,
+ unsigned char *pass,
+ ossl_ssize_t passlen,
+ const EVP_CIPHER *kekciph);
+
int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
@@ -330,6 +343,7 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CHECK_CONTENT 99
#define CMS_F_CMS_ADD0_CERT 164
#define CMS_F_CMS_ADD0_RECIPIENT_KEY 100
+#define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165
#define CMS_F_CMS_ADD1_RECEIPTREQUEST 158
#define CMS_F_CMS_ADD1_RECIPIENT_CERT 101
#define CMS_F_CMS_ADD1_SIGNER 102
@@ -344,6 +358,7 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CMS_DATAINIT 111
#define CMS_F_CMS_DECRYPT 112
#define CMS_F_CMS_DECRYPT_SET1_KEY 113
+#define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166
#define CMS_F_CMS_DECRYPT_SET1_PKEY 114
#define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115
#define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116
@@ -378,7 +393,9 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141
#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142
#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143
+#define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT 167
#define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144
+#define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168
#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145
#define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146
#define CMS_F_CMS_SET_DETACHED 147
@@ -419,6 +436,7 @@ void ERR_load_CMS_strings(void);
#define CMS_R_ERROR_SETTING_KEY 115
#define CMS_R_ERROR_SETTING_RECIPIENTINFO 116
#define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117
+#define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176
#define CMS_R_INVALID_KEY_LENGTH 118
#define CMS_R_MD_BIO_INIT_ERROR 119
#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120
@@ -431,6 +449,7 @@ void ERR_load_CMS_strings(void);
#define CMS_R_NOT_ENCRYPTED_DATA 122
#define CMS_R_NOT_KEK 123
#define CMS_R_NOT_KEY_TRANSPORT 124
+#define CMS_R_NOT_PWRI 177
#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125
#define CMS_R_NO_CIPHER 126
#define CMS_R_NO_CONTENT 127
@@ -443,6 +462,7 @@ void ERR_load_CMS_strings(void);
#define CMS_R_NO_MATCHING_RECIPIENT 132
#define CMS_R_NO_MATCHING_SIGNATURE 166
#define CMS_R_NO_MSGSIGDIGEST 167
+#define CMS_R_NO_PASSWORD 178
#define CMS_R_NO_PRIVATE_KEY 133
#define CMS_R_NO_PUBLIC_KEY 134
#define CMS_R_NO_RECEIPT_REQUEST 168
@@ -466,10 +486,12 @@ void ERR_load_CMS_strings(void);
#define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151
#define CMS_R_UNSUPPORTED_CONTENT_TYPE 152
#define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153
+#define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179
#define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154
#define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE 155
#define CMS_R_UNSUPPORTED_TYPE 156
#define CMS_R_UNWRAP_ERROR 157
+#define CMS_R_UNWRAP_FAILURE 180
#define CMS_R_VERIFICATION_FAILURE 158
#define CMS_R_WRAP_ERROR 159
diff --git a/deps/openssl/openssl/crypto/cms/cms_asn1.c b/deps/openssl/openssl/crypto/cms/cms_asn1.c
index fcba4dcbc..cfe67fb6c 100644
--- a/deps/openssl/openssl/crypto/cms/cms_asn1.c
+++ b/deps/openssl/openssl/crypto/cms/cms_asn1.c
@@ -237,6 +237,15 @@ static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
OPENSSL_free(kekri->key);
}
}
+ else if (ri->type == CMS_RECIPINFO_PASS)
+ {
+ CMS_PasswordRecipientInfo *pwri = ri->d.pwri;
+ if (pwri->pass)
+ {
+ OPENSSL_cleanse(pwri->pass, pwri->passlen);
+ OPENSSL_free(pwri->pass);
+ }
+ }
}
return 1;
}
diff --git a/deps/openssl/openssl/crypto/cms/cms_cd.c b/deps/openssl/openssl/crypto/cms/cms_cd.c
index a5fc2c4e2..202168810 100644
--- a/deps/openssl/openssl/crypto/cms/cms_cd.c
+++ b/deps/openssl/openssl/crypto/cms/cms_cd.c
@@ -58,7 +58,9 @@
#include <openssl/err.h>
#include <openssl/cms.h>
#include <openssl/bio.h>
+#ifndef OPENSSL_NO_COMP
#include <openssl/comp.h>
+#endif
#include "cms_lcl.h"
DECLARE_ASN1_ITEM(CMS_CompressedData)
diff --git a/deps/openssl/openssl/crypto/cms/cms_enc.c b/deps/openssl/openssl/crypto/cms/cms_enc.c
index bab26235b..bebeaf29c 100644
--- a/deps/openssl/openssl/crypto/cms/cms_enc.c
+++ b/deps/openssl/openssl/crypto/cms/cms_enc.c
@@ -73,6 +73,8 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
const EVP_CIPHER *ciph;
X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
+ unsigned char *tkey = NULL;
+ size_t tkeylen = 0;
int ok = 0;
@@ -137,32 +139,57 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
goto err;
}
-
-
- if (enc && !ec->key)
+ tkeylen = EVP_CIPHER_CTX_key_length(ctx);
+ /* Generate random session key */
+ if (!enc || !ec->key)
{
- /* Generate random key */
- if (!ec->keylen)
- ec->keylen = EVP_CIPHER_CTX_key_length(ctx);
- ec->key = OPENSSL_malloc(ec->keylen);
- if (!ec->key)
+ tkey = OPENSSL_malloc(tkeylen);
+ if (!tkey)
{
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
ERR_R_MALLOC_FAILURE);
goto err;
}
- if (EVP_CIPHER_CTX_rand_key(ctx, ec->key) <= 0)
+ if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
goto err;
- keep_key = 1;
}
- else if (ec->keylen != (unsigned int)EVP_CIPHER_CTX_key_length(ctx))
+
+ if (!ec->key)
+ {
+ ec->key = tkey;
+ ec->keylen = tkeylen;
+ tkey = NULL;
+ if (enc)
+ keep_key = 1;
+ else
+ ERR_clear_error();
+
+ }
+
+ if (ec->keylen != tkeylen)
{
/* If necessary set key length */
if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0)
{
- CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
- CMS_R_INVALID_KEY_LENGTH);
- goto err;
+ /* Only reveal failure if debugging so we don't
+ * leak information which may be useful in MMA.
+ */
+ if (enc || ec->debug)
+ {
+ CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+ CMS_R_INVALID_KEY_LENGTH);
+ goto err;
+ }
+ else
+ {
+ /* Use random key */
+ OPENSSL_cleanse(ec->key, ec->keylen);
+ OPENSSL_free(ec->key);
+ ec->key = tkey;
+ ec->keylen = tkeylen;
+ tkey = NULL;
+ ERR_clear_error();
+ }
}
}
@@ -198,6 +225,11 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
OPENSSL_free(ec->key);
ec->key = NULL;
}
+ if (tkey)
+ {
+ OPENSSL_cleanse(tkey, tkeylen);
+ OPENSSL_free(tkey);
+ }
if (ok)
return b;
BIO_free(b);
diff --git a/deps/openssl/openssl/crypto/cms/cms_env.c b/deps/openssl/openssl/crypto/cms/cms_env.c
index b3237d4b9..be20b1c02 100644
--- a/deps/openssl/openssl/crypto/cms/cms_env.c
+++ b/deps/openssl/openssl/crypto/cms/cms_env.c
@@ -65,14 +65,13 @@
/* CMS EnvelopedData Utilities */
DECLARE_ASN1_ITEM(CMS_EnvelopedData)
-DECLARE_ASN1_ITEM(CMS_RecipientInfo)
DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
DECLARE_STACK_OF(CMS_RecipientInfo)
-static CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
{
if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped)
{
@@ -371,6 +370,8 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
unsigned char *ek = NULL;
size_t eklen;
int ret = 0;
+ CMS_EncryptedContentInfo *ec;
+ ec = cms->d.envelopedData->encryptedContentInfo;
if (ktri->pkey == NULL)
{
@@ -417,8 +418,14 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
ret = 1;
- cms->d.envelopedData->encryptedContentInfo->key = ek;
- cms->d.envelopedData->encryptedContentInfo->keylen = eklen;
+ if (ec->key)
+ {
+ OPENSSL_cleanse(ec->key, ec->keylen);
+ OPENSSL_free(ec->key);
+ }
+
+ ec->key = ek;
+ ec->keylen = eklen;
err:
if (pctx)
@@ -786,6 +793,9 @@ int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
case CMS_RECIPINFO_KEK:
return cms_RecipientInfo_kekri_decrypt(cms, ri);
+ case CMS_RECIPINFO_PASS:
+ return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
+
default:
CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
@@ -829,6 +839,10 @@ BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
r = cms_RecipientInfo_kekri_encrypt(cms, ri);
break;
+ case CMS_RECIPINFO_PASS:
+ r = cms_RecipientInfo_pwri_crypt(cms, ri, 1);
+ break;
+
default:
CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
diff --git a/deps/openssl/openssl/crypto/cms/cms_err.c b/deps/openssl/openssl/crypto/cms/cms_err.c
index ff7b0309e..8330ead7e 100644
--- a/deps/openssl/openssl/crypto/cms/cms_err.c
+++ b/deps/openssl/openssl/crypto/cms/cms_err.c
@@ -1,6 +1,6 @@
/* crypto/cms/cms_err.c */
/* ====================================================================
- * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2009 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
@@ -73,6 +73,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CHECK_CONTENT), "CHECK_CONTENT"},
{ERR_FUNC(CMS_F_CMS_ADD0_CERT), "CMS_add0_cert"},
{ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY), "CMS_add0_recipient_key"},
+{ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD), "CMS_add0_recipient_password"},
{ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST), "CMS_add1_ReceiptRequest"},
{ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_add1_recipient_cert"},
{ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"},
@@ -87,6 +88,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"},
{ERR_FUNC(CMS_F_CMS_DECRYPT), "CMS_decrypt"},
{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY), "CMS_decrypt_set1_key"},
+{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PASSWORD), "CMS_decrypt_set1_password"},
{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY), "CMS_decrypt_set1_pkey"},
{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX), "cms_DigestAlgorithm_find_ctx"},
{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO), "cms_DigestAlgorithm_init_bio"},
@@ -105,7 +107,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), "CMS_GET0_CERTIFICATE_CHOICES"},
{ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"},
{ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE), "CMS_GET0_ECONTENT_TYPE"},
-{ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "CMS_GET0_ENVELOPED"},
+{ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "cms_get0_enveloped"},
{ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES), "CMS_GET0_REVOCATION_CHOICES"},
{ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "CMS_GET0_SIGNED"},
{ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1), "cms_msgSigDigest_add1"},
@@ -121,7 +123,9 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT), "CMS_RECIPIENTINFO_KTRI_ENCRYPT"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS), "CMS_RecipientInfo_ktri_get0_algs"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID), "CMS_RecipientInfo_ktri_get0_signer_id"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT), "cms_RecipientInfo_pwri_crypt"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY), "CMS_RecipientInfo_set0_key"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD), "CMS_RecipientInfo_set0_password"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY), "CMS_RecipientInfo_set0_pkey"},
{ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "cms_set1_SignerIdentifier"},
{ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"},
@@ -165,6 +169,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
{ERR_REASON(CMS_R_ERROR_SETTING_KEY) ,"error setting key"},
{ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),"error setting recipientinfo"},
{ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),"invalid encrypted key length"},
+{ERR_REASON(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),"invalid key encryption parameter"},
{ERR_REASON(CMS_R_INVALID_KEY_LENGTH) ,"invalid key length"},
{ERR_REASON(CMS_R_MD_BIO_INIT_ERROR) ,"md bio init error"},
{ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"},
@@ -177,6 +182,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
{ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA) ,"not encrypted data"},
{ERR_REASON(CMS_R_NOT_KEK) ,"not kek"},
{ERR_REASON(CMS_R_NOT_KEY_TRANSPORT) ,"not key transport"},
+{ERR_REASON(CMS_R_NOT_PWRI) ,"not pwri"},
{ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"not supported for this key type"},
{ERR_REASON(CMS_R_NO_CIPHER) ,"no cipher"},
{ERR_REASON(CMS_R_NO_CONTENT) ,"no content"},
@@ -189,6 +195,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
{ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"},
{ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE) ,"no matching signature"},
{ERR_REASON(CMS_R_NO_MSGSIGDIGEST) ,"no msgsigdigest"},
+{ERR_REASON(CMS_R_NO_PASSWORD) ,"no password"},
{ERR_REASON(CMS_R_NO_PRIVATE_KEY) ,"no private key"},
{ERR_REASON(CMS_R_NO_PUBLIC_KEY) ,"no public key"},
{ERR_REASON(CMS_R_NO_RECEIPT_REQUEST) ,"no receipt request"},
@@ -212,10 +219,12 @@ static ERR_STRING_DATA CMS_str_reasons[]=
{ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
{ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"},
{ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),"unsupported kek algorithm"},
+{ERR_REASON(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM),"unsupported key encryption algorithm"},
{ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),"unsupported recipient type"},
{ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),"unsupported recpientinfo type"},
{ERR_REASON(CMS_R_UNSUPPORTED_TYPE) ,"unsupported type"},
{ERR_REASON(CMS_R_UNWRAP_ERROR) ,"unwrap error"},
+{ERR_REASON(CMS_R_UNWRAP_FAILURE) ,"unwrap failure"},
{ERR_REASON(CMS_R_VERIFICATION_FAILURE) ,"verification failure"},
{ERR_REASON(CMS_R_WRAP_ERROR) ,"wrap error"},
{0,NULL}
diff --git a/deps/openssl/openssl/crypto/cms/cms_lcl.h b/deps/openssl/openssl/crypto/cms/cms_lcl.h
index c8ecfa724..a9f973015 100644
--- a/deps/openssl/openssl/crypto/cms/cms_lcl.h
+++ b/deps/openssl/openssl/crypto/cms/cms_lcl.h
@@ -175,6 +175,8 @@ struct CMS_EncryptedContentInfo_st
const EVP_CIPHER *cipher;
unsigned char *key;
size_t keylen;
+ /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
+ int debug;
};
struct CMS_RecipientInfo_st
@@ -273,6 +275,9 @@ struct CMS_PasswordRecipientInfo_st
X509_ALGOR *keyDerivationAlgorithm;
X509_ALGOR *keyEncryptionAlgorithm;
ASN1_OCTET_STRING *encryptedKey;
+ /* Extra info: password to use */
+ unsigned char *pass;
+ size_t passlen;
};
struct CMS_OtherRecipientInfo_st
@@ -411,6 +416,8 @@ DECLARE_ASN1_ITEM(CMS_SignerInfo)
DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
+DECLARE_ASN1_ITEM(CMS_RecipientInfo)
+DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo)
DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
#define CMS_SIGNERINFO_ISSUER_SERIAL 0
@@ -454,6 +461,11 @@ int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
+
+/* PWRI routines */
+int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+ int en_de);
#ifdef __cplusplus
}
diff --git a/deps/openssl/openssl/crypto/cms/cms_lib.c b/deps/openssl/openssl/crypto/cms/cms_lib.c
index d00fe0f87..b62d1bfac 100644
--- a/deps/openssl/openssl/crypto/cms/cms_lib.c
+++ b/deps/openssl/openssl/crypto/cms/cms_lib.c
@@ -411,10 +411,7 @@ int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
* algorithm OID instead of digest.
*/
|| EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
- {
- EVP_MD_CTX_copy_ex(mctx, mtmp);
- return 1;
- }
+ return EVP_MD_CTX_copy_ex(mctx, mtmp);
chain = BIO_next(chain);
}
}
diff --git a/deps/openssl/openssl/crypto/cms/cms_pwri.c b/deps/openssl/openssl/crypto/cms/cms_pwri.c
new file mode 100644
index 000000000..b79612a12
--- /dev/null
+++ b/deps/openssl/openssl/crypto/cms/cms_pwri.c
@@ -0,0 +1,454 @@
+/* crypto/cms/cms_pwri.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2009 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
+ * licensing@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.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/rand.h>
+#include <openssl/aes.h>
+#include "cms_lcl.h"
+#include "asn1_locl.h"
+
+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
+ unsigned char *pass, ossl_ssize_t passlen)
+ {
+ CMS_PasswordRecipientInfo *pwri;
+ if (ri->type != CMS_RECIPINFO_PASS)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI);
+ return 0;
+ }
+
+ pwri = ri->d.pwri;
+ pwri->pass = pass;
+ if (pass && passlen < 0)
+ passlen = strlen((char *)pass);
+ pwri->passlen = passlen;
+ return 1;
+ }
+
+CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
+ int iter, int wrap_nid, int pbe_nid,
+ unsigned char *pass,
+ ossl_ssize_t passlen,
+ const EVP_CIPHER *kekciph)
+ {
+ CMS_RecipientInfo *ri = NULL;
+ CMS_EnvelopedData *env;
+ CMS_PasswordRecipientInfo *pwri;
+ EVP_CIPHER_CTX ctx;
+ X509_ALGOR *encalg = NULL;
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+ int ivlen;
+ env = cms_get0_enveloped(cms);
+ if (!env)
+ goto err;
+
+ if (wrap_nid <= 0)
+ wrap_nid = NID_id_alg_PWRI_KEK;
+
+ if (pbe_nid <= 0)
+ pbe_nid = NID_id_pbkdf2;
+
+ /* Get from enveloped data */
+ if (kekciph == NULL)
+ kekciph = env->encryptedContentInfo->cipher;
+
+ if (kekciph == NULL)
+ {
+ CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER);
+ return NULL;
+ }
+ if (wrap_nid != NID_id_alg_PWRI_KEK)
+ {
+ CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
+ CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
+ return NULL;
+ }
+
+ /* Setup algorithm identifier for cipher */
+ encalg = X509_ALGOR_new();
+ EVP_CIPHER_CTX_init(&ctx);
+
+ if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0)
+ {
+ CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
+ goto err;
+ }
+
+ ivlen = EVP_CIPHER_CTX_iv_length(&ctx);
+
+ if (ivlen > 0)
+ {
+ if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+ goto err;
+ if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0)
+ {
+ CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
+ ERR_R_EVP_LIB);
+ goto err;
+ }
+ encalg->parameter = ASN1_TYPE_new();
+ if (!encalg->parameter)
+ {
+ CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0)
+ {
+ CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
+ CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+ goto err;
+ }
+ }
+
+
+ encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx));
+
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ /* Initialize recipient info */
+ ri = M_ASN1_new_of(CMS_RecipientInfo);
+ if (!ri)
+ goto merr;
+
+ ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
+ if (!ri->d.pwri)
+ goto merr;
+ ri->type = CMS_RECIPINFO_PASS;
+
+ pwri = ri->d.pwri;
+ /* Since this is overwritten, free up empty structure already there */
+ X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
+ pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
+ if (!pwri->keyEncryptionAlgorithm)
+ goto merr;
+ pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
+ pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
+ if (!pwri->keyEncryptionAlgorithm->parameter)
+ goto merr;
+
+ if(!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
+ &pwri->keyEncryptionAlgorithm->parameter->value.sequence))
+ goto merr;
+ pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
+
+ X509_ALGOR_free(encalg);
+ encalg = NULL;
+
+ /* Setup PBE algorithm */
+
+ pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);
+
+ if (!pwri->keyDerivationAlgorithm)
+ goto err;
+
+ CMS_RecipientInfo_set0_password(ri, pass, passlen);
+ pwri->version = 0;
+
+ if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+ goto merr;
+
+ return ri;
+
+ merr:
+ CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
+ err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ if (ri)
+ M_ASN1_free_of(ri, CMS_RecipientInfo);
+ if (encalg)
+ X509_ALGOR_free(encalg);
+ return NULL;
+
+ }
+
+/* This is an implementation of the key wrapping mechanism in RFC3211,
+ * at some point this should go into EVP.
+ */
+
+static int kek_unwrap_key(unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx)
+ {
+ size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
+ unsigned char *tmp;
+ int outl, rv = 0;
+ if (inlen < 2 * blocklen)
+ {
+ /* too small */
+ return 0;
+ }
+ if (inlen % blocklen)
+ {
+ /* Invalid size */
+ return 0;
+ }
+ tmp = OPENSSL_malloc(inlen);
+ /* setup IV by decrypting last two blocks */
+ EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
+ in + inlen - 2 * blocklen, blocklen * 2);
+ /* Do a decrypt of last decrypted block to set IV to correct value
+ * output it to start of buffer so we don't corrupt decrypted block
+ * this works because buffer is at least two block lengths long.
+ */
+ EVP_DecryptUpdate(ctx, tmp, &outl,
+ tmp + inlen - blocklen, blocklen);
+ /* Can now decrypt first n - 1 blocks */
+ EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen);
+
+ /* Reset IV to original value */
+ EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
+ /* Decrypt again */
+ EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen);
+ /* Check check bytes */
+ if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff)
+ {
+ /* Check byte failure */
+ goto err;
+ }
+ if (inlen < (size_t)(tmp[0] - 4 ))
+ {
+ /* Invalid length value */
+ goto err;
+ }
+ *outlen = (size_t)tmp[0];
+ memcpy(out, tmp + 4, *outlen);
+ rv = 1;
+ err:
+ OPENSSL_cleanse(tmp, inlen);
+ OPENSSL_free(tmp);
+ return rv;
+
+ }
+
+static int kek_wrap_key(unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx)
+ {
+ size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
+ size_t olen;
+ int dummy;
+ /* First decide length of output buffer: need header and round up to
+ * multiple of block length.
+ */
+ olen = (inlen + 4 + blocklen - 1)/blocklen;
+ olen *= blocklen;
+ if (olen < 2 * blocklen)
+ {
+ /* Key too small */
+ return 0;
+ }
+ if (inlen > 0xFF)
+ {
+ /* Key too large */
+ return 0;
+ }
+ if (out)
+ {
+ /* Set header */
+ out[0] = (unsigned char)inlen;
+ out[1] = in[0] ^ 0xFF;
+ out[2] = in[1] ^ 0xFF;
+ out[3] = in[2] ^ 0xFF;
+ memcpy(out + 4, in, inlen);
+ /* Add random padding to end */
+ if (olen > inlen + 4)
+ RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen);
+ /* Encrypt twice */
+ EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
+ EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
+ }
+
+ *outlen = olen;
+
+ return 1;
+ }
+
+/* Encrypt/Decrypt content key in PWRI recipient info */
+
+int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+ int en_de)
+ {
+ CMS_EncryptedContentInfo *ec;
+ CMS_PasswordRecipientInfo *pwri;
+ const unsigned char *p = NULL;
+ int plen;
+ int r = 0;
+ X509_ALGOR *algtmp, *kekalg = NULL;
+ EVP_CIPHER_CTX kekctx;
+ const EVP_CIPHER *kekcipher;
+ unsigned char *key = NULL;
+ size_t keylen;
+
+ ec = cms->d.envelopedData->encryptedContentInfo;
+
+ pwri = ri->d.pwri;
+ EVP_CIPHER_CTX_init(&kekctx);
+
+ if (!pwri->pass)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
+ return 0;
+ }
+ algtmp = pwri->keyEncryptionAlgorithm;
+
+ if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+ CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
+ return 0;
+ }
+
+ if (algtmp->parameter->type == V_ASN1_SEQUENCE)
+ {
+ p = algtmp->parameter->value.sequence->data;
+ plen = algtmp->parameter->value.sequence->length;
+ kekalg = d2i_X509_ALGOR(NULL, &p, plen);
+ }
+ if (kekalg == NULL)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+ CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
+ return 0;
+ }
+
+ kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
+
+ if(!kekcipher)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+ CMS_R_UNKNOWN_CIPHER);
+ goto err;
+ }
+
+ /* Fixup cipher based on AlgorithmIdentifier to set IV etc */
+ if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de))
+ goto err;
+ EVP_CIPHER_CTX_set_padding(&kekctx, 0);
+ if(EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+ CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+ goto err;
+ }
+
+ algtmp = pwri->keyDerivationAlgorithm;
+
+ /* Finish password based key derivation to setup key in "ctx" */
+
+ if (EVP_PBE_CipherInit(algtmp->algorithm,
+ (char *)pwri->pass, pwri->passlen,
+ algtmp->parameter, &kekctx, en_de) < 0)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
+ goto err;
+ }
+
+ /* Finally wrap/unwrap the key */
+
+ if (en_de)
+ {
+
+ if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx))
+ goto err;
+
+ key = OPENSSL_malloc(keylen);
+
+ if (!key)
+ goto err;
+
+ if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx))
+ goto err;
+ pwri->encryptedKey->data = key;
+ pwri->encryptedKey->length = keylen;
+ }
+ else
+ {
+ key = OPENSSL_malloc(pwri->encryptedKey->length);
+
+ if (!key)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!kek_unwrap_key(key, &keylen,
+ pwri->encryptedKey->data,
+ pwri->encryptedKey->length, &kekctx))
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+ CMS_R_UNWRAP_FAILURE);
+ goto err;
+ }
+
+ ec->key = key;
+ ec->keylen = keylen;
+
+ }
+
+ r = 1;
+
+ err:
+
+ EVP_CIPHER_CTX_cleanup(&kekctx);
+
+ if (!r && key)
+ OPENSSL_free(key);
+ X509_ALGOR_free(kekalg);
+
+ return r;
+
+ }
diff --git a/deps/openssl/openssl/crypto/cms/cms_sd.c b/deps/openssl/openssl/crypto/cms/cms_sd.c
index e3192b9c5..77fbd1359 100644
--- a/deps/openssl/openssl/crypto/cms/cms_sd.c
+++ b/deps/openssl/openssl/crypto/cms/cms_sd.c
@@ -641,7 +641,8 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
cms->d.signedData->encapContentInfo->eContentType;
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int mdlen;
- EVP_DigestFinal_ex(&mctx, md, &mdlen);
+ if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
+ goto err;
if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
V_ASN1_OCTET_STRING,
md, mdlen))
diff --git a/deps/openssl/openssl/crypto/cms/cms_smime.c b/deps/openssl/openssl/crypto/cms/cms_smime.c
index 4a799eb89..8c56e3a85 100644
--- a/deps/openssl/openssl/crypto/cms/cms_smime.c
+++ b/deps/openssl/openssl/crypto/cms/cms_smime.c
@@ -611,7 +611,10 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
STACK_OF(CMS_RecipientInfo) *ris;
CMS_RecipientInfo *ri;
int i, r;
+ int debug = 0;
ris = CMS_get0_RecipientInfos(cms);
+ if (ris)
+ debug = cms->d.envelopedData->encryptedContentInfo->debug;
for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
{
ri = sk_CMS_RecipientInfo_value(ris, i);
@@ -625,17 +628,38 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
CMS_RecipientInfo_set0_pkey(ri, pk);
r = CMS_RecipientInfo_decrypt(cms, ri);
CMS_RecipientInfo_set0_pkey(ri, NULL);
- if (r > 0)
- return 1;
if (cert)
{
+ /* If not debugging clear any error and
+ * return success to avoid leaking of
+ * information useful to MMA
+ */
+ if (!debug)
+ {
+ ERR_clear_error();
+ return 1;
+ }
+ if (r > 0)
+ return 1;
CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
CMS_R_DECRYPT_ERROR);
return 0;
}
- ERR_clear_error();
+ /* If no cert and not debugging don't leave loop
+ * after first successful decrypt. Always attempt
+ * to decrypt all recipients to avoid leaking timing
+ * of a successful decrypt.
+ */
+ else if (r > 0 && debug)
+ return 1;
}
}
+ /* If no cert and not debugging always return success */
+ if (!cert && !debug)
+ {
+ ERR_clear_error();
+ return 1;
+ }
CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
return 0;
@@ -680,6 +704,30 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
return 0;
}
+
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
+ unsigned char *pass, ossl_ssize_t passlen)
+ {
+ STACK_OF(CMS_RecipientInfo) *ris;
+ CMS_RecipientInfo *ri;
+ int i, r;
+ ris = CMS_get0_RecipientInfos(cms);
+ for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
+ {
+ ri = sk_CMS_RecipientInfo_value(ris, i);
+ if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
+ continue;
+ CMS_RecipientInfo_set0_password(ri, pass, passlen);
+ r = CMS_RecipientInfo_decrypt(cms, ri);
+ CMS_RecipientInfo_set0_password(ri, NULL, 0);
+ if (r > 0)
+ return 1;
+ }
+
+ CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT);
+ return 0;
+
+ }
int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
BIO *dcont, BIO *out,
@@ -694,9 +742,14 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
}
if (!dcont && !check_content(cms))
return 0;
+ if (flags & CMS_DEBUG_DECRYPT)
+ cms->d.envelopedData->encryptedContentInfo->debug = 1;
+ else
+ cms->d.envelopedData->encryptedContentInfo->debug = 0;
+ if (!pk && !cert && !dcont && !out)
+ return 1;
if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
return 0;
-
cont = CMS_dataInit(cms, dcont);
if (!cont)
return 0;
diff --git a/deps/openssl/openssl/crypto/comp/c_rle.c b/deps/openssl/openssl/crypto/comp/c_rle.c
index 18bceae51..47dfb67fb 100644
--- a/deps/openssl/openssl/crypto/comp/c_rle.c
+++ b/deps/openssl/openssl/crypto/comp/c_rle.c
@@ -30,7 +30,7 @@ static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
{
/* int i; */
- if (olen < (ilen+1))
+ if (ilen == 0 || olen < (ilen-1))
{
/* ZZZZZZZZZZZZZZZZZZZZZZ */
return(-1);
@@ -46,7 +46,7 @@ static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
{
int i;
- if (ilen == 0 || olen < (ilen-1))
+ if (olen < (ilen-1))
{
/* ZZZZZZZZZZZZZZZZZZZZZZ */
return(-1);
diff --git a/deps/openssl/openssl/crypto/conf/conf_mall.c b/deps/openssl/openssl/crypto/conf/conf_mall.c
index c6f4cb2d5..213890e0c 100644
--- a/deps/openssl/openssl/crypto/conf/conf_mall.c
+++ b/deps/openssl/openssl/crypto/conf/conf_mall.c
@@ -76,5 +76,6 @@ void OPENSSL_load_builtin_modules(void)
#ifndef OPENSSL_NO_ENGINE
ENGINE_add_conf_module();
#endif
+ EVP_add_alg_module();
}
diff --git a/deps/openssl/openssl/crypto/cpt_err.c b/deps/openssl/openssl/crypto/cpt_err.c
index 139b9284e..289005f66 100644
--- a/deps/openssl/openssl/crypto/cpt_err.c
+++ b/deps/openssl/openssl/crypto/cpt_err.c
@@ -1,6 +1,6 @@
/* crypto/cpt_err.c */
/* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -76,6 +76,7 @@ static ERR_STRING_DATA CRYPTO_str_functs[]=
{ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA), "CRYPTO_set_ex_data"},
{ERR_FUNC(CRYPTO_F_DEF_ADD_INDEX), "DEF_ADD_INDEX"},
{ERR_FUNC(CRYPTO_F_DEF_GET_CLASS), "DEF_GET_CLASS"},
+{ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"},
{ERR_FUNC(CRYPTO_F_INT_DUP_EX_DATA), "INT_DUP_EX_DATA"},
{ERR_FUNC(CRYPTO_F_INT_FREE_EX_DATA), "INT_FREE_EX_DATA"},
{ERR_FUNC(CRYPTO_F_INT_NEW_EX_DATA), "INT_NEW_EX_DATA"},
@@ -84,6 +85,7 @@ static ERR_STRING_DATA CRYPTO_str_functs[]=
static ERR_STRING_DATA CRYPTO_str_reasons[]=
{
+{ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
{ERR_REASON(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK),"no dynlock create callback"},
{0,NULL}
};
diff --git a/deps/openssl/openssl/crypto/cryptlib.c b/deps/openssl/openssl/crypto/cryptlib.c
index 24fe123e1..304c6b706 100644
--- a/deps/openssl/openssl/crypto/cryptlib.c
+++ b/deps/openssl/openssl/crypto/cryptlib.c
@@ -409,6 +409,10 @@ int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
const char *file,int line))
{
+ /* Calling this here ensures initialisation before any threads
+ * are started.
+ */
+ OPENSSL_init();
locking_callback=func;
}
@@ -500,7 +504,7 @@ void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
#else
/* For everything else, default to using the address of 'errno' */
- CRYPTO_THREADID_set_pointer(id, &errno);
+ CRYPTO_THREADID_set_pointer(id, (void*)&errno);
#endif
}
@@ -661,28 +665,53 @@ const char *CRYPTO_get_lock_name(int type)
defined(__INTEL__) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
-unsigned long OPENSSL_ia32cap_P=0;
-unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; }
+unsigned int OPENSSL_ia32cap_P[2];
+unsigned long *OPENSSL_ia32cap_loc(void)
+{ if (sizeof(long)==4)
+ /*
+ * If 32-bit application pulls address of OPENSSL_ia32cap_P[0]
+ * clear second element to maintain the illusion that vector
+ * is 32-bit.
+ */
+ OPENSSL_ia32cap_P[1]=0;
+ return (unsigned long *)OPENSSL_ia32cap_P;
+}
#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
#define OPENSSL_CPUID_SETUP
+#if defined(_WIN32)
+typedef unsigned __int64 IA32CAP;
+#else
+typedef unsigned long long IA32CAP;
+#endif
void OPENSSL_cpuid_setup(void)
{ static int trigger=0;
- unsigned long OPENSSL_ia32_cpuid(void);
+ IA32CAP OPENSSL_ia32_cpuid(void);
+ IA32CAP vec;
char *env;
if (trigger) return;
trigger=1;
- if ((env=getenv("OPENSSL_ia32cap")))
- OPENSSL_ia32cap_P = strtoul(env,NULL,0)|(1<<10);
+ if ((env=getenv("OPENSSL_ia32cap"))) {
+ int off = (env[0]=='~')?1:0;
+#if defined(_WIN32)
+ if (!sscanf(env+off,"%I64i",&vec)) vec = strtoul(env+off,NULL,0);
+#else
+ if (!sscanf(env+off,"%lli",(long long *)&vec)) vec = strtoul(env+off,NULL,0);
+#endif
+ if (off) vec = OPENSSL_ia32_cpuid()&~vec;
+ }
else
- OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid()|(1<<10);
+ vec = OPENSSL_ia32_cpuid();
+
/*
* |(1<<10) sets a reserved bit to signal that variable
* was initialized already... This is to avoid interference
* with cpuid snippets in ELF .init segment.
*/
+ OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10);
+ OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32);
}
#endif
@@ -896,3 +925,16 @@ void OpenSSLDie(const char *file,int line,const char *assertion)
}
void *OPENSSL_stderr(void) { return stderr; }
+
+int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
+ {
+ size_t i;
+ const unsigned char *a = in_a;
+ const unsigned char *b = in_b;
+ unsigned char x = 0;
+
+ for (i = 0; i < len; i++)
+ x |= a[i] ^ b[i];
+
+ return x;
+ }
diff --git a/deps/openssl/openssl/crypto/cryptlib.h b/deps/openssl/openssl/crypto/cryptlib.h
index fc249c57f..d26f9630e 100644
--- a/deps/openssl/openssl/crypto/cryptlib.h
+++ b/deps/openssl/openssl/crypto/cryptlib.h
@@ -99,8 +99,8 @@ extern "C" {
#define HEX_SIZE(type) (sizeof(type)*2)
void OPENSSL_cpuid_setup(void);
-extern unsigned long OPENSSL_ia32cap_P;
-void OPENSSL_showfatal(const char *,...);
+extern unsigned int OPENSSL_ia32cap_P[];
+void OPENSSL_showfatal(const char *fmta,...);
void *OPENSSL_stderr(void);
extern int OPENSSL_NONPIC_relocated;
diff --git a/deps/openssl/openssl/crypto/crypto-lib.com b/deps/openssl/openssl/crypto/crypto-lib.com
index a29c0afd9..dc8a8c174 100644
--- a/deps/openssl/openssl/crypto/crypto-lib.com
+++ b/deps/openssl/openssl/crypto/crypto-lib.com
@@ -117,7 +117,7 @@ $ ENCRYPT_TYPES = "Basic,"+ -
"BUFFER,BIO,STACK,LHASH,RAND,ERR,"+ -
"EVP,EVP_2,EVP_3,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
"CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,"+ -
- "STORE,CMS,PQUEUE,TS,JPAKE"
+ "CMS,PQUEUE,TS,JPAKE,SRP,STORE,CMAC"
$!
$! Check To Make Sure We Have Valid Command Line Parameters.
$!
@@ -207,7 +207,8 @@ $!
$ APPS_DES = "DES/DES,CBC3_ENC"
$ APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE"
$
-$ LIB_ = "cryptlib,mem,mem_clr,mem_dbg,cversion,ex_data,cpt_err,ebcdic,uid,o_time,o_str,o_dir"
+$ LIB_ = "cryptlib,mem,mem_clr,mem_dbg,cversion,ex_data,cpt_err,"+ -
+ "ebcdic,uid,o_time,o_str,o_dir,o_fips.c,o_init,fips_ers"
$ LIB_MD2 = "md2_dgst,md2_one"
$ LIB_MD4 = "md4_dgst,md4_one"
$ LIB_MD5 = "md5_dgst,md5_one"
@@ -224,15 +225,16 @@ $ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
"fcrypt,xcbc_enc,rpc_enc,cbc_cksm,"+ -
"ede_cbcm_enc,des_old,des_old2,read2pwd"
$ LIB_RC2 = "rc2_ecb,rc2_skey,rc2_cbc,rc2cfb64,rc2ofb64"
-$ LIB_RC4 = "rc4_skey,rc4_enc"
+$ LIB_RC4 = "rc4_skey,rc4_enc,rc4_utl"
$ LIB_RC5 = "rc5_skey,rc5_ecb,rc5_enc,rc5cfb64,rc5ofb64"
$ LIB_IDEA = "i_cbc,i_cfb64,i_ofb64,i_ecb,i_skey"
$ LIB_BF = "bf_skey,bf_ecb,bf_enc,bf_cfb64,bf_ofb64"
$ LIB_CAST = "c_skey,c_ecb,c_enc,c_cfb64,c_ofb64"
$ LIB_CAMELLIA = "camellia,cmll_misc,cmll_ecb,cmll_cbc,cmll_ofb,"+ -
- "cmll_cfb,cmll_ctr"
+ "cmll_cfb,cmll_ctr,cmll_utl"
$ LIB_SEED = "seed,seed_ecb,seed_cbc,seed_cfb,seed_ofb"
-$ LIB_MODES = "cbc128,ctr128,cts128,cfb128,ofb128"
+$ LIB_MODES = "cbc128,ctr128,cts128,cfb128,ofb128,gcm128,"+ -
+ "ccm128,xts128"
$ LIB_BN_ASM = "[.asm]vms.mar,vms-helper"
$ IF F$TRNLNM("OPENSSL_NO_ASM") .OR. ARCH .NES. "VAX" THEN -
LIB_BN_ASM = "bn_asm"
@@ -240,14 +242,16 @@ $ LIB_BN = "bn_add,bn_div,bn_exp,bn_lib,bn_ctx,bn_mul,bn_mod,"+ -
"bn_print,bn_rand,bn_shift,bn_word,bn_blind,"+ -
"bn_kron,bn_sqrt,bn_gcd,bn_prime,bn_err,bn_sqr,"+LIB_BN_ASM+","+ -
"bn_recp,bn_mont,bn_mpi,bn_exp2,bn_gf2m,bn_nist,"+ -
- "bn_depr,bn_const"
+ "bn_depr,bn_const,bn_x931p"
$ LIB_EC = "ec_lib,ecp_smpl,ecp_mont,ecp_nist,ec_cvt,ec_mult,"+ -
"ec_err,ec_curve,ec_check,ec_print,ec_asn1,ec_key,"+ -
- "ec2_smpl,ec2_mult,ec_ameth,ec_pmeth,eck_prn"
+ "ec2_smpl,ec2_mult,ec_ameth,ec_pmeth,eck_prn,"+ -
+ "ecp_nistp224,ecp_nistp256,ecp_nistp521,ecp_nistputil,"+ -
+ "ecp_oct,ec2_oct,ec_oct"
$ LIB_RSA = "rsa_eay,rsa_gen,rsa_lib,rsa_sign,rsa_saos,rsa_err,"+ -
"rsa_pk1,rsa_ssl,rsa_none,rsa_oaep,rsa_chk,rsa_null,"+ -
"rsa_pss,rsa_x931,rsa_asn1,rsa_depr,rsa_ameth,rsa_prn,"+ -
- "rsa_pmeth"
+ "rsa_pmeth,rsa_crpt"
$ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,"+ -
"dsa_err,dsa_ossl,dsa_depr,dsa_ameth,dsa_pmeth,dsa_prn"
$ LIB_ECDSA = "ecs_lib,ecs_asn1,ecs_ossl,ecs_sign,ecs_vrf,ecs_err"
@@ -260,10 +264,11 @@ $ LIB_ENGINE = "eng_err,eng_lib,eng_list,eng_init,eng_ctrl,"+ -
"eng_table,eng_pkey,eng_fat,eng_all,"+ -
"tb_rsa,tb_dsa,tb_ecdsa,tb_dh,tb_ecdh,tb_rand,tb_store,"+ -
"tb_cipher,tb_digest,tb_pkmeth,tb_asnmth,"+ -
- "eng_openssl,eng_dyn,eng_cnf,eng_cryptodev"
+ "eng_openssl,eng_dyn,eng_cnf,eng_cryptodev,"+ -
+ "eng_rsax,eng_rdrand"
$ LIB_AES = "aes_core,aes_misc,aes_ecb,aes_cbc,aes_cfb,aes_ofb,aes_ctr,"+ -
"aes_ige,aes_wrap"
-$ LIB_BUFFER = "buffer,buf_err"
+$ LIB_BUFFER = "buffer,buf_str,buf_err"
$ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
"bss_mem,bss_null,bss_fd,"+ -
"bss_file,bss_sock,bss_conn,"+ -
@@ -277,7 +282,7 @@ $ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,"+ -
"rand_vms"
$ LIB_ERR = "err,err_all,err_prn"
$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref"
-$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,"+ -
+$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,evp_cnf,"+ -
"e_des,e_bf,e_idea,e_des3,e_camellia,"+ -
"e_rc4,e_aes,names,e_seed,"+ -
"e_xcbc_d,e_rc2,e_cast,e_rc5"
@@ -287,7 +292,8 @@ $ LIB_EVP_2 = "m_null,m_md2,m_md4,m_md5,m_sha,m_sha1,m_wp," + -
"bio_md,bio_b64,bio_enc,evp_err,e_null,"+ -
"c_all,c_allc,c_alld,evp_lib,bio_ok,"+-
"evp_pkey,evp_pbe,p5_crpt,p5_crpt2"
-$ LIB_EVP_3 = "e_old,pmeth_lib,pmeth_fn,pmeth_gn,m_sigver"
+$ LIB_EVP_3 = "e_old,pmeth_lib,pmeth_fn,pmeth_gn,m_sigver,evp_fips,"+ -
+ "e_aes_cbc_hmac_sha1,e_rc4_hmac_md5"
$ LIB_ASN1 = "a_object,a_bitstr,a_utctm,a_gentm,a_time,a_int,a_octet,"+ -
"a_print,a_type,a_set,a_dup,a_d2i_fp,a_i2d_fp,"+ -
"a_enum,a_utf8,a_sign,a_digest,a_verify,a_mbstr,a_strex,"+ -
@@ -329,14 +335,17 @@ $ LIB_OCSP = "ocsp_asn,ocsp_ext,ocsp_ht,ocsp_lib,ocsp_cl,"+ -
$ LIB_UI_COMPAT = ",ui_compat"
$ LIB_UI = "ui_err,ui_lib,ui_openssl,ui_util"+LIB_UI_COMPAT
$ LIB_KRB5 = "krb5_asn"
-$ LIB_STORE = "str_err,str_lib,str_meth,str_mem"
$ LIB_CMS = "cms_lib,cms_asn1,cms_att,cms_io,cms_smime,cms_err,"+ -
- "cms_sd,cms_dd,cms_cd,cms_env,cms_enc,cms_ess"
+ "cms_sd,cms_dd,cms_cd,cms_env,cms_enc,cms_ess,"+ -
+ "cms_pwri"
$ LIB_PQUEUE = "pqueue"
$ LIB_TS = "ts_err,ts_req_utils,ts_req_print,ts_rsp_utils,ts_rsp_print,"+ -
"ts_rsp_sign,ts_rsp_verify,ts_verify_ctx,ts_lib,ts_conf,"+ -
"ts_asn1"
$ LIB_JPAKE = "jpake,jpake_err"
+$ LIB_SRP = "srp_lib,srp_vfy"
+$ LIB_STORE = "str_err,str_lib,str_meth,str_mem"
+$ LIB_CMAC = "cmac,cm_ameth.c,cm_pmeth"
$!
$! Setup exceptional compilations
$!
@@ -1021,7 +1030,7 @@ $!
$! Set basic C compiler /INCLUDE directories.
$!
$ CC_INCLUDES = "SYS$DISK:[.''ARCHD'],SYS$DISK:[],SYS$DISK:[-],"+ -
- "SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1]"
+ "SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.MODES],SYS$DISK:[.ASN1],SYS$DISK:[.EVP]"
$!
$! Check To See If P3 Is Blank.
$!
diff --git a/deps/openssl/openssl/crypto/crypto.h b/deps/openssl/openssl/crypto/crypto.h
index b0360cec5..f92fc5182 100644
--- a/deps/openssl/openssl/crypto/crypto.h
+++ b/deps/openssl/openssl/crypto/crypto.h
@@ -488,10 +488,10 @@ void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
long (**go)(void));
void *CRYPTO_malloc_locked(int num, const char *file, int line);
-void CRYPTO_free_locked(void *);
+void CRYPTO_free_locked(void *ptr);
void *CRYPTO_malloc(int num, const char *file, int line);
char *CRYPTO_strdup(const char *str, const char *file, int line);
-void CRYPTO_free(void *);
+void CRYPTO_free(void *ptr);
void *CRYPTO_realloc(void *addr,int num, const char *file, int line);
void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file,
int line);
@@ -547,6 +547,40 @@ unsigned long *OPENSSL_ia32cap_loc(void);
#define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
int OPENSSL_isservice(void);
+int FIPS_mode(void);
+int FIPS_mode_set(int r);
+
+void OPENSSL_init(void);
+
+#define fips_md_init(alg) fips_md_init_ctx(alg, alg)
+
+#ifdef OPENSSL_FIPS
+#define fips_md_init_ctx(alg, cx) \
+ int alg##_Init(cx##_CTX *c) \
+ { \
+ if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
+ "Low level API call to digest " #alg " forbidden in FIPS mode!"); \
+ return private_##alg##_Init(c); \
+ } \
+ int private_##alg##_Init(cx##_CTX *c)
+
+#define fips_cipher_abort(alg) \
+ if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
+ "Low level API call to cipher " #alg " forbidden in FIPS mode!")
+
+#else
+#define fips_md_init_ctx(alg, cx) \
+ int alg##_Init(cx##_CTX *c)
+#define fips_cipher_abort(alg) while(0)
+#endif
+
+/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It
+ * takes an amount of time dependent on |len|, but independent of the contents
+ * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a
+ * defined order as the return value when a != b is undefined, other than to be
+ * non-zero. */
+int CRYPTO_memcmp(const void *a, const void *b, size_t len);
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@@ -562,11 +596,13 @@ void ERR_load_CRYPTO_strings(void);
#define CRYPTO_F_CRYPTO_SET_EX_DATA 102
#define CRYPTO_F_DEF_ADD_INDEX 104
#define CRYPTO_F_DEF_GET_CLASS 105
+#define CRYPTO_F_FIPS_MODE_SET 109
#define CRYPTO_F_INT_DUP_EX_DATA 106
#define CRYPTO_F_INT_FREE_EX_DATA 107
#define CRYPTO_F_INT_NEW_EX_DATA 108
/* Reason codes. */
+#define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101
#define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100
#ifdef __cplusplus
diff --git a/deps/openssl/openssl/crypto/des/Makefile b/deps/openssl/openssl/crypto/des/Makefile
index ae982265f..a6e100132 100644
--- a/deps/openssl/openssl/crypto/des/Makefile
+++ b/deps/openssl/openssl/crypto/des/Makefile
@@ -257,8 +257,9 @@ rpc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
rpc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
rpc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
rpc_enc.o: des_locl.h des_ver.h rpc_des.h rpc_enc.c
-set_key.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-set_key.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+set_key.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+set_key.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+set_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
set_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
set_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
set_key.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
diff --git a/deps/openssl/openssl/crypto/des/des.h b/deps/openssl/openssl/crypto/des/des.h
index 92b666359..1eaedcbd2 100644
--- a/deps/openssl/openssl/crypto/des/des.h
+++ b/deps/openssl/openssl/crypto/des/des.h
@@ -224,6 +224,9 @@ int DES_set_key(const_DES_cblock *key,DES_key_schedule *schedule);
int DES_key_sched(const_DES_cblock *key,DES_key_schedule *schedule);
int DES_set_key_checked(const_DES_cblock *key,DES_key_schedule *schedule);
void DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule);
+#ifdef OPENSSL_FIPS
+void private_DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule);
+#endif
void DES_string_to_key(const char *str,DES_cblock *key);
void DES_string_to_2keys(const char *str,DES_cblock *key1,DES_cblock *key2);
void DES_cfb64_encrypt(const unsigned char *in,unsigned char *out,long length,
diff --git a/deps/openssl/openssl/crypto/des/set_key.c b/deps/openssl/openssl/crypto/des/set_key.c
index 3004cc3ab..da4d62e11 100644
--- a/deps/openssl/openssl/crypto/des/set_key.c
+++ b/deps/openssl/openssl/crypto/des/set_key.c
@@ -63,6 +63,7 @@
* 1.1 added norm_expand_bits
* 1.0 First working version
*/
+#include <openssl/crypto.h>
#include "des_locl.h"
OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key,0) /* defaults to false */
@@ -335,6 +336,13 @@ int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
}
void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
+#ifdef OPENSSL_FIPS
+ {
+ fips_cipher_abort(DES);
+ private_DES_set_key_unchecked(key, schedule);
+ }
+void private_DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
+#endif
{
static const int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
register DES_LONG c,d,t,s,t2;
diff --git a/deps/openssl/openssl/crypto/des/str2key.c b/deps/openssl/openssl/crypto/des/str2key.c
index 9c2054bda..1077f99d1 100644
--- a/deps/openssl/openssl/crypto/des/str2key.c
+++ b/deps/openssl/openssl/crypto/des/str2key.c
@@ -56,8 +56,8 @@
* [including the GNU Public Licence.]
*/
-#include "des_locl.h"
#include <openssl/crypto.h>
+#include "des_locl.h"
void DES_string_to_key(const char *str, DES_cblock *key)
{
diff --git a/deps/openssl/openssl/crypto/dh/dh.h b/deps/openssl/openssl/crypto/dh/dh.h
index 849309a48..ea59e610e 100644
--- a/deps/openssl/openssl/crypto/dh/dh.h
+++ b/deps/openssl/openssl/crypto/dh/dh.h
@@ -86,6 +86,21 @@
* be used for all exponents.
*/
+/* If this flag is set the DH method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its reposibility
+ * to ensure the result is compliant.
+ */
+
+#define DH_FLAG_FIPS_METHOD 0x0400
+
+/* If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+#define DH_FLAG_NON_FIPS_ALLOW 0x0400
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -230,6 +245,9 @@ void ERR_load_DH_strings(void);
#define DH_F_COMPUTE_KEY 102
#define DH_F_DHPARAMS_PRINT_FP 101
#define DH_F_DH_BUILTIN_GENPARAMS 106
+#define DH_F_DH_COMPUTE_KEY 114
+#define DH_F_DH_GENERATE_KEY 115
+#define DH_F_DH_GENERATE_PARAMETERS_EX 116
#define DH_F_DH_NEW_METHOD 105
#define DH_F_DH_PARAM_DECODE 107
#define DH_F_DH_PRIV_DECODE 110
@@ -249,7 +267,9 @@ void ERR_load_DH_strings(void);
#define DH_R_DECODE_ERROR 104
#define DH_R_INVALID_PUBKEY 102
#define DH_R_KEYS_NOT_SET 108
+#define DH_R_KEY_SIZE_TOO_SMALL 110
#define DH_R_MODULUS_TOO_LARGE 103
+#define DH_R_NON_FIPS_METHOD 111
#define DH_R_NO_PARAMETERS_SET 107
#define DH_R_NO_PRIVATE_VALUE 100
#define DH_R_PARAMETER_ENCODING_ERROR 105
diff --git a/deps/openssl/openssl/crypto/dh/dh_ameth.c b/deps/openssl/openssl/crypto/dh/dh_ameth.c
index 377caf96c..02ec2d47b 100644
--- a/deps/openssl/openssl/crypto/dh/dh_ameth.c
+++ b/deps/openssl/openssl/crypto/dh/dh_ameth.c
@@ -493,6 +493,7 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth =
dh_copy_parameters,
dh_cmp_parameters,
dh_param_print,
+ 0,
int_dh_free,
0
diff --git a/deps/openssl/openssl/crypto/dh/dh_err.c b/deps/openssl/openssl/crypto/dh/dh_err.c
index d5cf0c22a..56d3df735 100644
--- a/deps/openssl/openssl/crypto/dh/dh_err.c
+++ b/deps/openssl/openssl/crypto/dh/dh_err.c
@@ -1,6 +1,6 @@
/* crypto/dh/dh_err.c */
/* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -73,6 +73,9 @@ static ERR_STRING_DATA DH_str_functs[]=
{ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"},
{ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"},
{ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"},
+{ERR_FUNC(DH_F_DH_COMPUTE_KEY), "DH_compute_key"},
+{ERR_FUNC(DH_F_DH_GENERATE_KEY), "DH_generate_key"},
+{ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS_EX), "DH_generate_parameters_ex"},
{ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"},
{ERR_FUNC(DH_F_DH_PARAM_DECODE), "DH_PARAM_DECODE"},
{ERR_FUNC(DH_F_DH_PRIV_DECODE), "DH_PRIV_DECODE"},
@@ -95,7 +98,9 @@ static ERR_STRING_DATA DH_str_reasons[]=
{ERR_REASON(DH_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"},
{ERR_REASON(DH_R_KEYS_NOT_SET) ,"keys not set"},
+{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL) ,"key size too small"},
{ERR_REASON(DH_R_MODULUS_TOO_LARGE) ,"modulus too large"},
+{ERR_REASON(DH_R_NON_FIPS_METHOD) ,"non fips method"},
{ERR_REASON(DH_R_NO_PARAMETERS_SET) ,"no parameters set"},
{ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"},
{ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
diff --git a/deps/openssl/openssl/crypto/dh/dh_gen.c b/deps/openssl/openssl/crypto/dh/dh_gen.c
index cfd5b1186..7b1fe9c9c 100644
--- a/deps/openssl/openssl/crypto/dh/dh_gen.c
+++ b/deps/openssl/openssl/crypto/dh/dh_gen.c
@@ -66,12 +66,29 @@
#include <openssl/bn.h>
#include <openssl/dh.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb);
int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(ret->meth->flags & DH_FLAG_FIPS_METHOD)
+ && !(ret->flags & DH_FLAG_NON_FIPS_ALLOW))
+ {
+ DHerr(DH_F_DH_GENERATE_PARAMETERS_EX, DH_R_NON_FIPS_METHOD);
+ return 0;
+ }
+#endif
if(ret->meth->generate_params)
return ret->meth->generate_params(ret, prime_len, generator, cb);
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_dh_generate_parameters_ex(ret, prime_len,
+ generator, cb);
+#endif
return dh_builtin_genparams(ret, prime_len, generator, cb);
}
diff --git a/deps/openssl/openssl/crypto/dh/dh_key.c b/deps/openssl/openssl/crypto/dh/dh_key.c
index e7db44034..89a74db4e 100644
--- a/deps/openssl/openssl/crypto/dh/dh_key.c
+++ b/deps/openssl/openssl/crypto/dh/dh_key.c
@@ -73,11 +73,27 @@ static int dh_finish(DH *dh);
int DH_generate_key(DH *dh)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD)
+ && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW))
+ {
+ DHerr(DH_F_DH_GENERATE_KEY, DH_R_NON_FIPS_METHOD);
+ return 0;
+ }
+#endif
return dh->meth->generate_key(dh);
}
int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD)
+ && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW))
+ {
+ DHerr(DH_F_DH_COMPUTE_KEY, DH_R_NON_FIPS_METHOD);
+ return 0;
+ }
+#endif
return dh->meth->compute_key(key, pub_key, dh);
}
@@ -138,8 +154,21 @@ static int generate_key(DH *dh)
if (generate_new_key)
{
- l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
- if (!BN_rand(priv_key, l, 0, 0)) goto err;
+ if (dh->q)
+ {
+ do
+ {
+ if (!BN_rand_range(priv_key, dh->q))
+ goto err;
+ }
+ while (BN_is_zero(priv_key) || BN_is_one(priv_key));
+ }
+ else
+ {
+ /* secret exponent length */
+ l = dh->length ? dh->length : BN_num_bits(dh->p)-1;
+ if (!BN_rand(priv_key, l, 0, 0)) goto err;
+ }
}
{
diff --git a/deps/openssl/openssl/crypto/dh/dh_lib.c b/deps/openssl/openssl/crypto/dh/dh_lib.c
index 7aef080e7..00218f2b9 100644
--- a/deps/openssl/openssl/crypto/dh/dh_lib.c
+++ b/deps/openssl/openssl/crypto/dh/dh_lib.c
@@ -64,6 +64,10 @@
#include <openssl/engine.h>
#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
const char DH_version[]="Diffie-Hellman" OPENSSL_VERSION_PTEXT;
static const DH_METHOD *default_DH_method = NULL;
@@ -76,7 +80,16 @@ void DH_set_default_method(const DH_METHOD *meth)
const DH_METHOD *DH_get_default_method(void)
{
if(!default_DH_method)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_dh_openssl();
+ else
+ return DH_OpenSSL();
+#else
default_DH_method = DH_OpenSSL();
+#endif
+ }
return default_DH_method;
}
@@ -156,7 +169,7 @@ DH *DH_new_method(ENGINE *engine)
ret->counter = NULL;
ret->method_mont_p=NULL;
ret->references = 1;
- ret->flags=ret->meth->flags;
+ ret->flags=ret->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
if ((ret->meth->init != NULL) && !ret->meth->init(ret))
{
diff --git a/deps/openssl/openssl/crypto/dsa/Makefile b/deps/openssl/openssl/crypto/dsa/Makefile
index 8073c4ecf..5fef4ca5a 100644
--- a/deps/openssl/openssl/crypto/dsa/Makefile
+++ b/deps/openssl/openssl/crypto/dsa/Makefile
@@ -99,8 +99,9 @@ dsa_asn1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
dsa_asn1.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
dsa_asn1.o: ../../include/openssl/opensslconf.h
dsa_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dsa_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dsa_asn1.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_asn1.c
+dsa_asn1.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+dsa_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dsa_asn1.o: ../cryptlib.h dsa_asn1.c
dsa_depr.o: ../../e_os.h ../../include/openssl/asn1.h
dsa_depr.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
dsa_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
@@ -189,7 +190,7 @@ dsa_prn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
dsa_prn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
dsa_prn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
dsa_prn.o: ../cryptlib.h dsa_prn.c
-dsa_sign.o: ../../e_os.h ../../include/openssl/bio.h
+dsa_sign.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
dsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
diff --git a/deps/openssl/openssl/crypto/dsa/dsa.h b/deps/openssl/openssl/crypto/dsa/dsa.h
index ac50a5c84..a6f6d0b0b 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa.h
+++ b/deps/openssl/openssl/crypto/dsa/dsa.h
@@ -97,6 +97,21 @@
* be used for all exponents.
*/
+/* If this flag is set the DSA method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its reposibility
+ * to ensure the result is compliant.
+ */
+
+#define DSA_FLAG_FIPS_METHOD 0x0400
+
+/* If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+#define DSA_FLAG_NON_FIPS_ALLOW 0x0400
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -272,6 +287,8 @@ void ERR_load_DSA_strings(void);
#define DSA_F_DSAPARAMS_PRINT_FP 101
#define DSA_F_DSA_DO_SIGN 112
#define DSA_F_DSA_DO_VERIFY 113
+#define DSA_F_DSA_GENERATE_KEY 124
+#define DSA_F_DSA_GENERATE_PARAMETERS_EX 123
#define DSA_F_DSA_NEW_METHOD 103
#define DSA_F_DSA_PARAM_DECODE 119
#define DSA_F_DSA_PRINT_FP 105
@@ -282,6 +299,7 @@ void ERR_load_DSA_strings(void);
#define DSA_F_DSA_SIGN 106
#define DSA_F_DSA_SIGN_SETUP 107
#define DSA_F_DSA_SIG_NEW 109
+#define DSA_F_DSA_SIG_PRINT 125
#define DSA_F_DSA_VERIFY 108
#define DSA_F_I2D_DSA_SIG 111
#define DSA_F_OLD_DSA_PRIV_DECODE 122
@@ -298,6 +316,8 @@ void ERR_load_DSA_strings(void);
#define DSA_R_INVALID_DIGEST_TYPE 106
#define DSA_R_MISSING_PARAMETERS 101
#define DSA_R_MODULUS_TOO_LARGE 103
+#define DSA_R_NEED_NEW_SETUP_VALUES 110
+#define DSA_R_NON_FIPS_DSA_METHOD 111
#define DSA_R_NO_PARAMETERS_SET 107
#define DSA_R_PARAMETER_ENCODING_ERROR 105
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_ameth.c b/deps/openssl/openssl/crypto/dsa/dsa_ameth.c
index 6413aae46..376156ec5 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_ameth.c
+++ b/deps/openssl/openssl/crypto/dsa/dsa_ameth.c
@@ -542,6 +542,52 @@ static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
}
+static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
+ const ASN1_STRING *sig,
+ int indent, ASN1_PCTX *pctx)
+ {
+ DSA_SIG *dsa_sig;
+ const unsigned char *p;
+ if (!sig)
+ {
+ if (BIO_puts(bp, "\n") <= 0)
+ return 0;
+ else
+ return 1;
+ }
+ p = sig->data;
+ dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
+ if (dsa_sig)
+ {
+ int rv = 0;
+ size_t buf_len = 0;
+ unsigned char *m=NULL;
+ update_buflen(dsa_sig->r, &buf_len);
+ update_buflen(dsa_sig->s, &buf_len);
+ m = OPENSSL_malloc(buf_len+10);
+ if (m == NULL)
+ {
+ DSAerr(DSA_F_DSA_SIG_PRINT,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (BIO_write(bp, "\n", 1) != 1)
+ goto err;
+
+ if (!ASN1_bn_print(bp,"r: ",dsa_sig->r,m,indent))
+ goto err;
+ if (!ASN1_bn_print(bp,"s: ",dsa_sig->s,m,indent))
+ goto err;
+ rv = 1;
+ err:
+ if (m)
+ OPENSSL_free(m);
+ DSA_SIG_free(dsa_sig);
+ return rv;
+ }
+ return X509_signature_dump(bp, sig, indent);
+ }
+
static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
switch (op)
@@ -647,6 +693,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
dsa_copy_parameters,
dsa_cmp_parameters,
dsa_param_print,
+ dsa_sig_print,
int_dsa_free,
dsa_pkey_ctrl,
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_asn1.c b/deps/openssl/openssl/crypto/dsa/dsa_asn1.c
index c37460b2d..605853437 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_asn1.c
+++ b/deps/openssl/openssl/crypto/dsa/dsa_asn1.c
@@ -61,6 +61,7 @@
#include <openssl/dsa.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
+#include <openssl/rand.h>
/* Override the default new methods */
static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
@@ -87,7 +88,7 @@ ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = {
ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG)
-IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG)
/* Override the default free and new methods */
static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
@@ -148,3 +149,40 @@ DSA *DSAparams_dup(DSA *dsa)
{
return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
}
+
+int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
+ unsigned int *siglen, DSA *dsa)
+ {
+ DSA_SIG *s;
+ RAND_seed(dgst, dlen);
+ s=DSA_do_sign(dgst,dlen,dsa);
+ if (s == NULL)
+ {
+ *siglen=0;
+ return(0);
+ }
+ *siglen=i2d_DSA_SIG(s,&sig);
+ DSA_SIG_free(s);
+ return(1);
+ }
+
+/* data has already been hashed (probably with SHA or SHA-1). */
+/* returns
+ * 1: correct signature
+ * 0: incorrect signature
+ * -1: error
+ */
+int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
+ const unsigned char *sigbuf, int siglen, DSA *dsa)
+ {
+ DSA_SIG *s;
+ int ret=-1;
+
+ s = DSA_SIG_new();
+ if (s == NULL) return(ret);
+ if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
+ ret=DSA_do_verify(dgst,dgst_len,s,dsa);
+err:
+ DSA_SIG_free(s);
+ return(ret);
+ }
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_err.c b/deps/openssl/openssl/crypto/dsa/dsa_err.c
index bba984e92..00545b7b9 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_err.c
+++ b/deps/openssl/openssl/crypto/dsa/dsa_err.c
@@ -1,6 +1,6 @@
/* crypto/dsa/dsa_err.c */
/* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -76,6 +76,8 @@ static ERR_STRING_DATA DSA_str_functs[]=
{ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"},
{ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"},
{ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"},
+{ERR_FUNC(DSA_F_DSA_GENERATE_KEY), "DSA_generate_key"},
+{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS_EX), "DSA_generate_parameters_ex"},
{ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"},
{ERR_FUNC(DSA_F_DSA_PARAM_DECODE), "DSA_PARAM_DECODE"},
{ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
@@ -86,6 +88,7 @@ static ERR_STRING_DATA DSA_str_functs[]=
{ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"},
{ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"},
{ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"},
+{ERR_FUNC(DSA_F_DSA_SIG_PRINT), "DSA_SIG_PRINT"},
{ERR_FUNC(DSA_F_DSA_VERIFY), "DSA_verify"},
{ERR_FUNC(DSA_F_I2D_DSA_SIG), "i2d_DSA_SIG"},
{ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE), "OLD_DSA_PRIV_DECODE"},
@@ -105,6 +108,8 @@ static ERR_STRING_DATA DSA_str_reasons[]=
{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
{ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"},
{ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"},
+{ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES) ,"need new setup values"},
+{ERR_REASON(DSA_R_NON_FIPS_DSA_METHOD) ,"non fips dsa method"},
{ERR_REASON(DSA_R_NO_PARAMETERS_SET) ,"no parameters set"},
{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
{0,NULL}
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_gen.c b/deps/openssl/openssl/crypto/dsa/dsa_gen.c
index cb0b4538a..c398761d0 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_gen.c
+++ b/deps/openssl/openssl/crypto/dsa/dsa_gen.c
@@ -81,13 +81,33 @@
#include <openssl/sha.h>
#include "dsa_locl.h"
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
int DSA_generate_parameters_ex(DSA *ret, int bits,
const unsigned char *seed_in, int seed_len,
int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD)
+ && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW))
+ {
+ DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD);
+ return 0;
+ }
+#endif
if(ret->meth->dsa_paramgen)
return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
counter_ret, h_ret, cb);
+#ifdef OPENSSL_FIPS
+ else if (FIPS_mode())
+ {
+ return FIPS_dsa_generate_parameters_ex(ret, bits,
+ seed_in, seed_len,
+ counter_ret, h_ret, cb);
+ }
+#endif
else
{
const EVP_MD *evpmd;
@@ -105,12 +125,13 @@ int DSA_generate_parameters_ex(DSA *ret, int bits,
}
return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
- seed_in, seed_len, counter_ret, h_ret, cb);
+ seed_in, seed_len, NULL, counter_ret, h_ret, cb);
}
}
int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+ unsigned char *seed_out,
int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
{
int ok=0;
@@ -201,8 +222,10 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
}
/* step 2 */
- EVP_Digest(seed, qsize, md, NULL, evpmd, NULL);
- EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL);
+ if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
+ goto err;
+ if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
+ goto err;
for (i = 0; i < qsize; i++)
md[i]^=buf2[i];
@@ -251,7 +274,9 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
break;
}
- EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL);
+ if (!EVP_Digest(buf, qsize, md ,NULL, evpmd,
+ NULL))
+ goto err;
/* step 8 */
if (!BN_bin2bn(md, qsize, r0))
@@ -332,6 +357,8 @@ err:
}
if (counter_ret != NULL) *counter_ret=counter;
if (h_ret != NULL) *h_ret=h;
+ if (seed_out)
+ memcpy(seed_out, seed, qsize);
}
if(ctx)
{
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_key.c b/deps/openssl/openssl/crypto/dsa/dsa_key.c
index c4aa86bc6..9cf669b92 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_key.c
+++ b/deps/openssl/openssl/crypto/dsa/dsa_key.c
@@ -64,12 +64,28 @@
#include <openssl/dsa.h>
#include <openssl/rand.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
static int dsa_builtin_keygen(DSA *dsa);
int DSA_generate_key(DSA *dsa)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+ && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+ {
+ DSAerr(DSA_F_DSA_GENERATE_KEY, DSA_R_NON_FIPS_DSA_METHOD);
+ return 0;
+ }
+#endif
if(dsa->meth->dsa_keygen)
return dsa->meth->dsa_keygen(dsa);
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_dsa_generate_key(dsa);
+#endif
return dsa_builtin_keygen(dsa);
}
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_lib.c b/deps/openssl/openssl/crypto/dsa/dsa_lib.c
index e9b75902d..96d8d0c4b 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_lib.c
+++ b/deps/openssl/openssl/crypto/dsa/dsa_lib.c
@@ -70,6 +70,10 @@
#include <openssl/dh.h>
#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
const char DSA_version[]="DSA" OPENSSL_VERSION_PTEXT;
static const DSA_METHOD *default_DSA_method = NULL;
@@ -82,7 +86,16 @@ void DSA_set_default_method(const DSA_METHOD *meth)
const DSA_METHOD *DSA_get_default_method(void)
{
if(!default_DSA_method)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_dsa_openssl();
+ else
+ return DSA_OpenSSL();
+#else
default_DSA_method = DSA_OpenSSL();
+#endif
+ }
return default_DSA_method;
}
@@ -163,7 +176,7 @@ DSA *DSA_new_method(ENGINE *engine)
ret->method_mont_p=NULL;
ret->references=1;
- ret->flags=ret->meth->flags;
+ ret->flags=ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
if ((ret->meth->init != NULL) && !ret->meth->init(ret))
{
@@ -276,7 +289,8 @@ void *DSA_get_ex_data(DSA *d, int idx)
DH *DSA_dup_DH(const DSA *r)
{
/* DSA has p, q, g, optional pub_key, optional priv_key.
- * DH has p, optional length, g, optional pub_key, optional priv_key.
+ * DH has p, optional length, g, optional pub_key, optional priv_key,
+ * optional q.
*/
DH *ret = NULL;
@@ -290,7 +304,11 @@ DH *DSA_dup_DH(const DSA *r)
if ((ret->p = BN_dup(r->p)) == NULL)
goto err;
if (r->q != NULL)
+ {
ret->length = BN_num_bits(r->q);
+ if ((ret->q = BN_dup(r->q)) == NULL)
+ goto err;
+ }
if (r->g != NULL)
if ((ret->g = BN_dup(r->g)) == NULL)
goto err;
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_locl.h b/deps/openssl/openssl/crypto/dsa/dsa_locl.h
index 2b8cfee3d..21e2e4524 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_locl.h
+++ b/deps/openssl/openssl/crypto/dsa/dsa_locl.h
@@ -56,4 +56,5 @@
int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+ unsigned char *seed_out,
int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_ossl.c b/deps/openssl/openssl/crypto/dsa/dsa_ossl.c
index a3ddd7d28..b3d78e524 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_ossl.c
+++ b/deps/openssl/openssl/crypto/dsa/dsa_ossl.c
@@ -136,6 +136,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
BN_CTX *ctx=NULL;
int reason=ERR_R_BN_LIB;
DSA_SIG *ret=NULL;
+ int noredo = 0;
BN_init(&m);
BN_init(&xr);
@@ -150,7 +151,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
if (s == NULL) goto err;
ctx=BN_CTX_new();
if (ctx == NULL) goto err;
-
+redo:
if ((dsa->kinv == NULL) || (dsa->r == NULL))
{
if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
@@ -161,6 +162,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
dsa->kinv=NULL;
r=dsa->r;
dsa->r=NULL;
+ noredo = 1;
}
@@ -181,6 +183,18 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
ret=DSA_SIG_new();
if (ret == NULL) goto err;
+ /* Redo if r or s is zero as required by FIPS 186-3: this is
+ * very unlikely.
+ */
+ if (BN_is_zero(r) || BN_is_zero(s))
+ {
+ if (noredo)
+ {
+ reason = DSA_R_NEED_NEW_SETUP_VALUES;
+ goto err;
+ }
+ goto redo;
+ }
ret->r = r;
ret->s = s;
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_pmeth.c b/deps/openssl/openssl/crypto/dsa/dsa_pmeth.c
index e2df54fec..715d8d675 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_pmeth.c
+++ b/deps/openssl/openssl/crypto/dsa/dsa_pmeth.c
@@ -189,7 +189,9 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
EVP_MD_type((const EVP_MD *)p2) != NID_dsa &&
EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha256)
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
{
DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
return 0;
@@ -253,7 +255,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
if (!dsa)
return 0;
ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
- NULL, 0, NULL, NULL, pcb);
+ NULL, 0, NULL, NULL, NULL, pcb);
if (ret)
EVP_PKEY_assign_DSA(pkey, dsa);
else
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_sign.c b/deps/openssl/openssl/crypto/dsa/dsa_sign.c
index 17555e589..c3cc3642c 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_sign.c
+++ b/deps/openssl/openssl/crypto/dsa/dsa_sign.c
@@ -61,30 +61,54 @@
#include "cryptlib.h"
#include <openssl/dsa.h>
#include <openssl/rand.h>
+#include <openssl/bn.h>
DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+ && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+ {
+ DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_NON_FIPS_DSA_METHOD);
+ return NULL;
+ }
+#endif
return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
}
-int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
- unsigned int *siglen, DSA *dsa)
+int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
- DSA_SIG *s;
- RAND_seed(dgst, dlen);
- s=DSA_do_sign(dgst,dlen,dsa);
- if (s == NULL)
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+ && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
{
- *siglen=0;
- return(0);
+ DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NON_FIPS_DSA_METHOD);
+ return 0;
}
- *siglen=i2d_DSA_SIG(s,&sig);
- DSA_SIG_free(s);
- return(1);
+#endif
+ return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
}
-int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+DSA_SIG *DSA_SIG_new(void)
{
- return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
+ DSA_SIG *sig;
+ sig = OPENSSL_malloc(sizeof(DSA_SIG));
+ if (!sig)
+ return NULL;
+ sig->r = NULL;
+ sig->s = NULL;
+ return sig;
+ }
+
+void DSA_SIG_free(DSA_SIG *sig)
+ {
+ if (sig)
+ {
+ if (sig->r)
+ BN_free(sig->r);
+ if (sig->s)
+ BN_free(sig->s);
+ OPENSSL_free(sig);
+ }
}
diff --git a/deps/openssl/openssl/crypto/dsa/dsa_vrf.c b/deps/openssl/openssl/crypto/dsa/dsa_vrf.c
index 226a75ff3..674cb5fa5 100644
--- a/deps/openssl/openssl/crypto/dsa/dsa_vrf.c
+++ b/deps/openssl/openssl/crypto/dsa/dsa_vrf.c
@@ -64,26 +64,13 @@
int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
DSA *dsa)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+ && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+ {
+ DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_NON_FIPS_DSA_METHOD);
+ return -1;
+ }
+#endif
return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
}
-
-/* data has already been hashed (probably with SHA or SHA-1). */
-/* returns
- * 1: correct signature
- * 0: incorrect signature
- * -1: error
- */
-int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
- const unsigned char *sigbuf, int siglen, DSA *dsa)
- {
- DSA_SIG *s;
- int ret=-1;
-
- s = DSA_SIG_new();
- if (s == NULL) return(ret);
- if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
- ret=DSA_do_verify(dgst,dgst_len,s,dsa);
-err:
- DSA_SIG_free(s);
- return(ret);
- }
diff --git a/deps/openssl/openssl/crypto/dso/dso_dlfcn.c b/deps/openssl/openssl/crypto/dso/dso_dlfcn.c
index c2bc61760..5f2254806 100644
--- a/deps/openssl/openssl/crypto/dso/dso_dlfcn.c
+++ b/deps/openssl/openssl/crypto/dso/dso_dlfcn.c
@@ -86,7 +86,8 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
# if defined(_AIX) || defined(__CYGWIN__) || \
defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
(defined(__osf__) && !defined(RTLD_NEXT)) || \
- (defined(__OpenBSD__) && !defined(RTLD_SELF))
+ (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \
+ defined(__ANDROID__)
# undef HAVE_DLINFO
# endif
#endif
diff --git a/deps/openssl/openssl/crypto/ec/Makefile b/deps/openssl/openssl/crypto/ec/Makefile
index db380ed16..f85fc845c 100644
--- a/deps/openssl/openssl/crypto/ec/Makefile
+++ b/deps/openssl/openssl/crypto/ec/Makefile
@@ -19,11 +19,15 @@ APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c\
ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
- ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c
+ ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c \
+ ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \
+ ecp_oct.c ec2_oct.c ec_oct.c
LIBOBJ= ec_lib.o ecp_smpl.o ecp_mont.o ecp_nist.o ec_cvt.o ec_mult.o\
ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
- ec2_smpl.o ec2_mult.o ec_ameth.o ec_pmeth.o eck_prn.o
+ ec2_smpl.o ec2_mult.o ec_ameth.o ec_pmeth.o eck_prn.o \
+ ecp_nistp224.o ecp_nistp256.o ecp_nistp521.o ecp_nistputil.o \
+ ecp_oct.o ec2_oct.o ec_oct.o
SRC= $(LIBSRC)
@@ -87,6 +91,14 @@ ec2_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec2_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec2_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec2_mult.o: ../../include/openssl/symhacks.h ec2_mult.c ec_lcl.h
+ec2_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec2_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec2_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec2_oct.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec2_oct.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec2_oct.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec2_oct.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec2_oct.o: ../../include/openssl/symhacks.h ec2_oct.c ec_lcl.h
ec2_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec2_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec2_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -174,6 +186,14 @@ ec_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec_mult.o: ../../include/openssl/symhacks.h ec_lcl.h ec_mult.c
+ec_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec_oct.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_oct.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_oct.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_oct.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_oct.o: ../../include/openssl/symhacks.h ec_lcl.h ec_oct.c
ec_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
ec_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
ec_pmeth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
@@ -221,6 +241,18 @@ ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ecp_nist.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_nist.c
+ecp_nistp224.o: ../../include/openssl/opensslconf.h ecp_nistp224.c
+ecp_nistp256.o: ../../include/openssl/opensslconf.h ecp_nistp256.c
+ecp_nistp521.o: ../../include/openssl/opensslconf.h ecp_nistp521.c
+ecp_nistputil.o: ../../include/openssl/opensslconf.h ecp_nistputil.c
+ecp_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ecp_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ecp_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecp_oct.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ecp_oct.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ecp_oct.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ecp_oct.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ecp_oct.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_oct.c
ecp_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ecp_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ecp_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
diff --git a/deps/openssl/openssl/crypto/ec/ec.h b/deps/openssl/openssl/crypto/ec/ec.h
index ee7078130..dfe8710d3 100644
--- a/deps/openssl/openssl/crypto/ec/ec.h
+++ b/deps/openssl/openssl/crypto/ec/ec.h
@@ -151,7 +151,24 @@ const EC_METHOD *EC_GFp_mont_method(void);
*/
const EC_METHOD *EC_GFp_nist_method(void);
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+/** Returns 64-bit optimized methods for nistp224
+ * \return EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp224_method(void);
+
+/** Returns 64-bit optimized methods for nistp256
+ * \return EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp256_method(void);
+
+/** Returns 64-bit optimized methods for nistp521
+ * \return EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp521_method(void);
+#endif
+#ifndef OPENSSL_NO_EC2M
/********************************************************************/
/* EC_METHOD for curves over GF(2^m) */
/********************************************************************/
@@ -161,6 +178,8 @@ const EC_METHOD *EC_GFp_nist_method(void);
*/
const EC_METHOD *EC_GF2m_simple_method(void);
+#endif
+
/********************************************************************/
/* EC_GROUP functions */
@@ -255,10 +274,10 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group);
void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
-void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
+void EC_GROUP_set_point_conversion_form(EC_GROUP *group, point_conversion_form_t form);
point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
-unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
size_t EC_GROUP_get_seed_len(const EC_GROUP *);
size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
@@ -282,6 +301,7 @@ int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, co
*/
int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+#ifndef OPENSSL_NO_EC2M
/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
* \param group EC_GROUP object
* \param p BIGNUM with the polynomial defining the underlying field
@@ -301,7 +321,7 @@ int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, c
* \return 1 on success and 0 if an error occured
*/
int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
-
+#endif
/** Returns the number of bits needed to represent a field element
* \param group EC_GROUP object
* \return number of bits needed to represent a field element
@@ -342,7 +362,7 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
* \return newly created EC_GROUP object with the specified parameters
*/
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
-
+#ifndef OPENSSL_NO_EC2M
/** Creates a new EC_GROUP object with the specified parameters defined
* over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
* \param p BIGNUM with the polynomial defining the underlying field
@@ -352,7 +372,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
* \return newly created EC_GROUP object with the specified parameters
*/
EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
-
+#endif
/** Creates a EC_GROUP object with a curve specified by a NID
* \param nid NID of the OID of the curve name
* \return newly created EC_GROUP object with specified curve or NULL
@@ -481,7 +501,7 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
*/
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
const BIGNUM *x, int y_bit, BN_CTX *ctx);
-
+#ifndef OPENSSL_NO_EC2M
/** Sets the affine coordinates of a EC_POINT over GF2m
* \param group underlying EC_GROUP object
* \param p EC_POINT object
@@ -514,7 +534,7 @@ int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
*/
int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
const BIGNUM *x, int y_bit, BN_CTX *ctx);
-
+#endif
/** Encodes a EC_POINT object to a octet string
* \param group underlying EC_GROUP object
* \param p EC_POINT object
@@ -606,8 +626,8 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *c
*/
int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
-int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
-int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx);
/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
* \param group underlying EC_GROUP object
@@ -653,9 +673,11 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
/* EC_GROUP_get_basis_type() returns the NID of the basis type
* used to represent the field elements */
int EC_GROUP_get_basis_type(const EC_GROUP *);
+#ifndef OPENSSL_NO_EC2M
int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
unsigned int *k2, unsigned int *k3);
+#endif
#define OPENSSL_EC_NAMED_CURVE 0x001
@@ -689,11 +711,21 @@ typedef struct ec_key_st EC_KEY;
#define EC_PKEY_NO_PARAMETERS 0x001
#define EC_PKEY_NO_PUBKEY 0x002
+/* some values for the flags field */
+#define EC_FLAG_NON_FIPS_ALLOW 0x1
+#define EC_FLAG_FIPS_CHECKED 0x2
+
/** Creates a new EC_KEY object.
* \return EC_KEY object or NULL if an error occurred.
*/
EC_KEY *EC_KEY_new(void);
+int EC_KEY_get_flags(const EC_KEY *key);
+
+void EC_KEY_set_flags(EC_KEY *key, int flags);
+
+void EC_KEY_clear_flags(EC_KEY *key, int flags);
+
/** Creates a new EC_KEY object using a named curve as underlying
* EC_GROUP object.
* \param nid NID of the named curve.
@@ -768,16 +800,24 @@ const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
-void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
-point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
-void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
+void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
+void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
/* functions to set/get method specific data */
-void *EC_KEY_get_key_method_data(EC_KEY *,
+void *EC_KEY_get_key_method_data(EC_KEY *key,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
-void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
+/** Sets the key method data of an EC_KEY object, if none has yet been set.
+ * \param key EC_KEY object
+ * \param data opaque data to install.
+ * \param dup_func a function that duplicates |data|.
+ * \param free_func a function that frees |data|.
+ * \param clear_free_func a function that wipes and frees |data|.
+ * \return the previously set data pointer, or NULL if |data| was inserted.
+ */
+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
/* wrapper functions for the underlying EC_GROUP object */
-void EC_KEY_set_asn1_flag(EC_KEY *, int);
+void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
/** Creates a table of pre-computed multiples of the generator to
* accelerate further EC_KEY operations.
@@ -799,6 +839,15 @@ int EC_KEY_generate_key(EC_KEY *key);
*/
int EC_KEY_check_key(const EC_KEY *key);
+/** Sets a public key from affine coordindates performing
+ * neccessary NIST PKV tests.
+ * \param key the EC_KEY object
+ * \param x public key x coordinate
+ * \param y public key y coordinate
+ * \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y);
+
/********************************************************************/
/* de- and encoding functions for SEC1 ECPrivateKey */
@@ -926,6 +975,7 @@ void ERR_load_EC_strings(void);
/* Error codes for the EC functions. */
/* Function codes. */
+#define EC_F_BN_TO_FELEM 224
#define EC_F_COMPUTE_WNAF 143
#define EC_F_D2I_ECPARAMETERS 144
#define EC_F_D2I_ECPKPARAMETERS 145
@@ -968,6 +1018,15 @@ void ERR_load_EC_strings(void);
#define EC_F_EC_GFP_MONT_FIELD_SQR 132
#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189
#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135
+#define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225
+#define EC_F_EC_GFP_NISTP224_POINTS_MUL 228
+#define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226
+#define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230
+#define EC_F_EC_GFP_NISTP256_POINTS_MUL 231
+#define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232
+#define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233
+#define EC_F_EC_GFP_NISTP521_POINTS_MUL 234
+#define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235
#define EC_F_EC_GFP_NIST_FIELD_MUL 200
#define EC_F_EC_GFP_NIST_FIELD_SQR 201
#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202
@@ -1010,6 +1069,7 @@ void ERR_load_EC_strings(void);
#define EC_F_EC_KEY_NEW 182
#define EC_F_EC_KEY_PRINT 180
#define EC_F_EC_KEY_PRINT_FP 181
+#define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229
#define EC_F_EC_POINTS_MAKE_AFFINE 136
#define EC_F_EC_POINT_ADD 112
#define EC_F_EC_POINT_CMP 113
@@ -1040,6 +1100,9 @@ void ERR_load_EC_strings(void);
#define EC_F_I2D_ECPKPARAMETERS 191
#define EC_F_I2D_ECPRIVATEKEY 192
#define EC_F_I2O_ECPUBLICKEY 151
+#define EC_F_NISTP224_PRE_COMP_NEW 227
+#define EC_F_NISTP256_PRE_COMP_NEW 236
+#define EC_F_NISTP521_PRE_COMP_NEW 237
#define EC_F_O2I_ECPUBLICKEY 152
#define EC_F_OLD_EC_PRIV_DECODE 222
#define EC_F_PKEY_EC_CTRL 197
@@ -1052,12 +1115,15 @@ void ERR_load_EC_strings(void);
/* Reason codes. */
#define EC_R_ASN1_ERROR 115
#define EC_R_ASN1_UNKNOWN_FIELD 116
+#define EC_R_BIGNUM_OUT_OF_RANGE 144
#define EC_R_BUFFER_TOO_SMALL 100
+#define EC_R_COORDINATES_OUT_OF_RANGE 146
#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
#define EC_R_DECODE_ERROR 142
#define EC_R_DISCRIMINANT_IS_ZERO 118
#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
#define EC_R_FIELD_TOO_LARGE 143
+#define EC_R_GF2M_NOT_SUPPORTED 147
#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
#define EC_R_INCOMPATIBLE_OBJECTS 101
@@ -1092,6 +1158,7 @@ void ERR_load_EC_strings(void);
#define EC_R_UNKNOWN_GROUP 129
#define EC_R_UNKNOWN_ORDER 114
#define EC_R_UNSUPPORTED_FIELD 131
+#define EC_R_WRONG_CURVE_PARAMETERS 145
#define EC_R_WRONG_ORDER 130
#ifdef __cplusplus
diff --git a/deps/openssl/openssl/crypto/ec/ec2_mult.c b/deps/openssl/openssl/crypto/ec/ec2_mult.c
index e12b9b284..26f4a783f 100644
--- a/deps/openssl/openssl/crypto/ec/ec2_mult.c
+++ b/deps/openssl/openssl/crypto/ec/ec2_mult.c
@@ -71,6 +71,8 @@
#include "ec_lcl.h"
+#ifndef OPENSSL_NO_EC2M
+
/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
* coordinates.
@@ -384,3 +386,5 @@ int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
{
return ec_wNAF_have_precompute_mult(group);
}
+
+#endif
diff --git a/deps/openssl/openssl/crypto/ec/ec2_oct.c b/deps/openssl/openssl/crypto/ec/ec2_oct.c
new file mode 100644
index 000000000..f1d75e5dd
--- /dev/null
+++ b/deps/openssl/openssl/crypto/ec/ec2_oct.c
@@ -0,0 +1,407 @@
+/* crypto/ec/ec2_oct.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 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).
+ *
+ */
+
+#include <openssl/err.h>
+
+#include "ec_lcl.h"
+
+#ifndef OPENSSL_NO_EC2M
+
+/* Calculates and sets the affine coordinates of an EC_POINT from the given
+ * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
+ * Note that the simple implementation only uses affine coordinates.
+ *
+ * The method is from the following publication:
+ *
+ * Harper, Menezes, Vanstone:
+ * "Public-Key Cryptosystems with Very Small Key Lengths",
+ * EUROCRYPT '92, Springer-Verlag LNCS 658,
+ * published February 1993
+ *
+ * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
+ * the same method, but claim no priority date earlier than July 29, 1994
+ * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
+ */
+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x_, int y_bit, BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp, *x, *y, *z;
+ int ret = 0, z0;
+
+ /* clear error queue */
+ ERR_clear_error();
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ y_bit = (y_bit != 0) ? 1 : 0;
+
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ z = BN_CTX_get(ctx);
+ if (z == NULL) goto err;
+
+ if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
+ if (BN_is_zero(x))
+ {
+ if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
+ }
+ else
+ {
+ if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
+ if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
+ if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
+ if (!BN_GF2m_add(tmp, x, tmp)) goto err;
+ if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
+ {
+ unsigned long err = ERR_peek_last_error();
+
+ if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
+ {
+ ERR_clear_error();
+ ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+ }
+ else
+ ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
+ goto err;
+ }
+ z0 = (BN_is_odd(z)) ? 1 : 0;
+ if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
+ if (z0 != y_bit)
+ {
+ if (!BN_GF2m_add(y, y, x)) goto err;
+ }
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+/* Converts an EC_POINT to an octet string.
+ * If buf is NULL, the encoded length will be returned.
+ * If the length len of buf is smaller than required an error will be returned.
+ */
+size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *ctx)
+ {
+ size_t ret;
+ BN_CTX *new_ctx = NULL;
+ int used_ctx = 0;
+ BIGNUM *x, *y, *yxi;
+ size_t field_len, i, skip;
+
+ if ((form != POINT_CONVERSION_COMPRESSED)
+ && (form != POINT_CONVERSION_UNCOMPRESSED)
+ && (form != POINT_CONVERSION_HYBRID))
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+ goto err;
+ }
+
+ if (EC_POINT_is_at_infinity(group, point))
+ {
+ /* encodes to a single 0 octet */
+ if (buf != NULL)
+ {
+ if (len < 1)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ buf[0] = 0;
+ }
+ return 1;
+ }
+
+
+ /* ret := required output buffer length */
+ field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+ ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+ /* if 'buf' is NULL, just return required length */
+ if (buf != NULL)
+ {
+ if (len < ret)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ goto err;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ used_ctx = 1;
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ yxi = BN_CTX_get(ctx);
+ if (yxi == NULL) goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+
+ buf[0] = form;
+ if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
+ {
+ if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
+ if (BN_is_odd(yxi)) buf[0]++;
+ }
+
+ i = 1;
+
+ skip = field_len - BN_num_bytes(x);
+ if (skip > field_len)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ while (skip > 0)
+ {
+ buf[i++] = 0;
+ skip--;
+ }
+ skip = BN_bn2bin(x, buf + i);
+ i += skip;
+ if (i != 1 + field_len)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
+ {
+ skip = field_len - BN_num_bytes(y);
+ if (skip > field_len)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ while (skip > 0)
+ {
+ buf[i++] = 0;
+ skip--;
+ }
+ skip = BN_bn2bin(y, buf + i);
+ i += skip;
+ }
+
+ if (i != ret)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ if (used_ctx)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+
+ err:
+ if (used_ctx)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return 0;
+ }
+
+
+/* Converts an octet string representation to an EC_POINT.
+ * Note that the simple implementation only uses affine coordinates.
+ */
+int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+ const unsigned char *buf, size_t len, BN_CTX *ctx)
+ {
+ point_conversion_form_t form;
+ int y_bit;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y, *yxi;
+ size_t field_len, enc_len;
+ int ret = 0;
+
+ if (len == 0)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ form = buf[0];
+ y_bit = form & 1;
+ form = form & ~1U;
+ if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
+ && (form != POINT_CONVERSION_UNCOMPRESSED)
+ && (form != POINT_CONVERSION_HYBRID))
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+ if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ if (form == 0)
+ {
+ if (len != 1)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ return EC_POINT_set_to_infinity(group, point);
+ }
+
+ field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+ enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+ if (len != enc_len)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ yxi = BN_CTX_get(ctx);
+ if (yxi == NULL) goto err;
+
+ if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
+ if (BN_ucmp(x, &group->field) >= 0)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+
+ if (form == POINT_CONVERSION_COMPRESSED)
+ {
+ if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
+ if (BN_ucmp(y, &group->field) >= 0)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ if (form == POINT_CONVERSION_HYBRID)
+ {
+ if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
+ if (y_bit != BN_is_odd(yxi))
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+ }
+
+ if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
+ goto err;
+ }
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+#endif
diff --git a/deps/openssl/openssl/crypto/ec/ec2_smpl.c b/deps/openssl/openssl/crypto/ec/ec2_smpl.c
index 03deae667..e0e59c7d8 100644
--- a/deps/openssl/openssl/crypto/ec/ec2_smpl.c
+++ b/deps/openssl/openssl/crypto/ec/ec2_smpl.c
@@ -71,10 +71,20 @@
#include "ec_lcl.h"
+#ifndef OPENSSL_NO_EC2M
+
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
const EC_METHOD *EC_GF2m_simple_method(void)
{
+#ifdef OPENSSL_FIPS
+ return fips_ec_gf2m_simple_method();
+#else
static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
NID_X9_62_characteristic_two_field,
ec_GF2m_simple_group_init,
ec_GF2m_simple_group_finish,
@@ -93,9 +103,7 @@ const EC_METHOD *EC_GF2m_simple_method(void)
0 /* get_Jprojective_coordinates_GFp */,
ec_GF2m_simple_point_set_affine_coordinates,
ec_GF2m_simple_point_get_affine_coordinates,
- ec_GF2m_simple_set_compressed_coordinates,
- ec_GF2m_simple_point2oct,
- ec_GF2m_simple_oct2point,
+ 0,0,0,
ec_GF2m_simple_add,
ec_GF2m_simple_dbl,
ec_GF2m_simple_invert,
@@ -118,6 +126,7 @@ const EC_METHOD *EC_GF2m_simple_method(void)
0 /* field_set_to_one */ };
return &ret;
+#endif
}
@@ -405,340 +414,6 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_
return ret;
}
-
-/* Calculates and sets the affine coordinates of an EC_POINT from the given
- * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
- * Note that the simple implementation only uses affine coordinates.
- *
- * The method is from the following publication:
- *
- * Harper, Menezes, Vanstone:
- * "Public-Key Cryptosystems with Very Small Key Lengths",
- * EUROCRYPT '92, Springer-Verlag LNCS 658,
- * published February 1993
- *
- * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
- * the same method, but claim no priority date earlier than July 29, 1994
- * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
- */
-int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
- const BIGNUM *x_, int y_bit, BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- BIGNUM *tmp, *x, *y, *z;
- int ret = 0, z0;
-
- /* clear error queue */
- ERR_clear_error();
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- y_bit = (y_bit != 0) ? 1 : 0;
-
- BN_CTX_start(ctx);
- tmp = BN_CTX_get(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- z = BN_CTX_get(ctx);
- if (z == NULL) goto err;
-
- if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
- if (BN_is_zero(x))
- {
- if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
- }
- else
- {
- if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
- if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
- if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
- if (!BN_GF2m_add(tmp, x, tmp)) goto err;
- if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
- {
- unsigned long err = ERR_peek_last_error();
-
- if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
- {
- ERR_clear_error();
- ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
- }
- else
- ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
- goto err;
- }
- z0 = (BN_is_odd(z)) ? 1 : 0;
- if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
- if (z0 != y_bit)
- {
- if (!BN_GF2m_add(y, y, x)) goto err;
- }
- }
-
- if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-/* Converts an EC_POINT to an octet string.
- * If buf is NULL, the encoded length will be returned.
- * If the length len of buf is smaller than required an error will be returned.
- */
-size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
- unsigned char *buf, size_t len, BN_CTX *ctx)
- {
- size_t ret;
- BN_CTX *new_ctx = NULL;
- int used_ctx = 0;
- BIGNUM *x, *y, *yxi;
- size_t field_len, i, skip;
-
- if ((form != POINT_CONVERSION_COMPRESSED)
- && (form != POINT_CONVERSION_UNCOMPRESSED)
- && (form != POINT_CONVERSION_HYBRID))
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
- goto err;
- }
-
- if (EC_POINT_is_at_infinity(group, point))
- {
- /* encodes to a single 0 octet */
- if (buf != NULL)
- {
- if (len < 1)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
- return 0;
- }
- buf[0] = 0;
- }
- return 1;
- }
-
-
- /* ret := required output buffer length */
- field_len = (EC_GROUP_get_degree(group) + 7) / 8;
- ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
-
- /* if 'buf' is NULL, just return required length */
- if (buf != NULL)
- {
- if (len < ret)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
- goto err;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- used_ctx = 1;
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- yxi = BN_CTX_get(ctx);
- if (yxi == NULL) goto err;
-
- if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
-
- buf[0] = form;
- if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
- {
- if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
- if (BN_is_odd(yxi)) buf[0]++;
- }
-
- i = 1;
-
- skip = field_len - BN_num_bytes(x);
- if (skip > field_len)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- while (skip > 0)
- {
- buf[i++] = 0;
- skip--;
- }
- skip = BN_bn2bin(x, buf + i);
- i += skip;
- if (i != 1 + field_len)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
- {
- skip = field_len - BN_num_bytes(y);
- if (skip > field_len)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- while (skip > 0)
- {
- buf[i++] = 0;
- skip--;
- }
- skip = BN_bn2bin(y, buf + i);
- i += skip;
- }
-
- if (i != ret)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- }
-
- if (used_ctx)
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
-
- err:
- if (used_ctx)
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return 0;
- }
-
-
-/* Converts an octet string representation to an EC_POINT.
- * Note that the simple implementation only uses affine coordinates.
- */
-int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
- const unsigned char *buf, size_t len, BN_CTX *ctx)
- {
- point_conversion_form_t form;
- int y_bit;
- BN_CTX *new_ctx = NULL;
- BIGNUM *x, *y, *yxi;
- size_t field_len, enc_len;
- int ret = 0;
-
- if (len == 0)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
- return 0;
- }
- form = buf[0];
- y_bit = form & 1;
- form = form & ~1U;
- if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
- && (form != POINT_CONVERSION_UNCOMPRESSED)
- && (form != POINT_CONVERSION_HYBRID))
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
- if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- if (form == 0)
- {
- if (len != 1)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- return EC_POINT_set_to_infinity(group, point);
- }
-
- field_len = (EC_GROUP_get_degree(group) + 7) / 8;
- enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
-
- if (len != enc_len)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- yxi = BN_CTX_get(ctx);
- if (yxi == NULL) goto err;
-
- if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
- if (BN_ucmp(x, &group->field) >= 0)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
-
- if (form == POINT_CONVERSION_COMPRESSED)
- {
- if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
- }
- else
- {
- if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
- if (BN_ucmp(y, &group->field) >= 0)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
- if (form == POINT_CONVERSION_HYBRID)
- {
- if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
- if (y_bit != BN_is_odd(yxi))
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
- }
-
- if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
- }
-
- if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
- }
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
/* Computes a + b and stores the result in r. r could be a or b, a could be b.
* Uses algorithm A.10.2 of IEEE P1363.
*/
@@ -1040,3 +715,5 @@ int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
{
return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
}
+
+#endif
diff --git a/deps/openssl/openssl/crypto/ec/ec_ameth.c b/deps/openssl/openssl/crypto/ec/ec_ameth.c
index c00f7d746..83909c185 100644
--- a/deps/openssl/openssl/crypto/ec/ec_ameth.c
+++ b/deps/openssl/openssl/crypto/ec/ec_ameth.c
@@ -651,6 +651,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
ec_copy_parameters,
ec_cmp_parameters,
eckey_param_print,
+ 0,
int_ec_free,
ec_pkey_ctrl,
diff --git a/deps/openssl/openssl/crypto/ec/ec_asn1.c b/deps/openssl/openssl/crypto/ec/ec_asn1.c
index ae5553985..175eec534 100644
--- a/deps/openssl/openssl/crypto/ec/ec_asn1.c
+++ b/deps/openssl/openssl/crypto/ec/ec_asn1.c
@@ -83,7 +83,7 @@ int EC_GROUP_get_basis_type(const EC_GROUP *group)
/* everything else is currently not supported */
return 0;
}
-
+#ifndef OPENSSL_NO_EC2M
int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
{
if (group == NULL)
@@ -101,7 +101,6 @@ int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
return 1;
}
-
int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
unsigned int *k2, unsigned int *k3)
{
@@ -124,7 +123,7 @@ int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
return 1;
}
-
+#endif
/* some structures needed for the asn1 encoding */
@@ -340,6 +339,12 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
}
}
else /* nid == NID_X9_62_characteristic_two_field */
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
+ goto err;
+ }
+#else
{
int field_type;
X9_62_CHARACTERISTIC_TWO *char_two;
@@ -419,6 +424,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
}
}
}
+#endif
ok = 1;
@@ -456,6 +462,7 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else /* nid == NID_X9_62_characteristic_two_field */
{
if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL))
@@ -464,7 +471,7 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
goto err;
}
}
-
+#endif
len_1 = (size_t)BN_num_bytes(tmp_1);
len_2 = (size_t)BN_num_bytes(tmp_2);
@@ -775,8 +782,13 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
/* get the field parameters */
tmp = OBJ_obj2nid(params->fieldID->fieldType);
-
if (tmp == NID_X9_62_characteristic_two_field)
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
+ goto err;
+ }
+#else
{
X9_62_CHARACTERISTIC_TWO *char_two;
@@ -862,6 +874,7 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
/* create the EC_GROUP structure */
ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
}
+#endif
else if (tmp == NID_X9_62_prime_field)
{
/* we have a curve over a prime field */
@@ -1065,6 +1078,7 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
if ((group = ec_asn1_pkparameters2group(params)) == NULL)
{
ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
+ ECPKPARAMETERS_free(params);
return NULL;
}
diff --git a/deps/openssl/openssl/crypto/ec/ec_curve.c b/deps/openssl/openssl/crypto/ec/ec_curve.c
index 23274e403..c72fb2697 100644
--- a/deps/openssl/openssl/crypto/ec/ec_curve.c
+++ b/deps/openssl/openssl/crypto/ec/ec_curve.c
@@ -3,7 +3,7 @@
* Written by Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2010 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
@@ -72,6 +72,7 @@
#include "ec_lcl.h"
#include <openssl/err.h>
#include <openssl/obj_mac.h>
+#include <openssl/opensslconf.h>
typedef struct {
int field_type, /* either NID_X9_62_prime_field or
@@ -703,6 +704,8 @@ static const struct { EC_CURVE_DATA h; unsigned char data[0+28*6]; }
0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
};
+#ifndef OPENSSL_NO_EC2M
+
/* characteristic two curves */
static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
_EC_SECG_CHAR2_113R1 = {
@@ -1300,7 +1303,7 @@ static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
{ 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76, /* seed */
0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD,
- 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
+ 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x07,
0x01,0x08,0xB3,0x9E,0x77,0xC4,0xB1,0x08,0xBE,0xD9, /* a */
@@ -1817,103 +1820,128 @@ static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
0xBA,0xFC,0xA7,0x5E }
};
+#endif
+
typedef struct _ec_list_element_st {
int nid;
const EC_CURVE_DATA *data;
+ const EC_METHOD *(*meth)(void);
const char *comment;
} ec_list_element;
static const ec_list_element curve_list[] = {
- /* prime field curves */
+ /* prime field curves */
/* secg curves */
- { NID_secp112r1, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"},
- { NID_secp112r2, &_EC_SECG_PRIME_112R2.h, "SECG curve over a 112 bit prime field"},
- { NID_secp128r1, &_EC_SECG_PRIME_128R1.h, "SECG curve over a 128 bit prime field"},
- { NID_secp128r2, &_EC_SECG_PRIME_128R2.h, "SECG curve over a 128 bit prime field"},
- { NID_secp160k1, &_EC_SECG_PRIME_160K1.h, "SECG curve over a 160 bit prime field"},
- { NID_secp160r1, &_EC_SECG_PRIME_160R1.h, "SECG curve over a 160 bit prime field"},
- { NID_secp160r2, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"},
+ { NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field" },
+ { NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0, "SECG curve over a 112 bit prime field" },
+ { NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0, "SECG curve over a 128 bit prime field" },
+ { NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0, "SECG curve over a 128 bit prime field" },
+ { NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0, "SECG curve over a 160 bit prime field" },
+ { NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0, "SECG curve over a 160 bit prime field" },
+ { NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field" },
/* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
- { NID_secp192k1, &_EC_SECG_PRIME_192K1.h, "SECG curve over a 192 bit prime field"},
- { NID_secp224k1, &_EC_SECG_PRIME_224K1.h, "SECG curve over a 224 bit prime field"},
- { NID_secp224r1, &_EC_NIST_PRIME_224.h, "NIST/SECG curve over a 224 bit prime field"},
- { NID_secp256k1, &_EC_SECG_PRIME_256K1.h, "SECG curve over a 256 bit prime field"},
+ { NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, "SECG curve over a 192 bit prime field" },
+ { NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field" },
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ { NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field" },
+#else
+ { NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field" },
+#endif
+ { NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field" },
/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
- { NID_secp384r1, &_EC_NIST_PRIME_384.h, "NIST/SECG curve over a 384 bit prime field"},
- { NID_secp521r1, &_EC_NIST_PRIME_521.h, "NIST/SECG curve over a 521 bit prime field"},
+ { NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, "NIST/SECG curve over a 384 bit prime field" },
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ { NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, "NIST/SECG curve over a 521 bit prime field" },
+#else
+ { NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, "NIST/SECG curve over a 521 bit prime field" },
+#endif
/* X9.62 curves */
- { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, "NIST/X9.62/SECG curve over a 192 bit prime field"},
- { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, "X9.62 curve over a 192 bit prime field"},
- { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, "X9.62 curve over a 192 bit prime field"},
- { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, "X9.62 curve over a 239 bit prime field"},
- { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, "X9.62 curve over a 239 bit prime field"},
- { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, "X9.62 curve over a 239 bit prime field"},
- { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, "X9.62/SECG curve over a 256 bit prime field"},
+ { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, "NIST/X9.62/SECG curve over a 192 bit prime field" },
+ { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0, "X9.62 curve over a 192 bit prime field" },
+ { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0, "X9.62 curve over a 192 bit prime field" },
+ { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, "X9.62 curve over a 239 bit prime field" },
+ { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, "X9.62 curve over a 239 bit prime field" },
+ { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field" },
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method, "X9.62/SECG curve over a 256 bit prime field" },
+#else
+ { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, "X9.62/SECG curve over a 256 bit prime field" },
+#endif
+#ifndef OPENSSL_NO_EC2M
/* characteristic two field curves */
/* NIST/SECG curves */
- { NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"},
- { NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, "SECG curve over a 113 bit binary field"},
- { NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, "SECG/WTLS curve over a 131 bit binary field"},
- { NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, "SECG curve over a 131 bit binary field"},
- { NID_sect163k1, &_EC_NIST_CHAR2_163K.h, "NIST/SECG/WTLS curve over a 163 bit binary field" },
- { NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, "SECG curve over a 163 bit binary field"},
- { NID_sect163r2, &_EC_NIST_CHAR2_163B.h, "NIST/SECG curve over a 163 bit binary field" },
- { NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, "SECG curve over a 193 bit binary field"},
- { NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, "SECG curve over a 193 bit binary field"},
- { NID_sect233k1, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field" },
- { NID_sect233r1, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field" },
- { NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, "SECG curve over a 239 bit binary field"},
- { NID_sect283k1, &_EC_NIST_CHAR2_283K.h, "NIST/SECG curve over a 283 bit binary field" },
- { NID_sect283r1, &_EC_NIST_CHAR2_283B.h, "NIST/SECG curve over a 283 bit binary field" },
- { NID_sect409k1, &_EC_NIST_CHAR2_409K.h, "NIST/SECG curve over a 409 bit binary field" },
- { NID_sect409r1, &_EC_NIST_CHAR2_409B.h, "NIST/SECG curve over a 409 bit binary field" },
- { NID_sect571k1, &_EC_NIST_CHAR2_571K.h, "NIST/SECG curve over a 571 bit binary field" },
- { NID_sect571r1, &_EC_NIST_CHAR2_571B.h, "NIST/SECG curve over a 571 bit binary field" },
+ { NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field" },
+ { NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0, "SECG curve over a 113 bit binary field" },
+ { NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0, "SECG/WTLS curve over a 131 bit binary field" },
+ { NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0, "SECG curve over a 131 bit binary field" },
+ { NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field" },
+ { NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0, "SECG curve over a 163 bit binary field" },
+ { NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, "NIST/SECG curve over a 163 bit binary field" },
+ { NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0, "SECG curve over a 193 bit binary field" },
+ { NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0, "SECG curve over a 193 bit binary field" },
+ { NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
+ { NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
+ { NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0, "SECG curve over a 239 bit binary field" },
+ { NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, "NIST/SECG curve over a 283 bit binary field" },
+ { NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, "NIST/SECG curve over a 283 bit binary field" },
+ { NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, "NIST/SECG curve over a 409 bit binary field" },
+ { NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, "NIST/SECG curve over a 409 bit binary field" },
+ { NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, "NIST/SECG curve over a 571 bit binary field" },
+ { NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, "NIST/SECG curve over a 571 bit binary field" },
/* X9.62 curves */
- { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"},
- { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, "X9.62 curve over a 163 bit binary field"},
- { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, "X9.62 curve over a 163 bit binary field"},
- { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, "X9.62 curve over a 176 bit binary field"},
- { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, "X9.62 curve over a 191 bit binary field"},
- { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, "X9.62 curve over a 191 bit binary field"},
- { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, "X9.62 curve over a 191 bit binary field"},
- { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, "X9.62 curve over a 208 bit binary field"},
- { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, "X9.62 curve over a 239 bit binary field"},
- { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, "X9.62 curve over a 239 bit binary field"},
- { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, "X9.62 curve over a 239 bit binary field"},
- { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, "X9.62 curve over a 272 bit binary field"},
- { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, "X9.62 curve over a 304 bit binary field"},
- { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, "X9.62 curve over a 359 bit binary field"},
- { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, "X9.62 curve over a 368 bit binary field"},
- { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, "X9.62 curve over a 431 bit binary field"},
+ { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field" },
+ { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0, "X9.62 curve over a 163 bit binary field" },
+ { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0, "X9.62 curve over a 163 bit binary field" },
+ { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0, "X9.62 curve over a 176 bit binary field" },
+ { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0, "X9.62 curve over a 191 bit binary field" },
+ { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0, "X9.62 curve over a 191 bit binary field" },
+ { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0, "X9.62 curve over a 191 bit binary field" },
+ { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0, "X9.62 curve over a 208 bit binary field" },
+ { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0, "X9.62 curve over a 239 bit binary field" },
+ { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0, "X9.62 curve over a 239 bit binary field" },
+ { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0, "X9.62 curve over a 239 bit binary field" },
+ { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0, "X9.62 curve over a 272 bit binary field" },
+ { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0, "X9.62 curve over a 304 bit binary field" },
+ { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0, "X9.62 curve over a 359 bit binary field" },
+ { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0, "X9.62 curve over a 368 bit binary field" },
+ { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0, "X9.62 curve over a 431 bit binary field" },
/* the WAP/WTLS curves
* [unlike SECG, spec has its own OIDs for curves from X9.62] */
- { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, "WTLS curve over a 113 bit binary field"},
- { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, "NIST/SECG/WTLS curve over a 163 bit binary field"},
- { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"},
- { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"},
- { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"},
- { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"},
- { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, "WTLS curve over a 112 bit prime field"},
- { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, "WTLS curve over a 160 bit prime field" },
- { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field"},
- { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field"},
- { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, "WTLS curvs over a 224 bit prime field"},
+ { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0, "WTLS curve over a 113 bit binary field" },
+ { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field" },
+ { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field" },
+ { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field" },
+#endif
+ { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field" },
+ { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field" },
+ { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0, "WTLS curve over a 112 bit prime field" },
+ { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, "WTLS curve over a 160 bit prime field" },
+#ifndef OPENSSL_NO_EC2M
+ { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
+ { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
+#endif
+ { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, "WTLS curvs over a 224 bit prime field" },
+#ifndef OPENSSL_NO_EC2M
/* IPSec curves */
- { NID_ipsec3, &_EC_IPSEC_155_ID3.h, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
- { NID_ipsec4, &_EC_IPSEC_185_ID4.h, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
+ { NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
+ "\tNot suitable for ECDSA.\n\tQuestionable extension field!" },
+ { NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
+ "\tNot suitable for ECDSA.\n\tQuestionable extension field!" },
+#endif
};
#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
-static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
+static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
{
EC_GROUP *group=NULL;
EC_POINT *P=NULL;
BN_CTX *ctx=NULL;
- BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL;
+ BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL;
int ok=0;
int seed_len,param_len;
+ const EC_METHOD *meth;
+ const EC_CURVE_DATA *data;
const unsigned char *params;
if ((ctx = BN_CTX_new()) == NULL)
@@ -1922,10 +1950,11 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
goto err;
}
+ data = curve.data;
seed_len = data->seed_len;
param_len = data->param_len;
- params = (const unsigned char *)(data+1); /* skip header */
- params += seed_len; /* skip seed */
+ params = (const unsigned char *)(data+1); /* skip header */
+ params += seed_len; /* skip seed */
if (!(p = BN_bin2bn(params+0*param_len, param_len, NULL))
|| !(a = BN_bin2bn(params+1*param_len, param_len, NULL))
@@ -1935,7 +1964,17 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
goto err;
}
- if (data->field_type == NID_X9_62_prime_field)
+ if (curve.meth != 0)
+ {
+ meth = curve.meth();
+ if (((group = EC_GROUP_new(meth)) == NULL) ||
+ (!(group->meth->group_set_curve(group, p, a, b, ctx))))
+ {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+ else if (data->field_type == NID_X9_62_prime_field)
{
if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL)
{
@@ -1943,6 +1982,7 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else /* field_type == NID_X9_62_characteristic_two_field */
{
if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL)
@@ -1951,20 +1991,21 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
goto err;
}
}
+#endif
if ((P = EC_POINT_new(group)) == NULL)
{
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
goto err;
}
-
+
if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL))
|| !(y = BN_bin2bn(params+4*param_len, param_len, NULL)))
{
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
goto err;
}
- if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx))
+ if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
{
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
goto err;
@@ -2025,7 +2066,7 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
for (i=0; i<curve_list_length; i++)
if (curve_list[i].nid == nid)
{
- ret = ec_group_new_from_data(curve_list[i].data);
+ ret = ec_group_new_from_data(curve_list[i]);
break;
}
diff --git a/deps/openssl/openssl/crypto/ec/ec_cvt.c b/deps/openssl/openssl/crypto/ec/ec_cvt.c
index d45640bab..bfcbab35f 100644
--- a/deps/openssl/openssl/crypto/ec/ec_cvt.c
+++ b/deps/openssl/openssl/crypto/ec/ec_cvt.c
@@ -78,7 +78,32 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
const EC_METHOD *meth;
EC_GROUP *ret;
+#if defined(OPENSSL_BN_ASM_MONT)
+ /*
+ * This might appear controversial, but the fact is that generic
+ * prime method was observed to deliver better performance even
+ * for NIST primes on a range of platforms, e.g.: 60%-15%
+ * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25%
+ * in 32-bit build and 35%--12% in 64-bit build on Core2...
+ * Coefficients are relative to optimized bn_nist.c for most
+ * intensive ECDSA verify and ECDH operations for 192- and 521-
+ * bit keys respectively. Choice of these boundary values is
+ * arguable, because the dependency of improvement coefficient
+ * from key length is not a "monotone" curve. For example while
+ * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's
+ * generally faster, sometimes "respectfully" faster, sometimes
+ * "tolerably" slower... What effectively happens is that loop
+ * with bn_mul_add_words is put against bn_mul_mont, and the
+ * latter "wins" on short vectors. Correct solution should be
+ * implementing dedicated NxN multiplication subroutines for
+ * small N. But till it materializes, let's stick to generic
+ * prime method...
+ * <appro>
+ */
+ meth = EC_GFp_mont_method();
+#else
meth = EC_GFp_nist_method();
+#endif
ret = EC_GROUP_new(meth);
if (ret == NULL)
@@ -122,7 +147,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
return ret;
}
-
+#ifndef OPENSSL_NO_EC2M
EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
const EC_METHOD *meth;
@@ -142,3 +167,4 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM
return ret;
}
+#endif
diff --git a/deps/openssl/openssl/crypto/ec/ec_err.c b/deps/openssl/openssl/crypto/ec/ec_err.c
index 84b483337..0d1939873 100644
--- a/deps/openssl/openssl/crypto/ec/ec_err.c
+++ b/deps/openssl/openssl/crypto/ec/ec_err.c
@@ -1,6 +1,6 @@
/* crypto/ec/ec_err.c */
/* ====================================================================
- * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -70,6 +70,7 @@
static ERR_STRING_DATA EC_str_functs[]=
{
+{ERR_FUNC(EC_F_BN_TO_FELEM), "BN_TO_FELEM"},
{ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"},
{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
@@ -112,6 +113,15 @@ static ERR_STRING_DATA EC_str_functs[]=
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE), "ec_GFp_mont_group_set_curve"},
{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP), "EC_GFP_MONT_GROUP_SET_CURVE_GFP"},
+{ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE), "ec_GFp_nistp224_group_set_curve"},
+{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"},
+{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp224_point_get_affine_coordinates"},
+{ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE), "ec_GFp_nistp256_group_set_curve"},
+{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"},
+{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp256_point_get_affine_coordinates"},
+{ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE), "ec_GFp_nistp521_group_set_curve"},
+{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"},
+{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp521_point_get_affine_coordinates"},
{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), "ec_GFp_nist_group_set_curve"},
@@ -154,6 +164,7 @@ static ERR_STRING_DATA EC_str_functs[]=
{ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
+{ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES), "EC_KEY_set_public_key_affine_coordinates"},
{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
@@ -184,6 +195,9 @@ static ERR_STRING_DATA EC_str_functs[]=
{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
+{ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "NISTP224_PRE_COMP_NEW"},
+{ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "NISTP256_PRE_COMP_NEW"},
+{ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "NISTP521_PRE_COMP_NEW"},
{ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"},
{ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"},
@@ -199,12 +213,15 @@ static ERR_STRING_DATA EC_str_reasons[]=
{
{ERR_REASON(EC_R_ASN1_ERROR) ,"asn1 error"},
{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD) ,"asn1 unknown field"},
+{ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE) ,"bignum out of range"},
{ERR_REASON(EC_R_BUFFER_TOO_SMALL) ,"buffer too small"},
+{ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE),"coordinates out of range"},
{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
{ERR_REASON(EC_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO) ,"discriminant is zero"},
{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"},
{ERR_REASON(EC_R_FIELD_TOO_LARGE) ,"field too large"},
+{ERR_REASON(EC_R_GF2M_NOT_SUPPORTED) ,"gf2m not supported"},
{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),"group2pkparameters failure"},
{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),"i2d ecpkparameters failure"},
{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS) ,"incompatible objects"},
@@ -239,6 +256,7 @@ static ERR_STRING_DATA EC_str_reasons[]=
{ERR_REASON(EC_R_UNKNOWN_GROUP) ,"unknown group"},
{ERR_REASON(EC_R_UNKNOWN_ORDER) ,"unknown order"},
{ERR_REASON(EC_R_UNSUPPORTED_FIELD) ,"unsupported field"},
+{ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS) ,"wrong curve parameters"},
{ERR_REASON(EC_R_WRONG_ORDER) ,"wrong order"},
{0,NULL}
};
diff --git a/deps/openssl/openssl/crypto/ec/ec_key.c b/deps/openssl/openssl/crypto/ec/ec_key.c
index 522802c07..7fa247593 100644
--- a/deps/openssl/openssl/crypto/ec/ec_key.c
+++ b/deps/openssl/openssl/crypto/ec/ec_key.c
@@ -64,7 +64,9 @@
#include <string.h>
#include "ec_lcl.h"
#include <openssl/err.h>
-#include <string.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
EC_KEY *EC_KEY_new(void)
{
@@ -78,6 +80,7 @@ EC_KEY *EC_KEY_new(void)
}
ret->version = 1;
+ ret->flags = 0;
ret->group = NULL;
ret->pub_key = NULL;
ret->priv_key= NULL;
@@ -197,6 +200,7 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
dest->enc_flag = src->enc_flag;
dest->conv_form = src->conv_form;
dest->version = src->version;
+ dest->flags = src->flags;
return dest;
}
@@ -237,6 +241,11 @@ int EC_KEY_generate_key(EC_KEY *eckey)
BIGNUM *priv_key = NULL, *order = NULL;
EC_POINT *pub_key = NULL;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_ec_key_generate_key(eckey);
+#endif
+
if (!eckey || !eckey->group)
{
ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
@@ -371,6 +380,82 @@ err:
return(ok);
}
+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y)
+ {
+ BN_CTX *ctx = NULL;
+ BIGNUM *tx, *ty;
+ EC_POINT *point = NULL;
+ int ok = 0, tmp_nid, is_char_two = 0;
+
+ if (!key || !key->group || !x || !y)
+ {
+ ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ ctx = BN_CTX_new();
+ if (!ctx)
+ goto err;
+
+ point = EC_POINT_new(key->group);
+
+ if (!point)
+ goto err;
+
+ tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
+
+ if (tmp_nid == NID_X9_62_characteristic_two_field)
+ is_char_two = 1;
+
+ tx = BN_CTX_get(ctx);
+ ty = BN_CTX_get(ctx);
+#ifndef OPENSSL_NO_EC2M
+ if (is_char_two)
+ {
+ if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
+ x, y, ctx))
+ goto err;
+ if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
+ tx, ty, ctx))
+ goto err;
+ }
+ else
+#endif
+ {
+ if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
+ x, y, ctx))
+ goto err;
+ if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
+ tx, ty, ctx))
+ goto err;
+ }
+ /* Check if retrieved coordinates match originals: if not values
+ * are out of range.
+ */
+ if (BN_cmp(x, tx) || BN_cmp(y, ty))
+ {
+ ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+ EC_R_COORDINATES_OUT_OF_RANGE);
+ goto err;
+ }
+
+ if (!EC_KEY_set_public_key(key, point))
+ goto err;
+
+ if (EC_KEY_check_key(key) == 0)
+ goto err;
+
+ ok = 1;
+
+ err:
+ if (ctx)
+ BN_CTX_free(ctx);
+ if (point)
+ EC_POINT_free(point);
+ return ok;
+
+ }
+
const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
{
return key->group;
@@ -435,18 +520,27 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
void *EC_KEY_get_key_method_data(EC_KEY *key,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
{
- return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+ void *ret;
+
+ CRYPTO_r_lock(CRYPTO_LOCK_EC);
+ ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+ CRYPTO_r_unlock(CRYPTO_LOCK_EC);
+
+ return ret;
}
-void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
{
EC_EXTRA_DATA *ex_data;
+
CRYPTO_w_lock(CRYPTO_LOCK_EC);
ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
if (ex_data == NULL)
EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
CRYPTO_w_unlock(CRYPTO_LOCK_EC);
+
+ return ex_data;
}
void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
@@ -461,3 +555,18 @@ int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
return 0;
return EC_GROUP_precompute_mult(key->group, ctx);
}
+
+int EC_KEY_get_flags(const EC_KEY *key)
+ {
+ return key->flags;
+ }
+
+void EC_KEY_set_flags(EC_KEY *key, int flags)
+ {
+ key->flags |= flags;
+ }
+
+void EC_KEY_clear_flags(EC_KEY *key, int flags)
+ {
+ key->flags &= ~flags;
+ }
diff --git a/deps/openssl/openssl/crypto/ec/ec_lcl.h b/deps/openssl/openssl/crypto/ec/ec_lcl.h
index 3e2c34b0b..da7967df3 100644
--- a/deps/openssl/openssl/crypto/ec/ec_lcl.h
+++ b/deps/openssl/openssl/crypto/ec/ec_lcl.h
@@ -3,7 +3,7 @@
* Originally written by Bodo Moeller for the OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2010 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
@@ -82,10 +82,15 @@
# endif
#endif
+/* Use default functions for poin2oct, oct2point and compressed coordinates */
+#define EC_FLAGS_DEFAULT_OCT 0x1
+
/* Structure details are not part of the exported interface,
* so all this may change in future versions. */
struct ec_method_st {
+ /* Various method flags */
+ int flags;
/* used by EC_METHOD_get_field_type: */
int field_type; /* a NID */
@@ -244,6 +249,7 @@ struct ec_key_st {
point_conversion_form_t conv_form;
int references;
+ int flags;
EC_EXTRA_DATA *method_data;
} /* EC_KEY */;
@@ -391,3 +397,50 @@ int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ec2_mult.c */
+int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+ size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
+
+#ifndef OPENSSL_EC_NISTP_64_GCC_128
+/* method functions in ecp_nistp224.c */
+int ec_GFp_nistp224_group_init(EC_GROUP *group);
+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ecp_nistp256.c */
+int ec_GFp_nistp256_group_init(EC_GROUP *group);
+int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
+int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ecp_nistp521.c */
+int ec_GFp_nistp521_group_init(EC_GROUP *group);
+int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
+int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
+
+/* utility functions in ecp_nistputil.c */
+void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
+ size_t felem_size, void *tmp_felems,
+ void (*felem_one)(void *out),
+ int (*felem_is_zero)(const void *in),
+ void (*felem_assign)(void *out, const void *in),
+ void (*felem_square)(void *out, const void *in),
+ void (*felem_mul)(void *out, const void *in1, const void *in2),
+ void (*felem_inv)(void *out, const void *in),
+ void (*felem_contract)(void *out, const void *in));
+void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in);
+#endif
diff --git a/deps/openssl/openssl/crypto/ec/ec_lib.c b/deps/openssl/openssl/crypto/ec/ec_lib.c
index dd7da0fcf..25247b580 100644
--- a/deps/openssl/openssl/crypto/ec/ec_lib.c
+++ b/deps/openssl/openssl/crypto/ec/ec_lib.c
@@ -425,7 +425,7 @@ int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *
return group->meth->group_get_curve(group, p, a, b, ctx);
}
-
+#ifndef OPENSSL_NO_EC2M
int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
if (group->meth->group_set_curve == 0)
@@ -446,7 +446,7 @@ int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM
}
return group->meth->group_get_curve(group, p, a, b, ctx);
}
-
+#endif
int EC_GROUP_get_degree(const EC_GROUP *group)
{
@@ -856,7 +856,7 @@ int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
}
-
+#ifndef OPENSSL_NO_EC2M
int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
{
@@ -872,7 +872,7 @@ int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
}
return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
}
-
+#endif
int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
@@ -890,7 +890,7 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *p
return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
}
-
+#ifndef OPENSSL_NO_EC2M
int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
{
@@ -906,75 +906,7 @@ int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *
}
return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
}
-
-
-int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
- const BIGNUM *x, int y_bit, BN_CTX *ctx)
- {
- if (group->meth->point_set_compressed_coordinates == 0)
- {
- ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- if (group->meth != point->meth)
- {
- ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
- return 0;
- }
- return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
- }
-
-
-int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
- const BIGNUM *x, int y_bit, BN_CTX *ctx)
- {
- if (group->meth->point_set_compressed_coordinates == 0)
- {
- ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- if (group->meth != point->meth)
- {
- ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
- return 0;
- }
- return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
- }
-
-
-size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
- unsigned char *buf, size_t len, BN_CTX *ctx)
- {
- if (group->meth->point2oct == 0)
- {
- ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- if (group->meth != point->meth)
- {
- ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
- return 0;
- }
- return group->meth->point2oct(group, point, form, buf, len, ctx);
- }
-
-
-int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
- const unsigned char *buf, size_t len, BN_CTX *ctx)
- {
- if (group->meth->oct2point == 0)
- {
- ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- if (group->meth != point->meth)
- {
- ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
- return 0;
- }
- return group->meth->oct2point(group, point, buf, len, ctx);
- }
-
+#endif
int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
{
diff --git a/deps/openssl/openssl/crypto/ec/ec_oct.c b/deps/openssl/openssl/crypto/ec/ec_oct.c
new file mode 100644
index 000000000..fd9db0798
--- /dev/null
+++ b/deps/openssl/openssl/crypto/ec/ec_oct.c
@@ -0,0 +1,199 @@
+/* crypto/ec/ec_lib.c */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Binary polynomial ECC support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/opensslv.h>
+
+#include "ec_lcl.h"
+
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x, int y_bit, BN_CTX *ctx)
+ {
+ if (group->meth->point_set_compressed_coordinates == 0
+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
+ {
+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth)
+ {
+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
+ {
+ if (group->meth->field_type == NID_X9_62_prime_field)
+ return ec_GFp_simple_set_compressed_coordinates(
+ group, point, x, y_bit, ctx);
+ else
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_GF2M_NOT_SUPPORTED);
+ return 0;
+ }
+#else
+ return ec_GF2m_simple_set_compressed_coordinates(
+ group, point, x, y_bit, ctx);
+#endif
+ }
+ return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
+ }
+
+#ifndef OPENSSL_NO_EC2M
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x, int y_bit, BN_CTX *ctx)
+ {
+ if (group->meth->point_set_compressed_coordinates == 0
+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
+ {
+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth)
+ {
+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
+ {
+ if (group->meth->field_type == NID_X9_62_prime_field)
+ return ec_GFp_simple_set_compressed_coordinates(
+ group, point, x, y_bit, ctx);
+ else
+ return ec_GF2m_simple_set_compressed_coordinates(
+ group, point, x, y_bit, ctx);
+ }
+ return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
+ }
+#endif
+
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *ctx)
+ {
+ if (group->meth->point2oct == 0
+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
+ {
+ ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth)
+ {
+ ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
+ {
+ if (group->meth->field_type == NID_X9_62_prime_field)
+ return ec_GFp_simple_point2oct(group, point,
+ form, buf, len, ctx);
+ else
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
+ return 0;
+ }
+#else
+ return ec_GF2m_simple_point2oct(group, point,
+ form, buf, len, ctx);
+#endif
+ }
+
+ return group->meth->point2oct(group, point, form, buf, len, ctx);
+ }
+
+
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
+ const unsigned char *buf, size_t len, BN_CTX *ctx)
+ {
+ if (group->meth->oct2point == 0
+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
+ {
+ ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth)
+ {
+ ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
+ {
+ if (group->meth->field_type == NID_X9_62_prime_field)
+ return ec_GFp_simple_oct2point(group, point,
+ buf, len, ctx);
+ else
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
+ return 0;
+ }
+#else
+ return ec_GF2m_simple_oct2point(group, point,
+ buf, len, ctx);
+#endif
+ }
+ return group->meth->oct2point(group, point, buf, len, ctx);
+ }
+
diff --git a/deps/openssl/openssl/crypto/ec/ec_pmeth.c b/deps/openssl/openssl/crypto/ec/ec_pmeth.c
index f433076ca..66ee397d8 100644
--- a/deps/openssl/openssl/crypto/ec/ec_pmeth.c
+++ b/deps/openssl/openssl/crypto/ec/ec_pmeth.c
@@ -188,7 +188,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
- /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is
+ /* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
* not an error, the result is truncated.
*/
@@ -221,6 +221,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_MD:
if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
diff --git a/deps/openssl/openssl/crypto/ec/eck_prn.c b/deps/openssl/openssl/crypto/ec/eck_prn.c
index 7d3e175ae..06de8f395 100644
--- a/deps/openssl/openssl/crypto/ec/eck_prn.c
+++ b/deps/openssl/openssl/crypto/ec/eck_prn.c
@@ -207,7 +207,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
-
+#ifndef OPENSSL_NO_EC2M
if (is_char_two)
{
if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
@@ -217,6 +217,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
}
}
else /* prime field */
+#endif
{
if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
{
diff --git a/deps/openssl/openssl/crypto/ec/ecp_mont.c b/deps/openssl/openssl/crypto/ec/ecp_mont.c
index 9fc4a466a..f04f132c7 100644
--- a/deps/openssl/openssl/crypto/ec/ecp_mont.c
+++ b/deps/openssl/openssl/crypto/ec/ecp_mont.c
@@ -63,12 +63,20 @@
#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
#include "ec_lcl.h"
const EC_METHOD *EC_GFp_mont_method(void)
{
+#ifdef OPENSSL_FIPS
+ return fips_ec_gfp_mont_method();
+#else
static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
ec_GFp_mont_group_init,
ec_GFp_mont_group_finish,
@@ -87,9 +95,7 @@ const EC_METHOD *EC_GFp_mont_method(void)
ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
- ec_GFp_simple_set_compressed_coordinates,
- ec_GFp_simple_point2oct,
- ec_GFp_simple_oct2point,
+ 0,0,0,
ec_GFp_simple_add,
ec_GFp_simple_dbl,
ec_GFp_simple_invert,
@@ -109,6 +115,7 @@ const EC_METHOD *EC_GFp_mont_method(void)
ec_GFp_mont_field_set_to_one };
return &ret;
+#endif
}
diff --git a/deps/openssl/openssl/crypto/ec/ecp_nist.c b/deps/openssl/openssl/crypto/ec/ecp_nist.c
index 2a5682ea4..aad2d5f44 100644
--- a/deps/openssl/openssl/crypto/ec/ecp_nist.c
+++ b/deps/openssl/openssl/crypto/ec/ecp_nist.c
@@ -67,9 +67,17 @@
#include <openssl/obj_mac.h>
#include "ec_lcl.h"
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
const EC_METHOD *EC_GFp_nist_method(void)
{
+#ifdef OPENSSL_FIPS
+ return fips_ec_gfp_nist_method();
+#else
static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
ec_GFp_simple_group_init,
ec_GFp_simple_group_finish,
@@ -88,9 +96,7 @@ const EC_METHOD *EC_GFp_nist_method(void)
ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
- ec_GFp_simple_set_compressed_coordinates,
- ec_GFp_simple_point2oct,
- ec_GFp_simple_oct2point,
+ 0,0,0,
ec_GFp_simple_add,
ec_GFp_simple_dbl,
ec_GFp_simple_invert,
@@ -110,6 +116,7 @@ const EC_METHOD *EC_GFp_nist_method(void)
0 /* field_set_to_one */ };
return &ret;
+#endif
}
int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
diff --git a/deps/openssl/openssl/crypto/ec/ecp_nistp224.c b/deps/openssl/openssl/crypto/ec/ecp_nistp224.c
new file mode 100644
index 000000000..b5ff56c25
--- /dev/null
+++ b/deps/openssl/openssl/crypto/ec/ecp_nistp224.c
@@ -0,0 +1,1658 @@
+/* crypto/ec/ecp_nistp224.c */
+/*
+ * Written by Emilia Kasper (Google) for the OpenSSL project.
+ */
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
+ *
+ * Inspired by Daniel J. Bernstein's public domain nistp224 implementation
+ * and Adam Langley's public domain 64-bit C implementation of curve25519
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+
+#ifndef OPENSSL_SYS_VMS
+#include <stdint.h>
+#else
+#include <inttypes.h>
+#endif
+
+#include <string.h>
+#include <openssl/err.h>
+#include "ec_lcl.h"
+
+#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+ /* even with gcc, the typedef won't work for 32-bit platforms */
+ typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
+#else
+ #error "Need GCC 3.1 or later to define type uint128_t"
+#endif
+
+typedef uint8_t u8;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+
+/******************************************************************************/
+/* INTERNAL REPRESENTATION OF FIELD ELEMENTS
+ *
+ * Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
+ * using 64-bit coefficients called 'limbs',
+ * and sometimes (for multiplication results) as
+ * b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + 2^336*b_6
+ * using 128-bit coefficients called 'widelimbs'.
+ * A 4-limb representation is an 'felem';
+ * a 7-widelimb representation is a 'widefelem'.
+ * Even within felems, bits of adjacent limbs overlap, and we don't always
+ * reduce the representations: we ensure that inputs to each felem
+ * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60,
+ * and fit into a 128-bit word without overflow. The coefficients are then
+ * again partially reduced to obtain an felem satisfying a_i < 2^57.
+ * We only reduce to the unique minimal representation at the end of the
+ * computation.
+ */
+
+typedef uint64_t limb;
+typedef uint128_t widelimb;
+
+typedef limb felem[4];
+typedef widelimb widefelem[7];
+
+/* Field element represented as a byte arrary.
+ * 28*8 = 224 bits is also the group order size for the elliptic curve,
+ * and we also use this type for scalars for point multiplication.
+ */
+typedef u8 felem_bytearray[28];
+
+static const felem_bytearray nistp224_curve_params[5] = {
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE},
+ {0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */
+ 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
+ 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4},
+ {0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */
+ 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
+ 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21},
+ {0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */
+ 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
+ 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34}
+};
+
+/* Precomputed multiples of the standard generator
+ * Points are given in coordinates (X, Y, Z) where Z normally is 1
+ * (0 for the point at infinity).
+ * For each field element, slice a_0 is word 0, etc.
+ *
+ * The table has 2 * 16 elements, starting with the following:
+ * index | bits | point
+ * ------+---------+------------------------------
+ * 0 | 0 0 0 0 | 0G
+ * 1 | 0 0 0 1 | 1G
+ * 2 | 0 0 1 0 | 2^56G
+ * 3 | 0 0 1 1 | (2^56 + 1)G
+ * 4 | 0 1 0 0 | 2^112G
+ * 5 | 0 1 0 1 | (2^112 + 1)G
+ * 6 | 0 1 1 0 | (2^112 + 2^56)G
+ * 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
+ * 8 | 1 0 0 0 | 2^168G
+ * 9 | 1 0 0 1 | (2^168 + 1)G
+ * 10 | 1 0 1 0 | (2^168 + 2^56)G
+ * 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
+ * 12 | 1 1 0 0 | (2^168 + 2^112)G
+ * 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
+ * 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
+ * 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
+ * followed by a copy of this with each element multiplied by 2^28.
+ *
+ * The reason for this is so that we can clock bits into four different
+ * locations when doing simple scalar multiplies against the base point,
+ * and then another four locations using the second 16 elements.
+ */
+static const felem gmul[2][16][3] =
+{{{{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+ {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
+ {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
+ {1, 0, 0, 0}},
+ {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
+ {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
+ {1, 0, 0, 0}},
+ {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
+ {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
+ {1, 0, 0, 0}},
+ {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
+ {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
+ {1, 0, 0, 0}},
+ {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
+ {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
+ {1, 0, 0, 0}},
+ {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
+ {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
+ {1, 0, 0, 0}},
+ {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
+ {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
+ {1, 0, 0, 0}},
+ {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
+ {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
+ {1, 0, 0, 0}},
+ {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
+ {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
+ {1, 0, 0, 0}},
+ {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
+ {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
+ {1, 0, 0, 0}},
+ {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
+ {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
+ {1, 0, 0, 0}},
+ {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
+ {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
+ {1, 0, 0, 0}},
+ {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
+ {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
+ {1, 0, 0, 0}},
+ {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
+ {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
+ {1, 0, 0, 0}},
+ {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
+ {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
+ {1, 0, 0, 0}}},
+ {{{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+ {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
+ {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
+ {1, 0, 0, 0}},
+ {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
+ {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
+ {1, 0, 0, 0}},
+ {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
+ {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
+ {1, 0, 0, 0}},
+ {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
+ {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
+ {1, 0, 0, 0}},
+ {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
+ {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
+ {1, 0, 0, 0}},
+ {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
+ {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
+ {1, 0, 0, 0}},
+ {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
+ {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
+ {1, 0, 0, 0}},
+ {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
+ {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
+ {1, 0, 0, 0}},
+ {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
+ {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
+ {1, 0, 0, 0}},
+ {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
+ {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
+ {1, 0, 0, 0}},
+ {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
+ {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
+ {1, 0, 0, 0}},
+ {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
+ {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
+ {1, 0, 0, 0}},
+ {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
+ {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
+ {1, 0, 0, 0}},
+ {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
+ {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
+ {1, 0, 0, 0}},
+ {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
+ {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
+ {1, 0, 0, 0}}}};
+
+/* Precomputation for the group generator. */
+typedef struct {
+ felem g_pre_comp[2][16][3];
+ int references;
+} NISTP224_PRE_COMP;
+
+const EC_METHOD *EC_GFp_nistp224_method(void)
+ {
+ static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
+ NID_X9_62_prime_field,
+ ec_GFp_nistp224_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_nist_group_copy,
+ ec_GFp_nistp224_group_set_curve,
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+ ec_GFp_simple_point_copy,
+ ec_GFp_simple_point_set_to_infinity,
+ ec_GFp_simple_set_Jprojective_coordinates_GFp,
+ ec_GFp_simple_get_Jprojective_coordinates_GFp,
+ ec_GFp_simple_point_set_affine_coordinates,
+ ec_GFp_nistp224_point_get_affine_coordinates,
+ 0 /* point_set_compressed_coordinates */,
+ 0 /* point2oct */,
+ 0 /* oct2point */,
+ ec_GFp_simple_add,
+ ec_GFp_simple_dbl,
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
+ ec_GFp_simple_cmp,
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ ec_GFp_nistp224_points_mul,
+ ec_GFp_nistp224_precompute_mult,
+ ec_GFp_nistp224_have_precompute_mult,
+ ec_GFp_nist_field_mul,
+ ec_GFp_nist_field_sqr,
+ 0 /* field_div */,
+ 0 /* field_encode */,
+ 0 /* field_decode */,
+ 0 /* field_set_to_one */ };
+
+ return &ret;
+ }
+
+/* Helper functions to convert field elements to/from internal representation */
+static void bin28_to_felem(felem out, const u8 in[28])
+ {
+ out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
+ out[1] = (*((const uint64_t *)(in+7))) & 0x00ffffffffffffff;
+ out[2] = (*((const uint64_t *)(in+14))) & 0x00ffffffffffffff;
+ out[3] = (*((const uint64_t *)(in+21))) & 0x00ffffffffffffff;
+ }
+
+static void felem_to_bin28(u8 out[28], const felem in)
+ {
+ unsigned i;
+ for (i = 0; i < 7; ++i)
+ {
+ out[i] = in[0]>>(8*i);
+ out[i+7] = in[1]>>(8*i);
+ out[i+14] = in[2]>>(8*i);
+ out[i+21] = in[3]>>(8*i);
+ }
+ }
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len)
+ {
+ unsigned i;
+ for (i = 0; i < len; ++i)
+ out[i] = in[len-1-i];
+ }
+
+/* From OpenSSL BIGNUM to internal representation */
+static int BN_to_felem(felem out, const BIGNUM *bn)
+ {
+ felem_bytearray b_in;
+ felem_bytearray b_out;
+ unsigned num_bytes;
+
+ /* BN_bn2bin eats leading zeroes */
+ memset(b_out, 0, sizeof b_out);
+ num_bytes = BN_num_bytes(bn);
+ if (num_bytes > sizeof b_out)
+ {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ if (BN_is_negative(bn))
+ {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ num_bytes = BN_bn2bin(bn, b_in);
+ flip_endian(b_out, b_in, num_bytes);
+ bin28_to_felem(out, b_out);
+ return 1;
+ }
+
+/* From internal representation to OpenSSL BIGNUM */
+static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
+ {
+ felem_bytearray b_in, b_out;
+ felem_to_bin28(b_in, in);
+ flip_endian(b_out, b_in, sizeof b_out);
+ return BN_bin2bn(b_out, sizeof b_out, out);
+ }
+
+/******************************************************************************/
+/* FIELD OPERATIONS
+ *
+ * Field operations, using the internal representation of field elements.
+ * NB! These operations are specific to our point multiplication and cannot be
+ * expected to be correct in general - e.g., multiplication with a large scalar
+ * will cause an overflow.
+ *
+ */
+
+static void felem_one(felem out)
+ {
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 0;
+ out[3] = 0;
+ }
+
+static void felem_assign(felem out, const felem in)
+ {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ }
+
+/* Sum two field elements: out += in */
+static void felem_sum(felem out, const felem in)
+ {
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+ }
+
+/* Get negative value: out = -in */
+/* Assumes in[i] < 2^57 */
+static void felem_neg(felem out, const felem in)
+ {
+ static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
+ static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
+ static const limb two58m42m2 = (((limb) 1) << 58) -
+ (((limb) 1) << 42) - (((limb) 1) << 2);
+
+ /* Set to 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] = two58p2 - in[0];
+ out[1] = two58m42m2 - in[1];
+ out[2] = two58m2 - in[2];
+ out[3] = two58m2 - in[3];
+ }
+
+/* Subtract field elements: out -= in */
+/* Assumes in[i] < 2^57 */
+static void felem_diff(felem out, const felem in)
+ {
+ static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
+ static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
+ static const limb two58m42m2 = (((limb) 1) << 58) -
+ (((limb) 1) << 42) - (((limb) 1) << 2);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two58p2;
+ out[1] += two58m42m2;
+ out[2] += two58m2;
+ out[3] += two58m2;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ }
+
+/* Subtract in unreduced 128-bit mode: out -= in */
+/* Assumes in[i] < 2^119 */
+static void widefelem_diff(widefelem out, const widefelem in)
+ {
+ static const widelimb two120 = ((widelimb) 1) << 120;
+ static const widelimb two120m64 = (((widelimb) 1) << 120) -
+ (((widelimb) 1) << 64);
+ static const widelimb two120m104m64 = (((widelimb) 1) << 120) -
+ (((widelimb) 1) << 104) - (((widelimb) 1) << 64);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two120;
+ out[1] += two120m64;
+ out[2] += two120m64;
+ out[3] += two120;
+ out[4] += two120m104m64;
+ out[5] += two120m64;
+ out[6] += two120m64;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ out[4] -= in[4];
+ out[5] -= in[5];
+ out[6] -= in[6];
+ }
+
+/* Subtract in mixed mode: out128 -= in64 */
+/* in[i] < 2^63 */
+static void felem_diff_128_64(widefelem out, const felem in)
+ {
+ static const widelimb two64p8 = (((widelimb) 1) << 64) +
+ (((widelimb) 1) << 8);
+ static const widelimb two64m8 = (((widelimb) 1) << 64) -
+ (((widelimb) 1) << 8);
+ static const widelimb two64m48m8 = (((widelimb) 1) << 64) -
+ (((widelimb) 1) << 48) - (((widelimb) 1) << 8);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two64p8;
+ out[1] += two64m48m8;
+ out[2] += two64m8;
+ out[3] += two64m8;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ }
+
+/* Multiply a field element by a scalar: out = out * scalar
+ * The scalars we actually use are small, so results fit without overflow */
+static void felem_scalar(felem out, const limb scalar)
+ {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ }
+
+/* Multiply an unreduced field element by a scalar: out = out * scalar
+ * The scalars we actually use are small, so results fit without overflow */
+static void widefelem_scalar(widefelem out, const widelimb scalar)
+ {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+ }
+
+/* Square a field element: out = in^2 */
+static void felem_square(widefelem out, const felem in)
+ {
+ limb tmp0, tmp1, tmp2;
+ tmp0 = 2 * in[0]; tmp1 = 2 * in[1]; tmp2 = 2 * in[2];
+ out[0] = ((widelimb) in[0]) * in[0];
+ out[1] = ((widelimb) in[0]) * tmp1;
+ out[2] = ((widelimb) in[0]) * tmp2 + ((widelimb) in[1]) * in[1];
+ out[3] = ((widelimb) in[3]) * tmp0 +
+ ((widelimb) in[1]) * tmp2;
+ out[4] = ((widelimb) in[3]) * tmp1 + ((widelimb) in[2]) * in[2];
+ out[5] = ((widelimb) in[3]) * tmp2;
+ out[6] = ((widelimb) in[3]) * in[3];
+ }
+
+/* Multiply two field elements: out = in1 * in2 */
+static void felem_mul(widefelem out, const felem in1, const felem in2)
+ {
+ out[0] = ((widelimb) in1[0]) * in2[0];
+ out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0];
+ out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] +
+ ((widelimb) in1[2]) * in2[0];
+ out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] +
+ ((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0];
+ out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] +
+ ((widelimb) in1[3]) * in2[1];
+ out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2];
+ out[6] = ((widelimb) in1[3]) * in2[3];
+ }
+
+/* Reduce seven 128-bit coefficients to four 64-bit coefficients.
+ * Requires in[i] < 2^126,
+ * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */
+static void felem_reduce(felem out, const widefelem in)
+ {
+ static const widelimb two127p15 = (((widelimb) 1) << 127) +
+ (((widelimb) 1) << 15);
+ static const widelimb two127m71 = (((widelimb) 1) << 127) -
+ (((widelimb) 1) << 71);
+ static const widelimb two127m71m55 = (((widelimb) 1) << 127) -
+ (((widelimb) 1) << 71) - (((widelimb) 1) << 55);
+ widelimb output[5];
+
+ /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */
+ output[0] = in[0] + two127p15;
+ output[1] = in[1] + two127m71m55;
+ output[2] = in[2] + two127m71;
+ output[3] = in[3];
+ output[4] = in[4];
+
+ /* Eliminate in[4], in[5], in[6] */
+ output[4] += in[6] >> 16;
+ output[3] += (in[6] & 0xffff) << 40;
+ output[2] -= in[6];
+
+ output[3] += in[5] >> 16;
+ output[2] += (in[5] & 0xffff) << 40;
+ output[1] -= in[5];
+
+ output[2] += output[4] >> 16;
+ output[1] += (output[4] & 0xffff) << 40;
+ output[0] -= output[4];
+
+ /* Carry 2 -> 3 -> 4 */
+ output[3] += output[2] >> 56;
+ output[2] &= 0x00ffffffffffffff;
+
+ output[4] = output[3] >> 56;
+ output[3] &= 0x00ffffffffffffff;
+
+ /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */
+
+ /* Eliminate output[4] */
+ output[2] += output[4] >> 16;
+ /* output[2] < 2^56 + 2^56 = 2^57 */
+ output[1] += (output[4] & 0xffff) << 40;
+ output[0] -= output[4];
+
+ /* Carry 0 -> 1 -> 2 -> 3 */
+ output[1] += output[0] >> 56;
+ out[0] = output[0] & 0x00ffffffffffffff;
+
+ output[2] += output[1] >> 56;
+ /* output[2] < 2^57 + 2^72 */
+ out[1] = output[1] & 0x00ffffffffffffff;
+ output[3] += output[2] >> 56;
+ /* output[3] <= 2^56 + 2^16 */
+ out[2] = output[2] & 0x00ffffffffffffff;
+
+ /* out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
+ * out[3] <= 2^56 + 2^16 (due to final carry),
+ * so out < 2*p */
+ out[3] = output[3];
+ }
+
+static void felem_square_reduce(felem out, const felem in)
+ {
+ widefelem tmp;
+ felem_square(tmp, in);
+ felem_reduce(out, tmp);
+ }
+
+static void felem_mul_reduce(felem out, const felem in1, const felem in2)
+ {
+ widefelem tmp;
+ felem_mul(tmp, in1, in2);
+ felem_reduce(out, tmp);
+ }
+
+/* Reduce to unique minimal representation.
+ * Requires 0 <= in < 2*p (always call felem_reduce first) */
+static void felem_contract(felem out, const felem in)
+ {
+ static const int64_t two56 = ((limb) 1) << 56;
+ /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */
+ /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */
+ int64_t tmp[4], a;
+ tmp[0] = in[0];
+ tmp[1] = in[1];
+ tmp[2] = in[2];
+ tmp[3] = in[3];
+ /* Case 1: a = 1 iff in >= 2^224 */
+ a = (in[3] >> 56);
+ tmp[0] -= a;
+ tmp[1] += a << 40;
+ tmp[3] &= 0x00ffffffffffffff;
+ /* Case 2: a = 0 iff p <= in < 2^224, i.e.,
+ * the high 128 bits are all 1 and the lower part is non-zero */
+ a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
+ (((int64_t)(in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
+ a &= 0x00ffffffffffffff;
+ /* turn a into an all-one mask (if a = 0) or an all-zero mask */
+ a = (a - 1) >> 63;
+ /* subtract 2^224 - 2^96 + 1 if a is all-one*/
+ tmp[3] &= a ^ 0xffffffffffffffff;
+ tmp[2] &= a ^ 0xffffffffffffffff;
+ tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
+ tmp[0] -= 1 & a;
+
+ /* eliminate negative coefficients: if tmp[0] is negative, tmp[1] must
+ * be non-zero, so we only need one step */
+ a = tmp[0] >> 63;
+ tmp[0] += two56 & a;
+ tmp[1] -= 1 & a;
+
+ /* carry 1 -> 2 -> 3 */
+ tmp[2] += tmp[1] >> 56;
+ tmp[1] &= 0x00ffffffffffffff;
+
+ tmp[3] += tmp[2] >> 56;
+ tmp[2] &= 0x00ffffffffffffff;
+
+ /* Now 0 <= out < p */
+ out[0] = tmp[0];
+ out[1] = tmp[1];
+ out[2] = tmp[2];
+ out[3] = tmp[3];
+ }
+
+/* Zero-check: returns 1 if input is 0, and 0 otherwise.
+ * We know that field elements are reduced to in < 2^225,
+ * so we only need to check three cases: 0, 2^224 - 2^96 + 1,
+ * and 2^225 - 2^97 + 2 */
+static limb felem_is_zero(const felem in)
+ {
+ limb zero, two224m96p1, two225m97p2;
+
+ zero = in[0] | in[1] | in[2] | in[3];
+ zero = (((int64_t)(zero) - 1) >> 63) & 1;
+ two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000)
+ | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x00ffffffffffffff);
+ two224m96p1 = (((int64_t)(two224m96p1) - 1) >> 63) & 1;
+ two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000)
+ | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x01ffffffffffffff);
+ two225m97p2 = (((int64_t)(two225m97p2) - 1) >> 63) & 1;
+ return (zero | two224m96p1 | two225m97p2);
+ }
+
+static limb felem_is_zero_int(const felem in)
+ {
+ return (int) (felem_is_zero(in) & ((limb)1));
+ }
+
+/* Invert a field element */
+/* Computation chain copied from djb's code */
+static void felem_inv(felem out, const felem in)
+ {
+ felem ftmp, ftmp2, ftmp3, ftmp4;
+ widefelem tmp;
+ unsigned i;
+
+ felem_square(tmp, in); felem_reduce(ftmp, tmp); /* 2 */
+ felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp); /* 2^2 - 1 */
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^3 - 2 */
+ felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp); /* 2^3 - 1 */
+ felem_square(tmp, ftmp); felem_reduce(ftmp2, tmp); /* 2^4 - 2 */
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^5 - 4 */
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^6 - 8 */
+ felem_mul(tmp, ftmp2, ftmp); felem_reduce(ftmp, tmp); /* 2^6 - 1 */
+ felem_square(tmp, ftmp); felem_reduce(ftmp2, tmp); /* 2^7 - 2 */
+ for (i = 0; i < 5; ++i) /* 2^12 - 2^6 */
+ {
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp); felem_reduce(ftmp2, tmp); /* 2^12 - 1 */
+ felem_square(tmp, ftmp2); felem_reduce(ftmp3, tmp); /* 2^13 - 2 */
+ for (i = 0; i < 11; ++i) /* 2^24 - 2^12 */
+ {
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp2, tmp); /* 2^24 - 1 */
+ felem_square(tmp, ftmp2); felem_reduce(ftmp3, tmp); /* 2^25 - 2 */
+ for (i = 0; i < 23; ++i) /* 2^48 - 2^24 */
+ {
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^48 - 1 */
+ felem_square(tmp, ftmp3); felem_reduce(ftmp4, tmp); /* 2^49 - 2 */
+ for (i = 0; i < 47; ++i) /* 2^96 - 2^48 */
+ {
+ felem_square(tmp, ftmp4); felem_reduce(ftmp4, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp4); felem_reduce(ftmp3, tmp); /* 2^96 - 1 */
+ felem_square(tmp, ftmp3); felem_reduce(ftmp4, tmp); /* 2^97 - 2 */
+ for (i = 0; i < 23; ++i) /* 2^120 - 2^24 */
+ {
+ felem_square(tmp, ftmp4); felem_reduce(ftmp4, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp4); felem_reduce(ftmp2, tmp); /* 2^120 - 1 */
+ for (i = 0; i < 6; ++i) /* 2^126 - 2^6 */
+ {
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp); felem_reduce(ftmp, tmp); /* 2^126 - 1 */
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^127 - 2 */
+ felem_mul(tmp, ftmp, in); felem_reduce(ftmp, tmp); /* 2^127 - 1 */
+ for (i = 0; i < 97; ++i) /* 2^224 - 2^97 */
+ {
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
+ }
+ felem_mul(tmp, ftmp, ftmp3); felem_reduce(out, tmp); /* 2^224 - 2^96 - 1 */
+ }
+
+/* Copy in constant time:
+ * if icopy == 1, copy in to out,
+ * if icopy == 0, copy out to itself. */
+static void
+copy_conditional(felem out, const felem in, limb icopy)
+ {
+ unsigned i;
+ /* icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one */
+ const limb copy = -icopy;
+ for (i = 0; i < 4; ++i)
+ {
+ const limb tmp = copy & (in[i] ^ out[i]);
+ out[i] ^= tmp;
+ }
+ }
+
+/******************************************************************************/
+/* ELLIPTIC CURVE POINT OPERATIONS
+ *
+ * Points are represented in Jacobian projective coordinates:
+ * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
+ * or to the point at infinity if Z == 0.
+ *
+ */
+
+/* Double an elliptic curve point:
+ * (X', Y', Z') = 2 * (X, Y, Z), where
+ * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
+ * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
+ * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
+ * while x_out == y_in is not (maybe this works, but it's not tested). */
+static void
+point_double(felem x_out, felem y_out, felem z_out,
+ const felem x_in, const felem y_in, const felem z_in)
+ {
+ widefelem tmp, tmp2;
+ felem delta, gamma, beta, alpha, ftmp, ftmp2;
+
+ felem_assign(ftmp, x_in);
+ felem_assign(ftmp2, x_in);
+
+ /* delta = z^2 */
+ felem_square(tmp, z_in);
+ felem_reduce(delta, tmp);
+
+ /* gamma = y^2 */
+ felem_square(tmp, y_in);
+ felem_reduce(gamma, tmp);
+
+ /* beta = x*gamma */
+ felem_mul(tmp, x_in, gamma);
+ felem_reduce(beta, tmp);
+
+ /* alpha = 3*(x-delta)*(x+delta) */
+ felem_diff(ftmp, delta);
+ /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */
+ felem_sum(ftmp2, delta);
+ /* ftmp2[i] < 2^57 + 2^57 = 2^58 */
+ felem_scalar(ftmp2, 3);
+ /* ftmp2[i] < 3 * 2^58 < 2^60 */
+ felem_mul(tmp, ftmp, ftmp2);
+ /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */
+ felem_reduce(alpha, tmp);
+
+ /* x' = alpha^2 - 8*beta */
+ felem_square(tmp, alpha);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+ felem_assign(ftmp, beta);
+ felem_scalar(ftmp, 8);
+ /* ftmp[i] < 8 * 2^57 = 2^60 */
+ felem_diff_128_64(tmp, ftmp);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(x_out, tmp);
+
+ /* z' = (y + z)^2 - gamma - delta */
+ felem_sum(delta, gamma);
+ /* delta[i] < 2^57 + 2^57 = 2^58 */
+ felem_assign(ftmp, y_in);
+ felem_sum(ftmp, z_in);
+ /* ftmp[i] < 2^57 + 2^57 = 2^58 */
+ felem_square(tmp, ftmp);
+ /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */
+ felem_diff_128_64(tmp, delta);
+ /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */
+ felem_reduce(z_out, tmp);
+
+ /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+ felem_scalar(beta, 4);
+ /* beta[i] < 4 * 2^57 = 2^59 */
+ felem_diff(beta, x_out);
+ /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */
+ felem_mul(tmp, alpha, beta);
+ /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */
+ felem_square(tmp2, gamma);
+ /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */
+ widefelem_scalar(tmp2, 8);
+ /* tmp2[i] < 8 * 2^116 = 2^119 */
+ widefelem_diff(tmp, tmp2);
+ /* tmp[i] < 2^119 + 2^120 < 2^121 */
+ felem_reduce(y_out, tmp);
+ }
+
+/* Add two elliptic curve points:
+ * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
+ * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
+ * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
+ * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - X_3) -
+ * Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
+ * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
+ *
+ * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0.
+ */
+
+/* This function is not entirely constant-time:
+ * it includes a branch for checking whether the two input points are equal,
+ * (while not equal to the point at infinity).
+ * This case never happens during single point multiplication,
+ * so there is no timing leak for ECDH or ECDSA signing. */
+static void point_add(felem x3, felem y3, felem z3,
+ const felem x1, const felem y1, const felem z1,
+ const int mixed, const felem x2, const felem y2, const felem z2)
+ {
+ felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
+ widefelem tmp, tmp2;
+ limb z1_is_zero, z2_is_zero, x_equal, y_equal;
+
+ if (!mixed)
+ {
+ /* ftmp2 = z2^2 */
+ felem_square(tmp, z2);
+ felem_reduce(ftmp2, tmp);
+
+ /* ftmp4 = z2^3 */
+ felem_mul(tmp, ftmp2, z2);
+ felem_reduce(ftmp4, tmp);
+
+ /* ftmp4 = z2^3*y1 */
+ felem_mul(tmp2, ftmp4, y1);
+ felem_reduce(ftmp4, tmp2);
+
+ /* ftmp2 = z2^2*x1 */
+ felem_mul(tmp2, ftmp2, x1);
+ felem_reduce(ftmp2, tmp2);
+ }
+ else
+ {
+ /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
+
+ /* ftmp4 = z2^3*y1 */
+ felem_assign(ftmp4, y1);
+
+ /* ftmp2 = z2^2*x1 */
+ felem_assign(ftmp2, x1);
+ }
+
+ /* ftmp = z1^2 */
+ felem_square(tmp, z1);
+ felem_reduce(ftmp, tmp);
+
+ /* ftmp3 = z1^3 */
+ felem_mul(tmp, ftmp, z1);
+ felem_reduce(ftmp3, tmp);
+
+ /* tmp = z1^3*y2 */
+ felem_mul(tmp, ftmp3, y2);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* ftmp3 = z1^3*y2 - z2^3*y1 */
+ felem_diff_128_64(tmp, ftmp4);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(ftmp3, tmp);
+
+ /* tmp = z1^2*x2 */
+ felem_mul(tmp, ftmp, x2);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* ftmp = z1^2*x2 - z2^2*x1 */
+ felem_diff_128_64(tmp, ftmp2);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(ftmp, tmp);
+
+ /* the formulae are incorrect if the points are equal
+ * so we check for this and do doubling if this happens */
+ x_equal = felem_is_zero(ftmp);
+ y_equal = felem_is_zero(ftmp3);
+ z1_is_zero = felem_is_zero(z1);
+ z2_is_zero = felem_is_zero(z2);
+ /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
+ if (x_equal && y_equal && !z1_is_zero && !z2_is_zero)
+ {
+ point_double(x3, y3, z3, x1, y1, z1);
+ return;
+ }
+
+ /* ftmp5 = z1*z2 */
+ if (!mixed)
+ {
+ felem_mul(tmp, z1, z2);
+ felem_reduce(ftmp5, tmp);
+ }
+ else
+ {
+ /* special case z2 = 0 is handled later */
+ felem_assign(ftmp5, z1);
+ }
+
+ /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */
+ felem_mul(tmp, ftmp, ftmp5);
+ felem_reduce(z_out, tmp);
+
+ /* ftmp = (z1^2*x2 - z2^2*x1)^2 */
+ felem_assign(ftmp5, ftmp);
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+
+ /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */
+ felem_mul(tmp, ftmp, ftmp5);
+ felem_reduce(ftmp5, tmp);
+
+ /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp2, tmp);
+
+ /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
+ felem_mul(tmp, ftmp4, ftmp5);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */
+ felem_square(tmp2, ftmp3);
+ /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */
+ felem_diff_128_64(tmp2, ftmp5);
+ /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */
+
+ /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_assign(ftmp5, ftmp2);
+ felem_scalar(ftmp5, 2);
+ /* ftmp5[i] < 2 * 2^57 = 2^58 */
+
+ /* x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
+ 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_diff_128_64(tmp2, ftmp5);
+ /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */
+ felem_reduce(x_out, tmp2);
+
+ /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */
+ felem_diff(ftmp2, x_out);
+ /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) */
+ felem_mul(tmp2, ftmp3, ftmp2);
+ /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */
+
+ /* y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
+ z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
+ widefelem_diff(tmp2, tmp);
+ /* tmp2[i] < 2^118 + 2^120 < 2^121 */
+ felem_reduce(y_out, tmp2);
+
+ /* the result (x_out, y_out, z_out) is incorrect if one of the inputs is
+ * the point at infinity, so we need to check for this separately */
+
+ /* if point 1 is at infinity, copy point 2 to output, and vice versa */
+ copy_conditional(x_out, x2, z1_is_zero);
+ copy_conditional(x_out, x1, z2_is_zero);
+ copy_conditional(y_out, y2, z1_is_zero);
+ copy_conditional(y_out, y1, z2_is_zero);
+ copy_conditional(z_out, z2, z1_is_zero);
+ copy_conditional(z_out, z1, z2_is_zero);
+ felem_assign(x3, x_out);
+ felem_assign(y3, y_out);
+ felem_assign(z3, z_out);
+ }
+
+/* select_point selects the |idx|th point from a precomputation table and
+ * copies it to out. */
+static void select_point(const u64 idx, unsigned int size, const felem pre_comp[/*size*/][3], felem out[3])
+ {
+ unsigned i, j;
+ limb *outlimbs = &out[0][0];
+ memset(outlimbs, 0, 3 * sizeof(felem));
+
+ for (i = 0; i < size; i++)
+ {
+ const limb *inlimbs = &pre_comp[i][0][0];
+ u64 mask = i ^ idx;
+ mask |= mask >> 4;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (j = 0; j < 4 * 3; j++)
+ outlimbs[j] |= inlimbs[j] & mask;
+ }
+ }
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, unsigned i)
+ {
+ if (i >= 224)
+ return 0;
+ return (in[i >> 3] >> (i & 7)) & 1;
+ }
+
+/* Interleaved point multiplication using precomputed point multiples:
+ * The small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[],
+ * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
+ * of the generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
+static void batch_mul(felem x_out, felem y_out, felem z_out,
+ const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar,
+ const int mixed, const felem pre_comp[][17][3], const felem g_pre_comp[2][16][3])
+ {
+ int i, skip;
+ unsigned num;
+ unsigned gen_mul = (g_scalar != NULL);
+ felem nq[3], tmp[4];
+ u64 bits;
+ u8 sign, digit;
+
+ /* set nq to the point at infinity */
+ memset(nq, 0, 3 * sizeof(felem));
+
+ /* Loop over all scalars msb-to-lsb, interleaving additions
+ * of multiples of the generator (two in each of the last 28 rounds)
+ * and additions of other points multiples (every 5th round).
+ */
+ skip = 1; /* save two point operations in the first round */
+ for (i = (num_points ? 220 : 27); i >= 0; --i)
+ {
+ /* double */
+ if (!skip)
+ point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+
+ /* add multiples of the generator */
+ if (gen_mul && (i <= 27))
+ {
+ /* first, look 28 bits upwards */
+ bits = get_bit(g_scalar, i + 196) << 3;
+ bits |= get_bit(g_scalar, i + 140) << 2;
+ bits |= get_bit(g_scalar, i + 84) << 1;
+ bits |= get_bit(g_scalar, i + 28);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[1], tmp);
+
+ if (!skip)
+ {
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
+ }
+ else
+ {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+
+ /* second, look at the current position */
+ bits = get_bit(g_scalar, i + 168) << 3;
+ bits |= get_bit(g_scalar, i + 112) << 2;
+ bits |= get_bit(g_scalar, i + 56) << 1;
+ bits |= get_bit(g_scalar, i);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[0], tmp);
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
+ }
+
+ /* do other additions every 5 doublings */
+ if (num_points && (i % 5 == 0))
+ {
+ /* loop over all scalars */
+ for (num = 0; num < num_points; ++num)
+ {
+ bits = get_bit(scalars[num], i + 4) << 5;
+ bits |= get_bit(scalars[num], i + 3) << 4;
+ bits |= get_bit(scalars[num], i + 2) << 3;
+ bits |= get_bit(scalars[num], i + 1) << 2;
+ bits |= get_bit(scalars[num], i) << 1;
+ bits |= get_bit(scalars[num], i - 1);
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ /* select the point to add or subtract */
+ select_point(digit, 17, pre_comp[num], tmp);
+ felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative point */
+ copy_conditional(tmp[1], tmp[3], sign);
+
+ if (!skip)
+ {
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ mixed, tmp[0], tmp[1], tmp[2]);
+ }
+ else
+ {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+ }
+ }
+ }
+ felem_assign(x_out, nq[0]);
+ felem_assign(y_out, nq[1]);
+ felem_assign(z_out, nq[2]);
+ }
+
+/******************************************************************************/
+/* FUNCTIONS TO MANAGE PRECOMPUTATION
+ */
+
+static NISTP224_PRE_COMP *nistp224_pre_comp_new()
+ {
+ NISTP224_PRE_COMP *ret = NULL;
+ ret = (NISTP224_PRE_COMP *) OPENSSL_malloc(sizeof *ret);
+ if (!ret)
+ {
+ ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ return ret;
+ }
+ memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
+ ret->references = 1;
+ return ret;
+ }
+
+static void *nistp224_pre_comp_dup(void *src_)
+ {
+ NISTP224_PRE_COMP *src = src_;
+
+ /* no need to actually copy, these objects never change! */
+ CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+
+ return src_;
+ }
+
+static void nistp224_pre_comp_free(void *pre_)
+ {
+ int i;
+ NISTP224_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_free(pre);
+ }
+
+static void nistp224_pre_comp_clear_free(void *pre_)
+ {
+ int i;
+ NISTP224_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_cleanse(pre, sizeof *pre);
+ OPENSSL_free(pre);
+ }
+
+/******************************************************************************/
+/* OPENSSL EC_METHOD FUNCTIONS
+ */
+
+int ec_GFp_nistp224_group_init(EC_GROUP *group)
+ {
+ int ret;
+ ret = ec_GFp_simple_group_init(group);
+ group->a_is_minus3 = 1;
+ return ret;
+ }
+
+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+ {
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *curve_p, *curve_a, *curve_b;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
+ BN_CTX_start(ctx);
+ if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_b = BN_CTX_get(ctx)) == NULL)) goto err;
+ BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
+ BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
+ BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
+ if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
+ (BN_cmp(curve_b, b)))
+ {
+ ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE,
+ EC_R_WRONG_CURVE_PARAMETERS);
+ goto err;
+ }
+ group->field_mod_func = BN_nist_mod_224;
+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
+ * (X', Y') = (X/Z^2, Y/Z^3) */
+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+ {
+ felem z1, z2, x_in, y_in, x_out, y_out;
+ widefelem tmp;
+
+ if (EC_POINT_is_at_infinity(group, point))
+ {
+ ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
+ EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+ if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
+ (!BN_to_felem(z1, &point->Z))) return 0;
+ felem_inv(z2, z1);
+ felem_square(tmp, z2); felem_reduce(z1, tmp);
+ felem_mul(tmp, x_in, z1); felem_reduce(x_in, tmp);
+ felem_contract(x_out, x_in);
+ if (x != NULL)
+ {
+ if (!felem_to_BN(x, x_out)) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ felem_mul(tmp, z1, z2); felem_reduce(z1, tmp);
+ felem_mul(tmp, y_in, z1); felem_reduce(y_in, tmp);
+ felem_contract(y_out, y_in);
+ if (y != NULL)
+ {
+ if (!felem_to_BN(y, y_out)) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+static void make_points_affine(size_t num, felem points[/*num*/][3], felem tmp_felems[/*num+1*/])
+ {
+ /* Runs in constant time, unless an input is the point at infinity
+ * (which normally shouldn't happen). */
+ ec_GFp_nistp_points_make_affine_internal(
+ num,
+ points,
+ sizeof(felem),
+ tmp_felems,
+ (void (*)(void *)) felem_one,
+ (int (*)(const void *)) felem_is_zero_int,
+ (void (*)(void *, const void *)) felem_assign,
+ (void (*)(void *, const void *)) felem_square_reduce,
+ (void (*)(void *, const void *, const void *)) felem_mul_reduce,
+ (void (*)(void *, const void *)) felem_inv,
+ (void (*)(void *, const void *)) felem_contract);
+ }
+
+/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
+ * Result is stored in r (r can equal one of the inputs). */
+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num, const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
+ {
+ int ret = 0;
+ int j;
+ unsigned i;
+ int mixed = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y, *z, *tmp_scalar;
+ felem_bytearray g_secret;
+ felem_bytearray *secrets = NULL;
+ felem (*pre_comp)[17][3] = NULL;
+ felem *tmp_felems = NULL;
+ felem_bytearray tmp;
+ unsigned num_bytes;
+ int have_pre_comp = 0;
+ size_t num_points = num;
+ felem x_in, y_in, z_in, x_out, y_out, z_out;
+ NISTP224_PRE_COMP *pre = NULL;
+ const felem (*g_pre_comp)[16][3] = NULL;
+ EC_POINT *generator = NULL;
+ const EC_POINT *p = NULL;
+ const BIGNUM *p_scalar = NULL;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) ||
+ ((y = BN_CTX_get(ctx)) == NULL) ||
+ ((z = BN_CTX_get(ctx)) == NULL) ||
+ ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
+ goto err;
+
+ if (scalar != NULL)
+ {
+ pre = EC_EX_DATA_get_data(group->extra_data,
+ nistp224_pre_comp_dup, nistp224_pre_comp_free,
+ nistp224_pre_comp_clear_free);
+ if (pre)
+ /* we have precomputation, try to use it */
+ g_pre_comp = (const felem (*)[16][3]) pre->g_pre_comp;
+ else
+ /* try to use the standard precomputation */
+ g_pre_comp = &gmul[0];
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ /* get the generator from precomputation */
+ if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
+ !felem_to_BN(y, g_pre_comp[0][1][1]) ||
+ !felem_to_BN(z, g_pre_comp[0][1][2]))
+ {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
+ generator, x, y, z, ctx))
+ goto err;
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+ /* precomputation matches generator */
+ have_pre_comp = 1;
+ else
+ /* we don't have valid precomputation:
+ * treat the generator as a random point */
+ num_points = num_points + 1;
+ }
+
+ if (num_points > 0)
+ {
+ if (num_points >= 3)
+ {
+ /* unless we precompute multiples for just one or two points,
+ * converting those into affine form is time well spent */
+ mixed = 1;
+ }
+ secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
+ pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
+ if (mixed)
+ tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
+ if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_felems == NULL)))
+ {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* we treat NULL scalars as 0, and NULL points as points at infinity,
+ * i.e., they contribute nothing to the linear combination */
+ memset(secrets, 0, num_points * sizeof(felem_bytearray));
+ memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
+ for (i = 0; i < num_points; ++i)
+ {
+ if (i == num)
+ /* the generator */
+ {
+ p = EC_GROUP_get0_generator(group);
+ p_scalar = scalar;
+ }
+ else
+ /* the i^th point */
+ {
+ p = points[i];
+ p_scalar = scalars[i];
+ }
+ if ((p_scalar != NULL) && (p != NULL))
+ {
+ /* reduce scalar to 0 <= scalar < 2^224 */
+ if ((BN_num_bits(p_scalar) > 224) || (BN_is_negative(p_scalar)))
+ {
+ /* this is an unusual input, and we don't guarantee
+ * constant-timeness */
+ if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx))
+ {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ }
+ else
+ num_bytes = BN_bn2bin(p_scalar, tmp);
+ flip_endian(secrets[i], tmp, num_bytes);
+ /* precompute multiples */
+ if ((!BN_to_felem(x_out, &p->X)) ||
+ (!BN_to_felem(y_out, &p->Y)) ||
+ (!BN_to_felem(z_out, &p->Z))) goto err;
+ felem_assign(pre_comp[i][1][0], x_out);
+ felem_assign(pre_comp[i][1][1], y_out);
+ felem_assign(pre_comp[i][1][2], z_out);
+ for (j = 2; j <= 16; ++j)
+ {
+ if (j & 1)
+ {
+ point_add(
+ pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
+ pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
+ 0, pre_comp[i][j-1][0], pre_comp[i][j-1][1], pre_comp[i][j-1][2]);
+ }
+ else
+ {
+ point_double(
+ pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
+ pre_comp[i][j/2][0], pre_comp[i][j/2][1], pre_comp[i][j/2][2]);
+ }
+ }
+ }
+ }
+ if (mixed)
+ make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
+ }
+
+ /* the scalar for the generator */
+ if ((scalar != NULL) && (have_pre_comp))
+ {
+ memset(g_secret, 0, sizeof g_secret);
+ /* reduce scalar to 0 <= scalar < 2^224 */
+ if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar)))
+ {
+ /* this is an unusual input, and we don't guarantee
+ * constant-timeness */
+ if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx))
+ {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ }
+ else
+ num_bytes = BN_bn2bin(scalar, tmp);
+ flip_endian(g_secret, tmp, num_bytes);
+ /* do the multiplication with generator precomputation*/
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray (*)) secrets, num_points,
+ g_secret,
+ mixed, (const felem (*)[17][3]) pre_comp,
+ g_pre_comp);
+ }
+ else
+ /* do the multiplication without generator precomputation */
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray (*)) secrets, num_points,
+ NULL, mixed, (const felem (*)[17][3]) pre_comp, NULL);
+ /* reduce the output to its unique minimal representation */
+ felem_contract(x_in, x_out);
+ felem_contract(y_in, y_out);
+ felem_contract(z_in, z_out);
+ if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
+ (!felem_to_BN(z, z_in)))
+ {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (secrets != NULL)
+ OPENSSL_free(secrets);
+ if (pre_comp != NULL)
+ OPENSSL_free(pre_comp);
+ if (tmp_felems != NULL)
+ OPENSSL_free(tmp_felems);
+ return ret;
+ }
+
+int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+ {
+ int ret = 0;
+ NISTP224_PRE_COMP *pre = NULL;
+ int i, j;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y;
+ EC_POINT *generator = NULL;
+ felem tmp_felems[32];
+
+ /* throw away old precomputation */
+ EC_EX_DATA_free_data(&group->extra_data, nistp224_pre_comp_dup,
+ nistp224_pre_comp_free, nistp224_pre_comp_clear_free);
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) ||
+ ((y = BN_CTX_get(ctx)) == NULL))
+ goto err;
+ /* get the generator */
+ if (group->generator == NULL) goto err;
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ BN_bin2bn(nistp224_curve_params[3], sizeof (felem_bytearray), x);
+ BN_bin2bn(nistp224_curve_params[4], sizeof (felem_bytearray), y);
+ if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
+ goto err;
+ if ((pre = nistp224_pre_comp_new()) == NULL)
+ goto err;
+ /* if the generator is the standard one, use built-in precomputation */
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+ {
+ memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
+ ret = 1;
+ goto err;
+ }
+ if ((!BN_to_felem(pre->g_pre_comp[0][1][0], &group->generator->X)) ||
+ (!BN_to_felem(pre->g_pre_comp[0][1][1], &group->generator->Y)) ||
+ (!BN_to_felem(pre->g_pre_comp[0][1][2], &group->generator->Z)))
+ goto err;
+ /* compute 2^56*G, 2^112*G, 2^168*G for the first table,
+ * 2^28*G, 2^84*G, 2^140*G, 2^196*G for the second one
+ */
+ for (i = 1; i <= 8; i <<= 1)
+ {
+ point_double(
+ pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
+ pre->g_pre_comp[0][i][0], pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
+ for (j = 0; j < 27; ++j)
+ {
+ point_double(
+ pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
+ pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
+ }
+ if (i == 8)
+ break;
+ point_double(
+ pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
+ pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
+ for (j = 0; j < 27; ++j)
+ {
+ point_double(
+ pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
+ pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2]);
+ }
+ }
+ for (i = 0; i < 2; i++)
+ {
+ /* g_pre_comp[i][0] is the point at infinity */
+ memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
+ /* the remaining multiples */
+ /* 2^56*G + 2^112*G resp. 2^84*G + 2^140*G */
+ point_add(
+ pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1],
+ pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0],
+ pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
+ 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+ pre->g_pre_comp[i][2][2]);
+ /* 2^56*G + 2^168*G resp. 2^84*G + 2^196*G */
+ point_add(
+ pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1],
+ pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0],
+ pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+ 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+ pre->g_pre_comp[i][2][2]);
+ /* 2^112*G + 2^168*G resp. 2^140*G + 2^196*G */
+ point_add(
+ pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1],
+ pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0],
+ pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+ 0, pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1],
+ pre->g_pre_comp[i][4][2]);
+ /* 2^56*G + 2^112*G + 2^168*G resp. 2^84*G + 2^140*G + 2^196*G */
+ point_add(
+ pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1],
+ pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0],
+ pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
+ 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+ pre->g_pre_comp[i][2][2]);
+ for (j = 1; j < 8; ++j)
+ {
+ /* odd multiples: add G resp. 2^28*G */
+ point_add(
+ pre->g_pre_comp[i][2*j+1][0], pre->g_pre_comp[i][2*j+1][1],
+ pre->g_pre_comp[i][2*j+1][2], pre->g_pre_comp[i][2*j][0],
+ pre->g_pre_comp[i][2*j][1], pre->g_pre_comp[i][2*j][2],
+ 0, pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1],
+ pre->g_pre_comp[i][1][2]);
+ }
+ }
+ make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems);
+
+ if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp224_pre_comp_dup,
+ nistp224_pre_comp_free, nistp224_pre_comp_clear_free))
+ goto err;
+ ret = 1;
+ pre = NULL;
+ err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (pre)
+ nistp224_pre_comp_free(pre);
+ return ret;
+ }
+
+int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
+ {
+ if (EC_EX_DATA_get_data(group->extra_data, nistp224_pre_comp_dup,
+ nistp224_pre_comp_free, nistp224_pre_comp_clear_free)
+ != NULL)
+ return 1;
+ else
+ return 0;
+ }
+
+#else
+static void *dummy=&dummy;
+#endif
diff --git a/deps/openssl/openssl/crypto/ec/ecp_nistp256.c b/deps/openssl/openssl/crypto/ec/ecp_nistp256.c
new file mode 100644
index 000000000..4bc0f5dce
--- /dev/null
+++ b/deps/openssl/openssl/crypto/ec/ecp_nistp256.c
@@ -0,0 +1,2171 @@
+/* crypto/ec/ecp_nistp256.c */
+/*
+ * Written by Adam Langley (Google) for the OpenSSL project
+ */
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication
+ *
+ * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
+ * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
+ * work which got its smarts from Daniel J. Bernstein's work on the same.
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+
+#ifndef OPENSSL_SYS_VMS
+#include <stdint.h>
+#else
+#include <inttypes.h>
+#endif
+
+#include <string.h>
+#include <openssl/err.h>
+#include "ec_lcl.h"
+
+#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+ /* even with gcc, the typedef won't work for 32-bit platforms */
+ typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
+ typedef __int128_t int128_t;
+#else
+ #error "Need GCC 3.1 or later to define type uint128_t"
+#endif
+
+typedef uint8_t u8;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+/* The underlying field.
+ *
+ * P256 operates over GF(2^256-2^224+2^192+2^96-1). We can serialise an element
+ * of this field into 32 bytes. We call this an felem_bytearray. */
+
+typedef u8 felem_bytearray[32];
+
+/* These are the parameters of P256, taken from FIPS 186-3, page 86. These
+ * values are big-endian. */
+static const felem_bytearray nistp256_curve_params[5] = {
+ {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+ {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */
+ {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
+ 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
+ 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
+ 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
+ {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */
+ 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
+ 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
+ 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96},
+ {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */
+ 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+ 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
+ 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5}
+};
+
+/* The representation of field elements.
+ * ------------------------------------
+ *
+ * We represent field elements with either four 128-bit values, eight 128-bit
+ * values, or four 64-bit values. The field element represented is:
+ * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192 (mod p)
+ * or:
+ * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512 (mod p)
+ *
+ * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits
+ * apart, but are 128-bits wide, the most significant bits of each limb overlap
+ * with the least significant bits of the next.
+ *
+ * A field element with four limbs is an 'felem'. One with eight limbs is a
+ * 'longfelem'
+ *
+ * A field element with four, 64-bit values is called a 'smallfelem'. Small
+ * values are used as intermediate values before multiplication.
+ */
+
+#define NLIMBS 4
+
+typedef uint128_t limb;
+typedef limb felem[NLIMBS];
+typedef limb longfelem[NLIMBS * 2];
+typedef u64 smallfelem[NLIMBS];
+
+/* This is the value of the prime as four 64-bit words, little-endian. */
+static const u64 kPrime[4] = { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul };
+static const limb bottom32bits = 0xffffffff;
+static const u64 bottom63bits = 0x7ffffffffffffffful;
+
+/* bin32_to_felem takes a little-endian byte array and converts it into felem
+ * form. This assumes that the CPU is little-endian. */
+static void bin32_to_felem(felem out, const u8 in[32])
+ {
+ out[0] = *((u64*) &in[0]);
+ out[1] = *((u64*) &in[8]);
+ out[2] = *((u64*) &in[16]);
+ out[3] = *((u64*) &in[24]);
+ }
+
+/* smallfelem_to_bin32 takes a smallfelem and serialises into a little endian,
+ * 32 byte array. This assumes that the CPU is little-endian. */
+static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
+ {
+ *((u64*) &out[0]) = in[0];
+ *((u64*) &out[8]) = in[1];
+ *((u64*) &out[16]) = in[2];
+ *((u64*) &out[24]) = in[3];
+ }
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len)
+ {
+ unsigned i;
+ for (i = 0; i < len; ++i)
+ out[i] = in[len-1-i];
+ }
+
+/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
+static int BN_to_felem(felem out, const BIGNUM *bn)
+ {
+ felem_bytearray b_in;
+ felem_bytearray b_out;
+ unsigned num_bytes;
+
+ /* BN_bn2bin eats leading zeroes */
+ memset(b_out, 0, sizeof b_out);
+ num_bytes = BN_num_bytes(bn);
+ if (num_bytes > sizeof b_out)
+ {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ if (BN_is_negative(bn))
+ {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ num_bytes = BN_bn2bin(bn, b_in);
+ flip_endian(b_out, b_in, num_bytes);
+ bin32_to_felem(out, b_out);
+ return 1;
+ }
+
+/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
+static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in)
+ {
+ felem_bytearray b_in, b_out;
+ smallfelem_to_bin32(b_in, in);
+ flip_endian(b_out, b_in, sizeof b_out);
+ return BN_bin2bn(b_out, sizeof b_out, out);
+ }
+
+
+/* Field operations
+ * ---------------- */
+
+static void smallfelem_one(smallfelem out)
+ {
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 0;
+ out[3] = 0;
+ }
+
+static void smallfelem_assign(smallfelem out, const smallfelem in)
+ {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ }
+
+static void felem_assign(felem out, const felem in)
+ {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ }
+
+/* felem_sum sets out = out + in. */
+static void felem_sum(felem out, const felem in)
+ {
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+ }
+
+/* felem_small_sum sets out = out + in. */
+static void felem_small_sum(felem out, const smallfelem in)
+ {
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+ }
+
+/* felem_scalar sets out = out * scalar */
+static void felem_scalar(felem out, const u64 scalar)
+ {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ }
+
+/* longfelem_scalar sets out = out * scalar */
+static void longfelem_scalar(longfelem out, const u64 scalar)
+ {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+ out[7] *= scalar;
+ }
+
+#define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
+#define two105 (((limb)1) << 105)
+#define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
+
+/* zero105 is 0 mod p */
+static const felem zero105 = { two105m41m9, two105, two105m41p9, two105m41p9 };
+
+/* smallfelem_neg sets |out| to |-small|
+ * On exit:
+ * out[i] < out[i] + 2^105
+ */
+static void smallfelem_neg(felem out, const smallfelem small)
+ {
+ /* In order to prevent underflow, we subtract from 0 mod p. */
+ out[0] = zero105[0] - small[0];
+ out[1] = zero105[1] - small[1];
+ out[2] = zero105[2] - small[2];
+ out[3] = zero105[3] - small[3];
+ }
+
+/* felem_diff subtracts |in| from |out|
+ * On entry:
+ * in[i] < 2^104
+ * On exit:
+ * out[i] < out[i] + 2^105
+ */
+static void felem_diff(felem out, const felem in)
+ {
+ /* In order to prevent underflow, we add 0 mod p before subtracting. */
+ out[0] += zero105[0];
+ out[1] += zero105[1];
+ out[2] += zero105[2];
+ out[3] += zero105[3];
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ }
+
+#define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
+#define two107 (((limb)1) << 107)
+#define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
+
+/* zero107 is 0 mod p */
+static const felem zero107 = { two107m43m11, two107, two107m43p11, two107m43p11 };
+
+/* An alternative felem_diff for larger inputs |in|
+ * felem_diff_zero107 subtracts |in| from |out|
+ * On entry:
+ * in[i] < 2^106
+ * On exit:
+ * out[i] < out[i] + 2^107
+ */
+static void felem_diff_zero107(felem out, const felem in)
+ {
+ /* In order to prevent underflow, we add 0 mod p before subtracting. */
+ out[0] += zero107[0];
+ out[1] += zero107[1];
+ out[2] += zero107[2];
+ out[3] += zero107[3];
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ }
+
+/* longfelem_diff subtracts |in| from |out|
+ * On entry:
+ * in[i] < 7*2^67
+ * On exit:
+ * out[i] < out[i] + 2^70 + 2^40
+ */
+static void longfelem_diff(longfelem out, const longfelem in)
+ {
+ static const limb two70m8p6 = (((limb)1) << 70) - (((limb)1) << 8) + (((limb)1) << 6);
+ static const limb two70p40 = (((limb)1) << 70) + (((limb)1) << 40);
+ static const limb two70 = (((limb)1) << 70);
+ static const limb two70m40m38p6 = (((limb)1) << 70) - (((limb)1) << 40) - (((limb)1) << 38) + (((limb)1) << 6);
+ static const limb two70m6 = (((limb)1) << 70) - (((limb)1) << 6);
+
+ /* add 0 mod p to avoid underflow */
+ out[0] += two70m8p6;
+ out[1] += two70p40;
+ out[2] += two70;
+ out[3] += two70m40m38p6;
+ out[4] += two70m6;
+ out[5] += two70m6;
+ out[6] += two70m6;
+ out[7] += two70m6;
+
+ /* in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6 */
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ out[4] -= in[4];
+ out[5] -= in[5];
+ out[6] -= in[6];
+ out[7] -= in[7];
+ }
+
+#define two64m0 (((limb)1) << 64) - 1
+#define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
+#define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
+#define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
+
+/* zero110 is 0 mod p */
+static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 };
+
+/* felem_shrink converts an felem into a smallfelem. The result isn't quite
+ * minimal as the value may be greater than p.
+ *
+ * On entry:
+ * in[i] < 2^109
+ * On exit:
+ * out[i] < 2^64
+ */
+static void felem_shrink(smallfelem out, const felem in)
+ {
+ felem tmp;
+ u64 a, b, mask;
+ s64 high, low;
+ static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */
+
+ /* Carry 2->3 */
+ tmp[3] = zero110[3] + in[3] + ((u64) (in[2] >> 64));
+ /* tmp[3] < 2^110 */
+
+ tmp[2] = zero110[2] + (u64) in[2];
+ tmp[0] = zero110[0] + in[0];
+ tmp[1] = zero110[1] + in[1];
+ /* tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65 */
+
+ /* We perform two partial reductions where we eliminate the
+ * high-word of tmp[3]. We don't update the other words till the end.
+ */
+ a = tmp[3] >> 64; /* a < 2^46 */
+ tmp[3] = (u64) tmp[3];
+ tmp[3] -= a;
+ tmp[3] += ((limb)a) << 32;
+ /* tmp[3] < 2^79 */
+
+ b = a;
+ a = tmp[3] >> 64; /* a < 2^15 */
+ b += a; /* b < 2^46 + 2^15 < 2^47 */
+ tmp[3] = (u64) tmp[3];
+ tmp[3] -= a;
+ tmp[3] += ((limb)a) << 32;
+ /* tmp[3] < 2^64 + 2^47 */
+
+ /* This adjusts the other two words to complete the two partial
+ * reductions. */
+ tmp[0] += b;
+ tmp[1] -= (((limb)b) << 32);
+
+ /* In order to make space in tmp[3] for the carry from 2 -> 3, we
+ * conditionally subtract kPrime if tmp[3] is large enough. */
+ high = tmp[3] >> 64;
+ /* As tmp[3] < 2^65, high is either 1 or 0 */
+ high <<= 63;
+ high >>= 63;
+ /* high is:
+ * all ones if the high word of tmp[3] is 1
+ * all zeros if the high word of tmp[3] if 0 */
+ low = tmp[3];
+ mask = low >> 63;
+ /* mask is:
+ * all ones if the MSB of low is 1
+ * all zeros if the MSB of low if 0 */
+ low &= bottom63bits;
+ low -= kPrime3Test;
+ /* if low was greater than kPrime3Test then the MSB is zero */
+ low = ~low;
+ low >>= 63;
+ /* low is:
+ * all ones if low was > kPrime3Test
+ * all zeros if low was <= kPrime3Test */
+ mask = (mask & low) | high;
+ tmp[0] -= mask & kPrime[0];
+ tmp[1] -= mask & kPrime[1];
+ /* kPrime[2] is zero, so omitted */
+ tmp[3] -= mask & kPrime[3];
+ /* tmp[3] < 2**64 - 2**32 + 1 */
+
+ tmp[1] += ((u64) (tmp[0] >> 64)); tmp[0] = (u64) tmp[0];
+ tmp[2] += ((u64) (tmp[1] >> 64)); tmp[1] = (u64) tmp[1];
+ tmp[3] += ((u64) (tmp[2] >> 64)); tmp[2] = (u64) tmp[2];
+ /* tmp[i] < 2^64 */
+
+ out[0] = tmp[0];
+ out[1] = tmp[1];
+ out[2] = tmp[2];
+ out[3] = tmp[3];
+ }
+
+/* smallfelem_expand converts a smallfelem to an felem */
+static void smallfelem_expand(felem out, const smallfelem in)
+ {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ }
+
+/* smallfelem_square sets |out| = |small|^2
+ * On entry:
+ * small[i] < 2^64
+ * On exit:
+ * out[i] < 7 * 2^64 < 2^67
+ */
+static void smallfelem_square(longfelem out, const smallfelem small)
+ {
+ limb a;
+ u64 high, low;
+
+ a = ((uint128_t) small[0]) * small[0];
+ low = a;
+ high = a >> 64;
+ out[0] = low;
+ out[1] = high;
+
+ a = ((uint128_t) small[0]) * small[1];
+ low = a;
+ high = a >> 64;
+ out[1] += low;
+ out[1] += low;
+ out[2] = high;
+
+ a = ((uint128_t) small[0]) * small[2];
+ low = a;
+ high = a >> 64;
+ out[2] += low;
+ out[2] *= 2;
+ out[3] = high;
+
+ a = ((uint128_t) small[0]) * small[3];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[4] = high;
+
+ a = ((uint128_t) small[1]) * small[2];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[3] *= 2;
+ out[4] += high;
+
+ a = ((uint128_t) small[1]) * small[1];
+ low = a;
+ high = a >> 64;
+ out[2] += low;
+ out[3] += high;
+
+ a = ((uint128_t) small[1]) * small[3];
+ low = a;
+ high = a >> 64;
+ out[4] += low;
+ out[4] *= 2;
+ out[5] = high;
+
+ a = ((uint128_t) small[2]) * small[3];
+ low = a;
+ high = a >> 64;
+ out[5] += low;
+ out[5] *= 2;
+ out[6] = high;
+ out[6] += high;
+
+ a = ((uint128_t) small[2]) * small[2];
+ low = a;
+ high = a >> 64;
+ out[4] += low;
+ out[5] += high;
+
+ a = ((uint128_t) small[3]) * small[3];
+ low = a;
+ high = a >> 64;
+ out[6] += low;
+ out[7] = high;
+ }
+
+/* felem_square sets |out| = |in|^2
+ * On entry:
+ * in[i] < 2^109
+ * On exit:
+ * out[i] < 7 * 2^64 < 2^67
+ */
+static void felem_square(longfelem out, const felem in)
+ {
+ u64 small[4];
+ felem_shrink(small, in);
+ smallfelem_square(out, small);
+ }
+
+/* smallfelem_mul sets |out| = |small1| * |small2|
+ * On entry:
+ * small1[i] < 2^64
+ * small2[i] < 2^64
+ * On exit:
+ * out[i] < 7 * 2^64 < 2^67
+ */
+static void smallfelem_mul(longfelem out, const smallfelem small1, const smallfelem small2)
+ {
+ limb a;
+ u64 high, low;
+
+ a = ((uint128_t) small1[0]) * small2[0];
+ low = a;
+ high = a >> 64;
+ out[0] = low;
+ out[1] = high;
+
+
+ a = ((uint128_t) small1[0]) * small2[1];
+ low = a;
+ high = a >> 64;
+ out[1] += low;
+ out[2] = high;
+
+ a = ((uint128_t) small1[1]) * small2[0];
+ low = a;
+ high = a >> 64;
+ out[1] += low;
+ out[2] += high;
+
+
+ a = ((uint128_t) small1[0]) * small2[2];
+ low = a;
+ high = a >> 64;
+ out[2] += low;
+ out[3] = high;
+
+ a = ((uint128_t) small1[1]) * small2[1];
+ low = a;
+ high = a >> 64;
+ out[2] += low;
+ out[3] += high;
+
+ a = ((uint128_t) small1[2]) * small2[0];
+ low = a;
+ high = a >> 64;
+ out[2] += low;
+ out[3] += high;
+
+
+ a = ((uint128_t) small1[0]) * small2[3];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[4] = high;
+
+ a = ((uint128_t) small1[1]) * small2[2];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[4] += high;
+
+ a = ((uint128_t) small1[2]) * small2[1];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[4] += high;
+
+ a = ((uint128_t) small1[3]) * small2[0];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[4] += high;
+
+
+ a = ((uint128_t) small1[1]) * small2[3];
+ low = a;
+ high = a >> 64;
+ out[4] += low;
+ out[5] = high;
+
+ a = ((uint128_t) small1[2]) * small2[2];
+ low = a;
+ high = a >> 64;
+ out[4] += low;
+ out[5] += high;
+
+ a = ((uint128_t) small1[3]) * small2[1];
+ low = a;
+ high = a >> 64;
+ out[4] += low;
+ out[5] += high;
+
+
+ a = ((uint128_t) small1[2]) * small2[3];
+ low = a;
+ high = a >> 64;
+ out[5] += low;
+ out[6] = high;
+
+ a = ((uint128_t) small1[3]) * small2[2];
+ low = a;
+ high = a >> 64;
+ out[5] += low;
+ out[6] += high;
+
+
+ a = ((uint128_t) small1[3]) * small2[3];
+ low = a;
+ high = a >> 64;
+ out[6] += low;
+ out[7] = high;
+ }
+
+/* felem_mul sets |out| = |in1| * |in2|
+ * On entry:
+ * in1[i] < 2^109
+ * in2[i] < 2^109
+ * On exit:
+ * out[i] < 7 * 2^64 < 2^67
+ */
+static void felem_mul(longfelem out, const felem in1, const felem in2)
+ {
+ smallfelem small1, small2;
+ felem_shrink(small1, in1);
+ felem_shrink(small2, in2);
+ smallfelem_mul(out, small1, small2);
+ }
+
+/* felem_small_mul sets |out| = |small1| * |in2|
+ * On entry:
+ * small1[i] < 2^64
+ * in2[i] < 2^109
+ * On exit:
+ * out[i] < 7 * 2^64 < 2^67
+ */
+static void felem_small_mul(longfelem out, const smallfelem small1, const felem in2)
+ {
+ smallfelem small2;
+ felem_shrink(small2, in2);
+ smallfelem_mul(out, small1, small2);
+ }
+
+#define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
+#define two100 (((limb)1) << 100)
+#define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
+/* zero100 is 0 mod p */
+static const felem zero100 = { two100m36m4, two100, two100m36p4, two100m36p4 };
+
+/* Internal function for the different flavours of felem_reduce.
+ * felem_reduce_ reduces the higher coefficients in[4]-in[7].
+ * On entry:
+ * out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7]
+ * out[1] >= in[7] + 2^32*in[4]
+ * out[2] >= in[5] + 2^32*in[5]
+ * out[3] >= in[4] + 2^32*in[5] + 2^32*in[6]
+ * On exit:
+ * out[0] <= out[0] + in[4] + 2^32*in[5]
+ * out[1] <= out[1] + in[5] + 2^33*in[6]
+ * out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7]
+ * out[3] <= out[3] + 2^32*in[4] + 3*in[7]
+ */
+static void felem_reduce_(felem out, const longfelem in)
+ {
+ int128_t c;
+ /* combine common terms from below */
+ c = in[4] + (in[5] << 32);
+ out[0] += c;
+ out[3] -= c;
+
+ c = in[5] - in[7];
+ out[1] += c;
+ out[2] -= c;
+
+ /* the remaining terms */
+ /* 256: [(0,1),(96,-1),(192,-1),(224,1)] */
+ out[1] -= (in[4] << 32);
+ out[3] += (in[4] << 32);
+
+ /* 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)] */
+ out[2] -= (in[5] << 32);
+
+ /* 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)] */
+ out[0] -= in[6];
+ out[0] -= (in[6] << 32);
+ out[1] += (in[6] << 33);
+ out[2] += (in[6] * 2);
+ out[3] -= (in[6] << 32);
+
+ /* 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)] */
+ out[0] -= in[7];
+ out[0] -= (in[7] << 32);
+ out[2] += (in[7] << 33);
+ out[3] += (in[7] * 3);
+ }
+
+/* felem_reduce converts a longfelem into an felem.
+ * To be called directly after felem_square or felem_mul.
+ * On entry:
+ * in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64
+ * in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64
+ * On exit:
+ * out[i] < 2^101
+ */
+static void felem_reduce(felem out, const longfelem in)
+ {
+ out[0] = zero100[0] + in[0];
+ out[1] = zero100[1] + in[1];
+ out[2] = zero100[2] + in[2];
+ out[3] = zero100[3] + in[3];
+
+ felem_reduce_(out, in);
+
+ /* out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0
+ * out[1] > 2^100 - 2^64 - 7*2^96 > 0
+ * out[2] > 2^100 - 2^36 + 2^4 - 5*2^64 - 5*2^96 > 0
+ * out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96 - 3*2^96 > 0
+ *
+ * out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101
+ * out[1] < 2^100 + 3*2^64 + 5*2^64 + 3*2^97 < 2^101
+ * out[2] < 2^100 + 5*2^64 + 2^64 + 3*2^65 + 2^97 < 2^101
+ * out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 < 2^101
+ */
+ }
+
+/* felem_reduce_zero105 converts a larger longfelem into an felem.
+ * On entry:
+ * in[0] < 2^71
+ * On exit:
+ * out[i] < 2^106
+ */
+static void felem_reduce_zero105(felem out, const longfelem in)
+ {
+ out[0] = zero105[0] + in[0];
+ out[1] = zero105[1] + in[1];
+ out[2] = zero105[2] + in[2];
+ out[3] = zero105[3] + in[3];
+
+ felem_reduce_(out, in);
+
+ /* out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0
+ * out[1] > 2^105 - 2^71 - 2^103 > 0
+ * out[2] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 > 0
+ * out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 - 2^103 > 0
+ *
+ * out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
+ * out[1] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
+ * out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 < 2^106
+ * out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106
+ */
+ }
+
+/* subtract_u64 sets *result = *result - v and *carry to one if the subtraction
+ * underflowed. */
+static void subtract_u64(u64* result, u64* carry, u64 v)
+ {
+ uint128_t r = *result;
+ r -= v;
+ *carry = (r >> 64) & 1;
+ *result = (u64) r;
+ }
+
+/* felem_contract converts |in| to its unique, minimal representation.
+ * On entry:
+ * in[i] < 2^109
+ */
+static void felem_contract(smallfelem out, const felem in)
+ {
+ unsigned i;
+ u64 all_equal_so_far = 0, result = 0, carry;
+
+ felem_shrink(out, in);
+ /* small is minimal except that the value might be > p */
+
+ all_equal_so_far--;
+ /* We are doing a constant time test if out >= kPrime. We need to
+ * compare each u64, from most-significant to least significant. For
+ * each one, if all words so far have been equal (m is all ones) then a
+ * non-equal result is the answer. Otherwise we continue. */
+ for (i = 3; i < 4; i--)
+ {
+ u64 equal;
+ uint128_t a = ((uint128_t) kPrime[i]) - out[i];
+ /* if out[i] > kPrime[i] then a will underflow and the high
+ * 64-bits will all be set. */
+ result |= all_equal_so_far & ((u64) (a >> 64));
+
+ /* if kPrime[i] == out[i] then |equal| will be all zeros and
+ * the decrement will make it all ones. */
+ equal = kPrime[i] ^ out[i];
+ equal--;
+ equal &= equal << 32;
+ equal &= equal << 16;
+ equal &= equal << 8;
+ equal &= equal << 4;
+ equal &= equal << 2;
+ equal &= equal << 1;
+ equal = ((s64) equal) >> 63;
+
+ all_equal_so_far &= equal;
+ }
+
+ /* if all_equal_so_far is still all ones then the two values are equal
+ * and so out >= kPrime is true. */
+ result |= all_equal_so_far;
+
+ /* if out >= kPrime then we subtract kPrime. */
+ subtract_u64(&out[0], &carry, result & kPrime[0]);
+ subtract_u64(&out[1], &carry, carry);
+ subtract_u64(&out[2], &carry, carry);
+ subtract_u64(&out[3], &carry, carry);
+
+ subtract_u64(&out[1], &carry, result & kPrime[1]);
+ subtract_u64(&out[2], &carry, carry);
+ subtract_u64(&out[3], &carry, carry);
+
+ subtract_u64(&out[2], &carry, result & kPrime[2]);
+ subtract_u64(&out[3], &carry, carry);
+
+ subtract_u64(&out[3], &carry, result & kPrime[3]);
+ }
+
+static void smallfelem_square_contract(smallfelem out, const smallfelem in)
+ {
+ longfelem longtmp;
+ felem tmp;
+
+ smallfelem_square(longtmp, in);
+ felem_reduce(tmp, longtmp);
+ felem_contract(out, tmp);
+ }
+
+static void smallfelem_mul_contract(smallfelem out, const smallfelem in1, const smallfelem in2)
+ {
+ longfelem longtmp;
+ felem tmp;
+
+ smallfelem_mul(longtmp, in1, in2);
+ felem_reduce(tmp, longtmp);
+ felem_contract(out, tmp);
+ }
+
+/* felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
+ * otherwise.
+ * On entry:
+ * small[i] < 2^64
+ */
+static limb smallfelem_is_zero(const smallfelem small)
+ {
+ limb result;
+ u64 is_p;
+
+ u64 is_zero = small[0] | small[1] | small[2] | small[3];
+ is_zero--;
+ is_zero &= is_zero << 32;
+ is_zero &= is_zero << 16;
+ is_zero &= is_zero << 8;
+ is_zero &= is_zero << 4;
+ is_zero &= is_zero << 2;
+ is_zero &= is_zero << 1;
+ is_zero = ((s64) is_zero) >> 63;
+
+ is_p = (small[0] ^ kPrime[0]) |
+ (small[1] ^ kPrime[1]) |
+ (small[2] ^ kPrime[2]) |
+ (small[3] ^ kPrime[3]);
+ is_p--;
+ is_p &= is_p << 32;
+ is_p &= is_p << 16;
+ is_p &= is_p << 8;
+ is_p &= is_p << 4;
+ is_p &= is_p << 2;
+ is_p &= is_p << 1;
+ is_p = ((s64) is_p) >> 63;
+
+ is_zero |= is_p;
+
+ result = is_zero;
+ result |= ((limb) is_zero) << 64;
+ return result;
+ }
+
+static int smallfelem_is_zero_int(const smallfelem small)
+ {
+ return (int) (smallfelem_is_zero(small) & ((limb)1));
+ }
+
+/* felem_inv calculates |out| = |in|^{-1}
+ *
+ * Based on Fermat's Little Theorem:
+ * a^p = a (mod p)
+ * a^{p-1} = 1 (mod p)
+ * a^{p-2} = a^{-1} (mod p)
+ */
+static void felem_inv(felem out, const felem in)
+ {
+ felem ftmp, ftmp2;
+ /* each e_I will hold |in|^{2^I - 1} */
+ felem e2, e4, e8, e16, e32, e64;
+ longfelem tmp;
+ unsigned i;
+
+ felem_square(tmp, in); felem_reduce(ftmp, tmp); /* 2^1 */
+ felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */
+ felem_assign(e2, ftmp);
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^4 - 2^2 */
+ felem_mul(tmp, ftmp, e2); felem_reduce(ftmp, tmp); /* 2^4 - 2^0 */
+ felem_assign(e4, ftmp);
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^5 - 2^1 */
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^6 - 2^2 */
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^7 - 2^3 */
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^8 - 2^4 */
+ felem_mul(tmp, ftmp, e4); felem_reduce(ftmp, tmp); /* 2^8 - 2^0 */
+ felem_assign(e8, ftmp);
+ for (i = 0; i < 8; i++) {
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
+ } /* 2^16 - 2^8 */
+ felem_mul(tmp, ftmp, e8); felem_reduce(ftmp, tmp); /* 2^16 - 2^0 */
+ felem_assign(e16, ftmp);
+ for (i = 0; i < 16; i++) {
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
+ } /* 2^32 - 2^16 */
+ felem_mul(tmp, ftmp, e16); felem_reduce(ftmp, tmp); /* 2^32 - 2^0 */
+ felem_assign(e32, ftmp);
+ for (i = 0; i < 32; i++) {
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
+ } /* 2^64 - 2^32 */
+ felem_assign(e64, ftmp);
+ felem_mul(tmp, ftmp, in); felem_reduce(ftmp, tmp); /* 2^64 - 2^32 + 2^0 */
+ for (i = 0; i < 192; i++) {
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
+ } /* 2^256 - 2^224 + 2^192 */
+
+ felem_mul(tmp, e64, e32); felem_reduce(ftmp2, tmp); /* 2^64 - 2^0 */
+ for (i = 0; i < 16; i++) {
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
+ } /* 2^80 - 2^16 */
+ felem_mul(tmp, ftmp2, e16); felem_reduce(ftmp2, tmp); /* 2^80 - 2^0 */
+ for (i = 0; i < 8; i++) {
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
+ } /* 2^88 - 2^8 */
+ felem_mul(tmp, ftmp2, e8); felem_reduce(ftmp2, tmp); /* 2^88 - 2^0 */
+ for (i = 0; i < 4; i++) {
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
+ } /* 2^92 - 2^4 */
+ felem_mul(tmp, ftmp2, e4); felem_reduce(ftmp2, tmp); /* 2^92 - 2^0 */
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^93 - 2^1 */
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^94 - 2^2 */
+ felem_mul(tmp, ftmp2, e2); felem_reduce(ftmp2, tmp); /* 2^94 - 2^0 */
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^95 - 2^1 */
+ felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^96 - 2^2 */
+ felem_mul(tmp, ftmp2, in); felem_reduce(ftmp2, tmp); /* 2^96 - 3 */
+
+ felem_mul(tmp, ftmp2, ftmp); felem_reduce(out, tmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
+ }
+
+static void smallfelem_inv_contract(smallfelem out, const smallfelem in)
+ {
+ felem tmp;
+
+ smallfelem_expand(tmp, in);
+ felem_inv(tmp, tmp);
+ felem_contract(out, tmp);
+ }
+
+/* Group operations
+ * ----------------
+ *
+ * Building on top of the field operations we have the operations on the
+ * elliptic curve group itself. Points on the curve are represented in Jacobian
+ * coordinates */
+
+/* point_double calculates 2*(x_in, y_in, z_in)
+ *
+ * The method is taken from:
+ * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+ *
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
+ * while x_out == y_in is not (maybe this works, but it's not tested). */
+static void
+point_double(felem x_out, felem y_out, felem z_out,
+ const felem x_in, const felem y_in, const felem z_in)
+ {
+ longfelem tmp, tmp2;
+ felem delta, gamma, beta, alpha, ftmp, ftmp2;
+ smallfelem small1, small2;
+
+ felem_assign(ftmp, x_in);
+ /* ftmp[i] < 2^106 */
+ felem_assign(ftmp2, x_in);
+ /* ftmp2[i] < 2^106 */
+
+ /* delta = z^2 */
+ felem_square(tmp, z_in);
+ felem_reduce(delta, tmp);
+ /* delta[i] < 2^101 */
+
+ /* gamma = y^2 */
+ felem_square(tmp, y_in);
+ felem_reduce(gamma, tmp);
+ /* gamma[i] < 2^101 */
+ felem_shrink(small1, gamma);
+
+ /* beta = x*gamma */
+ felem_small_mul(tmp, small1, x_in);
+ felem_reduce(beta, tmp);
+ /* beta[i] < 2^101 */
+
+ /* alpha = 3*(x-delta)*(x+delta) */
+ felem_diff(ftmp, delta);
+ /* ftmp[i] < 2^105 + 2^106 < 2^107 */
+ felem_sum(ftmp2, delta);
+ /* ftmp2[i] < 2^105 + 2^106 < 2^107 */
+ felem_scalar(ftmp2, 3);
+ /* ftmp2[i] < 3 * 2^107 < 2^109 */
+ felem_mul(tmp, ftmp, ftmp2);
+ felem_reduce(alpha, tmp);
+ /* alpha[i] < 2^101 */
+ felem_shrink(small2, alpha);
+
+ /* x' = alpha^2 - 8*beta */
+ smallfelem_square(tmp, small2);
+ felem_reduce(x_out, tmp);
+ felem_assign(ftmp, beta);
+ felem_scalar(ftmp, 8);
+ /* ftmp[i] < 8 * 2^101 = 2^104 */
+ felem_diff(x_out, ftmp);
+ /* x_out[i] < 2^105 + 2^101 < 2^106 */
+
+ /* z' = (y + z)^2 - gamma - delta */
+ felem_sum(delta, gamma);
+ /* delta[i] < 2^101 + 2^101 = 2^102 */
+ felem_assign(ftmp, y_in);
+ felem_sum(ftmp, z_in);
+ /* ftmp[i] < 2^106 + 2^106 = 2^107 */
+ felem_square(tmp, ftmp);
+ felem_reduce(z_out, tmp);
+ felem_diff(z_out, delta);
+ /* z_out[i] < 2^105 + 2^101 < 2^106 */
+
+ /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+ felem_scalar(beta, 4);
+ /* beta[i] < 4 * 2^101 = 2^103 */
+ felem_diff_zero107(beta, x_out);
+ /* beta[i] < 2^107 + 2^103 < 2^108 */
+ felem_small_mul(tmp, small2, beta);
+ /* tmp[i] < 7 * 2^64 < 2^67 */
+ smallfelem_square(tmp2, small1);
+ /* tmp2[i] < 7 * 2^64 */
+ longfelem_scalar(tmp2, 8);
+ /* tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67 */
+ longfelem_diff(tmp, tmp2);
+ /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
+ felem_reduce_zero105(y_out, tmp);
+ /* y_out[i] < 2^106 */
+ }
+
+/* point_double_small is the same as point_double, except that it operates on
+ * smallfelems */
+static void
+point_double_small(smallfelem x_out, smallfelem y_out, smallfelem z_out,
+ const smallfelem x_in, const smallfelem y_in, const smallfelem z_in)
+ {
+ felem felem_x_out, felem_y_out, felem_z_out;
+ felem felem_x_in, felem_y_in, felem_z_in;
+
+ smallfelem_expand(felem_x_in, x_in);
+ smallfelem_expand(felem_y_in, y_in);
+ smallfelem_expand(felem_z_in, z_in);
+ point_double(felem_x_out, felem_y_out, felem_z_out,
+ felem_x_in, felem_y_in, felem_z_in);
+ felem_shrink(x_out, felem_x_out);
+ felem_shrink(y_out, felem_y_out);
+ felem_shrink(z_out, felem_z_out);
+ }
+
+/* copy_conditional copies in to out iff mask is all ones. */
+static void
+copy_conditional(felem out, const felem in, limb mask)
+ {
+ unsigned i;
+ for (i = 0; i < NLIMBS; ++i)
+ {
+ const limb tmp = mask & (in[i] ^ out[i]);
+ out[i] ^= tmp;
+ }
+ }
+
+/* copy_small_conditional copies in to out iff mask is all ones. */
+static void
+copy_small_conditional(felem out, const smallfelem in, limb mask)
+ {
+ unsigned i;
+ const u64 mask64 = mask;
+ for (i = 0; i < NLIMBS; ++i)
+ {
+ out[i] = ((limb) (in[i] & mask64)) | (out[i] & ~mask);
+ }
+ }
+
+/* point_add calcuates (x1, y1, z1) + (x2, y2, z2)
+ *
+ * The method is taken from:
+ * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
+ * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
+ *
+ * This function includes a branch for checking whether the two input points
+ * are equal, (while not equal to the point at infinity). This case never
+ * happens during single point multiplication, so there is no timing leak for
+ * ECDH or ECDSA signing. */
+static void point_add(felem x3, felem y3, felem z3,
+ const felem x1, const felem y1, const felem z1,
+ const int mixed, const smallfelem x2, const smallfelem y2, const smallfelem z2)
+ {
+ felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
+ longfelem tmp, tmp2;
+ smallfelem small1, small2, small3, small4, small5;
+ limb x_equal, y_equal, z1_is_zero, z2_is_zero;
+
+ felem_shrink(small3, z1);
+
+ z1_is_zero = smallfelem_is_zero(small3);
+ z2_is_zero = smallfelem_is_zero(z2);
+
+ /* ftmp = z1z1 = z1**2 */
+ smallfelem_square(tmp, small3);
+ felem_reduce(ftmp, tmp);
+ /* ftmp[i] < 2^101 */
+ felem_shrink(small1, ftmp);
+
+ if(!mixed)
+ {
+ /* ftmp2 = z2z2 = z2**2 */
+ smallfelem_square(tmp, z2);
+ felem_reduce(ftmp2, tmp);
+ /* ftmp2[i] < 2^101 */
+ felem_shrink(small2, ftmp2);
+
+ felem_shrink(small5, x1);
+
+ /* u1 = ftmp3 = x1*z2z2 */
+ smallfelem_mul(tmp, small5, small2);
+ felem_reduce(ftmp3, tmp);
+ /* ftmp3[i] < 2^101 */
+
+ /* ftmp5 = z1 + z2 */
+ felem_assign(ftmp5, z1);
+ felem_small_sum(ftmp5, z2);
+ /* ftmp5[i] < 2^107 */
+
+ /* ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 */
+ felem_square(tmp, ftmp5);
+ felem_reduce(ftmp5, tmp);
+ /* ftmp2 = z2z2 + z1z1 */
+ felem_sum(ftmp2, ftmp);
+ /* ftmp2[i] < 2^101 + 2^101 = 2^102 */
+ felem_diff(ftmp5, ftmp2);
+ /* ftmp5[i] < 2^105 + 2^101 < 2^106 */
+
+ /* ftmp2 = z2 * z2z2 */
+ smallfelem_mul(tmp, small2, z2);
+ felem_reduce(ftmp2, tmp);
+
+ /* s1 = ftmp2 = y1 * z2**3 */
+ felem_mul(tmp, y1, ftmp2);
+ felem_reduce(ftmp6, tmp);
+ /* ftmp6[i] < 2^101 */
+ }
+ else
+ {
+ /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
+
+ /* u1 = ftmp3 = x1*z2z2 */
+ felem_assign(ftmp3, x1);
+ /* ftmp3[i] < 2^106 */
+
+ /* ftmp5 = 2z1z2 */
+ felem_assign(ftmp5, z1);
+ felem_scalar(ftmp5, 2);
+ /* ftmp5[i] < 2*2^106 = 2^107 */
+
+ /* s1 = ftmp2 = y1 * z2**3 */
+ felem_assign(ftmp6, y1);
+ /* ftmp6[i] < 2^106 */
+ }
+
+ /* u2 = x2*z1z1 */
+ smallfelem_mul(tmp, x2, small1);
+ felem_reduce(ftmp4, tmp);
+
+ /* h = ftmp4 = u2 - u1 */
+ felem_diff_zero107(ftmp4, ftmp3);
+ /* ftmp4[i] < 2^107 + 2^101 < 2^108 */
+ felem_shrink(small4, ftmp4);
+
+ x_equal = smallfelem_is_zero(small4);
+
+ /* z_out = ftmp5 * h */
+ felem_small_mul(tmp, small4, ftmp5);
+ felem_reduce(z_out, tmp);
+ /* z_out[i] < 2^101 */
+
+ /* ftmp = z1 * z1z1 */
+ smallfelem_mul(tmp, small1, small3);
+ felem_reduce(ftmp, tmp);
+
+ /* s2 = tmp = y2 * z1**3 */
+ felem_small_mul(tmp, y2, ftmp);
+ felem_reduce(ftmp5, tmp);
+
+ /* r = ftmp5 = (s2 - s1)*2 */
+ felem_diff_zero107(ftmp5, ftmp6);
+ /* ftmp5[i] < 2^107 + 2^107 = 2^108*/
+ felem_scalar(ftmp5, 2);
+ /* ftmp5[i] < 2^109 */
+ felem_shrink(small1, ftmp5);
+ y_equal = smallfelem_is_zero(small1);
+
+ if (x_equal && y_equal && !z1_is_zero && !z2_is_zero)
+ {
+ point_double(x3, y3, z3, x1, y1, z1);
+ return;
+ }
+
+ /* I = ftmp = (2h)**2 */
+ felem_assign(ftmp, ftmp4);
+ felem_scalar(ftmp, 2);
+ /* ftmp[i] < 2*2^108 = 2^109 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+
+ /* J = ftmp2 = h * I */
+ felem_mul(tmp, ftmp4, ftmp);
+ felem_reduce(ftmp2, tmp);
+
+ /* V = ftmp4 = U1 * I */
+ felem_mul(tmp, ftmp3, ftmp);
+ felem_reduce(ftmp4, tmp);
+
+ /* x_out = r**2 - J - 2V */
+ smallfelem_square(tmp, small1);
+ felem_reduce(x_out, tmp);
+ felem_assign(ftmp3, ftmp4);
+ felem_scalar(ftmp4, 2);
+ felem_sum(ftmp4, ftmp2);
+ /* ftmp4[i] < 2*2^101 + 2^101 < 2^103 */
+ felem_diff(x_out, ftmp4);
+ /* x_out[i] < 2^105 + 2^101 */
+
+ /* y_out = r(V-x_out) - 2 * s1 * J */
+ felem_diff_zero107(ftmp3, x_out);
+ /* ftmp3[i] < 2^107 + 2^101 < 2^108 */
+ felem_small_mul(tmp, small1, ftmp3);
+ felem_mul(tmp2, ftmp6, ftmp2);
+ longfelem_scalar(tmp2, 2);
+ /* tmp2[i] < 2*2^67 = 2^68 */
+ longfelem_diff(tmp, tmp2);
+ /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
+ felem_reduce_zero105(y_out, tmp);
+ /* y_out[i] < 2^106 */
+
+ copy_small_conditional(x_out, x2, z1_is_zero);
+ copy_conditional(x_out, x1, z2_is_zero);
+ copy_small_conditional(y_out, y2, z1_is_zero);
+ copy_conditional(y_out, y1, z2_is_zero);
+ copy_small_conditional(z_out, z2, z1_is_zero);
+ copy_conditional(z_out, z1, z2_is_zero);
+ felem_assign(x3, x_out);
+ felem_assign(y3, y_out);
+ felem_assign(z3, z_out);
+ }
+
+/* point_add_small is the same as point_add, except that it operates on
+ * smallfelems */
+static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
+ smallfelem x1, smallfelem y1, smallfelem z1,
+ smallfelem x2, smallfelem y2, smallfelem z2)
+ {
+ felem felem_x3, felem_y3, felem_z3;
+ felem felem_x1, felem_y1, felem_z1;
+ smallfelem_expand(felem_x1, x1);
+ smallfelem_expand(felem_y1, y1);
+ smallfelem_expand(felem_z1, z1);
+ point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0, x2, y2, z2);
+ felem_shrink(x3, felem_x3);
+ felem_shrink(y3, felem_y3);
+ felem_shrink(z3, felem_z3);
+ }
+
+/* Base point pre computation
+ * --------------------------
+ *
+ * Two different sorts of precomputed tables are used in the following code.
+ * Each contain various points on the curve, where each point is three field
+ * elements (x, y, z).
+ *
+ * For the base point table, z is usually 1 (0 for the point at infinity).
+ * This table has 2 * 16 elements, starting with the following:
+ * index | bits | point
+ * ------+---------+------------------------------
+ * 0 | 0 0 0 0 | 0G
+ * 1 | 0 0 0 1 | 1G
+ * 2 | 0 0 1 0 | 2^64G
+ * 3 | 0 0 1 1 | (2^64 + 1)G
+ * 4 | 0 1 0 0 | 2^128G
+ * 5 | 0 1 0 1 | (2^128 + 1)G
+ * 6 | 0 1 1 0 | (2^128 + 2^64)G
+ * 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
+ * 8 | 1 0 0 0 | 2^192G
+ * 9 | 1 0 0 1 | (2^192 + 1)G
+ * 10 | 1 0 1 0 | (2^192 + 2^64)G
+ * 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
+ * 12 | 1 1 0 0 | (2^192 + 2^128)G
+ * 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
+ * 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
+ * 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
+ * followed by a copy of this with each element multiplied by 2^32.
+ *
+ * The reason for this is so that we can clock bits into four different
+ * locations when doing simple scalar multiplies against the base point,
+ * and then another four locations using the second 16 elements.
+ *
+ * Tables for other points have table[i] = iG for i in 0 .. 16. */
+
+/* gmul is the table of precomputed base points */
+static const smallfelem gmul[2][16][3] =
+{{{{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+ {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2, 0x6b17d1f2e12c4247},
+ {0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16, 0x4fe342e2fe1a7f9b},
+ {1, 0, 0, 0}},
+ {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de, 0x0fa822bc2811aaa5},
+ {0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b, 0xbff44ae8f5dba80d},
+ {1, 0, 0, 0}},
+ {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789, 0x300a4bbc89d6726f},
+ {0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f, 0x72aac7e0d09b4644},
+ {1, 0, 0, 0}},
+ {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e, 0x447d739beedb5e67},
+ {0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7, 0x2d4825ab834131ee},
+ {1, 0, 0, 0}},
+ {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60, 0xef9519328a9c72ff},
+ {0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c, 0x611e9fc37dbb2c9b},
+ {1, 0, 0, 0}},
+ {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf, 0x550663797b51f5d8},
+ {0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5, 0x157164848aecb851},
+ {1, 0, 0, 0}},
+ {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391, 0xeb5d7745b21141ea},
+ {0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee, 0xeafd72ebdbecc17b},
+ {1, 0, 0, 0}},
+ {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5, 0xa6d39677a7849276},
+ {0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf, 0x674f84749b0b8816},
+ {1, 0, 0, 0}},
+ {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb, 0x4e769e7672c9ddad},
+ {0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281, 0x42b99082de830663},
+ {1, 0, 0, 0}},
+ {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478, 0x78878ef61c6ce04d},
+ {0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def, 0xb6cb3f5d7b72c321},
+ {1, 0, 0, 0}},
+ {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae, 0x0c88bc4d716b1287},
+ {0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa, 0xdd5ddea3f3901dc6},
+ {1, 0, 0, 0}},
+ {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3, 0x68f344af6b317466},
+ {0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3, 0x31b9c405f8540a20},
+ {1, 0, 0, 0}},
+ {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0, 0x4052bf4b6f461db9},
+ {0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8, 0xfecf4d5190b0fc61},
+ {1, 0, 0, 0}},
+ {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a, 0x1eddbae2c802e41a},
+ {0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0, 0x43104d86560ebcfc},
+ {1, 0, 0, 0}},
+ {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a, 0xb48e26b484f7a21c},
+ {0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668, 0xfac015404d4d3dab},
+ {1, 0, 0, 0}}},
+ {{{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+ {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da, 0x7fe36b40af22af89},
+ {0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1, 0xe697d45825b63624},
+ {1, 0, 0, 0}},
+ {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902, 0x4a5b506612a677a6},
+ {0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40, 0xeb13461ceac089f1},
+ {1, 0, 0, 0}},
+ {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857, 0x0781b8291c6a220a},
+ {0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434, 0x690cde8df0151593},
+ {1, 0, 0, 0}},
+ {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326, 0x8a535f566ec73617},
+ {0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf, 0x0455c08468b08bd7},
+ {1, 0, 0, 0}},
+ {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279, 0x06bada7ab77f8276},
+ {0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70, 0x5b476dfd0e6cb18a},
+ {1, 0, 0, 0}},
+ {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8, 0x3e29864e8a2ec908},
+ {0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed, 0x239b90ea3dc31e7e},
+ {1, 0, 0, 0}},
+ {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4, 0x820f4dd949f72ff7},
+ {0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3, 0x140406ec783a05ec},
+ {1, 0, 0, 0}},
+ {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe, 0x68f6b8542783dfee},
+ {0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028, 0xcbe1feba92e40ce6},
+ {1, 0, 0, 0}},
+ {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927, 0xd0b2f94d2f420109},
+ {0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a, 0x971459828b0719e5},
+ {1, 0, 0, 0}},
+ {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687, 0x961610004a866aba},
+ {0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c, 0x7acb9fadcee75e44},
+ {1, 0, 0, 0}},
+ {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea, 0x24eb9acca333bf5b},
+ {0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d, 0x69f891c5acd079cc},
+ {1, 0, 0, 0}},
+ {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514, 0xe51f547c5972a107},
+ {0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06, 0x1c309a2b25bb1387},
+ {1, 0, 0, 0}},
+ {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828, 0x20b87b8aa2c4e503},
+ {0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044, 0xf5c6fa49919776be},
+ {1, 0, 0, 0}},
+ {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56, 0x1ed7d1b9332010b9},
+ {0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24, 0x3a2b03f03217257a},
+ {1, 0, 0, 0}},
+ {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b, 0x15fee545c78dd9f6},
+ {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb, 0x4ab5b6b2b8753f81},
+ {1, 0, 0, 0}}}};
+
+/* select_point selects the |idx|th point from a precomputation table and
+ * copies it to out. */
+static void select_point(const u64 idx, unsigned int size, const smallfelem pre_comp[16][3], smallfelem out[3])
+ {
+ unsigned i, j;
+ u64 *outlimbs = &out[0][0];
+ memset(outlimbs, 0, 3 * sizeof(smallfelem));
+
+ for (i = 0; i < size; i++)
+ {
+ const u64 *inlimbs = (u64*) &pre_comp[i][0][0];
+ u64 mask = i ^ idx;
+ mask |= mask >> 4;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (j = 0; j < NLIMBS * 3; j++)
+ outlimbs[j] |= inlimbs[j] & mask;
+ }
+ }
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, int i)
+ {
+ if ((i < 0) || (i >= 256))
+ return 0;
+ return (in[i >> 3] >> (i & 7)) & 1;
+ }
+
+/* Interleaved point multiplication using precomputed point multiples:
+ * The small point multiples 0*P, 1*P, ..., 17*P are in pre_comp[],
+ * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
+ * of the generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
+static void batch_mul(felem x_out, felem y_out, felem z_out,
+ const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar,
+ const int mixed, const smallfelem pre_comp[][17][3], const smallfelem g_pre_comp[2][16][3])
+ {
+ int i, skip;
+ unsigned num, gen_mul = (g_scalar != NULL);
+ felem nq[3], ftmp;
+ smallfelem tmp[3];
+ u64 bits;
+ u8 sign, digit;
+
+ /* set nq to the point at infinity */
+ memset(nq, 0, 3 * sizeof(felem));
+
+ /* Loop over all scalars msb-to-lsb, interleaving additions
+ * of multiples of the generator (two in each of the last 32 rounds)
+ * and additions of other points multiples (every 5th round).
+ */
+ skip = 1; /* save two point operations in the first round */
+ for (i = (num_points ? 255 : 31); i >= 0; --i)
+ {
+ /* double */
+ if (!skip)
+ point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+
+ /* add multiples of the generator */
+ if (gen_mul && (i <= 31))
+ {
+ /* first, look 32 bits upwards */
+ bits = get_bit(g_scalar, i + 224) << 3;
+ bits |= get_bit(g_scalar, i + 160) << 2;
+ bits |= get_bit(g_scalar, i + 96) << 1;
+ bits |= get_bit(g_scalar, i + 32);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[1], tmp);
+
+ if (!skip)
+ {
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
+ }
+ else
+ {
+ smallfelem_expand(nq[0], tmp[0]);
+ smallfelem_expand(nq[1], tmp[1]);
+ smallfelem_expand(nq[2], tmp[2]);
+ skip = 0;
+ }
+
+ /* second, look at the current position */
+ bits = get_bit(g_scalar, i + 192) << 3;
+ bits |= get_bit(g_scalar, i + 128) << 2;
+ bits |= get_bit(g_scalar, i + 64) << 1;
+ bits |= get_bit(g_scalar, i);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[0], tmp);
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
+ }
+
+ /* do other additions every 5 doublings */
+ if (num_points && (i % 5 == 0))
+ {
+ /* loop over all scalars */
+ for (num = 0; num < num_points; ++num)
+ {
+ bits = get_bit(scalars[num], i + 4) << 5;
+ bits |= get_bit(scalars[num], i + 3) << 4;
+ bits |= get_bit(scalars[num], i + 2) << 3;
+ bits |= get_bit(scalars[num], i + 1) << 2;
+ bits |= get_bit(scalars[num], i) << 1;
+ bits |= get_bit(scalars[num], i - 1);
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ /* select the point to add or subtract, in constant time */
+ select_point(digit, 17, pre_comp[num], tmp);
+ smallfelem_neg(ftmp, tmp[1]); /* (X, -Y, Z) is the negative point */
+ copy_small_conditional(ftmp, tmp[1], (((limb) sign) - 1));
+ felem_contract(tmp[1], ftmp);
+
+ if (!skip)
+ {
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ mixed, tmp[0], tmp[1], tmp[2]);
+ }
+ else
+ {
+ smallfelem_expand(nq[0], tmp[0]);
+ smallfelem_expand(nq[1], tmp[1]);
+ smallfelem_expand(nq[2], tmp[2]);
+ skip = 0;
+ }
+ }
+ }
+ }
+ felem_assign(x_out, nq[0]);
+ felem_assign(y_out, nq[1]);
+ felem_assign(z_out, nq[2]);
+ }
+
+/* Precomputation for the group generator. */
+typedef struct {
+ smallfelem g_pre_comp[2][16][3];
+ int references;
+} NISTP256_PRE_COMP;
+
+const EC_METHOD *EC_GFp_nistp256_method(void)
+ {
+ static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
+ NID_X9_62_prime_field,
+ ec_GFp_nistp256_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_nist_group_copy,
+ ec_GFp_nistp256_group_set_curve,
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+ ec_GFp_simple_point_copy,
+ ec_GFp_simple_point_set_to_infinity,
+ ec_GFp_simple_set_Jprojective_coordinates_GFp,
+ ec_GFp_simple_get_Jprojective_coordinates_GFp,
+ ec_GFp_simple_point_set_affine_coordinates,
+ ec_GFp_nistp256_point_get_affine_coordinates,
+ 0 /* point_set_compressed_coordinates */,
+ 0 /* point2oct */,
+ 0 /* oct2point */,
+ ec_GFp_simple_add,
+ ec_GFp_simple_dbl,
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
+ ec_GFp_simple_cmp,
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ ec_GFp_nistp256_points_mul,
+ ec_GFp_nistp256_precompute_mult,
+ ec_GFp_nistp256_have_precompute_mult,
+ ec_GFp_nist_field_mul,
+ ec_GFp_nist_field_sqr,
+ 0 /* field_div */,
+ 0 /* field_encode */,
+ 0 /* field_decode */,
+ 0 /* field_set_to_one */ };
+
+ return &ret;
+ }
+
+/******************************************************************************/
+/* FUNCTIONS TO MANAGE PRECOMPUTATION
+ */
+
+static NISTP256_PRE_COMP *nistp256_pre_comp_new()
+ {
+ NISTP256_PRE_COMP *ret = NULL;
+ ret = (NISTP256_PRE_COMP *) OPENSSL_malloc(sizeof *ret);
+ if (!ret)
+ {
+ ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ return ret;
+ }
+ memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
+ ret->references = 1;
+ return ret;
+ }
+
+static void *nistp256_pre_comp_dup(void *src_)
+ {
+ NISTP256_PRE_COMP *src = src_;
+
+ /* no need to actually copy, these objects never change! */
+ CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+
+ return src_;
+ }
+
+static void nistp256_pre_comp_free(void *pre_)
+ {
+ int i;
+ NISTP256_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_free(pre);
+ }
+
+static void nistp256_pre_comp_clear_free(void *pre_)
+ {
+ int i;
+ NISTP256_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_cleanse(pre, sizeof *pre);
+ OPENSSL_free(pre);
+ }
+
+/******************************************************************************/
+/* OPENSSL EC_METHOD FUNCTIONS
+ */
+
+int ec_GFp_nistp256_group_init(EC_GROUP *group)
+ {
+ int ret;
+ ret = ec_GFp_simple_group_init(group);
+ group->a_is_minus3 = 1;
+ return ret;
+ }
+
+int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+ {
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *curve_p, *curve_a, *curve_b;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
+ BN_CTX_start(ctx);
+ if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_b = BN_CTX_get(ctx)) == NULL)) goto err;
+ BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p);
+ BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
+ BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b);
+ if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
+ (BN_cmp(curve_b, b)))
+ {
+ ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE,
+ EC_R_WRONG_CURVE_PARAMETERS);
+ goto err;
+ }
+ group->field_mod_func = BN_nist_mod_256;
+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
+ * (X', Y') = (X/Z^2, Y/Z^3) */
+int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+ {
+ felem z1, z2, x_in, y_in;
+ smallfelem x_out, y_out;
+ longfelem tmp;
+
+ if (EC_POINT_is_at_infinity(group, point))
+ {
+ ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
+ EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+ if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
+ (!BN_to_felem(z1, &point->Z))) return 0;
+ felem_inv(z2, z1);
+ felem_square(tmp, z2); felem_reduce(z1, tmp);
+ felem_mul(tmp, x_in, z1); felem_reduce(x_in, tmp);
+ felem_contract(x_out, x_in);
+ if (x != NULL)
+ {
+ if (!smallfelem_to_BN(x, x_out)) {
+ ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ felem_mul(tmp, z1, z2); felem_reduce(z1, tmp);
+ felem_mul(tmp, y_in, z1); felem_reduce(y_in, tmp);
+ felem_contract(y_out, y_in);
+ if (y != NULL)
+ {
+ if (!smallfelem_to_BN(y, y_out))
+ {
+ ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+static void make_points_affine(size_t num, smallfelem points[/* num */][3], smallfelem tmp_smallfelems[/* num+1 */])
+ {
+ /* Runs in constant time, unless an input is the point at infinity
+ * (which normally shouldn't happen). */
+ ec_GFp_nistp_points_make_affine_internal(
+ num,
+ points,
+ sizeof(smallfelem),
+ tmp_smallfelems,
+ (void (*)(void *)) smallfelem_one,
+ (int (*)(const void *)) smallfelem_is_zero_int,
+ (void (*)(void *, const void *)) smallfelem_assign,
+ (void (*)(void *, const void *)) smallfelem_square_contract,
+ (void (*)(void *, const void *, const void *)) smallfelem_mul_contract,
+ (void (*)(void *, const void *)) smallfelem_inv_contract,
+ (void (*)(void *, const void *)) smallfelem_assign /* nothing to contract */);
+ }
+
+/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
+ * Result is stored in r (r can equal one of the inputs). */
+int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num, const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
+ {
+ int ret = 0;
+ int j;
+ int mixed = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y, *z, *tmp_scalar;
+ felem_bytearray g_secret;
+ felem_bytearray *secrets = NULL;
+ smallfelem (*pre_comp)[17][3] = NULL;
+ smallfelem *tmp_smallfelems = NULL;
+ felem_bytearray tmp;
+ unsigned i, num_bytes;
+ int have_pre_comp = 0;
+ size_t num_points = num;
+ smallfelem x_in, y_in, z_in;
+ felem x_out, y_out, z_out;
+ NISTP256_PRE_COMP *pre = NULL;
+ const smallfelem (*g_pre_comp)[16][3] = NULL;
+ EC_POINT *generator = NULL;
+ const EC_POINT *p = NULL;
+ const BIGNUM *p_scalar = NULL;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) ||
+ ((y = BN_CTX_get(ctx)) == NULL) ||
+ ((z = BN_CTX_get(ctx)) == NULL) ||
+ ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
+ goto err;
+
+ if (scalar != NULL)
+ {
+ pre = EC_EX_DATA_get_data(group->extra_data,
+ nistp256_pre_comp_dup, nistp256_pre_comp_free,
+ nistp256_pre_comp_clear_free);
+ if (pre)
+ /* we have precomputation, try to use it */
+ g_pre_comp = (const smallfelem (*)[16][3]) pre->g_pre_comp;
+ else
+ /* try to use the standard precomputation */
+ g_pre_comp = &gmul[0];
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ /* get the generator from precomputation */
+ if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
+ !smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
+ !smallfelem_to_BN(z, g_pre_comp[0][1][2]))
+ {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
+ generator, x, y, z, ctx))
+ goto err;
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+ /* precomputation matches generator */
+ have_pre_comp = 1;
+ else
+ /* we don't have valid precomputation:
+ * treat the generator as a random point */
+ num_points++;
+ }
+ if (num_points > 0)
+ {
+ if (num_points >= 3)
+ {
+ /* unless we precompute multiples for just one or two points,
+ * converting those into affine form is time well spent */
+ mixed = 1;
+ }
+ secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
+ pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem));
+ if (mixed)
+ tmp_smallfelems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem));
+ if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_smallfelems == NULL)))
+ {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* we treat NULL scalars as 0, and NULL points as points at infinity,
+ * i.e., they contribute nothing to the linear combination */
+ memset(secrets, 0, num_points * sizeof(felem_bytearray));
+ memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem));
+ for (i = 0; i < num_points; ++i)
+ {
+ if (i == num)
+ /* we didn't have a valid precomputation, so we pick
+ * the generator */
+ {
+ p = EC_GROUP_get0_generator(group);
+ p_scalar = scalar;
+ }
+ else
+ /* the i^th point */
+ {
+ p = points[i];
+ p_scalar = scalars[i];
+ }
+ if ((p_scalar != NULL) && (p != NULL))
+ {
+ /* reduce scalar to 0 <= scalar < 2^256 */
+ if ((BN_num_bits(p_scalar) > 256) || (BN_is_negative(p_scalar)))
+ {
+ /* this is an unusual input, and we don't guarantee
+ * constant-timeness */
+ if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx))
+ {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ }
+ else
+ num_bytes = BN_bn2bin(p_scalar, tmp);
+ flip_endian(secrets[i], tmp, num_bytes);
+ /* precompute multiples */
+ if ((!BN_to_felem(x_out, &p->X)) ||
+ (!BN_to_felem(y_out, &p->Y)) ||
+ (!BN_to_felem(z_out, &p->Z))) goto err;
+ felem_shrink(pre_comp[i][1][0], x_out);
+ felem_shrink(pre_comp[i][1][1], y_out);
+ felem_shrink(pre_comp[i][1][2], z_out);
+ for (j = 2; j <= 16; ++j)
+ {
+ if (j & 1)
+ {
+ point_add_small(
+ pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
+ pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
+ pre_comp[i][j-1][0], pre_comp[i][j-1][1], pre_comp[i][j-1][2]);
+ }
+ else
+ {
+ point_double_small(
+ pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
+ pre_comp[i][j/2][0], pre_comp[i][j/2][1], pre_comp[i][j/2][2]);
+ }
+ }
+ }
+ }
+ if (mixed)
+ make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems);
+ }
+
+ /* the scalar for the generator */
+ if ((scalar != NULL) && (have_pre_comp))
+ {
+ memset(g_secret, 0, sizeof(g_secret));
+ /* reduce scalar to 0 <= scalar < 2^256 */
+ if ((BN_num_bits(scalar) > 256) || (BN_is_negative(scalar)))
+ {
+ /* this is an unusual input, and we don't guarantee
+ * constant-timeness */
+ if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx))
+ {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ }
+ else
+ num_bytes = BN_bn2bin(scalar, tmp);
+ flip_endian(g_secret, tmp, num_bytes);
+ /* do the multiplication with generator precomputation*/
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray (*)) secrets, num_points,
+ g_secret,
+ mixed, (const smallfelem (*)[17][3]) pre_comp,
+ g_pre_comp);
+ }
+ else
+ /* do the multiplication without generator precomputation */
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray (*)) secrets, num_points,
+ NULL, mixed, (const smallfelem (*)[17][3]) pre_comp, NULL);
+ /* reduce the output to its unique minimal representation */
+ felem_contract(x_in, x_out);
+ felem_contract(y_in, y_out);
+ felem_contract(z_in, z_out);
+ if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) ||
+ (!smallfelem_to_BN(z, z_in)))
+ {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (secrets != NULL)
+ OPENSSL_free(secrets);
+ if (pre_comp != NULL)
+ OPENSSL_free(pre_comp);
+ if (tmp_smallfelems != NULL)
+ OPENSSL_free(tmp_smallfelems);
+ return ret;
+ }
+
+int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+ {
+ int ret = 0;
+ NISTP256_PRE_COMP *pre = NULL;
+ int i, j;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y;
+ EC_POINT *generator = NULL;
+ smallfelem tmp_smallfelems[32];
+ felem x_tmp, y_tmp, z_tmp;
+
+ /* throw away old precomputation */
+ EC_EX_DATA_free_data(&group->extra_data, nistp256_pre_comp_dup,
+ nistp256_pre_comp_free, nistp256_pre_comp_clear_free);
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) ||
+ ((y = BN_CTX_get(ctx)) == NULL))
+ goto err;
+ /* get the generator */
+ if (group->generator == NULL) goto err;
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ BN_bin2bn(nistp256_curve_params[3], sizeof (felem_bytearray), x);
+ BN_bin2bn(nistp256_curve_params[4], sizeof (felem_bytearray), y);
+ if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
+ goto err;
+ if ((pre = nistp256_pre_comp_new()) == NULL)
+ goto err;
+ /* if the generator is the standard one, use built-in precomputation */
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+ {
+ memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
+ ret = 1;
+ goto err;
+ }
+ if ((!BN_to_felem(x_tmp, &group->generator->X)) ||
+ (!BN_to_felem(y_tmp, &group->generator->Y)) ||
+ (!BN_to_felem(z_tmp, &group->generator->Z)))
+ goto err;
+ felem_shrink(pre->g_pre_comp[0][1][0], x_tmp);
+ felem_shrink(pre->g_pre_comp[0][1][1], y_tmp);
+ felem_shrink(pre->g_pre_comp[0][1][2], z_tmp);
+ /* compute 2^64*G, 2^128*G, 2^192*G for the first table,
+ * 2^32*G, 2^96*G, 2^160*G, 2^224*G for the second one
+ */
+ for (i = 1; i <= 8; i <<= 1)
+ {
+ point_double_small(
+ pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
+ pre->g_pre_comp[0][i][0], pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
+ for (j = 0; j < 31; ++j)
+ {
+ point_double_small(
+ pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
+ pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
+ }
+ if (i == 8)
+ break;
+ point_double_small(
+ pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
+ pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
+ for (j = 0; j < 31; ++j)
+ {
+ point_double_small(
+ pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
+ pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2]);
+ }
+ }
+ for (i = 0; i < 2; i++)
+ {
+ /* g_pre_comp[i][0] is the point at infinity */
+ memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
+ /* the remaining multiples */
+ /* 2^64*G + 2^128*G resp. 2^96*G + 2^160*G */
+ point_add_small(
+ pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1], pre->g_pre_comp[i][6][2],
+ pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
+ pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
+ /* 2^64*G + 2^192*G resp. 2^96*G + 2^224*G */
+ point_add_small(
+ pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1], pre->g_pre_comp[i][10][2],
+ pre->g_pre_comp[i][8][0], pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+ pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
+ /* 2^128*G + 2^192*G resp. 2^160*G + 2^224*G */
+ point_add_small(
+ pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
+ pre->g_pre_comp[i][8][0], pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+ pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2]);
+ /* 2^64*G + 2^128*G + 2^192*G resp. 2^96*G + 2^160*G + 2^224*G */
+ point_add_small(
+ pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1], pre->g_pre_comp[i][14][2],
+ pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
+ pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
+ for (j = 1; j < 8; ++j)
+ {
+ /* odd multiples: add G resp. 2^32*G */
+ point_add_small(
+ pre->g_pre_comp[i][2*j+1][0], pre->g_pre_comp[i][2*j+1][1], pre->g_pre_comp[i][2*j+1][2],
+ pre->g_pre_comp[i][2*j][0], pre->g_pre_comp[i][2*j][1], pre->g_pre_comp[i][2*j][2],
+ pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1], pre->g_pre_comp[i][1][2]);
+ }
+ }
+ make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems);
+
+ if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp256_pre_comp_dup,
+ nistp256_pre_comp_free, nistp256_pre_comp_clear_free))
+ goto err;
+ ret = 1;
+ pre = NULL;
+ err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (pre)
+ nistp256_pre_comp_free(pre);
+ return ret;
+ }
+
+int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group)
+ {
+ if (EC_EX_DATA_get_data(group->extra_data, nistp256_pre_comp_dup,
+ nistp256_pre_comp_free, nistp256_pre_comp_clear_free)
+ != NULL)
+ return 1;
+ else
+ return 0;
+ }
+#else
+static void *dummy=&dummy;
+#endif
diff --git a/deps/openssl/openssl/crypto/ec/ecp_nistp521.c b/deps/openssl/openssl/crypto/ec/ecp_nistp521.c
new file mode 100644
index 000000000..178b655f7
--- /dev/null
+++ b/deps/openssl/openssl/crypto/ec/ecp_nistp521.c
@@ -0,0 +1,2025 @@
+/* crypto/ec/ecp_nistp521.c */
+/*
+ * Written by Adam Langley (Google) for the OpenSSL project
+ */
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication
+ *
+ * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
+ * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
+ * work which got its smarts from Daniel J. Bernstein's work on the same.
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+
+#ifndef OPENSSL_SYS_VMS
+#include <stdint.h>
+#else
+#include <inttypes.h>
+#endif
+
+#include <string.h>
+#include <openssl/err.h>
+#include "ec_lcl.h"
+
+#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+ /* even with gcc, the typedef won't work for 32-bit platforms */
+ typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
+#else
+ #error "Need GCC 3.1 or later to define type uint128_t"
+#endif
+
+typedef uint8_t u8;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+/* The underlying field.
+ *
+ * P521 operates over GF(2^521-1). We can serialise an element of this field
+ * into 66 bytes where the most significant byte contains only a single bit. We
+ * call this an felem_bytearray. */
+
+typedef u8 felem_bytearray[66];
+
+/* These are the parameters of P521, taken from FIPS 186-3, section D.1.2.5.
+ * These values are big-endian. */
+static const felem_bytearray nistp521_curve_params[5] =
+ {
+ {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff},
+ {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a = -3 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xfc},
+ {0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, /* b */
+ 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
+ 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
+ 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
+ 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
+ 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
+ 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
+ 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
+ 0x3f, 0x00},
+ {0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, /* x */
+ 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
+ 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
+ 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
+ 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
+ 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
+ 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
+ 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
+ 0xbd, 0x66},
+ {0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, /* y */
+ 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
+ 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
+ 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
+ 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
+ 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
+ 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
+ 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
+ 0x66, 0x50}
+ };
+
+/* The representation of field elements.
+ * ------------------------------------
+ *
+ * We represent field elements with nine values. These values are either 64 or
+ * 128 bits and the field element represented is:
+ * v[0]*2^0 + v[1]*2^58 + v[2]*2^116 + ... + v[8]*2^464 (mod p)
+ * Each of the nine values is called a 'limb'. Since the limbs are spaced only
+ * 58 bits apart, but are greater than 58 bits in length, the most significant
+ * bits of each limb overlap with the least significant bits of the next.
+ *
+ * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a
+ * 'largefelem' */
+
+#define NLIMBS 9
+
+typedef uint64_t limb;
+typedef limb felem[NLIMBS];
+typedef uint128_t largefelem[NLIMBS];
+
+static const limb bottom57bits = 0x1ffffffffffffff;
+static const limb bottom58bits = 0x3ffffffffffffff;
+
+/* bin66_to_felem takes a little-endian byte array and converts it into felem
+ * form. This assumes that the CPU is little-endian. */
+static void bin66_to_felem(felem out, const u8 in[66])
+ {
+ out[0] = (*((limb*) &in[0])) & bottom58bits;
+ out[1] = (*((limb*) &in[7]) >> 2) & bottom58bits;
+ out[2] = (*((limb*) &in[14]) >> 4) & bottom58bits;
+ out[3] = (*((limb*) &in[21]) >> 6) & bottom58bits;
+ out[4] = (*((limb*) &in[29])) & bottom58bits;
+ out[5] = (*((limb*) &in[36]) >> 2) & bottom58bits;
+ out[6] = (*((limb*) &in[43]) >> 4) & bottom58bits;
+ out[7] = (*((limb*) &in[50]) >> 6) & bottom58bits;
+ out[8] = (*((limb*) &in[58])) & bottom57bits;
+ }
+
+/* felem_to_bin66 takes an felem and serialises into a little endian, 66 byte
+ * array. This assumes that the CPU is little-endian. */
+static void felem_to_bin66(u8 out[66], const felem in)
+ {
+ memset(out, 0, 66);
+ (*((limb*) &out[0])) = in[0];
+ (*((limb*) &out[7])) |= in[1] << 2;
+ (*((limb*) &out[14])) |= in[2] << 4;
+ (*((limb*) &out[21])) |= in[3] << 6;
+ (*((limb*) &out[29])) = in[4];
+ (*((limb*) &out[36])) |= in[5] << 2;
+ (*((limb*) &out[43])) |= in[6] << 4;
+ (*((limb*) &out[50])) |= in[7] << 6;
+ (*((limb*) &out[58])) = in[8];
+ }
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len)
+ {
+ unsigned i;
+ for (i = 0; i < len; ++i)
+ out[i] = in[len-1-i];
+ }
+
+/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
+static int BN_to_felem(felem out, const BIGNUM *bn)
+ {
+ felem_bytearray b_in;
+ felem_bytearray b_out;
+ unsigned num_bytes;
+
+ /* BN_bn2bin eats leading zeroes */
+ memset(b_out, 0, sizeof b_out);
+ num_bytes = BN_num_bytes(bn);
+ if (num_bytes > sizeof b_out)
+ {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ if (BN_is_negative(bn))
+ {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ num_bytes = BN_bn2bin(bn, b_in);
+ flip_endian(b_out, b_in, num_bytes);
+ bin66_to_felem(out, b_out);
+ return 1;
+ }
+
+/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
+static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
+ {
+ felem_bytearray b_in, b_out;
+ felem_to_bin66(b_in, in);
+ flip_endian(b_out, b_in, sizeof b_out);
+ return BN_bin2bn(b_out, sizeof b_out, out);
+ }
+
+
+/* Field operations
+ * ---------------- */
+
+static void felem_one(felem out)
+ {
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 0;
+ out[3] = 0;
+ out[4] = 0;
+ out[5] = 0;
+ out[6] = 0;
+ out[7] = 0;
+ out[8] = 0;
+ }
+
+static void felem_assign(felem out, const felem in)
+ {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ out[4] = in[4];
+ out[5] = in[5];
+ out[6] = in[6];
+ out[7] = in[7];
+ out[8] = in[8];
+ }
+
+/* felem_sum64 sets out = out + in. */
+static void felem_sum64(felem out, const felem in)
+ {
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+ out[4] += in[4];
+ out[5] += in[5];
+ out[6] += in[6];
+ out[7] += in[7];
+ out[8] += in[8];
+ }
+
+/* felem_scalar sets out = in * scalar */
+static void felem_scalar(felem out, const felem in, limb scalar)
+ {
+ out[0] = in[0] * scalar;
+ out[1] = in[1] * scalar;
+ out[2] = in[2] * scalar;
+ out[3] = in[3] * scalar;
+ out[4] = in[4] * scalar;
+ out[5] = in[5] * scalar;
+ out[6] = in[6] * scalar;
+ out[7] = in[7] * scalar;
+ out[8] = in[8] * scalar;
+ }
+
+/* felem_scalar64 sets out = out * scalar */
+static void felem_scalar64(felem out, limb scalar)
+ {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+ out[7] *= scalar;
+ out[8] *= scalar;
+ }
+
+/* felem_scalar128 sets out = out * scalar */
+static void felem_scalar128(largefelem out, limb scalar)
+ {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+ out[7] *= scalar;
+ out[8] *= scalar;
+ }
+
+/* felem_neg sets |out| to |-in|
+ * On entry:
+ * in[i] < 2^59 + 2^14
+ * On exit:
+ * out[i] < 2^62
+ */
+static void felem_neg(felem out, const felem in)
+ {
+ /* In order to prevent underflow, we subtract from 0 mod p. */
+ static const limb two62m3 = (((limb)1) << 62) - (((limb)1) << 5);
+ static const limb two62m2 = (((limb)1) << 62) - (((limb)1) << 4);
+
+ out[0] = two62m3 - in[0];
+ out[1] = two62m2 - in[1];
+ out[2] = two62m2 - in[2];
+ out[3] = two62m2 - in[3];
+ out[4] = two62m2 - in[4];
+ out[5] = two62m2 - in[5];
+ out[6] = two62m2 - in[6];
+ out[7] = two62m2 - in[7];
+ out[8] = two62m2 - in[8];
+ }
+
+/* felem_diff64 subtracts |in| from |out|
+ * On entry:
+ * in[i] < 2^59 + 2^14
+ * On exit:
+ * out[i] < out[i] + 2^62
+ */
+static void felem_diff64(felem out, const felem in)
+ {
+ /* In order to prevent underflow, we add 0 mod p before subtracting. */
+ static const limb two62m3 = (((limb)1) << 62) - (((limb)1) << 5);
+ static const limb two62m2 = (((limb)1) << 62) - (((limb)1) << 4);
+
+ out[0] += two62m3 - in[0];
+ out[1] += two62m2 - in[1];
+ out[2] += two62m2 - in[2];
+ out[3] += two62m2 - in[3];
+ out[4] += two62m2 - in[4];
+ out[5] += two62m2 - in[5];
+ out[6] += two62m2 - in[6];
+ out[7] += two62m2 - in[7];
+ out[8] += two62m2 - in[8];
+ }
+
+/* felem_diff_128_64 subtracts |in| from |out|
+ * On entry:
+ * in[i] < 2^62 + 2^17
+ * On exit:
+ * out[i] < out[i] + 2^63
+ */
+static void felem_diff_128_64(largefelem out, const felem in)
+ {
+ /* In order to prevent underflow, we add 0 mod p before subtracting. */
+ static const limb two63m6 = (((limb)1) << 62) - (((limb)1) << 5);
+ static const limb two63m5 = (((limb)1) << 62) - (((limb)1) << 4);
+
+ out[0] += two63m6 - in[0];
+ out[1] += two63m5 - in[1];
+ out[2] += two63m5 - in[2];
+ out[3] += two63m5 - in[3];
+ out[4] += two63m5 - in[4];
+ out[5] += two63m5 - in[5];
+ out[6] += two63m5 - in[6];
+ out[7] += two63m5 - in[7];
+ out[8] += two63m5 - in[8];
+ }
+
+/* felem_diff_128_64 subtracts |in| from |out|
+ * On entry:
+ * in[i] < 2^126
+ * On exit:
+ * out[i] < out[i] + 2^127 - 2^69
+ */
+static void felem_diff128(largefelem out, const largefelem in)
+ {
+ /* In order to prevent underflow, we add 0 mod p before subtracting. */
+ static const uint128_t two127m70 = (((uint128_t)1) << 127) - (((uint128_t)1) << 70);
+ static const uint128_t two127m69 = (((uint128_t)1) << 127) - (((uint128_t)1) << 69);
+
+ out[0] += (two127m70 - in[0]);
+ out[1] += (two127m69 - in[1]);
+ out[2] += (two127m69 - in[2]);
+ out[3] += (two127m69 - in[3]);
+ out[4] += (two127m69 - in[4]);
+ out[5] += (two127m69 - in[5]);
+ out[6] += (two127m69 - in[6]);
+ out[7] += (two127m69 - in[7]);
+ out[8] += (two127m69 - in[8]);
+ }
+
+/* felem_square sets |out| = |in|^2
+ * On entry:
+ * in[i] < 2^62
+ * On exit:
+ * out[i] < 17 * max(in[i]) * max(in[i])
+ */
+static void felem_square(largefelem out, const felem in)
+ {
+ felem inx2, inx4;
+ felem_scalar(inx2, in, 2);
+ felem_scalar(inx4, in, 4);
+
+ /* We have many cases were we want to do
+ * in[x] * in[y] +
+ * in[y] * in[x]
+ * This is obviously just
+ * 2 * in[x] * in[y]
+ * However, rather than do the doubling on the 128 bit result, we
+ * double one of the inputs to the multiplication by reading from
+ * |inx2| */
+
+ out[0] = ((uint128_t) in[0]) * in[0];
+ out[1] = ((uint128_t) in[0]) * inx2[1];
+ out[2] = ((uint128_t) in[0]) * inx2[2] +
+ ((uint128_t) in[1]) * in[1];
+ out[3] = ((uint128_t) in[0]) * inx2[3] +
+ ((uint128_t) in[1]) * inx2[2];
+ out[4] = ((uint128_t) in[0]) * inx2[4] +
+ ((uint128_t) in[1]) * inx2[3] +
+ ((uint128_t) in[2]) * in[2];
+ out[5] = ((uint128_t) in[0]) * inx2[5] +
+ ((uint128_t) in[1]) * inx2[4] +
+ ((uint128_t) in[2]) * inx2[3];
+ out[6] = ((uint128_t) in[0]) * inx2[6] +
+ ((uint128_t) in[1]) * inx2[5] +
+ ((uint128_t) in[2]) * inx2[4] +
+ ((uint128_t) in[3]) * in[3];
+ out[7] = ((uint128_t) in[0]) * inx2[7] +
+ ((uint128_t) in[1]) * inx2[6] +
+ ((uint128_t) in[2]) * inx2[5] +
+ ((uint128_t) in[3]) * inx2[4];
+ out[8] = ((uint128_t) in[0]) * inx2[8] +
+ ((uint128_t) in[1]) * inx2[7] +
+ ((uint128_t) in[2]) * inx2[6] +
+ ((uint128_t) in[3]) * inx2[5] +
+ ((uint128_t) in[4]) * in[4];
+
+ /* The remaining limbs fall above 2^521, with the first falling at
+ * 2^522. They correspond to locations one bit up from the limbs
+ * produced above so we would have to multiply by two to align them.
+ * Again, rather than operate on the 128-bit result, we double one of
+ * the inputs to the multiplication. If we want to double for both this
+ * reason, and the reason above, then we end up multiplying by four. */
+
+ /* 9 */
+ out[0] += ((uint128_t) in[1]) * inx4[8] +
+ ((uint128_t) in[2]) * inx4[7] +
+ ((uint128_t) in[3]) * inx4[6] +
+ ((uint128_t) in[4]) * inx4[5];
+
+ /* 10 */
+ out[1] += ((uint128_t) in[2]) * inx4[8] +
+ ((uint128_t) in[3]) * inx4[7] +
+ ((uint128_t) in[4]) * inx4[6] +
+ ((uint128_t) in[5]) * inx2[5];
+
+ /* 11 */
+ out[2] += ((uint128_t) in[3]) * inx4[8] +
+ ((uint128_t) in[4]) * inx4[7] +
+ ((uint128_t) in[5]) * inx4[6];
+
+ /* 12 */
+ out[3] += ((uint128_t) in[4]) * inx4[8] +
+ ((uint128_t) in[5]) * inx4[7] +
+ ((uint128_t) in[6]) * inx2[6];
+
+ /* 13 */
+ out[4] += ((uint128_t) in[5]) * inx4[8] +
+ ((uint128_t) in[6]) * inx4[7];
+
+ /* 14 */
+ out[5] += ((uint128_t) in[6]) * inx4[8] +
+ ((uint128_t) in[7]) * inx2[7];
+
+ /* 15 */
+ out[6] += ((uint128_t) in[7]) * inx4[8];
+
+ /* 16 */
+ out[7] += ((uint128_t) in[8]) * inx2[8];
+ }
+
+/* felem_mul sets |out| = |in1| * |in2|
+ * On entry:
+ * in1[i] < 2^64
+ * in2[i] < 2^63
+ * On exit:
+ * out[i] < 17 * max(in1[i]) * max(in2[i])
+ */
+static void felem_mul(largefelem out, const felem in1, const felem in2)
+ {
+ felem in2x2;
+ felem_scalar(in2x2, in2, 2);
+
+ out[0] = ((uint128_t) in1[0]) * in2[0];
+
+ out[1] = ((uint128_t) in1[0]) * in2[1] +
+ ((uint128_t) in1[1]) * in2[0];
+
+ out[2] = ((uint128_t) in1[0]) * in2[2] +
+ ((uint128_t) in1[1]) * in2[1] +
+ ((uint128_t) in1[2]) * in2[0];
+
+ out[3] = ((uint128_t) in1[0]) * in2[3] +
+ ((uint128_t) in1[1]) * in2[2] +
+ ((uint128_t) in1[2]) * in2[1] +
+ ((uint128_t) in1[3]) * in2[0];
+
+ out[4] = ((uint128_t) in1[0]) * in2[4] +
+ ((uint128_t) in1[1]) * in2[3] +
+ ((uint128_t) in1[2]) * in2[2] +
+ ((uint128_t) in1[3]) * in2[1] +
+ ((uint128_t) in1[4]) * in2[0];
+
+ out[5] = ((uint128_t) in1[0]) * in2[5] +
+ ((uint128_t) in1[1]) * in2[4] +
+ ((uint128_t) in1[2]) * in2[3] +
+ ((uint128_t) in1[3]) * in2[2] +
+ ((uint128_t) in1[4]) * in2[1] +
+ ((uint128_t) in1[5]) * in2[0];
+
+ out[6] = ((uint128_t) in1[0]) * in2[6] +
+ ((uint128_t) in1[1]) * in2[5] +
+ ((uint128_t) in1[2]) * in2[4] +
+ ((uint128_t) in1[3]) * in2[3] +
+ ((uint128_t) in1[4]) * in2[2] +
+ ((uint128_t) in1[5]) * in2[1] +
+ ((uint128_t) in1[6]) * in2[0];
+
+ out[7] = ((uint128_t) in1[0]) * in2[7] +
+ ((uint128_t) in1[1]) * in2[6] +
+ ((uint128_t) in1[2]) * in2[5] +
+ ((uint128_t) in1[3]) * in2[4] +
+ ((uint128_t) in1[4]) * in2[3] +
+ ((uint128_t) in1[5]) * in2[2] +
+ ((uint128_t) in1[6]) * in2[1] +
+ ((uint128_t) in1[7]) * in2[0];
+
+ out[8] = ((uint128_t) in1[0]) * in2[8] +
+ ((uint128_t) in1[1]) * in2[7] +
+ ((uint128_t) in1[2]) * in2[6] +
+ ((uint128_t) in1[3]) * in2[5] +
+ ((uint128_t) in1[4]) * in2[4] +
+ ((uint128_t) in1[5]) * in2[3] +
+ ((uint128_t) in1[6]) * in2[2] +
+ ((uint128_t) in1[7]) * in2[1] +
+ ((uint128_t) in1[8]) * in2[0];
+
+ /* See comment in felem_square about the use of in2x2 here */
+
+ out[0] += ((uint128_t) in1[1]) * in2x2[8] +
+ ((uint128_t) in1[2]) * in2x2[7] +
+ ((uint128_t) in1[3]) * in2x2[6] +
+ ((uint128_t) in1[4]) * in2x2[5] +
+ ((uint128_t) in1[5]) * in2x2[4] +
+ ((uint128_t) in1[6]) * in2x2[3] +
+ ((uint128_t) in1[7]) * in2x2[2] +
+ ((uint128_t) in1[8]) * in2x2[1];
+
+ out[1] += ((uint128_t) in1[2]) * in2x2[8] +
+ ((uint128_t) in1[3]) * in2x2[7] +
+ ((uint128_t) in1[4]) * in2x2[6] +
+ ((uint128_t) in1[5]) * in2x2[5] +
+ ((uint128_t) in1[6]) * in2x2[4] +
+ ((uint128_t) in1[7]) * in2x2[3] +
+ ((uint128_t) in1[8]) * in2x2[2];
+
+ out[2] += ((uint128_t) in1[3]) * in2x2[8] +
+ ((uint128_t) in1[4]) * in2x2[7] +
+ ((uint128_t) in1[5]) * in2x2[6] +
+ ((uint128_t) in1[6]) * in2x2[5] +
+ ((uint128_t) in1[7]) * in2x2[4] +
+ ((uint128_t) in1[8]) * in2x2[3];
+
+ out[3] += ((uint128_t) in1[4]) * in2x2[8] +
+ ((uint128_t) in1[5]) * in2x2[7] +
+ ((uint128_t) in1[6]) * in2x2[6] +
+ ((uint128_t) in1[7]) * in2x2[5] +
+ ((uint128_t) in1[8]) * in2x2[4];
+
+ out[4] += ((uint128_t) in1[5]) * in2x2[8] +
+ ((uint128_t) in1[6]) * in2x2[7] +
+ ((uint128_t) in1[7]) * in2x2[6] +
+ ((uint128_t) in1[8]) * in2x2[5];
+
+ out[5] += ((uint128_t) in1[6]) * in2x2[8] +
+ ((uint128_t) in1[7]) * in2x2[7] +
+ ((uint128_t) in1[8]) * in2x2[6];
+
+ out[6] += ((uint128_t) in1[7]) * in2x2[8] +
+ ((uint128_t) in1[8]) * in2x2[7];
+
+ out[7] += ((uint128_t) in1[8]) * in2x2[8];
+ }
+
+static const limb bottom52bits = 0xfffffffffffff;
+
+/* felem_reduce converts a largefelem to an felem.
+ * On entry:
+ * in[i] < 2^128
+ * On exit:
+ * out[i] < 2^59 + 2^14
+ */
+static void felem_reduce(felem out, const largefelem in)
+ {
+ u64 overflow1, overflow2;
+
+ out[0] = ((limb) in[0]) & bottom58bits;
+ out[1] = ((limb) in[1]) & bottom58bits;
+ out[2] = ((limb) in[2]) & bottom58bits;
+ out[3] = ((limb) in[3]) & bottom58bits;
+ out[4] = ((limb) in[4]) & bottom58bits;
+ out[5] = ((limb) in[5]) & bottom58bits;
+ out[6] = ((limb) in[6]) & bottom58bits;
+ out[7] = ((limb) in[7]) & bottom58bits;
+ out[8] = ((limb) in[8]) & bottom58bits;
+
+ /* out[i] < 2^58 */
+
+ out[1] += ((limb) in[0]) >> 58;
+ out[1] += (((limb) (in[0] >> 64)) & bottom52bits) << 6;
+ /* out[1] < 2^58 + 2^6 + 2^58
+ * = 2^59 + 2^6 */
+ out[2] += ((limb) (in[0] >> 64)) >> 52;
+
+ out[2] += ((limb) in[1]) >> 58;
+ out[2] += (((limb) (in[1] >> 64)) & bottom52bits) << 6;
+ out[3] += ((limb) (in[1] >> 64)) >> 52;
+
+ out[3] += ((limb) in[2]) >> 58;
+ out[3] += (((limb) (in[2] >> 64)) & bottom52bits) << 6;
+ out[4] += ((limb) (in[2] >> 64)) >> 52;
+
+ out[4] += ((limb) in[3]) >> 58;
+ out[4] += (((limb) (in[3] >> 64)) & bottom52bits) << 6;
+ out[5] += ((limb) (in[3] >> 64)) >> 52;
+
+ out[5] += ((limb) in[4]) >> 58;
+ out[5] += (((limb) (in[4] >> 64)) & bottom52bits) << 6;
+ out[6] += ((limb) (in[4] >> 64)) >> 52;
+
+ out[6] += ((limb) in[5]) >> 58;
+ out[6] += (((limb) (in[5] >> 64)) & bottom52bits) << 6;
+ out[7] += ((limb) (in[5] >> 64)) >> 52;
+
+ out[7] += ((limb) in[6]) >> 58;
+ out[7] += (((limb) (in[6] >> 64)) & bottom52bits) << 6;
+ out[8] += ((limb) (in[6] >> 64)) >> 52;
+
+ out[8] += ((limb) in[7]) >> 58;
+ out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6;
+ /* out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12
+ * < 2^59 + 2^13 */
+ overflow1 = ((limb) (in[7] >> 64)) >> 52;
+
+ overflow1 += ((limb) in[8]) >> 58;
+ overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6;
+ overflow2 = ((limb) (in[8] >> 64)) >> 52;
+
+ overflow1 <<= 1; /* overflow1 < 2^13 + 2^7 + 2^59 */
+ overflow2 <<= 1; /* overflow2 < 2^13 */
+
+ out[0] += overflow1; /* out[0] < 2^60 */
+ out[1] += overflow2; /* out[1] < 2^59 + 2^6 + 2^13 */
+
+ out[1] += out[0] >> 58; out[0] &= bottom58bits;
+ /* out[0] < 2^58
+ * out[1] < 2^59 + 2^6 + 2^13 + 2^2
+ * < 2^59 + 2^14 */
+ }
+
+static void felem_square_reduce(felem out, const felem in)
+ {
+ largefelem tmp;
+ felem_square(tmp, in);
+ felem_reduce(out, tmp);
+ }
+
+static void felem_mul_reduce(felem out, const felem in1, const felem in2)
+ {
+ largefelem tmp;
+ felem_mul(tmp, in1, in2);
+ felem_reduce(out, tmp);
+ }
+
+/* felem_inv calculates |out| = |in|^{-1}
+ *
+ * Based on Fermat's Little Theorem:
+ * a^p = a (mod p)
+ * a^{p-1} = 1 (mod p)
+ * a^{p-2} = a^{-1} (mod p)
+ */
+static void felem_inv(felem out, const felem in)
+ {
+ felem ftmp, ftmp2, ftmp3, ftmp4;
+ largefelem tmp;
+ unsigned i;
+
+ felem_square(tmp, in); felem_reduce(ftmp, tmp); /* 2^1 */
+ felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */
+ felem_assign(ftmp2, ftmp);
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */
+ felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp); /* 2^3 - 2^0 */
+ felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^4 - 2^1 */
+
+ felem_square(tmp, ftmp2); felem_reduce(ftmp3, tmp); /* 2^3 - 2^1 */
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^4 - 2^2 */
+ felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^4 - 2^0 */
+
+ felem_assign(ftmp2, ftmp3);
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^5 - 2^1 */
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^6 - 2^2 */
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^7 - 2^3 */
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^8 - 2^4 */
+ felem_assign(ftmp4, ftmp3);
+ felem_mul(tmp, ftmp3, ftmp); felem_reduce(ftmp4, tmp); /* 2^8 - 2^1 */
+ felem_square(tmp, ftmp4); felem_reduce(ftmp4, tmp); /* 2^9 - 2^2 */
+ felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^8 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 8; i++)
+ {
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^16 - 2^8 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^16 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 16; i++)
+ {
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^32 - 2^16 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^32 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 32; i++)
+ {
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^64 - 2^32 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^64 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 64; i++)
+ {
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^128 - 2^64 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^128 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 128; i++)
+ {
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^256 - 2^128 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^256 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 256; i++)
+ {
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^512 - 2^256 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^512 - 2^0 */
+
+ for (i = 0; i < 9; i++)
+ {
+ felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^521 - 2^9 */
+ }
+ felem_mul(tmp, ftmp3, ftmp4); felem_reduce(ftmp3, tmp); /* 2^512 - 2^2 */
+ felem_mul(tmp, ftmp3, in); felem_reduce(out, tmp); /* 2^512 - 3 */
+}
+
+/* This is 2^521-1, expressed as an felem */
+static const felem kPrime =
+ {
+ 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
+ 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
+ 0x03ffffffffffffff, 0x03ffffffffffffff, 0x01ffffffffffffff
+ };
+
+/* felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
+ * otherwise.
+ * On entry:
+ * in[i] < 2^59 + 2^14
+ */
+static limb felem_is_zero(const felem in)
+ {
+ felem ftmp;
+ limb is_zero, is_p;
+ felem_assign(ftmp, in);
+
+ ftmp[0] += ftmp[8] >> 57; ftmp[8] &= bottom57bits;
+ /* ftmp[8] < 2^57 */
+ ftmp[1] += ftmp[0] >> 58; ftmp[0] &= bottom58bits;
+ ftmp[2] += ftmp[1] >> 58; ftmp[1] &= bottom58bits;
+ ftmp[3] += ftmp[2] >> 58; ftmp[2] &= bottom58bits;
+ ftmp[4] += ftmp[3] >> 58; ftmp[3] &= bottom58bits;
+ ftmp[5] += ftmp[4] >> 58; ftmp[4] &= bottom58bits;
+ ftmp[6] += ftmp[5] >> 58; ftmp[5] &= bottom58bits;
+ ftmp[7] += ftmp[6] >> 58; ftmp[6] &= bottom58bits;
+ ftmp[8] += ftmp[7] >> 58; ftmp[7] &= bottom58bits;
+ /* ftmp[8] < 2^57 + 4 */
+
+ /* The ninth limb of 2*(2^521-1) is 0x03ffffffffffffff, which is
+ * greater than our bound for ftmp[8]. Therefore we only have to check
+ * if the zero is zero or 2^521-1. */
+
+ is_zero = 0;
+ is_zero |= ftmp[0];
+ is_zero |= ftmp[1];
+ is_zero |= ftmp[2];
+ is_zero |= ftmp[3];
+ is_zero |= ftmp[4];
+ is_zero |= ftmp[5];
+ is_zero |= ftmp[6];
+ is_zero |= ftmp[7];
+ is_zero |= ftmp[8];
+
+ is_zero--;
+ /* We know that ftmp[i] < 2^63, therefore the only way that the top bit
+ * can be set is if is_zero was 0 before the decrement. */
+ is_zero = ((s64) is_zero) >> 63;
+
+ is_p = ftmp[0] ^ kPrime[0];
+ is_p |= ftmp[1] ^ kPrime[1];
+ is_p |= ftmp[2] ^ kPrime[2];
+ is_p |= ftmp[3] ^ kPrime[3];
+ is_p |= ftmp[4] ^ kPrime[4];
+ is_p |= ftmp[5] ^ kPrime[5];
+ is_p |= ftmp[6] ^ kPrime[6];
+ is_p |= ftmp[7] ^ kPrime[7];
+ is_p |= ftmp[8] ^ kPrime[8];
+
+ is_p--;
+ is_p = ((s64) is_p) >> 63;
+
+ is_zero |= is_p;
+ return is_zero;
+ }
+
+static int felem_is_zero_int(const felem in)
+ {
+ return (int) (felem_is_zero(in) & ((limb)1));
+ }
+
+/* felem_contract converts |in| to its unique, minimal representation.
+ * On entry:
+ * in[i] < 2^59 + 2^14
+ */
+static void felem_contract(felem out, const felem in)
+ {
+ limb is_p, is_greater, sign;
+ static const limb two58 = ((limb)1) << 58;
+
+ felem_assign(out, in);
+
+ out[0] += out[8] >> 57; out[8] &= bottom57bits;
+ /* out[8] < 2^57 */
+ out[1] += out[0] >> 58; out[0] &= bottom58bits;
+ out[2] += out[1] >> 58; out[1] &= bottom58bits;
+ out[3] += out[2] >> 58; out[2] &= bottom58bits;
+ out[4] += out[3] >> 58; out[3] &= bottom58bits;
+ out[5] += out[4] >> 58; out[4] &= bottom58bits;
+ out[6] += out[5] >> 58; out[5] &= bottom58bits;
+ out[7] += out[6] >> 58; out[6] &= bottom58bits;
+ out[8] += out[7] >> 58; out[7] &= bottom58bits;
+ /* out[8] < 2^57 + 4 */
+
+ /* If the value is greater than 2^521-1 then we have to subtract
+ * 2^521-1 out. See the comments in felem_is_zero regarding why we
+ * don't test for other multiples of the prime. */
+
+ /* First, if |out| is equal to 2^521-1, we subtract it out to get zero. */
+
+ is_p = out[0] ^ kPrime[0];
+ is_p |= out[1] ^ kPrime[1];
+ is_p |= out[2] ^ kPrime[2];
+ is_p |= out[3] ^ kPrime[3];
+ is_p |= out[4] ^ kPrime[4];
+ is_p |= out[5] ^ kPrime[5];
+ is_p |= out[6] ^ kPrime[6];
+ is_p |= out[7] ^ kPrime[7];
+ is_p |= out[8] ^ kPrime[8];
+
+ is_p--;
+ is_p &= is_p << 32;
+ is_p &= is_p << 16;
+ is_p &= is_p << 8;
+ is_p &= is_p << 4;
+ is_p &= is_p << 2;
+ is_p &= is_p << 1;
+ is_p = ((s64) is_p) >> 63;
+ is_p = ~is_p;
+
+ /* is_p is 0 iff |out| == 2^521-1 and all ones otherwise */
+
+ out[0] &= is_p;
+ out[1] &= is_p;
+ out[2] &= is_p;
+ out[3] &= is_p;
+ out[4] &= is_p;
+ out[5] &= is_p;
+ out[6] &= is_p;
+ out[7] &= is_p;
+ out[8] &= is_p;
+
+ /* In order to test that |out| >= 2^521-1 we need only test if out[8]
+ * >> 57 is greater than zero as (2^521-1) + x >= 2^522 */
+ is_greater = out[8] >> 57;
+ is_greater |= is_greater << 32;
+ is_greater |= is_greater << 16;
+ is_greater |= is_greater << 8;
+ is_greater |= is_greater << 4;
+ is_greater |= is_greater << 2;
+ is_greater |= is_greater << 1;
+ is_greater = ((s64) is_greater) >> 63;
+
+ out[0] -= kPrime[0] & is_greater;
+ out[1] -= kPrime[1] & is_greater;
+ out[2] -= kPrime[2] & is_greater;
+ out[3] -= kPrime[3] & is_greater;
+ out[4] -= kPrime[4] & is_greater;
+ out[5] -= kPrime[5] & is_greater;
+ out[6] -= kPrime[6] & is_greater;
+ out[7] -= kPrime[7] & is_greater;
+ out[8] -= kPrime[8] & is_greater;
+
+ /* Eliminate negative coefficients */
+ sign = -(out[0] >> 63); out[0] += (two58 & sign); out[1] -= (1 & sign);
+ sign = -(out[1] >> 63); out[1] += (two58 & sign); out[2] -= (1 & sign);
+ sign = -(out[2] >> 63); out[2] += (two58 & sign); out[3] -= (1 & sign);
+ sign = -(out[3] >> 63); out[3] += (two58 & sign); out[4] -= (1 & sign);
+ sign = -(out[4] >> 63); out[4] += (two58 & sign); out[5] -= (1 & sign);
+ sign = -(out[0] >> 63); out[5] += (two58 & sign); out[6] -= (1 & sign);
+ sign = -(out[6] >> 63); out[6] += (two58 & sign); out[7] -= (1 & sign);
+ sign = -(out[7] >> 63); out[7] += (two58 & sign); out[8] -= (1 & sign);
+ sign = -(out[5] >> 63); out[5] += (two58 & sign); out[6] -= (1 & sign);
+ sign = -(out[6] >> 63); out[6] += (two58 & sign); out[7] -= (1 & sign);
+ sign = -(out[7] >> 63); out[7] += (two58 & sign); out[8] -= (1 & sign);
+ }
+
+/* Group operations
+ * ----------------
+ *
+ * Building on top of the field operations we have the operations on the
+ * elliptic curve group itself. Points on the curve are represented in Jacobian
+ * coordinates */
+
+/* point_double calcuates 2*(x_in, y_in, z_in)
+ *
+ * The method is taken from:
+ * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+ *
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
+ * while x_out == y_in is not (maybe this works, but it's not tested). */
+static void
+point_double(felem x_out, felem y_out, felem z_out,
+ const felem x_in, const felem y_in, const felem z_in)
+ {
+ largefelem tmp, tmp2;
+ felem delta, gamma, beta, alpha, ftmp, ftmp2;
+
+ felem_assign(ftmp, x_in);
+ felem_assign(ftmp2, x_in);
+
+ /* delta = z^2 */
+ felem_square(tmp, z_in);
+ felem_reduce(delta, tmp); /* delta[i] < 2^59 + 2^14 */
+
+ /* gamma = y^2 */
+ felem_square(tmp, y_in);
+ felem_reduce(gamma, tmp); /* gamma[i] < 2^59 + 2^14 */
+
+ /* beta = x*gamma */
+ felem_mul(tmp, x_in, gamma);
+ felem_reduce(beta, tmp); /* beta[i] < 2^59 + 2^14 */
+
+ /* alpha = 3*(x-delta)*(x+delta) */
+ felem_diff64(ftmp, delta);
+ /* ftmp[i] < 2^61 */
+ felem_sum64(ftmp2, delta);
+ /* ftmp2[i] < 2^60 + 2^15 */
+ felem_scalar64(ftmp2, 3);
+ /* ftmp2[i] < 3*2^60 + 3*2^15 */
+ felem_mul(tmp, ftmp, ftmp2);
+ /* tmp[i] < 17(3*2^121 + 3*2^76)
+ * = 61*2^121 + 61*2^76
+ * < 64*2^121 + 64*2^76
+ * = 2^127 + 2^82
+ * < 2^128 */
+ felem_reduce(alpha, tmp);
+
+ /* x' = alpha^2 - 8*beta */
+ felem_square(tmp, alpha);
+ /* tmp[i] < 17*2^120
+ * < 2^125 */
+ felem_assign(ftmp, beta);
+ felem_scalar64(ftmp, 8);
+ /* ftmp[i] < 2^62 + 2^17 */
+ felem_diff_128_64(tmp, ftmp);
+ /* tmp[i] < 2^125 + 2^63 + 2^62 + 2^17 */
+ felem_reduce(x_out, tmp);
+
+ /* z' = (y + z)^2 - gamma - delta */
+ felem_sum64(delta, gamma);
+ /* delta[i] < 2^60 + 2^15 */
+ felem_assign(ftmp, y_in);
+ felem_sum64(ftmp, z_in);
+ /* ftmp[i] < 2^60 + 2^15 */
+ felem_square(tmp, ftmp);
+ /* tmp[i] < 17(2^122)
+ * < 2^127 */
+ felem_diff_128_64(tmp, delta);
+ /* tmp[i] < 2^127 + 2^63 */
+ felem_reduce(z_out, tmp);
+
+ /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+ felem_scalar64(beta, 4);
+ /* beta[i] < 2^61 + 2^16 */
+ felem_diff64(beta, x_out);
+ /* beta[i] < 2^61 + 2^60 + 2^16 */
+ felem_mul(tmp, alpha, beta);
+ /* tmp[i] < 17*((2^59 + 2^14)(2^61 + 2^60 + 2^16))
+ * = 17*(2^120 + 2^75 + 2^119 + 2^74 + 2^75 + 2^30)
+ * = 17*(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
+ * < 2^128 */
+ felem_square(tmp2, gamma);
+ /* tmp2[i] < 17*(2^59 + 2^14)^2
+ * = 17*(2^118 + 2^74 + 2^28) */
+ felem_scalar128(tmp2, 8);
+ /* tmp2[i] < 8*17*(2^118 + 2^74 + 2^28)
+ * = 2^125 + 2^121 + 2^81 + 2^77 + 2^35 + 2^31
+ * < 2^126 */
+ felem_diff128(tmp, tmp2);
+ /* tmp[i] < 2^127 - 2^69 + 17(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
+ * = 2^127 + 2^124 + 2^122 + 2^120 + 2^118 + 2^80 + 2^78 + 2^76 +
+ * 2^74 + 2^69 + 2^34 + 2^30
+ * < 2^128 */
+ felem_reduce(y_out, tmp);
+ }
+
+/* copy_conditional copies in to out iff mask is all ones. */
+static void
+copy_conditional(felem out, const felem in, limb mask)
+ {
+ unsigned i;
+ for (i = 0; i < NLIMBS; ++i)
+ {
+ const limb tmp = mask & (in[i] ^ out[i]);
+ out[i] ^= tmp;
+ }
+ }
+
+/* point_add calcuates (x1, y1, z1) + (x2, y2, z2)
+ *
+ * The method is taken from
+ * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
+ * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
+ *
+ * This function includes a branch for checking whether the two input points
+ * are equal (while not equal to the point at infinity). This case never
+ * happens during single point multiplication, so there is no timing leak for
+ * ECDH or ECDSA signing. */
+static void point_add(felem x3, felem y3, felem z3,
+ const felem x1, const felem y1, const felem z1,
+ const int mixed, const felem x2, const felem y2, const felem z2)
+ {
+ felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
+ largefelem tmp, tmp2;
+ limb x_equal, y_equal, z1_is_zero, z2_is_zero;
+
+ z1_is_zero = felem_is_zero(z1);
+ z2_is_zero = felem_is_zero(z2);
+
+ /* ftmp = z1z1 = z1**2 */
+ felem_square(tmp, z1);
+ felem_reduce(ftmp, tmp);
+
+ if (!mixed)
+ {
+ /* ftmp2 = z2z2 = z2**2 */
+ felem_square(tmp, z2);
+ felem_reduce(ftmp2, tmp);
+
+ /* u1 = ftmp3 = x1*z2z2 */
+ felem_mul(tmp, x1, ftmp2);
+ felem_reduce(ftmp3, tmp);
+
+ /* ftmp5 = z1 + z2 */
+ felem_assign(ftmp5, z1);
+ felem_sum64(ftmp5, z2);
+ /* ftmp5[i] < 2^61 */
+
+ /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */
+ felem_square(tmp, ftmp5);
+ /* tmp[i] < 17*2^122 */
+ felem_diff_128_64(tmp, ftmp);
+ /* tmp[i] < 17*2^122 + 2^63 */
+ felem_diff_128_64(tmp, ftmp2);
+ /* tmp[i] < 17*2^122 + 2^64 */
+ felem_reduce(ftmp5, tmp);
+
+ /* ftmp2 = z2 * z2z2 */
+ felem_mul(tmp, ftmp2, z2);
+ felem_reduce(ftmp2, tmp);
+
+ /* s1 = ftmp6 = y1 * z2**3 */
+ felem_mul(tmp, y1, ftmp2);
+ felem_reduce(ftmp6, tmp);
+ }
+ else
+ {
+ /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
+
+ /* u1 = ftmp3 = x1*z2z2 */
+ felem_assign(ftmp3, x1);
+
+ /* ftmp5 = 2*z1z2 */
+ felem_scalar(ftmp5, z1, 2);
+
+ /* s1 = ftmp6 = y1 * z2**3 */
+ felem_assign(ftmp6, y1);
+ }
+
+ /* u2 = x2*z1z1 */
+ felem_mul(tmp, x2, ftmp);
+ /* tmp[i] < 17*2^120 */
+
+ /* h = ftmp4 = u2 - u1 */
+ felem_diff_128_64(tmp, ftmp3);
+ /* tmp[i] < 17*2^120 + 2^63 */
+ felem_reduce(ftmp4, tmp);
+
+ x_equal = felem_is_zero(ftmp4);
+
+ /* z_out = ftmp5 * h */
+ felem_mul(tmp, ftmp5, ftmp4);
+ felem_reduce(z_out, tmp);
+
+ /* ftmp = z1 * z1z1 */
+ felem_mul(tmp, ftmp, z1);
+ felem_reduce(ftmp, tmp);
+
+ /* s2 = tmp = y2 * z1**3 */
+ felem_mul(tmp, y2, ftmp);
+ /* tmp[i] < 17*2^120 */
+
+ /* r = ftmp5 = (s2 - s1)*2 */
+ felem_diff_128_64(tmp, ftmp6);
+ /* tmp[i] < 17*2^120 + 2^63 */
+ felem_reduce(ftmp5, tmp);
+ y_equal = felem_is_zero(ftmp5);
+ felem_scalar64(ftmp5, 2);
+ /* ftmp5[i] < 2^61 */
+
+ if (x_equal && y_equal && !z1_is_zero && !z2_is_zero)
+ {
+ point_double(x3, y3, z3, x1, y1, z1);
+ return;
+ }
+
+ /* I = ftmp = (2h)**2 */
+ felem_assign(ftmp, ftmp4);
+ felem_scalar64(ftmp, 2);
+ /* ftmp[i] < 2^61 */
+ felem_square(tmp, ftmp);
+ /* tmp[i] < 17*2^122 */
+ felem_reduce(ftmp, tmp);
+
+ /* J = ftmp2 = h * I */
+ felem_mul(tmp, ftmp4, ftmp);
+ felem_reduce(ftmp2, tmp);
+
+ /* V = ftmp4 = U1 * I */
+ felem_mul(tmp, ftmp3, ftmp);
+ felem_reduce(ftmp4, tmp);
+
+ /* x_out = r**2 - J - 2V */
+ felem_square(tmp, ftmp5);
+ /* tmp[i] < 17*2^122 */
+ felem_diff_128_64(tmp, ftmp2);
+ /* tmp[i] < 17*2^122 + 2^63 */
+ felem_assign(ftmp3, ftmp4);
+ felem_scalar64(ftmp4, 2);
+ /* ftmp4[i] < 2^61 */
+ felem_diff_128_64(tmp, ftmp4);
+ /* tmp[i] < 17*2^122 + 2^64 */
+ felem_reduce(x_out, tmp);
+
+ /* y_out = r(V-x_out) - 2 * s1 * J */
+ felem_diff64(ftmp3, x_out);
+ /* ftmp3[i] < 2^60 + 2^60
+ * = 2^61 */
+ felem_mul(tmp, ftmp5, ftmp3);
+ /* tmp[i] < 17*2^122 */
+ felem_mul(tmp2, ftmp6, ftmp2);
+ /* tmp2[i] < 17*2^120 */
+ felem_scalar128(tmp2, 2);
+ /* tmp2[i] < 17*2^121 */
+ felem_diff128(tmp, tmp2);
+ /* tmp[i] < 2^127 - 2^69 + 17*2^122
+ * = 2^126 - 2^122 - 2^6 - 2^2 - 1
+ * < 2^127 */
+ felem_reduce(y_out, tmp);
+
+ copy_conditional(x_out, x2, z1_is_zero);
+ copy_conditional(x_out, x1, z2_is_zero);
+ copy_conditional(y_out, y2, z1_is_zero);
+ copy_conditional(y_out, y1, z2_is_zero);
+ copy_conditional(z_out, z2, z1_is_zero);
+ copy_conditional(z_out, z1, z2_is_zero);
+ felem_assign(x3, x_out);
+ felem_assign(y3, y_out);
+ felem_assign(z3, z_out);
+ }
+
+/* Base point pre computation
+ * --------------------------
+ *
+ * Two different sorts of precomputed tables are used in the following code.
+ * Each contain various points on the curve, where each point is three field
+ * elements (x, y, z).
+ *
+ * For the base point table, z is usually 1 (0 for the point at infinity).
+ * This table has 16 elements:
+ * index | bits | point
+ * ------+---------+------------------------------
+ * 0 | 0 0 0 0 | 0G
+ * 1 | 0 0 0 1 | 1G
+ * 2 | 0 0 1 0 | 2^130G
+ * 3 | 0 0 1 1 | (2^130 + 1)G
+ * 4 | 0 1 0 0 | 2^260G
+ * 5 | 0 1 0 1 | (2^260 + 1)G
+ * 6 | 0 1 1 0 | (2^260 + 2^130)G
+ * 7 | 0 1 1 1 | (2^260 + 2^130 + 1)G
+ * 8 | 1 0 0 0 | 2^390G
+ * 9 | 1 0 0 1 | (2^390 + 1)G
+ * 10 | 1 0 1 0 | (2^390 + 2^130)G
+ * 11 | 1 0 1 1 | (2^390 + 2^130 + 1)G
+ * 12 | 1 1 0 0 | (2^390 + 2^260)G
+ * 13 | 1 1 0 1 | (2^390 + 2^260 + 1)G
+ * 14 | 1 1 1 0 | (2^390 + 2^260 + 2^130)G
+ * 15 | 1 1 1 1 | (2^390 + 2^260 + 2^130 + 1)G
+ *
+ * The reason for this is so that we can clock bits into four different
+ * locations when doing simple scalar multiplies against the base point.
+ *
+ * Tables for other points have table[i] = iG for i in 0 .. 16. */
+
+/* gmul is the table of precomputed base points */
+static const felem gmul[16][3] =
+ {{{0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334,
+ 0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8,
+ 0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404},
+ {0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353,
+ 0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45,
+ 0x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad,
+ 0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e,
+ 0x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5},
+ {0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58,
+ 0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c,
+ 0x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873,
+ 0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c,
+ 0x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9},
+ {0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52,
+ 0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e,
+ 0x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2,
+ 0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561,
+ 0x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065},
+ {0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a,
+ 0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e,
+ 0x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6,
+ 0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51,
+ 0x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe},
+ {0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d,
+ 0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c,
+ 0x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27,
+ 0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f,
+ 0x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256},
+ {0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa,
+ 0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2,
+ 0x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890,
+ 0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74,
+ 0x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23},
+ {0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516,
+ 0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1,
+ 0x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce,
+ 0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7,
+ 0x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5},
+ {0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318,
+ 0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83,
+ 0x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae,
+ 0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef,
+ 0x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203},
+ {0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447,
+ 0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283,
+ 0x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5,
+ 0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c,
+ 0x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a},
+ {0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df,
+ 0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645,
+ 0x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292,
+ 0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422,
+ 0x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b},
+ {0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30,
+ 0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb,
+ 0x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767,
+ 0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3,
+ 0x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf},
+ {0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2,
+ 0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692,
+ 0x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3,
+ 0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade,
+ 0x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684},
+ {0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8,
+ 0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a,
+ 0x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608,
+ 0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610,
+ 0x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d},
+ {0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006,
+ 0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86,
+ 0x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c,
+ 0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9,
+ 0x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f},
+ {0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7,
+ 0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c,
+ 0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}}};
+
+/* select_point selects the |idx|th point from a precomputation table and
+ * copies it to out. */
+static void select_point(const limb idx, unsigned int size, const felem pre_comp[/* size */][3],
+ felem out[3])
+ {
+ unsigned i, j;
+ limb *outlimbs = &out[0][0];
+ memset(outlimbs, 0, 3 * sizeof(felem));
+
+ for (i = 0; i < size; i++)
+ {
+ const limb *inlimbs = &pre_comp[i][0][0];
+ limb mask = i ^ idx;
+ mask |= mask >> 4;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (j = 0; j < NLIMBS * 3; j++)
+ outlimbs[j] |= inlimbs[j] & mask;
+ }
+ }
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, int i)
+ {
+ if (i < 0)
+ return 0;
+ return (in[i >> 3] >> (i & 7)) & 1;
+ }
+
+/* Interleaved point multiplication using precomputed point multiples:
+ * The small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[],
+ * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
+ * of the generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
+static void batch_mul(felem x_out, felem y_out, felem z_out,
+ const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar,
+ const int mixed, const felem pre_comp[][17][3], const felem g_pre_comp[16][3])
+ {
+ int i, skip;
+ unsigned num, gen_mul = (g_scalar != NULL);
+ felem nq[3], tmp[4];
+ limb bits;
+ u8 sign, digit;
+
+ /* set nq to the point at infinity */
+ memset(nq, 0, 3 * sizeof(felem));
+
+ /* Loop over all scalars msb-to-lsb, interleaving additions
+ * of multiples of the generator (last quarter of rounds)
+ * and additions of other points multiples (every 5th round).
+ */
+ skip = 1; /* save two point operations in the first round */
+ for (i = (num_points ? 520 : 130); i >= 0; --i)
+ {
+ /* double */
+ if (!skip)
+ point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+
+ /* add multiples of the generator */
+ if (gen_mul && (i <= 130))
+ {
+ bits = get_bit(g_scalar, i + 390) << 3;
+ if (i < 130)
+ {
+ bits |= get_bit(g_scalar, i + 260) << 2;
+ bits |= get_bit(g_scalar, i + 130) << 1;
+ bits |= get_bit(g_scalar, i);
+ }
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp, tmp);
+ if (!skip)
+ {
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
+ }
+ else
+ {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+ }
+
+ /* do other additions every 5 doublings */
+ if (num_points && (i % 5 == 0))
+ {
+ /* loop over all scalars */
+ for (num = 0; num < num_points; ++num)
+ {
+ bits = get_bit(scalars[num], i + 4) << 5;
+ bits |= get_bit(scalars[num], i + 3) << 4;
+ bits |= get_bit(scalars[num], i + 2) << 3;
+ bits |= get_bit(scalars[num], i + 1) << 2;
+ bits |= get_bit(scalars[num], i) << 1;
+ bits |= get_bit(scalars[num], i - 1);
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ /* select the point to add or subtract, in constant time */
+ select_point(digit, 17, pre_comp[num], tmp);
+ felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative point */
+ copy_conditional(tmp[1], tmp[3], (-(limb) sign));
+
+ if (!skip)
+ {
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ mixed, tmp[0], tmp[1], tmp[2]);
+ }
+ else
+ {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+ }
+ }
+ }
+ felem_assign(x_out, nq[0]);
+ felem_assign(y_out, nq[1]);
+ felem_assign(z_out, nq[2]);
+ }
+
+
+/* Precomputation for the group generator. */
+typedef struct {
+ felem g_pre_comp[16][3];
+ int references;
+} NISTP521_PRE_COMP;
+
+const EC_METHOD *EC_GFp_nistp521_method(void)
+ {
+ static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
+ NID_X9_62_prime_field,
+ ec_GFp_nistp521_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_nist_group_copy,
+ ec_GFp_nistp521_group_set_curve,
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+ ec_GFp_simple_point_copy,
+ ec_GFp_simple_point_set_to_infinity,
+ ec_GFp_simple_set_Jprojective_coordinates_GFp,
+ ec_GFp_simple_get_Jprojective_coordinates_GFp,
+ ec_GFp_simple_point_set_affine_coordinates,
+ ec_GFp_nistp521_point_get_affine_coordinates,
+ 0 /* point_set_compressed_coordinates */,
+ 0 /* point2oct */,
+ 0 /* oct2point */,
+ ec_GFp_simple_add,
+ ec_GFp_simple_dbl,
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
+ ec_GFp_simple_cmp,
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ ec_GFp_nistp521_points_mul,
+ ec_GFp_nistp521_precompute_mult,
+ ec_GFp_nistp521_have_precompute_mult,
+ ec_GFp_nist_field_mul,
+ ec_GFp_nist_field_sqr,
+ 0 /* field_div */,
+ 0 /* field_encode */,
+ 0 /* field_decode */,
+ 0 /* field_set_to_one */ };
+
+ return &ret;
+ }
+
+
+/******************************************************************************/
+/* FUNCTIONS TO MANAGE PRECOMPUTATION
+ */
+
+static NISTP521_PRE_COMP *nistp521_pre_comp_new()
+ {
+ NISTP521_PRE_COMP *ret = NULL;
+ ret = (NISTP521_PRE_COMP *)OPENSSL_malloc(sizeof(NISTP521_PRE_COMP));
+ if (!ret)
+ {
+ ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ return ret;
+ }
+ memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
+ ret->references = 1;
+ return ret;
+ }
+
+static void *nistp521_pre_comp_dup(void *src_)
+ {
+ NISTP521_PRE_COMP *src = src_;
+
+ /* no need to actually copy, these objects never change! */
+ CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+
+ return src_;
+ }
+
+static void nistp521_pre_comp_free(void *pre_)
+ {
+ int i;
+ NISTP521_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_free(pre);
+ }
+
+static void nistp521_pre_comp_clear_free(void *pre_)
+ {
+ int i;
+ NISTP521_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_cleanse(pre, sizeof(*pre));
+ OPENSSL_free(pre);
+ }
+
+/******************************************************************************/
+/* OPENSSL EC_METHOD FUNCTIONS
+ */
+
+int ec_GFp_nistp521_group_init(EC_GROUP *group)
+ {
+ int ret;
+ ret = ec_GFp_simple_group_init(group);
+ group->a_is_minus3 = 1;
+ return ret;
+ }
+
+int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+ {
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *curve_p, *curve_a, *curve_b;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
+ BN_CTX_start(ctx);
+ if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_b = BN_CTX_get(ctx)) == NULL)) goto err;
+ BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p);
+ BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a);
+ BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b);
+ if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
+ (BN_cmp(curve_b, b)))
+ {
+ ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE,
+ EC_R_WRONG_CURVE_PARAMETERS);
+ goto err;
+ }
+ group->field_mod_func = BN_nist_mod_521;
+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
+ * (X', Y') = (X/Z^2, Y/Z^3) */
+int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+ {
+ felem z1, z2, x_in, y_in, x_out, y_out;
+ largefelem tmp;
+
+ if (EC_POINT_is_at_infinity(group, point))
+ {
+ ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
+ EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+ if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
+ (!BN_to_felem(z1, &point->Z))) return 0;
+ felem_inv(z2, z1);
+ felem_square(tmp, z2); felem_reduce(z1, tmp);
+ felem_mul(tmp, x_in, z1); felem_reduce(x_in, tmp);
+ felem_contract(x_out, x_in);
+ if (x != NULL)
+ {
+ if (!felem_to_BN(x, x_out))
+ {
+ ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ felem_mul(tmp, z1, z2); felem_reduce(z1, tmp);
+ felem_mul(tmp, y_in, z1); felem_reduce(y_in, tmp);
+ felem_contract(y_out, y_in);
+ if (y != NULL)
+ {
+ if (!felem_to_BN(y, y_out))
+ {
+ ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+static void make_points_affine(size_t num, felem points[/* num */][3], felem tmp_felems[/* num+1 */])
+ {
+ /* Runs in constant time, unless an input is the point at infinity
+ * (which normally shouldn't happen). */
+ ec_GFp_nistp_points_make_affine_internal(
+ num,
+ points,
+ sizeof(felem),
+ tmp_felems,
+ (void (*)(void *)) felem_one,
+ (int (*)(const void *)) felem_is_zero_int,
+ (void (*)(void *, const void *)) felem_assign,
+ (void (*)(void *, const void *)) felem_square_reduce,
+ (void (*)(void *, const void *, const void *)) felem_mul_reduce,
+ (void (*)(void *, const void *)) felem_inv,
+ (void (*)(void *, const void *)) felem_contract);
+ }
+
+/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
+ * Result is stored in r (r can equal one of the inputs). */
+int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num, const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
+ {
+ int ret = 0;
+ int j;
+ int mixed = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y, *z, *tmp_scalar;
+ felem_bytearray g_secret;
+ felem_bytearray *secrets = NULL;
+ felem (*pre_comp)[17][3] = NULL;
+ felem *tmp_felems = NULL;
+ felem_bytearray tmp;
+ unsigned i, num_bytes;
+ int have_pre_comp = 0;
+ size_t num_points = num;
+ felem x_in, y_in, z_in, x_out, y_out, z_out;
+ NISTP521_PRE_COMP *pre = NULL;
+ felem (*g_pre_comp)[3] = NULL;
+ EC_POINT *generator = NULL;
+ const EC_POINT *p = NULL;
+ const BIGNUM *p_scalar = NULL;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) ||
+ ((y = BN_CTX_get(ctx)) == NULL) ||
+ ((z = BN_CTX_get(ctx)) == NULL) ||
+ ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
+ goto err;
+
+ if (scalar != NULL)
+ {
+ pre = EC_EX_DATA_get_data(group->extra_data,
+ nistp521_pre_comp_dup, nistp521_pre_comp_free,
+ nistp521_pre_comp_clear_free);
+ if (pre)
+ /* we have precomputation, try to use it */
+ g_pre_comp = &pre->g_pre_comp[0];
+ else
+ /* try to use the standard precomputation */
+ g_pre_comp = (felem (*)[3]) gmul;
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ /* get the generator from precomputation */
+ if (!felem_to_BN(x, g_pre_comp[1][0]) ||
+ !felem_to_BN(y, g_pre_comp[1][1]) ||
+ !felem_to_BN(z, g_pre_comp[1][2]))
+ {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
+ generator, x, y, z, ctx))
+ goto err;
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+ /* precomputation matches generator */
+ have_pre_comp = 1;
+ else
+ /* we don't have valid precomputation:
+ * treat the generator as a random point */
+ num_points++;
+ }
+
+ if (num_points > 0)
+ {
+ if (num_points >= 2)
+ {
+ /* unless we precompute multiples for just one point,
+ * converting those into affine form is time well spent */
+ mixed = 1;
+ }
+ secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
+ pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
+ if (mixed)
+ tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
+ if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_felems == NULL)))
+ {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* we treat NULL scalars as 0, and NULL points as points at infinity,
+ * i.e., they contribute nothing to the linear combination */
+ memset(secrets, 0, num_points * sizeof(felem_bytearray));
+ memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
+ for (i = 0; i < num_points; ++i)
+ {
+ if (i == num)
+ /* we didn't have a valid precomputation, so we pick
+ * the generator */
+ {
+ p = EC_GROUP_get0_generator(group);
+ p_scalar = scalar;
+ }
+ else
+ /* the i^th point */
+ {
+ p = points[i];
+ p_scalar = scalars[i];
+ }
+ if ((p_scalar != NULL) && (p != NULL))
+ {
+ /* reduce scalar to 0 <= scalar < 2^521 */
+ if ((BN_num_bits(p_scalar) > 521) || (BN_is_negative(p_scalar)))
+ {
+ /* this is an unusual input, and we don't guarantee
+ * constant-timeness */
+ if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx))
+ {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ }
+ else
+ num_bytes = BN_bn2bin(p_scalar, tmp);
+ flip_endian(secrets[i], tmp, num_bytes);
+ /* precompute multiples */
+ if ((!BN_to_felem(x_out, &p->X)) ||
+ (!BN_to_felem(y_out, &p->Y)) ||
+ (!BN_to_felem(z_out, &p->Z))) goto err;
+ memcpy(pre_comp[i][1][0], x_out, sizeof(felem));
+ memcpy(pre_comp[i][1][1], y_out, sizeof(felem));
+ memcpy(pre_comp[i][1][2], z_out, sizeof(felem));
+ for (j = 2; j <= 16; ++j)
+ {
+ if (j & 1)
+ {
+ point_add(
+ pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
+ pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
+ 0, pre_comp[i][j-1][0], pre_comp[i][j-1][1], pre_comp[i][j-1][2]);
+ }
+ else
+ {
+ point_double(
+ pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
+ pre_comp[i][j/2][0], pre_comp[i][j/2][1], pre_comp[i][j/2][2]);
+ }
+ }
+ }
+ }
+ if (mixed)
+ make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
+ }
+
+ /* the scalar for the generator */
+ if ((scalar != NULL) && (have_pre_comp))
+ {
+ memset(g_secret, 0, sizeof(g_secret));
+ /* reduce scalar to 0 <= scalar < 2^521 */
+ if ((BN_num_bits(scalar) > 521) || (BN_is_negative(scalar)))
+ {
+ /* this is an unusual input, and we don't guarantee
+ * constant-timeness */
+ if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx))
+ {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ }
+ else
+ num_bytes = BN_bn2bin(scalar, tmp);
+ flip_endian(g_secret, tmp, num_bytes);
+ /* do the multiplication with generator precomputation*/
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray (*)) secrets, num_points,
+ g_secret,
+ mixed, (const felem (*)[17][3]) pre_comp,
+ (const felem (*)[3]) g_pre_comp);
+ }
+ else
+ /* do the multiplication without generator precomputation */
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray (*)) secrets, num_points,
+ NULL, mixed, (const felem (*)[17][3]) pre_comp, NULL);
+ /* reduce the output to its unique minimal representation */
+ felem_contract(x_in, x_out);
+ felem_contract(y_in, y_out);
+ felem_contract(z_in, z_out);
+ if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
+ (!felem_to_BN(z, z_in)))
+ {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (secrets != NULL)
+ OPENSSL_free(secrets);
+ if (pre_comp != NULL)
+ OPENSSL_free(pre_comp);
+ if (tmp_felems != NULL)
+ OPENSSL_free(tmp_felems);
+ return ret;
+ }
+
+int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+ {
+ int ret = 0;
+ NISTP521_PRE_COMP *pre = NULL;
+ int i, j;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y;
+ EC_POINT *generator = NULL;
+ felem tmp_felems[16];
+
+ /* throw away old precomputation */
+ EC_EX_DATA_free_data(&group->extra_data, nistp521_pre_comp_dup,
+ nistp521_pre_comp_free, nistp521_pre_comp_clear_free);
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) ||
+ ((y = BN_CTX_get(ctx)) == NULL))
+ goto err;
+ /* get the generator */
+ if (group->generator == NULL) goto err;
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ BN_bin2bn(nistp521_curve_params[3], sizeof (felem_bytearray), x);
+ BN_bin2bn(nistp521_curve_params[4], sizeof (felem_bytearray), y);
+ if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
+ goto err;
+ if ((pre = nistp521_pre_comp_new()) == NULL)
+ goto err;
+ /* if the generator is the standard one, use built-in precomputation */
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+ {
+ memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
+ ret = 1;
+ goto err;
+ }
+ if ((!BN_to_felem(pre->g_pre_comp[1][0], &group->generator->X)) ||
+ (!BN_to_felem(pre->g_pre_comp[1][1], &group->generator->Y)) ||
+ (!BN_to_felem(pre->g_pre_comp[1][2], &group->generator->Z)))
+ goto err;
+ /* compute 2^130*G, 2^260*G, 2^390*G */
+ for (i = 1; i <= 4; i <<= 1)
+ {
+ point_double(pre->g_pre_comp[2*i][0], pre->g_pre_comp[2*i][1],
+ pre->g_pre_comp[2*i][2], pre->g_pre_comp[i][0],
+ pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]);
+ for (j = 0; j < 129; ++j)
+ {
+ point_double(pre->g_pre_comp[2*i][0],
+ pre->g_pre_comp[2*i][1],
+ pre->g_pre_comp[2*i][2],
+ pre->g_pre_comp[2*i][0],
+ pre->g_pre_comp[2*i][1],
+ pre->g_pre_comp[2*i][2]);
+ }
+ }
+ /* g_pre_comp[0] is the point at infinity */
+ memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0]));
+ /* the remaining multiples */
+ /* 2^130*G + 2^260*G */
+ point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1],
+ pre->g_pre_comp[6][2], pre->g_pre_comp[4][0],
+ pre->g_pre_comp[4][1], pre->g_pre_comp[4][2],
+ 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
+ pre->g_pre_comp[2][2]);
+ /* 2^130*G + 2^390*G */
+ point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1],
+ pre->g_pre_comp[10][2], pre->g_pre_comp[8][0],
+ pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
+ 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
+ pre->g_pre_comp[2][2]);
+ /* 2^260*G + 2^390*G */
+ point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1],
+ pre->g_pre_comp[12][2], pre->g_pre_comp[8][0],
+ pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
+ 0, pre->g_pre_comp[4][0], pre->g_pre_comp[4][1],
+ pre->g_pre_comp[4][2]);
+ /* 2^130*G + 2^260*G + 2^390*G */
+ point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1],
+ pre->g_pre_comp[14][2], pre->g_pre_comp[12][0],
+ pre->g_pre_comp[12][1], pre->g_pre_comp[12][2],
+ 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
+ pre->g_pre_comp[2][2]);
+ for (i = 1; i < 8; ++i)
+ {
+ /* odd multiples: add G */
+ point_add(pre->g_pre_comp[2*i+1][0], pre->g_pre_comp[2*i+1][1],
+ pre->g_pre_comp[2*i+1][2], pre->g_pre_comp[2*i][0],
+ pre->g_pre_comp[2*i][1], pre->g_pre_comp[2*i][2],
+ 0, pre->g_pre_comp[1][0], pre->g_pre_comp[1][1],
+ pre->g_pre_comp[1][2]);
+ }
+ make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems);
+
+ if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp521_pre_comp_dup,
+ nistp521_pre_comp_free, nistp521_pre_comp_clear_free))
+ goto err;
+ ret = 1;
+ pre = NULL;
+ err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (pre)
+ nistp521_pre_comp_free(pre);
+ return ret;
+ }
+
+int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group)
+ {
+ if (EC_EX_DATA_get_data(group->extra_data, nistp521_pre_comp_dup,
+ nistp521_pre_comp_free, nistp521_pre_comp_clear_free)
+ != NULL)
+ return 1;
+ else
+ return 0;
+ }
+
+#else
+static void *dummy=&dummy;
+#endif
diff --git a/deps/openssl/openssl/crypto/ec/ecp_nistputil.c b/deps/openssl/openssl/crypto/ec/ecp_nistputil.c
new file mode 100644
index 000000000..c8140c807
--- /dev/null
+++ b/deps/openssl/openssl/crypto/ec/ecp_nistputil.c
@@ -0,0 +1,197 @@
+/* crypto/ec/ecp_nistputil.c */
+/*
+ * Written by Bodo Moeller for the OpenSSL project.
+ */
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+
+/*
+ * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
+ */
+
+#include <stddef.h>
+#include "ec_lcl.h"
+
+/* Convert an array of points into affine coordinates.
+ * (If the point at infinity is found (Z = 0), it remains unchanged.)
+ * This function is essentially an equivalent to EC_POINTs_make_affine(), but
+ * works with the internal representation of points as used by ecp_nistp###.c
+ * rather than with (BIGNUM-based) EC_POINT data structures.
+ *
+ * point_array is the input/output buffer ('num' points in projective form,
+ * i.e. three coordinates each), based on an internal representation of
+ * field elements of size 'felem_size'.
+ *
+ * tmp_felems needs to point to a temporary array of 'num'+1 field elements
+ * for storage of intermediate values.
+ */
+void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
+ size_t felem_size, void *tmp_felems,
+ void (*felem_one)(void *out),
+ int (*felem_is_zero)(const void *in),
+ void (*felem_assign)(void *out, const void *in),
+ void (*felem_square)(void *out, const void *in),
+ void (*felem_mul)(void *out, const void *in1, const void *in2),
+ void (*felem_inv)(void *out, const void *in),
+ void (*felem_contract)(void *out, const void *in))
+ {
+ int i = 0;
+
+#define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
+#define X(I) (&((char *)point_array)[3*(I) * felem_size])
+#define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
+#define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
+
+ if (!felem_is_zero(Z(0)))
+ felem_assign(tmp_felem(0), Z(0));
+ else
+ felem_one(tmp_felem(0));
+ for (i = 1; i < (int)num; i++)
+ {
+ if (!felem_is_zero(Z(i)))
+ felem_mul(tmp_felem(i), tmp_felem(i-1), Z(i));
+ else
+ felem_assign(tmp_felem(i), tmp_felem(i-1));
+ }
+ /* Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any zero-valued factors:
+ * if Z(i) = 0, we essentially pretend that Z(i) = 1 */
+
+ felem_inv(tmp_felem(num-1), tmp_felem(num-1));
+ for (i = num - 1; i >= 0; i--)
+ {
+ if (i > 0)
+ /* tmp_felem(i-1) is the product of Z(0) .. Z(i-1),
+ * tmp_felem(i) is the inverse of the product of Z(0) .. Z(i)
+ */
+ felem_mul(tmp_felem(num), tmp_felem(i-1), tmp_felem(i)); /* 1/Z(i) */
+ else
+ felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
+
+ if (!felem_is_zero(Z(i)))
+ {
+ if (i > 0)
+ /* For next iteration, replace tmp_felem(i-1) by its inverse */
+ felem_mul(tmp_felem(i-1), tmp_felem(i), Z(i));
+
+ /* Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1) */
+ felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */
+ felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */
+ felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
+ felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */
+ felem_contract(X(i), X(i));
+ felem_contract(Y(i), Y(i));
+ felem_one(Z(i));
+ }
+ else
+ {
+ if (i > 0)
+ /* For next iteration, replace tmp_felem(i-1) by its inverse */
+ felem_assign(tmp_felem(i-1), tmp_felem(i));
+ }
+ }
+ }
+
+/*
+ * This function looks at 5+1 scalar bits (5 current, 1 adjacent less
+ * significant bit), and recodes them into a signed digit for use in fast point
+ * multiplication: the use of signed rather than unsigned digits means that
+ * fewer points need to be precomputed, given that point inversion is easy
+ * (a precomputed point dP makes -dP available as well).
+ *
+ * BACKGROUND:
+ *
+ * Signed digits for multiplication were introduced by Booth ("A signed binary
+ * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
+ * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
+ * Booth's original encoding did not generally improve the density of nonzero
+ * digits over the binary representation, and was merely meant to simplify the
+ * handling of signed factors given in two's complement; but it has since been
+ * shown to be the basis of various signed-digit representations that do have
+ * further advantages, including the wNAF, using the following general approach:
+ *
+ * (1) Given a binary representation
+ *
+ * b_k ... b_2 b_1 b_0,
+ *
+ * of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
+ * by using bit-wise subtraction as follows:
+ *
+ * b_k b_(k-1) ... b_2 b_1 b_0
+ * - b_k ... b_3 b_2 b_1 b_0
+ * -------------------------------------
+ * s_k b_(k-1) ... s_3 s_2 s_1 s_0
+ *
+ * A left-shift followed by subtraction of the original value yields a new
+ * representation of the same value, using signed bits s_i = b_(i+1) - b_i.
+ * This representation from Booth's paper has since appeared in the
+ * literature under a variety of different names including "reversed binary
+ * form", "alternating greedy expansion", "mutual opposite form", and
+ * "sign-alternating {+-1}-representation".
+ *
+ * An interesting property is that among the nonzero bits, values 1 and -1
+ * strictly alternate.
+ *
+ * (2) Various window schemes can be applied to the Booth representation of
+ * integers: for example, right-to-left sliding windows yield the wNAF
+ * (a signed-digit encoding independently discovered by various researchers
+ * in the 1990s), and left-to-right sliding windows yield a left-to-right
+ * equivalent of the wNAF (independently discovered by various researchers
+ * around 2004).
+ *
+ * To prevent leaking information through side channels in point multiplication,
+ * we need to recode the given integer into a regular pattern: sliding windows
+ * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
+ * decades older: we'll be using the so-called "modified Booth encoding" due to
+ * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
+ * (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five
+ * signed bits into a signed digit:
+ *
+ * s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
+ *
+ * The sign-alternating property implies that the resulting digit values are
+ * integers from -16 to 16.
+ *
+ * Of course, we don't actually need to compute the signed digits s_i as an
+ * intermediate step (that's just a nice way to see how this scheme relates
+ * to the wNAF): a direct computation obtains the recoded digit from the
+ * six bits b_(4j + 4) ... b_(4j - 1).
+ *
+ * This function takes those five bits as an integer (0 .. 63), writing the
+ * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
+ * value, in the range 0 .. 8). Note that this integer essentially provides the
+ * input bits "shifted to the left" by one position: for example, the input to
+ * compute the least significant recoded digit, given that there's no bit b_-1,
+ * has to be b_4 b_3 b_2 b_1 b_0 0.
+ *
+ */
+void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in)
+ {
+ unsigned char s, d;
+
+ s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as 6-bit value */
+ d = (1 << 6) - in - 1;
+ d = (d & s) | (in & ~s);
+ d = (d >> 1) + (d & 1);
+
+ *sign = s & 1;
+ *digit = d;
+ }
+#else
+static void *dummy=&dummy;
+#endif
diff --git a/deps/openssl/openssl/crypto/ec/ecp_oct.c b/deps/openssl/openssl/crypto/ec/ecp_oct.c
new file mode 100644
index 000000000..374a0ee73
--- /dev/null
+++ b/deps/openssl/openssl/crypto/ec/ecp_oct.c
@@ -0,0 +1,433 @@
+/* crypto/ec/ecp_oct.c */
+/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
+ * for the OpenSSL project.
+ * Includes code written by Bodo Moeller for the OpenSSL project.
+*/
+/* ====================================================================
+ * Copyright (c) 1998-2002 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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <openssl/err.h>
+#include <openssl/symhacks.h>
+
+#include "ec_lcl.h"
+
+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x_, int y_bit, BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp1, *tmp2, *x, *y;
+ int ret = 0;
+
+ /* clear error queue*/
+ ERR_clear_error();
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ y_bit = (y_bit != 0);
+
+ BN_CTX_start(ctx);
+ tmp1 = BN_CTX_get(ctx);
+ tmp2 = BN_CTX_get(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL) goto err;
+
+ /* Recover y. We have a Weierstrass equation
+ * y^2 = x^3 + a*x + b,
+ * so y is one of the square roots of x^3 + a*x + b.
+ */
+
+ /* tmp1 := x^3 */
+ if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;
+ if (group->meth->field_decode == 0)
+ {
+ /* field_{sqr,mul} work on standard representation */
+ if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;
+ if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;
+ if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;
+ }
+
+ /* tmp1 := tmp1 + a*x */
+ if (group->a_is_minus3)
+ {
+ if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;
+ if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;
+ if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
+ }
+ else
+ {
+ if (group->meth->field_decode)
+ {
+ if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;
+ if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;
+ }
+ else
+ {
+ /* field_mul works on standard representation */
+ if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;
+ }
+
+ if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
+ }
+
+ /* tmp1 := tmp1 + b */
+ if (group->meth->field_decode)
+ {
+ if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;
+ if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
+ }
+ else
+ {
+ if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;
+ }
+
+ if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
+ {
+ unsigned long err = ERR_peek_last_error();
+
+ if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
+ {
+ ERR_clear_error();
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+ }
+ else
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ if (y_bit != BN_is_odd(y))
+ {
+ if (BN_is_zero(y))
+ {
+ int kron;
+
+ kron = BN_kronecker(x, &group->field, ctx);
+ if (kron == -2) goto err;
+
+ if (kron == 1)
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
+ else
+ /* BN_mod_sqrt() should have cought this error (not a square) */
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+ goto err;
+ }
+ if (!BN_usub(y, &group->field, y)) goto err;
+ }
+ if (y_bit != BN_is_odd(y))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *ctx)
+ {
+ size_t ret;
+ BN_CTX *new_ctx = NULL;
+ int used_ctx = 0;
+ BIGNUM *x, *y;
+ size_t field_len, i, skip;
+
+ if ((form != POINT_CONVERSION_COMPRESSED)
+ && (form != POINT_CONVERSION_UNCOMPRESSED)
+ && (form != POINT_CONVERSION_HYBRID))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+ goto err;
+ }
+
+ if (EC_POINT_is_at_infinity(group, point))
+ {
+ /* encodes to a single 0 octet */
+ if (buf != NULL)
+ {
+ if (len < 1)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ buf[0] = 0;
+ }
+ return 1;
+ }
+
+
+ /* ret := required output buffer length */
+ field_len = BN_num_bytes(&group->field);
+ ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+ /* if 'buf' is NULL, just return required length */
+ if (buf != NULL)
+ {
+ if (len < ret)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ goto err;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ used_ctx = 1;
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL) goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+
+ if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
+ buf[0] = form + 1;
+ else
+ buf[0] = form;
+
+ i = 1;
+
+ skip = field_len - BN_num_bytes(x);
+ if (skip > field_len)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ while (skip > 0)
+ {
+ buf[i++] = 0;
+ skip--;
+ }
+ skip = BN_bn2bin(x, buf + i);
+ i += skip;
+ if (i != 1 + field_len)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
+ {
+ skip = field_len - BN_num_bytes(y);
+ if (skip > field_len)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ while (skip > 0)
+ {
+ buf[i++] = 0;
+ skip--;
+ }
+ skip = BN_bn2bin(y, buf + i);
+ i += skip;
+ }
+
+ if (i != ret)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ if (used_ctx)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+
+ err:
+ if (used_ctx)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return 0;
+ }
+
+
+int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+ const unsigned char *buf, size_t len, BN_CTX *ctx)
+ {
+ point_conversion_form_t form;
+ int y_bit;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y;
+ size_t field_len, enc_len;
+ int ret = 0;
+
+ if (len == 0)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ form = buf[0];
+ y_bit = form & 1;
+ form = form & ~1U;
+ if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
+ && (form != POINT_CONVERSION_UNCOMPRESSED)
+ && (form != POINT_CONVERSION_HYBRID))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+ if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ if (form == 0)
+ {
+ if (len != 1)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ return EC_POINT_set_to_infinity(group, point);
+ }
+
+ field_len = BN_num_bytes(&group->field);
+ enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+ if (len != enc_len)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL) goto err;
+
+ if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
+ if (BN_ucmp(x, &group->field) >= 0)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+
+ if (form == POINT_CONVERSION_COMPRESSED)
+ {
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
+ if (BN_ucmp(y, &group->field) >= 0)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ if (form == POINT_CONVERSION_HYBRID)
+ {
+ if (y_bit != BN_is_odd(y))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+ }
+
+ if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
+ goto err;
+ }
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
diff --git a/deps/openssl/openssl/crypto/ec/ecp_smpl.c b/deps/openssl/openssl/crypto/ec/ecp_smpl.c
index 66a92e2a9..7cbb321f9 100644
--- a/deps/openssl/openssl/crypto/ec/ecp_smpl.c
+++ b/deps/openssl/openssl/crypto/ec/ecp_smpl.c
@@ -65,11 +65,19 @@
#include <openssl/err.h>
#include <openssl/symhacks.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
#include "ec_lcl.h"
const EC_METHOD *EC_GFp_simple_method(void)
{
+#ifdef OPENSSL_FIPS
+ return fips_ec_gfp_simple_method();
+#else
static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
ec_GFp_simple_group_init,
ec_GFp_simple_group_finish,
@@ -88,9 +96,7 @@ const EC_METHOD *EC_GFp_simple_method(void)
ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
- ec_GFp_simple_set_compressed_coordinates,
- ec_GFp_simple_point2oct,
- ec_GFp_simple_oct2point,
+ 0,0,0,
ec_GFp_simple_add,
ec_GFp_simple_dbl,
ec_GFp_simple_invert,
@@ -110,6 +116,7 @@ const EC_METHOD *EC_GFp_simple_method(void)
0 /* field_set_to_one */ };
return &ret;
+#endif
}
@@ -633,372 +640,6 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_P
return ret;
}
-
-int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
- const BIGNUM *x_, int y_bit, BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- BIGNUM *tmp1, *tmp2, *x, *y;
- int ret = 0;
-
- /* clear error queue*/
- ERR_clear_error();
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- y_bit = (y_bit != 0);
-
- BN_CTX_start(ctx);
- tmp1 = BN_CTX_get(ctx);
- tmp2 = BN_CTX_get(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- if (y == NULL) goto err;
-
- /* Recover y. We have a Weierstrass equation
- * y^2 = x^3 + a*x + b,
- * so y is one of the square roots of x^3 + a*x + b.
- */
-
- /* tmp1 := x^3 */
- if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;
- if (group->meth->field_decode == 0)
- {
- /* field_{sqr,mul} work on standard representation */
- if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;
- if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;
- }
- else
- {
- if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;
- if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;
- }
-
- /* tmp1 := tmp1 + a*x */
- if (group->a_is_minus3)
- {
- if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;
- if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;
- if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
- }
- else
- {
- if (group->meth->field_decode)
- {
- if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;
- if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;
- }
- else
- {
- /* field_mul works on standard representation */
- if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;
- }
-
- if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
- }
-
- /* tmp1 := tmp1 + b */
- if (group->meth->field_decode)
- {
- if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;
- if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
- }
- else
- {
- if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;
- }
-
- if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
- {
- unsigned long err = ERR_peek_last_error();
-
- if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
- {
- ERR_clear_error();
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
- }
- else
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
- goto err;
- }
-
- if (y_bit != BN_is_odd(y))
- {
- if (BN_is_zero(y))
- {
- int kron;
-
- kron = BN_kronecker(x, &group->field, ctx);
- if (kron == -2) goto err;
-
- if (kron == 1)
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
- else
- /* BN_mod_sqrt() should have cought this error (not a square) */
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
- goto err;
- }
- if (!BN_usub(y, &group->field, y)) goto err;
- }
- if (y_bit != BN_is_odd(y))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
- unsigned char *buf, size_t len, BN_CTX *ctx)
- {
- size_t ret;
- BN_CTX *new_ctx = NULL;
- int used_ctx = 0;
- BIGNUM *x, *y;
- size_t field_len, i, skip;
-
- if ((form != POINT_CONVERSION_COMPRESSED)
- && (form != POINT_CONVERSION_UNCOMPRESSED)
- && (form != POINT_CONVERSION_HYBRID))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
- goto err;
- }
-
- if (EC_POINT_is_at_infinity(group, point))
- {
- /* encodes to a single 0 octet */
- if (buf != NULL)
- {
- if (len < 1)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
- return 0;
- }
- buf[0] = 0;
- }
- return 1;
- }
-
-
- /* ret := required output buffer length */
- field_len = BN_num_bytes(&group->field);
- ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
-
- /* if 'buf' is NULL, just return required length */
- if (buf != NULL)
- {
- if (len < ret)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
- goto err;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- used_ctx = 1;
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- if (y == NULL) goto err;
-
- if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
-
- if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
- buf[0] = form + 1;
- else
- buf[0] = form;
-
- i = 1;
-
- skip = field_len - BN_num_bytes(x);
- if (skip > field_len)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- while (skip > 0)
- {
- buf[i++] = 0;
- skip--;
- }
- skip = BN_bn2bin(x, buf + i);
- i += skip;
- if (i != 1 + field_len)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
- {
- skip = field_len - BN_num_bytes(y);
- if (skip > field_len)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- while (skip > 0)
- {
- buf[i++] = 0;
- skip--;
- }
- skip = BN_bn2bin(y, buf + i);
- i += skip;
- }
-
- if (i != ret)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- }
-
- if (used_ctx)
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
-
- err:
- if (used_ctx)
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return 0;
- }
-
-
-int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
- const unsigned char *buf, size_t len, BN_CTX *ctx)
- {
- point_conversion_form_t form;
- int y_bit;
- BN_CTX *new_ctx = NULL;
- BIGNUM *x, *y;
- size_t field_len, enc_len;
- int ret = 0;
-
- if (len == 0)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
- return 0;
- }
- form = buf[0];
- y_bit = form & 1;
- form = form & ~1U;
- if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
- && (form != POINT_CONVERSION_UNCOMPRESSED)
- && (form != POINT_CONVERSION_HYBRID))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
- if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- if (form == 0)
- {
- if (len != 1)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- return EC_POINT_set_to_infinity(group, point);
- }
-
- field_len = BN_num_bytes(&group->field);
- enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
-
- if (len != enc_len)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- if (y == NULL) goto err;
-
- if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
- if (BN_ucmp(x, &group->field) >= 0)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
-
- if (form == POINT_CONVERSION_COMPRESSED)
- {
- if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err;
- }
- else
- {
- if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
- if (BN_ucmp(y, &group->field) >= 0)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
- if (form == POINT_CONVERSION_HYBRID)
- {
- if (y_bit != BN_is_odd(y))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
- }
-
- if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
- }
-
- if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
- }
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
{
int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
diff --git a/deps/openssl/openssl/crypto/ec/ectest.c b/deps/openssl/openssl/crypto/ec/ectest.c
index 7509cb9c7..102eaa9b2 100644
--- a/deps/openssl/openssl/crypto/ec/ectest.c
+++ b/deps/openssl/openssl/crypto/ec/ectest.c
@@ -94,6 +94,7 @@ int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); retur
#include <openssl/objects.h>
#include <openssl/rand.h>
#include <openssl/bn.h>
+#include <openssl/opensslconf.h>
#if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
/* suppress "too big too optimize" warning */
@@ -107,10 +108,6 @@ int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); retur
EXIT(1); \
} while (0)
-void prime_field_tests(void);
-void char2_field_tests(void);
-void internal_curve_test(void);
-
#define TIMING_BASE_PT 0
#define TIMING_RAND_PT 1
#define TIMING_SIMUL 2
@@ -195,8 +192,51 @@ static void timings(EC_GROUP *group, int type, BN_CTX *ctx)
}
#endif
-void prime_field_tests()
- {
+/* test multiplication with group order, long and negative scalars */
+static void group_order_tests(EC_GROUP *group)
+ {
+ BIGNUM *n1, *n2, *order;
+ EC_POINT *P = EC_POINT_new(group);
+ EC_POINT *Q = EC_POINT_new(group);
+ BN_CTX *ctx = BN_CTX_new();
+
+ n1 = BN_new(); n2 = BN_new(); order = BN_new();
+ fprintf(stdout, "verify group order ...");
+ fflush(stdout);
+ if (!EC_GROUP_get_order(group, order, ctx)) ABORT;
+ if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+ fprintf(stdout, ".");
+ fflush(stdout);
+ if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
+ if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+ fprintf(stdout, " ok\n");
+ fprintf(stdout, "long/negative scalar tests ... ");
+ if (!BN_one(n1)) ABORT;
+ /* n1 = 1 - order */
+ if (!BN_sub(n1, n1, order)) ABORT;
+ if(!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
+ /* n2 = 1 + order */
+ if (!BN_add(n2, order, BN_value_one())) ABORT;
+ if(!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
+ /* n2 = (1 - order) * (1 + order) */
+ if (!BN_mul(n2, n1, n2, ctx)) ABORT;
+ if(!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
+ fprintf(stdout, "ok\n");
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ BN_free(n1);
+ BN_free(n2);
+ BN_free(order);
+ BN_CTX_free(ctx);
+ }
+
+static void prime_field_tests(void)
+ {
BN_CTX *ctx = NULL;
BIGNUM *p, *a, *b;
EC_GROUP *group;
@@ -321,21 +361,21 @@ void prime_field_tests()
if (len == 0) ABORT;
if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
- fprintf(stdout, "Generator as octect string, compressed form:\n ");
+ fprintf(stdout, "Generator as octet string, compressed form:\n ");
for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
if (len == 0) ABORT;
if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
- fprintf(stdout, "\nGenerator as octect string, uncompressed form:\n ");
+ fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n ");
for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
if (len == 0) ABORT;
if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
- fprintf(stdout, "\nGenerator as octect string, hybrid form:\n ");
+ fprintf(stdout, "\nGenerator as octet string, hybrid form:\n ");
for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
@@ -381,17 +421,7 @@ void prime_field_tests()
if (EC_GROUP_get_degree(group) != 160) ABORT;
fprintf(stdout, " ok\n");
- fprintf(stdout, "verify group order ...");
- fflush(stdout);
- if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, ".");
- fflush(stdout);
- if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, " ok\n");
+ group_order_tests(group);
if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
if (!EC_GROUP_copy(P_160, group)) ABORT;
@@ -425,17 +455,7 @@ void prime_field_tests()
if (EC_GROUP_get_degree(group) != 192) ABORT;
fprintf(stdout, " ok\n");
- fprintf(stdout, "verify group order ...");
- fflush(stdout);
- if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, ".");
- fflush(stdout);
- if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, " ok\n");
+ group_order_tests(group);
if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
if (!EC_GROUP_copy(P_192, group)) ABORT;
@@ -469,17 +489,7 @@ void prime_field_tests()
if (EC_GROUP_get_degree(group) != 224) ABORT;
fprintf(stdout, " ok\n");
- fprintf(stdout, "verify group order ...");
- fflush(stdout);
- if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, ".");
- fflush(stdout);
- if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, " ok\n");
+ group_order_tests(group);
if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
if (!EC_GROUP_copy(P_224, group)) ABORT;
@@ -514,17 +524,7 @@ void prime_field_tests()
if (EC_GROUP_get_degree(group) != 256) ABORT;
fprintf(stdout, " ok\n");
- fprintf(stdout, "verify group order ...");
- fflush(stdout);
- if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, ".");
- fflush(stdout);
- if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, " ok\n");
+ group_order_tests(group);
if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
if (!EC_GROUP_copy(P_256, group)) ABORT;
@@ -563,18 +563,8 @@ void prime_field_tests()
fprintf(stdout, "verify degree ...");
if (EC_GROUP_get_degree(group) != 384) ABORT;
fprintf(stdout, " ok\n");
-
- fprintf(stdout, "verify group order ...");
- fflush(stdout);
- if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, ".");
- fflush(stdout);
- if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
if (!EC_GROUP_copy(P_384, group)) ABORT;
@@ -619,18 +609,8 @@ void prime_field_tests()
fprintf(stdout, "verify degree ...");
if (EC_GROUP_get_degree(group) != 521) ABORT;
fprintf(stdout, " ok\n");
-
- fprintf(stdout, "verify group order ...");
- fflush(stdout);
- if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, ".");
- fflush(stdout);
- if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
- fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
if (!EC_GROUP_copy(P_521, group)) ABORT;
@@ -659,6 +639,7 @@ void prime_field_tests()
points[2] = Q;
points[3] = Q;
+ if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
if (!BN_add(y, z, BN_value_one())) ABORT;
if (BN_is_odd(y)) ABORT;
if (!BN_rshift1(y, y)) ABORT;
@@ -792,22 +773,14 @@ void prime_field_tests()
fprintf(stdout, "verify degree ..."); \
if (EC_GROUP_get_degree(group) != _degree) ABORT; \
fprintf(stdout, " ok\n"); \
- fprintf(stdout, "verify group order ..."); \
- fflush(stdout); \
- if (!EC_GROUP_get_order(group, z, ctx)) ABORT; \
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
- fprintf(stdout, "."); \
- fflush(stdout); \
- if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; \
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
- fprintf(stdout, " ok\n"); \
+ group_order_tests(group); \
if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
- if (!EC_GROUP_copy(_variable, group)) ABORT;
+ if (!EC_GROUP_copy(_variable, group)) ABORT; \
-void char2_field_tests()
- {
+#ifndef OPENSSL_NO_EC2M
+
+static void char2_field_tests(void)
+ {
BN_CTX *ctx = NULL;
BIGNUM *p, *a, *b;
EC_GROUP *group;
@@ -1239,8 +1212,9 @@ void char2_field_tests()
if (C2_B571) EC_GROUP_free(C2_B571);
}
+#endif
-void internal_curve_test(void)
+static void internal_curve_test(void)
{
EC_builtin_curve *curves = NULL;
size_t crv_len = 0, n = 0;
@@ -1287,13 +1261,189 @@ void internal_curve_test(void)
EC_GROUP_free(group);
}
if (ok)
- fprintf(stdout, " ok\n");
+ fprintf(stdout, " ok\n\n");
else
- fprintf(stdout, " failed\n");
+ {
+ fprintf(stdout, " failed\n\n");
+ ABORT;
+ }
OPENSSL_free(curves);
return;
}
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+/* nistp_test_params contains magic numbers for testing our optimized
+ * implementations of several NIST curves with characteristic > 3. */
+struct nistp_test_params
+ {
+ const EC_METHOD* (*meth) ();
+ int degree;
+ /* Qx, Qy and D are taken from
+ * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
+ * Otherwise, values are standard curve parameters from FIPS 180-3 */
+ const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
+ };
+
+static const struct nistp_test_params nistp_tests_params[] =
+ {
+ {
+ /* P-224 */
+ EC_GFp_nistp224_method,
+ 224,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* p */
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* a */
+ "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* b */
+ "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E", /* Qx */
+ "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555", /* Qy */
+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */
+ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */
+ "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8", /* d */
+ },
+ {
+ /* P-256 */
+ EC_GFp_nistp256_method,
+ 256,
+ "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", /* p */
+ "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", /* a */
+ "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", /* b */
+ "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", /* Qx */
+ "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", /* Qy */
+ "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", /* Gx */
+ "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", /* Gy */
+ "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", /* order */
+ "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", /* d */
+ },
+ {
+ /* P-521 */
+ EC_GFp_nistp521_method,
+ 521,
+ "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", /* p */
+ "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", /* a */
+ "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", /* b */
+ "0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", /* Qx */
+ "0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", /* Qy */
+ "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", /* Gx */
+ "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", /* Gy */
+ "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", /* order */
+ "0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", /* d */
+ },
+ };
+
+void nistp_single_test(const struct nistp_test_params *test)
+ {
+ BN_CTX *ctx;
+ BIGNUM *p, *a, *b, *x, *y, *n, *m, *order;
+ EC_GROUP *NISTP;
+ EC_POINT *G, *P, *Q, *Q_CHECK;
+
+ fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", test->degree);
+ ctx = BN_CTX_new();
+ p = BN_new();
+ a = BN_new();
+ b = BN_new();
+ x = BN_new(); y = BN_new();
+ m = BN_new(); n = BN_new(); order = BN_new();
+
+ NISTP = EC_GROUP_new(test->meth());
+ if(!NISTP) ABORT;
+ if (!BN_hex2bn(&p, test->p)) ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+ if (!BN_hex2bn(&a, test->a)) ABORT;
+ if (!BN_hex2bn(&b, test->b)) ABORT;
+ if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx)) ABORT;
+ G = EC_POINT_new(NISTP);
+ P = EC_POINT_new(NISTP);
+ Q = EC_POINT_new(NISTP);
+ Q_CHECK = EC_POINT_new(NISTP);
+ if(!BN_hex2bn(&x, test->Qx)) ABORT;
+ if(!BN_hex2bn(&y, test->Qy)) ABORT;
+ if(!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx)) ABORT;
+ if (!BN_hex2bn(&x, test->Gx)) ABORT;
+ if (!BN_hex2bn(&y, test->Gy)) ABORT;
+ if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx)) ABORT;
+ if (!BN_hex2bn(&order, test->order)) ABORT;
+ if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT;
+
+ fprintf(stdout, "verify degree ... ");
+ if (EC_GROUP_get_degree(NISTP) != test->degree) ABORT;
+ fprintf(stdout, "ok\n");
+
+ fprintf(stdout, "NIST test vectors ... ");
+ if (!BN_hex2bn(&n, test->d)) ABORT;
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+
+ /* set generator to P = 2*G, where G is the standard generator */
+ if (!EC_POINT_dbl(NISTP, P, G, ctx)) ABORT;
+ if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) ABORT;
+ /* set the scalar to m=n/2, where n is the NIST test scalar */
+ if (!BN_rshift(m, n, 1)) ABORT;
+
+ /* test the non-standard generator */
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+
+ /* now repeat all tests with precomputation */
+ if (!EC_GROUP_precompute_mult(NISTP, ctx)) ABORT;
+
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+
+ /* reset generator */
+ if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT;
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+
+ fprintf(stdout, "ok\n");
+ group_order_tests(NISTP);
+#if 0
+ timings(NISTP, TIMING_BASE_PT, ctx);
+ timings(NISTP, TIMING_RAND_PT, ctx);
+#endif
+ EC_GROUP_free(NISTP);
+ EC_POINT_free(G);
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ EC_POINT_free(Q_CHECK);
+ BN_free(n);
+ BN_free(m);
+ BN_free(p);
+ BN_free(a);
+ BN_free(b);
+ BN_free(x);
+ BN_free(y);
+ BN_free(order);
+ BN_CTX_free(ctx);
+ }
+
+void nistp_tests()
+ {
+ unsigned i;
+
+ for (i = 0; i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params); i++)
+ {
+ nistp_single_test(&nistp_tests_params[i]);
+ }
+ }
+#endif
+
static const char rnd_seed[] = "string to make the random number generator think it has entropy";
int main(int argc, char *argv[])
@@ -1317,7 +1467,12 @@ int main(int argc, char *argv[])
prime_field_tests();
puts("");
+#ifndef OPENSSL_NO_EC2M
char2_field_tests();
+#endif
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ nistp_tests();
+#endif
/* test the internal curves */
internal_curve_test();
diff --git a/deps/openssl/openssl/crypto/ecdh/Makefile b/deps/openssl/openssl/crypto/ecdh/Makefile
index 65d8904ee..ba05fea05 100644
--- a/deps/openssl/openssl/crypto/ecdh/Makefile
+++ b/deps/openssl/openssl/crypto/ecdh/Makefile
@@ -84,17 +84,12 @@ ech_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
ech_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ech_err.o: ech_err.c
ech_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ech_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-ech_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ech_key.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-ech_key.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
-ech_key.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ech_key.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-ech_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ech_key.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-ech_key.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-ech_key.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-ech_key.o: ../../include/openssl/x509_vfy.h ech_key.c ech_locl.h
+ech_key.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ech_key.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ech_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ech_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ech_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ech_key.o: ech_key.c ech_locl.h
ech_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ech_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
ech_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
diff --git a/deps/openssl/openssl/crypto/ecdh/ecdh.h b/deps/openssl/openssl/crypto/ecdh/ecdh.h
index b4b58ee65..8887102c0 100644
--- a/deps/openssl/openssl/crypto/ecdh/ecdh.h
+++ b/deps/openssl/openssl/crypto/ecdh/ecdh.h
@@ -109,11 +109,13 @@ void ERR_load_ECDH_strings(void);
/* Error codes for the ECDH functions. */
/* Function codes. */
+#define ECDH_F_ECDH_CHECK 102
#define ECDH_F_ECDH_COMPUTE_KEY 100
#define ECDH_F_ECDH_DATA_NEW_METHOD 101
/* Reason codes. */
#define ECDH_R_KDF_FAILED 102
+#define ECDH_R_NON_FIPS_METHOD 103
#define ECDH_R_NO_PRIVATE_VALUE 100
#define ECDH_R_POINT_ARITHMETIC_FAILURE 101
diff --git a/deps/openssl/openssl/crypto/ecdh/ecdhtest.c b/deps/openssl/openssl/crypto/ecdh/ecdhtest.c
index 212a87efa..823d7baa6 100644
--- a/deps/openssl/openssl/crypto/ecdh/ecdhtest.c
+++ b/deps/openssl/openssl/crypto/ecdh/ecdhtest.c
@@ -158,11 +158,13 @@ static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
if (!EC_POINT_get_affine_coordinates_GFp(group,
EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
}
+#ifndef OPENSSL_NO_EC2M
else
{
if (!EC_POINT_get_affine_coordinates_GF2m(group,
EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
}
+#endif
#ifdef NOISY
BIO_puts(out," pri 1=");
BN_print(out,a->priv_key);
@@ -183,11 +185,13 @@ static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
if (!EC_POINT_get_affine_coordinates_GFp(group,
EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
}
+#ifndef OPENSSL_NO_EC2M
else
{
if (!EC_POINT_get_affine_coordinates_GF2m(group,
EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
}
+#endif
#ifdef NOISY
BIO_puts(out," pri 2=");
@@ -324,6 +328,7 @@ int main(int argc, char *argv[])
if (!test_ecdh_curve(NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) goto err;
if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) goto err;
if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) goto err;
+#ifndef OPENSSL_NO_EC2M
/* NIST BINARY CURVES TESTS */
if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) goto err;
if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) goto err;
@@ -335,6 +340,7 @@ int main(int argc, char *argv[])
if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) goto err;
if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) goto err;
if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) goto err;
+#endif
ret = 0;
diff --git a/deps/openssl/openssl/crypto/ecdh/ech_err.c b/deps/openssl/openssl/crypto/ecdh/ech_err.c
index 6f4b0c995..3bd247398 100644
--- a/deps/openssl/openssl/crypto/ecdh/ech_err.c
+++ b/deps/openssl/openssl/crypto/ecdh/ech_err.c
@@ -1,6 +1,6 @@
/* crypto/ecdh/ech_err.c */
/* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -70,6 +70,7 @@
static ERR_STRING_DATA ECDH_str_functs[]=
{
+{ERR_FUNC(ECDH_F_ECDH_CHECK), "ECDH_CHECK"},
{ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"},
{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_new_method"},
{0,NULL}
@@ -78,6 +79,7 @@ static ERR_STRING_DATA ECDH_str_functs[]=
static ERR_STRING_DATA ECDH_str_reasons[]=
{
{ERR_REASON(ECDH_R_KDF_FAILED) ,"KDF failed"},
+{ERR_REASON(ECDH_R_NON_FIPS_METHOD) ,"non fips method"},
{ERR_REASON(ECDH_R_NO_PRIVATE_VALUE) ,"no private value"},
{ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE),"point arithmetic failure"},
{0,NULL}
diff --git a/deps/openssl/openssl/crypto/ecdh/ech_key.c b/deps/openssl/openssl/crypto/ecdh/ech_key.c
index f44da9298..2988899ea 100644
--- a/deps/openssl/openssl/crypto/ecdh/ech_key.c
+++ b/deps/openssl/openssl/crypto/ecdh/ech_key.c
@@ -68,9 +68,6 @@
*/
#include "ech_locl.h"
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
EC_KEY *eckey,
diff --git a/deps/openssl/openssl/crypto/ecdh/ech_lib.c b/deps/openssl/openssl/crypto/ecdh/ech_lib.c
index 4d8ea03d3..0644431b7 100644
--- a/deps/openssl/openssl/crypto/ecdh/ech_lib.c
+++ b/deps/openssl/openssl/crypto/ecdh/ech_lib.c
@@ -73,6 +73,9 @@
#include <openssl/engine.h>
#endif
#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
const char ECDH_version[]="ECDH" OPENSSL_VERSION_PTEXT;
@@ -90,7 +93,16 @@ void ECDH_set_default_method(const ECDH_METHOD *meth)
const ECDH_METHOD *ECDH_get_default_method(void)
{
if(!default_ECDH_method)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_ecdh_openssl();
+ else
+ return ECDH_OpenSSL();
+#else
default_ECDH_method = ECDH_OpenSSL();
+#endif
+ }
return default_ECDH_method;
}
@@ -210,11 +222,26 @@ ECDH_DATA *ecdh_check(EC_KEY *key)
ecdh_data = (ECDH_DATA *)ecdh_data_new();
if (ecdh_data == NULL)
return NULL;
- EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
- ecdh_data_dup, ecdh_data_free, ecdh_data_free);
+ data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
+ ecdh_data_dup, ecdh_data_free, ecdh_data_free);
+ if (data != NULL)
+ {
+ /* Another thread raced us to install the key_method
+ * data and won. */
+ ecdh_data_free(ecdh_data);
+ ecdh_data = (ECDH_DATA *)data;
+ }
}
else
ecdh_data = (ECDH_DATA *)data;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD)
+ && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW))
+ {
+ ECDHerr(ECDH_F_ECDH_CHECK, ECDH_R_NON_FIPS_METHOD);
+ return NULL;
+ }
+#endif
return ecdh_data;
diff --git a/deps/openssl/openssl/crypto/ecdh/ech_locl.h b/deps/openssl/openssl/crypto/ecdh/ech_locl.h
index f658526a7..f6cad6a89 100644
--- a/deps/openssl/openssl/crypto/ecdh/ech_locl.h
+++ b/deps/openssl/openssl/crypto/ecdh/ech_locl.h
@@ -75,6 +75,14 @@ struct ecdh_method
char *app_data;
};
+/* If this flag is set the ECDH method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its responsibility
+ * to ensure the result is compliant.
+ */
+
+#define ECDH_FLAG_FIPS_METHOD 0x1
+
typedef struct ecdh_data_st {
/* EC_KEY_METH_DATA part */
int (*init)(EC_KEY *);
diff --git a/deps/openssl/openssl/crypto/ecdh/ech_ossl.c b/deps/openssl/openssl/crypto/ecdh/ech_ossl.c
index 2a40ff12d..4a30628fb 100644
--- a/deps/openssl/openssl/crypto/ecdh/ech_ossl.c
+++ b/deps/openssl/openssl/crypto/ecdh/ech_ossl.c
@@ -157,6 +157,7 @@ static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else
{
if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx))
@@ -165,6 +166,7 @@ static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
goto err;
}
}
+#endif
buflen = (EC_GROUP_get_degree(group) + 7)/8;
len = BN_num_bytes(x);
diff --git a/deps/openssl/openssl/crypto/ecdsa/ecdsa.h b/deps/openssl/openssl/crypto/ecdsa/ecdsa.h
index e61c53981..7fb5254b6 100644
--- a/deps/openssl/openssl/crypto/ecdsa/ecdsa.h
+++ b/deps/openssl/openssl/crypto/ecdsa/ecdsa.h
@@ -238,6 +238,7 @@ void ERR_load_ECDSA_strings(void);
/* Error codes for the ECDSA functions. */
/* Function codes. */
+#define ECDSA_F_ECDSA_CHECK 104
#define ECDSA_F_ECDSA_DATA_NEW_METHOD 100
#define ECDSA_F_ECDSA_DO_SIGN 101
#define ECDSA_F_ECDSA_DO_VERIFY 102
@@ -249,6 +250,7 @@ void ERR_load_ECDSA_strings(void);
#define ECDSA_R_ERR_EC_LIB 102
#define ECDSA_R_MISSING_PARAMETERS 103
#define ECDSA_R_NEED_NEW_SETUP_VALUES 106
+#define ECDSA_R_NON_FIPS_METHOD 107
#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104
#define ECDSA_R_SIGNATURE_MALLOC_FAILED 105
diff --git a/deps/openssl/openssl/crypto/ecdsa/ecdsatest.c b/deps/openssl/openssl/crypto/ecdsa/ecdsatest.c
index 54cfb8c75..537bb3036 100644
--- a/deps/openssl/openssl/crypto/ecdsa/ecdsatest.c
+++ b/deps/openssl/openssl/crypto/ecdsa/ecdsatest.c
@@ -262,6 +262,7 @@ int x9_62_tests(BIO *out)
"3238135532097973577080787768312505059318910517550078427819"
"78505179448783"))
goto x962_err;
+#ifndef OPENSSL_NO_EC2M
if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1,
"87194383164871543355722284926904419997237591535066528048",
"308992691965804947361541664549085895292153777025772063598"))
@@ -272,7 +273,7 @@ int x9_62_tests(BIO *out)
"1970303740007316867383349976549972270528498040721988191026"
"49413465737174"))
goto x962_err;
-
+#endif
ret = 1;
x962_err:
if (!restore_rand())
@@ -289,7 +290,8 @@ int test_builtin(BIO *out)
ECDSA_SIG *ecdsa_sig = NULL;
unsigned char digest[20], wrong_digest[20];
unsigned char *signature = NULL;
- unsigned char *sig_ptr;
+ const unsigned char *sig_ptr;
+ unsigned char *sig_ptr2;
unsigned char *raw_buf = NULL;
unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
int nid, ret = 0;
@@ -464,8 +466,8 @@ int test_builtin(BIO *out)
(BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
goto builtin_err;
- sig_ptr = signature;
- sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr);
+ sig_ptr2 = signature;
+ sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
{
BIO_printf(out, " failed\n");
@@ -477,8 +479,8 @@ int test_builtin(BIO *out)
(BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
goto builtin_err;
- sig_ptr = signature;
- sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr);
+ sig_ptr2 = signature;
+ sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
{
BIO_printf(out, " failed\n");
diff --git a/deps/openssl/openssl/crypto/ecdsa/ecs_err.c b/deps/openssl/openssl/crypto/ecdsa/ecs_err.c
index 98e38d537..81542e6d1 100644
--- a/deps/openssl/openssl/crypto/ecdsa/ecs_err.c
+++ b/deps/openssl/openssl/crypto/ecdsa/ecs_err.c
@@ -1,6 +1,6 @@
/* crypto/ecdsa/ecs_err.c */
/* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -70,6 +70,7 @@
static ERR_STRING_DATA ECDSA_str_functs[]=
{
+{ERR_FUNC(ECDSA_F_ECDSA_CHECK), "ECDSA_CHECK"},
{ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD), "ECDSA_DATA_NEW_METHOD"},
{ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN), "ECDSA_do_sign"},
{ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"},
@@ -84,6 +85,7 @@ static ERR_STRING_DATA ECDSA_str_reasons[]=
{ERR_REASON(ECDSA_R_ERR_EC_LIB) ,"err ec lib"},
{ERR_REASON(ECDSA_R_MISSING_PARAMETERS) ,"missing parameters"},
{ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES),"need new setup values"},
+{ERR_REASON(ECDSA_R_NON_FIPS_METHOD) ,"non fips method"},
{ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED),"random number generation failed"},
{ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED),"signature malloc failed"},
{0,NULL}
diff --git a/deps/openssl/openssl/crypto/ecdsa/ecs_lib.c b/deps/openssl/openssl/crypto/ecdsa/ecs_lib.c
index 2ebae3aa2..814a6bf40 100644
--- a/deps/openssl/openssl/crypto/ecdsa/ecs_lib.c
+++ b/deps/openssl/openssl/crypto/ecdsa/ecs_lib.c
@@ -60,6 +60,9 @@
#endif
#include <openssl/err.h>
#include <openssl/bn.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
const char ECDSA_version[]="ECDSA" OPENSSL_VERSION_PTEXT;
@@ -77,7 +80,16 @@ void ECDSA_set_default_method(const ECDSA_METHOD *meth)
const ECDSA_METHOD *ECDSA_get_default_method(void)
{
if(!default_ECDSA_method)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_ecdsa_openssl();
+ else
+ return ECDSA_OpenSSL();
+#else
default_ECDSA_method = ECDSA_OpenSSL();
+#endif
+ }
return default_ECDSA_method;
}
@@ -188,12 +200,26 @@ ECDSA_DATA *ecdsa_check(EC_KEY *key)
ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
if (ecdsa_data == NULL)
return NULL;
- EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
- ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
+ data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
+ ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
+ if (data != NULL)
+ {
+ /* Another thread raced us to install the key_method
+ * data and won. */
+ ecdsa_data_free(ecdsa_data);
+ ecdsa_data = (ECDSA_DATA *)data;
+ }
}
else
ecdsa_data = (ECDSA_DATA *)data;
-
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD)
+ && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW))
+ {
+ ECDSAerr(ECDSA_F_ECDSA_CHECK, ECDSA_R_NON_FIPS_METHOD);
+ return NULL;
+ }
+#endif
return ecdsa_data;
}
diff --git a/deps/openssl/openssl/crypto/ecdsa/ecs_locl.h b/deps/openssl/openssl/crypto/ecdsa/ecs_locl.h
index 3a69a840e..cb3be13cf 100644
--- a/deps/openssl/openssl/crypto/ecdsa/ecs_locl.h
+++ b/deps/openssl/openssl/crypto/ecdsa/ecs_locl.h
@@ -82,6 +82,14 @@ struct ecdsa_method
char *app_data;
};
+/* If this flag is set the ECDSA method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its responsibility
+ * to ensure the result is compliant.
+ */
+
+#define ECDSA_FLAG_FIPS_METHOD 0x1
+
typedef struct ecdsa_data_st {
/* EC_KEY_METH_DATA part */
int (*init)(EC_KEY *);
diff --git a/deps/openssl/openssl/crypto/ecdsa/ecs_ossl.c b/deps/openssl/openssl/crypto/ecdsa/ecs_ossl.c
index 1bbf328de..772593561 100644
--- a/deps/openssl/openssl/crypto/ecdsa/ecs_ossl.c
+++ b/deps/openssl/openssl/crypto/ecdsa/ecs_ossl.c
@@ -167,6 +167,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else /* NID_X9_62_characteristic_two_field */
{
if (!EC_POINT_get_affine_coordinates_GF2m(group,
@@ -176,6 +177,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
goto err;
}
}
+#endif
if (!BN_nnmod(r, X, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
@@ -454,6 +456,7 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else /* NID_X9_62_characteristic_two_field */
{
if (!EC_POINT_get_affine_coordinates_GF2m(group,
@@ -463,7 +466,7 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
goto err;
}
}
-
+#endif
if (!BN_nnmod(u1, X, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
diff --git a/deps/openssl/openssl/crypto/engine/Makefile b/deps/openssl/openssl/crypto/engine/Makefile
index 9c214824e..d29bdd09a 100644
--- a/deps/openssl/openssl/crypto/engine/Makefile
+++ b/deps/openssl/openssl/crypto/engine/Makefile
@@ -21,12 +21,14 @@ LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
eng_table.c eng_pkey.c eng_fat.c eng_all.c \
tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
- eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c
+ eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c \
+ eng_rsax.c eng_rdrand.c
LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
eng_table.o eng_pkey.o eng_fat.o eng_all.o \
tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \
- eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o
+ eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o \
+ eng_rsax.o eng_rdrand.o
SRC= $(LIBSRC)
@@ -249,6 +251,34 @@ eng_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
eng_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
eng_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_pkey.c
+eng_rdrand.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+eng_rdrand.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+eng_rdrand.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_rdrand.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+eng_rdrand.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+eng_rdrand.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+eng_rdrand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+eng_rdrand.o: ../../include/openssl/opensslconf.h
+eng_rdrand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eng_rdrand.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+eng_rdrand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+eng_rdrand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+eng_rdrand.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+eng_rdrand.o: eng_rdrand.c
+eng_rsax.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+eng_rsax.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+eng_rsax.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_rsax.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_rsax.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_rsax.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_rsax.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_rsax.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+eng_rsax.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eng_rsax.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+eng_rsax.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+eng_rsax.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+eng_rsax.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+eng_rsax.o: eng_rsax.c
eng_table.o: ../../e_os.h ../../include/openssl/asn1.h
eng_table.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
eng_table.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
diff --git a/deps/openssl/openssl/crypto/engine/eng_all.c b/deps/openssl/openssl/crypto/engine/eng_all.c
index 22c120454..6093376df 100644
--- a/deps/openssl/openssl/crypto/engine/eng_all.c
+++ b/deps/openssl/openssl/crypto/engine/eng_all.c
@@ -61,6 +61,8 @@
void ENGINE_load_builtin_engines(void)
{
+ /* Some ENGINEs need this */
+ OPENSSL_cpuid_setup();
#if 0
/* There's no longer any need for an "openssl" ENGINE unless, one day,
* it is the *only* way for standard builtin implementations to be be
@@ -71,6 +73,12 @@ void ENGINE_load_builtin_engines(void)
#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
ENGINE_load_cryptodev();
#endif
+#ifndef OPENSSL_NO_RSAX
+ ENGINE_load_rsax();
+#endif
+#ifndef OPENSSL_NO_RDRAND
+ ENGINE_load_rdrand();
+#endif
ENGINE_load_dynamic();
#ifndef OPENSSL_NO_STATIC_ENGINE
#ifndef OPENSSL_NO_HW
@@ -112,6 +120,7 @@ void ENGINE_load_builtin_engines(void)
ENGINE_load_capi();
#endif
#endif
+ ENGINE_register_all_complete();
}
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
diff --git a/deps/openssl/openssl/crypto/engine/eng_cryptodev.c b/deps/openssl/openssl/crypto/engine/eng_cryptodev.c
index 52f4ca390..5a715aca4 100644
--- a/deps/openssl/openssl/crypto/engine/eng_cryptodev.c
+++ b/deps/openssl/openssl/crypto/engine/eng_cryptodev.c
@@ -79,8 +79,6 @@ struct dev_crypto_state {
unsigned char digest_res[HASH_MAX_LEN];
char *mac_data;
int mac_len;
-
- int copy;
#endif
};
@@ -200,6 +198,7 @@ get_dev_crypto(void)
if ((fd = open_dev_crypto()) == -1)
return (-1);
+#ifndef CRIOGET_NOT_NEEDED
if (ioctl(fd, CRIOGET, &retfd) == -1)
return (-1);
@@ -208,9 +207,19 @@ get_dev_crypto(void)
close(retfd);
return (-1);
}
+#else
+ retfd = fd;
+#endif
return (retfd);
}
+static void put_dev_crypto(int fd)
+{
+#ifndef CRIOGET_NOT_NEEDED
+ close(fd);
+#endif
+}
+
/* Caching version for asym operations */
static int
get_asym_dev_crypto(void)
@@ -252,7 +261,7 @@ get_cryptodev_ciphers(const int **cnids)
ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
nids[count++] = ciphers[i].nid;
}
- close(fd);
+ put_dev_crypto(fd);
if (count > 0)
*cnids = nids;
@@ -291,7 +300,7 @@ get_cryptodev_digests(const int **cnids)
ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
nids[count++] = digests[i].nid;
}
- close(fd);
+ put_dev_crypto(fd);
if (count > 0)
*cnids = nids;
@@ -436,7 +445,7 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
sess->cipher = cipher;
if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
- close(state->d_fd);
+ put_dev_crypto(state->d_fd);
state->d_fd = -1;
return (0);
}
@@ -473,7 +482,7 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
} else {
ret = 1;
}
- close(state->d_fd);
+ put_dev_crypto(state->d_fd);
state->d_fd = -1;
return (ret);
@@ -686,7 +695,7 @@ static int cryptodev_digest_init(EVP_MD_CTX *ctx)
sess->mac = digest;
if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
- close(state->d_fd);
+ put_dev_crypto(state->d_fd);
state->d_fd = -1;
printf("cryptodev_digest_init: Open session failed\n");
return (0);
@@ -758,14 +767,12 @@ static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
/* if application doesn't support one buffer */
memset(&cryp, 0, sizeof(cryp));
-
cryp.ses = sess->ses;
cryp.flags = 0;
cryp.len = state->mac_len;
cryp.src = state->mac_data;
cryp.dst = NULL;
cryp.mac = (caddr_t)md;
-
if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
printf("cryptodev_digest_final: digest failed\n");
return (0);
@@ -786,6 +793,9 @@ static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
struct dev_crypto_state *state = ctx->md_data;
struct session_op *sess = &state->d_sess;
+ if (state == NULL)
+ return 0;
+
if (state->d_fd < 0) {
printf("cryptodev_digest_cleanup: illegal input\n");
return (0);
@@ -797,16 +807,13 @@ static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
state->mac_len = 0;
}
- if (state->copy)
- return 1;
-
if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
printf("cryptodev_digest_cleanup: failed to close session\n");
ret = 0;
} else {
ret = 1;
}
- close(state->d_fd);
+ put_dev_crypto(state->d_fd);
state->d_fd = -1;
return (ret);
@@ -816,15 +823,39 @@ static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
{
struct dev_crypto_state *fstate = from->md_data;
struct dev_crypto_state *dstate = to->md_data;
+ struct session_op *sess;
+ int digest;
- memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
+ if (dstate == NULL || fstate == NULL)
+ return 1;
- if (fstate->mac_len != 0) {
- dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
- memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
+ memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
+
+ sess = &dstate->d_sess;
+
+ digest = digest_nid_to_cryptodev(to->digest->type);
+
+ sess->mackey = dstate->dummy_mac_key;
+ sess->mackeylen = digest_key_length(to->digest->type);
+ sess->mac = digest;
+
+ dstate->d_fd = get_dev_crypto();
+
+ if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
+ put_dev_crypto(dstate->d_fd);
+ dstate->d_fd = -1;
+ printf("cryptodev_digest_init: Open session failed\n");
+ return (0);
}
- dstate->copy = 1;
+ if (fstate->mac_len != 0) {
+ if (fstate->mac_data != NULL)
+ {
+ dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
+ memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
+ dstate->mac_len = fstate->mac_len;
+ }
+ }
return 1;
}
@@ -1347,11 +1378,11 @@ ENGINE_load_cryptodev(void)
* find out what asymmetric crypto algorithms we support
*/
if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
- close(fd);
+ put_dev_crypto(fd);
ENGINE_free(engine);
return;
}
- close(fd);
+ put_dev_crypto(fd);
if (!ENGINE_set_id(engine, "cryptodev") ||
!ENGINE_set_name(engine, "BSD cryptodev engine") ||
diff --git a/deps/openssl/openssl/crypto/engine/eng_fat.c b/deps/openssl/openssl/crypto/engine/eng_fat.c
index db66e6235..789b8d57e 100644
--- a/deps/openssl/openssl/crypto/engine/eng_fat.c
+++ b/deps/openssl/openssl/crypto/engine/eng_fat.c
@@ -176,6 +176,7 @@ int ENGINE_register_all_complete(void)
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
- ENGINE_register_complete(e);
+ if (!(e->flags & ENGINE_FLAGS_NO_REGISTER_ALL))
+ ENGINE_register_complete(e);
return 1;
}
diff --git a/deps/openssl/openssl/crypto/engine/eng_rdrand.c b/deps/openssl/openssl/crypto/engine/eng_rdrand.c
new file mode 100644
index 000000000..a9ba5ae6f
--- /dev/null
+++ b/deps/openssl/openssl/crypto/engine/eng_rdrand.c
@@ -0,0 +1,142 @@
+/* ====================================================================
+ * Copyright (c) 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
+ * licensing@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.
+ * ====================================================================
+ */
+
+#include <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/engine.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ)
+
+size_t OPENSSL_ia32_rdrand(void);
+
+static int get_random_bytes (unsigned char *buf, int num)
+ {
+ size_t rnd;
+
+ while (num>=(int)sizeof(size_t)) {
+ if ((rnd = OPENSSL_ia32_rdrand()) == 0) return 0;
+
+ *((size_t *)buf) = rnd;
+ buf += sizeof(size_t);
+ num -= sizeof(size_t);
+ }
+ if (num) {
+ if ((rnd = OPENSSL_ia32_rdrand()) == 0) return 0;
+
+ memcpy (buf,&rnd,num);
+ }
+
+ return 1;
+ }
+
+static int random_status (void)
+{ return 1; }
+
+static RAND_METHOD rdrand_meth =
+ {
+ NULL, /* seed */
+ get_random_bytes,
+ NULL, /* cleanup */
+ NULL, /* add */
+ get_random_bytes,
+ random_status,
+ };
+
+static int rdrand_init(ENGINE *e)
+{ return 1; }
+
+static const char *engine_e_rdrand_id = "rdrand";
+static const char *engine_e_rdrand_name = "Intel RDRAND engine";
+
+static int bind_helper(ENGINE *e)
+ {
+ if (!ENGINE_set_id(e, engine_e_rdrand_id) ||
+ !ENGINE_set_name(e, engine_e_rdrand_name) ||
+ !ENGINE_set_init_function(e, rdrand_init) ||
+ !ENGINE_set_RAND(e, &rdrand_meth) )
+ return 0;
+
+ return 1;
+ }
+
+static ENGINE *ENGINE_rdrand(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_rdrand (void)
+ {
+ extern unsigned int OPENSSL_ia32cap_P[];
+
+ if (OPENSSL_ia32cap_P[1] & (1<<(62-32)))
+ {
+ ENGINE *toadd = ENGINE_rdrand();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+ }
+#else
+void ENGINE_load_rdrand (void) {}
+#endif
diff --git a/deps/openssl/openssl/crypto/engine/eng_rsax.c b/deps/openssl/openssl/crypto/engine/eng_rsax.c
new file mode 100644
index 000000000..96e63477e
--- /dev/null
+++ b/deps/openssl/openssl/crypto/engine/eng_rsax.c
@@ -0,0 +1,668 @@
+/* crypto/engine/eng_rsax.c */
+/* Copyright (c) 2010-2010 Intel Corp.
+ * Author: Vinodh.Gopal@intel.com
+ * Jim Guilford
+ * Erdinc.Ozturk@intel.com
+ * Maxim.Perminov@intel.com
+ * Ying.Huang@intel.com
+ *
+ * More information about algorithm used can be found at:
+ * http://www.cse.buffalo.edu/srds2009/escs2009_submission_Gopal.pdf
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 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
+ * licensing@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).
+ */
+
+#include <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/engine.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include <openssl/bn.h>
+#include <openssl/err.h>
+
+/* RSAX is available **ONLY* on x86_64 CPUs */
+#undef COMPILE_RSAX
+
+#if (defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined (_M_X64)) && !defined(OPENSSL_NO_ASM)
+#define COMPILE_RSAX
+static ENGINE *ENGINE_rsax (void);
+#endif
+
+void ENGINE_load_rsax (void)
+ {
+/* On non-x86 CPUs it just returns. */
+#ifdef COMPILE_RSAX
+ ENGINE *toadd = ENGINE_rsax();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+#endif
+ }
+
+#ifdef COMPILE_RSAX
+#define E_RSAX_LIB_NAME "rsax engine"
+
+static int e_rsax_destroy(ENGINE *e);
+static int e_rsax_init(ENGINE *e);
+static int e_rsax_finish(ENGINE *e);
+static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int e_rsax_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+static int e_rsax_rsa_finish(RSA *r);
+#endif
+
+static const ENGINE_CMD_DEFN e_rsax_cmd_defns[] = {
+ {0, NULL, NULL, 0}
+ };
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD e_rsax_rsa =
+ {
+ "Intel RSA-X method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ e_rsax_rsa_mod_exp,
+ NULL,
+ NULL,
+ e_rsax_rsa_finish,
+ RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_e_rsax_id = "rsax";
+static const char *engine_e_rsax_name = "RSAX engine support";
+
+/* This internal function is used by ENGINE_rsax() */
+static int bind_helper(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ const RSA_METHOD *meth1;
+#endif
+ if(!ENGINE_set_id(e, engine_e_rsax_id) ||
+ !ENGINE_set_name(e, engine_e_rsax_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &e_rsax_rsa) ||
+#endif
+ !ENGINE_set_destroy_function(e, e_rsax_destroy) ||
+ !ENGINE_set_init_function(e, e_rsax_init) ||
+ !ENGINE_set_finish_function(e, e_rsax_finish) ||
+ !ENGINE_set_ctrl_function(e, e_rsax_ctrl) ||
+ !ENGINE_set_cmd_defns(e, e_rsax_cmd_defns))
+ return 0;
+
+#ifndef OPENSSL_NO_RSA
+ meth1 = RSA_PKCS1_SSLeay();
+ e_rsax_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ e_rsax_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ e_rsax_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ e_rsax_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+ e_rsax_rsa.bn_mod_exp = meth1->bn_mod_exp;
+#endif
+ return 1;
+ }
+
+static ENGINE *ENGINE_rsax(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+#ifndef OPENSSL_NO_RSA
+/* Used to attach our own key-data to an RSA structure */
+static int rsax_ex_data_idx = -1;
+#endif
+
+static int e_rsax_destroy(ENGINE *e)
+ {
+ return 1;
+ }
+
+/* (de)initialisation functions. */
+static int e_rsax_init(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ if (rsax_ex_data_idx == -1)
+ rsax_ex_data_idx = RSA_get_ex_new_index(0,
+ NULL,
+ NULL, NULL, NULL);
+#endif
+ if (rsax_ex_data_idx == -1)
+ return 0;
+ return 1;
+ }
+
+static int e_rsax_finish(ENGINE *e)
+ {
+ return 1;
+ }
+
+static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int to_return = 1;
+
+ switch(cmd)
+ {
+ /* The command isn't understood by this engine */
+ default:
+ to_return = 0;
+ break;
+ }
+
+ return to_return;
+ }
+
+
+#ifndef OPENSSL_NO_RSA
+
+#ifdef _WIN32
+typedef unsigned __int64 UINT64;
+#else
+typedef unsigned long long UINT64;
+#endif
+typedef unsigned short UINT16;
+
+/* Table t is interleaved in the following manner:
+ * The order in memory is t[0][0], t[0][1], ..., t[0][7], t[1][0], ...
+ * A particular 512-bit value is stored in t[][index] rather than the more
+ * normal t[index][]; i.e. the qwords of a particular entry in t are not
+ * adjacent in memory
+ */
+
+/* Init BIGNUM b from the interleaved UINT64 array */
+static int interleaved_array_to_bn_512(BIGNUM* b, UINT64 *array);
+
+/* Extract array elements from BIGNUM b
+ * To set the whole array from b, call with n=8
+ */
+static int bn_extract_to_array_512(const BIGNUM* b, unsigned int n, UINT64 *array);
+
+struct mod_ctx_512 {
+ UINT64 t[8][8];
+ UINT64 m[8];
+ UINT64 m1[8]; /* 2^278 % m */
+ UINT64 m2[8]; /* 2^640 % m */
+ UINT64 k1[2]; /* (- 1/m) % 2^128 */
+};
+
+static int mod_exp_pre_compute_data_512(UINT64 *m, struct mod_ctx_512 *data);
+
+void mod_exp_512(UINT64 *result, /* 512 bits, 8 qwords */
+ UINT64 *g, /* 512 bits, 8 qwords */
+ UINT64 *exp, /* 512 bits, 8 qwords */
+ struct mod_ctx_512 *data);
+
+typedef struct st_e_rsax_mod_ctx
+{
+ UINT64 type;
+ union {
+ struct mod_ctx_512 b512;
+ } ctx;
+
+} E_RSAX_MOD_CTX;
+
+static E_RSAX_MOD_CTX *e_rsax_get_ctx(RSA *rsa, int idx, BIGNUM* m)
+{
+ E_RSAX_MOD_CTX *hptr;
+
+ if (idx < 0 || idx > 2)
+ return NULL;
+
+ hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx);
+ if (!hptr) {
+ hptr = OPENSSL_malloc(3*sizeof(E_RSAX_MOD_CTX));
+ if (!hptr) return NULL;
+ hptr[2].type = hptr[1].type= hptr[0].type = 0;
+ RSA_set_ex_data(rsa, rsax_ex_data_idx, hptr);
+ }
+
+ if (hptr[idx].type == (UINT64)BN_num_bits(m))
+ return hptr+idx;
+
+ if (BN_num_bits(m) == 512) {
+ UINT64 _m[8];
+ bn_extract_to_array_512(m, 8, _m);
+ memset( &hptr[idx].ctx.b512, 0, sizeof(struct mod_ctx_512));
+ mod_exp_pre_compute_data_512(_m, &hptr[idx].ctx.b512);
+ }
+
+ hptr[idx].type = BN_num_bits(m);
+ return hptr+idx;
+}
+
+static int e_rsax_rsa_finish(RSA *rsa)
+ {
+ E_RSAX_MOD_CTX *hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx);
+ if(hptr)
+ {
+ OPENSSL_free(hptr);
+ RSA_set_ex_data(rsa, rsax_ex_data_idx, NULL);
+ }
+ if (rsa->_method_mod_n)
+ BN_MONT_CTX_free(rsa->_method_mod_n);
+ if (rsa->_method_mod_p)
+ BN_MONT_CTX_free(rsa->_method_mod_p);
+ if (rsa->_method_mod_q)
+ BN_MONT_CTX_free(rsa->_method_mod_q);
+ return 1;
+ }
+
+
+static int e_rsax_bn_mod_exp(BIGNUM *r, const BIGNUM *g, const BIGNUM *e,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont, E_RSAX_MOD_CTX* rsax_mod_ctx )
+{
+ if (rsax_mod_ctx && BN_get_flags(e, BN_FLG_CONSTTIME) != 0) {
+ if (BN_num_bits(m) == 512) {
+ UINT64 _r[8];
+ UINT64 _g[8];
+ UINT64 _e[8];
+
+ /* Init the arrays from the BIGNUMs */
+ bn_extract_to_array_512(g, 8, _g);
+ bn_extract_to_array_512(e, 8, _e);
+
+ mod_exp_512(_r, _g, _e, &rsax_mod_ctx->ctx.b512);
+ /* Return the result in the BIGNUM */
+ interleaved_array_to_bn_512(r, _r);
+ return 1;
+ }
+ }
+
+ return BN_mod_exp_mont(r, g, e, m, ctx, in_mont);
+}
+
+/* Declares for the Intel CIAP 512-bit / CRT / 1024 bit RSA modular
+ * exponentiation routine precalculations and a structure to hold the
+ * necessary values. These files are meant to live in crypto/rsa/ in
+ * the target openssl.
+ */
+
+/*
+ * Local method: extracts a piece from a BIGNUM, to fit it into
+ * an array. Call with n=8 to extract an entire 512-bit BIGNUM
+ */
+static int bn_extract_to_array_512(const BIGNUM* b, unsigned int n, UINT64 *array)
+{
+ int i;
+ UINT64 tmp;
+ unsigned char bn_buff[64];
+ memset(bn_buff, 0, 64);
+ if (BN_num_bytes(b) > 64) {
+ printf ("Can't support this byte size\n");
+ return 0; }
+ if (BN_num_bytes(b)!=0) {
+ if (!BN_bn2bin(b, bn_buff+(64-BN_num_bytes(b)))) {
+ printf ("Error's in bn2bin\n");
+ /* We have to error, here */
+ return 0; } }
+ while (n-- > 0) {
+ array[n] = 0;
+ for (i=7; i>=0; i--) {
+ tmp = bn_buff[63-(n*8+i)];
+ array[n] |= tmp << (8*i); } }
+ return 1;
+}
+
+/* Init a 512-bit BIGNUM from the UINT64*_ (8 * 64) interleaved array */
+static int interleaved_array_to_bn_512(BIGNUM* b, UINT64 *array)
+{
+ unsigned char tmp[64];
+ int n=8;
+ int i;
+ while (n-- > 0) {
+ for (i = 7; i>=0; i--) {
+ tmp[63-(n*8+i)] = (unsigned char)(array[n]>>(8*i)); } }
+ BN_bin2bn(tmp, 64, b);
+ return 0;
+}
+
+
+/* The main 512bit precompute call */
+static int mod_exp_pre_compute_data_512(UINT64 *m, struct mod_ctx_512 *data)
+ {
+ BIGNUM two_768, two_640, two_128, two_512, tmp, _m, tmp2;
+
+ /* We need a BN_CTX for the modulo functions */
+ BN_CTX* ctx;
+ /* Some tmps */
+ UINT64 _t[8];
+ int i, j, ret = 0;
+
+ /* Init _m with m */
+ BN_init(&_m);
+ interleaved_array_to_bn_512(&_m, m);
+ memset(_t, 0, 64);
+
+ /* Inits */
+ BN_init(&two_768);
+ BN_init(&two_640);
+ BN_init(&two_128);
+ BN_init(&two_512);
+ BN_init(&tmp);
+ BN_init(&tmp2);
+
+ /* Create our context */
+ if ((ctx=BN_CTX_new()) == NULL) { goto err; }
+ BN_CTX_start(ctx);
+
+ /*
+ * For production, if you care, these only need to be set once,
+ * and may be made constants.
+ */
+ BN_lshift(&two_768, BN_value_one(), 768);
+ BN_lshift(&two_640, BN_value_one(), 640);
+ BN_lshift(&two_128, BN_value_one(), 128);
+ BN_lshift(&two_512, BN_value_one(), 512);
+
+ if (0 == (m[7] & 0x8000000000000000)) {
+ exit(1);
+ }
+ if (0 == (m[0] & 0x1)) { /* Odd modulus required for Mont */
+ exit(1);
+ }
+
+ /* Precompute m1 */
+ BN_mod(&tmp, &two_768, &_m, ctx);
+ if (!bn_extract_to_array_512(&tmp, 8, &data->m1[0])) {
+ goto err; }
+
+ /* Precompute m2 */
+ BN_mod(&tmp, &two_640, &_m, ctx);
+ if (!bn_extract_to_array_512(&tmp, 8, &data->m2[0])) {
+ goto err;
+ }
+
+ /*
+ * Precompute k1, a 128b number = ((-1)* m-1 ) mod 2128; k1 should
+ * be non-negative.
+ */
+ BN_mod_inverse(&tmp, &_m, &two_128, ctx);
+ if (!BN_is_zero(&tmp)) { BN_sub(&tmp, &two_128, &tmp); }
+ if (!bn_extract_to_array_512(&tmp, 2, &data->k1[0])) {
+ goto err; }
+
+ /* Precompute t */
+ for (i=0; i<8; i++) {
+ BN_zero(&tmp);
+ if (i & 1) { BN_add(&tmp, &two_512, &tmp); }
+ if (i & 2) { BN_add(&tmp, &two_512, &tmp); }
+ if (i & 4) { BN_add(&tmp, &two_640, &tmp); }
+
+ BN_nnmod(&tmp2, &tmp, &_m, ctx);
+ if (!bn_extract_to_array_512(&tmp2, 8, _t)) {
+ goto err; }
+ for (j=0; j<8; j++) data->t[j][i] = _t[j]; }
+
+ /* Precompute m */
+ for (i=0; i<8; i++) {
+ data->m[i] = m[i]; }
+
+ ret = 1;
+
+err:
+ /* Cleanup */
+ if (ctx != NULL) {
+ BN_CTX_end(ctx); BN_CTX_free(ctx); }
+ BN_free(&two_768);
+ BN_free(&two_640);
+ BN_free(&two_128);
+ BN_free(&two_512);
+ BN_free(&tmp);
+ BN_free(&tmp2);
+ BN_free(&_m);
+
+ return ret;
+}
+
+
+static int e_rsax_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+ {
+ BIGNUM *r1,*m1,*vrfy;
+ BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
+ BIGNUM *dmp1,*dmq1,*c,*pr1;
+ int ret=0;
+
+ BN_CTX_start(ctx);
+ r1 = BN_CTX_get(ctx);
+ m1 = BN_CTX_get(ctx);
+ vrfy = BN_CTX_get(ctx);
+
+ {
+ BIGNUM local_p, local_q;
+ BIGNUM *p = NULL, *q = NULL;
+ int error = 0;
+
+ /* Make sure BN_mod_inverse in Montgomery
+ * intialization uses the BN_FLG_CONSTTIME flag
+ * (unless RSA_FLAG_NO_CONSTTIME is set)
+ */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ BN_init(&local_p);
+ p = &local_p;
+ BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+
+ BN_init(&local_q);
+ q = &local_q;
+ BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
+ }
+ else
+ {
+ p = rsa->p;
+ q = rsa->q;
+ }
+
+ if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
+ {
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
+ error = 1;
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
+ error = 1;
+ }
+
+ /* clean up */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ BN_free(&local_p);
+ BN_free(&local_q);
+ }
+ if ( error )
+ goto err;
+ }
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ goto err;
+
+ /* compute I mod q */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ c = &local_c;
+ BN_with_flags(c, I, BN_FLG_CONSTTIME);
+ if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
+ }
+
+ /* compute r1^dmq1 mod q */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ dmq1 = &local_dmq1;
+ BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
+ }
+ else
+ dmq1 = rsa->dmq1;
+
+ if (!e_rsax_bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
+ rsa->_method_mod_q, e_rsax_get_ctx(rsa, 0, rsa->q) )) goto err;
+
+ /* compute I mod p */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ c = &local_c;
+ BN_with_flags(c, I, BN_FLG_CONSTTIME);
+ if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
+ }
+
+ /* compute r1^dmp1 mod p */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ dmp1 = &local_dmp1;
+ BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
+ }
+ else
+ dmp1 = rsa->dmp1;
+
+ if (!e_rsax_bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
+ rsa->_method_mod_p, e_rsax_get_ctx(rsa, 1, rsa->p) )) goto err;
+
+ if (!BN_sub(r0,r0,m1)) goto err;
+ /* This will help stop the size of r0 increasing, which does
+ * affect the multiply if it optimised for a power of 2 size */
+ if (BN_is_negative(r0))
+ if (!BN_add(r0,r0,rsa->p)) goto err;
+
+ if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
+
+ /* Turn BN_FLG_CONSTTIME flag on before division operation */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ pr1 = &local_r1;
+ BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
+ }
+ else
+ pr1 = r1;
+ if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
+
+ /* If p < q it is occasionally possible for the correction of
+ * adding 'p' if r0 is negative above to leave the result still
+ * negative. This can break the private key operations: the following
+ * second correction should *always* correct this rare occurrence.
+ * This will *never* happen with OpenSSL generated keys because
+ * they ensure p > q [steve]
+ */
+ if (BN_is_negative(r0))
+ if (!BN_add(r0,r0,rsa->p)) goto err;
+ if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
+ if (!BN_add(r0,r1,m1)) goto err;
+
+ if (rsa->e && rsa->n)
+ {
+ if (!e_rsax_bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n, e_rsax_get_ctx(rsa, 2, rsa->n) ))
+ goto err;
+
+ /* If 'I' was greater than (or equal to) rsa->n, the operation
+ * will be equivalent to using 'I mod n'. However, the result of
+ * the verify will *always* be less than 'n' so we don't check
+ * for absolute equality, just congruency. */
+ if (!BN_sub(vrfy, vrfy, I)) goto err;
+ if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
+ if (BN_is_negative(vrfy))
+ if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
+ if (!BN_is_zero(vrfy))
+ {
+ /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
+ * miscalculated CRT output, just do a raw (slower)
+ * mod_exp and return that instead. */
+
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+ }
+ else
+ d = rsa->d;
+ if (!e_rsax_bn_mod_exp(r0,I,d,rsa->n,ctx,
+ rsa->_method_mod_n, e_rsax_get_ctx(rsa, 2, rsa->n) )) goto err;
+ }
+ }
+ ret=1;
+
+err:
+ BN_CTX_end(ctx);
+
+ return ret;
+ }
+#endif /* !OPENSSL_NO_RSA */
+#endif /* !COMPILE_RSAX */
diff --git a/deps/openssl/openssl/crypto/engine/engine.h b/deps/openssl/openssl/crypto/engine/engine.h
index 943aeae21..f8be49772 100644
--- a/deps/openssl/openssl/crypto/engine/engine.h
+++ b/deps/openssl/openssl/crypto/engine/engine.h
@@ -141,6 +141,13 @@ extern "C" {
* the existing ENGINE's structural reference count. */
#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004
+/* This flag if for an ENGINE that does not want its methods registered as
+ * part of ENGINE_register_all_complete() for example if the methods are
+ * not usable as default methods.
+ */
+
+#define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008
+
/* ENGINEs can support their own command types, and these flags are used in
* ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
* command expects. Currently only numeric and string input is supported. If a
@@ -344,6 +351,8 @@ void ENGINE_load_gost(void);
#endif
#endif
void ENGINE_load_cryptodev(void);
+void ENGINE_load_rsax(void);
+void ENGINE_load_rdrand(void);
void ENGINE_load_builtin_engines(void);
/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
diff --git a/deps/openssl/openssl/crypto/err/err.c b/deps/openssl/openssl/crypto/err/err.c
index 69713a6e2..fcdb24400 100644
--- a/deps/openssl/openssl/crypto/err/err.c
+++ b/deps/openssl/openssl/crypto/err/err.c
@@ -1066,6 +1066,13 @@ void ERR_set_error_data(char *data, int flags)
void ERR_add_error_data(int num, ...)
{
va_list args;
+ va_start(args, num);
+ ERR_add_error_vdata(num, args);
+ va_end(args);
+ }
+
+void ERR_add_error_vdata(int num, va_list args)
+ {
int i,n,s;
char *str,*p,*a;
@@ -1074,7 +1081,6 @@ void ERR_add_error_data(int num, ...)
if (str == NULL) return;
str[0]='\0';
- va_start(args, num);
n=0;
for (i=0; i<num; i++)
{
@@ -1090,7 +1096,7 @@ void ERR_add_error_data(int num, ...)
if (p == NULL)
{
OPENSSL_free(str);
- goto err;
+ return;
}
else
str=p;
@@ -1099,9 +1105,6 @@ void ERR_add_error_data(int num, ...)
}
}
ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
-
-err:
- va_end(args);
}
int ERR_set_mark(void)
diff --git a/deps/openssl/openssl/crypto/err/err.h b/deps/openssl/openssl/crypto/err/err.h
index b9f8c16d4..974cc9cc6 100644
--- a/deps/openssl/openssl/crypto/err/err.h
+++ b/deps/openssl/openssl/crypto/err/err.h
@@ -344,8 +344,9 @@ void ERR_print_errors_fp(FILE *fp);
#endif
#ifndef OPENSSL_NO_BIO
void ERR_print_errors(BIO *bp);
-void ERR_add_error_data(int num, ...);
#endif
+void ERR_add_error_data(int num, ...);
+void ERR_add_error_vdata(int num, va_list args);
void ERR_load_strings(int lib,ERR_STRING_DATA str[]);
void ERR_unload_strings(int lib,ERR_STRING_DATA str[]);
void ERR_load_ERR_strings(void);
diff --git a/deps/openssl/openssl/crypto/err/err_all.c b/deps/openssl/openssl/crypto/err/err_all.c
index fc049e8e8..8eb547d98 100644
--- a/deps/openssl/openssl/crypto/err/err_all.c
+++ b/deps/openssl/openssl/crypto/err/err_all.c
@@ -64,7 +64,9 @@
#endif
#include <openssl/buffer.h>
#include <openssl/bio.h>
+#ifndef OPENSSL_NO_COMP
#include <openssl/comp.h>
+#endif
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
@@ -95,6 +97,9 @@
#include <openssl/ui.h>
#include <openssl/ocsp.h>
#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
#include <openssl/ts.h>
#ifndef OPENSSL_NO_CMS
#include <openssl/cms.h>
@@ -102,7 +107,6 @@
#ifndef OPENSSL_NO_JPAKE
#include <openssl/jpake.h>
#endif
-#include <openssl/comp.h>
void ERR_load_crypto_strings(void)
{
@@ -126,7 +130,9 @@ void ERR_load_crypto_strings(void)
ERR_load_ASN1_strings();
ERR_load_CONF_strings();
ERR_load_CRYPTO_strings();
+#ifndef OPENSSL_NO_COMP
ERR_load_COMP_strings();
+#endif
#ifndef OPENSSL_NO_EC
ERR_load_EC_strings();
#endif
@@ -149,12 +155,14 @@ void ERR_load_crypto_strings(void)
#endif
ERR_load_OCSP_strings();
ERR_load_UI_strings();
+#ifdef OPENSSL_FIPS
+ ERR_load_FIPS_strings();
+#endif
#ifndef OPENSSL_NO_CMS
ERR_load_CMS_strings();
#endif
#ifndef OPENSSL_NO_JPAKE
ERR_load_JPAKE_strings();
#endif
- ERR_load_COMP_strings();
#endif
}
diff --git a/deps/openssl/openssl/crypto/evp/Makefile b/deps/openssl/openssl/crypto/evp/Makefile
index 82825e529..1e46cebf5 100644
--- a/deps/openssl/openssl/crypto/evp/Makefile
+++ b/deps/openssl/openssl/crypto/evp/Makefile
@@ -18,7 +18,7 @@ TESTDATA=evptests.txt
APPS=
LIB=$(TOP)/libcrypto.a
-LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c \
+LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c evp_cnf.c \
e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
e_rc4.c e_aes.c names.c e_seed.c \
e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
@@ -28,9 +28,10 @@ LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c \
bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
c_all.c c_allc.c c_alld.c evp_lib.c bio_ok.c \
evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \
- e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c
+ e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c evp_fips.c \
+ e_aes_cbc_hmac_sha1.c e_rc4_hmac_md5.c
-LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o \
+LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o evp_cnf.o \
e_des.o e_bf.o e_idea.o e_des3.o e_camellia.o\
e_rc4.o e_aes.o names.o e_seed.o \
e_xcbc_d.o e_rc2.o e_cast.o e_rc5.o \
@@ -40,7 +41,8 @@ LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o \
bio_md.o bio_b64.o bio_enc.o evp_err.o e_null.o \
c_all.o c_allc.o c_alld.o evp_lib.o bio_ok.o \
evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o \
- e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o
+ e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o evp_fips.o \
+ e_aes_cbc_hmac_sha1.o e_rc4_hmac_md5.o
SRC= $(LIBSRC)
@@ -65,7 +67,7 @@ files:
links:
@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
- cp $(TESTDATA) ../../test
+ [ ! -f $(TESTDATA) ] || cp $(TESTDATA) ../../test
@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
install:
@@ -189,11 +191,27 @@ e_aes.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
e_aes.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
e_aes.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
e_aes.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-e_aes.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-e_aes.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-e_aes.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-e_aes.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h e_aes.c
-e_aes.o: evp_locl.h
+e_aes.o: ../../include/openssl/modes.h ../../include/openssl/obj_mac.h
+e_aes.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_aes.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_aes.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+e_aes.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_aes.o: ../modes/modes_lcl.h e_aes.c evp_locl.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/bio.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/crypto.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/e_os2.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/evp.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/obj_mac.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/objects.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/opensslconf.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/opensslv.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/ossl_typ.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/safestack.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/sha.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/stack.h
+e_aes_cbc_hmac_sha1.o: ../../include/openssl/symhacks.h e_aes_cbc_hmac_sha1.c
+e_aes_cbc_hmac_sha1.o: evp_locl.h
e_bf.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
e_bf.o: ../../include/openssl/blowfish.h ../../include/openssl/buffer.h
e_bf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -279,7 +297,18 @@ e_rc4.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
e_rc4.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
e_rc4.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc4.h
e_rc4.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_rc4.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc4.c
+e_rc4.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc4.c evp_locl.h
+e_rc4_hmac_md5.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_rc4_hmac_md5.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+e_rc4_hmac_md5.o: ../../include/openssl/evp.h ../../include/openssl/md5.h
+e_rc4_hmac_md5.o: ../../include/openssl/obj_mac.h
+e_rc4_hmac_md5.o: ../../include/openssl/objects.h
+e_rc4_hmac_md5.o: ../../include/openssl/opensslconf.h
+e_rc4_hmac_md5.o: ../../include/openssl/opensslv.h
+e_rc4_hmac_md5.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc4.h
+e_rc4_hmac_md5.o: ../../include/openssl/safestack.h
+e_rc4_hmac_md5.o: ../../include/openssl/stack.h
+e_rc4_hmac_md5.o: ../../include/openssl/symhacks.h e_rc4_hmac_md5.c
e_rc5.o: ../../e_os.h ../../include/openssl/bio.h
e_rc5.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
e_rc5.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -327,6 +356,20 @@ evp_acnf.o: ../../include/openssl/opensslconf.h
evp_acnf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
evp_acnf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
evp_acnf.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_acnf.c
+evp_cnf.o: ../../e_os.h ../../include/openssl/asn1.h
+evp_cnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+evp_cnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+evp_cnf.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+evp_cnf.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+evp_cnf.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+evp_cnf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+evp_cnf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+evp_cnf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+evp_cnf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+evp_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+evp_cnf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+evp_cnf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+evp_cnf.o: ../../include/openssl/x509v3.h ../cryptlib.h evp_cnf.c
evp_enc.o: ../../e_os.h ../../include/openssl/asn1.h
evp_enc.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
evp_enc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -349,6 +392,13 @@ evp_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
evp_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
evp_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
evp_err.o: ../../include/openssl/symhacks.h evp_err.c
+evp_fips.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+evp_fips.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+evp_fips.o: ../../include/openssl/evp.h ../../include/openssl/obj_mac.h
+evp_fips.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+evp_fips.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+evp_fips.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+evp_fips.o: ../../include/openssl/symhacks.h evp_fips.c
evp_key.o: ../../e_os.h ../../include/openssl/asn1.h
evp_key.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
evp_key.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -383,7 +433,7 @@ evp_pbe.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
evp_pbe.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
evp_pbe.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
evp_pbe.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-evp_pbe.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_pbe.c
+evp_pbe.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h evp_pbe.c
evp_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
evp_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
evp_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -401,28 +451,22 @@ evp_pkey.o: ../asn1/asn1_locl.h ../cryptlib.h evp_pkey.c
m_dss.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
m_dss.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
m_dss.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-m_dss.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-m_dss.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-m_dss.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-m_dss.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-m_dss.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-m_dss.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_dss.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+m_dss.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+m_dss.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_dss.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
m_dss.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
m_dss.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-m_dss.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
m_dss.o: ../cryptlib.h m_dss.c
m_dss1.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
m_dss1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
m_dss1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-m_dss1.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-m_dss1.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-m_dss1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-m_dss1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-m_dss1.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-m_dss1.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_dss1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+m_dss1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+m_dss1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_dss1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
m_dss1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
m_dss1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-m_dss1.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
m_dss1.o: ../cryptlib.h m_dss1.c
m_ecdsa.o: ../../e_os.h ../../include/openssl/asn1.h
m_ecdsa.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
@@ -456,7 +500,7 @@ m_md4.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
m_md4.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
m_md4.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
m_md4.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-m_md4.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_md4.c
+m_md4.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h m_md4.c
m_md5.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
m_md5.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
m_md5.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -469,7 +513,7 @@ m_md5.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
m_md5.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
m_md5.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
m_md5.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-m_md5.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_md5.c
+m_md5.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h m_md5.c
m_mdc2.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
m_mdc2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
m_mdc2.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
@@ -484,7 +528,7 @@ m_mdc2.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
m_mdc2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
m_mdc2.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
m_mdc2.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
-m_mdc2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_mdc2.c
+m_mdc2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h m_mdc2.c
m_null.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
m_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
m_null.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -510,7 +554,8 @@ m_ripemd.o: ../../include/openssl/pkcs7.h ../../include/openssl/ripemd.h
m_ripemd.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
m_ripemd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
m_ripemd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-m_ripemd.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_ripemd.c
+m_ripemd.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h
+m_ripemd.o: m_ripemd.c
m_sha.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
m_sha.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
m_sha.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -523,19 +568,16 @@ m_sha.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
m_sha.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
m_sha.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
m_sha.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-m_sha.o: ../cryptlib.h m_sha.c
+m_sha.o: ../cryptlib.h evp_locl.h m_sha.c
m_sha1.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
m_sha1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-m_sha1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-m_sha1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-m_sha1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-m_sha1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-m_sha1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-m_sha1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-m_sha1.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+m_sha1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+m_sha1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+m_sha1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_sha1.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_sha1.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
m_sha1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
m_sha1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-m_sha1.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
m_sha1.o: ../cryptlib.h m_sha1.c
m_sigver.o: ../../e_os.h ../../include/openssl/asn1.h
m_sigver.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
@@ -563,7 +605,7 @@ m_wp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
m_wp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
m_wp.o: ../../include/openssl/symhacks.h ../../include/openssl/whrlpool.h
m_wp.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-m_wp.o: ../cryptlib.h m_wp.c
+m_wp.o: ../cryptlib.h evp_locl.h m_wp.c
names.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
names.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
names.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -601,7 +643,8 @@ p5_crpt2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
p5_crpt2.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
p5_crpt2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
p5_crpt2.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p5_crpt2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p5_crpt2.c
+p5_crpt2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h
+p5_crpt2.o: p5_crpt2.c
p_dec.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
p_dec.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
p_dec.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
diff --git a/deps/openssl/openssl/crypto/evp/bio_md.c b/deps/openssl/openssl/crypto/evp/bio_md.c
index 9841e32e1..144fdfd56 100644
--- a/deps/openssl/openssl/crypto/evp/bio_md.c
+++ b/deps/openssl/openssl/crypto/evp/bio_md.c
@@ -153,8 +153,12 @@ static int md_write(BIO *b, const char *in, int inl)
{
if (ret > 0)
{
- EVP_DigestUpdate(ctx,(const unsigned char *)in,
- (unsigned int)ret);
+ if (!EVP_DigestUpdate(ctx,(const unsigned char *)in,
+ (unsigned int)ret))
+ {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
}
}
if(b->next_bio != NULL)
@@ -220,7 +224,8 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_CTRL_DUP:
dbio=ptr;
dctx=dbio->ptr;
- EVP_MD_CTX_copy_ex(dctx,ctx);
+ if (!EVP_MD_CTX_copy_ex(dctx,ctx))
+ return 0;
b->init=1;
break;
default:
diff --git a/deps/openssl/openssl/crypto/evp/bio_ok.c b/deps/openssl/openssl/crypto/evp/bio_ok.c
index 98bc1ab40..e64335353 100644
--- a/deps/openssl/openssl/crypto/evp/bio_ok.c
+++ b/deps/openssl/openssl/crypto/evp/bio_ok.c
@@ -133,10 +133,10 @@ static int ok_new(BIO *h);
static int ok_free(BIO *data);
static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-static void sig_out(BIO* b);
-static void sig_in(BIO* b);
-static void block_out(BIO* b);
-static void block_in(BIO* b);
+static int sig_out(BIO* b);
+static int sig_in(BIO* b);
+static int block_out(BIO* b);
+static int block_in(BIO* b);
#define OK_BLOCK_SIZE (1024*4)
#define OK_BLOCK_BLOCK 4
#define IOBS (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
@@ -266,10 +266,24 @@ static int ok_read(BIO *b, char *out, int outl)
ctx->buf_len+= i;
/* no signature yet -- check if we got one */
- if (ctx->sigio == 1) sig_in(b);
+ if (ctx->sigio == 1)
+ {
+ if (!sig_in(b))
+ {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
/* signature ok -- check if we got block */
- if (ctx->sigio == 0) block_in(b);
+ if (ctx->sigio == 0)
+ {
+ if (!block_in(b))
+ {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
/* invalid block -- cancel */
if (ctx->cont <= 0) break;
@@ -293,7 +307,8 @@ static int ok_write(BIO *b, const char *in, int inl)
if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);
- if(ctx->sigio) sig_out(b);
+ if(ctx->sigio && !sig_out(b))
+ return 0;
do{
BIO_clear_retry_flags(b);
@@ -332,7 +347,11 @@ static int ok_write(BIO *b, const char *in, int inl)
if(ctx->buf_len >= OK_BLOCK_SIZE+ OK_BLOCK_BLOCK)
{
- block_out(b);
+ if (!block_out(b))
+ {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
}
}while(inl > 0);
@@ -379,7 +398,8 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_CTRL_FLUSH:
/* do a final write */
if(ctx->blockout == 0)
- block_out(b);
+ if (!block_out(b))
+ return 0;
while (ctx->blockout)
{
@@ -408,7 +428,8 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
case BIO_C_SET_MD:
md=ptr;
- EVP_DigestInit_ex(&ctx->md, md, NULL);
+ if (!EVP_DigestInit_ex(&ctx->md, md, NULL))
+ return 0;
b->init=1;
break;
case BIO_C_GET_MD:
@@ -455,7 +476,7 @@ static void longswap(void *_ptr, size_t len)
}
}
-static void sig_out(BIO* b)
+static int sig_out(BIO* b)
{
BIO_OK_CTX *ctx;
EVP_MD_CTX *md;
@@ -463,9 +484,10 @@ static void sig_out(BIO* b)
ctx=b->ptr;
md=&ctx->md;
- if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return;
+ if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return 1;
- EVP_DigestInit_ex(md, md->digest, NULL);
+ if (!EVP_DigestInit_ex(md, md->digest, NULL))
+ goto berr;
/* FIXME: there's absolutely no guarantee this makes any sense at all,
* particularly now EVP_MD_CTX has been restructured.
*/
@@ -474,14 +496,20 @@ static void sig_out(BIO* b)
longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
ctx->buf_len+= md->digest->md_size;
- EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
- EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
+ if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
+ goto berr;
ctx->buf_len+= md->digest->md_size;
ctx->blockout= 1;
ctx->sigio= 0;
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
}
-static void sig_in(BIO* b)
+static int sig_in(BIO* b)
{
BIO_OK_CTX *ctx;
EVP_MD_CTX *md;
@@ -491,15 +519,18 @@ static void sig_in(BIO* b)
ctx=b->ptr;
md=&ctx->md;
- if((int)(ctx->buf_len-ctx->buf_off) < 2*md->digest->md_size) return;
+ if((int)(ctx->buf_len-ctx->buf_off) < 2*md->digest->md_size) return 1;
- EVP_DigestInit_ex(md, md->digest, NULL);
+ if (!EVP_DigestInit_ex(md, md->digest, NULL))
+ goto berr;
memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
longswap(md->md_data, md->digest->md_size);
ctx->buf_off+= md->digest->md_size;
- EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
- EVP_DigestFinal_ex(md, tmp, NULL);
+ if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, tmp, NULL))
+ goto berr;
ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
ctx->buf_off+= md->digest->md_size;
if(ret == 1)
@@ -516,9 +547,13 @@ static void sig_in(BIO* b)
{
ctx->cont= 0;
}
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
}
-static void block_out(BIO* b)
+static int block_out(BIO* b)
{
BIO_OK_CTX *ctx;
EVP_MD_CTX *md;
@@ -532,13 +567,20 @@ static void block_out(BIO* b)
ctx->buf[1]=(unsigned char)(tl>>16);
ctx->buf[2]=(unsigned char)(tl>>8);
ctx->buf[3]=(unsigned char)(tl);
- EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
- EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
+ if (!EVP_DigestUpdate(md,
+ (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
+ goto berr;
ctx->buf_len+= md->digest->md_size;
ctx->blockout= 1;
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
}
-static void block_in(BIO* b)
+static int block_in(BIO* b)
{
BIO_OK_CTX *ctx;
EVP_MD_CTX *md;
@@ -554,10 +596,13 @@ static void block_in(BIO* b)
tl|=ctx->buf[2]; tl<<=8;
tl|=ctx->buf[3];
- if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return;
+ if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return 1;
- EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
- EVP_DigestFinal_ex(md, tmp, NULL);
+ if (!EVP_DigestUpdate(md,
+ (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, tmp, NULL))
+ goto berr;
if(memcmp(&(ctx->buf[tl+ OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == 0)
{
/* there might be parts from next block lurking around ! */
@@ -571,5 +616,9 @@ static void block_in(BIO* b)
{
ctx->cont= 0;
}
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
}
diff --git a/deps/openssl/openssl/crypto/evp/c_allc.c b/deps/openssl/openssl/crypto/evp/c_allc.c
index c5f926837..2a45d435e 100644
--- a/deps/openssl/openssl/crypto/evp/c_allc.c
+++ b/deps/openssl/openssl/crypto/evp/c_allc.c
@@ -98,6 +98,9 @@ void OpenSSL_add_all_ciphers(void)
#ifndef OPENSSL_NO_RC4
EVP_add_cipher(EVP_rc4());
EVP_add_cipher(EVP_rc4_40());
+#ifndef OPENSSL_NO_MD5
+ EVP_add_cipher(EVP_rc4_hmac_md5());
+#endif
#endif
#ifndef OPENSSL_NO_IDEA
@@ -166,9 +169,9 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_128_cfb1());
EVP_add_cipher(EVP_aes_128_cfb8());
EVP_add_cipher(EVP_aes_128_ofb());
-#if 0
EVP_add_cipher(EVP_aes_128_ctr());
-#endif
+ EVP_add_cipher(EVP_aes_128_gcm());
+ EVP_add_cipher(EVP_aes_128_xts());
EVP_add_cipher_alias(SN_aes_128_cbc,"AES128");
EVP_add_cipher_alias(SN_aes_128_cbc,"aes128");
EVP_add_cipher(EVP_aes_192_ecb());
@@ -177,9 +180,8 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_192_cfb1());
EVP_add_cipher(EVP_aes_192_cfb8());
EVP_add_cipher(EVP_aes_192_ofb());
-#if 0
EVP_add_cipher(EVP_aes_192_ctr());
-#endif
+ EVP_add_cipher(EVP_aes_192_gcm());
EVP_add_cipher_alias(SN_aes_192_cbc,"AES192");
EVP_add_cipher_alias(SN_aes_192_cbc,"aes192");
EVP_add_cipher(EVP_aes_256_ecb());
@@ -188,11 +190,15 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_256_cfb1());
EVP_add_cipher(EVP_aes_256_cfb8());
EVP_add_cipher(EVP_aes_256_ofb());
-#if 0
EVP_add_cipher(EVP_aes_256_ctr());
-#endif
+ EVP_add_cipher(EVP_aes_256_gcm());
+ EVP_add_cipher(EVP_aes_256_xts());
EVP_add_cipher_alias(SN_aes_256_cbc,"AES256");
EVP_add_cipher_alias(SN_aes_256_cbc,"aes256");
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+ EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
+ EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
+#endif
#endif
#ifndef OPENSSL_NO_CAMELLIA
diff --git a/deps/openssl/openssl/crypto/evp/digest.c b/deps/openssl/openssl/crypto/evp/digest.c
index 982ba2b13..6fc469f9c 100644
--- a/deps/openssl/openssl/crypto/evp/digest.c
+++ b/deps/openssl/openssl/crypto/evp/digest.c
@@ -117,6 +117,10 @@
#include <openssl/engine.h>
#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
{
memset(ctx,'\0',sizeof *ctx);
@@ -225,12 +229,26 @@ skip_to_init:
}
if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
return 1;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ {
+ if (FIPS_digestinit(ctx, type))
+ return 1;
+ OPENSSL_free(ctx->md_data);
+ ctx->md_data = NULL;
+ return 0;
+ }
+#endif
return ctx->digest->init(ctx);
}
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
{
+#ifdef OPENSSL_FIPS
+ return FIPS_digestupdate(ctx, data, count);
+#else
return ctx->update(ctx,data,count);
+#endif
}
/* The caller can assume that this removes any secret data from the context */
@@ -245,6 +263,9 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
/* The caller can assume that this removes any secret data from the context */
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
{
+#ifdef OPENSSL_FIPS
+ return FIPS_digestfinal(ctx, md, size);
+#else
int ret;
OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
@@ -258,6 +279,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
}
memset(ctx->md_data,0,ctx->digest->ctx_size);
return ret;
+#endif
}
int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
@@ -351,6 +373,7 @@ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
/* This call frees resources associated with the context */
int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
{
+#ifndef OPENSSL_FIPS
/* Don't assume ctx->md_data was cleaned in EVP_Digest_Final,
* because sometimes only copies of the context are ever finalised.
*/
@@ -363,6 +386,7 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
OPENSSL_free(ctx->md_data);
}
+#endif
if (ctx->pctx)
EVP_PKEY_CTX_free(ctx->pctx);
#ifndef OPENSSL_NO_ENGINE
@@ -371,6 +395,9 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
* functional reference we held for this reason. */
ENGINE_finish(ctx->engine);
#endif
+#ifdef OPENSSL_FIPS
+ FIPS_md_ctx_cleanup(ctx);
+#endif
memset(ctx,'\0',sizeof *ctx);
return 1;
diff --git a/deps/openssl/openssl/crypto/evp/e_aes.c b/deps/openssl/openssl/crypto/evp/e_aes.c
index bd6c0a3a6..1bfb5d92b 100644
--- a/deps/openssl/openssl/crypto/evp/e_aes.c
+++ b/deps/openssl/openssl/crypto/evp/e_aes.c
@@ -1,5 +1,5 @@
/* ====================================================================
- * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2001-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
@@ -56,57 +56,511 @@
#include <assert.h>
#include <openssl/aes.h>
#include "evp_locl.h"
-
-static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc);
+#ifndef OPENSSL_FIPS
+#include "modes_lcl.h"
+#include <openssl/rand.h>
typedef struct
{
AES_KEY ks;
+ block128_f block;
+ union {
+ cbc128_f cbc;
+ ctr128_f ctr;
+ } stream;
} EVP_AES_KEY;
-#define data(ctx) EVP_C_DATA(EVP_AES_KEY,ctx)
-
-IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY,
- NID_aes_128, 16, 16, 16, 128,
- 0, aes_init_key, NULL,
- EVP_CIPHER_set_asn1_iv,
- EVP_CIPHER_get_asn1_iv,
- NULL)
-IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY,
- NID_aes_192, 16, 24, 16, 128,
- 0, aes_init_key, NULL,
- EVP_CIPHER_set_asn1_iv,
- EVP_CIPHER_get_asn1_iv,
- NULL)
-IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY,
- NID_aes_256, 16, 32, 16, 128,
- 0, aes_init_key, NULL,
- EVP_CIPHER_set_asn1_iv,
- EVP_CIPHER_get_asn1_iv,
- NULL)
-
-#define IMPLEMENT_AES_CFBR(ksize,cbits) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16)
-
-IMPLEMENT_AES_CFBR(128,1)
-IMPLEMENT_AES_CFBR(192,1)
-IMPLEMENT_AES_CFBR(256,1)
-
-IMPLEMENT_AES_CFBR(128,8)
-IMPLEMENT_AES_CFBR(192,8)
-IMPLEMENT_AES_CFBR(256,8)
+typedef struct
+ {
+ AES_KEY ks; /* AES key schedule to use */
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ GCM128_CONTEXT gcm;
+ unsigned char *iv; /* Temporary IV store */
+ int ivlen; /* IV length */
+ int taglen;
+ int iv_gen; /* It is OK to generate IVs */
+ int tls_aad_len; /* TLS AAD length */
+ ctr128_f ctr;
+ } EVP_AES_GCM_CTX;
+
+typedef struct
+ {
+ AES_KEY ks1, ks2; /* AES key schedules to use */
+ XTS128_CONTEXT xts;
+ void (*stream)(const unsigned char *in,
+ unsigned char *out, size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+ } EVP_AES_XTS_CTX;
+
+typedef struct
+ {
+ AES_KEY ks; /* AES key schedule to use */
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ int tag_set; /* Set if tag is valid */
+ int len_set; /* Set if message length set */
+ int L, M; /* L and M parameters from RFC3610 */
+ CCM128_CONTEXT ccm;
+ ccm128_f str;
+ } EVP_AES_CCM_CTX;
+
+#define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4))
+
+#ifdef VPAES_ASM
+int vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void vpaes_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void vpaes_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+
+void vpaes_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key,
+ unsigned char *ivec, int enc);
+#endif
+#ifdef BSAES_ASM
+void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char ivec[16], int enc);
+void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ const unsigned char ivec[16]);
+void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
+ size_t len, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char iv[16]);
+void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
+ size_t len, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char iv[16]);
+#endif
+#ifdef AES_CTR_ASM
+void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key,
+ const unsigned char ivec[AES_BLOCK_SIZE]);
+#endif
+#ifdef AES_XTS_ASM
+void AES_xts_encrypt(const char *inp,char *out,size_t len,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+void AES_xts_decrypt(const char *inp,char *out,size_t len,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+#endif
+
+#if defined(AES_ASM) && !defined(I386_ONLY) && ( \
+ ((defined(__i386) || defined(__i386__) || \
+ defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) )
+
+extern unsigned int OPENSSL_ia32cap_P[2];
+
+#ifdef VPAES_ASM
+#define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
+#endif
+#ifdef BSAES_ASM
+#define BSAES_CAPABLE VPAES_CAPABLE
+#endif
+/*
+ * AES-NI section
+ */
+#define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32)))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void aesni_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void aesni_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+
+void aesni_ecb_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key,
+ int enc);
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key,
+ unsigned char *ivec, int enc);
+
+void aesni_ctr32_encrypt_blocks(const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key,
+ const unsigned char *ivec);
+
+void aesni_xts_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+
+void aesni_xts_decrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+
+void aesni_ccm64_encrypt_blocks (const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key,
+ const unsigned char ivec[16],
+ unsigned char cmac[16]);
+
+void aesni_ccm64_decrypt_blocks (const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key,
+ const unsigned char ivec[16],
+ unsigned char cmac[16]);
+
+static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ int ret, mode;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc)
+ {
+ ret = aesni_set_decrypt_key(key, ctx->key_len*8, ctx->cipher_data);
+ dat->block = (block128_f)aesni_decrypt;
+ dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
+ (cbc128_f)aesni_cbc_encrypt :
+ NULL;
+ }
+ else {
+ ret = aesni_set_encrypt_key(key, ctx->key_len*8, ctx->cipher_data);
+ dat->block = (block128_f)aesni_encrypt;
+ if (mode==EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f)aesni_cbc_encrypt;
+ else if (mode==EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
+ else
+ dat->stream.cbc = NULL;
+ }
+
+ if(ret < 0)
+ {
+ EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+ }
+
+static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ aesni_cbc_encrypt(in,out,len,ctx->cipher_data,ctx->iv,ctx->encrypt);
+
+ return 1;
+}
+
+static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ size_t bl = ctx->cipher->block_size;
+
+ if (len<bl) return 1;
+
+ aesni_ecb_encrypt(in,out,len,ctx->cipher_data,ctx->encrypt);
+
+ return 1;
+}
+
+#define aesni_ofb_cipher aes_ofb_cipher
+static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len);
+
+#define aesni_cfb_cipher aes_cfb_cipher
+static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len);
+
+#define aesni_cfb8_cipher aes_cfb8_cipher
+static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len);
+
+#define aesni_cfb1_cipher aes_cfb1_cipher
+static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len);
+
+#define aesni_ctr_cipher aes_ctr_cipher
+static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key)
+ {
+ aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f)aesni_encrypt);
+ gctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
+ /* If we have an iv can set it directly, otherwise use
+ * saved IV.
+ */
+ if (iv == NULL && gctx->iv_set)
+ iv = gctx->iv;
+ if (iv)
+ {
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ }
+ else
+ {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ else
+ memcpy(gctx->iv, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ gctx->iv_gen = 0;
+ }
+ return 1;
+ }
+
+#define aesni_gcm_cipher aes_gcm_cipher
+static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+
+ if (key)
+ {
+ /* key_len is two AES keys */
+ if (enc)
+ {
+ aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)aesni_encrypt;
+ xctx->stream = aesni_xts_encrypt;
+ }
+ else
+ {
+ aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)aesni_decrypt;
+ xctx->stream = aesni_xts_decrypt;
+ }
+
+ aesni_set_encrypt_key(key + ctx->key_len/2,
+ ctx->key_len * 4, &xctx->ks2);
+ xctx->xts.block2 = (block128_f)aesni_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ }
+
+ if (iv)
+ {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+ }
+
+#define aesni_xts_cipher aes_xts_cipher
+static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key)
+ {
+ aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f)aesni_encrypt);
+ cctx->str = enc?(ccm128_f)aesni_ccm64_encrypt_blocks :
+ (ccm128_f)aesni_ccm64_decrypt_blocks;
+ cctx->key_set = 1;
+ }
+ if (iv)
+ {
+ memcpy(ctx->iv, iv, 15 - cctx->L);
+ cctx->iv_set = 1;
+ }
+ return 1;
+ }
+
+#define aesni_ccm_cipher aes_ccm_cipher
+static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aesni_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aesni_init_key, \
+ aesni_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize, \
+ keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_init_key, \
+ aes_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aesni_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aesni_##mode##_init_key, \
+ aesni_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_##mode##_init_key, \
+ aes_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+#else
+
+#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_init_key, \
+ aes_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return &aes_##keylen##_##mode; }
+
+#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_##mode##_init_key, \
+ aes_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return &aes_##keylen##_##mode; }
+#endif
+
+#define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
- int ret;
+ int ret, mode;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
- if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE
- || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE
- || enc)
- ret=AES_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc)
+#ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE && mode==EVP_CIPH_CBC_MODE)
+ {
+ ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)AES_decrypt;
+ dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt;
+ }
+ else
+#endif
+#ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE)
+ {
+ ret = vpaes_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)vpaes_decrypt;
+ dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
+ (cbc128_f)vpaes_cbc_encrypt :
+ NULL;
+ }
+ else
+#endif
+ {
+ ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)AES_decrypt;
+ dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
+ (cbc128_f)AES_cbc_encrypt :
+ NULL;
+ }
else
- ret=AES_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+#ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE && mode==EVP_CIPH_CTR_MODE)
+ {
+ ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)AES_encrypt;
+ dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
+ }
+ else
+#endif
+#ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE)
+ {
+ ret = vpaes_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)vpaes_encrypt;
+ dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
+ (cbc128_f)vpaes_cbc_encrypt :
+ NULL;
+ }
+ else
+#endif
+ {
+ ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)AES_encrypt;
+ dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
+ (cbc128_f)AES_cbc_encrypt :
+ NULL;
+#ifdef AES_CTR_ASM
+ if (mode==EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt;
+#endif
+ }
if(ret < 0)
{
@@ -117,4 +571,744 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
return 1;
}
+static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ if (dat->stream.cbc)
+ (*dat->stream.cbc)(in,out,len,&dat->ks,ctx->iv,ctx->encrypt);
+ else if (ctx->encrypt)
+ CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
+ else
+ CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
+
+ return 1;
+}
+
+static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ size_t bl = ctx->cipher->block_size;
+ size_t i;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ if (len<bl) return 1;
+
+ for (i=0,len-=bl;i<=len;i+=bl)
+ (*dat->block)(in+i,out+i,&dat->ks);
+
+ return 1;
+}
+
+static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ CRYPTO_ofb128_encrypt(in,out,len,&dat->ks,
+ ctx->iv,&ctx->num,dat->block);
+ return 1;
+}
+
+static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ CRYPTO_cfb128_encrypt(in,out,len,&dat->ks,
+ ctx->iv,&ctx->num,ctx->encrypt,dat->block);
+ return 1;
+}
+
+static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ CRYPTO_cfb128_8_encrypt(in,out,len,&dat->ks,
+ ctx->iv,&ctx->num,ctx->encrypt,dat->block);
+ return 1;
+}
+
+static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ if (ctx->flags&EVP_CIPH_FLAG_LENGTH_BITS) {
+ CRYPTO_cfb128_1_encrypt(in,out,len,&dat->ks,
+ ctx->iv,&ctx->num,ctx->encrypt,dat->block);
+ return 1;
+ }
+
+ while (len>=MAXBITCHUNK) {
+ CRYPTO_cfb128_1_encrypt(in,out,MAXBITCHUNK*8,&dat->ks,
+ ctx->iv,&ctx->num,ctx->encrypt,dat->block);
+ len-=MAXBITCHUNK;
+ }
+ if (len)
+ CRYPTO_cfb128_1_encrypt(in,out,len*8,&dat->ks,
+ ctx->iv,&ctx->num,ctx->encrypt,dat->block);
+
+ return 1;
+}
+
+static int aes_ctr_cipher (EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ unsigned int num = ctx->num;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ if (dat->stream.ctr)
+ CRYPTO_ctr128_encrypt_ctr32(in,out,len,&dat->ks,
+ ctx->iv,ctx->buf,&num,dat->stream.ctr);
+ else
+ CRYPTO_ctr128_encrypt(in,out,len,&dat->ks,
+ ctx->iv,ctx->buf,&num,dat->block);
+ ctx->num = (size_t)num;
+ return 1;
+}
+
+BLOCK_CIPHER_generic_pack(NID_aes,128,EVP_CIPH_FLAG_FIPS)
+BLOCK_CIPHER_generic_pack(NID_aes,192,EVP_CIPH_FLAG_FIPS)
+BLOCK_CIPHER_generic_pack(NID_aes,256,EVP_CIPH_FLAG_FIPS)
+
+static int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
+ {
+ EVP_AES_GCM_CTX *gctx = c->cipher_data;
+ OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
+ if (gctx->iv != c->iv)
+ OPENSSL_free(gctx->iv);
+ return 1;
+ }
+
+/* increment counter (64-bit int) by 1 */
+static void ctr64_inc(unsigned char *counter) {
+ int n=8;
+ unsigned char c;
+
+ do {
+ --n;
+ c = counter[n];
+ ++c;
+ counter[n] = c;
+ if (c) return;
+ } while (n);
+}
+
+static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+ {
+ EVP_AES_GCM_CTX *gctx = c->cipher_data;
+ switch (type)
+ {
+ case EVP_CTRL_INIT:
+ gctx->key_set = 0;
+ gctx->iv_set = 0;
+ gctx->ivlen = c->cipher->iv_len;
+ gctx->iv = c->iv;
+ gctx->taglen = -1;
+ gctx->iv_gen = 0;
+ gctx->tls_aad_len = -1;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IVLEN:
+ if (arg <= 0)
+ return 0;
+#ifdef OPENSSL_FIPS
+ if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)
+ && arg < 12)
+ return 0;
+#endif
+ /* Allocate memory for IV if needed */
+ if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen))
+ {
+ if (gctx->iv != c->iv)
+ OPENSSL_free(gctx->iv);
+ gctx->iv = OPENSSL_malloc(arg);
+ if (!gctx->iv)
+ return 0;
+ }
+ gctx->ivlen = arg;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_TAG:
+ if (arg <= 0 || arg > 16 || c->encrypt)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->taglen = arg;
+ return 1;
+
+ case EVP_CTRL_GCM_GET_TAG:
+ if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0)
+ return 0;
+ memcpy(ptr, c->buf, arg);
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IV_FIXED:
+ /* Special case: -1 length restores whole IV */
+ if (arg == -1)
+ {
+ memcpy(gctx->iv, ptr, gctx->ivlen);
+ gctx->iv_gen = 1;
+ return 1;
+ }
+ /* Fixed field must be at least 4 bytes and invocation field
+ * at least 8.
+ */
+ if ((arg < 4) || (gctx->ivlen - arg) < 8)
+ return 0;
+ if (arg)
+ memcpy(gctx->iv, ptr, arg);
+ if (c->encrypt &&
+ RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
+ return 0;
+ gctx->iv_gen = 1;
+ return 1;
+
+ case EVP_CTRL_GCM_IV_GEN:
+ if (gctx->iv_gen == 0 || gctx->key_set == 0)
+ return 0;
+ CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ if (arg <= 0 || arg > gctx->ivlen)
+ arg = gctx->ivlen;
+ memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
+ /* Invocation field will be at least 8 bytes in size and
+ * so no need to check wrap around or increment more than
+ * last 8 bytes.
+ */
+ ctr64_inc(gctx->iv + gctx->ivlen - 8);
+ gctx->iv_set = 1;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IV_INV:
+ if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt)
+ return 0;
+ memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
+ CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ return 1;
+
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ /* Save the AAD for later use */
+ if (arg != 13)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->tls_aad_len = arg;
+ {
+ unsigned int len=c->buf[arg-2]<<8|c->buf[arg-1];
+ /* Correct length for explicit IV */
+ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ /* If decrypting correct for tag too */
+ if (!c->encrypt)
+ len -= EVP_GCM_TLS_TAG_LEN;
+ c->buf[arg-2] = len>>8;
+ c->buf[arg-1] = len & 0xff;
+ }
+ /* Extra padding: tag appended to record */
+ return EVP_GCM_TLS_TAG_LEN;
+
+ default:
+ return -1;
+
+ }
+ }
+
+static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key)
+ { do {
+#ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE)
+ {
+ AES_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
+ CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
+ (block128_f)AES_encrypt);
+ gctx->ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
+ break;
+ }
+ else
+#endif
+#ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE)
+ {
+ vpaes_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
+ CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
+ (block128_f)vpaes_encrypt);
+ gctx->ctr = NULL;
+ break;
+ }
+#endif
+ AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encrypt);
+#ifdef AES_CTR_ASM
+ gctx->ctr = (ctr128_f)AES_ctr32_encrypt;
+#else
+ gctx->ctr = NULL;
+#endif
+ } while (0);
+
+ /* If we have an iv can set it directly, otherwise use
+ * saved IV.
+ */
+ if (iv == NULL && gctx->iv_set)
+ iv = gctx->iv;
+ if (iv)
+ {
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ }
+ else
+ {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ else
+ memcpy(gctx->iv, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ gctx->iv_gen = 0;
+ }
+ return 1;
+ }
+
+/* Handle TLS GCM packet format. This consists of the last portion of the IV
+ * followed by the payload and finally the tag. On encrypt generate IV,
+ * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
+ * and verify tag.
+ */
+
+static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ int rv = -1;
+ /* Encrypt/decrypt must be performed in place */
+ if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN+EVP_GCM_TLS_TAG_LEN))
+ return -1;
+ /* Set IV from start of buffer or generate IV and write to start
+ * of buffer.
+ */
+ if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ?
+ EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
+ EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
+ goto err;
+ /* Use saved AAD */
+ if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len))
+ goto err;
+ /* Fix buffer and length to point to payload */
+ in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+ if (ctx->encrypt)
+ {
+ /* Encrypt payload */
+ if (gctx->ctr)
+ {
+ if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+ in, out, len,
+ gctx->ctr))
+ goto err;
+ }
+ else {
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
+ goto err;
+ }
+ out += len;
+ /* Finally write tag */
+ CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
+ rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+ }
+ else
+ {
+ /* Decrypt */
+ if (gctx->ctr)
+ {
+ if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+ in, out, len,
+ gctx->ctr))
+ goto err;
+ }
+ else {
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
+ goto err;
+ }
+ /* Retrieve tag */
+ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf,
+ EVP_GCM_TLS_TAG_LEN);
+ /* If tag mismatch wipe buffer */
+ if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN))
+ {
+ OPENSSL_cleanse(out, len);
+ goto err;
+ }
+ rv = len;
+ }
+
+ err:
+ gctx->iv_set = 0;
+ gctx->tls_aad_len = -1;
+ return rv;
+ }
+
+static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ /* If not set up, return error */
+ if (!gctx->key_set)
+ return -1;
+
+ if (gctx->tls_aad_len >= 0)
+ return aes_gcm_tls_cipher(ctx, out, in, len);
+
+ if (!gctx->iv_set)
+ return -1;
+ if (in)
+ {
+ if (out == NULL)
+ {
+ if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
+ return -1;
+ }
+ else if (ctx->encrypt)
+ {
+ if (gctx->ctr)
+ {
+ if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+ in, out, len,
+ gctx->ctr))
+ return -1;
+ }
+ else {
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
+ return -1;
+ }
+ }
+ else
+ {
+ if (gctx->ctr)
+ {
+ if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+ in, out, len,
+ gctx->ctr))
+ return -1;
+ }
+ else {
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
+ return -1;
+ }
+ }
+ return len;
+ }
+ else
+ {
+ if (!ctx->encrypt)
+ {
+ if (gctx->taglen < 0)
+ return -1;
+ if (CRYPTO_gcm128_finish(&gctx->gcm,
+ ctx->buf, gctx->taglen) != 0)
+ return -1;
+ gctx->iv_set = 0;
+ return 0;
+ }
+ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
+ gctx->taglen = 16;
+ /* Don't reuse the IV */
+ gctx->iv_set = 0;
+ return 0;
+ }
+
+ }
+
+#define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
+ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT)
+
+BLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM,
+ EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes,192,1,12,gcm,GCM,
+ EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM,
+ EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
+
+static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+ {
+ EVP_AES_XTS_CTX *xctx = c->cipher_data;
+ if (type != EVP_CTRL_INIT)
+ return -1;
+ /* key1 and key2 are used as an indicator both key and IV are set */
+ xctx->xts.key1 = NULL;
+ xctx->xts.key2 = NULL;
+ return 1;
+ }
+
+static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+
+ if (key) do
+ {
+#ifdef AES_XTS_ASM
+ xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
+#else
+ xctx->stream = NULL;
+#endif
+ /* key_len is two AES keys */
+#ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE)
+ xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt;
+ else
+#endif
+#ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE)
+ {
+ if (enc)
+ {
+ vpaes_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)vpaes_encrypt;
+ }
+ else
+ {
+ vpaes_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)vpaes_decrypt;
+ }
+
+ vpaes_set_encrypt_key(key + ctx->key_len/2,
+ ctx->key_len * 4, &xctx->ks2);
+ xctx->xts.block2 = (block128_f)vpaes_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ break;
+ }
+#endif
+ if (enc)
+ {
+ AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)AES_encrypt;
+ }
+ else
+ {
+ AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)AES_decrypt;
+ }
+
+ AES_set_encrypt_key(key + ctx->key_len/2,
+ ctx->key_len * 4, &xctx->ks2);
+ xctx->xts.block2 = (block128_f)AES_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ } while (0);
+
+ if (iv)
+ {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+ }
+
+static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!xctx->xts.key1 || !xctx->xts.key2)
+ return 0;
+ if (!out || !in || len<AES_BLOCK_SIZE)
+ return 0;
+#ifdef OPENSSL_FIPS
+ /* Requirement of SP800-38E */
+ if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) &&
+ (len > (1UL<<20)*16))
+ {
+ EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE);
+ return 0;
+ }
+#endif
+ if (xctx->stream)
+ (*xctx->stream)(in, out, len,
+ xctx->xts.key1, xctx->xts.key2, ctx->iv);
+ else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len,
+ ctx->encrypt))
+ return 0;
+ return 1;
+ }
+
+#define aes_xts_cleanup NULL
+
+#define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT)
+
+BLOCK_CIPHER_custom(NID_aes,128,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
+BLOCK_CIPHER_custom(NID_aes,256,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
+
+static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+ {
+ EVP_AES_CCM_CTX *cctx = c->cipher_data;
+ switch (type)
+ {
+ case EVP_CTRL_INIT:
+ cctx->key_set = 0;
+ cctx->iv_set = 0;
+ cctx->L = 8;
+ cctx->M = 12;
+ cctx->tag_set = 0;
+ cctx->len_set = 0;
+ return 1;
+
+ case EVP_CTRL_CCM_SET_IVLEN:
+ arg = 15 - arg;
+ case EVP_CTRL_CCM_SET_L:
+ if (arg < 2 || arg > 8)
+ return 0;
+ cctx->L = arg;
+ return 1;
+
+ case EVP_CTRL_CCM_SET_TAG:
+ if ((arg & 1) || arg < 4 || arg > 16)
+ return 0;
+ if ((c->encrypt && ptr) || (!c->encrypt && !ptr))
+ return 0;
+ if (ptr)
+ {
+ cctx->tag_set = 1;
+ memcpy(c->buf, ptr, arg);
+ }
+ cctx->M = arg;
+ return 1;
+
+ case EVP_CTRL_CCM_GET_TAG:
+ if (!c->encrypt || !cctx->tag_set)
+ return 0;
+ if(!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
+ return 0;
+ cctx->tag_set = 0;
+ cctx->iv_set = 0;
+ cctx->len_set = 0;
+ return 1;
+
+ default:
+ return -1;
+
+ }
+ }
+
+static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) do
+ {
+#ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE)
+ {
+ vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f)vpaes_encrypt);
+ cctx->str = NULL;
+ cctx->key_set = 1;
+ break;
+ }
+#endif
+ AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f)AES_encrypt);
+ cctx->str = NULL;
+ cctx->key_set = 1;
+ } while (0);
+ if (iv)
+ {
+ memcpy(ctx->iv, iv, 15 - cctx->L);
+ cctx->iv_set = 1;
+ }
+ return 1;
+ }
+
+static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ CCM128_CONTEXT *ccm = &cctx->ccm;
+ /* If not set up, return error */
+ if (!cctx->iv_set && !cctx->key_set)
+ return -1;
+ if (!ctx->encrypt && !cctx->tag_set)
+ return -1;
+ if (!out)
+ {
+ if (!in)
+ {
+ if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L,len))
+ return -1;
+ cctx->len_set = 1;
+ return len;
+ }
+ /* If have AAD need message length */
+ if (!cctx->len_set && len)
+ return -1;
+ CRYPTO_ccm128_aad(ccm, in, len);
+ return len;
+ }
+ /* EVP_*Final() doesn't return any data */
+ if (!in)
+ return 0;
+ /* If not set length yet do it */
+ if (!cctx->len_set)
+ {
+ if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
+ return -1;
+ cctx->len_set = 1;
+ }
+ if (ctx->encrypt)
+ {
+ if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
+ cctx->str) :
+ CRYPTO_ccm128_encrypt(ccm, in, out, len))
+ return -1;
+ cctx->tag_set = 1;
+ return len;
+ }
+ else
+ {
+ int rv = -1;
+ if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
+ cctx->str) :
+ !CRYPTO_ccm128_decrypt(ccm, in, out, len))
+ {
+ unsigned char tag[16];
+ if (CRYPTO_ccm128_tag(ccm, tag, cctx->M))
+ {
+ if (!memcmp(tag, ctx->buf, cctx->M))
+ rv = len;
+ }
+ }
+ if (rv == -1)
+ OPENSSL_cleanse(out, len);
+ cctx->iv_set = 0;
+ cctx->tag_set = 0;
+ cctx->len_set = 0;
+ return rv;
+ }
+
+ }
+
+#define aes_ccm_cleanup NULL
+
+BLOCK_CIPHER_custom(NID_aes,128,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes,192,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
+
+#endif
#endif
diff --git a/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
new file mode 100644
index 000000000..483e04b60
--- /dev/null
+++ b/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
@@ -0,0 +1,580 @@
+/* ====================================================================
+ * Copyright (c) 2011-2013 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
+ * licensing@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.
+ * ====================================================================
+ */
+
+#include <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/aes.h>
+#include <openssl/sha.h>
+#include "evp_locl.h"
+
+#ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+#define EVP_CTRL_AEAD_TLS1_AAD 0x16
+#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+#endif
+
+#if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
+#define EVP_CIPH_FLAG_DEFAULT_ASN1 0
+#endif
+
+#define TLS1_1_VERSION 0x0302
+
+typedef struct
+ {
+ AES_KEY ks;
+ SHA_CTX head,tail,md;
+ size_t payload_length; /* AAD length in decrypt case */
+ union {
+ unsigned int tls_ver;
+ unsigned char tls_aad[16]; /* 13 used */
+ } aux;
+ } EVP_AES_HMAC_SHA1;
+
+#define NO_PAYLOAD_LENGTH ((size_t)-1)
+
+#if defined(AES_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) )
+
+#if defined(__GNUC__) && __GNUC__>=2 && !defined(PEDANTIC)
+# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; })
+#endif
+
+extern unsigned int OPENSSL_ia32cap_P[2];
+#define AESNI_CAPABLE (1<<(57-32))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key,
+ unsigned char *ivec, int enc);
+
+void aesni_cbc_sha1_enc (const void *inp, void *out, size_t blocks,
+ const AES_KEY *key, unsigned char iv[16],
+ SHA_CTX *ctx,const void *in0);
+
+#define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
+
+static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *inkey,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+ int ret;
+
+ if (enc)
+ ret=aesni_set_encrypt_key(inkey,ctx->key_len*8,&key->ks);
+ else
+ ret=aesni_set_decrypt_key(inkey,ctx->key_len*8,&key->ks);
+
+ SHA1_Init(&key->head); /* handy when benchmarking */
+ key->tail = key->head;
+ key->md = key->head;
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return ret<0?0:1;
+ }
+
+#define STITCHED_CALL
+
+#if !defined(STITCHED_CALL)
+#define aes_off 0
+#endif
+
+void sha1_block_data_order (void *c,const void *p,size_t len);
+
+static void sha1_update(SHA_CTX *c,const void *data,size_t len)
+{ const unsigned char *ptr = data;
+ size_t res;
+
+ if ((res = c->num)) {
+ res = SHA_CBLOCK-res;
+ if (len<res) res=len;
+ SHA1_Update (c,ptr,res);
+ ptr += res;
+ len -= res;
+ }
+
+ res = len % SHA_CBLOCK;
+ len -= res;
+
+ if (len) {
+ sha1_block_data_order(c,ptr,len/SHA_CBLOCK);
+
+ ptr += len;
+ c->Nh += len>>29;
+ c->Nl += len<<=3;
+ if (c->Nl<(unsigned int)len) c->Nh++;
+ }
+
+ if (res)
+ SHA1_Update(c,ptr,res);
+}
+
+#ifdef SHA1_Update
+#undef SHA1_Update
+#endif
+#define SHA1_Update sha1_update
+
+static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+ unsigned int l;
+ size_t plen = key->payload_length,
+ iv = 0, /* explicit IV in TLS 1.1 and later */
+ sha_off = 0;
+#if defined(STITCHED_CALL)
+ size_t aes_off = 0,
+ blocks;
+
+ sha_off = SHA_CBLOCK-key->md.num;
+#endif
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ if (len%AES_BLOCK_SIZE) return 0;
+
+ if (ctx->encrypt) {
+ if (plen==NO_PAYLOAD_LENGTH)
+ plen = len;
+ else if (len!=((plen+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE))
+ return 0;
+ else if (key->aux.tls_ver >= TLS1_1_VERSION)
+ iv = AES_BLOCK_SIZE;
+
+#if defined(STITCHED_CALL)
+ if (plen>(sha_off+iv) && (blocks=(plen-(sha_off+iv))/SHA_CBLOCK)) {
+ SHA1_Update(&key->md,in+iv,sha_off);
+
+ aesni_cbc_sha1_enc(in,out,blocks,&key->ks,
+ ctx->iv,&key->md,in+iv+sha_off);
+ blocks *= SHA_CBLOCK;
+ aes_off += blocks;
+ sha_off += blocks;
+ key->md.Nh += blocks>>29;
+ key->md.Nl += blocks<<=3;
+ if (key->md.Nl<(unsigned int)blocks) key->md.Nh++;
+ } else {
+ sha_off = 0;
+ }
+#endif
+ sha_off += iv;
+ SHA1_Update(&key->md,in+sha_off,plen-sha_off);
+
+ if (plen!=len) { /* "TLS" mode of operation */
+ if (in!=out)
+ memcpy(out+aes_off,in+aes_off,plen-aes_off);
+
+ /* calculate HMAC and append it to payload */
+ SHA1_Final(out+plen,&key->md);
+ key->md = key->tail;
+ SHA1_Update(&key->md,out+plen,SHA_DIGEST_LENGTH);
+ SHA1_Final(out+plen,&key->md);
+
+ /* pad the payload|hmac */
+ plen += SHA_DIGEST_LENGTH;
+ for (l=len-plen-1;plen<len;plen++) out[plen]=l;
+ /* encrypt HMAC|padding at once */
+ aesni_cbc_encrypt(out+aes_off,out+aes_off,len-aes_off,
+ &key->ks,ctx->iv,1);
+ } else {
+ aesni_cbc_encrypt(in+aes_off,out+aes_off,len-aes_off,
+ &key->ks,ctx->iv,1);
+ }
+ } else {
+ union { unsigned int u[SHA_DIGEST_LENGTH/sizeof(unsigned int)];
+ unsigned char c[32+SHA_DIGEST_LENGTH]; } mac, *pmac;
+
+ /* arrange cache line alignment */
+ pmac = (void *)(((size_t)mac.c+31)&((size_t)0-32));
+
+ /* decrypt HMAC|padding at once */
+ aesni_cbc_encrypt(in,out,len,
+ &key->ks,ctx->iv,0);
+
+ if (plen) { /* "TLS" mode of operation */
+ size_t inp_len, mask, j, i;
+ unsigned int res, maxpad, pad, bitlen;
+ int ret = 1;
+ union { unsigned int u[SHA_LBLOCK];
+ unsigned char c[SHA_CBLOCK]; }
+ *data = (void *)key->md.data;
+
+ if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3])
+ >= TLS1_1_VERSION)
+ iv = AES_BLOCK_SIZE;
+
+ if (len<(iv+SHA_DIGEST_LENGTH+1))
+ return 0;
+
+ /* omit explicit iv */
+ out += iv;
+ len -= iv;
+
+ /* figure out payload length */
+ pad = out[len-1];
+ maxpad = len-(SHA_DIGEST_LENGTH+1);
+ maxpad |= (255-maxpad)>>(sizeof(maxpad)*8-8);
+ maxpad &= 255;
+
+ inp_len = len - (SHA_DIGEST_LENGTH+pad+1);
+ mask = (0-((inp_len-len)>>(sizeof(inp_len)*8-1)));
+ inp_len &= mask;
+ ret &= (int)mask;
+
+ key->aux.tls_aad[plen-2] = inp_len>>8;
+ key->aux.tls_aad[plen-1] = inp_len;
+
+ /* calculate HMAC */
+ key->md = key->head;
+ SHA1_Update(&key->md,key->aux.tls_aad,plen);
+
+#if 1
+ len -= SHA_DIGEST_LENGTH; /* amend mac */
+ if (len>=(256+SHA_CBLOCK)) {
+ j = (len-(256+SHA_CBLOCK))&(0-SHA_CBLOCK);
+ j += SHA_CBLOCK-key->md.num;
+ SHA1_Update(&key->md,out,j);
+ out += j;
+ len -= j;
+ inp_len -= j;
+ }
+
+ /* but pretend as if we hashed padded payload */
+ bitlen = key->md.Nl+(inp_len<<3); /* at most 18 bits */
+#ifdef BSWAP
+ bitlen = BSWAP(bitlen);
+#else
+ mac.c[0] = 0;
+ mac.c[1] = (unsigned char)(bitlen>>16);
+ mac.c[2] = (unsigned char)(bitlen>>8);
+ mac.c[3] = (unsigned char)bitlen;
+ bitlen = mac.u[0];
+#endif
+
+ pmac->u[0]=0;
+ pmac->u[1]=0;
+ pmac->u[2]=0;
+ pmac->u[3]=0;
+ pmac->u[4]=0;
+
+ for (res=key->md.num, j=0;j<len;j++) {
+ size_t c = out[j];
+ mask = (j-inp_len)>>(sizeof(j)*8-8);
+ c &= mask;
+ c |= 0x80&~mask&~((inp_len-j)>>(sizeof(j)*8-8));
+ data->c[res++]=(unsigned char)c;
+
+ if (res!=SHA_CBLOCK) continue;
+
+ mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
+ data->u[SHA_LBLOCK-1] |= bitlen&mask;
+ sha1_block_data_order(&key->md,data,1);
+ mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+ res=0;
+ }
+
+ for(i=res;i<SHA_CBLOCK;i++,j++) data->c[i]=0;
+
+ if (res>SHA_CBLOCK-8) {
+ mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
+ data->u[SHA_LBLOCK-1] |= bitlen&mask;
+ sha1_block_data_order(&key->md,data,1);
+ mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+
+ memset(data,0,SHA_CBLOCK);
+ j+=64;
+ }
+ data->u[SHA_LBLOCK-1] = bitlen;
+ sha1_block_data_order(&key->md,data,1);
+ mask = 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+
+#ifdef BSWAP
+ pmac->u[0] = BSWAP(pmac->u[0]);
+ pmac->u[1] = BSWAP(pmac->u[1]);
+ pmac->u[2] = BSWAP(pmac->u[2]);
+ pmac->u[3] = BSWAP(pmac->u[3]);
+ pmac->u[4] = BSWAP(pmac->u[4]);
+#else
+ for (i=0;i<5;i++) {
+ res = pmac->u[i];
+ pmac->c[4*i+0]=(unsigned char)(res>>24);
+ pmac->c[4*i+1]=(unsigned char)(res>>16);
+ pmac->c[4*i+2]=(unsigned char)(res>>8);
+ pmac->c[4*i+3]=(unsigned char)res;
+ }
+#endif
+ len += SHA_DIGEST_LENGTH;
+#else
+ SHA1_Update(&key->md,out,inp_len);
+ res = key->md.num;
+ SHA1_Final(pmac->c,&key->md);
+
+ {
+ unsigned int inp_blocks, pad_blocks;
+
+ /* but pretend as if we hashed padded payload */
+ inp_blocks = 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
+ res += (unsigned int)(len-inp_len);
+ pad_blocks = res / SHA_CBLOCK;
+ res %= SHA_CBLOCK;
+ pad_blocks += 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
+ for (;inp_blocks<pad_blocks;inp_blocks++)
+ sha1_block_data_order(&key->md,data,1);
+ }
+#endif
+ key->md = key->tail;
+ SHA1_Update(&key->md,pmac->c,SHA_DIGEST_LENGTH);
+ SHA1_Final(pmac->c,&key->md);
+
+ /* verify HMAC */
+ out += inp_len;
+ len -= inp_len;
+#if 1
+ {
+ unsigned char *p = out+len-1-maxpad-SHA_DIGEST_LENGTH;
+ size_t off = out-p;
+ unsigned int c, cmask;
+
+ maxpad += SHA_DIGEST_LENGTH;
+ for (res=0,i=0,j=0;j<maxpad;j++) {
+ c = p[j];
+ cmask = ((int)(j-off-SHA_DIGEST_LENGTH))>>(sizeof(int)*8-1);
+ res |= (c^pad)&~cmask; /* ... and padding */
+ cmask &= ((int)(off-1-j))>>(sizeof(int)*8-1);
+ res |= (c^pmac->c[i])&cmask;
+ i += 1&cmask;
+ }
+ maxpad -= SHA_DIGEST_LENGTH;
+
+ res = 0-((0-res)>>(sizeof(res)*8-1));
+ ret &= (int)~res;
+ }
+#else
+ for (res=0,i=0;i<SHA_DIGEST_LENGTH;i++)
+ res |= out[i]^pmac->c[i];
+ res = 0-((0-res)>>(sizeof(res)*8-1));
+ ret &= (int)~res;
+
+ /* verify padding */
+ pad = (pad&~res) | (maxpad&res);
+ out = out+len-1-pad;
+ for (res=0,i=0;i<pad;i++)
+ res |= out[i]^pad;
+
+ res = (0-res)>>(sizeof(res)*8-1);
+ ret &= (int)~res;
+#endif
+ return ret;
+ } else {
+ SHA1_Update(&key->md,out,len);
+ }
+ }
+
+ return 1;
+ }
+
+static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+ {
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+
+ switch (type)
+ {
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ {
+ unsigned int i;
+ unsigned char hmac_key[64];
+
+ memset (hmac_key,0,sizeof(hmac_key));
+
+ if (arg > (int)sizeof(hmac_key)) {
+ SHA1_Init(&key->head);
+ SHA1_Update(&key->head,ptr,arg);
+ SHA1_Final(hmac_key,&key->head);
+ } else {
+ memcpy(hmac_key,ptr,arg);
+ }
+
+ for (i=0;i<sizeof(hmac_key);i++)
+ hmac_key[i] ^= 0x36; /* ipad */
+ SHA1_Init(&key->head);
+ SHA1_Update(&key->head,hmac_key,sizeof(hmac_key));
+
+ for (i=0;i<sizeof(hmac_key);i++)
+ hmac_key[i] ^= 0x36^0x5c; /* opad */
+ SHA1_Init(&key->tail);
+ SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key));
+
+ OPENSSL_cleanse(hmac_key,sizeof(hmac_key));
+
+ return 1;
+ }
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ {
+ unsigned char *p=ptr;
+ unsigned int len=p[arg-2]<<8|p[arg-1];
+
+ if (ctx->encrypt)
+ {
+ key->payload_length = len;
+ if ((key->aux.tls_ver=p[arg-4]<<8|p[arg-3]) >= TLS1_1_VERSION) {
+ len -= AES_BLOCK_SIZE;
+ p[arg-2] = len>>8;
+ p[arg-1] = len;
+ }
+ key->md = key->head;
+ SHA1_Update(&key->md,p,arg);
+
+ return (int)(((len+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE)
+ - len);
+ }
+ else
+ {
+ if (arg>13) arg = 13;
+ memcpy(key->aux.tls_aad,ptr,arg);
+ key->payload_length = arg;
+
+ return SHA_DIGEST_LENGTH;
+ }
+ }
+ default:
+ return -1;
+ }
+ }
+
+static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher =
+ {
+#ifdef NID_aes_128_cbc_hmac_sha1
+ NID_aes_128_cbc_hmac_sha1,
+#else
+ NID_undef,
+#endif
+ 16,16,16,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
+ aesni_cbc_hmac_sha1_init_key,
+ aesni_cbc_hmac_sha1_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA1),
+ EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha1_ctrl,
+ NULL
+ };
+
+static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher =
+ {
+#ifdef NID_aes_256_cbc_hmac_sha1
+ NID_aes_256_cbc_hmac_sha1,
+#else
+ NID_undef,
+#endif
+ 16,32,16,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
+ aesni_cbc_hmac_sha1_init_key,
+ aesni_cbc_hmac_sha1_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA1),
+ EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha1_ctrl,
+ NULL
+ };
+
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
+ {
+ return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
+ &aesni_128_cbc_hmac_sha1_cipher:NULL);
+ }
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
+ {
+ return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
+ &aesni_256_cbc_hmac_sha1_cipher:NULL);
+ }
+#else
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
+ {
+ return NULL;
+ }
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
+ {
+ return NULL;
+ }
+#endif
+#endif
diff --git a/deps/openssl/openssl/crypto/evp/e_des3.c b/deps/openssl/openssl/crypto/evp/e_des3.c
index 3232cfe02..1e6997266 100644
--- a/deps/openssl/openssl/crypto/evp/e_des3.c
+++ b/deps/openssl/openssl/crypto/evp/e_des3.c
@@ -65,6 +65,8 @@
#include <openssl/des.h>
#include <openssl/rand.h>
+#ifndef OPENSSL_FIPS
+
static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv,int enc);
@@ -311,3 +313,4 @@ const EVP_CIPHER *EVP_des_ede3(void)
return &des_ede3_ecb;
}
#endif
+#endif
diff --git a/deps/openssl/openssl/crypto/evp/e_null.c b/deps/openssl/openssl/crypto/evp/e_null.c
index 7cf50e141..f0c1f78b5 100644
--- a/deps/openssl/openssl/crypto/evp/e_null.c
+++ b/deps/openssl/openssl/crypto/evp/e_null.c
@@ -61,6 +61,8 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
+#ifndef OPENSSL_FIPS
+
static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv,int enc);
static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
@@ -99,4 +101,4 @@ static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
memcpy((char *)out,(const char *)in,inl);
return 1;
}
-
+#endif
diff --git a/deps/openssl/openssl/crypto/evp/e_rc2.c b/deps/openssl/openssl/crypto/evp/e_rc2.c
index f78d78112..d4c33b58d 100644
--- a/deps/openssl/openssl/crypto/evp/e_rc2.c
+++ b/deps/openssl/openssl/crypto/evp/e_rc2.c
@@ -183,7 +183,8 @@ static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
key_bits =rc2_magic_to_meth((int)num);
if (!key_bits)
return(-1);
- if(i > 0) EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1);
+ if(i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
+ return -1;
EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
EVP_CIPHER_CTX_set_key_length(c, key_bits / 8);
}
diff --git a/deps/openssl/openssl/crypto/evp/e_rc4.c b/deps/openssl/openssl/crypto/evp/e_rc4.c
index 8b5175e0f..b4f6bda82 100644
--- a/deps/openssl/openssl/crypto/evp/e_rc4.c
+++ b/deps/openssl/openssl/crypto/evp/e_rc4.c
@@ -62,6 +62,7 @@
#ifndef OPENSSL_NO_RC4
#include <openssl/evp.h>
+#include "evp_locl.h"
#include <openssl/objects.h>
#include <openssl/rc4.h>
diff --git a/deps/openssl/openssl/crypto/evp/e_rc4_hmac_md5.c b/deps/openssl/openssl/crypto/evp/e_rc4_hmac_md5.c
new file mode 100644
index 000000000..56563191b
--- /dev/null
+++ b/deps/openssl/openssl/crypto/evp/e_rc4_hmac_md5.c
@@ -0,0 +1,298 @@
+/* ====================================================================
+ * Copyright (c) 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
+ * licensing@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.
+ * ====================================================================
+ */
+
+#include <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/rc4.h>
+#include <openssl/md5.h>
+
+#ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+#define EVP_CTRL_AEAD_TLS1_AAD 0x16
+#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+#endif
+
+/* FIXME: surely this is available elsewhere? */
+#define EVP_RC4_KEY_SIZE 16
+
+typedef struct
+ {
+ RC4_KEY ks;
+ MD5_CTX head,tail,md;
+ size_t payload_length;
+ } EVP_RC4_HMAC_MD5;
+
+#define NO_PAYLOAD_LENGTH ((size_t)-1)
+
+void rc4_md5_enc (RC4_KEY *key, const void *in0, void *out,
+ MD5_CTX *ctx,const void *inp,size_t blocks);
+
+#define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data)
+
+static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *inkey,
+ const unsigned char *iv, int enc)
+ {
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+ RC4_set_key(&key->ks,EVP_CIPHER_CTX_key_length(ctx),
+ inkey);
+
+ MD5_Init(&key->head); /* handy when benchmarking */
+ key->tail = key->head;
+ key->md = key->head;
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return 1;
+ }
+
+#if !defined(OPENSSL_NO_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) ) && \
+ !(defined(__APPLE__) && defined(__MACH__))
+#define STITCHED_CALL
+#endif
+
+#if !defined(STITCHED_CALL)
+#define rc4_off 0
+#define md5_off 0
+#endif
+
+static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+#if defined(STITCHED_CALL)
+ size_t rc4_off = 32-1-(key->ks.x&(32-1)), /* 32 is $MOD from rc4_md5-x86_64.pl */
+ md5_off = MD5_CBLOCK-key->md.num,
+ blocks;
+ unsigned int l;
+ extern unsigned int OPENSSL_ia32cap_P[];
+#endif
+ size_t plen = key->payload_length;
+
+ if (plen!=NO_PAYLOAD_LENGTH && len!=(plen+MD5_DIGEST_LENGTH)) return 0;
+
+ if (ctx->encrypt) {
+ if (plen==NO_PAYLOAD_LENGTH) plen = len;
+#if defined(STITCHED_CALL)
+ /* cipher has to "fall behind" */
+ if (rc4_off>md5_off) md5_off+=MD5_CBLOCK;
+
+ if (plen>md5_off && (blocks=(plen-md5_off)/MD5_CBLOCK) &&
+ (OPENSSL_ia32cap_P[0]&(1<<20))==0) {
+ MD5_Update(&key->md,in,md5_off);
+ RC4(&key->ks,rc4_off,in,out);
+
+ rc4_md5_enc(&key->ks,in+rc4_off,out+rc4_off,
+ &key->md,in+md5_off,blocks);
+ blocks *= MD5_CBLOCK;
+ rc4_off += blocks;
+ md5_off += blocks;
+ key->md.Nh += blocks>>29;
+ key->md.Nl += blocks<<=3;
+ if (key->md.Nl<(unsigned int)blocks) key->md.Nh++;
+ } else {
+ rc4_off = 0;
+ md5_off = 0;
+ }
+#endif
+ MD5_Update(&key->md,in+md5_off,plen-md5_off);
+
+ if (plen!=len) { /* "TLS" mode of operation */
+ if (in!=out)
+ memcpy(out+rc4_off,in+rc4_off,plen-rc4_off);
+
+ /* calculate HMAC and append it to payload */
+ MD5_Final(out+plen,&key->md);
+ key->md = key->tail;
+ MD5_Update(&key->md,out+plen,MD5_DIGEST_LENGTH);
+ MD5_Final(out+plen,&key->md);
+ /* encrypt HMAC at once */
+ RC4(&key->ks,len-rc4_off,out+rc4_off,out+rc4_off);
+ } else {
+ RC4(&key->ks,len-rc4_off,in+rc4_off,out+rc4_off);
+ }
+ } else {
+ unsigned char mac[MD5_DIGEST_LENGTH];
+#if defined(STITCHED_CALL)
+ /* digest has to "fall behind" */
+ if (md5_off>rc4_off) rc4_off += 2*MD5_CBLOCK;
+ else rc4_off += MD5_CBLOCK;
+
+ if (len>rc4_off && (blocks=(len-rc4_off)/MD5_CBLOCK) &&
+ (OPENSSL_ia32cap_P[0]&(1<<20))==0) {
+ RC4(&key->ks,rc4_off,in,out);
+ MD5_Update(&key->md,out,md5_off);
+
+ rc4_md5_enc(&key->ks,in+rc4_off,out+rc4_off,
+ &key->md,out+md5_off,blocks);
+ blocks *= MD5_CBLOCK;
+ rc4_off += blocks;
+ md5_off += blocks;
+ l = (key->md.Nl+(blocks<<3))&0xffffffffU;
+ if (l<key->md.Nl) key->md.Nh++;
+ key->md.Nl = l;
+ key->md.Nh += blocks>>29;
+ } else {
+ md5_off=0;
+ rc4_off=0;
+ }
+#endif
+ /* decrypt HMAC at once */
+ RC4(&key->ks,len-rc4_off,in+rc4_off,out+rc4_off);
+ if (plen!=NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+ MD5_Update(&key->md,out+md5_off,plen-md5_off);
+
+ /* calculate HMAC and verify it */
+ MD5_Final(mac,&key->md);
+ key->md = key->tail;
+ MD5_Update(&key->md,mac,MD5_DIGEST_LENGTH);
+ MD5_Final(mac,&key->md);
+
+ if (memcmp(out+plen,mac,MD5_DIGEST_LENGTH))
+ return 0;
+ } else {
+ MD5_Update(&key->md,out+md5_off,len-md5_off);
+ }
+ }
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return 1;
+ }
+
+static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+ {
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+ switch (type)
+ {
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ {
+ unsigned int i;
+ unsigned char hmac_key[64];
+
+ memset (hmac_key,0,sizeof(hmac_key));
+
+ if (arg > (int)sizeof(hmac_key)) {
+ MD5_Init(&key->head);
+ MD5_Update(&key->head,ptr,arg);
+ MD5_Final(hmac_key,&key->head);
+ } else {
+ memcpy(hmac_key,ptr,arg);
+ }
+
+ for (i=0;i<sizeof(hmac_key);i++)
+ hmac_key[i] ^= 0x36; /* ipad */
+ MD5_Init(&key->head);
+ MD5_Update(&key->head,hmac_key,sizeof(hmac_key));
+
+ for (i=0;i<sizeof(hmac_key);i++)
+ hmac_key[i] ^= 0x36^0x5c; /* opad */
+ MD5_Init(&key->tail);
+ MD5_Update(&key->tail,hmac_key,sizeof(hmac_key));
+
+ return 1;
+ }
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ {
+ unsigned char *p=ptr;
+ unsigned int len=p[arg-2]<<8|p[arg-1];
+
+ if (!ctx->encrypt)
+ {
+ len -= MD5_DIGEST_LENGTH;
+ p[arg-2] = len>>8;
+ p[arg-1] = len;
+ }
+ key->payload_length=len;
+ key->md = key->head;
+ MD5_Update(&key->md,p,arg);
+
+ return MD5_DIGEST_LENGTH;
+ }
+ default:
+ return -1;
+ }
+ }
+
+static EVP_CIPHER r4_hmac_md5_cipher=
+ {
+#ifdef NID_rc4_hmac_md5
+ NID_rc4_hmac_md5,
+#else
+ NID_undef,
+#endif
+ 1,EVP_RC4_KEY_SIZE,0,
+ EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH|EVP_CIPH_FLAG_AEAD_CIPHER,
+ rc4_hmac_md5_init_key,
+ rc4_hmac_md5_cipher,
+ NULL,
+ sizeof(EVP_RC4_HMAC_MD5),
+ NULL,
+ NULL,
+ rc4_hmac_md5_ctrl,
+ NULL
+ };
+
+const EVP_CIPHER *EVP_rc4_hmac_md5(void)
+ {
+ return(&r4_hmac_md5_cipher);
+ }
+#endif
diff --git a/deps/openssl/openssl/crypto/evp/evp.h b/deps/openssl/openssl/crypto/evp/evp.h
index 9f9795e2d..faeb3c24e 100644
--- a/deps/openssl/openssl/crypto/evp/evp.h
+++ b/deps/openssl/openssl/crypto/evp/evp.h
@@ -83,7 +83,7 @@
#define EVP_RC5_32_12_16_KEY_SIZE 16
*/
#define EVP_MAX_MD_SIZE 64 /* longest known is SHA512 */
-#define EVP_MAX_KEY_LENGTH 32
+#define EVP_MAX_KEY_LENGTH 64
#define EVP_MAX_IV_LENGTH 16
#define EVP_MAX_BLOCK_LENGTH 32
@@ -116,6 +116,7 @@
#define EVP_PKEY_DH NID_dhKeyAgreement
#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
#define EVP_PKEY_HMAC NID_hmac
+#define EVP_PKEY_CMAC NID_cmac
#ifdef __cplusplus
extern "C" {
@@ -216,6 +217,8 @@ typedef int evp_verify_method(int type,const unsigned char *m,
#define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018
+#define EVP_MD_FLAG_FIPS 0x0400 /* Note if suitable for use in FIPS mode */
+
/* Digest ctrls */
#define EVP_MD_CTRL_DIGALGID 0x1
@@ -325,6 +328,10 @@ struct evp_cipher_st
#define EVP_CIPH_CBC_MODE 0x2
#define EVP_CIPH_CFB_MODE 0x3
#define EVP_CIPH_OFB_MODE 0x4
+#define EVP_CIPH_CTR_MODE 0x5
+#define EVP_CIPH_GCM_MODE 0x6
+#define EVP_CIPH_CCM_MODE 0x7
+#define EVP_CIPH_XTS_MODE 0x10001
#define EVP_CIPH_MODE 0xF0007
/* Set if variable length cipher */
#define EVP_CIPH_VARIABLE_LENGTH 0x8
@@ -346,6 +353,15 @@ struct evp_cipher_st
#define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000
/* Buffer length in bits not bytes: CFB1 mode only */
#define EVP_CIPH_FLAG_LENGTH_BITS 0x2000
+/* Note if suitable for use in FIPS mode */
+#define EVP_CIPH_FLAG_FIPS 0x4000
+/* Allow non FIPS cipher in FIPS mode */
+#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000
+/* Cipher handles any and all padding logic as well
+ * as finalisation.
+ */
+#define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000
+#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
/* ctrl() values */
@@ -358,6 +374,33 @@ struct evp_cipher_st
#define EVP_CTRL_RAND_KEY 0x6
#define EVP_CTRL_PBE_PRF_NID 0x7
#define EVP_CTRL_COPY 0x8
+#define EVP_CTRL_GCM_SET_IVLEN 0x9
+#define EVP_CTRL_GCM_GET_TAG 0x10
+#define EVP_CTRL_GCM_SET_TAG 0x11
+#define EVP_CTRL_GCM_SET_IV_FIXED 0x12
+#define EVP_CTRL_GCM_IV_GEN 0x13
+#define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN
+#define EVP_CTRL_CCM_GET_TAG EVP_CTRL_GCM_GET_TAG
+#define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG
+#define EVP_CTRL_CCM_SET_L 0x14
+#define EVP_CTRL_CCM_SET_MSGLEN 0x15
+/* AEAD cipher deduces payload length and returns number of bytes
+ * required to store MAC and eventual padding. Subsequent call to
+ * EVP_Cipher even appends/verifies MAC.
+ */
+#define EVP_CTRL_AEAD_TLS1_AAD 0x16
+/* Used by composite AEAD ciphers, no-op in GCM, CCM... */
+#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+/* Set the GCM invocation field, decrypt only */
+#define EVP_CTRL_GCM_SET_IV_INV 0x18
+
+/* GCM TLS constants */
+/* Length of fixed part of IV derived from PRF */
+#define EVP_GCM_TLS_FIXED_IV_LEN 4
+/* Length of explicit part of IV part of TLS records */
+#define EVP_GCM_TLS_EXPLICIT_IV_LEN 8
+/* Length of tag for TLS */
+#define EVP_GCM_TLS_TAG_LEN 16
typedef struct evp_cipher_info_st
{
@@ -375,7 +418,7 @@ struct evp_cipher_ctx_st
unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */
- int num; /* used by cfb/ofb mode */
+ int num; /* used by cfb/ofb/ctr mode */
void *app_data; /* application stuff */
int key_len; /* May change for variable length cipher */
@@ -695,6 +738,9 @@ const EVP_MD *EVP_dev_crypto_md5(void);
#ifndef OPENSSL_NO_RC4
const EVP_CIPHER *EVP_rc4(void);
const EVP_CIPHER *EVP_rc4_40(void);
+#ifndef OPENSSL_NO_MD5
+const EVP_CIPHER *EVP_rc4_hmac_md5(void);
+#endif
#endif
#ifndef OPENSSL_NO_IDEA
const EVP_CIPHER *EVP_idea_ecb(void);
@@ -741,9 +787,10 @@ const EVP_CIPHER *EVP_aes_128_cfb8(void);
const EVP_CIPHER *EVP_aes_128_cfb128(void);
# define EVP_aes_128_cfb EVP_aes_128_cfb128
const EVP_CIPHER *EVP_aes_128_ofb(void);
-#if 0
const EVP_CIPHER *EVP_aes_128_ctr(void);
-#endif
+const EVP_CIPHER *EVP_aes_128_ccm(void);
+const EVP_CIPHER *EVP_aes_128_gcm(void);
+const EVP_CIPHER *EVP_aes_128_xts(void);
const EVP_CIPHER *EVP_aes_192_ecb(void);
const EVP_CIPHER *EVP_aes_192_cbc(void);
const EVP_CIPHER *EVP_aes_192_cfb1(void);
@@ -751,9 +798,9 @@ const EVP_CIPHER *EVP_aes_192_cfb8(void);
const EVP_CIPHER *EVP_aes_192_cfb128(void);
# define EVP_aes_192_cfb EVP_aes_192_cfb128
const EVP_CIPHER *EVP_aes_192_ofb(void);
-#if 0
const EVP_CIPHER *EVP_aes_192_ctr(void);
-#endif
+const EVP_CIPHER *EVP_aes_192_ccm(void);
+const EVP_CIPHER *EVP_aes_192_gcm(void);
const EVP_CIPHER *EVP_aes_256_ecb(void);
const EVP_CIPHER *EVP_aes_256_cbc(void);
const EVP_CIPHER *EVP_aes_256_cfb1(void);
@@ -761,8 +808,13 @@ const EVP_CIPHER *EVP_aes_256_cfb8(void);
const EVP_CIPHER *EVP_aes_256_cfb128(void);
# define EVP_aes_256_cfb EVP_aes_256_cfb128
const EVP_CIPHER *EVP_aes_256_ofb(void);
-#if 0
const EVP_CIPHER *EVP_aes_256_ctr(void);
+const EVP_CIPHER *EVP_aes_256_ccm(void);
+const EVP_CIPHER *EVP_aes_256_gcm(void);
+const EVP_CIPHER *EVP_aes_256_xts(void);
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
#endif
#endif
#ifndef OPENSSL_NO_CAMELLIA
@@ -1047,13 +1099,22 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
#define EVP_PKEY_CTRL_CMS_DECRYPT 10
#define EVP_PKEY_CTRL_CMS_SIGN 11
+#define EVP_PKEY_CTRL_CIPHER 12
+
#define EVP_PKEY_ALG_CTRL 0x1000
#define EVP_PKEY_FLAG_AUTOARGLEN 2
+/* Method handles all operations: don't assume any digest related
+ * defaults.
+ */
+#define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4
const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags);
+void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
+ const EVP_PKEY_METHOD *meth);
+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src);
void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
@@ -1071,7 +1132,7 @@ int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
- unsigned char *key, int keylen);
+ const unsigned char *key, int keylen);
void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
@@ -1181,6 +1242,8 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
int (*ctrl_str)(EVP_PKEY_CTX *ctx,
const char *type, const char *value));
+void EVP_add_alg_module(void);
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@@ -1190,8 +1253,14 @@ void ERR_load_EVP_strings(void);
/* Error codes for the EVP functions. */
/* Function codes. */
+#define EVP_F_AESNI_INIT_KEY 165
+#define EVP_F_AESNI_XTS_CIPHER 176
#define EVP_F_AES_INIT_KEY 133
+#define EVP_F_AES_XTS 172
+#define EVP_F_AES_XTS_CIPHER 175
+#define EVP_F_ALG_MODULE_INIT 177
#define EVP_F_CAMELLIA_INIT_KEY 159
+#define EVP_F_CMAC_INIT 173
#define EVP_F_D2I_PKEY 100
#define EVP_F_DO_SIGVER_INIT 161
#define EVP_F_DSAPKEY2PKCS8 134
@@ -1246,15 +1315,24 @@ void ERR_load_EVP_strings(void);
#define EVP_F_EVP_RIJNDAEL 126
#define EVP_F_EVP_SIGNFINAL 107
#define EVP_F_EVP_VERIFYFINAL 108
+#define EVP_F_FIPS_CIPHERINIT 166
+#define EVP_F_FIPS_CIPHER_CTX_COPY 170
+#define EVP_F_FIPS_CIPHER_CTX_CTRL 167
+#define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH 171
+#define EVP_F_FIPS_DIGESTINIT 168
+#define EVP_F_FIPS_MD_CTX_COPY 169
+#define EVP_F_HMAC_INIT_EX 174
#define EVP_F_INT_CTX_NEW 157
#define EVP_F_PKCS5_PBE_KEYIVGEN 117
#define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118
+#define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164
#define EVP_F_PKCS8_SET_BROKEN 112
#define EVP_F_PKEY_SET_TYPE 158
#define EVP_F_RC2_MAGIC_TO_METH 109
#define EVP_F_RC5_CTRL 125
/* Reason codes. */
+#define EVP_R_AES_IV_SETUP_FAILED 162
#define EVP_R_AES_KEY_SETUP_FAILED 143
#define EVP_R_ASN1_LIB 140
#define EVP_R_BAD_BLOCK_LENGTH 136
@@ -1272,16 +1350,21 @@ void ERR_load_EVP_strings(void);
#define EVP_R_DECODE_ERROR 114
#define EVP_R_DIFFERENT_KEY_TYPES 101
#define EVP_R_DIFFERENT_PARAMETERS 153
+#define EVP_R_DISABLED_FOR_FIPS 163
#define EVP_R_ENCODE_ERROR 115
+#define EVP_R_ERROR_LOADING_SECTION 165
+#define EVP_R_ERROR_SETTING_FIPS_MODE 166
#define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119
#define EVP_R_EXPECTING_AN_RSA_KEY 127
#define EVP_R_EXPECTING_A_DH_KEY 128
#define EVP_R_EXPECTING_A_DSA_KEY 129
#define EVP_R_EXPECTING_A_ECDSA_KEY 141
#define EVP_R_EXPECTING_A_EC_KEY 142
+#define EVP_R_FIPS_MODE_NOT_SUPPORTED 167
#define EVP_R_INITIALIZATION_ERROR 134
#define EVP_R_INPUT_NOT_INITIALIZED 111
#define EVP_R_INVALID_DIGEST 152
+#define EVP_R_INVALID_FIPS_MODE 168
#define EVP_R_INVALID_KEY_LENGTH 130
#define EVP_R_INVALID_OPERATION 148
#define EVP_R_IV_TOO_LARGE 102
@@ -1303,8 +1386,10 @@ void ERR_load_EVP_strings(void);
#define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
#define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146
#define EVP_R_PUBLIC_KEY_NOT_RSA 106
+#define EVP_R_TOO_LARGE 164
#define EVP_R_UNKNOWN_CIPHER 160
#define EVP_R_UNKNOWN_DIGEST 161
+#define EVP_R_UNKNOWN_OPTION 169
#define EVP_R_UNKNOWN_PBE_ALGORITHM 121
#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135
#define EVP_R_UNSUPPORTED_ALGORITHM 156
diff --git a/deps/openssl/openssl/crypto/evp/evp_cnf.c b/deps/openssl/openssl/crypto/evp/evp_cnf.c
new file mode 100644
index 000000000..2e4db3023
--- /dev/null
+++ b/deps/openssl/openssl/crypto/evp/evp_cnf.c
@@ -0,0 +1,125 @@
+/* evp_cnf.c */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 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
+ * licensing@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).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
+
+/* Algorithm configuration module. */
+
+static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
+ {
+ int i;
+ const char *oid_section;
+ STACK_OF(CONF_VALUE) *sktmp;
+ CONF_VALUE *oval;
+ oid_section = CONF_imodule_get_value(md);
+ if(!(sktmp = NCONF_get_section(cnf, oid_section)))
+ {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
+ return 0;
+ }
+ for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
+ {
+ oval = sk_CONF_VALUE_value(sktmp, i);
+ if (!strcmp(oval->name, "fips_mode"))
+ {
+ int m;
+ if (!X509V3_get_value_bool(oval, &m))
+ {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
+ return 0;
+ }
+ if (m > 0)
+ {
+#ifdef OPENSSL_FIPS
+ if (!FIPS_mode() && !FIPS_mode_set(1))
+ {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE);
+ return 0;
+ }
+#else
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
+ return 0;
+#endif
+ }
+ }
+ else
+ {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
+ ERR_add_error_data(4, "name=", oval->name,
+ ", value=", oval->value);
+ }
+
+ }
+ return 1;
+ }
+
+void EVP_add_alg_module(void)
+ {
+ CONF_module_add("alg_section", alg_module_init, 0);
+ }
diff --git a/deps/openssl/openssl/crypto/evp/evp_enc.c b/deps/openssl/openssl/crypto/evp/evp_enc.c
index c268d25cb..0c54f05e6 100644
--- a/deps/openssl/openssl/crypto/evp/evp_enc.c
+++ b/deps/openssl/openssl/crypto/evp/evp_enc.c
@@ -64,8 +64,18 @@
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
#include "evp_locl.h"
+#ifdef OPENSSL_FIPS
+#define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl)
+#else
+#define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl)
+#endif
+
+
const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
@@ -115,10 +125,14 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp
/* Ensure a context left lying around from last time is cleared
* (the previous check attempted to avoid this if the same
* ENGINE and EVP_CIPHER could be used). */
- EVP_CIPHER_CTX_cleanup(ctx);
-
- /* Restore encrypt field: it is zeroed by cleanup */
- ctx->encrypt = enc;
+ if (ctx->cipher)
+ {
+ unsigned long flags = ctx->flags;
+ EVP_CIPHER_CTX_cleanup(ctx);
+ /* Restore encrypt and flags */
+ ctx->encrypt = enc;
+ ctx->flags = flags;
+ }
#ifndef OPENSSL_NO_ENGINE
if(impl)
{
@@ -155,6 +169,10 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp
ctx->engine = NULL;
#endif
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_cipherinit(ctx, cipher, key, iv, enc);
+#endif
ctx->cipher=cipher;
if (ctx->cipher->ctx_size)
{
@@ -188,6 +206,10 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp
#ifndef OPENSSL_NO_ENGINE
skip_to_init:
#endif
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_cipherinit(ctx, cipher, key, iv, enc);
+#endif
/* we assume block size is a power of 2 in *cryptUpdate */
OPENSSL_assert(ctx->cipher->block_size == 1
|| ctx->cipher->block_size == 8
@@ -214,6 +236,13 @@ skip_to_init:
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
break;
+ case EVP_CIPH_CTR_MODE:
+ ctx->num = 0;
+ /* Don't reuse IV for CTR mode */
+ if(iv)
+ memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+ break;
+
default:
return 0;
break;
@@ -280,6 +309,16 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
{
int i,j,bl;
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+ {
+ i = M_do_cipher(ctx, out, in, inl);
+ if (i < 0)
+ return 0;
+ else
+ *outl = i;
+ return 1;
+ }
+
if (inl <= 0)
{
*outl = 0;
@@ -288,7 +327,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
{
- if(ctx->cipher->do_cipher(ctx,out,in,inl))
+ if(M_do_cipher(ctx,out,in,inl))
{
*outl=inl;
return 1;
@@ -315,7 +354,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
{
j=bl-i;
memcpy(&(ctx->buf[i]),in,j);
- if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
+ if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0;
inl-=j;
in+=j;
out+=bl;
@@ -328,7 +367,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
inl-=i;
if (inl > 0)
{
- if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
+ if(!M_do_cipher(ctx,out,in,inl)) return 0;
*outl+=inl;
}
@@ -350,6 +389,16 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int n,ret;
unsigned int i, b, bl;
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+ {
+ ret = M_do_cipher(ctx, out, NULL, 0);
+ if (ret < 0)
+ return 0;
+ else
+ *outl = ret;
+ return 1;
+ }
+
b=ctx->cipher->block_size;
OPENSSL_assert(b <= sizeof ctx->buf);
if (b == 1)
@@ -372,7 +421,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
n=b-bl;
for (i=bl; i<b; i++)
ctx->buf[i]=n;
- ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
+ ret=M_do_cipher(ctx,out,ctx->buf,b);
if(ret)
@@ -387,6 +436,19 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
int fix_len;
unsigned int b;
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+ {
+ fix_len = M_do_cipher(ctx, out, in, inl);
+ if (fix_len < 0)
+ {
+ *outl = 0;
+ return 0;
+ }
+ else
+ *outl = fix_len;
+ return 1;
+ }
+
if (inl <= 0)
{
*outl = 0;
@@ -440,8 +502,18 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int i,n;
unsigned int b;
-
*outl=0;
+
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+ {
+ i = M_do_cipher(ctx, out, NULL, 0);
+ if (i < 0)
+ return 0;
+ else
+ *outl = i;
+ return 1;
+ }
+
b=ctx->cipher->block_size;
if (ctx->flags & EVP_CIPH_NO_PADDING)
{
@@ -496,6 +568,7 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
{
+#ifndef OPENSSL_FIPS
if (c->cipher != NULL)
{
if(c->cipher->cleanup && !c->cipher->cleanup(c))
@@ -506,12 +579,16 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
}
if (c->cipher_data)
OPENSSL_free(c->cipher_data);
+#endif
#ifndef OPENSSL_NO_ENGINE
if (c->engine)
/* The EVP_CIPHER we used belongs to an ENGINE, release the
* functional reference we held for this reason. */
ENGINE_finish(c->engine);
#endif
+#ifdef OPENSSL_FIPS
+ FIPS_cipher_ctx_cleanup(c);
+#endif
memset(c,0,sizeof(EVP_CIPHER_CTX));
return 1;
}
diff --git a/deps/openssl/openssl/crypto/evp/evp_err.c b/deps/openssl/openssl/crypto/evp/evp_err.c
index d8bfec095..08eab9882 100644
--- a/deps/openssl/openssl/crypto/evp/evp_err.c
+++ b/deps/openssl/openssl/crypto/evp/evp_err.c
@@ -1,6 +1,6 @@
/* crypto/evp/evp_err.c */
/* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -70,8 +70,14 @@
static ERR_STRING_DATA EVP_str_functs[]=
{
+{ERR_FUNC(EVP_F_AESNI_INIT_KEY), "AESNI_INIT_KEY"},
+{ERR_FUNC(EVP_F_AESNI_XTS_CIPHER), "AESNI_XTS_CIPHER"},
{ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"},
+{ERR_FUNC(EVP_F_AES_XTS), "AES_XTS"},
+{ERR_FUNC(EVP_F_AES_XTS_CIPHER), "AES_XTS_CIPHER"},
+{ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"},
{ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"},
+{ERR_FUNC(EVP_F_CMAC_INIT), "CMAC_INIT"},
{ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"},
{ERR_FUNC(EVP_F_DO_SIGVER_INIT), "DO_SIGVER_INIT"},
{ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"},
@@ -86,7 +92,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
{ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
{ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
{ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"},
-{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_SIZE"},
+{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"},
{ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"},
{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"},
{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"},
@@ -126,9 +132,17 @@ static ERR_STRING_DATA EVP_str_functs[]=
{ERR_FUNC(EVP_F_EVP_RIJNDAEL), "EVP_RIJNDAEL"},
{ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"},
{ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"},
+{ERR_FUNC(EVP_F_FIPS_CIPHERINIT), "FIPS_CIPHERINIT"},
+{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_COPY), "FIPS_CIPHER_CTX_COPY"},
+{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"},
+{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH), "FIPS_CIPHER_CTX_SET_KEY_LENGTH"},
+{ERR_FUNC(EVP_F_FIPS_DIGESTINIT), "FIPS_DIGESTINIT"},
+{ERR_FUNC(EVP_F_FIPS_MD_CTX_COPY), "FIPS_MD_CTX_COPY"},
+{ERR_FUNC(EVP_F_HMAC_INIT_EX), "HMAC_Init_ex"},
{ERR_FUNC(EVP_F_INT_CTX_NEW), "INT_CTX_NEW"},
{ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"},
{ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"},
+{ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_V2_PBKDF2_KEYIVGEN"},
{ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"},
{ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"},
{ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"},
@@ -138,6 +152,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
static ERR_STRING_DATA EVP_str_reasons[]=
{
+{ERR_REASON(EVP_R_AES_IV_SETUP_FAILED) ,"aes iv setup failed"},
{ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED) ,"aes key setup failed"},
{ERR_REASON(EVP_R_ASN1_LIB) ,"asn1 lib"},
{ERR_REASON(EVP_R_BAD_BLOCK_LENGTH) ,"bad block length"},
@@ -155,16 +170,21 @@ static ERR_STRING_DATA EVP_str_reasons[]=
{ERR_REASON(EVP_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) ,"different key types"},
{ERR_REASON(EVP_R_DIFFERENT_PARAMETERS) ,"different parameters"},
+{ERR_REASON(EVP_R_DISABLED_FOR_FIPS) ,"disabled for fips"},
{ERR_REASON(EVP_R_ENCODE_ERROR) ,"encode error"},
+{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"},
+{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"},
{ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
{ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) ,"expecting an rsa key"},
{ERR_REASON(EVP_R_EXPECTING_A_DH_KEY) ,"expecting a dh key"},
{ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY) ,"expecting a dsa key"},
{ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"},
{ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) ,"expecting a ec key"},
+{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
{ERR_REASON(EVP_R_INITIALIZATION_ERROR) ,"initialization error"},
{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
{ERR_REASON(EVP_R_INVALID_DIGEST) ,"invalid digest"},
+{ERR_REASON(EVP_R_INVALID_FIPS_MODE) ,"invalid fips mode"},
{ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"},
{ERR_REASON(EVP_R_INVALID_OPERATION) ,"invalid operation"},
{ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"},
@@ -186,8 +206,10 @@ static ERR_STRING_DATA EVP_str_reasons[]=
{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR),"private key decode error"},
{ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR),"private key encode error"},
{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"},
+{ERR_REASON(EVP_R_TOO_LARGE) ,"too large"},
{ERR_REASON(EVP_R_UNKNOWN_CIPHER) ,"unknown cipher"},
{ERR_REASON(EVP_R_UNKNOWN_DIGEST) ,"unknown digest"},
+{ERR_REASON(EVP_R_UNKNOWN_OPTION) ,"unknown option"},
{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"},
diff --git a/deps/openssl/openssl/crypto/evp/evp_fips.c b/deps/openssl/openssl/crypto/evp/evp_fips.c
new file mode 100644
index 000000000..cb7f4fc0f
--- /dev/null
+++ b/deps/openssl/openssl/crypto/evp/evp_fips.c
@@ -0,0 +1,113 @@
+/* crypto/evp/evp_fips.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 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
+ * licensing@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.
+ * ====================================================================
+ */
+
+
+#include <openssl/evp.h>
+
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+
+const EVP_CIPHER *EVP_aes_128_cbc(void) { return FIPS_evp_aes_128_cbc(); }
+const EVP_CIPHER *EVP_aes_128_ccm(void) { return FIPS_evp_aes_128_ccm(); }
+const EVP_CIPHER *EVP_aes_128_cfb1(void) { return FIPS_evp_aes_128_cfb1(); }
+const EVP_CIPHER *EVP_aes_128_cfb128(void) { return FIPS_evp_aes_128_cfb128(); }
+const EVP_CIPHER *EVP_aes_128_cfb8(void) { return FIPS_evp_aes_128_cfb8(); }
+const EVP_CIPHER *EVP_aes_128_ctr(void) { return FIPS_evp_aes_128_ctr(); }
+const EVP_CIPHER *EVP_aes_128_ecb(void) { return FIPS_evp_aes_128_ecb(); }
+const EVP_CIPHER *EVP_aes_128_gcm(void) { return FIPS_evp_aes_128_gcm(); }
+const EVP_CIPHER *EVP_aes_128_ofb(void) { return FIPS_evp_aes_128_ofb(); }
+const EVP_CIPHER *EVP_aes_128_xts(void) { return FIPS_evp_aes_128_xts(); }
+const EVP_CIPHER *EVP_aes_192_cbc(void) { return FIPS_evp_aes_192_cbc(); }
+const EVP_CIPHER *EVP_aes_192_ccm(void) { return FIPS_evp_aes_192_ccm(); }
+const EVP_CIPHER *EVP_aes_192_cfb1(void) { return FIPS_evp_aes_192_cfb1(); }
+const EVP_CIPHER *EVP_aes_192_cfb128(void) { return FIPS_evp_aes_192_cfb128(); }
+const EVP_CIPHER *EVP_aes_192_cfb8(void) { return FIPS_evp_aes_192_cfb8(); }
+const EVP_CIPHER *EVP_aes_192_ctr(void) { return FIPS_evp_aes_192_ctr(); }
+const EVP_CIPHER *EVP_aes_192_ecb(void) { return FIPS_evp_aes_192_ecb(); }
+const EVP_CIPHER *EVP_aes_192_gcm(void) { return FIPS_evp_aes_192_gcm(); }
+const EVP_CIPHER *EVP_aes_192_ofb(void) { return FIPS_evp_aes_192_ofb(); }
+const EVP_CIPHER *EVP_aes_256_cbc(void) { return FIPS_evp_aes_256_cbc(); }
+const EVP_CIPHER *EVP_aes_256_ccm(void) { return FIPS_evp_aes_256_ccm(); }
+const EVP_CIPHER *EVP_aes_256_cfb1(void) { return FIPS_evp_aes_256_cfb1(); }
+const EVP_CIPHER *EVP_aes_256_cfb128(void) { return FIPS_evp_aes_256_cfb128(); }
+const EVP_CIPHER *EVP_aes_256_cfb8(void) { return FIPS_evp_aes_256_cfb8(); }
+const EVP_CIPHER *EVP_aes_256_ctr(void) { return FIPS_evp_aes_256_ctr(); }
+const EVP_CIPHER *EVP_aes_256_ecb(void) { return FIPS_evp_aes_256_ecb(); }
+const EVP_CIPHER *EVP_aes_256_gcm(void) { return FIPS_evp_aes_256_gcm(); }
+const EVP_CIPHER *EVP_aes_256_ofb(void) { return FIPS_evp_aes_256_ofb(); }
+const EVP_CIPHER *EVP_aes_256_xts(void) { return FIPS_evp_aes_256_xts(); }
+const EVP_CIPHER *EVP_des_ede(void) { return FIPS_evp_des_ede(); }
+const EVP_CIPHER *EVP_des_ede3(void) { return FIPS_evp_des_ede3(); }
+const EVP_CIPHER *EVP_des_ede3_cbc(void) { return FIPS_evp_des_ede3_cbc(); }
+const EVP_CIPHER *EVP_des_ede3_cfb1(void) { return FIPS_evp_des_ede3_cfb1(); }
+const EVP_CIPHER *EVP_des_ede3_cfb64(void) { return FIPS_evp_des_ede3_cfb64(); }
+const EVP_CIPHER *EVP_des_ede3_cfb8(void) { return FIPS_evp_des_ede3_cfb8(); }
+const EVP_CIPHER *EVP_des_ede3_ecb(void) { return FIPS_evp_des_ede3_ecb(); }
+const EVP_CIPHER *EVP_des_ede3_ofb(void) { return FIPS_evp_des_ede3_ofb(); }
+const EVP_CIPHER *EVP_des_ede_cbc(void) { return FIPS_evp_des_ede_cbc(); }
+const EVP_CIPHER *EVP_des_ede_cfb64(void) { return FIPS_evp_des_ede_cfb64(); }
+const EVP_CIPHER *EVP_des_ede_ecb(void) { return FIPS_evp_des_ede_ecb(); }
+const EVP_CIPHER *EVP_des_ede_ofb(void) { return FIPS_evp_des_ede_ofb(); }
+const EVP_CIPHER *EVP_enc_null(void) { return FIPS_evp_enc_null(); }
+
+const EVP_MD *EVP_sha1(void) { return FIPS_evp_sha1(); }
+const EVP_MD *EVP_sha224(void) { return FIPS_evp_sha224(); }
+const EVP_MD *EVP_sha256(void) { return FIPS_evp_sha256(); }
+const EVP_MD *EVP_sha384(void) { return FIPS_evp_sha384(); }
+const EVP_MD *EVP_sha512(void) { return FIPS_evp_sha512(); }
+
+const EVP_MD *EVP_dss(void) { return FIPS_evp_dss(); }
+const EVP_MD *EVP_dss1(void) { return FIPS_evp_dss1(); }
+const EVP_MD *EVP_ecdsa(void) { return FIPS_evp_ecdsa(); }
+
+#endif
diff --git a/deps/openssl/openssl/crypto/evp/evp_key.c b/deps/openssl/openssl/crypto/evp/evp_key.c
index 839d6a3a1..7961fbebf 100644
--- a/deps/openssl/openssl/crypto/evp/evp_key.c
+++ b/deps/openssl/openssl/crypto/evp/evp_key.c
@@ -120,7 +120,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
unsigned char md_buf[EVP_MAX_MD_SIZE];
int niv,nkey,addmd=0;
unsigned int mds=0,i;
-
+ int rv = 0;
nkey=type->key_len;
niv=type->iv_len;
OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
@@ -134,17 +134,24 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
if (!EVP_DigestInit_ex(&c,md, NULL))
return 0;
if (addmd++)
- EVP_DigestUpdate(&c,&(md_buf[0]),mds);
- EVP_DigestUpdate(&c,data,datal);
+ if (!EVP_DigestUpdate(&c,&(md_buf[0]),mds))
+ goto err;
+ if (!EVP_DigestUpdate(&c,data,datal))
+ goto err;
if (salt != NULL)
- EVP_DigestUpdate(&c,salt,PKCS5_SALT_LEN);
- EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds);
+ if (!EVP_DigestUpdate(&c,salt,PKCS5_SALT_LEN))
+ goto err;
+ if (!EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds))
+ goto err;
for (i=1; i<(unsigned int)count; i++)
{
- EVP_DigestInit_ex(&c,md, NULL);
- EVP_DigestUpdate(&c,&(md_buf[0]),mds);
- EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds);
+ if (!EVP_DigestInit_ex(&c,md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&c,&(md_buf[0]),mds))
+ goto err;
+ if (!EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds))
+ goto err;
}
i=0;
if (nkey)
@@ -173,8 +180,10 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
}
if ((nkey == 0) && (niv == 0)) break;
}
+ rv = type->key_len;
+ err:
EVP_MD_CTX_cleanup(&c);
OPENSSL_cleanse(&(md_buf[0]),EVP_MAX_MD_SIZE);
- return(type->key_len);
+ return rv;
}
diff --git a/deps/openssl/openssl/crypto/evp/evp_lib.c b/deps/openssl/openssl/crypto/evp/evp_lib.c
index 40951a04f..b180e4828 100644
--- a/deps/openssl/openssl/crypto/evp/evp_lib.c
+++ b/deps/openssl/openssl/crypto/evp/evp_lib.c
@@ -67,6 +67,8 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
if (c->cipher->set_asn1_parameters != NULL)
ret=c->cipher->set_asn1_parameters(c,type);
+ else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
+ ret=EVP_CIPHER_set_asn1_iv(c, type);
else
ret=-1;
return(ret);
@@ -78,6 +80,8 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
if (c->cipher->get_asn1_parameters != NULL)
ret=c->cipher->get_asn1_parameters(c,type);
+ else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
+ ret=EVP_CIPHER_get_asn1_iv(c, type);
else
ret=-1;
return(ret);
diff --git a/deps/openssl/openssl/crypto/evp/evp_locl.h b/deps/openssl/openssl/crypto/evp/evp_locl.h
index 292d74c18..08c0a66d3 100644
--- a/deps/openssl/openssl/crypto/evp/evp_locl.h
+++ b/deps/openssl/openssl/crypto/evp/evp_locl.h
@@ -343,3 +343,43 @@ struct evp_pkey_method_st
} /* EVP_PKEY_METHOD */;
void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+ ASN1_TYPE *param,
+ const EVP_CIPHER *c, const EVP_MD *md, int en_de);
+
+#ifdef OPENSSL_FIPS
+
+#ifdef OPENSSL_DOING_MAKEDEPEND
+#undef SHA1_Init
+#undef SHA1_Update
+#undef SHA224_Init
+#undef SHA256_Init
+#undef SHA384_Init
+#undef SHA512_Init
+#undef DES_set_key_unchecked
+#endif
+
+#define RIPEMD160_Init private_RIPEMD160_Init
+#define WHIRLPOOL_Init private_WHIRLPOOL_Init
+#define MD5_Init private_MD5_Init
+#define MD4_Init private_MD4_Init
+#define MD2_Init private_MD2_Init
+#define MDC2_Init private_MDC2_Init
+#define SHA_Init private_SHA_Init
+#define SHA1_Init private_SHA1_Init
+#define SHA224_Init private_SHA224_Init
+#define SHA256_Init private_SHA256_Init
+#define SHA384_Init private_SHA384_Init
+#define SHA512_Init private_SHA512_Init
+
+#define BF_set_key private_BF_set_key
+#define CAST_set_key private_CAST_set_key
+#define idea_set_encrypt_key private_idea_set_encrypt_key
+#define SEED_set_key private_SEED_set_key
+#define RC2_set_key private_RC2_set_key
+#define RC4_set_key private_RC4_set_key
+#define DES_set_key_unchecked private_DES_set_key_unchecked
+#define Camellia_set_key private_Camellia_set_key
+
+#endif
diff --git a/deps/openssl/openssl/crypto/evp/evp_pbe.c b/deps/openssl/openssl/crypto/evp/evp_pbe.c
index c9d932d20..f8c32d825 100644
--- a/deps/openssl/openssl/crypto/evp/evp_pbe.c
+++ b/deps/openssl/openssl/crypto/evp/evp_pbe.c
@@ -61,6 +61,7 @@
#include <openssl/evp.h>
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
+#include "evp_locl.h"
/* Password based encryption (PBE) functions */
@@ -87,6 +88,10 @@ static const EVP_PBE_CTL builtin_pbe[] =
{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+#ifndef OPENSSL_NO_HMAC
+ {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
+#endif
+
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
diff --git a/deps/openssl/openssl/crypto/evp/evptests.txt b/deps/openssl/openssl/crypto/evp/evptests.txt
index beb12144b..c273707c1 100644
--- a/deps/openssl/openssl/crypto/evp/evptests.txt
+++ b/deps/openssl/openssl/crypto/evp/evptests.txt
@@ -158,6 +158,19 @@ AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7B
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0
+# AES Counter test vectors from RFC3686
+aes-128-ctr:AE6852F8121067CC4BF7A5765577F39E:00000030000000000000000000000001:53696E676C6520626C6F636B206D7367:E4095D4FB7A7B3792D6175A3261311B8:1
+aes-128-ctr:7E24067817FAE0D743D6CE1F32539163:006CB6DBC0543B59DA48D90B00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28:1
+aes-128-ctr:7691BE035E5020A8AC6E618529F9A0DC:00E0017B27777F3F4A1786F000000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F:1
+
+aes-192-ctr:16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515:0000004836733C147D6D93CB00000001:53696E676C6520626C6F636B206D7367:4B55384FE259C9C84E7935A003CBE928:1
+aes-192-ctr:7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A:0096B03B020C6EADC2CB500D00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00:1
+aes-192-ctr:02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE:0007BDFD5CBD60278DCC091200000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935:1
+
+aes-256-ctr:776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104:00000060DB5672C97AA8F0B200000001:53696E676C6520626C6F636B206D7367:145AD01DBF824EC7560863DC71E3E0C0:1
+aes-256-ctr:F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884:00FAAC24C1585EF15A43D87500000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C:1
+aes-256-ctr:FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D:001CC5B751A51D70A1C1114800000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8:1
+
# DES ECB tests (from destest)
DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7
diff --git a/deps/openssl/openssl/crypto/evp/m_dss.c b/deps/openssl/openssl/crypto/evp/m_dss.c
index 48c268950..6fb7e9a86 100644
--- a/deps/openssl/openssl/crypto/evp/m_dss.c
+++ b/deps/openssl/openssl/crypto/evp/m_dss.c
@@ -60,12 +60,13 @@
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_SHA
+#ifndef OPENSSL_FIPS
static int init(EVP_MD_CTX *ctx)
{ return SHA1_Init(ctx->md_data); }
@@ -97,3 +98,4 @@ const EVP_MD *EVP_dss(void)
return(&dsa_md);
}
#endif
+#endif
diff --git a/deps/openssl/openssl/crypto/evp/m_dss1.c b/deps/openssl/openssl/crypto/evp/m_dss1.c
index 4f03fb70e..2df362a67 100644
--- a/deps/openssl/openssl/crypto/evp/m_dss1.c
+++ b/deps/openssl/openssl/crypto/evp/m_dss1.c
@@ -63,11 +63,13 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
+#ifndef OPENSSL_FIPS
+
static int init(EVP_MD_CTX *ctx)
{ return SHA1_Init(ctx->md_data); }
@@ -98,3 +100,4 @@ const EVP_MD *EVP_dss1(void)
return(&dss1_md);
}
#endif
+#endif
diff --git a/deps/openssl/openssl/crypto/evp/m_ecdsa.c b/deps/openssl/openssl/crypto/evp/m_ecdsa.c
index 8d87a49eb..4b15fb0f6 100644
--- a/deps/openssl/openssl/crypto/evp/m_ecdsa.c
+++ b/deps/openssl/openssl/crypto/evp/m_ecdsa.c
@@ -116,6 +116,8 @@
#include <openssl/x509.h>
#ifndef OPENSSL_NO_SHA
+#ifndef OPENSSL_FIPS
+
static int init(EVP_MD_CTX *ctx)
{ return SHA1_Init(ctx->md_data); }
@@ -146,3 +148,4 @@ const EVP_MD *EVP_ecdsa(void)
return(&ecdsa_md);
}
#endif
+#endif
diff --git a/deps/openssl/openssl/crypto/evp/m_md4.c b/deps/openssl/openssl/crypto/evp/m_md4.c
index 1e0b7c5b4..6d47f61b2 100644
--- a/deps/openssl/openssl/crypto/evp/m_md4.c
+++ b/deps/openssl/openssl/crypto/evp/m_md4.c
@@ -69,6 +69,8 @@
#include <openssl/rsa.h>
#endif
+#include "evp_locl.h"
+
static int init(EVP_MD_CTX *ctx)
{ return MD4_Init(ctx->md_data); }
diff --git a/deps/openssl/openssl/crypto/evp/m_md5.c b/deps/openssl/openssl/crypto/evp/m_md5.c
index 63c142119..9a8bae025 100644
--- a/deps/openssl/openssl/crypto/evp/m_md5.c
+++ b/deps/openssl/openssl/crypto/evp/m_md5.c
@@ -68,6 +68,7 @@
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
+#include "evp_locl.h"
static int init(EVP_MD_CTX *ctx)
{ return MD5_Init(ctx->md_data); }
diff --git a/deps/openssl/openssl/crypto/evp/m_mdc2.c b/deps/openssl/openssl/crypto/evp/m_mdc2.c
index b08d55980..3602bed31 100644
--- a/deps/openssl/openssl/crypto/evp/m_mdc2.c
+++ b/deps/openssl/openssl/crypto/evp/m_mdc2.c
@@ -69,6 +69,8 @@
#include <openssl/rsa.h>
#endif
+#include "evp_locl.h"
+
static int init(EVP_MD_CTX *ctx)
{ return MDC2_Init(ctx->md_data); }
diff --git a/deps/openssl/openssl/crypto/evp/m_ripemd.c b/deps/openssl/openssl/crypto/evp/m_ripemd.c
index a1d60ee78..7bf4804cf 100644
--- a/deps/openssl/openssl/crypto/evp/m_ripemd.c
+++ b/deps/openssl/openssl/crypto/evp/m_ripemd.c
@@ -68,6 +68,7 @@
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
+#include "evp_locl.h"
static int init(EVP_MD_CTX *ctx)
{ return RIPEMD160_Init(ctx->md_data); }
diff --git a/deps/openssl/openssl/crypto/evp/m_sha.c b/deps/openssl/openssl/crypto/evp/m_sha.c
index acccc8f92..8769cdd42 100644
--- a/deps/openssl/openssl/crypto/evp/m_sha.c
+++ b/deps/openssl/openssl/crypto/evp/m_sha.c
@@ -67,6 +67,7 @@
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
+#include "evp_locl.h"
static int init(EVP_MD_CTX *ctx)
{ return SHA_Init(ctx->md_data); }
diff --git a/deps/openssl/openssl/crypto/evp/m_sha1.c b/deps/openssl/openssl/crypto/evp/m_sha1.c
index 9a2790fde..bd0c01ad3 100644
--- a/deps/openssl/openssl/crypto/evp/m_sha1.c
+++ b/deps/openssl/openssl/crypto/evp/m_sha1.c
@@ -59,15 +59,18 @@
#include <stdio.h>
#include "cryptlib.h"
+#ifndef OPENSSL_FIPS
+
#ifndef OPENSSL_NO_SHA
#include <openssl/evp.h>
#include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
+
static int init(EVP_MD_CTX *ctx)
{ return SHA1_Init(ctx->md_data); }
@@ -202,3 +205,5 @@ static const EVP_MD sha512_md=
const EVP_MD *EVP_sha512(void)
{ return(&sha512_md); }
#endif /* ifndef OPENSSL_NO_SHA512 */
+
+#endif
diff --git a/deps/openssl/openssl/crypto/evp/m_wp.c b/deps/openssl/openssl/crypto/evp/m_wp.c
index 1ce47c040..c51bc2d5d 100644
--- a/deps/openssl/openssl/crypto/evp/m_wp.c
+++ b/deps/openssl/openssl/crypto/evp/m_wp.c
@@ -9,6 +9,7 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/whrlpool.h>
+#include "evp_locl.h"
static int init(EVP_MD_CTX *ctx)
{ return WHIRLPOOL_Init(ctx->md_data); }
diff --git a/deps/openssl/openssl/crypto/evp/names.c b/deps/openssl/openssl/crypto/evp/names.c
index f2869f5c7..6311ad7cf 100644
--- a/deps/openssl/openssl/crypto/evp/names.c
+++ b/deps/openssl/openssl/crypto/evp/names.c
@@ -66,6 +66,10 @@ int EVP_add_cipher(const EVP_CIPHER *c)
{
int r;
+ if (c == NULL) return 0;
+
+ OPENSSL_init();
+
r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
if (r == 0) return(0);
check_defer(c->nid);
@@ -78,6 +82,7 @@ int EVP_add_digest(const EVP_MD *md)
{
int r;
const char *name;
+ OPENSSL_init();
name=OBJ_nid2sn(md->type);
r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md);
diff --git a/deps/openssl/openssl/crypto/evp/p5_crpt.c b/deps/openssl/openssl/crypto/evp/p5_crpt.c
index 7ecfa8dad..294cc90d8 100644
--- a/deps/openssl/openssl/crypto/evp/p5_crpt.c
+++ b/deps/openssl/openssl/crypto/evp/p5_crpt.c
@@ -82,6 +82,8 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
unsigned char *salt;
const unsigned char *pbuf;
int mdsize;
+ int rv = 0;
+ EVP_MD_CTX_init(&ctx);
/* Extract useful info from parameter */
if (param == NULL || param->type != V_ASN1_SEQUENCE ||
@@ -104,29 +106,38 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
if(!pass) passlen = 0;
else if(passlen == -1) passlen = strlen(pass);
- EVP_MD_CTX_init(&ctx);
- EVP_DigestInit_ex(&ctx, md, NULL);
- EVP_DigestUpdate(&ctx, pass, passlen);
- EVP_DigestUpdate(&ctx, salt, saltlen);
+ if (!EVP_DigestInit_ex(&ctx, md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, pass, passlen))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, salt, saltlen))
+ goto err;
PBEPARAM_free(pbe);
- EVP_DigestFinal_ex(&ctx, md_tmp, NULL);
+ if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
+ goto err;
mdsize = EVP_MD_size(md);
if (mdsize < 0)
return 0;
for (i = 1; i < iter; i++) {
- EVP_DigestInit_ex(&ctx, md, NULL);
- EVP_DigestUpdate(&ctx, md_tmp, mdsize);
- EVP_DigestFinal_ex (&ctx, md_tmp, NULL);
+ if (!EVP_DigestInit_ex(&ctx, md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize))
+ goto err;
+ if (!EVP_DigestFinal_ex (&ctx, md_tmp, NULL))
+ goto err;
}
- EVP_MD_CTX_cleanup(&ctx);
OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
EVP_CIPHER_iv_length(cipher));
- EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de);
+ if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
+ goto err;
OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
- return 1;
+ rv = 1;
+ err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return rv;
}
diff --git a/deps/openssl/openssl/crypto/evp/p5_crpt2.c b/deps/openssl/openssl/crypto/evp/p5_crpt2.c
index 334379f31..975d004df 100644
--- a/deps/openssl/openssl/crypto/evp/p5_crpt2.c
+++ b/deps/openssl/openssl/crypto/evp/p5_crpt2.c
@@ -62,6 +62,7 @@
#include <openssl/x509.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#include "evp_locl.h"
/* set this to print out info about the keygen algorithm */
/* #define DEBUG_PKCS5V2 */
@@ -110,10 +111,14 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
itmp[1] = (unsigned char)((i >> 16) & 0xff);
itmp[2] = (unsigned char)((i >> 8) & 0xff);
itmp[3] = (unsigned char)(i & 0xff);
- HMAC_Init_ex(&hctx, pass, passlen, digest, NULL);
- HMAC_Update(&hctx, salt, saltlen);
- HMAC_Update(&hctx, itmp, 4);
- HMAC_Final(&hctx, digtmp, NULL);
+ if (!HMAC_Init_ex(&hctx, pass, passlen, digest, NULL)
+ || !HMAC_Update(&hctx, salt, saltlen)
+ || !HMAC_Update(&hctx, itmp, 4)
+ || !HMAC_Final(&hctx, digtmp, NULL))
+ {
+ HMAC_CTX_cleanup(&hctx);
+ return 0;
+ }
memcpy(p, digtmp, cplen);
for(j = 1; j < iter; j++)
{
@@ -168,27 +173,24 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md,
int en_de)
{
- unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
const unsigned char *pbuf;
- int saltlen, iter, plen;
- unsigned int keylen;
+ int plen;
PBE2PARAM *pbe2 = NULL;
const EVP_CIPHER *cipher;
- PBKDF2PARAM *kdf = NULL;
- const EVP_MD *prfmd;
- int prf_nid, hmac_md_nid;
+
+ int rv = 0;
if (param == NULL || param->type != V_ASN1_SEQUENCE ||
param->value.sequence == NULL) {
EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
- return 0;
+ goto err;
}
pbuf = param->value.sequence->data;
plen = param->value.sequence->length;
if(!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
- return 0;
+ goto err;
}
/* See if we recognise the key derivation function */
@@ -211,38 +213,63 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
}
/* Fixup cipher based on AlgorithmIdentifier */
- EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de);
+ if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
+ goto err;
if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
EVP_R_CIPHER_PARAMETER_ERROR);
goto err;
}
+ rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen,
+ pbe2->keyfunc->parameter, c, md, en_de);
+ err:
+ PBE2PARAM_free(pbe2);
+ return rv;
+}
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+ ASN1_TYPE *param,
+ const EVP_CIPHER *c, const EVP_MD *md, int en_de)
+{
+ unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
+ const unsigned char *pbuf;
+ int saltlen, iter, plen;
+ int rv = 0;
+ unsigned int keylen = 0;
+ int prf_nid, hmac_md_nid;
+ PBKDF2PARAM *kdf = NULL;
+ const EVP_MD *prfmd;
+
+ if (EVP_CIPHER_CTX_cipher(ctx) == NULL)
+ {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_NO_CIPHER_SET);
+ goto err;
+ }
keylen = EVP_CIPHER_CTX_key_length(ctx);
OPENSSL_assert(keylen <= sizeof key);
- /* Now decode key derivation function */
+ /* Decode parameter */
- if(!pbe2->keyfunc->parameter ||
- (pbe2->keyfunc->parameter->type != V_ASN1_SEQUENCE))
+ if(!param || (param->type != V_ASN1_SEQUENCE))
{
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_DECODE_ERROR);
goto err;
}
- pbuf = pbe2->keyfunc->parameter->value.sequence->data;
- plen = pbe2->keyfunc->parameter->value.sequence->length;
+ pbuf = param->value.sequence->data;
+ plen = param->value.sequence->length;
+
if(!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_DECODE_ERROR);
goto err;
}
- PBE2PARAM_free(pbe2);
- pbe2 = NULL;
+ keylen = EVP_CIPHER_CTX_key_length(ctx);
/* Now check the parameters of the kdf */
if(kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,
EVP_R_UNSUPPORTED_KEYLENGTH);
goto err;
}
@@ -254,19 +281,19 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0))
{
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
goto err;
}
prfmd = EVP_get_digestbynid(hmac_md_nid);
if (prfmd == NULL)
{
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
goto err;
}
if(kdf->salt->type != V_ASN1_OCTET_STRING) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,
EVP_R_UNSUPPORTED_SALT_TYPE);
goto err;
}
@@ -278,15 +305,11 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
keylen, key))
goto err;
- EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
- OPENSSL_cleanse(key, keylen);
- PBKDF2PARAM_free(kdf);
- return 1;
-
+ rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
err:
- PBE2PARAM_free(pbe2);
+ OPENSSL_cleanse(key, keylen);
PBKDF2PARAM_free(kdf);
- return 0;
+ return rv;
}
#ifdef DEBUG_PKCS5V2
diff --git a/deps/openssl/openssl/crypto/evp/p_open.c b/deps/openssl/openssl/crypto/evp/p_open.c
index 53a59a295..c748fbea8 100644
--- a/deps/openssl/openssl/crypto/evp/p_open.c
+++ b/deps/openssl/openssl/crypto/evp/p_open.c
@@ -115,7 +115,8 @@ int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int i;
i=EVP_DecryptFinal_ex(ctx,out,outl);
- EVP_DecryptInit_ex(ctx,NULL,NULL,NULL,NULL);
+ if (i)
+ i = EVP_DecryptInit_ex(ctx,NULL,NULL,NULL,NULL);
return(i);
}
#else /* !OPENSSL_NO_RSA */
diff --git a/deps/openssl/openssl/crypto/evp/p_seal.c b/deps/openssl/openssl/crypto/evp/p_seal.c
index d8324526e..e5919b0fb 100644
--- a/deps/openssl/openssl/crypto/evp/p_seal.c
+++ b/deps/openssl/openssl/crypto/evp/p_seal.c
@@ -110,6 +110,7 @@ int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int i;
i = EVP_EncryptFinal_ex(ctx,out,outl);
- EVP_EncryptInit_ex(ctx,NULL,NULL,NULL,NULL);
+ if (i)
+ i = EVP_EncryptInit_ex(ctx,NULL,NULL,NULL,NULL);
return i;
}
diff --git a/deps/openssl/openssl/crypto/evp/p_sign.c b/deps/openssl/openssl/crypto/evp/p_sign.c
index bb893f5bd..8afb66430 100644
--- a/deps/openssl/openssl/crypto/evp/p_sign.c
+++ b/deps/openssl/openssl/crypto/evp/p_sign.c
@@ -80,18 +80,20 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
{
unsigned char m[EVP_MAX_MD_SIZE];
unsigned int m_len;
- int i,ok=0,v;
+ int i = 0,ok = 0,v;
EVP_MD_CTX tmp_ctx;
+ EVP_PKEY_CTX *pkctx = NULL;
*siglen=0;
EVP_MD_CTX_init(&tmp_ctx);
- EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
- EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
+ goto err;
+ if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len))
+ goto err;
EVP_MD_CTX_cleanup(&tmp_ctx);
if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
{
- EVP_PKEY_CTX *pkctx = NULL;
size_t sltmp = (size_t)EVP_PKEY_size(pkey);
i = 0;
pkctx = EVP_PKEY_CTX_new(pkey, NULL);
diff --git a/deps/openssl/openssl/crypto/evp/p_verify.c b/deps/openssl/openssl/crypto/evp/p_verify.c
index 41d4b6713..c66d63ccf 100644
--- a/deps/openssl/openssl/crypto/evp/p_verify.c
+++ b/deps/openssl/openssl/crypto/evp/p_verify.c
@@ -67,17 +67,19 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
{
unsigned char m[EVP_MAX_MD_SIZE];
unsigned int m_len;
- int i,ok=0,v;
+ int i = 0,ok = 0,v;
EVP_MD_CTX tmp_ctx;
+ EVP_PKEY_CTX *pkctx = NULL;
EVP_MD_CTX_init(&tmp_ctx);
- EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
- EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
+ goto err;
+ if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len))
+ goto err;
EVP_MD_CTX_cleanup(&tmp_ctx);
if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
{
- EVP_PKEY_CTX *pkctx = NULL;
i = -1;
pkctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!pkctx)
diff --git a/deps/openssl/openssl/crypto/evp/pmeth_gn.c b/deps/openssl/openssl/crypto/evp/pmeth_gn.c
index 5d74161a0..4651c8137 100644
--- a/deps/openssl/openssl/crypto/evp/pmeth_gn.c
+++ b/deps/openssl/openssl/crypto/evp/pmeth_gn.c
@@ -199,7 +199,7 @@ int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
}
EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
- unsigned char *key, int keylen)
+ const unsigned char *key, int keylen)
{
EVP_PKEY_CTX *mac_ctx = NULL;
EVP_PKEY *mac_key = NULL;
@@ -209,7 +209,8 @@ EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
goto merr;
if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
- EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key) <= 0)
+ EVP_PKEY_CTRL_SET_MAC_KEY,
+ keylen, (void *)key) <= 0)
goto merr;
if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
goto merr;
diff --git a/deps/openssl/openssl/crypto/evp/pmeth_lib.c b/deps/openssl/openssl/crypto/evp/pmeth_lib.c
index 5481d4b8a..acfa7b6f8 100644
--- a/deps/openssl/openssl/crypto/evp/pmeth_lib.c
+++ b/deps/openssl/openssl/crypto/evp/pmeth_lib.c
@@ -73,7 +73,7 @@ DECLARE_STACK_OF(EVP_PKEY_METHOD)
STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
-extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth;
+extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth;
static const EVP_PKEY_METHOD *standard_methods[] =
{
@@ -90,6 +90,7 @@ static const EVP_PKEY_METHOD *standard_methods[] =
&ec_pkey_meth,
#endif
&hmac_pkey_meth,
+ &cmac_pkey_meth
};
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
@@ -203,6 +204,8 @@ EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags)
if (!pmeth)
return NULL;
+ memset(pmeth, 0, sizeof(EVP_PKEY_METHOD));
+
pmeth->pkey_id = id;
pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
@@ -235,6 +238,56 @@ EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags)
return pmeth;
}
+void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
+ const EVP_PKEY_METHOD *meth)
+ {
+ if (ppkey_id)
+ *ppkey_id = meth->pkey_id;
+ if (pflags)
+ *pflags = meth->flags;
+ }
+
+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
+ {
+
+ dst->init = src->init;
+ dst->copy = src->copy;
+ dst->cleanup = src->cleanup;
+
+ dst->paramgen_init = src->paramgen_init;
+ dst->paramgen = src->paramgen;
+
+ dst->keygen_init = src->keygen_init;
+ dst->keygen = src->keygen;
+
+ dst->sign_init = src->sign_init;
+ dst->sign = src->sign;
+
+ dst->verify_init = src->verify_init;
+ dst->verify = src->verify;
+
+ dst->verify_recover_init = src->verify_recover_init;
+ dst->verify_recover = src->verify_recover;
+
+ dst->signctx_init = src->signctx_init;
+ dst->signctx = src->signctx;
+
+ dst->verifyctx_init = src->verifyctx_init;
+ dst->verifyctx = src->verifyctx;
+
+ dst->encrypt_init = src->encrypt_init;
+ dst->encrypt = src->encrypt;
+
+ dst->decrypt_init = src->decrypt_init;
+ dst->decrypt = src->decrypt;
+
+ dst->derive_init = src->derive_init;
+ dst->derive = src->derive;
+
+ dst->ctrl = src->ctrl;
+ dst->ctrl_str = src->ctrl_str;
+ }
+
void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
{
if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
diff --git a/deps/openssl/openssl/crypto/fips_err.h b/deps/openssl/openssl/crypto/fips_err.h
new file mode 100644
index 000000000..c671691b4
--- /dev/null
+++ b/deps/openssl/openssl/crypto/fips_err.h
@@ -0,0 +1,209 @@
+/* crypto/fips_err.h */
+/* ====================================================================
+ * Copyright (c) 1999-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).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_FIPS,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_FIPS,0,reason)
+
+static ERR_STRING_DATA FIPS_str_functs[]=
+ {
+{ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"},
+{ERR_FUNC(FIPS_F_DH_INIT), "DH_INIT"},
+{ERR_FUNC(FIPS_F_DRBG_RESEED), "DRBG_RESEED"},
+{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"},
+{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"},
+{ERR_FUNC(FIPS_F_DSA_DO_SIGN), "DSA_do_sign"},
+{ERR_FUNC(FIPS_F_DSA_DO_VERIFY), "DSA_do_verify"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_DSA), "FIPS_CHECK_DSA"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_DSA_PRNG), "fips_check_dsa_prng"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_EC), "FIPS_CHECK_EC"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_EC_PRNG), "fips_check_ec_prng"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT), "FIPS_check_incore_fingerprint"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_RSA), "fips_check_rsa"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_RSA_PRNG), "fips_check_rsa_prng"},
+{ERR_FUNC(FIPS_F_FIPS_CIPHER), "FIPS_cipher"},
+{ERR_FUNC(FIPS_F_FIPS_CIPHERINIT), "FIPS_cipherinit"},
+{ERR_FUNC(FIPS_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"},
+{ERR_FUNC(FIPS_F_FIPS_DIGESTFINAL), "FIPS_digestfinal"},
+{ERR_FUNC(FIPS_F_FIPS_DIGESTINIT), "FIPS_digestinit"},
+{ERR_FUNC(FIPS_F_FIPS_DIGESTUPDATE), "FIPS_digestupdate"},
+{ERR_FUNC(FIPS_F_FIPS_DRBG_BYTES), "FIPS_DRBG_BYTES"},
+{ERR_FUNC(FIPS_F_FIPS_DRBG_CHECK), "FIPS_DRBG_CHECK"},
+{ERR_FUNC(FIPS_F_FIPS_DRBG_CPRNG_TEST), "FIPS_DRBG_CPRNG_TEST"},
+{ERR_FUNC(FIPS_F_FIPS_DRBG_ERROR_CHECK), "FIPS_DRBG_ERROR_CHECK"},
+{ERR_FUNC(FIPS_F_FIPS_DRBG_GENERATE), "FIPS_drbg_generate"},
+{ERR_FUNC(FIPS_F_FIPS_DRBG_INIT), "FIPS_drbg_init"},
+{ERR_FUNC(FIPS_F_FIPS_DRBG_INSTANTIATE), "FIPS_drbg_instantiate"},
+{ERR_FUNC(FIPS_F_FIPS_DRBG_NEW), "FIPS_drbg_new"},
+{ERR_FUNC(FIPS_F_FIPS_DRBG_RESEED), "FIPS_drbg_reseed"},
+{ERR_FUNC(FIPS_F_FIPS_DRBG_SINGLE_KAT), "FIPS_DRBG_SINGLE_KAT"},
+{ERR_FUNC(FIPS_F_FIPS_DSA_SIGN_DIGEST), "FIPS_dsa_sign_digest"},
+{ERR_FUNC(FIPS_F_FIPS_DSA_VERIFY_DIGEST), "FIPS_dsa_verify_digest"},
+{ERR_FUNC(FIPS_F_FIPS_GET_ENTROPY), "FIPS_GET_ENTROPY"},
+{ERR_FUNC(FIPS_F_FIPS_MODULE_MODE_SET), "FIPS_module_mode_set"},
+{ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST), "fips_pkey_signature_test"},
+{ERR_FUNC(FIPS_F_FIPS_RAND_ADD), "FIPS_rand_add"},
+{ERR_FUNC(FIPS_F_FIPS_RAND_BYTES), "FIPS_rand_bytes"},
+{ERR_FUNC(FIPS_F_FIPS_RAND_PSEUDO_BYTES), "FIPS_rand_pseudo_bytes"},
+{ERR_FUNC(FIPS_F_FIPS_RAND_SEED), "FIPS_rand_seed"},
+{ERR_FUNC(FIPS_F_FIPS_RAND_SET_METHOD), "FIPS_rand_set_method"},
+{ERR_FUNC(FIPS_F_FIPS_RAND_STATUS), "FIPS_rand_status"},
+{ERR_FUNC(FIPS_F_FIPS_RSA_SIGN_DIGEST), "FIPS_rsa_sign_digest"},
+{ERR_FUNC(FIPS_F_FIPS_RSA_VERIFY_DIGEST), "FIPS_rsa_verify_digest"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES), "FIPS_selftest_aes"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_CCM), "FIPS_selftest_aes_ccm"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_GCM), "FIPS_selftest_aes_gcm"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_XTS), "FIPS_selftest_aes_xts"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_CMAC), "FIPS_selftest_cmac"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES), "FIPS_selftest_des"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_ECDSA), "FIPS_selftest_ecdsa"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC), "FIPS_selftest_hmac"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1), "FIPS_selftest_sha1"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_X931), "FIPS_selftest_x931"},
+{ERR_FUNC(FIPS_F_FIPS_SET_PRNG_KEY), "FIPS_SET_PRNG_KEY"},
+{ERR_FUNC(FIPS_F_HASH_FINAL), "HASH_FINAL"},
+{ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"},
+{ERR_FUNC(FIPS_F_RSA_EAY_INIT), "RSA_EAY_INIT"},
+{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"},
+{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"},
+{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"},
+{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"},
+{ERR_FUNC(FIPS_F_RSA_X931_GENERATE_KEY_EX), "RSA_X931_generate_key_ex"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA FIPS_str_reasons[]=
+ {
+{ERR_REASON(FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED),"additional input error undetected"},
+{ERR_REASON(FIPS_R_ADDITIONAL_INPUT_TOO_LONG),"additional input too long"},
+{ERR_REASON(FIPS_R_ALREADY_INSTANTIATED) ,"already instantiated"},
+{ERR_REASON(FIPS_R_AUTHENTICATION_FAILURE),"authentication failure"},
+{ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE),"contradicting evidence"},
+{ERR_REASON(FIPS_R_DRBG_NOT_INITIALISED) ,"drbg not initialised"},
+{ERR_REASON(FIPS_R_DRBG_STUCK) ,"drbg stuck"},
+{ERR_REASON(FIPS_R_ENTROPY_ERROR_UNDETECTED),"entropy error undetected"},
+{ERR_REASON(FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED),"entropy not requested for reseed"},
+{ERR_REASON(FIPS_R_ENTROPY_SOURCE_STUCK) ,"entropy source stuck"},
+{ERR_REASON(FIPS_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
+{ERR_REASON(FIPS_R_ERROR_INSTANTIATING_DRBG),"error instantiating drbg"},
+{ERR_REASON(FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT),"error retrieving additional input"},
+{ERR_REASON(FIPS_R_ERROR_RETRIEVING_ENTROPY),"error retrieving entropy"},
+{ERR_REASON(FIPS_R_ERROR_RETRIEVING_NONCE),"error retrieving nonce"},
+{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH),"fingerprint does not match"},
+{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED),"fingerprint does not match nonpic relocated"},
+{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING),"fingerprint does not match segment aliasing"},
+{ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET),"fips mode already set"},
+{ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED) ,"fips selftest failed"},
+{ERR_REASON(FIPS_R_FUNCTION_ERROR) ,"function error"},
+{ERR_REASON(FIPS_R_GENERATE_ERROR) ,"generate error"},
+{ERR_REASON(FIPS_R_GENERATE_ERROR_UNDETECTED),"generate error undetected"},
+{ERR_REASON(FIPS_R_INSTANTIATE_ERROR) ,"instantiate error"},
+{ERR_REASON(FIPS_R_INSUFFICIENT_SECURITY_STRENGTH),"insufficient security strength"},
+{ERR_REASON(FIPS_R_INTERNAL_ERROR) ,"internal error"},
+{ERR_REASON(FIPS_R_INVALID_KEY_LENGTH) ,"invalid key length"},
+{ERR_REASON(FIPS_R_INVALID_PARAMETERS) ,"invalid parameters"},
+{ERR_REASON(FIPS_R_IN_ERROR_STATE) ,"in error state"},
+{ERR_REASON(FIPS_R_KEY_TOO_SHORT) ,"key too short"},
+{ERR_REASON(FIPS_R_NONCE_ERROR_UNDETECTED),"nonce error undetected"},
+{ERR_REASON(FIPS_R_NON_FIPS_METHOD) ,"non fips method"},
+{ERR_REASON(FIPS_R_NOPR_TEST1_FAILURE) ,"nopr test1 failure"},
+{ERR_REASON(FIPS_R_NOPR_TEST2_FAILURE) ,"nopr test2 failure"},
+{ERR_REASON(FIPS_R_NOT_INSTANTIATED) ,"not instantiated"},
+{ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED) ,"pairwise test failed"},
+{ERR_REASON(FIPS_R_PERSONALISATION_ERROR_UNDETECTED),"personalisation error undetected"},
+{ERR_REASON(FIPS_R_PERSONALISATION_STRING_TOO_LONG),"personalisation string too long"},
+{ERR_REASON(FIPS_R_PRNG_STRENGTH_TOO_LOW),"prng strength too low"},
+{ERR_REASON(FIPS_R_PR_TEST1_FAILURE) ,"pr test1 failure"},
+{ERR_REASON(FIPS_R_PR_TEST2_FAILURE) ,"pr test2 failure"},
+{ERR_REASON(FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED),"request length error undetected"},
+{ERR_REASON(FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG),"request too large for drbg"},
+{ERR_REASON(FIPS_R_RESEED_COUNTER_ERROR) ,"reseed counter error"},
+{ERR_REASON(FIPS_R_RESEED_ERROR) ,"reseed error"},
+{ERR_REASON(FIPS_R_SELFTEST_FAILED) ,"selftest failed"},
+{ERR_REASON(FIPS_R_SELFTEST_FAILURE) ,"selftest failure"},
+{ERR_REASON(FIPS_R_STRENGTH_ERROR_UNDETECTED),"strength error undetected"},
+{ERR_REASON(FIPS_R_TEST_FAILURE) ,"test failure"},
+{ERR_REASON(FIPS_R_UNINSTANTIATE_ERROR) ,"uninstantiate error"},
+{ERR_REASON(FIPS_R_UNINSTANTIATE_ZEROISE_ERROR),"uninstantiate zeroise error"},
+{ERR_REASON(FIPS_R_UNSUPPORTED_DRBG_TYPE),"unsupported drbg type"},
+{ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM) ,"unsupported platform"},
+{0,NULL}
+ };
+
+#endif
+
+void ERR_load_FIPS_strings(void)
+ {
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(FIPS_str_functs[0].error) == NULL)
+ {
+ ERR_load_strings(0,FIPS_str_functs);
+ ERR_load_strings(0,FIPS_str_reasons);
+ }
+#endif
+ }
diff --git a/deps/openssl/openssl/crypto/fips_ers.c b/deps/openssl/openssl/crypto/fips_ers.c
new file mode 100644
index 000000000..09f11748f
--- /dev/null
+++ b/deps/openssl/openssl/crypto/fips_ers.c
@@ -0,0 +1,7 @@
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_FIPS
+# include "fips_err.h"
+#else
+static void *dummy=&dummy;
+#endif
diff --git a/deps/openssl/openssl/crypto/hmac/hm_ameth.c b/deps/openssl/openssl/crypto/hmac/hm_ameth.c
index 6d8a89149..e03f24aed 100644
--- a/deps/openssl/openssl/crypto/hmac/hm_ameth.c
+++ b/deps/openssl/openssl/crypto/hmac/hm_ameth.c
@@ -153,7 +153,7 @@ const EVP_PKEY_ASN1_METHOD hmac_asn1_meth =
hmac_size,
0,
- 0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,
hmac_key_free,
hmac_pkey_ctrl,
diff --git a/deps/openssl/openssl/crypto/hmac/hm_pmeth.c b/deps/openssl/openssl/crypto/hmac/hm_pmeth.c
index 71e8567a1..0daa44511 100644
--- a/deps/openssl/openssl/crypto/hmac/hm_pmeth.c
+++ b/deps/openssl/openssl/crypto/hmac/hm_pmeth.c
@@ -100,7 +100,8 @@ static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
dctx = dst->data;
dctx->md = sctx->md;
HMAC_CTX_init(&dctx->ctx);
- HMAC_CTX_copy(&dctx->ctx, &sctx->ctx);
+ if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx))
+ return 0;
if (sctx->ktmp.data)
{
if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
@@ -141,7 +142,8 @@ static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
static int int_update(EVP_MD_CTX *ctx,const void *data,size_t count)
{
HMAC_PKEY_CTX *hctx = ctx->pctx->data;
- HMAC_Update(&hctx->ctx, data, count);
+ if (!HMAC_Update(&hctx->ctx, data, count))
+ return 0;
return 1;
}
@@ -167,7 +169,8 @@ static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
if (!sig)
return 1;
- HMAC_Final(&hctx->ctx, sig, &hlen);
+ if (!HMAC_Final(&hctx->ctx, sig, &hlen))
+ return 0;
*siglen = (size_t)hlen;
return 1;
}
@@ -192,8 +195,9 @@ static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_DIGESTINIT:
key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
- HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
- ctx->engine);
+ if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
+ ctx->engine))
+ return 0;
break;
default:
diff --git a/deps/openssl/openssl/crypto/hmac/hmac.c b/deps/openssl/openssl/crypto/hmac/hmac.c
index 6c98fc43a..ba27cbf56 100644
--- a/deps/openssl/openssl/crypto/hmac/hmac.c
+++ b/deps/openssl/openssl/crypto/hmac/hmac.c
@@ -61,12 +61,34 @@
#include "cryptlib.h"
#include <openssl/hmac.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
const EVP_MD *md, ENGINE *impl)
{
int i,j,reset=0;
unsigned char pad[HMAC_MAX_MD_CBLOCK];
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ {
+ /* If we have an ENGINE need to allow non FIPS */
+ if ((impl || ctx->i_ctx.engine)
+ && !(ctx->i_ctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW))
+ {
+ EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS);
+ return 0;
+ }
+ /* Other algorithm blocking will be done in FIPS_cmac_init,
+ * via FIPS_hmac_init_ex().
+ */
+ if (!impl && !ctx->i_ctx.engine)
+ return FIPS_hmac_init_ex(ctx, key, len, md, NULL);
+ }
+#endif
+
if (md != NULL)
{
reset=1;
@@ -133,6 +155,10 @@ int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->i_ctx.engine)
+ return FIPS_hmac_update(ctx, data, len);
+#endif
return EVP_DigestUpdate(&ctx->md_ctx,data,len);
}
@@ -140,6 +166,10 @@ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
{
unsigned int i;
unsigned char buf[EVP_MAX_MD_SIZE];
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->i_ctx.engine)
+ return FIPS_hmac_final(ctx, md, len);
+#endif
if (!EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i))
goto err;
@@ -179,6 +209,13 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
void HMAC_CTX_cleanup(HMAC_CTX *ctx)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->i_ctx.engine)
+ {
+ FIPS_hmac_ctx_cleanup(ctx);
+ return;
+ }
+#endif
EVP_MD_CTX_cleanup(&ctx->i_ctx);
EVP_MD_CTX_cleanup(&ctx->o_ctx);
EVP_MD_CTX_cleanup(&ctx->md_ctx);
diff --git a/deps/openssl/openssl/crypto/ia64cpuid.S b/deps/openssl/openssl/crypto/ia64cpuid.S
index d705fff7e..7832b9b64 100644
--- a/deps/openssl/openssl/crypto/ia64cpuid.S
+++ b/deps/openssl/openssl/crypto/ia64cpuid.S
@@ -26,7 +26,7 @@ OPENSSL_atomic_add:
{ .mii; mov ar.ccv=r2
add r8=r2,r33
mov r3=r2 };;
-{ .mmi; mf
+{ .mmi; mf;;
cmpxchg4.acq r2=[r32],r8,ar.ccv
nop.i 0 };;
{ .mib; cmp.ne p6,p0=r2,r3
diff --git a/deps/openssl/openssl/crypto/idea/Makefile b/deps/openssl/openssl/crypto/idea/Makefile
index b2e7add66..8af0acdad 100644
--- a/deps/openssl/openssl/crypto/idea/Makefile
+++ b/deps/openssl/openssl/crypto/idea/Makefile
@@ -82,5 +82,8 @@ i_ecb.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
i_ecb.o: ../../include/openssl/opensslv.h i_ecb.c idea_lcl.h
i_ofb64.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
i_ofb64.o: i_ofb64.c idea_lcl.h
+i_skey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
i_skey.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
-i_skey.o: i_skey.c idea_lcl.h
+i_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+i_skey.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+i_skey.o: ../../include/openssl/symhacks.h i_skey.c idea_lcl.h
diff --git a/deps/openssl/openssl/crypto/idea/i_skey.c b/deps/openssl/openssl/crypto/idea/i_skey.c
index 1c95bc9c7..afb830964 100644
--- a/deps/openssl/openssl/crypto/idea/i_skey.c
+++ b/deps/openssl/openssl/crypto/idea/i_skey.c
@@ -56,11 +56,19 @@
* [including the GNU Public Licence.]
*/
+#include <openssl/crypto.h>
#include <openssl/idea.h>
#include "idea_lcl.h"
static IDEA_INT inverse(unsigned int xin);
void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks)
+#ifdef OPENSSL_FIPS
+ {
+ fips_cipher_abort(IDEA);
+ private_idea_set_encrypt_key(key, ks);
+ }
+void private_idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks)
+#endif
{
int i;
register IDEA_INT *kt,*kf,r0,r1,r2;
diff --git a/deps/openssl/openssl/crypto/idea/idea.h b/deps/openssl/openssl/crypto/idea/idea.h
index 5782e54b0..e9a1e7f1a 100644
--- a/deps/openssl/openssl/crypto/idea/idea.h
+++ b/deps/openssl/openssl/crypto/idea/idea.h
@@ -83,6 +83,9 @@ typedef struct idea_key_st
const char *idea_options(void);
void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
IDEA_KEY_SCHEDULE *ks);
+#ifdef OPENSSL_FIPS
+void private_idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
+#endif
void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk);
void idea_cbc_encrypt(const unsigned char *in, unsigned char *out,
diff --git a/deps/openssl/openssl/crypto/install-crypto.com b/deps/openssl/openssl/crypto/install-crypto.com
index 85b3d583c..85b3d583c 100644..100755
--- a/deps/openssl/openssl/crypto/install-crypto.com
+++ b/deps/openssl/openssl/crypto/install-crypto.com
diff --git a/deps/openssl/openssl/crypto/md2/md2.h b/deps/openssl/openssl/crypto/md2/md2.h
index a46120e7d..d59c9f259 100644
--- a/deps/openssl/openssl/crypto/md2/md2.h
+++ b/deps/openssl/openssl/crypto/md2/md2.h
@@ -81,6 +81,9 @@ typedef struct MD2state_st
} MD2_CTX;
const char *MD2_options(void);
+#ifdef OPENSSL_FIPS
+int private_MD2_Init(MD2_CTX *c);
+#endif
int MD2_Init(MD2_CTX *c);
int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
int MD2_Final(unsigned char *md, MD2_CTX *c);
diff --git a/deps/openssl/openssl/crypto/md2/md2_dgst.c b/deps/openssl/openssl/crypto/md2/md2_dgst.c
index c57b3da28..bf89def73 100644
--- a/deps/openssl/openssl/crypto/md2/md2_dgst.c
+++ b/deps/openssl/openssl/crypto/md2/md2_dgst.c
@@ -116,7 +116,7 @@ const char *MD2_options(void)
return("md2(int)");
}
-int MD2_Init(MD2_CTX *c)
+fips_md_init(MD2)
{
c->num=0;
memset(c->state,0,sizeof c->state);
diff --git a/deps/openssl/openssl/crypto/md4/Makefile b/deps/openssl/openssl/crypto/md4/Makefile
index c94a1398e..e6f1e4478 100644
--- a/deps/openssl/openssl/crypto/md4/Makefile
+++ b/deps/openssl/openssl/crypto/md4/Makefile
@@ -76,9 +76,11 @@ clean:
# DO NOT DELETE THIS LINE -- make depend depends on it.
-md4_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/md4.h
-md4_dgst.o: ../../include/openssl/opensslconf.h
-md4_dgst.o: ../../include/openssl/opensslv.h ../md32_common.h md4_dgst.c
+md4_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+md4_dgst.o: ../../include/openssl/md4.h ../../include/openssl/opensslconf.h
+md4_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+md4_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+md4_dgst.o: ../../include/openssl/symhacks.h ../md32_common.h md4_dgst.c
md4_dgst.o: md4_locl.h
md4_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
md4_one.o: ../../include/openssl/md4.h ../../include/openssl/opensslconf.h
diff --git a/deps/openssl/openssl/crypto/md4/md4.h b/deps/openssl/openssl/crypto/md4/md4.h
index c3ed9b3f7..a55368a79 100644
--- a/deps/openssl/openssl/crypto/md4/md4.h
+++ b/deps/openssl/openssl/crypto/md4/md4.h
@@ -105,6 +105,9 @@ typedef struct MD4state_st
unsigned int num;
} MD4_CTX;
+#ifdef OPENSSL_FIPS
+int private_MD4_Init(MD4_CTX *c);
+#endif
int MD4_Init(MD4_CTX *c);
int MD4_Update(MD4_CTX *c, const void *data, size_t len);
int MD4_Final(unsigned char *md, MD4_CTX *c);
diff --git a/deps/openssl/openssl/crypto/md4/md4_dgst.c b/deps/openssl/openssl/crypto/md4/md4_dgst.c
index e0c42e859..b5b165b05 100644
--- a/deps/openssl/openssl/crypto/md4/md4_dgst.c
+++ b/deps/openssl/openssl/crypto/md4/md4_dgst.c
@@ -57,8 +57,9 @@
*/
#include <stdio.h>
-#include "md4_locl.h"
#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include "md4_locl.h"
const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT;
@@ -70,7 +71,7 @@ const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT;
#define INIT_DATA_C (unsigned long)0x98badcfeL
#define INIT_DATA_D (unsigned long)0x10325476L
-int MD4_Init(MD4_CTX *c)
+fips_md_init(MD4)
{
memset (c,0,sizeof(*c));
c->A=INIT_DATA_A;
@@ -105,22 +106,23 @@ void md4_block_data_order (MD4_CTX *c, const void *data_, size_t num)
for (;num--;)
{
- HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l;
+ (void)HOST_c2l(data,l); X( 0)=l;
+ (void)HOST_c2l(data,l); X( 1)=l;
/* Round 0 */
- R0(A,B,C,D,X( 0), 3,0); HOST_c2l(data,l); X( 2)=l;
- R0(D,A,B,C,X( 1), 7,0); HOST_c2l(data,l); X( 3)=l;
- R0(C,D,A,B,X( 2),11,0); HOST_c2l(data,l); X( 4)=l;
- R0(B,C,D,A,X( 3),19,0); HOST_c2l(data,l); X( 5)=l;
- R0(A,B,C,D,X( 4), 3,0); HOST_c2l(data,l); X( 6)=l;
- R0(D,A,B,C,X( 5), 7,0); HOST_c2l(data,l); X( 7)=l;
- R0(C,D,A,B,X( 6),11,0); HOST_c2l(data,l); X( 8)=l;
- R0(B,C,D,A,X( 7),19,0); HOST_c2l(data,l); X( 9)=l;
- R0(A,B,C,D,X( 8), 3,0); HOST_c2l(data,l); X(10)=l;
- R0(D,A,B,C,X( 9), 7,0); HOST_c2l(data,l); X(11)=l;
- R0(C,D,A,B,X(10),11,0); HOST_c2l(data,l); X(12)=l;
- R0(B,C,D,A,X(11),19,0); HOST_c2l(data,l); X(13)=l;
- R0(A,B,C,D,X(12), 3,0); HOST_c2l(data,l); X(14)=l;
- R0(D,A,B,C,X(13), 7,0); HOST_c2l(data,l); X(15)=l;
+ R0(A,B,C,D,X( 0), 3,0); (void)HOST_c2l(data,l); X( 2)=l;
+ R0(D,A,B,C,X( 1), 7,0); (void)HOST_c2l(data,l); X( 3)=l;
+ R0(C,D,A,B,X( 2),11,0); (void)HOST_c2l(data,l); X( 4)=l;
+ R0(B,C,D,A,X( 3),19,0); (void)HOST_c2l(data,l); X( 5)=l;
+ R0(A,B,C,D,X( 4), 3,0); (void)HOST_c2l(data,l); X( 6)=l;
+ R0(D,A,B,C,X( 5), 7,0); (void)HOST_c2l(data,l); X( 7)=l;
+ R0(C,D,A,B,X( 6),11,0); (void)HOST_c2l(data,l); X( 8)=l;
+ R0(B,C,D,A,X( 7),19,0); (void)HOST_c2l(data,l); X( 9)=l;
+ R0(A,B,C,D,X( 8), 3,0); (void)HOST_c2l(data,l); X(10)=l;
+ R0(D,A,B,C,X( 9), 7,0); (void)HOST_c2l(data,l); X(11)=l;
+ R0(C,D,A,B,X(10),11,0); (void)HOST_c2l(data,l); X(12)=l;
+ R0(B,C,D,A,X(11),19,0); (void)HOST_c2l(data,l); X(13)=l;
+ R0(A,B,C,D,X(12), 3,0); (void)HOST_c2l(data,l); X(14)=l;
+ R0(D,A,B,C,X(13), 7,0); (void)HOST_c2l(data,l); X(15)=l;
R0(C,D,A,B,X(14),11,0);
R0(B,C,D,A,X(15),19,0);
/* Round 1 */
diff --git a/deps/openssl/openssl/crypto/md4/md4_locl.h b/deps/openssl/openssl/crypto/md4/md4_locl.h
index c8085b0ea..99c3e5004 100644
--- a/deps/openssl/openssl/crypto/md4/md4_locl.h
+++ b/deps/openssl/openssl/crypto/md4/md4_locl.h
@@ -77,10 +77,10 @@ void md4_block_data_order (MD4_CTX *c, const void *p,size_t num);
#define HASH_FINAL MD4_Final
#define HASH_MAKE_STRING(c,s) do { \
unsigned long ll; \
- ll=(c)->A; HOST_l2c(ll,(s)); \
- ll=(c)->B; HOST_l2c(ll,(s)); \
- ll=(c)->C; HOST_l2c(ll,(s)); \
- ll=(c)->D; HOST_l2c(ll,(s)); \
+ ll=(c)->A; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->B; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->C; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->D; (void)HOST_l2c(ll,(s)); \
} while (0)
#define HASH_BLOCK_DATA_ORDER md4_block_data_order
diff --git a/deps/openssl/openssl/crypto/md5/Makefile b/deps/openssl/openssl/crypto/md5/Makefile
index 9858d53d3..b9e2ce9a3 100644
--- a/deps/openssl/openssl/crypto/md5/Makefile
+++ b/deps/openssl/openssl/crypto/md5/Makefile
@@ -89,9 +89,11 @@ clean:
# DO NOT DELETE THIS LINE -- make depend depends on it.
-md5_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/md5.h
-md5_dgst.o: ../../include/openssl/opensslconf.h
-md5_dgst.o: ../../include/openssl/opensslv.h ../md32_common.h md5_dgst.c
+md5_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+md5_dgst.o: ../../include/openssl/md5.h ../../include/openssl/opensslconf.h
+md5_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+md5_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+md5_dgst.o: ../../include/openssl/symhacks.h ../md32_common.h md5_dgst.c
md5_dgst.o: md5_locl.h
md5_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
md5_one.o: ../../include/openssl/md5.h ../../include/openssl/opensslconf.h
diff --git a/deps/openssl/openssl/crypto/md5/asm/md5-x86_64.pl b/deps/openssl/openssl/crypto/md5/asm/md5-x86_64.pl
index 867885435..f11224d17 100755
--- a/deps/openssl/openssl/crypto/md5/asm/md5-x86_64.pl
+++ b/deps/openssl/openssl/crypto/md5/asm/md5-x86_64.pl
@@ -120,7 +120,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
die "can't locate x86_64-xlate.pl";
no warnings qw(uninitialized);
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
$code .= <<EOF;
.text
diff --git a/deps/openssl/openssl/crypto/md5/md5.h b/deps/openssl/openssl/crypto/md5/md5.h
index 4cbf84386..541cc925f 100644
--- a/deps/openssl/openssl/crypto/md5/md5.h
+++ b/deps/openssl/openssl/crypto/md5/md5.h
@@ -105,6 +105,9 @@ typedef struct MD5state_st
unsigned int num;
} MD5_CTX;
+#ifdef OPENSSL_FIPS
+int private_MD5_Init(MD5_CTX *c);
+#endif
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
diff --git a/deps/openssl/openssl/crypto/md5/md5_dgst.c b/deps/openssl/openssl/crypto/md5/md5_dgst.c
index beace632e..265890de5 100644
--- a/deps/openssl/openssl/crypto/md5/md5_dgst.c
+++ b/deps/openssl/openssl/crypto/md5/md5_dgst.c
@@ -59,6 +59,7 @@
#include <stdio.h>
#include "md5_locl.h"
#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT;
@@ -70,7 +71,7 @@ const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT;
#define INIT_DATA_C (unsigned long)0x98badcfeL
#define INIT_DATA_D (unsigned long)0x10325476L
-int MD5_Init(MD5_CTX *c)
+fips_md_init(MD5)
{
memset (c,0,sizeof(*c));
c->A=INIT_DATA_A;
diff --git a/deps/openssl/openssl/crypto/md5/md5_locl.h b/deps/openssl/openssl/crypto/md5/md5_locl.h
index 968d57799..74d63d1f9 100644
--- a/deps/openssl/openssl/crypto/md5/md5_locl.h
+++ b/deps/openssl/openssl/crypto/md5/md5_locl.h
@@ -86,10 +86,10 @@ void md5_block_data_order (MD5_CTX *c, const void *p,size_t num);
#define HASH_FINAL MD5_Final
#define HASH_MAKE_STRING(c,s) do { \
unsigned long ll; \
- ll=(c)->A; HOST_l2c(ll,(s)); \
- ll=(c)->B; HOST_l2c(ll,(s)); \
- ll=(c)->C; HOST_l2c(ll,(s)); \
- ll=(c)->D; HOST_l2c(ll,(s)); \
+ ll=(c)->A; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->B; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->C; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->D; (void)HOST_l2c(ll,(s)); \
} while (0)
#define HASH_BLOCK_DATA_ORDER md5_block_data_order
diff --git a/deps/openssl/openssl/crypto/mdc2/Makefile b/deps/openssl/openssl/crypto/mdc2/Makefile
index 1d064f17a..141553149 100644
--- a/deps/openssl/openssl/crypto/mdc2/Makefile
+++ b/deps/openssl/openssl/crypto/mdc2/Makefile
@@ -84,10 +84,10 @@ mdc2_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
mdc2_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
mdc2_one.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
mdc2_one.o: ../../include/openssl/ui_compat.h ../cryptlib.h mdc2_one.c
-mdc2dgst.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-mdc2dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/mdc2.h
-mdc2dgst.o: ../../include/openssl/opensslconf.h
-mdc2dgst.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-mdc2dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-mdc2dgst.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-mdc2dgst.o: mdc2dgst.c
+mdc2dgst.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+mdc2dgst.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+mdc2dgst.o: ../../include/openssl/mdc2.h ../../include/openssl/opensslconf.h
+mdc2dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+mdc2dgst.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+mdc2dgst.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+mdc2dgst.o: ../../include/openssl/ui_compat.h mdc2dgst.c
diff --git a/deps/openssl/openssl/crypto/mdc2/mdc2.h b/deps/openssl/openssl/crypto/mdc2/mdc2.h
index 72778a521..f3e8e579d 100644
--- a/deps/openssl/openssl/crypto/mdc2/mdc2.h
+++ b/deps/openssl/openssl/crypto/mdc2/mdc2.h
@@ -81,6 +81,9 @@ typedef struct mdc2_ctx_st
} MDC2_CTX;
+#ifdef OPENSSL_FIPS
+int private_MDC2_Init(MDC2_CTX *c);
+#endif
int MDC2_Init(MDC2_CTX *c);
int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len);
int MDC2_Final(unsigned char *md, MDC2_CTX *c);
diff --git a/deps/openssl/openssl/crypto/mdc2/mdc2dgst.c b/deps/openssl/openssl/crypto/mdc2/mdc2dgst.c
index 4aa406edc..d66ed6a1c 100644
--- a/deps/openssl/openssl/crypto/mdc2/mdc2dgst.c
+++ b/deps/openssl/openssl/crypto/mdc2/mdc2dgst.c
@@ -59,6 +59,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <openssl/crypto.h>
#include <openssl/des.h>
#include <openssl/mdc2.h>
@@ -75,7 +76,7 @@
*((c)++)=(unsigned char)(((l)>>24L)&0xff))
static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len);
-int MDC2_Init(MDC2_CTX *c)
+fips_md_init(MDC2)
{
c->num=0;
c->pad_type=1;
diff --git a/deps/openssl/openssl/crypto/mem.c b/deps/openssl/openssl/crypto/mem.c
index ae40de37f..1cc62eafd 100644
--- a/deps/openssl/openssl/crypto/mem.c
+++ b/deps/openssl/openssl/crypto/mem.c
@@ -121,10 +121,11 @@ static void (*set_debug_options_func)(long) = NULL;
static long (*get_debug_options_func)(void) = NULL;
#endif
-
int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t),
void (*f)(void *))
{
+ /* Dummy call just to ensure OPENSSL_init() gets linked in */
+ OPENSSL_init();
if (!allow_customize)
return 0;
if ((m == 0) || (r == 0) || (f == 0))
@@ -186,6 +187,7 @@ int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int),
{
if (!allow_customize_debug)
return 0;
+ OPENSSL_init();
malloc_debug_func=m;
realloc_debug_func=r;
free_debug_func=f;
diff --git a/deps/openssl/openssl/crypto/modes/Makefile b/deps/openssl/openssl/crypto/modes/Makefile
index 6c85861b6..c825b12f2 100644
--- a/deps/openssl/openssl/crypto/modes/Makefile
+++ b/deps/openssl/openssl/crypto/modes/Makefile
@@ -10,21 +10,27 @@ CFLAG=-g
MAKEFILE= Makefile
AR= ar r
+MODES_ASM_OBJ=
+
CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
GENERAL=Makefile
TEST=
APPS=
LIB=$(TOP)/libcrypto.a
-LIBSRC= cbc128.c ctr128.c cts128.c cfb128.c ofb128.c
-LIBOBJ= cbc128.o ctr128.o cts128.o cfb128.o ofb128.o
+LIBSRC= cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c \
+ ccm128.c xts128.c
+LIBOBJ= cbc128.o ctr128.o cts128.o cfb128.o ofb128.o gcm128.o \
+ ccm128.o xts128.o $(MODES_ASM_OBJ)
SRC= $(LIBSRC)
#EXHEADER= store.h str_compat.h
EXHEADER= modes.h
-HEADER= $(EXHEADER)
+HEADER= modes_lcl.h $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)
@@ -38,6 +44,24 @@ lib: $(LIBOBJ)
$(RANLIB) $(LIB) || echo Never mind.
@touch lib
+ghash-ia64.s: asm/ghash-ia64.pl
+ $(PERL) asm/ghash-ia64.pl $@ $(CFLAGS)
+ghash-x86.s: asm/ghash-x86.pl
+ $(PERL) asm/ghash-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+ghash-x86_64.s: asm/ghash-x86_64.pl
+ $(PERL) asm/ghash-x86_64.pl $(PERLASM_SCHEME) > $@
+ghash-sparcv9.s: asm/ghash-sparcv9.pl
+ $(PERL) asm/ghash-sparcv9.pl $@ $(CFLAGS)
+ghash-alpha.s: asm/ghash-alpha.pl
+ $(PERL) $< | $(CC) -E - | tee $@ > /dev/null
+ghash-parisc.s: asm/ghash-parisc.pl
+ $(PERL) asm/ghash-parisc.pl $(PERLASM_SCHEME) $@
+
+# GNU make "catch all"
+ghash-%.S: asm/ghash-%.pl; $(PERL) $< $(PERLASM_SCHEME) $@
+
+ghash-armv4.o: ghash-armv4.S
+
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
@@ -71,12 +95,47 @@ dclean:
mv -f Makefile.new $(MAKEFILE)
clean:
- rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+ rm -f *.s *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
# DO NOT DELETE THIS LINE -- make depend depends on it.
-cbc128.o: cbc128.c modes.h
-cfb128.o: cfb128.c modes.h
-ctr128.o: ctr128.c modes.h
-cts128.o: cts128.c modes.h
-ofb128.o: modes.h ofb128.c
+cbc128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cbc128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+cbc128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cbc128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+cbc128.o: ../../include/openssl/symhacks.h cbc128.c modes_lcl.h
+ccm128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ccm128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+ccm128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ccm128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ccm128.o: ../../include/openssl/symhacks.h ccm128.c modes_lcl.h
+cfb128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cfb128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+cfb128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cfb128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+cfb128.o: ../../include/openssl/symhacks.h cfb128.c modes_lcl.h
+ctr128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ctr128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+ctr128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ctr128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ctr128.o: ../../include/openssl/symhacks.h ctr128.c modes_lcl.h
+cts128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cts128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+cts128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cts128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+cts128.o: ../../include/openssl/symhacks.h cts128.c modes_lcl.h
+gcm128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+gcm128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+gcm128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+gcm128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+gcm128.o: ../../include/openssl/symhacks.h gcm128.c modes_lcl.h
+ofb128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ofb128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+ofb128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ofb128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ofb128.o: ../../include/openssl/symhacks.h modes_lcl.h ofb128.c
+xts128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+xts128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+xts128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+xts128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+xts128.o: ../../include/openssl/symhacks.h modes_lcl.h xts128.c
diff --git a/deps/openssl/openssl/crypto/modes/asm/ghash-alpha.pl b/deps/openssl/openssl/crypto/modes/asm/ghash-alpha.pl
new file mode 100644
index 000000000..6358b2750
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/asm/ghash-alpha.pl
@@ -0,0 +1,451 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# March 2010
+#
+# The module implements "4-bit" GCM GHASH function and underlying
+# single multiplication operation in GF(2^128). "4-bit" means that it
+# uses 256 bytes per-key table [+128 bytes shared table]. Even though
+# loops are aggressively modulo-scheduled in respect to references to
+# Htbl and Z.hi updates for 8 cycles per byte, measured performance is
+# ~12 cycles per processed byte on 21264 CPU. It seems to be a dynamic
+# scheduling "glitch," because uprofile(1) indicates uniform sample
+# distribution, as if all instruction bundles execute in 1.5 cycles.
+# Meaning that it could have been even faster, yet 12 cycles is ~60%
+# better than gcc-generated code and ~80% than code generated by vendor
+# compiler.
+
+$cnt="v0"; # $0
+$t0="t0";
+$t1="t1";
+$t2="t2";
+$Thi0="t3"; # $4
+$Tlo0="t4";
+$Thi1="t5";
+$Tlo1="t6";
+$rem="t7"; # $8
+#################
+$Xi="a0"; # $16, input argument block
+$Htbl="a1";
+$inp="a2";
+$len="a3";
+$nlo="a4"; # $20
+$nhi="a5";
+$Zhi="t8";
+$Zlo="t9";
+$Xhi="t10"; # $24
+$Xlo="t11";
+$remp="t12";
+$rem_4bit="AT"; # $28
+
+{ my $N;
+ sub loop() {
+
+ $N++;
+$code.=<<___;
+.align 4
+ extbl $Xlo,7,$nlo
+ and $nlo,0xf0,$nhi
+ sll $nlo,4,$nlo
+ and $nlo,0xf0,$nlo
+
+ addq $nlo,$Htbl,$nlo
+ ldq $Zlo,8($nlo)
+ addq $nhi,$Htbl,$nhi
+ ldq $Zhi,0($nlo)
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ lda $cnt,6(zero)
+ extbl $Xlo,6,$nlo
+
+ ldq $Tlo1,8($nhi)
+ s8addq $remp,$rem_4bit,$remp
+ ldq $Thi1,0($nhi)
+ srl $Zlo,4,$Zlo
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $t0,$Zlo,$Zlo
+ and $nlo,0xf0,$nhi
+
+ xor $Tlo1,$Zlo,$Zlo
+ sll $nlo,4,$nlo
+ xor $Thi1,$Zhi,$Zhi
+ and $nlo,0xf0,$nlo
+
+ addq $nlo,$Htbl,$nlo
+ ldq $Tlo0,8($nlo)
+ addq $nhi,$Htbl,$nhi
+ ldq $Thi0,0($nlo)
+
+.Looplo$N:
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ subq $cnt,1,$cnt
+ srl $Zlo,4,$Zlo
+
+ ldq $Tlo1,8($nhi)
+ xor $rem,$Zhi,$Zhi
+ ldq $Thi1,0($nhi)
+ s8addq $remp,$rem_4bit,$remp
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $t0,$Zlo,$Zlo
+ extbl $Xlo,$cnt,$nlo
+
+ and $nlo,0xf0,$nhi
+ xor $Thi0,$Zhi,$Zhi
+ xor $Tlo0,$Zlo,$Zlo
+ sll $nlo,4,$nlo
+
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ and $nlo,0xf0,$nlo
+ srl $Zlo,4,$Zlo
+
+ s8addq $remp,$rem_4bit,$remp
+ xor $rem,$Zhi,$Zhi
+ addq $nlo,$Htbl,$nlo
+ addq $nhi,$Htbl,$nhi
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ ldq $Tlo0,8($nlo)
+ xor $t0,$Zlo,$Zlo
+
+ xor $Tlo1,$Zlo,$Zlo
+ xor $Thi1,$Zhi,$Zhi
+ ldq $Thi0,0($nlo)
+ bne $cnt,.Looplo$N
+
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ lda $cnt,7(zero)
+ srl $Zlo,4,$Zlo
+
+ ldq $Tlo1,8($nhi)
+ xor $rem,$Zhi,$Zhi
+ ldq $Thi1,0($nhi)
+ s8addq $remp,$rem_4bit,$remp
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $t0,$Zlo,$Zlo
+ extbl $Xhi,$cnt,$nlo
+
+ and $nlo,0xf0,$nhi
+ xor $Thi0,$Zhi,$Zhi
+ xor $Tlo0,$Zlo,$Zlo
+ sll $nlo,4,$nlo
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ and $nlo,0xf0,$nlo
+ srl $Zlo,4,$Zlo
+
+ s8addq $remp,$rem_4bit,$remp
+ xor $rem,$Zhi,$Zhi
+ addq $nlo,$Htbl,$nlo
+ addq $nhi,$Htbl,$nhi
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ ldq $Tlo0,8($nlo)
+ xor $t0,$Zlo,$Zlo
+
+ xor $Tlo1,$Zlo,$Zlo
+ xor $Thi1,$Zhi,$Zhi
+ ldq $Thi0,0($nlo)
+ unop
+
+
+.Loophi$N:
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ subq $cnt,1,$cnt
+ srl $Zlo,4,$Zlo
+
+ ldq $Tlo1,8($nhi)
+ xor $rem,$Zhi,$Zhi
+ ldq $Thi1,0($nhi)
+ s8addq $remp,$rem_4bit,$remp
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $t0,$Zlo,$Zlo
+ extbl $Xhi,$cnt,$nlo
+
+ and $nlo,0xf0,$nhi
+ xor $Thi0,$Zhi,$Zhi
+ xor $Tlo0,$Zlo,$Zlo
+ sll $nlo,4,$nlo
+
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ and $nlo,0xf0,$nlo
+ srl $Zlo,4,$Zlo
+
+ s8addq $remp,$rem_4bit,$remp
+ xor $rem,$Zhi,$Zhi
+ addq $nlo,$Htbl,$nlo
+ addq $nhi,$Htbl,$nhi
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ ldq $Tlo0,8($nlo)
+ xor $t0,$Zlo,$Zlo
+
+ xor $Tlo1,$Zlo,$Zlo
+ xor $Thi1,$Zhi,$Zhi
+ ldq $Thi0,0($nlo)
+ bne $cnt,.Loophi$N
+
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ srl $Zlo,4,$Zlo
+
+ ldq $Tlo1,8($nhi)
+ xor $rem,$Zhi,$Zhi
+ ldq $Thi1,0($nhi)
+ s8addq $remp,$rem_4bit,$remp
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $t0,$Zlo,$Zlo
+
+ xor $Tlo0,$Zlo,$Zlo
+ xor $Thi0,$Zhi,$Zhi
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ srl $Zlo,4,$Zlo
+
+ s8addq $remp,$rem_4bit,$remp
+ xor $rem,$Zhi,$Zhi
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $Tlo1,$Zlo,$Zlo
+ xor $Thi1,$Zhi,$Zhi
+ xor $t0,$Zlo,$Zlo
+ xor $rem,$Zhi,$Zhi
+___
+}}
+
+$code=<<___;
+#ifdef __linux__
+#include <asm/regdef.h>
+#else
+#include <asm.h>
+#include <regdef.h>
+#endif
+
+.text
+
+.set noat
+.set noreorder
+.globl gcm_gmult_4bit
+.align 4
+.ent gcm_gmult_4bit
+gcm_gmult_4bit:
+ .frame sp,0,ra
+ .prologue 0
+
+ ldq $Xlo,8($Xi)
+ ldq $Xhi,0($Xi)
+
+ br $rem_4bit,.Lpic1
+.Lpic1: lda $rem_4bit,rem_4bit-.Lpic1($rem_4bit)
+___
+
+ &loop();
+
+$code.=<<___;
+ srl $Zlo,24,$t0 # byte swap
+ srl $Zlo,8,$t1
+
+ sll $Zlo,8,$t2
+ sll $Zlo,24,$Zlo
+ zapnot $t0,0x11,$t0
+ zapnot $t1,0x22,$t1
+
+ zapnot $Zlo,0x88,$Zlo
+ or $t0,$t1,$t0
+ zapnot $t2,0x44,$t2
+
+ or $Zlo,$t0,$Zlo
+ srl $Zhi,24,$t0
+ srl $Zhi,8,$t1
+
+ or $Zlo,$t2,$Zlo
+ sll $Zhi,8,$t2
+ sll $Zhi,24,$Zhi
+
+ srl $Zlo,32,$Xlo
+ sll $Zlo,32,$Zlo
+
+ zapnot $t0,0x11,$t0
+ zapnot $t1,0x22,$t1
+ or $Zlo,$Xlo,$Xlo
+
+ zapnot $Zhi,0x88,$Zhi
+ or $t0,$t1,$t0
+ zapnot $t2,0x44,$t2
+
+ or $Zhi,$t0,$Zhi
+ or $Zhi,$t2,$Zhi
+
+ srl $Zhi,32,$Xhi
+ sll $Zhi,32,$Zhi
+
+ or $Zhi,$Xhi,$Xhi
+ stq $Xlo,8($Xi)
+ stq $Xhi,0($Xi)
+
+ ret (ra)
+.end gcm_gmult_4bit
+___
+
+$inhi="s0";
+$inlo="s1";
+
+$code.=<<___;
+.globl gcm_ghash_4bit
+.align 4
+.ent gcm_ghash_4bit
+gcm_ghash_4bit:
+ lda sp,-32(sp)
+ stq ra,0(sp)
+ stq s0,8(sp)
+ stq s1,16(sp)
+ .mask 0x04000600,-32
+ .frame sp,32,ra
+ .prologue 0
+
+ ldq_u $inhi,0($inp)
+ ldq_u $Thi0,7($inp)
+ ldq_u $inlo,8($inp)
+ ldq_u $Tlo0,15($inp)
+ ldq $Xhi,0($Xi)
+ ldq $Xlo,8($Xi)
+
+ br $rem_4bit,.Lpic2
+.Lpic2: lda $rem_4bit,rem_4bit-.Lpic2($rem_4bit)
+
+.Louter:
+ extql $inhi,$inp,$inhi
+ extqh $Thi0,$inp,$Thi0
+ or $inhi,$Thi0,$inhi
+ lda $inp,16($inp)
+
+ extql $inlo,$inp,$inlo
+ extqh $Tlo0,$inp,$Tlo0
+ or $inlo,$Tlo0,$inlo
+ subq $len,16,$len
+
+ xor $Xlo,$inlo,$Xlo
+ xor $Xhi,$inhi,$Xhi
+___
+
+ &loop();
+
+$code.=<<___;
+ srl $Zlo,24,$t0 # byte swap
+ srl $Zlo,8,$t1
+
+ sll $Zlo,8,$t2
+ sll $Zlo,24,$Zlo
+ zapnot $t0,0x11,$t0
+ zapnot $t1,0x22,$t1
+
+ zapnot $Zlo,0x88,$Zlo
+ or $t0,$t1,$t0
+ zapnot $t2,0x44,$t2
+
+ or $Zlo,$t0,$Zlo
+ srl $Zhi,24,$t0
+ srl $Zhi,8,$t1
+
+ or $Zlo,$t2,$Zlo
+ sll $Zhi,8,$t2
+ sll $Zhi,24,$Zhi
+
+ srl $Zlo,32,$Xlo
+ sll $Zlo,32,$Zlo
+ beq $len,.Ldone
+
+ zapnot $t0,0x11,$t0
+ zapnot $t1,0x22,$t1
+ or $Zlo,$Xlo,$Xlo
+ ldq_u $inhi,0($inp)
+
+ zapnot $Zhi,0x88,$Zhi
+ or $t0,$t1,$t0
+ zapnot $t2,0x44,$t2
+ ldq_u $Thi0,7($inp)
+
+ or $Zhi,$t0,$Zhi
+ or $Zhi,$t2,$Zhi
+ ldq_u $inlo,8($inp)
+ ldq_u $Tlo0,15($inp)
+
+ srl $Zhi,32,$Xhi
+ sll $Zhi,32,$Zhi
+
+ or $Zhi,$Xhi,$Xhi
+ br zero,.Louter
+
+.Ldone:
+ zapnot $t0,0x11,$t0
+ zapnot $t1,0x22,$t1
+ or $Zlo,$Xlo,$Xlo
+
+ zapnot $Zhi,0x88,$Zhi
+ or $t0,$t1,$t0
+ zapnot $t2,0x44,$t2
+
+ or $Zhi,$t0,$Zhi
+ or $Zhi,$t2,$Zhi
+
+ srl $Zhi,32,$Xhi
+ sll $Zhi,32,$Zhi
+
+ or $Zhi,$Xhi,$Xhi
+
+ stq $Xlo,8($Xi)
+ stq $Xhi,0($Xi)
+
+ .set noreorder
+ /*ldq ra,0(sp)*/
+ ldq s0,8(sp)
+ ldq s1,16(sp)
+ lda sp,32(sp)
+ ret (ra)
+.end gcm_ghash_4bit
+
+.align 4
+rem_4bit:
+ .quad 0x0000<<48, 0x1C20<<48, 0x3840<<48, 0x2460<<48
+ .quad 0x7080<<48, 0x6CA0<<48, 0x48C0<<48, 0x54E0<<48
+ .quad 0xE100<<48, 0xFD20<<48, 0xD940<<48, 0xC560<<48
+ .quad 0x9180<<48, 0x8DA0<<48, 0xA9C0<<48, 0xB5E0<<48
+.ascii "GHASH for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
+.align 4
+
+___
+$output=shift and open STDOUT,">$output";
+print $code;
+close STDOUT;
+
diff --git a/deps/openssl/openssl/crypto/modes/asm/ghash-armv4.pl b/deps/openssl/openssl/crypto/modes/asm/ghash-armv4.pl
new file mode 100644
index 000000000..d91586ee2
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/asm/ghash-armv4.pl
@@ -0,0 +1,429 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# April 2010
+#
+# The module implements "4-bit" GCM GHASH function and underlying
+# single multiplication operation in GF(2^128). "4-bit" means that it
+# uses 256 bytes per-key table [+32 bytes shared table]. There is no
+# experimental performance data available yet. The only approximation
+# that can be made at this point is based on code size. Inner loop is
+# 32 instructions long and on single-issue core should execute in <40
+# cycles. Having verified that gcc 3.4 didn't unroll corresponding
+# loop, this assembler loop body was found to be ~3x smaller than
+# compiler-generated one...
+#
+# July 2010
+#
+# Rescheduling for dual-issue pipeline resulted in 8.5% improvement on
+# Cortex A8 core and ~25 cycles per processed byte (which was observed
+# to be ~3 times faster than gcc-generated code:-)
+#
+# February 2011
+#
+# Profiler-assisted and platform-specific optimization resulted in 7%
+# improvement on Cortex A8 core and ~23.5 cycles per byte.
+#
+# March 2011
+#
+# Add NEON implementation featuring polynomial multiplication, i.e. no
+# lookup tables involved. On Cortex A8 it was measured to process one
+# byte in 15 cycles or 55% faster than integer-only code.
+
+# ====================================================================
+# Note about "528B" variant. In ARM case it makes lesser sense to
+# implement it for following reasons:
+#
+# - performance improvement won't be anywhere near 50%, because 128-
+# bit shift operation is neatly fused with 128-bit xor here, and
+# "538B" variant would eliminate only 4-5 instructions out of 32
+# in the inner loop (meaning that estimated improvement is ~15%);
+# - ARM-based systems are often embedded ones and extra memory
+# consumption might be unappreciated (for so little improvement);
+#
+# Byte order [in]dependence. =========================================
+#
+# Caller is expected to maintain specific *dword* order in Htable,
+# namely with *least* significant dword of 128-bit value at *lower*
+# address. This differs completely from C code and has everything to
+# do with ldm instruction and order in which dwords are "consumed" by
+# algorithm. *Byte* order within these dwords in turn is whatever
+# *native* byte order on current platform. See gcm128.c for working
+# example...
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$Xi="r0"; # argument block
+$Htbl="r1";
+$inp="r2";
+$len="r3";
+
+$Zll="r4"; # variables
+$Zlh="r5";
+$Zhl="r6";
+$Zhh="r7";
+$Tll="r8";
+$Tlh="r9";
+$Thl="r10";
+$Thh="r11";
+$nlo="r12";
+################# r13 is stack pointer
+$nhi="r14";
+################# r15 is program counter
+
+$rem_4bit=$inp; # used in gcm_gmult_4bit
+$cnt=$len;
+
+sub Zsmash() {
+ my $i=12;
+ my @args=@_;
+ for ($Zll,$Zlh,$Zhl,$Zhh) {
+ $code.=<<___;
+#if __ARM_ARCH__>=7 && defined(__ARMEL__)
+ rev $_,$_
+ str $_,[$Xi,#$i]
+#elif defined(__ARMEB__)
+ str $_,[$Xi,#$i]
+#else
+ mov $Tlh,$_,lsr#8
+ strb $_,[$Xi,#$i+3]
+ mov $Thl,$_,lsr#16
+ strb $Tlh,[$Xi,#$i+2]
+ mov $Thh,$_,lsr#24
+ strb $Thl,[$Xi,#$i+1]
+ strb $Thh,[$Xi,#$i]
+#endif
+___
+ $code.="\t".shift(@args)."\n";
+ $i-=4;
+ }
+}
+
+$code=<<___;
+#include "arm_arch.h"
+
+.text
+.code 32
+
+.type rem_4bit,%object
+.align 5
+rem_4bit:
+.short 0x0000,0x1C20,0x3840,0x2460
+.short 0x7080,0x6CA0,0x48C0,0x54E0
+.short 0xE100,0xFD20,0xD940,0xC560
+.short 0x9180,0x8DA0,0xA9C0,0xB5E0
+.size rem_4bit,.-rem_4bit
+
+.type rem_4bit_get,%function
+rem_4bit_get:
+ sub $rem_4bit,pc,#8
+ sub $rem_4bit,$rem_4bit,#32 @ &rem_4bit
+ b .Lrem_4bit_got
+ nop
+.size rem_4bit_get,.-rem_4bit_get
+
+.global gcm_ghash_4bit
+.type gcm_ghash_4bit,%function
+gcm_ghash_4bit:
+ sub r12,pc,#8
+ add $len,$inp,$len @ $len to point at the end
+ stmdb sp!,{r3-r11,lr} @ save $len/end too
+ sub r12,r12,#48 @ &rem_4bit
+
+ ldmia r12,{r4-r11} @ copy rem_4bit ...
+ stmdb sp!,{r4-r11} @ ... to stack
+
+ ldrb $nlo,[$inp,#15]
+ ldrb $nhi,[$Xi,#15]
+.Louter:
+ eor $nlo,$nlo,$nhi
+ and $nhi,$nlo,#0xf0
+ and $nlo,$nlo,#0x0f
+ mov $cnt,#14
+
+ add $Zhh,$Htbl,$nlo,lsl#4
+ ldmia $Zhh,{$Zll-$Zhh} @ load Htbl[nlo]
+ add $Thh,$Htbl,$nhi
+ ldrb $nlo,[$inp,#14]
+
+ and $nhi,$Zll,#0xf @ rem
+ ldmia $Thh,{$Tll-$Thh} @ load Htbl[nhi]
+ add $nhi,$nhi,$nhi
+ eor $Zll,$Tll,$Zll,lsr#4
+ ldrh $Tll,[sp,$nhi] @ rem_4bit[rem]
+ eor $Zll,$Zll,$Zlh,lsl#28
+ ldrb $nhi,[$Xi,#14]
+ eor $Zlh,$Tlh,$Zlh,lsr#4
+ eor $Zlh,$Zlh,$Zhl,lsl#28
+ eor $Zhl,$Thl,$Zhl,lsr#4
+ eor $Zhl,$Zhl,$Zhh,lsl#28
+ eor $Zhh,$Thh,$Zhh,lsr#4
+ eor $nlo,$nlo,$nhi
+ and $nhi,$nlo,#0xf0
+ and $nlo,$nlo,#0x0f
+ eor $Zhh,$Zhh,$Tll,lsl#16
+
+.Linner:
+ add $Thh,$Htbl,$nlo,lsl#4
+ and $nlo,$Zll,#0xf @ rem
+ subs $cnt,$cnt,#1
+ add $nlo,$nlo,$nlo
+ ldmia $Thh,{$Tll-$Thh} @ load Htbl[nlo]
+ eor $Zll,$Tll,$Zll,lsr#4
+ eor $Zll,$Zll,$Zlh,lsl#28
+ eor $Zlh,$Tlh,$Zlh,lsr#4
+ eor $Zlh,$Zlh,$Zhl,lsl#28
+ ldrh $Tll,[sp,$nlo] @ rem_4bit[rem]
+ eor $Zhl,$Thl,$Zhl,lsr#4
+ ldrplb $nlo,[$inp,$cnt]
+ eor $Zhl,$Zhl,$Zhh,lsl#28
+ eor $Zhh,$Thh,$Zhh,lsr#4
+
+ add $Thh,$Htbl,$nhi
+ and $nhi,$Zll,#0xf @ rem
+ eor $Zhh,$Zhh,$Tll,lsl#16 @ ^= rem_4bit[rem]
+ add $nhi,$nhi,$nhi
+ ldmia $Thh,{$Tll-$Thh} @ load Htbl[nhi]
+ eor $Zll,$Tll,$Zll,lsr#4
+ ldrplb $Tll,[$Xi,$cnt]
+ eor $Zll,$Zll,$Zlh,lsl#28
+ eor $Zlh,$Tlh,$Zlh,lsr#4
+ ldrh $Tlh,[sp,$nhi]
+ eor $Zlh,$Zlh,$Zhl,lsl#28
+ eor $Zhl,$Thl,$Zhl,lsr#4
+ eor $Zhl,$Zhl,$Zhh,lsl#28
+ eorpl $nlo,$nlo,$Tll
+ eor $Zhh,$Thh,$Zhh,lsr#4
+ andpl $nhi,$nlo,#0xf0
+ andpl $nlo,$nlo,#0x0f
+ eor $Zhh,$Zhh,$Tlh,lsl#16 @ ^= rem_4bit[rem]
+ bpl .Linner
+
+ ldr $len,[sp,#32] @ re-load $len/end
+ add $inp,$inp,#16
+ mov $nhi,$Zll
+___
+ &Zsmash("cmp\t$inp,$len","ldrneb\t$nlo,[$inp,#15]");
+$code.=<<___;
+ bne .Louter
+
+ add sp,sp,#36
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r11,pc}
+#else
+ ldmia sp!,{r4-r11,lr}
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ bx lr @ interoperable with Thumb ISA:-)
+#endif
+.size gcm_ghash_4bit,.-gcm_ghash_4bit
+
+.global gcm_gmult_4bit
+.type gcm_gmult_4bit,%function
+gcm_gmult_4bit:
+ stmdb sp!,{r4-r11,lr}
+ ldrb $nlo,[$Xi,#15]
+ b rem_4bit_get
+.Lrem_4bit_got:
+ and $nhi,$nlo,#0xf0
+ and $nlo,$nlo,#0x0f
+ mov $cnt,#14
+
+ add $Zhh,$Htbl,$nlo,lsl#4
+ ldmia $Zhh,{$Zll-$Zhh} @ load Htbl[nlo]
+ ldrb $nlo,[$Xi,#14]
+
+ add $Thh,$Htbl,$nhi
+ and $nhi,$Zll,#0xf @ rem
+ ldmia $Thh,{$Tll-$Thh} @ load Htbl[nhi]
+ add $nhi,$nhi,$nhi
+ eor $Zll,$Tll,$Zll,lsr#4
+ ldrh $Tll,[$rem_4bit,$nhi] @ rem_4bit[rem]
+ eor $Zll,$Zll,$Zlh,lsl#28
+ eor $Zlh,$Tlh,$Zlh,lsr#4
+ eor $Zlh,$Zlh,$Zhl,lsl#28
+ eor $Zhl,$Thl,$Zhl,lsr#4
+ eor $Zhl,$Zhl,$Zhh,lsl#28
+ eor $Zhh,$Thh,$Zhh,lsr#4
+ and $nhi,$nlo,#0xf0
+ eor $Zhh,$Zhh,$Tll,lsl#16
+ and $nlo,$nlo,#0x0f
+
+.Loop:
+ add $Thh,$Htbl,$nlo,lsl#4
+ and $nlo,$Zll,#0xf @ rem
+ subs $cnt,$cnt,#1
+ add $nlo,$nlo,$nlo
+ ldmia $Thh,{$Tll-$Thh} @ load Htbl[nlo]
+ eor $Zll,$Tll,$Zll,lsr#4
+ eor $Zll,$Zll,$Zlh,lsl#28
+ eor $Zlh,$Tlh,$Zlh,lsr#4
+ eor $Zlh,$Zlh,$Zhl,lsl#28
+ ldrh $Tll,[$rem_4bit,$nlo] @ rem_4bit[rem]
+ eor $Zhl,$Thl,$Zhl,lsr#4
+ ldrplb $nlo,[$Xi,$cnt]
+ eor $Zhl,$Zhl,$Zhh,lsl#28
+ eor $Zhh,$Thh,$Zhh,lsr#4
+
+ add $Thh,$Htbl,$nhi
+ and $nhi,$Zll,#0xf @ rem
+ eor $Zhh,$Zhh,$Tll,lsl#16 @ ^= rem_4bit[rem]
+ add $nhi,$nhi,$nhi
+ ldmia $Thh,{$Tll-$Thh} @ load Htbl[nhi]
+ eor $Zll,$Tll,$Zll,lsr#4
+ eor $Zll,$Zll,$Zlh,lsl#28
+ eor $Zlh,$Tlh,$Zlh,lsr#4
+ ldrh $Tll,[$rem_4bit,$nhi] @ rem_4bit[rem]
+ eor $Zlh,$Zlh,$Zhl,lsl#28
+ eor $Zhl,$Thl,$Zhl,lsr#4
+ eor $Zhl,$Zhl,$Zhh,lsl#28
+ eor $Zhh,$Thh,$Zhh,lsr#4
+ andpl $nhi,$nlo,#0xf0
+ andpl $nlo,$nlo,#0x0f
+ eor $Zhh,$Zhh,$Tll,lsl#16 @ ^= rem_4bit[rem]
+ bpl .Loop
+___
+ &Zsmash();
+$code.=<<___;
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r11,pc}
+#else
+ ldmia sp!,{r4-r11,lr}
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ bx lr @ interoperable with Thumb ISA:-)
+#endif
+.size gcm_gmult_4bit,.-gcm_gmult_4bit
+___
+{
+my $cnt=$Htbl; # $Htbl is used once in the very beginning
+
+my ($Hhi, $Hlo, $Zo, $T, $xi, $mod) = map("d$_",(0..7));
+my ($Qhi, $Qlo, $Z, $R, $zero, $Qpost, $IN) = map("q$_",(8..15));
+
+# Z:Zo keeps 128-bit result shifted by 1 to the right, with bottom bit
+# in Zo. Or should I say "top bit", because GHASH is specified in
+# reverse bit order? Otherwise straightforward 128-bt H by one input
+# byte multiplication and modulo-reduction, times 16.
+
+sub Dlo() { shift=~m|q([1]?[0-9])|?"d".($1*2):""; }
+sub Dhi() { shift=~m|q([1]?[0-9])|?"d".($1*2+1):""; }
+sub Q() { shift=~m|d([1-3]?[02468])|?"q".($1/2):""; }
+
+$code.=<<___;
+#if __ARM_ARCH__>=7
+.fpu neon
+
+.global gcm_gmult_neon
+.type gcm_gmult_neon,%function
+.align 4
+gcm_gmult_neon:
+ sub $Htbl,#16 @ point at H in GCM128_CTX
+ vld1.64 `&Dhi("$IN")`,[$Xi,:64]!@ load Xi
+ vmov.i32 $mod,#0xe1 @ our irreducible polynomial
+ vld1.64 `&Dlo("$IN")`,[$Xi,:64]!
+ vshr.u64 $mod,#32
+ vldmia $Htbl,{$Hhi-$Hlo} @ load H
+ veor $zero,$zero
+#ifdef __ARMEL__
+ vrev64.8 $IN,$IN
+#endif
+ veor $Qpost,$Qpost
+ veor $R,$R
+ mov $cnt,#16
+ veor $Z,$Z
+ mov $len,#16
+ veor $Zo,$Zo
+ vdup.8 $xi,`&Dlo("$IN")`[0] @ broadcast lowest byte
+ b .Linner_neon
+.size gcm_gmult_neon,.-gcm_gmult_neon
+
+.global gcm_ghash_neon
+.type gcm_ghash_neon,%function
+.align 4
+gcm_ghash_neon:
+ vld1.64 `&Dhi("$Z")`,[$Xi,:64]! @ load Xi
+ vmov.i32 $mod,#0xe1 @ our irreducible polynomial
+ vld1.64 `&Dlo("$Z")`,[$Xi,:64]!
+ vshr.u64 $mod,#32
+ vldmia $Xi,{$Hhi-$Hlo} @ load H
+ veor $zero,$zero
+ nop
+#ifdef __ARMEL__
+ vrev64.8 $Z,$Z
+#endif
+.Louter_neon:
+ vld1.64 `&Dhi($IN)`,[$inp]! @ load inp
+ veor $Qpost,$Qpost
+ vld1.64 `&Dlo($IN)`,[$inp]!
+ veor $R,$R
+ mov $cnt,#16
+#ifdef __ARMEL__
+ vrev64.8 $IN,$IN
+#endif
+ veor $Zo,$Zo
+ veor $IN,$Z @ inp^=Xi
+ veor $Z,$Z
+ vdup.8 $xi,`&Dlo("$IN")`[0] @ broadcast lowest byte
+.Linner_neon:
+ subs $cnt,$cnt,#1
+ vmull.p8 $Qlo,$Hlo,$xi @ H.lo·Xi[i]
+ vmull.p8 $Qhi,$Hhi,$xi @ H.hi·Xi[i]
+ vext.8 $IN,$zero,#1 @ IN>>=8
+
+ veor $Z,$Qpost @ modulo-scheduled part
+ vshl.i64 `&Dlo("$R")`,#48
+ vdup.8 $xi,`&Dlo("$IN")`[0] @ broadcast lowest byte
+ veor $T,`&Dlo("$Qlo")`,`&Dlo("$Z")`
+
+ veor `&Dhi("$Z")`,`&Dlo("$R")`
+ vuzp.8 $Qlo,$Qhi
+ vsli.8 $Zo,$T,#1 @ compose the "carry" byte
+ vext.8 $Z,$zero,#1 @ Z>>=8
+
+ vmull.p8 $R,$Zo,$mod @ "carry"·0xe1
+ vshr.u8 $Zo,$T,#7 @ save Z's bottom bit
+ vext.8 $Qpost,$Qlo,$zero,#1 @ Qlo>>=8
+ veor $Z,$Qhi
+ bne .Linner_neon
+
+ veor $Z,$Qpost @ modulo-scheduled artefact
+ vshl.i64 `&Dlo("$R")`,#48
+ veor `&Dhi("$Z")`,`&Dlo("$R")`
+
+ @ finalization, normalize Z:Zo
+ vand $Zo,$mod @ suffices to mask the bit
+ vshr.u64 `&Dhi(&Q("$Zo"))`,`&Dlo("$Z")`,#63
+ vshl.i64 $Z,#1
+ subs $len,#16
+ vorr $Z,`&Q("$Zo")` @ Z=Z:Zo<<1
+ bne .Louter_neon
+
+#ifdef __ARMEL__
+ vrev64.8 $Z,$Z
+#endif
+ sub $Xi,#16
+ vst1.64 `&Dhi("$Z")`,[$Xi,:64]! @ write out Xi
+ vst1.64 `&Dlo("$Z")`,[$Xi,:64]
+
+ bx lr
+.size gcm_ghash_neon,.-gcm_ghash_neon
+#endif
+___
+}
+$code.=<<___;
+.asciz "GHASH for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
+.align 2
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
+print $code;
+close STDOUT; # enforce flush
diff --git a/deps/openssl/openssl/crypto/modes/asm/ghash-ia64.pl b/deps/openssl/openssl/crypto/modes/asm/ghash-ia64.pl
new file mode 100755
index 000000000..0354c9544
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/asm/ghash-ia64.pl
@@ -0,0 +1,463 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# March 2010
+#
+# The module implements "4-bit" GCM GHASH function and underlying
+# single multiplication operation in GF(2^128). "4-bit" means that it
+# uses 256 bytes per-key table [+128 bytes shared table]. Streamed
+# GHASH performance was measured to be 6.67 cycles per processed byte
+# on Itanium 2, which is >90% better than Microsoft compiler generated
+# code. To anchor to something else sha1-ia64.pl module processes one
+# byte in 5.7 cycles. On Itanium GHASH should run at ~8.5 cycles per
+# byte.
+
+# September 2010
+#
+# It was originally thought that it makes lesser sense to implement
+# "528B" variant on Itanium 2 for following reason. Because number of
+# functional units is naturally limited, it appeared impossible to
+# implement "528B" loop in 4 cycles, only in 5. This would mean that
+# theoretically performance improvement couldn't be more than 20%.
+# But occasionally you prove yourself wrong:-) I figured out a way to
+# fold couple of instructions and having freed yet another instruction
+# slot by unrolling the loop... Resulting performance is 4.45 cycles
+# per processed byte and 50% better than "256B" version. On original
+# Itanium performance should remain the same as the "256B" version,
+# i.e. ~8.5 cycles.
+
+$output=shift and (open STDOUT,">$output" or die "can't open $output: $!");
+
+if ($^O eq "hpux") {
+ $ADDP="addp4";
+ for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
+} else { $ADDP="add"; }
+for (@ARGV) { $big_endian=1 if (/\-DB_ENDIAN/);
+ $big_endian=0 if (/\-DL_ENDIAN/); }
+if (!defined($big_endian))
+ { $big_endian=(unpack('L',pack('N',1))==1); }
+
+sub loop() {
+my $label=shift;
+my ($p16,$p17)=(shift)?("p63","p63"):("p16","p17"); # mask references to inp
+
+# Loop is scheduled for 6 ticks on Itanium 2 and 8 on Itanium, i.e.
+# in scalable manner;-) Naturally assuming data in L1 cache...
+# Special note about 'dep' instruction, which is used to construct
+# &rem_4bit[Zlo&0xf]. It works, because rem_4bit is aligned at 128
+# bytes boundary and lower 7 bits of its address are guaranteed to
+# be zero.
+$code.=<<___;
+$label:
+{ .mfi; (p18) ld8 Hlo=[Hi[1]],-8
+ (p19) dep rem=Zlo,rem_4bitp,3,4 }
+{ .mfi; (p19) xor Zhi=Zhi,Hhi
+ ($p17) xor xi[1]=xi[1],in[1] };;
+{ .mfi; (p18) ld8 Hhi=[Hi[1]]
+ (p19) shrp Zlo=Zhi,Zlo,4 }
+{ .mfi; (p19) ld8 rem=[rem]
+ (p18) and Hi[1]=mask0xf0,xi[2] };;
+{ .mmi; ($p16) ld1 in[0]=[inp],-1
+ (p18) xor Zlo=Zlo,Hlo
+ (p19) shr.u Zhi=Zhi,4 }
+{ .mib; (p19) xor Hhi=Hhi,rem
+ (p18) add Hi[1]=Htbl,Hi[1] };;
+
+{ .mfi; (p18) ld8 Hlo=[Hi[1]],-8
+ (p18) dep rem=Zlo,rem_4bitp,3,4 }
+{ .mfi; (p17) shladd Hi[0]=xi[1],4,r0
+ (p18) xor Zhi=Zhi,Hhi };;
+{ .mfi; (p18) ld8 Hhi=[Hi[1]]
+ (p18) shrp Zlo=Zhi,Zlo,4 }
+{ .mfi; (p18) ld8 rem=[rem]
+ (p17) and Hi[0]=mask0xf0,Hi[0] };;
+{ .mmi; (p16) ld1 xi[0]=[Xi],-1
+ (p18) xor Zlo=Zlo,Hlo
+ (p18) shr.u Zhi=Zhi,4 }
+{ .mib; (p18) xor Hhi=Hhi,rem
+ (p17) add Hi[0]=Htbl,Hi[0]
+ br.ctop.sptk $label };;
+___
+}
+
+$code=<<___;
+.explicit
+.text
+
+prevfs=r2; prevlc=r3; prevpr=r8;
+mask0xf0=r21;
+rem=r22; rem_4bitp=r23;
+Xi=r24; Htbl=r25;
+inp=r26; end=r27;
+Hhi=r28; Hlo=r29;
+Zhi=r30; Zlo=r31;
+
+.align 128
+.skip 16 // aligns loop body
+.global gcm_gmult_4bit#
+.proc gcm_gmult_4bit#
+gcm_gmult_4bit:
+ .prologue
+{ .mmi; .save ar.pfs,prevfs
+ alloc prevfs=ar.pfs,2,6,0,8
+ $ADDP Xi=15,in0 // &Xi[15]
+ mov rem_4bitp=ip }
+{ .mii; $ADDP Htbl=8,in1 // &Htbl[0].lo
+ .save ar.lc,prevlc
+ mov prevlc=ar.lc
+ .save pr,prevpr
+ mov prevpr=pr };;
+
+ .body
+ .rotr in[3],xi[3],Hi[2]
+
+{ .mib; ld1 xi[2]=[Xi],-1 // Xi[15]
+ mov mask0xf0=0xf0
+ brp.loop.imp .Loop1,.Lend1-16};;
+{ .mmi; ld1 xi[1]=[Xi],-1 // Xi[14]
+ };;
+{ .mii; shladd Hi[1]=xi[2],4,r0
+ mov pr.rot=0x7<<16
+ mov ar.lc=13 };;
+{ .mii; and Hi[1]=mask0xf0,Hi[1]
+ mov ar.ec=3
+ xor Zlo=Zlo,Zlo };;
+{ .mii; add Hi[1]=Htbl,Hi[1] // &Htbl[nlo].lo
+ add rem_4bitp=rem_4bit#-gcm_gmult_4bit#,rem_4bitp
+ xor Zhi=Zhi,Zhi };;
+___
+ &loop (".Loop1",1);
+$code.=<<___;
+.Lend1:
+{ .mib; xor Zhi=Zhi,Hhi };; // modulo-scheduling artefact
+{ .mib; mux1 Zlo=Zlo,\@rev };;
+{ .mib; mux1 Zhi=Zhi,\@rev };;
+{ .mmi; add Hlo=9,Xi;; // ;; is here to prevent
+ add Hhi=1,Xi };; // pipeline flush on Itanium
+{ .mib; st8 [Hlo]=Zlo
+ mov pr=prevpr,0x1ffff };;
+{ .mib; st8 [Hhi]=Zhi
+ mov ar.lc=prevlc
+ br.ret.sptk.many b0 };;
+.endp gcm_gmult_4bit#
+___
+
+######################################################################
+# "528B" (well, "512B" actualy) streamed GHASH
+#
+$Xip="in0";
+$Htbl="in1";
+$inp="in2";
+$len="in3";
+$rem_8bit="loc0";
+$mask0xff="loc1";
+($sum,$rum) = $big_endian ? ("nop.m","nop.m") : ("sum","rum");
+
+sub load_htable() {
+ for (my $i=0;$i<8;$i++) {
+ $code.=<<___;
+{ .mmi; ld8 r`16+2*$i+1`=[r8],16 // Htable[$i].hi
+ ld8 r`16+2*$i`=[r9],16 } // Htable[$i].lo
+{ .mmi; ldf8 f`32+2*$i+1`=[r10],16 // Htable[`8+$i`].hi
+ ldf8 f`32+2*$i`=[r11],16 // Htable[`8+$i`].lo
+___
+ $code.=shift if (($i+$#_)==7);
+ $code.="\t};;\n"
+ }
+}
+
+$code.=<<___;
+prevsp=r3;
+
+.align 32
+.skip 16 // aligns loop body
+.global gcm_ghash_4bit#
+.proc gcm_ghash_4bit#
+gcm_ghash_4bit:
+ .prologue
+{ .mmi; .save ar.pfs,prevfs
+ alloc prevfs=ar.pfs,4,2,0,0
+ .vframe prevsp
+ mov prevsp=sp
+ mov $rem_8bit=ip };;
+ .body
+{ .mfi; $ADDP r8=0+0,$Htbl
+ $ADDP r9=0+8,$Htbl }
+{ .mfi; $ADDP r10=128+0,$Htbl
+ $ADDP r11=128+8,$Htbl };;
+___
+ &load_htable(
+ " $ADDP $Xip=15,$Xip", # &Xi[15]
+ " $ADDP $len=$len,$inp", # &inp[len]
+ " $ADDP $inp=15,$inp", # &inp[15]
+ " mov $mask0xff=0xff",
+ " add sp=-512,sp",
+ " andcm sp=sp,$mask0xff", # align stack frame
+ " add r14=0,sp",
+ " add r15=8,sp");
+$code.=<<___;
+{ .mmi; $sum 1<<1 // go big-endian
+ add r8=256+0,sp
+ add r9=256+8,sp }
+{ .mmi; add r10=256+128+0,sp
+ add r11=256+128+8,sp
+ add $len=-17,$len };;
+___
+for($i=0;$i<8;$i++) { # generate first half of Hshr4[]
+my ($rlo,$rhi)=("r".eval(16+2*$i),"r".eval(16+2*$i+1));
+$code.=<<___;
+{ .mmi; st8 [r8]=$rlo,16 // Htable[$i].lo
+ st8 [r9]=$rhi,16 // Htable[$i].hi
+ shrp $rlo=$rhi,$rlo,4 }//;;
+{ .mmi; stf8 [r10]=f`32+2*$i`,16 // Htable[`8+$i`].lo
+ stf8 [r11]=f`32+2*$i+1`,16 // Htable[`8+$i`].hi
+ shr.u $rhi=$rhi,4 };;
+{ .mmi; st8 [r14]=$rlo,16 // Htable[$i].lo>>4
+ st8 [r15]=$rhi,16 }//;; // Htable[$i].hi>>4
+___
+}
+$code.=<<___;
+{ .mmi; ld8 r16=[r8],16 // Htable[8].lo
+ ld8 r17=[r9],16 };; // Htable[8].hi
+{ .mmi; ld8 r18=[r8],16 // Htable[9].lo
+ ld8 r19=[r9],16 } // Htable[9].hi
+{ .mmi; rum 1<<5 // clear um.mfh
+ shrp r16=r17,r16,4 };;
+___
+for($i=0;$i<6;$i++) { # generate second half of Hshr4[]
+$code.=<<___;
+{ .mmi; ld8 r`20+2*$i`=[r8],16 // Htable[`10+$i`].lo
+ ld8 r`20+2*$i+1`=[r9],16 // Htable[`10+$i`].hi
+ shr.u r`16+2*$i+1`=r`16+2*$i+1`,4 };;
+{ .mmi; st8 [r14]=r`16+2*$i`,16 // Htable[`8+$i`].lo>>4
+ st8 [r15]=r`16+2*$i+1`,16 // Htable[`8+$i`].hi>>4
+ shrp r`18+2*$i`=r`18+2*$i+1`,r`18+2*$i`,4 }
+___
+}
+$code.=<<___;
+{ .mmi; shr.u r`16+2*$i+1`=r`16+2*$i+1`,4 };;
+{ .mmi; st8 [r14]=r`16+2*$i`,16 // Htable[`8+$i`].lo>>4
+ st8 [r15]=r`16+2*$i+1`,16 // Htable[`8+$i`].hi>>4
+ shrp r`18+2*$i`=r`18+2*$i+1`,r`18+2*$i`,4 }
+{ .mmi; add $Htbl=256,sp // &Htable[0]
+ add $rem_8bit=rem_8bit#-gcm_ghash_4bit#,$rem_8bit
+ shr.u r`18+2*$i+1`=r`18+2*$i+1`,4 };;
+{ .mmi; st8 [r14]=r`18+2*$i` // Htable[`8+$i`].lo>>4
+ st8 [r15]=r`18+2*$i+1` } // Htable[`8+$i`].hi>>4
+___
+
+$in="r15";
+@xi=("r16","r17");
+@rem=("r18","r19");
+($Alo,$Ahi,$Blo,$Bhi,$Zlo,$Zhi)=("r20","r21","r22","r23","r24","r25");
+($Atbl,$Btbl)=("r26","r27");
+
+$code.=<<___; # (p16)
+{ .mmi; ld1 $in=[$inp],-1 //(p16) *inp--
+ ld1 $xi[0]=[$Xip],-1 //(p16) *Xi--
+ cmp.eq p0,p6=r0,r0 };; // clear p6
+___
+push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers
+
+$code.=<<___; # (p16),(p17)
+{ .mmi; ld1 $xi[0]=[$Xip],-1 //(p16) *Xi--
+ xor $xi[1]=$xi[1],$in };; //(p17) xi=$xi[i]^inp[i]
+{ .mii; ld1 $in=[$inp],-1 //(p16) *inp--
+ dep $Atbl=$xi[1],$Htbl,4,4 //(p17) &Htable[nlo].lo
+ and $xi[1]=-16,$xi[1] };; //(p17) nhi=xi&0xf0
+.align 32
+.LOOP:
+{ .mmi;
+(p6) st8 [$Xip]=$Zhi,13
+ xor $Zlo=$Zlo,$Zlo
+ add $Btbl=$xi[1],$Htbl };; //(p17) &Htable[nhi].lo
+___
+push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers
+
+$code.=<<___; # (p16),(p17),(p18)
+{ .mmi; ld8 $Alo=[$Atbl],8 //(p18) Htable[nlo].lo,&Htable[nlo].hi
+ ld8 $rem[0]=[$Btbl],-256 //(p18) Htable[nhi].lo,&Hshr4[nhi].lo
+ xor $xi[1]=$xi[1],$in };; //(p17) xi=$xi[i]^inp[i]
+{ .mfi; ld8 $Ahi=[$Atbl] //(p18) Htable[nlo].hi
+ dep $Atbl=$xi[1],$Htbl,4,4 } //(p17) &Htable[nlo].lo
+{ .mfi; shladd $rem[0]=$rem[0],4,r0 //(p18) Htable[nhi].lo<<4
+ xor $Zlo=$Zlo,$Alo };; //(p18) Z.lo^=Htable[nlo].lo
+{ .mmi; ld8 $Blo=[$Btbl],8 //(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi
+ ld1 $in=[$inp],-1 } //(p16) *inp--
+{ .mmi; xor $rem[0]=$rem[0],$Zlo //(p18) Z.lo^(Htable[nhi].lo<<4)
+ mov $Zhi=$Ahi //(p18) Z.hi^=Htable[nlo].hi
+ and $xi[1]=-16,$xi[1] };; //(p17) nhi=xi&0xf0
+{ .mmi; ld8 $Bhi=[$Btbl] //(p18) Hshr4[nhi].hi
+ ld1 $xi[0]=[$Xip],-1 //(p16) *Xi--
+ shrp $Zlo=$Zhi,$Zlo,8 } //(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8)
+{ .mmi; and $rem[0]=$rem[0],$mask0xff //(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
+ add $Btbl=$xi[1],$Htbl };; //(p17) &Htable[nhi]
+___
+push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers
+
+for ($i=1;$i<14;$i++) {
+# Above and below fragments are derived from this one by removing
+# unsuitable (p??) instructions.
+$code.=<<___; # (p16),(p17),(p18),(p19)
+{ .mmi; ld8 $Alo=[$Atbl],8 //(p18) Htable[nlo].lo,&Htable[nlo].hi
+ ld8 $rem[0]=[$Btbl],-256 //(p18) Htable[nhi].lo,&Hshr4[nhi].lo
+ shr.u $Zhi=$Zhi,8 } //(p19) Z.hi>>=8
+{ .mmi; shladd $rem[1]=$rem[1],1,$rem_8bit //(p19) &rem_8bit[rem]
+ xor $Zlo=$Zlo,$Blo //(p19) Z.lo^=Hshr4[nhi].lo
+ xor $xi[1]=$xi[1],$in };; //(p17) xi=$xi[i]^inp[i]
+{ .mmi; ld8 $Ahi=[$Atbl] //(p18) Htable[nlo].hi
+ ld2 $rem[1]=[$rem[1]] //(p19) rem_8bit[rem]
+ dep $Atbl=$xi[1],$Htbl,4,4 } //(p17) &Htable[nlo].lo
+{ .mmi; shladd $rem[0]=$rem[0],4,r0 //(p18) Htable[nhi].lo<<4
+ xor $Zlo=$Zlo,$Alo //(p18) Z.lo^=Htable[nlo].lo
+ xor $Zhi=$Zhi,$Bhi };; //(p19) Z.hi^=Hshr4[nhi].hi
+{ .mmi; ld8 $Blo=[$Btbl],8 //(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi
+ ld1 $in=[$inp],-1 //(p16) *inp--
+ shl $rem[1]=$rem[1],48 } //(p19) rem_8bit[rem]<<48
+{ .mmi; xor $rem[0]=$rem[0],$Zlo //(p18) Z.lo^(Htable[nhi].lo<<4)
+ xor $Zhi=$Zhi,$Ahi //(p18) Z.hi^=Htable[nlo].hi
+ and $xi[1]=-16,$xi[1] };; //(p17) nhi=xi&0xf0
+{ .mmi; ld8 $Bhi=[$Btbl] //(p18) Hshr4[nhi].hi
+ ld1 $xi[0]=[$Xip],-1 //(p16) *Xi--
+ shrp $Zlo=$Zhi,$Zlo,8 } //(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8)
+{ .mmi; and $rem[0]=$rem[0],$mask0xff //(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
+ xor $Zhi=$Zhi,$rem[1] //(p19) Z.hi^=rem_8bit[rem]<<48
+ add $Btbl=$xi[1],$Htbl };; //(p17) &Htable[nhi]
+___
+push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers
+}
+
+$code.=<<___; # (p17),(p18),(p19)
+{ .mmi; ld8 $Alo=[$Atbl],8 //(p18) Htable[nlo].lo,&Htable[nlo].hi
+ ld8 $rem[0]=[$Btbl],-256 //(p18) Htable[nhi].lo,&Hshr4[nhi].lo
+ shr.u $Zhi=$Zhi,8 } //(p19) Z.hi>>=8
+{ .mmi; shladd $rem[1]=$rem[1],1,$rem_8bit //(p19) &rem_8bit[rem]
+ xor $Zlo=$Zlo,$Blo //(p19) Z.lo^=Hshr4[nhi].lo
+ xor $xi[1]=$xi[1],$in };; //(p17) xi=$xi[i]^inp[i]
+{ .mmi; ld8 $Ahi=[$Atbl] //(p18) Htable[nlo].hi
+ ld2 $rem[1]=[$rem[1]] //(p19) rem_8bit[rem]
+ dep $Atbl=$xi[1],$Htbl,4,4 };; //(p17) &Htable[nlo].lo
+{ .mmi; shladd $rem[0]=$rem[0],4,r0 //(p18) Htable[nhi].lo<<4
+ xor $Zlo=$Zlo,$Alo //(p18) Z.lo^=Htable[nlo].lo
+ xor $Zhi=$Zhi,$Bhi };; //(p19) Z.hi^=Hshr4[nhi].hi
+{ .mmi; ld8 $Blo=[$Btbl],8 //(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi
+ shl $rem[1]=$rem[1],48 } //(p19) rem_8bit[rem]<<48
+{ .mmi; xor $rem[0]=$rem[0],$Zlo //(p18) Z.lo^(Htable[nhi].lo<<4)
+ xor $Zhi=$Zhi,$Ahi //(p18) Z.hi^=Htable[nlo].hi
+ and $xi[1]=-16,$xi[1] };; //(p17) nhi=xi&0xf0
+{ .mmi; ld8 $Bhi=[$Btbl] //(p18) Hshr4[nhi].hi
+ shrp $Zlo=$Zhi,$Zlo,8 } //(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8)
+{ .mmi; and $rem[0]=$rem[0],$mask0xff //(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
+ xor $Zhi=$Zhi,$rem[1] //(p19) Z.hi^=rem_8bit[rem]<<48
+ add $Btbl=$xi[1],$Htbl };; //(p17) &Htable[nhi]
+___
+push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers
+
+$code.=<<___; # (p18),(p19)
+{ .mfi; ld8 $Alo=[$Atbl],8 //(p18) Htable[nlo].lo,&Htable[nlo].hi
+ shr.u $Zhi=$Zhi,8 } //(p19) Z.hi>>=8
+{ .mfi; shladd $rem[1]=$rem[1],1,$rem_8bit //(p19) &rem_8bit[rem]
+ xor $Zlo=$Zlo,$Blo };; //(p19) Z.lo^=Hshr4[nhi].lo
+{ .mfi; ld8 $Ahi=[$Atbl] //(p18) Htable[nlo].hi
+ xor $Zlo=$Zlo,$Alo } //(p18) Z.lo^=Htable[nlo].lo
+{ .mfi; ld2 $rem[1]=[$rem[1]] //(p19) rem_8bit[rem]
+ xor $Zhi=$Zhi,$Bhi };; //(p19) Z.hi^=Hshr4[nhi].hi
+{ .mfi; ld8 $Blo=[$Btbl],8 //(p18) Htable[nhi].lo,&Htable[nhi].hi
+ shl $rem[1]=$rem[1],48 } //(p19) rem_8bit[rem]<<48
+{ .mfi; shladd $rem[0]=$Zlo,4,r0 //(p18) Z.lo<<4
+ xor $Zhi=$Zhi,$Ahi };; //(p18) Z.hi^=Htable[nlo].hi
+{ .mfi; ld8 $Bhi=[$Btbl] //(p18) Htable[nhi].hi
+ shrp $Zlo=$Zhi,$Zlo,4 } //(p18) Z.lo=(Z.hi<<60)|(Z.lo>>4)
+{ .mfi; and $rem[0]=$rem[0],$mask0xff //(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
+ xor $Zhi=$Zhi,$rem[1] };; //(p19) Z.hi^=rem_8bit[rem]<<48
+___
+push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers
+
+$code.=<<___; # (p19)
+{ .mmi; cmp.ltu p6,p0=$inp,$len
+ add $inp=32,$inp
+ shr.u $Zhi=$Zhi,4 } //(p19) Z.hi>>=4
+{ .mmi; shladd $rem[1]=$rem[1],1,$rem_8bit //(p19) &rem_8bit[rem]
+ xor $Zlo=$Zlo,$Blo //(p19) Z.lo^=Hshr4[nhi].lo
+ add $Xip=9,$Xip };; // &Xi.lo
+{ .mmi; ld2 $rem[1]=[$rem[1]] //(p19) rem_8bit[rem]
+(p6) ld1 $in=[$inp],-1 //[p16] *inp--
+(p6) extr.u $xi[1]=$Zlo,8,8 } //[p17] Xi[14]
+{ .mmi; xor $Zhi=$Zhi,$Bhi //(p19) Z.hi^=Hshr4[nhi].hi
+(p6) and $xi[0]=$Zlo,$mask0xff };; //[p16] Xi[15]
+{ .mmi; st8 [$Xip]=$Zlo,-8
+(p6) xor $xi[0]=$xi[0],$in //[p17] xi=$xi[i]^inp[i]
+ shl $rem[1]=$rem[1],48 };; //(p19) rem_8bit[rem]<<48
+{ .mmi;
+(p6) ld1 $in=[$inp],-1 //[p16] *inp--
+ xor $Zhi=$Zhi,$rem[1] //(p19) Z.hi^=rem_8bit[rem]<<48
+(p6) dep $Atbl=$xi[0],$Htbl,4,4 } //[p17] &Htable[nlo].lo
+{ .mib;
+(p6) and $xi[0]=-16,$xi[0] //[p17] nhi=xi&0xf0
+(p6) br.cond.dptk.many .LOOP };;
+
+{ .mib; st8 [$Xip]=$Zhi };;
+{ .mib; $rum 1<<1 // return to little-endian
+ .restore sp
+ mov sp=prevsp
+ br.ret.sptk.many b0 };;
+.endp gcm_ghash_4bit#
+___
+$code.=<<___;
+.align 128
+.type rem_4bit#,\@object
+rem_4bit:
+ data8 0x0000<<48, 0x1C20<<48, 0x3840<<48, 0x2460<<48
+ data8 0x7080<<48, 0x6CA0<<48, 0x48C0<<48, 0x54E0<<48
+ data8 0xE100<<48, 0xFD20<<48, 0xD940<<48, 0xC560<<48
+ data8 0x9180<<48, 0x8DA0<<48, 0xA9C0<<48, 0xB5E0<<48
+.size rem_4bit#,128
+.type rem_8bit#,\@object
+rem_8bit:
+ data1 0x00,0x00, 0x01,0xC2, 0x03,0x84, 0x02,0x46, 0x07,0x08, 0x06,0xCA, 0x04,0x8C, 0x05,0x4E
+ data1 0x0E,0x10, 0x0F,0xD2, 0x0D,0x94, 0x0C,0x56, 0x09,0x18, 0x08,0xDA, 0x0A,0x9C, 0x0B,0x5E
+ data1 0x1C,0x20, 0x1D,0xE2, 0x1F,0xA4, 0x1E,0x66, 0x1B,0x28, 0x1A,0xEA, 0x18,0xAC, 0x19,0x6E
+ data1 0x12,0x30, 0x13,0xF2, 0x11,0xB4, 0x10,0x76, 0x15,0x38, 0x14,0xFA, 0x16,0xBC, 0x17,0x7E
+ data1 0x38,0x40, 0x39,0x82, 0x3B,0xC4, 0x3A,0x06, 0x3F,0x48, 0x3E,0x8A, 0x3C,0xCC, 0x3D,0x0E
+ data1 0x36,0x50, 0x37,0x92, 0x35,0xD4, 0x34,0x16, 0x31,0x58, 0x30,0x9A, 0x32,0xDC, 0x33,0x1E
+ data1 0x24,0x60, 0x25,0xA2, 0x27,0xE4, 0x26,0x26, 0x23,0x68, 0x22,0xAA, 0x20,0xEC, 0x21,0x2E
+ data1 0x2A,0x70, 0x2B,0xB2, 0x29,0xF4, 0x28,0x36, 0x2D,0x78, 0x2C,0xBA, 0x2E,0xFC, 0x2F,0x3E
+ data1 0x70,0x80, 0x71,0x42, 0x73,0x04, 0x72,0xC6, 0x77,0x88, 0x76,0x4A, 0x74,0x0C, 0x75,0xCE
+ data1 0x7E,0x90, 0x7F,0x52, 0x7D,0x14, 0x7C,0xD6, 0x79,0x98, 0x78,0x5A, 0x7A,0x1C, 0x7B,0xDE
+ data1 0x6C,0xA0, 0x6D,0x62, 0x6F,0x24, 0x6E,0xE6, 0x6B,0xA8, 0x6A,0x6A, 0x68,0x2C, 0x69,0xEE
+ data1 0x62,0xB0, 0x63,0x72, 0x61,0x34, 0x60,0xF6, 0x65,0xB8, 0x64,0x7A, 0x66,0x3C, 0x67,0xFE
+ data1 0x48,0xC0, 0x49,0x02, 0x4B,0x44, 0x4A,0x86, 0x4F,0xC8, 0x4E,0x0A, 0x4C,0x4C, 0x4D,0x8E
+ data1 0x46,0xD0, 0x47,0x12, 0x45,0x54, 0x44,0x96, 0x41,0xD8, 0x40,0x1A, 0x42,0x5C, 0x43,0x9E
+ data1 0x54,0xE0, 0x55,0x22, 0x57,0x64, 0x56,0xA6, 0x53,0xE8, 0x52,0x2A, 0x50,0x6C, 0x51,0xAE
+ data1 0x5A,0xF0, 0x5B,0x32, 0x59,0x74, 0x58,0xB6, 0x5D,0xF8, 0x5C,0x3A, 0x5E,0x7C, 0x5F,0xBE
+ data1 0xE1,0x00, 0xE0,0xC2, 0xE2,0x84, 0xE3,0x46, 0xE6,0x08, 0xE7,0xCA, 0xE5,0x8C, 0xE4,0x4E
+ data1 0xEF,0x10, 0xEE,0xD2, 0xEC,0x94, 0xED,0x56, 0xE8,0x18, 0xE9,0xDA, 0xEB,0x9C, 0xEA,0x5E
+ data1 0xFD,0x20, 0xFC,0xE2, 0xFE,0xA4, 0xFF,0x66, 0xFA,0x28, 0xFB,0xEA, 0xF9,0xAC, 0xF8,0x6E
+ data1 0xF3,0x30, 0xF2,0xF2, 0xF0,0xB4, 0xF1,0x76, 0xF4,0x38, 0xF5,0xFA, 0xF7,0xBC, 0xF6,0x7E
+ data1 0xD9,0x40, 0xD8,0x82, 0xDA,0xC4, 0xDB,0x06, 0xDE,0x48, 0xDF,0x8A, 0xDD,0xCC, 0xDC,0x0E
+ data1 0xD7,0x50, 0xD6,0x92, 0xD4,0xD4, 0xD5,0x16, 0xD0,0x58, 0xD1,0x9A, 0xD3,0xDC, 0xD2,0x1E
+ data1 0xC5,0x60, 0xC4,0xA2, 0xC6,0xE4, 0xC7,0x26, 0xC2,0x68, 0xC3,0xAA, 0xC1,0xEC, 0xC0,0x2E
+ data1 0xCB,0x70, 0xCA,0xB2, 0xC8,0xF4, 0xC9,0x36, 0xCC,0x78, 0xCD,0xBA, 0xCF,0xFC, 0xCE,0x3E
+ data1 0x91,0x80, 0x90,0x42, 0x92,0x04, 0x93,0xC6, 0x96,0x88, 0x97,0x4A, 0x95,0x0C, 0x94,0xCE
+ data1 0x9F,0x90, 0x9E,0x52, 0x9C,0x14, 0x9D,0xD6, 0x98,0x98, 0x99,0x5A, 0x9B,0x1C, 0x9A,0xDE
+ data1 0x8D,0xA0, 0x8C,0x62, 0x8E,0x24, 0x8F,0xE6, 0x8A,0xA8, 0x8B,0x6A, 0x89,0x2C, 0x88,0xEE
+ data1 0x83,0xB0, 0x82,0x72, 0x80,0x34, 0x81,0xF6, 0x84,0xB8, 0x85,0x7A, 0x87,0x3C, 0x86,0xFE
+ data1 0xA9,0xC0, 0xA8,0x02, 0xAA,0x44, 0xAB,0x86, 0xAE,0xC8, 0xAF,0x0A, 0xAD,0x4C, 0xAC,0x8E
+ data1 0xA7,0xD0, 0xA6,0x12, 0xA4,0x54, 0xA5,0x96, 0xA0,0xD8, 0xA1,0x1A, 0xA3,0x5C, 0xA2,0x9E
+ data1 0xB5,0xE0, 0xB4,0x22, 0xB6,0x64, 0xB7,0xA6, 0xB2,0xE8, 0xB3,0x2A, 0xB1,0x6C, 0xB0,0xAE
+ data1 0xBB,0xF0, 0xBA,0x32, 0xB8,0x74, 0xB9,0xB6, 0xBC,0xF8, 0xBD,0x3A, 0xBF,0x7C, 0xBE,0xBE
+.size rem_8bit#,512
+stringz "GHASH for IA64, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/mux1(\s+)\S+\@rev/nop.i$1 0x0/gm if ($big_endian);
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/modes/asm/ghash-parisc.pl b/deps/openssl/openssl/crypto/modes/asm/ghash-parisc.pl
new file mode 100644
index 000000000..8c7454ee9
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/asm/ghash-parisc.pl
@@ -0,0 +1,730 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# April 2010
+#
+# The module implements "4-bit" GCM GHASH function and underlying
+# single multiplication operation in GF(2^128). "4-bit" means that it
+# uses 256 bytes per-key table [+128 bytes shared table]. On PA-7100LC
+# it processes one byte in 19.6 cycles, which is more than twice as
+# fast as code generated by gcc 3.2. PA-RISC 2.0 loop is scheduled for
+# 8 cycles, but measured performance on PA-8600 system is ~9 cycles per
+# processed byte. This is ~2.2x faster than 64-bit code generated by
+# vendor compiler (which used to be very hard to beat:-).
+#
+# Special thanks to polarhome.com for providing HP-UX account.
+
+$flavour = shift;
+$output = shift;
+open STDOUT,">$output";
+
+if ($flavour =~ /64/) {
+ $LEVEL ="2.0W";
+ $SIZE_T =8;
+ $FRAME_MARKER =80;
+ $SAVED_RP =16;
+ $PUSH ="std";
+ $PUSHMA ="std,ma";
+ $POP ="ldd";
+ $POPMB ="ldd,mb";
+ $NREGS =6;
+} else {
+ $LEVEL ="1.0"; #"\n\t.ALLOW\t2.0";
+ $SIZE_T =4;
+ $FRAME_MARKER =48;
+ $SAVED_RP =20;
+ $PUSH ="stw";
+ $PUSHMA ="stwm";
+ $POP ="ldw";
+ $POPMB ="ldwm";
+ $NREGS =11;
+}
+
+$FRAME=10*$SIZE_T+$FRAME_MARKER;# NREGS saved regs + frame marker
+ # [+ argument transfer]
+
+################# volatile registers
+$Xi="%r26"; # argument block
+$Htbl="%r25";
+$inp="%r24";
+$len="%r23";
+$Hhh=$Htbl; # variables
+$Hll="%r22";
+$Zhh="%r21";
+$Zll="%r20";
+$cnt="%r19";
+$rem_4bit="%r28";
+$rem="%r29";
+$mask0xf0="%r31";
+
+################# preserved registers
+$Thh="%r1";
+$Tll="%r2";
+$nlo="%r3";
+$nhi="%r4";
+$byte="%r5";
+if ($SIZE_T==4) {
+ $Zhl="%r6";
+ $Zlh="%r7";
+ $Hhl="%r8";
+ $Hlh="%r9";
+ $Thl="%r10";
+ $Tlh="%r11";
+}
+$rem2="%r6"; # used in PA-RISC 2.0 code
+
+$code.=<<___;
+ .LEVEL $LEVEL
+ .SPACE \$TEXT\$
+ .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
+
+ .EXPORT gcm_gmult_4bit,ENTRY,ARGW0=GR,ARGW1=GR
+ .ALIGN 64
+gcm_gmult_4bit
+ .PROC
+ .CALLINFO FRAME=`$FRAME-10*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=$NREGS
+ .ENTRY
+ $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue
+ $PUSHMA %r3,$FRAME(%sp)
+ $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp)
+ $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp)
+ $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp)
+___
+$code.=<<___ if ($SIZE_T==4);
+ $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp)
+ $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp)
+ $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp)
+ $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp)
+ $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp)
+___
+$code.=<<___;
+ blr %r0,$rem_4bit
+ ldi 3,$rem
+L\$pic_gmult
+ andcm $rem_4bit,$rem,$rem_4bit
+ addl $inp,$len,$len
+ ldo L\$rem_4bit-L\$pic_gmult($rem_4bit),$rem_4bit
+ ldi 0xf0,$mask0xf0
+___
+$code.=<<___ if ($SIZE_T==4);
+ ldi 31,$rem
+ mtctl $rem,%cr11
+ extrd,u,*= $rem,%sar,1,$rem ; executes on PA-RISC 1.0
+ b L\$parisc1_gmult
+ nop
+___
+
+$code.=<<___;
+ ldb 15($Xi),$nlo
+ ldo 8($Htbl),$Hll
+
+ and $mask0xf0,$nlo,$nhi
+ depd,z $nlo,59,4,$nlo
+
+ ldd $nlo($Hll),$Zll
+ ldd $nlo($Hhh),$Zhh
+
+ depd,z $Zll,60,4,$rem
+ shrpd $Zhh,$Zll,4,$Zll
+ extrd,u $Zhh,59,60,$Zhh
+ ldb 14($Xi),$nlo
+
+ ldd $nhi($Hll),$Tll
+ ldd $nhi($Hhh),$Thh
+ and $mask0xf0,$nlo,$nhi
+ depd,z $nlo,59,4,$nlo
+
+ xor $Tll,$Zll,$Zll
+ xor $Thh,$Zhh,$Zhh
+ ldd $rem($rem_4bit),$rem
+ b L\$oop_gmult_pa2
+ ldi 13,$cnt
+
+ .ALIGN 8
+L\$oop_gmult_pa2
+ xor $rem,$Zhh,$Zhh ; moved here to work around gas bug
+ depd,z $Zll,60,4,$rem
+
+ shrpd $Zhh,$Zll,4,$Zll
+ extrd,u $Zhh,59,60,$Zhh
+ ldd $nlo($Hll),$Tll
+ ldd $nlo($Hhh),$Thh
+
+ xor $Tll,$Zll,$Zll
+ xor $Thh,$Zhh,$Zhh
+ ldd $rem($rem_4bit),$rem
+
+ xor $rem,$Zhh,$Zhh
+ depd,z $Zll,60,4,$rem
+ ldbx $cnt($Xi),$nlo
+
+ shrpd $Zhh,$Zll,4,$Zll
+ extrd,u $Zhh,59,60,$Zhh
+ ldd $nhi($Hll),$Tll
+ ldd $nhi($Hhh),$Thh
+
+ and $mask0xf0,$nlo,$nhi
+ depd,z $nlo,59,4,$nlo
+ ldd $rem($rem_4bit),$rem
+
+ xor $Tll,$Zll,$Zll
+ addib,uv -1,$cnt,L\$oop_gmult_pa2
+ xor $Thh,$Zhh,$Zhh
+
+ xor $rem,$Zhh,$Zhh
+ depd,z $Zll,60,4,$rem
+
+ shrpd $Zhh,$Zll,4,$Zll
+ extrd,u $Zhh,59,60,$Zhh
+ ldd $nlo($Hll),$Tll
+ ldd $nlo($Hhh),$Thh
+
+ xor $Tll,$Zll,$Zll
+ xor $Thh,$Zhh,$Zhh
+ ldd $rem($rem_4bit),$rem
+
+ xor $rem,$Zhh,$Zhh
+ depd,z $Zll,60,4,$rem
+
+ shrpd $Zhh,$Zll,4,$Zll
+ extrd,u $Zhh,59,60,$Zhh
+ ldd $nhi($Hll),$Tll
+ ldd $nhi($Hhh),$Thh
+
+ xor $Tll,$Zll,$Zll
+ xor $Thh,$Zhh,$Zhh
+ ldd $rem($rem_4bit),$rem
+
+ xor $rem,$Zhh,$Zhh
+ std $Zll,8($Xi)
+ std $Zhh,0($Xi)
+___
+
+$code.=<<___ if ($SIZE_T==4);
+ b L\$done_gmult
+ nop
+
+L\$parisc1_gmult
+ ldb 15($Xi),$nlo
+ ldo 12($Htbl),$Hll
+ ldo 8($Htbl),$Hlh
+ ldo 4($Htbl),$Hhl
+
+ and $mask0xf0,$nlo,$nhi
+ zdep $nlo,27,4,$nlo
+
+ ldwx $nlo($Hll),$Zll
+ ldwx $nlo($Hlh),$Zlh
+ ldwx $nlo($Hhl),$Zhl
+ ldwx $nlo($Hhh),$Zhh
+ zdep $Zll,28,4,$rem
+ ldb 14($Xi),$nlo
+ ldwx $rem($rem_4bit),$rem
+ shrpw $Zlh,$Zll,4,$Zll
+ ldwx $nhi($Hll),$Tll
+ shrpw $Zhl,$Zlh,4,$Zlh
+ ldwx $nhi($Hlh),$Tlh
+ shrpw $Zhh,$Zhl,4,$Zhl
+ ldwx $nhi($Hhl),$Thl
+ extru $Zhh,27,28,$Zhh
+ ldwx $nhi($Hhh),$Thh
+ xor $rem,$Zhh,$Zhh
+ and $mask0xf0,$nlo,$nhi
+ zdep $nlo,27,4,$nlo
+
+ xor $Tll,$Zll,$Zll
+ ldwx $nlo($Hll),$Tll
+ xor $Tlh,$Zlh,$Zlh
+ ldwx $nlo($Hlh),$Tlh
+ xor $Thl,$Zhl,$Zhl
+ b L\$oop_gmult_pa1
+ ldi 13,$cnt
+
+ .ALIGN 8
+L\$oop_gmult_pa1
+ zdep $Zll,28,4,$rem
+ ldwx $nlo($Hhl),$Thl
+ xor $Thh,$Zhh,$Zhh
+ ldwx $rem($rem_4bit),$rem
+ shrpw $Zlh,$Zll,4,$Zll
+ ldwx $nlo($Hhh),$Thh
+ shrpw $Zhl,$Zlh,4,$Zlh
+ ldbx $cnt($Xi),$nlo
+ xor $Tll,$Zll,$Zll
+ ldwx $nhi($Hll),$Tll
+ shrpw $Zhh,$Zhl,4,$Zhl
+ xor $Tlh,$Zlh,$Zlh
+ ldwx $nhi($Hlh),$Tlh
+ extru $Zhh,27,28,$Zhh
+ xor $Thl,$Zhl,$Zhl
+ ldwx $nhi($Hhl),$Thl
+ xor $rem,$Zhh,$Zhh
+ zdep $Zll,28,4,$rem
+ xor $Thh,$Zhh,$Zhh
+ ldwx $nhi($Hhh),$Thh
+ shrpw $Zlh,$Zll,4,$Zll
+ ldwx $rem($rem_4bit),$rem
+ shrpw $Zhl,$Zlh,4,$Zlh
+ shrpw $Zhh,$Zhl,4,$Zhl
+ and $mask0xf0,$nlo,$nhi
+ extru $Zhh,27,28,$Zhh
+ zdep $nlo,27,4,$nlo
+ xor $Tll,$Zll,$Zll
+ ldwx $nlo($Hll),$Tll
+ xor $Tlh,$Zlh,$Zlh
+ ldwx $nlo($Hlh),$Tlh
+ xor $rem,$Zhh,$Zhh
+ addib,uv -1,$cnt,L\$oop_gmult_pa1
+ xor $Thl,$Zhl,$Zhl
+
+ zdep $Zll,28,4,$rem
+ ldwx $nlo($Hhl),$Thl
+ xor $Thh,$Zhh,$Zhh
+ ldwx $rem($rem_4bit),$rem
+ shrpw $Zlh,$Zll,4,$Zll
+ ldwx $nlo($Hhh),$Thh
+ shrpw $Zhl,$Zlh,4,$Zlh
+ xor $Tll,$Zll,$Zll
+ ldwx $nhi($Hll),$Tll
+ shrpw $Zhh,$Zhl,4,$Zhl
+ xor $Tlh,$Zlh,$Zlh
+ ldwx $nhi($Hlh),$Tlh
+ extru $Zhh,27,28,$Zhh
+ xor $rem,$Zhh,$Zhh
+ xor $Thl,$Zhl,$Zhl
+ ldwx $nhi($Hhl),$Thl
+ xor $Thh,$Zhh,$Zhh
+ ldwx $nhi($Hhh),$Thh
+ zdep $Zll,28,4,$rem
+ ldwx $rem($rem_4bit),$rem
+ shrpw $Zlh,$Zll,4,$Zll
+ shrpw $Zhl,$Zlh,4,$Zlh
+ shrpw $Zhh,$Zhl,4,$Zhl
+ extru $Zhh,27,28,$Zhh
+ xor $Tll,$Zll,$Zll
+ xor $Tlh,$Zlh,$Zlh
+ xor $rem,$Zhh,$Zhh
+ stw $Zll,12($Xi)
+ xor $Thl,$Zhl,$Zhl
+ stw $Zlh,8($Xi)
+ xor $Thh,$Zhh,$Zhh
+ stw $Zhl,4($Xi)
+ stw $Zhh,0($Xi)
+___
+$code.=<<___;
+L\$done_gmult
+ $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue
+ $POP `-$FRAME+1*$SIZE_T`(%sp),%r4
+ $POP `-$FRAME+2*$SIZE_T`(%sp),%r5
+ $POP `-$FRAME+3*$SIZE_T`(%sp),%r6
+___
+$code.=<<___ if ($SIZE_T==4);
+ $POP `-$FRAME+4*$SIZE_T`(%sp),%r7
+ $POP `-$FRAME+5*$SIZE_T`(%sp),%r8
+ $POP `-$FRAME+6*$SIZE_T`(%sp),%r9
+ $POP `-$FRAME+7*$SIZE_T`(%sp),%r10
+ $POP `-$FRAME+8*$SIZE_T`(%sp),%r11
+___
+$code.=<<___;
+ bv (%r2)
+ .EXIT
+ $POPMB -$FRAME(%sp),%r3
+ .PROCEND
+
+ .EXPORT gcm_ghash_4bit,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ .ALIGN 64
+gcm_ghash_4bit
+ .PROC
+ .CALLINFO FRAME=`$FRAME-10*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=11
+ .ENTRY
+ $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue
+ $PUSHMA %r3,$FRAME(%sp)
+ $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp)
+ $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp)
+ $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp)
+___
+$code.=<<___ if ($SIZE_T==4);
+ $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp)
+ $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp)
+ $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp)
+ $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp)
+ $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp)
+___
+$code.=<<___;
+ blr %r0,$rem_4bit
+ ldi 3,$rem
+L\$pic_ghash
+ andcm $rem_4bit,$rem,$rem_4bit
+ addl $inp,$len,$len
+ ldo L\$rem_4bit-L\$pic_ghash($rem_4bit),$rem_4bit
+ ldi 0xf0,$mask0xf0
+___
+$code.=<<___ if ($SIZE_T==4);
+ ldi 31,$rem
+ mtctl $rem,%cr11
+ extrd,u,*= $rem,%sar,1,$rem ; executes on PA-RISC 1.0
+ b L\$parisc1_ghash
+ nop
+___
+
+$code.=<<___;
+ ldb 15($Xi),$nlo
+ ldo 8($Htbl),$Hll
+
+L\$outer_ghash_pa2
+ ldb 15($inp),$nhi
+ xor $nhi,$nlo,$nlo
+ and $mask0xf0,$nlo,$nhi
+ depd,z $nlo,59,4,$nlo
+
+ ldd $nlo($Hll),$Zll
+ ldd $nlo($Hhh),$Zhh
+
+ depd,z $Zll,60,4,$rem
+ shrpd $Zhh,$Zll,4,$Zll
+ extrd,u $Zhh,59,60,$Zhh
+ ldb 14($Xi),$nlo
+ ldb 14($inp),$byte
+
+ ldd $nhi($Hll),$Tll
+ ldd $nhi($Hhh),$Thh
+ xor $byte,$nlo,$nlo
+ and $mask0xf0,$nlo,$nhi
+ depd,z $nlo,59,4,$nlo
+
+ xor $Tll,$Zll,$Zll
+ xor $Thh,$Zhh,$Zhh
+ ldd $rem($rem_4bit),$rem
+ b L\$oop_ghash_pa2
+ ldi 13,$cnt
+
+ .ALIGN 8
+L\$oop_ghash_pa2
+ xor $rem,$Zhh,$Zhh ; moved here to work around gas bug
+ depd,z $Zll,60,4,$rem2
+
+ shrpd $Zhh,$Zll,4,$Zll
+ extrd,u $Zhh,59,60,$Zhh
+ ldd $nlo($Hll),$Tll
+ ldd $nlo($Hhh),$Thh
+
+ xor $Tll,$Zll,$Zll
+ xor $Thh,$Zhh,$Zhh
+ ldbx $cnt($Xi),$nlo
+ ldbx $cnt($inp),$byte
+
+ depd,z $Zll,60,4,$rem
+ shrpd $Zhh,$Zll,4,$Zll
+ ldd $rem2($rem_4bit),$rem2
+
+ xor $rem2,$Zhh,$Zhh
+ xor $byte,$nlo,$nlo
+ ldd $nhi($Hll),$Tll
+ ldd $nhi($Hhh),$Thh
+
+ and $mask0xf0,$nlo,$nhi
+ depd,z $nlo,59,4,$nlo
+
+ extrd,u $Zhh,59,60,$Zhh
+ xor $Tll,$Zll,$Zll
+
+ ldd $rem($rem_4bit),$rem
+ addib,uv -1,$cnt,L\$oop_ghash_pa2
+ xor $Thh,$Zhh,$Zhh
+
+ xor $rem,$Zhh,$Zhh
+ depd,z $Zll,60,4,$rem2
+
+ shrpd $Zhh,$Zll,4,$Zll
+ extrd,u $Zhh,59,60,$Zhh
+ ldd $nlo($Hll),$Tll
+ ldd $nlo($Hhh),$Thh
+
+ xor $Tll,$Zll,$Zll
+ xor $Thh,$Zhh,$Zhh
+
+ depd,z $Zll,60,4,$rem
+ shrpd $Zhh,$Zll,4,$Zll
+ ldd $rem2($rem_4bit),$rem2
+
+ xor $rem2,$Zhh,$Zhh
+ ldd $nhi($Hll),$Tll
+ ldd $nhi($Hhh),$Thh
+
+ extrd,u $Zhh,59,60,$Zhh
+ xor $Tll,$Zll,$Zll
+ xor $Thh,$Zhh,$Zhh
+ ldd $rem($rem_4bit),$rem
+
+ xor $rem,$Zhh,$Zhh
+ std $Zll,8($Xi)
+ ldo 16($inp),$inp
+ std $Zhh,0($Xi)
+ cmpb,*<> $inp,$len,L\$outer_ghash_pa2
+ copy $Zll,$nlo
+___
+
+$code.=<<___ if ($SIZE_T==4);
+ b L\$done_ghash
+ nop
+
+L\$parisc1_ghash
+ ldb 15($Xi),$nlo
+ ldo 12($Htbl),$Hll
+ ldo 8($Htbl),$Hlh
+ ldo 4($Htbl),$Hhl
+
+L\$outer_ghash_pa1
+ ldb 15($inp),$byte
+ xor $byte,$nlo,$nlo
+ and $mask0xf0,$nlo,$nhi
+ zdep $nlo,27,4,$nlo
+
+ ldwx $nlo($Hll),$Zll
+ ldwx $nlo($Hlh),$Zlh
+ ldwx $nlo($Hhl),$Zhl
+ ldwx $nlo($Hhh),$Zhh
+ zdep $Zll,28,4,$rem
+ ldb 14($Xi),$nlo
+ ldb 14($inp),$byte
+ ldwx $rem($rem_4bit),$rem
+ shrpw $Zlh,$Zll,4,$Zll
+ ldwx $nhi($Hll),$Tll
+ shrpw $Zhl,$Zlh,4,$Zlh
+ ldwx $nhi($Hlh),$Tlh
+ shrpw $Zhh,$Zhl,4,$Zhl
+ ldwx $nhi($Hhl),$Thl
+ extru $Zhh,27,28,$Zhh
+ ldwx $nhi($Hhh),$Thh
+ xor $byte,$nlo,$nlo
+ xor $rem,$Zhh,$Zhh
+ and $mask0xf0,$nlo,$nhi
+ zdep $nlo,27,4,$nlo
+
+ xor $Tll,$Zll,$Zll
+ ldwx $nlo($Hll),$Tll
+ xor $Tlh,$Zlh,$Zlh
+ ldwx $nlo($Hlh),$Tlh
+ xor $Thl,$Zhl,$Zhl
+ b L\$oop_ghash_pa1
+ ldi 13,$cnt
+
+ .ALIGN 8
+L\$oop_ghash_pa1
+ zdep $Zll,28,4,$rem
+ ldwx $nlo($Hhl),$Thl
+ xor $Thh,$Zhh,$Zhh
+ ldwx $rem($rem_4bit),$rem
+ shrpw $Zlh,$Zll,4,$Zll
+ ldwx $nlo($Hhh),$Thh
+ shrpw $Zhl,$Zlh,4,$Zlh
+ ldbx $cnt($Xi),$nlo
+ xor $Tll,$Zll,$Zll
+ ldwx $nhi($Hll),$Tll
+ shrpw $Zhh,$Zhl,4,$Zhl
+ ldbx $cnt($inp),$byte
+ xor $Tlh,$Zlh,$Zlh
+ ldwx $nhi($Hlh),$Tlh
+ extru $Zhh,27,28,$Zhh
+ xor $Thl,$Zhl,$Zhl
+ ldwx $nhi($Hhl),$Thl
+ xor $rem,$Zhh,$Zhh
+ zdep $Zll,28,4,$rem
+ xor $Thh,$Zhh,$Zhh
+ ldwx $nhi($Hhh),$Thh
+ shrpw $Zlh,$Zll,4,$Zll
+ ldwx $rem($rem_4bit),$rem
+ shrpw $Zhl,$Zlh,4,$Zlh
+ xor $byte,$nlo,$nlo
+ shrpw $Zhh,$Zhl,4,$Zhl
+ and $mask0xf0,$nlo,$nhi
+ extru $Zhh,27,28,$Zhh
+ zdep $nlo,27,4,$nlo
+ xor $Tll,$Zll,$Zll
+ ldwx $nlo($Hll),$Tll
+ xor $Tlh,$Zlh,$Zlh
+ ldwx $nlo($Hlh),$Tlh
+ xor $rem,$Zhh,$Zhh
+ addib,uv -1,$cnt,L\$oop_ghash_pa1
+ xor $Thl,$Zhl,$Zhl
+
+ zdep $Zll,28,4,$rem
+ ldwx $nlo($Hhl),$Thl
+ xor $Thh,$Zhh,$Zhh
+ ldwx $rem($rem_4bit),$rem
+ shrpw $Zlh,$Zll,4,$Zll
+ ldwx $nlo($Hhh),$Thh
+ shrpw $Zhl,$Zlh,4,$Zlh
+ xor $Tll,$Zll,$Zll
+ ldwx $nhi($Hll),$Tll
+ shrpw $Zhh,$Zhl,4,$Zhl
+ xor $Tlh,$Zlh,$Zlh
+ ldwx $nhi($Hlh),$Tlh
+ extru $Zhh,27,28,$Zhh
+ xor $rem,$Zhh,$Zhh
+ xor $Thl,$Zhl,$Zhl
+ ldwx $nhi($Hhl),$Thl
+ xor $Thh,$Zhh,$Zhh
+ ldwx $nhi($Hhh),$Thh
+ zdep $Zll,28,4,$rem
+ ldwx $rem($rem_4bit),$rem
+ shrpw $Zlh,$Zll,4,$Zll
+ shrpw $Zhl,$Zlh,4,$Zlh
+ shrpw $Zhh,$Zhl,4,$Zhl
+ extru $Zhh,27,28,$Zhh
+ xor $Tll,$Zll,$Zll
+ xor $Tlh,$Zlh,$Zlh
+ xor $rem,$Zhh,$Zhh
+ stw $Zll,12($Xi)
+ xor $Thl,$Zhl,$Zhl
+ stw $Zlh,8($Xi)
+ xor $Thh,$Zhh,$Zhh
+ stw $Zhl,4($Xi)
+ ldo 16($inp),$inp
+ stw $Zhh,0($Xi)
+ comb,<> $inp,$len,L\$outer_ghash_pa1
+ copy $Zll,$nlo
+___
+$code.=<<___;
+L\$done_ghash
+ $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue
+ $POP `-$FRAME+1*$SIZE_T`(%sp),%r4
+ $POP `-$FRAME+2*$SIZE_T`(%sp),%r5
+ $POP `-$FRAME+3*$SIZE_T`(%sp),%r6
+___
+$code.=<<___ if ($SIZE_T==4);
+ $POP `-$FRAME+4*$SIZE_T`(%sp),%r7
+ $POP `-$FRAME+5*$SIZE_T`(%sp),%r8
+ $POP `-$FRAME+6*$SIZE_T`(%sp),%r9
+ $POP `-$FRAME+7*$SIZE_T`(%sp),%r10
+ $POP `-$FRAME+8*$SIZE_T`(%sp),%r11
+___
+$code.=<<___;
+ bv (%r2)
+ .EXIT
+ $POPMB -$FRAME(%sp),%r3
+ .PROCEND
+
+ .ALIGN 64
+L\$rem_4bit
+ .WORD `0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`,0
+ .WORD `0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`,0
+ .WORD `0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`,0
+ .WORD `0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`,0
+ .STRINGZ "GHASH for PA-RISC, GRYPTOGAMS by <appro\@openssl.org>"
+ .ALIGN 64
+___
+
+# Explicitly encode PA-RISC 2.0 instructions used in this module, so
+# that it can be compiled with .LEVEL 1.0. It should be noted that I
+# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0
+# directive...
+
+my $ldd = sub {
+ my ($mod,$args) = @_;
+ my $orig = "ldd$mod\t$args";
+
+ if ($args =~ /%r([0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 4
+ { my $opcode=(0x03<<26)|($2<<21)|($1<<16)|(3<<6)|$3;
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ elsif ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 5
+ { my $opcode=(0x03<<26)|($2<<21)|(1<<12)|(3<<6)|$3;
+ $opcode|=(($1&0xF)<<17)|(($1&0x10)<<12); # encode offset
+ $opcode|=(1<<5) if ($mod =~ /^,m/);
+ $opcode|=(1<<13) if ($mod =~ /^,mb/);
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $std = sub {
+ my ($mod,$args) = @_;
+ my $orig = "std$mod\t$args";
+
+ if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/) # format 3 suffices
+ { my $opcode=(0x1c<<26)|($3<<21)|($1<<16)|(($2&0x1FF8)<<1)|(($2>>13)&1);
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $extrd = sub {
+ my ($mod,$args) = @_;
+ my $orig = "extrd$mod\t$args";
+
+ # I only have ",u" completer, it's implicitly encoded...
+ if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/) # format 15
+ { my $opcode=(0x36<<26)|($1<<21)|($4<<16);
+ my $len=32-$3;
+ $opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5); # encode pos
+ $opcode |= (($len&0x20)<<7)|($len&0x1f); # encode len
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/) # format 12
+ { my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9);
+ my $len=32-$2;
+ $opcode |= (($len&0x20)<<3)|($len&0x1f); # encode len
+ $opcode |= (1<<13) if ($mod =~ /,\**=/);
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $shrpd = sub {
+ my ($mod,$args) = @_;
+ my $orig = "shrpd$mod\t$args";
+
+ if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/) # format 14
+ { my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4;
+ my $cpos=63-$3;
+ $opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5); # encode sa
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ elsif ($args =~ /%r([0-9]+),%r([0-9]+),%sar,%r([0-9]+)/) # format 11
+ { sprintf "\t.WORD\t0x%08x\t; %s",
+ (0x34<<26)|($2<<21)|($1<<16)|(1<<9)|$3,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $depd = sub {
+ my ($mod,$args) = @_;
+ my $orig = "depd$mod\t$args";
+
+ # I only have ",z" completer, it's impicitly encoded...
+ if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/) # format 16
+ { my $opcode=(0x3c<<26)|($4<<21)|($1<<16);
+ my $cpos=63-$2;
+ my $len=32-$3;
+ $opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5); # encode pos
+ $opcode |= (($len&0x20)<<7)|($len&0x1f); # encode len
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+sub assemble {
+ my ($mnemonic,$mod,$args)=@_;
+ my $opcode = eval("\$$mnemonic");
+
+ ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args";
+}
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/ge;
+ if ($SIZE_T==4) {
+ s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e;
+ s/cmpb,\*/comb,/;
+ s/,\*/,/;
+ }
+ print $_,"\n";
+}
+
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/modes/asm/ghash-s390x.pl b/deps/openssl/openssl/crypto/modes/asm/ghash-s390x.pl
new file mode 100644
index 000000000..6a40d5d89
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/asm/ghash-s390x.pl
@@ -0,0 +1,262 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# September 2010.
+#
+# The module implements "4-bit" GCM GHASH function and underlying
+# single multiplication operation in GF(2^128). "4-bit" means that it
+# uses 256 bytes per-key table [+128 bytes shared table]. Performance
+# was measured to be ~18 cycles per processed byte on z10, which is
+# almost 40% better than gcc-generated code. It should be noted that
+# 18 cycles is worse result than expected: loop is scheduled for 12
+# and the result should be close to 12. In the lack of instruction-
+# level profiling data it's impossible to tell why...
+
+# November 2010.
+#
+# Adapt for -m31 build. If kernel supports what's called "highgprs"
+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
+# instructions and achieve "64-bit" performance even in 31-bit legacy
+# application context. The feature is not specific to any particular
+# processor, as long as it's "z-CPU". Latter implies that the code
+# remains z/Architecture specific. On z990 it was measured to perform
+# 2.8x better than 32-bit code generated by gcc 4.3.
+
+# March 2011.
+#
+# Support for hardware KIMD-GHASH is verified to produce correct
+# result and therefore is engaged. On z196 it was measured to process
+# 8KB buffer ~7 faster than software implementation. It's not as
+# impressive for smaller buffer sizes and for smallest 16-bytes buffer
+# it's actually almost 2 times slower. Which is the reason why
+# KIMD-GHASH is not used in gcm_gmult_4bit.
+
+$flavour = shift;
+
+if ($flavour =~ /3[12]/) {
+ $SIZE_T=4;
+ $g="";
+} else {
+ $SIZE_T=8;
+ $g="g";
+}
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$softonly=0;
+
+$Zhi="%r0";
+$Zlo="%r1";
+
+$Xi="%r2"; # argument block
+$Htbl="%r3";
+$inp="%r4";
+$len="%r5";
+
+$rem0="%r6"; # variables
+$rem1="%r7";
+$nlo="%r8";
+$nhi="%r9";
+$xi="%r10";
+$cnt="%r11";
+$tmp="%r12";
+$x78="%r13";
+$rem_4bit="%r14";
+
+$sp="%r15";
+
+$code.=<<___;
+.text
+
+.globl gcm_gmult_4bit
+.align 32
+gcm_gmult_4bit:
+___
+$code.=<<___ if(!$softonly && 0); # hardware is slow for single block...
+ larl %r1,OPENSSL_s390xcap_P
+ lg %r0,0(%r1)
+ tmhl %r0,0x4000 # check for message-security-assist
+ jz .Lsoft_gmult
+ lghi %r0,0
+ la %r1,16($sp)
+ .long 0xb93e0004 # kimd %r0,%r4
+ lg %r1,24($sp)
+ tmhh %r1,0x4000 # check for function 65
+ jz .Lsoft_gmult
+ stg %r0,16($sp) # arrange 16 bytes of zero input
+ stg %r0,24($sp)
+ lghi %r0,65 # function 65
+ la %r1,0($Xi) # H lies right after Xi in gcm128_context
+ la $inp,16($sp)
+ lghi $len,16
+ .long 0xb93e0004 # kimd %r0,$inp
+ brc 1,.-4 # pay attention to "partial completion"
+ br %r14
+.align 32
+.Lsoft_gmult:
+___
+$code.=<<___;
+ stm${g} %r6,%r14,6*$SIZE_T($sp)
+
+ aghi $Xi,-1
+ lghi $len,1
+ lghi $x78,`0xf<<3`
+ larl $rem_4bit,rem_4bit
+
+ lg $Zlo,8+1($Xi) # Xi
+ j .Lgmult_shortcut
+.type gcm_gmult_4bit,\@function
+.size gcm_gmult_4bit,(.-gcm_gmult_4bit)
+
+.globl gcm_ghash_4bit
+.align 32
+gcm_ghash_4bit:
+___
+$code.=<<___ if(!$softonly);
+ larl %r1,OPENSSL_s390xcap_P
+ lg %r0,0(%r1)
+ tmhl %r0,0x4000 # check for message-security-assist
+ jz .Lsoft_ghash
+ lghi %r0,0
+ la %r1,16($sp)
+ .long 0xb93e0004 # kimd %r0,%r4
+ lg %r1,24($sp)
+ tmhh %r1,0x4000 # check for function 65
+ jz .Lsoft_ghash
+ lghi %r0,65 # function 65
+ la %r1,0($Xi) # H lies right after Xi in gcm128_context
+ .long 0xb93e0004 # kimd %r0,$inp
+ brc 1,.-4 # pay attention to "partial completion"
+ br %r14
+.align 32
+.Lsoft_ghash:
+___
+$code.=<<___ if ($flavour =~ /3[12]/);
+ llgfr $len,$len
+___
+$code.=<<___;
+ stm${g} %r6,%r14,6*$SIZE_T($sp)
+
+ aghi $Xi,-1
+ srlg $len,$len,4
+ lghi $x78,`0xf<<3`
+ larl $rem_4bit,rem_4bit
+
+ lg $Zlo,8+1($Xi) # Xi
+ lg $Zhi,0+1($Xi)
+ lghi $tmp,0
+.Louter:
+ xg $Zhi,0($inp) # Xi ^= inp
+ xg $Zlo,8($inp)
+ xgr $Zhi,$tmp
+ stg $Zlo,8+1($Xi)
+ stg $Zhi,0+1($Xi)
+
+.Lgmult_shortcut:
+ lghi $tmp,0xf0
+ sllg $nlo,$Zlo,4
+ srlg $xi,$Zlo,8 # extract second byte
+ ngr $nlo,$tmp
+ lgr $nhi,$Zlo
+ lghi $cnt,14
+ ngr $nhi,$tmp
+
+ lg $Zlo,8($nlo,$Htbl)
+ lg $Zhi,0($nlo,$Htbl)
+
+ sllg $nlo,$xi,4
+ sllg $rem0,$Zlo,3
+ ngr $nlo,$tmp
+ ngr $rem0,$x78
+ ngr $xi,$tmp
+
+ sllg $tmp,$Zhi,60
+ srlg $Zlo,$Zlo,4
+ srlg $Zhi,$Zhi,4
+ xg $Zlo,8($nhi,$Htbl)
+ xg $Zhi,0($nhi,$Htbl)
+ lgr $nhi,$xi
+ sllg $rem1,$Zlo,3
+ xgr $Zlo,$tmp
+ ngr $rem1,$x78
+ j .Lghash_inner
+.align 16
+.Lghash_inner:
+ srlg $Zlo,$Zlo,4
+ sllg $tmp,$Zhi,60
+ xg $Zlo,8($nlo,$Htbl)
+ srlg $Zhi,$Zhi,4
+ llgc $xi,0($cnt,$Xi)
+ xg $Zhi,0($nlo,$Htbl)
+ sllg $nlo,$xi,4
+ xg $Zhi,0($rem0,$rem_4bit)
+ nill $nlo,0xf0
+ sllg $rem0,$Zlo,3
+ xgr $Zlo,$tmp
+ ngr $rem0,$x78
+ nill $xi,0xf0
+
+ sllg $tmp,$Zhi,60
+ srlg $Zlo,$Zlo,4
+ srlg $Zhi,$Zhi,4
+ xg $Zlo,8($nhi,$Htbl)
+ xg $Zhi,0($nhi,$Htbl)
+ lgr $nhi,$xi
+ xg $Zhi,0($rem1,$rem_4bit)
+ sllg $rem1,$Zlo,3
+ xgr $Zlo,$tmp
+ ngr $rem1,$x78
+ brct $cnt,.Lghash_inner
+
+ sllg $tmp,$Zhi,60
+ srlg $Zlo,$Zlo,4
+ srlg $Zhi,$Zhi,4
+ xg $Zlo,8($nlo,$Htbl)
+ xg $Zhi,0($nlo,$Htbl)
+ sllg $xi,$Zlo,3
+ xg $Zhi,0($rem0,$rem_4bit)
+ xgr $Zlo,$tmp
+ ngr $xi,$x78
+
+ sllg $tmp,$Zhi,60
+ srlg $Zlo,$Zlo,4
+ srlg $Zhi,$Zhi,4
+ xg $Zlo,8($nhi,$Htbl)
+ xg $Zhi,0($nhi,$Htbl)
+ xgr $Zlo,$tmp
+ xg $Zhi,0($rem1,$rem_4bit)
+
+ lg $tmp,0($xi,$rem_4bit)
+ la $inp,16($inp)
+ sllg $tmp,$tmp,4 # correct last rem_4bit[rem]
+ brctg $len,.Louter
+
+ xgr $Zhi,$tmp
+ stg $Zlo,8+1($Xi)
+ stg $Zhi,0+1($Xi)
+ lm${g} %r6,%r14,6*$SIZE_T($sp)
+ br %r14
+.type gcm_ghash_4bit,\@function
+.size gcm_ghash_4bit,(.-gcm_ghash_4bit)
+
+.align 64
+rem_4bit:
+ .long `0x0000<<12`,0,`0x1C20<<12`,0,`0x3840<<12`,0,`0x2460<<12`,0
+ .long `0x7080<<12`,0,`0x6CA0<<12`,0,`0x48C0<<12`,0,`0x54E0<<12`,0
+ .long `0xE100<<12`,0,`0xFD20<<12`,0,`0xD940<<12`,0,`0xC560<<12`,0
+ .long `0x9180<<12`,0,`0x8DA0<<12`,0,`0xA9C0<<12`,0,`0xB5E0<<12`,0
+.type rem_4bit,\@object
+.size rem_4bit,(.-rem_4bit)
+.string "GHASH for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/modes/asm/ghash-sparcv9.pl b/deps/openssl/openssl/crypto/modes/asm/ghash-sparcv9.pl
new file mode 100644
index 000000000..70e7b044a
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/asm/ghash-sparcv9.pl
@@ -0,0 +1,330 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# March 2010
+#
+# The module implements "4-bit" GCM GHASH function and underlying
+# single multiplication operation in GF(2^128). "4-bit" means that it
+# uses 256 bytes per-key table [+128 bytes shared table]. Performance
+# results are for streamed GHASH subroutine on UltraSPARC pre-Tx CPU
+# and are expressed in cycles per processed byte, less is better:
+#
+# gcc 3.3.x cc 5.2 this assembler
+#
+# 32-bit build 81.4 43.3 12.6 (+546%/+244%)
+# 64-bit build 20.2 21.2 12.6 (+60%/+68%)
+#
+# Here is data collected on UltraSPARC T1 system running Linux:
+#
+# gcc 4.4.1 this assembler
+#
+# 32-bit build 566 50 (+1000%)
+# 64-bit build 56 50 (+12%)
+#
+# I don't quite understand why difference between 32-bit and 64-bit
+# compiler-generated code is so big. Compilers *were* instructed to
+# generate code for UltraSPARC and should have used 64-bit registers
+# for Z vector (see C code) even in 32-bit build... Oh well, it only
+# means more impressive improvement coefficients for this assembler
+# module;-) Loops are aggressively modulo-scheduled in respect to
+# references to input data and Z.hi updates to achieve 12 cycles
+# timing. To anchor to something else, sha1-sparcv9.pl spends 11.6
+# cycles to process one byte on UltraSPARC pre-Tx CPU and ~24 on T1.
+
+$bits=32;
+for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64) { $bias=2047; $frame=192; }
+else { $bias=0; $frame=112; }
+
+$output=shift;
+open STDOUT,">$output";
+
+$Zhi="%o0"; # 64-bit values
+$Zlo="%o1";
+$Thi="%o2";
+$Tlo="%o3";
+$rem="%o4";
+$tmp="%o5";
+
+$nhi="%l0"; # small values and pointers
+$nlo="%l1";
+$xi0="%l2";
+$xi1="%l3";
+$rem_4bit="%l4";
+$remi="%l5";
+$Htblo="%l6";
+$cnt="%l7";
+
+$Xi="%i0"; # input argument block
+$Htbl="%i1";
+$inp="%i2";
+$len="%i3";
+
+$code.=<<___;
+.section ".text",#alloc,#execinstr
+
+.align 64
+rem_4bit:
+ .long `0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`,0
+ .long `0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`,0
+ .long `0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`,0
+ .long `0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`,0
+.type rem_4bit,#object
+.size rem_4bit,(.-rem_4bit)
+
+.globl gcm_ghash_4bit
+.align 32
+gcm_ghash_4bit:
+ save %sp,-$frame,%sp
+ ldub [$inp+15],$nlo
+ ldub [$Xi+15],$xi0
+ ldub [$Xi+14],$xi1
+ add $len,$inp,$len
+ add $Htbl,8,$Htblo
+
+1: call .+8
+ add %o7,rem_4bit-1b,$rem_4bit
+
+.Louter:
+ xor $xi0,$nlo,$nlo
+ and $nlo,0xf0,$nhi
+ and $nlo,0x0f,$nlo
+ sll $nlo,4,$nlo
+ ldx [$Htblo+$nlo],$Zlo
+ ldx [$Htbl+$nlo],$Zhi
+
+ ldub [$inp+14],$nlo
+
+ ldx [$Htblo+$nhi],$Tlo
+ and $Zlo,0xf,$remi
+ ldx [$Htbl+$nhi],$Thi
+ sll $remi,3,$remi
+ ldx [$rem_4bit+$remi],$rem
+ srlx $Zlo,4,$Zlo
+ mov 13,$cnt
+ sllx $Zhi,60,$tmp
+ xor $Tlo,$Zlo,$Zlo
+ srlx $Zhi,4,$Zhi
+ xor $Zlo,$tmp,$Zlo
+
+ xor $xi1,$nlo,$nlo
+ and $Zlo,0xf,$remi
+ and $nlo,0xf0,$nhi
+ and $nlo,0x0f,$nlo
+ ba .Lghash_inner
+ sll $nlo,4,$nlo
+.align 32
+.Lghash_inner:
+ ldx [$Htblo+$nlo],$Tlo
+ sll $remi,3,$remi
+ xor $Thi,$Zhi,$Zhi
+ ldx [$Htbl+$nlo],$Thi
+ srlx $Zlo,4,$Zlo
+ xor $rem,$Zhi,$Zhi
+ ldx [$rem_4bit+$remi],$rem
+ sllx $Zhi,60,$tmp
+ xor $Tlo,$Zlo,$Zlo
+ ldub [$inp+$cnt],$nlo
+ srlx $Zhi,4,$Zhi
+ xor $Zlo,$tmp,$Zlo
+ ldub [$Xi+$cnt],$xi1
+ xor $Thi,$Zhi,$Zhi
+ and $Zlo,0xf,$remi
+
+ ldx [$Htblo+$nhi],$Tlo
+ sll $remi,3,$remi
+ xor $rem,$Zhi,$Zhi
+ ldx [$Htbl+$nhi],$Thi
+ srlx $Zlo,4,$Zlo
+ ldx [$rem_4bit+$remi],$rem
+ sllx $Zhi,60,$tmp
+ xor $xi1,$nlo,$nlo
+ srlx $Zhi,4,$Zhi
+ and $nlo,0xf0,$nhi
+ addcc $cnt,-1,$cnt
+ xor $Zlo,$tmp,$Zlo
+ and $nlo,0x0f,$nlo
+ xor $Tlo,$Zlo,$Zlo
+ sll $nlo,4,$nlo
+ blu .Lghash_inner
+ and $Zlo,0xf,$remi
+
+ ldx [$Htblo+$nlo],$Tlo
+ sll $remi,3,$remi
+ xor $Thi,$Zhi,$Zhi
+ ldx [$Htbl+$nlo],$Thi
+ srlx $Zlo,4,$Zlo
+ xor $rem,$Zhi,$Zhi
+ ldx [$rem_4bit+$remi],$rem
+ sllx $Zhi,60,$tmp
+ xor $Tlo,$Zlo,$Zlo
+ srlx $Zhi,4,$Zhi
+ xor $Zlo,$tmp,$Zlo
+ xor $Thi,$Zhi,$Zhi
+
+ add $inp,16,$inp
+ cmp $inp,$len
+ be,pn `$bits==64?"%xcc":"%icc"`,.Ldone
+ and $Zlo,0xf,$remi
+
+ ldx [$Htblo+$nhi],$Tlo
+ sll $remi,3,$remi
+ xor $rem,$Zhi,$Zhi
+ ldx [$Htbl+$nhi],$Thi
+ srlx $Zlo,4,$Zlo
+ ldx [$rem_4bit+$remi],$rem
+ sllx $Zhi,60,$tmp
+ xor $Tlo,$Zlo,$Zlo
+ ldub [$inp+15],$nlo
+ srlx $Zhi,4,$Zhi
+ xor $Zlo,$tmp,$Zlo
+ xor $Thi,$Zhi,$Zhi
+ stx $Zlo,[$Xi+8]
+ xor $rem,$Zhi,$Zhi
+ stx $Zhi,[$Xi]
+ srl $Zlo,8,$xi1
+ and $Zlo,0xff,$xi0
+ ba .Louter
+ and $xi1,0xff,$xi1
+.align 32
+.Ldone:
+ ldx [$Htblo+$nhi],$Tlo
+ sll $remi,3,$remi
+ xor $rem,$Zhi,$Zhi
+ ldx [$Htbl+$nhi],$Thi
+ srlx $Zlo,4,$Zlo
+ ldx [$rem_4bit+$remi],$rem
+ sllx $Zhi,60,$tmp
+ xor $Tlo,$Zlo,$Zlo
+ srlx $Zhi,4,$Zhi
+ xor $Zlo,$tmp,$Zlo
+ xor $Thi,$Zhi,$Zhi
+ stx $Zlo,[$Xi+8]
+ xor $rem,$Zhi,$Zhi
+ stx $Zhi,[$Xi]
+
+ ret
+ restore
+.type gcm_ghash_4bit,#function
+.size gcm_ghash_4bit,(.-gcm_ghash_4bit)
+___
+
+undef $inp;
+undef $len;
+
+$code.=<<___;
+.globl gcm_gmult_4bit
+.align 32
+gcm_gmult_4bit:
+ save %sp,-$frame,%sp
+ ldub [$Xi+15],$nlo
+ add $Htbl,8,$Htblo
+
+1: call .+8
+ add %o7,rem_4bit-1b,$rem_4bit
+
+ and $nlo,0xf0,$nhi
+ and $nlo,0x0f,$nlo
+ sll $nlo,4,$nlo
+ ldx [$Htblo+$nlo],$Zlo
+ ldx [$Htbl+$nlo],$Zhi
+
+ ldub [$Xi+14],$nlo
+
+ ldx [$Htblo+$nhi],$Tlo
+ and $Zlo,0xf,$remi
+ ldx [$Htbl+$nhi],$Thi
+ sll $remi,3,$remi
+ ldx [$rem_4bit+$remi],$rem
+ srlx $Zlo,4,$Zlo
+ mov 13,$cnt
+ sllx $Zhi,60,$tmp
+ xor $Tlo,$Zlo,$Zlo
+ srlx $Zhi,4,$Zhi
+ xor $Zlo,$tmp,$Zlo
+
+ and $Zlo,0xf,$remi
+ and $nlo,0xf0,$nhi
+ and $nlo,0x0f,$nlo
+ ba .Lgmult_inner
+ sll $nlo,4,$nlo
+.align 32
+.Lgmult_inner:
+ ldx [$Htblo+$nlo],$Tlo
+ sll $remi,3,$remi
+ xor $Thi,$Zhi,$Zhi
+ ldx [$Htbl+$nlo],$Thi
+ srlx $Zlo,4,$Zlo
+ xor $rem,$Zhi,$Zhi
+ ldx [$rem_4bit+$remi],$rem
+ sllx $Zhi,60,$tmp
+ xor $Tlo,$Zlo,$Zlo
+ ldub [$Xi+$cnt],$nlo
+ srlx $Zhi,4,$Zhi
+ xor $Zlo,$tmp,$Zlo
+ xor $Thi,$Zhi,$Zhi
+ and $Zlo,0xf,$remi
+
+ ldx [$Htblo+$nhi],$Tlo
+ sll $remi,3,$remi
+ xor $rem,$Zhi,$Zhi
+ ldx [$Htbl+$nhi],$Thi
+ srlx $Zlo,4,$Zlo
+ ldx [$rem_4bit+$remi],$rem
+ sllx $Zhi,60,$tmp
+ srlx $Zhi,4,$Zhi
+ and $nlo,0xf0,$nhi
+ addcc $cnt,-1,$cnt
+ xor $Zlo,$tmp,$Zlo
+ and $nlo,0x0f,$nlo
+ xor $Tlo,$Zlo,$Zlo
+ sll $nlo,4,$nlo
+ blu .Lgmult_inner
+ and $Zlo,0xf,$remi
+
+ ldx [$Htblo+$nlo],$Tlo
+ sll $remi,3,$remi
+ xor $Thi,$Zhi,$Zhi
+ ldx [$Htbl+$nlo],$Thi
+ srlx $Zlo,4,$Zlo
+ xor $rem,$Zhi,$Zhi
+ ldx [$rem_4bit+$remi],$rem
+ sllx $Zhi,60,$tmp
+ xor $Tlo,$Zlo,$Zlo
+ srlx $Zhi,4,$Zhi
+ xor $Zlo,$tmp,$Zlo
+ xor $Thi,$Zhi,$Zhi
+ and $Zlo,0xf,$remi
+
+ ldx [$Htblo+$nhi],$Tlo
+ sll $remi,3,$remi
+ xor $rem,$Zhi,$Zhi
+ ldx [$Htbl+$nhi],$Thi
+ srlx $Zlo,4,$Zlo
+ ldx [$rem_4bit+$remi],$rem
+ sllx $Zhi,60,$tmp
+ xor $Tlo,$Zlo,$Zlo
+ srlx $Zhi,4,$Zhi
+ xor $Zlo,$tmp,$Zlo
+ xor $Thi,$Zhi,$Zhi
+ stx $Zlo,[$Xi+8]
+ xor $rem,$Zhi,$Zhi
+ stx $Zhi,[$Xi]
+
+ ret
+ restore
+.type gcm_gmult_4bit,#function
+.size gcm_gmult_4bit,(.-gcm_gmult_4bit)
+.asciz "GHASH for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
+.align 4
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/modes/asm/ghash-x86.pl b/deps/openssl/openssl/crypto/modes/asm/ghash-x86.pl
new file mode 100644
index 000000000..83c727e07
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/asm/ghash-x86.pl
@@ -0,0 +1,1342 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# March, May, June 2010
+#
+# The module implements "4-bit" GCM GHASH function and underlying
+# single multiplication operation in GF(2^128). "4-bit" means that it
+# uses 256 bytes per-key table [+64/128 bytes fixed table]. It has two
+# code paths: vanilla x86 and vanilla MMX. Former will be executed on
+# 486 and Pentium, latter on all others. MMX GHASH features so called
+# "528B" variant of "4-bit" method utilizing additional 256+16 bytes
+# of per-key storage [+512 bytes shared table]. Performance results
+# are for streamed GHASH subroutine and are expressed in cycles per
+# processed byte, less is better:
+#
+# gcc 2.95.3(*) MMX assembler x86 assembler
+#
+# Pentium 105/111(**) - 50
+# PIII 68 /75 12.2 24
+# P4 125/125 17.8 84(***)
+# Opteron 66 /70 10.1 30
+# Core2 54 /67 8.4 18
+#
+# (*) gcc 3.4.x was observed to generate few percent slower code,
+# which is one of reasons why 2.95.3 results were chosen,
+# another reason is lack of 3.4.x results for older CPUs;
+# comparison with MMX results is not completely fair, because C
+# results are for vanilla "256B" implementation, while
+# assembler results are for "528B";-)
+# (**) second number is result for code compiled with -fPIC flag,
+# which is actually more relevant, because assembler code is
+# position-independent;
+# (***) see comment in non-MMX routine for further details;
+#
+# To summarize, it's >2-5 times faster than gcc-generated code. To
+# anchor it to something else SHA1 assembler processes one byte in
+# 11-13 cycles on contemporary x86 cores. As for choice of MMX in
+# particular, see comment at the end of the file...
+
+# May 2010
+#
+# Add PCLMULQDQ version performing at 2.10 cycles per processed byte.
+# The question is how close is it to theoretical limit? The pclmulqdq
+# instruction latency appears to be 14 cycles and there can't be more
+# than 2 of them executing at any given time. This means that single
+# Karatsuba multiplication would take 28 cycles *plus* few cycles for
+# pre- and post-processing. Then multiplication has to be followed by
+# modulo-reduction. Given that aggregated reduction method [see
+# "Carry-less Multiplication and Its Usage for Computing the GCM Mode"
+# white paper by Intel] allows you to perform reduction only once in
+# a while we can assume that asymptotic performance can be estimated
+# as (28+Tmod/Naggr)/16, where Tmod is time to perform reduction
+# and Naggr is the aggregation factor.
+#
+# Before we proceed to this implementation let's have closer look at
+# the best-performing code suggested by Intel in their white paper.
+# By tracing inter-register dependencies Tmod is estimated as ~19
+# cycles and Naggr chosen by Intel is 4, resulting in 2.05 cycles per
+# processed byte. As implied, this is quite optimistic estimate,
+# because it does not account for Karatsuba pre- and post-processing,
+# which for a single multiplication is ~5 cycles. Unfortunately Intel
+# does not provide performance data for GHASH alone. But benchmarking
+# AES_GCM_encrypt ripped out of Fig. 15 of the white paper with aadt
+# alone resulted in 2.46 cycles per byte of out 16KB buffer. Note that
+# the result accounts even for pre-computing of degrees of the hash
+# key H, but its portion is negligible at 16KB buffer size.
+#
+# Moving on to the implementation in question. Tmod is estimated as
+# ~13 cycles and Naggr is 2, giving asymptotic performance of ...
+# 2.16. How is it possible that measured performance is better than
+# optimistic theoretical estimate? There is one thing Intel failed
+# to recognize. By serializing GHASH with CTR in same subroutine
+# former's performance is really limited to above (Tmul + Tmod/Naggr)
+# equation. But if GHASH procedure is detached, the modulo-reduction
+# can be interleaved with Naggr-1 multiplications at instruction level
+# and under ideal conditions even disappear from the equation. So that
+# optimistic theoretical estimate for this implementation is ...
+# 28/16=1.75, and not 2.16. Well, it's probably way too optimistic,
+# at least for such small Naggr. I'd argue that (28+Tproc/Naggr),
+# where Tproc is time required for Karatsuba pre- and post-processing,
+# is more realistic estimate. In this case it gives ... 1.91 cycles.
+# Or in other words, depending on how well we can interleave reduction
+# and one of the two multiplications the performance should be betwen
+# 1.91 and 2.16. As already mentioned, this implementation processes
+# one byte out of 8KB buffer in 2.10 cycles, while x86_64 counterpart
+# - in 2.02. x86_64 performance is better, because larger register
+# bank allows to interleave reduction and multiplication better.
+#
+# Does it make sense to increase Naggr? To start with it's virtually
+# impossible in 32-bit mode, because of limited register bank
+# capacity. Otherwise improvement has to be weighed agiainst slower
+# setup, as well as code size and complexity increase. As even
+# optimistic estimate doesn't promise 30% performance improvement,
+# there are currently no plans to increase Naggr.
+#
+# Special thanks to David Woodhouse <dwmw2@infradead.org> for
+# providing access to a Westmere-based system on behalf of Intel
+# Open Source Technology Centre.
+
+# January 2010
+#
+# Tweaked to optimize transitions between integer and FP operations
+# on same XMM register, PCLMULQDQ subroutine was measured to process
+# one byte in 2.07 cycles on Sandy Bridge, and in 2.12 - on Westmere.
+# The minor regression on Westmere is outweighed by ~15% improvement
+# on Sandy Bridge. Strangely enough attempt to modify 64-bit code in
+# similar manner resulted in almost 20% degradation on Sandy Bridge,
+# where original 64-bit code processes one byte in 1.95 cycles.
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"ghash-x86.pl",$x86only = $ARGV[$#ARGV] eq "386");
+
+$sse2=0;
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+($Zhh,$Zhl,$Zlh,$Zll) = ("ebp","edx","ecx","ebx");
+$inp = "edi";
+$Htbl = "esi";
+
+$unroll = 0; # Affects x86 loop. Folded loop performs ~7% worse
+ # than unrolled, which has to be weighted against
+ # 2.5x x86-specific code size reduction.
+
+sub x86_loop {
+ my $off = shift;
+ my $rem = "eax";
+
+ &mov ($Zhh,&DWP(4,$Htbl,$Zll));
+ &mov ($Zhl,&DWP(0,$Htbl,$Zll));
+ &mov ($Zlh,&DWP(12,$Htbl,$Zll));
+ &mov ($Zll,&DWP(8,$Htbl,$Zll));
+ &xor ($rem,$rem); # avoid partial register stalls on PIII
+
+ # shrd practically kills P4, 2.5x deterioration, but P4 has
+ # MMX code-path to execute. shrd runs tad faster [than twice
+ # the shifts, move's and or's] on pre-MMX Pentium (as well as
+ # PIII and Core2), *but* minimizes code size, spares register
+ # and thus allows to fold the loop...
+ if (!$unroll) {
+ my $cnt = $inp;
+ &mov ($cnt,15);
+ &jmp (&label("x86_loop"));
+ &set_label("x86_loop",16);
+ for($i=1;$i<=2;$i++) {
+ &mov (&LB($rem),&LB($Zll));
+ &shrd ($Zll,$Zlh,4);
+ &and (&LB($rem),0xf);
+ &shrd ($Zlh,$Zhl,4);
+ &shrd ($Zhl,$Zhh,4);
+ &shr ($Zhh,4);
+ &xor ($Zhh,&DWP($off+16,"esp",$rem,4));
+
+ &mov (&LB($rem),&BP($off,"esp",$cnt));
+ if ($i&1) {
+ &and (&LB($rem),0xf0);
+ } else {
+ &shl (&LB($rem),4);
+ }
+
+ &xor ($Zll,&DWP(8,$Htbl,$rem));
+ &xor ($Zlh,&DWP(12,$Htbl,$rem));
+ &xor ($Zhl,&DWP(0,$Htbl,$rem));
+ &xor ($Zhh,&DWP(4,$Htbl,$rem));
+
+ if ($i&1) {
+ &dec ($cnt);
+ &js (&label("x86_break"));
+ } else {
+ &jmp (&label("x86_loop"));
+ }
+ }
+ &set_label("x86_break",16);
+ } else {
+ for($i=1;$i<32;$i++) {
+ &comment($i);
+ &mov (&LB($rem),&LB($Zll));
+ &shrd ($Zll,$Zlh,4);
+ &and (&LB($rem),0xf);
+ &shrd ($Zlh,$Zhl,4);
+ &shrd ($Zhl,$Zhh,4);
+ &shr ($Zhh,4);
+ &xor ($Zhh,&DWP($off+16,"esp",$rem,4));
+
+ if ($i&1) {
+ &mov (&LB($rem),&BP($off+15-($i>>1),"esp"));
+ &and (&LB($rem),0xf0);
+ } else {
+ &mov (&LB($rem),&BP($off+15-($i>>1),"esp"));
+ &shl (&LB($rem),4);
+ }
+
+ &xor ($Zll,&DWP(8,$Htbl,$rem));
+ &xor ($Zlh,&DWP(12,$Htbl,$rem));
+ &xor ($Zhl,&DWP(0,$Htbl,$rem));
+ &xor ($Zhh,&DWP(4,$Htbl,$rem));
+ }
+ }
+ &bswap ($Zll);
+ &bswap ($Zlh);
+ &bswap ($Zhl);
+ if (!$x86only) {
+ &bswap ($Zhh);
+ } else {
+ &mov ("eax",$Zhh);
+ &bswap ("eax");
+ &mov ($Zhh,"eax");
+ }
+}
+
+if ($unroll) {
+ &function_begin_B("_x86_gmult_4bit_inner");
+ &x86_loop(4);
+ &ret ();
+ &function_end_B("_x86_gmult_4bit_inner");
+}
+
+sub deposit_rem_4bit {
+ my $bias = shift;
+
+ &mov (&DWP($bias+0, "esp"),0x0000<<16);
+ &mov (&DWP($bias+4, "esp"),0x1C20<<16);
+ &mov (&DWP($bias+8, "esp"),0x3840<<16);
+ &mov (&DWP($bias+12,"esp"),0x2460<<16);
+ &mov (&DWP($bias+16,"esp"),0x7080<<16);
+ &mov (&DWP($bias+20,"esp"),0x6CA0<<16);
+ &mov (&DWP($bias+24,"esp"),0x48C0<<16);
+ &mov (&DWP($bias+28,"esp"),0x54E0<<16);
+ &mov (&DWP($bias+32,"esp"),0xE100<<16);
+ &mov (&DWP($bias+36,"esp"),0xFD20<<16);
+ &mov (&DWP($bias+40,"esp"),0xD940<<16);
+ &mov (&DWP($bias+44,"esp"),0xC560<<16);
+ &mov (&DWP($bias+48,"esp"),0x9180<<16);
+ &mov (&DWP($bias+52,"esp"),0x8DA0<<16);
+ &mov (&DWP($bias+56,"esp"),0xA9C0<<16);
+ &mov (&DWP($bias+60,"esp"),0xB5E0<<16);
+}
+
+$suffix = $x86only ? "" : "_x86";
+
+&function_begin("gcm_gmult_4bit".$suffix);
+ &stack_push(16+4+1); # +1 for stack alignment
+ &mov ($inp,&wparam(0)); # load Xi
+ &mov ($Htbl,&wparam(1)); # load Htable
+
+ &mov ($Zhh,&DWP(0,$inp)); # load Xi[16]
+ &mov ($Zhl,&DWP(4,$inp));
+ &mov ($Zlh,&DWP(8,$inp));
+ &mov ($Zll,&DWP(12,$inp));
+
+ &deposit_rem_4bit(16);
+
+ &mov (&DWP(0,"esp"),$Zhh); # copy Xi[16] on stack
+ &mov (&DWP(4,"esp"),$Zhl);
+ &mov (&DWP(8,"esp"),$Zlh);
+ &mov (&DWP(12,"esp"),$Zll);
+ &shr ($Zll,20);
+ &and ($Zll,0xf0);
+
+ if ($unroll) {
+ &call ("_x86_gmult_4bit_inner");
+ } else {
+ &x86_loop(0);
+ &mov ($inp,&wparam(0));
+ }
+
+ &mov (&DWP(12,$inp),$Zll);
+ &mov (&DWP(8,$inp),$Zlh);
+ &mov (&DWP(4,$inp),$Zhl);
+ &mov (&DWP(0,$inp),$Zhh);
+ &stack_pop(16+4+1);
+&function_end("gcm_gmult_4bit".$suffix);
+
+&function_begin("gcm_ghash_4bit".$suffix);
+ &stack_push(16+4+1); # +1 for 64-bit alignment
+ &mov ($Zll,&wparam(0)); # load Xi
+ &mov ($Htbl,&wparam(1)); # load Htable
+ &mov ($inp,&wparam(2)); # load in
+ &mov ("ecx",&wparam(3)); # load len
+ &add ("ecx",$inp);
+ &mov (&wparam(3),"ecx");
+
+ &mov ($Zhh,&DWP(0,$Zll)); # load Xi[16]
+ &mov ($Zhl,&DWP(4,$Zll));
+ &mov ($Zlh,&DWP(8,$Zll));
+ &mov ($Zll,&DWP(12,$Zll));
+
+ &deposit_rem_4bit(16);
+
+ &set_label("x86_outer_loop",16);
+ &xor ($Zll,&DWP(12,$inp)); # xor with input
+ &xor ($Zlh,&DWP(8,$inp));
+ &xor ($Zhl,&DWP(4,$inp));
+ &xor ($Zhh,&DWP(0,$inp));
+ &mov (&DWP(12,"esp"),$Zll); # dump it on stack
+ &mov (&DWP(8,"esp"),$Zlh);
+ &mov (&DWP(4,"esp"),$Zhl);
+ &mov (&DWP(0,"esp"),$Zhh);
+
+ &shr ($Zll,20);
+ &and ($Zll,0xf0);
+
+ if ($unroll) {
+ &call ("_x86_gmult_4bit_inner");
+ } else {
+ &x86_loop(0);
+ &mov ($inp,&wparam(2));
+ }
+ &lea ($inp,&DWP(16,$inp));
+ &cmp ($inp,&wparam(3));
+ &mov (&wparam(2),$inp) if (!$unroll);
+ &jb (&label("x86_outer_loop"));
+
+ &mov ($inp,&wparam(0)); # load Xi
+ &mov (&DWP(12,$inp),$Zll);
+ &mov (&DWP(8,$inp),$Zlh);
+ &mov (&DWP(4,$inp),$Zhl);
+ &mov (&DWP(0,$inp),$Zhh);
+ &stack_pop(16+4+1);
+&function_end("gcm_ghash_4bit".$suffix);
+
+if (!$x86only) {{{
+
+&static_label("rem_4bit");
+
+if (!$sse2) {{ # pure-MMX "May" version...
+
+$S=12; # shift factor for rem_4bit
+
+&function_begin_B("_mmx_gmult_4bit_inner");
+# MMX version performs 3.5 times better on P4 (see comment in non-MMX
+# routine for further details), 100% better on Opteron, ~70% better
+# on Core2 and PIII... In other words effort is considered to be well
+# spent... Since initial release the loop was unrolled in order to
+# "liberate" register previously used as loop counter. Instead it's
+# used to optimize critical path in 'Z.hi ^= rem_4bit[Z.lo&0xf]'.
+# The path involves move of Z.lo from MMX to integer register,
+# effective address calculation and finally merge of value to Z.hi.
+# Reference to rem_4bit is scheduled so late that I had to >>4
+# rem_4bit elements. This resulted in 20-45% procent improvement
+# on contemporary µ-archs.
+{
+ my $cnt;
+ my $rem_4bit = "eax";
+ my @rem = ($Zhh,$Zll);
+ my $nhi = $Zhl;
+ my $nlo = $Zlh;
+
+ my ($Zlo,$Zhi) = ("mm0","mm1");
+ my $tmp = "mm2";
+
+ &xor ($nlo,$nlo); # avoid partial register stalls on PIII
+ &mov ($nhi,$Zll);
+ &mov (&LB($nlo),&LB($nhi));
+ &shl (&LB($nlo),4);
+ &and ($nhi,0xf0);
+ &movq ($Zlo,&QWP(8,$Htbl,$nlo));
+ &movq ($Zhi,&QWP(0,$Htbl,$nlo));
+ &movd ($rem[0],$Zlo);
+
+ for ($cnt=28;$cnt>=-2;$cnt--) {
+ my $odd = $cnt&1;
+ my $nix = $odd ? $nlo : $nhi;
+
+ &shl (&LB($nlo),4) if ($odd);
+ &psrlq ($Zlo,4);
+ &movq ($tmp,$Zhi);
+ &psrlq ($Zhi,4);
+ &pxor ($Zlo,&QWP(8,$Htbl,$nix));
+ &mov (&LB($nlo),&BP($cnt/2,$inp)) if (!$odd && $cnt>=0);
+ &psllq ($tmp,60);
+ &and ($nhi,0xf0) if ($odd);
+ &pxor ($Zhi,&QWP(0,$rem_4bit,$rem[1],8)) if ($cnt<28);
+ &and ($rem[0],0xf);
+ &pxor ($Zhi,&QWP(0,$Htbl,$nix));
+ &mov ($nhi,$nlo) if (!$odd && $cnt>=0);
+ &movd ($rem[1],$Zlo);
+ &pxor ($Zlo,$tmp);
+
+ push (@rem,shift(@rem)); # "rotate" registers
+ }
+
+ &mov ($inp,&DWP(4,$rem_4bit,$rem[1],8)); # last rem_4bit[rem]
+
+ &psrlq ($Zlo,32); # lower part of Zlo is already there
+ &movd ($Zhl,$Zhi);
+ &psrlq ($Zhi,32);
+ &movd ($Zlh,$Zlo);
+ &movd ($Zhh,$Zhi);
+ &shl ($inp,4); # compensate for rem_4bit[i] being >>4
+
+ &bswap ($Zll);
+ &bswap ($Zhl);
+ &bswap ($Zlh);
+ &xor ($Zhh,$inp);
+ &bswap ($Zhh);
+
+ &ret ();
+}
+&function_end_B("_mmx_gmult_4bit_inner");
+
+&function_begin("gcm_gmult_4bit_mmx");
+ &mov ($inp,&wparam(0)); # load Xi
+ &mov ($Htbl,&wparam(1)); # load Htable
+
+ &call (&label("pic_point"));
+ &set_label("pic_point");
+ &blindpop("eax");
+ &lea ("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax"));
+
+ &movz ($Zll,&BP(15,$inp));
+
+ &call ("_mmx_gmult_4bit_inner");
+
+ &mov ($inp,&wparam(0)); # load Xi
+ &emms ();
+ &mov (&DWP(12,$inp),$Zll);
+ &mov (&DWP(4,$inp),$Zhl);
+ &mov (&DWP(8,$inp),$Zlh);
+ &mov (&DWP(0,$inp),$Zhh);
+&function_end("gcm_gmult_4bit_mmx");
+
+# Streamed version performs 20% better on P4, 7% on Opteron,
+# 10% on Core2 and PIII...
+&function_begin("gcm_ghash_4bit_mmx");
+ &mov ($Zhh,&wparam(0)); # load Xi
+ &mov ($Htbl,&wparam(1)); # load Htable
+ &mov ($inp,&wparam(2)); # load in
+ &mov ($Zlh,&wparam(3)); # load len
+
+ &call (&label("pic_point"));
+ &set_label("pic_point");
+ &blindpop("eax");
+ &lea ("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax"));
+
+ &add ($Zlh,$inp);
+ &mov (&wparam(3),$Zlh); # len to point at the end of input
+ &stack_push(4+1); # +1 for stack alignment
+
+ &mov ($Zll,&DWP(12,$Zhh)); # load Xi[16]
+ &mov ($Zhl,&DWP(4,$Zhh));
+ &mov ($Zlh,&DWP(8,$Zhh));
+ &mov ($Zhh,&DWP(0,$Zhh));
+ &jmp (&label("mmx_outer_loop"));
+
+ &set_label("mmx_outer_loop",16);
+ &xor ($Zll,&DWP(12,$inp));
+ &xor ($Zhl,&DWP(4,$inp));
+ &xor ($Zlh,&DWP(8,$inp));
+ &xor ($Zhh,&DWP(0,$inp));
+ &mov (&wparam(2),$inp);
+ &mov (&DWP(12,"esp"),$Zll);
+ &mov (&DWP(4,"esp"),$Zhl);
+ &mov (&DWP(8,"esp"),$Zlh);
+ &mov (&DWP(0,"esp"),$Zhh);
+
+ &mov ($inp,"esp");
+ &shr ($Zll,24);
+
+ &call ("_mmx_gmult_4bit_inner");
+
+ &mov ($inp,&wparam(2));
+ &lea ($inp,&DWP(16,$inp));
+ &cmp ($inp,&wparam(3));
+ &jb (&label("mmx_outer_loop"));
+
+ &mov ($inp,&wparam(0)); # load Xi
+ &emms ();
+ &mov (&DWP(12,$inp),$Zll);
+ &mov (&DWP(4,$inp),$Zhl);
+ &mov (&DWP(8,$inp),$Zlh);
+ &mov (&DWP(0,$inp),$Zhh);
+
+ &stack_pop(4+1);
+&function_end("gcm_ghash_4bit_mmx");
+
+}} else {{ # "June" MMX version...
+ # ... has slower "April" gcm_gmult_4bit_mmx with folded
+ # loop. This is done to conserve code size...
+$S=16; # shift factor for rem_4bit
+
+sub mmx_loop() {
+# MMX version performs 2.8 times better on P4 (see comment in non-MMX
+# routine for further details), 40% better on Opteron and Core2, 50%
+# better on PIII... In other words effort is considered to be well
+# spent...
+ my $inp = shift;
+ my $rem_4bit = shift;
+ my $cnt = $Zhh;
+ my $nhi = $Zhl;
+ my $nlo = $Zlh;
+ my $rem = $Zll;
+
+ my ($Zlo,$Zhi) = ("mm0","mm1");
+ my $tmp = "mm2";
+
+ &xor ($nlo,$nlo); # avoid partial register stalls on PIII
+ &mov ($nhi,$Zll);
+ &mov (&LB($nlo),&LB($nhi));
+ &mov ($cnt,14);
+ &shl (&LB($nlo),4);
+ &and ($nhi,0xf0);
+ &movq ($Zlo,&QWP(8,$Htbl,$nlo));
+ &movq ($Zhi,&QWP(0,$Htbl,$nlo));
+ &movd ($rem,$Zlo);
+ &jmp (&label("mmx_loop"));
+
+ &set_label("mmx_loop",16);
+ &psrlq ($Zlo,4);
+ &and ($rem,0xf);
+ &movq ($tmp,$Zhi);
+ &psrlq ($Zhi,4);
+ &pxor ($Zlo,&QWP(8,$Htbl,$nhi));
+ &mov (&LB($nlo),&BP(0,$inp,$cnt));
+ &psllq ($tmp,60);
+ &pxor ($Zhi,&QWP(0,$rem_4bit,$rem,8));
+ &dec ($cnt);
+ &movd ($rem,$Zlo);
+ &pxor ($Zhi,&QWP(0,$Htbl,$nhi));
+ &mov ($nhi,$nlo);
+ &pxor ($Zlo,$tmp);
+ &js (&label("mmx_break"));
+
+ &shl (&LB($nlo),4);
+ &and ($rem,0xf);
+ &psrlq ($Zlo,4);
+ &and ($nhi,0xf0);
+ &movq ($tmp,$Zhi);
+ &psrlq ($Zhi,4);
+ &pxor ($Zlo,&QWP(8,$Htbl,$nlo));
+ &psllq ($tmp,60);
+ &pxor ($Zhi,&QWP(0,$rem_4bit,$rem,8));
+ &movd ($rem,$Zlo);
+ &pxor ($Zhi,&QWP(0,$Htbl,$nlo));
+ &pxor ($Zlo,$tmp);
+ &jmp (&label("mmx_loop"));
+
+ &set_label("mmx_break",16);
+ &shl (&LB($nlo),4);
+ &and ($rem,0xf);
+ &psrlq ($Zlo,4);
+ &and ($nhi,0xf0);
+ &movq ($tmp,$Zhi);
+ &psrlq ($Zhi,4);
+ &pxor ($Zlo,&QWP(8,$Htbl,$nlo));
+ &psllq ($tmp,60);
+ &pxor ($Zhi,&QWP(0,$rem_4bit,$rem,8));
+ &movd ($rem,$Zlo);
+ &pxor ($Zhi,&QWP(0,$Htbl,$nlo));
+ &pxor ($Zlo,$tmp);
+
+ &psrlq ($Zlo,4);
+ &and ($rem,0xf);
+ &movq ($tmp,$Zhi);
+ &psrlq ($Zhi,4);
+ &pxor ($Zlo,&QWP(8,$Htbl,$nhi));
+ &psllq ($tmp,60);
+ &pxor ($Zhi,&QWP(0,$rem_4bit,$rem,8));
+ &movd ($rem,$Zlo);
+ &pxor ($Zhi,&QWP(0,$Htbl,$nhi));
+ &pxor ($Zlo,$tmp);
+
+ &psrlq ($Zlo,32); # lower part of Zlo is already there
+ &movd ($Zhl,$Zhi);
+ &psrlq ($Zhi,32);
+ &movd ($Zlh,$Zlo);
+ &movd ($Zhh,$Zhi);
+
+ &bswap ($Zll);
+ &bswap ($Zhl);
+ &bswap ($Zlh);
+ &bswap ($Zhh);
+}
+
+&function_begin("gcm_gmult_4bit_mmx");
+ &mov ($inp,&wparam(0)); # load Xi
+ &mov ($Htbl,&wparam(1)); # load Htable
+
+ &call (&label("pic_point"));
+ &set_label("pic_point");
+ &blindpop("eax");
+ &lea ("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax"));
+
+ &movz ($Zll,&BP(15,$inp));
+
+ &mmx_loop($inp,"eax");
+
+ &emms ();
+ &mov (&DWP(12,$inp),$Zll);
+ &mov (&DWP(4,$inp),$Zhl);
+ &mov (&DWP(8,$inp),$Zlh);
+ &mov (&DWP(0,$inp),$Zhh);
+&function_end("gcm_gmult_4bit_mmx");
+
+######################################################################
+# Below subroutine is "528B" variant of "4-bit" GCM GHASH function
+# (see gcm128.c for details). It provides further 20-40% performance
+# improvement over above mentioned "May" version.
+
+&static_label("rem_8bit");
+
+&function_begin("gcm_ghash_4bit_mmx");
+{ my ($Zlo,$Zhi) = ("mm7","mm6");
+ my $rem_8bit = "esi";
+ my $Htbl = "ebx";
+
+ # parameter block
+ &mov ("eax",&wparam(0)); # Xi
+ &mov ("ebx",&wparam(1)); # Htable
+ &mov ("ecx",&wparam(2)); # inp
+ &mov ("edx",&wparam(3)); # len
+ &mov ("ebp","esp"); # original %esp
+ &call (&label("pic_point"));
+ &set_label ("pic_point");
+ &blindpop ($rem_8bit);
+ &lea ($rem_8bit,&DWP(&label("rem_8bit")."-".&label("pic_point"),$rem_8bit));
+
+ &sub ("esp",512+16+16); # allocate stack frame...
+ &and ("esp",-64); # ...and align it
+ &sub ("esp",16); # place for (u8)(H[]<<4)
+
+ &add ("edx","ecx"); # pointer to the end of input
+ &mov (&DWP(528+16+0,"esp"),"eax"); # save Xi
+ &mov (&DWP(528+16+8,"esp"),"edx"); # save inp+len
+ &mov (&DWP(528+16+12,"esp"),"ebp"); # save original %esp
+
+ { my @lo = ("mm0","mm1","mm2");
+ my @hi = ("mm3","mm4","mm5");
+ my @tmp = ("mm6","mm7");
+ my ($off1,$off2,$i) = (0,0,);
+
+ &add ($Htbl,128); # optimize for size
+ &lea ("edi",&DWP(16+128,"esp"));
+ &lea ("ebp",&DWP(16+256+128,"esp"));
+
+ # decompose Htable (low and high parts are kept separately),
+ # generate Htable[]>>4, (u8)(Htable[]<<4), save to stack...
+ for ($i=0;$i<18;$i++) {
+
+ &mov ("edx",&DWP(16*$i+8-128,$Htbl)) if ($i<16);
+ &movq ($lo[0],&QWP(16*$i+8-128,$Htbl)) if ($i<16);
+ &psllq ($tmp[1],60) if ($i>1);
+ &movq ($hi[0],&QWP(16*$i+0-128,$Htbl)) if ($i<16);
+ &por ($lo[2],$tmp[1]) if ($i>1);
+ &movq (&QWP($off1-128,"edi"),$lo[1]) if ($i>0 && $i<17);
+ &psrlq ($lo[1],4) if ($i>0 && $i<17);
+ &movq (&QWP($off1,"edi"),$hi[1]) if ($i>0 && $i<17);
+ &movq ($tmp[0],$hi[1]) if ($i>0 && $i<17);
+ &movq (&QWP($off2-128,"ebp"),$lo[2]) if ($i>1);
+ &psrlq ($hi[1],4) if ($i>0 && $i<17);
+ &movq (&QWP($off2,"ebp"),$hi[2]) if ($i>1);
+ &shl ("edx",4) if ($i<16);
+ &mov (&BP($i,"esp"),&LB("edx")) if ($i<16);
+
+ unshift (@lo,pop(@lo)); # "rotate" registers
+ unshift (@hi,pop(@hi));
+ unshift (@tmp,pop(@tmp));
+ $off1 += 8 if ($i>0);
+ $off2 += 8 if ($i>1);
+ }
+ }
+
+ &movq ($Zhi,&QWP(0,"eax"));
+ &mov ("ebx",&DWP(8,"eax"));
+ &mov ("edx",&DWP(12,"eax")); # load Xi
+
+&set_label("outer",16);
+ { my $nlo = "eax";
+ my $dat = "edx";
+ my @nhi = ("edi","ebp");
+ my @rem = ("ebx","ecx");
+ my @red = ("mm0","mm1","mm2");
+ my $tmp = "mm3";
+
+ &xor ($dat,&DWP(12,"ecx")); # merge input data
+ &xor ("ebx",&DWP(8,"ecx"));
+ &pxor ($Zhi,&QWP(0,"ecx"));
+ &lea ("ecx",&DWP(16,"ecx")); # inp+=16
+ #&mov (&DWP(528+12,"esp"),$dat); # save inp^Xi
+ &mov (&DWP(528+8,"esp"),"ebx");
+ &movq (&QWP(528+0,"esp"),$Zhi);
+ &mov (&DWP(528+16+4,"esp"),"ecx"); # save inp
+
+ &xor ($nlo,$nlo);
+ &rol ($dat,8);
+ &mov (&LB($nlo),&LB($dat));
+ &mov ($nhi[1],$nlo);
+ &and (&LB($nlo),0x0f);
+ &shr ($nhi[1],4);
+ &pxor ($red[0],$red[0]);
+ &rol ($dat,8); # next byte
+ &pxor ($red[1],$red[1]);
+ &pxor ($red[2],$red[2]);
+
+ # Just like in "May" verson modulo-schedule for critical path in
+ # 'Z.hi ^= rem_8bit[Z.lo&0xff^((u8)H[nhi]<<4)]<<48'. Final 'pxor'
+ # is scheduled so late that rem_8bit[] has to be shifted *right*
+ # by 16, which is why last argument to pinsrw is 2, which
+ # corresponds to <<32=<<48>>16...
+ for ($j=11,$i=0;$i<15;$i++) {
+
+ if ($i>0) {
+ &pxor ($Zlo,&QWP(16,"esp",$nlo,8)); # Z^=H[nlo]
+ &rol ($dat,8); # next byte
+ &pxor ($Zhi,&QWP(16+128,"esp",$nlo,8));
+
+ &pxor ($Zlo,$tmp);
+ &pxor ($Zhi,&QWP(16+256+128,"esp",$nhi[0],8));
+ &xor (&LB($rem[1]),&BP(0,"esp",$nhi[0])); # rem^(H[nhi]<<4)
+ } else {
+ &movq ($Zlo,&QWP(16,"esp",$nlo,8));
+ &movq ($Zhi,&QWP(16+128,"esp",$nlo,8));
+ }
+
+ &mov (&LB($nlo),&LB($dat));
+ &mov ($dat,&DWP(528+$j,"esp")) if (--$j%4==0);
+
+ &movd ($rem[0],$Zlo);
+ &movz ($rem[1],&LB($rem[1])) if ($i>0);
+ &psrlq ($Zlo,8); # Z>>=8
+
+ &movq ($tmp,$Zhi);
+ &mov ($nhi[0],$nlo);
+ &psrlq ($Zhi,8);
+
+ &pxor ($Zlo,&QWP(16+256+0,"esp",$nhi[1],8)); # Z^=H[nhi]>>4
+ &and (&LB($nlo),0x0f);
+ &psllq ($tmp,56);
+
+ &pxor ($Zhi,$red[1]) if ($i>1);
+ &shr ($nhi[0],4);
+ &pinsrw ($red[0],&WP(0,$rem_8bit,$rem[1],2),2) if ($i>0);
+
+ unshift (@red,pop(@red)); # "rotate" registers
+ unshift (@rem,pop(@rem));
+ unshift (@nhi,pop(@nhi));
+ }
+
+ &pxor ($Zlo,&QWP(16,"esp",$nlo,8)); # Z^=H[nlo]
+ &pxor ($Zhi,&QWP(16+128,"esp",$nlo,8));
+ &xor (&LB($rem[1]),&BP(0,"esp",$nhi[0])); # rem^(H[nhi]<<4)
+
+ &pxor ($Zlo,$tmp);
+ &pxor ($Zhi,&QWP(16+256+128,"esp",$nhi[0],8));
+ &movz ($rem[1],&LB($rem[1]));
+
+ &pxor ($red[2],$red[2]); # clear 2nd word
+ &psllq ($red[1],4);
+
+ &movd ($rem[0],$Zlo);
+ &psrlq ($Zlo,4); # Z>>=4
+
+ &movq ($tmp,$Zhi);
+ &psrlq ($Zhi,4);
+ &shl ($rem[0],4); # rem<<4
+
+ &pxor ($Zlo,&QWP(16,"esp",$nhi[1],8)); # Z^=H[nhi]
+ &psllq ($tmp,60);
+ &movz ($rem[0],&LB($rem[0]));
+
+ &pxor ($Zlo,$tmp);
+ &pxor ($Zhi,&QWP(16+128,"esp",$nhi[1],8));
+
+ &pinsrw ($red[0],&WP(0,$rem_8bit,$rem[1],2),2);
+ &pxor ($Zhi,$red[1]);
+
+ &movd ($dat,$Zlo);
+ &pinsrw ($red[2],&WP(0,$rem_8bit,$rem[0],2),3); # last is <<48
+
+ &psllq ($red[0],12); # correct by <<16>>4
+ &pxor ($Zhi,$red[0]);
+ &psrlq ($Zlo,32);
+ &pxor ($Zhi,$red[2]);
+
+ &mov ("ecx",&DWP(528+16+4,"esp")); # restore inp
+ &movd ("ebx",$Zlo);
+ &movq ($tmp,$Zhi); # 01234567
+ &psllw ($Zhi,8); # 1.3.5.7.
+ &psrlw ($tmp,8); # .0.2.4.6
+ &por ($Zhi,$tmp); # 10325476
+ &bswap ($dat);
+ &pshufw ($Zhi,$Zhi,0b00011011); # 76543210
+ &bswap ("ebx");
+
+ &cmp ("ecx",&DWP(528+16+8,"esp")); # are we done?
+ &jne (&label("outer"));
+ }
+
+ &mov ("eax",&DWP(528+16+0,"esp")); # restore Xi
+ &mov (&DWP(12,"eax"),"edx");
+ &mov (&DWP(8,"eax"),"ebx");
+ &movq (&QWP(0,"eax"),$Zhi);
+
+ &mov ("esp",&DWP(528+16+12,"esp")); # restore original %esp
+ &emms ();
+}
+&function_end("gcm_ghash_4bit_mmx");
+}}
+
+if ($sse2) {{
+######################################################################
+# PCLMULQDQ version.
+
+$Xip="eax";
+$Htbl="edx";
+$const="ecx";
+$inp="esi";
+$len="ebx";
+
+($Xi,$Xhi)=("xmm0","xmm1"); $Hkey="xmm2";
+($T1,$T2,$T3)=("xmm3","xmm4","xmm5");
+($Xn,$Xhn)=("xmm6","xmm7");
+
+&static_label("bswap");
+
+sub clmul64x64_T2 { # minimal "register" pressure
+my ($Xhi,$Xi,$Hkey)=@_;
+
+ &movdqa ($Xhi,$Xi); #
+ &pshufd ($T1,$Xi,0b01001110);
+ &pshufd ($T2,$Hkey,0b01001110);
+ &pxor ($T1,$Xi); #
+ &pxor ($T2,$Hkey);
+
+ &pclmulqdq ($Xi,$Hkey,0x00); #######
+ &pclmulqdq ($Xhi,$Hkey,0x11); #######
+ &pclmulqdq ($T1,$T2,0x00); #######
+ &xorps ($T1,$Xi); #
+ &xorps ($T1,$Xhi); #
+
+ &movdqa ($T2,$T1); #
+ &psrldq ($T1,8);
+ &pslldq ($T2,8); #
+ &pxor ($Xhi,$T1);
+ &pxor ($Xi,$T2); #
+}
+
+sub clmul64x64_T3 {
+# Even though this subroutine offers visually better ILP, it
+# was empirically found to be a tad slower than above version.
+# At least in gcm_ghash_clmul context. But it's just as well,
+# because loop modulo-scheduling is possible only thanks to
+# minimized "register" pressure...
+my ($Xhi,$Xi,$Hkey)=@_;
+
+ &movdqa ($T1,$Xi); #
+ &movdqa ($Xhi,$Xi);
+ &pclmulqdq ($Xi,$Hkey,0x00); #######
+ &pclmulqdq ($Xhi,$Hkey,0x11); #######
+ &pshufd ($T2,$T1,0b01001110); #
+ &pshufd ($T3,$Hkey,0b01001110);
+ &pxor ($T2,$T1); #
+ &pxor ($T3,$Hkey);
+ &pclmulqdq ($T2,$T3,0x00); #######
+ &pxor ($T2,$Xi); #
+ &pxor ($T2,$Xhi); #
+
+ &movdqa ($T3,$T2); #
+ &psrldq ($T2,8);
+ &pslldq ($T3,8); #
+ &pxor ($Xhi,$T2);
+ &pxor ($Xi,$T3); #
+}
+
+if (1) { # Algorithm 9 with <<1 twist.
+ # Reduction is shorter and uses only two
+ # temporary registers, which makes it better
+ # candidate for interleaving with 64x64
+ # multiplication. Pre-modulo-scheduled loop
+ # was found to be ~20% faster than Algorithm 5
+ # below. Algorithm 9 was therefore chosen for
+ # further optimization...
+
+sub reduction_alg9 { # 17/13 times faster than Intel version
+my ($Xhi,$Xi) = @_;
+
+ # 1st phase
+ &movdqa ($T1,$Xi); #
+ &psllq ($Xi,1);
+ &pxor ($Xi,$T1); #
+ &psllq ($Xi,5); #
+ &pxor ($Xi,$T1); #
+ &psllq ($Xi,57); #
+ &movdqa ($T2,$Xi); #
+ &pslldq ($Xi,8);
+ &psrldq ($T2,8); #
+ &pxor ($Xi,$T1);
+ &pxor ($Xhi,$T2); #
+
+ # 2nd phase
+ &movdqa ($T2,$Xi);
+ &psrlq ($Xi,5);
+ &pxor ($Xi,$T2); #
+ &psrlq ($Xi,1); #
+ &pxor ($Xi,$T2); #
+ &pxor ($T2,$Xhi);
+ &psrlq ($Xi,1); #
+ &pxor ($Xi,$T2); #
+}
+
+&function_begin_B("gcm_init_clmul");
+ &mov ($Htbl,&wparam(0));
+ &mov ($Xip,&wparam(1));
+
+ &call (&label("pic"));
+&set_label("pic");
+ &blindpop ($const);
+ &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const));
+
+ &movdqu ($Hkey,&QWP(0,$Xip));
+ &pshufd ($Hkey,$Hkey,0b01001110);# dword swap
+
+ # <<1 twist
+ &pshufd ($T2,$Hkey,0b11111111); # broadcast uppermost dword
+ &movdqa ($T1,$Hkey);
+ &psllq ($Hkey,1);
+ &pxor ($T3,$T3); #
+ &psrlq ($T1,63);
+ &pcmpgtd ($T3,$T2); # broadcast carry bit
+ &pslldq ($T1,8);
+ &por ($Hkey,$T1); # H<<=1
+
+ # magic reduction
+ &pand ($T3,&QWP(16,$const)); # 0x1c2_polynomial
+ &pxor ($Hkey,$T3); # if(carry) H^=0x1c2_polynomial
+
+ # calculate H^2
+ &movdqa ($Xi,$Hkey);
+ &clmul64x64_T2 ($Xhi,$Xi,$Hkey);
+ &reduction_alg9 ($Xhi,$Xi);
+
+ &movdqu (&QWP(0,$Htbl),$Hkey); # save H
+ &movdqu (&QWP(16,$Htbl),$Xi); # save H^2
+
+ &ret ();
+&function_end_B("gcm_init_clmul");
+
+&function_begin_B("gcm_gmult_clmul");
+ &mov ($Xip,&wparam(0));
+ &mov ($Htbl,&wparam(1));
+
+ &call (&label("pic"));
+&set_label("pic");
+ &blindpop ($const);
+ &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const));
+
+ &movdqu ($Xi,&QWP(0,$Xip));
+ &movdqa ($T3,&QWP(0,$const));
+ &movups ($Hkey,&QWP(0,$Htbl));
+ &pshufb ($Xi,$T3);
+
+ &clmul64x64_T2 ($Xhi,$Xi,$Hkey);
+ &reduction_alg9 ($Xhi,$Xi);
+
+ &pshufb ($Xi,$T3);
+ &movdqu (&QWP(0,$Xip),$Xi);
+
+ &ret ();
+&function_end_B("gcm_gmult_clmul");
+
+&function_begin("gcm_ghash_clmul");
+ &mov ($Xip,&wparam(0));
+ &mov ($Htbl,&wparam(1));
+ &mov ($inp,&wparam(2));
+ &mov ($len,&wparam(3));
+
+ &call (&label("pic"));
+&set_label("pic");
+ &blindpop ($const);
+ &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const));
+
+ &movdqu ($Xi,&QWP(0,$Xip));
+ &movdqa ($T3,&QWP(0,$const));
+ &movdqu ($Hkey,&QWP(0,$Htbl));
+ &pshufb ($Xi,$T3);
+
+ &sub ($len,0x10);
+ &jz (&label("odd_tail"));
+
+ #######
+ # Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
+ # [(H*Ii+1) + (H*Xi+1)] mod P =
+ # [(H*Ii+1) + H^2*(Ii+Xi)] mod P
+ #
+ &movdqu ($T1,&QWP(0,$inp)); # Ii
+ &movdqu ($Xn,&QWP(16,$inp)); # Ii+1
+ &pshufb ($T1,$T3);
+ &pshufb ($Xn,$T3);
+ &pxor ($Xi,$T1); # Ii+Xi
+
+ &clmul64x64_T2 ($Xhn,$Xn,$Hkey); # H*Ii+1
+ &movups ($Hkey,&QWP(16,$Htbl)); # load H^2
+
+ &lea ($inp,&DWP(32,$inp)); # i+=2
+ &sub ($len,0x20);
+ &jbe (&label("even_tail"));
+
+&set_label("mod_loop");
+ &clmul64x64_T2 ($Xhi,$Xi,$Hkey); # H^2*(Ii+Xi)
+ &movdqu ($T1,&QWP(0,$inp)); # Ii
+ &movups ($Hkey,&QWP(0,$Htbl)); # load H
+
+ &pxor ($Xi,$Xn); # (H*Ii+1) + H^2*(Ii+Xi)
+ &pxor ($Xhi,$Xhn);
+
+ &movdqu ($Xn,&QWP(16,$inp)); # Ii+1
+ &pshufb ($T1,$T3);
+ &pshufb ($Xn,$T3);
+
+ &movdqa ($T3,$Xn); #&clmul64x64_TX ($Xhn,$Xn,$Hkey); H*Ii+1
+ &movdqa ($Xhn,$Xn);
+ &pxor ($Xhi,$T1); # "Ii+Xi", consume early
+
+ &movdqa ($T1,$Xi); #&reduction_alg9($Xhi,$Xi); 1st phase
+ &psllq ($Xi,1);
+ &pxor ($Xi,$T1); #
+ &psllq ($Xi,5); #
+ &pxor ($Xi,$T1); #
+ &pclmulqdq ($Xn,$Hkey,0x00); #######
+ &psllq ($Xi,57); #
+ &movdqa ($T2,$Xi); #
+ &pslldq ($Xi,8);
+ &psrldq ($T2,8); #
+ &pxor ($Xi,$T1);
+ &pshufd ($T1,$T3,0b01001110);
+ &pxor ($Xhi,$T2); #
+ &pxor ($T1,$T3);
+ &pshufd ($T3,$Hkey,0b01001110);
+ &pxor ($T3,$Hkey); #
+
+ &pclmulqdq ($Xhn,$Hkey,0x11); #######
+ &movdqa ($T2,$Xi); # 2nd phase
+ &psrlq ($Xi,5);
+ &pxor ($Xi,$T2); #
+ &psrlq ($Xi,1); #
+ &pxor ($Xi,$T2); #
+ &pxor ($T2,$Xhi);
+ &psrlq ($Xi,1); #
+ &pxor ($Xi,$T2); #
+
+ &pclmulqdq ($T1,$T3,0x00); #######
+ &movups ($Hkey,&QWP(16,$Htbl)); # load H^2
+ &xorps ($T1,$Xn); #
+ &xorps ($T1,$Xhn); #
+
+ &movdqa ($T3,$T1); #
+ &psrldq ($T1,8);
+ &pslldq ($T3,8); #
+ &pxor ($Xhn,$T1);
+ &pxor ($Xn,$T3); #
+ &movdqa ($T3,&QWP(0,$const));
+
+ &lea ($inp,&DWP(32,$inp));
+ &sub ($len,0x20);
+ &ja (&label("mod_loop"));
+
+&set_label("even_tail");
+ &clmul64x64_T2 ($Xhi,$Xi,$Hkey); # H^2*(Ii+Xi)
+
+ &pxor ($Xi,$Xn); # (H*Ii+1) + H^2*(Ii+Xi)
+ &pxor ($Xhi,$Xhn);
+
+ &reduction_alg9 ($Xhi,$Xi);
+
+ &test ($len,$len);
+ &jnz (&label("done"));
+
+ &movups ($Hkey,&QWP(0,$Htbl)); # load H
+&set_label("odd_tail");
+ &movdqu ($T1,&QWP(0,$inp)); # Ii
+ &pshufb ($T1,$T3);
+ &pxor ($Xi,$T1); # Ii+Xi
+
+ &clmul64x64_T2 ($Xhi,$Xi,$Hkey); # H*(Ii+Xi)
+ &reduction_alg9 ($Xhi,$Xi);
+
+&set_label("done");
+ &pshufb ($Xi,$T3);
+ &movdqu (&QWP(0,$Xip),$Xi);
+&function_end("gcm_ghash_clmul");
+
+} else { # Algorith 5. Kept for reference purposes.
+
+sub reduction_alg5 { # 19/16 times faster than Intel version
+my ($Xhi,$Xi)=@_;
+
+ # <<1
+ &movdqa ($T1,$Xi); #
+ &movdqa ($T2,$Xhi);
+ &pslld ($Xi,1);
+ &pslld ($Xhi,1); #
+ &psrld ($T1,31);
+ &psrld ($T2,31); #
+ &movdqa ($T3,$T1);
+ &pslldq ($T1,4);
+ &psrldq ($T3,12); #
+ &pslldq ($T2,4);
+ &por ($Xhi,$T3); #
+ &por ($Xi,$T1);
+ &por ($Xhi,$T2); #
+
+ # 1st phase
+ &movdqa ($T1,$Xi);
+ &movdqa ($T2,$Xi);
+ &movdqa ($T3,$Xi); #
+ &pslld ($T1,31);
+ &pslld ($T2,30);
+ &pslld ($Xi,25); #
+ &pxor ($T1,$T2);
+ &pxor ($T1,$Xi); #
+ &movdqa ($T2,$T1); #
+ &pslldq ($T1,12);
+ &psrldq ($T2,4); #
+ &pxor ($T3,$T1);
+
+ # 2nd phase
+ &pxor ($Xhi,$T3); #
+ &movdqa ($Xi,$T3);
+ &movdqa ($T1,$T3);
+ &psrld ($Xi,1); #
+ &psrld ($T1,2);
+ &psrld ($T3,7); #
+ &pxor ($Xi,$T1);
+ &pxor ($Xhi,$T2);
+ &pxor ($Xi,$T3); #
+ &pxor ($Xi,$Xhi); #
+}
+
+&function_begin_B("gcm_init_clmul");
+ &mov ($Htbl,&wparam(0));
+ &mov ($Xip,&wparam(1));
+
+ &call (&label("pic"));
+&set_label("pic");
+ &blindpop ($const);
+ &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const));
+
+ &movdqu ($Hkey,&QWP(0,$Xip));
+ &pshufd ($Hkey,$Hkey,0b01001110);# dword swap
+
+ # calculate H^2
+ &movdqa ($Xi,$Hkey);
+ &clmul64x64_T3 ($Xhi,$Xi,$Hkey);
+ &reduction_alg5 ($Xhi,$Xi);
+
+ &movdqu (&QWP(0,$Htbl),$Hkey); # save H
+ &movdqu (&QWP(16,$Htbl),$Xi); # save H^2
+
+ &ret ();
+&function_end_B("gcm_init_clmul");
+
+&function_begin_B("gcm_gmult_clmul");
+ &mov ($Xip,&wparam(0));
+ &mov ($Htbl,&wparam(1));
+
+ &call (&label("pic"));
+&set_label("pic");
+ &blindpop ($const);
+ &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const));
+
+ &movdqu ($Xi,&QWP(0,$Xip));
+ &movdqa ($Xn,&QWP(0,$const));
+ &movdqu ($Hkey,&QWP(0,$Htbl));
+ &pshufb ($Xi,$Xn);
+
+ &clmul64x64_T3 ($Xhi,$Xi,$Hkey);
+ &reduction_alg5 ($Xhi,$Xi);
+
+ &pshufb ($Xi,$Xn);
+ &movdqu (&QWP(0,$Xip),$Xi);
+
+ &ret ();
+&function_end_B("gcm_gmult_clmul");
+
+&function_begin("gcm_ghash_clmul");
+ &mov ($Xip,&wparam(0));
+ &mov ($Htbl,&wparam(1));
+ &mov ($inp,&wparam(2));
+ &mov ($len,&wparam(3));
+
+ &call (&label("pic"));
+&set_label("pic");
+ &blindpop ($const);
+ &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const));
+
+ &movdqu ($Xi,&QWP(0,$Xip));
+ &movdqa ($T3,&QWP(0,$const));
+ &movdqu ($Hkey,&QWP(0,$Htbl));
+ &pshufb ($Xi,$T3);
+
+ &sub ($len,0x10);
+ &jz (&label("odd_tail"));
+
+ #######
+ # Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
+ # [(H*Ii+1) + (H*Xi+1)] mod P =
+ # [(H*Ii+1) + H^2*(Ii+Xi)] mod P
+ #
+ &movdqu ($T1,&QWP(0,$inp)); # Ii
+ &movdqu ($Xn,&QWP(16,$inp)); # Ii+1
+ &pshufb ($T1,$T3);
+ &pshufb ($Xn,$T3);
+ &pxor ($Xi,$T1); # Ii+Xi
+
+ &clmul64x64_T3 ($Xhn,$Xn,$Hkey); # H*Ii+1
+ &movdqu ($Hkey,&QWP(16,$Htbl)); # load H^2
+
+ &sub ($len,0x20);
+ &lea ($inp,&DWP(32,$inp)); # i+=2
+ &jbe (&label("even_tail"));
+
+&set_label("mod_loop");
+ &clmul64x64_T3 ($Xhi,$Xi,$Hkey); # H^2*(Ii+Xi)
+ &movdqu ($Hkey,&QWP(0,$Htbl)); # load H
+
+ &pxor ($Xi,$Xn); # (H*Ii+1) + H^2*(Ii+Xi)
+ &pxor ($Xhi,$Xhn);
+
+ &reduction_alg5 ($Xhi,$Xi);
+
+ #######
+ &movdqa ($T3,&QWP(0,$const));
+ &movdqu ($T1,&QWP(0,$inp)); # Ii
+ &movdqu ($Xn,&QWP(16,$inp)); # Ii+1
+ &pshufb ($T1,$T3);
+ &pshufb ($Xn,$T3);
+ &pxor ($Xi,$T1); # Ii+Xi
+
+ &clmul64x64_T3 ($Xhn,$Xn,$Hkey); # H*Ii+1
+ &movdqu ($Hkey,&QWP(16,$Htbl)); # load H^2
+
+ &sub ($len,0x20);
+ &lea ($inp,&DWP(32,$inp));
+ &ja (&label("mod_loop"));
+
+&set_label("even_tail");
+ &clmul64x64_T3 ($Xhi,$Xi,$Hkey); # H^2*(Ii+Xi)
+
+ &pxor ($Xi,$Xn); # (H*Ii+1) + H^2*(Ii+Xi)
+ &pxor ($Xhi,$Xhn);
+
+ &reduction_alg5 ($Xhi,$Xi);
+
+ &movdqa ($T3,&QWP(0,$const));
+ &test ($len,$len);
+ &jnz (&label("done"));
+
+ &movdqu ($Hkey,&QWP(0,$Htbl)); # load H
+&set_label("odd_tail");
+ &movdqu ($T1,&QWP(0,$inp)); # Ii
+ &pshufb ($T1,$T3);
+ &pxor ($Xi,$T1); # Ii+Xi
+
+ &clmul64x64_T3 ($Xhi,$Xi,$Hkey); # H*(Ii+Xi)
+ &reduction_alg5 ($Xhi,$Xi);
+
+ &movdqa ($T3,&QWP(0,$const));
+&set_label("done");
+ &pshufb ($Xi,$T3);
+ &movdqu (&QWP(0,$Xip),$Xi);
+&function_end("gcm_ghash_clmul");
+
+}
+
+&set_label("bswap",64);
+ &data_byte(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
+ &data_byte(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2); # 0x1c2_polynomial
+}} # $sse2
+
+&set_label("rem_4bit",64);
+ &data_word(0,0x0000<<$S,0,0x1C20<<$S,0,0x3840<<$S,0,0x2460<<$S);
+ &data_word(0,0x7080<<$S,0,0x6CA0<<$S,0,0x48C0<<$S,0,0x54E0<<$S);
+ &data_word(0,0xE100<<$S,0,0xFD20<<$S,0,0xD940<<$S,0,0xC560<<$S);
+ &data_word(0,0x9180<<$S,0,0x8DA0<<$S,0,0xA9C0<<$S,0,0xB5E0<<$S);
+&set_label("rem_8bit",64);
+ &data_short(0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E);
+ &data_short(0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E);
+ &data_short(0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E);
+ &data_short(0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E);
+ &data_short(0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E);
+ &data_short(0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E);
+ &data_short(0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E);
+ &data_short(0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E);
+ &data_short(0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE);
+ &data_short(0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE);
+ &data_short(0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE);
+ &data_short(0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE);
+ &data_short(0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E);
+ &data_short(0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E);
+ &data_short(0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE);
+ &data_short(0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE);
+ &data_short(0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E);
+ &data_short(0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E);
+ &data_short(0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E);
+ &data_short(0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E);
+ &data_short(0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E);
+ &data_short(0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E);
+ &data_short(0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E);
+ &data_short(0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E);
+ &data_short(0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE);
+ &data_short(0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE);
+ &data_short(0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE);
+ &data_short(0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE);
+ &data_short(0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E);
+ &data_short(0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E);
+ &data_short(0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE);
+ &data_short(0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE);
+}}} # !$x86only
+
+&asciz("GHASH for x86, CRYPTOGAMS by <appro\@openssl.org>");
+&asm_finish();
+
+# A question was risen about choice of vanilla MMX. Or rather why wasn't
+# SSE2 chosen instead? In addition to the fact that MMX runs on legacy
+# CPUs such as PIII, "4-bit" MMX version was observed to provide better
+# performance than *corresponding* SSE2 one even on contemporary CPUs.
+# SSE2 results were provided by Peter-Michael Hager. He maintains SSE2
+# implementation featuring full range of lookup-table sizes, but with
+# per-invocation lookup table setup. Latter means that table size is
+# chosen depending on how much data is to be hashed in every given call,
+# more data - larger table. Best reported result for Core2 is ~4 cycles
+# per processed byte out of 64KB block. This number accounts even for
+# 64KB table setup overhead. As discussed in gcm128.c we choose to be
+# more conservative in respect to lookup table sizes, but how do the
+# results compare? Minimalistic "256B" MMX version delivers ~11 cycles
+# on same platform. As also discussed in gcm128.c, next in line "8-bit
+# Shoup's" or "4KB" method should deliver twice the performance of
+# "256B" one, in other words not worse than ~6 cycles per byte. It
+# should be also be noted that in SSE2 case improvement can be "super-
+# linear," i.e. more than twice, mostly because >>8 maps to single
+# instruction on SSE2 register. This is unlike "4-bit" case when >>4
+# maps to same amount of instructions in both MMX and SSE2 cases.
+# Bottom line is that switch to SSE2 is considered to be justifiable
+# only in case we choose to implement "8-bit" method...
diff --git a/deps/openssl/openssl/crypto/modes/asm/ghash-x86_64.pl b/deps/openssl/openssl/crypto/modes/asm/ghash-x86_64.pl
new file mode 100644
index 000000000..38d779edb
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/asm/ghash-x86_64.pl
@@ -0,0 +1,806 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# March, June 2010
+#
+# The module implements "4-bit" GCM GHASH function and underlying
+# single multiplication operation in GF(2^128). "4-bit" means that
+# it uses 256 bytes per-key table [+128 bytes shared table]. GHASH
+# function features so called "528B" variant utilizing additional
+# 256+16 bytes of per-key storage [+512 bytes shared table].
+# Performance results are for this streamed GHASH subroutine and are
+# expressed in cycles per processed byte, less is better:
+#
+# gcc 3.4.x(*) assembler
+#
+# P4 28.6 14.0 +100%
+# Opteron 19.3 7.7 +150%
+# Core2 17.8 8.1(**) +120%
+#
+# (*) comparison is not completely fair, because C results are
+# for vanilla "256B" implementation, while assembler results
+# are for "528B";-)
+# (**) it's mystery [to me] why Core2 result is not same as for
+# Opteron;
+
+# May 2010
+#
+# Add PCLMULQDQ version performing at 2.02 cycles per processed byte.
+# See ghash-x86.pl for background information and details about coding
+# techniques.
+#
+# Special thanks to David Woodhouse <dwmw2@infradead.org> for
+# providing access to a Westmere-based system on behalf of Intel
+# Open Source Technology Centre.
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+# common register layout
+$nlo="%rax";
+$nhi="%rbx";
+$Zlo="%r8";
+$Zhi="%r9";
+$tmp="%r10";
+$rem_4bit = "%r11";
+
+$Xi="%rdi";
+$Htbl="%rsi";
+
+# per-function register layout
+$cnt="%rcx";
+$rem="%rdx";
+
+sub LB() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/ or
+ $r =~ s/%[er]([sd]i)/%\1l/ or
+ $r =~ s/%[er](bp)/%\1l/ or
+ $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; }
+
+sub AUTOLOAD() # thunk [simplified] 32-bit style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
+ my $arg = pop;
+ $arg = "\$$arg" if ($arg*1 eq $arg);
+ $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
+}
+
+{ my $N;
+ sub loop() {
+ my $inp = shift;
+
+ $N++;
+$code.=<<___;
+ xor $nlo,$nlo
+ xor $nhi,$nhi
+ mov `&LB("$Zlo")`,`&LB("$nlo")`
+ mov `&LB("$Zlo")`,`&LB("$nhi")`
+ shl \$4,`&LB("$nlo")`
+ mov \$14,$cnt
+ mov 8($Htbl,$nlo),$Zlo
+ mov ($Htbl,$nlo),$Zhi
+ and \$0xf0,`&LB("$nhi")`
+ mov $Zlo,$rem
+ jmp .Loop$N
+
+.align 16
+.Loop$N:
+ shr \$4,$Zlo
+ and \$0xf,$rem
+ mov $Zhi,$tmp
+ mov ($inp,$cnt),`&LB("$nlo")`
+ shr \$4,$Zhi
+ xor 8($Htbl,$nhi),$Zlo
+ shl \$60,$tmp
+ xor ($Htbl,$nhi),$Zhi
+ mov `&LB("$nlo")`,`&LB("$nhi")`
+ xor ($rem_4bit,$rem,8),$Zhi
+ mov $Zlo,$rem
+ shl \$4,`&LB("$nlo")`
+ xor $tmp,$Zlo
+ dec $cnt
+ js .Lbreak$N
+
+ shr \$4,$Zlo
+ and \$0xf,$rem
+ mov $Zhi,$tmp
+ shr \$4,$Zhi
+ xor 8($Htbl,$nlo),$Zlo
+ shl \$60,$tmp
+ xor ($Htbl,$nlo),$Zhi
+ and \$0xf0,`&LB("$nhi")`
+ xor ($rem_4bit,$rem,8),$Zhi
+ mov $Zlo,$rem
+ xor $tmp,$Zlo
+ jmp .Loop$N
+
+.align 16
+.Lbreak$N:
+ shr \$4,$Zlo
+ and \$0xf,$rem
+ mov $Zhi,$tmp
+ shr \$4,$Zhi
+ xor 8($Htbl,$nlo),$Zlo
+ shl \$60,$tmp
+ xor ($Htbl,$nlo),$Zhi
+ and \$0xf0,`&LB("$nhi")`
+ xor ($rem_4bit,$rem,8),$Zhi
+ mov $Zlo,$rem
+ xor $tmp,$Zlo
+
+ shr \$4,$Zlo
+ and \$0xf,$rem
+ mov $Zhi,$tmp
+ shr \$4,$Zhi
+ xor 8($Htbl,$nhi),$Zlo
+ shl \$60,$tmp
+ xor ($Htbl,$nhi),$Zhi
+ xor $tmp,$Zlo
+ xor ($rem_4bit,$rem,8),$Zhi
+
+ bswap $Zlo
+ bswap $Zhi
+___
+}}
+
+$code=<<___;
+.text
+
+.globl gcm_gmult_4bit
+.type gcm_gmult_4bit,\@function,2
+.align 16
+gcm_gmult_4bit:
+ push %rbx
+ push %rbp # %rbp and %r12 are pushed exclusively in
+ push %r12 # order to reuse Win64 exception handler...
+.Lgmult_prologue:
+
+ movzb 15($Xi),$Zlo
+ lea .Lrem_4bit(%rip),$rem_4bit
+___
+ &loop ($Xi);
+$code.=<<___;
+ mov $Zlo,8($Xi)
+ mov $Zhi,($Xi)
+
+ mov 16(%rsp),%rbx
+ lea 24(%rsp),%rsp
+.Lgmult_epilogue:
+ ret
+.size gcm_gmult_4bit,.-gcm_gmult_4bit
+___
+
+# per-function register layout
+$inp="%rdx";
+$len="%rcx";
+$rem_8bit=$rem_4bit;
+
+$code.=<<___;
+.globl gcm_ghash_4bit
+.type gcm_ghash_4bit,\@function,4
+.align 16
+gcm_ghash_4bit:
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ sub \$280,%rsp
+.Lghash_prologue:
+ mov $inp,%r14 # reassign couple of args
+ mov $len,%r15
+___
+{ my $inp="%r14";
+ my $dat="%edx";
+ my $len="%r15";
+ my @nhi=("%ebx","%ecx");
+ my @rem=("%r12","%r13");
+ my $Hshr4="%rbp";
+
+ &sub ($Htbl,-128); # size optimization
+ &lea ($Hshr4,"16+128(%rsp)");
+ { my @lo =($nlo,$nhi);
+ my @hi =($Zlo,$Zhi);
+
+ &xor ($dat,$dat);
+ for ($i=0,$j=-2;$i<18;$i++,$j++) {
+ &mov ("$j(%rsp)",&LB($dat)) if ($i>1);
+ &or ($lo[0],$tmp) if ($i>1);
+ &mov (&LB($dat),&LB($lo[1])) if ($i>0 && $i<17);
+ &shr ($lo[1],4) if ($i>0 && $i<17);
+ &mov ($tmp,$hi[1]) if ($i>0 && $i<17);
+ &shr ($hi[1],4) if ($i>0 && $i<17);
+ &mov ("8*$j($Hshr4)",$hi[0]) if ($i>1);
+ &mov ($hi[0],"16*$i+0-128($Htbl)") if ($i<16);
+ &shl (&LB($dat),4) if ($i>0 && $i<17);
+ &mov ("8*$j-128($Hshr4)",$lo[0]) if ($i>1);
+ &mov ($lo[0],"16*$i+8-128($Htbl)") if ($i<16);
+ &shl ($tmp,60) if ($i>0 && $i<17);
+
+ push (@lo,shift(@lo));
+ push (@hi,shift(@hi));
+ }
+ }
+ &add ($Htbl,-128);
+ &mov ($Zlo,"8($Xi)");
+ &mov ($Zhi,"0($Xi)");
+ &add ($len,$inp); # pointer to the end of data
+ &lea ($rem_8bit,".Lrem_8bit(%rip)");
+ &jmp (".Louter_loop");
+
+$code.=".align 16\n.Louter_loop:\n";
+ &xor ($Zhi,"($inp)");
+ &mov ("%rdx","8($inp)");
+ &lea ($inp,"16($inp)");
+ &xor ("%rdx",$Zlo);
+ &mov ("($Xi)",$Zhi);
+ &mov ("8($Xi)","%rdx");
+ &shr ("%rdx",32);
+
+ &xor ($nlo,$nlo);
+ &rol ($dat,8);
+ &mov (&LB($nlo),&LB($dat));
+ &movz ($nhi[0],&LB($dat));
+ &shl (&LB($nlo),4);
+ &shr ($nhi[0],4);
+
+ for ($j=11,$i=0;$i<15;$i++) {
+ &rol ($dat,8);
+ &xor ($Zlo,"8($Htbl,$nlo)") if ($i>0);
+ &xor ($Zhi,"($Htbl,$nlo)") if ($i>0);
+ &mov ($Zlo,"8($Htbl,$nlo)") if ($i==0);
+ &mov ($Zhi,"($Htbl,$nlo)") if ($i==0);
+
+ &mov (&LB($nlo),&LB($dat));
+ &xor ($Zlo,$tmp) if ($i>0);
+ &movzw ($rem[1],"($rem_8bit,$rem[1],2)") if ($i>0);
+
+ &movz ($nhi[1],&LB($dat));
+ &shl (&LB($nlo),4);
+ &movzb ($rem[0],"(%rsp,$nhi[0])");
+
+ &shr ($nhi[1],4) if ($i<14);
+ &and ($nhi[1],0xf0) if ($i==14);
+ &shl ($rem[1],48) if ($i>0);
+ &xor ($rem[0],$Zlo);
+
+ &mov ($tmp,$Zhi);
+ &xor ($Zhi,$rem[1]) if ($i>0);
+ &shr ($Zlo,8);
+
+ &movz ($rem[0],&LB($rem[0]));
+ &mov ($dat,"$j($Xi)") if (--$j%4==0);
+ &shr ($Zhi,8);
+
+ &xor ($Zlo,"-128($Hshr4,$nhi[0],8)");
+ &shl ($tmp,56);
+ &xor ($Zhi,"($Hshr4,$nhi[0],8)");
+
+ unshift (@nhi,pop(@nhi)); # "rotate" registers
+ unshift (@rem,pop(@rem));
+ }
+ &movzw ($rem[1],"($rem_8bit,$rem[1],2)");
+ &xor ($Zlo,"8($Htbl,$nlo)");
+ &xor ($Zhi,"($Htbl,$nlo)");
+
+ &shl ($rem[1],48);
+ &xor ($Zlo,$tmp);
+
+ &xor ($Zhi,$rem[1]);
+ &movz ($rem[0],&LB($Zlo));
+ &shr ($Zlo,4);
+
+ &mov ($tmp,$Zhi);
+ &shl (&LB($rem[0]),4);
+ &shr ($Zhi,4);
+
+ &xor ($Zlo,"8($Htbl,$nhi[0])");
+ &movzw ($rem[0],"($rem_8bit,$rem[0],2)");
+ &shl ($tmp,60);
+
+ &xor ($Zhi,"($Htbl,$nhi[0])");
+ &xor ($Zlo,$tmp);
+ &shl ($rem[0],48);
+
+ &bswap ($Zlo);
+ &xor ($Zhi,$rem[0]);
+
+ &bswap ($Zhi);
+ &cmp ($inp,$len);
+ &jb (".Louter_loop");
+}
+$code.=<<___;
+ mov $Zlo,8($Xi)
+ mov $Zhi,($Xi)
+
+ lea 280(%rsp),%rsi
+ mov 0(%rsi),%r15
+ mov 8(%rsi),%r14
+ mov 16(%rsi),%r13
+ mov 24(%rsi),%r12
+ mov 32(%rsi),%rbp
+ mov 40(%rsi),%rbx
+ lea 48(%rsi),%rsp
+.Lghash_epilogue:
+ ret
+.size gcm_ghash_4bit,.-gcm_ghash_4bit
+___
+
+######################################################################
+# PCLMULQDQ version.
+
+@_4args=$win64? ("%rcx","%rdx","%r8", "%r9") : # Win64 order
+ ("%rdi","%rsi","%rdx","%rcx"); # Unix order
+
+($Xi,$Xhi)=("%xmm0","%xmm1"); $Hkey="%xmm2";
+($T1,$T2,$T3)=("%xmm3","%xmm4","%xmm5");
+
+sub clmul64x64_T2 { # minimal register pressure
+my ($Xhi,$Xi,$Hkey,$modulo)=@_;
+
+$code.=<<___ if (!defined($modulo));
+ movdqa $Xi,$Xhi #
+ pshufd \$0b01001110,$Xi,$T1
+ pshufd \$0b01001110,$Hkey,$T2
+ pxor $Xi,$T1 #
+ pxor $Hkey,$T2
+___
+$code.=<<___;
+ pclmulqdq \$0x00,$Hkey,$Xi #######
+ pclmulqdq \$0x11,$Hkey,$Xhi #######
+ pclmulqdq \$0x00,$T2,$T1 #######
+ pxor $Xi,$T1 #
+ pxor $Xhi,$T1 #
+
+ movdqa $T1,$T2 #
+ psrldq \$8,$T1
+ pslldq \$8,$T2 #
+ pxor $T1,$Xhi
+ pxor $T2,$Xi #
+___
+}
+
+sub reduction_alg9 { # 17/13 times faster than Intel version
+my ($Xhi,$Xi) = @_;
+
+$code.=<<___;
+ # 1st phase
+ movdqa $Xi,$T1 #
+ psllq \$1,$Xi
+ pxor $T1,$Xi #
+ psllq \$5,$Xi #
+ pxor $T1,$Xi #
+ psllq \$57,$Xi #
+ movdqa $Xi,$T2 #
+ pslldq \$8,$Xi
+ psrldq \$8,$T2 #
+ pxor $T1,$Xi
+ pxor $T2,$Xhi #
+
+ # 2nd phase
+ movdqa $Xi,$T2
+ psrlq \$5,$Xi
+ pxor $T2,$Xi #
+ psrlq \$1,$Xi #
+ pxor $T2,$Xi #
+ pxor $Xhi,$T2
+ psrlq \$1,$Xi #
+ pxor $T2,$Xi #
+___
+}
+
+{ my ($Htbl,$Xip)=@_4args;
+
+$code.=<<___;
+.globl gcm_init_clmul
+.type gcm_init_clmul,\@abi-omnipotent
+.align 16
+gcm_init_clmul:
+ movdqu ($Xip),$Hkey
+ pshufd \$0b01001110,$Hkey,$Hkey # dword swap
+
+ # <<1 twist
+ pshufd \$0b11111111,$Hkey,$T2 # broadcast uppermost dword
+ movdqa $Hkey,$T1
+ psllq \$1,$Hkey
+ pxor $T3,$T3 #
+ psrlq \$63,$T1
+ pcmpgtd $T2,$T3 # broadcast carry bit
+ pslldq \$8,$T1
+ por $T1,$Hkey # H<<=1
+
+ # magic reduction
+ pand .L0x1c2_polynomial(%rip),$T3
+ pxor $T3,$Hkey # if(carry) H^=0x1c2_polynomial
+
+ # calculate H^2
+ movdqa $Hkey,$Xi
+___
+ &clmul64x64_T2 ($Xhi,$Xi,$Hkey);
+ &reduction_alg9 ($Xhi,$Xi);
+$code.=<<___;
+ movdqu $Hkey,($Htbl) # save H
+ movdqu $Xi,16($Htbl) # save H^2
+ ret
+.size gcm_init_clmul,.-gcm_init_clmul
+___
+}
+
+{ my ($Xip,$Htbl)=@_4args;
+
+$code.=<<___;
+.globl gcm_gmult_clmul
+.type gcm_gmult_clmul,\@abi-omnipotent
+.align 16
+gcm_gmult_clmul:
+ movdqu ($Xip),$Xi
+ movdqa .Lbswap_mask(%rip),$T3
+ movdqu ($Htbl),$Hkey
+ pshufb $T3,$Xi
+___
+ &clmul64x64_T2 ($Xhi,$Xi,$Hkey);
+ &reduction_alg9 ($Xhi,$Xi);
+$code.=<<___;
+ pshufb $T3,$Xi
+ movdqu $Xi,($Xip)
+ ret
+.size gcm_gmult_clmul,.-gcm_gmult_clmul
+___
+}
+
+{ my ($Xip,$Htbl,$inp,$len)=@_4args;
+ my $Xn="%xmm6";
+ my $Xhn="%xmm7";
+ my $Hkey2="%xmm8";
+ my $T1n="%xmm9";
+ my $T2n="%xmm10";
+
+$code.=<<___;
+.globl gcm_ghash_clmul
+.type gcm_ghash_clmul,\@abi-omnipotent
+.align 16
+gcm_ghash_clmul:
+___
+$code.=<<___ if ($win64);
+.LSEH_begin_gcm_ghash_clmul:
+ # I can't trust assembler to use specific encoding:-(
+ .byte 0x48,0x83,0xec,0x58 #sub \$0x58,%rsp
+ .byte 0x0f,0x29,0x34,0x24 #movaps %xmm6,(%rsp)
+ .byte 0x0f,0x29,0x7c,0x24,0x10 #movdqa %xmm7,0x10(%rsp)
+ .byte 0x44,0x0f,0x29,0x44,0x24,0x20 #movaps %xmm8,0x20(%rsp)
+ .byte 0x44,0x0f,0x29,0x4c,0x24,0x30 #movaps %xmm9,0x30(%rsp)
+ .byte 0x44,0x0f,0x29,0x54,0x24,0x40 #movaps %xmm10,0x40(%rsp)
+___
+$code.=<<___;
+ movdqa .Lbswap_mask(%rip),$T3
+
+ movdqu ($Xip),$Xi
+ movdqu ($Htbl),$Hkey
+ pshufb $T3,$Xi
+
+ sub \$0x10,$len
+ jz .Lodd_tail
+
+ movdqu 16($Htbl),$Hkey2
+ #######
+ # Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
+ # [(H*Ii+1) + (H*Xi+1)] mod P =
+ # [(H*Ii+1) + H^2*(Ii+Xi)] mod P
+ #
+ movdqu ($inp),$T1 # Ii
+ movdqu 16($inp),$Xn # Ii+1
+ pshufb $T3,$T1
+ pshufb $T3,$Xn
+ pxor $T1,$Xi # Ii+Xi
+___
+ &clmul64x64_T2 ($Xhn,$Xn,$Hkey); # H*Ii+1
+$code.=<<___;
+ movdqa $Xi,$Xhi #
+ pshufd \$0b01001110,$Xi,$T1
+ pshufd \$0b01001110,$Hkey2,$T2
+ pxor $Xi,$T1 #
+ pxor $Hkey2,$T2
+
+ lea 32($inp),$inp # i+=2
+ sub \$0x20,$len
+ jbe .Leven_tail
+
+.Lmod_loop:
+___
+ &clmul64x64_T2 ($Xhi,$Xi,$Hkey2,1); # H^2*(Ii+Xi)
+$code.=<<___;
+ movdqu ($inp),$T1 # Ii
+ pxor $Xn,$Xi # (H*Ii+1) + H^2*(Ii+Xi)
+ pxor $Xhn,$Xhi
+
+ movdqu 16($inp),$Xn # Ii+1
+ pshufb $T3,$T1
+ pshufb $T3,$Xn
+
+ movdqa $Xn,$Xhn #
+ pshufd \$0b01001110,$Xn,$T1n
+ pshufd \$0b01001110,$Hkey,$T2n
+ pxor $Xn,$T1n #
+ pxor $Hkey,$T2n
+ pxor $T1,$Xhi # "Ii+Xi", consume early
+
+ movdqa $Xi,$T1 # 1st phase
+ psllq \$1,$Xi
+ pxor $T1,$Xi #
+ psllq \$5,$Xi #
+ pxor $T1,$Xi #
+ pclmulqdq \$0x00,$Hkey,$Xn #######
+ psllq \$57,$Xi #
+ movdqa $Xi,$T2 #
+ pslldq \$8,$Xi
+ psrldq \$8,$T2 #
+ pxor $T1,$Xi
+ pxor $T2,$Xhi #
+
+ pclmulqdq \$0x11,$Hkey,$Xhn #######
+ movdqa $Xi,$T2 # 2nd phase
+ psrlq \$5,$Xi
+ pxor $T2,$Xi #
+ psrlq \$1,$Xi #
+ pxor $T2,$Xi #
+ pxor $Xhi,$T2
+ psrlq \$1,$Xi #
+ pxor $T2,$Xi #
+
+ pclmulqdq \$0x00,$T2n,$T1n #######
+ movdqa $Xi,$Xhi #
+ pshufd \$0b01001110,$Xi,$T1
+ pshufd \$0b01001110,$Hkey2,$T2
+ pxor $Xi,$T1 #
+ pxor $Hkey2,$T2
+
+ pxor $Xn,$T1n #
+ pxor $Xhn,$T1n #
+ movdqa $T1n,$T2n #
+ psrldq \$8,$T1n
+ pslldq \$8,$T2n #
+ pxor $T1n,$Xhn
+ pxor $T2n,$Xn #
+
+ lea 32($inp),$inp
+ sub \$0x20,$len
+ ja .Lmod_loop
+
+.Leven_tail:
+___
+ &clmul64x64_T2 ($Xhi,$Xi,$Hkey2,1); # H^2*(Ii+Xi)
+$code.=<<___;
+ pxor $Xn,$Xi # (H*Ii+1) + H^2*(Ii+Xi)
+ pxor $Xhn,$Xhi
+___
+ &reduction_alg9 ($Xhi,$Xi);
+$code.=<<___;
+ test $len,$len
+ jnz .Ldone
+
+.Lodd_tail:
+ movdqu ($inp),$T1 # Ii
+ pshufb $T3,$T1
+ pxor $T1,$Xi # Ii+Xi
+___
+ &clmul64x64_T2 ($Xhi,$Xi,$Hkey); # H*(Ii+Xi)
+ &reduction_alg9 ($Xhi,$Xi);
+$code.=<<___;
+.Ldone:
+ pshufb $T3,$Xi
+ movdqu $Xi,($Xip)
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp),%xmm6
+ movaps 0x10(%rsp),%xmm7
+ movaps 0x20(%rsp),%xmm8
+ movaps 0x30(%rsp),%xmm9
+ movaps 0x40(%rsp),%xmm10
+ add \$0x58,%rsp
+___
+$code.=<<___;
+ ret
+.LSEH_end_gcm_ghash_clmul:
+.size gcm_ghash_clmul,.-gcm_ghash_clmul
+___
+}
+
+$code.=<<___;
+.align 64
+.Lbswap_mask:
+ .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+.L0x1c2_polynomial:
+ .byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2
+.align 64
+.type .Lrem_4bit,\@object
+.Lrem_4bit:
+ .long 0,`0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`
+ .long 0,`0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`
+ .long 0,`0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`
+ .long 0,`0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`
+.type .Lrem_8bit,\@object
+.Lrem_8bit:
+ .value 0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E
+ .value 0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E
+ .value 0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E
+ .value 0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E
+ .value 0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E
+ .value 0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E
+ .value 0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E
+ .value 0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E
+ .value 0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE
+ .value 0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE
+ .value 0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE
+ .value 0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE
+ .value 0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E
+ .value 0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E
+ .value 0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE
+ .value 0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE
+ .value 0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E
+ .value 0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E
+ .value 0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E
+ .value 0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E
+ .value 0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E
+ .value 0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E
+ .value 0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E
+ .value 0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E
+ .value 0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE
+ .value 0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE
+ .value 0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE
+ .value 0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE
+ .value 0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E
+ .value 0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E
+ .value 0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE
+ .value 0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE
+
+.asciz "GHASH for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align 64
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+.type se_handler,\@abi-omnipotent
+.align 16
+se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # prologue label
+ cmp %r10,%rbx # context->Rip<prologue label
+ jb .Lin_prologue
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lin_prologue
+
+ lea 24(%rax),%rax # adjust "rsp"
+
+ mov -8(%rax),%rbx
+ mov -16(%rax),%rbp
+ mov -24(%rax),%r12
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %r12,216($context) # restore context->R12
+
+.Lin_prologue:
+ mov 8(%rax),%rdi
+ mov 16(%rax),%rsi
+ mov %rax,152($context) # restore context->Rsp
+ mov %rsi,168($context) # restore context->Rsi
+ mov %rdi,176($context) # restore context->Rdi
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$`1232/8`,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size se_handler,.-se_handler
+
+.section .pdata
+.align 4
+ .rva .LSEH_begin_gcm_gmult_4bit
+ .rva .LSEH_end_gcm_gmult_4bit
+ .rva .LSEH_info_gcm_gmult_4bit
+
+ .rva .LSEH_begin_gcm_ghash_4bit
+ .rva .LSEH_end_gcm_ghash_4bit
+ .rva .LSEH_info_gcm_ghash_4bit
+
+ .rva .LSEH_begin_gcm_ghash_clmul
+ .rva .LSEH_end_gcm_ghash_clmul
+ .rva .LSEH_info_gcm_ghash_clmul
+
+.section .xdata
+.align 8
+.LSEH_info_gcm_gmult_4bit:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lgmult_prologue,.Lgmult_epilogue # HandlerData
+.LSEH_info_gcm_ghash_4bit:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lghash_prologue,.Lghash_epilogue # HandlerData
+.LSEH_info_gcm_ghash_clmul:
+ .byte 0x01,0x1f,0x0b,0x00
+ .byte 0x1f,0xa8,0x04,0x00 #movaps 0x40(rsp),xmm10
+ .byte 0x19,0x98,0x03,0x00 #movaps 0x30(rsp),xmm9
+ .byte 0x13,0x88,0x02,0x00 #movaps 0x20(rsp),xmm8
+ .byte 0x0d,0x78,0x01,0x00 #movaps 0x10(rsp),xmm7
+ .byte 0x08,0x68,0x00,0x00 #movaps (rsp),xmm6
+ .byte 0x04,0xa2,0x00,0x00 #sub rsp,0x58
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+
+print $code;
+
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/modes/cbc128.c b/deps/openssl/openssl/crypto/modes/cbc128.c
index 8f8bd563b..3d3782cbe 100644
--- a/deps/openssl/openssl/crypto/modes/cbc128.c
+++ b/deps/openssl/openssl/crypto/modes/cbc128.c
@@ -48,7 +48,8 @@
*
*/
-#include "modes.h"
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
#include <string.h>
#ifndef MODES_DEBUG
@@ -58,12 +59,7 @@
#endif
#include <assert.h>
-#define STRICT_ALIGNMENT 1
-#if defined(__i386) || defined(__i386__) || \
- defined(__x86_64) || defined(__x86_64__) || \
- defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
- defined(__s390__) || defined(__s390x__)
-# undef STRICT_ALIGNMENT
+#ifndef STRICT_ALIGNMENT
# define STRICT_ALIGNMENT 0
#endif
diff --git a/deps/openssl/openssl/crypto/modes/ccm128.c b/deps/openssl/openssl/crypto/modes/ccm128.c
new file mode 100644
index 000000000..c9b35e5b3
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/ccm128.c
@@ -0,0 +1,441 @@
+/* ====================================================================
+ * Copyright (c) 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.
+ * ====================================================================
+ */
+
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+/* First you setup M and L parameters and pass the key schedule.
+ * This is called once per session setup... */
+void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
+ unsigned int M,unsigned int L,void *key,block128_f block)
+{
+ memset(ctx->nonce.c,0,sizeof(ctx->nonce.c));
+ ctx->nonce.c[0] = ((u8)(L-1)&7) | (u8)(((M-2)/2)&7)<<3;
+ ctx->blocks = 0;
+ ctx->block = block;
+ ctx->key = key;
+}
+
+/* !!! Following interfaces are to be called *once* per packet !!! */
+
+/* Then you setup per-message nonce and pass the length of the message */
+int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
+ const unsigned char *nonce,size_t nlen,size_t mlen)
+{
+ unsigned int L = ctx->nonce.c[0]&7; /* the L parameter */
+
+ if (nlen<(14-L)) return -1; /* nonce is too short */
+
+ if (sizeof(mlen)==8 && L>=3) {
+ ctx->nonce.c[8] = (u8)(mlen>>(56%(sizeof(mlen)*8)));
+ ctx->nonce.c[9] = (u8)(mlen>>(48%(sizeof(mlen)*8)));
+ ctx->nonce.c[10] = (u8)(mlen>>(40%(sizeof(mlen)*8)));
+ ctx->nonce.c[11] = (u8)(mlen>>(32%(sizeof(mlen)*8)));
+ }
+ else
+ *(u32*)(&ctx->nonce.c[8]) = 0;
+
+ ctx->nonce.c[12] = (u8)(mlen>>24);
+ ctx->nonce.c[13] = (u8)(mlen>>16);
+ ctx->nonce.c[14] = (u8)(mlen>>8);
+ ctx->nonce.c[15] = (u8)mlen;
+
+ ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */
+ memcpy(&ctx->nonce.c[1],nonce,14-L);
+
+ return 0;
+}
+
+/* Then you pass additional authentication data, this is optional */
+void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
+ const unsigned char *aad,size_t alen)
+{ unsigned int i;
+ block128_f block = ctx->block;
+
+ if (alen==0) return;
+
+ ctx->nonce.c[0] |= 0x40; /* set Adata flag */
+ (*block)(ctx->nonce.c,ctx->cmac.c,ctx->key),
+ ctx->blocks++;
+
+ if (alen<(0x10000-0x100)) {
+ ctx->cmac.c[0] ^= (u8)(alen>>8);
+ ctx->cmac.c[1] ^= (u8)alen;
+ i=2;
+ }
+ else if (sizeof(alen)==8 && alen>=(size_t)1<<(32%(sizeof(alen)*8))) {
+ ctx->cmac.c[0] ^= 0xFF;
+ ctx->cmac.c[1] ^= 0xFF;
+ ctx->cmac.c[2] ^= (u8)(alen>>(56%(sizeof(alen)*8)));
+ ctx->cmac.c[3] ^= (u8)(alen>>(48%(sizeof(alen)*8)));
+ ctx->cmac.c[4] ^= (u8)(alen>>(40%(sizeof(alen)*8)));
+ ctx->cmac.c[5] ^= (u8)(alen>>(32%(sizeof(alen)*8)));
+ ctx->cmac.c[6] ^= (u8)(alen>>24);
+ ctx->cmac.c[7] ^= (u8)(alen>>16);
+ ctx->cmac.c[8] ^= (u8)(alen>>8);
+ ctx->cmac.c[9] ^= (u8)alen;
+ i=10;
+ }
+ else {
+ ctx->cmac.c[0] ^= 0xFF;
+ ctx->cmac.c[1] ^= 0xFE;
+ ctx->cmac.c[2] ^= (u8)(alen>>24);
+ ctx->cmac.c[3] ^= (u8)(alen>>16);
+ ctx->cmac.c[4] ^= (u8)(alen>>8);
+ ctx->cmac.c[5] ^= (u8)alen;
+ i=6;
+ }
+
+ do {
+ for(;i<16 && alen;++i,++aad,--alen)
+ ctx->cmac.c[i] ^= *aad;
+ (*block)(ctx->cmac.c,ctx->cmac.c,ctx->key),
+ ctx->blocks++;
+ i=0;
+ } while (alen);
+}
+
+/* Finally you encrypt or decrypt the message */
+
+/* counter part of nonce may not be larger than L*8 bits,
+ * L is not larger than 8, therefore 64-bit counter... */
+static void ctr64_inc(unsigned char *counter) {
+ unsigned int n=8;
+ u8 c;
+
+ counter += 8;
+ do {
+ --n;
+ c = counter[n];
+ ++c;
+ counter[n] = c;
+ if (c) return;
+ } while (n);
+}
+
+int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out,
+ size_t len)
+{
+ size_t n;
+ unsigned int i,L;
+ unsigned char flags0 = ctx->nonce.c[0];
+ block128_f block = ctx->block;
+ void * key = ctx->key;
+ union { u64 u[2]; u8 c[16]; } scratch;
+
+ if (!(flags0&0x40))
+ (*block)(ctx->nonce.c,ctx->cmac.c,key),
+ ctx->blocks++;
+
+ ctx->nonce.c[0] = L = flags0&7;
+ for (n=0,i=15-L;i<15;++i) {
+ n |= ctx->nonce.c[i];
+ ctx->nonce.c[i]=0;
+ n <<= 8;
+ }
+ n |= ctx->nonce.c[15]; /* reconstructed length */
+ ctx->nonce.c[15]=1;
+
+ if (n!=len) return -1; /* length mismatch */
+
+ ctx->blocks += ((len+15)>>3)|1;
+ if (ctx->blocks > (U64(1)<<61)) return -2; /* too much data */
+
+ while (len>=16) {
+#if defined(STRICT_ALIGNMENT)
+ union { u64 u[2]; u8 c[16]; } temp;
+
+ memcpy (temp.c,inp,16);
+ ctx->cmac.u[0] ^= temp.u[0];
+ ctx->cmac.u[1] ^= temp.u[1];
+#else
+ ctx->cmac.u[0] ^= ((u64*)inp)[0];
+ ctx->cmac.u[1] ^= ((u64*)inp)[1];
+#endif
+ (*block)(ctx->cmac.c,ctx->cmac.c,key);
+ (*block)(ctx->nonce.c,scratch.c,key);
+ ctr64_inc(ctx->nonce.c);
+#if defined(STRICT_ALIGNMENT)
+ temp.u[0] ^= scratch.u[0];
+ temp.u[1] ^= scratch.u[1];
+ memcpy(out,temp.c,16);
+#else
+ ((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0];
+ ((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1];
+#endif
+ inp += 16;
+ out += 16;
+ len -= 16;
+ }
+
+ if (len) {
+ for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i];
+ (*block)(ctx->cmac.c,ctx->cmac.c,key);
+ (*block)(ctx->nonce.c,scratch.c,key);
+ for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i];
+ }
+
+ for (i=15-L;i<16;++i)
+ ctx->nonce.c[i]=0;
+
+ (*block)(ctx->nonce.c,scratch.c,key);
+ ctx->cmac.u[0] ^= scratch.u[0];
+ ctx->cmac.u[1] ^= scratch.u[1];
+
+ ctx->nonce.c[0] = flags0;
+
+ return 0;
+}
+
+int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out,
+ size_t len)
+{
+ size_t n;
+ unsigned int i,L;
+ unsigned char flags0 = ctx->nonce.c[0];
+ block128_f block = ctx->block;
+ void * key = ctx->key;
+ union { u64 u[2]; u8 c[16]; } scratch;
+
+ if (!(flags0&0x40))
+ (*block)(ctx->nonce.c,ctx->cmac.c,key);
+
+ ctx->nonce.c[0] = L = flags0&7;
+ for (n=0,i=15-L;i<15;++i) {
+ n |= ctx->nonce.c[i];
+ ctx->nonce.c[i]=0;
+ n <<= 8;
+ }
+ n |= ctx->nonce.c[15]; /* reconstructed length */
+ ctx->nonce.c[15]=1;
+
+ if (n!=len) return -1;
+
+ while (len>=16) {
+#if defined(STRICT_ALIGNMENT)
+ union { u64 u[2]; u8 c[16]; } temp;
+#endif
+ (*block)(ctx->nonce.c,scratch.c,key);
+ ctr64_inc(ctx->nonce.c);
+#if defined(STRICT_ALIGNMENT)
+ memcpy (temp.c,inp,16);
+ ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
+ ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
+ memcpy (out,scratch.c,16);
+#else
+ ctx->cmac.u[0] ^= (((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]);
+ ctx->cmac.u[1] ^= (((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]);
+#endif
+ (*block)(ctx->cmac.c,ctx->cmac.c,key);
+
+ inp += 16;
+ out += 16;
+ len -= 16;
+ }
+
+ if (len) {
+ (*block)(ctx->nonce.c,scratch.c,key);
+ for (i=0; i<len; ++i)
+ ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]);
+ (*block)(ctx->cmac.c,ctx->cmac.c,key);
+ }
+
+ for (i=15-L;i<16;++i)
+ ctx->nonce.c[i]=0;
+
+ (*block)(ctx->nonce.c,scratch.c,key);
+ ctx->cmac.u[0] ^= scratch.u[0];
+ ctx->cmac.u[1] ^= scratch.u[1];
+
+ ctx->nonce.c[0] = flags0;
+
+ return 0;
+}
+
+static void ctr64_add (unsigned char *counter,size_t inc)
+{ size_t n=8, val=0;
+
+ counter += 8;
+ do {
+ --n;
+ val += counter[n] + (inc&0xff);
+ counter[n] = (unsigned char)val;
+ val >>= 8; /* carry bit */
+ inc >>= 8;
+ } while(n && (inc || val));
+}
+
+int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out,
+ size_t len,ccm128_f stream)
+{
+ size_t n;
+ unsigned int i,L;
+ unsigned char flags0 = ctx->nonce.c[0];
+ block128_f block = ctx->block;
+ void * key = ctx->key;
+ union { u64 u[2]; u8 c[16]; } scratch;
+
+ if (!(flags0&0x40))
+ (*block)(ctx->nonce.c,ctx->cmac.c,key),
+ ctx->blocks++;
+
+ ctx->nonce.c[0] = L = flags0&7;
+ for (n=0,i=15-L;i<15;++i) {
+ n |= ctx->nonce.c[i];
+ ctx->nonce.c[i]=0;
+ n <<= 8;
+ }
+ n |= ctx->nonce.c[15]; /* reconstructed length */
+ ctx->nonce.c[15]=1;
+
+ if (n!=len) return -1; /* length mismatch */
+
+ ctx->blocks += ((len+15)>>3)|1;
+ if (ctx->blocks > (U64(1)<<61)) return -2; /* too much data */
+
+ if ((n=len/16)) {
+ (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c);
+ n *= 16;
+ inp += n;
+ out += n;
+ len -= n;
+ if (len) ctr64_add(ctx->nonce.c,n/16);
+ }
+
+ if (len) {
+ for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i];
+ (*block)(ctx->cmac.c,ctx->cmac.c,key);
+ (*block)(ctx->nonce.c,scratch.c,key);
+ for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i];
+ }
+
+ for (i=15-L;i<16;++i)
+ ctx->nonce.c[i]=0;
+
+ (*block)(ctx->nonce.c,scratch.c,key);
+ ctx->cmac.u[0] ^= scratch.u[0];
+ ctx->cmac.u[1] ^= scratch.u[1];
+
+ ctx->nonce.c[0] = flags0;
+
+ return 0;
+}
+
+int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out,
+ size_t len,ccm128_f stream)
+{
+ size_t n;
+ unsigned int i,L;
+ unsigned char flags0 = ctx->nonce.c[0];
+ block128_f block = ctx->block;
+ void * key = ctx->key;
+ union { u64 u[2]; u8 c[16]; } scratch;
+
+ if (!(flags0&0x40))
+ (*block)(ctx->nonce.c,ctx->cmac.c,key);
+
+ ctx->nonce.c[0] = L = flags0&7;
+ for (n=0,i=15-L;i<15;++i) {
+ n |= ctx->nonce.c[i];
+ ctx->nonce.c[i]=0;
+ n <<= 8;
+ }
+ n |= ctx->nonce.c[15]; /* reconstructed length */
+ ctx->nonce.c[15]=1;
+
+ if (n!=len) return -1;
+
+ if ((n=len/16)) {
+ (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c);
+ n *= 16;
+ inp += n;
+ out += n;
+ len -= n;
+ if (len) ctr64_add(ctx->nonce.c,n/16);
+ }
+
+ if (len) {
+ (*block)(ctx->nonce.c,scratch.c,key);
+ for (i=0; i<len; ++i)
+ ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]);
+ (*block)(ctx->cmac.c,ctx->cmac.c,key);
+ }
+
+ for (i=15-L;i<16;++i)
+ ctx->nonce.c[i]=0;
+
+ (*block)(ctx->nonce.c,scratch.c,key);
+ ctx->cmac.u[0] ^= scratch.u[0];
+ ctx->cmac.u[1] ^= scratch.u[1];
+
+ ctx->nonce.c[0] = flags0;
+
+ return 0;
+}
+
+size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx,unsigned char *tag,size_t len)
+{ unsigned int M = (ctx->nonce.c[0]>>3)&7; /* the M parameter */
+
+ M *= 2; M += 2;
+ if (len<M) return 0;
+ memcpy(tag,ctx->cmac.c,M);
+ return M;
+}
diff --git a/deps/openssl/openssl/crypto/modes/cfb128.c b/deps/openssl/openssl/crypto/modes/cfb128.c
index e5938c613..4e6f5d35e 100644
--- a/deps/openssl/openssl/crypto/modes/cfb128.c
+++ b/deps/openssl/openssl/crypto/modes/cfb128.c
@@ -48,7 +48,8 @@
*
*/
-#include "modes.h"
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
#include <string.h>
#ifndef MODES_DEBUG
@@ -58,14 +59,6 @@
#endif
#include <assert.h>
-#define STRICT_ALIGNMENT
-#if defined(__i386) || defined(__i386__) || \
- defined(__x86_64) || defined(__x86_64__) || \
- defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
- defined(__s390__) || defined(__s390x__)
-# undef STRICT_ALIGNMENT
-#endif
-
/* The input and output encrypted as though 128bit cfb mode is being
* used. The extra state information to record how much of the
* 128bit block we have used is contained in *num;
diff --git a/deps/openssl/openssl/crypto/modes/ctr128.c b/deps/openssl/openssl/crypto/modes/ctr128.c
index 932037f55..ee642c586 100644
--- a/deps/openssl/openssl/crypto/modes/ctr128.c
+++ b/deps/openssl/openssl/crypto/modes/ctr128.c
@@ -48,7 +48,8 @@
*
*/
-#include "modes.h"
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
#include <string.h>
#ifndef MODES_DEBUG
@@ -58,17 +59,6 @@
#endif
#include <assert.h>
-typedef unsigned int u32;
-typedef unsigned char u8;
-
-#define STRICT_ALIGNMENT
-#if defined(__i386) || defined(__i386__) || \
- defined(__x86_64) || defined(__x86_64__) || \
- defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
- defined(__s390__) || defined(__s390x__)
-# undef STRICT_ALIGNMENT
-#endif
-
/* NOTE: the IV/counter CTR mode is big-endian. The code itself
* is endian-neutral. */
@@ -182,3 +172,81 @@ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
*num=n;
}
+
+/* increment upper 96 bits of 128-bit counter by 1 */
+static void ctr96_inc(unsigned char *counter) {
+ u32 n=12;
+ u8 c;
+
+ do {
+ --n;
+ c = counter[n];
+ ++c;
+ counter[n] = c;
+ if (c) return;
+ } while (n);
+}
+
+void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], unsigned char ecount_buf[16],
+ unsigned int *num, ctr128_f func)
+{
+ unsigned int n,ctr32;
+
+ assert(in && out && key && ecount_buf && num);
+ assert(*num < 16);
+
+ n = *num;
+
+ while (n && len) {
+ *(out++) = *(in++) ^ ecount_buf[n];
+ --len;
+ n = (n+1) % 16;
+ }
+
+ ctr32 = GETU32(ivec+12);
+ while (len>=16) {
+ size_t blocks = len/16;
+ /*
+ * 1<<28 is just a not-so-small yet not-so-large number...
+ * Below condition is practically never met, but it has to
+ * be checked for code correctness.
+ */
+ if (sizeof(size_t)>sizeof(unsigned int) && blocks>(1U<<28))
+ blocks = (1U<<28);
+ /*
+ * As (*func) operates on 32-bit counter, caller
+ * has to handle overflow. 'if' below detects the
+ * overflow, which is then handled by limiting the
+ * amount of blocks to the exact overflow point...
+ */
+ ctr32 += (u32)blocks;
+ if (ctr32 < blocks) {
+ blocks -= ctr32;
+ ctr32 = 0;
+ }
+ (*func)(in,out,blocks,key,ivec);
+ /* (*ctr) does not update ivec, caller does: */
+ PUTU32(ivec+12,ctr32);
+ /* ... overflow was detected, propogate carry. */
+ if (ctr32 == 0) ctr96_inc(ivec);
+ blocks *= 16;
+ len -= blocks;
+ out += blocks;
+ in += blocks;
+ }
+ if (len) {
+ memset(ecount_buf,0,16);
+ (*func)(ecount_buf,ecount_buf,1,key,ivec);
+ ++ctr32;
+ PUTU32(ivec+12,ctr32);
+ if (ctr32 == 0) ctr96_inc(ivec);
+ while (len--) {
+ out[n] = in[n] ^ ecount_buf[n];
+ ++n;
+ }
+ }
+
+ *num=n;
+}
diff --git a/deps/openssl/openssl/crypto/modes/cts128.c b/deps/openssl/openssl/crypto/modes/cts128.c
index e0430f9fd..c0e1f3696 100644
--- a/deps/openssl/openssl/crypto/modes/cts128.c
+++ b/deps/openssl/openssl/crypto/modes/cts128.c
@@ -5,7 +5,8 @@
* forms are granted according to the OpenSSL license.
*/
-#include "modes.h"
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
#include <string.h>
#ifndef MODES_DEBUG
@@ -23,8 +24,9 @@
* deviates from mentioned RFCs. Most notably it allows input to be
* of block length and it doesn't flip the order of the last two
* blocks. CTS is being discussed even in ECB context, but it's not
- * adopted for any known application. This implementation complies
- * with mentioned RFCs and [as such] extends CBC mode.
+ * adopted for any known application. This implementation provides
+ * two interfaces: one compliant with above mentioned RFCs and one
+ * compliant with the NIST proposal, both extending CBC mode.
*/
size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
@@ -54,6 +56,34 @@ size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
return len+residue;
}
+size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], block128_f block)
+{ size_t residue, n;
+
+ assert (in && out && key && ivec);
+
+ if (len < 16) return 0;
+
+ residue=len%16;
+
+ len -= residue;
+
+ CRYPTO_cbc128_encrypt(in,out,len,key,ivec,block);
+
+ if (residue==0) return len;
+
+ in += len;
+ out += len;
+
+ for (n=0; n<residue; ++n)
+ ivec[n] ^= in[n];
+ (*block)(ivec,ivec,key);
+ memcpy(out-16+residue,ivec,16);
+
+ return len+residue;
+}
+
size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const void *key,
unsigned char ivec[16], cbc128_f cbc)
@@ -90,6 +120,41 @@ size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
return len+residue;
}
+size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], cbc128_f cbc)
+{ size_t residue;
+ union { size_t align; unsigned char c[16]; } tmp;
+
+ assert (in && out && key && ivec);
+
+ if (len < 16) return 0;
+
+ residue=len%16;
+
+ len -= residue;
+
+ (*cbc)(in,out,len,key,ivec,1);
+
+ if (residue==0) return len;
+
+ in += len;
+ out += len;
+
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+ (*cbc)(in,out-16+residue,residue,key,ivec,1);
+#else
+ {
+ size_t n;
+ for (n=0; n<16; n+=sizeof(size_t))
+ *(size_t *)(tmp.c+n) = 0;
+ memcpy(tmp.c,in,residue);
+ }
+ (*cbc)(tmp.c,out-16+residue,16,key,ivec,1);
+#endif
+ return len+residue;
+}
+
size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
size_t len, const void *key,
unsigned char ivec[16], block128_f block)
@@ -125,7 +190,51 @@ size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
for(residue+=16; n<residue; ++n)
out[n] = tmp.c[n] ^ in[n];
- return len+residue-16;
+ return 16+len+residue;
+}
+
+size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], block128_f block)
+{ size_t residue, n;
+ union { size_t align; unsigned char c[32]; } tmp;
+
+ assert (in && out && key && ivec);
+
+ if (len<16) return 0;
+
+ residue=len%16;
+
+ if (residue==0) {
+ CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block);
+ return len;
+ }
+
+ len -= 16+residue;
+
+ if (len) {
+ CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block);
+ in += len;
+ out += len;
+ }
+
+ (*block)(in+residue,tmp.c+16,key);
+
+ for (n=0; n<16; n+=sizeof(size_t))
+ *(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
+ memcpy(tmp.c,in,residue);
+ (*block)(tmp.c,tmp.c,key);
+
+ for(n=0; n<16; ++n) {
+ unsigned char c = in[n];
+ out[n] = tmp.c[n] ^ ivec[n];
+ ivec[n] = in[n+residue];
+ tmp.c[n] = c;
+ }
+ for(residue+=16; n<residue; ++n)
+ out[n] = tmp.c[n] ^ tmp.c[n-16];
+
+ return 16+len+residue;
}
size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
@@ -160,7 +269,47 @@ size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
(*cbc)(tmp.c,tmp.c,32,key,ivec,0);
memcpy(out,tmp.c,16+residue);
#endif
- return len+residue;
+ return 16+len+residue;
+}
+
+size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], cbc128_f cbc)
+{ size_t residue, n;
+ union { size_t align; unsigned char c[32]; } tmp;
+
+ assert (in && out && key && ivec);
+
+ if (len<16) return 0;
+
+ residue=len%16;
+
+ if (residue==0) {
+ (*cbc)(in,out,len,key,ivec,0);
+ return len;
+ }
+
+ len -= 16+residue;
+
+ if (len) {
+ (*cbc)(in,out,len,key,ivec,0);
+ in += len;
+ out += len;
+ }
+
+ for (n=16; n<32; n+=sizeof(size_t))
+ *(size_t *)(tmp.c+n) = 0;
+ /* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
+ (*cbc)(in+residue,tmp.c,16,key,tmp.c+16,0);
+
+ memcpy(tmp.c,in,residue);
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+ (*cbc)(tmp.c,out,16+residue,key,ivec,0);
+#else
+ (*cbc)(tmp.c,tmp.c,32,key,ivec,0);
+ memcpy(out,tmp.c,16+residue);
+#endif
+ return 16+len+residue;
}
#if defined(SELFTEST)
@@ -200,9 +349,8 @@ static const unsigned char vector_64[64] =
static AES_KEY encks, decks;
void test_vector(const unsigned char *vector,size_t len)
-{ unsigned char cleartext[64];
- unsigned char iv[sizeof(test_iv)];
- unsigned char ciphertext[64];
+{ unsigned char iv[sizeof(test_iv)];
+ unsigned char cleartext[64],ciphertext[64];
size_t tail;
printf("vector_%d\n",len); fflush(stdout);
@@ -243,7 +391,57 @@ void test_vector(const unsigned char *vector,size_t len)
fprintf(stderr,"iv_%d mismatch\n",len), exit(4);
}
-main()
+void test_nistvector(const unsigned char *vector,size_t len)
+{ unsigned char iv[sizeof(test_iv)];
+ unsigned char cleartext[64],ciphertext[64],nistvector[64];
+ size_t tail;
+
+ printf("nistvector_%d\n",len); fflush(stdout);
+
+ if ((tail=len%16) == 0) tail = 16;
+
+ len -= 16 + tail;
+ memcpy(nistvector,vector,len);
+ /* flip two last blocks */
+ memcpy(nistvector+len,vector+len+16,tail);
+ memcpy(nistvector+len+tail,vector+len,16);
+ len += 16 + tail;
+ tail = 16;
+
+ /* test block-based encryption */
+ memcpy(iv,test_iv,sizeof(test_iv));
+ CRYPTO_nistcts128_encrypt_block(test_input,ciphertext,len,&encks,iv,(block128_f)AES_encrypt);
+ if (memcmp(ciphertext,nistvector,len))
+ fprintf(stderr,"output_%d mismatch\n",len), exit(1);
+ if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
+ fprintf(stderr,"iv_%d mismatch\n",len), exit(1);
+
+ /* test block-based decryption */
+ memcpy(iv,test_iv,sizeof(test_iv));
+ CRYPTO_nistcts128_decrypt_block(ciphertext,cleartext,len,&decks,iv,(block128_f)AES_decrypt);
+ if (memcmp(cleartext,test_input,len))
+ fprintf(stderr,"input_%d mismatch\n",len), exit(2);
+ if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
+ fprintf(stderr,"iv_%d mismatch\n",len), exit(2);
+
+ /* test streamed encryption */
+ memcpy(iv,test_iv,sizeof(test_iv));
+ CRYPTO_nistcts128_encrypt(test_input,ciphertext,len,&encks,iv,(cbc128_f)AES_cbc_encrypt);
+ if (memcmp(ciphertext,nistvector,len))
+ fprintf(stderr,"output_%d mismatch\n",len), exit(3);
+ if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
+ fprintf(stderr,"iv_%d mismatch\n",len), exit(3);
+
+ /* test streamed decryption */
+ memcpy(iv,test_iv,sizeof(test_iv));
+ CRYPTO_nistcts128_decrypt(ciphertext,cleartext,len,&decks,iv,(cbc128_f)AES_cbc_encrypt);
+ if (memcmp(cleartext,test_input,len))
+ fprintf(stderr,"input_%d mismatch\n",len), exit(4);
+ if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
+ fprintf(stderr,"iv_%d mismatch\n",len), exit(4);
+}
+
+int main()
{
AES_set_encrypt_key(test_key,128,&encks);
AES_set_decrypt_key(test_key,128,&decks);
@@ -254,6 +452,14 @@ main()
test_vector(vector_47,sizeof(vector_47));
test_vector(vector_48,sizeof(vector_48));
test_vector(vector_64,sizeof(vector_64));
- exit(0);
+
+ test_nistvector(vector_17,sizeof(vector_17));
+ test_nistvector(vector_31,sizeof(vector_31));
+ test_nistvector(vector_32,sizeof(vector_32));
+ test_nistvector(vector_47,sizeof(vector_47));
+ test_nistvector(vector_48,sizeof(vector_48));
+ test_nistvector(vector_64,sizeof(vector_64));
+
+ return 0;
}
#endif
diff --git a/deps/openssl/openssl/crypto/modes/gcm128.c b/deps/openssl/openssl/crypto/modes/gcm128.c
new file mode 100644
index 000000000..0e6ff8b0a
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/gcm128.c
@@ -0,0 +1,1757 @@
+/* ====================================================================
+ * Copyright (c) 2010 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.
+ * ====================================================================
+ */
+
+#define OPENSSL_FIPSAPI
+
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#if defined(BSWAP4) && defined(STRICT_ALIGNMENT)
+/* redefine, because alignment is ensured */
+#undef GETU32
+#define GETU32(p) BSWAP4(*(const u32 *)(p))
+#undef PUTU32
+#define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v)
+#endif
+
+#define PACK(s) ((size_t)(s)<<(sizeof(size_t)*8-16))
+#define REDUCE1BIT(V) do { \
+ if (sizeof(size_t)==8) { \
+ u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \
+ V.lo = (V.hi<<63)|(V.lo>>1); \
+ V.hi = (V.hi>>1 )^T; \
+ } \
+ else { \
+ u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \
+ V.lo = (V.hi<<63)|(V.lo>>1); \
+ V.hi = (V.hi>>1 )^((u64)T<<32); \
+ } \
+} while(0)
+
+/*
+ * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
+ * never be set to 8. 8 is effectively reserved for testing purposes.
+ * TABLE_BITS>1 are lookup-table-driven implementations referred to as
+ * "Shoup's" in GCM specification. In other words OpenSSL does not cover
+ * whole spectrum of possible table driven implementations. Why? In
+ * non-"Shoup's" case memory access pattern is segmented in such manner,
+ * that it's trivial to see that cache timing information can reveal
+ * fair portion of intermediate hash value. Given that ciphertext is
+ * always available to attacker, it's possible for him to attempt to
+ * deduce secret parameter H and if successful, tamper with messages
+ * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's
+ * not as trivial, but there is no reason to believe that it's resistant
+ * to cache-timing attack. And the thing about "8-bit" implementation is
+ * that it consumes 16 (sixteen) times more memory, 4KB per individual
+ * key + 1KB shared. Well, on pros side it should be twice as fast as
+ * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version
+ * was observed to run ~75% faster, closer to 100% for commercial
+ * compilers... Yet "4-bit" procedure is preferred, because it's
+ * believed to provide better security-performance balance and adequate
+ * all-round performance. "All-round" refers to things like:
+ *
+ * - shorter setup time effectively improves overall timing for
+ * handling short messages;
+ * - larger table allocation can become unbearable because of VM
+ * subsystem penalties (for example on Windows large enough free
+ * results in VM working set trimming, meaning that consequent
+ * malloc would immediately incur working set expansion);
+ * - larger table has larger cache footprint, which can affect
+ * performance of other code paths (not necessarily even from same
+ * thread in Hyper-Threading world);
+ *
+ * Value of 1 is not appropriate for performance reasons.
+ */
+#if TABLE_BITS==8
+
+static void gcm_init_8bit(u128 Htable[256], u64 H[2])
+{
+ int i, j;
+ u128 V;
+
+ Htable[0].hi = 0;
+ Htable[0].lo = 0;
+ V.hi = H[0];
+ V.lo = H[1];
+
+ for (Htable[128]=V, i=64; i>0; i>>=1) {
+ REDUCE1BIT(V);
+ Htable[i] = V;
+ }
+
+ for (i=2; i<256; i<<=1) {
+ u128 *Hi = Htable+i, H0 = *Hi;
+ for (j=1; j<i; ++j) {
+ Hi[j].hi = H0.hi^Htable[j].hi;
+ Hi[j].lo = H0.lo^Htable[j].lo;
+ }
+ }
+}
+
+static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256])
+{
+ u128 Z = { 0, 0};
+ const u8 *xi = (const u8 *)Xi+15;
+ size_t rem, n = *xi;
+ const union { long one; char little; } is_endian = {1};
+ static const size_t rem_8bit[256] = {
+ PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246),
+ PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E),
+ PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56),
+ PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E),
+ PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66),
+ PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E),
+ PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076),
+ PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E),
+ PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06),
+ PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E),
+ PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416),
+ PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E),
+ PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626),
+ PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E),
+ PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836),
+ PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E),
+ PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6),
+ PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE),
+ PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6),
+ PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE),
+ PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6),
+ PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE),
+ PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6),
+ PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE),
+ PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86),
+ PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E),
+ PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496),
+ PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E),
+ PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6),
+ PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE),
+ PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6),
+ PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE),
+ PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346),
+ PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E),
+ PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56),
+ PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E),
+ PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66),
+ PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E),
+ PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176),
+ PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E),
+ PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06),
+ PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E),
+ PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516),
+ PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E),
+ PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726),
+ PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E),
+ PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936),
+ PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E),
+ PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6),
+ PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE),
+ PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6),
+ PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE),
+ PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6),
+ PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE),
+ PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6),
+ PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE),
+ PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86),
+ PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E),
+ PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596),
+ PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E),
+ PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6),
+ PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE),
+ PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6),
+ PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE) };
+
+ while (1) {
+ Z.hi ^= Htable[n].hi;
+ Z.lo ^= Htable[n].lo;
+
+ if ((u8 *)Xi==xi) break;
+
+ n = *(--xi);
+
+ rem = (size_t)Z.lo&0xff;
+ Z.lo = (Z.hi<<56)|(Z.lo>>8);
+ Z.hi = (Z.hi>>8);
+ if (sizeof(size_t)==8)
+ Z.hi ^= rem_8bit[rem];
+ else
+ Z.hi ^= (u64)rem_8bit[rem]<<32;
+ }
+
+ if (is_endian.little) {
+#ifdef BSWAP8
+ Xi[0] = BSWAP8(Z.hi);
+ Xi[1] = BSWAP8(Z.lo);
+#else
+ u8 *p = (u8 *)Xi;
+ u32 v;
+ v = (u32)(Z.hi>>32); PUTU32(p,v);
+ v = (u32)(Z.hi); PUTU32(p+4,v);
+ v = (u32)(Z.lo>>32); PUTU32(p+8,v);
+ v = (u32)(Z.lo); PUTU32(p+12,v);
+#endif
+ }
+ else {
+ Xi[0] = Z.hi;
+ Xi[1] = Z.lo;
+ }
+}
+#define GCM_MUL(ctx,Xi) gcm_gmult_8bit(ctx->Xi.u,ctx->Htable)
+
+#elif TABLE_BITS==4
+
+static void gcm_init_4bit(u128 Htable[16], u64 H[2])
+{
+ u128 V;
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+ int i;
+#endif
+
+ Htable[0].hi = 0;
+ Htable[0].lo = 0;
+ V.hi = H[0];
+ V.lo = H[1];
+
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+ for (Htable[8]=V, i=4; i>0; i>>=1) {
+ REDUCE1BIT(V);
+ Htable[i] = V;
+ }
+
+ for (i=2; i<16; i<<=1) {
+ u128 *Hi = Htable+i;
+ int j;
+ for (V=*Hi, j=1; j<i; ++j) {
+ Hi[j].hi = V.hi^Htable[j].hi;
+ Hi[j].lo = V.lo^Htable[j].lo;
+ }
+ }
+#else
+ Htable[8] = V;
+ REDUCE1BIT(V);
+ Htable[4] = V;
+ REDUCE1BIT(V);
+ Htable[2] = V;
+ REDUCE1BIT(V);
+ Htable[1] = V;
+ Htable[3].hi = V.hi^Htable[2].hi, Htable[3].lo = V.lo^Htable[2].lo;
+ V=Htable[4];
+ Htable[5].hi = V.hi^Htable[1].hi, Htable[5].lo = V.lo^Htable[1].lo;
+ Htable[6].hi = V.hi^Htable[2].hi, Htable[6].lo = V.lo^Htable[2].lo;
+ Htable[7].hi = V.hi^Htable[3].hi, Htable[7].lo = V.lo^Htable[3].lo;
+ V=Htable[8];
+ Htable[9].hi = V.hi^Htable[1].hi, Htable[9].lo = V.lo^Htable[1].lo;
+ Htable[10].hi = V.hi^Htable[2].hi, Htable[10].lo = V.lo^Htable[2].lo;
+ Htable[11].hi = V.hi^Htable[3].hi, Htable[11].lo = V.lo^Htable[3].lo;
+ Htable[12].hi = V.hi^Htable[4].hi, Htable[12].lo = V.lo^Htable[4].lo;
+ Htable[13].hi = V.hi^Htable[5].hi, Htable[13].lo = V.lo^Htable[5].lo;
+ Htable[14].hi = V.hi^Htable[6].hi, Htable[14].lo = V.lo^Htable[6].lo;
+ Htable[15].hi = V.hi^Htable[7].hi, Htable[15].lo = V.lo^Htable[7].lo;
+#endif
+#if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm))
+ /*
+ * ARM assembler expects specific dword order in Htable.
+ */
+ {
+ int j;
+ const union { long one; char little; } is_endian = {1};
+
+ if (is_endian.little)
+ for (j=0;j<16;++j) {
+ V = Htable[j];
+ Htable[j].hi = V.lo;
+ Htable[j].lo = V.hi;
+ }
+ else
+ for (j=0;j<16;++j) {
+ V = Htable[j];
+ Htable[j].hi = V.lo<<32|V.lo>>32;
+ Htable[j].lo = V.hi<<32|V.hi>>32;
+ }
+ }
+#endif
+}
+
+#ifndef GHASH_ASM
+static const size_t rem_4bit[16] = {
+ PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460),
+ PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0),
+ PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560),
+ PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0) };
+
+static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16])
+{
+ u128 Z;
+ int cnt = 15;
+ size_t rem, nlo, nhi;
+ const union { long one; char little; } is_endian = {1};
+
+ nlo = ((const u8 *)Xi)[15];
+ nhi = nlo>>4;
+ nlo &= 0xf;
+
+ Z.hi = Htable[nlo].hi;
+ Z.lo = Htable[nlo].lo;
+
+ while (1) {
+ rem = (size_t)Z.lo&0xf;
+ Z.lo = (Z.hi<<60)|(Z.lo>>4);
+ Z.hi = (Z.hi>>4);
+ if (sizeof(size_t)==8)
+ Z.hi ^= rem_4bit[rem];
+ else
+ Z.hi ^= (u64)rem_4bit[rem]<<32;
+
+ Z.hi ^= Htable[nhi].hi;
+ Z.lo ^= Htable[nhi].lo;
+
+ if (--cnt<0) break;
+
+ nlo = ((const u8 *)Xi)[cnt];
+ nhi = nlo>>4;
+ nlo &= 0xf;
+
+ rem = (size_t)Z.lo&0xf;
+ Z.lo = (Z.hi<<60)|(Z.lo>>4);
+ Z.hi = (Z.hi>>4);
+ if (sizeof(size_t)==8)
+ Z.hi ^= rem_4bit[rem];
+ else
+ Z.hi ^= (u64)rem_4bit[rem]<<32;
+
+ Z.hi ^= Htable[nlo].hi;
+ Z.lo ^= Htable[nlo].lo;
+ }
+
+ if (is_endian.little) {
+#ifdef BSWAP8
+ Xi[0] = BSWAP8(Z.hi);
+ Xi[1] = BSWAP8(Z.lo);
+#else
+ u8 *p = (u8 *)Xi;
+ u32 v;
+ v = (u32)(Z.hi>>32); PUTU32(p,v);
+ v = (u32)(Z.hi); PUTU32(p+4,v);
+ v = (u32)(Z.lo>>32); PUTU32(p+8,v);
+ v = (u32)(Z.lo); PUTU32(p+12,v);
+#endif
+ }
+ else {
+ Xi[0] = Z.hi;
+ Xi[1] = Z.lo;
+ }
+}
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+/*
+ * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for
+ * details... Compiler-generated code doesn't seem to give any
+ * performance improvement, at least not on x86[_64]. It's here
+ * mostly as reference and a placeholder for possible future
+ * non-trivial optimization[s]...
+ */
+static void gcm_ghash_4bit(u64 Xi[2],const u128 Htable[16],
+ const u8 *inp,size_t len)
+{
+ u128 Z;
+ int cnt;
+ size_t rem, nlo, nhi;
+ const union { long one; char little; } is_endian = {1};
+
+#if 1
+ do {
+ cnt = 15;
+ nlo = ((const u8 *)Xi)[15];
+ nlo ^= inp[15];
+ nhi = nlo>>4;
+ nlo &= 0xf;
+
+ Z.hi = Htable[nlo].hi;
+ Z.lo = Htable[nlo].lo;
+
+ while (1) {
+ rem = (size_t)Z.lo&0xf;
+ Z.lo = (Z.hi<<60)|(Z.lo>>4);
+ Z.hi = (Z.hi>>4);
+ if (sizeof(size_t)==8)
+ Z.hi ^= rem_4bit[rem];
+ else
+ Z.hi ^= (u64)rem_4bit[rem]<<32;
+
+ Z.hi ^= Htable[nhi].hi;
+ Z.lo ^= Htable[nhi].lo;
+
+ if (--cnt<0) break;
+
+ nlo = ((const u8 *)Xi)[cnt];
+ nlo ^= inp[cnt];
+ nhi = nlo>>4;
+ nlo &= 0xf;
+
+ rem = (size_t)Z.lo&0xf;
+ Z.lo = (Z.hi<<60)|(Z.lo>>4);
+ Z.hi = (Z.hi>>4);
+ if (sizeof(size_t)==8)
+ Z.hi ^= rem_4bit[rem];
+ else
+ Z.hi ^= (u64)rem_4bit[rem]<<32;
+
+ Z.hi ^= Htable[nlo].hi;
+ Z.lo ^= Htable[nlo].lo;
+ }
+#else
+ /*
+ * Extra 256+16 bytes per-key plus 512 bytes shared tables
+ * [should] give ~50% improvement... One could have PACK()-ed
+ * the rem_8bit even here, but the priority is to minimize
+ * cache footprint...
+ */
+ u128 Hshr4[16]; /* Htable shifted right by 4 bits */
+ u8 Hshl4[16]; /* Htable shifted left by 4 bits */
+ static const unsigned short rem_8bit[256] = {
+ 0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E,
+ 0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E,
+ 0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E,
+ 0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E,
+ 0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E,
+ 0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E,
+ 0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E,
+ 0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E,
+ 0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE,
+ 0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE,
+ 0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE,
+ 0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE,
+ 0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E,
+ 0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E,
+ 0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE,
+ 0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE,
+ 0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E,
+ 0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E,
+ 0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E,
+ 0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E,
+ 0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E,
+ 0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E,
+ 0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E,
+ 0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E,
+ 0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE,
+ 0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE,
+ 0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE,
+ 0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE,
+ 0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E,
+ 0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E,
+ 0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE,
+ 0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE };
+ /*
+ * This pre-processing phase slows down procedure by approximately
+ * same time as it makes each loop spin faster. In other words
+ * single block performance is approximately same as straightforward
+ * "4-bit" implementation, and then it goes only faster...
+ */
+ for (cnt=0; cnt<16; ++cnt) {
+ Z.hi = Htable[cnt].hi;
+ Z.lo = Htable[cnt].lo;
+ Hshr4[cnt].lo = (Z.hi<<60)|(Z.lo>>4);
+ Hshr4[cnt].hi = (Z.hi>>4);
+ Hshl4[cnt] = (u8)(Z.lo<<4);
+ }
+
+ do {
+ for (Z.lo=0, Z.hi=0, cnt=15; cnt; --cnt) {
+ nlo = ((const u8 *)Xi)[cnt];
+ nlo ^= inp[cnt];
+ nhi = nlo>>4;
+ nlo &= 0xf;
+
+ Z.hi ^= Htable[nlo].hi;
+ Z.lo ^= Htable[nlo].lo;
+
+ rem = (size_t)Z.lo&0xff;
+
+ Z.lo = (Z.hi<<56)|(Z.lo>>8);
+ Z.hi = (Z.hi>>8);
+
+ Z.hi ^= Hshr4[nhi].hi;
+ Z.lo ^= Hshr4[nhi].lo;
+ Z.hi ^= (u64)rem_8bit[rem^Hshl4[nhi]]<<48;
+ }
+
+ nlo = ((const u8 *)Xi)[0];
+ nlo ^= inp[0];
+ nhi = nlo>>4;
+ nlo &= 0xf;
+
+ Z.hi ^= Htable[nlo].hi;
+ Z.lo ^= Htable[nlo].lo;
+
+ rem = (size_t)Z.lo&0xf;
+
+ Z.lo = (Z.hi<<60)|(Z.lo>>4);
+ Z.hi = (Z.hi>>4);
+
+ Z.hi ^= Htable[nhi].hi;
+ Z.lo ^= Htable[nhi].lo;
+ Z.hi ^= ((u64)rem_8bit[rem<<4])<<48;
+#endif
+
+ if (is_endian.little) {
+#ifdef BSWAP8
+ Xi[0] = BSWAP8(Z.hi);
+ Xi[1] = BSWAP8(Z.lo);
+#else
+ u8 *p = (u8 *)Xi;
+ u32 v;
+ v = (u32)(Z.hi>>32); PUTU32(p,v);
+ v = (u32)(Z.hi); PUTU32(p+4,v);
+ v = (u32)(Z.lo>>32); PUTU32(p+8,v);
+ v = (u32)(Z.lo); PUTU32(p+12,v);
+#endif
+ }
+ else {
+ Xi[0] = Z.hi;
+ Xi[1] = Z.lo;
+ }
+ } while (inp+=16, len-=16);
+}
+#endif
+#else
+void gcm_gmult_4bit(u64 Xi[2],const u128 Htable[16]);
+void gcm_ghash_4bit(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+#endif
+
+#define GCM_MUL(ctx,Xi) gcm_gmult_4bit(ctx->Xi.u,ctx->Htable)
+#if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT)
+#define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len)
+/* GHASH_CHUNK is "stride parameter" missioned to mitigate cache
+ * trashing effect. In other words idea is to hash data while it's
+ * still in L1 cache after encryption pass... */
+#define GHASH_CHUNK (3*1024)
+#endif
+
+#else /* TABLE_BITS */
+
+static void gcm_gmult_1bit(u64 Xi[2],const u64 H[2])
+{
+ u128 V,Z = { 0,0 };
+ long X;
+ int i,j;
+ const long *xi = (const long *)Xi;
+ const union { long one; char little; } is_endian = {1};
+
+ V.hi = H[0]; /* H is in host byte order, no byte swapping */
+ V.lo = H[1];
+
+ for (j=0; j<16/sizeof(long); ++j) {
+ if (is_endian.little) {
+ if (sizeof(long)==8) {
+#ifdef BSWAP8
+ X = (long)(BSWAP8(xi[j]));
+#else
+ const u8 *p = (const u8 *)(xi+j);
+ X = (long)((u64)GETU32(p)<<32|GETU32(p+4));
+#endif
+ }
+ else {
+ const u8 *p = (const u8 *)(xi+j);
+ X = (long)GETU32(p);
+ }
+ }
+ else
+ X = xi[j];
+
+ for (i=0; i<8*sizeof(long); ++i, X<<=1) {
+ u64 M = (u64)(X>>(8*sizeof(long)-1));
+ Z.hi ^= V.hi&M;
+ Z.lo ^= V.lo&M;
+
+ REDUCE1BIT(V);
+ }
+ }
+
+ if (is_endian.little) {
+#ifdef BSWAP8
+ Xi[0] = BSWAP8(Z.hi);
+ Xi[1] = BSWAP8(Z.lo);
+#else
+ u8 *p = (u8 *)Xi;
+ u32 v;
+ v = (u32)(Z.hi>>32); PUTU32(p,v);
+ v = (u32)(Z.hi); PUTU32(p+4,v);
+ v = (u32)(Z.lo>>32); PUTU32(p+8,v);
+ v = (u32)(Z.lo); PUTU32(p+12,v);
+#endif
+ }
+ else {
+ Xi[0] = Z.hi;
+ Xi[1] = Z.lo;
+ }
+}
+#define GCM_MUL(ctx,Xi) gcm_gmult_1bit(ctx->Xi.u,ctx->H.u)
+
+#endif
+
+#if TABLE_BITS==4 && defined(GHASH_ASM)
+# if !defined(I386_ONLY) && \
+ (defined(__i386) || defined(__i386__) || \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
+# define GHASH_ASM_X86_OR_64
+# define GCM_FUNCREF_4BIT
+extern unsigned int OPENSSL_ia32cap_P[2];
+
+void gcm_init_clmul(u128 Htable[16],const u64 Xi[2]);
+void gcm_gmult_clmul(u64 Xi[2],const u128 Htable[16]);
+void gcm_ghash_clmul(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+# define GHASH_ASM_X86
+void gcm_gmult_4bit_mmx(u64 Xi[2],const u128 Htable[16]);
+void gcm_ghash_4bit_mmx(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+
+void gcm_gmult_4bit_x86(u64 Xi[2],const u128 Htable[16]);
+void gcm_ghash_4bit_x86(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+# endif
+# elif defined(__arm__) || defined(__arm)
+# include "arm_arch.h"
+# if __ARM_ARCH__>=7
+# define GHASH_ASM_ARM
+# define GCM_FUNCREF_4BIT
+void gcm_gmult_neon(u64 Xi[2],const u128 Htable[16]);
+void gcm_ghash_neon(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+# endif
+# endif
+#endif
+
+#ifdef GCM_FUNCREF_4BIT
+# undef GCM_MUL
+# define GCM_MUL(ctx,Xi) (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable)
+# ifdef GHASH
+# undef GHASH
+# define GHASH(ctx,in,len) (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len)
+# endif
+#endif
+
+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block)
+{
+ const union { long one; char little; } is_endian = {1};
+
+ memset(ctx,0,sizeof(*ctx));
+ ctx->block = block;
+ ctx->key = key;
+
+ (*block)(ctx->H.c,ctx->H.c,key);
+
+ if (is_endian.little) {
+ /* H is stored in host byte order */
+#ifdef BSWAP8
+ ctx->H.u[0] = BSWAP8(ctx->H.u[0]);
+ ctx->H.u[1] = BSWAP8(ctx->H.u[1]);
+#else
+ u8 *p = ctx->H.c;
+ u64 hi,lo;
+ hi = (u64)GETU32(p) <<32|GETU32(p+4);
+ lo = (u64)GETU32(p+8)<<32|GETU32(p+12);
+ ctx->H.u[0] = hi;
+ ctx->H.u[1] = lo;
+#endif
+ }
+
+#if TABLE_BITS==8
+ gcm_init_8bit(ctx->Htable,ctx->H.u);
+#elif TABLE_BITS==4
+# if defined(GHASH_ASM_X86_OR_64)
+# if !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2)
+ if (OPENSSL_ia32cap_P[0]&(1<<24) && /* check FXSR bit */
+ OPENSSL_ia32cap_P[1]&(1<<1) ) { /* check PCLMULQDQ bit */
+ gcm_init_clmul(ctx->Htable,ctx->H.u);
+ ctx->gmult = gcm_gmult_clmul;
+ ctx->ghash = gcm_ghash_clmul;
+ return;
+ }
+# endif
+ gcm_init_4bit(ctx->Htable,ctx->H.u);
+# if defined(GHASH_ASM_X86) /* x86 only */
+# if defined(OPENSSL_IA32_SSE2)
+ if (OPENSSL_ia32cap_P[0]&(1<<25)) { /* check SSE bit */
+# else
+ if (OPENSSL_ia32cap_P[0]&(1<<23)) { /* check MMX bit */
+# endif
+ ctx->gmult = gcm_gmult_4bit_mmx;
+ ctx->ghash = gcm_ghash_4bit_mmx;
+ } else {
+ ctx->gmult = gcm_gmult_4bit_x86;
+ ctx->ghash = gcm_ghash_4bit_x86;
+ }
+# else
+ ctx->gmult = gcm_gmult_4bit;
+ ctx->ghash = gcm_ghash_4bit;
+# endif
+# elif defined(GHASH_ASM_ARM)
+ if (OPENSSL_armcap_P & ARMV7_NEON) {
+ ctx->gmult = gcm_gmult_neon;
+ ctx->ghash = gcm_ghash_neon;
+ } else {
+ gcm_init_4bit(ctx->Htable,ctx->H.u);
+ ctx->gmult = gcm_gmult_4bit;
+ ctx->ghash = gcm_ghash_4bit;
+ }
+# else
+ gcm_init_4bit(ctx->Htable,ctx->H.u);
+# endif
+#endif
+}
+
+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx,const unsigned char *iv,size_t len)
+{
+ const union { long one; char little; } is_endian = {1};
+ unsigned int ctr;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16]) = ctx->gmult;
+#endif
+
+ ctx->Yi.u[0] = 0;
+ ctx->Yi.u[1] = 0;
+ ctx->Xi.u[0] = 0;
+ ctx->Xi.u[1] = 0;
+ ctx->len.u[0] = 0; /* AAD length */
+ ctx->len.u[1] = 0; /* message length */
+ ctx->ares = 0;
+ ctx->mres = 0;
+
+ if (len==12) {
+ memcpy(ctx->Yi.c,iv,12);
+ ctx->Yi.c[15]=1;
+ ctr=1;
+ }
+ else {
+ size_t i;
+ u64 len0 = len;
+
+ while (len>=16) {
+ for (i=0; i<16; ++i) ctx->Yi.c[i] ^= iv[i];
+ GCM_MUL(ctx,Yi);
+ iv += 16;
+ len -= 16;
+ }
+ if (len) {
+ for (i=0; i<len; ++i) ctx->Yi.c[i] ^= iv[i];
+ GCM_MUL(ctx,Yi);
+ }
+ len0 <<= 3;
+ if (is_endian.little) {
+#ifdef BSWAP8
+ ctx->Yi.u[1] ^= BSWAP8(len0);
+#else
+ ctx->Yi.c[8] ^= (u8)(len0>>56);
+ ctx->Yi.c[9] ^= (u8)(len0>>48);
+ ctx->Yi.c[10] ^= (u8)(len0>>40);
+ ctx->Yi.c[11] ^= (u8)(len0>>32);
+ ctx->Yi.c[12] ^= (u8)(len0>>24);
+ ctx->Yi.c[13] ^= (u8)(len0>>16);
+ ctx->Yi.c[14] ^= (u8)(len0>>8);
+ ctx->Yi.c[15] ^= (u8)(len0);
+#endif
+ }
+ else
+ ctx->Yi.u[1] ^= len0;
+
+ GCM_MUL(ctx,Yi);
+
+ if (is_endian.little)
+ ctr = GETU32(ctx->Yi.c+12);
+ else
+ ctr = ctx->Yi.d[3];
+ }
+
+ (*ctx->block)(ctx->Yi.c,ctx->EK0.c,ctx->key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+}
+
+int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx,const unsigned char *aad,size_t len)
+{
+ size_t i;
+ unsigned int n;
+ u64 alen = ctx->len.u[0];
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+ void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+ const u8 *inp,size_t len) = ctx->ghash;
+# endif
+#endif
+
+ if (ctx->len.u[1]) return -2;
+
+ alen += len;
+ if (alen>(U64(1)<<61) || (sizeof(len)==8 && alen<len))
+ return -1;
+ ctx->len.u[0] = alen;
+
+ n = ctx->ares;
+ if (n) {
+ while (n && len) {
+ ctx->Xi.c[n] ^= *(aad++);
+ --len;
+ n = (n+1)%16;
+ }
+ if (n==0) GCM_MUL(ctx,Xi);
+ else {
+ ctx->ares = n;
+ return 0;
+ }
+ }
+
+#ifdef GHASH
+ if ((i = (len&(size_t)-16))) {
+ GHASH(ctx,aad,i);
+ aad += i;
+ len -= i;
+ }
+#else
+ while (len>=16) {
+ for (i=0; i<16; ++i) ctx->Xi.c[i] ^= aad[i];
+ GCM_MUL(ctx,Xi);
+ aad += 16;
+ len -= 16;
+ }
+#endif
+ if (len) {
+ n = (unsigned int)len;
+ for (i=0; i<len; ++i) ctx->Xi.c[i] ^= aad[i];
+ }
+
+ ctx->ares = n;
+ return 0;
+}
+
+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len)
+{
+ const union { long one; char little; } is_endian = {1};
+ unsigned int n, ctr;
+ size_t i;
+ u64 mlen = ctx->len.u[1];
+ block128_f block = ctx->block;
+ void *key = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+ void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+ const u8 *inp,size_t len) = ctx->ghash;
+# endif
+#endif
+
+#if 0
+ n = (unsigned int)mlen%16; /* alternative to ctx->mres */
+#endif
+ mlen += len;
+ if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlen<len))
+ return -1;
+ ctx->len.u[1] = mlen;
+
+ if (ctx->ares) {
+ /* First call to encrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx,Xi);
+ ctx->ares = 0;
+ }
+
+ if (is_endian.little)
+ ctr = GETU32(ctx->Yi.c+12);
+ else
+ ctr = ctx->Yi.d[3];
+
+ n = ctx->mres;
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (16%sizeof(size_t) == 0) do { /* always true actually */
+ if (n) {
+ while (n && len) {
+ ctx->Xi.c[n] ^= *(out++) = *(in++)^ctx->EKi.c[n];
+ --len;
+ n = (n+1)%16;
+ }
+ if (n==0) GCM_MUL(ctx,Xi);
+ else {
+ ctx->mres = n;
+ return 0;
+ }
+ }
+#if defined(STRICT_ALIGNMENT)
+ if (((size_t)in|(size_t)out)%sizeof(size_t) != 0)
+ break;
+#endif
+#if defined(GHASH) && defined(GHASH_CHUNK)
+ while (len>=GHASH_CHUNK) {
+ size_t j=GHASH_CHUNK;
+
+ while (j) {
+ (*block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i=0; i<16; i+=sizeof(size_t))
+ *(size_t *)(out+i) =
+ *(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
+ out += 16;
+ in += 16;
+ j -= 16;
+ }
+ GHASH(ctx,out-GHASH_CHUNK,GHASH_CHUNK);
+ len -= GHASH_CHUNK;
+ }
+ if ((i = (len&(size_t)-16))) {
+ size_t j=i;
+
+ while (len>=16) {
+ (*block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i=0; i<16; i+=sizeof(size_t))
+ *(size_t *)(out+i) =
+ *(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
+ out += 16;
+ in += 16;
+ len -= 16;
+ }
+ GHASH(ctx,out-j,j);
+ }
+#else
+ while (len>=16) {
+ (*block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i=0; i<16; i+=sizeof(size_t))
+ *(size_t *)(ctx->Xi.c+i) ^=
+ *(size_t *)(out+i) =
+ *(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
+ GCM_MUL(ctx,Xi);
+ out += 16;
+ in += 16;
+ len -= 16;
+ }
+#endif
+ if (len) {
+ (*block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ while (len--) {
+ ctx->Xi.c[n] ^= out[n] = in[n]^ctx->EKi.c[n];
+ ++n;
+ }
+ }
+
+ ctx->mres = n;
+ return 0;
+ } while(0);
+#endif
+ for (i=0;i<len;++i) {
+ if (n==0) {
+ (*block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ }
+ ctx->Xi.c[n] ^= out[i] = in[i]^ctx->EKi.c[n];
+ n = (n+1)%16;
+ if (n==0)
+ GCM_MUL(ctx,Xi);
+ }
+
+ ctx->mres = n;
+ return 0;
+}
+
+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len)
+{
+ const union { long one; char little; } is_endian = {1};
+ unsigned int n, ctr;
+ size_t i;
+ u64 mlen = ctx->len.u[1];
+ block128_f block = ctx->block;
+ void *key = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+ void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+ const u8 *inp,size_t len) = ctx->ghash;
+# endif
+#endif
+
+ mlen += len;
+ if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlen<len))
+ return -1;
+ ctx->len.u[1] = mlen;
+
+ if (ctx->ares) {
+ /* First call to decrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx,Xi);
+ ctx->ares = 0;
+ }
+
+ if (is_endian.little)
+ ctr = GETU32(ctx->Yi.c+12);
+ else
+ ctr = ctx->Yi.d[3];
+
+ n = ctx->mres;
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (16%sizeof(size_t) == 0) do { /* always true actually */
+ if (n) {
+ while (n && len) {
+ u8 c = *(in++);
+ *(out++) = c^ctx->EKi.c[n];
+ ctx->Xi.c[n] ^= c;
+ --len;
+ n = (n+1)%16;
+ }
+ if (n==0) GCM_MUL (ctx,Xi);
+ else {
+ ctx->mres = n;
+ return 0;
+ }
+ }
+#if defined(STRICT_ALIGNMENT)
+ if (((size_t)in|(size_t)out)%sizeof(size_t) != 0)
+ break;
+#endif
+#if defined(GHASH) && defined(GHASH_CHUNK)
+ while (len>=GHASH_CHUNK) {
+ size_t j=GHASH_CHUNK;
+
+ GHASH(ctx,in,GHASH_CHUNK);
+ while (j) {
+ (*block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i=0; i<16; i+=sizeof(size_t))
+ *(size_t *)(out+i) =
+ *(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
+ out += 16;
+ in += 16;
+ j -= 16;
+ }
+ len -= GHASH_CHUNK;
+ }
+ if ((i = (len&(size_t)-16))) {
+ GHASH(ctx,in,i);
+ while (len>=16) {
+ (*block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i=0; i<16; i+=sizeof(size_t))
+ *(size_t *)(out+i) =
+ *(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
+ out += 16;
+ in += 16;
+ len -= 16;
+ }
+ }
+#else
+ while (len>=16) {
+ (*block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i=0; i<16; i+=sizeof(size_t)) {
+ size_t c = *(size_t *)(in+i);
+ *(size_t *)(out+i) = c^*(size_t *)(ctx->EKi.c+i);
+ *(size_t *)(ctx->Xi.c+i) ^= c;
+ }
+ GCM_MUL(ctx,Xi);
+ out += 16;
+ in += 16;
+ len -= 16;
+ }
+#endif
+ if (len) {
+ (*block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ while (len--) {
+ u8 c = in[n];
+ ctx->Xi.c[n] ^= c;
+ out[n] = c^ctx->EKi.c[n];
+ ++n;
+ }
+ }
+
+ ctx->mres = n;
+ return 0;
+ } while(0);
+#endif
+ for (i=0;i<len;++i) {
+ u8 c;
+ if (n==0) {
+ (*block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ }
+ c = in[i];
+ out[i] = c^ctx->EKi.c[n];
+ ctx->Xi.c[n] ^= c;
+ n = (n+1)%16;
+ if (n==0)
+ GCM_MUL(ctx,Xi);
+ }
+
+ ctx->mres = n;
+ return 0;
+}
+
+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len, ctr128_f stream)
+{
+ const union { long one; char little; } is_endian = {1};
+ unsigned int n, ctr;
+ size_t i;
+ u64 mlen = ctx->len.u[1];
+ void *key = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+ void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+ const u8 *inp,size_t len) = ctx->ghash;
+# endif
+#endif
+
+ mlen += len;
+ if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlen<len))
+ return -1;
+ ctx->len.u[1] = mlen;
+
+ if (ctx->ares) {
+ /* First call to encrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx,Xi);
+ ctx->ares = 0;
+ }
+
+ if (is_endian.little)
+ ctr = GETU32(ctx->Yi.c+12);
+ else
+ ctr = ctx->Yi.d[3];
+
+ n = ctx->mres;
+ if (n) {
+ while (n && len) {
+ ctx->Xi.c[n] ^= *(out++) = *(in++)^ctx->EKi.c[n];
+ --len;
+ n = (n+1)%16;
+ }
+ if (n==0) GCM_MUL(ctx,Xi);
+ else {
+ ctx->mres = n;
+ return 0;
+ }
+ }
+#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
+ while (len>=GHASH_CHUNK) {
+ (*stream)(in,out,GHASH_CHUNK/16,key,ctx->Yi.c);
+ ctr += GHASH_CHUNK/16;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ GHASH(ctx,out,GHASH_CHUNK);
+ out += GHASH_CHUNK;
+ in += GHASH_CHUNK;
+ len -= GHASH_CHUNK;
+ }
+#endif
+ if ((i = (len&(size_t)-16))) {
+ size_t j=i/16;
+
+ (*stream)(in,out,j,key,ctx->Yi.c);
+ ctr += (unsigned int)j;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ in += i;
+ len -= i;
+#if defined(GHASH)
+ GHASH(ctx,out,i);
+ out += i;
+#else
+ while (j--) {
+ for (i=0;i<16;++i) ctx->Xi.c[i] ^= out[i];
+ GCM_MUL(ctx,Xi);
+ out += 16;
+ }
+#endif
+ }
+ if (len) {
+ (*ctx->block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ while (len--) {
+ ctx->Xi.c[n] ^= out[n] = in[n]^ctx->EKi.c[n];
+ ++n;
+ }
+ }
+
+ ctx->mres = n;
+ return 0;
+}
+
+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len,ctr128_f stream)
+{
+ const union { long one; char little; } is_endian = {1};
+ unsigned int n, ctr;
+ size_t i;
+ u64 mlen = ctx->len.u[1];
+ void *key = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+ void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+ const u8 *inp,size_t len) = ctx->ghash;
+# endif
+#endif
+
+ mlen += len;
+ if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlen<len))
+ return -1;
+ ctx->len.u[1] = mlen;
+
+ if (ctx->ares) {
+ /* First call to decrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx,Xi);
+ ctx->ares = 0;
+ }
+
+ if (is_endian.little)
+ ctr = GETU32(ctx->Yi.c+12);
+ else
+ ctr = ctx->Yi.d[3];
+
+ n = ctx->mres;
+ if (n) {
+ while (n && len) {
+ u8 c = *(in++);
+ *(out++) = c^ctx->EKi.c[n];
+ ctx->Xi.c[n] ^= c;
+ --len;
+ n = (n+1)%16;
+ }
+ if (n==0) GCM_MUL (ctx,Xi);
+ else {
+ ctx->mres = n;
+ return 0;
+ }
+ }
+#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
+ while (len>=GHASH_CHUNK) {
+ GHASH(ctx,in,GHASH_CHUNK);
+ (*stream)(in,out,GHASH_CHUNK/16,key,ctx->Yi.c);
+ ctr += GHASH_CHUNK/16;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ out += GHASH_CHUNK;
+ in += GHASH_CHUNK;
+ len -= GHASH_CHUNK;
+ }
+#endif
+ if ((i = (len&(size_t)-16))) {
+ size_t j=i/16;
+
+#if defined(GHASH)
+ GHASH(ctx,in,i);
+#else
+ while (j--) {
+ size_t k;
+ for (k=0;k<16;++k) ctx->Xi.c[k] ^= in[k];
+ GCM_MUL(ctx,Xi);
+ in += 16;
+ }
+ j = i/16;
+ in -= i;
+#endif
+ (*stream)(in,out,j,key,ctx->Yi.c);
+ ctr += (unsigned int)j;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ out += i;
+ in += i;
+ len -= i;
+ }
+ if (len) {
+ (*ctx->block)(ctx->Yi.c,ctx->EKi.c,key);
+ ++ctr;
+ if (is_endian.little)
+ PUTU32(ctx->Yi.c+12,ctr);
+ else
+ ctx->Yi.d[3] = ctr;
+ while (len--) {
+ u8 c = in[n];
+ ctx->Xi.c[n] ^= c;
+ out[n] = c^ctx->EKi.c[n];
+ ++n;
+ }
+ }
+
+ ctx->mres = n;
+ return 0;
+}
+
+int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
+ size_t len)
+{
+ const union { long one; char little; } is_endian = {1};
+ u64 alen = ctx->len.u[0]<<3;
+ u64 clen = ctx->len.u[1]<<3;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16]) = ctx->gmult;
+#endif
+
+ if (ctx->mres || ctx->ares)
+ GCM_MUL(ctx,Xi);
+
+ if (is_endian.little) {
+#ifdef BSWAP8
+ alen = BSWAP8(alen);
+ clen = BSWAP8(clen);
+#else
+ u8 *p = ctx->len.c;
+
+ ctx->len.u[0] = alen;
+ ctx->len.u[1] = clen;
+
+ alen = (u64)GETU32(p) <<32|GETU32(p+4);
+ clen = (u64)GETU32(p+8)<<32|GETU32(p+12);
+#endif
+ }
+
+ ctx->Xi.u[0] ^= alen;
+ ctx->Xi.u[1] ^= clen;
+ GCM_MUL(ctx,Xi);
+
+ ctx->Xi.u[0] ^= ctx->EK0.u[0];
+ ctx->Xi.u[1] ^= ctx->EK0.u[1];
+
+ if (tag && len<=sizeof(ctx->Xi))
+ return memcmp(ctx->Xi.c,tag,len);
+ else
+ return -1;
+}
+
+void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
+{
+ CRYPTO_gcm128_finish(ctx, NULL, 0);
+ memcpy(tag, ctx->Xi.c, len<=sizeof(ctx->Xi.c)?len:sizeof(ctx->Xi.c));
+}
+
+GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block)
+{
+ GCM128_CONTEXT *ret;
+
+ if ((ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT))))
+ CRYPTO_gcm128_init(ret,key,block);
+
+ return ret;
+}
+
+void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx)
+{
+ if (ctx) {
+ OPENSSL_cleanse(ctx,sizeof(*ctx));
+ OPENSSL_free(ctx);
+ }
+}
+
+#if defined(SELFTEST)
+#include <stdio.h>
+#include <openssl/aes.h>
+
+/* Test Case 1 */
+static const u8 K1[16],
+ *P1=NULL,
+ *A1=NULL,
+ IV1[12],
+ *C1=NULL,
+ T1[]= {0x58,0xe2,0xfc,0xce,0xfa,0x7e,0x30,0x61,0x36,0x7f,0x1d,0x57,0xa4,0xe7,0x45,0x5a};
+
+/* Test Case 2 */
+#define K2 K1
+#define A2 A1
+#define IV2 IV1
+static const u8 P2[16],
+ C2[]= {0x03,0x88,0xda,0xce,0x60,0xb6,0xa3,0x92,0xf3,0x28,0xc2,0xb9,0x71,0xb2,0xfe,0x78},
+ T2[]= {0xab,0x6e,0x47,0xd4,0x2c,0xec,0x13,0xbd,0xf5,0x3a,0x67,0xb2,0x12,0x57,0xbd,0xdf};
+
+/* Test Case 3 */
+#define A3 A2
+static const u8 K3[]= {0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08},
+ P3[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
+ 0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
+ 0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
+ 0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55},
+ IV3[]= {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88},
+ C3[]= {0x42,0x83,0x1e,0xc2,0x21,0x77,0x74,0x24,0x4b,0x72,0x21,0xb7,0x84,0xd0,0xd4,0x9c,
+ 0xe3,0xaa,0x21,0x2f,0x2c,0x02,0xa4,0xe0,0x35,0xc1,0x7e,0x23,0x29,0xac,0xa1,0x2e,
+ 0x21,0xd5,0x14,0xb2,0x54,0x66,0x93,0x1c,0x7d,0x8f,0x6a,0x5a,0xac,0x84,0xaa,0x05,
+ 0x1b,0xa3,0x0b,0x39,0x6a,0x0a,0xac,0x97,0x3d,0x58,0xe0,0x91,0x47,0x3f,0x59,0x85},
+ T3[]= {0x4d,0x5c,0x2a,0xf3,0x27,0xcd,0x64,0xa6,0x2c,0xf3,0x5a,0xbd,0x2b,0xa6,0xfa,0xb4};
+
+/* Test Case 4 */
+#define K4 K3
+#define IV4 IV3
+static const u8 P4[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
+ 0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
+ 0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
+ 0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39},
+ A4[]= {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
+ 0xab,0xad,0xda,0xd2},
+ C4[]= {0x42,0x83,0x1e,0xc2,0x21,0x77,0x74,0x24,0x4b,0x72,0x21,0xb7,0x84,0xd0,0xd4,0x9c,
+ 0xe3,0xaa,0x21,0x2f,0x2c,0x02,0xa4,0xe0,0x35,0xc1,0x7e,0x23,0x29,0xac,0xa1,0x2e,
+ 0x21,0xd5,0x14,0xb2,0x54,0x66,0x93,0x1c,0x7d,0x8f,0x6a,0x5a,0xac,0x84,0xaa,0x05,
+ 0x1b,0xa3,0x0b,0x39,0x6a,0x0a,0xac,0x97,0x3d,0x58,0xe0,0x91},
+ T4[]= {0x5b,0xc9,0x4f,0xbc,0x32,0x21,0xa5,0xdb,0x94,0xfa,0xe9,0x5a,0xe7,0x12,0x1a,0x47};
+
+/* Test Case 5 */
+#define K5 K4
+#define P5 P4
+#define A5 A4
+static const u8 IV5[]= {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad},
+ C5[]= {0x61,0x35,0x3b,0x4c,0x28,0x06,0x93,0x4a,0x77,0x7f,0xf5,0x1f,0xa2,0x2a,0x47,0x55,
+ 0x69,0x9b,0x2a,0x71,0x4f,0xcd,0xc6,0xf8,0x37,0x66,0xe5,0xf9,0x7b,0x6c,0x74,0x23,
+ 0x73,0x80,0x69,0x00,0xe4,0x9f,0x24,0xb2,0x2b,0x09,0x75,0x44,0xd4,0x89,0x6b,0x42,
+ 0x49,0x89,0xb5,0xe1,0xeb,0xac,0x0f,0x07,0xc2,0x3f,0x45,0x98},
+ T5[]= {0x36,0x12,0xd2,0xe7,0x9e,0x3b,0x07,0x85,0x56,0x1b,0xe1,0x4a,0xac,0xa2,0xfc,0xcb};
+
+/* Test Case 6 */
+#define K6 K5
+#define P6 P5
+#define A6 A5
+static const u8 IV6[]= {0x93,0x13,0x22,0x5d,0xf8,0x84,0x06,0xe5,0x55,0x90,0x9c,0x5a,0xff,0x52,0x69,0xaa,
+ 0x6a,0x7a,0x95,0x38,0x53,0x4f,0x7d,0xa1,0xe4,0xc3,0x03,0xd2,0xa3,0x18,0xa7,0x28,
+ 0xc3,0xc0,0xc9,0x51,0x56,0x80,0x95,0x39,0xfc,0xf0,0xe2,0x42,0x9a,0x6b,0x52,0x54,
+ 0x16,0xae,0xdb,0xf5,0xa0,0xde,0x6a,0x57,0xa6,0x37,0xb3,0x9b},
+ C6[]= {0x8c,0xe2,0x49,0x98,0x62,0x56,0x15,0xb6,0x03,0xa0,0x33,0xac,0xa1,0x3f,0xb8,0x94,
+ 0xbe,0x91,0x12,0xa5,0xc3,0xa2,0x11,0xa8,0xba,0x26,0x2a,0x3c,0xca,0x7e,0x2c,0xa7,
+ 0x01,0xe4,0xa9,0xa4,0xfb,0xa4,0x3c,0x90,0xcc,0xdc,0xb2,0x81,0xd4,0x8c,0x7c,0x6f,
+ 0xd6,0x28,0x75,0xd2,0xac,0xa4,0x17,0x03,0x4c,0x34,0xae,0xe5},
+ T6[]= {0x61,0x9c,0xc5,0xae,0xff,0xfe,0x0b,0xfa,0x46,0x2a,0xf4,0x3c,0x16,0x99,0xd0,0x50};
+
+/* Test Case 7 */
+static const u8 K7[24],
+ *P7=NULL,
+ *A7=NULL,
+ IV7[12],
+ *C7=NULL,
+ T7[]= {0xcd,0x33,0xb2,0x8a,0xc7,0x73,0xf7,0x4b,0xa0,0x0e,0xd1,0xf3,0x12,0x57,0x24,0x35};
+
+/* Test Case 8 */
+#define K8 K7
+#define IV8 IV7
+#define A8 A7
+static const u8 P8[16],
+ C8[]= {0x98,0xe7,0x24,0x7c,0x07,0xf0,0xfe,0x41,0x1c,0x26,0x7e,0x43,0x84,0xb0,0xf6,0x00},
+ T8[]= {0x2f,0xf5,0x8d,0x80,0x03,0x39,0x27,0xab,0x8e,0xf4,0xd4,0x58,0x75,0x14,0xf0,0xfb};
+
+/* Test Case 9 */
+#define A9 A8
+static const u8 K9[]= {0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08,
+ 0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c},
+ P9[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
+ 0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
+ 0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
+ 0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55},
+ IV9[]= {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88},
+ C9[]= {0x39,0x80,0xca,0x0b,0x3c,0x00,0xe8,0x41,0xeb,0x06,0xfa,0xc4,0x87,0x2a,0x27,0x57,
+ 0x85,0x9e,0x1c,0xea,0xa6,0xef,0xd9,0x84,0x62,0x85,0x93,0xb4,0x0c,0xa1,0xe1,0x9c,
+ 0x7d,0x77,0x3d,0x00,0xc1,0x44,0xc5,0x25,0xac,0x61,0x9d,0x18,0xc8,0x4a,0x3f,0x47,
+ 0x18,0xe2,0x44,0x8b,0x2f,0xe3,0x24,0xd9,0xcc,0xda,0x27,0x10,0xac,0xad,0xe2,0x56},
+ T9[]= {0x99,0x24,0xa7,0xc8,0x58,0x73,0x36,0xbf,0xb1,0x18,0x02,0x4d,0xb8,0x67,0x4a,0x14};
+
+/* Test Case 10 */
+#define K10 K9
+#define IV10 IV9
+static const u8 P10[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
+ 0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
+ 0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
+ 0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39},
+ A10[]= {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
+ 0xab,0xad,0xda,0xd2},
+ C10[]= {0x39,0x80,0xca,0x0b,0x3c,0x00,0xe8,0x41,0xeb,0x06,0xfa,0xc4,0x87,0x2a,0x27,0x57,
+ 0x85,0x9e,0x1c,0xea,0xa6,0xef,0xd9,0x84,0x62,0x85,0x93,0xb4,0x0c,0xa1,0xe1,0x9c,
+ 0x7d,0x77,0x3d,0x00,0xc1,0x44,0xc5,0x25,0xac,0x61,0x9d,0x18,0xc8,0x4a,0x3f,0x47,
+ 0x18,0xe2,0x44,0x8b,0x2f,0xe3,0x24,0xd9,0xcc,0xda,0x27,0x10},
+ T10[]= {0x25,0x19,0x49,0x8e,0x80,0xf1,0x47,0x8f,0x37,0xba,0x55,0xbd,0x6d,0x27,0x61,0x8c};
+
+/* Test Case 11 */
+#define K11 K10
+#define P11 P10
+#define A11 A10
+static const u8 IV11[]={0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad},
+ C11[]= {0x0f,0x10,0xf5,0x99,0xae,0x14,0xa1,0x54,0xed,0x24,0xb3,0x6e,0x25,0x32,0x4d,0xb8,
+ 0xc5,0x66,0x63,0x2e,0xf2,0xbb,0xb3,0x4f,0x83,0x47,0x28,0x0f,0xc4,0x50,0x70,0x57,
+ 0xfd,0xdc,0x29,0xdf,0x9a,0x47,0x1f,0x75,0xc6,0x65,0x41,0xd4,0xd4,0xda,0xd1,0xc9,
+ 0xe9,0x3a,0x19,0xa5,0x8e,0x8b,0x47,0x3f,0xa0,0xf0,0x62,0xf7},
+ T11[]= {0x65,0xdc,0xc5,0x7f,0xcf,0x62,0x3a,0x24,0x09,0x4f,0xcc,0xa4,0x0d,0x35,0x33,0xf8};
+
+/* Test Case 12 */
+#define K12 K11
+#define P12 P11
+#define A12 A11
+static const u8 IV12[]={0x93,0x13,0x22,0x5d,0xf8,0x84,0x06,0xe5,0x55,0x90,0x9c,0x5a,0xff,0x52,0x69,0xaa,
+ 0x6a,0x7a,0x95,0x38,0x53,0x4f,0x7d,0xa1,0xe4,0xc3,0x03,0xd2,0xa3,0x18,0xa7,0x28,
+ 0xc3,0xc0,0xc9,0x51,0x56,0x80,0x95,0x39,0xfc,0xf0,0xe2,0x42,0x9a,0x6b,0x52,0x54,
+ 0x16,0xae,0xdb,0xf5,0xa0,0xde,0x6a,0x57,0xa6,0x37,0xb3,0x9b},
+ C12[]= {0xd2,0x7e,0x88,0x68,0x1c,0xe3,0x24,0x3c,0x48,0x30,0x16,0x5a,0x8f,0xdc,0xf9,0xff,
+ 0x1d,0xe9,0xa1,0xd8,0xe6,0xb4,0x47,0xef,0x6e,0xf7,0xb7,0x98,0x28,0x66,0x6e,0x45,
+ 0x81,0xe7,0x90,0x12,0xaf,0x34,0xdd,0xd9,0xe2,0xf0,0x37,0x58,0x9b,0x29,0x2d,0xb3,
+ 0xe6,0x7c,0x03,0x67,0x45,0xfa,0x22,0xe7,0xe9,0xb7,0x37,0x3b},
+ T12[]= {0xdc,0xf5,0x66,0xff,0x29,0x1c,0x25,0xbb,0xb8,0x56,0x8f,0xc3,0xd3,0x76,0xa6,0xd9};
+
+/* Test Case 13 */
+static const u8 K13[32],
+ *P13=NULL,
+ *A13=NULL,
+ IV13[12],
+ *C13=NULL,
+ T13[]={0x53,0x0f,0x8a,0xfb,0xc7,0x45,0x36,0xb9,0xa9,0x63,0xb4,0xf1,0xc4,0xcb,0x73,0x8b};
+
+/* Test Case 14 */
+#define K14 K13
+#define A14 A13
+static const u8 P14[16],
+ IV14[12],
+ C14[]= {0xce,0xa7,0x40,0x3d,0x4d,0x60,0x6b,0x6e,0x07,0x4e,0xc5,0xd3,0xba,0xf3,0x9d,0x18},
+ T14[]= {0xd0,0xd1,0xc8,0xa7,0x99,0x99,0x6b,0xf0,0x26,0x5b,0x98,0xb5,0xd4,0x8a,0xb9,0x19};
+
+/* Test Case 15 */
+#define A15 A14
+static const u8 K15[]= {0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08,
+ 0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08},
+ P15[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
+ 0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
+ 0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
+ 0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55},
+ IV15[]={0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88},
+ C15[]= {0x52,0x2d,0xc1,0xf0,0x99,0x56,0x7d,0x07,0xf4,0x7f,0x37,0xa3,0x2a,0x84,0x42,0x7d,
+ 0x64,0x3a,0x8c,0xdc,0xbf,0xe5,0xc0,0xc9,0x75,0x98,0xa2,0xbd,0x25,0x55,0xd1,0xaa,
+ 0x8c,0xb0,0x8e,0x48,0x59,0x0d,0xbb,0x3d,0xa7,0xb0,0x8b,0x10,0x56,0x82,0x88,0x38,
+ 0xc5,0xf6,0x1e,0x63,0x93,0xba,0x7a,0x0a,0xbc,0xc9,0xf6,0x62,0x89,0x80,0x15,0xad},
+ T15[]= {0xb0,0x94,0xda,0xc5,0xd9,0x34,0x71,0xbd,0xec,0x1a,0x50,0x22,0x70,0xe3,0xcc,0x6c};
+
+/* Test Case 16 */
+#define K16 K15
+#define IV16 IV15
+static const u8 P16[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
+ 0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
+ 0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
+ 0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39},
+ A16[]= {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
+ 0xab,0xad,0xda,0xd2},
+ C16[]= {0x52,0x2d,0xc1,0xf0,0x99,0x56,0x7d,0x07,0xf4,0x7f,0x37,0xa3,0x2a,0x84,0x42,0x7d,
+ 0x64,0x3a,0x8c,0xdc,0xbf,0xe5,0xc0,0xc9,0x75,0x98,0xa2,0xbd,0x25,0x55,0xd1,0xaa,
+ 0x8c,0xb0,0x8e,0x48,0x59,0x0d,0xbb,0x3d,0xa7,0xb0,0x8b,0x10,0x56,0x82,0x88,0x38,
+ 0xc5,0xf6,0x1e,0x63,0x93,0xba,0x7a,0x0a,0xbc,0xc9,0xf6,0x62},
+ T16[]= {0x76,0xfc,0x6e,0xce,0x0f,0x4e,0x17,0x68,0xcd,0xdf,0x88,0x53,0xbb,0x2d,0x55,0x1b};
+
+/* Test Case 17 */
+#define K17 K16
+#define P17 P16
+#define A17 A16
+static const u8 IV17[]={0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad},
+ C17[]= {0xc3,0x76,0x2d,0xf1,0xca,0x78,0x7d,0x32,0xae,0x47,0xc1,0x3b,0xf1,0x98,0x44,0xcb,
+ 0xaf,0x1a,0xe1,0x4d,0x0b,0x97,0x6a,0xfa,0xc5,0x2f,0xf7,0xd7,0x9b,0xba,0x9d,0xe0,
+ 0xfe,0xb5,0x82,0xd3,0x39,0x34,0xa4,0xf0,0x95,0x4c,0xc2,0x36,0x3b,0xc7,0x3f,0x78,
+ 0x62,0xac,0x43,0x0e,0x64,0xab,0xe4,0x99,0xf4,0x7c,0x9b,0x1f},
+ T17[]= {0x3a,0x33,0x7d,0xbf,0x46,0xa7,0x92,0xc4,0x5e,0x45,0x49,0x13,0xfe,0x2e,0xa8,0xf2};
+
+/* Test Case 18 */
+#define K18 K17
+#define P18 P17
+#define A18 A17
+static const u8 IV18[]={0x93,0x13,0x22,0x5d,0xf8,0x84,0x06,0xe5,0x55,0x90,0x9c,0x5a,0xff,0x52,0x69,0xaa,
+ 0x6a,0x7a,0x95,0x38,0x53,0x4f,0x7d,0xa1,0xe4,0xc3,0x03,0xd2,0xa3,0x18,0xa7,0x28,
+ 0xc3,0xc0,0xc9,0x51,0x56,0x80,0x95,0x39,0xfc,0xf0,0xe2,0x42,0x9a,0x6b,0x52,0x54,
+ 0x16,0xae,0xdb,0xf5,0xa0,0xde,0x6a,0x57,0xa6,0x37,0xb3,0x9b},
+ C18[]= {0x5a,0x8d,0xef,0x2f,0x0c,0x9e,0x53,0xf1,0xf7,0x5d,0x78,0x53,0x65,0x9e,0x2a,0x20,
+ 0xee,0xb2,0xb2,0x2a,0xaf,0xde,0x64,0x19,0xa0,0x58,0xab,0x4f,0x6f,0x74,0x6b,0xf4,
+ 0x0f,0xc0,0xc3,0xb7,0x80,0xf2,0x44,0x45,0x2d,0xa3,0xeb,0xf1,0xc5,0xd8,0x2c,0xde,
+ 0xa2,0x41,0x89,0x97,0x20,0x0e,0xf8,0x2e,0x44,0xae,0x7e,0x3f},
+ T18[]= {0xa4,0x4a,0x82,0x66,0xee,0x1c,0x8e,0xb0,0xc8,0xb5,0xd4,0xcf,0x5a,0xe9,0xf1,0x9a};
+
+#define TEST_CASE(n) do { \
+ u8 out[sizeof(P##n)]; \
+ AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key); \
+ CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt); \
+ CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \
+ memset(out,0,sizeof(out)); \
+ if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \
+ if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out)); \
+ if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \
+ (C##n && memcmp(out,C##n,sizeof(out)))) \
+ ret++, printf ("encrypt test#%d failed.\n",n); \
+ CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \
+ memset(out,0,sizeof(out)); \
+ if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \
+ if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out)); \
+ if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \
+ (P##n && memcmp(out,P##n,sizeof(out)))) \
+ ret++, printf ("decrypt test#%d failed.\n",n); \
+ } while(0)
+
+int main()
+{
+ GCM128_CONTEXT ctx;
+ AES_KEY key;
+ int ret=0;
+
+ TEST_CASE(1);
+ TEST_CASE(2);
+ TEST_CASE(3);
+ TEST_CASE(4);
+ TEST_CASE(5);
+ TEST_CASE(6);
+ TEST_CASE(7);
+ TEST_CASE(8);
+ TEST_CASE(9);
+ TEST_CASE(10);
+ TEST_CASE(11);
+ TEST_CASE(12);
+ TEST_CASE(13);
+ TEST_CASE(14);
+ TEST_CASE(15);
+ TEST_CASE(16);
+ TEST_CASE(17);
+ TEST_CASE(18);
+
+#ifdef OPENSSL_CPUID_OBJ
+ {
+ size_t start,stop,gcm_t,ctr_t,OPENSSL_rdtsc();
+ union { u64 u; u8 c[1024]; } buf;
+ int i;
+
+ AES_set_encrypt_key(K1,sizeof(K1)*8,&key);
+ CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt);
+ CRYPTO_gcm128_setiv(&ctx,IV1,sizeof(IV1));
+
+ CRYPTO_gcm128_encrypt(&ctx,buf.c,buf.c,sizeof(buf));
+ start = OPENSSL_rdtsc();
+ CRYPTO_gcm128_encrypt(&ctx,buf.c,buf.c,sizeof(buf));
+ gcm_t = OPENSSL_rdtsc() - start;
+
+ CRYPTO_ctr128_encrypt(buf.c,buf.c,sizeof(buf),
+ &key,ctx.Yi.c,ctx.EKi.c,&ctx.mres,
+ (block128_f)AES_encrypt);
+ start = OPENSSL_rdtsc();
+ CRYPTO_ctr128_encrypt(buf.c,buf.c,sizeof(buf),
+ &key,ctx.Yi.c,ctx.EKi.c,&ctx.mres,
+ (block128_f)AES_encrypt);
+ ctr_t = OPENSSL_rdtsc() - start;
+
+ printf("%.2f-%.2f=%.2f\n",
+ gcm_t/(double)sizeof(buf),
+ ctr_t/(double)sizeof(buf),
+ (gcm_t-ctr_t)/(double)sizeof(buf));
+#ifdef GHASH
+ GHASH(&ctx,buf.c,sizeof(buf));
+ start = OPENSSL_rdtsc();
+ for (i=0;i<100;++i) GHASH(&ctx,buf.c,sizeof(buf));
+ gcm_t = OPENSSL_rdtsc() - start;
+ printf("%.2f\n",gcm_t/(double)sizeof(buf)/(double)i);
+#endif
+ }
+#endif
+
+ return ret;
+}
+#endif
diff --git a/deps/openssl/openssl/crypto/modes/modes.h b/deps/openssl/openssl/crypto/modes/modes.h
index af8d97d79..f18215bb2 100644
--- a/deps/openssl/openssl/crypto/modes/modes.h
+++ b/deps/openssl/openssl/crypto/modes/modes.h
@@ -15,6 +15,14 @@ typedef void (*cbc128_f)(const unsigned char *in, unsigned char *out,
size_t len, const void *key,
unsigned char ivec[16], int enc);
+typedef void (*ctr128_f)(const unsigned char *in, unsigned char *out,
+ size_t blocks, const void *key,
+ const unsigned char ivec[16]);
+
+typedef void (*ccm128_f)(const unsigned char *in, unsigned char *out,
+ size_t blocks, const void *key,
+ const unsigned char ivec[16],unsigned char cmac[16]);
+
void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const void *key,
unsigned char ivec[16], block128_f block);
@@ -27,6 +35,11 @@ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
unsigned char ivec[16], unsigned char ecount_buf[16],
unsigned int *num, block128_f block);
+void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], unsigned char ecount_buf[16],
+ unsigned int *num, ctr128_f ctr);
+
void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const void *key,
unsigned char ivec[16], int *num,
@@ -57,3 +70,66 @@ size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
size_t len, const void *key,
unsigned char ivec[16], cbc128_f cbc);
+
+size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], block128_f block);
+size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], cbc128_f cbc);
+size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], block128_f block);
+size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], cbc128_f cbc);
+
+typedef struct gcm128_context GCM128_CONTEXT;
+
+GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block);
+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block);
+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv,
+ size_t len);
+int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad,
+ size_t len);
+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len);
+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len);
+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len, ctr128_f stream);
+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len, ctr128_f stream);
+int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
+ size_t len);
+void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
+void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
+
+typedef struct ccm128_context CCM128_CONTEXT;
+
+void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
+ unsigned int M, unsigned int L, void *key,block128_f block);
+int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
+ const unsigned char *nonce, size_t nlen, size_t mlen);
+void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
+ const unsigned char *aad, size_t alen);
+int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out, size_t len);
+int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out, size_t len);
+int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out, size_t len,
+ ccm128_f stream);
+int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out, size_t len,
+ ccm128_f stream);
+size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
+
+typedef struct xts128_context XTS128_CONTEXT;
+
+int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16],
+ const unsigned char *inp, unsigned char *out, size_t len, int enc);
diff --git a/deps/openssl/openssl/crypto/modes/modes_lcl.h b/deps/openssl/openssl/crypto/modes/modes_lcl.h
new file mode 100644
index 000000000..b6dc3c336
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/modes_lcl.h
@@ -0,0 +1,131 @@
+/* ====================================================================
+ * Copyright (c) 2010 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use is governed by OpenSSL license.
+ * ====================================================================
+ */
+
+#include <openssl/modes.h>
+
+
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+typedef __int64 i64;
+typedef unsigned __int64 u64;
+#define U64(C) C##UI64
+#elif defined(__arch64__)
+typedef long i64;
+typedef unsigned long u64;
+#define U64(C) C##UL
+#else
+typedef long long i64;
+typedef unsigned long long u64;
+#define U64(C) C##ULL
+#endif
+
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+#define STRICT_ALIGNMENT 1
+#if defined(__i386) || defined(__i386__) || \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__s390__) || defined(__s390x__) || \
+ ( (defined(__arm__) || defined(__arm)) && \
+ (defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
+ defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)) )
+# undef STRICT_ALIGNMENT
+#endif
+
+#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+#if defined(__GNUC__) && __GNUC__>=2
+# if defined(__x86_64) || defined(__x86_64__)
+# define BSWAP8(x) ({ u64 ret=(x); \
+ asm ("bswapq %0" \
+ : "+r"(ret)); ret; })
+# define BSWAP4(x) ({ u32 ret=(x); \
+ asm ("bswapl %0" \
+ : "+r"(ret)); ret; })
+# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)
+# define BSWAP8(x) ({ u32 lo=(u64)(x)>>32,hi=(x); \
+ asm ("bswapl %0; bswapl %1" \
+ : "+r"(hi),"+r"(lo)); \
+ (u64)hi<<32|lo; })
+# define BSWAP4(x) ({ u32 ret=(x); \
+ asm ("bswapl %0" \
+ : "+r"(ret)); ret; })
+# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT)
+# define BSWAP8(x) ({ u32 lo=(u64)(x)>>32,hi=(x); \
+ asm ("rev %0,%0; rev %1,%1" \
+ : "+r"(hi),"+r"(lo)); \
+ (u64)hi<<32|lo; })
+# define BSWAP4(x) ({ u32 ret; \
+ asm ("rev %0,%1" \
+ : "=r"(ret) : "r"((u32)(x))); \
+ ret; })
+# endif
+#elif defined(_MSC_VER)
+# if _MSC_VER>=1300
+# pragma intrinsic(_byteswap_uint64,_byteswap_ulong)
+# define BSWAP8(x) _byteswap_uint64((u64)(x))
+# define BSWAP4(x) _byteswap_ulong((u32)(x))
+# elif defined(_M_IX86)
+ __inline u32 _bswap4(u32 val) {
+ _asm mov eax,val
+ _asm bswap eax
+ }
+# define BSWAP4(x) _bswap4(x)
+# endif
+#endif
+#endif
+
+#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT)
+#define GETU32(p) BSWAP4(*(const u32 *)(p))
+#define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v)
+#else
+#define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3])
+#define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
+#endif
+
+/* GCM definitions */
+
+typedef struct { u64 hi,lo; } u128;
+
+#ifdef TABLE_BITS
+#undef TABLE_BITS
+#endif
+/*
+ * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
+ * never be set to 8 [or 1]. For further information see gcm128.c.
+ */
+#define TABLE_BITS 4
+
+struct gcm128_context {
+ /* Following 6 names follow names in GCM specification */
+ union { u64 u[2]; u32 d[4]; u8 c[16]; } Yi,EKi,EK0,len,
+ Xi,H;
+ /* Relative position of Xi, H and pre-computed Htable is used
+ * in some assembler modules, i.e. don't change the order! */
+#if TABLE_BITS==8
+ u128 Htable[256];
+#else
+ u128 Htable[16];
+ void (*gmult)(u64 Xi[2],const u128 Htable[16]);
+ void (*ghash)(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+#endif
+ unsigned int mres, ares;
+ block128_f block;
+ void *key;
+};
+
+struct xts128_context {
+ void *key1, *key2;
+ block128_f block1,block2;
+};
+
+struct ccm128_context {
+ union { u64 u[2]; u8 c[16]; } nonce, cmac;
+ u64 blocks;
+ block128_f block;
+ void *key;
+};
+
diff --git a/deps/openssl/openssl/crypto/modes/ofb128.c b/deps/openssl/openssl/crypto/modes/ofb128.c
index c732e2ec5..01c01702c 100644
--- a/deps/openssl/openssl/crypto/modes/ofb128.c
+++ b/deps/openssl/openssl/crypto/modes/ofb128.c
@@ -48,7 +48,8 @@
*
*/
-#include "modes.h"
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
#include <string.h>
#ifndef MODES_DEBUG
@@ -58,14 +59,6 @@
#endif
#include <assert.h>
-#define STRICT_ALIGNMENT
-#if defined(__i386) || defined(__i386__) || \
- defined(__x86_64) || defined(__x86_64__) || \
- defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
- defined(__s390__) || defined(__s390x__)
-# undef STRICT_ALIGNMENT
-#endif
-
/* The input and output encrypted as though 128bit ofb mode is being
* used. The extra state information to record how much of the
* 128bit block we have used is contained in *num;
diff --git a/deps/openssl/openssl/crypto/modes/xts128.c b/deps/openssl/openssl/crypto/modes/xts128.c
new file mode 100644
index 000000000..9cf27a25e
--- /dev/null
+++ b/deps/openssl/openssl/crypto/modes/xts128.c
@@ -0,0 +1,187 @@
+/* ====================================================================
+ * Copyright (c) 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.
+ * ====================================================================
+ */
+
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16],
+ const unsigned char *inp, unsigned char *out,
+ size_t len, int enc)
+{
+ const union { long one; char little; } is_endian = {1};
+ union { u64 u[2]; u32 d[4]; u8 c[16]; } tweak, scratch;
+ unsigned int i;
+
+ if (len<16) return -1;
+
+ memcpy(tweak.c, iv, 16);
+
+ (*ctx->block2)(tweak.c,tweak.c,ctx->key2);
+
+ if (!enc && (len%16)) len-=16;
+
+ while (len>=16) {
+#if defined(STRICT_ALIGNMENT)
+ memcpy(scratch.c,inp,16);
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+#else
+ scratch.u[0] = ((u64*)inp)[0]^tweak.u[0];
+ scratch.u[1] = ((u64*)inp)[1]^tweak.u[1];
+#endif
+ (*ctx->block1)(scratch.c,scratch.c,ctx->key1);
+#if defined(STRICT_ALIGNMENT)
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out,scratch.c,16);
+#else
+ ((u64*)out)[0] = scratch.u[0]^=tweak.u[0];
+ ((u64*)out)[1] = scratch.u[1]^=tweak.u[1];
+#endif
+ inp += 16;
+ out += 16;
+ len -= 16;
+
+ if (len==0) return 0;
+
+ if (is_endian.little) {
+ unsigned int carry,res;
+
+ res = 0x87&(((int)tweak.d[3])>>31);
+ carry = (unsigned int)(tweak.u[0]>>63);
+ tweak.u[0] = (tweak.u[0]<<1)^res;
+ tweak.u[1] = (tweak.u[1]<<1)|carry;
+ }
+ else {
+ size_t c;
+
+ for (c=0,i=0;i<16;++i) {
+ /*+ substitutes for |, because c is 1 bit */
+ c += ((size_t)tweak.c[i])<<1;
+ tweak.c[i] = (u8)c;
+ c = c>>8;
+ }
+ tweak.c[0] ^= (u8)(0x87&(0-c));
+ }
+ }
+ if (enc) {
+ for (i=0;i<len;++i) {
+ u8 c = inp[i];
+ out[i] = scratch.c[i];
+ scratch.c[i] = c;
+ }
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ (*ctx->block1)(scratch.c,scratch.c,ctx->key1);
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out-16,scratch.c,16);
+ }
+ else {
+ union { u64 u[2]; u8 c[16]; } tweak1;
+
+ if (is_endian.little) {
+ unsigned int carry,res;
+
+ res = 0x87&(((int)tweak.d[3])>>31);
+ carry = (unsigned int)(tweak.u[0]>>63);
+ tweak1.u[0] = (tweak.u[0]<<1)^res;
+ tweak1.u[1] = (tweak.u[1]<<1)|carry;
+ }
+ else {
+ size_t c;
+
+ for (c=0,i=0;i<16;++i) {
+ /*+ substitutes for |, because c is 1 bit */
+ c += ((size_t)tweak.c[i])<<1;
+ tweak1.c[i] = (u8)c;
+ c = c>>8;
+ }
+ tweak1.c[0] ^= (u8)(0x87&(0-c));
+ }
+#if defined(STRICT_ALIGNMENT)
+ memcpy(scratch.c,inp,16);
+ scratch.u[0] ^= tweak1.u[0];
+ scratch.u[1] ^= tweak1.u[1];
+#else
+ scratch.u[0] = ((u64*)inp)[0]^tweak1.u[0];
+ scratch.u[1] = ((u64*)inp)[1]^tweak1.u[1];
+#endif
+ (*ctx->block1)(scratch.c,scratch.c,ctx->key1);
+ scratch.u[0] ^= tweak1.u[0];
+ scratch.u[1] ^= tweak1.u[1];
+
+ for (i=0;i<len;++i) {
+ u8 c = inp[16+i];
+ out[16+i] = scratch.c[i];
+ scratch.c[i] = c;
+ }
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ (*ctx->block1)(scratch.c,scratch.c,ctx->key1);
+#if defined(STRICT_ALIGNMENT)
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy (out,scratch.c,16);
+#else
+ ((u64*)out)[0] = scratch.u[0]^tweak.u[0];
+ ((u64*)out)[1] = scratch.u[1]^tweak.u[1];
+#endif
+ }
+
+ return 0;
+}
diff --git a/deps/openssl/openssl/crypto/o_fips.c b/deps/openssl/openssl/crypto/o_fips.c
new file mode 100644
index 000000000..f6d1b2185
--- /dev/null
+++ b/deps/openssl/openssl/crypto/o_fips.c
@@ -0,0 +1,96 @@
+/* Written by Stephen henson (steve@openssl.org) for the OpenSSL
+ * project 2011.
+ */
+/* ====================================================================
+ * Copyright (c) 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).
+ *
+ */
+
+#include "cryptlib.h"
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+#include <openssl/rand.h>
+#endif
+
+int FIPS_mode(void)
+ {
+ OPENSSL_init();
+#ifdef OPENSSL_FIPS
+ return FIPS_module_mode();
+#else
+ return 0;
+#endif
+ }
+
+int FIPS_mode_set(int r)
+ {
+ OPENSSL_init();
+#ifdef OPENSSL_FIPS
+#ifndef FIPS_AUTH_USER_PASS
+#define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password"
+#endif
+ if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS))
+ return 0;
+ if (r)
+ RAND_set_rand_method(FIPS_rand_get_method());
+ else
+ RAND_set_rand_method(NULL);
+ return 1;
+#else
+ if (r == 0)
+ return 1;
+ CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED);
+ return 0;
+#endif
+ }
+
diff --git a/deps/openssl/openssl/crypto/o_init.c b/deps/openssl/openssl/crypto/o_init.c
new file mode 100644
index 000000000..db4cdc443
--- /dev/null
+++ b/deps/openssl/openssl/crypto/o_init.c
@@ -0,0 +1,82 @@
+/* o_init.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 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.
+ * ====================================================================
+ *
+ */
+
+#include <e_os.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#include <openssl/rand.h>
+#endif
+
+/* Perform any essential OpenSSL initialization operations.
+ * Currently only sets FIPS callbacks
+ */
+
+void OPENSSL_init(void)
+ {
+ static int done = 0;
+ if (done)
+ return;
+ done = 1;
+#ifdef OPENSSL_FIPS
+ FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock);
+ FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata);
+ FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free);
+ RAND_init_fips();
+#endif
+#if 0
+ fprintf(stderr, "Called OPENSSL_init\n");
+#endif
+ }
+
diff --git a/deps/openssl/openssl/crypto/objects/o_names.c b/deps/openssl/openssl/crypto/objects/o_names.c
index 84380a96a..4a548c2ed 100644
--- a/deps/openssl/openssl/crypto/objects/o_names.c
+++ b/deps/openssl/openssl/crypto/objects/o_names.c
@@ -73,7 +73,7 @@ int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
name_funcs_stack=sk_NAME_FUNCS_new_null();
MemCheck_on();
}
- if ((name_funcs_stack == NULL))
+ if (name_funcs_stack == NULL)
{
/* ERROR */
return(0);
diff --git a/deps/openssl/openssl/crypto/objects/obj_dat.h b/deps/openssl/openssl/crypto/objects/obj_dat.h
index 6449be607..d404ad07c 100644
--- a/deps/openssl/openssl/crypto/objects/obj_dat.h
+++ b/deps/openssl/openssl/crypto/objects/obj_dat.h
@@ -62,12 +62,12 @@
* [including the GNU Public Licence.]
*/
-#define NUM_NID 893
-#define NUM_SN 886
-#define NUM_LN 886
-#define NUM_OBJ 840
+#define NUM_NID 920
+#define NUM_SN 913
+#define NUM_LN 913
+#define NUM_OBJ 857
-static const unsigned char lvalues[5824]={
+static const unsigned char lvalues[5980]={
0x00, /* [ 0] OBJ_undef */
0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 1] OBJ_rsadsi */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 7] OBJ_pkcs */
@@ -908,6 +908,23 @@ static const unsigned char lvalues[5824]={
0x55,0x04,0x34, /* [5814] OBJ_supportedAlgorithms */
0x55,0x04,0x35, /* [5817] OBJ_deltaRevocationList */
0x55,0x04,0x36, /* [5820] OBJ_dmdName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,/* [5823] OBJ_id_alg_PWRI_KEK */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,/* [5834] OBJ_aes_128_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,/* [5843] OBJ_aes_128_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,/* [5852] OBJ_id_aes128_wrap_pad */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,/* [5861] OBJ_aes_192_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,/* [5870] OBJ_aes_192_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,/* [5879] OBJ_id_aes192_wrap_pad */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,/* [5888] OBJ_aes_256_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,/* [5897] OBJ_aes_256_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,/* [5906] OBJ_id_aes256_wrap_pad */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,/* [5915] OBJ_id_camellia128_wrap */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,/* [5926] OBJ_id_camellia192_wrap */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,/* [5937] OBJ_id_camellia256_wrap */
+0x55,0x1D,0x25,0x00, /* [5948] OBJ_anyExtendedKeyUsage */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,/* [5952] OBJ_mgf1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,/* [5961] OBJ_rsassaPss */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,/* [5970] OBJ_rsaesOaep */
};
static const ASN1_OBJECT nid_objs[NUM_NID]={
@@ -2351,28 +2368,74 @@ static const ASN1_OBJECT nid_objs[NUM_NID]={
{"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList,
3,&(lvalues[5817]),0},
{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5820]),0},
+{"id-alg-PWRI-KEK","id-alg-PWRI-KEK",NID_id_alg_PWRI_KEK,11,
+ &(lvalues[5823]),0},
+{"CMAC","cmac",NID_cmac,0,NULL,0},
+{"id-aes128-GCM","aes-128-gcm",NID_aes_128_gcm,9,&(lvalues[5834]),0},
+{"id-aes128-CCM","aes-128-ccm",NID_aes_128_ccm,9,&(lvalues[5843]),0},
+{"id-aes128-wrap-pad","id-aes128-wrap-pad",NID_id_aes128_wrap_pad,9,
+ &(lvalues[5852]),0},
+{"id-aes192-GCM","aes-192-gcm",NID_aes_192_gcm,9,&(lvalues[5861]),0},
+{"id-aes192-CCM","aes-192-ccm",NID_aes_192_ccm,9,&(lvalues[5870]),0},
+{"id-aes192-wrap-pad","id-aes192-wrap-pad",NID_id_aes192_wrap_pad,9,
+ &(lvalues[5879]),0},
+{"id-aes256-GCM","aes-256-gcm",NID_aes_256_gcm,9,&(lvalues[5888]),0},
+{"id-aes256-CCM","aes-256-ccm",NID_aes_256_ccm,9,&(lvalues[5897]),0},
+{"id-aes256-wrap-pad","id-aes256-wrap-pad",NID_id_aes256_wrap_pad,9,
+ &(lvalues[5906]),0},
+{"AES-128-CTR","aes-128-ctr",NID_aes_128_ctr,0,NULL,0},
+{"AES-192-CTR","aes-192-ctr",NID_aes_192_ctr,0,NULL,0},
+{"AES-256-CTR","aes-256-ctr",NID_aes_256_ctr,0,NULL,0},
+{"id-camellia128-wrap","id-camellia128-wrap",NID_id_camellia128_wrap,
+ 11,&(lvalues[5915]),0},
+{"id-camellia192-wrap","id-camellia192-wrap",NID_id_camellia192_wrap,
+ 11,&(lvalues[5926]),0},
+{"id-camellia256-wrap","id-camellia256-wrap",NID_id_camellia256_wrap,
+ 11,&(lvalues[5937]),0},
+{"anyExtendedKeyUsage","Any Extended Key Usage",
+ NID_anyExtendedKeyUsage,4,&(lvalues[5948]),0},
+{"MGF1","mgf1",NID_mgf1,9,&(lvalues[5952]),0},
+{"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5961]),0},
+{"AES-128-XTS","aes-128-xts",NID_aes_128_xts,0,NULL,0},
+{"AES-256-XTS","aes-256-xts",NID_aes_256_xts,0,NULL,0},
+{"RC4-HMAC-MD5","rc4-hmac-md5",NID_rc4_hmac_md5,0,NULL,0},
+{"AES-128-CBC-HMAC-SHA1","aes-128-cbc-hmac-sha1",
+ NID_aes_128_cbc_hmac_sha1,0,NULL,0},
+{"AES-192-CBC-HMAC-SHA1","aes-192-cbc-hmac-sha1",
+ NID_aes_192_cbc_hmac_sha1,0,NULL,0},
+{"AES-256-CBC-HMAC-SHA1","aes-256-cbc-hmac-sha1",
+ NID_aes_256_cbc_hmac_sha1,0,NULL,0},
+{"RSAES-OAEP","rsaesOaep",NID_rsaesOaep,9,&(lvalues[5970]),0},
};
static const unsigned int sn_objs[NUM_SN]={
364, /* "AD_DVCS" */
419, /* "AES-128-CBC" */
+916, /* "AES-128-CBC-HMAC-SHA1" */
421, /* "AES-128-CFB" */
650, /* "AES-128-CFB1" */
653, /* "AES-128-CFB8" */
+904, /* "AES-128-CTR" */
418, /* "AES-128-ECB" */
420, /* "AES-128-OFB" */
+913, /* "AES-128-XTS" */
423, /* "AES-192-CBC" */
+917, /* "AES-192-CBC-HMAC-SHA1" */
425, /* "AES-192-CFB" */
651, /* "AES-192-CFB1" */
654, /* "AES-192-CFB8" */
+905, /* "AES-192-CTR" */
422, /* "AES-192-ECB" */
424, /* "AES-192-OFB" */
427, /* "AES-256-CBC" */
+918, /* "AES-256-CBC-HMAC-SHA1" */
429, /* "AES-256-CFB" */
652, /* "AES-256-CFB1" */
655, /* "AES-256-CFB8" */
+906, /* "AES-256-CTR" */
426, /* "AES-256-ECB" */
428, /* "AES-256-OFB" */
+914, /* "AES-256-XTS" */
91, /* "BF-CBC" */
93, /* "BF-CFB" */
92, /* "BF-ECB" */
@@ -2400,6 +2463,7 @@ static const unsigned int sn_objs[NUM_SN]={
110, /* "CAST5-CFB" */
109, /* "CAST5-ECB" */
111, /* "CAST5-OFB" */
+894, /* "CMAC" */
13, /* "CN" */
141, /* "CRLReason" */
417, /* "CSPName" */
@@ -2451,6 +2515,7 @@ static const unsigned int sn_objs[NUM_SN]={
4, /* "MD5" */
114, /* "MD5-SHA1" */
95, /* "MDC2" */
+911, /* "MGF1" */
388, /* "Mail" */
393, /* "NULL" */
404, /* "NULL" */
@@ -2487,6 +2552,7 @@ static const unsigned int sn_objs[NUM_SN]={
40, /* "RC2-OFB" */
5, /* "RC4" */
97, /* "RC4-40" */
+915, /* "RC4-HMAC-MD5" */
120, /* "RC5-CBC" */
122, /* "RC5-CFB" */
121, /* "RC5-ECB" */
@@ -2507,6 +2573,8 @@ static const unsigned int sn_objs[NUM_SN]={
668, /* "RSA-SHA256" */
669, /* "RSA-SHA384" */
670, /* "RSA-SHA512" */
+919, /* "RSAES-OAEP" */
+912, /* "RSASSA-PSS" */
777, /* "SEED-CBC" */
779, /* "SEED-CFB" */
776, /* "SEED-ECB" */
@@ -2540,6 +2608,7 @@ static const unsigned int sn_objs[NUM_SN]={
363, /* "ad_timestamping" */
376, /* "algorithm" */
405, /* "ansi-X9-62" */
+910, /* "anyExtendedKeyUsage" */
746, /* "anyPolicy" */
370, /* "archiveCutoff" */
484, /* "associatedDomain" */
@@ -2716,14 +2785,27 @@ static const unsigned int sn_objs[NUM_SN]={
357, /* "id-aca-group" */
358, /* "id-aca-role" */
176, /* "id-ad" */
+896, /* "id-aes128-CCM" */
+895, /* "id-aes128-GCM" */
788, /* "id-aes128-wrap" */
+897, /* "id-aes128-wrap-pad" */
+899, /* "id-aes192-CCM" */
+898, /* "id-aes192-GCM" */
789, /* "id-aes192-wrap" */
+900, /* "id-aes192-wrap-pad" */
+902, /* "id-aes256-CCM" */
+901, /* "id-aes256-GCM" */
790, /* "id-aes256-wrap" */
+903, /* "id-aes256-wrap-pad" */
262, /* "id-alg" */
+893, /* "id-alg-PWRI-KEK" */
323, /* "id-alg-des40" */
326, /* "id-alg-dh-pop" */
325, /* "id-alg-dh-sig-hmac-sha1" */
324, /* "id-alg-noSignature" */
+907, /* "id-camellia128-wrap" */
+908, /* "id-camellia192-wrap" */
+909, /* "id-camellia256-wrap" */
268, /* "id-cct" */
361, /* "id-cct-PKIData" */
362, /* "id-cct-PKIResponse" */
@@ -3246,6 +3328,7 @@ static const unsigned int ln_objs[NUM_LN]={
363, /* "AD Time Stamping" */
405, /* "ANSI X9.62" */
368, /* "Acceptable OCSP Responses" */
+910, /* "Any Extended Key Usage" */
664, /* "Any language" */
177, /* "Authority Information Access" */
365, /* "Basic OCSP Response" */
@@ -3386,23 +3469,37 @@ static const unsigned int ln_objs[NUM_LN]={
364, /* "ad dvcs" */
606, /* "additional verification" */
419, /* "aes-128-cbc" */
+916, /* "aes-128-cbc-hmac-sha1" */
+896, /* "aes-128-ccm" */
421, /* "aes-128-cfb" */
650, /* "aes-128-cfb1" */
653, /* "aes-128-cfb8" */
+904, /* "aes-128-ctr" */
418, /* "aes-128-ecb" */
+895, /* "aes-128-gcm" */
420, /* "aes-128-ofb" */
+913, /* "aes-128-xts" */
423, /* "aes-192-cbc" */
+917, /* "aes-192-cbc-hmac-sha1" */
+899, /* "aes-192-ccm" */
425, /* "aes-192-cfb" */
651, /* "aes-192-cfb1" */
654, /* "aes-192-cfb8" */
+905, /* "aes-192-ctr" */
422, /* "aes-192-ecb" */
+898, /* "aes-192-gcm" */
424, /* "aes-192-ofb" */
427, /* "aes-256-cbc" */
+918, /* "aes-256-cbc-hmac-sha1" */
+902, /* "aes-256-ccm" */
429, /* "aes-256-cfb" */
652, /* "aes-256-cfb1" */
655, /* "aes-256-cfb8" */
+906, /* "aes-256-ctr" */
426, /* "aes-256-ecb" */
+901, /* "aes-256-gcm" */
428, /* "aes-256-ofb" */
+914, /* "aes-256-xts" */
376, /* "algorithm" */
484, /* "associatedDomain" */
485, /* "associatedName" */
@@ -3467,6 +3564,7 @@ static const unsigned int ln_objs[NUM_LN]={
407, /* "characteristic-two-field" */
395, /* "clearance" */
633, /* "cleartext track 2" */
+894, /* "cmac" */
13, /* "commonName" */
513, /* "content types" */
50, /* "contentType" */
@@ -3602,13 +3700,20 @@ static const unsigned int ln_objs[NUM_LN]={
358, /* "id-aca-role" */
176, /* "id-ad" */
788, /* "id-aes128-wrap" */
+897, /* "id-aes128-wrap-pad" */
789, /* "id-aes192-wrap" */
+900, /* "id-aes192-wrap-pad" */
790, /* "id-aes256-wrap" */
+903, /* "id-aes256-wrap-pad" */
262, /* "id-alg" */
+893, /* "id-alg-PWRI-KEK" */
323, /* "id-alg-des40" */
326, /* "id-alg-dh-pop" */
325, /* "id-alg-dh-sig-hmac-sha1" */
324, /* "id-alg-noSignature" */
+907, /* "id-camellia128-wrap" */
+908, /* "id-camellia192-wrap" */
+909, /* "id-camellia256-wrap" */
268, /* "id-cct" */
361, /* "id-cct-PKIData" */
362, /* "id-cct-PKIResponse" */
@@ -3806,6 +3911,7 @@ static const unsigned int ln_objs[NUM_LN]={
602, /* "merchant initiated auth" */
514, /* "message extensions" */
51, /* "messageDigest" */
+911, /* "mgf1" */
506, /* "mime-mhs-bodies" */
505, /* "mime-mhs-headings" */
488, /* "mobileTelephoneNumber" */
@@ -3889,6 +3995,7 @@ static const unsigned int ln_objs[NUM_LN]={
40, /* "rc2-ofb" */
5, /* "rc4" */
97, /* "rc4-40" */
+915, /* "rc4-hmac-md5" */
120, /* "rc5-cbc" */
122, /* "rc5-cfb" */
121, /* "rc5-ecb" */
@@ -3905,6 +4012,8 @@ static const unsigned int ln_objs[NUM_LN]={
6, /* "rsaEncryption" */
644, /* "rsaOAEPEncryptionSET" */
377, /* "rsaSignature" */
+919, /* "rsaesOaep" */
+912, /* "rsassaPss" */
124, /* "run length compression" */
482, /* "sOARecord" */
155, /* "safeContentsBag" */
@@ -4254,6 +4363,7 @@ static const unsigned int obj_objs[NUM_OBJ]={
96, /* OBJ_mdc2WithRSA 2 5 8 3 100 */
95, /* OBJ_mdc2 2 5 8 3 101 */
746, /* OBJ_any_policy 2 5 29 32 0 */
+910, /* OBJ_anyExtendedKeyUsage 2 5 29 37 0 */
519, /* OBJ_setct_PANData 2 23 42 0 0 */
520, /* OBJ_setct_PANToken 2 23 42 0 1 */
521, /* OBJ_setct_PANOnly 2 23 42 0 2 */
@@ -4720,6 +4830,9 @@ static const unsigned int obj_objs[NUM_OBJ]={
8, /* OBJ_md5WithRSAEncryption 1 2 840 113549 1 1 4 */
65, /* OBJ_sha1WithRSAEncryption 1 2 840 113549 1 1 5 */
644, /* OBJ_rsaOAEPEncryptionSET 1 2 840 113549 1 1 6 */
+919, /* OBJ_rsaesOaep 1 2 840 113549 1 1 7 */
+911, /* OBJ_mgf1 1 2 840 113549 1 1 8 */
+912, /* OBJ_rsassaPss 1 2 840 113549 1 1 10 */
668, /* OBJ_sha256WithRSAEncryption 1 2 840 113549 1 1 11 */
669, /* OBJ_sha384WithRSAEncryption 1 2 840 113549 1 1 12 */
670, /* OBJ_sha512WithRSAEncryption 1 2 840 113549 1 1 13 */
@@ -4785,16 +4898,25 @@ static const unsigned int obj_objs[NUM_OBJ]={
420, /* OBJ_aes_128_ofb128 2 16 840 1 101 3 4 1 3 */
421, /* OBJ_aes_128_cfb128 2 16 840 1 101 3 4 1 4 */
788, /* OBJ_id_aes128_wrap 2 16 840 1 101 3 4 1 5 */
+895, /* OBJ_aes_128_gcm 2 16 840 1 101 3 4 1 6 */
+896, /* OBJ_aes_128_ccm 2 16 840 1 101 3 4 1 7 */
+897, /* OBJ_id_aes128_wrap_pad 2 16 840 1 101 3 4 1 8 */
422, /* OBJ_aes_192_ecb 2 16 840 1 101 3 4 1 21 */
423, /* OBJ_aes_192_cbc 2 16 840 1 101 3 4 1 22 */
424, /* OBJ_aes_192_ofb128 2 16 840 1 101 3 4 1 23 */
425, /* OBJ_aes_192_cfb128 2 16 840 1 101 3 4 1 24 */
789, /* OBJ_id_aes192_wrap 2 16 840 1 101 3 4 1 25 */
+898, /* OBJ_aes_192_gcm 2 16 840 1 101 3 4 1 26 */
+899, /* OBJ_aes_192_ccm 2 16 840 1 101 3 4 1 27 */
+900, /* OBJ_id_aes192_wrap_pad 2 16 840 1 101 3 4 1 28 */
426, /* OBJ_aes_256_ecb 2 16 840 1 101 3 4 1 41 */
427, /* OBJ_aes_256_cbc 2 16 840 1 101 3 4 1 42 */
428, /* OBJ_aes_256_ofb128 2 16 840 1 101 3 4 1 43 */
429, /* OBJ_aes_256_cfb128 2 16 840 1 101 3 4 1 44 */
790, /* OBJ_id_aes256_wrap 2 16 840 1 101 3 4 1 45 */
+901, /* OBJ_aes_256_gcm 2 16 840 1 101 3 4 1 46 */
+902, /* OBJ_aes_256_ccm 2 16 840 1 101 3 4 1 47 */
+903, /* OBJ_id_aes256_wrap_pad 2 16 840 1 101 3 4 1 48 */
672, /* OBJ_sha256 2 16 840 1 101 3 4 2 1 */
673, /* OBJ_sha384 2 16 840 1 101 3 4 2 2 */
674, /* OBJ_sha512 2 16 840 1 101 3 4 2 3 */
@@ -4901,6 +5023,9 @@ static const unsigned int obj_objs[NUM_OBJ]={
751, /* OBJ_camellia_128_cbc 1 2 392 200011 61 1 1 1 2 */
752, /* OBJ_camellia_192_cbc 1 2 392 200011 61 1 1 1 3 */
753, /* OBJ_camellia_256_cbc 1 2 392 200011 61 1 1 1 4 */
+907, /* OBJ_id_camellia128_wrap 1 2 392 200011 61 1 1 3 2 */
+908, /* OBJ_id_camellia192_wrap 1 2 392 200011 61 1 1 3 3 */
+909, /* OBJ_id_camellia256_wrap 1 2 392 200011 61 1 1 3 4 */
196, /* OBJ_id_smime_mod_cms 1 2 840 113549 1 9 16 0 1 */
197, /* OBJ_id_smime_mod_ess 1 2 840 113549 1 9 16 0 2 */
198, /* OBJ_id_smime_mod_oid 1 2 840 113549 1 9 16 0 3 */
@@ -4956,6 +5081,7 @@ static const unsigned int obj_objs[NUM_OBJ]={
246, /* OBJ_id_smime_alg_CMS3DESwrap 1 2 840 113549 1 9 16 3 6 */
247, /* OBJ_id_smime_alg_CMSRC2wrap 1 2 840 113549 1 9 16 3 7 */
125, /* OBJ_zlib_compression 1 2 840 113549 1 9 16 3 8 */
+893, /* OBJ_id_alg_PWRI_KEK 1 2 840 113549 1 9 16 3 9 */
248, /* OBJ_id_smime_cd_ldap 1 2 840 113549 1 9 16 4 1 */
249, /* OBJ_id_smime_spq_ets_sqt_uri 1 2 840 113549 1 9 16 5 1 */
250, /* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */
diff --git a/deps/openssl/openssl/crypto/objects/obj_mac.h b/deps/openssl/openssl/crypto/objects/obj_mac.h
index 282f11a8a..b5ea7cdab 100644
--- a/deps/openssl/openssl/crypto/objects/obj_mac.h
+++ b/deps/openssl/openssl/crypto/objects/obj_mac.h
@@ -580,6 +580,21 @@
#define NID_sha1WithRSAEncryption 65
#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L
+#define SN_rsaesOaep "RSAES-OAEP"
+#define LN_rsaesOaep "rsaesOaep"
+#define NID_rsaesOaep 919
+#define OBJ_rsaesOaep OBJ_pkcs1,7L
+
+#define SN_mgf1 "MGF1"
+#define LN_mgf1 "mgf1"
+#define NID_mgf1 911
+#define OBJ_mgf1 OBJ_pkcs1,8L
+
+#define SN_rsassaPss "RSASSA-PSS"
+#define LN_rsassaPss "rsassaPss"
+#define NID_rsassaPss 912
+#define OBJ_rsassaPss OBJ_pkcs1,10L
+
#define SN_sha256WithRSAEncryption "RSA-SHA256"
#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption"
#define NID_sha256WithRSAEncryption 668
@@ -981,6 +996,10 @@
#define NID_id_smime_alg_CMSRC2wrap 247
#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L
+#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK"
+#define NID_id_alg_PWRI_KEK 893
+#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L
+
#define SN_id_smime_cd_ldap "id-smime-cd-ldap"
#define NID_id_smime_cd_ldap 248
#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L
@@ -2399,6 +2418,11 @@
#define NID_no_rev_avail 403
#define OBJ_no_rev_avail OBJ_id_ce,56L
+#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage"
+#define LN_anyExtendedKeyUsage "Any Extended Key Usage"
+#define NID_anyExtendedKeyUsage 910
+#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L
+
#define SN_netscape "Netscape"
#define LN_netscape "Netscape Communications Corp."
#define NID_netscape 57
@@ -2586,6 +2610,24 @@
#define NID_aes_128_cfb128 421
#define OBJ_aes_128_cfb128 OBJ_aes,4L
+#define SN_id_aes128_wrap "id-aes128-wrap"
+#define NID_id_aes128_wrap 788
+#define OBJ_id_aes128_wrap OBJ_aes,5L
+
+#define SN_aes_128_gcm "id-aes128-GCM"
+#define LN_aes_128_gcm "aes-128-gcm"
+#define NID_aes_128_gcm 895
+#define OBJ_aes_128_gcm OBJ_aes,6L
+
+#define SN_aes_128_ccm "id-aes128-CCM"
+#define LN_aes_128_ccm "aes-128-ccm"
+#define NID_aes_128_ccm 896
+#define OBJ_aes_128_ccm OBJ_aes,7L
+
+#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad"
+#define NID_id_aes128_wrap_pad 897
+#define OBJ_id_aes128_wrap_pad OBJ_aes,8L
+
#define SN_aes_192_ecb "AES-192-ECB"
#define LN_aes_192_ecb "aes-192-ecb"
#define NID_aes_192_ecb 422
@@ -2606,6 +2648,24 @@
#define NID_aes_192_cfb128 425
#define OBJ_aes_192_cfb128 OBJ_aes,24L
+#define SN_id_aes192_wrap "id-aes192-wrap"
+#define NID_id_aes192_wrap 789
+#define OBJ_id_aes192_wrap OBJ_aes,25L
+
+#define SN_aes_192_gcm "id-aes192-GCM"
+#define LN_aes_192_gcm "aes-192-gcm"
+#define NID_aes_192_gcm 898
+#define OBJ_aes_192_gcm OBJ_aes,26L
+
+#define SN_aes_192_ccm "id-aes192-CCM"
+#define LN_aes_192_ccm "aes-192-ccm"
+#define NID_aes_192_ccm 899
+#define OBJ_aes_192_ccm OBJ_aes,27L
+
+#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad"
+#define NID_id_aes192_wrap_pad 900
+#define OBJ_id_aes192_wrap_pad OBJ_aes,28L
+
#define SN_aes_256_ecb "AES-256-ECB"
#define LN_aes_256_ecb "aes-256-ecb"
#define NID_aes_256_ecb 426
@@ -2626,6 +2686,24 @@
#define NID_aes_256_cfb128 429
#define OBJ_aes_256_cfb128 OBJ_aes,44L
+#define SN_id_aes256_wrap "id-aes256-wrap"
+#define NID_id_aes256_wrap 790
+#define OBJ_id_aes256_wrap OBJ_aes,45L
+
+#define SN_aes_256_gcm "id-aes256-GCM"
+#define LN_aes_256_gcm "aes-256-gcm"
+#define NID_aes_256_gcm 901
+#define OBJ_aes_256_gcm OBJ_aes,46L
+
+#define SN_aes_256_ccm "id-aes256-CCM"
+#define LN_aes_256_ccm "aes-256-ccm"
+#define NID_aes_256_ccm 902
+#define OBJ_aes_256_ccm OBJ_aes,47L
+
+#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad"
+#define NID_id_aes256_wrap_pad 903
+#define OBJ_id_aes256_wrap_pad OBJ_aes,48L
+
#define SN_aes_128_cfb1 "AES-128-CFB1"
#define LN_aes_128_cfb1 "aes-128-cfb1"
#define NID_aes_128_cfb1 650
@@ -2650,6 +2728,26 @@
#define LN_aes_256_cfb8 "aes-256-cfb8"
#define NID_aes_256_cfb8 655
+#define SN_aes_128_ctr "AES-128-CTR"
+#define LN_aes_128_ctr "aes-128-ctr"
+#define NID_aes_128_ctr 904
+
+#define SN_aes_192_ctr "AES-192-CTR"
+#define LN_aes_192_ctr "aes-192-ctr"
+#define NID_aes_192_ctr 905
+
+#define SN_aes_256_ctr "AES-256-CTR"
+#define LN_aes_256_ctr "aes-256-ctr"
+#define NID_aes_256_ctr 906
+
+#define SN_aes_128_xts "AES-128-XTS"
+#define LN_aes_128_xts "aes-128-xts"
+#define NID_aes_128_xts 913
+
+#define SN_aes_256_xts "AES-256-XTS"
+#define LN_aes_256_xts "aes-256-xts"
+#define NID_aes_256_xts 914
+
#define SN_des_cfb1 "DES-CFB1"
#define LN_des_cfb1 "des-cfb1"
#define NID_des_cfb1 656
@@ -2666,18 +2764,6 @@
#define LN_des_ede3_cfb8 "des-ede3-cfb8"
#define NID_des_ede3_cfb8 659
-#define SN_id_aes128_wrap "id-aes128-wrap"
-#define NID_id_aes128_wrap 788
-#define OBJ_id_aes128_wrap OBJ_aes,5L
-
-#define SN_id_aes192_wrap "id-aes192-wrap"
-#define NID_id_aes192_wrap 789
-#define OBJ_id_aes192_wrap OBJ_aes,25L
-
-#define SN_id_aes256_wrap "id-aes256-wrap"
-#define NID_id_aes256_wrap 790
-#define OBJ_id_aes256_wrap OBJ_aes,45L
-
#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L
#define SN_sha256 "SHA256"
@@ -3810,6 +3896,18 @@
#define NID_camellia_256_cbc 753
#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L
+#define SN_id_camellia128_wrap "id-camellia128-wrap"
+#define NID_id_camellia128_wrap 907
+#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L
+
+#define SN_id_camellia192_wrap "id-camellia192-wrap"
+#define NID_id_camellia192_wrap 908
+#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L
+
+#define SN_id_camellia256_wrap "id-camellia256-wrap"
+#define NID_id_camellia256_wrap 909
+#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L
+
#define OBJ_ntt_ds 0L,3L,4401L,5L
#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L
@@ -3912,3 +4010,23 @@
#define LN_hmac "hmac"
#define NID_hmac 855
+#define SN_cmac "CMAC"
+#define LN_cmac "cmac"
+#define NID_cmac 894
+
+#define SN_rc4_hmac_md5 "RC4-HMAC-MD5"
+#define LN_rc4_hmac_md5 "rc4-hmac-md5"
+#define NID_rc4_hmac_md5 915
+
+#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1"
+#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1"
+#define NID_aes_128_cbc_hmac_sha1 916
+
+#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1"
+#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1"
+#define NID_aes_192_cbc_hmac_sha1 917
+
+#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1"
+#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1"
+#define NID_aes_256_cbc_hmac_sha1 918
+
diff --git a/deps/openssl/openssl/crypto/objects/obj_mac.num b/deps/openssl/openssl/crypto/objects/obj_mac.num
index 8c50aac27..1d0a7c802 100644
--- a/deps/openssl/openssl/crypto/objects/obj_mac.num
+++ b/deps/openssl/openssl/crypto/objects/obj_mac.num
@@ -890,3 +890,30 @@ houseIdentifier 889
supportedAlgorithms 890
deltaRevocationList 891
dmdName 892
+id_alg_PWRI_KEK 893
+cmac 894
+aes_128_gcm 895
+aes_128_ccm 896
+id_aes128_wrap_pad 897
+aes_192_gcm 898
+aes_192_ccm 899
+id_aes192_wrap_pad 900
+aes_256_gcm 901
+aes_256_ccm 902
+id_aes256_wrap_pad 903
+aes_128_ctr 904
+aes_192_ctr 905
+aes_256_ctr 906
+id_camellia128_wrap 907
+id_camellia192_wrap 908
+id_camellia256_wrap 909
+anyExtendedKeyUsage 910
+mgf1 911
+rsassaPss 912
+aes_128_xts 913
+aes_256_xts 914
+rc4_hmac_md5 915
+aes_128_cbc_hmac_sha1 916
+aes_192_cbc_hmac_sha1 917
+aes_256_cbc_hmac_sha1 918
+rsaesOaep 919
diff --git a/deps/openssl/openssl/crypto/objects/obj_xref.c b/deps/openssl/openssl/crypto/objects/obj_xref.c
index 152eca5c6..9f744bced 100644
--- a/deps/openssl/openssl/crypto/objects/obj_xref.c
+++ b/deps/openssl/openssl/crypto/objects/obj_xref.c
@@ -110,8 +110,10 @@ int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid)
#endif
if (rv == NULL)
return 0;
- *pdig_nid = rv->hash_id;
- *ppkey_nid = rv->pkey_id;
+ if (pdig_nid)
+ *pdig_nid = rv->hash_id;
+ if (ppkey_nid)
+ *ppkey_nid = rv->pkey_id;
return 1;
}
@@ -144,7 +146,8 @@ int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid)
#endif
if (rv == NULL)
return 0;
- *psignid = (*rv)->sign_id;
+ if (psignid)
+ *psignid = (*rv)->sign_id;
return 1;
}
diff --git a/deps/openssl/openssl/crypto/objects/obj_xref.h b/deps/openssl/openssl/crypto/objects/obj_xref.h
index d5b9b8e19..e23938c29 100644
--- a/deps/openssl/openssl/crypto/objects/obj_xref.h
+++ b/deps/openssl/openssl/crypto/objects/obj_xref.h
@@ -38,10 +38,12 @@ static const nid_triple sigoid_srt[] =
{NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, NID_id_GostR3410_94},
{NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, NID_id_GostR3410_94_cc},
{NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, NID_id_GostR3410_2001_cc},
+ {NID_rsassaPss, NID_undef, NID_rsaEncryption},
};
static const nid_triple * const sigoid_srt_xref[] =
{
+ &sigoid_srt[29],
&sigoid_srt[17],
&sigoid_srt[18],
&sigoid_srt[0],
diff --git a/deps/openssl/openssl/crypto/objects/obj_xref.txt b/deps/openssl/openssl/crypto/objects/obj_xref.txt
index e45b3d34b..cb917182e 100644
--- a/deps/openssl/openssl/crypto/objects/obj_xref.txt
+++ b/deps/openssl/openssl/crypto/objects/obj_xref.txt
@@ -13,6 +13,10 @@ sha512WithRSAEncryption sha512 rsaEncryption
sha224WithRSAEncryption sha224 rsaEncryption
mdc2WithRSA mdc2 rsaEncryption
ripemd160WithRSA ripemd160 rsaEncryption
+# For PSS the digest algorithm can vary and depends on the included
+# AlgorithmIdentifier. The digest "undef" indicates the public key
+# method should handle this explicitly.
+rsassaPss undef rsaEncryption
# Alternative deprecated OIDs. By using the older "rsa" OID this
# type will be recognized by not normally used.
diff --git a/deps/openssl/openssl/crypto/objects/objects.txt b/deps/openssl/openssl/crypto/objects/objects.txt
index e61fe60cb..d3bfad72a 100644
--- a/deps/openssl/openssl/crypto/objects/objects.txt
+++ b/deps/openssl/openssl/crypto/objects/objects.txt
@@ -166,6 +166,10 @@ pkcs1 3 : RSA-MD4 : md4WithRSAEncryption
pkcs1 4 : RSA-MD5 : md5WithRSAEncryption
pkcs1 5 : RSA-SHA1 : sha1WithRSAEncryption
# According to PKCS #1 version 2.1
+pkcs1 7 : RSAES-OAEP : rsaesOaep
+pkcs1 8 : MGF1 : mgf1
+pkcs1 10 : RSASSA-PSS : rsassaPss
+
pkcs1 11 : RSA-SHA256 : sha256WithRSAEncryption
pkcs1 12 : RSA-SHA384 : sha384WithRSAEncryption
pkcs1 13 : RSA-SHA512 : sha512WithRSAEncryption
@@ -299,6 +303,7 @@ id-smime-alg 4 : id-smime-alg-RC2wrap
id-smime-alg 5 : id-smime-alg-ESDH
id-smime-alg 6 : id-smime-alg-CMS3DESwrap
id-smime-alg 7 : id-smime-alg-CMSRC2wrap
+id-smime-alg 9 : id-alg-PWRI-KEK
# S/MIME Certificate Distribution
id-smime-cd 1 : id-smime-cd-ldap
@@ -770,6 +775,10 @@ id-ce 55 : targetInformation : X509v3 AC Targeting
!Cname no-rev-avail
id-ce 56 : noRevAvail : X509v3 No Revocation Available
+# From RFC5280
+ext-key-usage 0 : anyExtendedKeyUsage : Any Extended Key Usage
+
+
!Cname netscape
2 16 840 1 113730 : Netscape : Netscape Communications Corp.
!Cname netscape-cert-extension
@@ -846,6 +855,10 @@ aes 2 : AES-128-CBC : aes-128-cbc
aes 3 : AES-128-OFB : aes-128-ofb
!Cname aes-128-cfb128
aes 4 : AES-128-CFB : aes-128-cfb
+aes 5 : id-aes128-wrap
+aes 6 : id-aes128-GCM : aes-128-gcm
+aes 7 : id-aes128-CCM : aes-128-ccm
+aes 8 : id-aes128-wrap-pad
aes 21 : AES-192-ECB : aes-192-ecb
aes 22 : AES-192-CBC : aes-192-cbc
@@ -853,6 +866,10 @@ aes 22 : AES-192-CBC : aes-192-cbc
aes 23 : AES-192-OFB : aes-192-ofb
!Cname aes-192-cfb128
aes 24 : AES-192-CFB : aes-192-cfb
+aes 25 : id-aes192-wrap
+aes 26 : id-aes192-GCM : aes-192-gcm
+aes 27 : id-aes192-CCM : aes-192-ccm
+aes 28 : id-aes192-wrap-pad
aes 41 : AES-256-ECB : aes-256-ecb
aes 42 : AES-256-CBC : aes-256-cbc
@@ -860,6 +877,10 @@ aes 42 : AES-256-CBC : aes-256-cbc
aes 43 : AES-256-OFB : aes-256-ofb
!Cname aes-256-cfb128
aes 44 : AES-256-CFB : aes-256-cfb
+aes 45 : id-aes256-wrap
+aes 46 : id-aes256-GCM : aes-256-gcm
+aes 47 : id-aes256-CCM : aes-256-ccm
+aes 48 : id-aes256-wrap-pad
# There are no OIDs for these modes...
@@ -869,15 +890,16 @@ aes 44 : AES-256-CFB : aes-256-cfb
: AES-128-CFB8 : aes-128-cfb8
: AES-192-CFB8 : aes-192-cfb8
: AES-256-CFB8 : aes-256-cfb8
+ : AES-128-CTR : aes-128-ctr
+ : AES-192-CTR : aes-192-ctr
+ : AES-256-CTR : aes-256-ctr
+ : AES-128-XTS : aes-128-xts
+ : AES-256-XTS : aes-256-xts
: DES-CFB1 : des-cfb1
: DES-CFB8 : des-cfb8
: DES-EDE3-CFB1 : des-ede3-cfb1
: DES-EDE3-CFB8 : des-ede3-cfb8
-aes 5 : id-aes128-wrap
-aes 25 : id-aes192-wrap
-aes 45 : id-aes256-wrap
-
# OIDs for SHA224, SHA256, SHA385 and SHA512, according to x9.84.
!Alias nist_hashalgs nistAlgorithms 2
nist_hashalgs 1 : SHA256 : sha256
@@ -1211,6 +1233,9 @@ cryptocom 1 8 1 : id-GostR3410-2001-ParamSet-cc : GOST R 3410-2001 Parameter Se
1 2 392 200011 61 1 1 1 2 : CAMELLIA-128-CBC : camellia-128-cbc
1 2 392 200011 61 1 1 1 3 : CAMELLIA-192-CBC : camellia-192-cbc
1 2 392 200011 61 1 1 1 4 : CAMELLIA-256-CBC : camellia-256-cbc
+1 2 392 200011 61 1 1 3 2 : id-camellia128-wrap
+1 2 392 200011 61 1 1 3 3 : id-camellia192-wrap
+1 2 392 200011 61 1 1 3 4 : id-camellia256-wrap
# Definitions for Camellia cipher - ECB, CFB, OFB MODE
@@ -1257,3 +1282,11 @@ kisa 1 6 : SEED-OFB : seed-ofb
# There is no OID that just denotes "HMAC" oddly enough...
: HMAC : hmac
+# Nor CMAC either
+ : CMAC : cmac
+
+# Synthetic composite ciphersuites
+ : RC4-HMAC-MD5 : rc4-hmac-md5
+ : AES-128-CBC-HMAC-SHA1 : aes-128-cbc-hmac-sha1
+ : AES-192-CBC-HMAC-SHA1 : aes-192-cbc-hmac-sha1
+ : AES-256-CBC-HMAC-SHA1 : aes-256-cbc-hmac-sha1
diff --git a/deps/openssl/openssl/crypto/ocsp/ocsp_lib.c b/deps/openssl/openssl/crypto/ocsp/ocsp_lib.c
index e92b86c06..a94dc838e 100644
--- a/deps/openssl/openssl/crypto/ocsp/ocsp_lib.c
+++ b/deps/openssl/openssl/crypto/ocsp/ocsp_lib.c
@@ -124,7 +124,8 @@ OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) goto err;
/* Calculate the issuerKey hash, excluding tag and length */
- EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL);
+ if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL))
+ goto err;
if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) goto err;
diff --git a/deps/openssl/openssl/crypto/ocsp/ocsp_vfy.c b/deps/openssl/openssl/crypto/ocsp/ocsp_vfy.c
index 415d67e61..276718304 100644
--- a/deps/openssl/openssl/crypto/ocsp/ocsp_vfy.c
+++ b/deps/openssl/openssl/crypto/ocsp/ocsp_vfy.c
@@ -91,9 +91,12 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
{
EVP_PKEY *skey;
skey = X509_get_pubkey(signer);
- ret = OCSP_BASICRESP_verify(bs, skey, 0);
- EVP_PKEY_free(skey);
- if(ret <= 0)
+ if (skey)
+ {
+ ret = OCSP_BASICRESP_verify(bs, skey, 0);
+ EVP_PKEY_free(skey);
+ }
+ if(!skey || ret <= 0)
{
OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
goto end;
@@ -108,6 +111,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs);
if(!init_res)
{
+ ret = -1;
OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB);
goto end;
}
diff --git a/deps/openssl/openssl/crypto/opensslconf.h b/deps/openssl/openssl/crypto/opensslconf.h
new file mode 100644
index 000000000..76c99d433
--- /dev/null
+++ b/deps/openssl/openssl/crypto/opensslconf.h
@@ -0,0 +1 @@
+#include "../../config/opensslconf.h"
diff --git a/deps/openssl/openssl/crypto/opensslv.h b/deps/openssl/openssl/crypto/opensslv.h
index d6d61a0c7..5bc8e53e6 100644
--- a/deps/openssl/openssl/crypto/opensslv.h
+++ b/deps/openssl/openssl/crypto/opensslv.h
@@ -25,11 +25,11 @@
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
-#define OPENSSL_VERSION_NUMBER 0x1000006fL
+#define OPENSSL_VERSION_NUMBER 0x1000105fL
#ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0f-fips 4 Jan 2012"
+#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1e-fips 11 Feb 2013"
#else
-#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0f 4 Jan 2012"
+#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1e 11 Feb 2013"
#endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
diff --git a/deps/openssl/openssl/crypto/ossl_typ.h b/deps/openssl/openssl/crypto/ossl_typ.h
index 12bd7014d..ea9227f6f 100644
--- a/deps/openssl/openssl/crypto/ossl_typ.h
+++ b/deps/openssl/openssl/crypto/ossl_typ.h
@@ -91,10 +91,12 @@ typedef struct asn1_string_st ASN1_TIME;
typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
typedef struct asn1_string_st ASN1_VISIBLESTRING;
typedef struct asn1_string_st ASN1_UTF8STRING;
+typedef struct asn1_string_st ASN1_STRING;
typedef int ASN1_BOOLEAN;
typedef int ASN1_NULL;
#endif
+typedef struct ASN1_ITEM_st ASN1_ITEM;
typedef struct asn1_pctx_st ASN1_PCTX;
#ifdef OPENSSL_SYS_WIN32
diff --git a/deps/openssl/openssl/crypto/pariscid.pl b/deps/openssl/openssl/crypto/pariscid.pl
new file mode 100644
index 000000000..477ec9b87
--- /dev/null
+++ b/deps/openssl/openssl/crypto/pariscid.pl
@@ -0,0 +1,224 @@
+#!/usr/bin/env perl
+
+$flavour = shift;
+$output = shift;
+open STDOUT,">$output";
+
+if ($flavour =~ /64/) {
+ $LEVEL ="2.0W";
+ $SIZE_T =8;
+ $ST ="std";
+} else {
+ $LEVEL ="1.1";
+ $SIZE_T =4;
+ $ST ="stw";
+}
+
+$rp="%r2";
+$sp="%r30";
+$rv="%r28";
+
+$code=<<___;
+ .LEVEL $LEVEL
+ .SPACE \$TEXT\$
+ .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
+
+ .EXPORT OPENSSL_cpuid_setup,ENTRY
+ .ALIGN 8
+OPENSSL_cpuid_setup
+ .PROC
+ .CALLINFO NO_CALLS
+ .ENTRY
+ bv ($rp)
+ .EXIT
+ nop
+ .PROCEND
+
+ .EXPORT OPENSSL_rdtsc,ENTRY
+ .ALIGN 8
+OPENSSL_rdtsc
+ .PROC
+ .CALLINFO NO_CALLS
+ .ENTRY
+ mfctl %cr16,$rv
+ bv ($rp)
+ .EXIT
+ nop
+ .PROCEND
+
+ .EXPORT OPENSSL_wipe_cpu,ENTRY
+ .ALIGN 8
+OPENSSL_wipe_cpu
+ .PROC
+ .CALLINFO NO_CALLS
+ .ENTRY
+ xor %r0,%r0,%r1
+ fcpy,dbl %fr0,%fr4
+ xor %r0,%r0,%r19
+ fcpy,dbl %fr0,%fr5
+ xor %r0,%r0,%r20
+ fcpy,dbl %fr0,%fr6
+ xor %r0,%r0,%r21
+ fcpy,dbl %fr0,%fr7
+ xor %r0,%r0,%r22
+ fcpy,dbl %fr0,%fr8
+ xor %r0,%r0,%r23
+ fcpy,dbl %fr0,%fr9
+ xor %r0,%r0,%r24
+ fcpy,dbl %fr0,%fr10
+ xor %r0,%r0,%r25
+ fcpy,dbl %fr0,%fr11
+ xor %r0,%r0,%r26
+ fcpy,dbl %fr0,%fr22
+ xor %r0,%r0,%r29
+ fcpy,dbl %fr0,%fr23
+ xor %r0,%r0,%r31
+ fcpy,dbl %fr0,%fr24
+ fcpy,dbl %fr0,%fr25
+ fcpy,dbl %fr0,%fr26
+ fcpy,dbl %fr0,%fr27
+ fcpy,dbl %fr0,%fr28
+ fcpy,dbl %fr0,%fr29
+ fcpy,dbl %fr0,%fr30
+ fcpy,dbl %fr0,%fr31
+ bv ($rp)
+ .EXIT
+ ldo 0($sp),$rv
+ .PROCEND
+___
+{
+my $inp="%r26";
+my $len="%r25";
+
+$code.=<<___;
+ .EXPORT OPENSSL_cleanse,ENTRY,ARGW0=GR,ARGW1=GR
+ .ALIGN 8
+OPENSSL_cleanse
+ .PROC
+ .CALLINFO NO_CALLS
+ .ENTRY
+ cmpib,*= 0,$len,Ldone
+ nop
+ cmpib,*>>= 15,$len,Little
+ ldi $SIZE_T-1,%r1
+
+Lalign
+ and,*<> $inp,%r1,%r28
+ b,n Laligned
+ stb %r0,0($inp)
+ ldo -1($len),$len
+ b Lalign
+ ldo 1($inp),$inp
+
+Laligned
+ andcm $len,%r1,%r28
+Lot
+ $ST %r0,0($inp)
+ addib,*<> -$SIZE_T,%r28,Lot
+ ldo $SIZE_T($inp),$inp
+
+ and,*<> $len,%r1,$len
+ b,n Ldone
+Little
+ stb %r0,0($inp)
+ addib,*<> -1,$len,Little
+ ldo 1($inp),$inp
+Ldone
+ bv ($rp)
+ .EXIT
+ nop
+ .PROCEND
+___
+}
+{
+my ($out,$cnt,$max)=("%r26","%r25","%r24");
+my ($tick,$lasttick)=("%r23","%r22");
+my ($diff,$lastdiff)=("%r21","%r20");
+
+$code.=<<___;
+ .EXPORT OPENSSL_instrument_bus,ENTRY,ARGW0=GR,ARGW1=GR
+ .ALIGN 8
+OPENSSL_instrument_bus
+ .PROC
+ .CALLINFO NO_CALLS
+ .ENTRY
+ copy $cnt,$rv
+ mfctl %cr16,$tick
+ copy $tick,$lasttick
+ ldi 0,$diff
+
+ fdc 0($out)
+ ldw 0($out),$tick
+ add $diff,$tick,$tick
+ stw $tick,0($out)
+Loop
+ mfctl %cr16,$tick
+ sub $tick,$lasttick,$diff
+ copy $tick,$lasttick
+
+ fdc 0($out)
+ ldw 0($out),$tick
+ add $diff,$tick,$tick
+ stw $tick,0($out)
+
+ addib,<> -1,$cnt,Loop
+ addi 4,$out,$out
+
+ bv ($rp)
+ .EXIT
+ sub $rv,$cnt,$rv
+ .PROCEND
+
+ .EXPORT OPENSSL_instrument_bus2,ENTRY,ARGW0=GR,ARGW1=GR
+ .ALIGN 8
+OPENSSL_instrument_bus2
+ .PROC
+ .CALLINFO NO_CALLS
+ .ENTRY
+ copy $cnt,$rv
+ sub %r0,$cnt,$cnt
+
+ mfctl %cr16,$tick
+ copy $tick,$lasttick
+ ldi 0,$diff
+
+ fdc 0($out)
+ ldw 0($out),$tick
+ add $diff,$tick,$tick
+ stw $tick,0($out)
+
+ mfctl %cr16,$tick
+ sub $tick,$lasttick,$diff
+ copy $tick,$lasttick
+Loop2
+ copy $diff,$lastdiff
+ fdc 0($out)
+ ldw 0($out),$tick
+ add $diff,$tick,$tick
+ stw $tick,0($out)
+
+ addib,= -1,$max,Ldone2
+ nop
+
+ mfctl %cr16,$tick
+ sub $tick,$lasttick,$diff
+ copy $tick,$lasttick
+ cmpclr,<> $lastdiff,$diff,$tick
+ ldi 1,$tick
+
+ ldi 1,%r1
+ xor %r1,$tick,$tick
+ addb,<> $tick,$cnt,Loop2
+ shladd,l $tick,2,$out,$out
+Ldone2
+ bv ($rp)
+ .EXIT
+ add $rv,$cnt,$rv
+ .PROCEND
+___
+}
+$code =~ s/cmpib,\*/comib,/gm if ($SIZE_T==4);
+$code =~ s/,\*/,/gm if ($SIZE_T==4);
+print $code;
+close STDOUT;
+
diff --git a/deps/openssl/openssl/crypto/pem/pem_all.c b/deps/openssl/openssl/crypto/pem/pem_all.c
index 3e7a6093a..eac0460e3 100644
--- a/deps/openssl/openssl/crypto/pem/pem_all.c
+++ b/deps/openssl/openssl/crypto/pem/pem_all.c
@@ -193,7 +193,61 @@ RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
#endif
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
+ unsigned char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ if (FIPS_mode())
+ {
+ EVP_PKEY *k;
+ int ret;
+ k = EVP_PKEY_new();
+ if (!k)
+ return 0;
+ EVP_PKEY_set1_RSA(k, x);
+
+ ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+ EVP_PKEY_free(k);
+ return ret;
+ }
+ else
+ return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey,
+ PEM_STRING_RSA,bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
+ unsigned char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ if (FIPS_mode())
+ {
+ EVP_PKEY *k;
+ int ret;
+ k = EVP_PKEY_new();
+ if (!k)
+ return 0;
+
+ EVP_PKEY_set1_RSA(k, x);
+
+ ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+ EVP_PKEY_free(k);
+ return ret;
+ }
+ else
+ return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey,
+ PEM_STRING_RSA,fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
+
+#endif
+
IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
@@ -223,7 +277,59 @@ DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
}
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
+ unsigned char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ if (FIPS_mode())
+ {
+ EVP_PKEY *k;
+ int ret;
+ k = EVP_PKEY_new();
+ if (!k)
+ return 0;
+ EVP_PKEY_set1_DSA(k, x);
+
+ ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+ EVP_PKEY_free(k);
+ return ret;
+ }
+ else
+ return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey,
+ PEM_STRING_DSA,bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
+ unsigned char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ if (FIPS_mode())
+ {
+ EVP_PKEY *k;
+ int ret;
+ k = EVP_PKEY_new();
+ if (!k)
+ return 0;
+ EVP_PKEY_set1_DSA(k, x);
+ ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+ EVP_PKEY_free(k);
+ return ret;
+ }
+ else
+ return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey,
+ PEM_STRING_DSA,fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
+
+#endif
+
IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
#ifndef OPENSSL_NO_FP_API
@@ -269,8 +375,63 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)
+
+
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
+ unsigned char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ if (FIPS_mode())
+ {
+ EVP_PKEY *k;
+ int ret;
+ k = EVP_PKEY_new();
+ if (!k)
+ return 0;
+ EVP_PKEY_set1_EC_KEY(k, x);
+
+ ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+ EVP_PKEY_free(k);
+ return ret;
+ }
+ else
+ return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey,
+ PEM_STRING_ECPRIVATEKEY,
+ bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
+ unsigned char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ if (FIPS_mode())
+ {
+ EVP_PKEY *k;
+ int ret;
+ k = EVP_PKEY_new();
+ if (!k)
+ return 0;
+ EVP_PKEY_set1_EC_KEY(k, x);
+ ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+ EVP_PKEY_free(k);
+ return ret;
+ }
+ else
+ return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey,
+ PEM_STRING_ECPRIVATEKEY,
+ fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
+#endif
+
IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
#ifndef OPENSSL_NO_FP_API
diff --git a/deps/openssl/openssl/crypto/pem/pem_lib.c b/deps/openssl/openssl/crypto/pem/pem_lib.c
index cfc89a992..5a421fc4b 100644
--- a/deps/openssl/openssl/crypto/pem/pem_lib.c
+++ b/deps/openssl/openssl/crypto/pem/pem_lib.c
@@ -394,7 +394,8 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
goto err;
/* The 'iv' is used as the iv and as a salt. It is
* NOT taken from the BytesToKey function */
- EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL);
+ if (!EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL))
+ goto err;
if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);
@@ -406,12 +407,15 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
/* k=strlen(buf); */
EVP_CIPHER_CTX_init(&ctx);
- EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv);
- EVP_EncryptUpdate(&ctx,data,&j,data,i);
- EVP_EncryptFinal_ex(&ctx,&(data[j]),&i);
+ ret = 1;
+ if (!EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv)
+ || !EVP_EncryptUpdate(&ctx,data,&j,data,i)
+ || !EVP_EncryptFinal_ex(&ctx,&(data[j]),&i))
+ ret = 0;
EVP_CIPHER_CTX_cleanup(&ctx);
+ if (ret == 0)
+ goto err;
i+=j;
- ret=1;
}
else
{
@@ -459,14 +463,17 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
ebcdic2ascii(buf, buf, klen);
#endif
- EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
- (unsigned char *)buf,klen,1,key,NULL);
+ if (!EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
+ (unsigned char *)buf,klen,1,key,NULL))
+ return 0;
j=(int)len;
EVP_CIPHER_CTX_init(&ctx);
- EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
- EVP_DecryptUpdate(&ctx,data,&i,data,j);
- o=EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
+ o = EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
+ if (o)
+ o = EVP_DecryptUpdate(&ctx,data,&i,data,j);
+ if (o)
+ o = EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
EVP_CIPHER_CTX_cleanup(&ctx);
OPENSSL_cleanse((char *)buf,sizeof(buf));
OPENSSL_cleanse((char *)key,sizeof(key));
diff --git a/deps/openssl/openssl/crypto/pem/pem_seal.c b/deps/openssl/openssl/crypto/pem/pem_seal.c
index 59690b56a..b6b4e1349 100644
--- a/deps/openssl/openssl/crypto/pem/pem_seal.c
+++ b/deps/openssl/openssl/crypto/pem/pem_seal.c
@@ -96,7 +96,8 @@ int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
EVP_EncodeInit(&ctx->encode);
EVP_MD_CTX_init(&ctx->md);
- EVP_SignInit(&ctx->md,md_type);
+ if (!EVP_SignInit(&ctx->md,md_type))
+ goto err;
EVP_CIPHER_CTX_init(&ctx->cipher);
ret=EVP_SealInit(&ctx->cipher,type,ek,ekl,iv,pubk,npubk);
@@ -163,7 +164,8 @@ int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
goto err;
}
- EVP_EncryptFinal_ex(&ctx->cipher,s,(int *)&i);
+ if (!EVP_EncryptFinal_ex(&ctx->cipher,s,(int *)&i))
+ goto err;
EVP_EncodeUpdate(&ctx->encode,out,&j,s,i);
*outl=j;
out+=j;
diff --git a/deps/openssl/openssl/crypto/pem/pvkfmt.c b/deps/openssl/openssl/crypto/pem/pvkfmt.c
index 5f130c452..b1bf71a5d 100644
--- a/deps/openssl/openssl/crypto/pem/pvkfmt.c
+++ b/deps/openssl/openssl/crypto/pem/pvkfmt.c
@@ -709,13 +709,16 @@ static int derive_pvk_key(unsigned char *key,
const unsigned char *pass, int passlen)
{
EVP_MD_CTX mctx;
+ int rv = 1;
EVP_MD_CTX_init(&mctx);
- EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
- EVP_DigestUpdate(&mctx, salt, saltlen);
- EVP_DigestUpdate(&mctx, pass, passlen);
- EVP_DigestFinal_ex(&mctx, key, NULL);
+ if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL)
+ || !EVP_DigestUpdate(&mctx, salt, saltlen)
+ || !EVP_DigestUpdate(&mctx, pass, passlen)
+ || !EVP_DigestFinal_ex(&mctx, key, NULL))
+ rv = 0;
+
EVP_MD_CTX_cleanup(&mctx);
- return 1;
+ return rv;
}
@@ -727,11 +730,12 @@ static EVP_PKEY *do_PVK_body(const unsigned char **in,
const unsigned char *p = *in;
unsigned int magic;
unsigned char *enctmp = NULL, *q;
+ EVP_CIPHER_CTX cctx;
+ EVP_CIPHER_CTX_init(&cctx);
if (saltlen)
{
char psbuf[PEM_BUFSIZE];
unsigned char keybuf[20];
- EVP_CIPHER_CTX cctx;
int enctmplen, inlen;
if (cb)
inlen=cb(psbuf,PEM_BUFSIZE,0,u);
@@ -757,37 +761,41 @@ static EVP_PKEY *do_PVK_body(const unsigned char **in,
p += 8;
inlen = keylen - 8;
q = enctmp + 8;
- EVP_CIPHER_CTX_init(&cctx);
- EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
- EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
- EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen);
+ if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
+ goto err;
+ if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
+ goto err;
+ if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
+ goto err;
magic = read_ledword((const unsigned char **)&q);
if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
{
q = enctmp + 8;
memset(keybuf + 5, 0, 11);
- EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
- NULL);
+ if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
+ NULL))
+ goto err;
OPENSSL_cleanse(keybuf, 20);
- EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
- EVP_DecryptFinal_ex(&cctx, q + enctmplen,
- &enctmplen);
+ if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
+ goto err;
+ if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen,
+ &enctmplen))
+ goto err;
magic = read_ledword((const unsigned char **)&q);
if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
{
- EVP_CIPHER_CTX_cleanup(&cctx);
PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
goto err;
}
}
else
OPENSSL_cleanse(keybuf, 20);
- EVP_CIPHER_CTX_cleanup(&cctx);
p = enctmp;
}
ret = b2i_PrivateKey(&p, keylen);
err:
+ EVP_CIPHER_CTX_cleanup(&cctx);
if (enctmp && saltlen)
OPENSSL_free(enctmp);
return ret;
@@ -841,6 +849,8 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
{
int outlen = 24, pklen;
unsigned char *p, *salt = NULL;
+ EVP_CIPHER_CTX cctx;
+ EVP_CIPHER_CTX_init(&cctx);
if (enclevel)
outlen += PVK_SALTLEN;
pklen = do_i2b(NULL, pk, 0);
@@ -885,7 +895,6 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
{
char psbuf[PEM_BUFSIZE];
unsigned char keybuf[20];
- EVP_CIPHER_CTX cctx;
int enctmplen, inlen;
if (cb)
inlen=cb(psbuf,PEM_BUFSIZE,1,u);
@@ -902,16 +911,19 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
if (enclevel == 1)
memset(keybuf + 5, 0, 11);
p = salt + PVK_SALTLEN + 8;
- EVP_CIPHER_CTX_init(&cctx);
- EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
+ if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
+ goto error;
OPENSSL_cleanse(keybuf, 20);
- EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8);
- EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen);
- EVP_CIPHER_CTX_cleanup(&cctx);
+ if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8))
+ goto error;
+ if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen))
+ goto error;
}
+ EVP_CIPHER_CTX_cleanup(&cctx);
return outlen;
error:
+ EVP_CIPHER_CTX_cleanup(&cctx);
return -1;
}
diff --git a/deps/openssl/openssl/crypto/perlasm/cbc.pl b/deps/openssl/openssl/crypto/perlasm/cbc.pl
index 6fc251090..24561e759 100644
--- a/deps/openssl/openssl/crypto/perlasm/cbc.pl
+++ b/deps/openssl/openssl/crypto/perlasm/cbc.pl
@@ -150,7 +150,7 @@ sub cbc
&set_label("PIC_point");
&blindpop("edx");
&lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx"));
- &mov($count,&DWP(0,"ecx",$count,4))
+ &mov($count,&DWP(0,"ecx",$count,4));
&add($count,"edx");
&xor("ecx","ecx");
&xor("edx","edx");
diff --git a/deps/openssl/openssl/crypto/perlasm/ppc-xlate.pl b/deps/openssl/openssl/crypto/perlasm/ppc-xlate.pl
index 4579671c9..a3edd982b 100644..100755
--- a/deps/openssl/openssl/crypto/perlasm/ppc-xlate.pl
+++ b/deps/openssl/openssl/crypto/perlasm/ppc-xlate.pl
@@ -31,10 +31,9 @@ my $globl = sub {
$ret .= ".type $name,\@function";
last;
};
- /linux.*64/ && do { $ret .= ".globl .$name\n";
- $ret .= ".type .$name,\@function\n";
+ /linux.*64/ && do { $ret .= ".globl $name\n";
+ $ret .= ".type $name,\@function\n";
$ret .= ".section \".opd\",\"aw\"\n";
- $ret .= ".globl $name\n";
$ret .= ".align 3\n";
$ret .= "$name:\n";
$ret .= ".quad .$name,.TOC.\@tocbase,0\n";
@@ -62,6 +61,14 @@ my $machine = sub {
}
".machine $arch";
};
+my $size = sub {
+ if ($flavour =~ /linux.*32/)
+ { shift;
+ ".size " . join(",",@_);
+ }
+ else
+ { ""; }
+};
my $asciz = sub {
shift;
my $line = join(",",@_);
diff --git a/deps/openssl/openssl/crypto/perlasm/x86_64-xlate.pl b/deps/openssl/openssl/crypto/perlasm/x86_64-xlate.pl
index 674da3b7e..56d9b64b6 100755
--- a/deps/openssl/openssl/crypto/perlasm/x86_64-xlate.pl
+++ b/deps/openssl/openssl/crypto/perlasm/x86_64-xlate.pl
@@ -62,12 +62,8 @@ my $flavour = shift;
my $output = shift;
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-{ my ($stddev,$stdino,@junk)=stat(STDOUT);
- my ($outdev,$outino,@junk)=stat($output);
-
- open STDOUT,">$output" || die "can't open $output: $!"
- if ($stddev!=$outdev || $stdino!=$outino);
-}
+open STDOUT,">$output" || die "can't open $output: $!"
+ if (defined($output));
my $gas=1; $gas=0 if ($output =~ /\.asm$/);
my $elf=1; $elf=0 if (!$gas);
@@ -116,12 +112,16 @@ my %globals;
$line = substr($line,@+[0]); $line =~ s/^\s+//;
undef $self->{sz};
- if ($self->{op} =~ /^(movz)b.*/) { # movz is pain...
+ if ($self->{op} =~ /^(movz)x?([bw]).*/) { # movz is pain...
$self->{op} = $1;
- $self->{sz} = "b";
+ $self->{sz} = $2;
} elsif ($self->{op} =~ /call|jmp/) {
$self->{sz} = "";
- } elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op)/) { # SSEn
+ } elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op|insrw)/) { # SSEn
+ $self->{sz} = "";
+ } elsif ($self->{op} =~ /^v/) { # VEX
+ $self->{sz} = "";
+ } elsif ($self->{op} =~ /movq/ && $line =~ /%xmm/) {
$self->{sz} = "";
} elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) {
$self->{op} = $1;
@@ -246,35 +246,39 @@ my %globals;
$self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
$self->{base} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
+ # Solaris /usr/ccs/bin/as can't handle multiplications
+ # in $self->{label}, new gas requires sign extension...
+ use integer;
+ $self->{label} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
+ $self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
+ $self->{label} =~ s/([0-9]+)/$1<<32>>32/eg;
+
if ($gas) {
- # Solaris /usr/ccs/bin/as can't handle multiplications
- # in $self->{label}, new gas requires sign extension...
- use integer;
- $self->{label} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
- $self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
- $self->{label} =~ s/([0-9]+)/$1<<32>>32/eg;
$self->{label} =~ s/^___imp_/__imp__/ if ($flavour eq "mingw64");
if (defined($self->{index})) {
- sprintf "%s%s(%%%s,%%%s,%d)",$self->{asterisk},
- $self->{label},$self->{base},
+ sprintf "%s%s(%s,%%%s,%d)",$self->{asterisk},
+ $self->{label},
+ $self->{base}?"%$self->{base}":"",
$self->{index},$self->{scale};
} else {
sprintf "%s%s(%%%s)", $self->{asterisk},$self->{label},$self->{base};
}
} else {
- %szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR", l=>"DWORD$PTR", q=>"QWORD$PTR" );
+ %szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR", l=>"DWORD$PTR",
+ q=>"QWORD$PTR",o=>"OWORD$PTR",x=>"XMMWORD$PTR" );
$self->{label} =~ s/\./\$/g;
$self->{label} =~ s/(?<![\w\$\.])0x([0-9a-f]+)/0$1h/ig;
$self->{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/);
- $sz="q" if ($self->{asterisk});
+ $sz="q" if ($self->{asterisk} || opcode->mnemonic() eq "movq");
+ $sz="l" if (opcode->mnemonic() eq "movd");
if (defined($self->{index})) {
- sprintf "%s[%s%s*%d+%s]",$szmap{$sz},
+ sprintf "%s[%s%s*%d%s]",$szmap{$sz},
$self->{label}?"$self->{label}+":"",
$self->{index},$self->{scale},
- $self->{base};
+ $self->{base}?"+$self->{base}":"";
} elsif ($self->{base} eq "rip") {
sprintf "%s[%s]",$szmap{$sz},$self->{label};
} else {
@@ -506,6 +510,12 @@ my %globals;
}
} elsif ($dir =~ /\.(text|data)/) {
$current_segment=".$1";
+ } elsif ($dir =~ /\.hidden/) {
+ if ($flavour eq "macosx") { $self->{value} = ".private_extern\t$prefix$line"; }
+ elsif ($flavour eq "mingw64") { $self->{value} = ""; }
+ } elsif ($dir =~ /\.comm/) {
+ $self->{value} = "$dir\t$prefix$line";
+ $self->{value} =~ s|,([0-9]+),([0-9]+)$|",$1,".log($2)/log(2)|e if ($flavour eq "macosx");
}
$line = "";
return $self;
@@ -578,7 +588,7 @@ my %globals;
$self->{value}="${decor}SEH_end_$current_function->{name}:";
$self->{value}.=":\n" if($masm);
}
- $self->{value}.="$current_function->{name}\tENDP" if($masm);
+ $self->{value}.="$current_function->{name}\tENDP" if($masm && $current_function->{name});
undef $current_function;
}
last;
@@ -614,6 +624,19 @@ my %globals;
.join(",",@str) if (@str);
last;
};
+ /\.comm/ && do { my @str=split(/,\s*/,$line);
+ my $v=undef;
+ if ($nasm) {
+ $v.="common $prefix@str[0] @str[1]";
+ } else {
+ $v="$current_segment\tENDS\n" if ($current_segment);
+ $current_segment = "_DATA";
+ $v.="$current_segment\tSEGMENT\n";
+ $v.="COMM @str[0]:DWORD:".@str[1]/4;
+ }
+ $self->{value} = $v;
+ last;
+ };
}
$line = "";
}
@@ -626,9 +649,133 @@ my %globals;
}
}
+sub rex {
+ local *opcode=shift;
+ my ($dst,$src,$rex)=@_;
+
+ $rex|=0x04 if($dst>=8);
+ $rex|=0x01 if($src>=8);
+ push @opcode,($rex|0x40) if ($rex);
+}
+
+# older gas and ml64 don't handle SSE>2 instructions
+my %regrm = ( "%eax"=>0, "%ecx"=>1, "%edx"=>2, "%ebx"=>3,
+ "%esp"=>4, "%ebp"=>5, "%esi"=>6, "%edi"=>7 );
+
+my $movq = sub { # elderly gas can't handle inter-register movq
+ my $arg = shift;
+ my @opcode=(0x66);
+ if ($arg =~ /%xmm([0-9]+),\s*%r(\w+)/) {
+ my ($src,$dst)=($1,$2);
+ if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
+ rex(\@opcode,$src,$dst,0x8);
+ push @opcode,0x0f,0x7e;
+ push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M
+ @opcode;
+ } elsif ($arg =~ /%r(\w+),\s*%xmm([0-9]+)/) {
+ my ($src,$dst)=($2,$1);
+ if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
+ rex(\@opcode,$src,$dst,0x8);
+ push @opcode,0x0f,0x6e;
+ push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M
+ @opcode;
+ } else {
+ ();
+ }
+};
+
+my $pextrd = sub {
+ if (shift =~ /\$([0-9]+),\s*%xmm([0-9]+),\s*(%\w+)/) {
+ my @opcode=(0x66);
+ $imm=$1;
+ $src=$2;
+ $dst=$3;
+ if ($dst =~ /%r([0-9]+)d/) { $dst = $1; }
+ elsif ($dst =~ /%e/) { $dst = $regrm{$dst}; }
+ rex(\@opcode,$src,$dst);
+ push @opcode,0x0f,0x3a,0x16;
+ push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M
+ push @opcode,$imm;
+ @opcode;
+ } else {
+ ();
+ }
+};
+
+my $pinsrd = sub {
+ if (shift =~ /\$([0-9]+),\s*(%\w+),\s*%xmm([0-9]+)/) {
+ my @opcode=(0x66);
+ $imm=$1;
+ $src=$2;
+ $dst=$3;
+ if ($src =~ /%r([0-9]+)/) { $src = $1; }
+ elsif ($src =~ /%e/) { $src = $regrm{$src}; }
+ rex(\@opcode,$dst,$src);
+ push @opcode,0x0f,0x3a,0x22;
+ push @opcode,0xc0|(($dst&7)<<3)|($src&7); # ModR/M
+ push @opcode,$imm;
+ @opcode;
+ } else {
+ ();
+ }
+};
+
+my $pshufb = sub {
+ if (shift =~ /%xmm([0-9]+),\s*%xmm([0-9]+)/) {
+ my @opcode=(0x66);
+ rex(\@opcode,$2,$1);
+ push @opcode,0x0f,0x38,0x00;
+ push @opcode,0xc0|($1&7)|(($2&7)<<3); # ModR/M
+ @opcode;
+ } else {
+ ();
+ }
+};
+
+my $palignr = sub {
+ if (shift =~ /\$([0-9]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
+ my @opcode=(0x66);
+ rex(\@opcode,$3,$2);
+ push @opcode,0x0f,0x3a,0x0f;
+ push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M
+ push @opcode,$1;
+ @opcode;
+ } else {
+ ();
+ }
+};
+
+my $pclmulqdq = sub {
+ if (shift =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
+ my @opcode=(0x66);
+ rex(\@opcode,$3,$2);
+ push @opcode,0x0f,0x3a,0x44;
+ push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M
+ my $c=$1;
+ push @opcode,$c=~/^0/?oct($c):$c;
+ @opcode;
+ } else {
+ ();
+ }
+};
+
+my $rdrand = sub {
+ if (shift =~ /%[er](\w+)/) {
+ my @opcode=();
+ my $dst=$1;
+ if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
+ rex(\@opcode,0,$1,8);
+ push @opcode,0x0f,0xc7,0xf0|($dst&7);
+ @opcode;
+ } else {
+ ();
+ }
+};
+
if ($nasm) {
print <<___;
default rel
+%define XMMWORD
___
} elsif ($masm) {
print <<___;
@@ -645,14 +792,22 @@ while($line=<>) {
undef $label;
undef $opcode;
- undef $sz;
undef @args;
if ($label=label->re(\$line)) { print $label->out(); }
if (directive->re(\$line)) {
printf "%s",directive->out();
- } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: while (1) {
+ } elsif ($opcode=opcode->re(\$line)) {
+ my $asm = eval("\$".$opcode->mnemonic());
+ undef @bytes;
+
+ if ((ref($asm) eq 'CODE') && scalar(@bytes=&$asm($line))) {
+ print $gas?".byte\t":"DB\t",join(',',@bytes),"\n";
+ next;
+ }
+
+ ARGUMENT: while (1) {
my $arg;
if ($arg=register->re(\$line)) { opcode->size($arg->size()); }
@@ -668,19 +823,26 @@ while($line=<>) {
$line =~ s/^,\s*//;
} # ARGUMENT:
- $sz=opcode->size();
-
if ($#args>=0) {
my $insn;
+ my $sz=opcode->size();
+
if ($gas) {
$insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
+ @args = map($_->out($sz),@args);
+ printf "\t%s\t%s",$insn,join(",",@args);
} else {
$insn = $opcode->out();
- $insn .= $sz if (map($_->out() =~ /x?mm/,@args));
+ foreach (@args) {
+ my $arg = $_->out();
+ # $insn.=$sz compensates for movq, pinsrw, ...
+ if ($arg =~ /^xmm[0-9]+$/) { $insn.=$sz; $sz="x" if(!$sz); last; }
+ if ($arg =~ /^mm[0-9]+$/) { $insn.=$sz; $sz="q" if(!$sz); last; }
+ }
@args = reverse(@args);
undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
+ printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
}
- printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
} else {
printf "\t%s",$opcode->out();
}
diff --git a/deps/openssl/openssl/crypto/perlasm/x86asm.pl b/deps/openssl/openssl/crypto/perlasm/x86asm.pl
index 28080caaa..eb543db2f 100644
--- a/deps/openssl/openssl/crypto/perlasm/x86asm.pl
+++ b/deps/openssl/openssl/crypto/perlasm/x86asm.pl
@@ -80,6 +80,57 @@ sub ::movq
{ &::generic("movq",@_); }
}
+# SSE>2 instructions
+my %regrm = ( "eax"=>0, "ecx"=>1, "edx"=>2, "ebx"=>3,
+ "esp"=>4, "ebp"=>5, "esi"=>6, "edi"=>7 );
+sub ::pextrd
+{ my($dst,$src,$imm)=@_;
+ if ("$dst:$src" =~ /(e[a-dsd][ixp]):xmm([0-7])/)
+ { &::data_byte(0x66,0x0f,0x3a,0x16,0xc0|($2<<3)|$regrm{$1},$imm); }
+ else
+ { &::generic("pextrd",@_); }
+}
+
+sub ::pinsrd
+{ my($dst,$src,$imm)=@_;
+ if ("$dst:$src" =~ /xmm([0-7]):(e[a-dsd][ixp])/)
+ { &::data_byte(0x66,0x0f,0x3a,0x22,0xc0|($1<<3)|$regrm{$2},$imm); }
+ else
+ { &::generic("pinsrd",@_); }
+}
+
+sub ::pshufb
+{ my($dst,$src)=@_;
+ if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
+ { &data_byte(0x66,0x0f,0x38,0x00,0xc0|($1<<3)|$2); }
+ else
+ { &::generic("pshufb",@_); }
+}
+
+sub ::palignr
+{ my($dst,$src,$imm)=@_;
+ if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
+ { &::data_byte(0x66,0x0f,0x3a,0x0f,0xc0|($1<<3)|$2,$imm); }
+ else
+ { &::generic("palignr",@_); }
+}
+
+sub ::pclmulqdq
+{ my($dst,$src,$imm)=@_;
+ if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
+ { &::data_byte(0x66,0x0f,0x3a,0x44,0xc0|($1<<3)|$2,$imm); }
+ else
+ { &::generic("pclmulqdq",@_); }
+}
+
+sub ::rdrand
+{ my ($dst)=@_;
+ if ($dst =~ /(e[a-dsd][ixp])/)
+ { &::data_byte(0x0f,0xc7,0xf0|$regrm{$dst}); }
+ else
+ { &::generic("rdrand",@_); }
+}
+
# label management
$lbdecor="L"; # local label decoration, set by package
$label="000";
@@ -167,7 +218,7 @@ sub ::asm_init
$filename=$fn;
$i386=$cpu;
- $elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=0;
+ $elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=$android=0;
if (($type eq "elf"))
{ $elf=1; require "x86gas.pl"; }
elsif (($type eq "a\.out"))
@@ -184,6 +235,8 @@ sub ::asm_init
{ $win32=1; require "x86masm.pl"; }
elsif (($type eq "macosx"))
{ $aout=1; $macosx=1; require "x86gas.pl"; }
+ elsif (($type eq "android"))
+ { $elf=1; $android=1; require "x86gas.pl"; }
else
{ print STDERR <<"EOF";
Pick one target type from
diff --git a/deps/openssl/openssl/crypto/perlasm/x86gas.pl b/deps/openssl/openssl/crypto/perlasm/x86gas.pl
index 6eab727fd..682a3a316 100644
--- a/deps/openssl/openssl/crypto/perlasm/x86gas.pl
+++ b/deps/openssl/openssl/crypto/perlasm/x86gas.pl
@@ -45,9 +45,8 @@ sub ::generic
undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o);
if ($#_==0) { &::emit($opcode); }
- elsif ($opcode =~ m/^j/o && $#_==1) { &::emit($opcode,@arg); }
- elsif ($opcode eq "call" && $#_==1) { &::emit($opcode,@arg); }
- elsif ($opcode =~ m/^set/&& $#_==1) { &::emit($opcode,@arg); }
+ elsif ($#_==1 && $opcode =~ m/^(call|clflush|j|loop|set)/o)
+ { &::emit($opcode,@arg); }
else { &::emit($opcode.$suffix,@arg);}
1;
@@ -91,6 +90,7 @@ sub ::DWP
}
sub ::QWP { &::DWP(@_); }
sub ::BP { &::DWP(@_); }
+sub ::WP { &::DWP(@_); }
sub ::BC { @_; }
sub ::DWC { @_; }
@@ -149,22 +149,24 @@ sub ::public_label
{ push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n"); }
sub ::file_end
-{ if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
- my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,4";
- if ($::elf) { push (@out,"$tmp,4\n"); }
- else { push (@out,"$tmp\n"); }
- }
- if ($::macosx)
+{ if ($::macosx)
{ if (%non_lazy_ptr)
{ push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
foreach $i (keys %non_lazy_ptr)
{ push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n"); }
}
}
+ if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
+ my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,8";
+ if ($::macosx) { push (@out,"$tmp,2\n"); }
+ elsif ($::elf) { push (@out,"$tmp,4\n"); }
+ else { push (@out,"$tmp\n"); }
+ }
push(@out,$initseg) if ($initseg);
}
sub ::data_byte { push(@out,".byte\t".join(',',@_)."\n"); }
+sub ::data_short{ push(@out,".value\t".join(',',@_)."\n"); }
sub ::data_word { push(@out,".long\t".join(',',@_)."\n"); }
sub ::align
@@ -180,7 +182,7 @@ sub ::align
sub ::picmeup
{ my($dst,$sym,$base,$reflabel)=@_;
- if ($::pic && ($::elf || $::aout))
+ if (($::pic && ($::elf || $::aout)) || $::macosx)
{ if (!defined($base))
{ &::call(&::label("PIC_me_up"));
&::set_label("PIC_me_up");
@@ -206,13 +208,17 @@ sub ::picmeup
sub ::initseg
{ my $f=$nmdecor.shift;
- if ($::elf)
+ if ($::android)
+ { $initseg.=<<___;
+.section .init_array
+.align 4
+.long $f
+___
+ }
+ elsif ($::elf)
{ $initseg.=<<___;
.section .init
call $f
- jmp .Linitalign
-.align $align
-.Linitalign:
___
}
elsif ($::coff)
diff --git a/deps/openssl/openssl/crypto/perlasm/x86masm.pl b/deps/openssl/openssl/crypto/perlasm/x86masm.pl
index 7815b17c4..6b33b146f 100644
--- a/deps/openssl/openssl/crypto/perlasm/x86masm.pl
+++ b/deps/openssl/openssl/crypto/perlasm/x86masm.pl
@@ -14,9 +14,11 @@ sub ::generic
{ my ($opcode,@arg)=@_;
# fix hexadecimal constants
- for (@arg) { s/0x([0-9a-f]+)/0$1h/oi; }
+ for (@arg) { s/(?<![\w\$\.])0x([0-9a-f]+)/0$1h/oi; }
- if ($opcode !~ /movq/)
+ if ($opcode =~ /lea/ && @arg[1] =~ s/.*PTR\s+(\(.*\))$/OFFSET $1/) # no []
+ { $opcode="mov"; }
+ elsif ($opcode !~ /movq/)
{ # fix xmm references
$arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[1]=~/\bxmm[0-7]\b/i);
$arg[1] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[0]=~/\bxmm[0-7]\b/i);
@@ -31,6 +33,7 @@ sub ::generic
sub ::call { &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
sub ::call_ptr { &::emit("call",@_); }
sub ::jmp_ptr { &::emit("jmp",@_); }
+sub ::lock { &::data_byte(0xf0); }
sub get_mem
{ my($size,$addr,$reg1,$reg2,$idx)=@_;
@@ -65,6 +68,7 @@ sub get_mem
$ret;
}
sub ::BP { &get_mem("BYTE",@_); }
+sub ::WP { &get_mem("WORD",@_); }
sub ::DWP { &get_mem("DWORD",@_); }
sub ::QWP { &get_mem("QWORD",@_); }
sub ::BC { "@_"; }
@@ -76,7 +80,7 @@ TITLE $_[0].asm
IF \@Version LT 800
ECHO MASM version 8.00 or later is strongly recommended.
ENDIF
-.586
+.686
.MODEL FLAT
OPTION DOTNAME
IF \@Version LT 800
@@ -129,7 +133,7 @@ ___
if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
{ my $comm=<<___;
.bss SEGMENT 'BSS'
-COMM ${nmdecor}OPENSSL_ia32cap_P:DWORD
+COMM ${nmdecor}OPENSSL_ia32cap_P:QWORD
.bss ENDS
___
# comment out OPENSSL_ia32cap_P declarations
@@ -156,6 +160,9 @@ sub ::public_label
sub ::data_byte
{ push(@out,("DB\t").join(',',@_)."\n"); }
+sub ::data_short
+{ push(@out,("DW\t").join(',',@_)."\n"); }
+
sub ::data_word
{ push(@out,("DD\t").join(',',@_)."\n"); }
@@ -181,4 +188,11 @@ ___
sub ::dataseg
{ push(@out,"$segment\tENDS\n_DATA\tSEGMENT\n"); $segment="_DATA"; }
+sub ::safeseh
+{ my $nm=shift;
+ push(@out,"IF \@Version GE 710\n");
+ push(@out,".SAFESEH ".&::LABEL($nm,$nmdecor.$nm)."\n");
+ push(@out,"ENDIF\n");
+}
+
1;
diff --git a/deps/openssl/openssl/crypto/perlasm/x86nasm.pl b/deps/openssl/openssl/crypto/perlasm/x86nasm.pl
index ce2bed9bb..ca2511c9e 100644
--- a/deps/openssl/openssl/crypto/perlasm/x86nasm.pl
+++ b/deps/openssl/openssl/crypto/perlasm/x86nasm.pl
@@ -19,6 +19,8 @@ sub ::generic
{ $_[0] = "NEAR $_[0]"; }
elsif ($opcode eq "lea" && $#_==1) # wipe storage qualifier from lea
{ $_[1] =~ s/^[^\[]*\[/\[/o; }
+ elsif ($opcode eq "clflush" && $#_==0)
+ { $_[0] =~ s/^[^\[]*\[/\[/o; }
}
&::emit($opcode,@_);
1;
@@ -67,6 +69,7 @@ sub get_mem
}
sub ::BP { &get_mem("BYTE",@_); }
sub ::DWP { &get_mem("DWORD",@_); }
+sub ::WP { &get_mem("WORD",@_); }
sub ::QWP { &get_mem("",@_); }
sub ::BC { (($::mwerks)?"":"BYTE ")."@_"; }
sub ::DWC { (($::mwerks)?"":"DWORD ")."@_"; }
@@ -114,7 +117,7 @@ sub ::file_end
{ if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
{ my $comm=<<___;
${drdecor}segment .bss
-${drdecor}common ${nmdecor}OPENSSL_ia32cap_P 4
+${drdecor}common ${nmdecor}OPENSSL_ia32cap_P 8
___
# comment out OPENSSL_ia32cap_P declarations
grep {s/(^extern\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
@@ -135,7 +138,8 @@ sub ::public_label
sub ::data_byte
{ push(@out,(($::mwerks)?".byte\t":"db\t").join(',',@_)."\n"); }
-
+sub ::data_short
+{ push(@out,(($::mwerks)?".word\t":"dw\t").join(',',@_)."\n"); }
sub ::data_word
{ push(@out,(($::mwerks)?".long\t":"dd\t").join(',',@_)."\n"); }
@@ -163,4 +167,11 @@ sub ::dataseg
else { push(@out,"section\t.data align=4\n"); }
}
+sub ::safeseh
+{ my $nm=shift;
+ push(@out,"%if __NASM_VERSION_ID__ >= 0x02030000\n");
+ push(@out,"safeseh ".&::LABEL($nm,$nmdecor.$nm)."\n");
+ push(@out,"%endif\n");
+}
+
1;
diff --git a/deps/openssl/openssl/crypto/pkcs12/p12_decr.c b/deps/openssl/openssl/crypto/pkcs12/p12_decr.c
index ba77dbbe3..9d3557e8d 100644
--- a/deps/openssl/openssl/crypto/pkcs12/p12_decr.c
+++ b/deps/openssl/openssl/crypto/pkcs12/p12_decr.c
@@ -89,7 +89,14 @@ unsigned char * PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass,
goto err;
}
- EVP_CipherUpdate(&ctx, out, &i, in, inlen);
+ if (!EVP_CipherUpdate(&ctx, out, &i, in, inlen))
+ {
+ OPENSSL_free(out);
+ out = NULL;
+ PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,ERR_R_EVP_LIB);
+ goto err;
+ }
+
outlen = i;
if(!EVP_CipherFinal_ex(&ctx, out + i, &i)) {
OPENSSL_free(out);
diff --git a/deps/openssl/openssl/crypto/pkcs12/p12_key.c b/deps/openssl/openssl/crypto/pkcs12/p12_key.c
index 424203f64..61d58502f 100644
--- a/deps/openssl/openssl/crypto/pkcs12/p12_key.c
+++ b/deps/openssl/openssl/crypto/pkcs12/p12_key.c
@@ -152,14 +152,16 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
for (i = 0; i < Slen; i++) *p++ = salt[i % saltlen];
for (i = 0; i < Plen; i++) *p++ = pass[i % passlen];
for (;;) {
- EVP_DigestInit_ex(&ctx, md_type, NULL);
- EVP_DigestUpdate(&ctx, D, v);
- EVP_DigestUpdate(&ctx, I, Ilen);
- EVP_DigestFinal_ex(&ctx, Ai, NULL);
+ if (!EVP_DigestInit_ex(&ctx, md_type, NULL)
+ || !EVP_DigestUpdate(&ctx, D, v)
+ || !EVP_DigestUpdate(&ctx, I, Ilen)
+ || !EVP_DigestFinal_ex(&ctx, Ai, NULL))
+ goto err;
for (j = 1; j < iter; j++) {
- EVP_DigestInit_ex(&ctx, md_type, NULL);
- EVP_DigestUpdate(&ctx, Ai, u);
- EVP_DigestFinal_ex(&ctx, Ai, NULL);
+ if (!EVP_DigestInit_ex(&ctx, md_type, NULL)
+ || !EVP_DigestUpdate(&ctx, Ai, u)
+ || !EVP_DigestFinal_ex(&ctx, Ai, NULL))
+ goto err;
}
memcpy (out, Ai, min (n, u));
if (u >= n) {
@@ -174,24 +176,32 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
out += u;
for (j = 0; j < v; j++) B[j] = Ai[j % u];
/* Work out B + 1 first then can use B as tmp space */
- if (!BN_bin2bn (B, v, Bpl1)) goto err;
- if (!BN_add_word (Bpl1, 1)) goto err;
+ if (!BN_bin2bn (B, v, Bpl1))
+ goto err;
+ if (!BN_add_word (Bpl1, 1))
+ goto err;
for (j = 0; j < Ilen ; j+=v) {
- if (!BN_bin2bn (I + j, v, Ij)) goto err;
- if (!BN_add (Ij, Ij, Bpl1)) goto err;
- BN_bn2bin (Ij, B);
+ if (!BN_bin2bn(I + j, v, Ij))
+ goto err;
+ if (!BN_add(Ij, Ij, Bpl1))
+ goto err;
+ if (!BN_bn2bin(Ij, B))
+ goto err;
Ijlen = BN_num_bytes (Ij);
/* If more than 2^(v*8) - 1 cut off MSB */
if (Ijlen > v) {
- BN_bn2bin (Ij, B);
+ if (!BN_bn2bin (Ij, B))
+ goto err;
memcpy (I + j, B + 1, v);
#ifndef PKCS12_BROKEN_KEYGEN
/* If less than v bytes pad with zeroes */
} else if (Ijlen < v) {
memset(I + j, 0, v - Ijlen);
- BN_bn2bin(Ij, I + j + v - Ijlen);
+ if (!BN_bn2bin(Ij, I + j + v - Ijlen))
+ goto err;
#endif
- } else BN_bn2bin (Ij, I + j);
+ } else if (!BN_bn2bin (Ij, I + j))
+ goto err;
}
}
diff --git a/deps/openssl/openssl/crypto/pkcs12/p12_kiss.c b/deps/openssl/openssl/crypto/pkcs12/p12_kiss.c
index 292cc3ed4..206b1b0b1 100644
--- a/deps/openssl/openssl/crypto/pkcs12/p12_kiss.c
+++ b/deps/openssl/openssl/crypto/pkcs12/p12_kiss.c
@@ -167,7 +167,7 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
if (cert && *cert)
X509_free(*cert);
if (x)
- X509_free(*cert);
+ X509_free(x);
if (ocerts)
sk_X509_pop_free(ocerts, X509_free);
return 0;
diff --git a/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c b/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c
index 9ab740d51..96de1bd11 100644
--- a/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c
+++ b/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c
@@ -97,10 +97,14 @@ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
return 0;
}
HMAC_CTX_init(&hmac);
- HMAC_Init_ex(&hmac, key, md_size, md_type, NULL);
- HMAC_Update(&hmac, p12->authsafes->d.data->data,
- p12->authsafes->d.data->length);
- HMAC_Final(&hmac, mac, maclen);
+ if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL)
+ || !HMAC_Update(&hmac, p12->authsafes->d.data->data,
+ p12->authsafes->d.data->length)
+ || !HMAC_Final(&hmac, mac, maclen))
+ {
+ HMAC_CTX_cleanup(&hmac);
+ return 0;
+ }
HMAC_CTX_cleanup(&hmac);
return 1;
}
diff --git a/deps/openssl/openssl/crypto/pkcs7/bio_pk7.c b/deps/openssl/openssl/crypto/pkcs7/bio_pk7.c
index c8d06d6cd..0fd31e730 100644
--- a/deps/openssl/openssl/crypto/pkcs7/bio_pk7.c
+++ b/deps/openssl/openssl/crypto/pkcs7/bio_pk7.c
@@ -56,7 +56,7 @@
#include <openssl/pkcs7.h>
#include <openssl/bio.h>
-#ifndef OPENSSL_SYSNAME_NETWARE
+#if !defined(OPENSSL_SYSNAME_NETWARE) && !defined(OPENSSL_SYSNAME_VXWORKS)
#include <memory.h>
#endif
#include <stdio.h>
diff --git a/deps/openssl/openssl/crypto/pkcs7/pk7_doit.c b/deps/openssl/openssl/crypto/pkcs7/pk7_doit.c
index 3bf1a367b..77fda3b82 100644
--- a/deps/openssl/openssl/crypto/pkcs7/pk7_doit.c
+++ b/deps/openssl/openssl/crypto/pkcs7/pk7_doit.c
@@ -204,11 +204,11 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
unsigned char *ek = NULL;
size_t eklen;
- int ret = 0;
+ int ret = -1;
pctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!pctx)
- return 0;
+ return -1;
if (EVP_PKEY_decrypt_init(pctx) <= 0)
goto err;
@@ -235,12 +235,19 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
if (EVP_PKEY_decrypt(pctx, ek, &eklen,
ri->enc_key->data, ri->enc_key->length) <= 0)
{
+ ret = 0;
PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
goto err;
}
ret = 1;
+ if (*pek)
+ {
+ OPENSSL_cleanse(*pek, *peklen);
+ OPENSSL_free(*pek);
+ }
+
*pek = ek;
*peklen = eklen;
@@ -423,6 +430,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
STACK_OF(X509_ALGOR) *md_sk=NULL;
STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
PKCS7_RECIP_INFO *ri=NULL;
+ unsigned char *ek = NULL, *tkey = NULL;
+ int eklen = 0, tkeylen = 0;
i=OBJ_obj2nid(p7->type);
p7->state=PKCS7_S_HEADER;
@@ -500,8 +509,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
int max;
X509_OBJECT ret;
#endif
- unsigned char *ek = NULL;
- int eklen;
if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
{
@@ -534,29 +541,28 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
}
/* If we haven't got a certificate try each ri in turn */
-
if (pcert == NULL)
{
+ /* Always attempt to decrypt all rinfo even
+ * after sucess as a defence against MMA timing
+ * attacks.
+ */
for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
{
ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
+
if (pkcs7_decrypt_rinfo(&ek, &eklen,
- ri, pkey) > 0)
- break;
+ ri, pkey) < 0)
+ goto err;
ERR_clear_error();
- ri = NULL;
- }
- if (ri == NULL)
- {
- PKCS7err(PKCS7_F_PKCS7_DATADECODE,
- PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
- goto err;
}
}
else
{
- if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) <= 0)
+ /* Only exit on fatal errors, not decrypt failure */
+ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
goto err;
+ ERR_clear_error();
}
evp_ctx=NULL;
@@ -565,6 +571,19 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
goto err;
if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
goto err;
+ /* Generate random key as MMA defence */
+ tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
+ tkey = OPENSSL_malloc(tkeylen);
+ if (!tkey)
+ goto err;
+ if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
+ goto err;
+ if (ek == NULL)
+ {
+ ek = tkey;
+ eklen = tkeylen;
+ tkey = NULL;
+ }
if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
/* Some S/MIME clients don't use the same key
@@ -573,11 +592,16 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
*/
if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen))
{
- PKCS7err(PKCS7_F_PKCS7_DATADECODE,
- PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
- goto err;
+ /* Use random key as MMA defence */
+ OPENSSL_cleanse(ek, eklen);
+ OPENSSL_free(ek);
+ ek = tkey;
+ eklen = tkeylen;
+ tkey = NULL;
}
}
+ /* Clear errors so we don't leak information useful in MMA */
+ ERR_clear_error();
if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0)
goto err;
@@ -585,6 +609,13 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
{
OPENSSL_cleanse(ek,eklen);
OPENSSL_free(ek);
+ ek = NULL;
+ }
+ if (tkey)
+ {
+ OPENSSL_cleanse(tkey,tkeylen);
+ OPENSSL_free(tkey);
+ tkey = NULL;
}
if (out == NULL)
@@ -627,6 +658,16 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
if (0)
{
err:
+ if (ek)
+ {
+ OPENSSL_cleanse(ek,eklen);
+ OPENSSL_free(ek);
+ }
+ if (tkey)
+ {
+ OPENSSL_cleanse(tkey,tkeylen);
+ OPENSSL_free(tkey);
+ }
if (out != NULL) BIO_free_all(out);
if (btmp != NULL) BIO_free_all(btmp);
if (etmp != NULL) BIO_free_all(etmp);
@@ -676,7 +717,11 @@ static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
}
/* Add digest */
- EVP_DigestFinal_ex(mctx, md_data,&md_len);
+ if (!EVP_DigestFinal_ex(mctx, md_data,&md_len))
+ {
+ PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
+ return 0;
+ }
if (!PKCS7_add1_attrib_digest(si, md_data, md_len))
{
PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
@@ -784,7 +829,8 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
/* We now have the EVP_MD_CTX, lets do the
* signing. */
- EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
+ if (!EVP_MD_CTX_copy_ex(&ctx_tmp,mdc))
+ goto err;
sk=si->auth_attr;
@@ -822,7 +868,8 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
if (!PKCS7_find_digest(&mdc, bio,
OBJ_obj2nid(p7->d.digest->md->algorithm)))
goto err;
- EVP_DigestFinal_ex(mdc,md_data,&md_len);
+ if (!EVP_DigestFinal_ex(mdc,md_data,&md_len))
+ goto err;
M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
}
@@ -1015,7 +1062,8 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
/* mdc is the digest ctx that we want, unless there are attributes,
* in which case the digest is the signed attributes */
- EVP_MD_CTX_copy_ex(&mdc_tmp,mdc);
+ if (!EVP_MD_CTX_copy_ex(&mdc_tmp,mdc))
+ goto err;
sk=si->auth_attr;
if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
@@ -1025,7 +1073,8 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
int alen;
ASN1_OCTET_STRING *message_digest;
- EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
+ if (!EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len))
+ goto err;
message_digest=PKCS7_digest_from_attributes(sk);
if (!message_digest)
{
@@ -1050,7 +1099,8 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
goto err;
}
- EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL);
+ if (!EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL))
+ goto err;
alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
@@ -1060,7 +1110,8 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
ret = -1;
goto err;
}
- EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
+ if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen))
+ goto err;
OPENSSL_free(abuf);
}
diff --git a/deps/openssl/openssl/crypto/pkcs7/pk7_smime.c b/deps/openssl/openssl/crypto/pkcs7/pk7_smime.c
index 86742d0dc..a5104f8d0 100644
--- a/deps/openssl/openssl/crypto/pkcs7/pk7_smime.c
+++ b/deps/openssl/openssl/crypto/pkcs7/pk7_smime.c
@@ -573,15 +573,34 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
return 0;
}
ret = SMIME_text(bread, data);
+ if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER)
+ {
+ if (!BIO_get_cipher_status(tmpmem))
+ ret = 0;
+ }
BIO_free_all(bread);
return ret;
} else {
for(;;) {
i = BIO_read(tmpmem, buf, sizeof(buf));
- if(i <= 0) break;
- BIO_write(data, buf, i);
+ if(i <= 0)
+ {
+ ret = 1;
+ if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER)
+ {
+ if (!BIO_get_cipher_status(tmpmem))
+ ret = 0;
+ }
+
+ break;
+ }
+ if (BIO_write(data, buf, i) != i)
+ {
+ ret = 0;
+ break;
+ }
}
BIO_free_all(tmpmem);
- return 1;
+ return ret;
}
}
diff --git a/deps/openssl/openssl/crypto/ppccap.c b/deps/openssl/openssl/crypto/ppccap.c
new file mode 100644
index 000000000..f71ba66aa
--- /dev/null
+++ b/deps/openssl/openssl/crypto/ppccap.c
@@ -0,0 +1,126 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <unistd.h>
+#include <crypto.h>
+#include <openssl/bn.h>
+
+#define PPC_FPU64 (1<<0)
+#define PPC_ALTIVEC (1<<1)
+
+static int OPENSSL_ppccap_P = 0;
+
+static sigset_t all_masked;
+
+#ifdef OPENSSL_BN_ASM_MONT
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num)
+ {
+ int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num);
+ int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num);
+
+ if (sizeof(size_t)==4)
+ {
+#if (defined(__APPLE__) && defined(__MACH__))
+ if (num>=8 && (num&3)==0 && (OPENSSL_ppccap_P&PPC_FPU64))
+ return bn_mul_mont_fpu64(rp,ap,bp,np,n0,num);
+#else
+ /* boundary of 32 was experimentally determined on
+ Linux 2.6.22, might have to be adjusted on AIX... */
+ if (num>=32 && (num&3)==0 && (OPENSSL_ppccap_P&PPC_FPU64))
+ {
+ sigset_t oset;
+ int ret;
+
+ sigprocmask(SIG_SETMASK,&all_masked,&oset);
+ ret=bn_mul_mont_fpu64(rp,ap,bp,np,n0,num);
+ sigprocmask(SIG_SETMASK,&oset,NULL);
+
+ return ret;
+ }
+#endif
+ }
+ else if ((OPENSSL_ppccap_P&PPC_FPU64))
+ /* this is a "must" on POWER6, but run-time detection
+ * is not implemented yet... */
+ return bn_mul_mont_fpu64(rp,ap,bp,np,n0,num);
+
+ return bn_mul_mont_int(rp,ap,bp,np,n0,num);
+ }
+#endif
+
+static sigjmp_buf ill_jmp;
+static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
+
+void OPENSSL_ppc64_probe(void);
+void OPENSSL_altivec_probe(void);
+
+void OPENSSL_cpuid_setup(void)
+ {
+ char *e;
+ struct sigaction ill_oact,ill_act;
+ sigset_t oset;
+ static int trigger=0;
+
+ if (trigger) return;
+ trigger=1;
+
+ sigfillset(&all_masked);
+ sigdelset(&all_masked,SIGILL);
+ sigdelset(&all_masked,SIGTRAP);
+#ifdef SIGEMT
+ sigdelset(&all_masked,SIGEMT);
+#endif
+ sigdelset(&all_masked,SIGFPE);
+ sigdelset(&all_masked,SIGBUS);
+ sigdelset(&all_masked,SIGSEGV);
+
+ if ((e=getenv("OPENSSL_ppccap")))
+ {
+ OPENSSL_ppccap_P=strtoul(e,NULL,0);
+ return;
+ }
+
+ OPENSSL_ppccap_P = 0;
+
+#if defined(_AIX)
+ if (sizeof(size_t)==4
+# if defined(_SC_AIX_KERNEL_BITMODE)
+ && sysconf(_SC_AIX_KERNEL_BITMODE)!=64
+# endif
+ )
+ return;
+#endif
+
+ memset(&ill_act,0,sizeof(ill_act));
+ ill_act.sa_handler = ill_handler;
+ ill_act.sa_mask = all_masked;
+
+ sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
+ sigaction(SIGILL,&ill_act,&ill_oact);
+
+ if (sizeof(size_t)==4)
+ {
+ if (sigsetjmp(ill_jmp,1) == 0)
+ {
+ OPENSSL_ppc64_probe();
+ OPENSSL_ppccap_P |= PPC_FPU64;
+ }
+ }
+ else
+ {
+ /*
+ * Wanted code detecting POWER6 CPU and setting PPC_FPU64
+ */
+ }
+
+ if (sigsetjmp(ill_jmp,1) == 0)
+ {
+ OPENSSL_altivec_probe();
+ OPENSSL_ppccap_P |= PPC_ALTIVEC;
+ }
+
+ sigaction (SIGILL,&ill_oact,NULL);
+ sigprocmask(SIG_SETMASK,&oset,NULL);
+ }
diff --git a/deps/openssl/openssl/crypto/ppccpuid.pl b/deps/openssl/openssl/crypto/ppccpuid.pl
index 369e1d0df..4ba736a1d 100644..100755
--- a/deps/openssl/openssl/crypto/ppccpuid.pl
+++ b/deps/openssl/openssl/crypto/ppccpuid.pl
@@ -23,36 +23,67 @@ $code=<<___;
.machine "any"
.text
-.globl .OPENSSL_cpuid_setup
+.globl .OPENSSL_ppc64_probe
.align 4
-.OPENSSL_cpuid_setup:
+.OPENSSL_ppc64_probe:
+ fcfid f1,f1
+ extrdi r0,r0,32,0
blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
+
+.globl .OPENSSL_altivec_probe
+.align 4
+.OPENSSL_altivec_probe:
+ .long 0x10000484 # vor v0,v0,v0
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
.globl .OPENSSL_wipe_cpu
.align 4
.OPENSSL_wipe_cpu:
xor r0,r0,r0
+ fmr f0,f31
+ fmr f1,f31
+ fmr f2,f31
mr r3,r1
+ fmr f3,f31
xor r4,r4,r4
+ fmr f4,f31
xor r5,r5,r5
+ fmr f5,f31
xor r6,r6,r6
+ fmr f6,f31
xor r7,r7,r7
+ fmr f7,f31
xor r8,r8,r8
+ fmr f8,f31
xor r9,r9,r9
+ fmr f9,f31
xor r10,r10,r10
+ fmr f10,f31
xor r11,r11,r11
+ fmr f11,f31
xor r12,r12,r12
+ fmr f12,f31
+ fmr f13,f31
blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
.globl .OPENSSL_atomic_add
.align 4
.OPENSSL_atomic_add:
-Loop: lwarx r5,0,r3
+Ladd: lwarx r5,0,r3
add r0,r4,r5
stwcx. r0,0,r3
- bne- Loop
+ bne- Ladd
$SIGNX r3,r0
blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,2,0
+ .long 0
.globl .OPENSSL_rdtsc
.align 4
@@ -60,6 +91,8 @@ Loop: lwarx r5,0,r3
mftb r3
mftbu r4
blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
.globl .OPENSSL_cleanse
.align 4
@@ -72,7 +105,7 @@ Loop: lwarx r5,0,r3
Little: mtctr r4
stb r0,0(r3)
addi r3,r3,1
- bdnz- \$-8
+ bdnz \$-8
blr
Lot: andi. r5,r3,3
beq Laligned
@@ -85,10 +118,13 @@ Laligned:
mtctr r5
stw r0,0(r3)
addi r3,r3,4
- bdnz- \$-8
+ bdnz \$-8
andi. r4,r4,3
bne Little
blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,2,0
+ .long 0
___
$code =~ s/\`([^\`]*)\`/eval $1/gem;
diff --git a/deps/openssl/openssl/crypto/rand/md_rand.c b/deps/openssl/openssl/crypto/rand/md_rand.c
index b2f04ff13..1e3bcb9bc 100644
--- a/deps/openssl/openssl/crypto/rand/md_rand.c
+++ b/deps/openssl/openssl/crypto/rand/md_rand.c
@@ -109,6 +109,8 @@
*
*/
+#define OPENSSL_FIPSEVP
+
#ifdef MD_RAND_DEBUG
# ifndef NDEBUG
# define NDEBUG
@@ -121,10 +123,10 @@
#include "e_os.h"
+#include <openssl/crypto.h>
#include <openssl/rand.h>
#include "rand_lcl.h"
-#include <openssl/crypto.h>
#include <openssl/err.h>
#ifdef BN_DEBUG
@@ -157,13 +159,14 @@ const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
static void ssleay_rand_cleanup(void);
static void ssleay_rand_seed(const void *buf, int num);
static void ssleay_rand_add(const void *buf, int num, double add_entropy);
-static int ssleay_rand_bytes(unsigned char *buf, int num);
+static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo);
+static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num);
static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
static int ssleay_rand_status(void);
RAND_METHOD rand_ssleay_meth={
ssleay_rand_seed,
- ssleay_rand_bytes,
+ ssleay_rand_nopseudo_bytes,
ssleay_rand_cleanup,
ssleay_rand_add,
ssleay_rand_pseudo_bytes,
@@ -328,7 +331,7 @@ static void ssleay_rand_seed(const void *buf, int num)
ssleay_rand_add(buf, num, (double)num);
}
-static int ssleay_rand_bytes(unsigned char *buf, int num)
+static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
{
static volatile int stirred_pool = 0;
int i,j,k,st_num,st_idx;
@@ -517,7 +520,9 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
EVP_MD_CTX_cleanup(&m);
if (ok)
return(1);
- else
+ else if (pseudo)
+ return 0;
+ else
{
RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
@@ -526,22 +531,16 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
}
}
+static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
+ {
+ return ssleay_rand_bytes(buf, num, 0);
+ }
+
/* pseudo-random bytes that are guaranteed to be unique but not
unpredictable */
static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
{
- int ret;
- unsigned long err;
-
- ret = RAND_bytes(buf, num);
- if (ret == 0)
- {
- err = ERR_peek_error();
- if (ERR_GET_LIB(err) == ERR_LIB_RAND &&
- ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED)
- ERR_clear_error();
- }
- return (ret);
+ return ssleay_rand_bytes(buf, num, 1);
}
static int ssleay_rand_status(void)
diff --git a/deps/openssl/openssl/crypto/rand/rand.h b/deps/openssl/openssl/crypto/rand/rand.h
index ac6c02176..dc8fcf94c 100644
--- a/deps/openssl/openssl/crypto/rand/rand.h
+++ b/deps/openssl/openssl/crypto/rand/rand.h
@@ -119,6 +119,11 @@ int RAND_event(UINT, WPARAM, LPARAM);
#endif
+#ifdef OPENSSL_FIPS
+void RAND_set_fips_drbg_type(int type, int flags);
+int RAND_init_fips(void);
+#endif
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@@ -129,9 +134,13 @@ void ERR_load_RAND_strings(void);
/* Function codes. */
#define RAND_F_RAND_GET_RAND_METHOD 101
+#define RAND_F_RAND_INIT_FIPS 102
#define RAND_F_SSLEAY_RAND_BYTES 100
/* Reason codes. */
+#define RAND_R_ERROR_INITIALISING_DRBG 102
+#define RAND_R_ERROR_INSTANTIATING_DRBG 103
+#define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101
#define RAND_R_PRNG_NOT_SEEDED 100
#ifdef __cplusplus
diff --git a/deps/openssl/openssl/crypto/rand/rand_err.c b/deps/openssl/openssl/crypto/rand/rand_err.c
index 03cda4dd9..b8586c8f4 100644
--- a/deps/openssl/openssl/crypto/rand/rand_err.c
+++ b/deps/openssl/openssl/crypto/rand/rand_err.c
@@ -1,6 +1,6 @@
/* crypto/rand/rand_err.c */
/* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -71,12 +71,16 @@
static ERR_STRING_DATA RAND_str_functs[]=
{
{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"},
+{ERR_FUNC(RAND_F_RAND_INIT_FIPS), "RAND_init_fips"},
{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"},
{0,NULL}
};
static ERR_STRING_DATA RAND_str_reasons[]=
{
+{ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
+{ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG),"error instantiating drbg"},
+{ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET),"no fips random method set"},
{ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"},
{0,NULL}
};
diff --git a/deps/openssl/openssl/crypto/rand/rand_lib.c b/deps/openssl/openssl/crypto/rand/rand_lib.c
index 513e33898..476a0cd18 100644
--- a/deps/openssl/openssl/crypto/rand/rand_lib.c
+++ b/deps/openssl/openssl/crypto/rand/rand_lib.c
@@ -60,10 +60,16 @@
#include <time.h>
#include "cryptlib.h"
#include <openssl/rand.h>
+
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+#endif
+
#ifndef OPENSSL_NO_ENGINE
/* non-NULL if default_RAND_meth is ENGINE-provided */
static ENGINE *funct_ref =NULL;
@@ -174,3 +180,119 @@ int RAND_status(void)
return meth->status();
return 0;
}
+
+#ifdef OPENSSL_FIPS
+
+/* FIPS DRBG initialisation code. This sets up the DRBG for use by the
+ * rest of OpenSSL.
+ */
+
+/* Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather
+ * entropy internally through RAND_poll().
+ */
+
+static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
+ int entropy, size_t min_len, size_t max_len)
+ {
+ /* Round up request to multiple of block size */
+ min_len = ((min_len + 19) / 20) * 20;
+ *pout = OPENSSL_malloc(min_len);
+ if (!*pout)
+ return 0;
+ if (RAND_SSLeay()->bytes(*pout, min_len) <= 0)
+ {
+ OPENSSL_free(*pout);
+ *pout = NULL;
+ return 0;
+ }
+ return min_len;
+ }
+
+static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
+ {
+ if (out)
+ {
+ OPENSSL_cleanse(out, olen);
+ OPENSSL_free(out);
+ }
+ }
+
+/* Set "additional input" when generating random data. This uses the
+ * current PID, a time value and a counter.
+ */
+
+static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
+ {
+ /* Use of static variables is OK as this happens under a lock */
+ static unsigned char buf[16];
+ static unsigned long counter;
+ FIPS_get_timevec(buf, &counter);
+ *pout = buf;
+ return sizeof(buf);
+ }
+
+/* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is
+ * correctly seeded by RAND_poll().
+ */
+
+static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
+ double entropy)
+ {
+ RAND_SSLeay()->add(in, inlen, entropy);
+ return 1;
+ }
+
+static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
+ {
+ RAND_SSLeay()->seed(in, inlen);
+ return 1;
+ }
+
+#ifndef OPENSSL_DRBG_DEFAULT_TYPE
+#define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr
+#endif
+#ifndef OPENSSL_DRBG_DEFAULT_FLAGS
+#define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF
+#endif
+
+static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
+static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
+
+void RAND_set_fips_drbg_type(int type, int flags)
+ {
+ fips_drbg_type = type;
+ fips_drbg_flags = flags;
+ }
+
+int RAND_init_fips(void)
+ {
+ DRBG_CTX *dctx;
+ size_t plen;
+ unsigned char pers[32], *p;
+ dctx = FIPS_get_default_drbg();
+ if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0)
+ {
+ RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
+ return 0;
+ }
+
+ FIPS_drbg_set_callbacks(dctx,
+ drbg_get_entropy, drbg_free_entropy, 20,
+ drbg_get_entropy, drbg_free_entropy);
+ FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
+ drbg_rand_seed, drbg_rand_add);
+ /* Personalisation string: a string followed by date time vector */
+ strcpy((char *)pers, "OpenSSL DRBG2.0");
+ plen = drbg_get_adin(dctx, &p);
+ memcpy(pers + 16, p, plen);
+
+ if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0)
+ {
+ RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
+ return 0;
+ }
+ FIPS_rand_set_method(FIPS_drbg_method());
+ return 1;
+ }
+
+#endif
diff --git a/deps/openssl/openssl/crypto/rand/randfile.c b/deps/openssl/openssl/crypto/rand/randfile.c
index bc7d9c580..7f1428072 100644
--- a/deps/openssl/openssl/crypto/rand/randfile.c
+++ b/deps/openssl/openssl/crypto/rand/randfile.c
@@ -57,7 +57,9 @@
*/
/* We need to define this to get macros like S_IFBLK and S_IFCHR */
+#if !defined(OPENSSL_SYS_VXWORKS)
#define _XOPEN_SOURCE 500
+#endif
#include <errno.h>
#include <stdio.h>
@@ -137,7 +139,7 @@ int RAND_load_file(const char *file, long bytes)
in=fopen(file,"rb");
#endif
if (in == NULL) goto err;
-#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPNESSL_NO_POSIX_IO)
+#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO)
if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
/* this file is a device. we don't want read an infinite number
* of bytes from a random device, nor do we want to use buffered
diff --git a/deps/openssl/openssl/crypto/rc2/Makefile b/deps/openssl/openssl/crypto/rc2/Makefile
index 73eac347e..8a9d49ab5 100644
--- a/deps/openssl/openssl/crypto/rc2/Makefile
+++ b/deps/openssl/openssl/crypto/rc2/Makefile
@@ -78,7 +78,11 @@ rc2_cbc.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
rc2_cbc.o: rc2_cbc.c rc2_locl.h
rc2_ecb.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
rc2_ecb.o: ../../include/openssl/rc2.h rc2_ecb.c rc2_locl.h
-rc2_skey.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
+rc2_skey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rc2_skey.o: ../../include/openssl/opensslconf.h
+rc2_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rc2_skey.o: ../../include/openssl/rc2.h ../../include/openssl/safestack.h
+rc2_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
rc2_skey.o: rc2_locl.h rc2_skey.c
rc2cfb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
rc2cfb64.o: rc2_locl.h rc2cfb64.c
diff --git a/deps/openssl/openssl/crypto/rc2/rc2.h b/deps/openssl/openssl/crypto/rc2/rc2.h
index 34c836231..e542ec94f 100644
--- a/deps/openssl/openssl/crypto/rc2/rc2.h
+++ b/deps/openssl/openssl/crypto/rc2/rc2.h
@@ -79,7 +79,9 @@ typedef struct rc2_key_st
RC2_INT data[64];
} RC2_KEY;
-
+#ifdef OPENSSL_FIPS
+void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
+#endif
void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key,
int enc);
diff --git a/deps/openssl/openssl/crypto/rc2/rc2_skey.c b/deps/openssl/openssl/crypto/rc2/rc2_skey.c
index 0150b0e03..6668ac011 100644
--- a/deps/openssl/openssl/crypto/rc2/rc2_skey.c
+++ b/deps/openssl/openssl/crypto/rc2/rc2_skey.c
@@ -56,6 +56,7 @@
* [including the GNU Public Licence.]
*/
+#include <openssl/crypto.h>
#include <openssl/rc2.h>
#include "rc2_locl.h"
@@ -95,6 +96,13 @@ static const unsigned char key_table[256]={
* the same as specifying 1024 for the 'bits' parameter. Bsafe uses
* a version where the bits parameter is the same as len*8 */
void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
+#ifdef OPENSSL_FIPS
+ {
+ fips_cipher_abort(RC2);
+ private_RC2_set_key(key, len, data, bits);
+ }
+void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
+#endif
{
int i,j;
unsigned char *k;
diff --git a/deps/openssl/openssl/crypto/rc4/Makefile b/deps/openssl/openssl/crypto/rc4/Makefile
index 264451a21..1614d4796 100644
--- a/deps/openssl/openssl/crypto/rc4/Makefile
+++ b/deps/openssl/openssl/crypto/rc4/Makefile
@@ -21,8 +21,8 @@ TEST=rc4test.c
APPS=
LIB=$(TOP)/libcrypto.a
-LIBSRC=rc4_skey.c rc4_enc.c
-LIBOBJ=$(RC4_ENC)
+LIBSRC=rc4_skey.c rc4_enc.c rc4_utl.c
+LIBOBJ=$(RC4_ENC) rc4_utl.o
SRC= $(LIBSRC)
@@ -46,12 +46,14 @@ rc4-586.s: asm/rc4-586.pl ../perlasm/x86asm.pl
rc4-x86_64.s: asm/rc4-x86_64.pl
$(PERL) asm/rc4-x86_64.pl $(PERLASM_SCHEME) > $@
+rc4-md5-x86_64.s: asm/rc4-md5-x86_64.pl
+ $(PERL) asm/rc4-md5-x86_64.pl $(PERLASM_SCHEME) > $@
rc4-ia64.S: asm/rc4-ia64.pl
$(PERL) asm/rc4-ia64.pl $(CFLAGS) > $@
-rc4-s390x.s: asm/rc4-s390x.pl
- $(PERL) asm/rc4-s390x.pl > $@
+rc4-parisc.s: asm/rc4-parisc.pl
+ $(PERL) asm/rc4-parisc.pl $(PERLASM_SCHEME) $@
rc4-ia64.s: rc4-ia64.S
@case `awk '/^#define RC4_INT/{print$$NF}' $(TOP)/include/openssl/opensslconf.h` in \
@@ -60,6 +62,9 @@ rc4-ia64.s: rc4-ia64.S
*) exit 1 ;; \
esac
+# GNU make "catch all"
+rc4-%.s: asm/rc4-%.pl; $(PERL) $< $(PERLASM_SCHEME) $@
+
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
@@ -113,3 +118,8 @@ rc4_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
rc4_skey.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h
rc4_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
rc4_skey.o: ../cryptlib.h rc4_locl.h rc4_skey.c
+rc4_utl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rc4_utl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+rc4_utl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc4.h
+rc4_utl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rc4_utl.o: ../../include/openssl/symhacks.h rc4_utl.c
diff --git a/deps/openssl/openssl/crypto/rc4/asm/rc4-586.pl b/deps/openssl/openssl/crypto/rc4/asm/rc4-586.pl
index 38a44a70e..5c9ac6ad2 100644
--- a/deps/openssl/openssl/crypto/rc4/asm/rc4-586.pl
+++ b/deps/openssl/openssl/crypto/rc4/asm/rc4-586.pl
@@ -28,6 +28,34 @@
#
# <appro@fy.chalmers.se>
+# May 2011
+#
+# Optimize for Core2 and Westmere [and incidentally Opteron]. Current
+# performance in cycles per processed byte (less is better) and
+# improvement relative to previous version of this module is:
+#
+# Pentium 10.2 # original numbers
+# Pentium III 7.8(*)
+# Intel P4 7.5
+#
+# Opteron 6.1/+20% # new MMX numbers
+# Core2 5.3/+67%(**)
+# Westmere 5.1/+94%(**)
+# Sandy Bridge 5.0/+8%
+# Atom 12.6/+6%
+#
+# (*) PIII can actually deliver 6.6 cycles per byte with MMX code,
+# but this specific code performs poorly on Core2. And vice
+# versa, below MMX/SSE code delivering 5.8/7.1 on Core2 performs
+# poorly on PIII, at 8.0/14.5:-( As PIII is not a "hot" CPU
+# [anymore], I chose to discard PIII-specific code path and opt
+# for original IALU-only code, which is why MMX/SSE code path
+# is guarded by SSE2 bit (see below), not MMX/SSE.
+# (**) Performance vs. block size on Core2 and Westmere had a maximum
+# at ... 64 bytes block size. And it was quite a maximum, 40-60%
+# in comparison to largest 8KB block size. Above improvement
+# coefficients are for the largest block size.
+
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
push(@INC,"${dir}","${dir}../../perlasm");
require "x86asm.pl";
@@ -62,6 +90,68 @@ sub RC4_loop {
&$func ($out,&DWP(0,$dat,$ty,4));
}
+if ($alt=0) {
+ # >20% faster on Atom and Sandy Bridge[!], 8% faster on Opteron,
+ # but ~40% slower on Core2 and Westmere... Attempt to add movz
+ # brings down Opteron by 25%, Atom and Sandy Bridge by 15%, yet
+ # on Core2 with movz it's almost 20% slower than below alternative
+ # code... Yes, it's a total mess...
+ my @XX=($xx,$out);
+ $RC4_loop_mmx = sub { # SSE actually...
+ my $i=shift;
+ my $j=$i<=0?0:$i>>1;
+ my $mm=$i<=0?"mm0":"mm".($i&1);
+
+ &add (&LB($yy),&LB($tx));
+ &lea (@XX[1],&DWP(1,@XX[0]));
+ &pxor ("mm2","mm0") if ($i==0);
+ &psllq ("mm1",8) if ($i==0);
+ &and (@XX[1],0xff);
+ &pxor ("mm0","mm0") if ($i<=0);
+ &mov ($ty,&DWP(0,$dat,$yy,4));
+ &mov (&DWP(0,$dat,$yy,4),$tx);
+ &pxor ("mm1","mm2") if ($i==0);
+ &mov (&DWP(0,$dat,$XX[0],4),$ty);
+ &add (&LB($ty),&LB($tx));
+ &movd (@XX[0],"mm7") if ($i==0);
+ &mov ($tx,&DWP(0,$dat,@XX[1],4));
+ &pxor ("mm1","mm1") if ($i==1);
+ &movq ("mm2",&QWP(0,$inp)) if ($i==1);
+ &movq (&QWP(-8,(@XX[0],$inp)),"mm1") if ($i==0);
+ &pinsrw ($mm,&DWP(0,$dat,$ty,4),$j);
+
+ push (@XX,shift(@XX)) if ($i>=0);
+ }
+} else {
+ # Using pinsrw here improves performane on Intel CPUs by 2-3%, but
+ # brings down AMD by 7%...
+ $RC4_loop_mmx = sub {
+ my $i=shift;
+
+ &add (&LB($yy),&LB($tx));
+ &psllq ("mm1",8*(($i-1)&7)) if (abs($i)!=1);
+ &mov ($ty,&DWP(0,$dat,$yy,4));
+ &mov (&DWP(0,$dat,$yy,4),$tx);
+ &mov (&DWP(0,$dat,$xx,4),$ty);
+ &inc ($xx);
+ &add ($ty,$tx);
+ &movz ($xx,&LB($xx)); # (*)
+ &movz ($ty,&LB($ty)); # (*)
+ &pxor ("mm2",$i==1?"mm0":"mm1") if ($i>=0);
+ &movq ("mm0",&QWP(0,$inp)) if ($i<=0);
+ &movq (&QWP(-8,($out,$inp)),"mm2") if ($i==0);
+ &mov ($tx,&DWP(0,$dat,$xx,4));
+ &movd ($i>0?"mm1":"mm2",&DWP(0,$dat,$ty,4));
+
+ # (*) This is the key to Core2 and Westmere performance.
+ # Whithout movz out-of-order execution logic confuses
+ # itself and fails to reorder loads and stores. Problem
+ # appears to be fixed in Sandy Bridge...
+ }
+}
+
+&external_label("OPENSSL_ia32cap_P");
+
# void RC4(RC4_KEY *key,size_t len,const unsigned char *inp,unsigned char *out);
&function_begin("RC4");
&mov ($dat,&wparam(0)); # load key schedule pointer
@@ -94,11 +184,56 @@ sub RC4_loop {
&and ($ty,-4); # how many 4-byte chunks?
&jz (&label("loop1"));
+ &test ($ty,-8);
+ &mov (&wparam(3),$out); # $out as accumulator in these loops
+ &jz (&label("go4loop4"));
+
+ &picmeup($out,"OPENSSL_ia32cap_P");
+ &bt (&DWP(0,$out),26); # check SSE2 bit [could have been MMX]
+ &jnc (&label("go4loop4"));
+
+ &mov ($out,&wparam(3)) if (!$alt);
+ &movd ("mm7",&wparam(3)) if ($alt);
+ &and ($ty,-8);
+ &lea ($ty,&DWP(-8,$inp,$ty));
+ &mov (&DWP(-4,$dat),$ty); # save input+(len/8)*8-8
+
+ &$RC4_loop_mmx(-1);
+ &jmp(&label("loop_mmx_enter"));
+
+ &set_label("loop_mmx",16);
+ &$RC4_loop_mmx(0);
+ &set_label("loop_mmx_enter");
+ for ($i=1;$i<8;$i++) { &$RC4_loop_mmx($i); }
+ &mov ($ty,$yy);
+ &xor ($yy,$yy); # this is second key to Core2
+ &mov (&LB($yy),&LB($ty)); # and Westmere performance...
+ &cmp ($inp,&DWP(-4,$dat));
+ &lea ($inp,&DWP(8,$inp));
+ &jb (&label("loop_mmx"));
+
+ if ($alt) {
+ &movd ($out,"mm7");
+ &pxor ("mm2","mm0");
+ &psllq ("mm1",8);
+ &pxor ("mm1","mm2");
+ &movq (&QWP(-8,$out,$inp),"mm1");
+ } else {
+ &psllq ("mm1",56);
+ &pxor ("mm2","mm1");
+ &movq (&QWP(-8,$out,$inp),"mm2");
+ }
+ &emms ();
+
+ &cmp ($inp,&wparam(1)); # compare to input+len
+ &je (&label("done"));
+ &jmp (&label("loop1"));
+
+&set_label("go4loop4",16);
&lea ($ty,&DWP(-4,$inp,$ty));
&mov (&wparam(2),$ty); # save input+(len/4)*4-4
- &mov (&wparam(3),$out); # $out as accumulator in this loop
- &set_label("loop4",16);
+ &set_label("loop4");
for ($i=0;$i<4;$i++) { RC4_loop($i); }
&ror ($out,8);
&xor ($out,&DWP(0,$inp));
@@ -151,7 +286,7 @@ sub RC4_loop {
&set_label("done");
&dec (&LB($xx));
- &mov (&BP(-4,$dat),&LB($yy)); # save key->y
+ &mov (&DWP(-4,$dat),$yy); # save key->y
&mov (&BP(-8,$dat),&LB($xx)); # save key->x
&set_label("abort");
&function_end("RC4");
@@ -164,10 +299,8 @@ $idi="ebp";
$ido="ecx";
$idx="edx";
-&external_label("OPENSSL_ia32cap_P");
-
# void RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
-&function_begin("RC4_set_key");
+&function_begin("private_RC4_set_key");
&mov ($out,&wparam(0)); # load key
&mov ($idi,&wparam(1)); # load len
&mov ($inp,&wparam(2)); # load data
@@ -245,7 +378,7 @@ $idx="edx";
&xor ("eax","eax");
&mov (&DWP(-8,$out),"eax"); # key->x=0;
&mov (&DWP(-4,$out),"eax"); # key->y=0;
-&function_end("RC4_set_key");
+&function_end("private_RC4_set_key");
# const char *RC4_options(void);
&function_begin_B("RC4_options");
@@ -254,14 +387,21 @@ $idx="edx";
&blindpop("eax");
&lea ("eax",&DWP(&label("opts")."-".&label("pic_point"),"eax"));
&picmeup("edx","OPENSSL_ia32cap_P");
- &bt (&DWP(0,"edx"),20);
- &jnc (&label("skip"));
- &add ("eax",12);
- &set_label("skip");
+ &mov ("edx",&DWP(0,"edx"));
+ &bt ("edx",20);
+ &jc (&label("1xchar"));
+ &bt ("edx",26);
+ &jnc (&label("ret"));
+ &add ("eax",25);
+ &ret ();
+&set_label("1xchar");
+ &add ("eax",12);
+&set_label("ret");
&ret ();
&set_label("opts",64);
&asciz ("rc4(4x,int)");
&asciz ("rc4(1x,char)");
+&asciz ("rc4(8x,mmx)");
&asciz ("RC4 for x86, CRYPTOGAMS by <appro\@openssl.org>");
&align (64);
&function_end_B("RC4_options");
diff --git a/deps/openssl/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl b/deps/openssl/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
new file mode 100644
index 000000000..272fa91e1
--- /dev/null
+++ b/deps/openssl/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
@@ -0,0 +1,632 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# June 2011
+#
+# This is RC4+MD5 "stitch" implementation. The idea, as spelled in
+# http://download.intel.com/design/intarch/papers/323686.pdf, is that
+# since both algorithms exhibit instruction-level parallelism, ILP,
+# below theoretical maximum, interleaving them would allow to utilize
+# processor resources better and achieve better performance. RC4
+# instruction sequence is virtually identical to rc4-x86_64.pl, which
+# is heavily based on submission by Maxim Perminov, Maxim Locktyukhin
+# and Jim Guilford of Intel. MD5 is fresh implementation aiming to
+# minimize register usage, which was used as "main thread" with RC4
+# weaved into it, one RC4 round per one MD5 round. In addition to the
+# stiched subroutine the script can generate standalone replacement
+# md5_block_asm_data_order and RC4. Below are performance numbers in
+# cycles per processed byte, less is better, for these the standalone
+# subroutines, sum of them, and stitched one:
+#
+# RC4 MD5 RC4+MD5 stitch gain
+# Opteron 6.5(*) 5.4 11.9 7.0 +70%(*)
+# Core2 6.5 5.8 12.3 7.7 +60%
+# Westmere 4.3 5.2 9.5 7.0 +36%
+# Sandy Bridge 4.2 5.5 9.7 6.8 +43%
+# Atom 9.3 6.5 15.8 11.1 +42%
+#
+# (*) rc4-x86_64.pl delivers 5.3 on Opteron, so real improvement
+# is +53%...
+
+my ($rc4,$md5)=(1,1); # what to generate?
+my $D="#" if (!$md5); # if set to "#", MD5 is stitched into RC4(),
+ # but its result is discarded. Idea here is
+ # to be able to use 'openssl speed rc4' for
+ # benchmarking the stitched subroutine...
+
+my $flavour = shift;
+my $output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs);
+
+if ($rc4 && !$md5) {
+ ($dat,$len,$in0,$out) = ("%rdi","%rsi","%rdx","%rcx");
+ $func="RC4"; $nargs=4;
+} elsif ($md5 && !$rc4) {
+ ($ctx,$inp,$len) = ("%rdi","%rsi","%rdx");
+ $func="md5_block_asm_data_order"; $nargs=3;
+} else {
+ ($dat,$in0,$out,$ctx,$inp,$len) = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9");
+ $func="rc4_md5_enc"; $nargs=6;
+ # void rc4_md5_enc(
+ # RC4_KEY *key, #
+ # const void *in0, # RC4 input
+ # void *out, # RC4 output
+ # MD5_CTX *ctx, #
+ # const void *inp, # MD5 input
+ # size_t len); # number of 64-byte blocks
+}
+
+my @K=( 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
+ 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
+ 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
+ 0x6b901122,0xfd987193,0xa679438e,0x49b40821,
+
+ 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
+ 0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
+ 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
+ 0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
+
+ 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
+ 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
+ 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
+ 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
+
+ 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
+ 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
+ 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
+ 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 );
+
+my @V=("%r8d","%r9d","%r10d","%r11d"); # MD5 registers
+my $tmp="%r12d";
+
+my @XX=("%rbp","%rsi"); # RC4 registers
+my @TX=("%rax","%rbx");
+my $YY="%rcx";
+my $TY="%rdx";
+
+my $MOD=32; # 16, 32 or 64
+
+$code.=<<___;
+.text
+.align 16
+
+.globl $func
+.type $func,\@function,$nargs
+$func:
+ cmp \$0,$len
+ je .Labort
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ sub \$40,%rsp
+.Lbody:
+___
+if ($rc4) {
+$code.=<<___;
+$D#md5# mov $ctx,%r11 # reassign arguments
+ mov $len,%r12
+ mov $in0,%r13
+ mov $out,%r14
+$D#md5# mov $inp,%r15
+___
+ $ctx="%r11" if ($md5); # reassign arguments
+ $len="%r12";
+ $in0="%r13";
+ $out="%r14";
+ $inp="%r15" if ($md5);
+ $inp=$in0 if (!$md5);
+$code.=<<___;
+ xor $XX[0],$XX[0]
+ xor $YY,$YY
+
+ lea 8($dat),$dat
+ mov -8($dat),$XX[0]#b
+ mov -4($dat),$YY#b
+
+ inc $XX[0]#b
+ sub $in0,$out
+ movl ($dat,$XX[0],4),$TX[0]#d
+___
+$code.=<<___ if (!$md5);
+ xor $TX[1],$TX[1]
+ test \$-128,$len
+ jz .Loop1
+ sub $XX[0],$TX[1]
+ and \$`$MOD-1`,$TX[1]
+ jz .Loop${MOD}_is_hot
+ sub $TX[1],$len
+.Loop${MOD}_warmup:
+ add $TX[0]#b,$YY#b
+ movl ($dat,$YY,4),$TY#d
+ movl $TX[0]#d,($dat,$YY,4)
+ movl $TY#d,($dat,$XX[0],4)
+ add $TY#b,$TX[0]#b
+ inc $XX[0]#b
+ movl ($dat,$TX[0],4),$TY#d
+ movl ($dat,$XX[0],4),$TX[0]#d
+ xorb ($in0),$TY#b
+ movb $TY#b,($out,$in0)
+ lea 1($in0),$in0
+ dec $TX[1]
+ jnz .Loop${MOD}_warmup
+
+ mov $YY,$TX[1]
+ xor $YY,$YY
+ mov $TX[1]#b,$YY#b
+
+.Loop${MOD}_is_hot:
+ mov $len,32(%rsp) # save original $len
+ shr \$6,$len # number of 64-byte blocks
+___
+ if ($D && !$md5) { # stitch in dummy MD5
+ $md5=1;
+ $ctx="%r11";
+ $inp="%r15";
+ $code.=<<___;
+ mov %rsp,$ctx
+ mov $in0,$inp
+___
+ }
+}
+$code.=<<___;
+#rc4# add $TX[0]#b,$YY#b
+#rc4# lea ($dat,$XX[0],4),$XX[1]
+ shl \$6,$len
+ add $inp,$len # pointer to the end of input
+ mov $len,16(%rsp)
+
+#md5# mov $ctx,24(%rsp) # save pointer to MD5_CTX
+#md5# mov 0*4($ctx),$V[0] # load current hash value from MD5_CTX
+#md5# mov 1*4($ctx),$V[1]
+#md5# mov 2*4($ctx),$V[2]
+#md5# mov 3*4($ctx),$V[3]
+ jmp .Loop
+
+.align 16
+.Loop:
+#md5# mov $V[0],0*4(%rsp) # put aside current hash value
+#md5# mov $V[1],1*4(%rsp)
+#md5# mov $V[2],2*4(%rsp)
+#md5# mov $V[3],$tmp # forward reference
+#md5# mov $V[3],3*4(%rsp)
+___
+
+sub R0 {
+ my ($i,$a,$b,$c,$d)=@_;
+ my @rot0=(7,12,17,22);
+ my $j=$i%16;
+ my $k=$i%$MOD;
+ my $xmm="%xmm".($j&1);
+ $code.=" movdqu ($in0),%xmm2\n" if ($rc4 && $j==15);
+ $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
+ $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
+ $code.=<<___;
+#rc4# movl ($dat,$YY,4),$TY#d
+#md5# xor $c,$tmp
+#rc4# movl $TX[0]#d,($dat,$YY,4)
+#md5# and $b,$tmp
+#md5# add 4*`$j`($inp),$a
+#rc4# add $TY#b,$TX[0]#b
+#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
+#md5# add \$$K[$i],$a
+#md5# xor $d,$tmp
+#rc4# movz $TX[0]#b,$TX[0]#d
+#rc4# movl $TY#d,4*$k($XX[1])
+#md5# add $tmp,$a
+#rc4# add $TX[1]#b,$YY#b
+#md5# rol \$$rot0[$j%4],$a
+#md5# mov `$j==15?"$b":"$c"`,$tmp # forward reference
+#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
+#md5# add $b,$a
+___
+ $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
+ mov $YY,$XX[1]
+ xor $YY,$YY # keyword to partial register
+ mov $XX[1]#b,$YY#b
+ lea ($dat,$XX[0],4),$XX[1]
+___
+ $code.=<<___ if ($rc4 && $j==15);
+ psllq \$8,%xmm1
+ pxor %xmm0,%xmm2
+ pxor %xmm1,%xmm2
+___
+}
+sub R1 {
+ my ($i,$a,$b,$c,$d)=@_;
+ my @rot1=(5,9,14,20);
+ my $j=$i%16;
+ my $k=$i%$MOD;
+ my $xmm="%xmm".($j&1);
+ $code.=" movdqu 16($in0),%xmm3\n" if ($rc4 && $j==15);
+ $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
+ $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
+ $code.=<<___;
+#rc4# movl ($dat,$YY,4),$TY#d
+#md5# xor $b,$tmp
+#rc4# movl $TX[0]#d,($dat,$YY,4)
+#md5# and $d,$tmp
+#md5# add 4*`((1+5*$j)%16)`($inp),$a
+#rc4# add $TY#b,$TX[0]#b
+#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
+#md5# add \$$K[$i],$a
+#md5# xor $c,$tmp
+#rc4# movz $TX[0]#b,$TX[0]#d
+#rc4# movl $TY#d,4*$k($XX[1])
+#md5# add $tmp,$a
+#rc4# add $TX[1]#b,$YY#b
+#md5# rol \$$rot1[$j%4],$a
+#md5# mov `$j==15?"$c":"$b"`,$tmp # forward reference
+#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
+#md5# add $b,$a
+___
+ $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
+ mov $YY,$XX[1]
+ xor $YY,$YY # keyword to partial register
+ mov $XX[1]#b,$YY#b
+ lea ($dat,$XX[0],4),$XX[1]
+___
+ $code.=<<___ if ($rc4 && $j==15);
+ psllq \$8,%xmm1
+ pxor %xmm0,%xmm3
+ pxor %xmm1,%xmm3
+___
+}
+sub R2 {
+ my ($i,$a,$b,$c,$d)=@_;
+ my @rot2=(4,11,16,23);
+ my $j=$i%16;
+ my $k=$i%$MOD;
+ my $xmm="%xmm".($j&1);
+ $code.=" movdqu 32($in0),%xmm4\n" if ($rc4 && $j==15);
+ $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
+ $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
+ $code.=<<___;
+#rc4# movl ($dat,$YY,4),$TY#d
+#md5# xor $c,$tmp
+#rc4# movl $TX[0]#d,($dat,$YY,4)
+#md5# xor $b,$tmp
+#md5# add 4*`((5+3*$j)%16)`($inp),$a
+#rc4# add $TY#b,$TX[0]#b
+#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
+#md5# add \$$K[$i],$a
+#rc4# movz $TX[0]#b,$TX[0]#d
+#md5# add $tmp,$a
+#rc4# movl $TY#d,4*$k($XX[1])
+#rc4# add $TX[1]#b,$YY#b
+#md5# rol \$$rot2[$j%4],$a
+#md5# mov `$j==15?"\\\$-1":"$c"`,$tmp # forward reference
+#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
+#md5# add $b,$a
+___
+ $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
+ mov $YY,$XX[1]
+ xor $YY,$YY # keyword to partial register
+ mov $XX[1]#b,$YY#b
+ lea ($dat,$XX[0],4),$XX[1]
+___
+ $code.=<<___ if ($rc4 && $j==15);
+ psllq \$8,%xmm1
+ pxor %xmm0,%xmm4
+ pxor %xmm1,%xmm4
+___
+}
+sub R3 {
+ my ($i,$a,$b,$c,$d)=@_;
+ my @rot3=(6,10,15,21);
+ my $j=$i%16;
+ my $k=$i%$MOD;
+ my $xmm="%xmm".($j&1);
+ $code.=" movdqu 48($in0),%xmm5\n" if ($rc4 && $j==15);
+ $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
+ $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
+ $code.=<<___;
+#rc4# movl ($dat,$YY,4),$TY#d
+#md5# xor $d,$tmp
+#rc4# movl $TX[0]#d,($dat,$YY,4)
+#md5# or $b,$tmp
+#md5# add 4*`((7*$j)%16)`($inp),$a
+#rc4# add $TY#b,$TX[0]#b
+#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
+#md5# add \$$K[$i],$a
+#rc4# movz $TX[0]#b,$TX[0]#d
+#md5# xor $c,$tmp
+#rc4# movl $TY#d,4*$k($XX[1])
+#md5# add $tmp,$a
+#rc4# add $TX[1]#b,$YY#b
+#md5# rol \$$rot3[$j%4],$a
+#md5# mov \$-1,$tmp # forward reference
+#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
+#md5# add $b,$a
+___
+ $code.=<<___ if ($rc4 && $j==15);
+ mov $XX[0],$XX[1]
+ xor $XX[0],$XX[0] # keyword to partial register
+ mov $XX[1]#b,$XX[0]#b
+ mov $YY,$XX[1]
+ xor $YY,$YY # keyword to partial register
+ mov $XX[1]#b,$YY#b
+ lea ($dat,$XX[0],4),$XX[1]
+ psllq \$8,%xmm1
+ pxor %xmm0,%xmm5
+ pxor %xmm1,%xmm5
+___
+}
+
+my $i=0;
+for(;$i<16;$i++) { R0($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
+for(;$i<32;$i++) { R1($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
+for(;$i<48;$i++) { R2($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
+for(;$i<64;$i++) { R3($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
+
+$code.=<<___;
+#md5# add 0*4(%rsp),$V[0] # accumulate hash value
+#md5# add 1*4(%rsp),$V[1]
+#md5# add 2*4(%rsp),$V[2]
+#md5# add 3*4(%rsp),$V[3]
+
+#rc4# movdqu %xmm2,($out,$in0) # write RC4 output
+#rc4# movdqu %xmm3,16($out,$in0)
+#rc4# movdqu %xmm4,32($out,$in0)
+#rc4# movdqu %xmm5,48($out,$in0)
+#md5# lea 64($inp),$inp
+#rc4# lea 64($in0),$in0
+ cmp 16(%rsp),$inp # are we done?
+ jb .Loop
+
+#md5# mov 24(%rsp),$len # restore pointer to MD5_CTX
+#rc4# sub $TX[0]#b,$YY#b # correct $YY
+#md5# mov $V[0],0*4($len) # write MD5_CTX
+#md5# mov $V[1],1*4($len)
+#md5# mov $V[2],2*4($len)
+#md5# mov $V[3],3*4($len)
+___
+$code.=<<___ if ($rc4 && (!$md5 || $D));
+ mov 32(%rsp),$len # restore original $len
+ and \$63,$len # remaining bytes
+ jnz .Loop1
+ jmp .Ldone
+
+.align 16
+.Loop1:
+ add $TX[0]#b,$YY#b
+ movl ($dat,$YY,4),$TY#d
+ movl $TX[0]#d,($dat,$YY,4)
+ movl $TY#d,($dat,$XX[0],4)
+ add $TY#b,$TX[0]#b
+ inc $XX[0]#b
+ movl ($dat,$TX[0],4),$TY#d
+ movl ($dat,$XX[0],4),$TX[0]#d
+ xorb ($in0),$TY#b
+ movb $TY#b,($out,$in0)
+ lea 1($in0),$in0
+ dec $len
+ jnz .Loop1
+
+.Ldone:
+___
+$code.=<<___;
+#rc4# sub \$1,$XX[0]#b
+#rc4# movl $XX[0]#d,-8($dat)
+#rc4# movl $YY#d,-4($dat)
+
+ mov 40(%rsp),%r15
+ mov 48(%rsp),%r14
+ mov 56(%rsp),%r13
+ mov 64(%rsp),%r12
+ mov 72(%rsp),%rbp
+ mov 80(%rsp),%rbx
+ lea 88(%rsp),%rsp
+.Lepilogue:
+.Labort:
+ ret
+.size $func,.-$func
+___
+
+if ($rc4 && $D) { # sole purpose of this section is to provide
+ # option to use the generated module as drop-in
+ # replacement for rc4-x86_64.pl for debugging
+ # and testing purposes...
+my ($idx,$ido)=("%r8","%r9");
+my ($dat,$len,$inp)=("%rdi","%rsi","%rdx");
+
+$code.=<<___;
+.globl RC4_set_key
+.type RC4_set_key,\@function,3
+.align 16
+RC4_set_key:
+ lea 8($dat),$dat
+ lea ($inp,$len),$inp
+ neg $len
+ mov $len,%rcx
+ xor %eax,%eax
+ xor $ido,$ido
+ xor %r10,%r10
+ xor %r11,%r11
+ jmp .Lw1stloop
+
+.align 16
+.Lw1stloop:
+ mov %eax,($dat,%rax,4)
+ add \$1,%al
+ jnc .Lw1stloop
+
+ xor $ido,$ido
+ xor $idx,$idx
+.align 16
+.Lw2ndloop:
+ mov ($dat,$ido,4),%r10d
+ add ($inp,$len,1),$idx#b
+ add %r10b,$idx#b
+ add \$1,$len
+ mov ($dat,$idx,4),%r11d
+ cmovz %rcx,$len
+ mov %r10d,($dat,$idx,4)
+ mov %r11d,($dat,$ido,4)
+ add \$1,$ido#b
+ jnc .Lw2ndloop
+
+ xor %eax,%eax
+ mov %eax,-8($dat)
+ mov %eax,-4($dat)
+ ret
+.size RC4_set_key,.-RC4_set_key
+
+.globl RC4_options
+.type RC4_options,\@abi-omnipotent
+.align 16
+RC4_options:
+ lea .Lopts(%rip),%rax
+ ret
+.align 64
+.Lopts:
+.asciz "rc4(64x,int)"
+.align 64
+.size RC4_options,.-RC4_options
+___
+}
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+my $rec="%rcx";
+my $frame="%rdx";
+my $context="%r8";
+my $disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+.type se_handler,\@abi-omnipotent
+.align 16
+se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ lea .Lbody(%rip),%r10
+ cmp %r10,%rbx # context->Rip<.Lbody
+ jb .Lin_prologue
+
+ mov 152($context),%rax # pull context->Rsp
+
+ lea .Lepilogue(%rip),%r10
+ cmp %r10,%rbx # context->Rip>=.Lepilogue
+ jae .Lin_prologue
+
+ mov 40(%rax),%r15
+ mov 48(%rax),%r14
+ mov 56(%rax),%r13
+ mov 64(%rax),%r12
+ mov 72(%rax),%rbp
+ mov 80(%rax),%rbx
+ lea 88(%rax),%rax
+
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R12
+ mov %r14,232($context) # restore context->R14
+ mov %r15,240($context) # restore context->R15
+
+.Lin_prologue:
+ mov 8(%rax),%rdi
+ mov 16(%rax),%rsi
+ mov %rax,152($context) # restore context->Rsp
+ mov %rsi,168($context) # restore context->Rsi
+ mov %rdi,176($context) # restore context->Rdi
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$154,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size se_handler,.-se_handler
+
+.section .pdata
+.align 4
+ .rva .LSEH_begin_$func
+ .rva .LSEH_end_$func
+ .rva .LSEH_info_$func
+
+.section .xdata
+.align 8
+.LSEH_info_$func:
+ .byte 9,0,0,0
+ .rva se_handler
+___
+}
+
+sub reg_part {
+my ($reg,$conv)=@_;
+ if ($reg =~ /%r[0-9]+/) { $reg .= $conv; }
+ elsif ($conv eq "b") { $reg =~ s/%[er]([^x]+)x?/%$1l/; }
+ elsif ($conv eq "w") { $reg =~ s/%[er](.+)/%$1/; }
+ elsif ($conv eq "d") { $reg =~ s/%[er](.+)/%e$1/; }
+ return $reg;
+}
+
+$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/pinsrw\s+\$0,/movd /gm;
+
+$code =~ s/#md5#//gm if ($md5);
+$code =~ s/#rc4#//gm if ($rc4);
+
+print $code;
+
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/rc4/asm/rc4-parisc.pl b/deps/openssl/openssl/crypto/rc4/asm/rc4-parisc.pl
new file mode 100644
index 000000000..916506708
--- /dev/null
+++ b/deps/openssl/openssl/crypto/rc4/asm/rc4-parisc.pl
@@ -0,0 +1,313 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# RC4 for PA-RISC.
+
+# June 2009.
+#
+# Performance is 33% better than gcc 3.2 generated code on PA-7100LC.
+# For reference, [4x] unrolled loop is >40% faster than folded one.
+# It's possible to unroll loop 8 times on PA-RISC 2.0, but improvement
+# is believed to be not sufficient to justify the effort...
+#
+# Special thanks to polarhome.com for providing HP-UX account.
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+
+$flavour = shift;
+$output = shift;
+open STDOUT,">$output";
+
+if ($flavour =~ /64/) {
+ $LEVEL ="2.0W";
+ $SIZE_T =8;
+ $FRAME_MARKER =80;
+ $SAVED_RP =16;
+ $PUSH ="std";
+ $PUSHMA ="std,ma";
+ $POP ="ldd";
+ $POPMB ="ldd,mb";
+} else {
+ $LEVEL ="1.0";
+ $SIZE_T =4;
+ $FRAME_MARKER =48;
+ $SAVED_RP =20;
+ $PUSH ="stw";
+ $PUSHMA ="stwm";
+ $POP ="ldw";
+ $POPMB ="ldwm";
+}
+
+$FRAME=4*$SIZE_T+$FRAME_MARKER; # 4 saved regs + frame marker
+ # [+ argument transfer]
+$SZ=1; # defaults to RC4_CHAR
+if (open CONF,"<${dir}../../opensslconf.h") {
+ while(<CONF>) {
+ if (m/#\s*define\s+RC4_INT\s+(.*)/) {
+ $SZ = ($1=~/char$/) ? 1 : 4;
+ last;
+ }
+ }
+ close CONF;
+}
+
+if ($SZ==1) { # RC4_CHAR
+ $LD="ldb";
+ $LDX="ldbx";
+ $MKX="addl";
+ $ST="stb";
+} else { # RC4_INT (~5% faster than RC4_CHAR on PA-7100LC)
+ $LD="ldw";
+ $LDX="ldwx,s";
+ $MKX="sh2addl";
+ $ST="stw";
+}
+
+$key="%r26";
+$len="%r25";
+$inp="%r24";
+$out="%r23";
+
+@XX=("%r19","%r20");
+@TX=("%r21","%r22");
+$YY="%r28";
+$TY="%r29";
+
+$acc="%r1";
+$ix="%r2";
+$iy="%r3";
+$dat0="%r4";
+$dat1="%r5";
+$rem="%r6";
+$mask="%r31";
+
+sub unrolledloopbody {
+for ($i=0;$i<4;$i++) {
+$code.=<<___;
+ ldo 1($XX[0]),$XX[1]
+ `sprintf("$LDX %$TY(%$key),%$dat1") if ($i>0)`
+ and $mask,$XX[1],$XX[1]
+ $LDX $YY($key),$TY
+ $MKX $YY,$key,$ix
+ $LDX $XX[1]($key),$TX[1]
+ $MKX $XX[0],$key,$iy
+ $ST $TX[0],0($ix)
+ comclr,<> $XX[1],$YY,%r0 ; conditional
+ copy $TX[0],$TX[1] ; move
+ `sprintf("%sdep %$dat1,%d,8,%$acc",$i==1?"z":"",8*($i-1)+7) if ($i>0)`
+ $ST $TY,0($iy)
+ addl $TX[0],$TY,$TY
+ addl $TX[1],$YY,$YY
+ and $mask,$TY,$TY
+ and $mask,$YY,$YY
+___
+push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers
+} }
+
+sub foldedloop {
+my ($label,$count)=@_;
+$code.=<<___;
+$label
+ $MKX $YY,$key,$iy
+ $LDX $YY($key),$TY
+ $MKX $XX[0],$key,$ix
+ $ST $TX[0],0($iy)
+ ldo 1($XX[0]),$XX[0]
+ $ST $TY,0($ix)
+ addl $TX[0],$TY,$TY
+ ldbx $inp($out),$dat1
+ and $mask,$TY,$TY
+ and $mask,$XX[0],$XX[0]
+ $LDX $TY($key),$acc
+ $LDX $XX[0]($key),$TX[0]
+ ldo 1($out),$out
+ xor $dat1,$acc,$acc
+ addl $TX[0],$YY,$YY
+ stb $acc,-1($out)
+ addib,<> -1,$count,$label ; $count is always small
+ and $mask,$YY,$YY
+___
+}
+
+$code=<<___;
+ .LEVEL $LEVEL
+ .SPACE \$TEXT\$
+ .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
+
+ .EXPORT RC4,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+RC4
+ .PROC
+ .CALLINFO FRAME=`$FRAME-4*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=6
+ .ENTRY
+ $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue
+ $PUSHMA %r3,$FRAME(%sp)
+ $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp)
+ $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp)
+ $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp)
+
+ cmpib,*= 0,$len,L\$abort
+ sub $inp,$out,$inp ; distance between $inp and $out
+
+ $LD `0*$SZ`($key),$XX[0]
+ $LD `1*$SZ`($key),$YY
+ ldo `2*$SZ`($key),$key
+
+ ldi 0xff,$mask
+ ldi 3,$dat0
+
+ ldo 1($XX[0]),$XX[0] ; warm up loop
+ and $mask,$XX[0],$XX[0]
+ $LDX $XX[0]($key),$TX[0]
+ addl $TX[0],$YY,$YY
+ cmpib,*>>= 6,$len,L\$oop1 ; is $len large enough to bother?
+ and $mask,$YY,$YY
+
+ and,<> $out,$dat0,$rem ; is $out aligned?
+ b L\$alignedout
+ subi 4,$rem,$rem
+ sub $len,$rem,$len
+___
+&foldedloop("L\$alignout",$rem); # process till $out is aligned
+
+$code.=<<___;
+L\$alignedout ; $len is at least 4 here
+ and,<> $inp,$dat0,$acc ; is $inp aligned?
+ b L\$oop4
+ sub $inp,$acc,$rem ; align $inp
+
+ sh3addl $acc,%r0,$acc
+ subi 32,$acc,$acc
+ mtctl $acc,%cr11 ; load %sar with vshd align factor
+ ldwx $rem($out),$dat0
+ ldo 4($rem),$rem
+L\$oop4misalignedinp
+___
+&unrolledloopbody();
+$code.=<<___;
+ $LDX $TY($key),$ix
+ ldwx $rem($out),$dat1
+ ldo -4($len),$len
+ or $ix,$acc,$acc ; last piece, no need to dep
+ vshd $dat0,$dat1,$iy ; align data
+ copy $dat1,$dat0
+ xor $iy,$acc,$acc
+ stw $acc,0($out)
+ cmpib,*<< 3,$len,L\$oop4misalignedinp
+ ldo 4($out),$out
+ cmpib,*= 0,$len,L\$done
+ nop
+ b L\$oop1
+ nop
+
+ .ALIGN 8
+L\$oop4
+___
+&unrolledloopbody();
+$code.=<<___;
+ $LDX $TY($key),$ix
+ ldwx $inp($out),$dat0
+ ldo -4($len),$len
+ or $ix,$acc,$acc ; last piece, no need to dep
+ xor $dat0,$acc,$acc
+ stw $acc,0($out)
+ cmpib,*<< 3,$len,L\$oop4
+ ldo 4($out),$out
+ cmpib,*= 0,$len,L\$done
+ nop
+___
+&foldedloop("L\$oop1",$len);
+$code.=<<___;
+L\$done
+ $POP `-$FRAME-$SAVED_RP`(%sp),%r2
+ ldo -1($XX[0]),$XX[0] ; chill out loop
+ sub $YY,$TX[0],$YY
+ and $mask,$XX[0],$XX[0]
+ and $mask,$YY,$YY
+ $ST $XX[0],`-2*$SZ`($key)
+ $ST $YY,`-1*$SZ`($key)
+ $POP `-$FRAME+1*$SIZE_T`(%sp),%r4
+ $POP `-$FRAME+2*$SIZE_T`(%sp),%r5
+ $POP `-$FRAME+3*$SIZE_T`(%sp),%r6
+L\$abort
+ bv (%r2)
+ .EXIT
+ $POPMB -$FRAME(%sp),%r3
+ .PROCEND
+___
+
+$code.=<<___;
+
+ .EXPORT private_RC4_set_key,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
+ .ALIGN 8
+private_RC4_set_key
+ .PROC
+ .CALLINFO NO_CALLS
+ .ENTRY
+ $ST %r0,`0*$SZ`($key)
+ $ST %r0,`1*$SZ`($key)
+ ldo `2*$SZ`($key),$key
+ copy %r0,@XX[0]
+L\$1st
+ $ST @XX[0],0($key)
+ ldo 1(@XX[0]),@XX[0]
+ bb,>= @XX[0],`31-8`,L\$1st ; @XX[0]<256
+ ldo $SZ($key),$key
+
+ ldo `-256*$SZ`($key),$key ; rewind $key
+ addl $len,$inp,$inp ; $inp to point at the end
+ sub %r0,$len,%r23 ; inverse index
+ copy %r0,@XX[0]
+ copy %r0,@XX[1]
+ ldi 0xff,$mask
+
+L\$2nd
+ $LDX @XX[0]($key),@TX[0]
+ ldbx %r23($inp),@TX[1]
+ addi,nuv 1,%r23,%r23 ; increment and conditional
+ sub %r0,$len,%r23 ; inverse index
+ addl @TX[0],@XX[1],@XX[1]
+ addl @TX[1],@XX[1],@XX[1]
+ and $mask,@XX[1],@XX[1]
+ $MKX @XX[0],$key,$TY
+ $LDX @XX[1]($key),@TX[1]
+ $MKX @XX[1],$key,$YY
+ ldo 1(@XX[0]),@XX[0]
+ $ST @TX[0],0($YY)
+ bb,>= @XX[0],`31-8`,L\$2nd ; @XX[0]<256
+ $ST @TX[1],0($TY)
+
+ bv,n (%r2)
+ .EXIT
+ nop
+ .PROCEND
+
+ .EXPORT RC4_options,ENTRY
+ .ALIGN 8
+RC4_options
+ .PROC
+ .CALLINFO NO_CALLS
+ .ENTRY
+ blr %r0,%r28
+ ldi 3,%r1
+L\$pic
+ andcm %r28,%r1,%r28
+ bv (%r2)
+ .EXIT
+ ldo L\$opts-L\$pic(%r28),%r28
+ .PROCEND
+ .ALIGN 8
+L\$opts
+ .STRINGZ "rc4(4x,`$SZ==1?"char":"int"`)"
+ .STRINGZ "RC4 for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
+___
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/cmpib,\*/comib,/gm if ($SIZE_T==4);
+
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/rc4/asm/rc4-s390x.pl b/deps/openssl/openssl/crypto/rc4/asm/rc4-s390x.pl
index 96681fa05..7528ece13 100644
--- a/deps/openssl/openssl/crypto/rc4/asm/rc4-s390x.pl
+++ b/deps/openssl/openssl/crypto/rc4/asm/rc4-s390x.pl
@@ -13,6 +13,29 @@
# "cluster" Address Generation Interlocks, so that one pipeline stall
# resolves several dependencies.
+# November 2010.
+#
+# Adapt for -m31 build. If kernel supports what's called "highgprs"
+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
+# instructions and achieve "64-bit" performance even in 31-bit legacy
+# application context. The feature is not specific to any particular
+# processor, as long as it's "z-CPU". Latter implies that the code
+# remains z/Architecture specific. On z990 it was measured to perform
+# 50% better than code generated by gcc 4.3.
+
+$flavour = shift;
+
+if ($flavour =~ /3[12]/) {
+ $SIZE_T=4;
+ $g="";
+} else {
+ $SIZE_T=8;
+ $g="g";
+}
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
$rp="%r14";
$sp="%r15";
$code=<<___;
@@ -39,7 +62,12 @@ $code.=<<___;
.type RC4,\@function
.align 64
RC4:
- stmg %r6,%r11,48($sp)
+ stm${g} %r6,%r11,6*$SIZE_T($sp)
+___
+$code.=<<___ if ($flavour =~ /3[12]/);
+ llgfr $len,$len
+___
+$code.=<<___;
llgc $XX[0],0($key)
llgc $YY,1($key)
la $XX[0],1($XX[0])
@@ -90,7 +118,7 @@ $code.=<<___;
xgr $acc,$TX[1]
stg $acc,0($out)
la $out,8($out)
- brct $cnt,.Loop8
+ brctg $cnt,.Loop8
.Lshort:
lghi $acc,7
@@ -122,7 +150,7 @@ $code.=<<___;
ahi $XX[0],-1
stc $XX[0],0($key)
stc $YY,1($key)
- lmg %r6,%r11,48($sp)
+ lm${g} %r6,%r11,6*$SIZE_T($sp)
br $rp
.size RC4,.-RC4
.string "RC4 for s390x, CRYPTOGAMS by <appro\@openssl.org>"
@@ -143,11 +171,11 @@ $ikey="%r7";
$iinp="%r8";
$code.=<<___;
-.globl RC4_set_key
-.type RC4_set_key,\@function
+.globl private_RC4_set_key
+.type private_RC4_set_key,\@function
.align 64
-RC4_set_key:
- stmg %r6,%r8,48($sp)
+private_RC4_set_key:
+ stm${g} %r6,%r8,6*$SIZE_T($sp)
lhi $cnt,256
la $idx,0(%r0)
sth $idx,0($key)
@@ -180,9 +208,9 @@ RC4_set_key:
la $iinp,0(%r0)
j .L2ndloop
.Ldone:
- lmg %r6,%r8,48($sp)
+ lm${g} %r6,%r8,6*$SIZE_T($sp)
br $rp
-.size RC4_set_key,.-RC4_set_key
+.size private_RC4_set_key,.-private_RC4_set_key
___
}
@@ -203,3 +231,4 @@ RC4_options:
___
print $code;
+close STDOUT; # force flush
diff --git a/deps/openssl/openssl/crypto/rc4/asm/rc4-x86_64.pl b/deps/openssl/openssl/crypto/rc4/asm/rc4-x86_64.pl
index 677be5fe2..75750dbf3 100755
--- a/deps/openssl/openssl/crypto/rc4/asm/rc4-x86_64.pl
+++ b/deps/openssl/openssl/crypto/rc4/asm/rc4-x86_64.pl
@@ -7,6 +7,8 @@
# details see http://www.openssl.org/~appro/cryptogams/.
# ====================================================================
#
+# July 2004
+#
# 2.22x RC4 tune-up:-) It should be noted though that my hand [as in
# "hand-coded assembler"] doesn't stand for the whole improvement
# coefficient. It turned out that eliminating RC4_CHAR from config
@@ -19,6 +21,8 @@
# to operate on partial registers, it turned out to be the best bet.
# At least for AMD... How IA32E would perform remains to be seen...
+# November 2004
+#
# As was shown by Marc Bevand reordering of couple of load operations
# results in even higher performance gain of 3.3x:-) At least on
# Opteron... For reference, 1x in this case is RC4_CHAR C-code
@@ -26,6 +30,8 @@
# Latter means that if you want to *estimate* what to expect from
# *your* Opteron, then multiply 54 by 3.3 and clock frequency in GHz.
+# November 2004
+#
# Intel P4 EM64T core was found to run the AMD64 code really slow...
# The only way to achieve comparable performance on P4 was to keep
# RC4_CHAR. Kind of ironic, huh? As it's apparently impossible to
@@ -33,10 +39,14 @@
# on either AMD and Intel platforms, I implement both cases. See
# rc4_skey.c for further details...
+# April 2005
+#
# P4 EM64T core appears to be "allergic" to 64-bit inc/dec. Replacing
# those with add/sub results in 50% performance improvement of folded
# loop...
+# May 2005
+#
# As was shown by Zou Nanhai loop unrolling can improve Intel EM64T
# performance by >30% [unlike P4 32-bit case that is]. But this is
# provided that loads are reordered even more aggressively! Both code
@@ -50,6 +60,8 @@
# is not implemented, then this final RC4_CHAR code-path should be
# preferred, as it provides better *all-round* performance].
+# March 2007
+#
# Intel Core2 was observed to perform poorly on both code paths:-( It
# apparently suffers from some kind of partial register stall, which
# occurs in 64-bit mode only [as virtually identical 32-bit loop was
@@ -58,6 +70,37 @@
# fit for Core2 and therefore the code was modified to skip cloop8 on
# this CPU.
+# May 2010
+#
+# Intel Westmere was observed to perform suboptimally. Adding yet
+# another movzb to cloop1 improved performance by almost 50%! Core2
+# performance is improved too, but nominally...
+
+# May 2011
+#
+# The only code path that was not modified is P4-specific one. Non-P4
+# Intel code path optimization is heavily based on submission by Maxim
+# Perminov, Maxim Locktyukhin and Jim Guilford of Intel. I've used
+# some of the ideas even in attempt to optmize the original RC4_INT
+# code path... Current performance in cycles per processed byte (less
+# is better) and improvement coefficients relative to previous
+# version of this module are:
+#
+# Opteron 5.3/+0%(*)
+# P4 6.5
+# Core2 6.2/+15%(**)
+# Westmere 4.2/+60%
+# Sandy Bridge 4.2/+120%
+# Atom 9.3/+80%
+#
+# (*) But corresponding loop has less instructions, which should have
+# positive effect on upcoming Bulldozer, which has one less ALU.
+# For reference, Intel code runs at 6.8 cpb rate on Opteron.
+# (**) Note that Core2 result is ~15% lower than corresponding result
+# for 32-bit code, meaning that it's possible to improve it,
+# but more than likely at the cost of the others (see rc4-586.pl
+# to get the idea)...
+
$flavour = shift;
$output = shift;
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
@@ -69,20 +112,18 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
$dat="%rdi"; # arg1
$len="%rsi"; # arg2
$inp="%rdx"; # arg3
$out="%rcx"; # arg4
-@XX=("%r8","%r10");
-@TX=("%r9","%r11");
-$YY="%r12";
-$TY="%r13";
-
+{
$code=<<___;
.text
+.extern OPENSSL_ia32cap_P
.globl RC4
.type RC4,\@function,4
@@ -95,48 +136,173 @@ RC4: or $len,$len
push %r12
push %r13
.Lprologue:
+ mov $len,%r11
+ mov $inp,%r12
+ mov $out,%r13
+___
+my $len="%r11"; # reassign input arguments
+my $inp="%r12";
+my $out="%r13";
- add \$8,$dat
- movl -8($dat),$XX[0]#d
- movl -4($dat),$YY#d
+my @XX=("%r10","%rsi");
+my @TX=("%rax","%rbx");
+my $YY="%rcx";
+my $TY="%rdx";
+
+$code.=<<___;
+ xor $XX[0],$XX[0]
+ xor $YY,$YY
+
+ lea 8($dat),$dat
+ mov -8($dat),$XX[0]#b
+ mov -4($dat),$YY#b
cmpl \$-1,256($dat)
je .LRC4_CHAR
+ mov OPENSSL_ia32cap_P(%rip),%r8d
+ xor $TX[1],$TX[1]
inc $XX[0]#b
+ sub $XX[0],$TX[1]
+ sub $inp,$out
movl ($dat,$XX[0],4),$TX[0]#d
- test \$-8,$len
+ test \$-16,$len
jz .Lloop1
- jmp .Lloop8
+ bt \$30,%r8d # Intel CPU?
+ jc .Lintel
+ and \$7,$TX[1]
+ lea 1($XX[0]),$XX[1]
+ jz .Loop8
+ sub $TX[1],$len
+.Loop8_warmup:
+ add $TX[0]#b,$YY#b
+ movl ($dat,$YY,4),$TY#d
+ movl $TX[0]#d,($dat,$YY,4)
+ movl $TY#d,($dat,$XX[0],4)
+ add $TY#b,$TX[0]#b
+ inc $XX[0]#b
+ movl ($dat,$TX[0],4),$TY#d
+ movl ($dat,$XX[0],4),$TX[0]#d
+ xorb ($inp),$TY#b
+ movb $TY#b,($out,$inp)
+ lea 1($inp),$inp
+ dec $TX[1]
+ jnz .Loop8_warmup
+
+ lea 1($XX[0]),$XX[1]
+ jmp .Loop8
.align 16
-.Lloop8:
+.Loop8:
___
for ($i=0;$i<8;$i++) {
+$code.=<<___ if ($i==7);
+ add \$8,$XX[1]#b
+___
$code.=<<___;
add $TX[0]#b,$YY#b
- mov $XX[0],$XX[1]
movl ($dat,$YY,4),$TY#d
- ror \$8,%rax # ror is redundant when $i=0
- inc $XX[1]#b
- movl ($dat,$XX[1],4),$TX[1]#d
- cmp $XX[1],$YY
movl $TX[0]#d,($dat,$YY,4)
- cmove $TX[0],$TX[1]
- movl $TY#d,($dat,$XX[0],4)
+ movl `4*($i==7?-1:$i)`($dat,$XX[1],4),$TX[1]#d
+ ror \$8,%r8 # ror is redundant when $i=0
+ movl $TY#d,4*$i($dat,$XX[0],4)
add $TX[0]#b,$TY#b
- movb ($dat,$TY,4),%al
+ movb ($dat,$TY,4),%r8b
___
-push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers
+push(@TX,shift(@TX)); #push(@XX,shift(@XX)); # "rotate" registers
}
$code.=<<___;
- ror \$8,%rax
+ add \$8,$XX[0]#b
+ ror \$8,%r8
sub \$8,$len
- xor ($inp),%rax
- add \$8,$inp
- mov %rax,($out)
- add \$8,$out
+ xor ($inp),%r8
+ mov %r8,($out,$inp)
+ lea 8($inp),$inp
test \$-8,$len
- jnz .Lloop8
+ jnz .Loop8
+ cmp \$0,$len
+ jne .Lloop1
+ jmp .Lexit
+
+.align 16
+.Lintel:
+ test \$-32,$len
+ jz .Lloop1
+ and \$15,$TX[1]
+ jz .Loop16_is_hot
+ sub $TX[1],$len
+.Loop16_warmup:
+ add $TX[0]#b,$YY#b
+ movl ($dat,$YY,4),$TY#d
+ movl $TX[0]#d,($dat,$YY,4)
+ movl $TY#d,($dat,$XX[0],4)
+ add $TY#b,$TX[0]#b
+ inc $XX[0]#b
+ movl ($dat,$TX[0],4),$TY#d
+ movl ($dat,$XX[0],4),$TX[0]#d
+ xorb ($inp),$TY#b
+ movb $TY#b,($out,$inp)
+ lea 1($inp),$inp
+ dec $TX[1]
+ jnz .Loop16_warmup
+
+ mov $YY,$TX[1]
+ xor $YY,$YY
+ mov $TX[1]#b,$YY#b
+
+.Loop16_is_hot:
+ lea ($dat,$XX[0],4),$XX[1]
+___
+sub RC4_loop {
+ my $i=shift;
+ my $j=$i<0?0:$i;
+ my $xmm="%xmm".($j&1);
+
+ $code.=" add \$16,$XX[0]#b\n" if ($i==15);
+ $code.=" movdqu ($inp),%xmm2\n" if ($i==15);
+ $code.=" add $TX[0]#b,$YY#b\n" if ($i<=0);
+ $code.=" movl ($dat,$YY,4),$TY#d\n";
+ $code.=" pxor %xmm0,%xmm2\n" if ($i==0);
+ $code.=" psllq \$8,%xmm1\n" if ($i==0);
+ $code.=" pxor $xmm,$xmm\n" if ($i<=1);
+ $code.=" movl $TX[0]#d,($dat,$YY,4)\n";
+ $code.=" add $TY#b,$TX[0]#b\n";
+ $code.=" movl `4*($j+1)`($XX[1]),$TX[1]#d\n" if ($i<15);
+ $code.=" movz $TX[0]#b,$TX[0]#d\n";
+ $code.=" movl $TY#d,4*$j($XX[1])\n";
+ $code.=" pxor %xmm1,%xmm2\n" if ($i==0);
+ $code.=" lea ($dat,$XX[0],4),$XX[1]\n" if ($i==15);
+ $code.=" add $TX[1]#b,$YY#b\n" if ($i<15);
+ $code.=" pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n";
+ $code.=" movdqu %xmm2,($out,$inp)\n" if ($i==0);
+ $code.=" lea 16($inp),$inp\n" if ($i==0);
+ $code.=" movl ($XX[1]),$TX[1]#d\n" if ($i==15);
+}
+ RC4_loop(-1);
+$code.=<<___;
+ jmp .Loop16_enter
+.align 16
+.Loop16:
+___
+
+for ($i=0;$i<16;$i++) {
+ $code.=".Loop16_enter:\n" if ($i==1);
+ RC4_loop($i);
+ push(@TX,shift(@TX)); # "rotate" registers
+}
+$code.=<<___;
+ mov $YY,$TX[1]
+ xor $YY,$YY # keyword to partial register
+ sub \$16,$len
+ mov $TX[1]#b,$YY#b
+ test \$-16,$len
+ jnz .Loop16
+
+ psllq \$8,%xmm1
+ pxor %xmm0,%xmm2
+ pxor %xmm1,%xmm2
+ movdqu %xmm2,($out,$inp)
+ lea 16($inp),$inp
+
cmp \$0,$len
jne .Lloop1
jmp .Lexit
@@ -152,9 +318,8 @@ $code.=<<___;
movl ($dat,$TX[0],4),$TY#d
movl ($dat,$XX[0],4),$TX[0]#d
xorb ($inp),$TY#b
- inc $inp
- movb $TY#b,($out)
- inc $out
+ movb $TY#b,($out,$inp)
+ lea 1($inp),$inp
dec $len
jnz .Lloop1
jmp .Lexit
@@ -165,13 +330,11 @@ $code.=<<___;
movzb ($dat,$XX[0]),$TX[0]#d
test \$-8,$len
jz .Lcloop1
- cmpl \$0,260($dat)
- jnz .Lcloop1
jmp .Lcloop8
.align 16
.Lcloop8:
- mov ($inp),%eax
- mov 4($inp),%ebx
+ mov ($inp),%r8d
+ mov 4($inp),%r9d
___
# unroll 2x4-wise, because 64-bit rotates kill Intel P4...
for ($i=0;$i<4;$i++) {
@@ -188,8 +351,8 @@ $code.=<<___;
mov $TX[0],$TX[1]
.Lcmov$i:
add $TX[0]#b,$TY#b
- xor ($dat,$TY),%al
- ror \$8,%eax
+ xor ($dat,$TY),%r8b
+ ror \$8,%r8d
___
push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers
}
@@ -207,16 +370,16 @@ $code.=<<___;
mov $TX[0],$TX[1]
.Lcmov$i:
add $TX[0]#b,$TY#b
- xor ($dat,$TY),%bl
- ror \$8,%ebx
+ xor ($dat,$TY),%r9b
+ ror \$8,%r9d
___
push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers
}
$code.=<<___;
lea -8($len),$len
- mov %eax,($out)
+ mov %r8d,($out)
lea 8($inp),$inp
- mov %ebx,4($out)
+ mov %r9d,4($out)
lea 8($out),$out
test \$-8,$len
@@ -229,6 +392,7 @@ $code.=<<___;
.align 16
.Lcloop1:
add $TX[0]#b,$YY#b
+ movzb $YY#b,$YY#d
movzb ($dat,$YY),$TY#d
movb $TX[0]#b,($dat,$YY)
movb $TY#b,($dat,$XX[0])
@@ -260,16 +424,16 @@ $code.=<<___;
ret
.size RC4,.-RC4
___
+}
$idx="%r8";
$ido="%r9";
$code.=<<___;
-.extern OPENSSL_ia32cap_P
-.globl RC4_set_key
-.type RC4_set_key,\@function,3
+.globl private_RC4_set_key
+.type private_RC4_set_key,\@function,3
.align 16
-RC4_set_key:
+private_RC4_set_key:
lea 8($dat),$dat
lea ($inp,$len),$inp
neg $len
@@ -280,12 +444,9 @@ RC4_set_key:
xor %r11,%r11
mov OPENSSL_ia32cap_P(%rip),$idx#d
- bt \$20,$idx#d
- jnc .Lw1stloop
- bt \$30,$idx#d
- setc $ido#b
- mov $ido#d,260($dat)
- jmp .Lc1stloop
+ bt \$20,$idx#d # RC4_CHAR?
+ jc .Lc1stloop
+ jmp .Lw1stloop
.align 16
.Lw1stloop:
@@ -339,7 +500,7 @@ RC4_set_key:
mov %eax,-8($dat)
mov %eax,-4($dat)
ret
-.size RC4_set_key,.-RC4_set_key
+.size private_RC4_set_key,.-private_RC4_set_key
.globl RC4_options
.type RC4_options,\@abi-omnipotent
@@ -348,18 +509,20 @@ RC4_options:
lea .Lopts(%rip),%rax
mov OPENSSL_ia32cap_P(%rip),%edx
bt \$20,%edx
- jnc .Ldone
- add \$12,%rax
+ jc .L8xchar
bt \$30,%edx
jnc .Ldone
- add \$13,%rax
+ add \$25,%rax
+ ret
+.L8xchar:
+ add \$12,%rax
.Ldone:
ret
.align 64
.Lopts:
.asciz "rc4(8x,int)"
.asciz "rc4(8x,char)"
-.asciz "rc4(1x,char)"
+.asciz "rc4(16x,int)"
.asciz "RC4 for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
.align 64
.size RC4_options,.-RC4_options
@@ -482,22 +645,32 @@ key_se_handler:
.rva .LSEH_end_RC4
.rva .LSEH_info_RC4
- .rva .LSEH_begin_RC4_set_key
- .rva .LSEH_end_RC4_set_key
- .rva .LSEH_info_RC4_set_key
+ .rva .LSEH_begin_private_RC4_set_key
+ .rva .LSEH_end_private_RC4_set_key
+ .rva .LSEH_info_private_RC4_set_key
.section .xdata
.align 8
.LSEH_info_RC4:
.byte 9,0,0,0
.rva stream_se_handler
-.LSEH_info_RC4_set_key:
+.LSEH_info_private_RC4_set_key:
.byte 9,0,0,0
.rva key_se_handler
___
}
-$code =~ s/#([bwd])/$1/gm;
+sub reg_part {
+my ($reg,$conv)=@_;
+ if ($reg =~ /%r[0-9]+/) { $reg .= $conv; }
+ elsif ($conv eq "b") { $reg =~ s/%[er]([^x]+)x?/%$1l/; }
+ elsif ($conv eq "w") { $reg =~ s/%[er](.+)/%$1/; }
+ elsif ($conv eq "d") { $reg =~ s/%[er](.+)/%e$1/; }
+ return $reg;
+}
+
+$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
print $code;
diff --git a/deps/openssl/openssl/crypto/rc4/rc4.h b/deps/openssl/openssl/crypto/rc4/rc4.h
index 29d1acccf..88ceb46bc 100644
--- a/deps/openssl/openssl/crypto/rc4/rc4.h
+++ b/deps/openssl/openssl/crypto/rc4/rc4.h
@@ -79,6 +79,7 @@ typedef struct rc4_key_st
const char *RC4_options(void);
void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
unsigned char *outdata);
diff --git a/deps/openssl/openssl/crypto/rc4/rc4_skey.c b/deps/openssl/openssl/crypto/rc4/rc4_skey.c
index b22c40b0b..fda27636e 100644
--- a/deps/openssl/openssl/crypto/rc4/rc4_skey.c
+++ b/deps/openssl/openssl/crypto/rc4/rc4_skey.c
@@ -85,7 +85,7 @@ const char *RC4_options(void)
* Date: Wed, 14 Sep 1994 06:35:31 GMT
*/
-void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
{
register RC4_INT tmp;
register int id1,id2;
@@ -104,40 +104,6 @@ void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
d[(n)]=d[id2]; \
d[id2]=tmp; }
-#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM)
-# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
- defined(__INTEL__) || \
- defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64)
- if (sizeof(RC4_INT) > 1) {
- /*
- * Unlike all other x86 [and x86_64] implementations,
- * Intel P4 core [including EM64T] was found to perform
- * poorly with wider RC4_INT. Performance improvement
- * for IA-32 hand-coded assembler turned out to be 2.8x
- * if re-coded for RC4_CHAR! It's however inappropriate
- * to just switch to RC4_CHAR for x86[_64], as non-P4
- * implementations suffer from significant performance
- * losses then, e.g. PIII exhibits >2x deterioration,
- * and so does Opteron. In order to assure optimal
- * all-round performance, let us [try to] detect P4 at
- * run-time by checking upon HTT bit in CPU capability
- * vector and set up compressed key schedule, which is
- * recognized by correspondingly updated assembler
- * module...
- * <appro@fy.chalmers.se>
- */
- if (OPENSSL_ia32cap_P & (1<<28)) {
- unsigned char *cp=(unsigned char *)d;
-
- for (i=0;i<256;i++) cp[i]=i;
- for (i=0;i<256;i++) SK_LOOP(cp,i);
- /* mark schedule as compressed! */
- d[256/sizeof(RC4_INT)]=-1;
- return;
- }
- }
-# endif
-#endif
for (i=0; i < 256; i++) d[i]=i;
for (i=0; i < 256; i+=4)
{
diff --git a/deps/openssl/openssl/crypto/rc4/rc4_utl.c b/deps/openssl/openssl/crypto/rc4/rc4_utl.c
new file mode 100644
index 000000000..ab3f02fe6
--- /dev/null
+++ b/deps/openssl/openssl/crypto/rc4/rc4_utl.c
@@ -0,0 +1,62 @@
+/* crypto/rc4/rc4_utl.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 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.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include <openssl/rc4.h>
+
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+ {
+#ifdef OPENSSL_FIPS
+ fips_cipher_abort(RC4);
+#endif
+ private_RC4_set_key(key, len, data);
+ }
diff --git a/deps/openssl/openssl/crypto/rc4/rc4test.c b/deps/openssl/openssl/crypto/rc4/rc4test.c
index 633a79e75..4312605cc 100644
--- a/deps/openssl/openssl/crypto/rc4/rc4test.c
+++ b/deps/openssl/openssl/crypto/rc4/rc4test.c
@@ -120,6 +120,12 @@ int main(int argc, char *argv[])
RC4_KEY key;
unsigned char obuf[512];
+#if !defined(OPENSSL_PIC)
+ void OPENSSL_cpuid_setup(void);
+
+ OPENSSL_cpuid_setup();
+#endif
+
for (i=0; i<6; i++)
{
RC4_set_key(&key,keys[i][0],&(keys[i][1]));
diff --git a/deps/openssl/openssl/crypto/ripemd/Makefile b/deps/openssl/openssl/crypto/ripemd/Makefile
index d5b1067db..25140b2a7 100644
--- a/deps/openssl/openssl/crypto/ripemd/Makefile
+++ b/deps/openssl/openssl/crypto/ripemd/Makefile
@@ -82,8 +82,11 @@ clean:
# DO NOT DELETE THIS LINE -- make depend depends on it.
-rmd_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-rmd_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ripemd.h
+rmd_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rmd_dgst.o: ../../include/openssl/opensslconf.h
+rmd_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rmd_dgst.o: ../../include/openssl/ripemd.h ../../include/openssl/safestack.h
+rmd_dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
rmd_dgst.o: ../md32_common.h rmd_dgst.c rmd_locl.h rmdconst.h
rmd_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
rmd_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
diff --git a/deps/openssl/openssl/crypto/ripemd/ripemd.h b/deps/openssl/openssl/crypto/ripemd/ripemd.h
index 5942eb618..189bd8c90 100644
--- a/deps/openssl/openssl/crypto/ripemd/ripemd.h
+++ b/deps/openssl/openssl/crypto/ripemd/ripemd.h
@@ -91,6 +91,9 @@ typedef struct RIPEMD160state_st
unsigned int num;
} RIPEMD160_CTX;
+#ifdef OPENSSL_FIPS
+int private_RIPEMD160_Init(RIPEMD160_CTX *c);
+#endif
int RIPEMD160_Init(RIPEMD160_CTX *c);
int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len);
int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
diff --git a/deps/openssl/openssl/crypto/ripemd/rmd_dgst.c b/deps/openssl/openssl/crypto/ripemd/rmd_dgst.c
index 59b017f8c..d8e72da51 100644
--- a/deps/openssl/openssl/crypto/ripemd/rmd_dgst.c
+++ b/deps/openssl/openssl/crypto/ripemd/rmd_dgst.c
@@ -59,6 +59,7 @@
#include <stdio.h>
#include "rmd_locl.h"
#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT;
@@ -69,7 +70,7 @@ const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT;
void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num);
# endif
-int RIPEMD160_Init(RIPEMD160_CTX *c)
+fips_md_init(RIPEMD160)
{
memset (c,0,sizeof(*c));
c->A=RIPEMD160_A;
@@ -104,21 +105,21 @@ void ripemd160_block_data_order (RIPEMD160_CTX *ctx, const void *p, size_t num)
A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
- HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l;
- RIP1(A,B,C,D,E,WL00,SL00); HOST_c2l(data,l); X( 2)=l;
- RIP1(E,A,B,C,D,WL01,SL01); HOST_c2l(data,l); X( 3)=l;
- RIP1(D,E,A,B,C,WL02,SL02); HOST_c2l(data,l); X( 4)=l;
- RIP1(C,D,E,A,B,WL03,SL03); HOST_c2l(data,l); X( 5)=l;
- RIP1(B,C,D,E,A,WL04,SL04); HOST_c2l(data,l); X( 6)=l;
- RIP1(A,B,C,D,E,WL05,SL05); HOST_c2l(data,l); X( 7)=l;
- RIP1(E,A,B,C,D,WL06,SL06); HOST_c2l(data,l); X( 8)=l;
- RIP1(D,E,A,B,C,WL07,SL07); HOST_c2l(data,l); X( 9)=l;
- RIP1(C,D,E,A,B,WL08,SL08); HOST_c2l(data,l); X(10)=l;
- RIP1(B,C,D,E,A,WL09,SL09); HOST_c2l(data,l); X(11)=l;
- RIP1(A,B,C,D,E,WL10,SL10); HOST_c2l(data,l); X(12)=l;
- RIP1(E,A,B,C,D,WL11,SL11); HOST_c2l(data,l); X(13)=l;
- RIP1(D,E,A,B,C,WL12,SL12); HOST_c2l(data,l); X(14)=l;
- RIP1(C,D,E,A,B,WL13,SL13); HOST_c2l(data,l); X(15)=l;
+ (void)HOST_c2l(data,l); X( 0)=l;(void)HOST_c2l(data,l); X( 1)=l;
+ RIP1(A,B,C,D,E,WL00,SL00); (void)HOST_c2l(data,l); X( 2)=l;
+ RIP1(E,A,B,C,D,WL01,SL01); (void)HOST_c2l(data,l); X( 3)=l;
+ RIP1(D,E,A,B,C,WL02,SL02); (void)HOST_c2l(data,l); X( 4)=l;
+ RIP1(C,D,E,A,B,WL03,SL03); (void)HOST_c2l(data,l); X( 5)=l;
+ RIP1(B,C,D,E,A,WL04,SL04); (void)HOST_c2l(data,l); X( 6)=l;
+ RIP1(A,B,C,D,E,WL05,SL05); (void)HOST_c2l(data,l); X( 7)=l;
+ RIP1(E,A,B,C,D,WL06,SL06); (void)HOST_c2l(data,l); X( 8)=l;
+ RIP1(D,E,A,B,C,WL07,SL07); (void)HOST_c2l(data,l); X( 9)=l;
+ RIP1(C,D,E,A,B,WL08,SL08); (void)HOST_c2l(data,l); X(10)=l;
+ RIP1(B,C,D,E,A,WL09,SL09); (void)HOST_c2l(data,l); X(11)=l;
+ RIP1(A,B,C,D,E,WL10,SL10); (void)HOST_c2l(data,l); X(12)=l;
+ RIP1(E,A,B,C,D,WL11,SL11); (void)HOST_c2l(data,l); X(13)=l;
+ RIP1(D,E,A,B,C,WL12,SL12); (void)HOST_c2l(data,l); X(14)=l;
+ RIP1(C,D,E,A,B,WL13,SL13); (void)HOST_c2l(data,l); X(15)=l;
RIP1(B,C,D,E,A,WL14,SL14);
RIP1(A,B,C,D,E,WL15,SL15);
diff --git a/deps/openssl/openssl/crypto/ripemd/rmd_locl.h b/deps/openssl/openssl/crypto/ripemd/rmd_locl.h
index f14b346e6..2bd8957d1 100644
--- a/deps/openssl/openssl/crypto/ripemd/rmd_locl.h
+++ b/deps/openssl/openssl/crypto/ripemd/rmd_locl.h
@@ -88,11 +88,11 @@ void ripemd160_block_data_order (RIPEMD160_CTX *c, const void *p,size_t num);
#define HASH_FINAL RIPEMD160_Final
#define HASH_MAKE_STRING(c,s) do { \
unsigned long ll; \
- ll=(c)->A; HOST_l2c(ll,(s)); \
- ll=(c)->B; HOST_l2c(ll,(s)); \
- ll=(c)->C; HOST_l2c(ll,(s)); \
- ll=(c)->D; HOST_l2c(ll,(s)); \
- ll=(c)->E; HOST_l2c(ll,(s)); \
+ ll=(c)->A; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->B; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->C; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->D; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->E; (void)HOST_l2c(ll,(s)); \
} while (0)
#define HASH_BLOCK_DATA_ORDER ripemd160_block_data_order
diff --git a/deps/openssl/openssl/crypto/rsa/Makefile b/deps/openssl/openssl/crypto/rsa/Makefile
index bb64223e0..f798d2f74 100644
--- a/deps/openssl/openssl/crypto/rsa/Makefile
+++ b/deps/openssl/openssl/crypto/rsa/Makefile
@@ -20,11 +20,11 @@ LIB=$(TOP)/libcrypto.a
LIBSRC= rsa_eay.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \
rsa_pk1.c rsa_ssl.c rsa_none.c rsa_oaep.c rsa_chk.c rsa_null.c \
rsa_pss.c rsa_x931.c rsa_asn1.c rsa_depr.c rsa_ameth.c rsa_prn.c \
- rsa_pmeth.c
+ rsa_pmeth.c rsa_crpt.c
LIBOBJ= rsa_eay.o rsa_gen.o rsa_lib.o rsa_sign.o rsa_saos.o rsa_err.o \
rsa_pk1.o rsa_ssl.o rsa_none.o rsa_oaep.o rsa_chk.o rsa_null.o \
rsa_pss.o rsa_x931.o rsa_asn1.o rsa_depr.o rsa_ameth.o rsa_prn.o \
- rsa_pmeth.o
+ rsa_pmeth.o rsa_crpt.o
SRC= $(LIBSRC)
@@ -100,11 +100,16 @@ rsa_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
rsa_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
rsa_asn1.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
rsa_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-rsa_asn1.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+rsa_asn1.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+rsa_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+rsa_asn1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+rsa_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
rsa_asn1.o: ../../include/openssl/opensslconf.h
rsa_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_asn1.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+rsa_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
rsa_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_asn1.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
rsa_asn1.o: ../cryptlib.h rsa_asn1.c
rsa_chk.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
rsa_chk.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
@@ -114,6 +119,21 @@ rsa_chk.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
rsa_chk.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
rsa_chk.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
rsa_chk.o: rsa_chk.c
+rsa_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_crpt.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_crpt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_crpt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+rsa_crpt.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+rsa_crpt.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+rsa_crpt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+rsa_crpt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rsa_crpt.o: ../../include/openssl/opensslconf.h
+rsa_crpt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_crpt.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+rsa_crpt.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_crpt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rsa_crpt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+rsa_crpt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h rsa_crpt.c
rsa_depr.o: ../../e_os.h ../../include/openssl/asn1.h
rsa_depr.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
rsa_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
@@ -205,11 +225,12 @@ rsa_pk1.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pk1.c
rsa_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
rsa_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
rsa_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-rsa_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-rsa_pmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-rsa_pmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-rsa_pmeth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-rsa_pmeth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rsa_pmeth.o: ../../include/openssl/cms.h ../../include/openssl/crypto.h
+rsa_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+rsa_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+rsa_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rsa_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_pmeth.o: ../../include/openssl/objects.h
rsa_pmeth.o: ../../include/openssl/opensslconf.h
rsa_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
rsa_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
diff --git a/deps/openssl/openssl/crypto/rsa/rsa.h b/deps/openssl/openssl/crypto/rsa/rsa.h
index cf7434365..5f269e577 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa.h
+++ b/deps/openssl/openssl/crypto/rsa/rsa.h
@@ -222,12 +222,22 @@ struct rsa_st
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
pad, NULL)
+#define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, \
+ EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad)
+
#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
(EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \
len, NULL)
+#define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+ (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
+ EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, \
+ 0, plen)
+
#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
@@ -236,11 +246,24 @@ struct rsa_st
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)
+#define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_SIG, \
+ EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md)
+
+#define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_SIG, \
+ EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)pmd)
+
#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1)
#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2)
#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3)
#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4)
+#define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5)
+
+#define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6)
+#define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7)
+#define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8)
#define RSA_PKCS1_PADDING 1
#define RSA_SSLV23_PADDING 2
@@ -257,7 +280,7 @@ struct rsa_st
RSA * RSA_new(void);
RSA * RSA_new_method(ENGINE *engine);
-int RSA_size(const RSA *);
+int RSA_size(const RSA *rsa);
/* Deprecated version */
#ifndef OPENSSL_NO_DEPRECATED
@@ -300,6 +323,16 @@ const RSA_METHOD *RSA_null_method(void);
DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)
+typedef struct rsa_pss_params_st
+ {
+ X509_ALGOR *hashAlgorithm;
+ X509_ALGOR *maskGenAlgorithm;
+ ASN1_INTEGER *saltLength;
+ ASN1_INTEGER *trailerField;
+ } RSA_PSS_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
#ifndef OPENSSL_NO_FP_API
int RSA_print_fp(FILE *fp, const RSA *r,int offset);
#endif
@@ -380,6 +413,14 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
const unsigned char *mHash,
const EVP_MD *Hash, int sLen);
+int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
+ const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+ const unsigned char *EM, int sLen);
+
+int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
+ const unsigned char *mHash,
+ const EVP_MD *Hash, const EVP_MD *mgf1Hash, int sLen);
+
int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
int RSA_set_ex_data(RSA *r,int idx,void *arg);
@@ -388,6 +429,25 @@ void *RSA_get_ex_data(const RSA *r, int idx);
RSA *RSAPublicKey_dup(RSA *rsa);
RSA *RSAPrivateKey_dup(RSA *rsa);
+/* If this flag is set the RSA method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its responsibility
+ * to ensure the result is compliant.
+ */
+
+#define RSA_FLAG_FIPS_METHOD 0x0400
+
+/* If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+#define RSA_FLAG_NON_FIPS_ALLOW 0x0400
+/* Application has decided PRNG is good enough to generate a key: don't
+ * check.
+ */
+#define RSA_FLAG_CHECKED 0x0800
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@@ -405,6 +465,7 @@ void ERR_load_RSA_strings(void);
#define RSA_F_PKEY_RSA_CTRL 143
#define RSA_F_PKEY_RSA_CTRL_STR 144
#define RSA_F_PKEY_RSA_SIGN 142
+#define RSA_F_PKEY_RSA_VERIFY 154
#define RSA_F_PKEY_RSA_VERIFYRECOVER 141
#define RSA_F_RSA_BUILTIN_KEYGEN 129
#define RSA_F_RSA_CHECK_KEY 123
@@ -413,6 +474,8 @@ void ERR_load_RSA_strings(void);
#define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103
#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT 104
#define RSA_F_RSA_GENERATE_KEY 105
+#define RSA_F_RSA_GENERATE_KEY_EX 155
+#define RSA_F_RSA_ITEM_VERIFY 156
#define RSA_F_RSA_MEMORY_LOCK 130
#define RSA_F_RSA_NEW_METHOD 106
#define RSA_F_RSA_NULL 124
@@ -424,6 +487,7 @@ void ERR_load_RSA_strings(void);
#define RSA_F_RSA_PADDING_ADD_NONE 107
#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121
#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125
+#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 148
#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108
#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109
#define RSA_F_RSA_PADDING_ADD_SSLV23 110
@@ -436,8 +500,12 @@ void ERR_load_RSA_strings(void);
#define RSA_F_RSA_PADDING_CHECK_X931 128
#define RSA_F_RSA_PRINT 115
#define RSA_F_RSA_PRINT_FP 116
+#define RSA_F_RSA_PRIVATE_DECRYPT 150
+#define RSA_F_RSA_PRIVATE_ENCRYPT 151
#define RSA_F_RSA_PRIV_DECODE 137
#define RSA_F_RSA_PRIV_ENCODE 138
+#define RSA_F_RSA_PUBLIC_DECRYPT 152
+#define RSA_F_RSA_PUBLIC_ENCRYPT 153
#define RSA_F_RSA_PUB_DECODE 139
#define RSA_F_RSA_SETUP_BLINDING 136
#define RSA_F_RSA_SIGN 117
@@ -445,6 +513,7 @@ void ERR_load_RSA_strings(void);
#define RSA_F_RSA_VERIFY 119
#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120
#define RSA_F_RSA_VERIFY_PKCS1_PSS 126
+#define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 149
/* Reason codes. */
#define RSA_R_ALGORITHM_MISMATCH 100
@@ -470,19 +539,24 @@ void ERR_load_RSA_strings(void);
#define RSA_R_INVALID_HEADER 137
#define RSA_R_INVALID_KEYBITS 145
#define RSA_R_INVALID_MESSAGE_LENGTH 131
+#define RSA_R_INVALID_MGF1_MD 156
#define RSA_R_INVALID_PADDING 138
#define RSA_R_INVALID_PADDING_MODE 141
+#define RSA_R_INVALID_PSS_PARAMETERS 149
#define RSA_R_INVALID_PSS_SALTLEN 146
+#define RSA_R_INVALID_SALT_LENGTH 150
#define RSA_R_INVALID_TRAILER 139
#define RSA_R_INVALID_X931_DIGEST 142
#define RSA_R_IQMP_NOT_INVERSE_OF_Q 126
#define RSA_R_KEY_SIZE_TOO_SMALL 120
#define RSA_R_LAST_OCTET_INVALID 134
#define RSA_R_MODULUS_TOO_LARGE 105
+#define RSA_R_NON_FIPS_RSA_METHOD 157
#define RSA_R_NO_PUBLIC_EXPONENT 140
#define RSA_R_NULL_BEFORE_BLOCK_MISSING 113
#define RSA_R_N_DOES_NOT_EQUAL_P_Q 127
#define RSA_R_OAEP_DECODING_ERROR 121
+#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 158
#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148
#define RSA_R_PADDING_CHECK_FAILED 114
#define RSA_R_P_NOT_PRIME 128
@@ -493,7 +567,12 @@ void ERR_load_RSA_strings(void);
#define RSA_R_SSLV3_ROLLBACK_ATTACK 115
#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
#define RSA_R_UNKNOWN_ALGORITHM_TYPE 117
+#define RSA_R_UNKNOWN_MASK_DIGEST 151
#define RSA_R_UNKNOWN_PADDING_TYPE 118
+#define RSA_R_UNKNOWN_PSS_DIGEST 152
+#define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153
+#define RSA_R_UNSUPPORTED_MASK_PARAMETER 154
+#define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155
#define RSA_R_VALUE_MISSING 147
#define RSA_R_WRONG_SIGNATURE_LENGTH 119
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_ameth.c b/deps/openssl/openssl/crypto/rsa/rsa_ameth.c
index 8c3209885..2460910ab 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_ameth.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_ameth.c
@@ -265,6 +265,147 @@ static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
}
+static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
+ X509_ALGOR **pmaskHash)
+ {
+ const unsigned char *p;
+ int plen;
+ RSA_PSS_PARAMS *pss;
+
+ *pmaskHash = NULL;
+
+ if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE)
+ return NULL;
+ p = alg->parameter->value.sequence->data;
+ plen = alg->parameter->value.sequence->length;
+ pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);
+
+ if (!pss)
+ return NULL;
+
+ if (pss->maskGenAlgorithm)
+ {
+ ASN1_TYPE *param = pss->maskGenAlgorithm->parameter;
+ if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1
+ && param->type == V_ASN1_SEQUENCE)
+ {
+ p = param->value.sequence->data;
+ plen = param->value.sequence->length;
+ *pmaskHash = d2i_X509_ALGOR(NULL, &p, plen);
+ }
+ }
+
+ return pss;
+ }
+
+static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss,
+ X509_ALGOR *maskHash, int indent)
+ {
+ int rv = 0;
+ if (!pss)
+ {
+ if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0)
+ return 0;
+ return 1;
+ }
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+ if (!BIO_indent(bp, indent, 128))
+ goto err;
+ if (BIO_puts(bp, "Hash Algorithm: ") <= 0)
+ goto err;
+
+ if (pss->hashAlgorithm)
+ {
+ if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0)
+ goto err;
+ }
+ else if (BIO_puts(bp, "sha1 (default)") <= 0)
+ goto err;
+
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+
+ if (!BIO_indent(bp, indent, 128))
+ goto err;
+
+ if (BIO_puts(bp, "Mask Algorithm: ") <= 0)
+ goto err;
+ if (pss->maskGenAlgorithm)
+ {
+ if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0)
+ goto err;
+ if (BIO_puts(bp, " with ") <= 0)
+ goto err;
+ if (maskHash)
+ {
+ if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0)
+ goto err;
+ }
+ else if (BIO_puts(bp, "INVALID") <= 0)
+ goto err;
+ }
+ else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0)
+ goto err;
+ BIO_puts(bp, "\n");
+
+ if (!BIO_indent(bp, indent, 128))
+ goto err;
+ if (BIO_puts(bp, "Salt Length: ") <= 0)
+ goto err;
+ if (pss->saltLength)
+ {
+ if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
+ goto err;
+ }
+ else if (BIO_puts(bp, "20 (default)") <= 0)
+ goto err;
+ BIO_puts(bp, "\n");
+
+ if (!BIO_indent(bp, indent, 128))
+ goto err;
+ if (BIO_puts(bp, "Trailer Field: ") <= 0)
+ goto err;
+ if (pss->trailerField)
+ {
+ if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0)
+ goto err;
+ }
+ else if (BIO_puts(bp, "0xbc (default)") <= 0)
+ goto err;
+ BIO_puts(bp, "\n");
+
+ rv = 1;
+
+ err:
+ return rv;
+
+ }
+
+static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
+ const ASN1_STRING *sig,
+ int indent, ASN1_PCTX *pctx)
+ {
+ if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss)
+ {
+ int rv;
+ RSA_PSS_PARAMS *pss;
+ X509_ALGOR *maskHash;
+ pss = rsa_pss_decode(sigalg, &maskHash);
+ rv = rsa_pss_param_print(bp, pss, maskHash, indent);
+ if (pss)
+ RSA_PSS_PARAMS_free(pss);
+ if (maskHash)
+ X509_ALGOR_free(maskHash);
+ if (!rv)
+ return 0;
+ }
+ else if (!sig && BIO_puts(bp, "\n") <= 0)
+ return 0;
+ if (sig)
+ return X509_signature_dump(bp, sig, indent);
+ return 1;
+ }
static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
@@ -310,6 +451,211 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
}
+/* Customised RSA item verification routine. This is called
+ * when a signature is encountered requiring special handling. We
+ * currently only handle PSS.
+ */
+
+
+static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *sigalg, ASN1_BIT_STRING *sig,
+ EVP_PKEY *pkey)
+ {
+ int rv = -1;
+ int saltlen;
+ const EVP_MD *mgf1md = NULL, *md = NULL;
+ RSA_PSS_PARAMS *pss;
+ X509_ALGOR *maskHash;
+ EVP_PKEY_CTX *pkctx;
+ /* Sanity check: make sure it is PSS */
+ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss)
+ {
+ RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
+ return -1;
+ }
+ /* Decode PSS parameters */
+ pss = rsa_pss_decode(sigalg, &maskHash);
+
+ if (pss == NULL)
+ {
+ RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS);
+ goto err;
+ }
+ /* Check mask and lookup mask hash algorithm */
+ if (pss->maskGenAlgorithm)
+ {
+ if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1)
+ {
+ RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_ALGORITHM);
+ goto err;
+ }
+ if (!maskHash)
+ {
+ RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_PARAMETER);
+ goto err;
+ }
+ mgf1md = EVP_get_digestbyobj(maskHash->algorithm);
+ if (mgf1md == NULL)
+ {
+ RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_MASK_DIGEST);
+ goto err;
+ }
+ }
+ else
+ mgf1md = EVP_sha1();
+
+ if (pss->hashAlgorithm)
+ {
+ md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm);
+ if (md == NULL)
+ {
+ RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST);
+ goto err;
+ }
+ }
+ else
+ md = EVP_sha1();
+
+ if (pss->saltLength)
+ {
+ saltlen = ASN1_INTEGER_get(pss->saltLength);
+
+ /* Could perform more salt length sanity checks but the main
+ * RSA routines will trap other invalid values anyway.
+ */
+ if (saltlen < 0)
+ {
+ RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_SALT_LENGTH);
+ goto err;
+ }
+ }
+ else
+ saltlen = 20;
+
+ /* low-level routines support only trailer field 0xbc (value 1)
+ * and PKCS#1 says we should reject any other value anyway.
+ */
+ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1)
+ {
+ RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER);
+ goto err;
+ }
+
+ /* We have all parameters now set up context */
+
+ if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
+ goto err;
+ /* Carry on */
+ rv = 2;
+
+ err:
+ RSA_PSS_PARAMS_free(pss);
+ if (maskHash)
+ X509_ALGOR_free(maskHash);
+ return rv;
+ }
+
+static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *alg1, X509_ALGOR *alg2,
+ ASN1_BIT_STRING *sig)
+ {
+ int pad_mode;
+ EVP_PKEY_CTX *pkctx = ctx->pctx;
+ if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+ return 0;
+ if (pad_mode == RSA_PKCS1_PADDING)
+ return 2;
+ if (pad_mode == RSA_PKCS1_PSS_PADDING)
+ {
+ const EVP_MD *sigmd, *mgf1md;
+ RSA_PSS_PARAMS *pss = NULL;
+ X509_ALGOR *mgf1alg = NULL;
+ ASN1_STRING *os1 = NULL, *os2 = NULL;
+ EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
+ int saltlen, rv = 0;
+ sigmd = EVP_MD_CTX_md(ctx);
+ if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
+ goto err;
+ if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen))
+ goto err;
+ if (saltlen == -1)
+ saltlen = EVP_MD_size(sigmd);
+ else if (saltlen == -2)
+ {
+ saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
+ if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0)
+ saltlen--;
+ }
+ pss = RSA_PSS_PARAMS_new();
+ if (!pss)
+ goto err;
+ if (saltlen != 20)
+ {
+ pss->saltLength = ASN1_INTEGER_new();
+ if (!pss->saltLength)
+ goto err;
+ if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
+ goto err;
+ }
+ if (EVP_MD_type(sigmd) != NID_sha1)
+ {
+ pss->hashAlgorithm = X509_ALGOR_new();
+ if (!pss->hashAlgorithm)
+ goto err;
+ X509_ALGOR_set_md(pss->hashAlgorithm, sigmd);
+ }
+ if (EVP_MD_type(mgf1md) != NID_sha1)
+ {
+ ASN1_STRING *stmp = NULL;
+ /* need to embed algorithm ID inside another */
+ mgf1alg = X509_ALGOR_new();
+ X509_ALGOR_set_md(mgf1alg, mgf1md);
+ if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR),
+ &stmp))
+ goto err;
+ pss->maskGenAlgorithm = X509_ALGOR_new();
+ if (!pss->maskGenAlgorithm)
+ goto err;
+ X509_ALGOR_set0(pss->maskGenAlgorithm,
+ OBJ_nid2obj(NID_mgf1),
+ V_ASN1_SEQUENCE, stmp);
+ }
+ /* Finally create string with pss parameter encoding. */
+ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1))
+ goto err;
+ if (alg2)
+ {
+ os2 = ASN1_STRING_dup(os1);
+ if (!os2)
+ goto err;
+ X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss),
+ V_ASN1_SEQUENCE, os2);
+ }
+ X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss),
+ V_ASN1_SEQUENCE, os1);
+ os1 = os2 = NULL;
+ rv = 3;
+ err:
+ if (mgf1alg)
+ X509_ALGOR_free(mgf1alg);
+ if (pss)
+ RSA_PSS_PARAMS_free(pss);
+ if (os1)
+ ASN1_STRING_free(os1);
+ return rv;
+
+ }
+ return 2;
+ }
const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
{
@@ -335,10 +681,13 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
0,0,0,0,0,0,
+ rsa_sig_print,
int_rsa_free,
rsa_pkey_ctrl,
old_rsa_priv_decode,
- old_rsa_priv_encode
+ old_rsa_priv_encode,
+ rsa_item_verify,
+ rsa_item_sign
},
{
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_asn1.c b/deps/openssl/openssl/crypto/rsa/rsa_asn1.c
index 4efca8cdc..6ed5de3db 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_asn1.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_asn1.c
@@ -60,6 +60,7 @@
#include "cryptlib.h"
#include <openssl/bn.h>
#include <openssl/rsa.h>
+#include <openssl/x509.h>
#include <openssl/asn1t.h>
/* Override the default free and new methods */
@@ -96,6 +97,15 @@ ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = {
ASN1_SIMPLE(RSA, e, BIGNUM),
} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey)
+ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3)
+} ASN1_SEQUENCE_END(RSA_PSS_PARAMS)
+
+IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey)
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_crpt.c b/deps/openssl/openssl/crypto/rsa/rsa_crpt.c
new file mode 100644
index 000000000..d3e44785d
--- /dev/null
+++ b/deps/openssl/openssl/crypto/rsa/rsa_crpt.c
@@ -0,0 +1,257 @@
+/* crypto/rsa/rsa_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+int RSA_size(const RSA *r)
+ {
+ return(BN_num_bytes(r->n));
+ }
+
+int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
+ RSA *rsa, int padding)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+ {
+ RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+ return -1;
+ }
+#endif
+ return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
+ }
+
+int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
+ RSA *rsa, int padding)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+ {
+ RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+ return -1;
+ }
+#endif
+ return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
+ }
+
+int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
+ RSA *rsa, int padding)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+ {
+ RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+ return -1;
+ }
+#endif
+ return(rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
+ }
+
+int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
+ RSA *rsa, int padding)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+ {
+ RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+ return -1;
+ }
+#endif
+ return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
+ }
+
+int RSA_flags(const RSA *r)
+ {
+ return((r == NULL)?0:r->meth->flags);
+ }
+
+void RSA_blinding_off(RSA *rsa)
+ {
+ if (rsa->blinding != NULL)
+ {
+ BN_BLINDING_free(rsa->blinding);
+ rsa->blinding=NULL;
+ }
+ rsa->flags &= ~RSA_FLAG_BLINDING;
+ rsa->flags |= RSA_FLAG_NO_BLINDING;
+ }
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
+ {
+ int ret=0;
+
+ if (rsa->blinding != NULL)
+ RSA_blinding_off(rsa);
+
+ rsa->blinding = RSA_setup_blinding(rsa, ctx);
+ if (rsa->blinding == NULL)
+ goto err;
+
+ rsa->flags |= RSA_FLAG_BLINDING;
+ rsa->flags &= ~RSA_FLAG_NO_BLINDING;
+ ret=1;
+err:
+ return(ret);
+ }
+
+static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
+ const BIGNUM *q, BN_CTX *ctx)
+{
+ BIGNUM *ret = NULL, *r0, *r1, *r2;
+
+ if (d == NULL || p == NULL || q == NULL)
+ return NULL;
+
+ BN_CTX_start(ctx);
+ r0 = BN_CTX_get(ctx);
+ r1 = BN_CTX_get(ctx);
+ r2 = BN_CTX_get(ctx);
+ if (r2 == NULL)
+ goto err;
+
+ if (!BN_sub(r1, p, BN_value_one())) goto err;
+ if (!BN_sub(r2, q, BN_value_one())) goto err;
+ if (!BN_mul(r0, r1, r2, ctx)) goto err;
+
+ ret = BN_mod_inverse(NULL, d, r0, ctx);
+err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
+{
+ BIGNUM local_n;
+ BIGNUM *e,*n;
+ BN_CTX *ctx;
+ BN_BLINDING *ret = NULL;
+
+ if (in_ctx == NULL)
+ {
+ if ((ctx = BN_CTX_new()) == NULL) return 0;
+ }
+ else
+ ctx = in_ctx;
+
+ BN_CTX_start(ctx);
+ e = BN_CTX_get(ctx);
+ if (e == NULL)
+ {
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (rsa->e == NULL)
+ {
+ e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
+ if (e == NULL)
+ {
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
+ goto err;
+ }
+ }
+ else
+ e = rsa->e;
+
+
+ if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
+ {
+ /* if PRNG is not properly seeded, resort to secret
+ * exponent as unpredictable seed */
+ RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
+ }
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ /* Set BN_FLG_CONSTTIME flag */
+ n = &local_n;
+ BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
+ }
+ else
+ n = rsa->n;
+
+ ret = BN_BLINDING_create_param(NULL, e, n, ctx,
+ rsa->meth->bn_mod_exp, rsa->_method_mod_n);
+ if (ret == NULL)
+ {
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
+ goto err;
+ }
+ CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
+err:
+ BN_CTX_end(ctx);
+ if (in_ctx == NULL)
+ BN_CTX_free(ctx);
+ if(rsa->e == NULL)
+ BN_free(e);
+
+ return ret;
+}
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_eay.c b/deps/openssl/openssl/crypto/rsa/rsa_eay.c
index 2e1ddd48d..88ee2cb55 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_eay.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_eay.c
@@ -847,12 +847,12 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
/* If p < q it is occasionally possible for the correction of
- * adding 'p' if r0 is negative above to leave the result still
+ * adding 'p' if r0 is negative above to leave the result still
* negative. This can break the private key operations: the following
* second correction should *always* correct this rare occurrence.
* This will *never* happen with OpenSSL generated keys because
- * they ensure p > q [steve]
- */
+ * they ensure p > q [steve]
+ */
if (BN_is_negative(r0))
if (!BN_add(r0,r0,rsa->p)) goto err;
if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_err.c b/deps/openssl/openssl/crypto/rsa/rsa_err.c
index cf9f1106b..46e0bf998 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_err.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_err.c
@@ -1,6 +1,6 @@
/* crypto/rsa/rsa_err.c */
/* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -78,6 +78,7 @@ static ERR_STRING_DATA RSA_str_functs[]=
{ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "PKEY_RSA_CTRL"},
{ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "PKEY_RSA_CTRL_STR"},
{ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "PKEY_RSA_SIGN"},
+{ERR_FUNC(RSA_F_PKEY_RSA_VERIFY), "PKEY_RSA_VERIFY"},
{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"},
{ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"},
{ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"},
@@ -86,6 +87,8 @@ static ERR_STRING_DATA RSA_str_functs[]=
{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"},
{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"},
{ERR_FUNC(RSA_F_RSA_GENERATE_KEY), "RSA_generate_key"},
+{ERR_FUNC(RSA_F_RSA_GENERATE_KEY_EX), "RSA_generate_key_ex"},
+{ERR_FUNC(RSA_F_RSA_ITEM_VERIFY), "RSA_ITEM_VERIFY"},
{ERR_FUNC(RSA_F_RSA_MEMORY_LOCK), "RSA_memory_lock"},
{ERR_FUNC(RSA_F_RSA_NEW_METHOD), "RSA_new_method"},
{ERR_FUNC(RSA_F_RSA_NULL), "RSA_NULL"},
@@ -97,6 +100,7 @@ static ERR_STRING_DATA RSA_str_functs[]=
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP), "RSA_padding_add_PKCS1_OAEP"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1), "RSA_padding_add_PKCS1_PSS_mgf1"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1), "RSA_padding_add_PKCS1_type_1"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2), "RSA_padding_add_PKCS1_type_2"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"},
@@ -109,8 +113,12 @@ static ERR_STRING_DATA RSA_str_functs[]=
{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"},
{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
+{ERR_FUNC(RSA_F_RSA_PRIVATE_DECRYPT), "RSA_private_decrypt"},
+{ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT), "RSA_private_encrypt"},
{ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"},
{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"},
+{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"},
+{ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT), "RSA_public_encrypt"},
{ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"},
{ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"},
{ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
@@ -118,6 +126,7 @@ static ERR_STRING_DATA RSA_str_functs[]=
{ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"},
{ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING), "RSA_verify_ASN1_OCTET_STRING"},
{ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS), "RSA_verify_PKCS1_PSS"},
+{ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1), "RSA_verify_PKCS1_PSS_mgf1"},
{0,NULL}
};
@@ -146,19 +155,24 @@ static ERR_STRING_DATA RSA_str_reasons[]=
{ERR_REASON(RSA_R_INVALID_HEADER) ,"invalid header"},
{ERR_REASON(RSA_R_INVALID_KEYBITS) ,"invalid keybits"},
{ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"},
+{ERR_REASON(RSA_R_INVALID_MGF1_MD) ,"invalid mgf1 md"},
{ERR_REASON(RSA_R_INVALID_PADDING) ,"invalid padding"},
{ERR_REASON(RSA_R_INVALID_PADDING_MODE) ,"invalid padding mode"},
+{ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS),"invalid pss parameters"},
{ERR_REASON(RSA_R_INVALID_PSS_SALTLEN) ,"invalid pss saltlen"},
+{ERR_REASON(RSA_R_INVALID_SALT_LENGTH) ,"invalid salt length"},
{ERR_REASON(RSA_R_INVALID_TRAILER) ,"invalid trailer"},
{ERR_REASON(RSA_R_INVALID_X931_DIGEST) ,"invalid x931 digest"},
{ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"},
{ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"},
{ERR_REASON(RSA_R_MODULUS_TOO_LARGE) ,"modulus too large"},
+{ERR_REASON(RSA_R_NON_FIPS_RSA_METHOD) ,"non fips rsa method"},
{ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT) ,"no public exponent"},
{ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
{ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) ,"n does not equal p q"},
{ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"},
+{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
{ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"},
{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"},
@@ -169,7 +183,12 @@ static ERR_STRING_DATA RSA_str_reasons[]=
{ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK) ,"sslv3 rollback attack"},
{ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
{ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
+{ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST) ,"unknown mask digest"},
{ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE) ,"unknown padding type"},
+{ERR_REASON(RSA_R_UNKNOWN_PSS_DIGEST) ,"unknown pss digest"},
+{ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM),"unsupported mask algorithm"},
+{ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER),"unsupported mask parameter"},
+{ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE),"unsupported signature type"},
{ERR_REASON(RSA_R_VALUE_MISSING) ,"value missing"},
{ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
{0,NULL}
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_gen.c b/deps/openssl/openssl/crypto/rsa/rsa_gen.c
index 767f7ab68..42290cce6 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_gen.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_gen.c
@@ -67,6 +67,9 @@
#include "cryptlib.h"
#include <openssl/bn.h>
#include <openssl/rsa.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
@@ -77,8 +80,20 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
* now just because key-generation is part of RSA_METHOD. */
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+ {
+ RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD);
+ return 0;
+ }
+#endif
if(rsa->meth->rsa_keygen)
return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_rsa_generate_key_ex(rsa, bits, e_value, cb);
+#endif
return rsa_builtin_keygen(rsa, bits, e_value, cb);
}
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_lib.c b/deps/openssl/openssl/crypto/rsa/rsa_lib.c
index de45088d7..c95ceafc8 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_lib.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_lib.c
@@ -67,6 +67,10 @@
#include <openssl/engine.h>
#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
static const RSA_METHOD *default_RSA_meth=NULL;
@@ -87,12 +91,15 @@ const RSA_METHOD *RSA_get_default_method(void)
{
if (default_RSA_meth == NULL)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_rsa_pkcs1_ssleay();
+ else
+ return RSA_PKCS1_SSLeay();
+#else
#ifdef RSA_NULL
default_RSA_meth=RSA_null_method();
#else
-#if 0 /* was: #ifdef RSAref */
- default_RSA_meth=RSA_PKCS1_RSAref();
-#else
default_RSA_meth=RSA_PKCS1_SSLeay();
#endif
#endif
@@ -181,7 +188,7 @@ RSA *RSA_new_method(ENGINE *engine)
ret->blinding=NULL;
ret->mt_blinding=NULL;
ret->bignum_data=NULL;
- ret->flags=ret->meth->flags;
+ ret->flags=ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
{
#ifndef OPENSSL_NO_ENGINE
@@ -280,163 +287,6 @@ void *RSA_get_ex_data(const RSA *r, int idx)
return(CRYPTO_get_ex_data(&r->ex_data,idx));
}
-int RSA_size(const RSA *r)
- {
- return(BN_num_bytes(r->n));
- }
-
-int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
- RSA *rsa, int padding)
- {
- return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
- }
-
-int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
- RSA *rsa, int padding)
- {
- return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
- }
-
-int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
- RSA *rsa, int padding)
- {
- return(rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
- }
-
-int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
- RSA *rsa, int padding)
- {
- return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
- }
-
-int RSA_flags(const RSA *r)
- {
- return((r == NULL)?0:r->meth->flags);
- }
-
-void RSA_blinding_off(RSA *rsa)
- {
- if (rsa->blinding != NULL)
- {
- BN_BLINDING_free(rsa->blinding);
- rsa->blinding=NULL;
- }
- rsa->flags &= ~RSA_FLAG_BLINDING;
- rsa->flags |= RSA_FLAG_NO_BLINDING;
- }
-
-int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
- {
- int ret=0;
-
- if (rsa->blinding != NULL)
- RSA_blinding_off(rsa);
-
- rsa->blinding = RSA_setup_blinding(rsa, ctx);
- if (rsa->blinding == NULL)
- goto err;
-
- rsa->flags |= RSA_FLAG_BLINDING;
- rsa->flags &= ~RSA_FLAG_NO_BLINDING;
- ret=1;
-err:
- return(ret);
- }
-
-static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
- const BIGNUM *q, BN_CTX *ctx)
-{
- BIGNUM *ret = NULL, *r0, *r1, *r2;
-
- if (d == NULL || p == NULL || q == NULL)
- return NULL;
-
- BN_CTX_start(ctx);
- r0 = BN_CTX_get(ctx);
- r1 = BN_CTX_get(ctx);
- r2 = BN_CTX_get(ctx);
- if (r2 == NULL)
- goto err;
-
- if (!BN_sub(r1, p, BN_value_one())) goto err;
- if (!BN_sub(r2, q, BN_value_one())) goto err;
- if (!BN_mul(r0, r1, r2, ctx)) goto err;
-
- ret = BN_mod_inverse(NULL, d, r0, ctx);
-err:
- BN_CTX_end(ctx);
- return ret;
-}
-
-BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
-{
- BIGNUM local_n;
- BIGNUM *e,*n;
- BN_CTX *ctx;
- BN_BLINDING *ret = NULL;
-
- if (in_ctx == NULL)
- {
- if ((ctx = BN_CTX_new()) == NULL) return 0;
- }
- else
- ctx = in_ctx;
-
- BN_CTX_start(ctx);
- e = BN_CTX_get(ctx);
- if (e == NULL)
- {
- RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (rsa->e == NULL)
- {
- e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
- if (e == NULL)
- {
- RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
- goto err;
- }
- }
- else
- e = rsa->e;
-
-
- if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
- {
- /* if PRNG is not properly seeded, resort to secret
- * exponent as unpredictable seed */
- RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
- }
-
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- /* Set BN_FLG_CONSTTIME flag */
- n = &local_n;
- BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
- }
- else
- n = rsa->n;
-
- ret = BN_BLINDING_create_param(NULL, e, n, ctx,
- rsa->meth->bn_mod_exp, rsa->_method_mod_n);
- if (ret == NULL)
- {
- RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
- goto err;
- }
- CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
-err:
- BN_CTX_end(ctx);
- if (in_ctx == NULL)
- BN_CTX_free(ctx);
- if(rsa->e == NULL)
- BN_free(e);
-
- return ret;
-}
-
int RSA_memory_lock(RSA *r)
{
int i,j,k,off;
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_oaep.c b/deps/openssl/openssl/crypto/rsa/rsa_oaep.c
index 18d307ea9..af4d24a56 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_oaep.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_oaep.c
@@ -56,7 +56,8 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
seed = to + 1;
db = to + SHA_DIGEST_LENGTH + 1;
- EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL);
+ if (!EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL))
+ return 0;
memset(db + SHA_DIGEST_LENGTH, 0,
emlen - flen - 2 * SHA_DIGEST_LENGTH - 1);
db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01;
@@ -145,9 +146,10 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
for (i = 0; i < dblen; i++)
db[i] ^= maskeddb[i];
- EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL);
+ if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL))
+ return -1;
- if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
+ if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
goto decoding_err;
else
{
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c b/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c
index c6892ecd0..5b2ecf56a 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c
@@ -63,6 +63,12 @@
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
#include "evp_locl.h"
#include "rsa_locl.h"
@@ -79,6 +85,8 @@ typedef struct
int pad_mode;
/* message digest */
const EVP_MD *md;
+ /* message digest for MGF1 */
+ const EVP_MD *mgf1md;
/* PSS/OAEP salt length */
int saltlen;
/* Temp buffer */
@@ -95,6 +103,7 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
rctx->pub_exp = NULL;
rctx->pad_mode = RSA_PKCS1_PADDING;
rctx->md = NULL;
+ rctx->mgf1md = NULL;
rctx->tbuf = NULL;
rctx->saltlen = -2;
@@ -147,6 +156,31 @@ static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
OPENSSL_free(rctx);
}
}
+#ifdef OPENSSL_FIPS
+/* FIP checker. Return value indicates status of context parameters:
+ * 1 : redirect to FIPS.
+ * 0 : don't redirect to FIPS.
+ * -1 : illegal operation in FIPS mode.
+ */
+
+static int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx)
+ {
+ RSA_PKEY_CTX *rctx = ctx->data;
+ RSA *rsa = ctx->pkey->pkey.rsa;
+ int rv = -1;
+ if (!FIPS_mode())
+ return 0;
+ if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
+ rv = 0;
+ if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv)
+ return -1;
+ if (rctx->md && !(rctx->md->flags & EVP_MD_FLAG_FIPS))
+ return rv;
+ if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS))
+ return rv;
+ return 1;
+ }
+#endif
static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen)
@@ -155,6 +189,15 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
RSA_PKEY_CTX *rctx = ctx->data;
RSA *rsa = ctx->pkey->pkey.rsa;
+#ifdef OPENSSL_FIPS
+ ret = pkey_fips_check_ctx(ctx);
+ if (ret < 0)
+ {
+ RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+ return -1;
+ }
+#endif
+
if (rctx->md)
{
if (tbslen != (size_t)EVP_MD_size(rctx->md))
@@ -163,7 +206,36 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
RSA_R_INVALID_DIGEST_LENGTH);
return -1;
}
- if (rctx->pad_mode == RSA_X931_PADDING)
+#ifdef OPENSSL_FIPS
+ if (ret > 0)
+ {
+ unsigned int slen;
+ ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md,
+ rctx->pad_mode,
+ rctx->saltlen,
+ rctx->mgf1md,
+ sig, &slen);
+ if (ret > 0)
+ *siglen = slen;
+ else
+ *siglen = 0;
+ return ret;
+ }
+#endif
+
+ if (EVP_MD_type(rctx->md) == NID_mdc2)
+ {
+ unsigned int sltmp;
+ if (rctx->pad_mode != RSA_PKCS1_PADDING)
+ return -1;
+ ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2,
+ tbs, tbslen, sig, &sltmp, rsa);
+
+ if (ret <= 0)
+ return ret;
+ ret = sltmp;
+ }
+ else if (rctx->pad_mode == RSA_X931_PADDING)
{
if (!setup_tbuf(rctx, ctx))
return -1;
@@ -186,8 +258,10 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
{
if (!setup_tbuf(rctx, ctx))
return -1;
- if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs,
- rctx->md, rctx->saltlen))
+ if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa,
+ rctx->tbuf, tbs,
+ rctx->md, rctx->mgf1md,
+ rctx->saltlen))
return -1;
ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
sig, rsa, RSA_NO_PADDING);
@@ -269,8 +343,30 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
RSA_PKEY_CTX *rctx = ctx->data;
RSA *rsa = ctx->pkey->pkey.rsa;
size_t rslen;
+#ifdef OPENSSL_FIPS
+ int rv;
+ rv = pkey_fips_check_ctx(ctx);
+ if (rv < 0)
+ {
+ RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+ return -1;
+ }
+#endif
if (rctx->md)
{
+#ifdef OPENSSL_FIPS
+ if (rv > 0)
+ {
+ return FIPS_rsa_verify_digest(rsa,
+ tbs, tbslen,
+ rctx->md,
+ rctx->pad_mode,
+ rctx->saltlen,
+ rctx->mgf1md,
+ sig, siglen);
+
+ }
+#endif
if (rctx->pad_mode == RSA_PKCS1_PADDING)
return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
sig, siglen, rsa);
@@ -289,7 +385,8 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
rsa, RSA_NO_PADDING);
if (ret <= 0)
return 0;
- ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md,
+ ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs,
+ rctx->md, rctx->mgf1md,
rctx->tbuf, rctx->saltlen);
if (ret <= 0)
return 0;
@@ -403,15 +500,25 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
return -2;
+ case EVP_PKEY_CTRL_GET_RSA_PADDING:
+ *(int *)p2 = rctx->pad_mode;
+ return 1;
+
case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
- if (p1 < -2)
- return -2;
+ case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
{
RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
return -2;
}
- rctx->saltlen = p1;
+ if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN)
+ *(int *)p2 = rctx->saltlen;
+ else
+ {
+ if (p1 < -2)
+ return -2;
+ rctx->saltlen = p1;
+ }
return 1;
case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
@@ -435,16 +542,45 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
rctx->md = p2;
return 1;
+ case EVP_PKEY_CTRL_RSA_MGF1_MD:
+ case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
+ if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
+ {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD);
+ return -2;
+ }
+ if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD)
+ {
+ if (rctx->mgf1md)
+ *(const EVP_MD **)p2 = rctx->mgf1md;
+ else
+ *(const EVP_MD **)p2 = rctx->md;
+ }
+ else
+ rctx->mgf1md = p2;
+ return 1;
+
case EVP_PKEY_CTRL_DIGESTINIT:
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
case EVP_PKEY_CTRL_PKCS7_SIGN:
+ return 1;
#ifndef OPENSSL_NO_CMS
- case EVP_PKEY_CTRL_CMS_ENCRYPT:
case EVP_PKEY_CTRL_CMS_DECRYPT:
+ {
+ X509_ALGOR *alg = NULL;
+ ASN1_OBJECT *encalg = NULL;
+ if (p2)
+ CMS_RecipientInfo_ktri_get0_algs(p2, NULL, NULL, &alg);
+ if (alg)
+ X509_ALGOR_get0(&encalg, NULL, NULL, alg);
+ if (encalg && OBJ_obj2nid(encalg) == NID_rsaesOaep)
+ rctx->pad_mode = RSA_PKCS1_OAEP_PADDING;
+ }
+ case EVP_PKEY_CTRL_CMS_ENCRYPT:
case EVP_PKEY_CTRL_CMS_SIGN:
-#endif
return 1;
+#endif
case EVP_PKEY_CTRL_PEER_KEY:
RSAerr(RSA_F_PKEY_RSA_CTRL,
RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_pss.c b/deps/openssl/openssl/crypto/rsa/rsa_pss.c
index ac211e2ff..5f9f533d0 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_pss.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_pss.c
@@ -73,6 +73,13 @@ static const unsigned char zeroes[] = {0,0,0,0,0,0,0,0};
int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
const EVP_MD *Hash, const unsigned char *EM, int sLen)
{
+ return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen);
+ }
+
+int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
+ const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+ const unsigned char *EM, int sLen)
+ {
int i;
int ret = 0;
int hLen, maskedDBLen, MSBits, emLen;
@@ -80,6 +87,10 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
unsigned char *DB = NULL;
EVP_MD_CTX ctx;
unsigned char H_[EVP_MAX_MD_SIZE];
+ EVP_MD_CTX_init(&ctx);
+
+ if (mgf1Hash == NULL)
+ mgf1Hash = Hash;
hLen = EVP_MD_size(Hash);
if (hLen < 0)
@@ -94,7 +105,7 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
else if (sLen == -2) sLen = -2;
else if (sLen < -2)
{
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
@@ -102,7 +113,7 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
emLen = RSA_size(rsa);
if (EM[0] & (0xFF << MSBits))
{
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_FIRST_OCTET_INVALID);
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
goto err;
}
if (MSBits == 0)
@@ -112,12 +123,12 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
}
if (emLen < (hLen + sLen + 2)) /* sLen can be small negative */
{
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_DATA_TOO_LARGE);
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
goto err;
}
if (EM[emLen - 1] != 0xbc)
{
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_LAST_OCTET_INVALID);
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
goto err;
}
maskedDBLen = emLen - hLen - 1;
@@ -125,10 +136,10 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
DB = OPENSSL_malloc(maskedDBLen);
if (!DB)
{
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE);
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0)
+ if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
goto err;
for (i = 0; i < maskedDBLen; i++)
DB[i] ^= EM[i];
@@ -137,25 +148,28 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
for (i = 0; DB[i] == 0 && i < (maskedDBLen-1); i++) ;
if (DB[i++] != 0x1)
{
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_RECOVERY_FAILED);
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
goto err;
}
if (sLen >= 0 && (maskedDBLen - i) != sLen)
{
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
- EVP_MD_CTX_init(&ctx);
- EVP_DigestInit_ex(&ctx, Hash, NULL);
- EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes);
- EVP_DigestUpdate(&ctx, mHash, hLen);
+ if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
+ || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
+ || !EVP_DigestUpdate(&ctx, mHash, hLen))
+ goto err;
if (maskedDBLen - i)
- EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i);
- EVP_DigestFinal(&ctx, H_, NULL);
- EVP_MD_CTX_cleanup(&ctx);
+ {
+ if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i))
+ goto err;
+ }
+ if (!EVP_DigestFinal_ex(&ctx, H_, NULL))
+ goto err;
if (memcmp(H_, H, hLen))
{
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_BAD_SIGNATURE);
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
ret = 0;
}
else
@@ -164,6 +178,7 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
err:
if (DB)
OPENSSL_free(DB);
+ EVP_MD_CTX_cleanup(&ctx);
return ret;
@@ -173,12 +188,22 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
const unsigned char *mHash,
const EVP_MD *Hash, int sLen)
{
+ return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen);
+ }
+
+int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
+ const unsigned char *mHash,
+ const EVP_MD *Hash, const EVP_MD *mgf1Hash, int sLen)
+ {
int i;
int ret = 0;
int hLen, maskedDBLen, MSBits, emLen;
unsigned char *H, *salt = NULL, *p;
EVP_MD_CTX ctx;
+ if (mgf1Hash == NULL)
+ mgf1Hash = Hash;
+
hLen = EVP_MD_size(Hash);
if (hLen < 0)
goto err;
@@ -192,7 +217,7 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
else if (sLen == -2) sLen = -2;
else if (sLen < -2)
{
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
@@ -209,8 +234,7 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
}
else if (emLen < (hLen + sLen + 2))
{
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
goto err;
}
if (sLen > 0)
@@ -218,8 +242,7 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
salt = OPENSSL_malloc(sLen);
if (!salt)
{
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
- ERR_R_MALLOC_FAILURE);
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,ERR_R_MALLOC_FAILURE);
goto err;
}
if (RAND_bytes(salt, sLen) <= 0)
@@ -228,16 +251,18 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
maskedDBLen = emLen - hLen - 1;
H = EM + maskedDBLen;
EVP_MD_CTX_init(&ctx);
- EVP_DigestInit_ex(&ctx, Hash, NULL);
- EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes);
- EVP_DigestUpdate(&ctx, mHash, hLen);
- if (sLen)
- EVP_DigestUpdate(&ctx, salt, sLen);
- EVP_DigestFinal(&ctx, H, NULL);
+ if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
+ || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
+ || !EVP_DigestUpdate(&ctx, mHash, hLen))
+ goto err;
+ if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen))
+ goto err;
+ if (!EVP_DigestFinal_ex(&ctx, H, NULL))
+ goto err;
EVP_MD_CTX_cleanup(&ctx);
/* Generate dbMask in place then perform XOR on it */
- if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash))
+ if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash))
goto err;
p = EM;
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_sign.c b/deps/openssl/openssl/crypto/rsa/rsa_sign.c
index 0be4ec7fb..b6f6037ae 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_sign.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_sign.c
@@ -77,6 +77,14 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
const unsigned char *s = NULL;
X509_ALGOR algor;
ASN1_OCTET_STRING digest;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+ {
+ RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD);
+ return 0;
+ }
+#endif
if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign)
{
return rsa->meth->rsa_sign(type, m, m_len,
@@ -153,6 +161,15 @@ int int_rsa_verify(int dtype, const unsigned char *m,
unsigned char *s;
X509_SIG *sig=NULL;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+ {
+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD);
+ return 0;
+ }
+#endif
+
if (siglen != (unsigned int)RSA_size(rsa))
{
RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
@@ -182,6 +199,22 @@ int int_rsa_verify(int dtype, const unsigned char *m,
i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
if (i <= 0) goto err;
+ /* Oddball MDC2 case: signature can be OCTET STRING.
+ * check for correct tag and length octets.
+ */
+ if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10)
+ {
+ if (rm)
+ {
+ memcpy(rm, s + 2, 16);
+ *prm_len = 16;
+ ret = 1;
+ }
+ else if(memcmp(m, s + 2, 16))
+ RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+ else
+ ret = 1;
+ }
/* Special case: SSL signature */
if(dtype == NID_md5_sha1) {
diff --git a/deps/openssl/openssl/crypto/s390xcap.c b/deps/openssl/openssl/crypto/s390xcap.c
index ffbe0235f..f2e94ef47 100644
--- a/deps/openssl/openssl/crypto/s390xcap.c
+++ b/deps/openssl/openssl/crypto/s390xcap.c
@@ -4,7 +4,7 @@
#include <setjmp.h>
#include <signal.h>
-extern unsigned long OPENSSL_s390xcap_P;
+extern unsigned long OPENSSL_s390xcap_P[];
static sigjmp_buf ill_jmp;
static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
@@ -16,7 +16,9 @@ void OPENSSL_cpuid_setup(void)
sigset_t oset;
struct sigaction ill_act,oact;
- if (OPENSSL_s390xcap_P) return;
+ if (OPENSSL_s390xcap_P[0]) return;
+
+ OPENSSL_s390xcap_P[0] = 1UL<<(8*sizeof(unsigned long)-1);
memset(&ill_act,0,sizeof(ill_act));
ill_act.sa_handler = ill_handler;
@@ -27,10 +29,8 @@ void OPENSSL_cpuid_setup(void)
sigaction (SIGILL,&ill_act,&oact);
/* protection against missing store-facility-list-extended */
- if (sigsetjmp(ill_jmp,0) == 0)
- OPENSSL_s390xcap_P = OPENSSL_s390x_facilities();
- else
- OPENSSL_s390xcap_P = 1UL<<63;
+ if (sigsetjmp(ill_jmp,1) == 0)
+ OPENSSL_s390x_facilities();
sigaction (SIGILL,&oact,NULL);
sigprocmask(SIG_SETMASK,&oset,NULL);
diff --git a/deps/openssl/openssl/crypto/s390xcpuid.S b/deps/openssl/openssl/crypto/s390xcpuid.S
index b053c6a28..06815347e 100644
--- a/deps/openssl/openssl/crypto/s390xcpuid.S
+++ b/deps/openssl/openssl/crypto/s390xcpuid.S
@@ -5,10 +5,14 @@
.align 16
OPENSSL_s390x_facilities:
lghi %r0,0
- .long 0xb2b0f010 # stfle 16(%r15)
- lg %r2,16(%r15)
- larl %r1,OPENSSL_s390xcap_P
- stg %r2,0(%r1)
+ larl %r2,OPENSSL_s390xcap_P
+ stg %r0,8(%r2)
+ .long 0xb2b02000 # stfle 0(%r2)
+ brc 8,.Ldone
+ lghi %r0,1
+ .long 0xb2b02000 # stfle 0(%r2)
+.Ldone:
+ lg %r2,0(%r2)
br %r14
.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
@@ -58,6 +62,9 @@ OPENSSL_wipe_cpu:
.type OPENSSL_cleanse,@function
.align 16
OPENSSL_cleanse:
+#if !defined(__s390x__) && !defined(__s390x)
+ llgfr %r3,%r3
+#endif
lghi %r4,15
lghi %r0,0
clgr %r3,%r4
@@ -89,4 +96,4 @@ OPENSSL_cleanse:
.section .init
brasl %r14,OPENSSL_cpuid_setup
-.comm OPENSSL_s390xcap_P,8,8
+.comm OPENSSL_s390xcap_P,16,8
diff --git a/deps/openssl/openssl/crypto/seed/seed.c b/deps/openssl/openssl/crypto/seed/seed.c
index 2bc384a19..3e675a8d7 100644
--- a/deps/openssl/openssl/crypto/seed/seed.c
+++ b/deps/openssl/openssl/crypto/seed/seed.c
@@ -32,9 +32,14 @@
#include <memory.h>
#endif
+#include <openssl/crypto.h>
#include <openssl/seed.h>
#include "seed_locl.h"
+#ifdef SS /* can get defined on Solaris by inclusion of <stdlib.h> */
+#undef SS
+#endif
+
static const seed_word SS[4][256] = { {
0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
@@ -192,8 +197,14 @@ static const seed_word KC[] = {
KC0, KC1, KC2, KC3, KC4, KC5, KC6, KC7,
KC8, KC9, KC10, KC11, KC12, KC13, KC14, KC15 };
#endif
-
void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks)
+#ifdef OPENSSL_FIPS
+ {
+ fips_cipher_abort(SEED);
+ private_SEED_set_key(rawkey, ks);
+ }
+void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks)
+#endif
{
seed_word x1, x2, x3, x4;
seed_word t0, t1;
diff --git a/deps/openssl/openssl/crypto/seed/seed.h b/deps/openssl/openssl/crypto/seed/seed.h
index 6ffa5f024..c50fdd360 100644
--- a/deps/openssl/openssl/crypto/seed/seed.h
+++ b/deps/openssl/openssl/crypto/seed/seed.h
@@ -116,7 +116,9 @@ typedef struct seed_key_st {
#endif
} SEED_KEY_SCHEDULE;
-
+#ifdef OPENSSL_FIPS
+void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks);
+#endif
void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks);
void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks);
diff --git a/deps/openssl/openssl/crypto/sha/Makefile b/deps/openssl/openssl/crypto/sha/Makefile
index e6eccb05f..6d191d393 100644
--- a/deps/openssl/openssl/crypto/sha/Makefile
+++ b/deps/openssl/openssl/crypto/sha/Makefile
@@ -56,8 +56,11 @@ sha256-ia64.s: asm/sha512-ia64.pl
sha512-ia64.s: asm/sha512-ia64.pl
(cd asm; $(PERL) sha512-ia64.pl ../$@ $(CFLAGS))
-sha256-armv4.s: asm/sha256-armv4.pl
- $(PERL) $< $@
+sha256-armv4.S: asm/sha256-armv4.pl
+ $(PERL) $< $(PERLASM_SCHEME) $@
+
+sha1-alpha.s: asm/sha1-alpha.pl
+ $(PERL) $< | $(CC) -E - | tee $@ > /dev/null
# Solaris make has to be explicitly told
sha1-x86_64.s: asm/sha1-x86_64.pl; $(PERL) asm/sha1-x86_64.pl $(PERLASM_SCHEME) > $@
@@ -71,10 +74,22 @@ sha1-ppc.s: asm/sha1-ppc.pl; $(PERL) asm/sha1-ppc.pl $(PERLASM_SCHEME) $@
sha256-ppc.s: asm/sha512-ppc.pl; $(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@
sha512-ppc.s: asm/sha512-ppc.pl; $(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@
+sha1-parisc.s: asm/sha1-parisc.pl; $(PERL) asm/sha1-parisc.pl $(PERLASM_SCHEME) $@
+sha256-parisc.s:asm/sha512-parisc.pl; $(PERL) asm/sha512-parisc.pl $(PERLASM_SCHEME) $@
+sha512-parisc.s:asm/sha512-parisc.pl; $(PERL) asm/sha512-parisc.pl $(PERLASM_SCHEME) $@
+
+sha1-mips.S: asm/sha1-mips.pl; $(PERL) asm/sha1-mips.pl $(PERLASM_SCHEME) $@
+sha256-mips.S: asm/sha512-mips.pl; $(PERL) asm/sha512-mips.pl $(PERLASM_SCHEME) $@
+sha512-mips.S: asm/sha512-mips.pl; $(PERL) asm/sha512-mips.pl $(PERLASM_SCHEME) $@
+
# GNU make "catch all"
-sha1-%.s: asm/sha1-%.pl; $(PERL) $< $@
-sha256-%.s: asm/sha512-%.pl; $(PERL) $< $@
-sha512-%.s: asm/sha512-%.pl; $(PERL) $< $@
+sha1-%.S: asm/sha1-%.pl; $(PERL) $< $(PERLASM_SCHEME) $@
+sha256-%.S: asm/sha512-%.pl; $(PERL) $< $(PERLASM_SCHEME) $@
+sha512-%.S: asm/sha512-%.pl; $(PERL) $< $(PERLASM_SCHEME) $@
+
+sha1-armv4-large.o: sha1-armv4-large.S
+sha256-armv4.o: sha256-armv4.S
+sha512-armv4.o: sha512-armv4.S
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
@@ -119,8 +134,11 @@ sha1_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
sha1_one.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
sha1_one.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
sha1_one.o: sha1_one.c
-sha1dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-sha1dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/sha.h
+sha1dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+sha1dgst.o: ../../include/openssl/opensslconf.h
+sha1dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+sha1dgst.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+sha1dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
sha1dgst.o: ../md32_common.h sha1dgst.c sha_locl.h
sha256.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
sha256.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
@@ -135,8 +153,11 @@ sha512.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
sha512.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
sha512.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
sha512.o: ../cryptlib.h sha512.c
-sha_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-sha_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/sha.h
+sha_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+sha_dgst.o: ../../include/openssl/opensslconf.h
+sha_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+sha_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+sha_dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
sha_dgst.o: ../md32_common.h sha_dgst.c sha_locl.h
sha_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
sha_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha1-586.pl b/deps/openssl/openssl/crypto/sha/asm/sha1-586.pl
index a1f876281..1084d227f 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha1-586.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha1-586.pl
@@ -12,6 +12,8 @@
# commentary below], and in 2006 the rest was rewritten in order to
# gain freedom to liberate licensing terms.
+# January, September 2004.
+#
# It was noted that Intel IA-32 C compiler generates code which
# performs ~30% *faster* on P4 CPU than original *hand-coded*
# SHA1 assembler implementation. To address this problem (and
@@ -31,12 +33,92 @@
# ----------------------------------------------------------------
# <appro@fy.chalmers.se>
+# August 2009.
+#
+# George Spelvin has tipped that F_40_59(b,c,d) can be rewritten as
+# '(c&d) + (b&(c^d))', which allows to accumulate partial results
+# and lighten "pressure" on scratch registers. This resulted in
+# >12% performance improvement on contemporary AMD cores (with no
+# degradation on other CPUs:-). Also, the code was revised to maximize
+# "distance" between instructions producing input to 'lea' instruction
+# and the 'lea' instruction itself, which is essential for Intel Atom
+# core and resulted in ~15% improvement.
+
+# October 2010.
+#
+# Add SSSE3, Supplemental[!] SSE3, implementation. The idea behind it
+# is to offload message schedule denoted by Wt in NIST specification,
+# or Xupdate in OpenSSL source, to SIMD unit. The idea is not novel,
+# and in SSE2 context was first explored by Dean Gaudet in 2004, see
+# http://arctic.org/~dean/crypto/sha1.html. Since then several things
+# have changed that made it interesting again:
+#
+# a) XMM units became faster and wider;
+# b) instruction set became more versatile;
+# c) an important observation was made by Max Locktykhin, which made
+# it possible to reduce amount of instructions required to perform
+# the operation in question, for further details see
+# http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1/.
+
+# April 2011.
+#
+# Add AVX code path, probably most controversial... The thing is that
+# switch to AVX alone improves performance by as little as 4% in
+# comparison to SSSE3 code path. But below result doesn't look like
+# 4% improvement... Trouble is that Sandy Bridge decodes 'ro[rl]' as
+# pair of µ-ops, and it's the additional µ-ops, two per round, that
+# make it run slower than Core2 and Westmere. But 'sh[rl]d' is decoded
+# as single µ-op by Sandy Bridge and it's replacing 'ro[rl]' with
+# equivalent 'sh[rl]d' that is responsible for the impressive 5.1
+# cycles per processed byte. But 'sh[rl]d' is not something that used
+# to be fast, nor does it appear to be fast in upcoming Bulldozer
+# [according to its optimization manual]. Which is why AVX code path
+# is guarded by *both* AVX and synthetic bit denoting Intel CPUs.
+# One can argue that it's unfair to AMD, but without 'sh[rl]d' it
+# makes no sense to keep the AVX code path. If somebody feels that
+# strongly, it's probably more appropriate to discuss possibility of
+# using vector rotate XOP on AMD...
+
+######################################################################
+# Current performance is summarized in following table. Numbers are
+# CPU clock cycles spent to process single byte (less is better).
+#
+# x86 SSSE3 AVX
+# Pentium 15.7 -
+# PIII 11.5 -
+# P4 10.6 -
+# AMD K8 7.1 -
+# Core2 7.3 6.1/+20% -
+# Atom 12.5 9.5(*)/+32% -
+# Westmere 7.3 5.6/+30% -
+# Sandy Bridge 8.8 6.2/+40% 5.1(**)/+70%
+#
+# (*) Loop is 1056 instructions long and expected result is ~8.25.
+# It remains mystery [to me] why ILP is limited to 1.7.
+#
+# (**) As per above comment, the result is for AVX *plus* sh[rl]d.
+
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
push(@INC,"${dir}","${dir}../../perlasm");
require "x86asm.pl";
&asm_init($ARGV[0],"sha1-586.pl",$ARGV[$#ARGV] eq "386");
+$xmm=$ymm=0;
+for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+$ymm=1 if ($xmm &&
+ `$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
+ =~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
+ $1>=2.19); # first version supporting AVX
+
+$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32n" &&
+ `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
+ $1>=2.03); # first version supporting AVX
+
+&external_label("OPENSSL_ia32cap_P") if ($xmm);
+
+
$A="eax";
$B="ebx";
$C="ecx";
@@ -47,6 +129,10 @@ $tmp1="ebp";
@V=($A,$B,$C,$D,$E,$T);
+$alt=0; # 1 denotes alternative IALU implementation, which performs
+ # 8% *worse* on P4, same on Westmere and Atom, 2% better on
+ # Sandy Bridge...
+
sub BODY_00_15
{
local($n,$a,$b,$c,$d,$e,$f)=@_;
@@ -59,16 +145,18 @@ sub BODY_00_15
&rotl($tmp1,5); # tmp1=ROTATE(a,5)
&xor($f,$d);
&add($tmp1,$e); # tmp1+=e;
- &and($f,$b);
- &mov($e,&swtmp($n%16)); # e becomes volatile and is loaded
+ &mov($e,&swtmp($n%16)); # e becomes volatile and is loaded
# with xi, also note that e becomes
# f in next round...
- &xor($f,$d); # f holds F_00_19(b,c,d)
+ &and($f,$b);
&rotr($b,2); # b=ROTATE(b,30)
- &lea($tmp1,&DWP(0x5a827999,$tmp1,$e)); # tmp1+=K_00_19+xi
+ &xor($f,$d); # f holds F_00_19(b,c,d)
+ &lea($tmp1,&DWP(0x5a827999,$tmp1,$e)); # tmp1+=K_00_19+xi
- if ($n==15) { &add($f,$tmp1); } # f+=tmp1
+ if ($n==15) { &mov($e,&swtmp(($n+1)%16));# pre-fetch f for next round
+ &add($f,$tmp1); } # f+=tmp1
else { &add($tmp1,$f); } # f becomes a in next round
+ &mov($tmp1,$a) if ($alt && $n==15);
}
sub BODY_16_19
@@ -77,22 +165,41 @@ sub BODY_16_19
&comment("16_19 $n");
- &mov($f,&swtmp($n%16)); # f to hold Xupdate(xi,xa,xb,xc,xd)
- &mov($tmp1,$c); # tmp1 to hold F_00_19(b,c,d)
- &xor($f,&swtmp(($n+2)%16));
- &xor($tmp1,$d);
- &xor($f,&swtmp(($n+8)%16));
- &and($tmp1,$b); # tmp1 holds F_00_19(b,c,d)
- &rotr($b,2); # b=ROTATE(b,30)
+if ($alt) {
+ &xor($c,$d);
+ &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd)
+ &and($tmp1,$c); # tmp1 to hold F_00_19(b,c,d), b&=c^d
+ &xor($f,&swtmp(($n+8)%16));
+ &xor($tmp1,$d); # tmp1=F_00_19(b,c,d)
+ &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd
+ &rotl($f,1); # f=ROTATE(f,1)
+ &add($e,$tmp1); # e+=F_00_19(b,c,d)
+ &xor($c,$d); # restore $c
+ &mov($tmp1,$a); # b in next round
+ &rotr($b,$n==16?2:7); # b=ROTATE(b,30)
+ &mov(&swtmp($n%16),$f); # xi=f
+ &rotl($a,5); # ROTATE(a,5)
+ &lea($f,&DWP(0x5a827999,$f,$e));# f+=F_00_19(b,c,d)+e
+ &mov($e,&swtmp(($n+1)%16)); # pre-fetch f for next round
+ &add($f,$a); # f+=ROTATE(a,5)
+} else {
+ &mov($tmp1,$c); # tmp1 to hold F_00_19(b,c,d)
+ &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd)
+ &xor($tmp1,$d);
+ &xor($f,&swtmp(($n+8)%16));
+ &and($tmp1,$b);
&xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd
&rotl($f,1); # f=ROTATE(f,1)
&xor($tmp1,$d); # tmp1=F_00_19(b,c,d)
- &mov(&swtmp($n%16),$f); # xi=f
- &lea($f,&DWP(0x5a827999,$f,$e));# f+=K_00_19+e
- &mov($e,$a); # e becomes volatile
- &rotl($e,5); # e=ROTATE(a,5)
- &add($f,$tmp1); # f+=F_00_19(b,c,d)
- &add($f,$e); # f+=ROTATE(a,5)
+ &add($e,$tmp1); # e+=F_00_19(b,c,d)
+ &mov($tmp1,$a);
+ &rotr($b,2); # b=ROTATE(b,30)
+ &mov(&swtmp($n%16),$f); # xi=f
+ &rotl($tmp1,5); # ROTATE(a,5)
+ &lea($f,&DWP(0x5a827999,$f,$e));# f+=F_00_19(b,c,d)+e
+ &mov($e,&swtmp(($n+1)%16)); # pre-fetch f for next round
+ &add($f,$tmp1); # f+=ROTATE(a,5)
+}
}
sub BODY_20_39
@@ -102,21 +209,41 @@ sub BODY_20_39
&comment("20_39 $n");
+if ($alt) {
+ &xor($tmp1,$c); # tmp1 to hold F_20_39(b,c,d), b^=c
+ &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd)
+ &xor($tmp1,$d); # tmp1 holds F_20_39(b,c,d)
+ &xor($f,&swtmp(($n+8)%16));
+ &add($e,$tmp1); # e+=F_20_39(b,c,d)
+ &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd
+ &rotl($f,1); # f=ROTATE(f,1)
+ &mov($tmp1,$a); # b in next round
+ &rotr($b,7); # b=ROTATE(b,30)
+ &mov(&swtmp($n%16),$f) if($n<77);# xi=f
+ &rotl($a,5); # ROTATE(a,5)
+ &xor($b,$c) if($n==39);# warm up for BODY_40_59
+ &and($tmp1,$b) if($n==39);
+ &lea($f,&DWP($K,$f,$e)); # f+=e+K_XX_YY
+ &mov($e,&swtmp(($n+1)%16)) if($n<79);# pre-fetch f for next round
+ &add($f,$a); # f+=ROTATE(a,5)
+ &rotr($a,5) if ($n==79);
+} else {
&mov($tmp1,$b); # tmp1 to hold F_20_39(b,c,d)
- &mov($f,&swtmp($n%16)); # f to hold Xupdate(xi,xa,xb,xc,xd)
- &rotr($b,2); # b=ROTATE(b,30)
- &xor($f,&swtmp(($n+2)%16));
+ &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd)
&xor($tmp1,$c);
&xor($f,&swtmp(($n+8)%16));
&xor($tmp1,$d); # tmp1 holds F_20_39(b,c,d)
&xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd
&rotl($f,1); # f=ROTATE(f,1)
- &add($tmp1,$e);
- &mov(&swtmp($n%16),$f); # xi=f
- &mov($e,$a); # e becomes volatile
- &rotl($e,5); # e=ROTATE(a,5)
- &lea($f,&DWP($K,$f,$tmp1)); # f+=K_20_39+e
- &add($f,$e); # f+=ROTATE(a,5)
+ &add($e,$tmp1); # e+=F_20_39(b,c,d)
+ &rotr($b,2); # b=ROTATE(b,30)
+ &mov($tmp1,$a);
+ &rotl($tmp1,5); # ROTATE(a,5)
+ &mov(&swtmp($n%16),$f) if($n<77);# xi=f
+ &lea($f,&DWP($K,$f,$e)); # f+=e+K_XX_YY
+ &mov($e,&swtmp(($n+1)%16)) if($n<79);# pre-fetch f for next round
+ &add($f,$tmp1); # f+=ROTATE(a,5)
+}
}
sub BODY_40_59
@@ -125,41 +252,86 @@ sub BODY_40_59
&comment("40_59 $n");
- &mov($f,&swtmp($n%16)); # f to hold Xupdate(xi,xa,xb,xc,xd)
- &mov($tmp1,&swtmp(($n+2)%16));
- &xor($f,$tmp1);
- &mov($tmp1,&swtmp(($n+8)%16));
- &xor($f,$tmp1);
- &mov($tmp1,&swtmp(($n+13)%16));
- &xor($f,$tmp1); # f holds xa^xb^xc^xd
- &mov($tmp1,$b); # tmp1 to hold F_40_59(b,c,d)
+if ($alt) {
+ &add($e,$tmp1); # e+=b&(c^d)
+ &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd)
+ &mov($tmp1,$d);
+ &xor($f,&swtmp(($n+8)%16));
+ &xor($c,$d); # restore $c
+ &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd
&rotl($f,1); # f=ROTATE(f,1)
- &or($tmp1,$c);
- &mov(&swtmp($n%16),$f); # xi=f
- &and($tmp1,$d);
- &lea($f,&DWP(0x8f1bbcdc,$f,$e));# f+=K_40_59+e
- &mov($e,$b); # e becomes volatile and is used
- # to calculate F_40_59(b,c,d)
+ &and($tmp1,$c);
+ &rotr($b,7); # b=ROTATE(b,30)
+ &add($e,$tmp1); # e+=c&d
+ &mov($tmp1,$a); # b in next round
+ &mov(&swtmp($n%16),$f); # xi=f
+ &rotl($a,5); # ROTATE(a,5)
+ &xor($b,$c) if ($n<59);
+ &and($tmp1,$b) if ($n<59);# tmp1 to hold F_40_59(b,c,d)
+ &lea($f,&DWP(0x8f1bbcdc,$f,$e));# f+=K_40_59+e+(b&(c^d))
+ &mov($e,&swtmp(($n+1)%16)); # pre-fetch f for next round
+ &add($f,$a); # f+=ROTATE(a,5)
+} else {
+ &mov($tmp1,$c); # tmp1 to hold F_40_59(b,c,d)
+ &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd)
+ &xor($tmp1,$d);
+ &xor($f,&swtmp(($n+8)%16));
+ &and($tmp1,$b);
+ &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd
+ &rotl($f,1); # f=ROTATE(f,1)
+ &add($tmp1,$e); # b&(c^d)+=e
&rotr($b,2); # b=ROTATE(b,30)
- &and($e,$c);
- &or($tmp1,$e); # tmp1 holds F_40_59(b,c,d)
- &mov($e,$a);
- &rotl($e,5); # e=ROTATE(a,5)
- &add($f,$tmp1); # f+=tmp1;
+ &mov($e,$a); # e becomes volatile
+ &rotl($e,5); # ROTATE(a,5)
+ &mov(&swtmp($n%16),$f); # xi=f
+ &lea($f,&DWP(0x8f1bbcdc,$f,$tmp1));# f+=K_40_59+e+(b&(c^d))
+ &mov($tmp1,$c);
&add($f,$e); # f+=ROTATE(a,5)
+ &and($tmp1,$d);
+ &mov($e,&swtmp(($n+1)%16)); # pre-fetch f for next round
+ &add($f,$tmp1); # f+=c&d
+}
}
&function_begin("sha1_block_data_order");
+if ($xmm) {
+ &static_label("ssse3_shortcut");
+ &static_label("avx_shortcut") if ($ymm);
+ &static_label("K_XX_XX");
+
+ &call (&label("pic_point")); # make it PIC!
+ &set_label("pic_point");
+ &blindpop($tmp1);
+ &picmeup($T,"OPENSSL_ia32cap_P",$tmp1,&label("pic_point"));
+ &lea ($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1));
+
+ &mov ($A,&DWP(0,$T));
+ &mov ($D,&DWP(4,$T));
+ &test ($D,1<<9); # check SSSE3 bit
+ &jz (&label("x86"));
+ &test ($A,1<<24); # check FXSR bit
+ &jz (&label("x86"));
+ if ($ymm) {
+ &and ($D,1<<28); # mask AVX bit
+ &and ($A,1<<30); # mask "Intel CPU" bit
+ &or ($A,$D);
+ &cmp ($A,1<<28|1<<30);
+ &je (&label("avx_shortcut"));
+ }
+ &jmp (&label("ssse3_shortcut"));
+ &set_label("x86",16);
+}
&mov($tmp1,&wparam(0)); # SHA_CTX *c
&mov($T,&wparam(1)); # const void *input
&mov($A,&wparam(2)); # size_t num
- &stack_push(16); # allocate X[16]
+ &stack_push(16+3); # allocate X[16]
&shl($A,6);
&add($A,$T);
&mov(&wparam(2),$A); # pointer beyond the end of input
&mov($E,&DWP(16,$tmp1));# pre-load E
+ &jmp(&label("loop"));
- &set_label("loop",16);
+&set_label("loop",16);
# copy input chunk to X, but reversing byte order!
for ($i=0; $i<16; $i+=4)
@@ -213,8 +385,845 @@ sub BODY_40_59
&mov(&DWP(16,$tmp1),$C);
&jb(&label("loop"));
- &stack_pop(16);
+ &stack_pop(16+3);
&function_end("sha1_block_data_order");
+
+if ($xmm) {
+######################################################################
+# The SSSE3 implementation.
+#
+# %xmm[0-7] are used as ring @X[] buffer containing quadruples of last
+# 32 elements of the message schedule or Xupdate outputs. First 4
+# quadruples are simply byte-swapped input, next 4 are calculated
+# according to method originally suggested by Dean Gaudet (modulo
+# being implemented in SSSE3). Once 8 quadruples or 32 elements are
+# collected, it switches to routine proposed by Max Locktyukhin.
+#
+# Calculations inevitably require temporary reqisters, and there are
+# no %xmm registers left to spare. For this reason part of the ring
+# buffer, X[2..4] to be specific, is offloaded to 3 quadriples ring
+# buffer on the stack. Keep in mind that X[2] is alias X[-6], X[3] -
+# X[-5], and X[4] - X[-4]...
+#
+# Another notable optimization is aggressive stack frame compression
+# aiming to minimize amount of 9-byte instructions...
+#
+# Yet another notable optimization is "jumping" $B variable. It means
+# that there is no register permanently allocated for $B value. This
+# allowed to eliminate one instruction from body_20_39...
+#
+my $Xi=4; # 4xSIMD Xupdate round, start pre-seeded
+my @X=map("xmm$_",(4..7,0..3)); # pre-seeded for $Xi=4
+my @V=($A,$B,$C,$D,$E);
+my $j=0; # hash round
+my @T=($T,$tmp1);
+my $inp;
+
+my $_rol=sub { &rol(@_) };
+my $_ror=sub { &ror(@_) };
+
+&function_begin("_sha1_block_data_order_ssse3");
+ &call (&label("pic_point")); # make it PIC!
+ &set_label("pic_point");
+ &blindpop($tmp1);
+ &lea ($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1));
+&set_label("ssse3_shortcut");
+
+ &movdqa (@X[3],&QWP(0,$tmp1)); # K_00_19
+ &movdqa (@X[4],&QWP(16,$tmp1)); # K_20_39
+ &movdqa (@X[5],&QWP(32,$tmp1)); # K_40_59
+ &movdqa (@X[6],&QWP(48,$tmp1)); # K_60_79
+ &movdqa (@X[2],&QWP(64,$tmp1)); # pbswap mask
+
+ &mov ($E,&wparam(0)); # load argument block
+ &mov ($inp=@T[1],&wparam(1));
+ &mov ($D,&wparam(2));
+ &mov (@T[0],"esp");
+
+ # stack frame layout
+ #
+ # +0 X[0]+K X[1]+K X[2]+K X[3]+K # XMM->IALU xfer area
+ # X[4]+K X[5]+K X[6]+K X[7]+K
+ # X[8]+K X[9]+K X[10]+K X[11]+K
+ # X[12]+K X[13]+K X[14]+K X[15]+K
+ #
+ # +64 X[0] X[1] X[2] X[3] # XMM->XMM backtrace area
+ # X[4] X[5] X[6] X[7]
+ # X[8] X[9] X[10] X[11] # even borrowed for K_00_19
+ #
+ # +112 K_20_39 K_20_39 K_20_39 K_20_39 # constants
+ # K_40_59 K_40_59 K_40_59 K_40_59
+ # K_60_79 K_60_79 K_60_79 K_60_79
+ # K_00_19 K_00_19 K_00_19 K_00_19
+ # pbswap mask
+ #
+ # +192 ctx # argument block
+ # +196 inp
+ # +200 end
+ # +204 esp
+ &sub ("esp",208);
+ &and ("esp",-64);
+
+ &movdqa (&QWP(112+0,"esp"),@X[4]); # copy constants
+ &movdqa (&QWP(112+16,"esp"),@X[5]);
+ &movdqa (&QWP(112+32,"esp"),@X[6]);
+ &shl ($D,6); # len*64
+ &movdqa (&QWP(112+48,"esp"),@X[3]);
+ &add ($D,$inp); # end of input
+ &movdqa (&QWP(112+64,"esp"),@X[2]);
+ &add ($inp,64);
+ &mov (&DWP(192+0,"esp"),$E); # save argument block
+ &mov (&DWP(192+4,"esp"),$inp);
+ &mov (&DWP(192+8,"esp"),$D);
+ &mov (&DWP(192+12,"esp"),@T[0]); # save original %esp
+
+ &mov ($A,&DWP(0,$E)); # load context
+ &mov ($B,&DWP(4,$E));
+ &mov ($C,&DWP(8,$E));
+ &mov ($D,&DWP(12,$E));
+ &mov ($E,&DWP(16,$E));
+ &mov (@T[0],$B); # magic seed
+
+ &movdqu (@X[-4&7],&QWP(-64,$inp)); # load input to %xmm[0-3]
+ &movdqu (@X[-3&7],&QWP(-48,$inp));
+ &movdqu (@X[-2&7],&QWP(-32,$inp));
+ &movdqu (@X[-1&7],&QWP(-16,$inp));
+ &pshufb (@X[-4&7],@X[2]); # byte swap
+ &pshufb (@X[-3&7],@X[2]);
+ &pshufb (@X[-2&7],@X[2]);
+ &movdqa (&QWP(112-16,"esp"),@X[3]); # borrow last backtrace slot
+ &pshufb (@X[-1&7],@X[2]);
+ &paddd (@X[-4&7],@X[3]); # add K_00_19
+ &paddd (@X[-3&7],@X[3]);
+ &paddd (@X[-2&7],@X[3]);
+ &movdqa (&QWP(0,"esp"),@X[-4&7]); # X[]+K xfer to IALU
+ &psubd (@X[-4&7],@X[3]); # restore X[]
+ &movdqa (&QWP(0+16,"esp"),@X[-3&7]);
+ &psubd (@X[-3&7],@X[3]);
+ &movdqa (&QWP(0+32,"esp"),@X[-2&7]);
+ &psubd (@X[-2&7],@X[3]);
+ &movdqa (@X[0],@X[-3&7]);
+ &jmp (&label("loop"));
+
+######################################################################
+# SSE instruction sequence is first broken to groups of indepentent
+# instructions, independent in respect to their inputs and shifter
+# (not all architectures have more than one). Then IALU instructions
+# are "knitted in" between the SSE groups. Distance is maintained for
+# SSE latency of 2 in hope that it fits better upcoming AMD Bulldozer
+# [which allegedly also implements SSSE3]...
+#
+# Temporary registers usage. X[2] is volatile at the entry and at the
+# end is restored from backtrace ring buffer. X[3] is expected to
+# contain current K_XX_XX constant and is used to caclulate X[-1]+K
+# from previous round, it becomes volatile the moment the value is
+# saved to stack for transfer to IALU. X[4] becomes volatile whenever
+# X[-4] is accumulated and offloaded to backtrace ring buffer, at the
+# end it is loaded with next K_XX_XX [which becomes X[3] in next
+# round]...
+#
+sub Xupdate_ssse3_16_31() # recall that $Xi starts wtih 4
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 40 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &palignr(@X[0],@X[-4&7],8); # compose "X[-14]" in "X[0]"
+ &movdqa (@X[2],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &paddd (@X[3],@X[-1&7]);
+ &movdqa (&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);# save X[] to backtrace buffer
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &psrldq (@X[2],4); # "X[-3]", 3 dwords
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &pxor (@X[0],@X[-4&7]); # "X[0]"^="X[-16]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pxor (@X[2],@X[-2&7]); # "X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pxor (@X[0],@X[2]); # "X[0]"^="X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &movdqa (@X[4],@X[0]);
+ &movdqa (@X[2],@X[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pslldq (@X[4],12); # "X[0]"<<96, extract one dword
+ &paddd (@X[0],@X[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &psrld (@X[2],31);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (@X[3],@X[4]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &psrld (@X[4],30);
+ &por (@X[0],@X[2]); # "X[0]"<<<=1
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if ($Xi>5); # restore X[] from backtrace buffer
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pslld (@X[3],2);
+ &pxor (@X[0],@X[4]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (@X[4],&QWP(112-16+16*(($Xi)/5),"esp")); # K_XX_XX
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pxor (@X[0],@X[3]); # "X[0]"^=("X[0]"<<96)<<<2
+ &movdqa (@X[1],@X[-2&7]) if ($Xi<7);
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; } # remaining instructions [if any]
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+}
+
+sub Xupdate_ssse3_32_79()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions
+ my ($a,$b,$c,$d,$e);
+
+ &movdqa (@X[2],@X[-1&7]) if ($Xi==8);
+ eval(shift(@insns)); # body_20_39
+ &pxor (@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]"
+ &palignr(@X[2],@X[-2&7],8); # compose "X[-6]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &pxor (@X[0],@X[-7&7]); # "X[0]"^="X[-28]"
+ &movdqa (&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]); # save X[] to backtrace buffer
+ eval(shift(@insns));
+ eval(shift(@insns));
+ if ($Xi%5) {
+ &movdqa (@X[4],@X[3]); # "perpetuate" K_XX_XX...
+ } else { # ... or load next one
+ &movdqa (@X[4],&QWP(112-16+16*($Xi/5),"esp"));
+ }
+ &paddd (@X[3],@X[-1&7]);
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &pxor (@X[0],@X[2]); # "X[0]"^="X[-6]"
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &movdqa (@X[2],@X[0]);
+ &movdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &pslld (@X[0],2);
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ &psrld (@X[2],30);
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &por (@X[0],@X[2]); # "X[0]"<<<=2
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ &movdqa (@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if($Xi<19); # restore X[] from backtrace buffer
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ &movdqa (@X[3],@X[0]) if ($Xi<19);
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+}
+
+sub Xuplast_ssse3_80()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ &paddd (@X[3],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &movdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer IALU
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ &mov ($inp=@T[1],&DWP(192+4,"esp"));
+ &cmp ($inp,&DWP(192+8,"esp"));
+ &je (&label("done"));
+
+ &movdqa (@X[3],&QWP(112+48,"esp")); # K_00_19
+ &movdqa (@X[2],&QWP(112+64,"esp")); # pbswap mask
+ &movdqu (@X[-4&7],&QWP(0,$inp)); # load input
+ &movdqu (@X[-3&7],&QWP(16,$inp));
+ &movdqu (@X[-2&7],&QWP(32,$inp));
+ &movdqu (@X[-1&7],&QWP(48,$inp));
+ &add ($inp,64);
+ &pshufb (@X[-4&7],@X[2]); # byte swap
+ &mov (&DWP(192+4,"esp"),$inp);
+ &movdqa (&QWP(112-16,"esp"),@X[3]); # borrow last backtrace slot
+
+ $Xi=0;
+}
+
+sub Xloop_ssse3()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &pshufb (@X[($Xi-3)&7],@X[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &paddd (@X[($Xi-4)&7],@X[3]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (&QWP(0+16*$Xi,"esp"),@X[($Xi-4)&7]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &psubd (@X[($Xi-4)&7],@X[3]);
+
+ foreach (@insns) { eval; }
+ $Xi++;
+}
+
+sub Xtail_ssse3()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ foreach (@insns) { eval; }
+}
+
+sub body_00_19 () {
+ (
+ '($a,$b,$c,$d,$e)=@V;'.
+ '&add ($e,&DWP(4*($j&15),"esp"));', # X[]+K xfer
+ '&xor ($c,$d);',
+ '&mov (@T[1],$a);', # $b in next round
+ '&$_rol ($a,5);',
+ '&and (@T[0],$c);', # ($b&($c^$d))
+ '&xor ($c,$d);', # restore $c
+ '&xor (@T[0],$d);',
+ '&add ($e,$a);',
+ '&$_ror ($b,$j?7:2);', # $b>>>2
+ '&add ($e,@T[0]);' .'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+ );
+}
+
+sub body_20_39 () {
+ (
+ '($a,$b,$c,$d,$e)=@V;'.
+ '&add ($e,&DWP(4*($j++&15),"esp"));', # X[]+K xfer
+ '&xor (@T[0],$d);', # ($b^$d)
+ '&mov (@T[1],$a);', # $b in next round
+ '&$_rol ($a,5);',
+ '&xor (@T[0],$c);', # ($b^$d^$c)
+ '&add ($e,$a);',
+ '&$_ror ($b,7);', # $b>>>2
+ '&add ($e,@T[0]);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+ );
+}
+
+sub body_40_59 () {
+ (
+ '($a,$b,$c,$d,$e)=@V;'.
+ '&mov (@T[1],$c);',
+ '&xor ($c,$d);',
+ '&add ($e,&DWP(4*($j++&15),"esp"));', # X[]+K xfer
+ '&and (@T[1],$d);',
+ '&and (@T[0],$c);', # ($b&($c^$d))
+ '&$_ror ($b,7);', # $b>>>2
+ '&add ($e,@T[1]);',
+ '&mov (@T[1],$a);', # $b in next round
+ '&$_rol ($a,5);',
+ '&add ($e,@T[0]);',
+ '&xor ($c,$d);', # restore $c
+ '&add ($e,$a);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+ );
+}
+
+&set_label("loop",16);
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_32_79(\&body_00_19);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xuplast_ssse3_80(\&body_20_39); # can jump to "done"
+
+ $saved_j=$j; @saved_V=@V;
+
+ &Xloop_ssse3(\&body_20_39);
+ &Xloop_ssse3(\&body_20_39);
+ &Xloop_ssse3(\&body_20_39);
+
+ &mov (@T[1],&DWP(192,"esp")); # update context
+ &add ($A,&DWP(0,@T[1]));
+ &add (@T[0],&DWP(4,@T[1])); # $b
+ &add ($C,&DWP(8,@T[1]));
+ &mov (&DWP(0,@T[1]),$A);
+ &add ($D,&DWP(12,@T[1]));
+ &mov (&DWP(4,@T[1]),@T[0]);
+ &add ($E,&DWP(16,@T[1]));
+ &mov (&DWP(8,@T[1]),$C);
+ &mov ($B,@T[0]);
+ &mov (&DWP(12,@T[1]),$D);
+ &mov (&DWP(16,@T[1]),$E);
+ &movdqa (@X[0],@X[-3&7]);
+
+ &jmp (&label("loop"));
+
+&set_label("done",16); $j=$saved_j; @V=@saved_V;
+
+ &Xtail_ssse3(\&body_20_39);
+ &Xtail_ssse3(\&body_20_39);
+ &Xtail_ssse3(\&body_20_39);
+
+ &mov (@T[1],&DWP(192,"esp")); # update context
+ &add ($A,&DWP(0,@T[1]));
+ &mov ("esp",&DWP(192+12,"esp")); # restore %esp
+ &add (@T[0],&DWP(4,@T[1])); # $b
+ &add ($C,&DWP(8,@T[1]));
+ &mov (&DWP(0,@T[1]),$A);
+ &add ($D,&DWP(12,@T[1]));
+ &mov (&DWP(4,@T[1]),@T[0]);
+ &add ($E,&DWP(16,@T[1]));
+ &mov (&DWP(8,@T[1]),$C);
+ &mov (&DWP(12,@T[1]),$D);
+ &mov (&DWP(16,@T[1]),$E);
+
+&function_end("_sha1_block_data_order_ssse3");
+
+if ($ymm) {
+my $Xi=4; # 4xSIMD Xupdate round, start pre-seeded
+my @X=map("xmm$_",(4..7,0..3)); # pre-seeded for $Xi=4
+my @V=($A,$B,$C,$D,$E);
+my $j=0; # hash round
+my @T=($T,$tmp1);
+my $inp;
+
+my $_rol=sub { &shld(@_[0],@_) };
+my $_ror=sub { &shrd(@_[0],@_) };
+
+&function_begin("_sha1_block_data_order_avx");
+ &call (&label("pic_point")); # make it PIC!
+ &set_label("pic_point");
+ &blindpop($tmp1);
+ &lea ($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1));
+&set_label("avx_shortcut");
+ &vzeroall();
+
+ &vmovdqa(@X[3],&QWP(0,$tmp1)); # K_00_19
+ &vmovdqa(@X[4],&QWP(16,$tmp1)); # K_20_39
+ &vmovdqa(@X[5],&QWP(32,$tmp1)); # K_40_59
+ &vmovdqa(@X[6],&QWP(48,$tmp1)); # K_60_79
+ &vmovdqa(@X[2],&QWP(64,$tmp1)); # pbswap mask
+
+ &mov ($E,&wparam(0)); # load argument block
+ &mov ($inp=@T[1],&wparam(1));
+ &mov ($D,&wparam(2));
+ &mov (@T[0],"esp");
+
+ # stack frame layout
+ #
+ # +0 X[0]+K X[1]+K X[2]+K X[3]+K # XMM->IALU xfer area
+ # X[4]+K X[5]+K X[6]+K X[7]+K
+ # X[8]+K X[9]+K X[10]+K X[11]+K
+ # X[12]+K X[13]+K X[14]+K X[15]+K
+ #
+ # +64 X[0] X[1] X[2] X[3] # XMM->XMM backtrace area
+ # X[4] X[5] X[6] X[7]
+ # X[8] X[9] X[10] X[11] # even borrowed for K_00_19
+ #
+ # +112 K_20_39 K_20_39 K_20_39 K_20_39 # constants
+ # K_40_59 K_40_59 K_40_59 K_40_59
+ # K_60_79 K_60_79 K_60_79 K_60_79
+ # K_00_19 K_00_19 K_00_19 K_00_19
+ # pbswap mask
+ #
+ # +192 ctx # argument block
+ # +196 inp
+ # +200 end
+ # +204 esp
+ &sub ("esp",208);
+ &and ("esp",-64);
+
+ &vmovdqa(&QWP(112+0,"esp"),@X[4]); # copy constants
+ &vmovdqa(&QWP(112+16,"esp"),@X[5]);
+ &vmovdqa(&QWP(112+32,"esp"),@X[6]);
+ &shl ($D,6); # len*64
+ &vmovdqa(&QWP(112+48,"esp"),@X[3]);
+ &add ($D,$inp); # end of input
+ &vmovdqa(&QWP(112+64,"esp"),@X[2]);
+ &add ($inp,64);
+ &mov (&DWP(192+0,"esp"),$E); # save argument block
+ &mov (&DWP(192+4,"esp"),$inp);
+ &mov (&DWP(192+8,"esp"),$D);
+ &mov (&DWP(192+12,"esp"),@T[0]); # save original %esp
+
+ &mov ($A,&DWP(0,$E)); # load context
+ &mov ($B,&DWP(4,$E));
+ &mov ($C,&DWP(8,$E));
+ &mov ($D,&DWP(12,$E));
+ &mov ($E,&DWP(16,$E));
+ &mov (@T[0],$B); # magic seed
+
+ &vmovdqu(@X[-4&7],&QWP(-64,$inp)); # load input to %xmm[0-3]
+ &vmovdqu(@X[-3&7],&QWP(-48,$inp));
+ &vmovdqu(@X[-2&7],&QWP(-32,$inp));
+ &vmovdqu(@X[-1&7],&QWP(-16,$inp));
+ &vpshufb(@X[-4&7],@X[-4&7],@X[2]); # byte swap
+ &vpshufb(@X[-3&7],@X[-3&7],@X[2]);
+ &vpshufb(@X[-2&7],@X[-2&7],@X[2]);
+ &vmovdqa(&QWP(112-16,"esp"),@X[3]); # borrow last backtrace slot
+ &vpshufb(@X[-1&7],@X[-1&7],@X[2]);
+ &vpaddd (@X[0],@X[-4&7],@X[3]); # add K_00_19
+ &vpaddd (@X[1],@X[-3&7],@X[3]);
+ &vpaddd (@X[2],@X[-2&7],@X[3]);
+ &vmovdqa(&QWP(0,"esp"),@X[0]); # X[]+K xfer to IALU
+ &vmovdqa(&QWP(0+16,"esp"),@X[1]);
+ &vmovdqa(&QWP(0+32,"esp"),@X[2]);
+ &jmp (&label("loop"));
+
+sub Xupdate_avx_16_31() # recall that $Xi starts wtih 4
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 40 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpalignr(@X[0],@X[-3&7],@X[-4&7],8); # compose "X[-14]" in "X[0]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpaddd (@X[3],@X[3],@X[-1&7]);
+ &vmovdqa (&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);# save X[] to backtrace buffer
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpsrldq(@X[2],@X[-1&7],4); # "X[-3]", 3 dwords
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"^="X[-16]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpxor (@X[2],@X[2],@X[-2&7]); # "X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vmovdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpxor (@X[0],@X[0],@X[2]); # "X[0]"^="X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpsrld (@X[2],@X[0],31);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpslldq(@X[4],@X[0],12); # "X[0]"<<96, extract one dword
+ &vpaddd (@X[0],@X[0],@X[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpsrld (@X[3],@X[4],30);
+ &vpor (@X[0],@X[0],@X[2]); # "X[0]"<<<=1
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpslld (@X[4],@X[4],2);
+ &vmovdqa (@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if ($Xi>5); # restore X[] from backtrace buffer
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpxor (@X[0],@X[0],@X[3]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpxor (@X[0],@X[0],@X[4]); # "X[0]"^=("X[0]"<<96)<<<2
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vmovdqa (@X[4],&QWP(112-16+16*(($Xi)/5),"esp")); # K_XX_XX
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; } # remaining instructions [if any]
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+}
+
+sub Xupdate_avx_32_79()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions
+ my ($a,$b,$c,$d,$e);
+
+ &vpalignr(@X[2],@X[-1&7],@X[-2&7],8); # compose "X[-6]"
+ &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]"
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &vpxor (@X[0],@X[0],@X[-7&7]); # "X[0]"^="X[-28]"
+ &vmovdqa (&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]); # save X[] to backtrace buffer
+ eval(shift(@insns));
+ eval(shift(@insns));
+ if ($Xi%5) {
+ &vmovdqa (@X[4],@X[3]); # "perpetuate" K_XX_XX...
+ } else { # ... or load next one
+ &vmovdqa (@X[4],&QWP(112-16+16*($Xi/5),"esp"));
+ }
+ &vpaddd (@X[3],@X[3],@X[-1&7]);
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &vpxor (@X[0],@X[0],@X[2]); # "X[0]"^="X[-6]"
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &vpsrld (@X[2],@X[0],30);
+ &vmovdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &vpslld (@X[0],@X[0],2);
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &vpor (@X[0],@X[0],@X[2]); # "X[0]"<<<=2
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ &vmovdqa (@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if($Xi<19); # restore X[] from backtrace buffer
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+}
+
+sub Xuplast_avx_80()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ &vpaddd (@X[3],@X[3],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vmovdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer IALU
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ &mov ($inp=@T[1],&DWP(192+4,"esp"));
+ &cmp ($inp,&DWP(192+8,"esp"));
+ &je (&label("done"));
+
+ &vmovdqa(@X[3],&QWP(112+48,"esp")); # K_00_19
+ &vmovdqa(@X[2],&QWP(112+64,"esp")); # pbswap mask
+ &vmovdqu(@X[-4&7],&QWP(0,$inp)); # load input
+ &vmovdqu(@X[-3&7],&QWP(16,$inp));
+ &vmovdqu(@X[-2&7],&QWP(32,$inp));
+ &vmovdqu(@X[-1&7],&QWP(48,$inp));
+ &add ($inp,64);
+ &vpshufb(@X[-4&7],@X[-4&7],@X[2]); # byte swap
+ &mov (&DWP(192+4,"esp"),$inp);
+ &vmovdqa(&QWP(112-16,"esp"),@X[3]); # borrow last backtrace slot
+
+ $Xi=0;
+}
+
+sub Xloop_avx()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpshufb (@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpaddd (@X[$Xi&7],@X[($Xi-4)&7],@X[3]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vmovdqa (&QWP(0+16*$Xi,"esp"),@X[$Xi&7]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; }
+ $Xi++;
+}
+
+sub Xtail_avx()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ foreach (@insns) { eval; }
+}
+
+&set_label("loop",16);
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_32_79(\&body_00_19);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xuplast_avx_80(\&body_20_39); # can jump to "done"
+
+ $saved_j=$j; @saved_V=@V;
+
+ &Xloop_avx(\&body_20_39);
+ &Xloop_avx(\&body_20_39);
+ &Xloop_avx(\&body_20_39);
+
+ &mov (@T[1],&DWP(192,"esp")); # update context
+ &add ($A,&DWP(0,@T[1]));
+ &add (@T[0],&DWP(4,@T[1])); # $b
+ &add ($C,&DWP(8,@T[1]));
+ &mov (&DWP(0,@T[1]),$A);
+ &add ($D,&DWP(12,@T[1]));
+ &mov (&DWP(4,@T[1]),@T[0]);
+ &add ($E,&DWP(16,@T[1]));
+ &mov (&DWP(8,@T[1]),$C);
+ &mov ($B,@T[0]);
+ &mov (&DWP(12,@T[1]),$D);
+ &mov (&DWP(16,@T[1]),$E);
+
+ &jmp (&label("loop"));
+
+&set_label("done",16); $j=$saved_j; @V=@saved_V;
+
+ &Xtail_avx(\&body_20_39);
+ &Xtail_avx(\&body_20_39);
+ &Xtail_avx(\&body_20_39);
+
+ &vzeroall();
+
+ &mov (@T[1],&DWP(192,"esp")); # update context
+ &add ($A,&DWP(0,@T[1]));
+ &mov ("esp",&DWP(192+12,"esp")); # restore %esp
+ &add (@T[0],&DWP(4,@T[1])); # $b
+ &add ($C,&DWP(8,@T[1]));
+ &mov (&DWP(0,@T[1]),$A);
+ &add ($D,&DWP(12,@T[1]));
+ &mov (&DWP(4,@T[1]),@T[0]);
+ &add ($E,&DWP(16,@T[1]));
+ &mov (&DWP(8,@T[1]),$C);
+ &mov (&DWP(12,@T[1]),$D);
+ &mov (&DWP(16,@T[1]),$E);
+&function_end("_sha1_block_data_order_avx");
+}
+&set_label("K_XX_XX",64);
+&data_word(0x5a827999,0x5a827999,0x5a827999,0x5a827999); # K_00_19
+&data_word(0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1); # K_20_39
+&data_word(0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc); # K_40_59
+&data_word(0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6); # K_60_79
+&data_word(0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f); # pbswap mask
+}
&asciz("SHA1 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
&asm_finish();
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha1-alpha.pl b/deps/openssl/openssl/crypto/sha/asm/sha1-alpha.pl
new file mode 100644
index 000000000..6c4b9251f
--- /dev/null
+++ b/deps/openssl/openssl/crypto/sha/asm/sha1-alpha.pl
@@ -0,0 +1,322 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA1 block procedure for Alpha.
+
+# On 21264 performance is 33% better than code generated by vendor
+# compiler, and 75% better than GCC [3.4], and in absolute terms is
+# 8.7 cycles per processed byte. Implementation features vectorized
+# byte swap, but not Xupdate.
+
+@X=( "\$0", "\$1", "\$2", "\$3", "\$4", "\$5", "\$6", "\$7",
+ "\$8", "\$9", "\$10", "\$11", "\$12", "\$13", "\$14", "\$15");
+$ctx="a0"; # $16
+$inp="a1";
+$num="a2";
+$A="a3";
+$B="a4"; # 20
+$C="a5";
+$D="t8";
+$E="t9"; @V=($A,$B,$C,$D,$E);
+$t0="t10"; # 24
+$t1="t11";
+$t2="ra";
+$t3="t12";
+$K="AT"; # 28
+
+sub BODY_00_19 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i==0);
+ ldq_u @X[0],0+0($inp)
+ ldq_u @X[1],0+7($inp)
+___
+$code.=<<___ if (!($i&1) && $i<14);
+ ldq_u @X[$i+2],($i+2)*4+0($inp)
+ ldq_u @X[$i+3],($i+2)*4+7($inp)
+___
+$code.=<<___ if (!($i&1) && $i<15);
+ extql @X[$i],$inp,@X[$i]
+ extqh @X[$i+1],$inp,@X[$i+1]
+
+ or @X[$i+1],@X[$i],@X[$i] # pair of 32-bit values are fetched
+
+ srl @X[$i],24,$t0 # vectorized byte swap
+ srl @X[$i],8,$t2
+
+ sll @X[$i],8,$t3
+ sll @X[$i],24,@X[$i]
+ zapnot $t0,0x11,$t0
+ zapnot $t2,0x22,$t2
+
+ zapnot @X[$i],0x88,@X[$i]
+ or $t0,$t2,$t0
+ zapnot $t3,0x44,$t3
+ sll $a,5,$t1
+
+ or @X[$i],$t0,@X[$i]
+ addl $K,$e,$e
+ and $b,$c,$t2
+ zapnot $a,0xf,$a
+
+ or @X[$i],$t3,@X[$i]
+ srl $a,27,$t0
+ bic $d,$b,$t3
+ sll $b,30,$b
+
+ extll @X[$i],4,@X[$i+1] # extract upper half
+ or $t2,$t3,$t2
+ addl @X[$i],$e,$e
+
+ addl $t1,$e,$e
+ srl $b,32,$t3
+ zapnot @X[$i],0xf,@X[$i]
+
+ addl $t0,$e,$e
+ addl $t2,$e,$e
+ or $t3,$b,$b
+___
+$code.=<<___ if (($i&1) && $i<15);
+ sll $a,5,$t1
+ addl $K,$e,$e
+ and $b,$c,$t2
+ zapnot $a,0xf,$a
+
+ srl $a,27,$t0
+ addl @X[$i%16],$e,$e
+ bic $d,$b,$t3
+ sll $b,30,$b
+
+ or $t2,$t3,$t2
+ addl $t1,$e,$e
+ srl $b,32,$t3
+ zapnot @X[$i],0xf,@X[$i]
+
+ addl $t0,$e,$e
+ addl $t2,$e,$e
+ or $t3,$b,$b
+___
+$code.=<<___ if ($i>=15); # with forward Xupdate
+ sll $a,5,$t1
+ addl $K,$e,$e
+ and $b,$c,$t2
+ xor @X[($j+2)%16],@X[$j%16],@X[$j%16]
+
+ zapnot $a,0xf,$a
+ addl @X[$i%16],$e,$e
+ bic $d,$b,$t3
+ xor @X[($j+8)%16],@X[$j%16],@X[$j%16]
+
+ srl $a,27,$t0
+ addl $t1,$e,$e
+ or $t2,$t3,$t2
+ xor @X[($j+13)%16],@X[$j%16],@X[$j%16]
+
+ sll $b,30,$b
+ addl $t0,$e,$e
+ srl @X[$j%16],31,$t1
+
+ addl $t2,$e,$e
+ srl $b,32,$t3
+ addl @X[$j%16],@X[$j%16],@X[$j%16]
+
+ or $t3,$b,$b
+ zapnot @X[$i%16],0xf,@X[$i%16]
+ or $t1,@X[$j%16],@X[$j%16]
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i<79); # with forward Xupdate
+ sll $a,5,$t1
+ addl $K,$e,$e
+ zapnot $a,0xf,$a
+ xor @X[($j+2)%16],@X[$j%16],@X[$j%16]
+
+ sll $b,30,$t3
+ addl $t1,$e,$e
+ xor $b,$c,$t2
+ xor @X[($j+8)%16],@X[$j%16],@X[$j%16]
+
+ srl $b,2,$b
+ addl @X[$i%16],$e,$e
+ xor $d,$t2,$t2
+ xor @X[($j+13)%16],@X[$j%16],@X[$j%16]
+
+ srl @X[$j%16],31,$t1
+ addl $t2,$e,$e
+ srl $a,27,$t0
+ addl @X[$j%16],@X[$j%16],@X[$j%16]
+
+ or $t3,$b,$b
+ addl $t0,$e,$e
+ or $t1,@X[$j%16],@X[$j%16]
+___
+$code.=<<___ if ($i<77);
+ zapnot @X[$i%16],0xf,@X[$i%16]
+___
+$code.=<<___ if ($i==79); # with context fetch
+ sll $a,5,$t1
+ addl $K,$e,$e
+ zapnot $a,0xf,$a
+ ldl @X[0],0($ctx)
+
+ sll $b,30,$t3
+ addl $t1,$e,$e
+ xor $b,$c,$t2
+ ldl @X[1],4($ctx)
+
+ srl $b,2,$b
+ addl @X[$i%16],$e,$e
+ xor $d,$t2,$t2
+ ldl @X[2],8($ctx)
+
+ srl $a,27,$t0
+ addl $t2,$e,$e
+ ldl @X[3],12($ctx)
+
+ or $t3,$b,$b
+ addl $t0,$e,$e
+ ldl @X[4],16($ctx)
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___; # with forward Xupdate
+ sll $a,5,$t1
+ addl $K,$e,$e
+ zapnot $a,0xf,$a
+ xor @X[($j+2)%16],@X[$j%16],@X[$j%16]
+
+ srl $a,27,$t0
+ and $b,$c,$t2
+ and $b,$d,$t3
+ xor @X[($j+8)%16],@X[$j%16],@X[$j%16]
+
+ sll $b,30,$b
+ addl $t1,$e,$e
+ xor @X[($j+13)%16],@X[$j%16],@X[$j%16]
+
+ srl @X[$j%16],31,$t1
+ addl $t0,$e,$e
+ or $t2,$t3,$t2
+ and $c,$d,$t3
+
+ or $t2,$t3,$t2
+ srl $b,32,$t3
+ addl @X[$i%16],$e,$e
+ addl @X[$j%16],@X[$j%16],@X[$j%16]
+
+ or $t3,$b,$b
+ addl $t2,$e,$e
+ or $t1,@X[$j%16],@X[$j%16]
+ zapnot @X[$i%16],0xf,@X[$i%16]
+___
+}
+
+$code=<<___;
+#ifdef __linux__
+#include <asm/regdef.h>
+#else
+#include <asm.h>
+#include <regdef.h>
+#endif
+
+.text
+
+.set noat
+.set noreorder
+.globl sha1_block_data_order
+.align 5
+.ent sha1_block_data_order
+sha1_block_data_order:
+ lda sp,-64(sp)
+ stq ra,0(sp)
+ stq s0,8(sp)
+ stq s1,16(sp)
+ stq s2,24(sp)
+ stq s3,32(sp)
+ stq s4,40(sp)
+ stq s5,48(sp)
+ stq fp,56(sp)
+ .mask 0x0400fe00,-64
+ .frame sp,64,ra
+ .prologue 0
+
+ ldl $A,0($ctx)
+ ldl $B,4($ctx)
+ sll $num,6,$num
+ ldl $C,8($ctx)
+ ldl $D,12($ctx)
+ ldl $E,16($ctx)
+ addq $inp,$num,$num
+
+.Lloop:
+ .set noreorder
+ ldah $K,23170(zero)
+ zapnot $B,0xf,$B
+ lda $K,31129($K) # K_00_19
+___
+for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
+
+$code.=<<___;
+ ldah $K,28378(zero)
+ lda $K,-5215($K) # K_20_39
+___
+for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+
+$code.=<<___;
+ ldah $K,-28900(zero)
+ lda $K,-17188($K) # K_40_59
+___
+for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+
+$code.=<<___;
+ ldah $K,-13725(zero)
+ lda $K,-15914($K) # K_60_79
+___
+for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+
+$code.=<<___;
+ addl @X[0],$A,$A
+ addl @X[1],$B,$B
+ addl @X[2],$C,$C
+ addl @X[3],$D,$D
+ addl @X[4],$E,$E
+ stl $A,0($ctx)
+ stl $B,4($ctx)
+ addq $inp,64,$inp
+ stl $C,8($ctx)
+ stl $D,12($ctx)
+ stl $E,16($ctx)
+ cmpult $inp,$num,$t1
+ bne $t1,.Lloop
+
+ .set noreorder
+ ldq ra,0(sp)
+ ldq s0,8(sp)
+ ldq s1,16(sp)
+ ldq s2,24(sp)
+ ldq s3,32(sp)
+ ldq s4,40(sp)
+ ldq s5,48(sp)
+ ldq fp,56(sp)
+ lda sp,64(sp)
+ ret (ra)
+.end sha1_block_data_order
+.ascii "SHA1 block transform for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
+.align 2
+___
+$output=shift and open STDOUT,">$output";
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha1-armv4-large.pl b/deps/openssl/openssl/crypto/sha/asm/sha1-armv4-large.pl
index 79e3f6137..33da3e0e3 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha1-armv4-large.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha1-armv4-large.pl
@@ -47,6 +47,10 @@
# Cortex A8 core and in absolute terms ~870 cycles per input block
# [or 13.6 cycles per byte].
+# February 2011.
+#
+# Profiler-assisted and platform-specific optimization resulted in 10%
+# improvement on Cortex A8 core and 12.2 cycles per byte.
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
@@ -76,31 +80,41 @@ $code.=<<___;
add $e,$K,$e,ror#2 @ E+=K_xx_xx
ldr $t3,[$Xi,#2*4]
eor $t0,$t0,$t1
- eor $t2,$t2,$t3
+ eor $t2,$t2,$t3 @ 1 cycle stall
eor $t1,$c,$d @ F_xx_xx
mov $t0,$t0,ror#31
add $e,$e,$a,ror#27 @ E+=ROR(A,27)
eor $t0,$t0,$t2,ror#31
+ str $t0,[$Xi,#-4]!
$opt1 @ F_xx_xx
$opt2 @ F_xx_xx
add $e,$e,$t0 @ E+=X[i]
- str $t0,[$Xi,#-4]!
___
}
sub BODY_00_15 {
my ($a,$b,$c,$d,$e)=@_;
$code.=<<___;
- ldrb $t0,[$inp],#4
- ldrb $t1,[$inp,#-1]
- ldrb $t2,[$inp,#-2]
+#if __ARM_ARCH__<7
+ ldrb $t1,[$inp,#2]
+ ldrb $t0,[$inp,#3]
+ ldrb $t2,[$inp,#1]
add $e,$K,$e,ror#2 @ E+=K_00_19
- ldrb $t3,[$inp,#-3]
+ ldrb $t3,[$inp],#4
+ orr $t0,$t0,$t1,lsl#8
+ eor $t1,$c,$d @ F_xx_xx
+ orr $t0,$t0,$t2,lsl#16
add $e,$e,$a,ror#27 @ E+=ROR(A,27)
- orr $t0,$t1,$t0,lsl#24
+ orr $t0,$t0,$t3,lsl#24
+#else
+ ldr $t0,[$inp],#4 @ handles unaligned
+ add $e,$K,$e,ror#2 @ E+=K_00_19
eor $t1,$c,$d @ F_xx_xx
- orr $t0,$t0,$t2,lsl#8
- orr $t0,$t0,$t3,lsl#16
+ add $e,$e,$a,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev $t0,$t0 @ byte swap
+#endif
+#endif
and $t1,$b,$t1,ror#2
add $e,$e,$t0 @ E+=X[i]
eor $t1,$t1,$d,ror#2 @ F_00_19(B,C,D)
@@ -136,6 +150,8 @@ ___
}
$code=<<___;
+#include "arm_arch.h"
+
.text
.global sha1_block_data_order
@@ -161,7 +177,7 @@ for($i=0;$i<5;$i++) {
$code.=<<___;
teq $Xi,sp
bne .L_00_15 @ [((11+4)*5+2)*3]
- sub sp,sp,#5*4
+ sub sp,sp,#25*4
___
&BODY_00_15(@V); unshift(@V,pop(@V));
&BODY_16_19(@V); unshift(@V,pop(@V));
@@ -171,7 +187,6 @@ ___
$code.=<<___;
ldr $K,.LK_20_39 @ [+15+16*4]
- sub sp,sp,#20*4
cmn sp,#0 @ [+3], clear carry to denote 20_39
.L_20_39_or_60_79:
___
@@ -210,10 +225,14 @@ $code.=<<___;
teq $inp,$len
bne .Lloop @ [+18], total 1307
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r12,pc}
+#else
ldmia sp!,{r4-r12,lr}
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
bx lr @ interoperable with Thumb ISA:-)
+#endif
.align 2
.LK_00_19: .word 0x5a827999
.LK_20_39: .word 0x6ed9eba1
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha1-ia64.pl b/deps/openssl/openssl/crypto/sha/asm/sha1-ia64.pl
index 51c4f47ec..02d35d161 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha1-ia64.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha1-ia64.pl
@@ -15,7 +15,7 @@
# is >50% better than HP C and >2x better than gcc.
$code=<<___;
-.ident \"sha1-ia64.s, version 1.2\"
+.ident \"sha1-ia64.s, version 1.3\"
.ident \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\"
.explicit
@@ -26,14 +26,10 @@ if ($^O eq "hpux") {
$ADDP="addp4";
for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
} else { $ADDP="add"; }
-for (@ARGV) { $big_endian=1 if (/\-DB_ENDIAN/);
- $big_endian=0 if (/\-DL_ENDIAN/); }
-if (!defined($big_endian))
- { $big_endian=(unpack('L',pack('N',1))==1); }
#$human=1;
if ($human) { # useful for visual code auditing...
- ($A,$B,$C,$D,$E,$T) = ("A","B","C","D","E","T");
+ ($A,$B,$C,$D,$E) = ("A","B","C","D","E");
($h0,$h1,$h2,$h3,$h4) = ("h0","h1","h2","h3","h4");
($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
( "K_00_19","K_20_39","K_40_59","K_60_79" );
@@ -41,47 +37,50 @@ if ($human) { # useful for visual code auditing...
"X8", "X9","X10","X11","X12","X13","X14","X15" );
}
else {
- ($A,$B,$C,$D,$E,$T) = ("loc0","loc1","loc2","loc3","loc4","loc5");
- ($h0,$h1,$h2,$h3,$h4) = ("loc6","loc7","loc8","loc9","loc10");
+ ($A,$B,$C,$D,$E) = ("loc0","loc1","loc2","loc3","loc4");
+ ($h0,$h1,$h2,$h3,$h4) = ("loc5","loc6","loc7","loc8","loc9");
($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
- ( "r14", "r15", "loc11", "loc12" );
+ ( "r14", "r15", "loc10", "loc11" );
@X= ( "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" );
}
sub BODY_00_15 {
local *code=shift;
-local ($i,$a,$b,$c,$d,$e,$f)=@_;
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+my $Xn=@X[$j%16];
$code.=<<___ if ($i==0);
-{ .mmi; ld1 $X[$i&0xf]=[inp],2 // MSB
+{ .mmi; ld1 $X[$i]=[inp],2 // MSB
ld1 tmp2=[tmp3],2 };;
{ .mmi; ld1 tmp0=[inp],2
ld1 tmp4=[tmp3],2 // LSB
- dep $X[$i&0xf]=$X[$i&0xf],tmp2,8,8 };;
+ dep $X[$i]=$X[$i],tmp2,8,8 };;
___
if ($i<15) {
$code.=<<___;
-{ .mmi; ld1 $X[($i+1)&0xf]=[inp],2 // +1
+{ .mmi; ld1 $Xn=[inp],2 // forward Xload
+ nop.m 0x0
dep tmp1=tmp0,tmp4,8,8 };;
-{ .mmi; ld1 tmp2=[tmp3],2 // +1
+{ .mmi; ld1 tmp2=[tmp3],2 // forward Xload
and tmp4=$c,$b
- dep $X[$i&0xf]=$X[$i&0xf],tmp1,16,16 } //;;
-{ .mmi; andcm tmp1=$d,$b
- add tmp0=$e,$K_00_19
+ dep $X[$i]=$X[$i],tmp1,16,16} //;;
+{ .mmi; add $e=$e,$K_00_19 // e+=K_00_19
+ andcm tmp1=$d,$b
dep.z tmp5=$a,5,27 };; // a<<5
-{ .mmi; or tmp4=tmp4,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d)
- add $f=tmp0,$X[$i&0xf] // f=xi+e+K_00_19
+{ .mmi; add $e=$e,$X[$i] // e+=Xload
+ or tmp4=tmp4,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d)
extr.u tmp1=$a,27,5 };; // a>>27
-{ .mmi; ld1 tmp0=[inp],2 // +1
- add $f=$f,tmp4 // f+=F_00_19(b,c,d)
+{ .mmi; ld1 tmp0=[inp],2 // forward Xload
+ add $e=$e,tmp4 // e+=F_00_19(b,c,d)
shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30)
-{ .mmi; ld1 tmp4=[tmp3],2 // +1
+{ .mmi; ld1 tmp4=[tmp3],2 // forward Xload
or tmp5=tmp1,tmp5 // ROTATE(a,5)
mux2 tmp6=$a,0x44 };; // see b in next iteration
-{ .mii; add $f=$f,tmp5 // f+=ROTATE(a,5)
- dep $X[($i+1)&0xf]=$X[($i+1)&0xf],tmp2,8,8 // +1
- mux2 $X[$i&0xf]=$X[$i&0xf],0x44 } //;;
+{ .mii; add $e=$e,tmp5 // e+=ROTATE(a,5)
+ dep $Xn=$Xn,tmp2,8,8 // forward Xload
+ mux2 $X[$i]=$X[$i],0x44 } //;;
___
}
@@ -89,24 +88,24 @@ else {
$code.=<<___;
{ .mii; and tmp3=$c,$b
dep tmp1=tmp0,tmp4,8,8;;
- dep $X[$i&0xf]=$X[$i&0xf],tmp1,16,16 } //;;
-{ .mmi; andcm tmp1=$d,$b
- add tmp0=$e,$K_00_19
+ dep $X[$i]=$X[$i],tmp1,16,16} //;;
+{ .mmi; add $e=$e,$K_00_19 // e+=K_00_19
+ andcm tmp1=$d,$b
dep.z tmp5=$a,5,27 };; // a<<5
-{ .mmi; or tmp4=tmp3,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d)
- add $f=tmp0,$X[$i&0xf] // f=xi+e+K_00_19
+{ .mmi; add $e=$e,$X[$i] // e+=Xupdate
+ or tmp4=tmp3,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d)
extr.u tmp1=$a,27,5 } // a>>27
-{ .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1
- xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1
+{ .mmi; xor $Xn=$Xn,$X[($j+2)%16] // forward Xupdate
+ xor tmp3=$X[($j+8)%16],$X[($j+13)%16] // forward Xupdate
nop.i 0 };;
-{ .mmi; add $f=$f,tmp4 // f+=F_00_19(b,c,d)
- xor tmp2=tmp2,tmp3 // +1
+{ .mmi; add $e=$e,tmp4 // e+=F_00_19(b,c,d)
+ xor $Xn=$Xn,tmp3 // forward Xupdate
shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30)
{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5)
mux2 tmp6=$a,0x44 };; // see b in next iteration
-{ .mii; add $f=$f,tmp1 // f+=ROTATE(a,5)
- shrp $e=tmp2,tmp2,31 // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
- mux2 $X[$i&0xf]=$X[$i&0xf],0x44 };;
+{ .mii; add $e=$e,tmp1 // e+=ROTATE(a,5)
+ shrp $Xn=$Xn,$Xn,31 // ROTATE(x[0]^x[2]^x[8]^x[13],1)
+ mux2 $X[$i]=$X[$i],0x44 };;
___
}
@@ -114,27 +113,28 @@ ___
sub BODY_16_19 {
local *code=shift;
-local ($i,$a,$b,$c,$d,$e,$f)=@_;
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+my $Xn=@X[$j%16];
$code.=<<___;
-{ .mmi; mov $X[$i&0xf]=$f // Xupdate
- and tmp0=$c,$b
+{ .mib; add $e=$e,$K_00_19 // e+=K_00_19
dep.z tmp5=$a,5,27 } // a<<5
-{ .mmi; andcm tmp1=$d,$b
- add tmp4=$e,$K_00_19 };;
-{ .mmi; or tmp0=tmp0,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d)
- add $f=$f,tmp4 // f+=e+K_00_19
+{ .mib; andcm tmp1=$d,$b
+ and tmp0=$c,$b };;
+{ .mmi; add $e=$e,$X[$i%16] // e+=Xupdate
+ or tmp0=tmp0,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d)
extr.u tmp1=$a,27,5 } // a>>27
-{ .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1
- xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1
+{ .mmi; xor $Xn=$Xn,$X[($j+2)%16] // forward Xupdate
+ xor tmp3=$X[($j+8)%16],$X[($j+13)%16] // forward Xupdate
nop.i 0 };;
-{ .mmi; add $f=$f,tmp0 // f+=F_00_19(b,c,d)
- xor tmp2=tmp2,tmp3 // +1
+{ .mmi; add $e=$e,tmp0 // f+=F_00_19(b,c,d)
+ xor $Xn=$Xn,tmp3 // forward Xupdate
shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30)
{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5)
mux2 tmp6=$a,0x44 };; // see b in next iteration
-{ .mii; add $f=$f,tmp1 // f+=ROTATE(a,5)
- shrp $e=tmp2,tmp2,31 // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
+{ .mii; add $e=$e,tmp1 // e+=ROTATE(a,5)
+ shrp $Xn=$Xn,$Xn,31 // ROTATE(x[0]^x[2]^x[8]^x[13],1)
nop.i 0 };;
___
@@ -142,49 +142,47 @@ ___
sub BODY_20_39 {
local *code=shift;
-local ($i,$a,$b,$c,$d,$e,$f,$Konst)=@_;
+my ($i,$a,$b,$c,$d,$e,$Konst)=@_;
$Konst = $K_20_39 if (!defined($Konst));
+my $j=$i+1;
+my $Xn=@X[$j%16];
if ($i<79) {
$code.=<<___;
-{ .mib; mov $X[$i&0xf]=$f // Xupdate
+{ .mib; add $e=$e,$Konst // e+=K_XX_XX
dep.z tmp5=$a,5,27 } // a<<5
{ .mib; xor tmp0=$c,$b
- add tmp4=$e,$Konst };;
-{ .mmi; xor tmp0=tmp0,$d // F_20_39(b,c,d)=b^c^d
- add $f=$f,tmp4 // f+=e+K_20_39
+ xor $Xn=$Xn,$X[($j+2)%16] };; // forward Xupdate
+{ .mib; add $e=$e,$X[$i%16] // e+=Xupdate
extr.u tmp1=$a,27,5 } // a>>27
-{ .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1
- xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1
- nop.i 0 };;
-{ .mmi; add $f=$f,tmp0 // f+=F_20_39(b,c,d)
- xor tmp2=tmp2,tmp3 // +1
+{ .mib; xor tmp0=tmp0,$d // F_20_39(b,c,d)=b^c^d
+ xor $Xn=$Xn,$X[($j+8)%16] };; // forward Xupdate
+{ .mmi; add $e=$e,tmp0 // e+=F_20_39(b,c,d)
+ xor $Xn=$Xn,$X[($j+13)%16] // forward Xupdate
shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30)
{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5)
mux2 tmp6=$a,0x44 };; // see b in next iteration
-{ .mii; add $f=$f,tmp1 // f+=ROTATE(a,5)
- shrp $e=tmp2,tmp2,31 // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
+{ .mii; add $e=$e,tmp1 // e+=ROTATE(a,5)
+ shrp $Xn=$Xn,$Xn,31 // ROTATE(x[0]^x[2]^x[8]^x[13],1)
nop.i 0 };;
___
}
else {
$code.=<<___;
-{ .mib; mov $X[$i&0xf]=$f // Xupdate
+{ .mib; add $e=$e,$Konst // e+=K_60_79
dep.z tmp5=$a,5,27 } // a<<5
{ .mib; xor tmp0=$c,$b
- add tmp4=$e,$Konst };;
-{ .mib; xor tmp0=tmp0,$d // F_20_39(b,c,d)=b^c^d
- extr.u tmp1=$a,27,5 } // a>>27
-{ .mib; add $f=$f,tmp4 // f+=e+K_20_39
add $h1=$h1,$a };; // wrap up
-{ .mmi; add $f=$f,tmp0 // f+=F_20_39(b,c,d)
- shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) ;;?
-{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5)
+{ .mib; add $e=$e,$X[$i%16] // e+=Xupdate
+ extr.u tmp1=$a,27,5 } // a>>27
+{ .mib; xor tmp0=tmp0,$d // F_20_39(b,c,d)=b^c^d
add $h3=$h3,$c };; // wrap up
-{ .mib; add tmp3=1,inp // used in unaligned codepath
- add $f=$f,tmp1 } // f+=ROTATE(a,5)
-{ .mib; add $h2=$h2,$b // wrap up
+{ .mmi; add $e=$e,tmp0 // e+=F_20_39(b,c,d)
+ or tmp1=tmp1,tmp5 // ROTATE(a,5)
+ shrp $b=tmp6,tmp6,2 };; // b=ROTATE(b,30) ;;?
+{ .mmi; add $e=$e,tmp1 // e+=ROTATE(a,5)
+ add tmp3=1,inp // used in unaligned codepath
add $h4=$h4,$d };; // wrap up
___
@@ -193,29 +191,29 @@ ___
sub BODY_40_59 {
local *code=shift;
-local ($i,$a,$b,$c,$d,$e,$f)=@_;
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+my $Xn=@X[$j%16];
$code.=<<___;
-{ .mmi; mov $X[$i&0xf]=$f // Xupdate
- and tmp0=$c,$b
+{ .mib; add $e=$e,$K_40_59 // e+=K_40_59
dep.z tmp5=$a,5,27 } // a<<5
-{ .mmi; and tmp1=$d,$b
- add tmp4=$e,$K_40_59 };;
-{ .mmi; or tmp0=tmp0,tmp1 // (b&c)|(b&d)
- add $f=$f,tmp4 // f+=e+K_40_59
+{ .mib; and tmp1=$c,$d
+ xor tmp0=$c,$d };;
+{ .mmi; add $e=$e,$X[$i%16] // e+=Xupdate
+ add tmp5=tmp5,tmp1 // a<<5+(c&d)
extr.u tmp1=$a,27,5 } // a>>27
-{ .mmi; and tmp4=$c,$d
- xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1
- xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1
- };;
-{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5)
- xor tmp2=tmp2,tmp3 // +1
+{ .mmi; and tmp0=tmp0,$b
+ xor $Xn=$Xn,$X[($j+2)%16] // forward Xupdate
+ xor tmp3=$X[($j+8)%16],$X[($j+13)%16] };; // forward Xupdate
+{ .mmi; add $e=$e,tmp0 // e+=b&(c^d)
+ add tmp5=tmp5,tmp1 // ROTATE(a,5)+(c&d)
shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30)
-{ .mmi; or tmp0=tmp0,tmp4 // F_40_59(b,c,d)=(b&c)|(b&d)|(c&d)
+{ .mmi; xor $Xn=$Xn,tmp3
mux2 tmp6=$a,0x44 };; // see b in next iteration
-{ .mii; add $f=$f,tmp0 // f+=F_40_59(b,c,d)
- shrp $e=tmp2,tmp2,31;; // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
- add $f=$f,tmp1 };; // f+=ROTATE(a,5)
+{ .mii; add $e=$e,tmp5 // e+=ROTATE(a,5)+(c&d)
+ shrp $Xn=$Xn,$Xn,31 // ROTATE(x[0]^x[2]^x[8]^x[13],1)
+ nop.i 0x0 };;
___
}
@@ -237,7 +235,7 @@ inp=r33; // in1
.align 32
sha1_block_data_order:
.prologue
-{ .mmi; alloc tmp1=ar.pfs,3,15,0,0
+{ .mmi; alloc tmp1=ar.pfs,3,14,0,0
$ADDP tmp0=4,ctx
.save ar.lc,r3
mov r3=ar.lc }
@@ -245,8 +243,8 @@ sha1_block_data_order:
$ADDP inp=0,inp
mov r2=pr };;
tmp4=in2;
-tmp5=loc13;
-tmp6=loc14;
+tmp5=loc12;
+tmp6=loc13;
.body
{ .mlx; ld4 $h0=[ctx],8
movl $K_00_19=0x5a827999 }
@@ -273,7 +271,8 @@ tmp6=loc14;
___
-{ my $i,@V=($A,$B,$C,$D,$E,$T);
+{ my $i;
+ my @V=($A,$B,$C,$D,$E);
for($i=0;$i<16;$i++) { &BODY_00_15(\$code,$i,@V); unshift(@V,pop(@V)); }
for(;$i<20;$i++) { &BODY_16_19(\$code,$i,@V); unshift(@V,pop(@V)); }
@@ -281,12 +280,12 @@ ___
for(;$i<60;$i++) { &BODY_40_59(\$code,$i,@V); unshift(@V,pop(@V)); }
for(;$i<80;$i++) { &BODY_60_79(\$code,$i,@V); unshift(@V,pop(@V)); }
- (($V[5] eq $D) and ($V[0] eq $E)) or die; # double-check
+ (($V[0] eq $A) and ($V[4] eq $E)) or die; # double-check
}
$code.=<<___;
-{ .mmb; add $h0=$h0,$E
- nop.m 0
+{ .mmb; add $h0=$h0,$A
+ add $h2=$h2,$C
br.ctop.dptk.many .Ldtop };;
.Ldend:
{ .mmi; add tmp0=4,ctx
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha1-mips.pl b/deps/openssl/openssl/crypto/sha/asm/sha1-mips.pl
new file mode 100644
index 000000000..f1a702f38
--- /dev/null
+++ b/deps/openssl/openssl/crypto/sha/asm/sha1-mips.pl
@@ -0,0 +1,354 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA1 block procedure for MIPS.
+
+# Performance improvement is 30% on unaligned input. The "secret" is
+# to deploy lwl/lwr pair to load unaligned input. One could have
+# vectorized Xupdate on MIPSIII/IV, but the goal was to code MIPS32-
+# compatible subroutine. There is room for minor optimization on
+# little-endian platforms...
+
+######################################################################
+# There is a number of MIPS ABI in use, O32 and N32/64 are most
+# widely used. Then there is a new contender: NUBI. It appears that if
+# one picks the latter, it's possible to arrange code in ABI neutral
+# manner. Therefore let's stick to NUBI register layout:
+#
+($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
+($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
+#
+# The return value is placed in $a0. Following coding rules facilitate
+# interoperability:
+#
+# - never ever touch $tp, "thread pointer", former $gp;
+# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
+# old code];
+# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
+#
+# For reference here is register layout for N32/64 MIPS ABIs:
+#
+# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
+# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
+# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
+# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
+# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
+#
+$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
+
+if ($flavour =~ /64|n32/i) {
+ $PTR_ADD="dadd"; # incidentally works even on n32
+ $PTR_SUB="dsub"; # incidentally works even on n32
+ $REG_S="sd";
+ $REG_L="ld";
+ $PTR_SLL="dsll"; # incidentally works even on n32
+ $SZREG=8;
+} else {
+ $PTR_ADD="add";
+ $PTR_SUB="sub";
+ $REG_S="sw";
+ $REG_L="lw";
+ $PTR_SLL="sll";
+ $SZREG=4;
+}
+#
+# <appro@openssl.org>
+#
+######################################################################
+
+$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0;
+
+for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); }
+open STDOUT,">$output";
+
+if (!defined($big_endian))
+ { $big_endian=(unpack('L',pack('N',1))==1); }
+
+# offsets of the Most and Least Significant Bytes
+$MSB=$big_endian?0:3;
+$LSB=3&~$MSB;
+
+@X=map("\$$_",(8..23)); # a4-a7,s0-s11
+
+$ctx=$a0;
+$inp=$a1;
+$num=$a2;
+$A="\$1";
+$B="\$2";
+$C="\$3";
+$D="\$7";
+$E="\$24"; @V=($A,$B,$C,$D,$E);
+$t0="\$25";
+$t1=$num; # $num is offloaded to stack
+$t2="\$30"; # fp
+$K="\$31"; # ra
+
+sub BODY_00_14 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___ if (!$big_endian);
+ srl $t0,@X[$i],24 # byte swap($i)
+ srl $t1,@X[$i],8
+ andi $t2,@X[$i],0xFF00
+ sll @X[$i],@X[$i],24
+ andi $t1,0xFF00
+ sll $t2,$t2,8
+ or @X[$i],$t0
+ or $t1,$t2
+ or @X[$i],$t1
+___
+$code.=<<___;
+ lwl @X[$j],$j*4+$MSB($inp)
+ sll $t0,$a,5 # $i
+ addu $e,$K
+ lwr @X[$j],$j*4+$LSB($inp)
+ srl $t1,$a,27
+ addu $e,$t0
+ xor $t0,$c,$d
+ addu $e,$t1
+ sll $t2,$b,30
+ and $t0,$b
+ srl $b,$b,2
+ xor $t0,$d
+ addu $e,@X[$i]
+ or $b,$t2
+ addu $e,$t0
+___
+}
+
+sub BODY_15_19 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+
+$code.=<<___ if (!$big_endian && $i==15);
+ srl $t0,@X[$i],24 # byte swap($i)
+ srl $t1,@X[$i],8
+ andi $t2,@X[$i],0xFF00
+ sll @X[$i],@X[$i],24
+ andi $t1,0xFF00
+ sll $t2,$t2,8
+ or @X[$i],$t0
+ or @X[$i],$t1
+ or @X[$i],$t2
+___
+$code.=<<___;
+ xor @X[$j%16],@X[($j+2)%16]
+ sll $t0,$a,5 # $i
+ addu $e,$K
+ srl $t1,$a,27
+ addu $e,$t0
+ xor @X[$j%16],@X[($j+8)%16]
+ xor $t0,$c,$d
+ addu $e,$t1
+ xor @X[$j%16],@X[($j+13)%16]
+ sll $t2,$b,30
+ and $t0,$b
+ srl $t1,@X[$j%16],31
+ addu @X[$j%16],@X[$j%16]
+ srl $b,$b,2
+ xor $t0,$d
+ or @X[$j%16],$t1
+ addu $e,@X[$i%16]
+ or $b,$t2
+ addu $e,$t0
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i<79);
+ xor @X[$j%16],@X[($j+2)%16]
+ sll $t0,$a,5 # $i
+ addu $e,$K
+ srl $t1,$a,27
+ addu $e,$t0
+ xor @X[$j%16],@X[($j+8)%16]
+ xor $t0,$c,$d
+ addu $e,$t1
+ xor @X[$j%16],@X[($j+13)%16]
+ sll $t2,$b,30
+ xor $t0,$b
+ srl $t1,@X[$j%16],31
+ addu @X[$j%16],@X[$j%16]
+ srl $b,$b,2
+ addu $e,@X[$i%16]
+ or @X[$j%16],$t1
+ or $b,$t2
+ addu $e,$t0
+___
+$code.=<<___ if ($i==79);
+ lw @X[0],0($ctx)
+ sll $t0,$a,5 # $i
+ addu $e,$K
+ lw @X[1],4($ctx)
+ srl $t1,$a,27
+ addu $e,$t0
+ lw @X[2],8($ctx)
+ xor $t0,$c,$d
+ addu $e,$t1
+ lw @X[3],12($ctx)
+ sll $t2,$b,30
+ xor $t0,$b
+ lw @X[4],16($ctx)
+ srl $b,$b,2
+ addu $e,@X[$i%16]
+ or $b,$t2
+ addu $e,$t0
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i<79);
+ xor @X[$j%16],@X[($j+2)%16]
+ sll $t0,$a,5 # $i
+ addu $e,$K
+ srl $t1,$a,27
+ addu $e,$t0
+ xor @X[$j%16],@X[($j+8)%16]
+ and $t0,$c,$d
+ addu $e,$t1
+ xor @X[$j%16],@X[($j+13)%16]
+ sll $t2,$b,30
+ addu $e,$t0
+ srl $t1,@X[$j%16],31
+ xor $t0,$c,$d
+ addu @X[$j%16],@X[$j%16]
+ and $t0,$b
+ srl $b,$b,2
+ or @X[$j%16],$t1
+ addu $e,@X[$i%16]
+ or $b,$t2
+ addu $e,$t0
+___
+}
+
+$FRAMESIZE=16; # large enough to accomodate NUBI saved registers
+$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000;
+
+$code=<<___;
+#ifdef OPENSSL_FIPSCANISTER
+# include <openssl/fipssyms.h>
+#endif
+
+.text
+
+.set noat
+.set noreorder
+.align 5
+.globl sha1_block_data_order
+.ent sha1_block_data_order
+sha1_block_data_order:
+ .frame $sp,$FRAMESIZE*$SZREG,$ra
+ .mask $SAVED_REGS_MASK,-$SZREG
+ .set noreorder
+ $PTR_SUB $sp,$FRAMESIZE*$SZREG
+ $REG_S $ra,($FRAMESIZE-1)*$SZREG($sp)
+ $REG_S $fp,($FRAMESIZE-2)*$SZREG($sp)
+ $REG_S $s11,($FRAMESIZE-3)*$SZREG($sp)
+ $REG_S $s10,($FRAMESIZE-4)*$SZREG($sp)
+ $REG_S $s9,($FRAMESIZE-5)*$SZREG($sp)
+ $REG_S $s8,($FRAMESIZE-6)*$SZREG($sp)
+ $REG_S $s7,($FRAMESIZE-7)*$SZREG($sp)
+ $REG_S $s6,($FRAMESIZE-8)*$SZREG($sp)
+ $REG_S $s5,($FRAMESIZE-9)*$SZREG($sp)
+ $REG_S $s4,($FRAMESIZE-10)*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue
+ $REG_S $s3,($FRAMESIZE-11)*$SZREG($sp)
+ $REG_S $s2,($FRAMESIZE-12)*$SZREG($sp)
+ $REG_S $s1,($FRAMESIZE-13)*$SZREG($sp)
+ $REG_S $s0,($FRAMESIZE-14)*$SZREG($sp)
+ $REG_S $gp,($FRAMESIZE-15)*$SZREG($sp)
+___
+$code.=<<___;
+ $PTR_SLL $num,6
+ $PTR_ADD $num,$inp
+ $REG_S $num,0($sp)
+ lw $A,0($ctx)
+ lw $B,4($ctx)
+ lw $C,8($ctx)
+ lw $D,12($ctx)
+ b .Loop
+ lw $E,16($ctx)
+.align 4
+.Loop:
+ .set reorder
+ lwl @X[0],$MSB($inp)
+ lui $K,0x5a82
+ lwr @X[0],$LSB($inp)
+ ori $K,0x7999 # K_00_19
+___
+for ($i=0;$i<15;$i++) { &BODY_00_14($i,@V); unshift(@V,pop(@V)); }
+for (;$i<20;$i++) { &BODY_15_19($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+ lui $K,0x6ed9
+ ori $K,0xeba1 # K_20_39
+___
+for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+ lui $K,0x8f1b
+ ori $K,0xbcdc # K_40_59
+___
+for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+ lui $K,0xca62
+ ori $K,0xc1d6 # K_60_79
+___
+for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+ $PTR_ADD $inp,64
+ $REG_L $num,0($sp)
+
+ addu $A,$X[0]
+ addu $B,$X[1]
+ sw $A,0($ctx)
+ addu $C,$X[2]
+ addu $D,$X[3]
+ sw $B,4($ctx)
+ addu $E,$X[4]
+ sw $C,8($ctx)
+ sw $D,12($ctx)
+ sw $E,16($ctx)
+ .set noreorder
+ bne $inp,$num,.Loop
+ nop
+
+ .set noreorder
+ $REG_L $ra,($FRAMESIZE-1)*$SZREG($sp)
+ $REG_L $fp,($FRAMESIZE-2)*$SZREG($sp)
+ $REG_L $s11,($FRAMESIZE-3)*$SZREG($sp)
+ $REG_L $s10,($FRAMESIZE-4)*$SZREG($sp)
+ $REG_L $s9,($FRAMESIZE-5)*$SZREG($sp)
+ $REG_L $s8,($FRAMESIZE-6)*$SZREG($sp)
+ $REG_L $s7,($FRAMESIZE-7)*$SZREG($sp)
+ $REG_L $s6,($FRAMESIZE-8)*$SZREG($sp)
+ $REG_L $s5,($FRAMESIZE-9)*$SZREG($sp)
+ $REG_L $s4,($FRAMESIZE-10)*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $s3,($FRAMESIZE-11)*$SZREG($sp)
+ $REG_L $s2,($FRAMESIZE-12)*$SZREG($sp)
+ $REG_L $s1,($FRAMESIZE-13)*$SZREG($sp)
+ $REG_L $s0,($FRAMESIZE-14)*$SZREG($sp)
+ $REG_L $gp,($FRAMESIZE-15)*$SZREG($sp)
+___
+$code.=<<___;
+ jr $ra
+ $PTR_ADD $sp,$FRAMESIZE*$SZREG
+.end sha1_block_data_order
+.rdata
+.asciiz "SHA1 for MIPS, CRYPTOGAMS by <appro\@openssl.org>"
+___
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha1-parisc.pl b/deps/openssl/openssl/crypto/sha/asm/sha1-parisc.pl
new file mode 100644
index 000000000..6d7bf495b
--- /dev/null
+++ b/deps/openssl/openssl/crypto/sha/asm/sha1-parisc.pl
@@ -0,0 +1,259 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA1 block procedure for PA-RISC.
+
+# June 2009.
+#
+# On PA-7100LC performance is >30% better than gcc 3.2 generated code
+# for aligned input and >50% better for unaligned. Compared to vendor
+# compiler on PA-8600 it's almost 60% faster in 64-bit build and just
+# few percent faster in 32-bit one (this for aligned input, data for
+# unaligned input is not available).
+#
+# Special thanks to polarhome.com for providing HP-UX account.
+
+$flavour = shift;
+$output = shift;
+open STDOUT,">$output";
+
+if ($flavour =~ /64/) {
+ $LEVEL ="2.0W";
+ $SIZE_T =8;
+ $FRAME_MARKER =80;
+ $SAVED_RP =16;
+ $PUSH ="std";
+ $PUSHMA ="std,ma";
+ $POP ="ldd";
+ $POPMB ="ldd,mb";
+} else {
+ $LEVEL ="1.0";
+ $SIZE_T =4;
+ $FRAME_MARKER =48;
+ $SAVED_RP =20;
+ $PUSH ="stw";
+ $PUSHMA ="stwm";
+ $POP ="ldw";
+ $POPMB ="ldwm";
+}
+
+$FRAME=14*$SIZE_T+$FRAME_MARKER;# 14 saved regs + frame marker
+ # [+ argument transfer]
+$ctx="%r26"; # arg0
+$inp="%r25"; # arg1
+$num="%r24"; # arg2
+
+$t0="%r28";
+$t1="%r29";
+$K="%r31";
+
+@X=("%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8",
+ "%r9", "%r10","%r11","%r12","%r13","%r14","%r15","%r16",$t0);
+
+@V=($A,$B,$C,$D,$E)=("%r19","%r20","%r21","%r22","%r23");
+
+sub BODY_00_19 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i<15);
+ addl $K,$e,$e ; $i
+ shd $a,$a,27,$t1
+ addl @X[$i],$e,$e
+ and $c,$b,$t0
+ addl $t1,$e,$e
+ andcm $d,$b,$t1
+ shd $b,$b,2,$b
+ or $t1,$t0,$t0
+ addl $t0,$e,$e
+___
+$code.=<<___ if ($i>=15); # with forward Xupdate
+ addl $K,$e,$e ; $i
+ shd $a,$a,27,$t1
+ xor @X[($j+2)%16],@X[$j%16],@X[$j%16]
+ addl @X[$i%16],$e,$e
+ and $c,$b,$t0
+ xor @X[($j+8)%16],@X[$j%16],@X[$j%16]
+ addl $t1,$e,$e
+ andcm $d,$b,$t1
+ shd $b,$b,2,$b
+ or $t1,$t0,$t0
+ xor @X[($j+13)%16],@X[$j%16],@X[$j%16]
+ add $t0,$e,$e
+ shd @X[$j%16],@X[$j%16],31,@X[$j%16]
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i<79);
+ xor @X[($j+2)%16],@X[$j%16],@X[$j%16] ; $i
+ addl $K,$e,$e
+ shd $a,$a,27,$t1
+ xor @X[($j+8)%16],@X[$j%16],@X[$j%16]
+ addl @X[$i%16],$e,$e
+ xor $b,$c,$t0
+ xor @X[($j+13)%16],@X[$j%16],@X[$j%16]
+ addl $t1,$e,$e
+ shd $b,$b,2,$b
+ xor $d,$t0,$t0
+ shd @X[$j%16],@X[$j%16],31,@X[$j%16]
+ addl $t0,$e,$e
+___
+$code.=<<___ if ($i==79); # with context load
+ ldw 0($ctx),@X[0] ; $i
+ addl $K,$e,$e
+ shd $a,$a,27,$t1
+ ldw 4($ctx),@X[1]
+ addl @X[$i%16],$e,$e
+ xor $b,$c,$t0
+ ldw 8($ctx),@X[2]
+ addl $t1,$e,$e
+ shd $b,$b,2,$b
+ xor $d,$t0,$t0
+ ldw 12($ctx),@X[3]
+ addl $t0,$e,$e
+ ldw 16($ctx),@X[4]
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___;
+ shd $a,$a,27,$t1 ; $i
+ addl $K,$e,$e
+ xor @X[($j+2)%16],@X[$j%16],@X[$j%16]
+ xor $d,$c,$t0
+ addl @X[$i%16],$e,$e
+ xor @X[($j+8)%16],@X[$j%16],@X[$j%16]
+ and $b,$t0,$t0
+ addl $t1,$e,$e
+ shd $b,$b,2,$b
+ xor @X[($j+13)%16],@X[$j%16],@X[$j%16]
+ addl $t0,$e,$e
+ and $d,$c,$t1
+ shd @X[$j%16],@X[$j%16],31,@X[$j%16]
+ addl $t1,$e,$e
+___
+}
+
+$code=<<___;
+ .LEVEL $LEVEL
+ .SPACE \$TEXT\$
+ .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
+
+ .EXPORT sha1_block_data_order,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
+sha1_block_data_order
+ .PROC
+ .CALLINFO FRAME=`$FRAME-14*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=16
+ .ENTRY
+ $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue
+ $PUSHMA %r3,$FRAME(%sp)
+ $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp)
+ $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp)
+ $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp)
+ $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp)
+ $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp)
+ $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp)
+ $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp)
+ $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp)
+ $PUSH %r12,`-$FRAME+9*$SIZE_T`(%sp)
+ $PUSH %r13,`-$FRAME+10*$SIZE_T`(%sp)
+ $PUSH %r14,`-$FRAME+11*$SIZE_T`(%sp)
+ $PUSH %r15,`-$FRAME+12*$SIZE_T`(%sp)
+ $PUSH %r16,`-$FRAME+13*$SIZE_T`(%sp)
+
+ ldw 0($ctx),$A
+ ldw 4($ctx),$B
+ ldw 8($ctx),$C
+ ldw 12($ctx),$D
+ ldw 16($ctx),$E
+
+ extru $inp,31,2,$t0 ; t0=inp&3;
+ sh3addl $t0,%r0,$t0 ; t0*=8;
+ subi 32,$t0,$t0 ; t0=32-t0;
+ mtctl $t0,%cr11 ; %sar=t0;
+
+L\$oop
+ ldi 3,$t0
+ andcm $inp,$t0,$t0 ; 64-bit neutral
+___
+ for ($i=0;$i<15;$i++) { # load input block
+ $code.="\tldw `4*$i`($t0),@X[$i]\n"; }
+$code.=<<___;
+ cmpb,*= $inp,$t0,L\$aligned
+ ldw 60($t0),@X[15]
+ ldw 64($t0),@X[16]
+___
+ for ($i=0;$i<16;$i++) { # align input
+ $code.="\tvshd @X[$i],@X[$i+1],@X[$i]\n"; }
+$code.=<<___;
+L\$aligned
+ ldil L'0x5a827000,$K ; K_00_19
+ ldo 0x999($K),$K
+___
+for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+ ldil L'0x6ed9e000,$K ; K_20_39
+ ldo 0xba1($K),$K
+___
+
+for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+ ldil L'0x8f1bb000,$K ; K_40_59
+ ldo 0xcdc($K),$K
+___
+
+for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+ ldil L'0xca62c000,$K ; K_60_79
+ ldo 0x1d6($K),$K
+___
+for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+
+$code.=<<___;
+ addl @X[0],$A,$A
+ addl @X[1],$B,$B
+ addl @X[2],$C,$C
+ addl @X[3],$D,$D
+ addl @X[4],$E,$E
+ stw $A,0($ctx)
+ stw $B,4($ctx)
+ stw $C,8($ctx)
+ stw $D,12($ctx)
+ stw $E,16($ctx)
+ addib,*<> -1,$num,L\$oop
+ ldo 64($inp),$inp
+
+ $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue
+ $POP `-$FRAME+1*$SIZE_T`(%sp),%r4
+ $POP `-$FRAME+2*$SIZE_T`(%sp),%r5
+ $POP `-$FRAME+3*$SIZE_T`(%sp),%r6
+ $POP `-$FRAME+4*$SIZE_T`(%sp),%r7
+ $POP `-$FRAME+5*$SIZE_T`(%sp),%r8
+ $POP `-$FRAME+6*$SIZE_T`(%sp),%r9
+ $POP `-$FRAME+7*$SIZE_T`(%sp),%r10
+ $POP `-$FRAME+8*$SIZE_T`(%sp),%r11
+ $POP `-$FRAME+9*$SIZE_T`(%sp),%r12
+ $POP `-$FRAME+10*$SIZE_T`(%sp),%r13
+ $POP `-$FRAME+11*$SIZE_T`(%sp),%r14
+ $POP `-$FRAME+12*$SIZE_T`(%sp),%r15
+ $POP `-$FRAME+13*$SIZE_T`(%sp),%r16
+ bv (%r2)
+ .EXIT
+ $POPMB -$FRAME(%sp),%r3
+ .PROCEND
+ .STRINGZ "SHA1 block transform for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/,\*/,/gm if ($SIZE_T==4);
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha1-ppc.pl b/deps/openssl/openssl/crypto/sha/asm/sha1-ppc.pl
index dcd0fcdfc..2140dd2f8 100644..100755
--- a/deps/openssl/openssl/crypto/sha/asm/sha1-ppc.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha1-ppc.pl
@@ -24,12 +24,14 @@ $flavour = shift;
if ($flavour =~ /64/) {
$SIZE_T =8;
+ $LRSAVE =2*$SIZE_T;
$UCMP ="cmpld";
$STU ="stdu";
$POP ="ld";
$PUSH ="std";
} elsif ($flavour =~ /32/) {
$SIZE_T =4;
+ $LRSAVE =$SIZE_T;
$UCMP ="cmplw";
$STU ="stwu";
$POP ="lwz";
@@ -43,7 +45,8 @@ die "can't locate ppc-xlate.pl";
open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-$FRAME=24*$SIZE_T;
+$FRAME=24*$SIZE_T+64;
+$LOCALS=6*$SIZE_T;
$K ="r0";
$sp ="r1";
@@ -162,9 +165,8 @@ $code=<<___;
.globl .sha1_block_data_order
.align 4
.sha1_block_data_order:
+ $STU $sp,-$FRAME($sp)
mflr r0
- $STU $sp,`-($FRAME+64)`($sp)
- $PUSH r0,`$FRAME-$SIZE_T*18`($sp)
$PUSH r15,`$FRAME-$SIZE_T*17`($sp)
$PUSH r16,`$FRAME-$SIZE_T*16`($sp)
$PUSH r17,`$FRAME-$SIZE_T*15`($sp)
@@ -182,6 +184,7 @@ $code=<<___;
$PUSH r29,`$FRAME-$SIZE_T*3`($sp)
$PUSH r30,`$FRAME-$SIZE_T*2`($sp)
$PUSH r31,`$FRAME-$SIZE_T*1`($sp)
+ $PUSH r0,`$FRAME+$LRSAVE`($sp)
lwz $A,0($ctx)
lwz $B,4($ctx)
lwz $C,8($ctx)
@@ -192,37 +195,14 @@ $code=<<___;
Laligned:
mtctr $num
bl Lsha1_block_private
-Ldone:
- $POP r0,`$FRAME-$SIZE_T*18`($sp)
- $POP r15,`$FRAME-$SIZE_T*17`($sp)
- $POP r16,`$FRAME-$SIZE_T*16`($sp)
- $POP r17,`$FRAME-$SIZE_T*15`($sp)
- $POP r18,`$FRAME-$SIZE_T*14`($sp)
- $POP r19,`$FRAME-$SIZE_T*13`($sp)
- $POP r20,`$FRAME-$SIZE_T*12`($sp)
- $POP r21,`$FRAME-$SIZE_T*11`($sp)
- $POP r22,`$FRAME-$SIZE_T*10`($sp)
- $POP r23,`$FRAME-$SIZE_T*9`($sp)
- $POP r24,`$FRAME-$SIZE_T*8`($sp)
- $POP r25,`$FRAME-$SIZE_T*7`($sp)
- $POP r26,`$FRAME-$SIZE_T*6`($sp)
- $POP r27,`$FRAME-$SIZE_T*5`($sp)
- $POP r28,`$FRAME-$SIZE_T*4`($sp)
- $POP r29,`$FRAME-$SIZE_T*3`($sp)
- $POP r30,`$FRAME-$SIZE_T*2`($sp)
- $POP r31,`$FRAME-$SIZE_T*1`($sp)
- mtlr r0
- addi $sp,$sp,`$FRAME+64`
- blr
-___
+ b Ldone
-# PowerPC specification allows an implementation to be ill-behaved
-# upon unaligned access which crosses page boundary. "Better safe
-# than sorry" principle makes me treat it specially. But I don't
-# look for particular offending word, but rather for 64-byte input
-# block which crosses the boundary. Once found that block is aligned
-# and hashed separately...
-$code.=<<___;
+; PowerPC specification allows an implementation to be ill-behaved
+; upon unaligned access which crosses page boundary. "Better safe
+; than sorry" principle makes me treat it specially. But I don't
+; look for particular offending word, but rather for 64-byte input
+; block which crosses the boundary. Once found that block is aligned
+; and hashed separately...
.align 4
Lunaligned:
subfic $t1,$inp,4096
@@ -237,7 +217,7 @@ Lunaligned:
Lcross_page:
li $t1,16
mtctr $t1
- addi r20,$sp,$FRAME ; spot below the frame
+ addi r20,$sp,$LOCALS ; spot within the frame
Lmemcpy:
lbz r16,0($inp)
lbz r17,1($inp)
@@ -251,15 +231,40 @@ Lmemcpy:
addi r20,r20,4
bdnz Lmemcpy
- $PUSH $inp,`$FRAME-$SIZE_T*19`($sp)
+ $PUSH $inp,`$FRAME-$SIZE_T*18`($sp)
li $t1,1
- addi $inp,$sp,$FRAME
+ addi $inp,$sp,$LOCALS
mtctr $t1
bl Lsha1_block_private
- $POP $inp,`$FRAME-$SIZE_T*19`($sp)
+ $POP $inp,`$FRAME-$SIZE_T*18`($sp)
addic. $num,$num,-1
bne- Lunaligned
- b Ldone
+
+Ldone:
+ $POP r0,`$FRAME+$LRSAVE`($sp)
+ $POP r15,`$FRAME-$SIZE_T*17`($sp)
+ $POP r16,`$FRAME-$SIZE_T*16`($sp)
+ $POP r17,`$FRAME-$SIZE_T*15`($sp)
+ $POP r18,`$FRAME-$SIZE_T*14`($sp)
+ $POP r19,`$FRAME-$SIZE_T*13`($sp)
+ $POP r20,`$FRAME-$SIZE_T*12`($sp)
+ $POP r21,`$FRAME-$SIZE_T*11`($sp)
+ $POP r22,`$FRAME-$SIZE_T*10`($sp)
+ $POP r23,`$FRAME-$SIZE_T*9`($sp)
+ $POP r24,`$FRAME-$SIZE_T*8`($sp)
+ $POP r25,`$FRAME-$SIZE_T*7`($sp)
+ $POP r26,`$FRAME-$SIZE_T*6`($sp)
+ $POP r27,`$FRAME-$SIZE_T*5`($sp)
+ $POP r28,`$FRAME-$SIZE_T*4`($sp)
+ $POP r29,`$FRAME-$SIZE_T*3`($sp)
+ $POP r30,`$FRAME-$SIZE_T*2`($sp)
+ $POP r31,`$FRAME-$SIZE_T*1`($sp)
+ mtlr r0
+ addi $sp,$sp,$FRAME
+ blr
+ .long 0
+ .byte 0,12,4,1,0x80,18,3,0
+ .long 0
___
# This is private block function, which uses tailored calling
@@ -309,6 +314,8 @@ $code.=<<___;
addi $inp,$inp,`16*4`
bdnz- Lsha1_block_private
blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
___
$code.=<<___;
.asciz "SHA1 block transform for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha1-s390x.pl b/deps/openssl/openssl/crypto/sha/asm/sha1-s390x.pl
index 4b1784828..9193dda45 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha1-s390x.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha1-s390x.pl
@@ -21,9 +21,28 @@
# instructions to favour dual-issue z10 pipeline. On z10 hardware is
# "only" ~2.3x faster than software.
+# November 2010.
+#
+# Adapt for -m31 build. If kernel supports what's called "highgprs"
+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
+# instructions and achieve "64-bit" performance even in 31-bit legacy
+# application context. The feature is not specific to any particular
+# processor, as long as it's "z-CPU". Latter implies that the code
+# remains z/Architecture specific.
+
$kimdfunc=1; # magic function code for kimd instruction
-$output=shift;
+$flavour = shift;
+
+if ($flavour =~ /3[12]/) {
+ $SIZE_T=4;
+ $g="";
+} else {
+ $SIZE_T=8;
+ $g="g";
+}
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
$K_00_39="%r0"; $K=$K_00_39;
@@ -42,13 +61,14 @@ $t1="%r11";
@X=("%r12","%r13","%r14");
$sp="%r15";
-$frame=160+16*4;
+$stdframe=16*$SIZE_T+4*8;
+$frame=$stdframe+16*4;
sub Xupdate {
my $i=shift;
$code.=<<___ if ($i==15);
- lg $prefetch,160($sp) ### Xupdate(16) warm-up
+ lg $prefetch,$stdframe($sp) ### Xupdate(16) warm-up
lr $X[0],$X[2]
___
return if ($i&1); # Xupdate is vectorized and executed every 2nd cycle
@@ -58,8 +78,8 @@ $code.=<<___ if ($i<16);
___
$code.=<<___ if ($i>=16);
xgr $X[0],$prefetch ### Xupdate($i)
- lg $prefetch,`160+4*(($i+2)%16)`($sp)
- xg $X[0],`160+4*(($i+8)%16)`($sp)
+ lg $prefetch,`$stdframe+4*(($i+2)%16)`($sp)
+ xg $X[0],`$stdframe+4*(($i+8)%16)`($sp)
xgr $X[0],$prefetch
rll $X[0],$X[0],1
rllg $X[1],$X[0],32
@@ -68,7 +88,7 @@ $code.=<<___ if ($i>=16);
lr $X[2],$X[1] # feedback
___
$code.=<<___ if ($i<=70);
- stg $X[0],`160+4*($i%16)`($sp)
+ stg $X[0],`$stdframe+4*($i%16)`($sp)
___
unshift(@X,pop(@X));
}
@@ -148,9 +168,9 @@ $code.=<<___ if ($kimdfunc);
tmhl %r0,0x4000 # check for message-security assist
jz .Lsoftware
lghi %r0,0
- la %r1,16($sp)
+ la %r1,`2*$SIZE_T`($sp)
.long 0xb93e0002 # kimd %r0,%r2
- lg %r0,16($sp)
+ lg %r0,`2*$SIZE_T`($sp)
tmhh %r0,`0x8000>>$kimdfunc`
jz .Lsoftware
lghi %r0,$kimdfunc
@@ -165,11 +185,11 @@ $code.=<<___ if ($kimdfunc);
___
$code.=<<___;
lghi %r1,-$frame
- stg $ctx,16($sp)
- stmg %r6,%r15,48($sp)
+ st${g} $ctx,`2*$SIZE_T`($sp)
+ stm${g} %r6,%r15,`6*$SIZE_T`($sp)
lgr %r0,$sp
la $sp,0(%r1,$sp)
- stg %r0,0($sp)
+ st${g} %r0,0($sp)
larl $t0,Ktable
llgf $A,0($ctx)
@@ -199,7 +219,7 @@ ___
for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
$code.=<<___;
- lg $ctx,`$frame+16`($sp)
+ l${g} $ctx,`$frame+2*$SIZE_T`($sp)
la $inp,64($inp)
al $A,0($ctx)
al $B,4($ctx)
@@ -211,13 +231,13 @@ $code.=<<___;
st $C,8($ctx)
st $D,12($ctx)
st $E,16($ctx)
- brct $len,.Lloop
+ brct${g} $len,.Lloop
- lmg %r6,%r15,`$frame+48`($sp)
+ lm${g} %r6,%r15,`$frame+6*$SIZE_T`($sp)
br %r14
.size sha1_block_data_order,.-sha1_block_data_order
.string "SHA1 block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
-.comm OPENSSL_s390xcap_P,8,8
+.comm OPENSSL_s390xcap_P,16,8
___
$code =~ s/\`([^\`]*)\`/eval $1/gem;
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha1-sparcv9a.pl b/deps/openssl/openssl/crypto/sha/asm/sha1-sparcv9a.pl
index 85e8d6808..e65291bbd 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha1-sparcv9a.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha1-sparcv9a.pl
@@ -549,7 +549,7 @@ ___
# programmer detect if current CPU is VIS capable at run-time.
sub unvis {
my ($mnemonic,$rs1,$rs2,$rd)=@_;
-my $ref,$opf;
+my ($ref,$opf);
my %visopf = ( "fmul8ulx16" => 0x037,
"faligndata" => 0x048,
"fpadd32" => 0x052,
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha1-x86_64.pl b/deps/openssl/openssl/crypto/sha/asm/sha1-x86_64.pl
index 4edc5ea9a..cfdc45cce 100755
--- a/deps/openssl/openssl/crypto/sha/asm/sha1-x86_64.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha1-x86_64.pl
@@ -16,7 +16,7 @@
# There was suggestion to mechanically translate 32-bit code, but I
# dismissed it, reasoning that x86_64 offers enough register bank
# capacity to fully utilize SHA-1 parallelism. Therefore this fresh
-# implementation:-) However! While 64-bit code does performs better
+# implementation:-) However! While 64-bit code does perform better
# on Opteron, I failed to beat 32-bit assembler on EM64T core. Well,
# x86_64 does offer larger *addressable* bank, but out-of-order core
# reaches for even more registers through dynamic aliasing, and EM64T
@@ -29,6 +29,38 @@
# Xeon P4 +65% +0% 9.9
# Core2 +60% +10% 7.0
+# August 2009.
+#
+# The code was revised to minimize code size and to maximize
+# "distance" between instructions producing input to 'lea'
+# instruction and the 'lea' instruction itself, which is essential
+# for Intel Atom core.
+
+# October 2010.
+#
+# Add SSSE3, Supplemental[!] SSE3, implementation. The idea behind it
+# is to offload message schedule denoted by Wt in NIST specification,
+# or Xupdate in OpenSSL source, to SIMD unit. See sha1-586.pl module
+# for background and implementation details. The only difference from
+# 32-bit code is that 64-bit code doesn't have to spill @X[] elements
+# to free temporary registers.
+
+# April 2011.
+#
+# Add AVX code path. See sha1-586.pl for further information.
+
+######################################################################
+# Current performance is summarized in following table. Numbers are
+# CPU clock cycles spent to process single byte (less is better).
+#
+# x86_64 SSSE3 AVX
+# P4 9.8 -
+# Opteron 6.6 -
+# Core2 6.7 6.1/+10% -
+# Atom 11.0 9.7/+13% -
+# Westmere 7.1 5.6/+27% -
+# Sandy Bridge 7.9 6.3/+25% 5.2/+51%
+
$flavour = shift;
$output = shift;
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
@@ -40,7 +72,18 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-open STDOUT,"| $^X $xlate $flavour $output";
+$avx=1 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
+ =~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
+ $1>=2.19);
+$avx=1 if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
+ `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
+ $1>=2.09);
+$avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
+ `ml64 2>&1` =~ /Version ([0-9]+)\./ &&
+ $1>=10);
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
$ctx="%rdi"; # 1st arg
$inp="%rsi"; # 2nd arg
@@ -51,196 +94,994 @@ $ctx="%r8";
$inp="%r9";
$num="%r10";
-$xi="%eax";
-$t0="%ebx";
-$t1="%ecx";
-$A="%edx";
-$B="%esi";
-$C="%edi";
-$D="%ebp";
-$E="%r11d";
-$T="%r12d";
-
-@V=($A,$B,$C,$D,$E,$T);
+$t0="%eax";
+$t1="%ebx";
+$t2="%ecx";
+@xi=("%edx","%ebp");
+$A="%esi";
+$B="%edi";
+$C="%r11d";
+$D="%r12d";
+$E="%r13d";
-sub PROLOGUE {
-my $func=shift;
-$code.=<<___;
-.globl $func
-.type $func,\@function,3
-.align 16
-$func:
- push %rbx
- push %rbp
- push %r12
- mov %rsp,%r11
- mov %rdi,$ctx # reassigned argument
- sub \$`8+16*4`,%rsp
- mov %rsi,$inp # reassigned argument
- and \$-64,%rsp
- mov %rdx,$num # reassigned argument
- mov %r11,`16*4`(%rsp)
-.Lprologue:
-
- mov 0($ctx),$A
- mov 4($ctx),$B
- mov 8($ctx),$C
- mov 12($ctx),$D
- mov 16($ctx),$E
-___
-}
-
-sub EPILOGUE {
-my $func=shift;
-$code.=<<___;
- mov `16*4`(%rsp),%rsi
- mov (%rsi),%r12
- mov 8(%rsi),%rbp
- mov 16(%rsi),%rbx
- lea 24(%rsi),%rsp
-.Lepilogue:
- ret
-.size $func,.-$func
-___
-}
+@V=($A,$B,$C,$D,$E);
sub BODY_00_19 {
-my ($i,$a,$b,$c,$d,$e,$f,$host)=@_;
+my ($i,$a,$b,$c,$d,$e)=@_;
my $j=$i+1;
$code.=<<___ if ($i==0);
- mov `4*$i`($inp),$xi
- `"bswap $xi" if(!defined($host))`
- mov $xi,`4*$i`(%rsp)
+ mov `4*$i`($inp),$xi[0]
+ bswap $xi[0]
+ mov $xi[0],`4*$i`(%rsp)
___
$code.=<<___ if ($i<15);
- lea 0x5a827999($xi,$e),$f
mov $c,$t0
- mov `4*$j`($inp),$xi
- mov $a,$e
+ mov `4*$j`($inp),$xi[1]
+ mov $a,$t2
xor $d,$t0
- `"bswap $xi" if(!defined($host))`
- rol \$5,$e
+ bswap $xi[1]
+ rol \$5,$t2
+ lea 0x5a827999($xi[0],$e),$e
and $b,$t0
- mov $xi,`4*$j`(%rsp)
- add $e,$f
+ mov $xi[1],`4*$j`(%rsp)
+ add $t2,$e
xor $d,$t0
rol \$30,$b
- add $t0,$f
+ add $t0,$e
___
$code.=<<___ if ($i>=15);
- lea 0x5a827999($xi,$e),$f
- mov `4*($j%16)`(%rsp),$xi
+ mov `4*($j%16)`(%rsp),$xi[1]
mov $c,$t0
- mov $a,$e
- xor `4*(($j+2)%16)`(%rsp),$xi
+ mov $a,$t2
+ xor `4*(($j+2)%16)`(%rsp),$xi[1]
xor $d,$t0
- rol \$5,$e
- xor `4*(($j+8)%16)`(%rsp),$xi
+ rol \$5,$t2
+ xor `4*(($j+8)%16)`(%rsp),$xi[1]
and $b,$t0
- add $e,$f
- xor `4*(($j+13)%16)`(%rsp),$xi
+ lea 0x5a827999($xi[0],$e),$e
+ xor `4*(($j+13)%16)`(%rsp),$xi[1]
xor $d,$t0
+ rol \$1,$xi[1]
+ add $t2,$e
rol \$30,$b
- add $t0,$f
- rol \$1,$xi
- mov $xi,`4*($j%16)`(%rsp)
+ mov $xi[1],`4*($j%16)`(%rsp)
+ add $t0,$e
___
+unshift(@xi,pop(@xi));
}
sub BODY_20_39 {
-my ($i,$a,$b,$c,$d,$e,$f)=@_;
+my ($i,$a,$b,$c,$d,$e)=@_;
my $j=$i+1;
my $K=($i<40)?0x6ed9eba1:0xca62c1d6;
$code.=<<___ if ($i<79);
- lea $K($xi,$e),$f
- mov `4*($j%16)`(%rsp),$xi
+ mov `4*($j%16)`(%rsp),$xi[1]
mov $c,$t0
- mov $a,$e
- xor `4*(($j+2)%16)`(%rsp),$xi
+ mov $a,$t2
+ xor `4*(($j+2)%16)`(%rsp),$xi[1]
xor $b,$t0
- rol \$5,$e
- xor `4*(($j+8)%16)`(%rsp),$xi
+ rol \$5,$t2
+ lea $K($xi[0],$e),$e
+ xor `4*(($j+8)%16)`(%rsp),$xi[1]
xor $d,$t0
- add $e,$f
- xor `4*(($j+13)%16)`(%rsp),$xi
+ add $t2,$e
+ xor `4*(($j+13)%16)`(%rsp),$xi[1]
rol \$30,$b
- add $t0,$f
- rol \$1,$xi
+ add $t0,$e
+ rol \$1,$xi[1]
___
$code.=<<___ if ($i<76);
- mov $xi,`4*($j%16)`(%rsp)
+ mov $xi[1],`4*($j%16)`(%rsp)
___
$code.=<<___ if ($i==79);
- lea $K($xi,$e),$f
mov $c,$t0
- mov $a,$e
+ mov $a,$t2
xor $b,$t0
- rol \$5,$e
+ lea $K($xi[0],$e),$e
+ rol \$5,$t2
xor $d,$t0
- add $e,$f
+ add $t2,$e
rol \$30,$b
- add $t0,$f
+ add $t0,$e
___
+unshift(@xi,pop(@xi));
}
sub BODY_40_59 {
-my ($i,$a,$b,$c,$d,$e,$f)=@_;
+my ($i,$a,$b,$c,$d,$e)=@_;
my $j=$i+1;
$code.=<<___;
- lea 0x8f1bbcdc($xi,$e),$f
- mov `4*($j%16)`(%rsp),$xi
- mov $b,$t0
- mov $b,$t1
- xor `4*(($j+2)%16)`(%rsp),$xi
- mov $a,$e
- and $c,$t0
- xor `4*(($j+8)%16)`(%rsp),$xi
- or $c,$t1
- rol \$5,$e
- xor `4*(($j+13)%16)`(%rsp),$xi
- and $d,$t1
- add $e,$f
- rol \$1,$xi
- or $t1,$t0
+ mov `4*($j%16)`(%rsp),$xi[1]
+ mov $c,$t0
+ mov $c,$t1
+ xor `4*(($j+2)%16)`(%rsp),$xi[1]
+ and $d,$t0
+ mov $a,$t2
+ xor `4*(($j+8)%16)`(%rsp),$xi[1]
+ xor $d,$t1
+ lea 0x8f1bbcdc($xi[0],$e),$e
+ rol \$5,$t2
+ xor `4*(($j+13)%16)`(%rsp),$xi[1]
+ add $t0,$e
+ and $b,$t1
+ rol \$1,$xi[1]
+ add $t1,$e
rol \$30,$b
- mov $xi,`4*($j%16)`(%rsp)
- add $t0,$f
+ mov $xi[1],`4*($j%16)`(%rsp)
+ add $t2,$e
___
+unshift(@xi,pop(@xi));
}
-$code=".text\n";
+$code.=<<___;
+.text
+.extern OPENSSL_ia32cap_P
-&PROLOGUE("sha1_block_data_order");
-$code.=".align 4\n.Lloop:\n";
+.globl sha1_block_data_order
+.type sha1_block_data_order,\@function,3
+.align 16
+sha1_block_data_order:
+ mov OPENSSL_ia32cap_P+0(%rip),%r9d
+ mov OPENSSL_ia32cap_P+4(%rip),%r8d
+ test \$`1<<9`,%r8d # check SSSE3 bit
+ jz .Lialu
+___
+$code.=<<___ if ($avx);
+ and \$`1<<28`,%r8d # mask AVX bit
+ and \$`1<<30`,%r9d # mask "Intel CPU" bit
+ or %r9d,%r8d
+ cmp \$`1<<28|1<<30`,%r8d
+ je _avx_shortcut
+___
+$code.=<<___;
+ jmp _ssse3_shortcut
+
+.align 16
+.Lialu:
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ mov %rsp,%r11
+ mov %rdi,$ctx # reassigned argument
+ sub \$`8+16*4`,%rsp
+ mov %rsi,$inp # reassigned argument
+ and \$-64,%rsp
+ mov %rdx,$num # reassigned argument
+ mov %r11,`16*4`(%rsp)
+.Lprologue:
+
+ mov 0($ctx),$A
+ mov 4($ctx),$B
+ mov 8($ctx),$C
+ mov 12($ctx),$D
+ mov 16($ctx),$E
+ jmp .Lloop
+
+.align 16
+.Lloop:
+___
for($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
for(;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
for(;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
for(;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
$code.=<<___;
- add 0($ctx),$E
- add 4($ctx),$T
- add 8($ctx),$A
- add 12($ctx),$B
- add 16($ctx),$C
- mov $E,0($ctx)
- mov $T,4($ctx)
- mov $A,8($ctx)
- mov $B,12($ctx)
- mov $C,16($ctx)
-
- xchg $E,$A # mov $E,$A
- xchg $T,$B # mov $T,$B
- xchg $E,$C # mov $A,$C
- xchg $T,$D # mov $B,$D
- # mov $C,$E
- lea `16*4`($inp),$inp
+ add 0($ctx),$A
+ add 4($ctx),$B
+ add 8($ctx),$C
+ add 12($ctx),$D
+ add 16($ctx),$E
+ mov $A,0($ctx)
+ mov $B,4($ctx)
+ mov $C,8($ctx)
+ mov $D,12($ctx)
+ mov $E,16($ctx)
+
sub \$1,$num
+ lea `16*4`($inp),$inp
jnz .Lloop
+
+ mov `16*4`(%rsp),%rsi
+ mov (%rsi),%r13
+ mov 8(%rsi),%r12
+ mov 16(%rsi),%rbp
+ mov 24(%rsi),%rbx
+ lea 32(%rsi),%rsp
+.Lepilogue:
+ ret
+.size sha1_block_data_order,.-sha1_block_data_order
___
-&EPILOGUE("sha1_block_data_order");
+{{{
+my $Xi=4;
+my @X=map("%xmm$_",(4..7,0..3));
+my @Tx=map("%xmm$_",(8..10));
+my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp"); # size optimization
+my @T=("%esi","%edi");
+my $j=0;
+my $K_XX_XX="%r11";
+
+my $_rol=sub { &rol(@_) };
+my $_ror=sub { &ror(@_) };
+
+$code.=<<___;
+.type sha1_block_data_order_ssse3,\@function,3
+.align 16
+sha1_block_data_order_ssse3:
+_ssse3_shortcut:
+ push %rbx
+ push %rbp
+ push %r12
+ lea `-64-($win64?5*16:0)`(%rsp),%rsp
+___
+$code.=<<___ if ($win64);
+ movaps %xmm6,64+0(%rsp)
+ movaps %xmm7,64+16(%rsp)
+ movaps %xmm8,64+32(%rsp)
+ movaps %xmm9,64+48(%rsp)
+ movaps %xmm10,64+64(%rsp)
+.Lprologue_ssse3:
+___
+$code.=<<___;
+ mov %rdi,$ctx # reassigned argument
+ mov %rsi,$inp # reassigned argument
+ mov %rdx,$num # reassigned argument
+
+ shl \$6,$num
+ add $inp,$num
+ lea K_XX_XX(%rip),$K_XX_XX
+
+ mov 0($ctx),$A # load context
+ mov 4($ctx),$B
+ mov 8($ctx),$C
+ mov 12($ctx),$D
+ mov $B,@T[0] # magic seed
+ mov 16($ctx),$E
+
+ movdqa 64($K_XX_XX),@X[2] # pbswap mask
+ movdqa 0($K_XX_XX),@Tx[1] # K_00_19
+ movdqu 0($inp),@X[-4&7] # load input to %xmm[0-3]
+ movdqu 16($inp),@X[-3&7]
+ movdqu 32($inp),@X[-2&7]
+ movdqu 48($inp),@X[-1&7]
+ pshufb @X[2],@X[-4&7] # byte swap
+ add \$64,$inp
+ pshufb @X[2],@X[-3&7]
+ pshufb @X[2],@X[-2&7]
+ pshufb @X[2],@X[-1&7]
+ paddd @Tx[1],@X[-4&7] # add K_00_19
+ paddd @Tx[1],@X[-3&7]
+ paddd @Tx[1],@X[-2&7]
+ movdqa @X[-4&7],0(%rsp) # X[]+K xfer to IALU
+ psubd @Tx[1],@X[-4&7] # restore X[]
+ movdqa @X[-3&7],16(%rsp)
+ psubd @Tx[1],@X[-3&7]
+ movdqa @X[-2&7],32(%rsp)
+ psubd @Tx[1],@X[-2&7]
+ jmp .Loop_ssse3
+___
+
+sub AUTOLOAD() # thunk [simplified] 32-bit style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
+ my $arg = pop;
+ $arg = "\$$arg" if ($arg*1 eq $arg);
+ $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
+}
+
+sub Xupdate_ssse3_16_31() # recall that $Xi starts wtih 4
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 40 instructions
+ my ($a,$b,$c,$d,$e);
+
+ &movdqa (@X[0],@X[-3&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (@Tx[0],@X[-1&7]);
+ &palignr(@X[0],@X[-4&7],8); # compose "X[-14]" in "X[0]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &paddd (@Tx[1],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &psrldq (@Tx[0],4); # "X[-3]", 3 dwords
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &pxor (@X[0],@X[-4&7]); # "X[0]"^="X[-16]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pxor (@Tx[0],@X[-2&7]); # "X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pxor (@X[0],@Tx[0]); # "X[0]"^="X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &movdqa (@Tx[2],@X[0]);
+ &movdqa (@Tx[0],@X[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pslldq (@Tx[2],12); # "X[0]"<<96, extract one dword
+ &paddd (@X[0],@X[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &psrld (@Tx[0],31);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (@Tx[1],@Tx[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &psrld (@Tx[2],30);
+ &por (@X[0],@Tx[0]); # "X[0]"<<<=1
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pslld (@Tx[1],2);
+ &pxor (@X[0],@Tx[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)"); # K_XX_XX
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &pxor (@X[0],@Tx[1]); # "X[0]"^=("X[0]">>96)<<<2
+
+ foreach (@insns) { eval; } # remaining instructions [if any]
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+ push(@Tx,shift(@Tx));
+}
+
+sub Xupdate_ssse3_32_79()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions
+ my ($a,$b,$c,$d,$e);
+
+ &movdqa (@Tx[0],@X[-1&7]) if ($Xi==8);
+ eval(shift(@insns)); # body_20_39
+ &pxor (@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]"
+ &palignr(@Tx[0],@X[-2&7],8); # compose "X[-6]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &pxor (@X[0],@X[-7&7]); # "X[0]"^="X[-28]"
+ eval(shift(@insns));
+ eval(shift(@insns)) if (@insns[0] !~ /&ro[rl]/);
+ if ($Xi%5) {
+ &movdqa (@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX...
+ } else { # ... or load next one
+ &movdqa (@Tx[2],eval(16*($Xi/5))."($K_XX_XX)");
+ }
+ &paddd (@Tx[1],@X[-1&7]);
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &pxor (@X[0],@Tx[0]); # "X[0]"^="X[-6]"
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &movdqa (@Tx[0],@X[0]);
+ &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &pslld (@X[0],2);
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ &psrld (@Tx[0],30);
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &por (@X[0],@Tx[0]); # "X[0]"<<<=2
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ &movdqa (@Tx[1],@X[0]) if ($Xi<19);
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+ push(@Tx,shift(@Tx));
+}
+
+sub Xuplast_ssse3_80()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ &paddd (@Tx[1],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer IALU
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ &cmp ($inp,$num);
+ &je (".Ldone_ssse3");
+
+ unshift(@Tx,pop(@Tx));
+
+ &movdqa (@X[2],"64($K_XX_XX)"); # pbswap mask
+ &movdqa (@Tx[1],"0($K_XX_XX)"); # K_00_19
+ &movdqu (@X[-4&7],"0($inp)"); # load input
+ &movdqu (@X[-3&7],"16($inp)");
+ &movdqu (@X[-2&7],"32($inp)");
+ &movdqu (@X[-1&7],"48($inp)");
+ &pshufb (@X[-4&7],@X[2]); # byte swap
+ &add ($inp,64);
+
+ $Xi=0;
+}
+
+sub Xloop_ssse3()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &pshufb (@X[($Xi-3)&7],@X[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &paddd (@X[($Xi-4)&7],@Tx[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &movdqa (eval(16*$Xi)."(%rsp)",@X[($Xi-4)&7]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &psubd (@X[($Xi-4)&7],@Tx[1]);
+
+ foreach (@insns) { eval; }
+ $Xi++;
+}
+
+sub Xtail_ssse3()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ foreach (@insns) { eval; }
+}
+
+sub body_00_19 () {
+ (
+ '($a,$b,$c,$d,$e)=@V;'.
+ '&add ($e,eval(4*($j&15))."(%rsp)");', # X[]+K xfer
+ '&xor ($c,$d);',
+ '&mov (@T[1],$a);', # $b in next round
+ '&$_rol ($a,5);',
+ '&and (@T[0],$c);', # ($b&($c^$d))
+ '&xor ($c,$d);', # restore $c
+ '&xor (@T[0],$d);',
+ '&add ($e,$a);',
+ '&$_ror ($b,$j?7:2);', # $b>>>2
+ '&add ($e,@T[0]);' .'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+ );
+}
+
+sub body_20_39 () {
+ (
+ '($a,$b,$c,$d,$e)=@V;'.
+ '&add ($e,eval(4*($j++&15))."(%rsp)");', # X[]+K xfer
+ '&xor (@T[0],$d);', # ($b^$d)
+ '&mov (@T[1],$a);', # $b in next round
+ '&$_rol ($a,5);',
+ '&xor (@T[0],$c);', # ($b^$d^$c)
+ '&add ($e,$a);',
+ '&$_ror ($b,7);', # $b>>>2
+ '&add ($e,@T[0]);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+ );
+}
+
+sub body_40_59 () {
+ (
+ '($a,$b,$c,$d,$e)=@V;'.
+ '&mov (@T[1],$c);',
+ '&xor ($c,$d);',
+ '&add ($e,eval(4*($j++&15))."(%rsp)");', # X[]+K xfer
+ '&and (@T[1],$d);',
+ '&and (@T[0],$c);', # ($b&($c^$d))
+ '&$_ror ($b,7);', # $b>>>2
+ '&add ($e,@T[1]);',
+ '&mov (@T[1],$a);', # $b in next round
+ '&$_rol ($a,5);',
+ '&add ($e,@T[0]);',
+ '&xor ($c,$d);', # restore $c
+ '&add ($e,$a);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+ );
+}
$code.=<<___;
-.asciz "SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
.align 16
+.Loop_ssse3:
+___
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_16_31(\&body_00_19);
+ &Xupdate_ssse3_32_79(\&body_00_19);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_40_59);
+ &Xupdate_ssse3_32_79(\&body_20_39);
+ &Xuplast_ssse3_80(\&body_20_39); # can jump to "done"
+
+ $saved_j=$j; @saved_V=@V;
+
+ &Xloop_ssse3(\&body_20_39);
+ &Xloop_ssse3(\&body_20_39);
+ &Xloop_ssse3(\&body_20_39);
+
+$code.=<<___;
+ add 0($ctx),$A # update context
+ add 4($ctx),@T[0]
+ add 8($ctx),$C
+ add 12($ctx),$D
+ mov $A,0($ctx)
+ add 16($ctx),$E
+ mov @T[0],4($ctx)
+ mov @T[0],$B # magic seed
+ mov $C,8($ctx)
+ mov $D,12($ctx)
+ mov $E,16($ctx)
+ jmp .Loop_ssse3
+
+.align 16
+.Ldone_ssse3:
+___
+ $j=$saved_j; @V=@saved_V;
+
+ &Xtail_ssse3(\&body_20_39);
+ &Xtail_ssse3(\&body_20_39);
+ &Xtail_ssse3(\&body_20_39);
+
+$code.=<<___;
+ add 0($ctx),$A # update context
+ add 4($ctx),@T[0]
+ add 8($ctx),$C
+ mov $A,0($ctx)
+ add 12($ctx),$D
+ mov @T[0],4($ctx)
+ add 16($ctx),$E
+ mov $C,8($ctx)
+ mov $D,12($ctx)
+ mov $E,16($ctx)
+___
+$code.=<<___ if ($win64);
+ movaps 64+0(%rsp),%xmm6
+ movaps 64+16(%rsp),%xmm7
+ movaps 64+32(%rsp),%xmm8
+ movaps 64+48(%rsp),%xmm9
+ movaps 64+64(%rsp),%xmm10
+___
+$code.=<<___;
+ lea `64+($win64?5*16:0)`(%rsp),%rsi
+ mov 0(%rsi),%r12
+ mov 8(%rsi),%rbp
+ mov 16(%rsi),%rbx
+ lea 24(%rsi),%rsp
+.Lepilogue_ssse3:
+ ret
+.size sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3
+___
+
+if ($avx) {
+my $Xi=4;
+my @X=map("%xmm$_",(4..7,0..3));
+my @Tx=map("%xmm$_",(8..10));
+my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp"); # size optimization
+my @T=("%esi","%edi");
+my $j=0;
+my $K_XX_XX="%r11";
+
+my $_rol=sub { &shld(@_[0],@_) };
+my $_ror=sub { &shrd(@_[0],@_) };
+
+$code.=<<___;
+.type sha1_block_data_order_avx,\@function,3
+.align 16
+sha1_block_data_order_avx:
+_avx_shortcut:
+ push %rbx
+ push %rbp
+ push %r12
+ lea `-64-($win64?5*16:0)`(%rsp),%rsp
+___
+$code.=<<___ if ($win64);
+ movaps %xmm6,64+0(%rsp)
+ movaps %xmm7,64+16(%rsp)
+ movaps %xmm8,64+32(%rsp)
+ movaps %xmm9,64+48(%rsp)
+ movaps %xmm10,64+64(%rsp)
+.Lprologue_avx:
+___
+$code.=<<___;
+ mov %rdi,$ctx # reassigned argument
+ mov %rsi,$inp # reassigned argument
+ mov %rdx,$num # reassigned argument
+ vzeroall
+
+ shl \$6,$num
+ add $inp,$num
+ lea K_XX_XX(%rip),$K_XX_XX
+
+ mov 0($ctx),$A # load context
+ mov 4($ctx),$B
+ mov 8($ctx),$C
+ mov 12($ctx),$D
+ mov $B,@T[0] # magic seed
+ mov 16($ctx),$E
+
+ vmovdqa 64($K_XX_XX),@X[2] # pbswap mask
+ vmovdqa 0($K_XX_XX),@Tx[1] # K_00_19
+ vmovdqu 0($inp),@X[-4&7] # load input to %xmm[0-3]
+ vmovdqu 16($inp),@X[-3&7]
+ vmovdqu 32($inp),@X[-2&7]
+ vmovdqu 48($inp),@X[-1&7]
+ vpshufb @X[2],@X[-4&7],@X[-4&7] # byte swap
+ add \$64,$inp
+ vpshufb @X[2],@X[-3&7],@X[-3&7]
+ vpshufb @X[2],@X[-2&7],@X[-2&7]
+ vpshufb @X[2],@X[-1&7],@X[-1&7]
+ vpaddd @Tx[1],@X[-4&7],@X[0] # add K_00_19
+ vpaddd @Tx[1],@X[-3&7],@X[1]
+ vpaddd @Tx[1],@X[-2&7],@X[2]
+ vmovdqa @X[0],0(%rsp) # X[]+K xfer to IALU
+ vmovdqa @X[1],16(%rsp)
+ vmovdqa @X[2],32(%rsp)
+ jmp .Loop_avx
+___
+
+sub Xupdate_avx_16_31() # recall that $Xi starts wtih 4
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 40 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpalignr(@X[0],@X[-3&7],@X[-4&7],8); # compose "X[-14]" in "X[0]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpaddd (@Tx[1],@Tx[1],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpsrldq(@Tx[0],@X[-1&7],4); # "X[-3]", 3 dwords
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"^="X[-16]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpxor (@Tx[0],@Tx[0],@X[-2&7]); # "X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpxor (@X[0],@X[0],@Tx[0]); # "X[0]"^="X[-3]"^"X[-8]"
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vmovdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpsrld (@Tx[0],@X[0],31);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpslldq(@Tx[2],@X[0],12); # "X[0]"<<96, extract one dword
+ &vpaddd (@X[0],@X[0],@X[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpsrld (@Tx[1],@Tx[2],30);
+ &vpor (@X[0],@X[0],@Tx[0]); # "X[0]"<<<=1
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpslld (@Tx[2],@Tx[2],2);
+ &vpxor (@X[0],@X[0],@Tx[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &vpxor (@X[0],@X[0],@Tx[2]); # "X[0]"^=("X[0]">>96)<<<2
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vmovdqa (@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)"); # K_XX_XX
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+
+ foreach (@insns) { eval; } # remaining instructions [if any]
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+ push(@Tx,shift(@Tx));
+}
+
+sub Xupdate_avx_32_79()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions
+ my ($a,$b,$c,$d,$e);
+
+ &vpalignr(@Tx[0],@X[-1&7],@X[-2&7],8); # compose "X[-6]"
+ &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]"
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &vpxor (@X[0],@X[0],@X[-7&7]); # "X[0]"^="X[-28]"
+ eval(shift(@insns));
+ eval(shift(@insns)) if (@insns[0] !~ /&ro[rl]/);
+ if ($Xi%5) {
+ &vmovdqa (@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX...
+ } else { # ... or load next one
+ &vmovdqa (@Tx[2],eval(16*($Xi/5))."($K_XX_XX)");
+ }
+ &vpaddd (@Tx[1],@Tx[1],@X[-1&7]);
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &vpxor (@X[0],@X[0],@Tx[0]); # "X[0]"^="X[-6]"
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+
+ &vpsrld (@Tx[0],@X[0],30);
+ &vmovdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &vpslld (@X[0],@X[0],2);
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # ror
+ eval(shift(@insns));
+
+ &vpor (@X[0],@X[0],@Tx[0]); # "X[0]"<<<=2
+ eval(shift(@insns)); # body_20_39
+ eval(shift(@insns));
+ &vmovdqa (@Tx[1],@X[0]) if ($Xi<19);
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns)); # rol
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ $Xi++; push(@X,shift(@X)); # "rotate" X[]
+ push(@Tx,shift(@Tx));
+}
+
+sub Xuplast_avx_80()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ &vpaddd (@Tx[1],@Tx[1],@X[-1&7]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer IALU
+
+ foreach (@insns) { eval; } # remaining instructions
+
+ &cmp ($inp,$num);
+ &je (".Ldone_avx");
+
+ unshift(@Tx,pop(@Tx));
+
+ &vmovdqa(@X[2],"64($K_XX_XX)"); # pbswap mask
+ &vmovdqa(@Tx[1],"0($K_XX_XX)"); # K_00_19
+ &vmovdqu(@X[-4&7],"0($inp)"); # load input
+ &vmovdqu(@X[-3&7],"16($inp)");
+ &vmovdqu(@X[-2&7],"32($inp)");
+ &vmovdqu(@X[-1&7],"48($inp)");
+ &vpshufb(@X[-4&7],@X[-4&7],@X[2]); # byte swap
+ &add ($inp,64);
+
+ $Xi=0;
+}
+
+sub Xloop_avx()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpshufb(@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vpaddd (@X[$Xi&7],@X[($Xi-4)&7],@Tx[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vmovdqa(eval(16*$Xi)."(%rsp)",@X[$Xi&7]); # X[]+K xfer to IALU
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ foreach (@insns) { eval; }
+ $Xi++;
+}
+
+sub Xtail_avx()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body); # 32 instructions
+ my ($a,$b,$c,$d,$e);
+
+ foreach (@insns) { eval; }
+}
+
+$code.=<<___;
+.align 16
+.Loop_avx:
+___
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_16_31(\&body_00_19);
+ &Xupdate_avx_32_79(\&body_00_19);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_40_59);
+ &Xupdate_avx_32_79(\&body_20_39);
+ &Xuplast_avx_80(\&body_20_39); # can jump to "done"
+
+ $saved_j=$j; @saved_V=@V;
+
+ &Xloop_avx(\&body_20_39);
+ &Xloop_avx(\&body_20_39);
+ &Xloop_avx(\&body_20_39);
+
+$code.=<<___;
+ add 0($ctx),$A # update context
+ add 4($ctx),@T[0]
+ add 8($ctx),$C
+ add 12($ctx),$D
+ mov $A,0($ctx)
+ add 16($ctx),$E
+ mov @T[0],4($ctx)
+ mov @T[0],$B # magic seed
+ mov $C,8($ctx)
+ mov $D,12($ctx)
+ mov $E,16($ctx)
+ jmp .Loop_avx
+
+.align 16
+.Ldone_avx:
+___
+ $j=$saved_j; @V=@saved_V;
+
+ &Xtail_avx(\&body_20_39);
+ &Xtail_avx(\&body_20_39);
+ &Xtail_avx(\&body_20_39);
+
+$code.=<<___;
+ vzeroall
+
+ add 0($ctx),$A # update context
+ add 4($ctx),@T[0]
+ add 8($ctx),$C
+ mov $A,0($ctx)
+ add 12($ctx),$D
+ mov @T[0],4($ctx)
+ add 16($ctx),$E
+ mov $C,8($ctx)
+ mov $D,12($ctx)
+ mov $E,16($ctx)
+___
+$code.=<<___ if ($win64);
+ movaps 64+0(%rsp),%xmm6
+ movaps 64+16(%rsp),%xmm7
+ movaps 64+32(%rsp),%xmm8
+ movaps 64+48(%rsp),%xmm9
+ movaps 64+64(%rsp),%xmm10
+___
+$code.=<<___;
+ lea `64+($win64?5*16:0)`(%rsp),%rsi
+ mov 0(%rsi),%r12
+ mov 8(%rsi),%rbp
+ mov 16(%rsi),%rbx
+ lea 24(%rsi),%rsp
+.Lepilogue_avx:
+ ret
+.size sha1_block_data_order_avx,.-sha1_block_data_order_avx
+___
+}
+$code.=<<___;
+.align 64
+K_XX_XX:
+.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 # K_00_19
+.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 # K_20_39
+.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc # K_40_59
+.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 # K_60_79
+.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f # pbswap mask
+___
+}}}
+$code.=<<___;
+.asciz "SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align 64
___
# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
@@ -272,25 +1113,75 @@ se_handler:
lea .Lprologue(%rip),%r10
cmp %r10,%rbx # context->Rip<.Lprologue
- jb .Lin_prologue
+ jb .Lcommon_seh_tail
mov 152($context),%rax # pull context->Rsp
lea .Lepilogue(%rip),%r10
cmp %r10,%rbx # context->Rip>=.Lepilogue
- jae .Lin_prologue
+ jae .Lcommon_seh_tail
mov `16*4`(%rax),%rax # pull saved stack pointer
- lea 24(%rax),%rax
+ lea 32(%rax),%rax
mov -8(%rax),%rbx
mov -16(%rax),%rbp
mov -24(%rax),%r12
+ mov -32(%rax),%r13
mov %rbx,144($context) # restore context->Rbx
mov %rbp,160($context) # restore context->Rbp
mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R13
+
+ jmp .Lcommon_seh_tail
+.size se_handler,.-se_handler
-.Lin_prologue:
+.type ssse3_handler,\@abi-omnipotent
+.align 16
+ssse3_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # prologue label
+ cmp %r10,%rbx # context->Rip<prologue label
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lcommon_seh_tail
+
+ lea 64(%rax),%rsi
+ lea 512($context),%rdi # &context.Xmm6
+ mov \$10,%ecx
+ .long 0xa548f3fc # cld; rep movsq
+ lea `24+64+5*16`(%rax),%rax # adjust stack pointer
+
+ mov -8(%rax),%rbx
+ mov -16(%rax),%rbp
+ mov -24(%rax),%r12
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %r12,216($context) # restore cotnext->R12
+
+.Lcommon_seh_tail:
mov 8(%rax),%rdi
mov 16(%rax),%rsi
mov %rax,152($context) # restore context->Rsp
@@ -328,19 +1219,38 @@ se_handler:
pop %rdi
pop %rsi
ret
-.size se_handler,.-se_handler
+.size ssse3_handler,.-ssse3_handler
.section .pdata
.align 4
.rva .LSEH_begin_sha1_block_data_order
.rva .LSEH_end_sha1_block_data_order
.rva .LSEH_info_sha1_block_data_order
-
+ .rva .LSEH_begin_sha1_block_data_order_ssse3
+ .rva .LSEH_end_sha1_block_data_order_ssse3
+ .rva .LSEH_info_sha1_block_data_order_ssse3
+___
+$code.=<<___ if ($avx);
+ .rva .LSEH_begin_sha1_block_data_order_avx
+ .rva .LSEH_end_sha1_block_data_order_avx
+ .rva .LSEH_info_sha1_block_data_order_avx
+___
+$code.=<<___;
.section .xdata
.align 8
.LSEH_info_sha1_block_data_order:
.byte 9,0,0,0
.rva se_handler
+.LSEH_info_sha1_block_data_order_ssse3:
+ .byte 9,0,0,0
+ .rva ssse3_handler
+ .rva .Lprologue_ssse3,.Lepilogue_ssse3 # HandlerData[]
+___
+$code.=<<___ if ($avx);
+.LSEH_info_sha1_block_data_order_avx:
+ .byte 9,0,0,0
+ .rva ssse3_handler
+ .rva .Lprologue_avx,.Lepilogue_avx # HandlerData[]
___
}
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha256-586.pl b/deps/openssl/openssl/crypto/sha/asm/sha256-586.pl
index ecc8b69c7..928ec5312 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha256-586.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha256-586.pl
@@ -14,8 +14,8 @@
# Pentium PIII P4 AMD K8 Core2
# gcc 46 36 41 27 26
# icc 57 33 38 25 23
-# x86 asm 40 30 35 20 20
-# x86_64 asm(*) - - 21 15.8 16.5
+# x86 asm 40 30 33 20 18
+# x86_64 asm(*) - - 21 16 16
#
# (*) x86_64 assembler performance is presented for reference
# purposes.
@@ -48,20 +48,19 @@ sub BODY_00_15() {
my $in_16_63=shift;
&mov ("ecx",$E);
- &add ($T,&DWP(4*(8+15+16-9),"esp")) if ($in_16_63); # T += X[-7]
- &ror ("ecx",6);
- &mov ("edi",$E);
- &ror ("edi",11);
+ &add ($T,"edi") if ($in_16_63); # T += sigma1(X[-2])
+ &ror ("ecx",25-11);
&mov ("esi",$Foff);
- &xor ("ecx","edi");
- &ror ("edi",25-11);
+ &xor ("ecx",$E);
+ &ror ("ecx",11-6);
&mov (&DWP(4*(8+15),"esp"),$T) if ($in_16_63); # save X[0]
- &xor ("ecx","edi"); # Sigma1(e)
+ &xor ("ecx",$E);
+ &ror ("ecx",6); # Sigma1(e)
&mov ("edi",$Goff);
&add ($T,"ecx"); # T += Sigma1(e)
- &mov ($Eoff,$E); # modulo-scheduled
&xor ("esi","edi");
+ &mov ($Eoff,$E); # modulo-scheduled
&mov ("ecx",$A);
&and ("esi",$E);
&mov ($E,$Doff); # e becomes d, which is e in next iteration
@@ -69,14 +68,14 @@ sub BODY_00_15() {
&mov ("edi",$A);
&add ($T,"esi"); # T += Ch(e,f,g)
- &ror ("ecx",2);
+ &ror ("ecx",22-13);
&add ($T,$Hoff); # T += h
- &ror ("edi",13);
+ &xor ("ecx",$A);
+ &ror ("ecx",13-2);
&mov ("esi",$Boff);
- &xor ("ecx","edi");
- &ror ("edi",22-13);
+ &xor ("ecx",$A);
+ &ror ("ecx",2); # Sigma0(a)
&add ($E,$T); # d += T
- &xor ("ecx","edi"); # Sigma0(a)
&mov ("edi",$Coff);
&add ($T,"ecx"); # T += Sigma0(a)
@@ -168,23 +167,22 @@ sub BODY_00_15() {
&set_label("16_63",16);
&mov ("esi",$T);
&mov ("ecx",&DWP(4*(8+15+16-14),"esp"));
- &shr ($T,3);
- &ror ("esi",7);
- &xor ($T,"esi");
&ror ("esi",18-7);
&mov ("edi","ecx");
- &xor ($T,"esi"); # T = sigma0(X[-15])
+ &xor ("esi",$T);
+ &ror ("esi",7);
+ &shr ($T,3);
- &shr ("ecx",10);
- &mov ("esi",&DWP(4*(8+15+16),"esp"));
- &ror ("edi",17);
- &xor ("ecx","edi");
&ror ("edi",19-17);
- &add ($T,"esi"); # T += X[-16]
- &xor ("edi","ecx") # sigma1(X[-2])
+ &xor ($T,"esi"); # T = sigma0(X[-15])
+ &xor ("edi","ecx");
+ &ror ("edi",17);
+ &shr ("ecx",10);
+ &add ($T,&DWP(4*(8+15+16),"esp")); # T += X[-16]
+ &xor ("edi","ecx"); # sigma1(X[-2])
- &add ($T,"edi"); # T += sigma1(X[-2])
- # &add ($T,&DWP(4*(8+15+16-9),"esp")); # T += X[-7], moved to BODY_00_15(1)
+ &add ($T,&DWP(4*(8+15+16-9),"esp")); # T += X[-7]
+ # &add ($T,"edi"); # T += sigma1(X[-2])
# &mov (&DWP(4*(8+15),"esp"),$T); # save X[0]
&BODY_00_15(1);
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha256-armv4.pl b/deps/openssl/openssl/crypto/sha/asm/sha256-armv4.pl
index 492cb62bc..9c84e8d93 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha256-armv4.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha256-armv4.pl
@@ -18,11 +18,16 @@
# Rescheduling for dual-issue pipeline resulted in 22% improvement on
# Cortex A8 core and ~20 cycles per processed byte.
+# February 2011.
+#
+# Profiler-assisted and platform-specific optimization resulted in 16%
+# improvement on Cortex A8 core and ~17 cycles per processed byte.
+
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
$ctx="r0"; $t0="r0";
-$inp="r1";
+$inp="r1"; $t3="r1";
$len="r2"; $t1="r2";
$T1="r3";
$A="r4";
@@ -46,6 +51,9 @@ sub BODY_00_15 {
my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
$code.=<<___ if ($i<16);
+#if __ARM_ARCH__>=7
+ ldr $T1,[$inp],#4
+#else
ldrb $T1,[$inp,#3] @ $i
ldrb $t2,[$inp,#2]
ldrb $t1,[$inp,#1]
@@ -53,16 +61,24 @@ $code.=<<___ if ($i<16);
orr $T1,$T1,$t2,lsl#8
orr $T1,$T1,$t1,lsl#16
orr $T1,$T1,$t0,lsl#24
- `"str $inp,[sp,#17*4]" if ($i==15)`
+#endif
___
$code.=<<___;
- ldr $t2,[$Ktbl],#4 @ *K256++
mov $t0,$e,ror#$Sigma1[0]
- str $T1,[sp,#`$i%16`*4]
+ ldr $t2,[$Ktbl],#4 @ *K256++
eor $t0,$t0,$e,ror#$Sigma1[1]
eor $t1,$f,$g
+#if $i>=16
+ add $T1,$T1,$t3 @ from BODY_16_xx
+#elif __ARM_ARCH__>=7 && defined(__ARMEL__)
+ rev $T1,$T1
+#endif
+#if $i==15
+ str $inp,[sp,#17*4] @ leave room for $t3
+#endif
eor $t0,$t0,$e,ror#$Sigma1[2] @ Sigma1(e)
and $t1,$t1,$e
+ str $T1,[sp,#`$i%16`*4]
add $T1,$T1,$t0
eor $t1,$t1,$g @ Ch(e,f,g)
add $T1,$T1,$h
@@ -71,6 +87,9 @@ $code.=<<___;
eor $h,$h,$a,ror#$Sigma0[1]
add $T1,$T1,$t2
eor $h,$h,$a,ror#$Sigma0[2] @ Sigma0(a)
+#if $i>=15
+ ldr $t3,[sp,#`($i+2)%16`*4] @ from BODY_16_xx
+#endif
orr $t0,$a,$b
and $t1,$a,$b
and $t0,$t0,$c
@@ -85,24 +104,26 @@ sub BODY_16_XX {
my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
$code.=<<___;
- ldr $t1,[sp,#`($i+1)%16`*4] @ $i
+ @ ldr $t3,[sp,#`($i+1)%16`*4] @ $i
ldr $t2,[sp,#`($i+14)%16`*4]
+ mov $t0,$t3,ror#$sigma0[0]
ldr $T1,[sp,#`($i+0)%16`*4]
- mov $t0,$t1,ror#$sigma0[0]
- ldr $inp,[sp,#`($i+9)%16`*4]
- eor $t0,$t0,$t1,ror#$sigma0[1]
- eor $t0,$t0,$t1,lsr#$sigma0[2] @ sigma0(X[i+1])
- mov $t1,$t2,ror#$sigma1[0]
+ eor $t0,$t0,$t3,ror#$sigma0[1]
+ ldr $t1,[sp,#`($i+9)%16`*4]
+ eor $t0,$t0,$t3,lsr#$sigma0[2] @ sigma0(X[i+1])
+ mov $t3,$t2,ror#$sigma1[0]
add $T1,$T1,$t0
- eor $t1,$t1,$t2,ror#$sigma1[1]
- add $T1,$T1,$inp
- eor $t1,$t1,$t2,lsr#$sigma1[2] @ sigma1(X[i+14])
+ eor $t3,$t3,$t2,ror#$sigma1[1]
add $T1,$T1,$t1
+ eor $t3,$t3,$t2,lsr#$sigma1[2] @ sigma1(X[i+14])
+ @ add $T1,$T1,$t3
___
&BODY_00_15(@_);
}
$code=<<___;
+#include "arm_arch.h"
+
.text
.code 32
@@ -132,7 +153,7 @@ K256:
sha256_block_data_order:
sub r3,pc,#8 @ sha256_block_data_order
add $len,$inp,$len,lsl#6 @ len to point at the end of inp
- stmdb sp!,{$ctx,$inp,$len,r4-r12,lr}
+ stmdb sp!,{$ctx,$inp,$len,r4-r11,lr}
ldmia $ctx,{$A,$B,$C,$D,$E,$F,$G,$H}
sub $Ktbl,r3,#256 @ K256
sub sp,sp,#16*4 @ alloca(X[16])
@@ -171,10 +192,14 @@ $code.=<<___;
bne .Loop
add sp,sp,#`16+3`*4 @ destroy frame
- ldmia sp!,{r4-r12,lr}
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r11,pc}
+#else
+ ldmia sp!,{r4-r11,lr}
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
bx lr @ interoperable with Thumb ISA:-)
+#endif
.size sha256_block_data_order,.-sha256_block_data_order
.asciz "SHA256 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
.align 2
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha512-586.pl b/deps/openssl/openssl/crypto/sha/asm/sha512-586.pl
index 5b9f3337a..7eab6a5b8 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha512-586.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha512-586.pl
@@ -142,9 +142,9 @@ sub BODY_00_15_x86 {
&mov ("edx",$Ehi);
&mov ("esi","ecx");
- &shr ("ecx",9) # lo>>9
+ &shr ("ecx",9); # lo>>9
&mov ("edi","edx");
- &shr ("edx",9) # hi>>9
+ &shr ("edx",9); # hi>>9
&mov ("ebx","ecx");
&shl ("esi",14); # lo<<14
&mov ("eax","edx");
@@ -207,9 +207,9 @@ sub BODY_00_15_x86 {
&mov ($Dhi,"ebx");
&mov ("esi","ecx");
- &shr ("ecx",2) # lo>>2
+ &shr ("ecx",2); # lo>>2
&mov ("edi","edx");
- &shr ("edx",2) # hi>>2
+ &shr ("edx",2); # hi>>2
&mov ("ebx","ecx");
&shl ("esi",4); # lo<<4
&mov ("eax","edx");
@@ -452,9 +452,9 @@ if ($sse2) {
&mov ("edx",&DWP(8*(9+15+16-1)+4,"esp"));
&mov ("esi","ecx");
- &shr ("ecx",1) # lo>>1
+ &shr ("ecx",1); # lo>>1
&mov ("edi","edx");
- &shr ("edx",1) # hi>>1
+ &shr ("edx",1); # hi>>1
&mov ("eax","ecx");
&shl ("esi",24); # lo<<24
&mov ("ebx","edx");
@@ -488,9 +488,9 @@ if ($sse2) {
&mov ("edx",&DWP(8*(9+15+16-14)+4,"esp"));
&mov ("esi","ecx");
- &shr ("ecx",6) # lo>>6
+ &shr ("ecx",6); # lo>>6
&mov ("edi","edx");
- &shr ("edx",6) # hi>>6
+ &shr ("edx",6); # hi>>6
&mov ("eax","ecx");
&shl ("esi",3); # lo<<3
&mov ("ebx","edx");
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha512-armv4.pl b/deps/openssl/openssl/crypto/sha/asm/sha512-armv4.pl
index 3a35861ac..7faf37b14 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha512-armv4.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha512-armv4.pl
@@ -18,22 +18,33 @@
# Rescheduling for dual-issue pipeline resulted in 6% improvement on
# Cortex A8 core and ~40 cycles per processed byte.
+# February 2011.
+#
+# Profiler-assisted and platform-specific optimization resulted in 7%
+# improvement on Coxtex A8 core and ~38 cycles per byte.
+
+# March 2011.
+#
+# Add NEON implementation. On Cortex A8 it was measured to process
+# one byte in 25.5 cycles or 47% faster than integer-only code.
+
# Byte order [in]dependence. =========================================
#
-# Caller is expected to maintain specific *dword* order in h[0-7],
-# namely with most significant dword at *lower* address, which is
-# reflected in below two parameters. *Byte* order within these dwords
-# in turn is whatever *native* byte order on current platform.
-$hi=0;
-$lo=4;
+# Originally caller was expected to maintain specific *dword* order in
+# h[0-7], namely with most significant dword at *lower* address, which
+# was reflected in below two parameters as 0 and 4. Now caller is
+# expected to maintain native byte order for whole 64-bit values.
+$hi="HI";
+$lo="LO";
# ====================================================================
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
-$ctx="r0";
+$ctx="r0"; # parameter block
$inp="r1";
$len="r2";
+
$Tlo="r3";
$Thi="r4";
$Alo="r5";
@@ -61,15 +72,17 @@ $Xoff=8*8;
sub BODY_00_15() {
my $magic = shift;
$code.=<<___;
- ldr $t2,[sp,#$Hoff+0] @ h.lo
- ldr $t3,[sp,#$Hoff+4] @ h.hi
@ Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
@ LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
@ HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
mov $t0,$Elo,lsr#14
+ str $Tlo,[sp,#$Xoff+0]
mov $t1,$Ehi,lsr#14
+ str $Thi,[sp,#$Xoff+4]
eor $t0,$t0,$Ehi,lsl#18
+ ldr $t2,[sp,#$Hoff+0] @ h.lo
eor $t1,$t1,$Elo,lsl#18
+ ldr $t3,[sp,#$Hoff+4] @ h.hi
eor $t0,$t0,$Elo,lsr#18
eor $t1,$t1,$Ehi,lsr#18
eor $t0,$t0,$Ehi,lsl#14
@@ -96,25 +109,24 @@ $code.=<<___;
and $t1,$t1,$Ehi
str $Ahi,[sp,#$Aoff+4]
eor $t0,$t0,$t2
- ldr $t2,[$Ktbl,#4] @ K[i].lo
+ ldr $t2,[$Ktbl,#$lo] @ K[i].lo
eor $t1,$t1,$t3 @ Ch(e,f,g)
- ldr $t3,[$Ktbl,#0] @ K[i].hi
+ ldr $t3,[$Ktbl,#$hi] @ K[i].hi
adds $Tlo,$Tlo,$t0
ldr $Elo,[sp,#$Doff+0] @ d.lo
adc $Thi,$Thi,$t1 @ T += Ch(e,f,g)
ldr $Ehi,[sp,#$Doff+4] @ d.hi
adds $Tlo,$Tlo,$t2
+ and $t0,$t2,#0xff
adc $Thi,$Thi,$t3 @ T += K[i]
adds $Elo,$Elo,$Tlo
+ ldr $t2,[sp,#$Boff+0] @ b.lo
adc $Ehi,$Ehi,$Thi @ d += T
-
- and $t0,$t2,#0xff
teq $t0,#$magic
- orreq $Ktbl,$Ktbl,#1
- ldr $t2,[sp,#$Boff+0] @ b.lo
ldr $t3,[sp,#$Coff+0] @ c.lo
+ orreq $Ktbl,$Ktbl,#1
@ Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
@ LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
@ HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
@@ -131,80 +143,100 @@ $code.=<<___;
eor $t0,$t0,$Alo,lsl#25
eor $t1,$t1,$Ahi,lsl#25 @ Sigma0(a)
adds $Tlo,$Tlo,$t0
+ and $t0,$Alo,$t2
adc $Thi,$Thi,$t1 @ T += Sigma0(a)
- and $t0,$Alo,$t2
- orr $Alo,$Alo,$t2
ldr $t1,[sp,#$Boff+4] @ b.hi
+ orr $Alo,$Alo,$t2
ldr $t2,[sp,#$Coff+4] @ c.hi
and $Alo,$Alo,$t3
- orr $Alo,$Alo,$t0 @ Maj(a,b,c).lo
and $t3,$Ahi,$t1
orr $Ahi,$Ahi,$t1
+ orr $Alo,$Alo,$t0 @ Maj(a,b,c).lo
and $Ahi,$Ahi,$t2
- orr $Ahi,$Ahi,$t3 @ Maj(a,b,c).hi
adds $Alo,$Alo,$Tlo
- adc $Ahi,$Ahi,$Thi @ h += T
-
+ orr $Ahi,$Ahi,$t3 @ Maj(a,b,c).hi
sub sp,sp,#8
+ adc $Ahi,$Ahi,$Thi @ h += T
+ tst $Ktbl,#1
add $Ktbl,$Ktbl,#8
___
}
$code=<<___;
+#include "arm_arch.h"
+#ifdef __ARMEL__
+# define LO 0
+# define HI 4
+# define WORD64(hi0,lo0,hi1,lo1) .word lo0,hi0, lo1,hi1
+#else
+# define HI 0
+# define LO 4
+# define WORD64(hi0,lo0,hi1,lo1) .word hi0,lo0, hi1,lo1
+#endif
+
.text
.code 32
.type K512,%object
.align 5
K512:
-.word 0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
-.word 0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
-.word 0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
-.word 0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
-.word 0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
-.word 0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
-.word 0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
-.word 0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
-.word 0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
-.word 0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
-.word 0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
-.word 0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
-.word 0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
-.word 0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
-.word 0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
-.word 0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
-.word 0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
-.word 0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
-.word 0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
-.word 0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
-.word 0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
-.word 0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
-.word 0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
-.word 0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
-.word 0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
-.word 0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
-.word 0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
-.word 0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
-.word 0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
-.word 0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
-.word 0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
-.word 0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
-.word 0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
-.word 0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
-.word 0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
-.word 0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
-.word 0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
-.word 0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
-.word 0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
-.word 0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
+WORD64(0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd)
+WORD64(0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc)
+WORD64(0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019)
+WORD64(0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118)
+WORD64(0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe)
+WORD64(0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2)
+WORD64(0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1)
+WORD64(0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694)
+WORD64(0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3)
+WORD64(0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65)
+WORD64(0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483)
+WORD64(0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5)
+WORD64(0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210)
+WORD64(0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4)
+WORD64(0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725)
+WORD64(0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70)
+WORD64(0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926)
+WORD64(0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df)
+WORD64(0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8)
+WORD64(0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b)
+WORD64(0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001)
+WORD64(0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30)
+WORD64(0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910)
+WORD64(0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8)
+WORD64(0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53)
+WORD64(0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8)
+WORD64(0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb)
+WORD64(0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3)
+WORD64(0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60)
+WORD64(0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec)
+WORD64(0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9)
+WORD64(0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b)
+WORD64(0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207)
+WORD64(0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178)
+WORD64(0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6)
+WORD64(0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b)
+WORD64(0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493)
+WORD64(0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c)
+WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a)
+WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817)
.size K512,.-K512
+.LOPENSSL_armcap:
+.word OPENSSL_armcap_P-sha512_block_data_order
+.skip 32-4
.global sha512_block_data_order
.type sha512_block_data_order,%function
sha512_block_data_order:
sub r3,pc,#8 @ sha512_block_data_order
add $len,$inp,$len,lsl#7 @ len to point at the end of inp
+#if __ARM_ARCH__>=7
+ ldr r12,.LOPENSSL_armcap
+ ldr r12,[r3,r12] @ OPENSSL_armcap_P
+ tst r12,#1
+ bne .LNEON
+#endif
stmdb sp!,{r4-r12,lr}
- sub $Ktbl,r3,#640 @ K512
+ sub $Ktbl,r3,#672 @ K512
sub sp,sp,#9*8
ldr $Elo,[$ctx,#$Eoff+$lo]
@@ -238,6 +270,7 @@ sha512_block_data_order:
str $Thi,[sp,#$Foff+4]
.L00_15:
+#if __ARM_ARCH__<7
ldrb $Tlo,[$inp,#7]
ldrb $t0, [$inp,#6]
ldrb $t1, [$inp,#5]
@@ -252,26 +285,30 @@ sha512_block_data_order:
orr $Thi,$Thi,$t3,lsl#8
orr $Thi,$Thi,$t0,lsl#16
orr $Thi,$Thi,$t1,lsl#24
- str $Tlo,[sp,#$Xoff+0]
- str $Thi,[sp,#$Xoff+4]
+#else
+ ldr $Tlo,[$inp,#4]
+ ldr $Thi,[$inp],#8
+#ifdef __ARMEL__
+ rev $Tlo,$Tlo
+ rev $Thi,$Thi
+#endif
+#endif
___
&BODY_00_15(0x94);
$code.=<<___;
tst $Ktbl,#1
beq .L00_15
- bic $Ktbl,$Ktbl,#1
-
-.L16_79:
ldr $t0,[sp,#`$Xoff+8*(16-1)`+0]
ldr $t1,[sp,#`$Xoff+8*(16-1)`+4]
- ldr $t2,[sp,#`$Xoff+8*(16-14)`+0]
- ldr $t3,[sp,#`$Xoff+8*(16-14)`+4]
-
+ bic $Ktbl,$Ktbl,#1
+.L16_79:
@ sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
@ LO lo>>1^hi<<31 ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
@ HI hi>>1^lo<<31 ^ hi>>8^lo<<24 ^ hi>>7
mov $Tlo,$t0,lsr#1
+ ldr $t2,[sp,#`$Xoff+8*(16-14)`+0]
mov $Thi,$t1,lsr#1
+ ldr $t3,[sp,#`$Xoff+8*(16-14)`+4]
eor $Tlo,$Tlo,$t1,lsl#31
eor $Thi,$Thi,$t0,lsl#31
eor $Tlo,$Tlo,$t0,lsr#8
@@ -295,25 +332,24 @@ $code.=<<___;
eor $t1,$t1,$t3,lsl#3
eor $t0,$t0,$t2,lsr#6
eor $t1,$t1,$t3,lsr#6
+ ldr $t2,[sp,#`$Xoff+8*(16-9)`+0]
eor $t0,$t0,$t3,lsl#26
- ldr $t2,[sp,#`$Xoff+8*(16-9)`+0]
ldr $t3,[sp,#`$Xoff+8*(16-9)`+4]
adds $Tlo,$Tlo,$t0
+ ldr $t0,[sp,#`$Xoff+8*16`+0]
adc $Thi,$Thi,$t1
- ldr $t0,[sp,#`$Xoff+8*16`+0]
ldr $t1,[sp,#`$Xoff+8*16`+4]
adds $Tlo,$Tlo,$t2
adc $Thi,$Thi,$t3
adds $Tlo,$Tlo,$t0
adc $Thi,$Thi,$t1
- str $Tlo,[sp,#$Xoff+0]
- str $Thi,[sp,#$Xoff+4]
___
&BODY_00_15(0x17);
$code.=<<___;
- tst $Ktbl,#1
+ ldreq $t0,[sp,#`$Xoff+8*(16-1)`+0]
+ ldreq $t1,[sp,#`$Xoff+8*(16-1)`+4]
beq .L16_79
bic $Ktbl,$Ktbl,#1
@@ -324,12 +360,12 @@ $code.=<<___;
ldr $t2, [$ctx,#$Boff+$lo]
ldr $t3, [$ctx,#$Boff+$hi]
adds $t0,$Alo,$t0
- adc $t1,$Ahi,$t1
- adds $t2,$Tlo,$t2
- adc $t3,$Thi,$t3
str $t0, [$ctx,#$Aoff+$lo]
+ adc $t1,$Ahi,$t1
str $t1, [$ctx,#$Aoff+$hi]
+ adds $t2,$Tlo,$t2
str $t2, [$ctx,#$Boff+$lo]
+ adc $t3,$Thi,$t3
str $t3, [$ctx,#$Boff+$hi]
ldr $Alo,[sp,#$Coff+0]
@@ -341,12 +377,12 @@ $code.=<<___;
ldr $t2, [$ctx,#$Doff+$lo]
ldr $t3, [$ctx,#$Doff+$hi]
adds $t0,$Alo,$t0
- adc $t1,$Ahi,$t1
- adds $t2,$Tlo,$t2
- adc $t3,$Thi,$t3
str $t0, [$ctx,#$Coff+$lo]
+ adc $t1,$Ahi,$t1
str $t1, [$ctx,#$Coff+$hi]
+ adds $t2,$Tlo,$t2
str $t2, [$ctx,#$Doff+$lo]
+ adc $t3,$Thi,$t3
str $t3, [$ctx,#$Doff+$hi]
ldr $Tlo,[sp,#$Foff+0]
@@ -356,12 +392,12 @@ $code.=<<___;
ldr $t2, [$ctx,#$Foff+$lo]
ldr $t3, [$ctx,#$Foff+$hi]
adds $Elo,$Elo,$t0
- adc $Ehi,$Ehi,$t1
- adds $t2,$Tlo,$t2
- adc $t3,$Thi,$t3
str $Elo,[$ctx,#$Eoff+$lo]
+ adc $Ehi,$Ehi,$t1
str $Ehi,[$ctx,#$Eoff+$hi]
+ adds $t2,$Tlo,$t2
str $t2, [$ctx,#$Foff+$lo]
+ adc $t3,$Thi,$t3
str $t3, [$ctx,#$Foff+$hi]
ldr $Alo,[sp,#$Goff+0]
@@ -373,12 +409,12 @@ $code.=<<___;
ldr $t2, [$ctx,#$Hoff+$lo]
ldr $t3, [$ctx,#$Hoff+$hi]
adds $t0,$Alo,$t0
- adc $t1,$Ahi,$t1
- adds $t2,$Tlo,$t2
- adc $t3,$Thi,$t3
str $t0, [$ctx,#$Goff+$lo]
+ adc $t1,$Ahi,$t1
str $t1, [$ctx,#$Goff+$hi]
+ adds $t2,$Tlo,$t2
str $t2, [$ctx,#$Hoff+$lo]
+ adc $t3,$Thi,$t3
str $t3, [$ctx,#$Hoff+$hi]
add sp,sp,#640
@@ -388,13 +424,156 @@ $code.=<<___;
bne .Loop
add sp,sp,#8*9 @ destroy frame
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r12,pc}
+#else
ldmia sp!,{r4-r12,lr}
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
bx lr @ interoperable with Thumb ISA:-)
-.size sha512_block_data_order,.-sha512_block_data_order
-.asciz "SHA512 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
+#endif
+___
+
+{
+my @Sigma0=(28,34,39);
+my @Sigma1=(14,18,41);
+my @sigma0=(1, 8, 7);
+my @sigma1=(19,61,6);
+
+my $Ktbl="r3";
+my $cnt="r12"; # volatile register known as ip, intra-procedure-call scratch
+
+my @X=map("d$_",(0..15));
+my @V=($A,$B,$C,$D,$E,$F,$G,$H)=map("d$_",(16..23));
+
+sub NEON_00_15() {
+my $i=shift;
+my ($a,$b,$c,$d,$e,$f,$g,$h)=@_;
+my ($t0,$t1,$t2,$T1,$K,$Ch,$Maj)=map("d$_",(24..31)); # temps
+
+$code.=<<___ if ($i<16 || $i&1);
+ vshr.u64 $t0,$e,#@Sigma1[0] @ $i
+#if $i<16
+ vld1.64 {@X[$i%16]},[$inp]! @ handles unaligned
+#endif
+ vshr.u64 $t1,$e,#@Sigma1[1]
+ vshr.u64 $t2,$e,#@Sigma1[2]
+___
+$code.=<<___;
+ vld1.64 {$K},[$Ktbl,:64]! @ K[i++]
+ vsli.64 $t0,$e,#`64-@Sigma1[0]`
+ vsli.64 $t1,$e,#`64-@Sigma1[1]`
+ vsli.64 $t2,$e,#`64-@Sigma1[2]`
+#if $i<16 && defined(__ARMEL__)
+ vrev64.8 @X[$i],@X[$i]
+#endif
+ vadd.i64 $T1,$K,$h
+ veor $Ch,$f,$g
+ veor $t0,$t1
+ vand $Ch,$e
+ veor $t0,$t2 @ Sigma1(e)
+ veor $Ch,$g @ Ch(e,f,g)
+ vadd.i64 $T1,$t0
+ vshr.u64 $t0,$a,#@Sigma0[0]
+ vadd.i64 $T1,$Ch
+ vshr.u64 $t1,$a,#@Sigma0[1]
+ vshr.u64 $t2,$a,#@Sigma0[2]
+ vsli.64 $t0,$a,#`64-@Sigma0[0]`
+ vsli.64 $t1,$a,#`64-@Sigma0[1]`
+ vsli.64 $t2,$a,#`64-@Sigma0[2]`
+ vadd.i64 $T1,@X[$i%16]
+ vorr $Maj,$a,$c
+ vand $Ch,$a,$c
+ veor $h,$t0,$t1
+ vand $Maj,$b
+ veor $h,$t2 @ Sigma0(a)
+ vorr $Maj,$Ch @ Maj(a,b,c)
+ vadd.i64 $h,$T1
+ vadd.i64 $d,$T1
+ vadd.i64 $h,$Maj
+___
+}
+
+sub NEON_16_79() {
+my $i=shift;
+
+if ($i&1) { &NEON_00_15($i,@_); return; }
+
+# 2x-vectorized, therefore runs every 2nd round
+my @X=map("q$_",(0..7)); # view @X as 128-bit vector
+my ($t0,$t1,$s0,$s1) = map("q$_",(12..15)); # temps
+my ($d0,$d1,$d2) = map("d$_",(24..26)); # temps from NEON_00_15
+my $e=@_[4]; # $e from NEON_00_15
+$i /= 2;
+$code.=<<___;
+ vshr.u64 $t0,@X[($i+7)%8],#@sigma1[0]
+ vshr.u64 $t1,@X[($i+7)%8],#@sigma1[1]
+ vshr.u64 $s1,@X[($i+7)%8],#@sigma1[2]
+ vsli.64 $t0,@X[($i+7)%8],#`64-@sigma1[0]`
+ vext.8 $s0,@X[$i%8],@X[($i+1)%8],#8 @ X[i+1]
+ vsli.64 $t1,@X[($i+7)%8],#`64-@sigma1[1]`
+ veor $s1,$t0
+ vshr.u64 $t0,$s0,#@sigma0[0]
+ veor $s1,$t1 @ sigma1(X[i+14])
+ vshr.u64 $t1,$s0,#@sigma0[1]
+ vadd.i64 @X[$i%8],$s1
+ vshr.u64 $s1,$s0,#@sigma0[2]
+ vsli.64 $t0,$s0,#`64-@sigma0[0]`
+ vsli.64 $t1,$s0,#`64-@sigma0[1]`
+ vext.8 $s0,@X[($i+4)%8],@X[($i+5)%8],#8 @ X[i+9]
+ veor $s1,$t0
+ vshr.u64 $d0,$e,#@Sigma1[0] @ from NEON_00_15
+ vadd.i64 @X[$i%8],$s0
+ vshr.u64 $d1,$e,#@Sigma1[1] @ from NEON_00_15
+ veor $s1,$t1 @ sigma0(X[i+1])
+ vshr.u64 $d2,$e,#@Sigma1[2] @ from NEON_00_15
+ vadd.i64 @X[$i%8],$s1
+___
+ &NEON_00_15(2*$i,@_);
+}
+
+$code.=<<___;
+#if __ARM_ARCH__>=7
+.fpu neon
+
+.align 4
+.LNEON:
+ dmb @ errata #451034 on early Cortex A8
+ vstmdb sp!,{d8-d15} @ ABI specification says so
+ sub $Ktbl,r3,#672 @ K512
+ vldmia $ctx,{$A-$H} @ load context
+.Loop_neon:
+___
+for($i=0;$i<16;$i++) { &NEON_00_15($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+ mov $cnt,#4
+.L16_79_neon:
+ subs $cnt,#1
+___
+for(;$i<32;$i++) { &NEON_16_79($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+ bne .L16_79_neon
+
+ vldmia $ctx,{d24-d31} @ load context to temp
+ vadd.i64 q8,q12 @ vectorized accumulate
+ vadd.i64 q9,q13
+ vadd.i64 q10,q14
+ vadd.i64 q11,q15
+ vstmia $ctx,{$A-$H} @ save context
+ teq $inp,$len
+ sub $Ktbl,#640 @ rewind K512
+ bne .Loop_neon
+
+ vldmia sp!,{d8-d15} @ epilogue
+ bx lr
+#endif
+___
+}
+$code.=<<___;
+.size sha512_block_data_order,.-sha512_block_data_order
+.asciz "SHA512 block transform for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
.align 2
+.comm OPENSSL_armcap_P,4,4
___
$code =~ s/\`([^\`]*)\`/eval $1/gem;
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha512-mips.pl b/deps/openssl/openssl/crypto/sha/asm/sha512-mips.pl
new file mode 100644
index 000000000..ba5b25089
--- /dev/null
+++ b/deps/openssl/openssl/crypto/sha/asm/sha512-mips.pl
@@ -0,0 +1,455 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA2 block procedures for MIPS.
+
+# October 2010.
+#
+# SHA256 performance improvement on MIPS R5000 CPU is ~27% over gcc-
+# generated code in o32 build and ~55% in n32/64 build. SHA512 [which
+# for now can only be compiled for MIPS64 ISA] improvement is modest
+# ~17%, but it comes for free, because it's same instruction sequence.
+# Improvement coefficients are for aligned input.
+
+######################################################################
+# There is a number of MIPS ABI in use, O32 and N32/64 are most
+# widely used. Then there is a new contender: NUBI. It appears that if
+# one picks the latter, it's possible to arrange code in ABI neutral
+# manner. Therefore let's stick to NUBI register layout:
+#
+($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
+($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
+#
+# The return value is placed in $a0. Following coding rules facilitate
+# interoperability:
+#
+# - never ever touch $tp, "thread pointer", former $gp [o32 can be
+# excluded from the rule, because it's specified volatile];
+# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
+# old code];
+# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
+#
+# For reference here is register layout for N32/64 MIPS ABIs:
+#
+# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
+# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
+# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
+# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
+# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
+#
+$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
+
+if ($flavour =~ /64|n32/i) {
+ $PTR_ADD="dadd"; # incidentally works even on n32
+ $PTR_SUB="dsub"; # incidentally works even on n32
+ $REG_S="sd";
+ $REG_L="ld";
+ $PTR_SLL="dsll"; # incidentally works even on n32
+ $SZREG=8;
+} else {
+ $PTR_ADD="add";
+ $PTR_SUB="sub";
+ $REG_S="sw";
+ $REG_L="lw";
+ $PTR_SLL="sll";
+ $SZREG=4;
+}
+$pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
+#
+# <appro@openssl.org>
+#
+######################################################################
+
+$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0;
+
+for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); }
+open STDOUT,">$output";
+
+if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); }
+
+if ($output =~ /512/) {
+ $label="512";
+ $SZ=8;
+ $LD="ld"; # load from memory
+ $ST="sd"; # store to memory
+ $SLL="dsll"; # shift left logical
+ $SRL="dsrl"; # shift right logical
+ $ADDU="daddu";
+ @Sigma0=(28,34,39);
+ @Sigma1=(14,18,41);
+ @sigma0=( 7, 1, 8); # right shift first
+ @sigma1=( 6,19,61); # right shift first
+ $lastK=0x817;
+ $rounds=80;
+} else {
+ $label="256";
+ $SZ=4;
+ $LD="lw"; # load from memory
+ $ST="sw"; # store to memory
+ $SLL="sll"; # shift left logical
+ $SRL="srl"; # shift right logical
+ $ADDU="addu";
+ @Sigma0=( 2,13,22);
+ @Sigma1=( 6,11,25);
+ @sigma0=( 3, 7,18); # right shift first
+ @sigma1=(10,17,19); # right shift first
+ $lastK=0x8f2;
+ $rounds=64;
+}
+
+$MSB = $big_endian ? 0 : ($SZ-1);
+$LSB = ($SZ-1)&~$MSB;
+
+@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("\$$_",(1,2,3,7,24,25,30,31));
+@X=map("\$$_",(8..23));
+
+$ctx=$a0;
+$inp=$a1;
+$len=$a2; $Ktbl=$len;
+
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+my ($T1,$tmp0,$tmp1,$tmp2)=(@X[4],@X[5],@X[6],@X[7]);
+
+$code.=<<___ if ($i<15);
+ ${LD}l @X[1],`($i+1)*$SZ+$MSB`($inp)
+ ${LD}r @X[1],`($i+1)*$SZ+$LSB`($inp)
+___
+$code.=<<___ if (!$big_endian && $i<16 && $SZ==4);
+ srl $tmp0,@X[0],24 # byte swap($i)
+ srl $tmp1,@X[0],8
+ andi $tmp2,@X[0],0xFF00
+ sll @X[0],@X[0],24
+ andi $tmp1,0xFF00
+ sll $tmp2,$tmp2,8
+ or @X[0],$tmp0
+ or $tmp1,$tmp2
+ or @X[0],$tmp1
+___
+$code.=<<___ if (!$big_endian && $i<16 && $SZ==8);
+ ori $tmp0,$zero,0xFF
+ dsll $tmp2,$tmp0,32
+ or $tmp0,$tmp2 # 0x000000FF000000FF
+ and $tmp1,@X[0],$tmp0 # byte swap($i)
+ dsrl $tmp2,@X[0],24
+ dsll $tmp1,24
+ and $tmp2,$tmp0
+ dsll $tmp0,8 # 0x0000FF000000FF00
+ or $tmp1,$tmp2
+ and $tmp2,@X[0],$tmp0
+ dsrl @X[0],8
+ dsll $tmp2,8
+ and @X[0],$tmp0
+ or $tmp1,$tmp2
+ or @X[0],$tmp1
+ dsrl $tmp1,@X[0],32
+ dsll @X[0],32
+ or @X[0],$tmp1
+___
+$code.=<<___;
+ $ADDU $T1,$X[0],$h # $i
+ $SRL $h,$e,@Sigma1[0]
+ xor $tmp2,$f,$g
+ $SLL $tmp1,$e,`$SZ*8-@Sigma1[2]`
+ and $tmp2,$e
+ $SRL $tmp0,$e,@Sigma1[1]
+ xor $h,$tmp1
+ $SLL $tmp1,$e,`$SZ*8-@Sigma1[1]`
+ xor $h,$tmp0
+ $SRL $tmp0,$e,@Sigma1[2]
+ xor $h,$tmp1
+ $SLL $tmp1,$e,`$SZ*8-@Sigma1[0]`
+ xor $h,$tmp0
+ xor $tmp2,$g # Ch(e,f,g)
+ xor $tmp0,$tmp1,$h # Sigma1(e)
+
+ $SRL $h,$a,@Sigma0[0]
+ $ADDU $T1,$tmp2
+ $LD $tmp2,`$i*$SZ`($Ktbl) # K[$i]
+ $SLL $tmp1,$a,`$SZ*8-@Sigma0[2]`
+ $ADDU $T1,$tmp0
+ $SRL $tmp0,$a,@Sigma0[1]
+ xor $h,$tmp1
+ $SLL $tmp1,$a,`$SZ*8-@Sigma0[1]`
+ xor $h,$tmp0
+ $SRL $tmp0,$a,@Sigma0[2]
+ xor $h,$tmp1
+ $SLL $tmp1,$a,`$SZ*8-@Sigma0[0]`
+ xor $h,$tmp0
+ $ST @X[0],`($i%16)*$SZ`($sp) # offload to ring buffer
+ xor $h,$tmp1 # Sigma0(a)
+
+ or $tmp0,$a,$b
+ and $tmp1,$a,$b
+ and $tmp0,$c
+ or $tmp1,$tmp0 # Maj(a,b,c)
+ $ADDU $T1,$tmp2 # +=K[$i]
+ $ADDU $h,$tmp1
+
+ $ADDU $d,$T1
+ $ADDU $h,$T1
+___
+$code.=<<___ if ($i>=13);
+ $LD @X[3],`(($i+3)%16)*$SZ`($sp) # prefetch from ring buffer
+___
+}
+
+sub BODY_16_XX {
+my $i=@_[0];
+my ($tmp0,$tmp1,$tmp2,$tmp3)=(@X[4],@X[5],@X[6],@X[7]);
+
+$code.=<<___;
+ $SRL $tmp2,@X[1],@sigma0[0] # Xupdate($i)
+ $ADDU @X[0],@X[9] # +=X[i+9]
+ $SLL $tmp1,@X[1],`$SZ*8-@sigma0[2]`
+ $SRL $tmp0,@X[1],@sigma0[1]
+ xor $tmp2,$tmp1
+ $SLL $tmp1,`@sigma0[2]-@sigma0[1]`
+ xor $tmp2,$tmp0
+ $SRL $tmp0,@X[1],@sigma0[2]
+ xor $tmp2,$tmp1
+
+ $SRL $tmp3,@X[14],@sigma1[0]
+ xor $tmp2,$tmp0 # sigma0(X[i+1])
+ $SLL $tmp1,@X[14],`$SZ*8-@sigma1[2]`
+ $ADDU @X[0],$tmp2
+ $SRL $tmp0,@X[14],@sigma1[1]
+ xor $tmp3,$tmp1
+ $SLL $tmp1,`@sigma1[2]-@sigma1[1]`
+ xor $tmp3,$tmp0
+ $SRL $tmp0,@X[14],@sigma1[2]
+ xor $tmp3,$tmp1
+
+ xor $tmp3,$tmp0 # sigma1(X[i+14])
+ $ADDU @X[0],$tmp3
+___
+ &BODY_00_15(@_);
+}
+
+$FRAMESIZE=16*$SZ+16*$SZREG;
+$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000;
+
+$code.=<<___;
+#ifdef OPENSSL_FIPSCANISTER
+# include <openssl/fipssyms.h>
+#endif
+
+.text
+.set noat
+#if !defined(__vxworks) || defined(__pic__)
+.option pic2
+#endif
+
+.align 5
+.globl sha${label}_block_data_order
+.ent sha${label}_block_data_order
+sha${label}_block_data_order:
+ .frame $sp,$FRAMESIZE,$ra
+ .mask $SAVED_REGS_MASK,-$SZREG
+ .set noreorder
+___
+$code.=<<___ if ($flavour =~ /o32/i); # o32 PIC-ification
+ .cpload $pf
+___
+$code.=<<___;
+ $PTR_SUB $sp,$FRAMESIZE
+ $REG_S $ra,$FRAMESIZE-1*$SZREG($sp)
+ $REG_S $fp,$FRAMESIZE-2*$SZREG($sp)
+ $REG_S $s11,$FRAMESIZE-3*$SZREG($sp)
+ $REG_S $s10,$FRAMESIZE-4*$SZREG($sp)
+ $REG_S $s9,$FRAMESIZE-5*$SZREG($sp)
+ $REG_S $s8,$FRAMESIZE-6*$SZREG($sp)
+ $REG_S $s7,$FRAMESIZE-7*$SZREG($sp)
+ $REG_S $s6,$FRAMESIZE-8*$SZREG($sp)
+ $REG_S $s5,$FRAMESIZE-9*$SZREG($sp)
+ $REG_S $s4,$FRAMESIZE-10*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue
+ $REG_S $s3,$FRAMESIZE-11*$SZREG($sp)
+ $REG_S $s2,$FRAMESIZE-12*$SZREG($sp)
+ $REG_S $s1,$FRAMESIZE-13*$SZREG($sp)
+ $REG_S $s0,$FRAMESIZE-14*$SZREG($sp)
+ $REG_S $gp,$FRAMESIZE-15*$SZREG($sp)
+___
+$code.=<<___;
+ $PTR_SLL @X[15],$len,`log(16*$SZ)/log(2)`
+___
+$code.=<<___ if ($flavour !~ /o32/i); # non-o32 PIC-ification
+ .cplocal $Ktbl
+ .cpsetup $pf,$zero,sha${label}_block_data_order
+___
+$code.=<<___;
+ .set reorder
+ la $Ktbl,K${label} # PIC-ified 'load address'
+
+ $LD $A,0*$SZ($ctx) # load context
+ $LD $B,1*$SZ($ctx)
+ $LD $C,2*$SZ($ctx)
+ $LD $D,3*$SZ($ctx)
+ $LD $E,4*$SZ($ctx)
+ $LD $F,5*$SZ($ctx)
+ $LD $G,6*$SZ($ctx)
+ $LD $H,7*$SZ($ctx)
+
+ $PTR_ADD @X[15],$inp # pointer to the end of input
+ $REG_S @X[15],16*$SZ($sp)
+ b .Loop
+
+.align 5
+.Loop:
+ ${LD}l @X[0],$MSB($inp)
+ ${LD}r @X[0],$LSB($inp)
+___
+for ($i=0;$i<16;$i++)
+{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); push(@X,shift(@X)); }
+$code.=<<___;
+ b .L16_xx
+.align 4
+.L16_xx:
+___
+for (;$i<32;$i++)
+{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); push(@X,shift(@X)); }
+$code.=<<___;
+ and @X[6],0xfff
+ li @X[7],$lastK
+ .set noreorder
+ bne @X[6],@X[7],.L16_xx
+ $PTR_ADD $Ktbl,16*$SZ # Ktbl+=16
+
+ $REG_L @X[15],16*$SZ($sp) # restore pointer to the end of input
+ $LD @X[0],0*$SZ($ctx)
+ $LD @X[1],1*$SZ($ctx)
+ $LD @X[2],2*$SZ($ctx)
+ $PTR_ADD $inp,16*$SZ
+ $LD @X[3],3*$SZ($ctx)
+ $ADDU $A,@X[0]
+ $LD @X[4],4*$SZ($ctx)
+ $ADDU $B,@X[1]
+ $LD @X[5],5*$SZ($ctx)
+ $ADDU $C,@X[2]
+ $LD @X[6],6*$SZ($ctx)
+ $ADDU $D,@X[3]
+ $LD @X[7],7*$SZ($ctx)
+ $ADDU $E,@X[4]
+ $ST $A,0*$SZ($ctx)
+ $ADDU $F,@X[5]
+ $ST $B,1*$SZ($ctx)
+ $ADDU $G,@X[6]
+ $ST $C,2*$SZ($ctx)
+ $ADDU $H,@X[7]
+ $ST $D,3*$SZ($ctx)
+ $ST $E,4*$SZ($ctx)
+ $ST $F,5*$SZ($ctx)
+ $ST $G,6*$SZ($ctx)
+ $ST $H,7*$SZ($ctx)
+
+ bnel $inp,@X[15],.Loop
+ $PTR_SUB $Ktbl,`($rounds-16)*$SZ` # rewind $Ktbl
+
+ $REG_L $ra,$FRAMESIZE-1*$SZREG($sp)
+ $REG_L $fp,$FRAMESIZE-2*$SZREG($sp)
+ $REG_L $s11,$FRAMESIZE-3*$SZREG($sp)
+ $REG_L $s10,$FRAMESIZE-4*$SZREG($sp)
+ $REG_L $s9,$FRAMESIZE-5*$SZREG($sp)
+ $REG_L $s8,$FRAMESIZE-6*$SZREG($sp)
+ $REG_L $s7,$FRAMESIZE-7*$SZREG($sp)
+ $REG_L $s6,$FRAMESIZE-8*$SZREG($sp)
+ $REG_L $s5,$FRAMESIZE-9*$SZREG($sp)
+ $REG_L $s4,$FRAMESIZE-10*$SZREG($sp)
+___
+$code.=<<___ if ($flavour =~ /nubi/i);
+ $REG_L $s3,$FRAMESIZE-11*$SZREG($sp)
+ $REG_L $s2,$FRAMESIZE-12*$SZREG($sp)
+ $REG_L $s1,$FRAMESIZE-13*$SZREG($sp)
+ $REG_L $s0,$FRAMESIZE-14*$SZREG($sp)
+ $REG_L $gp,$FRAMESIZE-15*$SZREG($sp)
+___
+$code.=<<___;
+ jr $ra
+ $PTR_ADD $sp,$FRAMESIZE
+.end sha${label}_block_data_order
+
+.rdata
+.align 5
+K${label}:
+___
+if ($SZ==4) {
+$code.=<<___;
+ .word 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
+ .word 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
+ .word 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
+ .word 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
+ .word 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
+ .word 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
+ .word 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
+ .word 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
+ .word 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
+ .word 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
+ .word 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
+ .word 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
+ .word 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
+ .word 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
+ .word 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
+ .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+___
+} else {
+$code.=<<___;
+ .dword 0x428a2f98d728ae22, 0x7137449123ef65cd
+ .dword 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc
+ .dword 0x3956c25bf348b538, 0x59f111f1b605d019
+ .dword 0x923f82a4af194f9b, 0xab1c5ed5da6d8118
+ .dword 0xd807aa98a3030242, 0x12835b0145706fbe
+ .dword 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2
+ .dword 0x72be5d74f27b896f, 0x80deb1fe3b1696b1
+ .dword 0x9bdc06a725c71235, 0xc19bf174cf692694
+ .dword 0xe49b69c19ef14ad2, 0xefbe4786384f25e3
+ .dword 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65
+ .dword 0x2de92c6f592b0275, 0x4a7484aa6ea6e483
+ .dword 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5
+ .dword 0x983e5152ee66dfab, 0xa831c66d2db43210
+ .dword 0xb00327c898fb213f, 0xbf597fc7beef0ee4
+ .dword 0xc6e00bf33da88fc2, 0xd5a79147930aa725
+ .dword 0x06ca6351e003826f, 0x142929670a0e6e70
+ .dword 0x27b70a8546d22ffc, 0x2e1b21385c26c926
+ .dword 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df
+ .dword 0x650a73548baf63de, 0x766a0abb3c77b2a8
+ .dword 0x81c2c92e47edaee6, 0x92722c851482353b
+ .dword 0xa2bfe8a14cf10364, 0xa81a664bbc423001
+ .dword 0xc24b8b70d0f89791, 0xc76c51a30654be30
+ .dword 0xd192e819d6ef5218, 0xd69906245565a910
+ .dword 0xf40e35855771202a, 0x106aa07032bbd1b8
+ .dword 0x19a4c116b8d2d0c8, 0x1e376c085141ab53
+ .dword 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8
+ .dword 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb
+ .dword 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3
+ .dword 0x748f82ee5defb2fc, 0x78a5636f43172f60
+ .dword 0x84c87814a1f0ab72, 0x8cc702081a6439ec
+ .dword 0x90befffa23631e28, 0xa4506cebde82bde9
+ .dword 0xbef9a3f7b2c67915, 0xc67178f2e372532b
+ .dword 0xca273eceea26619c, 0xd186b8c721c0c207
+ .dword 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178
+ .dword 0x06f067aa72176fba, 0x0a637dc5a2c898a6
+ .dword 0x113f9804bef90dae, 0x1b710b35131c471b
+ .dword 0x28db77f523047d84, 0x32caab7b40c72493
+ .dword 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c
+ .dword 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a
+ .dword 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
+___
+}
+$code.=<<___;
+.asciiz "SHA${label} for MIPS, CRYPTOGAMS by <appro\@openssl.org>"
+.align 5
+
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha512-parisc.pl b/deps/openssl/openssl/crypto/sha/asm/sha512-parisc.pl
new file mode 100755
index 000000000..e24ee58ae
--- /dev/null
+++ b/deps/openssl/openssl/crypto/sha/asm/sha512-parisc.pl
@@ -0,0 +1,791 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA256/512 block procedure for PA-RISC.
+
+# June 2009.
+#
+# SHA256 performance is >75% better than gcc 3.2 generated code on
+# PA-7100LC. Compared to code generated by vendor compiler this
+# implementation is almost 70% faster in 64-bit build, but delivers
+# virtually same performance in 32-bit build on PA-8600.
+#
+# SHA512 performance is >2.9x better than gcc 3.2 generated code on
+# PA-7100LC, PA-RISC 1.1 processor. Then implementation detects if the
+# code is executed on PA-RISC 2.0 processor and switches to 64-bit
+# code path delivering adequate peformance even in "blended" 32-bit
+# build. Though 64-bit code is not any faster than code generated by
+# vendor compiler on PA-8600...
+#
+# Special thanks to polarhome.com for providing HP-UX account.
+
+$flavour = shift;
+$output = shift;
+open STDOUT,">$output";
+
+if ($flavour =~ /64/) {
+ $LEVEL ="2.0W";
+ $SIZE_T =8;
+ $FRAME_MARKER =80;
+ $SAVED_RP =16;
+ $PUSH ="std";
+ $PUSHMA ="std,ma";
+ $POP ="ldd";
+ $POPMB ="ldd,mb";
+} else {
+ $LEVEL ="1.0";
+ $SIZE_T =4;
+ $FRAME_MARKER =48;
+ $SAVED_RP =20;
+ $PUSH ="stw";
+ $PUSHMA ="stwm";
+ $POP ="ldw";
+ $POPMB ="ldwm";
+}
+
+if ($output =~ /512/) {
+ $func="sha512_block_data_order";
+ $SZ=8;
+ @Sigma0=(28,34,39);
+ @Sigma1=(14,18,41);
+ @sigma0=(1, 8, 7);
+ @sigma1=(19,61, 6);
+ $rounds=80;
+ $LAST10BITS=0x017;
+ $LD="ldd";
+ $LDM="ldd,ma";
+ $ST="std";
+} else {
+ $func="sha256_block_data_order";
+ $SZ=4;
+ @Sigma0=( 2,13,22);
+ @Sigma1=( 6,11,25);
+ @sigma0=( 7,18, 3);
+ @sigma1=(17,19,10);
+ $rounds=64;
+ $LAST10BITS=0x0f2;
+ $LD="ldw";
+ $LDM="ldwm";
+ $ST="stw";
+}
+
+$FRAME=16*$SIZE_T+$FRAME_MARKER;# 16 saved regs + frame marker
+ # [+ argument transfer]
+$XOFF=16*$SZ+32; # local variables
+$FRAME+=$XOFF;
+$XOFF+=$FRAME_MARKER; # distance between %sp and local variables
+
+$ctx="%r26"; # zapped by $a0
+$inp="%r25"; # zapped by $a1
+$num="%r24"; # zapped by $t0
+
+$a0 ="%r26";
+$a1 ="%r25";
+$t0 ="%r24";
+$t1 ="%r29";
+$Tbl="%r31";
+
+@V=($A,$B,$C,$D,$E,$F,$G,$H)=("%r17","%r18","%r19","%r20","%r21","%r22","%r23","%r28");
+
+@X=("%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8",
+ "%r9", "%r10","%r11","%r12","%r13","%r14","%r15","%r16",$inp);
+
+sub ROUND_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+$code.=<<___;
+ _ror $e,$Sigma1[0],$a0
+ and $f,$e,$t0
+ _ror $e,$Sigma1[1],$a1
+ addl $t1,$h,$h
+ andcm $g,$e,$t1
+ xor $a1,$a0,$a0
+ _ror $a1,`$Sigma1[2]-$Sigma1[1]`,$a1
+ or $t0,$t1,$t1 ; Ch(e,f,g)
+ addl @X[$i%16],$h,$h
+ xor $a0,$a1,$a1 ; Sigma1(e)
+ addl $t1,$h,$h
+ _ror $a,$Sigma0[0],$a0
+ addl $a1,$h,$h
+
+ _ror $a,$Sigma0[1],$a1
+ and $a,$b,$t0
+ and $a,$c,$t1
+ xor $a1,$a0,$a0
+ _ror $a1,`$Sigma0[2]-$Sigma0[1]`,$a1
+ xor $t1,$t0,$t0
+ and $b,$c,$t1
+ xor $a0,$a1,$a1 ; Sigma0(a)
+ addl $h,$d,$d
+ xor $t1,$t0,$t0 ; Maj(a,b,c)
+ `"$LDM $SZ($Tbl),$t1" if ($i<15)`
+ addl $a1,$h,$h
+ addl $t0,$h,$h
+
+___
+}
+
+sub ROUND_16_xx {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+$i-=16;
+$code.=<<___;
+ _ror @X[($i+1)%16],$sigma0[0],$a0
+ _ror @X[($i+1)%16],$sigma0[1],$a1
+ addl @X[($i+9)%16],@X[$i],@X[$i]
+ _ror @X[($i+14)%16],$sigma1[0],$t0
+ _ror @X[($i+14)%16],$sigma1[1],$t1
+ xor $a1,$a0,$a0
+ _shr @X[($i+1)%16],$sigma0[2],$a1
+ xor $t1,$t0,$t0
+ _shr @X[($i+14)%16],$sigma1[2],$t1
+ xor $a1,$a0,$a0 ; sigma0(X[(i+1)&0x0f])
+ xor $t1,$t0,$t0 ; sigma1(X[(i+14)&0x0f])
+ $LDM $SZ($Tbl),$t1
+ addl $a0,@X[$i],@X[$i]
+ addl $t0,@X[$i],@X[$i]
+___
+$code.=<<___ if ($i==15);
+ extru $t1,31,10,$a1
+ comiclr,<> $LAST10BITS,$a1,%r0
+ ldo 1($Tbl),$Tbl ; signal end of $Tbl
+___
+&ROUND_00_15($i+16,$a,$b,$c,$d,$e,$f,$g,$h);
+}
+
+$code=<<___;
+ .LEVEL $LEVEL
+ .SPACE \$TEXT\$
+ .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
+
+ .ALIGN 64
+L\$table
+___
+$code.=<<___ if ($SZ==8);
+ .WORD 0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd
+ .WORD 0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc
+ .WORD 0x3956c25b,0xf348b538,0x59f111f1,0xb605d019
+ .WORD 0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118
+ .WORD 0xd807aa98,0xa3030242,0x12835b01,0x45706fbe
+ .WORD 0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2
+ .WORD 0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1
+ .WORD 0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694
+ .WORD 0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3
+ .WORD 0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65
+ .WORD 0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483
+ .WORD 0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5
+ .WORD 0x983e5152,0xee66dfab,0xa831c66d,0x2db43210
+ .WORD 0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4
+ .WORD 0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725
+ .WORD 0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70
+ .WORD 0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926
+ .WORD 0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df
+ .WORD 0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8
+ .WORD 0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b
+ .WORD 0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001
+ .WORD 0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30
+ .WORD 0xd192e819,0xd6ef5218,0xd6990624,0x5565a910
+ .WORD 0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8
+ .WORD 0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53
+ .WORD 0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8
+ .WORD 0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb
+ .WORD 0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3
+ .WORD 0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60
+ .WORD 0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec
+ .WORD 0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9
+ .WORD 0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b
+ .WORD 0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207
+ .WORD 0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178
+ .WORD 0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6
+ .WORD 0x113f9804,0xbef90dae,0x1b710b35,0x131c471b
+ .WORD 0x28db77f5,0x23047d84,0x32caab7b,0x40c72493
+ .WORD 0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c
+ .WORD 0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a
+ .WORD 0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817
+___
+$code.=<<___ if ($SZ==4);
+ .WORD 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+ .WORD 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+ .WORD 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+ .WORD 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+ .WORD 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+ .WORD 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+ .WORD 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+ .WORD 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+ .WORD 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+ .WORD 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+ .WORD 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+ .WORD 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+ .WORD 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+ .WORD 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+ .WORD 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+ .WORD 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+___
+$code.=<<___;
+
+ .EXPORT $func,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
+ .ALIGN 64
+$func
+ .PROC
+ .CALLINFO FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18
+ .ENTRY
+ $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue
+ $PUSHMA %r3,$FRAME(%sp)
+ $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp)
+ $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp)
+ $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp)
+ $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp)
+ $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp)
+ $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp)
+ $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp)
+ $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp)
+ $PUSH %r12,`-$FRAME+9*$SIZE_T`(%sp)
+ $PUSH %r13,`-$FRAME+10*$SIZE_T`(%sp)
+ $PUSH %r14,`-$FRAME+11*$SIZE_T`(%sp)
+ $PUSH %r15,`-$FRAME+12*$SIZE_T`(%sp)
+ $PUSH %r16,`-$FRAME+13*$SIZE_T`(%sp)
+ $PUSH %r17,`-$FRAME+14*$SIZE_T`(%sp)
+ $PUSH %r18,`-$FRAME+15*$SIZE_T`(%sp)
+
+ _shl $num,`log(16*$SZ)/log(2)`,$num
+ addl $inp,$num,$num ; $num to point at the end of $inp
+
+ $PUSH $num,`-$FRAME_MARKER-4*$SIZE_T`(%sp) ; save arguments
+ $PUSH $inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp)
+ $PUSH $ctx,`-$FRAME_MARKER-2*$SIZE_T`(%sp)
+
+ blr %r0,$Tbl
+ ldi 3,$t1
+L\$pic
+ andcm $Tbl,$t1,$Tbl ; wipe privilege level
+ ldo L\$table-L\$pic($Tbl),$Tbl
+___
+$code.=<<___ if ($SZ==8 && $SIZE_T==4);
+ ldi 31,$t1
+ mtctl $t1,%cr11
+ extrd,u,*= $t1,%sar,1,$t1 ; executes on PA-RISC 1.0
+ b L\$parisc1
+ nop
+___
+$code.=<<___;
+ $LD `0*$SZ`($ctx),$A ; load context
+ $LD `1*$SZ`($ctx),$B
+ $LD `2*$SZ`($ctx),$C
+ $LD `3*$SZ`($ctx),$D
+ $LD `4*$SZ`($ctx),$E
+ $LD `5*$SZ`($ctx),$F
+ $LD `6*$SZ`($ctx),$G
+ $LD `7*$SZ`($ctx),$H
+
+ extru $inp,31,`log($SZ)/log(2)`,$t0
+ sh3addl $t0,%r0,$t0
+ subi `8*$SZ`,$t0,$t0
+ mtctl $t0,%cr11 ; load %sar with align factor
+
+L\$oop
+ ldi `$SZ-1`,$t0
+ $LDM $SZ($Tbl),$t1
+ andcm $inp,$t0,$t0 ; align $inp
+___
+ for ($i=0;$i<15;$i++) { # load input block
+ $code.="\t$LD `$SZ*$i`($t0),@X[$i]\n"; }
+$code.=<<___;
+ cmpb,*= $inp,$t0,L\$aligned
+ $LD `$SZ*15`($t0),@X[15]
+ $LD `$SZ*16`($t0),@X[16]
+___
+ for ($i=0;$i<16;$i++) { # align data
+ $code.="\t_align @X[$i],@X[$i+1],@X[$i]\n"; }
+$code.=<<___;
+L\$aligned
+ nop ; otherwise /usr/ccs/bin/as is confused by below .WORD
+___
+
+for($i=0;$i<16;$i++) { &ROUND_00_15($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+L\$rounds
+ nop ; otherwise /usr/ccs/bin/as is confused by below .WORD
+___
+for(;$i<32;$i++) { &ROUND_16_xx($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+ bb,>= $Tbl,31,L\$rounds ; end of $Tbl signalled?
+ nop
+
+ $POP `-$FRAME_MARKER-2*$SIZE_T`(%sp),$ctx ; restore arguments
+ $POP `-$FRAME_MARKER-3*$SIZE_T`(%sp),$inp
+ $POP `-$FRAME_MARKER-4*$SIZE_T`(%sp),$num
+ ldo `-$rounds*$SZ-1`($Tbl),$Tbl ; rewind $Tbl
+
+ $LD `0*$SZ`($ctx),@X[0] ; load context
+ $LD `1*$SZ`($ctx),@X[1]
+ $LD `2*$SZ`($ctx),@X[2]
+ $LD `3*$SZ`($ctx),@X[3]
+ $LD `4*$SZ`($ctx),@X[4]
+ $LD `5*$SZ`($ctx),@X[5]
+ addl @X[0],$A,$A
+ $LD `6*$SZ`($ctx),@X[6]
+ addl @X[1],$B,$B
+ $LD `7*$SZ`($ctx),@X[7]
+ ldo `16*$SZ`($inp),$inp ; advance $inp
+
+ $ST $A,`0*$SZ`($ctx) ; save context
+ addl @X[2],$C,$C
+ $ST $B,`1*$SZ`($ctx)
+ addl @X[3],$D,$D
+ $ST $C,`2*$SZ`($ctx)
+ addl @X[4],$E,$E
+ $ST $D,`3*$SZ`($ctx)
+ addl @X[5],$F,$F
+ $ST $E,`4*$SZ`($ctx)
+ addl @X[6],$G,$G
+ $ST $F,`5*$SZ`($ctx)
+ addl @X[7],$H,$H
+ $ST $G,`6*$SZ`($ctx)
+ $ST $H,`7*$SZ`($ctx)
+
+ cmpb,*<>,n $inp,$num,L\$oop
+ $PUSH $inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp) ; save $inp
+___
+if ($SZ==8 && $SIZE_T==4) # SHA512 for 32-bit PA-RISC 1.0
+{{
+$code.=<<___;
+ b L\$done
+ nop
+
+ .ALIGN 64
+L\$parisc1
+___
+
+@V=( $Ahi, $Alo, $Bhi, $Blo, $Chi, $Clo, $Dhi, $Dlo,
+ $Ehi, $Elo, $Fhi, $Flo, $Ghi, $Glo, $Hhi, $Hlo) =
+ ( "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8",
+ "%r9","%r10","%r11","%r12","%r13","%r14","%r15","%r16");
+$a0 ="%r17";
+$a1 ="%r18";
+$a2 ="%r19";
+$a3 ="%r20";
+$t0 ="%r21";
+$t1 ="%r22";
+$t2 ="%r28";
+$t3 ="%r29";
+$Tbl="%r31";
+
+@X=("%r23","%r24","%r25","%r26"); # zaps $num,$inp,$ctx
+
+sub ROUND_00_15_pa1 {
+my ($i,$ahi,$alo,$bhi,$blo,$chi,$clo,$dhi,$dlo,
+ $ehi,$elo,$fhi,$flo,$ghi,$glo,$hhi,$hlo,$flag)=@_;
+my ($Xhi,$Xlo,$Xnhi,$Xnlo) = @X;
+
+$code.=<<___ if (!$flag);
+ ldw `-$XOFF+8*(($i+1)%16)`(%sp),$Xnhi
+ ldw `-$XOFF+8*(($i+1)%16)+4`(%sp),$Xnlo ; load X[i+1]
+___
+$code.=<<___;
+ shd $ehi,$elo,$Sigma1[0],$t0
+ add $Xlo,$hlo,$hlo
+ shd $elo,$ehi,$Sigma1[0],$t1
+ addc $Xhi,$hhi,$hhi ; h += X[i]
+ shd $ehi,$elo,$Sigma1[1],$t2
+ ldwm 8($Tbl),$Xhi
+ shd $elo,$ehi,$Sigma1[1],$t3
+ ldw -4($Tbl),$Xlo ; load K[i]
+ xor $t2,$t0,$t0
+ xor $t3,$t1,$t1
+ and $flo,$elo,$a0
+ and $fhi,$ehi,$a1
+ shd $ehi,$elo,$Sigma1[2],$t2
+ andcm $glo,$elo,$a2
+ shd $elo,$ehi,$Sigma1[2],$t3
+ andcm $ghi,$ehi,$a3
+ xor $t2,$t0,$t0
+ xor $t3,$t1,$t1 ; Sigma1(e)
+ add $Xlo,$hlo,$hlo
+ xor $a2,$a0,$a0
+ addc $Xhi,$hhi,$hhi ; h += K[i]
+ xor $a3,$a1,$a1 ; Ch(e,f,g)
+
+ add $t0,$hlo,$hlo
+ shd $ahi,$alo,$Sigma0[0],$t0
+ addc $t1,$hhi,$hhi ; h += Sigma1(e)
+ shd $alo,$ahi,$Sigma0[0],$t1
+ add $a0,$hlo,$hlo
+ shd $ahi,$alo,$Sigma0[1],$t2
+ addc $a1,$hhi,$hhi ; h += Ch(e,f,g)
+ shd $alo,$ahi,$Sigma0[1],$t3
+
+ xor $t2,$t0,$t0
+ xor $t3,$t1,$t1
+ shd $ahi,$alo,$Sigma0[2],$t2
+ and $alo,$blo,$a0
+ shd $alo,$ahi,$Sigma0[2],$t3
+ and $ahi,$bhi,$a1
+ xor $t2,$t0,$t0
+ xor $t3,$t1,$t1 ; Sigma0(a)
+
+ and $alo,$clo,$a2
+ and $ahi,$chi,$a3
+ xor $a2,$a0,$a0
+ add $hlo,$dlo,$dlo
+ xor $a3,$a1,$a1
+ addc $hhi,$dhi,$dhi ; d += h
+ and $blo,$clo,$a2
+ add $t0,$hlo,$hlo
+ and $bhi,$chi,$a3
+ addc $t1,$hhi,$hhi ; h += Sigma0(a)
+ xor $a2,$a0,$a0
+ add $a0,$hlo,$hlo
+ xor $a3,$a1,$a1 ; Maj(a,b,c)
+ addc $a1,$hhi,$hhi ; h += Maj(a,b,c)
+
+___
+$code.=<<___ if ($i==15 && $flag);
+ extru $Xlo,31,10,$Xlo
+ comiclr,= $LAST10BITS,$Xlo,%r0
+ b L\$rounds_pa1
+ nop
+___
+push(@X,shift(@X)); push(@X,shift(@X));
+}
+
+sub ROUND_16_xx_pa1 {
+my ($Xhi,$Xlo,$Xnhi,$Xnlo) = @X;
+my ($i)=shift;
+$i-=16;
+$code.=<<___;
+ ldw `-$XOFF+8*(($i+1)%16)`(%sp),$Xnhi
+ ldw `-$XOFF+8*(($i+1)%16)+4`(%sp),$Xnlo ; load X[i+1]
+ ldw `-$XOFF+8*(($i+9)%16)`(%sp),$a1
+ ldw `-$XOFF+8*(($i+9)%16)+4`(%sp),$a0 ; load X[i+9]
+ ldw `-$XOFF+8*(($i+14)%16)`(%sp),$a3
+ ldw `-$XOFF+8*(($i+14)%16)+4`(%sp),$a2 ; load X[i+14]
+ shd $Xnhi,$Xnlo,$sigma0[0],$t0
+ shd $Xnlo,$Xnhi,$sigma0[0],$t1
+ add $a0,$Xlo,$Xlo
+ shd $Xnhi,$Xnlo,$sigma0[1],$t2
+ addc $a1,$Xhi,$Xhi
+ shd $Xnlo,$Xnhi,$sigma0[1],$t3
+ xor $t2,$t0,$t0
+ shd $Xnhi,$Xnlo,$sigma0[2],$t2
+ xor $t3,$t1,$t1
+ extru $Xnhi,`31-$sigma0[2]`,`32-$sigma0[2]`,$t3
+ xor $t2,$t0,$t0
+ shd $a3,$a2,$sigma1[0],$a0
+ xor $t3,$t1,$t1 ; sigma0(X[i+1)&0x0f])
+ shd $a2,$a3,$sigma1[0],$a1
+ add $t0,$Xlo,$Xlo
+ shd $a3,$a2,$sigma1[1],$t2
+ addc $t1,$Xhi,$Xhi
+ shd $a2,$a3,$sigma1[1],$t3
+ xor $t2,$a0,$a0
+ shd $a3,$a2,$sigma1[2],$t2
+ xor $t3,$a1,$a1
+ extru $a3,`31-$sigma1[2]`,`32-$sigma1[2]`,$t3
+ xor $t2,$a0,$a0
+ xor $t3,$a1,$a1 ; sigma0(X[i+14)&0x0f])
+ add $a0,$Xlo,$Xlo
+ addc $a1,$Xhi,$Xhi
+
+ stw $Xhi,`-$XOFF+8*($i%16)`(%sp)
+ stw $Xlo,`-$XOFF+8*($i%16)+4`(%sp)
+___
+&ROUND_00_15_pa1($i,@_,1);
+}
+$code.=<<___;
+ ldw `0*4`($ctx),$Ahi ; load context
+ ldw `1*4`($ctx),$Alo
+ ldw `2*4`($ctx),$Bhi
+ ldw `3*4`($ctx),$Blo
+ ldw `4*4`($ctx),$Chi
+ ldw `5*4`($ctx),$Clo
+ ldw `6*4`($ctx),$Dhi
+ ldw `7*4`($ctx),$Dlo
+ ldw `8*4`($ctx),$Ehi
+ ldw `9*4`($ctx),$Elo
+ ldw `10*4`($ctx),$Fhi
+ ldw `11*4`($ctx),$Flo
+ ldw `12*4`($ctx),$Ghi
+ ldw `13*4`($ctx),$Glo
+ ldw `14*4`($ctx),$Hhi
+ ldw `15*4`($ctx),$Hlo
+
+ extru $inp,31,2,$t0
+ sh3addl $t0,%r0,$t0
+ subi 32,$t0,$t0
+ mtctl $t0,%cr11 ; load %sar with align factor
+
+L\$oop_pa1
+ extru $inp,31,2,$a3
+ comib,= 0,$a3,L\$aligned_pa1
+ sub $inp,$a3,$inp
+
+ ldw `0*4`($inp),$X[0]
+ ldw `1*4`($inp),$X[1]
+ ldw `2*4`($inp),$t2
+ ldw `3*4`($inp),$t3
+ ldw `4*4`($inp),$a0
+ ldw `5*4`($inp),$a1
+ ldw `6*4`($inp),$a2
+ ldw `7*4`($inp),$a3
+ vshd $X[0],$X[1],$X[0]
+ vshd $X[1],$t2,$X[1]
+ stw $X[0],`-$XOFF+0*4`(%sp)
+ ldw `8*4`($inp),$t0
+ vshd $t2,$t3,$t2
+ stw $X[1],`-$XOFF+1*4`(%sp)
+ ldw `9*4`($inp),$t1
+ vshd $t3,$a0,$t3
+___
+{
+my @t=($t2,$t3,$a0,$a1,$a2,$a3,$t0,$t1);
+for ($i=2;$i<=(128/4-8);$i++) {
+$code.=<<___;
+ stw $t[0],`-$XOFF+$i*4`(%sp)
+ ldw `(8+$i)*4`($inp),$t[0]
+ vshd $t[1],$t[2],$t[1]
+___
+push(@t,shift(@t));
+}
+for (;$i<(128/4-1);$i++) {
+$code.=<<___;
+ stw $t[0],`-$XOFF+$i*4`(%sp)
+ vshd $t[1],$t[2],$t[1]
+___
+push(@t,shift(@t));
+}
+$code.=<<___;
+ b L\$collected_pa1
+ stw $t[0],`-$XOFF+$i*4`(%sp)
+
+___
+}
+$code.=<<___;
+L\$aligned_pa1
+ ldw `0*4`($inp),$X[0]
+ ldw `1*4`($inp),$X[1]
+ ldw `2*4`($inp),$t2
+ ldw `3*4`($inp),$t3
+ ldw `4*4`($inp),$a0
+ ldw `5*4`($inp),$a1
+ ldw `6*4`($inp),$a2
+ ldw `7*4`($inp),$a3
+ stw $X[0],`-$XOFF+0*4`(%sp)
+ ldw `8*4`($inp),$t0
+ stw $X[1],`-$XOFF+1*4`(%sp)
+ ldw `9*4`($inp),$t1
+___
+{
+my @t=($t2,$t3,$a0,$a1,$a2,$a3,$t0,$t1);
+for ($i=2;$i<(128/4-8);$i++) {
+$code.=<<___;
+ stw $t[0],`-$XOFF+$i*4`(%sp)
+ ldw `(8+$i)*4`($inp),$t[0]
+___
+push(@t,shift(@t));
+}
+for (;$i<128/4;$i++) {
+$code.=<<___;
+ stw $t[0],`-$XOFF+$i*4`(%sp)
+___
+push(@t,shift(@t));
+}
+$code.="L\$collected_pa1\n";
+}
+
+for($i=0;$i<16;$i++) { &ROUND_00_15_pa1($i,@V); unshift(@V,pop(@V)); unshift(@V,pop(@V)); }
+$code.="L\$rounds_pa1\n";
+for(;$i<32;$i++) { &ROUND_16_xx_pa1($i,@V); unshift(@V,pop(@V)); unshift(@V,pop(@V)); }
+
+$code.=<<___;
+ $POP `-$FRAME_MARKER-2*$SIZE_T`(%sp),$ctx ; restore arguments
+ $POP `-$FRAME_MARKER-3*$SIZE_T`(%sp),$inp
+ $POP `-$FRAME_MARKER-4*$SIZE_T`(%sp),$num
+ ldo `-$rounds*$SZ`($Tbl),$Tbl ; rewind $Tbl
+
+ ldw `0*4`($ctx),$t1 ; update context
+ ldw `1*4`($ctx),$t0
+ ldw `2*4`($ctx),$t3
+ ldw `3*4`($ctx),$t2
+ ldw `4*4`($ctx),$a1
+ ldw `5*4`($ctx),$a0
+ ldw `6*4`($ctx),$a3
+ add $t0,$Alo,$Alo
+ ldw `7*4`($ctx),$a2
+ addc $t1,$Ahi,$Ahi
+ ldw `8*4`($ctx),$t1
+ add $t2,$Blo,$Blo
+ ldw `9*4`($ctx),$t0
+ addc $t3,$Bhi,$Bhi
+ ldw `10*4`($ctx),$t3
+ add $a0,$Clo,$Clo
+ ldw `11*4`($ctx),$t2
+ addc $a1,$Chi,$Chi
+ ldw `12*4`($ctx),$a1
+ add $a2,$Dlo,$Dlo
+ ldw `13*4`($ctx),$a0
+ addc $a3,$Dhi,$Dhi
+ ldw `14*4`($ctx),$a3
+ add $t0,$Elo,$Elo
+ ldw `15*4`($ctx),$a2
+ addc $t1,$Ehi,$Ehi
+ stw $Ahi,`0*4`($ctx)
+ add $t2,$Flo,$Flo
+ stw $Alo,`1*4`($ctx)
+ addc $t3,$Fhi,$Fhi
+ stw $Bhi,`2*4`($ctx)
+ add $a0,$Glo,$Glo
+ stw $Blo,`3*4`($ctx)
+ addc $a1,$Ghi,$Ghi
+ stw $Chi,`4*4`($ctx)
+ add $a2,$Hlo,$Hlo
+ stw $Clo,`5*4`($ctx)
+ addc $a3,$Hhi,$Hhi
+ stw $Dhi,`6*4`($ctx)
+ ldo `16*$SZ`($inp),$inp ; advance $inp
+ stw $Dlo,`7*4`($ctx)
+ stw $Ehi,`8*4`($ctx)
+ stw $Elo,`9*4`($ctx)
+ stw $Fhi,`10*4`($ctx)
+ stw $Flo,`11*4`($ctx)
+ stw $Ghi,`12*4`($ctx)
+ stw $Glo,`13*4`($ctx)
+ stw $Hhi,`14*4`($ctx)
+ comb,= $inp,$num,L\$done
+ stw $Hlo,`15*4`($ctx)
+ b L\$oop_pa1
+ $PUSH $inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp) ; save $inp
+L\$done
+___
+}}
+$code.=<<___;
+ $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue
+ $POP `-$FRAME+1*$SIZE_T`(%sp),%r4
+ $POP `-$FRAME+2*$SIZE_T`(%sp),%r5
+ $POP `-$FRAME+3*$SIZE_T`(%sp),%r6
+ $POP `-$FRAME+4*$SIZE_T`(%sp),%r7
+ $POP `-$FRAME+5*$SIZE_T`(%sp),%r8
+ $POP `-$FRAME+6*$SIZE_T`(%sp),%r9
+ $POP `-$FRAME+7*$SIZE_T`(%sp),%r10
+ $POP `-$FRAME+8*$SIZE_T`(%sp),%r11
+ $POP `-$FRAME+9*$SIZE_T`(%sp),%r12
+ $POP `-$FRAME+10*$SIZE_T`(%sp),%r13
+ $POP `-$FRAME+11*$SIZE_T`(%sp),%r14
+ $POP `-$FRAME+12*$SIZE_T`(%sp),%r15
+ $POP `-$FRAME+13*$SIZE_T`(%sp),%r16
+ $POP `-$FRAME+14*$SIZE_T`(%sp),%r17
+ $POP `-$FRAME+15*$SIZE_T`(%sp),%r18
+ bv (%r2)
+ .EXIT
+ $POPMB -$FRAME(%sp),%r3
+ .PROCEND
+ .STRINGZ "SHA`64*$SZ` block transform for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+# Explicitly encode PA-RISC 2.0 instructions used in this module, so
+# that it can be compiled with .LEVEL 1.0. It should be noted that I
+# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0
+# directive...
+
+my $ldd = sub {
+ my ($mod,$args) = @_;
+ my $orig = "ldd$mod\t$args";
+
+ if ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 3 suffices
+ { my $opcode=(0x14<<26)|($2<<21)|($3<<16)|(($1&0x1FF8)<<1)|(($1>>13)&1);
+ $opcode|=(1<<3) if ($mod =~ /^,m/);
+ $opcode|=(1<<2) if ($mod =~ /^,mb/);
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $std = sub {
+ my ($mod,$args) = @_;
+ my $orig = "std$mod\t$args";
+
+ if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/) # format 3 suffices
+ { my $opcode=(0x1c<<26)|($3<<21)|($1<<16)|(($2&0x1FF8)<<1)|(($2>>13)&1);
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $extrd = sub {
+ my ($mod,$args) = @_;
+ my $orig = "extrd$mod\t$args";
+
+ # I only have ",u" completer, it's implicitly encoded...
+ if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/) # format 15
+ { my $opcode=(0x36<<26)|($1<<21)|($4<<16);
+ my $len=32-$3;
+ $opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5); # encode pos
+ $opcode |= (($len&0x20)<<7)|($len&0x1f); # encode len
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/) # format 12
+ { my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9);
+ my $len=32-$2;
+ $opcode |= (($len&0x20)<<3)|($len&0x1f); # encode len
+ $opcode |= (1<<13) if ($mod =~ /,\**=/);
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+my $shrpd = sub {
+ my ($mod,$args) = @_;
+ my $orig = "shrpd$mod\t$args";
+
+ if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/) # format 14
+ { my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4;
+ my $cpos=63-$3;
+ $opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5); # encode sa
+ sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
+ }
+ elsif ($args =~ /%r([0-9]+),%r([0-9]+),%sar,%r([0-9]+)/) # format 11
+ { sprintf "\t.WORD\t0x%08x\t; %s",
+ (0x34<<26)|($2<<21)|($1<<16)|(1<<9)|$3,$orig;
+ }
+ else { "\t".$orig; }
+};
+
+sub assemble {
+ my ($mnemonic,$mod,$args)=@_;
+ my $opcode = eval("\$$mnemonic");
+
+ ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args";
+}
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/ge;
+
+ s/shd\s+(%r[0-9]+),(%r[0-9]+),([0-9]+)/
+ $3>31 ? sprintf("shd\t%$2,%$1,%d",$3-32) # rotation for >=32
+ : sprintf("shd\t%$1,%$2,%d",$3)/e or
+ # translate made up instructons: _ror, _shr, _align, _shl
+ s/_ror(\s+)(%r[0-9]+),/
+ ($SZ==4 ? "shd" : "shrpd")."$1$2,$2,"/e or
+
+ s/_shr(\s+%r[0-9]+),([0-9]+),/
+ $SZ==4 ? sprintf("extru%s,%d,%d,",$1,31-$2,32-$2)
+ : sprintf("extrd,u%s,%d,%d,",$1,63-$2,64-$2)/e or
+
+ s/_align(\s+%r[0-9]+,%r[0-9]+),/
+ ($SZ==4 ? "vshd$1," : "shrpd$1,%sar,")/e or
+
+ s/_shl(\s+%r[0-9]+),([0-9]+),/
+ $SIZE_T==4 ? sprintf("zdep%s,%d,%d,",$1,31-$2,32-$2)
+ : sprintf("depd,z%s,%d,%d,",$1,63-$2,64-$2)/e;
+
+ s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e if ($SIZE_T==4);
+
+ s/cmpb,\*/comb,/ if ($SIZE_T==4);
+
+ print $_,"\n";
+}
+
+close STDOUT;
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha512-ppc.pl b/deps/openssl/openssl/crypto/sha/asm/sha512-ppc.pl
index 768a6a6fa..6b44a68e5 100644..100755
--- a/deps/openssl/openssl/crypto/sha/asm/sha512-ppc.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha512-ppc.pl
@@ -40,6 +40,7 @@ $output =shift;
if ($flavour =~ /64/) {
$SIZE_T=8;
+ $LRSAVE=2*$SIZE_T;
$STU="stdu";
$UCMP="cmpld";
$SHL="sldi";
@@ -47,6 +48,7 @@ if ($flavour =~ /64/) {
$PUSH="std";
} elsif ($flavour =~ /32/) {
$SIZE_T=4;
+ $LRSAVE=$SIZE_T;
$STU="stwu";
$UCMP="cmplw";
$SHL="slwi";
@@ -87,7 +89,8 @@ if ($output =~ /512/) {
$SHR="srwi";
}
-$FRAME=32*$SIZE_T;
+$FRAME=32*$SIZE_T+16*$SZ;
+$LOCALS=6*$SIZE_T;
$sp ="r1";
$toc="r2";
@@ -179,13 +182,12 @@ $code=<<___;
.globl $func
.align 6
$func:
+ $STU $sp,-$FRAME($sp)
mflr r0
- $STU $sp,`-($FRAME+16*$SZ)`($sp)
$SHL $num,$num,`log(16*$SZ)/log(2)`
$PUSH $ctx,`$FRAME-$SIZE_T*22`($sp)
- $PUSH r0,`$FRAME-$SIZE_T*21`($sp)
$PUSH $toc,`$FRAME-$SIZE_T*20`($sp)
$PUSH r13,`$FRAME-$SIZE_T*19`($sp)
$PUSH r14,`$FRAME-$SIZE_T*18`($sp)
@@ -206,6 +208,7 @@ $func:
$PUSH r29,`$FRAME-$SIZE_T*3`($sp)
$PUSH r30,`$FRAME-$SIZE_T*2`($sp)
$PUSH r31,`$FRAME-$SIZE_T*1`($sp)
+ $PUSH r0,`$FRAME+$LRSAVE`($sp)
$LD $A,`0*$SZ`($ctx)
mr $inp,r4 ; incarnate $inp
@@ -217,7 +220,7 @@ $func:
$LD $G,`6*$SZ`($ctx)
$LD $H,`7*$SZ`($ctx)
- b LPICmeup
+ bl LPICmeup
LPICedup:
andi. r0,$inp,3
bne Lunaligned
@@ -226,40 +229,14 @@ Laligned:
$PUSH $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer
$PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer
bl Lsha2_block_private
-Ldone:
- $POP r0,`$FRAME-$SIZE_T*21`($sp)
- $POP $toc,`$FRAME-$SIZE_T*20`($sp)
- $POP r13,`$FRAME-$SIZE_T*19`($sp)
- $POP r14,`$FRAME-$SIZE_T*18`($sp)
- $POP r15,`$FRAME-$SIZE_T*17`($sp)
- $POP r16,`$FRAME-$SIZE_T*16`($sp)
- $POP r17,`$FRAME-$SIZE_T*15`($sp)
- $POP r18,`$FRAME-$SIZE_T*14`($sp)
- $POP r19,`$FRAME-$SIZE_T*13`($sp)
- $POP r20,`$FRAME-$SIZE_T*12`($sp)
- $POP r21,`$FRAME-$SIZE_T*11`($sp)
- $POP r22,`$FRAME-$SIZE_T*10`($sp)
- $POP r23,`$FRAME-$SIZE_T*9`($sp)
- $POP r24,`$FRAME-$SIZE_T*8`($sp)
- $POP r25,`$FRAME-$SIZE_T*7`($sp)
- $POP r26,`$FRAME-$SIZE_T*6`($sp)
- $POP r27,`$FRAME-$SIZE_T*5`($sp)
- $POP r28,`$FRAME-$SIZE_T*4`($sp)
- $POP r29,`$FRAME-$SIZE_T*3`($sp)
- $POP r30,`$FRAME-$SIZE_T*2`($sp)
- $POP r31,`$FRAME-$SIZE_T*1`($sp)
- mtlr r0
- addi $sp,$sp,`$FRAME+16*$SZ`
- blr
-___
+ b Ldone
-# PowerPC specification allows an implementation to be ill-behaved
-# upon unaligned access which crosses page boundary. "Better safe
-# than sorry" principle makes me treat it specially. But I don't
-# look for particular offending word, but rather for the input
-# block which crosses the boundary. Once found that block is aligned
-# and hashed separately...
-$code.=<<___;
+; PowerPC specification allows an implementation to be ill-behaved
+; upon unaligned access which crosses page boundary. "Better safe
+; than sorry" principle makes me treat it specially. But I don't
+; look for particular offending word, but rather for the input
+; block which crosses the boundary. Once found that block is aligned
+; and hashed separately...
.align 4
Lunaligned:
subfic $t1,$inp,4096
@@ -278,7 +255,7 @@ Lunaligned:
Lcross_page:
li $t1,`16*$SZ/4`
mtctr $t1
- addi r20,$sp,$FRAME ; aligned spot below the frame
+ addi r20,$sp,$LOCALS ; aligned spot below the frame
Lmemcpy:
lbz r16,0($inp)
lbz r17,1($inp)
@@ -293,8 +270,8 @@ Lmemcpy:
bdnz Lmemcpy
$PUSH $inp,`$FRAME-$SIZE_T*26`($sp) ; save real inp
- addi $t1,$sp,`$FRAME+16*$SZ` ; fictitious end pointer
- addi $inp,$sp,$FRAME ; fictitious inp pointer
+ addi $t1,$sp,`$LOCALS+16*$SZ` ; fictitious end pointer
+ addi $inp,$sp,$LOCALS ; fictitious inp pointer
$PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real num
$PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; end pointer
$PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer
@@ -303,10 +280,36 @@ Lmemcpy:
$POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real num
addic. $num,$num,`-16*$SZ` ; num--
bne- Lunaligned
- b Ldone
-___
-$code.=<<___;
+Ldone:
+ $POP r0,`$FRAME+$LRSAVE`($sp)
+ $POP $toc,`$FRAME-$SIZE_T*20`($sp)
+ $POP r13,`$FRAME-$SIZE_T*19`($sp)
+ $POP r14,`$FRAME-$SIZE_T*18`($sp)
+ $POP r15,`$FRAME-$SIZE_T*17`($sp)
+ $POP r16,`$FRAME-$SIZE_T*16`($sp)
+ $POP r17,`$FRAME-$SIZE_T*15`($sp)
+ $POP r18,`$FRAME-$SIZE_T*14`($sp)
+ $POP r19,`$FRAME-$SIZE_T*13`($sp)
+ $POP r20,`$FRAME-$SIZE_T*12`($sp)
+ $POP r21,`$FRAME-$SIZE_T*11`($sp)
+ $POP r22,`$FRAME-$SIZE_T*10`($sp)
+ $POP r23,`$FRAME-$SIZE_T*9`($sp)
+ $POP r24,`$FRAME-$SIZE_T*8`($sp)
+ $POP r25,`$FRAME-$SIZE_T*7`($sp)
+ $POP r26,`$FRAME-$SIZE_T*6`($sp)
+ $POP r27,`$FRAME-$SIZE_T*5`($sp)
+ $POP r28,`$FRAME-$SIZE_T*4`($sp)
+ $POP r29,`$FRAME-$SIZE_T*3`($sp)
+ $POP r30,`$FRAME-$SIZE_T*2`($sp)
+ $POP r31,`$FRAME-$SIZE_T*1`($sp)
+ mtlr r0
+ addi $sp,$sp,$FRAME
+ blr
+ .long 0
+ .byte 0,12,4,1,0x80,18,3,0
+ .long 0
+
.align 4
Lsha2_block_private:
___
@@ -372,6 +375,8 @@ $code.=<<___;
$ST $H,`7*$SZ`($ctx)
bne Lsha2_block_private
blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
___
# Ugly hack here, because PPC assembler syntax seem to vary too
@@ -379,22 +384,15 @@ ___
$code.=<<___;
.align 6
LPICmeup:
- bl LPIC
- addi $Tbl,$Tbl,`64-4` ; "distance" between . and last nop
- b LPICedup
- nop
- nop
- nop
- nop
- nop
-LPIC: mflr $Tbl
+ mflr r0
+ bcl 20,31,\$+4
+ mflr $Tbl ; vvvvvv "distance" between . and 1st data entry
+ addi $Tbl,$Tbl,`64-8`
+ mtlr r0
blr
- nop
- nop
- nop
- nop
- nop
- nop
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
+ .space `64-9*4`
___
$code.=<<___ if ($SZ==8);
.long 0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha512-s390x.pl b/deps/openssl/openssl/crypto/sha/asm/sha512-s390x.pl
index e7ef2d5a9..079a3fc78 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha512-s390x.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha512-s390x.pl
@@ -26,6 +26,26 @@
# favour dual-issue z10 pipeline. Hardware SHA256/512 is ~4.7x faster
# than software.
+# November 2010.
+#
+# Adapt for -m31 build. If kernel supports what's called "highgprs"
+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
+# instructions and achieve "64-bit" performance even in 31-bit legacy
+# application context. The feature is not specific to any particular
+# processor, as long as it's "z-CPU". Latter implies that the code
+# remains z/Architecture specific. On z900 SHA256 was measured to
+# perform 2.4x and SHA512 - 13x better than code generated by gcc 4.3.
+
+$flavour = shift;
+
+if ($flavour =~ /3[12]/) {
+ $SIZE_T=4;
+ $g="";
+} else {
+ $SIZE_T=8;
+ $g="g";
+}
+
$t0="%r0";
$t1="%r1";
$ctx="%r2"; $t2="%r2";
@@ -44,7 +64,7 @@ $tbl="%r13";
$T1="%r14";
$sp="%r15";
-$output=shift;
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
if ($output =~ /512/) {
@@ -78,7 +98,8 @@ if ($output =~ /512/) {
}
$Func="sha${label}_block_data_order";
$Table="K${label}";
-$frame=160+16*$SZ;
+$stdframe=16*$SIZE_T+4*8;
+$frame=$stdframe+16*$SZ;
sub BODY_00_15 {
my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
@@ -93,9 +114,9 @@ $code.=<<___;
xgr $t0,$t1
$ROT $t1,$t1,`$Sigma1[2]-$Sigma1[1]`
xgr $t2,$g
- $ST $T1,`160+$SZ*($i%16)`($sp)
+ $ST $T1,`$stdframe+$SZ*($i%16)`($sp)
xgr $t0,$t1 # Sigma1(e)
- la $T1,0($T1,$h) # T1+=h
+ algr $T1,$h # T1+=h
ngr $t2,$e
lgr $t1,$a
algr $T1,$t0 # T1+=Sigma1(e)
@@ -113,7 +134,7 @@ $code.=<<___;
ngr $t2,$b
algr $h,$T1 # h+=T1
ogr $t2,$t1 # Maj(a,b,c)
- la $d,0($d,$T1) # d+=T1
+ algr $d,$T1 # d+=T1
algr $h,$t2 # h+=Maj(a,b,c)
___
}
@@ -122,19 +143,19 @@ sub BODY_16_XX {
my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
$code.=<<___;
- $LD $T1,`160+$SZ*(($i+1)%16)`($sp) ### $i
- $LD $t1,`160+$SZ*(($i+14)%16)`($sp)
+ $LD $T1,`$stdframe+$SZ*(($i+1)%16)`($sp) ### $i
+ $LD $t1,`$stdframe+$SZ*(($i+14)%16)`($sp)
$ROT $t0,$T1,$sigma0[0]
$SHR $T1,$sigma0[2]
$ROT $t2,$t0,`$sigma0[1]-$sigma0[0]`
xgr $T1,$t0
$ROT $t0,$t1,$sigma1[0]
- xgr $T1,$t2 # sigma0(X[i+1])
+ xgr $T1,$t2 # sigma0(X[i+1])
$SHR $t1,$sigma1[2]
- $ADD $T1,`160+$SZ*($i%16)`($sp) # +=X[i]
+ $ADD $T1,`$stdframe+$SZ*($i%16)`($sp) # +=X[i]
xgr $t1,$t0
$ROT $t0,$t0,`$sigma1[1]-$sigma1[0]`
- $ADD $T1,`160+$SZ*(($i+9)%16)`($sp) # +=X[i+9]
+ $ADD $T1,`$stdframe+$SZ*(($i+9)%16)`($sp) # +=X[i+9]
xgr $t1,$t0 # sigma1(X[i+14])
algr $T1,$t1 # +=sigma1(X[i+14])
___
@@ -212,6 +233,7 @@ $code.=<<___;
.globl $Func
.type $Func,\@function
$Func:
+ sllg $len,$len,`log(16*$SZ)/log(2)`
___
$code.=<<___ if ($kimdfunc);
larl %r1,OPENSSL_s390xcap_P
@@ -219,15 +241,15 @@ $code.=<<___ if ($kimdfunc);
tmhl %r0,0x4000 # check for message-security assist
jz .Lsoftware
lghi %r0,0
- la %r1,16($sp)
+ la %r1,`2*$SIZE_T`($sp)
.long 0xb93e0002 # kimd %r0,%r2
- lg %r0,16($sp)
+ lg %r0,`2*$SIZE_T`($sp)
tmhh %r0,`0x8000>>$kimdfunc`
jz .Lsoftware
lghi %r0,$kimdfunc
lgr %r1,$ctx
lgr %r2,$inp
- sllg %r3,$len,`log(16*$SZ)/log(2)`
+ lgr %r3,$len
.long 0xb93e0002 # kimd %r0,%r2
brc 1,.-4 # pay attention to "partial completion"
br %r14
@@ -235,13 +257,12 @@ $code.=<<___ if ($kimdfunc);
.Lsoftware:
___
$code.=<<___;
- sllg $len,$len,`log(16*$SZ)/log(2)`
lghi %r1,-$frame
- agr $len,$inp
- stmg $ctx,%r15,16($sp)
+ la $len,0($len,$inp)
+ stm${g} $ctx,%r15,`2*$SIZE_T`($sp)
lgr %r0,$sp
la $sp,0(%r1,$sp)
- stg %r0,0($sp)
+ st${g} %r0,0($sp)
larl $tbl,$Table
$LD $A,`0*$SZ`($ctx)
@@ -265,7 +286,7 @@ $code.=<<___;
clgr $len,$t0
jne .Lrounds_16_xx
- lg $ctx,`$frame+16`($sp)
+ l${g} $ctx,`$frame+2*$SIZE_T`($sp)
la $inp,`16*$SZ`($inp)
$ADD $A,`0*$SZ`($ctx)
$ADD $B,`1*$SZ`($ctx)
@@ -283,14 +304,14 @@ $code.=<<___;
$ST $F,`5*$SZ`($ctx)
$ST $G,`6*$SZ`($ctx)
$ST $H,`7*$SZ`($ctx)
- clg $inp,`$frame+32`($sp)
+ cl${g} $inp,`$frame+4*$SIZE_T`($sp)
jne .Lloop
- lmg %r6,%r15,`$frame+48`($sp)
+ lm${g} %r6,%r15,`$frame+6*$SIZE_T`($sp)
br %r14
.size $Func,.-$Func
.string "SHA${label} block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
-.comm OPENSSL_s390xcap_P,8,8
+.comm OPENSSL_s390xcap_P,16,8
___
$code =~ s/\`([^\`]*)\`/eval $1/gem;
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha512-sparcv9.pl b/deps/openssl/openssl/crypto/sha/asm/sha512-sparcv9.pl
index ec5d78135..585740789 100644
--- a/deps/openssl/openssl/crypto/sha/asm/sha512-sparcv9.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha512-sparcv9.pl
@@ -305,9 +305,9 @@ $code.=<<___;
srlx @X[(($i+9)/2)%8],32,$tmp1 ! X[i+9]
xor $tmp0,$tmp2,$tmp2 ! sigma1(X[i+14])
srl @X[($i/2)%8],0,$tmp0
+ add $tmp2,$tmp1,$tmp1
add $xi,$T1,$T1 ! +=X[i]
xor $tmp0,@X[($i/2)%8],@X[($i/2)%8]
- add $tmp2,$T1,$T1
add $tmp1,$T1,$T1
srl $T1,0,$T1
@@ -318,9 +318,9 @@ ___
$code.=<<___;
srlx @X[($i/2)%8],32,$tmp1 ! X[i]
xor $tmp0,$tmp2,$tmp2 ! sigma1(X[i+14])
- srl @X[($i/2)%8],0,@X[($i/2)%8]
add $xi,$T1,$T1 ! +=X[i+9]
- add $tmp2,$T1,$T1
+ add $tmp2,$tmp1,$tmp1
+ srl @X[($i/2)%8],0,@X[($i/2)%8]
add $tmp1,$T1,$T1
sllx $T1,32,$tmp0
diff --git a/deps/openssl/openssl/crypto/sha/asm/sha512-x86_64.pl b/deps/openssl/openssl/crypto/sha/asm/sha512-x86_64.pl
index e6643f8cf..8d5167855 100755
--- a/deps/openssl/openssl/crypto/sha/asm/sha512-x86_64.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/sha512-x86_64.pl
@@ -51,7 +51,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
if ($output =~ /512/) {
$func="sha512_block_data_order";
@@ -95,50 +96,44 @@ sub ROUND_00_15()
{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
$code.=<<___;
- mov $e,$a0
- mov $e,$a1
+ ror \$`$Sigma1[2]-$Sigma1[1]`,$a0
mov $f,$a2
+ mov $T1,`$SZ*($i&0xf)`(%rsp)
- ror \$$Sigma1[0],$a0
- ror \$$Sigma1[1],$a1
+ ror \$`$Sigma0[2]-$Sigma0[1]`,$a1
+ xor $e,$a0
xor $g,$a2 # f^g
- xor $a1,$a0
- ror \$`$Sigma1[2]-$Sigma1[1]`,$a1
+ ror \$`$Sigma1[1]-$Sigma1[0]`,$a0
+ add $h,$T1 # T1+=h
+ xor $a,$a1
+
+ add ($Tbl,$round,$SZ),$T1 # T1+=K[round]
and $e,$a2 # (f^g)&e
- mov $T1,`$SZ*($i&0xf)`(%rsp)
+ mov $b,$h
- xor $a1,$a0 # Sigma1(e)
+ ror \$`$Sigma0[1]-$Sigma0[0]`,$a1
+ xor $e,$a0
xor $g,$a2 # Ch(e,f,g)=((f^g)&e)^g
- add $h,$T1 # T1+=h
-
- mov $a,$h
- add $a0,$T1 # T1+=Sigma1(e)
+ xor $c,$h # b^c
+ xor $a,$a1
add $a2,$T1 # T1+=Ch(e,f,g)
- mov $a,$a0
- mov $a,$a1
+ mov $b,$a2
- ror \$$Sigma0[0],$h
- ror \$$Sigma0[1],$a0
- mov $a,$a2
- add ($Tbl,$round,$SZ),$T1 # T1+=K[round]
+ ror \$$Sigma1[0],$a0 # Sigma1(e)
+ and $a,$h # h=(b^c)&a
+ and $c,$a2 # b&c
- xor $a0,$h
- ror \$`$Sigma0[2]-$Sigma0[1]`,$a0
- or $c,$a1 # a|c
+ ror \$$Sigma0[0],$a1 # Sigma0(a)
+ add $a0,$T1 # T1+=Sigma1(e)
+ add $a2,$h # h+=b&c (completes +=Maj(a,b,c)
- xor $a0,$h # h=Sigma0(a)
- and $c,$a2 # a&c
add $T1,$d # d+=T1
-
- and $b,$a1 # (a|c)&b
add $T1,$h # h+=T1
-
- or $a2,$a1 # Maj(a,b,c)=((a|c)&b)|(a&c)
lea 1($round),$round # round++
+ add $a1,$h # h+=Sigma0(a)
- add $a1,$h # h+=Maj(a,b,c)
___
}
@@ -147,32 +142,30 @@ sub ROUND_16_XX()
$code.=<<___;
mov `$SZ*(($i+1)&0xf)`(%rsp),$a0
- mov `$SZ*(($i+14)&0xf)`(%rsp),$T1
-
- mov $a0,$a2
+ mov `$SZ*(($i+14)&0xf)`(%rsp),$a1
+ mov $a0,$T1
+ mov $a1,$a2
+ ror \$`$sigma0[1]-$sigma0[0]`,$T1
+ xor $a0,$T1
shr \$$sigma0[2],$a0
- ror \$$sigma0[0],$a2
-
- xor $a2,$a0
- ror \$`$sigma0[1]-$sigma0[0]`,$a2
- xor $a2,$a0 # sigma0(X[(i+1)&0xf])
- mov $T1,$a1
+ ror \$$sigma0[0],$T1
+ xor $T1,$a0 # sigma0(X[(i+1)&0xf])
+ mov `$SZ*(($i+9)&0xf)`(%rsp),$T1
- shr \$$sigma1[2],$T1
- ror \$$sigma1[0],$a1
-
- xor $a1,$T1
- ror \$`$sigma1[1]-$sigma1[0]`,$a1
-
- xor $a1,$T1 # sigma1(X[(i+14)&0xf])
+ ror \$`$sigma1[1]-$sigma1[0]`,$a2
+ xor $a1,$a2
+ shr \$$sigma1[2],$a1
+ ror \$$sigma1[0],$a2
add $a0,$T1
-
- add `$SZ*(($i+9)&0xf)`(%rsp),$T1
+ xor $a2,$a1 # sigma1(X[(i+14)&0xf])
add `$SZ*($i&0xf)`(%rsp),$T1
+ mov $e,$a0
+ add $a1,$T1
+ mov $a,$a1
___
&ROUND_00_15(@_);
}
@@ -219,6 +212,8 @@ $func:
___
for($i=0;$i<16;$i++) {
$code.=" mov $SZ*$i($inp),$T1\n";
+ $code.=" mov @ROT[4],$a0\n";
+ $code.=" mov @ROT[0],$a1\n";
$code.=" bswap $T1\n";
&ROUND_00_15($i,@ROT);
unshift(@ROT,pop(@ROT));
diff --git a/deps/openssl/openssl/crypto/sha/sha.h b/deps/openssl/openssl/crypto/sha/sha.h
index 16cacf9fc..8a6bf4bbb 100644
--- a/deps/openssl/openssl/crypto/sha/sha.h
+++ b/deps/openssl/openssl/crypto/sha/sha.h
@@ -106,6 +106,9 @@ typedef struct SHAstate_st
} SHA_CTX;
#ifndef OPENSSL_NO_SHA0
+#ifdef OPENSSL_FIPS
+int private_SHA_Init(SHA_CTX *c);
+#endif
int SHA_Init(SHA_CTX *c);
int SHA_Update(SHA_CTX *c, const void *data, size_t len);
int SHA_Final(unsigned char *md, SHA_CTX *c);
@@ -113,6 +116,9 @@ unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md);
void SHA_Transform(SHA_CTX *c, const unsigned char *data);
#endif
#ifndef OPENSSL_NO_SHA1
+#ifdef OPENSSL_FIPS
+int private_SHA1_Init(SHA_CTX *c);
+#endif
int SHA1_Init(SHA_CTX *c);
int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
int SHA1_Final(unsigned char *md, SHA_CTX *c);
@@ -135,6 +141,10 @@ typedef struct SHA256state_st
} SHA256_CTX;
#ifndef OPENSSL_NO_SHA256
+#ifdef OPENSSL_FIPS
+int private_SHA224_Init(SHA256_CTX *c);
+int private_SHA256_Init(SHA256_CTX *c);
+#endif
int SHA224_Init(SHA256_CTX *c);
int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA224_Final(unsigned char *md, SHA256_CTX *c);
@@ -182,6 +192,10 @@ typedef struct SHA512state_st
#endif
#ifndef OPENSSL_NO_SHA512
+#ifdef OPENSSL_FIPS
+int private_SHA384_Init(SHA512_CTX *c);
+int private_SHA512_Init(SHA512_CTX *c);
+#endif
int SHA384_Init(SHA512_CTX *c);
int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA384_Final(unsigned char *md, SHA512_CTX *c);
diff --git a/deps/openssl/openssl/crypto/sha/sha1_one.c b/deps/openssl/openssl/crypto/sha/sha1_one.c
index 7c65b6027..c56ec9402 100644
--- a/deps/openssl/openssl/crypto/sha/sha1_one.c
+++ b/deps/openssl/openssl/crypto/sha/sha1_one.c
@@ -58,8 +58,8 @@
#include <stdio.h>
#include <string.h>
-#include <openssl/sha.h>
#include <openssl/crypto.h>
+#include <openssl/sha.h>
#ifndef OPENSSL_NO_SHA1
unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
diff --git a/deps/openssl/openssl/crypto/sha/sha1dgst.c b/deps/openssl/openssl/crypto/sha/sha1dgst.c
index 50d1925cd..a98690225 100644
--- a/deps/openssl/openssl/crypto/sha/sha1dgst.c
+++ b/deps/openssl/openssl/crypto/sha/sha1dgst.c
@@ -56,6 +56,7 @@
* [including the GNU Public Licence.]
*/
+#include <openssl/crypto.h>
#include <openssl/opensslconf.h>
#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA)
diff --git a/deps/openssl/openssl/crypto/sha/sha256.c b/deps/openssl/openssl/crypto/sha/sha256.c
index 8952d8767..4eae07484 100644
--- a/deps/openssl/openssl/crypto/sha/sha256.c
+++ b/deps/openssl/openssl/crypto/sha/sha256.c
@@ -16,7 +16,7 @@
const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT;
-int SHA224_Init (SHA256_CTX *c)
+fips_md_init_ctx(SHA224, SHA256)
{
memset (c,0,sizeof(*c));
c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL;
@@ -27,7 +27,7 @@ int SHA224_Init (SHA256_CTX *c)
return 1;
}
-int SHA256_Init (SHA256_CTX *c)
+fips_md_init(SHA256)
{
memset (c,0,sizeof(*c));
c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL;
@@ -88,17 +88,17 @@ int SHA224_Final (unsigned char *md, SHA256_CTX *c)
switch ((c)->md_len) \
{ case SHA224_DIGEST_LENGTH: \
for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++) \
- { ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \
+ { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \
break; \
case SHA256_DIGEST_LENGTH: \
for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++) \
- { ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \
+ { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \
break; \
default: \
if ((c)->md_len > SHA256_DIGEST_LENGTH) \
return 0; \
for (nn=0;nn<(c)->md_len/4;nn++) \
- { ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \
+ { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \
break; \
} \
} while (0)
diff --git a/deps/openssl/openssl/crypto/sha/sha512.c b/deps/openssl/openssl/crypto/sha/sha512.c
index cbc0e58c4..50dd7dc74 100644
--- a/deps/openssl/openssl/crypto/sha/sha512.c
+++ b/deps/openssl/openssl/crypto/sha/sha512.c
@@ -59,21 +59,8 @@ const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT;
#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
#endif
-int SHA384_Init (SHA512_CTX *c)
+fips_md_init_ctx(SHA384, SHA512)
{
-#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
- /* maintain dword order required by assembler module */
- unsigned int *h = (unsigned int *)c->h;
-
- h[0] = 0xcbbb9d5d; h[1] = 0xc1059ed8;
- h[2] = 0x629a292a; h[3] = 0x367cd507;
- h[4] = 0x9159015a; h[5] = 0x3070dd17;
- h[6] = 0x152fecd8; h[7] = 0xf70e5939;
- h[8] = 0x67332667; h[9] = 0xffc00b31;
- h[10] = 0x8eb44a87; h[11] = 0x68581511;
- h[12] = 0xdb0c2e0d; h[13] = 0x64f98fa7;
- h[14] = 0x47b5481d; h[15] = 0xbefa4fa4;
-#else
c->h[0]=U64(0xcbbb9d5dc1059ed8);
c->h[1]=U64(0x629a292a367cd507);
c->h[2]=U64(0x9159015a3070dd17);
@@ -82,27 +69,14 @@ int SHA384_Init (SHA512_CTX *c)
c->h[5]=U64(0x8eb44a8768581511);
c->h[6]=U64(0xdb0c2e0d64f98fa7);
c->h[7]=U64(0x47b5481dbefa4fa4);
-#endif
+
c->Nl=0; c->Nh=0;
c->num=0; c->md_len=SHA384_DIGEST_LENGTH;
return 1;
}
-int SHA512_Init (SHA512_CTX *c)
+fips_md_init(SHA512)
{
-#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
- /* maintain dword order required by assembler module */
- unsigned int *h = (unsigned int *)c->h;
-
- h[0] = 0x6a09e667; h[1] = 0xf3bcc908;
- h[2] = 0xbb67ae85; h[3] = 0x84caa73b;
- h[4] = 0x3c6ef372; h[5] = 0xfe94f82b;
- h[6] = 0xa54ff53a; h[7] = 0x5f1d36f1;
- h[8] = 0x510e527f; h[9] = 0xade682d1;
- h[10] = 0x9b05688c; h[11] = 0x2b3e6c1f;
- h[12] = 0x1f83d9ab; h[13] = 0xfb41bd6b;
- h[14] = 0x5be0cd19; h[15] = 0x137e2179;
-#else
c->h[0]=U64(0x6a09e667f3bcc908);
c->h[1]=U64(0xbb67ae8584caa73b);
c->h[2]=U64(0x3c6ef372fe94f82b);
@@ -111,7 +85,7 @@ int SHA512_Init (SHA512_CTX *c)
c->h[5]=U64(0x9b05688c2b3e6c1f);
c->h[6]=U64(0x1f83d9abfb41bd6b);
c->h[7]=U64(0x5be0cd19137e2179);
-#endif
+
c->Nl=0; c->Nh=0;
c->num=0; c->md_len=SHA512_DIGEST_LENGTH;
return 1;
@@ -160,24 +134,6 @@ int SHA512_Final (unsigned char *md, SHA512_CTX *c)
if (md==0) return 0;
-#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
- /* recall assembler dword order... */
- n = c->md_len;
- if (n == SHA384_DIGEST_LENGTH || n == SHA512_DIGEST_LENGTH)
- {
- unsigned int *h = (unsigned int *)c->h, t;
-
- for (n/=4;n;n--)
- {
- t = *(h++);
- *(md++) = (unsigned char)(t>>24);
- *(md++) = (unsigned char)(t>>16);
- *(md++) = (unsigned char)(t>>8);
- *(md++) = (unsigned char)(t);
- }
- }
- else return 0;
-#else
switch (c->md_len)
{
/* Let compiler decide if it's appropriate to unroll... */
@@ -214,7 +170,7 @@ int SHA512_Final (unsigned char *md, SHA512_CTX *c)
/* ... as well as make sure md_len is not abused. */
default: return 0;
}
-#endif
+
return 1;
}
diff --git a/deps/openssl/openssl/crypto/sha/sha_dgst.c b/deps/openssl/openssl/crypto/sha/sha_dgst.c
index 70eb56032..fb63b17ff 100644
--- a/deps/openssl/openssl/crypto/sha/sha_dgst.c
+++ b/deps/openssl/openssl/crypto/sha/sha_dgst.c
@@ -56,6 +56,7 @@
* [including the GNU Public Licence.]
*/
+#include <openssl/crypto.h>
#include <openssl/opensslconf.h>
#if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA)
diff --git a/deps/openssl/openssl/crypto/sha/sha_locl.h b/deps/openssl/openssl/crypto/sha/sha_locl.h
index 672c26eee..d673255f7 100644
--- a/deps/openssl/openssl/crypto/sha/sha_locl.h
+++ b/deps/openssl/openssl/crypto/sha/sha_locl.h
@@ -69,11 +69,11 @@
#define HASH_CBLOCK SHA_CBLOCK
#define HASH_MAKE_STRING(c,s) do { \
unsigned long ll; \
- ll=(c)->h0; HOST_l2c(ll,(s)); \
- ll=(c)->h1; HOST_l2c(ll,(s)); \
- ll=(c)->h2; HOST_l2c(ll,(s)); \
- ll=(c)->h3; HOST_l2c(ll,(s)); \
- ll=(c)->h4; HOST_l2c(ll,(s)); \
+ ll=(c)->h0; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h1; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h2; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h3; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h4; (void)HOST_l2c(ll,(s)); \
} while (0)
#if defined(SHA_0)
@@ -122,7 +122,11 @@ void sha1_block_data_order (SHA_CTX *c, const void *p,size_t num);
#define INIT_DATA_h3 0x10325476UL
#define INIT_DATA_h4 0xc3d2e1f0UL
-int HASH_INIT (SHA_CTX *c)
+#ifdef SHA_0
+fips_md_init(SHA)
+#else
+fips_md_init_ctx(SHA1, SHA)
+#endif
{
memset (c,0,sizeof(*c));
c->h0=INIT_DATA_h0;
@@ -252,21 +256,21 @@ static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
}
else
{
- HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l;
- BODY_00_15( 0,A,B,C,D,E,T,X( 0)); HOST_c2l(data,l); X( 2)=l;
- BODY_00_15( 1,T,A,B,C,D,E,X( 1)); HOST_c2l(data,l); X( 3)=l;
- BODY_00_15( 2,E,T,A,B,C,D,X( 2)); HOST_c2l(data,l); X( 4)=l;
- BODY_00_15( 3,D,E,T,A,B,C,X( 3)); HOST_c2l(data,l); X( 5)=l;
- BODY_00_15( 4,C,D,E,T,A,B,X( 4)); HOST_c2l(data,l); X( 6)=l;
- BODY_00_15( 5,B,C,D,E,T,A,X( 5)); HOST_c2l(data,l); X( 7)=l;
- BODY_00_15( 6,A,B,C,D,E,T,X( 6)); HOST_c2l(data,l); X( 8)=l;
- BODY_00_15( 7,T,A,B,C,D,E,X( 7)); HOST_c2l(data,l); X( 9)=l;
- BODY_00_15( 8,E,T,A,B,C,D,X( 8)); HOST_c2l(data,l); X(10)=l;
- BODY_00_15( 9,D,E,T,A,B,C,X( 9)); HOST_c2l(data,l); X(11)=l;
- BODY_00_15(10,C,D,E,T,A,B,X(10)); HOST_c2l(data,l); X(12)=l;
- BODY_00_15(11,B,C,D,E,T,A,X(11)); HOST_c2l(data,l); X(13)=l;
- BODY_00_15(12,A,B,C,D,E,T,X(12)); HOST_c2l(data,l); X(14)=l;
- BODY_00_15(13,T,A,B,C,D,E,X(13)); HOST_c2l(data,l); X(15)=l;
+ (void)HOST_c2l(data,l); X( 0)=l; (void)HOST_c2l(data,l); X( 1)=l;
+ BODY_00_15( 0,A,B,C,D,E,T,X( 0)); (void)HOST_c2l(data,l); X( 2)=l;
+ BODY_00_15( 1,T,A,B,C,D,E,X( 1)); (void)HOST_c2l(data,l); X( 3)=l;
+ BODY_00_15( 2,E,T,A,B,C,D,X( 2)); (void)HOST_c2l(data,l); X( 4)=l;
+ BODY_00_15( 3,D,E,T,A,B,C,X( 3)); (void)HOST_c2l(data,l); X( 5)=l;
+ BODY_00_15( 4,C,D,E,T,A,B,X( 4)); (void)HOST_c2l(data,l); X( 6)=l;
+ BODY_00_15( 5,B,C,D,E,T,A,X( 5)); (void)HOST_c2l(data,l); X( 7)=l;
+ BODY_00_15( 6,A,B,C,D,E,T,X( 6)); (void)HOST_c2l(data,l); X( 8)=l;
+ BODY_00_15( 7,T,A,B,C,D,E,X( 7)); (void)HOST_c2l(data,l); X( 9)=l;
+ BODY_00_15( 8,E,T,A,B,C,D,X( 8)); (void)HOST_c2l(data,l); X(10)=l;
+ BODY_00_15( 9,D,E,T,A,B,C,X( 9)); (void)HOST_c2l(data,l); X(11)=l;
+ BODY_00_15(10,C,D,E,T,A,B,X(10)); (void)HOST_c2l(data,l); X(12)=l;
+ BODY_00_15(11,B,C,D,E,T,A,X(11)); (void)HOST_c2l(data,l); X(13)=l;
+ BODY_00_15(12,A,B,C,D,E,T,X(12)); (void)HOST_c2l(data,l); X(14)=l;
+ BODY_00_15(13,T,A,B,C,D,E,X(13)); (void)HOST_c2l(data,l); X(15)=l;
BODY_00_15(14,E,T,A,B,C,D,X(14));
BODY_00_15(15,D,E,T,A,B,C,X(15));
}
diff --git a/deps/openssl/openssl/crypto/sparccpuid.S b/deps/openssl/openssl/crypto/sparccpuid.S
index ae61f7f5c..0cc247e48 100644
--- a/deps/openssl/openssl/crypto/sparccpuid.S
+++ b/deps/openssl/openssl/crypto/sparccpuid.S
@@ -235,10 +235,10 @@ _sparcv9_rdtick:
.global _sparcv9_vis1_probe
.align 8
_sparcv9_vis1_probe:
- .word 0x81b00d80 !fxor %f0,%f0,%f0
add %sp,BIAS+2,%o1
- retl
.word 0xc19a5a40 !ldda [%o1]ASI_FP16_P,%f0
+ retl
+ .word 0x81b00d80 !fxor %f0,%f0,%f0
.type _sparcv9_vis1_probe,#function
.size _sparcv9_vis1_probe,.-_sparcv9_vis1_probe
diff --git a/deps/openssl/openssl/crypto/sparcv9cap.c b/deps/openssl/openssl/crypto/sparcv9cap.c
index ed195ab40..43b3ac6f8 100644
--- a/deps/openssl/openssl/crypto/sparcv9cap.c
+++ b/deps/openssl/openssl/crypto/sparcv9cap.c
@@ -19,7 +19,8 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_U
int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
- if ((OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
+ if (num>=8 && !(num&1) &&
+ (OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
(SPARCV9_PREFER_FPU|SPARCV9_VIS1))
return bn_mul_mont_fpu(rp,ap,bp,np,n0,num);
else
@@ -169,7 +170,6 @@ void OPENSSL_cpuid_setup(void)
char *e;
struct sigaction common_act,ill_oact,bus_oact;
sigset_t all_masked,oset;
- int sig;
static int trigger=0;
if (trigger) return;
diff --git a/deps/openssl/openssl/crypto/srp/Makefile b/deps/openssl/openssl/crypto/srp/Makefile
new file mode 100644
index 000000000..41859d46f
--- /dev/null
+++ b/deps/openssl/openssl/crypto/srp/Makefile
@@ -0,0 +1,98 @@
+DIR= srp
+TOP= ../..
+CC= cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKE= make -f Makefile.ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile.ssl
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=srptest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=srp_lib.c srp_vfy.c
+LIBOBJ=srp_lib.o srp_vfy.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= srp.h
+HEADER= $(EXHEADER)
+
+top:
+ (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ $(AR) $(LIB) $(LIBOBJ)
+ $(RANLIB) $(LIB) || echo Never mind.
+ @touch lib
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+ @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+ @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done;
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+srptest: top srptest.c $(LIB)
+ $(CC) $(CFLAGS) -Wall -Werror -g -o srptest srptest.c $(LIB)
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+srp_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+srp_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+srp_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+srp_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+srp_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+srp_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+srp_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+srp_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+srp_lib.o: ../../include/openssl/sha.h ../../include/openssl/srp.h
+srp_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+srp_lib.o: ../cryptlib.h srp_grps.h srp_lcl.h srp_lib.c
+srp_vfy.o: ../../e_os.h ../../include/openssl/asn1.h
+srp_vfy.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+srp_vfy.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+srp_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+srp_vfy.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+srp_vfy.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+srp_vfy.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+srp_vfy.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+srp_vfy.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+srp_vfy.o: ../../include/openssl/srp.h ../../include/openssl/stack.h
+srp_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/txt_db.h
+srp_vfy.o: ../cryptlib.h srp_lcl.h srp_vfy.c
diff --git a/deps/openssl/openssl/crypto/srp/srp.h b/deps/openssl/openssl/crypto/srp/srp.h
new file mode 100644
index 000000000..7ec7825ca
--- /dev/null
+++ b/deps/openssl/openssl/crypto/srp/srp.h
@@ -0,0 +1,172 @@
+/* crypto/srp/srp.h */
+/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
+ * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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
+ * licensing@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).
+ *
+ */
+#ifndef __SRP_H__
+#define __SRP_H__
+
+#ifndef OPENSSL_NO_SRP
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/safestack.h>
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+
+typedef struct SRP_gN_cache_st
+ {
+ char *b64_bn;
+ BIGNUM *bn;
+ } SRP_gN_cache;
+
+
+DECLARE_STACK_OF(SRP_gN_cache)
+
+typedef struct SRP_user_pwd_st
+ {
+ char *id;
+ BIGNUM *s;
+ BIGNUM *v;
+ const BIGNUM *g;
+ const BIGNUM *N;
+ char *info;
+ } SRP_user_pwd;
+
+DECLARE_STACK_OF(SRP_user_pwd)
+
+typedef struct SRP_VBASE_st
+ {
+ STACK_OF(SRP_user_pwd) *users_pwd;
+ STACK_OF(SRP_gN_cache) *gN_cache;
+/* to simulate a user */
+ char *seed_key;
+ BIGNUM *default_g;
+ BIGNUM *default_N;
+ } SRP_VBASE;
+
+
+/*Structure interne pour retenir les couples N et g*/
+typedef struct SRP_gN_st
+ {
+ char *id;
+ BIGNUM *g;
+ BIGNUM *N;
+ } SRP_gN;
+
+DECLARE_STACK_OF(SRP_gN)
+
+SRP_VBASE *SRP_VBASE_new(char *seed_key);
+int SRP_VBASE_free(SRP_VBASE *vb);
+int SRP_VBASE_init(SRP_VBASE *vb, char * verifier_file);
+SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username);
+char *SRP_create_verifier(const char *user, const char *pass, char **salt,
+ char **verifier, const char *N, const char *g);
+int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g);
+
+
+#define SRP_NO_ERROR 0
+#define SRP_ERR_VBASE_INCOMPLETE_FILE 1
+#define SRP_ERR_VBASE_BN_LIB 2
+#define SRP_ERR_OPEN_FILE 3
+#define SRP_ERR_MEMORY 4
+
+#define DB_srptype 0
+#define DB_srpverifier 1
+#define DB_srpsalt 2
+#define DB_srpid 3
+#define DB_srpgN 4
+#define DB_srpinfo 5
+#undef DB_NUMBER
+#define DB_NUMBER 6
+
+#define DB_SRP_INDEX 'I'
+#define DB_SRP_VALID 'V'
+#define DB_SRP_REVOKED 'R'
+#define DB_SRP_MODIF 'v'
+
+
+/* see srp.c */
+char * SRP_check_known_gN_param(BIGNUM* g, BIGNUM* N);
+SRP_gN *SRP_get_default_gN(const char * id) ;
+
+/* server side .... */
+BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N);
+BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v);
+int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N);
+BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) ;
+
+
+
+/* client side .... */
+BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass);
+BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g);
+BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u);
+int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N);
+
+#define SRP_MINIMAL_N 1024
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#endif
diff --git a/deps/openssl/openssl/crypto/srp/srp_grps.h b/deps/openssl/openssl/crypto/srp/srp_grps.h
new file mode 100644
index 000000000..d77c9fff4
--- /dev/null
+++ b/deps/openssl/openssl/crypto/srp/srp_grps.h
@@ -0,0 +1,517 @@
+/* start of generated data */
+
+static BN_ULONG bn_group_1024_value[] = {
+ bn_pack4(9FC6,1D2F,C0EB,06E3),
+ bn_pack4(FD51,38FE,8376,435B),
+ bn_pack4(2FD4,CBF4,976E,AA9A),
+ bn_pack4(68ED,BC3C,0572,6CC0),
+ bn_pack4(C529,F566,660E,57EC),
+ bn_pack4(8255,9B29,7BCF,1885),
+ bn_pack4(CE8E,F4AD,69B1,5D49),
+ bn_pack4(5DC7,D7B4,6154,D6B6),
+ bn_pack4(8E49,5C1D,6089,DAD1),
+ bn_pack4(E0D5,D8E2,50B9,8BE4),
+ bn_pack4(383B,4813,D692,C6E0),
+ bn_pack4(D674,DF74,96EA,81D3),
+ bn_pack4(9EA2,314C,9C25,6576),
+ bn_pack4(6072,6187,75FF,3C0B),
+ bn_pack4(9C33,F80A,FA8F,C5E8),
+ bn_pack4(EEAF,0AB9,ADB3,8DD6)
+};
+static BIGNUM bn_group_1024 = {
+ bn_group_1024_value,
+ (sizeof bn_group_1024_value)/sizeof(BN_ULONG),
+ (sizeof bn_group_1024_value)/sizeof(BN_ULONG),
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_1536_value[] = {
+ bn_pack4(CF76,E3FE,D135,F9BB),
+ bn_pack4(1518,0F93,499A,234D),
+ bn_pack4(8CE7,A28C,2442,C6F3),
+ bn_pack4(5A02,1FFF,5E91,479E),
+ bn_pack4(7F8A,2FE9,B8B5,292E),
+ bn_pack4(837C,264A,E3A9,BEB8),
+ bn_pack4(E442,734A,F7CC,B7AE),
+ bn_pack4(6577,2E43,7D6C,7F8C),
+ bn_pack4(DB2F,D53D,24B7,C486),
+ bn_pack4(6EDF,0195,3934,9627),
+ bn_pack4(158B,FD3E,2B9C,8CF5),
+ bn_pack4(764E,3F4B,53DD,9DA1),
+ bn_pack4(4754,8381,DBC5,B1FC),
+ bn_pack4(9B60,9E0B,E3BA,B63D),
+ bn_pack4(8134,B1C8,B979,8914),
+ bn_pack4(DF02,8A7C,EC67,F0D0),
+ bn_pack4(80B6,55BB,9A22,E8DC),
+ bn_pack4(1558,903B,A0D0,F843),
+ bn_pack4(51C6,A94B,E460,7A29),
+ bn_pack4(5F4F,5F55,6E27,CBDE),
+ bn_pack4(BEEE,A961,4B19,CC4D),
+ bn_pack4(DBA5,1DF4,99AC,4C80),
+ bn_pack4(B1F1,2A86,17A4,7BBB),
+ bn_pack4(9DEF,3CAF,B939,277A)
+};
+static BIGNUM bn_group_1536 = {
+ bn_group_1536_value,
+ (sizeof bn_group_1536_value)/sizeof(BN_ULONG),
+ (sizeof bn_group_1536_value)/sizeof(BN_ULONG),
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_2048_value[] = {
+ bn_pack4(0FA7,111F,9E4A,FF73),
+ bn_pack4(9B65,E372,FCD6,8EF2),
+ bn_pack4(35DE,236D,525F,5475),
+ bn_pack4(94B5,C803,D89F,7AE4),
+ bn_pack4(71AE,35F8,E9DB,FBB6),
+ bn_pack4(2A56,98F3,A8D0,C382),
+ bn_pack4(9CCC,041C,7BC3,08D8),
+ bn_pack4(AF87,4E73,03CE,5329),
+ bn_pack4(6160,2790,04E5,7AE6),
+ bn_pack4(032C,FBDB,F52F,B378),
+ bn_pack4(5EA7,7A27,75D2,ECFA),
+ bn_pack4(5445,23B5,24B0,D57D),
+ bn_pack4(5B9D,32E6,88F8,7748),
+ bn_pack4(F1D2,B907,8717,461A),
+ bn_pack4(76BD,207A,436C,6481),
+ bn_pack4(CA97,B43A,23FB,8016),
+ bn_pack4(1D28,1E44,6B14,773B),
+ bn_pack4(7359,D041,D5C3,3EA7),
+ bn_pack4(A80D,740A,DBF4,FF74),
+ bn_pack4(55F9,7993,EC97,5EEA),
+ bn_pack4(2918,A996,2F0B,93B8),
+ bn_pack4(661A,05FB,D5FA,AAE8),
+ bn_pack4(CF60,9517,9A16,3AB3),
+ bn_pack4(E808,3969,EDB7,67B0),
+ bn_pack4(CD7F,48A9,DA04,FD50),
+ bn_pack4(D523,12AB,4B03,310D),
+ bn_pack4(8193,E075,7767,A13D),
+ bn_pack4(A373,29CB,B4A0,99ED),
+ bn_pack4(FC31,9294,3DB5,6050),
+ bn_pack4(AF72,B665,1987,EE07),
+ bn_pack4(F166,DE5E,1389,582F),
+ bn_pack4(AC6B,DB41,324A,9A9B)
+};
+static BIGNUM bn_group_2048 = {
+ bn_group_2048_value,
+ (sizeof bn_group_2048_value)/sizeof(BN_ULONG),
+ (sizeof bn_group_2048_value)/sizeof(BN_ULONG),
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_3072_value[] = {
+ bn_pack4(FFFF,FFFF,FFFF,FFFF),
+ bn_pack4(4B82,D120,A93A,D2CA),
+ bn_pack4(43DB,5BFC,E0FD,108E),
+ bn_pack4(08E2,4FA0,74E5,AB31),
+ bn_pack4(7709,88C0,BAD9,46E2),
+ bn_pack4(BBE1,1757,7A61,5D6C),
+ bn_pack4(521F,2B18,177B,200C),
+ bn_pack4(D876,0273,3EC8,6A64),
+ bn_pack4(F12F,FA06,D98A,0864),
+ bn_pack4(CEE3,D226,1AD2,EE6B),
+ bn_pack4(1E8C,94E0,4A25,619D),
+ bn_pack4(ABF5,AE8C,DB09,33D7),
+ bn_pack4(B397,0F85,A6E1,E4C7),
+ bn_pack4(8AEA,7157,5D06,0C7D),
+ bn_pack4(ECFB,8504,58DB,EF0A),
+ bn_pack4(A855,21AB,DF1C,BA64),
+ bn_pack4(AD33,170D,0450,7A33),
+ bn_pack4(1572,8E5A,8AAA,C42D),
+ bn_pack4(15D2,2618,98FA,0510),
+ bn_pack4(3995,497C,EA95,6AE5),
+ bn_pack4(DE2B,CBF6,9558,1718),
+ bn_pack4(B5C5,5DF0,6F4C,52C9),
+ bn_pack4(9B27,83A2,EC07,A28F),
+ bn_pack4(E39E,772C,180E,8603),
+ bn_pack4(3290,5E46,2E36,CE3B),
+ bn_pack4(F174,6C08,CA18,217C),
+ bn_pack4(670C,354E,4ABC,9804),
+ bn_pack4(9ED5,2907,7096,966D),
+ bn_pack4(1C62,F356,2085,52BB),
+ bn_pack4(8365,5D23,DCA3,AD96),
+ bn_pack4(6916,3FA8,FD24,CF5F),
+ bn_pack4(98DA,4836,1C55,D39A),
+ bn_pack4(C200,7CB8,A163,BF05),
+ bn_pack4(4928,6651,ECE4,5B3D),
+ bn_pack4(AE9F,2411,7C4B,1FE6),
+ bn_pack4(EE38,6BFB,5A89,9FA5),
+ bn_pack4(0BFF,5CB6,F406,B7ED),
+ bn_pack4(F44C,42E9,A637,ED6B),
+ bn_pack4(E485,B576,625E,7EC6),
+ bn_pack4(4FE1,356D,6D51,C245),
+ bn_pack4(302B,0A6D,F25F,1437),
+ bn_pack4(EF95,19B3,CD3A,431B),
+ bn_pack4(514A,0879,8E34,04DD),
+ bn_pack4(020B,BEA6,3B13,9B22),
+ bn_pack4(2902,4E08,8A67,CC74),
+ bn_pack4(C4C6,628B,80DC,1CD1),
+ bn_pack4(C90F,DAA2,2168,C234),
+ bn_pack4(FFFF,FFFF,FFFF,FFFF)
+};
+static BIGNUM bn_group_3072 = {
+ bn_group_3072_value,
+ (sizeof bn_group_3072_value)/sizeof(BN_ULONG),
+ (sizeof bn_group_3072_value)/sizeof(BN_ULONG),
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_4096_value[] = {
+ bn_pack4(FFFF,FFFF,FFFF,FFFF),
+ bn_pack4(4DF4,35C9,3406,3199),
+ bn_pack4(86FF,B7DC,90A6,C08F),
+ bn_pack4(93B4,EA98,8D8F,DDC1),
+ bn_pack4(D006,9127,D5B0,5AA9),
+ bn_pack4(B81B,DD76,2170,481C),
+ bn_pack4(1F61,2970,CEE2,D7AF),
+ bn_pack4(233B,A186,515B,E7ED),
+ bn_pack4(99B2,964F,A090,C3A2),
+ bn_pack4(287C,5947,4E6B,C05D),
+ bn_pack4(2E8E,FC14,1FBE,CAA6),
+ bn_pack4(DBBB,C2DB,04DE,8EF9),
+ bn_pack4(2583,E9CA,2AD4,4CE8),
+ bn_pack4(1A94,6834,B615,0BDA),
+ bn_pack4(99C3,2718,6AF4,E23C),
+ bn_pack4(8871,9A10,BDBA,5B26),
+ bn_pack4(1A72,3C12,A787,E6D7),
+ bn_pack4(4B82,D120,A921,0801),
+ bn_pack4(43DB,5BFC,E0FD,108E),
+ bn_pack4(08E2,4FA0,74E5,AB31),
+ bn_pack4(7709,88C0,BAD9,46E2),
+ bn_pack4(BBE1,1757,7A61,5D6C),
+ bn_pack4(521F,2B18,177B,200C),
+ bn_pack4(D876,0273,3EC8,6A64),
+ bn_pack4(F12F,FA06,D98A,0864),
+ bn_pack4(CEE3,D226,1AD2,EE6B),
+ bn_pack4(1E8C,94E0,4A25,619D),
+ bn_pack4(ABF5,AE8C,DB09,33D7),
+ bn_pack4(B397,0F85,A6E1,E4C7),
+ bn_pack4(8AEA,7157,5D06,0C7D),
+ bn_pack4(ECFB,8504,58DB,EF0A),
+ bn_pack4(A855,21AB,DF1C,BA64),
+ bn_pack4(AD33,170D,0450,7A33),
+ bn_pack4(1572,8E5A,8AAA,C42D),
+ bn_pack4(15D2,2618,98FA,0510),
+ bn_pack4(3995,497C,EA95,6AE5),
+ bn_pack4(DE2B,CBF6,9558,1718),
+ bn_pack4(B5C5,5DF0,6F4C,52C9),
+ bn_pack4(9B27,83A2,EC07,A28F),
+ bn_pack4(E39E,772C,180E,8603),
+ bn_pack4(3290,5E46,2E36,CE3B),
+ bn_pack4(F174,6C08,CA18,217C),
+ bn_pack4(670C,354E,4ABC,9804),
+ bn_pack4(9ED5,2907,7096,966D),
+ bn_pack4(1C62,F356,2085,52BB),
+ bn_pack4(8365,5D23,DCA3,AD96),
+ bn_pack4(6916,3FA8,FD24,CF5F),
+ bn_pack4(98DA,4836,1C55,D39A),
+ bn_pack4(C200,7CB8,A163,BF05),
+ bn_pack4(4928,6651,ECE4,5B3D),
+ bn_pack4(AE9F,2411,7C4B,1FE6),
+ bn_pack4(EE38,6BFB,5A89,9FA5),
+ bn_pack4(0BFF,5CB6,F406,B7ED),
+ bn_pack4(F44C,42E9,A637,ED6B),
+ bn_pack4(E485,B576,625E,7EC6),
+ bn_pack4(4FE1,356D,6D51,C245),
+ bn_pack4(302B,0A6D,F25F,1437),
+ bn_pack4(EF95,19B3,CD3A,431B),
+ bn_pack4(514A,0879,8E34,04DD),
+ bn_pack4(020B,BEA6,3B13,9B22),
+ bn_pack4(2902,4E08,8A67,CC74),
+ bn_pack4(C4C6,628B,80DC,1CD1),
+ bn_pack4(C90F,DAA2,2168,C234),
+ bn_pack4(FFFF,FFFF,FFFF,FFFF)
+};
+static BIGNUM bn_group_4096 = {
+ bn_group_4096_value,
+ (sizeof bn_group_4096_value)/sizeof(BN_ULONG),
+ (sizeof bn_group_4096_value)/sizeof(BN_ULONG),
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_6144_value[] = {
+ bn_pack4(FFFF,FFFF,FFFF,FFFF),
+ bn_pack4(E694,F91E,6DCC,4024),
+ bn_pack4(12BF,2D5B,0B74,74D6),
+ bn_pack4(043E,8F66,3F48,60EE),
+ bn_pack4(387F,E8D7,6E3C,0468),
+ bn_pack4(DA56,C9EC,2EF2,9632),
+ bn_pack4(EB19,CCB1,A313,D55C),
+ bn_pack4(F550,AA3D,8A1F,BFF0),
+ bn_pack4(06A1,D58B,B7C5,DA76),
+ bn_pack4(A797,15EE,F29B,E328),
+ bn_pack4(14CC,5ED2,0F80,37E0),
+ bn_pack4(CC8F,6D7E,BF48,E1D8),
+ bn_pack4(4BD4,07B2,2B41,54AA),
+ bn_pack4(0F1D,45B7,FF58,5AC5),
+ bn_pack4(23A9,7A7E,36CC,88BE),
+ bn_pack4(59E7,C97F,BEC7,E8F3),
+ bn_pack4(B5A8,4031,900B,1C9E),
+ bn_pack4(D55E,702F,4698,0C82),
+ bn_pack4(F482,D7CE,6E74,FEF6),
+ bn_pack4(F032,EA15,D172,1D03),
+ bn_pack4(5983,CA01,C64B,92EC),
+ bn_pack4(6FB8,F401,378C,D2BF),
+ bn_pack4(3320,5151,2BD7,AF42),
+ bn_pack4(DB7F,1447,E6CC,254B),
+ bn_pack4(44CE,6CBA,CED4,BB1B),
+ bn_pack4(DA3E,DBEB,CF9B,14ED),
+ bn_pack4(1797,27B0,865A,8918),
+ bn_pack4(B06A,53ED,9027,D831),
+ bn_pack4(E5DB,382F,4130,01AE),
+ bn_pack4(F8FF,9406,AD9E,530E),
+ bn_pack4(C975,1E76,3DBA,37BD),
+ bn_pack4(C1D4,DCB2,6026,46DE),
+ bn_pack4(36C3,FAB4,D27C,7026),
+ bn_pack4(4DF4,35C9,3402,8492),
+ bn_pack4(86FF,B7DC,90A6,C08F),
+ bn_pack4(93B4,EA98,8D8F,DDC1),
+ bn_pack4(D006,9127,D5B0,5AA9),
+ bn_pack4(B81B,DD76,2170,481C),
+ bn_pack4(1F61,2970,CEE2,D7AF),
+ bn_pack4(233B,A186,515B,E7ED),
+ bn_pack4(99B2,964F,A090,C3A2),
+ bn_pack4(287C,5947,4E6B,C05D),
+ bn_pack4(2E8E,FC14,1FBE,CAA6),
+ bn_pack4(DBBB,C2DB,04DE,8EF9),
+ bn_pack4(2583,E9CA,2AD4,4CE8),
+ bn_pack4(1A94,6834,B615,0BDA),
+ bn_pack4(99C3,2718,6AF4,E23C),
+ bn_pack4(8871,9A10,BDBA,5B26),
+ bn_pack4(1A72,3C12,A787,E6D7),
+ bn_pack4(4B82,D120,A921,0801),
+ bn_pack4(43DB,5BFC,E0FD,108E),
+ bn_pack4(08E2,4FA0,74E5,AB31),
+ bn_pack4(7709,88C0,BAD9,46E2),
+ bn_pack4(BBE1,1757,7A61,5D6C),
+ bn_pack4(521F,2B18,177B,200C),
+ bn_pack4(D876,0273,3EC8,6A64),
+ bn_pack4(F12F,FA06,D98A,0864),
+ bn_pack4(CEE3,D226,1AD2,EE6B),
+ bn_pack4(1E8C,94E0,4A25,619D),
+ bn_pack4(ABF5,AE8C,DB09,33D7),
+ bn_pack4(B397,0F85,A6E1,E4C7),
+ bn_pack4(8AEA,7157,5D06,0C7D),
+ bn_pack4(ECFB,8504,58DB,EF0A),
+ bn_pack4(A855,21AB,DF1C,BA64),
+ bn_pack4(AD33,170D,0450,7A33),
+ bn_pack4(1572,8E5A,8AAA,C42D),
+ bn_pack4(15D2,2618,98FA,0510),
+ bn_pack4(3995,497C,EA95,6AE5),
+ bn_pack4(DE2B,CBF6,9558,1718),
+ bn_pack4(B5C5,5DF0,6F4C,52C9),
+ bn_pack4(9B27,83A2,EC07,A28F),
+ bn_pack4(E39E,772C,180E,8603),
+ bn_pack4(3290,5E46,2E36,CE3B),
+ bn_pack4(F174,6C08,CA18,217C),
+ bn_pack4(670C,354E,4ABC,9804),
+ bn_pack4(9ED5,2907,7096,966D),
+ bn_pack4(1C62,F356,2085,52BB),
+ bn_pack4(8365,5D23,DCA3,AD96),
+ bn_pack4(6916,3FA8,FD24,CF5F),
+ bn_pack4(98DA,4836,1C55,D39A),
+ bn_pack4(C200,7CB8,A163,BF05),
+ bn_pack4(4928,6651,ECE4,5B3D),
+ bn_pack4(AE9F,2411,7C4B,1FE6),
+ bn_pack4(EE38,6BFB,5A89,9FA5),
+ bn_pack4(0BFF,5CB6,F406,B7ED),
+ bn_pack4(F44C,42E9,A637,ED6B),
+ bn_pack4(E485,B576,625E,7EC6),
+ bn_pack4(4FE1,356D,6D51,C245),
+ bn_pack4(302B,0A6D,F25F,1437),
+ bn_pack4(EF95,19B3,CD3A,431B),
+ bn_pack4(514A,0879,8E34,04DD),
+ bn_pack4(020B,BEA6,3B13,9B22),
+ bn_pack4(2902,4E08,8A67,CC74),
+ bn_pack4(C4C6,628B,80DC,1CD1),
+ bn_pack4(C90F,DAA2,2168,C234),
+ bn_pack4(FFFF,FFFF,FFFF,FFFF)
+};
+static BIGNUM bn_group_6144 = {
+ bn_group_6144_value,
+ (sizeof bn_group_6144_value)/sizeof(BN_ULONG),
+ (sizeof bn_group_6144_value)/sizeof(BN_ULONG),
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_8192_value[] = {
+ bn_pack4(FFFF,FFFF,FFFF,FFFF),
+ bn_pack4(60C9,80DD,98ED,D3DF),
+ bn_pack4(C81F,56E8,80B9,6E71),
+ bn_pack4(9E30,50E2,7656,94DF),
+ bn_pack4(9558,E447,5677,E9AA),
+ bn_pack4(C919,0DA6,FC02,6E47),
+ bn_pack4(889A,002E,D5EE,382B),
+ bn_pack4(4009,438B,481C,6CD7),
+ bn_pack4(3590,46F4,EB87,9F92),
+ bn_pack4(FAF3,6BC3,1ECF,A268),
+ bn_pack4(B1D5,10BD,7EE7,4D73),
+ bn_pack4(F9AB,4819,5DED,7EA1),
+ bn_pack4(64F3,1CC5,0846,851D),
+ bn_pack4(4597,E899,A025,5DC1),
+ bn_pack4(DF31,0EE0,74AB,6A36),
+ bn_pack4(6D2A,13F8,3F44,F82D),
+ bn_pack4(062B,3CF5,B3A2,78A6),
+ bn_pack4(7968,3303,ED5B,DD3A),
+ bn_pack4(FA9D,4B7F,A2C0,87E8),
+ bn_pack4(4BCB,C886,2F83,85DD),
+ bn_pack4(3473,FC64,6CEA,306B),
+ bn_pack4(13EB,57A8,1A23,F0C7),
+ bn_pack4(2222,2E04,A403,7C07),
+ bn_pack4(E3FD,B8BE,FC84,8AD9),
+ bn_pack4(238F,16CB,E39D,652D),
+ bn_pack4(3423,B474,2BF1,C978),
+ bn_pack4(3AAB,639C,5AE4,F568),
+ bn_pack4(2576,F693,6BA4,2466),
+ bn_pack4(741F,A7BF,8AFC,47ED),
+ bn_pack4(3BC8,32B6,8D9D,D300),
+ bn_pack4(D8BE,C4D0,73B9,31BA),
+ bn_pack4(3877,7CB6,A932,DF8C),
+ bn_pack4(74A3,926F,12FE,E5E4),
+ bn_pack4(E694,F91E,6DBE,1159),
+ bn_pack4(12BF,2D5B,0B74,74D6),
+ bn_pack4(043E,8F66,3F48,60EE),
+ bn_pack4(387F,E8D7,6E3C,0468),
+ bn_pack4(DA56,C9EC,2EF2,9632),
+ bn_pack4(EB19,CCB1,A313,D55C),
+ bn_pack4(F550,AA3D,8A1F,BFF0),
+ bn_pack4(06A1,D58B,B7C5,DA76),
+ bn_pack4(A797,15EE,F29B,E328),
+ bn_pack4(14CC,5ED2,0F80,37E0),
+ bn_pack4(CC8F,6D7E,BF48,E1D8),
+ bn_pack4(4BD4,07B2,2B41,54AA),
+ bn_pack4(0F1D,45B7,FF58,5AC5),
+ bn_pack4(23A9,7A7E,36CC,88BE),
+ bn_pack4(59E7,C97F,BEC7,E8F3),
+ bn_pack4(B5A8,4031,900B,1C9E),
+ bn_pack4(D55E,702F,4698,0C82),
+ bn_pack4(F482,D7CE,6E74,FEF6),
+ bn_pack4(F032,EA15,D172,1D03),
+ bn_pack4(5983,CA01,C64B,92EC),
+ bn_pack4(6FB8,F401,378C,D2BF),
+ bn_pack4(3320,5151,2BD7,AF42),
+ bn_pack4(DB7F,1447,E6CC,254B),
+ bn_pack4(44CE,6CBA,CED4,BB1B),
+ bn_pack4(DA3E,DBEB,CF9B,14ED),
+ bn_pack4(1797,27B0,865A,8918),
+ bn_pack4(B06A,53ED,9027,D831),
+ bn_pack4(E5DB,382F,4130,01AE),
+ bn_pack4(F8FF,9406,AD9E,530E),
+ bn_pack4(C975,1E76,3DBA,37BD),
+ bn_pack4(C1D4,DCB2,6026,46DE),
+ bn_pack4(36C3,FAB4,D27C,7026),
+ bn_pack4(4DF4,35C9,3402,8492),
+ bn_pack4(86FF,B7DC,90A6,C08F),
+ bn_pack4(93B4,EA98,8D8F,DDC1),
+ bn_pack4(D006,9127,D5B0,5AA9),
+ bn_pack4(B81B,DD76,2170,481C),
+ bn_pack4(1F61,2970,CEE2,D7AF),
+ bn_pack4(233B,A186,515B,E7ED),
+ bn_pack4(99B2,964F,A090,C3A2),
+ bn_pack4(287C,5947,4E6B,C05D),
+ bn_pack4(2E8E,FC14,1FBE,CAA6),
+ bn_pack4(DBBB,C2DB,04DE,8EF9),
+ bn_pack4(2583,E9CA,2AD4,4CE8),
+ bn_pack4(1A94,6834,B615,0BDA),
+ bn_pack4(99C3,2718,6AF4,E23C),
+ bn_pack4(8871,9A10,BDBA,5B26),
+ bn_pack4(1A72,3C12,A787,E6D7),
+ bn_pack4(4B82,D120,A921,0801),
+ bn_pack4(43DB,5BFC,E0FD,108E),
+ bn_pack4(08E2,4FA0,74E5,AB31),
+ bn_pack4(7709,88C0,BAD9,46E2),
+ bn_pack4(BBE1,1757,7A61,5D6C),
+ bn_pack4(521F,2B18,177B,200C),
+ bn_pack4(D876,0273,3EC8,6A64),
+ bn_pack4(F12F,FA06,D98A,0864),
+ bn_pack4(CEE3,D226,1AD2,EE6B),
+ bn_pack4(1E8C,94E0,4A25,619D),
+ bn_pack4(ABF5,AE8C,DB09,33D7),
+ bn_pack4(B397,0F85,A6E1,E4C7),
+ bn_pack4(8AEA,7157,5D06,0C7D),
+ bn_pack4(ECFB,8504,58DB,EF0A),
+ bn_pack4(A855,21AB,DF1C,BA64),
+ bn_pack4(AD33,170D,0450,7A33),
+ bn_pack4(1572,8E5A,8AAA,C42D),
+ bn_pack4(15D2,2618,98FA,0510),
+ bn_pack4(3995,497C,EA95,6AE5),
+ bn_pack4(DE2B,CBF6,9558,1718),
+ bn_pack4(B5C5,5DF0,6F4C,52C9),
+ bn_pack4(9B27,83A2,EC07,A28F),
+ bn_pack4(E39E,772C,180E,8603),
+ bn_pack4(3290,5E46,2E36,CE3B),
+ bn_pack4(F174,6C08,CA18,217C),
+ bn_pack4(670C,354E,4ABC,9804),
+ bn_pack4(9ED5,2907,7096,966D),
+ bn_pack4(1C62,F356,2085,52BB),
+ bn_pack4(8365,5D23,DCA3,AD96),
+ bn_pack4(6916,3FA8,FD24,CF5F),
+ bn_pack4(98DA,4836,1C55,D39A),
+ bn_pack4(C200,7CB8,A163,BF05),
+ bn_pack4(4928,6651,ECE4,5B3D),
+ bn_pack4(AE9F,2411,7C4B,1FE6),
+ bn_pack4(EE38,6BFB,5A89,9FA5),
+ bn_pack4(0BFF,5CB6,F406,B7ED),
+ bn_pack4(F44C,42E9,A637,ED6B),
+ bn_pack4(E485,B576,625E,7EC6),
+ bn_pack4(4FE1,356D,6D51,C245),
+ bn_pack4(302B,0A6D,F25F,1437),
+ bn_pack4(EF95,19B3,CD3A,431B),
+ bn_pack4(514A,0879,8E34,04DD),
+ bn_pack4(020B,BEA6,3B13,9B22),
+ bn_pack4(2902,4E08,8A67,CC74),
+ bn_pack4(C4C6,628B,80DC,1CD1),
+ bn_pack4(C90F,DAA2,2168,C234),
+ bn_pack4(FFFF,FFFF,FFFF,FFFF)
+};
+static BIGNUM bn_group_8192 = {
+ bn_group_8192_value,
+ (sizeof bn_group_8192_value)/sizeof(BN_ULONG),
+ (sizeof bn_group_8192_value)/sizeof(BN_ULONG),
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_generator_19_value[] = {19} ;
+static BIGNUM bn_generator_19 = {
+ bn_generator_19_value,
+ 1,
+ 1,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+static BN_ULONG bn_generator_5_value[] = {5} ;
+static BIGNUM bn_generator_5 = {
+ bn_generator_5_value,
+ 1,
+ 1,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+static BN_ULONG bn_generator_2_value[] = {2} ;
+static BIGNUM bn_generator_2 = {
+ bn_generator_2_value,
+ 1,
+ 1,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static SRP_gN knowngN[] = {
+ {"8192",&bn_generator_19 , &bn_group_8192},
+ {"6144",&bn_generator_5 , &bn_group_6144},
+ {"4096",&bn_generator_5 , &bn_group_4096},
+ {"3072",&bn_generator_5 , &bn_group_3072},
+ {"2048",&bn_generator_2 , &bn_group_2048},
+ {"1536",&bn_generator_2 , &bn_group_1536},
+ {"1024",&bn_generator_2 , &bn_group_1024},
+};
+#define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN)
+
+/* end of generated data */
diff --git a/deps/openssl/openssl/crypto/srp/srp_lcl.h b/deps/openssl/openssl/crypto/srp/srp_lcl.h
new file mode 100644
index 000000000..42bda3f14
--- /dev/null
+++ b/deps/openssl/openssl/crypto/srp/srp_lcl.h
@@ -0,0 +1,83 @@
+/* crypto/srp/srp_lcl.h */
+/* Written by Peter Sylvester (peter.sylvester@edelweb.fr)
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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
+ * licensing@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).
+ *
+ */
+#ifndef HEADER_SRP_LCL_H
+#define HEADER_SRP_LCL_H
+
+#include <openssl/srp.h>
+#include <openssl/sha.h>
+
+#if 0
+#define srp_bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \
+ fprintf(stderr,"\n");}
+#else
+#define srp_bn_print(a)
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/deps/openssl/openssl/crypto/srp/srp_lib.c b/deps/openssl/openssl/crypto/srp/srp_lib.c
new file mode 100644
index 000000000..92cea98dc
--- /dev/null
+++ b/deps/openssl/openssl/crypto/srp/srp_lib.c
@@ -0,0 +1,357 @@
+/* crypto/srp/srp_lib.c */
+/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
+ * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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
+ * licensing@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).
+ *
+ */
+#ifndef OPENSSL_NO_SRP
+#include "cryptlib.h"
+#include "srp_lcl.h"
+#include <openssl/srp.h>
+#include <openssl/evp.h>
+
+#if (BN_BYTES == 8)
+#define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##ul
+#endif
+#if (BN_BYTES == 4)
+#define bn_pack4(a1,a2,a3,a4) 0x##a3##a4##ul, 0x##a1##a2##ul
+#endif
+#if (BN_BYTES == 2)
+#define bn_pack4(a1,a2,a3,a4) 0x##a4##u,0x##a3##u,0x##a2##u,0x##a1##u
+#endif
+
+
+#include "srp_grps.h"
+
+static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g)
+ {
+ /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */
+
+ unsigned char digest[SHA_DIGEST_LENGTH];
+ unsigned char *tmp;
+ EVP_MD_CTX ctxt;
+ int longg ;
+ int longN = BN_num_bytes(N);
+
+ if ((tmp = OPENSSL_malloc(longN)) == NULL)
+ return NULL;
+ BN_bn2bin(N,tmp) ;
+
+ EVP_MD_CTX_init(&ctxt);
+ EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+ EVP_DigestUpdate(&ctxt, tmp, longN);
+
+ memset(tmp, 0, longN);
+ longg = BN_bn2bin(g,tmp) ;
+ /* use the zeros behind to pad on left */
+ EVP_DigestUpdate(&ctxt, tmp + longg, longN-longg);
+ EVP_DigestUpdate(&ctxt, tmp, longg);
+ OPENSSL_free(tmp);
+
+ EVP_DigestFinal_ex(&ctxt, digest, NULL);
+ EVP_MD_CTX_cleanup(&ctxt);
+ return BN_bin2bn(digest, sizeof(digest), NULL);
+ }
+
+BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N)
+ {
+ /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */
+
+ BIGNUM *u;
+ unsigned char cu[SHA_DIGEST_LENGTH];
+ unsigned char *cAB;
+ EVP_MD_CTX ctxt;
+ int longN;
+ if ((A == NULL) ||(B == NULL) || (N == NULL))
+ return NULL;
+
+ longN= BN_num_bytes(N);
+
+ if ((cAB = OPENSSL_malloc(2*longN)) == NULL)
+ return NULL;
+
+ memset(cAB, 0, longN);
+
+ EVP_MD_CTX_init(&ctxt);
+ EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+ EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A,cAB+longN), longN);
+ EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B,cAB+longN), longN);
+ OPENSSL_free(cAB);
+ EVP_DigestFinal_ex(&ctxt, cu, NULL);
+ EVP_MD_CTX_cleanup(&ctxt);
+
+ if (!(u = BN_bin2bn(cu, sizeof(cu), NULL)))
+ return NULL;
+ if (!BN_is_zero(u))
+ return u;
+ BN_free(u);
+ return NULL;
+}
+
+BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N)
+ {
+ BIGNUM *tmp = NULL, *S = NULL;
+ BN_CTX *bn_ctx;
+
+ if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL)
+ return NULL;
+
+ if ((bn_ctx = BN_CTX_new()) == NULL ||
+ (tmp = BN_new()) == NULL ||
+ (S = BN_new()) == NULL )
+ goto err;
+
+ /* S = (A*v**u) ** b */
+
+ if (!BN_mod_exp(tmp,v,u,N,bn_ctx))
+ goto err;
+ if (!BN_mod_mul(tmp,A,tmp,N,bn_ctx))
+ goto err;
+ if (!BN_mod_exp(S,tmp,b,N,bn_ctx))
+ goto err;
+err:
+ BN_CTX_free(bn_ctx);
+ BN_clear_free(tmp);
+ return S;
+ }
+
+BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v)
+ {
+ BIGNUM *kv = NULL, *gb = NULL;
+ BIGNUM *B = NULL, *k = NULL;
+ BN_CTX *bn_ctx;
+
+ if (b == NULL || N == NULL || g == NULL || v == NULL ||
+ (bn_ctx = BN_CTX_new()) == NULL)
+ return NULL;
+
+ if ( (kv = BN_new()) == NULL ||
+ (gb = BN_new()) == NULL ||
+ (B = BN_new())== NULL)
+ goto err;
+
+ /* B = g**b + k*v */
+
+ if (!BN_mod_exp(gb,g,b,N,bn_ctx) ||
+ !(k = srp_Calc_k(N,g)) ||
+ !BN_mod_mul(kv,v,k,N,bn_ctx) ||
+ !BN_mod_add(B,gb,kv,N,bn_ctx))
+ {
+ BN_free(B);
+ B = NULL;
+ }
+err:
+ BN_CTX_free(bn_ctx);
+ BN_clear_free(kv);
+ BN_clear_free(gb);
+ BN_free(k);
+ return B;
+ }
+
+BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass)
+ {
+ unsigned char dig[SHA_DIGEST_LENGTH];
+ EVP_MD_CTX ctxt;
+ unsigned char *cs;
+
+ if ((s == NULL) ||
+ (user == NULL) ||
+ (pass == NULL))
+ return NULL;
+
+ if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
+ return NULL;
+
+ EVP_MD_CTX_init(&ctxt);
+ EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+ EVP_DigestUpdate(&ctxt, user, strlen(user));
+ EVP_DigestUpdate(&ctxt, ":", 1);
+ EVP_DigestUpdate(&ctxt, pass, strlen(pass));
+ EVP_DigestFinal_ex(&ctxt, dig, NULL);
+
+ EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+ BN_bn2bin(s,cs);
+ EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s));
+ OPENSSL_free(cs);
+ EVP_DigestUpdate(&ctxt, dig, sizeof(dig));
+ EVP_DigestFinal_ex(&ctxt, dig, NULL);
+ EVP_MD_CTX_cleanup(&ctxt);
+
+ return BN_bin2bn(dig, sizeof(dig), NULL);
+ }
+
+BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g)
+ {
+ BN_CTX *bn_ctx;
+ BIGNUM * A = NULL;
+
+ if (a == NULL || N == NULL || g == NULL ||
+ (bn_ctx = BN_CTX_new()) == NULL)
+ return NULL;
+
+ if ((A = BN_new()) != NULL &&
+ !BN_mod_exp(A,g,a,N,bn_ctx))
+ {
+ BN_free(A);
+ A = NULL;
+ }
+ BN_CTX_free(bn_ctx);
+ return A;
+ }
+
+
+BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u)
+ {
+ BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL , *k = NULL, *K = NULL;
+ BN_CTX *bn_ctx;
+
+ if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL || a == NULL ||
+ (bn_ctx = BN_CTX_new()) == NULL)
+ return NULL;
+
+ if ((tmp = BN_new()) == NULL ||
+ (tmp2 = BN_new())== NULL ||
+ (tmp3 = BN_new())== NULL ||
+ (K = BN_new()) == NULL)
+ goto err;
+
+ if (!BN_mod_exp(tmp,g,x,N,bn_ctx))
+ goto err;
+ if (!(k = srp_Calc_k(N,g)))
+ goto err;
+ if (!BN_mod_mul(tmp2,tmp,k,N,bn_ctx))
+ goto err;
+ if (!BN_mod_sub(tmp,B,tmp2,N,bn_ctx))
+ goto err;
+
+ if (!BN_mod_mul(tmp3,u,x,N,bn_ctx))
+ goto err;
+ if (!BN_mod_add(tmp2,a,tmp3,N,bn_ctx))
+ goto err;
+ if (!BN_mod_exp(K,tmp,tmp2,N,bn_ctx))
+ goto err;
+
+err :
+ BN_CTX_free(bn_ctx);
+ BN_clear_free(tmp);
+ BN_clear_free(tmp2);
+ BN_clear_free(tmp3);
+ BN_free(k);
+ return K;
+ }
+
+int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N)
+ {
+ BIGNUM *r;
+ BN_CTX *bn_ctx;
+ int ret = 0;
+
+ if (B == NULL || N == NULL ||
+ (bn_ctx = BN_CTX_new()) == NULL)
+ return 0;
+
+ if ((r = BN_new()) == NULL)
+ goto err;
+ /* Checks if B % N == 0 */
+ if (!BN_nnmod(r,B,N,bn_ctx))
+ goto err;
+ ret = !BN_is_zero(r);
+err:
+ BN_CTX_free(bn_ctx);
+ BN_free(r);
+ return ret;
+ }
+
+int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N)
+ {
+ /* Checks if A % N == 0 */
+ return SRP_Verify_B_mod_N(A,N) ;
+ }
+
+
+/* Check if G and N are kwown parameters.
+ The values have been generated from the ietf-tls-srp draft version 8
+*/
+char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N)
+ {
+ size_t i;
+ if ((g == NULL) || (N == NULL))
+ return 0;
+
+ srp_bn_print(g);
+ srp_bn_print(N);
+
+ for(i = 0; i < KNOWN_GN_NUMBER; i++)
+ {
+ if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0)
+ return knowngN[i].id;
+ }
+ return NULL;
+ }
+
+SRP_gN *SRP_get_default_gN(const char *id)
+ {
+ size_t i;
+
+ if (id == NULL)
+ return knowngN;
+ for(i = 0; i < KNOWN_GN_NUMBER; i++)
+ {
+ if (strcmp(knowngN[i].id, id)==0)
+ return knowngN + i;
+ }
+ return NULL;
+ }
+#endif
diff --git a/deps/openssl/openssl/crypto/srp/srp_vfy.c b/deps/openssl/openssl/crypto/srp/srp_vfy.c
new file mode 100644
index 000000000..4a3d13edf
--- /dev/null
+++ b/deps/openssl/openssl/crypto/srp/srp_vfy.c
@@ -0,0 +1,658 @@
+/* crypto/srp/srp_vfy.c */
+/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
+ * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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
+ * licensing@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).
+ *
+ */
+#ifndef OPENSSL_NO_SRP
+#include "cryptlib.h"
+#include "srp_lcl.h"
+#include <openssl/srp.h>
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/txt_db.h>
+
+#define SRP_RANDOM_SALT_LEN 20
+#define MAX_LEN 2500
+
+static char b64table[] =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
+
+/* the following two conversion routines have been inspired by code from Stanford */
+
+/*
+ * Convert a base64 string into raw byte array representation.
+ */
+static int t_fromb64(unsigned char *a, const char *src)
+ {
+ char *loc;
+ int i, j;
+ int size;
+
+ while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
+ ++src;
+ size = strlen(src);
+ i = 0;
+ while(i < size)
+ {
+ loc = strchr(b64table, src[i]);
+ if(loc == (char *) 0) break;
+ else a[i] = loc - b64table;
+ ++i;
+ }
+ size = i;
+ i = size - 1;
+ j = size;
+ while(1)
+ {
+ a[j] = a[i];
+ if(--i < 0) break;
+ a[j] |= (a[i] & 3) << 6;
+ --j;
+ a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
+ if(--i < 0) break;
+ a[j] |= (a[i] & 0xf) << 4;
+ --j;
+ a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
+ if(--i < 0) break;
+ a[j] |= (a[i] << 2);
+
+ a[--j] = 0;
+ if(--i < 0) break;
+ }
+ while(a[j] == 0 && j <= size) ++j;
+ i = 0;
+ while (j <= size) a[i++] = a[j++];
+ return i;
+ }
+
+
+/*
+ * Convert a raw byte string into a null-terminated base64 ASCII string.
+ */
+static char *t_tob64(char *dst, const unsigned char *src, int size)
+ {
+ int c, pos = size % 3;
+ unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
+ char *olddst = dst;
+
+ switch(pos)
+ {
+ case 1:
+ b2 = src[0];
+ break;
+ case 2:
+ b1 = src[0];
+ b2 = src[1];
+ break;
+ }
+
+ while(1)
+ {
+ c = (b0 & 0xfc) >> 2;
+ if(notleading || c != 0)
+ {
+ *dst++ = b64table[c];
+ notleading = 1;
+ }
+ c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
+ if(notleading || c != 0)
+ {
+ *dst++ = b64table[c];
+ notleading = 1;
+ }
+ c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
+ if(notleading || c != 0)
+ {
+ *dst++ = b64table[c];
+ notleading = 1;
+ }
+ c = b2 & 0x3f;
+ if(notleading || c != 0)
+ {
+ *dst++ = b64table[c];
+ notleading = 1;
+ }
+ if(pos >= size) break;
+ else
+ {
+ b0 = src[pos++];
+ b1 = src[pos++];
+ b2 = src[pos++];
+ }
+ }
+
+ *dst++ = '\0';
+ return olddst;
+ }
+
+static void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
+ {
+ if (user_pwd == NULL)
+ return;
+ BN_free(user_pwd->s);
+ BN_clear_free(user_pwd->v);
+ OPENSSL_free(user_pwd->id);
+ OPENSSL_free(user_pwd->info);
+ OPENSSL_free(user_pwd);
+ }
+
+static SRP_user_pwd *SRP_user_pwd_new()
+ {
+ SRP_user_pwd *ret = OPENSSL_malloc(sizeof(SRP_user_pwd));
+ if (ret == NULL)
+ return NULL;
+ ret->N = NULL;
+ ret->g = NULL;
+ ret->s = NULL;
+ ret->v = NULL;
+ ret->id = NULL ;
+ ret->info = NULL;
+ return ret;
+ }
+
+static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g,
+ const BIGNUM *N)
+ {
+ vinfo->N = N;
+ vinfo->g = g;
+ }
+
+static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id,
+ const char *info)
+ {
+ if (id != NULL && NULL == (vinfo->id = BUF_strdup(id)))
+ return 0;
+ return (info == NULL || NULL != (vinfo->info = BUF_strdup(info))) ;
+ }
+
+static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s,
+ const char *v)
+ {
+ unsigned char tmp[MAX_LEN];
+ int len;
+
+ if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN)
+ return 0;
+ len = t_fromb64(tmp, v);
+ if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)) )
+ return 0;
+ len = t_fromb64(tmp, s);
+ return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL) ;
+ }
+
+static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v)
+ {
+ vinfo->v = v;
+ vinfo->s = s;
+ return (vinfo->s != NULL && vinfo->v != NULL) ;
+ }
+
+SRP_VBASE *SRP_VBASE_new(char *seed_key)
+ {
+ SRP_VBASE *vb = (SRP_VBASE *) OPENSSL_malloc(sizeof(SRP_VBASE));
+
+ if (vb == NULL)
+ return NULL;
+ if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) ||
+ !(vb->gN_cache = sk_SRP_gN_cache_new_null()))
+ {
+ OPENSSL_free(vb);
+ return NULL;
+ }
+ vb->default_g = NULL;
+ vb->default_N = NULL;
+ vb->seed_key = NULL;
+ if ((seed_key != NULL) &&
+ (vb->seed_key = BUF_strdup(seed_key)) == NULL)
+ {
+ sk_SRP_user_pwd_free(vb->users_pwd);
+ sk_SRP_gN_cache_free(vb->gN_cache);
+ OPENSSL_free(vb);
+ return NULL;
+ }
+ return vb;
+ }
+
+
+int SRP_VBASE_free(SRP_VBASE *vb)
+ {
+ sk_SRP_user_pwd_pop_free(vb->users_pwd,SRP_user_pwd_free);
+ sk_SRP_gN_cache_free(vb->gN_cache);
+ OPENSSL_free(vb->seed_key);
+ OPENSSL_free(vb);
+ return 0;
+ }
+
+
+static SRP_gN_cache *SRP_gN_new_init(const char *ch)
+ {
+ unsigned char tmp[MAX_LEN];
+ int len;
+
+ SRP_gN_cache *newgN = (SRP_gN_cache *)OPENSSL_malloc(sizeof(SRP_gN_cache));
+ if (newgN == NULL)
+ return NULL;
+
+ if ((newgN->b64_bn = BUF_strdup(ch)) == NULL)
+ goto err;
+
+ len = t_fromb64(tmp, ch);
+ if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
+ return newgN;
+
+ OPENSSL_free(newgN->b64_bn);
+err:
+ OPENSSL_free(newgN);
+ return NULL;
+ }
+
+
+static void SRP_gN_free(SRP_gN_cache *gN_cache)
+ {
+ if (gN_cache == NULL)
+ return;
+ OPENSSL_free(gN_cache->b64_bn);
+ BN_free(gN_cache->bn);
+ OPENSSL_free(gN_cache);
+ }
+
+static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab)
+ {
+ int i;
+
+ SRP_gN *gN;
+ if (gN_tab != NULL)
+ for(i = 0; i < sk_SRP_gN_num(gN_tab); i++)
+ {
+ gN = sk_SRP_gN_value(gN_tab, i);
+ if (gN && (id == NULL || strcmp(gN->id,id)==0))
+ return gN;
+ }
+
+ return SRP_get_default_gN(id);
+ }
+
+static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch)
+ {
+ int i;
+ if (gN_cache == NULL)
+ return NULL;
+
+ /* search if we have already one... */
+ for(i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++)
+ {
+ SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i);
+ if (strcmp(cache->b64_bn,ch)==0)
+ return cache->bn;
+ }
+ { /* it is the first time that we find it */
+ SRP_gN_cache *newgN = SRP_gN_new_init(ch);
+ if (newgN)
+ {
+ if (sk_SRP_gN_cache_insert(gN_cache,newgN,0)>0)
+ return newgN->bn;
+ SRP_gN_free(newgN);
+ }
+ }
+ return NULL;
+ }
+
+/* this function parses verifier file. Format is:
+ * string(index):base64(N):base64(g):0
+ * string(username):base64(v):base64(salt):int(index)
+ */
+
+
+int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
+ {
+ int error_code ;
+ STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null();
+ char *last_index = NULL;
+ int i;
+ char **pp;
+
+ SRP_gN *gN = NULL;
+ SRP_user_pwd *user_pwd = NULL ;
+
+ TXT_DB *tmpdb = NULL;
+ BIO *in = BIO_new(BIO_s_file());
+
+ error_code = SRP_ERR_OPEN_FILE;
+
+ if (in == NULL || BIO_read_filename(in,verifier_file) <= 0)
+ goto err;
+
+ error_code = SRP_ERR_VBASE_INCOMPLETE_FILE;
+
+ if ((tmpdb =TXT_DB_read(in,DB_NUMBER)) == NULL)
+ goto err;
+
+ error_code = SRP_ERR_MEMORY;
+
+
+ if (vb->seed_key)
+ {
+ last_index = SRP_get_default_gN(NULL)->id;
+ }
+ for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++)
+ {
+ pp = sk_OPENSSL_PSTRING_value(tmpdb->data,i);
+ if (pp[DB_srptype][0] == DB_SRP_INDEX)
+ {
+ /*we add this couple in the internal Stack */
+
+ if ((gN = (SRP_gN *)OPENSSL_malloc(sizeof(SRP_gN))) == NULL)
+ goto err;
+
+ if (!(gN->id = BUF_strdup(pp[DB_srpid]))
+ || !(gN->N = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpverifier]))
+ || !(gN->g = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpsalt]))
+ || sk_SRP_gN_insert(SRP_gN_tab,gN,0) == 0)
+ goto err;
+
+ gN = NULL;
+
+ if (vb->seed_key != NULL)
+ {
+ last_index = pp[DB_srpid];
+ }
+ }
+ else if (pp[DB_srptype][0] == DB_SRP_VALID)
+ {
+ /* it is a user .... */
+ SRP_gN *lgN;
+ if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN],SRP_gN_tab))!=NULL)
+ {
+ error_code = SRP_ERR_MEMORY;
+ if ((user_pwd = SRP_user_pwd_new()) == NULL)
+ goto err;
+
+ SRP_user_pwd_set_gN(user_pwd,lgN->g,lgN->N);
+ if (!SRP_user_pwd_set_ids(user_pwd, pp[DB_srpid],pp[DB_srpinfo]))
+ goto err;
+
+ error_code = SRP_ERR_VBASE_BN_LIB;
+ if (!SRP_user_pwd_set_sv(user_pwd, pp[DB_srpsalt],pp[DB_srpverifier]))
+ goto err;
+
+ if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0)
+ goto err;
+ user_pwd = NULL; /* abandon responsability */
+ }
+ }
+ }
+
+ if (last_index != NULL)
+ {
+ /* this means that we want to simulate a default user */
+
+ if (((gN = SRP_get_gN_by_id(last_index,SRP_gN_tab))==NULL))
+ {
+ error_code = SRP_ERR_VBASE_BN_LIB;
+ goto err;
+ }
+ vb->default_g = gN->g ;
+ vb->default_N = gN->N ;
+ gN = NULL ;
+ }
+ error_code = SRP_NO_ERROR;
+
+ err:
+ /* there may be still some leaks to fix, if this fails, the application terminates most likely */
+
+ if (gN != NULL)
+ {
+ OPENSSL_free(gN->id);
+ OPENSSL_free(gN);
+ }
+
+ SRP_user_pwd_free(user_pwd);
+
+ if (tmpdb) TXT_DB_free(tmpdb);
+ if (in) BIO_free_all(in);
+
+ sk_SRP_gN_free(SRP_gN_tab);
+
+ return error_code;
+
+ }
+
+
+SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
+ {
+ int i;
+ SRP_user_pwd *user;
+ unsigned char digv[SHA_DIGEST_LENGTH];
+ unsigned char digs[SHA_DIGEST_LENGTH];
+ EVP_MD_CTX ctxt;
+
+ if (vb == NULL)
+ return NULL;
+ for(i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++)
+ {
+ user = sk_SRP_user_pwd_value(vb->users_pwd, i);
+ if (strcmp(user->id,username)==0)
+ return user;
+ }
+ if ((vb->seed_key == NULL) ||
+ (vb->default_g == NULL) ||
+ (vb->default_N == NULL))
+ return NULL;
+
+/* if the user is unknown we set parameters as well if we have a seed_key */
+
+ if ((user = SRP_user_pwd_new()) == NULL)
+ return NULL;
+
+ SRP_user_pwd_set_gN(user,vb->default_g,vb->default_N);
+
+ if (!SRP_user_pwd_set_ids(user,username,NULL))
+ goto err;
+
+ RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH);
+ EVP_MD_CTX_init(&ctxt);
+ EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+ EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key));
+ EVP_DigestUpdate(&ctxt, username, strlen(username));
+ EVP_DigestFinal_ex(&ctxt, digs, NULL);
+ EVP_MD_CTX_cleanup(&ctxt);
+ if (SRP_user_pwd_set_sv_BN(user, BN_bin2bn(digs,SHA_DIGEST_LENGTH,NULL), BN_bin2bn(digv,SHA_DIGEST_LENGTH, NULL)))
+ return user;
+
+err: SRP_user_pwd_free(user);
+ return NULL;
+ }
+
+
+/*
+ create a verifier (*salt,*verifier,g and N are in base64)
+*/
+char *SRP_create_verifier(const char *user, const char *pass, char **salt,
+ char **verifier, const char *N, const char *g)
+ {
+ int len;
+ char * result=NULL;
+ char *vf;
+ BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL;
+ unsigned char tmp[MAX_LEN];
+ unsigned char tmp2[MAX_LEN];
+ char * defgNid = NULL;
+
+ if ((user == NULL)||
+ (pass == NULL)||
+ (salt == NULL)||
+ (verifier == NULL))
+ goto err;
+
+ if (N)
+ {
+ if (!(len = t_fromb64(tmp, N))) goto err;
+ N_bn = BN_bin2bn(tmp, len, NULL);
+ if (!(len = t_fromb64(tmp, g))) goto err;
+ g_bn = BN_bin2bn(tmp, len, NULL);
+ defgNid = "*";
+ }
+ else
+ {
+ SRP_gN * gN = SRP_get_gN_by_id(g, NULL) ;
+ if (gN == NULL)
+ goto err;
+ N_bn = gN->N;
+ g_bn = gN->g;
+ defgNid = gN->id;
+ }
+
+ if (*salt == NULL)
+ {
+ RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
+
+ s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
+ }
+ else
+ {
+ if (!(len = t_fromb64(tmp2, *salt)))
+ goto err;
+ s = BN_bin2bn(tmp2, len, NULL);
+ }
+
+
+ if(!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) goto err;
+
+ BN_bn2bin(v,tmp);
+ if (((vf = OPENSSL_malloc(BN_num_bytes(v)*2)) == NULL))
+ goto err;
+ t_tob64(vf, tmp, BN_num_bytes(v));
+
+ *verifier = vf;
+ if (*salt == NULL)
+ {
+ char *tmp_salt;
+
+ if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL)
+ {
+ OPENSSL_free(vf);
+ goto err;
+ }
+ t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN);
+ *salt = tmp_salt;
+ }
+
+ result=defgNid;
+
+err:
+ if(N)
+ {
+ BN_free(N_bn);
+ BN_free(g_bn);
+ }
+ return result;
+ }
+
+/*
+ create a verifier (*salt,*verifier,g and N are BIGNUMs)
+*/
+int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g)
+ {
+ int result=0;
+ BIGNUM *x = NULL;
+ BN_CTX *bn_ctx = BN_CTX_new();
+ unsigned char tmp2[MAX_LEN];
+
+ if ((user == NULL)||
+ (pass == NULL)||
+ (salt == NULL)||
+ (verifier == NULL)||
+ (N == NULL)||
+ (g == NULL)||
+ (bn_ctx == NULL))
+ goto err;
+
+ srp_bn_print(N);
+ srp_bn_print(g);
+
+ if (*salt == NULL)
+ {
+ RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
+
+ *salt = BN_bin2bn(tmp2,SRP_RANDOM_SALT_LEN,NULL);
+ }
+
+ x = SRP_Calc_x(*salt,user,pass);
+
+ *verifier = BN_new();
+ if(*verifier == NULL) goto err;
+
+ if (!BN_mod_exp(*verifier,g,x,N,bn_ctx))
+ {
+ BN_clear_free(*verifier);
+ goto err;
+ }
+
+ srp_bn_print(*verifier);
+
+ result=1;
+
+err:
+
+ BN_clear_free(x);
+ BN_CTX_free(bn_ctx);
+ return result;
+ }
+
+
+
+#endif
diff --git a/deps/openssl/openssl/crypto/srp/srptest.c b/deps/openssl/openssl/crypto/srp/srptest.c
new file mode 100644
index 000000000..04b66b454
--- /dev/null
+++ b/deps/openssl/openssl/crypto/srp/srptest.c
@@ -0,0 +1,162 @@
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_SRP
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+ {
+ printf("No SRP support\n");
+ return(0);
+ }
+
+#else
+
+#include <openssl/srp.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+static void showbn(const char *name, const BIGNUM *bn)
+ {
+ fputs(name, stdout);
+ fputs(" = ", stdout);
+ BN_print_fp(stdout, bn);
+ putc('\n', stdout);
+ }
+
+#define RANDOM_SIZE 32 /* use 256 bits on each side */
+
+static int run_srp(const char *username, const char *client_pass, const char *server_pass)
+ {
+ int ret=-1;
+ BIGNUM *s = NULL;
+ BIGNUM *v = NULL;
+ BIGNUM *a = NULL;
+ BIGNUM *b = NULL;
+ BIGNUM *u = NULL;
+ BIGNUM *x = NULL;
+ BIGNUM *Apub = NULL;
+ BIGNUM *Bpub = NULL;
+ BIGNUM *Kclient = NULL;
+ BIGNUM *Kserver = NULL;
+ unsigned char rand_tmp[RANDOM_SIZE];
+ /* use builtin 1024-bit params */
+ SRP_gN *GN = SRP_get_default_gN("1024");
+
+ if(GN == NULL)
+ {
+ fprintf(stderr, "Failed to get SRP parameters\n");
+ return -1;
+ }
+ /* Set up server's password entry */
+ if(!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g))
+ {
+ fprintf(stderr, "Failed to create SRP verifier\n");
+ return -1;
+ }
+
+ showbn("N", GN->N);
+ showbn("g", GN->g);
+ showbn("Salt", s);
+ showbn("Verifier", v);
+
+ /* Server random */
+ RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
+ b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
+ /* TODO - check b != 0 */
+ showbn("b", b);
+
+ /* Server's first message */
+ Bpub = SRP_Calc_B(b, GN->N, GN->g, v);
+ showbn("B", Bpub);
+
+ if(!SRP_Verify_B_mod_N(Bpub, GN->N))
+ {
+ fprintf(stderr, "Invalid B\n");
+ return -1;
+ }
+
+ /* Client random */
+ RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
+ a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
+ /* TODO - check a != 0 */
+ showbn("a", a);
+
+ /* Client's response */
+ Apub = SRP_Calc_A(a, GN->N, GN->g);
+ showbn("A", Apub);
+
+ if(!SRP_Verify_A_mod_N(Apub, GN->N))
+ {
+ fprintf(stderr, "Invalid A\n");
+ return -1;
+ }
+
+ /* Both sides calculate u */
+ u = SRP_Calc_u(Apub, Bpub, GN->N);
+
+ /* Client's key */
+ x = SRP_Calc_x(s, username, client_pass);
+ Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u);
+ showbn("Client's key", Kclient);
+
+ /* Server's key */
+ Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N);
+ showbn("Server's key", Kserver);
+
+ if(BN_cmp(Kclient, Kserver) == 0)
+ {
+ ret = 0;
+ }
+ else
+ {
+ fprintf(stderr, "Keys mismatch\n");
+ ret = 1;
+ }
+
+ BN_clear_free(Kclient);
+ BN_clear_free(Kserver);
+ BN_clear_free(x);
+ BN_free(u);
+ BN_free(Apub);
+ BN_clear_free(a);
+ BN_free(Bpub);
+ BN_clear_free(b);
+ BN_free(s);
+ BN_clear_free(v);
+
+ return ret;
+ }
+
+int main(int argc, char **argv)
+ {
+ BIO *bio_err;
+ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+ CRYPTO_malloc_debug_init();
+ CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ ERR_load_crypto_strings();
+
+ /* "Negative" test, expect a mismatch */
+ if(run_srp("alice", "password1", "password2") == 0)
+ {
+ fprintf(stderr, "Mismatched SRP run failed\n");
+ return 1;
+ }
+
+ /* "Positive" test, should pass */
+ if(run_srp("alice", "password", "password") != 0)
+ {
+ fprintf(stderr, "Plain SRP run failed\n");
+ return 1;
+ }
+
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+ ERR_free_strings();
+ CRYPTO_mem_leaks(bio_err);
+
+ return 0;
+ }
+#endif
diff --git a/deps/openssl/openssl/crypto/stack/safestack.h b/deps/openssl/openssl/crypto/stack/safestack.h
index 3e76aa58f..ea3aa0d80 100644
--- a/deps/openssl/openssl/crypto/stack/safestack.h
+++ b/deps/openssl/openssl/crypto/stack/safestack.h
@@ -1459,6 +1459,94 @@ DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
+#define sk_SRP_gN_new(cmp) SKM_sk_new(SRP_gN, (cmp))
+#define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN)
+#define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st))
+#define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st))
+#define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i))
+#define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val))
+#define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st))
+#define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val))
+#define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val))
+#define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val))
+#define sk_SRP_gN_find_ex(st, val) SKM_sk_find_ex(SRP_gN, (st), (val))
+#define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i))
+#define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr))
+#define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i))
+#define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp))
+#define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st)
+#define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func))
+#define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st))
+#define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st))
+#define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st))
+#define sk_SRP_gN_is_sorted(st) SKM_sk_is_sorted(SRP_gN, (st))
+
+#define sk_SRP_gN_cache_new(cmp) SKM_sk_new(SRP_gN_cache, (cmp))
+#define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache)
+#define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i))
+#define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val))
+#define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val))
+#define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val))
+#define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val))
+#define sk_SRP_gN_cache_find_ex(st, val) SKM_sk_find_ex(SRP_gN_cache, (st), (val))
+#define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i))
+#define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr))
+#define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i))
+#define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp))
+#define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st)
+#define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func))
+#define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_is_sorted(st) SKM_sk_is_sorted(SRP_gN_cache, (st))
+
+#define sk_SRP_user_pwd_new(cmp) SKM_sk_new(SRP_user_pwd, (cmp))
+#define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd)
+#define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i))
+#define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val))
+#define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val))
+#define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val))
+#define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val))
+#define sk_SRP_user_pwd_find_ex(st, val) SKM_sk_find_ex(SRP_user_pwd, (st), (val))
+#define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i))
+#define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr))
+#define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i))
+#define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp))
+#define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st)
+#define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func))
+#define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st))
+
+#define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp))
+#define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE)
+#define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i))
+#define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val))
+#define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val))
+#define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val))
+#define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val))
+#define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val))
+#define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i))
+#define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr))
+#define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i))
+#define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp))
+#define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st)
+#define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func))
+#define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st))
+
#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
@@ -2056,31 +2144,6 @@ DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
-#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
-#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
-#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
-#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
-#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i))
-#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
-#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func))
-#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
-#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
-#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
-#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
-#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
-#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
-#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
-#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
-#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \
- ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
- sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
-#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
-#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
-#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st))
-#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
-#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
-
-
#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
@@ -2106,6 +2169,31 @@ DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
+#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i))
+#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func))
+#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
+#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
+#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
+#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \
+ ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
+ sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st))
+#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
+
+
#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
diff --git a/deps/openssl/openssl/crypto/symhacks.h b/deps/openssl/openssl/crypto/symhacks.h
index 3fd4a8169..07a412f84 100644
--- a/deps/openssl/openssl/crypto/symhacks.h
+++ b/deps/openssl/openssl/crypto/symhacks.h
@@ -176,7 +176,6 @@
#define SSL_CTX_set_default_passwd_cb_userdata SSL_CTX_set_def_passwd_cb_ud
#undef SSL_COMP_get_compression_methods
#define SSL_COMP_get_compression_methods SSL_COMP_get_compress_methods
-
#undef ssl_add_clienthello_renegotiate_ext
#define ssl_add_clienthello_renegotiate_ext ssl_add_clienthello_reneg_ext
#undef ssl_add_serverhello_renegotiate_ext
@@ -185,6 +184,26 @@
#define ssl_parse_clienthello_renegotiate_ext ssl_parse_clienthello_reneg_ext
#undef ssl_parse_serverhello_renegotiate_ext
#define ssl_parse_serverhello_renegotiate_ext ssl_parse_serverhello_reneg_ext
+#undef SSL_srp_server_param_with_username
+#define SSL_srp_server_param_with_username SSL_srp_server_param_with_un
+#undef SSL_CTX_set_srp_client_pwd_callback
+#define SSL_CTX_set_srp_client_pwd_callback SSL_CTX_set_srp_client_pwd_cb
+#undef SSL_CTX_set_srp_verify_param_callback
+#define SSL_CTX_set_srp_verify_param_callback SSL_CTX_set_srp_vfy_param_cb
+#undef SSL_CTX_set_srp_username_callback
+#define SSL_CTX_set_srp_username_callback SSL_CTX_set_srp_un_cb
+#undef ssl_add_clienthello_use_srtp_ext
+#define ssl_add_clienthello_use_srtp_ext ssl_add_clihello_use_srtp_ext
+#undef ssl_add_serverhello_use_srtp_ext
+#define ssl_add_serverhello_use_srtp_ext ssl_add_serhello_use_srtp_ext
+#undef ssl_parse_clienthello_use_srtp_ext
+#define ssl_parse_clienthello_use_srtp_ext ssl_parse_clihello_use_srtp_ext
+#undef ssl_parse_serverhello_use_srtp_ext
+#define ssl_parse_serverhello_use_srtp_ext ssl_parse_serhello_use_srtp_ext
+#undef SSL_CTX_set_next_protos_advertised_cb
+#define SSL_CTX_set_next_protos_advertised_cb SSL_CTX_set_next_protos_adv_cb
+#undef SSL_CTX_set_next_proto_select_cb
+#define SSL_CTX_set_next_proto_select_cb SSL_CTX_set_next_proto_sel_cb
/* Hack some long ENGINE names */
#undef ENGINE_get_default_BN_mod_exp_crt
@@ -238,6 +257,9 @@
#define EC_GROUP_get_point_conversion_form EC_GROUP_get_point_conv_form
#undef EC_GROUP_clear_free_all_extra_data
#define EC_GROUP_clear_free_all_extra_data EC_GROUP_clr_free_all_xtra_data
+#undef EC_KEY_set_public_key_affine_coordinates
+#define EC_KEY_set_public_key_affine_coordinates \
+ EC_KEY_set_pub_key_aff_coords
#undef EC_POINT_set_Jprojective_coordinates_GFp
#define EC_POINT_set_Jprojective_coordinates_GFp \
EC_POINT_set_Jproj_coords_GFp
@@ -294,8 +316,6 @@
#define ec_GFp_simple_point_set_to_infinity ec_GFp_simple_pt_set_to_inf
#undef ec_GFp_simple_points_make_affine
#define ec_GFp_simple_points_make_affine ec_GFp_simple_pts_make_affine
-#undef ec_GFp_simple_group_get_curve_GFp
-#define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp
#undef ec_GFp_simple_set_Jprojective_coordinates_GFp
#define ec_GFp_simple_set_Jprojective_coordinates_GFp \
ec_GFp_smp_set_Jproj_coords_GFp
@@ -399,6 +419,12 @@
#undef dtls1_retransmit_buffered_messages
#define dtls1_retransmit_buffered_messages dtls1_retransmit_buffered_msgs
+/* Hack some long SRP names */
+#undef SRP_generate_server_master_secret
+#define SRP_generate_server_master_secret SRP_gen_server_master_secret
+#undef SRP_generate_client_master_secret
+#define SRP_generate_client_master_secret SRP_gen_client_master_secret
+
/* Hack some long UI names */
#undef UI_method_get_prompt_constructor
#define UI_method_get_prompt_constructor UI_method_get_prompt_constructr
diff --git a/deps/openssl/openssl/crypto/ts/ts.h b/deps/openssl/openssl/crypto/ts/ts.h
index 190e8a1bf..c2448e3c3 100644
--- a/deps/openssl/openssl/crypto/ts/ts.h
+++ b/deps/openssl/openssl/crypto/ts/ts.h
@@ -86,9 +86,6 @@
#include <openssl/dh.h>
#endif
-#include <openssl/evp.h>
-
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/deps/openssl/openssl/crypto/ts/ts_rsp_verify.c b/deps/openssl/openssl/crypto/ts/ts_rsp_verify.c
index e1f3b534a..afe16afbe 100644
--- a/deps/openssl/openssl/crypto/ts/ts_rsp_verify.c
+++ b/deps/openssl/openssl/crypto/ts/ts_rsp_verify.c
@@ -614,12 +614,15 @@ static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
goto err;
}
- EVP_DigestInit(&md_ctx, md);
+ if (!EVP_DigestInit(&md_ctx, md))
+ goto err;
while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0)
{
- EVP_DigestUpdate(&md_ctx, buffer, length);
+ if (!EVP_DigestUpdate(&md_ctx, buffer, length))
+ goto err;
}
- EVP_DigestFinal(&md_ctx, *imprint, NULL);
+ if (!EVP_DigestFinal(&md_ctx, *imprint, NULL))
+ goto err;
return 1;
err:
diff --git a/deps/openssl/openssl/crypto/ui/ui.h b/deps/openssl/openssl/crypto/ui/ui.h
index 2b1cfa228..bd78aa413 100644
--- a/deps/openssl/openssl/crypto/ui/ui.h
+++ b/deps/openssl/openssl/crypto/ui/ui.h
@@ -316,7 +316,7 @@ int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*);
int (*UI_method_get_flusher(UI_METHOD *method))(UI*);
int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*);
int (*UI_method_get_closer(UI_METHOD *method))(UI*);
-char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*);
+char * (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*);
/* The following functions are helpers for method writers to access relevant
data from a UI_STRING. */
diff --git a/deps/openssl/openssl/crypto/ui/ui_openssl.c b/deps/openssl/openssl/crypto/ui/ui_openssl.c
index b05cbf348..a38c7581e 100644
--- a/deps/openssl/openssl/crypto/ui/ui_openssl.c
+++ b/deps/openssl/openssl/crypto/ui/ui_openssl.c
@@ -122,9 +122,15 @@
* sigaction and fileno included. -pedantic would be more appropriate for
* the intended purposes, but we can't prevent users from adding -ansi.
*/
+#if defined(OPENSSL_SYSNAME_VXWORKS)
+#include <sys/types.h>
+#endif
+
+#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 2
#endif
+#endif
#include <signal.h>
#include <stdio.h>
#include <string.h>
@@ -184,7 +190,7 @@
# undef SGTTY
#endif
-#if defined(linux) && !defined(TERMIO) && !defined(__ANDROID__)
+#if defined(linux) && !defined(TERMIO)
# undef TERMIOS
# define TERMIO
# undef SGTTY
diff --git a/deps/openssl/openssl/crypto/vms_rms.h b/deps/openssl/openssl/crypto/vms_rms.h
index 00a00d993..00a00d993 100644..100755
--- a/deps/openssl/openssl/crypto/vms_rms.h
+++ b/deps/openssl/openssl/crypto/vms_rms.h
diff --git a/deps/openssl/openssl/crypto/whrlpool/Makefile b/deps/openssl/openssl/crypto/whrlpool/Makefile
index 566b99629..f4d46e4d1 100644
--- a/deps/openssl/openssl/crypto/whrlpool/Makefile
+++ b/deps/openssl/openssl/crypto/whrlpool/Makefile
@@ -89,5 +89,8 @@ clean:
wp_block.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
wp_block.o: ../../include/openssl/whrlpool.h wp_block.c wp_locl.h
-wp_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+wp_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+wp_dgst.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+wp_dgst.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+wp_dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
wp_dgst.o: ../../include/openssl/whrlpool.h wp_dgst.c wp_locl.h
diff --git a/deps/openssl/openssl/crypto/whrlpool/asm/wp-mmx.pl b/deps/openssl/openssl/crypto/whrlpool/asm/wp-mmx.pl
index 32cf16380..cb2381c22 100644
--- a/deps/openssl/openssl/crypto/whrlpool/asm/wp-mmx.pl
+++ b/deps/openssl/openssl/crypto/whrlpool/asm/wp-mmx.pl
@@ -119,7 +119,7 @@ $tbl="ebp";
&mov ("eax",&DWP(0,"esp"));
&mov ("ebx",&DWP(4,"esp"));
for($i=0;$i<8;$i++) {
- my $func = ($i==0)? movq : pxor;
+ my $func = ($i==0)? \&movq : \&pxor;
&movb (&LB("ecx"),&LB("eax"));
&movb (&LB("edx"),&HB("eax"));
&scale ("esi","ecx");
diff --git a/deps/openssl/openssl/crypto/whrlpool/asm/wp-x86_64.pl b/deps/openssl/openssl/crypto/whrlpool/asm/wp-x86_64.pl
index 87c0843dc..24b2ff60c 100644
--- a/deps/openssl/openssl/crypto/whrlpool/asm/wp-x86_64.pl
+++ b/deps/openssl/openssl/crypto/whrlpool/asm/wp-x86_64.pl
@@ -41,7 +41,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
sub L() { $code.=".byte ".join(',',@_)."\n"; }
sub LL(){ $code.=".byte ".join(',',@_).",".join(',',@_)."\n"; }
diff --git a/deps/openssl/openssl/crypto/whrlpool/whrlpool.h b/deps/openssl/openssl/crypto/whrlpool/whrlpool.h
index 03c91da11..9e01f5b07 100644
--- a/deps/openssl/openssl/crypto/whrlpool/whrlpool.h
+++ b/deps/openssl/openssl/crypto/whrlpool/whrlpool.h
@@ -24,6 +24,9 @@ typedef struct {
} WHIRLPOOL_CTX;
#ifndef OPENSSL_NO_WHIRLPOOL
+#ifdef OPENSSL_FIPS
+int private_WHIRLPOOL_Init(WHIRLPOOL_CTX *c);
+#endif
int WHIRLPOOL_Init (WHIRLPOOL_CTX *c);
int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *inp,size_t bytes);
void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *inp,size_t bits);
diff --git a/deps/openssl/openssl/crypto/whrlpool/wp_block.c b/deps/openssl/openssl/crypto/whrlpool/wp_block.c
index 221f6cc59..824ed1827 100644
--- a/deps/openssl/openssl/crypto/whrlpool/wp_block.c
+++ b/deps/openssl/openssl/crypto/whrlpool/wp_block.c
@@ -68,9 +68,9 @@ typedef unsigned long long u64;
CPUs this is actually faster! */
# endif
# define GO_FOR_MMX(ctx,inp,num) do { \
- extern unsigned long OPENSSL_ia32cap_P; \
+ extern unsigned int OPENSSL_ia32cap_P[]; \
void whirlpool_block_mmx(void *,const void *,size_t); \
- if (!(OPENSSL_ia32cap_P & (1<<23))) break; \
+ if (!(OPENSSL_ia32cap_P[0] & (1<<23))) break; \
whirlpool_block_mmx(ctx->H.c,inp,num); return; \
} while (0)
# endif
diff --git a/deps/openssl/openssl/crypto/whrlpool/wp_dgst.c b/deps/openssl/openssl/crypto/whrlpool/wp_dgst.c
index ee5c5c1bf..7e28bef51 100644
--- a/deps/openssl/openssl/crypto/whrlpool/wp_dgst.c
+++ b/deps/openssl/openssl/crypto/whrlpool/wp_dgst.c
@@ -52,9 +52,10 @@
*/
#include "wp_locl.h"
+#include <openssl/crypto.h>
#include <string.h>
-int WHIRLPOOL_Init (WHIRLPOOL_CTX *c)
+fips_md_init(WHIRLPOOL)
{
memset (c,0,sizeof(*c));
return(1);
diff --git a/deps/openssl/openssl/crypto/x509/by_dir.c b/deps/openssl/openssl/crypto/x509/by_dir.c
index 03293ac2d..27ca5150c 100644
--- a/deps/openssl/openssl/crypto/x509/by_dir.c
+++ b/deps/openssl/openssl/crypto/x509/by_dir.c
@@ -287,8 +287,6 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
int ok=0;
int i,j,k;
unsigned long h;
- unsigned long hash_array[2];
- int hash_index;
BUF_MEM *b=NULL;
X509_OBJECT stmp,*tmp;
const char *postfix="";
@@ -325,11 +323,6 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
ctx=(BY_DIR *)xl->method_data;
h=X509_NAME_hash(name);
- hash_array[0]=h;
- hash_array[1]=X509_NAME_hash_old(name);
- for (hash_index=0; hash_index < 2; hash_index++)
- {
- h=hash_array[hash_index];
for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
{
BY_DIR_ENTRY *ent;
@@ -483,7 +476,6 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
goto finish;
}
}
- }
finish:
if (b != NULL) BUF_MEM_free(b);
return(ok);
diff --git a/deps/openssl/openssl/crypto/x509/x509.h b/deps/openssl/openssl/crypto/x509/x509.h
index e6f8a4039..092dd7450 100644
--- a/deps/openssl/openssl/crypto/x509/x509.h
+++ b/deps/openssl/openssl/crypto/x509/x509.h
@@ -657,11 +657,15 @@ int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+int X509_signature_dump(BIO *bp,const ASN1_STRING *sig, int indent);
int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig);
int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
@@ -763,6 +767,7 @@ X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
X509_ALGOR *algor);
+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
X509_NAME *X509_NAME_dup(X509_NAME *xn);
X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
@@ -896,6 +901,9 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
ASN1_BIT_STRING *signature,
void *data, EVP_PKEY *pkey, const EVP_MD *type);
+int ASN1_item_sign_ctx(const ASN1_ITEM *it,
+ X509_ALGOR *algor1, X509_ALGOR *algor2,
+ ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx);
#endif
int X509_set_version(X509 *x,long version);
@@ -1161,6 +1169,9 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid);
+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+ int prf_nid, int keylen);
+
/* PKCS#8 utilities */
DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
diff --git a/deps/openssl/openssl/crypto/x509/x509_cmp.c b/deps/openssl/openssl/crypto/x509/x509_cmp.c
index 4bc9da07e..352aa3743 100644
--- a/deps/openssl/openssl/crypto/x509/x509_cmp.c
+++ b/deps/openssl/openssl/crypto/x509/x509_cmp.c
@@ -86,16 +86,20 @@ unsigned long X509_issuer_and_serial_hash(X509 *a)
EVP_MD_CTX_init(&ctx);
f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
- ret=strlen(f);
- EVP_DigestInit_ex(&ctx, EVP_md5(), NULL);
- EVP_DigestUpdate(&ctx,(unsigned char *)f,ret);
+ if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
+ goto err;
OPENSSL_free(f);
- EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
- (unsigned long)a->cert_info->serialNumber->length);
- EVP_DigestFinal_ex(&ctx,&(md[0]),NULL);
+ if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
+ (unsigned long)a->cert_info->serialNumber->length))
+ goto err;
+ if (!EVP_DigestFinal_ex(&ctx,&(md[0]),NULL))
+ goto err;
ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
)&0xffffffffL;
+ err:
EVP_MD_CTX_cleanup(&ctx);
return(ret);
}
@@ -219,7 +223,9 @@ unsigned long X509_NAME_hash(X509_NAME *x)
/* Make sure X509_NAME structure contains valid cached encoding */
i2d_X509_NAME(x,NULL);
- EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), NULL);
+ if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
+ NULL))
+ return 0;
ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
@@ -234,16 +240,22 @@ unsigned long X509_NAME_hash(X509_NAME *x)
unsigned long X509_NAME_hash_old(X509_NAME *x)
{
+ EVP_MD_CTX md_ctx;
unsigned long ret=0;
unsigned char md[16];
/* Make sure X509_NAME structure contains valid cached encoding */
i2d_X509_NAME(x,NULL);
- EVP_Digest(x->bytes->data, x->bytes->length, md, NULL, EVP_md5(), NULL);
+ EVP_MD_CTX_init(&md_ctx);
+ EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
+ && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
+ && EVP_DigestFinal_ex(&md_ctx,md,NULL))
+ ret=(((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
+ ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
+ )&0xffffffffL;
+ EVP_MD_CTX_cleanup(&md_ctx);
- ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
- ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
- )&0xffffffffL;
return(ret);
}
#endif
diff --git a/deps/openssl/openssl/crypto/x509/x509_lu.c b/deps/openssl/openssl/crypto/x509/x509_lu.c
index 3a6e04a1d..38525a8cd 100644
--- a/deps/openssl/openssl/crypto/x509/x509_lu.c
+++ b/deps/openssl/openssl/crypto/x509/x509_lu.c
@@ -87,7 +87,7 @@ void X509_LOOKUP_free(X509_LOOKUP *ctx)
if (ctx == NULL) return;
if ( (ctx->method != NULL) &&
(ctx->method->free != NULL))
- ctx->method->free(ctx);
+ (*ctx->method->free)(ctx);
OPENSSL_free(ctx);
}
diff --git a/deps/openssl/openssl/crypto/x509/x509_vfy.c b/deps/openssl/openssl/crypto/x509/x509_vfy.c
index 701ec565e..12d71f54e 100644
--- a/deps/openssl/openssl/crypto/x509/x509_vfy.c
+++ b/deps/openssl/openssl/crypto/x509/x509_vfy.c
@@ -153,7 +153,6 @@ static int x509_subject_cmp(X509 **a, X509 **b)
int X509_verify_cert(X509_STORE_CTX *ctx)
{
X509 *x,*xtmp,*chain_ss=NULL;
- X509_NAME *xn;
int bad_chain = 0;
X509_VERIFY_PARAM *param = ctx->param;
int depth,i,ok=0;
@@ -205,7 +204,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
*/
/* If we are self signed, we break */
- xn=X509_get_issuer_name(x);
if (ctx->check_issued(ctx, x,x)) break;
/* If we were passed a cert chain, use it first */
@@ -242,7 +240,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
i=sk_X509_num(ctx->chain);
x=sk_X509_value(ctx->chain,i-1);
- xn = X509_get_subject_name(x);
if (ctx->check_issued(ctx, x, x))
{
/* we have a self signed certificate */
@@ -291,7 +288,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (depth < num) break;
/* If we are self signed, we break */
- xn=X509_get_issuer_name(x);
if (ctx->check_issued(ctx,x,x)) break;
ok = ctx->get_issuer(&xtmp, ctx, x);
@@ -310,7 +306,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
}
/* we now have our chain, lets check it... */
- xn=X509_get_issuer_name(x);
/* Is last certificate looked up self signed? */
if (!ctx->check_issued(ctx,x,x))
@@ -877,7 +872,7 @@ static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
{
ASN1_OCTET_STRING *exta, *extb;
int i;
- i = X509_CRL_get_ext_by_NID(a, nid, 0);
+ i = X509_CRL_get_ext_by_NID(a, nid, -1);
if (i >= 0)
{
/* Can't have multiple occurrences */
@@ -888,7 +883,7 @@ static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
else
exta = NULL;
- i = X509_CRL_get_ext_by_NID(b, nid, 0);
+ i = X509_CRL_get_ext_by_NID(b, nid, -1);
if (i >= 0)
{
diff --git a/deps/openssl/openssl/crypto/x509/x509type.c b/deps/openssl/openssl/crypto/x509/x509type.c
index 3385ad3f6..9702ec531 100644
--- a/deps/openssl/openssl/crypto/x509/x509type.c
+++ b/deps/openssl/openssl/crypto/x509/x509type.c
@@ -100,20 +100,26 @@ int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
break;
}
- i=X509_get_signature_type(x);
- switch (i)
+ i=OBJ_obj2nid(x->sig_alg->algorithm);
+ if (i && OBJ_find_sigid_algs(i, NULL, &i))
{
- case EVP_PKEY_RSA:
- ret|=EVP_PKS_RSA;
- break;
- case EVP_PKEY_DSA:
- ret|=EVP_PKS_DSA;
- break;
- case EVP_PKEY_EC:
- ret|=EVP_PKS_EC;
- break;
- default:
- break;
+
+ switch (i)
+ {
+ case NID_rsaEncryption:
+ case NID_rsa:
+ ret|=EVP_PKS_RSA;
+ break;
+ case NID_dsa:
+ case NID_dsa_2:
+ ret|=EVP_PKS_DSA;
+ break;
+ case NID_X9_62_id_ecPublicKey:
+ ret|=EVP_PKS_EC;
+ break;
+ default:
+ break;
+ }
}
if (EVP_PKEY_size(pk) <= 1024/8)/* /8 because it's 1024 bits we look
diff --git a/deps/openssl/openssl/crypto/x509/x_all.c b/deps/openssl/openssl/crypto/x509/x_all.c
index 8ec88c215..b94aeeb87 100644
--- a/deps/openssl/openssl/crypto/x509/x_all.c
+++ b/deps/openssl/openssl/crypto/x509/x_all.c
@@ -95,12 +95,25 @@ int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
x->sig_alg, x->signature, x->cert_info,pkey,md));
}
+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
+ {
+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
+ x->cert_info->signature,
+ x->sig_alg, x->signature, x->cert_info, ctx);
+ }
+
int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
{
return(ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO),x->sig_alg, NULL,
x->signature, x->req_info,pkey,md));
}
+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
+ {
+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
+ x->sig_alg, NULL, x->signature, x->req_info, ctx);
+ }
+
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
{
x->crl->enc.modified = 1;
@@ -108,6 +121,12 @@ int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
x->sig_alg, x->signature, x->crl,pkey,md));
}
+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
+ {
+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
+ x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx);
+ }
+
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
{
return(ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,NULL,
diff --git a/deps/openssl/openssl/crypto/x509v3/v3_asid.c b/deps/openssl/openssl/crypto/x509v3/v3_asid.c
index 3f434c060..1587e8ed7 100644
--- a/deps/openssl/openssl/crypto/x509v3/v3_asid.c
+++ b/deps/openssl/openssl/crypto/x509v3/v3_asid.c
@@ -358,6 +358,20 @@ static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
goto done;
}
+ /*
+ * Check for inverted range.
+ */
+ i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
+ {
+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ ASN1_INTEGER *a_min, *a_max;
+ if (a != NULL && a->type == ASIdOrRange_range) {
+ extract_min_max(a, &a_min, &a_max);
+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
+ goto done;
+ }
+ }
+
ret = 1;
done:
@@ -392,9 +406,18 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
return 1;
/*
- * We have a list. Sort it.
+ * If not a list, or if empty list, it's broken.
+ */
+ if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
+ sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ return 0;
+ }
+
+ /*
+ * We have a non-empty list. Sort it.
*/
- OPENSSL_assert(choice->type == ASIdentifierChoice_asIdsOrRanges);
sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
/*
@@ -415,6 +438,13 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
/*
+ * Punt inverted ranges.
+ */
+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
+ ASN1_INTEGER_cmp(b_min, b_max) > 0)
+ goto done;
+
+ /*
* Check for overlaps.
*/
if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
@@ -465,12 +495,26 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
break;
}
ASIdOrRange_free(b);
- sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
+ (void) sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
i--;
continue;
}
}
+ /*
+ * Check for final inverted range.
+ */
+ i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
+ {
+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ ASN1_INTEGER *a_min, *a_max;
+ if (a != NULL && a->type == ASIdOrRange_range) {
+ extract_min_max(a, &a_min, &a_max);
+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
+ goto done;
+ }
+ }
+
OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
ret = 1;
@@ -498,6 +542,7 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
struct v3_ext_ctx *ctx,
STACK_OF(CONF_VALUE) *values)
{
+ ASN1_INTEGER *min = NULL, *max = NULL;
ASIdentifiers *asid = NULL;
int i;
@@ -508,7 +553,6 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
- ASN1_INTEGER *min = NULL, *max = NULL;
int i1, i2, i3, is_range, which;
/*
@@ -578,18 +622,19 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
max = s2i_ASN1_INTEGER(NULL, s + i2);
OPENSSL_free(s);
if (min == NULL || max == NULL) {
- ASN1_INTEGER_free(min);
- ASN1_INTEGER_free(max);
X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
goto err;
}
+ if (ASN1_INTEGER_cmp(min, max) > 0) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_VALUE_ERROR);
+ goto err;
+ }
}
if (!v3_asid_add_id_or_range(asid, which, min, max)) {
- ASN1_INTEGER_free(min);
- ASN1_INTEGER_free(max);
X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
goto err;
}
+ min = max = NULL;
}
/*
@@ -601,6 +646,8 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
err:
ASIdentifiers_free(asid);
+ ASN1_INTEGER_free(min);
+ ASN1_INTEGER_free(max);
return NULL;
}
diff --git a/deps/openssl/openssl/crypto/x509v3/v3_purp.c b/deps/openssl/openssl/crypto/x509v3/v3_purp.c
index 181bd3497..ad688657e 100644
--- a/deps/openssl/openssl/crypto/x509v3/v3_purp.c
+++ b/deps/openssl/openssl/crypto/x509v3/v3_purp.c
@@ -474,11 +474,11 @@ static void x509v3_cache_extensions(X509 *x)
for (i = 0; i < X509_get_ext_count(x); i++)
{
ex = X509_get_ext(x, i);
- if (!X509_EXTENSION_get_critical(ex))
- continue;
if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
== NID_freshest_crl)
x->ex_flags |= EXFLAG_FRESHEST;
+ if (!X509_EXTENSION_get_critical(ex))
+ continue;
if (!X509_supported_extension(ex))
{
x->ex_flags |= EXFLAG_CRITICAL;
diff --git a/deps/openssl/openssl/crypto/x509v3/v3_skey.c b/deps/openssl/openssl/crypto/x509v3/v3_skey.c
index 202c9e489..0a984fbaa 100644
--- a/deps/openssl/openssl/crypto/x509v3/v3_skey.c
+++ b/deps/openssl/openssl/crypto/x509v3/v3_skey.c
@@ -129,7 +129,8 @@ static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
goto err;
}
- EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL);
+ if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL))
+ goto err;
if(!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
X509V3err(X509V3_F_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
diff --git a/deps/openssl/openssl/crypto/x86_64cpuid.pl b/deps/openssl/openssl/crypto/x86_64cpuid.pl
index c96821a3c..6ebfd017e 100644
--- a/deps/openssl/openssl/crypto/x86_64cpuid.pl
+++ b/deps/openssl/openssl/crypto/x86_64cpuid.pl
@@ -7,15 +7,25 @@ if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-open STDOUT,"| $^X ${dir}perlasm/x86_64-xlate.pl $flavour $output";
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order
+ ("%rdi","%rsi","%rdx","%rcx"); # Unix order
-if ($win64) { $arg1="%rcx"; $arg2="%rdx"; }
-else { $arg1="%rdi"; $arg2="%rsi"; }
print<<___;
.extern OPENSSL_cpuid_setup
+.hidden OPENSSL_cpuid_setup
.section .init
call OPENSSL_cpuid_setup
+.hidden OPENSSL_ia32cap_P
+.comm OPENSSL_ia32cap_P,8,4
+
.text
.globl OPENSSL_atomic_add
@@ -46,7 +56,7 @@ OPENSSL_rdtsc:
.type OPENSSL_ia32_cpuid,\@abi-omnipotent
.align 16
OPENSSL_ia32_cpuid:
- mov %rbx,%r8
+ mov %rbx,%r8 # save %rbx
xor %eax,%eax
cpuid
@@ -78,7 +88,15 @@ OPENSSL_ia32_cpuid:
# AMD specific
mov \$0x80000000,%eax
cpuid
- cmp \$0x80000008,%eax
+ cmp \$0x80000001,%eax
+ jb .Lintel
+ mov %eax,%r10d
+ mov \$0x80000001,%eax
+ cpuid
+ or %ecx,%r9d
+ and \$0x00000801,%r9d # isolate AMD XOP bit, 1<<11
+
+ cmp \$0x80000008,%r10d
jb .Lintel
mov \$0x80000008,%eax
@@ -89,12 +107,12 @@ OPENSSL_ia32_cpuid:
mov \$1,%eax
cpuid
bt \$28,%edx # test hyper-threading bit
- jnc .Ldone
+ jnc .Lgeneric
shr \$16,%ebx # number of logical processors
cmp %r10b,%bl
- ja .Ldone
+ ja .Lgeneric
and \$0xefffffff,%edx # ~(1<<28)
- jmp .Ldone
+ jmp .Lgeneric
.Lintel:
cmp \$4,%r11d
@@ -111,30 +129,47 @@ OPENSSL_ia32_cpuid:
.Lnocacheinfo:
mov \$1,%eax
cpuid
+ and \$0xbfefffff,%edx # force reserved bits to 0
cmp \$0,%r9d
jne .Lnotintel
- or \$0x00100000,%edx # use reserved 20th bit to engage RC4_CHAR
+ or \$0x40000000,%edx # set reserved bit#30 on Intel CPUs
and \$15,%ah
cmp \$15,%ah # examine Family ID
- je .Lnotintel
- or \$0x40000000,%edx # use reserved bit to skip unrolled loop
+ jne .Lnotintel
+ or \$0x00100000,%edx # set reserved bit#20 to engage RC4_CHAR
.Lnotintel:
bt \$28,%edx # test hyper-threading bit
- jnc .Ldone
+ jnc .Lgeneric
and \$0xefffffff,%edx # ~(1<<28)
cmp \$0,%r10d
- je .Ldone
+ je .Lgeneric
or \$0x10000000,%edx # 1<<28
shr \$16,%ebx
cmp \$1,%bl # see if cache is shared
- ja .Ldone
+ ja .Lgeneric
and \$0xefffffff,%edx # ~(1<<28)
+.Lgeneric:
+ and \$0x00000800,%r9d # isolate AMD XOP flag
+ and \$0xfffff7ff,%ecx
+ or %ecx,%r9d # merge AMD XOP flag
+
+ mov %edx,%r10d # %r9d:%r10d is copy of %ecx:%edx
+ bt \$27,%r9d # check OSXSAVE bit
+ jnc .Lclear_avx
+ xor %ecx,%ecx # XCR0
+ .byte 0x0f,0x01,0xd0 # xgetbv
+ and \$6,%eax # isolate XMM and YMM state support
+ cmp \$6,%eax
+ je .Ldone
+.Lclear_avx:
+ mov \$0xefffe7ff,%eax # ~(1<<28|1<<12|1<<11)
+ and %eax,%r9d # clear AVX, FMA and AMD XOP bits
.Ldone:
- shl \$32,%rcx
- mov %edx,%eax
- mov %r8,%rbx
- or %rcx,%rax
+ shl \$32,%r9
+ mov %r10d,%eax
+ mov %r8,%rbx # restore %rbx
+ or %r9,%rax
ret
.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
@@ -229,4 +264,21 @@ OPENSSL_wipe_cpu:
.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
___
+print<<___;
+.globl OPENSSL_ia32_rdrand
+.type OPENSSL_ia32_rdrand,\@abi-omnipotent
+.align 16
+OPENSSL_ia32_rdrand:
+ mov \$8,%ecx
+.Loop_rdrand:
+ rdrand %rax
+ jc .Lbreak_rdrand
+ loop .Loop_rdrand
+.Lbreak_rdrand:
+ cmp \$0,%rax
+ cmove %rcx,%rax
+ ret
+.size OPENSSL_ia32_rdrand,.-OPENSSL_ia32_rdrand
+___
+
close STDOUT; # flush
diff --git a/deps/openssl/openssl/crypto/x86cpuid.pl b/deps/openssl/openssl/crypto/x86cpuid.pl
index a7464af19..c18b0e248 100644
--- a/deps/openssl/openssl/crypto/x86cpuid.pl
+++ b/deps/openssl/openssl/crypto/x86cpuid.pl
@@ -19,9 +19,9 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
&pushf ();
&pop ("eax");
&xor ("ecx","eax");
- &bt ("ecx",21);
- &jnc (&label("done"));
&xor ("eax","eax");
+ &bt ("ecx",21);
+ &jnc (&label("nocpuid"));
&cpuid ();
&mov ("edi","eax"); # max value for standard query level
@@ -51,7 +51,14 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
# AMD specific
&mov ("eax",0x80000000);
&cpuid ();
- &cmp ("eax",0x80000008);
+ &cmp ("eax",0x80000001);
+ &jb (&label("intel"));
+ &mov ("esi","eax");
+ &mov ("eax",0x80000001);
+ &cpuid ();
+ &or ("ebp","ecx");
+ &and ("ebp",1<<11|1); # isolate XOP bit
+ &cmp ("esi",0x80000008);
&jb (&label("intel"));
&mov ("eax",0x80000008);
@@ -62,13 +69,13 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
&mov ("eax",1);
&cpuid ();
&bt ("edx",28);
- &jnc (&label("done"));
+ &jnc (&label("generic"));
&shr ("ebx",16);
&and ("ebx",0xff);
&cmp ("ebx","esi");
- &ja (&label("done"));
+ &ja (&label("generic"));
&and ("edx",0xefffffff); # clear hyper-threading bit
- &jmp (&label("done"));
+ &jmp (&label("generic"));
&set_label("intel");
&cmp ("edi",4);
@@ -85,27 +92,51 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
&set_label("nocacheinfo");
&mov ("eax",1);
&cpuid ();
+ &and ("edx",0xbfefffff); # force reserved bits #20, #30 to 0
&cmp ("ebp",0);
- &jne (&label("notP4"));
+ &jne (&label("notintel"));
+ &or ("edx",1<<30); # set reserved bit#30 on Intel CPUs
&and (&HB("eax"),15); # familiy ID
&cmp (&HB("eax"),15); # P4?
- &jne (&label("notP4"));
- &or ("edx",1<<20); # use reserved bit to engage RC4_CHAR
-&set_label("notP4");
+ &jne (&label("notintel"));
+ &or ("edx",1<<20); # set reserved bit#20 to engage RC4_CHAR
+&set_label("notintel");
&bt ("edx",28); # test hyper-threading bit
- &jnc (&label("done"));
+ &jnc (&label("generic"));
&and ("edx",0xefffffff);
&cmp ("edi",0);
- &je (&label("done"));
+ &je (&label("generic"));
&or ("edx",0x10000000);
&shr ("ebx",16);
&cmp (&LB("ebx"),1);
- &ja (&label("done"));
+ &ja (&label("generic"));
&and ("edx",0xefffffff); # clear hyper-threading bit if not
+
+&set_label("generic");
+ &and ("ebp",1<<11); # isolate AMD XOP flag
+ &and ("ecx",0xfffff7ff); # force 11th bit to 0
+ &mov ("esi","edx");
+ &or ("ebp","ecx"); # merge AMD XOP flag
+
+ &bt ("ecx",27); # check OSXSAVE bit
+ &jnc (&label("clear_avx"));
+ &xor ("ecx","ecx");
+ &data_byte(0x0f,0x01,0xd0); # xgetbv
+ &and ("eax",6);
+ &cmp ("eax",6);
+ &je (&label("done"));
+ &cmp ("eax",2);
+ &je (&label("clear_avx"));
+&set_label("clear_xmm");
+ &and ("ebp",0xfdfffffd); # clear AESNI and PCLMULQDQ bits
+ &and ("esi",0xfeffffff); # clear FXSR
+&set_label("clear_avx");
+ &and ("ebp",0xefffe7ff); # clear AVX, FMA and AMD XOP bits
&set_label("done");
- &mov ("eax","edx");
- &mov ("edx","ecx");
+ &mov ("eax","esi");
+ &mov ("edx","ebp");
+&set_label("nocpuid");
&function_end("OPENSSL_ia32_cpuid");
&external_label("OPENSSL_ia32cap_P");
@@ -134,7 +165,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
&jnz (&label("nohalt")); # not enough privileges
&pushf ();
- &pop ("eax")
+ &pop ("eax");
&bt ("eax",9);
&jnc (&label("nohalt")); # interrupts are disabled
@@ -199,8 +230,9 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
&bt (&DWP(0,"ecx"),1);
&jnc (&label("no_x87"));
if ($sse2) {
- &bt (&DWP(0,"ecx"),26);
- &jnc (&label("no_sse2"));
+ &and ("ecx",1<<26|1<<24); # check SSE2 and FXSR bits
+ &cmp ("ecx",1<<26|1<<24);
+ &jne (&label("no_sse2"));
&pxor ("xmm0","xmm0");
&pxor ("xmm1","xmm1");
&pxor ("xmm2","xmm2");
@@ -248,7 +280,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
# arguments is 1 or 2!
&function_begin_B("OPENSSL_indirect_call");
{
- my $i,$max=7; # $max has to be chosen as 4*n-1
+ my ($max,$i)=(7,); # $max has to be chosen as 4*n-1
# in order to preserve eventual
# stack alignment
&push ("ebp");
@@ -307,6 +339,18 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
&ret ();
&function_end_B("OPENSSL_cleanse");
+&function_begin_B("OPENSSL_ia32_rdrand");
+ &mov ("ecx",8);
+&set_label("loop");
+ &rdrand ("eax");
+ &jc (&label("break"));
+ &loop (&label("loop"));
+&set_label("break");
+ &cmp ("eax",0);
+ &cmove ("eax","ecx");
+ &ret ();
+&function_end_B("OPENSSL_ia32_rdrand");
+
&initseg("OPENSSL_cpuid_setup");
&asm_finish();
diff --git a/deps/openssl/openssl/doc/HOWTO/proxy_certificates.txt b/deps/openssl/openssl/doc/HOWTO/proxy_certificates.txt
index 3d36b02f6..f98ec3607 100644
--- a/deps/openssl/openssl/doc/HOWTO/proxy_certificates.txt
+++ b/deps/openssl/openssl/doc/HOWTO/proxy_certificates.txt
@@ -57,7 +57,7 @@ following methods:
- in all other cases, proxy certificate validation can be enabled
before starting the application by setting the envirnoment variable
- OPENSSL_ALLOW_PROXY with some non-empty value.
+ OPENSSL_ALLOW_PROXY_CERTS with some non-empty value.
There are thoughts to allow proxy certificates with a line in the
default openssl.cnf, but that's still in the future.
diff --git a/deps/openssl/openssl/doc/apps/CA.pl.pod b/deps/openssl/openssl/doc/apps/CA.pl.pod
index ed69952f3..d326101cd 100644
--- a/deps/openssl/openssl/doc/apps/CA.pl.pod
+++ b/deps/openssl/openssl/doc/apps/CA.pl.pod
@@ -39,13 +39,13 @@ prints a usage message.
=item B<-newcert>
-creates a new self signed certificate. The private key and certificate are
-written to the file "newreq.pem".
+creates a new self signed certificate. The private key is written to the file
+"newkey.pem" and the request written to the file "newreq.pem".
=item B<-newreq>
-creates a new certificate request. The private key and request are
-written to the file "newreq.pem".
+creates a new certificate request. The private key is written to the file
+"newkey.pem" and the request written to the file "newreq.pem".
=item B<-newreq-nodes>
diff --git a/deps/openssl/openssl/doc/apps/genpkey.pod b/deps/openssl/openssl/doc/apps/genpkey.pod
index 1611b5ca7..c74d097fb 100644
--- a/deps/openssl/openssl/doc/apps/genpkey.pod
+++ b/deps/openssl/openssl/doc/apps/genpkey.pod
@@ -114,6 +114,8 @@ hexadecimal value if preceded by B<0x>. Default value is 65537.
The number of bits in the generated parameters. If not specified 1024 is used.
+=back
+
=head1 DH PARAMETER GENERATION OPTIONS
=over 4
diff --git a/deps/openssl/openssl/doc/apps/openssl.pod b/deps/openssl/openssl/doc/apps/openssl.pod
index 738142e9f..64a160c20 100644
--- a/deps/openssl/openssl/doc/apps/openssl.pod
+++ b/deps/openssl/openssl/doc/apps/openssl.pod
@@ -287,8 +287,6 @@ SHA Digest
SHA-1 Digest
-=back
-
=item B<sha224>
SHA-224 Digest
@@ -305,6 +303,8 @@ SHA-384 Digest
SHA-512 Digest
+=back
+
=head2 ENCODING AND CIPHER COMMANDS
=over 10
diff --git a/deps/openssl/openssl/doc/apps/verify.pod b/deps/openssl/openssl/doc/apps/verify.pod
index 336098f1e..da683004b 100644
--- a/deps/openssl/openssl/doc/apps/verify.pod
+++ b/deps/openssl/openssl/doc/apps/verify.pod
@@ -54,35 +54,37 @@ in PEM format concatenated together.
=item B<-untrusted file>
A file of untrusted certificates. The file should contain multiple certificates
+in PEM format concatenated together.
=item B<-purpose purpose>
-the intended use for the certificate. Without this option no chain verification
-will be done. Currently accepted uses are B<sslclient>, B<sslserver>,
-B<nssslserver>, B<smimesign>, B<smimeencrypt>. See the B<VERIFY OPERATION>
-section for more information.
+The intended use for the certificate. If this option is not specified,
+B<verify> will not consider certificate purpose during chain verification.
+Currently accepted uses are B<sslclient>, B<sslserver>, B<nssslserver>,
+B<smimesign>, B<smimeencrypt>. See the B<VERIFY OPERATION> section for more
+information.
=item B<-help>
-prints out a usage message.
+Print out a usage message.
=item B<-verbose>
-print extra information about the operations being performed.
+Print extra information about the operations being performed.
=item B<-issuer_checks>
-print out diagnostics relating to searches for the issuer certificate
-of the current certificate. This shows why each candidate issuer
-certificate was rejected. However the presence of rejection messages
-does not itself imply that anything is wrong: during the normal
-verify process several rejections may take place.
+Print out diagnostics relating to searches for the issuer certificate of the
+current certificate. This shows why each candidate issuer certificate was
+rejected. The presence of rejection messages does not itself imply that
+anything is wrong; during the normal verification process, several
+rejections may take place.
=item B<-policy arg>
-Enable policy processing and add B<arg> to the user-initial-policy-set
-(see RFC3280 et al). The policy B<arg> can be an object name an OID in numeric
-form. This argument can appear more than once.
+Enable policy processing and add B<arg> to the user-initial-policy-set (see
+RFC5280). The policy B<arg> can be an object name an OID in numeric form.
+This argument can appear more than once.
=item B<-policy_check>
@@ -90,41 +92,40 @@ Enables certificate policy processing.
=item B<-explicit_policy>
-Set policy variable require-explicit-policy (see RFC3280 et al).
+Set policy variable require-explicit-policy (see RFC5280).
=item B<-inhibit_any>
-Set policy variable inhibit-any-policy (see RFC3280 et al).
+Set policy variable inhibit-any-policy (see RFC5280).
=item B<-inhibit_map>
-Set policy variable inhibit-policy-mapping (see RFC3280 et al).
+Set policy variable inhibit-policy-mapping (see RFC5280).
=item B<-policy_print>
-Print out diagnostics, related to policy checking
+Print out diagnostics related to policy processing.
=item B<-crl_check>
-Checks end entity certificate validity by attempting to lookup a valid CRL.
+Checks end entity certificate validity by attempting to look up a valid CRL.
If a valid CRL cannot be found an error occurs.
=item B<-crl_check_all>
Checks the validity of B<all> certificates in the chain by attempting
-to lookup valid CRLs.
+to look up valid CRLs.
=item B<-ignore_critical>
Normally if an unhandled critical extension is present which is not
-supported by OpenSSL the certificate is rejected (as required by
-RFC3280 et al). If this option is set critical extensions are
-ignored.
+supported by OpenSSL the certificate is rejected (as required by RFC5280).
+If this option is set critical extensions are ignored.
=item B<-x509_strict>
-Disable workarounds for broken certificates which have to be disabled
-for strict X.509 compliance.
+For strict X.509 compliance, disable non-compliant workarounds for broken
+certificates.
=item B<-extended_crl>
@@ -142,16 +143,15 @@ because it doesn't add any security.
=item B<->
-marks the last option. All arguments following this are assumed to be
+Indicates the last option. All arguments following this are assumed to be
certificate files. This is useful if the first certificate filename begins
with a B<->.
=item B<certificates>
-one or more certificates to verify. If no certificate filenames are included
-then an attempt is made to read a certificate from standard input. They should
-all be in PEM format.
-
+One or more certificates to verify. If no certificates are given, B<verify>
+will attempt to read a certificate from standard input. Certificates must be
+in PEM format.
=back
diff --git a/deps/openssl/openssl/doc/apps/x509.pod b/deps/openssl/openssl/doc/apps/x509.pod
index 3002b0812..d2d9eb812 100644
--- a/deps/openssl/openssl/doc/apps/x509.pod
+++ b/deps/openssl/openssl/doc/apps/x509.pod
@@ -29,6 +29,7 @@ B<openssl> B<x509>
[B<-purpose>]
[B<-dates>]
[B<-modulus>]
+[B<-pubkey>]
[B<-fingerprint>]
[B<-alias>]
[B<-noout>]
@@ -135,6 +136,10 @@ section for more information.
this option prevents output of the encoded version of the request.
+=item B<-pubkey>
+
+outputs the the certificate's SubjectPublicKeyInfo block in PEM format.
+
=item B<-modulus>
this option prints out the value of the modulus of the public key
diff --git a/deps/openssl/openssl/doc/crypto/EVP_DigestInit.pod b/deps/openssl/openssl/doc/crypto/EVP_DigestInit.pod
index 5b477ac6e..367691cc7 100644
--- a/deps/openssl/openssl/doc/crypto/EVP_DigestInit.pod
+++ b/deps/openssl/openssl/doc/crypto/EVP_DigestInit.pod
@@ -6,7 +6,8 @@ EVP_MD_CTX_init, EVP_MD_CTX_create, EVP_DigestInit_ex, EVP_DigestUpdate,
EVP_DigestFinal_ex, EVP_MD_CTX_cleanup, EVP_MD_CTX_destroy, EVP_MAX_MD_SIZE,
EVP_MD_CTX_copy_ex, EVP_MD_CTX_copy, EVP_MD_type, EVP_MD_pkey_type, EVP_MD_size,
EVP_MD_block_size, EVP_MD_CTX_md, EVP_MD_CTX_size, EVP_MD_CTX_block_size, EVP_MD_CTX_type,
-EVP_md_null, EVP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_dss, EVP_dss1, EVP_mdc2,
+EVP_md_null, EVP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_sha224, EVP_sha256,
+EVP_sha384, EVP_sha512, EVP_dss, EVP_dss1, EVP_mdc2,
EVP_ripemd160, EVP_get_digestbyname, EVP_get_digestbynid, EVP_get_digestbyobj -
EVP digest routines
@@ -33,16 +34,15 @@ EVP digest routines
int EVP_MD_CTX_copy(EVP_MD_CTX *out,EVP_MD_CTX *in);
- #define EVP_MAX_MD_SIZE (16+20) /* The SSLv3 md5+sha1 type */
+ #define EVP_MAX_MD_SIZE 64 /* SHA512 */
+ int EVP_MD_type(const EVP_MD *md);
+ int EVP_MD_pkey_type(const EVP_MD *md);
+ int EVP_MD_size(const EVP_MD *md);
+ int EVP_MD_block_size(const EVP_MD *md);
- #define EVP_MD_type(e) ((e)->type)
- #define EVP_MD_pkey_type(e) ((e)->pkey_type)
- #define EVP_MD_size(e) ((e)->md_size)
- #define EVP_MD_block_size(e) ((e)->block_size)
-
- #define EVP_MD_CTX_md(e) (e)->digest)
- #define EVP_MD_CTX_size(e) EVP_MD_size((e)->digest)
+ const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+ #define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e))
#define EVP_MD_CTX_block_size(e) EVP_MD_block_size((e)->digest)
#define EVP_MD_CTX_type(e) EVP_MD_type((e)->digest)
@@ -56,6 +56,11 @@ EVP digest routines
const EVP_MD *EVP_mdc2(void);
const EVP_MD *EVP_ripemd160(void);
+ const EVP_MD *EVP_sha224(void);
+ const EVP_MD *EVP_sha256(void);
+ const EVP_MD *EVP_sha384(void);
+ const EVP_MD *EVP_sha512(void);
+
const EVP_MD *EVP_get_digestbyname(const char *name);
#define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
#define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
@@ -124,12 +129,14 @@ B<EVP_MD_CTX>.
EVP_MD_pkey_type() returns the NID of the public key signing algorithm associated
with this digest. For example EVP_sha1() is associated with RSA so this will
-return B<NID_sha1WithRSAEncryption>. This "link" between digests and signature
-algorithms may not be retained in future versions of OpenSSL.
+return B<NID_sha1WithRSAEncryption>. Since digests and signature algorithms
+are no longer linked this function is only retained for compatibility
+reasons.
-EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_mdc2() and EVP_ripemd160()
-return B<EVP_MD> structures for the MD2, MD5, SHA, SHA1, MDC2 and RIPEMD160 digest
-algorithms respectively. The associated signature algorithm is RSA in each case.
+EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_sha224(), EVP_sha256(),
+EVP_sha384(), EVP_sha512(), EVP_mdc2() and EVP_ripemd160() return B<EVP_MD>
+structures for the MD2, MD5, SHA, SHA1, SHA224, SHA256, SHA384, SHA512, MDC2
+and RIPEMD160 digest algorithms respectively.
EVP_dss() and EVP_dss1() return B<EVP_MD> structures for SHA and SHA1 digest
algorithms but using DSS (DSA) for the signature algorithm. Note: there is
@@ -171,8 +178,8 @@ The B<EVP> interface to message digests should almost always be used in
preference to the low level interfaces. This is because the code then becomes
transparent to the digest used and much more flexible.
-SHA1 is the digest of choice for new applications. The other digest algorithms
-are still in common use.
+New applications should use the SHA2 digest algorithms such as SHA256.
+The other digest algorithms are still in common use.
For most applications the B<impl> parameter to EVP_DigestInit_ex() will be
set to NULL to use the default digest implementation.
@@ -187,6 +194,19 @@ implementations of digests to be specified.
In OpenSSL 0.9.7 and later if digest contexts are not cleaned up after use
memory leaks will occur.
+Stack allocation of EVP_MD_CTX structures is common, for example:
+
+ EVP_MD_CTX mctx;
+ EVP_MD_CTX_init(&mctx);
+
+This will cause binary compatibility issues if the size of EVP_MD_CTX
+structure changes (this will only happen with a major release of OpenSSL).
+Applications wishing to avoid this should use EVP_MD_CTX_create() instead:
+
+ EVP_MD_CTX *mctx;
+ mctx = EVP_MD_CTX_create();
+
+
=head1 EXAMPLE
This example digests the data "Test Message\n" and "Hello World\n", using the
@@ -197,7 +217,7 @@ digest name passed on the command line.
main(int argc, char *argv[])
{
- EVP_MD_CTX mdctx;
+ EVP_MD_CTX *mdctx;
const EVP_MD *md;
char mess1[] = "Test Message\n";
char mess2[] = "Hello World\n";
@@ -218,12 +238,12 @@ digest name passed on the command line.
exit(1);
}
- EVP_MD_CTX_init(&mdctx);
- EVP_DigestInit_ex(&mdctx, md, NULL);
- EVP_DigestUpdate(&mdctx, mess1, strlen(mess1));
- EVP_DigestUpdate(&mdctx, mess2, strlen(mess2));
- EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
- EVP_MD_CTX_cleanup(&mdctx);
+ mdctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(mdctx, md, NULL);
+ EVP_DigestUpdate(mdctx, mess1, strlen(mess1));
+ EVP_DigestUpdate(mdctx, mess2, strlen(mess2));
+ EVP_DigestFinal_ex(mdctx, md_value, &md_len);
+ EVP_MD_CTX_destroy(mdctx);
printf("Digest is: ");
for(i = 0; i < md_len; i++) printf("%02x", md_value[i]);
diff --git a/deps/openssl/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod b/deps/openssl/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod
index f2f455990..13b91f1e6 100644
--- a/deps/openssl/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod
+++ b/deps/openssl/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod
@@ -117,7 +117,7 @@ L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)>
diff --git a/deps/openssl/openssl/doc/crypto/EVP_PKEY_decrypt.pod b/deps/openssl/openssl/doc/crypto/EVP_PKEY_decrypt.pod
index 42b2a8c44..847983237 100644
--- a/deps/openssl/openssl/doc/crypto/EVP_PKEY_decrypt.pod
+++ b/deps/openssl/openssl/doc/crypto/EVP_PKEY_decrypt.pod
@@ -83,7 +83,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
=head1 HISTORY
diff --git a/deps/openssl/openssl/doc/crypto/EVP_PKEY_derive.pod b/deps/openssl/openssl/doc/crypto/EVP_PKEY_derive.pod
index d9d6d76c7..27464be57 100644
--- a/deps/openssl/openssl/doc/crypto/EVP_PKEY_derive.pod
+++ b/deps/openssl/openssl/doc/crypto/EVP_PKEY_derive.pod
@@ -84,7 +84,7 @@ L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
=head1 HISTORY
diff --git a/deps/openssl/openssl/doc/crypto/EVP_PKEY_encrypt.pod b/deps/openssl/openssl/doc/crypto/EVP_PKEY_encrypt.pod
index 91c9c5d0a..e495a8124 100644
--- a/deps/openssl/openssl/doc/crypto/EVP_PKEY_encrypt.pod
+++ b/deps/openssl/openssl/doc/crypto/EVP_PKEY_encrypt.pod
@@ -83,7 +83,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
=head1 HISTORY
diff --git a/deps/openssl/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod b/deps/openssl/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod
index 1a9c7954c..8ff597d44 100644
--- a/deps/openssl/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod
+++ b/deps/openssl/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod
@@ -32,7 +32,7 @@ public key algorithm.
L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
=head1 HISTORY
diff --git a/deps/openssl/openssl/doc/crypto/EVP_PKEY_keygen.pod b/deps/openssl/openssl/doc/crypto/EVP_PKEY_keygen.pod
index 37c6fe950..fd431ace6 100644
--- a/deps/openssl/openssl/doc/crypto/EVP_PKEY_keygen.pod
+++ b/deps/openssl/openssl/doc/crypto/EVP_PKEY_keygen.pod
@@ -151,7 +151,7 @@ L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
=head1 HISTORY
diff --git a/deps/openssl/openssl/doc/crypto/EVP_PKEY_sign.pod b/deps/openssl/openssl/doc/crypto/EVP_PKEY_sign.pod
index 2fb52c348..a044f2c13 100644
--- a/deps/openssl/openssl/doc/crypto/EVP_PKEY_sign.pod
+++ b/deps/openssl/openssl/doc/crypto/EVP_PKEY_sign.pod
@@ -86,7 +86,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
=head1 HISTORY
diff --git a/deps/openssl/openssl/doc/crypto/EVP_PKEY_verify.pod b/deps/openssl/openssl/doc/crypto/EVP_PKEY_verify.pod
index f93e5fc6c..90612ba2f 100644
--- a/deps/openssl/openssl/doc/crypto/EVP_PKEY_verify.pod
+++ b/deps/openssl/openssl/doc/crypto/EVP_PKEY_verify.pod
@@ -81,7 +81,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
=head1 HISTORY
diff --git a/deps/openssl/openssl/doc/crypto/EVP_PKEY_verify_recover.pod b/deps/openssl/openssl/doc/crypto/EVP_PKEY_verify_recover.pod
new file mode 100644
index 000000000..23a28a9c4
--- /dev/null
+++ b/deps/openssl/openssl/doc/crypto/EVP_PKEY_verify_recover.pod
@@ -0,0 +1,103 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_verify_recover_init, EVP_PKEY_verify_recover - recover signature using a public key algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+ unsigned char *rout, size_t *routlen,
+ const unsigned char *sig, size_t siglen);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_verify_recover_init() function initializes a public key algorithm
+context using key B<pkey> for a verify recover operation.
+
+The EVP_PKEY_verify_recover() function recovers signed data
+using B<ctx>. The signature is specified using the B<sig> and
+B<siglen> parameters. If B<rout> is B<NULL> then the maximum size of the output
+buffer is written to the B<routlen> parameter. If B<rout> is not B<NULL> then
+before the call the B<routlen> parameter should contain the length of the
+B<rout> buffer, if the call is successful recovered data is written to
+B<rout> and the amount of data written to B<routlen>.
+
+=head1 NOTES
+
+Normally an application is only interested in whether a signature verification
+operation is successful in those cases the EVP_verify() function should be
+used.
+
+Sometimes however it is useful to obtain the data originally signed using a
+signing operation. Only certain public key algorithms can recover a signature
+in this way (for example RSA in PKCS padding mode).
+
+After the call to EVP_PKEY_verify_recover_init() algorithm specific control
+operations can be performed to set any appropriate parameters for the
+operation.
+
+The function EVP_PKEY_verify_recover() can be called more than once on the same
+context if several operations are performed using the same parameters.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_verify_recover_init() and EVP_PKEY_verify_recover() return 1 for success
+and 0 or a negative value for failure. In particular a return value of -2
+indicates the operation is not supported by the public key algorithm.
+
+=head1 EXAMPLE
+
+Recover digest originally signed using PKCS#1 and SHA256 digest:
+
+ #include <openssl/evp.h>
+ #include <openssl/rsa.h>
+
+ EVP_PKEY_CTX *ctx;
+ unsigned char *rout, *sig;
+ size_t routlen, siglen;
+ EVP_PKEY *verify_key;
+ /* NB: assumes verify_key, sig and siglen are already set up
+ * and that verify_key is an RSA public key
+ */
+ ctx = EVP_PKEY_CTX_new(verify_key);
+ if (!ctx)
+ /* Error occurred */
+ if (EVP_PKEY_verify_recover_init(ctx) <= 0)
+ /* Error */
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+ /* Error */
+ if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
+ /* Error */
+
+ /* Determine buffer length */
+ if (EVP_PKEY_verify_recover(ctx, NULL, &routlen, sig, siglen) <= 0)
+ /* Error */
+
+ rout = OPENSSL_malloc(routlen);
+
+ if (!rout)
+ /* malloc failure */
+
+ if (EVP_PKEY_verify_recover(ctx, rout, &routlen, sig, siglen) <= 0)
+ /* Error */
+
+ /* Recovered data is routlen bytes written to buffer rout */
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
+L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
+L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
+L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/deps/openssl/openssl/doc/crypto/ecdsa.pod b/deps/openssl/openssl/doc/crypto/ecdsa.pod
index 49b10f224..20edff97f 100644
--- a/deps/openssl/openssl/doc/crypto/ecdsa.pod
+++ b/deps/openssl/openssl/doc/crypto/ecdsa.pod
@@ -114,7 +114,7 @@ using the public key B<eckey>.
ECDSA_size() returns the maximum length signature or 0 on error.
-ECDSA_sign_setup() and ECDSA_sign() return 1 if successful or -1
+ECDSA_sign_setup() and ECDSA_sign() return 1 if successful or 0
on error.
ECDSA_verify() and ECDSA_do_verify() return 1 for a valid
diff --git a/deps/openssl/openssl/doc/ssl/SSL_alert_type_string.pod b/deps/openssl/openssl/doc/ssl/SSL_alert_type_string.pod
index 94e28cc30..0329c3486 100644
--- a/deps/openssl/openssl/doc/ssl/SSL_alert_type_string.pod
+++ b/deps/openssl/openssl/doc/ssl/SSL_alert_type_string.pod
@@ -214,6 +214,11 @@ satisfy a request; the process might receive security parameters
difficult to communicate changes to these parameters after that
point. This message is always a warning.
+=item "UP"/"unknown PSK identity"
+
+Sent by the server to indicate that it does not recognize a PSK
+identity or an SRP identity.
+
=item "UK"/"unknown"
This indicates that no description is available for this alert type.
diff --git a/deps/openssl/openssl/e_os.h b/deps/openssl/openssl/e_os.h
index 5ceeeeb95..79c139257 100644
--- a/deps/openssl/openssl/e_os.h
+++ b/deps/openssl/openssl/e_os.h
@@ -99,7 +99,6 @@ extern "C" {
# ifndef MAC_OS_GUSI_SOURCE
# define MAC_OS_pre_X
# define NO_SYS_TYPES_H
- typedef long ssize_t;
# endif
# define NO_SYS_PARAM_H
# define NO_CHMOD
@@ -340,8 +339,6 @@ static unsigned int _strlen31(const char *str)
# define OPENSSL_NO_POSIX_IO
# endif
-# define ssize_t long
-
# if defined (__BORLANDC__)
# define _setmode setmode
# define _O_TEXT O_TEXT
@@ -456,9 +453,6 @@ static unsigned int _strlen31(const char *str)
* (unless when compiling with -D_POSIX_SOURCE,
* which doesn't work for us) */
# endif
-# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS)
-# define ssize_t int /* ditto */
-# endif
# ifdef OPENSSL_SYS_NEWS4 /* setvbuf is missing on mips-sony-bsd */
# define setvbuf(a, b, c, d) setbuffer((a), (b), (d))
typedef unsigned long clock_t;
@@ -637,12 +631,6 @@ static unsigned int _strlen31(const char *str)
#endif
-#if defined(__ultrix)
-# ifndef ssize_t
-# define ssize_t int
-# endif
-#endif
-
#if defined(sun) && !defined(__svr4__) && !defined(__SVR4)
/* include headers first, so our defines don't break it */
#include <stdlib.h>
diff --git a/deps/openssl/openssl/e_os2.h b/deps/openssl/openssl/e_os2.h
index d30724d30..d22c0368f 100644
--- a/deps/openssl/openssl/e_os2.h
+++ b/deps/openssl/openssl/e_os2.h
@@ -289,6 +289,26 @@ extern "C" {
# define OPENSSL_GLOBAL_REF(name) _shadow_##name
#endif
+#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && macintosh==1 && !defined(MAC_OS_GUSI_SOURCE)
+# define ossl_ssize_t long
+#endif
+
+#ifdef OPENSSL_SYS_MSDOS
+# define ossl_ssize_t long
+#endif
+
+#if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS)
+# define ssize_t int
+#endif
+
+#if defined(__ultrix) && !defined(ssize_t)
+# define ossl_ssize_t int
+#endif
+
+#ifndef ossl_ssize_t
+# define ossl_ssize_t ssize_t
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/deps/openssl/openssl/engines/ccgost/Makefile b/deps/openssl/openssl/engines/ccgost/Makefile
index dadb5230e..d661c1082 100644
--- a/deps/openssl/openssl/engines/ccgost/Makefile
+++ b/deps/openssl/openssl/engines/ccgost/Makefile
@@ -142,13 +142,13 @@ gost94_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h
gost94_keyx.o: gost94_keyx.c gost_keywrap.h gost_lcl.h gosthash.h
gost_ameth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-gost_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-gost_ameth.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-gost_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-gost_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
-gost_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-gost_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-gost_ameth.o: ../../include/openssl/objects.h
+gost_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
+gost_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+gost_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+gost_ameth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+gost_ameth.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+gost_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+gost_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
gost_ameth.o: ../../include/openssl/opensslconf.h
gost_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
gost_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
diff --git a/deps/openssl/openssl/engines/ccgost/gost89.c b/deps/openssl/openssl/engines/ccgost/gost89.c
index 7ebae0f71..b0568c6b3 100644
--- a/deps/openssl/openssl/engines/ccgost/gost89.c
+++ b/deps/openssl/openssl/engines/ccgost/gost89.c
@@ -369,7 +369,13 @@ int gost_mac(gost_ctx *ctx,int mac_len,const unsigned char *data,
memset(buf2,0,8);
memcpy(buf2,data+i,data_len-i);
mac_block(ctx,buffer,buf2);
- }
+ i+=8;
+ }
+ if (i==8)
+ {
+ memset(buf2,0,8);
+ mac_block(ctx,buffer,buf2);
+ }
get_mac(buffer,mac_len,mac);
return 1;
}
@@ -389,7 +395,13 @@ int gost_mac_iv(gost_ctx *ctx,int mac_len,const unsigned char *iv,const unsigned
memset(buf2,0,8);
memcpy(buf2,data+i,data_len-i);
mac_block(ctx,buffer,buf2);
+ i+=8;
}
+ if (i==8)
+ {
+ memset(buf2,0,8);
+ mac_block(ctx,buffer,buf2);
+ }
get_mac(buffer,mac_len,mac);
return 1;
}
diff --git a/deps/openssl/openssl/engines/ccgost/gost_ameth.c b/deps/openssl/openssl/engines/ccgost/gost_ameth.c
index e6c2839e5..2cde1fcfd 100644
--- a/deps/openssl/openssl/engines/ccgost/gost_ameth.c
+++ b/deps/openssl/openssl/engines/ccgost/gost_ameth.c
@@ -13,6 +13,9 @@
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
#include "gost_params.h"
#include "gost_lcl.h"
#include "e_gost_err.h"
@@ -230,6 +233,24 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
}
return 1;
+#ifndef OPENSSL_NO_CMS
+ case ASN1_PKEY_CTRL_CMS_SIGN:
+ if (arg1 == 0)
+ {
+ X509_ALGOR *alg1 = NULL, *alg2 = NULL;
+ int nid = EVP_PKEY_base_id(pkey);
+ CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2,
+ NULL, NULL, &alg1, &alg2);
+ X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
+ V_ASN1_NULL, 0);
+ if (nid == NID_undef)
+ {
+ return (-1);
+ }
+ X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
+ }
+ return 1;
+#endif
case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
if (arg1 == 0)
{
@@ -244,6 +265,22 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
V_ASN1_SEQUENCE, params);
}
return 1;
+#ifndef OPENSSL_NO_CMS
+ case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+ if (arg1 == 0)
+ {
+ X509_ALGOR *alg;
+ ASN1_STRING * params = encode_gost_algor_params(pkey);
+ if (!params)
+ {
+ return -1;
+ }
+ CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, NULL, &alg);
+ X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
+ V_ASN1_SEQUENCE, params);
+ }
+ return 1;
+#endif
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
*(int *)arg2 = NID_id_GostR3411_94;
return 2;
diff --git a/deps/openssl/openssl/engines/ccgost/gost_crypt.c b/deps/openssl/openssl/engines/ccgost/gost_crypt.c
index cde58c0e9..52aef15ac 100644
--- a/deps/openssl/openssl/engines/ccgost/gost_crypt.c
+++ b/deps/openssl/openssl/engines/ccgost/gost_crypt.c
@@ -11,6 +11,14 @@
#include <openssl/rand.h>
#include "e_gost_err.h"
#include "gost_lcl.h"
+
+#if !defined(CCGOST_DEBUG) && !defined(DEBUG)
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc);
static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
@@ -206,12 +214,13 @@ int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf)
{
struct ossl_gost_cipher_ctx *c = ctx;
- if (c->count&&c->key_meshing && c->count%1024==0)
+ assert(c->count%8 == 0 && c->count <= 1024);
+ if (c->key_meshing && c->count==1024)
{
cryptopro_key_meshing(&(c->cctx),iv);
}
gostcrypt(&(c->cctx),iv,buf);
- c->count+=8;
+ c->count = c->count%1024 + 8;
}
static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
@@ -219,7 +228,8 @@ static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
struct ossl_gost_cipher_ctx *c = ctx;
word32 g,go;
unsigned char buf1[8];
- if (c->count && c->key_meshing && c->count %1024 ==0)
+ assert(c->count%8 == 0 && c->count <= 1024);
+ if (c->key_meshing && c->count==1024)
{
cryptopro_key_meshing(&(c->cctx),iv);
}
@@ -248,7 +258,7 @@ static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
buf1[7]=(unsigned char)((g>>24)&0xff);
memcpy(iv,buf1,8);
gostcrypt(&(c->cctx),buf1,buf);
- c->count +=8;
+ c->count = c->count%1024 + 8;
}
/* GOST encryption in CFB mode */
@@ -511,12 +521,13 @@ static void mac_block_mesh(struct ossl_gost_imit_ctx *c,const unsigned char *dat
* interpret internal state of MAC algorithm as iv during keymeshing
* (but does initialize internal state from iv in key transport
*/
- if (c->key_meshing&& c->count && c->count %1024 ==0)
+ assert(c->count%8 == 0 && c->count <= 1024);
+ if (c->key_meshing && c->count==1024)
{
cryptopro_key_meshing(&(c->cctx),buffer);
}
mac_block(&(c->cctx),c->buffer,data);
- c->count +=8;
+ c->count = c->count%1024 + 8;
}
int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
@@ -565,6 +576,12 @@ int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md)
GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
return 0;
}
+ if (c->count==0 && c->bytes_left)
+ {
+ unsigned char buffer[8];
+ memset(buffer, 0, 8);
+ gost_imit_update(ctx, buffer, 8);
+ }
if (c->bytes_left)
{
int i;
diff --git a/deps/openssl/openssl/engines/ccgost/gost_eng.c b/deps/openssl/openssl/engines/ccgost/gost_eng.c
index d2cbe3b83..8f29bf6f8 100644
--- a/deps/openssl/openssl/engines/ccgost/gost_eng.c
+++ b/deps/openssl/openssl/engines/ccgost/gost_eng.c
@@ -64,6 +64,13 @@ static int gost_engine_finish(ENGINE *e)
static int gost_engine_destroy(ENGINE *e)
{
gost_param_free();
+
+ pmeth_GostR3410_94 = NULL;
+ pmeth_GostR3410_2001 = NULL;
+ pmeth_Gost28147_MAC = NULL;
+ ameth_GostR3410_94 = NULL;
+ ameth_GostR3410_2001 = NULL;
+ ameth_Gost28147_MAC = NULL;
return 1;
}
@@ -71,6 +78,11 @@ static int bind_gost (ENGINE *e,const char *id)
{
int ret = 0;
if (id && strcmp(id, engine_gost_id)) return 0;
+ if (ameth_GostR3410_94)
+ {
+ printf("GOST engine already loaded\n");
+ goto end;
+ }
if (!ENGINE_set_id(e, engine_gost_id))
{
@@ -263,7 +275,10 @@ static ENGINE *engine_gost(void)
void ENGINE_load_gost(void)
{
- ENGINE *toadd =engine_gost();
+ ENGINE *toadd;
+ if (pmeth_GostR3410_94)
+ return;
+ toadd = engine_gost();
if (!toadd) return;
ENGINE_add(toadd);
ENGINE_free(toadd);
diff --git a/deps/openssl/openssl/engines/ccgost/gost_lcl.h b/deps/openssl/openssl/engines/ccgost/gost_lcl.h
index 437a48cc8..00aa42cea 100644
--- a/deps/openssl/openssl/engines/ccgost/gost_lcl.h
+++ b/deps/openssl/openssl/engines/ccgost/gost_lcl.h
@@ -136,7 +136,7 @@ extern EVP_MD imit_gost_cpa;
/* Cipher context used for EVP_CIPHER operation */
struct ossl_gost_cipher_ctx {
int paramNID;
- off_t count;
+ unsigned int count;
int key_meshing;
gost_ctx cctx;
};
@@ -151,7 +151,7 @@ struct ossl_gost_imit_ctx {
gost_ctx cctx;
unsigned char buffer[8];
unsigned char partial_block[8];
- off_t count;
+ unsigned int count;
int key_meshing;
int bytes_left;
int key_set;
diff --git a/deps/openssl/openssl/engines/ccgost/gost_pmeth.c b/deps/openssl/openssl/engines/ccgost/gost_pmeth.c
index caaea99d3..f91c9b193 100644
--- a/deps/openssl/openssl/engines/ccgost/gost_pmeth.c
+++ b/deps/openssl/openssl/engines/ccgost/gost_pmeth.c
@@ -89,6 +89,12 @@ static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
case EVP_PKEY_CTRL_PKCS7_SIGN:
+ case EVP_PKEY_CTRL_DIGESTINIT:
+#ifndef OPENSSL_NO_CMS
+ case EVP_PKEY_CTRL_CMS_ENCRYPT:
+ case EVP_PKEY_CTRL_CMS_DECRYPT:
+ case EVP_PKEY_CTRL_CMS_SIGN:
+#endif
return 1;
case EVP_PKEY_CTRL_GOST_PARAMSET:
@@ -123,7 +129,7 @@ static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
}
if (strlen(value) == 1)
{
- switch(toupper(value[0]))
+ switch(toupper((unsigned char)value[0]))
{
case 'A':
param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
@@ -142,9 +148,9 @@ static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
break;
}
}
- else if ((strlen(value) == 2) && (toupper(value[0]) == 'X'))
+ else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X'))
{
- switch (toupper(value[1]))
+ switch (toupper((unsigned char)value[1]))
{
case 'A':
param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
@@ -198,7 +204,7 @@ static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
}
if (strlen(value) == 1)
{
- switch(toupper(value[0]))
+ switch(toupper((unsigned char)value[0]))
{
case 'A':
param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
@@ -217,9 +223,9 @@ static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
break;
}
}
- else if ((strlen(value) == 2) && (toupper(value[0]) == 'X'))
+ else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X'))
{
- switch (toupper(value[1]))
+ switch (toupper((unsigned char)value[1]))
{
case 'A':
param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
@@ -521,6 +527,7 @@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
{
GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
GOST_R_INVALID_MAC_KEY_LENGTH);
+ OPENSSL_free(keybuf);
return 0;
}
ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
diff --git a/deps/openssl/openssl/engines/ccgost/gosthash.c b/deps/openssl/openssl/engines/ccgost/gosthash.c
index a5c0662ff..8c278aa64 100644
--- a/deps/openssl/openssl/engines/ccgost/gosthash.c
+++ b/deps/openssl/openssl/engines/ccgost/gosthash.c
@@ -42,7 +42,7 @@ static void circle_xor8 (const byte *w, byte *k)
byte buf[8];
int i;
memcpy(buf,w,8);
- memcpy(k,w+8,24);
+ memmove(k,w+8,24);
for(i=0;i<8;i++)
k[i+24]=buf[i]^k[i];
}
diff --git a/deps/openssl/openssl/engines/e_aep.c b/deps/openssl/openssl/engines/e_aep.c
index d7f89e515..1953f0643 100644
--- a/deps/openssl/openssl/engines/e_aep.c
+++ b/deps/openssl/openssl/engines/e_aep.c
@@ -85,7 +85,6 @@ extern int GetThreadID(void);
#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
#endif
-#include <openssl/bn.h>
#ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_AEP
diff --git a/deps/openssl/openssl/engines/e_capi.c b/deps/openssl/openssl/engines/e_capi.c
index 24b620fc0..c1085b56c 100644
--- a/deps/openssl/openssl/engines/e_capi.c
+++ b/deps/openssl/openssl/engines/e_capi.c
@@ -442,28 +442,36 @@ static int capi_init(ENGINE *e)
CAPI_CTX *ctx;
const RSA_METHOD *ossl_rsa_meth;
const DSA_METHOD *ossl_dsa_meth;
- capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
- cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
+
+ if (capi_idx < 0)
+ {
+ capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ if (capi_idx < 0)
+ goto memerr;
+
+ cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
+
+ /* Setup RSA_METHOD */
+ rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ ossl_rsa_meth = RSA_PKCS1_SSLeay();
+ capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc;
+ capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec;
+ capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp;
+ capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp;
+
+ /* Setup DSA Method */
+ dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ ossl_dsa_meth = DSA_OpenSSL();
+ capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify;
+ capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
+ capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
+ }
ctx = capi_ctx_new();
- if (!ctx || (capi_idx < 0))
+ if (!ctx)
goto memerr;
ENGINE_set_ex_data(e, capi_idx, ctx);
- /* Setup RSA_METHOD */
- rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
- ossl_rsa_meth = RSA_PKCS1_SSLeay();
- capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc;
- capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec;
- capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp;
- capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp;
-
- /* Setup DSA Method */
- dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
- ossl_dsa_meth = DSA_OpenSSL();
- capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify;
- capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
- capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
#ifdef OPENSSL_CAPIENG_DIALOG
{
@@ -522,6 +530,7 @@ static int bind_capi(ENGINE *e)
{
if (!ENGINE_set_id(e, engine_capi_id)
|| !ENGINE_set_name(e, engine_capi_name)
+ || !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL)
|| !ENGINE_set_init_function(e, capi_init)
|| !ENGINE_set_finish_function(e, capi_finish)
|| !ENGINE_set_destroy_function(e, capi_destroy)
@@ -1155,6 +1164,7 @@ static int capi_list_containers(CAPI_CTX *ctx, BIO *out)
{
CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
capi_addlasterror();
+ CryptReleaseContext(hprov, 0);
return 0;
}
CAPI_trace(ctx, "Got max container len %d\n", buflen);
@@ -1422,10 +1432,13 @@ static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE h
static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec)
{
CAPI_KEY *key;
+ DWORD dwFlags = 0;
key = OPENSSL_malloc(sizeof(CAPI_KEY));
CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n",
contname, provname, ptype);
- if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, 0))
+ if(ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE)
+ dwFlags = CRYPT_MACHINE_KEYSET;
+ if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, dwFlags))
{
CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
capi_addlasterror();
@@ -1572,6 +1585,8 @@ static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int che
}
CryptReleaseContext(hprov, 0);
}
+ if (ctx->cspname)
+ OPENSSL_free(ctx->cspname);
ctx->cspname = BUF_strdup(pname);
ctx->csptype = type;
return 1;
@@ -1581,9 +1596,12 @@ static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx)
{
LPSTR pname;
DWORD type;
+ int res;
if (capi_get_provname(ctx, &pname, &type, idx) != 1)
return 0;
- return capi_ctx_set_provname(ctx, pname, type, 0);
+ res = capi_ctx_set_provname(ctx, pname, type, 0);
+ OPENSSL_free(pname);
+ return res;
}
static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x)
diff --git a/deps/openssl/openssl/engines/e_padlock.c b/deps/openssl/openssl/engines/e_padlock.c
index 7d0941980..9f7a85a8d 100644
--- a/deps/openssl/openssl/engines/e_padlock.c
+++ b/deps/openssl/openssl/engines/e_padlock.c
@@ -104,11 +104,13 @@
# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
(defined(_MSC_VER) && defined(_M_IX86))
# define COMPILE_HW_PADLOCK
-static ENGINE *ENGINE_padlock (void);
# endif
#endif
#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+#ifdef COMPILE_HW_PADLOCK
+static ENGINE *ENGINE_padlock (void);
+#endif
void ENGINE_load_padlock (void)
{
@@ -197,6 +199,8 @@ padlock_bind_helper(ENGINE *e)
return 1;
}
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+
/* Constructor */
static ENGINE *
ENGINE_padlock(void)
@@ -215,6 +219,8 @@ ENGINE_padlock(void)
return eng;
}
+#endif
+
/* Check availability of the engine */
static int
padlock_init(ENGINE *e)
diff --git a/deps/openssl/openssl/include/openssl/cmac.h b/deps/openssl/openssl/include/openssl/cmac.h
new file mode 100644
index 000000000..a7579aeab
--- /dev/null
+++ b/deps/openssl/openssl/include/openssl/cmac.h
@@ -0,0 +1 @@
+#include "../../crypto/cmac/cmac.h"
diff --git a/deps/openssl/openssl/include/openssl/opensslconf.h b/deps/openssl/openssl/include/openssl/opensslconf.h
new file mode 100644
index 000000000..221be629b
--- /dev/null
+++ b/deps/openssl/openssl/include/openssl/opensslconf.h
@@ -0,0 +1 @@
+#include "../../crypto/opensslconf.h"
diff --git a/deps/openssl/openssl/include/openssl/srp.h b/deps/openssl/openssl/include/openssl/srp.h
new file mode 100644
index 000000000..821747677
--- /dev/null
+++ b/deps/openssl/openssl/include/openssl/srp.h
@@ -0,0 +1 @@
+#include "../../crypto/srp/srp.h"
diff --git a/deps/openssl/openssl/include/openssl/srtp.h b/deps/openssl/openssl/include/openssl/srtp.h
new file mode 100644
index 000000000..e185494a5
--- /dev/null
+++ b/deps/openssl/openssl/include/openssl/srtp.h
@@ -0,0 +1 @@
+#include "../../ssl/srtp.h"
diff --git a/deps/openssl/openssl/makevms.com b/deps/openssl/openssl/makevms.com
index eb22f20db..de1dbd905 100755
--- a/deps/openssl/openssl/makevms.com
+++ b/deps/openssl/openssl/makevms.com
@@ -263,8 +263,10 @@ $ CONFIG_LOGICALS := AES,-
DH,-
DSA,-
EC,-
+ EC2M,-
ECDH,-
ECDSA,-
+ EC_NISTP_64_GCC_128,-
ENGINE,-
ERR,-
EVP,-
@@ -296,7 +298,9 @@ $ CONFIG_LOGICALS := AES,-
SHA256,-
SHA512,-
SOCK,-
+ SRP,-
SSL2,-
+ SSL_INTERN,-
STACK,-
STATIC_ENGINE,-
STDIO,-
@@ -335,7 +339,8 @@ $ CONFIG_DISABLE_RULES := RIJNDAEL/AES;-
DSA/GOST;-
DH/GOST;-
/STATIC_ENGINE;-
- /KRB5
+ /KRB5;-
+ /EC_NISTP_64_GCC_128
$ CONFIG_ENABLE_RULES := ZLIB_DYNAMIC/ZLIB;-
/THREADS
$
@@ -498,6 +503,9 @@ $ WRITE H_FILE " * value _IONBF is not supported."
$ WRITE H_FILE " * So, skip it on VMS."
$ WRITE H_FILE " */"
$ WRITE H_FILE "#define OPENSSL_NO_SETVBUF_IONBF"
+$ WRITE H_FILE "/* STCP support comes with TCPIP 5.7 ECO 2 "
+$ WRITE H_FILE " * enable on newer systems / 2012-02-24 arpadffy */"
+$ WRITE H_FILE "#define OPENSSL_NO_SCTP"
$ WRITE H_FILE ""
$!
$! Add in the common "crypto/opensslconf.h.in".
@@ -704,7 +712,7 @@ $ SDIRS := , -
BUFFER, BIO, STACK, LHASH, RAND, ERR, -
EVP, ASN1, PEM, X509, X509V3, CONF, TXT_DB, PKCS7, PKCS12, -
COMP, OCSP, UI, KRB5, -
- STORE, CMS, PQUEUE, TS, JPAKE
+ CMS, PQUEUE, TS, JPAKE, SRP, STORE, CMAC
$!
$ EXHEADER_ := crypto.h, opensslv.h, ebcdic.h, symhacks.h, ossl_typ.h
$ EXHEADER_'ARCHD' := opensslconf.h
@@ -756,12 +764,14 @@ $ EXHEADER_COMP := comp.h
$ EXHEADER_OCSP := ocsp.h
$ EXHEADER_UI := ui.h, ui_compat.h
$ EXHEADER_KRB5 := krb5_asn.h
-$!!! EXHEADER_STORE := store.h, str_compat.h
-$ EXHEADER_STORE := store.h
$ EXHEADER_CMS := cms.h
$ EXHEADER_PQUEUE := pqueue.h
$ EXHEADER_TS := ts.h
$ EXHEADER_JPAKE := jpake.h
+$ EXHEADER_SRP := srp.h
+$!!! EXHEADER_STORE := store.h, str_compat.h
+$ EXHEADER_STORE := store.h
+$ EXHEADER_CMAC := cmac.h
$!
$ i = 0
$ loop_sdirs:
@@ -777,7 +787,7 @@ $!
$! Copy All The ".H" Files From The [.SSL] Directory.
$!
$! (keep these in the same order as ssl/Makefile)
-$ EXHEADER := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h
+$ EXHEADER := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h, srtp.h
$ copy sys$disk:[.ssl]'exheader' sys$disk:[.include.openssl]
$!
$! Purge the [.include.openssl] header files.
diff --git a/deps/openssl/openssl/ms/do_win64a.bat b/deps/openssl/openssl/ms/do_win64a.bat
index 495f1ea7d..ff8b19ccf 100755
--- a/deps/openssl/openssl/ms/do_win64a.bat
+++ b/deps/openssl/openssl/ms/do_win64a.bat
@@ -1,9 +1,19 @@
-
perl util\mkfiles.pl >MINFO
-perl ms\uplink.pl win64a > ms\uptable.asm
+
+cmd /c "nasm -f win64 -v" >NUL: 2>&1
+if %errorlevel% neq 0 goto ml64
+
+perl ms\uplink-x86_64.pl nasm > ms\uptable.asm
+nasm -f win64 -o ms\uptable.obj ms\uptable.asm
+goto proceed
+
+:ml64
+perl ms\uplink-x86_64.pl masm > ms\uptable.asm
ml64 -c -Foms\uptable.obj ms\uptable.asm
-perl util\mk1mf.pl no-asm VC-WIN64A >ms\nt.mak
-perl util\mk1mf.pl dll no-asm VC-WIN64A >ms\ntdll.mak
+
+:proceed
+perl util\mk1mf.pl VC-WIN64A >ms\nt.mak
+perl util\mk1mf.pl dll VC-WIN64A >ms\ntdll.mak
perl util\mkdef.pl 32 libeay > ms\libeay32.def
perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
diff --git a/deps/openssl/openssl/ms/do_win64i.bat b/deps/openssl/openssl/ms/do_win64i.bat
index 15ebcaaeb..088f5e1d0 100755
--- a/deps/openssl/openssl/ms/do_win64i.bat
+++ b/deps/openssl/openssl/ms/do_win64i.bat
@@ -1,9 +1,9 @@
perl util\mkfiles.pl >MINFO
-perl ms\uplink.pl win64i > ms\uptable.asm
+perl ms\uplink-ia64.pl > ms\uptable.asm
ias -o ms\uptable.obj ms\uptable.asm
-perl util\mk1mf.pl no-asm VC-WIN64I >ms\nt.mak
-perl util\mk1mf.pl dll no-asm VC-WIN64I >ms\ntdll.mak
+perl util\mk1mf.pl VC-WIN64I >ms\nt.mak
+perl util\mk1mf.pl dll VC-WIN64I >ms\ntdll.mak
perl util\mkdef.pl 32 libeay > ms\libeay32.def
perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
diff --git a/deps/openssl/openssl/ms/uplink-common.pl b/deps/openssl/openssl/ms/uplink-common.pl
index 1d20e6e03..1d20e6e03 100644..100755
--- a/deps/openssl/openssl/ms/uplink-common.pl
+++ b/deps/openssl/openssl/ms/uplink-common.pl
diff --git a/deps/openssl/openssl/ms/uplink-ia64.pl b/deps/openssl/openssl/ms/uplink-ia64.pl
index 4204c73d5..4204c73d5 100644..100755
--- a/deps/openssl/openssl/ms/uplink-ia64.pl
+++ b/deps/openssl/openssl/ms/uplink-ia64.pl
diff --git a/deps/openssl/openssl/ms/uplink-x86.pl b/deps/openssl/openssl/ms/uplink-x86.pl
index 0dffc14fc..0dffc14fc 100644..100755
--- a/deps/openssl/openssl/ms/uplink-x86.pl
+++ b/deps/openssl/openssl/ms/uplink-x86.pl
diff --git a/deps/openssl/openssl/ms/uplink-x86_64.pl b/deps/openssl/openssl/ms/uplink-x86_64.pl
index 9acbf6be6..48bf559ee 100644..100755
--- a/deps/openssl/openssl/ms/uplink-x86_64.pl
+++ b/deps/openssl/openssl/ms/uplink-x86_64.pl
@@ -2,7 +2,8 @@
$output=shift;
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-open STDOUT,"| $^X ${dir}../crypto/perlasm/x86_64-xlate.pl $output";
+open OUT,"| \"$^X\" ${dir}../crypto/perlasm/x86_64-xlate.pl $output";
+*STDOUT=*OUT;
push(@INC,"${dir}.");
require "uplink-common.pl";
diff --git a/deps/openssl/openssl/ms/uplink.h b/deps/openssl/openssl/ms/uplink.h
index a4a67d3c1..4881ba7d4 100644
--- a/deps/openssl/openssl/ms/uplink.h
+++ b/deps/openssl/openssl/ms/uplink.h
@@ -23,7 +23,7 @@ extern void *OPENSSL_UplinkTable[];
#define UP_fileno (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FILENO])
#define UP_open (*(int (*)(const char *,int,...))OPENSSL_UplinkTable[APPLINK_OPEN])
-#define UP_read (*(ssize_t (*)(int,void *,size_t))OPENSSL_UplinkTable[APPLINK_READ])
-#define UP_write (*(ssize_t (*)(int,const void *,size_t))OPENSSL_UplinkTable[APPLINK_WRITE])
+#define UP_read (*(ossl_ssize_t (*)(int,void *,size_t))OPENSSL_UplinkTable[APPLINK_READ])
+#define UP_write (*(ossl_ssize_t (*)(int,const void *,size_t))OPENSSL_UplinkTable[APPLINK_WRITE])
#define UP_lseek (*(long (*)(int,long,int))OPENSSL_UplinkTable[APPLINK_LSEEK])
#define UP_close (*(int (*)(int))OPENSSL_UplinkTable[APPLINK_CLOSE])
diff --git a/deps/openssl/openssl/openssl.spec b/deps/openssl/openssl/openssl.spec
index 703cea2a5..8ad98b363 100644
--- a/deps/openssl/openssl/openssl.spec
+++ b/deps/openssl/openssl/openssl.spec
@@ -1,8 +1,8 @@
%define _unpackaged_files_terminate_build 0
%define libmaj 1
%define libmin 0
-%define librel 0
-%define librev f
+%define librel 1
+%define librev e
Release: 1
%define openssldir /var/ssl
diff --git a/deps/openssl/openssl/ssl/Makefile b/deps/openssl/openssl/ssl/Makefile
index 2b275faf6..debe07405 100644
--- a/deps/openssl/openssl/ssl/Makefile
+++ b/deps/openssl/openssl/ssl/Makefile
@@ -22,30 +22,30 @@ LIB=$(TOP)/libssl.a
SHARED_LIB= libssl$(SHLIB_EXT)
LIBSRC= \
s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \
- s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c \
+ s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c s3_cbc.c \
s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \
t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \
d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \
- d1_both.c d1_enc.c \
+ d1_both.c d1_enc.c d1_srtp.c \
ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
ssl_ciph.c ssl_stat.c ssl_rsa.c \
ssl_asn1.c ssl_txt.c ssl_algs.c \
- bio_ssl.c ssl_err.c kssl.c t1_reneg.c
+ bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c
LIBOBJ= \
s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \
- s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \
+ s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o s3_cbc.o \
s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \
t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \
d1_meth.o d1_srvr.o d1_clnt.o d1_lib.o d1_pkt.o \
- d1_both.o d1_enc.o \
+ d1_both.o d1_enc.o d1_srtp.o\
ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
ssl_ciph.o ssl_stat.o ssl_rsa.o \
ssl_asn1.o ssl_txt.o ssl_algs.o \
- bio_ssl.o ssl_err.o kssl.o t1_reneg.o
+ bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o
SRC= $(LIBSRC)
-EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h kssl.h
+EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h kssl.h srtp.h
HEADER= $(EXHEADER) ssl_locl.h kssl_lcl.h
ALL= $(GENERAL) $(SRC) $(HEADER)
@@ -118,11 +118,11 @@ bio_ssl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
bio_ssl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
bio_ssl.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
bio_ssl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-bio_ssl.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-bio_ssl.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-bio_ssl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-bio_ssl.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-bio_ssl.o: ../include/openssl/x509_vfy.h bio_ssl.c
+bio_ssl.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+bio_ssl.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+bio_ssl.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+bio_ssl.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+bio_ssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h bio_ssl.c
d1_both.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
d1_both.o: ../include/openssl/buffer.h ../include/openssl/comp.h
d1_both.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -137,12 +137,12 @@ d1_both.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
d1_both.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
d1_both.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
d1_both.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-d1_both.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-d1_both.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-d1_both.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-d1_both.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-d1_both.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_both.c
-d1_both.o: ssl_locl.h
+d1_both.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+d1_both.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+d1_both.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+d1_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+d1_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+d1_both.o: ../include/openssl/x509_vfy.h d1_both.c ssl_locl.h
d1_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
d1_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
d1_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -159,11 +159,12 @@ d1_clnt.o: ../include/openssl/pem.h ../include/openssl/pem2.h
d1_clnt.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
d1_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
d1_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-d1_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-d1_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-d1_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-d1_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_clnt.o: ../include/openssl/x509_vfy.h d1_clnt.c kssl_lcl.h ssl_locl.h
+d1_clnt.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+d1_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_clnt.c
+d1_clnt.o: kssl_lcl.h ssl_locl.h
d1_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
d1_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
d1_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -179,11 +180,12 @@ d1_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
d1_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
d1_enc.o: ../include/openssl/rand.h ../include/openssl/rsa.h
d1_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-d1_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-d1_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-d1_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-d1_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_enc.o: ../include/openssl/x509_vfy.h d1_enc.c ssl_locl.h
+d1_enc.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+d1_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_enc.c
+d1_enc.o: ssl_locl.h
d1_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
d1_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
d1_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -198,11 +200,12 @@ d1_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
d1_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
d1_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
d1_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-d1_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-d1_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-d1_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-d1_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_lib.o: ../include/openssl/x509_vfy.h d1_lib.c ssl_locl.h
+d1_lib.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+d1_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_lib.c
+d1_lib.o: ssl_locl.h
d1_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
d1_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
d1_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -217,11 +220,12 @@ d1_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
d1_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
d1_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
d1_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-d1_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-d1_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-d1_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-d1_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_meth.o: ../include/openssl/x509_vfy.h d1_meth.c ssl_locl.h
+d1_meth.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+d1_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_meth.c
+d1_meth.o: ssl_locl.h
d1_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
d1_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
d1_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -236,12 +240,32 @@ d1_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
d1_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
d1_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
d1_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-d1_pkt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-d1_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-d1_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-d1_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-d1_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_pkt.c
-d1_pkt.o: ssl_locl.h
+d1_pkt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+d1_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+d1_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+d1_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+d1_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+d1_pkt.o: ../include/openssl/x509_vfy.h d1_pkt.c ssl_locl.h
+d1_srtp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+d1_srtp.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+d1_srtp.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_srtp.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_srtp.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_srtp.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_srtp.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+d1_srtp.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_srtp.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+d1_srtp.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+d1_srtp.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+d1_srtp.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+d1_srtp.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+d1_srtp.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+d1_srtp.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+d1_srtp.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_srtp.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_srtp.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_srtp.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_srtp.c
+d1_srtp.o: srtp.h ssl_locl.h
d1_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
d1_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
d1_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -258,11 +282,12 @@ d1_srvr.o: ../include/openssl/pem.h ../include/openssl/pem2.h
d1_srvr.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
d1_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
d1_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-d1_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-d1_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-d1_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-d1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_srvr.o: ../include/openssl/x509_vfy.h d1_srvr.c ssl_locl.h
+d1_srvr.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+d1_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_srvr.c
+d1_srvr.o: ssl_locl.h
kssl.o: ../include/openssl/asn1.h ../include/openssl/bio.h
kssl.o: ../include/openssl/buffer.h ../include/openssl/comp.h
kssl.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
@@ -276,11 +301,12 @@ kssl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
kssl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
kssl.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
kssl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-kssl.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-kssl.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-kssl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-kssl.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-kssl.o: ../include/openssl/x509_vfy.h kssl.c kssl_lcl.h
+kssl.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+kssl.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+kssl.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+kssl.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+kssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl.c
+kssl.o: kssl_lcl.h
s23_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s23_clnt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s23_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -295,12 +321,12 @@ s23_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s23_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s23_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
s23_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s23_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s23_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s23_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s23_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s23_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_clnt.c
-s23_clnt.o: ssl_locl.h
+s23_clnt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s23_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s23_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s23_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s23_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s23_clnt.o: ../include/openssl/x509_vfy.h s23_clnt.c ssl_locl.h
s23_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s23_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s23_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -315,11 +341,12 @@ s23_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s23_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s23_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
s23_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s23_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s23_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s23_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s23_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s23_lib.o: ../include/openssl/x509_vfy.h s23_lib.c ssl_locl.h
+s23_lib.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s23_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s23_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s23_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s23_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_lib.c
+s23_lib.o: ssl_locl.h
s23_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s23_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s23_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -334,11 +361,12 @@ s23_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s23_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s23_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
s23_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s23_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s23_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s23_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s23_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s23_meth.o: ../include/openssl/x509_vfy.h s23_meth.c ssl_locl.h
+s23_meth.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s23_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s23_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s23_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s23_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_meth.c
+s23_meth.o: ssl_locl.h
s23_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s23_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s23_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -353,11 +381,12 @@ s23_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s23_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s23_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
s23_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s23_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s23_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s23_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s23_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s23_pkt.o: ../include/openssl/x509_vfy.h s23_pkt.c ssl_locl.h
+s23_pkt.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s23_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s23_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s23_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s23_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_pkt.c
+s23_pkt.o: ssl_locl.h
s23_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s23_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s23_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -372,12 +401,12 @@ s23_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s23_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s23_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
s23_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s23_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s23_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s23_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s23_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s23_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_srvr.c
-s23_srvr.o: ssl_locl.h
+s23_srvr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s23_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s23_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s23_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s23_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s23_srvr.o: ../include/openssl/x509_vfy.h s23_srvr.c ssl_locl.h
s2_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s2_clnt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s2_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -392,12 +421,12 @@ s2_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s2_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s2_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
s2_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s2_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s2_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s2_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s2_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s2_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_clnt.c
-s2_clnt.o: ssl_locl.h
+s2_clnt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s2_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s2_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s2_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s2_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s2_clnt.o: ../include/openssl/x509_vfy.h s2_clnt.c ssl_locl.h
s2_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s2_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s2_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -412,11 +441,12 @@ s2_enc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s2_enc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s2_enc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
s2_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s2_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s2_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s2_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s2_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s2_enc.o: ../include/openssl/x509_vfy.h s2_enc.c ssl_locl.h
+s2_enc.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s2_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s2_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s2_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s2_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_enc.c
+s2_enc.o: ssl_locl.h
s2_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s2_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s2_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -431,12 +461,12 @@ s2_lib.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
s2_lib.o: ../include/openssl/pem.h ../include/openssl/pem2.h
s2_lib.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
s2_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s2_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s2_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s2_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s2_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s2_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_lib.c
-s2_lib.o: ssl_locl.h
+s2_lib.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s2_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s2_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s2_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s2_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s2_lib.o: ../include/openssl/x509_vfy.h s2_lib.c ssl_locl.h
s2_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s2_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s2_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -451,11 +481,12 @@ s2_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s2_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s2_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
s2_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s2_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s2_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s2_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s2_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s2_meth.o: ../include/openssl/x509_vfy.h s2_meth.c ssl_locl.h
+s2_meth.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s2_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s2_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s2_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s2_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_meth.c
+s2_meth.o: ssl_locl.h
s2_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s2_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s2_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -470,11 +501,12 @@ s2_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s2_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s2_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
s2_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s2_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s2_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s2_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s2_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s2_pkt.o: ../include/openssl/x509_vfy.h s2_pkt.c ssl_locl.h
+s2_pkt.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s2_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s2_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s2_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s2_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_pkt.c
+s2_pkt.o: ssl_locl.h
s2_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s2_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s2_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -489,12 +521,12 @@ s2_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s2_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s2_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
s2_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s2_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s2_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s2_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s2_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s2_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_srvr.c
-s2_srvr.o: ssl_locl.h
+s2_srvr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s2_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s2_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s2_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s2_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s2_srvr.o: ../include/openssl/x509_vfy.h s2_srvr.c ssl_locl.h
s3_both.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s3_both.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s3_both.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -509,12 +541,32 @@ s3_both.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s3_both.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s3_both.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
s3_both.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_both.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_both.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_both.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_both.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_both.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_both.c
-s3_both.o: ssl_locl.h
+s3_both.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s3_both.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_both.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_both.o: ../include/openssl/x509_vfy.h s3_both.c ssl_locl.h
+s3_cbc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s3_cbc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s3_cbc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s3_cbc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_cbc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_cbc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_cbc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s3_cbc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s3_cbc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+s3_cbc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+s3_cbc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+s3_cbc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+s3_cbc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+s3_cbc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_cbc.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s3_cbc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_cbc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_cbc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_cbc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_cbc.o: ../include/openssl/x509_vfy.h s3_cbc.c ssl_locl.h
s3_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s3_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
s3_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -531,12 +583,12 @@ s3_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s3_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s3_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
s3_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
-s3_clnt.o: s3_clnt.c ssl_locl.h
+s3_clnt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s3_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_clnt.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_clnt.c ssl_locl.h
s3_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s3_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s3_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -551,12 +603,12 @@ s3_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
s3_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
s3_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
s3_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_enc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_enc.c
-s3_enc.o: ssl_locl.h
+s3_enc.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s3_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_enc.o: ../include/openssl/x509_vfy.h s3_enc.c ssl_locl.h
s3_lib.o: ../crypto/ec/ec_lcl.h ../e_os.h ../include/openssl/asn1.h
s3_lib.o: ../include/openssl/bio.h ../include/openssl/bn.h
s3_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
@@ -573,11 +625,12 @@ s3_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s3_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s3_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
s3_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s3_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_lib.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_lib.c ssl_locl.h
+s3_lib.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s3_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
+s3_lib.o: s3_lib.c ssl_locl.h
s3_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s3_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s3_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -592,11 +645,12 @@ s3_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s3_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s3_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
s3_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s3_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_meth.o: ../include/openssl/x509_vfy.h s3_meth.c ssl_locl.h
+s3_meth.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s3_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_meth.c
+s3_meth.o: ssl_locl.h
s3_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s3_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s3_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -609,8 +663,9 @@ s3_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
s3_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
s3_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s3_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s3_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-s3_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s3_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_pkt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
s3_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
s3_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
s3_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
@@ -632,12 +687,12 @@ s3_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s3_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s3_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
s3_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
-s3_srvr.o: s3_srvr.c ssl_locl.h
+s3_srvr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+s3_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_srvr.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_srvr.c ssl_locl.h
ssl_algs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_algs.o: ../include/openssl/buffer.h ../include/openssl/comp.h
ssl_algs.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -652,11 +707,12 @@ ssl_algs.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
ssl_algs.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
ssl_algs.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
ssl_algs.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_algs.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_algs.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_algs.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_algs.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_algs.o: ../include/openssl/x509_vfy.h ssl_algs.c ssl_locl.h
+ssl_algs.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ssl_algs.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_algs.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_algs.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_algs.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_algs.c
+ssl_algs.o: ssl_locl.h
ssl_asn1.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/asn1_mac.h
ssl_asn1.o: ../include/openssl/bio.h ../include/openssl/buffer.h
ssl_asn1.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -671,12 +727,12 @@ ssl_asn1.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
ssl_asn1.o: ../include/openssl/pem.h ../include/openssl/pem2.h
ssl_asn1.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
ssl_asn1.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_asn1.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_asn1.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_asn1.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_asn1.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_asn1.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_asn1.c
-ssl_asn1.o: ssl_locl.h
+ssl_asn1.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+ssl_asn1.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_asn1.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_asn1.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_asn1.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_asn1.o: ../include/openssl/x509_vfy.h ssl_asn1.c ssl_locl.h
ssl_cert.o: ../crypto/o_dir.h ../e_os.h ../include/openssl/asn1.h
ssl_cert.o: ../include/openssl/bio.h ../include/openssl/bn.h
ssl_cert.o: ../include/openssl/buffer.h ../include/openssl/comp.h
@@ -693,12 +749,12 @@ ssl_cert.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
ssl_cert.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
ssl_cert.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
ssl_cert.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_cert.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_cert.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_cert.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_cert.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_cert.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h
-ssl_cert.o: ssl_cert.c ssl_locl.h
+ssl_cert.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ssl_cert.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_cert.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_cert.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_cert.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ssl_cert.o: ../include/openssl/x509v3.h ssl_cert.c ssl_locl.h
ssl_ciph.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_ciph.o: ../include/openssl/buffer.h ../include/openssl/comp.h
ssl_ciph.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -713,12 +769,12 @@ ssl_ciph.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
ssl_ciph.o: ../include/openssl/pem.h ../include/openssl/pem2.h
ssl_ciph.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
ssl_ciph.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_ciph.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_ciph.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_ciph.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_ciph.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_ciph.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_ciph.c
-ssl_ciph.o: ssl_locl.h
+ssl_ciph.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+ssl_ciph.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_ciph.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_ciph.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_ciph.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_ciph.o: ../include/openssl/x509_vfy.h ssl_ciph.c ssl_locl.h
ssl_err.o: ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_err.o: ../include/openssl/buffer.h ../include/openssl/comp.h
ssl_err.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
@@ -732,11 +788,11 @@ ssl_err.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
ssl_err.o: ../include/openssl/pem.h ../include/openssl/pem2.h
ssl_err.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
ssl_err.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_err.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_err.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_err.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_err.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_err.o: ../include/openssl/x509_vfy.h ssl_err.c
+ssl_err.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ssl_err.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_err.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_err.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_err.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_err.c
ssl_err2.o: ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_err2.o: ../include/openssl/buffer.h ../include/openssl/comp.h
ssl_err2.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
@@ -750,11 +806,11 @@ ssl_err2.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
ssl_err2.o: ../include/openssl/pem.h ../include/openssl/pem2.h
ssl_err2.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
ssl_err2.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_err2.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_err2.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_err2.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_err2.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_err2.o: ../include/openssl/x509_vfy.h ssl_err2.c
+ssl_err2.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ssl_err2.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_err2.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_err2.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_err2.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_err2.c
ssl_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
ssl_lib.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -771,12 +827,13 @@ ssl_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
ssl_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
ssl_lib.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
ssl_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-ssl_lib.o: ../include/openssl/x509v3.h kssl_lcl.h ssl_lib.c ssl_locl.h
+ssl_lib.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+ssl_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_lib.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h kssl_lcl.h
+ssl_lib.o: ssl_lib.c ssl_locl.h
ssl_rsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_rsa.o: ../include/openssl/buffer.h ../include/openssl/comp.h
ssl_rsa.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -791,11 +848,12 @@ ssl_rsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
ssl_rsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
ssl_rsa.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
ssl_rsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_rsa.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_rsa.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_rsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_rsa.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_rsa.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_rsa.c
+ssl_rsa.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ssl_rsa.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_rsa.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_rsa.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_rsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+ssl_rsa.o: ssl_rsa.c
ssl_sess.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_sess.o: ../include/openssl/buffer.h ../include/openssl/comp.h
ssl_sess.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -811,11 +869,12 @@ ssl_sess.o: ../include/openssl/pem.h ../include/openssl/pem2.h
ssl_sess.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
ssl_sess.o: ../include/openssl/rand.h ../include/openssl/rsa.h
ssl_sess.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_sess.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_sess.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_sess.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_sess.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_sess.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_sess.c
+ssl_sess.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ssl_sess.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_sess.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_sess.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_sess.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+ssl_sess.o: ssl_sess.c
ssl_stat.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_stat.o: ../include/openssl/buffer.h ../include/openssl/comp.h
ssl_stat.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -830,11 +889,12 @@ ssl_stat.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
ssl_stat.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
ssl_stat.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
ssl_stat.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_stat.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_stat.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_stat.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_stat.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_stat.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_stat.c
+ssl_stat.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ssl_stat.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_stat.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_stat.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_stat.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+ssl_stat.o: ssl_stat.c
ssl_txt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_txt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
ssl_txt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -849,11 +909,12 @@ ssl_txt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
ssl_txt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
ssl_txt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
ssl_txt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_txt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_txt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_txt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_txt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_txt.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_txt.c
+ssl_txt.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ssl_txt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_txt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_txt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_txt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+ssl_txt.o: ssl_txt.c
t1_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
t1_clnt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
t1_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -868,12 +929,12 @@ t1_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
t1_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
t1_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
t1_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-t1_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-t1_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-t1_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-t1_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-t1_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-t1_clnt.o: t1_clnt.c
+t1_clnt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+t1_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+t1_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+t1_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+t1_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+t1_clnt.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_clnt.c
t1_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
t1_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
t1_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -887,8 +948,9 @@ t1_enc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
t1_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
t1_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
t1_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
-t1_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-t1_enc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+t1_enc.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+t1_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+t1_enc.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
t1_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
t1_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
t1_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
@@ -907,8 +969,9 @@ t1_lib.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
t1_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
t1_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
t1_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-t1_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-t1_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+t1_lib.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+t1_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+t1_lib.o: ../include/openssl/sha.h ../include/openssl/srtp.h
t1_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
t1_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
t1_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
@@ -929,11 +992,12 @@ t1_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
t1_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
t1_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
t1_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-t1_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-t1_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-t1_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-t1_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-t1_meth.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_meth.c
+t1_meth.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+t1_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+t1_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+t1_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+t1_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+t1_meth.o: t1_meth.c
t1_reneg.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
t1_reneg.o: ../include/openssl/buffer.h ../include/openssl/comp.h
t1_reneg.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -948,11 +1012,12 @@ t1_reneg.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
t1_reneg.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
t1_reneg.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
t1_reneg.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-t1_reneg.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-t1_reneg.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-t1_reneg.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-t1_reneg.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-t1_reneg.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_reneg.c
+t1_reneg.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+t1_reneg.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+t1_reneg.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+t1_reneg.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+t1_reneg.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+t1_reneg.o: t1_reneg.c
t1_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
t1_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
t1_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -967,9 +1032,30 @@ t1_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
t1_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
t1_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
t1_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-t1_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-t1_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-t1_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-t1_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-t1_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-t1_srvr.o: t1_srvr.c
+t1_srvr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+t1_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+t1_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+t1_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+t1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+t1_srvr.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_srvr.c
+tls_srp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+tls_srp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+tls_srp.o: ../include/openssl/comp.h ../include/openssl/crypto.h
+tls_srp.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+tls_srp.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+tls_srp.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+tls_srp.o: ../include/openssl/err.h ../include/openssl/evp.h
+tls_srp.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+tls_srp.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+tls_srp.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+tls_srp.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+tls_srp.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+tls_srp.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+tls_srp.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+tls_srp.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+tls_srp.o: ../include/openssl/srp.h ../include/openssl/srtp.h
+tls_srp.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+tls_srp.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+tls_srp.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+tls_srp.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+tls_srp.o: ../include/openssl/x509_vfy.h ssl_locl.h tls_srp.c
diff --git a/deps/openssl/openssl/ssl/d1_both.c b/deps/openssl/openssl/ssl/d1_both.c
index 9f898d699..de8bab873 100644
--- a/deps/openssl/openssl/ssl/d1_both.c
+++ b/deps/openssl/openssl/ssl/d1_both.c
@@ -227,14 +227,14 @@ int dtls1_do_write(SSL *s, int type)
unsigned int len, frag_off, mac_size, blocksize;
/* AHA! Figure out the MTU, and stick to the right size */
- if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
+ if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
{
s->d1->mtu =
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
/* I've seen the kernel return bogus numbers when it doesn't know
* (initial write), so just make sure we have a reasonable number */
- if ( s->d1->mtu < dtls1_min_mtu())
+ if (s->d1->mtu < dtls1_min_mtu())
{
s->d1->mtu = 0;
s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
@@ -1084,7 +1084,11 @@ int dtls1_read_failed(SSL *s, int code)
return code;
}
- if ( ! SSL_in_init(s)) /* done, no need to send a retransmit */
+#ifndef OPENSSL_NO_HEARTBEATS
+ if (!SSL_in_init(s) && !s->tlsext_hb_pending) /* done, no need to send a retransmit */
+#else
+ if (!SSL_in_init(s)) /* done, no need to send a retransmit */
+#endif
{
BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
return code;
@@ -1417,3 +1421,171 @@ dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)
ccs_hdr->type = *(data++);
}
+
+int dtls1_shutdown(SSL *s)
+ {
+ int ret;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
+ !(s->shutdown & SSL_SENT_SHUTDOWN))
+ {
+ ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
+ if (ret < 0) return -1;
+
+ if (ret == 0)
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1, NULL);
+ }
+#endif
+ ret = ssl3_shutdown(s);
+#ifndef OPENSSL_NO_SCTP
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL);
+#endif
+ return ret;
+ }
+
+#ifndef OPENSSL_NO_HEARTBEATS
+int
+dtls1_process_heartbeat(SSL *s)
+ {
+ unsigned char *p = &s->s3->rrec.data[0], *pl;
+ unsigned short hbtype;
+ unsigned int payload;
+ unsigned int padding = 16; /* Use minimum padding */
+
+ /* Read type and payload length first */
+ hbtype = *p++;
+ n2s(p, payload);
+ pl = p;
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
+ &s->s3->rrec.data[0], s->s3->rrec.length,
+ s, s->msg_callback_arg);
+
+ if (hbtype == TLS1_HB_REQUEST)
+ {
+ unsigned char *buffer, *bp;
+ int r;
+
+ /* Allocate memory for the response, size is 1 byte
+ * message type, plus 2 bytes payload length, plus
+ * payload, plus padding
+ */
+ buffer = OPENSSL_malloc(1 + 2 + payload + padding);
+ bp = buffer;
+
+ /* Enter response type, length and copy payload */
+ *bp++ = TLS1_HB_RESPONSE;
+ s2n(payload, bp);
+ memcpy(bp, pl, payload);
+ bp += payload;
+ /* Random padding */
+ RAND_pseudo_bytes(bp, padding);
+
+ r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
+
+ if (r >= 0 && s->msg_callback)
+ s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
+ buffer, 3 + payload + padding,
+ s, s->msg_callback_arg);
+
+ OPENSSL_free(buffer);
+
+ if (r < 0)
+ return r;
+ }
+ else if (hbtype == TLS1_HB_RESPONSE)
+ {
+ unsigned int seq;
+
+ /* We only send sequence numbers (2 bytes unsigned int),
+ * and 16 random bytes, so we just try to read the
+ * sequence number */
+ n2s(pl, seq);
+
+ if (payload == 18 && seq == s->tlsext_hb_seq)
+ {
+ dtls1_stop_timer(s);
+ s->tlsext_hb_seq++;
+ s->tlsext_hb_pending = 0;
+ }
+ }
+
+ return 0;
+ }
+
+int
+dtls1_heartbeat(SSL *s)
+ {
+ unsigned char *buf, *p;
+ int ret;
+ unsigned int payload = 18; /* Sequence number + random bytes */
+ unsigned int padding = 16; /* Use minimum padding */
+
+ /* Only send if peer supports and accepts HB requests... */
+ if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
+ s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS)
+ {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
+ return -1;
+ }
+
+ /* ...and there is none in flight yet... */
+ if (s->tlsext_hb_pending)
+ {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING);
+ return -1;
+ }
+
+ /* ...and no handshake in progress. */
+ if (SSL_in_init(s) || s->in_handshake)
+ {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE);
+ return -1;
+ }
+
+ /* Check if padding is too long, payload and padding
+ * must not exceed 2^14 - 3 = 16381 bytes in total.
+ */
+ OPENSSL_assert(payload + padding <= 16381);
+
+ /* Create HeartBeat message, we just use a sequence number
+ * as payload to distuingish different messages and add
+ * some random stuff.
+ * - Message Type, 1 byte
+ * - Payload Length, 2 bytes (unsigned int)
+ * - Payload, the sequence number (2 bytes uint)
+ * - Payload, random bytes (16 bytes uint)
+ * - Padding
+ */
+ buf = OPENSSL_malloc(1 + 2 + payload + padding);
+ p = buf;
+ /* Message Type */
+ *p++ = TLS1_HB_REQUEST;
+ /* Payload length (18 bytes here) */
+ s2n(payload, p);
+ /* Sequence number */
+ s2n(s->tlsext_hb_seq, p);
+ /* 16 random bytes */
+ RAND_pseudo_bytes(p, 16);
+ p += 16;
+ /* Random padding */
+ RAND_pseudo_bytes(p, padding);
+
+ ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
+ if (ret >= 0)
+ {
+ if (s->msg_callback)
+ s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
+ buf, 3 + payload + padding,
+ s, s->msg_callback_arg);
+
+ dtls1_start_timer(s);
+ s->tlsext_hb_pending = 1;
+ }
+
+ OPENSSL_free(buf);
+
+ return ret;
+ }
+#endif
diff --git a/deps/openssl/openssl/ssl/d1_clnt.c b/deps/openssl/openssl/ssl/d1_clnt.c
index 577667176..a6ed09c51 100644
--- a/deps/openssl/openssl/ssl/d1_clnt.c
+++ b/deps/openssl/openssl/ssl/d1_clnt.c
@@ -150,7 +150,11 @@ int dtls1_connect(SSL *s)
unsigned long Time=(unsigned long)time(NULL);
void (*cb)(const SSL *ssl,int type,int val)=NULL;
int ret= -1;
- int new_state,state,skip=0;;
+ int new_state,state,skip=0;
+#ifndef OPENSSL_NO_SCTP
+ unsigned char sctpauthkey[64];
+ char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
+#endif
RAND_add(&Time,sizeof(Time),0);
ERR_clear_error();
@@ -164,6 +168,27 @@ int dtls1_connect(SSL *s)
s->in_handshake++;
if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
+#ifndef OPENSSL_NO_SCTP
+ /* Notify SCTP BIO socket to enter handshake
+ * mode and prevent stream identifier other
+ * than 0. Will be ignored if no SCTP is used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
+#endif
+
+#ifndef OPENSSL_NO_HEARTBEATS
+ /* If we're awaiting a HeartbeatResponse, pretend we
+ * already got and don't await it anymore, because
+ * Heartbeats don't make sense during handshakes anyway.
+ */
+ if (s->tlsext_hb_pending)
+ {
+ dtls1_stop_timer(s);
+ s->tlsext_hb_pending = 0;
+ s->tlsext_hb_seq++;
+ }
+#endif
+
for (;;)
{
state=s->state;
@@ -171,7 +196,7 @@ int dtls1_connect(SSL *s)
switch(s->state)
{
case SSL_ST_RENEGOTIATE:
- s->new_session=1;
+ s->renegotiate=1;
s->state=SSL_ST_CONNECT;
s->ctx->stats.sess_connect_renegotiate++;
/* break */
@@ -226,6 +251,42 @@ int dtls1_connect(SSL *s)
s->hit = 0;
break;
+#ifndef OPENSSL_NO_SCTP
+ case DTLS1_SCTP_ST_CR_READ_SOCK:
+
+ if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)))
+ {
+ s->s3->in_read_app_data=2;
+ s->rwstate=SSL_READING;
+ BIO_clear_retry_flags(SSL_get_rbio(s));
+ BIO_set_retry_read(SSL_get_rbio(s));
+ ret = -1;
+ goto end;
+ }
+
+ s->state=s->s3->tmp.next_state;
+ break;
+
+ case DTLS1_SCTP_ST_CW_WRITE_SOCK:
+ /* read app data until dry event */
+
+ ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
+ if (ret < 0) goto end;
+
+ if (ret == 0)
+ {
+ s->s3->in_read_app_data=2;
+ s->rwstate=SSL_READING;
+ BIO_clear_retry_flags(SSL_get_rbio(s));
+ BIO_set_retry_read(SSL_get_rbio(s));
+ ret = -1;
+ goto end;
+ }
+
+ s->state=s->d1->next_state;
+ break;
+#endif
+
case SSL3_ST_CW_CLNT_HELLO_A:
case SSL3_ST_CW_CLNT_HELLO_B:
@@ -248,9 +309,17 @@ int dtls1_connect(SSL *s)
s->init_num=0;
- /* turn on buffering for the next lot of output */
- if (s->bbio != s->wbio)
- s->wbio=BIO_push(s->bbio,s->wbio);
+#ifndef OPENSSL_NO_SCTP
+ /* Disable buffering for SCTP */
+ if (!BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+#endif
+ /* turn on buffering for the next lot of output */
+ if (s->bbio != s->wbio)
+ s->wbio=BIO_push(s->bbio,s->wbio);
+#ifndef OPENSSL_NO_SCTP
+ }
+#endif
break;
@@ -260,9 +329,25 @@ int dtls1_connect(SSL *s)
if (ret <= 0) goto end;
else
{
- dtls1_stop_timer(s);
if (s->hit)
+ {
+#ifndef OPENSSL_NO_SCTP
+ /* Add new shared key for SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
+ DTLS1_SCTP_AUTH_LABEL);
+
+ SSL_export_keying_material(s, sctpauthkey,
+ sizeof(sctpauthkey), labelbuffer,
+ sizeof(labelbuffer), NULL, 0, 0);
+
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
+ sizeof(sctpauthkey), sctpauthkey);
+#endif
+
s->state=SSL3_ST_CR_FINISHED_A;
+ }
else
s->state=DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
}
@@ -354,12 +439,20 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CR_SRVR_DONE_B:
ret=ssl3_get_server_done(s);
if (ret <= 0) goto end;
+ dtls1_stop_timer(s);
if (s->s3->tmp.cert_req)
- s->state=SSL3_ST_CW_CERT_A;
+ s->s3->tmp.next_state=SSL3_ST_CW_CERT_A;
else
- s->state=SSL3_ST_CW_KEY_EXCH_A;
+ s->s3->tmp.next_state=SSL3_ST_CW_KEY_EXCH_A;
s->init_num=0;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
+ state == SSL_ST_RENEGOTIATE)
+ s->state=DTLS1_SCTP_ST_CR_READ_SOCK;
+ else
+#endif
+ s->state=s->s3->tmp.next_state;
break;
case SSL3_ST_CW_CERT_A:
@@ -378,6 +471,22 @@ int dtls1_connect(SSL *s)
dtls1_start_timer(s);
ret=dtls1_send_client_key_exchange(s);
if (ret <= 0) goto end;
+
+#ifndef OPENSSL_NO_SCTP
+ /* Add new shared key for SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
+ DTLS1_SCTP_AUTH_LABEL);
+
+ SSL_export_keying_material(s, sctpauthkey,
+ sizeof(sctpauthkey), labelbuffer,
+ sizeof(labelbuffer), NULL, 0, 0);
+
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
+ sizeof(sctpauthkey), sctpauthkey);
+#endif
+
/* EAY EAY EAY need to check for DH fix cert
* sent back */
/* For TLS, cert_req is set to 2, so a cert chain
@@ -388,7 +497,15 @@ int dtls1_connect(SSL *s)
}
else
{
- s->state=SSL3_ST_CW_CHANGE_A;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+ s->d1->next_state=SSL3_ST_CW_CHANGE_A;
+ s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
+ }
+ else
+#endif
+ s->state=SSL3_ST_CW_CHANGE_A;
s->s3->change_cipher_spec=0;
}
@@ -400,7 +517,15 @@ int dtls1_connect(SSL *s)
dtls1_start_timer(s);
ret=dtls1_send_client_verify(s);
if (ret <= 0) goto end;
- s->state=SSL3_ST_CW_CHANGE_A;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+ s->d1->next_state=SSL3_ST_CW_CHANGE_A;
+ s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
+ }
+ else
+#endif
+ s->state=SSL3_ST_CW_CHANGE_A;
s->init_num=0;
s->s3->change_cipher_spec=0;
break;
@@ -412,6 +537,14 @@ int dtls1_connect(SSL *s)
ret=dtls1_send_change_cipher_spec(s,
SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
if (ret <= 0) goto end;
+
+#ifndef OPENSSL_NO_SCTP
+ /* Change to new shared key of SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+#endif
+
s->state=SSL3_ST_CW_FINISHED_A;
s->init_num=0;
@@ -457,9 +590,23 @@ int dtls1_connect(SSL *s)
if (s->hit)
{
s->s3->tmp.next_state=SSL_ST_OK;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+ s->d1->next_state = s->s3->tmp.next_state;
+ s->s3->tmp.next_state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
+ }
+#endif
if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
{
s->state=SSL_ST_OK;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+ s->d1->next_state = SSL_ST_OK;
+ s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
+ }
+#endif
s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
s->s3->delay_buf_pop_ret=0;
}
@@ -508,6 +655,16 @@ int dtls1_connect(SSL *s)
s->state=SSL3_ST_CW_CHANGE_A;
else
s->state=SSL_ST_OK;
+
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
+ state == SSL_ST_RENEGOTIATE)
+ {
+ s->d1->next_state=s->state;
+ s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
+ }
+#endif
+
s->init_num=0;
break;
@@ -515,6 +672,13 @@ int dtls1_connect(SSL *s)
s->rwstate=SSL_WRITING;
if (BIO_flush(s->wbio) <= 0)
{
+ /* If the write error was fatal, stop trying */
+ if (!BIO_should_retry(s->wbio))
+ {
+ s->rwstate=SSL_NOTHING;
+ s->state=s->s3->tmp.next_state;
+ }
+
ret= -1;
goto end;
}
@@ -541,6 +705,7 @@ int dtls1_connect(SSL *s)
/* else do it later in ssl3_write */
s->init_num=0;
+ s->renegotiate=0;
s->new_session=0;
ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
@@ -587,6 +752,15 @@ int dtls1_connect(SSL *s)
}
end:
s->in_handshake--;
+
+#ifndef OPENSSL_NO_SCTP
+ /* Notify SCTP BIO socket to leave handshake
+ * mode and allow stream identifier other
+ * than 0. Will be ignored if no SCTP is used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
+#endif
+
if (buf != NULL)
BUF_MEM_free(buf);
if (cb != NULL)
@@ -615,12 +789,6 @@ int dtls1_client_hello(SSL *s)
#endif
(s->session->not_resumable))
{
- if (!s->session_creation_enabled)
- {
- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
- SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
- goto err;
- }
if (!ssl_get_new_session(s,0))
goto err;
}
diff --git a/deps/openssl/openssl/ssl/d1_enc.c b/deps/openssl/openssl/ssl/d1_enc.c
index becbab91c..712c4647f 100644
--- a/deps/openssl/openssl/ssl/d1_enc.c
+++ b/deps/openssl/openssl/ssl/d1_enc.c
@@ -126,20 +126,28 @@
#include <openssl/des.h>
#endif
+/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+ *
+ * Returns:
+ * 0: (in non-constant time) if the record is publically invalid (i.e. too
+ * short etc).
+ * 1: if the record's padding is valid / the encryption was successful.
+ * -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
+ * an internal error occured. */
int dtls1_enc(SSL *s, int send)
{
SSL3_RECORD *rec;
EVP_CIPHER_CTX *ds;
unsigned long l;
- int bs,i,ii,j,k,n=0;
+ int bs,i,j,k,mac_size=0;
const EVP_CIPHER *enc;
if (send)
{
if (EVP_MD_CTX_md(s->write_hash))
{
- n=EVP_MD_CTX_size(s->write_hash);
- if (n < 0)
+ mac_size=EVP_MD_CTX_size(s->write_hash);
+ if (mac_size < 0)
return -1;
}
ds=s->enc_write_ctx;
@@ -164,9 +172,8 @@ int dtls1_enc(SSL *s, int send)
{
if (EVP_MD_CTX_md(s->read_hash))
{
- n=EVP_MD_CTX_size(s->read_hash);
- if (n < 0)
- return -1;
+ mac_size=EVP_MD_CTX_size(s->read_hash);
+ OPENSSL_assert(mac_size >= 0);
}
ds=s->enc_read_ctx;
rec= &(s->s3->rrec);
@@ -231,7 +238,7 @@ int dtls1_enc(SSL *s, int send)
if (!send)
{
if (l == 0 || l%bs != 0)
- return -1;
+ return 0;
}
EVP_Cipher(ds,rec->data,rec->input,l);
@@ -246,43 +253,7 @@ int dtls1_enc(SSL *s, int send)
#endif /* KSSL_DEBUG */
if ((bs != 1) && !send)
- {
- ii=i=rec->data[l-1]; /* padding_length */
- i++;
- if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
- {
- /* First packet is even in size, so check */
- if ((memcmp(s->s3->read_sequence,
- "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
- s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
- if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
- i--;
- }
- /* TLS 1.0 does not bound the number of padding bytes by the block size.
- * All of them must have value 'padding_length'. */
- if (i > (int)rec->length)
- {
- /* Incorrect padding. SSLerr() and ssl3_alert are done
- * by caller: we don't want to reveal whether this is
- * a decryption error or a MAC verification failure
- * (see http://www.openssl.org/~bodo/tls-cbc.txt)
- */
- return -1;
- }
- for (j=(int)(l-i); j<(int)l; j++)
- {
- if (rec->data[j] != ii)
- {
- /* Incorrect padding */
- return -1;
- }
- }
- rec->length-=i;
-
- rec->data += bs; /* skip the implicit IV */
- rec->input += bs;
- rec->length -= bs;
- }
+ return tls1_cbc_remove_padding(s, rec, bs, mac_size);
}
return(1);
}
diff --git a/deps/openssl/openssl/ssl/d1_lib.c b/deps/openssl/openssl/ssl/d1_lib.c
index a94290a83..f61f71818 100644
--- a/deps/openssl/openssl/ssl/d1_lib.c
+++ b/deps/openssl/openssl/ssl/d1_lib.c
@@ -292,6 +292,15 @@ const SSL_CIPHER *dtls1_get_cipher(unsigned int u)
void dtls1_start_timer(SSL *s)
{
+#ifndef OPENSSL_NO_SCTP
+ /* Disable timer for SCTP */
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+ memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
+ return;
+ }
+#endif
+
/* If timer is not set, initialize duration with 1 second */
if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
{
@@ -382,6 +391,7 @@ void dtls1_double_timeout(SSL *s)
void dtls1_stop_timer(SSL *s)
{
/* Reset everything */
+ memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st));
memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
s->d1->timeout_duration = 1;
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
@@ -389,10 +399,28 @@ void dtls1_stop_timer(SSL *s)
dtls1_clear_record_buffer(s);
}
-int dtls1_handle_timeout(SSL *s)
+int dtls1_check_timeout_num(SSL *s)
{
- DTLS1_STATE *state;
+ s->d1->timeout.num_alerts++;
+
+ /* Reduce MTU after 2 unsuccessful retransmissions */
+ if (s->d1->timeout.num_alerts > 2)
+ {
+ s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
+ }
+ if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
+ {
+ /* fail the connection, enough alerts have been sent */
+ SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM,SSL_R_READ_TIMEOUT_EXPIRED);
+ return -1;
+ }
+
+ return 0;
+ }
+
+int dtls1_handle_timeout(SSL *s)
+ {
/* if no timer is expired, don't do anything */
if (!dtls1_is_timer_expired(s))
{
@@ -400,20 +428,23 @@ int dtls1_handle_timeout(SSL *s)
}
dtls1_double_timeout(s);
- state = s->d1;
- state->timeout.num_alerts++;
- if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
- {
- /* fail the connection, enough alerts have been sent */
- SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
+
+ if (dtls1_check_timeout_num(s) < 0)
return -1;
+
+ s->d1->timeout.read_timeouts++;
+ if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
+ {
+ s->d1->timeout.read_timeouts = 1;
}
- state->timeout.read_timeouts++;
- if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
+#ifndef OPENSSL_NO_HEARTBEATS
+ if (s->tlsext_hb_pending)
{
- state->timeout.read_timeouts = 1;
+ s->tlsext_hb_pending = 0;
+ return dtls1_heartbeat(s);
}
+#endif
dtls1_start_timer(s);
return dtls1_retransmit_buffered_messages(s);
diff --git a/deps/openssl/openssl/ssl/d1_pkt.c b/deps/openssl/openssl/ssl/d1_pkt.c
index 3927dad27..0bf87be6d 100644
--- a/deps/openssl/openssl/ssl/d1_pkt.c
+++ b/deps/openssl/openssl/ssl/d1_pkt.c
@@ -179,7 +179,6 @@ static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
static int dtls1_buffer_record(SSL *s, record_pqueue *q,
unsigned char *priority);
static int dtls1_process_record(SSL *s);
-static void dtls1_clear_timeouts(SSL *s);
/* copy buffered record into SSL structure */
static int
@@ -232,6 +231,14 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
item->data = rdata;
+#ifndef OPENSSL_NO_SCTP
+ /* Store bio_dgram_sctp_rcvinfo struct */
+ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+ (s->state == SSL3_ST_SR_FINISHED_A || s->state == SSL3_ST_CR_FINISHED_A)) {
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, sizeof(rdata->recordinfo), &rdata->recordinfo);
+ }
+#endif
+
/* insert should not fail, since duplicates are dropped */
if (pqueue_insert(queue->q, item) == NULL)
{
@@ -369,14 +376,11 @@ static int
dtls1_process_record(SSL *s)
{
int i,al;
- int clear=0;
int enc_err;
SSL_SESSION *sess;
SSL3_RECORD *rr;
- unsigned int mac_size;
+ unsigned int mac_size, orig_len;
unsigned char md[EVP_MAX_MD_SIZE];
- int decryption_failed_or_bad_record_mac = 0;
-
rr= &(s->s3->rrec);
sess = s->session;
@@ -408,12 +412,16 @@ dtls1_process_record(SSL *s)
rr->data=rr->input;
enc_err = s->method->ssl3_enc->enc(s,0);
- if (enc_err <= 0)
+ /* enc_err is:
+ * 0: (in non-constant time) if the record is publically invalid.
+ * 1: if the padding is valid
+ * -1: if the padding is invalid */
+ if (enc_err == 0)
{
- /* To minimize information leaked via timing, we will always
- * perform all computations before discarding the message.
- */
- decryption_failed_or_bad_record_mac = 1;
+ /* For DTLS we simply ignore bad packets. */
+ rr->length = 0;
+ s->packet_length = 0;
+ goto err;
}
#ifdef TLS_DEBUG
@@ -423,49 +431,62 @@ printf("\n");
#endif
/* r->length is now the compressed data plus mac */
- if ( (sess == NULL) ||
- (s->enc_read_ctx == NULL) ||
- (s->read_hash == NULL))
- clear=1;
-
- if (!clear)
+ if ((sess != NULL) &&
+ (s->enc_read_ctx != NULL) &&
+ (EVP_MD_CTX_md(s->read_hash) != NULL))
{
- /* !clear => s->read_hash != NULL => mac_size != -1 */
- int t;
- t=EVP_MD_CTX_size(s->read_hash);
- OPENSSL_assert(t >= 0);
- mac_size=t;
-
- if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
- {
-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
- al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
- goto f_err;
-#else
- decryption_failed_or_bad_record_mac = 1;
-#endif
- }
- /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
- if (rr->length < mac_size)
+ /* s->read_hash != NULL => mac_size != -1 */
+ unsigned char *mac = NULL;
+ unsigned char mac_tmp[EVP_MAX_MD_SIZE];
+ mac_size=EVP_MD_CTX_size(s->read_hash);
+ OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
+
+ /* kludge: *_cbc_remove_padding passes padding length in rr->type */
+ orig_len = rr->length+((unsigned int)rr->type>>8);
+
+ /* orig_len is the length of the record before any padding was
+ * removed. This is public information, as is the MAC in use,
+ * therefore we can safely process the record in a different
+ * amount of time if it's too short to possibly contain a MAC.
+ */
+ if (orig_len < mac_size ||
+ /* CBC records must have a padding length byte too. */
+ (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+ orig_len < mac_size+1))
{
-#if 0 /* OK only for stream ciphers */
al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
goto f_err;
-#else
- decryption_failed_or_bad_record_mac = 1;
-#endif
}
- rr->length-=mac_size;
- i=s->method->ssl3_enc->mac(s,md,0);
- if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
+
+ if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
{
- decryption_failed_or_bad_record_mac = 1;
+ /* We update the length so that the TLS header bytes
+ * can be constructed correctly but we need to extract
+ * the MAC in constant time from within the record,
+ * without leaking the contents of the padding bytes.
+ * */
+ mac = mac_tmp;
+ ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
+ rr->length -= mac_size;
}
+ else
+ {
+ /* In this case there's no padding, so |orig_len|
+ * equals |rec->length| and we checked that there's
+ * enough bytes for |mac_size| above. */
+ rr->length -= mac_size;
+ mac = &rr->data[rr->length];
+ }
+
+ i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
+ if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+ enc_err = -1;
+ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
+ enc_err = -1;
}
- if (decryption_failed_or_bad_record_mac)
+ if (enc_err < 0)
{
/* decryption failed, silently discard message */
rr->length = 0;
@@ -610,24 +631,6 @@ again:
goto again;
}
- /* If we receive a valid record larger than the current buffer size,
- * allocate some memory for it.
- */
- if (rr->length > s->s3->rbuf.len - DTLS1_RT_HEADER_LENGTH)
- {
- unsigned char *pp;
- unsigned int newlen = rr->length + DTLS1_RT_HEADER_LENGTH;
- if ((pp=OPENSSL_realloc(s->s3->rbuf.buf, newlen))==NULL)
- {
- SSLerr(SSL_F_DTLS1_GET_RECORD,ERR_R_MALLOC_FAILURE);
- return(-1);
- }
- p = pp + (p - s->s3->rbuf.buf);
- s->s3->rbuf.buf=pp;
- s->s3->rbuf.len=newlen;
- s->packet= &(s->s3->rbuf.buf[0]);
- }
-
/* now s->rstate == SSL_ST_READ_BODY */
}
@@ -662,20 +665,28 @@ again:
goto again; /* get another record */
}
- /* Check whether this is a repeat, or aged record.
- * Don't check if we're listening and this message is
- * a ClientHello. They can look as if they're replayed,
- * since they arrive from different connections and
- * would be dropped unnecessarily.
- */
- if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
- *p == SSL3_MT_CLIENT_HELLO) &&
- !dtls1_record_replay_check(s, bitmap))
- {
- rr->length = 0;
- s->packet_length=0; /* dump this record */
- goto again; /* get another record */
- }
+#ifndef OPENSSL_NO_SCTP
+ /* Only do replay check if no SCTP bio */
+ if (!BIO_dgram_is_sctp(SSL_get_rbio(s)))
+ {
+#endif
+ /* Check whether this is a repeat, or aged record.
+ * Don't check if we're listening and this message is
+ * a ClientHello. They can look as if they're replayed,
+ * since they arrive from different connections and
+ * would be dropped unnecessarily.
+ */
+ if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
+ *p == SSL3_MT_CLIENT_HELLO) &&
+ !dtls1_record_replay_check(s, bitmap))
+ {
+ rr->length = 0;
+ s->packet_length=0; /* dump this record */
+ goto again; /* get another record */
+ }
+#ifndef OPENSSL_NO_SCTP
+ }
+#endif
/* just read a 0 length packet */
if (rr->length == 0) goto again;
@@ -703,7 +714,6 @@ again:
goto again; /* get another record */
}
- dtls1_clear_timeouts(s); /* done waiting */
return(1);
}
@@ -761,7 +771,17 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
/* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */
+#ifndef OPENSSL_NO_SCTP
+ /* Continue handshake if it had to be interrupted to read
+ * app data with SCTP.
+ */
+ if ((!s->in_handshake && SSL_in_init(s)) ||
+ (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+ (s->state == DTLS1_SCTP_ST_SR_READ_SOCK || s->state == DTLS1_SCTP_ST_CR_READ_SOCK) &&
+ s->s3->in_read_app_data != 2))
+#else
if (!s->in_handshake && SSL_in_init(s))
+#endif
{
/* type == SSL3_RT_APPLICATION_DATA */
i=s->handshake_func(s);
@@ -792,6 +812,15 @@ start:
item = pqueue_pop(s->d1->buffered_app_data.q);
if (item)
{
+#ifndef OPENSSL_NO_SCTP
+ /* Restore bio_dgram_sctp_rcvinfo struct */
+ if (BIO_dgram_is_sctp(SSL_get_rbio(s)))
+ {
+ DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *) item->data;
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO, sizeof(rdata->recordinfo), &rdata->recordinfo);
+ }
+#endif
+
dtls1_copy_record(s, item);
OPENSSL_free(item->data);
@@ -874,6 +903,31 @@ start:
rr->off=0;
}
}
+
+#ifndef OPENSSL_NO_SCTP
+ /* We were about to renegotiate but had to read
+ * belated application data first, so retry.
+ */
+ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+ rr->type == SSL3_RT_APPLICATION_DATA &&
+ (s->state == DTLS1_SCTP_ST_SR_READ_SOCK || s->state == DTLS1_SCTP_ST_CR_READ_SOCK))
+ {
+ s->rwstate=SSL_READING;
+ BIO_clear_retry_flags(SSL_get_rbio(s));
+ BIO_set_retry_read(SSL_get_rbio(s));
+ }
+
+ /* We might had to delay a close_notify alert because
+ * of reordered app data. If there was an alert and there
+ * is no message to read anymore, finally set shutdown.
+ */
+ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+ s->d1->shutdown_received && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)))
+ {
+ s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+ return(0);
+ }
+#endif
return(n);
}
@@ -901,6 +955,19 @@ start:
dest = s->d1->alert_fragment;
dest_len = &s->d1->alert_fragment_len;
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ else if (rr->type == TLS1_RT_HEARTBEAT)
+ {
+ dtls1_process_heartbeat(s);
+
+ /* Exit and notify application to read again */
+ rr->length = 0;
+ s->rwstate=SSL_READING;
+ BIO_clear_retry_flags(SSL_get_rbio(s));
+ BIO_set_retry_read(SSL_get_rbio(s));
+ return(-1);
+ }
+#endif
/* else it's a CCS message, or application data or wrong */
else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
{
@@ -984,6 +1051,7 @@ start:
!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
!s->s3->renegotiate)
{
+ s->new_session = 1;
ssl3_renegotiate(s);
if (ssl3_renegotiate_check(s))
{
@@ -1045,6 +1113,21 @@ start:
s->s3->warn_alert = alert_descr;
if (alert_descr == SSL_AD_CLOSE_NOTIFY)
{
+#ifndef OPENSSL_NO_SCTP
+ /* With SCTP and streams the socket may deliver app data
+ * after a close_notify alert. We have to check this
+ * first so that nothing gets discarded.
+ */
+ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+ BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)))
+ {
+ s->d1->shutdown_received = 1;
+ s->rwstate=SSL_READING;
+ BIO_clear_retry_flags(SSL_get_rbio(s));
+ BIO_set_retry_read(SSL_get_rbio(s));
+ return -1;
+ }
+#endif
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
return(0);
}
@@ -1151,6 +1234,15 @@ start:
if (s->version == DTLS1_BAD_VER)
s->d1->handshake_read_seq++;
+#ifndef OPENSSL_NO_SCTP
+ /* Remember that a CCS has been received,
+ * so that an old key of SCTP-Auth can be
+ * deleted when a CCS is sent. Will be ignored
+ * if no SCTP is used
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL);
+#endif
+
goto start;
}
@@ -1173,6 +1265,9 @@ start:
*/
if (msg_hdr.type == SSL3_MT_FINISHED)
{
+ if (dtls1_check_timeout_num(s) < 0)
+ return -1;
+
dtls1_retransmit_buffered_messages(s);
rr->length = 0;
goto start;
@@ -1190,6 +1285,7 @@ start:
#else
s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
#endif
+ s->renegotiate=1;
s->new_session=1;
}
i=s->handshake_func(s);
@@ -1286,7 +1382,16 @@ dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
{
int i;
- if (SSL_in_init(s) && !s->in_handshake)
+#ifndef OPENSSL_NO_SCTP
+ /* Check if we have to continue an interrupted handshake
+ * for reading belated app data with SCTP.
+ */
+ if ((SSL_in_init(s) && !s->in_handshake) ||
+ (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
+ (s->state == DTLS1_SCTP_ST_SR_READ_SOCK || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)))
+#else
+ if (SSL_in_init(s) && !s->in_handshake)
+#endif
{
i=s->handshake_func(s);
if (i < 0) return(i);
@@ -1364,7 +1469,6 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
SSL3_BUFFER *wb;
SSL_SESSION *sess;
int bs;
- unsigned int len_with_overhead = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
/* first check if there is a SSL3_BUFFER still being written
* out. This will happen with non blocking IO */
@@ -1374,16 +1478,6 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
return(ssl3_write_pending(s,type,buf,len));
}
- if (s->s3->wbuf.len < len_with_overhead)
- {
- if ((p=OPENSSL_realloc(s->s3->wbuf.buf, len_with_overhead)) == NULL) {
- SSLerr(SSL_F_DO_DTLS1_WRITE,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s->s3->wbuf.buf = p;
- s->s3->wbuf.len = len_with_overhead;
- }
-
/* If we have an alert to send, lets send it */
if (s->s3->alert_dispatch)
{
@@ -1797,10 +1891,3 @@ dtls1_reset_seq_numbers(SSL *s, int rw)
memset(seq, 0x00, seq_bytes);
}
-
-
-static void
-dtls1_clear_timeouts(SSL *s)
- {
- memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st));
- }
diff --git a/deps/openssl/openssl/ssl/d1_srtp.c b/deps/openssl/openssl/ssl/d1_srtp.c
new file mode 100644
index 000000000..ab9c41922
--- /dev/null
+++ b/deps/openssl/openssl/ssl/d1_srtp.c
@@ -0,0 +1,494 @@
+/* ssl/t1_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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).
+ *
+ */
+/*
+ DTLS code by Eric Rescorla <ekr@rtfm.com>
+
+ Copyright (C) 2006, Network Resonance, Inc.
+ Copyright (C) 2011, RTFM, Inc.
+*/
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+#ifndef OPENSSL_NO_SRTP
+
+#include "srtp.h"
+
+
+static SRTP_PROTECTION_PROFILE srtp_known_profiles[]=
+ {
+ {
+ "SRTP_AES128_CM_SHA1_80",
+ SRTP_AES128_CM_SHA1_80,
+ },
+ {
+ "SRTP_AES128_CM_SHA1_32",
+ SRTP_AES128_CM_SHA1_32,
+ },
+#if 0
+ {
+ "SRTP_NULL_SHA1_80",
+ SRTP_NULL_SHA1_80,
+ },
+ {
+ "SRTP_NULL_SHA1_32",
+ SRTP_NULL_SHA1_32,
+ },
+#endif
+ {0}
+ };
+
+static int find_profile_by_name(char *profile_name,
+ SRTP_PROTECTION_PROFILE **pptr,unsigned len)
+ {
+ SRTP_PROTECTION_PROFILE *p;
+
+ p=srtp_known_profiles;
+ while(p->name)
+ {
+ if((len == strlen(p->name)) && !strncmp(p->name,profile_name,
+ len))
+ {
+ *pptr=p;
+ return 0;
+ }
+
+ p++;
+ }
+
+ return 1;
+ }
+
+static int find_profile_by_num(unsigned profile_num,
+ SRTP_PROTECTION_PROFILE **pptr)
+ {
+ SRTP_PROTECTION_PROFILE *p;
+
+ p=srtp_known_profiles;
+ while(p->name)
+ {
+ if(p->id == profile_num)
+ {
+ *pptr=p;
+ return 0;
+ }
+ p++;
+ }
+
+ return 1;
+ }
+
+static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTECTION_PROFILE) **out)
+ {
+ STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
+
+ char *col;
+ char *ptr=(char *)profiles_string;
+
+ SRTP_PROTECTION_PROFILE *p;
+
+ if(!(profiles=sk_SRTP_PROTECTION_PROFILE_new_null()))
+ {
+ SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
+ return 1;
+ }
+
+ do
+ {
+ col=strchr(ptr,':');
+
+ if(!find_profile_by_name(ptr,&p,
+ col ? col-ptr : (int)strlen(ptr)))
+ {
+ sk_SRTP_PROTECTION_PROFILE_push(profiles,p);
+ }
+ else
+ {
+ SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
+ return 1;
+ }
+
+ if(col) ptr=col+1;
+ } while (col);
+
+ *out=profiles;
+
+ return 0;
+ }
+
+int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,const char *profiles)
+ {
+ return ssl_ctx_make_profiles(profiles,&ctx->srtp_profiles);
+ }
+
+int SSL_set_tlsext_use_srtp(SSL *s,const char *profiles)
+ {
+ return ssl_ctx_make_profiles(profiles,&s->srtp_profiles);
+ }
+
+
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s)
+ {
+ if(s != NULL)
+ {
+ if(s->srtp_profiles != NULL)
+ {
+ return s->srtp_profiles;
+ }
+ else if((s->ctx != NULL) &&
+ (s->ctx->srtp_profiles != NULL))
+ {
+ return s->ctx->srtp_profiles;
+ }
+ }
+
+ return NULL;
+ }
+
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s)
+ {
+ return s->srtp_profile;
+ }
+
+/* Note: this function returns 0 length if there are no
+ profiles specified */
+int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
+ {
+ int ct=0;
+ int i;
+ STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0;
+ SRTP_PROTECTION_PROFILE *prof;
+
+ clnt=SSL_get_srtp_profiles(s);
+ ct=sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
+
+ if(p)
+ {
+ if(ct==0)
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
+ return 1;
+ }
+
+ if((2 + ct*2 + 1) > maxlen)
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
+ return 1;
+ }
+
+ /* Add the length */
+ s2n(ct * 2, p);
+ for(i=0;i<ct;i++)
+ {
+ prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i);
+ s2n(prof->id,p);
+ }
+
+ /* Add an empty use_mki value */
+ *p++ = 0;
+ }
+
+ *len=2 + ct*2 + 1;
+
+ return 0;
+ }
+
+
+int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
+ {
+ SRTP_PROTECTION_PROFILE *cprof,*sprof;
+ STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0,*srvr;
+ int ct;
+ int mki_len;
+ int i,j;
+ int id;
+ int ret;
+
+ /* Length value + the MKI length */
+ if(len < 3)
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ /* Pull off the length of the cipher suite list */
+ n2s(d, ct);
+ len -= 2;
+
+ /* Check that it is even */
+ if(ct%2)
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ /* Check that lengths are consistent */
+ if(len < (ct + 1))
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+
+ clnt=sk_SRTP_PROTECTION_PROFILE_new_null();
+
+ while(ct)
+ {
+ n2s(d,id);
+ ct-=2;
+ len-=2;
+
+ if(!find_profile_by_num(id,&cprof))
+ {
+ sk_SRTP_PROTECTION_PROFILE_push(clnt,cprof);
+ }
+ else
+ {
+ ; /* Ignore */
+ }
+ }
+
+ /* Now extract the MKI value as a sanity check, but discard it for now */
+ mki_len = *d;
+ d++; len--;
+
+ if (mki_len != len)
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_MKI_VALUE);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ srvr=SSL_get_srtp_profiles(s);
+
+ /* Pick our most preferred profile. If no profiles have been
+ configured then the outer loop doesn't run
+ (sk_SRTP_PROTECTION_PROFILE_num() = -1)
+ and so we just return without doing anything */
+ for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(srvr);i++)
+ {
+ sprof=sk_SRTP_PROTECTION_PROFILE_value(srvr,i);
+
+ for(j=0;j<sk_SRTP_PROTECTION_PROFILE_num(clnt);j++)
+ {
+ cprof=sk_SRTP_PROTECTION_PROFILE_value(clnt,j);
+
+ if(cprof->id==sprof->id)
+ {
+ s->srtp_profile=sprof;
+ *al=0;
+ ret=0;
+ goto done;
+ }
+ }
+ }
+
+ ret=0;
+
+done:
+ if(clnt) sk_SRTP_PROTECTION_PROFILE_free(clnt);
+
+ return ret;
+ }
+
+int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
+ {
+ if(p)
+ {
+ if(maxlen < 5)
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
+ return 1;
+ }
+
+ if(s->srtp_profile==0)
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,SSL_R_USE_SRTP_NOT_NEGOTIATED);
+ return 1;
+ }
+ s2n(2, p);
+ s2n(s->srtp_profile->id,p);
+ *p++ = 0;
+ }
+ *len=5;
+
+ return 0;
+ }
+
+
+int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
+ {
+ unsigned id;
+ int i;
+ int ct;
+
+ STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
+ SRTP_PROTECTION_PROFILE *prof;
+
+ if(len!=5)
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ n2s(d, ct);
+ if(ct!=2)
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ n2s(d,id);
+ if (*d) /* Must be no MKI, since we never offer one */
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_MKI_VALUE);
+ *al=SSL_AD_ILLEGAL_PARAMETER;
+ return 1;
+ }
+
+ clnt=SSL_get_srtp_profiles(s);
+
+ /* Throw an error if the server gave us an unsolicited extension */
+ if (clnt == NULL)
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_NO_SRTP_PROFILES);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ /* Check to see if the server gave us something we support
+ (and presumably offered)
+ */
+ for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(clnt);i++)
+ {
+ prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i);
+
+ if(prof->id == id)
+ {
+ s->srtp_profile=prof;
+ *al=0;
+ return 0;
+ }
+ }
+
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+
+#endif
diff --git a/deps/openssl/openssl/ssl/d1_srvr.c b/deps/openssl/openssl/ssl/d1_srvr.c
index 149983be3..29421da9a 100644
--- a/deps/openssl/openssl/ssl/d1_srvr.c
+++ b/deps/openssl/openssl/ssl/d1_srvr.c
@@ -151,6 +151,10 @@ int dtls1_accept(SSL *s)
int ret= -1;
int new_state,state,skip=0;
int listen;
+#ifndef OPENSSL_NO_SCTP
+ unsigned char sctpauthkey[64];
+ char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
+#endif
RAND_add(&Time,sizeof(Time),0);
ERR_clear_error();
@@ -168,6 +172,13 @@ int dtls1_accept(SSL *s)
if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
s->d1->listen = listen;
+#ifndef OPENSSL_NO_SCTP
+ /* Notify SCTP BIO socket to enter handshake
+ * mode and prevent stream identifier other
+ * than 0. Will be ignored if no SCTP is used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
+#endif
if (s->cert == NULL)
{
@@ -175,6 +186,19 @@ int dtls1_accept(SSL *s)
return(-1);
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ /* If we're awaiting a HeartbeatResponse, pretend we
+ * already got and don't await it anymore, because
+ * Heartbeats don't make sense during handshakes anyway.
+ */
+ if (s->tlsext_hb_pending)
+ {
+ dtls1_stop_timer(s);
+ s->tlsext_hb_pending = 0;
+ s->tlsext_hb_seq++;
+ }
+#endif
+
for (;;)
{
state=s->state;
@@ -182,7 +206,7 @@ int dtls1_accept(SSL *s)
switch (s->state)
{
case SSL_ST_RENEGOTIATE:
- s->new_session=1;
+ s->renegotiate=1;
/* s->state=SSL_ST_ACCEPT; */
case SSL_ST_BEFORE:
@@ -227,8 +251,12 @@ int dtls1_accept(SSL *s)
{
/* Ok, we now need to push on a buffering BIO so that
* the output is sent in a way that TCP likes :-)
+ * ...but not with SCTP :-)
*/
- if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; }
+#ifndef OPENSSL_NO_SCTP
+ if (!BIO_dgram_is_sctp(SSL_get_wbio(s)))
+#endif
+ if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; }
ssl3_init_finished_mac(s);
s->state=SSL3_ST_SR_CLNT_HELLO_A;
@@ -313,25 +341,75 @@ int dtls1_accept(SSL *s)
ssl3_init_finished_mac(s);
break;
+#ifndef OPENSSL_NO_SCTP
+ case DTLS1_SCTP_ST_SR_READ_SOCK:
+
+ if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)))
+ {
+ s->s3->in_read_app_data=2;
+ s->rwstate=SSL_READING;
+ BIO_clear_retry_flags(SSL_get_rbio(s));
+ BIO_set_retry_read(SSL_get_rbio(s));
+ ret = -1;
+ goto end;
+ }
+
+ s->state=SSL3_ST_SR_FINISHED_A;
+ break;
+
+ case DTLS1_SCTP_ST_SW_WRITE_SOCK:
+ ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
+ if (ret < 0) goto end;
+
+ if (ret == 0)
+ {
+ if (s->d1->next_state != SSL_ST_OK)
+ {
+ s->s3->in_read_app_data=2;
+ s->rwstate=SSL_READING;
+ BIO_clear_retry_flags(SSL_get_rbio(s));
+ BIO_set_retry_read(SSL_get_rbio(s));
+ ret = -1;
+ goto end;
+ }
+ }
+
+ s->state=s->d1->next_state;
+ break;
+#endif
+
case SSL3_ST_SW_SRVR_HELLO_A:
case SSL3_ST_SW_SRVR_HELLO_B:
- s->new_session = 2;
+ s->renegotiate = 2;
dtls1_start_timer(s);
ret=dtls1_send_server_hello(s);
if (ret <= 0) goto end;
-#ifndef OPENSSL_NO_TLSEXT
if (s->hit)
{
+#ifndef OPENSSL_NO_SCTP
+ /* Add new shared key for SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
+ DTLS1_SCTP_AUTH_LABEL);
+
+ SSL_export_keying_material(s, sctpauthkey,
+ sizeof(sctpauthkey), labelbuffer,
+ sizeof(labelbuffer), NULL, 0, 0);
+
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
+ sizeof(sctpauthkey), sctpauthkey);
+#endif
+#ifndef OPENSSL_NO_TLSEXT
if (s->tlsext_ticket_expected)
s->state=SSL3_ST_SW_SESSION_TICKET_A;
else
s->state=SSL3_ST_SW_CHANGE_A;
- }
#else
- if (s->hit)
- s->state=SSL3_ST_SW_CHANGE_A;
+ s->state=SSL3_ST_SW_CHANGE_A;
#endif
+ }
else
s->state=SSL3_ST_SW_CERT_A;
s->init_num=0;
@@ -441,6 +519,13 @@ int dtls1_accept(SSL *s)
skip=1;
s->s3->tmp.cert_request=0;
s->state=SSL3_ST_SW_SRVR_DONE_A;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+ s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A;
+ s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
+ }
+#endif
}
else
{
@@ -450,9 +535,23 @@ int dtls1_accept(SSL *s)
if (ret <= 0) goto end;
#ifndef NETSCAPE_HANG_BUG
s->state=SSL3_ST_SW_SRVR_DONE_A;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+ s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A;
+ s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
+ }
+#endif
#else
s->state=SSL3_ST_SW_FLUSH;
s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+ s->d1->next_state = s->s3->tmp.next_state;
+ s->s3->tmp.next_state=DTLS1_SCTP_ST_SW_WRITE_SOCK;
+ }
+#endif
#endif
s->init_num=0;
}
@@ -472,6 +571,13 @@ int dtls1_accept(SSL *s)
s->rwstate=SSL_WRITING;
if (BIO_flush(s->wbio) <= 0)
{
+ /* If the write error was fatal, stop trying */
+ if (!BIO_should_retry(s->wbio))
+ {
+ s->rwstate=SSL_NOTHING;
+ s->state=s->s3->tmp.next_state;
+ }
+
ret= -1;
goto end;
}
@@ -485,15 +591,16 @@ int dtls1_accept(SSL *s)
ret = ssl3_check_client_hello(s);
if (ret <= 0)
goto end;
- dtls1_stop_timer(s);
if (ret == 2)
+ {
+ dtls1_stop_timer(s);
s->state = SSL3_ST_SR_CLNT_HELLO_C;
+ }
else {
/* could be sent for a DH cert, even if we
* have not asked for it :-) */
ret=ssl3_get_client_certificate(s);
if (ret <= 0) goto end;
- dtls1_stop_timer(s);
s->init_num=0;
s->state=SSL3_ST_SR_KEY_EXCH_A;
}
@@ -503,7 +610,21 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_KEY_EXCH_B:
ret=ssl3_get_client_key_exchange(s);
if (ret <= 0) goto end;
- dtls1_stop_timer(s);
+#ifndef OPENSSL_NO_SCTP
+ /* Add new shared key for SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ snprintf((char *) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
+ DTLS1_SCTP_AUTH_LABEL);
+
+ SSL_export_keying_material(s, sctpauthkey,
+ sizeof(sctpauthkey), labelbuffer,
+ sizeof(labelbuffer), NULL, 0, 0);
+
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
+ sizeof(sctpauthkey), sctpauthkey);
+#endif
+
s->state=SSL3_ST_SR_CERT_VRFY_A;
s->init_num=0;
@@ -540,9 +661,13 @@ int dtls1_accept(SSL *s)
/* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end;
- dtls1_stop_timer(s);
-
- s->state=SSL3_ST_SR_FINISHED_A;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
+ state == SSL_ST_RENEGOTIATE)
+ s->state=DTLS1_SCTP_ST_SR_READ_SOCK;
+ else
+#endif
+ s->state=SSL3_ST_SR_FINISHED_A;
s->init_num=0;
break;
@@ -594,6 +719,14 @@ int dtls1_accept(SSL *s)
SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B);
if (ret <= 0) goto end;
+
+#ifndef OPENSSL_NO_SCTP
+ /* Change to new shared key of SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+#endif
+
s->state=SSL3_ST_SW_FINISHED_A;
s->init_num=0;
@@ -618,7 +751,16 @@ int dtls1_accept(SSL *s)
if (s->hit)
s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
else
+ {
s->s3->tmp.next_state=SSL_ST_OK;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+ s->d1->next_state = s->s3->tmp.next_state;
+ s->s3->tmp.next_state=DTLS1_SCTP_ST_SW_WRITE_SOCK;
+ }
+#endif
+ }
s->init_num=0;
break;
@@ -636,11 +778,9 @@ int dtls1_accept(SSL *s)
s->init_num=0;
- if (s->new_session == 2) /* skipped if we just sent a HelloRequest */
+ if (s->renegotiate == 2) /* skipped if we just sent a HelloRequest */
{
- /* actually not necessarily a 'new' session unless
- * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
-
+ s->renegotiate=0;
s->new_session=0;
ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
@@ -692,6 +832,14 @@ end:
/* BIO_flush(s->wbio); */
s->in_handshake--;
+#ifndef OPENSSL_NO_SCTP
+ /* Notify SCTP BIO socket to leave handshake
+ * mode and prevent stream identifier other
+ * than 0. Will be ignored if no SCTP is used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
+#endif
+
if (cb != NULL)
cb(s,SSL_CB_ACCEPT_EXIT,ret);
return(ret);
@@ -772,7 +920,7 @@ int dtls1_send_server_hello(SSL *s)
p=s->s3->server_random;
Time=(unsigned long)time(NULL); /* Time */
l2n(Time,p);
- RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time));
+ RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
/* Do the message type and length last */
d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
@@ -1147,7 +1295,7 @@ int dtls1_send_server_key_exchange(SSL *s)
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
{
- if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
+ if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher, NULL))
== NULL)
{
al=SSL_AD_DECODE_ERROR;
diff --git a/deps/openssl/openssl/ssl/dtls1.h b/deps/openssl/openssl/ssl/dtls1.h
index 2900d1d8a..e65d50119 100644
--- a/deps/openssl/openssl/ssl/dtls1.h
+++ b/deps/openssl/openssl/ssl/dtls1.h
@@ -57,8 +57,8 @@
*
*/
-#ifndef HEADER_DTLS1_H
-#define HEADER_DTLS1_H
+#ifndef HEADER_DTLS1_H
+#define HEADER_DTLS1_H
#include <openssl/buffer.h>
#include <openssl/pqueue.h>
@@ -72,8 +72,12 @@
#elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_)
#include <sys/timeval.h>
#else
+#if defined(OPENSSL_SYS_VXWORKS)
+#include <sys/times.h>
+#else
#include <sys/time.h>
#endif
+#endif
#ifdef __cplusplus
extern "C" {
@@ -105,6 +109,11 @@ extern "C" {
#define DTLS1_AL_HEADER_LENGTH 2
#endif
+#ifndef OPENSSL_NO_SSL_INTERN
+
+#ifndef OPENSSL_NO_SCTP
+#define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP"
+#endif
typedef struct dtls1_bitmap_st
{
@@ -227,7 +236,7 @@ typedef struct dtls1_state_st
struct dtls1_timeout_st timeout;
- /* Indicates when the last handshake msg sent will timeout */
+ /* Indicates when the last handshake msg or heartbeat sent will timeout */
struct timeval next_timeout;
/* Timeout duration */
@@ -243,6 +252,13 @@ typedef struct dtls1_state_st
unsigned int retransmitting;
unsigned int change_cipher_spec_ok;
+#ifndef OPENSSL_NO_SCTP
+ /* used when SSL_ST_XX_FLUSH is entered */
+ int next_state;
+
+ int shutdown_received;
+#endif
+
} DTLS1_STATE;
typedef struct dtls1_record_data_st
@@ -251,8 +267,12 @@ typedef struct dtls1_record_data_st
unsigned int packet_length;
SSL3_BUFFER rbuf;
SSL3_RECORD rrec;
+#ifndef OPENSSL_NO_SCTP
+ struct bio_dgram_sctp_rcvinfo recordinfo;
+#endif
} DTLS1_RECORD_DATA;
+#endif
/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */
#define DTLS1_TMO_READ_COUNT 2
diff --git a/deps/openssl/openssl/ssl/install-ssl.com b/deps/openssl/openssl/ssl/install-ssl.com
index 1bd6ccaa7..afe6967f8 100644..100755
--- a/deps/openssl/openssl/ssl/install-ssl.com
+++ b/deps/openssl/openssl/ssl/install-ssl.com
@@ -73,7 +73,7 @@ $ if f$parse("wrk_sslxexe:") .eqs. "" then -
$ if f$parse("wrk_sslxlib:") .eqs. "" then -
create /directory /log wrk_sslxlib:
$!
-$ exheader := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h
+$ exheader := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h, srtp.h
$ e_exe := ssl_task
$ libs := ssl_libssl
$!
diff --git a/deps/openssl/openssl/ssl/kssl.c b/deps/openssl/openssl/ssl/kssl.c
index b820e3746..fd7c67bb1 100644
--- a/deps/openssl/openssl/ssl/kssl.c
+++ b/deps/openssl/openssl/ssl/kssl.c
@@ -2194,6 +2194,22 @@ krb5_error_code kssl_build_principal_2(
return ENOMEM;
}
+void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx)
+ {
+ s->kssl_ctx = kctx;
+ }
+
+KSSL_CTX * SSL_get0_kssl_ctx(SSL *s)
+ {
+ return s->kssl_ctx;
+ }
+
+char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx)
+ {
+ if (kctx)
+ return kctx->client_princ;
+ return NULL;
+ }
#else /* !OPENSSL_NO_KRB5 */
diff --git a/deps/openssl/openssl/ssl/kssl.h b/deps/openssl/openssl/ssl/kssl.h
index a3d20e1cc..8242fd5ee 100644
--- a/deps/openssl/openssl/ssl/kssl.h
+++ b/deps/openssl/openssl/ssl/kssl.h
@@ -172,6 +172,10 @@ krb5_error_code kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp,
krb5_timestamp *atimep, KSSL_ERR *kssl_err);
unsigned char *kssl_skip_confound(krb5_enctype enctype, unsigned char *authn);
+void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx);
+KSSL_CTX * SSL_get0_kssl_ctx(SSL *s);
+char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx);
+
#ifdef __cplusplus
}
#endif
diff --git a/deps/openssl/openssl/ssl/s23_clnt.c b/deps/openssl/openssl/ssl/s23_clnt.c
index f41fe3ab5..47673e740 100644
--- a/deps/openssl/openssl/ssl/s23_clnt.c
+++ b/deps/openssl/openssl/ssl/s23_clnt.c
@@ -129,6 +129,10 @@ static const SSL_METHOD *ssl23_get_client_method(int ver)
return(SSLv3_client_method());
else if (ver == TLS1_VERSION)
return(TLSv1_client_method());
+ else if (ver == TLS1_1_VERSION)
+ return(TLSv1_1_client_method());
+ else if (ver == TLS1_2_VERSION)
+ return(TLSv1_2_client_method());
else
return(NULL);
}
@@ -278,24 +282,51 @@ static int ssl23_client_hello(SSL *s)
SSL_COMP *comp;
#endif
int ret;
+ unsigned long mask, options = s->options;
- ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1;
+ ssl2_compat = (options & SSL_OP_NO_SSLv2) ? 0 : 1;
if (ssl2_compat && ssl23_no_ssl2_ciphers(s))
ssl2_compat = 0;
- if (!(s->options & SSL_OP_NO_TLSv1))
- {
+ /*
+ * SSL_OP_NO_X disables all protocols above X *if* there are
+ * some protocols below X enabled. This is required in order
+ * to maintain "version capability" vector contiguous. So
+ * that if application wants to disable TLS1.0 in favour of
+ * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the
+ * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2.
+ */
+ mask = SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1
+#if !defined(OPENSSL_NO_SSL3)
+ |SSL_OP_NO_SSLv3
+#endif
+#if !defined(OPENSSL_NO_SSL2)
+ |(ssl2_compat?SSL_OP_NO_SSLv2:0)
+#endif
+ ;
+#if !defined(OPENSSL_NO_TLS1_2_CLIENT)
+ version = TLS1_2_VERSION;
+
+ if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask)
+ version = TLS1_1_VERSION;
+#else
+ version = TLS1_1_VERSION;
+#endif
+ mask &= ~SSL_OP_NO_TLSv1_1;
+ if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask)
version = TLS1_VERSION;
- }
- else if (!(s->options & SSL_OP_NO_SSLv3))
- {
+ mask &= ~SSL_OP_NO_TLSv1;
+#if !defined(OPENSSL_NO_SSL3)
+ if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask)
version = SSL3_VERSION;
- }
- else if (!(s->options & SSL_OP_NO_SSLv2))
- {
+ mask &= ~SSL_OP_NO_SSLv3;
+#endif
+#if !defined(OPENSSL_NO_SSL2)
+ if ((options & SSL_OP_NO_SSLv3) && (options & mask) != mask)
version = SSL2_VERSION;
- }
+#endif
+
#ifndef OPENSSL_NO_TLSEXT
if (version != SSL2_VERSION)
{
@@ -329,11 +360,29 @@ static int ssl23_client_hello(SSL *s)
if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
return -1;
- if (version == TLS1_VERSION)
+ if (version == TLS1_2_VERSION)
+ {
+ version_major = TLS1_2_VERSION_MAJOR;
+ version_minor = TLS1_2_VERSION_MINOR;
+ }
+ else if (version == TLS1_1_VERSION)
+ {
+ version_major = TLS1_1_VERSION_MAJOR;
+ version_minor = TLS1_1_VERSION_MINOR;
+ }
+ else if (version == TLS1_VERSION)
{
version_major = TLS1_VERSION_MAJOR;
version_minor = TLS1_VERSION_MINOR;
}
+#ifdef OPENSSL_FIPS
+ else if(FIPS_mode())
+ {
+ SSLerr(SSL_F_SSL23_CLIENT_HELLO,
+ SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+ return -1;
+ }
+#endif
else if (version == SSL3_VERSION)
{
version_major = SSL3_VERSION_MAJOR;
@@ -437,6 +486,15 @@ static int ssl23_client_hello(SSL *s)
SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
return -1;
}
+#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
+ /* Some servers hang if client hello > 256 bytes
+ * as hack workaround chop number of supported ciphers
+ * to keep it well below this if we use TLS v1.2
+ */
+ if (TLS1_get_version(s) >= TLS1_2_VERSION
+ && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
+ i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
+#endif
s2n(i,p);
p+=i;
@@ -491,8 +549,13 @@ static int ssl23_client_hello(SSL *s)
d=buf;
*(d++) = SSL3_RT_HANDSHAKE;
*(d++) = version_major;
- *(d++) = version_minor; /* arguably we should send the *lowest* suported version here
- * (indicating, e.g., TLS 1.0 in "SSL 3.0 format") */
+ /* Some servers hang if we use long client hellos
+ * and a record number > TLS 1.0.
+ */
+ if (TLS1_get_client_version(s) > TLS1_VERSION)
+ *(d++) = 1;
+ else
+ *(d++) = version_minor;
s2n((int)l,d);
/* number of bytes to write */
@@ -608,7 +671,7 @@ static int ssl23_get_server_hello(SSL *s)
#endif
}
else if (p[1] == SSL3_VERSION_MAJOR &&
- (p[2] == SSL3_VERSION_MINOR || p[2] == TLS1_VERSION_MINOR) &&
+ p[2] <= TLS1_2_VERSION_MINOR &&
((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) ||
(p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2)))
{
@@ -617,6 +680,14 @@ static int ssl23_get_server_hello(SSL *s)
if ((p[2] == SSL3_VERSION_MINOR) &&
!(s->options & SSL_OP_NO_SSLv3))
{
+#ifdef OPENSSL_FIPS
+ if(FIPS_mode())
+ {
+ SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,
+ SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+ goto err;
+ }
+#endif
s->version=SSL3_VERSION;
s->method=SSLv3_client_method();
}
@@ -626,6 +697,18 @@ static int ssl23_get_server_hello(SSL *s)
s->version=TLS1_VERSION;
s->method=TLSv1_client_method();
}
+ else if ((p[2] == TLS1_1_VERSION_MINOR) &&
+ !(s->options & SSL_OP_NO_TLSv1_1))
+ {
+ s->version=TLS1_1_VERSION;
+ s->method=TLSv1_1_client_method();
+ }
+ else if ((p[2] == TLS1_2_VERSION_MINOR) &&
+ !(s->options & SSL_OP_NO_TLSv1_2))
+ {
+ s->version=TLS1_2_VERSION;
+ s->method=TLSv1_2_client_method();
+ }
else
{
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
@@ -687,13 +770,6 @@ static int ssl23_get_server_hello(SSL *s)
/* Since, if we are sending a ssl23 client hello, we are not
* reusing a session-id */
- if (!s->session_creation_enabled)
- {
- if (!(s->client_version == SSL2_VERSION))
- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
- SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
- goto err;
- }
if (!ssl_get_new_session(s,0))
goto err;
diff --git a/deps/openssl/openssl/ssl/s23_meth.c b/deps/openssl/openssl/ssl/s23_meth.c
index c6099efcf..40eae0f0b 100644
--- a/deps/openssl/openssl/ssl/s23_meth.c
+++ b/deps/openssl/openssl/ssl/s23_meth.c
@@ -76,6 +76,10 @@ static const SSL_METHOD *ssl23_get_method(int ver)
#ifndef OPENSSL_NO_TLS1
if (ver == TLS1_VERSION)
return(TLSv1_method());
+ else if (ver == TLS1_1_VERSION)
+ return(TLSv1_1_method());
+ else if (ver == TLS1_2_VERSION)
+ return(TLSv1_2_method());
else
#endif
return(NULL);
diff --git a/deps/openssl/openssl/ssl/s23_srvr.c b/deps/openssl/openssl/ssl/s23_srvr.c
index e22879c83..487784901 100644
--- a/deps/openssl/openssl/ssl/s23_srvr.c
+++ b/deps/openssl/openssl/ssl/s23_srvr.c
@@ -115,6 +115,9 @@
#include <openssl/rand.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
static const SSL_METHOD *ssl23_get_server_method(int ver);
int ssl23_get_client_hello(SSL *s);
@@ -128,6 +131,10 @@ static const SSL_METHOD *ssl23_get_server_method(int ver)
return(SSLv3_server_method());
else if (ver == TLS1_VERSION)
return(TLSv1_server_method());
+ else if (ver == TLS1_1_VERSION)
+ return(TLSv1_1_server_method());
+ else if (ver == TLS1_2_VERSION)
+ return(TLSv1_2_server_method());
else
return(NULL);
}
@@ -283,7 +290,20 @@ int ssl23_get_client_hello(SSL *s)
/* SSLv3/TLSv1 */
if (p[4] >= TLS1_VERSION_MINOR)
{
- if (!(s->options & SSL_OP_NO_TLSv1))
+ if (p[4] >= TLS1_2_VERSION_MINOR &&
+ !(s->options & SSL_OP_NO_TLSv1_2))
+ {
+ s->version=TLS1_2_VERSION;
+ s->state=SSL23_ST_SR_CLNT_HELLO_B;
+ }
+ else if (p[4] >= TLS1_1_VERSION_MINOR &&
+ !(s->options & SSL_OP_NO_TLSv1_1))
+ {
+ s->version=TLS1_1_VERSION;
+ /* type=2; */ /* done later to survive restarts */
+ s->state=SSL23_ST_SR_CLNT_HELLO_B;
+ }
+ else if (!(s->options & SSL_OP_NO_TLSv1))
{
s->version=TLS1_VERSION;
/* type=2; */ /* done later to survive restarts */
@@ -350,7 +370,19 @@ int ssl23_get_client_hello(SSL *s)
v[1]=p[10]; /* minor version according to client_version */
if (v[1] >= TLS1_VERSION_MINOR)
{
- if (!(s->options & SSL_OP_NO_TLSv1))
+ if (v[1] >= TLS1_2_VERSION_MINOR &&
+ !(s->options & SSL_OP_NO_TLSv1_2))
+ {
+ s->version=TLS1_2_VERSION;
+ type=3;
+ }
+ else if (v[1] >= TLS1_1_VERSION_MINOR &&
+ !(s->options & SSL_OP_NO_TLSv1_1))
+ {
+ s->version=TLS1_1_VERSION;
+ type=3;
+ }
+ else if (!(s->options & SSL_OP_NO_TLSv1))
{
s->version=TLS1_VERSION;
type=3;
@@ -393,6 +425,15 @@ int ssl23_get_client_hello(SSL *s)
}
}
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && (s->version < TLS1_VERSION))
+ {
+ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,
+ SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+ goto err;
+ }
+#endif
+
if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
{
/* we have SSLv3/TLSv1 in an SSLv2 header
@@ -403,13 +444,8 @@ int ssl23_get_client_hello(SSL *s)
v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
v[1] = p[4];
-/* The SSL2 protocol allows n to be larger, just pick
- * a reasonable buffer size. */
-#if SSL3_RT_DEFAULT_PACKET_SIZE < 1024*4 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
-#error "SSL3_RT_DEFAULT_PACKET_SIZE is too small."
-#endif
n=((p[0]&0x7f)<<8)|p[1];
- if (n > SSL3_RT_DEFAULT_PACKET_SIZE - 2)
+ if (n > (1024*4))
{
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
goto err;
@@ -572,8 +608,11 @@ int ssl23_get_client_hello(SSL *s)
s->s3->rbuf.left=0;
s->s3->rbuf.offset=0;
}
-
- if (s->version == TLS1_VERSION)
+ if (s->version == TLS1_2_VERSION)
+ s->method = TLSv1_2_server_method();
+ else if (s->version == TLS1_1_VERSION)
+ s->method = TLSv1_1_server_method();
+ else if (s->version == TLS1_VERSION)
s->method = TLSv1_server_method();
else
s->method = SSLv3_server_method();
diff --git a/deps/openssl/openssl/ssl/s2_clnt.c b/deps/openssl/openssl/ssl/s2_clnt.c
index 00ac158f9..03b6cf967 100644
--- a/deps/openssl/openssl/ssl/s2_clnt.c
+++ b/deps/openssl/openssl/ssl/s2_clnt.c
@@ -359,12 +359,14 @@ static int get_server_hello(SSL *s)
SSL_R_PEER_ERROR);
return(-1);
}
-#ifdef __APPLE_CC__
- /* The Rhapsody 5.5 (a.k.a. MacOS X) compiler bug
- * workaround. <appro@fy.chalmers.se> */
- s->hit=(i=*(p++))?1:0;
-#else
+#if 0
s->hit=(*(p++))?1:0;
+ /* Some [PPC?] compilers fail to increment p in above
+ statement, e.g. one provided with Rhapsody 5.5, but
+ most recent example XL C 11.1 for AIX, even without
+ optimization flag... */
+#else
+ s->hit=(*p)?1:0; p++;
#endif
s->s2->tmp.cert_type= *(p++);
n2s(p,i);
@@ -937,7 +939,7 @@ static int get_server_verify(SSL *s)
s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */
p += 1;
- if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
+ if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
{
ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT);
diff --git a/deps/openssl/openssl/ssl/s2_pkt.c b/deps/openssl/openssl/ssl/s2_pkt.c
index ac963b2d4..8bb6ab8ba 100644
--- a/deps/openssl/openssl/ssl/s2_pkt.c
+++ b/deps/openssl/openssl/ssl/s2_pkt.c
@@ -269,8 +269,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
s->s2->ract_data_length-=mac_size;
ssl2_mac(s,mac,0);
s->s2->ract_data_length-=s->s2->padding;
- if ( (memcmp(mac,s->s2->mac_data,
- (unsigned int)mac_size) != 0) ||
+ if ( (CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) ||
(s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
{
SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);
diff --git a/deps/openssl/openssl/ssl/s2_srvr.c b/deps/openssl/openssl/ssl/s2_srvr.c
index bc885e8e7..2cba426bb 100644
--- a/deps/openssl/openssl/ssl/s2_srvr.c
+++ b/deps/openssl/openssl/ssl/s2_srvr.c
@@ -1059,10 +1059,12 @@ static int request_certificate(SSL *s)
EVP_PKEY *pkey=NULL;
EVP_MD_CTX_init(&ctx);
- EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL);
- EVP_VerifyUpdate(&ctx,s->s2->key_material,
- s->s2->key_material_length);
- EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
+ if (!EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL)
+ || !EVP_VerifyUpdate(&ctx,s->s2->key_material,
+ s->s2->key_material_length)
+ || !EVP_VerifyUpdate(&ctx,ccd,
+ SSL2_MIN_CERT_CHALLENGE_LENGTH))
+ goto msg_end;
i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
buf2=OPENSSL_malloc((unsigned int)i);
@@ -1073,7 +1075,11 @@ static int request_certificate(SSL *s)
}
p2=buf2;
i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
- EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
+ if (!EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i))
+ {
+ OPENSSL_free(buf2);
+ goto msg_end;
+ }
OPENSSL_free(buf2);
pkey=X509_get_pubkey(x509);
diff --git a/deps/openssl/openssl/ssl/s3_both.c b/deps/openssl/openssl/ssl/s3_both.c
index 508e39021..ead01c82a 100644
--- a/deps/openssl/openssl/ssl/s3_both.c
+++ b/deps/openssl/openssl/ssl/s3_both.c
@@ -233,7 +233,7 @@ int ssl3_get_finished(SSL *s, int a, int b)
#ifdef OPENSSL_NO_NEXTPROTONEG
/* the mac has already been generated when we received the
- * change cipher spec message and is in s->s3->tmp.peer_finish_md
+ * change cipher spec message and is in s->s3->tmp.peer_finish_md.
*/
#endif
@@ -265,7 +265,7 @@ int ssl3_get_finished(SSL *s, int a, int b)
goto f_err;
}
- if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
+ if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
{
al=SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
@@ -347,11 +347,8 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
unsigned long l=7;
BUF_MEM *buf;
int no_chain;
- STACK_OF(X509) *cert_chain;
- cert_chain = SSL_get_certificate_chain(s, x);
-
- if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain)
+ if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
no_chain = 1;
else
no_chain = 0;
@@ -403,10 +400,6 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
return(0);
}
- for (i=0; i<sk_X509_num(cert_chain); i++)
- if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i)))
- return(0);
-
l-=7;
p=(unsigned char *)&(buf->data[4]);
l2n3(l,p);
@@ -756,20 +749,13 @@ int ssl3_setup_read_buffer(SSL *s)
if (s->s3->rbuf.buf == NULL)
{
- if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
- {
- len = SSL3_RT_DEFAULT_PACKET_SIZE;
- }
- else
+ len = SSL3_RT_MAX_PLAIN_LENGTH
+ + SSL3_RT_MAX_ENCRYPTED_OVERHEAD
+ + headerlen + align;
+ if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
{
- len = SSL3_RT_MAX_PLAIN_LENGTH
- + SSL3_RT_MAX_ENCRYPTED_OVERHEAD
- + headerlen + align;
- if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
- {
- s->s3->init_extra = 1;
- len += SSL3_RT_MAX_EXTRA;
- }
+ s->s3->init_extra = 1;
+ len += SSL3_RT_MAX_EXTRA;
}
#ifndef OPENSSL_NO_COMP
if (!(s->options & SSL_OP_NO_COMPRESSION))
@@ -805,15 +791,7 @@ int ssl3_setup_write_buffer(SSL *s)
if (s->s3->wbuf.buf == NULL)
{
- if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
- {
- len = SSL3_RT_DEFAULT_PACKET_SIZE;
- }
- else
- {
- len = s->max_send_fragment;
- }
- len += 0
+ len = s->max_send_fragment
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
+ headerlen + align;
#ifndef OPENSSL_NO_COMP
@@ -823,6 +801,7 @@ int ssl3_setup_write_buffer(SSL *s)
if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
len += headerlen + align
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+
if ((p=freelist_extract(s->ctx, 0, len)) == NULL)
goto err;
s->s3->wbuf.buf = p;
@@ -865,3 +844,4 @@ int ssl3_release_read_buffer(SSL *s)
}
return 1;
}
+
diff --git a/deps/openssl/openssl/ssl/s3_cbc.c b/deps/openssl/openssl/ssl/s3_cbc.c
new file mode 100644
index 000000000..02edf3f91
--- /dev/null
+++ b/deps/openssl/openssl/ssl/s3_cbc.c
@@ -0,0 +1,790 @@
+/* ssl/s3_cbc.c */
+/* ====================================================================
+ * Copyright (c) 2012 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).
+ *
+ */
+
+#include "ssl_locl.h"
+
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+
+/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
+ * field. (SHA-384/512 have 128-bit length.) */
+#define MAX_HASH_BIT_COUNT_BYTES 16
+
+/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support.
+ * Currently SHA-384/512 has a 128-byte block size and that's the largest
+ * supported by TLS.) */
+#define MAX_HASH_BLOCK_SIZE 128
+
+/* Some utility functions are needed:
+ *
+ * These macros return the given value with the MSB copied to all the other
+ * bits. They use the fact that arithmetic shift shifts-in the sign bit.
+ * However, this is not ensured by the C standard so you may need to replace
+ * them with something else on odd CPUs. */
+#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
+#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
+
+/* constant_time_lt returns 0xff if a<b and 0x00 otherwise. */
+static unsigned constant_time_lt(unsigned a, unsigned b)
+ {
+ a -= b;
+ return DUPLICATE_MSB_TO_ALL(a);
+ }
+
+/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
+static unsigned constant_time_ge(unsigned a, unsigned b)
+ {
+ a -= b;
+ return DUPLICATE_MSB_TO_ALL(~a);
+ }
+
+/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
+static unsigned char constant_time_eq_8(unsigned a, unsigned b)
+ {
+ unsigned c = a ^ b;
+ c--;
+ return DUPLICATE_MSB_TO_ALL_8(c);
+ }
+
+/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
+ * record in |rec| by updating |rec->length| in constant time.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ * 0: (in non-constant time) if the record is publicly invalid.
+ * 1: if the padding was valid
+ * -1: otherwise. */
+int ssl3_cbc_remove_padding(const SSL* s,
+ SSL3_RECORD *rec,
+ unsigned block_size,
+ unsigned mac_size)
+ {
+ unsigned padding_length, good;
+ const unsigned overhead = 1 /* padding length byte */ + mac_size;
+
+ /* These lengths are all public so we can test them in non-constant
+ * time. */
+ if (overhead > rec->length)
+ return 0;
+
+ padding_length = rec->data[rec->length-1];
+ good = constant_time_ge(rec->length, padding_length+overhead);
+ /* SSLv3 requires that the padding is minimal. */
+ good &= constant_time_ge(block_size, padding_length+1);
+ padding_length = good & (padding_length+1);
+ rec->length -= padding_length;
+ rec->type |= padding_length<<8; /* kludge: pass padding length */
+ return (int)((good & 1) | (~good & -1));
+}
+
+/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
+ * record in |rec| in constant time and returns 1 if the padding is valid and
+ * -1 otherwise. It also removes any explicit IV from the start of the record
+ * without leaking any timing about whether there was enough space after the
+ * padding was removed.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ * 0: (in non-constant time) if the record is publicly invalid.
+ * 1: if the padding was valid
+ * -1: otherwise. */
+int tls1_cbc_remove_padding(const SSL* s,
+ SSL3_RECORD *rec,
+ unsigned block_size,
+ unsigned mac_size)
+ {
+ unsigned padding_length, good, to_check, i;
+ const unsigned overhead = 1 /* padding length byte */ + mac_size;
+ /* Check if version requires explicit IV */
+ if (s->version >= TLS1_1_VERSION || s->version == DTLS1_VERSION)
+ {
+ /* These lengths are all public so we can test them in
+ * non-constant time.
+ */
+ if (overhead + block_size > rec->length)
+ return 0;
+ /* We can now safely skip explicit IV */
+ rec->data += block_size;
+ rec->input += block_size;
+ rec->length -= block_size;
+ }
+ else if (overhead > rec->length)
+ return 0;
+
+ padding_length = rec->data[rec->length-1];
+
+ /* NB: if compression is in operation the first packet may not be of
+ * even length so the padding bug check cannot be performed. This bug
+ * workaround has been around since SSLeay so hopefully it is either
+ * fixed now or no buggy implementation supports compression [steve]
+ */
+ if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand)
+ {
+ /* First packet is even in size, so check */
+ if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) &&
+ !(padding_length & 1))
+ {
+ s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
+ }
+ if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) &&
+ padding_length > 0)
+ {
+ padding_length--;
+ }
+ }
+
+ if (EVP_CIPHER_flags(s->enc_read_ctx->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER)
+ {
+ /* padding is already verified */
+ rec->length -= padding_length + 1;
+ return 1;
+ }
+
+ good = constant_time_ge(rec->length, overhead+padding_length);
+ /* The padding consists of a length byte at the end of the record and
+ * then that many bytes of padding, all with the same value as the
+ * length byte. Thus, with the length byte included, there are i+1
+ * bytes of padding.
+ *
+ * We can't check just |padding_length+1| bytes because that leaks
+ * decrypted information. Therefore we always have to check the maximum
+ * amount of padding possible. (Again, the length of the record is
+ * public information so we can use it.) */
+ to_check = 255; /* maximum amount of padding. */
+ if (to_check > rec->length-1)
+ to_check = rec->length-1;
+
+ for (i = 0; i < to_check; i++)
+ {
+ unsigned char mask = constant_time_ge(padding_length, i);
+ unsigned char b = rec->data[rec->length-1-i];
+ /* The final |padding_length+1| bytes should all have the value
+ * |padding_length|. Therefore the XOR should be zero. */
+ good &= ~(mask&(padding_length ^ b));
+ }
+
+ /* If any of the final |padding_length+1| bytes had the wrong value,
+ * one or more of the lower eight bits of |good| will be cleared. We
+ * AND the bottom 8 bits together and duplicate the result to all the
+ * bits. */
+ good &= good >> 4;
+ good &= good >> 2;
+ good &= good >> 1;
+ good <<= sizeof(good)*8-1;
+ good = DUPLICATE_MSB_TO_ALL(good);
+
+ padding_length = good & (padding_length+1);
+ rec->length -= padding_length;
+ rec->type |= padding_length<<8; /* kludge: pass padding length */
+
+ return (int)((good & 1) | (~good & -1));
+ }
+
+/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
+ * constant time (independent of the concrete value of rec->length, which may
+ * vary within a 256-byte window).
+ *
+ * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to
+ * this function.
+ *
+ * On entry:
+ * rec->orig_len >= md_size
+ * md_size <= EVP_MAX_MD_SIZE
+ *
+ * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with
+ * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into
+ * a single or pair of cache-lines, then the variable memory accesses don't
+ * actually affect the timing. CPUs with smaller cache-lines [if any] are
+ * not multi-core and are not considered vulnerable to cache-timing attacks.
+ */
+#define CBC_MAC_ROTATE_IN_PLACE
+
+void ssl3_cbc_copy_mac(unsigned char* out,
+ const SSL3_RECORD *rec,
+ unsigned md_size,unsigned orig_len)
+ {
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+ unsigned char rotated_mac_buf[64+EVP_MAX_MD_SIZE];
+ unsigned char *rotated_mac;
+#else
+ unsigned char rotated_mac[EVP_MAX_MD_SIZE];
+#endif
+
+ /* mac_end is the index of |rec->data| just after the end of the MAC. */
+ unsigned mac_end = rec->length;
+ unsigned mac_start = mac_end - md_size;
+ /* scan_start contains the number of bytes that we can ignore because
+ * the MAC's position can only vary by 255 bytes. */
+ unsigned scan_start = 0;
+ unsigned i, j;
+ unsigned div_spoiler;
+ unsigned rotate_offset;
+
+ OPENSSL_assert(orig_len >= md_size);
+ OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
+
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+ rotated_mac = rotated_mac_buf + ((0-(size_t)rotated_mac_buf)&63);
+#endif
+
+ /* This information is public so it's safe to branch based on it. */
+ if (orig_len > md_size + 255 + 1)
+ scan_start = orig_len - (md_size + 255 + 1);
+ /* div_spoiler contains a multiple of md_size that is used to cause the
+ * modulo operation to be constant time. Without this, the time varies
+ * based on the amount of padding when running on Intel chips at least.
+ *
+ * The aim of right-shifting md_size is so that the compiler doesn't
+ * figure out that it can remove div_spoiler as that would require it
+ * to prove that md_size is always even, which I hope is beyond it. */
+ div_spoiler = md_size >> 1;
+ div_spoiler <<= (sizeof(div_spoiler)-1)*8;
+ rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
+
+ memset(rotated_mac, 0, md_size);
+ for (i = scan_start, j = 0; i < orig_len; i++)
+ {
+ unsigned char mac_started = constant_time_ge(i, mac_start);
+ unsigned char mac_ended = constant_time_ge(i, mac_end);
+ unsigned char b = rec->data[i];
+ rotated_mac[j++] |= b & mac_started & ~mac_ended;
+ j &= constant_time_lt(j,md_size);
+ }
+
+ /* Now rotate the MAC */
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+ j = 0;
+ for (i = 0; i < md_size; i++)
+ {
+ /* in case cache-line is 32 bytes, touch second line */
+ ((volatile unsigned char *)rotated_mac)[rotate_offset^32];
+ out[j++] = rotated_mac[rotate_offset++];
+ rotate_offset &= constant_time_lt(rotate_offset,md_size);
+ }
+#else
+ memset(out, 0, md_size);
+ rotate_offset = md_size - rotate_offset;
+ rotate_offset &= constant_time_lt(rotate_offset,md_size);
+ for (i = 0; i < md_size; i++)
+ {
+ for (j = 0; j < md_size; j++)
+ out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
+ rotate_offset++;
+ rotate_offset &= constant_time_lt(rotate_offset,md_size);
+ }
+#endif
+ }
+
+/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
+ * little-endian order. The value of p is advanced by four. */
+#define u32toLE(n, p) \
+ (*((p)++)=(unsigned char)(n), \
+ *((p)++)=(unsigned char)(n>>8), \
+ *((p)++)=(unsigned char)(n>>16), \
+ *((p)++)=(unsigned char)(n>>24))
+
+/* These functions serialize the state of a hash and thus perform the standard
+ * "final" operation without adding the padding and length that such a function
+ * typically does. */
+static void tls1_md5_final_raw(void* ctx, unsigned char *md_out)
+ {
+ MD5_CTX *md5 = ctx;
+ u32toLE(md5->A, md_out);
+ u32toLE(md5->B, md_out);
+ u32toLE(md5->C, md_out);
+ u32toLE(md5->D, md_out);
+ }
+
+static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out)
+ {
+ SHA_CTX *sha1 = ctx;
+ l2n(sha1->h0, md_out);
+ l2n(sha1->h1, md_out);
+ l2n(sha1->h2, md_out);
+ l2n(sha1->h3, md_out);
+ l2n(sha1->h4, md_out);
+ }
+#define LARGEST_DIGEST_CTX SHA_CTX
+
+#ifndef OPENSSL_NO_SHA256
+static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out)
+ {
+ SHA256_CTX *sha256 = ctx;
+ unsigned i;
+
+ for (i = 0; i < 8; i++)
+ {
+ l2n(sha256->h[i], md_out);
+ }
+ }
+#undef LARGEST_DIGEST_CTX
+#define LARGEST_DIGEST_CTX SHA256_CTX
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out)
+ {
+ SHA512_CTX *sha512 = ctx;
+ unsigned i;
+
+ for (i = 0; i < 8; i++)
+ {
+ l2n8(sha512->h[i], md_out);
+ }
+ }
+#undef LARGEST_DIGEST_CTX
+#define LARGEST_DIGEST_CTX SHA512_CTX
+#endif
+
+/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
+ * which ssl3_cbc_digest_record supports. */
+char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return 0;
+#endif
+ switch (EVP_MD_CTX_type(ctx))
+ {
+ case NID_md5:
+ case NID_sha1:
+#ifndef OPENSSL_NO_SHA256
+ case NID_sha224:
+ case NID_sha256:
+#endif
+#ifndef OPENSSL_NO_SHA512
+ case NID_sha384:
+ case NID_sha512:
+#endif
+ return 1;
+ default:
+ return 0;
+ }
+ }
+
+/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS
+ * record.
+ *
+ * ctx: the EVP_MD_CTX from which we take the hash function.
+ * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX.
+ * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written.
+ * md_out_size: if non-NULL, the number of output bytes is written here.
+ * header: the 13-byte, TLS record header.
+ * data: the record data itself, less any preceeding explicit IV.
+ * data_plus_mac_size: the secret, reported length of the data and MAC
+ * once the padding has been removed.
+ * data_plus_mac_plus_padding_size: the public length of the whole
+ * record, including padding.
+ * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS.
+ *
+ * On entry: by virtue of having been through one of the remove_padding
+ * functions, above, we know that data_plus_mac_size is large enough to contain
+ * a padding byte and MAC. (If the padding was invalid, it might contain the
+ * padding too. ) */
+void ssl3_cbc_digest_record(
+ const EVP_MD_CTX *ctx,
+ unsigned char* md_out,
+ size_t* md_out_size,
+ const unsigned char header[13],
+ const unsigned char *data,
+ size_t data_plus_mac_size,
+ size_t data_plus_mac_plus_padding_size,
+ const unsigned char *mac_secret,
+ unsigned mac_secret_length,
+ char is_sslv3)
+ {
+ union { double align;
+ unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state;
+ void (*md_final_raw)(void *ctx, unsigned char *md_out);
+ void (*md_transform)(void *ctx, const unsigned char *block);
+ unsigned md_size, md_block_size = 64;
+ unsigned sslv3_pad_length = 40, header_length, variance_blocks,
+ len, max_mac_bytes, num_blocks,
+ num_starting_blocks, k, mac_end_offset, c, index_a, index_b;
+ unsigned int bits; /* at most 18 bits */
+ unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
+ /* hmac_pad is the masked HMAC key. */
+ unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
+ unsigned char first_block[MAX_HASH_BLOCK_SIZE];
+ unsigned char mac_out[EVP_MAX_MD_SIZE];
+ unsigned i, j, md_out_size_u;
+ EVP_MD_CTX md_ctx;
+ /* mdLengthSize is the number of bytes in the length field that terminates
+ * the hash. */
+ unsigned md_length_size = 8;
+ char length_is_big_endian = 1;
+
+ /* This is a, hopefully redundant, check that allows us to forget about
+ * many possible overflows later in this function. */
+ OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024);
+
+ switch (EVP_MD_CTX_type(ctx))
+ {
+ case NID_md5:
+ MD5_Init((MD5_CTX*)md_state.c);
+ md_final_raw = tls1_md5_final_raw;
+ md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform;
+ md_size = 16;
+ sslv3_pad_length = 48;
+ length_is_big_endian = 0;
+ break;
+ case NID_sha1:
+ SHA1_Init((SHA_CTX*)md_state.c);
+ md_final_raw = tls1_sha1_final_raw;
+ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform;
+ md_size = 20;
+ break;
+#ifndef OPENSSL_NO_SHA256
+ case NID_sha224:
+ SHA224_Init((SHA256_CTX*)md_state.c);
+ md_final_raw = tls1_sha256_final_raw;
+ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
+ md_size = 224/8;
+ break;
+ case NID_sha256:
+ SHA256_Init((SHA256_CTX*)md_state.c);
+ md_final_raw = tls1_sha256_final_raw;
+ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
+ md_size = 32;
+ break;
+#endif
+#ifndef OPENSSL_NO_SHA512
+ case NID_sha384:
+ SHA384_Init((SHA512_CTX*)md_state.c);
+ md_final_raw = tls1_sha512_final_raw;
+ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
+ md_size = 384/8;
+ md_block_size = 128;
+ md_length_size = 16;
+ break;
+ case NID_sha512:
+ SHA512_Init((SHA512_CTX*)md_state.c);
+ md_final_raw = tls1_sha512_final_raw;
+ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
+ md_size = 64;
+ md_block_size = 128;
+ md_length_size = 16;
+ break;
+#endif
+ default:
+ /* ssl3_cbc_record_digest_supported should have been
+ * called first to check that the hash function is
+ * supported. */
+ OPENSSL_assert(0);
+ if (md_out_size)
+ *md_out_size = -1;
+ return;
+ }
+
+ OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
+ OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
+ OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
+
+ header_length = 13;
+ if (is_sslv3)
+ {
+ header_length =
+ mac_secret_length +
+ sslv3_pad_length +
+ 8 /* sequence number */ +
+ 1 /* record type */ +
+ 2 /* record length */;
+ }
+
+ /* variance_blocks is the number of blocks of the hash that we have to
+ * calculate in constant time because they could be altered by the
+ * padding value.
+ *
+ * In SSLv3, the padding must be minimal so the end of the plaintext
+ * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that
+ * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash
+ * termination (0x80 + 64-bit length) don't fit in the final block, we
+ * say that the final two blocks can vary based on the padding.
+ *
+ * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
+ * required to be minimal. Therefore we say that the final six blocks
+ * can vary based on the padding.
+ *
+ * Later in the function, if the message is short and there obviously
+ * cannot be this many blocks then variance_blocks can be reduced. */
+ variance_blocks = is_sslv3 ? 2 : 6;
+ /* From now on we're dealing with the MAC, which conceptually has 13
+ * bytes of `header' before the start of the data (TLS) or 71/75 bytes
+ * (SSLv3) */
+ len = data_plus_mac_plus_padding_size + header_length;
+ /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including
+ * |header|, assuming that there's no padding. */
+ max_mac_bytes = len - md_size - 1;
+ /* num_blocks is the maximum number of hash blocks. */
+ num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size;
+ /* In order to calculate the MAC in constant time we have to handle
+ * the final blocks specially because the padding value could cause the
+ * end to appear somewhere in the final |variance_blocks| blocks and we
+ * can't leak where. However, |num_starting_blocks| worth of data can
+ * be hashed right away because no padding value can affect whether
+ * they are plaintext. */
+ num_starting_blocks = 0;
+ /* k is the starting byte offset into the conceptual header||data where
+ * we start processing. */
+ k = 0;
+ /* mac_end_offset is the index just past the end of the data to be
+ * MACed. */
+ mac_end_offset = data_plus_mac_size + header_length - md_size;
+ /* c is the index of the 0x80 byte in the final hash block that
+ * contains application data. */
+ c = mac_end_offset % md_block_size;
+ /* index_a is the hash block number that contains the 0x80 terminating
+ * value. */
+ index_a = mac_end_offset / md_block_size;
+ /* index_b is the hash block number that contains the 64-bit hash
+ * length, in bits. */
+ index_b = (mac_end_offset + md_length_size) / md_block_size;
+ /* bits is the hash-length in bits. It includes the additional hash
+ * block for the masked HMAC key, or whole of |header| in the case of
+ * SSLv3. */
+
+ /* For SSLv3, if we're going to have any starting blocks then we need
+ * at least two because the header is larger than a single block. */
+ if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0))
+ {
+ num_starting_blocks = num_blocks - variance_blocks;
+ k = md_block_size*num_starting_blocks;
+ }
+
+ bits = 8*mac_end_offset;
+ if (!is_sslv3)
+ {
+ /* Compute the initial HMAC block. For SSLv3, the padding and
+ * secret bytes are included in |header| because they take more
+ * than a single block. */
+ bits += 8*md_block_size;
+ memset(hmac_pad, 0, md_block_size);
+ OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad));
+ memcpy(hmac_pad, mac_secret, mac_secret_length);
+ for (i = 0; i < md_block_size; i++)
+ hmac_pad[i] ^= 0x36;
+
+ md_transform(md_state.c, hmac_pad);
+ }
+
+ if (length_is_big_endian)
+ {
+ memset(length_bytes,0,md_length_size-4);
+ length_bytes[md_length_size-4] = (unsigned char)(bits>>24);
+ length_bytes[md_length_size-3] = (unsigned char)(bits>>16);
+ length_bytes[md_length_size-2] = (unsigned char)(bits>>8);
+ length_bytes[md_length_size-1] = (unsigned char)bits;
+ }
+ else
+ {
+ memset(length_bytes,0,md_length_size);
+ length_bytes[md_length_size-5] = (unsigned char)(bits>>24);
+ length_bytes[md_length_size-6] = (unsigned char)(bits>>16);
+ length_bytes[md_length_size-7] = (unsigned char)(bits>>8);
+ length_bytes[md_length_size-8] = (unsigned char)bits;
+ }
+
+ if (k > 0)
+ {
+ if (is_sslv3)
+ {
+ /* The SSLv3 header is larger than a single block.
+ * overhang is the number of bytes beyond a single
+ * block that the header consumes: either 7 bytes
+ * (SHA1) or 11 bytes (MD5). */
+ unsigned overhang = header_length-md_block_size;
+ md_transform(md_state.c, header);
+ memcpy(first_block, header + md_block_size, overhang);
+ memcpy(first_block + overhang, data, md_block_size-overhang);
+ md_transform(md_state.c, first_block);
+ for (i = 1; i < k/md_block_size - 1; i++)
+ md_transform(md_state.c, data + md_block_size*i - overhang);
+ }
+ else
+ {
+ /* k is a multiple of md_block_size. */
+ memcpy(first_block, header, 13);
+ memcpy(first_block+13, data, md_block_size-13);
+ md_transform(md_state.c, first_block);
+ for (i = 1; i < k/md_block_size; i++)
+ md_transform(md_state.c, data + md_block_size*i - 13);
+ }
+ }
+
+ memset(mac_out, 0, sizeof(mac_out));
+
+ /* We now process the final hash blocks. For each block, we construct
+ * it in constant time. If the |i==index_a| then we'll include the 0x80
+ * bytes and zero pad etc. For each block we selectively copy it, in
+ * constant time, to |mac_out|. */
+ for (i = num_starting_blocks; i <= num_starting_blocks+variance_blocks; i++)
+ {
+ unsigned char block[MAX_HASH_BLOCK_SIZE];
+ unsigned char is_block_a = constant_time_eq_8(i, index_a);
+ unsigned char is_block_b = constant_time_eq_8(i, index_b);
+ for (j = 0; j < md_block_size; j++)
+ {
+ unsigned char b = 0, is_past_c, is_past_cp1;
+ if (k < header_length)
+ b = header[k];
+ else if (k < data_plus_mac_plus_padding_size + header_length)
+ b = data[k-header_length];
+ k++;
+
+ is_past_c = is_block_a & constant_time_ge(j, c);
+ is_past_cp1 = is_block_a & constant_time_ge(j, c+1);
+ /* If this is the block containing the end of the
+ * application data, and we are at the offset for the
+ * 0x80 value, then overwrite b with 0x80. */
+ b = (b&~is_past_c) | (0x80&is_past_c);
+ /* If this the the block containing the end of the
+ * application data and we're past the 0x80 value then
+ * just write zero. */
+ b = b&~is_past_cp1;
+ /* If this is index_b (the final block), but not
+ * index_a (the end of the data), then the 64-bit
+ * length didn't fit into index_a and we're having to
+ * add an extra block of zeros. */
+ b &= ~is_block_b | is_block_a;
+
+ /* The final bytes of one of the blocks contains the
+ * length. */
+ if (j >= md_block_size - md_length_size)
+ {
+ /* If this is index_b, write a length byte. */
+ b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]);
+ }
+ block[j] = b;
+ }
+
+ md_transform(md_state.c, block);
+ md_final_raw(md_state.c, block);
+ /* If this is index_b, copy the hash value to |mac_out|. */
+ for (j = 0; j < md_size; j++)
+ mac_out[j] |= block[j]&is_block_b;
+ }
+
+ EVP_MD_CTX_init(&md_ctx);
+ EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */);
+ if (is_sslv3)
+ {
+ /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
+ memset(hmac_pad, 0x5c, sslv3_pad_length);
+
+ EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length);
+ EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length);
+ EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+ }
+ else
+ {
+ /* Complete the HMAC in the standard manner. */
+ for (i = 0; i < md_block_size; i++)
+ hmac_pad[i] ^= 0x6a;
+
+ EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
+ EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+ }
+ EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
+ if (md_out_size)
+ *md_out_size = md_out_size_u;
+ EVP_MD_CTX_cleanup(&md_ctx);
+ }
+
+#ifdef OPENSSL_FIPS
+
+/* Due to the need to use EVP in FIPS mode we can't reimplement digests but
+ * we can ensure the number of blocks processed is equal for all cases
+ * by digesting additional data.
+ */
+
+void tls_fips_digest_extra(
+ const EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *mac_ctx,
+ const unsigned char *data, size_t data_len, size_t orig_len)
+ {
+ size_t block_size, digest_pad, blocks_data, blocks_orig;
+ if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE)
+ return;
+ block_size = EVP_MD_CTX_block_size(mac_ctx);
+ /* We are in FIPS mode if we get this far so we know we have only SHA*
+ * digests and TLS to deal with.
+ * Minimum digest padding length is 17 for SHA384/SHA512 and 9
+ * otherwise.
+ * Additional header is 13 bytes. To get the number of digest blocks
+ * processed round up the amount of data plus padding to the nearest
+ * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise.
+ * So we have:
+ * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size
+ * equivalently:
+ * blocks = (payload_len + digest_pad + 12)/block_size + 1
+ * HMAC adds a constant overhead.
+ * We're ultimately only interested in differences so this becomes
+ * blocks = (payload_len + 29)/128
+ * for SHA384/SHA512 and
+ * blocks = (payload_len + 21)/64
+ * otherwise.
+ */
+ digest_pad = block_size == 64 ? 21 : 29;
+ blocks_orig = (orig_len + digest_pad)/block_size;
+ blocks_data = (data_len + digest_pad)/block_size;
+ /* MAC enough blocks to make up the difference between the original
+ * and actual lengths plus one extra block to ensure this is never a
+ * no op. The "data" pointer should always have enough space to
+ * perform this operation as it is large enough for a maximum
+ * length TLS buffer.
+ */
+ EVP_DigestSignUpdate(mac_ctx, data,
+ (blocks_orig - blocks_data + 1) * block_size);
+ }
+#endif
diff --git a/deps/openssl/openssl/ssl/s3_clnt.c b/deps/openssl/openssl/ssl/s3_clnt.c
index 04d6e5bb7..344e2eb1a 100644
--- a/deps/openssl/openssl/ssl/s3_clnt.c
+++ b/deps/openssl/openssl/ssl/s3_clnt.c
@@ -156,6 +156,9 @@
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/md5.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
#endif
@@ -199,16 +202,16 @@ int ssl3_connect(SSL *s)
s->in_handshake++;
if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
-#if 0 /* Send app data in separate packet, otherwise, some particular site
- * (only one site so far) closes the socket.
- * Note: there is a very small chance that two TCP packets
- * could be arriving at server combined into a single TCP packet,
- * then trigger that site to break. We haven't encounter that though.
+
+#ifndef OPENSSL_NO_HEARTBEATS
+ /* If we're awaiting a HeartbeatResponse, pretend we
+ * already got and don't await it anymore, because
+ * Heartbeats don't make sense during handshakes anyway.
*/
- if (SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
+ if (s->tlsext_hb_pending)
{
- /* Send app data along with CCS/Finished */
- s->s3->flags |= SSL3_FLAGS_DELAY_CLIENT_FINISHED;
+ s->tlsext_hb_pending = 0;
+ s->tlsext_hb_seq++;
}
#endif
@@ -219,7 +222,7 @@ int ssl3_connect(SSL *s)
switch(s->state)
{
case SSL_ST_RENEGOTIATE:
- s->new_session=1;
+ s->renegotiate=1;
s->state=SSL_ST_CONNECT;
s->ctx->stats.sess_connect_renegotiate++;
/* break */
@@ -292,7 +295,16 @@ int ssl3_connect(SSL *s)
if (ret <= 0) goto end;
if (s->hit)
+ {
s->state=SSL3_ST_CR_FINISHED_A;
+#ifndef OPENSSL_NO_TLSEXT
+ if (s->tlsext_ticket_expected)
+ {
+ /* receive renewed session ticket */
+ s->state=SSL3_ST_CR_SESSION_TICKET_A;
+ }
+#endif
+ }
else
s->state=SSL3_ST_CR_CERT_A;
s->init_num=0;
@@ -370,6 +382,17 @@ int ssl3_connect(SSL *s)
case SSL3_ST_CR_SRVR_DONE_B:
ret=ssl3_get_server_done(s);
if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_SRP
+ if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP)
+ {
+ if ((ret = SRP_Calc_A_param(s))<=0)
+ {
+ SSLerr(SSL_F_SSL3_CONNECT,SSL_R_SRP_A_CALC);
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
+ goto end;
+ }
+ }
+#endif
if (s->s3->tmp.cert_req)
s->state=SSL3_ST_CW_CERT_A;
else
@@ -439,12 +462,11 @@ int ssl3_connect(SSL *s)
#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
s->state=SSL3_ST_CW_FINISHED_A;
#else
- if (s->next_proto_negotiated)
+ if (s->s3->next_proto_neg_seen)
s->state=SSL3_ST_CW_NEXT_PROTO_A;
else
s->state=SSL3_ST_CW_FINISHED_A;
#endif
-
s->init_num=0;
s->session->cipher=s->s3->tmp.new_cipher;
@@ -504,31 +526,14 @@ int ssl3_connect(SSL *s)
}
else
{
- if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && SSL_get_cipher_bits(s, NULL) >= 128
- && s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */
- )
- {
- if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
- {
- s->state=SSL3_ST_CUTTHROUGH_COMPLETE;
- s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
- s->s3->delay_buf_pop_ret=0;
- }
- else
- {
- s->s3->tmp.next_state=SSL3_ST_CUTTHROUGH_COMPLETE;
- }
- }
- else
- {
#ifndef OPENSSL_NO_TLSEXT
- /* Allow NewSessionTicket if ticket expected */
- if (s->tlsext_ticket_expected)
- s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
- else
+ /* Allow NewSessionTicket if ticket expected */
+ if (s->tlsext_ticket_expected)
+ s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
+ else
#endif
- s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
- }
+
+ s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
}
s->init_num=0;
break;
@@ -576,24 +581,6 @@ int ssl3_connect(SSL *s)
s->state=s->s3->tmp.next_state;
break;
- case SSL3_ST_CUTTHROUGH_COMPLETE:
-#ifndef OPENSSL_NO_TLSEXT
- /* Allow NewSessionTicket if ticket expected */
- if (s->tlsext_ticket_expected)
- s->state=SSL3_ST_CR_SESSION_TICKET_A;
- else
-#endif
- s->state=SSL3_ST_CR_FINISHED_A;
-
- /* SSL_write() will take care of flushing buffered data if
- * DELAY_CLIENT_FINISHED is set.
- */
- if (!(s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED))
- ssl_free_wbio_buffer(s);
- ret = 1;
- goto end;
- /* break; */
-
case SSL_ST_OK:
/* clean a few things up */
ssl3_cleanup_key_block(s);
@@ -611,6 +598,7 @@ int ssl3_connect(SSL *s)
/* else do it later in ssl3_write */
s->init_num=0;
+ s->renegotiate=0;
s->new_session=0;
ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
@@ -686,12 +674,6 @@ int ssl3_client_hello(SSL *s)
#endif
(sess->not_resumable))
{
- if (!s->session_creation_enabled)
- {
- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
- SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
- goto err;
- }
if (!ssl_get_new_session(s,0))
goto err;
}
@@ -706,9 +688,43 @@ int ssl3_client_hello(SSL *s)
/* Do the message type and length last */
d=p= &(buf[4]);
+ /* version indicates the negotiated version: for example from
+ * an SSLv2/v3 compatible client hello). The client_version
+ * field is the maximum version we permit and it is also
+ * used in RSA encrypted premaster secrets. Some servers can
+ * choke if we initially report a higher version then
+ * renegotiate to a lower one in the premaster secret. This
+ * didn't happen with TLS 1.0 as most servers supported it
+ * but it can with TLS 1.1 or later if the server only supports
+ * 1.0.
+ *
+ * Possible scenario with previous logic:
+ * 1. Client hello indicates TLS 1.2
+ * 2. Server hello says TLS 1.0
+ * 3. RSA encrypted premaster secret uses 1.2.
+ * 4. Handhaked proceeds using TLS 1.0.
+ * 5. Server sends hello request to renegotiate.
+ * 6. Client hello indicates TLS v1.0 as we now
+ * know that is maximum server supports.
+ * 7. Server chokes on RSA encrypted premaster secret
+ * containing version 1.0.
+ *
+ * For interoperability it should be OK to always use the
+ * maximum version we support in client hello and then rely
+ * on the checking of version to ensure the servers isn't
+ * being inconsistent: for example initially negotiating with
+ * TLS 1.0 and renegotiating with TLS 1.2. We do this by using
+ * client_version in client hello and not resetting it to
+ * the negotiated version.
+ */
+#if 0
*(p++)=s->version>>8;
*(p++)=s->version&0xff;
s->client_version=s->version;
+#else
+ *(p++)=s->client_version>>8;
+ *(p++)=s->client_version&0xff;
+#endif
/* Random stuff */
memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
@@ -738,6 +754,15 @@ int ssl3_client_hello(SSL *s)
SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
goto err;
}
+#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
+ /* Some servers hang if client hello > 256 bytes
+ * as hack workaround chop number of supported ciphers
+ * to keep it well below this if we use TLS v1.2
+ */
+ if (TLS1_get_version(s) >= TLS1_2_VERSION
+ && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
+ i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
+#endif
s2n(i,p);
p+=i;
@@ -900,12 +925,6 @@ int ssl3_get_server_hello(SSL *s)
s->hit=0;
if (s->session->session_id_length > 0)
{
- if (!s->session_creation_enabled)
- {
- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
- SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
- goto err;
- }
if (!ssl_get_new_session(s,0))
{
al=SSL_AD_INTERNAL_ERROR;
@@ -924,6 +943,14 @@ int ssl3_get_server_hello(SSL *s)
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNKNOWN_CIPHER_RETURNED);
goto f_err;
}
+ /* TLS v1.2 only ciphersuites require v1.2 or later */
+ if ((c->algorithm_ssl & SSL_TLSV1_2) &&
+ (TLS1_get_version(s) < TLS1_2_VERSION))
+ {
+ al=SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
+ goto f_err;
+ }
p+=ssl_put_cipher_by_char(s,NULL,NULL);
sk=ssl_get_ciphers_by_id(s);
@@ -955,9 +982,14 @@ int ssl3_get_server_hello(SSL *s)
}
}
s->s3->tmp.new_cipher=c;
- if (!ssl3_digest_cached_records(s))
+ /* Don't digest cached records if TLS v1.2: we may need them for
+ * client authentication.
+ */
+ if (TLS1_get_version(s) < TLS1_2_VERSION && !ssl3_digest_cached_records(s))
+ {
+ al = SSL_AD_INTERNAL_ERROR;
goto f_err;
-
+ }
/* lets get the compression algorithm */
/* COMPRESSION */
#ifdef OPENSSL_NO_COMP
@@ -1236,6 +1268,7 @@ int ssl3_get_key_exchange(SSL *s)
int al,i,j,param_len,ok;
long n,alg_k,alg_a;
EVP_PKEY *pkey=NULL;
+ const EVP_MD *md = NULL;
#ifndef OPENSSL_NO_RSA
RSA *rsa=NULL;
#endif
@@ -1359,6 +1392,86 @@ int ssl3_get_key_exchange(SSL *s)
}
else
#endif /* !OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+ if (alg_k & SSL_kSRP)
+ {
+ n2s(p,i);
+ param_len=i+2;
+ if (param_len > n)
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_N_LENGTH);
+ goto f_err;
+ }
+ if (!(s->srp_ctx.N=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+ goto err;
+ }
+ p+=i;
+
+ n2s(p,i);
+ param_len+=i+2;
+ if (param_len > n)
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_G_LENGTH);
+ goto f_err;
+ }
+ if (!(s->srp_ctx.g=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+ goto err;
+ }
+ p+=i;
+
+ i = (unsigned int)(p[0]);
+ p++;
+ param_len+=i+1;
+ if (param_len > n)
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_S_LENGTH);
+ goto f_err;
+ }
+ if (!(s->srp_ctx.s=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+ goto err;
+ }
+ p+=i;
+
+ n2s(p,i);
+ param_len+=i+2;
+ if (param_len > n)
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_B_LENGTH);
+ goto f_err;
+ }
+ if (!(s->srp_ctx.B=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+ goto err;
+ }
+ p+=i;
+ n-=param_len;
+
+/* We must check if there is a certificate */
+#ifndef OPENSSL_NO_RSA
+ if (alg_a & SSL_aRSA)
+ pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+#else
+ if (0)
+ ;
+#endif
+#ifndef OPENSSL_NO_DSA
+ else if (alg_a & SSL_aDSS)
+ pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
+#endif
+ }
+ else
+#endif /* !OPENSSL_NO_SRP */
#ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA)
{
@@ -1606,6 +1719,38 @@ int ssl3_get_key_exchange(SSL *s)
/* if it was signed, check the signature */
if (pkey != NULL)
{
+ if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ {
+ int sigalg = tls12_get_sigid(pkey);
+ /* Should never happen */
+ if (sigalg == -1)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ /* Check key type is consistent with signature */
+ if (sigalg != (int)p[1])
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_TYPE);
+ al=SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
+ md = tls12_get_hash(p[0]);
+ if (md == NULL)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNKNOWN_DIGEST);
+ al=SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
+#ifdef SSL_DEBUG
+fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
+#endif
+ p += 2;
+ n -= 2;
+ }
+ else
+ md = EVP_sha1();
+
n2s(p,i);
n-=2;
j=EVP_PKEY_size(pkey);
@@ -1619,7 +1764,7 @@ int ssl3_get_key_exchange(SSL *s)
}
#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA)
+ if (pkey->type == EVP_PKEY_RSA && TLS1_get_version(s) < TLS1_2_VERSION)
{
int num;
@@ -1627,6 +1772,8 @@ int ssl3_get_key_exchange(SSL *s)
q=md_buf;
for (num=2; num > 0; num--)
{
+ EVP_MD_CTX_set_flags(&md_ctx,
+ EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
EVP_DigestInit_ex(&md_ctx,(num == 2)
?s->ctx->md5:s->ctx->sha1, NULL);
EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
@@ -1654,29 +1801,8 @@ int ssl3_get_key_exchange(SSL *s)
}
else
#endif
-#ifndef OPENSSL_NO_DSA
- if (pkey->type == EVP_PKEY_DSA)
- {
- /* lets do DSS */
- EVP_VerifyInit_ex(&md_ctx,EVP_dss1(), NULL);
- EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
- EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
- EVP_VerifyUpdate(&md_ctx,param,param_len);
- if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0)
- {
- /* bad signature */
- al=SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);
- goto f_err;
- }
- }
- else
-#endif
-#ifndef OPENSSL_NO_ECDSA
- if (pkey->type == EVP_PKEY_EC)
{
- /* let's do ECDSA */
- EVP_VerifyInit_ex(&md_ctx,EVP_ecdsa(), NULL);
+ EVP_VerifyInit_ex(&md_ctx, md, NULL);
EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,param,param_len);
@@ -1688,12 +1814,6 @@ int ssl3_get_key_exchange(SSL *s)
goto f_err;
}
}
- else
-#endif
- {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
- goto err;
- }
}
else
{
@@ -1740,7 +1860,7 @@ int ssl3_get_certificate_request(SSL *s)
{
int ok,ret=0;
unsigned long n,nc,l;
- unsigned int llen,ctype_num,i;
+ unsigned int llen, ctype_num,i;
X509_NAME *xn=NULL;
const unsigned char *p,*q;
unsigned char *d;
@@ -1760,6 +1880,14 @@ int ssl3_get_certificate_request(SSL *s)
if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)
{
s->s3->tmp.reuse_message=1;
+ /* If we get here we don't need any cached handshake records
+ * as we wont be doing client auth.
+ */
+ if (s->s3->handshake_buffer)
+ {
+ if (!ssl3_digest_cached_records(s))
+ goto err;
+ }
return(1);
}
@@ -1796,6 +1924,26 @@ int ssl3_get_certificate_request(SSL *s)
for (i=0; i<ctype_num; i++)
s->s3->tmp.ctype[i]= p[i];
p+=ctype_num;
+ if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ {
+ n2s(p, llen);
+ /* Check we have enough room for signature algorithms and
+ * following length value.
+ */
+ if ((unsigned long)(p - d + llen + 2) > n)
+ {
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_DATA_LENGTH_TOO_LONG);
+ goto err;
+ }
+ if ((llen & 1) || !tls1_process_sigalgs(s, p, llen))
+ {
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_SIGNATURE_ALGORITHMS_ERROR);
+ goto err;
+ }
+ p += llen;
+ }
/* get the CA RDNs */
n2s(p,llen);
@@ -1808,7 +1956,7 @@ fclose(out);
}
#endif
- if ((llen+ctype_num+2+1) != n)
+ if ((unsigned long)(p - d + llen) != n)
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH);
@@ -2630,6 +2778,39 @@ int ssl3_send_client_key_exchange(SSL *s)
EVP_PKEY_free(pub_key);
}
+#ifndef OPENSSL_NO_SRP
+ else if (alg_k & SSL_kSRP)
+ {
+ if (s->srp_ctx.A != NULL)
+ {
+ /* send off the data */
+ n=BN_num_bytes(s->srp_ctx.A);
+ s2n(n,p);
+ BN_bn2bin(s->srp_ctx.A,p);
+ n+=2;
+ }
+ else
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if (s->session->srp_username != NULL)
+ OPENSSL_free(s->session->srp_username);
+ s->session->srp_username = BUF_strdup(s->srp_ctx.login);
+ if (s->session->srp_username == NULL)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if ((s->session->master_key_length = SRP_generate_client_master_secret(s,s->session->master_key))<0)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+#endif
#ifndef OPENSSL_NO_PSK
else if (alg_k & SSL_kPSK)
{
@@ -2749,12 +2930,13 @@ int ssl3_send_client_verify(SSL *s)
unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
EVP_PKEY *pkey;
EVP_PKEY_CTX *pctx=NULL;
-#ifndef OPENSSL_NO_RSA
+ EVP_MD_CTX mctx;
unsigned u=0;
-#endif
unsigned long n;
int j;
+ EVP_MD_CTX_init(&mctx);
+
if (s->state == SSL3_ST_CW_CERT_VRFY_A)
{
d=(unsigned char *)s->init_buf->data;
@@ -2765,7 +2947,8 @@ int ssl3_send_client_verify(SSL *s)
EVP_PKEY_sign_init(pctx);
if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0)
{
- s->method->ssl3_enc->cert_verify_mac(s,
+ if (TLS1_get_version(s) < TLS1_2_VERSION)
+ s->method->ssl3_enc->cert_verify_mac(s,
NID_sha1,
&(data[MD5_DIGEST_LENGTH]));
}
@@ -2773,6 +2956,41 @@ int ssl3_send_client_verify(SSL *s)
{
ERR_clear_error();
}
+ /* For TLS v1.2 send signature algorithm and signature
+ * using agreed digest and cached handshake records.
+ */
+ if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ {
+ long hdatalen = 0;
+ void *hdata;
+ const EVP_MD *md = s->cert->key->digest;
+ hdatalen = BIO_get_mem_data(s->s3->handshake_buffer,
+ &hdata);
+ if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md))
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+ ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ p += 2;
+#ifdef SSL_DEBUG
+ fprintf(stderr, "Using TLS 1.2 with client alg %s\n",
+ EVP_MD_name(md));
+#endif
+ if (!EVP_SignInit_ex(&mctx, md, NULL)
+ || !EVP_SignUpdate(&mctx, hdata, hdatalen)
+ || !EVP_SignFinal(&mctx, p + 2, &u, pkey))
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+ ERR_R_EVP_LIB);
+ goto err;
+ }
+ s2n(u,p);
+ n = u + 4;
+ if (!ssl3_digest_cached_records(s))
+ goto err;
+ }
+ else
#ifndef OPENSSL_NO_RSA
if (pkey->type == EVP_PKEY_RSA)
{
@@ -2855,9 +3073,11 @@ int ssl3_send_client_verify(SSL *s)
s->init_num=(int)n+4;
s->init_off=0;
}
+ EVP_MD_CTX_cleanup(&mctx);
EVP_PKEY_CTX_free(pctx);
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
err:
+ EVP_MD_CTX_cleanup(&mctx);
EVP_PKEY_CTX_free(pctx);
return(-1);
}
@@ -2981,7 +3201,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
if (idx == SSL_PKEY_ECC)
{
if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509,
- s->s3->tmp.new_cipher) == 0)
+ s) == 0)
{ /* check failed */
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_BAD_ECC_CERT);
goto f_err;
@@ -3077,13 +3297,7 @@ err:
return(0);
}
-/* Check to see if handshake is full or resumed. Usually this is just a
- * case of checking to see if a cache hit has occurred. In the case of
- * session tickets we have to check the next message to be sure.
- */
-
-#ifndef OPENSSL_NO_TLSEXT
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
int ssl3_send_next_proto(SSL *s)
{
unsigned int len, padding_len;
@@ -3106,9 +3320,15 @@ int ssl3_send_next_proto(SSL *s)
}
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
- }
-# endif
+}
+#endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
+/* Check to see if handshake is full or resumed. Usually this is just a
+ * case of checking to see if a cache hit has occurred. In the case of
+ * session tickets we have to check the next message to be sure.
+ */
+
+#ifndef OPENSSL_NO_TLSEXT
int ssl3_check_finished(SSL *s)
{
int ok;
diff --git a/deps/openssl/openssl/ssl/s3_enc.c b/deps/openssl/openssl/ssl/s3_enc.c
index b14597076..e3cd4f062 100644
--- a/deps/openssl/openssl/ssl/s3_enc.c
+++ b/deps/openssl/openssl/ssl/s3_enc.c
@@ -170,6 +170,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
#endif
k=0;
EVP_MD_CTX_init(&m5);
+ EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
EVP_MD_CTX_init(&s1);
for (i=0; (int)i<num; i+=MD5_DIGEST_LENGTH)
{
@@ -465,12 +466,21 @@ void ssl3_cleanup_key_block(SSL *s)
s->s3->tmp.key_block_length=0;
}
+/* ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+ *
+ * Returns:
+ * 0: (in non-constant time) if the record is publically invalid (i.e. too
+ * short etc).
+ * 1: if the record's padding is valid / the encryption was successful.
+ * -1: if the record's padding is invalid or, if sending, an internal error
+ * occured.
+ */
int ssl3_enc(SSL *s, int send)
{
SSL3_RECORD *rec;
EVP_CIPHER_CTX *ds;
unsigned long l;
- int bs,i;
+ int bs,i,mac_size=0;
const EVP_CIPHER *enc;
if (send)
@@ -521,32 +531,16 @@ int ssl3_enc(SSL *s, int send)
if (!send)
{
if (l == 0 || l%bs != 0)
- {
- SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
return 0;
- }
/* otherwise, rec->length >= bs */
}
EVP_Cipher(ds,rec->data,rec->input,l);
+ if (EVP_MD_CTX_md(s->read_hash) != NULL)
+ mac_size = EVP_MD_CTX_size(s->read_hash);
if ((bs != 1) && !send)
- {
- i=rec->data[l-1]+1;
- /* SSL 3.0 bounds the number of padding bytes by the block size;
- * padding bytes (except the last one) are arbitrary */
- if (i > bs)
- {
- /* Incorrect padding. SSLerr() and ssl3_alert are done
- * by caller: we don't want to reveal whether this is
- * a decryption error or a MAC verification failure
- * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
- return -1;
- }
- /* now i <= bs <= rec->length */
- rec->length-=i;
- }
+ return ssl3_cbc_remove_padding(s, rec, bs, mac_size);
}
return(1);
}
@@ -571,12 +565,12 @@ void ssl3_free_digest_list(SSL *s)
OPENSSL_free(s->s3->handshake_dgst);
s->s3->handshake_dgst=NULL;
}
-
+
void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
{
- if (s->s3->handshake_buffer)
+ if (s->s3->handshake_buffer && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE))
{
BIO_write (s->s3->handshake_buffer,(void *)buf,len);
}
@@ -613,9 +607,16 @@ int ssl3_digest_cached_records(SSL *s)
/* Loop through bitso of algorithm2 field and create MD_CTX-es */
for (i=0;ssl_get_handshake_digest(i,&mask,&md); i++)
{
- if ((mask & s->s3->tmp.new_cipher->algorithm2) && md)
+ if ((mask & ssl_get_algorithm2(s)) && md)
{
s->s3->handshake_dgst[i]=EVP_MD_CTX_create();
+#ifdef OPENSSL_FIPS
+ if (EVP_MD_nid(md) == NID_md5)
+ {
+ EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
+ EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ }
+#endif
EVP_DigestInit_ex(s->s3->handshake_dgst[i],md,NULL);
EVP_DigestUpdate(s->s3->handshake_dgst[i],hdata,hdatalen);
}
@@ -624,9 +625,12 @@ int ssl3_digest_cached_records(SSL *s)
s->s3->handshake_dgst[i]=NULL;
}
}
- /* Free handshake_buffer BIO */
- BIO_free(s->s3->handshake_buffer);
- s->s3->handshake_buffer = NULL;
+ if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE))
+ {
+ /* Free handshake_buffer BIO */
+ BIO_free(s->s3->handshake_buffer);
+ s->s3->handshake_buffer = NULL;
+ }
return 1;
}
@@ -672,6 +676,7 @@ static int ssl3_handshake_mac(SSL *s, int md_nid,
return 0;
}
EVP_MD_CTX_init(&ctx);
+ EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
EVP_MD_CTX_copy_ex(&ctx,d);
n=EVP_MD_CTX_size(&ctx);
if (n < 0)
@@ -704,7 +709,7 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
EVP_MD_CTX md_ctx;
const EVP_MD_CTX *hash;
unsigned char *p,rec_char;
- unsigned int md_size;
+ size_t md_size, orig_len;
int npad;
int t;
@@ -729,28 +734,72 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
md_size=t;
npad=(48/md_size)*md_size;
- /* Chop the digest off the end :-) */
- EVP_MD_CTX_init(&md_ctx);
-
- EVP_MD_CTX_copy_ex( &md_ctx,hash);
- EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
- EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);
- EVP_DigestUpdate(&md_ctx,seq,8);
- rec_char=rec->type;
- EVP_DigestUpdate(&md_ctx,&rec_char,1);
- p=md;
- s2n(rec->length,p);
- EVP_DigestUpdate(&md_ctx,md,2);
- EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
- EVP_DigestFinal_ex( &md_ctx,md,NULL);
-
- EVP_MD_CTX_copy_ex( &md_ctx,hash);
- EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
- EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);
- EVP_DigestUpdate(&md_ctx,md,md_size);
- EVP_DigestFinal_ex( &md_ctx,md,&md_size);
-
- EVP_MD_CTX_cleanup(&md_ctx);
+ /* kludge: ssl3_cbc_remove_padding passes padding length in rec->type */
+ orig_len = rec->length+md_size+((unsigned int)rec->type>>8);
+ rec->type &= 0xff;
+
+ if (!send &&
+ EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+ ssl3_cbc_record_digest_supported(hash))
+ {
+ /* This is a CBC-encrypted record. We must avoid leaking any
+ * timing-side channel information about how many blocks of
+ * data we are hashing because that gives an attacker a
+ * timing-oracle. */
+
+ /* npad is, at most, 48 bytes and that's with MD5:
+ * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
+ *
+ * With SHA-1 (the largest hash speced for SSLv3) the hash size
+ * goes up 4, but npad goes down by 8, resulting in a smaller
+ * total size. */
+ unsigned char header[75];
+ unsigned j = 0;
+ memcpy(header+j, mac_sec, md_size);
+ j += md_size;
+ memcpy(header+j, ssl3_pad_1, npad);
+ j += npad;
+ memcpy(header+j, seq, 8);
+ j += 8;
+ header[j++] = rec->type;
+ header[j++] = rec->length >> 8;
+ header[j++] = rec->length & 0xff;
+
+ ssl3_cbc_digest_record(
+ hash,
+ md, &md_size,
+ header, rec->input,
+ rec->length + md_size, orig_len,
+ mac_sec, md_size,
+ 1 /* is SSLv3 */);
+ }
+ else
+ {
+ unsigned int md_size_u;
+ /* Chop the digest off the end :-) */
+ EVP_MD_CTX_init(&md_ctx);
+
+ EVP_MD_CTX_copy_ex( &md_ctx,hash);
+ EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
+ EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);
+ EVP_DigestUpdate(&md_ctx,seq,8);
+ rec_char=rec->type;
+ EVP_DigestUpdate(&md_ctx,&rec_char,1);
+ p=md;
+ s2n(rec->length,p);
+ EVP_DigestUpdate(&md_ctx,md,2);
+ EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
+ EVP_DigestFinal_ex( &md_ctx,md,NULL);
+
+ EVP_MD_CTX_copy_ex( &md_ctx,hash);
+ EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
+ EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);
+ EVP_DigestUpdate(&md_ctx,md,md_size);
+ EVP_DigestFinal_ex( &md_ctx,md,&md_size_u);
+ md_size = md_size_u;
+
+ EVP_MD_CTX_cleanup(&md_ctx);
+ }
ssl3_record_sequence_update(seq);
return(md_size);
diff --git a/deps/openssl/openssl/ssl/s3_lib.c b/deps/openssl/openssl/ssl/s3_lib.c
index 72d3f1fd5..e7c5dcb80 100644
--- a/deps/openssl/openssl/ssl/s3_lib.c
+++ b/deps/openssl/openssl/ssl/s3_lib.c
@@ -1071,6 +1071,103 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
256,
},
+ /* TLS v1.2 ciphersuites */
+ /* Cipher 3B */
+ {
+ 1,
+ TLS1_TXT_RSA_WITH_NULL_SHA256,
+ TLS1_CK_RSA_WITH_NULL_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_eNULL,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 0,
+ 0,
+ },
+
+ /* Cipher 3C */
+ {
+ 1,
+ TLS1_TXT_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_RSA_WITH_AES_128_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher 3D */
+ {
+ 1,
+ TLS1_TXT_RSA_WITH_AES_256_SHA256,
+ TLS1_CK_RSA_WITH_AES_256_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher 3E */
+ {
+ 0, /* not implemented (non-ephemeral DH) */
+ TLS1_TXT_DH_DSS_WITH_AES_128_SHA256,
+ TLS1_CK_DH_DSS_WITH_AES_128_SHA256,
+ SSL_kDHd,
+ SSL_aDH,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher 3F */
+ {
+ 0, /* not implemented (non-ephemeral DH) */
+ TLS1_TXT_DH_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_DH_RSA_WITH_AES_128_SHA256,
+ SSL_kDHr,
+ SSL_aDH,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher 40 */
+ {
+ 1,
+ TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256,
+ TLS1_CK_DHE_DSS_WITH_AES_128_SHA256,
+ SSL_kEDH,
+ SSL_aDSS,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
#ifndef OPENSSL_NO_CAMELLIA
/* Camellia ciphersuites from RFC4132 (128-bit portion) */
@@ -1287,6 +1384,122 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
128,
},
#endif
+
+ /* TLS v1.2 ciphersuites */
+ /* Cipher 67 */
+ {
+ 1,
+ TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
+ SSL_kEDH,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher 68 */
+ {
+ 0, /* not implemented (non-ephemeral DH) */
+ TLS1_TXT_DH_DSS_WITH_AES_256_SHA256,
+ TLS1_CK_DH_DSS_WITH_AES_256_SHA256,
+ SSL_kDHd,
+ SSL_aDH,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher 69 */
+ {
+ 0, /* not implemented (non-ephemeral DH) */
+ TLS1_TXT_DH_RSA_WITH_AES_256_SHA256,
+ TLS1_CK_DH_RSA_WITH_AES_256_SHA256,
+ SSL_kDHr,
+ SSL_aDH,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher 6A */
+ {
+ 1,
+ TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256,
+ TLS1_CK_DHE_DSS_WITH_AES_256_SHA256,
+ SSL_kEDH,
+ SSL_aDSS,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher 6B */
+ {
+ 1,
+ TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256,
+ TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
+ SSL_kEDH,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher 6C */
+ {
+ 1,
+ TLS1_TXT_ADH_WITH_AES_128_SHA256,
+ TLS1_CK_ADH_WITH_AES_128_SHA256,
+ SSL_kEDH,
+ SSL_aNULL,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher 6D */
+ {
+ 1,
+ TLS1_TXT_ADH_WITH_AES_256_SHA256,
+ TLS1_CK_ADH_WITH_AES_256_SHA256,
+ SSL_kEDH,
+ SSL_aNULL,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* GOST Ciphersuites */
+
{
1,
"GOST94-GOST89-GOST89",
@@ -1610,6 +1823,200 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
#endif /* OPENSSL_NO_SEED */
+ /* GCM ciphersuites from RFC5288 */
+
+ /* Cipher 9C */
+ {
+ 1,
+ TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
+ TLS1_CK_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher 9D */
+ {
+ 1,
+ TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
+ TLS1_CK_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher 9E */
+ {
+ 1,
+ TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kEDH,
+ SSL_aRSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher 9F */
+ {
+ 1,
+ TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kEDH,
+ SSL_aRSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher A0 */
+ {
+ 0,
+ TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256,
+ TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kDHr,
+ SSL_aDH,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher A1 */
+ {
+ 0,
+ TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384,
+ TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kDHr,
+ SSL_aDH,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher A2 */
+ {
+ 1,
+ TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256,
+ TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256,
+ SSL_kEDH,
+ SSL_aDSS,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher A3 */
+ {
+ 1,
+ TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384,
+ TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384,
+ SSL_kEDH,
+ SSL_aDSS,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher A4 */
+ {
+ 0,
+ TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256,
+ TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256,
+ SSL_kDHd,
+ SSL_aDH,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher A5 */
+ {
+ 0,
+ TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384,
+ TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384,
+ SSL_kDHd,
+ SSL_aDH,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher A6 */
+ {
+ 1,
+ TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256,
+ TLS1_CK_ADH_WITH_AES_128_GCM_SHA256,
+ SSL_kEDH,
+ SSL_aNULL,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher A7 */
+ {
+ 1,
+ TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384,
+ TLS1_CK_ADH_WITH_AES_256_GCM_SHA384,
+ SSL_kEDH,
+ SSL_aNULL,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
#ifndef OPENSSL_NO_ECDH
/* Cipher C001 */
{
@@ -1621,7 +2028,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_eNULL,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_STRONG_NONE,
+ SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
0,
0,
@@ -1653,7 +2060,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
168,
168,
@@ -1669,7 +2076,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES128,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
128,
128,
@@ -1685,7 +2092,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES256,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
256,
256,
@@ -1701,7 +2108,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_eNULL,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_STRONG_NONE,
+ SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
0,
0,
@@ -1733,7 +2140,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
168,
168,
@@ -1749,7 +2156,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES128,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
128,
128,
@@ -1765,7 +2172,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES256,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
256,
256,
@@ -1781,7 +2188,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_eNULL,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_STRONG_NONE,
+ SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
0,
0,
@@ -1813,7 +2220,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
168,
168,
@@ -1829,7 +2236,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES128,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
128,
128,
@@ -1845,7 +2252,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES256,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
256,
256,
@@ -1861,7 +2268,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_eNULL,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_STRONG_NONE,
+ SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
0,
0,
@@ -1893,7 +2300,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
168,
168,
@@ -1909,7 +2316,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES128,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
128,
128,
@@ -1925,7 +2332,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES256,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
256,
256,
@@ -1941,7 +2348,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_eNULL,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_STRONG_NONE,
+ SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
0,
0,
@@ -1973,7 +2380,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
168,
168,
@@ -1989,7 +2396,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES128,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
128,
128,
@@ -2005,13 +2412,423 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES256,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
256,
256,
},
#endif /* OPENSSL_NO_ECDH */
+#ifndef OPENSSL_NO_SRP
+ /* Cipher C01A */
+ {
+ 1,
+ TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
+ TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
+ SSL_kSRP,
+ SSL_aNULL,
+ SSL_3DES,
+ SSL_SHA1,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 168,
+ 168,
+ },
+
+ /* Cipher C01B */
+ {
+ 1,
+ TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
+ SSL_kSRP,
+ SSL_aRSA,
+ SSL_3DES,
+ SSL_SHA1,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 168,
+ 168,
+ },
+
+ /* Cipher C01C */
+ {
+ 1,
+ TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
+ TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
+ SSL_kSRP,
+ SSL_aDSS,
+ SSL_3DES,
+ SSL_SHA1,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 168,
+ 168,
+ },
+
+ /* Cipher C01D */
+ {
+ 1,
+ TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA,
+ TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA,
+ SSL_kSRP,
+ SSL_aNULL,
+ SSL_AES128,
+ SSL_SHA1,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher C01E */
+ {
+ 1,
+ TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
+ TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
+ SSL_kSRP,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA1,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher C01F */
+ {
+ 1,
+ TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
+ TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
+ SSL_kSRP,
+ SSL_aDSS,
+ SSL_AES128,
+ SSL_SHA1,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher C020 */
+ {
+ 1,
+ TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA,
+ TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA,
+ SSL_kSRP,
+ SSL_aNULL,
+ SSL_AES256,
+ SSL_SHA1,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher C021 */
+ {
+ 1,
+ TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
+ TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
+ SSL_kSRP,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA1,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher C022 */
+ {
+ 1,
+ TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+ TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+ SSL_kSRP,
+ SSL_aDSS,
+ SSL_AES256,
+ SSL_SHA1,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+#endif /* OPENSSL_NO_SRP */
+#ifndef OPENSSL_NO_ECDH
+
+ /* HMAC based TLS v1.2 ciphersuites from RFC5289 */
+
+ /* Cipher C023 */
+ {
+ 1,
+ TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
+ SSL_kEECDH,
+ SSL_aECDSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C024 */
+ {
+ 1,
+ TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
+ SSL_kEECDH,
+ SSL_aECDSA,
+ SSL_AES256,
+ SSL_SHA384,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher C025 */
+ {
+ 1,
+ TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256,
+ TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256,
+ SSL_kECDHe,
+ SSL_aECDH,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C026 */
+ {
+ 1,
+ TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384,
+ TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384,
+ SSL_kECDHe,
+ SSL_aECDH,
+ SSL_AES256,
+ SSL_SHA384,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher C027 */
+ {
+ 1,
+ TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
+ SSL_kEECDH,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C028 */
+ {
+ 1,
+ TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384,
+ TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
+ SSL_kEECDH,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA384,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher C029 */
+ {
+ 1,
+ TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256,
+ SSL_kECDHr,
+ SSL_aECDH,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C02A */
+ {
+ 1,
+ TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384,
+ TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384,
+ SSL_kECDHr,
+ SSL_aECDH,
+ SSL_AES256,
+ SSL_SHA384,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* GCM based TLS v1.2 ciphersuites from RFC5289 */
+
+ /* Cipher C02B */
+ {
+ 1,
+ TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ SSL_kEECDH,
+ SSL_aECDSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C02C */
+ {
+ 1,
+ TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ SSL_kEECDH,
+ SSL_aECDSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher C02D */
+ {
+ 1,
+ TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+ SSL_kECDHe,
+ SSL_aECDH,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C02E */
+ {
+ 1,
+ TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
+ SSL_kECDHe,
+ SSL_aECDH,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher C02F */
+ {
+ 1,
+ TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kEECDH,
+ SSL_aRSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C030 */
+ {
+ 1,
+ TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kEECDH,
+ SSL_aRSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher C031 */
+ {
+ 1,
+ TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+ TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kECDHr,
+ SSL_aECDH,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C032 */
+ {
+ 1,
+ TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384,
+ TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kECDHr,
+ SSL_aECDH,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+#endif /* OPENSSL_NO_ECDH */
+
+
#ifdef TEMP_GOST_TLS
/* Cipher FF00 */
{
@@ -2089,7 +2906,7 @@ SSL3_ENC_METHOD SSLv3_enc_data={
ssl3_alert_code,
(int (*)(SSL *, unsigned char *, size_t, const char *,
size_t, const unsigned char *, size_t,
- int use_context)) ssl_undefined_function,
+ int use_context))ssl_undefined_function,
};
long ssl3_default_timeout(void)
@@ -2131,6 +2948,9 @@ int ssl3_new(SSL *s)
s->s3=s3;
+#ifndef OPENSSL_NO_SRP
+ SSL_SRP_CTX_init(s);
+#endif
s->method->ssl_clear(s);
return(1);
err:
@@ -2171,6 +2991,9 @@ void ssl3_free(SSL *s)
BIO_free(s->s3->handshake_buffer);
}
if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
+#ifndef OPENSSL_NO_SRP
+ SSL_SRP_CTX_free(s);
+#endif
OPENSSL_cleanse(s->s3,sizeof *s->s3);
OPENSSL_free(s->s3);
s->s3=NULL;
@@ -2253,6 +3076,13 @@ void ssl3_clear(SSL *s)
#endif
}
+#ifndef OPENSSL_NO_SRP
+static char * MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg)
+ {
+ return BUF_strdup(s->srp_ctx.info) ;
+ }
+#endif
+
long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
{
int ret=0;
@@ -2498,6 +3328,27 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
ret = 1;
break;
+#ifndef OPENSSL_NO_HEARTBEATS
+ case SSL_CTRL_TLS_EXT_SEND_HEARTBEAT:
+ if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+ ret = dtls1_heartbeat(s);
+ else
+ ret = tls1_heartbeat(s);
+ break;
+
+ case SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING:
+ ret = s->tlsext_hb_pending;
+ break;
+
+ case SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS:
+ if (larg)
+ s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_RECV_REQUESTS;
+ else
+ s->tlsext_heartbeat &= ~SSL_TLSEXT_HB_DONT_RECV_REQUESTS;
+ ret = 1;
+ break;
+#endif
+
#endif /* !OPENSSL_NO_TLSEXT */
default:
break;
@@ -2730,6 +3581,38 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
return 1;
break;
+#ifndef OPENSSL_NO_SRP
+ case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME:
+ ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+ if (ctx->srp_ctx.login != NULL)
+ OPENSSL_free(ctx->srp_ctx.login);
+ ctx->srp_ctx.login = NULL;
+ if (parg == NULL)
+ break;
+ if (strlen((const char *)parg) > 255 || strlen((const char *)parg) < 1)
+ {
+ SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME);
+ return 0;
+ }
+ if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL)
+ {
+ SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ break;
+ case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD:
+ ctx->srp_ctx.SRP_give_srp_client_pwd_callback=srp_password_from_info_cb;
+ ctx->srp_ctx.info=parg;
+ break;
+ case SSL_CTRL_SET_SRP_ARG:
+ ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+ ctx->srp_ctx.SRP_cb_arg=parg;
+ break;
+
+ case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH:
+ ctx->srp_ctx.strength=larg;
+ break;
+#endif
#endif /* !OPENSSL_NO_TLSEXT */
/* A Thawte special :-) */
@@ -2742,6 +3625,18 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
sk_X509_push(ctx->extra_certs,(X509 *)parg);
break;
+ case SSL_CTRL_GET_EXTRA_CHAIN_CERTS:
+ *(STACK_OF(X509) **)parg = ctx->extra_certs;
+ break;
+
+ case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS:
+ if (ctx->extra_certs)
+ {
+ sk_X509_pop_free(ctx->extra_certs, X509_free);
+ ctx->extra_certs = NULL;
+ }
+ break;
+
default:
return(0);
}
@@ -2799,6 +3694,20 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
HMAC_CTX *, int))fp;
break;
+#ifndef OPENSSL_NO_SRP
+ case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB:
+ ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+ ctx->srp_ctx.SRP_verify_param_callback=(int (*)(SSL *,void *))fp;
+ break;
+ case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB:
+ ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+ ctx->srp_ctx.TLS_ext_srp_username_callback=(int (*)(SSL *,int *,void *))fp;
+ break;
+ case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB:
+ ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+ ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
+ break;
+#endif
#endif
default:
return(0);
@@ -2817,6 +3726,9 @@ const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
id=0x03000000L|((unsigned long)p[0]<<8L)|(unsigned long)p[1];
c.id=id;
cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS);
+#ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES
+if (cp == NULL) fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]);
+#endif
if (cp == NULL || cp->valid == 0)
return NULL;
else
@@ -2894,11 +3806,20 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
{
c=sk_SSL_CIPHER_value(prio,i);
+ /* Skip TLS v1.2 only ciphersuites if lower than v1.2 */
+ if ((c->algorithm_ssl & SSL_TLSV1_2) &&
+ (TLS1_get_version(s) < TLS1_2_VERSION))
+ continue;
+
ssl_set_cert_masks(cert,c);
mask_k = cert->mask_k;
mask_a = cert->mask_a;
emask_k = cert->export_mask_k;
emask_a = cert->export_mask_a;
+#ifndef OPENSSL_NO_SRP
+ mask_k=cert->mask_k | s->srp_ctx.srp_Mask;
+ emask_k=cert->export_mask_k | s->srp_ctx.srp_Mask;
+#endif
#ifdef KSSL_DEBUG
/* printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
@@ -3278,22 +4199,9 @@ int ssl3_write(SSL *s, const void *buf, int len)
static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
{
- int n,ret;
+ int ret;
clear_sys_error();
- if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio))
- {
- /* Deal with an application that calls SSL_read() when handshake data
- * is yet to be written.
- */
- if (BIO_wpending(s->wbio) > 0)
- {
- s->rwstate=SSL_WRITING;
- n=BIO_flush(s->wbio);
- if (n <= 0) return(n);
- s->rwstate=SSL_NOTHING;
- }
- }
if (s->s3->renegotiate) ssl3_renegotiate_check(s);
s->s3->in_read_app_data=1;
ret=s->method->ssl_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek);
@@ -3360,4 +4268,15 @@ need to go to SSL_ST_ACCEPT.
}
return(ret);
}
-
+/* If we are using TLS v1.2 or later and default SHA1+MD5 algorithms switch
+ * to new SHA256 PRF and handshake macs
+ */
+long ssl_get_algorithm2(SSL *s)
+ {
+ long alg2 = s->s3->tmp.new_cipher->algorithm2;
+ if (TLS1_get_version(s) >= TLS1_2_VERSION &&
+ alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF))
+ return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
+ return alg2;
+ }
+
diff --git a/deps/openssl/openssl/ssl/s3_pkt.c b/deps/openssl/openssl/ssl/s3_pkt.c
index 0d3874ae4..804291e27 100644
--- a/deps/openssl/openssl/ssl/s3_pkt.c
+++ b/deps/openssl/openssl/ssl/s3_pkt.c
@@ -115,6 +115,7 @@
#include "ssl_locl.h"
#include <openssl/evp.h>
#include <openssl/buffer.h>
+#include <openssl/rand.h>
static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
unsigned int len, int create_empty_fragment);
@@ -289,16 +290,8 @@ static int ssl3_get_record(SSL *s)
unsigned char *p;
unsigned char md[EVP_MAX_MD_SIZE];
short version;
- int mac_size;
- int clear=0;
+ unsigned mac_size, orig_len;
size_t extra;
- int decryption_failed_or_bad_record_mac = 0;
- unsigned char *mac = NULL;
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
- long align=SSL3_ALIGN_PAYLOAD;
-#else
- long align=0;
-#endif
rr= &(s->s3->rrec);
sess=s->session;
@@ -307,8 +300,7 @@ static int ssl3_get_record(SSL *s)
extra=SSL3_RT_MAX_EXTRA;
else
extra=0;
- if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) &&
- extra && !s->s3->init_extra)
+ if (extra && !s->s3->init_extra)
{
/* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
* set after ssl3_setup_buffers() was done */
@@ -357,21 +349,6 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
goto err;
}
- /* If we receive a valid record larger than the current buffer size,
- * allocate some memory for it.
- */
- if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH - align)
- {
- if ((p=OPENSSL_realloc(s->s3->rbuf.buf, rr->length + SSL3_RT_HEADER_LENGTH + align))==NULL)
- {
- SSLerr(SSL_F_SSL3_GET_RECORD,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s->s3->rbuf.buf=p;
- s->s3->rbuf.len=rr->length + SSL3_RT_HEADER_LENGTH + align;
- s->packet= &(s->s3->rbuf.buf[0]);
- }
-
if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
{
al=SSL_AD_RECORD_OVERFLOW;
@@ -423,17 +400,15 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
rr->data=rr->input;
enc_err = s->method->ssl3_enc->enc(s,0);
- if (enc_err <= 0)
+ /* enc_err is:
+ * 0: (in non-constant time) if the record is publically invalid.
+ * 1: if the padding is valid
+ * -1: if the padding is invalid */
+ if (enc_err == 0)
{
- if (enc_err == 0)
- /* SSLerr() and ssl3_send_alert() have been called */
- goto err;
-
- /* Otherwise enc_err == -1, which indicates bad padding
- * (rec->length has not been changed in this case).
- * To minimize information leaked via timing, we will perform
- * the MAC computation anyway. */
- decryption_failed_or_bad_record_mac = 1;
+ al=SSL_AD_DECRYPTION_FAILED;
+ SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
+ goto f_err;
}
#ifdef TLS_DEBUG
@@ -443,53 +418,62 @@ printf("\n");
#endif
/* r->length is now the compressed data plus mac */
- if ( (sess == NULL) ||
- (s->enc_read_ctx == NULL) ||
- (EVP_MD_CTX_md(s->read_hash) == NULL))
- clear=1;
-
- if (!clear)
+ if ((sess != NULL) &&
+ (s->enc_read_ctx != NULL) &&
+ (EVP_MD_CTX_md(s->read_hash) != NULL))
{
- /* !clear => s->read_hash != NULL => mac_size != -1 */
+ /* s->read_hash != NULL => mac_size != -1 */
+ unsigned char *mac = NULL;
+ unsigned char mac_tmp[EVP_MAX_MD_SIZE];
mac_size=EVP_MD_CTX_size(s->read_hash);
- OPENSSL_assert(mac_size >= 0);
+ OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
- if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
+ /* kludge: *_cbc_remove_padding passes padding length in rr->type */
+ orig_len = rr->length+((unsigned int)rr->type>>8);
+
+ /* orig_len is the length of the record before any padding was
+ * removed. This is public information, as is the MAC in use,
+ * therefore we can safely process the record in a different
+ * amount of time if it's too short to possibly contain a MAC.
+ */
+ if (orig_len < mac_size ||
+ /* CBC records must have a padding length byte too. */
+ (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+ orig_len < mac_size+1))
{
-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
- al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
goto f_err;
-#else
- decryption_failed_or_bad_record_mac = 1;
-#endif
}
- /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
- if (rr->length >= (unsigned int)mac_size)
+
+ if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
{
+ /* We update the length so that the TLS header bytes
+ * can be constructed correctly but we need to extract
+ * the MAC in constant time from within the record,
+ * without leaking the contents of the padding bytes.
+ * */
+ mac = mac_tmp;
+ ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
rr->length -= mac_size;
- mac = &rr->data[rr->length];
}
else
{
- /* record (minus padding) is too short to contain a MAC */
-#if 0 /* OK only for stream ciphers */
- al=SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
-#else
- decryption_failed_or_bad_record_mac = 1;
- rr->length = 0;
-#endif
- }
- i=s->method->ssl3_enc->mac(s,md,0);
- if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0)
- {
- decryption_failed_or_bad_record_mac = 1;
+ /* In this case there's no padding, so |orig_len|
+ * equals |rec->length| and we checked that there's
+ * enough bytes for |mac_size| above. */
+ rr->length -= mac_size;
+ mac = &rr->data[rr->length];
}
+
+ i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
+ if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+ enc_err = -1;
+ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
+ enc_err = -1;
}
- if (decryption_failed_or_bad_record_mac)
+ if (enc_err < 0)
{
/* A separate 'decryption_failed' alert was introduced with TLS 1.0,
* SSL 3.0 only has 'bad_record_mac'. But unless a decryption
@@ -598,7 +582,6 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
const unsigned char *buf=buf_;
unsigned int tot,n,nw;
int i;
- unsigned int max_plain_length;
s->rwstate=SSL_NOTHING;
tot=s->s3->wnum;
@@ -618,13 +601,8 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
n=(len-tot);
for (;;)
{
- if (type == SSL3_RT_APPLICATION_DATA && (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS))
- max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH;
- else
- max_plain_length = s->max_send_fragment;
-
- if (n > max_plain_length)
- nw = max_plain_length;
+ if (n > s->max_send_fragment)
+ nw=s->max_send_fragment;
else
nw=n;
@@ -657,6 +635,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
unsigned char *p,*plen;
int i,mac_size,clear=0;
int prefix_len=0;
+ int eivlen;
long align=0;
SSL3_RECORD *wr;
SSL3_BUFFER *wb=&(s->s3->wbuf);
@@ -689,10 +668,14 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
if ( (sess == NULL) ||
(s->enc_write_ctx == NULL) ||
(EVP_MD_CTX_md(s->write_hash) == NULL))
+ {
+#if 1
+ clear=s->enc_write_ctx?0:1; /* must be AEAD cipher */
+#else
clear=1;
-
- if (clear)
+#endif
mac_size=0;
+ }
else
{
mac_size=EVP_MD_CTX_size(s->write_hash);
@@ -728,18 +711,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
s->s3->empty_fragment_done = 1;
}
- /* resize if necessary to hold the data. */
- if (len + SSL3_RT_DEFAULT_WRITE_OVERHEAD > wb->len)
- {
- if ((p=OPENSSL_realloc(wb->buf, len + SSL3_RT_DEFAULT_WRITE_OVERHEAD))==NULL)
- {
- SSLerr(SSL_F_DO_SSL3_WRITE,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- wb->buf = p;
- wb->len = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
- }
-
if (create_empty_fragment)
{
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
@@ -773,14 +744,40 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
wr->type=type;
*(p++)=(s->version>>8);
- *(p++)=s->version&0xff;
+ /* Some servers hang if iniatial client hello is larger than 256
+ * bytes and record version number > TLS 1.0
+ */
+ if (s->state == SSL3_ST_CW_CLNT_HELLO_B
+ && !s->renegotiate
+ && TLS1_get_version(s) > TLS1_VERSION)
+ *(p++) = 0x1;
+ else
+ *(p++)=s->version&0xff;
/* field where we are to write out packet length */
plen=p;
p+=2;
+ /* Explicit IV length, block ciphers and TLS version 1.1 or later */
+ if (s->enc_write_ctx && s->version >= TLS1_1_VERSION)
+ {
+ int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
+ if (mode == EVP_CIPH_CBC_MODE)
+ {
+ eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
+ if (eivlen <= 1)
+ eivlen = 0;
+ }
+ /* Need explicit part of IV for GCM mode */
+ else if (mode == EVP_CIPH_GCM_MODE)
+ eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ else
+ eivlen = 0;
+ }
+ else
+ eivlen = 0;
/* lets setup the record stuff. */
- wr->data=p;
+ wr->data=p + eivlen;
wr->length=(int)len;
wr->input=(unsigned char *)buf;
@@ -808,11 +805,19 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
if (mac_size != 0)
{
- if (s->method->ssl3_enc->mac(s,&(p[wr->length]),1) < 0)
+ if (s->method->ssl3_enc->mac(s,&(p[wr->length + eivlen]),1) < 0)
goto err;
wr->length+=mac_size;
- wr->input=p;
- wr->data=p;
+ }
+
+ wr->input=p;
+ wr->data=p;
+
+ if (eivlen)
+ {
+ /* if (RAND_pseudo_bytes(p, eivlen) <= 0)
+ goto err; */
+ wr->length += eivlen;
}
/* ssl3_enc can only have an error on read */
@@ -1081,6 +1086,19 @@ start:
dest = s->s3->alert_fragment;
dest_len = &s->s3->alert_fragment_len;
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ else if (rr->type == TLS1_RT_HEARTBEAT)
+ {
+ tls1_process_heartbeat(s);
+
+ /* Exit and notify application to read again */
+ rr->length = 0;
+ s->rwstate=SSL_READING;
+ BIO_clear_retry_flags(SSL_get_rbio(s));
+ BIO_set_retry_read(SSL_get_rbio(s));
+ return(-1);
+ }
+#endif
if (dest_maxlen > 0)
{
@@ -1224,6 +1242,10 @@ start:
SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION);
goto f_err;
}
+#ifdef SSL_AD_MISSING_SRP_USERNAME
+ else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
+ return(0);
+#endif
}
else if (alert_level == 2) /* fatal */
{
@@ -1302,6 +1324,7 @@ start:
#else
s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
#endif
+ s->renegotiate=1;
s->new_session=1;
}
i=s->handshake_func(s);
@@ -1335,8 +1358,10 @@ start:
{
default:
#ifndef OPENSSL_NO_TLS
- /* TLS just ignores unknown message types */
- if (s->version == TLS1_VERSION)
+ /* TLS up to v1.1 just ignores unknown message types:
+ * TLS v1.2 give an unexpected message alert.
+ */
+ if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION)
{
rr->length = 0;
goto start;
@@ -1396,10 +1421,8 @@ err:
int ssl3_do_change_cipher_spec(SSL *s)
{
int i;
-#ifdef OPENSSL_NO_NEXTPROTONEG
const char *sender;
int slen;
-#endif
if (s->state & SSL_ST_ACCEPT)
i=SSL3_CHANGE_CIPHER_SERVER_READ;
@@ -1422,7 +1445,6 @@ int ssl3_do_change_cipher_spec(SSL *s)
if (!s->method->ssl3_enc->change_cipher_state(s,i))
return(0);
-#ifdef OPENSSL_NO_NEXTPROTONEG
/* we have to record the message digest at
* this point so we can get it before we read
* the finished message */
@@ -1439,7 +1461,6 @@ int ssl3_do_change_cipher_spec(SSL *s)
s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
sender,slen,s->s3->tmp.peer_finish_md);
-#endif
return(1);
}
diff --git a/deps/openssl/openssl/ssl/s3_srvr.c b/deps/openssl/openssl/ssl/s3_srvr.c
index 41e597f8b..bfb848054 100644
--- a/deps/openssl/openssl/ssl/s3_srvr.c
+++ b/deps/openssl/openssl/ssl/s3_srvr.c
@@ -179,6 +179,32 @@ static const SSL_METHOD *ssl3_get_server_method(int ver)
return(NULL);
}
+#ifndef OPENSSL_NO_SRP
+static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
+ {
+ int ret = SSL_ERROR_NONE;
+
+ *al = SSL_AD_UNRECOGNIZED_NAME;
+
+ if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) &&
+ (s->srp_ctx.TLS_ext_srp_username_callback != NULL))
+ {
+ if(s->srp_ctx.login == NULL)
+ {
+ /* RFC 5054 says SHOULD reject,
+ we do so if There is no srp login name */
+ ret = SSL3_AL_FATAL;
+ *al = SSL_AD_UNKNOWN_PSK_IDENTITY;
+ }
+ else
+ {
+ ret = SSL_srp_server_param_with_username(s,al);
+ }
+ }
+ return ret;
+ }
+#endif
+
IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
ssl3_accept,
ssl_undefined_function,
@@ -211,6 +237,18 @@ int ssl3_accept(SSL *s)
return(-1);
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ /* If we're awaiting a HeartbeatResponse, pretend we
+ * already got and don't await it anymore, because
+ * Heartbeats don't make sense during handshakes anyway.
+ */
+ if (s->tlsext_hb_pending)
+ {
+ s->tlsext_hb_pending = 0;
+ s->tlsext_hb_seq++;
+ }
+#endif
+
for (;;)
{
state=s->state;
@@ -218,7 +256,7 @@ int ssl3_accept(SSL *s)
switch (s->state)
{
case SSL_ST_RENEGOTIATE:
- s->new_session=1;
+ s->renegotiate=1;
/* s->state=SSL_ST_ACCEPT; */
case SSL_ST_BEFORE:
@@ -314,10 +352,35 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_CLNT_HELLO_C:
s->shutdown=0;
- ret=ssl3_get_client_hello(s);
- if (ret <= 0) goto end;
+ if (s->rwstate != SSL_X509_LOOKUP)
+ {
+ ret=ssl3_get_client_hello(s);
+ if (ret <= 0) goto end;
+ }
+#ifndef OPENSSL_NO_SRP
+ {
+ int al;
+ if ((ret = ssl_check_srp_ext_ClientHello(s,&al)) < 0)
+ {
+ /* callback indicates firther work to be done */
+ s->rwstate=SSL_X509_LOOKUP;
+ goto end;
+ }
+ if (ret != SSL_ERROR_NONE)
+ {
+ ssl3_send_alert(s,SSL3_AL_FATAL,al);
+ /* This is not really an error but the only means to
+ for a client to detect whether srp is supported. */
+ if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY)
+ SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ ret= -1;
+ goto end;
+ }
+ }
+#endif
- s->new_session = 2;
+ s->renegotiate = 2;
s->state=SSL3_ST_SW_SRVR_HELLO_A;
s->init_num=0;
break;
@@ -346,7 +409,7 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SW_CERT_A:
case SSL3_ST_SW_CERT_B:
/* Check if it is anon DH or anon ECDH, */
- /* normal PSK or KRB5 */
+ /* normal PSK or KRB5 or SRP */
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
&& !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
@@ -411,6 +474,10 @@ int ssl3_accept(SSL *s)
#ifndef OPENSSL_NO_PSK
|| ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
#endif
+#ifndef OPENSSL_NO_SRP
+ /* SRP: send ServerKeyExchange */
+ || (alg_k & SSL_kSRP)
+#endif
|| (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH))
|| (alg_k & SSL_kEECDH)
|| ((alg_k & SSL_kRSA)
@@ -457,6 +524,9 @@ int ssl3_accept(SSL *s)
skip=1;
s->s3->tmp.cert_request=0;
s->state=SSL3_ST_SW_SRVR_DONE_A;
+ if (s->s3->handshake_buffer)
+ if (!ssl3_digest_cached_records(s))
+ return -1;
}
else
{
@@ -549,6 +619,24 @@ int ssl3_accept(SSL *s)
#endif
s->init_num = 0;
}
+ else if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ {
+ s->state=SSL3_ST_SR_CERT_VRFY_A;
+ s->init_num=0;
+ if (!s->session->peer)
+ break;
+ /* For TLS v1.2 freeze the handshake buffer
+ * at this point and digest cached records.
+ */
+ if (!s->s3->handshake_buffer)
+ {
+ SSLerr(SSL_F_SSL3_ACCEPT,ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
+ if (!ssl3_digest_cached_records(s))
+ return -1;
+ }
else
{
int offset=0;
@@ -615,14 +703,11 @@ int ssl3_accept(SSL *s)
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end;
-#ifndef OPENSSL_NO_TLSEXT
- if (s->tlsext_ticket_expected)
- s->state=SSL3_ST_SW_SESSION_TICKET_A;
- else if (s->hit)
- s->state=SSL_ST_OK;
-#else
if (s->hit)
s->state=SSL_ST_OK;
+#ifndef OPENSSL_NO_TLSEXT
+ else if (s->tlsext_ticket_expected)
+ s->state=SSL3_ST_SW_SESSION_TICKET_A;
#endif
else
s->state=SSL3_ST_SW_CHANGE_A;
@@ -707,11 +792,9 @@ int ssl3_accept(SSL *s)
s->init_num=0;
- if (s->new_session == 2) /* skipped if we just sent a HelloRequest */
+ if (s->renegotiate == 2) /* skipped if we just sent a HelloRequest */
{
- /* actually not necessarily a 'new' session unless
- * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
-
+ s->renegotiate=0;
s->new_session=0;
ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
@@ -789,14 +872,6 @@ int ssl3_check_client_hello(SSL *s)
int ok;
long n;
- /* We only allow the client to restart the handshake once per
- * negotiation. */
- if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
- {
- SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
- return -1;
- }
-
/* this function is called when we really expect a Certificate message,
* so permit appropriate message length */
n=s->method->ssl_get_message(s,
@@ -809,6 +884,13 @@ int ssl3_check_client_hello(SSL *s)
s->s3->tmp.reuse_message = 1;
if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
{
+ /* We only allow the client to restart the handshake once per
+ * negotiation. */
+ if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
+ {
+ SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
+ return -1;
+ }
/* Throw away what we have done so far in the current handshake,
* which will now be aborted. (A full SSL_clear would be too much.) */
#ifndef OPENSSL_NO_DH
@@ -850,7 +932,8 @@ int ssl3_get_client_hello(SSL *s)
* If we are SSLv3, we will respond with SSLv3, even if prompted with
* TLSv1.
*/
- if (s->state == SSL3_ST_SR_CLNT_HELLO_A)
+ if (s->state == SSL3_ST_SR_CLNT_HELLO_A
+ )
{
s->state=SSL3_ST_SR_CLNT_HELLO_B;
}
@@ -907,22 +990,19 @@ int ssl3_get_client_hello(SSL *s)
j= *(p++);
s->hit=0;
- /* Versions before 0.9.7 always allow session reuse during renegotiation
- * (i.e. when s->new_session is true), option
- * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is new with 0.9.7.
- * Maybe this optional behaviour should always have been the default,
- * but we cannot safely change the default behaviour (or new applications
- * might be written that become totally unsecure when compiled with
- * an earlier library version)
+ /* Versions before 0.9.7 always allow clients to resume sessions in renegotiation.
+ * 0.9.7 and later allow this by default, but optionally ignore resumption requests
+ * with flag SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather
+ * than a change to default behavior so that applications relying on this for security
+ * won't even compile against older library versions).
+ *
+ * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to request
+ * renegotiation but not a new session (s->new_session remains unset): for servers,
+ * this essentially just means that the SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
+ * setting will be ignored.
*/
if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
{
- if (!s->session_creation_enabled)
- {
- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
- goto err;
- }
if (!ssl_get_new_session(s,1))
goto err;
}
@@ -937,12 +1017,6 @@ int ssl3_get_client_hello(SSL *s)
goto err;
else /* i == 0 */
{
- if (!s->session_creation_enabled)
- {
- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
- goto err;
- }
if (!ssl_get_new_session(s,1))
goto err;
}
@@ -1109,7 +1183,7 @@ int ssl3_get_client_hello(SSL *s)
goto f_err;
}
}
- if (ssl_check_clienthello_tlsext(s) <= 0) {
+ if (ssl_check_clienthello_tlsext_early(s) <= 0) {
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
goto err;
}
@@ -1314,8 +1388,14 @@ int ssl3_get_client_hello(SSL *s)
s->s3->tmp.new_cipher=s->session->cipher;
}
- if (!ssl3_digest_cached_records(s))
- goto f_err;
+ if (TLS1_get_version(s) < TLS1_2_VERSION || !(s->verify_mode & SSL_VERIFY_PEER))
+ {
+ if (!ssl3_digest_cached_records(s))
+ {
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
+ }
/* we now have the following setup.
* client_random
@@ -1328,6 +1408,16 @@ int ssl3_get_client_hello(SSL *s)
* s->tmp.new_cipher - the new cipher to use.
*/
+ /* Handles TLS extensions that we couldn't check earlier */
+ if (s->version >= SSL3_VERSION)
+ {
+ if (ssl_check_clienthello_tlsext_late(s) <= 0)
+ {
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
+ goto err;
+ }
+ }
+
if (ret < 0) ret=1;
if (0)
{
@@ -1370,20 +1460,20 @@ int ssl3_send_server_hello(SSL *s)
memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
p+=SSL3_RANDOM_SIZE;
- /* now in theory we have 3 options to sending back the
- * session id. If it is a re-use, we send back the
- * old session-id, if it is a new session, we send
- * back the new session-id or we send back a 0 length
- * session-id if we want it to be single use.
- * Currently I will not implement the '0' length session-id
- * 12-Jan-98 - I'll now support the '0' length stuff.
- *
- * We also have an additional case where stateless session
- * resumption is successful: we always send back the old
- * session id. In this case s->hit is non zero: this can
- * only happen if stateless session resumption is succesful
- * if session caching is disabled so existing functionality
- * is unaffected.
+ /* There are several cases for the session ID to send
+ * back in the server hello:
+ * - For session reuse from the session cache,
+ * we send back the old session ID.
+ * - If stateless session reuse (using a session ticket)
+ * is successful, we send back the client's "session ID"
+ * (which doesn't actually identify the session).
+ * - If it is a new session, we send back the new
+ * session ID.
+ * - However, if we want the new session to be single-use,
+ * we send back a 0-length session ID.
+ * s->hit is non-zero in either case of session reuse,
+ * so the following won't overwrite an ID that we're supposed
+ * to send back.
*/
if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
&& !s->hit)
@@ -1484,6 +1574,7 @@ int ssl3_send_server_key_exchange(SSL *s)
BN_CTX *bn_ctx = NULL;
#endif
EVP_PKEY *pkey;
+ const EVP_MD *md = NULL;
unsigned char *p,*d;
int al,i;
unsigned long type;
@@ -1724,21 +1815,44 @@ int ssl3_send_server_key_exchange(SSL *s)
}
else
#endif /* !OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+ if (type & SSL_kSRP)
+ {
+ if ((s->srp_ctx.N == NULL) ||
+ (s->srp_ctx.g == NULL) ||
+ (s->srp_ctx.s == NULL) ||
+ (s->srp_ctx.B == NULL))
+ {
+ SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_SRP_PARAM);
+ goto err;
+ }
+ r[0]=s->srp_ctx.N;
+ r[1]=s->srp_ctx.g;
+ r[2]=s->srp_ctx.s;
+ r[3]=s->srp_ctx.B;
+ }
+ else
+#endif
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
goto f_err;
}
- for (i=0; r[i] != NULL; i++)
+ for (i=0; r[i] != NULL && i<4; i++)
{
nr[i]=BN_num_bytes(r[i]);
+#ifndef OPENSSL_NO_SRP
+ if ((i == 2) && (type & SSL_kSRP))
+ n+=1+nr[i];
+ else
+#endif
n+=2+nr[i];
}
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
{
- if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
+ if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md))
== NULL)
{
al=SSL_AD_DECODE_ERROR;
@@ -1760,8 +1874,16 @@ int ssl3_send_server_key_exchange(SSL *s)
d=(unsigned char *)s->init_buf->data;
p= &(d[4]);
- for (i=0; r[i] != NULL; i++)
+ for (i=0; r[i] != NULL && i<4; i++)
{
+#ifndef OPENSSL_NO_SRP
+ if ((i == 2) && (type & SSL_kSRP))
+ {
+ *p = nr[i];
+ p++;
+ }
+ else
+#endif
s2n(nr[i],p);
BN_bn2bin(r[i],p);
p+=nr[i];
@@ -1809,12 +1931,15 @@ int ssl3_send_server_key_exchange(SSL *s)
/* n is the length of the params, they start at &(d[4])
* and p points to the space at the end. */
#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA)
+ if (pkey->type == EVP_PKEY_RSA
+ && TLS1_get_version(s) < TLS1_2_VERSION)
{
q=md_buf;
j=0;
for (num=2; num > 0; num--)
{
+ EVP_MD_CTX_set_flags(&md_ctx,
+ EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
EVP_DigestInit_ex(&md_ctx,(num == 2)
?s->ctx->md5:s->ctx->sha1, NULL);
EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
@@ -1836,44 +1961,41 @@ int ssl3_send_server_key_exchange(SSL *s)
}
else
#endif
-#if !defined(OPENSSL_NO_DSA)
- if (pkey->type == EVP_PKEY_DSA)
+ if (md)
{
- /* lets do DSS */
- EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL);
- EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
- EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
- EVP_SignUpdate(&md_ctx,&(d[4]),n);
- if (!EVP_SignFinal(&md_ctx,&(p[2]),
- (unsigned int *)&i,pkey))
+ /* For TLS1.2 and later send signature
+ * algorithm */
+ if (TLS1_get_version(s) >= TLS1_2_VERSION)
{
- SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
- goto err;
+ if (!tls12_get_sigandhash(p, pkey, md))
+ {
+ /* Should never happen */
+ al=SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+ p+=2;
}
- s2n(i,p);
- n+=i+2;
- }
- else
+#ifdef SSL_DEBUG
+ fprintf(stderr, "Using hash %s\n",
+ EVP_MD_name(md));
#endif
-#if !defined(OPENSSL_NO_ECDSA)
- if (pkey->type == EVP_PKEY_EC)
- {
- /* let's do ECDSA */
- EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL);
+ EVP_SignInit_ex(&md_ctx, md, NULL);
EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_SignUpdate(&md_ctx,&(d[4]),n);
if (!EVP_SignFinal(&md_ctx,&(p[2]),
(unsigned int *)&i,pkey))
{
- SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA);
+ SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_EVP);
goto err;
}
s2n(i,p);
n+=i+2;
+ if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ n+= 2;
}
else
-#endif
{
/* Is this error check actually needed? */
al=SSL_AD_HANDSHAKE_FAILURE;
@@ -1926,6 +2048,14 @@ int ssl3_send_certificate_request(SSL *s)
p+=n;
n++;
+ if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ {
+ nl = tls12_get_req_sig_algs(s, p + 2);
+ s2n(nl, p);
+ p += nl + 2;
+ n += nl + 2;
+ }
+
off=n;
p+=2;
n+=2;
@@ -2645,6 +2775,44 @@ int ssl3_get_client_key_exchange(SSL *s)
}
else
#endif
+#ifndef OPENSSL_NO_SRP
+ if (alg_k & SSL_kSRP)
+ {
+ int param_len;
+
+ n2s(p,i);
+ param_len=i+2;
+ if (param_len > n)
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH);
+ goto f_err;
+ }
+ if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB);
+ goto err;
+ }
+ if (s->session->srp_username != NULL)
+ OPENSSL_free(s->session->srp_username);
+ s->session->srp_username = BUF_strdup(s->srp_ctx.login);
+ if (s->session->srp_username == NULL)
+ {
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0)
+ {
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ p+=i;
+ }
+ else
+#endif /* OPENSSL_NO_SRP */
if (alg_k & SSL_kGOST)
{
int ret = 0;
@@ -2728,7 +2896,7 @@ int ssl3_get_client_key_exchange(SSL *s)
return(1);
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
-#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH)
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP)
err:
#endif
#ifndef OPENSSL_NO_ECDH
@@ -2749,12 +2917,15 @@ int ssl3_get_cert_verify(SSL *s)
long n;
int type=0,i,j;
X509 *peer;
+ const EVP_MD *md = NULL;
+ EVP_MD_CTX mctx;
+ EVP_MD_CTX_init(&mctx);
n=s->method->ssl_get_message(s,
SSL3_ST_SR_CERT_VRFY_A,
SSL3_ST_SR_CERT_VRFY_B,
-1,
- 514, /* 514? */
+ 516, /* Enough for 4096 bit RSA key with TLS v1.2 */
&ok);
if (!ok) return((int)n);
@@ -2774,7 +2945,7 @@ int ssl3_get_cert_verify(SSL *s)
if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
{
s->s3->tmp.reuse_message=1;
- if ((peer != NULL) && (type | EVP_PKT_SIGN))
+ if ((peer != NULL) && (type & EVP_PKT_SIGN))
{
al=SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
@@ -2817,6 +2988,36 @@ int ssl3_get_cert_verify(SSL *s)
}
else
{
+ if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ {
+ int sigalg = tls12_get_sigid(pkey);
+ /* Should never happen */
+ if (sigalg == -1)
+ {
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR);
+ al=SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
+ /* Check key type is consistent with signature */
+ if (sigalg != (int)p[1])
+ {
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_TYPE);
+ al=SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
+ md = tls12_get_hash(p[0]);
+ if (md == NULL)
+ {
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_UNKNOWN_DIGEST);
+ al=SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
+#ifdef SSL_DEBUG
+fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
+#endif
+ p += 2;
+ n -= 2;
+ }
n2s(p,i);
n-=2;
if (i > n)
@@ -2834,6 +3035,37 @@ int ssl3_get_cert_verify(SSL *s)
goto f_err;
}
+ if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ {
+ long hdatalen = 0;
+ void *hdata;
+ hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+ if (hdatalen <= 0)
+ {
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
+ al=SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
+#ifdef SSL_DEBUG
+ fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n",
+ EVP_MD_name(md));
+#endif
+ if (!EVP_VerifyInit_ex(&mctx, md, NULL)
+ || !EVP_VerifyUpdate(&mctx, hdata, hdatalen))
+ {
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_EVP_LIB);
+ al=SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
+
+ if (EVP_VerifyFinal(&mctx, p , i, pkey) <= 0)
+ {
+ al=SSL_AD_DECRYPT_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_SIGNATURE);
+ goto f_err;
+ }
+ }
+ else
#ifndef OPENSSL_NO_RSA
if (pkey->type == EVP_PKEY_RSA)
{
@@ -2924,6 +3156,13 @@ f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
}
end:
+ if (s->s3->handshake_buffer)
+ {
+ BIO_free(s->s3->handshake_buffer);
+ s->s3->handshake_buffer = NULL;
+ s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE;
+ }
+ EVP_MD_CTX_cleanup(&mctx);
EVP_PKEY_free(pkey);
return(ret);
}
@@ -3036,6 +3275,12 @@ int ssl3_get_client_certificate(SSL *s)
al=SSL_AD_HANDSHAKE_FAILURE;
goto f_err;
}
+ /* No client certificate so digest cached records */
+ if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s))
+ {
+ al=SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
}
else
{
@@ -3112,13 +3357,17 @@ int ssl3_send_server_certificate(SSL *s)
/* SSL3_ST_SW_CERT_B */
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
}
+
#ifndef OPENSSL_NO_TLSEXT
+/* send a new session ticket (not necessarily for a new session) */
int ssl3_send_newsession_ticket(SSL *s)
{
if (s->state == SSL3_ST_SW_SESSION_TICKET_A)
{
unsigned char *p, *senc, *macstart;
- int len, slen;
+ const unsigned char *const_p;
+ int len, slen_full, slen;
+ SSL_SESSION *sess;
unsigned int hlen;
EVP_CIPHER_CTX ctx;
HMAC_CTX hctx;
@@ -3127,12 +3376,38 @@ int ssl3_send_newsession_ticket(SSL *s)
unsigned char key_name[16];
/* get session encoding length */
- slen = i2d_SSL_SESSION(s->session, NULL);
+ slen_full = i2d_SSL_SESSION(s->session, NULL);
/* Some length values are 16 bits, so forget it if session is
* too long
*/
- if (slen > 0xFF00)
+ if (slen_full > 0xFF00)
+ return -1;
+ senc = OPENSSL_malloc(slen_full);
+ if (!senc)
+ return -1;
+ p = senc;
+ i2d_SSL_SESSION(s->session, &p);
+
+ /* create a fresh copy (not shared with other threads) to clean up */
+ const_p = senc;
+ sess = d2i_SSL_SESSION(NULL, &const_p, slen_full);
+ if (sess == NULL)
+ {
+ OPENSSL_free(senc);
return -1;
+ }
+ sess->session_id_length = 0; /* ID is irrelevant for the ticket */
+
+ slen = i2d_SSL_SESSION(sess, NULL);
+ if (slen > slen_full) /* shouldn't ever happen */
+ {
+ OPENSSL_free(senc);
+ return -1;
+ }
+ p = senc;
+ i2d_SSL_SESSION(sess, &p);
+ SSL_SESSION_free(sess);
+
/* Grow buffer if need be: the length calculation is as
* follows 1 (size of message name) + 3 (message length
* bytes) + 4 (ticket lifetime hint) + 2 (ticket length) +
@@ -3144,11 +3419,6 @@ int ssl3_send_newsession_ticket(SSL *s)
26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +
EVP_MAX_MD_SIZE + slen))
return -1;
- senc = OPENSSL_malloc(slen);
- if (!senc)
- return -1;
- p = senc;
- i2d_SSL_SESSION(s->session, &p);
p=(unsigned char *)s->init_buf->data;
/* do the header */
@@ -3179,7 +3449,13 @@ int ssl3_send_newsession_ticket(SSL *s)
tlsext_tick_md(), NULL);
memcpy(key_name, tctx->tlsext_tick_key_name, 16);
}
- l2n(s->session->tlsext_tick_lifetime_hint, p);
+
+ /* Ticket lifetime hint (advisory only):
+ * We leave this unspecified for resumed session (for simplicity),
+ * and guess that tickets for new sessions will live as long
+ * as their sessions. */
+ l2n(s->hit ? 0 : s->session->timeout, p);
+
/* Skip ticket length for now */
p += 2;
/* Output key name */
@@ -3255,13 +3531,13 @@ int ssl3_send_cert_status(SSL *s)
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
}
-# ifndef OPENSSL_NO_NPN
+# ifndef OPENSSL_NO_NEXTPROTONEG
/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It
* sets the next_proto member in s if found */
int ssl3_get_next_proto(SSL *s)
{
int ok;
- unsigned proto_len, padding_len;
+ int proto_len, padding_len;
long n;
const unsigned char *p;
diff --git a/deps/openssl/openssl/ssl/srtp.h b/deps/openssl/openssl/ssl/srtp.h
new file mode 100644
index 000000000..c0cf33ef2
--- /dev/null
+++ b/deps/openssl/openssl/ssl/srtp.h
@@ -0,0 +1,145 @@
+/* ssl/tls1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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).
+ *
+ */
+/*
+ DTLS code by Eric Rescorla <ekr@rtfm.com>
+
+ Copyright (C) 2006, Network Resonance, Inc.
+ Copyright (C) 2011, RTFM, Inc.
+*/
+
+#ifndef HEADER_D1_SRTP_H
+#define HEADER_D1_SRTP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define SRTP_AES128_CM_SHA1_80 0x0001
+#define SRTP_AES128_CM_SHA1_32 0x0002
+#define SRTP_AES128_F8_SHA1_80 0x0003
+#define SRTP_AES128_F8_SHA1_32 0x0004
+#define SRTP_NULL_SHA1_80 0x0005
+#define SRTP_NULL_SHA1_32 0x0006
+
+int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
+int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/deps/openssl/openssl/ssl/ssl-lib.com b/deps/openssl/openssl/ssl/ssl-lib.com
index 180f3a2d8..a77f7707f 100644
--- a/deps/openssl/openssl/ssl/ssl-lib.com
+++ b/deps/openssl/openssl/ssl/ssl-lib.com
@@ -218,11 +218,11 @@ $ LIB_SSL = "s2_meth,s2_srvr,s2_clnt,s2_lib,s2_enc,s2_pkt,"+ -
"s23_meth,s23_srvr,s23_clnt,s23_lib,s23_pkt,"+ -
"t1_meth,t1_srvr,t1_clnt,t1_lib,t1_enc,"+ -
"d1_meth,d1_srvr,d1_clnt,d1_lib,d1_pkt,"+ -
- "d1_both,d1_enc,"+ -
+ "d1_both,d1_enc,d1_srtp,"+ -
"ssl_lib,ssl_err2,ssl_cert,ssl_sess,"+ -
"ssl_ciph,ssl_stat,ssl_rsa,"+ -
"ssl_asn1,ssl_txt,ssl_algs,"+ -
- "bio_ssl,ssl_err,kssl,t1_reneg"
+ "bio_ssl,ssl_err,kssl,tls_srp,t1_reneg"
$!
$ COMPILEWITH_CC5 = ""
$!
diff --git a/deps/openssl/openssl/ssl/ssl.h b/deps/openssl/openssl/ssl/ssl.h
index fdcab6f23..593579ed3 100644
--- a/deps/openssl/openssl/ssl/ssl.h
+++ b/deps/openssl/openssl/ssl/ssl.h
@@ -252,6 +252,7 @@ extern "C" {
#define SSL_TXT_kEECDH "kEECDH"
#define SSL_TXT_kPSK "kPSK"
#define SSL_TXT_kGOST "kGOST"
+#define SSL_TXT_kSRP "kSRP"
#define SSL_TXT_aRSA "aRSA"
#define SSL_TXT_aDSS "aDSS"
@@ -275,6 +276,7 @@ extern "C" {
#define SSL_TXT_ECDSA "ECDSA"
#define SSL_TXT_KRB5 "KRB5"
#define SSL_TXT_PSK "PSK"
+#define SSL_TXT_SRP "SRP"
#define SSL_TXT_DES "DES"
#define SSL_TXT_3DES "3DES"
@@ -285,6 +287,7 @@ extern "C" {
#define SSL_TXT_AES128 "AES128"
#define SSL_TXT_AES256 "AES256"
#define SSL_TXT_AES "AES"
+#define SSL_TXT_AES_GCM "AESGCM"
#define SSL_TXT_CAMELLIA128 "CAMELLIA128"
#define SSL_TXT_CAMELLIA256 "CAMELLIA256"
#define SSL_TXT_CAMELLIA "CAMELLIA"
@@ -294,10 +297,14 @@ extern "C" {
#define SSL_TXT_SHA "SHA" /* same as "SHA1" */
#define SSL_TXT_GOST94 "GOST94"
#define SSL_TXT_GOST89MAC "GOST89MAC"
+#define SSL_TXT_SHA256 "SHA256"
+#define SSL_TXT_SHA384 "SHA384"
#define SSL_TXT_SSLV2 "SSLv2"
#define SSL_TXT_SSLV3 "SSLv3"
#define SSL_TXT_TLSV1 "TLSv1"
+#define SSL_TXT_TLSV1_1 "TLSv1.1"
+#define SSL_TXT_TLSV1_2 "TLSv1.2"
#define SSL_TXT_EXP "EXP"
#define SSL_TXT_EXPORT "EXPORT"
@@ -356,9 +363,29 @@ extern "C" {
* in SSL_CTX. */
typedef struct ssl_st *ssl_crock_st;
typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
+typedef struct ssl_method_st SSL_METHOD;
+typedef struct ssl_cipher_st SSL_CIPHER;
+typedef struct ssl_session_st SSL_SESSION;
+
+DECLARE_STACK_OF(SSL_CIPHER)
+
+/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/
+typedef struct srtp_protection_profile_st
+ {
+ const char *name;
+ unsigned long id;
+ } SRTP_PROTECTION_PROFILE;
+
+DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
+
+typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg);
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
+
+
+#ifndef OPENSSL_NO_SSL_INTERN
/* used to hold info on the particular ciphers used */
-typedef struct ssl_cipher_st
+struct ssl_cipher_st
{
int valid;
const char *name; /* text name */
@@ -375,15 +402,11 @@ typedef struct ssl_cipher_st
unsigned long algorithm2; /* Extra flags */
int strength_bits; /* Number of bits really used */
int alg_bits; /* Number of bits for algorithm */
- } SSL_CIPHER;
+ };
-DECLARE_STACK_OF(SSL_CIPHER)
-
-typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg);
-typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
-typedef struct ssl_method_st
+struct ssl_method_st
{
int version;
int (*ssl_new)(SSL *s);
@@ -416,7 +439,7 @@ typedef struct ssl_method_st
int (*ssl_version)(void);
long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));
long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void));
- } SSL_METHOD;
+ };
/* Lets make this into an ASN.1 type structure as follows
* SSL_SESSION_ID ::= SEQUENCE {
@@ -433,14 +456,17 @@ typedef struct ssl_method_st
* Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context
* Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer'
* HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension
- * ECPointFormatList [ 7 ] OCTET STRING, -- optional EC point format list from TLS extension
- * PSK_identity_hint [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
- * PSK_identity [ 9 ] EXPLICIT OCTET STRING -- optional PSK identity
+ * PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
+ * PSK_identity [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity
+ * Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket
+ * Ticket [10] EXPLICIT OCTET STRING, -- session ticket (clients only)
+ * Compression_meth [11] EXPLICIT OCTET STRING, -- optional compression method
+ * SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username
* }
* Look in ssl/ssl_asn1.c for more details
* I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
*/
-typedef struct ssl_session_st
+struct ssl_session_st
{
int ssl_version; /* what ssl version session info is
* being kept in here? */
@@ -467,6 +493,9 @@ typedef struct ssl_session_st
char *psk_identity_hint;
char *psk_identity;
#endif
+ /* Used to indicate that session resumption is not allowed.
+ * Applications can also set this bit for a new session via
+ * not_resumable_session_cb to disable session caching and tickets. */
int not_resumable;
/* The cert is the certificate used to establish this connection */
@@ -509,11 +538,15 @@ typedef struct ssl_session_st
#endif /* OPENSSL_NO_EC */
/* RFC4507 info */
unsigned char *tlsext_tick; /* Session ticket */
- size_t tlsext_ticklen; /* Session ticket length */
+ size_t tlsext_ticklen; /* Session ticket length */
long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
#endif
- } SSL_SESSION;
+#ifndef OPENSSL_NO_SRP
+ char *srp_username;
+#endif
+ };
+#endif
#define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L
#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L
@@ -536,7 +569,7 @@ typedef struct ssl_session_st
/* SSL_OP_ALL: various bug workarounds that should be rather harmless.
* This used to be 0x000FFFFFL before 0.9.7. */
-#define SSL_OP_ALL 0x80000FFFL
+#define SSL_OP_ALL 0x80000BFFL
/* DTLS options */
#define SSL_OP_NO_QUERY_MTU 0x00001000L
@@ -572,11 +605,17 @@ typedef struct ssl_session_st
#define SSL_OP_NO_SSLv2 0x01000000L
#define SSL_OP_NO_SSLv3 0x02000000L
#define SSL_OP_NO_TLSv1 0x04000000L
+#define SSL_OP_NO_TLSv1_2 0x08000000L
+#define SSL_OP_NO_TLSv1_1 0x10000000L
+/* These next two were never actually used for anything since SSLeay
+ * zap so we have some more flags.
+ */
/* The next flag deliberately changes the ciphertest, this is a check
* for the PKCS#1 attack */
-#define SSL_OP_PKCS1_CHECK_1 0x08000000L
-#define SSL_OP_PKCS1_CHECK_2 0x10000000L
+#define SSL_OP_PKCS1_CHECK_1 0x0
+#define SSL_OP_PKCS1_CHECK_2 0x0
+
#define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L
#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000L
/* Make server add server-hello extension from early version of
@@ -602,13 +641,6 @@ typedef struct ssl_session_st
* TLS only.) "Released" buffers are put onto a free-list in the context
* or just freed (depending on the context's setting for freelist_max_len). */
#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
-/* Use small read and write buffers: (a) lazy allocate read buffers for
- * large incoming records, and (b) limit the size of outgoing records. */
-#define SSL_MODE_SMALL_BUFFERS 0x00000020L
-/* When set, clients may send application data before receipt of CCS
- * and Finished. This mode enables full-handshakes to 'complete' in
- * one RTT. */
-#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000040L
/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
* they cannot be used to clear bits. */
@@ -644,12 +676,53 @@ typedef struct ssl_session_st
#define SSL_get_secure_renegotiation_support(ssl) \
SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
+#ifndef OPENSSL_NO_HEARTBEATS
+#define SSL_heartbeat(ssl) \
+ SSL_ctrl((ssl),SSL_CTRL_TLS_EXT_SEND_HEARTBEAT,0,NULL)
+#endif
+
void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
#define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
#define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+#ifndef OPENSSL_NO_SRP
+#ifndef OPENSSL_NO_SSL_INTERN
+
+typedef struct srp_ctx_st
+ {
+ /* param for all the callbacks */
+ void *SRP_cb_arg;
+ /* set client Hello login callback */
+ int (*TLS_ext_srp_username_callback)(SSL *, int *, void *);
+ /* set SRP N/g param callback for verification */
+ int (*SRP_verify_param_callback)(SSL *, void *);
+ /* set SRP client passwd callback */
+ char *(*SRP_give_srp_client_pwd_callback)(SSL *, void *);
+
+ char *login;
+ BIGNUM *N,*g,*s,*B,*A;
+ BIGNUM *a,*b,*v;
+ char *info;
+ int strength;
+
+ unsigned long srp_Mask;
+ } SRP_CTX;
+
+#endif
+
+/* see tls_srp.c */
+int SSL_SRP_CTX_init(SSL *s);
+int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx);
+int SSL_SRP_CTX_free(SSL *ctx);
+int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx);
+int SSL_srp_server_param_with_username(SSL *s, int *ad);
+int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key);
+int SRP_Calc_A_param(SSL *s);
+int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key);
+
+#endif
#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
#define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */
@@ -675,7 +748,11 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id,
unsigned int *id_len);
-typedef struct ssl_comp_st
+typedef struct ssl_comp_st SSL_COMP;
+
+#ifndef OPENSSL_NO_SSL_INTERN
+
+struct ssl_comp_st
{
int id;
const char *name;
@@ -684,7 +761,7 @@ typedef struct ssl_comp_st
#else
char *method;
#endif
- } SSL_COMP;
+ };
DECLARE_STACK_OF(SSL_COMP)
DECLARE_LHASH_OF(SSL_SESSION);
@@ -857,6 +934,28 @@ struct ssl_ctx_st
/* draft-rescorla-tls-opaque-prf-input-00.txt information */
int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
void *tlsext_opaque_prf_input_callback_arg;
+#endif
+
+#ifndef OPENSSL_NO_PSK
+ char *psk_identity_hint;
+ unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
+ unsigned int max_identity_len, unsigned char *psk,
+ unsigned int max_psk_len);
+ unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+ unsigned char *psk, unsigned int max_psk_len);
+#endif
+
+#ifndef OPENSSL_NO_BUF_FREELISTS
+#define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32
+ unsigned int freelist_max_len;
+ struct ssl3_buf_freelist_st *wbuf_freelist;
+ struct ssl3_buf_freelist_st *rbuf_freelist;
+#endif
+#ifndef OPENSSL_NO_SRP
+ SRP_CTX srp_ctx; /* ctx for SRP authentication */
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT
# ifndef OPENSSL_NO_NEXTPROTONEG
/* Next protocol negotiation information */
@@ -876,24 +975,12 @@ struct ssl_ctx_st
void *arg);
void *next_proto_select_cb_arg;
# endif
+ /* SRTP profiles we are willing to do from RFC 5764 */
+ STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
#endif
+ };
-#ifndef OPENSSL_NO_PSK
- char *psk_identity_hint;
- unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
- unsigned int max_identity_len, unsigned char *psk,
- unsigned int max_psk_len);
- unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
- unsigned char *psk, unsigned int max_psk_len);
-#endif
-
-#ifndef OPENSSL_NO_BUF_FREELISTS
-#define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32
- unsigned int freelist_max_len;
- struct ssl3_buf_freelist_st *wbuf_freelist;
- struct ssl3_buf_freelist_st *rbuf_freelist;
#endif
- };
#define SSL_SESS_CACHE_OFF 0x0000
#define SSL_SESS_CACHE_CLIENT 0x0001
@@ -952,24 +1039,26 @@ void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
int (*cb) (SSL *ssl,
const unsigned char **out,
unsigned int *outlen,
- void *arg), void *arg);
+ void *arg),
+ void *arg);
void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
- int (*cb) (SSL *ssl, unsigned char **out,
+ int (*cb) (SSL *ssl,
+ unsigned char **out,
unsigned char *outlen,
const unsigned char *in,
- unsigned int inlen, void *arg),
+ unsigned int inlen,
+ void *arg),
void *arg);
int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen,
const unsigned char *client, unsigned int client_len);
-void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
- unsigned *len);
+void SSL_get0_next_proto_negotiated(const SSL *s,
+ const unsigned char **data, unsigned *len);
#define OPENSSL_NPN_UNSUPPORTED 0
#define OPENSSL_NPN_NEGOTIATED 1
#define OPENSSL_NPN_NO_OVERLAP 2
-
#endif
#ifndef OPENSSL_NO_PSK
@@ -1011,6 +1100,8 @@ const char *SSL_get_psk_identity(const SSL *s);
#define SSL_MAC_FLAG_READ_MAC_STREAM 1
#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
+#ifndef OPENSSL_NO_SSL_INTERN
+
struct ssl_st
{
/* protocol version
@@ -1055,9 +1146,7 @@ struct ssl_st
int server; /* are we the server side? - mostly used by SSL_clear*/
- int new_session;/* 1 if we are to use a new session.
- * 2 if we are a server and are inside a handshake
- * (i.e. not just sending a HelloRequest)
+ int new_session;/* Generate a new session or reuse an old one.
* NB: For servers, the 'new' session may actually be a previously
* cached session or even the previous session unless
* SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
@@ -1133,9 +1222,6 @@ struct ssl_st
/* This can also be in the session once a session is established */
SSL_SESSION *session;
- /* This can be disabled to prevent the use of uncached sessions */
- int session_creation_enabled;
-
/* Default generate session ID callback. */
GEN_SESSION_CB generate_session_id;
@@ -1244,11 +1330,32 @@ struct ssl_st
#endif
#define session_ctx initial_ctx
+
+ STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; /* What we'll do */
+ SRTP_PROTECTION_PROFILE *srtp_profile; /* What's been chosen */
+
+ unsigned int tlsext_heartbeat; /* Is use of the Heartbeat extension negotiated?
+ 0: disabled
+ 1: enabled
+ 2: enabled, but not allowed to send Requests
+ */
+ unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */
+ unsigned int tlsext_hb_seq; /* HeartbeatRequest sequence number */
#else
#define session_ctx ctx
#endif /* OPENSSL_NO_TLSEXT */
+
+ int renegotiate;/* 1 if we are renegotiating.
+ * 2 if we are a server and are inside a handshake
+ * (i.e. not just sending a HelloRequest) */
+
+#ifndef OPENSSL_NO_SRP
+ SRP_CTX srp_ctx; /* ctx for SRP authentication */
+#endif
};
+#endif
+
#ifdef __cplusplus
}
#endif
@@ -1258,6 +1365,7 @@ struct ssl_st
#include <openssl/tls1.h> /* This is mostly sslv3 with a few tweaks */
#include <openssl/dtls1.h> /* Datagram TLS */
#include <openssl/ssl23.h>
+#include <openssl/srtp.h> /* Support for the use_srtp extension */
#ifdef __cplusplus
extern "C" {
@@ -1303,12 +1411,10 @@ extern "C" {
/* Is the SSL_connection established? */
#define SSL_get_state(a) SSL_state(a)
#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
-#define SSL_in_init(a) ((SSL_state(a)&SSL_ST_INIT) && \
- !SSL_cutthrough_complete(a))
+#define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT)
#define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE)
#define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT)
#define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT)
-int SSL_cutthrough_complete(const SSL *s);
/* The following 2 states are kept in ssl->rstate when reads fail,
* you should not need these */
@@ -1476,6 +1582,20 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72
+
+#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75
+#define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76
+#define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77
+
+#define SSL_CTRL_SET_SRP_ARG 78
+#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79
+#define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80
+#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81
+#ifndef OPENSSL_NO_HEARTBEATS
+#define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT 85
+#define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86
+#define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87
+#endif
#endif
#define DTLS_CTRL_GET_TIMEOUT 73
@@ -1486,6 +1606,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_CLEAR_OPTIONS 77
#define SSL_CTRL_CLEAR_MODE 78
+#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82
+#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83
+
#define DTLSv1_get_timeout(ssl, arg) \
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
#define DTLSv1_handle_timeout(ssl) \
@@ -1522,6 +1645,10 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTX_add_extra_chain_cert(ctx,x509) \
SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
+#define SSL_CTX_get_extra_chain_certs(ctx,px509) \
+ SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509)
+#define SSL_CTX_clear_extra_chain_certs(ctx) \
+ SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL)
#ifndef OPENSSL_NO_BIO
BIO_METHOD *BIO_f_ssl(void);
@@ -1549,7 +1676,7 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
int SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
char * SSL_CIPHER_get_version(const SSL_CIPHER *c);
const char * SSL_CIPHER_get_name(const SSL_CIPHER *c);
-const char * SSL_CIPHER_authentication_method(const SSL_CIPHER *c);
+unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c);
int SSL_get_fd(const SSL *s);
int SSL_get_rfd(const SSL *s);
@@ -1558,7 +1685,6 @@ const char * SSL_get_cipher_list(const SSL *s,int n);
char * SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
int SSL_get_read_ahead(const SSL * s);
int SSL_pending(const SSL *s);
-const char * SSL_authentication_method(const SSL *c);
#ifndef OPENSSL_NO_SOCK
int SSL_set_fd(SSL *s, int fd);
int SSL_set_rfd(SSL *s, int fd);
@@ -1570,7 +1696,6 @@ BIO * SSL_get_rbio(const SSL *s);
BIO * SSL_get_wbio(const SSL *s);
#endif
int SSL_set_cipher_list(SSL *s, const char *str);
-int SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk);
void SSL_set_read_ahead(SSL *s, int yes);
int SSL_get_verify_mode(const SSL *s);
int SSL_get_verify_depth(const SSL *s);
@@ -1586,8 +1711,6 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
int SSL_use_certificate(SSL *ssl, X509 *x);
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
-int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
-STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x);
#ifndef OPENSSL_NO_STDIO
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
@@ -1619,11 +1742,14 @@ long SSL_SESSION_set_time(SSL_SESSION *s, long t);
long SSL_SESSION_get_timeout(const SSL_SESSION *s);
long SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
void SSL_copy_session_id(SSL *to,const SSL *from);
+X509 *SSL_SESSION_get0_peer(SSL_SESSION *s);
+int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
+ unsigned int sid_ctx_len);
SSL_SESSION *SSL_SESSION_new(void);
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
unsigned int *len);
-const char * SSL_SESSION_get_version(const SSL_SESSION *s);
+unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s);
#ifndef OPENSSL_NO_FP_API
int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
#endif
@@ -1633,7 +1759,6 @@ int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
void SSL_SESSION_free(SSL_SESSION *ses);
int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
int SSL_set_session(SSL *to, SSL_SESSION *session);
-void SSL_set_session_creation_enabled(SSL *, int);
int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
int SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
@@ -1687,6 +1812,30 @@ int SSL_set_trust(SSL *s, int trust);
int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
+#ifndef OPENSSL_NO_SRP
+int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name);
+int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password);
+int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength);
+int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
+ char *(*cb)(SSL *,void *));
+int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
+ int (*cb)(SSL *,void *));
+int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
+ int (*cb)(SSL *,int *,void *));
+int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg);
+
+int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
+ BIGNUM *sa, BIGNUM *v, char *info);
+int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
+ const char *grp);
+
+BIGNUM *SSL_get_srp_g(SSL *s);
+BIGNUM *SSL_get_srp_N(SSL *s);
+
+char *SSL_get_srp_username(SSL *s);
+char *SSL_get_srp_userinfo(SSL *s);
+#endif
+
void SSL_free(SSL *ssl);
int SSL_accept(SSL *ssl);
int SSL_connect(SSL *ssl);
@@ -1722,6 +1871,15 @@ const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */
const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */
const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */
+const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */
+const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */
+const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */
+
+const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */
+const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */
+const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */
+
+
const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */
const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */
const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */
@@ -1730,6 +1888,7 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
int SSL_do_handshake(SSL *s);
int SSL_renegotiate(SSL *s);
+int SSL_renegotiate_abbreviated(SSL *s);
int SSL_renegotiate_pending(SSL *s);
int SSL_shutdown(SSL *s);
@@ -1781,6 +1940,7 @@ void SSL_set_info_callback(SSL *ssl,
void (*cb)(const SSL *ssl,int type,int val));
void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,int type,int val);
int SSL_state(const SSL *ssl);
+void SSL_set_state(SSL *ssl, int state);
void SSL_set_verify_result(SSL *ssl,long v);
long SSL_get_verify_result(const SSL *ssl);
@@ -1881,6 +2041,9 @@ int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
/* Pre-shared secret session resumption functions */
int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
+void SSL_set_debug(SSL *s, int debug);
+int SSL_cache_hit(SSL *s);
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@@ -1900,6 +2063,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_DTLS1_ACCEPT 246
#define SSL_F_DTLS1_ADD_CERT_TO_BUF 295
#define SSL_F_DTLS1_BUFFER_RECORD 247
+#define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 316
#define SSL_F_DTLS1_CLIENT_HELLO 248
#define SSL_F_DTLS1_CONNECT 249
#define SSL_F_DTLS1_ENC 250
@@ -1908,6 +2072,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253
#define SSL_F_DTLS1_GET_RECORD 254
#define SSL_F_DTLS1_HANDLE_TIMEOUT 297
+#define SSL_F_DTLS1_HEARTBEAT 305
#define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255
#define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288
#define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256
@@ -1976,7 +2141,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL3_GET_KEY_EXCHANGE 141
#define SSL_F_SSL3_GET_MESSAGE 142
#define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283
-#define SSL_F_SSL3_GET_NEXT_PROTO 304
+#define SSL_F_SSL3_GET_NEXT_PROTO 306
#define SSL_F_SSL3_GET_RECORD 143
#define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144
#define SSL_F_SSL3_GET_SERVER_DONE 145
@@ -2001,10 +2166,12 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL3_WRITE_PENDING 159
#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298
#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277
+#define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307
#define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215
#define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216
#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299
#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278
+#define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308
#define SSL_F_SSL_BAD_METHOD 160
#define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161
#define SSL_F_SSL_CERT_DUP 221
@@ -2021,6 +2188,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_CREATE_CIPHER_LIST 166
#define SSL_F_SSL_CTRL 232
#define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168
+#define SSL_F_SSL_CTX_MAKE_PROFILES 309
#define SSL_F_SSL_CTX_NEW 169
#define SSL_F_SSL_CTX_SET_CIPHER_LIST 269
#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290
@@ -2043,16 +2211,18 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_GET_NEW_SESSION 181
#define SSL_F_SSL_GET_PREV_SESSION 217
#define SSL_F_SSL_GET_SERVER_SEND_CERT 182
+#define SSL_F_SSL_GET_SERVER_SEND_PKEY 317
#define SSL_F_SSL_GET_SIGN_PKEY 183
#define SSL_F_SSL_INIT_WBIO_BUFFER 184
#define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185
#define SSL_F_SSL_NEW 186
#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300
#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302
+#define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT 310
#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301
#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303
+#define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311
#define SSL_F_SSL_PEEK 270
-#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 312
#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281
#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282
#define SSL_F_SSL_READ 223
@@ -2060,6 +2230,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188
#define SSL_F_SSL_SESSION_NEW 189
#define SSL_F_SSL_SESSION_PRINT_FP 190
+#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312
#define SSL_F_SSL_SESS_CERT_NEW 225
#define SSL_F_SSL_SET_CERT 191
#define SSL_F_SSL_SET_CIPHER_LIST 271
@@ -2073,12 +2244,12 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_SET_TRUST 228
#define SSL_F_SSL_SET_WFD 196
#define SSL_F_SSL_SHUTDOWN 224
+#define SSL_F_SSL_SRP_CTX_INIT 313
#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243
#define SSL_F_SSL_UNDEFINED_FUNCTION 197
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
#define SSL_F_SSL_USE_CERTIFICATE 198
#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
-#define SSL_F_SSL_USE_CERTIFICATE_CHAIN 2000
#define SSL_F_SSL_USE_CERTIFICATE_FILE 200
#define SSL_F_SSL_USE_PRIVATEKEY 201
#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202
@@ -2093,6 +2264,8 @@ void ERR_load_SSL_strings(void);
#define SSL_F_TLS1_CHANGE_CIPHER_STATE 209
#define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274
#define SSL_F_TLS1_ENC 210
+#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314
+#define SSL_F_TLS1_HEARTBEAT 315
#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275
#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276
#define SSL_F_TLS1_PRF 284
@@ -2132,6 +2305,13 @@ void ERR_load_SSL_strings(void);
#define SSL_R_BAD_RSA_MODULUS_LENGTH 121
#define SSL_R_BAD_RSA_SIGNATURE 122
#define SSL_R_BAD_SIGNATURE 123
+#define SSL_R_BAD_SRP_A_LENGTH 347
+#define SSL_R_BAD_SRP_B_LENGTH 348
+#define SSL_R_BAD_SRP_G_LENGTH 349
+#define SSL_R_BAD_SRP_N_LENGTH 350
+#define SSL_R_BAD_SRP_S_LENGTH 351
+#define SSL_R_BAD_SRTP_MKI_VALUE 352
+#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353
#define SSL_R_BAD_SSL_FILETYPE 124
#define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125
#define SSL_R_BAD_STATE 126
@@ -2170,14 +2350,15 @@ void ERR_load_SSL_strings(void);
#define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE 322
#define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE 323
#define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310
+#define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354
#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150
#define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282
#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151
#define SSL_R_EXCESSIVE_MESSAGE_SIZE 152
#define SSL_R_EXTRA_DATA_IN_MESSAGE 153
#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154
-#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 346
-#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 347
+#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 355
+#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 356
#define SSL_R_HTTPS_PROXY_REQUEST 155
#define SSL_R_HTTP_REQUEST 156
#define SSL_R_ILLEGAL_PADDING 283
@@ -2186,6 +2367,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_INVALID_COMMAND 280
#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
#define SSL_R_INVALID_PURPOSE 278
+#define SSL_R_INVALID_SRP_USERNAME 357
#define SSL_R_INVALID_STATUS_RESPONSE 328
#define SSL_R_INVALID_TICKET_KEYS_LENGTH 325
#define SSL_R_INVALID_TRUST 279
@@ -2215,6 +2397,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_MISSING_RSA_CERTIFICATE 168
#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169
#define SSL_R_MISSING_RSA_SIGNING_CERT 170
+#define SSL_R_MISSING_SRP_PARAM 358
#define SSL_R_MISSING_TMP_DH_KEY 171
#define SSL_R_MISSING_TMP_ECDH_KEY 311
#define SSL_R_MISSING_TMP_RSA_KEY 172
@@ -2244,6 +2427,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_NO_RENEGOTIATION 339
#define SSL_R_NO_REQUIRED_DIGEST 324
#define SSL_R_NO_SHARED_CIPHER 193
+#define SSL_R_NO_SRTP_PROFILES 359
#define SSL_R_NO_VERIFY_CALLBACK 194
#define SSL_R_NULL_SSL_CTX 195
#define SSL_R_NULL_SSL_METHOD_PASSED 196
@@ -2286,9 +2470,13 @@ void ERR_load_SSL_strings(void);
#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345
#define SSL_R_SERVERHELLO_TLSEXT 275
#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
-#define SSL_R_SESSION_MAY_NOT_BE_CREATED 2000
#define SSL_R_SHORT_READ 219
+#define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360
#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220
+#define SSL_R_SRP_A_CALC 361
+#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362
+#define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363
+#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364
#define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221
#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299
#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321
@@ -2333,6 +2521,8 @@ void ERR_load_SSL_strings(void);
#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112
#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232
+#define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365
+#define SSL_R_TLS_HEARTBEAT_PENDING 366
#define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367
#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157
#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
@@ -2355,6 +2545,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247
#define SSL_R_UNKNOWN_CIPHER_RETURNED 248
#define SSL_R_UNKNOWN_CIPHER_TYPE 249
+#define SSL_R_UNKNOWN_DIGEST 368
#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250
#define SSL_R_UNKNOWN_PKEY_TYPE 251
#define SSL_R_UNKNOWN_PROTOCOL 252
@@ -2369,12 +2560,14 @@ void ERR_load_SSL_strings(void);
#define SSL_R_UNSUPPORTED_PROTOCOL 258
#define SSL_R_UNSUPPORTED_SSL_VERSION 259
#define SSL_R_UNSUPPORTED_STATUS_TYPE 329
+#define SSL_R_USE_SRTP_NOT_NEGOTIATED 369
#define SSL_R_WRITE_BIO_NOT_SET 260
#define SSL_R_WRONG_CIPHER_RETURNED 261
#define SSL_R_WRONG_MESSAGE_TYPE 262
#define SSL_R_WRONG_NUMBER_OF_KEY_BITS 263
#define SSL_R_WRONG_SIGNATURE_LENGTH 264
#define SSL_R_WRONG_SIGNATURE_SIZE 265
+#define SSL_R_WRONG_SIGNATURE_TYPE 370
#define SSL_R_WRONG_SSL_VERSION 266
#define SSL_R_WRONG_VERSION_NUMBER 267
#define SSL_R_X509_LIB 268
diff --git a/deps/openssl/openssl/ssl/ssl2.h b/deps/openssl/openssl/ssl/ssl2.h
index 99a52ea0d..eb25dcb0b 100644
--- a/deps/openssl/openssl/ssl/ssl2.h
+++ b/deps/openssl/openssl/ssl/ssl2.h
@@ -155,6 +155,8 @@ extern "C" {
#define CERT char
#endif
+#ifndef OPENSSL_NO_SSL_INTERN
+
typedef struct ssl2_state_st
{
int three_byte_header;
@@ -219,6 +221,8 @@ typedef struct ssl2_state_st
} tmp;
} SSL2_STATE;
+#endif
+
/* SSLv2 */
/* client */
#define SSL2_ST_SEND_CLIENT_HELLO_A (0x10|SSL_ST_CONNECT)
diff --git a/deps/openssl/openssl/ssl/ssl3.h b/deps/openssl/openssl/ssl/ssl3.h
index d6425e5a5..247e88c2d 100644
--- a/deps/openssl/openssl/ssl/ssl3.h
+++ b/deps/openssl/openssl/ssl/ssl3.h
@@ -280,9 +280,6 @@ extern "C" {
#define SSL3_RT_MAX_EXTRA (16384)
-/* Default buffer length used for writen records. Thus a generated record
- * will contain plaintext no larger than this value. */
-#define SSL3_RT_DEFAULT_PLAIN_LENGTH 2048
/* Maximum plaintext length: defined by SSL/TLS standards */
#define SSL3_RT_MAX_PLAIN_LENGTH 16384
/* Maximum compression overhead: defined by SSL/TLS standards */
@@ -314,13 +311,6 @@ extern "C" {
#define SSL3_RT_MAX_PACKET_SIZE \
(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
-/* Extra space for empty fragment, headers, MAC, and padding. */
-#define SSL3_RT_DEFAULT_WRITE_OVERHEAD 256
-#define SSL3_RT_DEFAULT_PACKET_SIZE 4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
-#if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE
-#error "Insufficient space allocated for write buffers."
-#endif
-
#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54"
#define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52"
@@ -332,6 +322,7 @@ extern "C" {
#define SSL3_RT_ALERT 21
#define SSL3_RT_HANDSHAKE 22
#define SSL3_RT_APPLICATION_DATA 23
+#define TLS1_RT_HEARTBEAT 24
#define SSL3_AL_WARNING 1
#define SSL3_AL_FATAL 2
@@ -349,6 +340,11 @@ extern "C" {
#define SSL3_AD_CERTIFICATE_UNKNOWN 46
#define SSL3_AD_ILLEGAL_PARAMETER 47 /* fatal */
+#define TLS1_HB_REQUEST 1
+#define TLS1_HB_RESPONSE 2
+
+#ifndef OPENSSL_NO_SSL_INTERN
+
typedef struct ssl3_record_st
{
/*r */ int type; /* type of record */
@@ -370,6 +366,8 @@ typedef struct ssl3_buffer_st
int left; /* how many bytes left */
} SSL3_BUFFER;
+#endif
+
#define SSL3_CT_RSA_SIGN 1
#define SSL3_CT_DSS_SIGN 2
#define SSL3_CT_RSA_FIXED_DH 3
@@ -389,6 +387,7 @@ typedef struct ssl3_buffer_st
#define SSL3_FLAGS_POP_BUFFER 0x0004
#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008
#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
+#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020
/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
* restart a handshake because of MS SGC and so prevents us
@@ -401,6 +400,8 @@ typedef struct ssl3_buffer_st
*/
#define SSL3_FLAGS_SGC_RESTART_DONE 0x0040
+#ifndef OPENSSL_NO_SSL_INTERN
+
typedef struct ssl3_state_st
{
long flags;
@@ -476,12 +477,6 @@ typedef struct ssl3_state_st
void *server_opaque_prf_input;
size_t server_opaque_prf_input_len;
-#ifndef OPENSSL_NO_NEXTPROTONEG
- /* Set if we saw the Next Protocol Negotiation extension from
- our peer. */
- int next_proto_neg_seen;
-#endif
-
struct {
/* actually only needs to be 16+20 */
unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
@@ -491,7 +486,7 @@ typedef struct ssl3_state_st
int finish_md_len;
unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2];
int peer_finish_md_len;
-
+
unsigned long message_size;
int message_type;
@@ -539,14 +534,23 @@ typedef struct ssl3_state_st
unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
unsigned char previous_server_finished_len;
int send_connection_binding; /* TODOEKR */
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ /* Set if we saw the Next Protocol Negotiation extension from our peer. */
+ int next_proto_neg_seen;
+#endif
} SSL3_STATE;
+#endif
/* SSLv3 */
/*client */
/* extra state */
#define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT)
-#define SSL3_ST_CUTTHROUGH_COMPLETE (0x101|SSL_ST_CONNECT)
+#ifndef OPENSSL_NO_SCTP
+#define DTLS1_SCTP_ST_CW_WRITE_SOCK (0x310|SSL_ST_CONNECT)
+#define DTLS1_SCTP_ST_CR_READ_SOCK (0x320|SSL_ST_CONNECT)
+#endif
/* write to server */
#define SSL3_ST_CW_CLNT_HELLO_A (0x110|SSL_ST_CONNECT)
#define SSL3_ST_CW_CLNT_HELLO_B (0x111|SSL_ST_CONNECT)
@@ -593,6 +597,10 @@ typedef struct ssl3_state_st
/* server */
/* extra state */
#define SSL3_ST_SW_FLUSH (0x100|SSL_ST_ACCEPT)
+#ifndef OPENSSL_NO_SCTP
+#define DTLS1_SCTP_ST_SW_WRITE_SOCK (0x310|SSL_ST_ACCEPT)
+#define DTLS1_SCTP_ST_SR_READ_SOCK (0x320|SSL_ST_ACCEPT)
+#endif
/* read from client */
/* Do not change the number values, they do matter */
#define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT)
@@ -673,3 +681,4 @@ typedef struct ssl3_state_st
}
#endif
#endif
+
diff --git a/deps/openssl/openssl/ssl/ssl_algs.c b/deps/openssl/openssl/ssl/ssl_algs.c
index 0967b2dfe..9c34d1972 100644
--- a/deps/openssl/openssl/ssl/ssl_algs.c
+++ b/deps/openssl/openssl/ssl/ssl_algs.c
@@ -73,6 +73,9 @@ int SSL_library_init(void)
#endif
#ifndef OPENSSL_NO_RC4
EVP_add_cipher(EVP_rc4());
+#if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__))
+ EVP_add_cipher(EVP_rc4_hmac_md5());
+#endif
#endif
#ifndef OPENSSL_NO_RC2
EVP_add_cipher(EVP_rc2_cbc());
@@ -85,6 +88,13 @@ int SSL_library_init(void)
EVP_add_cipher(EVP_aes_128_cbc());
EVP_add_cipher(EVP_aes_192_cbc());
EVP_add_cipher(EVP_aes_256_cbc());
+ EVP_add_cipher(EVP_aes_128_gcm());
+ EVP_add_cipher(EVP_aes_256_gcm());
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+ EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
+ EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
+#endif
+
#endif
#ifndef OPENSSL_NO_CAMELLIA
EVP_add_cipher(EVP_camellia_128_cbc());
diff --git a/deps/openssl/openssl/ssl/ssl_asn1.c b/deps/openssl/openssl/ssl/ssl_asn1.c
index d7f4c6087..38540be1e 100644
--- a/deps/openssl/openssl/ssl/ssl_asn1.c
+++ b/deps/openssl/openssl/ssl/ssl_asn1.c
@@ -114,6 +114,9 @@ typedef struct ssl_session_asn1_st
ASN1_OCTET_STRING psk_identity_hint;
ASN1_OCTET_STRING psk_identity;
#endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+ ASN1_OCTET_STRING srp_username;
+#endif /* OPENSSL_NO_SRP */
} SSL_SESSION_ASN1;
int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
@@ -130,6 +133,9 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
unsigned char cbuf;
int v11=0;
#endif
+#ifndef OPENSSL_NO_SRP
+ int v12=0;
+#endif
long l;
SSL_SESSION_ASN1 a;
M_ASN1_I2D_vars(in);
@@ -267,6 +273,14 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
a.psk_identity.data=(unsigned char *)(in->psk_identity);
}
#endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+ if (in->srp_username)
+ {
+ a.srp_username.length=strlen(in->srp_username);
+ a.srp_username.type=V_ASN1_OCTET_STRING;
+ a.srp_username.data=(unsigned char *)(in->srp_username);
+ }
+#endif /* OPENSSL_NO_SRP */
M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER);
M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER);
@@ -307,6 +321,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
if (in->psk_identity)
M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
#endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+ if (in->srp_username)
+ M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
+#endif /* OPENSSL_NO_SRP */
M_ASN1_I2D_seq_total();
@@ -351,6 +369,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
if (in->compress_meth)
M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
#endif
+#ifndef OPENSSL_NO_SRP
+ if (in->srp_username)
+ M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
+#endif /* OPENSSL_NO_SRP */
M_ASN1_I2D_finish();
}
@@ -549,6 +571,19 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
}
else
ret->psk_identity_hint=NULL;
+
+ os.length=0;
+ os.data=NULL;
+ M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,8);
+ if (os.data)
+ {
+ ret->psk_identity = BUF_strndup((char *)os.data, os.length);
+ OPENSSL_free(os.data);
+ os.data = NULL;
+ os.length = 0;
+ }
+ else
+ ret->psk_identity=NULL;
#endif /* OPENSSL_NO_PSK */
#ifndef OPENSSL_NO_TLSEXT
@@ -588,5 +623,20 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
}
#endif
+#ifndef OPENSSL_NO_SRP
+ os.length=0;
+ os.data=NULL;
+ M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,12);
+ if (os.data)
+ {
+ ret->srp_username = BUF_strndup((char *)os.data, os.length);
+ OPENSSL_free(os.data);
+ os.data = NULL;
+ os.length = 0;
+ }
+ else
+ ret->srp_username=NULL;
+#endif /* OPENSSL_NO_SRP */
+
M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
}
diff --git a/deps/openssl/openssl/ssl/ssl_cert.c b/deps/openssl/openssl/ssl/ssl_cert.c
index 27256eea8..5123a8918 100644
--- a/deps/openssl/openssl/ssl/ssl_cert.c
+++ b/deps/openssl/openssl/ssl/ssl_cert.c
@@ -160,6 +160,21 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void)
return ssl_x509_store_ctx_idx;
}
+static void ssl_cert_set_default_md(CERT *cert)
+ {
+ /* Set digest values to defaults */
+#ifndef OPENSSL_NO_DSA
+ cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_RSA
+ cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
+ cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
+#endif
+ }
+
CERT *ssl_cert_new(void)
{
CERT *ret;
@@ -174,7 +189,7 @@ CERT *ssl_cert_new(void)
ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
ret->references=1;
-
+ ssl_cert_set_default_md(ret);
return(ret);
}
@@ -307,6 +322,10 @@ CERT *ssl_cert_dup(CERT *cert)
* chain is held inside SSL_CTX */
ret->references=1;
+ /* Set digests to defaults. NB: we don't copy existing values as they
+ * will be set during handshake.
+ */
+ ssl_cert_set_default_md(ret);
return(ret);
diff --git a/deps/openssl/openssl/ssl/ssl_ciph.c b/deps/openssl/openssl/ssl/ssl_ciph.c
index 462c45a3d..0aba8e048 100644
--- a/deps/openssl/openssl/ssl/ssl_ciph.c
+++ b/deps/openssl/openssl/ssl/ssl_ciph.c
@@ -162,11 +162,13 @@
#define SSL_ENC_CAMELLIA256_IDX 9
#define SSL_ENC_GOST89_IDX 10
#define SSL_ENC_SEED_IDX 11
-#define SSL_ENC_NUM_IDX 12
+#define SSL_ENC_AES128GCM_IDX 12
+#define SSL_ENC_AES256GCM_IDX 13
+#define SSL_ENC_NUM_IDX 14
static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
};
#define SSL_COMP_NULL_IDX 0
@@ -179,28 +181,32 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL;
#define SSL_MD_SHA1_IDX 1
#define SSL_MD_GOST94_IDX 2
#define SSL_MD_GOST89MAC_IDX 3
+#define SSL_MD_SHA256_IDX 4
+#define SSL_MD_SHA384_IDX 5
/*Constant SSL_MAX_DIGEST equal to size of digests array should be
* defined in the
* ssl_locl.h */
#define SSL_MD_NUM_IDX SSL_MAX_DIGEST
static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
- NULL,NULL,NULL,NULL
+ NULL,NULL,NULL,NULL,NULL,NULL
};
/* PKEY_TYPE for GOST89MAC is known in advance, but, because
* implementation is engine-provided, we'll fill it only if
* corresponding EVP_PKEY_METHOD is found
*/
static int ssl_mac_pkey_id[SSL_MD_NUM_IDX]={
- EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef
+ EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef,
+ EVP_PKEY_HMAC,EVP_PKEY_HMAC
};
static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={
- 0,0,0,0
+ 0,0,0,0,0,0
};
static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={
SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA,
- SSL_HANDSHAKE_MAC_GOST94,0
+ SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256,
+ SSL_HANDSHAKE_MAC_SHA384
};
#define CIPHER_ADD 1
@@ -247,6 +253,7 @@ static const SSL_CIPHER cipher_aliases[]={
{0,SSL_TXT_ECDH,0, SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,0,0,0,0,0,0,0,0},
{0,SSL_TXT_kPSK,0, SSL_kPSK, 0,0,0,0,0,0,0,0},
+ {0,SSL_TXT_kSRP,0, SSL_kSRP, 0,0,0,0,0,0,0,0},
{0,SSL_TXT_kGOST,0, SSL_kGOST,0,0,0,0,0,0,0,0},
/* server authentication aliases */
@@ -273,6 +280,7 @@ static const SSL_CIPHER cipher_aliases[]={
{0,SSL_TXT_ADH,0, SSL_kEDH,SSL_aNULL,0,0,0,0,0,0,0},
{0,SSL_TXT_AECDH,0, SSL_kEECDH,SSL_aNULL,0,0,0,0,0,0,0},
{0,SSL_TXT_PSK,0, SSL_kPSK,SSL_aPSK,0,0,0,0,0,0,0},
+ {0,SSL_TXT_SRP,0, SSL_kSRP,0,0,0,0,0,0,0,0},
/* symmetric encryption aliases */
@@ -283,9 +291,10 @@ static const SSL_CIPHER cipher_aliases[]={
{0,SSL_TXT_IDEA,0, 0,0,SSL_IDEA, 0,0,0,0,0,0},
{0,SSL_TXT_SEED,0, 0,0,SSL_SEED, 0,0,0,0,0,0},
{0,SSL_TXT_eNULL,0, 0,0,SSL_eNULL, 0,0,0,0,0,0},
- {0,SSL_TXT_AES128,0, 0,0,SSL_AES128,0,0,0,0,0,0},
- {0,SSL_TXT_AES256,0, 0,0,SSL_AES256,0,0,0,0,0,0},
- {0,SSL_TXT_AES,0, 0,0,SSL_AES128|SSL_AES256,0,0,0,0,0,0},
+ {0,SSL_TXT_AES128,0, 0,0,SSL_AES128|SSL_AES128GCM,0,0,0,0,0,0},
+ {0,SSL_TXT_AES256,0, 0,0,SSL_AES256|SSL_AES256GCM,0,0,0,0,0,0},
+ {0,SSL_TXT_AES,0, 0,0,SSL_AES,0,0,0,0,0,0},
+ {0,SSL_TXT_AES_GCM,0, 0,0,SSL_AES128GCM|SSL_AES256GCM,0,0,0,0,0,0},
{0,SSL_TXT_CAMELLIA128,0,0,0,SSL_CAMELLIA128,0,0,0,0,0,0},
{0,SSL_TXT_CAMELLIA256,0,0,0,SSL_CAMELLIA256,0,0,0,0,0,0},
{0,SSL_TXT_CAMELLIA ,0,0,0,SSL_CAMELLIA128|SSL_CAMELLIA256,0,0,0,0,0,0},
@@ -296,11 +305,14 @@ static const SSL_CIPHER cipher_aliases[]={
{0,SSL_TXT_SHA,0, 0,0,0,SSL_SHA1, 0,0,0,0,0},
{0,SSL_TXT_GOST94,0, 0,0,0,SSL_GOST94, 0,0,0,0,0},
{0,SSL_TXT_GOST89MAC,0, 0,0,0,SSL_GOST89MAC, 0,0,0,0,0},
+ {0,SSL_TXT_SHA256,0, 0,0,0,SSL_SHA256, 0,0,0,0,0},
+ {0,SSL_TXT_SHA384,0, 0,0,0,SSL_SHA384, 0,0,0,0,0},
/* protocol version aliases */
{0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0},
{0,SSL_TXT_SSLV3,0, 0,0,0,0,SSL_SSLV3, 0,0,0,0},
{0,SSL_TXT_TLSV1,0, 0,0,0,0,SSL_TLSV1, 0,0,0,0},
+ {0,SSL_TXT_TLSV1_2,0, 0,0,0,0,SSL_TLSV1_2, 0,0,0,0},
/* export flag */
{0,SSL_TXT_EXP,0, 0,0,0,0,0,SSL_EXPORT,0,0,0},
@@ -379,6 +391,11 @@ void ssl_load_ciphers(void)
ssl_cipher_methods[SSL_ENC_SEED_IDX]=
EVP_get_cipherbyname(SN_seed_cbc);
+ ssl_cipher_methods[SSL_ENC_AES128GCM_IDX]=
+ EVP_get_cipherbyname(SN_aes_128_gcm);
+ ssl_cipher_methods[SSL_ENC_AES256GCM_IDX]=
+ EVP_get_cipherbyname(SN_aes_256_gcm);
+
ssl_digest_methods[SSL_MD_MD5_IDX]=
EVP_get_digestbyname(SN_md5);
ssl_mac_secret_size[SSL_MD_MD5_IDX]=
@@ -404,6 +421,14 @@ void ssl_load_ciphers(void)
ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX]=32;
}
+ ssl_digest_methods[SSL_MD_SHA256_IDX]=
+ EVP_get_digestbyname(SN_sha256);
+ ssl_mac_secret_size[SSL_MD_SHA256_IDX]=
+ EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]);
+ ssl_digest_methods[SSL_MD_SHA384_IDX]=
+ EVP_get_digestbyname(SN_sha384);
+ ssl_mac_secret_size[SSL_MD_SHA384_IDX]=
+ EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]);
}
#ifndef OPENSSL_NO_COMP
@@ -526,6 +551,12 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
case SSL_SEED:
i=SSL_ENC_SEED_IDX;
break;
+ case SSL_AES128GCM:
+ i=SSL_ENC_AES128GCM_IDX;
+ break;
+ case SSL_AES256GCM:
+ i=SSL_ENC_AES256GCM_IDX;
+ break;
default:
i= -1;
break;
@@ -549,6 +580,12 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
case SSL_SHA1:
i=SSL_MD_SHA1_IDX;
break;
+ case SSL_SHA256:
+ i=SSL_MD_SHA256_IDX;
+ break;
+ case SSL_SHA384:
+ i=SSL_MD_SHA384_IDX;
+ break;
case SSL_GOST94:
i = SSL_MD_GOST94_IDX;
break;
@@ -564,17 +601,45 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
*md=NULL;
if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef;
if (mac_secret_size!=NULL) *mac_secret_size = 0;
-
+ if (c->algorithm_mac == SSL_AEAD)
+ mac_pkey_type = NULL;
}
else
{
*md=ssl_digest_methods[i];
if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i];
if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i];
- }
+ }
+
+ if ((*enc != NULL) &&
+ (*md != NULL || (EVP_CIPHER_flags(*enc)&EVP_CIPH_FLAG_AEAD_CIPHER)) &&
+ (!mac_pkey_type||*mac_pkey_type != NID_undef))
+ {
+ const EVP_CIPHER *evp;
+
+ if (s->ssl_version>>8 != TLS1_VERSION_MAJOR ||
+ s->ssl_version < TLS1_VERSION)
+ return 1;
- if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type != NID_undef))
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return 1;
+#endif
+
+ if (c->algorithm_enc == SSL_RC4 &&
+ c->algorithm_mac == SSL_MD5 &&
+ (evp=EVP_get_cipherbyname("RC4-HMAC-MD5")))
+ *enc = evp, *md = NULL;
+ else if (c->algorithm_enc == SSL_AES128 &&
+ c->algorithm_mac == SSL_SHA1 &&
+ (evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
+ *enc = evp, *md = NULL;
+ else if (c->algorithm_enc == SSL_AES256 &&
+ c->algorithm_mac == SSL_SHA1 &&
+ (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
+ *enc = evp, *md = NULL;
return(1);
+ }
else
return(0);
}
@@ -585,9 +650,11 @@ int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md)
{
return 0;
}
- if (ssl_handshake_digest_flag[idx]==0) return 0;
*mask = ssl_handshake_digest_flag[idx];
- *md = ssl_digest_methods[idx];
+ if (*mask)
+ *md = ssl_digest_methods[idx];
+ else
+ *md = NULL;
return 1;
}
@@ -662,6 +729,9 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un
*mkey |= SSL_kPSK;
*auth |= SSL_aPSK;
#endif
+#ifdef OPENSSL_NO_SRP
+ *mkey |= SSL_kSRP;
+#endif
/* Check for presence of GOST 34.10 algorithms, and if they
* do not present, disable appropriate auth and key exchange */
if (!get_optional_pkey_id("gost94")) {
@@ -687,6 +757,8 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un
*enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
*enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128:0;
*enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256:0;
+ *enc |= (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == NULL) ? SSL_AES128GCM:0;
+ *enc |= (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == NULL) ? SSL_AES256GCM:0;
*enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128:0;
*enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256:0;
*enc |= (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == NULL) ? SSL_eGOST2814789CNT:0;
@@ -694,6 +766,8 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un
*mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
*mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
+ *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256:0;
+ *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384:0;
*mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94:0;
*mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef)? SSL_GOST89MAC:0;
@@ -724,6 +798,9 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
c = ssl_method->get_cipher(i);
/* drop those that use any of that is not available */
if ((c != NULL) && c->valid &&
+#ifdef OPENSSL_FIPS
+ (!FIPS_mode() || (c->algo_strength & SSL_FIPS)) &&
+#endif
!(c->algorithm_mkey & disabled_mkey) &&
!(c->algorithm_auth & disabled_auth) &&
!(c->algorithm_enc & disabled_enc) &&
@@ -1074,9 +1151,9 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
while ( ((ch >= 'A') && (ch <= 'Z')) ||
((ch >= '0') && (ch <= '9')) ||
((ch >= 'a') && (ch <= 'z')) ||
- (ch == '-'))
+ (ch == '-') || (ch == '.'))
#else
- while ( isalnum(ch) || (ch == '-'))
+ while ( isalnum(ch) || (ch == '-') || (ch == '.'))
#endif
{
ch = *(++l);
@@ -1423,7 +1500,11 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
*/
for (curr = head; curr != NULL; curr = curr->next)
{
+#ifdef OPENSSL_FIPS
+ if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS))
+#else
if (curr->active)
+#endif
{
sk_SSL_CIPHER_push(cipherstack, curr->cipher);
#ifdef CIPHER_DEBUG
@@ -1480,6 +1561,8 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
ver="SSLv2";
else if (alg_ssl & SSL_SSLV3)
ver="SSLv3";
+ else if (alg_ssl & SSL_TLSV1_2)
+ ver="TLSv1.2";
else
ver="unknown";
@@ -1512,6 +1595,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_kPSK:
kx="PSK";
break;
+ case SSL_kSRP:
+ kx="SRP";
+ break;
default:
kx="unknown";
}
@@ -1574,6 +1660,12 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_AES256:
enc="AES(256)";
break;
+ case SSL_AES128GCM:
+ enc="AESGCM(128)";
+ break;
+ case SSL_AES256GCM:
+ enc="AESGCM(256)";
+ break;
case SSL_CAMELLIA128:
enc="Camellia(128)";
break;
@@ -1596,6 +1688,15 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_SHA1:
mac="SHA1";
break;
+ case SSL_SHA256:
+ mac="SHA256";
+ break;
+ case SSL_SHA384:
+ mac="SHA384";
+ break;
+ case SSL_AEAD:
+ mac="AEAD";
+ break;
default:
mac="unknown";
break;
@@ -1653,50 +1754,9 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
return(ret);
}
-/* return string version of key exchange algorithm */
-const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher)
+unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c)
{
- switch (cipher->algorithm_mkey)
- {
- case SSL_kRSA:
- return SSL_TXT_RSA;
- case SSL_kDHr:
- return SSL_TXT_DH "_" SSL_TXT_RSA;
- case SSL_kDHd:
- return SSL_TXT_DH "_" SSL_TXT_DSS;
- case SSL_kEDH:
- switch (cipher->algorithm_auth)
- {
- case SSL_aDSS:
- return "DHE_" SSL_TXT_DSS;
- case SSL_aRSA:
- return "DHE_" SSL_TXT_RSA;
- case SSL_aNULL:
- return SSL_TXT_DH "_anon";
- default:
- return "UNKNOWN";
- }
- case SSL_kKRB5:
- return SSL_TXT_KRB5;
- case SSL_kECDHr:
- return SSL_TXT_ECDH "_" SSL_TXT_RSA;
- case SSL_kECDHe:
- return SSL_TXT_ECDH "_" SSL_TXT_ECDSA;
- case SSL_kEECDH:
- switch (cipher->algorithm_auth)
- {
- case SSL_aECDSA:
- return "ECDHE_" SSL_TXT_ECDSA;
- case SSL_aRSA:
- return "ECDHE_" SSL_TXT_RSA;
- case SSL_aNULL:
- return SSL_TXT_ECDH "_anon";
- default:
- return "UNKNOWN";
- }
- default:
- return "UNKNOWN";
- }
+ return c->id;
}
SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
diff --git a/deps/openssl/openssl/ssl/ssl_err.c b/deps/openssl/openssl/ssl/ssl_err.c
index 4fcd5c007..370fb57e3 100644
--- a/deps/openssl/openssl/ssl/ssl_err.c
+++ b/deps/openssl/openssl/ssl/ssl_err.c
@@ -80,6 +80,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_DTLS1_ACCEPT), "DTLS1_ACCEPT"},
{ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF), "DTLS1_ADD_CERT_TO_BUF"},
{ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "DTLS1_BUFFER_RECORD"},
+{ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM), "DTLS1_CHECK_TIMEOUT_NUM"},
{ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO), "DTLS1_CLIENT_HELLO"},
{ERR_FUNC(SSL_F_DTLS1_CONNECT), "DTLS1_CONNECT"},
{ERR_FUNC(SSL_F_DTLS1_ENC), "DTLS1_ENC"},
@@ -88,6 +89,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), "DTLS1_GET_MESSAGE_FRAGMENT"},
{ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "DTLS1_GET_RECORD"},
{ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "DTLS1_HANDLE_TIMEOUT"},
+{ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "DTLS1_HEARTBEAT"},
{ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"},
{ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"},
{ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"},
@@ -181,10 +183,12 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "SSL3_WRITE_PENDING"},
{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT), "SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"},
{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT), "SSL_ADD_CLIENTHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT), "SSL_ADD_CLIENTHELLO_USE_SRTP_EXT"},
{ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK), "SSL_add_dir_cert_subjects_to_stack"},
{ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK), "SSL_add_file_cert_subjects_to_stack"},
{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT), "SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT"},
{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT), "SSL_ADD_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT), "SSL_ADD_SERVERHELLO_USE_SRTP_EXT"},
{ERR_FUNC(SSL_F_SSL_BAD_METHOD), "SSL_BAD_METHOD"},
{ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "SSL_BYTES_TO_CIPHER_LIST"},
{ERR_FUNC(SSL_F_SSL_CERT_DUP), "SSL_CERT_DUP"},
@@ -201,6 +205,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST), "SSL_CREATE_CIPHER_LIST"},
{ERR_FUNC(SSL_F_SSL_CTRL), "SSL_ctrl"},
{ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY), "SSL_CTX_check_private_key"},
+{ERR_FUNC(SSL_F_SSL_CTX_MAKE_PROFILES), "SSL_CTX_MAKE_PROFILES"},
{ERR_FUNC(SSL_F_SSL_CTX_NEW), "SSL_CTX_new"},
{ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST), "SSL_CTX_set_cipher_list"},
{ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE), "SSL_CTX_set_client_cert_engine"},
@@ -223,14 +228,17 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "SSL_GET_NEW_SESSION"},
{ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "SSL_GET_PREV_SESSION"},
{ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT), "SSL_GET_SERVER_SEND_CERT"},
+{ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "SSL_GET_SERVER_SEND_PKEY"},
{ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "SSL_GET_SIGN_PKEY"},
{ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"},
{ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"},
{ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"},
{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT), "SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT"},
{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT), "SSL_PARSE_CLIENTHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT), "SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT"},
{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT), "SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT"},
{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT), "SSL_PARSE_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT), "SSL_PARSE_SERVERHELLO_USE_SRTP_EXT"},
{ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"},
{ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT), "SSL_PREPARE_CLIENTHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT), "SSL_PREPARE_SERVERHELLO_TLSEXT"},
@@ -239,6 +247,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"},
{ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"},
{ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
+{ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"},
{ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "SSL_SESS_CERT_NEW"},
{ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"},
{ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"},
@@ -252,6 +261,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"},
{ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"},
{ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"},
+{ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_init"},
{ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), "SSL_UNDEFINED_CONST_FUNCTION"},
{ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "SSL_UNDEFINED_FUNCTION"},
{ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), "SSL_UNDEFINED_VOID_FUNCTION"},
@@ -271,6 +281,8 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "TLS1_CHANGE_CIPHER_STATE"},
{ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), "TLS1_CHECK_SERVERHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"},
+{ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), "TLS1_EXPORT_KEYING_MATERIAL"},
+{ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "SSL_F_TLS1_HEARTBEAT"},
{ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), "TLS1_PREPARE_CLIENTHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), "TLS1_PREPARE_SERVERHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"},
@@ -313,6 +325,13 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH),"bad rsa modulus length"},
{ERR_REASON(SSL_R_BAD_RSA_SIGNATURE) ,"bad rsa signature"},
{ERR_REASON(SSL_R_BAD_SIGNATURE) ,"bad signature"},
+{ERR_REASON(SSL_R_BAD_SRP_A_LENGTH) ,"bad srp a length"},
+{ERR_REASON(SSL_R_BAD_SRP_B_LENGTH) ,"bad srp b length"},
+{ERR_REASON(SSL_R_BAD_SRP_G_LENGTH) ,"bad srp g length"},
+{ERR_REASON(SSL_R_BAD_SRP_N_LENGTH) ,"bad srp n length"},
+{ERR_REASON(SSL_R_BAD_SRP_S_LENGTH) ,"bad srp s length"},
+{ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE) ,"bad srtp mki value"},
+{ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST),"bad srtp protection profile list"},
{ERR_REASON(SSL_R_BAD_SSL_FILETYPE) ,"bad ssl filetype"},
{ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH),"bad ssl session id length"},
{ERR_REASON(SSL_R_BAD_STATE) ,"bad state"},
@@ -351,6 +370,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE),"ecc cert should have rsa signature"},
{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE),"ecc cert should have sha1 signature"},
{ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER),"ecgroup too large for cipher"},
+{ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST),"empty srtp protection profile list"},
{ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"},
{ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),"error generating tmp rsa key"},
{ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST),"error in received cipher list"},
@@ -367,6 +387,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
{ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"},
+{ERR_REASON(SSL_R_INVALID_SRP_USERNAME) ,"invalid srp username"},
{ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"},
{ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"},
{ERR_REASON(SSL_R_INVALID_TRUST) ,"invalid trust"},
@@ -396,6 +417,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE),"missing rsa certificate"},
{ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT),"missing rsa encrypting cert"},
{ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT),"missing rsa signing cert"},
+{ERR_REASON(SSL_R_MISSING_SRP_PARAM) ,"can't find SRP server param"},
{ERR_REASON(SSL_R_MISSING_TMP_DH_KEY) ,"missing tmp dh key"},
{ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY) ,"missing tmp ecdh key"},
{ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) ,"missing tmp rsa key"},
@@ -425,6 +447,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_NO_RENEGOTIATION) ,"no renegotiation"},
{ERR_REASON(SSL_R_NO_REQUIRED_DIGEST) ,"digest requred for handshake isn't computed"},
{ERR_REASON(SSL_R_NO_SHARED_CIPHER) ,"no shared cipher"},
+{ERR_REASON(SSL_R_NO_SRTP_PROFILES) ,"no srtp profiles"},
{ERR_REASON(SSL_R_NO_VERIFY_CALLBACK) ,"no verify callback"},
{ERR_REASON(SSL_R_NULL_SSL_CTX) ,"null ssl ctx"},
{ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED),"null ssl method passed"},
@@ -467,9 +490,13 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"},
{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
-{ERR_REASON(SSL_R_SESSION_MAY_NOT_BE_CREATED),"session may not be created"},
{ERR_REASON(SSL_R_SHORT_READ) ,"short read"},
+{ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR),"signature algorithms error"},
{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
+{ERR_REASON(SSL_R_SRP_A_CALC) ,"error with the srp params"},
+{ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES),"srtp could not allocate profiles"},
+{ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG),"srtp protection profile list too long"},
+{ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE),"srtp unknown protection profile"},
{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
{ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2 connection id too long"},
{ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT),"ssl3 ext invalid ecpointformat"},
@@ -514,6 +541,9 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME),"tlsv1 unrecognized name"},
{ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),"tlsv1 unsupported extension"},
{ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),"tls client cert req with anon cipher"},
+{ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT),"peer does not accept heartbearts"},
+{ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING) ,"heartbeat request already pending"},
+{ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL),"tls illegal exporter label"},
{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"},
{ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),"tls peer did not respond with certificate list"},
{ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),"tls rsa encrypted value length is wrong"},
@@ -535,6 +565,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE),"unknown certificate type"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED),"unknown cipher returned"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) ,"unknown cipher type"},
+{ERR_REASON(SSL_R_UNKNOWN_DIGEST) ,"unknown digest"},
{ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE),"unknown key exchange type"},
{ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE) ,"unknown pkey type"},
{ERR_REASON(SSL_R_UNKNOWN_PROTOCOL) ,"unknown protocol"},
@@ -549,12 +580,14 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL) ,"unsupported protocol"},
{ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION),"unsupported ssl version"},
{ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE),"unsupported status type"},
+{ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED),"use srtp not negotiated"},
{ERR_REASON(SSL_R_WRITE_BIO_NOT_SET) ,"write bio not set"},
{ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) ,"wrong cipher returned"},
{ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE) ,"wrong message type"},
{ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS),"wrong number of key bits"},
{ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
{ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE) ,"wrong signature size"},
+{ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE) ,"wrong signature type"},
{ERR_REASON(SSL_R_WRONG_SSL_VERSION) ,"wrong ssl version"},
{ERR_REASON(SSL_R_WRONG_VERSION_NUMBER) ,"wrong version number"},
{ERR_REASON(SSL_R_X509_LIB) ,"x509 lib"},
diff --git a/deps/openssl/openssl/ssl/ssl_lib.c b/deps/openssl/openssl/ssl/ssl_lib.c
index add3058fc..14d143da0 100644
--- a/deps/openssl/openssl/ssl/ssl_lib.c
+++ b/deps/openssl/openssl/ssl/ssl_lib.c
@@ -176,7 +176,10 @@ SSL3_ENC_METHOD ssl3_undef_enc_method={
0, /* client_finished_label_len */
NULL, /* server_finished_label */
0, /* server_finished_label_len */
- (int (*)(int))ssl_undefined_function
+ (int (*)(int))ssl_undefined_function,
+ (int (*)(SSL *, unsigned char *, size_t, const char *,
+ size_t, const unsigned char *, size_t,
+ int use_context)) ssl_undefined_function,
};
int SSL_clear(SSL *s)
@@ -202,9 +205,9 @@ int SSL_clear(SSL *s)
* needed because SSL_clear is not called when doing renegotiation) */
/* This is set if we are doing dynamic renegotiation so keep
* the old cipher. It is sort of a SSL_clear_lite :-) */
- if (s->new_session) return(1);
+ if (s->renegotiate) return(1);
#else
- if (s->new_session)
+ if (s->renegotiate)
{
SSLerr(SSL_F_SSL_CLEAR,ERR_R_INTERNAL_ERROR);
return 0;
@@ -326,7 +329,6 @@ SSL *SSL_new(SSL_CTX *ctx)
OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
s->verify_callback=ctx->default_verify_callback;
- s->session_creation_enabled=1;
s->generate_session_id=ctx->generate_session_id;
s->param = X509_VERIFY_PARAM_new();
@@ -595,6 +597,11 @@ void SSL_free(SSL *s)
OPENSSL_free(s->next_proto_negotiated);
#endif
+#ifndef OPENSSL_NO_SRTP
+ if (s->srtp_profiles)
+ sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
+#endif
+
OPENSSL_free(s);
}
@@ -1017,10 +1024,21 @@ int SSL_shutdown(SSL *s)
int SSL_renegotiate(SSL *s)
{
- if (s->new_session == 0)
- {
- s->new_session=1;
- }
+ if (s->renegotiate == 0)
+ s->renegotiate=1;
+
+ s->new_session=1;
+
+ return(s->method->ssl_renegotiate(s));
+ }
+
+int SSL_renegotiate_abbreviated(SSL *s)
+ {
+ if (s->renegotiate == 0)
+ s->renegotiate=1;
+
+ s->new_session=0;
+
return(s->method->ssl_renegotiate(s));
}
@@ -1028,7 +1046,7 @@ int SSL_renegotiate_pending(SSL *s)
{
/* becomes true when negotiation is requested;
* false again once a handshake has finished */
- return (s->new_session != 0);
+ return (s->renegotiate != 0);
}
long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
@@ -1317,32 +1335,6 @@ int SSL_set_cipher_list(SSL *s,const char *str)
return 1;
}
-/** specify the ciphers to be used by the SSL */
-int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk)
- {
- STACK_OF(SSL_CIPHER) *tmp_cipher_list;
-
- if (sk == NULL)
- return 0;
-
- /* Based on end of ssl_create_cipher_list */
- tmp_cipher_list = sk_SSL_CIPHER_dup(sk);
- if (tmp_cipher_list == NULL)
- {
- return 0;
- }
- if (s->cipher_list != NULL)
- sk_SSL_CIPHER_free(s->cipher_list);
- s->cipher_list = sk;
- if (s->cipher_list_by_id != NULL)
- sk_SSL_CIPHER_free(s->cipher_list_by_id);
- s->cipher_list_by_id = tmp_cipher_list;
- (void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp);
-
- sk_SSL_CIPHER_sort(s->cipher_list_by_id);
- return 1;
- }
-
/* works well for SSLv2, not so good for SSLv3 */
char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
{
@@ -1395,6 +1387,10 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
{
c=sk_SSL_CIPHER_value(sk,i);
+ /* Skip TLS v1.2 only ciphersuites if lower than v1.2 */
+ if ((c->algorithm_ssl & SSL_TLSV1_2) &&
+ (TLS1_get_client_version(s) < TLS1_2_VERSION))
+ continue;
#ifndef OPENSSL_NO_KRB5
if (((c->algorithm_mkey & SSL_kKRB5) || (c->algorithm_auth & SSL_aKRB5)) &&
nokrb5)
@@ -1412,7 +1408,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
/* If p == q, no ciphers and caller indicates an error. Otherwise
* add SCSV if not renegotiating.
*/
- if (p != q && !s->new_session)
+ if (p != q && !s->renegotiate)
{
static SSL_CIPHER scsv =
{
@@ -1459,7 +1455,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
(p[n-1] == (SSL3_CK_SCSV & 0xff)))
{
/* SCSV fatal if renegotiating */
- if (s->new_session)
+ if (s->renegotiate)
{
SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
@@ -1632,10 +1628,21 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned
ctx->next_proto_select_cb = cb;
ctx->next_proto_select_cb_arg = arg;
}
-
# endif
#endif
+int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+ const char *label, size_t llen, const unsigned char *p, size_t plen,
+ int use_context)
+ {
+ if (s->version < TLS1_VERSION)
+ return -1;
+
+ return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
+ llen, p, plen,
+ use_context);
+ }
+
static unsigned long ssl_session_hash(const SSL_SESSION *a)
{
unsigned long l;
@@ -1679,6 +1686,14 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
return(NULL);
}
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && (meth->version < TLS1_VERSION))
+ {
+ SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+ return NULL;
+ }
+#endif
+
if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)
{
SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
@@ -1808,6 +1823,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
ret->psk_client_callback=NULL;
ret->psk_server_callback=NULL;
#endif
+#ifndef OPENSSL_NO_SRP
+ SSL_CTX_SRP_CTX_init(ret);
+#endif
#ifndef OPENSSL_NO_BUF_FREELISTS
ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
@@ -1936,10 +1954,18 @@ void SSL_CTX_free(SSL_CTX *a)
a->comp_methods = NULL;
#endif
+#ifndef OPENSSL_NO_SRTP
+ if (a->srtp_profiles)
+ sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
+#endif
+
#ifndef OPENSSL_NO_PSK
if (a->psk_identity_hint)
OPENSSL_free(a->psk_identity_hint);
#endif
+#ifndef OPENSSL_NO_SRP
+ SSL_CTX_SRP_CTX_free(a);
+#endif
#ifndef OPENSSL_NO_ENGINE
if (a->client_cert_engine)
ENGINE_finish(a->client_cert_engine);
@@ -2193,12 +2219,13 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
#ifndef OPENSSL_NO_EC
-int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)
+int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
{
unsigned long alg_k, alg_a;
EVP_PKEY *pkey = NULL;
int keysize = 0;
int signature_nid = 0, md_nid = 0, pk_nid = 0;
+ const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
alg_k = cs->algorithm_mkey;
alg_a = cs->algorithm_auth;
@@ -2228,7 +2255,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)
SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT);
return 0;
}
- if (alg_k & SSL_kECDHe)
+ if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION)
{
/* signature alg must be ECDSA */
if (pk_nid != NID_X9_62_id_ecPublicKey)
@@ -2237,7 +2264,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)
return 0;
}
}
- if (alg_k & SSL_kECDHr)
+ if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION)
{
/* signature alg must be RSA */
@@ -2264,7 +2291,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)
#endif
/* THIS NEEDS CLEANING UP */
-X509 *ssl_get_server_send_cert(SSL *s)
+CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
{
unsigned long alg_k,alg_a;
CERT *c;
@@ -2319,42 +2346,52 @@ X509 *ssl_get_server_send_cert(SSL *s)
i=SSL_PKEY_GOST01;
else /* if (alg_a & SSL_aNULL) */
{
- SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR);
+ SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY,ERR_R_INTERNAL_ERROR);
return(NULL);
}
- if (c->pkeys[i].x509 == NULL) return(NULL);
- return(c->pkeys[i].x509);
+ return c->pkeys + i;
+ }
+
+X509 *ssl_get_server_send_cert(const SSL *s)
+ {
+ CERT_PKEY *cpk;
+ cpk = ssl_get_server_send_pkey(s);
+ if (!cpk)
+ return NULL;
+ return cpk->x509;
}
-EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher)
+EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)
{
unsigned long alg_a;
CERT *c;
+ int idx = -1;
alg_a = cipher->algorithm_auth;
c=s->cert;
if ((alg_a & SSL_aDSS) &&
(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
- return(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey);
+ idx = SSL_PKEY_DSA_SIGN;
else if (alg_a & SSL_aRSA)
{
if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
- return(c->pkeys[SSL_PKEY_RSA_SIGN].privatekey);
+ idx = SSL_PKEY_RSA_SIGN;
else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL)
- return(c->pkeys[SSL_PKEY_RSA_ENC].privatekey);
- else
- return(NULL);
+ idx = SSL_PKEY_RSA_ENC;
}
else if ((alg_a & SSL_aECDSA) &&
(c->pkeys[SSL_PKEY_ECC].privatekey != NULL))
- return(c->pkeys[SSL_PKEY_ECC].privatekey);
- else /* if (alg_a & SSL_aNULL) */
+ idx = SSL_PKEY_ECC;
+ if (idx == -1)
{
SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR);
return(NULL);
}
+ if (pmd)
+ *pmd = c->pkeys[idx].digest;
+ return c->pkeys[idx].privatekey;
}
void ssl_update_cache(SSL *s,int mode)
@@ -2577,45 +2614,22 @@ SSL_METHOD *ssl_bad_method(int ver)
return(NULL);
}
-static const char *ssl_get_version(int version)
+const char *SSL_get_version(const SSL *s)
{
- if (version == TLS1_VERSION)
+ if (s->version == TLS1_2_VERSION)
+ return("TLSv1.2");
+ else if (s->version == TLS1_1_VERSION)
+ return("TLSv1.1");
+ else if (s->version == TLS1_VERSION)
return("TLSv1");
- else if (version == SSL3_VERSION)
+ else if (s->version == SSL3_VERSION)
return("SSLv3");
- else if (version == SSL2_VERSION)
+ else if (s->version == SSL2_VERSION)
return("SSLv2");
else
return("unknown");
}
-const char *SSL_get_version(const SSL *s)
- {
- return ssl_get_version(s->version);
- }
-
-const char *SSL_SESSION_get_version(const SSL_SESSION *s)
- {
- return ssl_get_version(s->ssl_version);
- }
-
-const char* SSL_authentication_method(const SSL* ssl)
- {
- if (ssl->cert != NULL && ssl->cert->rsa_tmp != NULL)
- return SSL_TXT_RSA "_" SSL_TXT_EXPORT;
- switch (ssl->version)
- {
- case SSL2_VERSION:
- return SSL_TXT_RSA;
- case SSL3_VERSION:
- case TLS1_VERSION:
- case DTLS1_VERSION:
- return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher);
- default:
- return "UNKNOWN";
- }
- }
-
SSL *SSL_dup(SSL *s)
{
STACK_OF(X509_NAME) *sk;
@@ -2700,6 +2714,7 @@ SSL *SSL_dup(SSL *s)
ret->in_handshake = s->in_handshake;
ret->handshake_func = s->handshake_func;
ret->server = s->server;
+ ret->renegotiate = s->renegotiate;
ret->new_session = s->new_session;
ret->quiet_shutdown = s->quiet_shutdown;
ret->shutdown=s->shutdown;
@@ -2777,7 +2792,9 @@ void ssl_clear_cipher_ctx(SSL *s)
/* Fix this function so that it takes an optional type parameter */
X509 *SSL_get_certificate(const SSL *s)
{
- if (s->cert != NULL)
+ if (s->server)
+ return(ssl_get_server_send_cert(s));
+ else if (s->cert != NULL)
return(s->cert->key->x509);
else
return(NULL);
@@ -2965,6 +2982,11 @@ int SSL_state(const SSL *ssl)
return(ssl->state);
}
+void SSL_set_state(SSL *ssl, int state)
+ {
+ ssl->state = state;
+ }
+
void SSL_set_verify_result(SSL *ssl,long arg)
{
ssl->verify_result=arg;
@@ -3203,31 +3225,6 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
}
-int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
- const char *label, size_t llen, const unsigned char *p, size_t plen,
- int use_context)
- {
- if (s->version < TLS1_VERSION)
- return -1;
-
- return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
- llen, p, plen,
- use_context);
- }
-
-int SSL_cutthrough_complete(const SSL *s)
- {
- return (!s->server && /* cutthrough only applies to clients */
- !s->hit && /* full-handshake */
- s->version >= SSL3_VERSION &&
- s->s3->in_read_app_data == 0 && /* cutthrough only applies to write() */
- (SSL_get_mode((SSL*)s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && /* cutthrough enabled */
- SSL_get_cipher_bits(s, NULL) >= 128 && /* strong cipher choosen */
- s->s3->previous_server_finished_len == 0 && /* not a renegotiation handshake */
- (s->state == SSL3_ST_CR_SESSION_TICKET_A || /* ready to write app-data*/
- s->state == SSL3_ST_CR_FINISHED_A));
- }
-
/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
* vairable, freeing EVP_MD_CTX previously stored in that variable, if
* any. If EVP_MD pointer is passed, initializes ctx with this md
@@ -3248,6 +3245,16 @@ void ssl_clear_hash_ctx(EVP_MD_CTX **hash)
*hash=NULL;
}
+void SSL_set_debug(SSL *s, int debug)
+ {
+ s->debug = debug;
+ }
+
+int SSL_cache_hit(SSL *s)
+ {
+ return s->hit;
+ }
+
#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
#include "../crypto/bio/bss_file.c"
#endif
@@ -3256,4 +3263,3 @@ IMPLEMENT_STACK_OF(SSL_CIPHER)
IMPLEMENT_STACK_OF(SSL_COMP)
IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
ssl_cipher_id);
-
diff --git a/deps/openssl/openssl/ssl/ssl_locl.h b/deps/openssl/openssl/ssl/ssl_locl.h
index af607e662..1b98947e6 100644
--- a/deps/openssl/openssl/ssl/ssl_locl.h
+++ b/deps/openssl/openssl/ssl/ssl_locl.h
@@ -170,7 +170,7 @@
# define OPENSSL_EXTERN OPENSSL_EXPORT
#endif
-#define PKCS1_CHECK
+#undef PKCS1_CHECK
#define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \
l|=(((unsigned long)(*((c)++)))<< 8), \
@@ -215,6 +215,15 @@
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
+#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>48)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>40)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>32)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
#define n2l6(c,l) (l =((BN_ULLONG)(*((c)++)))<<40, \
l|=((BN_ULLONG)(*((c)++)))<<32, \
l|=((BN_ULLONG)(*((c)++)))<<24, \
@@ -289,6 +298,7 @@
#define SSL_kEECDH 0x00000080L /* ephemeral ECDH */
#define SSL_kPSK 0x00000100L /* PSK */
#define SSL_kGOST 0x00000200L /* GOST key exchange */
+#define SSL_kSRP 0x00000400L /* SRP */
/* Bits for algorithm_auth (server authentication) */
#define SSL_aRSA 0x00000001L /* RSA auth */
@@ -316,21 +326,29 @@
#define SSL_CAMELLIA256 0x00000200L
#define SSL_eGOST2814789CNT 0x00000400L
#define SSL_SEED 0x00000800L
+#define SSL_AES128GCM 0x00001000L
+#define SSL_AES256GCM 0x00002000L
-#define SSL_AES (SSL_AES128|SSL_AES256)
+#define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM)
#define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256)
/* Bits for algorithm_mac (symmetric authentication) */
+
#define SSL_MD5 0x00000001L
#define SSL_SHA1 0x00000002L
#define SSL_GOST94 0x00000004L
#define SSL_GOST89MAC 0x00000008L
+#define SSL_SHA256 0x00000010L
+#define SSL_SHA384 0x00000020L
+/* Not a real MAC, just an indication it is part of cipher */
+#define SSL_AEAD 0x00000040L
/* Bits for algorithm_ssl (protocol version) */
#define SSL_SSLV2 0x00000001L
#define SSL_SSLV3 0x00000002L
#define SSL_TLSV1 SSL_SSLV3 /* for now */
+#define SSL_TLSV1_2 0x00000004L
/* Bits for algorithm2 (handshake digests and other extra flags) */
@@ -338,15 +356,21 @@
#define SSL_HANDSHAKE_MAC_MD5 0x10
#define SSL_HANDSHAKE_MAC_SHA 0x20
#define SSL_HANDSHAKE_MAC_GOST94 0x40
+#define SSL_HANDSHAKE_MAC_SHA256 0x80
+#define SSL_HANDSHAKE_MAC_SHA384 0x100
#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX
* make sure to update this constant too */
-#define SSL_MAX_DIGEST 4
+#define SSL_MAX_DIGEST 6
-#define TLS1_PRF_DGST_SHIFT 8
+#define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT)
+
+#define TLS1_PRF_DGST_SHIFT 10
#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT)
#define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT)
#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
@@ -456,8 +480,9 @@
typedef struct cert_pkey_st
{
X509 *x509;
- STACK_OF(X509) *cert_chain;
EVP_PKEY *privatekey;
+ /* Digest to use when signing */
+ const EVP_MD *digest;
} CERT_PKEY;
typedef struct cert_st
@@ -596,11 +621,12 @@ extern SSL3_ENC_METHOD TLSv1_enc_data;
extern SSL3_ENC_METHOD SSLv3_enc_data;
extern SSL3_ENC_METHOD DTLSv1_enc_data;
-#define IMPLEMENT_tls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \
+#define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \
+ s_get_meth) \
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
- TLS1_VERSION, \
+ version, \
tls1_new, \
tls1_clear, \
tls1_free, \
@@ -674,7 +700,7 @@ const SSL_METHOD *func_name(void) \
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
- TLS1_VERSION, \
+ TLS1_2_VERSION, \
tls1_new, \
tls1_clear, \
tls1_free, \
@@ -757,7 +783,7 @@ const SSL_METHOD *func_name(void) \
ssl3_read, \
ssl3_peek, \
ssl3_write, \
- ssl3_shutdown, \
+ dtls1_shutdown, \
ssl3_renegotiate, \
ssl3_renegotiate_check, \
dtls1_get_message, \
@@ -813,8 +839,9 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
int ssl_undefined_function(SSL *s);
int ssl_undefined_void_function(void);
int ssl_undefined_const_function(const SSL *s);
-X509 *ssl_get_server_send_cert(SSL *);
-EVP_PKEY *ssl_get_sign_pkey(SSL *,const SSL_CIPHER *);
+CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
+X509 *ssl_get_server_send_cert(const SSL *);
+EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *c, const EVP_MD **pmd);
int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
@@ -948,6 +975,7 @@ void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
void dtls1_reset_seq_numbers(SSL *s, int rw);
long dtls1_default_timeout(void);
struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
+int dtls1_check_timeout_num(SSL *s);
int dtls1_handle_timeout(SSL *s);
const SSL_CIPHER *dtls1_get_cipher(unsigned int u);
void dtls1_start_timer(SSL *s);
@@ -1024,6 +1052,7 @@ int dtls1_connect(SSL *s);
void dtls1_free(SSL *s);
void dtls1_clear(SSL *s);
long dtls1_ctrl(SSL *s,int cmd, long larg, void *parg);
+int dtls1_shutdown(SSL *s);
long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
int dtls1_get_record(SSL *s);
@@ -1045,14 +1074,14 @@ int tls1_mac(SSL *ssl, unsigned char *md, int snd);
int tls1_generate_master_secret(SSL *s, unsigned char *out,
unsigned char *p, int len);
int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
- const char *label, size_t llen, const unsigned char *p,
- size_t plen, int use_context);
+ const char *label, size_t llen,
+ const unsigned char *p, size_t plen, int use_context);
int tls1_alert_code(int code);
int ssl3_alert_code(int code);
int ssl_ok(SSL *s);
#ifndef OPENSSL_NO_ECDH
-int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs);
+int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
#endif
SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
@@ -1069,9 +1098,17 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d,
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
int ssl_prepare_clienthello_tlsext(SSL *s);
int ssl_prepare_serverhello_tlsext(SSL *s);
-int ssl_check_clienthello_tlsext(SSL *s);
+int ssl_check_clienthello_tlsext_early(SSL *s);
+int ssl_check_clienthello_tlsext_late(SSL *s);
int ssl_check_serverhello_tlsext(SSL *s);
+#ifndef OPENSSL_NO_HEARTBEATS
+int tls1_heartbeat(SSL *s);
+int dtls1_heartbeat(SSL *s);
+int tls1_process_heartbeat(SSL *s);
+int dtls1_process_heartbeat(SSL *s);
+#endif
+
#ifdef OPENSSL_NO_SHA256
#define tlsext_tick_md EVP_sha1
#else
@@ -1079,6 +1116,12 @@ int ssl_check_serverhello_tlsext(SSL *s);
#endif
int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
const unsigned char *limit, SSL_SESSION **ret);
+
+int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
+ const EVP_MD *md);
+int tls12_get_sigid(const EVP_PKEY *pk);
+const EVP_MD *tls12_get_hash(unsigned char hash_alg);
+
#endif
EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
@@ -1090,4 +1133,42 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
int maxlen);
int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
int *al);
+long ssl_get_algorithm2(SSL *s);
+int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
+int tls12_get_req_sig_algs(SSL *s, unsigned char *p);
+
+int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen);
+int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al);
+int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen);
+int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al);
+
+/* s3_cbc.c */
+void ssl3_cbc_copy_mac(unsigned char* out,
+ const SSL3_RECORD *rec,
+ unsigned md_size,unsigned orig_len);
+int ssl3_cbc_remove_padding(const SSL* s,
+ SSL3_RECORD *rec,
+ unsigned block_size,
+ unsigned mac_size);
+int tls1_cbc_remove_padding(const SSL* s,
+ SSL3_RECORD *rec,
+ unsigned block_size,
+ unsigned mac_size);
+char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
+void ssl3_cbc_digest_record(
+ const EVP_MD_CTX *ctx,
+ unsigned char* md_out,
+ size_t* md_out_size,
+ const unsigned char header[13],
+ const unsigned char *data,
+ size_t data_plus_mac_size,
+ size_t data_plus_mac_plus_padding_size,
+ const unsigned char *mac_secret,
+ unsigned mac_secret_length,
+ char is_sslv3);
+
+void tls_fips_digest_extra(
+ const EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *mac_ctx,
+ const unsigned char *data, size_t data_len, size_t orig_len);
+
#endif
diff --git a/deps/openssl/openssl/ssl/ssl_rsa.c b/deps/openssl/openssl/ssl/ssl_rsa.c
index c43f3e2a3..60e7b6685 100644
--- a/deps/openssl/openssl/ssl/ssl_rsa.c
+++ b/deps/openssl/openssl/ssl/ssl_rsa.c
@@ -697,42 +697,6 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
}
-int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain)
- {
- if (ssl == NULL)
- {
- SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER);
- return(0);
- }
- if (ssl->cert == NULL)
- {
- SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
- return(0);
- }
- if (ssl->cert->key == NULL)
- {
- SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
- return(0);
- }
- ssl->cert->key->cert_chain = cert_chain;
- return(1);
- }
-
-STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x)
- {
- int i;
- if (x == NULL)
- return NULL;
- if (ssl == NULL)
- return NULL;
- if (ssl->cert == NULL)
- return NULL;
- for (i = 0; i < SSL_PKEY_NUM; i++)
- if (ssl->cert->pkeys[i].x509 == x)
- return ssl->cert->pkeys[i].cert_chain;
- return NULL;
- }
-
#ifndef OPENSSL_NO_STDIO
/* Read a file that contains our certificate in "PEM" format,
* possibly followed by a sequence of CA certificates that should be
@@ -746,7 +710,7 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
- in=BIO_new(BIO_s_file_internal());
+ in = BIO_new(BIO_s_file_internal());
if (in == NULL)
{
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB);
@@ -759,14 +723,16 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
goto end;
}
- x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
+ x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata);
if (x == NULL)
{
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB);
goto end;
}
- ret=SSL_CTX_use_certificate(ctx,x);
+ ret = SSL_CTX_use_certificate(ctx, x);
+
if (ERR_peek_error() != 0)
ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */
if (ret)
@@ -778,13 +744,15 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
int r;
unsigned long err;
- if (ctx->extra_certs != NULL)
+ if (ctx->extra_certs != NULL)
{
sk_X509_pop_free(ctx->extra_certs, X509_free);
ctx->extra_certs = NULL;
}
- while ((ca = PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata))
+ while ((ca = PEM_read_bio_X509(in, NULL,
+ ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata))
!= NULL)
{
r = SSL_CTX_add_extra_chain_cert(ctx, ca);
diff --git a/deps/openssl/openssl/ssl/ssl_sess.c b/deps/openssl/openssl/ssl/ssl_sess.c
index 93954e489..ad40fadd0 100644
--- a/deps/openssl/openssl/ssl/ssl_sess.c
+++ b/deps/openssl/openssl/ssl/ssl_sess.c
@@ -218,6 +218,9 @@ SSL_SESSION *SSL_SESSION_new(void)
ss->psk_identity_hint=NULL;
ss->psk_identity=NULL;
#endif
+#ifndef OPENSSL_NO_SRP
+ ss->srp_username=NULL;
+#endif
return(ss);
}
@@ -228,6 +231,11 @@ const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
return s->session_id;
}
+unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s)
+ {
+ return s->compress_meth;
+ }
+
/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1
* has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly
* until we have no conflict is going to complete in one iteration pretty much
@@ -261,11 +269,6 @@ static int def_generate_session_id(const SSL *ssl, unsigned char *id,
return 0;
}
-void SSL_set_session_creation_enabled (SSL *s, int creation_enabled)
- {
- s->session_creation_enabled = creation_enabled;
- }
-
int ssl_get_new_session(SSL *s, int session)
{
/* This gets used by clients and servers. */
@@ -274,8 +277,6 @@ int ssl_get_new_session(SSL *s, int session)
SSL_SESSION *ss=NULL;
GEN_SESSION_CB cb = def_generate_session_id;
- /* caller should check this if they can do better error handling */
- if (!s->session_creation_enabled) return(0);
if ((ss=SSL_SESSION_new()) == NULL) return(0);
/* If the context has a default timeout, use it */
@@ -307,6 +308,16 @@ int ssl_get_new_session(SSL *s, int session)
ss->ssl_version=TLS1_VERSION;
ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
}
+ else if (s->version == TLS1_1_VERSION)
+ {
+ ss->ssl_version=TLS1_1_VERSION;
+ ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
+ }
+ else if (s->version == TLS1_2_VERSION)
+ {
+ ss->ssl_version=TLS1_2_VERSION;
+ ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
+ }
else if (s->version == DTLS1_BAD_VER)
{
ss->ssl_version=DTLS1_BAD_VER;
@@ -430,6 +441,25 @@ int ssl_get_new_session(SSL *s, int session)
return(1);
}
+/* ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
+ * connection. It is only called by servers.
+ *
+ * session_id: points at the session ID in the ClientHello. This code will
+ * read past the end of this in order to parse out the session ticket
+ * extension, if any.
+ * len: the length of the session ID.
+ * limit: a pointer to the first byte after the ClientHello.
+ *
+ * Returns:
+ * -1: error
+ * 0: a session may have been found.
+ *
+ * Side effects:
+ * - If a session is found then s->session is pointed at it (after freeing an
+ * existing session if need be) and s->verify_result is set from the session.
+ * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1
+ * if the server should issue a new session ticket (to 0 otherwise).
+ */
int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
const unsigned char *limit)
{
@@ -437,27 +467,39 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
SSL_SESSION *ret=NULL;
int fatal = 0;
+ int try_session_cache = 1;
#ifndef OPENSSL_NO_TLSEXT
int r;
#endif
if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
goto err;
+
+ if (len == 0)
+ try_session_cache = 0;
+
#ifndef OPENSSL_NO_TLSEXT
- r = tls1_process_ticket(s, session_id, len, limit, &ret);
- if (r == -1)
+ r = tls1_process_ticket(s, session_id, len, limit, &ret); /* sets s->tlsext_ticket_expected */
+ switch (r)
{
+ case -1: /* Error during processing */
fatal = 1;
goto err;
+ case 0: /* No ticket found */
+ case 1: /* Zero length ticket found */
+ break; /* Ok to carry on processing session id. */
+ case 2: /* Ticket found but not decrypted. */
+ case 3: /* Ticket decrypted, *ret has been set. */
+ try_session_cache = 0;
+ break;
+ default:
+ abort();
}
- else if (r == 0 || (!ret && !len))
- goto err;
- else if (!ret && !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
-#else
- if (len == 0)
- goto err;
- if (!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
#endif
+
+ if (try_session_cache &&
+ ret == NULL &&
+ !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
{
SSL_SESSION data;
data.ssl_version=s->version;
@@ -468,20 +510,22 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data);
if (ret != NULL)
- /* don't allow other threads to steal it: */
- CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
+ {
+ /* don't allow other threads to steal it: */
+ CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
+ }
CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+ if (ret == NULL)
+ s->session_ctx->stats.sess_miss++;
}
- if (ret == NULL)
+ if (try_session_cache &&
+ ret == NULL &&
+ s->session_ctx->get_session_cb != NULL)
{
int copy=1;
- s->session_ctx->stats.sess_miss++;
- ret=NULL;
- if (s->session_ctx->get_session_cb != NULL
- && (ret=s->session_ctx->get_session_cb(s,session_id,len,&copy))
- != NULL)
+ if ((ret=s->session_ctx->get_session_cb(s,session_id,len,&copy)))
{
s->session_ctx->stats.sess_cb_hit++;
@@ -500,23 +544,18 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
* things are very strange */
SSL_CTX_add_session(s->session_ctx,ret);
}
- if (ret == NULL)
- goto err;
}
- /* Now ret is non-NULL, and we own one of its reference counts. */
+ if (ret == NULL)
+ goto err;
+
+ /* Now ret is non-NULL and we own one of its reference counts. */
if (ret->sid_ctx_length != s->sid_ctx_length
|| memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))
{
- /* We've found the session named by the client, but we don't
+ /* We have the session requested by the client, but we don't
* want to use it in this context. */
-
-#if 0 /* The client cannot always know when a session is not appropriate,
- * so we shouldn't generate an error message. */
-
- SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
-#endif
goto err; /* treat like cache miss */
}
@@ -553,39 +592,38 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
goto err;
}
-
-#if 0 /* This is way too late. */
-
- /* If a thread got the session, then 'swaped', and another got
- * it and then due to a time-out decided to 'OPENSSL_free' it we could
- * be in trouble. So I'll increment it now, then double decrement
- * later - am I speaking rubbish?. */
- CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
-#endif
-
if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */
{
s->session_ctx->stats.sess_timeout++;
- /* remove it from the cache */
- SSL_CTX_remove_session(s->session_ctx,ret);
+ if (try_session_cache)
+ {
+ /* session was from the cache, so remove it */
+ SSL_CTX_remove_session(s->session_ctx,ret);
+ }
goto err;
}
s->session_ctx->stats.sess_hit++;
- /* ret->time=time(NULL); */ /* rezero timeout? */
- /* again, just leave the session
- * if it is the same session, we have just incremented and
- * then decremented the reference count :-) */
if (s->session != NULL)
SSL_SESSION_free(s->session);
s->session=ret;
s->verify_result = s->session->verify_result;
- return(1);
+ return 1;
err:
if (ret != NULL)
+ {
SSL_SESSION_free(ret);
+#ifndef OPENSSL_NO_TLSEXT
+ if (!try_session_cache)
+ {
+ /* The session was from a ticket, so we should
+ * issue a ticket for the new session */
+ s->tlsext_ticket_expected = 1;
+ }
+#endif
+ }
if (fatal)
return -1;
else
@@ -736,6 +774,10 @@ void SSL_SESSION_free(SSL_SESSION *ss)
if (ss->psk_identity != NULL)
OPENSSL_free(ss->psk_identity);
#endif
+#ifndef OPENSSL_NO_SRP
+ if (ss->srp_username != NULL)
+ OPENSSL_free(ss->srp_username);
+#endif
OPENSSL_cleanse(ss,sizeof(*ss));
OPENSSL_free(ss);
}
@@ -760,10 +802,6 @@ int SSL_set_session(SSL *s, SSL_SESSION *session)
{
if (!SSL_set_ssl_method(s,meth))
return(0);
- if (s->ctx->session_timeout == 0)
- session->timeout=SSL_get_default_timeout(s);
- else
- session->timeout=s->ctx->session_timeout;
}
#ifndef OPENSSL_NO_KRB5
@@ -831,6 +869,25 @@ long SSL_SESSION_set_time(SSL_SESSION *s, long t)
return(t);
}
+X509 *SSL_SESSION_get0_peer(SSL_SESSION *s)
+ {
+ return s->peer;
+ }
+
+int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
+ unsigned int sid_ctx_len)
+ {
+ if(sid_ctx_len > SSL_MAX_SID_CTX_LENGTH)
+ {
+ SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
+ return 0;
+ }
+ s->sid_ctx_length=sid_ctx_len;
+ memcpy(s->sid_ctx,sid_ctx,sid_ctx_len);
+
+ return 1;
+ }
+
long SSL_CTX_set_timeout(SSL_CTX *s, long t)
{
long l;
diff --git a/deps/openssl/openssl/ssl/ssl_txt.c b/deps/openssl/openssl/ssl/ssl_txt.c
index 3122440e2..6479d52c0 100644
--- a/deps/openssl/openssl/ssl/ssl_txt.c
+++ b/deps/openssl/openssl/ssl/ssl_txt.c
@@ -115,6 +115,10 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
s="SSLv2";
else if (x->ssl_version == SSL3_VERSION)
s="SSLv3";
+ else if (x->ssl_version == TLS1_2_VERSION)
+ s="TLSv1.2";
+ else if (x->ssl_version == TLS1_1_VERSION)
+ s="TLSv1.1";
else if (x->ssl_version == TLS1_VERSION)
s="TLSv1";
else if (x->ssl_version == DTLS1_VERSION)
@@ -187,6 +191,10 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
if (BIO_puts(bp,"\n PSK identity hint: ") <= 0) goto err;
if (BIO_printf(bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) goto err;
#endif
+#ifndef OPENSSL_NO_SRP
+ if (BIO_puts(bp,"\n SRP username: ") <= 0) goto err;
+ if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0) goto err;
+#endif
#ifndef OPENSSL_NO_TLSEXT
if (x->tlsext_tick_lifetime_hint)
{
diff --git a/deps/openssl/openssl/ssl/ssltest.c b/deps/openssl/openssl/ssl/ssltest.c
index f6a2c79db..316bbb0c9 100644
--- a/deps/openssl/openssl/ssl/ssltest.c
+++ b/deps/openssl/openssl/ssl/ssltest.c
@@ -181,6 +181,9 @@
#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
#endif
+#ifndef OPENSSL_NO_SRP
+#include <openssl/srp.h>
+#endif
#include <openssl/bn.h>
#define _XOPEN_SOURCE_EXTENDED 1 /* Or gethostname won't be declared properly
@@ -246,6 +249,49 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned
unsigned int max_psk_len);
#endif
+#ifndef OPENSSL_NO_SRP
+/* SRP client */
+/* This is a context that we pass to all callbacks */
+typedef struct srp_client_arg_st
+ {
+ char *srppassin;
+ char *srplogin;
+ } SRP_CLIENT_ARG;
+
+#define PWD_STRLEN 1024
+
+static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
+ {
+ SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
+ return BUF_strdup((char *)srp_client_arg->srppassin);
+ }
+
+/* SRP server */
+/* This is a context that we pass to SRP server callbacks */
+typedef struct srp_server_arg_st
+ {
+ char *expected_user;
+ char *pass;
+ } SRP_SERVER_ARG;
+
+static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
+ {
+ SRP_SERVER_ARG * p = (SRP_SERVER_ARG *) arg;
+
+ if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0)
+ {
+ fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s));
+ return SSL3_AL_FATAL;
+ }
+ if (SSL_set_srp_server_param_pw(s,p->expected_user,p->pass,"1024")<0)
+ {
+ *ad = SSL_AD_INTERNAL_ERROR;
+ return SSL3_AL_FATAL;
+ }
+ return SSL_ERROR_NONE;
+ }
+#endif
+
static BIO *bio_err=NULL;
static BIO *bio_stdout=NULL;
@@ -268,6 +314,9 @@ static void sv_usage(void)
{
fprintf(stderr,"usage: ssltest [args ...]\n");
fprintf(stderr,"\n");
+#ifdef OPENSSL_FIPS
+ fprintf(stderr,"-F - run test in FIPS mode\n");
+#endif
fprintf(stderr," -server_auth - check server certificate\n");
fprintf(stderr," -client_auth - do client authentication\n");
fprintf(stderr," -proxy - allow proxy certificates\n");
@@ -289,6 +338,10 @@ static void sv_usage(void)
#ifndef OPENSSL_NO_PSK
fprintf(stderr," -psk arg - PSK in hex (without 0x)\n");
#endif
+#ifndef OPENSSL_NO_SRP
+ fprintf(stderr," -srpuser user - SRP username to use\n");
+ fprintf(stderr," -srppass arg - password for 'user'\n");
+#endif
#ifndef OPENSSL_NO_SSL2
fprintf(stderr," -ssl2 - use SSLv2\n");
#endif
@@ -316,9 +369,6 @@ static void sv_usage(void)
" (default is sect163r2).\n");
#endif
fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
- fprintf(stderr," -c_small_records - enable client side use of small SSL record buffers\n");
- fprintf(stderr," -s_small_records - enable server side use of small SSL record buffers\n");
- fprintf(stderr," -cutthrough - enable 1-RTT full-handshake for strong ciphers\n");
}
static void print_details(SSL *c_ssl, const char *prefix)
@@ -447,10 +497,6 @@ int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_)
return arg->ret;
}
#endif
- int ssl_mode = 0;
- int c_small_records=0;
- int s_small_records=0;
- int cutthrough = 0;
int main(int argc, char *argv[])
{
@@ -483,6 +529,12 @@ int main(int argc, char *argv[])
#ifndef OPENSSL_NO_ECDH
EC_KEY *ecdh = NULL;
#endif
+#ifndef OPENSSL_NO_SRP
+ /* client */
+ SRP_CLIENT_ARG srp_client_arg = {NULL,NULL};
+ /* server */
+ SRP_SERVER_ARG srp_server_arg = {NULL,NULL};
+#endif
int no_dhe = 0;
int no_ecdhe = 0;
int no_psk = 0;
@@ -491,9 +543,12 @@ int main(int argc, char *argv[])
int comp = 0;
#ifndef OPENSSL_NO_COMP
COMP_METHOD *cm = NULL;
-#endif
STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+#endif
int test_cipherlist = 0;
+#ifdef OPENSSL_FIPS
+ int fips_mode=0;
+#endif
verbose = 0;
debug = 0;
@@ -525,7 +580,16 @@ int main(int argc, char *argv[])
while (argc >= 1)
{
- if (strcmp(*argv,"-server_auth") == 0)
+ if(!strcmp(*argv,"-F"))
+ {
+#ifdef OPENSSL_FIPS
+ fips_mode=1;
+#else
+ fprintf(stderr,"not compiled with FIPS support, so exitting without running.\n");
+ EXIT(0);
+#endif
+ }
+ else if (strcmp(*argv,"-server_auth") == 0)
server_auth=1;
else if (strcmp(*argv,"-client_auth") == 0)
client_auth=1;
@@ -579,6 +643,20 @@ int main(int argc, char *argv[])
no_psk=1;
#endif
}
+#ifndef OPENSSL_NO_SRP
+ else if (strcmp(*argv,"-srpuser") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srp_server_arg.expected_user = srp_client_arg.srplogin= *(++argv);
+ tls1=1;
+ }
+ else if (strcmp(*argv,"-srppass") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srp_server_arg.pass = srp_client_arg.srppassin= *(++argv);
+ tls1=1;
+ }
+#endif
else if (strcmp(*argv,"-ssl2") == 0)
ssl2=1;
else if (strcmp(*argv,"-tls1") == 0)
@@ -687,18 +765,6 @@ int main(int argc, char *argv[])
{
test_cipherlist = 1;
}
- else if (strcmp(*argv, "-c_small_records") == 0)
- {
- c_small_records = 1;
- }
- else if (strcmp(*argv, "-s_small_records") == 0)
- {
- s_small_records = 1;
- }
- else if (strcmp(*argv, "-cutthrough") == 0)
- {
- cutthrough = 1;
- }
else
{
fprintf(stderr,"unknown option %s\n",*argv);
@@ -733,6 +799,20 @@ bad:
EXIT(1);
}
+#ifdef OPENSSL_FIPS
+ if(fips_mode)
+ {
+ if(!FIPS_mode_set(1))
+ {
+ ERR_load_crypto_strings();
+ ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
+ EXIT(1);
+ }
+ else
+ fprintf(stderr,"*** IN FIPS MODE ***\n");
+ }
+#endif
+
if (print_time)
{
if (!bio_pair)
@@ -821,28 +901,6 @@ bad:
SSL_CTX_set_cipher_list(s_ctx,cipher);
}
- ssl_mode = 0;
- if (c_small_records)
- {
- ssl_mode = SSL_CTX_get_mode(c_ctx);
- ssl_mode |= SSL_MODE_SMALL_BUFFERS;
- SSL_CTX_set_mode(c_ctx, ssl_mode);
- }
- ssl_mode = 0;
- if (s_small_records)
- {
- ssl_mode = SSL_CTX_get_mode(s_ctx);
- ssl_mode |= SSL_MODE_SMALL_BUFFERS;
- SSL_CTX_set_mode(s_ctx, ssl_mode);
- }
- ssl_mode = 0;
- if (cutthrough)
- {
- ssl_mode = SSL_CTX_get_mode(c_ctx);
- ssl_mode = SSL_MODE_HANDSHAKE_CUTTHROUGH;
- SSL_CTX_set_mode(c_ctx, ssl_mode);
- }
-
#ifndef OPENSSL_NO_DH
if (!no_dhe)
{
@@ -878,7 +936,11 @@ bad:
}
}
else
+#ifdef OPENSSL_NO_EC2M
+ nid = NID_X9_62_prime256v1;
+#else
nid = NID_sect163r2;
+#endif
ecdh = EC_KEY_new_by_curve_name(nid);
if (ecdh == NULL)
@@ -981,6 +1043,26 @@ bad:
}
#endif
}
+#ifndef OPENSSL_NO_SRP
+ if (srp_client_arg.srplogin)
+ {
+ if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin))
+ {
+ BIO_printf(bio_err,"Unable to set SRP username\n");
+ goto end;
+ }
+ SSL_CTX_set_srp_cb_arg(c_ctx,&srp_client_arg);
+ SSL_CTX_set_srp_client_pwd_callback(c_ctx, ssl_give_srp_client_pwd_cb);
+ /*SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength);*/
+ }
+
+ if (srp_server_arg.expected_user != NULL)
+ {
+ SSL_CTX_set_verify(s_ctx,SSL_VERIFY_NONE,verify_callback);
+ SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg);
+ SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb);
+ }
+#endif
c_ssl=SSL_new(c_ctx);
s_ssl=SSL_new(s_ctx);
@@ -2205,15 +2287,7 @@ static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
}
#ifndef OPENSSL_NO_X509_VERIFY
-# ifdef OPENSSL_FIPS
- if(s->version == TLS1_VERSION)
- FIPS_allow_md5(1);
-# endif
ok = X509_verify_cert(ctx);
-# ifdef OPENSSL_FIPS
- if(s->version == TLS1_VERSION)
- FIPS_allow_md5(0);
-# endif
#endif
if (cb_arg->proxy_auth)
diff --git a/deps/openssl/openssl/ssl/t1_clnt.c b/deps/openssl/openssl/ssl/t1_clnt.c
index c87af1771..578617ed8 100644
--- a/deps/openssl/openssl/ssl/t1_clnt.c
+++ b/deps/openssl/openssl/ssl/t1_clnt.c
@@ -66,13 +66,26 @@
static const SSL_METHOD *tls1_get_client_method(int ver);
static const SSL_METHOD *tls1_get_client_method(int ver)
{
+ if (ver == TLS1_2_VERSION)
+ return TLSv1_2_client_method();
+ if (ver == TLS1_1_VERSION)
+ return TLSv1_1_client_method();
if (ver == TLS1_VERSION)
- return(TLSv1_client_method());
- else
- return(NULL);
+ return TLSv1_client_method();
+ return NULL;
}
-IMPLEMENT_tls1_meth_func(TLSv1_client_method,
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_client_method,
+ ssl_undefined_function,
+ ssl3_connect,
+ tls1_get_client_method)
+
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method,
+ ssl_undefined_function,
+ ssl3_connect,
+ tls1_get_client_method)
+
+IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_client_method,
ssl_undefined_function,
ssl3_connect,
tls1_get_client_method)
diff --git a/deps/openssl/openssl/ssl/t1_enc.c b/deps/openssl/openssl/ssl/t1_enc.c
index b1d5b2808..809ad2ee1 100644
--- a/deps/openssl/openssl/ssl/t1_enc.c
+++ b/deps/openssl/openssl/ssl/t1_enc.c
@@ -143,6 +143,7 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/md5.h>
+#include <openssl/rand.h>
#ifdef KSSL_DEBUG
#include <openssl/des.h>
#endif
@@ -158,68 +159,75 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
unsigned char *out, int olen)
{
int chunk;
- unsigned int j;
- HMAC_CTX ctx;
- HMAC_CTX ctx_tmp;
+ size_t j;
+ EVP_MD_CTX ctx, ctx_tmp;
+ EVP_PKEY *mac_key;
unsigned char A1[EVP_MAX_MD_SIZE];
- unsigned int A1_len;
+ size_t A1_len;
int ret = 0;
chunk=EVP_MD_size(md);
OPENSSL_assert(chunk >= 0);
- HMAC_CTX_init(&ctx);
- HMAC_CTX_init(&ctx_tmp);
- if (!HMAC_Init_ex(&ctx,sec,sec_len,md, NULL))
+ EVP_MD_CTX_init(&ctx);
+ EVP_MD_CTX_init(&ctx_tmp);
+ EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
+ if (!mac_key)
+ goto err;
+ if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
goto err;
- if (!HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL))
+ if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
goto err;
- if (seed1 != NULL && !HMAC_Update(&ctx,seed1,seed1_len))
+ if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
goto err;
- if (seed2 != NULL && !HMAC_Update(&ctx,seed2,seed2_len))
+ if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
goto err;
- if (seed3 != NULL && !HMAC_Update(&ctx,seed3,seed3_len))
+ if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
goto err;
- if (seed4 != NULL && !HMAC_Update(&ctx,seed4,seed4_len))
+ if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
goto err;
- if (seed5 != NULL && !HMAC_Update(&ctx,seed5,seed5_len))
+ if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
goto err;
- if (!HMAC_Final(&ctx,A1,&A1_len))
+ if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
goto err;
for (;;)
{
- if (!HMAC_Init_ex(&ctx,NULL,0,NULL,NULL)) /* re-init */
+ /* Reinit mac contexts */
+ if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
goto err;
- if (!HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL)) /* re-init */
+ if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
goto err;
- if (!HMAC_Update(&ctx,A1,A1_len))
+ if (!EVP_DigestSignUpdate(&ctx,A1,A1_len))
goto err;
- if (!HMAC_Update(&ctx_tmp,A1,A1_len))
+ if (!EVP_DigestSignUpdate(&ctx_tmp,A1,A1_len))
goto err;
- if (seed1 != NULL && !HMAC_Update(&ctx,seed1,seed1_len))
+ if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
goto err;
- if (seed2 != NULL && !HMAC_Update(&ctx,seed2,seed2_len))
+ if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
goto err;
- if (seed3 != NULL && !HMAC_Update(&ctx,seed3,seed3_len))
+ if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
goto err;
- if (seed4 != NULL && !HMAC_Update(&ctx,seed4,seed4_len))
+ if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
goto err;
- if (seed5 != NULL && !HMAC_Update(&ctx,seed5,seed5_len))
+ if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
goto err;
if (olen > chunk)
{
- if (!HMAC_Final(&ctx,out,&j))
+ if (!EVP_DigestSignFinal(&ctx,out,&j))
goto err;
out+=j;
olen-=j;
- if (!HMAC_Final(&ctx_tmp,A1,&A1_len)) /* calc the next A1 value */
+ /* calc the next A1 value */
+ if (!EVP_DigestSignFinal(&ctx_tmp,A1,&A1_len))
goto err;
}
else /* last one */
{
- if (!HMAC_Final(&ctx,A1,&A1_len))
+ if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
goto err;
memcpy(out,A1,olen);
break;
@@ -227,8 +235,9 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
}
ret = 1;
err:
- HMAC_CTX_cleanup(&ctx);
- HMAC_CTX_cleanup(&ctx_tmp);
+ EVP_PKEY_free(mac_key);
+ EVP_MD_CTX_cleanup(&ctx);
+ EVP_MD_CTX_cleanup(&ctx_tmp);
OPENSSL_cleanse(A1,sizeof(A1));
return ret;
}
@@ -256,6 +265,8 @@ static int tls1_PRF(long digest_mask,
if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) count++;
}
len=slen/count;
+ if (count == 1)
+ slen = 0;
S1=sec;
memset(out1,0,olen);
for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
@@ -284,7 +295,7 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km,
unsigned char *tmp, int num)
{
int ret;
- ret = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ ret = tls1_PRF(ssl_get_algorithm2(s),
TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE,
s->s3->server_random,SSL3_RANDOM_SIZE,
s->s3->client_random,SSL3_RANDOM_SIZE,
@@ -350,7 +361,7 @@ int tls1_change_cipher_state(SSL *s, int which)
{
int i;
for (i=0; i<s->s3->tmp.key_block_length; i++)
- printf("%02x", key_block[i]); printf("\n");
+ printf("%02x", s->s3->tmp.key_block[i]); printf("\n");
}
#endif /* KSSL_DEBUG */
@@ -358,7 +369,7 @@ int tls1_change_cipher_state(SSL *s, int which)
{
if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
- else
+ else
s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
if (s->enc_read_ctx != NULL)
@@ -445,7 +456,11 @@ int tls1_change_cipher_state(SSL *s, int which)
j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
/* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
- k=EVP_CIPHER_iv_length(c);
+ /* If GCM mode only part of IV comes from PRF */
+ if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
+ k = EVP_GCM_TLS_FIXED_IV_LEN;
+ else
+ k=EVP_CIPHER_iv_length(c);
if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
(which == SSL3_CHANGE_CIPHER_SERVER_READ))
{
@@ -474,10 +489,14 @@ int tls1_change_cipher_state(SSL *s, int which)
}
memcpy(mac_secret,ms,i);
- mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
- mac_secret,*mac_secret_size);
- EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
- EVP_PKEY_free(mac_key);
+
+ if (!(EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER))
+ {
+ mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
+ mac_secret,*mac_secret_size);
+ EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
+ EVP_PKEY_free(mac_key);
+ }
#ifdef TLS_DEBUG
printf("which = %04X\nmac key=",which);
{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
@@ -487,7 +506,7 @@ printf("which = %04X\nmac key=",which);
/* In here I set both the read and write key/iv to the
* same value since only the correct one will be used :-).
*/
- if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ if (!tls1_PRF(ssl_get_algorithm2(s),
exp_label,exp_label_len,
s->s3->client_random,SSL3_RANDOM_SIZE,
s->s3->server_random,SSL3_RANDOM_SIZE,
@@ -498,7 +517,7 @@ printf("which = %04X\nmac key=",which);
if (k > 0)
{
- if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ if (!tls1_PRF(ssl_get_algorithm2(s),
TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE,
s->s3->client_random,SSL3_RANDOM_SIZE,
s->s3->server_random,SSL3_RANDOM_SIZE,
@@ -524,7 +543,19 @@ printf("which = %04X\nmac key=",which);
}
#endif /* KSSL_DEBUG */
- EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
+ if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
+ {
+ EVP_CipherInit_ex(dd,c,NULL,key,NULL,(which & SSL3_CC_WRITE));
+ EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv);
+ }
+ else
+ EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
+
+ /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
+ if ((EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size)
+ EVP_CIPHER_CTX_ctrl(dd,EVP_CTRL_AEAD_SET_MAC_KEY,
+ *mac_secret_size,mac_secret);
+
#ifdef TLS_DEBUG
printf("which = %04X\nkey=",which);
{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); }
@@ -606,7 +637,8 @@ printf("\nkey block\n");
{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
#endif
- if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+ if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
+ && s->method->version <= TLS1_VERSION)
{
/* enable vulnerability countermeasure for CBC ciphers with
* known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
@@ -635,19 +667,28 @@ err:
return(ret);
}
+/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+ *
+ * Returns:
+ * 0: (in non-constant time) if the record is publically invalid (i.e. too
+ * short etc).
+ * 1: if the record's padding is valid / the encryption was successful.
+ * -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
+ * an internal error occured.
+ */
int tls1_enc(SSL *s, int send)
{
SSL3_RECORD *rec;
EVP_CIPHER_CTX *ds;
unsigned long l;
- int bs,i,ii,j,k,n=0;
+ int bs,i,j,k,pad=0,ret,mac_size=0;
const EVP_CIPHER *enc;
if (send)
{
if (EVP_MD_CTX_md(s->write_hash))
{
- n=EVP_MD_CTX_size(s->write_hash);
+ int n=EVP_MD_CTX_size(s->write_hash);
OPENSSL_assert(n >= 0);
}
ds=s->enc_write_ctx;
@@ -655,13 +696,34 @@ int tls1_enc(SSL *s, int send)
if (s->enc_write_ctx == NULL)
enc=NULL;
else
+ {
+ int ivlen;
enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
+ /* For TLSv1.1 and later explicit IV */
+ if (s->version >= TLS1_1_VERSION
+ && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE)
+ ivlen = EVP_CIPHER_iv_length(enc);
+ else
+ ivlen = 0;
+ if (ivlen > 1)
+ {
+ if ( rec->data != rec->input)
+ /* we can't write into the input stream:
+ * Can this ever happen?? (steve)
+ */
+ fprintf(stderr,
+ "%s:%d: rec->data != rec->input\n",
+ __FILE__, __LINE__);
+ else if (RAND_bytes(rec->input, ivlen) <= 0)
+ return -1;
+ }
+ }
}
else
{
if (EVP_MD_CTX_md(s->read_hash))
{
- n=EVP_MD_CTX_size(s->read_hash);
+ int n=EVP_MD_CTX_size(s->read_hash);
OPENSSL_assert(n >= 0);
}
ds=s->enc_read_ctx;
@@ -676,18 +738,54 @@ int tls1_enc(SSL *s, int send)
printf("tls1_enc(%d)\n", send);
#endif /* KSSL_DEBUG */
- if ((s->session == NULL) || (ds == NULL) ||
- (enc == NULL))
+ if ((s->session == NULL) || (ds == NULL) || (enc == NULL))
{
memmove(rec->data,rec->input,rec->length);
rec->input=rec->data;
+ ret = 1;
}
else
{
l=rec->length;
bs=EVP_CIPHER_block_size(ds->cipher);
- if ((bs != 1) && send)
+ if (EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER)
+ {
+ unsigned char buf[13],*seq;
+
+ seq = send?s->s3->write_sequence:s->s3->read_sequence;
+
+ if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
+ {
+ unsigned char dtlsseq[9],*p=dtlsseq;
+
+ s2n(send?s->d1->w_epoch:s->d1->r_epoch,p);
+ memcpy(p,&seq[2],6);
+ memcpy(buf,dtlsseq,8);
+ }
+ else
+ {
+ memcpy(buf,seq,8);
+ for (i=7; i>=0; i--) /* increment */
+ {
+ ++seq[i];
+ if (seq[i] != 0) break;
+ }
+ }
+
+ buf[8]=rec->type;
+ buf[9]=(unsigned char)(s->version>>8);
+ buf[10]=(unsigned char)(s->version);
+ buf[11]=rec->length>>8;
+ buf[12]=rec->length&0xff;
+ pad=EVP_CIPHER_CTX_ctrl(ds,EVP_CTRL_AEAD_TLS1_AAD,13,buf);
+ if (send)
+ {
+ l+=pad;
+ rec->length+=pad;
+ }
+ }
+ else if ((bs != 1) && send)
{
i=bs-((int)l%bs);
@@ -708,13 +806,13 @@ int tls1_enc(SSL *s, int send)
#ifdef KSSL_DEBUG
{
- unsigned long ui;
+ unsigned long ui;
printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
- ds,rec->data,rec->input,l);
+ ds,rec->data,rec->input,l);
printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
- ds->buf_len, ds->cipher->key_len,
- DES_KEY_SZ, DES_SCHEDULE_SZ,
- ds->cipher->iv_len);
+ ds->buf_len, ds->cipher->key_len,
+ DES_KEY_SZ, DES_SCHEDULE_SZ,
+ ds->cipher->iv_len);
printf("\t\tIV: ");
for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
printf("\n");
@@ -727,68 +825,41 @@ int tls1_enc(SSL *s, int send)
if (!send)
{
if (l == 0 || l%bs != 0)
- {
- SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
return 0;
- }
}
- EVP_Cipher(ds,rec->data,rec->input,l);
+ i = EVP_Cipher(ds,rec->data,rec->input,l);
+ if ((EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_CUSTOM_CIPHER)
+ ?(i<0)
+ :(i==0))
+ return -1; /* AEAD can fail to verify MAC */
+ if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send)
+ {
+ rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ }
#ifdef KSSL_DEBUG
{
- unsigned long i;
- printf("\trec->data=");
+ unsigned long i;
+ printf("\trec->data=");
for (i=0; i<l; i++)
- printf(" %02x", rec->data[i]); printf("\n");
- }
+ printf(" %02x", rec->data[i]); printf("\n");
+ }
#endif /* KSSL_DEBUG */
+ ret = 1;
+ if (EVP_MD_CTX_md(s->read_hash) != NULL)
+ mac_size = EVP_MD_CTX_size(s->read_hash);
if ((bs != 1) && !send)
- {
- ii=i=rec->data[l-1]; /* padding_length */
- i++;
- /* NB: if compression is in operation the first packet
- * may not be of even length so the padding bug check
- * cannot be performed. This bug workaround has been
- * around since SSLeay so hopefully it is either fixed
- * now or no buggy implementation supports compression
- * [steve]
- */
- if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
- && !s->expand)
- {
- /* First packet is even in size, so check */
- if ((memcmp(s->s3->read_sequence,
- "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
- s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
- if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
- i--;
- }
- /* TLS 1.0 does not bound the number of padding bytes by the block size.
- * All of them must have value 'padding_length'. */
- if (i > (int)rec->length)
- {
- /* Incorrect padding. SSLerr() and ssl3_alert are done
- * by caller: we don't want to reveal whether this is
- * a decryption error or a MAC verification failure
- * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
- return -1;
- }
- for (j=(int)(l-i); j<(int)l; j++)
- {
- if (rec->data[j] != ii)
- {
- /* Incorrect padding */
- return -1;
- }
- }
- rec->length-=i;
- }
+ ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
+ if (pad && !send)
+ rec->length -= pad;
}
- return(1);
+ return ret;
}
+
int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
{
unsigned int ret;
@@ -841,7 +912,7 @@ int tls1_final_finish_mac(SSL *s,
for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
{
- if (mask & s->s3->tmp.new_cipher->algorithm2)
+ if (mask & ssl_get_algorithm2(s))
{
int hashsize = EVP_MD_size(md);
if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
@@ -860,7 +931,7 @@ int tls1_final_finish_mac(SSL *s,
}
}
- if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ if (!tls1_PRF(ssl_get_algorithm2(s),
str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
s->session->master_key,s->session->master_key_length,
out,buf2,sizeof buf2))
@@ -878,10 +949,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
SSL3_RECORD *rec;
unsigned char *seq;
EVP_MD_CTX *hash;
- size_t md_size;
+ size_t md_size, orig_len;
int i;
EVP_MD_CTX hmac, *mac_ctx;
- unsigned char buf[5];
+ unsigned char header[13];
int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM));
int t;
@@ -902,12 +973,6 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
OPENSSL_assert(t >= 0);
md_size=t;
- buf[0]=rec->type;
- buf[1]=(unsigned char)(ssl->version>>8);
- buf[2]=(unsigned char)(ssl->version);
- buf[3]=rec->length>>8;
- buf[4]=rec->length&0xff;
-
/* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
if (stream_mac)
{
@@ -926,17 +991,55 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p);
memcpy (p,&seq[2],6);
- EVP_DigestSignUpdate(mac_ctx,dtlsseq,8);
+ memcpy(header, dtlsseq, 8);
}
else
- EVP_DigestSignUpdate(mac_ctx,seq,8);
+ memcpy(header, seq, 8);
+
+ /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */
+ orig_len = rec->length+md_size+((unsigned int)rec->type>>8);
+ rec->type &= 0xff;
+
+ header[8]=rec->type;
+ header[9]=(unsigned char)(ssl->version>>8);
+ header[10]=(unsigned char)(ssl->version);
+ header[11]=(rec->length)>>8;
+ header[12]=(rec->length)&0xff;
- EVP_DigestSignUpdate(mac_ctx,buf,5);
- EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
- t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
- OPENSSL_assert(t > 0);
+ if (!send &&
+ EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+ ssl3_cbc_record_digest_supported(mac_ctx))
+ {
+ /* This is a CBC-encrypted record. We must avoid leaking any
+ * timing-side channel information about how many blocks of
+ * data we are hashing because that gives an attacker a
+ * timing-oracle. */
+ ssl3_cbc_digest_record(
+ mac_ctx,
+ md, &md_size,
+ header, rec->input,
+ rec->length + md_size, orig_len,
+ ssl->s3->read_mac_secret,
+ ssl->s3->read_mac_secret_size,
+ 0 /* not SSLv3 */);
+ }
+ else
+ {
+ EVP_DigestSignUpdate(mac_ctx,header,sizeof(header));
+ EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
+ t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
+ OPENSSL_assert(t > 0);
+#ifdef OPENSSL_FIPS
+ if (!send && FIPS_mode())
+ tls_fips_digest_extra(
+ ssl->enc_read_ctx,
+ mac_ctx, rec->input,
+ rec->length, orig_len);
+#endif
+ }
- if (!stream_mac) EVP_MD_CTX_cleanup(&hmac);
+ if (!stream_mac)
+ EVP_MD_CTX_cleanup(&hmac);
#ifdef TLS_DEBUG
printf("sec=");
{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
@@ -970,6 +1073,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
const void *co = NULL, *so = NULL;
int col = 0, sol = 0;
+
#ifdef KSSL_DEBUG
printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
#endif /* KSSL_DEBUG */
@@ -986,7 +1090,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
}
#endif
- tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ tls1_PRF(ssl_get_algorithm2(s),
TLS_MD_MASTER_SECRET_CONST,TLS_MD_MASTER_SECRET_CONST_SIZE,
s->s3->client_random,SSL3_RANDOM_SIZE,
co, col,
@@ -994,6 +1098,16 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
so, sol,
p,len,
s->session->master_key,buff,sizeof buff);
+#ifdef SSL_DEBUG
+ fprintf(stderr, "Premaster Secret:\n");
+ BIO_dump_fp(stderr, (char *)p, len);
+ fprintf(stderr, "Client Random:\n");
+ BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE);
+ fprintf(stderr, "Server Random:\n");
+ BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE);
+ fprintf(stderr, "Master Secret:\n");
+ BIO_dump_fp(stderr, (char *)s->session->master_key, SSL3_MASTER_SECRET_SIZE);
+#endif
#ifdef KSSL_DEBUG
printf ("tls1_generate_master_secret() complete\n");
@@ -1131,4 +1245,3 @@ int tls1_alert_code(int code)
default: return(-1);
}
}
-
diff --git a/deps/openssl/openssl/ssl/t1_lib.c b/deps/openssl/openssl/ssl/t1_lib.c
index 03becbc10..e08088c57 100644
--- a/deps/openssl/openssl/ssl/t1_lib.c
+++ b/deps/openssl/openssl/ssl/t1_lib.c
@@ -114,6 +114,7 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/ocsp.h>
+#include <openssl/rand.h>
#include "ssl_locl.h"
const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
@@ -167,10 +168,11 @@ void tls1_free(SSL *s)
void tls1_clear(SSL *s)
{
ssl3_clear(s);
- s->version=TLS1_VERSION;
+ s->version = s->method->version;
}
#ifndef OPENSSL_NO_EC
+
static int nid_list[] =
{
NID_sect163k1, /* sect163k1 (1) */
@@ -199,7 +201,36 @@ static int nid_list[] =
NID_secp384r1, /* secp384r1 (24) */
NID_secp521r1 /* secp521r1 (25) */
};
-
+
+static int pref_list[] =
+ {
+ NID_sect571r1, /* sect571r1 (14) */
+ NID_sect571k1, /* sect571k1 (13) */
+ NID_secp521r1, /* secp521r1 (25) */
+ NID_sect409k1, /* sect409k1 (11) */
+ NID_sect409r1, /* sect409r1 (12) */
+ NID_secp384r1, /* secp384r1 (24) */
+ NID_sect283k1, /* sect283k1 (9) */
+ NID_sect283r1, /* sect283r1 (10) */
+ NID_secp256k1, /* secp256k1 (22) */
+ NID_X9_62_prime256v1, /* secp256r1 (23) */
+ NID_sect239k1, /* sect239k1 (8) */
+ NID_sect233k1, /* sect233k1 (6) */
+ NID_sect233r1, /* sect233r1 (7) */
+ NID_secp224k1, /* secp224k1 (20) */
+ NID_secp224r1, /* secp224r1 (21) */
+ NID_sect193r1, /* sect193r1 (4) */
+ NID_sect193r2, /* sect193r2 (5) */
+ NID_secp192k1, /* secp192k1 (18) */
+ NID_X9_62_prime192v1, /* secp192r1 (19) */
+ NID_sect163k1, /* sect163k1 (1) */
+ NID_sect163r1, /* sect163r1 (2) */
+ NID_sect163r2, /* sect163r2 (3) */
+ NID_secp160k1, /* secp160k1 (15) */
+ NID_secp160r1, /* secp160r1 (16) */
+ NID_secp160r2, /* secp160r2 (17) */
+ };
+
int tls1_ec_curve_id2nid(int curve_id)
{
/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
@@ -271,6 +302,64 @@ int tls1_ec_nid2curve_id(int nid)
#endif /* OPENSSL_NO_EC */
#ifndef OPENSSL_NO_TLSEXT
+
+/* List of supported signature algorithms and hashes. Should make this
+ * customisable at some point, for now include everything we support.
+ */
+
+#ifdef OPENSSL_NO_RSA
+#define tlsext_sigalg_rsa(md) /* */
+#else
+#define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
+#endif
+
+#ifdef OPENSSL_NO_DSA
+#define tlsext_sigalg_dsa(md) /* */
+#else
+#define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
+#endif
+
+#ifdef OPENSSL_NO_ECDSA
+#define tlsext_sigalg_ecdsa(md) /* */
+#else
+#define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
+#endif
+
+#define tlsext_sigalg(md) \
+ tlsext_sigalg_rsa(md) \
+ tlsext_sigalg_dsa(md) \
+ tlsext_sigalg_ecdsa(md)
+
+static unsigned char tls12_sigalgs[] = {
+#ifndef OPENSSL_NO_SHA512
+ tlsext_sigalg(TLSEXT_hash_sha512)
+ tlsext_sigalg(TLSEXT_hash_sha384)
+#endif
+#ifndef OPENSSL_NO_SHA256
+ tlsext_sigalg(TLSEXT_hash_sha256)
+ tlsext_sigalg(TLSEXT_hash_sha224)
+#endif
+#ifndef OPENSSL_NO_SHA
+ tlsext_sigalg(TLSEXT_hash_sha1)
+#endif
+#ifndef OPENSSL_NO_MD5
+ tlsext_sigalg_rsa(TLSEXT_hash_md5)
+#endif
+};
+
+int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
+ {
+ size_t slen = sizeof(tls12_sigalgs);
+#ifdef OPENSSL_FIPS
+ /* If FIPS mode don't include MD5 which is last */
+ if (FIPS_mode())
+ slen -= 2;
+#endif
+ if (p)
+ memcpy(p, tls12_sigalgs, slen);
+ return (int)slen;
+ }
+
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
{
int extdatalen=0;
@@ -318,7 +407,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
/* Add RI if renegotiating */
- if (s->new_session)
+ if (s->renegotiate)
{
int el;
@@ -342,6 +431,34 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
ret += el;
}
+#ifndef OPENSSL_NO_SRP
+ /* Add SRP username if there is one */
+ if (s->srp_ctx.login != NULL)
+ { /* Add TLS extension SRP username to the Client Hello message */
+
+ int login_len = strlen(s->srp_ctx.login);
+ if (login_len > 255 || login_len == 0)
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ /* check for enough space.
+ 4 for the srp type type and entension length
+ 1 for the srp user identity
+ + srp user identity length
+ */
+ if ((limit - ret - 5 - login_len) < 0) return NULL;
+
+ /* fill in the extension */
+ s2n(TLSEXT_TYPE_srp,ret);
+ s2n(login_len+1,ret);
+ (*ret++) = (unsigned char) login_len;
+ memcpy(ret, s->srp_ctx.login, login_len);
+ ret+=login_len;
+ }
+#endif
+
#ifndef OPENSSL_NO_EC
if (s->tlsext_ecpointformatlist != NULL &&
s->version != DTLS1_VERSION)
@@ -427,6 +544,17 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
skip_ext:
+ if (TLS1_get_client_version(s) >= TLS1_2_VERSION)
+ {
+ if ((size_t)(limit - ret) < sizeof(tls12_sigalgs) + 6)
+ return NULL;
+ s2n(TLSEXT_TYPE_signature_algorithms,ret);
+ s2n(sizeof(tls12_sigalgs) + 2, ret);
+ s2n(sizeof(tls12_sigalgs), ret);
+ memcpy(ret, tls12_sigalgs, sizeof(tls12_sigalgs));
+ ret += sizeof(tls12_sigalgs);
+ }
+
#ifdef TLSEXT_TYPE_opaque_prf_input
if (s->s3->client_opaque_prf_input != NULL &&
s->version != DTLS1_VERSION)
@@ -495,6 +623,20 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ /* Add Heartbeat extension */
+ s2n(TLSEXT_TYPE_heartbeat,ret);
+ s2n(1,ret);
+ /* Set mode:
+ * 1: peer may send requests
+ * 2: peer not allowed to send requests
+ */
+ if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
+ *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
+ else
+ *(ret++) = SSL_TLSEXT_HB_ENABLED;
+#endif
+
#ifndef OPENSSL_NO_NEXTPROTONEG
if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len)
{
@@ -507,6 +649,27 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
#endif
+#ifndef OPENSSL_NO_SRTP
+ if(SSL_get_srtp_profiles(s))
+ {
+ int el;
+
+ ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
+
+ if((limit - p - 4 - el) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_use_srtp,ret);
+ s2n(el,ret);
+
+ if(ssl_add_clienthello_use_srtp_ext(s, ret, &el, el))
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+ ret += el;
+ }
+#endif
+
if ((extdatalen = ret-p-2)== 0)
return p;
@@ -619,6 +782,28 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
ret += sol;
}
#endif
+
+#ifndef OPENSSL_NO_SRTP
+ if(s->srtp_profile)
+ {
+ int el;
+
+ ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
+
+ if((limit - p - 4 - el) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_use_srtp,ret);
+ s2n(el,ret);
+
+ if(ssl_add_serverhello_use_srtp_ext(s, ret, &el, el))
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+ ret+=el;
+ }
+#endif
+
if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81)
&& (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG))
{ const unsigned char cryptopro_ext[36] = {
@@ -634,6 +819,24 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ /* Add Heartbeat extension if we've received one */
+ if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED)
+ {
+ s2n(TLSEXT_TYPE_heartbeat,ret);
+ s2n(1,ret);
+ /* Set mode:
+ * 1: peer may send requests
+ * 2: peer not allowed to send requests
+ */
+ if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
+ *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
+ else
+ *(ret++) = SSL_TLSEXT_HB_ENABLED;
+
+ }
+#endif
+
#ifndef OPENSSL_NO_NEXTPROTONEG
next_proto_neg_seen = s->s3->next_proto_neg_seen;
s->s3->next_proto_neg_seen = 0;
@@ -670,9 +873,18 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
unsigned short len;
unsigned char *data = *p;
int renegotiate_seen = 0;
+ int sigalg_seen = 0;
s->servername_done = 0;
s->tlsext_status_type = -1;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ s->s3->next_proto_neg_seen = 0;
+#endif
+
+#ifndef OPENSSL_NO_HEARTBEATS
+ s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
+ SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
+#endif
if (data >= (d+n-2))
goto ri_check;
@@ -800,6 +1012,31 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
}
}
+#ifndef OPENSSL_NO_SRP
+ else if (type == TLSEXT_TYPE_srp)
+ {
+ if (size <= 0 || ((len = data[0])) != (size -1))
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ if (s->srp_ctx.login != NULL)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ if ((s->srp_ctx.login = OPENSSL_malloc(len+1)) == NULL)
+ return -1;
+ memcpy(s->srp_ctx.login, &data[1], len);
+ s->srp_ctx.login[len]='\0';
+
+ if (strlen(s->srp_ctx.login) != len)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ }
+#endif
#ifndef OPENSSL_NO_EC
else if (type == TLSEXT_TYPE_ec_point_formats &&
@@ -844,7 +1081,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
int ellipticcurvelist_length = (*(sdata++) << 8);
ellipticcurvelist_length += (*(sdata++));
- if (ellipticcurvelist_length != size - 2)
+ if (ellipticcurvelist_length != size - 2 ||
+ ellipticcurvelist_length < 1)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
@@ -920,6 +1158,28 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
return 0;
renegotiate_seen = 1;
}
+ else if (type == TLSEXT_TYPE_signature_algorithms)
+ {
+ int dsize;
+ if (sigalg_seen || size < 2)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ sigalg_seen = 1;
+ n2s(data,dsize);
+ size -= 2;
+ if (dsize != size || dsize & 1)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ if (!tls1_process_sigalgs(s, data, dsize))
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ }
else if (type == TLSEXT_TYPE_status_request &&
s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
{
@@ -1032,9 +1292,26 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
else
s->tlsext_status_type = -1;
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ else if (type == TLSEXT_TYPE_heartbeat)
+ {
+ switch(data[0])
+ {
+ case 0x01: /* Client allows us to send HB requests */
+ s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
+ break;
+ case 0x02: /* Client doesn't accept HB requests */
+ s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
+ s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
+ break;
+ default: *al = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+ }
+#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
else if (type == TLSEXT_TYPE_next_proto_neg &&
- s->s3->tmp.finish_md_len == 0)
+ s->s3->tmp.finish_md_len == 0)
{
/* We shouldn't accept this extension on a
* renegotiation.
@@ -1056,6 +1333,15 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
#endif
/* session ticket processed earlier */
+#ifndef OPENSSL_NO_SRTP
+ else if (type == TLSEXT_TYPE_use_srtp)
+ {
+ if(ssl_parse_clienthello_use_srtp_ext(s, data, size,
+ al))
+ return 0;
+ }
+#endif
+
data+=size;
}
@@ -1065,7 +1351,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
/* Need RI if renegotiating */
- if (!renegotiate_seen && s->new_session &&
+ if (!renegotiate_seen && s->renegotiate &&
!(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
{
*al = SSL_AD_HANDSHAKE_FAILURE;
@@ -1081,7 +1367,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
/* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
* elements of zero length are allowed and the set of elements must exactly fill
* the length of the block. */
-static int ssl_next_proto_validate(unsigned char *d, unsigned len)
+static char ssl_next_proto_validate(unsigned char *d, unsigned len)
{
unsigned int off = 0;
@@ -1106,6 +1392,15 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
int tlsext_servername = 0;
int renegotiate_seen = 0;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ s->s3->next_proto_neg_seen = 0;
+#endif
+
+#ifndef OPENSSL_NO_HEARTBEATS
+ s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
+ SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
+#endif
+
if (data >= (d+n-2))
goto ri_check;
@@ -1145,7 +1440,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
unsigned char *sdata = data;
int ecpointformatlist_length = *(sdata++);
- if (ecpointformatlist_length != size - 1)
+ if (ecpointformatlist_length != size - 1 ||
+ ecpointformatlist_length < 1)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
@@ -1232,13 +1528,14 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
s->tlsext_status_expected = 1;
}
#ifndef OPENSSL_NO_NEXTPROTONEG
- else if (type == TLSEXT_TYPE_next_proto_neg)
+ else if (type == TLSEXT_TYPE_next_proto_neg &&
+ s->s3->tmp.finish_md_len == 0)
{
unsigned char *selected;
unsigned char selected_len;
/* We must have requested it. */
- if ((s->ctx->next_proto_select_cb == NULL))
+ if (s->ctx->next_proto_select_cb == NULL)
{
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
return 0;
@@ -1262,6 +1559,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
}
memcpy(s->next_proto_negotiated, selected, selected_len);
s->next_proto_negotiated_len = selected_len;
+ s->s3->next_proto_neg_seen = 1;
}
#endif
else if (type == TLSEXT_TYPE_renegotiate)
@@ -1270,6 +1568,32 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
return 0;
renegotiate_seen = 1;
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ else if (type == TLSEXT_TYPE_heartbeat)
+ {
+ switch(data[0])
+ {
+ case 0x01: /* Server allows us to send HB requests */
+ s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
+ break;
+ case 0x02: /* Server doesn't accept HB requests */
+ s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
+ s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
+ break;
+ default: *al = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_SRTP
+ else if (type == TLSEXT_TYPE_use_srtp)
+ {
+ if(ssl_parse_serverhello_use_srtp_ext(s, data, size,
+ al))
+ return 0;
+ }
+#endif
+
data+=size;
}
@@ -1349,7 +1673,7 @@ int ssl_prepare_clienthello_tlsext(SSL *s)
break;
}
}
- using_ecc = using_ecc && (s->version == TLS1_VERSION);
+ using_ecc = using_ecc && (s->version >= TLS1_VERSION);
if (using_ecc)
{
if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
@@ -1365,16 +1689,19 @@ int ssl_prepare_clienthello_tlsext(SSL *s)
/* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
- s->tlsext_ellipticcurvelist_length = sizeof(nid_list)/sizeof(nid_list[0]) * 2;
+ s->tlsext_ellipticcurvelist_length = sizeof(pref_list)/sizeof(pref_list[0]) * 2;
if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
{
s->tlsext_ellipticcurvelist_length = 0;
SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
return -1;
}
- for (i = 1, j = s->tlsext_ellipticcurvelist; (unsigned int)i <=
- sizeof(nid_list)/sizeof(nid_list[0]); i++)
- s2n(i,j);
+ for (i = 0, j = s->tlsext_ellipticcurvelist; (unsigned int)i <
+ sizeof(pref_list)/sizeof(pref_list[0]); i++)
+ {
+ int id = tls1_ec_nid2curve_id(pref_list[i]);
+ s2n(id,j);
+ }
}
#endif /* OPENSSL_NO_EC */
@@ -1446,7 +1773,7 @@ int ssl_prepare_serverhello_tlsext(SSL *s)
return 1;
}
-int ssl_check_clienthello_tlsext(SSL *s)
+int ssl_check_clienthello_tlsext_early(SSL *s)
{
int ret=SSL_TLSEXT_ERR_NOACK;
int al = SSL_AD_UNRECOGNIZED_NAME;
@@ -1465,42 +1792,12 @@ int ssl_check_clienthello_tlsext(SSL *s)
else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)
ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
- /* If status request then ask callback what to do.
- * Note: this must be called after servername callbacks in case
- * the certificate has changed.
- */
- if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
- {
- int r;
- r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
- switch (r)
- {
- /* We don't want to send a status request response */
- case SSL_TLSEXT_ERR_NOACK:
- s->tlsext_status_expected = 0;
- break;
- /* status request response should be sent */
- case SSL_TLSEXT_ERR_OK:
- if (s->tlsext_ocsp_resp)
- s->tlsext_status_expected = 1;
- else
- s->tlsext_status_expected = 0;
- break;
- /* something bad happened */
- case SSL_TLSEXT_ERR_ALERT_FATAL:
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_INTERNAL_ERROR;
- goto err;
- }
- }
- else
- s->tlsext_status_expected = 0;
-
#ifdef TLSEXT_TYPE_opaque_prf_input
{
/* This sort of belongs into ssl_prepare_serverhello_tlsext(),
* but we might be sending an alert in response to the client hello,
- * so this has to happen here in ssl_check_clienthello_tlsext(). */
+ * so this has to happen here in
+ * ssl_check_clienthello_tlsext_early(). */
int r = 1;
@@ -1552,8 +1849,8 @@ int ssl_check_clienthello_tlsext(SSL *s)
}
}
-#endif
err:
+#endif
switch (ret)
{
case SSL_TLSEXT_ERR_ALERT_FATAL:
@@ -1571,6 +1868,71 @@ int ssl_check_clienthello_tlsext(SSL *s)
}
}
+int ssl_check_clienthello_tlsext_late(SSL *s)
+ {
+ int ret = SSL_TLSEXT_ERR_OK;
+ int al;
+
+ /* If status request then ask callback what to do.
+ * Note: this must be called after servername callbacks in case
+ * the certificate has changed, and must be called after the cipher
+ * has been chosen because this may influence which certificate is sent
+ */
+ if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
+ {
+ int r;
+ CERT_PKEY *certpkey;
+ certpkey = ssl_get_server_send_pkey(s);
+ /* If no certificate can't return certificate status */
+ if (certpkey == NULL)
+ {
+ s->tlsext_status_expected = 0;
+ return 1;
+ }
+ /* Set current certificate to one we will use so
+ * SSL_get_certificate et al can pick it up.
+ */
+ s->cert->key = certpkey;
+ r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+ switch (r)
+ {
+ /* We don't want to send a status request response */
+ case SSL_TLSEXT_ERR_NOACK:
+ s->tlsext_status_expected = 0;
+ break;
+ /* status request response should be sent */
+ case SSL_TLSEXT_ERR_OK:
+ if (s->tlsext_ocsp_resp)
+ s->tlsext_status_expected = 1;
+ else
+ s->tlsext_status_expected = 0;
+ break;
+ /* something bad happened */
+ case SSL_TLSEXT_ERR_ALERT_FATAL:
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ al = SSL_AD_INTERNAL_ERROR;
+ goto err;
+ }
+ }
+ else
+ s->tlsext_status_expected = 0;
+
+ err:
+ switch (ret)
+ {
+ case SSL_TLSEXT_ERR_ALERT_FATAL:
+ ssl3_send_alert(s,SSL3_AL_FATAL,al);
+ return -1;
+
+ case SSL_TLSEXT_ERR_ALERT_WARNING:
+ ssl3_send_alert(s,SSL3_AL_WARNING,al);
+ return 1;
+
+ default:
+ return 1;
+ }
+ }
+
int ssl_check_serverhello_tlsext(SSL *s)
{
int ret=SSL_TLSEXT_ERR_NOACK;
@@ -1683,26 +2045,56 @@ int ssl_check_serverhello_tlsext(SSL *s)
}
}
-/* Since the server cache lookup is done early on in the processing of client
- * hello and other operations depend on the result we need to handle any TLS
- * session ticket extension at the same time.
+/* Since the server cache lookup is done early on in the processing of the
+ * ClientHello, and other operations depend on the result, we need to handle
+ * any TLS session ticket extension at the same time.
+ *
+ * session_id: points at the session ID in the ClientHello. This code will
+ * read past the end of this in order to parse out the session ticket
+ * extension, if any.
+ * len: the length of the session ID.
+ * limit: a pointer to the first byte after the ClientHello.
+ * ret: (output) on return, if a ticket was decrypted, then this is set to
+ * point to the resulting session.
+ *
+ * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
+ * ciphersuite, in which case we have no use for session tickets and one will
+ * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
+ *
+ * Returns:
+ * -1: fatal error, either from parsing or decrypting the ticket.
+ * 0: no ticket was found (or was ignored, based on settings).
+ * 1: a zero length extension was found, indicating that the client supports
+ * session tickets but doesn't currently have one to offer.
+ * 2: either s->tls_session_secret_cb was set, or a ticket was offered but
+ * couldn't be decrypted because of a non-fatal error.
+ * 3: a ticket was successfully decrypted and *ret was set.
+ *
+ * Side effects:
+ * Sets s->tlsext_ticket_expected to 1 if the server will have to issue
+ * a new session ticket to the client because the client indicated support
+ * (and s->tls_session_secret_cb is NULL) but the client either doesn't have
+ * a session ticket or we couldn't use the one it gave us, or if
+ * s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
+ * Otherwise, s->tlsext_ticket_expected is set to 0.
*/
-
int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
- const unsigned char *limit, SSL_SESSION **ret)
+ const unsigned char *limit, SSL_SESSION **ret)
{
/* Point after session ID in client hello */
const unsigned char *p = session_id + len;
unsigned short i;
+ *ret = NULL;
+ s->tlsext_ticket_expected = 0;
+
/* If tickets disabled behave as if no ticket present
- * to permit stateful resumption.
- */
+ * to permit stateful resumption.
+ */
if (SSL_get_options(s) & SSL_OP_NO_TICKET)
- return 1;
-
+ return 0;
if ((s->version <= SSL3_VERSION) || !limit)
- return 1;
+ return 0;
if (p >= limit)
return -1;
/* Skip past DTLS cookie */
@@ -1725,7 +2117,7 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
return -1;
/* Now at start of extensions */
if ((p + 2) >= limit)
- return 1;
+ return 0;
n2s(p, i);
while ((p + 4) <= limit)
{
@@ -1733,39 +2125,61 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
n2s(p, type);
n2s(p, size);
if (p + size > limit)
- return 1;
+ return 0;
if (type == TLSEXT_TYPE_session_ticket)
{
- /* If tickets disabled indicate cache miss which will
- * trigger a full handshake
- */
- if (SSL_get_options(s) & SSL_OP_NO_TICKET)
- return 1;
- /* If zero length note client will accept a ticket
- * and indicate cache miss to trigger full handshake
- */
+ int r;
if (size == 0)
{
+ /* The client will accept a ticket but doesn't
+ * currently have one. */
s->tlsext_ticket_expected = 1;
- return 0; /* Cache miss */
+ return 1;
}
if (s->tls_session_secret_cb)
{
- /* Indicate cache miss here and instead of
- * generating the session from ticket now,
- * trigger abbreviated handshake based on
- * external mechanism to calculate the master
- * secret later. */
- return 0;
+ /* Indicate that the ticket couldn't be
+ * decrypted rather than generating the session
+ * from ticket now, trigger abbreviated
+ * handshake based on external mechanism to
+ * calculate the master secret later. */
+ return 2;
+ }
+ r = tls_decrypt_ticket(s, p, size, session_id, len, ret);
+ switch (r)
+ {
+ case 2: /* ticket couldn't be decrypted */
+ s->tlsext_ticket_expected = 1;
+ return 2;
+ case 3: /* ticket was decrypted */
+ return r;
+ case 4: /* ticket decrypted but need to renew */
+ s->tlsext_ticket_expected = 1;
+ return 3;
+ default: /* fatal error */
+ return -1;
}
- return tls_decrypt_ticket(s, p, size, session_id, len,
- ret);
}
p += size;
}
- return 1;
+ return 0;
}
+/* tls_decrypt_ticket attempts to decrypt a session ticket.
+ *
+ * etick: points to the body of the session ticket extension.
+ * eticklen: the length of the session tickets extenion.
+ * sess_id: points at the session ID.
+ * sesslen: the length of the session ID.
+ * psess: (output) on return, if a ticket was decrypted, then this is set to
+ * point to the resulting session.
+ *
+ * Returns:
+ * -1: fatal error, either from parsing or decrypting the ticket.
+ * 2: the ticket couldn't be decrypted.
+ * 3: a ticket was successfully decrypted and *psess was set.
+ * 4: same as 3, but the ticket needs to be renewed.
+ */
static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
const unsigned char *sess_id, int sesslen,
SSL_SESSION **psess)
@@ -1780,7 +2194,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
SSL_CTX *tctx = s->initial_ctx;
/* Need at least keyname + iv + some encrypted data */
if (eticklen < 48)
- goto tickerr;
+ return 2;
/* Initialize session ticket encryption and HMAC contexts */
HMAC_CTX_init(&hctx);
EVP_CIPHER_CTX_init(&ctx);
@@ -1792,7 +2206,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
if (rv < 0)
return -1;
if (rv == 0)
- goto tickerr;
+ return 2;
if (rv == 2)
renew_ticket = 1;
}
@@ -1800,15 +2214,15 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
{
/* Check key name matches */
if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
- goto tickerr;
+ return 2;
HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
tlsext_tick_md(), NULL);
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
tctx->tlsext_tick_aes_key, etick + 16);
}
/* Attempt to process session ticket, first conduct sanity and
- * integrity checks on ticket.
- */
+ * integrity checks on ticket.
+ */
mlen = HMAC_size(&hctx);
if (mlen < 0)
{
@@ -1820,8 +2234,8 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
HMAC_Update(&hctx, etick, eticklen);
HMAC_Final(&hctx, tick_hmac, NULL);
HMAC_CTX_cleanup(&hctx);
- if (memcmp(tick_hmac, etick + eticklen, mlen))
- goto tickerr;
+ if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen))
+ return 2;
/* Attempt to decrypt session data */
/* Move p after IV to start of encrypted ticket, update length */
p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
@@ -1834,33 +2248,376 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
}
EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
- goto tickerr;
+ return 2;
slen += mlen;
EVP_CIPHER_CTX_cleanup(&ctx);
p = sdec;
-
+
sess = d2i_SSL_SESSION(NULL, &p, slen);
OPENSSL_free(sdec);
if (sess)
{
- /* The session ID if non-empty is used by some clients to
- * detect that the ticket has been accepted. So we copy it to
- * the session structure. If it is empty set length to zero
- * as required by standard.
- */
+ /* The session ID, if non-empty, is used by some clients to
+ * detect that the ticket has been accepted. So we copy it to
+ * the session structure. If it is empty set length to zero
+ * as required by standard.
+ */
if (sesslen)
memcpy(sess->session_id, sess_id, sesslen);
sess->session_id_length = sesslen;
*psess = sess;
- s->tlsext_ticket_expected = renew_ticket;
+ if (renew_ticket)
+ return 4;
+ else
+ return 3;
+ }
+ ERR_clear_error();
+ /* For session parse failure, indicate that we need to send a new
+ * ticket. */
+ return 2;
+ }
+
+/* Tables to translate from NIDs to TLS v1.2 ids */
+
+typedef struct
+ {
+ int nid;
+ int id;
+ } tls12_lookup;
+
+static tls12_lookup tls12_md[] = {
+#ifndef OPENSSL_NO_MD5
+ {NID_md5, TLSEXT_hash_md5},
+#endif
+#ifndef OPENSSL_NO_SHA
+ {NID_sha1, TLSEXT_hash_sha1},
+#endif
+#ifndef OPENSSL_NO_SHA256
+ {NID_sha224, TLSEXT_hash_sha224},
+ {NID_sha256, TLSEXT_hash_sha256},
+#endif
+#ifndef OPENSSL_NO_SHA512
+ {NID_sha384, TLSEXT_hash_sha384},
+ {NID_sha512, TLSEXT_hash_sha512}
+#endif
+};
+
+static tls12_lookup tls12_sig[] = {
+#ifndef OPENSSL_NO_RSA
+ {EVP_PKEY_RSA, TLSEXT_signature_rsa},
+#endif
+#ifndef OPENSSL_NO_DSA
+ {EVP_PKEY_DSA, TLSEXT_signature_dsa},
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ {EVP_PKEY_EC, TLSEXT_signature_ecdsa}
+#endif
+};
+
+static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
+ {
+ size_t i;
+ for (i = 0; i < tlen; i++)
+ {
+ if (table[i].nid == nid)
+ return table[i].id;
+ }
+ return -1;
+ }
+#if 0
+static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
+ {
+ size_t i;
+ for (i = 0; i < tlen; i++)
+ {
+ if (table[i].id == id)
+ return table[i].nid;
+ }
+ return -1;
+ }
+#endif
+
+int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md)
+ {
+ int sig_id, md_id;
+ if (!md)
+ return 0;
+ md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
+ sizeof(tls12_md)/sizeof(tls12_lookup));
+ if (md_id == -1)
+ return 0;
+ sig_id = tls12_get_sigid(pk);
+ if (sig_id == -1)
+ return 0;
+ p[0] = (unsigned char)md_id;
+ p[1] = (unsigned char)sig_id;
+ return 1;
+ }
+
+int tls12_get_sigid(const EVP_PKEY *pk)
+ {
+ return tls12_find_id(pk->type, tls12_sig,
+ sizeof(tls12_sig)/sizeof(tls12_lookup));
+ }
+
+const EVP_MD *tls12_get_hash(unsigned char hash_alg)
+ {
+ switch(hash_alg)
+ {
+#ifndef OPENSSL_NO_MD5
+ case TLSEXT_hash_md5:
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return NULL;
+#endif
+ return EVP_md5();
+#endif
+#ifndef OPENSSL_NO_SHA
+ case TLSEXT_hash_sha1:
+ return EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_SHA256
+ case TLSEXT_hash_sha224:
+ return EVP_sha224();
+
+ case TLSEXT_hash_sha256:
+ return EVP_sha256();
+#endif
+#ifndef OPENSSL_NO_SHA512
+ case TLSEXT_hash_sha384:
+ return EVP_sha384();
+
+ case TLSEXT_hash_sha512:
+ return EVP_sha512();
+#endif
+ default:
+ return NULL;
+
+ }
+ }
+
+/* Set preferred digest for each key type */
+
+int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
+ {
+ int i, idx;
+ const EVP_MD *md;
+ CERT *c = s->cert;
+ /* Extension ignored for TLS versions below 1.2 */
+ if (TLS1_get_version(s) < TLS1_2_VERSION)
return 1;
+ /* Should never happen */
+ if (!c)
+ return 0;
+
+ c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL;
+ c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL;
+ c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL;
+ c->pkeys[SSL_PKEY_ECC].digest = NULL;
+
+ for (i = 0; i < dsize; i += 2)
+ {
+ unsigned char hash_alg = data[i], sig_alg = data[i+1];
+
+ switch(sig_alg)
+ {
+#ifndef OPENSSL_NO_RSA
+ case TLSEXT_signature_rsa:
+ idx = SSL_PKEY_RSA_SIGN;
+ break;
+#endif
+#ifndef OPENSSL_NO_DSA
+ case TLSEXT_signature_dsa:
+ idx = SSL_PKEY_DSA_SIGN;
+ break;
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ case TLSEXT_signature_ecdsa:
+ idx = SSL_PKEY_ECC;
+ break;
+#endif
+ default:
+ continue;
+ }
+
+ if (c->pkeys[idx].digest == NULL)
+ {
+ md = tls12_get_hash(hash_alg);
+ if (md)
+ {
+ c->pkeys[idx].digest = md;
+ if (idx == SSL_PKEY_RSA_SIGN)
+ c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
+ }
+ }
+
}
- /* If session decrypt failure indicate a cache miss and set state to
- * send a new ticket
- */
- tickerr:
- s->tlsext_ticket_expected = 1;
+
+
+ /* Set any remaining keys to default values. NOTE: if alg is not
+ * supported it stays as NULL.
+ */
+#ifndef OPENSSL_NO_DSA
+ if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
+ c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_RSA
+ if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest)
+ {
+ c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
+ c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
+ }
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ if (!c->pkeys[SSL_PKEY_ECC].digest)
+ c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
+#endif
+ return 1;
+ }
+
+#endif
+
+#ifndef OPENSSL_NO_HEARTBEATS
+int
+tls1_process_heartbeat(SSL *s)
+ {
+ unsigned char *p = &s->s3->rrec.data[0], *pl;
+ unsigned short hbtype;
+ unsigned int payload;
+ unsigned int padding = 16; /* Use minimum padding */
+
+ /* Read type and payload length first */
+ hbtype = *p++;
+ n2s(p, payload);
+ pl = p;
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
+ &s->s3->rrec.data[0], s->s3->rrec.length,
+ s, s->msg_callback_arg);
+
+ if (hbtype == TLS1_HB_REQUEST)
+ {
+ unsigned char *buffer, *bp;
+ int r;
+
+ /* Allocate memory for the response, size is 1 bytes
+ * message type, plus 2 bytes payload length, plus
+ * payload, plus padding
+ */
+ buffer = OPENSSL_malloc(1 + 2 + payload + padding);
+ bp = buffer;
+
+ /* Enter response type, length and copy payload */
+ *bp++ = TLS1_HB_RESPONSE;
+ s2n(payload, bp);
+ memcpy(bp, pl, payload);
+ bp += payload;
+ /* Random padding */
+ RAND_pseudo_bytes(bp, padding);
+
+ r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
+
+ if (r >= 0 && s->msg_callback)
+ s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
+ buffer, 3 + payload + padding,
+ s, s->msg_callback_arg);
+
+ OPENSSL_free(buffer);
+
+ if (r < 0)
+ return r;
+ }
+ else if (hbtype == TLS1_HB_RESPONSE)
+ {
+ unsigned int seq;
+
+ /* We only send sequence numbers (2 bytes unsigned int),
+ * and 16 random bytes, so we just try to read the
+ * sequence number */
+ n2s(pl, seq);
+
+ if (payload == 18 && seq == s->tlsext_hb_seq)
+ {
+ s->tlsext_hb_seq++;
+ s->tlsext_hb_pending = 0;
+ }
+ }
+
return 0;
}
+int
+tls1_heartbeat(SSL *s)
+ {
+ unsigned char *buf, *p;
+ int ret;
+ unsigned int payload = 18; /* Sequence number + random bytes */
+ unsigned int padding = 16; /* Use minimum padding */
+
+ /* Only send if peer supports and accepts HB requests... */
+ if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
+ s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS)
+ {
+ SSLerr(SSL_F_TLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
+ return -1;
+ }
+
+ /* ...and there is none in flight yet... */
+ if (s->tlsext_hb_pending)
+ {
+ SSLerr(SSL_F_TLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING);
+ return -1;
+ }
+
+ /* ...and no handshake in progress. */
+ if (SSL_in_init(s) || s->in_handshake)
+ {
+ SSLerr(SSL_F_TLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE);
+ return -1;
+ }
+
+ /* Check if padding is too long, payload and padding
+ * must not exceed 2^14 - 3 = 16381 bytes in total.
+ */
+ OPENSSL_assert(payload + padding <= 16381);
+
+ /* Create HeartBeat message, we just use a sequence number
+ * as payload to distuingish different messages and add
+ * some random stuff.
+ * - Message Type, 1 byte
+ * - Payload Length, 2 bytes (unsigned int)
+ * - Payload, the sequence number (2 bytes uint)
+ * - Payload, random bytes (16 bytes uint)
+ * - Padding
+ */
+ buf = OPENSSL_malloc(1 + 2 + payload + padding);
+ p = buf;
+ /* Message Type */
+ *p++ = TLS1_HB_REQUEST;
+ /* Payload length (18 bytes here) */
+ s2n(payload, p);
+ /* Sequence number */
+ s2n(s->tlsext_hb_seq, p);
+ /* 16 random bytes */
+ RAND_pseudo_bytes(p, 16);
+ p += 16;
+ /* Random padding */
+ RAND_pseudo_bytes(p, padding);
+
+ ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
+ if (ret >= 0)
+ {
+ if (s->msg_callback)
+ s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
+ buf, 3 + payload + padding,
+ s, s->msg_callback_arg);
+
+ s->tlsext_hb_pending = 1;
+ }
+
+ OPENSSL_free(buf);
+
+ return ret;
+ }
#endif
diff --git a/deps/openssl/openssl/ssl/t1_meth.c b/deps/openssl/openssl/ssl/t1_meth.c
index 6ce7c0bbf..53c807de2 100644
--- a/deps/openssl/openssl/ssl/t1_meth.c
+++ b/deps/openssl/openssl/ssl/t1_meth.c
@@ -60,16 +60,28 @@
#include <openssl/objects.h>
#include "ssl_locl.h"
-static const SSL_METHOD *tls1_get_method(int ver);
static const SSL_METHOD *tls1_get_method(int ver)
{
+ if (ver == TLS1_2_VERSION)
+ return TLSv1_2_method();
+ if (ver == TLS1_1_VERSION)
+ return TLSv1_1_method();
if (ver == TLS1_VERSION)
- return(TLSv1_method());
- else
- return(NULL);
+ return TLSv1_method();
+ return NULL;
}
-IMPLEMENT_tls1_meth_func(TLSv1_method,
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method,
+ ssl3_accept,
+ ssl3_connect,
+ tls1_get_method)
+
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method,
+ ssl3_accept,
+ ssl3_connect,
+ tls1_get_method)
+
+IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method,
ssl3_accept,
ssl3_connect,
tls1_get_method)
diff --git a/deps/openssl/openssl/ssl/t1_srvr.c b/deps/openssl/openssl/ssl/t1_srvr.c
index 42525e9e8..f1d156576 100644
--- a/deps/openssl/openssl/ssl/t1_srvr.c
+++ b/deps/openssl/openssl/ssl/t1_srvr.c
@@ -67,13 +67,26 @@
static const SSL_METHOD *tls1_get_server_method(int ver);
static const SSL_METHOD *tls1_get_server_method(int ver)
{
+ if (ver == TLS1_2_VERSION)
+ return TLSv1_2_server_method();
+ if (ver == TLS1_1_VERSION)
+ return TLSv1_1_server_method();
if (ver == TLS1_VERSION)
- return(TLSv1_server_method());
- else
- return(NULL);
+ return TLSv1_server_method();
+ return NULL;
}
-IMPLEMENT_tls1_meth_func(TLSv1_server_method,
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method,
+ ssl3_accept,
+ ssl_undefined_function,
+ tls1_get_server_method)
+
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method,
+ ssl3_accept,
+ ssl_undefined_function,
+ tls1_get_server_method)
+
+IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method,
ssl3_accept,
ssl_undefined_function,
tls1_get_server_method)
diff --git a/deps/openssl/openssl/ssl/tls1.h b/deps/openssl/openssl/ssl/tls1.h
index 71f97227e..c39c267f0 100644
--- a/deps/openssl/openssl/ssl/tls1.h
+++ b/deps/openssl/openssl/ssl/tls1.h
@@ -159,10 +159,24 @@ extern "C" {
#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0
+#define TLS1_2_VERSION 0x0303
+#define TLS1_2_VERSION_MAJOR 0x03
+#define TLS1_2_VERSION_MINOR 0x03
+
+#define TLS1_1_VERSION 0x0302
+#define TLS1_1_VERSION_MAJOR 0x03
+#define TLS1_1_VERSION_MINOR 0x02
+
#define TLS1_VERSION 0x0301
#define TLS1_VERSION_MAJOR 0x03
#define TLS1_VERSION_MINOR 0x01
+#define TLS1_get_version(s) \
+ ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0)
+
+#define TLS1_get_client_version(s) \
+ ((s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0)
+
#define TLS1_AD_DECRYPTION_FAILED 21
#define TLS1_AD_RECORD_OVERFLOW 22
#define TLS1_AD_UNKNOWN_CA 48 /* fatal */
@@ -183,17 +197,42 @@ extern "C" {
#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */
-/* ExtensionType values from RFC3546 / RFC4366 */
+/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */
#define TLSEXT_TYPE_server_name 0
#define TLSEXT_TYPE_max_fragment_length 1
#define TLSEXT_TYPE_client_certificate_url 2
#define TLSEXT_TYPE_trusted_ca_keys 3
#define TLSEXT_TYPE_truncated_hmac 4
#define TLSEXT_TYPE_status_request 5
+/* ExtensionType values from RFC4681 */
+#define TLSEXT_TYPE_user_mapping 6
+
+/* ExtensionType values from RFC5878 */
+#define TLSEXT_TYPE_client_authz 7
+#define TLSEXT_TYPE_server_authz 8
+
+/* ExtensionType values from RFC6091 */
+#define TLSEXT_TYPE_cert_type 9
+
/* ExtensionType values from RFC4492 */
#define TLSEXT_TYPE_elliptic_curves 10
#define TLSEXT_TYPE_ec_point_formats 11
+
+/* ExtensionType value from RFC5054 */
+#define TLSEXT_TYPE_srp 12
+
+/* ExtensionType values from RFC5246 */
+#define TLSEXT_TYPE_signature_algorithms 13
+
+/* ExtensionType value from RFC5764 */
+#define TLSEXT_TYPE_use_srtp 14
+
+/* ExtensionType value from RFC5620 */
+#define TLSEXT_TYPE_heartbeat 15
+
+/* ExtensionType value from RFC4507 */
#define TLSEXT_TYPE_session_ticket 35
+
/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
#if 0 /* will have to be provided externally for now ,
* i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183
@@ -221,12 +260,34 @@ extern "C" {
#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2
#define TLSEXT_ECPOINTFORMAT_last 2
+/* Signature and hash algorithms from RFC 5246 */
+
+#define TLSEXT_signature_anonymous 0
+#define TLSEXT_signature_rsa 1
+#define TLSEXT_signature_dsa 2
+#define TLSEXT_signature_ecdsa 3
+
+#define TLSEXT_hash_none 0
+#define TLSEXT_hash_md5 1
+#define TLSEXT_hash_sha1 2
+#define TLSEXT_hash_sha224 3
+#define TLSEXT_hash_sha256 4
+#define TLSEXT_hash_sha384 5
+#define TLSEXT_hash_sha512 6
+
#ifndef OPENSSL_NO_TLSEXT
#define TLSEXT_MAXLEN_host_name 255
-const char *SSL_get_servername(const SSL *s, const int type) ;
-int SSL_get_servername_type(const SSL *s) ;
+const char *SSL_get_servername(const SSL *s, const int type);
+int SSL_get_servername_type(const SSL *s);
+/* SSL_export_keying_material exports a value derived from the master secret,
+ * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
+ * optional context. (Since a zero length context is allowed, the |use_context|
+ * flag controls whether a context is included.)
+ *
+ * It returns 1 on success and zero otherwise.
+ */
int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
const char *label, size_t llen, const unsigned char *p, size_t plen,
int use_context);
@@ -293,6 +354,16 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
+#ifndef OPENSSL_NO_HEARTBEATS
+#define SSL_TLSEXT_HB_ENABLED 0x01
+#define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02
+#define SSL_TLSEXT_HB_DONT_RECV_REQUESTS 0x04
+
+#define SSL_get_tlsext_heartbeat_pending(ssl) \
+ SSL_ctrl((ssl),SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING,0,NULL)
+#define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \
+ SSL_ctrl((ssl),SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL)
+#endif
#endif
/* PSK ciphersuites from 4279 */
@@ -330,6 +401,14 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039
#define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A
+/* TLS v1.2 ciphersuites */
+#define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B
+#define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C
+#define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D
+#define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E
+#define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F
+#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040
+
/* Camellia ciphersuites from RFC4132 */
#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041
#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042
@@ -338,6 +417,16 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045
#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046
+/* TLS v1.2 ciphersuites */
+#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067
+#define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068
+#define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069
+#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A
+#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B
+#define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C
+#define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D
+
+/* Camellia ciphersuites from RFC4132 */
#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084
#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085
#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086
@@ -353,6 +442,20 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A
#define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B
+/* TLS v1.2 GCM ciphersuites from RFC5288 */
+#define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C
+#define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D
+#define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E
+#define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F
+#define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0
+#define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1
+#define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2
+#define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3
+#define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4
+#define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5
+#define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6
+#define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7
+
/* ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in draft 13 */
#define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001
#define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002
@@ -384,6 +487,38 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018
#define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019
+/* SRP ciphersuites from RFC 5054 */
+#define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A
+#define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B
+#define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C
+#define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D
+#define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E
+#define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F
+#define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020
+#define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021
+#define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022
+
+/* ECDH HMAC based ciphersuites from RFC5289 */
+
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026
+#define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027
+#define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028
+#define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029
+#define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A
+
+/* ECDH GCM based ciphersuites from RFC5289 */
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E
+#define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F
+#define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030
+#define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031
+#define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032
+
/* XXX
* Inconsistency alert:
* The OpenSSL names of ciphers with ephemeral DH here include the string
@@ -451,6 +586,17 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA"
#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA"
+/* SRP ciphersuite from RFC 5054 */
+#define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA"
+
/* Camellia ciphersuites from RFC4132 */
#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA"
#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA"
@@ -474,6 +620,55 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA"
#define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA"
+/* TLS v1.2 ciphersuites */
+#define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256"
+#define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256"
+#define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256"
+#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256"
+#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256"
+#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256"
+#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256"
+#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256"
+#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256"
+#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256"
+#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256"
+#define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256"
+#define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256"
+
+/* TLS v1.2 GCM ciphersuites from RFC5288 */
+#define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256"
+#define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384"
+#define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256"
+#define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384"
+#define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256"
+#define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384"
+#define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256"
+#define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384"
+#define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256"
+#define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384"
+#define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256"
+#define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384"
+
+/* ECDH HMAC based ciphersuites from RFC5289 */
+
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384"
+
+/* ECDH GCM based ciphersuites from RFC5289 */
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "ECDHE-ECDSA-AES128-GCM-SHA256"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "ECDHE-ECDSA-AES256-GCM-SHA384"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 "ECDH-ECDSA-AES128-GCM-SHA256"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 "ECDH-ECDSA-AES256-GCM-SHA384"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384"
#define TLS_CT_RSA_SIGN 1
#define TLS_CT_DSS_SIGN 2
diff --git a/deps/openssl/openssl/ssl/tls_srp.c b/deps/openssl/openssl/ssl/tls_srp.c
new file mode 100644
index 000000000..2315a7c0a
--- /dev/null
+++ b/deps/openssl/openssl/ssl/tls_srp.c
@@ -0,0 +1,507 @@
+/* ssl/tls_srp.c */
+/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
+ * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004-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
+ * licensing@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).
+ *
+ */
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_SRP
+
+#include <openssl/rand.h>
+#include <openssl/srp.h>
+#include <openssl/err.h>
+
+int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx)
+ {
+ if (ctx == NULL)
+ return 0;
+ OPENSSL_free(ctx->srp_ctx.login);
+ BN_free(ctx->srp_ctx.N);
+ BN_free(ctx->srp_ctx.g);
+ BN_free(ctx->srp_ctx.s);
+ BN_free(ctx->srp_ctx.B);
+ BN_free(ctx->srp_ctx.A);
+ BN_free(ctx->srp_ctx.a);
+ BN_free(ctx->srp_ctx.b);
+ BN_free(ctx->srp_ctx.v);
+ ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
+ ctx->srp_ctx.SRP_cb_arg = NULL;
+ ctx->srp_ctx.SRP_verify_param_callback = NULL;
+ ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+ ctx->srp_ctx.N = NULL;
+ ctx->srp_ctx.g = NULL;
+ ctx->srp_ctx.s = NULL;
+ ctx->srp_ctx.B = NULL;
+ ctx->srp_ctx.A = NULL;
+ ctx->srp_ctx.a = NULL;
+ ctx->srp_ctx.b = NULL;
+ ctx->srp_ctx.v = NULL;
+ ctx->srp_ctx.login = NULL;
+ ctx->srp_ctx.info = NULL;
+ ctx->srp_ctx.strength = SRP_MINIMAL_N;
+ ctx->srp_ctx.srp_Mask = 0;
+ return (1);
+ }
+
+int SSL_SRP_CTX_free(struct ssl_st *s)
+ {
+ if (s == NULL)
+ return 0;
+ OPENSSL_free(s->srp_ctx.login);
+ BN_free(s->srp_ctx.N);
+ BN_free(s->srp_ctx.g);
+ BN_free(s->srp_ctx.s);
+ BN_free(s->srp_ctx.B);
+ BN_free(s->srp_ctx.A);
+ BN_free(s->srp_ctx.a);
+ BN_free(s->srp_ctx.b);
+ BN_free(s->srp_ctx.v);
+ s->srp_ctx.TLS_ext_srp_username_callback = NULL;
+ s->srp_ctx.SRP_cb_arg = NULL;
+ s->srp_ctx.SRP_verify_param_callback = NULL;
+ s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+ s->srp_ctx.N = NULL;
+ s->srp_ctx.g = NULL;
+ s->srp_ctx.s = NULL;
+ s->srp_ctx.B = NULL;
+ s->srp_ctx.A = NULL;
+ s->srp_ctx.a = NULL;
+ s->srp_ctx.b = NULL;
+ s->srp_ctx.v = NULL;
+ s->srp_ctx.login = NULL;
+ s->srp_ctx.info = NULL;
+ s->srp_ctx.strength = SRP_MINIMAL_N;
+ s->srp_ctx.srp_Mask = 0;
+ return (1);
+ }
+
+int SSL_SRP_CTX_init(struct ssl_st *s)
+ {
+ SSL_CTX *ctx;
+
+ if ((s == NULL) || ((ctx = s->ctx) == NULL))
+ return 0;
+ s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg;
+ /* set client Hello login callback */
+ s->srp_ctx.TLS_ext_srp_username_callback = ctx->srp_ctx.TLS_ext_srp_username_callback;
+ /* set SRP N/g param callback for verification */
+ s->srp_ctx.SRP_verify_param_callback = ctx->srp_ctx.SRP_verify_param_callback;
+ /* set SRP client passwd callback */
+ s->srp_ctx.SRP_give_srp_client_pwd_callback = ctx->srp_ctx.SRP_give_srp_client_pwd_callback;
+
+ s->srp_ctx.N = NULL;
+ s->srp_ctx.g = NULL;
+ s->srp_ctx.s = NULL;
+ s->srp_ctx.B = NULL;
+ s->srp_ctx.A = NULL;
+ s->srp_ctx.a = NULL;
+ s->srp_ctx.b = NULL;
+ s->srp_ctx.v = NULL;
+ s->srp_ctx.login = NULL;
+ s->srp_ctx.info = ctx->srp_ctx.info;
+ s->srp_ctx.strength = ctx->srp_ctx.strength;
+
+ if (((ctx->srp_ctx.N != NULL) &&
+ ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) ||
+ ((ctx->srp_ctx.g != NULL) &&
+ ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) ||
+ ((ctx->srp_ctx.s != NULL) &&
+ ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) ||
+ ((ctx->srp_ctx.B != NULL) &&
+ ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) ||
+ ((ctx->srp_ctx.A != NULL) &&
+ ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) ||
+ ((ctx->srp_ctx.a != NULL) &&
+ ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) ||
+ ((ctx->srp_ctx.v != NULL) &&
+ ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) ||
+ ((ctx->srp_ctx.b != NULL) &&
+ ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL)))
+ {
+ SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_BN_LIB);
+ goto err;
+ }
+ if ((ctx->srp_ctx.login != NULL) &&
+ ((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL))
+ {
+ SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;
+
+ return (1);
+err:
+ OPENSSL_free(s->srp_ctx.login);
+ BN_free(s->srp_ctx.N);
+ BN_free(s->srp_ctx.g);
+ BN_free(s->srp_ctx.s);
+ BN_free(s->srp_ctx.B);
+ BN_free(s->srp_ctx.A);
+ BN_free(s->srp_ctx.a);
+ BN_free(s->srp_ctx.b);
+ BN_free(s->srp_ctx.v);
+ return (0);
+ }
+
+int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx)
+ {
+ if (ctx == NULL)
+ return 0;
+
+ ctx->srp_ctx.SRP_cb_arg = NULL;
+ /* set client Hello login callback */
+ ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
+ /* set SRP N/g param callback for verification */
+ ctx->srp_ctx.SRP_verify_param_callback = NULL;
+ /* set SRP client passwd callback */
+ ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+
+ ctx->srp_ctx.N = NULL;
+ ctx->srp_ctx.g = NULL;
+ ctx->srp_ctx.s = NULL;
+ ctx->srp_ctx.B = NULL;
+ ctx->srp_ctx.A = NULL;
+ ctx->srp_ctx.a = NULL;
+ ctx->srp_ctx.b = NULL;
+ ctx->srp_ctx.v = NULL;
+ ctx->srp_ctx.login = NULL;
+ ctx->srp_ctx.srp_Mask = 0;
+ ctx->srp_ctx.info = NULL;
+ ctx->srp_ctx.strength = SRP_MINIMAL_N;
+
+ return (1);
+ }
+
+/* server side */
+int SSL_srp_server_param_with_username(SSL *s, int *ad)
+ {
+ unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
+ int al;
+
+ *ad = SSL_AD_UNKNOWN_PSK_IDENTITY;
+ if ((s->srp_ctx.TLS_ext_srp_username_callback !=NULL) &&
+ ((al = s->srp_ctx.TLS_ext_srp_username_callback(s, ad, s->srp_ctx.SRP_cb_arg))!=SSL_ERROR_NONE))
+ return al;
+
+ *ad = SSL_AD_INTERNAL_ERROR;
+ if ((s->srp_ctx.N == NULL) ||
+ (s->srp_ctx.g == NULL) ||
+ (s->srp_ctx.s == NULL) ||
+ (s->srp_ctx.v == NULL))
+ return SSL3_AL_FATAL;
+
+ if (RAND_bytes(b, sizeof(b)) <= 0)
+ return SSL3_AL_FATAL;
+ s->srp_ctx.b = BN_bin2bn(b,sizeof(b),NULL);
+ OPENSSL_cleanse(b,sizeof(b));
+
+ /* Calculate: B = (kv + g^b) % N */
+
+ return ((s->srp_ctx.B = SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, s->srp_ctx.v)) != NULL)?
+ SSL_ERROR_NONE:SSL3_AL_FATAL;
+ }
+
+/* If the server just has the raw password, make up a verifier entry on the fly */
+int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, const char *grp)
+ {
+ SRP_gN *GN = SRP_get_default_gN(grp);
+ if(GN == NULL) return -1;
+ s->srp_ctx.N = BN_dup(GN->N);
+ s->srp_ctx.g = BN_dup(GN->g);
+ if(s->srp_ctx.v != NULL)
+ {
+ BN_clear_free(s->srp_ctx.v);
+ s->srp_ctx.v = NULL;
+ }
+ if(s->srp_ctx.s != NULL)
+ {
+ BN_clear_free(s->srp_ctx.s);
+ s->srp_ctx.s = NULL;
+ }
+ if(!SRP_create_verifier_BN(user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) return -1;
+
+ return 1;
+ }
+
+int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
+ BIGNUM *sa, BIGNUM *v, char *info)
+ {
+ if (N!= NULL)
+ {
+ if (s->srp_ctx.N != NULL)
+ {
+ if (!BN_copy(s->srp_ctx.N,N))
+ {
+ BN_free(s->srp_ctx.N);
+ s->srp_ctx.N = NULL;
+ }
+ }
+ else
+ s->srp_ctx.N = BN_dup(N);
+ }
+ if (g!= NULL)
+ {
+ if (s->srp_ctx.g != NULL)
+ {
+ if (!BN_copy(s->srp_ctx.g,g))
+ {
+ BN_free(s->srp_ctx.g);
+ s->srp_ctx.g = NULL;
+ }
+ }
+ else
+ s->srp_ctx.g = BN_dup(g);
+ }
+ if (sa!= NULL)
+ {
+ if (s->srp_ctx.s != NULL)
+ {
+ if (!BN_copy(s->srp_ctx.s,sa))
+ {
+ BN_free(s->srp_ctx.s);
+ s->srp_ctx.s = NULL;
+ }
+ }
+ else
+ s->srp_ctx.s = BN_dup(sa);
+ }
+ if (v!= NULL)
+ {
+ if (s->srp_ctx.v != NULL)
+ {
+ if (!BN_copy(s->srp_ctx.v,v))
+ {
+ BN_free(s->srp_ctx.v);
+ s->srp_ctx.v = NULL;
+ }
+ }
+ else
+ s->srp_ctx.v = BN_dup(v);
+ }
+ s->srp_ctx.info = info;
+
+ if (!(s->srp_ctx.N) ||
+ !(s->srp_ctx.g) ||
+ !(s->srp_ctx.s) ||
+ !(s->srp_ctx.v))
+ return -1;
+
+ return 1;
+ }
+
+int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key)
+ {
+ BIGNUM *K = NULL, *u = NULL;
+ int ret = -1, tmp_len;
+ unsigned char *tmp = NULL;
+
+ if (!SRP_Verify_A_mod_N(s->srp_ctx.A,s->srp_ctx.N))
+ goto err;
+ if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N)))
+ goto err;
+ if (!(K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, s->srp_ctx.N)))
+ goto err;
+
+ tmp_len = BN_num_bytes(K);
+ if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
+ goto err;
+ BN_bn2bin(K, tmp);
+ ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
+err:
+ if (tmp)
+ {
+ OPENSSL_cleanse(tmp,tmp_len) ;
+ OPENSSL_free(tmp);
+ }
+ BN_clear_free(K);
+ BN_clear_free(u);
+ return ret;
+ }
+
+/* client side */
+int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key)
+ {
+ BIGNUM *x = NULL, *u = NULL, *K = NULL;
+ int ret = -1, tmp_len;
+ char *passwd = NULL;
+ unsigned char *tmp = NULL;
+
+ /* Checks if b % n == 0
+ */
+ if (SRP_Verify_B_mod_N(s->srp_ctx.B,s->srp_ctx.N)==0) goto err;
+ if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N))) goto err;
+ if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) goto err;
+ if (!(passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s, s->srp_ctx.SRP_cb_arg))) goto err;
+ if (!(x = SRP_Calc_x(s->srp_ctx.s,s->srp_ctx.login,passwd))) goto err;
+ if (!(K = SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, s->srp_ctx.a, u))) goto err;
+
+ tmp_len = BN_num_bytes(K);
+ if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) goto err;
+ BN_bn2bin(K, tmp);
+ ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
+err:
+ if (tmp)
+ {
+ OPENSSL_cleanse(tmp,tmp_len) ;
+ OPENSSL_free(tmp);
+ }
+ BN_clear_free(K);
+ BN_clear_free(x);
+ if (passwd)
+ {
+ OPENSSL_cleanse(passwd,strlen(passwd)) ;
+ OPENSSL_free(passwd);
+ }
+ BN_clear_free(u);
+ return ret;
+ }
+
+int SRP_Calc_A_param(SSL *s)
+ {
+ unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
+
+ if (BN_num_bits(s->srp_ctx.N) < s->srp_ctx.strength)
+ return -1;
+
+ if (s->srp_ctx.SRP_verify_param_callback ==NULL &&
+ !SRP_check_known_gN_param(s->srp_ctx.g,s->srp_ctx.N))
+ return -1 ;
+
+ RAND_bytes(rnd, sizeof(rnd));
+ s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
+ OPENSSL_cleanse(rnd, sizeof(rnd));
+
+ if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a,s->srp_ctx.N,s->srp_ctx.g)))
+ return -1;
+
+ /* We can have a callback to verify SRP param!! */
+ if (s->srp_ctx.SRP_verify_param_callback !=NULL)
+ return s->srp_ctx.SRP_verify_param_callback(s,s->srp_ctx.SRP_cb_arg);
+
+ return 1;
+ }
+
+BIGNUM *SSL_get_srp_g(SSL *s)
+ {
+ if (s->srp_ctx.g != NULL)
+ return s->srp_ctx.g;
+ return s->ctx->srp_ctx.g;
+ }
+
+BIGNUM *SSL_get_srp_N(SSL *s)
+ {
+ if (s->srp_ctx.N != NULL)
+ return s->srp_ctx.N;
+ return s->ctx->srp_ctx.N;
+ }
+
+char *SSL_get_srp_username(SSL *s)
+ {
+ if (s->srp_ctx.login != NULL)
+ return s->srp_ctx.login;
+ return s->ctx->srp_ctx.login;
+ }
+
+char *SSL_get_srp_userinfo(SSL *s)
+ {
+ if (s->srp_ctx.info != NULL)
+ return s->srp_ctx.info;
+ return s->ctx->srp_ctx.info;
+ }
+
+#define tls1_ctx_ctrl ssl3_ctx_ctrl
+#define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
+
+int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name)
+ {
+ return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME,0,name);
+ }
+
+int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password)
+ {
+ return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD,0,password);
+ }
+
+int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
+ {
+ return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
+ NULL);
+ }
+
+int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, int (*cb)(SSL *,void *))
+ {
+ return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
+ (void (*)(void))cb);
+ }
+
+int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
+ {
+ return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_SRP_ARG,0,arg);
+ }
+
+int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
+ int (*cb)(SSL *,int *,void *))
+ {
+ return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
+ (void (*)(void))cb);
+ }
+
+int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *))
+ {
+ return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
+ (void (*)(void))cb);
+ }
+
+#endif
diff --git a/deps/openssl/openssl/test/CAss.cnf b/deps/openssl/openssl/test/CAss.cnf
new file mode 100644
index 000000000..109bc8c10
--- /dev/null
+++ b/deps/openssl/openssl/test/CAss.cnf
@@ -0,0 +1,76 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE = ./.rnd
+
+####################################################################
+[ req ]
+default_bits = 2048
+default_keyfile = keySS.pem
+distinguished_name = req_distinguished_name
+encrypt_rsa_key = no
+default_md = sha1
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = AU
+countryName_value = AU
+
+organizationName = Organization Name (eg, company)
+organizationName_value = Dodgy Brothers
+
+commonName = Common Name (eg, YOUR name)
+commonName_value = Dodgy CA
+
+####################################################################
+[ ca ]
+default_ca = CA_default # The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir = ./demoCA # Where everything is kept
+certs = $dir/certs # Where the issued certs are kept
+crl_dir = $dir/crl # Where the issued crl are kept
+database = $dir/index.txt # database index file.
+#unique_subject = no # Set to 'no' to allow creation of
+ # several ctificates with same subject.
+new_certs_dir = $dir/newcerts # default place for new certs.
+
+certificate = $dir/cacert.pem # The CA certificate
+serial = $dir/serial # The current serial number
+crl = $dir/crl.pem # The current CRL
+private_key = $dir/private/cakey.pem# The private key
+RANDFILE = $dir/private/.rand # private random number file
+
+x509_extensions = v3_ca # The extentions to add to the cert
+
+name_opt = ca_default # Subject Name options
+cert_opt = ca_default # Certificate field options
+
+default_days = 365 # how long to certify for
+default_crl_days= 30 # how long before next CRL
+default_md = md5 # which md to use.
+preserve = no # keep passed DN ordering
+
+policy = policy_anything
+
+[ policy_anything ]
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+
+
+[ v3_ca ]
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always,issuer:always
+basicConstraints = CA:true,pathlen:1
+keyUsage = cRLSign, keyCertSign
+issuerAltName=issuer:copy
diff --git a/deps/openssl/openssl/test/CAssdh.cnf b/deps/openssl/openssl/test/CAssdh.cnf
new file mode 100644
index 000000000..4e0a90867
--- /dev/null
+++ b/deps/openssl/openssl/test/CAssdh.cnf
@@ -0,0 +1,24 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+# hacked by iang to do DH certs - CA
+
+RANDFILE = ./.rnd
+
+####################################################################
+[ req ]
+distinguished_name = req_distinguished_name
+encrypt_rsa_key = no
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = CU
+countryName_value = CU
+
+organizationName = Organization Name (eg, company)
+organizationName_value = La Junta de la Revolucion
+
+commonName = Common Name (eg, YOUR name)
+commonName_value = Junta
+
diff --git a/deps/openssl/openssl/test/CAssdsa.cnf b/deps/openssl/openssl/test/CAssdsa.cnf
new file mode 100644
index 000000000..a6b4d1810
--- /dev/null
+++ b/deps/openssl/openssl/test/CAssdsa.cnf
@@ -0,0 +1,23 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+# hacked by iang to do DSA certs - CA
+
+RANDFILE = ./.rnd
+
+####################################################################
+[ req ]
+distinguished_name = req_distinguished_name
+encrypt_rsa_key = no
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = ES
+countryName_value = ES
+
+organizationName = Organization Name (eg, company)
+organizationName_value = Hermanos Locos
+
+commonName = Common Name (eg, YOUR name)
+commonName_value = Hermanos Locos CA
diff --git a/deps/openssl/openssl/test/CAssrsa.cnf b/deps/openssl/openssl/test/CAssrsa.cnf
new file mode 100644
index 000000000..eb24a6dfc
--- /dev/null
+++ b/deps/openssl/openssl/test/CAssrsa.cnf
@@ -0,0 +1,24 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+# create RSA certs - CA
+
+RANDFILE = ./.rnd
+
+####################################################################
+[ req ]
+distinguished_name = req_distinguished_name
+encrypt_key = no
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = ES
+countryName_value = ES
+
+organizationName = Organization Name (eg, company)
+organizationName_value = Hermanos Locos
+
+commonName = Common Name (eg, YOUR name)
+commonName_value = Hermanos Locos CA
+
diff --git a/deps/openssl/openssl/test/CAtsa.cnf b/deps/openssl/openssl/test/CAtsa.cnf
new file mode 100644
index 000000000..f5a275bfc
--- /dev/null
+++ b/deps/openssl/openssl/test/CAtsa.cnf
@@ -0,0 +1,163 @@
+
+#
+# This config is used by the Time Stamp Authority tests.
+#
+
+RANDFILE = ./.rnd
+
+# Extra OBJECT IDENTIFIER info:
+oid_section = new_oids
+
+TSDNSECT = ts_cert_dn
+INDEX = 1
+
+[ new_oids ]
+
+# Policies used by the TSA tests.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
+#----------------------------------------------------------------------
+[ ca ]
+default_ca = CA_default # The default ca section
+
+[ CA_default ]
+
+dir = ./demoCA
+certs = $dir/certs # Where the issued certs are kept
+database = $dir/index.txt # database index file.
+new_certs_dir = $dir/newcerts # default place for new certs.
+
+certificate = $dir/cacert.pem # The CA certificate
+serial = $dir/serial # The current serial number
+private_key = $dir/private/cakey.pem# The private key
+RANDFILE = $dir/private/.rand # private random number file
+
+default_days = 365 # how long to certify for
+default_md = sha1 # which md to use.
+preserve = no # keep passed DN ordering
+
+policy = policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName = supplied
+stateOrProvinceName = supplied
+organizationName = supplied
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+#----------------------------------------------------------------------
+[ req ]
+default_bits = 1024
+default_md = sha1
+distinguished_name = $ENV::TSDNSECT
+encrypt_rsa_key = no
+prompt = no
+# attributes = req_attributes
+x509_extensions = v3_ca # The extentions to add to the self signed cert
+
+string_mask = nombstr
+
+[ ts_ca_dn ]
+countryName = HU
+stateOrProvinceName = Budapest
+localityName = Budapest
+organizationName = Gov-CA Ltd.
+commonName = ca1
+
+[ ts_cert_dn ]
+countryName = HU
+stateOrProvinceName = Budapest
+localityName = Buda
+organizationName = Hun-TSA Ltd.
+commonName = tsa$ENV::INDEX
+
+[ tsa_cert ]
+
+# TSA server cert is not a CA cert.
+basicConstraints=CA:FALSE
+
+# The following key usage flags are needed for TSA server certificates.
+keyUsage = nonRepudiation, digitalSignature
+extendedKeyUsage = critical,timeStamping
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+[ non_tsa_cert ]
+
+# This is not a CA cert and not a TSA cert, either (timeStamping usage missing)
+basicConstraints=CA:FALSE
+
+# The following key usage flags are needed for TSA server certificates.
+keyUsage = nonRepudiation, digitalSignature
+# timeStamping is not supported by this certificate
+# extendedKeyUsage = critical,timeStamping
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature
+
+[ v3_ca ]
+
+# Extensions for a typical CA
+
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always,issuer:always
+basicConstraints = critical,CA:true
+keyUsage = cRLSign, keyCertSign
+
+#----------------------------------------------------------------------
+[ tsa ]
+
+default_tsa = tsa_config1 # the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir = . # TSA root directory
+serial = $dir/tsa_serial # The current serial number (mandatory)
+signer_cert = $dir/tsa_cert1.pem # The TSA signing certificate
+ # (optional)
+certs = $dir/tsaca.pem # Certificate chain to include in reply
+ # (optional)
+signer_key = $dir/tsa_key1.pem # The TSA private key (optional)
+
+default_policy = tsa_policy1 # Policy if request did not specify it
+ # (optional)
+other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
+digests = md5, sha1 # Acceptable message digests (mandatory)
+accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
+ordering = yes # Is ordering defined for timestamps?
+ # (optional, default: no)
+tsa_name = yes # Must the TSA name be included in the reply?
+ # (optional, default: no)
+ess_cert_id_chain = yes # Must the ESS cert id chain be included?
+ # (optional, default: no)
+
+[ tsa_config2 ]
+
+# This configuration uses a certificate which doesn't have timeStamping usage.
+# These are used by the TSA reply generation only.
+dir = . # TSA root directory
+serial = $dir/tsa_serial # The current serial number (mandatory)
+signer_cert = $dir/tsa_cert2.pem # The TSA signing certificate
+ # (optional)
+certs = $dir/demoCA/cacert.pem# Certificate chain to include in reply
+ # (optional)
+signer_key = $dir/tsa_key2.pem # The TSA private key (optional)
+
+default_policy = tsa_policy1 # Policy if request did not specify it
+ # (optional)
+other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
+digests = md5, sha1 # Acceptable message digests (mandatory)
diff --git a/deps/openssl/openssl/test/Makefile b/deps/openssl/openssl/test/Makefile
new file mode 100644
index 000000000..4c9eabcc2
--- /dev/null
+++ b/deps/openssl/openssl/test/Makefile
@@ -0,0 +1,729 @@
+#
+# test/Makefile
+#
+
+DIR= test
+TOP= ..
+CC= cc
+INCLUDES= -I$(TOP) -I../include $(KRB5_INCLUDES)
+CFLAG= -g
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+PERL= perl
+# KRB5 stuff
+KRB5_INCLUDES=
+LIBKRB5=
+
+PEX_LIBS=
+EX_LIBS= #-lnsl -lsocket
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile maketests.com \
+ tests.com testenc.com tx509.com trsa.com tcrl.com tsid.com treq.com \
+ tpkcs7.com tpkcs7d.com tverify.com testgen.com testss.com testssl.com \
+ testca.com VMSca-response.1 VMSca-response.2
+
+DLIBCRYPTO= ../libcrypto.a
+DLIBSSL= ../libssl.a
+LIBCRYPTO= -L.. -lcrypto
+LIBSSL= -L.. -lssl
+
+BNTEST= bntest
+ECTEST= ectest
+ECDSATEST= ecdsatest
+ECDHTEST= ecdhtest
+EXPTEST= exptest
+IDEATEST= ideatest
+SHATEST= shatest
+SHA1TEST= sha1test
+SHA256TEST= sha256t
+SHA512TEST= sha512t
+MDC2TEST= mdc2test
+RMDTEST= rmdtest
+MD2TEST= md2test
+MD4TEST= md4test
+MD5TEST= md5test
+HMACTEST= hmactest
+WPTEST= wp_test
+RC2TEST= rc2test
+RC4TEST= rc4test
+RC5TEST= rc5test
+BFTEST= bftest
+CASTTEST= casttest
+DESTEST= destest
+RANDTEST= randtest
+DHTEST= dhtest
+DSATEST= dsatest
+METHTEST= methtest
+SSLTEST= ssltest
+RSATEST= rsa_test
+ENGINETEST= enginetest
+EVPTEST= evp_test
+IGETEST= igetest
+JPAKETEST= jpaketest
+SRPTEST= srptest
+ASN1TEST= asn1test
+
+TESTS= alltests
+
+EXE= $(BNTEST)$(EXE_EXT) $(ECTEST)$(EXE_EXT) $(ECDSATEST)$(EXE_EXT) $(ECDHTEST)$(EXE_EXT) $(IDEATEST)$(EXE_EXT) \
+ $(MD2TEST)$(EXE_EXT) $(MD4TEST)$(EXE_EXT) $(MD5TEST)$(EXE_EXT) $(HMACTEST)$(EXE_EXT) $(WPTEST)$(EXE_EXT) \
+ $(RC2TEST)$(EXE_EXT) $(RC4TEST)$(EXE_EXT) $(RC5TEST)$(EXE_EXT) \
+ $(DESTEST)$(EXE_EXT) $(SHATEST)$(EXE_EXT) $(SHA1TEST)$(EXE_EXT) $(SHA256TEST)$(EXE_EXT) $(SHA512TEST)$(EXE_EXT) \
+ $(MDC2TEST)$(EXE_EXT) $(RMDTEST)$(EXE_EXT) \
+ $(RANDTEST)$(EXE_EXT) $(DHTEST)$(EXE_EXT) $(ENGINETEST)$(EXE_EXT) \
+ $(BFTEST)$(EXE_EXT) $(CASTTEST)$(EXE_EXT) $(SSLTEST)$(EXE_EXT) $(EXPTEST)$(EXE_EXT) $(DSATEST)$(EXE_EXT) $(RSATEST)$(EXE_EXT) \
+ $(EVPTEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT) $(SRPTEST)$(EXE_EXT) \
+ $(ASN1TEST)$(EXE_EXT)
+
+# $(METHTEST)$(EXE_EXT)
+
+OBJ= $(BNTEST).o $(ECTEST).o $(ECDSATEST).o $(ECDHTEST).o $(IDEATEST).o \
+ $(MD2TEST).o $(MD4TEST).o $(MD5TEST).o \
+ $(HMACTEST).o $(WPTEST).o \
+ $(RC2TEST).o $(RC4TEST).o $(RC5TEST).o \
+ $(DESTEST).o $(SHATEST).o $(SHA1TEST).o $(SHA256TEST).o $(SHA512TEST).o \
+ $(MDC2TEST).o $(RMDTEST).o \
+ $(RANDTEST).o $(DHTEST).o $(ENGINETEST).o $(CASTTEST).o \
+ $(BFTEST).o $(SSLTEST).o $(DSATEST).o $(EXPTEST).o $(RSATEST).o \
+ $(EVPTEST).o $(IGETEST).o $(JPAKETEST).o $(ASN1TEST).o
+SRC= $(BNTEST).c $(ECTEST).c $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
+ $(MD2TEST).c $(MD4TEST).c $(MD5TEST).c \
+ $(HMACTEST).c $(WPTEST).c \
+ $(RC2TEST).c $(RC4TEST).c $(RC5TEST).c \
+ $(DESTEST).c $(SHATEST).c $(SHA1TEST).c $(MDC2TEST).c $(RMDTEST).c \
+ $(RANDTEST).c $(DHTEST).c $(ENGINETEST).c $(CASTTEST).c \
+ $(BFTEST).c $(SSLTEST).c $(DSATEST).c $(EXPTEST).c $(RSATEST).c \
+ $(EVPTEST).c $(IGETEST).c $(JPAKETEST).c $(SRPTEST).c $(ASN1TEST).c
+
+EXHEADER=
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd ..; $(MAKE) DIRS=$(DIR) TESTS=$(TESTS) all)
+
+all: exe
+
+exe: $(EXE) dummytest$(EXE_EXT)
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+
+generate: $(SRC)
+$(SRC):
+ @sh $(TOP)/util/point.sh dummytest.c $@
+
+errors:
+
+install:
+
+tags:
+ ctags $(SRC)
+
+tests: exe apps $(TESTS)
+
+apps:
+ @(cd ..; $(MAKE) DIRS=apps all)
+
+alltests: \
+ test_des test_idea test_sha test_md4 test_md5 test_hmac \
+ test_md2 test_mdc2 test_wp \
+ test_rmd test_rc2 test_rc4 test_rc5 test_bf test_cast test_aes \
+ test_rand test_bn test_ec test_ecdsa test_ecdh \
+ test_enc test_x509 test_rsa test_crl test_sid \
+ test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
+ test_ss test_ca test_engine test_evp test_ssl test_tsa test_ige \
+ test_jpake test_srp test_cms
+
+test_evp:
+ ../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt
+
+test_des:
+ ../util/shlib_wrap.sh ./$(DESTEST)
+
+test_idea:
+ ../util/shlib_wrap.sh ./$(IDEATEST)
+
+test_sha:
+ ../util/shlib_wrap.sh ./$(SHATEST)
+ ../util/shlib_wrap.sh ./$(SHA1TEST)
+ ../util/shlib_wrap.sh ./$(SHA256TEST)
+ ../util/shlib_wrap.sh ./$(SHA512TEST)
+
+test_mdc2:
+ ../util/shlib_wrap.sh ./$(MDC2TEST)
+
+test_md5:
+ ../util/shlib_wrap.sh ./$(MD5TEST)
+
+test_md4:
+ ../util/shlib_wrap.sh ./$(MD4TEST)
+
+test_hmac:
+ ../util/shlib_wrap.sh ./$(HMACTEST)
+
+test_wp:
+ ../util/shlib_wrap.sh ./$(WPTEST)
+
+test_md2:
+ ../util/shlib_wrap.sh ./$(MD2TEST)
+
+test_rmd:
+ ../util/shlib_wrap.sh ./$(RMDTEST)
+
+test_bf:
+ ../util/shlib_wrap.sh ./$(BFTEST)
+
+test_cast:
+ ../util/shlib_wrap.sh ./$(CASTTEST)
+
+test_rc2:
+ ../util/shlib_wrap.sh ./$(RC2TEST)
+
+test_rc4:
+ ../util/shlib_wrap.sh ./$(RC4TEST)
+
+test_rc5:
+ ../util/shlib_wrap.sh ./$(RC5TEST)
+
+test_rand:
+ ../util/shlib_wrap.sh ./$(RANDTEST)
+
+test_enc:
+ @sh ./testenc
+
+test_x509:
+ echo test normal x509v1 certificate
+ sh ./tx509 2>/dev/null
+ echo test first x509v3 certificate
+ sh ./tx509 v3-cert1.pem 2>/dev/null
+ echo test second x509v3 certificate
+ sh ./tx509 v3-cert2.pem 2>/dev/null
+
+test_rsa: $(RSATEST)$(EXE_EXT)
+ @sh ./trsa 2>/dev/null
+ ../util/shlib_wrap.sh ./$(RSATEST)
+
+test_crl:
+ @sh ./tcrl 2>/dev/null
+
+test_sid:
+ @sh ./tsid 2>/dev/null
+
+test_req:
+ @sh ./treq 2>/dev/null
+ @sh ./treq testreq2.pem 2>/dev/null
+
+test_pkcs7:
+ @sh ./tpkcs7 2>/dev/null
+ @sh ./tpkcs7d 2>/dev/null
+
+test_bn:
+ @echo starting big number library test, could take a while...
+ @../util/shlib_wrap.sh ./$(BNTEST) >tmp.bntest
+ @echo quit >>tmp.bntest
+ @echo "running bc"
+ @<tmp.bntest sh -c "`sh ./bctest ignore`" | $(PERL) -e '$$i=0; while (<STDIN>) {if (/^test (.*)/) {print STDERR "\nverify $$1";} elsif (!/^0$$/) {die "\nFailed! bc: $$_";} else {print STDERR "."; $$i++;}} print STDERR "\n$$i tests passed\n"'
+ @echo 'test a^b%c implementations'
+ ../util/shlib_wrap.sh ./$(EXPTEST)
+
+test_ec:
+ @echo 'test elliptic curves'
+ ../util/shlib_wrap.sh ./$(ECTEST)
+
+test_ecdsa:
+ @echo 'test ecdsa'
+ ../util/shlib_wrap.sh ./$(ECDSATEST)
+
+test_ecdh:
+ @echo 'test ecdh'
+ ../util/shlib_wrap.sh ./$(ECDHTEST)
+
+test_verify:
+ @echo "The following command should have some OK's and some failures"
+ @echo "There are definitly a few expired certificates"
+ ../util/shlib_wrap.sh ../apps/openssl verify -CApath ../certs/demo ../certs/demo/*.pem
+
+test_dh:
+ @echo "Generate a set of DH parameters"
+ ../util/shlib_wrap.sh ./$(DHTEST)
+
+test_dsa:
+ @echo "Generate a set of DSA parameters"
+ ../util/shlib_wrap.sh ./$(DSATEST)
+ ../util/shlib_wrap.sh ./$(DSATEST) -app2_1
+
+test_gen:
+ @echo "Generate and verify a certificate request"
+ @sh ./testgen
+
+test_ss keyU.ss certU.ss certCA.ss certP1.ss keyP1.ss certP2.ss keyP2.ss \
+ intP1.ss intP2.ss: testss
+ @echo "Generate and certify a test certificate"
+ @sh ./testss
+ @cat certCA.ss certU.ss > intP1.ss
+ @cat certCA.ss certU.ss certP1.ss > intP2.ss
+
+test_engine:
+ @echo "Manipulate the ENGINE structures"
+ ../util/shlib_wrap.sh ./$(ENGINETEST)
+
+test_ssl: keyU.ss certU.ss certCA.ss certP1.ss keyP1.ss certP2.ss keyP2.ss \
+ intP1.ss intP2.ss
+ @echo "test SSL protocol"
+ @if [ -n "$(FIPSCANLIB)" ]; then \
+ sh ./testfipsssl keyU.ss certU.ss certCA.ss; \
+ fi
+ ../util/shlib_wrap.sh ./$(SSLTEST) -test_cipherlist
+ @sh ./testssl keyU.ss certU.ss certCA.ss
+ @sh ./testsslproxy keyP1.ss certP1.ss intP1.ss
+ @sh ./testsslproxy keyP2.ss certP2.ss intP2.ss
+
+test_ca:
+ @if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then \
+ echo "skipping CA.sh test -- requires RSA"; \
+ else \
+ echo "Generate and certify a test certificate via the 'ca' program"; \
+ sh ./testca; \
+ fi
+
+test_aes: #$(AESTEST)
+# @echo "test Rijndael"
+# ../util/shlib_wrap.sh ./$(AESTEST)
+
+test_tsa:
+ @if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then \
+ echo "skipping testtsa test -- requires RSA"; \
+ else \
+ sh ./testtsa; \
+ fi
+
+test_ige: $(IGETEST)$(EXE_EXT)
+ @echo "Test IGE mode"
+ ../util/shlib_wrap.sh ./$(IGETEST)
+
+test_jpake: $(JPAKETEST)$(EXE_EXT)
+ @echo "Test JPAKE"
+ ../util/shlib_wrap.sh ./$(JPAKETEST)
+
+test_cms:
+ @echo "CMS consistency test"
+ $(PERL) cms-test.pl
+
+test_srp: $(SRPTEST)$(EXE_EXT)
+ @echo "Test SRP"
+ ../util/shlib_wrap.sh ./srptest
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ @if [ -z "$(THIS)" ]; then \
+ $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
+ else \
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(SRC); \
+ fi
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+ rm -f $(SRC) $(SHA256TEST).c $(SHA512TEST).c evptests.txt newkey.pem testkey.pem \
+ testreq.pem
+
+clean:
+ rm -f .rnd tmp.bntest tmp.bctest *.o *.obj *.dll lib tags core .pure .nfs* *.old *.bak fluff $(EXE) *.ss *.srl log dummytest
+
+$(DLIBSSL):
+ (cd ..; $(MAKE) DIRS=ssl all)
+
+$(DLIBCRYPTO):
+ (cd ..; $(MAKE) DIRS=crypto all)
+
+BUILD_CMD=shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
+ shlib_target="$(SHLIB_TARGET)"; \
+ fi; \
+ LIBRARIES="$(LIBSSL) $(LIBCRYPTO) $(LIBKRB5)"; \
+ $(MAKE) -f $(TOP)/Makefile.shared -e \
+ CC="$${CC}" APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \
+ LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
+ link_app.$${shlib_target}
+
+FIPS_BUILD_CMD=shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
+ shlib_target="$(SHLIB_TARGET)"; \
+ fi; \
+ LIBRARIES="$(LIBSSL) $(LIBCRYPTO) $(LIBKRB5)"; \
+ if [ -z "$(SHARED_LIBS)" -a -n "$(FIPSCANLIB)" ] ; then \
+ FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; export CC FIPSLD_CC; \
+ fi; \
+ $(MAKE) -f $(TOP)/Makefile.shared -e \
+ CC="$${CC}" APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \
+ LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
+ link_app.$${shlib_target}
+
+$(RSATEST)$(EXE_EXT): $(RSATEST).o $(DLIBCRYPTO)
+ @target=$(RSATEST); $(BUILD_CMD)
+
+$(BNTEST)$(EXE_EXT): $(BNTEST).o $(DLIBCRYPTO)
+ @target=$(BNTEST); $(BUILD_CMD)
+
+$(ECTEST)$(EXE_EXT): $(ECTEST).o $(DLIBCRYPTO)
+ @target=$(ECTEST); $(BUILD_CMD)
+
+$(EXPTEST)$(EXE_EXT): $(EXPTEST).o $(DLIBCRYPTO)
+ @target=$(EXPTEST); $(BUILD_CMD)
+
+$(IDEATEST)$(EXE_EXT): $(IDEATEST).o $(DLIBCRYPTO)
+ @target=$(IDEATEST); $(BUILD_CMD)
+
+$(MD2TEST)$(EXE_EXT): $(MD2TEST).o $(DLIBCRYPTO)
+ @target=$(MD2TEST); $(BUILD_CMD)
+
+$(SHATEST)$(EXE_EXT): $(SHATEST).o $(DLIBCRYPTO)
+ @target=$(SHATEST); $(BUILD_CMD)
+
+$(SHA1TEST)$(EXE_EXT): $(SHA1TEST).o $(DLIBCRYPTO)
+ @target=$(SHA1TEST); $(BUILD_CMD)
+
+$(SHA256TEST)$(EXE_EXT): $(SHA256TEST).o $(DLIBCRYPTO)
+ @target=$(SHA256TEST); $(BUILD_CMD)
+
+$(SHA512TEST)$(EXE_EXT): $(SHA512TEST).o $(DLIBCRYPTO)
+ @target=$(SHA512TEST); $(BUILD_CMD)
+
+$(RMDTEST)$(EXE_EXT): $(RMDTEST).o $(DLIBCRYPTO)
+ @target=$(RMDTEST); $(BUILD_CMD)
+
+$(MDC2TEST)$(EXE_EXT): $(MDC2TEST).o $(DLIBCRYPTO)
+ @target=$(MDC2TEST); $(BUILD_CMD)
+
+$(MD4TEST)$(EXE_EXT): $(MD4TEST).o $(DLIBCRYPTO)
+ @target=$(MD4TEST); $(BUILD_CMD)
+
+$(MD5TEST)$(EXE_EXT): $(MD5TEST).o $(DLIBCRYPTO)
+ @target=$(MD5TEST); $(BUILD_CMD)
+
+$(HMACTEST)$(EXE_EXT): $(HMACTEST).o $(DLIBCRYPTO)
+ @target=$(HMACTEST); $(BUILD_CMD)
+
+$(WPTEST)$(EXE_EXT): $(WPTEST).o $(DLIBCRYPTO)
+ @target=$(WPTEST); $(BUILD_CMD)
+
+$(RC2TEST)$(EXE_EXT): $(RC2TEST).o $(DLIBCRYPTO)
+ @target=$(RC2TEST); $(BUILD_CMD)
+
+$(BFTEST)$(EXE_EXT): $(BFTEST).o $(DLIBCRYPTO)
+ @target=$(BFTEST); $(BUILD_CMD)
+
+$(CASTTEST)$(EXE_EXT): $(CASTTEST).o $(DLIBCRYPTO)
+ @target=$(CASTTEST); $(BUILD_CMD)
+
+$(RC4TEST)$(EXE_EXT): $(RC4TEST).o $(DLIBCRYPTO)
+ @target=$(RC4TEST); $(BUILD_CMD)
+
+$(RC5TEST)$(EXE_EXT): $(RC5TEST).o $(DLIBCRYPTO)
+ @target=$(RC5TEST); $(BUILD_CMD)
+
+$(DESTEST)$(EXE_EXT): $(DESTEST).o $(DLIBCRYPTO)
+ @target=$(DESTEST); $(BUILD_CMD)
+
+$(RANDTEST)$(EXE_EXT): $(RANDTEST).o $(DLIBCRYPTO)
+ @target=$(RANDTEST); $(BUILD_CMD)
+
+$(DHTEST)$(EXE_EXT): $(DHTEST).o $(DLIBCRYPTO)
+ @target=$(DHTEST); $(BUILD_CMD)
+
+$(DSATEST)$(EXE_EXT): $(DSATEST).o $(DLIBCRYPTO)
+ @target=$(DSATEST); $(BUILD_CMD)
+
+$(METHTEST)$(EXE_EXT): $(METHTEST).o $(DLIBCRYPTO)
+ @target=$(METHTEST); $(BUILD_CMD)
+
+$(SSLTEST)$(EXE_EXT): $(SSLTEST).o $(DLIBSSL) $(DLIBCRYPTO)
+ @target=$(SSLTEST); $(FIPS_BUILD_CMD)
+
+$(ENGINETEST)$(EXE_EXT): $(ENGINETEST).o $(DLIBCRYPTO)
+ @target=$(ENGINETEST); $(BUILD_CMD)
+
+$(EVPTEST)$(EXE_EXT): $(EVPTEST).o $(DLIBCRYPTO)
+ @target=$(EVPTEST); $(BUILD_CMD)
+
+$(ECDSATEST)$(EXE_EXT): $(ECDSATEST).o $(DLIBCRYPTO)
+ @target=$(ECDSATEST); $(BUILD_CMD)
+
+$(ECDHTEST)$(EXE_EXT): $(ECDHTEST).o $(DLIBCRYPTO)
+ @target=$(ECDHTEST); $(BUILD_CMD)
+
+$(IGETEST)$(EXE_EXT): $(IGETEST).o $(DLIBCRYPTO)
+ @target=$(IGETEST); $(BUILD_CMD)
+
+$(JPAKETEST)$(EXE_EXT): $(JPAKETEST).o $(DLIBCRYPTO)
+ @target=$(JPAKETEST); $(BUILD_CMD)
+
+$(ASN1TEST)$(EXE_EXT): $(ASN1TEST).o $(DLIBCRYPTO)
+ @target=$(ASN1TEST); $(BUILD_CMD)
+
+$(SRPTEST)$(EXE_EXT): $(SRPTEST).o $(DLIBCRYPTO)
+ @target=$(SRPTEST); $(BUILD_CMD)
+
+#$(AESTEST).o: $(AESTEST).c
+# $(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c
+
+#$(AESTEST)$(EXE_EXT): $(AESTEST).o $(DLIBCRYPTO)
+# if [ "$(SHLIB_TARGET)" = "hpux-shared" -o "$(SHLIB_TARGET)" = "darwin-shared" ] ; then \
+# $(CC) -o $(AESTEST)$(EXE_EXT) $(CFLAGS) $(AESTEST).o $(PEX_LIBS) $(DLIBCRYPTO) $(EX_LIBS) ; \
+# else \
+# $(CC) -o $(AESTEST)$(EXE_EXT) $(CFLAGS) $(AESTEST).o $(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS) ; \
+# fi
+
+dummytest$(EXE_EXT): dummytest.o $(DLIBCRYPTO)
+ @target=dummytest; $(BUILD_CMD)
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+asn1test.o: ../include/openssl/asn1.h ../include/openssl/asn1_mac.h
+asn1test.o: ../include/openssl/bio.h ../include/openssl/buffer.h
+asn1test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+asn1test.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+asn1test.o: ../include/openssl/ecdsa.h ../include/openssl/evp.h
+asn1test.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+asn1test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+asn1test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+asn1test.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+asn1test.o: ../include/openssl/sha.h ../include/openssl/stack.h
+asn1test.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+asn1test.o: ../include/openssl/x509_vfy.h asn1test.c
+bftest.o: ../e_os.h ../include/openssl/blowfish.h ../include/openssl/e_os2.h
+bftest.o: ../include/openssl/opensslconf.h bftest.c
+bntest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+bntest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+bntest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+bntest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+bntest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+bntest.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+bntest.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+bntest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+bntest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+bntest.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+bntest.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+bntest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+bntest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+bntest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h bntest.c
+casttest.o: ../e_os.h ../include/openssl/cast.h ../include/openssl/e_os2.h
+casttest.o: ../include/openssl/opensslconf.h casttest.c
+destest.o: ../include/openssl/des.h ../include/openssl/des_old.h
+destest.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+destest.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+destest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+destest.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h destest.c
+dhtest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
+dhtest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+dhtest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+dhtest.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
+dhtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+dhtest.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+dhtest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h dhtest.c
+dsatest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
+dsatest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+dsatest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+dsatest.o: ../include/openssl/err.h ../include/openssl/lhash.h
+dsatest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+dsatest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
+dsatest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+dsatest.o: ../include/openssl/symhacks.h dsatest.c
+ecdhtest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ecdhtest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+ecdhtest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ecdhtest.o: ../include/openssl/ecdh.h ../include/openssl/err.h
+ecdhtest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ecdhtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ecdhtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ecdhtest.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+ecdhtest.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ecdhtest.o: ../include/openssl/symhacks.h ecdhtest.c
+ecdsatest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+ecdsatest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ecdsatest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+ecdsatest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ecdsatest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ecdsatest.o: ../include/openssl/err.h ../include/openssl/evp.h
+ecdsatest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ecdsatest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ecdsatest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ecdsatest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+ecdsatest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ecdsatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ecdsatest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ecdsatest.o: ecdsatest.c
+ectest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ectest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ectest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+ectest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ectest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ectest.o: ../include/openssl/err.h ../include/openssl/evp.h
+ectest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ectest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ectest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ectest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+ectest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ectest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ectest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ectest.c
+enginetest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+enginetest.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
+enginetest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+enginetest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+enginetest.o: ../include/openssl/engine.h ../include/openssl/err.h
+enginetest.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+enginetest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+enginetest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+enginetest.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+enginetest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+enginetest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+enginetest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+enginetest.o: enginetest.c
+evp_test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+evp_test.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+evp_test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+evp_test.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+evp_test.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+evp_test.o: ../include/openssl/err.h ../include/openssl/evp.h
+evp_test.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+evp_test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+evp_test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+evp_test.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+evp_test.o: ../include/openssl/sha.h ../include/openssl/stack.h
+evp_test.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+evp_test.o: ../include/openssl/x509_vfy.h evp_test.c
+exptest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
+exptest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+exptest.o: ../include/openssl/err.h ../include/openssl/lhash.h
+exptest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+exptest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
+exptest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+exptest.o: ../include/openssl/symhacks.h exptest.c
+hmactest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+hmactest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+hmactest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+hmactest.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+hmactest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+hmactest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+hmactest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+hmactest.o: ../include/openssl/symhacks.h hmactest.c
+ideatest.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/idea.h
+ideatest.o: ../include/openssl/opensslconf.h ideatest.c
+igetest.o: ../include/openssl/aes.h ../include/openssl/e_os2.h
+igetest.o: ../include/openssl/opensslconf.h ../include/openssl/ossl_typ.h
+igetest.o: ../include/openssl/rand.h igetest.c
+jpaketest.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
+jpaketest.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+jpaketest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+jpaketest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+jpaketest.o: ../include/openssl/symhacks.h jpaketest.c
+md2test.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
+md2test.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+md2test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+md2test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+md2test.o: ../include/openssl/symhacks.h md2test.c
+md4test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+md4test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+md4test.o: ../include/openssl/evp.h ../include/openssl/md4.h
+md4test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+md4test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+md4test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+md4test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h md4test.c
+md5test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+md5test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+md5test.o: ../include/openssl/evp.h ../include/openssl/md5.h
+md5test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+md5test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+md5test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+md5test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h md5test.c
+mdc2test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+mdc2test.o: ../include/openssl/crypto.h ../include/openssl/des.h
+mdc2test.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
+mdc2test.o: ../include/openssl/evp.h ../include/openssl/mdc2.h
+mdc2test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+mdc2test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+mdc2test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+mdc2test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+mdc2test.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h mdc2test.c
+randtest.o: ../e_os.h ../include/openssl/e_os2.h
+randtest.o: ../include/openssl/opensslconf.h ../include/openssl/ossl_typ.h
+randtest.o: ../include/openssl/rand.h randtest.c
+rc2test.o: ../e_os.h ../include/openssl/e_os2.h
+rc2test.o: ../include/openssl/opensslconf.h ../include/openssl/rc2.h rc2test.c
+rc4test.o: ../e_os.h ../include/openssl/e_os2.h
+rc4test.o: ../include/openssl/opensslconf.h ../include/openssl/rc4.h
+rc4test.o: ../include/openssl/sha.h rc4test.c
+rc5test.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
+rc5test.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+rc5test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rc5test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+rc5test.o: ../include/openssl/symhacks.h rc5test.c
+rmdtest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+rmdtest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+rmdtest.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
+rmdtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+rmdtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rmdtest.o: ../include/openssl/ripemd.h ../include/openssl/safestack.h
+rmdtest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h rmdtest.c
+rsa_test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+rsa_test.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+rsa_test.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+rsa_test.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
+rsa_test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rsa_test.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+rsa_test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+rsa_test.o: ../include/openssl/symhacks.h rsa_test.c
+sha1test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+sha1test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+sha1test.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
+sha1test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+sha1test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+sha1test.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+sha1test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h sha1test.c
+shatest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+shatest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+shatest.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
+shatest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+shatest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+shatest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+shatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h shatest.c
+srptest.o: ../include/openssl/bio.h ../include/openssl/bn.h
+srptest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+srptest.o: ../include/openssl/err.h ../include/openssl/lhash.h
+srptest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+srptest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
+srptest.o: ../include/openssl/safestack.h ../include/openssl/srp.h
+srptest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h srptest.c
+ssltest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ssltest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ssltest.o: ../include/openssl/comp.h ../include/openssl/conf.h
+ssltest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+ssltest.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+ssltest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ssltest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ssltest.o: ../include/openssl/engine.h ../include/openssl/err.h
+ssltest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ssltest.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssltest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssltest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssltest.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssltest.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssltest.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+ssltest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ssltest.o: ../include/openssl/sha.h ../include/openssl/srp.h
+ssltest.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ssltest.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssltest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssltest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssltest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ssltest.o: ../include/openssl/x509v3.h ssltest.c
+wp_test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+wp_test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+wp_test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+wp_test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+wp_test.o: ../include/openssl/whrlpool.h wp_test.c
diff --git a/deps/openssl/openssl/test/P1ss.cnf b/deps/openssl/openssl/test/P1ss.cnf
new file mode 100644
index 000000000..326cce2ba
--- /dev/null
+++ b/deps/openssl/openssl/test/P1ss.cnf
@@ -0,0 +1,37 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE = ./.rnd
+
+####################################################################
+[ req ]
+default_bits = 1024
+default_keyfile = keySS.pem
+distinguished_name = req_distinguished_name
+encrypt_rsa_key = no
+default_md = md2
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = AU
+countryName_value = AU
+
+organizationName = Organization Name (eg, company)
+organizationName_value = Dodgy Brothers
+
+0.commonName = Common Name (eg, YOUR name)
+0.commonName_value = Brother 1
+
+1.commonName = Common Name (eg, YOUR name)
+1.commonName_value = Brother 2
+
+2.commonName = Common Name (eg, YOUR name)
+2.commonName_value = Proxy 1
+
+[ v3_proxy ]
+basicConstraints=CA:FALSE
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB
diff --git a/deps/openssl/openssl/test/P2ss.cnf b/deps/openssl/openssl/test/P2ss.cnf
new file mode 100644
index 000000000..8b502321b
--- /dev/null
+++ b/deps/openssl/openssl/test/P2ss.cnf
@@ -0,0 +1,45 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE = ./.rnd
+
+####################################################################
+[ req ]
+default_bits = 1024
+default_keyfile = keySS.pem
+distinguished_name = req_distinguished_name
+encrypt_rsa_key = no
+default_md = md2
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = AU
+countryName_value = AU
+
+organizationName = Organization Name (eg, company)
+organizationName_value = Dodgy Brothers
+
+0.commonName = Common Name (eg, YOUR name)
+0.commonName_value = Brother 1
+
+1.commonName = Common Name (eg, YOUR name)
+1.commonName_value = Brother 2
+
+2.commonName = Common Name (eg, YOUR name)
+2.commonName_value = Proxy 1
+
+3.commonName = Common Name (eg, YOUR name)
+3.commonName_value = Proxy 2
+
+[ v3_proxy ]
+basicConstraints=CA:FALSE
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+proxyCertInfo=critical,@proxy_ext
+
+[ proxy_ext ]
+language=id-ppl-anyLanguage
+pathlen=0
+policy=text:BC
diff --git a/deps/openssl/openssl/test/Sssdsa.cnf b/deps/openssl/openssl/test/Sssdsa.cnf
new file mode 100644
index 000000000..8e170a28e
--- /dev/null
+++ b/deps/openssl/openssl/test/Sssdsa.cnf
@@ -0,0 +1,27 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+# hacked by iang to do DSA certs - Server
+
+RANDFILE = ./.rnd
+
+####################################################################
+[ req ]
+distinguished_name = req_distinguished_name
+encrypt_rsa_key = no
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = ES
+countryName_value = ES
+
+organizationName = Organization Name (eg, company)
+organizationName_value = Tortilleras S.A.
+
+0.commonName = Common Name (eg, YOUR name)
+0.commonName_value = Torti
+
+1.commonName = Common Name (eg, YOUR name)
+1.commonName_value = Gordita
+
diff --git a/deps/openssl/openssl/test/Sssrsa.cnf b/deps/openssl/openssl/test/Sssrsa.cnf
new file mode 100644
index 000000000..8c79a03fc
--- /dev/null
+++ b/deps/openssl/openssl/test/Sssrsa.cnf
@@ -0,0 +1,26 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+# create RSA certs - Server
+
+RANDFILE = ./.rnd
+
+####################################################################
+[ req ]
+distinguished_name = req_distinguished_name
+encrypt_key = no
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = ES
+countryName_value = ES
+
+organizationName = Organization Name (eg, company)
+organizationName_value = Tortilleras S.A.
+
+0.commonName = Common Name (eg, YOUR name)
+0.commonName_value = Torti
+
+1.commonName = Common Name (eg, YOUR name)
+1.commonName_value = Gordita
diff --git a/deps/openssl/openssl/test/Uss.cnf b/deps/openssl/openssl/test/Uss.cnf
new file mode 100644
index 000000000..58ac0ca54
--- /dev/null
+++ b/deps/openssl/openssl/test/Uss.cnf
@@ -0,0 +1,36 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE = ./.rnd
+
+####################################################################
+[ req ]
+default_bits = 2048
+default_keyfile = keySS.pem
+distinguished_name = req_distinguished_name
+encrypt_rsa_key = no
+default_md = sha256
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = AU
+countryName_value = AU
+
+organizationName = Organization Name (eg, company)
+organizationName_value = Dodgy Brothers
+
+0.commonName = Common Name (eg, YOUR name)
+0.commonName_value = Brother 1
+
+1.commonName = Common Name (eg, YOUR name)
+1.commonName_value = Brother 2
+
+[ v3_ee ]
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+basicConstraints = CA:false
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+issuerAltName=issuer:copy
+
diff --git a/deps/openssl/openssl/test/VMSca-response.1 b/deps/openssl/openssl/test/VMSca-response.1
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/deps/openssl/openssl/test/VMSca-response.1
@@ -0,0 +1 @@
+
diff --git a/deps/openssl/openssl/test/VMSca-response.2 b/deps/openssl/openssl/test/VMSca-response.2
new file mode 100644
index 000000000..9b48ee4cf
--- /dev/null
+++ b/deps/openssl/openssl/test/VMSca-response.2
@@ -0,0 +1,2 @@
+y
+y
diff --git a/deps/openssl/openssl/test/asn1test.c b/deps/openssl/openssl/test/asn1test.c
new file mode 100755
index 000000000..9f53d8034
--- /dev/null
+++ b/deps/openssl/openssl/test/asn1test.c
@@ -0,0 +1,22 @@
+#include <openssl/x509.h>
+#include <openssl/asn1_mac.h>
+
+typedef struct X
+ {
+ STACK_OF(X509_EXTENSION) *ext;
+ } X;
+
+/* This isn't meant to run particularly, it's just to test type checking */
+int main(int argc, char **argv)
+ {
+ X *x = NULL;
+ unsigned char **pp = NULL;
+
+ M_ASN1_I2D_vars(x);
+ M_ASN1_I2D_len_SEQUENCE_opt_type(X509_EXTENSION, x->ext,
+ i2d_X509_EXTENSION);
+ M_ASN1_I2D_seq_total();
+ M_ASN1_I2D_put_SEQUENCE_opt_type(X509_EXTENSION, x->ext,
+ i2d_X509_EXTENSION);
+ M_ASN1_I2D_finish();
+ }
diff --git a/deps/openssl/openssl/test/bctest b/deps/openssl/openssl/test/bctest
new file mode 100755
index 000000000..bdb3218f7
--- /dev/null
+++ b/deps/openssl/openssl/test/bctest
@@ -0,0 +1,111 @@
+#!/bin/sh
+
+# This script is used by test/Makefile.ssl to check whether a sane 'bc'
+# is installed.
+# ('make test_bn' should not try to run 'bc' if it does not exist or if
+# it is a broken 'bc' version that is known to cause trouble.)
+#
+# If 'bc' works, we also test if it knows the 'print' command.
+#
+# In any case, output an appropriate command line for running (or not
+# running) bc.
+
+
+IFS=:
+try_without_dir=true
+# First we try "bc", then "$dir/bc" for each item in $PATH.
+for dir in dummy:$PATH; do
+ if [ "$try_without_dir" = true ]; then
+ # first iteration
+ bc=bc
+ try_without_dir=false
+ else
+ # second and later iterations
+ bc="$dir/bc"
+ if [ ! -f "$bc" ]; then # '-x' is not available on Ultrix
+ bc=''
+ fi
+ fi
+
+ if [ ! "$bc" = '' ]; then
+ failure=none
+
+
+ # Test for SunOS 5.[78] bc bug
+ "$bc" >tmp.bctest <<\EOF
+obase=16
+ibase=16
+a=AD88C418F31B3FC712D0425001D522B3AE9134FF3A98C13C1FCC1682211195406C1A6C66C6A\
+CEEC1A0EC16950233F77F1C2F2363D56DD71A36C57E0B2511FC4BA8F22D261FE2E9356D99AF57\
+10F3817C0E05BF79C423C3F66FDF321BE8D3F18F625D91B670931C1EF25F28E489BDA1C5422D1\
+C3F6F7A1AD21585746ECC4F10A14A778AF56F08898E965E9909E965E0CB6F85B514150C644759\
+3BE731877B16EA07B552088FF2EA728AC5E0FF3A23EB939304519AB8B60F2C33D6BA0945B66F0\
+4FC3CADF855448B24A9D7640BCF473E
+b=DCE91E7D120B983EA9A104B5A96D634DD644C37657B1C7860B45E6838999B3DCE5A555583C6\
+9209E41F413422954175A06E67FFEF6746DD652F0F48AEFECC3D8CAC13523BDAAD3F5AF4212BD\
+8B3CD64126E1A82E190228020C05B91C8B141F1110086FC2A4C6ED631EBA129D04BB9A19FC53D\
+3ED0E2017D60A68775B75481449
+(a/b)*b + (a%b) - a
+EOF
+ if [ 0 != "`cat tmp.bctest`" ]; then
+ failure=SunOStest
+ fi
+
+
+ if [ "$failure" = none ]; then
+ # Test for SCO bc bug.
+ "$bc" >tmp.bctest <<\EOF
+obase=16
+ibase=16
+-FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4AEC6F15AC177F176F2274D2\
+9DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7F5ADFACEE54573F5D256A06\
+11B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99FB9812A0E4A5773D8B254117\
+1239157EC6E3D8D50199 * -FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4\
+AEC6F15AC177F176F2274D29DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7\
+F5ADFACEE54573F5D256A0611B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99F\
+B9812A0E4A5773D8B2541171239157EC6E3D8D50199 - FFBACC221682DA464B6D7F123482522\
+02EDAEDCA38C3B69E9B7BBCD6165A9CD8716C4903417F23C09A85B851961F92C217258CEEB866\
+85EFCC5DD131853A02C07A873B8E2AF2E40C6D5ED598CD0E8F35AD49F3C3A17FDB7653E4E2DC4\
+A8D23CC34686EE4AD01F7407A7CD74429AC6D36DBF0CB6A3E302D0E5BDFCD048A3B90C1BE5AA8\
+E16C3D5884F9136B43FF7BB443764153D4AEC176C681B078F4CC53D6EB6AB76285537DDEE7C18\
+8C72441B52EDBDDBC77E02D34E513F2AABF92F44109CAFE8242BD0ECBAC5604A94B02EA44D43C\
+04E9476E6FBC48043916BFA1485C6093603600273C9C33F13114D78064AE42F3DC466C7DA543D\
+89C8D71
+AD534AFBED2FA39EE9F40E20FCF9E2C861024DB98DDCBA1CD118C49CA55EEBC20D6BA51B2271C\
+928B693D6A73F67FEB1B4571448588B46194617D25D910C6A9A130CC963155CF34079CB218A44\
+8A1F57E276D92A33386DDCA3D241DB78C8974ABD71DD05B0FA555709C9910D745185E6FE108E3\
+37F1907D0C56F8BFBF52B9704 % -E557905B56B13441574CAFCE2BD257A750B1A8B2C88D0E36\
+E18EF7C38DAC80D3948E17ED63AFF3B3467866E3B89D09A81B3D16B52F6A3C7134D3C6F5123E9\
+F617E3145BBFBE9AFD0D6E437EA4FF6F04BC67C4F1458B4F0F47B64 - 1C2BBBB19B74E86FD32\
+9E8DB6A8C3B1B9986D57ED5419C2E855F7D5469E35E76334BB42F4C43E3F3A31B9697C171DAC4\
+D97935A7E1A14AD209D6CF811F55C6DB83AA9E6DFECFCD6669DED7171EE22A40C6181615CAF3F\
+5296964
+EOF
+ if [ "0
+0" != "`cat tmp.bctest`" ]; then
+ failure=SCOtest
+ fi
+ fi
+
+
+ if [ "$failure" = none ]; then
+ # bc works; now check if it knows the 'print' command.
+ if [ "OK" = "`echo 'print \"OK\"' | $bc 2>/dev/null`" ]
+ then
+ echo "$bc"
+ else
+ echo "sed 's/print.*//' | $bc"
+ fi
+ exit 0
+ fi
+
+ echo "$bc does not work properly ('$failure' failed). Looking for another bc ..." >&2
+ fi
+done
+
+echo "No working bc found. Consider installing GNU bc." >&2
+if [ "$1" = ignore ]; then
+ echo "cat >/dev/null"
+ exit 0
+fi
+exit 1
diff --git a/deps/openssl/openssl/test/bctest.com b/deps/openssl/openssl/test/bctest.com
new file mode 100644
index 000000000..d7e5ec139
--- /dev/null
+++ b/deps/openssl/openssl/test/bctest.com
@@ -0,0 +1,152 @@
+$!
+$! Check operation of "bc".
+$!
+$! 2010-04-05 SMS. New. Based (loosely) on "bctest".
+$!
+$!
+$ tmp_file_name = "tmp.bctest"
+$ failure = ""
+$!
+$! Basic command test.
+$!
+$ on warning then goto bc_fail
+$ bc
+$ on error then exit
+$!
+$! Test for SunOS 5.[78] bc bug.
+$!
+$ if (failure .eqs. "")
+$ then
+$!
+$ define /user_mode sys$output 'tmp_file_name'
+$ bc
+obase=16
+ibase=16
+a=AD88C418F31B3FC712D0425001D522B3AE9134FF3A98C13C1FCC1682211195406C1A6C66C6A\
+CEEC1A0EC16950233F77F1C2F2363D56DD71A36C57E0B2511FC4BA8F22D261FE2E9356D99AF57\
+10F3817C0E05BF79C423C3F66FDF321BE8D3F18F625D91B670931C1EF25F28E489BDA1C5422D1\
+C3F6F7A1AD21585746ECC4F10A14A778AF56F08898E965E9909E965E0CB6F85B514150C644759\
+3BE731877B16EA07B552088FF2EA728AC5E0FF3A23EB939304519AB8B60F2C33D6BA0945B66F0\
+4FC3CADF855448B24A9D7640BCF473E
+b=DCE91E7D120B983EA9A104B5A96D634DD644C37657B1C7860B45E6838999B3DCE5A555583C6\
+9209E41F413422954175A06E67FFEF6746DD652F0F48AEFECC3D8CAC13523BDAAD3F5AF4212BD\
+8B3CD64126E1A82E190228020C05B91C8B141F1110086FC2A4C6ED631EBA129D04BB9A19FC53D\
+3ED0E2017D60A68775B75481449
+(a/b)*b + (a%b) - a
+$ status = $status
+$ output_expected = "0"
+$ gosub check_output
+$ if (output .ne. 1)
+$ then
+$ failure = "SunOStest"
+$ else
+$ delete 'f$parse( tmp_file_name)'
+$ endif
+$ endif
+$!
+$! Test for SCO bc bug.
+$!
+$ if (failure .eqs. "")
+$ then
+$!
+$ define /user_mode sys$output 'tmp_file_name'
+$ bc
+obase=16
+ibase=16
+-FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4AEC6F15AC177F176F2274D2\
+9DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7F5ADFACEE54573F5D256A06\
+11B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99FB9812A0E4A5773D8B254117\
+1239157EC6E3D8D50199 * -FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4\
+AEC6F15AC177F176F2274D29DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7\
+F5ADFACEE54573F5D256A0611B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99F\
+B9812A0E4A5773D8B2541171239157EC6E3D8D50199 - FFBACC221682DA464B6D7F123482522\
+02EDAEDCA38C3B69E9B7BBCD6165A9CD8716C4903417F23C09A85B851961F92C217258CEEB866\
+85EFCC5DD131853A02C07A873B8E2AF2E40C6D5ED598CD0E8F35AD49F3C3A17FDB7653E4E2DC4\
+A8D23CC34686EE4AD01F7407A7CD74429AC6D36DBF0CB6A3E302D0E5BDFCD048A3B90C1BE5AA8\
+E16C3D5884F9136B43FF7BB443764153D4AEC176C681B078F4CC53D6EB6AB76285537DDEE7C18\
+8C72441B52EDBDDBC77E02D34E513F2AABF92F44109CAFE8242BD0ECBAC5604A94B02EA44D43C\
+04E9476E6FBC48043916BFA1485C6093603600273C9C33F13114D78064AE42F3DC466C7DA543D\
+89C8D71
+AD534AFBED2FA39EE9F40E20FCF9E2C861024DB98DDCBA1CD118C49CA55EEBC20D6BA51B2271C\
+928B693D6A73F67FEB1B4571448588B46194617D25D910C6A9A130CC963155CF34079CB218A44\
+8A1F57E276D92A33386DDCA3D241DB78C8974ABD71DD05B0FA555709C9910D745185E6FE108E3\
+37F1907D0C56F8BFBF52B9704 % -E557905B56B13441574CAFCE2BD257A750B1A8B2C88D0E36\
+E18EF7C38DAC80D3948E17ED63AFF3B3467866E3B89D09A81B3D16B52F6A3C7134D3C6F5123E9\
+F617E3145BBFBE9AFD0D6E437EA4FF6F04BC67C4F1458B4F0F47B64 - 1C2BBBB19B74E86FD32\
+9E8DB6A8C3B1B9986D57ED5419C2E855F7D5469E35E76334BB42F4C43E3F3A31B9697C171DAC4\
+D97935A7E1A14AD209D6CF811F55C6DB83AA9E6DFECFCD6669DED7171EE22A40C6181615CAF3F\
+5296964
+$ status = $status
+$ output_expected = "0\0"
+$ gosub check_output
+$ if (output .ne. 1)
+$ then
+$ failure = "SCOtest"
+$ else
+$ delete 'f$parse( tmp_file_name)'
+$ endif
+$ endif
+$!
+$! Test for working 'print' command.
+$!
+$ if (failure .eqs. "")
+$ then
+$!
+$ define /user_mode sys$output 'tmp_file_name'
+$ bc
+print "OK"
+$ status = $status
+$ output_expected = "OK"
+$ gosub check_output
+$ if (output .ne. 1)
+$ then
+$ failure = "printtest"
+$ else
+$ delete 'f$parse( tmp_file_name)'
+$ endif
+$ endif
+$!
+$ if (failure .nes. "")
+$ then
+$ write sys$output -
+ "No working bc found. Consider installing GNU bc."
+$ exit %X00030000 ! %DCL-W-NORMAL
+$ endif
+$!
+$ exit
+$!
+$!
+$! Complete "bc" command failure.
+$!
+$ bc_fail:
+$ write sys$output -
+ "No ""bc"" program/symbol found. Consider installing GNU bc."
+$ exit %X00030000 ! %DCL-W-NORMAL
+$!
+$!
+$! Output check subroutine.
+$!
+$ check_output:
+$ eof = 0
+$ line_nr = 0
+$ open /read tmp_file 'tmp_file_name'
+$ c_o_loop:
+$ read /error = error_read tmp_file line
+$ goto ok_read
+$ error_read:
+$ eof = 1
+$ ok_read:
+$ line_expected = f$element( line_nr, "\", output_expected)
+$ line_nr = line_nr+ 1
+$ if ((line_expected .nes. "\") .and. (.not. eof) .and. -
+ (line_expected .eqs. line)) then goto c_o_loop
+$!
+$ if ((line_expected .eqs. "\") .and. eof)
+$ then
+$ output = 1
+$ else
+$ output = 0
+$ endif
+$ close tmp_file
+$ return
+$!
diff --git a/deps/openssl/openssl/test/bftest.c b/deps/openssl/openssl/test/bftest.c
new file mode 100644
index 000000000..97e6634d3
--- /dev/null
+++ b/deps/openssl/openssl/test/bftest.c
@@ -0,0 +1,540 @@
+/* crypto/bf/bftest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* This has been a quickly hacked 'ideatest.c'. When I add tests for other
+ * RC2 modes, more of the code will be uncommented. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_BF is defined */
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_BF
+int main(int argc, char *argv[])
+{
+ printf("No BF support\n");
+ return(0);
+}
+#else
+#include <openssl/blowfish.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+static char *bf_key[2]={
+ "abcdefghijklmnopqrstuvwxyz",
+ "Who is John Galt?"
+ };
+
+/* big endian */
+static BF_LONG bf_plain[2][2]={
+ {0x424c4f57L,0x46495348L},
+ {0xfedcba98L,0x76543210L}
+ };
+
+static BF_LONG bf_cipher[2][2]={
+ {0x324ed0feL,0xf413a203L},
+ {0xcc91732bL,0x8022f684L}
+ };
+/************/
+
+/* Lets use the DES test vectors :-) */
+#define NUM_TESTS 34
+static unsigned char ecb_data[NUM_TESTS][8]={
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
+ {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
+ {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
+ {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
+ {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
+ {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
+ {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
+ {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
+ {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
+ {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
+ {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
+ {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
+ {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
+ {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
+ {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
+ {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
+ {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
+ {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
+ {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
+ {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+ {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
+
+static unsigned char plain_data[NUM_TESTS][8]={
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
+ {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
+ {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
+ {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
+ {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
+ {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
+ {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
+ {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
+ {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
+ {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
+ {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
+ {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
+ {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
+ {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
+ {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
+ {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
+ {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
+ {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
+ {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
+
+static unsigned char cipher_data[NUM_TESTS][8]={
+ {0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78},
+ {0x51,0x86,0x6F,0xD5,0xB8,0x5E,0xCB,0x8A},
+ {0x7D,0x85,0x6F,0x9A,0x61,0x30,0x63,0xF2},
+ {0x24,0x66,0xDD,0x87,0x8B,0x96,0x3C,0x9D},
+ {0x61,0xF9,0xC3,0x80,0x22,0x81,0xB0,0x96},
+ {0x7D,0x0C,0xC6,0x30,0xAF,0xDA,0x1E,0xC7},
+ {0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78},
+ {0x0A,0xCE,0xAB,0x0F,0xC6,0xA0,0xA2,0x8D},
+ {0x59,0xC6,0x82,0x45,0xEB,0x05,0x28,0x2B},
+ {0xB1,0xB8,0xCC,0x0B,0x25,0x0F,0x09,0xA0},
+ {0x17,0x30,0xE5,0x77,0x8B,0xEA,0x1D,0xA4},
+ {0xA2,0x5E,0x78,0x56,0xCF,0x26,0x51,0xEB},
+ {0x35,0x38,0x82,0xB1,0x09,0xCE,0x8F,0x1A},
+ {0x48,0xF4,0xD0,0x88,0x4C,0x37,0x99,0x18},
+ {0x43,0x21,0x93,0xB7,0x89,0x51,0xFC,0x98},
+ {0x13,0xF0,0x41,0x54,0xD6,0x9D,0x1A,0xE5},
+ {0x2E,0xED,0xDA,0x93,0xFF,0xD3,0x9C,0x79},
+ {0xD8,0x87,0xE0,0x39,0x3C,0x2D,0xA6,0xE3},
+ {0x5F,0x99,0xD0,0x4F,0x5B,0x16,0x39,0x69},
+ {0x4A,0x05,0x7A,0x3B,0x24,0xD3,0x97,0x7B},
+ {0x45,0x20,0x31,0xC1,0xE4,0xFA,0xDA,0x8E},
+ {0x75,0x55,0xAE,0x39,0xF5,0x9B,0x87,0xBD},
+ {0x53,0xC5,0x5F,0x9C,0xB4,0x9F,0xC0,0x19},
+ {0x7A,0x8E,0x7B,0xFA,0x93,0x7E,0x89,0xA3},
+ {0xCF,0x9C,0x5D,0x7A,0x49,0x86,0xAD,0xB5},
+ {0xD1,0xAB,0xB2,0x90,0x65,0x8B,0xC7,0x78},
+ {0x55,0xCB,0x37,0x74,0xD1,0x3E,0xF2,0x01},
+ {0xFA,0x34,0xEC,0x48,0x47,0xB2,0x68,0xB2},
+ {0xA7,0x90,0x79,0x51,0x08,0xEA,0x3C,0xAE},
+ {0xC3,0x9E,0x07,0x2D,0x9F,0xAC,0x63,0x1D},
+ {0x01,0x49,0x33,0xE0,0xCD,0xAF,0xF6,0xE4},
+ {0xF2,0x1E,0x9A,0x77,0xB7,0x1C,0x49,0xBC},
+ {0x24,0x59,0x46,0x88,0x57,0x54,0x36,0x9A},
+ {0x6B,0x5C,0x5A,0x9C,0x5D,0x9E,0x0A,0x5A},
+ };
+
+static unsigned char cbc_key [16]={
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+ 0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
+static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static char cbc_data[40]="7654321 Now is the time for ";
+static unsigned char cbc_ok[32]={
+ 0x6B,0x77,0xB4,0xD6,0x30,0x06,0xDE,0xE6,
+ 0x05,0xB1,0x56,0xE2,0x74,0x03,0x97,0x93,
+ 0x58,0xDE,0xB9,0xE7,0x15,0x46,0x16,0xD9,
+ 0x59,0xF1,0x65,0x2B,0xD5,0xFF,0x92,0xCC};
+
+static unsigned char cfb64_ok[]={
+ 0xE7,0x32,0x14,0xA2,0x82,0x21,0x39,0xCA,
+ 0xF2,0x6E,0xCF,0x6D,0x2E,0xB9,0xE7,0x6E,
+ 0x3D,0xA3,0xDE,0x04,0xD1,0x51,0x72,0x00,
+ 0x51,0x9D,0x57,0xA6,0xC3};
+
+static unsigned char ofb64_ok[]={
+ 0xE7,0x32,0x14,0xA2,0x82,0x21,0x39,0xCA,
+ 0x62,0xB3,0x43,0xCC,0x5B,0x65,0x58,0x73,
+ 0x10,0xDD,0x90,0x8D,0x0C,0x24,0x1B,0x22,
+ 0x63,0xC2,0xCF,0x80,0xDA};
+
+#define KEY_TEST_NUM 25
+static unsigned char key_test[KEY_TEST_NUM]={
+ 0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87,
+ 0x78,0x69,0x5a,0x4b,0x3c,0x2d,0x1e,0x0f,
+ 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
+ 0x88};
+
+static unsigned char key_data[8]=
+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10};
+
+static unsigned char key_out[KEY_TEST_NUM][8]={
+ {0xF9,0xAD,0x59,0x7C,0x49,0xDB,0x00,0x5E},
+ {0xE9,0x1D,0x21,0xC1,0xD9,0x61,0xA6,0xD6},
+ {0xE9,0xC2,0xB7,0x0A,0x1B,0xC6,0x5C,0xF3},
+ {0xBE,0x1E,0x63,0x94,0x08,0x64,0x0F,0x05},
+ {0xB3,0x9E,0x44,0x48,0x1B,0xDB,0x1E,0x6E},
+ {0x94,0x57,0xAA,0x83,0xB1,0x92,0x8C,0x0D},
+ {0x8B,0xB7,0x70,0x32,0xF9,0x60,0x62,0x9D},
+ {0xE8,0x7A,0x24,0x4E,0x2C,0xC8,0x5E,0x82},
+ {0x15,0x75,0x0E,0x7A,0x4F,0x4E,0xC5,0x77},
+ {0x12,0x2B,0xA7,0x0B,0x3A,0xB6,0x4A,0xE0},
+ {0x3A,0x83,0x3C,0x9A,0xFF,0xC5,0x37,0xF6},
+ {0x94,0x09,0xDA,0x87,0xA9,0x0F,0x6B,0xF2},
+ {0x88,0x4F,0x80,0x62,0x50,0x60,0xB8,0xB4},
+ {0x1F,0x85,0x03,0x1C,0x19,0xE1,0x19,0x68},
+ {0x79,0xD9,0x37,0x3A,0x71,0x4C,0xA3,0x4F},
+ {0x93,0x14,0x28,0x87,0xEE,0x3B,0xE1,0x5C},
+ {0x03,0x42,0x9E,0x83,0x8C,0xE2,0xD1,0x4B},
+ {0xA4,0x29,0x9E,0x27,0x46,0x9F,0xF6,0x7B},
+ {0xAF,0xD5,0xAE,0xD1,0xC1,0xBC,0x96,0xA8},
+ {0x10,0x85,0x1C,0x0E,0x38,0x58,0xDA,0x9F},
+ {0xE6,0xF5,0x1E,0xD7,0x9B,0x9D,0xB2,0x1F},
+ {0x64,0xA6,0xE1,0x4A,0xFD,0x36,0xB4,0x6F},
+ {0x80,0xC7,0xD7,0xD4,0x5A,0x54,0x79,0xAD},
+ {0x05,0x04,0x4B,0x62,0xFA,0x52,0xD0,0x80},
+ };
+
+static int test(void );
+static int print_test_data(void );
+int main(int argc, char *argv[])
+ {
+ int ret;
+
+ if (argc > 1)
+ ret=print_test_data();
+ else
+ ret=test();
+
+#ifdef OPENSSL_SYS_NETWARE
+ if (ret) printf("ERROR: %d\n", ret);
+#endif
+ EXIT(ret);
+ return(0);
+ }
+
+static int print_test_data(void)
+ {
+ unsigned int i,j;
+
+ printf("ecb test data\n");
+ printf("key bytes\t\tclear bytes\t\tcipher bytes\n");
+ for (i=0; i<NUM_TESTS; i++)
+ {
+ for (j=0; j<8; j++)
+ printf("%02X",ecb_data[i][j]);
+ printf("\t");
+ for (j=0; j<8; j++)
+ printf("%02X",plain_data[i][j]);
+ printf("\t");
+ for (j=0; j<8; j++)
+ printf("%02X",cipher_data[i][j]);
+ printf("\n");
+ }
+
+ printf("set_key test data\n");
+ printf("data[8]= ");
+ for (j=0; j<8; j++)
+ printf("%02X",key_data[j]);
+ printf("\n");
+ for (i=0; i<KEY_TEST_NUM-1; i++)
+ {
+ printf("c=");
+ for (j=0; j<8; j++)
+ printf("%02X",key_out[i][j]);
+ printf(" k[%2u]=",i+1);
+ for (j=0; j<i+1; j++)
+ printf("%02X",key_test[j]);
+ printf("\n");
+ }
+
+ printf("\nchaining mode test data\n");
+ printf("key[16] = ");
+ for (j=0; j<16; j++)
+ printf("%02X",cbc_key[j]);
+ printf("\niv[8] = ");
+ for (j=0; j<8; j++)
+ printf("%02X",cbc_iv[j]);
+ printf("\ndata[%d] = '%s'",(int)strlen(cbc_data)+1,cbc_data);
+ printf("\ndata[%d] = ",(int)strlen(cbc_data)+1);
+ for (j=0; j<strlen(cbc_data)+1; j++)
+ printf("%02X",cbc_data[j]);
+ printf("\n");
+ printf("cbc cipher text\n");
+ printf("cipher[%d]= ",32);
+ for (j=0; j<32; j++)
+ printf("%02X",cbc_ok[j]);
+ printf("\n");
+
+ printf("cfb64 cipher text\n");
+ printf("cipher[%d]= ",(int)strlen(cbc_data)+1);
+ for (j=0; j<strlen(cbc_data)+1; j++)
+ printf("%02X",cfb64_ok[j]);
+ printf("\n");
+
+ printf("ofb64 cipher text\n");
+ printf("cipher[%d]= ",(int)strlen(cbc_data)+1);
+ for (j=0; j<strlen(cbc_data)+1; j++)
+ printf("%02X",ofb64_ok[j]);
+ printf("\n");
+ return(0);
+ }
+
+static int test(void)
+ {
+ unsigned char cbc_in[40],cbc_out[40],iv[8];
+ int i,n,err=0;
+ BF_KEY key;
+ BF_LONG data[2];
+ unsigned char out[8];
+ BF_LONG len;
+
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(cbc_data, cbc_data, strlen(cbc_data));
+#endif
+
+ printf("testing blowfish in raw ecb mode\n");
+ for (n=0; n<2; n++)
+ {
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(bf_key[n], bf_key[n], strlen(bf_key[n]));
+#endif
+ BF_set_key(&key,strlen(bf_key[n]),(unsigned char *)bf_key[n]);
+
+ data[0]=bf_plain[n][0];
+ data[1]=bf_plain[n][1];
+ BF_encrypt(data,&key);
+ if (memcmp(&(bf_cipher[n][0]),&(data[0]),8) != 0)
+ {
+ printf("BF_encrypt error encrypting\n");
+ printf("got :");
+ for (i=0; i<2; i++)
+ printf("%08lX ",(unsigned long)data[i]);
+ printf("\n");
+ printf("expected:");
+ for (i=0; i<2; i++)
+ printf("%08lX ",(unsigned long)bf_cipher[n][i]);
+ err=1;
+ printf("\n");
+ }
+
+ BF_decrypt(&(data[0]),&key);
+ if (memcmp(&(bf_plain[n][0]),&(data[0]),8) != 0)
+ {
+ printf("BF_encrypt error decrypting\n");
+ printf("got :");
+ for (i=0; i<2; i++)
+ printf("%08lX ",(unsigned long)data[i]);
+ printf("\n");
+ printf("expected:");
+ for (i=0; i<2; i++)
+ printf("%08lX ",(unsigned long)bf_plain[n][i]);
+ printf("\n");
+ err=1;
+ }
+ }
+
+ printf("testing blowfish in ecb mode\n");
+
+ for (n=0; n<NUM_TESTS; n++)
+ {
+ BF_set_key(&key,8,ecb_data[n]);
+
+ BF_ecb_encrypt(&(plain_data[n][0]),out,&key,BF_ENCRYPT);
+ if (memcmp(&(cipher_data[n][0]),out,8) != 0)
+ {
+ printf("BF_ecb_encrypt blowfish error encrypting\n");
+ printf("got :");
+ for (i=0; i<8; i++)
+ printf("%02X ",out[i]);
+ printf("\n");
+ printf("expected:");
+ for (i=0; i<8; i++)
+ printf("%02X ",cipher_data[n][i]);
+ err=1;
+ printf("\n");
+ }
+
+ BF_ecb_encrypt(out,out,&key,BF_DECRYPT);
+ if (memcmp(&(plain_data[n][0]),out,8) != 0)
+ {
+ printf("BF_ecb_encrypt error decrypting\n");
+ printf("got :");
+ for (i=0; i<8; i++)
+ printf("%02X ",out[i]);
+ printf("\n");
+ printf("expected:");
+ for (i=0; i<8; i++)
+ printf("%02X ",plain_data[n][i]);
+ printf("\n");
+ err=1;
+ }
+ }
+
+ printf("testing blowfish set_key\n");
+ for (n=1; n<KEY_TEST_NUM; n++)
+ {
+ BF_set_key(&key,n,key_test);
+ BF_ecb_encrypt(key_data,out,&key,BF_ENCRYPT);
+ /* mips-sgi-irix6.5-gcc vv -mabi=64 bug workaround */
+ if (memcmp(out,&(key_out[i=n-1][0]),8) != 0)
+ {
+ printf("blowfish setkey error\n");
+ err=1;
+ }
+ }
+
+ printf("testing blowfish in cbc mode\n");
+ len=strlen(cbc_data)+1;
+
+ BF_set_key(&key,16,cbc_key);
+ memset(cbc_in,0,sizeof cbc_in);
+ memset(cbc_out,0,sizeof cbc_out);
+ memcpy(iv,cbc_iv,sizeof iv);
+ BF_cbc_encrypt((unsigned char *)cbc_data,cbc_out,len,
+ &key,iv,BF_ENCRYPT);
+ if (memcmp(cbc_out,cbc_ok,32) != 0)
+ {
+ err=1;
+ printf("BF_cbc_encrypt encrypt error\n");
+ for (i=0; i<32; i++) printf("0x%02X,",cbc_out[i]);
+ }
+ memcpy(iv,cbc_iv,8);
+ BF_cbc_encrypt(cbc_out,cbc_in,len,
+ &key,iv,BF_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
+ {
+ printf("BF_cbc_encrypt decrypt error\n");
+ err=1;
+ }
+
+ printf("testing blowfish in cfb64 mode\n");
+
+ BF_set_key(&key,16,cbc_key);
+ memset(cbc_in,0,40);
+ memset(cbc_out,0,40);
+ memcpy(iv,cbc_iv,8);
+ n=0;
+ BF_cfb64_encrypt((unsigned char *)cbc_data,cbc_out,(long)13,
+ &key,iv,&n,BF_ENCRYPT);
+ BF_cfb64_encrypt((unsigned char *)&(cbc_data[13]),&(cbc_out[13]),len-13,
+ &key,iv,&n,BF_ENCRYPT);
+ if (memcmp(cbc_out,cfb64_ok,(int)len) != 0)
+ {
+ err=1;
+ printf("BF_cfb64_encrypt encrypt error\n");
+ for (i=0; i<(int)len; i++) printf("0x%02X,",cbc_out[i]);
+ }
+ n=0;
+ memcpy(iv,cbc_iv,8);
+ BF_cfb64_encrypt(cbc_out,cbc_in,17,
+ &key,iv,&n,BF_DECRYPT);
+ BF_cfb64_encrypt(&(cbc_out[17]),&(cbc_in[17]),len-17,
+ &key,iv,&n,BF_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,(int)len) != 0)
+ {
+ printf("BF_cfb64_encrypt decrypt error\n");
+ err=1;
+ }
+
+ printf("testing blowfish in ofb64\n");
+
+ BF_set_key(&key,16,cbc_key);
+ memset(cbc_in,0,40);
+ memset(cbc_out,0,40);
+ memcpy(iv,cbc_iv,8);
+ n=0;
+ BF_ofb64_encrypt((unsigned char *)cbc_data,cbc_out,(long)13,&key,iv,&n);
+ BF_ofb64_encrypt((unsigned char *)&(cbc_data[13]),
+ &(cbc_out[13]),len-13,&key,iv,&n);
+ if (memcmp(cbc_out,ofb64_ok,(int)len) != 0)
+ {
+ err=1;
+ printf("BF_ofb64_encrypt encrypt error\n");
+ for (i=0; i<(int)len; i++) printf("0x%02X,",cbc_out[i]);
+ }
+ n=0;
+ memcpy(iv,cbc_iv,8);
+ BF_ofb64_encrypt(cbc_out,cbc_in,17,&key,iv,&n);
+ BF_ofb64_encrypt(&(cbc_out[17]),&(cbc_in[17]),len-17,&key,iv,&n);
+ if (memcmp(cbc_in,cbc_data,(int)len) != 0)
+ {
+ printf("BF_ofb64_encrypt decrypt error\n");
+ err=1;
+ }
+
+ return(err);
+ }
+#endif
diff --git a/deps/openssl/openssl/test/bntest.c b/deps/openssl/openssl/test/bntest.c
new file mode 100644
index 000000000..06f5954ac
--- /dev/null
+++ b/deps/openssl/openssl/test/bntest.c
@@ -0,0 +1,2013 @@
+/* crypto/bn/bntest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the Eric Young open source
+ * license provided above.
+ *
+ * The binary polynomial arithmetic software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "e_os.h"
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+const int num0 = 100; /* number of tests */
+const int num1 = 50; /* additional tests for some functions */
+const int num2 = 5; /* number of tests for slow functions */
+
+int test_add(BIO *bp);
+int test_sub(BIO *bp);
+int test_lshift1(BIO *bp);
+int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
+int test_rshift1(BIO *bp);
+int test_rshift(BIO *bp,BN_CTX *ctx);
+int test_div(BIO *bp,BN_CTX *ctx);
+int test_div_word(BIO *bp);
+int test_div_recp(BIO *bp,BN_CTX *ctx);
+int test_mul(BIO *bp);
+int test_sqr(BIO *bp,BN_CTX *ctx);
+int test_mont(BIO *bp,BN_CTX *ctx);
+int test_mod(BIO *bp,BN_CTX *ctx);
+int test_mod_mul(BIO *bp,BN_CTX *ctx);
+int test_mod_exp(BIO *bp,BN_CTX *ctx);
+int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx);
+int test_exp(BIO *bp,BN_CTX *ctx);
+int test_gf2m_add(BIO *bp);
+int test_gf2m_mod(BIO *bp);
+int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
+int test_kron(BIO *bp,BN_CTX *ctx);
+int test_sqrt(BIO *bp,BN_CTX *ctx);
+int rand_neg(void);
+static int results=0;
+
+static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
+"\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+static void message(BIO *out, char *m)
+ {
+ fprintf(stderr, "test %s\n", m);
+ BIO_puts(out, "print \"test ");
+ BIO_puts(out, m);
+ BIO_puts(out, "\\n\"\n");
+ }
+
+int main(int argc, char *argv[])
+ {
+ BN_CTX *ctx;
+ BIO *out;
+ char *outfile=NULL;
+
+ results = 0;
+
+ RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
+
+ argc--;
+ argv++;
+ while (argc >= 1)
+ {
+ if (strcmp(*argv,"-results") == 0)
+ results=1;
+ else if (strcmp(*argv,"-out") == 0)
+ {
+ if (--argc < 1) break;
+ outfile= *(++argv);
+ }
+ argc--;
+ argv++;
+ }
+
+
+ ctx=BN_CTX_new();
+ if (ctx == NULL) EXIT(1);
+
+ out=BIO_new(BIO_s_file());
+ if (out == NULL) EXIT(1);
+ if (outfile == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+ }
+ else
+ {
+ if (!BIO_write_filename(out,outfile))
+ {
+ perror(outfile);
+ EXIT(1);
+ }
+ }
+
+ if (!results)
+ BIO_puts(out,"obase=16\nibase=16\n");
+
+ message(out,"BN_add");
+ if (!test_add(out)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_sub");
+ if (!test_sub(out)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_lshift1");
+ if (!test_lshift1(out)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_lshift (fixed)");
+ if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_lshift");
+ if (!test_lshift(out,ctx,NULL)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_rshift1");
+ if (!test_rshift1(out)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_rshift");
+ if (!test_rshift(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_sqr");
+ if (!test_sqr(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_mul");
+ if (!test_mul(out)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_div");
+ if (!test_div(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_div_word");
+ if (!test_div_word(out)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_div_recp");
+ if (!test_div_recp(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_mod");
+ if (!test_mod(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_mod_mul");
+ if (!test_mod_mul(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_mont");
+ if (!test_mont(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_mod_exp");
+ if (!test_mod_exp(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_mod_exp_mont_consttime");
+ if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_exp");
+ if (!test_exp(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_kronecker");
+ if (!test_kron(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_mod_sqrt");
+ if (!test_sqrt(out,ctx)) goto err;
+ (void)BIO_flush(out);
+#ifndef OPENSSL_NO_EC2M
+ message(out,"BN_GF2m_add");
+ if (!test_gf2m_add(out)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_GF2m_mod");
+ if (!test_gf2m_mod(out)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_GF2m_mod_mul");
+ if (!test_gf2m_mod_mul(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_GF2m_mod_sqr");
+ if (!test_gf2m_mod_sqr(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_GF2m_mod_inv");
+ if (!test_gf2m_mod_inv(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_GF2m_mod_div");
+ if (!test_gf2m_mod_div(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_GF2m_mod_exp");
+ if (!test_gf2m_mod_exp(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_GF2m_mod_sqrt");
+ if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
+ (void)BIO_flush(out);
+
+ message(out,"BN_GF2m_mod_solve_quad");
+ if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
+ (void)BIO_flush(out);
+#endif
+ BN_CTX_free(ctx);
+ BIO_free(out);
+
+/**/
+ EXIT(0);
+err:
+ BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
+ * the failure, see test_bn in test/Makefile.ssl*/
+ (void)BIO_flush(out);
+ ERR_load_crypto_strings();
+ ERR_print_errors_fp(stderr);
+ EXIT(1);
+ return(1);
+ }
+
+int test_add(BIO *bp)
+ {
+ BIGNUM a,b,c;
+ int i;
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+
+ BN_bntest_rand(&a,512,0,0);
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(&b,450+i,0,0);
+ a.neg=rand_neg();
+ b.neg=rand_neg();
+ BN_add(&c,&a,&b);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," + ");
+ BN_print(bp,&b);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,&c);
+ BIO_puts(bp,"\n");
+ }
+ a.neg=!a.neg;
+ b.neg=!b.neg;
+ BN_add(&c,&c,&b);
+ BN_add(&c,&c,&a);
+ if(!BN_is_zero(&c))
+ {
+ fprintf(stderr,"Add test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ return(1);
+ }
+
+int test_sub(BIO *bp)
+ {
+ BIGNUM a,b,c;
+ int i;
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+
+ for (i=0; i<num0+num1; i++)
+ {
+ if (i < num1)
+ {
+ BN_bntest_rand(&a,512,0,0);
+ BN_copy(&b,&a);
+ if (BN_set_bit(&a,i)==0) return(0);
+ BN_add_word(&b,i);
+ }
+ else
+ {
+ BN_bntest_rand(&b,400+i-num1,0,0);
+ a.neg=rand_neg();
+ b.neg=rand_neg();
+ }
+ BN_sub(&c,&a,&b);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," - ");
+ BN_print(bp,&b);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,&c);
+ BIO_puts(bp,"\n");
+ }
+ BN_add(&c,&c,&b);
+ BN_sub(&c,&c,&a);
+ if(!BN_is_zero(&c))
+ {
+ fprintf(stderr,"Subtract test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ return(1);
+ }
+
+int test_div(BIO *bp, BN_CTX *ctx)
+ {
+ BIGNUM a,b,c,d,e;
+ int i;
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+ BN_init(&d);
+ BN_init(&e);
+
+ for (i=0; i<num0+num1; i++)
+ {
+ if (i < num1)
+ {
+ BN_bntest_rand(&a,400,0,0);
+ BN_copy(&b,&a);
+ BN_lshift(&a,&a,i);
+ BN_add_word(&a,i);
+ }
+ else
+ BN_bntest_rand(&b,50+3*(i-num1),0,0);
+ a.neg=rand_neg();
+ b.neg=rand_neg();
+ BN_div(&d,&c,&a,&b,ctx);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," / ");
+ BN_print(bp,&b);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,&d);
+ BIO_puts(bp,"\n");
+
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," % ");
+ BN_print(bp,&b);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,&c);
+ BIO_puts(bp,"\n");
+ }
+ BN_mul(&e,&d,&b,ctx);
+ BN_add(&d,&e,&c);
+ BN_sub(&d,&d,&a);
+ if(!BN_is_zero(&d))
+ {
+ fprintf(stderr,"Division test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ BN_free(&d);
+ BN_free(&e);
+ return(1);
+ }
+
+static void print_word(BIO *bp,BN_ULONG w)
+ {
+#ifdef SIXTY_FOUR_BIT
+ if (sizeof(w) > sizeof(unsigned long))
+ {
+ unsigned long h=(unsigned long)(w>>32),
+ l=(unsigned long)(w);
+
+ if (h) BIO_printf(bp,"%lX%08lX",h,l);
+ else BIO_printf(bp,"%lX",l);
+ return;
+ }
+#endif
+ BIO_printf(bp,BN_HEX_FMT1,w);
+ }
+
+int test_div_word(BIO *bp)
+ {
+ BIGNUM a,b;
+ BN_ULONG r,s;
+ int i;
+
+ BN_init(&a);
+ BN_init(&b);
+
+ for (i=0; i<num0; i++)
+ {
+ do {
+ BN_bntest_rand(&a,512,-1,0);
+ BN_bntest_rand(&b,BN_BITS2,-1,0);
+ s = b.d[0];
+ } while (!s);
+
+ BN_copy(&b, &a);
+ r = BN_div_word(&b, s);
+
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," / ");
+ print_word(bp,s);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,&b);
+ BIO_puts(bp,"\n");
+
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," % ");
+ print_word(bp,s);
+ BIO_puts(bp," - ");
+ }
+ print_word(bp,r);
+ BIO_puts(bp,"\n");
+ }
+ BN_mul_word(&b,s);
+ BN_add_word(&b,r);
+ BN_sub(&b,&a,&b);
+ if(!BN_is_zero(&b))
+ {
+ fprintf(stderr,"Division (word) test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ return(1);
+ }
+
+int test_div_recp(BIO *bp, BN_CTX *ctx)
+ {
+ BIGNUM a,b,c,d,e;
+ BN_RECP_CTX recp;
+ int i;
+
+ BN_RECP_CTX_init(&recp);
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+ BN_init(&d);
+ BN_init(&e);
+
+ for (i=0; i<num0+num1; i++)
+ {
+ if (i < num1)
+ {
+ BN_bntest_rand(&a,400,0,0);
+ BN_copy(&b,&a);
+ BN_lshift(&a,&a,i);
+ BN_add_word(&a,i);
+ }
+ else
+ BN_bntest_rand(&b,50+3*(i-num1),0,0);
+ a.neg=rand_neg();
+ b.neg=rand_neg();
+ BN_RECP_CTX_set(&recp,&b,ctx);
+ BN_div_recp(&d,&c,&a,&recp,ctx);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," / ");
+ BN_print(bp,&b);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,&d);
+ BIO_puts(bp,"\n");
+
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," % ");
+ BN_print(bp,&b);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,&c);
+ BIO_puts(bp,"\n");
+ }
+ BN_mul(&e,&d,&b,ctx);
+ BN_add(&d,&e,&c);
+ BN_sub(&d,&d,&a);
+ if(!BN_is_zero(&d))
+ {
+ fprintf(stderr,"Reciprocal division test failed!\n");
+ fprintf(stderr,"a=");
+ BN_print_fp(stderr,&a);
+ fprintf(stderr,"\nb=");
+ BN_print_fp(stderr,&b);
+ fprintf(stderr,"\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ BN_free(&d);
+ BN_free(&e);
+ BN_RECP_CTX_free(&recp);
+ return(1);
+ }
+
+int test_mul(BIO *bp)
+ {
+ BIGNUM a,b,c,d,e;
+ int i;
+ BN_CTX *ctx;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) EXIT(1);
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+ BN_init(&d);
+ BN_init(&e);
+
+ for (i=0; i<num0+num1; i++)
+ {
+ if (i <= num1)
+ {
+ BN_bntest_rand(&a,100,0,0);
+ BN_bntest_rand(&b,100,0,0);
+ }
+ else
+ BN_bntest_rand(&b,i-num1,0,0);
+ a.neg=rand_neg();
+ b.neg=rand_neg();
+ BN_mul(&c,&a,&b,ctx);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," * ");
+ BN_print(bp,&b);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,&c);
+ BIO_puts(bp,"\n");
+ }
+ BN_div(&d,&e,&c,&a,ctx);
+ BN_sub(&d,&d,&b);
+ if(!BN_is_zero(&d) || !BN_is_zero(&e))
+ {
+ fprintf(stderr,"Multiplication test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ BN_free(&d);
+ BN_free(&e);
+ BN_CTX_free(ctx);
+ return(1);
+ }
+
+int test_sqr(BIO *bp, BN_CTX *ctx)
+ {
+ BIGNUM a,c,d,e;
+ int i;
+
+ BN_init(&a);
+ BN_init(&c);
+ BN_init(&d);
+ BN_init(&e);
+
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(&a,40+i*10,0,0);
+ a.neg=rand_neg();
+ BN_sqr(&c,&a,ctx);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," * ");
+ BN_print(bp,&a);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,&c);
+ BIO_puts(bp,"\n");
+ }
+ BN_div(&d,&e,&c,&a,ctx);
+ BN_sub(&d,&d,&a);
+ if(!BN_is_zero(&d) || !BN_is_zero(&e))
+ {
+ fprintf(stderr,"Square test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&c);
+ BN_free(&d);
+ BN_free(&e);
+ return(1);
+ }
+
+int test_mont(BIO *bp, BN_CTX *ctx)
+ {
+ BIGNUM a,b,c,d,A,B;
+ BIGNUM n;
+ int i;
+ BN_MONT_CTX *mont;
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+ BN_init(&d);
+ BN_init(&A);
+ BN_init(&B);
+ BN_init(&n);
+
+ mont=BN_MONT_CTX_new();
+ if (mont == NULL)
+ return 0;
+
+ BN_bntest_rand(&a,100,0,0); /**/
+ BN_bntest_rand(&b,100,0,0); /**/
+ for (i=0; i<num2; i++)
+ {
+ int bits = (200*(i+1))/num2;
+
+ if (bits == 0)
+ continue;
+ BN_bntest_rand(&n,bits,0,1);
+ BN_MONT_CTX_set(mont,&n,ctx);
+
+ BN_nnmod(&a,&a,&n,ctx);
+ BN_nnmod(&b,&b,&n,ctx);
+
+ BN_to_montgomery(&A,&a,mont,ctx);
+ BN_to_montgomery(&B,&b,mont,ctx);
+
+ BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
+ BN_from_montgomery(&A,&c,mont,ctx);/**/
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+#ifdef undef
+fprintf(stderr,"%d * %d %% %d\n",
+BN_num_bits(&a),
+BN_num_bits(&b),
+BN_num_bits(mont->N));
+#endif
+ BN_print(bp,&a);
+ BIO_puts(bp," * ");
+ BN_print(bp,&b);
+ BIO_puts(bp," % ");
+ BN_print(bp,&(mont->N));
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,&A);
+ BIO_puts(bp,"\n");
+ }
+ BN_mod_mul(&d,&a,&b,&n,ctx);
+ BN_sub(&d,&d,&A);
+ if(!BN_is_zero(&d))
+ {
+ fprintf(stderr,"Montgomery multiplication test failed!\n");
+ return 0;
+ }
+ }
+ BN_MONT_CTX_free(mont);
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ BN_free(&d);
+ BN_free(&A);
+ BN_free(&B);
+ BN_free(&n);
+ return(1);
+ }
+
+int test_mod(BIO *bp, BN_CTX *ctx)
+ {
+ BIGNUM *a,*b,*c,*d,*e;
+ int i;
+
+ a=BN_new();
+ b=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+
+ BN_bntest_rand(a,1024,0,0); /**/
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(b,450+i*10,0,0); /**/
+ a->neg=rand_neg();
+ b->neg=rand_neg();
+ BN_mod(c,a,b,ctx);/**/
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," % ");
+ BN_print(bp,b);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,c);
+ BIO_puts(bp,"\n");
+ }
+ BN_div(d,e,a,b,ctx);
+ BN_sub(e,e,c);
+ if(!BN_is_zero(e))
+ {
+ fprintf(stderr,"Modulo test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return(1);
+ }
+
+int test_mod_mul(BIO *bp, BN_CTX *ctx)
+ {
+ BIGNUM *a,*b,*c,*d,*e;
+ int i,j;
+
+ a=BN_new();
+ b=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+
+ for (j=0; j<3; j++) {
+ BN_bntest_rand(c,1024,0,0); /**/
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(a,475+i*10,0,0); /**/
+ BN_bntest_rand(b,425+i*11,0,0); /**/
+ a->neg=rand_neg();
+ b->neg=rand_neg();
+ if (!BN_mod_mul(e,a,b,c,ctx))
+ {
+ unsigned long l;
+
+ while ((l=ERR_get_error()))
+ fprintf(stderr,"ERROR:%s\n",
+ ERR_error_string(l,NULL));
+ EXIT(1);
+ }
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," * ");
+ BN_print(bp,b);
+ BIO_puts(bp," % ");
+ BN_print(bp,c);
+ if ((a->neg ^ b->neg) && !BN_is_zero(e))
+ {
+ /* If (a*b) % c is negative, c must be added
+ * in order to obtain the normalized remainder
+ * (new with OpenSSL 0.9.7, previous versions of
+ * BN_mod_mul could generate negative results)
+ */
+ BIO_puts(bp," + ");
+ BN_print(bp,c);
+ }
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,e);
+ BIO_puts(bp,"\n");
+ }
+ BN_mul(d,a,b,ctx);
+ BN_sub(d,d,e);
+ BN_div(a,b,d,c,ctx);
+ if(!BN_is_zero(b))
+ {
+ fprintf(stderr,"Modulo multiply test failed!\n");
+ ERR_print_errors_fp(stderr);
+ return 0;
+ }
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return(1);
+ }
+
+int test_mod_exp(BIO *bp, BN_CTX *ctx)
+ {
+ BIGNUM *a,*b,*c,*d,*e;
+ int i;
+
+ a=BN_new();
+ b=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+
+ BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
+ for (i=0; i<num2; i++)
+ {
+ BN_bntest_rand(a,20+i*5,0,0); /**/
+ BN_bntest_rand(b,2+i,0,0); /**/
+
+ if (!BN_mod_exp(d,a,b,c,ctx))
+ return(0);
+
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," ^ ");
+ BN_print(bp,b);
+ BIO_puts(bp," % ");
+ BN_print(bp,c);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,d);
+ BIO_puts(bp,"\n");
+ }
+ BN_exp(e,a,b,ctx);
+ BN_sub(e,e,d);
+ BN_div(a,b,e,c,ctx);
+ if(!BN_is_zero(b))
+ {
+ fprintf(stderr,"Modulo exponentiation test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return(1);
+ }
+
+int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
+ {
+ BIGNUM *a,*b,*c,*d,*e;
+ int i;
+
+ a=BN_new();
+ b=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+
+ BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
+ for (i=0; i<num2; i++)
+ {
+ BN_bntest_rand(a,20+i*5,0,0); /**/
+ BN_bntest_rand(b,2+i,0,0); /**/
+
+ if (!BN_mod_exp_mont_consttime(d,a,b,c,ctx,NULL))
+ return(00);
+
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," ^ ");
+ BN_print(bp,b);
+ BIO_puts(bp," % ");
+ BN_print(bp,c);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,d);
+ BIO_puts(bp,"\n");
+ }
+ BN_exp(e,a,b,ctx);
+ BN_sub(e,e,d);
+ BN_div(a,b,e,c,ctx);
+ if(!BN_is_zero(b))
+ {
+ fprintf(stderr,"Modulo exponentiation test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return(1);
+ }
+
+int test_exp(BIO *bp, BN_CTX *ctx)
+ {
+ BIGNUM *a,*b,*d,*e,*one;
+ int i;
+
+ a=BN_new();
+ b=BN_new();
+ d=BN_new();
+ e=BN_new();
+ one=BN_new();
+ BN_one(one);
+
+ for (i=0; i<num2; i++)
+ {
+ BN_bntest_rand(a,20+i*5,0,0); /**/
+ BN_bntest_rand(b,2+i,0,0); /**/
+
+ if (BN_exp(d,a,b,ctx) <= 0)
+ return(0);
+
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," ^ ");
+ BN_print(bp,b);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,d);
+ BIO_puts(bp,"\n");
+ }
+ BN_one(e);
+ for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
+ BN_mul(e,e,a,ctx);
+ BN_sub(e,e,d);
+ if(!BN_is_zero(e))
+ {
+ fprintf(stderr,"Exponentiation test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(d);
+ BN_free(e);
+ BN_free(one);
+ return(1);
+ }
+#ifndef OPENSSL_NO_EC2M
+int test_gf2m_add(BIO *bp)
+ {
+ BIGNUM a,b,c;
+ int i, ret = 0;
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+
+ for (i=0; i<num0; i++)
+ {
+ BN_rand(&a,512,0,0);
+ BN_copy(&b, BN_value_one());
+ a.neg=rand_neg();
+ b.neg=rand_neg();
+ BN_GF2m_add(&c,&a,&b);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,&a);
+ BIO_puts(bp," ^ ");
+ BN_print(bp,&b);
+ BIO_puts(bp," = ");
+ }
+ BN_print(bp,&c);
+ BIO_puts(bp,"\n");
+ }
+#endif
+ /* Test that two added values have the correct parity. */
+ if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
+ {
+ fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
+ goto err;
+ }
+ BN_GF2m_add(&c,&c,&c);
+ /* Test that c + c = 0. */
+ if(!BN_is_zero(&c))
+ {
+ fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
+ goto err;
+ }
+ }
+ ret = 1;
+ err:
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ return ret;
+ }
+
+int test_gf2m_mod(BIO *bp)
+ {
+ BIGNUM *a,*b[2],*c,*d,*e;
+ int i, j, ret = 0;
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
+
+ a=BN_new();
+ b[0]=BN_new();
+ b[1]=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+
+ BN_GF2m_arr2poly(p0, b[0]);
+ BN_GF2m_arr2poly(p1, b[1]);
+
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(a, 1024, 0, 0);
+ for (j=0; j < 2; j++)
+ {
+ BN_GF2m_mod(c, a, b[j]);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," % ");
+ BN_print(bp,b[j]);
+ BIO_puts(bp," - ");
+ BN_print(bp,c);
+ BIO_puts(bp,"\n");
+ }
+ }
+#endif
+ BN_GF2m_add(d, a, c);
+ BN_GF2m_mod(e, d, b[j]);
+ /* Test that a + (a mod p) mod p == 0. */
+ if(!BN_is_zero(e))
+ {
+ fprintf(stderr,"GF(2^m) modulo test failed!\n");
+ goto err;
+ }
+ }
+ }
+ ret = 1;
+ err:
+ BN_free(a);
+ BN_free(b[0]);
+ BN_free(b[1]);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return ret;
+ }
+
+int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
+ {
+ BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
+ int i, j, ret = 0;
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
+
+ a=BN_new();
+ b[0]=BN_new();
+ b[1]=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+ f=BN_new();
+ g=BN_new();
+ h=BN_new();
+
+ BN_GF2m_arr2poly(p0, b[0]);
+ BN_GF2m_arr2poly(p1, b[1]);
+
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(a, 1024, 0, 0);
+ BN_bntest_rand(c, 1024, 0, 0);
+ BN_bntest_rand(d, 1024, 0, 0);
+ for (j=0; j < 2; j++)
+ {
+ BN_GF2m_mod_mul(e, a, c, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," * ");
+ BN_print(bp,c);
+ BIO_puts(bp," % ");
+ BN_print(bp,b[j]);
+ BIO_puts(bp," - ");
+ BN_print(bp,e);
+ BIO_puts(bp,"\n");
+ }
+ }
+#endif
+ BN_GF2m_add(f, a, d);
+ BN_GF2m_mod_mul(g, f, c, b[j], ctx);
+ BN_GF2m_mod_mul(h, d, c, b[j], ctx);
+ BN_GF2m_add(f, e, g);
+ BN_GF2m_add(f, f, h);
+ /* Test that (a+d)*c = a*c + d*c. */
+ if(!BN_is_zero(f))
+ {
+ fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
+ goto err;
+ }
+ }
+ }
+ ret = 1;
+ err:
+ BN_free(a);
+ BN_free(b[0]);
+ BN_free(b[1]);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ BN_free(f);
+ BN_free(g);
+ BN_free(h);
+ return ret;
+ }
+
+int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
+ {
+ BIGNUM *a,*b[2],*c,*d;
+ int i, j, ret = 0;
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
+
+ a=BN_new();
+ b[0]=BN_new();
+ b[1]=BN_new();
+ c=BN_new();
+ d=BN_new();
+
+ BN_GF2m_arr2poly(p0, b[0]);
+ BN_GF2m_arr2poly(p1, b[1]);
+
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(a, 1024, 0, 0);
+ for (j=0; j < 2; j++)
+ {
+ BN_GF2m_mod_sqr(c, a, b[j], ctx);
+ BN_copy(d, a);
+ BN_GF2m_mod_mul(d, a, d, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," ^ 2 % ");
+ BN_print(bp,b[j]);
+ BIO_puts(bp, " = ");
+ BN_print(bp,c);
+ BIO_puts(bp,"; a * a = ");
+ BN_print(bp,d);
+ BIO_puts(bp,"\n");
+ }
+ }
+#endif
+ BN_GF2m_add(d, c, d);
+ /* Test that a*a = a^2. */
+ if(!BN_is_zero(d))
+ {
+ fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
+ goto err;
+ }
+ }
+ }
+ ret = 1;
+ err:
+ BN_free(a);
+ BN_free(b[0]);
+ BN_free(b[1]);
+ BN_free(c);
+ BN_free(d);
+ return ret;
+ }
+
+int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
+ {
+ BIGNUM *a,*b[2],*c,*d;
+ int i, j, ret = 0;
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
+
+ a=BN_new();
+ b[0]=BN_new();
+ b[1]=BN_new();
+ c=BN_new();
+ d=BN_new();
+
+ BN_GF2m_arr2poly(p0, b[0]);
+ BN_GF2m_arr2poly(p1, b[1]);
+
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(a, 512, 0, 0);
+ for (j=0; j < 2; j++)
+ {
+ BN_GF2m_mod_inv(c, a, b[j], ctx);
+ BN_GF2m_mod_mul(d, a, c, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp, " * ");
+ BN_print(bp,c);
+ BIO_puts(bp," - 1 % ");
+ BN_print(bp,b[j]);
+ BIO_puts(bp,"\n");
+ }
+ }
+#endif
+ /* Test that ((1/a)*a) = 1. */
+ if(!BN_is_one(d))
+ {
+ fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
+ goto err;
+ }
+ }
+ }
+ ret = 1;
+ err:
+ BN_free(a);
+ BN_free(b[0]);
+ BN_free(b[1]);
+ BN_free(c);
+ BN_free(d);
+ return ret;
+ }
+
+int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
+ {
+ BIGNUM *a,*b[2],*c,*d,*e,*f;
+ int i, j, ret = 0;
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
+
+ a=BN_new();
+ b[0]=BN_new();
+ b[1]=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+ f=BN_new();
+
+ BN_GF2m_arr2poly(p0, b[0]);
+ BN_GF2m_arr2poly(p1, b[1]);
+
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(a, 512, 0, 0);
+ BN_bntest_rand(c, 512, 0, 0);
+ for (j=0; j < 2; j++)
+ {
+ BN_GF2m_mod_div(d, a, c, b[j], ctx);
+ BN_GF2m_mod_mul(e, d, c, b[j], ctx);
+ BN_GF2m_mod_div(f, a, e, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp, " = ");
+ BN_print(bp,c);
+ BIO_puts(bp," * ");
+ BN_print(bp,d);
+ BIO_puts(bp, " % ");
+ BN_print(bp,b[j]);
+ BIO_puts(bp,"\n");
+ }
+ }
+#endif
+ /* Test that ((a/c)*c)/a = 1. */
+ if(!BN_is_one(f))
+ {
+ fprintf(stderr,"GF(2^m) modular division test failed!\n");
+ goto err;
+ }
+ }
+ }
+ ret = 1;
+ err:
+ BN_free(a);
+ BN_free(b[0]);
+ BN_free(b[1]);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ BN_free(f);
+ return ret;
+ }
+
+int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
+ {
+ BIGNUM *a,*b[2],*c,*d,*e,*f;
+ int i, j, ret = 0;
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
+
+ a=BN_new();
+ b[0]=BN_new();
+ b[1]=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+ f=BN_new();
+
+ BN_GF2m_arr2poly(p0, b[0]);
+ BN_GF2m_arr2poly(p1, b[1]);
+
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(a, 512, 0, 0);
+ BN_bntest_rand(c, 512, 0, 0);
+ BN_bntest_rand(d, 512, 0, 0);
+ for (j=0; j < 2; j++)
+ {
+ BN_GF2m_mod_exp(e, a, c, b[j], ctx);
+ BN_GF2m_mod_exp(f, a, d, b[j], ctx);
+ BN_GF2m_mod_mul(e, e, f, b[j], ctx);
+ BN_add(f, c, d);
+ BN_GF2m_mod_exp(f, a, f, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp, " ^ (");
+ BN_print(bp,c);
+ BIO_puts(bp," + ");
+ BN_print(bp,d);
+ BIO_puts(bp, ") = ");
+ BN_print(bp,e);
+ BIO_puts(bp, "; - ");
+ BN_print(bp,f);
+ BIO_puts(bp, " % ");
+ BN_print(bp,b[j]);
+ BIO_puts(bp,"\n");
+ }
+ }
+#endif
+ BN_GF2m_add(f, e, f);
+ /* Test that a^(c+d)=a^c*a^d. */
+ if(!BN_is_zero(f))
+ {
+ fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
+ goto err;
+ }
+ }
+ }
+ ret = 1;
+ err:
+ BN_free(a);
+ BN_free(b[0]);
+ BN_free(b[1]);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ BN_free(f);
+ return ret;
+ }
+
+int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
+ {
+ BIGNUM *a,*b[2],*c,*d,*e,*f;
+ int i, j, ret = 0;
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
+
+ a=BN_new();
+ b[0]=BN_new();
+ b[1]=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+ f=BN_new();
+
+ BN_GF2m_arr2poly(p0, b[0]);
+ BN_GF2m_arr2poly(p1, b[1]);
+
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(a, 512, 0, 0);
+ for (j=0; j < 2; j++)
+ {
+ BN_GF2m_mod(c, a, b[j]);
+ BN_GF2m_mod_sqrt(d, a, b[j], ctx);
+ BN_GF2m_mod_sqr(e, d, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,d);
+ BIO_puts(bp, " ^ 2 - ");
+ BN_print(bp,a);
+ BIO_puts(bp,"\n");
+ }
+ }
+#endif
+ BN_GF2m_add(f, c, e);
+ /* Test that d^2 = a, where d = sqrt(a). */
+ if(!BN_is_zero(f))
+ {
+ fprintf(stderr,"GF(2^m) modular square root test failed!\n");
+ goto err;
+ }
+ }
+ }
+ ret = 1;
+ err:
+ BN_free(a);
+ BN_free(b[0]);
+ BN_free(b[1]);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ BN_free(f);
+ return ret;
+ }
+
+int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
+ {
+ BIGNUM *a,*b[2],*c,*d,*e;
+ int i, j, s = 0, t, ret = 0;
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
+
+ a=BN_new();
+ b[0]=BN_new();
+ b[1]=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+
+ BN_GF2m_arr2poly(p0, b[0]);
+ BN_GF2m_arr2poly(p1, b[1]);
+
+ for (i=0; i<num0; i++)
+ {
+ BN_bntest_rand(a, 512, 0, 0);
+ for (j=0; j < 2; j++)
+ {
+ t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
+ if (t)
+ {
+ s++;
+ BN_GF2m_mod_sqr(d, c, b[j], ctx);
+ BN_GF2m_add(d, c, d);
+ BN_GF2m_mod(e, a, b[j]);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,c);
+ BIO_puts(bp, " is root of z^2 + z = ");
+ BN_print(bp,a);
+ BIO_puts(bp, " % ");
+ BN_print(bp,b[j]);
+ BIO_puts(bp, "\n");
+ }
+ }
+#endif
+ BN_GF2m_add(e, e, d);
+ /* Test that solution of quadratic c satisfies c^2 + c = a. */
+ if(!BN_is_zero(e))
+ {
+ fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
+ goto err;
+ }
+
+ }
+ else
+ {
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BIO_puts(bp, "There are no roots of z^2 + z = ");
+ BN_print(bp,a);
+ BIO_puts(bp, " % ");
+ BN_print(bp,b[j]);
+ BIO_puts(bp, "\n");
+ }
+ }
+#endif
+ }
+ }
+ }
+ if (s == 0)
+ {
+ fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
+ fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
+ goto err;
+ }
+ ret = 1;
+ err:
+ BN_free(a);
+ BN_free(b[0]);
+ BN_free(b[1]);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return ret;
+ }
+#endif
+static int genprime_cb(int p, int n, BN_GENCB *arg)
+ {
+ char c='*';
+
+ if (p == 0) c='.';
+ if (p == 1) c='+';
+ if (p == 2) c='*';
+ if (p == 3) c='\n';
+ putc(c, stderr);
+ fflush(stderr);
+ return 1;
+ }
+
+int test_kron(BIO *bp, BN_CTX *ctx)
+ {
+ BN_GENCB cb;
+ BIGNUM *a,*b,*r,*t;
+ int i;
+ int legendre, kronecker;
+ int ret = 0;
+
+ a = BN_new();
+ b = BN_new();
+ r = BN_new();
+ t = BN_new();
+ if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
+
+ BN_GENCB_set(&cb, genprime_cb, NULL);
+
+ /* We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol).
+ * In this case we know that if b is prime, then BN_kronecker(a, b, ctx)
+ * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
+ * So we generate a random prime b and compare these values
+ * for a number of random a's. (That is, we run the Solovay-Strassen
+ * primality test to confirm that b is prime, except that we
+ * don't want to test whether b is prime but whether BN_kronecker
+ * works.) */
+
+ if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb)) goto err;
+ b->neg = rand_neg();
+ putc('\n', stderr);
+
+ for (i = 0; i < num0; i++)
+ {
+ if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
+ a->neg = rand_neg();
+
+ /* t := (|b|-1)/2 (note that b is odd) */
+ if (!BN_copy(t, b)) goto err;
+ t->neg = 0;
+ if (!BN_sub_word(t, 1)) goto err;
+ if (!BN_rshift1(t, t)) goto err;
+ /* r := a^t mod b */
+ b->neg=0;
+
+ if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
+ b->neg=1;
+
+ if (BN_is_word(r, 1))
+ legendre = 1;
+ else if (BN_is_zero(r))
+ legendre = 0;
+ else
+ {
+ if (!BN_add_word(r, 1)) goto err;
+ if (0 != BN_ucmp(r, b))
+ {
+ fprintf(stderr, "Legendre symbol computation failed\n");
+ goto err;
+ }
+ legendre = -1;
+ }
+
+ kronecker = BN_kronecker(a, b, ctx);
+ if (kronecker < -1) goto err;
+ /* we actually need BN_kronecker(a, |b|) */
+ if (a->neg && b->neg)
+ kronecker = -kronecker;
+
+ if (legendre != kronecker)
+ {
+ fprintf(stderr, "legendre != kronecker; a = ");
+ BN_print_fp(stderr, a);
+ fprintf(stderr, ", b = ");
+ BN_print_fp(stderr, b);
+ fprintf(stderr, "\n");
+ goto err;
+ }
+
+ putc('.', stderr);
+ fflush(stderr);
+ }
+
+ putc('\n', stderr);
+ fflush(stderr);
+ ret = 1;
+ err:
+ if (a != NULL) BN_free(a);
+ if (b != NULL) BN_free(b);
+ if (r != NULL) BN_free(r);
+ if (t != NULL) BN_free(t);
+ return ret;
+ }
+
+int test_sqrt(BIO *bp, BN_CTX *ctx)
+ {
+ BN_GENCB cb;
+ BIGNUM *a,*p,*r;
+ int i, j;
+ int ret = 0;
+
+ a = BN_new();
+ p = BN_new();
+ r = BN_new();
+ if (a == NULL || p == NULL || r == NULL) goto err;
+
+ BN_GENCB_set(&cb, genprime_cb, NULL);
+
+ for (i = 0; i < 16; i++)
+ {
+ if (i < 8)
+ {
+ unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
+
+ if (!BN_set_word(p, primes[i])) goto err;
+ }
+ else
+ {
+ if (!BN_set_word(a, 32)) goto err;
+ if (!BN_set_word(r, 2*i + 1)) goto err;
+
+ if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) goto err;
+ putc('\n', stderr);
+ }
+ p->neg = rand_neg();
+
+ for (j = 0; j < num2; j++)
+ {
+ /* construct 'a' such that it is a square modulo p,
+ * but in general not a proper square and not reduced modulo p */
+ if (!BN_bntest_rand(r, 256, 0, 3)) goto err;
+ if (!BN_nnmod(r, r, p, ctx)) goto err;
+ if (!BN_mod_sqr(r, r, p, ctx)) goto err;
+ if (!BN_bntest_rand(a, 256, 0, 3)) goto err;
+ if (!BN_nnmod(a, a, p, ctx)) goto err;
+ if (!BN_mod_sqr(a, a, p, ctx)) goto err;
+ if (!BN_mul(a, a, r, ctx)) goto err;
+ if (rand_neg())
+ if (!BN_sub(a, a, p)) goto err;
+
+ if (!BN_mod_sqrt(r, a, p, ctx)) goto err;
+ if (!BN_mod_sqr(r, r, p, ctx)) goto err;
+
+ if (!BN_nnmod(a, a, p, ctx)) goto err;
+
+ if (BN_cmp(a, r) != 0)
+ {
+ fprintf(stderr, "BN_mod_sqrt failed: a = ");
+ BN_print_fp(stderr, a);
+ fprintf(stderr, ", r = ");
+ BN_print_fp(stderr, r);
+ fprintf(stderr, ", p = ");
+ BN_print_fp(stderr, p);
+ fprintf(stderr, "\n");
+ goto err;
+ }
+
+ putc('.', stderr);
+ fflush(stderr);
+ }
+
+ putc('\n', stderr);
+ fflush(stderr);
+ }
+ ret = 1;
+ err:
+ if (a != NULL) BN_free(a);
+ if (p != NULL) BN_free(p);
+ if (r != NULL) BN_free(r);
+ return ret;
+ }
+
+int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
+ {
+ BIGNUM *a,*b,*c,*d;
+ int i;
+
+ b=BN_new();
+ c=BN_new();
+ d=BN_new();
+ BN_one(c);
+
+ if(a_)
+ a=a_;
+ else
+ {
+ a=BN_new();
+ BN_bntest_rand(a,200,0,0); /**/
+ a->neg=rand_neg();
+ }
+ for (i=0; i<num0; i++)
+ {
+ BN_lshift(b,a,i+1);
+ BN_add(c,c,c);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," * ");
+ BN_print(bp,c);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,b);
+ BIO_puts(bp,"\n");
+ }
+ BN_mul(d,a,c,ctx);
+ BN_sub(d,d,b);
+ if(!BN_is_zero(d))
+ {
+ fprintf(stderr,"Left shift test failed!\n");
+ fprintf(stderr,"a=");
+ BN_print_fp(stderr,a);
+ fprintf(stderr,"\nb=");
+ BN_print_fp(stderr,b);
+ fprintf(stderr,"\nc=");
+ BN_print_fp(stderr,c);
+ fprintf(stderr,"\nd=");
+ BN_print_fp(stderr,d);
+ fprintf(stderr,"\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ return(1);
+ }
+
+int test_lshift1(BIO *bp)
+ {
+ BIGNUM *a,*b,*c;
+ int i;
+
+ a=BN_new();
+ b=BN_new();
+ c=BN_new();
+
+ BN_bntest_rand(a,200,0,0); /**/
+ a->neg=rand_neg();
+ for (i=0; i<num0; i++)
+ {
+ BN_lshift1(b,a);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," * 2");
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,b);
+ BIO_puts(bp,"\n");
+ }
+ BN_add(c,a,a);
+ BN_sub(a,b,c);
+ if(!BN_is_zero(a))
+ {
+ fprintf(stderr,"Left shift one test failed!\n");
+ return 0;
+ }
+
+ BN_copy(a,b);
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ return(1);
+ }
+
+int test_rshift(BIO *bp,BN_CTX *ctx)
+ {
+ BIGNUM *a,*b,*c,*d,*e;
+ int i;
+
+ a=BN_new();
+ b=BN_new();
+ c=BN_new();
+ d=BN_new();
+ e=BN_new();
+ BN_one(c);
+
+ BN_bntest_rand(a,200,0,0); /**/
+ a->neg=rand_neg();
+ for (i=0; i<num0; i++)
+ {
+ BN_rshift(b,a,i+1);
+ BN_add(c,c,c);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," / ");
+ BN_print(bp,c);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,b);
+ BIO_puts(bp,"\n");
+ }
+ BN_div(d,e,a,c,ctx);
+ BN_sub(d,d,b);
+ if(!BN_is_zero(d))
+ {
+ fprintf(stderr,"Right shift test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return(1);
+ }
+
+int test_rshift1(BIO *bp)
+ {
+ BIGNUM *a,*b,*c;
+ int i;
+
+ a=BN_new();
+ b=BN_new();
+ c=BN_new();
+
+ BN_bntest_rand(a,200,0,0); /**/
+ a->neg=rand_neg();
+ for (i=0; i<num0; i++)
+ {
+ BN_rshift1(b,a);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," / 2");
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,b);
+ BIO_puts(bp,"\n");
+ }
+ BN_sub(c,a,b);
+ BN_sub(c,c,b);
+ if(!BN_is_zero(c) && !BN_abs_is_word(c, 1))
+ {
+ fprintf(stderr,"Right shift one test failed!\n");
+ return 0;
+ }
+ BN_copy(a,b);
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ return(1);
+ }
+
+int rand_neg(void)
+ {
+ static unsigned int neg=0;
+ static int sign[8]={0,0,0,1,1,0,1,1};
+
+ return(sign[(neg++)%8]);
+ }
diff --git a/deps/openssl/openssl/test/bntest.com b/deps/openssl/openssl/test/bntest.com
new file mode 100644
index 000000000..6545d2e5a
--- /dev/null
+++ b/deps/openssl/openssl/test/bntest.com
@@ -0,0 +1,76 @@
+$!
+$! Analyze bntest output file.
+$!
+$! Exit status = 1 (success) if all tests passed,
+$! 0 (warning) if any test failed.
+$!
+$! 2011-02-20 SMS. Added code to skip "#" comments in the input file.
+$!
+$! 2010-04-05 SMS. New. Based (loosely) on perl code in bntest-vms.sh.
+$!
+$! Expect data like:
+$! test test_name1
+$! 0
+$! [...]
+$! test test_name2
+$! 0
+$! [...]
+$! [...]
+$!
+$! Some tests have no following "0" lines.
+$!
+$ result_file_name = f$edit( p1, "TRIM")
+$ if (result_file_name .eqs. "")
+$ then
+$ result_file_name = "bntest-vms.out"
+$ endif
+$!
+$ fail = 0
+$ passed = 0
+$ tests = 0
+$!
+$ on control_c then goto tidy
+$ on error then goto tidy
+$!
+$ open /read result_file 'result_file_name'
+$!
+$ read_loop:
+$ read /end = read_loop_end /error = tidy result_file line
+$ t1 = f$element( 0, " ", line)
+$!
+$! Skip "#" comment lines.
+$ if (f$extract( 0, 1, f$edit( line, "TRIM")) .eqs. "#") then -
+ goto read_loop
+$!
+$ if (t1 .eqs. "test")
+$ then
+$ passed = passed+ 1
+$ tests = tests+ 1
+$ fail = 1
+$ t2 = f$extract( 5, 1000, line)
+$ write sys$output "verify ''t2'"
+$ else
+$ if (t1 .nes. "0")
+$ then
+$ write sys$output "Failed! bc: ''line'"
+$ passed = passed- fail
+$ fail = 0
+$ endif
+$ endif
+$ goto read_loop
+$ read_loop_end:
+$ write sys$output "''passed'/''tests' tests passed"
+$!
+$ tidy:
+$ if f$trnlnm( "result_file", "LNM$PROCESS_TABLE", , "SUPERVISOR", , "CONFINE")
+$ then
+$ close result_file
+$ endif
+$!
+$ if ((tests .gt. 0) .and. (tests .eq. passed))
+$ then
+$ exit 1
+$ else
+$ exit 0
+$ endif
+$!
diff --git a/deps/openssl/openssl/test/casttest.c b/deps/openssl/openssl/test/casttest.c
new file mode 100644
index 000000000..0d020d697
--- /dev/null
+++ b/deps/openssl/openssl/test/casttest.c
@@ -0,0 +1,233 @@
+/* crypto/cast/casttest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_CAST is defined */
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_CAST
+int main(int argc, char *argv[])
+{
+ printf("No CAST support\n");
+ return(0);
+}
+#else
+#include <openssl/cast.h>
+
+#define FULL_TEST
+
+static unsigned char k[16]={
+ 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
+ 0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A
+ };
+
+static unsigned char in[8]={ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
+
+static int k_len[3]={16,10,5};
+static unsigned char c[3][8]={
+ {0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2},
+ {0xEB,0x6A,0x71,0x1A,0x2C,0x02,0x27,0x1B},
+ {0x7A,0xC8,0x16,0xD1,0x6E,0x9B,0x30,0x2E},
+ };
+static unsigned char out[80];
+
+static unsigned char in_a[16]={
+ 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
+ 0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};
+static unsigned char in_b[16]={
+ 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
+ 0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};
+
+static unsigned char c_a[16]={
+ 0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
+ 0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92};
+static unsigned char c_b[16]={
+ 0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
+ 0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E};
+
+#if 0
+char *text="Hello to all people out there";
+
+static unsigned char cfb_key[16]={
+ 0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
+ 0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
+ };
+static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+#define CFB_TEST_SIZE 24
+static unsigned char plain[CFB_TEST_SIZE]=
+ {
+ 0x4e,0x6f,0x77,0x20,0x69,0x73,
+ 0x20,0x74,0x68,0x65,0x20,0x74,
+ 0x69,0x6d,0x65,0x20,0x66,0x6f,
+ 0x72,0x20,0x61,0x6c,0x6c,0x20
+ };
+static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
+ 0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
+ 0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
+ 0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
+
+/* 0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
+ 0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
+ 0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
+ };
+#endif
+
+int main(int argc, char *argv[])
+ {
+#ifdef FULL_TEST
+ long l;
+ CAST_KEY key_b;
+#endif
+ int i,z,err=0;
+ CAST_KEY key;
+
+ for (z=0; z<3; z++)
+ {
+ CAST_set_key(&key,k_len[z],k);
+
+ CAST_ecb_encrypt(in,out,&key,CAST_ENCRYPT);
+ if (memcmp(out,&(c[z][0]),8) != 0)
+ {
+ printf("ecb cast error encrypting for keysize %d\n",k_len[z]*8);
+ printf("got :");
+ for (i=0; i<8; i++)
+ printf("%02X ",out[i]);
+ printf("\n");
+ printf("expected:");
+ for (i=0; i<8; i++)
+ printf("%02X ",c[z][i]);
+ err=20;
+ printf("\n");
+ }
+
+ CAST_ecb_encrypt(out,out,&key,CAST_DECRYPT);
+ if (memcmp(out,in,8) != 0)
+ {
+ printf("ecb cast error decrypting for keysize %d\n",k_len[z]*8);
+ printf("got :");
+ for (i=0; i<8; i++)
+ printf("%02X ",out[i]);
+ printf("\n");
+ printf("expected:");
+ for (i=0; i<8; i++)
+ printf("%02X ",in[i]);
+ printf("\n");
+ err=3;
+ }
+ }
+ if (err == 0)
+ printf("ecb cast5 ok\n");
+
+#ifdef FULL_TEST
+ {
+ unsigned char out_a[16],out_b[16];
+ static char *hex="0123456789ABCDEF";
+
+ printf("This test will take some time....");
+ fflush(stdout);
+ memcpy(out_a,in_a,sizeof(in_a));
+ memcpy(out_b,in_b,sizeof(in_b));
+ i=1;
+
+ for (l=0; l<1000000L; l++)
+ {
+ CAST_set_key(&key_b,16,out_b);
+ CAST_ecb_encrypt(&(out_a[0]),&(out_a[0]),&key_b,CAST_ENCRYPT);
+ CAST_ecb_encrypt(&(out_a[8]),&(out_a[8]),&key_b,CAST_ENCRYPT);
+ CAST_set_key(&key,16,out_a);
+ CAST_ecb_encrypt(&(out_b[0]),&(out_b[0]),&key,CAST_ENCRYPT);
+ CAST_ecb_encrypt(&(out_b[8]),&(out_b[8]),&key,CAST_ENCRYPT);
+ if ((l & 0xffff) == 0xffff)
+ {
+ printf("%c",hex[i&0x0f]);
+ fflush(stdout);
+ i++;
+ }
+ }
+
+ if ( (memcmp(out_a,c_a,sizeof(c_a)) != 0) ||
+ (memcmp(out_b,c_b,sizeof(c_b)) != 0))
+ {
+ printf("\n");
+ printf("Error\n");
+
+ printf("A out =");
+ for (i=0; i<16; i++) printf("%02X ",out_a[i]);
+ printf("\nactual=");
+ for (i=0; i<16; i++) printf("%02X ",c_a[i]);
+ printf("\n");
+
+ printf("B out =");
+ for (i=0; i<16; i++) printf("%02X ",out_b[i]);
+ printf("\nactual=");
+ for (i=0; i<16; i++) printf("%02X ",c_b[i]);
+ printf("\n");
+ }
+ else
+ printf(" ok\n");
+ }
+#endif
+
+ EXIT(err);
+ return(err);
+ }
+#endif
diff --git a/deps/openssl/openssl/test/clean_test.com b/deps/openssl/openssl/test/clean_test.com
new file mode 100755
index 000000000..7df633fbe
--- /dev/null
+++ b/deps/openssl/openssl/test/clean_test.com
@@ -0,0 +1,35 @@
+$!
+$! Delete various test results files.
+$!
+$ def_orig = f$environment( "default")
+$ proc = f$environment( "procedure")
+$ proc_dev_dir = f$parse( "A.;", proc) - "A.;"
+$!
+$ on control_c then goto tidy
+$ on error then goto tidy
+$!
+$ set default 'proc_dev_dir'
+$!
+$ files := *.cms;*, *.srl;*, *.ss;*, -
+ cms.err;*, cms.out;*, newreq.pem;*, -
+ p.txt-zlib-cipher;*, -
+ smtst.txt;*, testkey.pem;*, testreq.pem;*, -
+ test_*.err;*, test_*.out;*, -
+ .rnd;*
+$!
+$ delim = ","
+$ i = 0
+$ loop:
+$ file = f$edit( f$element( i, delim, files), "trim")
+$ if (file .eqs. delim) then goto loop_end
+$ if (f$search( file) .nes. "") then -
+ delete 'p1' 'file'
+$ i = i+ 1
+$ goto loop
+$ loop_end:
+$!
+$ tidy:
+$
+$ if (f$type( def_orig) .nes. "") then -
+ set default 'def_orig'
+$!
diff --git a/deps/openssl/openssl/test/cms-examples.pl b/deps/openssl/openssl/test/cms-examples.pl
new file mode 100644
index 000000000..2e95b48ba
--- /dev/null
+++ b/deps/openssl/openssl/test/cms-examples.pl
@@ -0,0 +1,409 @@
+# test/cms-examples.pl
+# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+# project.
+#
+# ====================================================================
+# Copyright (c) 2008 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
+# licensing@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.
+# ====================================================================
+
+# Perl script to run tests against S/MIME examples in RFC4134
+# Assumes RFC is in current directory and called "rfc4134.txt"
+
+use MIME::Base64;
+
+my $badttest = 0;
+my $verbose = 1;
+
+my $cmscmd;
+my $exdir = "./";
+my $exfile = "./rfc4134.txt";
+
+if (-f "../apps/openssl")
+ {
+ $cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms";
+ }
+elsif (-f "..\\out32dll\\openssl.exe")
+ {
+ $cmscmd = "..\\out32dll\\openssl.exe cms";
+ }
+elsif (-f "..\\out32\\openssl.exe")
+ {
+ $cmscmd = "..\\out32\\openssl.exe cms";
+ }
+
+my @test_list = (
+ [ "3.1.bin" => "dataout" ],
+ [ "3.2.bin" => "encode, dataout" ],
+ [ "4.1.bin" => "encode, verifyder, cont, dss" ],
+ [ "4.2.bin" => "encode, verifyder, cont, rsa" ],
+ [ "4.3.bin" => "encode, verifyder, cont_extern, dss" ],
+ [ "4.4.bin" => "encode, verifyder, cont, dss" ],
+ [ "4.5.bin" => "verifyder, cont, rsa" ],
+ [ "4.6.bin" => "encode, verifyder, cont, dss" ],
+ [ "4.7.bin" => "encode, verifyder, cont, dss" ],
+ [ "4.8.eml" => "verifymime, dss" ],
+ [ "4.9.eml" => "verifymime, dss" ],
+ [ "4.10.bin" => "encode, verifyder, cont, dss" ],
+ [ "4.11.bin" => "encode, certsout" ],
+ [ "5.1.bin" => "encode, envelopeder, cont" ],
+ [ "5.2.bin" => "encode, envelopeder, cont" ],
+ [ "5.3.eml" => "envelopemime, cont" ],
+ [ "6.0.bin" => "encode, digest, cont" ],
+ [ "7.1.bin" => "encode, encrypted, cont" ],
+ [ "7.2.bin" => "encode, encrypted, cont" ]
+);
+
+# Extract examples from RFC4134 text.
+# Base64 decode all examples, certificates and
+# private keys are converted to PEM format.
+
+my ( $filename, $data );
+
+my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" );
+
+$data = "";
+
+open( IN, $exfile ) || die "Can't Open RFC examples file $exfile";
+
+while (<IN>) {
+ next unless (/^\|/);
+ s/^\|//;
+ next if (/^\*/);
+ if (/^>(.*)$/) {
+ $filename = $1;
+ next;
+ }
+ if (/^</) {
+ $filename = "$exdir/$filename";
+ if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) {
+ $data = decode_base64($data);
+ open OUT, ">$filename";
+ binmode OUT;
+ print OUT $data;
+ close OUT;
+ push @cleanup, $filename;
+ }
+ elsif ( $filename =~ /\.cer$/ ) {
+ write_pem( $filename, "CERTIFICATE", $data );
+ }
+ elsif ( $filename =~ /\.pri$/ ) {
+ write_pem( $filename, "PRIVATE KEY", $data );
+ }
+ $data = "";
+ $filename = "";
+ }
+ else {
+ $data .= $_;
+ }
+
+}
+
+my $secretkey =
+ "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32";
+
+foreach (@test_list) {
+ my ( $file, $tlist ) = @$_;
+ print "Example file $file:\n";
+ if ( $tlist =~ /encode/ ) {
+ run_reencode_test( $exdir, $file );
+ }
+ if ( $tlist =~ /certsout/ ) {
+ run_certsout_test( $exdir, $file );
+ }
+ if ( $tlist =~ /dataout/ ) {
+ run_dataout_test( $exdir, $file );
+ }
+ if ( $tlist =~ /verify/ ) {
+ run_verify_test( $exdir, $tlist, $file );
+ }
+ if ( $tlist =~ /digest/ ) {
+ run_digest_test( $exdir, $tlist, $file );
+ }
+ if ( $tlist =~ /encrypted/ ) {
+ run_encrypted_test( $exdir, $tlist, $file, $secretkey );
+ }
+ if ( $tlist =~ /envelope/ ) {
+ run_envelope_test( $exdir, $tlist, $file );
+ }
+
+}
+
+foreach (@cleanup) {
+ unlink $_;
+}
+
+if ($badtest) {
+ print "\n$badtest TESTS FAILED!!\n";
+}
+else {
+ print "\n***All tests successful***\n";
+}
+
+sub write_pem {
+ my ( $filename, $str, $data ) = @_;
+
+ $filename =~ s/\.[^.]*$/.pem/;
+
+ push @cleanup, $filename;
+
+ open OUT, ">$filename";
+
+ print OUT "-----BEGIN $str-----\n";
+ print OUT $data;
+ print OUT "-----END $str-----\n";
+
+ close OUT;
+}
+
+sub run_reencode_test {
+ my ( $cmsdir, $tfile ) = @_;
+ unlink "tmp.der";
+
+ system( "$cmscmd -cmsout -inform DER -outform DER"
+ . " -in $cmsdir/$tfile -out tmp.der" );
+
+ if ($?) {
+ print "\tReencode command FAILED!!\n";
+ $badtest++;
+ }
+ elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) {
+ print "\tReencode FAILED!!\n";
+ $badtest++;
+ }
+ else {
+ print "\tReencode passed\n" if $verbose;
+ }
+}
+
+sub run_certsout_test {
+ my ( $cmsdir, $tfile ) = @_;
+ unlink "tmp.der";
+ unlink "tmp.pem";
+
+ system( "$cmscmd -cmsout -inform DER -certsout tmp.pem"
+ . " -in $cmsdir/$tfile -out tmp.der" );
+
+ if ($?) {
+ print "\tCertificate output command FAILED!!\n";
+ $badtest++;
+ }
+ else {
+ print "\tCertificate output passed\n" if $verbose;
+ }
+}
+
+sub run_dataout_test {
+ my ( $cmsdir, $tfile ) = @_;
+ unlink "tmp.txt";
+
+ system(
+ "$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" );
+
+ if ($?) {
+ print "\tDataout command FAILED!!\n";
+ $badtest++;
+ }
+ elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) {
+ print "\tDataout compare FAILED!!\n";
+ $badtest++;
+ }
+ else {
+ print "\tDataout passed\n" if $verbose;
+ }
+}
+
+sub run_verify_test {
+ my ( $cmsdir, $tlist, $tfile ) = @_;
+ unlink "tmp.txt";
+
+ $form = "DER" if $tlist =~ /verifyder/;
+ $form = "SMIME" if $tlist =~ /verifymime/;
+ $cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/;
+ $cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/;
+
+ $cmd =
+ "$cmscmd -verify -inform $form"
+ . " -CAfile $cafile"
+ . " -in $cmsdir/$tfile -out tmp.txt";
+
+ $cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/;
+
+ system("$cmd 2>cms.err 1>cms.out");
+
+ if ($?) {
+ print "\tVerify command FAILED!!\n";
+ $badtest++;
+ }
+ elsif ( $tlist =~ /cont/
+ && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
+ {
+ print "\tVerify content compare FAILED!!\n";
+ $badtest++;
+ }
+ else {
+ print "\tVerify passed\n" if $verbose;
+ }
+}
+
+sub run_envelope_test {
+ my ( $cmsdir, $tlist, $tfile ) = @_;
+ unlink "tmp.txt";
+
+ $form = "DER" if $tlist =~ /envelopeder/;
+ $form = "SMIME" if $tlist =~ /envelopemime/;
+
+ $cmd =
+ "$cmscmd -decrypt -inform $form"
+ . " -recip $cmsdir/BobRSASignByCarl.pem"
+ . " -inkey $cmsdir/BobPrivRSAEncrypt.pem"
+ . " -in $cmsdir/$tfile -out tmp.txt";
+
+ system("$cmd 2>cms.err 1>cms.out");
+
+ if ($?) {
+ print "\tDecrypt command FAILED!!\n";
+ $badtest++;
+ }
+ elsif ( $tlist =~ /cont/
+ && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
+ {
+ print "\tDecrypt content compare FAILED!!\n";
+ $badtest++;
+ }
+ else {
+ print "\tDecrypt passed\n" if $verbose;
+ }
+}
+
+sub run_digest_test {
+ my ( $cmsdir, $tlist, $tfile ) = @_;
+ unlink "tmp.txt";
+
+ my $cmd =
+ "$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt";
+
+ system("$cmd 2>cms.err 1>cms.out");
+
+ if ($?) {
+ print "\tDigest verify command FAILED!!\n";
+ $badtest++;
+ }
+ elsif ( $tlist =~ /cont/
+ && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
+ {
+ print "\tDigest verify content compare FAILED!!\n";
+ $badtest++;
+ }
+ else {
+ print "\tDigest verify passed\n" if $verbose;
+ }
+}
+
+sub run_encrypted_test {
+ my ( $cmsdir, $tlist, $tfile, $key ) = @_;
+ unlink "tmp.txt";
+
+ system( "$cmscmd -EncryptedData_decrypt -inform DER"
+ . " -secretkey $key"
+ . " -in $cmsdir/$tfile -out tmp.txt" );
+
+ if ($?) {
+ print "\tEncrypted Data command FAILED!!\n";
+ $badtest++;
+ }
+ elsif ( $tlist =~ /cont/
+ && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
+ {
+ print "\tEncrypted Data content compare FAILED!!\n";
+ $badtest++;
+ }
+ else {
+ print "\tEncryptedData verify passed\n" if $verbose;
+ }
+}
+
+sub cmp_files {
+ my ( $f1, $f2 ) = @_;
+ my ( $fp1, $fp2 );
+
+ my ( $rd1, $rd2 );
+
+ if ( !open( $fp1, "<$f1" ) ) {
+ print STDERR "Can't Open file $f1\n";
+ return 0;
+ }
+
+ if ( !open( $fp2, "<$f2" ) ) {
+ print STDERR "Can't Open file $f2\n";
+ return 0;
+ }
+
+ binmode $fp1;
+ binmode $fp2;
+
+ my $ret = 0;
+
+ for ( ; ; ) {
+ $n1 = sysread $fp1, $rd1, 4096;
+ $n2 = sysread $fp2, $rd2, 4096;
+ last if ( $n1 != $n2 );
+ last if ( $rd1 ne $rd2 );
+
+ if ( $n1 == 0 ) {
+ $ret = 1;
+ last;
+ }
+
+ }
+
+ close $fp1;
+ close $fp2;
+
+ return $ret;
+
+}
+
diff --git a/deps/openssl/openssl/test/cms-test.pl b/deps/openssl/openssl/test/cms-test.pl
new file mode 100644
index 000000000..c938bcf00
--- /dev/null
+++ b/deps/openssl/openssl/test/cms-test.pl
@@ -0,0 +1,457 @@
+# test/cms-test.pl
+# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+# project.
+#
+# ====================================================================
+# Copyright (c) 2008 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
+# licensing@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.
+# ====================================================================
+
+# CMS, PKCS7 consistency test script. Run extensive tests on
+# OpenSSL PKCS#7 and CMS implementations.
+
+my $ossl_path;
+my $redir = " 2> cms.err > cms.out";
+# Make VMS work
+if ( $^O eq "VMS" && -f "OSSLX:openssl.exe" ) {
+ $ossl_path = "pipe mcr OSSLX:openssl";
+}
+# Make MSYS work
+elsif ( $^O eq "MSWin32" && -f "../apps/openssl.exe" ) {
+ $ossl_path = "cmd /c ..\\apps\\openssl";
+}
+elsif ( -f "../apps/openssl$ENV{EXE_EXT}" ) {
+ $ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
+}
+elsif ( -f "..\\out32dll\\openssl.exe" ) {
+ $ossl_path = "..\\out32dll\\openssl.exe";
+}
+elsif ( -f "..\\out32\\openssl.exe" ) {
+ $ossl_path = "..\\out32\\openssl.exe";
+}
+else {
+ die "Can't find OpenSSL executable";
+}
+
+my $pk7cmd = "$ossl_path smime ";
+my $cmscmd = "$ossl_path cms ";
+my $smdir = "smime-certs";
+my $halt_err = 1;
+
+my $badcmd = 0;
+my $ossl8 = `$ossl_path version -v` =~ /0\.9\.8/;
+
+my @smime_pkcs7_tests = (
+
+ [
+ "signed content DER format, RSA key",
+ "-sign -in smcont.txt -outform \"DER\" -nodetach"
+ . " -certfile $smdir/smroot.pem"
+ . " -signer $smdir/smrsa1.pem -out test.cms",
+ "-verify -in test.cms -inform \"DER\" "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+ "signed detached content DER format, RSA key",
+ "-sign -in smcont.txt -outform \"DER\""
+ . " -signer $smdir/smrsa1.pem -out test.cms",
+ "-verify -in test.cms -inform \"DER\" "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt -content smcont.txt"
+ ],
+
+ [
+ "signed content test streaming BER format, RSA",
+ "-sign -in smcont.txt -outform \"DER\" -nodetach"
+ . " -stream -signer $smdir/smrsa1.pem -out test.cms",
+ "-verify -in test.cms -inform \"DER\" "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+ "signed content DER format, DSA key",
+ "-sign -in smcont.txt -outform \"DER\" -nodetach"
+ . " -signer $smdir/smdsa1.pem -out test.cms",
+ "-verify -in test.cms -inform \"DER\" "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+ "signed detached content DER format, DSA key",
+ "-sign -in smcont.txt -outform \"DER\""
+ . " -signer $smdir/smdsa1.pem -out test.cms",
+ "-verify -in test.cms -inform \"DER\" "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt -content smcont.txt"
+ ],
+
+ [
+ "signed detached content DER format, add RSA signer",
+ "-resign -inform \"DER\" -in test.cms -outform \"DER\""
+ . " -signer $smdir/smrsa1.pem -out test2.cms",
+ "-verify -in test2.cms -inform \"DER\" "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt -content smcont.txt"
+ ],
+
+ [
+ "signed content test streaming BER format, DSA key",
+ "-sign -in smcont.txt -outform \"DER\" -nodetach"
+ . " -stream -signer $smdir/smdsa1.pem -out test.cms",
+ "-verify -in test.cms -inform \"DER\" "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+ "signed content test streaming BER format, 2 DSA and 2 RSA keys",
+ "-sign -in smcont.txt -outform \"DER\" -nodetach"
+ . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+ . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+ . " -stream -out test.cms",
+ "-verify -in test.cms -inform \"DER\" "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+"signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes",
+ "-sign -in smcont.txt -outform \"DER\" -noattr -nodetach"
+ . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+ . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+ . " -stream -out test.cms",
+ "-verify -in test.cms -inform \"DER\" "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+ "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys",
+ "-sign -in smcont.txt -nodetach"
+ . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+ . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+ . " -stream -out test.cms",
+ "-verify -in test.cms " . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+"signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys",
+ "-sign -in smcont.txt"
+ . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+ . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+ . " -stream -out test.cms",
+ "-verify -in test.cms " . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+ "enveloped content test streaming S/MIME format, 3 recipients",
+ "-encrypt -in smcont.txt"
+ . " -stream -out test.cms"
+ . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
+ "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
+ ],
+
+ [
+"enveloped content test streaming S/MIME format, 3 recipients, 3rd used",
+ "-encrypt -in smcont.txt"
+ . " -stream -out test.cms"
+ . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
+ "-decrypt -recip $smdir/smrsa3.pem -in test.cms -out smtst.txt"
+ ],
+
+ [
+"enveloped content test streaming S/MIME format, 3 recipients, key only used",
+ "-encrypt -in smcont.txt"
+ . " -stream -out test.cms"
+ . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
+ "-decrypt -inkey $smdir/smrsa3.pem -in test.cms -out smtst.txt"
+ ],
+
+ [
+"enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients",
+ "-encrypt -in smcont.txt"
+ . " -aes256 -stream -out test.cms"
+ . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
+ "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
+ ],
+
+);
+
+my @smime_cms_tests = (
+
+ [
+ "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid",
+ "-sign -in smcont.txt -outform \"DER\" -nodetach -keyid"
+ . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+ . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+ . " -stream -out test.cms",
+ "-verify -in test.cms -inform \"DER\" "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+ "signed content test streaming PEM format, 2 DSA and 2 RSA keys",
+ "-sign -in smcont.txt -outform PEM -nodetach"
+ . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+ . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+ . " -stream -out test.cms",
+ "-verify -in test.cms -inform PEM "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+ "signed content MIME format, RSA key, signed receipt request",
+ "-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach"
+ . " -receipt_request_to test\@openssl.org -receipt_request_all"
+ . " -out test.cms",
+ "-verify -in test.cms "
+ . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+ ],
+
+ [
+ "signed receipt MIME format, RSA key",
+ "-sign_receipt -in test.cms"
+ . " -signer $smdir/smrsa2.pem"
+ . " -out test2.cms",
+ "-verify_receipt test2.cms -in test.cms"
+ . " \"-CAfile\" $smdir/smroot.pem"
+ ],
+
+ [
+ "enveloped content test streaming S/MIME format, 3 recipients, keyid",
+ "-encrypt -in smcont.txt"
+ . " -stream -out test.cms -keyid"
+ . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
+ "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
+ ],
+
+ [
+ "enveloped content test streaming PEM format, KEK",
+ "-encrypt -in smcont.txt -outform PEM -aes128"
+ . " -stream -out test.cms "
+ . " -secretkey 000102030405060708090A0B0C0D0E0F "
+ . " -secretkeyid C0FEE0",
+ "-decrypt -in test.cms -out smtst.txt -inform PEM"
+ . " -secretkey 000102030405060708090A0B0C0D0E0F "
+ . " -secretkeyid C0FEE0"
+ ],
+
+ [
+ "enveloped content test streaming PEM format, KEK, key only",
+ "-encrypt -in smcont.txt -outform PEM -aes128"
+ . " -stream -out test.cms "
+ . " -secretkey 000102030405060708090A0B0C0D0E0F "
+ . " -secretkeyid C0FEE0",
+ "-decrypt -in test.cms -out smtst.txt -inform PEM"
+ . " -secretkey 000102030405060708090A0B0C0D0E0F "
+ ],
+
+ [
+ "data content test streaming PEM format",
+ "-data_create -in smcont.txt -outform PEM -nodetach"
+ . " -stream -out test.cms",
+ "-data_out -in test.cms -inform PEM -out smtst.txt"
+ ],
+
+ [
+ "encrypted content test streaming PEM format, 128 bit RC2 key",
+ "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
+ . " -rc2 -secretkey 000102030405060708090A0B0C0D0E0F"
+ . " -stream -out test.cms",
+ "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
+ . " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt"
+ ],
+
+ [
+ "encrypted content test streaming PEM format, 40 bit RC2 key",
+ "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
+ . " -rc2 -secretkey 0001020304"
+ . " -stream -out test.cms",
+ "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
+ . " -secretkey 0001020304 -out smtst.txt"
+ ],
+
+ [
+ "encrypted content test streaming PEM format, triple DES key",
+ "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
+ . " -des3 -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617"
+ . " -stream -out test.cms",
+ "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
+ . " -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617"
+ . " -out smtst.txt"
+ ],
+
+ [
+ "encrypted content test streaming PEM format, 128 bit AES key",
+ "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
+ . " -aes128 -secretkey 000102030405060708090A0B0C0D0E0F"
+ . " -stream -out test.cms",
+ "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
+ . " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt"
+ ],
+
+);
+
+my @smime_cms_comp_tests = (
+
+ [
+ "compressed content test streaming PEM format",
+ "-compress -in smcont.txt -outform PEM -nodetach"
+ . " -stream -out test.cms",
+ "-uncompress -in test.cms -inform PEM -out smtst.txt"
+ ]
+
+);
+
+print "CMS => PKCS#7 compatibility tests\n";
+
+run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd );
+
+print "CMS <= PKCS#7 compatibility tests\n";
+
+run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $cmscmd );
+
+print "CMS <=> CMS consistency tests\n";
+
+run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $cmscmd );
+run_smime_tests( \$badcmd, \@smime_cms_tests, $cmscmd, $cmscmd );
+
+if ( `$ossl_path version -f` =~ /ZLIB/ ) {
+ run_smime_tests( \$badcmd, \@smime_cms_comp_tests, $cmscmd, $cmscmd );
+}
+else {
+ print "Zlib not supported: compression tests skipped\n";
+}
+
+print "Running modified tests for OpenSSL 0.9.8 cms backport\n" if($ossl8);
+
+if ($badcmd) {
+ print "$badcmd TESTS FAILED!!\n";
+}
+else {
+ print "ALL TESTS SUCCESSFUL.\n";
+}
+
+unlink "test.cms";
+unlink "test2.cms";
+unlink "smtst.txt";
+unlink "cms.out";
+unlink "cms.err";
+
+sub run_smime_tests {
+ my ( $rv, $aref, $scmd, $vcmd ) = @_;
+
+ foreach $smtst (@$aref) {
+ my ( $tnam, $rscmd, $rvcmd ) = @$smtst;
+ if ($ossl8)
+ {
+ # Skip smime resign: 0.9.8 smime doesn't support -resign
+ next if ($scmd =~ /smime/ && $rscmd =~ /-resign/);
+ # Disable streaming: option not supported in 0.9.8
+ $tnam =~ s/streaming//;
+ $rscmd =~ s/-stream//;
+ $rvcmd =~ s/-stream//;
+ }
+ system("$scmd$rscmd$redir");
+ if ($?) {
+ print "$tnam: generation error\n";
+ $$rv++;
+ exit 1 if $halt_err;
+ next;
+ }
+ system("$vcmd$rvcmd$redir");
+ if ($?) {
+ print "$tnam: verify error\n";
+ $$rv++;
+ exit 1 if $halt_err;
+ next;
+ }
+ if (!cmp_files("smtst.txt", "smcont.txt")) {
+ print "$tnam: content verify error\n";
+ $$rv++;
+ exit 1 if $halt_err;
+ next;
+ }
+ print "$tnam: OK\n";
+ }
+}
+
+sub cmp_files {
+ my ( $f1, $f2 ) = @_;
+ my ( $fp1, $fp2 );
+
+ my ( $rd1, $rd2 );
+
+ if ( !open( $fp1, "<$f1" ) ) {
+ print STDERR "Can't Open file $f1\n";
+ return 0;
+ }
+
+ if ( !open( $fp2, "<$f2" ) ) {
+ print STDERR "Can't Open file $f2\n";
+ return 0;
+ }
+
+ binmode $fp1;
+ binmode $fp2;
+
+ my $ret = 0;
+
+ for ( ; ; ) {
+ $n1 = sysread $fp1, $rd1, 4096;
+ $n2 = sysread $fp2, $rd2, 4096;
+ last if ( $n1 != $n2 );
+ last if ( $rd1 ne $rd2 );
+
+ if ( $n1 == 0 ) {
+ $ret = 1;
+ last;
+ }
+
+ }
+
+ close $fp1;
+ close $fp2;
+
+ return $ret;
+
+}
+
diff --git a/deps/openssl/openssl/test/destest.c b/deps/openssl/openssl/test/destest.c
new file mode 100644
index 000000000..64b92a34f
--- /dev/null
+++ b/deps/openssl/openssl/test/destest.c
@@ -0,0 +1,952 @@
+/* crypto/des/destest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <openssl/e_os2.h>
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_WINDOWS)
+#ifndef OPENSSL_SYS_MSDOS
+#define OPENSSL_SYS_MSDOS
+#endif
+#endif
+
+#ifndef OPENSSL_SYS_MSDOS
+#if !defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VMS_DECC)
+#include OPENSSL_UNISTD
+#endif
+#else
+#include <io.h>
+#endif
+#include <string.h>
+
+#ifdef OPENSSL_NO_DES
+int main(int argc, char *argv[])
+{
+ printf("No DES support\n");
+ return(0);
+}
+#else
+#include <openssl/des.h>
+
+#define crypt(c,s) (DES_crypt((c),(s)))
+
+/* tisk tisk - the test keys don't all have odd parity :-( */
+/* test data */
+#define NUM_TESTS 34
+static unsigned char key_data[NUM_TESTS][8]={
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
+ {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
+ {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
+ {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
+ {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
+ {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
+ {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
+ {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
+ {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
+ {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
+ {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
+ {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
+ {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
+ {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
+ {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
+ {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
+ {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
+ {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
+ {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
+ {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+ {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
+
+static unsigned char plain_data[NUM_TESTS][8]={
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
+ {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
+ {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
+ {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
+ {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
+ {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
+ {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
+ {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
+ {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
+ {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
+ {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
+ {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
+ {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
+ {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
+ {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
+ {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
+ {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
+ {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
+ {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
+
+static unsigned char cipher_data[NUM_TESTS][8]={
+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+ {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
+ {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
+ {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
+ {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
+ {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+ {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
+ {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
+ {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
+ {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
+ {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
+ {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
+ {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
+ {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
+ {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
+ {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
+ {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
+ {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
+ {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
+ {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
+ {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
+ {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
+ {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
+ {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
+ {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
+ {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
+ {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
+ {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
+ {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
+ {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
+ {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
+ {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
+ {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
+
+static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
+ {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
+ {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
+ {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
+ {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
+ {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
+ {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
+ {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
+ {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
+ {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
+ {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
+ {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
+ {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
+ {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
+ {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
+ {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
+ {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
+ {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
+ {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
+ {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
+ {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
+ {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
+ {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
+ {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
+ {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
+ {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
+ {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
+ {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
+ {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
+ {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
+ {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
+ {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
+ {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
+ {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
+
+static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cbc2_key[8]={0xf1,0xe0,0xd3,0xc2,0xb5,0xa4,0x97,0x86};
+static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+/* Changed the following text constant to binary so it will work on ebcdic
+ * machines :-) */
+/* static char cbc_data[40]="7654321 Now is the time for \0001"; */
+static unsigned char cbc_data[40]={
+ 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x20,
+ 0x4E,0x6F,0x77,0x20,0x69,0x73,0x20,0x74,
+ 0x68,0x65,0x20,0x74,0x69,0x6D,0x65,0x20,
+ 0x66,0x6F,0x72,0x20,0x00,0x31,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ };
+
+static unsigned char cbc_ok[32]={
+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+ 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
+ 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
+ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+#ifdef SCREW_THE_PARITY
+#error "SCREW_THE_PARITY is not ment to be defined."
+#error "Original vectors are preserved for reference only."
+static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
+static unsigned char xcbc_ok[32]={
+ 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
+ 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
+ 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
+ 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
+ };
+#else
+static unsigned char xcbc_ok[32]={
+ 0x84,0x6B,0x29,0x14,0x85,0x1E,0x9A,0x29,
+ 0x54,0x73,0x2F,0x8A,0xA0,0xA6,0x11,0xC1,
+ 0x15,0xCD,0xC2,0xD7,0x95,0x1B,0x10,0x53,
+ 0xA6,0x3C,0x5E,0x03,0xB2,0x1A,0xA3,0xC4,
+ };
+#endif
+
+static unsigned char cbc3_ok[32]={
+ 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
+ 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
+ 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
+ 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
+
+static unsigned char pcbc_ok[32]={
+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+ 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
+ 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
+ 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
+
+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+static unsigned char plain[24]=
+ {
+ 0x4e,0x6f,0x77,0x20,0x69,0x73,
+ 0x20,0x74,0x68,0x65,0x20,0x74,
+ 0x69,0x6d,0x65,0x20,0x66,0x6f,
+ 0x72,0x20,0x61,0x6c,0x6c,0x20
+ };
+static unsigned char cfb_cipher8[24]= {
+ 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
+ 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
+static unsigned char cfb_cipher16[24]={
+ 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
+ 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
+static unsigned char cfb_cipher32[24]={
+ 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
+ 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
+static unsigned char cfb_cipher48[24]={
+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
+ 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
+static unsigned char cfb_cipher64[24]={
+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
+ 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
+
+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
+static unsigned char ofb_cipher[24]=
+ {
+ 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
+ 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
+ 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
+ };
+
+#if 0
+static DES_LONG cbc_cksum_ret=0xB462FEF7L;
+#else
+static DES_LONG cbc_cksum_ret=0xF7FE62B4L;
+#endif
+static unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+static char *pt(unsigned char *p);
+static int cfb_test(int bits, unsigned char *cfb_cipher);
+static int cfb64_test(unsigned char *cfb_cipher);
+static int ede_cfb64_test(unsigned char *cfb_cipher);
+int main(int argc, char *argv[])
+ {
+ int j,err=0;
+ unsigned int i;
+ des_cblock in,out,outin,iv3,iv2;
+ des_key_schedule ks,ks2,ks3;
+ unsigned char cbc_in[40];
+ unsigned char cbc_out[40];
+ DES_LONG cs;
+ unsigned char cret[8];
+#ifdef _CRAY
+ struct {
+ int a:32;
+ int b:32;
+ } lqret[2];
+#else
+ DES_LONG lqret[4];
+#endif
+ int num;
+ char *str;
+
+#ifndef OPENSSL_NO_DESCBCM
+ printf("Doing cbcm\n");
+ if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ memset(cbc_out,0,40);
+ memset(cbc_in,0,40);
+ i=strlen((char *)cbc_data)+1;
+ /* i=((i+7)/8)*8; */
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ memset(iv2,'\0',sizeof iv2);
+
+ DES_ede3_cbcm_encrypt(cbc_data,cbc_out,16L,&ks,&ks2,&ks3,&iv3,&iv2,
+ DES_ENCRYPT);
+ DES_ede3_cbcm_encrypt(&cbc_data[16],&cbc_out[16],i-16,&ks,&ks2,&ks3,
+ &iv3,&iv2,DES_ENCRYPT);
+ /* if (memcmp(cbc_out,cbc3_ok,
+ (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
+ {
+ printf("des_ede3_cbc_encrypt encrypt error\n");
+ err=1;
+ }
+ */
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ memset(iv2,'\0',sizeof iv2);
+ DES_ede3_cbcm_encrypt(cbc_out,cbc_in,i,&ks,&ks2,&ks3,&iv3,&iv2,DES_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
+ {
+ unsigned int n;
+
+ printf("des_ede3_cbcm_encrypt decrypt error\n");
+ for(n=0 ; n < i ; ++n)
+ printf(" %02x",cbc_data[n]);
+ printf("\n");
+ for(n=0 ; n < i ; ++n)
+ printf(" %02x",cbc_in[n]);
+ printf("\n");
+ err=1;
+ }
+#endif
+
+ printf("Doing ecb\n");
+ for (i=0; i<NUM_TESTS; i++)
+ {
+ DES_set_key_unchecked(&key_data[i],&ks);
+ memcpy(in,plain_data[i],8);
+ memset(out,0,8);
+ memset(outin,0,8);
+ des_ecb_encrypt(&in,&out,ks,DES_ENCRYPT);
+ des_ecb_encrypt(&out,&outin,ks,DES_DECRYPT);
+
+ if (memcmp(out,cipher_data[i],8) != 0)
+ {
+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
+ pt(out));
+ err=1;
+ }
+ if (memcmp(in,outin,8) != 0)
+ {
+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+ err=1;
+ }
+ }
+
+#ifndef LIBDES_LIT
+ printf("Doing ede ecb\n");
+ for (i=0; i<(NUM_TESTS-2); i++)
+ {
+ DES_set_key_unchecked(&key_data[i],&ks);
+ DES_set_key_unchecked(&key_data[i+1],&ks2);
+ DES_set_key_unchecked(&key_data[i+2],&ks3);
+ memcpy(in,plain_data[i],8);
+ memset(out,0,8);
+ memset(outin,0,8);
+ des_ecb2_encrypt(&in,&out,ks,ks2,DES_ENCRYPT);
+ des_ecb2_encrypt(&out,&outin,ks,ks2,DES_DECRYPT);
+
+ if (memcmp(out,cipher_ecb2[i],8) != 0)
+ {
+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
+ pt(out));
+ err=1;
+ }
+ if (memcmp(in,outin,8) != 0)
+ {
+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+ err=1;
+ }
+ }
+#endif
+
+ printf("Doing cbc\n");
+ if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ memset(cbc_out,0,40);
+ memset(cbc_in,0,40);
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ des_ncbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
+ &iv3,DES_ENCRYPT);
+ if (memcmp(cbc_out,cbc_ok,32) != 0)
+ {
+ printf("cbc_encrypt encrypt error\n");
+ err=1;
+ }
+
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ des_ncbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
+ &iv3,DES_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
+ {
+ printf("cbc_encrypt decrypt error\n");
+ err=1;
+ }
+
+#ifndef LIBDES_LIT
+ printf("Doing desx cbc\n");
+ if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ memset(cbc_out,0,40);
+ memset(cbc_in,0,40);
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ des_xcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
+ &iv3,&cbc2_key,&cbc3_key, DES_ENCRYPT);
+ if (memcmp(cbc_out,xcbc_ok,32) != 0)
+ {
+ printf("des_xcbc_encrypt encrypt error\n");
+ err=1;
+ }
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ des_xcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
+ &iv3,&cbc2_key,&cbc3_key, DES_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
+ {
+ printf("des_xcbc_encrypt decrypt error\n");
+ err=1;
+ }
+#endif
+
+ printf("Doing ede cbc\n");
+ if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ memset(cbc_out,0,40);
+ memset(cbc_in,0,40);
+ i=strlen((char *)cbc_data)+1;
+ /* i=((i+7)/8)*8; */
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+
+ des_ede3_cbc_encrypt(cbc_data,cbc_out,16L,ks,ks2,ks3,&iv3,
+ DES_ENCRYPT);
+ des_ede3_cbc_encrypt(&(cbc_data[16]),&(cbc_out[16]),i-16,ks,ks2,ks3,
+ &iv3,DES_ENCRYPT);
+ if (memcmp(cbc_out,cbc3_ok,
+ (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
+ {
+ unsigned int n;
+
+ printf("des_ede3_cbc_encrypt encrypt error\n");
+ for(n=0 ; n < i ; ++n)
+ printf(" %02x",cbc_out[n]);
+ printf("\n");
+ for(n=0 ; n < i ; ++n)
+ printf(" %02x",cbc3_ok[n]);
+ printf("\n");
+ err=1;
+ }
+
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ des_ede3_cbc_encrypt(cbc_out,cbc_in,i,ks,ks2,ks3,&iv3,DES_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
+ {
+ unsigned int n;
+
+ printf("des_ede3_cbc_encrypt decrypt error\n");
+ for(n=0 ; n < i ; ++n)
+ printf(" %02x",cbc_data[n]);
+ printf("\n");
+ for(n=0 ; n < i ; ++n)
+ printf(" %02x",cbc_in[n]);
+ printf("\n");
+ err=1;
+ }
+
+#ifndef LIBDES_LIT
+ printf("Doing pcbc\n");
+ if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ memset(cbc_out,0,40);
+ memset(cbc_in,0,40);
+ des_pcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
+ &cbc_iv,DES_ENCRYPT);
+ if (memcmp(cbc_out,pcbc_ok,32) != 0)
+ {
+ printf("pcbc_encrypt encrypt error\n");
+ err=1;
+ }
+ des_pcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,&cbc_iv,
+ DES_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
+ {
+ printf("pcbc_encrypt decrypt error\n");
+ err=1;
+ }
+
+ printf("Doing ");
+ printf("cfb8 ");
+ err+=cfb_test(8,cfb_cipher8);
+ printf("cfb16 ");
+ err+=cfb_test(16,cfb_cipher16);
+ printf("cfb32 ");
+ err+=cfb_test(32,cfb_cipher32);
+ printf("cfb48 ");
+ err+=cfb_test(48,cfb_cipher48);
+ printf("cfb64 ");
+ err+=cfb_test(64,cfb_cipher64);
+
+ printf("cfb64() ");
+ err+=cfb64_test(cfb_cipher64);
+
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ for (i=0; i<sizeof(plain); i++)
+ des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
+ 8,1,ks,&cfb_tmp,DES_ENCRYPT);
+ if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
+ {
+ printf("cfb_encrypt small encrypt error\n");
+ err=1;
+ }
+
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ for (i=0; i<sizeof(plain); i++)
+ des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
+ 8,1,ks,&cfb_tmp,DES_DECRYPT);
+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+ {
+ printf("cfb_encrypt small decrypt error\n");
+ err=1;
+ }
+
+ printf("ede_cfb64() ");
+ err+=ede_cfb64_test(cfb_cipher64);
+
+ printf("done\n");
+
+ printf("Doing ofb\n");
+ DES_set_key_checked(&ofb_key,&ks);
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ des_ofb_encrypt(plain,ofb_buf1,64,sizeof(plain)/8,ks,&ofb_tmp);
+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+ {
+ printf("ofb_encrypt encrypt error\n");
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
+ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
+ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
+ err=1;
+ }
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ des_ofb_encrypt(ofb_buf1,ofb_buf2,64,sizeof(ofb_buf1)/8,ks,&ofb_tmp);
+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+ {
+ printf("ofb_encrypt decrypt error\n");
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
+ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+plain[8+0], plain[8+1], plain[8+2], plain[8+3],
+plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
+ err=1;
+ }
+
+ printf("Doing ofb64\n");
+ DES_set_key_checked(&ofb_key,&ks);
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ memset(ofb_buf1,0,sizeof(ofb_buf1));
+ memset(ofb_buf2,0,sizeof(ofb_buf1));
+ num=0;
+ for (i=0; i<sizeof(plain); i++)
+ {
+ des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,&ofb_tmp,
+ &num);
+ }
+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+ {
+ printf("ofb64_encrypt encrypt error\n");
+ err=1;
+ }
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ num=0;
+ des_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,&ofb_tmp,
+ &num);
+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+ {
+ printf("ofb64_encrypt decrypt error\n");
+ err=1;
+ }
+
+ printf("Doing ede_ofb64\n");
+ DES_set_key_checked(&ofb_key,&ks);
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ memset(ofb_buf1,0,sizeof(ofb_buf1));
+ memset(ofb_buf2,0,sizeof(ofb_buf1));
+ num=0;
+ for (i=0; i<sizeof(plain); i++)
+ {
+ des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,
+ ks,&ofb_tmp,&num);
+ }
+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+ {
+ printf("ede_ofb64_encrypt encrypt error\n");
+ err=1;
+ }
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ num=0;
+ des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,ks,ks,
+ &ofb_tmp,&num);
+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+ {
+ printf("ede_ofb64_encrypt decrypt error\n");
+ err=1;
+ }
+
+ printf("Doing cbc_cksum\n");
+ DES_set_key_checked(&cbc_key,&ks);
+ cs=des_cbc_cksum(cbc_data,&cret,strlen((char *)cbc_data),ks,&cbc_iv);
+ if (cs != cbc_cksum_ret)
+ {
+ printf("bad return value (%08lX), should be %08lX\n",
+ (unsigned long)cs,(unsigned long)cbc_cksum_ret);
+ err=1;
+ }
+ if (memcmp(cret,cbc_cksum_data,8) != 0)
+ {
+ printf("bad cbc_cksum block returned\n");
+ err=1;
+ }
+
+ printf("Doing quad_cksum\n");
+ cs=des_quad_cksum(cbc_data,(des_cblock *)lqret,
+ (long)strlen((char *)cbc_data),2,(des_cblock *)cbc_iv);
+ if (cs != 0x70d7a63aL)
+ {
+ printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
+ (unsigned long)cs);
+ err=1;
+ }
+#ifdef _CRAY
+ if (lqret[0].a != 0x327eba8dL)
+ {
+ printf("quad_cksum error, out[0] %08lx is not %08lx\n",
+ (unsigned long)lqret[0].a,0x327eba8dUL);
+ err=1;
+ }
+ if (lqret[0].b != 0x201a49ccL)
+ {
+ printf("quad_cksum error, out[1] %08lx is not %08lx\n",
+ (unsigned long)lqret[0].b,0x201a49ccUL);
+ err=1;
+ }
+ if (lqret[1].a != 0x70d7a63aL)
+ {
+ printf("quad_cksum error, out[2] %08lx is not %08lx\n",
+ (unsigned long)lqret[1].a,0x70d7a63aUL);
+ err=1;
+ }
+ if (lqret[1].b != 0x501c2c26L)
+ {
+ printf("quad_cksum error, out[3] %08lx is not %08lx\n",
+ (unsigned long)lqret[1].b,0x501c2c26UL);
+ err=1;
+ }
+#else
+ if (lqret[0] != 0x327eba8dL)
+ {
+ printf("quad_cksum error, out[0] %08lx is not %08lx\n",
+ (unsigned long)lqret[0],0x327eba8dUL);
+ err=1;
+ }
+ if (lqret[1] != 0x201a49ccL)
+ {
+ printf("quad_cksum error, out[1] %08lx is not %08lx\n",
+ (unsigned long)lqret[1],0x201a49ccUL);
+ err=1;
+ }
+ if (lqret[2] != 0x70d7a63aL)
+ {
+ printf("quad_cksum error, out[2] %08lx is not %08lx\n",
+ (unsigned long)lqret[2],0x70d7a63aUL);
+ err=1;
+ }
+ if (lqret[3] != 0x501c2c26L)
+ {
+ printf("quad_cksum error, out[3] %08lx is not %08lx\n",
+ (unsigned long)lqret[3],0x501c2c26UL);
+ err=1;
+ }
+#endif
+#endif
+
+ printf("input word alignment test");
+ for (i=0; i<4; i++)
+ {
+ printf(" %d",i);
+ des_ncbc_encrypt(&(cbc_out[i]),cbc_in,
+ strlen((char *)cbc_data)+1,ks,
+ &cbc_iv,DES_ENCRYPT);
+ }
+ printf("\noutput word alignment test");
+ for (i=0; i<4; i++)
+ {
+ printf(" %d",i);
+ des_ncbc_encrypt(cbc_out,&(cbc_in[i]),
+ strlen((char *)cbc_data)+1,ks,
+ &cbc_iv,DES_ENCRYPT);
+ }
+ printf("\n");
+ printf("fast crypt test ");
+ str=crypt("testing","ef");
+ if (strcmp("efGnQx2725bI2",str) != 0)
+ {
+ printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
+ err=1;
+ }
+ str=crypt("bca76;23","yA");
+ if (strcmp("yA1Rp/1hZXIJk",str) != 0)
+ {
+ printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
+ err=1;
+ }
+#ifdef OPENSSL_SYS_NETWARE
+ if (err) printf("ERROR: %d\n", err);
+#endif
+ printf("\n");
+ return(err);
+ }
+
+static char *pt(unsigned char *p)
+ {
+ static char bufs[10][20];
+ static int bnum=0;
+ char *ret;
+ int i;
+ static char *f="0123456789ABCDEF";
+
+ ret= &(bufs[bnum++][0]);
+ bnum%=10;
+ for (i=0; i<8; i++)
+ {
+ ret[i*2]=f[(p[i]>>4)&0xf];
+ ret[i*2+1]=f[p[i]&0xf];
+ }
+ ret[16]='\0';
+ return(ret);
+ }
+
+#ifndef LIBDES_LIT
+
+static int cfb_test(int bits, unsigned char *cfb_cipher)
+ {
+ des_key_schedule ks;
+ int i,err=0;
+
+ DES_set_key_checked(&cfb_key,&ks);
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ des_cfb_encrypt(plain,cfb_buf1,bits,sizeof(plain),ks,&cfb_tmp,
+ DES_ENCRYPT);
+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("cfb_encrypt encrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf1[i])));
+ }
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,sizeof(plain),ks,&cfb_tmp,
+ DES_DECRYPT);
+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("cfb_encrypt decrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf1[i])));
+ }
+ return(err);
+ }
+
+static int cfb64_test(unsigned char *cfb_cipher)
+ {
+ des_key_schedule ks;
+ int err=0,i,n;
+
+ DES_set_key_checked(&cfb_key,&ks);
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ n=0;
+ des_cfb64_encrypt(plain,cfb_buf1,12,ks,&cfb_tmp,&n,DES_ENCRYPT);
+ des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),sizeof(plain)-12,ks,
+ &cfb_tmp,&n,DES_ENCRYPT);
+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("cfb_encrypt encrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf1[i])));
+ }
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ n=0;
+ des_cfb64_encrypt(cfb_buf1,cfb_buf2,17,ks,&cfb_tmp,&n,DES_DECRYPT);
+ des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+ sizeof(plain)-17,ks,&cfb_tmp,&n,DES_DECRYPT);
+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("cfb_encrypt decrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf2[i])));
+ }
+ return(err);
+ }
+
+static int ede_cfb64_test(unsigned char *cfb_cipher)
+ {
+ des_key_schedule ks;
+ int err=0,i,n;
+
+ DES_set_key_checked(&cfb_key,&ks);
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ n=0;
+ des_ede3_cfb64_encrypt(plain,cfb_buf1,12,ks,ks,ks,&cfb_tmp,&n,
+ DES_ENCRYPT);
+ des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+ sizeof(plain)-12,ks,ks,ks,
+ &cfb_tmp,&n,DES_ENCRYPT);
+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("ede_cfb_encrypt encrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf1[i])));
+ }
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ n=0;
+ des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
+ &cfb_tmp,&n,DES_DECRYPT);
+ des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+ sizeof(plain)-17,ks,ks,ks,
+ &cfb_tmp,&n,DES_DECRYPT);
+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("ede_cfb_encrypt decrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf2[i])));
+ }
+ return(err);
+ }
+
+#endif
+#endif
diff --git a/deps/openssl/openssl/test/dhtest.c b/deps/openssl/openssl/test/dhtest.c
new file mode 100644
index 000000000..882f5c310
--- /dev/null
+++ b/deps/openssl/openssl/test/dhtest.c
@@ -0,0 +1,226 @@
+/* crypto/dh/dhtest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#ifdef OPENSSL_NO_DH
+int main(int argc, char *argv[])
+{
+ printf("No DH support\n");
+ return(0);
+}
+#else
+#include <openssl/dh.h>
+
+#ifdef OPENSSL_SYS_WIN16
+#define MS_CALLBACK _far _loadds
+#else
+#define MS_CALLBACK
+#endif
+
+static int MS_CALLBACK cb(int p, int n, BN_GENCB *arg);
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int main(int argc, char *argv[])
+ {
+ BN_GENCB _cb;
+ DH *a;
+ DH *b=NULL;
+ char buf[12];
+ unsigned char *abuf=NULL,*bbuf=NULL;
+ int i,alen,blen,aout,bout,ret=1;
+ BIO *out;
+
+ CRYPTO_malloc_debug_init();
+ CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+#ifdef OPENSSL_SYS_WIN32
+ CRYPTO_malloc_init();
+#endif
+
+ RAND_seed(rnd_seed, sizeof rnd_seed);
+
+ out=BIO_new(BIO_s_file());
+ if (out == NULL) EXIT(1);
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+
+ BN_GENCB_set(&_cb, &cb, out);
+ if(((a = DH_new()) == NULL) || !DH_generate_parameters_ex(a, 64,
+ DH_GENERATOR_5, &_cb))
+ goto err;
+
+ if (!DH_check(a, &i)) goto err;
+ if (i & DH_CHECK_P_NOT_PRIME)
+ BIO_puts(out, "p value is not prime\n");
+ if (i & DH_CHECK_P_NOT_SAFE_PRIME)
+ BIO_puts(out, "p value is not a safe prime\n");
+ if (i & DH_UNABLE_TO_CHECK_GENERATOR)
+ BIO_puts(out, "unable to check the generator value\n");
+ if (i & DH_NOT_SUITABLE_GENERATOR)
+ BIO_puts(out, "the g value is not a generator\n");
+
+ BIO_puts(out,"\np =");
+ BN_print(out,a->p);
+ BIO_puts(out,"\ng =");
+ BN_print(out,a->g);
+ BIO_puts(out,"\n");
+
+ b=DH_new();
+ if (b == NULL) goto err;
+
+ b->p=BN_dup(a->p);
+ b->g=BN_dup(a->g);
+ if ((b->p == NULL) || (b->g == NULL)) goto err;
+
+ /* Set a to run with normal modexp and b to use constant time */
+ a->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
+ b->flags |= DH_FLAG_NO_EXP_CONSTTIME;
+
+ if (!DH_generate_key(a)) goto err;
+ BIO_puts(out,"pri 1=");
+ BN_print(out,a->priv_key);
+ BIO_puts(out,"\npub 1=");
+ BN_print(out,a->pub_key);
+ BIO_puts(out,"\n");
+
+ if (!DH_generate_key(b)) goto err;
+ BIO_puts(out,"pri 2=");
+ BN_print(out,b->priv_key);
+ BIO_puts(out,"\npub 2=");
+ BN_print(out,b->pub_key);
+ BIO_puts(out,"\n");
+
+ alen=DH_size(a);
+ abuf=(unsigned char *)OPENSSL_malloc(alen);
+ aout=DH_compute_key(abuf,b->pub_key,a);
+
+ BIO_puts(out,"key1 =");
+ for (i=0; i<aout; i++)
+ {
+ sprintf(buf,"%02X",abuf[i]);
+ BIO_puts(out,buf);
+ }
+ BIO_puts(out,"\n");
+
+ blen=DH_size(b);
+ bbuf=(unsigned char *)OPENSSL_malloc(blen);
+ bout=DH_compute_key(bbuf,a->pub_key,b);
+
+ BIO_puts(out,"key2 =");
+ for (i=0; i<bout; i++)
+ {
+ sprintf(buf,"%02X",bbuf[i]);
+ BIO_puts(out,buf);
+ }
+ BIO_puts(out,"\n");
+ if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0))
+ {
+ fprintf(stderr,"Error in DH routines\n");
+ ret=1;
+ }
+ else
+ ret=0;
+err:
+ ERR_print_errors_fp(stderr);
+
+ if (abuf != NULL) OPENSSL_free(abuf);
+ if (bbuf != NULL) OPENSSL_free(bbuf);
+ if(b != NULL) DH_free(b);
+ if(a != NULL) DH_free(a);
+ BIO_free(out);
+#ifdef OPENSSL_SYS_NETWARE
+ if (ret) printf("ERROR: %d\n", ret);
+#endif
+ EXIT(ret);
+ return(ret);
+ }
+
+static int MS_CALLBACK cb(int p, int n, BN_GENCB *arg)
+ {
+ char c='*';
+
+ if (p == 0) c='.';
+ if (p == 1) c='+';
+ if (p == 2) c='*';
+ if (p == 3) c='\n';
+ BIO_write(arg->arg,&c,1);
+ (void)BIO_flush(arg->arg);
+#ifdef LINT
+ p=n;
+#endif
+ return 1;
+ }
+#endif
diff --git a/deps/openssl/openssl/test/dsatest.c b/deps/openssl/openssl/test/dsatest.c
new file mode 100644
index 000000000..edffd24e6
--- /dev/null
+++ b/deps/openssl/openssl/test/dsatest.c
@@ -0,0 +1,259 @@
+/* crypto/dsa/dsatest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "../e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+#ifdef OPENSSL_NO_DSA
+int main(int argc, char *argv[])
+{
+ printf("No DSA support\n");
+ return(0);
+}
+#else
+#include <openssl/dsa.h>
+
+#ifdef OPENSSL_SYS_WIN16
+#define MS_CALLBACK _far _loadds
+#else
+#define MS_CALLBACK
+#endif
+
+static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg);
+
+/* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to
+ * FIPS PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */
+static unsigned char seed[20]={
+ 0xd5,0x01,0x4e,0x4b,0x60,0xef,0x2b,0xa8,0xb6,0x21,0x1b,0x40,
+ 0x62,0xba,0x32,0x24,0xe0,0x42,0x7d,0xd3,
+ };
+
+static unsigned char out_p[]={
+ 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
+ 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
+ 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
+ 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
+ 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
+ 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac,
+ 0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2,
+ 0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91,
+ };
+
+static unsigned char out_q[]={
+ 0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee,
+ 0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e,
+ 0xda,0xce,0x91,0x5f,
+ };
+
+static unsigned char out_g[]={
+ 0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13,
+ 0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00,
+ 0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb,
+ 0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e,
+ 0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf,
+ 0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c,
+ 0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c,
+ 0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02,
+ };
+
+static const unsigned char str1[]="12345678901234567890";
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+static BIO *bio_err=NULL;
+
+int main(int argc, char **argv)
+ {
+ BN_GENCB cb;
+ DSA *dsa=NULL;
+ int counter,ret=0,i,j;
+ unsigned char buf[256];
+ unsigned long h;
+ unsigned char sig[256];
+ unsigned int siglen;
+
+ if (bio_err == NULL)
+ bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+ CRYPTO_malloc_debug_init();
+ CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ ERR_load_crypto_strings();
+ RAND_seed(rnd_seed, sizeof rnd_seed);
+
+ BIO_printf(bio_err,"test generation of DSA parameters\n");
+
+ BN_GENCB_set(&cb, dsa_cb, bio_err);
+ if(((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 512,
+ seed, 20, &counter, &h, &cb))
+ goto end;
+
+ BIO_printf(bio_err,"seed\n");
+ for (i=0; i<20; i+=4)
+ {
+ BIO_printf(bio_err,"%02X%02X%02X%02X ",
+ seed[i],seed[i+1],seed[i+2],seed[i+3]);
+ }
+ BIO_printf(bio_err,"\ncounter=%d h=%ld\n",counter,h);
+
+ DSA_print(bio_err,dsa,0);
+ if (counter != 105)
+ {
+ BIO_printf(bio_err,"counter should be 105\n");
+ goto end;
+ }
+ if (h != 2)
+ {
+ BIO_printf(bio_err,"h should be 2\n");
+ goto end;
+ }
+
+ i=BN_bn2bin(dsa->q,buf);
+ j=sizeof(out_q);
+ if ((i != j) || (memcmp(buf,out_q,i) != 0))
+ {
+ BIO_printf(bio_err,"q value is wrong\n");
+ goto end;
+ }
+
+ i=BN_bn2bin(dsa->p,buf);
+ j=sizeof(out_p);
+ if ((i != j) || (memcmp(buf,out_p,i) != 0))
+ {
+ BIO_printf(bio_err,"p value is wrong\n");
+ goto end;
+ }
+
+ i=BN_bn2bin(dsa->g,buf);
+ j=sizeof(out_g);
+ if ((i != j) || (memcmp(buf,out_g,i) != 0))
+ {
+ BIO_printf(bio_err,"g value is wrong\n");
+ goto end;
+ }
+
+ dsa->flags |= DSA_FLAG_NO_EXP_CONSTTIME;
+ DSA_generate_key(dsa);
+ DSA_sign(0, str1, 20, sig, &siglen, dsa);
+ if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
+ ret=1;
+
+ dsa->flags &= ~DSA_FLAG_NO_EXP_CONSTTIME;
+ DSA_generate_key(dsa);
+ DSA_sign(0, str1, 20, sig, &siglen, dsa);
+ if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
+ ret=1;
+
+end:
+ if (!ret)
+ ERR_print_errors(bio_err);
+ if (dsa != NULL) DSA_free(dsa);
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+ ERR_free_strings();
+ CRYPTO_mem_leaks(bio_err);
+ if (bio_err != NULL)
+ {
+ BIO_free(bio_err);
+ bio_err = NULL;
+ }
+#ifdef OPENSSL_SYS_NETWARE
+ if (!ret) printf("ERROR\n");
+#endif
+ EXIT(!ret);
+ return(0);
+ }
+
+static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg)
+ {
+ char c='*';
+ static int ok=0,num=0;
+
+ if (p == 0) { c='.'; num++; };
+ if (p == 1) c='+';
+ if (p == 2) { c='*'; ok++; }
+ if (p == 3) c='\n';
+ BIO_write(arg->arg,&c,1);
+ (void)BIO_flush(arg->arg);
+
+ if (!ok && (p == 0) && (num > 1))
+ {
+ BIO_printf((BIO *)arg,"error in dsatest\n");
+ return 0;
+ }
+ return 1;
+ }
+#endif
diff --git a/deps/openssl/openssl/test/dummytest.c b/deps/openssl/openssl/test/dummytest.c
new file mode 100644
index 000000000..5b4467e04
--- /dev/null
+++ b/deps/openssl/openssl/test/dummytest.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <openssl/e_os2.h>
+#include <openssl/buffer.h>
+#include <openssl/crypto.h>
+
+int main(int argc, char *argv[])
+ {
+ char *p, *q = 0, *program;
+
+ p = strrchr(argv[0], '/');
+ if (!p) p = strrchr(argv[0], '\\');
+#ifdef OPENSSL_SYS_VMS
+ if (!p) p = strrchr(argv[0], ']');
+ if (p) q = strrchr(p, '>');
+ if (q) p = q;
+ if (!p) p = strrchr(argv[0], ':');
+ q = 0;
+#endif
+ if (p) p++;
+ if (!p) p = argv[0];
+ if (p) q = strchr(p, '.');
+ if (p && !q) q = p + strlen(p);
+
+ if (!p)
+ program = BUF_strdup("(unknown)");
+ else
+ {
+ program = OPENSSL_malloc((q - p) + 1);
+ strncpy(program, p, q - p);
+ program[q - p] = '\0';
+ }
+
+ for(p = program; *p; p++)
+ if (islower((unsigned char)(*p)))
+ *p = toupper((unsigned char)(*p));
+
+ q = strstr(program, "TEST");
+ if (q > p && q[-1] == '_') q--;
+ *q = '\0';
+
+ printf("No %s support\n", program);
+
+ OPENSSL_free(program);
+ return(0);
+ }
diff --git a/deps/openssl/openssl/test/ecdhtest.c b/deps/openssl/openssl/test/ecdhtest.c
new file mode 100644
index 000000000..823d7baa6
--- /dev/null
+++ b/deps/openssl/openssl/test/ecdhtest.c
@@ -0,0 +1,374 @@
+/* crypto/ecdh/ecdhtest.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 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).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#include <openssl/opensslconf.h> /* for OPENSSL_NO_ECDH */
+#include <openssl/crypto.h>
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+#include <openssl/err.h>
+
+#ifdef OPENSSL_NO_ECDH
+int main(int argc, char *argv[])
+{
+ printf("No ECDH support\n");
+ return(0);
+}
+#else
+#include <openssl/ec.h>
+#include <openssl/ecdh.h>
+
+#ifdef OPENSSL_SYS_WIN16
+#define MS_CALLBACK _far _loadds
+#else
+#define MS_CALLBACK
+#endif
+
+#if 0
+static void MS_CALLBACK cb(int p, int n, void *arg);
+#endif
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+
+static const int KDF1_SHA1_len = 20;
+static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
+ {
+#ifndef OPENSSL_NO_SHA
+ if (*outlen < SHA_DIGEST_LENGTH)
+ return NULL;
+ else
+ *outlen = SHA_DIGEST_LENGTH;
+ return SHA1(in, inlen, out);
+#else
+ return NULL;
+#endif
+ }
+
+
+static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
+ {
+ EC_KEY *a=NULL;
+ EC_KEY *b=NULL;
+ BIGNUM *x_a=NULL, *y_a=NULL,
+ *x_b=NULL, *y_b=NULL;
+ char buf[12];
+ unsigned char *abuf=NULL,*bbuf=NULL;
+ int i,alen,blen,aout,bout,ret=0;
+ const EC_GROUP *group;
+
+ a = EC_KEY_new_by_curve_name(nid);
+ b = EC_KEY_new_by_curve_name(nid);
+ if (a == NULL || b == NULL)
+ goto err;
+
+ group = EC_KEY_get0_group(a);
+
+ if ((x_a=BN_new()) == NULL) goto err;
+ if ((y_a=BN_new()) == NULL) goto err;
+ if ((x_b=BN_new()) == NULL) goto err;
+ if ((y_b=BN_new()) == NULL) goto err;
+
+ BIO_puts(out,"Testing key generation with ");
+ BIO_puts(out,text);
+#ifdef NOISY
+ BIO_puts(out,"\n");
+#else
+ (void)BIO_flush(out);
+#endif
+
+ if (!EC_KEY_generate_key(a)) goto err;
+
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
+ {
+ if (!EC_POINT_get_affine_coordinates_GFp(group,
+ EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
+ }
+#ifndef OPENSSL_NO_EC2M
+ else
+ {
+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
+ EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
+ }
+#endif
+#ifdef NOISY
+ BIO_puts(out," pri 1=");
+ BN_print(out,a->priv_key);
+ BIO_puts(out,"\n pub 1=");
+ BN_print(out,x_a);
+ BIO_puts(out,",");
+ BN_print(out,y_a);
+ BIO_puts(out,"\n");
+#else
+ BIO_printf(out," .");
+ (void)BIO_flush(out);
+#endif
+
+ if (!EC_KEY_generate_key(b)) goto err;
+
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
+ {
+ if (!EC_POINT_get_affine_coordinates_GFp(group,
+ EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
+ }
+#ifndef OPENSSL_NO_EC2M
+ else
+ {
+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
+ EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
+ }
+#endif
+
+#ifdef NOISY
+ BIO_puts(out," pri 2=");
+ BN_print(out,b->priv_key);
+ BIO_puts(out,"\n pub 2=");
+ BN_print(out,x_b);
+ BIO_puts(out,",");
+ BN_print(out,y_b);
+ BIO_puts(out,"\n");
+#else
+ BIO_printf(out,".");
+ (void)BIO_flush(out);
+#endif
+
+ alen=KDF1_SHA1_len;
+ abuf=(unsigned char *)OPENSSL_malloc(alen);
+ aout=ECDH_compute_key(abuf,alen,EC_KEY_get0_public_key(b),a,KDF1_SHA1);
+
+#ifdef NOISY
+ BIO_puts(out," key1 =");
+ for (i=0; i<aout; i++)
+ {
+ sprintf(buf,"%02X",abuf[i]);
+ BIO_puts(out,buf);
+ }
+ BIO_puts(out,"\n");
+#else
+ BIO_printf(out,".");
+ (void)BIO_flush(out);
+#endif
+
+ blen=KDF1_SHA1_len;
+ bbuf=(unsigned char *)OPENSSL_malloc(blen);
+ bout=ECDH_compute_key(bbuf,blen,EC_KEY_get0_public_key(a),b,KDF1_SHA1);
+
+#ifdef NOISY
+ BIO_puts(out," key2 =");
+ for (i=0; i<bout; i++)
+ {
+ sprintf(buf,"%02X",bbuf[i]);
+ BIO_puts(out,buf);
+ }
+ BIO_puts(out,"\n");
+#else
+ BIO_printf(out,".");
+ (void)BIO_flush(out);
+#endif
+
+ if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0))
+ {
+#ifndef NOISY
+ BIO_printf(out, " failed\n\n");
+ BIO_printf(out, "key a:\n");
+ BIO_printf(out, "private key: ");
+ BN_print(out, EC_KEY_get0_private_key(a));
+ BIO_printf(out, "\n");
+ BIO_printf(out, "public key (x,y): ");
+ BN_print(out, x_a);
+ BIO_printf(out, ",");
+ BN_print(out, y_a);
+ BIO_printf(out, "\nkey b:\n");
+ BIO_printf(out, "private key: ");
+ BN_print(out, EC_KEY_get0_private_key(b));
+ BIO_printf(out, "\n");
+ BIO_printf(out, "public key (x,y): ");
+ BN_print(out, x_b);
+ BIO_printf(out, ",");
+ BN_print(out, y_b);
+ BIO_printf(out, "\n");
+ BIO_printf(out, "generated key a: ");
+ for (i=0; i<bout; i++)
+ {
+ sprintf(buf, "%02X", bbuf[i]);
+ BIO_puts(out, buf);
+ }
+ BIO_printf(out, "\n");
+ BIO_printf(out, "generated key b: ");
+ for (i=0; i<aout; i++)
+ {
+ sprintf(buf, "%02X", abuf[i]);
+ BIO_puts(out,buf);
+ }
+ BIO_printf(out, "\n");
+#endif
+ fprintf(stderr,"Error in ECDH routines\n");
+ ret=0;
+ }
+ else
+ {
+#ifndef NOISY
+ BIO_printf(out, " ok\n");
+#endif
+ ret=1;
+ }
+err:
+ ERR_print_errors_fp(stderr);
+
+ if (abuf != NULL) OPENSSL_free(abuf);
+ if (bbuf != NULL) OPENSSL_free(bbuf);
+ if (x_a) BN_free(x_a);
+ if (y_a) BN_free(y_a);
+ if (x_b) BN_free(x_b);
+ if (y_b) BN_free(y_b);
+ if (b) EC_KEY_free(b);
+ if (a) EC_KEY_free(a);
+ return(ret);
+ }
+
+int main(int argc, char *argv[])
+ {
+ BN_CTX *ctx=NULL;
+ int ret=1;
+ BIO *out;
+
+ CRYPTO_malloc_debug_init();
+ CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+#ifdef OPENSSL_SYS_WIN32
+ CRYPTO_malloc_init();
+#endif
+
+ RAND_seed(rnd_seed, sizeof rnd_seed);
+
+ out=BIO_new(BIO_s_file());
+ if (out == NULL) EXIT(1);
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+ /* NIST PRIME CURVES TESTS */
+ if (!test_ecdh_curve(NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) goto err;
+#ifndef OPENSSL_NO_EC2M
+ /* NIST BINARY CURVES TESTS */
+ if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) goto err;
+ if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) goto err;
+#endif
+
+ ret = 0;
+
+err:
+ ERR_print_errors_fp(stderr);
+ if (ctx) BN_CTX_free(ctx);
+ BIO_free(out);
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+ CRYPTO_mem_leaks_fp(stderr);
+ EXIT(ret);
+ return(ret);
+ }
+
+#if 0
+static void MS_CALLBACK cb(int p, int n, void *arg)
+ {
+ char c='*';
+
+ if (p == 0) c='.';
+ if (p == 1) c='+';
+ if (p == 2) c='*';
+ if (p == 3) c='\n';
+ BIO_write((BIO *)arg,&c,1);
+ (void)BIO_flush((BIO *)arg);
+#ifdef LINT
+ p=n;
+#endif
+ }
+#endif
+#endif
diff --git a/deps/openssl/openssl/test/ecdsatest.c b/deps/openssl/openssl/test/ecdsatest.c
new file mode 100644
index 000000000..537bb3036
--- /dev/null
+++ b/deps/openssl/openssl/test/ecdsatest.c
@@ -0,0 +1,572 @@
+/* crypto/ecdsa/ecdsatest.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 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
+ * licensing@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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_ECDSA is defined */
+
+#ifdef OPENSSL_NO_ECDSA
+int main(int argc, char * argv[])
+ {
+ puts("Elliptic curves are disabled.");
+ return 0;
+ }
+#else
+
+#include <openssl/crypto.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/ecdsa.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+static const char rnd_seed[] = "string to make the random number generator "
+ "think it has entropy";
+
+/* declaration of the test functions */
+int x9_62_tests(BIO *);
+int x9_62_test_internal(BIO *out, int nid, const char *r, const char *s);
+int test_builtin(BIO *);
+
+/* functions to change the RAND_METHOD */
+int change_rand(void);
+int restore_rand(void);
+int fbytes(unsigned char *buf, int num);
+
+RAND_METHOD fake_rand;
+const RAND_METHOD *old_rand;
+
+int change_rand(void)
+ {
+ /* save old rand method */
+ if ((old_rand = RAND_get_rand_method()) == NULL)
+ return 0;
+
+ fake_rand.seed = old_rand->seed;
+ fake_rand.cleanup = old_rand->cleanup;
+ fake_rand.add = old_rand->add;
+ fake_rand.status = old_rand->status;
+ /* use own random function */
+ fake_rand.bytes = fbytes;
+ fake_rand.pseudorand = old_rand->bytes;
+ /* set new RAND_METHOD */
+ if (!RAND_set_rand_method(&fake_rand))
+ return 0;
+ return 1;
+ }
+
+int restore_rand(void)
+ {
+ if (!RAND_set_rand_method(old_rand))
+ return 0;
+ else
+ return 1;
+ }
+
+static int fbytes_counter = 0;
+static const char *numbers[8] = {
+ "651056770906015076056810763456358567190100156695615665659",
+ "6140507067065001063065065565667405560006161556565665656654",
+ "8763001015071075675010661307616710783570106710677817767166"
+ "71676178726717",
+ "7000000175690566466555057817571571075705015757757057795755"
+ "55657156756655",
+ "1275552191113212300012030439187146164646146646466749494799",
+ "1542725565216523985789236956265265265235675811949404040041",
+ "1456427555219115346513212300075341203043918714616464614664"
+ "64667494947990",
+ "1712787255652165239672857892369562652652652356758119494040"
+ "40041670216363"};
+
+int fbytes(unsigned char *buf, int num)
+ {
+ int ret;
+ BIGNUM *tmp = NULL;
+
+ if (fbytes_counter >= 8)
+ return 0;
+ tmp = BN_new();
+ if (!tmp)
+ return 0;
+ if (!BN_dec2bn(&tmp, numbers[fbytes_counter]))
+ {
+ BN_free(tmp);
+ return 0;
+ }
+ fbytes_counter ++;
+ if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf))
+ ret = 0;
+ else
+ ret = 1;
+ if (tmp)
+ BN_free(tmp);
+ return ret;
+ }
+
+/* some tests from the X9.62 draft */
+int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
+ {
+ int ret = 0;
+ const char message[] = "abc";
+ unsigned char digest[20];
+ unsigned int dgst_len = 0;
+ EVP_MD_CTX md_ctx;
+ EC_KEY *key = NULL;
+ ECDSA_SIG *signature = NULL;
+ BIGNUM *r = NULL, *s = NULL;
+
+ EVP_MD_CTX_init(&md_ctx);
+ /* get the message digest */
+ EVP_DigestInit(&md_ctx, EVP_ecdsa());
+ EVP_DigestUpdate(&md_ctx, (const void*)message, 3);
+ EVP_DigestFinal(&md_ctx, digest, &dgst_len);
+
+ BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
+ /* create the key */
+ if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
+ goto x962_int_err;
+ if (!EC_KEY_generate_key(key))
+ goto x962_int_err;
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* create the signature */
+ signature = ECDSA_do_sign(digest, 20, key);
+ if (signature == NULL)
+ goto x962_int_err;
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* compare the created signature with the expected signature */
+ if ((r = BN_new()) == NULL || (s = BN_new()) == NULL)
+ goto x962_int_err;
+ if (!BN_dec2bn(&r, r_in) ||
+ !BN_dec2bn(&s, s_in))
+ goto x962_int_err;
+ if (BN_cmp(signature->r ,r) || BN_cmp(signature->s, s))
+ goto x962_int_err;
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* verify the signature */
+ if (ECDSA_do_verify(digest, 20, signature, key) != 1)
+ goto x962_int_err;
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+
+ BIO_printf(out, " ok\n");
+ ret = 1;
+x962_int_err:
+ if (!ret)
+ BIO_printf(out, " failed\n");
+ if (key)
+ EC_KEY_free(key);
+ if (signature)
+ ECDSA_SIG_free(signature);
+ if (r)
+ BN_free(r);
+ if (s)
+ BN_free(s);
+ EVP_MD_CTX_cleanup(&md_ctx);
+ return ret;
+ }
+
+int x9_62_tests(BIO *out)
+ {
+ int ret = 0;
+
+ BIO_printf(out, "some tests from X9.62:\n");
+
+ /* set own rand method */
+ if (!change_rand())
+ goto x962_err;
+
+ if (!x9_62_test_internal(out, NID_X9_62_prime192v1,
+ "3342403536405981729393488334694600415596881826869351677613",
+ "5735822328888155254683894997897571951568553642892029982342"))
+ goto x962_err;
+ if (!x9_62_test_internal(out, NID_X9_62_prime239v1,
+ "3086361431751678114926225473006680188549593787585317781474"
+ "62058306432176",
+ "3238135532097973577080787768312505059318910517550078427819"
+ "78505179448783"))
+ goto x962_err;
+#ifndef OPENSSL_NO_EC2M
+ if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1,
+ "87194383164871543355722284926904419997237591535066528048",
+ "308992691965804947361541664549085895292153777025772063598"))
+ goto x962_err;
+ if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1,
+ "2159633321041961198501834003903461262881815148684178964245"
+ "5876922391552",
+ "1970303740007316867383349976549972270528498040721988191026"
+ "49413465737174"))
+ goto x962_err;
+#endif
+ ret = 1;
+x962_err:
+ if (!restore_rand())
+ ret = 0;
+ return ret;
+ }
+
+int test_builtin(BIO *out)
+ {
+ EC_builtin_curve *curves = NULL;
+ size_t crv_len = 0, n = 0;
+ EC_KEY *eckey = NULL, *wrong_eckey = NULL;
+ EC_GROUP *group;
+ ECDSA_SIG *ecdsa_sig = NULL;
+ unsigned char digest[20], wrong_digest[20];
+ unsigned char *signature = NULL;
+ const unsigned char *sig_ptr;
+ unsigned char *sig_ptr2;
+ unsigned char *raw_buf = NULL;
+ unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
+ int nid, ret = 0;
+
+ /* fill digest values with some random data */
+ if (!RAND_pseudo_bytes(digest, 20) ||
+ !RAND_pseudo_bytes(wrong_digest, 20))
+ {
+ BIO_printf(out, "ERROR: unable to get random data\n");
+ goto builtin_err;
+ }
+
+ /* create and verify a ecdsa signature with every availble curve
+ * (with ) */
+ BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() "
+ "with some internal curves:\n");
+
+ /* get a list of all internal curves */
+ crv_len = EC_get_builtin_curves(NULL, 0);
+
+ curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
+
+ if (curves == NULL)
+ {
+ BIO_printf(out, "malloc error\n");
+ goto builtin_err;
+ }
+
+ if (!EC_get_builtin_curves(curves, crv_len))
+ {
+ BIO_printf(out, "unable to get internal curves\n");
+ goto builtin_err;
+ }
+
+ /* now create and verify a signature for every curve */
+ for (n = 0; n < crv_len; n++)
+ {
+ unsigned char dirt, offset;
+
+ nid = curves[n].nid;
+ if (nid == NID_ipsec4)
+ continue;
+ /* create new ecdsa key (== EC_KEY) */
+ if ((eckey = EC_KEY_new()) == NULL)
+ goto builtin_err;
+ group = EC_GROUP_new_by_curve_name(nid);
+ if (group == NULL)
+ goto builtin_err;
+ if (EC_KEY_set_group(eckey, group) == 0)
+ goto builtin_err;
+ EC_GROUP_free(group);
+ degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
+ if (degree < 160)
+ /* drop the curve */
+ {
+ EC_KEY_free(eckey);
+ eckey = NULL;
+ continue;
+ }
+ BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
+ /* create key */
+ if (!EC_KEY_generate_key(eckey))
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ /* create second key */
+ if ((wrong_eckey = EC_KEY_new()) == NULL)
+ goto builtin_err;
+ group = EC_GROUP_new_by_curve_name(nid);
+ if (group == NULL)
+ goto builtin_err;
+ if (EC_KEY_set_group(wrong_eckey, group) == 0)
+ goto builtin_err;
+ EC_GROUP_free(group);
+ if (!EC_KEY_generate_key(wrong_eckey))
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* check key */
+ if (!EC_KEY_check_key(eckey))
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* create signature */
+ sig_len = ECDSA_size(eckey);
+ if ((signature = OPENSSL_malloc(sig_len)) == NULL)
+ goto builtin_err;
+ if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey))
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* verify signature */
+ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* verify signature with the wrong key */
+ if (ECDSA_verify(0, digest, 20, signature, sig_len,
+ wrong_eckey) == 1)
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* wrong digest */
+ if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len,
+ eckey) == 1)
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* wrong length */
+ if (ECDSA_verify(0, digest, 20, signature, sig_len - 1,
+ eckey) == 1)
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+
+ /* Modify a single byte of the signature: to ensure we don't
+ * garble the ASN1 structure, we read the raw signature and
+ * modify a byte in one of the bignums directly. */
+ sig_ptr = signature;
+ if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL)
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+
+ /* Store the two BIGNUMs in raw_buf. */
+ r_len = BN_num_bytes(ecdsa_sig->r);
+ s_len = BN_num_bytes(ecdsa_sig->s);
+ bn_len = (degree + 7) / 8;
+ if ((r_len > bn_len) || (s_len > bn_len))
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ buf_len = 2 * bn_len;
+ if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL)
+ goto builtin_err;
+ /* Pad the bignums with leading zeroes. */
+ memset(raw_buf, 0, buf_len);
+ BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
+ BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);
+
+ /* Modify a single byte in the buffer. */
+ offset = raw_buf[10] % buf_len;
+ dirt = raw_buf[11] ? raw_buf[11] : 1;
+ raw_buf[offset] ^= dirt;
+ /* Now read the BIGNUMs back in from raw_buf. */
+ if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
+ (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
+ goto builtin_err;
+
+ sig_ptr2 = signature;
+ sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
+ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ /* Sanity check: undo the modification and verify signature. */
+ raw_buf[offset] ^= dirt;
+ if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
+ (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
+ goto builtin_err;
+
+ sig_ptr2 = signature;
+ sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
+ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+
+ BIO_printf(out, " ok\n");
+ /* cleanup */
+ /* clean bogus errors */
+ ERR_clear_error();
+ OPENSSL_free(signature);
+ signature = NULL;
+ EC_KEY_free(eckey);
+ eckey = NULL;
+ EC_KEY_free(wrong_eckey);
+ wrong_eckey = NULL;
+ ECDSA_SIG_free(ecdsa_sig);
+ ecdsa_sig = NULL;
+ OPENSSL_free(raw_buf);
+ raw_buf = NULL;
+ }
+
+ ret = 1;
+builtin_err:
+ if (eckey)
+ EC_KEY_free(eckey);
+ if (wrong_eckey)
+ EC_KEY_free(wrong_eckey);
+ if (ecdsa_sig)
+ ECDSA_SIG_free(ecdsa_sig);
+ if (signature)
+ OPENSSL_free(signature);
+ if (raw_buf)
+ OPENSSL_free(raw_buf);
+ if (curves)
+ OPENSSL_free(curves);
+
+ return ret;
+ }
+
+int main(void)
+ {
+ int ret = 1;
+ BIO *out;
+
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+ /* enable memory leak checking unless explicitly disabled */
+ if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) &&
+ (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
+ {
+ CRYPTO_malloc_debug_init();
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+ }
+ else
+ {
+ /* OPENSSL_DEBUG_MEMORY=off */
+ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+ }
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ ERR_load_crypto_strings();
+
+ /* initialize the prng */
+ RAND_seed(rnd_seed, sizeof(rnd_seed));
+
+ /* the tests */
+ if (!x9_62_tests(out)) goto err;
+ if (!test_builtin(out)) goto err;
+
+ ret = 0;
+err:
+ if (ret)
+ BIO_printf(out, "\nECDSA test failed\n");
+ else
+ BIO_printf(out, "\nECDSA test passed\n");
+ if (ret)
+ ERR_print_errors(out);
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+ ERR_free_strings();
+ CRYPTO_mem_leaks(out);
+ if (out != NULL)
+ BIO_free(out);
+ return ret;
+ }
+#endif
diff --git a/deps/openssl/openssl/test/ectest.c b/deps/openssl/openssl/test/ectest.c
new file mode 100644
index 000000000..102eaa9b2
--- /dev/null
+++ b/deps/openssl/openssl/test/ectest.c
@@ -0,0 +1,1489 @@
+/* crypto/ec/ectest.c */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef FLAT_INC
+#include "e_os.h"
+#else
+#include "../e_os.h"
+#endif
+#include <string.h>
+#include <time.h>
+
+
+#ifdef OPENSSL_NO_EC
+int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); return 0; }
+#else
+
+
+#include <openssl/ec.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/opensslconf.h>
+
+#if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
+/* suppress "too big too optimize" warning */
+#pragma warning(disable:4959)
+#endif
+
+#define ABORT do { \
+ fflush(stdout); \
+ fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
+ ERR_print_errors_fp(stderr); \
+ EXIT(1); \
+} while (0)
+
+#define TIMING_BASE_PT 0
+#define TIMING_RAND_PT 1
+#define TIMING_SIMUL 2
+
+#if 0
+static void timings(EC_GROUP *group, int type, BN_CTX *ctx)
+ {
+ clock_t clck;
+ int i, j;
+ BIGNUM *s;
+ BIGNUM *r[10], *r0[10];
+ EC_POINT *P;
+
+ s = BN_new();
+ if (s == NULL) ABORT;
+
+ fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group));
+ if (!EC_GROUP_get_order(group, s, ctx)) ABORT;
+ fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s));
+ fflush(stdout);
+
+ P = EC_POINT_new(group);
+ if (P == NULL) ABORT;
+ EC_POINT_copy(P, EC_GROUP_get0_generator(group));
+
+ for (i = 0; i < 10; i++)
+ {
+ if ((r[i] = BN_new()) == NULL) ABORT;
+ if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0)) ABORT;
+ if (type != TIMING_BASE_PT)
+ {
+ if ((r0[i] = BN_new()) == NULL) ABORT;
+ if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0)) ABORT;
+ }
+ }
+
+ clck = clock();
+ for (i = 0; i < 10; i++)
+ {
+ for (j = 0; j < 10; j++)
+ {
+ if (!EC_POINT_mul(group, P, (type != TIMING_RAND_PT) ? r[i] : NULL,
+ (type != TIMING_BASE_PT) ? P : NULL, (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx)) ABORT;
+ }
+ }
+ clck = clock() - clck;
+
+ fprintf(stdout, "\n");
+
+#ifdef CLOCKS_PER_SEC
+ /* "To determine the time in seconds, the value returned
+ * by the clock function should be divided by the value
+ * of the macro CLOCKS_PER_SEC."
+ * -- ISO/IEC 9899 */
+# define UNIT "s"
+#else
+ /* "`CLOCKS_PER_SEC' undeclared (first use this function)"
+ * -- cc on NeXTstep/OpenStep */
+# define UNIT "units"
+# define CLOCKS_PER_SEC 1
+#endif
+
+ if (type == TIMING_BASE_PT) {
+ fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
+ "base point multiplications", (double)clck/CLOCKS_PER_SEC);
+ } else if (type == TIMING_RAND_PT) {
+ fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
+ "random point multiplications", (double)clck/CLOCKS_PER_SEC);
+ } else if (type == TIMING_SIMUL) {
+ fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
+ "s*P+t*Q operations", (double)clck/CLOCKS_PER_SEC);
+ }
+ fprintf(stdout, "average: %.4f " UNIT "\n", (double)clck/(CLOCKS_PER_SEC*i*j));
+
+ EC_POINT_free(P);
+ BN_free(s);
+ for (i = 0; i < 10; i++)
+ {
+ BN_free(r[i]);
+ if (type != TIMING_BASE_PT) BN_free(r0[i]);
+ }
+ }
+#endif
+
+/* test multiplication with group order, long and negative scalars */
+static void group_order_tests(EC_GROUP *group)
+ {
+ BIGNUM *n1, *n2, *order;
+ EC_POINT *P = EC_POINT_new(group);
+ EC_POINT *Q = EC_POINT_new(group);
+ BN_CTX *ctx = BN_CTX_new();
+
+ n1 = BN_new(); n2 = BN_new(); order = BN_new();
+ fprintf(stdout, "verify group order ...");
+ fflush(stdout);
+ if (!EC_GROUP_get_order(group, order, ctx)) ABORT;
+ if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+ fprintf(stdout, ".");
+ fflush(stdout);
+ if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
+ if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+ fprintf(stdout, " ok\n");
+ fprintf(stdout, "long/negative scalar tests ... ");
+ if (!BN_one(n1)) ABORT;
+ /* n1 = 1 - order */
+ if (!BN_sub(n1, n1, order)) ABORT;
+ if(!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
+ /* n2 = 1 + order */
+ if (!BN_add(n2, order, BN_value_one())) ABORT;
+ if(!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
+ /* n2 = (1 - order) * (1 + order) */
+ if (!BN_mul(n2, n1, n2, ctx)) ABORT;
+ if(!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
+ fprintf(stdout, "ok\n");
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ BN_free(n1);
+ BN_free(n2);
+ BN_free(order);
+ BN_CTX_free(ctx);
+ }
+
+static void prime_field_tests(void)
+ {
+ BN_CTX *ctx = NULL;
+ BIGNUM *p, *a, *b;
+ EC_GROUP *group;
+ EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
+ EC_POINT *P, *Q, *R;
+ BIGNUM *x, *y, *z;
+ unsigned char buf[100];
+ size_t i, len;
+ int k;
+
+#if 1 /* optional */
+ ctx = BN_CTX_new();
+ if (!ctx) ABORT;
+#endif
+
+ p = BN_new();
+ a = BN_new();
+ b = BN_new();
+ if (!p || !a || !b) ABORT;
+
+ if (!BN_hex2bn(&p, "17")) ABORT;
+ if (!BN_hex2bn(&a, "1")) ABORT;
+ if (!BN_hex2bn(&b, "1")) ABORT;
+
+ group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
+ * so that the library gets to choose the EC_METHOD */
+ if (!group) ABORT;
+
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+ {
+ EC_GROUP *tmp;
+ tmp = EC_GROUP_new(EC_GROUP_method_of(group));
+ if (!tmp) ABORT;
+ if (!EC_GROUP_copy(tmp, group)) ABORT;
+ EC_GROUP_free(group);
+ group = tmp;
+ }
+
+ if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+ fprintf(stdout, "Curve defined by Weierstrass equation\n y^2 = x^3 + a*x + b (mod 0x");
+ BN_print_fp(stdout, p);
+ fprintf(stdout, ")\n a = 0x");
+ BN_print_fp(stdout, a);
+ fprintf(stdout, "\n b = 0x");
+ BN_print_fp(stdout, b);
+ fprintf(stdout, "\n");
+
+ P = EC_POINT_new(group);
+ Q = EC_POINT_new(group);
+ R = EC_POINT_new(group);
+ if (!P || !Q || !R) ABORT;
+
+ if (!EC_POINT_set_to_infinity(group, P)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+ buf[0] = 0;
+ if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
+
+ if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+ x = BN_new();
+ y = BN_new();
+ z = BN_new();
+ if (!x || !y || !z) ABORT;
+
+ if (!BN_hex2bn(&x, "D")) ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
+ if (!EC_POINT_is_on_curve(group, Q, ctx))
+ {
+ if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
+ fprintf(stderr, "Point is not on curve: x = 0x");
+ BN_print_fp(stderr, x);
+ fprintf(stderr, ", y = 0x");
+ BN_print_fp(stderr, y);
+ fprintf(stderr, "\n");
+ ABORT;
+ }
+
+ fprintf(stdout, "A cyclic subgroup:\n");
+ k = 100;
+ do
+ {
+ if (k-- == 0) ABORT;
+
+ if (EC_POINT_is_at_infinity(group, P))
+ fprintf(stdout, " point at infinity\n");
+ else
+ {
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+
+ fprintf(stdout, " x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, ", y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ }
+
+ if (!EC_POINT_copy(R, P)) ABORT;
+ if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
+
+#if 0 /* optional */
+ {
+ EC_POINT *points[3];
+
+ points[0] = R;
+ points[1] = Q;
+ points[2] = P;
+ if (!EC_POINTs_make_affine(group, 2, points, ctx)) ABORT;
+ }
+#endif
+
+ }
+ while (!EC_POINT_is_at_infinity(group, P));
+
+ if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+ len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
+ if (len == 0) ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+ fprintf(stdout, "Generator as octet string, compressed form:\n ");
+ for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+
+ len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
+ if (len == 0) ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+ fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n ");
+ for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+
+ len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
+ if (len == 0) ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+ fprintf(stdout, "\nGenerator as octet string, hybrid form:\n ");
+ for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+
+ if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
+ fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n X = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, ", Y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, ", Z = 0x");
+ BN_print_fp(stdout, z);
+ fprintf(stdout, "\n");
+
+ if (!EC_POINT_invert(group, P, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
+
+
+ /* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000)
+ * -- not a NIST curve, but commonly used */
+
+ if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+ if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) ABORT;
+ if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+ if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT;
+ if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
+ if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+ fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
+ if (0 != BN_cmp(y, z)) ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 160) ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+ if (!EC_GROUP_copy(P_160, group)) ABORT;
+
+
+ /* Curve P-192 (FIPS PUB 186-2, App. 6) */
+
+ if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+ if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) ABORT;
+ if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+ if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+ fprintf(stdout, "\nNIST curve P-192 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) ABORT;
+ if (0 != BN_cmp(y, z)) ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 192) ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+ if (!EC_GROUP_copy(P_192, group)) ABORT;
+
+
+ /* Curve P-224 (FIPS PUB 186-2, App. 6) */
+
+ if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+ if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
+ if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+ if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+ fprintf(stdout, "\nNIST curve P-224 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
+ if (0 != BN_cmp(y, z)) ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 224) ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+ if (!EC_GROUP_copy(P_224, group)) ABORT;
+
+
+ /* Curve P-256 (FIPS PUB 186-2, App. 6) */
+
+ if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+ if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
+ if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+ if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
+ "84F3B9CAC2FC632551")) ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+ fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) ABORT;
+ if (0 != BN_cmp(y, z)) ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 256) ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+ if (!EC_GROUP_copy(P_256, group)) ABORT;
+
+
+ /* Curve P-384 (FIPS PUB 186-2, App. 6) */
+
+ if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+ if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT;
+ if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
+ "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+ if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
+ "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+ fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
+ "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT;
+ if (0 != BN_cmp(y, z)) ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 384) ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+ if (!EC_GROUP_copy(P_384, group)) ABORT;
+
+
+ /* Curve P-521 (FIPS PUB 186-2, App. 6) */
+
+ if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+ if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
+ if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
+ "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
+ "DF883D2C34F1EF451FD46B503F00")) ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+ if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
+ "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
+ "3C1856A429BF97E7E31C2E5BD66")) ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
+ "C9B8899C47AEBB6FB71E91386409")) ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+ fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
+ "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
+ "7086A272C24088BE94769FD16650")) ABORT;
+ if (0 != BN_cmp(y, z)) ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 521) ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+ if (!EC_GROUP_copy(P_521, group)) ABORT;
+
+
+ /* more tests using the last curve */
+
+ if (!EC_POINT_copy(Q, P)) ABORT;
+ if (EC_POINT_is_at_infinity(group, Q)) ABORT;
+ if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
+
+ if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
+ if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
+
+ {
+ const EC_POINT *points[4];
+ const BIGNUM *scalars[4];
+ BIGNUM scalar3;
+
+ if (EC_POINT_is_at_infinity(group, Q)) ABORT;
+ points[0] = Q;
+ points[1] = Q;
+ points[2] = Q;
+ points[3] = Q;
+
+ if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
+ if (!BN_add(y, z, BN_value_one())) ABORT;
+ if (BN_is_odd(y)) ABORT;
+ if (!BN_rshift1(y, y)) ABORT;
+ scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
+ scalars[1] = y;
+
+ fprintf(stdout, "combined multiplication ...");
+ fflush(stdout);
+
+ /* z is still the group order */
+ if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
+ if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
+
+ fprintf(stdout, ".");
+ fflush(stdout);
+
+ if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
+ if (!BN_add(z, z, y)) ABORT;
+ BN_set_negative(z, 1);
+ scalars[0] = y;
+ scalars[1] = z; /* z = -(order + y) */
+
+ if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+ fprintf(stdout, ".");
+ fflush(stdout);
+
+ if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
+ if (!BN_add(z, x, y)) ABORT;
+ BN_set_negative(z, 1);
+ scalars[0] = x;
+ scalars[1] = y;
+ scalars[2] = z; /* z = -(x+y) */
+
+ BN_init(&scalar3);
+ BN_zero(&scalar3);
+ scalars[3] = &scalar3;
+
+ if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+ fprintf(stdout, " ok\n\n");
+
+ BN_free(&scalar3);
+ }
+
+
+#if 0
+ timings(P_160, TIMING_BASE_PT, ctx);
+ timings(P_160, TIMING_RAND_PT, ctx);
+ timings(P_160, TIMING_SIMUL, ctx);
+ timings(P_192, TIMING_BASE_PT, ctx);
+ timings(P_192, TIMING_RAND_PT, ctx);
+ timings(P_192, TIMING_SIMUL, ctx);
+ timings(P_224, TIMING_BASE_PT, ctx);
+ timings(P_224, TIMING_RAND_PT, ctx);
+ timings(P_224, TIMING_SIMUL, ctx);
+ timings(P_256, TIMING_BASE_PT, ctx);
+ timings(P_256, TIMING_RAND_PT, ctx);
+ timings(P_256, TIMING_SIMUL, ctx);
+ timings(P_384, TIMING_BASE_PT, ctx);
+ timings(P_384, TIMING_RAND_PT, ctx);
+ timings(P_384, TIMING_SIMUL, ctx);
+ timings(P_521, TIMING_BASE_PT, ctx);
+ timings(P_521, TIMING_RAND_PT, ctx);
+ timings(P_521, TIMING_SIMUL, ctx);
+#endif
+
+
+ if (ctx)
+ BN_CTX_free(ctx);
+ BN_free(p); BN_free(a); BN_free(b);
+ EC_GROUP_free(group);
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ EC_POINT_free(R);
+ BN_free(x); BN_free(y); BN_free(z);
+
+ if (P_160) EC_GROUP_free(P_160);
+ if (P_192) EC_GROUP_free(P_192);
+ if (P_224) EC_GROUP_free(P_224);
+ if (P_256) EC_GROUP_free(P_256);
+ if (P_384) EC_GROUP_free(P_384);
+ if (P_521) EC_GROUP_free(P_521);
+
+ }
+
+/* Change test based on whether binary point compression is enabled or not. */
+#ifdef OPENSSL_EC_BIN_PT_COMP
+#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+ if (!BN_hex2bn(&x, _x)) ABORT; \
+ if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
+ if (!BN_hex2bn(&z, _order)) ABORT; \
+ if (!BN_hex2bn(&cof, _cof)) ABORT; \
+ if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
+ fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \
+ BN_print_fp(stdout, x); \
+ fprintf(stdout, "\n y = 0x"); \
+ BN_print_fp(stdout, y); \
+ fprintf(stdout, "\n"); \
+ /* G_y value taken from the standard: */ \
+ if (!BN_hex2bn(&z, _y)) ABORT; \
+ if (0 != BN_cmp(y, z)) ABORT;
+#else
+#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+ if (!BN_hex2bn(&x, _x)) ABORT; \
+ if (!BN_hex2bn(&y, _y)) ABORT; \
+ if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
+ if (!BN_hex2bn(&z, _order)) ABORT; \
+ if (!BN_hex2bn(&cof, _cof)) ABORT; \
+ if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
+ fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \
+ BN_print_fp(stdout, x); \
+ fprintf(stdout, "\n y = 0x"); \
+ BN_print_fp(stdout, y); \
+ fprintf(stdout, "\n");
+#endif
+
+#define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+ if (!BN_hex2bn(&p, _p)) ABORT; \
+ if (!BN_hex2bn(&a, _a)) ABORT; \
+ if (!BN_hex2bn(&b, _b)) ABORT; \
+ if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \
+ CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+ fprintf(stdout, "verify degree ..."); \
+ if (EC_GROUP_get_degree(group) != _degree) ABORT; \
+ fprintf(stdout, " ok\n"); \
+ group_order_tests(group); \
+ if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
+ if (!EC_GROUP_copy(_variable, group)) ABORT; \
+
+#ifndef OPENSSL_NO_EC2M
+
+static void char2_field_tests(void)
+ {
+ BN_CTX *ctx = NULL;
+ BIGNUM *p, *a, *b;
+ EC_GROUP *group;
+ EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = NULL, *C2_K571 = NULL;
+ EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = NULL, *C2_B571 = NULL;
+ EC_POINT *P, *Q, *R;
+ BIGNUM *x, *y, *z, *cof;
+ unsigned char buf[100];
+ size_t i, len;
+ int k;
+
+#if 1 /* optional */
+ ctx = BN_CTX_new();
+ if (!ctx) ABORT;
+#endif
+
+ p = BN_new();
+ a = BN_new();
+ b = BN_new();
+ if (!p || !a || !b) ABORT;
+
+ if (!BN_hex2bn(&p, "13")) ABORT;
+ if (!BN_hex2bn(&a, "3")) ABORT;
+ if (!BN_hex2bn(&b, "1")) ABORT;
+
+ group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use EC_GROUP_new_curve_GF2m
+ * so that the library gets to choose the EC_METHOD */
+ if (!group) ABORT;
+ if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT;
+
+ {
+ EC_GROUP *tmp;
+ tmp = EC_GROUP_new(EC_GROUP_method_of(group));
+ if (!tmp) ABORT;
+ if (!EC_GROUP_copy(tmp, group)) ABORT;
+ EC_GROUP_free(group);
+ group = tmp;
+ }
+
+ if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) ABORT;
+
+ fprintf(stdout, "Curve defined by Weierstrass equation\n y^2 + x*y = x^3 + a*x^2 + b (mod 0x");
+ BN_print_fp(stdout, p);
+ fprintf(stdout, ")\n a = 0x");
+ BN_print_fp(stdout, a);
+ fprintf(stdout, "\n b = 0x");
+ BN_print_fp(stdout, b);
+ fprintf(stdout, "\n(0x... means binary polynomial)\n");
+
+ P = EC_POINT_new(group);
+ Q = EC_POINT_new(group);
+ R = EC_POINT_new(group);
+ if (!P || !Q || !R) ABORT;
+
+ if (!EC_POINT_set_to_infinity(group, P)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+ buf[0] = 0;
+ if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
+
+ if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+ x = BN_new();
+ y = BN_new();
+ z = BN_new();
+ cof = BN_new();
+ if (!x || !y || !z || !cof) ABORT;
+
+ if (!BN_hex2bn(&x, "6")) ABORT;
+/* Change test based on whether binary point compression is enabled or not. */
+#ifdef OPENSSL_EC_BIN_PT_COMP
+ if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) ABORT;
+#else
+ if (!BN_hex2bn(&y, "8")) ABORT;
+ if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
+#endif
+ if (!EC_POINT_is_on_curve(group, Q, ctx))
+ {
+/* Change test based on whether binary point compression is enabled or not. */
+#ifdef OPENSSL_EC_BIN_PT_COMP
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
+#endif
+ fprintf(stderr, "Point is not on curve: x = 0x");
+ BN_print_fp(stderr, x);
+ fprintf(stderr, ", y = 0x");
+ BN_print_fp(stderr, y);
+ fprintf(stderr, "\n");
+ ABORT;
+ }
+
+ fprintf(stdout, "A cyclic subgroup:\n");
+ k = 100;
+ do
+ {
+ if (k-- == 0) ABORT;
+
+ if (EC_POINT_is_at_infinity(group, P))
+ fprintf(stdout, " point at infinity\n");
+ else
+ {
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT;
+
+ fprintf(stdout, " x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, ", y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ }
+
+ if (!EC_POINT_copy(R, P)) ABORT;
+ if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
+ }
+ while (!EC_POINT_is_at_infinity(group, P));
+
+ if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+/* Change test based on whether binary point compression is enabled or not. */
+#ifdef OPENSSL_EC_BIN_PT_COMP
+ len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
+ if (len == 0) ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+ fprintf(stdout, "Generator as octet string, compressed form:\n ");
+ for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+#endif
+
+ len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
+ if (len == 0) ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+ fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n ");
+ for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+
+/* Change test based on whether binary point compression is enabled or not. */
+#ifdef OPENSSL_EC_BIN_PT_COMP
+ len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
+ if (len == 0) ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+ fprintf(stdout, "\nGenerator as octet string, hybrid form:\n ");
+ for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+#endif
+
+ fprintf(stdout, "\n");
+
+ if (!EC_POINT_invert(group, P, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
+
+
+ /* Curve K-163 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ (
+ "NIST curve K-163",
+ "0800000000000000000000000000000000000000C9",
+ "1",
+ "1",
+ "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
+ "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
+ 1,
+ "04000000000000000000020108A2E0CC0D99F8A5EF",
+ "2",
+ 163,
+ C2_K163
+ );
+
+ /* Curve B-163 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ (
+ "NIST curve B-163",
+ "0800000000000000000000000000000000000000C9",
+ "1",
+ "020A601907B8C953CA1481EB10512F78744A3205FD",
+ "03F0EBA16286A2D57EA0991168D4994637E8343E36",
+ "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
+ 1,
+ "040000000000000000000292FE77E70C12A4234C33",
+ "2",
+ 163,
+ C2_B163
+ );
+
+ /* Curve K-233 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ (
+ "NIST curve K-233",
+ "020000000000000000000000000000000000000004000000000000000001",
+ "0",
+ "1",
+ "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
+ "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
+ 0,
+ "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
+ "4",
+ 233,
+ C2_K233
+ );
+
+ /* Curve B-233 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ (
+ "NIST curve B-233",
+ "020000000000000000000000000000000000000004000000000000000001",
+ "000000000000000000000000000000000000000000000000000000000001",
+ "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
+ "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
+ "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
+ 1,
+ "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
+ "2",
+ 233,
+ C2_B233
+ );
+
+ /* Curve K-283 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ (
+ "NIST curve K-283",
+ "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+ "0",
+ "1",
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
+ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
+ 0,
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
+ "4",
+ 283,
+ C2_K283
+ );
+
+ /* Curve B-283 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ (
+ "NIST curve B-283",
+ "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+ "000000000000000000000000000000000000000000000000000000000000000000000001",
+ "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
+ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
+ 1,
+ "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
+ "2",
+ 283,
+ C2_B283
+ );
+
+ /* Curve K-409 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ (
+ "NIST curve K-409",
+ "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+ "0",
+ "1",
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
+ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
+ 1,
+ "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
+ "4",
+ 409,
+ C2_K409
+ );
+
+ /* Curve B-409 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ (
+ "NIST curve B-409",
+ "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
+ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
+ 1,
+ "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
+ "2",
+ 409,
+ C2_B409
+ );
+
+ /* Curve K-571 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ (
+ "NIST curve K-571",
+ "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+ "0",
+ "1",
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
+ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
+ 0,
+ "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
+ "4",
+ 571,
+ C2_K571
+ );
+
+ /* Curve B-571 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ (
+ "NIST curve B-571",
+ "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
+ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
+ 1,
+ "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
+ "2",
+ 571,
+ C2_B571
+ );
+
+ /* more tests using the last curve */
+
+ if (!EC_POINT_copy(Q, P)) ABORT;
+ if (EC_POINT_is_at_infinity(group, Q)) ABORT;
+ if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
+
+ if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
+ if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
+
+ {
+ const EC_POINT *points[3];
+ const BIGNUM *scalars[3];
+
+ if (EC_POINT_is_at_infinity(group, Q)) ABORT;
+ points[0] = Q;
+ points[1] = Q;
+ points[2] = Q;
+
+ if (!BN_add(y, z, BN_value_one())) ABORT;
+ if (BN_is_odd(y)) ABORT;
+ if (!BN_rshift1(y, y)) ABORT;
+ scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
+ scalars[1] = y;
+
+ fprintf(stdout, "combined multiplication ...");
+ fflush(stdout);
+
+ /* z is still the group order */
+ if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
+ if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
+ if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
+
+ fprintf(stdout, ".");
+ fflush(stdout);
+
+ if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
+ if (!BN_add(z, z, y)) ABORT;
+ BN_set_negative(z, 1);
+ scalars[0] = y;
+ scalars[1] = z; /* z = -(order + y) */
+
+ if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+ fprintf(stdout, ".");
+ fflush(stdout);
+
+ if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
+ if (!BN_add(z, x, y)) ABORT;
+ BN_set_negative(z, 1);
+ scalars[0] = x;
+ scalars[1] = y;
+ scalars[2] = z; /* z = -(x+y) */
+
+ if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT;
+ if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+ fprintf(stdout, " ok\n\n");
+ }
+
+
+#if 0
+ timings(C2_K163, TIMING_BASE_PT, ctx);
+ timings(C2_K163, TIMING_RAND_PT, ctx);
+ timings(C2_K163, TIMING_SIMUL, ctx);
+ timings(C2_B163, TIMING_BASE_PT, ctx);
+ timings(C2_B163, TIMING_RAND_PT, ctx);
+ timings(C2_B163, TIMING_SIMUL, ctx);
+ timings(C2_K233, TIMING_BASE_PT, ctx);
+ timings(C2_K233, TIMING_RAND_PT, ctx);
+ timings(C2_K233, TIMING_SIMUL, ctx);
+ timings(C2_B233, TIMING_BASE_PT, ctx);
+ timings(C2_B233, TIMING_RAND_PT, ctx);
+ timings(C2_B233, TIMING_SIMUL, ctx);
+ timings(C2_K283, TIMING_BASE_PT, ctx);
+ timings(C2_K283, TIMING_RAND_PT, ctx);
+ timings(C2_K283, TIMING_SIMUL, ctx);
+ timings(C2_B283, TIMING_BASE_PT, ctx);
+ timings(C2_B283, TIMING_RAND_PT, ctx);
+ timings(C2_B283, TIMING_SIMUL, ctx);
+ timings(C2_K409, TIMING_BASE_PT, ctx);
+ timings(C2_K409, TIMING_RAND_PT, ctx);
+ timings(C2_K409, TIMING_SIMUL, ctx);
+ timings(C2_B409, TIMING_BASE_PT, ctx);
+ timings(C2_B409, TIMING_RAND_PT, ctx);
+ timings(C2_B409, TIMING_SIMUL, ctx);
+ timings(C2_K571, TIMING_BASE_PT, ctx);
+ timings(C2_K571, TIMING_RAND_PT, ctx);
+ timings(C2_K571, TIMING_SIMUL, ctx);
+ timings(C2_B571, TIMING_BASE_PT, ctx);
+ timings(C2_B571, TIMING_RAND_PT, ctx);
+ timings(C2_B571, TIMING_SIMUL, ctx);
+#endif
+
+
+ if (ctx)
+ BN_CTX_free(ctx);
+ BN_free(p); BN_free(a); BN_free(b);
+ EC_GROUP_free(group);
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ EC_POINT_free(R);
+ BN_free(x); BN_free(y); BN_free(z); BN_free(cof);
+
+ if (C2_K163) EC_GROUP_free(C2_K163);
+ if (C2_B163) EC_GROUP_free(C2_B163);
+ if (C2_K233) EC_GROUP_free(C2_K233);
+ if (C2_B233) EC_GROUP_free(C2_B233);
+ if (C2_K283) EC_GROUP_free(C2_K283);
+ if (C2_B283) EC_GROUP_free(C2_B283);
+ if (C2_K409) EC_GROUP_free(C2_K409);
+ if (C2_B409) EC_GROUP_free(C2_B409);
+ if (C2_K571) EC_GROUP_free(C2_K571);
+ if (C2_B571) EC_GROUP_free(C2_B571);
+
+ }
+#endif
+
+static void internal_curve_test(void)
+ {
+ EC_builtin_curve *curves = NULL;
+ size_t crv_len = 0, n = 0;
+ int ok = 1;
+
+ crv_len = EC_get_builtin_curves(NULL, 0);
+
+ curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
+
+ if (curves == NULL)
+ return;
+
+ if (!EC_get_builtin_curves(curves, crv_len))
+ {
+ OPENSSL_free(curves);
+ return;
+ }
+
+ fprintf(stdout, "testing internal curves: ");
+
+ for (n = 0; n < crv_len; n++)
+ {
+ EC_GROUP *group = NULL;
+ int nid = curves[n].nid;
+ if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL)
+ {
+ ok = 0;
+ fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with"
+ " curve %s\n", OBJ_nid2sn(nid));
+ /* try next curve */
+ continue;
+ }
+ if (!EC_GROUP_check(group, NULL))
+ {
+ ok = 0;
+ fprintf(stdout, "\nEC_GROUP_check() failed with"
+ " curve %s\n", OBJ_nid2sn(nid));
+ EC_GROUP_free(group);
+ /* try the next curve */
+ continue;
+ }
+ fprintf(stdout, ".");
+ fflush(stdout);
+ EC_GROUP_free(group);
+ }
+ if (ok)
+ fprintf(stdout, " ok\n\n");
+ else
+ {
+ fprintf(stdout, " failed\n\n");
+ ABORT;
+ }
+ OPENSSL_free(curves);
+ return;
+ }
+
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+/* nistp_test_params contains magic numbers for testing our optimized
+ * implementations of several NIST curves with characteristic > 3. */
+struct nistp_test_params
+ {
+ const EC_METHOD* (*meth) ();
+ int degree;
+ /* Qx, Qy and D are taken from
+ * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
+ * Otherwise, values are standard curve parameters from FIPS 180-3 */
+ const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
+ };
+
+static const struct nistp_test_params nistp_tests_params[] =
+ {
+ {
+ /* P-224 */
+ EC_GFp_nistp224_method,
+ 224,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* p */
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* a */
+ "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* b */
+ "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E", /* Qx */
+ "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555", /* Qy */
+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */
+ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */
+ "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8", /* d */
+ },
+ {
+ /* P-256 */
+ EC_GFp_nistp256_method,
+ 256,
+ "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", /* p */
+ "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", /* a */
+ "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", /* b */
+ "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", /* Qx */
+ "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", /* Qy */
+ "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", /* Gx */
+ "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", /* Gy */
+ "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", /* order */
+ "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", /* d */
+ },
+ {
+ /* P-521 */
+ EC_GFp_nistp521_method,
+ 521,
+ "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", /* p */
+ "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", /* a */
+ "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", /* b */
+ "0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", /* Qx */
+ "0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", /* Qy */
+ "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", /* Gx */
+ "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", /* Gy */
+ "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", /* order */
+ "0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", /* d */
+ },
+ };
+
+void nistp_single_test(const struct nistp_test_params *test)
+ {
+ BN_CTX *ctx;
+ BIGNUM *p, *a, *b, *x, *y, *n, *m, *order;
+ EC_GROUP *NISTP;
+ EC_POINT *G, *P, *Q, *Q_CHECK;
+
+ fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", test->degree);
+ ctx = BN_CTX_new();
+ p = BN_new();
+ a = BN_new();
+ b = BN_new();
+ x = BN_new(); y = BN_new();
+ m = BN_new(); n = BN_new(); order = BN_new();
+
+ NISTP = EC_GROUP_new(test->meth());
+ if(!NISTP) ABORT;
+ if (!BN_hex2bn(&p, test->p)) ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+ if (!BN_hex2bn(&a, test->a)) ABORT;
+ if (!BN_hex2bn(&b, test->b)) ABORT;
+ if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx)) ABORT;
+ G = EC_POINT_new(NISTP);
+ P = EC_POINT_new(NISTP);
+ Q = EC_POINT_new(NISTP);
+ Q_CHECK = EC_POINT_new(NISTP);
+ if(!BN_hex2bn(&x, test->Qx)) ABORT;
+ if(!BN_hex2bn(&y, test->Qy)) ABORT;
+ if(!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx)) ABORT;
+ if (!BN_hex2bn(&x, test->Gx)) ABORT;
+ if (!BN_hex2bn(&y, test->Gy)) ABORT;
+ if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx)) ABORT;
+ if (!BN_hex2bn(&order, test->order)) ABORT;
+ if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT;
+
+ fprintf(stdout, "verify degree ... ");
+ if (EC_GROUP_get_degree(NISTP) != test->degree) ABORT;
+ fprintf(stdout, "ok\n");
+
+ fprintf(stdout, "NIST test vectors ... ");
+ if (!BN_hex2bn(&n, test->d)) ABORT;
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+
+ /* set generator to P = 2*G, where G is the standard generator */
+ if (!EC_POINT_dbl(NISTP, P, G, ctx)) ABORT;
+ if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) ABORT;
+ /* set the scalar to m=n/2, where n is the NIST test scalar */
+ if (!BN_rshift(m, n, 1)) ABORT;
+
+ /* test the non-standard generator */
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+
+ /* now repeat all tests with precomputation */
+ if (!EC_GROUP_precompute_mult(NISTP, ctx)) ABORT;
+
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+
+ /* reset generator */
+ if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT;
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
+
+ fprintf(stdout, "ok\n");
+ group_order_tests(NISTP);
+#if 0
+ timings(NISTP, TIMING_BASE_PT, ctx);
+ timings(NISTP, TIMING_RAND_PT, ctx);
+#endif
+ EC_GROUP_free(NISTP);
+ EC_POINT_free(G);
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ EC_POINT_free(Q_CHECK);
+ BN_free(n);
+ BN_free(m);
+ BN_free(p);
+ BN_free(a);
+ BN_free(b);
+ BN_free(x);
+ BN_free(y);
+ BN_free(order);
+ BN_CTX_free(ctx);
+ }
+
+void nistp_tests()
+ {
+ unsigned i;
+
+ for (i = 0; i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params); i++)
+ {
+ nistp_single_test(&nistp_tests_params[i]);
+ }
+ }
+#endif
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int main(int argc, char *argv[])
+ {
+
+ /* enable memory leak checking unless explicitly disabled */
+ if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
+ {
+ CRYPTO_malloc_debug_init();
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+ }
+ else
+ {
+ /* OPENSSL_DEBUG_MEMORY=off */
+ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+ }
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+ ERR_load_crypto_strings();
+
+ RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
+
+ prime_field_tests();
+ puts("");
+#ifndef OPENSSL_NO_EC2M
+ char2_field_tests();
+#endif
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ nistp_tests();
+#endif
+ /* test the internal curves */
+ internal_curve_test();
+
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_cleanup();
+#endif
+ CRYPTO_cleanup_all_ex_data();
+ ERR_free_strings();
+ ERR_remove_thread_state(NULL);
+ CRYPTO_mem_leaks_fp(stderr);
+
+ return 0;
+ }
+#endif
diff --git a/deps/openssl/openssl/test/enginetest.c b/deps/openssl/openssl/test/enginetest.c
new file mode 100644
index 000000000..f4d70e7e0
--- /dev/null
+++ b/deps/openssl/openssl/test/enginetest.c
@@ -0,0 +1,283 @@
+/* crypto/engine/enginetest.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 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
+ * licensing@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).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/e_os2.h>
+
+#ifdef OPENSSL_NO_ENGINE
+int main(int argc, char *argv[])
+{
+ printf("No ENGINE support\n");
+ return(0);
+}
+#else
+#include <openssl/buffer.h>
+#include <openssl/crypto.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+
+static void display_engine_list(void)
+ {
+ ENGINE *h;
+ int loop;
+
+ h = ENGINE_get_first();
+ loop = 0;
+ printf("listing available engine types\n");
+ while(h)
+ {
+ printf("engine %i, id = \"%s\", name = \"%s\"\n",
+ loop++, ENGINE_get_id(h), ENGINE_get_name(h));
+ h = ENGINE_get_next(h);
+ }
+ printf("end of list\n");
+ /* ENGINE_get_first() increases the struct_ref counter, so we
+ must call ENGINE_free() to decrease it again */
+ ENGINE_free(h);
+ }
+
+int main(int argc, char *argv[])
+ {
+ ENGINE *block[512];
+ char buf[256];
+ const char *id, *name;
+ ENGINE *ptr;
+ int loop;
+ int to_return = 1;
+ ENGINE *new_h1 = NULL;
+ ENGINE *new_h2 = NULL;
+ ENGINE *new_h3 = NULL;
+ ENGINE *new_h4 = NULL;
+
+ /* enable memory leak checking unless explicitly disabled */
+ if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
+ {
+ CRYPTO_malloc_debug_init();
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+ }
+ else
+ {
+ /* OPENSSL_DEBUG_MEMORY=off */
+ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+ }
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+ ERR_load_crypto_strings();
+
+ memset(block, 0, 512 * sizeof(ENGINE *));
+ if(((new_h1 = ENGINE_new()) == NULL) ||
+ !ENGINE_set_id(new_h1, "test_id0") ||
+ !ENGINE_set_name(new_h1, "First test item") ||
+ ((new_h2 = ENGINE_new()) == NULL) ||
+ !ENGINE_set_id(new_h2, "test_id1") ||
+ !ENGINE_set_name(new_h2, "Second test item") ||
+ ((new_h3 = ENGINE_new()) == NULL) ||
+ !ENGINE_set_id(new_h3, "test_id2") ||
+ !ENGINE_set_name(new_h3, "Third test item") ||
+ ((new_h4 = ENGINE_new()) == NULL) ||
+ !ENGINE_set_id(new_h4, "test_id3") ||
+ !ENGINE_set_name(new_h4, "Fourth test item"))
+ {
+ printf("Couldn't set up test ENGINE structures\n");
+ goto end;
+ }
+ printf("\nenginetest beginning\n\n");
+ display_engine_list();
+ if(!ENGINE_add(new_h1))
+ {
+ printf("Add failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ ptr = ENGINE_get_first();
+ if(!ENGINE_remove(ptr))
+ {
+ printf("Remove failed!\n");
+ goto end;
+ }
+ if (ptr)
+ ENGINE_free(ptr);
+ display_engine_list();
+ if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2))
+ {
+ printf("Add failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ if(!ENGINE_remove(new_h2))
+ {
+ printf("Remove failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ if(!ENGINE_add(new_h4))
+ {
+ printf("Add failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ if(ENGINE_add(new_h3))
+ {
+ printf("Add *should* have failed but didn't!\n");
+ goto end;
+ }
+ else
+ printf("Add that should fail did.\n");
+ ERR_clear_error();
+ if(ENGINE_remove(new_h2))
+ {
+ printf("Remove *should* have failed but didn't!\n");
+ goto end;
+ }
+ else
+ printf("Remove that should fail did.\n");
+ ERR_clear_error();
+ if(!ENGINE_remove(new_h3))
+ {
+ printf("Remove failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ if(!ENGINE_remove(new_h4))
+ {
+ printf("Remove failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ /* Depending on whether there's any hardware support compiled
+ * in, this remove may be destined to fail. */
+ ptr = ENGINE_get_first();
+ if(ptr)
+ if(!ENGINE_remove(ptr))
+ printf("Remove failed!i - probably no hardware "
+ "support present.\n");
+ if (ptr)
+ ENGINE_free(ptr);
+ display_engine_list();
+ if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1))
+ {
+ printf("Couldn't add and remove to an empty list!\n");
+ goto end;
+ }
+ else
+ printf("Successfully added and removed to an empty list!\n");
+ printf("About to beef up the engine-type list\n");
+ for(loop = 0; loop < 512; loop++)
+ {
+ sprintf(buf, "id%i", loop);
+ id = BUF_strdup(buf);
+ sprintf(buf, "Fake engine type %i", loop);
+ name = BUF_strdup(buf);
+ if(((block[loop] = ENGINE_new()) == NULL) ||
+ !ENGINE_set_id(block[loop], id) ||
+ !ENGINE_set_name(block[loop], name))
+ {
+ printf("Couldn't create block of ENGINE structures.\n"
+ "I'll probably also core-dump now, damn.\n");
+ goto end;
+ }
+ }
+ for(loop = 0; loop < 512; loop++)
+ {
+ if(!ENGINE_add(block[loop]))
+ {
+ printf("\nAdding stopped at %i, (%s,%s)\n",
+ loop, ENGINE_get_id(block[loop]),
+ ENGINE_get_name(block[loop]));
+ goto cleanup_loop;
+ }
+ else
+ printf("."); fflush(stdout);
+ }
+cleanup_loop:
+ printf("\nAbout to empty the engine-type list\n");
+ while((ptr = ENGINE_get_first()) != NULL)
+ {
+ if(!ENGINE_remove(ptr))
+ {
+ printf("\nRemove failed!\n");
+ goto end;
+ }
+ ENGINE_free(ptr);
+ printf("."); fflush(stdout);
+ }
+ for(loop = 0; loop < 512; loop++)
+ {
+ OPENSSL_free((void *)ENGINE_get_id(block[loop]));
+ OPENSSL_free((void *)ENGINE_get_name(block[loop]));
+ }
+ printf("\nTests completed happily\n");
+ to_return = 0;
+end:
+ if(to_return)
+ ERR_print_errors_fp(stderr);
+ if(new_h1) ENGINE_free(new_h1);
+ if(new_h2) ENGINE_free(new_h2);
+ if(new_h3) ENGINE_free(new_h3);
+ if(new_h4) ENGINE_free(new_h4);
+ for(loop = 0; loop < 512; loop++)
+ if(block[loop])
+ ENGINE_free(block[loop]);
+ ENGINE_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+ ERR_free_strings();
+ ERR_remove_thread_state(NULL);
+ CRYPTO_mem_leaks_fp(stderr);
+ return to_return;
+ }
+#endif
diff --git a/deps/openssl/openssl/test/evp_test.c b/deps/openssl/openssl/test/evp_test.c
new file mode 100644
index 000000000..55c7cdfdc
--- /dev/null
+++ b/deps/openssl/openssl/test/evp_test.c
@@ -0,0 +1,450 @@
+/* Written by Ben Laurie, 2001 */
+/*
+ * Copyright (c) 2001 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#include <openssl/opensslconf.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/conf.h>
+
+static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
+ {
+ int n=0;
+
+ fprintf(f,"%s",title);
+ for( ; n < l ; ++n)
+ {
+ if((n%16) == 0)
+ fprintf(f,"\n%04x",n);
+ fprintf(f," %02x",s[n]);
+ }
+ fprintf(f,"\n");
+ }
+
+static int convert(unsigned char *s)
+ {
+ unsigned char *d;
+
+ for(d=s ; *s ; s+=2,++d)
+ {
+ unsigned int n;
+
+ if(!s[1])
+ {
+ fprintf(stderr,"Odd number of hex digits!");
+ EXIT(4);
+ }
+ sscanf((char *)s,"%2x",&n);
+ *d=(unsigned char)n;
+ }
+ return s-d;
+ }
+
+static char *sstrsep(char **string, const char *delim)
+ {
+ char isdelim[256];
+ char *token = *string;
+
+ if (**string == 0)
+ return NULL;
+
+ memset(isdelim, 0, 256);
+ isdelim[0] = 1;
+
+ while (*delim)
+ {
+ isdelim[(unsigned char)(*delim)] = 1;
+ delim++;
+ }
+
+ while (!isdelim[(unsigned char)(**string)])
+ {
+ (*string)++;
+ }
+
+ if (**string)
+ {
+ **string = 0;
+ (*string)++;
+ }
+
+ return token;
+ }
+
+static unsigned char *ustrsep(char **p,const char *sep)
+ { return (unsigned char *)sstrsep(p,sep); }
+
+static int test1_exit(int ec)
+ {
+ EXIT(ec);
+ return(0); /* To keep some compilers quiet */
+ }
+
+static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
+ const unsigned char *iv,int in,
+ const unsigned char *plaintext,int pn,
+ const unsigned char *ciphertext,int cn,
+ int encdec)
+ {
+ EVP_CIPHER_CTX ctx;
+ unsigned char out[4096];
+ int outl,outl2;
+
+ printf("Testing cipher %s%s\n",EVP_CIPHER_name(c),
+ (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)")));
+ hexdump(stdout,"Key",key,kn);
+ if(in)
+ hexdump(stdout,"IV",iv,in);
+ hexdump(stdout,"Plaintext",plaintext,pn);
+ hexdump(stdout,"Ciphertext",ciphertext,cn);
+
+ if(kn != c->key_len)
+ {
+ fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn,
+ (unsigned long)c->key_len);
+ test1_exit(5);
+ }
+ EVP_CIPHER_CTX_init(&ctx);
+ if (encdec != 0)
+ {
+ if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv))
+ {
+ fprintf(stderr,"EncryptInit failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(10);
+ }
+ EVP_CIPHER_CTX_set_padding(&ctx,0);
+
+ if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn))
+ {
+ fprintf(stderr,"Encrypt failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(6);
+ }
+ if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2))
+ {
+ fprintf(stderr,"EncryptFinal failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(7);
+ }
+
+ if(outl+outl2 != cn)
+ {
+ fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n",
+ outl+outl2,cn);
+ test1_exit(8);
+ }
+
+ if(memcmp(out,ciphertext,cn))
+ {
+ fprintf(stderr,"Ciphertext mismatch\n");
+ hexdump(stderr,"Got",out,cn);
+ hexdump(stderr,"Expected",ciphertext,cn);
+ test1_exit(9);
+ }
+ }
+
+ if (encdec <= 0)
+ {
+ if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv))
+ {
+ fprintf(stderr,"DecryptInit failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(11);
+ }
+ EVP_CIPHER_CTX_set_padding(&ctx,0);
+
+ if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn))
+ {
+ fprintf(stderr,"Decrypt failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(6);
+ }
+ if(!EVP_DecryptFinal_ex(&ctx,out+outl,&outl2))
+ {
+ fprintf(stderr,"DecryptFinal failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(7);
+ }
+
+ if(outl+outl2 != pn)
+ {
+ fprintf(stderr,"Plaintext length mismatch got %d expected %d\n",
+ outl+outl2,pn);
+ test1_exit(8);
+ }
+
+ if(memcmp(out,plaintext,pn))
+ {
+ fprintf(stderr,"Plaintext mismatch\n");
+ hexdump(stderr,"Got",out,pn);
+ hexdump(stderr,"Expected",plaintext,pn);
+ test1_exit(9);
+ }
+ }
+
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ printf("\n");
+ }
+
+static int test_cipher(const char *cipher,const unsigned char *key,int kn,
+ const unsigned char *iv,int in,
+ const unsigned char *plaintext,int pn,
+ const unsigned char *ciphertext,int cn,
+ int encdec)
+ {
+ const EVP_CIPHER *c;
+
+ c=EVP_get_cipherbyname(cipher);
+ if(!c)
+ return 0;
+
+ test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec);
+
+ return 1;
+ }
+
+static int test_digest(const char *digest,
+ const unsigned char *plaintext,int pn,
+ const unsigned char *ciphertext, unsigned int cn)
+ {
+ const EVP_MD *d;
+ EVP_MD_CTX ctx;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ unsigned int mdn;
+
+ d=EVP_get_digestbyname(digest);
+ if(!d)
+ return 0;
+
+ printf("Testing digest %s\n",EVP_MD_name(d));
+ hexdump(stdout,"Plaintext",plaintext,pn);
+ hexdump(stdout,"Digest",ciphertext,cn);
+
+ EVP_MD_CTX_init(&ctx);
+ if(!EVP_DigestInit_ex(&ctx,d, NULL))
+ {
+ fprintf(stderr,"DigestInit failed\n");
+ ERR_print_errors_fp(stderr);
+ EXIT(100);
+ }
+ if(!EVP_DigestUpdate(&ctx,plaintext,pn))
+ {
+ fprintf(stderr,"DigestUpdate failed\n");
+ ERR_print_errors_fp(stderr);
+ EXIT(101);
+ }
+ if(!EVP_DigestFinal_ex(&ctx,md,&mdn))
+ {
+ fprintf(stderr,"DigestFinal failed\n");
+ ERR_print_errors_fp(stderr);
+ EXIT(101);
+ }
+ EVP_MD_CTX_cleanup(&ctx);
+
+ if(mdn != cn)
+ {
+ fprintf(stderr,"Digest length mismatch, got %d expected %d\n",mdn,cn);
+ EXIT(102);
+ }
+
+ if(memcmp(md,ciphertext,cn))
+ {
+ fprintf(stderr,"Digest mismatch\n");
+ hexdump(stderr,"Got",md,cn);
+ hexdump(stderr,"Expected",ciphertext,cn);
+ EXIT(103);
+ }
+
+ printf("\n");
+
+ EVP_MD_CTX_cleanup(&ctx);
+
+ return 1;
+ }
+
+int main(int argc,char **argv)
+ {
+ const char *szTestFile;
+ FILE *f;
+
+ if(argc != 2)
+ {
+ fprintf(stderr,"%s <test file>\n",argv[0]);
+ EXIT(1);
+ }
+ CRYPTO_malloc_debug_init();
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ szTestFile=argv[1];
+
+ f=fopen(szTestFile,"r");
+ if(!f)
+ {
+ perror(szTestFile);
+ EXIT(2);
+ }
+
+ /* Load up the software EVP_CIPHER and EVP_MD definitions */
+ OpenSSL_add_all_ciphers();
+ OpenSSL_add_all_digests();
+#ifndef OPENSSL_NO_ENGINE
+ /* Load all compiled-in ENGINEs */
+ ENGINE_load_builtin_engines();
+#endif
+#if 0
+ OPENSSL_config();
+#endif
+#ifndef OPENSSL_NO_ENGINE
+ /* Register all available ENGINE implementations of ciphers and digests.
+ * This could perhaps be changed to "ENGINE_register_all_complete()"? */
+ ENGINE_register_all_ciphers();
+ ENGINE_register_all_digests();
+ /* If we add command-line options, this statement should be switchable.
+ * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use if
+ * they weren't already initialised. */
+ /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */
+#endif
+
+ for( ; ; )
+ {
+ char line[4096];
+ char *p;
+ char *cipher;
+ unsigned char *iv,*key,*plaintext,*ciphertext;
+ int encdec;
+ int kn,in,pn,cn;
+
+ if(!fgets((char *)line,sizeof line,f))
+ break;
+ if(line[0] == '#' || line[0] == '\n')
+ continue;
+ p=line;
+ cipher=sstrsep(&p,":");
+ key=ustrsep(&p,":");
+ iv=ustrsep(&p,":");
+ plaintext=ustrsep(&p,":");
+ ciphertext=ustrsep(&p,":");
+ if (p[-1] == '\n') {
+ p[-1] = '\0';
+ encdec = -1;
+ } else {
+ encdec = atoi(sstrsep(&p,"\n"));
+ }
+
+
+ kn=convert(key);
+ in=convert(iv);
+ pn=convert(plaintext);
+ cn=convert(ciphertext);
+
+ if(!test_cipher(cipher,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec)
+ && !test_digest(cipher,plaintext,pn,ciphertext,cn))
+ {
+#ifdef OPENSSL_NO_AES
+ if (strstr(cipher, "AES") == cipher)
+ {
+ fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
+ continue;
+ }
+#endif
+#ifdef OPENSSL_NO_DES
+ if (strstr(cipher, "DES") == cipher)
+ {
+ fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
+ continue;
+ }
+#endif
+#ifdef OPENSSL_NO_RC4
+ if (strstr(cipher, "RC4") == cipher)
+ {
+ fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
+ continue;
+ }
+#endif
+#ifdef OPENSSL_NO_CAMELLIA
+ if (strstr(cipher, "CAMELLIA") == cipher)
+ {
+ fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
+ continue;
+ }
+#endif
+#ifdef OPENSSL_NO_SEED
+ if (strstr(cipher, "SEED") == cipher)
+ {
+ fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
+ continue;
+ }
+#endif
+ fprintf(stderr,"Can't find %s\n",cipher);
+ EXIT(3);
+ }
+ }
+ fclose(f);
+
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_cleanup();
+#endif
+ EVP_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+ ERR_free_strings();
+ CRYPTO_mem_leaks_fp(stderr);
+
+ return 0;
+ }
diff --git a/deps/openssl/openssl/test/evptests.txt b/deps/openssl/openssl/test/evptests.txt
new file mode 100644
index 000000000..c273707c1
--- /dev/null
+++ b/deps/openssl/openssl/test/evptests.txt
@@ -0,0 +1,334 @@
+#cipher:key:iv:plaintext:ciphertext:0/1(decrypt/encrypt)
+#digest:::input:output
+
+# SHA(1) tests (from shatest.c)
+SHA1:::616263:a9993e364706816aba3e25717850c26c9cd0d89d
+
+# MD5 tests (from md5test.c)
+MD5::::d41d8cd98f00b204e9800998ecf8427e
+MD5:::61:0cc175b9c0f1b6a831c399e269772661
+MD5:::616263:900150983cd24fb0d6963f7d28e17f72
+MD5:::6d65737361676520646967657374:f96b697d7cb7938d525a2f31aaf161d0
+MD5:::6162636465666768696a6b6c6d6e6f707172737475767778797a:c3fcd3d76192e4007dfb496cca67e13b
+MD5:::4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839:d174ab98d277d9f5a5611c2c9f419d9f
+MD5:::3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930:57edf4a22be3c955ac49da2e2107b67a
+
+# AES 128 ECB tests (from FIPS-197 test vectors, encrypt)
+
+AES-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:69C4E0D86A7B0430D8CDB78070B4C55A:1
+
+# AES 192 ECB tests (from FIPS-197 test vectors, encrypt)
+
+AES-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:DDA97CA4864CDFE06EAF70A0EC0D7191:1
+
+# AES 256 ECB tests (from FIPS-197 test vectors, encrypt)
+
+AES-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:8EA2B7CA516745BFEAFC49904B496089:1
+
+# AES 128 ECB tests (from NIST test vectors, encrypt)
+
+#AES-128-ECB:00000000000000000000000000000000::00000000000000000000000000000000:C34C052CC0DA8D73451AFE5F03BE297F:1
+
+# AES 128 ECB tests (from NIST test vectors, decrypt)
+
+#AES-128-ECB:00000000000000000000000000000000::44416AC2D1F53C583303917E6BE9EBE0:00000000000000000000000000000000:0
+
+# AES 192 ECB tests (from NIST test vectors, decrypt)
+
+#AES-192-ECB:000000000000000000000000000000000000000000000000::48E31E9E256718F29229319C19F15BA4:00000000000000000000000000000000:0
+
+# AES 256 ECB tests (from NIST test vectors, decrypt)
+
+#AES-256-ECB:0000000000000000000000000000000000000000000000000000000000000000::058CCFFDBBCB382D1F6F56585D8A4ADE:00000000000000000000000000000000:0
+
+# AES 128 CBC tests (from NIST test vectors, encrypt)
+
+#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:8A05FC5E095AF4848A08D328D3688E3D:1
+
+# AES 192 CBC tests (from NIST test vectors, encrypt)
+
+#AES-192-CBC:000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:7BD966D53AD8C1BB85D2ADFAE87BB104:1
+
+# AES 256 CBC tests (from NIST test vectors, encrypt)
+
+#AES-256-CBC:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:FE3C53653E2F45B56FCD88B2CC898FF0:1
+
+# AES 128 CBC tests (from NIST test vectors, decrypt)
+
+#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:FACA37E0B0C85373DF706E73F7C9AF86:00000000000000000000000000000000:0
+
+# AES tests from NIST document SP800-38A
+# For all ECB encrypts and decrypts, the transformed sequence is
+# AES-bits-ECB:key::plaintext:ciphertext:encdec
+# ECB-AES128.Encrypt and ECB-AES128.Decrypt
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:3AD77BB40D7A3660A89ECAF32466EF97
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4
+# ECB-AES192.Encrypt and ECB-AES192.Decrypt
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E
+# ECB-AES256.Encrypt and ECB-AES256.Decrypt
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7
+# For all CBC encrypts and decrypts, the transformed sequence is
+# AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CBC-AES128.Encrypt and CBC-AES128.Decrypt
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7
+# CBC-AES192.Encrypt and CBC-AES192.Decrypt
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD
+# CBC-AES256.Encrypt and CBC-AES256.Decrypt
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B
+# We don't support CFB{1,8}-AESxxx.{En,De}crypt
+# For all CFB128 encrypts and decrypts, the transformed sequence is
+# AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CFB128-AES128.Encrypt
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:1
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:1
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:1
+# CFB128-AES128.Decrypt
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:0
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:0
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:0
+# CFB128-AES192.Encrypt
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:1
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:1
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:1
+# CFB128-AES192.Decrypt
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:0
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:0
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:0
+# CFB128-AES256.Encrypt
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:1
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:1
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:1
+# CFB128-AES256.Decrypt
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:0
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:0
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:0
+# For all OFB encrypts and decrypts, the transformed sequence is
+# AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec
+# OFB-AES128.Encrypt
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1
+# OFB-AES128.Decrypt
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0
+# OFB-AES192.Encrypt
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1
+# OFB-AES192.Decrypt
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0
+# OFB-AES256.Encrypt
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1
+# OFB-AES256.Decrypt
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0
+
+# AES Counter test vectors from RFC3686
+aes-128-ctr:AE6852F8121067CC4BF7A5765577F39E:00000030000000000000000000000001:53696E676C6520626C6F636B206D7367:E4095D4FB7A7B3792D6175A3261311B8:1
+aes-128-ctr:7E24067817FAE0D743D6CE1F32539163:006CB6DBC0543B59DA48D90B00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28:1
+aes-128-ctr:7691BE035E5020A8AC6E618529F9A0DC:00E0017B27777F3F4A1786F000000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F:1
+
+aes-192-ctr:16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515:0000004836733C147D6D93CB00000001:53696E676C6520626C6F636B206D7367:4B55384FE259C9C84E7935A003CBE928:1
+aes-192-ctr:7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A:0096B03B020C6EADC2CB500D00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00:1
+aes-192-ctr:02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE:0007BDFD5CBD60278DCC091200000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935:1
+
+aes-256-ctr:776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104:00000060DB5672C97AA8F0B200000001:53696E676C6520626C6F636B206D7367:145AD01DBF824EC7560863DC71E3E0C0:1
+aes-256-ctr:F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884:00FAAC24C1585EF15A43D87500000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C:1
+aes-256-ctr:FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D:001CC5B751A51D70A1C1114800000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8:1
+
+# DES ECB tests (from destest)
+
+DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7
+DES-ECB:FFFFFFFFFFFFFFFF::FFFFFFFFFFFFFFFF:7359B2163E4EDC58
+DES-ECB:3000000000000000::1000000000000001:958E6E627A05557B
+DES-ECB:1111111111111111::1111111111111111:F40379AB9E0EC533
+DES-ECB:0123456789ABCDEF::1111111111111111:17668DFC7292532D
+DES-ECB:1111111111111111::0123456789ABCDEF:8A5AE1F81AB8F2DD
+DES-ECB:FEDCBA9876543210::0123456789ABCDEF:ED39D950FA74BCC4
+
+# DESX-CBC tests (from destest)
+DESX-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:846B2914851E9A2954732F8AA0A611C115CDC2D7951B1053A63C5E03B21AA3C4
+
+# DES EDE3 CBC tests (from destest)
+DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
+
+# RC4 tests (from rc4test)
+RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596
+RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879
+RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a
+RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858
+RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf
+RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61
+
+
+# Camellia tests from RFC3713
+# For all ECB encrypts and decrypts, the transformed sequence is
+# CAMELLIA-bits-ECB:key::plaintext:ciphertext:encdec
+CAMELLIA-128-ECB:0123456789abcdeffedcba9876543210::0123456789abcdeffedcba9876543210:67673138549669730857065648eabe43
+CAMELLIA-192-ECB:0123456789abcdeffedcba98765432100011223344556677::0123456789abcdeffedcba9876543210:b4993401b3e996f84ee5cee7d79b09b9
+CAMELLIA-256-ECB:0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff::0123456789abcdeffedcba9876543210:9acc237dff16d76c20ef7c919e3a7509
+
+# ECB-CAMELLIA128.Encrypt
+CAMELLIA-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:77CF412067AF8270613529149919546F:1
+CAMELLIA-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:B22F3C36B72D31329EEE8ADDC2906C68:1
+CAMELLIA-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:2EDF1F3418D53B88841FC8985FB1ECF2:1
+
+# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:432FC5DCD628115B7C388D770B270C96
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:0BE1F14023782A22E8384C5ABB7FAB2B
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:A0A1ABCD1893AB6FE0FE5B65DF5F8636
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:E61925E0D5DFAA9BB29F815B3076E51A
+
+# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:CCCC6C4E138B45848514D48D0D3439D3
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:5713C62C14B2EC0F8393B6AFD6F5785A
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:B40ED2B60EB54D09D030CF511FEEF366
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:909DBD95799096748CB27357E73E1D26
+
+# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:BEFD219B112FA00098919CD101C9CCFA
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:C91D3A8F1AEA08A9386CF4B66C0169EA
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:A623D711DC5F25A51BB8A80D56397D28
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:7960109FB6DC42947FCFE59EA3C5EB6B
+
+# For all CBC encrypts and decrypts, the transformed sequence is
+# CAMELLIA-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:1607CF494B36BBF00DAEB0B503C831AB
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:1607CF494B36BBF00DAEB0B503C831AB:AE2D8A571E03AC9C9EB76FAC45AF8E51:A2F2CF671629EF7840C5A5DFB5074887
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:A2F2CF671629EF7840C5A5DFB5074887:30C81C46A35CE411E5FBC1191A0A52EF:0F06165008CF8B8B5A63586362543E54
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:36A84CDAFD5F9A85ADA0F0A993D6D577:F69F2445DF4F9B17AD2B417BE66C3710:74C64268CDB8B8FAF5B34E8AF3732980
+
+# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:2A4830AB5AC4A1A2405955FD2195CF93
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2A4830AB5AC4A1A2405955FD2195CF93:AE2D8A571E03AC9C9EB76FAC45AF8E51:5D5A869BD14CE54264F892A6DD2EC3D5
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:5D5A869BD14CE54264F892A6DD2EC3D5:30C81C46A35CE411E5FBC1191A0A52EF:37D359C3349836D884E310ADDF68C449
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:37D359C3349836D884E310ADDF68C449:F69F2445DF4F9B17AD2B417BE66C3710:01FAAA930B4AB9916E9668E1428C6B08
+
+# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:E6CFA35FC02B134A4D2C0B6737AC3EDA
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E6CFA35FC02B134A4D2C0B6737AC3EDA:AE2D8A571E03AC9C9EB76FAC45AF8E51:36CBEB73BD504B4070B1B7DE2B21EB50
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:36CBEB73BD504B4070B1B7DE2B21EB50:30C81C46A35CE411E5FBC1191A0A52EF:E31A6055297D96CA3330CDF1B1860A83
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E31A6055297D96CA3330CDF1B1860A83:F69F2445DF4F9B17AD2B417BE66C3710:5D563F6D1CCCF236051C0C5C1C58F28F
+
+# We don't support CFB{1,8}-CAMELLIAxxx.{En,De}crypt
+# For all CFB128 encrypts and decrypts, the transformed sequence is
+# CAMELLIA-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CFB128-CAMELLIA128.Encrypt
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:1
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:1
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:1
+
+# CFB128-CAMELLIA128.Decrypt
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:0
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:0
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:0
+
+# CFB128-CAMELLIA192.Encrypt
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:1
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:1
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:1
+
+# CFB128-CAMELLIA192.Decrypt
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:0
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:0
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:0
+
+# CFB128-CAMELLIA256.Encrypt
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:1
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:1
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:1
+
+# CFB128-CAMELLIA256.Decrypt
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:0
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:0
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:0
+
+# For all OFB encrypts and decrypts, the transformed sequence is
+# CAMELLIA-bits-OFB:key:IV/output':plaintext:ciphertext:encdec
+# OFB-CAMELLIA128.Encrypt
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:1
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:1
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:1
+
+# OFB-CAMELLIA128.Decrypt
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:0
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:0
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:0
+
+# OFB-CAMELLIA192.Encrypt
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:1
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:1
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:1
+
+# OFB-CAMELLIA192.Decrypt
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:0
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:0
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:0
+
+# OFB-CAMELLIA256.Encrypt
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:1
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:1
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:1
+
+# OFB-CAMELLIA256.Decrypt
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:0
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:0
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:0
+
+# SEED test vectors from RFC4269
+SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:0
+SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:0
+SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:0
+SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:0
+SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:1
+SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:1
+SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:1
+SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:1
diff --git a/deps/openssl/openssl/test/exptest.c b/deps/openssl/openssl/test/exptest.c
new file mode 100644
index 000000000..074a8e882
--- /dev/null
+++ b/deps/openssl/openssl/test/exptest.c
@@ -0,0 +1,204 @@
+/* crypto/bn/exptest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#define NUM_BITS (BN_BITS*2)
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int main(int argc, char *argv[])
+ {
+ BN_CTX *ctx;
+ BIO *out=NULL;
+ int i,ret;
+ unsigned char c;
+ BIGNUM *r_mont,*r_mont_const,*r_recp,*r_simple,*a,*b,*m;
+
+ RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
+ * even check its return value
+ * (which we should) */
+
+ ERR_load_BN_strings();
+
+ ctx=BN_CTX_new();
+ if (ctx == NULL) EXIT(1);
+ r_mont=BN_new();
+ r_mont_const=BN_new();
+ r_recp=BN_new();
+ r_simple=BN_new();
+ a=BN_new();
+ b=BN_new();
+ m=BN_new();
+ if ( (r_mont == NULL) || (r_recp == NULL) ||
+ (a == NULL) || (b == NULL))
+ goto err;
+
+ out=BIO_new(BIO_s_file());
+
+ if (out == NULL) EXIT(1);
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+
+ for (i=0; i<200; i++)
+ {
+ RAND_bytes(&c,1);
+ c=(c%BN_BITS)-BN_BITS2;
+ BN_rand(a,NUM_BITS+c,0,0);
+
+ RAND_bytes(&c,1);
+ c=(c%BN_BITS)-BN_BITS2;
+ BN_rand(b,NUM_BITS+c,0,0);
+
+ RAND_bytes(&c,1);
+ c=(c%BN_BITS)-BN_BITS2;
+ BN_rand(m,NUM_BITS+c,0,1);
+
+ BN_mod(a,a,m,ctx);
+ BN_mod(b,b,m,ctx);
+
+ ret=BN_mod_exp_mont(r_mont,a,b,m,ctx,NULL);
+ if (ret <= 0)
+ {
+ printf("BN_mod_exp_mont() problems\n");
+ ERR_print_errors(out);
+ EXIT(1);
+ }
+
+ ret=BN_mod_exp_recp(r_recp,a,b,m,ctx);
+ if (ret <= 0)
+ {
+ printf("BN_mod_exp_recp() problems\n");
+ ERR_print_errors(out);
+ EXIT(1);
+ }
+
+ ret=BN_mod_exp_simple(r_simple,a,b,m,ctx);
+ if (ret <= 0)
+ {
+ printf("BN_mod_exp_simple() problems\n");
+ ERR_print_errors(out);
+ EXIT(1);
+ }
+
+ ret=BN_mod_exp_mont_consttime(r_mont_const,a,b,m,ctx,NULL);
+ if (ret <= 0)
+ {
+ printf("BN_mod_exp_mont_consttime() problems\n");
+ ERR_print_errors(out);
+ EXIT(1);
+ }
+
+ if (BN_cmp(r_simple, r_mont) == 0
+ && BN_cmp(r_simple,r_recp) == 0
+ && BN_cmp(r_simple,r_mont_const) == 0)
+ {
+ printf(".");
+ fflush(stdout);
+ }
+ else
+ {
+ if (BN_cmp(r_simple,r_mont) != 0)
+ printf("\nsimple and mont results differ\n");
+ if (BN_cmp(r_simple,r_mont_const) != 0)
+ printf("\nsimple and mont const time results differ\n");
+ if (BN_cmp(r_simple,r_recp) != 0)
+ printf("\nsimple and recp results differ\n");
+
+ printf("a (%3d) = ",BN_num_bits(a)); BN_print(out,a);
+ printf("\nb (%3d) = ",BN_num_bits(b)); BN_print(out,b);
+ printf("\nm (%3d) = ",BN_num_bits(m)); BN_print(out,m);
+ printf("\nsimple ="); BN_print(out,r_simple);
+ printf("\nrecp ="); BN_print(out,r_recp);
+ printf("\nmont ="); BN_print(out,r_mont);
+ printf("\nmont_ct ="); BN_print(out,r_mont_const);
+ printf("\n");
+ EXIT(1);
+ }
+ }
+ BN_free(r_mont);
+ BN_free(r_mont_const);
+ BN_free(r_recp);
+ BN_free(r_simple);
+ BN_free(a);
+ BN_free(b);
+ BN_free(m);
+ BN_CTX_free(ctx);
+ ERR_remove_thread_state(NULL);
+ CRYPTO_mem_leaks(out);
+ BIO_free(out);
+ printf(" done\n");
+ EXIT(0);
+err:
+ ERR_load_crypto_strings();
+ ERR_print_errors(out);
+#ifdef OPENSSL_SYS_NETWARE
+ printf("ERROR\n");
+#endif
+ EXIT(1);
+ return(1);
+ }
+
diff --git a/deps/openssl/openssl/test/hmactest.c b/deps/openssl/openssl/test/hmactest.c
new file mode 100644
index 000000000..1b906b81a
--- /dev/null
+++ b/deps/openssl/openssl/test/hmactest.c
@@ -0,0 +1,175 @@
+/* crypto/hmac/hmactest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_HMAC
+int main(int argc, char *argv[])
+{
+ printf("No HMAC support\n");
+ return(0);
+}
+#else
+#include <openssl/hmac.h>
+#ifndef OPENSSL_NO_MD5
+#include <openssl/md5.h>
+#endif
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+#ifndef OPENSSL_NO_MD5
+static struct test_st
+ {
+ unsigned char key[16];
+ int key_len;
+ unsigned char data[64];
+ int data_len;
+ unsigned char *digest;
+ } test[4]={
+ { "",
+ 0,
+ "More text test vectors to stuff up EBCDIC machines :-)",
+ 54,
+ (unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
+ },{ {0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,},
+ 16,
+ "Hi There",
+ 8,
+ (unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
+ },{ "Jefe",
+ 4,
+ "what do ya want for nothing?",
+ 28,
+ (unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
+ },{
+ {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,},
+ 16,
+ {0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+ 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+ 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+ 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+ 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+ 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+ 0xdd,0xdd},
+ 50,
+ (unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
+ },
+ };
+#endif
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+ {
+#ifndef OPENSSL_NO_MD5
+ int i;
+ char *p;
+#endif
+ int err=0;
+
+#ifdef OPENSSL_NO_MD5
+ printf("test skipped: MD5 disabled\n");
+#else
+
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
+ ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
+ ebcdic2ascii(test[2].key, test[2].key, test[2].key_len);
+ ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
+#endif
+
+ for (i=0; i<4; i++)
+ {
+ p=pt(HMAC(EVP_md5(),
+ test[i].key, test[i].key_len,
+ test[i].data, test[i].data_len,
+ NULL,NULL));
+
+ if (strcmp(p,(char *)test[i].digest) != 0)
+ {
+ printf("error calculating HMAC on %d entry'\n",i);
+ printf("got %s instead of %s\n",p,test[i].digest);
+ err++;
+ }
+ else
+ printf("test %d ok\n",i);
+ }
+#endif /* OPENSSL_NO_MD5 */
+ EXIT(err);
+ return(0);
+ }
+
+#ifndef OPENSSL_NO_MD5
+static char *pt(unsigned char *md)
+ {
+ int i;
+ static char buf[80];
+
+ for (i=0; i<MD5_DIGEST_LENGTH; i++)
+ sprintf(&(buf[i*2]),"%02x",md[i]);
+ return(buf);
+ }
+#endif
+#endif
diff --git a/deps/openssl/openssl/test/ideatest.c b/deps/openssl/openssl/test/ideatest.c
new file mode 100644
index 000000000..e6ffc7025
--- /dev/null
+++ b/deps/openssl/openssl/test/ideatest.c
@@ -0,0 +1,235 @@
+/* crypto/idea/ideatest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_IDEA
+int main(int argc, char *argv[])
+{
+ printf("No IDEA support\n");
+ return(0);
+}
+#else
+#include <openssl/idea.h>
+
+unsigned char k[16]={
+ 0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,
+ 0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08};
+
+unsigned char in[8]={0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03};
+unsigned char c[8]={0x11,0xFB,0xED,0x2B,0x01,0x98,0x6D,0xE5};
+unsigned char out[80];
+
+char *text="Hello to all people out there";
+
+static unsigned char cfb_key[16]={
+ 0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
+ 0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
+ };
+static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+#define CFB_TEST_SIZE 24
+static unsigned char plain[CFB_TEST_SIZE]=
+ {
+ 0x4e,0x6f,0x77,0x20,0x69,0x73,
+ 0x20,0x74,0x68,0x65,0x20,0x74,
+ 0x69,0x6d,0x65,0x20,0x66,0x6f,
+ 0x72,0x20,0x61,0x6c,0x6c,0x20
+ };
+static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
+ 0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
+ 0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
+ 0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
+
+/* 0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
+ 0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
+ 0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
+ };
+
+static int cfb64_test(unsigned char *cfb_cipher);
+static char *pt(unsigned char *p);
+int main(int argc, char *argv[])
+ {
+ int i,err=0;
+ IDEA_KEY_SCHEDULE key,dkey;
+ unsigned char iv[8];
+
+ idea_set_encrypt_key(k,&key);
+ idea_ecb_encrypt(in,out,&key);
+ if (memcmp(out,c,8) != 0)
+ {
+ printf("ecb idea error encrypting\n");
+ printf("got :");
+ for (i=0; i<8; i++)
+ printf("%02X ",out[i]);
+ printf("\n");
+ printf("expected:");
+ for (i=0; i<8; i++)
+ printf("%02X ",c[i]);
+ err=20;
+ printf("\n");
+ }
+
+ idea_set_decrypt_key(&key,&dkey);
+ idea_ecb_encrypt(c,out,&dkey);
+ if (memcmp(out,in,8) != 0)
+ {
+ printf("ecb idea error decrypting\n");
+ printf("got :");
+ for (i=0; i<8; i++)
+ printf("%02X ",out[i]);
+ printf("\n");
+ printf("expected:");
+ for (i=0; i<8; i++)
+ printf("%02X ",in[i]);
+ printf("\n");
+ err=3;
+ }
+
+ if (err == 0) printf("ecb idea ok\n");
+
+ memcpy(iv,k,8);
+ idea_cbc_encrypt((unsigned char *)text,out,strlen(text)+1,&key,iv,1);
+ memcpy(iv,k,8);
+ idea_cbc_encrypt(out,out,8,&dkey,iv,0);
+ idea_cbc_encrypt(&(out[8]),&(out[8]),strlen(text)+1-8,&dkey,iv,0);
+ if (memcmp(text,out,strlen(text)+1) != 0)
+ {
+ printf("cbc idea bad\n");
+ err=4;
+ }
+ else
+ printf("cbc idea ok\n");
+
+ printf("cfb64 idea ");
+ if (cfb64_test(cfb_cipher64))
+ {
+ printf("bad\n");
+ err=5;
+ }
+ else
+ printf("ok\n");
+
+#ifdef OPENSSL_SYS_NETWARE
+ if (err) printf("ERROR: %d\n", err);
+#endif
+ EXIT(err);
+ return(err);
+ }
+
+static int cfb64_test(unsigned char *cfb_cipher)
+ {
+ IDEA_KEY_SCHEDULE eks,dks;
+ int err=0,i,n;
+
+ idea_set_encrypt_key(cfb_key,&eks);
+ idea_set_decrypt_key(&eks,&dks);
+ memcpy(cfb_tmp,cfb_iv,8);
+ n=0;
+ idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks,
+ cfb_tmp,&n,IDEA_ENCRYPT);
+ idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+ (long)CFB_TEST_SIZE-12,&eks,
+ cfb_tmp,&n,IDEA_ENCRYPT);
+ if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0)
+ {
+ err=1;
+ printf("idea_cfb64_encrypt encrypt error\n");
+ for (i=0; i<CFB_TEST_SIZE; i+=8)
+ printf("%s\n",pt(&(cfb_buf1[i])));
+ }
+ memcpy(cfb_tmp,cfb_iv,8);
+ n=0;
+ idea_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&eks,
+ cfb_tmp,&n,IDEA_DECRYPT);
+ idea_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+ (long)CFB_TEST_SIZE-17,&dks,
+ cfb_tmp,&n,IDEA_DECRYPT);
+ if (memcmp(plain,cfb_buf2,CFB_TEST_SIZE) != 0)
+ {
+ err=1;
+ printf("idea_cfb_encrypt decrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf2[i])));
+ }
+ return(err);
+ }
+
+static char *pt(unsigned char *p)
+ {
+ static char bufs[10][20];
+ static int bnum=0;
+ char *ret;
+ int i;
+ static char *f="0123456789ABCDEF";
+
+ ret= &(bufs[bnum++][0]);
+ bnum%=10;
+ for (i=0; i<8; i++)
+ {
+ ret[i*2]=f[(p[i]>>4)&0xf];
+ ret[i*2+1]=f[p[i]&0xf];
+ }
+ ret[16]='\0';
+ return(ret);
+ }
+#endif
diff --git a/deps/openssl/openssl/test/igetest.c b/deps/openssl/openssl/test/igetest.c
new file mode 100644
index 000000000..1ba900244
--- /dev/null
+++ b/deps/openssl/openssl/test/igetest.c
@@ -0,0 +1,503 @@
+/* test/igetest.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 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.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/aes.h>
+#include <openssl/rand.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#define TEST_SIZE 128
+#define BIG_TEST_SIZE 10240
+
+static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
+ {
+ int n=0;
+
+ fprintf(f,"%s",title);
+ for( ; n < l ; ++n)
+ {
+ if((n%16) == 0)
+ fprintf(f,"\n%04x",n);
+ fprintf(f," %02x",s[n]);
+ }
+ fprintf(f,"\n");
+ }
+
+#define MAX_VECTOR_SIZE 64
+
+struct ige_test
+ {
+ const unsigned char key[16];
+ const unsigned char iv[32];
+ const unsigned char in[MAX_VECTOR_SIZE];
+ const unsigned char out[MAX_VECTOR_SIZE];
+ const size_t length;
+ const int encrypt;
+ };
+
+static struct ige_test const ige_test_vectors[] = {
+{ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* key */
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, /* iv */
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* in */
+ { 0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52,
+ 0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45,
+ 0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3,
+ 0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb }, /* out */
+ 32, AES_ENCRYPT }, /* test vector 0 */
+
+{ { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
+ 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65 }, /* key */
+ { 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45,
+ 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f,
+ 0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53 }, /* iv */
+ { 0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73,
+ 0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65,
+ 0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74,
+ 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a }, /* in */
+ { 0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13,
+ 0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a,
+ 0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34,
+ 0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b }, /* out */
+ 32, AES_DECRYPT }, /* test vector 1 */
+};
+
+struct bi_ige_test
+ {
+ const unsigned char key1[32];
+ const unsigned char key2[32];
+ const unsigned char iv[64];
+ const unsigned char in[MAX_VECTOR_SIZE];
+ const unsigned char out[MAX_VECTOR_SIZE];
+ const size_t keysize;
+ const size_t length;
+ const int encrypt;
+ };
+
+static struct bi_ige_test const bi_ige_test_vectors[] = {
+{ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* key1 */
+ { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, /* key2 */
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f }, /* iv */
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* in */
+ { 0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56,
+ 0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc,
+ 0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16,
+ 0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12 }, /* out */
+ 16, 32, AES_ENCRYPT }, /* test vector 0 */
+{ { 0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c,
+ 0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a,
+ 0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75,
+ 0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37 }, /* key1 */
+ { 0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13,
+ 0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74,
+ 0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21,
+ 0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4 }, /* key2 */
+ { 0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9,
+ 0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70,
+ 0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42,
+ 0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67,
+ 0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a,
+ 0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20,
+ 0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd,
+ 0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3 }, /* iv */
+ { 0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c,
+ 0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0,
+ 0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f,
+ 0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b,
+ 0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52,
+ 0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a,
+ 0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c,
+ 0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */
+ { 0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23,
+ 0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79,
+ 0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf,
+ 0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92,
+ 0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51,
+ 0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67,
+ 0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76,
+ 0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */
+ 32, 64, AES_ENCRYPT }, /* test vector 1 */
+
+};
+
+static int run_test_vectors(void)
+ {
+ unsigned int n;
+ int errs = 0;
+
+ for(n=0 ; n < sizeof(ige_test_vectors)/sizeof(ige_test_vectors[0]) ; ++n)
+ {
+ const struct ige_test * const v = &ige_test_vectors[n];
+ AES_KEY key;
+ unsigned char buf[MAX_VECTOR_SIZE];
+ unsigned char iv[AES_BLOCK_SIZE*2];
+
+ assert(v->length <= MAX_VECTOR_SIZE);
+
+ if(v->encrypt == AES_ENCRYPT)
+ AES_set_encrypt_key(v->key, 8*sizeof v->key, &key);
+ else
+ AES_set_decrypt_key(v->key, 8*sizeof v->key, &key);
+ memcpy(iv, v->iv, sizeof iv);
+ AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt);
+
+ if(memcmp(v->out, buf, v->length))
+ {
+ printf("IGE test vector %d failed\n", n);
+ hexdump(stdout, "key", v->key, sizeof v->key);
+ hexdump(stdout, "iv", v->iv, sizeof v->iv);
+ hexdump(stdout, "in", v->in, v->length);
+ hexdump(stdout, "expected", v->out, v->length);
+ hexdump(stdout, "got", buf, v->length);
+
+ ++errs;
+ }
+
+ /* try with in == out */
+ memcpy(iv, v->iv, sizeof iv);
+ memcpy(buf, v->in, v->length);
+ AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt);
+
+ if(memcmp(v->out, buf, v->length))
+ {
+ printf("IGE test vector %d failed (with in == out)\n", n);
+ hexdump(stdout, "key", v->key, sizeof v->key);
+ hexdump(stdout, "iv", v->iv, sizeof v->iv);
+ hexdump(stdout, "in", v->in, v->length);
+ hexdump(stdout, "expected", v->out, v->length);
+ hexdump(stdout, "got", buf, v->length);
+
+ ++errs;
+ }
+ }
+
+ for(n=0 ; n < sizeof(bi_ige_test_vectors)/sizeof(bi_ige_test_vectors[0])
+ ; ++n)
+ {
+ const struct bi_ige_test * const v = &bi_ige_test_vectors[n];
+ AES_KEY key1;
+ AES_KEY key2;
+ unsigned char buf[MAX_VECTOR_SIZE];
+
+ assert(v->length <= MAX_VECTOR_SIZE);
+
+ if(v->encrypt == AES_ENCRYPT)
+ {
+ AES_set_encrypt_key(v->key1, 8*v->keysize, &key1);
+ AES_set_encrypt_key(v->key2, 8*v->keysize, &key2);
+ }
+ else
+ {
+ AES_set_decrypt_key(v->key1, 8*v->keysize, &key1);
+ AES_set_decrypt_key(v->key2, 8*v->keysize, &key2);
+ }
+
+ AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
+ v->encrypt);
+
+ if(memcmp(v->out, buf, v->length))
+ {
+ printf("Bidirectional IGE test vector %d failed\n", n);
+ hexdump(stdout, "key 1", v->key1, sizeof v->key1);
+ hexdump(stdout, "key 2", v->key2, sizeof v->key2);
+ hexdump(stdout, "iv", v->iv, sizeof v->iv);
+ hexdump(stdout, "in", v->in, v->length);
+ hexdump(stdout, "expected", v->out, v->length);
+ hexdump(stdout, "got", buf, v->length);
+
+ ++errs;
+ }
+ }
+
+ return errs;
+ }
+
+int main(int argc, char **argv)
+ {
+ unsigned char rkey[16];
+ unsigned char rkey2[16];
+ AES_KEY key;
+ AES_KEY key2;
+ unsigned char plaintext[BIG_TEST_SIZE];
+ unsigned char ciphertext[BIG_TEST_SIZE];
+ unsigned char checktext[BIG_TEST_SIZE];
+ unsigned char iv[AES_BLOCK_SIZE*4];
+ unsigned char saved_iv[AES_BLOCK_SIZE*4];
+ int err = 0;
+ unsigned int n;
+ unsigned matches;
+
+ assert(BIG_TEST_SIZE >= TEST_SIZE);
+
+ RAND_pseudo_bytes(rkey, sizeof rkey);
+ RAND_pseudo_bytes(plaintext, sizeof plaintext);
+ RAND_pseudo_bytes(iv, sizeof iv);
+ memcpy(saved_iv, iv, sizeof saved_iv);
+
+ /* Forward IGE only... */
+
+ /* Straight encrypt/decrypt */
+ AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+ AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv,
+ AES_ENCRYPT);
+
+ AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+ memcpy(iv, saved_iv, sizeof iv);
+ AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv,
+ AES_DECRYPT);
+
+ if(memcmp(checktext, plaintext, TEST_SIZE))
+ {
+ printf("Encrypt+decrypt doesn't match\n");
+ hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
+ hexdump(stdout, "Checktext", checktext, TEST_SIZE);
+ ++err;
+ }
+
+ /* Now check encrypt chaining works */
+ AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+ memcpy(iv, saved_iv, sizeof iv);
+ AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE/2, &key, iv,
+ AES_ENCRYPT);
+ AES_ige_encrypt(plaintext+TEST_SIZE/2,
+ ciphertext+TEST_SIZE/2, TEST_SIZE/2,
+ &key, iv, AES_ENCRYPT);
+
+ AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+ memcpy(iv, saved_iv, sizeof iv);
+ AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv,
+ AES_DECRYPT);
+
+ if(memcmp(checktext, plaintext, TEST_SIZE))
+ {
+ printf("Chained encrypt+decrypt doesn't match\n");
+ hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
+ hexdump(stdout, "Checktext", checktext, TEST_SIZE);
+ ++err;
+ }
+
+ /* And check decrypt chaining */
+ AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+ memcpy(iv, saved_iv, sizeof iv);
+ AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE/2, &key, iv,
+ AES_ENCRYPT);
+ AES_ige_encrypt(plaintext+TEST_SIZE/2,
+ ciphertext+TEST_SIZE/2, TEST_SIZE/2,
+ &key, iv, AES_ENCRYPT);
+
+ AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+ memcpy(iv, saved_iv, sizeof iv);
+ AES_ige_encrypt(ciphertext, checktext, TEST_SIZE/2, &key, iv,
+ AES_DECRYPT);
+ AES_ige_encrypt(ciphertext+TEST_SIZE/2,
+ checktext+TEST_SIZE/2, TEST_SIZE/2, &key, iv,
+ AES_DECRYPT);
+
+ if(memcmp(checktext, plaintext, TEST_SIZE))
+ {
+ printf("Chained encrypt+chained decrypt doesn't match\n");
+ hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
+ hexdump(stdout, "Checktext", checktext, TEST_SIZE);
+ ++err;
+ }
+
+ /* make sure garble extends forwards only */
+ AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+ memcpy(iv, saved_iv, sizeof iv);
+ AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
+ AES_ENCRYPT);
+
+ /* corrupt halfway through */
+ ++ciphertext[sizeof ciphertext/2];
+ AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+ memcpy(iv, saved_iv, sizeof iv);
+ AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
+ AES_DECRYPT);
+
+ matches=0;
+ for(n=0 ; n < sizeof checktext ; ++n)
+ if(checktext[n] == plaintext[n])
+ ++matches;
+
+ if(matches > sizeof checktext/2+sizeof checktext/100)
+ {
+ printf("More than 51%% matches after garbling\n");
+ ++err;
+ }
+
+ if(matches < sizeof checktext/2)
+ {
+ printf("Garble extends backwards!\n");
+ ++err;
+ }
+
+ /* Bi-directional IGE */
+
+ /* Note that we don't have to recover the IV, because chaining isn't */
+ /* possible with biIGE, so the IV is not updated. */
+
+ RAND_pseudo_bytes(rkey2, sizeof rkey2);
+
+ /* Straight encrypt/decrypt */
+ AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+ AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
+ AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
+ AES_ENCRYPT);
+
+ AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+ AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
+ AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
+ AES_DECRYPT);
+
+ if(memcmp(checktext, plaintext, TEST_SIZE))
+ {
+ printf("Encrypt+decrypt doesn't match\n");
+ hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
+ hexdump(stdout, "Checktext", checktext, TEST_SIZE);
+ ++err;
+ }
+
+ /* make sure garble extends both ways */
+ AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+ AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
+ AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
+ AES_ENCRYPT);
+
+ /* corrupt halfway through */
+ ++ciphertext[sizeof ciphertext/2];
+ AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+ AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
+ AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
+ AES_DECRYPT);
+
+ matches=0;
+ for(n=0 ; n < sizeof checktext ; ++n)
+ if(checktext[n] == plaintext[n])
+ ++matches;
+
+ if(matches > sizeof checktext/100)
+ {
+ printf("More than 1%% matches after bidirectional garbling\n");
+ ++err;
+ }
+
+ /* make sure garble extends both ways (2) */
+ AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+ AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
+ AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
+ AES_ENCRYPT);
+
+ /* corrupt right at the end */
+ ++ciphertext[sizeof ciphertext-1];
+ AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+ AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
+ AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
+ AES_DECRYPT);
+
+ matches=0;
+ for(n=0 ; n < sizeof checktext ; ++n)
+ if(checktext[n] == plaintext[n])
+ ++matches;
+
+ if(matches > sizeof checktext/100)
+ {
+ printf("More than 1%% matches after bidirectional garbling (2)\n");
+ ++err;
+ }
+
+ /* make sure garble extends both ways (3) */
+ AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+ AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
+ AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
+ AES_ENCRYPT);
+
+ /* corrupt right at the start */
+ ++ciphertext[0];
+ AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+ AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
+ AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
+ AES_DECRYPT);
+
+ matches=0;
+ for(n=0 ; n < sizeof checktext ; ++n)
+ if(checktext[n] == plaintext[n])
+ ++matches;
+
+ if(matches > sizeof checktext/100)
+ {
+ printf("More than 1%% matches after bidirectional garbling (3)\n");
+ ++err;
+ }
+
+ err += run_test_vectors();
+
+ return err;
+ }
diff --git a/deps/openssl/openssl/test/jpaketest.c b/deps/openssl/openssl/test/jpaketest.c
new file mode 100644
index 000000000..5b4467e04
--- /dev/null
+++ b/deps/openssl/openssl/test/jpaketest.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <openssl/e_os2.h>
+#include <openssl/buffer.h>
+#include <openssl/crypto.h>
+
+int main(int argc, char *argv[])
+ {
+ char *p, *q = 0, *program;
+
+ p = strrchr(argv[0], '/');
+ if (!p) p = strrchr(argv[0], '\\');
+#ifdef OPENSSL_SYS_VMS
+ if (!p) p = strrchr(argv[0], ']');
+ if (p) q = strrchr(p, '>');
+ if (q) p = q;
+ if (!p) p = strrchr(argv[0], ':');
+ q = 0;
+#endif
+ if (p) p++;
+ if (!p) p = argv[0];
+ if (p) q = strchr(p, '.');
+ if (p && !q) q = p + strlen(p);
+
+ if (!p)
+ program = BUF_strdup("(unknown)");
+ else
+ {
+ program = OPENSSL_malloc((q - p) + 1);
+ strncpy(program, p, q - p);
+ program[q - p] = '\0';
+ }
+
+ for(p = program; *p; p++)
+ if (islower((unsigned char)(*p)))
+ *p = toupper((unsigned char)(*p));
+
+ q = strstr(program, "TEST");
+ if (q > p && q[-1] == '_') q--;
+ *q = '\0';
+
+ printf("No %s support\n", program);
+
+ OPENSSL_free(program);
+ return(0);
+ }
diff --git a/deps/openssl/openssl/test/maketests.com b/deps/openssl/openssl/test/maketests.com
new file mode 100644
index 000000000..9b64cba23
--- /dev/null
+++ b/deps/openssl/openssl/test/maketests.com
@@ -0,0 +1,1087 @@
+$!
+$! MAKETESTS.COM
+$! Written By: Robert Byer
+$! Vice-President
+$! A-Com Computing, Inc.
+$! byer@mail.all-net.net
+$!
+$! Changes by Richard Levitte <richard@levitte.org>
+$!
+$! This command files compiles and creates all the various different
+$! "test" programs for the different types of encryption for OpenSSL.
+$! It was written so it would try to determine what "C" compiler to
+$! use or you can specify which "C" compiler to use.
+$!
+$! The test "executables" will be placed in a directory called
+$! [.xxx.EXE.TEST] where "xxx" denotes ALPHA, IA64, or VAX, depending
+$! on your machine architecture.
+$!
+$! Specify DEBUG or NODEBUG P1 to compile with or without debugger
+$! information.
+$!
+$! Specify which compiler at P2 to try to compile under.
+$!
+$! VAXC For VAX C.
+$! DECC For DEC C.
+$! GNUC For GNU C.
+$!
+$! If you don't specify a compiler, it will try to determine which
+$! "C" compiler to use.
+$!
+$! P3, if defined, sets a TCP/IP library to use, through one of the following
+$! keywords:
+$!
+$! UCX for UCX
+$! SOCKETSHR for SOCKETSHR+NETLIB
+$!
+$! P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$!
+$! P5, if defined, specifies the C pointer size. Ignored on VAX.
+$! ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
+$! Supported values are:
+$!
+$! "" Compile with default (/NOPOINTER_SIZE)
+$! 32 Compile with /POINTER_SIZE=32 (SHORT)
+$! 64 Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
+$! (Automatically select ARGV if compiler supports it.)
+$! 64= Compile with /POINTER_SIZE=64 (LONG).
+$! 64=ARGV Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
+$!
+$! P6, if defined, specifies a directory where ZLIB files (zlib.h,
+$! libz.olb) may be found. Optionally, a non-default object library
+$! name may be included ("dev:[dir]libz_64.olb", for example).
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+ f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That is, If We Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$ ZLIB_LIB = ""
+$!
+$! Check Which Architecture We Are Using.
+$!
+$ if (f$getsyi( "cpu") .lt. 128)
+$ then
+$ ARCH = "VAX"
+$ else
+$ ARCH = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if (ARCH .eqs. "") then ARCH = "UNK"
+$ endif
+$!
+$ ARCHD = ARCH
+$ LIB32 = "32"
+$ OPT_FILE = ""
+$ POINTER_SIZE = ""
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Define The OBJ and EXE Directories.
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.TEST]
+$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.TEST]
+$!
+$! Specify the destination directory in any /MAP option.
+$!
+$ if (LINKMAP .eqs. "MAP")
+$ then
+$ LINKMAP = LINKMAP+ "=''EXE_DIR'"
+$ endif
+$!
+$! Add the location prefix to the linker options file name.
+$!
+$ if (OPT_FILE .nes. "")
+$ then
+$ OPT_FILE = EXE_DIR+ OPT_FILE
+$ endif
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
+$!
+$! Define The CRYPTO-LIB We Are To Use.
+$!
+$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
+$!
+$! Define The SSL We Are To Use.
+$!
+$ SSL_LIB := SYS$DISK:[-.'ARCHD'.EXE.SSL]SSL_LIBSSL'LIB32'.OLB
+$!
+$! Create the OBJ and EXE Directories, if needed.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."") THEN -
+ CREATE /DIRECTORY 'OBJ_DIR'
+$ IF (F$PARSE(EXE_DIR).EQS."") THEN -
+ CREATE /DIRECTORY 'EXE_DIR'
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define The TEST Files.
+$! NOTE: Some might think this list ugly. However, it's made this way to
+$! reflect the EXE variable in Makefile as closely as possible,
+$! thereby making it fairly easy to verify that the lists are the same.
+$!
+$ TEST_FILES = "BNTEST,ECTEST,ECDSATEST,ECDHTEST,IDEATEST,"+ -
+ "MD2TEST,MD4TEST,MD5TEST,HMACTEST,WP_TEST,"+ -
+ "RC2TEST,RC4TEST,RC5TEST,"+ -
+ "DESTEST,SHATEST,SHA1TEST,SHA256T,SHA512T,"+ -
+ "MDC2TEST,RMDTEST,"+ -
+ "RANDTEST,DHTEST,ENGINETEST,"+ -
+ "BFTEST,CASTTEST,SSLTEST,EXPTEST,DSATEST,RSA_TEST,"+ -
+ "EVP_TEST,IGETEST,JPAKETEST,SRPTEST,"+ -
+ "ASN1TEST"
+$! Should we add MTTEST,PQ_TEST,LH_TEST,DIVTEST,TABTEST as well?
+$!
+$! Additional directory information.
+$ T_D_BNTEST := [-.crypto.bn]
+$ T_D_ECTEST := [-.crypto.ec]
+$ T_D_ECDSATEST := [-.crypto.ecdsa]
+$ T_D_ECDHTEST := [-.crypto.ecdh]
+$ T_D_IDEATEST := [-.crypto.idea]
+$ T_D_MD2TEST := [-.crypto.md2]
+$ T_D_MD4TEST := [-.crypto.md4]
+$ T_D_MD5TEST := [-.crypto.md5]
+$ T_D_HMACTEST := [-.crypto.hmac]
+$ T_D_WP_TEST := [-.crypto.whrlpool]
+$ T_D_RC2TEST := [-.crypto.rc2]
+$ T_D_RC4TEST := [-.crypto.rc4]
+$ T_D_RC5TEST := [-.crypto.rc5]
+$ T_D_DESTEST := [-.crypto.des]
+$ T_D_SHATEST := [-.crypto.sha]
+$ T_D_SHA1TEST := [-.crypto.sha]
+$ T_D_SHA256T := [-.crypto.sha]
+$ T_D_SHA512T := [-.crypto.sha]
+$ T_D_MDC2TEST := [-.crypto.mdc2]
+$ T_D_RMDTEST := [-.crypto.ripemd]
+$ T_D_RANDTEST := [-.crypto.rand]
+$ T_D_DHTEST := [-.crypto.dh]
+$ T_D_ENGINETEST := [-.crypto.engine]
+$ T_D_BFTEST := [-.crypto.bf]
+$ T_D_CASTTEST := [-.crypto.cast]
+$ T_D_SSLTEST := [-.ssl]
+$ T_D_EXPTEST := [-.crypto.bn]
+$ T_D_DSATEST := [-.crypto.dsa]
+$ T_D_RSA_TEST := [-.crypto.rsa]
+$ T_D_EVP_TEST := [-.crypto.evp]
+$ T_D_IGETEST := [-.test]
+$ T_D_JPAKETEST := [-.crypto.jpake]
+$ T_D_SRPTEST := [-.crypto.srp]
+$ T_D_ASN1TEST := [-.test]
+$!
+$ TCPIP_PROGRAMS = ",,"
+$ IF COMPILER .EQS. "VAXC" THEN -
+ TCPIP_PROGRAMS = ",SSLTEST,"
+$!
+$! Define A File Counter And Set It To "0".
+$!
+$ FILE_COUNTER = 0
+$!
+$! Top Of The File Loop.
+$!
+$ NEXT_FILE:
+$!
+$! O.K, Extract The File Name From The File List.
+$!
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",TEST_FILES)
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
+$!
+$! Increment The Counter.
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$! Create The Source File Name.
+$!
+$ SOURCE_FILE = "SYS$DISK:" + T_D_'FILE_NAME' + FILE_NAME + ".C"
+$!
+$! Create The Object File Name.
+$!
+$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
+$!
+$! Create The Executable File Name.
+$!
+$ EXE_FILE = EXE_DIR + FILE_NAME + ".EXE"
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH(SOURCE_FILE).EQS."")
+$ THEN
+$!
+$! Tell The User That The File Dosen't Exist.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Exit The Build.
+$!
+$ GOTO EXIT
+$ ENDIF
+$!
+$! Tell The User What We Are Building.
+$!
+$ WRITE SYS$OUTPUT "Building The ",FILE_NAME," Test Program."
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO NEXT_FILE
+$ CC /OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check If What We Are About To Compile Works Without A TCP/IP Library.
+$!
+$ IF ((TCPIP_LIB.EQS."").AND.((TCPIP_PROGRAMS-FILE_NAME).NES.TCPIP_PROGRAMS))
+$ THEN
+$!
+$! Inform The User That A TCP/IP Library Is Needed To Compile This Program.
+$!
+$ WRITE SYS$OUTPUT -
+ FILE_NAME," Needs A TCP/IP Library. Can't Link. Skipping..."
+$ GOTO NEXT_FILE
+$!
+$! End The TCP/IP Library Check.
+$!
+$ ENDIF
+$!
+$! Link The Program, Check To See If We Need To Link With RSAREF Or Not.
+$! Check To See If We Are To Link With A Specific TCP/IP Library.
+$!
+$! Don't Link With The RSAREF Routines And TCP/IP Library.
+$!
+$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXECTABLE = 'EXE_FILE' -
+ 'OBJECT_FILE', -
+ 'SSL_LIB' /LIBRARY, -
+ 'CRYPTO_LIB' /LIBRARY -
+ 'TCPIP_LIB' -
+ 'ZLIB_LIB' -
+ ,'OPT_FILE' /OPTIONS
+$!
+$! Go Back And Do It Again.
+$!
+$ GOTO NEXT_FILE
+$!
+$! All Done With This Library Part.
+$!
+$ FILE_DONE:
+$!
+$! All Done, Time To Exit.
+$!
+$ EXIT:
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$! Check To See If We Already Have A VAX C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A VAX C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE /SHAREABLE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If We Already Have A GNU C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A GNU C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB.OLB /LIBRARY
+SYS$SHARE:VAXCRTL.EXE /SHAREABLE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$! Check To See If We Already Have A DEC C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
+$!
+$ IF (ARCH.EQS."VAX")
+$ THEN
+$!
+$! We Need A DEC C Linker Option File For VAX.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE /SHAREABLE
+$EOD
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Create The non-VAX Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Against
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR.EXE /SHAREABLE
+SYS$SHARE:CMA$OPEN_RTL.EXE /SHAREABLE
+$EOD
+$!
+$! End The DEC C Option File Check.
+$!
+$ ENDIF
+$!
+$! End The Option File Search.
+$!
+$ ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check To See If We Have The Appropiate Libraries.
+$!
+$ LIB_CHECK:
+$!
+$! Look For The Library LIBCRYPTO.OLB.
+$!
+$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
+$ THEN
+$!
+$! Tell The User We Can't Find The LIBCRYPTO.OLB Library.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
+$ WRITE SYS$OUTPUT "We Can't Link Without It."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Since We Can't Link Without It, Exit.
+$!
+$ EXIT
+$!
+$! End The Crypto Library Check.
+$!
+$ ENDIF
+$!
+$! Look For The Library LIBSSL.OLB.
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$! Tell The User We Can't Find The LIBSSL.OLB Library.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
+$ WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Since We Can't Link Without It, Exit.
+$!
+$ EXIT
+$!
+$! End The SSL Library Check.
+$!
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Set basic C compiler /INCLUDE directories.
+$!
+$ CC_INCLUDES = "SYS$DISK:[-],SYS$DISK:[-.CRYPTO]"
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."NODEBUG")
+$ THEN
+$!
+$! P1 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$ DEBUGGER = "NODEBUG"
+$ LINKMAP = "NOMAP"
+$ TRACEBACK = "NOTRACEBACK"
+$ GCC_OPTIMIZE = "OPTIMIZE"
+$ CC_OPTIMIZE = "OPTIMIZE"
+$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Are To Compile With Debugger Information.
+$!
+$ IF (P1.EQS."DEBUG")
+$ THEN
+$!
+$! Compile With Debugger Information.
+$!
+$ DEBUGGER = "DEBUG"
+$ LINKMAP = "MAP"
+$ TRACEBACK = "TRACEBACK"
+$ GCC_OPTIMIZE = "NOOPTIMIZE"
+$ CC_OPTIMIZE = "NOOPTIMIZE"
+$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
+$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check P5 (POINTER_SIZE).
+$!
+$ IF (P5 .NES. "") .AND. (ARCH .NES. "VAX")
+$ THEN
+$!
+$ IF (P5 .EQS. "32")
+$ THEN
+$ POINTER_SIZE = " /POINTER_SIZE=32"
+$ ELSE
+$ POINTER_SIZE = F$EDIT( P5, "COLLAPSE, UPCASE")
+$ IF ((POINTER_SIZE .EQS. "64") .OR. -
+ (POINTER_SIZE .EQS. "64=") .OR. -
+ (POINTER_SIZE .EQS. "64=ARGV"))
+$ THEN
+$ ARCHD = ARCH+ "_64"
+$ LIB32 = ""
+$ IF (F$EXTRACT( 2, 1, POINTER_SIZE) .EQS. "=")
+$ THEN
+$! Explicit user choice: "64" or "64=ARGV".
+$ IF (POINTER_SIZE .EQS. "64=") THEN POINTER_SIZE = "64"
+$ ELSE
+$ SET NOON
+$ DEFINE /USER_MODE SYS$OUTPUT NL:
+$ DEFINE /USER_MODE SYS$ERROR NL:
+$ CC /NOLIST /NOOBJECT /POINTER_SIZE=64=ARGV NL:
+$ IF ($STATUS .AND. %X0FFF0000) .EQ. %X00030000
+$ THEN
+$ ! If we got here, it means DCL complained like this:
+$ ! %DCL-W-NOVALU, value not allowed - remove value specification
+$ ! \64=\
+$ !
+$ ! If the compiler was run, logicals defined in /USER would
+$ ! have been deassigned automatically. However, when DCL
+$ ! complains, they aren't, so we do it here (it might be
+$ ! unnecessary, but just in case there will be another error
+$ ! message further on that we don't want to miss)
+$ DEASSIGN /USER_MODE SYS$ERROR
+$ DEASSIGN /USER_MODE SYS$OUTPUT
+$ ELSE
+$ POINTER_SIZE = POINTER_SIZE + "=ARGV"
+$ ENDIF
+$ SET ON
+$ ENDIF
+$ POINTER_SIZE = " /POINTER_SIZE=''POINTER_SIZE'"
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ", P5, -
+ " Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT -
+ " """" : Compile with default (short) pointers."
+$ WRITE SYS$OUTPUT -
+ " 32 : Compile with 32-bit (short) pointers."
+$ WRITE SYS$OUTPUT -
+ " 64 : Compile with 64-bit (long) pointers (auto ARGV)."
+$ WRITE SYS$OUTPUT -
+ " 64= : Compile with 64-bit (long) pointers (no ARGV)."
+$ WRITE SYS$OUTPUT -
+ " 64=ARGV : Compile with 64-bit (long) pointers (ARGV)."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$ ENDIF
+$!
+$ ENDIF
+$!
+$! End The P5 (POINTER_SIZE) Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."")
+$ THEN
+$!
+$! O.K., The User Didn't Specify A Compiler, Let's Try To
+$! Find Out Which One To Use.
+$!
+$! Check To See If We Have GNU C.
+$!
+$ IF (F$TRNLNM("GNU_CC").NES."")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ P2 = "GNUC"
+$!
+$! End The GNU C Compiler Check.
+$!
+$ ELSE
+$!
+$! Check To See If We Have VAXC Or DECC.
+$!
+$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ P2 = "DECC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ P2 = "VAXC"
+$!
+$! End The VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The DECC & VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P3.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$! Find out what socket library we have available
+$!
+$ IF F$PARSE("SOCKETSHR:") .NES. ""
+$ THEN
+$!
+$! We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$ P3 = "SOCKETSHR"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$! Else, let's look for something else
+$!
+$ ELSE
+$!
+$! Like UCX (the reason to do this before Multinet is that the UCX
+$! emulation is easier to use...)
+$!
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+ .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+ .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$ THEN
+$!
+$! Last resort: a UCX or UCX-compatible library
+$!
+$ P3 = "UCX"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$! That was all...
+$!
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "TCPIP_TYPE_''P3'"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+ CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If We Have A ZLIB Option.
+$!
+$ ZLIB = P6
+$ IF (ZLIB .NES. "")
+$ THEN
+$!
+$! Check for expected ZLIB files.
+$!
+$ err = 0
+$ file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
+$ if (f$search( file1) .eqs. "")
+$ then
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$ WRITE SYS$OUTPUT " Can't find header: ''file1'"
+$ err = 1
+$ endif
+$ file1 = f$parse( "A.;", ZLIB)- "A.;"
+$!
+$ file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
+$ if (f$search( file2) .eqs. "")
+$ then
+$ if (err .eq. 0)
+$ then
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$ endif
+$ WRITE SYS$OUTPUT " Can't find library: ''file2'"
+$ WRITE SYS$OUTPUT ""
+$ err = err+ 2
+$ endif
+$ if (err .eq. 1)
+$ then
+$ WRITE SYS$OUTPUT ""
+$ endif
+$!
+$ if (err .ne. 0)
+$ then
+$ GOTO EXIT
+$ endif
+$!
+$ CCDEFS = """ZLIB=1"", "+ CCDEFS
+$ CC_INCLUDES = CC_INCLUDES+ ", "+ file1
+$ ZLIB_LIB = ", ''file2' /library"
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "ZLIB library spec: ", file2
+$!
+$! End The P8 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The User Entered A Valid Parameter.
+$!
+$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If The User Wanted DECC.
+$!
+$ IF (P2.EQS."DECC")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ COMPILER = "DECC"
+$!
+$! Tell The User We Are Using DECC.
+$!
+$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$! Use DECC...
+$!
+$ CC = "CC"
+$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+ THEN CC = "CC /DECC"
+$ CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
+ "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
+ " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "VAX_DECC_OPTIONS.OPT"
+$!
+$! End DECC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use VAXC.
+$!
+$ IF (P2.EQS."VAXC")
+$ THEN
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ COMPILER = "VAXC"
+$!
+$! Tell The User We Are Using VAX C.
+$!
+$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$! Compile Using VAXC.
+$!
+$ CC = "CC"
+$ IF ARCH.NES."VAX"
+$ THEN
+$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$ EXIT
+$ ENDIF
+$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC /VAXC"
+$ CC = CC + "/''CC_OPTIMIZE' /''DEBUGGER' /NOLIST" + -
+ "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
+$ CCDEFS = CCDEFS + ",""VAXC"""
+$!
+$! Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$ DEFINE /NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
+$!
+$! End VAXC Check
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use GNU C.
+$!
+$ IF (P2.EQS."GNUC")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ COMPILER = "GNUC"
+$!
+$! Tell The User We Are Using GNUC.
+$!
+$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$! Use GNU C...
+$!
+$ CC = "GCC /NOCASE_HACK /''GCC_OPTIMIZE' /''DEBUGGER' /NOLIST" + -
+ "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Set up default defines
+$!
+$ CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$! Finish up the definition of CC.
+$!
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$ IF CCDISABLEWARNINGS .EQS. ""
+$ THEN
+$ CC4DISABLEWARNINGS = "DOLLARID"
+$ ELSE
+$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
+$ CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$ ENDIF
+$ CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
+$ ELSE
+$ CCDISABLEWARNINGS = ""
+$ CC4DISABLEWARNINGS = ""
+$ ENDIF
+$ CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$! Show user the result
+$!
+$ WRITE /SYMBOL SYS$OUTPUT "Main Compiling Command: ", CC
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
+$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
+$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$ ENDIF
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
+ .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
+$ THEN
+$!
+$! Check to see if SOCKETSHR was chosen
+$!
+$ IF P3.EQS."SOCKETSHR"
+$ THEN
+$!
+$! Set the library to use SOCKETSHR
+$!
+$ TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
+$!
+$! Done with SOCKETSHR
+$!
+$ ENDIF
+$!
+$! Check to see if MULTINET was chosen
+$!
+$ IF P3.EQS."MULTINET"
+$ THEN
+$!
+$! Set the library to use UCX emulation.
+$!
+$ P3 = "UCX"
+$!
+$! Done with MULTINET
+$!
+$ ENDIF
+$!
+$! Check to see if UCX was chosen
+$!
+$ IF P3.EQS."UCX"
+$ THEN
+$!
+$! Set the library to use UCX.
+$!
+$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$ THEN
+$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
+$ ELSE
+$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
+$ ENDIF
+$!
+$! Done with UCX
+$!
+$ ENDIF
+$!
+$! Check to see if TCPIP was chosen
+$!
+$ IF P3.EQS."TCPIP"
+$ THEN
+$!
+$! Set the library to use TCPIP (post UCX).
+$!
+$ TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Check to see if NONE was chosen
+$!
+$ IF P3.EQS."NONE"
+$ THEN
+$!
+$! Do not use a TCPIP library.
+$!
+$ TCPIP_LIB = ""
+$!
+$! Done with NONE
+$!
+$ ENDIF
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
+$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
+$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$! Get The Version Of VMS We Are Using.
+$!
+$ ISSEVEN :=
+$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$! Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$ IF (TMP.GE.71)
+$ THEN
+$!
+$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$ ISSEVEN := ,PTHREAD_USE_D4
+$!
+$! End The VMS Version Check.
+$!
+$ ENDIF
+$!
+$! End The P4 Check.
+$!
+$ ENDIF
+$!
+$! Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "TEST]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL /NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$ DEASSIGN OPENSSL
+$ ELSE
+$ DEFINE /NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/deps/openssl/openssl/test/md2test.c b/deps/openssl/openssl/test/md2test.c
new file mode 100644
index 000000000..5b4467e04
--- /dev/null
+++ b/deps/openssl/openssl/test/md2test.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <openssl/e_os2.h>
+#include <openssl/buffer.h>
+#include <openssl/crypto.h>
+
+int main(int argc, char *argv[])
+ {
+ char *p, *q = 0, *program;
+
+ p = strrchr(argv[0], '/');
+ if (!p) p = strrchr(argv[0], '\\');
+#ifdef OPENSSL_SYS_VMS
+ if (!p) p = strrchr(argv[0], ']');
+ if (p) q = strrchr(p, '>');
+ if (q) p = q;
+ if (!p) p = strrchr(argv[0], ':');
+ q = 0;
+#endif
+ if (p) p++;
+ if (!p) p = argv[0];
+ if (p) q = strchr(p, '.');
+ if (p && !q) q = p + strlen(p);
+
+ if (!p)
+ program = BUF_strdup("(unknown)");
+ else
+ {
+ program = OPENSSL_malloc((q - p) + 1);
+ strncpy(program, p, q - p);
+ program[q - p] = '\0';
+ }
+
+ for(p = program; *p; p++)
+ if (islower((unsigned char)(*p)))
+ *p = toupper((unsigned char)(*p));
+
+ q = strstr(program, "TEST");
+ if (q > p && q[-1] == '_') q--;
+ *q = '\0';
+
+ printf("No %s support\n", program);
+
+ OPENSSL_free(program);
+ return(0);
+ }
diff --git a/deps/openssl/openssl/test/md4test.c b/deps/openssl/openssl/test/md4test.c
new file mode 100644
index 000000000..56591728a
--- /dev/null
+++ b/deps/openssl/openssl/test/md4test.c
@@ -0,0 +1,136 @@
+/* crypto/md4/md4test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_MD4
+int main(int argc, char *argv[])
+{
+ printf("No MD4 support\n");
+ return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/md4.h>
+
+static char *test[]={
+ "",
+ "a",
+ "abc",
+ "message digest",
+ "abcdefghijklmnopqrstuvwxyz",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ NULL,
+ };
+
+static char *ret[]={
+"31d6cfe0d16ae931b73c59d7e0c089c0",
+"bde52cb31de33e46245e05fbdbd6fb24",
+"a448017aaf21d8525fc10ae87aa6729d",
+"d9130a8164549fe818874806e1c7014b",
+"d79e1c308aa5bbcdeea8ed63df412da9",
+"043f8582f241db351ce627e153e7f0e4",
+"e33b4ddc9c38f2199c3e7b164fcc0536",
+};
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+ {
+ int i,err=0;
+ char **P,**R;
+ char *p;
+ unsigned char md[MD4_DIGEST_LENGTH];
+
+ P=test;
+ R=ret;
+ i=1;
+ while (*P != NULL)
+ {
+ EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_md4(), NULL);
+ p=pt(md);
+ if (strcmp(p,(char *)*R) != 0)
+ {
+ printf("error calculating MD4 on '%s'\n",*P);
+ printf("got %s instead of %s\n",p,*R);
+ err++;
+ }
+ else
+ printf("test %d ok\n",i);
+ i++;
+ R++;
+ P++;
+ }
+ EXIT(err);
+ return(0);
+ }
+
+static char *pt(unsigned char *md)
+ {
+ int i;
+ static char buf[80];
+
+ for (i=0; i<MD4_DIGEST_LENGTH; i++)
+ sprintf(&(buf[i*2]),"%02x",md[i]);
+ return(buf);
+ }
+#endif
diff --git a/deps/openssl/openssl/test/md5test.c b/deps/openssl/openssl/test/md5test.c
new file mode 100644
index 000000000..2b37190e3
--- /dev/null
+++ b/deps/openssl/openssl/test/md5test.c
@@ -0,0 +1,140 @@
+/* crypto/md5/md5test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_MD5
+int main(int argc, char *argv[])
+{
+ printf("No MD5 support\n");
+ return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+
+static char *test[]={
+ "",
+ "a",
+ "abc",
+ "message digest",
+ "abcdefghijklmnopqrstuvwxyz",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ NULL,
+ };
+
+static char *ret[]={
+ "d41d8cd98f00b204e9800998ecf8427e",
+ "0cc175b9c0f1b6a831c399e269772661",
+ "900150983cd24fb0d6963f7d28e17f72",
+ "f96b697d7cb7938d525a2f31aaf161d0",
+ "c3fcd3d76192e4007dfb496cca67e13b",
+ "d174ab98d277d9f5a5611c2c9f419d9f",
+ "57edf4a22be3c955ac49da2e2107b67a",
+ };
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+ {
+ int i,err=0;
+ char **P,**R;
+ char *p;
+ unsigned char md[MD5_DIGEST_LENGTH];
+
+ P=test;
+ R=ret;
+ i=1;
+ while (*P != NULL)
+ {
+ EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_md5(), NULL);
+ p=pt(md);
+ if (strcmp(p,(char *)*R) != 0)
+ {
+ printf("error calculating MD5 on '%s'\n",*P);
+ printf("got %s instead of %s\n",p,*R);
+ err++;
+ }
+ else
+ printf("test %d ok\n",i);
+ i++;
+ R++;
+ P++;
+ }
+
+#ifdef OPENSSL_SYS_NETWARE
+ if (err) printf("ERROR: %d\n", err);
+#endif
+ EXIT(err);
+ return(0);
+ }
+
+static char *pt(unsigned char *md)
+ {
+ int i;
+ static char buf[80];
+
+ for (i=0; i<MD5_DIGEST_LENGTH; i++)
+ sprintf(&(buf[i*2]),"%02x",md[i]);
+ return(buf);
+ }
+#endif
diff --git a/deps/openssl/openssl/test/mdc2test.c b/deps/openssl/openssl/test/mdc2test.c
new file mode 100644
index 000000000..017b31add
--- /dev/null
+++ b/deps/openssl/openssl/test/mdc2test.c
@@ -0,0 +1,149 @@
+/* crypto/mdc2/mdc2test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#if defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_MDC2)
+#define OPENSSL_NO_MDC2
+#endif
+
+#ifdef OPENSSL_NO_MDC2
+int main(int argc, char *argv[])
+{
+ printf("No MDC2 support\n");
+ return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/mdc2.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+static unsigned char pad1[16]={
+ 0x42,0xE5,0x0C,0xD2,0x24,0xBA,0xCE,0xBA,
+ 0x76,0x0B,0xDD,0x2B,0xD4,0x09,0x28,0x1A
+ };
+
+static unsigned char pad2[16]={
+ 0x2E,0x46,0x79,0xB5,0xAD,0xD9,0xCA,0x75,
+ 0x35,0xD8,0x7A,0xFE,0xAB,0x33,0xBE,0xE2
+ };
+
+int main(int argc, char *argv[])
+ {
+ int ret=0;
+ unsigned char md[MDC2_DIGEST_LENGTH];
+ int i;
+ EVP_MD_CTX c;
+ static char *text="Now is the time for all ";
+
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(text,text,strlen(text));
+#endif
+
+ EVP_MD_CTX_init(&c);
+ EVP_DigestInit_ex(&c,EVP_mdc2(), NULL);
+ EVP_DigestUpdate(&c,(unsigned char *)text,strlen(text));
+ EVP_DigestFinal_ex(&c,&(md[0]),NULL);
+
+ if (memcmp(md,pad1,MDC2_DIGEST_LENGTH) != 0)
+ {
+ for (i=0; i<MDC2_DIGEST_LENGTH; i++)
+ printf("%02X",md[i]);
+ printf(" <- generated\n");
+ for (i=0; i<MDC2_DIGEST_LENGTH; i++)
+ printf("%02X",pad1[i]);
+ printf(" <- correct\n");
+ ret=1;
+ }
+ else
+ printf("pad1 - ok\n");
+
+ EVP_DigestInit_ex(&c,EVP_mdc2(), NULL);
+ /* FIXME: use a ctl function? */
+ ((MDC2_CTX *)c.md_data)->pad_type=2;
+ EVP_DigestUpdate(&c,(unsigned char *)text,strlen(text));
+ EVP_DigestFinal_ex(&c,&(md[0]),NULL);
+
+ if (memcmp(md,pad2,MDC2_DIGEST_LENGTH) != 0)
+ {
+ for (i=0; i<MDC2_DIGEST_LENGTH; i++)
+ printf("%02X",md[i]);
+ printf(" <- generated\n");
+ for (i=0; i<MDC2_DIGEST_LENGTH; i++)
+ printf("%02X",pad2[i]);
+ printf(" <- correct\n");
+ ret=1;
+ }
+ else
+ printf("pad2 - ok\n");
+
+ EVP_MD_CTX_cleanup(&c);
+#ifdef OPENSSL_SYS_NETWARE
+ if (ret) printf("ERROR: %d\n", ret);
+#endif
+ EXIT(ret);
+ return(ret);
+ }
+#endif
diff --git a/deps/openssl/openssl/test/methtest.c b/deps/openssl/openssl/test/methtest.c
new file mode 100644
index 000000000..005c2f482
--- /dev/null
+++ b/deps/openssl/openssl/test/methtest.c
@@ -0,0 +1,105 @@
+/* test/methtest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/rsa.h>
+#include <openssl/x509.h>
+#include "meth.h"
+#include <openssl/err.h>
+
+int main(argc,argv)
+int argc;
+char *argv[];
+ {
+ METHOD_CTX *top,*tmp1,*tmp2;
+
+ top=METH_new(x509_lookup()); /* get a top level context */
+ if (top == NULL) goto err;
+
+ tmp1=METH_new(x509_by_file());
+ if (top == NULL) goto err;
+ METH_arg(tmp1,METH_TYPE_FILE,"cafile1");
+ METH_arg(tmp1,METH_TYPE_FILE,"cafile2");
+ METH_push(top,METH_X509_CA_BY_SUBJECT,tmp1);
+
+ tmp2=METH_new(x509_by_dir());
+ METH_arg(tmp2,METH_TYPE_DIR,"/home/eay/.CAcerts");
+ METH_arg(tmp2,METH_TYPE_DIR,"/home/eay/SSLeay/certs");
+ METH_arg(tmp2,METH_TYPE_DIR,"/usr/local/ssl/certs");
+ METH_push(top,METH_X509_CA_BY_SUBJECT,tmp2);
+
+/* tmp=METH_new(x509_by_issuer_dir);
+ METH_arg(tmp,METH_TYPE_DIR,"/home/eay/.mycerts");
+ METH_push(top,METH_X509_BY_ISSUER,tmp);
+
+ tmp=METH_new(x509_by_issuer_primary);
+ METH_arg(tmp,METH_TYPE_FILE,"/home/eay/.mycerts/primary.pem");
+ METH_push(top,METH_X509_BY_ISSUER,tmp);
+*/
+
+ METH_init(top);
+ METH_control(tmp1,METH_CONTROL_DUMP,stdout);
+ METH_control(tmp2,METH_CONTROL_DUMP,stdout);
+ EXIT(0);
+err:
+ ERR_load_crypto_strings();
+ ERR_print_errors_fp(stderr);
+ EXIT(1);
+ return(0);
+ }
diff --git a/deps/openssl/openssl/test/pkcs7-1.pem b/deps/openssl/openssl/test/pkcs7-1.pem
new file mode 100644
index 000000000..c47b27af8
--- /dev/null
+++ b/deps/openssl/openssl/test/pkcs7-1.pem
@@ -0,0 +1,15 @@
+-----BEGIN PKCS7-----
+MIICUAYJKoZIhvcNAQcCoIICQTCCAj0CAQExDjAMBggqhkiG9w0CAgUAMCgGCSqG
+SIb3DQEHAaAbBBlFdmVyeW9uZSBnZXRzIEZyaWRheSBvZmYuoIIBXjCCAVowggEE
+AgQUAAApMA0GCSqGSIb3DQEBAgUAMCwxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRF
+eGFtcGxlIE9yZ2FuaXphdGlvbjAeFw05MjA5MDkyMjE4MDZaFw05NDA5MDkyMjE4
+MDVaMEIxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRFeGFtcGxlIE9yZ2FuaXphdGlv
+bjEUMBIGA1UEAxMLVGVzdCBVc2VyIDEwWzANBgkqhkiG9w0BAQEFAANKADBHAkAK
+ZnkdxpiBaN56t3QZu3+wwAHGJxAnAHUUKULhmo2MUdBTs+N4Kh3l3Fr06+mUaBcB
+FKHf5nzcmpr1XWVWILurAgMBAAEwDQYJKoZIhvcNAQECBQADQQBFGqHhqncgSl/N
+9XYGnQL3MsJvNnsNV4puZPOakR9Hld8JlDQFEaDR30ogsmp3TMrvdfxpLlTCoZN8
+BxEmnZsWMYGbMIGYAgEBMDQwLDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFEV4YW1w
+bGUgT3JnYW5pemF0aW9uAgQUAAApMAwGCCqGSIb3DQICBQAwDQYJKoZIhvcNAQEB
+BQAEQAX6aoEvx9+L9PJUJQngPoRuEbnGIL4gCe+0QO+8xmkhaZSsBPNBtX0FIC1C
+j7Kie1x339mxW/w9VZNTUDQQweHh
+-----END PKCS7-----
diff --git a/deps/openssl/openssl/test/pkcs7.pem b/deps/openssl/openssl/test/pkcs7.pem
new file mode 100644
index 000000000..d55c60b94
--- /dev/null
+++ b/deps/openssl/openssl/test/pkcs7.pem
@@ -0,0 +1,54 @@
+ MIAGCSqGSIb3DQEHAqCAMIACAQExADCABgkqhkiG9w0BBwEAAKCAMIIE+DCCBGGg
+ AwIBAgIQaGSF/JpbS1C223+yrc+N1DANBgkqhkiG9w0BAQQFADBiMREwDwYDVQQH
+ EwhJbnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNVBAsTK1Zl
+ cmlTaWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXIwHhcNOTYw
+ ODEyMDAwMDAwWhcNOTYwODE3MjM1OTU5WjCCASAxETAPBgNVBAcTCEludGVybmV0
+ MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xh
+ c3MgMSBDQSAtIEluZGl2aWR1YWwgU3Vic2NyaWJlcjE3MDUGA1UECxMuRGlnaXRh
+ bCBJRCBDbGFzcyAxIC0gU01JTUUgVmVyaVNpZ24sIEluYy4gVEVTVDFGMEQGA1UE
+ CxM9d3d3LnZlcmlzaWduLmNvbS9yZXBvc2l0b3J5L0NQUyBJbmNvcnAuIGJ5IFJl
+ Zi4sTElBQi5MVEQoYyk5NjEZMBcGA1UEAxMQQWxleGFuZHJlIERlYWNvbjEgMB4G
+ CSqGSIb3DQEJARYRYWxleEB2ZXJpc2lnbi5jb20wWzANBgkqhkiG9w0BAQEFAANK
+ ADBHAkAOy7xxCAIkOfuIA2LyRpxgKlDORl8htdXYhF5iBGUx1GYaK6KF+bK/CCI0
+ l4j2OfWGFBUrwGoWqxTNcWgTfMzRAgMBAAGjggIyMIICLjAJBgNVHRMEAjAAMIIC
+ HwYDVR0DBIICFjCCAhIwggIOMIICCgYLYIZIAYb4RQEHAQEwggH5FoIBp1RoaXMg
+ Y2VydGlmaWNhdGUgaW5jb3Jwb3JhdGVzIGJ5IHJlZmVyZW5jZSwgYW5kIGl0cyB1
+ c2UgaXMgc3RyaWN0bHkgc3ViamVjdCB0bywgdGhlIFZlcmlTaWduIENlcnRpZmlj
+ YXRpb24gUHJhY3RpY2UgU3RhdGVtZW50IChDUFMpLCBhdmFpbGFibGUgYXQ6IGh0
+ dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9DUFM7IGJ5IEUtbWFpbCBhdCBDUFMtcmVx
+ dWVzdHNAdmVyaXNpZ24uY29tOyBvciBieSBtYWlsIGF0IFZlcmlTaWduLCBJbmMu
+ LCAyNTkzIENvYXN0IEF2ZS4sIE1vdW50YWluIFZpZXcsIENBIDk0MDQzIFVTQSBU
+ ZWwuICsxICg0MTUpIDk2MS04ODMwIENvcHlyaWdodCAoYykgMTk5NiBWZXJpU2ln
+ biwgSW5jLiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4gQ0VSVEFJTiBXQVJSQU5USUVT
+ IERJU0NMQUlNRUQgYW5kIExJQUJJTElUWSBMSU1JVEVELqAOBgxghkgBhvhFAQcB
+ AQGhDgYMYIZIAYb4RQEHAQECMCwwKhYoaHR0cHM6Ly93d3cudmVyaXNpZ24uY29t
+ L3JlcG9zaXRvcnkvQ1BTIDANBgkqhkiG9w0BAQQFAAOBgQAimWMGQwwwxk+b3KAL
+ HlSWXtU7LWHe29CEG8XeVNTvrqs6SBqT7OoENOkGxpfdpVgZ3Qw2SKjxDvbvpfSF
+ slsqcxWSgB/hWuaVuZCkvTw/dYGGOxkTJGxvDCfl1PZjX4dKbatslsi9Z9HpGWT7
+ ttItRwKqcBKgmCJvKi1pGWED0zCCAnkwggHioAMCAQICEDURpVKQb+fQKaRAGdQR
+ /D4wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlT
+ aWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRp
+ ZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDYyNzAwMDAwMFoXDTk3MDYyNzIzNTk1
+ OVowYjERMA8GA1UEBxMISW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMu
+ MTQwMgYDVQQLEytWZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5kaXZpZHVhbCBTdWJz
+ Y3JpYmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2FKbPTdAFDdjKI9Bv
+ qrQpkmOOLPhvltcunXZLEbE2jVfJw/0cxrr+Hgi6M8qV6r7jW80GqLd5HUQq7XPy
+ sVKDaBBwZJHXPmv5912dFEObbpdFmIFH0S3L3bty10w/cariQPJUObwW7s987Lrb
+ P2wqsxaxhhKdrpM01bjV0Pc+qQIDAQABozMwMTAPBgNVHRMECDAGAQH/AgEBMAsG
+ A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAgQwDQYJKoZIhvcNAQECBQADgYEA
+ KeXHoBmnbxRCgk0jM9e9mDppdxpsipIna/J8DOHEUuD4nONAr4+xOg73SBl026n7
+ Bk55A2wvAMGo7+kKTZ+rHaFDDcmq4O+rzFri2RIOeGAncj1IcGptAQhvXoIhFMG4
+ Jlzg1KlHZHqy7D3jex78zcSU7kKOu8f5tAX1jC3+sToAAKGAMIIBJzCBkTANBgkq
+ hkiG9w0BAQIFADBiMREwDwYDVQQHEwhJbnRlcm5ldDEXMBUGA1UEChMOVmVyaVNp
+ Z24sIEluYy4xNDAyBgNVBAsTK1ZlcmlTaWduIENsYXNzIDEgQ0EgLSBJbmRpdmlk
+ dWFsIFN1YnNjcmliZXIXDTk2MDcwMTE3MzA0MFoXDTk3MDcwMTAwMDAwMFowDQYJ
+ KoZIhvcNAQECBQADgYEAGLuQ6PX8A7AiqBEtWzYtl6lZNSDI0bR5YUo+D2Jzkw30
+ dxQnJSbKXEc6XYuzAW5HvrzATXu5c19WWPT4cRDwmjH71i9QcDysWwf/wE0qGTiW
+ I3tQT0I5VGh7jIJD07nlBw3R4Xl8dH9kr85JsWinqDH5YKpIo9o8knY5n7+qjOow
+ ggEkMIGOMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5W
+ ZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJpbWFyeSBD
+ ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eRcNOTYwNzE2MjMxMTI5WhcNOTYwODE1MDAw
+ MDAwWjANBgkqhkiG9w0BAQIFAAOBgQAXsLE4vnsY6sY67QrmWec7iaU2ehzxanEK
+ /9wKHZNuhlNzk+qGZZw2evxfUe2OaRbYpl8zuZvhK9BHD3ad14OSe9/zx5hOPgP/
+ DQXt6R4R8Q/1JheBrolrgbavjvI2wKS8/Psp2prBrkF4T48+AKRmS8Zzh1guxgvP
+ b+xSu/jH0gAAMYAAAAAAAAAAAA==
diff --git a/deps/openssl/openssl/test/pkits-test.pl b/deps/openssl/openssl/test/pkits-test.pl
new file mode 100644
index 000000000..5c6b89fcd
--- /dev/null
+++ b/deps/openssl/openssl/test/pkits-test.pl
@@ -0,0 +1,949 @@
+# test/pkits-test.pl
+# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+# project.
+#
+# ====================================================================
+# Copyright (c) 2008 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
+# licensing@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.
+# ====================================================================
+
+# Perl utility to run PKITS tests for RFC3280 compliance.
+
+my $ossl_path;
+
+if ( -f "../apps/openssl" ) {
+ $ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
+}
+elsif ( -f "..\\out32dll\\openssl.exe" ) {
+ $ossl_path = "..\\out32dll\\openssl.exe";
+}
+elsif ( -f "..\\out32\\openssl.exe" ) {
+ $ossl_path = "..\\out32\\openssl.exe";
+}
+else {
+ die "Can't find OpenSSL executable";
+}
+
+my $pkitsdir = "pkits/smime";
+my $pkitsta = "pkits/certs/TrustAnchorRootCertificate.crt";
+
+die "Can't find PKITS test data" if !-d $pkitsdir;
+
+my $nist1 = "2.16.840.1.101.3.2.1.48.1";
+my $nist2 = "2.16.840.1.101.3.2.1.48.2";
+my $nist3 = "2.16.840.1.101.3.2.1.48.3";
+my $nist4 = "2.16.840.1.101.3.2.1.48.4";
+my $nist5 = "2.16.840.1.101.3.2.1.48.5";
+my $nist6 = "2.16.840.1.101.3.2.1.48.6";
+
+my $apolicy = "X509v3 Any Policy";
+
+# This table contains the chapter headings of the accompanying PKITS
+# document. They provide useful informational output and their names
+# can be converted into the filename to test.
+
+my @testlists = (
+ [ "4.1", "Signature Verification" ],
+ [ "4.1.1", "Valid Signatures Test1", 0 ],
+ [ "4.1.2", "Invalid CA Signature Test2", 7 ],
+ [ "4.1.3", "Invalid EE Signature Test3", 7 ],
+ [ "4.1.4", "Valid DSA Signatures Test4", 0 ],
+ [ "4.1.5", "Valid DSA Parameter Inheritance Test5", 0 ],
+ [ "4.1.6", "Invalid DSA Signature Test6", 7 ],
+ [ "4.2", "Validity Periods" ],
+ [ "4.2.1", "Invalid CA notBefore Date Test1", 9 ],
+ [ "4.2.2", "Invalid EE notBefore Date Test2", 9 ],
+ [ "4.2.3", "Valid pre2000 UTC notBefore Date Test3", 0 ],
+ [ "4.2.4", "Valid GeneralizedTime notBefore Date Test4", 0 ],
+ [ "4.2.5", "Invalid CA notAfter Date Test5", 10 ],
+ [ "4.2.6", "Invalid EE notAfter Date Test6", 10 ],
+ [ "4.2.7", "Invalid pre2000 UTC EE notAfter Date Test7", 10 ],
+ [ "4.2.8", "Valid GeneralizedTime notAfter Date Test8", 0 ],
+ [ "4.3", "Verifying Name Chaining" ],
+ [ "4.3.1", "Invalid Name Chaining EE Test1", 20 ],
+ [ "4.3.2", "Invalid Name Chaining Order Test2", 20 ],
+ [ "4.3.3", "Valid Name Chaining Whitespace Test3", 0 ],
+ [ "4.3.4", "Valid Name Chaining Whitespace Test4", 0 ],
+ [ "4.3.5", "Valid Name Chaining Capitalization Test5", 0 ],
+ [ "4.3.6", "Valid Name Chaining UIDs Test6", 0 ],
+ [ "4.3.7", "Valid RFC3280 Mandatory Attribute Types Test7", 0 ],
+ [ "4.3.8", "Valid RFC3280 Optional Attribute Types Test8", 0 ],
+ [ "4.3.9", "Valid UTF8String Encoded Names Test9", 0 ],
+ [ "4.3.10", "Valid Rollover from PrintableString to UTF8String Test10", 0 ],
+ [ "4.3.11", "Valid UTF8String Case Insensitive Match Test11", 0 ],
+ [ "4.4", "Basic Certificate Revocation Tests" ],
+ [ "4.4.1", "Missing CRL Test1", 3 ],
+ [ "4.4.2", "Invalid Revoked CA Test2", 23 ],
+ [ "4.4.3", "Invalid Revoked EE Test3", 23 ],
+ [ "4.4.4", "Invalid Bad CRL Signature Test4", 8 ],
+ [ "4.4.5", "Invalid Bad CRL Issuer Name Test5", 3 ],
+ [ "4.4.6", "Invalid Wrong CRL Test6", 3 ],
+ [ "4.4.7", "Valid Two CRLs Test7", 0 ],
+
+ # The test document suggests these should return certificate revoked...
+ # Subsquent discussion has concluded they should not due to unhandle
+ # critical CRL extensions.
+ [ "4.4.8", "Invalid Unknown CRL Entry Extension Test8", 36 ],
+ [ "4.4.9", "Invalid Unknown CRL Extension Test9", 36 ],
+
+ [ "4.4.10", "Invalid Unknown CRL Extension Test10", 36 ],
+ [ "4.4.11", "Invalid Old CRL nextUpdate Test11", 12 ],
+ [ "4.4.12", "Invalid pre2000 CRL nextUpdate Test12", 12 ],
+ [ "4.4.13", "Valid GeneralizedTime CRL nextUpdate Test13", 0 ],
+ [ "4.4.14", "Valid Negative Serial Number Test14", 0 ],
+ [ "4.4.15", "Invalid Negative Serial Number Test15", 23 ],
+ [ "4.4.16", "Valid Long Serial Number Test16", 0 ],
+ [ "4.4.17", "Valid Long Serial Number Test17", 0 ],
+ [ "4.4.18", "Invalid Long Serial Number Test18", 23 ],
+ [ "4.4.19", "Valid Separate Certificate and CRL Keys Test19", 0 ],
+ [ "4.4.20", "Invalid Separate Certificate and CRL Keys Test20", 23 ],
+
+ # CRL path is revoked so get a CRL path validation error
+ [ "4.4.21", "Invalid Separate Certificate and CRL Keys Test21", 54 ],
+ [ "4.5", "Verifying Paths with Self-Issued Certificates" ],
+ [ "4.5.1", "Valid Basic Self-Issued Old With New Test1", 0 ],
+ [ "4.5.2", "Invalid Basic Self-Issued Old With New Test2", 23 ],
+ [ "4.5.3", "Valid Basic Self-Issued New With Old Test3", 0 ],
+ [ "4.5.4", "Valid Basic Self-Issued New With Old Test4", 0 ],
+ [ "4.5.5", "Invalid Basic Self-Issued New With Old Test5", 23 ],
+ [ "4.5.6", "Valid Basic Self-Issued CRL Signing Key Test6", 0 ],
+ [ "4.5.7", "Invalid Basic Self-Issued CRL Signing Key Test7", 23 ],
+ [ "4.5.8", "Invalid Basic Self-Issued CRL Signing Key Test8", 20 ],
+ [ "4.6", "Verifying Basic Constraints" ],
+ [ "4.6.1", "Invalid Missing basicConstraints Test1", 24 ],
+ [ "4.6.2", "Invalid cA False Test2", 24 ],
+ [ "4.6.3", "Invalid cA False Test3", 24 ],
+ [ "4.6.4", "Valid basicConstraints Not Critical Test4", 0 ],
+ [ "4.6.5", "Invalid pathLenConstraint Test5", 25 ],
+ [ "4.6.6", "Invalid pathLenConstraint Test6", 25 ],
+ [ "4.6.7", "Valid pathLenConstraint Test7", 0 ],
+ [ "4.6.8", "Valid pathLenConstraint Test8", 0 ],
+ [ "4.6.9", "Invalid pathLenConstraint Test9", 25 ],
+ [ "4.6.10", "Invalid pathLenConstraint Test10", 25 ],
+ [ "4.6.11", "Invalid pathLenConstraint Test11", 25 ],
+ [ "4.6.12", "Invalid pathLenConstraint Test12", 25 ],
+ [ "4.6.13", "Valid pathLenConstraint Test13", 0 ],
+ [ "4.6.14", "Valid pathLenConstraint Test14", 0 ],
+ [ "4.6.15", "Valid Self-Issued pathLenConstraint Test15", 0 ],
+ [ "4.6.16", "Invalid Self-Issued pathLenConstraint Test16", 25 ],
+ [ "4.6.17", "Valid Self-Issued pathLenConstraint Test17", 0 ],
+ [ "4.7", "Key Usage" ],
+ [ "4.7.1", "Invalid keyUsage Critical keyCertSign False Test1", 20 ],
+ [ "4.7.2", "Invalid keyUsage Not Critical keyCertSign False Test2", 20 ],
+ [ "4.7.3", "Valid keyUsage Not Critical Test3", 0 ],
+ [ "4.7.4", "Invalid keyUsage Critical cRLSign False Test4", 35 ],
+ [ "4.7.5", "Invalid keyUsage Not Critical cRLSign False Test5", 35 ],
+
+ # Certificate policy tests need special handling. They can have several
+ # sub tests and we need to check the outputs are correct.
+
+ [ "4.8", "Certificate Policies" ],
+ [
+ "4.8.1.1",
+ "All Certificates Same Policy Test1",
+ "-policy anyPolicy -explicit_policy",
+ "True", $nist1, $nist1, 0
+ ],
+ [
+ "4.8.1.2",
+ "All Certificates Same Policy Test1",
+ "-policy $nist1 -explicit_policy",
+ "True", $nist1, $nist1, 0
+ ],
+ [
+ "4.8.1.3",
+ "All Certificates Same Policy Test1",
+ "-policy $nist2 -explicit_policy",
+ "True", $nist1, "<empty>", 43
+ ],
+ [
+ "4.8.1.4",
+ "All Certificates Same Policy Test1",
+ "-policy $nist1 -policy $nist2 -explicit_policy",
+ "True", $nist1, $nist1, 0
+ ],
+ [
+ "4.8.2.1",
+ "All Certificates No Policies Test2",
+ "-policy anyPolicy",
+ "False", "<empty>", "<empty>", 0
+ ],
+ [
+ "4.8.2.2",
+ "All Certificates No Policies Test2",
+ "-policy anyPolicy -explicit_policy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.8.3.1",
+ "Different Policies Test3",
+ "-policy anyPolicy",
+ "False", "<empty>", "<empty>", 0
+ ],
+ [
+ "4.8.3.2",
+ "Different Policies Test3",
+ "-policy anyPolicy -explicit_policy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.8.3.3",
+ "Different Policies Test3",
+ "-policy $nist1 -policy $nist2 -explicit_policy",
+ "True", "<empty>", "<empty>", 43
+ ],
+
+ [
+ "4.8.4",
+ "Different Policies Test4",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.8.5",
+ "Different Policies Test5",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.8.6.1",
+ "Overlapping Policies Test6",
+ "-policy anyPolicy",
+ "True", $nist1, $nist1, 0
+ ],
+ [
+ "4.8.6.2",
+ "Overlapping Policies Test6",
+ "-policy $nist1",
+ "True", $nist1, $nist1, 0
+ ],
+ [
+ "4.8.6.3",
+ "Overlapping Policies Test6",
+ "-policy $nist2",
+ "True", $nist1, "<empty>", 43
+ ],
+ [
+ "4.8.7",
+ "Different Policies Test7",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.8.8",
+ "Different Policies Test8",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.8.9",
+ "Different Policies Test9",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.8.10.1",
+ "All Certificates Same Policies Test10",
+ "-policy $nist1",
+ "True", "$nist1:$nist2", "$nist1", 0
+ ],
+ [
+ "4.8.10.2",
+ "All Certificates Same Policies Test10",
+ "-policy $nist2",
+ "True", "$nist1:$nist2", "$nist2", 0
+ ],
+ [
+ "4.8.10.3",
+ "All Certificates Same Policies Test10",
+ "-policy anyPolicy",
+ "True", "$nist1:$nist2", "$nist1:$nist2", 0
+ ],
+ [
+ "4.8.11.1",
+ "All Certificates AnyPolicy Test11",
+ "-policy anyPolicy",
+ "True", "$apolicy", "$apolicy", 0
+ ],
+ [
+ "4.8.11.2",
+ "All Certificates AnyPolicy Test11",
+ "-policy $nist1",
+ "True", "$apolicy", "$nist1", 0
+ ],
+ [
+ "4.8.12",
+ "Different Policies Test12",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.8.13.1",
+ "All Certificates Same Policies Test13",
+ "-policy $nist1",
+ "True", "$nist1:$nist2:$nist3", "$nist1", 0
+ ],
+ [
+ "4.8.13.2",
+ "All Certificates Same Policies Test13",
+ "-policy $nist2",
+ "True", "$nist1:$nist2:$nist3", "$nist2", 0
+ ],
+ [
+ "4.8.13.3",
+ "All Certificates Same Policies Test13",
+ "-policy $nist3",
+ "True", "$nist1:$nist2:$nist3", "$nist3", 0
+ ],
+ [
+ "4.8.14.1", "AnyPolicy Test14",
+ "-policy $nist1", "True",
+ "$nist1", "$nist1",
+ 0
+ ],
+ [
+ "4.8.14.2", "AnyPolicy Test14",
+ "-policy $nist2", "True",
+ "$nist1", "<empty>",
+ 43
+ ],
+ [
+ "4.8.15",
+ "User Notice Qualifier Test15",
+ "-policy anyPolicy",
+ "False", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.8.16",
+ "User Notice Qualifier Test16",
+ "-policy anyPolicy",
+ "False", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.8.17",
+ "User Notice Qualifier Test17",
+ "-policy anyPolicy",
+ "False", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.8.18.1",
+ "User Notice Qualifier Test18",
+ "-policy $nist1",
+ "True", "$nist1:$nist2", "$nist1", 0
+ ],
+ [
+ "4.8.18.2",
+ "User Notice Qualifier Test18",
+ "-policy $nist2",
+ "True", "$nist1:$nist2", "$nist2", 0
+ ],
+ [
+ "4.8.19",
+ "User Notice Qualifier Test19",
+ "-policy anyPolicy",
+ "False", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.8.20",
+ "CPS Pointer Qualifier Test20",
+ "-policy anyPolicy -explicit_policy",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [ "4.9", "Require Explicit Policy" ],
+ [
+ "4.9.1",
+ "Valid RequireExplicitPolicy Test1",
+ "-policy anyPolicy",
+ "False", "<empty>", "<empty>", 0
+ ],
+ [
+ "4.9.2",
+ "Valid RequireExplicitPolicy Test2",
+ "-policy anyPolicy",
+ "False", "<empty>", "<empty>", 0
+ ],
+ [
+ "4.9.3",
+ "Invalid RequireExplicitPolicy Test3",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.9.4",
+ "Valid RequireExplicitPolicy Test4",
+ "-policy anyPolicy",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.9.5",
+ "Invalid RequireExplicitPolicy Test5",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.9.6",
+ "Valid Self-Issued requireExplicitPolicy Test6",
+ "-policy anyPolicy",
+ "False", "<empty>", "<empty>", 0
+ ],
+ [
+ "4.9.7",
+ "Invalid Self-Issued requireExplicitPolicy Test7",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.9.8",
+ "Invalid Self-Issued requireExplicitPolicy Test8",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [ "4.10", "Policy Mappings" ],
+ [
+ "4.10.1.1",
+ "Valid Policy Mapping Test1",
+ "-policy $nist1",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.10.1.2",
+ "Valid Policy Mapping Test1",
+ "-policy $nist2",
+ "True", "$nist1", "<empty>", 43
+ ],
+ [
+ "4.10.1.3",
+ "Valid Policy Mapping Test1",
+ "-policy anyPolicy -inhibit_map",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.10.2.1",
+ "Invalid Policy Mapping Test2",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.10.2.2",
+ "Invalid Policy Mapping Test2",
+ "-policy anyPolicy -inhibit_map",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.10.3.1",
+ "Valid Policy Mapping Test3",
+ "-policy $nist1",
+ "True", "$nist2", "<empty>", 43
+ ],
+ [
+ "4.10.3.2",
+ "Valid Policy Mapping Test3",
+ "-policy $nist2",
+ "True", "$nist2", "$nist2", 0
+ ],
+ [
+ "4.10.4",
+ "Invalid Policy Mapping Test4",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.10.5.1",
+ "Valid Policy Mapping Test5",
+ "-policy $nist1",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.10.5.2",
+ "Valid Policy Mapping Test5",
+ "-policy $nist6",
+ "True", "$nist1", "<empty>", 43
+ ],
+ [
+ "4.10.6.1",
+ "Valid Policy Mapping Test6",
+ "-policy $nist1",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.10.6.2",
+ "Valid Policy Mapping Test6",
+ "-policy $nist6",
+ "True", "$nist1", "<empty>", 43
+ ],
+ [ "4.10.7", "Invalid Mapping From anyPolicy Test7", 42 ],
+ [ "4.10.8", "Invalid Mapping To anyPolicy Test8", 42 ],
+ [
+ "4.10.9",
+ "Valid Policy Mapping Test9",
+ "-policy anyPolicy",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.10.10",
+ "Invalid Policy Mapping Test10",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.10.11",
+ "Valid Policy Mapping Test11",
+ "-policy anyPolicy",
+ "True", "$nist1", "$nist1", 0
+ ],
+
+ # TODO: check notice display
+ [
+ "4.10.12.1",
+ "Valid Policy Mapping Test12",
+ "-policy $nist1",
+ "True", "$nist1:$nist2", "$nist1", 0
+ ],
+
+ # TODO: check notice display
+ [
+ "4.10.12.2",
+ "Valid Policy Mapping Test12",
+ "-policy $nist2",
+ "True", "$nist1:$nist2", "$nist2", 0
+ ],
+ [
+ "4.10.13",
+ "Valid Policy Mapping Test13",
+ "-policy anyPolicy",
+ "True", "$nist1", "$nist1", 0
+ ],
+
+ # TODO: check notice display
+ [
+ "4.10.14",
+ "Valid Policy Mapping Test14",
+ "-policy anyPolicy",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [ "4.11", "Inhibit Policy Mapping" ],
+ [
+ "4.11.1",
+ "Invalid inhibitPolicyMapping Test1",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.11.2",
+ "Valid inhibitPolicyMapping Test2",
+ "-policy anyPolicy",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.11.3",
+ "Invalid inhibitPolicyMapping Test3",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.11.4",
+ "Valid inhibitPolicyMapping Test4",
+ "-policy anyPolicy",
+ "True", "$nist2", "$nist2", 0
+ ],
+ [
+ "4.11.5",
+ "Invalid inhibitPolicyMapping Test5",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.11.6",
+ "Invalid inhibitPolicyMapping Test6",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.11.7",
+ "Valid Self-Issued inhibitPolicyMapping Test7",
+ "-policy anyPolicy",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.11.8",
+ "Invalid Self-Issued inhibitPolicyMapping Test8",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.11.9",
+ "Invalid Self-Issued inhibitPolicyMapping Test9",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.11.10",
+ "Invalid Self-Issued inhibitPolicyMapping Test10",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.11.11",
+ "Invalid Self-Issued inhibitPolicyMapping Test11",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [ "4.12", "Inhibit Any Policy" ],
+ [
+ "4.12.1",
+ "Invalid inhibitAnyPolicy Test1",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.12.2",
+ "Valid inhibitAnyPolicy Test2",
+ "-policy anyPolicy",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.12.3.1",
+ "inhibitAnyPolicy Test3",
+ "-policy anyPolicy",
+ "True", "$nist1", "$nist1", 0
+ ],
+ [
+ "4.12.3.2",
+ "inhibitAnyPolicy Test3",
+ "-policy anyPolicy -inhibit_any",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.12.4",
+ "Invalid inhibitAnyPolicy Test4",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.12.5",
+ "Invalid inhibitAnyPolicy Test5",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [
+ "4.12.6",
+ "Invalid inhibitAnyPolicy Test6",
+ "-policy anyPolicy",
+ "True", "<empty>", "<empty>", 43
+ ],
+ [ "4.12.7", "Valid Self-Issued inhibitAnyPolicy Test7", 0 ],
+ [ "4.12.8", "Invalid Self-Issued inhibitAnyPolicy Test8", 43 ],
+ [ "4.12.9", "Valid Self-Issued inhibitAnyPolicy Test9", 0 ],
+ [ "4.12.10", "Invalid Self-Issued inhibitAnyPolicy Test10", 43 ],
+ [ "4.13", "Name Constraints" ],
+ [ "4.13.1", "Valid DN nameConstraints Test1", 0 ],
+ [ "4.13.2", "Invalid DN nameConstraints Test2", 47 ],
+ [ "4.13.3", "Invalid DN nameConstraints Test3", 47 ],
+ [ "4.13.4", "Valid DN nameConstraints Test4", 0 ],
+ [ "4.13.5", "Valid DN nameConstraints Test5", 0 ],
+ [ "4.13.6", "Valid DN nameConstraints Test6", 0 ],
+ [ "4.13.7", "Invalid DN nameConstraints Test7", 48 ],
+ [ "4.13.8", "Invalid DN nameConstraints Test8", 48 ],
+ [ "4.13.9", "Invalid DN nameConstraints Test9", 48 ],
+ [ "4.13.10", "Invalid DN nameConstraints Test10", 48 ],
+ [ "4.13.11", "Valid DN nameConstraints Test11", 0 ],
+ [ "4.13.12", "Invalid DN nameConstraints Test12", 47 ],
+ [ "4.13.13", "Invalid DN nameConstraints Test13", 47 ],
+ [ "4.13.14", "Valid DN nameConstraints Test14", 0 ],
+ [ "4.13.15", "Invalid DN nameConstraints Test15", 48 ],
+ [ "4.13.16", "Invalid DN nameConstraints Test16", 48 ],
+ [ "4.13.17", "Invalid DN nameConstraints Test17", 48 ],
+ [ "4.13.18", "Valid DN nameConstraints Test18", 0 ],
+ [ "4.13.19", "Valid Self-Issued DN nameConstraints Test19", 0 ],
+ [ "4.13.20", "Invalid Self-Issued DN nameConstraints Test20", 47 ],
+ [ "4.13.21", "Valid RFC822 nameConstraints Test21", 0 ],
+ [ "4.13.22", "Invalid RFC822 nameConstraints Test22", 47 ],
+ [ "4.13.23", "Valid RFC822 nameConstraints Test23", 0 ],
+ [ "4.13.24", "Invalid RFC822 nameConstraints Test24", 47 ],
+ [ "4.13.25", "Valid RFC822 nameConstraints Test25", 0 ],
+ [ "4.13.26", "Invalid RFC822 nameConstraints Test26", 48 ],
+ [ "4.13.27", "Valid DN and RFC822 nameConstraints Test27", 0 ],
+ [ "4.13.28", "Invalid DN and RFC822 nameConstraints Test28", 47 ],
+ [ "4.13.29", "Invalid DN and RFC822 nameConstraints Test29", 47 ],
+ [ "4.13.30", "Valid DNS nameConstraints Test30", 0 ],
+ [ "4.13.31", "Invalid DNS nameConstraints Test31", 47 ],
+ [ "4.13.32", "Valid DNS nameConstraints Test32", 0 ],
+ [ "4.13.33", "Invalid DNS nameConstraints Test33", 48 ],
+ [ "4.13.34", "Valid URI nameConstraints Test34", 0 ],
+ [ "4.13.35", "Invalid URI nameConstraints Test35", 47 ],
+ [ "4.13.36", "Valid URI nameConstraints Test36", 0 ],
+ [ "4.13.37", "Invalid URI nameConstraints Test37", 48 ],
+ [ "4.13.38", "Invalid DNS nameConstraints Test38", 47 ],
+ [ "4.14", "Distribution Points" ],
+ [ "4.14.1", "Valid distributionPoint Test1", 0 ],
+ [ "4.14.2", "Invalid distributionPoint Test2", 23 ],
+ [ "4.14.3", "Invalid distributionPoint Test3", 44 ],
+ [ "4.14.4", "Valid distributionPoint Test4", 0 ],
+ [ "4.14.5", "Valid distributionPoint Test5", 0 ],
+ [ "4.14.6", "Invalid distributionPoint Test6", 23 ],
+ [ "4.14.7", "Valid distributionPoint Test7", 0 ],
+ [ "4.14.8", "Invalid distributionPoint Test8", 44 ],
+ [ "4.14.9", "Invalid distributionPoint Test9", 44 ],
+ [ "4.14.10", "Valid No issuingDistributionPoint Test10", 0 ],
+ [ "4.14.11", "Invalid onlyContainsUserCerts CRL Test11", 44 ],
+ [ "4.14.12", "Invalid onlyContainsCACerts CRL Test12", 44 ],
+ [ "4.14.13", "Valid onlyContainsCACerts CRL Test13", 0 ],
+ [ "4.14.14", "Invalid onlyContainsAttributeCerts Test14", 44 ],
+ [ "4.14.15", "Invalid onlySomeReasons Test15", 23 ],
+ [ "4.14.16", "Invalid onlySomeReasons Test16", 23 ],
+ [ "4.14.17", "Invalid onlySomeReasons Test17", 3 ],
+ [ "4.14.18", "Valid onlySomeReasons Test18", 0 ],
+ [ "4.14.19", "Valid onlySomeReasons Test19", 0 ],
+ [ "4.14.20", "Invalid onlySomeReasons Test20", 23 ],
+ [ "4.14.21", "Invalid onlySomeReasons Test21", 23 ],
+ [ "4.14.22", "Valid IDP with indirectCRL Test22", 0 ],
+ [ "4.14.23", "Invalid IDP with indirectCRL Test23", 23 ],
+ [ "4.14.24", "Valid IDP with indirectCRL Test24", 0 ],
+ [ "4.14.25", "Valid IDP with indirectCRL Test25", 0 ],
+ [ "4.14.26", "Invalid IDP with indirectCRL Test26", 44 ],
+ [ "4.14.27", "Invalid cRLIssuer Test27", 3 ],
+ [ "4.14.28", "Valid cRLIssuer Test28", 0 ],
+ [ "4.14.29", "Valid cRLIssuer Test29", 0 ],
+
+ # Although this test is valid it has a circular dependency. As a result
+ # an attempt is made to reursively checks a CRL path and rejected due to
+ # a CRL path validation error. PKITS notes suggest this test does not
+ # need to be run due to this issue.
+ [ "4.14.30", "Valid cRLIssuer Test30", 54 ],
+ [ "4.14.31", "Invalid cRLIssuer Test31", 23 ],
+ [ "4.14.32", "Invalid cRLIssuer Test32", 23 ],
+ [ "4.14.33", "Valid cRLIssuer Test33", 0 ],
+ [ "4.14.34", "Invalid cRLIssuer Test34", 23 ],
+ [ "4.14.35", "Invalid cRLIssuer Test35", 44 ],
+ [ "4.15", "Delta-CRLs" ],
+ [ "4.15.1", "Invalid deltaCRLIndicator No Base Test1", 3 ],
+ [ "4.15.2", "Valid delta-CRL Test2", 0 ],
+ [ "4.15.3", "Invalid delta-CRL Test3", 23 ],
+ [ "4.15.4", "Invalid delta-CRL Test4", 23 ],
+ [ "4.15.5", "Valid delta-CRL Test5", 0 ],
+ [ "4.15.6", "Invalid delta-CRL Test6", 23 ],
+ [ "4.15.7", "Valid delta-CRL Test7", 0 ],
+ [ "4.15.8", "Valid delta-CRL Test8", 0 ],
+ [ "4.15.9", "Invalid delta-CRL Test9", 23 ],
+ [ "4.15.10", "Invalid delta-CRL Test10", 12 ],
+ [ "4.16", "Private Certificate Extensions" ],
+ [ "4.16.1", "Valid Unknown Not Critical Certificate Extension Test1", 0 ],
+ [ "4.16.2", "Invalid Unknown Critical Certificate Extension Test2", 34 ],
+);
+
+
+my $verbose = 1;
+
+my $numtest = 0;
+my $numfail = 0;
+
+my $ossl = "ossl/apps/openssl";
+
+my $ossl_cmd = "$ossl_path cms -verify -verify_retcode ";
+$ossl_cmd .= "-CAfile pkitsta.pem -crl_check_all -x509_strict ";
+
+# Check for expiry of trust anchor
+system "$ossl_path x509 -inform DER -in $pkitsta -checkend 0";
+if ($? == 256)
+ {
+ print STDERR "WARNING: using older expired data\n";
+ $ossl_cmd .= "-attime 1291940972 ";
+ }
+
+$ossl_cmd .= "-policy_check -extended_crl -use_deltas -out /dev/null 2>&1 ";
+
+system "$ossl_path x509 -inform DER -in $pkitsta -out pkitsta.pem";
+
+die "Can't create trust anchor file" if $?;
+
+print "Running PKITS tests:\n" if $verbose;
+
+foreach (@testlists) {
+ my $argnum = @$_;
+ if ( $argnum == 2 ) {
+ my ( $tnum, $title ) = @$_;
+ print "$tnum $title\n" if $verbose;
+ }
+ elsif ( $argnum == 3 ) {
+ my ( $tnum, $title, $exp_ret ) = @$_;
+ my $filename = $title;
+ $exp_ret += 32 if $exp_ret;
+ $filename =~ tr/ -//d;
+ $filename = "Signed${filename}.eml";
+ if ( !-f "$pkitsdir/$filename" ) {
+ print "\"$filename\" not found\n";
+ }
+ else {
+ my $ret;
+ my $test_fail = 0;
+ my $errmsg = "";
+ my $cmd = $ossl_cmd;
+ $cmd .= "-in $pkitsdir/$filename -policy anyPolicy";
+ my $cmdout = `$cmd`;
+ $ret = $? >> 8;
+ if ( $? & 0xff ) {
+ $errmsg .= "Abnormal OpenSSL termination\n";
+ $test_fail = 1;
+ }
+ if ( $exp_ret != $ret ) {
+ $errmsg .= "Return code:$ret, ";
+ $errmsg .= "expected $exp_ret\n";
+ $test_fail = 1;
+ }
+ if ($test_fail) {
+ print "$tnum $title : Failed!\n";
+ print "Filename: $pkitsdir/$filename\n";
+ print $errmsg;
+ print "Command output:\n$cmdout\n";
+ $numfail++;
+ }
+ $numtest++;
+ }
+ }
+ elsif ( $argnum == 7 ) {
+ my ( $tnum, $title, $exargs, $exp_epol, $exp_aset, $exp_uset, $exp_ret )
+ = @$_;
+ my $filename = $title;
+ $exp_ret += 32 if $exp_ret;
+ $filename =~ tr/ -//d;
+ $filename = "Signed${filename}.eml";
+ if ( !-f "$pkitsdir/$filename" ) {
+ print "\"$filename\" not found\n";
+ }
+ else {
+ my $ret;
+ my $cmdout = "";
+ my $errmsg = "";
+ my $epol = "";
+ my $aset = "";
+ my $uset = "";
+ my $pol = -1;
+ my $test_fail = 0;
+ my $cmd = $ossl_cmd;
+ $cmd .= "-in $pkitsdir/$filename $exargs -policy_print";
+ @oparr = `$cmd`;
+ $ret = $? >> 8;
+
+ if ( $? & 0xff ) {
+ $errmsg .= "Abnormal OpenSSL termination\n";
+ $test_fail = 1;
+ }
+ foreach (@oparr) {
+ my $test_failed = 0;
+ $cmdout .= $_;
+ if (/^Require explicit Policy: (.*)$/) {
+ $epol = $1;
+ }
+ if (/^Authority Policies/) {
+ if (/empty/) {
+ $aset = "<empty>";
+ }
+ else {
+ $pol = 1;
+ }
+ }
+ $test_fail = 1 if (/leak/i);
+ if (/^User Policies/) {
+ if (/empty/) {
+ $uset = "<empty>";
+ }
+ else {
+ $pol = 2;
+ }
+ }
+ if (/\s+Policy: (.*)$/) {
+ if ( $pol == 1 ) {
+ $aset .= ":" if $aset ne "";
+ $aset .= $1;
+ }
+ elsif ( $pol == 2 ) {
+ $uset .= ":" if $uset ne "";
+ $uset .= $1;
+ }
+ }
+ }
+
+ if ( $epol ne $exp_epol ) {
+ $errmsg .= "Explicit policy:$epol, ";
+ $errmsg .= "expected $exp_epol\n";
+ $test_fail = 1;
+ }
+ if ( $aset ne $exp_aset ) {
+ $errmsg .= "Authority policy set :$aset, ";
+ $errmsg .= "expected $exp_aset\n";
+ $test_fail = 1;
+ }
+ if ( $uset ne $exp_uset ) {
+ $errmsg .= "User policy set :$uset, ";
+ $errmsg .= "expected $exp_uset\n";
+ $test_fail = 1;
+ }
+
+ if ( $exp_ret != $ret ) {
+ print "Return code:$ret, expected $exp_ret\n";
+ $test_fail = 1;
+ }
+
+ if ($test_fail) {
+ print "$tnum $title : Failed!\n";
+ print "Filename: $pkitsdir/$filename\n";
+ print "Command output:\n$cmdout\n";
+ $numfail++;
+ }
+ $numtest++;
+ }
+ }
+}
+
+if ($numfail) {
+ print "$numfail tests failed out of $numtest\n";
+}
+else {
+ print "All Tests Successful.\n";
+}
+
+unlink "pkitsta.pem";
+
diff --git a/deps/openssl/openssl/test/r160test.c b/deps/openssl/openssl/test/r160test.c
new file mode 100644
index 000000000..a172e393c
--- /dev/null
+++ b/deps/openssl/openssl/test/r160test.c
@@ -0,0 +1,57 @@
+/* test/r160test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
diff --git a/deps/openssl/openssl/test/randtest.c b/deps/openssl/openssl/test/randtest.c
new file mode 100644
index 000000000..9e92a70b0
--- /dev/null
+++ b/deps/openssl/openssl/test/randtest.c
@@ -0,0 +1,219 @@
+/* crypto/rand/randtest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/rand.h>
+
+#include "../e_os.h"
+
+/* some FIPS 140-1 random number test */
+/* some simple tests */
+
+int main(int argc,char **argv)
+ {
+ unsigned char buf[2500];
+ int i,j,k,s,sign,nsign,err=0;
+ unsigned long n1;
+ unsigned long n2[16];
+ unsigned long runs[2][34];
+ /*double d; */
+ long d;
+
+ i = RAND_pseudo_bytes(buf,2500);
+ if (i < 0)
+ {
+ printf ("init failed, the rand method is not properly installed\n");
+ err++;
+ goto err;
+ }
+
+ n1=0;
+ for (i=0; i<16; i++) n2[i]=0;
+ for (i=0; i<34; i++) runs[0][i]=runs[1][i]=0;
+
+ /* test 1 and 2 */
+ sign=0;
+ nsign=0;
+ for (i=0; i<2500; i++)
+ {
+ j=buf[i];
+
+ n2[j&0x0f]++;
+ n2[(j>>4)&0x0f]++;
+
+ for (k=0; k<8; k++)
+ {
+ s=(j&0x01);
+ if (s == sign)
+ nsign++;
+ else
+ {
+ if (nsign > 34) nsign=34;
+ if (nsign != 0)
+ {
+ runs[sign][nsign-1]++;
+ if (nsign > 6)
+ runs[sign][5]++;
+ }
+ sign=s;
+ nsign=1;
+ }
+
+ if (s) n1++;
+ j>>=1;
+ }
+ }
+ if (nsign > 34) nsign=34;
+ if (nsign != 0) runs[sign][nsign-1]++;
+
+ /* test 1 */
+ if (!((9654 < n1) && (n1 < 10346)))
+ {
+ printf("test 1 failed, X=%lu\n",n1);
+ err++;
+ }
+ printf("test 1 done\n");
+
+ /* test 2 */
+#ifdef undef
+ d=0;
+ for (i=0; i<16; i++)
+ d+=n2[i]*n2[i];
+ d=d*16.0/5000.0-5000.0;
+ if (!((1.03 < d) && (d < 57.4)))
+ {
+ printf("test 2 failed, X=%.2f\n",d);
+ err++;
+ }
+#endif
+ d=0;
+ for (i=0; i<16; i++)
+ d+=n2[i]*n2[i];
+ d=(d*8)/25-500000;
+ if (!((103 < d) && (d < 5740)))
+ {
+ printf("test 2 failed, X=%ld.%02ld\n",d/100L,d%100L);
+ err++;
+ }
+ printf("test 2 done\n");
+
+ /* test 3 */
+ for (i=0; i<2; i++)
+ {
+ if (!((2267 < runs[i][0]) && (runs[i][0] < 2733)))
+ {
+ printf("test 3 failed, bit=%d run=%d num=%lu\n",
+ i,1,runs[i][0]);
+ err++;
+ }
+ if (!((1079 < runs[i][1]) && (runs[i][1] < 1421)))
+ {
+ printf("test 3 failed, bit=%d run=%d num=%lu\n",
+ i,2,runs[i][1]);
+ err++;
+ }
+ if (!(( 502 < runs[i][2]) && (runs[i][2] < 748)))
+ {
+ printf("test 3 failed, bit=%d run=%d num=%lu\n",
+ i,3,runs[i][2]);
+ err++;
+ }
+ if (!(( 223 < runs[i][3]) && (runs[i][3] < 402)))
+ {
+ printf("test 3 failed, bit=%d run=%d num=%lu\n",
+ i,4,runs[i][3]);
+ err++;
+ }
+ if (!(( 90 < runs[i][4]) && (runs[i][4] < 223)))
+ {
+ printf("test 3 failed, bit=%d run=%d num=%lu\n",
+ i,5,runs[i][4]);
+ err++;
+ }
+ if (!(( 90 < runs[i][5]) && (runs[i][5] < 223)))
+ {
+ printf("test 3 failed, bit=%d run=%d num=%lu\n",
+ i,6,runs[i][5]);
+ err++;
+ }
+ }
+ printf("test 3 done\n");
+
+ /* test 4 */
+ if (runs[0][33] != 0)
+ {
+ printf("test 4 failed, bit=%d run=%d num=%lu\n",
+ 0,34,runs[0][33]);
+ err++;
+ }
+ if (runs[1][33] != 0)
+ {
+ printf("test 4 failed, bit=%d run=%d num=%lu\n",
+ 1,34,runs[1][33]);
+ err++;
+ }
+ printf("test 4 done\n");
+ err:
+ err=((err)?1:0);
+#ifdef OPENSSL_SYS_NETWARE
+ if (err) printf("ERROR: %d\n", err);
+#endif
+ EXIT(err);
+ return(err);
+ }
diff --git a/deps/openssl/openssl/test/rc2test.c b/deps/openssl/openssl/test/rc2test.c
new file mode 100644
index 000000000..0e117436b
--- /dev/null
+++ b/deps/openssl/openssl/test/rc2test.c
@@ -0,0 +1,274 @@
+/* crypto/rc2/rc2test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* This has been a quickly hacked 'ideatest.c'. When I add tests for other
+ * RC2 modes, more of the code will be uncommented. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_RC2
+int main(int argc, char *argv[])
+{
+ printf("No RC2 support\n");
+ return(0);
+}
+#else
+#include <openssl/rc2.h>
+
+static unsigned char RC2key[4][16]={
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F},
+ };
+
+static unsigned char RC2plain[4][8]={
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ };
+
+static unsigned char RC2cipher[4][8]={
+ {0x1C,0x19,0x8A,0x83,0x8D,0xF0,0x28,0xB7},
+ {0x21,0x82,0x9C,0x78,0xA9,0xF9,0xC0,0x74},
+ {0x13,0xDB,0x35,0x17,0xD3,0x21,0x86,0x9E},
+ {0x50,0xDC,0x01,0x62,0xBD,0x75,0x7F,0x31},
+ };
+/************/
+#ifdef undef
+unsigned char k[16]={
+ 0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,
+ 0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08};
+
+unsigned char in[8]={0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03};
+unsigned char c[8]={0x11,0xFB,0xED,0x2B,0x01,0x98,0x6D,0xE5};
+unsigned char out[80];
+
+char *text="Hello to all people out there";
+
+static unsigned char cfb_key[16]={
+ 0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
+ 0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
+ };
+static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+#define CFB_TEST_SIZE 24
+static unsigned char plain[CFB_TEST_SIZE]=
+ {
+ 0x4e,0x6f,0x77,0x20,0x69,0x73,
+ 0x20,0x74,0x68,0x65,0x20,0x74,
+ 0x69,0x6d,0x65,0x20,0x66,0x6f,
+ 0x72,0x20,0x61,0x6c,0x6c,0x20
+ };
+static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
+ 0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
+ 0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
+ 0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
+
+/* 0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
+ 0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
+ 0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
+ };
+
+
+/*static int cfb64_test(unsigned char *cfb_cipher);*/
+static char *pt(unsigned char *p);
+#endif
+
+int main(int argc, char *argv[])
+ {
+ int i,n,err=0;
+ RC2_KEY key;
+ unsigned char buf[8],buf2[8];
+
+ for (n=0; n<4; n++)
+ {
+ RC2_set_key(&key,16,&(RC2key[n][0]),0 /* or 1024 */);
+
+ RC2_ecb_encrypt(&(RC2plain[n][0]),buf,&key,RC2_ENCRYPT);
+ if (memcmp(&(RC2cipher[n][0]),buf,8) != 0)
+ {
+ printf("ecb rc2 error encrypting\n");
+ printf("got :");
+ for (i=0; i<8; i++)
+ printf("%02X ",buf[i]);
+ printf("\n");
+ printf("expected:");
+ for (i=0; i<8; i++)
+ printf("%02X ",RC2cipher[n][i]);
+ err=20;
+ printf("\n");
+ }
+
+ RC2_ecb_encrypt(buf,buf2,&key,RC2_DECRYPT);
+ if (memcmp(&(RC2plain[n][0]),buf2,8) != 0)
+ {
+ printf("ecb RC2 error decrypting\n");
+ printf("got :");
+ for (i=0; i<8; i++)
+ printf("%02X ",buf[i]);
+ printf("\n");
+ printf("expected:");
+ for (i=0; i<8; i++)
+ printf("%02X ",RC2plain[n][i]);
+ printf("\n");
+ err=3;
+ }
+ }
+
+ if (err == 0) printf("ecb RC2 ok\n");
+#ifdef undef
+ memcpy(iv,k,8);
+ idea_cbc_encrypt((unsigned char *)text,out,strlen(text)+1,&key,iv,1);
+ memcpy(iv,k,8);
+ idea_cbc_encrypt(out,out,8,&dkey,iv,0);
+ idea_cbc_encrypt(&(out[8]),&(out[8]),strlen(text)+1-8,&dkey,iv,0);
+ if (memcmp(text,out,strlen(text)+1) != 0)
+ {
+ printf("cbc idea bad\n");
+ err=4;
+ }
+ else
+ printf("cbc idea ok\n");
+
+ printf("cfb64 idea ");
+ if (cfb64_test(cfb_cipher64))
+ {
+ printf("bad\n");
+ err=5;
+ }
+ else
+ printf("ok\n");
+#endif
+
+#ifdef OPENSSL_SYS_NETWARE
+ if (err) printf("ERROR: %d\n", err);
+#endif
+ EXIT(err);
+ return(err);
+ }
+
+#ifdef undef
+static int cfb64_test(unsigned char *cfb_cipher)
+ {
+ IDEA_KEY_SCHEDULE eks,dks;
+ int err=0,i,n;
+
+ idea_set_encrypt_key(cfb_key,&eks);
+ idea_set_decrypt_key(&eks,&dks);
+ memcpy(cfb_tmp,cfb_iv,8);
+ n=0;
+ idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks,
+ cfb_tmp,&n,IDEA_ENCRYPT);
+ idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+ (long)CFB_TEST_SIZE-12,&eks,
+ cfb_tmp,&n,IDEA_ENCRYPT);
+ if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0)
+ {
+ err=1;
+ printf("idea_cfb64_encrypt encrypt error\n");
+ for (i=0; i<CFB_TEST_SIZE; i+=8)
+ printf("%s\n",pt(&(cfb_buf1[i])));
+ }
+ memcpy(cfb_tmp,cfb_iv,8);
+ n=0;
+ idea_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&eks,
+ cfb_tmp,&n,IDEA_DECRYPT);
+ idea_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+ (long)CFB_TEST_SIZE-17,&dks,
+ cfb_tmp,&n,IDEA_DECRYPT);
+ if (memcmp(plain,cfb_buf2,CFB_TEST_SIZE) != 0)
+ {
+ err=1;
+ printf("idea_cfb_encrypt decrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf2[i])));
+ }
+ return(err);
+ }
+
+static char *pt(unsigned char *p)
+ {
+ static char bufs[10][20];
+ static int bnum=0;
+ char *ret;
+ int i;
+ static char *f="0123456789ABCDEF";
+
+ ret= &(bufs[bnum++][0]);
+ bnum%=10;
+ for (i=0; i<8; i++)
+ {
+ ret[i*2]=f[(p[i]>>4)&0xf];
+ ret[i*2+1]=f[p[i]&0xf];
+ }
+ ret[16]='\0';
+ return(ret);
+ }
+
+#endif
+#endif
diff --git a/deps/openssl/openssl/test/rc4test.c b/deps/openssl/openssl/test/rc4test.c
new file mode 100644
index 000000000..4312605cc
--- /dev/null
+++ b/deps/openssl/openssl/test/rc4test.c
@@ -0,0 +1,242 @@
+/* crypto/rc4/rc4test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_RC4
+int main(int argc, char *argv[])
+{
+ printf("No RC4 support\n");
+ return(0);
+}
+#else
+#include <openssl/rc4.h>
+#include <openssl/sha.h>
+
+static unsigned char keys[7][30]={
+ {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
+ {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
+ {8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {4,0xef,0x01,0x23,0x45},
+ {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
+ {4,0xef,0x01,0x23,0x45},
+ };
+
+static unsigned char data_len[7]={8,8,8,20,28,10};
+static unsigned char data[7][30]={
+ {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xff},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xff},
+ {0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
+ 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
+ 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
+ 0x12,0x34,0x56,0x78,0xff},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
+ {0},
+ };
+
+static unsigned char output[7][30]={
+ {0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96,0x00},
+ {0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79,0x00},
+ {0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a,0x00},
+ {0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,
+ 0xbd,0x61,0x5a,0x11,0x62,0xe1,0xc7,0xba,
+ 0x36,0xb6,0x78,0x58,0x00},
+ {0x66,0xa0,0x94,0x9f,0x8a,0xf7,0xd6,0x89,
+ 0x1f,0x7f,0x83,0x2b,0xa8,0x33,0xc0,0x0c,
+ 0x89,0x2e,0xbe,0x30,0x14,0x3c,0xe2,0x87,
+ 0x40,0x01,0x1e,0xcf,0x00},
+ {0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61,0x00},
+ {0},
+ };
+
+int main(int argc, char *argv[])
+ {
+ int i,err=0;
+ int j;
+ unsigned char *p;
+ RC4_KEY key;
+ unsigned char obuf[512];
+
+#if !defined(OPENSSL_PIC)
+ void OPENSSL_cpuid_setup(void);
+
+ OPENSSL_cpuid_setup();
+#endif
+
+ for (i=0; i<6; i++)
+ {
+ RC4_set_key(&key,keys[i][0],&(keys[i][1]));
+ memset(obuf,0x00,sizeof(obuf));
+ RC4(&key,data_len[i],&(data[i][0]),obuf);
+ if (memcmp(obuf,output[i],data_len[i]+1) != 0)
+ {
+ printf("error calculating RC4\n");
+ printf("output:");
+ for (j=0; j<data_len[i]+1; j++)
+ printf(" %02x",obuf[j]);
+ printf("\n");
+ printf("expect:");
+ p= &(output[i][0]);
+ for (j=0; j<data_len[i]+1; j++)
+ printf(" %02x",*(p++));
+ printf("\n");
+ err++;
+ }
+ else
+ printf("test %d ok\n",i);
+ }
+ printf("test end processing ");
+ for (i=0; i<data_len[3]; i++)
+ {
+ RC4_set_key(&key,keys[3][0],&(keys[3][1]));
+ memset(obuf,0x00,sizeof(obuf));
+ RC4(&key,i,&(data[3][0]),obuf);
+ if ((memcmp(obuf,output[3],i) != 0) || (obuf[i] != 0))
+ {
+ printf("error in RC4 length processing\n");
+ printf("output:");
+ for (j=0; j<i+1; j++)
+ printf(" %02x",obuf[j]);
+ printf("\n");
+ printf("expect:");
+ p= &(output[3][0]);
+ for (j=0; j<i; j++)
+ printf(" %02x",*(p++));
+ printf(" 00\n");
+ err++;
+ }
+ else
+ {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+ printf("done\n");
+ printf("test multi-call ");
+ for (i=0; i<data_len[3]; i++)
+ {
+ RC4_set_key(&key,keys[3][0],&(keys[3][1]));
+ memset(obuf,0x00,sizeof(obuf));
+ RC4(&key,i,&(data[3][0]),obuf);
+ RC4(&key,data_len[3]-i,&(data[3][i]),&(obuf[i]));
+ if (memcmp(obuf,output[3],data_len[3]+1) != 0)
+ {
+ printf("error in RC4 multi-call processing\n");
+ printf("output:");
+ for (j=0; j<data_len[3]+1; j++)
+ printf(" %02x",obuf[j]);
+ printf("\n");
+ printf("expect:");
+ p= &(output[3][0]);
+ for (j=0; j<data_len[3]+1; j++)
+ printf(" %02x",*(p++));
+ err++;
+ }
+ else
+ {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+ printf("done\n");
+ printf("bulk test ");
+ { unsigned char buf[513];
+ SHA_CTX c;
+ unsigned char md[SHA_DIGEST_LENGTH];
+ static unsigned char expected[]={
+ 0xa4,0x7b,0xcc,0x00,0x3d,0xd0,0xbd,0xe1,0xac,0x5f,
+ 0x12,0x1e,0x45,0xbc,0xfb,0x1a,0xa1,0xf2,0x7f,0xc5 };
+
+ RC4_set_key(&key,keys[0][0],&(keys[3][1]));
+ memset(buf,'\0',sizeof(buf));
+ SHA1_Init(&c);
+ for (i=0;i<2571;i++) {
+ RC4(&key,sizeof(buf),buf,buf);
+ SHA1_Update(&c,buf,sizeof(buf));
+ }
+ SHA1_Final(md,&c);
+
+ if (memcmp(md,expected,sizeof(md))) {
+ printf("error in RC4 bulk test\n");
+ printf("output:");
+ for (j=0; j<(int)sizeof(md); j++)
+ printf(" %02x",md[j]);
+ printf("\n");
+ printf("expect:");
+ for (j=0; j<(int)sizeof(md); j++)
+ printf(" %02x",expected[j]);
+ printf("\n");
+ err++;
+ }
+ else printf("ok\n");
+ }
+#ifdef OPENSSL_SYS_NETWARE
+ if (err) printf("ERROR: %d\n", err);
+#endif
+ EXIT(err);
+ return(0);
+ }
+#endif
diff --git a/deps/openssl/openssl/test/rc5test.c b/deps/openssl/openssl/test/rc5test.c
new file mode 100644
index 000000000..5b4467e04
--- /dev/null
+++ b/deps/openssl/openssl/test/rc5test.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <openssl/e_os2.h>
+#include <openssl/buffer.h>
+#include <openssl/crypto.h>
+
+int main(int argc, char *argv[])
+ {
+ char *p, *q = 0, *program;
+
+ p = strrchr(argv[0], '/');
+ if (!p) p = strrchr(argv[0], '\\');
+#ifdef OPENSSL_SYS_VMS
+ if (!p) p = strrchr(argv[0], ']');
+ if (p) q = strrchr(p, '>');
+ if (q) p = q;
+ if (!p) p = strrchr(argv[0], ':');
+ q = 0;
+#endif
+ if (p) p++;
+ if (!p) p = argv[0];
+ if (p) q = strchr(p, '.');
+ if (p && !q) q = p + strlen(p);
+
+ if (!p)
+ program = BUF_strdup("(unknown)");
+ else
+ {
+ program = OPENSSL_malloc((q - p) + 1);
+ strncpy(program, p, q - p);
+ program[q - p] = '\0';
+ }
+
+ for(p = program; *p; p++)
+ if (islower((unsigned char)(*p)))
+ *p = toupper((unsigned char)(*p));
+
+ q = strstr(program, "TEST");
+ if (q > p && q[-1] == '_') q--;
+ *q = '\0';
+
+ printf("No %s support\n", program);
+
+ OPENSSL_free(program);
+ return(0);
+ }
diff --git a/deps/openssl/openssl/test/rmdtest.c b/deps/openssl/openssl/test/rmdtest.c
new file mode 100644
index 000000000..fb34e0e83
--- /dev/null
+++ b/deps/openssl/openssl/test/rmdtest.c
@@ -0,0 +1,145 @@
+/* crypto/ripemd/rmdtest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_RIPEMD
+int main(int argc, char *argv[])
+{
+ printf("No ripemd support\n");
+ return(0);
+}
+#else
+#include <openssl/ripemd.h>
+#include <openssl/evp.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+static char *test[]={
+ "",
+ "a",
+ "abc",
+ "message digest",
+ "abcdefghijklmnopqrstuvwxyz",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ NULL,
+ };
+
+static char *ret[]={
+ "9c1185a5c5e9fc54612808977ee8f548b2258d31",
+ "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe",
+ "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc",
+ "5d0689ef49d2fae572b881b123a85ffa21595f36",
+ "f71c27109c692c1b56bbdceb5b9d2865b3708dbc",
+ "12a053384a9c0c88e405a06c27dcf49ada62eb2b",
+ "b0e20b6e3116640286ed3a87a5713079b21f5189",
+ "9b752e45573d4b39f4dbd3323cab82bf63326bfb",
+ };
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+ {
+ int i,err=0;
+ char **P,**R;
+ char *p;
+ unsigned char md[RIPEMD160_DIGEST_LENGTH];
+
+ P=test;
+ R=ret;
+ i=1;
+ while (*P != NULL)
+ {
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii((char *)*P, (char *)*P, strlen((char *)*P));
+#endif
+ EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_ripemd160(), NULL);
+ p=pt(md);
+ if (strcmp(p,(char *)*R) != 0)
+ {
+ printf("error calculating RIPEMD160 on '%s'\n",*P);
+ printf("got %s instead of %s\n",p,*R);
+ err++;
+ }
+ else
+ printf("test %d ok\n",i);
+ i++;
+ R++;
+ P++;
+ }
+ EXIT(err);
+ return(0);
+ }
+
+static char *pt(unsigned char *md)
+ {
+ int i;
+ static char buf[80];
+
+ for (i=0; i<RIPEMD160_DIGEST_LENGTH; i++)
+ sprintf(&(buf[i*2]),"%02x",md[i]);
+ return(buf);
+ }
+#endif
diff --git a/deps/openssl/openssl/test/rsa_test.c b/deps/openssl/openssl/test/rsa_test.c
new file mode 100644
index 000000000..c8705a0f6
--- /dev/null
+++ b/deps/openssl/openssl/test/rsa_test.c
@@ -0,0 +1,340 @@
+/* test vectors from p1ovect1.txt */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#ifdef OPENSSL_NO_RSA
+int main(int argc, char *argv[])
+{
+ printf("No RSA support\n");
+ return(0);
+}
+#else
+#include <openssl/rsa.h>
+
+#define SetKey \
+ key->n = BN_bin2bn(n, sizeof(n)-1, key->n); \
+ key->e = BN_bin2bn(e, sizeof(e)-1, key->e); \
+ key->d = BN_bin2bn(d, sizeof(d)-1, key->d); \
+ key->p = BN_bin2bn(p, sizeof(p)-1, key->p); \
+ key->q = BN_bin2bn(q, sizeof(q)-1, key->q); \
+ key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1); \
+ key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1); \
+ key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp); \
+ memcpy(c, ctext_ex, sizeof(ctext_ex) - 1); \
+ return (sizeof(ctext_ex) - 1);
+
+static int key1(RSA *key, unsigned char *c)
+ {
+ static unsigned char n[] =
+"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
+"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
+"\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
+"\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
+"\xF5";
+
+ static unsigned char e[] = "\x11";
+
+ static unsigned char d[] =
+"\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
+"\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
+"\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
+"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51";
+
+ static unsigned char p[] =
+"\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
+"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12"
+"\x0D";
+
+ static unsigned char q[] =
+"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
+"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
+"\x89";
+
+ static unsigned char dmp1[] =
+"\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF"
+"\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05";
+
+ static unsigned char dmq1[] =
+"\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99"
+"\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D"
+"\x51";
+
+ static unsigned char iqmp[] =
+"\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8"
+"\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26";
+
+ static unsigned char ctext_ex[] =
+"\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89"
+"\x2b\xfb\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52"
+"\x33\x89\x5c\x74\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44"
+"\xb0\x05\xc3\x9e\xd8\x27\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2";
+
+ SetKey;
+ }
+
+static int key2(RSA *key, unsigned char *c)
+ {
+ static unsigned char n[] =
+"\x00\xA3\x07\x9A\x90\xDF\x0D\xFD\x72\xAC\x09\x0C\xCC\x2A\x78\xB8"
+"\x74\x13\x13\x3E\x40\x75\x9C\x98\xFA\xF8\x20\x4F\x35\x8A\x0B\x26"
+"\x3C\x67\x70\xE7\x83\xA9\x3B\x69\x71\xB7\x37\x79\xD2\x71\x7B\xE8"
+"\x34\x77\xCF";
+
+ static unsigned char e[] = "\x3";
+
+ static unsigned char d[] =
+"\x6C\xAF\xBC\x60\x94\xB3\xFE\x4C\x72\xB0\xB3\x32\xC6\xFB\x25\xA2"
+"\xB7\x62\x29\x80\x4E\x68\x65\xFC\xA4\x5A\x74\xDF\x0F\x8F\xB8\x41"
+"\x3B\x52\xC0\xD0\xE5\x3D\x9B\x59\x0F\xF1\x9B\xE7\x9F\x49\xDD\x21"
+"\xE5\xEB";
+
+ static unsigned char p[] =
+"\x00\xCF\x20\x35\x02\x8B\x9D\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92"
+"\xEA\x0D\xA3\xB4\x32\x04\xB5\xCF\xCE\x91";
+
+ static unsigned char q[] =
+"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
+"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5F";
+
+ static unsigned char dmp1[] =
+"\x00\x8A\x15\x78\xAC\x5D\x13\xAF\x10\x2B\x22\xB9\x99\xCD\x74\x61"
+"\xF1\x5E\x6D\x22\xCC\x03\x23\xDF\xDF\x0B";
+
+ static unsigned char dmq1[] =
+"\x00\x86\x55\x21\x4A\xC5\x4D\x8D\x4E\xCD\x61\x77\xF1\xC7\x36\x90"
+"\xCE\x2A\x48\x2C\x8B\x05\x99\xCB\xE0\x3F";
+
+ static unsigned char iqmp[] =
+"\x00\x83\xEF\xEF\xB8\xA9\xA4\x0D\x1D\xB6\xED\x98\xAD\x84\xED\x13"
+"\x35\xDC\xC1\x08\xF3\x22\xD0\x57\xCF\x8D";
+
+ static unsigned char ctext_ex[] =
+"\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
+"\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
+"\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
+"\x62\x51";
+
+ SetKey;
+ }
+
+static int key3(RSA *key, unsigned char *c)
+ {
+ static unsigned char n[] =
+"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
+"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
+"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
+"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
+"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
+"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
+"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
+"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD"
+"\xCB";
+
+ static unsigned char e[] = "\x11";
+
+ static unsigned char d[] =
+"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
+"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
+"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
+"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
+"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
+"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
+"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
+"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
+"\xC1";
+
+ static unsigned char p[] =
+"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
+"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
+"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
+"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
+"\x99";
+
+ static unsigned char q[] =
+"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
+"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
+"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
+"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
+"\x03";
+
+ static unsigned char dmp1[] =
+"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
+"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
+"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
+"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81";
+
+ static unsigned char dmq1[] =
+"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
+"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
+"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
+"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D";
+
+ static unsigned char iqmp[] =
+"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
+"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
+"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
+"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
+"\xF7";
+
+ static unsigned char ctext_ex[] =
+"\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7"
+"\x90\xc4\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce"
+"\xf0\xc4\x36\x6f\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3"
+"\xf2\xf1\x92\xdb\xea\xca\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06"
+"\x69\xac\x22\xe9\xf3\xa7\x85\x2e\x3c\x15\xd9\x13\xca\xb0\xb8\x86"
+"\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49\x54\x61\x03\x46\xf4\xd4"
+"\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a\x1f\xc4\x02\x6a"
+"\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20\x2f\xb1";
+
+ SetKey;
+ }
+
+static int pad_unknown(void)
+{
+ unsigned long l;
+ while ((l = ERR_get_error()) != 0)
+ if (ERR_GET_REASON(l) == RSA_R_UNKNOWN_PADDING_TYPE)
+ return(1);
+ return(0);
+}
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int main(int argc, char *argv[])
+ {
+ int err=0;
+ int v;
+ RSA *key;
+ unsigned char ptext[256];
+ unsigned char ctext[256];
+ static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
+ unsigned char ctext_ex[256];
+ int plen;
+ int clen = 0;
+ int num;
+ int n;
+
+ CRYPTO_malloc_debug_init();
+ CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ RAND_seed(rnd_seed, sizeof rnd_seed); /* or OAEP may fail */
+
+ plen = sizeof(ptext_ex) - 1;
+
+ for (v = 0; v < 6; v++)
+ {
+ key = RSA_new();
+ switch (v%3) {
+ case 0:
+ clen = key1(key, ctext_ex);
+ break;
+ case 1:
+ clen = key2(key, ctext_ex);
+ break;
+ case 2:
+ clen = key3(key, ctext_ex);
+ break;
+ }
+ if (v/3 >= 1) key->flags |= RSA_FLAG_NO_CONSTTIME;
+
+ num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
+ RSA_PKCS1_PADDING);
+ if (num != clen)
+ {
+ printf("PKCS#1 v1.5 encryption failed!\n");
+ err=1;
+ goto oaep;
+ }
+
+ num = RSA_private_decrypt(num, ctext, ptext, key,
+ RSA_PKCS1_PADDING);
+ if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
+ {
+ printf("PKCS#1 v1.5 decryption failed!\n");
+ err=1;
+ }
+ else
+ printf("PKCS #1 v1.5 encryption/decryption ok\n");
+
+ oaep:
+ ERR_clear_error();
+ num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
+ RSA_PKCS1_OAEP_PADDING);
+ if (num == -1 && pad_unknown())
+ {
+ printf("No OAEP support\n");
+ goto next;
+ }
+ if (num != clen)
+ {
+ printf("OAEP encryption failed!\n");
+ err=1;
+ goto next;
+ }
+
+ num = RSA_private_decrypt(num, ctext, ptext, key,
+ RSA_PKCS1_OAEP_PADDING);
+ if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
+ {
+ printf("OAEP decryption (encrypted data) failed!\n");
+ err=1;
+ }
+ else if (memcmp(ctext, ctext_ex, num) == 0)
+ printf("OAEP test vector %d passed!\n", v);
+
+ /* Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT).
+ Try decrypting ctext_ex */
+
+ num = RSA_private_decrypt(clen, ctext_ex, ptext, key,
+ RSA_PKCS1_OAEP_PADDING);
+
+ if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
+ {
+ printf("OAEP decryption (test vector data) failed!\n");
+ err=1;
+ }
+ else
+ printf("OAEP encryption/decryption ok\n");
+
+ /* Try decrypting corrupted ciphertexts */
+ for(n = 0 ; n < clen ; ++n)
+ {
+ int b;
+ unsigned char saved = ctext[n];
+ for(b = 0 ; b < 256 ; ++b)
+ {
+ if(b == saved)
+ continue;
+ ctext[n] = b;
+ num = RSA_private_decrypt(num, ctext, ptext, key,
+ RSA_PKCS1_OAEP_PADDING);
+ if(num > 0)
+ {
+ printf("Corrupt data decrypted!\n");
+ err = 1;
+ }
+ }
+ }
+ next:
+ RSA_free(key);
+ }
+
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+
+ CRYPTO_mem_leaks_fp(stderr);
+
+#ifdef OPENSSL_SYS_NETWARE
+ if (err) printf("ERROR: %d\n", err);
+#endif
+ return err;
+ }
+#endif
diff --git a/deps/openssl/openssl/test/sha1test.c b/deps/openssl/openssl/test/sha1test.c
new file mode 100644
index 000000000..6feb3964c
--- /dev/null
+++ b/deps/openssl/openssl/test/sha1test.c
@@ -0,0 +1,178 @@
+/* crypto/sha/sha1test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_SHA
+int main(int argc, char *argv[])
+{
+ printf("No SHA support\n");
+ return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+#undef SHA_0 /* FIPS 180 */
+#define SHA_1 /* FIPS 180-1 */
+
+static char *test[]={
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ NULL,
+ };
+
+#ifdef SHA_0
+static char *ret[]={
+ "0164b8a914cd2a5e74c4f7ff082c4d97f1edf880",
+ "d2516ee1acfa5baf33dfc1c471e438449ef134c8",
+ };
+static char *bigret=
+ "3232affa48628a26653b5aaa44541fd90d690603";
+#endif
+#ifdef SHA_1
+static char *ret[]={
+ "a9993e364706816aba3e25717850c26c9cd0d89d",
+ "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
+ };
+static char *bigret=
+ "34aa973cd4c4daa4f61eeb2bdbad27316534016f";
+#endif
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+ {
+ int i,err=0;
+ char **P,**R;
+ static unsigned char buf[1000];
+ char *p,*r;
+ EVP_MD_CTX c;
+ unsigned char md[SHA_DIGEST_LENGTH];
+
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(test[0], test[0], strlen(test[0]));
+ ebcdic2ascii(test[1], test[1], strlen(test[1]));
+#endif
+
+ EVP_MD_CTX_init(&c);
+ P=test;
+ R=ret;
+ i=1;
+ while (*P != NULL)
+ {
+ EVP_Digest(*P,strlen((char *)*P),md,NULL,EVP_sha1(), NULL);
+ p=pt(md);
+ if (strcmp(p,(char *)*R) != 0)
+ {
+ printf("error calculating SHA1 on '%s'\n",*P);
+ printf("got %s instead of %s\n",p,*R);
+ err++;
+ }
+ else
+ printf("test %d ok\n",i);
+ i++;
+ R++;
+ P++;
+ }
+
+ memset(buf,'a',1000);
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(buf, buf, 1000);
+#endif /*CHARSET_EBCDIC*/
+ EVP_DigestInit_ex(&c,EVP_sha1(), NULL);
+ for (i=0; i<1000; i++)
+ EVP_DigestUpdate(&c,buf,1000);
+ EVP_DigestFinal_ex(&c,md,NULL);
+ p=pt(md);
+
+ r=bigret;
+ if (strcmp(p,r) != 0)
+ {
+ printf("error calculating SHA1 on 'a' * 1000\n");
+ printf("got %s instead of %s\n",p,r);
+ err++;
+ }
+ else
+ printf("test 3 ok\n");
+
+#ifdef OPENSSL_SYS_NETWARE
+ if (err) printf("ERROR: %d\n", err);
+#endif
+ EXIT(err);
+ EVP_MD_CTX_cleanup(&c);
+ return(0);
+ }
+
+static char *pt(unsigned char *md)
+ {
+ int i;
+ static char buf[80];
+
+ for (i=0; i<SHA_DIGEST_LENGTH; i++)
+ sprintf(&(buf[i*2]),"%02x",md[i]);
+ return(buf);
+ }
+#endif
diff --git a/deps/openssl/openssl/test/sha256t.c b/deps/openssl/openssl/test/sha256t.c
new file mode 100644
index 000000000..6b4a3bd00
--- /dev/null
+++ b/deps/openssl/openssl/test/sha256t.c
@@ -0,0 +1,147 @@
+/* crypto/sha/sha256t.c */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
+ * ====================================================================
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <openssl/sha.h>
+#include <openssl/evp.h>
+
+#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA256)
+int main(int argc, char *argv[])
+{
+ printf("No SHA256 support\n");
+ return(0);
+}
+#else
+
+unsigned char app_b1[SHA256_DIGEST_LENGTH] = {
+ 0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,
+ 0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23,
+ 0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,
+ 0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad };
+
+unsigned char app_b2[SHA256_DIGEST_LENGTH] = {
+ 0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,
+ 0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39,
+ 0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,
+ 0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1 };
+
+unsigned char app_b3[SHA256_DIGEST_LENGTH] = {
+ 0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,
+ 0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67,
+ 0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,
+ 0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0 };
+
+unsigned char addenum_1[SHA224_DIGEST_LENGTH] = {
+ 0x23,0x09,0x7d,0x22,0x34,0x05,0xd8,0x22,
+ 0x86,0x42,0xa4,0x77,0xbd,0xa2,0x55,0xb3,
+ 0x2a,0xad,0xbc,0xe4,0xbd,0xa0,0xb3,0xf7,
+ 0xe3,0x6c,0x9d,0xa7 };
+
+unsigned char addenum_2[SHA224_DIGEST_LENGTH] = {
+ 0x75,0x38,0x8b,0x16,0x51,0x27,0x76,0xcc,
+ 0x5d,0xba,0x5d,0xa1,0xfd,0x89,0x01,0x50,
+ 0xb0,0xc6,0x45,0x5c,0xb4,0xf5,0x8b,0x19,
+ 0x52,0x52,0x25,0x25 };
+
+unsigned char addenum_3[SHA224_DIGEST_LENGTH] = {
+ 0x20,0x79,0x46,0x55,0x98,0x0c,0x91,0xd8,
+ 0xbb,0xb4,0xc1,0xea,0x97,0x61,0x8a,0x4b,
+ 0xf0,0x3f,0x42,0x58,0x19,0x48,0xb2,0xee,
+ 0x4e,0xe7,0xad,0x67 };
+
+int main (int argc,char **argv)
+{ unsigned char md[SHA256_DIGEST_LENGTH];
+ int i;
+ EVP_MD_CTX evp;
+
+ fprintf(stdout,"Testing SHA-256 ");
+
+ EVP_Digest ("abc",3,md,NULL,EVP_sha256(),NULL);
+ if (memcmp(md,app_b1,sizeof(app_b1)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 1 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ EVP_Digest ("abcdbcde""cdefdefg""efghfghi""ghijhijk"
+ "ijkljklm""klmnlmno""mnopnopq",56,md,NULL,EVP_sha256(),NULL);
+ if (memcmp(md,app_b2,sizeof(app_b2)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 2 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ EVP_MD_CTX_init (&evp);
+ EVP_DigestInit_ex (&evp,EVP_sha256(),NULL);
+ for (i=0;i<1000000;i+=160)
+ EVP_DigestUpdate (&evp, "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
+ (1000000-i)<160?1000000-i:160);
+ EVP_DigestFinal_ex (&evp,md,NULL);
+ EVP_MD_CTX_cleanup (&evp);
+
+ if (memcmp(md,app_b3,sizeof(app_b3)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 3 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ fprintf(stdout," passed.\n"); fflush(stdout);
+
+ fprintf(stdout,"Testing SHA-224 ");
+
+ EVP_Digest ("abc",3,md,NULL,EVP_sha224(),NULL);
+ if (memcmp(md,addenum_1,sizeof(addenum_1)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 1 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ EVP_Digest ("abcdbcde""cdefdefg""efghfghi""ghijhijk"
+ "ijkljklm""klmnlmno""mnopnopq",56,md,NULL,EVP_sha224(),NULL);
+ if (memcmp(md,addenum_2,sizeof(addenum_2)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 2 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ EVP_MD_CTX_init (&evp);
+ EVP_DigestInit_ex (&evp,EVP_sha224(),NULL);
+ for (i=0;i<1000000;i+=64)
+ EVP_DigestUpdate (&evp, "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
+ (1000000-i)<64?1000000-i:64);
+ EVP_DigestFinal_ex (&evp,md,NULL);
+ EVP_MD_CTX_cleanup (&evp);
+
+ if (memcmp(md,addenum_3,sizeof(addenum_3)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 3 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ fprintf(stdout," passed.\n"); fflush(stdout);
+
+ return 0;
+}
+#endif
diff --git a/deps/openssl/openssl/test/sha512t.c b/deps/openssl/openssl/test/sha512t.c
new file mode 100644
index 000000000..210041d43
--- /dev/null
+++ b/deps/openssl/openssl/test/sha512t.c
@@ -0,0 +1,184 @@
+/* crypto/sha/sha512t.c */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
+ * ====================================================================
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <openssl/sha.h>
+#include <openssl/evp.h>
+#include <openssl/crypto.h>
+
+#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA512)
+int main(int argc, char *argv[])
+{
+ printf("No SHA512 support\n");
+ return(0);
+}
+#else
+
+unsigned char app_c1[SHA512_DIGEST_LENGTH] = {
+ 0xdd,0xaf,0x35,0xa1,0x93,0x61,0x7a,0xba,
+ 0xcc,0x41,0x73,0x49,0xae,0x20,0x41,0x31,
+ 0x12,0xe6,0xfa,0x4e,0x89,0xa9,0x7e,0xa2,
+ 0x0a,0x9e,0xee,0xe6,0x4b,0x55,0xd3,0x9a,
+ 0x21,0x92,0x99,0x2a,0x27,0x4f,0xc1,0xa8,
+ 0x36,0xba,0x3c,0x23,0xa3,0xfe,0xeb,0xbd,
+ 0x45,0x4d,0x44,0x23,0x64,0x3c,0xe8,0x0e,
+ 0x2a,0x9a,0xc9,0x4f,0xa5,0x4c,0xa4,0x9f };
+
+unsigned char app_c2[SHA512_DIGEST_LENGTH] = {
+ 0x8e,0x95,0x9b,0x75,0xda,0xe3,0x13,0xda,
+ 0x8c,0xf4,0xf7,0x28,0x14,0xfc,0x14,0x3f,
+ 0x8f,0x77,0x79,0xc6,0xeb,0x9f,0x7f,0xa1,
+ 0x72,0x99,0xae,0xad,0xb6,0x88,0x90,0x18,
+ 0x50,0x1d,0x28,0x9e,0x49,0x00,0xf7,0xe4,
+ 0x33,0x1b,0x99,0xde,0xc4,0xb5,0x43,0x3a,
+ 0xc7,0xd3,0x29,0xee,0xb6,0xdd,0x26,0x54,
+ 0x5e,0x96,0xe5,0x5b,0x87,0x4b,0xe9,0x09 };
+
+unsigned char app_c3[SHA512_DIGEST_LENGTH] = {
+ 0xe7,0x18,0x48,0x3d,0x0c,0xe7,0x69,0x64,
+ 0x4e,0x2e,0x42,0xc7,0xbc,0x15,0xb4,0x63,
+ 0x8e,0x1f,0x98,0xb1,0x3b,0x20,0x44,0x28,
+ 0x56,0x32,0xa8,0x03,0xaf,0xa9,0x73,0xeb,
+ 0xde,0x0f,0xf2,0x44,0x87,0x7e,0xa6,0x0a,
+ 0x4c,0xb0,0x43,0x2c,0xe5,0x77,0xc3,0x1b,
+ 0xeb,0x00,0x9c,0x5c,0x2c,0x49,0xaa,0x2e,
+ 0x4e,0xad,0xb2,0x17,0xad,0x8c,0xc0,0x9b };
+
+unsigned char app_d1[SHA384_DIGEST_LENGTH] = {
+ 0xcb,0x00,0x75,0x3f,0x45,0xa3,0x5e,0x8b,
+ 0xb5,0xa0,0x3d,0x69,0x9a,0xc6,0x50,0x07,
+ 0x27,0x2c,0x32,0xab,0x0e,0xde,0xd1,0x63,
+ 0x1a,0x8b,0x60,0x5a,0x43,0xff,0x5b,0xed,
+ 0x80,0x86,0x07,0x2b,0xa1,0xe7,0xcc,0x23,
+ 0x58,0xba,0xec,0xa1,0x34,0xc8,0x25,0xa7 };
+
+unsigned char app_d2[SHA384_DIGEST_LENGTH] = {
+ 0x09,0x33,0x0c,0x33,0xf7,0x11,0x47,0xe8,
+ 0x3d,0x19,0x2f,0xc7,0x82,0xcd,0x1b,0x47,
+ 0x53,0x11,0x1b,0x17,0x3b,0x3b,0x05,0xd2,
+ 0x2f,0xa0,0x80,0x86,0xe3,0xb0,0xf7,0x12,
+ 0xfc,0xc7,0xc7,0x1a,0x55,0x7e,0x2d,0xb9,
+ 0x66,0xc3,0xe9,0xfa,0x91,0x74,0x60,0x39 };
+
+unsigned char app_d3[SHA384_DIGEST_LENGTH] = {
+ 0x9d,0x0e,0x18,0x09,0x71,0x64,0x74,0xcb,
+ 0x08,0x6e,0x83,0x4e,0x31,0x0a,0x4a,0x1c,
+ 0xed,0x14,0x9e,0x9c,0x00,0xf2,0x48,0x52,
+ 0x79,0x72,0xce,0xc5,0x70,0x4c,0x2a,0x5b,
+ 0x07,0xb8,0xb3,0xdc,0x38,0xec,0xc4,0xeb,
+ 0xae,0x97,0xdd,0xd8,0x7f,0x3d,0x89,0x85 };
+
+int main (int argc,char **argv)
+{ unsigned char md[SHA512_DIGEST_LENGTH];
+ int i;
+ EVP_MD_CTX evp;
+
+#ifdef OPENSSL_IA32_SSE2
+ /* Alternative to this is to call OpenSSL_add_all_algorithms...
+ * The below code is retained exclusively for debugging purposes. */
+ { char *env;
+
+ if ((env=getenv("OPENSSL_ia32cap")))
+ OPENSSL_ia32cap = strtoul (env,NULL,0);
+ }
+#endif
+
+ fprintf(stdout,"Testing SHA-512 ");
+
+ EVP_Digest ("abc",3,md,NULL,EVP_sha512(),NULL);
+ if (memcmp(md,app_c1,sizeof(app_c1)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 1 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ EVP_Digest ("abcdefgh""bcdefghi""cdefghij""defghijk"
+ "efghijkl""fghijklm""ghijklmn""hijklmno"
+ "ijklmnop""jklmnopq""klmnopqr""lmnopqrs"
+ "mnopqrst""nopqrstu",112,md,NULL,EVP_sha512(),NULL);
+ if (memcmp(md,app_c2,sizeof(app_c2)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 2 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ EVP_MD_CTX_init (&evp);
+ EVP_DigestInit_ex (&evp,EVP_sha512(),NULL);
+ for (i=0;i<1000000;i+=288)
+ EVP_DigestUpdate (&evp, "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
+ (1000000-i)<288?1000000-i:288);
+ EVP_DigestFinal_ex (&evp,md,NULL);
+ EVP_MD_CTX_cleanup (&evp);
+
+ if (memcmp(md,app_c3,sizeof(app_c3)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 3 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ fprintf(stdout," passed.\n"); fflush(stdout);
+
+ fprintf(stdout,"Testing SHA-384 ");
+
+ EVP_Digest ("abc",3,md,NULL,EVP_sha384(),NULL);
+ if (memcmp(md,app_d1,sizeof(app_d1)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 1 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ EVP_Digest ("abcdefgh""bcdefghi""cdefghij""defghijk"
+ "efghijkl""fghijklm""ghijklmn""hijklmno"
+ "ijklmnop""jklmnopq""klmnopqr""lmnopqrs"
+ "mnopqrst""nopqrstu",112,md,NULL,EVP_sha384(),NULL);
+ if (memcmp(md,app_d2,sizeof(app_d2)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 2 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ EVP_MD_CTX_init (&evp);
+ EVP_DigestInit_ex (&evp,EVP_sha384(),NULL);
+ for (i=0;i<1000000;i+=64)
+ EVP_DigestUpdate (&evp, "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
+ (1000000-i)<64?1000000-i:64);
+ EVP_DigestFinal_ex (&evp,md,NULL);
+ EVP_MD_CTX_cleanup (&evp);
+
+ if (memcmp(md,app_d3,sizeof(app_d3)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 3 of 3 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ fprintf(stdout," passed.\n"); fflush(stdout);
+
+ return 0;
+}
+#endif
diff --git a/deps/openssl/openssl/test/shatest.c b/deps/openssl/openssl/test/shatest.c
new file mode 100644
index 000000000..27614646d
--- /dev/null
+++ b/deps/openssl/openssl/test/shatest.c
@@ -0,0 +1,178 @@
+/* crypto/sha/shatest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0)
+int main(int argc, char *argv[])
+{
+ printf("No SHA0 support\n");
+ return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+#define SHA_0 /* FIPS 180 */
+#undef SHA_1 /* FIPS 180-1 */
+
+static char *test[]={
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ NULL,
+ };
+
+#ifdef SHA_0
+static char *ret[]={
+ "0164b8a914cd2a5e74c4f7ff082c4d97f1edf880",
+ "d2516ee1acfa5baf33dfc1c471e438449ef134c8",
+ };
+static char *bigret=
+ "3232affa48628a26653b5aaa44541fd90d690603";
+#endif
+#ifdef SHA_1
+static char *ret[]={
+ "a9993e364706816aba3e25717850c26c9cd0d89d",
+ "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
+ };
+static char *bigret=
+ "34aa973cd4c4daa4f61eeb2bdbad27316534016f";
+#endif
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+ {
+ int i,err=0;
+ char **P,**R;
+ static unsigned char buf[1000];
+ char *p,*r;
+ EVP_MD_CTX c;
+ unsigned char md[SHA_DIGEST_LENGTH];
+
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(test[0], test[0], strlen(test[0]));
+ ebcdic2ascii(test[1], test[1], strlen(test[1]));
+#endif
+
+ EVP_MD_CTX_init(&c);
+ P=test;
+ R=ret;
+ i=1;
+ while (*P != NULL)
+ {
+ EVP_Digest(*P,strlen(*P),md,NULL,EVP_sha(), NULL);
+ p=pt(md);
+ if (strcmp(p,*R) != 0)
+ {
+ printf("error calculating SHA on '%s'\n",*P);
+ printf("got %s instead of %s\n",p,*R);
+ err++;
+ }
+ else
+ printf("test %d ok\n",i);
+ i++;
+ R++;
+ P++;
+ }
+
+ memset(buf,'a',1000);
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(buf, buf, 1000);
+#endif /*CHARSET_EBCDIC*/
+ EVP_DigestInit_ex(&c,EVP_sha(), NULL);
+ for (i=0; i<1000; i++)
+ EVP_DigestUpdate(&c,buf,1000);
+ EVP_DigestFinal_ex(&c,md,NULL);
+ p=pt(md);
+
+ r=bigret;
+ if (strcmp(p,r) != 0)
+ {
+ printf("error calculating SHA on '%s'\n",p);
+ printf("got %s instead of %s\n",p,r);
+ err++;
+ }
+ else
+ printf("test 3 ok\n");
+
+#ifdef OPENSSL_SYS_NETWARE
+ if (err) printf("ERROR: %d\n", err);
+#endif
+ EVP_MD_CTX_cleanup(&c);
+ EXIT(err);
+ return(0);
+ }
+
+static char *pt(unsigned char *md)
+ {
+ int i;
+ static char buf[80];
+
+ for (i=0; i<SHA_DIGEST_LENGTH; i++)
+ sprintf(&(buf[i*2]),"%02x",md[i]);
+ return(buf);
+ }
+#endif
diff --git a/deps/openssl/openssl/test/smcont.txt b/deps/openssl/openssl/test/smcont.txt
new file mode 100644
index 000000000..e837c0b75
--- /dev/null
+++ b/deps/openssl/openssl/test/smcont.txt
@@ -0,0 +1 @@
+Some test content for OpenSSL CMS \ No newline at end of file
diff --git a/deps/openssl/openssl/test/smime-certs/smdsa1.pem b/deps/openssl/openssl/test/smime-certs/smdsa1.pem
new file mode 100644
index 000000000..d5677dbfb
--- /dev/null
+++ b/deps/openssl/openssl/test/smime-certs/smdsa1.pem
@@ -0,0 +1,34 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
+OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
+GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
+jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
+wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
++FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
+SJCBQw5zAoGATQlPPF+OeU8nu3rsdXGDiZdJzOkuCce3KQfTABA9C+Dk4CVcvBdd
+YRLGpnykumkNTO1sTO+4/Gphsuje1ujK9td4UEhdYqylCe5QjEMrszDlJtelDQF9
+C0yhdjKGTP0kxofLhsGckcuQvcKEKffT2pDDKJIy4vWQO0UyJl1vjLcCFG2uiGGx
+9fMUZq1v0ePD4Wo0Xkxo
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsWMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBEU0EgIzEwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
+CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
+mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
+jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
+CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
+kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
+xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBN
+CU88X455Tye7eux1cYOJl0nM6S4Jx7cpB9MAED0L4OTgJVy8F11hEsamfKS6aQ1M
+7WxM77j8amGy6N7W6Mr213hQSF1irKUJ7lCMQyuzMOUm16UNAX0LTKF2MoZM/STG
+h8uGwZyRy5C9woQp99PakMMokjLi9ZA7RTImXW+Mt6OBgzCBgDAdBgNVHQ4EFgQU
+4Qfbhpi5yqXaXuCLXj427mR25MkwHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
+aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
+c21pbWVkc2ExQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBAFrdUzKK1pWO
+kd02S423KUBc4GWWyiGlVoEO7WxVhHLJ8sm67X7OtJOwe0UGt+Nc5qLtyJYSirw8
+phjiTdNpQCTJ8+Kc56tWkJ6H7NAI4vTJtPL5BM/EmeYrVSU9JI9xhqpyKw9IBD+n
+hRJ79W9FaiJRvaAOX+TkyTukJrxAWRyv
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/test/smime-certs/smdsa2.pem b/deps/openssl/openssl/test/smime-certs/smdsa2.pem
new file mode 100644
index 000000000..ef86c115d
--- /dev/null
+++ b/deps/openssl/openssl/test/smime-certs/smdsa2.pem
@@ -0,0 +1,34 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
+OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
+GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
+jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
+wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
++FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
+SJCBQw5zAoGBAIPmO8BtJ+Yac58trrPwq9b/6VW3jQTWzTLWSH84/QQdqQa+Pz3v
+It/+hHM0daNF5uls8ICsPL1aLXmRx0pHvIyb0aAzYae4T4Jv/COPDMTdKbA1uitJ
+VbkGZrm+LIrs7I9lOkb4T0vI6kL/XdOCXY1469zsqCgJ/O2ibn6mq0nWAhR716o2
+Nf8SimTZYB0/CKje6M5ufA==
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDpTCCAw6gAwIBAgIJAMtotfHYdEsXMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBEU0EgIzIwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
+CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
+mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
+jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
+CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
+kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
+xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhQACgYEA
+g+Y7wG0n5hpzny2us/Cr1v/pVbeNBNbNMtZIfzj9BB2pBr4/Pe8i3/6EczR1o0Xm
+6WzwgKw8vVoteZHHSke8jJvRoDNhp7hPgm/8I48MxN0psDW6K0lVuQZmub4siuzs
+j2U6RvhPS8jqQv9d04JdjXjr3OyoKAn87aJufqarSdajgYMwgYAwHQYDVR0OBBYE
+FHsAGNfVltSYUq4hC+YVYwsYtA+dMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcXdsab
+rWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMCAGA1UdEQQZMBeB
+FXNtaW1lZHNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQCx9BtCbaYF
+FXjLClkuKXbESaDZA1biPgY25i00FsUzARuhCpqD2v+0tu5c33ZzIhL6xlvBRU5l
+6Atw/xpZhae+hdBEtxPJoGekLLrHOau7Md3XwDjV4lFgcEJkWZoaSOOIK+4D5jF0
+jZWtHjnwEzuLYlo7ScHSsbcQfjH0M1TP5A==
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/test/smime-certs/smdsa3.pem b/deps/openssl/openssl/test/smime-certs/smdsa3.pem
new file mode 100644
index 000000000..eeb848dab
--- /dev/null
+++ b/deps/openssl/openssl/test/smime-certs/smdsa3.pem
@@ -0,0 +1,34 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
+OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
+GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
+jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
+wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
++FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
+SJCBQw5zAoGAYzOpPmh8Je1IDauEXhgaLz14wqYUHHcrj2VWVJ6fRm8GhdQFJSI7
+GUk08pgKZSKic2lNqxuzW7/vFxKQ/nvzfytY16b+2i+BR4Q6yvMzCebE1hHVg0Ju
+TwfUMwoFEOhYP6ZwHSUiQl9IBMH9TNJCMwYMxfY+VOrURFsjGTRUgpwCFQCIGt5g
+Y+XZd0Sv69CatDIRYWvaIA==
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsYMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBEU0EgIzMwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
+CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
+mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
+jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
+CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
+kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
+xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBj
+M6k+aHwl7UgNq4ReGBovPXjCphQcdyuPZVZUnp9GbwaF1AUlIjsZSTTymAplIqJz
+aU2rG7Nbv+8XEpD+e/N/K1jXpv7aL4FHhDrK8zMJ5sTWEdWDQm5PB9QzCgUQ6Fg/
+pnAdJSJCX0gEwf1M0kIzBgzF9j5U6tREWyMZNFSCnKOBgzCBgDAdBgNVHQ4EFgQU
+VhpVXqQ/EzUMdxLvP7o9EhJ8h70wHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
+aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
+c21pbWVkc2EzQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBACM9e75EQa8m
+k/AZkH/tROqf3yeqijULl9x8FjFatqoY+29OM6oMGM425IqSkKd2ipz7OxO0SShu
+rE0O3edS7DvYBwvhWPviRaYBMyZ4iFJVup+fOzoYK/j/bASxS3BHQBwb2r4rhe25
+OlTyyFEk7DJyW18YFOG97S1P52oQ5f5x
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/test/smime-certs/smdsap.pem b/deps/openssl/openssl/test/smime-certs/smdsap.pem
new file mode 100644
index 000000000..249706c8c
--- /dev/null
+++ b/deps/openssl/openssl/test/smime-certs/smdsap.pem
@@ -0,0 +1,9 @@
+-----BEGIN DSA PARAMETERS-----
+MIIBHwKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3OjSG
+Lh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqtGcoA
+gsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2Jjt+d
+qk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qtwjqv
+Wp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK+FMO
+GnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4ZSJCB
+Qw5z
+-----END DSA PARAMETERS-----
diff --git a/deps/openssl/openssl/test/smime-certs/smroot.pem b/deps/openssl/openssl/test/smime-certs/smroot.pem
new file mode 100644
index 000000000..a59eb2684
--- /dev/null
+++ b/deps/openssl/openssl/test/smime-certs/smroot.pem
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDBV1Z/Q5gPF7lojc8pKUdyz5+Jf2B3vs4he6egekugWnoJduki
+9Lnae/JchB/soIX0co3nLc11NuFFlnAWJNMDJr08l5AHAJLYNHevF5l/f9oDQwvZ
+speKh1xpIAJNqCTzVeQ/ZLx6/GccIXV/xDuKIiovqJTPgR5WPkYKaw++lQIDAQAB
+AoGALXnUj5SflJU4+B2652ydMKUjWl0KnL/VjkyejgGV/j6py8Ybaixz9q8Gv7oY
+JDlRqMC1HfZJCFQDQrHy5VJ+CywA/H9WrqKo/Ch9U4tJAZtkig1Cmay/BAYixVu0
+xBeim10aKF6hxHH4Chg9We+OCuzWBWJhqveNjuDedL/i7JUCQQDlejovcwBUCbhJ
+U12qKOwlaboolWbl7yF3XdckTJZg7+1UqQHZH5jYZlLZyZxiaC92SNV0SyTLJZnS
+Jh5CO+VDAkEA16/pPcuVtMMz/R6SSPpRSIAa1stLs0mFSs3NpR4pdm0n42mu05pO
+1tJEt3a1g7zkreQBf53+Dwb+lA841EkjRwJBAIFmt0DifKDnCkBu/jZh9SfzwsH3
+3Zpzik+hXxxdA7+ODCrdUul449vDd5zQD5t+XKU61QNLDGhxv5e9XvrCg7kCQH/a
+3ldsVF0oDaxxL+QkxoREtCQ5tLEd1u7F2q6Tl56FDE0pe6Ih6bQ8RtG+g9EI60IN
+U7oTrOO5kLWx5E0q4ccCQAZVgoenn9MhRU1agKOCuM6LT2DxReTu4XztJzynej+8
+0J93n3ebanB1MlRpn1XJwhQ7gAC8ImaQKLJK5jdJzFc=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICaTCCAdKgAwIBAgIJAP6VN47boiXRMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDdaFw0xNjA1MTExMzUzMDdaMEQx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRU
+ZXN0IFMvTUlNRSBSU0EgUm9vdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
+wVdWf0OYDxe5aI3PKSlHcs+fiX9gd77OIXunoHpLoFp6CXbpIvS52nvyXIQf7KCF
+9HKN5y3NdTbhRZZwFiTTAya9PJeQBwCS2DR3rxeZf3/aA0ML2bKXiodcaSACTagk
+81XkP2S8evxnHCF1f8Q7iiIqL6iUz4EeVj5GCmsPvpUCAwEAAaNjMGEwHQYDVR0O
+BBYEFBPPS6e7iS6zOFcXdsabrWhb5e0XMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcX
+dsabrWhb5e0XMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqG
+SIb3DQEBBQUAA4GBAIECprq5viDvnDbkyOaiSr9ubMUmWqvycfAJMdPZRKcOZczS
+l+L9R9lF3JSqbt3knOe9u6bGDBOTY2285PdCCuHRVMk2Af1f6El1fqAlRUwNqipp
+r68sWFuRqrcRNtk6QQvXfkOhrqQBuDa7te/OVQLa2lGN9Dr2mQsD8ijctatG
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/test/smime-certs/smrsa1.pem b/deps/openssl/openssl/test/smime-certs/smrsa1.pem
new file mode 100644
index 000000000..2cf3148e3
--- /dev/null
+++ b/deps/openssl/openssl/test/smime-certs/smrsa1.pem
@@ -0,0 +1,31 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQC6A978j4pmPgUtUQqF+bjh6vdhwGOGZSD7xXgFTMjm88twfv+E
+ixkq2KXSDjD0ZXoQbdOaSbvGRQrIJpG2NGiKAFdYNrP025kCCdh5wF/aEI7KLEm7
+JlHwXpQsuj4wkMgmkFjL3Ty4Z55aNH+2pPQIa0k+ENJXm2gDuhqgBmduAwIDAQAB
+AoGBAJMuYu51aO2THyeHGwt81uOytcCbqGP7eoib62ZOJhxPRGYjpmuqX+R9/V5i
+KiwGavm63JYUx0WO9YP+uIZxm1BUATzkgkS74u5LP6ajhkZh6/Bck1oIYYkbVOXl
+JVrdENuH6U7nupznsyYgONByo+ykFPVUGmutgiaC7NMVo/MxAkEA6KLejWXdCIEn
+xr7hGph9NlvY9xuRIMexRV/WrddcFfCdjI1PciIupgrIkR65M9yr7atm1iU6/aRf
+KOr8rLZsSQJBAMyyXN71NsDNx4BP6rtJ/LJMP0BylznWkA7zWfGCbAYn9VhZVlSY
+Eu9Gyr7quD1ix7G3kInKVYOEEOpockBLz+sCQQCedyMmKjcQLfpMVYW8uhbAynvW
+h36qV5yXZxszO7nMcCTBsxhk5IfmLv5EbCs3+p9avCDGyoGOeUMg+kC33WORAkAg
+oUIarH4o5+SoeJTTfCzTA0KF9H5U0vYt2+73h7HOnWoHxl3zqDZEfEVvf50U8/0f
+QELDJETTbScBJtsnkq43AkEA38etvoZ2i4FJvvo7R/9gWBHVEcrGzcsCBYrNnIR1
+SZLRwHEGaiOK1wxMsWzqp7PJwL9z/M8A8DyOFBx3GPOniA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICizCCAfSgAwIBAgIJAMtotfHYdEsTMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBSU0EgIzEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
+ALoD3vyPimY+BS1RCoX5uOHq92HAY4ZlIPvFeAVMyObzy3B+/4SLGSrYpdIOMPRl
+ehBt05pJu8ZFCsgmkbY0aIoAV1g2s/TbmQIJ2HnAX9oQjsosSbsmUfBelCy6PjCQ
+yCaQWMvdPLhnnlo0f7ak9AhrST4Q0lebaAO6GqAGZ24DAgMBAAGjgYMwgYAwHQYD
+VR0OBBYEFE2vMvKz5jrC7Lbdg68XwZ95iL/QMB8GA1UdIwQYMBaAFBPPS6e7iS6z
+OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
+EQQZMBeBFXNtaW1lcnNhMUBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQAi
+O3GOkUl646oLnOimc36i9wxZ1tejsqs8vMjJ0Pym6Uq9FE2JoGzJ6OhB1GOsEVmj
+9cQ5UNQcRYL3cqOFtl6f4Dpu/lhzfbaqgmLjv29G1mS0uuTZrixhlyCXjwcbOkNC
+I/+wvHHENYIK5+T/79M9LaZ2Qk4F9MNE1VMljdz9Qw==
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/test/smime-certs/smrsa2.pem b/deps/openssl/openssl/test/smime-certs/smrsa2.pem
new file mode 100644
index 000000000..d41f69c82
--- /dev/null
+++ b/deps/openssl/openssl/test/smime-certs/smrsa2.pem
@@ -0,0 +1,31 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWwIBAAKBgQCwBfryW4Vu5U9wNIDKspJO/N9YF4CcTlrCUyzVlKgb+8urHlSe
+59i5verR9IOCCXkemjOzZ/3nALTGqYZlnEvHp0Rjk+KdKXnKBIB+SRPpeu3LcXMT
+WPgsThPa0UQxedNKG0g6aG+kLhsDlFBCoxd09jJtSpb9jmroJOq0ZYEHLwIDAQAB
+AoGAKa/w4677Je1W5+r3SYoLDnvi5TkDs4D3C6ipKJgBTEdQz+DqB4w/DpZE4551
++rkFn1LDxcxuHGRVa+tAMhZW97fwq9YUbjVZEyOz79qrX+BMyl/NbHkf1lIKDo3q
+dWalzQvop7nbzeLC+VmmviwZfLQUbA61AQl3jm4dswT4XykCQQDloDadEv/28NTx
+bvvywvyGuvJkCkEIycm4JrIInvwsd76h/chZ3oymrqzc7hkEtK6kThqlS5y+WXl6
+QzPruTKTAkEAxD2ro/VUoN+scIVaLmn0RBmZ67+9Pdn6pNSfjlK3s0T0EM6/iUWS
+M06l6L9wFS3/ceu1tIifsh9BeqOGTa+udQJARIFnybTBaIqw/NZ/lA1YCVn8tpvY
+iyaoZ6gjtS65TQrsdKeh/i3HCHNUXxUpoZ3F/H7QtD+6o49ODou+EbVOwQJAVmex
+A2gp8wuJKaINqxIL81AybZLnCCzKJ3lXJ5tUNyLNM/lUbGStktm2Q1zHRQwTxV07
+jFn7trn8YrtNjzcjYQJAUKIJRt38A8Jw3HoPT+D0WS2IgxjVL0eYGsZX1lyeammG
+6rfnQ3u5uP7mEK2EH2o8mDUpAE0gclWBU9UkKxJsGA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICizCCAfSgAwIBAgIJAMtotfHYdEsUMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBSU0EgIzIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
+ALAF+vJbhW7lT3A0gMqykk7831gXgJxOWsJTLNWUqBv7y6seVJ7n2Lm96tH0g4IJ
+eR6aM7Nn/ecAtMaphmWcS8enRGOT4p0pecoEgH5JE+l67ctxcxNY+CxOE9rRRDF5
+00obSDpob6QuGwOUUEKjF3T2Mm1Klv2Oaugk6rRlgQcvAgMBAAGjgYMwgYAwHQYD
+VR0OBBYEFIL/u+mEvaw7RuKLRuElfVkxSQjYMB8GA1UdIwQYMBaAFBPPS6e7iS6z
+OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
+EQQZMBeBFXNtaW1lcnNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQC2
+rXR5bm/9RtOMQPleNpd3y6uUX3oy+0CafK5Yl3PMnItjjnKJ0l1/DbLbDj2twehe
+ewaB8CROcBCA3AMLSmGvPKgUCFMGtWam3328M4fBHzon5ka7qDXzM+imkAly/Yx2
+YNdR/aNOug+5sXygHmTSKqiCpQjOIClzXoPVVeEVHw==
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/test/smime-certs/smrsa3.pem b/deps/openssl/openssl/test/smime-certs/smrsa3.pem
new file mode 100644
index 000000000..c8cbe5515
--- /dev/null
+++ b/deps/openssl/openssl/test/smime-certs/smrsa3.pem
@@ -0,0 +1,31 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQC6syTZtZNe1hRScFc4PUVyVLsr7+C1HDIZnOHmwFoLayX6RHwy
+ep/TkdwiPHnemVLuwvpSjLMLZkXy/J764kSHJrNeVl3UvmCVCOm40hAtK1+F39pM
+h8phkbPPD7i+hwq4/Vs79o46nzwbVKmzgoZBJhZ+codujUSYM3LjJ4aq+wIDAQAB
+AoGAE1Zixrnr3bLGwBMqtYSDIOhtyos59whImCaLr17U9MHQWS+mvYO98if1aQZi
+iQ/QazJ+wvYXxWJ+dEB+JvYwqrGeuAU6He/rAb4OShG4FPVU2D19gzRnaButWMeT
+/1lgXV08hegGBL7RQNaN7b0viFYMcKnSghleMP0/q+Y/oaECQQDkXEwDYJW13X9p
+ijS20ykWdY5lLknjkHRhhOYux0rlhOqsyMZjoUmwI2m0qj9yrIysKhrk4MZaM/uC
+hy0xp3hdAkEA0Uv/UY0Kwsgc+W6YxeypECtg1qCE6FBib8n4iFy/6VcWqhvE5xrs
+OdhKv9/p6aLjLneGd1sU+F8eS9LGyKIbNwJBAJPgbNzXA7uUZriqZb5qeTXxBDfj
+RLfXSHYKAKEULxz3+JvRHB9SR4yHMiFrCdExiZrHXUkPgYLSHLGG5a4824UCQD6T
+9XvhquUARkGCAuWy0/3Eqoihp/t6BWSdQ9Upviu7YUhtUxsyXo0REZB7F4pGrJx5
+GlhXgFaewgUzuUHFzlMCQCzJMMWslWpoLntnR6sMhBMhBFHSw+Y5CbxBmFrdtSkd
+VdtNO1VuDCTxjjW7W3Khj7LX4KZ1ye/5jfAgnnnXisc=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICizCCAfSgAwIBAgIJAMtotfHYdEsVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBSU0EgIzMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
+ALqzJNm1k17WFFJwVzg9RXJUuyvv4LUcMhmc4ebAWgtrJfpEfDJ6n9OR3CI8ed6Z
+Uu7C+lKMswtmRfL8nvriRIcms15WXdS+YJUI6bjSEC0rX4Xf2kyHymGRs88PuL6H
+Crj9Wzv2jjqfPBtUqbOChkEmFn5yh26NRJgzcuMnhqr7AgMBAAGjgYMwgYAwHQYD
+VR0OBBYEFDsSFjNtYZzd0tTHafNS7tneQQj6MB8GA1UdIwQYMBaAFBPPS6e7iS6z
+OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
+EQQZMBeBFXNtaW1lcnNhM0BvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQBE
+tUDB+1Dqigu4p1xtdq7JRK6S+gfA7RWmhz0j2scb2zhpS12h37JLHsidGeKAzZYq
+jUjOrH/j3xcV5AnuJoqImJaN23nzzxtR4qGGX2mrq6EtObzdEGgCUaizsGM+0slJ
+PYxcy8KeY/63B1BpYhj2RjGkL6HrvuAaxVORa3acoA==
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/test/srptest.c b/deps/openssl/openssl/test/srptest.c
new file mode 100644
index 000000000..04b66b454
--- /dev/null
+++ b/deps/openssl/openssl/test/srptest.c
@@ -0,0 +1,162 @@
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_SRP
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+ {
+ printf("No SRP support\n");
+ return(0);
+ }
+
+#else
+
+#include <openssl/srp.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+static void showbn(const char *name, const BIGNUM *bn)
+ {
+ fputs(name, stdout);
+ fputs(" = ", stdout);
+ BN_print_fp(stdout, bn);
+ putc('\n', stdout);
+ }
+
+#define RANDOM_SIZE 32 /* use 256 bits on each side */
+
+static int run_srp(const char *username, const char *client_pass, const char *server_pass)
+ {
+ int ret=-1;
+ BIGNUM *s = NULL;
+ BIGNUM *v = NULL;
+ BIGNUM *a = NULL;
+ BIGNUM *b = NULL;
+ BIGNUM *u = NULL;
+ BIGNUM *x = NULL;
+ BIGNUM *Apub = NULL;
+ BIGNUM *Bpub = NULL;
+ BIGNUM *Kclient = NULL;
+ BIGNUM *Kserver = NULL;
+ unsigned char rand_tmp[RANDOM_SIZE];
+ /* use builtin 1024-bit params */
+ SRP_gN *GN = SRP_get_default_gN("1024");
+
+ if(GN == NULL)
+ {
+ fprintf(stderr, "Failed to get SRP parameters\n");
+ return -1;
+ }
+ /* Set up server's password entry */
+ if(!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g))
+ {
+ fprintf(stderr, "Failed to create SRP verifier\n");
+ return -1;
+ }
+
+ showbn("N", GN->N);
+ showbn("g", GN->g);
+ showbn("Salt", s);
+ showbn("Verifier", v);
+
+ /* Server random */
+ RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
+ b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
+ /* TODO - check b != 0 */
+ showbn("b", b);
+
+ /* Server's first message */
+ Bpub = SRP_Calc_B(b, GN->N, GN->g, v);
+ showbn("B", Bpub);
+
+ if(!SRP_Verify_B_mod_N(Bpub, GN->N))
+ {
+ fprintf(stderr, "Invalid B\n");
+ return -1;
+ }
+
+ /* Client random */
+ RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
+ a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
+ /* TODO - check a != 0 */
+ showbn("a", a);
+
+ /* Client's response */
+ Apub = SRP_Calc_A(a, GN->N, GN->g);
+ showbn("A", Apub);
+
+ if(!SRP_Verify_A_mod_N(Apub, GN->N))
+ {
+ fprintf(stderr, "Invalid A\n");
+ return -1;
+ }
+
+ /* Both sides calculate u */
+ u = SRP_Calc_u(Apub, Bpub, GN->N);
+
+ /* Client's key */
+ x = SRP_Calc_x(s, username, client_pass);
+ Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u);
+ showbn("Client's key", Kclient);
+
+ /* Server's key */
+ Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N);
+ showbn("Server's key", Kserver);
+
+ if(BN_cmp(Kclient, Kserver) == 0)
+ {
+ ret = 0;
+ }
+ else
+ {
+ fprintf(stderr, "Keys mismatch\n");
+ ret = 1;
+ }
+
+ BN_clear_free(Kclient);
+ BN_clear_free(Kserver);
+ BN_clear_free(x);
+ BN_free(u);
+ BN_free(Apub);
+ BN_clear_free(a);
+ BN_free(Bpub);
+ BN_clear_free(b);
+ BN_free(s);
+ BN_clear_free(v);
+
+ return ret;
+ }
+
+int main(int argc, char **argv)
+ {
+ BIO *bio_err;
+ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+ CRYPTO_malloc_debug_init();
+ CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ ERR_load_crypto_strings();
+
+ /* "Negative" test, expect a mismatch */
+ if(run_srp("alice", "password1", "password2") == 0)
+ {
+ fprintf(stderr, "Mismatched SRP run failed\n");
+ return 1;
+ }
+
+ /* "Positive" test, should pass */
+ if(run_srp("alice", "password", "password") != 0)
+ {
+ fprintf(stderr, "Plain SRP run failed\n");
+ return 1;
+ }
+
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+ ERR_free_strings();
+ CRYPTO_mem_leaks(bio_err);
+
+ return 0;
+ }
+#endif
diff --git a/deps/openssl/openssl/test/ssltest.c b/deps/openssl/openssl/test/ssltest.c
new file mode 100644
index 000000000..316bbb0c9
--- /dev/null
+++ b/deps/openssl/openssl/test/ssltest.c
@@ -0,0 +1,2577 @@
+/* ssl/ssltest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#define _BSD_SOURCE 1 /* Or gethostname won't be declared properly
+ on Linux and GNU platforms. */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#define USE_SOCKETS
+#include "e_os.h"
+
+#ifdef OPENSSL_SYS_VMS
+#define _XOPEN_SOURCE 500 /* Or isascii won't be declared properly on
+ VMS (at least with DECompHP C). */
+#endif
+
+#include <ctype.h>
+
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/ssl.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_SRP
+#include <openssl/srp.h>
+#endif
+#include <openssl/bn.h>
+
+#define _XOPEN_SOURCE_EXTENDED 1 /* Or gethostname won't be declared properly
+ on Compaq platforms (at least with DEC C).
+ Do not try to put it earlier, or IPv6 includes
+ get screwed...
+ */
+
+#ifdef OPENSSL_SYS_WINDOWS
+#include <winsock.h>
+#else
+#include OPENSSL_UNISTD
+#endif
+
+#ifdef OPENSSL_SYS_VMS
+# define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM"
+# define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM"
+#elif defined(OPENSSL_SYS_WINCE)
+# define TEST_SERVER_CERT "\\OpenSSL\\server.pem"
+# define TEST_CLIENT_CERT "\\OpenSSL\\client.pem"
+#elif defined(OPENSSL_SYS_NETWARE)
+# define TEST_SERVER_CERT "\\openssl\\apps\\server.pem"
+# define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem"
+#else
+# define TEST_SERVER_CERT "../apps/server.pem"
+# define TEST_CLIENT_CERT "../apps/client.pem"
+#endif
+
+/* There is really no standard for this, so let's assign some tentative
+ numbers. In any case, these numbers are only for this test */
+#define COMP_RLE 255
+#define COMP_ZLIB 1
+
+static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
+#ifndef OPENSSL_NO_RSA
+static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export,int keylength);
+static void free_tmp_rsa(void);
+#endif
+static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg);
+#define APP_CALLBACK_STRING "Test Callback Argument"
+struct app_verify_arg
+ {
+ char *string;
+ int app_verify;
+ int allow_proxy_certs;
+ char *proxy_auth;
+ char *proxy_cond;
+ };
+
+#ifndef OPENSSL_NO_DH
+static DH *get_dh512(void);
+static DH *get_dh1024(void);
+static DH *get_dh1024dsa(void);
+#endif
+
+
+static char *psk_key=NULL; /* by default PSK is not used */
+#ifndef OPENSSL_NO_PSK
+static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity,
+ unsigned int max_identity_len, unsigned char *psk,
+ unsigned int max_psk_len);
+static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk,
+ unsigned int max_psk_len);
+#endif
+
+#ifndef OPENSSL_NO_SRP
+/* SRP client */
+/* This is a context that we pass to all callbacks */
+typedef struct srp_client_arg_st
+ {
+ char *srppassin;
+ char *srplogin;
+ } SRP_CLIENT_ARG;
+
+#define PWD_STRLEN 1024
+
+static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
+ {
+ SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
+ return BUF_strdup((char *)srp_client_arg->srppassin);
+ }
+
+/* SRP server */
+/* This is a context that we pass to SRP server callbacks */
+typedef struct srp_server_arg_st
+ {
+ char *expected_user;
+ char *pass;
+ } SRP_SERVER_ARG;
+
+static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
+ {
+ SRP_SERVER_ARG * p = (SRP_SERVER_ARG *) arg;
+
+ if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0)
+ {
+ fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s));
+ return SSL3_AL_FATAL;
+ }
+ if (SSL_set_srp_server_param_pw(s,p->expected_user,p->pass,"1024")<0)
+ {
+ *ad = SSL_AD_INTERNAL_ERROR;
+ return SSL3_AL_FATAL;
+ }
+ return SSL_ERROR_NONE;
+ }
+#endif
+
+static BIO *bio_err=NULL;
+static BIO *bio_stdout=NULL;
+
+static char *cipher=NULL;
+static int verbose=0;
+static int debug=0;
+#if 0
+/* Not used yet. */
+#ifdef FIONBIO
+static int s_nbio=0;
+#endif
+#endif
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int doit_biopair(SSL *s_ssl,SSL *c_ssl,long bytes,clock_t *s_time,clock_t *c_time);
+int doit(SSL *s_ssl,SSL *c_ssl,long bytes);
+static int do_test_cipherlist(void);
+static void sv_usage(void)
+ {
+ fprintf(stderr,"usage: ssltest [args ...]\n");
+ fprintf(stderr,"\n");
+#ifdef OPENSSL_FIPS
+ fprintf(stderr,"-F - run test in FIPS mode\n");
+#endif
+ fprintf(stderr," -server_auth - check server certificate\n");
+ fprintf(stderr," -client_auth - do client authentication\n");
+ fprintf(stderr," -proxy - allow proxy certificates\n");
+ fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n");
+ fprintf(stderr," -proxy_cond <val> - experssion to test proxy policy rights\n");
+ fprintf(stderr," -v - more output\n");
+ fprintf(stderr," -d - debug output\n");
+ fprintf(stderr," -reuse - use session-id reuse\n");
+ fprintf(stderr," -num <val> - number of connections to perform\n");
+ fprintf(stderr," -bytes <val> - number of bytes to swap between client/server\n");
+#ifndef OPENSSL_NO_DH
+ fprintf(stderr," -dhe1024 - use 1024 bit key (safe prime) for DHE\n");
+ fprintf(stderr," -dhe1024dsa - use 1024 bit key (with 160-bit subprime) for DHE\n");
+ fprintf(stderr," -no_dhe - disable DHE\n");
+#endif
+#ifndef OPENSSL_NO_ECDH
+ fprintf(stderr," -no_ecdhe - disable ECDHE\n");
+#endif
+#ifndef OPENSSL_NO_PSK
+ fprintf(stderr," -psk arg - PSK in hex (without 0x)\n");
+#endif
+#ifndef OPENSSL_NO_SRP
+ fprintf(stderr," -srpuser user - SRP username to use\n");
+ fprintf(stderr," -srppass arg - password for 'user'\n");
+#endif
+#ifndef OPENSSL_NO_SSL2
+ fprintf(stderr," -ssl2 - use SSLv2\n");
+#endif
+#ifndef OPENSSL_NO_SSL3
+ fprintf(stderr," -ssl3 - use SSLv3\n");
+#endif
+#ifndef OPENSSL_NO_TLS1
+ fprintf(stderr," -tls1 - use TLSv1\n");
+#endif
+ fprintf(stderr," -CApath arg - PEM format directory of CA's\n");
+ fprintf(stderr," -CAfile arg - PEM format file of CA's\n");
+ fprintf(stderr," -cert arg - Server certificate file\n");
+ fprintf(stderr," -key arg - Server key file (default: same as -cert)\n");
+ fprintf(stderr," -c_cert arg - Client certificate file\n");
+ fprintf(stderr," -c_key arg - Client key file (default: same as -c_cert)\n");
+ fprintf(stderr," -cipher arg - The cipher list\n");
+ fprintf(stderr," -bio_pair - Use BIO pairs\n");
+ fprintf(stderr," -f - Test even cases that can't work\n");
+ fprintf(stderr," -time - measure processor time used by client and server\n");
+ fprintf(stderr," -zlib - use zlib compression\n");
+ fprintf(stderr," -rle - use rle compression\n");
+#ifndef OPENSSL_NO_ECDH
+ fprintf(stderr," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \
+ " Use \"openssl ecparam -list_curves\" for all names\n" \
+ " (default is sect163r2).\n");
+#endif
+ fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
+ }
+
+static void print_details(SSL *c_ssl, const char *prefix)
+ {
+ const SSL_CIPHER *ciph;
+ X509 *cert;
+
+ ciph=SSL_get_current_cipher(c_ssl);
+ BIO_printf(bio_stdout,"%s%s, cipher %s %s",
+ prefix,
+ SSL_get_version(c_ssl),
+ SSL_CIPHER_get_version(ciph),
+ SSL_CIPHER_get_name(ciph));
+ cert=SSL_get_peer_certificate(c_ssl);
+ if (cert != NULL)
+ {
+ EVP_PKEY *pkey = X509_get_pubkey(cert);
+ if (pkey != NULL)
+ {
+ if (0)
+ ;
+#ifndef OPENSSL_NO_RSA
+ else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
+ && pkey->pkey.rsa->n != NULL)
+ {
+ BIO_printf(bio_stdout, ", %d bit RSA",
+ BN_num_bits(pkey->pkey.rsa->n));
+ }
+#endif
+#ifndef OPENSSL_NO_DSA
+ else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
+ && pkey->pkey.dsa->p != NULL)
+ {
+ BIO_printf(bio_stdout, ", %d bit DSA",
+ BN_num_bits(pkey->pkey.dsa->p));
+ }
+#endif
+ EVP_PKEY_free(pkey);
+ }
+ X509_free(cert);
+ }
+ /* The SSL API does not allow us to look at temporary RSA/DH keys,
+ * otherwise we should print their lengths too */
+ BIO_printf(bio_stdout,"\n");
+ }
+
+static void lock_dbg_cb(int mode, int type, const char *file, int line)
+ {
+ static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
+ const char *errstr = NULL;
+ int rw;
+
+ rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
+ if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
+ {
+ errstr = "invalid mode";
+ goto err;
+ }
+
+ if (type < 0 || type >= CRYPTO_NUM_LOCKS)
+ {
+ errstr = "type out of bounds";
+ goto err;
+ }
+
+ if (mode & CRYPTO_LOCK)
+ {
+ if (modes[type])
+ {
+ errstr = "already locked";
+ /* must not happen in a single-threaded program
+ * (would deadlock) */
+ goto err;
+ }
+
+ modes[type] = rw;
+ }
+ else if (mode & CRYPTO_UNLOCK)
+ {
+ if (!modes[type])
+ {
+ errstr = "not locked";
+ goto err;
+ }
+
+ if (modes[type] != rw)
+ {
+ errstr = (rw == CRYPTO_READ) ?
+ "CRYPTO_r_unlock on write lock" :
+ "CRYPTO_w_unlock on read lock";
+ }
+
+ modes[type] = 0;
+ }
+ else
+ {
+ errstr = "invalid mode";
+ goto err;
+ }
+
+ err:
+ if (errstr)
+ {
+ /* we cannot use bio_err here */
+ fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
+ errstr, mode, type, file, line);
+ }
+ }
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+struct cb_info_st { void *input; size_t len; int ret; };
+struct cb_info_st co1 = { "C", 1, 1 }; /* try to negotiate oqaque PRF input */
+struct cb_info_st co2 = { "C", 1, 2 }; /* insist on oqaque PRF input */
+struct cb_info_st so1 = { "S", 1, 1 }; /* try to negotiate oqaque PRF input */
+struct cb_info_st so2 = { "S", 1, 2 }; /* insist on oqaque PRF input */
+
+int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_)
+ {
+ struct cb_info_st *arg = arg_;
+
+ if (arg == NULL)
+ return 1;
+
+ if (!SSL_set_tlsext_opaque_prf_input(ssl, arg->input, arg->len))
+ return 0;
+ return arg->ret;
+ }
+#endif
+
+int main(int argc, char *argv[])
+ {
+ char *CApath=NULL,*CAfile=NULL;
+ int badop=0;
+ int bio_pair=0;
+ int force=0;
+ int tls1=0,ssl2=0,ssl3=0,ret=1;
+ int client_auth=0;
+ int server_auth=0,i;
+ struct app_verify_arg app_verify_arg =
+ { APP_CALLBACK_STRING, 0, 0, NULL, NULL };
+ char *server_cert=TEST_SERVER_CERT;
+ char *server_key=NULL;
+ char *client_cert=TEST_CLIENT_CERT;
+ char *client_key=NULL;
+#ifndef OPENSSL_NO_ECDH
+ char *named_curve = NULL;
+#endif
+ SSL_CTX *s_ctx=NULL;
+ SSL_CTX *c_ctx=NULL;
+ const SSL_METHOD *meth=NULL;
+ SSL *c_ssl,*s_ssl;
+ int number=1,reuse=0;
+ long bytes=256L;
+#ifndef OPENSSL_NO_DH
+ DH *dh;
+ int dhe1024 = 0, dhe1024dsa = 0;
+#endif
+#ifndef OPENSSL_NO_ECDH
+ EC_KEY *ecdh = NULL;
+#endif
+#ifndef OPENSSL_NO_SRP
+ /* client */
+ SRP_CLIENT_ARG srp_client_arg = {NULL,NULL};
+ /* server */
+ SRP_SERVER_ARG srp_server_arg = {NULL,NULL};
+#endif
+ int no_dhe = 0;
+ int no_ecdhe = 0;
+ int no_psk = 0;
+ int print_time = 0;
+ clock_t s_time = 0, c_time = 0;
+ int comp = 0;
+#ifndef OPENSSL_NO_COMP
+ COMP_METHOD *cm = NULL;
+ STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+#endif
+ int test_cipherlist = 0;
+#ifdef OPENSSL_FIPS
+ int fips_mode=0;
+#endif
+
+ verbose = 0;
+ debug = 0;
+ cipher = 0;
+
+ bio_err=BIO_new_fp(stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ CRYPTO_set_locking_callback(lock_dbg_cb);
+
+ /* enable memory leak checking unless explicitly disabled */
+ if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
+ {
+ CRYPTO_malloc_debug_init();
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+ }
+ else
+ {
+ /* OPENSSL_DEBUG_MEMORY=off */
+ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+ }
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ RAND_seed(rnd_seed, sizeof rnd_seed);
+
+ bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE|BIO_FP_TEXT);
+
+ argc--;
+ argv++;
+
+ while (argc >= 1)
+ {
+ if(!strcmp(*argv,"-F"))
+ {
+#ifdef OPENSSL_FIPS
+ fips_mode=1;
+#else
+ fprintf(stderr,"not compiled with FIPS support, so exitting without running.\n");
+ EXIT(0);
+#endif
+ }
+ else if (strcmp(*argv,"-server_auth") == 0)
+ server_auth=1;
+ else if (strcmp(*argv,"-client_auth") == 0)
+ client_auth=1;
+ else if (strcmp(*argv,"-proxy_auth") == 0)
+ {
+ if (--argc < 1) goto bad;
+ app_verify_arg.proxy_auth= *(++argv);
+ }
+ else if (strcmp(*argv,"-proxy_cond") == 0)
+ {
+ if (--argc < 1) goto bad;
+ app_verify_arg.proxy_cond= *(++argv);
+ }
+ else if (strcmp(*argv,"-v") == 0)
+ verbose=1;
+ else if (strcmp(*argv,"-d") == 0)
+ debug=1;
+ else if (strcmp(*argv,"-reuse") == 0)
+ reuse=1;
+ else if (strcmp(*argv,"-dhe1024") == 0)
+ {
+#ifndef OPENSSL_NO_DH
+ dhe1024=1;
+#else
+ fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
+#endif
+ }
+ else if (strcmp(*argv,"-dhe1024dsa") == 0)
+ {
+#ifndef OPENSSL_NO_DH
+ dhe1024dsa=1;
+#else
+ fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
+#endif
+ }
+ else if (strcmp(*argv,"-no_dhe") == 0)
+ no_dhe=1;
+ else if (strcmp(*argv,"-no_ecdhe") == 0)
+ no_ecdhe=1;
+ else if (strcmp(*argv,"-psk") == 0)
+ {
+ if (--argc < 1) goto bad;
+ psk_key=*(++argv);
+#ifndef OPENSSL_NO_PSK
+ if (strspn(psk_key, "abcdefABCDEF1234567890") != strlen(psk_key))
+ {
+ BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
+ goto bad;
+ }
+#else
+ no_psk=1;
+#endif
+ }
+#ifndef OPENSSL_NO_SRP
+ else if (strcmp(*argv,"-srpuser") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srp_server_arg.expected_user = srp_client_arg.srplogin= *(++argv);
+ tls1=1;
+ }
+ else if (strcmp(*argv,"-srppass") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srp_server_arg.pass = srp_client_arg.srppassin= *(++argv);
+ tls1=1;
+ }
+#endif
+ else if (strcmp(*argv,"-ssl2") == 0)
+ ssl2=1;
+ else if (strcmp(*argv,"-tls1") == 0)
+ tls1=1;
+ else if (strcmp(*argv,"-ssl3") == 0)
+ ssl3=1;
+ else if (strncmp(*argv,"-num",4) == 0)
+ {
+ if (--argc < 1) goto bad;
+ number= atoi(*(++argv));
+ if (number == 0) number=1;
+ }
+ else if (strcmp(*argv,"-bytes") == 0)
+ {
+ if (--argc < 1) goto bad;
+ bytes= atol(*(++argv));
+ if (bytes == 0L) bytes=1L;
+ i=strlen(argv[0]);
+ if (argv[0][i-1] == 'k') bytes*=1024L;
+ if (argv[0][i-1] == 'm') bytes*=1024L*1024L;
+ }
+ else if (strcmp(*argv,"-cert") == 0)
+ {
+ if (--argc < 1) goto bad;
+ server_cert= *(++argv);
+ }
+ else if (strcmp(*argv,"-s_cert") == 0)
+ {
+ if (--argc < 1) goto bad;
+ server_cert= *(++argv);
+ }
+ else if (strcmp(*argv,"-key") == 0)
+ {
+ if (--argc < 1) goto bad;
+ server_key= *(++argv);
+ }
+ else if (strcmp(*argv,"-s_key") == 0)
+ {
+ if (--argc < 1) goto bad;
+ server_key= *(++argv);
+ }
+ else if (strcmp(*argv,"-c_cert") == 0)
+ {
+ if (--argc < 1) goto bad;
+ client_cert= *(++argv);
+ }
+ else if (strcmp(*argv,"-c_key") == 0)
+ {
+ if (--argc < 1) goto bad;
+ client_key= *(++argv);
+ }
+ else if (strcmp(*argv,"-cipher") == 0)
+ {
+ if (--argc < 1) goto bad;
+ cipher= *(++argv);
+ }
+ else if (strcmp(*argv,"-CApath") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CApath= *(++argv);
+ }
+ else if (strcmp(*argv,"-CAfile") == 0)
+ {
+ if (--argc < 1) goto bad;
+ CAfile= *(++argv);
+ }
+ else if (strcmp(*argv,"-bio_pair") == 0)
+ {
+ bio_pair = 1;
+ }
+ else if (strcmp(*argv,"-f") == 0)
+ {
+ force = 1;
+ }
+ else if (strcmp(*argv,"-time") == 0)
+ {
+ print_time = 1;
+ }
+ else if (strcmp(*argv,"-zlib") == 0)
+ {
+ comp = COMP_ZLIB;
+ }
+ else if (strcmp(*argv,"-rle") == 0)
+ {
+ comp = COMP_RLE;
+ }
+ else if (strcmp(*argv,"-named_curve") == 0)
+ {
+ if (--argc < 1) goto bad;
+#ifndef OPENSSL_NO_ECDH
+ named_curve = *(++argv);
+#else
+ fprintf(stderr,"ignoring -named_curve, since I'm compiled without ECDH\n");
+ ++argv;
+#endif
+ }
+ else if (strcmp(*argv,"-app_verify") == 0)
+ {
+ app_verify_arg.app_verify = 1;
+ }
+ else if (strcmp(*argv,"-proxy") == 0)
+ {
+ app_verify_arg.allow_proxy_certs = 1;
+ }
+ else if (strcmp(*argv,"-test_cipherlist") == 0)
+ {
+ test_cipherlist = 1;
+ }
+ else
+ {
+ fprintf(stderr,"unknown option %s\n",*argv);
+ badop=1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+ if (badop)
+ {
+bad:
+ sv_usage();
+ goto end;
+ }
+
+ if (test_cipherlist == 1)
+ {
+ /* ensure that the cipher list are correctly sorted and exit */
+ if (do_test_cipherlist() == 0)
+ EXIT(1);
+ ret = 0;
+ goto end;
+ }
+
+ if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
+ {
+ fprintf(stderr, "This case cannot work. Use -f to perform "
+ "the test anyway (and\n-d to see what happens), "
+ "or add one of -ssl2, -ssl3, -tls1, -reuse\n"
+ "to avoid protocol mismatch.\n");
+ EXIT(1);
+ }
+
+#ifdef OPENSSL_FIPS
+ if(fips_mode)
+ {
+ if(!FIPS_mode_set(1))
+ {
+ ERR_load_crypto_strings();
+ ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
+ EXIT(1);
+ }
+ else
+ fprintf(stderr,"*** IN FIPS MODE ***\n");
+ }
+#endif
+
+ if (print_time)
+ {
+ if (!bio_pair)
+ {
+ fprintf(stderr, "Using BIO pair (-bio_pair)\n");
+ bio_pair = 1;
+ }
+ if (number < 50 && !force)
+ fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n");
+ }
+
+/* if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */
+
+ SSL_library_init();
+ SSL_load_error_strings();
+
+#ifndef OPENSSL_NO_COMP
+ if (comp == COMP_ZLIB) cm = COMP_zlib();
+ if (comp == COMP_RLE) cm = COMP_rle();
+ if (cm != NULL)
+ {
+ if (cm->type != NID_undef)
+ {
+ if (SSL_COMP_add_compression_method(comp, cm) != 0)
+ {
+ fprintf(stderr,
+ "Failed to add compression method\n");
+ ERR_print_errors_fp(stderr);
+ }
+ }
+ else
+ {
+ fprintf(stderr,
+ "Warning: %s compression not supported\n",
+ (comp == COMP_RLE ? "rle" :
+ (comp == COMP_ZLIB ? "zlib" :
+ "unknown")));
+ ERR_print_errors_fp(stderr);
+ }
+ }
+ ssl_comp_methods = SSL_COMP_get_compression_methods();
+ fprintf(stderr, "Available compression methods:\n");
+ {
+ int j, n = sk_SSL_COMP_num(ssl_comp_methods);
+ if (n == 0)
+ fprintf(stderr, " NONE\n");
+ else
+ for (j = 0; j < n; j++)
+ {
+ SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
+ fprintf(stderr, " %d: %s\n", c->id, c->name);
+ }
+ }
+#endif
+
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+ if (ssl2)
+ meth=SSLv2_method();
+ else
+ if (tls1)
+ meth=TLSv1_method();
+ else
+ if (ssl3)
+ meth=SSLv3_method();
+ else
+ meth=SSLv23_method();
+#else
+#ifdef OPENSSL_NO_SSL2
+ meth=SSLv3_method();
+#else
+ meth=SSLv2_method();
+#endif
+#endif
+
+ c_ctx=SSL_CTX_new(meth);
+ s_ctx=SSL_CTX_new(meth);
+ if ((c_ctx == NULL) || (s_ctx == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (cipher != NULL)
+ {
+ SSL_CTX_set_cipher_list(c_ctx,cipher);
+ SSL_CTX_set_cipher_list(s_ctx,cipher);
+ }
+
+#ifndef OPENSSL_NO_DH
+ if (!no_dhe)
+ {
+ if (dhe1024dsa)
+ {
+ /* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */
+ SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
+ dh=get_dh1024dsa();
+ }
+ else if (dhe1024)
+ dh=get_dh1024();
+ else
+ dh=get_dh512();
+ SSL_CTX_set_tmp_dh(s_ctx,dh);
+ DH_free(dh);
+ }
+#else
+ (void)no_dhe;
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+ if (!no_ecdhe)
+ {
+ int nid;
+
+ if (named_curve != NULL)
+ {
+ nid = OBJ_sn2nid(named_curve);
+ if (nid == 0)
+ {
+ BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
+ goto end;
+ }
+ }
+ else
+#ifdef OPENSSL_NO_EC2M
+ nid = NID_X9_62_prime256v1;
+#else
+ nid = NID_sect163r2;
+#endif
+
+ ecdh = EC_KEY_new_by_curve_name(nid);
+ if (ecdh == NULL)
+ {
+ BIO_printf(bio_err, "unable to create curve\n");
+ goto end;
+ }
+
+ SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
+ SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
+ EC_KEY_free(ecdh);
+ }
+#else
+ (void)no_ecdhe;
+#endif
+
+#ifndef OPENSSL_NO_RSA
+ SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb);
+#endif
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ SSL_CTX_set_tlsext_opaque_prf_input_callback(c_ctx, opaque_prf_input_cb);
+ SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx, opaque_prf_input_cb);
+ SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); /* or &co2 or NULL */
+ SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); /* or &so2 or NULL */
+#endif
+
+ if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM))
+ {
+ ERR_print_errors(bio_err);
+ }
+ else if (!SSL_CTX_use_PrivateKey_file(s_ctx,
+ (server_key?server_key:server_cert), SSL_FILETYPE_PEM))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ if (client_auth)
+ {
+ SSL_CTX_use_certificate_file(c_ctx,client_cert,
+ SSL_FILETYPE_PEM);
+ SSL_CTX_use_PrivateKey_file(c_ctx,
+ (client_key?client_key:client_cert),
+ SSL_FILETYPE_PEM);
+ }
+
+ if ( (!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
+ (!SSL_CTX_set_default_verify_paths(s_ctx)) ||
+ (!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
+ (!SSL_CTX_set_default_verify_paths(c_ctx)))
+ {
+ /* fprintf(stderr,"SSL_load_verify_locations\n"); */
+ ERR_print_errors(bio_err);
+ /* goto end; */
+ }
+
+ if (client_auth)
+ {
+ BIO_printf(bio_err,"client authentication\n");
+ SSL_CTX_set_verify(s_ctx,
+ SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+ verify_callback);
+ SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, &app_verify_arg);
+ }
+ if (server_auth)
+ {
+ BIO_printf(bio_err,"server authentication\n");
+ SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
+ verify_callback);
+ SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, &app_verify_arg);
+ }
+
+ {
+ int session_id_context = 0;
+ SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, sizeof session_id_context);
+ }
+
+ /* Use PSK only if PSK key is given */
+ if (psk_key != NULL)
+ {
+ /* no_psk is used to avoid putting psk command to openssl tool */
+ if (no_psk)
+ {
+ /* if PSK is not compiled in and psk key is
+ * given, do nothing and exit successfully */
+ ret=0;
+ goto end;
+ }
+#ifndef OPENSSL_NO_PSK
+ SSL_CTX_set_psk_client_callback(c_ctx, psk_client_callback);
+ SSL_CTX_set_psk_server_callback(s_ctx, psk_server_callback);
+ if (debug)
+ BIO_printf(bio_err,"setting PSK identity hint to s_ctx\n");
+ if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint"))
+ {
+ BIO_printf(bio_err,"error setting PSK identity hint to s_ctx\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+#endif
+ }
+#ifndef OPENSSL_NO_SRP
+ if (srp_client_arg.srplogin)
+ {
+ if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin))
+ {
+ BIO_printf(bio_err,"Unable to set SRP username\n");
+ goto end;
+ }
+ SSL_CTX_set_srp_cb_arg(c_ctx,&srp_client_arg);
+ SSL_CTX_set_srp_client_pwd_callback(c_ctx, ssl_give_srp_client_pwd_cb);
+ /*SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength);*/
+ }
+
+ if (srp_server_arg.expected_user != NULL)
+ {
+ SSL_CTX_set_verify(s_ctx,SSL_VERIFY_NONE,verify_callback);
+ SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg);
+ SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb);
+ }
+#endif
+
+ c_ssl=SSL_new(c_ctx);
+ s_ssl=SSL_new(s_ctx);
+
+#ifndef OPENSSL_NO_KRB5
+ if (c_ssl && c_ssl->kssl_ctx)
+ {
+ char localhost[MAXHOSTNAMELEN+2];
+
+ if (gethostname(localhost, sizeof localhost-1) == 0)
+ {
+ localhost[sizeof localhost-1]='\0';
+ if(strlen(localhost) == sizeof localhost-1)
+ {
+ BIO_printf(bio_err,"localhost name too long\n");
+ goto end;
+ }
+ kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER,
+ localhost);
+ }
+ }
+#endif /* OPENSSL_NO_KRB5 */
+
+ for (i=0; i<number; i++)
+ {
+ if (!reuse) SSL_set_session(c_ssl,NULL);
+ if (bio_pair)
+ ret=doit_biopair(s_ssl,c_ssl,bytes,&s_time,&c_time);
+ else
+ ret=doit(s_ssl,c_ssl,bytes);
+ }
+
+ if (!verbose)
+ {
+ print_details(c_ssl, "");
+ }
+ if ((number > 1) || (bytes > 1L))
+ BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n",number,bytes);
+ if (print_time)
+ {
+#ifdef CLOCKS_PER_SEC
+ /* "To determine the time in seconds, the value returned
+ * by the clock function should be divided by the value
+ * of the macro CLOCKS_PER_SEC."
+ * -- ISO/IEC 9899 */
+ BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n"
+ "Approximate total client time: %6.2f s\n",
+ (double)s_time/CLOCKS_PER_SEC,
+ (double)c_time/CLOCKS_PER_SEC);
+#else
+ /* "`CLOCKS_PER_SEC' undeclared (first use this function)"
+ * -- cc on NeXTstep/OpenStep */
+ BIO_printf(bio_stdout,
+ "Approximate total server time: %6.2f units\n"
+ "Approximate total client time: %6.2f units\n",
+ (double)s_time,
+ (double)c_time);
+#endif
+ }
+
+ SSL_free(s_ssl);
+ SSL_free(c_ssl);
+
+end:
+ if (s_ctx != NULL) SSL_CTX_free(s_ctx);
+ if (c_ctx != NULL) SSL_CTX_free(c_ctx);
+
+ if (bio_stdout != NULL) BIO_free(bio_stdout);
+
+#ifndef OPENSSL_NO_RSA
+ free_tmp_rsa();
+#endif
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_cleanup();
+#endif
+ CRYPTO_cleanup_all_ex_data();
+ ERR_free_strings();
+ ERR_remove_thread_state(NULL);
+ EVP_cleanup();
+ CRYPTO_mem_leaks(bio_err);
+ if (bio_err != NULL) BIO_free(bio_err);
+ EXIT(ret);
+ return ret;
+ }
+
+int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
+ clock_t *s_time, clock_t *c_time)
+ {
+ long cw_num = count, cr_num = count, sw_num = count, sr_num = count;
+ BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
+ BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL;
+ int ret = 1;
+
+ size_t bufsiz = 256; /* small buffer for testing */
+
+ if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz))
+ goto err;
+ if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz))
+ goto err;
+
+ s_ssl_bio = BIO_new(BIO_f_ssl());
+ if (!s_ssl_bio)
+ goto err;
+
+ c_ssl_bio = BIO_new(BIO_f_ssl());
+ if (!c_ssl_bio)
+ goto err;
+
+ SSL_set_connect_state(c_ssl);
+ SSL_set_bio(c_ssl, client, client);
+ (void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);
+
+ SSL_set_accept_state(s_ssl);
+ SSL_set_bio(s_ssl, server, server);
+ (void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);
+
+ do
+ {
+ /* c_ssl_bio: SSL filter BIO
+ *
+ * client: pseudo-I/O for SSL library
+ *
+ * client_io: client's SSL communication; usually to be
+ * relayed over some I/O facility, but in this
+ * test program, we're the server, too:
+ *
+ * server_io: server's SSL communication
+ *
+ * server: pseudo-I/O for SSL library
+ *
+ * s_ssl_bio: SSL filter BIO
+ *
+ * The client and the server each employ a "BIO pair":
+ * client + client_io, server + server_io.
+ * BIO pairs are symmetric. A BIO pair behaves similar
+ * to a non-blocking socketpair (but both endpoints must
+ * be handled by the same thread).
+ * [Here we could connect client and server to the ends
+ * of a single BIO pair, but then this code would be less
+ * suitable as an example for BIO pairs in general.]
+ *
+ * Useful functions for querying the state of BIO pair endpoints:
+ *
+ * BIO_ctrl_pending(bio) number of bytes we can read now
+ * BIO_ctrl_get_read_request(bio) number of bytes needed to fulfil
+ * other side's read attempt
+ * BIO_ctrl_get_write_guarantee(bio) number of bytes we can write now
+ *
+ * ..._read_request is never more than ..._write_guarantee;
+ * it depends on the application which one you should use.
+ */
+
+ /* We have non-blocking behaviour throughout this test program, but
+ * can be sure that there is *some* progress in each iteration; so
+ * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE
+ * -- we just try everything in each iteration
+ */
+
+ {
+ /* CLIENT */
+
+ MS_STATIC char cbuf[1024*8];
+ int i, r;
+ clock_t c_clock = clock();
+
+ memset(cbuf, 0, sizeof(cbuf));
+
+ if (debug)
+ if (SSL_in_init(c_ssl))
+ printf("client waiting in SSL_connect - %s\n",
+ SSL_state_string_long(c_ssl));
+
+ if (cw_num > 0)
+ {
+ /* Write to server. */
+
+ if (cw_num > (long)sizeof cbuf)
+ i = sizeof cbuf;
+ else
+ i = (int)cw_num;
+ r = BIO_write(c_ssl_bio, cbuf, i);
+ if (r < 0)
+ {
+ if (!BIO_should_retry(c_ssl_bio))
+ {
+ fprintf(stderr,"ERROR in CLIENT\n");
+ goto err;
+ }
+ /* BIO_should_retry(...) can just be ignored here.
+ * The library expects us to call BIO_write with
+ * the same arguments again, and that's what we will
+ * do in the next iteration. */
+ }
+ else if (r == 0)
+ {
+ fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
+ goto err;
+ }
+ else
+ {
+ if (debug)
+ printf("client wrote %d\n", r);
+ cw_num -= r;
+ }
+ }
+
+ if (cr_num > 0)
+ {
+ /* Read from server. */
+
+ r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));
+ if (r < 0)
+ {
+ if (!BIO_should_retry(c_ssl_bio))
+ {
+ fprintf(stderr,"ERROR in CLIENT\n");
+ goto err;
+ }
+ /* Again, "BIO_should_retry" can be ignored. */
+ }
+ else if (r == 0)
+ {
+ fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
+ goto err;
+ }
+ else
+ {
+ if (debug)
+ printf("client read %d\n", r);
+ cr_num -= r;
+ }
+ }
+
+ /* c_time and s_time increments will typically be very small
+ * (depending on machine speed and clock tick intervals),
+ * but sampling over a large number of connections should
+ * result in fairly accurate figures. We cannot guarantee
+ * a lot, however -- if each connection lasts for exactly
+ * one clock tick, it will be counted only for the client
+ * or only for the server or even not at all.
+ */
+ *c_time += (clock() - c_clock);
+ }
+
+ {
+ /* SERVER */
+
+ MS_STATIC char sbuf[1024*8];
+ int i, r;
+ clock_t s_clock = clock();
+
+ memset(sbuf, 0, sizeof(sbuf));
+
+ if (debug)
+ if (SSL_in_init(s_ssl))
+ printf("server waiting in SSL_accept - %s\n",
+ SSL_state_string_long(s_ssl));
+
+ if (sw_num > 0)
+ {
+ /* Write to client. */
+
+ if (sw_num > (long)sizeof sbuf)
+ i = sizeof sbuf;
+ else
+ i = (int)sw_num;
+ r = BIO_write(s_ssl_bio, sbuf, i);
+ if (r < 0)
+ {
+ if (!BIO_should_retry(s_ssl_bio))
+ {
+ fprintf(stderr,"ERROR in SERVER\n");
+ goto err;
+ }
+ /* Ignore "BIO_should_retry". */
+ }
+ else if (r == 0)
+ {
+ fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
+ goto err;
+ }
+ else
+ {
+ if (debug)
+ printf("server wrote %d\n", r);
+ sw_num -= r;
+ }
+ }
+
+ if (sr_num > 0)
+ {
+ /* Read from client. */
+
+ r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));
+ if (r < 0)
+ {
+ if (!BIO_should_retry(s_ssl_bio))
+ {
+ fprintf(stderr,"ERROR in SERVER\n");
+ goto err;
+ }
+ /* blah, blah */
+ }
+ else if (r == 0)
+ {
+ fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
+ goto err;
+ }
+ else
+ {
+ if (debug)
+ printf("server read %d\n", r);
+ sr_num -= r;
+ }
+ }
+
+ *s_time += (clock() - s_clock);
+ }
+
+ {
+ /* "I/O" BETWEEN CLIENT AND SERVER. */
+
+ size_t r1, r2;
+ BIO *io1 = server_io, *io2 = client_io;
+ /* we use the non-copying interface for io1
+ * and the standard BIO_write/BIO_read interface for io2
+ */
+
+ static int prev_progress = 1;
+ int progress = 0;
+
+ /* io1 to io2 */
+ do
+ {
+ size_t num;
+ int r;
+
+ r1 = BIO_ctrl_pending(io1);
+ r2 = BIO_ctrl_get_write_guarantee(io2);
+
+ num = r1;
+ if (r2 < num)
+ num = r2;
+ if (num)
+ {
+ char *dataptr;
+
+ if (INT_MAX < num) /* yeah, right */
+ num = INT_MAX;
+
+ r = BIO_nread(io1, &dataptr, (int)num);
+ assert(r > 0);
+ assert(r <= (int)num);
+ /* possibly r < num (non-contiguous data) */
+ num = r;
+ r = BIO_write(io2, dataptr, (int)num);
+ if (r != (int)num) /* can't happen */
+ {
+ fprintf(stderr, "ERROR: BIO_write could not write "
+ "BIO_ctrl_get_write_guarantee() bytes");
+ goto err;
+ }
+ progress = 1;
+
+ if (debug)
+ printf((io1 == client_io) ?
+ "C->S relaying: %d bytes\n" :
+ "S->C relaying: %d bytes\n",
+ (int)num);
+ }
+ }
+ while (r1 && r2);
+
+ /* io2 to io1 */
+ {
+ size_t num;
+ int r;
+
+ r1 = BIO_ctrl_pending(io2);
+ r2 = BIO_ctrl_get_read_request(io1);
+ /* here we could use ..._get_write_guarantee instead of
+ * ..._get_read_request, but by using the latter
+ * we test restartability of the SSL implementation
+ * more thoroughly */
+ num = r1;
+ if (r2 < num)
+ num = r2;
+ if (num)
+ {
+ char *dataptr;
+
+ if (INT_MAX < num)
+ num = INT_MAX;
+
+ if (num > 1)
+ --num; /* test restartability even more thoroughly */
+
+ r = BIO_nwrite0(io1, &dataptr);
+ assert(r > 0);
+ if (r < (int)num)
+ num = r;
+ r = BIO_read(io2, dataptr, (int)num);
+ if (r != (int)num) /* can't happen */
+ {
+ fprintf(stderr, "ERROR: BIO_read could not read "
+ "BIO_ctrl_pending() bytes");
+ goto err;
+ }
+ progress = 1;
+ r = BIO_nwrite(io1, &dataptr, (int)num);
+ if (r != (int)num) /* can't happen */
+ {
+ fprintf(stderr, "ERROR: BIO_nwrite() did not accept "
+ "BIO_nwrite0() bytes");
+ goto err;
+ }
+
+ if (debug)
+ printf((io2 == client_io) ?
+ "C->S relaying: %d bytes\n" :
+ "S->C relaying: %d bytes\n",
+ (int)num);
+ }
+ } /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */
+
+ if (!progress && !prev_progress)
+ if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0)
+ {
+ fprintf(stderr, "ERROR: got stuck\n");
+ if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0)
+ {
+ fprintf(stderr, "This can happen for SSL2 because "
+ "CLIENT-FINISHED and SERVER-VERIFY are written \n"
+ "concurrently ...");
+ if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0
+ && strncmp("2SSV", SSL_state_string(s_ssl), 4) == 0)
+ {
+ fprintf(stderr, " ok.\n");
+ goto end;
+ }
+ }
+ fprintf(stderr, " ERROR.\n");
+ goto err;
+ }
+ prev_progress = progress;
+ }
+ }
+ while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);
+
+ if (verbose)
+ print_details(c_ssl, "DONE via BIO pair: ");
+end:
+ ret = 0;
+
+ err:
+ ERR_print_errors(bio_err);
+
+ if (server)
+ BIO_free(server);
+ if (server_io)
+ BIO_free(server_io);
+ if (client)
+ BIO_free(client);
+ if (client_io)
+ BIO_free(client_io);
+ if (s_ssl_bio)
+ BIO_free(s_ssl_bio);
+ if (c_ssl_bio)
+ BIO_free(c_ssl_bio);
+
+ return ret;
+ }
+
+
+#define W_READ 1
+#define W_WRITE 2
+#define C_DONE 1
+#define S_DONE 2
+
+int doit(SSL *s_ssl, SSL *c_ssl, long count)
+ {
+ MS_STATIC char cbuf[1024*8],sbuf[1024*8];
+ long cw_num=count,cr_num=count;
+ long sw_num=count,sr_num=count;
+ int ret=1;
+ BIO *c_to_s=NULL;
+ BIO *s_to_c=NULL;
+ BIO *c_bio=NULL;
+ BIO *s_bio=NULL;
+ int c_r,c_w,s_r,s_w;
+ int i,j;
+ int done=0;
+ int c_write,s_write;
+ int do_server=0,do_client=0;
+
+ memset(cbuf,0,sizeof(cbuf));
+ memset(sbuf,0,sizeof(sbuf));
+
+ c_to_s=BIO_new(BIO_s_mem());
+ s_to_c=BIO_new(BIO_s_mem());
+ if ((s_to_c == NULL) || (c_to_s == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ c_bio=BIO_new(BIO_f_ssl());
+ s_bio=BIO_new(BIO_f_ssl());
+ if ((c_bio == NULL) || (s_bio == NULL))
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ SSL_set_connect_state(c_ssl);
+ SSL_set_bio(c_ssl,s_to_c,c_to_s);
+ BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE);
+
+ SSL_set_accept_state(s_ssl);
+ SSL_set_bio(s_ssl,c_to_s,s_to_c);
+ BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE);
+
+ c_r=0; s_r=1;
+ c_w=1; s_w=0;
+ c_write=1,s_write=0;
+
+ /* We can always do writes */
+ for (;;)
+ {
+ do_server=0;
+ do_client=0;
+
+ i=(int)BIO_pending(s_bio);
+ if ((i && s_r) || s_w) do_server=1;
+
+ i=(int)BIO_pending(c_bio);
+ if ((i && c_r) || c_w) do_client=1;
+
+ if (do_server && debug)
+ {
+ if (SSL_in_init(s_ssl))
+ printf("server waiting in SSL_accept - %s\n",
+ SSL_state_string_long(s_ssl));
+/* else if (s_write)
+ printf("server:SSL_write()\n");
+ else
+ printf("server:SSL_read()\n"); */
+ }
+
+ if (do_client && debug)
+ {
+ if (SSL_in_init(c_ssl))
+ printf("client waiting in SSL_connect - %s\n",
+ SSL_state_string_long(c_ssl));
+/* else if (c_write)
+ printf("client:SSL_write()\n");
+ else
+ printf("client:SSL_read()\n"); */
+ }
+
+ if (!do_client && !do_server)
+ {
+ fprintf(stdout,"ERROR IN STARTUP\n");
+ ERR_print_errors(bio_err);
+ break;
+ }
+ if (do_client && !(done & C_DONE))
+ {
+ if (c_write)
+ {
+ j = (cw_num > (long)sizeof(cbuf)) ?
+ (int)sizeof(cbuf) : (int)cw_num;
+ i=BIO_write(c_bio,cbuf,j);
+ if (i < 0)
+ {
+ c_r=0;
+ c_w=0;
+ if (BIO_should_retry(c_bio))
+ {
+ if (BIO_should_read(c_bio))
+ c_r=1;
+ if (BIO_should_write(c_bio))
+ c_w=1;
+ }
+ else
+ {
+ fprintf(stderr,"ERROR in CLIENT\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ }
+ else if (i == 0)
+ {
+ fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
+ goto err;
+ }
+ else
+ {
+ if (debug)
+ printf("client wrote %d\n",i);
+ /* ok */
+ s_r=1;
+ c_write=0;
+ cw_num-=i;
+ }
+ }
+ else
+ {
+ i=BIO_read(c_bio,cbuf,sizeof(cbuf));
+ if (i < 0)
+ {
+ c_r=0;
+ c_w=0;
+ if (BIO_should_retry(c_bio))
+ {
+ if (BIO_should_read(c_bio))
+ c_r=1;
+ if (BIO_should_write(c_bio))
+ c_w=1;
+ }
+ else
+ {
+ fprintf(stderr,"ERROR in CLIENT\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ }
+ else if (i == 0)
+ {
+ fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
+ goto err;
+ }
+ else
+ {
+ if (debug)
+ printf("client read %d\n",i);
+ cr_num-=i;
+ if (sw_num > 0)
+ {
+ s_write=1;
+ s_w=1;
+ }
+ if (cr_num <= 0)
+ {
+ s_write=1;
+ s_w=1;
+ done=S_DONE|C_DONE;
+ }
+ }
+ }
+ }
+
+ if (do_server && !(done & S_DONE))
+ {
+ if (!s_write)
+ {
+ i=BIO_read(s_bio,sbuf,sizeof(cbuf));
+ if (i < 0)
+ {
+ s_r=0;
+ s_w=0;
+ if (BIO_should_retry(s_bio))
+ {
+ if (BIO_should_read(s_bio))
+ s_r=1;
+ if (BIO_should_write(s_bio))
+ s_w=1;
+ }
+ else
+ {
+ fprintf(stderr,"ERROR in SERVER\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ }
+ else if (i == 0)
+ {
+ ERR_print_errors(bio_err);
+ fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_read\n");
+ goto err;
+ }
+ else
+ {
+ if (debug)
+ printf("server read %d\n",i);
+ sr_num-=i;
+ if (cw_num > 0)
+ {
+ c_write=1;
+ c_w=1;
+ }
+ if (sr_num <= 0)
+ {
+ s_write=1;
+ s_w=1;
+ c_write=0;
+ }
+ }
+ }
+ else
+ {
+ j = (sw_num > (long)sizeof(sbuf)) ?
+ (int)sizeof(sbuf) : (int)sw_num;
+ i=BIO_write(s_bio,sbuf,j);
+ if (i < 0)
+ {
+ s_r=0;
+ s_w=0;
+ if (BIO_should_retry(s_bio))
+ {
+ if (BIO_should_read(s_bio))
+ s_r=1;
+ if (BIO_should_write(s_bio))
+ s_w=1;
+ }
+ else
+ {
+ fprintf(stderr,"ERROR in SERVER\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ }
+ else if (i == 0)
+ {
+ ERR_print_errors(bio_err);
+ fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_write\n");
+ goto err;
+ }
+ else
+ {
+ if (debug)
+ printf("server wrote %d\n",i);
+ sw_num-=i;
+ s_write=0;
+ c_r=1;
+ if (sw_num <= 0)
+ done|=S_DONE;
+ }
+ }
+ }
+
+ if ((done & S_DONE) && (done & C_DONE)) break;
+ }
+
+ if (verbose)
+ print_details(c_ssl, "DONE: ");
+ ret=0;
+err:
+ /* We have to set the BIO's to NULL otherwise they will be
+ * OPENSSL_free()ed twice. Once when th s_ssl is SSL_free()ed and
+ * again when c_ssl is SSL_free()ed.
+ * This is a hack required because s_ssl and c_ssl are sharing the same
+ * BIO structure and SSL_set_bio() and SSL_free() automatically
+ * BIO_free non NULL entries.
+ * You should not normally do this or be required to do this */
+ if (s_ssl != NULL)
+ {
+ s_ssl->rbio=NULL;
+ s_ssl->wbio=NULL;
+ }
+ if (c_ssl != NULL)
+ {
+ c_ssl->rbio=NULL;
+ c_ssl->wbio=NULL;
+ }
+
+ if (c_to_s != NULL) BIO_free(c_to_s);
+ if (s_to_c != NULL) BIO_free(s_to_c);
+ if (c_bio != NULL) BIO_free_all(c_bio);
+ if (s_bio != NULL) BIO_free_all(s_bio);
+ return(ret);
+ }
+
+static int get_proxy_auth_ex_data_idx(void)
+ {
+ static volatile int idx = -1;
+ if (idx < 0)
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+ if (idx < 0)
+ {
+ idx = X509_STORE_CTX_get_ex_new_index(0,
+ "SSLtest for verify callback", NULL,NULL,NULL);
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+ }
+ return idx;
+ }
+
+static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
+ {
+ char *s,buf[256];
+
+ s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf,
+ sizeof buf);
+ if (s != NULL)
+ {
+ if (ok)
+ fprintf(stderr,"depth=%d %s\n",
+ ctx->error_depth,buf);
+ else
+ {
+ fprintf(stderr,"depth=%d error=%d %s\n",
+ ctx->error_depth,ctx->error,buf);
+ }
+ }
+
+ if (ok == 0)
+ {
+ fprintf(stderr,"Error string: %s\n",
+ X509_verify_cert_error_string(ctx->error));
+ switch (ctx->error)
+ {
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ fprintf(stderr," ... ignored.\n");
+ ok=1;
+ }
+ }
+
+ if (ok == 1)
+ {
+ X509 *xs = ctx->current_cert;
+#if 0
+ X509 *xi = ctx->current_issuer;
+#endif
+
+ if (xs->ex_flags & EXFLAG_PROXY)
+ {
+ unsigned int *letters =
+ X509_STORE_CTX_get_ex_data(ctx,
+ get_proxy_auth_ex_data_idx());
+
+ if (letters)
+ {
+ int found_any = 0;
+ int i;
+ PROXY_CERT_INFO_EXTENSION *pci =
+ X509_get_ext_d2i(xs, NID_proxyCertInfo,
+ NULL, NULL);
+
+ switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
+ {
+ case NID_Independent:
+ /* Completely meaningless in this
+ program, as there's no way to
+ grant explicit rights to a
+ specific PrC. Basically, using
+ id-ppl-Independent is the perfect
+ way to grant no rights at all. */
+ fprintf(stderr, " Independent proxy certificate");
+ for (i = 0; i < 26; i++)
+ letters[i] = 0;
+ break;
+ case NID_id_ppl_inheritAll:
+ /* This is basically a NOP, we
+ simply let the current rights
+ stand as they are. */
+ fprintf(stderr, " Proxy certificate inherits all");
+ break;
+ default:
+ s = (char *)
+ pci->proxyPolicy->policy->data;
+ i = pci->proxyPolicy->policy->length;
+
+ /* The algorithm works as follows:
+ it is assumed that previous
+ iterations or the initial granted
+ rights has already set some elements
+ of `letters'. What we need to do is
+ to clear those that weren't granted
+ by the current PrC as well. The
+ easiest way to do this is to add 1
+ to all the elements whose letters
+ are given with the current policy.
+ That way, all elements that are set
+ by the current policy and were
+ already set by earlier policies and
+ through the original grant of rights
+ will get the value 2 or higher.
+ The last thing to do is to sweep
+ through `letters' and keep the
+ elements having the value 2 as set,
+ and clear all the others. */
+
+ fprintf(stderr, " Certificate proxy rights = %*.*s", i, i, s);
+ while(i-- > 0)
+ {
+ int c = *s++;
+ if (isascii(c) && isalpha(c))
+ {
+ if (islower(c))
+ c = toupper(c);
+ letters[c - 'A']++;
+ }
+ }
+ for (i = 0; i < 26; i++)
+ if (letters[i] < 2)
+ letters[i] = 0;
+ else
+ letters[i] = 1;
+ }
+
+ found_any = 0;
+ fprintf(stderr,
+ ", resulting proxy rights = ");
+ for(i = 0; i < 26; i++)
+ if (letters[i])
+ {
+ fprintf(stderr, "%c", i + 'A');
+ found_any = 1;
+ }
+ if (!found_any)
+ fprintf(stderr, "none");
+ fprintf(stderr, "\n");
+
+ PROXY_CERT_INFO_EXTENSION_free(pci);
+ }
+ }
+ }
+
+ return(ok);
+ }
+
+static void process_proxy_debug(int indent, const char *format, ...)
+ {
+ static const char indentation[] =
+ ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
+ ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
+ char my_format[256];
+ va_list args;
+
+ BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
+ indent, indent, indentation, format);
+
+ va_start(args, format);
+ vfprintf(stderr, my_format, args);
+ va_end(args);
+ }
+/* Priority levels:
+ 0 [!]var, ()
+ 1 & ^
+ 2 |
+*/
+static int process_proxy_cond_adders(unsigned int letters[26],
+ const char *cond, const char **cond_end, int *pos, int indent);
+static int process_proxy_cond_val(unsigned int letters[26],
+ const char *cond, const char **cond_end, int *pos, int indent)
+ {
+ int c;
+ int ok = 1;
+ int negate = 0;
+
+ while(isspace((int)*cond))
+ {
+ cond++; (*pos)++;
+ }
+ c = *cond;
+
+ if (debug)
+ process_proxy_debug(indent,
+ "Start process_proxy_cond_val at position %d: %s\n",
+ *pos, cond);
+
+ while(c == '!')
+ {
+ negate = !negate;
+ cond++; (*pos)++;
+ while(isspace((int)*cond))
+ {
+ cond++; (*pos)++;
+ }
+ c = *cond;
+ }
+
+ if (c == '(')
+ {
+ cond++; (*pos)++;
+ ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
+ indent + 1);
+ cond = *cond_end;
+ if (ok < 0)
+ goto end;
+ while(isspace((int)*cond))
+ {
+ cond++; (*pos)++;
+ }
+ c = *cond;
+ if (c != ')')
+ {
+ fprintf(stderr,
+ "Weird condition character in position %d: "
+ "%c\n", *pos, c);
+ ok = -1;
+ goto end;
+ }
+ cond++; (*pos)++;
+ }
+ else if (isascii(c) && isalpha(c))
+ {
+ if (islower(c))
+ c = toupper(c);
+ ok = letters[c - 'A'];
+ cond++; (*pos)++;
+ }
+ else
+ {
+ fprintf(stderr,
+ "Weird condition character in position %d: "
+ "%c\n", *pos, c);
+ ok = -1;
+ goto end;
+ }
+ end:
+ *cond_end = cond;
+ if (ok >= 0 && negate)
+ ok = !ok;
+
+ if (debug)
+ process_proxy_debug(indent,
+ "End process_proxy_cond_val at position %d: %s, returning %d\n",
+ *pos, cond, ok);
+
+ return ok;
+ }
+static int process_proxy_cond_multipliers(unsigned int letters[26],
+ const char *cond, const char **cond_end, int *pos, int indent)
+ {
+ int ok;
+ char c;
+
+ if (debug)
+ process_proxy_debug(indent,
+ "Start process_proxy_cond_multipliers at position %d: %s\n",
+ *pos, cond);
+
+ ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
+ cond = *cond_end;
+ if (ok < 0)
+ goto end;
+
+ while(ok >= 0)
+ {
+ while(isspace((int)*cond))
+ {
+ cond++; (*pos)++;
+ }
+ c = *cond;
+
+ switch(c)
+ {
+ case '&':
+ case '^':
+ {
+ int save_ok = ok;
+
+ cond++; (*pos)++;
+ ok = process_proxy_cond_val(letters,
+ cond, cond_end, pos, indent + 1);
+ cond = *cond_end;
+ if (ok < 0)
+ break;
+
+ switch(c)
+ {
+ case '&':
+ ok &= save_ok;
+ break;
+ case '^':
+ ok ^= save_ok;
+ break;
+ default:
+ fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
+ " STOPPING\n");
+ EXIT(1);
+ }
+ }
+ break;
+ default:
+ goto end;
+ }
+ }
+ end:
+ if (debug)
+ process_proxy_debug(indent,
+ "End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
+ *pos, cond, ok);
+
+ *cond_end = cond;
+ return ok;
+ }
+static int process_proxy_cond_adders(unsigned int letters[26],
+ const char *cond, const char **cond_end, int *pos, int indent)
+ {
+ int ok;
+ char c;
+
+ if (debug)
+ process_proxy_debug(indent,
+ "Start process_proxy_cond_adders at position %d: %s\n",
+ *pos, cond);
+
+ ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
+ indent + 1);
+ cond = *cond_end;
+ if (ok < 0)
+ goto end;
+
+ while(ok >= 0)
+ {
+ while(isspace((int)*cond))
+ {
+ cond++; (*pos)++;
+ }
+ c = *cond;
+
+ switch(c)
+ {
+ case '|':
+ {
+ int save_ok = ok;
+
+ cond++; (*pos)++;
+ ok = process_proxy_cond_multipliers(letters,
+ cond, cond_end, pos, indent + 1);
+ cond = *cond_end;
+ if (ok < 0)
+ break;
+
+ switch(c)
+ {
+ case '|':
+ ok |= save_ok;
+ break;
+ default:
+ fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
+ " STOPPING\n");
+ EXIT(1);
+ }
+ }
+ break;
+ default:
+ goto end;
+ }
+ }
+ end:
+ if (debug)
+ process_proxy_debug(indent,
+ "End process_proxy_cond_adders at position %d: %s, returning %d\n",
+ *pos, cond, ok);
+
+ *cond_end = cond;
+ return ok;
+ }
+
+static int process_proxy_cond(unsigned int letters[26],
+ const char *cond, const char **cond_end)
+ {
+ int pos = 1;
+ return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
+ }
+
+static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
+ {
+ int ok=1;
+ struct app_verify_arg *cb_arg = arg;
+ unsigned int letters[26]; /* only used with proxy_auth */
+
+ if (cb_arg->app_verify)
+ {
+ char *s = NULL,buf[256];
+
+ fprintf(stderr, "In app_verify_callback, allowing cert. ");
+ fprintf(stderr, "Arg is: %s\n", cb_arg->string);
+ fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
+ (void *)ctx, (void *)ctx->cert);
+ if (ctx->cert)
+ s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
+ if (s != NULL)
+ {
+ fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
+ }
+ return(1);
+ }
+ if (cb_arg->proxy_auth)
+ {
+ int found_any = 0, i;
+ char *sp;
+
+ for(i = 0; i < 26; i++)
+ letters[i] = 0;
+ for(sp = cb_arg->proxy_auth; *sp; sp++)
+ {
+ int c = *sp;
+ if (isascii(c) && isalpha(c))
+ {
+ if (islower(c))
+ c = toupper(c);
+ letters[c - 'A'] = 1;
+ }
+ }
+
+ fprintf(stderr,
+ " Initial proxy rights = ");
+ for(i = 0; i < 26; i++)
+ if (letters[i])
+ {
+ fprintf(stderr, "%c", i + 'A');
+ found_any = 1;
+ }
+ if (!found_any)
+ fprintf(stderr, "none");
+ fprintf(stderr, "\n");
+
+ X509_STORE_CTX_set_ex_data(ctx,
+ get_proxy_auth_ex_data_idx(),letters);
+ }
+ if (cb_arg->allow_proxy_certs)
+ {
+ X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
+ }
+
+#ifndef OPENSSL_NO_X509_VERIFY
+ ok = X509_verify_cert(ctx);
+#endif
+
+ if (cb_arg->proxy_auth)
+ {
+ if (ok > 0)
+ {
+ const char *cond_end = NULL;
+
+ ok = process_proxy_cond(letters,
+ cb_arg->proxy_cond, &cond_end);
+
+ if (ok < 0)
+ EXIT(3);
+ if (*cond_end)
+ {
+ fprintf(stderr, "Stopped processing condition before it's end.\n");
+ ok = 0;
+ }
+ if (!ok)
+ fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
+ cb_arg->proxy_cond);
+ else
+ fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
+ cb_arg->proxy_cond);
+ }
+ }
+ return(ok);
+ }
+
+#ifndef OPENSSL_NO_RSA
+static RSA *rsa_tmp=NULL;
+
+static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
+ {
+ BIGNUM *bn = NULL;
+ if (rsa_tmp == NULL)
+ {
+ bn = BN_new();
+ rsa_tmp = RSA_new();
+ if(!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4))
+ {
+ BIO_printf(bio_err, "Memory error...");
+ goto end;
+ }
+ BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
+ (void)BIO_flush(bio_err);
+ if(!RSA_generate_key_ex(rsa_tmp,keylength,bn,NULL))
+ {
+ BIO_printf(bio_err, "Error generating key.");
+ RSA_free(rsa_tmp);
+ rsa_tmp = NULL;
+ }
+end:
+ BIO_printf(bio_err,"\n");
+ (void)BIO_flush(bio_err);
+ }
+ if(bn) BN_free(bn);
+ return(rsa_tmp);
+ }
+
+static void free_tmp_rsa(void)
+ {
+ if (rsa_tmp != NULL)
+ {
+ RSA_free(rsa_tmp);
+ rsa_tmp = NULL;
+ }
+ }
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* These DH parameters have been generated as follows:
+ * $ openssl dhparam -C -noout 512
+ * $ openssl dhparam -C -noout 1024
+ * $ openssl dhparam -C -noout -dsaparam 1024
+ * (The third function has been renamed to avoid name conflicts.)
+ */
+static DH *get_dh512()
+ {
+ static unsigned char dh512_p[]={
+ 0xCB,0xC8,0xE1,0x86,0xD0,0x1F,0x94,0x17,0xA6,0x99,0xF0,0xC6,
+ 0x1F,0x0D,0xAC,0xB6,0x25,0x3E,0x06,0x39,0xCA,0x72,0x04,0xB0,
+ 0x6E,0xDA,0xC0,0x61,0xE6,0x7A,0x77,0x25,0xE8,0x3B,0xB9,0x5F,
+ 0x9A,0xB6,0xB5,0xFE,0x99,0x0B,0xA1,0x93,0x4E,0x35,0x33,0xB8,
+ 0xE1,0xF1,0x13,0x4F,0x59,0x1A,0xD2,0x57,0xC0,0x26,0x21,0x33,
+ 0x02,0xC5,0xAE,0x23,
+ };
+ static unsigned char dh512_g[]={
+ 0x02,
+ };
+ DH *dh;
+
+ if ((dh=DH_new()) == NULL) return(NULL);
+ dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
+ dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
+ if ((dh->p == NULL) || (dh->g == NULL))
+ { DH_free(dh); return(NULL); }
+ return(dh);
+ }
+
+static DH *get_dh1024()
+ {
+ static unsigned char dh1024_p[]={
+ 0xF8,0x81,0x89,0x7D,0x14,0x24,0xC5,0xD1,0xE6,0xF7,0xBF,0x3A,
+ 0xE4,0x90,0xF4,0xFC,0x73,0xFB,0x34,0xB5,0xFA,0x4C,0x56,0xA2,
+ 0xEA,0xA7,0xE9,0xC0,0xC0,0xCE,0x89,0xE1,0xFA,0x63,0x3F,0xB0,
+ 0x6B,0x32,0x66,0xF1,0xD1,0x7B,0xB0,0x00,0x8F,0xCA,0x87,0xC2,
+ 0xAE,0x98,0x89,0x26,0x17,0xC2,0x05,0xD2,0xEC,0x08,0xD0,0x8C,
+ 0xFF,0x17,0x52,0x8C,0xC5,0x07,0x93,0x03,0xB1,0xF6,0x2F,0xB8,
+ 0x1C,0x52,0x47,0x27,0x1B,0xDB,0xD1,0x8D,0x9D,0x69,0x1D,0x52,
+ 0x4B,0x32,0x81,0xAA,0x7F,0x00,0xC8,0xDC,0xE6,0xD9,0xCC,0xC1,
+ 0x11,0x2D,0x37,0x34,0x6C,0xEA,0x02,0x97,0x4B,0x0E,0xBB,0xB1,
+ 0x71,0x33,0x09,0x15,0xFD,0xDD,0x23,0x87,0x07,0x5E,0x89,0xAB,
+ 0x6B,0x7C,0x5F,0xEC,0xA6,0x24,0xDC,0x53,
+ };
+ static unsigned char dh1024_g[]={
+ 0x02,
+ };
+ DH *dh;
+
+ if ((dh=DH_new()) == NULL) return(NULL);
+ dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
+ dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
+ if ((dh->p == NULL) || (dh->g == NULL))
+ { DH_free(dh); return(NULL); }
+ return(dh);
+ }
+
+static DH *get_dh1024dsa()
+ {
+ static unsigned char dh1024_p[]={
+ 0xC8,0x00,0xF7,0x08,0x07,0x89,0x4D,0x90,0x53,0xF3,0xD5,0x00,
+ 0x21,0x1B,0xF7,0x31,0xA6,0xA2,0xDA,0x23,0x9A,0xC7,0x87,0x19,
+ 0x3B,0x47,0xB6,0x8C,0x04,0x6F,0xFF,0xC6,0x9B,0xB8,0x65,0xD2,
+ 0xC2,0x5F,0x31,0x83,0x4A,0xA7,0x5F,0x2F,0x88,0x38,0xB6,0x55,
+ 0xCF,0xD9,0x87,0x6D,0x6F,0x9F,0xDA,0xAC,0xA6,0x48,0xAF,0xFC,
+ 0x33,0x84,0x37,0x5B,0x82,0x4A,0x31,0x5D,0xE7,0xBD,0x52,0x97,
+ 0xA1,0x77,0xBF,0x10,0x9E,0x37,0xEA,0x64,0xFA,0xCA,0x28,0x8D,
+ 0x9D,0x3B,0xD2,0x6E,0x09,0x5C,0x68,0xC7,0x45,0x90,0xFD,0xBB,
+ 0x70,0xC9,0x3A,0xBB,0xDF,0xD4,0x21,0x0F,0xC4,0x6A,0x3C,0xF6,
+ 0x61,0xCF,0x3F,0xD6,0x13,0xF1,0x5F,0xBC,0xCF,0xBC,0x26,0x9E,
+ 0xBC,0x0B,0xBD,0xAB,0x5D,0xC9,0x54,0x39,
+ };
+ static unsigned char dh1024_g[]={
+ 0x3B,0x40,0x86,0xE7,0xF3,0x6C,0xDE,0x67,0x1C,0xCC,0x80,0x05,
+ 0x5A,0xDF,0xFE,0xBD,0x20,0x27,0x74,0x6C,0x24,0xC9,0x03,0xF3,
+ 0xE1,0x8D,0xC3,0x7D,0x98,0x27,0x40,0x08,0xB8,0x8C,0x6A,0xE9,
+ 0xBB,0x1A,0x3A,0xD6,0x86,0x83,0x5E,0x72,0x41,0xCE,0x85,0x3C,
+ 0xD2,0xB3,0xFC,0x13,0xCE,0x37,0x81,0x9E,0x4C,0x1C,0x7B,0x65,
+ 0xD3,0xE6,0xA6,0x00,0xF5,0x5A,0x95,0x43,0x5E,0x81,0xCF,0x60,
+ 0xA2,0x23,0xFC,0x36,0xA7,0x5D,0x7A,0x4C,0x06,0x91,0x6E,0xF6,
+ 0x57,0xEE,0x36,0xCB,0x06,0xEA,0xF5,0x3D,0x95,0x49,0xCB,0xA7,
+ 0xDD,0x81,0xDF,0x80,0x09,0x4A,0x97,0x4D,0xA8,0x22,0x72,0xA1,
+ 0x7F,0xC4,0x70,0x56,0x70,0xE8,0x20,0x10,0x18,0x8F,0x2E,0x60,
+ 0x07,0xE7,0x68,0x1A,0x82,0x5D,0x32,0xA2,
+ };
+ DH *dh;
+
+ if ((dh=DH_new()) == NULL) return(NULL);
+ dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
+ dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
+ if ((dh->p == NULL) || (dh->g == NULL))
+ { DH_free(dh); return(NULL); }
+ dh->length = 160;
+ return(dh);
+ }
+#endif
+
+#ifndef OPENSSL_NO_PSK
+/* convert the PSK key (psk_key) in ascii to binary (psk) */
+static int psk_key2bn(const char *pskkey, unsigned char *psk,
+ unsigned int max_psk_len)
+ {
+ int ret;
+ BIGNUM *bn = NULL;
+
+ ret = BN_hex2bn(&bn, pskkey);
+ if (!ret)
+ {
+ BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", pskkey);
+ if (bn)
+ BN_free(bn);
+ return 0;
+ }
+ if (BN_num_bytes(bn) > (int)max_psk_len)
+ {
+ BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
+ max_psk_len, BN_num_bytes(bn));
+ BN_free(bn);
+ return 0;
+ }
+ ret = BN_bn2bin(bn, psk);
+ BN_free(bn);
+ return ret;
+ }
+
+static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity,
+ unsigned int max_identity_len, unsigned char *psk,
+ unsigned int max_psk_len)
+ {
+ int ret;
+ unsigned int psk_len = 0;
+
+ ret = BIO_snprintf(identity, max_identity_len, "Client_identity");
+ if (ret < 0)
+ goto out_err;
+ if (debug)
+ fprintf(stderr, "client: created identity '%s' len=%d\n", identity, ret);
+ ret = psk_key2bn(psk_key, psk, max_psk_len);
+ if (ret < 0)
+ goto out_err;
+ psk_len = ret;
+out_err:
+ return psk_len;
+ }
+
+static unsigned int psk_server_callback(SSL *ssl, const char *identity,
+ unsigned char *psk, unsigned int max_psk_len)
+ {
+ unsigned int psk_len=0;
+
+ if (strcmp(identity, "Client_identity") != 0)
+ {
+ BIO_printf(bio_err, "server: PSK error: client identity not found\n");
+ return 0;
+ }
+ psk_len=psk_key2bn(psk_key, psk, max_psk_len);
+ return psk_len;
+ }
+#endif
+
+static int do_test_cipherlist(void)
+ {
+ int i = 0;
+ const SSL_METHOD *meth;
+ const SSL_CIPHER *ci, *tci = NULL;
+
+#ifndef OPENSSL_NO_SSL2
+ fprintf(stderr, "testing SSLv2 cipher list order: ");
+ meth = SSLv2_method();
+ while ((ci = meth->get_cipher(i++)) != NULL)
+ {
+ if (tci != NULL)
+ if (ci->id >= tci->id)
+ {
+ fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
+ return 0;
+ }
+ tci = ci;
+ }
+ fprintf(stderr, "ok\n");
+#endif
+#ifndef OPENSSL_NO_SSL3
+ fprintf(stderr, "testing SSLv3 cipher list order: ");
+ meth = SSLv3_method();
+ tci = NULL;
+ while ((ci = meth->get_cipher(i++)) != NULL)
+ {
+ if (tci != NULL)
+ if (ci->id >= tci->id)
+ {
+ fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
+ return 0;
+ }
+ tci = ci;
+ }
+ fprintf(stderr, "ok\n");
+#endif
+#ifndef OPENSSL_NO_TLS1
+ fprintf(stderr, "testing TLSv1 cipher list order: ");
+ meth = TLSv1_method();
+ tci = NULL;
+ while ((ci = meth->get_cipher(i++)) != NULL)
+ {
+ if (tci != NULL)
+ if (ci->id >= tci->id)
+ {
+ fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
+ return 0;
+ }
+ tci = ci;
+ }
+ fprintf(stderr, "ok\n");
+#endif
+
+ return 1;
+ }
diff --git a/deps/openssl/openssl/test/tcrl b/deps/openssl/openssl/test/tcrl
new file mode 100644
index 000000000..055269eab
--- /dev/null
+++ b/deps/openssl/openssl/test/tcrl
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl crl'
+
+if [ "$1"x != "x" ]; then
+ t=$1
+else
+ t=testcrl.pem
+fi
+
+echo testing crl conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in fff.p -inform p -outform t >f.t
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> d"
+#$cmd -in f.t -inform t -outform d >ff.d2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+#echo "d -> t"
+#$cmd -in f.d -inform d -outform t >ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#echo "t -> t"
+#$cmd -in f.t -inform t -outform t >ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in f.p -inform p -outform t >ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> p"
+#$cmd -in f.t -inform t -outform p >ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp fff.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+#cmp f.t ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp f.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/deps/openssl/openssl/test/tcrl.com b/deps/openssl/openssl/test/tcrl.com
new file mode 100644
index 000000000..dd96a2b6d
--- /dev/null
+++ b/deps/openssl/openssl/test/tcrl.com
@@ -0,0 +1,88 @@
+$! TCRL.COM -- Tests crl keys
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ cmd = "mcr ''exe_dir'openssl crl"
+$
+$ t = "testcrl.pem"
+$ if p1 .nes. "" then t = p1
+$
+$ write sys$output "testing CRL conversions"
+$ if f$search("fff.*") .nes "" then delete fff.*;*
+$ if f$search("ff.*") .nes "" then delete ff.*;*
+$ if f$search("f.*") .nes "" then delete f.*;*
+$ convert/fdl=sys$input: 't' fff.p
+RECORD
+ FORMAT STREAM_LF
+$
+$ write sys$output "p -> d"
+$ 'cmd' -in fff.p -inform p -outform d -out f.d
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "p -> t"
+$! 'cmd' -in fff.p -inform p -outform t -out f.t
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in fff.p -inform p -outform p -out f.p
+$ if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> d"
+$ 'cmd' -in f.d -inform d -outform d -out ff.d1
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "t -> d"
+$! 'cmd' -in f.t -inform t -outform d -out ff.d2
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> d"
+$ 'cmd' -in f.p -inform p -outform d -out ff.d3
+$ if $severity .ne. 1 then exit 3
+$
+$! write sys$output "d -> t"
+$! 'cmd' -in f.d -inform d -outform t -out ff.t1
+$! if $severity .ne. 1 then exit 3
+$! write sys$output "t -> t"
+$! 'cmd' -in f.t -inform t -outform t -out ff.t2
+$! if $severity .ne. 1 then exit 3
+$! write sys$output "p -> t"
+$! 'cmd' -in f.p -inform p -outform t -out ff.t3
+$! if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> p"
+$ 'cmd' -in f.d -inform d -outform p -out ff.p1
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "t -> p"
+$! 'cmd' -in f.t -inform t -outform p -out ff.p2
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in f.p -inform p -outform p -out ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ backup/compare fff.p f.p
+$ if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$! backup/compare fff.p ff.p2
+$! if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$! backup/compare f.t ff.t1
+$! if $severity .ne. 1 then exit 3
+$! backup/compare f.t ff.t2
+$! if $severity .ne. 1 then exit 3
+$! backup/compare f.t ff.t3
+$! if $severity .ne. 1 then exit 3
+$
+$ backup/compare f.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$! backup/compare f.p ff.p2
+$! if $severity .ne. 1 then exit 3
+$ backup/compare f.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ delete f.*;*,ff.*;*,fff.*;*
diff --git a/deps/openssl/openssl/test/test.cnf b/deps/openssl/openssl/test/test.cnf
new file mode 100644
index 000000000..10834442a
--- /dev/null
+++ b/deps/openssl/openssl/test/test.cnf
@@ -0,0 +1,88 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE = ./.rnd
+
+####################################################################
+[ ca ]
+default_ca = CA_default # The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir = ./demoCA # Where everything is kept
+certs = $dir/certs # Where the issued certs are kept
+crl_dir = $dir/crl # Where the issued crl are kept
+database = $dir/index.txt # database index file.
+new_certs_dir = $dir/new_certs # default place for new certs.
+
+certificate = $dir/CAcert.pem # The CA certificate
+serial = $dir/serial # The current serial number
+crl = $dir/crl.pem # The current CRL
+private_key = $dir/private/CAkey.pem# The private key
+RANDFILE = $dir/private/.rand # private random number file
+
+default_days = 365 # how long to certify for
+default_crl_days= 30 # how long before next CRL
+default_md = md5 # which md to use.
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy = policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName = match
+stateOrProvinceName = match
+organizationName = match
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+####################################################################
+[ req ]
+default_bits = 1024
+default_keyfile = testkey.pem
+distinguished_name = req_distinguished_name
+encrypt_rsa_key = no
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = AU
+countryName_value = AU
+
+stateOrProvinceName = State or Province Name (full name)
+stateOrProvinceName_default = Queensland
+stateOrProvinceName_value =
+
+localityName = Locality Name (eg, city)
+localityName_value = Brisbane
+
+organizationName = Organization Name (eg, company)
+organizationName_default =
+organizationName_value = CryptSoft Pty Ltd
+
+organizationalUnitName = Organizational Unit Name (eg, section)
+organizationalUnitName_default =
+organizationalUnitName_value = .
+
+commonName = Common Name (eg, YOUR name)
+commonName_value = Eric Young
+
+emailAddress = Email Address
+emailAddress_value = eay@mincom.oz.au
diff --git a/deps/openssl/openssl/test/test_padlock b/deps/openssl/openssl/test/test_padlock
new file mode 100755
index 000000000..5c0f21043
--- /dev/null
+++ b/deps/openssl/openssl/test/test_padlock
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+PROG=$1
+
+if [ -x $PROG ]; then
+ if expr "x`$PROG version`" : "xOpenSSL" > /dev/null; then
+ :
+ else
+ echo "$PROG is not OpenSSL executable"
+ exit 1
+ fi
+else
+ echo "$PROG is not executable"
+ exit 1;
+fi
+
+if $PROG engine padlock | grep -v no-ACE; then
+
+ HASH=`cat $PROG | $PROG dgst -hex`
+
+ ACE_ALGS=" aes-128-ecb aes-192-ecb aes-256-ecb \
+ aes-128-cbc aes-192-cbc aes-256-cbc \
+ aes-128-cfb aes-192-cfb aes-256-cfb \
+ aes-128-ofb aes-192-ofb aes-256-ofb"
+
+ nerr=0
+
+ for alg in $ACE_ALGS; do
+ echo $alg
+ TEST=`( cat $PROG | \
+ $PROG enc -e -k "$HASH" -$alg -bufsize 999 -engine padlock | \
+ $PROG enc -d -k "$HASH" -$alg | \
+ $PROG dgst -hex ) 2>/dev/null`
+ if [ "$TEST" != "$HASH" ]; then
+ echo "-$alg encrypt test failed"
+ nerr=`expr $nerr + 1`
+ fi
+ TEST=`( cat $PROG | \
+ $PROG enc -e -k "$HASH" -$alg | \
+ $PROG enc -d -k "$HASH" -$alg -bufsize 999 -engine padlock | \
+ $PROG dgst -hex ) 2>/dev/null`
+ if [ "$TEST" != "$HASH" ]; then
+ echo "-$alg decrypt test failed"
+ nerr=`expr $nerr + 1`
+ fi
+ TEST=`( cat $PROG | \
+ $PROG enc -e -k "$HASH" -$alg -engine padlock | \
+ $PROG enc -d -k "$HASH" -$alg -engine padlock | \
+ $PROG dgst -hex ) 2>/dev/null`
+ if [ "$TEST" != "$HASH" ]; then
+ echo "-$alg en/decrypt test failed"
+ nerr=`expr $nerr + 1`
+ fi
+ done
+
+ if [ $nerr -gt 0 ]; then
+ echo "PadLock ACE test failed."
+ exit 1;
+ fi
+else
+ echo "PadLock ACE is not available"
+fi
+
+exit 0
diff --git a/deps/openssl/openssl/test/testca b/deps/openssl/openssl/test/testca
new file mode 100644
index 000000000..b109cfe27
--- /dev/null
+++ b/deps/openssl/openssl/test/testca
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+SH="/bin/sh"
+if test "$OSTYPE" = msdosdjgpp; then
+ PATH="../apps\;$PATH"
+else
+ PATH="../apps:$PATH"
+fi
+export SH PATH
+
+SSLEAY_CONFIG="-config CAss.cnf"
+export SSLEAY_CONFIG
+
+OPENSSL="`pwd`/../util/opensslwrap.sh"
+export OPENSSL
+
+/bin/rm -fr demoCA
+$SH ../apps/CA.sh -newca <<EOF
+EOF
+
+if [ $? != 0 ]; then
+ exit 1;
+fi
+
+SSLEAY_CONFIG="-config Uss.cnf"
+export SSLEAY_CONFIG
+$SH ../apps/CA.sh -newreq
+if [ $? != 0 ]; then
+ exit 1;
+fi
+
+
+SSLEAY_CONFIG="-config ../apps/openssl.cnf"
+export SSLEAY_CONFIG
+$SH ../apps/CA.sh -sign <<EOF
+y
+y
+EOF
+if [ $? != 0 ]; then
+ exit 1;
+fi
+
+
+$SH ../apps/CA.sh -verify newcert.pem
+if [ $? != 0 ]; then
+ exit 1;
+fi
+
+/bin/rm -fr demoCA newcert.pem newreq.pem
+#usage: CA -newcert|-newreq|-newca|-sign|-verify
+
diff --git a/deps/openssl/openssl/test/testca.com b/deps/openssl/openssl/test/testca.com
new file mode 100644
index 000000000..78cda9ec5
--- /dev/null
+++ b/deps/openssl/openssl/test/testca.com
@@ -0,0 +1,52 @@
+$! TESTCA.COM
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p1 .eqs. "64") then __arch = __arch+ "_64"
+$
+$ openssl = "mcr ''exe_dir'openssl"
+$
+$ SSLEAY_CONFIG="-config ""CAss.cnf"""
+$
+$ set noon
+$ if f$search("demoCA.dir") .nes. ""
+$ then
+$ @[-.util]deltree [.demoCA]*.*
+$ set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) demoCA.dir;*
+$ delete demoCA.dir;*
+$ endif
+$ set on
+$ open/read sys$ca_input VMSca-response.1
+$ @[-.apps]CA.com -input sys$ca_input -newca
+$ close sys$ca_input
+$ if $severity .ne. 1 then exit 3
+$
+$
+$ SSLEAY_CONFIG="-config ""Uss.cnf"""
+$ @[-.apps]CA.com -newreq
+$ if $severity .ne. 1 then exit 3
+$
+$
+$ SSLEAY_CONFIG="-config [-.apps]openssl-vms.cnf"
+$ open/read sys$ca_input VMSca-response.2
+$ @[-.apps]CA.com -input sys$ca_input -sign
+$ close sys$ca_input
+$ if $severity .ne. 1 then exit 3
+$
+$
+$ @[-.apps]CA.com -verify newcert.pem
+$ if $severity .ne. 1 then exit 3
+$
+$ set noon
+$ @[-.util]deltree [.demoCA]*.*
+$ set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) demoCA.dir;*
+$ delete demoCA.dir;*
+$ if f$search("newcert.pem") .nes. "" then delete newcert.pem;*
+$ if f$search("newcert.pem") .nes. "" then delete newreq.pem;*
+$ set on
+$! #usage: CA -newcert|-newreq|-newca|-sign|-verify
+$
+$ exit
diff --git a/deps/openssl/openssl/test/testcrl.pem b/deps/openssl/openssl/test/testcrl.pem
new file mode 100644
index 000000000..098978835
--- /dev/null
+++ b/deps/openssl/openssl/test/testcrl.pem
@@ -0,0 +1,16 @@
+-----BEGIN X509 CRL-----
+MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT
+F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy
+IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw
+MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw
+MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw
+MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw
+MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw
+MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw
+MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw
+NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw
+NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF
+AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ
+wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt
+JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v
+-----END X509 CRL-----
diff --git a/deps/openssl/openssl/test/testenc b/deps/openssl/openssl/test/testenc
new file mode 100644
index 000000000..f5ce7c0c4
--- /dev/null
+++ b/deps/openssl/openssl/test/testenc
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+testsrc=Makefile
+test=./p
+cmd="../util/shlib_wrap.sh ../apps/openssl"
+
+cat $testsrc >$test;
+
+echo cat
+$cmd enc < $test > $test.cipher
+$cmd enc < $test.cipher >$test.clear
+cmp $test $test.clear
+if [ $? != 0 ]
+then
+ exit 1
+else
+ /bin/rm $test.cipher $test.clear
+fi
+echo base64
+$cmd enc -a -e < $test > $test.cipher
+$cmd enc -a -d < $test.cipher >$test.clear
+cmp $test $test.clear
+if [ $? != 0 ]
+then
+ exit 1
+else
+ /bin/rm $test.cipher $test.clear
+fi
+
+for i in `$cmd list-cipher-commands`
+do
+ echo $i
+ $cmd $i -bufsize 113 -e -k test < $test > $test.$i.cipher
+ $cmd $i -bufsize 157 -d -k test < $test.$i.cipher >$test.$i.clear
+ cmp $test $test.$i.clear
+ if [ $? != 0 ]
+ then
+ exit 1
+ else
+ /bin/rm $test.$i.cipher $test.$i.clear
+ fi
+
+ echo $i base64
+ $cmd $i -bufsize 113 -a -e -k test < $test > $test.$i.cipher
+ $cmd $i -bufsize 157 -a -d -k test < $test.$i.cipher >$test.$i.clear
+ cmp $test $test.$i.clear
+ if [ $? != 0 ]
+ then
+ exit 1
+ else
+ /bin/rm $test.$i.cipher $test.$i.clear
+ fi
+done
+rm -f $test
diff --git a/deps/openssl/openssl/test/testenc.com b/deps/openssl/openssl/test/testenc.com
new file mode 100644
index 000000000..75acd6f07
--- /dev/null
+++ b/deps/openssl/openssl/test/testenc.com
@@ -0,0 +1,66 @@
+$! TESTENC.COM -- Test encoding and decoding
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p1 .eqs. 64) then __arch = __arch+ "_64"
+$
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$ testsrc = "makefile."
+$ test = "p.txt"
+$ cmd = "mcr ''exe_dir'openssl"
+$
+$ if f$search(test) .nes. "" then delete 'test';*
+$ convert/fdl=sys$input: 'testsrc' 'test'
+RECORD
+ FORMAT STREAM_LF
+$
+$ if f$search(test+"-cipher") .nes. "" then delete 'test'-cipher;*
+$ if f$search(test+"-clear") .nes. "" then delete 'test'-clear;*
+$
+$ write sys$output "cat"
+$ 'cmd' enc -in 'test' -out 'test'-cipher
+$ 'cmd' enc -in 'test'-cipher -out 'test'-clear
+$ backup/compare 'test' 'test'-clear
+$ if $severity .ne. 1 then exit 3
+$ delete 'test'-cipher;*,'test'-clear;*
+$
+$ write sys$output "base64"
+$ 'cmd' enc -a -e -in 'test' -out 'test'-cipher
+$ 'cmd' enc -a -d -in 'test'-cipher -out 'test'-clear
+$ backup/compare 'test' 'test'-clear
+$ if $severity .ne. 1 then exit 3
+$ delete 'test'-cipher;*,'test'-clear;*
+$
+$ define/user sys$output 'test'-cipher-commands
+$ 'cmd' list-cipher-commands
+$ open/read f 'test'-cipher-commands
+$ loop_cipher_commands:
+$ read/end=loop_cipher_commands_end f i
+$ write sys$output i
+$
+$ if f$search(test+"-"+i+"-cipher") .nes. "" then -
+ delete 'test'-'i'-cipher;*
+$ if f$search(test+"-"+i+"-clear") .nes. "" then -
+ delete 'test'-'i'-clear;*
+$
+$ 'cmd' 'i' -bufsize 113 -e -k test -in 'test' -out 'test'-'i'-cipher
+$ 'cmd' 'i' -bufsize 157 -d -k test -in 'test'-'i'-cipher -out 'test'-'i'-clear
+$ backup/compare 'test' 'test'-'i'-clear
+$ if $severity .ne. 1 then exit 3
+$ delete 'test'-'i'-cipher;*,'test'-'i'-clear;*
+$
+$ write sys$output i," base64"
+$ 'cmd' 'i' -bufsize 113 -a -e -k test -in 'test' -out 'test'-'i'-cipher
+$ 'cmd' 'i' -bufsize 157 -a -d -k test -in 'test'-'i'-cipher -out 'test'-'i'-clear
+$ backup/compare 'test' 'test'-'i'-clear
+$ if $severity .ne. 1 then exit 3
+$ delete 'test'-'i'-cipher;*,'test'-'i'-clear;*
+$
+$ goto loop_cipher_commands
+$ loop_cipher_commands_end:
+$ close f
+$ delete 'test'-cipher-commands;*
+$ delete 'test';*
diff --git a/deps/openssl/openssl/test/testfipsssl b/deps/openssl/openssl/test/testfipsssl
new file mode 100644
index 000000000..c4836edc2
--- /dev/null
+++ b/deps/openssl/openssl/test/testfipsssl
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+if [ "$1" = "" ]; then
+ key=../apps/server.pem
+else
+ key="$1"
+fi
+if [ "$2" = "" ]; then
+ cert=../apps/server.pem
+else
+ cert="$2"
+fi
+
+ciphers="DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EXP1024-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA"
+
+ssltest="../util/shlib_wrap.sh ./ssltest -F -key $key -cert $cert -c_key $key -c_cert $cert -cipher $ciphers"
+
+if ../util/shlib_wrap.sh ../apps/openssl x509 -in $cert -text -noout | fgrep 'DSA Public Key' >/dev/null; then
+ dsa_cert=YES
+else
+ dsa_cert=NO
+fi
+
+if [ "$3" = "" ]; then
+ CA="-CApath ../certs"
+else
+ CA="-CAfile $3"
+fi
+
+if [ "$4" = "" ]; then
+ extra=""
+else
+ extra="$4"
+fi
+
+#############################################################################
+
+echo test ssl3 is forbidden in FIPS mode
+$ssltest -ssl3 $extra && exit 1
+
+echo test ssl2 is forbidden in FIPS mode
+$ssltest -ssl2 $extra && exit 1
+
+echo test tls1
+$ssltest -tls1 $extra || exit 1
+
+echo test tls1 with server authentication
+$ssltest -tls1 -server_auth $CA $extra || exit 1
+
+echo test tls1 with client authentication
+$ssltest -tls1 -client_auth $CA $extra || exit 1
+
+echo test tls1 with both client and server authentication
+$ssltest -tls1 -server_auth -client_auth $CA $extra || exit 1
+
+echo test tls1 via BIO pair
+$ssltest -bio_pair -tls1 $extra || exit 1
+
+echo test tls1 with server authentication via BIO pair
+$ssltest -bio_pair -tls1 -server_auth $CA $extra || exit 1
+
+echo test tls1 with client authentication via BIO pair
+$ssltest -bio_pair -tls1 -client_auth $CA $extra || exit 1
+
+echo test tls1 with both client and server authentication via BIO pair
+$ssltest -bio_pair -tls1 -server_auth -client_auth $CA $extra || exit 1
+
+# note that all the below actually choose TLS...
+
+if [ $dsa_cert = NO ]; then
+ echo test sslv2/sslv3 w/o DHE via BIO pair
+ $ssltest -bio_pair -no_dhe $extra || exit 1
+fi
+
+echo test sslv2/sslv3 with 1024bit DHE via BIO pair
+$ssltest -bio_pair -dhe1024dsa -v $extra || exit 1
+
+echo test sslv2/sslv3 with server authentication
+$ssltest -bio_pair -server_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with client authentication via BIO pair
+$ssltest -bio_pair -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication via BIO pair
+$ssltest -bio_pair -server_auth -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication via BIO pair and app verify
+$ssltest -bio_pair -server_auth -client_auth -app_verify $CA $extra || exit 1
+
+#############################################################################
+
+if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
+ echo skipping anonymous DH tests
+else
+ echo test tls1 with 1024bit anonymous DH, multiple handshakes
+ $ssltest -v -bio_pair -tls1 -cipher ADH -dhe1024dsa -num 10 -f -time $extra || exit 1
+fi
+
+if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
+ echo skipping RSA tests
+else
+ echo test tls1 with 1024bit RSA, no DHE, multiple handshakes
+ ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -no_dhe -num 10 -f -time $extra || exit 1
+
+ if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
+ echo skipping RSA+DHE tests
+ else
+ echo test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes
+ ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -dhe1024dsa -num 10 -f -time $extra || exit 1
+ fi
+fi
+
+exit 0
diff --git a/deps/openssl/openssl/test/testgen b/deps/openssl/openssl/test/testgen
new file mode 100644
index 000000000..524c0d134
--- /dev/null
+++ b/deps/openssl/openssl/test/testgen
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+T=testcert
+KEY=512
+CA=../certs/testca.pem
+
+/bin/rm -f $T.1 $T.2 $T.key
+
+if test "$OSTYPE" = msdosdjgpp; then
+ PATH=../apps\;$PATH;
+else
+ PATH=../apps:$PATH;
+fi
+export PATH
+
+echo "generating certificate request"
+
+echo "string to make the random number generator think it has entropy" >> ./.rnd
+
+if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
+ req_new='-newkey dsa:../apps/dsa512.pem'
+else
+ req_new='-new'
+ echo "There should be a 2 sequences of .'s and some +'s."
+ echo "There should not be more that at most 80 per line"
+fi
+
+echo "This could take some time."
+
+rm -f testkey.pem testreq.pem
+
+../util/shlib_wrap.sh ../apps/openssl req -config test.cnf $req_new -out testreq.pem
+if [ $? != 0 ]; then
+echo problems creating request
+exit 1
+fi
+
+../util/shlib_wrap.sh ../apps/openssl req -config test.cnf -verify -in testreq.pem -noout
+if [ $? != 0 ]; then
+echo signature on req is wrong
+exit 1
+fi
+
+exit 0
diff --git a/deps/openssl/openssl/test/testgen.com b/deps/openssl/openssl/test/testgen.com
new file mode 100644
index 000000000..e076da2f3
--- /dev/null
+++ b/deps/openssl/openssl/test/testgen.com
@@ -0,0 +1,58 @@
+$! TESTGEN.COM
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$ if (p1 .eqs. 64) then __arch = __arch+ "_64"
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ T = "testcert"
+$ KEY = 512
+$ CA = "[-.certs]testca.pem"
+$
+$ set noon
+$ if f$search(T+".1;*") .nes. "" then delete 'T'.1;*
+$ if f$search(T+".2;*") .nes. "" then delete 'T'.2;*
+$ if f$search(T+".key;*") .nes. "" then delete 'T'.key;*
+$ set on
+$
+$ write sys$output "generating certificate request"
+$
+$ append/new nl: .rnd
+$ open/append random_file .rnd
+$ write random_file -
+ "string to make the random number generator think it has entropy"
+$ close random_file
+$
+$ set noon
+$ define/user sys$output nla0:
+$ mcr 'exe_dir'openssl no-rsa
+$ save_severity=$SEVERITY
+$ set on
+$ if save_severity
+$ then
+$ req_new="-newkey dsa:[-.apps]dsa512.pem"
+$ else
+$ req_new="-new"
+$ write sys$output -
+ "There should be a 2 sequences of .'s and some +'s."
+$ write sys$output -
+ "There should not be more that at most 80 per line"
+$ endif
+$
+$ write sys$output "This could take some time."
+$
+$ mcr 'exe_dir'openssl req -config test.cnf 'req_new' -out testreq.pem
+$ if $severity .ne. 1
+$ then
+$ write sys$output "problems creating request"
+$ exit 3
+$ endif
+$
+$ mcr 'exe_dir'openssl req -config test.cnf -verify -in testreq.pem -noout
+$ if $severity .ne. 1
+$ then
+$ write sys$output "signature on req is wrong"
+$ exit 3
+$ endif
diff --git a/deps/openssl/openssl/test/testp7.pem b/deps/openssl/openssl/test/testp7.pem
new file mode 100644
index 000000000..e5b7866c3
--- /dev/null
+++ b/deps/openssl/openssl/test/testp7.pem
@@ -0,0 +1,46 @@
+-----BEGIN PKCS7-----
+MIIIGAYJKoZIhvcNAQcCoIIICTCCCAUCAQExADALBgkqhkiG9w0BBwGgggY8MIIE
+cjCCBBygAwIBAgIQeS+OJfWJUZAx6cX0eAiMjzANBgkqhkiG9w0BAQQFADBiMREw
+DwYDVQQHEwhJbnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNV
+BAsTK1ZlcmlTaWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXIw
+HhcNOTYwNzE5MDAwMDAwWhcNOTcwMzMwMjM1OTU5WjCB1TERMA8GA1UEBxMISW50
+ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJpU2ln
+biBDbGFzcyAxIENBIC0gSW5kaXZpZHVhbCBTdWJzY3JpYmVyMSgwJgYDVQQLEx9E
+aWdpdGFsIElEIENsYXNzIDEgLSBTTUlNRSBUZXN0MUcwRQYDVQQLEz53d3cudmVy
+aXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTLTEuMCBJbmMuIGJ5IFJlZi4sTElBQi5M
+VEQoYyk5NjBbMA0GCSqGSIb3DQEBAQUAA0oAMEcCQA7LvHEIAiQ5+4gDYvJGnGAq
+UM5GXyG11diEXmIEZTHUZhorooX5sr8IIjSXiPY59YYUFSvAaharFM1xaBN8zNEC
+AwEAAaOCAjkwggI1MAkGA1UdEwQCMAAwggImBgNVHQMEggIdMIICGTCCAhUwggIR
+BgtghkgBhvhFAQcBATCCAgAWggGrVGhpcyBjZXJ0aWZpY2F0ZSBpbmNvcnBvcmF0
+ZXMgYnkgcmVmZXJlbmNlLCBhbmQgaXRzIHVzZSBpcyBzdHJpY3RseSBzdWJqZWN0
+IHRvLCB0aGUgVmVyaVNpZ24gQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1l
+bnQgKENQUyksIGF2YWlsYWJsZSBhdDogaHR0cHM6Ly93d3cudmVyaXNpZ24uY29t
+L0NQUy0xLjA7IGJ5IEUtbWFpbCBhdCBDUFMtcmVxdWVzdHNAdmVyaXNpZ24uY29t
+OyBvciBieSBtYWlsIGF0IFZlcmlTaWduLCBJbmMuLCAyNTkzIENvYXN0IEF2ZS4s
+IE1vdW50YWluIFZpZXcsIENBIDk0MDQzIFVTQSBUZWwuICsxICg0MTUpIDk2MS04
+ODMwIENvcHlyaWdodCAoYykgMTk5NiBWZXJpU2lnbiwgSW5jLiAgQWxsIFJpZ2h0
+cyBSZXNlcnZlZC4gQ0VSVEFJTiBXQVJSQU5USUVTIERJU0NMQUlNRUQgYW5kIExJ
+QUJJTElUWSBMSU1JVEVELqAOBgxghkgBhvhFAQcBAQGhDgYMYIZIAYb4RQEHAQEC
+MC8wLRYraHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTLTEu
+AzANBgkqhkiG9w0BAQQFAANBAMCYDuSb/eIlYSxY31nZZTaCZkCSfHjlacMofExr
+cF+A2yHoEuT+eCQkqM0pMNHXddUeoQ9RjV+VuMBNmm63DUYwggHCMIIBbKADAgEC
+AhB8CYTq1bkRFJBYOd67cp9JMA0GCSqGSIb3DQEBAgUAMD4xCzAJBgNVBAYTAlVT
+MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEWMBQGA1UECxMNVEVTVCBSb290IFBD
+QTAeFw05NjA3MTcwMDAwMDBaFw05NzA3MTcyMzU5NTlaMGIxETAPBgNVBAcTCElu
+dGVybmV0MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNp
+Z24gQ2xhc3MgMSBDQSAtIEluZGl2aWR1YWwgU3Vic2NyaWJlcjBcMA0GCSqGSIb3
+DQEBAQUAA0sAMEgCQQDsVzrNgnDhbAJZrWeLd9g1vMZJA2W67D33TTbga6yMt+ES
+TWEywhS6RNP+fzLGg7utinjH4tL60cXa0G27GDsLAgMBAAGjIjAgMAsGA1UdDwQE
+AwIBBjARBglghkgBhvhCAQEEBAMCAgQwDQYJKoZIhvcNAQECBQADQQAUp6bRwkaD
+2d1MBs/mjUcgTI2fXVmW8tTm/Ud6OzUwpC3vYgybiOOA4f6mOC5dbyUHrLOsrihU
+47ZQ0Jo1DUfboYIBrTCBwTBtMA0GCSqGSIb3DQEBAgUAMD4xCzAJBgNVBAYTAlVT
+MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEWMBQGA1UECxMNVEVTVCBSb290IFBD
+QRcNOTYwNzE3MTc0NDA5WhcNOTgwNzE3MDAwMDAwWjANBgkqhkiG9w0BAQIFAANB
+AHitA0/xAukCjHzeh1AMT/l2oC68N+yFb+aJPHBBMxc6gG2MaKjBNwb5hcXUllMl
+ExONA3ju10f7owIq3s3wx10wgeYwgZEwDQYJKoZIhvcNAQECBQAwYjERMA8GA1UE
+BxMISW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytW
+ZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5kaXZpZHVhbCBTdWJzY3JpYmVyFw05NjA3
+MTcxNzU5MjlaFw05NzA3MTgwMDAwMDBaMA0GCSqGSIb3DQEBAgUAA0EAubVWYTsW
+sQmste9f+UgMw8BkjDlM25fwQLrCfmmnLxjewey10kSROypUaJLb+r4oRALc0fG9
+XfZsaiiIgotQHjEA
+-----END PKCS7-----
diff --git a/deps/openssl/openssl/test/testreq2.pem b/deps/openssl/openssl/test/testreq2.pem
new file mode 100644
index 000000000..c3cdcffcb
--- /dev/null
+++ b/deps/openssl/openssl/test/testreq2.pem
@@ -0,0 +1,7 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIHaMIGFAgEAMA4xDDAKBgNVBAMTA2NuNDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC
+QQCQsnkyUGDY2R3mYoeTprFJKgWuJ3f1jUjlIuW5+wfAUoeMt35c4vcFZ2mIBpEG
+DtzkNQN1kr2O9ldm9zYnYhyhAgMBAAGgEjAQBgorBgEEAYI3AgEOMQIwADANBgkq
+hkiG9w0BAQQFAANBAAb2szZgVIxg3vK6kYLjGSBISyuzcXJ6IvuPW6M+yzi1Qgoi
+gQhazHTJp91T8ItZEzUJGZSZl2e5iXlnffWB+/U=
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/openssl/openssl/test/testrsa.pem b/deps/openssl/openssl/test/testrsa.pem
new file mode 100644
index 000000000..aad21067a
--- /dev/null
+++ b/deps/openssl/openssl/test/testrsa.pem
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAKrbeqkuRk8VcRmWFmtP+LviMB3+6dizWW3DwaffznyHGAFwUJ/I
+Tv0XtbsCyl3QoyKGhrOAy3RvPK5M38iuXT0CAwEAAQJAZ3cnzaHXM/bxGaR5CR1R
+rD1qFBAVfoQFiOH9uPJgMaoAuoQEisPHVcZDKcOv4wEg6/TInAIXBnEigtqvRzuy
+oQIhAPcgZzUq3yVooAaoov8UbXPxqHlwo6GBMqnv20xzkf6ZAiEAsP4BnIaQTM8S
+mvcpHZwQJdmdHHkGKAs37Dfxi67HbkUCIQCeZGliHXFa071Fp06ZeWlR2ADonTZz
+rJBhdTe0v5pCeQIhAIZfkiGgGBX4cIuuckzEm43g9WMUjxP/0GlK39vIyihxAiEA
+mymehFRT0MvqW5xAKAx7Pgkt8HVKwVhc2LwGKHE0DZM=
+-----END RSA PRIVATE KEY-----
diff --git a/deps/openssl/openssl/test/tests.com b/deps/openssl/openssl/test/tests.com
new file mode 100644
index 000000000..a840d5078
--- /dev/null
+++ b/deps/openssl/openssl/test/tests.com
@@ -0,0 +1,375 @@
+$! TESTS.COM -- Performs the necessary tests
+$!
+$! P1 tests to be performed. Empty means all.
+$! P2 Pointer size: "", "32", or "64".
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+ f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ __proc = f$element(0,";",f$environment("procedure"))
+$ __here = f$parse(f$parse("A.;",__proc) - "A.;","[]A.;") - "A.;"
+$ __save_default = f$environment("default")
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ __archd = __arch
+$ pointer_size = ""
+$ if (p2 .eq. "64")
+$ then
+$ pointer_size = "64"
+$ __archd = __arch+ "_64"
+$ endif
+$!
+$ texe_dir := sys$disk:[-.'__archd'.exe.test]
+$ exe_dir := sys$disk:[-.'__archd'.exe.apps]
+$
+$ set default '__here'
+$
+$ ROOT = F$PARSE("sys$disk:[-]A.;0",,,,"SYNTAX_ONLY,NO_CONCEAL") - "A.;0"
+$ ROOT_DEV = F$PARSE(ROOT,,,"DEVICE","SYNTAX_ONLY")
+$ ROOT_DIR = F$PARSE(ROOT,,,"DIRECTORY","SYNTAX_ONLY") -
+ - ".][000000" - "[000000." - "][" - "[" - "]"
+$ ROOT = ROOT_DEV + "[" + ROOT_DIR
+$ DEFINE/NOLOG SSLROOT 'ROOT'.APPS.] /TRANS=CONC
+$ openssl_conf := sslroot:[000000]openssl-vms.cnf
+$
+$ on control_y then goto exit
+$ on error then goto exit
+$
+$ if p1 .nes. ""
+$ then
+$ tests = p1
+$ else
+$! NOTE: This list reflects the list of dependencies following the
+$! "alltests" target in Makefile. This should make it easy to see
+$! if there's a difference that needs to be taken care of.
+$ tests := -
+ test_des,test_idea,test_sha,test_md4,test_md5,test_hmac,-
+ test_md2,test_mdc2,test_wp,-
+ test_rmd,test_rc2,test_rc4,test_rc5,test_bf,test_cast,test_aes,-
+ test_rand,test_bn,test_ec,test_ecdsa,test_ecdh,-
+ test_enc,test_x509,test_rsa,test_crl,test_sid,-
+ test_gen,test_req,test_pkcs7,test_verify,test_dh,test_dsa,-
+ test_ss,test_ca,test_engine,test_evp,test_ssl,test_tsa,test_ige,-
+ test_jpake,test_srp,test_cms
+$ endif
+$ tests = f$edit(tests,"COLLAPSE")
+$
+$ BNTEST := bntest
+$ ECTEST := ectest
+$ ECDSATEST := ecdsatest
+$ ECDHTEST := ecdhtest
+$ EXPTEST := exptest
+$ IDEATEST := ideatest
+$ SHATEST := shatest
+$ SHA1TEST := sha1test
+$ SHA256TEST := sha256t
+$ SHA512TEST := sha512t
+$ MDC2TEST := mdc2test
+$ RMDTEST := rmdtest
+$ MD2TEST := md2test
+$ MD4TEST := md4test
+$ MD5TEST := md5test
+$ HMACTEST := hmactest
+$ WPTEST := wp_test
+$ RC2TEST := rc2test
+$ RC4TEST := rc4test
+$ RC5TEST := rc5test
+$ BFTEST := bftest
+$ CASTTEST := casttest
+$ DESTEST := destest
+$ RANDTEST := randtest
+$ DHTEST := dhtest
+$ DSATEST := dsatest
+$ METHTEST := methtest
+$ SSLTEST := ssltest
+$ RSATEST := rsa_test
+$ ENGINETEST := enginetest
+$ EVPTEST := evp_test
+$ IGETEST := igetest
+$ JPAKETEST := jpaketest
+$ SRPTEST := srptest
+$ ASN1TEST := asn1test
+$!
+$ tests_i = 0
+$ loop_tests:
+$ tests_e = f$element(tests_i,",",tests)
+$ tests_i = tests_i + 1
+$ if tests_e .eqs. "," then goto exit
+$ write sys$output "---> ''tests_e'"
+$ gosub 'tests_e'
+$ goto loop_tests
+$
+$ test_evp:
+$ mcr 'texe_dir''evptest' 'ROOT'.CRYPTO.EVP]evptests.txt
+$ return
+$ test_des:
+$ mcr 'texe_dir''destest'
+$ return
+$ test_idea:
+$ mcr 'texe_dir''ideatest'
+$ return
+$ test_sha:
+$ mcr 'texe_dir''shatest'
+$ mcr 'texe_dir''sha1test'
+$ mcr 'texe_dir''sha256test'
+$ mcr 'texe_dir''sha512test'
+$ return
+$ test_mdc2:
+$ mcr 'texe_dir''mdc2test'
+$ return
+$ test_md5:
+$ mcr 'texe_dir''md5test'
+$ return
+$ test_md4:
+$ mcr 'texe_dir''md4test'
+$ return
+$ test_hmac:
+$ mcr 'texe_dir''hmactest'
+$ return
+$ test_wp:
+$ mcr 'texe_dir''wptest'
+$ return
+$ test_md2:
+$ mcr 'texe_dir''md2test'
+$ return
+$ test_rmd:
+$ mcr 'texe_dir''rmdtest'
+$ return
+$ test_bf:
+$ mcr 'texe_dir''bftest'
+$ return
+$ test_cast:
+$ mcr 'texe_dir''casttest'
+$ return
+$ test_rc2:
+$ mcr 'texe_dir''rc2test'
+$ return
+$ test_rc4:
+$ mcr 'texe_dir''rc4test'
+$ return
+$ test_rc5:
+$ mcr 'texe_dir''rc5test'
+$ return
+$ test_rand:
+$ mcr 'texe_dir''randtest'
+$ return
+$ test_enc:
+$ @testenc.com 'pointer_size'
+$ return
+$ test_x509:
+$ set noon
+$ define sys$error test_x509.err
+$ write sys$output "test normal x509v1 certificate"
+$ @tx509.com "" 'pointer_size'
+$ write sys$output "test first x509v3 certificate"
+$ @tx509.com v3-cert1.pem 'pointer_size'
+$ write sys$output "test second x509v3 certificate"
+$ @tx509.com v3-cert2.pem 'pointer_size'
+$ deassign sys$error
+$ set on
+$ return
+$ test_rsa:
+$ set noon
+$ define sys$error test_rsa.err
+$ @trsa.com "" 'pointer_size'
+$ deassign sys$error
+$ mcr 'texe_dir''rsatest'
+$ set on
+$ return
+$ test_crl:
+$ set noon
+$ define sys$error test_crl.err
+$ @tcrl.com "" 'pointer_size'
+$ deassign sys$error
+$ set on
+$ return
+$ test_sid:
+$ set noon
+$ define sys$error test_sid.err
+$ @tsid.com "" 'pointer_size'
+$ deassign sys$error
+$ set on
+$ return
+$ test_req:
+$ set noon
+$ define sys$error test_req.err
+$ @treq.com "" 'pointer_size'
+$ @treq.com testreq2.pem 'pointer_size'
+$ deassign sys$error
+$ set on
+$ return
+$ test_pkcs7:
+$ set noon
+$ define sys$error test_pkcs7.err
+$ @tpkcs7.com "" 'pointer_size'
+$ @tpkcs7d.com "" 'pointer_size'
+$ deassign sys$error
+$ set on
+$ return
+$ test_bn:
+$ write sys$output -
+ "starting big number library test, could take a while..."
+$ set noon
+$ define sys$error test_bn.err
+$ define sys$output test_bn.out
+$ @ bctest.com
+$ status = $status
+$ deassign sys$error
+$ deassign sys$output
+$ set on
+$ if (status)
+$ then
+$ create /fdl = sys$input bntest-vms.tmp
+FILE
+ ORGANIZATION sequential
+RECORD
+ FORMAT stream_lf
+$ define /user_mode sys$output bntest-vms.tmp
+$ mcr 'texe_dir''bntest'
+$ define /user_mode sys$input bntest-vms.tmp
+$ define /user_mode sys$output bntest-vms.out
+$ bc
+$ @ bntest.com bntest-vms.out
+$ status = $status
+$ if (status)
+$ then
+$ delete bntest-vms.out;*
+$ delete bntest-vms.tmp;*
+$ endif
+$ else
+$ create /fdl = sys$input bntest-vms.sh
+FILE
+ ORGANIZATION sequential
+RECORD
+ FORMAT stream_lf
+$ open /append bntest_file bntest-vms.sh
+$ type /output = bntest_file sys$input:
+<< __FOO__ sh -c "`sh ./bctest`" | perl -e '$i=0; while (<STDIN>) {if (/^test (.*)/) {print STDERR "\nverify $1";} elsif (!/^0$/) {die "\nFailed! bc: $_";} else {print STDERR "."; $i++;}} print STDERR "\n$i tests passed\n"'
+$ define /user_mode sys$output bntest-vms.tmp
+$ mcr 'texe_dir''bntest'
+$ copy bntest-vms.tmp bntest_file
+$ delete bntest-vms.tmp;*
+$ type /output = bntest_file sys$input:
+__FOO__
+$ close bntest_file
+$ write sys$output "-- copy the [.test]bntest-vms.sh and [.test]bctest files to a Unix system and"
+$ write sys$output "-- run bntest-vms.sh through sh or bash to verify that the bignum operations"
+$ write sys$output "-- went well."
+$ write sys$output ""
+$ endif
+$ write sys$output "test a^b%c implementations"
+$ mcr 'texe_dir''exptest'
+$ return
+$ test_ec:
+$ write sys$output "test elliptic curves"
+$ mcr 'texe_dir''ectest'
+$ return
+$ test_ecdsa:
+$ write sys$output "test ecdsa"
+$ mcr 'texe_dir''ecdsatest'
+$ return
+$ test_ecdh:
+$ write sys$output "test ecdh"
+$ mcr 'texe_dir''ecdhtest'
+$ return
+$ test_verify:
+$ write sys$output "The following command should have some OK's and some failures"
+$ write sys$output "There are definitly a few expired certificates"
+$ @tverify.com 'pointer_size'
+$ return
+$ test_dh:
+$ write sys$output "Generate a set of DH parameters"
+$ mcr 'texe_dir''dhtest'
+$ return
+$ test_dsa:
+$ write sys$output "Generate a set of DSA parameters"
+$ mcr 'texe_dir''dsatest'
+$ return
+$ test_gen:
+$ write sys$output "Generate and verify a certificate request"
+$ @testgen.com 'pointer_size'
+$ return
+$ maybe_test_ss:
+$ testss_RDT = f$cvtime(f$file_attributes("testss.com","RDT"))
+$ if f$cvtime(f$file_attributes("keyU.ss","RDT")) .les. testss_RDT then -
+ goto test_ss
+$ if f$cvtime(f$file_attributes("certU.ss","RDT")) .les. testss_RDT then -
+ goto test_ss
+$ if f$cvtime(f$file_attributes("certCA.ss","RDT")) .les. testss_RDT then -
+ goto test_ss
+$ return
+$ test_ss:
+$ write sys$output "Generate and certify a test certificate"
+$ @testss.com 'pointer_size'
+$ return
+$ test_engine:
+$ write sys$output "Manipulate the ENGINE structures"
+$ mcr 'texe_dir''enginetest'
+$ return
+$ test_ssl:
+$ write sys$output "test SSL protocol"
+$ gosub maybe_test_ss
+$ @testssl.com keyU.ss certU.ss certCA.ss 'pointer_size'
+$ return
+$ test_ca:
+$ set noon
+$ define /user_mode sys$output test_ca.out
+$ mcr 'exe_dir'openssl no-rsa
+$ save_severity=$SEVERITY
+$ set on
+$ if save_severity
+$ then
+$ write sys$output "skipping CA.com test -- requires RSA"
+$ else
+$ write sys$output "Generate and certify a test certificate via the 'ca' program"
+$ @testca.com 'pointer_size'
+$ endif
+$ return
+$ test_aes:
+$! write sys$output "test AES"
+$! !mcr 'texe_dir''aestest'
+$ return
+$ test_tsa:
+$ set noon
+$ define /user_mode sys$output nla0:
+$ mcr 'exe_dir'openssl no-rsa
+$ save_severity=$SEVERITY
+$ set on
+$ if save_severity
+$ then
+$ write sys$output "skipping testtsa.com test -- requires RSA"
+$ else
+$ @testtsa.com "" "" "" 'pointer_size'
+$ endif
+$ return
+$ test_ige:
+$ write sys$output "Test IGE mode"
+$ mcr 'texe_dir''igetest'
+$ return
+$ test_jpake:
+$ write sys$output "Test JPAKE"
+$ mcr 'texe_dir''jpaketest'
+$ return
+$ test_cms:
+$ write sys$output "CMS consistency test"
+$ ! Define the logical name used to find openssl.exe in the perl script.
+$ define /user_mode osslx 'exe_dir'
+$ perl CMS-TEST.PL
+$ return
+$ test_srp:
+$ write sys$output "Test SRP"
+$ mcr 'texe_dir''srptest'
+$ return
+$
+$
+$ exit:
+$ mcr 'exe_dir'openssl version -a
+$ set default '__save_default'
+$ deassign sslroot
+$ exit
diff --git a/deps/openssl/openssl/test/testsid.pem b/deps/openssl/openssl/test/testsid.pem
new file mode 100644
index 000000000..7ffd008f6
--- /dev/null
+++ b/deps/openssl/openssl/test/testsid.pem
@@ -0,0 +1,12 @@
+-----BEGIN SSL SESSION PARAMETERS-----
+MIIB1gIBAQIBAgQDAQCABBCi11xa5qkOP8xrr02K/NQCBBBkIYQZM0Bt95W0EHNV
+bA58oQYCBDIBr7WiBAICASyjggGGMIIBgjCCASwCAQMwDQYJKoZIhvcNAQEEBQAw
+ODELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3Jz
+YSB0ZXN0IENBMB4XDTk1MTAwOTIzMzEzNFoXDTk4MDcwNTIzMzEzNFowYDELMAkG
+A1UEBhMCQVUxDDAKBgNVBAgTA1FMRDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRk
+LjELMAkGA1UECxMCQ1MxGzAZBgNVBAMTElNTTGVheSBkZW1vIGNsaWVudDBcMA0G
+CSqGSIb3DQEBAQUAA0sAMEgCQQC4pcXEL1lgVA+B5Q3TcuW/O3LZHoA73IYm8oFD
+TezgCDhL2RTMn+seKWF36UtJKRIOBU9jZHCVVd0Me5ls6BEjAgMBAAEwDQYJKoZI
+hvcNAQEEBQADQQBoIpOcwUY1qlVF7j3ROSGvUsbvByOBFmYWkIBgsCqR+9qo1A7L
+CrWF5i8LWt/vLwAHaxWNx2YuBJMFyuK81fTvpA0EC3Rlc3Rjb250ZXh0
+-----END SSL SESSION PARAMETERS-----
diff --git a/deps/openssl/openssl/test/testss b/deps/openssl/openssl/test/testss
new file mode 100644
index 000000000..1a426857d
--- /dev/null
+++ b/deps/openssl/openssl/test/testss
@@ -0,0 +1,163 @@
+#!/bin/sh
+
+digest='-sha1'
+reqcmd="../util/shlib_wrap.sh ../apps/openssl req"
+x509cmd="../util/shlib_wrap.sh ../apps/openssl x509 $digest"
+verifycmd="../util/shlib_wrap.sh ../apps/openssl verify"
+dummycnf="../apps/openssl.cnf"
+
+CAkey="keyCA.ss"
+CAcert="certCA.ss"
+CAreq="reqCA.ss"
+CAconf="CAss.cnf"
+CAreq2="req2CA.ss" # temp
+
+Uconf="Uss.cnf"
+Ukey="keyU.ss"
+Ureq="reqU.ss"
+Ucert="certU.ss"
+
+P1conf="P1ss.cnf"
+P1key="keyP1.ss"
+P1req="reqP1.ss"
+P1cert="certP1.ss"
+P1intermediate="tmp_intP1.ss"
+
+P2conf="P2ss.cnf"
+P2key="keyP2.ss"
+P2req="reqP2.ss"
+P2cert="certP2.ss"
+P2intermediate="tmp_intP2.ss"
+
+echo
+echo "make a certificate request using 'req'"
+
+echo "string to make the random number generator think it has entropy" >> ./.rnd
+
+if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
+ req_new='-newkey dsa:../apps/dsa512.pem'
+else
+ req_new='-new'
+fi
+
+$reqcmd -config $CAconf -out $CAreq -keyout $CAkey $req_new #>err.ss
+if [ $? != 0 ]; then
+ echo "error using 'req' to generate a certificate request"
+ exit 1
+fi
+echo
+echo "convert the certificate request into a self signed certificate using 'x509'"
+$x509cmd -CAcreateserial -in $CAreq -days 30 -req -out $CAcert -signkey $CAkey -extfile $CAconf -extensions v3_ca >err.ss
+if [ $? != 0 ]; then
+ echo "error using 'x509' to self sign a certificate request"
+ exit 1
+fi
+
+echo
+echo "convert a certificate into a certificate request using 'x509'"
+$x509cmd -in $CAcert -x509toreq -signkey $CAkey -out $CAreq2 >err.ss
+if [ $? != 0 ]; then
+ echo "error using 'x509' convert a certificate to a certificate request"
+ exit 1
+fi
+
+$reqcmd -config $dummycnf -verify -in $CAreq -noout
+if [ $? != 0 ]; then
+ echo first generated request is invalid
+ exit 1
+fi
+
+$reqcmd -config $dummycnf -verify -in $CAreq2 -noout
+if [ $? != 0 ]; then
+ echo second generated request is invalid
+ exit 1
+fi
+
+$verifycmd -CAfile $CAcert $CAcert
+if [ $? != 0 ]; then
+ echo first generated cert is invalid
+ exit 1
+fi
+
+echo
+echo "make a user certificate request using 'req'"
+$reqcmd -config $Uconf -out $Ureq -keyout $Ukey $req_new >err.ss
+if [ $? != 0 ]; then
+ echo "error using 'req' to generate a user certificate request"
+ exit 1
+fi
+
+echo
+echo "sign user certificate request with the just created CA via 'x509'"
+$x509cmd -CAcreateserial -in $Ureq -days 30 -req -out $Ucert -CA $CAcert -CAkey $CAkey -extfile $Uconf -extensions v3_ee >err.ss
+if [ $? != 0 ]; then
+ echo "error using 'x509' to sign a user certificate request"
+ exit 1
+fi
+
+$verifycmd -CAfile $CAcert $Ucert
+echo
+echo "Certificate details"
+$x509cmd -subject -issuer -startdate -enddate -noout -in $Ucert
+
+echo
+echo "make a proxy certificate request using 'req'"
+$reqcmd -config $P1conf -out $P1req -keyout $P1key $req_new >err.ss
+if [ $? != 0 ]; then
+ echo "error using 'req' to generate a proxy certificate request"
+ exit 1
+fi
+
+echo
+echo "sign proxy certificate request with the just created user certificate via 'x509'"
+$x509cmd -CAcreateserial -in $P1req -days 30 -req -out $P1cert -CA $Ucert -CAkey $Ukey -extfile $P1conf -extensions v3_proxy >err.ss
+if [ $? != 0 ]; then
+ echo "error using 'x509' to sign a proxy certificate request"
+ exit 1
+fi
+
+cat $Ucert > $P1intermediate
+$verifycmd -CAfile $CAcert -untrusted $P1intermediate $P1cert
+echo
+echo "Certificate details"
+$x509cmd -subject -issuer -startdate -enddate -noout -in $P1cert
+
+echo
+echo "make another proxy certificate request using 'req'"
+$reqcmd -config $P2conf -out $P2req -keyout $P2key $req_new >err.ss
+if [ $? != 0 ]; then
+ echo "error using 'req' to generate another proxy certificate request"
+ exit 1
+fi
+
+echo
+echo "sign second proxy certificate request with the first proxy certificate via 'x509'"
+$x509cmd -CAcreateserial -in $P2req -days 30 -req -out $P2cert -CA $P1cert -CAkey $P1key -extfile $P2conf -extensions v3_proxy >err.ss
+if [ $? != 0 ]; then
+ echo "error using 'x509' to sign a second proxy certificate request"
+ exit 1
+fi
+
+cat $Ucert $P1cert > $P2intermediate
+$verifycmd -CAfile $CAcert -untrusted $P2intermediate $P2cert
+echo
+echo "Certificate details"
+$x509cmd -subject -issuer -startdate -enddate -noout -in $P2cert
+
+echo
+echo The generated CA certificate is $CAcert
+echo The generated CA private key is $CAkey
+
+echo The generated user certificate is $Ucert
+echo The generated user private key is $Ukey
+
+echo The first generated proxy certificate is $P1cert
+echo The first generated proxy private key is $P1key
+
+echo The second generated proxy certificate is $P2cert
+echo The second generated proxy private key is $P2key
+
+/bin/rm err.ss
+#/bin/rm $P1intermediate
+#/bin/rm $P2intermediate
+exit 0
diff --git a/deps/openssl/openssl/test/testss.com b/deps/openssl/openssl/test/testss.com
new file mode 100644
index 000000000..32a74d0fc
--- /dev/null
+++ b/deps/openssl/openssl/test/testss.com
@@ -0,0 +1,123 @@
+$! TESTSS.COM
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p1 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ digest="-md5"
+$ reqcmd = "mcr ''exe_dir'openssl req"
+$ x509cmd = "mcr ''exe_dir'openssl x509 ''digest'"
+$ verifycmd = "mcr ''exe_dir'openssl verify"
+$ dummycnf = "sys$disk:[-.apps]openssl-vms.cnf"
+$
+$ CAkey="""keyCA.ss"""
+$ CAcert="""certCA.ss"""
+$ CAreq="""reqCA.ss"""
+$ CAconf="""CAss.cnf"""
+$ CAreq2="""req2CA.ss""" ! temp
+$
+$ Uconf="""Uss.cnf"""
+$ Ukey="""keyU.ss"""
+$ Ureq="""reqU.ss"""
+$ Ucert="""certU.ss"""
+$
+$ write sys$output ""
+$ write sys$output "make a certificate request using 'req'"
+$
+$ set noon
+$ define/user sys$output nla0:
+$ mcr 'exe_dir'openssl no-rsa
+$ save_severity=$SEVERITY
+$ set on
+$ if save_severity
+$ then
+$ req_new="-newkey dsa:[-.apps]dsa512.pem"
+$ else
+$ req_new="-new"
+$ endif
+$
+$ 'reqcmd' -config 'CAconf' -out 'CAreq' -keyout 'CAkey' 'req_new' ! -out err.ss
+$ if $severity .ne. 1
+$ then
+$ write sys$output "error using 'req' to generate a certificate request"
+$ exit 3
+$ endif
+$ write sys$output ""
+$ write sys$output "convert the certificate request into a self signed certificate using 'x509'"
+$ define /user sys$output err.ss
+$ 'x509cmd' "-CAcreateserial" -in 'CAreq' -days 30 -req -out 'CAcert' -signkey 'CAkey'
+$ if $severity .ne. 1
+$ then
+$ write sys$output "error using 'x509' to self sign a certificate request"
+$ exit 3
+$ endif
+$
+$ write sys$output ""
+$ write sys$output "convert a certificate into a certificate request using 'x509'"
+$ define /user sys$output err.ss
+$ 'x509cmd' -in 'CAcert' -x509toreq -signkey 'CAkey' -out 'CAreq2'
+$ if $severity .ne. 1
+$ then
+$ write sys$output "error using 'x509' convert a certificate to a certificate request"
+$ exit 3
+$ endif
+$
+$ 'reqcmd' -config 'dummycnf' -verify -in 'CAreq' -noout
+$ if $severity .ne. 1
+$ then
+$ write sys$output "first generated request is invalid"
+$ exit 3
+$ endif
+$
+$ 'reqcmd' -config 'dummycnf' -verify -in 'CAreq2' -noout
+$ if $severity .ne. 1
+$ then
+$ write sys$output "second generated request is invalid"
+$ exit 3
+$ endif
+$
+$ 'verifycmd' "-CAfile" 'CAcert' 'CAcert'
+$ if $severity .ne. 1
+$ then
+$ write sys$output "first generated cert is invalid"
+$ exit 3
+$ endif
+$
+$ write sys$output ""
+$ write sys$output "make another certificate request using 'req'"
+$ define /user sys$output err.ss
+$ 'reqcmd' -config 'Uconf' -out 'Ureq' -keyout 'Ukey' 'req_new'
+$ if $severity .ne. 1
+$ then
+$ write sys$output "error using 'req' to generate a certificate request"
+$ exit 3
+$ endif
+$
+$ write sys$output ""
+$ write sys$output "sign certificate request with the just created CA via 'x509'"
+$ define /user sys$output err.ss
+$ 'x509cmd' "-CAcreateserial" -in 'Ureq' -days 30 -req -out 'Ucert' "-CA" 'CAcert' "-CAkey" 'CAkey'
+$ if $severity .ne. 1
+$ then
+$ write sys$output "error using 'x509' to sign a certificate request"
+$ exit 3
+$ endif
+$
+$ 'verifycmd' "-CAfile" 'CAcert' 'Ucert'
+$ write sys$output ""
+$ write sys$output "Certificate details"
+$ 'x509cmd' -subject -issuer -startdate -enddate -noout -in 'Ucert'
+$
+$ write sys$output ""
+$ write sys$output "The generated CA certificate is ",CAcert
+$ write sys$output "The generated CA private key is ",CAkey
+$
+$ write sys$output "The generated user certificate is ",Ucert
+$ write sys$output "The generated user private key is ",Ukey
+$
+$ if f$search("err.ss;*") .nes. "" then delete err.ss;*
diff --git a/deps/openssl/openssl/test/testssl b/deps/openssl/openssl/test/testssl
new file mode 100644
index 000000000..4e8542b55
--- /dev/null
+++ b/deps/openssl/openssl/test/testssl
@@ -0,0 +1,178 @@
+#!/bin/sh
+
+if [ "$1" = "" ]; then
+ key=../apps/server.pem
+else
+ key="$1"
+fi
+if [ "$2" = "" ]; then
+ cert=../apps/server.pem
+else
+ cert="$2"
+fi
+ssltest="../util/shlib_wrap.sh ./ssltest -key $key -cert $cert -c_key $key -c_cert $cert"
+
+if ../util/shlib_wrap.sh ../apps/openssl x509 -in $cert -text -noout | fgrep 'DSA Public Key' >/dev/null; then
+ dsa_cert=YES
+else
+ dsa_cert=NO
+fi
+
+if [ "$3" = "" ]; then
+ CA="-CApath ../certs"
+else
+ CA="-CAfile $3"
+fi
+
+if [ "$4" = "" ]; then
+ extra=""
+else
+ extra="$4"
+fi
+
+#############################################################################
+
+echo test sslv2
+$ssltest -ssl2 $extra || exit 1
+
+echo test sslv2 with server authentication
+$ssltest -ssl2 -server_auth $CA $extra || exit 1
+
+if [ $dsa_cert = NO ]; then
+ echo test sslv2 with client authentication
+ $ssltest -ssl2 -client_auth $CA $extra || exit 1
+
+ echo test sslv2 with both client and server authentication
+ $ssltest -ssl2 -server_auth -client_auth $CA $extra || exit 1
+fi
+
+echo test sslv3
+$ssltest -ssl3 $extra || exit 1
+
+echo test sslv3 with server authentication
+$ssltest -ssl3 -server_auth $CA $extra || exit 1
+
+echo test sslv3 with client authentication
+$ssltest -ssl3 -client_auth $CA $extra || exit 1
+
+echo test sslv3 with both client and server authentication
+$ssltest -ssl3 -server_auth -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3
+$ssltest $extra || exit 1
+
+echo test sslv2/sslv3 with server authentication
+$ssltest -server_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with client authentication
+$ssltest -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication
+$ssltest -server_auth -client_auth $CA $extra || exit 1
+
+echo test sslv2 via BIO pair
+$ssltest -bio_pair -ssl2 $extra || exit 1
+
+echo test sslv2 with server authentication via BIO pair
+$ssltest -bio_pair -ssl2 -server_auth $CA $extra || exit 1
+
+if [ $dsa_cert = NO ]; then
+ echo test sslv2 with client authentication via BIO pair
+ $ssltest -bio_pair -ssl2 -client_auth $CA $extra || exit 1
+
+ echo test sslv2 with both client and server authentication via BIO pair
+ $ssltest -bio_pair -ssl2 -server_auth -client_auth $CA $extra || exit 1
+fi
+
+echo test sslv3 via BIO pair
+$ssltest -bio_pair -ssl3 $extra || exit 1
+
+echo test sslv3 with server authentication via BIO pair
+$ssltest -bio_pair -ssl3 -server_auth $CA $extra || exit 1
+
+echo test sslv3 with client authentication via BIO pair
+$ssltest -bio_pair -ssl3 -client_auth $CA $extra || exit 1
+
+echo test sslv3 with both client and server authentication via BIO pair
+$ssltest -bio_pair -ssl3 -server_auth -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 via BIO pair
+$ssltest $extra || exit 1
+
+if [ $dsa_cert = NO ]; then
+ echo 'test sslv2/sslv3 w/o (EC)DHE via BIO pair'
+ $ssltest -bio_pair -no_dhe -no_ecdhe $extra || exit 1
+fi
+
+echo test sslv2/sslv3 with 1024bit DHE via BIO pair
+$ssltest -bio_pair -dhe1024dsa -v $extra || exit 1
+
+echo test sslv2/sslv3 with server authentication
+$ssltest -bio_pair -server_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with client authentication via BIO pair
+$ssltest -bio_pair -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication via BIO pair
+$ssltest -bio_pair -server_auth -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication via BIO pair and app verify
+$ssltest -bio_pair -server_auth -client_auth -app_verify $CA $extra || exit 1
+
+echo "Testing ciphersuites"
+for protocol in TLSv1.2 SSLv3; do
+ echo "Testing ciphersuites for $protocol"
+ for cipher in `../util/shlib_wrap.sh ../apps/openssl ciphers "RSA+$protocol" | tr ':' ' '`; do
+ echo "Testing $cipher"
+ prot=""
+ if [ $protocol = "SSLv3" ] ; then
+ prot="-ssl3"
+ fi
+ $ssltest -cipher $cipher $prot
+ if [ $? -ne 0 ] ; then
+ echo "Failed $cipher"
+ exit 1
+ fi
+ done
+done
+
+#############################################################################
+
+if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
+ echo skipping anonymous DH tests
+else
+ echo test tls1 with 1024bit anonymous DH, multiple handshakes
+ $ssltest -v -bio_pair -tls1 -cipher ADH -dhe1024dsa -num 10 -f -time $extra || exit 1
+fi
+
+if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
+ echo skipping RSA tests
+else
+ echo 'test tls1 with 1024bit RSA, no (EC)DHE, multiple handshakes'
+ ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -no_dhe -no_ecdhe -num 10 -f -time $extra || exit 1
+
+ if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
+ echo skipping RSA+DHE tests
+ else
+ echo test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes
+ ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -dhe1024dsa -num 10 -f -time $extra || exit 1
+ fi
+fi
+
+echo test tls1 with PSK
+$ssltest -tls1 -cipher PSK -psk abc123 $extra || exit 1
+
+echo test tls1 with PSK via BIO pair
+$ssltest -bio_pair -tls1 -cipher PSK -psk abc123 $extra || exit 1
+
+if ../util/shlib_wrap.sh ../apps/openssl no-srp; then
+ echo skipping SRP tests
+else
+ echo test tls1 with SRP
+ $ssltest -tls1 -cipher SRP -srpuser test -srppass abc123
+
+ echo test tls1 with SRP via BIO pair
+ $ssltest -bio_pair -tls1 -cipher SRP -srpuser test -srppass abc123
+fi
+
+exit 0
diff --git a/deps/openssl/openssl/test/testssl.com b/deps/openssl/openssl/test/testssl.com
new file mode 100644
index 000000000..f19edc471
--- /dev/null
+++ b/deps/openssl/openssl/test/testssl.com
@@ -0,0 +1,208 @@
+$! TESTSSL.COM
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p4 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ texe_dir = "sys$disk:[-.''__arch'.exe.test]"
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ if p1 .eqs. ""
+$ then
+$ key="[-.apps]server.pem"
+$ else
+$ key=p1
+$ endif
+$ if p2 .eqs. ""
+$ then
+$ cert="[-.apps]server.pem"
+$ else
+$ cert=p2
+$ endif
+$ ssltest = "mcr ''texe_dir'ssltest -key ''key'"+ -
+ " -cert ''cert' -c_key ''key' -c_cert ''cert'"
+$!
+$ set noon
+$ define/user sys$output testssl-x509-output.
+$ define/user sys$error nla0:
+$ mcr 'exe_dir'openssl x509 -in 'cert' -text -noout
+$ define/user sys$error nla0:
+$ search/output=nla0: testssl-x509-output. "DSA Public Key"/exact
+$ if $severity .eq. 1
+$ then
+$ dsa_cert = "YES"
+$ else
+$ dsa_cert = "NO"
+$ endif
+$ delete testssl-x509-output.;*
+$
+$ if p3 .eqs. ""
+$ then
+$ copy/concatenate [-.certs]*.pem certs.tmp
+$ CA = """-CAfile"" certs.tmp"
+$ else
+$ CA = """-CAfile"" "+p3
+$ endif
+$
+$!###########################################################################
+$
+$ write sys$output "test sslv2"
+$ 'ssltest' -ssl2
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2 with server authentication"
+$ 'ssltest' -ssl2 -server_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ if .not. dsa_cert
+$ then
+$ write sys$output "test sslv2 with client authentication"
+$ 'ssltest' -ssl2 -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2 with both client and server authentication"
+$ 'ssltest' -ssl2 -server_auth -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$ endif
+$
+$ write sys$output "test sslv3"
+$ 'ssltest' -ssl3
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv3 with server authentication"
+$ 'ssltest' -ssl3 -server_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv3 with client authentication"
+$ 'ssltest' -ssl3 -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv3 with both client and server authentication"
+$ 'ssltest' -ssl3 -server_auth -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2/sslv3"
+$ 'ssltest'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2/sslv3 with server authentication"
+$ 'ssltest' -server_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2/sslv3 with client authentication"
+$ 'ssltest' -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2/sslv3 with both client and server authentication"
+$ 'ssltest' -server_auth -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2 via BIO pair"
+$ 'ssltest' -bio_pair -ssl2
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2 with server authentication via BIO pair"
+$ 'ssltest' -bio_pair -ssl2 -server_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ if .not. dsa_cert
+$ then
+$ write sys$output "test sslv2 with client authentication via BIO pair"
+$ 'ssltest' -bio_pair -ssl2 -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2 with both client and server authentication via BIO pair"
+$ 'ssltest' -bio_pair -ssl2 -server_auth -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$ endif
+$
+$ write sys$output "test sslv3 via BIO pair"
+$ 'ssltest' -bio_pair -ssl3
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv3 with server authentication via BIO pair"
+$ 'ssltest' -bio_pair -ssl3 -server_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv3 with client authentication via BIO pair"
+$ 'ssltest' -bio_pair -ssl3 -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+
+$ write sys$output "test sslv3 with both client and server authentication via BIO pair"
+$ 'ssltest' -bio_pair -ssl3 -server_auth -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2/sslv3 via BIO pair"
+$ 'ssltest'
+$ if $severity .ne. 1 then goto exit3
+$
+$ if .not. dsa_cert
+$ then
+$ write sys$output "test sslv2/sslv3 w/o DHE via BIO pair"
+$ 'ssltest' -bio_pair -no_dhe
+$ if $severity .ne. 1 then goto exit3
+$ endif
+$
+$ write sys$output "test sslv2/sslv3 with 1024 bit DHE via BIO pair"
+$ 'ssltest' -bio_pair -dhe1024dsa -v
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2/sslv3 with server authentication"
+$ 'ssltest' -bio_pair -server_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2/sslv3 with client authentication via BIO pair"
+$ 'ssltest' -bio_pair -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$ write sys$output "test sslv2/sslv3 with both client and server authentication via BIO pair"
+$ 'ssltest' -bio_pair -server_auth -client_auth 'CA'
+$ if $severity .ne. 1 then goto exit3
+$
+$!###########################################################################
+$
+$ define/user sys$output nla0:
+$ mcr 'exe_dir'openssl no-rsa
+$ no_rsa=$SEVERITY
+$ define/user sys$output nla0:
+$ mcr 'exe_dir'openssl no-dh
+$ no_dh=$SEVERITY
+$
+$ if no_dh
+$ then
+$ write sys$output "skipping anonymous DH tests"
+$ else
+$ write sys$output "test tls1 with 1024bit anonymous DH, multiple handshakes"
+$ 'ssltest' -v -bio_pair -tls1 -cipher "ADH" -dhe1024dsa -num 10 -f -time
+$ if $severity .ne. 1 then goto exit3
+$ endif
+$
+$ if no_rsa
+$ then
+$ write sys$output "skipping RSA tests"
+$ else
+$ write sys$output "test tls1 with 1024bit RSA, no DHE, multiple handshakes"
+$ mcr 'texe_dir'ssltest -v -bio_pair -tls1 -cert [-.apps]server2.pem -no_dhe -num 10 -f -time
+$ if $severity .ne. 1 then goto exit3
+$
+$ if no_dh
+$ then
+$ write sys$output "skipping RSA+DHE tests"
+$ else
+$ write sys$output "test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes"
+$ mcr 'texe_dir'ssltest -v -bio_pair -tls1 -cert [-.apps]server2.pem -dhe1024dsa -num 10 -f -time
+$ if $severity .ne. 1 then goto exit3
+$ endif
+$ endif
+$
+$ RET = 1
+$ goto exit
+$ exit3:
+$ RET = 3
+$ exit:
+$ if p3 .eqs. "" then delete certs.tmp;*
+$ set on
+$ exit 'RET'
diff --git a/deps/openssl/openssl/test/testsslproxy b/deps/openssl/openssl/test/testsslproxy
new file mode 100644
index 000000000..58bbda8ab
--- /dev/null
+++ b/deps/openssl/openssl/test/testsslproxy
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+echo 'Testing a lot of proxy conditions.'
+echo 'Some of them may turn out being invalid, which is fine.'
+for auth in A B C BC; do
+ for cond in A B C 'A|B&!C'; do
+ sh ./testssl $1 $2 $3 "-proxy -proxy_auth $auth -proxy_cond $cond"
+ if [ $? = 3 ]; then exit 1; fi
+ done
+done
diff --git a/deps/openssl/openssl/test/testtsa b/deps/openssl/openssl/test/testtsa
new file mode 100644
index 000000000..bb653b5f7
--- /dev/null
+++ b/deps/openssl/openssl/test/testtsa
@@ -0,0 +1,238 @@
+#!/bin/sh
+
+#
+# A few very basic tests for the 'ts' time stamping authority command.
+#
+
+SH="/bin/sh"
+if test "$OSTYPE" = msdosdjgpp; then
+ PATH="../apps\;$PATH"
+else
+ PATH="../apps:$PATH"
+fi
+export SH PATH
+
+OPENSSL_CONF="../CAtsa.cnf"
+export OPENSSL_CONF
+# Because that's what ../apps/CA.sh really looks at
+SSLEAY_CONFIG="-config $OPENSSL_CONF"
+export SSLEAY_CONFIG
+
+OPENSSL="`pwd`/../util/opensslwrap.sh"
+export OPENSSL
+
+error () {
+
+ echo "TSA test failed!" >&2
+ exit 1
+}
+
+setup_dir () {
+
+ rm -rf tsa 2>/dev/null
+ mkdir tsa
+ cd ./tsa
+}
+
+clean_up_dir () {
+
+ cd ..
+ rm -rf tsa
+}
+
+create_ca () {
+
+ echo "Creating a new CA for the TSA tests..."
+ TSDNSECT=ts_ca_dn
+ export TSDNSECT
+ ../../util/shlib_wrap.sh ../../apps/openssl req -new -x509 -nodes \
+ -out tsaca.pem -keyout tsacakey.pem
+ test $? != 0 && error
+}
+
+create_tsa_cert () {
+
+ INDEX=$1
+ export INDEX
+ EXT=$2
+ TSDNSECT=ts_cert_dn
+ export TSDNSECT
+
+ ../../util/shlib_wrap.sh ../../apps/openssl req -new \
+ -out tsa_req${INDEX}.pem -keyout tsa_key${INDEX}.pem
+ test $? != 0 && error
+echo Using extension $EXT
+ ../../util/shlib_wrap.sh ../../apps/openssl x509 -req \
+ -in tsa_req${INDEX}.pem -out tsa_cert${INDEX}.pem \
+ -CA tsaca.pem -CAkey tsacakey.pem -CAcreateserial \
+ -extfile $OPENSSL_CONF -extensions $EXT
+ test $? != 0 && error
+}
+
+print_request () {
+
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -query -in $1 -text
+}
+
+create_time_stamp_request1 () {
+
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../testtsa -policy tsa_policy1 -cert -out req1.tsq
+ test $? != 0 && error
+}
+
+create_time_stamp_request2 () {
+
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../testtsa -policy tsa_policy2 -no_nonce \
+ -out req2.tsq
+ test $? != 0 && error
+}
+
+create_time_stamp_request3 () {
+
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../CAtsa.cnf -no_nonce -out req3.tsq
+ test $? != 0 && error
+}
+
+print_response () {
+
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $1 -text
+ test $? != 0 && error
+}
+
+create_time_stamp_response () {
+
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -section $3 -queryfile $1 -out $2
+ test $? != 0 && error
+}
+
+time_stamp_response_token_test () {
+
+ RESPONSE2=$2.copy.tsr
+ TOKEN_DER=$2.token.der
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -out $TOKEN_DER -token_out
+ test $? != 0 && error
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $TOKEN_DER -token_in -out $RESPONSE2
+ test $? != 0 && error
+ cmp $RESPONSE2 $2
+ test $? != 0 && error
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -text -token_out
+ test $? != 0 && error
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $TOKEN_DER -token_in -text -token_out
+ test $? != 0 && error
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -queryfile $1 -text -token_out
+ test $? != 0 && error
+}
+
+verify_time_stamp_response () {
+
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2 -CAfile tsaca.pem \
+ -untrusted tsa_cert1.pem
+ test $? != 0 && error
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -data $3 -in $2 -CAfile tsaca.pem \
+ -untrusted tsa_cert1.pem
+ test $? != 0 && error
+}
+
+verify_time_stamp_token () {
+
+ # create the token from the response first
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -out $2.token -token_out
+ test $? != 0 && error
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2.token -token_in \
+ -CAfile tsaca.pem -untrusted tsa_cert1.pem
+ test $? != 0 && error
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -data $3 -in $2.token -token_in \
+ -CAfile tsaca.pem -untrusted tsa_cert1.pem
+ test $? != 0 && error
+}
+
+verify_time_stamp_response_fail () {
+
+ ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2 -CAfile tsaca.pem \
+ -untrusted tsa_cert1.pem
+ # Checks if the verification failed, as it should have.
+ test $? = 0 && error
+ echo Ok
+}
+
+# main functions
+
+echo "Setting up TSA test directory..."
+setup_dir
+
+echo "Creating CA for TSA tests..."
+create_ca
+
+echo "Creating tsa_cert1.pem TSA server cert..."
+create_tsa_cert 1 tsa_cert
+
+echo "Creating tsa_cert2.pem non-TSA server cert..."
+create_tsa_cert 2 non_tsa_cert
+
+echo "Creating req1.req time stamp request for file testtsa..."
+create_time_stamp_request1
+
+echo "Printing req1.req..."
+print_request req1.tsq
+
+echo "Generating valid response for req1.req..."
+create_time_stamp_response req1.tsq resp1.tsr tsa_config1
+
+echo "Printing response..."
+print_response resp1.tsr
+
+echo "Verifying valid response..."
+verify_time_stamp_response req1.tsq resp1.tsr ../testtsa
+
+echo "Verifying valid token..."
+verify_time_stamp_token req1.tsq resp1.tsr ../testtsa
+
+# The tests below are commented out, because invalid signer certificates
+# can no longer be specified in the config file.
+
+# echo "Generating _invalid_ response for req1.req..."
+# create_time_stamp_response req1.tsq resp1_bad.tsr tsa_config2
+
+# echo "Printing response..."
+# print_response resp1_bad.tsr
+
+# echo "Verifying invalid response, it should fail..."
+# verify_time_stamp_response_fail req1.tsq resp1_bad.tsr
+
+echo "Creating req2.req time stamp request for file testtsa..."
+create_time_stamp_request2
+
+echo "Printing req2.req..."
+print_request req2.tsq
+
+echo "Generating valid response for req2.req..."
+create_time_stamp_response req2.tsq resp2.tsr tsa_config1
+
+echo "Checking '-token_in' and '-token_out' options with '-reply'..."
+time_stamp_response_token_test req2.tsq resp2.tsr
+
+echo "Printing response..."
+print_response resp2.tsr
+
+echo "Verifying valid response..."
+verify_time_stamp_response req2.tsq resp2.tsr ../testtsa
+
+echo "Verifying response against wrong request, it should fail..."
+verify_time_stamp_response_fail req1.tsq resp2.tsr
+
+echo "Verifying response against wrong request, it should fail..."
+verify_time_stamp_response_fail req2.tsq resp1.tsr
+
+echo "Creating req3.req time stamp request for file CAtsa.cnf..."
+create_time_stamp_request3
+
+echo "Printing req3.req..."
+print_request req3.tsq
+
+echo "Verifying response against wrong request, it should fail..."
+verify_time_stamp_response_fail req3.tsq resp1.tsr
+
+echo "Cleaning up..."
+clean_up_dir
+
+exit 0
diff --git a/deps/openssl/openssl/test/testtsa.com b/deps/openssl/openssl/test/testtsa.com
new file mode 100644
index 000000000..29fb1d0e6
--- /dev/null
+++ b/deps/openssl/openssl/test/testtsa.com
@@ -0,0 +1,255 @@
+$!
+$! A few very basic tests for the 'ts' time stamping authority command.
+$!
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p4 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ openssl = "mcr ''f$parse(exe_dir+"openssl.exe")'"
+$ OPENSSL_CONF = "[-]CAtsa.cnf"
+$ ! Because that's what ../apps/CA.sh really looks at
+$ SSLEAY_CONFIG = "-config " + OPENSSL_CONF
+$
+$ error:
+$ subroutine
+$ write sys$error "TSA test failed!"
+$ exit 3
+$ endsubroutine
+$
+$ setup_dir:
+$ subroutine
+$
+$ if f$search("tsa.dir") .nes ""
+$ then
+$ @[-.util]deltree [.tsa]*.*
+$ set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) tsa.dir;*
+$ delete tsa.dir;*
+$ endif
+$
+$ create/dir [.tsa]
+$ set default [.tsa]
+$ endsubroutine
+$
+$ clean_up_dir:
+$ subroutine
+$
+$ set default [-]
+$ @[-.util]deltree [.tsa]*.*
+$ set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) tsa.dir;*
+$ delete tsa.dir;*
+$ endsubroutine
+$
+$ create_ca:
+$ subroutine
+$
+$ write sys$output "Creating a new CA for the TSA tests..."
+$ TSDNSECT = "ts_ca_dn"
+$ openssl req -new -x509 -nodes -
+ -out tsaca.pem -keyout tsacakey.pem
+$ if $severity .ne. 1 then call error
+$ endsubroutine
+$
+$ create_tsa_cert:
+$ subroutine
+$
+$ INDEX=p1
+$ EXT=p2
+$ TSDNSECT = "ts_cert_dn"
+$
+$ openssl req -new -
+ -out tsa_req'INDEX'.pem -keyout tsa_key'INDEX'.pem
+$ if $severity .ne. 1 then call error
+$
+$ write sys$output "Using extension ''EXT'"
+$ openssl x509 -req -
+ -in tsa_req'INDEX'.pem -out tsa_cert'INDEX'.pem -
+ "-CA" tsaca.pem "-CAkey" tsacakey.pem "-CAcreateserial" -
+ -extfile 'OPENSSL_CONF' -extensions "''EXT'"
+$ if $severity .ne. 1 then call error
+$ endsubroutine
+$
+$ print_request:
+$ subroutine
+$
+$ openssl ts -query -in 'p1' -text
+$ endsubroutine
+$
+$ create_time_stamp_request1: subroutine
+$
+$ openssl ts -query -data [-]testtsa.com -policy tsa_policy1 -
+ -cert -out req1.tsq
+$ if $severity .ne. 1 then call error
+$ endsubroutine
+$
+$ create_time_stamp_request2: subroutine
+$
+$ openssl ts -query -data [-]testtsa.com -policy tsa_policy2 -
+ -no_nonce -out req2.tsq
+$ if $severity .ne. 1 then call error
+$ endsubroutine
+$
+$ create_time_stamp_request3: subroutine
+$
+$ openssl ts -query -data [-]CAtsa.cnf -no_nonce -out req3.tsq
+$ if $severity .ne. 1 then call error
+$ endsubroutine
+$
+$ print_response:
+$ subroutine
+$
+$ openssl ts -reply -in 'p1' -text
+$ if $severity .ne. 1 then call error
+$ endsubroutine
+$
+$ create_time_stamp_response:
+$ subroutine
+$
+$ openssl ts -reply -section 'p3' -queryfile 'p1' -out 'p2'
+$ if $severity .ne. 1 then call error
+$ endsubroutine
+$
+$ time_stamp_response_token_test:
+$ subroutine
+$
+$ RESPONSE2 = p2+ "-copy_tsr"
+$ TOKEN_DER = p2+ "-token_der"
+$ openssl ts -reply -in 'p2' -out 'TOKEN_DER' -token_out
+$ if $severity .ne. 1 then call error
+$ openssl ts -reply -in 'TOKEN_DER' -token_in -out 'RESPONSE2'
+$ if $severity .ne. 1 then call error
+$ backup/compare 'RESPONSE2' 'p2'
+$ if $severity .ne. 1 then call error
+$ openssl ts -reply -in 'p2' -text -token_out
+$ if $severity .ne. 1 then call error
+$ openssl ts -reply -in 'TOKEN_DER' -token_in -text -token_out
+$ if $severity .ne. 1 then call error
+$ openssl ts -reply -queryfile 'p1' -text -token_out
+$ if $severity .ne. 1 then call error
+$ endsubroutine
+$
+$ verify_time_stamp_response:
+$ subroutine
+$
+$ openssl ts -verify -queryfile 'p1' -in 'p2' -
+ "-CAfile" tsaca.pem -untrusted tsa_cert1.pem
+$ if $severity .ne. 1 then call error
+$ openssl ts -verify -data 'p3' -in 'p2' -
+ "-CAfile" tsaca.pem -untrusted tsa_cert1.pem
+$ if $severity .ne. 1 then call error
+$ endsubroutine
+$
+$ verify_time_stamp_token:
+$ subroutine
+$
+$ ! create the token from the response first
+$ openssl ts -reply -in "''p2'" -out "''p2'-token" -token_out
+$ if $severity .ne. 1 then call error
+$ openssl ts -verify -queryfile "''p1'" -in "''p2'-token" -
+ -token_in "-CAfile" tsaca.pem -untrusted tsa_cert1.pem
+$ if $severity .ne. 1 then call error
+$ openssl ts -verify -data "''p3'" -in "''p2'-token" -
+ -token_in "-CAfile" tsaca.pem -untrusted tsa_cert1.pem
+$ if $severity .ne. 1 then call error
+$ endsubroutine
+$
+$ verify_time_stamp_response_fail:
+$ subroutine
+$
+$ openssl ts -verify -queryfile 'p1' -in 'p2' -
+ "-CAfile" tsaca.pem -untrusted tsa_cert1.pem
+$ ! Checks if the verification failed, as it should have.
+$ if $severity .eq. 1 then call error
+$ write sys$output "Ok"
+$ endsubroutine
+$
+$ ! Main body ----------------------------------------------------------
+$
+$ set noon
+$
+$ write sys$output "Setting up TSA test directory..."
+$ call setup_dir
+$
+$ write sys$output "Creating CA for TSA tests..."
+$ call create_ca
+$
+$ write sys$output "Creating tsa_cert1.pem TSA server cert..."
+$ call create_tsa_cert 1 "tsa_cert"
+$
+$ write sys$output "Creating tsa_cert2.pem non-TSA server cert..."
+$ call create_tsa_cert 2 "non_tsa_cert"
+$
+$ write sys$output "Creating req1.req time stamp request for file testtsa..."
+$ call create_time_stamp_request1
+$
+$ write sys$output "Printing req1.req..."
+$ call print_request "req1.tsq"
+$
+$ write sys$output "Generating valid response for req1.req..."
+$ call create_time_stamp_response "req1.tsq" "resp1.tsr" "tsa_config1"
+$
+$ write sys$output "Printing response..."
+$ call print_response "resp1.tsr"
+$
+$ write sys$output "Verifying valid response..."
+$ call verify_time_stamp_response "req1.tsq" "resp1.tsr" "[-]testtsa.com"
+$
+$ write sys$output "Verifying valid token..."
+$ call verify_time_stamp_token "req1.tsq" "resp1.tsr" "[-]testtsa.com"
+$
+$ ! The tests below are commented out, because invalid signer certificates
+$ ! can no longer be specified in the config file.
+$
+$ ! write sys$output "Generating _invalid_ response for req1.req..."
+$ ! call create_time_stamp_response "req1.tsq" "resp1_bad.tsr" "tsa_config2"
+$
+$ ! write sys$output "Printing response..."
+$ ! call print_response "resp1_bad.tsr"
+$
+$ ! write sys$output "Verifying invalid response, it should fail..."
+$ ! call verify_time_stamp_response_fail "req1.tsq" "resp1_bad.tsr"
+$
+$ write sys$output "Creating req2.req time stamp request for file testtsa..."
+$ call create_time_stamp_request2
+$
+$ write sys$output "Printing req2.req..."
+$ call print_request "req2.tsq"
+$
+$ write sys$output "Generating valid response for req2.req..."
+$ call create_time_stamp_response "req2.tsq" "resp2.tsr" "tsa_config1"
+$
+$ write sys$output "Checking '-token_in' and '-token_out' options with '-reply'..."
+$ call time_stamp_response_token_test "req2.tsq" "resp2.tsr"
+$
+$ write sys$output "Printing response..."
+$ call print_response "resp2.tsr"
+$
+$ write sys$output "Verifying valid response..."
+$ call verify_time_stamp_response "req2.tsq" "resp2.tsr" "[-]testtsa.com"
+$
+$ write sys$output "Verifying response against wrong request, it should fail..."
+$ call verify_time_stamp_response_fail "req1.tsq" "resp2.tsr"
+$
+$ write sys$output "Verifying response against wrong request, it should fail..."
+$ call verify_time_stamp_response_fail "req2.tsq" "resp1.tsr"
+$
+$ write sys$output "Creating req3.req time stamp request for file CAtsa.cnf..."
+$ call create_time_stamp_request3
+$
+$ write sys$output "Printing req3.req..."
+$ call print_request "req3.tsq"
+$
+$ write sys$output "Verifying response against wrong request, it should fail..."
+$ call verify_time_stamp_response_fail "req3.tsq" "resp1.tsr"
+$
+$ write sys$output "Cleaning up..."
+$ call clean_up_dir
+$
+$ set on
+$
+$ exit
diff --git a/deps/openssl/openssl/test/testx509.pem b/deps/openssl/openssl/test/testx509.pem
new file mode 100644
index 000000000..8a85d1496
--- /dev/null
+++ b/deps/openssl/openssl/test/testx509.pem
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
+BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz
+MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
+RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF
+AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO
+/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE
+Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ
+zl9HYIMxATFyqSiD9jsx
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/test/times b/deps/openssl/openssl/test/times
new file mode 100644
index 000000000..6b66eb342
--- /dev/null
+++ b/deps/openssl/openssl/test/times
@@ -0,0 +1,113 @@
+
+More number for the questions about SSL overheads....
+
+The following numbers were generated on a Pentium pro 200, running Linux.
+They give an indication of the SSL protocol and encryption overheads.
+
+The program that generated them is an unreleased version of ssl/ssltest.c
+which is the SSLeay ssl protocol testing program. It is a single process that
+talks both sides of the SSL protocol via a non-blocking memory buffer
+interface.
+
+How do I read this? The protocol and cipher are reasonable obvious.
+The next number is the number of connections being made. The next is the
+number of bytes exchanged between the client and server side of the protocol.
+This is the number of bytes that the client sends to the server, and then
+the server sends back. Because this is all happening in one process,
+the data is being encrypted, decrypted, encrypted and then decrypted again.
+It is a round trip of that many bytes. Because the one process performs
+both the client and server sides of the protocol and it sends this many bytes
+each direction, multiply this number by 4 to generate the number
+of bytes encrypted/decrypted/MACed. The first time value is how many seconds
+elapsed doing a full SSL handshake, the second is the cost of one
+full handshake and the rest being session-id reuse.
+
+SSLv2 RC4-MD5 1000 x 1 12.83s 0.70s
+SSLv3 NULL-MD5 1000 x 1 14.35s 1.47s
+SSLv3 RC4-MD5 1000 x 1 14.46s 1.56s
+SSLv3 RC4-MD5 1000 x 1 51.93s 1.62s 1024bit RSA
+SSLv3 RC4-SHA 1000 x 1 14.61s 1.83s
+SSLv3 DES-CBC-SHA 1000 x 1 14.70s 1.89s
+SSLv3 DES-CBC3-SHA 1000 x 1 15.16s 2.16s
+
+SSLv2 RC4-MD5 1000 x 1024 13.72s 1.27s
+SSLv3 NULL-MD5 1000 x 1024 14.79s 1.92s
+SSLv3 RC4-MD5 1000 x 1024 52.58s 2.29s 1024bit RSA
+SSLv3 RC4-SHA 1000 x 1024 15.39s 2.67s
+SSLv3 DES-CBC-SHA 1000 x 1024 16.45s 3.55s
+SSLv3 DES-CBC3-SHA 1000 x 1024 18.21s 5.38s
+
+SSLv2 RC4-MD5 1000 x 10240 18.97s 6.52s
+SSLv3 NULL-MD5 1000 x 10240 17.79s 5.11s
+SSLv3 RC4-MD5 1000 x 10240 20.25s 7.90s
+SSLv3 RC4-MD5 1000 x 10240 58.26s 8.08s 1024bit RSA
+SSLv3 RC4-SHA 1000 x 10240 22.96s 11.44s
+SSLv3 DES-CBC-SHA 1000 x 10240 30.65s 18.41s
+SSLv3 DES-CBC3-SHA 1000 x 10240 47.04s 34.53s
+
+SSLv2 RC4-MD5 1000 x 102400 70.22s 57.74s
+SSLv3 NULL-MD5 1000 x 102400 43.73s 31.03s
+SSLv3 RC4-MD5 1000 x 102400 71.32s 58.83s
+SSLv3 RC4-MD5 1000 x 102400 109.66s 59.20s 1024bit RSA
+SSLv3 RC4-SHA 1000 x 102400 95.88s 82.21s
+SSLv3 DES-CBC-SHA 1000 x 102400 173.22s 160.55s
+SSLv3 DES-CBC3-SHA 1000 x 102400 336.61s 323.82s
+
+What does this all mean? Well for a server, with no session-id reuse, with
+a transfer size of 10240 bytes, using RC4-MD5 and a 512bit server key,
+a Pentium pro 200 running Linux can handle the SSLv3 protocol overheads of
+about 49 connections a second. Reality will be quite different :-).
+
+Remember the first number is 1000 full ssl handshakes, the second is
+1 full and 999 with session-id reuse. The RSA overheads for each exchange
+would be one public and one private operation, but the protocol/MAC/cipher
+cost would be quite similar in both the client and server.
+
+eric (adding numbers to speculation)
+
+--- Appendix ---
+- The time measured is user time but these number a very rough.
+- Remember this is the cost of both client and server sides of the protocol.
+- The TCP/kernel overhead of connection establishment is normally the
+ killer in SSL. Often delays in the TCP protocol will make session-id
+ reuse look slower that new sessions, but this would not be the case on
+ a loaded server.
+- The TCP round trip latencies, while slowing individual connections,
+ would have minimal impact on throughput.
+- Instead of sending one 102400 byte buffer, one 8k buffer is sent until
+- the required number of bytes are processed.
+- The SSLv3 connections were actually SSLv2 compatible SSLv3 headers.
+- A 512bit server key was being used except where noted.
+- No server key verification was being performed on the client side of the
+ protocol. This would slow things down very little.
+- The library being used is SSLeay 0.8.x.
+- The normal measuring system was commands of the form
+ time ./ssltest -num 1000 -bytes 102400 -cipher DES-CBC-SHA -reuse
+ This modified version of ssltest should be in the next public release of
+ SSLeay.
+
+The general cipher performance number for this platform are
+
+SSLeay 0.8.2a 04-Sep-1997
+built on Fri Sep 5 17:37:05 EST 1997
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
+C flags:gcc -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
+The 'numbers' are in 1000s of bytes per second processed.
+type 8 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
+md2 131.02k 368.41k 500.57k 549.21k 566.09k
+mdc2 535.60k 589.10k 595.88k 595.97k 594.54k
+md5 1801.53k 9674.77k 17484.03k 21849.43k 23592.96k
+sha 1261.63k 5533.25k 9285.63k 11187.88k 11913.90k
+sha1 1103.13k 4782.53k 7933.78k 9472.34k 10070.70k
+rc4 10722.53k 14443.93k 15215.79k 15299.24k 15219.59k
+des cbc 3286.57k 3827.73k 3913.39k 3931.82k 3926.70k
+des ede3 1443.50k 1549.08k 1561.17k 1566.38k 1564.67k
+idea cbc 2203.64k 2508.16k 2538.33k 2543.62k 2547.71k
+rc2 cbc 1430.94k 1511.59k 1524.82k 1527.13k 1523.33k
+blowfish cbc 4716.07k 5965.82k 6190.17k 6243.67k 6234.11k
+ sign verify
+rsa 512 bits 0.0100s 0.0011s
+rsa 1024 bits 0.0451s 0.0012s
+rsa 2048 bits 0.2605s 0.0086s
+rsa 4096 bits 1.6883s 0.0302s
+
diff --git a/deps/openssl/openssl/test/tpkcs7 b/deps/openssl/openssl/test/tpkcs7
new file mode 100644
index 000000000..3e435ffbf
--- /dev/null
+++ b/deps/openssl/openssl/test/tpkcs7
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl pkcs7'
+
+if [ "$1"x != "x" ]; then
+ t=$1
+else
+ t=testp7.pem
+fi
+
+echo testing pkcs7 conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/deps/openssl/openssl/test/tpkcs7.com b/deps/openssl/openssl/test/tpkcs7.com
new file mode 100644
index 000000000..3fc4982bb
--- /dev/null
+++ b/deps/openssl/openssl/test/tpkcs7.com
@@ -0,0 +1,59 @@
+$! TPKCS7.COM -- Tests pkcs7 keys
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ cmd = "mcr ''exe_dir'openssl pkcs7"
+$
+$ t = "testp7.pem"
+$ if p1 .nes. "" then t = p1
+$
+$ write sys$output "testing PKCS7 conversions"
+$ if f$search("fff.*") .nes "" then delete fff.*;*
+$ if f$search("ff.*") .nes "" then delete ff.*;*
+$ if f$search("f.*") .nes "" then delete f.*;*
+$ convert/fdl=sys$input: 't' fff.p
+RECORD
+ FORMAT STREAM_LF
+$
+$ write sys$output "p -> d"
+$ 'cmd' -in fff.p -inform p -outform d -out f.d
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in fff.p -inform p -outform p -out f.p
+$ if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> d"
+$ 'cmd' -in f.d -inform d -outform d -out ff.d1
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> d"
+$ 'cmd' -in f.p -inform p -outform d -out ff.d3
+$ if $severity .ne. 1 then exit 3
+$
+$
+$ write sys$output "d -> p"
+$ 'cmd' -in f.d -inform d -outform p -out ff.p1
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in f.p -inform p -outform p -out ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ backup/compare fff.p f.p
+$ if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ backup/compare f.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$ backup/compare f.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ delete f.*;*,ff.*;*,fff.*;*
diff --git a/deps/openssl/openssl/test/tpkcs7d b/deps/openssl/openssl/test/tpkcs7d
new file mode 100644
index 000000000..64fc28e88
--- /dev/null
+++ b/deps/openssl/openssl/test/tpkcs7d
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl pkcs7'
+
+if [ "$1"x != "x" ]; then
+ t=$1
+else
+ t=pkcs7-1.pem
+fi
+
+echo "testing pkcs7 conversions (2)"
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/deps/openssl/openssl/test/tpkcs7d.com b/deps/openssl/openssl/test/tpkcs7d.com
new file mode 100644
index 000000000..eea8c888e
--- /dev/null
+++ b/deps/openssl/openssl/test/tpkcs7d.com
@@ -0,0 +1,52 @@
+$! TPKCS7.COM -- Tests pkcs7 keys
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ cmd = "mcr ''exe_dir'openssl pkcs7"
+$
+$ t = "pkcs7-1.pem"
+$ if p1 .nes. "" then t = p1
+$
+$ write sys$output "testing PKCS7 conversions (2)"
+$ if f$search("fff.*") .nes "" then delete fff.*;*
+$ if f$search("ff.*") .nes "" then delete ff.*;*
+$ if f$search("f.*") .nes "" then delete f.*;*
+$ convert/fdl=sys$input: 't' fff.p
+RECORD
+ FORMAT STREAM_LF
+$
+$ write sys$output "p -> d"
+$ 'cmd' -in fff.p -inform p -outform d -out f.d
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in fff.p -inform p -outform p -out f.p
+$ if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> d"
+$ 'cmd' -in f.d -inform d -outform d -out ff.d1
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> d"
+$ 'cmd' -in f.p -inform p -outform d -out ff.d3
+$ if $severity .ne. 1 then exit 3
+$
+$
+$ write sys$output "d -> p"
+$ 'cmd' -in f.d -inform d -outform p -out ff.p1
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in f.p -inform p -outform p -out ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ backup/compare f.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$ backup/compare f.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ delete f.*;*,ff.*;*,fff.*;*
diff --git a/deps/openssl/openssl/test/treq b/deps/openssl/openssl/test/treq
new file mode 100644
index 000000000..77f37dcf3
--- /dev/null
+++ b/deps/openssl/openssl/test/treq
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl req -config ../apps/openssl.cnf'
+
+if [ "$1"x != "x" ]; then
+ t=$1
+else
+ t=testreq.pem
+fi
+
+if $cmd -in $t -inform p -noout -text 2>&1 | fgrep -i 'Unknown Public Key'; then
+ echo "skipping req conversion test for $t"
+ exit 0
+fi
+
+echo testing req conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in fff.p -inform p -outform t >f.t
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -verify -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> d"
+#$cmd -in f.t -inform t -outform d >ff.d2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -verify -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+#echo "d -> t"
+#$cmd -in f.d -inform d -outform t >ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#echo "t -> t"
+#$cmd -in f.t -inform t -outform t >ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in f.p -inform p -outform t >ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> p"
+#$cmd -in f.t -inform t -outform p >ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp fff.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+#cmp f.t ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp f.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/deps/openssl/openssl/test/treq.com b/deps/openssl/openssl/test/treq.com
new file mode 100644
index 000000000..acf08b79e
--- /dev/null
+++ b/deps/openssl/openssl/test/treq.com
@@ -0,0 +1,88 @@
+$! TREQ.COM -- Tests req keys
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ cmd = "mcr ''exe_dir'openssl req -config [-.apps]openssl-vms.cnf"
+$
+$ t = "testreq.pem"
+$ if p1 .nes. "" then t = p1
+$
+$ write sys$output "testing req conversions"
+$ if f$search("fff.*") .nes "" then delete fff.*;*
+$ if f$search("ff.*") .nes "" then delete ff.*;*
+$ if f$search("f.*") .nes "" then delete f.*;*
+$ convert/fdl=sys$input: 't' fff.p
+RECORD
+ FORMAT STREAM_LF
+$
+$ write sys$output "p -> d"
+$ 'cmd' -in fff.p -inform p -outform d -out f.d
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "p -> t"
+$! 'cmd' -in fff.p -inform p -outform t -out f.t
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in fff.p -inform p -outform p -out f.p
+$ if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> d"
+$ 'cmd' -verify -in f.d -inform d -outform d -out ff.d1
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "t -> d"
+$! 'cmd' -verify -in f.t -inform t -outform d -out ff.d2
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> d"
+$ 'cmd' -verify -in f.p -inform p -outform d -out ff.d3
+$ if $severity .ne. 1 then exit 3
+$
+$! write sys$output "d -> t"
+$! 'cmd' -in f.d -inform d -outform t -out ff.t1
+$! if $severity .ne. 1 then exit 3
+$! write sys$output "t -> t"
+$! 'cmd' -in f.t -inform t -outform t -out ff.t2
+$! if $severity .ne. 1 then exit 3
+$! write sys$output "p -> t"
+$! 'cmd' -in f.p -inform p -outform t -out ff.t3
+$! if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> p"
+$ 'cmd' -in f.d -inform d -outform p -out ff.p1
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "t -> p"
+$! 'cmd' -in f.t -inform t -outform p -out ff.p2
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in f.p -inform p -outform p -out ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ backup/compare fff.p f.p
+$ if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$! backup/compare fff.p ff.p2
+$! if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$! backup/compare f.t ff.t1
+$! if $severity .ne. 1 then exit 3
+$! backup/compare f.t ff.t2
+$! if $severity .ne. 1 then exit 3
+$! backup/compare f.t ff.t3
+$! if $severity .ne. 1 then exit 3
+$
+$ backup/compare f.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$! backup/compare f.p ff.p2
+$! if $severity .ne. 1 then exit 3
+$ backup/compare f.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ delete f.*;*,ff.*;*,fff.*;*
diff --git a/deps/openssl/openssl/test/trsa b/deps/openssl/openssl/test/trsa
new file mode 100644
index 000000000..249ac1ddc
--- /dev/null
+++ b/deps/openssl/openssl/test/trsa
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
+ echo skipping rsa conversion test
+ exit 0
+fi
+
+cmd='../util/shlib_wrap.sh ../apps/openssl rsa'
+
+if [ "$1"x != "x" ]; then
+ t=$1
+else
+ t=testrsa.pem
+fi
+
+echo testing rsa conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in fff.p -inform p -outform t >f.t
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> d"
+#$cmd -in f.t -inform t -outform d >ff.d2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+#echo "d -> t"
+#$cmd -in f.d -inform d -outform t >ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#echo "t -> t"
+#$cmd -in f.t -inform t -outform t >ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in f.p -inform p -outform t >ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> p"
+#$cmd -in f.t -inform t -outform p >ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp fff.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+#cmp f.t ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp f.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/deps/openssl/openssl/test/trsa.com b/deps/openssl/openssl/test/trsa.com
new file mode 100644
index 000000000..54180843e
--- /dev/null
+++ b/deps/openssl/openssl/test/trsa.com
@@ -0,0 +1,99 @@
+$! TRSA.COM -- Tests rsa keys
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ set noon
+$ define/user sys$output nla0:
+$ mcr 'exe_dir'openssl no-rsa
+$ save_severity=$SEVERITY
+$ set on
+$ if save_severity
+$ then
+$ write sys$output "skipping RSA conversion test"
+$ exit
+$ endif
+$
+$ cmd = "mcr ''exe_dir'openssl rsa"
+$
+$ t = "testrsa.pem"
+$ if p1 .nes. "" then t = p1
+$
+$ write sys$output "testing RSA conversions"
+$ if f$search("fff.*") .nes "" then delete fff.*;*
+$ if f$search("ff.*") .nes "" then delete ff.*;*
+$ if f$search("f.*") .nes "" then delete f.*;*
+$ convert/fdl=sys$input: 't' fff.p
+RECORD
+ FORMAT STREAM_LF
+$
+$ write sys$output "p -> d"
+$ 'cmd' -in fff.p -inform p -outform d -out f.d
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "p -> t"
+$! 'cmd' -in fff.p -inform p -outform t -out f.t
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in fff.p -inform p -outform p -out f.p
+$ if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> d"
+$ 'cmd' -in f.d -inform d -outform d -out ff.d1
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "t -> d"
+$! 'cmd' -in f.t -inform t -outform d -out ff.d2
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> d"
+$ 'cmd' -in f.p -inform p -outform d -out ff.d3
+$ if $severity .ne. 1 then exit 3
+$
+$! write sys$output "d -> t"
+$! 'cmd' -in f.d -inform d -outform t -out ff.t1
+$! if $severity .ne. 1 then exit 3
+$! write sys$output "t -> t"
+$! 'cmd' -in f.t -inform t -outform t -out ff.t2
+$! if $severity .ne. 1 then exit 3
+$! write sys$output "p -> t"
+$! 'cmd' -in f.p -inform p -outform t -out ff.t3
+$! if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> p"
+$ 'cmd' -in f.d -inform d -outform p -out ff.p1
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "t -> p"
+$! 'cmd' -in f.t -inform t -outform p -out ff.p2
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in f.p -inform p -outform p -out ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ backup/compare fff.p f.p
+$ if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$! backup/compare fff.p ff.p2
+$! if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$! backup/compare f.t ff.t1
+$! if $severity .ne. 1 then exit 3
+$! backup/compare f.t ff.t2
+$! if $severity .ne. 1 then exit 3
+$! backup/compare f.t ff.t3
+$! if $severity .ne. 1 then exit 3
+$
+$ backup/compare f.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$! backup/compare f.p ff.p2
+$! if $severity .ne. 1 then exit 3
+$ backup/compare f.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ delete f.*;*,ff.*;*,fff.*;*
diff --git a/deps/openssl/openssl/test/tsid b/deps/openssl/openssl/test/tsid
new file mode 100644
index 000000000..6adbd531c
--- /dev/null
+++ b/deps/openssl/openssl/test/tsid
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl sess_id'
+
+if [ "$1"x != "x" ]; then
+ t=$1
+else
+ t=testsid.pem
+fi
+
+echo testing session-id conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in fff.p -inform p -outform t >f.t
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> d"
+#$cmd -in f.t -inform t -outform d >ff.d2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+#echo "d -> t"
+#$cmd -in f.d -inform d -outform t >ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#echo "t -> t"
+#$cmd -in f.t -inform t -outform t >ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in f.p -inform p -outform t >ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> p"
+#$cmd -in f.t -inform t -outform p >ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp fff.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+#cmp f.t ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp f.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/deps/openssl/openssl/test/tsid.com b/deps/openssl/openssl/test/tsid.com
new file mode 100644
index 000000000..b6c4e4947
--- /dev/null
+++ b/deps/openssl/openssl/test/tsid.com
@@ -0,0 +1,88 @@
+$! TSID.COM -- Tests sid keys
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ cmd = "mcr ''exe_dir'openssl sess_id"
+$
+$ t = "testsid.pem"
+$ if p1 .nes. "" then t = p1
+$
+$ write sys$output "testing session-id conversions"
+$ if f$search("fff.*") .nes "" then delete fff.*;*
+$ if f$search("ff.*") .nes "" then delete ff.*;*
+$ if f$search("f.*") .nes "" then delete f.*;*
+$ convert/fdl=sys$input: 't' fff.p
+RECORD
+ FORMAT STREAM_LF
+$
+$ write sys$output "p -> d"
+$ 'cmd' -in fff.p -inform p -outform d -out f.d
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "p -> t"
+$! 'cmd' -in fff.p -inform p -outform t -out f.t
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in fff.p -inform p -outform p -out f.p
+$ if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> d"
+$ 'cmd' -in f.d -inform d -outform d -out ff.d1
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "t -> d"
+$! 'cmd' -in f.t -inform t -outform d -out ff.d2
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> d"
+$ 'cmd' -in f.p -inform p -outform d -out ff.d3
+$ if $severity .ne. 1 then exit 3
+$
+$! write sys$output "d -> t"
+$! 'cmd' -in f.d -inform d -outform t -out ff.t1
+$! if $severity .ne. 1 then exit 3
+$! write sys$output "t -> t"
+$! 'cmd' -in f.t -inform t -outform t -out ff.t2
+$! if $severity .ne. 1 then exit 3
+$! write sys$output "p -> t"
+$! 'cmd' -in f.p -inform p -outform t -out ff.t3
+$! if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> p"
+$ 'cmd' -in f.d -inform d -outform p -out ff.p1
+$ if $severity .ne. 1 then exit 3
+$! write sys$output "t -> p"
+$! 'cmd' -in f.t -inform t -outform p -out ff.p2
+$! if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in f.p -inform p -outform p -out ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ backup/compare fff.p f.p
+$ if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$! backup/compare fff.p ff.p2
+$! if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$! backup/compare f.t ff.t1
+$! if $severity .ne. 1 then exit 3
+$! backup/compare f.t ff.t2
+$! if $severity .ne. 1 then exit 3
+$! backup/compare f.t ff.t3
+$! if $severity .ne. 1 then exit 3
+$
+$ backup/compare f.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$! backup/compare f.p ff.p2
+$! if $severity .ne. 1 then exit 3
+$ backup/compare f.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ delete f.*;*,ff.*;*,fff.*;*
diff --git a/deps/openssl/openssl/test/tverify.com b/deps/openssl/openssl/test/tverify.com
new file mode 100644
index 000000000..d88834463
--- /dev/null
+++ b/deps/openssl/openssl/test/tverify.com
@@ -0,0 +1,65 @@
+$! TVERIFY.COM
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p1 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ line_max = 255 ! Could be longer on modern non-VAX.
+$ temp_file_name = "certs_"+ f$getjpi( "", "PID")+ ".tmp"
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$ cmd = "mcr ''exe_dir'openssl verify ""-CAfile"" ''temp_file_name'"
+$ cmd_len = f$length( cmd)
+$ pems = "[-.certs...]*.pem"
+$!
+$! Concatenate all the certificate files.
+$!
+$ copy /concatenate 'pems' 'temp_file_name'
+$!
+$! Loop through all the certificate files.
+$!
+$ args = ""
+$ old_f = ""
+$ loop_file:
+$ f = f$search( pems)
+$ if ((f .nes. "") .and. (f .nes. old_f))
+$ then
+$ old_f = f
+$!
+$! If this file name would over-extend the command line, then
+$! run the command now.
+$!
+$ if (cmd_len+ f$length( args)+ 1+ f$length( f) .gt. line_max)
+$ then
+$ if (args .eqs. "") then goto disaster
+$ 'cmd''args'
+$ args = ""
+$ endif
+$! Add the next file to the argument list.
+$ args = args+ " "+ f
+$ else
+$! No more files in the list
+$ goto loop_file_end
+$ endif
+$ goto loop_file
+$ loop_file_end:
+$!
+$! Run the command for any left-over arguments.
+$!
+$ if (args .nes. "")
+$ then
+$ 'cmd''args'
+$ endif
+$!
+$! Delete the temporary file.
+$!
+$ if (f$search( "''temp_file_name';*") .nes. "") then -
+ delete 'temp_file_name';*
+$!
+$ exit
+$!
+$ disaster:
+$ write sys$output " Command line too long. Doomed."
+$!
diff --git a/deps/openssl/openssl/test/tx509 b/deps/openssl/openssl/test/tx509
new file mode 100644
index 000000000..4a15b98d1
--- /dev/null
+++ b/deps/openssl/openssl/test/tx509
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl x509'
+
+if [ "$1"x != "x" ]; then
+ t=$1
+else
+ t=testx509.pem
+fi
+
+echo testing X509 conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> n"
+$cmd -in fff.p -inform p -outform n >f.n
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+echo "n -> d"
+$cmd -in f.n -inform n -outform d >ff.d2
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> n"
+$cmd -in f.d -inform d -outform n >ff.n1
+if [ $? != 0 ]; then exit 1; fi
+echo "n -> n"
+$cmd -in f.n -inform n -outform n >ff.n2
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> n"
+$cmd -in f.p -inform p -outform n >ff.n3
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+echo "n -> p"
+$cmd -in f.n -inform n -outform p >ff.p2
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p2
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp f.n ff.n1
+if [ $? != 0 ]; then exit 1; fi
+cmp f.n ff.n2
+if [ $? != 0 ]; then exit 1; fi
+cmp f.n ff.n3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p2
+if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/deps/openssl/openssl/test/tx509.com b/deps/openssl/openssl/test/tx509.com
new file mode 100644
index 000000000..93ce988b4
--- /dev/null
+++ b/deps/openssl/openssl/test/tx509.com
@@ -0,0 +1,88 @@
+$! TX509.COM -- Tests x509 certificates
+$
+$ __arch = "VAX"
+$ if f$getsyi("cpu") .ge. 128 then -
+ __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if __arch .eqs. "" then __arch = "UNK"
+$!
+$ if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$ exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$ cmd = "mcr ''exe_dir'openssl x509"
+$
+$ t = "testx509.pem"
+$ if p1 .nes. "" then t = p1
+$
+$ write sys$output "testing X509 conversions"
+$ if f$search("fff.*") .nes "" then delete fff.*;*
+$ if f$search("ff.*") .nes "" then delete ff.*;*
+$ if f$search("f.*") .nes "" then delete f.*;*
+$ convert/fdl=sys$input: 't' fff.p
+RECORD
+ FORMAT STREAM_LF
+$
+$ write sys$output "p -> d"
+$ 'cmd' -in fff.p -inform p -outform d -out f.d
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> n"
+$ 'cmd' -in fff.p -inform p -outform n -out f.n
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in fff.p -inform p -outform p -out f.p
+$ if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> d"
+$ 'cmd' -in f.d -inform d -outform d -out ff.d1
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "n -> d"
+$ 'cmd' -in f.n -inform n -outform d -out ff.d2
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> d"
+$ 'cmd' -in f.p -inform p -outform d -out ff.d3
+$ if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> n"
+$ 'cmd' -in f.d -inform d -outform n -out ff.n1
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "n -> n"
+$ 'cmd' -in f.n -inform n -outform n -out ff.n2
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> n"
+$ 'cmd' -in f.p -inform p -outform n -out ff.n3
+$ if $severity .ne. 1 then exit 3
+$
+$ write sys$output "d -> p"
+$ 'cmd' -in f.d -inform d -outform p -out ff.p1
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "n -> p"
+$ 'cmd' -in f.n -inform n -outform p -out ff.p2
+$ if $severity .ne. 1 then exit 3
+$ write sys$output "p -> p"
+$ 'cmd' -in f.p -inform p -outform p -out ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ backup/compare fff.p f.p
+$ if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p2
+$ if $severity .ne. 1 then exit 3
+$ backup/compare fff.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ backup/compare f.n ff.n1
+$ if $severity .ne. 1 then exit 3
+$ backup/compare f.n ff.n2
+$ if $severity .ne. 1 then exit 3
+$ backup/compare f.n ff.n3
+$ if $severity .ne. 1 then exit 3
+$
+$ backup/compare f.p ff.p1
+$ if $severity .ne. 1 then exit 3
+$ backup/compare f.p ff.p2
+$ if $severity .ne. 1 then exit 3
+$ backup/compare f.p ff.p3
+$ if $severity .ne. 1 then exit 3
+$
+$ delete f.*;*,ff.*;*,fff.*;*
diff --git a/deps/openssl/openssl/test/v3-cert1.pem b/deps/openssl/openssl/test/v3-cert1.pem
new file mode 100644
index 000000000..0da253d5c
--- /dev/null
+++ b/deps/openssl/openssl/test/v3-cert1.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx
+NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz
+dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw
+ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu
+ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2
+ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp
+miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C
+AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK
+Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x
+DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR
+MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB
+AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21
+X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3
+WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/test/v3-cert2.pem b/deps/openssl/openssl/test/v3-cert2.pem
new file mode 100644
index 000000000..de0723ff8
--- /dev/null
+++ b/deps/openssl/openssl/test/v3-cert2.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD
+YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0
+ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu
+dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1
+WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV
+BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx
+FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA
+6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT
+G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ
+YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm
+b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc
+F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz
+lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap
+jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU=
+-----END CERTIFICATE-----
diff --git a/deps/openssl/openssl/test/wp_test.c b/deps/openssl/openssl/test/wp_test.c
new file mode 100644
index 000000000..c68c2c62c
--- /dev/null
+++ b/deps/openssl/openssl/test/wp_test.c
@@ -0,0 +1,228 @@
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
+ * ====================================================================
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <openssl/whrlpool.h>
+#include <openssl/crypto.h>
+
+#if defined(OPENSSL_NO_WHIRLPOOL)
+int main(int argc, char *argv[])
+{
+ printf("No Whirlpool support\n");
+ return(0);
+}
+#else
+
+/* ISO/IEC 10118-3 test vector set */
+unsigned char iso_test_1[WHIRLPOOL_DIGEST_LENGTH] = {
+ 0x19,0xFA,0x61,0xD7,0x55,0x22,0xA4,0x66,
+ 0x9B,0x44,0xE3,0x9C,0x1D,0x2E,0x17,0x26,
+ 0xC5,0x30,0x23,0x21,0x30,0xD4,0x07,0xF8,
+ 0x9A,0xFE,0xE0,0x96,0x49,0x97,0xF7,0xA7,
+ 0x3E,0x83,0xBE,0x69,0x8B,0x28,0x8F,0xEB,
+ 0xCF,0x88,0xE3,0xE0,0x3C,0x4F,0x07,0x57,
+ 0xEA,0x89,0x64,0xE5,0x9B,0x63,0xD9,0x37,
+ 0x08,0xB1,0x38,0xCC,0x42,0xA6,0x6E,0xB3 };
+
+unsigned char iso_test_2[WHIRLPOOL_DIGEST_LENGTH] = {
+ 0x8A,0xCA,0x26,0x02,0x79,0x2A,0xEC,0x6F,
+ 0x11,0xA6,0x72,0x06,0x53,0x1F,0xB7,0xD7,
+ 0xF0,0xDF,0xF5,0x94,0x13,0x14,0x5E,0x69,
+ 0x73,0xC4,0x50,0x01,0xD0,0x08,0x7B,0x42,
+ 0xD1,0x1B,0xC6,0x45,0x41,0x3A,0xEF,0xF6,
+ 0x3A,0x42,0x39,0x1A,0x39,0x14,0x5A,0x59,
+ 0x1A,0x92,0x20,0x0D,0x56,0x01,0x95,0xE5,
+ 0x3B,0x47,0x85,0x84,0xFD,0xAE,0x23,0x1A };
+
+unsigned char iso_test_3[WHIRLPOOL_DIGEST_LENGTH] = {
+ 0x4E,0x24,0x48,0xA4,0xC6,0xF4,0x86,0xBB,
+ 0x16,0xB6,0x56,0x2C,0x73,0xB4,0x02,0x0B,
+ 0xF3,0x04,0x3E,0x3A,0x73,0x1B,0xCE,0x72,
+ 0x1A,0xE1,0xB3,0x03,0xD9,0x7E,0x6D,0x4C,
+ 0x71,0x81,0xEE,0xBD,0xB6,0xC5,0x7E,0x27,
+ 0x7D,0x0E,0x34,0x95,0x71,0x14,0xCB,0xD6,
+ 0xC7,0x97,0xFC,0x9D,0x95,0xD8,0xB5,0x82,
+ 0xD2,0x25,0x29,0x20,0x76,0xD4,0xEE,0xF5 };
+
+unsigned char iso_test_4[WHIRLPOOL_DIGEST_LENGTH] = {
+ 0x37,0x8C,0x84,0xA4,0x12,0x6E,0x2D,0xC6,
+ 0xE5,0x6D,0xCC,0x74,0x58,0x37,0x7A,0xAC,
+ 0x83,0x8D,0x00,0x03,0x22,0x30,0xF5,0x3C,
+ 0xE1,0xF5,0x70,0x0C,0x0F,0xFB,0x4D,0x3B,
+ 0x84,0x21,0x55,0x76,0x59,0xEF,0x55,0xC1,
+ 0x06,0xB4,0xB5,0x2A,0xC5,0xA4,0xAA,0xA6,
+ 0x92,0xED,0x92,0x00,0x52,0x83,0x8F,0x33,
+ 0x62,0xE8,0x6D,0xBD,0x37,0xA8,0x90,0x3E };
+
+unsigned char iso_test_5[WHIRLPOOL_DIGEST_LENGTH] = {
+ 0xF1,0xD7,0x54,0x66,0x26,0x36,0xFF,0xE9,
+ 0x2C,0x82,0xEB,0xB9,0x21,0x2A,0x48,0x4A,
+ 0x8D,0x38,0x63,0x1E,0xAD,0x42,0x38,0xF5,
+ 0x44,0x2E,0xE1,0x3B,0x80,0x54,0xE4,0x1B,
+ 0x08,0xBF,0x2A,0x92,0x51,0xC3,0x0B,0x6A,
+ 0x0B,0x8A,0xAE,0x86,0x17,0x7A,0xB4,0xA6,
+ 0xF6,0x8F,0x67,0x3E,0x72,0x07,0x86,0x5D,
+ 0x5D,0x98,0x19,0xA3,0xDB,0xA4,0xEB,0x3B };
+
+unsigned char iso_test_6[WHIRLPOOL_DIGEST_LENGTH] = {
+ 0xDC,0x37,0xE0,0x08,0xCF,0x9E,0xE6,0x9B,
+ 0xF1,0x1F,0x00,0xED,0x9A,0xBA,0x26,0x90,
+ 0x1D,0xD7,0xC2,0x8C,0xDE,0xC0,0x66,0xCC,
+ 0x6A,0xF4,0x2E,0x40,0xF8,0x2F,0x3A,0x1E,
+ 0x08,0xEB,0xA2,0x66,0x29,0x12,0x9D,0x8F,
+ 0xB7,0xCB,0x57,0x21,0x1B,0x92,0x81,0xA6,
+ 0x55,0x17,0xCC,0x87,0x9D,0x7B,0x96,0x21,
+ 0x42,0xC6,0x5F,0x5A,0x7A,0xF0,0x14,0x67 };
+
+unsigned char iso_test_7[WHIRLPOOL_DIGEST_LENGTH] = {
+ 0x46,0x6E,0xF1,0x8B,0xAB,0xB0,0x15,0x4D,
+ 0x25,0xB9,0xD3,0x8A,0x64,0x14,0xF5,0xC0,
+ 0x87,0x84,0x37,0x2B,0xCC,0xB2,0x04,0xD6,
+ 0x54,0x9C,0x4A,0xFA,0xDB,0x60,0x14,0x29,
+ 0x4D,0x5B,0xD8,0xDF,0x2A,0x6C,0x44,0xE5,
+ 0x38,0xCD,0x04,0x7B,0x26,0x81,0xA5,0x1A,
+ 0x2C,0x60,0x48,0x1E,0x88,0xC5,0xA2,0x0B,
+ 0x2C,0x2A,0x80,0xCF,0x3A,0x9A,0x08,0x3B };
+
+unsigned char iso_test_8[WHIRLPOOL_DIGEST_LENGTH] = {
+ 0x2A,0x98,0x7E,0xA4,0x0F,0x91,0x70,0x61,
+ 0xF5,0xD6,0xF0,0xA0,0xE4,0x64,0x4F,0x48,
+ 0x8A,0x7A,0x5A,0x52,0xDE,0xEE,0x65,0x62,
+ 0x07,0xC5,0x62,0xF9,0x88,0xE9,0x5C,0x69,
+ 0x16,0xBD,0xC8,0x03,0x1B,0xC5,0xBE,0x1B,
+ 0x7B,0x94,0x76,0x39,0xFE,0x05,0x0B,0x56,
+ 0x93,0x9B,0xAA,0xA0,0xAD,0xFF,0x9A,0xE6,
+ 0x74,0x5B,0x7B,0x18,0x1C,0x3B,0xE3,0xFD };
+
+unsigned char iso_test_9[WHIRLPOOL_DIGEST_LENGTH] = {
+ 0x0C,0x99,0x00,0x5B,0xEB,0x57,0xEF,0xF5,
+ 0x0A,0x7C,0xF0,0x05,0x56,0x0D,0xDF,0x5D,
+ 0x29,0x05,0x7F,0xD8,0x6B,0x20,0xBF,0xD6,
+ 0x2D,0xEC,0xA0,0xF1,0xCC,0xEA,0x4A,0xF5,
+ 0x1F,0xC1,0x54,0x90,0xED,0xDC,0x47,0xAF,
+ 0x32,0xBB,0x2B,0x66,0xC3,0x4F,0xF9,0xAD,
+ 0x8C,0x60,0x08,0xAD,0x67,0x7F,0x77,0x12,
+ 0x69,0x53,0xB2,0x26,0xE4,0xED,0x8B,0x01 };
+
+int main (int argc,char *argv[])
+{ unsigned char md[WHIRLPOOL_DIGEST_LENGTH];
+ int i;
+ WHIRLPOOL_CTX ctx;
+
+#ifdef OPENSSL_IA32_SSE2
+ /* Alternative to this is to call OpenSSL_add_all_algorithms...
+ * The below code is retained exclusively for debugging purposes. */
+ { char *env;
+
+ if ((env=getenv("OPENSSL_ia32cap")))
+ OPENSSL_ia32cap = strtoul (env,NULL,0);
+ }
+#endif
+
+ fprintf(stdout,"Testing Whirlpool ");
+
+ WHIRLPOOL("",0,md);
+ if (memcmp(md,iso_test_1,sizeof(iso_test_1)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 1 of 9 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ WHIRLPOOL("a",1,md);
+ if (memcmp(md,iso_test_2,sizeof(iso_test_2)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 2 of 9 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ WHIRLPOOL("abc",3,md);
+ if (memcmp(md,iso_test_3,sizeof(iso_test_3)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 3 of 9 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ WHIRLPOOL("message digest",14,md);
+ if (memcmp(md,iso_test_4,sizeof(iso_test_4)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 4 of 9 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ WHIRLPOOL("abcdefghijklmnopqrstuvwxyz",26,md);
+ if (memcmp(md,iso_test_5,sizeof(iso_test_5)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 5 of 9 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ WHIRLPOOL( "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789",62,md);
+ if (memcmp(md,iso_test_6,sizeof(iso_test_6)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 6 of 9 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ WHIRLPOOL( "1234567890""1234567890""1234567890""1234567890"
+ "1234567890""1234567890""1234567890""1234567890",80,md);
+ if (memcmp(md,iso_test_7,sizeof(iso_test_7)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 7 of 9 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ WHIRLPOOL("abcdbcdecdefdefgefghfghighijhijk",32,md);
+ if (memcmp(md,iso_test_8,sizeof(iso_test_8)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 8 of 9 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ WHIRLPOOL_Init (&ctx);
+ for (i=0;i<1000000;i+=288)
+ WHIRLPOOL_Update (&ctx, "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+ "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
+ (1000000-i)<288?1000000-i:288);
+ WHIRLPOOL_Final (md,&ctx);
+ if (memcmp(md,iso_test_9,sizeof(iso_test_9)))
+ { fflush(stdout);
+ fprintf(stderr,"\nTEST 9 of 9 failed.\n");
+ return 1;
+ }
+ else
+ fprintf(stdout,"."); fflush(stdout);
+
+ fprintf(stdout," passed.\n"); fflush(stdout);
+
+ return 0;
+}
+#endif
diff --git a/deps/openssl/openssl/util/copy.pl b/deps/openssl/openssl/util/copy.pl
index e20b45530..eba6d5815 100644
--- a/deps/openssl/openssl/util/copy.pl
+++ b/deps/openssl/openssl/util/copy.pl
@@ -8,9 +8,16 @@ use Fcntl;
# Perl script 'copy' comment. On Windows the built in "copy" command also
# copies timestamps: this messes up Makefile dependencies.
+my $stripcr = 0;
+
my $arg;
foreach $arg (@ARGV) {
+ if ($arg eq "-stripcr")
+ {
+ $stripcr = 1;
+ next;
+ }
$arg =~ s|\\|/|g; # compensate for bug/feature in cygwin glob...
foreach (glob $arg)
{
@@ -49,6 +56,10 @@ foreach (@filelist)
|| die "Can't Open $dfile";
while (sysread IN, $buf, 10240)
{
+ if ($stripcr)
+ {
+ $buf =~ tr/\015//d;
+ }
syswrite(OUT, $buf, length($buf));
}
close(IN);
diff --git a/deps/openssl/openssl/util/cygwin.sh b/deps/openssl/openssl/util/cygwin.sh
index d6228521e..cfdb04d2a 100755
--- a/deps/openssl/openssl/util/cygwin.sh
+++ b/deps/openssl/openssl/util/cygwin.sh
@@ -11,6 +11,7 @@ CONFIG_OPTIONS="--prefix=/usr shared zlib no-idea no-rc5"
INSTALL_PREFIX=/tmp/install/INSTALL
VERSION=
+SHLIB_VERSION_NUMBER=
SUBVERSION=$1
function cleanup()
@@ -28,6 +29,13 @@ function get_openssl_version()
echo " Check value of variable VERSION in Makefile."
exit 1
fi
+ eval `grep '^SHLIB_VERSION_NUMBER=' Makefile`
+ if [ -z "${SHLIB_VERSION_NUMBER}" ]
+ then
+ echo "Error: Couldn't retrieve OpenSSL shared lib version from Makefile."
+ echo " Check value of variable SHLIB_VERSION_NUMBER in Makefile."
+ exit 1
+ fi
}
function base_install()
@@ -124,7 +132,7 @@ strip usr/bin/*.exe usr/bin/*.dll usr/lib/engines/*.so
chmod u-w usr/lib/engines/*.so
# Runtime package
-tar cjf libopenssl${VERSION//[!0-9]/}-${VERSION}-${SUBVERSION}.tar.bz2 \
+tar cjf libopenssl${SHLIB_VERSION_NUMBER//[!0-9]/}-${VERSION}-${SUBVERSION}.tar.bz2 \
usr/bin/cyg*dll
# Base package
find etc usr/bin/openssl.exe usr/bin/c_rehash usr/lib/engines usr/share/doc \
@@ -139,7 +147,7 @@ tar cjfT openssl-devel-${VERSION}-${SUBVERSION}.tar.bz2 -
ls -l openssl-${VERSION}-${SUBVERSION}.tar.bz2
ls -l openssl-devel-${VERSION}-${SUBVERSION}.tar.bz2
-ls -l libopenssl${VERSION//[!0-9]/}-${VERSION}-${SUBVERSION}.tar.bz2
+ls -l libopenssl${SHLIB_VERSION_NUMBER//[!0-9]/}-${VERSION}-${SUBVERSION}.tar.bz2
cleanup
diff --git a/deps/openssl/openssl/util/libeay.num b/deps/openssl/openssl/util/libeay.num
index b23619f20..6debdb60a 100755
--- a/deps/openssl/openssl/util/libeay.num
+++ b/deps/openssl/openssl/util/libeay.num
@@ -1050,7 +1050,7 @@ ASN1_TYPE_get_octetstring 1077 EXIST::FUNCTION:
ASN1_TYPE_set_int_octetstring 1078 EXIST::FUNCTION:
ASN1_TYPE_set_octetstring 1079 EXIST::FUNCTION:
ASN1_UTCTIME_set_string 1080 EXIST::FUNCTION:
-ERR_add_error_data 1081 EXIST::FUNCTION:BIO
+ERR_add_error_data 1081 EXIST::FUNCTION:
ERR_set_error_data 1082 EXIST::FUNCTION:
EVP_CIPHER_asn1_to_param 1083 EXIST::FUNCTION:
EVP_CIPHER_param_to_asn1 1084 EXIST::FUNCTION:
@@ -2808,7 +2808,7 @@ FIPS_corrupt_rsa 3249 NOEXIST::FUNCTION:
FIPS_selftest_des 3250 NOEXIST::FUNCTION:
EVP_aes_128_cfb1 3251 EXIST::FUNCTION:AES
EVP_aes_192_cfb8 3252 EXIST::FUNCTION:AES
-FIPS_mode_set 3253 NOEXIST::FUNCTION:
+FIPS_mode_set 3253 EXIST::FUNCTION:
FIPS_selftest_dsa 3254 NOEXIST::FUNCTION:
EVP_aes_256_cfb8 3255 EXIST::FUNCTION:AES
FIPS_allow_md5 3256 NOEXIST::FUNCTION:
@@ -2838,23 +2838,23 @@ AES_cfb1_encrypt 3279 EXIST::FUNCTION:AES
EVP_des_ede3_cfb1 3280 EXIST::FUNCTION:DES
FIPS_rand_check 3281 NOEXIST::FUNCTION:
FIPS_md5_allowed 3282 NOEXIST::FUNCTION:
-FIPS_mode 3283 NOEXIST::FUNCTION:
+FIPS_mode 3283 EXIST::FUNCTION:
FIPS_selftest_failed 3284 NOEXIST::FUNCTION:
sk_is_sorted 3285 EXIST::FUNCTION:
X509_check_ca 3286 EXIST::FUNCTION:
-private_idea_set_encrypt_key 3287 NOEXIST::FUNCTION:
+private_idea_set_encrypt_key 3287 EXIST:OPENSSL_FIPS:FUNCTION:IDEA
HMAC_CTX_set_flags 3288 EXIST::FUNCTION:HMAC
-private_SHA_Init 3289 NOEXIST::FUNCTION:
-private_CAST_set_key 3290 NOEXIST::FUNCTION:
-private_RIPEMD160_Init 3291 NOEXIST::FUNCTION:
+private_SHA_Init 3289 EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA0
+private_CAST_set_key 3290 EXIST:OPENSSL_FIPS:FUNCTION:CAST
+private_RIPEMD160_Init 3291 EXIST:OPENSSL_FIPS:FUNCTION:RIPEMD
private_RC5_32_set_key 3292 NOEXIST::FUNCTION:
-private_MD5_Init 3293 NOEXIST::FUNCTION:
-private_RC4_set_key 3294 NOEXIST::FUNCTION:
-private_MDC2_Init 3295 NOEXIST::FUNCTION:
-private_RC2_set_key 3296 NOEXIST::FUNCTION:
-private_MD4_Init 3297 NOEXIST::FUNCTION:
-private_BF_set_key 3298 NOEXIST::FUNCTION:
-private_MD2_Init 3299 NOEXIST::FUNCTION:
+private_MD5_Init 3293 EXIST:OPENSSL_FIPS:FUNCTION:MD5
+private_RC4_set_key 3294 EXIST::FUNCTION:RC4
+private_MDC2_Init 3295 EXIST:OPENSSL_FIPS:FUNCTION:MDC2
+private_RC2_set_key 3296 EXIST:OPENSSL_FIPS:FUNCTION:RC2
+private_MD4_Init 3297 EXIST:OPENSSL_FIPS:FUNCTION:MD4
+private_BF_set_key 3298 EXIST:OPENSSL_FIPS:FUNCTION:BF
+private_MD2_Init 3299 EXIST:OPENSSL_FIPS:FUNCTION:MD2
d2i_PROXY_CERT_INFO_EXTENSION 3300 EXIST::FUNCTION:
PROXY_POLICY_it 3301 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
PROXY_POLICY_it 3301 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
@@ -2882,7 +2882,7 @@ RSA_verify_PKCS1_PSS 3321 EXIST::FUNCTION:RSA
RSA_padding_add_X931 3322 EXIST::FUNCTION:RSA
RSA_padding_add_PKCS1_PSS 3323 EXIST::FUNCTION:RSA
PKCS1_MGF1 3324 EXIST::FUNCTION:RSA
-BN_X931_generate_Xpq 3325 NOEXIST::FUNCTION:
+BN_X931_generate_Xpq 3325 EXIST::FUNCTION:
RSA_X931_generate_key 3326 NOEXIST::FUNCTION:
BN_X931_derive_prime 3327 NOEXIST::FUNCTION:
BN_X931_generate_prime 3328 NOEXIST::FUNCTION:
@@ -2906,7 +2906,7 @@ STORE_parse_attrs_start 3343 NOEXIST::FUNCTION:
POLICY_CONSTRAINTS_free 3344 EXIST::FUNCTION:
EVP_PKEY_add1_attr_by_NID 3345 EXIST::FUNCTION:
BN_nist_mod_192 3346 EXIST::FUNCTION:
-EC_GROUP_get_trinomial_basis 3347 EXIST::FUNCTION:EC
+EC_GROUP_get_trinomial_basis 3347 EXIST::FUNCTION:EC,EC2M
STORE_set_method 3348 NOEXIST::FUNCTION:
GENERAL_SUBTREE_free 3349 EXIST::FUNCTION:
NAME_CONSTRAINTS_it 3350 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
@@ -2921,14 +2921,14 @@ SHA512_Update 3356 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
i2d_ECPrivateKey 3357 EXIST::FUNCTION:EC
BN_get0_nist_prime_192 3358 EXIST::FUNCTION:
STORE_modify_certificate 3359 NOEXIST::FUNCTION:
-EC_POINT_set_affine_coordinates_GF2m 3360 EXIST:!VMS:FUNCTION:EC
-EC_POINT_set_affine_coords_GF2m 3360 EXIST:VMS:FUNCTION:EC
-BN_GF2m_mod_exp_arr 3361 EXIST::FUNCTION:
+EC_POINT_set_affine_coordinates_GF2m 3360 EXIST:!VMS:FUNCTION:EC,EC2M
+EC_POINT_set_affine_coords_GF2m 3360 EXIST:VMS:FUNCTION:EC,EC2M
+BN_GF2m_mod_exp_arr 3361 EXIST::FUNCTION:EC2M
STORE_ATTR_INFO_modify_number 3362 NOEXIST::FUNCTION:
X509_keyid_get0 3363 EXIST::FUNCTION:
ENGINE_load_gmp 3364 EXIST::FUNCTION:ENGINE,GMP,STATIC_ENGINE
pitem_new 3365 EXIST::FUNCTION:
-BN_GF2m_mod_mul_arr 3366 EXIST::FUNCTION:
+BN_GF2m_mod_mul_arr 3366 EXIST::FUNCTION:EC2M
STORE_list_public_key_endp 3367 NOEXIST::FUNCTION:
o2i_ECPublicKey 3368 EXIST::FUNCTION:EC
EC_KEY_copy 3369 EXIST::FUNCTION:EC
@@ -2945,7 +2945,7 @@ X509_VERIFY_PARAM_inherit 3378 EXIST::FUNCTION:
EC_POINT_point2bn 3379 EXIST::FUNCTION:EC
STORE_ATTR_INFO_set_dn 3380 NOEXIST::FUNCTION:
X509_policy_tree_get0_policies 3381 EXIST::FUNCTION:
-EC_GROUP_new_curve_GF2m 3382 EXIST::FUNCTION:EC
+EC_GROUP_new_curve_GF2m 3382 EXIST::FUNCTION:EC,EC2M
STORE_destroy_method 3383 NOEXIST::FUNCTION:
ENGINE_unregister_STORE 3384 EXIST::FUNCTION:ENGINE
EVP_PKEY_get1_EC_KEY 3385 EXIST::FUNCTION:EC
@@ -2961,7 +2961,7 @@ ENGINE_get_static_state 3393 EXIST::FUNCTION:ENGINE
pqueue_iterator 3394 EXIST::FUNCTION:
ECDSA_SIG_new 3395 EXIST::FUNCTION:ECDSA
OPENSSL_DIR_end 3396 EXIST::FUNCTION:
-BN_GF2m_mod_sqr 3397 EXIST::FUNCTION:
+BN_GF2m_mod_sqr 3397 EXIST::FUNCTION:EC2M
EC_POINT_bn2point 3398 EXIST::FUNCTION:EC
X509_VERIFY_PARAM_set_depth 3399 EXIST::FUNCTION:
EC_KEY_set_asn1_flag 3400 EXIST::FUNCTION:EC
@@ -2974,7 +2974,7 @@ EC_GROUP_get_point_conv_form 3405 EXIST:VMS:FUNCTION:EC
STORE_method_set_store_function 3406 NOEXIST::FUNCTION:
STORE_ATTR_INFO_in 3407 NOEXIST::FUNCTION:
PEM_read_bio_ECPKParameters 3408 EXIST::FUNCTION:EC
-EC_GROUP_get_pentanomial_basis 3409 EXIST::FUNCTION:EC
+EC_GROUP_get_pentanomial_basis 3409 EXIST::FUNCTION:EC,EC2M
EVP_PKEY_add1_attr_by_txt 3410 EXIST::FUNCTION:
BN_BLINDING_set_flags 3411 EXIST::FUNCTION:
X509_VERIFY_PARAM_set1_policies 3412 EXIST::FUNCTION:
@@ -2982,10 +2982,10 @@ X509_VERIFY_PARAM_set1_name 3413 EXIST::FUNCTION:
X509_VERIFY_PARAM_set_purpose 3414 EXIST::FUNCTION:
STORE_get_number 3415 NOEXIST::FUNCTION:
ECDSA_sign_setup 3416 EXIST::FUNCTION:ECDSA
-BN_GF2m_mod_solve_quad_arr 3417 EXIST::FUNCTION:
+BN_GF2m_mod_solve_quad_arr 3417 EXIST::FUNCTION:EC2M
EC_KEY_up_ref 3418 EXIST::FUNCTION:EC
POLICY_MAPPING_free 3419 EXIST::FUNCTION:
-BN_GF2m_mod_div 3420 EXIST::FUNCTION:
+BN_GF2m_mod_div 3420 EXIST::FUNCTION:EC2M
X509_VERIFY_PARAM_set_flags 3421 EXIST::FUNCTION:
EC_KEY_free 3422 EXIST::FUNCTION:EC
STORE_meth_set_list_next_fn 3423 NOEXIST::FUNCTION:
@@ -2999,7 +2999,7 @@ STORE_method_set_list_end_function 3427 NOEXIST::FUNCTION:
pqueue_print 3428 EXIST::FUNCTION:
EC_GROUP_have_precompute_mult 3429 EXIST::FUNCTION:EC
EC_KEY_print_fp 3430 EXIST::FUNCTION:EC,FP_API
-BN_GF2m_mod_arr 3431 EXIST::FUNCTION:
+BN_GF2m_mod_arr 3431 EXIST::FUNCTION:EC2M
PEM_write_bio_X509_CERT_PAIR 3432 EXIST::FUNCTION:
EVP_PKEY_cmp 3433 EXIST::FUNCTION:
X509_policy_level_node_count 3434 EXIST::FUNCTION:
@@ -3020,7 +3020,7 @@ X509_policy_node_get0_qualifiers 3448 EXIST:!VMS:FUNCTION:
X509_pcy_node_get0_qualifiers 3448 EXIST:VMS:FUNCTION:
STORE_list_crl_end 3449 NOEXIST::FUNCTION:
EVP_PKEY_set1_EC_KEY 3450 EXIST::FUNCTION:EC
-BN_GF2m_mod_sqrt_arr 3451 EXIST::FUNCTION:
+BN_GF2m_mod_sqrt_arr 3451 EXIST::FUNCTION:EC2M
i2d_ECPrivateKey_bio 3452 EXIST::FUNCTION:BIO,EC
ECPKParameters_print_fp 3453 EXIST::FUNCTION:EC,FP_API
pqueue_find 3454 EXIST::FUNCTION:
@@ -3037,7 +3037,7 @@ PKCS12_add_safes 3464 EXIST::FUNCTION:
BN_BLINDING_convert_ex 3465 EXIST::FUNCTION:
X509_policy_tree_free 3466 EXIST::FUNCTION:
OPENSSL_ia32cap_loc 3467 EXIST::FUNCTION:
-BN_GF2m_poly2arr 3468 EXIST::FUNCTION:
+BN_GF2m_poly2arr 3468 EXIST::FUNCTION:EC2M
STORE_ctrl 3469 NOEXIST::FUNCTION:
STORE_ATTR_INFO_compare 3470 NOEXIST::FUNCTION:
BN_get0_nist_prime_224 3471 EXIST::FUNCTION:
@@ -3061,7 +3061,7 @@ STORE_method_set_delete_function 3486 NOEXIST::FUNCTION:
STORE_list_certificate_next 3487 NOEXIST::FUNCTION:
ASN1_generate_nconf 3488 EXIST::FUNCTION:
BUF_memdup 3489 EXIST::FUNCTION:
-BN_GF2m_mod_mul 3490 EXIST::FUNCTION:
+BN_GF2m_mod_mul 3490 EXIST::FUNCTION:EC2M
STORE_meth_get_list_next_fn 3491 NOEXIST::FUNCTION:
STORE_method_get_list_next_function 3491 NOEXIST::FUNCTION:
STORE_ATTR_INFO_get0_dn 3492 NOEXIST::FUNCTION:
@@ -3072,7 +3072,7 @@ STORE_ATTR_INFO_free 3496 NOEXIST::FUNCTION:
STORE_get_private_key 3497 NOEXIST::FUNCTION:
EVP_PKEY_get_attr_count 3498 EXIST::FUNCTION:
STORE_ATTR_INFO_new 3499 NOEXIST::FUNCTION:
-EC_GROUP_get_curve_GF2m 3500 EXIST::FUNCTION:EC
+EC_GROUP_get_curve_GF2m 3500 EXIST::FUNCTION:EC,EC2M
STORE_meth_set_revoke_fn 3501 NOEXIST::FUNCTION:
STORE_method_set_revoke_function 3501 NOEXIST::FUNCTION:
STORE_store_number 3502 NOEXIST::FUNCTION:
@@ -3088,7 +3088,7 @@ BIO_dump_indent_fp 3511 EXIST::FUNCTION:FP_API
EC_KEY_set_group 3512 EXIST::FUNCTION:EC
BUF_strndup 3513 EXIST::FUNCTION:
STORE_list_certificate_start 3514 NOEXIST::FUNCTION:
-BN_GF2m_mod 3515 EXIST::FUNCTION:
+BN_GF2m_mod 3515 EXIST::FUNCTION:EC2M
X509_REQ_check_private_key 3516 EXIST::FUNCTION:
EC_GROUP_get_seed_len 3517 EXIST::FUNCTION:EC
ERR_load_STORE_strings 3518 NOEXIST::FUNCTION:
@@ -3117,19 +3117,19 @@ STORE_method_set_get_function 3536 NOEXIST::FUNCTION:
STORE_modify_number 3537 NOEXIST::FUNCTION:
STORE_method_get_store_function 3538 NOEXIST::FUNCTION:
STORE_store_private_key 3539 NOEXIST::FUNCTION:
-BN_GF2m_mod_sqr_arr 3540 EXIST::FUNCTION:
+BN_GF2m_mod_sqr_arr 3540 EXIST::FUNCTION:EC2M
RSA_setup_blinding 3541 EXIST::FUNCTION:RSA
BIO_s_datagram 3542 EXIST::FUNCTION:DGRAM
STORE_Memory 3543 NOEXIST::FUNCTION:
sk_find_ex 3544 EXIST::FUNCTION:
-EC_GROUP_set_curve_GF2m 3545 EXIST::FUNCTION:EC
+EC_GROUP_set_curve_GF2m 3545 EXIST::FUNCTION:EC,EC2M
ENGINE_set_default_ECDSA 3546 EXIST::FUNCTION:ENGINE
POLICY_CONSTRAINTS_new 3547 EXIST::FUNCTION:
-BN_GF2m_mod_sqrt 3548 EXIST::FUNCTION:
+BN_GF2m_mod_sqrt 3548 EXIST::FUNCTION:EC2M
ECDH_set_default_method 3549 EXIST::FUNCTION:ECDH
EC_KEY_generate_key 3550 EXIST::FUNCTION:EC
SHA384_Update 3551 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
-BN_GF2m_arr2poly 3552 EXIST::FUNCTION:
+BN_GF2m_arr2poly 3552 EXIST::FUNCTION:EC2M
STORE_method_get_get_function 3553 NOEXIST::FUNCTION:
STORE_meth_set_cleanup_fn 3554 NOEXIST::FUNCTION:
STORE_method_set_cleanup_function 3554 NOEXIST::FUNCTION:
@@ -3154,7 +3154,7 @@ EC_GROUP_get_degree 3570 EXIST::FUNCTION:EC
ASN1_generate_v3 3571 EXIST::FUNCTION:
STORE_ATTR_INFO_modify_cstr 3572 NOEXIST::FUNCTION:
X509_policy_tree_level_count 3573 EXIST::FUNCTION:
-BN_GF2m_add 3574 EXIST::FUNCTION:
+BN_GF2m_add 3574 EXIST::FUNCTION:EC2M
EC_KEY_get0_group 3575 EXIST::FUNCTION:EC
STORE_generate_crl 3576 NOEXIST::FUNCTION:
STORE_store_public_key 3577 NOEXIST::FUNCTION:
@@ -3179,8 +3179,8 @@ STORE_store_certificate 3593 NOEXIST::FUNCTION:
OBJ_bsearch_ex 3594 NOEXIST::FUNCTION:
X509_STORE_CTX_set_default 3595 EXIST::FUNCTION:
STORE_ATTR_INFO_set_sha1str 3596 NOEXIST::FUNCTION:
-BN_GF2m_mod_inv 3597 EXIST::FUNCTION:
-BN_GF2m_mod_exp 3598 EXIST::FUNCTION:
+BN_GF2m_mod_inv 3597 EXIST::FUNCTION:EC2M
+BN_GF2m_mod_exp 3598 EXIST::FUNCTION:EC2M
STORE_modify_public_key 3599 NOEXIST::FUNCTION:
STORE_meth_get_list_start_fn 3600 NOEXIST::FUNCTION:
STORE_method_get_list_start_function 3600 NOEXIST::FUNCTION:
@@ -3188,7 +3188,7 @@ EC_GROUP_get0_seed 3601 EXIST::FUNCTION:EC
STORE_store_arbitrary 3602 NOEXIST::FUNCTION:
STORE_meth_set_unlock_store_fn 3603 NOEXIST::FUNCTION:
STORE_method_set_unlock_store_function 3603 NOEXIST::FUNCTION:
-BN_GF2m_mod_div_arr 3604 EXIST::FUNCTION:
+BN_GF2m_mod_div_arr 3604 EXIST::FUNCTION:EC2M
ENGINE_set_ECDSA 3605 EXIST::FUNCTION:ENGINE
STORE_create_method 3606 NOEXIST::FUNCTION:
ECPKParameters_print 3607 EXIST::FUNCTION:BIO,EC
@@ -3211,8 +3211,8 @@ EC_KEY_get_enc_flags 3622 EXIST::FUNCTION:EC
ASN1_const_check_infinite_end 3623 EXIST::FUNCTION:
EVP_PKEY_delete_attr 3624 EXIST::FUNCTION:
ECDSA_set_default_method 3625 EXIST::FUNCTION:ECDSA
-EC_POINT_set_compressed_coordinates_GF2m 3626 EXIST:!VMS:FUNCTION:EC
-EC_POINT_set_compr_coords_GF2m 3626 EXIST:VMS:FUNCTION:EC
+EC_POINT_set_compressed_coordinates_GF2m 3626 EXIST:!VMS:FUNCTION:EC,EC2M
+EC_POINT_set_compr_coords_GF2m 3626 EXIST:VMS:FUNCTION:EC,EC2M
EC_GROUP_cmp 3627 EXIST::FUNCTION:EC
STORE_revoke_certificate 3628 NOEXIST::FUNCTION:
BN_get0_nist_prime_256 3629 EXIST::FUNCTION:
@@ -3241,7 +3241,7 @@ POLICY_CONSTRAINTS_it 3649 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTI
STORE_get_ex_new_index 3650 NOEXIST::FUNCTION:
EVP_PKEY_get_attr_by_OBJ 3651 EXIST::FUNCTION:
X509_VERIFY_PARAM_add0_policy 3652 EXIST::FUNCTION:
-BN_GF2m_mod_solve_quad 3653 EXIST::FUNCTION:
+BN_GF2m_mod_solve_quad 3653 EXIST::FUNCTION:EC2M
SHA256 3654 EXIST::FUNCTION:SHA,SHA256
i2d_ECPrivateKey_fp 3655 EXIST::FUNCTION:EC,FP_API
X509_policy_tree_get0_user_policies 3656 EXIST:!VMS:FUNCTION:
@@ -3249,8 +3249,8 @@ X509_pcy_tree_get0_usr_policies 3656 EXIST:VMS:FUNCTION:
OPENSSL_DIR_read 3657 EXIST::FUNCTION:
ENGINE_register_all_ECDSA 3658 EXIST::FUNCTION:ENGINE
X509_VERIFY_PARAM_lookup 3659 EXIST::FUNCTION:
-EC_POINT_get_affine_coordinates_GF2m 3660 EXIST:!VMS:FUNCTION:EC
-EC_POINT_get_affine_coords_GF2m 3660 EXIST:VMS:FUNCTION:EC
+EC_POINT_get_affine_coordinates_GF2m 3660 EXIST:!VMS:FUNCTION:EC,EC2M
+EC_POINT_get_affine_coords_GF2m 3660 EXIST:VMS:FUNCTION:EC,EC2M
EC_GROUP_dup 3661 EXIST::FUNCTION:EC
ENGINE_get_default_ECDSA 3662 EXIST::FUNCTION:ENGINE
EC_KEY_new 3663 EXIST::FUNCTION:EC
@@ -3332,7 +3332,7 @@ STORE_list_certificate_end 3734 NOEXIST::FUNCTION:
STORE_get_crl 3735 NOEXIST::FUNCTION:
X509_POLICY_NODE_print 3736 EXIST::FUNCTION:
SHA384_Init 3737 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
-EC_GF2m_simple_method 3738 EXIST::FUNCTION:EC
+EC_GF2m_simple_method 3738 EXIST::FUNCTION:EC,EC2M
ECDSA_set_ex_data 3739 EXIST::FUNCTION:ECDSA
SHA384_Final 3740 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
PKCS7_set_digest 3741 EXIST::FUNCTION:
@@ -3364,7 +3364,7 @@ BIO_dump_cb 3764 EXIST::FUNCTION:
SHA256_Update 3765 EXIST::FUNCTION:SHA,SHA256
pqueue_insert 3766 EXIST::FUNCTION:
pitem_free 3767 EXIST::FUNCTION:
-BN_GF2m_mod_inv_arr 3768 EXIST::FUNCTION:
+BN_GF2m_mod_inv_arr 3768 EXIST::FUNCTION:EC2M
ENGINE_unregister_ECDSA 3769 EXIST::FUNCTION:ENGINE
BN_BLINDING_set_thread_id 3770 EXIST::FUNCTION:DEPRECATED
get_rfc3526_prime_8192 3771 EXIST::FUNCTION:
@@ -3510,6 +3510,7 @@ BIO_get_callback_arg 3902 EXIST::FUNCTION:
BIO_set_callback 3903 EXIST::FUNCTION:
d2i_ASIdOrRange 3904 EXIST::FUNCTION:RFC3779
i2d_ASIdentifiers 3905 EXIST::FUNCTION:RFC3779
+CRYPTO_memcmp 3906 EXIST::FUNCTION:
SEED_decrypt 3908 EXIST::FUNCTION:SEED
SEED_encrypt 3909 EXIST::FUNCTION:SEED
SEED_cbc_encrypt 3910 EXIST::FUNCTION:SEED
@@ -3670,7 +3671,7 @@ int_EVP_MD_set_engine_callbacks 4056 NOEXIST::FUNCTION:
int_CRYPTO_set_do_dynlock_callback 4057 NOEXIST::FUNCTION:
FIPS_rng_stick 4058 NOEXIST::FUNCTION:
EVP_CIPHER_CTX_set_flags 4059 EXIST::FUNCTION:
-BN_X931_generate_prime_ex 4060 NOEXIST::FUNCTION:
+BN_X931_generate_prime_ex 4060 EXIST::FUNCTION:
FIPS_selftest_check 4061 NOEXIST::FUNCTION:
FIPS_rand_set_dt 4062 NOEXIST::FUNCTION:
CRYPTO_dbg_pop_info 4063 NOEXIST::FUNCTION:
@@ -3687,7 +3688,7 @@ FIPS_dh_new 4073 NOEXIST::FUNCTION:
FIPS_corrupt_dsa_keygen 4074 NOEXIST::FUNCTION:
FIPS_dh_free 4075 NOEXIST::FUNCTION:
fips_pkey_signature_test 4076 NOEXIST::FUNCTION:
-EVP_add_alg_module 4077 NOEXIST::FUNCTION:
+EVP_add_alg_module 4077 EXIST::FUNCTION:
int_RAND_init_engine_callbacks 4078 NOEXIST::FUNCTION:
int_EVP_CIPHER_set_engine_callbacks 4079 NOEXIST::FUNCTION:
int_EVP_MD_init_engine_callbacks 4080 NOEXIST::FUNCTION:
@@ -3695,14 +3696,14 @@ FIPS_rand_test_mode 4081 NOEXIST::FUNCTION:
FIPS_rand_reset 4082 NOEXIST::FUNCTION:
FIPS_dsa_new 4083 NOEXIST::FUNCTION:
int_RAND_set_callbacks 4084 NOEXIST::FUNCTION:
-BN_X931_derive_prime_ex 4085 NOEXIST::FUNCTION:
+BN_X931_derive_prime_ex 4085 EXIST::FUNCTION:
int_ERR_lib_init 4086 NOEXIST::FUNCTION:
int_EVP_CIPHER_init_engine_callbacks 4087 NOEXIST::FUNCTION:
FIPS_rsa_free 4088 NOEXIST::FUNCTION:
FIPS_dsa_sig_encode 4089 NOEXIST::FUNCTION:
CRYPTO_dbg_remove_all_info 4090 NOEXIST::FUNCTION:
-OPENSSL_init 4091 NOEXIST::FUNCTION:
-private_Camellia_set_key 4092 NOEXIST::FUNCTION:
+OPENSSL_init 4091 EXIST::FUNCTION:
+private_Camellia_set_key 4092 EXIST:OPENSSL_FIPS:FUNCTION:CAMELLIA
CRYPTO_strdup 4093 EXIST::FUNCTION:
JPAKE_STEP3A_process 4094 EXIST::FUNCTION:JPAKE
JPAKE_STEP1_release 4095 EXIST::FUNCTION:JPAKE
@@ -4194,3 +4195,119 @@ OPENSSL_memcmp 4565 EXIST::FUNCTION:
OPENSSL_strncasecmp 4566 EXIST::FUNCTION:
OPENSSL_gmtime 4567 EXIST::FUNCTION:
OPENSSL_gmtime_adj 4568 EXIST::FUNCTION:
+SRP_VBASE_get_by_user 4569 EXIST::FUNCTION:SRP
+SRP_Calc_server_key 4570 EXIST::FUNCTION:SRP
+SRP_create_verifier 4571 EXIST::FUNCTION:SRP
+SRP_create_verifier_BN 4572 EXIST::FUNCTION:SRP
+SRP_Calc_u 4573 EXIST::FUNCTION:SRP
+SRP_VBASE_free 4574 EXIST::FUNCTION:SRP
+SRP_Calc_client_key 4575 EXIST::FUNCTION:SRP
+SRP_get_default_gN 4576 EXIST::FUNCTION:SRP
+SRP_Calc_x 4577 EXIST::FUNCTION:SRP
+SRP_Calc_B 4578 EXIST::FUNCTION:SRP
+SRP_VBASE_new 4579 EXIST::FUNCTION:SRP
+SRP_check_known_gN_param 4580 EXIST::FUNCTION:SRP
+SRP_Calc_A 4581 EXIST::FUNCTION:SRP
+SRP_Verify_A_mod_N 4582 EXIST::FUNCTION:SRP
+SRP_VBASE_init 4583 EXIST::FUNCTION:SRP
+SRP_Verify_B_mod_N 4584 EXIST::FUNCTION:SRP
+EC_KEY_set_public_key_affine_coordinates 4585 EXIST:!VMS:FUNCTION:EC
+EC_KEY_set_pub_key_aff_coords 4585 EXIST:VMS:FUNCTION:EC
+EVP_aes_192_ctr 4586 EXIST::FUNCTION:AES
+EVP_PKEY_meth_get0_info 4587 EXIST::FUNCTION:
+EVP_PKEY_meth_copy 4588 EXIST::FUNCTION:
+ERR_add_error_vdata 4589 EXIST::FUNCTION:
+EVP_aes_128_ctr 4590 EXIST::FUNCTION:AES
+EVP_aes_256_ctr 4591 EXIST::FUNCTION:AES
+EC_GFp_nistp224_method 4592 EXIST::FUNCTION:EC,EC_NISTP_64_GCC_128
+EC_KEY_get_flags 4593 EXIST::FUNCTION:EC
+RSA_padding_add_PKCS1_PSS_mgf1 4594 EXIST::FUNCTION:RSA
+EVP_aes_128_xts 4595 EXIST::FUNCTION:AES
+private_SHA224_Init 4596 EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA256
+private_AES_set_decrypt_key 4597 EXIST::FUNCTION:AES
+private_WHIRLPOOL_Init 4598 EXIST:OPENSSL_FIPS:FUNCTION:WHIRLPOOL
+EVP_aes_256_xts 4599 EXIST::FUNCTION:AES
+private_SHA512_Init 4600 EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA512
+EVP_aes_128_gcm 4601 EXIST::FUNCTION:AES
+EC_KEY_clear_flags 4602 EXIST::FUNCTION:EC
+EC_KEY_set_flags 4603 EXIST::FUNCTION:EC
+private_DES_set_key_unchecked 4604 EXIST:OPENSSL_FIPS:FUNCTION:DES
+EVP_aes_256_ccm 4605 EXIST::FUNCTION:AES
+private_AES_set_encrypt_key 4606 EXIST::FUNCTION:AES
+RSA_verify_PKCS1_PSS_mgf1 4607 EXIST::FUNCTION:RSA
+private_SHA1_Init 4608 EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA1
+EVP_aes_128_ccm 4609 EXIST::FUNCTION:AES
+private_SEED_set_key 4610 EXIST:OPENSSL_FIPS:FUNCTION:SEED
+EVP_aes_192_gcm 4611 EXIST::FUNCTION:AES
+X509_ALGOR_set_md 4612 EXIST::FUNCTION:
+private_SHA256_Init 4613 EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA256
+RAND_init_fips 4614 EXIST:OPENSSL_FIPS:FUNCTION:
+EVP_aes_256_gcm 4615 EXIST::FUNCTION:AES
+private_SHA384_Init 4616 EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA512
+EVP_aes_192_ccm 4617 EXIST::FUNCTION:AES
+CMAC_CTX_copy 4618 EXIST::FUNCTION:
+CMAC_CTX_free 4619 EXIST::FUNCTION:
+CMAC_CTX_get0_cipher_ctx 4620 EXIST::FUNCTION:
+CMAC_CTX_cleanup 4621 EXIST::FUNCTION:
+CMAC_Init 4622 EXIST::FUNCTION:
+CMAC_Update 4623 EXIST::FUNCTION:
+CMAC_resume 4624 EXIST::FUNCTION:
+CMAC_CTX_new 4625 EXIST::FUNCTION:
+CMAC_Final 4626 EXIST::FUNCTION:
+CRYPTO_ctr128_encrypt_ctr32 4627 EXIST::FUNCTION:
+CRYPTO_gcm128_release 4628 EXIST::FUNCTION:
+CRYPTO_ccm128_decrypt_ccm64 4629 EXIST::FUNCTION:
+CRYPTO_ccm128_encrypt 4630 EXIST::FUNCTION:
+CRYPTO_gcm128_encrypt 4631 EXIST::FUNCTION:
+CRYPTO_xts128_encrypt 4632 EXIST::FUNCTION:
+EVP_rc4_hmac_md5 4633 EXIST::FUNCTION:MD5,RC4
+CRYPTO_nistcts128_decrypt_block 4634 EXIST::FUNCTION:
+CRYPTO_gcm128_setiv 4635 EXIST::FUNCTION:
+CRYPTO_nistcts128_encrypt 4636 EXIST::FUNCTION:
+EVP_aes_128_cbc_hmac_sha1 4637 EXIST::FUNCTION:AES,SHA,SHA1
+CRYPTO_gcm128_tag 4638 EXIST::FUNCTION:
+CRYPTO_ccm128_encrypt_ccm64 4639 EXIST::FUNCTION:
+ENGINE_load_rdrand 4640 EXIST::FUNCTION:ENGINE
+CRYPTO_ccm128_setiv 4641 EXIST::FUNCTION:
+CRYPTO_nistcts128_encrypt_block 4642 EXIST::FUNCTION:
+CRYPTO_gcm128_aad 4643 EXIST::FUNCTION:
+CRYPTO_ccm128_init 4644 EXIST::FUNCTION:
+CRYPTO_nistcts128_decrypt 4645 EXIST::FUNCTION:
+CRYPTO_gcm128_new 4646 EXIST::FUNCTION:
+CRYPTO_ccm128_tag 4647 EXIST::FUNCTION:
+CRYPTO_ccm128_decrypt 4648 EXIST::FUNCTION:
+CRYPTO_ccm128_aad 4649 EXIST::FUNCTION:
+CRYPTO_gcm128_init 4650 EXIST::FUNCTION:
+CRYPTO_gcm128_decrypt 4651 EXIST::FUNCTION:
+ENGINE_load_rsax 4652 EXIST::FUNCTION:ENGINE
+CRYPTO_gcm128_decrypt_ctr32 4653 EXIST::FUNCTION:
+CRYPTO_gcm128_encrypt_ctr32 4654 EXIST::FUNCTION:
+CRYPTO_gcm128_finish 4655 EXIST::FUNCTION:
+EVP_aes_256_cbc_hmac_sha1 4656 EXIST::FUNCTION:AES,SHA,SHA1
+PKCS5_pbkdf2_set 4657 EXIST::FUNCTION:
+CMS_add0_recipient_password 4658 EXIST::FUNCTION:CMS
+CMS_decrypt_set1_password 4659 EXIST::FUNCTION:CMS
+CMS_RecipientInfo_set0_password 4660 EXIST::FUNCTION:CMS
+RAND_set_fips_drbg_type 4661 EXIST:OPENSSL_FIPS:FUNCTION:
+X509_REQ_sign_ctx 4662 EXIST::FUNCTION:EVP
+RSA_PSS_PARAMS_new 4663 EXIST::FUNCTION:RSA
+X509_CRL_sign_ctx 4664 EXIST::FUNCTION:EVP
+X509_signature_dump 4665 EXIST::FUNCTION:EVP
+d2i_RSA_PSS_PARAMS 4666 EXIST::FUNCTION:RSA
+RSA_PSS_PARAMS_it 4667 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RSA
+RSA_PSS_PARAMS_it 4667 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RSA
+RSA_PSS_PARAMS_free 4668 EXIST::FUNCTION:RSA
+X509_sign_ctx 4669 EXIST::FUNCTION:EVP
+i2d_RSA_PSS_PARAMS 4670 EXIST::FUNCTION:RSA
+ASN1_item_sign_ctx 4671 EXIST::FUNCTION:EVP
+EC_GFp_nistp521_method 4672 EXIST::FUNCTION:EC,EC_NISTP_64_GCC_128
+EC_GFp_nistp256_method 4673 EXIST::FUNCTION:EC,EC_NISTP_64_GCC_128
+OPENSSL_stderr 4674 EXIST::FUNCTION:
+OPENSSL_cpuid_setup 4675 EXIST::FUNCTION:
+OPENSSL_showfatal 4676 EXIST::FUNCTION:
+BIO_new_dgram_sctp 4677 EXIST::FUNCTION:SCTP
+BIO_dgram_sctp_msg_waiting 4678 EXIST::FUNCTION:SCTP
+BIO_dgram_sctp_wait_for_dry 4679 EXIST::FUNCTION:SCTP
+BIO_s_datagram_sctp 4680 EXIST::FUNCTION:DGRAM,SCTP
+BIO_dgram_is_sctp 4681 EXIST::FUNCTION:SCTP
+BIO_dgram_sctp_notification_cb 4682 EXIST::FUNCTION:SCTP
diff --git a/deps/openssl/openssl/util/mk1mf.pl b/deps/openssl/openssl/util/mk1mf.pl
index afe8c7326..72fa089f6 100755
--- a/deps/openssl/openssl/util/mk1mf.pl
+++ b/deps/openssl/openssl/util/mk1mf.pl
@@ -18,6 +18,8 @@ local $zlib_opt = 0; # 0 = no zlib, 1 = static, 2 = dynamic
local $zlib_lib = "";
local $perl_asm = 0; # 1 to autobuild asm files from perl scripts
+my $ex_l_libs = "";
+
# Options to import from top level Makefile
my %mf_import = (
@@ -40,7 +42,9 @@ my %mf_import = (
SHA1_ASM_OBJ => \$mf_sha_asm,
RMD160_ASM_OBJ => \$mf_rmd_asm,
WP_ASM_OBJ => \$mf_wp_asm,
- CMLL_ENC => \$mf_cm_asm
+ CMLL_ENC => \$mf_cm_asm,
+ BASEADDR => \$baseaddr,
+ FIPSDIR => \$fipsdir,
);
@@ -104,6 +108,7 @@ and [options] can be one of
just-ssl - remove all non-ssl keys/digest
no-asm - No x86 asm
no-krb5 - No KRB5
+ no-srp - No SRP
no-ec - No EC
no-ecdsa - No ECDSA
no-ecdh - No ECDH
@@ -228,6 +233,8 @@ else
$cflags.=' -DTERMIO';
}
+$fipsdir =~ s/\//${o}/g;
+
$out_dir=(defined($VARS{'OUT'}))?$VARS{'OUT'}:$out_def.($debug?".dbg":"");
$tmp_dir=(defined($VARS{'TMP'}))?$VARS{'TMP'}:$tmp_def.($debug?".dbg":"");
$inc_dir=(defined($VARS{'INC'}))?$VARS{'INC'}:$inc_def;
@@ -261,6 +268,7 @@ $cflags.=" -DOPENSSL_NO_SOCK" if $no_sock;
$cflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2;
$cflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3;
$cflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext;
+$cflags.=" -DOPENSSL_NO_SRP" if $no_srp;
$cflags.=" -DOPENSSL_NO_CMS" if $no_cms;
$cflags.=" -DOPENSSL_NO_ERR" if $no_err;
$cflags.=" -DOPENSSL_NO_KRB5" if $no_krb5;
@@ -270,7 +278,9 @@ $cflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
$cflags.=" -DOPENSSL_NO_GOST" if $no_gost;
$cflags.=" -DOPENSSL_NO_ENGINE" if $no_engine;
$cflags.=" -DOPENSSL_NO_HW" if $no_hw;
+$cflags.=" -DOPENSSL_FIPS" if $fips;
$cflags.=" -DOPENSSL_NO_JPAKE" if $no_jpake;
+$cflags.=" -DOPENSSL_NO_EC2M" if $no_ec2m;
$cflags.= " -DZLIB" if $zlib_opt;
$cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
@@ -404,6 +414,11 @@ else
\$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
EOF
$ex_libs .= " $zlib_lib" if $zlib_opt == 1;
+ if ($fips)
+ {
+ $build_targets .= " \$(LIB_D)$o$crypto_compat \$(PREMAIN_DSO_EXE)";
+ $ex_l_libs .= " \$(O_FIPSCANISTER)";
+ }
}
$defs= <<"EOF";
@@ -465,6 +480,18 @@ MKLIB=$bin_dir$mklib
MLFLAGS=$mlflags
ASM=$bin_dir$asm
+# FIPS validated module and support file locations
+
+FIPSDIR=$fipsdir
+BASEADDR=$baseaddr
+FIPSLIB_D=\$(FIPSDIR)${o}lib
+FIPS_PREMAIN_SRC=\$(FIPSLIB_D)${o}fips_premain.c
+O_FIPSCANISTER=\$(FIPSLIB_D)${o}fipscanister.lib
+FIPS_SHA1_EXE=\$(FIPSDIR)${o}bin${o}fips_standalone_sha1${exep}
+E_PREMAIN_DSO=fips_premain_dso
+PREMAIN_DSO_EXE=\$(BIN_D)${o}fips_premain_dso$exep
+FIPSLINK=\$(PERL) \$(FIPSDIR)${o}bin${o}fipslink.pl
+
######################################################
# You should not need to touch anything below this point
######################################################
@@ -497,7 +524,7 @@ SO_CRYPTO= $plib\$(CRYPTO)$so_shlibp
L_SSL= \$(LIB_D)$o$plib\$(SSL)$libp
L_CRYPTO= \$(LIB_D)$o$plib\$(CRYPTO)$libp
-L_LIBS= \$(L_SSL) \$(L_CRYPTO)
+L_LIBS= \$(L_SSL) \$(L_CRYPTO) $ex_l_libs
######################################################
# Don't touch anything below this point
@@ -513,7 +540,7 @@ LIBS_DEP=\$(O_CRYPTO) \$(O_SSL)
EOF
$rules=<<"EOF";
-all: banner \$(TMP_D) \$(BIN_D) \$(TEST_D) \$(LIB_D) \$(INCO_D) headers lib exe
+all: banner \$(TMP_D) \$(BIN_D) \$(TEST_D) \$(LIB_D) \$(INCO_D) headers lib exe $build_targets
banner:
$banner
@@ -629,6 +656,16 @@ $rules.=&do_compile_rule("\$(OBJ_D)",$test,"\$(APP_CFLAGS)");
$defs.=&do_defs("E_OBJ",$e_exe,"\$(OBJ_D)",$obj);
$rules.=&do_compile_rule("\$(OBJ_D)",$e_exe,'-DMONOLITH $(APP_CFLAGS)');
+# Special case rule for fips_premain_dso
+
+if ($fips)
+ {
+ $rules.=&cc_compile_target("\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj",
+ "\$(FIPS_PREMAIN_SRC)",
+ "-DFINGERPRINT_PREMAIN_DSO_LOAD \$(SHLIB_CFLAGS)", "");
+ $rules.=&do_link_rule("\$(PREMAIN_DSO_EXE)","\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj \$(CRYPTOOBJ) \$(O_FIPSCANISTER)","","\$(EX_LIBS)", 1);
+ }
+
foreach (values %lib_nam)
{
$lib_obj=$lib_obj{$_};
@@ -677,7 +714,28 @@ foreach (split(/\s+/,$engines))
$rules.= &do_lib_rule("\$(SSLOBJ)","\$(O_SSL)",$ssl,$shlib,"\$(SO_SSL)");
-$rules.= &do_lib_rule("\$(CRYPTOOBJ)","\$(O_CRYPTO)",$crypto,$shlib,"\$(SO_CRYPTO)");
+
+if ($fips)
+ {
+ if ($shlib)
+ {
+ $rules.= &do_lib_rule("\$(CRYPTOOBJ) \$(O_FIPSCANISTER)",
+ "\$(O_CRYPTO)", "$crypto",
+ $shlib, "\$(SO_CRYPTO)", "\$(BASEADDR)");
+ }
+ else
+ {
+ $rules.= &do_lib_rule("\$(CRYPTOOBJ)",
+ "\$(O_CRYPTO)",$crypto,$shlib,"\$(SO_CRYPTO)", "");
+ $rules.= &do_lib_rule("\$(CRYPTOOBJ) \$(O_FIPSCANISTER)",
+ "\$(LIB_D)$o$crypto_compat",$crypto,$shlib,"\$(SO_CRYPTO)", "");
+ }
+ }
+ else
+ {
+ $rules.= &do_lib_rule("\$(CRYPTOOBJ)","\$(O_CRYPTO)",$crypto,$shlib,
+ "\$(SO_CRYPTO)");
+ }
foreach (split(" ",$otherlibs))
{
@@ -687,7 +745,7 @@ foreach (split(" ",$otherlibs))
}
-$rules.=&do_link_rule("\$(BIN_D)$o\$(E_EXE)$exep","\$(E_OBJ)","\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)");
+$rules.=&do_link_rule("\$(BIN_D)$o\$(E_EXE)$exep","\$(E_OBJ)","\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)", ($fips && !$shlib) ? 2 : 0);
print $defs;
@@ -781,6 +839,8 @@ sub var_add
@a=grep(!/(^sha1)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
@a=grep(!/_mdc2$/,@a) if $no_mdc2;
+ @a=grep(!/(srp)/,@a) if $no_srp;
+
@a=grep(!/^engine$/,@a) if $no_engine;
@a=grep(!/^hw$/,@a) if $no_hw;
@a=grep(!/(^rsa$)|(^genrsa$)/,@a) if $no_rsa;
@@ -939,14 +999,15 @@ sub Sasm_compile_target
sub cc_compile_target
{
- local($target,$source,$ex_flags)=@_;
+ local($target,$source,$ex_flags, $srcd)=@_;
local($ret);
$ex_flags.=" -DMK1MF_BUILD -D$platform_cpp_symbol" if ($source =~ /cversion/);
$target =~ s/\//$o/g if $o ne "/";
$source =~ s/\//$o/g if $o ne "/";
- $ret ="$target: \$(SRC_D)$o$source\n\t";
- $ret.="\$(CC) ${ofile}$target $ex_flags -c \$(SRC_D)$o$source\n\n";
+ $srcd = "\$(SRC_D)$o" unless defined $srcd;
+ $ret ="$target: $srcd$source\n\t";
+ $ret.="\$(CC) ${ofile}$target $ex_flags -c $srcd$source\n\n";
return($ret);
}
@@ -1056,8 +1117,11 @@ sub read_options
"no-ssl2" => \$no_ssl2,
"no-ssl3" => \$no_ssl3,
"no-tlsext" => \$no_tlsext,
+ "no-srp" => \$no_srp,
"no-cms" => \$no_cms,
+ "no-ec2m" => \$no_ec2m,
"no-jpake" => \$no_jpake,
+ "no-ec_nistp_64_gcc_128" => 0,
"no-err" => \$no_err,
"no-sock" => \$no_sock,
"no-krb5" => \$no_krb5,
@@ -1067,11 +1131,12 @@ sub read_options
"no-gost" => \$no_gost,
"no-engine" => \$no_engine,
"no-hw" => \$no_hw,
+ "no-rsax" => 0,
"just-ssl" =>
[\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
\$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
\$no_ssl2, \$no_err, \$no_ripemd, \$no_rc5,
- \$no_aes, \$no_camellia, \$no_seed],
+ \$no_aes, \$no_camellia, \$no_seed, \$no_srp],
"rsaref" => 0,
"gcc" => \$gcc,
"debug" => \$debug,
@@ -1079,6 +1144,7 @@ sub read_options
"shlib" => \$shlib,
"dll" => \$shlib,
"shared" => 0,
+ "no-sctp" => 0,
"no-gmp" => 0,
"no-rfc3779" => 0,
"no-montasm" => 0,
@@ -1086,6 +1152,7 @@ sub read_options
"no-store" => 0,
"no-zlib" => 0,
"no-zlib-dynamic" => 0,
+ "fips" => \$fips
);
if (exists $valid_options{$_})
diff --git a/deps/openssl/openssl/util/mkdef.pl b/deps/openssl/openssl/util/mkdef.pl
index ab4732909..9a8c7b87d 100755
--- a/deps/openssl/openssl/util/mkdef.pl
+++ b/deps/openssl/openssl/util/mkdef.pl
@@ -79,13 +79,15 @@ my $OS2=0;
my $safe_stack_def = 0;
my @known_platforms = ( "__FreeBSD__", "PERL5", "NeXT",
- "EXPORT_VAR_AS_FUNCTION", "ZLIB" );
+ "EXPORT_VAR_AS_FUNCTION", "ZLIB", "OPENSSL_FIPS" );
my @known_ossl_platforms = ( "VMS", "WIN16", "WIN32", "WINNT", "OS2" );
my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
"CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1",
"SHA256", "SHA512", "RIPEMD",
- "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA",
+ "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA", "EC2M",
"HMAC", "AES", "CAMELLIA", "SEED", "GOST",
+ # EC_NISTP_64_GCC_128
+ "EC_NISTP_64_GCC_128",
# Envelope "algorithms"
"EVP", "X509", "ASN1_TYPEDEFS",
# Helper "algorithms"
@@ -98,7 +100,7 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
# RFC3779
"RFC3779",
# TLS
- "TLSEXT", "PSK",
+ "TLSEXT", "PSK", "SRP", "HEARTBEATS",
# CMS
"CMS",
# CryptoAPI Engine
@@ -107,8 +109,14 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
"SSL2",
# JPAKE
"JPAKE",
+ # NEXTPROTONEG
+ "NEXTPROTONEG",
# Deprecated functions
- "DEPRECATED" );
+ "DEPRECATED",
+ # Hide SSL internals
+ "SSL_INTERN",
+ # SCTP
+ "SCTP");
my $options="";
open(IN,"<Makefile") || die "unable to open Makefile!\n";
@@ -127,7 +135,10 @@ my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
-my $no_jpake; my $no_ssl2;
+my $no_jpake; my $no_srp; my $no_ssl2; my $no_ec2m; my $no_nistp_gcc;
+my $no_nextprotoneg; my $no_sctp;
+
+my $fips;
my $zlib;
@@ -151,6 +162,7 @@ foreach (@ARGV, split(/ /, $options))
}
$VMS=1 if $_ eq "VMS";
$OS2=1 if $_ eq "OS2";
+ $fips=1 if /^fips/;
if ($_ eq "zlib" || $_ eq "enable-zlib" || $_ eq "zlib-dynamic"
|| $_ eq "enable-zlib-dynamic") {
$zlib = 1;
@@ -215,9 +227,14 @@ foreach (@ARGV, split(/ /, $options))
elsif (/^no-rfc3779$/) { $no_rfc3779=1; }
elsif (/^no-tlsext$/) { $no_tlsext=1; }
elsif (/^no-cms$/) { $no_cms=1; }
+ elsif (/^no-ec2m$/) { $no_ec2m=1; }
+ elsif (/^no-ec_nistp_64_gcc_128$/) { $no_nistp_gcc=1; }
+ elsif (/^no-nextprotoneg$/) { $no_nextprotoneg=1; }
elsif (/^no-ssl2$/) { $no_ssl2=1; }
elsif (/^no-capieng$/) { $no_capieng=1; }
elsif (/^no-jpake$/) { $no_jpake=1; }
+ elsif (/^no-srp$/) { $no_srp=1; }
+ elsif (/^no-sctp$/) { $no_sctp=1; }
}
@@ -254,8 +271,10 @@ $max_crypto = $max_num;
my $ssl="ssl/ssl.h";
$ssl.=" ssl/kssl.h";
$ssl.=" ssl/tls1.h";
+$ssl.=" ssl/srtp.h";
my $crypto ="crypto/crypto.h";
+$crypto.=" crypto/cryptlib.h";
$crypto.=" crypto/o_dir.h";
$crypto.=" crypto/o_str.h";
$crypto.=" crypto/o_time.h";
@@ -285,6 +304,7 @@ $crypto.=" crypto/ec/ec.h" ; # unless $no_ec;
$crypto.=" crypto/ecdsa/ecdsa.h" ; # unless $no_ecdsa;
$crypto.=" crypto/ecdh/ecdh.h" ; # unless $no_ecdh;
$crypto.=" crypto/hmac/hmac.h" ; # unless $no_hmac;
+$crypto.=" crypto/cmac/cmac.h" ; # unless $no_hmac;
$crypto.=" crypto/engine/engine.h"; # unless $no_engine;
$crypto.=" crypto/stack/stack.h" ; # unless $no_stack;
@@ -319,6 +339,7 @@ $crypto.=" crypto/pqueue/pqueue.h";
$crypto.=" crypto/cms/cms.h";
$crypto.=" crypto/jpake/jpake.h";
$crypto.=" crypto/modes/modes.h";
+$crypto.=" crypto/srp/srp.h";
my $symhacks="crypto/symhacks.h";
@@ -1126,6 +1147,9 @@ sub is_valid
if ($keyword eq "EXPORT_VAR_AS_FUNCTION" && ($VMSVAX || $W32 || $W16)) {
return 1;
}
+ if ($keyword eq "OPENSSL_FIPS" && $fips) {
+ return 1;
+ }
if ($keyword eq "ZLIB" && $zlib) { return 1; }
return 0;
} else {
@@ -1172,9 +1196,15 @@ sub is_valid
if ($keyword eq "TLSEXT" && $no_tlsext) { return 0; }
if ($keyword eq "PSK" && $no_psk) { return 0; }
if ($keyword eq "CMS" && $no_cms) { return 0; }
+ if ($keyword eq "EC2M" && $no_ec2m) { return 0; }
+ if ($keyword eq "NEXTPROTONEG" && $no_nextprotoneg) { return 0; }
+ if ($keyword eq "EC_NISTP_64_GCC_128" && $no_nistp_gcc)
+ { return 0; }
if ($keyword eq "SSL2" && $no_ssl2) { return 0; }
if ($keyword eq "CAPIENG" && $no_capieng) { return 0; }
if ($keyword eq "JPAKE" && $no_jpake) { return 0; }
+ if ($keyword eq "SRP" && $no_srp) { return 0; }
+ if ($keyword eq "SCTP" && $no_sctp) { return 0; }
if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; }
# Nothing recognise as true
diff --git a/deps/openssl/openssl/util/mkfiles.pl b/deps/openssl/openssl/util/mkfiles.pl
index 6d1583145..7d9a9d5e5 100755
--- a/deps/openssl/openssl/util/mkfiles.pl
+++ b/deps/openssl/openssl/util/mkfiles.pl
@@ -15,6 +15,7 @@ my @dirs = (
"crypto/sha",
"crypto/mdc2",
"crypto/hmac",
+"crypto/cmac",
"crypto/ripemd",
"crypto/des",
"crypto/rc2",
@@ -62,6 +63,7 @@ my @dirs = (
"crypto/pqueue",
"crypto/whrlpool",
"crypto/ts",
+"crypto/srp",
"ssl",
"apps",
"engines",
diff --git a/deps/openssl/openssl/util/mkrc.pl b/deps/openssl/openssl/util/mkrc.pl
index 0ceadcf8d..0ceadcf8d 100644..100755
--- a/deps/openssl/openssl/util/mkrc.pl
+++ b/deps/openssl/openssl/util/mkrc.pl
diff --git a/deps/openssl/openssl/util/pl/VC-32.pl b/deps/openssl/openssl/util/pl/VC-32.pl
index 5f25fc41b..6c550f54a 100644
--- a/deps/openssl/openssl/util/pl/VC-32.pl
+++ b/deps/openssl/openssl/util/pl/VC-32.pl
@@ -6,6 +6,16 @@
$ssl= "ssleay32";
$crypto="libeay32";
+if ($fips && !$shlib)
+ {
+ $crypto="libeayfips32";
+ $crypto_compat = "libeaycompat32.lib";
+ }
+else
+ {
+ $crypto="libeay32";
+ }
+
$o='\\';
$cp='$(PERL) util/copy.pl';
$mkdir='$(PERL) util/mkdir-p.pl';
@@ -33,7 +43,7 @@ if ($FLAVOR =~ /WIN64/)
# considered safe to ignore.
#
$base_cflags= " $mf_cflag";
- my $f = $shlib?' /MD':' /MT';
+ my $f = $shlib || $fips ?' /MD':' /MT';
$lib_cflag='/Zl' if (!$shlib); # remove /DEFAULTLIBs from static lib
$opt_cflags=$f.' /Ox';
$dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
@@ -108,13 +118,13 @@ elsif ($FLAVOR =~ /CE/)
$base_cflags.=' -I$(WCECOMPAT)/include' if (defined($ENV{'WCECOMPAT'}));
$base_cflags.=' -I$(PORTSDK_LIBPATH)/../../include' if (defined($ENV{'PORTSDK_LIBPATH'}));
$opt_cflags=' /MC /O1i'; # optimize for space, but with intrinsics...
- $dbg_clfags=' /MC /Od -DDEBUG -D_DEBUG';
+ $dbg_cflags=' /MC /Od -DDEBUG -D_DEBUG';
$lflags="/nologo /opt:ref $wcelflag";
}
else # Win32
{
$base_cflags= " $mf_cflag";
- my $f = $shlib?' /MD':' /MT';
+ my $f = $shlib || $fips ?' /MD':' /MT';
$lib_cflag='/Zl' if (!$shlib); # remove /DEFAULTLIBs from static lib
$opt_cflags=$f.' /Ox /O2 /Ob2';
$dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
@@ -266,10 +276,19 @@ elsif ($shlib && $FLAVOR =~ /CE/)
sub do_lib_rule
{
- local($objs,$target,$name,$shlib)=@_;
+ my($objs,$target,$name,$shlib,$ign,$base_addr) = @_;
local($ret);
$taget =~ s/\//$o/g if $o ne '/';
+ my $base_arg;
+ if ($base_addr ne "")
+ {
+ $base_arg= " /base:$base_addr";
+ }
+ else
+ {
+ $base_arg = "";
+ }
if ($name ne "")
{
$name =~ tr/a-z/A-Z/;
@@ -277,17 +296,37 @@ sub do_lib_rule
}
# $target="\$(LIB_D)$o$target";
- $ret.="$target: $objs\n";
+# $ret.="$target: $objs\n";
if (!$shlib)
{
# $ret.="\t\$(RM) \$(O_$Name)\n";
+ $ret.="$target: $objs\n";
$ret.="\t\$(MKLIB) $lfile$target @<<\n $objs\n<<\n";
}
else
{
local($ex)=($target =~ /O_CRYPTO/)?'':' $(L_CRYPTO)';
$ex.=" $zlib_lib" if $zlib_opt == 1 && $target =~ /O_CRYPTO/;
- $ret.="\t\$(LINK) \$(MLFLAGS) $efile$target $name @<<\n \$(SHLIB_EX_OBJ) $objs $ex \$(EX_LIBS)\n<<\n";
+
+ if ($fips && $target =~ /O_CRYPTO/)
+ {
+ $ret.="$target: $objs \$(PREMAIN_DSO_EXE)";
+ $ret.="\n\tSET FIPS_LINK=\$(LINK)\n";
+ $ret.="\tSET FIPS_CC=\$(CC)\n";
+ $ret.="\tSET FIPS_CC_ARGS=/Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c\n";
+ $ret.="\tSET PREMAIN_DSO_EXE=\$(PREMAIN_DSO_EXE)\n";
+ $ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n";
+ $ret.="\tSET FIPS_TARGET=$target\n";
+ $ret.="\tSET FIPSLIB_D=\$(FIPSLIB_D)\n";
+ $ret.="\t\$(FIPSLINK) \$(MLFLAGS) /map $base_arg $efile$target ";
+ $ret.="$name @<<\n \$(SHLIB_EX_OBJ) $objs \$(EX_LIBS) ";
+ $ret.="\$(OBJ_D)${o}fips_premain.obj $ex\n<<\n";
+ }
+ else
+ {
+ $ret.="$target: $objs";
+ $ret.="\n\t\$(LINK) \$(MLFLAGS) $efile$target $name @<<\n \$(SHLIB_EX_OBJ) $objs $ex \$(EX_LIBS)\n<<\n";
+ }
$ret.="\tIF EXIST \$@.manifest mt -nologo -manifest \$@.manifest -outputresource:\$@;2\n\n";
}
$ret.="\n";
@@ -296,15 +335,35 @@ sub do_lib_rule
sub do_link_rule
{
- local($target,$files,$dep_libs,$libs)=@_;
+ my($target,$files,$dep_libs,$libs,$standalone)=@_;
local($ret,$_);
-
$file =~ s/\//$o/g if $o ne '/';
$n=&bname($targer);
$ret.="$target: $files $dep_libs\n";
- $ret.="\t\$(LINK) \$(LFLAGS) $efile$target @<<\n";
- $ret.=" \$(APP_EX_OBJ) $files $libs\n<<\n";
- $ret.="\tIF EXIST \$@.manifest mt -nologo -manifest \$@.manifest -outputresource:\$@;1\n\n";
+ if ($standalone == 1)
+ {
+ $ret.=" \$(LINK) \$(LFLAGS) $efile$target @<<\n\t";
+ $ret.= "\$(EX_LIBS) " if ($files =~ /O_FIPSCANISTER/ && !$fipscanisterbuild);
+ $ret.="$files $libs\n<<\n";
+ }
+ elsif ($standalone == 2)
+ {
+ $ret.="\tSET FIPS_LINK=\$(LINK)\n";
+ $ret.="\tSET FIPS_CC=\$(CC)\n";
+ $ret.="\tSET FIPS_CC_ARGS=/Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c\n";
+ $ret.="\tSET PREMAIN_DSO_EXE=\n";
+ $ret.="\tSET FIPS_TARGET=$target\n";
+ $ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n";
+ $ret.="\tSET FIPSLIB_D=\$(FIPSLIB_D)\n";
+ $ret.="\t\$(FIPSLINK) \$(LFLAGS) /map $efile$target @<<\n";
+ $ret.="\t\$(APP_EX_OBJ) $files \$(OBJ_D)${o}fips_premain.obj $libs\n<<\n";
+ }
+ else
+ {
+ $ret.="\t\$(LINK) \$(LFLAGS) $efile$target @<<\n";
+ $ret.="\t\$(APP_EX_OBJ) $files $libs\n<<\n";
+ }
+ $ret.="\tIF EXIST \$@.manifest mt -nologo -manifest \$@.manifest -outputresource:\$@;1\n\n";
return($ret);
}
diff --git a/deps/openssl/openssl/util/ssleay.num b/deps/openssl/openssl/util/ssleay.num
index 15a58e7b1..37655bc40 100755
--- a/deps/openssl/openssl/util/ssleay.num
+++ b/deps/openssl/openssl/util/ssleay.num
@@ -259,3 +259,64 @@ SSL_set_session_secret_cb 307 EXIST::FUNCTION:
SSL_set_session_ticket_ext_cb 308 EXIST::FUNCTION:
SSL_set1_param 309 EXIST::FUNCTION:
SSL_CTX_set1_param 310 EXIST::FUNCTION:
+SSL_tls1_key_exporter 311 NOEXIST::FUNCTION:
+SSL_renegotiate_abbreviated 312 EXIST::FUNCTION:
+TLSv1_1_method 313 EXIST::FUNCTION:
+TLSv1_1_client_method 314 EXIST::FUNCTION:
+TLSv1_1_server_method 315 EXIST::FUNCTION:
+SSL_CTX_set_srp_client_pwd_callback 316 EXIST:!VMS:FUNCTION:SRP
+SSL_CTX_set_srp_client_pwd_cb 316 EXIST:VMS:FUNCTION:SRP
+SSL_get_srp_g 317 EXIST::FUNCTION:SRP
+SSL_CTX_set_srp_username_callback 318 EXIST:!VMS:FUNCTION:SRP
+SSL_CTX_set_srp_un_cb 318 EXIST:VMS:FUNCTION:SRP
+SSL_get_srp_userinfo 319 EXIST::FUNCTION:SRP
+SSL_set_srp_server_param 320 EXIST::FUNCTION:SRP
+SSL_set_srp_server_param_pw 321 EXIST::FUNCTION:SRP
+SSL_get_srp_N 322 EXIST::FUNCTION:SRP
+SSL_get_srp_username 323 EXIST::FUNCTION:SRP
+SSL_CTX_set_srp_password 324 EXIST::FUNCTION:SRP
+SSL_CTX_set_srp_strength 325 EXIST::FUNCTION:SRP
+SSL_CTX_set_srp_verify_param_callback 326 EXIST:!VMS:FUNCTION:SRP
+SSL_CTX_set_srp_vfy_param_cb 326 EXIST:VMS:FUNCTION:SRP
+SSL_CTX_set_srp_miss_srp_un_cb 327 NOEXIST::FUNCTION:
+SSL_CTX_set_srp_missing_srp_username_callback 327 NOEXIST::FUNCTION:
+SSL_CTX_set_srp_cb_arg 328 EXIST::FUNCTION:SRP
+SSL_CTX_set_srp_username 329 EXIST::FUNCTION:SRP
+SSL_CTX_SRP_CTX_init 330 EXIST::FUNCTION:SRP
+SSL_SRP_CTX_init 331 EXIST::FUNCTION:SRP
+SRP_Calc_A_param 332 EXIST::FUNCTION:SRP
+SRP_generate_server_master_secret 333 EXIST:!VMS:FUNCTION:SRP
+SRP_gen_server_master_secret 333 EXIST:VMS:FUNCTION:SRP
+SSL_CTX_SRP_CTX_free 334 EXIST::FUNCTION:SRP
+SRP_generate_client_master_secret 335 EXIST:!VMS:FUNCTION:SRP
+SRP_gen_client_master_secret 335 EXIST:VMS:FUNCTION:SRP
+SSL_srp_server_param_with_username 336 EXIST:!VMS:FUNCTION:SRP
+SSL_srp_server_param_with_un 336 EXIST:VMS:FUNCTION:SRP
+SRP_have_to_put_srp_username 337 NOEXIST::FUNCTION:
+SSL_SRP_CTX_free 338 EXIST::FUNCTION:SRP
+SSL_set_debug 339 EXIST::FUNCTION:
+SSL_SESSION_get0_peer 340 EXIST::FUNCTION:
+TLSv1_2_client_method 341 EXIST::FUNCTION:
+SSL_SESSION_set1_id_context 342 EXIST::FUNCTION:
+TLSv1_2_server_method 343 EXIST::FUNCTION:
+SSL_cache_hit 344 EXIST::FUNCTION:
+SSL_get0_kssl_ctx 345 EXIST::FUNCTION:KRB5
+SSL_set0_kssl_ctx 346 EXIST::FUNCTION:KRB5
+SSL_SESSION_get0_id 347 NOEXIST::FUNCTION:
+SSL_set_state 348 EXIST::FUNCTION:
+SSL_CIPHER_get_id 349 EXIST::FUNCTION:
+TLSv1_2_method 350 EXIST::FUNCTION:
+SSL_SESSION_get_id_len 351 NOEXIST::FUNCTION:
+kssl_ctx_get0_client_princ 352 EXIST::FUNCTION:KRB5
+SSL_export_keying_material 353 EXIST::FUNCTION:TLSEXT
+SSL_set_tlsext_use_srtp 354 EXIST::FUNCTION:
+SSL_CTX_set_next_protos_advertised_cb 355 EXIST:!VMS:FUNCTION:NEXTPROTONEG
+SSL_CTX_set_next_protos_adv_cb 355 EXIST:VMS:FUNCTION:NEXTPROTONEG
+SSL_get0_next_proto_negotiated 356 EXIST::FUNCTION:NEXTPROTONEG
+SSL_get_selected_srtp_profile 357 EXIST::FUNCTION:
+SSL_CTX_set_tlsext_use_srtp 358 EXIST::FUNCTION:
+SSL_select_next_proto 359 EXIST::FUNCTION:NEXTPROTONEG
+SSL_get_srtp_profiles 360 EXIST::FUNCTION:
+SSL_CTX_set_next_proto_select_cb 361 EXIST:!VMS:FUNCTION:NEXTPROTONEG
+SSL_CTX_set_next_proto_sel_cb 361 EXIST:VMS:FUNCTION:NEXTPROTONEG
+SSL_SESSION_get_compress_id 362 EXIST::FUNCTION:
diff --git a/deps/openssl/patches/handshake_cutthrough.patch b/deps/openssl/patches/handshake_cutthrough.patch
deleted file mode 100644
index 4f298399c..000000000
--- a/deps/openssl/patches/handshake_cutthrough.patch
+++ /dev/null
@@ -1,275 +0,0 @@
-diff -uarp openssl-1.0.0.orig/apps/s_client.c openssl-1.0.0/apps/s_client.c
---- openssl-1.0.0.orig/apps/s_client.c 2009-12-16 15:28:28.000000000 -0500
-+++ openssl-1.0.0/apps/s_client.c 2010-04-21 14:39:49.000000000 -0400
-@@ -248,6 +248,7 @@ static void sc_usage(void)
- BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
- BIO_printf(bio_err," -status - request certificate status from server\n");
- BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
-+ BIO_printf(bio_err," -cutthrough - enable 1-RTT full-handshake for strong ciphers\n");
- #endif
- }
-
-@@ -304,6 +305,7 @@ int MAIN(int argc, char **argv)
- EVP_PKEY *key = NULL;
- char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
- int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
-+ int cutthrough=0;
- int crlf=0;
- int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
- SSL_CTX *ctx=NULL;
-@@ -533,6 +535,8 @@ int MAIN(int argc, char **argv)
- else if (strcmp(*argv,"-no_ticket") == 0)
- { off|=SSL_OP_NO_TICKET; }
- #endif
-+ else if (strcmp(*argv,"-cutthrough") == 0)
-+ cutthrough=1;
- else if (strcmp(*argv,"-serverpref") == 0)
- off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
- else if (strcmp(*argv,"-cipher") == 0)
-@@ -714,6 +718,15 @@ bad:
- */
- if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
-
-+ /* Enable handshake cutthrough for client connections using
-+ * strong ciphers. */
-+ if (cutthrough)
-+ {
-+ int ssl_mode = SSL_CTX_get_mode(ctx);
-+ ssl_mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;
-+ SSL_CTX_set_mode(ctx, ssl_mode);
-+ }
-+
- if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
- if (cipher != NULL)
- if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
-diff -uarp openssl-1.0.0.orig/ssl/s3_clnt.c openssl-1.0.0/ssl/s3_clnt.c
---- openssl-1.0.0.orig/ssl/s3_clnt.c 2010-02-27 19:24:24.000000000 -0500
-+++ openssl-1.0.0/ssl/s3_clnt.c 2010-04-21 14:39:49.000000000 -0400
-@@ -186,6 +186,18 @@ int ssl3_connect(SSL *s)
-
- s->in_handshake++;
- if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
-+#if 0 /* Send app data in separate packet, otherwise, some particular site
-+ * (only one site so far) closes the socket.
-+ * Note: there is a very small chance that two TCP packets
-+ * could be arriving at server combined into a single TCP packet,
-+ * then trigger that site to break. We haven't encounter that though.
-+ */
-+ if (SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
-+ {
-+ /* Send app data along with CCS/Finished */
-+ s->s3->flags |= SSL3_FLAGS_DELAY_CLIENT_FINISHED;
-+ }
-+#endif
-
- for (;;)
- {
-@@ -454,14 +468,31 @@ int ssl3_connect(SSL *s)
- }
- else
- {
--#ifndef OPENSSL_NO_TLSEXT
-- /* Allow NewSessionTicket if ticket expected */
-- if (s->tlsext_ticket_expected)
-- s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
-+ if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && SSL_get_cipher_bits(s, NULL) >= 128
-+ && s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */
-+ )
-+ {
-+ if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
-+ {
-+ s->state=SSL3_ST_CUTTHROUGH_COMPLETE;
-+ s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
-+ s->s3->delay_buf_pop_ret=0;
-+ }
-+ else
-+ {
-+ s->s3->tmp.next_state=SSL3_ST_CUTTHROUGH_COMPLETE;
-+ }
-+ }
- else
-+ {
-+#ifndef OPENSSL_NO_TLSEXT
-+ /* Allow NewSessionTicket if ticket expected */
-+ if (s->tlsext_ticket_expected)
-+ s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
-+ else
- #endif
--
-- s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
-+ s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
-+ }
- }
- s->init_num=0;
- break;
-@@ -512,6 +541,24 @@ int ssl3_connect(SSL *s)
- s->state=s->s3->tmp.next_state;
- break;
-
-+ case SSL3_ST_CUTTHROUGH_COMPLETE:
-+#ifndef OPENSSL_NO_TLSEXT
-+ /* Allow NewSessionTicket if ticket expected */
-+ if (s->tlsext_ticket_expected)
-+ s->state=SSL3_ST_CR_SESSION_TICKET_A;
-+ else
-+#endif
-+ s->state=SSL3_ST_CR_FINISHED_A;
-+
-+ /* SSL_write() will take care of flushing buffered data if
-+ * DELAY_CLIENT_FINISHED is set.
-+ */
-+ if (!(s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED))
-+ ssl_free_wbio_buffer(s);
-+ ret = 1;
-+ goto end;
-+ /* break; */
-+
- case SSL_ST_OK:
- /* clean a few things up */
- ssl3_cleanup_key_block(s);
-diff -uarp openssl-1.0.0.orig/ssl/s3_lib.c openssl-1.0.0/ssl/s3_lib.c
--- openssl-1.0.0.orig/ssl/s3_lib.c 2009-10-16 11:24:19.000000000 -0400
-+++ openssl-1.0.0/ssl/s3_lib.c 2010-04-21 14:39:49.000000000 -0400
-@@ -2551,9 +2551,22 @@ int ssl3_write(SSL *s, const void *buf,
-
- static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
- {
-- int ret;
-+ int n,ret;
-
- clear_sys_error();
-+ if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio))
-+ {
-+ /* Deal with an application that calls SSL_read() when handshake data
-+ * is yet to be written.
-+ */
-+ if (BIO_wpending(s->wbio) > 0)
-+ {
-+ s->rwstate=SSL_WRITING;
-+ n=BIO_flush(s->wbio);
-+ if (n <= 0) return(n);
-+ s->rwstate=SSL_NOTHING;
-+ }
-+ }
- if (s->s3->renegotiate) ssl3_renegotiate_check(s);
- s->s3->in_read_app_data=1;
- ret=s->method->ssl_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek);
-diff -uarp openssl-1.0.0.orig/ssl/ssl.h openssl-1.0.0/ssl/ssl.h
---- openssl-1.0.0.orig/ssl/ssl.h 2010-01-06 12:37:38.000000000 -0500
-+++ openssl-1.0.0/ssl/ssl.h 2010-04-21 16:57:49.000000000 -0400
-@@ -605,6 +605,10 @@ typedef struct ssl_session_st
- /* Use small read and write buffers: (a) lazy allocate read buffers for
- * large incoming records, and (b) limit the size of outgoing records. */
- #define SSL_MODE_SMALL_BUFFERS 0x00000020L
-+/* When set, clients may send application data before receipt of CCS
-+ * and Finished. This mode enables full-handshakes to 'complete' in
-+ * one RTT. */
-+#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000040L
-
- /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
- * they cannot be used to clear bits. */
-@@ -1097,10 +1101,12 @@ extern "C" {
- /* Is the SSL_connection established? */
- #define SSL_get_state(a) SSL_state(a)
- #define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
--#define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT)
-+#define SSL_in_init(a) ((SSL_state(a)&SSL_ST_INIT) && \
-+ !SSL_cutthrough_complete(a))
- #define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE)
- #define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT)
- #define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT)
-+int SSL_cutthrough_complete(const SSL *s);
-
- /* The following 2 states are kept in ssl->rstate when reads fail,
- * you should not need these */
-Only in openssl-1.0.0/ssl: ssl.h.orig
-diff -uarp openssl-1.0.0.orig/ssl/ssl3.h openssl-1.0.0/ssl/ssl3.h
--- openssl-1.0.0.orig/ssl/ssl3.h 2010-01-06 12:37:38.000000000 -0500
-+++ openssl-1.0.0/ssl/ssl3.h 2010-04-21 14:39:49.000000000 -0400
-@@ -456,6 +456,7 @@ typedef struct ssl3_state_st
- /*client */
- /* extra state */
- #define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT)
-+#define SSL3_ST_CUTTHROUGH_COMPLETE (0x101|SSL_ST_CONNECT)
- /* write to server */
- #define SSL3_ST_CW_CLNT_HELLO_A (0x110|SSL_ST_CONNECT)
- #define SSL3_ST_CW_CLNT_HELLO_B (0x111|SSL_ST_CONNECT)
-diff -uarp openssl-1.0.0.orig/ssl/ssl_lib.c openssl-1.0.0/ssl/ssl_lib.c
---- openssl-1.0.0.orig/ssl/ssl_lib.c 2010-02-17 14:43:46.000000000 -0500
-+++ openssl-1.0.0/ssl/ssl_lib.c 2010-04-21 17:02:45.000000000 -0400
-@@ -3031,6 +3031,19 @@ void SSL_set_msg_callback(SSL *ssl, void
- SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
- }
-
-+int SSL_cutthrough_complete(const SSL *s)
-+ {
-+ return (!s->server && /* cutthrough only applies to clients */
-+ !s->hit && /* full-handshake */
-+ s->version >= SSL3_VERSION &&
-+ s->s3->in_read_app_data == 0 && /* cutthrough only applies to write() */
-+ (SSL_get_mode((SSL*)s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && /* cutthrough enabled */
-+ SSL_get_cipher_bits(s, NULL) >= 128 && /* strong cipher choosen */
-+ s->s3->previous_server_finished_len == 0 && /* not a renegotiation handshake */
-+ (s->state == SSL3_ST_CR_SESSION_TICKET_A || /* ready to write app-data*/
-+ s->state == SSL3_ST_CR_FINISHED_A));
-+ }
-+
- /* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
- * vairable, freeing EVP_MD_CTX previously stored in that variable, if
- * any. If EVP_MD pointer is passed, initializes ctx with this md
-diff -uarp openssl-1.0.0.orig/ssl/ssltest.c openssl-1.0.0/ssl/ssltest.c
---- openssl-1.0.0.orig/ssl/ssltest.c 2010-01-24 11:57:38.000000000 -0500
-+++ openssl-1.0.0/ssl/ssltest.c 2010-04-21 17:06:35.000000000 -0400
-@@ -279,6 +279,7 @@ static void sv_usage(void)
- fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
- fprintf(stderr," -c_small_records - enable client side use of small SSL record buffers\n");
- fprintf(stderr," -s_small_records - enable server side use of small SSL record buffers\n");
-+ fprintf(stderr," -cutthrough - enable 1-RTT full-handshake for strong ciphers\n");
- }
-
- static void print_details(SSL *c_ssl, const char *prefix)
-@@ -436,6 +437,7 @@ int main(int argc, char *argv[])
- int ssl_mode = 0;
- int c_small_records=0;
- int s_small_records=0;
-+ int cutthrough = 0;
-
- verbose = 0;
- debug = 0;
-@@ -632,6 +634,10 @@ int main(int argc, char *argv[])
- {
- s_small_records = 1;
- }
-+ else if (strcmp(*argv, "-cutthrough") == 0)
-+ {
-+ cutthrough = 1;
-+ }
- else
- {
- fprintf(stderr,"unknown option %s\n",*argv);
-@@ -782,6 +788,13 @@ bad:
- ssl_mode |= SSL_MODE_SMALL_BUFFERS;
- SSL_CTX_set_mode(s_ctx, ssl_mode);
- }
-+ ssl_mode = 0;
-+ if (cutthrough)
-+ {
-+ ssl_mode = SSL_CTX_get_mode(c_ctx);
-+ ssl_mode = SSL_MODE_HANDSHAKE_CUTTHROUGH;
-+ SSL_CTX_set_mode(c_ctx, ssl_mode);
-+ }
-
- #ifndef OPENSSL_NO_DH
- if (!no_dhe)
-diff -uarp openssl-1.0.0.orig/test/testssl openssl-1.0.0/test/testssl
---- openssl-1.0.0.orig/test/testssl 2006-03-10 18:06:27.000000000 -0500
-+++ openssl-1.0.0/test/testssl 2010-04-21 16:50:13.000000000 -0400
-@@ -79,6 +79,8 @@ $ssltest -server_auth -client_auth -s_sm
- echo test sslv2/sslv3 with both client and server authentication and small client and server buffers
- $ssltest -server_auth -client_auth -c_small_records -s_small_records $CA $extra || exit 1
-
-+echo test sslv2/sslv3 with both client and server authentication and handshake cutthrough
-+$ssltest -server_auth -client_auth -cutthrough $CA $extra || exit 1
-
- echo test sslv2 via BIO pair
- $ssltest -bio_pair -ssl2 $extra || exit 1
diff --git a/deps/openssl/patches/jsse.patch b/deps/openssl/patches/jsse.patch
deleted file mode 100644
index 249fb5b2b..000000000
--- a/deps/openssl/patches/jsse.patch
+++ /dev/null
@@ -1,426 +0,0 @@
---- openssl-1.0.0b.orig/ssl/ssl.h 2010-11-30 00:03:46.000000000 +0000
-+++ openssl-1.0.0b/ssl/ssl.h 2010-11-30 00:03:47.000000000 +0000
-@@ -1133,6 +1133,9 @@ struct ssl_st
- /* This can also be in the session once a session is established */
- SSL_SESSION *session;
-
-+ /* This can be disabled to prevent the use of uncached sessions */
-+ int session_creation_enabled;
-+
- /* Default generate session ID callback. */
- GEN_SESSION_CB generate_session_id;
-
-@@ -1546,6 +1549,7 @@ const SSL_CIPHER *SSL_get_current_cipher
- int SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
- char * SSL_CIPHER_get_version(const SSL_CIPHER *c);
- const char * SSL_CIPHER_get_name(const SSL_CIPHER *c);
-+const char * SSL_CIPHER_authentication_method(const SSL_CIPHER *c);
-
- int SSL_get_fd(const SSL *s);
- int SSL_get_rfd(const SSL *s);
-@@ -1554,6 +1558,7 @@ const char * SSL_get_cipher_list(const
- char * SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
- int SSL_get_read_ahead(const SSL * s);
- int SSL_pending(const SSL *s);
-+const char * SSL_authentication_method(const SSL *c);
- #ifndef OPENSSL_NO_SOCK
- int SSL_set_fd(SSL *s, int fd);
- int SSL_set_rfd(SSL *s, int fd);
-@@ -1565,6 +1570,7 @@ BIO * SSL_get_rbio(const SSL *s);
- BIO * SSL_get_wbio(const SSL *s);
- #endif
- int SSL_set_cipher_list(SSL *s, const char *str);
-+int SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk);
- void SSL_set_read_ahead(SSL *s, int yes);
- int SSL_get_verify_mode(const SSL *s);
- int SSL_get_verify_depth(const SSL *s);
-@@ -1580,6 +1586,8 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKE
- int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
- int SSL_use_certificate(SSL *ssl, X509 *x);
- int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
-+int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
-+STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x);
-
- #ifndef OPENSSL_NO_STDIO
- int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
-@@ -1615,6 +1623,7 @@ void SSL_copy_session_id(SSL *to,const S
- SSL_SESSION *SSL_SESSION_new(void);
- const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
- unsigned int *len);
-+const char * SSL_SESSION_get_version(const SSL_SESSION *s);
- #ifndef OPENSSL_NO_FP_API
- int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
- #endif
-@@ -1624,6 +1633,7 @@ int SSL_SESSION_print(BIO *fp,const SSL_
- void SSL_SESSION_free(SSL_SESSION *ses);
- int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
- int SSL_set_session(SSL *to, SSL_SESSION *session);
-+void SSL_set_session_creation_enabled(SSL *, int);
- int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
- int SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
- int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
-@@ -2066,6 +2076,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
- #define SSL_F_SSL_USE_CERTIFICATE 198
- #define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
-+#define SSL_F_SSL_USE_CERTIFICATE_CHAIN 2000
- #define SSL_F_SSL_USE_CERTIFICATE_FILE 200
- #define SSL_F_SSL_USE_PRIVATEKEY 201
- #define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202
-@@ -2272,6 +2283,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345
- #define SSL_R_SERVERHELLO_TLSEXT 275
- #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
-+#define SSL_R_SESSION_MAY_NOT_BE_CREATED 2000
- #define SSL_R_SHORT_READ 219
- #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220
- #define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221
---- openssl-1.0.0b.orig/ssl/d1_clnt.c 2010-01-26 19:46:29.000000000 +0000
-+++ openssl-1.0.0b/ssl/d1_clnt.c 2010-11-30 00:03:47.000000000 +0000
-@@ -613,6 +613,12 @@ int dtls1_client_hello(SSL *s)
- #endif
- (s->session->not_resumable))
- {
-+ if (!s->session_creation_enabled)
-+ {
-+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
-+ SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
-+ goto err;
-+ }
- if (!ssl_get_new_session(s,0))
- goto err;
- }
---- openssl-1.0.0b.orig/ssl/s23_clnt.c 2010-02-16 14:20:40.000000000 +0000
-+++ openssl-1.0.0b/ssl/s23_clnt.c 2010-11-30 00:03:47.000000000 +0000
-@@ -687,6 +687,13 @@ static int ssl23_get_server_hello(SSL *s
-
- /* Since, if we are sending a ssl23 client hello, we are not
- * reusing a session-id */
-+ if (!s->session_creation_enabled)
-+ {
-+ if (!(s->client_version == SSL2_VERSION))
-+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
-+ SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
-+ goto err;
-+ }
- if (!ssl_get_new_session(s,0))
- goto err;
-
---- openssl-1.0.0b.orig/ssl/s3_both.c 2010-11-30 00:03:46.000000000 +0000
-+++ openssl-1.0.0b/ssl/s3_both.c 2010-11-30 00:03:47.000000000 +0000
-@@ -347,8 +347,11 @@ unsigned long ssl3_output_cert_chain(SSL
- unsigned long l=7;
- BUF_MEM *buf;
- int no_chain;
-+ STACK_OF(X509) *cert_chain;
-
-- if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
-+ cert_chain = SSL_get_certificate_chain(s, x);
-+
-+ if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain)
- no_chain = 1;
- else
- no_chain = 0;
-@@ -400,6 +403,10 @@ unsigned long ssl3_output_cert_chain(SSL
- return(0);
- }
-
-+ for (i=0; i<sk_X509_num(cert_chain); i++)
-+ if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i)))
-+ return(0);
-+
- l-=7;
- p=(unsigned char *)&(buf->data[4]);
- l2n3(l,p);
---- openssl-1.0.0b.orig/ssl/s3_clnt.c 2010-11-30 00:03:46.000000000 +0000
-+++ openssl-1.0.0b/ssl/s3_clnt.c 2010-11-30 00:03:47.000000000 +0000
-@@ -686,6 +686,12 @@ int ssl3_client_hello(SSL *s)
- #endif
- (sess->not_resumable))
- {
-+ if (!s->session_creation_enabled)
-+ {
-+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
-+ SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
-+ goto err;
-+ }
- if (!ssl_get_new_session(s,0))
- goto err;
- }
-@@ -894,6 +900,12 @@ int ssl3_get_server_hello(SSL *s)
- s->hit=0;
- if (s->session->session_id_length > 0)
- {
-+ if (!s->session_creation_enabled)
-+ {
-+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
-+ SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
-+ goto err;
-+ }
- if (!ssl_get_new_session(s,0))
- {
- al=SSL_AD_INTERNAL_ERROR;
---- openssl-1.0.0b.orig/ssl/s3_srvr.c 2010-11-30 00:03:46.000000000 +0000
-+++ openssl-1.0.0b/ssl/s3_srvr.c 2010-11-30 00:03:47.000000000 +0000
-@@ -902,6 +902,12 @@ int ssl3_get_client_hello(SSL *s)
- */
- if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
- {
-+ if (!s->session_creation_enabled)
-+ {
-+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
-+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
-+ goto err;
-+ }
- if (!ssl_get_new_session(s,1))
- goto err;
- }
-@@ -916,6 +922,12 @@ int ssl3_get_client_hello(SSL *s)
- goto err;
- else /* i == 0 */
- {
-+ if (!s->session_creation_enabled)
-+ {
-+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
-+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
-+ goto err;
-+ }
- if (!ssl_get_new_session(s,1))
- goto err;
- }
---- openssl-1.0.0b.orig/ssl/ssl_ciph.c 2010-06-15 17:25:14.000000000 +0000
-+++ openssl-1.0.0b/ssl/ssl_ciph.c 2010-11-30 00:03:47.000000000 +0000
-@@ -1652,6 +1652,52 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER
- return(ret);
- }
-
-+/* return string version of key exchange algorithm */
-+const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher)
-+ {
-+ switch (cipher->algorithm_mkey)
-+ {
-+ case SSL_kRSA:
-+ return SSL_TXT_RSA;
-+ case SSL_kDHr:
-+ return SSL_TXT_DH "_" SSL_TXT_RSA;
-+ case SSL_kDHd:
-+ return SSL_TXT_DH "_" SSL_TXT_DSS;
-+ case SSL_kEDH:
-+ switch (cipher->algorithm_auth)
-+ {
-+ case SSL_aDSS:
-+ return "DHE_" SSL_TXT_DSS;
-+ case SSL_aRSA:
-+ return "DHE_" SSL_TXT_RSA;
-+ case SSL_aNULL:
-+ return SSL_TXT_DH "_anon";
-+ default:
-+ return "UNKNOWN";
-+ }
-+ case SSL_kKRB5:
-+ return SSL_TXT_KRB5;
-+ case SSL_kECDHr:
-+ return SSL_TXT_ECDH "_" SSL_TXT_RSA;
-+ case SSL_kECDHe:
-+ return SSL_TXT_ECDH "_" SSL_TXT_ECDSA;
-+ case SSL_kEECDH:
-+ switch (cipher->algorithm_auth)
-+ {
-+ case SSL_aECDSA:
-+ return "ECDHE_" SSL_TXT_ECDSA;
-+ case SSL_aRSA:
-+ return "ECDHE_" SSL_TXT_RSA;
-+ case SSL_aNULL:
-+ return SSL_TXT_ECDH "_anon";
-+ default:
-+ return "UNKNOWN";
-+ }
-+ default:
-+ return "UNKNOWN";
-+ }
-+ }
-+
- SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
- {
- SSL_COMP *ctmp;
---- openssl-1.0.0b.orig/ssl/ssl_err.c 2010-11-30 00:03:46.000000000 +0000
-+++ openssl-1.0.0b/ssl/ssl_err.c 2010-11-30 00:03:47.000000000 +0000
-@@ -465,6 +465,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
- {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
- {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"},
- {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
-+{ERR_REASON(SSL_R_SESSION_MAY_NOT_BE_CREATED),"session may not be created"},
- {ERR_REASON(SSL_R_SHORT_READ) ,"short read"},
- {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
- {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
---- openssl-1.0.0b.orig/ssl/ssl_lib.c 2010-11-30 00:03:46.000000000 +0000
-+++ openssl-1.0.0b/ssl/ssl_lib.c 2010-11-30 00:03:47.000000000 +0000
-@@ -326,6 +326,7 @@ SSL *SSL_new(SSL_CTX *ctx)
- OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
- memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
- s->verify_callback=ctx->default_verify_callback;
-+ s->session_creation_enabled=1;
- s->generate_session_id=ctx->generate_session_id;
-
- s->param = X509_VERIFY_PARAM_new();
-@@ -1311,6 +1312,32 @@ int SSL_set_cipher_list(SSL *s,const cha
- return 1;
- }
-
-+/** specify the ciphers to be used by the SSL */
-+int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk)
-+ {
-+ STACK_OF(SSL_CIPHER) *tmp_cipher_list;
-+
-+ if (sk == NULL)
-+ return 0;
-+
-+ /* Based on end of ssl_create_cipher_list */
-+ tmp_cipher_list = sk_SSL_CIPHER_dup(sk);
-+ if (tmp_cipher_list == NULL)
-+ {
-+ return 0;
-+ }
-+ if (s->cipher_list != NULL)
-+ sk_SSL_CIPHER_free(s->cipher_list);
-+ s->cipher_list = sk;
-+ if (s->cipher_list_by_id != NULL)
-+ sk_SSL_CIPHER_free(s->cipher_list_by_id);
-+ s->cipher_list_by_id = tmp_cipher_list;
-+ (void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp);
-+
-+ sk_SSL_CIPHER_sort(s->cipher_list_by_id);
-+ return 1;
-+ }
-+
- /* works well for SSLv2, not so good for SSLv3 */
- char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
- {
-@@ -2551,18 +2578,45 @@ SSL_METHOD *ssl_bad_method(int ver)
- return(NULL);
- }
-
--const char *SSL_get_version(const SSL *s)
-+static const char *ssl_get_version(int version)
- {
-- if (s->version == TLS1_VERSION)
-+ if (version == TLS1_VERSION)
- return("TLSv1");
-- else if (s->version == SSL3_VERSION)
-+ else if (version == SSL3_VERSION)
- return("SSLv3");
-- else if (s->version == SSL2_VERSION)
-+ else if (version == SSL2_VERSION)
- return("SSLv2");
- else
- return("unknown");
- }
-
-+const char *SSL_get_version(const SSL *s)
-+ {
-+ return ssl_get_version(s->version);
-+ }
-+
-+const char *SSL_SESSION_get_version(const SSL_SESSION *s)
-+ {
-+ return ssl_get_version(s->ssl_version);
-+ }
-+
-+const char* SSL_authentication_method(const SSL* ssl)
-+ {
-+ if (ssl->cert != NULL && ssl->cert->rsa_tmp != NULL)
-+ return SSL_TXT_RSA "_" SSL_TXT_EXPORT;
-+ switch (ssl->version)
-+ {
-+ case SSL2_VERSION:
-+ return SSL_TXT_RSA;
-+ case SSL3_VERSION:
-+ case TLS1_VERSION:
-+ case DTLS1_VERSION:
-+ return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher);
-+ default:
-+ return "UNKNOWN";
-+ }
-+ }
-+
- SSL *SSL_dup(SSL *s)
- {
- STACK_OF(X509_NAME) *sk;
---- openssl-1.0.0b.orig/ssl/ssl_locl.h 2010-11-30 00:03:46.000000000 +0000
-+++ openssl-1.0.0b/ssl/ssl_locl.h 2010-11-30 00:03:47.000000000 +0000
-@@ -456,6 +456,7 @@
- typedef struct cert_pkey_st
- {
- X509 *x509;
-+ STACK_OF(X509) *cert_chain;
- EVP_PKEY *privatekey;
- } CERT_PKEY;
-
---- openssl-1.0.0b.orig/ssl/ssl_rsa.c 2009-09-12 23:09:26.000000000 +0000
-+++ openssl-1.0.0b/ssl/ssl_rsa.c 2010-11-30 00:03:47.000000000 +0000
-@@ -697,6 +697,42 @@ int SSL_CTX_use_PrivateKey_ASN1(int type
- }
-
-
-+int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain)
-+ {
-+ if (ssl == NULL)
-+ {
-+ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER);
-+ return(0);
-+ }
-+ if (ssl->cert == NULL)
-+ {
-+ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
-+ return(0);
-+ }
-+ if (ssl->cert->key == NULL)
-+ {
-+ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
-+ return(0);
-+ }
-+ ssl->cert->key->cert_chain = cert_chain;
-+ return(1);
-+ }
-+
-+STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x)
-+ {
-+ int i;
-+ if (x == NULL)
-+ return NULL;
-+ if (ssl == NULL)
-+ return NULL;
-+ if (ssl->cert == NULL)
-+ return NULL;
-+ for (i = 0; i < SSL_PKEY_NUM; i++)
-+ if (ssl->cert->pkeys[i].x509 == x)
-+ return ssl->cert->pkeys[i].cert_chain;
-+ return NULL;
-+ }
-+
- #ifndef OPENSSL_NO_STDIO
- /* Read a file that contains our certificate in "PEM" format,
- * possibly followed by a sequence of CA certificates that should be
---- openssl-1.0.0b.orig/ssl/ssl_sess.c 2010-02-01 16:49:42.000000000 +0000
-+++ openssl-1.0.0b/ssl/ssl_sess.c 2010-11-30 00:03:47.000000000 +0000
-@@ -261,6 +261,11 @@ static int def_generate_session_id(const
- return 0;
- }
-
-+void SSL_set_session_creation_enabled (SSL *s, int creation_enabled)
-+ {
-+ s->session_creation_enabled = creation_enabled;
-+ }
-+
- int ssl_get_new_session(SSL *s, int session)
- {
- /* This gets used by clients and servers. */
-@@ -269,6 +274,8 @@ int ssl_get_new_session(SSL *s, int sess
- SSL_SESSION *ss=NULL;
- GEN_SESSION_CB cb = def_generate_session_id;
-
-+ /* caller should check this if they can do better error handling */
-+ if (!s->session_creation_enabled) return(0);
- if ((ss=SSL_SESSION_new()) == NULL) return(0);
-
- /* If the context has a default timeout, use it */
diff --git a/deps/openssl/patches/npn.patch b/deps/openssl/patches/npn.patch
deleted file mode 100644
index 46b7a7df3..000000000
--- a/deps/openssl/patches/npn.patch
+++ /dev/null
@@ -1,1293 +0,0 @@
---- openssl-1.0.0b.orig/apps/apps.c 2010-11-11 14:42:19.000000000 +0000
-+++ openssl-1.0.0b/apps/apps.c 2010-11-29 19:56:04.902465346 +0000
-@@ -3012,3 +3012,46 @@ int raw_write_stdout(const void *buf,int
- int raw_write_stdout(const void *buf,int siz)
- { return write(fileno(stdout),buf,siz); }
- #endif
-+
-+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+/* next_protos_parse parses a comma separated list of strings into a string
-+ * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
-+ * outlen: (output) set to the length of the resulting buffer on success.
-+ * in: a NUL termianted string like "abc,def,ghi"
-+ *
-+ * returns: a malloced buffer or NULL on failure.
-+ */
-+unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
-+ {
-+ size_t len;
-+ unsigned char *out;
-+ size_t i, start = 0;
-+
-+ len = strlen(in);
-+ if (len >= 65535)
-+ return NULL;
-+
-+ out = OPENSSL_malloc(strlen(in) + 1);
-+ if (!out)
-+ return NULL;
-+
-+ for (i = 0; i <= len; ++i)
-+ {
-+ if (i == len || in[i] == ',')
-+ {
-+ if (i - start > 255)
-+ {
-+ OPENSSL_free(out);
-+ return NULL;
-+ }
-+ out[start] = i - start;
-+ start = i + 1;
-+ }
-+ else
-+ out[i+1] = in[i];
-+ }
-+
-+ *outlen = len + 1;
-+ return out;
-+ }
-+#endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
---- openssl-1.0.0b.orig/apps/apps.h 2009-10-31 13:34:19.000000000 +0000
-+++ openssl-1.0.0b/apps/apps.h 2010-11-29 19:56:04.902465346 +0000
-@@ -358,3 +358,7 @@ int raw_write_stdout(const void *,int);
- #define TM_STOP 1
- double app_tminterval (int stop,int usertime);
- #endif
-+
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+unsigned char *next_protos_parse(unsigned short *outlen, const char *in);
-+#endif
---- openssl-1.0.0b.orig/apps/s_client.c 2010-11-29 19:56:04.832465351 +0000
-+++ openssl-1.0.0b/apps/s_client.c 2010-11-29 19:56:04.902465346 +0000
-@@ -342,6 +342,9 @@ static void sc_usage(void)
- BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
- BIO_printf(bio_err," -status - request certificate status from server\n");
- BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
-+# endif
- BIO_printf(bio_err," -cutthrough - enable 1-RTT full-handshake for strong ciphers\n");
- #endif
- BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
-@@ -367,6 +370,40 @@ static int MS_CALLBACK ssl_servername_cb
-
- return SSL_TLSEXT_ERR_OK;
- }
-+
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+/* This the context that we pass to next_proto_cb */
-+typedef struct tlsextnextprotoctx_st {
-+ unsigned char *data;
-+ unsigned short len;
-+ int status;
-+} tlsextnextprotoctx;
-+
-+static tlsextnextprotoctx next_proto;
-+
-+static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
-+ {
-+ tlsextnextprotoctx *ctx = arg;
-+
-+ if (!c_quiet)
-+ {
-+ /* We can assume that |in| is syntactically valid. */
-+ unsigned i;
-+ BIO_printf(bio_c_out, "Protocols advertised by server: ");
-+ for (i = 0; i < inlen; )
-+ {
-+ if (i)
-+ BIO_write(bio_c_out, ", ", 2);
-+ BIO_write(bio_c_out, &in[i + 1], in[i]);
-+ i += in[i] + 1;
-+ }
-+ BIO_write(bio_c_out, "\n", 1);
-+ }
-+
-+ ctx->status = SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
-+ return SSL_TLSEXT_ERR_OK;
-+ }
-+# endif /* ndef OPENSSL_NO_NEXTPROTONEG */
- #endif
-
- enum
-@@ -431,6 +468,9 @@ int MAIN(int argc, char **argv)
- char *servername = NULL;
- tlsextctx tlsextcbp =
- {NULL,0};
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ const char *next_proto_neg_in = NULL;
-+# endif
- #endif
- char *sess_in = NULL;
- char *sess_out = NULL;
-@@ -658,6 +698,13 @@ int MAIN(int argc, char **argv)
- #ifndef OPENSSL_NO_TLSEXT
- else if (strcmp(*argv,"-no_ticket") == 0)
- { off|=SSL_OP_NO_TICKET; }
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ else if (strcmp(*argv,"-nextprotoneg") == 0)
-+ {
-+ if (--argc < 1) goto bad;
-+ next_proto_neg_in = *(++argv);
-+ }
-+# endif
- #endif
- else if (strcmp(*argv,"-cutthrough") == 0)
- cutthrough=1;
-@@ -766,6 +813,21 @@ bad:
- OpenSSL_add_ssl_algorithms();
- SSL_load_error_strings();
-
-+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+ next_proto.status = -1;
-+ if (next_proto_neg_in)
-+ {
-+ next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);
-+ if (next_proto.data == NULL)
-+ {
-+ BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
-+ goto end;
-+ }
-+ }
-+ else
-+ next_proto.data = NULL;
-+#endif
-+
- #ifndef OPENSSL_NO_ENGINE
- e = setup_engine(bio_err, engine_id, 1);
- if (ssl_client_engine_id)
-@@ -896,6 +958,11 @@ bad:
- SSL_CTX_set_mode(ctx, ssl_mode);
- }
-
-+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+ if (next_proto.data)
-+ SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
-+#endif
-+
- if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
- if (cipher != NULL)
- if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
-@@ -1755,6 +1822,18 @@ static void print_stuff(BIO *bio, SSL *s
- BIO_printf(bio,"Expansion: %s\n",
- expansion ? SSL_COMP_get_name(expansion) : "NONE");
- #endif
-+
-+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+ if (next_proto.status != -1) {
-+ const unsigned char *proto;
-+ unsigned int proto_len;
-+ SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
-+ BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
-+ BIO_write(bio, proto, proto_len);
-+ BIO_write(bio, "\n", 1);
-+ }
-+#endif
-+
- SSL_SESSION_print(bio,SSL_get_session(s));
- BIO_printf(bio,"---\n");
- if (peer != NULL)
---- openssl-1.0.0b.orig/apps/s_server.c 2010-06-15 17:25:02.000000000 +0000
-+++ openssl-1.0.0b/apps/s_server.c 2010-11-29 19:56:04.902465346 +0000
-@@ -492,6 +492,9 @@ static void sv_usage(void)
- BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
- BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
- BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ BIO_printf(bio_err," -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
-+# endif
- #endif
- }
-
-@@ -826,6 +829,24 @@ BIO_printf(err, "cert_status: received %
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- goto done;
- }
-+
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+/* This is the context that we pass to next_proto_cb */
-+typedef struct tlsextnextprotoctx_st {
-+ unsigned char *data;
-+ unsigned int len;
-+} tlsextnextprotoctx;
-+
-+static int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len, void *arg)
-+ {
-+ tlsextnextprotoctx *next_proto = arg;
-+
-+ *data = next_proto->data;
-+ *len = next_proto->len;
-+
-+ return SSL_TLSEXT_ERR_OK;
-+ }
-+# endif /* ndef OPENSSL_NO_NPN */
- #endif
-
- int MAIN(int, char **);
-@@ -867,6 +888,10 @@ int MAIN(int argc, char *argv[])
- #endif
- #ifndef OPENSSL_NO_TLSEXT
- tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ const char *next_proto_neg_in = NULL;
-+ tlsextnextprotoctx next_proto;
-+# endif
- #endif
- #ifndef OPENSSL_NO_PSK
- /* by default do not send a PSK identity hint */
-@@ -1191,7 +1216,13 @@ int MAIN(int argc, char *argv[])
- if (--argc < 1) goto bad;
- s_key_file2= *(++argv);
- }
--
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ else if (strcmp(*argv,"-nextprotoneg") == 0)
-+ {
-+ if (--argc < 1) goto bad;
-+ next_proto_neg_in = *(++argv);
-+ }
-+# endif
- #endif
- #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
- else if (strcmp(*argv,"-jpake") == 0)
-@@ -1476,6 +1507,11 @@ bad:
- if (vpm)
- SSL_CTX_set1_param(ctx2, vpm);
- }
-+
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ if (next_proto.data)
-+ SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto);
-+# endif
- #endif
-
- #ifndef OPENSSL_NO_DH
-@@ -1617,6 +1653,21 @@ bad:
- goto end;
- }
- }
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ if (next_proto_neg_in)
-+ {
-+ unsigned short len;
-+ next_proto.data = next_protos_parse(&len,
-+ next_proto_neg_in);
-+ if (next_proto.data == NULL)
-+ goto end;
-+ next_proto.len = len;
-+ }
-+ else
-+ {
-+ next_proto.data = NULL;
-+ }
-+# endif
- #endif
- RSA_free(rsa);
- BIO_printf(bio_s_out,"\n");
-@@ -2159,6 +2210,10 @@ static int init_ssl_connection(SSL *con)
- X509 *peer;
- long verify_error;
- MS_STATIC char buf[BUFSIZ];
-+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+ const unsigned char *next_proto_neg;
-+ unsigned next_proto_neg_len;
-+#endif
-
- if ((i=SSL_accept(con)) <= 0)
- {
-@@ -2198,6 +2253,15 @@ static int init_ssl_connection(SSL *con)
- BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
- str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
- BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
-+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+ SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
-+ if (next_proto_neg)
-+ {
-+ BIO_printf(bio_s_out,"NEXTPROTO is ");
-+ BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len);
-+ BIO_printf(bio_s_out, "\n");
-+ }
-+#endif
- if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n");
- if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
- TLS1_FLAGS_TLS_PADDING_BUG)
---- openssl-1.0.0b.orig/include/openssl/ssl.h 2010-11-29 19:56:04.846517045 +0000
-+++ openssl-1.0.0b/include/openssl/ssl.h 2010-11-29 19:56:04.965928855 +0000
-@@ -857,6 +857,25 @@ struct ssl_ctx_st
- /* draft-rescorla-tls-opaque-prf-input-00.txt information */
- int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
- void *tlsext_opaque_prf_input_callback_arg;
-+
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ /* Next protocol negotiation information */
-+ /* (for experimental NPN extension). */
-+
-+ /* For a server, this contains a callback function by which the set of
-+ * advertised protocols can be provided. */
-+ int (*next_protos_advertised_cb)(SSL *s, const unsigned char **buf,
-+ unsigned int *len, void *arg);
-+ void *next_protos_advertised_cb_arg;
-+ /* For a client, this contains a callback function that selects the
-+ * next protocol from the list provided by the server. */
-+ int (*next_proto_select_cb)(SSL *s, unsigned char **out,
-+ unsigned char *outlen,
-+ const unsigned char *in,
-+ unsigned int inlen,
-+ void *arg);
-+ void *next_proto_select_cb_arg;
-+# endif
- #endif
-
- #ifndef OPENSSL_NO_PSK
-@@ -928,6 +947,30 @@ int SSL_CTX_set_client_cert_engine(SSL_C
- #endif
- void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
- void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
-+ int (*cb) (SSL *ssl,
-+ const unsigned char **out,
-+ unsigned int *outlen,
-+ void *arg), void *arg);
-+void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
-+ int (*cb) (SSL *ssl, unsigned char **out,
-+ unsigned char *outlen,
-+ const unsigned char *in,
-+ unsigned int inlen, void *arg),
-+ void *arg);
-+
-+int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
-+ const unsigned char *in, unsigned int inlen,
-+ const unsigned char *client, unsigned int client_len);
-+void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
-+ unsigned *len);
-+
-+#define OPENSSL_NPN_UNSUPPORTED 0
-+#define OPENSSL_NPN_NEGOTIATED 1
-+#define OPENSSL_NPN_NO_OVERLAP 2
-+
-+#endif
-
- #ifndef OPENSSL_NO_PSK
- /* the maximum length of the buffer given to callbacks containing the
-@@ -1187,6 +1230,19 @@ struct ssl_st
- void *tls_session_secret_cb_arg;
-
- SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
-+
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+ /* Next protocol negotiation. For the client, this is the protocol that
-+ * we sent in NextProtocol and is set when handling ServerHello
-+ * extensions.
-+ *
-+ * For a server, this is the client's selected_protocol from
-+ * NextProtocol and is set when handling the NextProtocol message,
-+ * before the Finished message. */
-+ unsigned char *next_proto_negotiated;
-+ unsigned char next_proto_negotiated_len;
-+#endif
-+
- #define session_ctx initial_ctx
- #else
- #define session_ctx ctx
-@@ -1919,6 +1975,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_F_SSL3_GET_KEY_EXCHANGE 141
- #define SSL_F_SSL3_GET_MESSAGE 142
- #define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283
-+#define SSL_F_SSL3_GET_NEXT_PROTO 304
- #define SSL_F_SSL3_GET_RECORD 143
- #define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144
- #define SSL_F_SSL3_GET_SERVER_DONE 145
-@@ -2117,6 +2174,8 @@ void ERR_load_SSL_strings(void);
- #define SSL_R_EXCESSIVE_MESSAGE_SIZE 152
- #define SSL_R_EXTRA_DATA_IN_MESSAGE 153
- #define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154
-+#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 346
-+#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 347
- #define SSL_R_HTTPS_PROXY_REQUEST 155
- #define SSL_R_HTTP_REQUEST 156
- #define SSL_R_ILLEGAL_PADDING 283
---- openssl-1.0.0b.orig/include/openssl/ssl3.h 2010-11-29 19:56:04.832465351 +0000
-+++ openssl-1.0.0b/include/openssl/ssl3.h 2010-11-29 19:56:04.965928855 +0000
-@@ -465,6 +465,12 @@ typedef struct ssl3_state_st
- void *server_opaque_prf_input;
- size_t server_opaque_prf_input_len;
-
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+ /* Set if we saw the Next Protocol Negotiation extension from
-+ our peer. */
-+ int next_proto_neg_seen;
-+#endif
-+
- struct {
- /* actually only needs to be 16+20 */
- unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
-@@ -557,6 +563,10 @@ typedef struct ssl3_state_st
- #define SSL3_ST_CW_CERT_VRFY_B (0x191|SSL_ST_CONNECT)
- #define SSL3_ST_CW_CHANGE_A (0x1A0|SSL_ST_CONNECT)
- #define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT)
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+#define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT)
-+#define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT)
-+#endif
- #define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT)
- #define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT)
- /* read from server */
-@@ -602,6 +612,10 @@ typedef struct ssl3_state_st
- #define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT)
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+#define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT)
-+#define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT)
-+#endif
- #define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT)
- /* write to client */
-@@ -626,6 +640,9 @@ typedef struct ssl3_state_st
- #define SSL3_MT_CLIENT_KEY_EXCHANGE 16
- #define SSL3_MT_FINISHED 20
- #define SSL3_MT_CERTIFICATE_STATUS 22
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+#define SSL3_MT_NEXT_PROTO 67
-+#endif
- #define DTLS1_MT_HELLO_VERIFY_REQUEST 3
-
-
---- openssl-1.0.0b.orig/include/openssl/tls1.h 2009-11-11 14:51:29.000000000 +0000
-+++ openssl-1.0.0b/include/openssl/tls1.h 2010-11-29 19:56:04.965928855 +0000
-@@ -204,6 +204,11 @@ extern "C" {
- /* Temporary extension type */
- #define TLSEXT_TYPE_renegotiate 0xff01
-
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+/* This is not an IANA defined extension number */
-+#define TLSEXT_TYPE_next_proto_neg 13172
-+#endif
-+
- /* NameType value from RFC 3546 */
- #define TLSEXT_NAMETYPE_host_name 0
- /* status request value from RFC 3546 */
---- openssl-1.0.0b.orig/ssl/s3_both.c 2010-11-29 19:56:04.846517045 +0000
-+++ openssl-1.0.0b/ssl/s3_both.c 2010-11-29 19:56:04.965928855 +0000
-@@ -202,15 +202,40 @@ int ssl3_send_finished(SSL *s, int a, in
- return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
- }
-
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
-+static void ssl3_take_mac(SSL *s)
-+ {
-+ const char *sender;
-+ int slen;
-+
-+ if (s->state & SSL_ST_CONNECT)
-+ {
-+ sender=s->method->ssl3_enc->server_finished_label;
-+ slen=s->method->ssl3_enc->server_finished_label_len;
-+ }
-+ else
-+ {
-+ sender=s->method->ssl3_enc->client_finished_label;
-+ slen=s->method->ssl3_enc->client_finished_label_len;
-+ }
-+
-+ s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
-+ sender,slen,s->s3->tmp.peer_finish_md);
-+ }
-+#endif
-+
- int ssl3_get_finished(SSL *s, int a, int b)
- {
- int al,i,ok;
- long n;
- unsigned char *p;
-
-+#ifdef OPENSSL_NO_NEXTPROTONEG
- /* the mac has already been generated when we received the
- * change cipher spec message and is in s->s3->tmp.peer_finish_md
- */
-+#endif
-
- n=s->method->ssl_get_message(s,
- a,
-@@ -521,6 +546,15 @@ long ssl3_get_message(SSL *s, int st1, i
- s->init_num += i;
- n -= i;
- }
-+
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+ /* If receiving Finished, record MAC of prior handshake messages for
-+ * Finished verification. */
-+ if (*s->init_buf->data == SSL3_MT_FINISHED)
-+ ssl3_take_mac(s);
-+#endif
-+
-+ /* Feed this message into MAC computation. */
- ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
- if (s->msg_callback)
- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
---- openssl-1.0.0b.orig/ssl/s3_clnt.c 2010-11-29 19:56:04.846517045 +0000
-+++ openssl-1.0.0b/ssl/s3_clnt.c 2010-11-29 19:56:04.965928855 +0000
-@@ -435,7 +435,16 @@ int ssl3_connect(SSL *s)
- ret=ssl3_send_change_cipher_spec(s,
- SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
- if (ret <= 0) goto end;
-+
-+#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
- s->state=SSL3_ST_CW_FINISHED_A;
-+#else
-+ if (s->next_proto_negotiated)
-+ s->state=SSL3_ST_CW_NEXT_PROTO_A;
-+ else
-+ s->state=SSL3_ST_CW_FINISHED_A;
-+#endif
-+
- s->init_num=0;
-
- s->session->cipher=s->s3->tmp.new_cipher;
-@@ -463,6 +472,15 @@ int ssl3_connect(SSL *s)
-
- break;
-
-+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+ case SSL3_ST_CW_NEXT_PROTO_A:
-+ case SSL3_ST_CW_NEXT_PROTO_B:
-+ ret=ssl3_send_next_proto(s);
-+ if (ret <= 0) goto end;
-+ s->state=SSL3_ST_CW_FINISHED_A;
-+ break;
-+#endif
-+
- case SSL3_ST_CW_FINISHED_A:
- case SSL3_ST_CW_FINISHED_B:
- ret=ssl3_send_finished(s,
-@@ -3060,6 +3078,32 @@ err:
- */
-
- #ifndef OPENSSL_NO_TLSEXT
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+int ssl3_send_next_proto(SSL *s)
-+ {
-+ unsigned int len, padding_len;
-+ unsigned char *d;
-+
-+ if (s->state == SSL3_ST_CW_NEXT_PROTO_A)
-+ {
-+ len = s->next_proto_negotiated_len;
-+ padding_len = 32 - ((len + 2) % 32);
-+ d = (unsigned char *)s->init_buf->data;
-+ d[4] = len;
-+ memcpy(d + 5, s->next_proto_negotiated, len);
-+ d[5 + len] = padding_len;
-+ memset(d + 6 + len, 0, padding_len);
-+ *(d++)=SSL3_MT_NEXT_PROTO;
-+ l2n3(2 + len + padding_len, d);
-+ s->state = SSL3_ST_CW_NEXT_PROTO_B;
-+ s->init_num = 4 + 2 + len + padding_len;
-+ s->init_off = 0;
-+ }
-+
-+ return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
-+ }
-+# endif
-+
- int ssl3_check_finished(SSL *s)
- {
- int ok;
---- openssl-1.0.0b.orig/ssl/s3_lib.c 2010-11-29 19:56:04.832465351 +0000
-+++ openssl-1.0.0b/ssl/s3_lib.c 2010-11-29 19:56:04.965928855 +0000
-@@ -2230,6 +2230,15 @@ void ssl3_clear(SSL *s)
- s->s3->num_renegotiations=0;
- s->s3->in_read_app_data=0;
- s->version=SSL3_VERSION;
-+
-+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+ if (s->next_proto_negotiated)
-+ {
-+ OPENSSL_free(s->next_proto_negotiated);
-+ s->next_proto_negotiated = NULL;
-+ s->next_proto_negotiated_len = 0;
-+ }
-+#endif
- }
-
- long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
---- openssl-1.0.0b.orig/ssl/s3_pkt.c 2010-11-29 19:56:04.832465351 +0000
-+++ openssl-1.0.0b/ssl/s3_pkt.c 2010-11-29 19:56:04.965928855 +0000
-@@ -1394,8 +1394,10 @@ err:
- int ssl3_do_change_cipher_spec(SSL *s)
- {
- int i;
-+#ifdef OPENSSL_NO_NEXTPROTONEG
- const char *sender;
- int slen;
-+#endif
-
- if (s->state & SSL_ST_ACCEPT)
- i=SSL3_CHANGE_CIPHER_SERVER_READ;
-@@ -1418,6 +1420,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
- if (!s->method->ssl3_enc->change_cipher_state(s,i))
- return(0);
-
-+#ifdef OPENSSL_NO_NEXTPROTONEG
- /* we have to record the message digest at
- * this point so we can get it before we read
- * the finished message */
-@@ -1434,6 +1437,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
-
- s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
- sender,slen,s->s3->tmp.peer_finish_md);
-+#endif
-
- return(1);
- }
---- openssl-1.0.0b.orig/ssl/s3_srvr.c 2010-11-29 19:56:04.846517045 +0000
-+++ openssl-1.0.0b/ssl/s3_srvr.c 2010-11-29 19:56:04.965928855 +0000
-@@ -538,7 +538,14 @@ int ssl3_accept(SSL *s)
- * the client uses its key from the certificate
- * for key exchange.
- */
-+#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
- s->state=SSL3_ST_SR_FINISHED_A;
-+#else
-+ if (s->s3->next_proto_neg_seen)
-+ s->state=SSL3_ST_SR_NEXT_PROTO_A;
-+ else
-+ s->state=SSL3_ST_SR_FINISHED_A;
-+#endif
- s->init_num = 0;
- }
- else
-@@ -581,10 +588,27 @@ int ssl3_accept(SSL *s)
- ret=ssl3_get_cert_verify(s);
- if (ret <= 0) goto end;
-
-+#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
- s->state=SSL3_ST_SR_FINISHED_A;
-+#else
-+ if (s->s3->next_proto_neg_seen)
-+ s->state=SSL3_ST_SR_NEXT_PROTO_A;
-+ else
-+ s->state=SSL3_ST_SR_FINISHED_A;
-+#endif
- s->init_num=0;
- break;
-
-+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+ case SSL3_ST_SR_NEXT_PROTO_A:
-+ case SSL3_ST_SR_NEXT_PROTO_B:
-+ ret=ssl3_get_next_proto(s);
-+ if (ret <= 0) goto end;
-+ s->init_num = 0;
-+ s->state=SSL3_ST_SR_FINISHED_A;
-+ break;
-+#endif
-+
- case SSL3_ST_SR_FINISHED_A:
- case SSL3_ST_SR_FINISHED_B:
- ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
-@@ -655,7 +679,16 @@ int ssl3_accept(SSL *s)
- if (ret <= 0) goto end;
- s->state=SSL3_ST_SW_FLUSH;
- if (s->hit)
-+ {
-+#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
- s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
-+#else
-+ if (s->s3->next_proto_neg_seen)
-+ s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
-+ else
-+ s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
-+#endif
-+ }
- else
- s->s3->tmp.next_state=SSL_ST_OK;
- s->init_num=0;
-@@ -3196,4 +3229,72 @@ int ssl3_send_cert_status(SSL *s)
- /* SSL3_ST_SW_CERT_STATUS_B */
- return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
- }
-+
-+# ifndef OPENSSL_NO_NPN
-+/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It
-+ * sets the next_proto member in s if found */
-+int ssl3_get_next_proto(SSL *s)
-+ {
-+ int ok;
-+ unsigned proto_len, padding_len;
-+ long n;
-+ const unsigned char *p;
-+
-+ /* Clients cannot send a NextProtocol message if we didn't see the
-+ * extension in their ClientHello */
-+ if (!s->s3->next_proto_neg_seen)
-+ {
-+ SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
-+ return -1;
-+ }
-+
-+ n=s->method->ssl_get_message(s,
-+ SSL3_ST_SR_NEXT_PROTO_A,
-+ SSL3_ST_SR_NEXT_PROTO_B,
-+ SSL3_MT_NEXT_PROTO,
-+ 514, /* See the payload format below */
-+ &ok);
-+
-+ if (!ok)
-+ return((int)n);
-+
-+ /* s->state doesn't reflect whether ChangeCipherSpec has been received
-+ * in this handshake, but s->s3->change_cipher_spec does (will be reset
-+ * by ssl3_get_finished). */
-+ if (!s->s3->change_cipher_spec)
-+ {
-+ SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
-+ return -1;
-+ }
-+
-+ if (n < 2)
-+ return 0; /* The body must be > 1 bytes long */
-+
-+ p=(unsigned char *)s->init_msg;
-+
-+ /* The payload looks like:
-+ * uint8 proto_len;
-+ * uint8 proto[proto_len];
-+ * uint8 padding_len;
-+ * uint8 padding[padding_len];
-+ */
-+ proto_len = p[0];
-+ if (proto_len + 2 > s->init_num)
-+ return 0;
-+ padding_len = p[proto_len + 1];
-+ if (proto_len + padding_len + 2 != s->init_num)
-+ return 0;
-+
-+ s->next_proto_negotiated = OPENSSL_malloc(proto_len);
-+ if (!s->next_proto_negotiated)
-+ {
-+ SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,ERR_R_MALLOC_FAILURE);
-+ return 0;
-+ }
-+ memcpy(s->next_proto_negotiated, p + 1, proto_len);
-+ s->next_proto_negotiated_len = proto_len;
-+
-+ return 1;
-+ }
-+# endif
- #endif
---- openssl-1.0.0b.orig/ssl/ssl.h 2010-11-29 19:56:04.846517045 +0000
-+++ openssl-1.0.0b/ssl/ssl.h 2010-11-29 19:56:04.965928855 +0000
-@@ -857,6 +857,25 @@ struct ssl_ctx_st
- /* draft-rescorla-tls-opaque-prf-input-00.txt information */
- int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
- void *tlsext_opaque_prf_input_callback_arg;
-+
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ /* Next protocol negotiation information */
-+ /* (for experimental NPN extension). */
-+
-+ /* For a server, this contains a callback function by which the set of
-+ * advertised protocols can be provided. */
-+ int (*next_protos_advertised_cb)(SSL *s, const unsigned char **buf,
-+ unsigned int *len, void *arg);
-+ void *next_protos_advertised_cb_arg;
-+ /* For a client, this contains a callback function that selects the
-+ * next protocol from the list provided by the server. */
-+ int (*next_proto_select_cb)(SSL *s, unsigned char **out,
-+ unsigned char *outlen,
-+ const unsigned char *in,
-+ unsigned int inlen,
-+ void *arg);
-+ void *next_proto_select_cb_arg;
-+# endif
- #endif
-
- #ifndef OPENSSL_NO_PSK
-@@ -928,6 +947,30 @@ int SSL_CTX_set_client_cert_engine(SSL_C
- #endif
- void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
- void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
-+ int (*cb) (SSL *ssl,
-+ const unsigned char **out,
-+ unsigned int *outlen,
-+ void *arg), void *arg);
-+void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
-+ int (*cb) (SSL *ssl, unsigned char **out,
-+ unsigned char *outlen,
-+ const unsigned char *in,
-+ unsigned int inlen, void *arg),
-+ void *arg);
-+
-+int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
-+ const unsigned char *in, unsigned int inlen,
-+ const unsigned char *client, unsigned int client_len);
-+void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
-+ unsigned *len);
-+
-+#define OPENSSL_NPN_UNSUPPORTED 0
-+#define OPENSSL_NPN_NEGOTIATED 1
-+#define OPENSSL_NPN_NO_OVERLAP 2
-+
-+#endif
-
- #ifndef OPENSSL_NO_PSK
- /* the maximum length of the buffer given to callbacks containing the
-@@ -1187,6 +1230,19 @@ struct ssl_st
- void *tls_session_secret_cb_arg;
-
- SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
-+
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+ /* Next protocol negotiation. For the client, this is the protocol that
-+ * we sent in NextProtocol and is set when handling ServerHello
-+ * extensions.
-+ *
-+ * For a server, this is the client's selected_protocol from
-+ * NextProtocol and is set when handling the NextProtocol message,
-+ * before the Finished message. */
-+ unsigned char *next_proto_negotiated;
-+ unsigned char next_proto_negotiated_len;
-+#endif
-+
- #define session_ctx initial_ctx
- #else
- #define session_ctx ctx
-@@ -1919,6 +1975,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_F_SSL3_GET_KEY_EXCHANGE 141
- #define SSL_F_SSL3_GET_MESSAGE 142
- #define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283
-+#define SSL_F_SSL3_GET_NEXT_PROTO 304
- #define SSL_F_SSL3_GET_RECORD 143
- #define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144
- #define SSL_F_SSL3_GET_SERVER_DONE 145
-@@ -2117,6 +2174,8 @@ void ERR_load_SSL_strings(void);
- #define SSL_R_EXCESSIVE_MESSAGE_SIZE 152
- #define SSL_R_EXTRA_DATA_IN_MESSAGE 153
- #define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154
-+#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 346
-+#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 347
- #define SSL_R_HTTPS_PROXY_REQUEST 155
- #define SSL_R_HTTP_REQUEST 156
- #define SSL_R_ILLEGAL_PADDING 283
---- openssl-1.0.0b.orig/ssl/ssl3.h 2010-11-29 19:56:04.832465351 +0000
-+++ openssl-1.0.0b/ssl/ssl3.h 2010-11-29 19:56:04.965928855 +0000
-@@ -465,6 +465,12 @@ typedef struct ssl3_state_st
- void *server_opaque_prf_input;
- size_t server_opaque_prf_input_len;
-
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+ /* Set if we saw the Next Protocol Negotiation extension from
-+ our peer. */
-+ int next_proto_neg_seen;
-+#endif
-+
- struct {
- /* actually only needs to be 16+20 */
- unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
-@@ -557,6 +563,10 @@ typedef struct ssl3_state_st
- #define SSL3_ST_CW_CERT_VRFY_B (0x191|SSL_ST_CONNECT)
- #define SSL3_ST_CW_CHANGE_A (0x1A0|SSL_ST_CONNECT)
- #define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT)
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+#define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT)
-+#define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT)
-+#endif
- #define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT)
- #define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT)
- /* read from server */
-@@ -602,6 +612,10 @@ typedef struct ssl3_state_st
- #define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT)
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+#define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT)
-+#define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT)
-+#endif
- #define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT)
- /* write to client */
-@@ -626,6 +640,9 @@ typedef struct ssl3_state_st
- #define SSL3_MT_CLIENT_KEY_EXCHANGE 16
- #define SSL3_MT_FINISHED 20
- #define SSL3_MT_CERTIFICATE_STATUS 22
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+#define SSL3_MT_NEXT_PROTO 67
-+#endif
- #define DTLS1_MT_HELLO_VERIFY_REQUEST 3
-
-
---- openssl-1.0.0b.orig/ssl/ssl_err.c 2010-11-29 19:56:04.846517045 +0000
-+++ openssl-1.0.0b/ssl/ssl_err.c 2010-11-29 19:56:04.965928855 +0000
-@@ -155,6 +155,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
- {ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE), "SSL3_GET_KEY_EXCHANGE"},
- {ERR_FUNC(SSL_F_SSL3_GET_MESSAGE), "SSL3_GET_MESSAGE"},
- {ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET), "SSL3_GET_NEW_SESSION_TICKET"},
-+{ERR_FUNC(SSL_F_SSL3_GET_NEXT_PROTO), "SSL3_GET_NEXT_PROTO"},
- {ERR_FUNC(SSL_F_SSL3_GET_RECORD), "SSL3_GET_RECORD"},
- {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE), "SSL3_GET_SERVER_CERTIFICATE"},
- {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE), "SSL3_GET_SERVER_DONE"},
-@@ -355,6 +356,8 @@ static ERR_STRING_DATA SSL_str_reasons[]
- {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE),"excessive message size"},
- {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) ,"extra data in message"},
- {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS),"got a fin before a ccs"},
-+{ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS),"got next proto before a ccs"},
-+{ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION),"got next proto without seeing extension"},
- {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) ,"https proxy request"},
- {ERR_REASON(SSL_R_HTTP_REQUEST) ,"http request"},
- {ERR_REASON(SSL_R_ILLEGAL_PADDING) ,"illegal padding"},
---- openssl-1.0.0b.orig/ssl/ssl_lib.c 2010-11-29 19:56:04.846517045 +0000
-+++ openssl-1.0.0b/ssl/ssl_lib.c 2010-11-29 19:56:04.965928855 +0000
-@@ -354,6 +354,9 @@ SSL *SSL_new(SSL_CTX *ctx)
- s->tlsext_ocsp_resplen = -1;
- CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
- s->initial_ctx=ctx;
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ s->next_proto_negotiated = NULL;
-+# endif
- #endif
-
- s->verify_result=X509_V_OK;
-@@ -587,6 +590,11 @@ void SSL_free(SSL *s)
- kssl_ctx_free(s->kssl_ctx);
- #endif /* OPENSSL_NO_KRB5 */
-
-+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+ if (s->next_proto_negotiated)
-+ OPENSSL_free(s->next_proto_negotiated);
-+#endif
-+
- OPENSSL_free(s);
- }
-
-@@ -1503,6 +1511,124 @@ int SSL_get_servername_type(const SSL *s
- return TLSEXT_NAMETYPE_host_name;
- return -1;
- }
-+
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+/* SSL_select_next_proto implements the standard protocol selection. It is
-+ * expected that this function is called from the callback set by
-+ * SSL_CTX_set_next_proto_select_cb.
-+ *
-+ * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
-+ * strings. The length byte itself is not included in the length. A byte
-+ * string of length 0 is invalid. No byte string may be truncated.
-+ *
-+ * The current, but experimental algorithm for selecting the protocol is:
-+ *
-+ * 1) If the server doesn't support NPN then this is indicated to the
-+ * callback. In this case, the client application has to abort the connection
-+ * or have a default application level protocol.
-+ *
-+ * 2) If the server supports NPN, but advertises an empty list then the
-+ * client selects the first protcol in its list, but indicates via the
-+ * API that this fallback case was enacted.
-+ *
-+ * 3) Otherwise, the client finds the first protocol in the server's list
-+ * that it supports and selects this protocol. This is because it's
-+ * assumed that the server has better information about which protocol
-+ * a client should use.
-+ *
-+ * 4) If the client doesn't support any of the server's advertised
-+ * protocols, then this is treated the same as case 2.
-+ *
-+ * It returns either
-+ * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
-+ * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
-+ */
-+int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, const unsigned char *server, unsigned int server_len, const unsigned char *client, unsigned int client_len)
-+ {
-+ unsigned int i, j;
-+ const unsigned char *result;
-+ int status = OPENSSL_NPN_UNSUPPORTED;
-+
-+ /* For each protocol in server preference order, see if we support it. */
-+ for (i = 0; i < server_len; )
-+ {
-+ for (j = 0; j < client_len; )
-+ {
-+ if (server[i] == client[j] &&
-+ memcmp(&server[i+1], &client[j+1], server[i]) == 0)
-+ {
-+ /* We found a match */
-+ result = &server[i];
-+ status = OPENSSL_NPN_NEGOTIATED;
-+ goto found;
-+ }
-+ j += client[j];
-+ j++;
-+ }
-+ i += server[i];
-+ i++;
-+ }
-+
-+ /* There's no overlap between our protocols and the server's list. */
-+ result = client;
-+ status = OPENSSL_NPN_NO_OVERLAP;
-+
-+ found:
-+ *out = (unsigned char *) result + 1;
-+ *outlen = result[0];
-+ return status;
-+ }
-+
-+/* SSL_get0_next_proto_negotiated sets *data and *len to point to the client's
-+ * requested protocol for this connection and returns 0. If the client didn't
-+ * request any protocol, then *data is set to NULL.
-+ *
-+ * Note that the client can request any protocol it chooses. The value returned
-+ * from this function need not be a member of the list of supported protocols
-+ * provided by the callback.
-+ */
-+void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, unsigned *len)
-+ {
-+ *data = s->next_proto_negotiated;
-+ if (!*data) {
-+ *len = 0;
-+ } else {
-+ *len = s->next_proto_negotiated_len;
-+ }
-+}
-+
-+/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
-+ * TLS server needs a list of supported protocols for Next Protocol
-+ * Negotiation. The returned list must be in wire format. The list is returned
-+ * by setting |out| to point to it and |outlen| to its length. This memory will
-+ * not be modified, but one should assume that the SSL* keeps a reference to
-+ * it.
-+ *
-+ * The callback should return SSL_TLSEXT_ERR_OK if it wishes to advertise. Otherwise, no
-+ * such extension will be included in the ServerHello. */
-+void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx, int (*cb) (SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg), void *arg)
-+ {
-+ ctx->next_protos_advertised_cb = cb;
-+ ctx->next_protos_advertised_cb_arg = arg;
-+ }
-+
-+/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
-+ * client needs to select a protocol from the server's provided list. |out|
-+ * must be set to point to the selected protocol (which may be within |in|).
-+ * The length of the protocol name must be written into |outlen|. The server's
-+ * advertised protocols are provided in |in| and |inlen|. The callback can
-+ * assume that |in| is syntactically valid.
-+ *
-+ * The client must select a protocol. It is fatal to the connection if this
-+ * callback returns a value other than SSL_TLSEXT_ERR_OK.
-+ */
-+void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg), void *arg)
-+ {
-+ ctx->next_proto_select_cb = cb;
-+ ctx->next_proto_select_cb_arg = arg;
-+ }
-+
-+# endif
- #endif
-
- static unsigned long ssl_session_hash(const SSL_SESSION *a)
-@@ -1667,6 +1793,10 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *m
- ret->tlsext_status_cb = 0;
- ret->tlsext_status_arg = NULL;
-
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+ ret->next_protos_advertised_cb = 0;
-+ ret->next_proto_select_cb = 0;
-+# endif
- #endif
- #ifndef OPENSSL_NO_PSK
- ret->psk_identity_hint=NULL;
---- openssl-1.0.0b.orig/ssl/ssl_locl.h 2010-11-29 19:56:04.846517045 +0000
-+++ openssl-1.0.0b/ssl/ssl_locl.h 2010-11-29 19:56:04.965928855 +0000
-@@ -968,6 +968,9 @@ int ssl3_get_server_certificate(SSL *s);
- int ssl3_check_cert_and_algorithm(SSL *s);
- #ifndef OPENSSL_NO_TLSEXT
- int ssl3_check_finished(SSL *s);
-+# ifndef OPENSSL_NO_NEXTPROTONEG
-+int ssl3_send_next_proto(SSL *s);
-+# endif
- #endif
-
- int dtls1_client_hello(SSL *s);
-@@ -986,6 +989,9 @@ int ssl3_check_client_hello(SSL *s);
- int ssl3_get_client_certificate(SSL *s);
- int ssl3_get_client_key_exchange(SSL *s);
- int ssl3_get_cert_verify(SSL *s);
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+int ssl3_get_next_proto(SSL *s);
-+#endif
-
- int dtls1_send_hello_request(SSL *s);
- int dtls1_send_server_hello(SSL *s);
---- openssl-1.0.0b.orig/ssl/t1_lib.c 2010-11-16 13:26:24.000000000 +0000
-+++ openssl-1.0.0b/ssl/t1_lib.c 2010-11-29 19:56:04.965928855 +0000
-@@ -494,6 +494,18 @@ unsigned char *ssl_add_clienthello_tlsex
- i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
- }
-
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+ if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len)
-+ {
-+ /* The client advertises an emtpy extension to indicate its
-+ * support for Next Protocol Negotiation */
-+ if (limit - ret - 4 < 0)
-+ return NULL;
-+ s2n(TLSEXT_TYPE_next_proto_neg,ret);
-+ s2n(0,ret);
-+ }
-+#endif
-+
- if ((extdatalen = ret-p-2)== 0)
- return p;
-
-@@ -505,6 +517,9 @@ unsigned char *ssl_add_serverhello_tlsex
- {
- int extdatalen=0;
- unsigned char *ret = p;
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+ int next_proto_neg_seen;
-+#endif
-
- /* don't add extensions for SSLv3, unless doing secure renegotiation */
- if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
-@@ -618,6 +633,28 @@ unsigned char *ssl_add_serverhello_tlsex
-
- }
-
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+ next_proto_neg_seen = s->s3->next_proto_neg_seen;
-+ s->s3->next_proto_neg_seen = 0;
-+ if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb)
-+ {
-+ const unsigned char *npa;
-+ unsigned int npalen;
-+ int r;
-+
-+ r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, s->ctx->next_protos_advertised_cb_arg);
-+ if (r == SSL_TLSEXT_ERR_OK)
-+ {
-+ if ((long)(limit - ret - 4 - npalen) < 0) return NULL;
-+ s2n(TLSEXT_TYPE_next_proto_neg,ret);
-+ s2n(npalen,ret);
-+ memcpy(ret, npa, npalen);
-+ ret += npalen;
-+ s->s3->next_proto_neg_seen = 1;
-+ }
-+ }
-+#endif
-+
- if ((extdatalen = ret-p-2)== 0)
- return p;
-
-@@ -982,6 +1019,28 @@ int ssl_parse_clienthello_tlsext(SSL *s,
- else
- s->tlsext_status_type = -1;
- }
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+ else if (type == TLSEXT_TYPE_next_proto_neg &&
-+ s->s3->tmp.finish_md_len == 0)
-+ {
-+ /* We shouldn't accept this extension on a
-+ * renegotiation.
-+ *
-+ * s->new_session will be set on renegotiation, but we
-+ * probably shouldn't rely that it couldn't be set on
-+ * the initial renegotation too in certain cases (when
-+ * there's some other reason to disallow resuming an
-+ * earlier session -- the current code won't be doing
-+ * anything like that, but this might change).
-+
-+ * A valid sign that there's been a previous handshake
-+ * in this connection is if s->s3->tmp.finish_md_len >
-+ * 0. (We are talking about a check that will happen
-+ * in the Hello protocol round, well before a new
-+ * Finished message could have been computed.) */
-+ s->s3->next_proto_neg_seen = 1;
-+ }
-+#endif
-
- /* session ticket processed earlier */
- data+=size;
-@@ -1005,6 +1064,26 @@ int ssl_parse_clienthello_tlsext(SSL *s,
- return 1;
- }
-
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+/* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
-+ * elements of zero length are allowed and the set of elements must exactly fill
-+ * the length of the block. */
-+static int ssl_next_proto_validate(unsigned char *d, unsigned len)
-+ {
-+ unsigned int off = 0;
-+
-+ while (off < len)
-+ {
-+ if (d[off] == 0)
-+ return 0;
-+ off += d[off];
-+ off++;
-+ }
-+
-+ return off == len;
-+ }
-+#endif
-+
- int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
- {
- unsigned short length;
-@@ -1139,6 +1218,39 @@ int ssl_parse_serverhello_tlsext(SSL *s,
- /* Set flag to expect CertificateStatus message */
- s->tlsext_status_expected = 1;
- }
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+ else if (type == TLSEXT_TYPE_next_proto_neg)
-+ {
-+ unsigned char *selected;
-+ unsigned char selected_len;
-+
-+ /* We must have requested it. */
-+ if ((s->ctx->next_proto_select_cb == NULL))
-+ {
-+ *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-+ return 0;
-+ }
-+ /* The data must be valid */
-+ if (!ssl_next_proto_validate(data, size))
-+ {
-+ *al = TLS1_AD_DECODE_ERROR;
-+ return 0;
-+ }
-+ if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data, size, s->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK)
-+ {
-+ *al = TLS1_AD_INTERNAL_ERROR;
-+ return 0;
-+ }
-+ s->next_proto_negotiated = OPENSSL_malloc(selected_len);
-+ if (!s->next_proto_negotiated)
-+ {
-+ *al = TLS1_AD_INTERNAL_ERROR;
-+ return 0;
-+ }
-+ memcpy(s->next_proto_negotiated, selected, selected_len);
-+ s->next_proto_negotiated_len = selected_len;
-+ }
-+#endif
- else if (type == TLSEXT_TYPE_renegotiate)
- {
- if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
---- openssl-1.0.0b.orig/ssl/tls1.h 2009-11-11 14:51:29.000000000 +0000
-+++ openssl-1.0.0b/ssl/tls1.h 2010-11-29 19:56:04.965928855 +0000
-@@ -204,6 +204,11 @@ extern "C" {
- /* Temporary extension type */
- #define TLSEXT_TYPE_renegotiate 0xff01
-
-+#ifndef OPENSSL_NO_NEXTPROTONEG
-+/* This is not an IANA defined extension number */
-+#define TLSEXT_TYPE_next_proto_neg 13172
-+#endif
-+
- /* NameType value from RFC 3546 */
- #define TLSEXT_NAMETYPE_host_name 0
- /* status request value from RFC 3546 */
diff --git a/deps/openssl/patches/openssl_no_dtls1.patch b/deps/openssl/patches/openssl_no_dtls1.patch
deleted file mode 100644
index 8b61cd3f6..000000000
--- a/deps/openssl/patches/openssl_no_dtls1.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- openssl-1.0.0f.orig/ssl/ssl_lib.c 2012-01-04 22:13:21.000000000 +0000
-+++ openssl-1.0.0f/ssl/ssl_lib.c 2012-01-04 22:13:21.000000000 +0000
-@@ -1063,8 +1063,10 @@ long SSL_ctrl(SSL *s,int cmd,long larg,v
- s->max_cert_list=larg;
- return(l);
- case SSL_CTRL_SET_MTU:
-+#ifndef OPENSSL_NO_DTLS1
- if (larg < (long)dtls1_min_mtu())
- return 0;
-+#endif
-
- if (SSL_version(s) == DTLS1_VERSION ||
- SSL_version(s) == DTLS1_BAD_VER)
diff --git a/deps/openssl/patches/progs.patch b/deps/openssl/patches/progs.patch
deleted file mode 100644
index 16fd9b0b3..000000000
--- a/deps/openssl/patches/progs.patch
+++ /dev/null
@@ -1,54 +0,0 @@
---- openssl-1.0.0.orig/apps/openssl.c 2009-10-04 09:43:21.000000000 -0700
-+++ openssl-1.0.0/apps/openssl.c 2010-05-18 14:05:14.000000000 -0700
-@@ -275,8 +275,10 @@ int main(int Argc, char *Argv[])
- if (ERR_GET_REASON(ERR_peek_last_error())
- == CONF_R_NO_SUCH_FILE)
- {
-+#if 0 /* ANDROID */
- BIO_printf(bio_err,
- "WARNING: can't open config file: %s\n",p);
-+#endif
- ERR_clear_error();
- NCONF_free(config);
- config = NULL;
---- openssl-1.0.0.orig/apps/progs.h 2009-06-30 08:08:38.000000000 -0700
-+++ openssl-1.0.0/apps/progs.h 2010-05-18 14:05:38.000000000 -0700
-@@ -146,7 +152,9 @@ FUNCTION functions[] = {
- {FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
- #endif
- {FUNC_TYPE_GENERAL,"prime",prime_main},
-+#if 0 /* ANDROID */
- {FUNC_TYPE_GENERAL,"ts",ts_main},
-+#endif
- #ifndef OPENSSL_NO_MD2
- {FUNC_TYPE_MD,"md2",dgst_main},
- #endif
---- openssl-1.0.0.orig/apps/speed.c 2010-03-03 11:56:17.000000000 -0800
-+++ openssl-1.0.0/apps/speed.c 2010-05-18 14:05:57.000000000 -0700
-@@ -1718,6 +1718,7 @@ int MAIN(int argc, char **argv)
- }
- }
-
-+#if 0 /* ANDROID */
- if (doit[D_IGE_128_AES])
- {
- for (j=0; j<SIZE_NUM; j++)
-@@ -1763,6 +1764,7 @@ int MAIN(int argc, char **argv)
-
-
- #endif
-+#endif
- #ifndef OPENSSL_NO_CAMELLIA
- if (doit[D_CBC_128_CML])
- {
---- openssl-1.0.0.orig/crypto/ui/ui_openssl.c 2009-10-04 09:43:21.000000000 -0700
-+++ openssl-1.0.0/crypto/ui/ui_openssl.c 2010-05-18 13:36:26.000000000 -0700
-@@ -184,7 +184,7 @@
- # undef SGTTY
- #endif
-
--#if defined(linux) && !defined(TERMIO)
-+#if defined(linux) && !defined(TERMIO) && !defined(__ANDROID__)
- # undef TERMIOS
- # define TERMIO
- # undef SGTTY
diff --git a/deps/openssl/patches/sha1_armv4_large.patch b/deps/openssl/patches/sha1_armv4_large.patch
deleted file mode 100644
index 359ff94af..000000000
--- a/deps/openssl/patches/sha1_armv4_large.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff --git a/crypto/sha/asm/sha1-armv4-large.pl b/crypto/sha/asm/sha1-armv4-large.pl
-index 6e65fe3..79e3f61 100644
---- a/crypto/sha/asm/sha1-armv4-large.pl
-+++ b/crypto/sha/asm/sha1-armv4-large.pl
-@@ -161,6 +161,7 @@ for($i=0;$i<5;$i++) {
- $code.=<<___;
- teq $Xi,sp
- bne .L_00_15 @ [((11+4)*5+2)*3]
-+ sub sp,sp,#5*4
- ___
- &BODY_00_15(@V); unshift(@V,pop(@V));
- &BODY_16_19(@V); unshift(@V,pop(@V));
-@@ -170,7 +171,7 @@ ___
- $code.=<<___;
-
- ldr $K,.LK_20_39 @ [+15+16*4]
-- sub sp,sp,#25*4
-+ sub sp,sp,#20*4
- cmn sp,#0 @ [+3], clear carry to denote 20_39
- .L_20_39_or_60_79:
- ___
diff --git a/deps/openssl/patches/small_records.patch b/deps/openssl/patches/small_records.patch
deleted file mode 100644
index a2ea51ca4..000000000
--- a/deps/openssl/patches/small_records.patch
+++ /dev/null
@@ -1,337 +0,0 @@
---- openssl-1.0.0a.orig/ssl/d1_pkt.c 2010-04-14 00:09:55.000000000 +0000
-+++ openssl-1.0.0a/ssl/d1_pkt.c 2010-08-25 21:12:39.000000000 +0000
-@@ -608,6 +608,24 @@ again:
- goto again;
- }
-
-+ /* If we receive a valid record larger than the current buffer size,
-+ * allocate some memory for it.
-+ */
-+ if (rr->length > s->s3->rbuf.len - DTLS1_RT_HEADER_LENGTH)
-+ {
-+ unsigned char *pp;
-+ unsigned int newlen = rr->length + DTLS1_RT_HEADER_LENGTH;
-+ if ((pp=OPENSSL_realloc(s->s3->rbuf.buf, newlen))==NULL)
-+ {
-+ SSLerr(SSL_F_DTLS1_GET_RECORD,ERR_R_MALLOC_FAILURE);
-+ return(-1);
-+ }
-+ p = pp + (p - s->s3->rbuf.buf);
-+ s->s3->rbuf.buf=pp;
-+ s->s3->rbuf.len=newlen;
-+ s->packet= &(s->s3->rbuf.buf[0]);
-+ }
-+
- /* now s->rstate == SSL_ST_READ_BODY */
- }
-
-@@ -1342,6 +1360,7 @@ int do_dtls1_write(SSL *s, int type, con
- SSL3_BUFFER *wb;
- SSL_SESSION *sess;
- int bs;
-+ unsigned int len_with_overhead = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
-
- /* first check if there is a SSL3_BUFFER still being written
- * out. This will happen with non blocking IO */
-@@ -1351,6 +1370,16 @@ int do_dtls1_write(SSL *s, int type, con
- return(ssl3_write_pending(s,type,buf,len));
- }
-
-+ if (s->s3->wbuf.len < len_with_overhead)
-+ {
-+ if ((p=OPENSSL_realloc(s->s3->wbuf.buf, len_with_overhead)) == NULL) {
-+ SSLerr(SSL_F_DO_DTLS1_WRITE,ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ s->s3->wbuf.buf = p;
-+ s->s3->wbuf.len = len_with_overhead;
-+ }
-+
- /* If we have an alert to send, lets send it */
- if (s->s3->alert_dispatch)
- {
---- openssl-1.0.0a.orig/ssl/s23_srvr.c 2010-02-16 14:20:40.000000000 +0000
-+++ openssl-1.0.0a/ssl/s23_srvr.c 2010-08-25 21:12:39.000000000 +0000
-@@ -403,8 +403,13 @@ int ssl23_get_client_hello(SSL *s)
- v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
- v[1] = p[4];
-
-+/* The SSL2 protocol allows n to be larger, just pick
-+ * a reasonable buffer size. */
-+#if SSL3_RT_DEFAULT_PACKET_SIZE < 1024*4 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
-+#error "SSL3_RT_DEFAULT_PACKET_SIZE is too small."
-+#endif
- n=((p[0]&0x7f)<<8)|p[1];
-- if (n > (1024*4))
-+ if (n > SSL3_RT_DEFAULT_PACKET_SIZE - 2)
- {
- SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
- goto err;
---- openssl-1.0.0a.orig/ssl/s3_both.c 2010-03-24 23:16:49.000000000 +0000
-+++ openssl-1.0.0a/ssl/s3_both.c 2010-08-25 21:12:39.000000000 +0000
-@@ -715,13 +722,20 @@ int ssl3_setup_read_buffer(SSL *s)
-
- if (s->s3->rbuf.buf == NULL)
- {
-- len = SSL3_RT_MAX_PLAIN_LENGTH
-- + SSL3_RT_MAX_ENCRYPTED_OVERHEAD
-- + headerlen + align;
-- if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
-+ if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
- {
-- s->s3->init_extra = 1;
-- len += SSL3_RT_MAX_EXTRA;
-+ len = SSL3_RT_DEFAULT_PACKET_SIZE;
-+ }
-+ else
-+ {
-+ len = SSL3_RT_MAX_PLAIN_LENGTH
-+ + SSL3_RT_MAX_ENCRYPTED_OVERHEAD
-+ + headerlen + align;
-+ if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
-+ {
-+ s->s3->init_extra = 1;
-+ len += SSL3_RT_MAX_EXTRA;
-+ }
- }
- #ifndef OPENSSL_NO_COMP
- if (!(s->options & SSL_OP_NO_COMPRESSION))
-@@ -757,7 +771,15 @@ int ssl3_setup_write_buffer(SSL *s)
-
- if (s->s3->wbuf.buf == NULL)
- {
-- len = s->max_send_fragment
-+ if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
-+ {
-+ len = SSL3_RT_DEFAULT_PACKET_SIZE;
-+ }
-+ else
-+ {
-+ len = s->max_send_fragment;
-+ }
-+ len += 0
- + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
- + headerlen + align;
- #ifndef OPENSSL_NO_COMP
-@@ -767,7 +789,6 @@ int ssl3_setup_write_buffer(SSL *s)
- if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
- len += headerlen + align
- + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
--
- if ((p=freelist_extract(s->ctx, 0, len)) == NULL)
- goto err;
- s->s3->wbuf.buf = p;
-@@ -810,4 +831,3 @@ int ssl3_release_read_buffer(SSL *s)
- }
- return 1;
- }
--
---- openssl-1.0.0a.orig/ssl/s3_pkt.c 2010-03-25 11:22:42.000000000 +0000
-+++ openssl-1.0.0a/ssl/s3_pkt.c 2010-08-25 21:12:39.000000000 +0000
-@@ -293,6 +293,11 @@ static int ssl3_get_record(SSL *s)
- size_t extra;
- int decryption_failed_or_bad_record_mac = 0;
- unsigned char *mac = NULL;
-+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
-+ long align=SSL3_ALIGN_PAYLOAD;
-+#else
-+ long align=0;
-+#endif
-
- rr= &(s->s3->rrec);
- sess=s->session;
-@@ -301,7 +306,8 @@ static int ssl3_get_record(SSL *s)
- extra=SSL3_RT_MAX_EXTRA;
- else
- extra=0;
-- if (extra && !s->s3->init_extra)
-+ if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) &&
-+ extra && !s->s3->init_extra)
- {
- /* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
- * set after ssl3_setup_buffers() was done */
-@@ -350,6 +356,21 @@ fprintf(stderr, "Record type=%d, Length=
- goto err;
- }
-
-+ /* If we receive a valid record larger than the current buffer size,
-+ * allocate some memory for it.
-+ */
-+ if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH - align)
-+ {
-+ if ((p=OPENSSL_realloc(s->s3->rbuf.buf, rr->length + SSL3_RT_HEADER_LENGTH + align))==NULL)
-+ {
-+ SSLerr(SSL_F_SSL3_GET_RECORD,ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ s->s3->rbuf.buf=p;
-+ s->s3->rbuf.len=rr->length + SSL3_RT_HEADER_LENGTH + align;
-+ s->packet= &(s->s3->rbuf.buf[0]);
-+ }
-+
- if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
- {
- al=SSL_AD_RECORD_OVERFLOW;
-@@ -576,6 +597,7 @@ int ssl3_write_bytes(SSL *s, int type, c
- const unsigned char *buf=buf_;
- unsigned int tot,n,nw;
- int i;
-+ unsigned int max_plain_length;
-
- s->rwstate=SSL_NOTHING;
- tot=s->s3->wnum;
-@@ -595,8 +617,13 @@ int ssl3_write_bytes(SSL *s, int type, c
- n=(len-tot);
- for (;;)
- {
-- if (n > s->max_send_fragment)
-- nw=s->max_send_fragment;
-+ if (type == SSL3_RT_APPLICATION_DATA && (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS))
-+ max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH;
-+ else
-+ max_plain_length = s->max_send_fragment;
-+
-+ if (n > max_plain_length)
-+ nw = max_plain_length;
- else
- nw=n;
-
-@@ -727,6 +727,18 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
- s->s3->empty_fragment_done = 1;
- }
-
-+ /* resize if necessary to hold the data. */
-+ if (len + SSL3_RT_DEFAULT_WRITE_OVERHEAD > wb->len)
-+ {
-+ if ((p=OPENSSL_realloc(wb->buf, len + SSL3_RT_DEFAULT_WRITE_OVERHEAD))==NULL)
-+ {
-+ SSLerr(SSL_F_DO_SSL3_WRITE,ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ wb->buf = p;
-+ wb->len = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
-+ }
-+
- if (create_empty_fragment)
- {
- #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
---- openssl-1.0.0a.orig/ssl/ssl.h 2010-01-06 17:37:38.000000000 +0000
-+++ openssl-1.0.0a/ssl/ssl.h 2010-08-25 21:12:39.000000000 +0000
-@@ -602,6 +602,9 @@ typedef struct ssl_session_st
- * TLS only.) "Released" buffers are put onto a free-list in the context
- * or just freed (depending on the context's setting for freelist_max_len). */
- #define SSL_MODE_RELEASE_BUFFERS 0x00000010L
-+/* Use small read and write buffers: (a) lazy allocate read buffers for
-+ * large incoming records, and (b) limit the size of outgoing records. */
-+#define SSL_MODE_SMALL_BUFFERS 0x00000020L
-
- /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
- * they cannot be used to clear bits. */
---- openssl-1.0.0a.orig/ssl/ssl3.h 2010-01-06 17:37:38.000000000 +0000
-+++ openssl-1.0.0a/ssl/ssl3.h 2010-08-25 21:12:39.000000000 +0000
-@@ -280,6 +280,9 @@ extern "C" {
-
- #define SSL3_RT_MAX_EXTRA (16384)
-
-+/* Default buffer length used for writen records. Thus a generated record
-+ * will contain plaintext no larger than this value. */
-+#define SSL3_RT_DEFAULT_PLAIN_LENGTH 2048
- /* Maximum plaintext length: defined by SSL/TLS standards */
- #define SSL3_RT_MAX_PLAIN_LENGTH 16384
- /* Maximum compression overhead: defined by SSL/TLS standards */
-@@ -311,6 +314,13 @@ extern "C" {
- #define SSL3_RT_MAX_PACKET_SIZE \
- (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
-
-+/* Extra space for empty fragment, headers, MAC, and padding. */
-+#define SSL3_RT_DEFAULT_WRITE_OVERHEAD 256
-+#define SSL3_RT_DEFAULT_PACKET_SIZE 4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
-+#if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE
-+#error "Insufficient space allocated for write buffers."
-+#endif
-+
- #define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54"
- #define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52"
-
-@@ -634,4 +645,3 @@ typedef struct ssl3_state_st
- }
- #endif
- #endif
--
---- openssl-1.0.0a.orig/ssl/ssltest.c 2010-01-24 16:57:38.000000000 +0000
-+++ openssl-1.0.0a/ssl/ssltest.c 2010-08-25 21:12:39.000000000 +0000
-@@ -316,6 +316,8 @@ static void sv_usage(void)
- " (default is sect163r2).\n");
- #endif
- fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
-+ fprintf(stderr," -c_small_records - enable client side use of small SSL record buffers\n");
-+ fprintf(stderr," -s_small_records - enable server side use of small SSL record buffers\n");
- }
-
- static void print_details(SSL *c_ssl, const char *prefix)
-@@ -444,6 +447,9 @@ int opaque_prf_input_cb(SSL *ssl, void *
- return arg->ret;
- }
- #endif
-+ int ssl_mode = 0;
-+ int c_small_records=0;
-+ int s_small_records=0;
-
- int main(int argc, char *argv[])
- {
-@@ -680,6 +687,14 @@ int main(int argc, char *argv[])
- {
- test_cipherlist = 1;
- }
-+ else if (strcmp(*argv, "-c_small_records") == 0)
-+ {
-+ c_small_records = 1;
-+ }
-+ else if (strcmp(*argv, "-s_small_records") == 0)
-+ {
-+ s_small_records = 1;
-+ }
- else
- {
- fprintf(stderr,"unknown option %s\n",*argv);
-@@ -802,6 +821,21 @@ bad:
- SSL_CTX_set_cipher_list(s_ctx,cipher);
- }
-
-+ ssl_mode = 0;
-+ if (c_small_records)
-+ {
-+ ssl_mode = SSL_CTX_get_mode(c_ctx);
-+ ssl_mode |= SSL_MODE_SMALL_BUFFERS;
-+ SSL_CTX_set_mode(c_ctx, ssl_mode);
-+ }
-+ ssl_mode = 0;
-+ if (s_small_records)
-+ {
-+ ssl_mode = SSL_CTX_get_mode(s_ctx);
-+ ssl_mode |= SSL_MODE_SMALL_BUFFERS;
-+ SSL_CTX_set_mode(s_ctx, ssl_mode);
-+ }
-+
- #ifndef OPENSSL_NO_DH
- if (!no_dhe)
- {
---- openssl-1.0.0.orig/test/testssl 2006-03-10 15:06:27.000000000 -0800
-+++ openssl-1.0.0/test/testssl 2010-04-26 10:24:55.000000000 -0700
-@@ -70,6 +70,16 @@ $ssltest -client_auth $CA $extra || exit
- echo test sslv2/sslv3 with both client and server authentication
- $ssltest -server_auth -client_auth $CA $extra || exit 1
-
-+echo test sslv2/sslv3 with both client and server authentication and small client buffers
-+$ssltest -server_auth -client_auth -c_small_records $CA $extra || exit 1
-+
-+echo test sslv2/sslv3 with both client and server authentication and small server buffers
-+$ssltest -server_auth -client_auth -s_small_records $CA $extra || exit 1
-+
-+echo test sslv2/sslv3 with both client and server authentication and small client and server buffers
-+$ssltest -server_auth -client_auth -c_small_records -s_small_records $CA $extra || exit 1
-+
-+
- echo test sslv2 via BIO pair
- $ssltest -bio_pair -ssl2 $extra || exit 1
-
diff --git a/deps/openssl/patches/tls_exporter.patch b/deps/openssl/patches/tls_exporter.patch
deleted file mode 100755
index a9e64a3c7..000000000
--- a/deps/openssl/patches/tls_exporter.patch
+++ /dev/null
@@ -1,220 +0,0 @@
-diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
-index c3b77c8..a94290a 100644
---- a/ssl/d1_lib.c
-+++ b/ssl/d1_lib.c
-@@ -82,6 +82,7 @@ SSL3_ENC_METHOD DTLSv1_enc_data={
- TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
- TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
- tls1_alert_code,
-+ tls1_export_keying_material,
- };
-
- long dtls1_default_timeout(void)
-diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
-index c19538a..1fecbbc 100644
---- a/ssl/s3_lib.c
-+++ b/ssl/s3_lib.c
-@@ -2087,6 +2087,9 @@ SSL3_ENC_METHOD SSLv3_enc_data={
- SSL3_MD_CLIENT_FINISHED_CONST,4,
- SSL3_MD_SERVER_FINISHED_CONST,4,
- ssl3_alert_code,
-+ (int (*)(SSL *, unsigned char *, size_t, const char *,
-+ size_t, const unsigned char *, size_t,
-+ int use_context)) ssl_undefined_function,
- };
-
- long ssl3_default_timeout(void)
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index 9336af8..be4af2f 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -2116,6 +2116,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301
- #define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303
- #define SSL_F_SSL_PEEK 270
-+#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 312
- #define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281
- #define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282
- #define SSL_F_SSL_READ 223
-@@ -2394,6 +2395,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112
- #define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
- #define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232
-+#define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367
- #define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157
- #define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
- #define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234
-diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
-index 17d2cde..d6ad3c1 100644
---- a/ssl/ssl_lib.c
-+++ b/ssl/ssl_lib.c
-@@ -3127,6 +3127,18 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned
- }
- #endif
-
-+int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
-+ const char *label, size_t llen, const unsigned char *p, size_t plen,
-+ int use_context)
-+ {
-+ if (s->version < TLS1_VERSION)
-+ return -1;
-+
-+ return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
-+ llen, p, plen,
-+ use_context);
-+ }
-+
- int SSL_cutthrough_complete(const SSL *s)
- {
- return (!s->server && /* cutthrough only applies to clients */
-diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
-index 146c89c..e7c6b9a 100644
---- a/ssl/ssl_locl.h
-+++ b/ssl/ssl_locl.h
-@@ -557,6 +557,10 @@ typedef struct ssl3_enc_method
- const char *server_finished_label;
- int server_finished_label_len;
- int (*alert_value)(int);
-+ int (*export_keying_material)(SSL *, unsigned char *, size_t,
-+ const char *, size_t,
-+ const unsigned char *, size_t,
-+ int use_context);
- } SSL3_ENC_METHOD;
-
- #ifndef OPENSSL_NO_COMP
-@@ -1041,6 +1045,9 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
- int tls1_mac(SSL *ssl, unsigned char *md, int snd);
- int tls1_generate_master_secret(SSL *s, unsigned char *out,
- unsigned char *p, int len);
-+int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
-+ const char *label, size_t llen, const unsigned char *p,
-+ size_t plen, int use_context);
- int tls1_alert_code(int code);
- int ssl3_alert_code(int code);
- int ssl_ok(SSL *s);
-diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
-index 793ea43..b1d5b28 100644
---- a/ssl/t1_enc.c
-+++ b/ssl/t1_enc.c
-@@ -1001,6 +1001,95 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
- return(SSL3_MASTER_SECRET_SIZE);
- }
-
-+int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
-+ const char *label, size_t llen, const unsigned char *context,
-+ size_t contextlen, int use_context)
-+ {
-+ unsigned char *buff;
-+ unsigned char *val = NULL;
-+ size_t vallen, currentvalpos;
-+ int rv;
-+
-+#ifdef KSSL_DEBUG
-+ printf ("tls1_export_keying_material(%p,%p,%d,%s,%d,%p,%d)\n", s, out, olen, label, llen, p, plen);
-+#endif /* KSSL_DEBUG */
-+
-+ buff = OPENSSL_malloc(olen);
-+ if (buff == NULL) goto err2;
-+
-+ /* construct PRF arguments
-+ * we construct the PRF argument ourself rather than passing separate
-+ * values into the TLS PRF to ensure that the concatenation of values
-+ * does not create a prohibited label.
-+ */
-+ vallen = llen + SSL3_RANDOM_SIZE * 2;
-+ if (use_context)
-+ {
-+ vallen += 2 + contextlen;
-+ }
-+
-+ val = OPENSSL_malloc(vallen);
-+ if (val == NULL) goto err2;
-+ currentvalpos = 0;
-+ memcpy(val + currentvalpos, (unsigned char *) label, llen);
-+ currentvalpos += llen;
-+ memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
-+ currentvalpos += SSL3_RANDOM_SIZE;
-+ memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
-+ currentvalpos += SSL3_RANDOM_SIZE;
-+
-+ if (use_context)
-+ {
-+ val[currentvalpos] = (contextlen >> 8) & 0xff;
-+ currentvalpos++;
-+ val[currentvalpos] = contextlen & 0xff;
-+ currentvalpos++;
-+ if ((contextlen > 0) || (context != NULL))
-+ {
-+ memcpy(val + currentvalpos, context, contextlen);
-+ }
-+ }
-+
-+ /* disallow prohibited labels
-+ * note that SSL3_RANDOM_SIZE > max(prohibited label len) =
-+ * 15, so size of val > max(prohibited label len) = 15 and the
-+ * comparisons won't have buffer overflow
-+ */
-+ if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
-+ TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) goto err1;
-+ if (memcmp(val, TLS_MD_SERVER_FINISH_CONST,
-+ TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) goto err1;
-+ if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
-+ TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) goto err1;
-+ if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
-+ TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
-+
-+ rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
-+ val, vallen,
-+ NULL, 0,
-+ NULL, 0,
-+ NULL, 0,
-+ NULL, 0,
-+ s->session->master_key,s->session->master_key_length,
-+ out,buff,olen);
-+
-+#ifdef KSSL_DEBUG
-+ printf ("tls1_export_keying_material() complete\n");
-+#endif /* KSSL_DEBUG */
-+ goto ret;
-+err1:
-+ SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
-+ rv = 0;
-+ goto ret;
-+err2:
-+ SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE);
-+ rv = 0;
-+ret:
-+ if (buff != NULL) OPENSSL_free(buff);
-+ if (val != NULL) OPENSSL_free(val);
-+ return(rv);
-+ }
-+
- int tls1_alert_code(int code)
- {
- switch (code)
-diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
-index daa65c9..c094471 100644
---- a/ssl/t1_lib.c
-+++ b/ssl/t1_lib.c
-@@ -209,6 +209,7 @@ SSL3_ENC_METHOD TLSv1_enc_data={
- TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
- TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
- tls1_alert_code,
-+ tls1_export_keying_material,
- };
-
- long tls1_default_timeout(void)
-diff --git a/ssl/tls1.h b/ssl/tls1.h
-index 1fa96e5..7bbb875 100644
---- a/ssl/tls1.h
-+++ b/ssl/tls1.h
-@@ -231,6 +231,9 @@ extern "C" {
-
- const char *SSL_get_servername(const SSL *s, const int type) ;
- int SSL_get_servername_type(const SSL *s) ;
-+int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
-+ const char *label, size_t llen, const unsigned char *p, size_t plen,
-+ int use_context);
-
- #define SSL_set_tlsext_host_name(s,name) \
- SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) \ No newline at end of file
diff --git a/deps/openssl/patches/x509_hash_name_algorithm_change.patch b/deps/openssl/patches/x509_hash_name_algorithm_change.patch
deleted file mode 100644
index d9601844d..000000000
--- a/deps/openssl/patches/x509_hash_name_algorithm_change.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- openssl-1.0.0f-origin/crypto/x509/by_dir.c 2012-01-19 02:20:24.821550944 +0800
-+++ openssl-1.0.0f/crypto/x509/by_dir.c 2012-01-19 23:36:53.597870429 +0800
-@@ -287,6 +287,8 @@
- int ok=0;
- int i,j,k;
- unsigned long h;
-+ unsigned long hash_array[2];
-+ int hash_index;
- BUF_MEM *b=NULL;
- X509_OBJECT stmp,*tmp;
- const char *postfix="";
-@@ -323,6 +325,11 @@
- ctx=(BY_DIR *)xl->method_data;
-
- h=X509_NAME_hash(name);
-+ hash_array[0]=h;
-+ hash_array[1]=X509_NAME_hash_old(name);
-+ for (hash_index=0; hash_index < 2; hash_index++)
-+ {
-+ h=hash_array[hash_index];
- for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
- {
- BY_DIR_ENTRY *ent;
-@@ -476,6 +483,7 @@
- goto finish;
- }
- }
-+ }
- finish:
- if (b != NULL) BUF_MEM_free(b);
- return(ok);
diff --git a/deps/uv/.gitignore b/deps/uv/.gitignore
index fa9636d11..d6c65dbae 100644
--- a/deps/uv/.gitignore
+++ b/deps/uv/.gitignore
@@ -1,23 +1,26 @@
*.swp
-*.o
-*.lo
-*.la
-*.a
+*.[oa]
+*.l[oa]
*.opensdf
*.orig
*.sdf
*.suo
core
vgcore.*
+.buildstamp
+
+/libuv.so
+/libuv.dylib
+
/out/
/build/gyp
-/test/run-tests
-/test/run-tests.exe
-/test/run-tests.dSYM
-/test/run-benchmarks
-/test/run-benchmarks.exe
-/test/run-benchmarks.dSYM
+/run-tests
+/run-tests.exe
+/run-tests.dSYM
+/run-benchmarks
+/run-benchmarks.exe
+/run-benchmarks.dSYM
*.sln
*.vcproj
@@ -29,5 +32,3 @@ UpgradeLog*.XML
Debug
Release
ipch
-*.mk
-*.Makefile
diff --git a/deps/uv/.travis.yml b/deps/uv/.travis.yml
deleted file mode 100644
index f3b176fec..000000000
--- a/deps/uv/.travis.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-language: node_js
-
-script:
- - "make test"
-
-notifications:
- email: false
- irc:
- - "irc.freenode.net#libuv"
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 37452ac89..d28143bbf 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -43,3 +43,19 @@ Paddy Byers <paddy.byers@gmail.com>
Dan VerWeire <dverweire@gmail.com>
Brandon Benvie <brandon@bbenvie.com>
Brandon Philips <brandon.philips@rackspace.com>
+Nathan Rajlich <nathan@tootallnate.net>
+Brandon Philips <brandon@ifup.org>
+Charlie McConnell <charlie@charlieistheman.com>
+Vladimir Dronnikov <dronnikov@gmail.com>
+Aaron Bieber <qbit@deftly.net>
+Bulat Shakirzyanov <mallluhuct@gmail.com>
+Brian White <mscdex@mscdex.net>
+Erik Dubbelboer <erik@dubbelboer.com>
+Keno Fischer <kenof@stanford.edu>
+Ira Cooper <Ira.Cooper@mathworks.com>
+Andrius Bentkus <andrius.bentkus@gmail.com>
+Brian White <mscdex@gmail.com>
+Iñaki Baz Castillo <ibc@aliax.net>
+Mark Cavage <mark.cavage@joyent.com>
+George Yohng <georgegh@oss3d.com>
+Xidorn Quan <quanxunzhen@gmail.com>
diff --git a/deps/uv/LICENSE b/deps/uv/LICENSE
index f62d7f199..51c382cfb 100644
--- a/deps/uv/LICENSE
+++ b/deps/uv/LICENSE
@@ -33,10 +33,9 @@ The externally maintained libraries used by libuv are:
- ngx_queue.h (from Nginx), copyright Igor Sysoev. Two clause BSD license.
- - c-ares, copyright Daniel Stenberg and others. MIT licensed.
+ - inet_pton and inet_ntop implementations, contained in src/inet.c, are
+ copyright the Internet Systems Consortium, Inc., and licensed under the ISC
+ license.
- - libev, located at ev/ is copyright Marc Alexander Lehmann, and
- dual-licensed under the MIT license and GPL2.
-
- - libeio, located at eio/ is copyright Marc Alexander Lehmann, and
- dual-licensed under the MIT license and GPL2.
+ - stdint-msvc2008.h (from msinttypes), copyright Alexander Chemeris. Three
+ clause BSD license.
diff --git a/deps/uv/Makefile b/deps/uv/Makefile
index cf1e7880b..069c67e54 100644
--- a/deps/uv/Makefile
+++ b/deps/uv/Makefile
@@ -18,102 +18,36 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
-uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
+SRCDIR ?= $(CURDIR)
-ifdef MSVC
-uname_S := MINGW
-endif
-
-CPPFLAGS += -Iinclude -Iinclude/uv-private
-
-CARES_OBJS =
-CARES_OBJS += src/ares/ares__close_sockets.o
-CARES_OBJS += src/ares/ares__get_hostent.o
-CARES_OBJS += src/ares/ares__read_line.o
-CARES_OBJS += src/ares/ares__timeval.o
-CARES_OBJS += src/ares/ares_cancel.o
-CARES_OBJS += src/ares/ares_data.o
-CARES_OBJS += src/ares/ares_destroy.o
-CARES_OBJS += src/ares/ares_expand_name.o
-CARES_OBJS += src/ares/ares_expand_string.o
-CARES_OBJS += src/ares/ares_fds.o
-CARES_OBJS += src/ares/ares_free_hostent.o
-CARES_OBJS += src/ares/ares_free_string.o
-CARES_OBJS += src/ares/ares_gethostbyaddr.o
-CARES_OBJS += src/ares/ares_gethostbyname.o
-CARES_OBJS += src/ares/ares_getnameinfo.o
-CARES_OBJS += src/ares/ares_getopt.o
-CARES_OBJS += src/ares/ares_getsock.o
-CARES_OBJS += src/ares/ares_init.o
-CARES_OBJS += src/ares/ares_library_init.o
-CARES_OBJS += src/ares/ares_llist.o
-CARES_OBJS += src/ares/ares_mkquery.o
-CARES_OBJS += src/ares/ares_nowarn.o
-CARES_OBJS += src/ares/ares_options.o
-CARES_OBJS += src/ares/ares_parse_a_reply.o
-CARES_OBJS += src/ares/ares_parse_aaaa_reply.o
-CARES_OBJS += src/ares/ares_parse_mx_reply.o
-CARES_OBJS += src/ares/ares_parse_ns_reply.o
-CARES_OBJS += src/ares/ares_parse_ptr_reply.o
-CARES_OBJS += src/ares/ares_parse_srv_reply.o
-CARES_OBJS += src/ares/ares_parse_txt_reply.o
-CARES_OBJS += src/ares/ares_process.o
-CARES_OBJS += src/ares/ares_query.o
-CARES_OBJS += src/ares/ares_search.o
-CARES_OBJS += src/ares/ares_send.o
-CARES_OBJS += src/ares/ares_strcasecmp.o
-CARES_OBJS += src/ares/ares_strdup.o
-CARES_OBJS += src/ares/ares_strerror.o
-CARES_OBJS += src/ares/ares_timeout.o
-CARES_OBJS += src/ares/ares_version.o
-CARES_OBJS += src/ares/ares_writev.o
-CARES_OBJS += src/ares/bitncmp.o
-CARES_OBJS += src/ares/inet_net_pton.o
-CARES_OBJS += src/ares/inet_ntop.o
-
-ifneq (,$(findstring MINGW,$(uname_S)))
-include config-mingw.mk
-else
-include config-unix.mk
-endif
-
-TESTS=test/blackhole-server.c test/echo-server.c test/test-*.c
-BENCHMARKS=test/blackhole-server.c test/echo-server.c test/dns-server.c test/benchmark-*.c
+ifeq (,$(builddir_name))
-all: uv.a
+VPATH := $(SRCDIR)
+include $(SRCDIR)/build.mk
-$(CARES_OBJS): %.o: %.c
- $(CC) -o $*.o -c $(CFLAGS) $(CPPFLAGS) $< -DHAVE_CONFIG_H
+else # Out of tree build.
-test/run-tests$(E): test/*.h test/run-tests.c $(RUNNER_SRC) test/runner-unix.c $(TESTS) uv.a
- $(CC) $(CPPFLAGS) $(RUNNER_CFLAGS) -o test/run-tests test/run-tests.c \
- test/runner.c $(RUNNER_SRC) $(TESTS) uv.a $(RUNNER_LIBS) $(RUNNER_LINKFLAGS)
+# Drop all built-in rules.
+.SUFFIXES:
-test/run-benchmarks$(E): test/*.h test/run-benchmarks.c test/runner.c $(RUNNER_SRC) $(BENCHMARKS) uv.a
- $(CC) $(CPPFLAGS) $(RUNNER_CFLAGS) -o test/run-benchmarks test/run-benchmarks.c \
- test/runner.c $(RUNNER_SRC) $(BENCHMARKS) uv.a $(RUNNER_LIBS) $(RUNNER_LINKFLAGS)
+.PHONY: $(builddir_name)
+$(builddir_name): $(builddir_name)/.buildstamp
+ $(MAKE) -C $@ -f $(CURDIR)/Makefile $(MAKECMDGOALS) \
+ SRCDIR=$(CURDIR) builddir_name=
-test/echo.o: test/echo.c test/echo.h
- $(CC) $(CPPFLAGS) $(CFLAGS) -c test/echo.c -o test/echo.o
+$(builddir_name)/.buildstamp:
+ mkdir -p $(dir $@)
+ touch $@
+# Add no-op rules for Makefiles to stop make from trying to rebuild them.
+Makefile:: ;
+%.mk:: ;
-.PHONY: clean clean-platform distclean distclean-platform test bench
+# Turn everything else into a no-op rule that depends on the build directory.
+%:: $(builddir_name) ;
+.PHONY: clean
+clean:
+ $(RM) -fr $(builddir_name)
-test: test/run-tests$(E)
- test/run-tests
-
-#test-%: test/run-tests$(E)
-# test/run-tests $(@:test-%=%)
-
-bench: test/run-benchmarks$(E)
- test/run-benchmarks
-
-#bench-%: test/run-benchmarks$(E)
-# test/run-benchmarks $(@:bench-%=%)
-
-clean: clean-platform
- $(RM) -f src/*.o *.a test/run-tests$(E) test/run-benchmarks$(E)
-
-distclean: distclean-platform
- $(RM) -f src/*.o *.a test/run-tests$(E) test/run-benchmarks$(E)
+endif
diff --git a/deps/uv/README.md b/deps/uv/README.md
index f86a0000e..cdddbd2a4 100644
--- a/deps/uv/README.md
+++ b/deps/uv/README.md
@@ -1,8 +1,8 @@
-# libuv [![Build Status](https://secure.travis-ci.org/joyent/libuv.png)](http://travis-ci.org/joyent/libuv)
+# libuv
libuv is a new platform layer for Node. Its purpose is to abstract IOCP on
-Windows and libev on Unix systems. We intend to eventually contain all
-platform differences in this library.
+Windows and epoll/kqueue/event ports/etc. on Unix systems. We intend to
+eventually contain all platform differences in this library.
http://nodejs.org/
@@ -18,7 +18,7 @@ http://nodejs.org/
* Child process spawning
- * Asynchronous DNS via c-ares or `uv_getaddrinfo`.
+ * Asynchronous DNS via `uv_getaddrinfo`.
* Asynchronous file system APIs `uv_fs_*`
@@ -36,45 +36,75 @@ http://nodejs.org/
* IPC and socket sharing between processes `uv_write2`
+## Community
-## Documentation
+ * [Mailing list](http://groups.google.com/group/libuv)
-See `include/uv.h`.
+## Documentation
+ * [include/uv.h](https://github.com/joyent/libuv/blob/master/include/uv.h)
+ &mdash; API documentation in the form of detailed header comments.
+ * [An Introduction to libuv](http://nikhilm.github.com/uvbook/) &mdash; An
+ overview of libuv with tutorials.
+ * [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4) - High-level
+ introductory talk about libuv.
+ * [Tests and benchmarks](https://github.com/joyent/libuv/tree/master/test) -
+ API specification and usage examples.
## Build Instructions
For GCC (including MinGW) there are two methods building: via normal
makefiles or via GYP. GYP is a meta-build system which can generate MSVS,
Makefile, and XCode backends. It is best used for integration into other
-projects. The old (more stable) system is using Makefiles.
+projects. The old system is using plain GNU Makefiles.
To build via Makefile simply execute:
make
-To build with Visual Studio run the vcbuilds.bat file which will
+MinGW users should run this instead:
+
+ make OS=mingw
+
+Out-of-tree builds are supported:
+
+ make builddir_name=/path/to/builddir
+
+To build with Visual Studio run the vcbuild.bat file which will
checkout the GYP code into build/gyp and generate the uv.sln and
related files.
Windows users can also build from cmd-line using msbuild. This is
done by running vcbuild.bat from Visual Studio command prompt.
-To have GYP generate build script for another system you will need to
-checkout GYP into the project tree manually:
+To have GYP generate build script for another system, make sure that
+you have Python 2.6 or 2.7 installed, then checkout GYP into the
+project tree manually:
+ mkdir -p build
svn co http://gyp.googlecode.com/svn/trunk build/gyp
+Or:
+
+ mkdir -p build
+ git clone https://git.chromium.org/external/gyp.git build/gyp
+
Unix users run
./gyp_uv -f make
- make
+ make -C out
Macintosh users run
./gyp_uv -f xcode
xcodebuild -project uv.xcodeproj -configuration Release -target All
+Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and
+`-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically.
+
+Note for Linux users: compile your project with `-D_GNU_SOURCE` when you
+include `uv.h`. GYP builds take care of that automatically. If you use
+autotools, add a `AC_GNU_SOURCE` declaration to your `configure.ac`.
## Supported Platforms
diff --git a/deps/uv/build.mk b/deps/uv/build.mk
new file mode 100644
index 000000000..a19db4948
--- /dev/null
+++ b/deps/uv/build.mk
@@ -0,0 +1,164 @@
+# 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.
+
+OS ?= $(shell sh -c 'uname -s | tr "[A-Z]" "[a-z]"')
+
+CPPFLAGS += -I$(SRCDIR)/include -I$(SRCDIR)/include/uv-private
+
+ifeq (darwin,$(OS))
+SOEXT = dylib
+else
+SOEXT = so
+endif
+
+ifneq (,$(findstring mingw,$(OS)))
+include $(SRCDIR)/config-mingw.mk
+else
+include $(SRCDIR)/config-unix.mk
+endif
+
+BENCHMARKS= \
+ test/benchmark-async-pummel.o \
+ test/benchmark-async.o \
+ test/benchmark-fs-stat.o \
+ test/benchmark-getaddrinfo.o \
+ test/benchmark-loop-count.o \
+ test/benchmark-million-async.o \
+ test/benchmark-million-timers.o \
+ test/benchmark-multi-accept.o \
+ test/benchmark-ping-pongs.o \
+ test/benchmark-pound.o \
+ test/benchmark-pump.o \
+ test/benchmark-sizes.o \
+ test/benchmark-spawn.o \
+ test/benchmark-tcp-write-batch.o \
+ test/benchmark-thread.o \
+ test/benchmark-udp-pummel.o \
+ test/blackhole-server.o \
+ test/dns-server.o \
+ test/echo-server.o \
+
+TESTS= \
+ test/blackhole-server.o \
+ test/dns-server.o \
+ test/echo-server.o \
+ test/test-active.o \
+ test/test-async.o \
+ test/test-barrier.o \
+ test/test-callback-order.o \
+ test/test-callback-stack.o \
+ test/test-condvar.o \
+ test/test-connection-fail.o \
+ test/test-cwd-and-chdir.o \
+ test/test-delayed-accept.o \
+ test/test-dlerror.o \
+ test/test-embed.o \
+ test/test-error.o \
+ test/test-fail-always.o \
+ test/test-fs.o \
+ test/test-fs-event.o \
+ test/test-fs-poll.o \
+ test/test-getaddrinfo.o \
+ test/test-get-currentexe.o \
+ test/test-get-loadavg.o \
+ test/test-get-memory.o \
+ test/test-getsockname.o \
+ test/test-hrtime.o \
+ test/test-idle.o \
+ test/test-ipc.o \
+ test/test-ipc-send-recv.o \
+ test/test-loop-handles.o \
+ test/test-loop-stop.o \
+ test/test-multiple-listen.o \
+ test/test-mutexes.o \
+ test/test-pass-always.o \
+ test/test-ping-pong.o \
+ test/test-pipe-bind-error.o \
+ test/test-pipe-connect-error.o \
+ test/test-platform-output.o \
+ test/test-poll.o \
+ test/test-poll-close.o \
+ test/test-process-title.o \
+ test/test-ref.o \
+ test/test-run-nowait.o \
+ test/test-run-once.o \
+ test/test-semaphore.o \
+ test/test-shutdown-close.o \
+ test/test-shutdown-eof.o \
+ test/test-signal.o \
+ test/test-signal-multiple-loops.o \
+ test/test-spawn.o \
+ test/test-stdio-over-pipes.o \
+ test/test-tcp-bind6-error.o \
+ test/test-tcp-bind-error.o \
+ test/test-tcp-close.o \
+ test/test-tcp-close-while-connecting.o \
+ test/test-tcp-connect6-error.o \
+ test/test-tcp-connect-error-after-write.o \
+ test/test-tcp-connect-error.o \
+ test/test-tcp-connect-timeout.o \
+ test/test-tcp-flags.o \
+ test/test-tcp-open.o \
+ test/test-tcp-read-stop.o \
+ test/test-tcp-shutdown-after-write.o \
+ test/test-tcp-unexpected-read.o \
+ test/test-tcp-writealot.o \
+ test/test-tcp-write-to-half-open-connection.o \
+ test/test-thread.o \
+ test/test-threadpool.o \
+ test/test-threadpool-cancel.o \
+ test/test-timer-again.o \
+ test/test-timer.o \
+ test/test-tty.o \
+ test/test-udp-dgram-too-big.o \
+ test/test-udp-ipv6.o \
+ test/test-udp-multicast-join.o \
+ test/test-udp-multicast-ttl.o \
+ test/test-udp-open.o \
+ test/test-udp-options.o \
+ test/test-udp-send-and-recv.o \
+ test/test-util.o \
+ test/test-walk-handles.o \
+
+all: libuv.a
+
+run-tests$(E): test/run-tests.o test/runner.o $(RUNNER_SRC) $(TESTS) libuv.$(SOEXT)
+ $(CC) $(CPPFLAGS) $(RUNNER_CFLAGS) -o $@ $^ $(RUNNER_LIBS) $(RUNNER_LDFLAGS)
+
+run-benchmarks$(E): test/run-benchmarks.o test/runner.o $(RUNNER_SRC) $(BENCHMARKS) libuv.$(SOEXT)
+ $(CC) $(CPPFLAGS) $(RUNNER_CFLAGS) -o $@ $^ $(RUNNER_LIBS) $(RUNNER_LDFLAGS)
+
+test/echo.o: test/echo.c test/echo.h
+
+
+.PHONY: clean clean-platform distclean distclean-platform test bench
+
+
+test: run-tests$(E)
+ $(CURDIR)/$<
+
+bench: run-benchmarks$(E)
+ $(CURDIR)/$<
+
+clean: clean-platform
+ $(RM) -f *.a *.so test/run-tests$(E) test/run-benchmarks$(E)
+
+distclean: distclean-platform
+ $(RM) -f *.a *.so test/run-tests$(E) test/run-benchmarks$(E)
diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh
new file mode 100755
index 000000000..f06b27d28
--- /dev/null
+++ b/deps/uv/checksparse.sh
@@ -0,0 +1,230 @@
+#!/bin/sh
+
+# Copyright (c) 2013, 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.
+
+SPARSE=${SPARSE:-sparse}
+
+SPARSE_FLAGS=${SPARSE_FLAGS:-"
+-D__POSIX__
+-Wsparse-all
+-Wno-do-while
+-Wno-transparent-union
+-Iinclude
+-Iinclude/uv-private
+-Isrc
+"}
+
+SOURCES="
+include/uv-private/ngx-queue.h
+include/uv-private/tree.h
+include/uv-private/uv-unix.h
+include/uv.h
+src/fs-poll.c
+src/inet.c
+src/unix/async.c
+src/unix/core.c
+src/unix/dl.c
+src/unix/error.c
+src/unix/fs.c
+src/unix/getaddrinfo.c
+src/unix/internal.h
+src/unix/loop-watcher.c
+src/unix/loop.c
+src/unix/pipe.c
+src/unix/poll.c
+src/unix/process.c
+src/unix/signal.c
+src/unix/stream.c
+src/unix/tcp.c
+src/unix/thread.c
+src/unix/threadpool.c
+src/unix/timer.c
+src/unix/tty.c
+src/unix/udp.c
+src/uv-common.c
+src/uv-common.h
+"
+
+TESTS="
+test/benchmark-async-pummel.c
+test/benchmark-async.c
+test/benchmark-fs-stat.c
+test/benchmark-getaddrinfo.c
+test/benchmark-loop-count.c
+test/benchmark-million-async.c
+test/benchmark-million-timers.c
+test/benchmark-multi-accept.c
+test/benchmark-ping-pongs.c
+test/benchmark-pound.c
+test/benchmark-pump.c
+test/benchmark-sizes.c
+test/benchmark-spawn.c
+test/benchmark-tcp-write-batch.c
+test/benchmark-thread.c
+test/benchmark-udp-pummel.c
+test/blackhole-server.c
+test/dns-server.c
+test/echo-server.c
+test/run-benchmarks.c
+test/run-tests.c
+test/runner-unix.c
+test/runner-unix.h
+test/runner.c
+test/runner.h
+test/task.h
+test/test-active.c
+test/test-async.c
+test/test-barrier.c
+test/test-callback-order.c
+test/test-callback-stack.c
+test/test-condvar.c
+test/test-connection-fail.c
+test/test-cwd-and-chdir.c
+test/test-delayed-accept.c
+test/test-dlerror.c
+test/test-embed.c
+test/test-error.c
+test/test-fail-always.c
+test/test-fs-event.c
+test/test-fs-poll.c
+test/test-fs.c
+test/test-get-currentexe.c
+test/test-get-loadavg.c
+test/test-get-memory.c
+test/test-getaddrinfo.c
+test/test-getsockname.c
+test/test-hrtime.c
+test/test-idle.c
+test/test-ipc-send-recv.c
+test/test-ipc.c
+test/test-loop-handles.c
+test/test-multiple-listen.c
+test/test-mutexes.c
+test/test-pass-always.c
+test/test-ping-pong.c
+test/test-pipe-bind-error.c
+test/test-pipe-connect-error.c
+test/test-platform-output.c
+test/test-poll-close.c
+test/test-poll.c
+test/test-process-title.c
+test/test-ref.c
+test/test-run-nowait.c
+test/test-run-once.c
+test/test-semaphore.c
+test/test-shutdown-close.c
+test/test-shutdown-eof.c
+test/test-signal-multiple-loops.c
+test/test-signal.c
+test/test-spawn.c
+test/test-stdio-over-pipes.c
+test/test-tcp-bind-error.c
+test/test-tcp-bind6-error.c
+test/test-tcp-close-while-connecting.c
+test/test-tcp-close.c
+test/test-tcp-connect-error-after-write.c
+test/test-tcp-connect-error.c
+test/test-tcp-connect-timeout.c
+test/test-tcp-connect6-error.c
+test/test-tcp-flags.c
+test/test-tcp-open.c
+test/test-tcp-read-stop.c
+test/test-tcp-shutdown-after-write.c
+test/test-tcp-unexpected-read.c
+test/test-tcp-write-error.c
+test/test-tcp-write-to-half-open-connection.c
+test/test-tcp-writealot.c
+test/test-thread.c
+test/test-threadpool-cancel.c
+test/test-threadpool.c
+test/test-timer-again.c
+test/test-timer.c
+test/test-tty.c
+test/test-udp-dgram-too-big.c
+test/test-udp-ipv6.c
+test/test-udp-multicast-join.c
+test/test-udp-multicast-ttl.c
+test/test-udp-open.c
+test/test-udp-options.c
+test/test-udp-send-and-recv.c
+test/test-util.c
+test/test-walk-handles.c
+"
+
+case `uname -s` in
+AIX)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D_AIX=1"
+ SOURCES="$SOURCES
+ src/unix/aix.c"
+ ;;
+Darwin)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__APPLE__=1"
+ SOURCES="$SOURCES
+ include/uv-private/uv-bsd.h
+ src/unix/darwin.c
+ src/unix/kqueue.c
+ src/unix/fsevents.c"
+ ;;
+DragonFly)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__DragonFly__=1"
+ SOURCES="$SOURCES
+ include/uv-private/uv-bsd.h
+ src/unix/kqueue.c
+ src/unix/freebsd.c"
+ ;;
+FreeBSD)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__FreeBSD__=1"
+ SOURCES="$SOURCES
+ include/uv-private/uv-bsd.h
+ src/unix/kqueue.c
+ src/unix/freebsd.c"
+ ;;
+Linux)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__linux__=1"
+ SOURCES="$SOURCES
+ include/uv-private/uv-linux.h
+ src/unix/linux-inotify.c
+ src/unix/linux-core.c
+ src/unix/linux-syscalls.c
+ src/unix/linux-syscalls.h"
+ ;;
+NetBSD)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__NetBSD__=1"
+ SOURCES="$SOURCES
+ include/uv-private/uv-bsd.h
+ src/unix/kqueue.c
+ src/unix/netbsd.c"
+ ;;
+OpenBSD)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__OpenBSD__=1"
+ SOURCES="$SOURCES
+ include/uv-private/uv-bsd.h
+ src/unix/kqueue.c
+ src/unix/openbsd.c"
+ ;;
+SunOS)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__sun=1"
+ SOURCES="$SOURCES
+ include/uv-private/uv-sunos.h
+ src/unix/sunos.c"
+ ;;
+esac
+
+for ARCH in __i386__ __x86_64__ __arm__; do
+ $SPARSE $SPARSE_FLAGS -D$ARCH=1 $SOURCES
+done
+
+# Tests are architecture independent.
+$SPARSE $SPARSE_FLAGS -Itest $TESTS
diff --git a/deps/uv/common.gypi b/deps/uv/common.gypi
index 0ffb45e8d..8c6c88758 100644
--- a/deps/uv/common.gypi
+++ b/deps/uv/common.gypi
@@ -15,7 +15,7 @@
'configurations': {
'Debug': {
'defines': [ 'DEBUG', '_DEBUG' ],
- 'cflags': [ '-g', '-O0' ],
+ 'cflags': [ '-g', '-O0', '-fwrapv' ],
'msvs_settings': {
'VCCLCompilerTool': {
'target_conditions': [
@@ -45,7 +45,13 @@
},
'Release': {
'defines': [ 'NDEBUG' ],
- 'cflags': [ '-O3', '-fomit-frame-pointer', '-fdata-sections', '-ffunction-sections' ],
+ 'cflags': [
+ '-O3',
+ '-fstrict-aliasing',
+ '-fomit-frame-pointer',
+ '-fdata-sections',
+ '-ffunction-sections',
+ ],
'msvs_settings': {
'VCCLCompilerTool': {
'target_conditions': [
@@ -117,6 +123,11 @@
# POSIX names
'_CRT_NONSTDC_NO_DEPRECATE',
],
+ 'target_conditions': [
+ ['target_arch=="x64"', {
+ 'msvs_configuration_platform': 'x64'
+ }]
+ ]
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
'cflags': [ '-Wall' ],
@@ -158,7 +169,7 @@
'PREBINDING': 'NO', # No -Wl,-prebind
'USE_HEADERMAP': 'NO',
'OTHER_CFLAGS': [
- '-fno-strict-aliasing',
+ '-fstrict-aliasing',
],
'WARNING_CFLAGS': [
'-Wall',
@@ -167,6 +178,14 @@
'-Wno-unused-parameter',
],
},
+ 'conditions': [
+ ['target_arch=="ia32"', {
+ 'xcode_settings': {'ARCHS': ['i386']},
+ }],
+ ['target_arch=="x64"', {
+ 'xcode_settings': {'ARCHS': ['x86_64']},
+ }],
+ ],
'target_conditions': [
['_type!="static_library"', {
'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
diff --git a/deps/uv/config-mingw.mk b/deps/uv/config-mingw.mk
index 9e49ec71b..9906a1c62 100644
--- a/deps/uv/config-mingw.mk
+++ b/deps/uv/config-mingw.mk
@@ -24,21 +24,19 @@ CC = $(PREFIX)gcc
AR = $(PREFIX)ar
E=.exe
-CFLAGS=$(CPPFLAGS) -g --std=gnu89 -D_WIN32_WINNT=0x0600 -Isrc/ares/config_win32
-LINKFLAGS=-lm
+CFLAGS=$(CPPFLAGS) -g --std=gnu89 -D_WIN32_WINNT=0x0600
+LDFLAGS=-lm
-CARES_OBJS += src/ares/windows_port.o
-CARES_OBJS += src/ares/ares_platform.o
-WIN_SRCS=$(wildcard src/win/*.c)
+WIN_SRCS=$(wildcard $(SRCDIR)/src/win/*.c)
WIN_OBJS=$(WIN_SRCS:.c=.o)
RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE # Need _GNU_SOURCE for strdup?
-RUNNER_LINKFLAGS=$(LINKFLAGS)
+RUNNER_LDFLAGS=$(LDFLAGS)
RUNNER_LIBS=-lws2_32 -lpsapi -liphlpapi
RUNNER_SRC=test/runner-win.c
-uv.a: $(WIN_OBJS) src/cares.o src/fs-poll.o src/uv-common.o $(CARES_OBJS)
- $(AR) rcs uv.a $^
+libuv.a: $(WIN_OBJS) src/fs-poll.o src/inet.o src/uv-common.o
+ $(AR) rcs $@ $^
src/%.o: src/%.c include/uv.h include/uv-private/uv-win.h
$(CC) $(CFLAGS) -c $< -o $@
@@ -46,16 +44,8 @@ src/%.o: src/%.c include/uv.h include/uv-private/uv-win.h
src/win/%.o: src/win/%.c include/uv.h include/uv-private/uv-win.h src/win/internal.h
$(CC) $(CFLAGS) -o $@ -c $<
-EIO_CPPFLAGS += $(CPPFLAGS)
-EIO_CPPFLAGS += -DEIO_STACKSIZE=65536
-EIO_CPPFLAGS += -D_GNU_SOURCE
-
clean-platform:
- -rm -f src/ares/*.o
- -rm -f src/eio/*.o
-rm -f src/win/*.o
distclean-platform:
- -rm -f src/ares/*.o
- -rm -f src/eio/*.o
-rm -f src/win/*.o
diff --git a/deps/uv/config-unix.mk b/deps/uv/config-unix.mk
index 0581b5114..8d0189822 100644
--- a/deps/uv/config-unix.mk
+++ b/deps/uv/config-unix.mk
@@ -21,153 +21,147 @@
E=
CSTDFLAG=--std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter
CFLAGS += -g
-CPPFLAGS += -Isrc -Isrc/unix/ev
-LINKFLAGS=-lm
+CPPFLAGS += -I$(SRCDIR)/src
+LDFLAGS=-lm
CPPFLAGS += -D_LARGEFILE_SOURCE
CPPFLAGS += -D_FILE_OFFSET_BITS=64
+RUNNER_SRC=test/runner-unix.c
+RUNNER_CFLAGS=$(CFLAGS) -I$(SRCDIR)/test
+RUNNER_LDFLAGS=-L"$(CURDIR)" -luv -Xlinker -rpath -Xlinker "$(CURDIR)"
+
OBJS += src/unix/async.o
OBJS += src/unix/core.o
OBJS += src/unix/dl.o
OBJS += src/unix/error.o
OBJS += src/unix/fs.o
+OBJS += src/unix/getaddrinfo.o
OBJS += src/unix/loop.o
OBJS += src/unix/loop-watcher.o
OBJS += src/unix/pipe.o
OBJS += src/unix/poll.o
OBJS += src/unix/process.o
+OBJS += src/unix/signal.o
OBJS += src/unix/stream.o
OBJS += src/unix/tcp.o
OBJS += src/unix/thread.o
+OBJS += src/unix/threadpool.o
OBJS += src/unix/timer.o
OBJS += src/unix/tty.o
OBJS += src/unix/udp.o
-
-ifeq (SunOS,$(uname_S))
-EV_CONFIG=config_sunos.h
-EIO_CONFIG=config_sunos.h
-CPPFLAGS += -Isrc/ares/config_sunos -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
-LINKFLAGS+=-lsocket -lnsl -lkstat
+OBJS += src/fs-poll.o
+OBJS += src/uv-common.o
+OBJS += src/inet.o
+
+ifeq (sunos,$(OS))
+CPPFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
+LDFLAGS+=-lkstat -lnsl -lsendfile -lsocket
+# Library dependencies are not transitive.
+RUNNER_LDFLAGS += $(LDFLAGS)
OBJS += src/unix/sunos.o
endif
-ifeq (Darwin,$(uname_S))
-EV_CONFIG=config_darwin.h
-EIO_CONFIG=config_darwin.h
-CPPFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 -Isrc/ares/config_darwin
-LINKFLAGS+=-framework CoreServices
+ifeq (aix,$(OS))
+CPPFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500
+LDFLAGS+= -lperfstat
+OBJS += src/unix/aix.o
+endif
+
+ifeq (darwin,$(OS))
+CPPFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
+LDFLAGS += -framework Foundation \
+ -framework CoreServices \
+ -framework ApplicationServices \
+ -dynamiclib -install_name "@rpath/libuv.dylib"
+SOEXT = dylib
OBJS += src/unix/darwin.o
OBJS += src/unix/kqueue.o
+OBJS += src/unix/fsevents.o
+OBJS += src/unix/proctitle.o
+OBJS += src/unix/darwin-proctitle.o
endif
-ifeq (Linux,$(uname_S))
-EV_CONFIG=config_linux.h
-EIO_CONFIG=config_linux.h
+ifeq (linux,$(OS))
CSTDFLAG += -D_GNU_SOURCE
-CPPFLAGS += -Isrc/ares/config_linux
-LINKFLAGS+=-ldl -lrt
-OBJS += src/unix/linux/linux-core.o \
- src/unix/linux/inotify.o \
- src/unix/linux/syscalls.o
+LDFLAGS+=-ldl -lrt
+RUNNER_CFLAGS += -D_GNU_SOURCE
+OBJS += src/unix/linux-core.o \
+ src/unix/linux-inotify.o \
+ src/unix/linux-syscalls.o \
+ src/unix/proctitle.o
endif
-ifeq (FreeBSD,$(uname_S))
-EV_CONFIG=config_freebsd.h
-EIO_CONFIG=config_freebsd.h
-CPPFLAGS += -Isrc/ares/config_freebsd
-LINKFLAGS+=-lkvm
+ifeq (freebsd,$(OS))
+LDFLAGS+=-lkvm
OBJS += src/unix/freebsd.o
OBJS += src/unix/kqueue.o
endif
-ifeq (DragonFly,$(uname_S))
-EV_CONFIG=config_freebsd.h
-EIO_CONFIG=config_freebsd.h
-CPPFLAGS += -Isrc/ares/config_freebsd
-LINKFLAGS+=
+ifeq (dragonfly,$(OS))
+LDFLAGS+=-lkvm
OBJS += src/unix/freebsd.o
OBJS += src/unix/kqueue.o
endif
-ifeq (NetBSD,$(uname_S))
-EV_CONFIG=config_netbsd.h
-EIO_CONFIG=config_netbsd.h
-CPPFLAGS += -Isrc/ares/config_netbsd
-LINKFLAGS+=
+ifeq (netbsd,$(OS))
+LDFLAGS+=-lkvm
OBJS += src/unix/netbsd.o
OBJS += src/unix/kqueue.o
endif
-ifeq (OpenBSD,$(uname_S))
-EV_CONFIG=config_openbsd.h
-EIO_CONFIG=config_openbsd.h
-CPPFLAGS += -Isrc/ares/config_openbsd
-LINKFLAGS+=-lkvm
+ifeq (openbsd,$(OS))
+LDFLAGS+=-lkvm
OBJS += src/unix/openbsd.o
OBJS += src/unix/kqueue.o
endif
-ifneq (,$(findstring CYGWIN,$(uname_S)))
-EV_CONFIG=config_cygwin.h
-EIO_CONFIG=config_cygwin.h
+ifneq (,$(findstring cygwin,$(OS)))
# We drop the --std=c89, it hides CLOCK_MONOTONIC on cygwin
CSTDFLAG = -D_GNU_SOURCE
-CPPFLAGS += -Isrc/ares/config_cygwin
-LINKFLAGS+=
+LDFLAGS+=
OBJS += src/unix/cygwin.o
endif
-# Need _GNU_SOURCE for strdup?
-RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE
-RUNNER_LINKFLAGS=$(LINKFLAGS)
-
-ifeq (SunOS,$(uname_S))
-RUNNER_LINKFLAGS += -pthreads
+ifeq (sunos,$(OS))
+RUNNER_LDFLAGS += -pthreads
else
-RUNNER_LINKFLAGS += -pthread
+RUNNER_LDFLAGS += -pthread
endif
-RUNNER_LIBS=
-RUNNER_SRC=test/runner-unix.c
+libuv.a: $(OBJS)
+ $(AR) rcs $@ $^
-uv.a: $(OBJS) src/cares.o src/fs-poll.o src/uv-common.o src/unix/ev/ev.o src/unix/uv-eio.o src/unix/eio/eio.o $(CARES_OBJS)
- $(AR) rcs uv.a $^
+libuv.$(SOEXT): override CFLAGS += -fPIC
+libuv.$(SOEXT): $(OBJS:%.o=%.pic.o)
+ $(CC) -shared -o $@ $^ $(LDFLAGS)
-src/%.o: src/%.c include/uv.h include/uv-private/uv-unix.h
- $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
+include/uv-private/uv-unix.h: \
+ include/uv-private/uv-bsd.h \
+ include/uv-private/uv-darwin.h \
+ include/uv-private/uv-linux.h \
+ include/uv-private/uv-sunos.h
-src/unix/%.o: src/unix/%.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h
- $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
-
-src/unix/ev/ev.o: src/unix/ev/ev.c
- $(CC) $(CPPFLAGS) $(CFLAGS) -c src/unix/ev/ev.c -o src/unix/ev/ev.o -DEV_CONFIG_H=\"$(EV_CONFIG)\"
+src/unix/internal.h: src/unix/linux-syscalls.h
+src/.buildstamp src/unix/.buildstamp test/.buildstamp:
+ mkdir -p $(dir $@)
+ touch $@
-EIO_CPPFLAGS += $(CPPFLAGS)
-EIO_CPPFLAGS += -DEIO_CONFIG_H=\"$(EIO_CONFIG)\"
-EIO_CPPFLAGS += -DEIO_STACKSIZE=262144
-EIO_CPPFLAGS += -D_GNU_SOURCE
-
-src/unix/eio/eio.o: src/unix/eio/eio.c
- $(CC) $(EIO_CPPFLAGS) $(CFLAGS) -c src/unix/eio/eio.c -o src/unix/eio/eio.o
+src/unix/%.o src/unix/%.pic.o: src/unix/%.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h src/unix/.buildstamp
+ $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
-src/unix/uv-eio.o: src/unix/uv-eio.c
- $(CC) $(CPPFLAGS) -Isrc/unix/eio/ $(CSTDFLAG) $(CFLAGS) -c src/unix/uv-eio.c -o src/unix/uv-eio.o
+src/%.o src/%.pic.o: src/%.c include/uv.h include/uv-private/uv-unix.h src/.buildstamp
+ $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
+test/%.o: test/%.c include/uv.h test/.buildstamp
+ $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
clean-platform:
- -rm -f src/ares/*.o
- -rm -f src/unix/*.o
- -rm -f src/unix/ev/*.o
- -rm -f src/unix/eio/*.o
- -rm -f src/unix/linux/*.o
- -rm -rf test/run-tests.dSYM run-benchmarks.dSYM
+ -rm -f libuv.a libuv.$(SOEXT) test/run-{tests,benchmarks}.dSYM
distclean-platform:
- -rm -f src/ares/*.o
- -rm -f src/unix/*.o
- -rm -f src/unix/ev/*.o
- -rm -f src/unix/eio/*.o
- -rm -f src/unix/linux/*.o
- -rm -rf test/run-tests.dSYM run-benchmarks.dSYM
+ -rm -f libuv.a libuv.$(SOEXT) test/run-{tests,benchmarks}.dSYM
+
+%.pic.o %.o: %.m
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $^ -o $@
diff --git a/deps/uv/gyp_uv b/deps/uv/gyp_uv
index 9c719fde5..ab594515a 100755
--- a/deps/uv/gyp_uv
+++ b/deps/uv/gyp_uv
@@ -1,6 +1,7 @@
#!/usr/bin/env python
import glob
+import platform
import os
import subprocess
import sys
@@ -18,6 +19,14 @@ except ImportError:
sys.exit(42)
+def host_arch():
+ machine = platform.machine()
+ if machine == 'i386': return 'ia32'
+ if machine == 'x86_64': return 'x64'
+ if machine.startswith('arm'): return 'arm'
+ return machine # Return as-is and hope for the best.
+
+
def compiler_version():
proc = subprocess.Popen(CC.split() + ['--version'], stdout=subprocess.PIPE)
is_clang = 'clang' in proc.communicate()[0].split('\n')[0]
@@ -45,6 +54,9 @@ if __name__ == '__main__':
args.append(os.path.join(uv_root, 'uv.gyp'))
common_fn = os.path.join(uv_root, 'common.gypi')
options_fn = os.path.join(uv_root, 'options.gypi')
+ # we force vs 2010 over 2008 which would otherwise be the default for gyp
+ if not os.environ.get('GYP_MSVS_VERSION'):
+ os.environ['GYP_MSVS_VERSION'] = '2010'
else:
args.append(os.path.join(os.path.abspath(uv_root), 'uv.gyp'))
common_fn = os.path.join(os.path.abspath(uv_root), 'common.gypi')
@@ -69,9 +81,18 @@ if __name__ == '__main__':
args.append('-Dgcc_version=%d' % (10 * major + minor))
args.append('-Dclang=%d' % int(is_clang))
- args.append('-Dtarget_arch=ia32')
- args.append('-Dcomponent=static_library')
- args.append('-Dlibrary=static_library')
+ if not any(a.startswith('-Dhost_arch=') for a in args):
+ args.append('-Dhost_arch=%s' % host_arch())
+
+ if not any(a.startswith('-Dtarget_arch=') for a in args):
+ args.append('-Dtarget_arch=%s' % host_arch())
+
+ if not any(a.startswith('-Dlibrary=') for a in args):
+ args.append('-Dlibrary=static_library')
+
+ if not any(a.startswith('-Dcomponent=') for a in args):
+ args.append('-Dcomponent=static_library')
+
gyp_args = list(args)
print gyp_args
run_gyp(gyp_args)
diff --git a/deps/uv/include/ares.h b/deps/uv/include/ares.h
deleted file mode 100644
index 53ac861b2..000000000
--- a/deps/uv/include/ares.h
+++ /dev/null
@@ -1,591 +0,0 @@
-
-/* Copyright 1998, 2009 by the Massachusetts Institute of Technology.
- * Copyright (C) 2007-2011 by Daniel Stenberg
- *
- * 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.
- */
-
-#ifndef ARES__H
-#define ARES__H
-
-#include "ares_version.h" /* c-ares version defines */
-
-/*
- * Define WIN32 when build target is Win32 API
- */
-
-#if (defined(_WIN32) || defined(__WIN32__)) && \
- !defined(WIN32) && !defined(__SYMBIAN32__)
-# define WIN32
-#endif
-
-/*************************** libuv patch ***************/
-
-/*
- * We want to avoid autoconf altogether since there are a finite number of
- * operating systems and simply build c-ares. Therefore we do not want the
- * configurations provided by ares_build.h since we are always statically
- * linking c-ares into libuv. Having a system dependent ares_build.h forces
- * all users of ares.h to include the correct ares_build.h. We do not care
- * about the linking checks provided by ares_rules.h. This would complicate
- * the libuv build process.
- */
-
-
-#if defined(WIN32)
-/* Configure process defines this to 1 when it finds out that system */
-/* header file ws2tcpip.h must be included by the external interface. */
-/* #undef CARES_PULL_WS2TCPIP_H */
-# include <winsock2.h>
-# include <ws2tcpip.h>
-# include <windows.h>
-
-#else /* Not Windows */
-
-# include <sys/time.h>
-# include <sys/types.h>
-# include <sys/socket.h>
-#endif
-
-#if 0
-/* The size of `long', as computed by sizeof. */
-#define CARES_SIZEOF_LONG 4
-#endif
-
-/* Integral data type used for ares_socklen_t. */
-#define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
-
-#if 0
-/* The size of `ares_socklen_t', as computed by sizeof. */
-#define CARES_SIZEOF_ARES_SOCKLEN_T 4
-#endif
-
-/* Data type definition of ares_socklen_t. */
-typedef int ares_socklen_t;
-
-#if 0 /* libuv disabled */
-#include "ares_rules.h" /* c-ares rules enforcement */
-#endif
-
-/*********************** end libuv patch ***************/
-
-#include <sys/types.h>
-
-/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
- libc5-based Linux systems. Only include it on system that are known to
- require it! */
-#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
- defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY)
-#include <sys/select.h>
-#endif
-#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
-#include <sys/bsdskt.h>
-#endif
-
-#if defined(WATT32)
-# include <netinet/in.h>
-# include <sys/socket.h>
-# include <tcp.h>
-#elif defined(_WIN32_WCE)
-# ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-# endif
-# include <windows.h>
-# include <winsock.h>
-#elif defined(WIN32)
-# ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-# endif
-# include <windows.h>
-# include <winsock2.h>
-# include <ws2tcpip.h>
-#else
-# include <sys/socket.h>
-# include <netinet/in.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
-** c-ares external API function linkage decorations.
-*/
-
-#if !defined(CARES_STATICLIB) && \
- (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
- /* __declspec function decoration for Win32 and Symbian DLL's */
-# if defined(CARES_BUILDING_LIBRARY)
-# define CARES_EXTERN __declspec(dllexport)
-# else
-# define CARES_EXTERN __declspec(dllimport)
-# endif
-#else
- /* visibility function decoration for other cases */
-# if !defined(CARES_SYMBOL_HIDING) || \
- defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
-# define CARES_EXTERN
-# else
-# define CARES_EXTERN CARES_SYMBOL_SCOPE_EXTERN
-# endif
-#endif
-
-
-#define ARES_SUCCESS 0
-
-/* Server error codes (ARES_ENODATA indicates no relevant answer) */
-#define ARES_ENODATA 1
-#define ARES_EFORMERR 2
-#define ARES_ESERVFAIL 3
-#define ARES_ENOTFOUND 4
-#define ARES_ENOTIMP 5
-#define ARES_EREFUSED 6
-
-/* Locally generated error codes */
-#define ARES_EBADQUERY 7
-#define ARES_EBADNAME 8
-#define ARES_EBADFAMILY 9
-#define ARES_EBADRESP 10
-#define ARES_ECONNREFUSED 11
-#define ARES_ETIMEOUT 12
-#define ARES_EOF 13
-#define ARES_EFILE 14
-#define ARES_ENOMEM 15
-#define ARES_EDESTRUCTION 16
-#define ARES_EBADSTR 17
-
-/* ares_getnameinfo error codes */
-#define ARES_EBADFLAGS 18
-
-/* ares_getaddrinfo error codes */
-#define ARES_ENONAME 19
-#define ARES_EBADHINTS 20
-
-/* Uninitialized library error code */
-#define ARES_ENOTINITIALIZED 21 /* introduced in 1.7.0 */
-
-/* ares_library_init error codes */
-#define ARES_ELOADIPHLPAPI 22 /* introduced in 1.7.0 */
-#define ARES_EADDRGETNETWORKPARAMS 23 /* introduced in 1.7.0 */
-
-/* More error codes */
-#define ARES_ECANCELLED 24 /* introduced in 1.7.0 */
-
-/* Flag values */
-#define ARES_FLAG_USEVC (1 << 0)
-#define ARES_FLAG_PRIMARY (1 << 1)
-#define ARES_FLAG_IGNTC (1 << 2)
-#define ARES_FLAG_NORECURSE (1 << 3)
-#define ARES_FLAG_STAYOPEN (1 << 4)
-#define ARES_FLAG_NOSEARCH (1 << 5)
-#define ARES_FLAG_NOALIASES (1 << 6)
-#define ARES_FLAG_NOCHECKRESP (1 << 7)
-
-/* Option mask values */
-#define ARES_OPT_FLAGS (1 << 0)
-#define ARES_OPT_TIMEOUT (1 << 1)
-#define ARES_OPT_TRIES (1 << 2)
-#define ARES_OPT_NDOTS (1 << 3)
-#define ARES_OPT_UDP_PORT (1 << 4)
-#define ARES_OPT_TCP_PORT (1 << 5)
-#define ARES_OPT_SERVERS (1 << 6)
-#define ARES_OPT_DOMAINS (1 << 7)
-#define ARES_OPT_LOOKUPS (1 << 8)
-#define ARES_OPT_SOCK_STATE_CB (1 << 9)
-#define ARES_OPT_SORTLIST (1 << 10)
-#define ARES_OPT_SOCK_SNDBUF (1 << 11)
-#define ARES_OPT_SOCK_RCVBUF (1 << 12)
-#define ARES_OPT_TIMEOUTMS (1 << 13)
-#define ARES_OPT_ROTATE (1 << 14)
-
-/* Nameinfo flag values */
-#define ARES_NI_NOFQDN (1 << 0)
-#define ARES_NI_NUMERICHOST (1 << 1)
-#define ARES_NI_NAMEREQD (1 << 2)
-#define ARES_NI_NUMERICSERV (1 << 3)
-#define ARES_NI_DGRAM (1 << 4)
-#define ARES_NI_TCP 0
-#define ARES_NI_UDP ARES_NI_DGRAM
-#define ARES_NI_SCTP (1 << 5)
-#define ARES_NI_DCCP (1 << 6)
-#define ARES_NI_NUMERICSCOPE (1 << 7)
-#define ARES_NI_LOOKUPHOST (1 << 8)
-#define ARES_NI_LOOKUPSERVICE (1 << 9)
-/* Reserved for future use */
-#define ARES_NI_IDN (1 << 10)
-#define ARES_NI_IDN_ALLOW_UNASSIGNED (1 << 11)
-#define ARES_NI_IDN_USE_STD3_ASCII_RULES (1 << 12)
-
-/* Addrinfo flag values */
-#define ARES_AI_CANONNAME (1 << 0)
-#define ARES_AI_NUMERICHOST (1 << 1)
-#define ARES_AI_PASSIVE (1 << 2)
-#define ARES_AI_NUMERICSERV (1 << 3)
-#define ARES_AI_V4MAPPED (1 << 4)
-#define ARES_AI_ALL (1 << 5)
-#define ARES_AI_ADDRCONFIG (1 << 6)
-/* Reserved for future use */
-#define ARES_AI_IDN (1 << 10)
-#define ARES_AI_IDN_ALLOW_UNASSIGNED (1 << 11)
-#define ARES_AI_IDN_USE_STD3_ASCII_RULES (1 << 12)
-#define ARES_AI_CANONIDN (1 << 13)
-
-#define ARES_AI_MASK (ARES_AI_CANONNAME|ARES_AI_NUMERICHOST|ARES_AI_PASSIVE| \
- ARES_AI_NUMERICSERV|ARES_AI_V4MAPPED|ARES_AI_ALL| \
- ARES_AI_ADDRCONFIG)
-#define ARES_GETSOCK_MAXNUM 16 /* ares_getsock() can return info about this
- many sockets */
-#define ARES_GETSOCK_READABLE(bits,num) (bits & (1<< (num)))
-#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
- ARES_GETSOCK_MAXNUM)))
-
-/* c-ares library initialization flag values */
-#define ARES_LIB_INIT_NONE (0)
-#define ARES_LIB_INIT_WIN32 (1 << 0)
-#define ARES_LIB_INIT_ALL (ARES_LIB_INIT_WIN32)
-
-
-/*
- * Typedef our socket type
- */
-
-#ifndef ares_socket_typedef
-#ifdef WIN32
-typedef SOCKET ares_socket_t;
-#define ARES_SOCKET_BAD INVALID_SOCKET
-#else
-typedef int ares_socket_t;
-#define ARES_SOCKET_BAD -1
-#endif
-#define ares_socket_typedef
-#endif /* ares_socket_typedef */
-
-typedef void (*ares_sock_state_cb)(void *data,
- ares_socket_t socket_fd,
- int readable,
- int writable);
-
-struct apattern;
-
-/* NOTE about the ares_options struct to users and developers.
-
- This struct will remain looking like this. It will not be extended nor
- shrunk in future releases, but all new options will be set by ares_set_*()
- options instead of with the ares_init_options() function.
-
- Eventually (in a galaxy far far away), all options will be settable by
- ares_set_*() options and the ares_init_options() function will become
- deprecated.
-
- When new options are added to c-ares, they are not added to this
- struct. And they are not "saved" with the ares_save_options() function but
- instead we encourage the use of the ares_dup() function. Needless to say,
- if you add config options to c-ares you need to make sure ares_dup()
- duplicates this new option.
-
- */
-struct ares_options {
- int flags;
- int timeout; /* in seconds or milliseconds, depending on options */
- int tries;
- int ndots;
- unsigned short udp_port;
- unsigned short tcp_port;
- int socket_send_buffer_size;
- int socket_receive_buffer_size;
- struct in_addr *servers;
- int nservers;
- char **domains;
- int ndomains;
- char *lookups;
- ares_sock_state_cb sock_state_cb;
- void *sock_state_cb_data;
- struct apattern *sortlist;
- int nsort;
-};
-
-struct hostent;
-struct timeval;
-struct sockaddr;
-struct ares_channeldata;
-
-typedef struct ares_channeldata *ares_channel;
-
-typedef void (*ares_callback)(void *arg,
- int status,
- int timeouts,
- unsigned char *abuf,
- int alen);
-
-typedef void (*ares_host_callback)(void *arg,
- int status,
- int timeouts,
- struct hostent *hostent);
-
-typedef void (*ares_nameinfo_callback)(void *arg,
- int status,
- int timeouts,
- char *node,
- char *service);
-
-typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd,
- int type,
- void *data);
-
-CARES_EXTERN int ares_library_init(int flags);
-
-CARES_EXTERN void ares_library_cleanup(void);
-
-CARES_EXTERN const char *ares_version(int *version);
-
-CARES_EXTERN int ares_init(ares_channel *channelptr);
-
-CARES_EXTERN int ares_init_options(ares_channel *channelptr,
- struct ares_options *options,
- int optmask);
-
-CARES_EXTERN int ares_save_options(ares_channel channel,
- struct ares_options *options,
- int *optmask);
-
-CARES_EXTERN void ares_destroy_options(struct ares_options *options);
-
-CARES_EXTERN int ares_dup(ares_channel *dest,
- ares_channel src);
-
-CARES_EXTERN void ares_destroy(ares_channel channel);
-
-CARES_EXTERN void ares_cancel(ares_channel channel);
-
-/* These next 3 configure local binding for the out-going socket
- * connection. Use these to specify source IP and/or network device
- * on multi-homed systems.
- */
-CARES_EXTERN void ares_set_local_ip4(ares_channel channel, unsigned int local_ip);
-
-/* local_ip6 should be 16 bytes in length */
-CARES_EXTERN void ares_set_local_ip6(ares_channel channel,
- const unsigned char* local_ip6);
-
-/* local_dev_name should be null terminated. */
-CARES_EXTERN void ares_set_local_dev(ares_channel channel,
- const char* local_dev_name);
-
-CARES_EXTERN void ares_set_socket_callback(ares_channel channel,
- ares_sock_create_callback callback,
- void *user_data);
-
-CARES_EXTERN void ares_send(ares_channel channel,
- const unsigned char *qbuf,
- int qlen,
- ares_callback callback,
- void *arg);
-
-CARES_EXTERN void ares_query(ares_channel channel,
- const char *name,
- int dnsclass,
- int type,
- ares_callback callback,
- void *arg);
-
-CARES_EXTERN void ares_search(ares_channel channel,
- const char *name,
- int dnsclass,
- int type,
- ares_callback callback,
- void *arg);
-
-CARES_EXTERN void ares_gethostbyname(ares_channel channel,
- const char *name,
- int family,
- ares_host_callback callback,
- void *arg);
-
-CARES_EXTERN int ares_gethostbyname_file(ares_channel channel,
- const char *name,
- int family,
- struct hostent **host);
-
-CARES_EXTERN void ares_gethostbyaddr(ares_channel channel,
- const void *addr,
- int addrlen,
- int family,
- ares_host_callback callback,
- void *arg);
-
-CARES_EXTERN void ares_getnameinfo(ares_channel channel,
- const struct sockaddr *sa,
- ares_socklen_t salen,
- int flags,
- ares_nameinfo_callback callback,
- void *arg);
-
-CARES_EXTERN int ares_fds(ares_channel channel,
- fd_set *read_fds,
- fd_set *write_fds);
-
-CARES_EXTERN int ares_getsock(ares_channel channel,
- ares_socket_t *socks,
- int numsocks);
-
-CARES_EXTERN struct timeval *ares_timeout(ares_channel channel,
- struct timeval *maxtv,
- struct timeval *tv);
-
-CARES_EXTERN void ares_process(ares_channel channel,
- fd_set *read_fds,
- fd_set *write_fds);
-
-CARES_EXTERN void ares_process_fd(ares_channel channel,
- ares_socket_t read_fd,
- ares_socket_t write_fd);
-
-CARES_EXTERN int ares_mkquery(const char *name,
- int dnsclass,
- int type,
- unsigned short id,
- int rd,
- unsigned char **buf,
- int *buflen);
-
-CARES_EXTERN int ares_expand_name(const unsigned char *encoded,
- const unsigned char *abuf,
- int alen,
- char **s,
- long *enclen);
-
-CARES_EXTERN int ares_expand_string(const unsigned char *encoded,
- const unsigned char *abuf,
- int alen,
- unsigned char **s,
- long *enclen);
-
-/*
- * NOTE: before c-ares 1.7.0 we would most often use the system in6_addr
- * struct below when ares itself was built, but many apps would use this
- * private version since the header checked a HAVE_* define for it. Starting
- * with 1.7.0 we always declare and use our own to stop relying on the
- * system's one.
- */
-struct ares_in6_addr {
- union {
- unsigned char _S6_u8[16];
- } _S6_un;
-};
-
-struct ares_addrttl {
- struct in_addr ipaddr;
- int ttl;
-};
-
-struct ares_addr6ttl {
- struct ares_in6_addr ip6addr;
- int ttl;
-};
-
-struct ares_srv_reply {
- struct ares_srv_reply *next;
- char *host;
- unsigned short priority;
- unsigned short weight;
- unsigned short port;
-};
-
-struct ares_mx_reply {
- struct ares_mx_reply *next;
- char *host;
- unsigned short priority;
-};
-
-struct ares_txt_reply {
- struct ares_txt_reply *next;
- unsigned char *txt;
- size_t length; /* length excludes null termination */
-};
-
-/*
-** Parse the buffer, starting at *abuf and of length alen bytes, previously
-** obtained from an ares_search call. Put the results in *host, if nonnull.
-** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with
-** their TTLs in that array, and set *naddrttls to the number of addresses
-** so written.
-*/
-
-CARES_EXTERN int ares_parse_a_reply(const unsigned char *abuf,
- int alen,
- struct hostent **host,
- struct ares_addrttl *addrttls,
- int *naddrttls);
-
-CARES_EXTERN int ares_parse_aaaa_reply(const unsigned char *abuf,
- int alen,
- struct hostent **host,
- struct ares_addr6ttl *addrttls,
- int *naddrttls);
-
-CARES_EXTERN int ares_parse_ptr_reply(const unsigned char *abuf,
- int alen,
- const void *addr,
- int addrlen,
- int family,
- struct hostent **host);
-
-CARES_EXTERN int ares_parse_ns_reply(const unsigned char *abuf,
- int alen,
- struct hostent **host);
-
-CARES_EXTERN int ares_parse_srv_reply(const unsigned char* abuf,
- int alen,
- struct ares_srv_reply** srv_out);
-
-CARES_EXTERN int ares_parse_mx_reply(const unsigned char* abuf,
- int alen,
- struct ares_mx_reply** mx_out);
-
-CARES_EXTERN int ares_parse_txt_reply(const unsigned char* abuf,
- int alen,
- struct ares_txt_reply** txt_out);
-
-CARES_EXTERN void ares_free_string(void *str);
-
-CARES_EXTERN void ares_free_hostent(struct hostent *host);
-
-CARES_EXTERN void ares_free_data(void *dataptr);
-
-CARES_EXTERN const char *ares_strerror(int code);
-
-/* TODO: Hold port here as well. */
-struct ares_addr_node {
- struct ares_addr_node *next;
- int family;
- union {
- struct in_addr addr4;
- struct ares_in6_addr addr6;
- } addr;
-};
-
-CARES_EXTERN int ares_set_servers(ares_channel channel,
- struct ares_addr_node *servers);
-
-/* Incomming string format: host[:port][,host[:port]]... */
-CARES_EXTERN int ares_set_servers_csv(ares_channel channel,
- const char* servers);
-
-CARES_EXTERN int ares_get_servers(ares_channel channel,
- struct ares_addr_node **servers);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ARES__H */
diff --git a/deps/uv/include/ares_version.h b/deps/uv/include/ares_version.h
deleted file mode 100644
index efd0156dd..000000000
--- a/deps/uv/include/ares_version.h
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#ifndef ARES__VERSION_H
-#define ARES__VERSION_H
-
-/* This is the global package copyright */
-#define ARES_COPYRIGHT "2004 - 2010 Daniel Stenberg, <daniel@haxx.se>."
-
-#define ARES_VERSION_MAJOR 1
-#define ARES_VERSION_MINOR 7
-#define ARES_VERSION_PATCH 5
-#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
- (ARES_VERSION_MINOR<<8)|\
- (ARES_VERSION_PATCH))
-#define ARES_VERSION_STR "1.7.5-DEV"
-
-#if (ARES_VERSION >= 0x010700)
-# define CARES_HAVE_ARES_LIBRARY_INIT 1
-# define CARES_HAVE_ARES_LIBRARY_CLEANUP 1
-#else
-# undef CARES_HAVE_ARES_LIBRARY_INIT
-# undef CARES_HAVE_ARES_LIBRARY_CLEANUP
-#endif
-
-#endif
diff --git a/deps/uv/include/uv-private/eio.h b/deps/uv/include/uv-private/eio.h
deleted file mode 100644
index aab9988b8..000000000
--- a/deps/uv/include/uv-private/eio.h
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * libeio API header
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libeio@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifndef EIO_H_
-#define EIO_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>
-#include <signal.h>
-#include <sys/types.h>
-
-typedef struct eio_req eio_req;
-typedef struct eio_dirent eio_dirent;
-
-typedef int (*eio_cb)(eio_req *req);
-
-#ifndef EIO_REQ_MEMBERS
-# define EIO_REQ_MEMBERS
-#endif
-
-#ifndef EIO_STRUCT_STAT
-# ifdef _WIN32
-# define EIO_STRUCT_STAT struct _stati64
-# define EIO_STRUCT_STATI64
-# else
-# define EIO_STRUCT_STAT struct stat
-# endif
-#endif
-
-#ifdef _WIN32
- typedef int eio_uid_t;
- typedef int eio_gid_t;
- typedef int eio_mode_t;
- #ifdef __MINGW32__ /* no intptr_t */
- typedef ssize_t eio_ssize_t;
- #else
- typedef intptr_t eio_ssize_t; /* or SSIZE_T */
- #endif
- #if __GNUC__
- typedef long long eio_ino_t;
- #else
- typedef __int64 eio_ino_t; /* unsigned not supported by msvc */
- #endif
-#else
- typedef uid_t eio_uid_t;
- typedef gid_t eio_gid_t;
- typedef ssize_t eio_ssize_t;
- typedef ino_t eio_ino_t;
- typedef mode_t eio_mode_t;
-#endif
-
-#ifndef EIO_STRUCT_STATVFS
-# define EIO_STRUCT_STATVFS struct statvfs
-#endif
-
-/* for readdir */
-
-/* eio_readdir flags */
-enum
-{
- EIO_READDIR_DENTS = 0x01, /* ptr2 contains eio_dirents, not just the (unsorted) names */
- EIO_READDIR_DIRS_FIRST = 0x02, /* dirents gets sorted into a good stat() ing order to find directories first */
- EIO_READDIR_STAT_ORDER = 0x04, /* dirents gets sorted into a good stat() ing order to quickly stat all files */
- EIO_READDIR_FOUND_UNKNOWN = 0x80, /* set by eio_readdir when *_ARRAY was set and any TYPE=UNKNOWN's were found */
-
- EIO_READDIR_CUSTOM1 = 0x100, /* for use by apps */
- EIO_READDIR_CUSTOM2 = 0x200 /* for use by apps */
-};
-
-/* using "typical" values in the hope that the compiler will do something sensible */
-enum eio_dtype
-{
- EIO_DT_UNKNOWN = 0,
- EIO_DT_FIFO = 1,
- EIO_DT_CHR = 2,
- EIO_DT_MPC = 3, /* multiplexed char device (v7+coherent) */
- EIO_DT_DIR = 4,
- EIO_DT_NAM = 5, /* xenix special named file */
- EIO_DT_BLK = 6,
- EIO_DT_MPB = 7, /* multiplexed block device (v7+coherent) */
- EIO_DT_REG = 8,
- EIO_DT_NWK = 9, /* HP-UX network special */
- EIO_DT_CMP = 9, /* VxFS compressed */
- EIO_DT_LNK = 10,
- /* DT_SHAD = 11,*/
- EIO_DT_SOCK = 12,
- EIO_DT_DOOR = 13, /* solaris door */
- EIO_DT_WHT = 14,
- EIO_DT_MAX = 15 /* highest DT_VALUE ever, hopefully */
-};
-
-struct eio_dirent
-{
- int nameofs; /* offset of null-terminated name string in (char *)req->ptr2 */
- unsigned short namelen; /* size of filename without trailing 0 */
- unsigned char type; /* one of EIO_DT_* */
- signed char score; /* internal use */
- eio_ino_t inode; /* the inode number, if available, otherwise unspecified */
-};
-
-/* eio_msync flags */
-enum
-{
- EIO_MS_ASYNC = 1,
- EIO_MS_INVALIDATE = 2,
- EIO_MS_SYNC = 4
-};
-
-/* eio_mtouch flags */
-enum
-{
- EIO_MT_MODIFY = 1
-};
-
-/* eio_sync_file_range flags */
-enum
-{
- EIO_SYNC_FILE_RANGE_WAIT_BEFORE = 1,
- EIO_SYNC_FILE_RANGE_WRITE = 2,
- EIO_SYNC_FILE_RANGE_WAIT_AFTER = 4
-};
-
-/* eio_fallocate flags */
-enum
-{
- EIO_FALLOC_FL_KEEP_SIZE = 1 /* MUST match the value in linux/falloc.h */
-};
-
-/* timestamps and differences - feel free to use double in your code directly */
-typedef double eio_tstamp;
-
-/* the eio request structure */
-enum
-{
- EIO_CUSTOM,
- EIO_OPEN, EIO_CLOSE, EIO_DUP2,
- EIO_READ, EIO_WRITE,
- EIO_READAHEAD, EIO_SENDFILE,
- EIO_STAT, EIO_LSTAT, EIO_FSTAT,
- EIO_STATVFS, EIO_FSTATVFS,
- EIO_TRUNCATE, EIO_FTRUNCATE,
- EIO_UTIME, EIO_FUTIME,
- EIO_CHMOD, EIO_FCHMOD,
- EIO_CHOWN, EIO_FCHOWN,
- EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC, EIO_SYNCFS,
- EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE, EIO_FALLOCATE,
- EIO_MLOCK, EIO_MLOCKALL,
- EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME,
- EIO_MKNOD, EIO_READDIR,
- EIO_LINK, EIO_SYMLINK, EIO_READLINK, EIO_REALPATH,
- EIO_GROUP, EIO_NOP,
- EIO_BUSY
-};
-
-/* mlockall constants */
-enum
-{
- EIO_MCL_CURRENT = 1,
- EIO_MCL_FUTURE = 2
-};
-
-/* request priorities */
-
-enum {
- EIO_PRI_MIN = -4,
- EIO_PRI_MAX = 4,
- EIO_PRI_DEFAULT = 0
-};
-
-#define ETP_PRI_MIN EIO_PRI_MIN
-#define ETP_PRI_MAX EIO_PRI_MAX
-
-#define ETP_NUM_PRI (ETP_PRI_MAX - ETP_PRI_MIN + 1)
-
-#define ETP_REQ eio_req
-
-/*
- * a somewhat faster data structure might be nice, but
- * with 8 priorities this actually needs <20 insns
- * per shift, the most expensive operation.
- */
-typedef struct {
- ETP_REQ *qs[ETP_NUM_PRI], *qe[ETP_NUM_PRI]; /* qstart, qend */
- int size;
-} etp_reqq;
-
-typedef struct {
- etp_reqq res_queue; /* queue of outstanding responses for this channel */
- void *data; /* use this for what you want */
-} eio_channel;
-
-/* eio request structure */
-/* this structure is mostly read-only */
-/* when initialising it, all members must be zero-initialised */
-struct eio_req
-{
- eio_req volatile *next; /* private ETP */
-
- eio_ssize_t result; /* result of syscall, e.g. result = read (... */
- off_t offs; /* read, write, truncate, readahead, sync_file_range, fallocate: file offset, mknod: dev_t */
- size_t size; /* read, write, readahead, sendfile, msync, mlock, sync_file_range, fallocate: length */
- void *ptr1; /* all applicable requests: pathname, old name; readdir: optional eio_dirents */
- void *ptr2; /* all applicable requests: new name or memory buffer; readdir: name strings */
- eio_tstamp nv1; /* utime, futime: atime; busy: sleep time */
- eio_tstamp nv2; /* utime, futime: mtime */
-
- int type; /* EIO_xxx constant ETP */
- int int1; /* all applicable requests: file descriptor; sendfile: output fd; open, msync, mlockall, readdir: flags */
- long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range, fallocate: flags */
- long int3; /* chown, fchown: gid */
- int errorno; /* errno value on syscall return */
-
- eio_channel *channel; /* data used to direct poll callbacks arising from this req */
-
-#if __i386 || __amd64
- unsigned char cancelled;
-#else
- sig_atomic_t cancelled;
-#endif
-
- unsigned char flags; /* private */
- signed char pri; /* the priority */
-
- void *data;
- eio_cb finish;
- void (*destroy)(eio_req *req); /* called when request no longer needed */
- void (*feed)(eio_req *req); /* only used for group requests */
-
- EIO_REQ_MEMBERS
-
- eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private */
-};
-
-/* _private_ request flags */
-enum {
- EIO_FLAG_PTR1_FREE = 0x01, /* need to free(ptr1) */
- EIO_FLAG_PTR2_FREE = 0x02, /* need to free(ptr2) */
- EIO_FLAG_GROUPADD = 0x04 /* some request was added to the group */
-};
-
-/* undocumented/unsupported/private helper */
-/*void eio_page_align (void **addr, size_t *length);*/
-
-/* returns < 0 on error, errno set
- * need_poll, if non-zero, will be called when results are available
- * and eio_poll_cb needs to be invoked (it MUST NOT call eio_poll_cb itself).
- * done_poll is called when the need to poll is gone.
- */
-int eio_init (void (*want_poll)(eio_channel *), void (*done_poll)(eio_channel *));
-
-/* initialises a channel */
-void eio_channel_init(eio_channel *, void *data);
-
-/* must be called regularly to handle pending requests */
-/* returns 0 if all requests were handled, -1 if not, or the value of EIO_FINISH if != 0 */
-int eio_poll (eio_channel *channel);
-
-/* stop polling if poll took longer than duration seconds */
-void eio_set_max_poll_time (eio_tstamp nseconds);
-/* do not handle more then count requests in one call to eio_poll_cb */
-void eio_set_max_poll_reqs (unsigned int nreqs);
-
-/* set minimum required number
- * maximum wanted number
- * or maximum idle number of threads */
-void eio_set_min_parallel (unsigned int nthreads);
-void eio_set_max_parallel (unsigned int nthreads);
-void eio_set_max_idle (unsigned int nthreads);
-void eio_set_idle_timeout (unsigned int seconds);
-
-unsigned int eio_nreqs (void); /* number of requests in-flight */
-unsigned int eio_nready (void); /* number of not-yet handled requests */
-unsigned int eio_npending (void); /* number of finished but unhandled requests */
-unsigned int eio_nthreads (void); /* number of worker threads in use currently */
-
-/*****************************************************************************/
-/* convenience wrappers */
-
-#ifndef EIO_NO_WRAPPERS
-eio_req *eio_nop (int pri, eio_cb cb, void *data, eio_channel *channel); /* does nothing except go through the whole process */
-eio_req *eio_busy (eio_tstamp delay, int pri, eio_cb cb, void *data, eio_channel *channel); /* ties a thread for this long, simulating busyness */
-eio_req *eio_sync (int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_syncfs (int fd, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_close (int fd, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_write (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_fstat (int fd, int pri, eio_cb cb, void *data, eio_channel *channel); /* stat buffer=ptr2 allocated dynamically */
-eio_req *eio_fstatvfs (int fd, int pri, eio_cb cb, void *data, eio_channel *channel); /* stat buffer=ptr2 allocated dynamically */
-eio_req *eio_futime (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_fchmod (int fd, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_fchown (int fd, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_open (const char *path, int flags, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_utime (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_chown (const char *path, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_chmod (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_mkdir (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_readdir (const char *path, int flags, int pri, eio_cb cb, void *data, eio_channel *channel); /* result=ptr2 allocated dynamically */
-eio_req *eio_rmdir (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_unlink (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_readlink (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel); /* result=ptr2 allocated dynamically */
-eio_req *eio_realpath (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel); /* result=ptr2 allocated dynamically */
-eio_req *eio_stat (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel); /* stat buffer=ptr2 allocated dynamically */
-eio_req *eio_lstat (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel); /* stat buffer=ptr2 allocated dynamically */
-eio_req *eio_statvfs (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel); /* stat buffer=ptr2 allocated dynamically */
-eio_req *eio_mknod (const char *path, eio_mode_t mode, dev_t dev, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data, eio_channel *channel);
-eio_req *eio_custom (void (*execute)(eio_req *), int pri, eio_cb cb, void *data, eio_channel *channel);
-#endif
-
-/*****************************************************************************/
-/* groups */
-
-eio_req *eio_grp (eio_cb cb, void *data, eio_channel *channel);
-void eio_grp_feed (eio_req *grp, void (*feed)(eio_req *req), int limit);
-void eio_grp_limit (eio_req *grp, int limit);
-void eio_grp_add (eio_req *grp, eio_req *req);
-void eio_grp_cancel (eio_req *grp); /* cancels all sub requests but not the group */
-
-/*****************************************************************************/
-/* request api */
-
-/* true if the request was cancelled, useful in the invoke callback */
-#define EIO_CANCELLED(req) ((req)->cancelled)
-
-#define EIO_RESULT(req) ((req)->result)
-/* returns a pointer to the result buffer allocated by eio */
-#define EIO_BUF(req) ((req)->ptr2)
-#define EIO_STAT_BUF(req) ((EIO_STRUCT_STAT *)EIO_BUF(req))
-#define EIO_STATVFS_BUF(req) ((EIO_STRUCT_STATVFS *)EIO_BUF(req))
-#define EIO_PATH(req) ((char *)(req)->ptr1)
-
-/* submit a request for execution */
-void eio_submit (eio_req *req);
-/* cancel a request as soon fast as possible, if possible */
-void eio_cancel (eio_req *req);
-
-/*****************************************************************************/
-/* convenience functions */
-
-eio_ssize_t eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count);
-eio_ssize_t eio__pread (int fd, void *buf, size_t count, off_t offset);
-eio_ssize_t eio__pwrite (int fd, void *buf, size_t count, off_t offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/deps/uv/include/uv-private/ev.h b/deps/uv/include/uv-private/ev.h
deleted file mode 100644
index 11e81cda5..000000000
--- a/deps/uv/include/uv-private/ev.h
+++ /dev/null
@@ -1,838 +0,0 @@
-/*
- * libev native API header
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifndef EV_H_
-#define EV_H_
-
-#ifdef __cplusplus
-# define EV_CPP(x) x
-#else
-# define EV_CPP(x)
-#endif
-
-EV_CPP(extern "C" {)
-
-#ifdef __GNUC__
-# define EV_MAYBE_UNUSED __attribute__ ((unused))
-#else
-# define EV_MAYBE_UNUSED
-#endif
-
-/*****************************************************************************/
-
-/* pre-4.0 compatibility */
-#ifndef EV_COMPAT3
-# define EV_COMPAT3 1
-#endif
-
-#ifndef EV_FEATURES
-# define EV_FEATURES 0x7f
-#endif
-
-#define EV_FEATURE_CODE ((EV_FEATURES) & 1)
-#define EV_FEATURE_DATA ((EV_FEATURES) & 2)
-#define EV_FEATURE_CONFIG ((EV_FEATURES) & 4)
-#define EV_FEATURE_API ((EV_FEATURES) & 8)
-#define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16)
-#define EV_FEATURE_BACKENDS ((EV_FEATURES) & 32)
-#define EV_FEATURE_OS ((EV_FEATURES) & 64)
-
-/* these priorities are inclusive, higher priorities will be invoked earlier */
-#ifndef EV_MINPRI
-# define EV_MINPRI (EV_FEATURE_CONFIG ? -2 : 0)
-#endif
-#ifndef EV_MAXPRI
-# define EV_MAXPRI (EV_FEATURE_CONFIG ? +2 : 0)
-#endif
-
-#ifndef EV_MULTIPLICITY
-# define EV_MULTIPLICITY EV_FEATURE_CONFIG
-#endif
-
-#ifndef EV_PERIODIC_ENABLE
-# define EV_PERIODIC_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_STAT_ENABLE
-# define EV_STAT_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_PREPARE_ENABLE
-# define EV_PREPARE_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_CHECK_ENABLE
-# define EV_CHECK_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_IDLE_ENABLE
-# define EV_IDLE_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_FORK_ENABLE
-# define EV_FORK_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_CLEANUP_ENABLE
-# define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_SIGNAL_ENABLE
-# define EV_SIGNAL_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_CHILD_ENABLE
-# ifdef _WIN32
-# define EV_CHILD_ENABLE 0
-# else
-# define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
-#endif
-#endif
-
-#ifndef EV_ASYNC_ENABLE
-# define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_EMBED_ENABLE
-# define EV_EMBED_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_WALK_ENABLE
-# define EV_WALK_ENABLE 0 /* not yet */
-#endif
-
-/*****************************************************************************/
-
-#if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE
-# undef EV_SIGNAL_ENABLE
-# define EV_SIGNAL_ENABLE 1
-#endif
-
-/*****************************************************************************/
-
-typedef double ev_tstamp;
-
-#ifndef EV_ATOMIC_T
-# include <signal.h>
-# define EV_ATOMIC_T sig_atomic_t volatile
-#endif
-
-#if EV_STAT_ENABLE
-# ifdef _WIN32
-# include <time.h>
-# include <sys/types.h>
-# endif
-# include <sys/stat.h>
-#endif
-
-/* support multiple event loops? */
-#if EV_MULTIPLICITY
-struct ev_loop;
-# define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */
-# define EV_P_ EV_P, /* a loop as first of multiple parameters */
-# define EV_A loop /* a loop as sole argument to a function call */
-# define EV_A_ EV_A, /* a loop as first of multiple arguments */
-# define EV_DEFAULT_UC ev_default_loop_uc_ () /* the default loop, if initialised, as sole arg */
-# define EV_DEFAULT_UC_ EV_DEFAULT_UC, /* the default loop as first of multiple arguments */
-# define EV_DEFAULT ev_default_loop (0) /* the default loop as sole arg */
-# define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */
-#else
-# define EV_P void
-# define EV_P_
-# define EV_A
-# define EV_A_
-# define EV_DEFAULT
-# define EV_DEFAULT_
-# define EV_DEFAULT_UC
-# define EV_DEFAULT_UC_
-# undef EV_EMBED_ENABLE
-#endif
-
-/* EV_INLINE is used for functions in header files */
-#if __STDC_VERSION__ >= 199901L && __GNUC__ >= 3
-# define EV_INLINE static inline
-#else
-# define EV_INLINE static
-#endif
-
-/* EV_PROTOTYPES can be used to switch of prototype declarations */
-#ifndef EV_PROTOTYPES
-# define EV_PROTOTYPES 1
-#endif
-
-/*****************************************************************************/
-
-#define EV_VERSION_MAJOR 4
-#define EV_VERSION_MINOR 4
-
-/* eventmask, revents, events... */
-enum {
- EV_UNDEF = -1, /* guaranteed to be invalid */
- EV_NONE = 0x00, /* no events */
- EV_READ = 0x01, /* ev_io detected read will not block */
- EV_WRITE = 0x02, /* ev_io detected write will not block */
- EV_LIBUV_KQUEUE_HACK = 0x40,
- EV__IOFDSET = 0x80, /* internal use only */
- EV_IO = EV_READ, /* alias for type-detection */
- EV_TIMER = 0x00000100, /* timer timed out */
-#if EV_COMPAT3
- EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */
-#endif
- EV_PERIODIC = 0x00000200, /* periodic timer timed out */
- EV_SIGNAL = 0x00000400, /* signal was received */
- EV_CHILD = 0x00000800, /* child/pid had status change */
- EV_STAT = 0x00001000, /* stat data changed */
- EV_IDLE = 0x00002000, /* event loop is idling */
- EV_PREPARE = 0x00004000, /* event loop about to poll */
- EV_CHECK = 0x00008000, /* event loop finished poll */
- EV_EMBED = 0x00010000, /* embedded event loop needs sweep */
- EV_FORK = 0x00020000, /* event loop resumed in child */
- EV_CLEANUP = 0x00040000, /* event loop resumed in child */
- EV_ASYNC = 0x00080000, /* async intra-loop signal */
- EV_CUSTOM = 0x01000000, /* for use by user code */
- EV_ERROR = (-2147483647 - 1) /* sent when an error occurs */
-};
-
-/* can be used to add custom fields to all watchers, while losing binary compatibility */
-#ifndef EV_COMMON
-# define EV_COMMON void *data;
-#endif
-
-#ifndef EV_CB_DECLARE
-# define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents);
-#endif
-#ifndef EV_CB_INVOKE
-# define EV_CB_INVOKE(watcher,revents) (watcher)->cb (EV_A_ (watcher), (revents))
-#endif
-
-/* not official, do not use */
-#define EV_CB(type,name) void name (EV_P_ struct ev_ ## type *w, int revents)
-
-/*
- * struct member types:
- * private: you may look at them, but not change them,
- * and they might not mean anything to you.
- * ro: can be read anytime, but only changed when the watcher isn't active.
- * rw: can be read and modified anytime, even when the watcher is active.
- *
- * some internal details that might be helpful for debugging:
- *
- * active is either 0, which means the watcher is not active,
- * or the array index of the watcher (periodics, timers)
- * or the array index + 1 (most other watchers)
- * or simply 1 for watchers that aren't in some array.
- * pending is either 0, in which case the watcher isn't,
- * or the array index + 1 in the pendings array.
- */
-
-#if EV_MINPRI == EV_MAXPRI
-# define EV_DECL_PRIORITY
-#elif !defined (EV_DECL_PRIORITY)
-# define EV_DECL_PRIORITY int priority;
-#endif
-
-/* shared by all watchers */
-#define EV_WATCHER(type) \
- int active; /* private */ \
- int pending; /* private */ \
- EV_DECL_PRIORITY /* private */ \
- EV_COMMON /* rw */ \
- EV_CB_DECLARE (type) /* private */
-
-#define EV_WATCHER_LIST(type) \
- EV_WATCHER (type) \
- struct ev_watcher_list *next; /* private */
-
-#define EV_WATCHER_TIME(type) \
- EV_WATCHER (type) \
- ev_tstamp at; /* private */
-
-/* base class, nothing to see here unless you subclass */
-typedef struct ev_watcher
-{
- EV_WATCHER (ev_watcher)
-} ev_watcher;
-
-/* base class, nothing to see here unless you subclass */
-typedef struct ev_watcher_list
-{
- EV_WATCHER_LIST (ev_watcher_list)
-} ev_watcher_list;
-
-/* base class, nothing to see here unless you subclass */
-typedef struct ev_watcher_time
-{
- EV_WATCHER_TIME (ev_watcher_time)
-} ev_watcher_time;
-
-/* invoked when fd is either EV_READable or EV_WRITEable */
-/* revent EV_READ, EV_WRITE */
-typedef struct ev_io
-{
- EV_WATCHER_LIST (ev_io)
-
- int fd; /* ro */
- int events; /* ro */
-} ev_io;
-
-/* invoked after a specific time, repeatable (based on monotonic clock) */
-/* revent EV_TIMEOUT */
-typedef struct ev_timer
-{
- EV_WATCHER_TIME (ev_timer)
-
- ev_tstamp repeat; /* rw */
-} ev_timer;
-
-/* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */
-/* revent EV_PERIODIC */
-typedef struct ev_periodic
-{
- EV_WATCHER_TIME (ev_periodic)
-
- ev_tstamp offset; /* rw */
- ev_tstamp interval; /* rw */
- ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now); /* rw */
-} ev_periodic;
-
-/* invoked when the given signal has been received */
-/* revent EV_SIGNAL */
-typedef struct ev_signal
-{
- EV_WATCHER_LIST (ev_signal)
-
- int signum; /* ro */
-} ev_signal;
-
-/* invoked when sigchld is received and waitpid indicates the given pid */
-/* revent EV_CHILD */
-/* does not support priorities */
-typedef struct ev_child
-{
- EV_WATCHER_LIST (ev_child)
-
- int flags; /* private */
- int pid; /* ro */
- int rpid; /* rw, holds the received pid */
- int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */
-} ev_child;
-
-#if EV_STAT_ENABLE
-/* st_nlink = 0 means missing file or other error */
-# ifdef _WIN32
-typedef struct _stati64 ev_statdata;
-# else
-typedef struct stat ev_statdata;
-# endif
-
-/* invoked each time the stat data changes for a given path */
-/* revent EV_STAT */
-typedef struct ev_stat
-{
- EV_WATCHER_LIST (ev_stat)
-
- ev_timer timer; /* private */
- ev_tstamp interval; /* ro */
- const char *path; /* ro */
- ev_statdata prev; /* ro */
- ev_statdata attr; /* ro */
-
- int wd; /* wd for inotify, fd for kqueue */
-} ev_stat;
-#endif
-
-#if EV_IDLE_ENABLE
-/* invoked when the nothing else needs to be done, keeps the process from blocking */
-/* revent EV_IDLE */
-typedef struct ev_idle
-{
- EV_WATCHER (ev_idle)
-} ev_idle;
-#endif
-
-/* invoked for each run of the mainloop, just before the blocking call */
-/* you can still change events in any way you like */
-/* revent EV_PREPARE */
-typedef struct ev_prepare
-{
- EV_WATCHER (ev_prepare)
-} ev_prepare;
-
-/* invoked for each run of the mainloop, just after the blocking call */
-/* revent EV_CHECK */
-typedef struct ev_check
-{
- EV_WATCHER (ev_check)
-} ev_check;
-
-#if EV_FORK_ENABLE
-/* the callback gets invoked before check in the child process when a fork was detected */
-/* revent EV_FORK */
-typedef struct ev_fork
-{
- EV_WATCHER (ev_fork)
-} ev_fork;
-#endif
-
-#if EV_CLEANUP_ENABLE
-/* is invoked just before the loop gets destroyed */
-/* revent EV_CLEANUP */
-typedef struct ev_cleanup
-{
- EV_WATCHER (ev_cleanup)
-} ev_cleanup;
-#endif
-
-#if EV_EMBED_ENABLE
-/* used to embed an event loop inside another */
-/* the callback gets invoked when the event loop has handled events, and can be 0 */
-typedef struct ev_embed
-{
- EV_WATCHER (ev_embed)
-
- struct ev_loop *other; /* ro */
- ev_io io; /* private */
- ev_prepare prepare; /* private */
- ev_check check; /* unused */
- ev_timer timer; /* unused */
- ev_periodic periodic; /* unused */
- ev_idle idle; /* unused */
- ev_fork fork; /* private */
-#if EV_CLEANUP_ENABLE
- ev_cleanup cleanup; /* unused */
-#endif
-} ev_embed;
-#endif
-
-#if EV_ASYNC_ENABLE
-/* invoked when somebody calls ev_async_send on the watcher */
-/* revent EV_ASYNC */
-typedef struct ev_async
-{
- EV_WATCHER (ev_async)
-
- EV_ATOMIC_T sent; /* private */
-} ev_async;
-
-# define ev_async_pending(w) (+(w)->sent)
-#endif
-
-/* the presence of this union forces similar struct layout */
-union ev_any_watcher
-{
- struct ev_watcher w;
- struct ev_watcher_list wl;
-
- struct ev_io io;
- struct ev_timer timer;
- struct ev_periodic periodic;
- struct ev_signal signal;
- struct ev_child child;
-#if EV_STAT_ENABLE
- struct ev_stat stat;
-#endif
-#if EV_IDLE_ENABLE
- struct ev_idle idle;
-#endif
- struct ev_prepare prepare;
- struct ev_check check;
-#if EV_FORK_ENABLE
- struct ev_fork fork;
-#endif
-#if EV_CLEANUP_ENABLE
- struct ev_cleanup cleanup;
-#endif
-#if EV_EMBED_ENABLE
- struct ev_embed embed;
-#endif
-#if EV_ASYNC_ENABLE
- struct ev_async async;
-#endif
-};
-
-/* flag bits for ev_default_loop and ev_loop_new */
-enum {
- /* the default */
- EVFLAG_AUTO = 0x00000000U, /* not quite a mask */
- /* flag bits */
- EVFLAG_NOENV = 0x01000000U, /* do NOT consult environment */
- EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */
- /* debugging/feature disable */
- EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */
-#if EV_COMPAT3
- EVFLAG_NOSIGFD = 0, /* compatibility to pre-3.9 */
-#endif
- EVFLAG_SIGNALFD = 0x00200000U, /* attempt to use signalfd */
- EVFLAG_NOSIGMASK = 0x00400000U /* avoid modifying the signal mask */
-};
-
-/* method bits to be ored together */
-enum {
- EVBACKEND_SELECT = 0x00000001U, /* about anywhere */
- EVBACKEND_POLL = 0x00000002U, /* !win */
- EVBACKEND_EPOLL = 0x00000004U, /* linux */
- EVBACKEND_KQUEUE = 0x00000008U, /* bsd */
- EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */
- EVBACKEND_PORT = 0x00000020U, /* solaris 10 */
- EVBACKEND_ALL = 0x0000003FU, /* all known backends */
- EVBACKEND_MASK = 0x0000FFFFU /* all future backends */
-};
-
-#if EV_PROTOTYPES
-int ev_version_major (void);
-int ev_version_minor (void);
-
-unsigned int ev_supported_backends (void);
-unsigned int ev_recommended_backends (void);
-unsigned int ev_embeddable_backends (void);
-
-ev_tstamp ev_time (void);
-void ev_sleep (ev_tstamp delay); /* sleep for a while */
-
-/* Sets the allocation function to use, works like realloc.
- * It is used to allocate and free memory.
- * If it returns zero when memory needs to be allocated, the library might abort
- * or take some potentially destructive action.
- * The default is your system realloc function.
- */
-void ev_set_allocator (void *(*cb)(void *ptr, long size));
-
-/* set the callback function to call on a
- * retryable syscall error
- * (such as failed select, poll, epoll_wait)
- */
-void ev_set_syserr_cb (void (*cb)(const char *msg));
-
-#if EV_MULTIPLICITY
-
-/* the default loop is the only one that handles signals and child watchers */
-/* you can call this as often as you like */
-struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0));
-
-EV_INLINE struct ev_loop *
-EV_MAYBE_UNUSED ev_default_loop_uc_ (void)
-{
- extern struct ev_loop *ev_default_loop_ptr;
-
- return ev_default_loop_ptr;
-}
-
-EV_INLINE int
-EV_MAYBE_UNUSED ev_is_default_loop (EV_P)
-{
- return EV_A == EV_DEFAULT_UC;
-}
-
-/* create and destroy alternative loops that don't handle signals */
-struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0));
-
-int ev_loop_refcount (EV_P);
-
-ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */
-
-#else
-
-int ev_default_loop (unsigned int flags EV_CPP (= 0)); /* returns true when successful */
-
-EV_INLINE ev_tstamp
-ev_now (void)
-{
- extern ev_tstamp ev_rt_now;
-
- return ev_rt_now;
-}
-
-/* looks weird, but ev_is_default_loop (EV_A) still works if this exists */
-EV_INLINE int
-ev_is_default_loop (void)
-{
- return 1;
-}
-
-#endif /* multiplicity */
-
-/* destroy event loops, also works for the default loop */
-void ev_loop_destroy (EV_P);
-
-/* this needs to be called after fork, to duplicate the loop */
-/* when you want to re-use it in the child */
-/* you can call it in either the parent or the child */
-/* you can actually call it at any time, anywhere :) */
-void ev_loop_fork (EV_P);
-
-unsigned int ev_backend (EV_P); /* backend in use by loop */
-
-void ev_now_update (EV_P); /* update event loop time */
-
-#if EV_WALK_ENABLE
-/* walk (almost) all watchers in the loop of a given type, invoking the */
-/* callback on every such watcher. The callback might stop the watcher, */
-/* but do nothing else with the loop */
-void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w));
-#endif
-
-#endif /* prototypes */
-
-/* ev_run flags values */
-enum {
- EVRUN_NOWAIT = 1, /* do not block/wait */
- EVRUN_ONCE = 2 /* block *once* only */
-};
-
-/* ev_break how values */
-enum {
- EVBREAK_CANCEL = 0, /* undo unloop */
- EVBREAK_ONE = 1, /* unloop once */
- EVBREAK_ALL = 2 /* unloop all loops */
-};
-
-#if EV_PROTOTYPES
-void ev_run (EV_P_ int flags EV_CPP (= 0));
-void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)); /* break out of the loop */
-
-/*
- * ref/unref can be used to add or remove a refcount on the mainloop. every watcher
- * keeps one reference. if you have a long-running watcher you never unregister that
- * should not keep ev_loop from running, unref() after starting, and ref() before stopping.
- */
-void ev_ref (EV_P);
-void ev_unref (EV_P);
-
-/*
- * convenience function, wait for a single event, without registering an event watcher
- * if timeout is < 0, do wait indefinitely
- */
-void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg);
-
-# if EV_FEATURE_API
-unsigned int ev_iteration (EV_P); /* number of loop iterations */
-unsigned int ev_depth (EV_P); /* #ev_loop enters - #ev_loop leaves */
-void ev_verify (EV_P); /* abort if loop data corrupted */
-
-void ev_set_io_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
-void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
-
-/* advanced stuff for threading etc. support, see docs */
-void ev_set_userdata (EV_P_ void *data);
-void *ev_userdata (EV_P);
-void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P));
-void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P));
-
-unsigned int ev_pending_count (EV_P); /* number of pending events, if any */
-void ev_invoke_pending (EV_P); /* invoke all pending watchers */
-
-/*
- * stop/start the timer handling.
- */
-void ev_suspend (EV_P);
-void ev_resume (EV_P);
-#endif
-
-#endif
-
-/* these may evaluate ev multiple times, and the other arguments at most once */
-/* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */
-#define ev_init(ev,cb_) do { \
- ((ev_watcher *)(void *)(ev))->active = \
- ((ev_watcher *)(void *)(ev))->pending = 0; \
- ev_set_priority ((ev), 0); \
- ev_set_cb ((ev), cb_); \
-} while (0)
-
-#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0)
-#define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
-#define ev_periodic_set(ev,ofs_,ival_,rcb_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0)
-#define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0)
-#define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
-#define ev_stat_set(ev,path_,interval_) do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0)
-#define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */
-#define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */
-#define ev_check_set(ev) /* nop, yes, this is a serious in-joke */
-#define ev_embed_set(ev,other_) do { (ev)->other = (other_); } while (0)
-#define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */
-#define ev_cleanup_set(ev) /* nop, yes, this is a serious in-joke */
-#define ev_async_set(ev) /* nop, yes, this is a serious in-joke */
-
-#define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
-#define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
-#define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0)
-#define ev_signal_init(ev,cb,signum) do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
-#define ev_child_init(ev,cb,pid,trace) do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0)
-#define ev_stat_init(ev,cb,path,interval) do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0)
-#define ev_idle_init(ev,cb) do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
-#define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
-#define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
-#define ev_embed_init(ev,cb,other) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0)
-#define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
-#define ev_cleanup_init(ev,cb) do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0)
-#define ev_async_init(ev,cb) do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0)
-
-#define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
-#define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
-
-#define ev_cb(ev) (ev)->cb /* rw */
-
-#if EV_MINPRI == EV_MAXPRI
-# define ev_priority(ev) ((ev), EV_MINPRI)
-# define ev_set_priority(ev,pri) ((ev), (pri))
-#else
-# define ev_priority(ev) (+(((ev_watcher *)(void *)(ev))->priority))
-# define ev_set_priority(ev,pri) ( (ev_watcher *)(void *)(ev))->priority = (pri)
-#endif
-
-#define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at)
-
-#ifndef ev_set_cb
-# define ev_set_cb(ev,cb_) ev_cb (ev) = (cb_)
-#endif
-
-/* stopping (enabling, adding) a watcher does nothing if it is already running */
-/* stopping (disabling, deleting) a watcher does nothing unless its already running */
-#if EV_PROTOTYPES
-
-/* feeds an event into a watcher as if the event actually occured */
-/* accepts any ev_watcher type */
-void ev_feed_event (EV_P_ void *w, int revents);
-void ev_feed_fd_event (EV_P_ int fd, int revents);
-#if EV_SIGNAL_ENABLE
-void ev_feed_signal (int signum);
-void ev_feed_signal_event (EV_P_ int signum);
-#endif
-void ev_invoke (EV_P_ void *w, int revents);
-int ev_clear_pending (EV_P_ void *w);
-
-void ev_io_start (EV_P_ ev_io *w);
-void ev_io_stop (EV_P_ ev_io *w);
-
-void ev_timer_start (EV_P_ ev_timer *w);
-void ev_timer_stop (EV_P_ ev_timer *w);
-/* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */
-void ev_timer_again (EV_P_ ev_timer *w);
-/* return remaining time */
-ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w);
-
-#if EV_PERIODIC_ENABLE
-void ev_periodic_start (EV_P_ ev_periodic *w);
-void ev_periodic_stop (EV_P_ ev_periodic *w);
-void ev_periodic_again (EV_P_ ev_periodic *w);
-#endif
-
-/* only supported in the default loop */
-#if EV_SIGNAL_ENABLE
-void ev_signal_start (EV_P_ ev_signal *w);
-void ev_signal_stop (EV_P_ ev_signal *w);
-#endif
-
-/* only supported in the default loop */
-# if EV_CHILD_ENABLE
-void ev_child_start (EV_P_ ev_child *w);
-void ev_child_stop (EV_P_ ev_child *w);
-# endif
-
-# if EV_STAT_ENABLE
-void ev_stat_start (EV_P_ ev_stat *w);
-void ev_stat_stop (EV_P_ ev_stat *w);
-void ev_stat_stat (EV_P_ ev_stat *w);
-# endif
-
-# if EV_IDLE_ENABLE
-void ev_idle_start (EV_P_ ev_idle *w);
-void ev_idle_stop (EV_P_ ev_idle *w);
-# endif
-
-#if EV_PREPARE_ENABLE
-void ev_prepare_start (EV_P_ ev_prepare *w);
-void ev_prepare_stop (EV_P_ ev_prepare *w);
-#endif
-
-#if EV_CHECK_ENABLE
-void ev_check_start (EV_P_ ev_check *w);
-void ev_check_stop (EV_P_ ev_check *w);
-#endif
-
-# if EV_FORK_ENABLE
-void ev_fork_start (EV_P_ ev_fork *w);
-void ev_fork_stop (EV_P_ ev_fork *w);
-# endif
-
-# if EV_CLEANUP_ENABLE
-void ev_cleanup_start (EV_P_ ev_cleanup *w);
-void ev_cleanup_stop (EV_P_ ev_cleanup *w);
-# endif
-
-# if EV_EMBED_ENABLE
-/* only supported when loop to be embedded is in fact embeddable */
-void ev_embed_start (EV_P_ ev_embed *w);
-void ev_embed_stop (EV_P_ ev_embed *w);
-void ev_embed_sweep (EV_P_ ev_embed *w);
-# endif
-
-# if EV_ASYNC_ENABLE
-void ev_async_start (EV_P_ ev_async *w);
-void ev_async_stop (EV_P_ ev_async *w);
-void ev_async_send (EV_P_ ev_async *w);
-# endif
-
-#if EV_COMPAT3
- #define EVLOOP_NONBLOCK EVRUN_NOWAIT
- #define EVLOOP_ONESHOT EVRUN_ONCE
- #define EVUNLOOP_CANCEL EVBREAK_CANCEL
- #define EVUNLOOP_ONE EVBREAK_ONE
- #define EVUNLOOP_ALL EVBREAK_ALL
- #if EV_PROTOTYPES
- EV_INLINE void EV_MAYBE_UNUSED ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); }
- EV_INLINE void EV_MAYBE_UNUSED ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); }
- EV_INLINE void EV_MAYBE_UNUSED ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); }
- EV_INLINE void EV_MAYBE_UNUSED ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); }
- #if EV_FEATURE_API
- EV_INLINE unsigned int EV_MAYBE_UNUSED ev_loop_count (EV_P) { return ev_iteration (EV_A); }
- EV_INLINE unsigned int EV_MAYBE_UNUSED ev_loop_depth (EV_P) { return ev_depth (EV_A); }
- EV_INLINE void EV_MAYBE_UNUSED ev_loop_verify (EV_P) { ev_verify (EV_A); }
- #endif
- #endif
-#else
- typedef struct ev_loop ev_loop;
-#endif
-
-#endif
-
-EV_CPP(})
-
-#endif
-
diff --git a/deps/uv/include/uv-private/ngx-queue.h b/deps/uv/include/uv-private/ngx-queue.h
index 08fd655a1..3c3ed1b03 100644
--- a/deps/uv/include/uv-private/ngx-queue.h
+++ b/deps/uv/include/uv-private/ngx-queue.h
@@ -17,8 +17,11 @@ struct ngx_queue_s {
#define ngx_queue_init(q) \
+ do { \
(q)->prev = q; \
- (q)->next = q
+ (q)->next = q; \
+ } \
+ while (0)
#define ngx_queue_empty(h) \
@@ -26,20 +29,26 @@ struct ngx_queue_s {
#define ngx_queue_insert_head(h, x) \
+ do { \
(x)->next = (h)->next; \
(x)->next->prev = x; \
(x)->prev = h; \
- (h)->next = x
+ (h)->next = x; \
+ } \
+ while (0)
#define ngx_queue_insert_after ngx_queue_insert_head
#define ngx_queue_insert_tail(h, x) \
+ do { \
(x)->prev = (h)->prev; \
(x)->prev->next = x; \
(x)->next = h; \
- (h)->prev = x
+ (h)->prev = x; \
+ } \
+ while (0)
#define ngx_queue_head(h) \
@@ -62,41 +71,53 @@ struct ngx_queue_s {
(q)->prev
-#if (NGX_DEBUG)
+#if defined(NGX_DEBUG)
#define ngx_queue_remove(x) \
+ do { \
(x)->next->prev = (x)->prev; \
(x)->prev->next = (x)->next; \
(x)->prev = NULL; \
- (x)->next = NULL
+ (x)->next = NULL; \
+ } \
+ while (0)
#else
#define ngx_queue_remove(x) \
+ do { \
(x)->next->prev = (x)->prev; \
- (x)->prev->next = (x)->next
+ (x)->prev->next = (x)->next; \
+ } \
+ while (0)
#endif
#define ngx_queue_split(h, q, n) \
+ do { \
(n)->prev = (h)->prev; \
(n)->prev->next = n; \
(n)->next = q; \
(h)->prev = (q)->prev; \
(h)->prev->next = h; \
- (q)->prev = n;
+ (q)->prev = n; \
+ } \
+ while (0)
#define ngx_queue_add(h, n) \
+ do { \
(h)->prev->next = (n)->next; \
(n)->next->prev = (h)->prev; \
(h)->prev = (n)->prev; \
- (h)->prev->next = h;
+ (h)->prev->next = h; \
+ } \
+ while (0)
#define ngx_queue_data(q, type, link) \
- (type *) ((unsigned char *) q - offsetof(type, link))
+ ((type *) ((unsigned char *) q - offsetof(type, link)))
#define ngx_queue_foreach(q, h) \
diff --git a/deps/uv/include/uv-private/stdint-msvc2008.h b/deps/uv/include/uv-private/stdint-msvc2008.h
new file mode 100644
index 000000000..d02608a59
--- /dev/null
+++ b/deps/uv/include/uv-private/stdint-msvc2008.h
@@ -0,0 +1,247 @@
+// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2008 Alexander Chemeris
+//
+// 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. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef signed char int8_t;
+ typedef signed short int16_t;
+ typedef signed int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef signed __int8 int8_t;
+ typedef signed __int16 int16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+#endif
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef signed __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 signed int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/deps/uv/include/uv-private/uv-bsd.h b/deps/uv/include/uv-private/uv-bsd.h
new file mode 100644
index 000000000..2d72b3d77
--- /dev/null
+++ b/deps/uv/include/uv-private/uv-bsd.h
@@ -0,0 +1,34 @@
+/* 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.
+ */
+
+#ifndef UV_BSD_H
+#define UV_BSD_H
+
+#define UV_PLATFORM_FS_EVENT_FIELDS \
+ uv__io_t event_watcher; \
+
+#define UV_IO_PRIVATE_PLATFORM_FIELDS \
+ int rcount; \
+ int wcount; \
+
+#define UV_HAVE_KQUEUE 1
+
+#endif /* UV_BSD_H */
diff --git a/deps/uv/include/uv-private/uv-darwin.h b/deps/uv/include/uv-private/uv-darwin.h
new file mode 100644
index 000000000..e861cbab9
--- /dev/null
+++ b/deps/uv/include/uv-private/uv-darwin.h
@@ -0,0 +1,61 @@
+/* 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.
+ */
+
+#ifndef UV_DARWIN_H
+#define UV_DARWIN_H
+
+#if defined(__APPLE__) && defined(__MACH__)
+# include <mach/mach.h>
+# include <mach/task.h>
+# include <mach/semaphore.h>
+# include <TargetConditionals.h>
+# define UV_PLATFORM_SEM_T semaphore_t
+#endif
+
+#define UV_IO_PRIVATE_PLATFORM_FIELDS \
+ int rcount; \
+ int wcount; \
+
+#define UV_PLATFORM_LOOP_FIELDS \
+ uv_thread_t cf_thread; \
+ void* cf_cb; \
+ void* cf_loop; \
+ uv_mutex_t cf_mutex; \
+ uv_sem_t cf_sem; \
+ ngx_queue_t cf_signals; \
+
+#define UV_PLATFORM_FS_EVENT_FIELDS \
+ uv__io_t event_watcher; \
+ char* realpath; \
+ int realpath_len; \
+ int cf_flags; \
+ void* cf_eventstream; \
+ uv_async_t* cf_cb; \
+ ngx_queue_t cf_events; \
+ uv_sem_t cf_sem; \
+ uv_mutex_t cf_mutex; \
+
+#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \
+ void* select; \
+
+#define UV_HAVE_KQUEUE 1
+
+#endif /* UV_DARWIN_H */
diff --git a/deps/uv/include/uv-private/uv-linux.h b/deps/uv/include/uv-private/uv-linux.h
new file mode 100644
index 000000000..0d50123e3
--- /dev/null
+++ b/deps/uv/include/uv-private/uv-linux.h
@@ -0,0 +1,34 @@
+/* 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.
+ */
+
+#ifndef UV_LINUX_H
+#define UV_LINUX_H
+
+#define UV_PLATFORM_LOOP_FIELDS \
+ uv__io_t inotify_read_watcher; \
+ void* inotify_watchers; \
+ int inotify_fd; \
+
+#define UV_PLATFORM_FS_EVENT_FIELDS \
+ ngx_queue_t watchers; \
+ int wd; \
+
+#endif /* UV_LINUX_H */
diff --git a/deps/uv/include/uv-private/uv-sunos.h b/deps/uv/include/uv-private/uv-sunos.h
new file mode 100644
index 000000000..042166424
--- /dev/null
+++ b/deps/uv/include/uv-private/uv-sunos.h
@@ -0,0 +1,44 @@
+/* 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.
+ */
+
+#ifndef UV_SUNOS_H
+#define UV_SUNOS_H
+
+#include <sys/port.h>
+#include <port.h>
+
+/* For the sake of convenience and reduced #ifdef-ery in src/unix/sunos.c,
+ * add the fs_event fields even when this version of SunOS doesn't support
+ * file watching.
+ */
+#define UV_PLATFORM_LOOP_FIELDS \
+ uv__io_t fs_event_watcher; \
+ int fs_fd; \
+
+#if defined(PORT_SOURCE_FILE)
+
+# define UV_PLATFORM_FS_EVENT_FIELDS \
+ file_obj_t fo; \
+ int fd; \
+
+#endif /* defined(PORT_SOURCE_FILE) */
+
+#endif /* UV_SUNOS_H */
diff --git a/deps/uv/include/uv-private/uv-unix.h b/deps/uv/include/uv-private/uv-unix.h
index 40bbdf6ed..729082e0b 100644
--- a/deps/uv/include/uv-private/uv-unix.h
+++ b/deps/uv/include/uv-private/uv-unix.h
@@ -24,9 +24,6 @@
#include "ngx-queue.h"
-#include "ev.h"
-#include "eio.h"
-
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -40,20 +37,80 @@
#include <termios.h>
#include <pwd.h>
+#include <semaphore.h>
#include <pthread.h>
#include <signal.h>
-#if defined(__APPLE__) && defined(__MACH__)
-# include <mach/mach.h>
-# include <mach/task.h>
-# include <mach/semaphore.h>
-#else
-# include <semaphore.h>
+#if defined(__linux__)
+# include "uv-linux.h"
+#elif defined(__sun)
+# include "uv-sunos.h"
+#elif defined(__APPLE__)
+# include "uv-darwin.h"
+#elif defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__)
+# include "uv-bsd.h"
#endif
-#if __sun
-# include <sys/port.h>
-# include <port.h>
+#ifndef UV_IO_PRIVATE_PLATFORM_FIELDS
+# define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */
+#endif
+
+#define UV_IO_PRIVATE_FIELDS \
+ UV_IO_PRIVATE_PLATFORM_FIELDS \
+
+struct uv__io_s;
+struct uv__async;
+struct uv_loop_s;
+
+typedef void (*uv__io_cb)(struct uv_loop_s* loop,
+ struct uv__io_s* w,
+ unsigned int events);
+typedef struct uv__io_s uv__io_t;
+
+struct uv__io_s {
+ uv__io_cb cb;
+ ngx_queue_t pending_queue;
+ ngx_queue_t watcher_queue;
+ unsigned int pevents; /* Pending event mask i.e. mask at next tick. */
+ unsigned int events; /* Current event mask. */
+ int fd;
+ UV_IO_PRIVATE_FIELDS
+};
+
+typedef void (*uv__async_cb)(struct uv_loop_s* loop,
+ struct uv__async* w,
+ unsigned int nevents);
+
+struct uv__async {
+ uv__async_cb cb;
+ uv__io_t io_watcher;
+ int wfd;
+};
+
+struct uv__work {
+ void (*work)(struct uv__work *w);
+ void (*done)(struct uv__work *w, int status);
+ struct uv_loop_s* loop;
+ ngx_queue_t wq;
+};
+
+#ifndef UV_PLATFORM_SEM_T
+# define UV_PLATFORM_SEM_T sem_t
+#endif
+
+#ifndef UV_PLATFORM_LOOP_FIELDS
+# define UV_PLATFORM_LOOP_FIELDS /* empty */
+#endif
+
+#ifndef UV_PLATFORM_FS_EVENT_FIELDS
+# define UV_PLATFORM_FS_EVENT_FIELDS /* empty */
+#endif
+
+#ifndef UV_STREAM_PRIVATE_PLATFORM_FIELDS
+# define UV_STREAM_PRIVATE_PLATFORM_FIELDS /* empty */
#endif
/* Note: May be cast to struct iovec. See writev(2). */
@@ -63,9 +120,7 @@ typedef struct {
} uv_buf_t;
typedef int uv_file;
-
typedef int uv_os_sock_t;
-
typedef struct stat uv_statbuf_t;
#define UV_ONCE_INIT PTHREAD_ONCE_INIT
@@ -74,11 +129,25 @@ typedef pthread_once_t uv_once_t;
typedef pthread_t uv_thread_t;
typedef pthread_mutex_t uv_mutex_t;
typedef pthread_rwlock_t uv_rwlock_t;
+typedef UV_PLATFORM_SEM_T uv_sem_t;
+typedef pthread_cond_t uv_cond_t;
+
+
#if defined(__APPLE__) && defined(__MACH__)
-typedef semaphore_t uv_sem_t;
-#else
-typedef sem_t uv_sem_t;
-#endif
+
+typedef struct {
+ unsigned int n;
+ unsigned int count;
+ uv_mutex_t mutex;
+ uv_sem_t turnstile1;
+ uv_sem_t turnstile2;
+} uv_barrier_t;
+
+#else /* defined(__APPLE__) && defined(__MACH__) */
+
+typedef pthread_barrier_t uv_barrier_t;
+
+#endif /* defined(__APPLE__) && defined(__MACH__) */
/* Platform-specific definitions for uv_spawn support. */
typedef gid_t uv_gid_t;
@@ -86,158 +155,119 @@ typedef uid_t uv_uid_t;
/* Platform-specific definitions for uv_dlopen support. */
#define UV_DYNAMIC /* empty */
+
typedef struct {
void* handle;
char* errmsg;
} uv_lib_t;
-struct uv__io_s;
-struct uv_loop_s;
-
-typedef struct uv__io_s uv__io_t;
-typedef void (*uv__io_cb)(struct uv_loop_s* loop, uv__io_t* handle, int events);
-
-struct uv__io_s {
- ev_io io_watcher;
-};
-
-#define UV_REQ_TYPE_PRIVATE /* empty */
-
-#if __linux__
-# define UV_LOOP_PRIVATE_PLATFORM_FIELDS \
- uv__io_t inotify_read_watcher; \
- void* inotify_watchers; \
- int inotify_fd;
-#elif defined(PORT_SOURCE_FILE)
-# define UV_LOOP_PRIVATE_PLATFORM_FIELDS \
- ev_io fs_event_watcher; \
- int fs_fd;
-#else
-# define UV_LOOP_PRIVATE_PLATFORM_FIELDS
-#endif
-
#define UV_LOOP_PRIVATE_FIELDS \
- /* Poll result queue */ \
- eio_channel uv_eio_channel; \
- struct ev_loop* ev; \
- /* Various thing for libeio. */ \
- uv_async_t uv_eio_want_poll_notifier; \
- uv_async_t uv_eio_done_poll_notifier; \
- uv_idle_t uv_eio_poller; \
+ unsigned long flags; \
+ int backend_fd; \
+ ngx_queue_t pending_queue; \
+ ngx_queue_t watcher_queue; \
+ uv__io_t** watchers; \
+ unsigned int nwatchers; \
+ unsigned int nfds; \
+ ngx_queue_t wq; \
+ uv_mutex_t wq_mutex; \
+ uv_async_t wq_async; \
uv_handle_t* closing_handles; \
+ ngx_queue_t process_handles[1]; \
ngx_queue_t prepare_handles; \
ngx_queue_t check_handles; \
ngx_queue_t idle_handles; \
ngx_queue_t async_handles; \
- uv__io_t async_watcher; \
- int async_pipefd[2]; \
+ struct uv__async async_watcher; \
/* RB_HEAD(uv__timers, uv_timer_s) */ \
- struct uv__timers { struct uv_timer_s* rbh_root; } timer_handles; \
+ struct uv__timers { \
+ struct uv_timer_s* rbh_root; \
+ } timer_handles; \
uint64_t time; \
- UV_LOOP_PRIVATE_PLATFORM_FIELDS
+ int signal_pipefd[2]; \
+ uv__io_t signal_io_watcher; \
+ uv_signal_t child_watcher; \
+ int emfile_fd; \
+ uint64_t timer_counter; \
+ UV_PLATFORM_LOOP_FIELDS \
-#define UV_REQ_BUFSML_SIZE (4)
+#define UV_REQ_TYPE_PRIVATE /* empty */
#define UV_REQ_PRIVATE_FIELDS /* empty */
-#define UV_WRITE_PRIVATE_FIELDS \
- ngx_queue_t queue; \
- int write_index; \
- uv_buf_t* bufs; \
- int bufcnt; \
- int error; \
- uv_buf_t bufsml[UV_REQ_BUFSML_SIZE];
-
-#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */
-
-#define UV_CONNECT_PRIVATE_FIELDS \
- ngx_queue_t queue;
-
-#define UV_UDP_SEND_PRIVATE_FIELDS \
- ngx_queue_t queue; \
- struct sockaddr_in6 addr; \
- int bufcnt; \
- uv_buf_t* bufs; \
- ssize_t status; \
- uv_udp_send_cb send_cb; \
- uv_buf_t bufsml[UV_REQ_BUFSML_SIZE]; \
-
#define UV_PRIVATE_REQ_TYPES /* empty */
+#define UV_WRITE_PRIVATE_FIELDS \
+ ngx_queue_t queue; \
+ int write_index; \
+ uv_buf_t* bufs; \
+ int bufcnt; \
+ int error; \
+ uv_buf_t bufsml[4]; \
-/* TODO: union or classes please! */
-#define UV_HANDLE_PRIVATE_FIELDS \
- int flags; \
- uv_handle_t* next_closing; \
-
-
-#define UV_STREAM_PRIVATE_FIELDS \
- uv_connect_t *connect_req; \
- uv_shutdown_t *shutdown_req; \
- uv__io_t read_watcher; \
- uv__io_t write_watcher; \
- ngx_queue_t write_queue; \
- ngx_queue_t write_completed_queue; \
- uv_connection_cb connection_cb; \
- int delayed_error; \
- int accepted_fd; \
- int fd; \
-
-
-/* UV_TCP */
-#define UV_TCP_PRIVATE_FIELDS
-
-
-/* UV_UDP */
-#define UV_UDP_PRIVATE_FIELDS \
- int fd; \
- uv_alloc_cb alloc_cb; \
- uv_udp_recv_cb recv_cb; \
- uv__io_t read_watcher; \
- uv__io_t write_watcher; \
- ngx_queue_t write_queue; \
- ngx_queue_t write_completed_queue; \
+#define UV_CONNECT_PRIVATE_FIELDS \
+ ngx_queue_t queue; \
+#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */
-/* UV_NAMED_PIPE */
-#define UV_PIPE_PRIVATE_FIELDS \
+#define UV_UDP_SEND_PRIVATE_FIELDS \
+ ngx_queue_t queue; \
+ struct sockaddr_in6 addr; \
+ int bufcnt; \
+ uv_buf_t* bufs; \
+ ssize_t status; \
+ uv_udp_send_cb send_cb; \
+ uv_buf_t bufsml[4]; \
+
+#define UV_HANDLE_PRIVATE_FIELDS \
+ int flags; \
+ uv_handle_t* next_closing; \
+
+#define UV_STREAM_PRIVATE_FIELDS \
+ uv_connect_t *connect_req; \
+ uv_shutdown_t *shutdown_req; \
+ uv__io_t io_watcher; \
+ ngx_queue_t write_queue; \
+ ngx_queue_t write_completed_queue; \
+ uv_connection_cb connection_cb; \
+ int delayed_error; \
+ int accepted_fd; \
+ UV_STREAM_PRIVATE_PLATFORM_FIELDS \
+
+#define UV_TCP_PRIVATE_FIELDS /* empty */
+
+#define UV_UDP_PRIVATE_FIELDS \
+ uv_alloc_cb alloc_cb; \
+ uv_udp_recv_cb recv_cb; \
+ uv__io_t io_watcher; \
+ ngx_queue_t write_queue; \
+ ngx_queue_t write_completed_queue; \
+
+#define UV_PIPE_PRIVATE_FIELDS \
const char* pipe_fname; /* strdup'ed */
-
-/* UV_POLL */
-#define UV_POLL_PRIVATE_FIELDS \
- int fd; \
+#define UV_POLL_PRIVATE_FIELDS \
uv__io_t io_watcher;
-
-/* UV_PREPARE */
-#define UV_PREPARE_PRIVATE_FIELDS \
- uv_prepare_cb prepare_cb; \
+#define UV_PREPARE_PRIVATE_FIELDS \
+ uv_prepare_cb prepare_cb; \
ngx_queue_t queue;
-
-/* UV_CHECK */
-#define UV_CHECK_PRIVATE_FIELDS \
- uv_check_cb check_cb; \
+#define UV_CHECK_PRIVATE_FIELDS \
+ uv_check_cb check_cb; \
ngx_queue_t queue;
-
-/* UV_IDLE */
-#define UV_IDLE_PRIVATE_FIELDS \
- uv_idle_cb idle_cb; \
+#define UV_IDLE_PRIVATE_FIELDS \
+ uv_idle_cb idle_cb; \
ngx_queue_t queue;
-
-/* UV_ASYNC */
#define UV_ASYNC_PRIVATE_FIELDS \
- volatile sig_atomic_t pending; \
uv_async_cb async_cb; \
- ngx_queue_t queue;
-
+ ngx_queue_t queue; \
+ int pending; \
-/* UV_TIMER */
#define UV_TIMER_PRIVATE_FIELDS \
- /* RB_ENTRY(uv_timer_s) node; */ \
+ /* RB_ENTRY(uv_timer_s) tree_entry; */ \
struct { \
struct uv_timer_s* rbe_left; \
struct uv_timer_s* rbe_right; \
@@ -246,69 +276,57 @@ struct uv__io_s {
} tree_entry; \
uv_timer_cb timer_cb; \
uint64_t timeout; \
- uint64_t repeat;
-
-#define UV_GETADDRINFO_PRIVATE_FIELDS \
- uv_getaddrinfo_cb cb; \
- struct addrinfo* hints; \
- char* hostname; \
- char* service; \
- struct addrinfo* res; \
+ uint64_t repeat; \
+ uint64_t start_id;
+
+#define UV_GETADDRINFO_PRIVATE_FIELDS \
+ struct uv__work work_req; \
+ uv_getaddrinfo_cb cb; \
+ struct addrinfo* hints; \
+ char* hostname; \
+ char* service; \
+ struct addrinfo* res; \
int retcode;
-#define UV_PROCESS_PRIVATE_FIELDS \
- ev_child child_watcher;
-
-#define UV_FS_PRIVATE_FIELDS \
- struct stat statbuf; \
- eio_req* eio;
-
-#define UV_WORK_PRIVATE_FIELDS \
- eio_req* eio;
-
-#define UV_TTY_PRIVATE_FIELDS \
- struct termios orig_termios; \
+#define UV_PROCESS_PRIVATE_FIELDS \
+ ngx_queue_t queue; \
+ int errorno; \
+
+#define UV_FS_PRIVATE_FIELDS \
+ const char *new_path; \
+ uv_file file; \
+ int flags; \
+ mode_t mode; \
+ void* buf; \
+ size_t len; \
+ off_t off; \
+ uid_t uid; \
+ gid_t gid; \
+ double atime; \
+ double mtime; \
+ struct uv__work work_req; \
+
+#define UV_WORK_PRIVATE_FIELDS \
+ struct uv__work work_req;
+
+#define UV_TTY_PRIVATE_FIELDS \
+ struct termios orig_termios; \
int mode;
-/* UV_FS_EVENT_PRIVATE_FIELDS */
-#if defined(__linux__)
-
-#define UV_FS_EVENT_PRIVATE_FIELDS \
- ngx_queue_t watchers; \
- uv_fs_event_cb cb; \
- int wd; \
- void* pad0; \
- void* pad1; \
-
-#elif defined(__APPLE__) \
- || defined(__FreeBSD__) \
- || defined(__DragonFly__) \
- || defined(__OpenBSD__) \
- || defined(__NetBSD__)
-
-#define UV_FS_EVENT_PRIVATE_FIELDS \
- ev_io event_watcher; \
- uv_fs_event_cb cb; \
- int fflags; \
- int fd;
-
-#elif defined(__sun)
-
-#ifdef PORT_SOURCE_FILE
-# define UV_FS_EVENT_PRIVATE_FIELDS \
- ev_io event_watcher; \
- uv_fs_event_cb cb; \
- file_obj_t fo; \
- int fd;
-#else /* !PORT_SOURCE_FILE */
-# define UV_FS_EVENT_PRIVATE_FIELDS
-#endif
-
-#else
-
-/* Stub for platforms where the file watcher isn't implemented yet. */
-#define UV_FS_EVENT_PRIVATE_FIELDS
+#define UV_SIGNAL_PRIVATE_FIELDS \
+ /* RB_ENTRY(uv_signal_s) tree_entry; */ \
+ struct { \
+ struct uv_signal_s* rbe_left; \
+ struct uv_signal_s* rbe_right; \
+ struct uv_signal_s* rbe_parent; \
+ int rbe_color; \
+ } tree_entry; \
+ /* Use two counters here so we don have to fiddle with atomics. */ \
+ unsigned int caught_signals; \
+ unsigned int dispatched_signals;
-#endif
+#define UV_FS_EVENT_PRIVATE_FIELDS \
+ uv_fs_event_cb cb; \
+ UV_PLATFORM_FS_EVENT_FIELDS \
#endif /* UV_UNIX_H */
diff --git a/deps/uv/include/uv-private/uv-win.h b/deps/uv/include/uv-private/uv-win.h
index 5b0aba619..574aa8f26 100644
--- a/deps/uv/include/uv-private/uv-win.h
+++ b/deps/uv/include/uv-private/uv-win.h
@@ -29,21 +29,53 @@ typedef intptr_t ssize_t;
# define _SSIZE_T_DEFINED
#endif
-#include <process.h>
-#include <stdint.h>
#include <winsock2.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#include <windows.h>
+
+#include <process.h>
+#include <signal.h>
#include <sys/stat.h>
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
#include "tree.h"
#include "ngx-queue.h"
#define MAX_PIPENAME_LEN 256
#ifndef S_IFLNK
-# define S_IFLNK 0xA000
+# define S_IFLNK 0xA000
+#endif
+
+/* Additional signals supported by uv_signal and or uv_kill. The CRT defines
+ * the following signals already:
+ *
+ * #define SIGINT 2
+ * #define SIGILL 4
+ * #define SIGABRT_COMPAT 6
+ * #define SIGFPE 8
+ * #define SIGSEGV 11
+ * #define SIGTERM 15
+ * #define SIGBREAK 21
+ * #define SIGABRT 22
+ *
+ * The additional signals have values that are common on other Unix
+ * variants (Linux and Darwin)
+ */
+#define SIGHUP 1
+#define SIGKILL 9
+#define SIGWINCH 28
+
+/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many */
+/* unix-like platforms. However MinGW doesn't define it, so we do. */
+#ifndef SIGABRT_COMPAT
+# define SIGABRT_COMPAT 6
#endif
/*
@@ -51,24 +83,24 @@ typedef intptr_t ssize_t;
* Mingw32 doesn't have these :-(
*/
#ifndef WSAID_ACCEPTEX
-# define WSAID_ACCEPTEX \
- {0xb5367df1, 0xcbac, 0x11cf, \
+# define WSAID_ACCEPTEX \
+ {0xb5367df1, 0xcbac, 0x11cf, \
{0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
-# define WSAID_CONNECTEX \
- {0x25a207b9, 0xddf3, 0x4660, \
+# define WSAID_CONNECTEX \
+ {0x25a207b9, 0xddf3, 0x4660, \
{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}}
-# define WSAID_GETACCEPTEXSOCKADDRS \
- {0xb5367df2, 0xcbac, 0x11cf, \
+# define WSAID_GETACCEPTEXSOCKADDRS \
+ {0xb5367df2, 0xcbac, 0x11cf, \
{0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
-# define WSAID_DISCONNECTEX \
- {0x7fda2e11, 0x8630, 0x436f, \
+# define WSAID_DISCONNECTEX \
+ {0x7fda2e11, 0x8630, 0x436f, \
{0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57}}
-# define WSAID_TRANSMITFILE \
- {0xb5367df0, 0xcbac, 0x11cf, \
+# define WSAID_TRANSMITFILE \
+ {0xb5367df0, 0xcbac, 0x11cf, \
{0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
typedef BOOL PASCAL (*LPFN_ACCEPTEX)
@@ -144,6 +176,10 @@ typedef int (WSAAPI* LPFN_WSARECVFROM)
typedef NTSTATUS *PNTSTATUS;
#endif
+#ifndef RTL_CONDITION_VARIABLE_INIT
+ typedef PVOID CONDITION_VARIABLE, *PCONDITION_VARIABLE;
+#endif
+
typedef struct _AFD_POLL_HANDLE_INFO {
HANDLE Handle;
ULONG Events;
@@ -181,6 +217,23 @@ typedef HANDLE uv_sem_t;
typedef CRITICAL_SECTION uv_mutex_t;
+/* This condition variable implementation is based on the SetEvent solution
+ * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ * We could not use the SignalObjectAndWait solution (section 3.4) because
+ * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and
+ * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs.
+ */
+
+typedef union {
+ CONDITION_VARIABLE cond_var;
+ struct {
+ unsigned int waiters_count;
+ CRITICAL_SECTION waiters_count_lock;
+ HANDLE signal_event;
+ HANDLE broadcast_event;
+ } fallback;
+} uv_cond_t;
+
typedef union {
/* srwlock_ has type SRWLOCK, but not all toolchains define this type in */
/* windows.h. */
@@ -192,14 +245,19 @@ typedef union {
} fallback_;
} uv_rwlock_t;
-#define UV_ONCE_INIT { 0, NULL, NULL }
+typedef struct {
+ unsigned int n;
+ unsigned int count;
+ uv_mutex_t mutex;
+ uv_sem_t turnstile1;
+ uv_sem_t turnstile2;
+} uv_barrier_t;
+
+#define UV_ONCE_INIT { 0, NULL }
typedef struct uv_once_s {
unsigned char ran;
- /* The actual event handle must be aligned to sizeof(HANDLE), so in */
- /* practice it might overlap padding a little. */
HANDLE event;
- HANDLE padding;
} uv_once_t;
/* Platform-specific definitions for uv_spawn support. */
@@ -219,7 +277,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
/* The loop's I/O completion port */ \
HANDLE iocp; \
/* The current time according to the event loop. in msecs. */ \
- int64_t time; \
+ uint64_t time; \
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
/* is empty, tail_ is NULL. If there is only one item, */ \
/* tail_->next_req == tail_ */ \
@@ -244,274 +302,285 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
/* Counter to keep track of active tcp streams */ \
unsigned int active_tcp_streams; \
/* Counter to keep track of active udp streams */ \
- unsigned int active_udp_streams;
-
-#define UV_REQ_TYPE_PRIVATE \
- /* TODO: remove the req suffix */ \
- UV_ACCEPT, \
- UV_FS_EVENT_REQ, \
- UV_POLL_REQ, \
- UV_PROCESS_EXIT, \
- UV_PROCESS_CLOSE, \
- UV_READ, \
- UV_UDP_RECV, \
- UV_WAKEUP,
-
-#define UV_REQ_PRIVATE_FIELDS \
- union { \
- /* Used by I/O operations */ \
- struct { \
- OVERLAPPED overlapped; \
- size_t queued_bytes; \
- }; \
- }; \
+ unsigned int active_udp_streams; \
+ /* Counter to started timer */ \
+ uint64_t timer_counter;
+
+#define UV_REQ_TYPE_PRIVATE \
+ /* TODO: remove the req suffix */ \
+ UV_ACCEPT, \
+ UV_FS_EVENT_REQ, \
+ UV_POLL_REQ, \
+ UV_PROCESS_EXIT, \
+ UV_READ, \
+ UV_UDP_RECV, \
+ UV_WAKEUP, \
+ UV_SIGNAL_REQ,
+
+#define UV_REQ_PRIVATE_FIELDS \
+ union { \
+ /* Used by I/O operations */ \
+ struct { \
+ OVERLAPPED overlapped; \
+ size_t queued_bytes; \
+ }; \
+ }; \
struct uv_req_s* next_req;
-#define UV_WRITE_PRIVATE_FIELDS \
- int ipc_header; \
- uv_buf_t write_buffer; \
- HANDLE event_handle; \
+#define UV_WRITE_PRIVATE_FIELDS \
+ int ipc_header; \
+ uv_buf_t write_buffer; \
+ HANDLE event_handle; \
HANDLE wait_handle;
-#define UV_CONNECT_PRIVATE_FIELDS \
+#define UV_CONNECT_PRIVATE_FIELDS \
/* empty */
-#define UV_SHUTDOWN_PRIVATE_FIELDS \
+#define UV_SHUTDOWN_PRIVATE_FIELDS \
/* empty */
-#define UV_UDP_SEND_PRIVATE_FIELDS \
+#define UV_UDP_SEND_PRIVATE_FIELDS \
/* empty */
-#define UV_PRIVATE_REQ_TYPES \
- typedef struct uv_pipe_accept_s { \
- UV_REQ_FIELDS \
- HANDLE pipeHandle; \
- struct uv_pipe_accept_s* next_pending; \
- } uv_pipe_accept_t; \
- \
- typedef struct uv_tcp_accept_s { \
- UV_REQ_FIELDS \
- SOCKET accept_socket; \
- char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \
- HANDLE event_handle; \
- HANDLE wait_handle; \
- struct uv_tcp_accept_s* next_pending; \
- } uv_tcp_accept_t; \
- \
- typedef struct uv_read_s { \
- UV_REQ_FIELDS \
- HANDLE event_handle; \
- HANDLE wait_handle; \
+#define UV_PRIVATE_REQ_TYPES \
+ typedef struct uv_pipe_accept_s { \
+ UV_REQ_FIELDS \
+ HANDLE pipeHandle; \
+ struct uv_pipe_accept_s* next_pending; \
+ } uv_pipe_accept_t; \
+ \
+ typedef struct uv_tcp_accept_s { \
+ UV_REQ_FIELDS \
+ SOCKET accept_socket; \
+ char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \
+ HANDLE event_handle; \
+ HANDLE wait_handle; \
+ struct uv_tcp_accept_s* next_pending; \
+ } uv_tcp_accept_t; \
+ \
+ typedef struct uv_read_s { \
+ UV_REQ_FIELDS \
+ HANDLE event_handle; \
+ HANDLE wait_handle; \
} uv_read_t;
-#define uv_stream_connection_fields \
- unsigned int write_reqs_pending; \
+#define uv_stream_connection_fields \
+ unsigned int write_reqs_pending; \
uv_shutdown_t* shutdown_req;
-#define uv_stream_server_fields \
+#define uv_stream_server_fields \
uv_connection_cb connection_cb;
-#define UV_STREAM_PRIVATE_FIELDS \
- unsigned int reqs_pending; \
- int activecnt; \
- uv_read_t read_req; \
- union { \
- struct { uv_stream_connection_fields }; \
- struct { uv_stream_server_fields }; \
+#define UV_STREAM_PRIVATE_FIELDS \
+ unsigned int reqs_pending; \
+ int activecnt; \
+ uv_read_t read_req; \
+ union { \
+ struct { uv_stream_connection_fields }; \
+ struct { uv_stream_server_fields }; \
};
-#define uv_tcp_server_fields \
- uv_tcp_accept_t* accept_reqs; \
- unsigned int processed_accepts; \
- uv_tcp_accept_t* pending_accepts; \
+#define uv_tcp_server_fields \
+ uv_tcp_accept_t* accept_reqs; \
+ unsigned int processed_accepts; \
+ uv_tcp_accept_t* pending_accepts; \
LPFN_ACCEPTEX func_acceptex;
-#define uv_tcp_connection_fields \
- uv_buf_t read_buffer; \
+#define uv_tcp_connection_fields \
+ uv_buf_t read_buffer; \
LPFN_CONNECTEX func_connectex;
-#define UV_TCP_PRIVATE_FIELDS \
- SOCKET socket; \
- int bind_error; \
- union { \
- struct { uv_tcp_server_fields }; \
- struct { uv_tcp_connection_fields }; \
+#define UV_TCP_PRIVATE_FIELDS \
+ SOCKET socket; \
+ int bind_error; \
+ union { \
+ struct { uv_tcp_server_fields }; \
+ struct { uv_tcp_connection_fields }; \
};
-#define UV_UDP_PRIVATE_FIELDS \
- SOCKET socket; \
- unsigned int reqs_pending; \
- int activecnt; \
- uv_req_t recv_req; \
- uv_buf_t recv_buffer; \
- struct sockaddr_storage recv_from; \
- int recv_from_len; \
- uv_udp_recv_cb recv_cb; \
- uv_alloc_cb alloc_cb; \
- LPFN_WSARECV func_wsarecv; \
+#define UV_UDP_PRIVATE_FIELDS \
+ SOCKET socket; \
+ unsigned int reqs_pending; \
+ int activecnt; \
+ uv_req_t recv_req; \
+ uv_buf_t recv_buffer; \
+ struct sockaddr_storage recv_from; \
+ int recv_from_len; \
+ uv_udp_recv_cb recv_cb; \
+ uv_alloc_cb alloc_cb; \
+ LPFN_WSARECV func_wsarecv; \
LPFN_WSARECVFROM func_wsarecvfrom;
-#define uv_pipe_server_fields \
- int pending_instances; \
- uv_pipe_accept_t* accept_reqs; \
+#define uv_pipe_server_fields \
+ int pending_instances; \
+ uv_pipe_accept_t* accept_reqs; \
uv_pipe_accept_t* pending_accepts;
-#define uv_pipe_connection_fields \
- uv_timer_t* eof_timer; \
- uv_write_t ipc_header_write_req; \
- int ipc_pid; \
- uint64_t remaining_ipc_rawdata_bytes; \
- unsigned char reserved[sizeof(void*)]; \
- struct { \
- WSAPROTOCOL_INFOW* socket_info; \
- int tcp_connection; \
- } pending_ipc_info; \
+#define uv_pipe_connection_fields \
+ uv_timer_t* eof_timer; \
+ uv_write_t ipc_header_write_req; \
+ int ipc_pid; \
+ uint64_t remaining_ipc_rawdata_bytes; \
+ unsigned char reserved[sizeof(void*)]; \
+ struct { \
+ WSAPROTOCOL_INFOW* socket_info; \
+ int tcp_connection; \
+ } pending_ipc_info; \
uv_write_t* non_overlapped_writes_tail;
-#define UV_PIPE_PRIVATE_FIELDS \
- HANDLE handle; \
- wchar_t* name; \
- union { \
- struct { uv_pipe_server_fields }; \
- struct { uv_pipe_connection_fields }; \
+#define UV_PIPE_PRIVATE_FIELDS \
+ HANDLE handle; \
+ WCHAR* name; \
+ union { \
+ struct { uv_pipe_server_fields }; \
+ struct { uv_pipe_connection_fields }; \
};
/* TODO: put the parser states in an union - TTY handles are always */
/* half-duplex so read-state can safely overlap write-state. */
-#define UV_TTY_PRIVATE_FIELDS \
- HANDLE handle; \
- HANDLE read_line_handle; \
- uv_buf_t read_line_buffer; \
- HANDLE read_raw_wait; \
- DWORD original_console_mode; \
- /* Fields used for translating win */ \
- /* keystrokes into vt100 characters */ \
- char last_key[8]; \
- unsigned char last_key_offset; \
- unsigned char last_key_len; \
- INPUT_RECORD last_input_record; \
- WCHAR last_utf16_high_surrogate; \
- /* utf8-to-utf16 conversion state */ \
- unsigned char utf8_bytes_left; \
- unsigned int utf8_codepoint; \
- /* eol conversion state */ \
- unsigned char previous_eol; \
- /* ansi parser state */ \
- unsigned char ansi_parser_state; \
- unsigned char ansi_csi_argc; \
- unsigned short ansi_csi_argv[4]; \
- COORD saved_position; \
- WORD saved_attributes;
-
-#define UV_POLL_PRIVATE_FIELDS \
- SOCKET socket; \
- /* Used in fast mode */ \
- SOCKET peer_socket; \
- AFD_POLL_INFO afd_poll_info_1; \
- AFD_POLL_INFO afd_poll_info_2; \
- /* Used in fast and slow mode. */ \
- uv_req_t poll_req_1; \
- uv_req_t poll_req_2; \
- unsigned char submitted_events_1; \
- unsigned char submitted_events_2; \
- unsigned char mask_events_1; \
- unsigned char mask_events_2; \
+#define UV_TTY_PRIVATE_FIELDS \
+ HANDLE handle; \
+ union { \
+ struct { \
+ /* Used for readable TTY handles */ \
+ HANDLE read_line_handle; \
+ uv_buf_t read_line_buffer; \
+ HANDLE read_raw_wait; \
+ DWORD original_console_mode; \
+ /* Fields used for translating win keystrokes into vt100 characters */ \
+ char last_key[8]; \
+ unsigned char last_key_offset; \
+ unsigned char last_key_len; \
+ WCHAR last_utf16_high_surrogate; \
+ INPUT_RECORD last_input_record; \
+ }; \
+ struct { \
+ /* Used for writable TTY handles */ \
+ /* utf8-to-utf16 conversion state */ \
+ unsigned int utf8_codepoint; \
+ unsigned char utf8_bytes_left; \
+ /* eol conversion state */ \
+ unsigned char previous_eol; \
+ /* ansi parser state */ \
+ unsigned char ansi_parser_state; \
+ unsigned char ansi_csi_argc; \
+ unsigned short ansi_csi_argv[4]; \
+ COORD saved_position; \
+ WORD saved_attributes; \
+ }; \
+ };
+
+#define UV_POLL_PRIVATE_FIELDS \
+ SOCKET socket; \
+ /* Used in fast mode */ \
+ SOCKET peer_socket; \
+ AFD_POLL_INFO afd_poll_info_1; \
+ AFD_POLL_INFO afd_poll_info_2; \
+ /* Used in fast and slow mode. */ \
+ uv_req_t poll_req_1; \
+ uv_req_t poll_req_2; \
+ unsigned char submitted_events_1; \
+ unsigned char submitted_events_2; \
+ unsigned char mask_events_1; \
+ unsigned char mask_events_2; \
unsigned char events;
-#define UV_TIMER_PRIVATE_FIELDS \
- RB_ENTRY(uv_timer_s) tree_entry; \
- int64_t due; \
- int64_t repeat; \
+#define UV_TIMER_PRIVATE_FIELDS \
+ RB_ENTRY(uv_timer_s) tree_entry; \
+ uint64_t due; \
+ uint64_t repeat; \
+ uint64_t start_id; \
uv_timer_cb timer_cb;
-#define UV_ASYNC_PRIVATE_FIELDS \
- struct uv_req_s async_req; \
- uv_async_cb async_cb; \
- /* char to avoid alignment issues */ \
+#define UV_ASYNC_PRIVATE_FIELDS \
+ struct uv_req_s async_req; \
+ uv_async_cb async_cb; \
+ /* char to avoid alignment issues */ \
char volatile async_sent;
-#define UV_PREPARE_PRIVATE_FIELDS \
- uv_prepare_t* prepare_prev; \
- uv_prepare_t* prepare_next; \
+#define UV_PREPARE_PRIVATE_FIELDS \
+ uv_prepare_t* prepare_prev; \
+ uv_prepare_t* prepare_next; \
uv_prepare_cb prepare_cb;
-#define UV_CHECK_PRIVATE_FIELDS \
- uv_check_t* check_prev; \
- uv_check_t* check_next; \
+#define UV_CHECK_PRIVATE_FIELDS \
+ uv_check_t* check_prev; \
+ uv_check_t* check_next; \
uv_check_cb check_cb;
-#define UV_IDLE_PRIVATE_FIELDS \
- uv_idle_t* idle_prev; \
- uv_idle_t* idle_next; \
+#define UV_IDLE_PRIVATE_FIELDS \
+ uv_idle_t* idle_prev; \
+ uv_idle_t* idle_next; \
uv_idle_cb idle_cb;
-#define UV_HANDLE_PRIVATE_FIELDS \
- uv_handle_t* endgame_next; \
+#define UV_HANDLE_PRIVATE_FIELDS \
+ uv_handle_t* endgame_next; \
unsigned int flags;
-#define UV_GETADDRINFO_PRIVATE_FIELDS \
- uv_getaddrinfo_cb getaddrinfo_cb; \
- void* alloc; \
- wchar_t* node; \
- wchar_t* service; \
- struct addrinfoW* hints; \
- struct addrinfoW* res; \
+#define UV_GETADDRINFO_PRIVATE_FIELDS \
+ uv_getaddrinfo_cb getaddrinfo_cb; \
+ void* alloc; \
+ WCHAR* node; \
+ WCHAR* service; \
+ struct addrinfoW* hints; \
+ struct addrinfoW* res; \
int retcode;
-#define UV_PROCESS_PRIVATE_FIELDS \
- struct uv_process_exit_s { \
- UV_REQ_FIELDS \
- } exit_req; \
- struct uv_process_close_s { \
- UV_REQ_FIELDS \
- } close_req; \
- BYTE* child_stdio_buffer; \
- int exit_signal; \
- DWORD spawn_errno; \
- HANDLE wait_handle; \
- HANDLE process_handle; \
- HANDLE close_handle;
-
-#define UV_FS_PRIVATE_FIELDS \
- int flags; \
- DWORD sys_errno_; \
- union { \
- /* TODO: remove me in 0.9. */ \
- WCHAR* pathw; \
- int fd; \
- }; \
- union { \
- struct { \
- int mode; \
- WCHAR* new_pathw; \
- int file_flags; \
- int fd_out; \
- void* buf; \
- size_t length; \
- int64_t offset; \
- }; \
- struct _stati64 stat; \
- struct { \
- double atime; \
- double mtime; \
- }; \
+#define UV_PROCESS_PRIVATE_FIELDS \
+ struct uv_process_exit_s { \
+ UV_REQ_FIELDS \
+ } exit_req; \
+ BYTE* child_stdio_buffer; \
+ uv_err_t spawn_error; \
+ int exit_signal; \
+ HANDLE wait_handle; \
+ HANDLE process_handle; \
+ volatile char exit_cb_pending;
+
+#define UV_FS_PRIVATE_FIELDS \
+ int flags; \
+ DWORD sys_errno_; \
+ union { \
+ /* TODO: remove me in 0.9. */ \
+ WCHAR* pathw; \
+ int fd; \
+ }; \
+ union { \
+ struct { \
+ int mode; \
+ WCHAR* new_pathw; \
+ int file_flags; \
+ int fd_out; \
+ void* buf; \
+ size_t length; \
+ int64_t offset; \
+ }; \
+ struct { \
+ double atime; \
+ double mtime; \
+ }; \
};
-#define UV_WORK_PRIVATE_FIELDS \
-
-#define UV_FS_EVENT_PRIVATE_FIELDS \
- struct uv_fs_event_req_s { \
- UV_REQ_FIELDS \
- } req; \
- HANDLE dir_handle; \
- int req_pending; \
- uv_fs_event_cb cb; \
- wchar_t* filew; \
- wchar_t* short_filew; \
- wchar_t* dirw; \
+#define UV_WORK_PRIVATE_FIELDS \
+
+#define UV_FS_EVENT_PRIVATE_FIELDS \
+ struct uv_fs_event_req_s { \
+ UV_REQ_FIELDS \
+ } req; \
+ HANDLE dir_handle; \
+ int req_pending; \
+ uv_fs_event_cb cb; \
+ WCHAR* filew; \
+ WCHAR* short_filew; \
+ WCHAR* dirw; \
char* buffer;
-int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
+#define UV_SIGNAL_PRIVATE_FIELDS \
+ RB_ENTRY(uv_signal_s) tree_entry; \
+ struct uv_req_s signal_req; \
+ unsigned long pending_signum;
+
+int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size);
-int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
+int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
size_t utf16Size);
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index 49160b2bc..de375d4b0 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -19,7 +19,7 @@
* IN THE SOFTWARE.
*/
-/* See uv_loop_new for an introduction. */
+/* See http://nikhilm.github.com/uvbook/ for an introduction. */
#ifndef UV_H
#define UV_H
@@ -30,16 +30,14 @@ extern "C" {
#ifdef _WIN32
/* Windows - set up dll import/export decorators. */
# if defined(BUILDING_UV_SHARED)
- /* Building shared library. Export everything from c-ares as well. */
+ /* Building shared library. */
# define UV_EXTERN __declspec(dllexport)
-# define CARES_BUILDING_LIBRARY 1
# elif defined(USING_UV_SHARED)
- /* Using shared library. Use shared c-ares as well. */
+ /* Using shared library. */
# define UV_EXTERN __declspec(dllimport)
# else
- /* Building static library. Build c-ares statically as well. */
+ /* Building static library. */
# define UV_EXTERN /* nothing */
-# define CARES_STATICLIB 1
# endif
#elif __GNUC__ >= 4
# define UV_EXTERN __attribute__((visibility("default")))
@@ -49,80 +47,89 @@ extern "C" {
#define UV_VERSION_MAJOR 0
-#define UV_VERSION_MINOR 8
+#define UV_VERSION_MINOR 9
-#include <stdint.h> /* int64_t */
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
#include <sys/types.h> /* size_t */
-#include "ares.h"
+#if defined(__SVR4) && !defined(__unix__)
+# define __unix__
+#endif
-#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
+#if defined(__unix__) || defined(__POSIX__) || \
+ defined(__APPLE__) || defined(_AIX)
# include "uv-private/uv-unix.h"
#else
# include "uv-private/uv-win.h"
#endif
/* Expand this list if necessary. */
-#define UV_ERRNO_MAP(XX) \
- XX( -1, UNKNOWN, "unknown error") \
- XX( 0, OK, "success") \
- XX( 1, EOF, "end of file") \
- XX( 2, EADDRINFO, "getaddrinfo error") \
- XX( 3, EACCES, "permission denied") \
- XX( 4, EAGAIN, "no more processes") \
- XX( 5, EADDRINUSE, "address already in use") \
- XX( 6, EADDRNOTAVAIL, "") \
- XX( 7, EAFNOSUPPORT, "") \
- XX( 8, EALREADY, "") \
- XX( 9, EBADF, "bad file descriptor") \
- XX( 10, EBUSY, "resource busy or locked") \
- XX( 11, ECONNABORTED, "software caused connection abort") \
- XX( 12, ECONNREFUSED, "connection refused") \
- XX( 13, ECONNRESET, "connection reset by peer") \
- XX( 14, EDESTADDRREQ, "destination address required") \
- XX( 15, EFAULT, "bad address in system call argument") \
- XX( 16, EHOSTUNREACH, "host is unreachable") \
- XX( 17, EINTR, "interrupted system call") \
- XX( 18, EINVAL, "invalid argument") \
- XX( 19, EISCONN, "socket is already connected") \
- XX( 20, EMFILE, "too many open files") \
- XX( 21, EMSGSIZE, "message too long") \
- XX( 22, ENETDOWN, "network is down") \
- XX( 23, ENETUNREACH, "network is unreachable") \
- XX( 24, ENFILE, "file table overflow") \
- XX( 25, ENOBUFS, "no buffer space available") \
- XX( 26, ENOMEM, "not enough memory") \
- XX( 27, ENOTDIR, "not a directory") \
- XX( 28, EISDIR, "illegal operation on a directory") \
- XX( 29, ENONET, "machine is not on the network") \
- XX( 31, ENOTCONN, "socket is not connected") \
- XX( 32, ENOTSOCK, "socket operation on non-socket") \
- XX( 33, ENOTSUP, "operation not supported on socket") \
- XX( 34, ENOENT, "no such file or directory") \
- XX( 35, ENOSYS, "function not implemented") \
- XX( 36, EPIPE, "broken pipe") \
- XX( 37, EPROTO, "protocol error") \
- XX( 38, EPROTONOSUPPORT, "protocol not supported") \
- XX( 39, EPROTOTYPE, "protocol wrong type for socket") \
- XX( 40, ETIMEDOUT, "connection timed out") \
- XX( 41, ECHARSET, "") \
- XX( 42, EAIFAMNOSUPPORT, "") \
- XX( 44, EAISERVICE, "") \
- XX( 45, EAISOCKTYPE, "") \
- XX( 46, ESHUTDOWN, "") \
- XX( 47, EEXIST, "file already exists") \
- XX( 48, ESRCH, "no such process") \
- XX( 49, ENAMETOOLONG, "name too long") \
- XX( 50, EPERM, "operation not permitted") \
- XX( 51, ELOOP, "too many symbolic links encountered") \
- XX( 52, EXDEV, "cross-device link not permitted") \
- XX( 53, ENOTEMPTY, "directory not empty") \
- XX( 54, ENOSPC, "no space left on device") \
- XX( 55, EIO, "i/o error") \
- XX( 56, EROFS, "read-only file system") \
- XX( 57, ENODEV, "no such device") \
- XX( 58, ESPIPE, "invalid seek") \
+#define UV_ERRNO_MAP(XX) \
+ XX( -1, UNKNOWN, "unknown error") \
+ XX( 0, OK, "success") \
+ XX( 1, EOF, "end of file") \
+ XX( 2, EADDRINFO, "getaddrinfo error") \
+ XX( 3, EACCES, "permission denied") \
+ XX( 4, EAGAIN, "resource temporarily unavailable") \
+ XX( 5, EADDRINUSE, "address already in use") \
+ XX( 6, EADDRNOTAVAIL, "address not available") \
+ XX( 7, EAFNOSUPPORT, "address family not supported") \
+ XX( 8, EALREADY, "connection already in progress") \
+ XX( 9, EBADF, "bad file descriptor") \
+ XX( 10, EBUSY, "resource busy or locked") \
+ XX( 11, ECONNABORTED, "software caused connection abort") \
+ XX( 12, ECONNREFUSED, "connection refused") \
+ XX( 13, ECONNRESET, "connection reset by peer") \
+ XX( 14, EDESTADDRREQ, "destination address required") \
+ XX( 15, EFAULT, "bad address in system call argument") \
+ XX( 16, EHOSTUNREACH, "host is unreachable") \
+ XX( 17, EINTR, "interrupted system call") \
+ XX( 18, EINVAL, "invalid argument") \
+ XX( 19, EISCONN, "socket is already connected") \
+ XX( 20, EMFILE, "too many open files") \
+ XX( 21, EMSGSIZE, "message too long") \
+ XX( 22, ENETDOWN, "network is down") \
+ XX( 23, ENETUNREACH, "network is unreachable") \
+ XX( 24, ENFILE, "file table overflow") \
+ XX( 25, ENOBUFS, "no buffer space available") \
+ XX( 26, ENOMEM, "not enough memory") \
+ XX( 27, ENOTDIR, "not a directory") \
+ XX( 28, EISDIR, "illegal operation on a directory") \
+ XX( 29, ENONET, "machine is not on the network") \
+ XX( 31, ENOTCONN, "socket is not connected") \
+ XX( 32, ENOTSOCK, "socket operation on non-socket") \
+ XX( 33, ENOTSUP, "operation not supported on socket") \
+ XX( 34, ENOENT, "no such file or directory") \
+ XX( 35, ENOSYS, "function not implemented") \
+ XX( 36, EPIPE, "broken pipe") \
+ XX( 37, EPROTO, "protocol error") \
+ XX( 38, EPROTONOSUPPORT, "protocol not supported") \
+ XX( 39, EPROTOTYPE, "protocol wrong type for socket") \
+ XX( 40, ETIMEDOUT, "connection timed out") \
+ XX( 41, ECHARSET, "invalid Unicode character") \
+ XX( 42, EAIFAMNOSUPPORT, "address family for hostname not supported") \
+ XX( 44, EAISERVICE, "servname not supported for ai_socktype") \
+ XX( 45, EAISOCKTYPE, "ai_socktype not supported") \
+ XX( 46, ESHUTDOWN, "cannot send after transport endpoint shutdown") \
+ XX( 47, EEXIST, "file already exists") \
+ XX( 48, ESRCH, "no such process") \
+ XX( 49, ENAMETOOLONG, "name too long") \
+ XX( 50, EPERM, "operation not permitted") \
+ XX( 51, ELOOP, "too many symbolic links encountered") \
+ XX( 52, EXDEV, "cross-device link not permitted") \
+ XX( 53, ENOTEMPTY, "directory not empty") \
+ XX( 54, ENOSPC, "no space left on device") \
+ XX( 55, EIO, "i/o error") \
+ XX( 56, EROFS, "read-only file system") \
+ XX( 57, ENODEV, "no such device") \
+ XX( 58, ESPIPE, "invalid seek") \
+ XX( 59, ECANCELED, "operation canceled") \
#define UV_ERRNO_GEN(val, name, s) UV_##name = val,
@@ -132,36 +139,39 @@ typedef enum {
} uv_err_code;
#undef UV_ERRNO_GEN
-#define UV_HANDLE_TYPE_MAP(XX) \
- XX(ASYNC, async) \
- XX(CHECK, check) \
- XX(FS_EVENT, fs_event) \
- XX(FS_POLL, fs_poll) \
- XX(IDLE, idle) \
- XX(NAMED_PIPE, pipe) \
- XX(POLL, poll) \
- XX(PREPARE, prepare) \
- XX(PROCESS, process) \
- XX(TCP, tcp) \
- XX(TIMER, timer) \
- XX(TTY, tty) \
- XX(UDP, udp) \
-
-#define UV_REQ_TYPE_MAP(XX) \
- XX(CONNECT, connect) \
- XX(WRITE, write) \
- XX(SHUTDOWN, shutdown) \
- XX(UDP_SEND, udp_send) \
- XX(FS, fs) \
- XX(WORK, work) \
- XX(GETADDRINFO, getaddrinfo) \
+#define UV_HANDLE_TYPE_MAP(XX) \
+ XX(ASYNC, async) \
+ XX(CHECK, check) \
+ XX(FS_EVENT, fs_event) \
+ XX(FS_POLL, fs_poll) \
+ XX(HANDLE, handle) \
+ XX(IDLE, idle) \
+ XX(NAMED_PIPE, pipe) \
+ XX(POLL, poll) \
+ XX(PREPARE, prepare) \
+ XX(PROCESS, process) \
+ XX(STREAM, stream) \
+ XX(TCP, tcp) \
+ XX(TIMER, timer) \
+ XX(TTY, tty) \
+ XX(UDP, udp) \
+ XX(SIGNAL, signal) \
+
+#define UV_REQ_TYPE_MAP(XX) \
+ XX(REQ, req) \
+ XX(CONNECT, connect) \
+ XX(WRITE, write) \
+ XX(SHUTDOWN, shutdown) \
+ XX(UDP_SEND, udp_send) \
+ XX(FS, fs) \
+ XX(WORK, work) \
+ XX(GETADDRINFO, getaddrinfo) \
typedef enum {
UV_UNKNOWN_HANDLE = 0,
#define XX(uc, lc) UV_##uc,
UV_HANDLE_TYPE_MAP(XX)
#undef XX
- UV_ARES_TASK,
UV_FILE,
UV_HANDLE_TYPE_MAX
} uv_handle_type;
@@ -176,9 +186,8 @@ typedef enum {
} uv_req_type;
-
+/* Handle types. */
typedef struct uv_loop_s uv_loop_t;
-typedef struct uv_ares_task_s uv_ares_task_t;
typedef struct uv_err_s uv_err_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_stream_s uv_stream_t;
@@ -192,23 +201,32 @@ typedef struct uv_prepare_s uv_prepare_t;
typedef struct uv_check_s uv_check_t;
typedef struct uv_idle_s uv_idle_t;
typedef struct uv_async_s uv_async_t;
-typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
typedef struct uv_process_s uv_process_t;
-typedef struct uv_counters_s uv_counters_t;
-typedef struct uv_cpu_info_s uv_cpu_info_t;
-typedef struct uv_interface_address_s uv_interface_address_t;
-/* Request types */
+typedef struct uv_fs_event_s uv_fs_event_t;
+typedef struct uv_fs_poll_s uv_fs_poll_t;
+typedef struct uv_signal_s uv_signal_t;
+
+/* Request types. */
typedef struct uv_req_s uv_req_t;
+typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
typedef struct uv_shutdown_s uv_shutdown_t;
typedef struct uv_write_s uv_write_t;
typedef struct uv_connect_s uv_connect_t;
typedef struct uv_udp_send_s uv_udp_send_t;
typedef struct uv_fs_s uv_fs_t;
-/* uv_fs_event_t is a subclass of uv_handle_t. */
-typedef struct uv_fs_event_s uv_fs_event_t;
-typedef struct uv_fs_poll_s uv_fs_poll_t;
typedef struct uv_work_s uv_work_t;
+/* None of the above. */
+typedef struct uv_cpu_info_s uv_cpu_info_t;
+typedef struct uv_interface_address_s uv_interface_address_t;
+
+
+typedef enum {
+ UV_RUN_DEFAULT = 0,
+ UV_RUN_ONCE,
+ UV_RUN_NOWAIT
+} uv_run_mode;
+
/*
* This function must be called before any other functions in libuv.
@@ -227,18 +245,26 @@ UV_EXTERN void uv_loop_delete(uv_loop_t*);
UV_EXTERN uv_loop_t* uv_default_loop(void);
/*
- * This function starts the event loop. It blocks until the reference count
- * of the loop drops to zero. Always returns zero.
+ * This function runs the event loop. It will act differently depending on the
+ * specified mode:
+ * - UV_RUN_DEFAULT: Runs the event loop until the reference count drops to
+ * zero. Always returns zero.
+ * - UV_RUN_ONCE: Poll for new events once. Note that this function blocks if
+ * there are no pending events. Returns zero when done (no active handles
+ * or requests left), or non-zero if more events are expected (meaning you
+ * should run the event loop again sometime in the future).
+ * - UV_RUN_NOWAIT: Poll for new events once but don't block if there are no
+ * pending events.
*/
-UV_EXTERN int uv_run(uv_loop_t*);
+UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
/*
- * Poll for new events once. Note that this function blocks if there are no
- * pending events. Returns zero when done (no active handles or requests left),
- * or non-zero if more events are expected (meaning you should call
- * uv_run_once() again sometime in the future).
+ * This function will stop the event loop by forcing uv_run to end
+ * as soon as possible, but not sooner than the next loop iteration.
+ * If this function was called before blocking for i/o, the loop won't
+ * block for i/o on this iteration.
*/
-UV_EXTERN int uv_run_once(uv_loop_t*);
+UV_EXTERN void uv_stop(uv_loop_t*);
/*
* Manually modify the event loop's reference count. Useful if the user wants
@@ -248,7 +274,29 @@ UV_EXTERN void uv_ref(uv_handle_t*);
UV_EXTERN void uv_unref(uv_handle_t*);
UV_EXTERN void uv_update_time(uv_loop_t*);
-UV_EXTERN int64_t uv_now(uv_loop_t*);
+UV_EXTERN uint64_t uv_now(uv_loop_t*);
+
+/*
+ * Get backend file descriptor. Only kqueue, epoll and event ports are
+ * supported.
+ *
+ * This can be used in conjunction with uv_run_once() to poll in one thread and
+ * run the event loop's event callbacks in another.
+ *
+ * Useful for embedding libuv's event loop in another event loop.
+ * See test/test-embed.c for an example.
+ *
+ * Note that embedding a kqueue fd in another kqueue pollset doesn't work on
+ * all platforms. It's not an error to add the fd but it never generates
+ * events.
+ */
+UV_EXTERN int uv_backend_fd(const uv_loop_t*);
+
+/*
+ * Get the poll timeout. The return value is in milliseconds, or -1 for no
+ * timeout.
+ */
+UV_EXTERN int uv_backend_timeout(const uv_loop_t*);
/*
@@ -293,13 +341,14 @@ typedef void (*uv_async_cb)(uv_async_t* handle, int status);
typedef void (*uv_prepare_cb)(uv_prepare_t* handle, int status);
typedef void (*uv_check_cb)(uv_check_t* handle, int status);
typedef void (*uv_idle_cb)(uv_idle_t* handle, int status);
-typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* handle, int status,
- struct addrinfo* res);
typedef void (*uv_exit_cb)(uv_process_t*, int exit_status, int term_signal);
+typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg);
typedef void (*uv_fs_cb)(uv_fs_t* req);
typedef void (*uv_work_cb)(uv_work_t* req);
-typedef void (*uv_after_work_cb)(uv_work_t* req);
-typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg);
+typedef void (*uv_after_work_cb)(uv_work_t* req, int status);
+typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req,
+ int status,
+ struct addrinfo* res);
/*
* This will be called repeatedly after the uv_fs_event_t is initialized.
@@ -315,6 +364,9 @@ typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle,
const uv_statbuf_t* prev,
const uv_statbuf_t* curr);
+typedef void (*uv_signal_cb)(uv_signal_t* handle, int signum);
+
+
typedef enum {
UV_LEAVE_GROUP = 0,
UV_JOIN_GROUP
@@ -339,14 +391,14 @@ UV_EXTERN const char* uv_strerror(uv_err_t err);
UV_EXTERN const char* uv_err_name(uv_err_t err);
-#define UV_REQ_FIELDS \
- /* public */ \
- void* data; \
- /* private */ \
- ngx_queue_t active_queue; \
- UV_REQ_PRIVATE_FIELDS \
- /* read-only */ \
- uv_req_type type; \
+#define UV_REQ_FIELDS \
+ /* public */ \
+ void* data; \
+ /* read-only */ \
+ uv_req_type type; \
+ /* private */ \
+ ngx_queue_t active_queue; \
+ UV_REQ_PRIVATE_FIELDS \
/* Abstract base class of all requests. */
struct uv_req_s {
@@ -378,12 +430,11 @@ struct uv_shutdown_s {
#define UV_HANDLE_FIELDS \
- /* read-only */ \
- uv_loop_t* loop; \
/* public */ \
uv_close_cb close_cb; \
void* data; \
/* read-only */ \
+ uv_loop_t* loop; \
uv_handle_type type; \
/* private */ \
ngx_queue_t handle_queue; \
@@ -425,6 +476,10 @@ UV_EXTERN void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg);
* Note that handles that wrap file descriptors are closed immediately but
* close_cb will still be deferred to the next iteration of the event loop.
* It gives you a chance to free up any resources associated with the handle.
+ *
+ * In-progress requests, like uv_connect_t or uv_write_t, are cancelled and
+ * have their callbacks called asynchronously with status=-1 and the error code
+ * set to UV_ECANCELED.
*/
UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
@@ -453,13 +508,13 @@ UV_EXTERN size_t uv_strlcpy(char* dst, const char* src, size_t size);
UV_EXTERN size_t uv_strlcat(char* dst, const char* src, size_t size);
-#define UV_STREAM_FIELDS \
- /* number of bytes queued for writing */ \
- size_t write_queue_size; \
- uv_alloc_cb alloc_cb; \
- uv_read_cb read_cb; \
- uv_read2_cb read2_cb; \
- /* private */ \
+#define UV_STREAM_FIELDS \
+ /* number of bytes queued for writing */ \
+ size_t write_queue_size; \
+ uv_alloc_cb alloc_cb; \
+ uv_read_cb read_cb; \
+ uv_read2_cb read2_cb; \
+ /* private */ \
UV_STREAM_PRIVATE_FIELDS
/*
@@ -526,9 +581,12 @@ UV_EXTERN int uv_read2_start(uv_stream_t*, uv_alloc_cb alloc_cb,
* { .base = "4", .len = 1 }
* };
*
+ * uv_write_t req1;
+ * uv_write_t req2;
+ *
* // writes "1234"
- * uv_write(req, stream, a, 2);
- * uv_write(req, stream, b, 2);
+ * uv_write(&req1, stream, a, 2);
+ * uv_write(&req2, stream, b, 2);
*
*/
UV_EXTERN int uv_write(uv_write_t* req, uv_stream_t* handle,
@@ -584,15 +642,22 @@ struct uv_tcp_s {
UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
+/*
+ * Opens an existing file descriptor or SOCKET as a tcp handle.
+ */
+UV_EXTERN int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock);
+
/* Enable/disable Nagle's algorithm. */
UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
-/* Enable/disable TCP keep-alive.
+/*
+ * Enable/disable TCP keep-alive.
*
- * `ms` is the initial delay in seconds, ignored when `enable` is zero.
+ * `delay` is the initial delay in seconds, ignored when `enable` is zero.
*/
-UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle, int enable,
- unsigned int delay);
+UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle,
+ int enable,
+ unsigned int delay);
/*
* This setting applies to Windows only.
@@ -689,6 +754,11 @@ struct uv_udp_send_s {
UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
/*
+ * Opens an existing file descriptor or SOCKET as a udp handle.
+ */
+UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
+
+/*
* Bind to a IPv4 address and port.
*
* Arguments:
@@ -912,8 +982,8 @@ UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
struct uv_pipe_s {
UV_HANDLE_FIELDS
UV_STREAM_FIELDS
- UV_PIPE_PRIVATE_FIELDS
int ipc; /* non-zero if this pipe is used for passing handles */
+ UV_PIPE_PRIVATE_FIELDS
};
/*
@@ -925,7 +995,7 @@ UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc);
/*
* Opens an existing file descriptor or HANDLE as a pipe.
*/
-UV_EXTERN void uv_pipe_open(uv_pipe_t*, uv_file file);
+UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file);
UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
@@ -1011,9 +1081,8 @@ UV_EXTERN int uv_poll_stop(uv_poll_t* handle);
/*
* uv_prepare_t is a subclass of uv_handle_t.
*
- * libev wrapper. Every active prepare handle gets its callback called
- * exactly once per loop iteration, just before the system blocks to wait
- * for completed i/o.
+ * Every active prepare handle gets its callback called exactly once per loop
+ * iteration, just before the system blocks to wait for completed i/o.
*/
struct uv_prepare_s {
UV_HANDLE_FIELDS
@@ -1030,8 +1099,8 @@ UV_EXTERN int uv_prepare_stop(uv_prepare_t* prepare);
/*
* uv_check_t is a subclass of uv_handle_t.
*
- * libev wrapper. Every active check handle gets its callback called exactly
- * once per loop iteration, just after the system returns from blocking.
+ * Every active check handle gets its callback called exactly once per loop
+ * iteration, just after the system returns from blocking.
*/
struct uv_check_s {
UV_HANDLE_FIELDS
@@ -1048,10 +1117,10 @@ UV_EXTERN int uv_check_stop(uv_check_t* check);
/*
* uv_idle_t is a subclass of uv_handle_t.
*
- * libev wrapper. Every active idle handle gets its callback called
- * repeatedly until it is stopped. This happens after all other types of
- * callbacks are processed. When there are multiple "idle" handles active,
- * their callbacks are called in turn.
+ * Every active idle handle gets its callback called repeatedly until it is
+ * stopped. This happens after all other types of callbacks are processed.
+ * When there are multiple "idle" handles active, their callbacks are called
+ * in turn.
*/
struct uv_idle_s {
UV_HANDLE_FIELDS
@@ -1068,12 +1137,11 @@ UV_EXTERN int uv_idle_stop(uv_idle_t* idle);
/*
* uv_async_t is a subclass of uv_handle_t.
*
- * libev wrapper. uv_async_send wakes up the event
- * loop and calls the async handle's callback There is no guarantee that
- * every uv_async_send call leads to exactly one invocation of the callback;
- * The only guarantee is that the callback function is called at least once
- * after the call to async_send. Unlike all other libuv functions,
- * uv_async_send can be called from another thread.
+ * uv_async_send wakes up the event loop and calls the async handle's callback.
+ * There is no guarantee that every uv_async_send call leads to exactly one
+ * invocation of the callback; the only guarantee is that the callback function
+ * is called at least once after the call to async_send. Unlike all other
+ * libuv functions, uv_async_send can be called from another thread.
*/
struct uv_async_s {
UV_HANDLE_FIELDS
@@ -1101,7 +1169,7 @@ struct uv_timer_s {
UV_TIMER_PRIVATE_FIELDS
};
-UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* timer);
+UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* handle);
/*
* Start the timer. `timeout` and `repeat` are in milliseconds.
@@ -1110,24 +1178,20 @@ UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* timer);
*
* If repeat is non-zero, the callback fires first after timeout milliseconds
* and then repeatedly after repeat milliseconds.
- *
- * timeout and repeat are signed integers but that will change in a future
- * version of libuv. Don't pass in negative values, you'll get a nasty surprise
- * when that change becomes effective.
*/
-UV_EXTERN int uv_timer_start(uv_timer_t* timer,
+UV_EXTERN int uv_timer_start(uv_timer_t* handle,
uv_timer_cb cb,
- int64_t timeout,
- int64_t repeat);
+ uint64_t timeout,
+ uint64_t repeat);
-UV_EXTERN int uv_timer_stop(uv_timer_t* timer);
+UV_EXTERN int uv_timer_stop(uv_timer_t* handle);
/*
* Stop the timer, and if it is repeating restart it using the repeat value
* as the timeout. If the timer has never been started before it returns -1 and
* sets the error to UV_EINVAL.
*/
-UV_EXTERN int uv_timer_again(uv_timer_t* timer);
+UV_EXTERN int uv_timer_again(uv_timer_t* handle);
/*
* Set the repeat value in milliseconds. Note that if the repeat value is set
@@ -1135,17 +1199,9 @@ UV_EXTERN int uv_timer_again(uv_timer_t* timer);
* non-repeating before, it will have been stopped. If it was repeating, then
* the old repeat value will have been used to schedule the next timeout.
*/
-UV_EXTERN void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat);
-
-UV_EXTERN int64_t uv_timer_get_repeat(uv_timer_t* timer);
-
-
-/* c-ares integration initialize and terminate */
-UV_EXTERN int uv_ares_init_options(uv_loop_t*,
- ares_channel *channelptr, struct ares_options *options, int optmask);
+UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat);
-/* TODO remove the loop argument from this function? */
-UV_EXTERN void uv_ares_destroy(uv_loop_t*, ares_channel channel);
+UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle);
/*
@@ -1164,19 +1220,33 @@ struct uv_getaddrinfo_s {
/*
* Asynchronous getaddrinfo(3).
*
- * Return code 0 means that request is accepted and callback will be called
- * with result. Other return codes mean that there will not be a callback.
- * Input arguments may be released after return from this call.
+ * Either node or service may be NULL but not both.
*
- * uv_freeaddrinfo() must be called after completion to free the addrinfo
- * structure.
+ * hints is a pointer to a struct addrinfo with additional address type
+ * constraints, or NULL. Consult `man -s 3 getaddrinfo` for details.
*
- * On error NXDOMAIN the status code will be non-zero and UV_ENOENT returned.
+ * Returns 0 on success, -1 on error. Call uv_last_error() to get the error.
+ *
+ * If successful, your callback gets called sometime in the future with the
+ * lookup result, which is either:
+ *
+ * a) status == 0, the res argument points to a valid struct addrinfo, or
+ * b) status == -1, the res argument is NULL.
+ *
+ * On NXDOMAIN, the status code is -1 and uv_last_error() returns UV_ENOENT.
+ *
+ * Call uv_freeaddrinfo() to free the addrinfo structure.
*/
-UV_EXTERN int uv_getaddrinfo(uv_loop_t*, uv_getaddrinfo_t* handle,
- uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service,
- const struct addrinfo* hints);
+UV_EXTERN int uv_getaddrinfo(uv_loop_t* loop,
+ uv_getaddrinfo_t* req,
+ uv_getaddrinfo_cb getaddrinfo_cb,
+ const char* node,
+ const char* service,
+ const struct addrinfo* hints);
+/*
+ * Free the struct addrinfo. Passing NULL is allowed and is a no-op.
+ */
UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai);
/* uv_spawn() options */
@@ -1229,14 +1299,6 @@ typedef struct uv_process_options_s {
*/
unsigned int flags;
/*
- * Libuv can change the child process' user/group id. This happens only when
- * the appropriate bits are set in the flags fields. This is not supported on
- * windows; uv_spawn() will fail and set the error to UV_ENOTSUP.
- */
- uv_uid_t uid;
- uv_gid_t gid;
-
- /*
* The `stdio` field points to an array of uv_stdio_container_t structs that
* describe the file descriptors that will be made available to the child
* process. The convention is that stdio[0] points to stdin, fd 1 is used for
@@ -1247,6 +1309,13 @@ typedef struct uv_process_options_s {
*/
int stdio_count;
uv_stdio_container_t* stdio;
+ /*
+ * Libuv can change the child process' user/group id. This happens only when
+ * the appropriate bits are set in the flags fields. This is not supported on
+ * windows; uv_spawn() will fail and set the error to UV_ENOTSUP.
+ */
+ uv_uid_t uid;
+ uv_gid_t gid;
} uv_process_options_t;
/*
@@ -1278,7 +1347,13 @@ enum uv_process_flags {
* parent's event loop alive unless the parent process calls uv_unref() on
* the child's process handle.
*/
- UV_PROCESS_DETACHED = (1 << 3)
+ UV_PROCESS_DETACHED = (1 << 3),
+ /*
+ * Hide the subprocess console window that would normally be created. This
+ * option is only meaningful on Windows systems. On unix it is silently
+ * ignored.
+ */
+ UV_PROCESS_WINDOWS_HIDE = (1 << 4)
};
/*
@@ -1322,6 +1397,30 @@ struct uv_work_s {
UV_EXTERN int uv_queue_work(uv_loop_t* loop, uv_work_t* req,
uv_work_cb work_cb, uv_after_work_cb after_work_cb);
+/* Cancel a pending request. Fails if the request is executing or has finished
+ * executing.
+ *
+ * Returns 0 on success, -1 on error. The loop error code is not touched.
+ *
+ * Only cancellation of uv_fs_t, uv_getaddrinfo_t and uv_work_t requests is
+ * currently supported.
+ *
+ * Cancelled requests have their callbacks invoked some time in the future.
+ * It's _not_ safe to free the memory associated with the request until your
+ * callback is called.
+ *
+ * Here is how cancellation is reported to your callback:
+ *
+ * - A uv_fs_t request has its req->errorno field set to UV_ECANCELED.
+ *
+ * - A uv_work_t or uv_getaddrinfo_t request has its callback invoked with
+ * status == -1 and uv_last_error(loop).code == UV_ECANCELED.
+ *
+ * This function is currently only implemented on UNIX platforms. On Windows,
+ * it always returns -1.
+ */
+UV_EXTERN int uv_cancel(uv_req_t* req);
+
struct uv_cpu_info_s {
char* model;
@@ -1420,6 +1519,7 @@ struct uv_fs_s {
void* ptr;
const char* path;
uv_err_code errorno;
+ uv_statbuf_t statbuf; /* Stores the result of uv_fs_stat and uv_fs_fstat. */
UV_FS_PRIVATE_FIELDS
};
@@ -1533,16 +1633,6 @@ struct uv_fs_poll_s {
UV_HANDLE_FIELDS
/* Private, don't touch. */
void* poll_ctx;
- /* v0.8 ABI compatibility */
- char padding[sizeof(int)
- + sizeof(unsigned int)
- + sizeof(uint64_t)
- + sizeof(char*)
- + sizeof(uv_fs_poll_cb)
- + sizeof(uv_timer_t)
- + sizeof(uv_fs_t*)
- + sizeof(uv_statbuf_t)
- - sizeof(void*)];
};
UV_EXTERN int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle);
@@ -1569,6 +1659,58 @@ UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle,
UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
+
+/*
+ * UNIX signal handling on a per-event loop basis. The implementation is not
+ * ultra efficient so don't go creating a million event loops with a million
+ * signal watchers.
+ *
+ * Note to Linux users: SIGRT0 and SIGRT1 (signals 32 and 33) are used by the
+ * NPTL pthreads library to manage threads. Installing watchers for those
+ * signals will lead to unpredictable behavior and is strongly discouraged.
+ * Future versions of libuv may simply reject them.
+ *
+ * Some signal support is available on Windows:
+ *
+ * SIGINT is normally delivered when the user presses CTRL+C. However, like
+ * on Unix, it is not generated when terminal raw mode is enabled.
+ *
+ * SIGBREAK is delivered when the user pressed CTRL+BREAK.
+ *
+ * SIGHUP is generated when the user closes the console window. On SIGHUP the
+ * program is given approximately 10 seconds to perform cleanup. After that
+ * Windows will unconditionally terminate it.
+ *
+ * SIGWINCH is raised whenever libuv detects that the console has been
+ * resized. SIGWINCH is emulated by libuv when the program uses an uv_tty_t
+ * handle to write to the console. SIGWINCH may not always be delivered in a
+ * timely manner; libuv will only detect size changes when the cursor is
+ * being moved. When a readable uv_tty_handle is used in raw mode, resizing
+ * the console buffer will also trigger a SIGWINCH signal.
+ *
+ * Watchers for other signals can be successfully created, but these signals
+ * are never generated. These signals are: SIGILL, SIGABRT, SIGFPE, SIGSEGV,
+ * SIGTERM and SIGKILL.
+ *
+ * Note that calls to raise() or abort() to programmatically raise a signal are
+ * not detected by libuv; these will not trigger a signal watcher.
+ */
+struct uv_signal_s {
+ UV_HANDLE_FIELDS
+ uv_signal_cb signal_cb;
+ int signum;
+ UV_SIGNAL_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle);
+
+UV_EXTERN int uv_signal_start(uv_signal_t* handle,
+ uv_signal_cb signal_cb,
+ int signum);
+
+UV_EXTERN int uv_signal_stop(uv_signal_t* handle);
+
+
/*
* Gets load avg
* See: http://en.wikipedia.org/wiki/Load_(computing)
@@ -1597,7 +1739,14 @@ enum uv_fs_event_flags {
* regular interval.
* This flag is currently not implemented yet on any backend.
*/
- UV_FS_EVENT_STAT = 2
+ UV_FS_EVENT_STAT = 2,
+
+ /*
+ * By default, event watcher, when watching directory, is not registering
+ * (is ignoring) changes in it's subdirectories.
+ * This flag will override this behaviour on platforms that support it.
+ */
+ UV_FS_EVENT_RECURSIVE = 3
};
@@ -1614,6 +1763,12 @@ UV_EXTERN struct sockaddr_in6 uv_ip6_addr(const char* ip, int port);
UV_EXTERN int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size);
UV_EXTERN int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size);
+/* Cross-platform IPv6-capable implementation of the 'standard' inet_ntop */
+/* and inet_pton functions. On success they return UV_OK. If an error */
+/* the target of the `dst` pointer is unmodified. */
+UV_EXTERN uv_err_t uv_inet_ntop(int af, const void* src, char* dst, size_t size);
+UV_EXTERN uv_err_t uv_inet_pton(int af, const char* src, void* dst);
+
/* Gets the executable path */
UV_EXTERN int uv_exepath(char* buffer, size_t* size);
@@ -1642,7 +1797,7 @@ UV_EXTERN extern uint64_t uv_hrtime(void);
/*
* Disables inheritance for file descriptors / handles that this process
* inherited from its parent. The effect is that child processes spawned by
- * this proces don't accidently inherit these handles.
+ * this process don't accidentally inherit these handles.
*
* It is recommended to call this function as early in your program as possible,
* before the inherited file descriptors can be closed or duplicated.
@@ -1662,7 +1817,7 @@ UV_EXTERN void uv_disable_stdio_inheritance(void);
UV_EXTERN int uv_dlopen(const char* filename, uv_lib_t* lib);
/*
- * Close the shared libary.
+ * Close the shared library.
*/
UV_EXTERN void uv_dlclose(uv_lib_t* lib);
@@ -1708,6 +1863,34 @@ UV_EXTERN void uv_sem_post(uv_sem_t* sem);
UV_EXTERN void uv_sem_wait(uv_sem_t* sem);
UV_EXTERN int uv_sem_trywait(uv_sem_t* sem);
+/*
+ * Same goes for the condition variable functions.
+ */
+UV_EXTERN int uv_cond_init(uv_cond_t* cond);
+UV_EXTERN void uv_cond_destroy(uv_cond_t* cond);
+UV_EXTERN void uv_cond_signal(uv_cond_t* cond);
+UV_EXTERN void uv_cond_broadcast(uv_cond_t* cond);
+/* Waits on a condition variable without a timeout.
+ *
+ * Note:
+ * 1. callers should be prepared to deal with spurious wakeups.
+ */
+UV_EXTERN void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex);
+/* Waits on a condition variable with a timeout in nano seconds.
+ * Returns 0 for success or -1 on timeout, * aborts when other errors happen.
+ *
+ * Note:
+ * 1. callers should be prepared to deal with spurious wakeups.
+ * 2. the granularity of timeout on Windows is never less than one millisecond.
+ * 3. uv_cond_timedwait takes a relative timeout, not an absolute time.
+ */
+UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex,
+ uint64_t timeout);
+
+UV_EXTERN int uv_barrier_init(uv_barrier_t* barrier, unsigned int count);
+UV_EXTERN void uv_barrier_destroy(uv_barrier_t* barrier);
+UV_EXTERN void uv_barrier_wait(uv_barrier_t* barrier);
+
/* Runs a function once and only once. Concurrent calls to uv_once() with the
* same guard will block all callers except one (it's unspecified which one).
* The guard should be initialized statically with the UV_ONCE_INIT macro.
@@ -1716,10 +1899,13 @@ UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void));
UV_EXTERN int uv_thread_create(uv_thread_t *tid,
void (*entry)(void *arg), void *arg);
+UV_EXTERN unsigned long uv_thread_self(void);
UV_EXTERN int uv_thread_join(uv_thread_t *tid);
/* the presence of these unions force similar struct layout */
union uv_any_handle {
+ uv_handle_t handle;
+ uv_stream_t stream;
uv_tcp_t tcp;
uv_pipe_t pipe;
uv_prepare_t prepare;
@@ -1727,8 +1913,12 @@ union uv_any_handle {
uv_idle_t idle;
uv_async_t async;
uv_timer_t timer;
- uv_getaddrinfo_t getaddrinfo;
uv_fs_event_t fs_event;
+ uv_fs_poll_t fs_poll;
+ uv_poll_t poll;
+ uv_process_t process;
+ uv_tty_t tty;
+ uv_udp_t udp;
};
union uv_any_req {
@@ -1738,49 +1928,23 @@ union uv_any_req {
uv_shutdown_t shutdown;
uv_fs_t fs_req;
uv_work_t work_req;
-};
-
-
-struct uv_counters_s {
- uint64_t async_init;
- uint64_t check_init;
- uint64_t eio_init;
- uint64_t fs_event_init;
- uint64_t fs_poll_init;
- uint64_t handle_init;
- uint64_t idle_init;
- uint64_t pipe_init;
- uint64_t poll_init;
- uint64_t prepare_init;
- uint64_t process_init;
- uint64_t req_init;
- uint64_t stream_init;
- uint64_t tcp_init;
- uint64_t timer_init;
- uint64_t tty_init;
- uint64_t udp_init;
+ uv_udp_send_t udp_send_req;
+ uv_getaddrinfo_t getaddrinfo_req;
};
struct uv_loop_s {
- UV_LOOP_PRIVATE_FIELDS
- ares_channel channel;
- /* While the channel is active this timer is called once per second to be */
- /* sure that we're always calling ares_process. See the warning above the */
- /* definition of ares_timeout(). */
- uv_timer_t ares_timer; \
- /* RB_HEAD(uv__ares_tasks, uv_ares_task_t) */
- struct uv__ares_tasks { uv_ares_task_t* rbh_root; } ares_handles;
- /* Diagnostic counters */
- uv_counters_t counters;
+ /* User data - use this for whatever. */
+ void* data;
/* The last error */
uv_err_t last_err;
/* Loop reference counting */
unsigned int active_handles;
ngx_queue_t handle_queue;
ngx_queue_t active_reqs;
- /* User data - use this for whatever. */
- void* data;
+ /* Internal flag to signal loop stop */
+ unsigned int stop_flag;
+ UV_LOOP_PRIVATE_FIELDS
};
@@ -1799,6 +1963,7 @@ struct uv_loop_s {
#undef UV_FS_REQ_PRIVATE_FIELDS
#undef UV_WORK_PRIVATE_FIELDS
#undef UV_FS_EVENT_PRIVATE_FIELDS
+#undef UV_SIGNAL_PRIVATE_FIELDS
#undef UV_LOOP_PRIVATE_FIELDS
#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS
diff --git a/deps/uv/src/ares/CHANGES b/deps/uv/src/ares/CHANGES
deleted file mode 100644
index 73fe8c771..000000000
--- a/deps/uv/src/ares/CHANGES
+++ /dev/null
@@ -1,1218 +0,0 @@
- Changelog for the c-ares project
-
-Version 1.7.5 (August 16, 2011)
-
-Fixed:
-
- o detection of semicolon comments in resolv.conf
- o avoid using system's inet_net_pton affected by the WLB-2008080064 advisory
- o replacement ares_inet_net_pton affected by the WLB-2008080064 advisory
- o replacement ares_inet_ntop affected by potential out of bounds write
- o added install target to Makefile.msvc
- o only fall back to AF_INET searches when looking for AF_UNSPEC addresses
- o fixed ares_parse_*_reply memory leaks
- o Use correct sizeof in ares_getnameinfo()
- o IPv6-on-windows: find DNS servers correctly
- o man pages: docs for the c-ares utility programs
- o getservbyport replacement for Win CE
- o config_sortlist: (win32) missing else
- o advance_tcp_send_queue: avoid NULL ptr dereference
- o configure: fix a bashism
- o ares_expand_name: Fix encoded length for indirect root
-
-Version 1.7.4 (December 9, 2010)
-
-Changed:
-
- o local-bind: Support binding to local interface/IPs, see
- ares_set_local_ip4, ares_set_local_ip6, ares_set_local_dev
-
-Fixed:
-
- o memory leak in ares_getnameinfo
- o add missing break that caused get_ares_servers to fail
- o ares_parse_a_reply: fix CNAME response parsing
- o init_by_options: don't copy an empty sortlist
- o Replaced uint32_t with unsigned int to fix broken builds
- on a couple of platforms
- o Fix lookup with HOSTALIASES set
- o adig: fix NAPTR parsing
- o compiler warning cleanups
-
-Version 1.7.3 (June 11, 2010)
-
-Fixed:
-
- o builds on Android
- o now includes all files necessary to build it (1.7.2 lacked a file)
-
-Version 1.7.2 (June 10, 2010)
-
-Changed:
-
- o Added ares_parse_mx_reply()
-
-Fixed:
-
- o ares_init: Last, not first instance of domain or search should win
- o improve alternative definition of bool
- o fix VS2010 compiler warnings
-
-
-Version 1.7.1 (Mar 23, 2010)
-
-* May 31, 2010 (Jakub Hrozek)
-- Use the last instance of domain/search, not the first one
-
-* March 23, 2010 (Daniel Stenberg)
-- We switched from CVS to git. See http://github.com/bagder/c-ares
-
-* March 5, 2010 (Daniel Stenberg)
-- Daniel Johnson provided fixes for building with the clang compiler.
-
-* March 5, 2010 (Yang Tse)
-- Added IPv6 name servers support. Implementation has been based on code,
- comments and feedback provided November and December of 2008 by Daniel
- Stenberg, Gregor Jasny, Phil Blundell and myself, December 2009 by Cedric
- Bail, and February 2010 by Jakub Hrozek on the c-ares mailing list. On
- March I reviewed all that, selected the best of each, and adjusted or
- extended parts of it to make the best fit.
-
- The external and visible result of all this is that two new functions are
- added to the external API, ares_get_servers() and ares_set_servers(), which
- becomes now the preferred way of getting and setting name servers for any
- ares channel as these support both IPv4 and IPv6 name servers.
-
- In order to not break ABI compatibility, ares_init_options() with option
- mask ARES_OPT_SERVERS and ares_save_options() may still be used in code
- which is intended to run on IPv4-only stacks. But remember that these
- functions do not support IPv6 name servers. This implies that if the user
- is capable of defining or providing an IPv6 name server, and the app is
- using ares_init_options() or ares_save_options() at some point to handle
- the name servers, the app will likely lose IPv6 name servers.
-
-* January 28, 2010 (Daniel Stenberg)
-- Tommie Gannert pointed out a silly bug in ares_process_fd() since it didn't
- check for broken connections like ares_process() did. Based on that, I
- merged the two functions into a single generic one with two front-ends.
-
-* December 29, 2009 (Yang Tse)
-- Laszlo Tamas Szabo adjusted Makefile.msvc compiler options so that where
- run-time error checks enabling compiler option /GZ was used it is replaced
- with equivalent /RTCsu for Visual Studio 2003 and newer versions. Option
- /GX is replaced with equivalent /EHsc for all versions. Also fixed socket
- data type for internal configure_socket function.
-
-* December 21, 2009 (Yang Tse)
-- Ingmar Runge noticed that Windows config-win32.h configuration file
- did not include a definition for HAVE_CLOSESOCKET which resulted in
- function close() being inappropriately used to close sockets.
-
-Version 1.7.0 (Nov 30, 2009)
-
-* November 26, 2009 (Yang Tse)
-- Larry Lansing fixed ares_parse_srv_reply to properly parse replies
- which might contain non-SRV answers, skipping over potential non-SRV
- ones such as CNAMEs.
-
-* November 23, 2009 (Yang Tse)
-- Changed naming convention for c-ares libraries built with MSVC, details
- and build instructions provided in README.msvc file.
-
-* November 22, 2009 (Yang Tse)
-- Jakub Hrozek fixed more function prototypes in man pages to sync them
- with the ones declared in ares.h
-
-- Jakub Hrozek renamed addrttl and addr6ttl structs to ares_addrttl and
- ares_addr6ttl in order to prevent name space pollution, along with
- necessary changes to code base and man pages.This change does not break
- ABI, there is no need to recompile existing applications. But existing
- applications using these structs with the old name will need source code
- adjustments when recompiled using c-ares 1.7.0.
-
-* November 21, 2009 (Yang Tse)
-- Added manifest stuff to Makefile.msvc.
-
-* November 20, 2009 (Yang Tse)
-- Fixed several function prototypes in man pages that were out of sync
- with the ones declared in ares.h. Added ares_free_data() along with
- man page. Updated ares_parse_srv_reply() and ares_parse_txt_reply()
- with changes from Jakub Hrozek making these now return linked lists
- instead of arrays, and merging the ares_free_data() adjustments.
-
-* November 10, 2009 (Yang Tse)
-- Updated MSVC 6.0 project files to match settings from Makefile.msvc.
-
-* November 9, 2009 (Yang Tse)
-- Makefile.msvc is now the reference method to build c-ares and sample
- programs with any MSVC compiler or MS Visual Studio version. If no
- option or target are specified it builds dynamic and static c-ares
- libraries in debug and release flavours and also builds all sample
- programs using each of the different c-ares libraries.
-
-* November 2, 2009 (Yang Tse)
-- Renamed c-ares setup.h to ares_setup.h
-
-* October 31, 2009 (Yang Tse)
-- Symbol hiding configure options are named now --enable-symbol-hiding
- and --disable-symbol-hiding in an attempt to make them less ambiguous.
-
-* October 30, 2009 (Yang Tse)
-- Many fixes for ares_parse_txt_reply()
-
-* October 29, 2009 (Daniel Stenberg)
-- Jakub Hrozek added ares_parse_txt_reply() for TXT parsing
-
-* October 29, 2009 (Yang Tse)
-- Updated MSVC 6.0 workspace and project files that allows building
- dynamic and static c-ares libraries in debug and release flavours.
- Additionally each of the three sample programs is built against
- each of the four possible c-ares libraries, generating all this
- a total number of 12 executables and 4 libraries.
-
-* October 28, 2009 (Yang Tse)
-- Initial step towards the ability to reduce c-ares exported symbols
- when built as a shared library based on the 'visibility' attribute
- for GNUC and Intel compilers and based on __global for Sun compilers,
- taking also in account __declspec function decoration for Win32 and
- Symbian DLL's.
-
-* October 27, 2009 (Yang Tse)
-- Fixed Pelles C Win32 target compilation issues.
-
-* October 23, 2009 (Yang Tse)
-- John Engelhart noticed an unreleased problem relative to a duplicate
- ARES_ECANCELLED error code value and missing error code description.
-
-* October 7, 2009 (Yang Tse)
-- Overhauled ares__get_hostent() Fixing out of bounds memory overwrite
- triggered with malformed /etc/hosts file. Improving parsing of /etc/hosts
- file. Validating requested address family. Ensuring that failures always
- return a NULL pointer. Adjusting header inclusions.
-
-* October 6, 2009 (Yang Tse)
-- Fix ssize_t redefinition errors on WIN64 reported by Alexey Simak.
-
-* September 29, 2009 (Yang Tse)
-- Make configure script also check if _REENTRANT definition is required to
- make errno available as a preprocessor macro.
-
-* September 7, 2009 (Yang Tse)
-- Add T_SRV portability check to ares_parse_srv_reply.c
-
-* 4 Sep 2009 (Daniel Stenberg)
-- Jakub Hrozek added ares_parse_srv_reply() for SRV parsing
-
-* 3 Aug 2009 (Daniel Stenberg)
-- Joshua Kwan fixed the init routine to fill in the defaults for stuff that
- fails to get inited by other means. This fixes a case of when the c-ares
- init fails when internet access is fone.
-
-- Timo Teras changed the reason code used in the resolve callback done when
- ares_cancel() is used, to be ARES_ECANCELLED instead of ARES_ETIMEOUT to
- better allow the callback to know what's happening.
-
-* 14 Jul 2009 (Guenter Knauf)
-- renamed generated config.h to ares_config.h to avoid any future clashes
- with config.h from other projects.
-
-* June 20 2009 (Yang Tse)
-- Refactor how libraries are checked for connect() function in configure
- script and check for connect() as it is done for other functions.
-
-* June 19 2009 (Yang Tse)
-- Make sclose() function-like macro definition used to close a socket,
- now solely based on HAVE_CLOSESOCKET and HAVE_CLOSESOCKET_CAMEL
- config file preprocessor definitions
-
-* June 18 2009 (Yang Tse)
-- Add CloseSocket camel case function check for configure script.
-
-* June 17 2009 (Yang Tse)
-- Check for socket() and closesocket() as it is done for other functions
- in configure script.
-
-* June 11 2009 (Yang Tse)
-- Modified buildconf so that when automake runs it copies missing files
- instead of symlinking them.
-
-* June 8 2009 (Yang Tse)
-- Removed buildconf.bat from release and daily snapshot archives. This
- file is only for CVS tree checkout builds.
-
-* May 26 2009 (Yang Tse)
-- Added --enable-curldebug configure option to enable and disable building
- with the low-level curl debug memory tracking 'feature' to allow decoupled
- setting from --enable-debug, allowing again to build c-ares independently
- out of the CVS tree.
-
- For the c-ares library option --enable-debug enables debug build features
- which are _not_ related with memory tracking. For the c-ares library when
- --enable-debug is given it does not enable the memory tracking feature. If
- you wish to enable the curl debug memory tracking you must use configure
- option --enable-curldebug explicitily to do so.
-
- Internally, definition of preprocessor symbol DEBUGBUILD restricts code
- which is only compiled for debug enabled builds. And symbol CURLDEBUG is
- used to differentiate code which is _only_ used for memory tracking.
-
- Make ares_init(), ares_dup() and ares_init_options() fail returning
- ARES_ENOTINITIALIZED if library initialization has not been performed
- calling ares_library_init().
-
-* May 20 2009 (Yang Tse)
-- Added ares_library_init() and ares_library_cleanup() man pages.
-
-* May 19 2009 (Yang Tse)
-- Introduced ares_library_init() and ares_library_cleanup() functions.
-
- This is an API and ABI break for Win32/64 systems. Non-Win32/64 build targets
- using c-ares 1.7.0 can still survive without calling these functions. Read all
- the details on ares_library_init(3) and ares_library_cleanup(3) man pages that
- are included.
-
- curl/libcurl 7.19.5 is fully compatible with c-ares 1.7.0 on all systems.
-
- In order to use c-ares 1.7.0 with curl/libcurl on Win32/64 systems it is
- required that curl/libcurl is 7.19.5 or newer. In other words, it is not
- possible on Win32/64 to use c-ares 1.7.0 with a curl/libcurl version less
- than 7.19.5
-
-* May 11 2009 (Daniel Stenberg)
-- Gregor Jasny made c-ares link with libtool 's -export-symbols-regex option to
- only expose functions starting with ares_.
-
-* May 7 2009 (Yang Tse)
-- Fix an m4 overquoting triggering a spurious 'AS_TR_CPP' symbol definition
- attempt in generated config.h
-
-* May 2 2009 (Yang Tse)
-- Use a build-time configured ares_socklen_t data type instead of socklen_t.
-
-* April 21 2009 (Yang Tse)
-- Moved potential inclusion of system's malloc.h and memory.h header files to
- setup_once.h. Inclusion of each header file is based on the definition of
- NEED_MALLOC_H and NEED_MEMORY_H respectively.
-
-* March 11 2009 (Yang Tse)
-- Japheth Cleaver fixed acountry.c replacing u_long with unsigned long.
-
-* February 20 2009 (Yang Tse)
-- Do not halt compilation when using VS2008 to build a Windows 2000 target.
-
-* February 3 2009 (Phil Blundell)
-- If the server returns garbage or nothing at all in response to an AAAA query,
- go on and ask for A records anyway.
-
-* January 31 2009 (Daniel Stenberg)
-- ares_gethostbyname() now accepts 'AF_UNSPEC' as a family for resolving
- either AF_INET6 or AF_INET. It works by accepting any of the looksups in the
- hosts file, and it resolves the AAAA field with a fallback to A.
-
-* January 14 2009 (Daniel Stenberg)
-- ares.h no longer uses the HAVE_STRUCT_IN6_ADDR define check, but instead it
- now declares the private struct ares_in6_addr for all systems instead of
- relying on one possibly not present in the system.
-
-* January 13 2009 (Phil Blundell)
-- ares__send_query() now varies the retry timeout pseudo-randomly to avoid
- packet storms when several queries were started at the same time.
-
-* January 11 2009 (Daniel Stenberg)
-- Phil Blundell added the internal function ares__expand_name_for_response()
- that is now used by the ares_parse_*_reply() functions instead of the
- ares_expand_name() simply to easier return ARES_EBADRESP for the cases where
- the name expansion fails as in responses that really isn't expected.
-
-Version 1.6.0 (Dec 9, 2008)
-
-* December 9 2008 (Gisle Vanem)
-
- Fixes for Win32 targets using the Watt-32 tcp/ip stack.
-
-* Dec 4 2008 (Daniel Stenberg)
-
- Gregor Jasny provided the patch that introduces ares_set_socket_callback(),
- and I edited it to also get duped by ares_dup().
-
-* Dec 3 2008 (Daniel Stenberg)
-
- API changes:
-
- I made sure the public ares_config struct looks like before and yet it
- supports the ROTATE option thanks to c-ares now storing the "optmask"
- internally. Thus we should be ABI compatible with the past release(s)
- now. My efforts mentioned below should not break backwards ABI compliance.
-
- Here's how I suggest we proceed with the API:
-
- ares_init() will be primary "channel creator" function.
-
- ares_init_options() will continue to work exactly like now and before. For
- starters, it will be the (only) way to set the existing options.
-
- ares_save_options() will continue to work like today, but will ONLY save
- options that you can set today (including ARES_OPT_ROTATE actually) but new
- options that we add may not be saved with this.
-
- Instead we introduce:
-
- ares_dup() that instead can make a new channel and clone the config used
- from an existing channel. It will then clone all config options, including
- future new things we add.
-
- ares_set_*() style functions that set (new) config options. As a start we
- simply add these for new functionality, but over time we can also introduce
- them for existing "struct ares_options" so that we can eventually deprecate
- the two ares_*_options() functions.
-
- ares_get_*() style functions for extracting info from a channel handle that
- should be used instead of ares_save_options().
-
-* Nov 26 2008 (Yang Tse)
-- Brad Spencer provided changes to allow buildconf to work on OS X.
-
-- Gerald Combs fixed a bug in ares_parse_ptr_reply() which would cause a
- buffer to shrink instead of expand if a reply contained 8 or more records.
-
-* Nov 25 2008 (Yang Tse)
-- In preparation for the upcomming IPv6 nameservers patch, the internal
- ares_addr union is now changed into an internal struct which also holds
- the address family.
-
-* Nov 19 2008 (Daniel Stenberg)
-- Brad Spencer brought the new function ares_gethostbyname_file() which simply
- resolves a host name from the given file, using the regular hosts syntax.
-
-* Nov 1 2008 (Daniel Stenberg)
-- Carlo Contavalli added support for the glibc "rotate" option, as documented
- in man resolv.conf:
-
- causes round robin selection of nameservers from among those listed. This
- has the effect of spreading the query load among all listed servers, rather
- than having all clients try the first listed server first every time.
-
- You can enable it with ARES_OPT_ROTATE
-
-* Oct 21 2008 (Yang Tse)
- Charles Hardin added handling of EINPROGRESS for UDP connects.
-
-* Oct 18 2008 (Daniel Stenberg)
- Charles Hardin made adig support a regular numerical dotted IP address for the
- -s option as well.
-
-* Oct 7 2008 (Yang Tse)
-- Added --enable-optimize configure option to enable and disable compiler
- optimizations to allow decoupled setting from --enable-debug.
-
-* Oct 2 2008 (Yang Tse)
-- Added --enable-warnings configure option to enable and disable strict
- compiler warnings to allow decoupled setting from --enable-debug.
-
-* Sep 17 2008 (Yang Tse)
-- Code reorganization to allow internal/private use of "nameser.h" to any
- system that lacks arpa/nameser.h or arpa/nameser_compat.h header files.
-
-* Sep 16 2008 (Yang Tse)
-- Code reorganization to allow internal/private use of ares_writev to any
- system that lacks the writev function.
-
-* Sep 15 2008 (Yang Tse)
-- Code reorganization to allow internal/private use of ares_strcasecmp to any
- system that lacks the strcasecmp function.
-
-- Improve configure detection of some string functions.
-
-* Sep 11 2008 (Yang Tse)
-- Code reorganization to allow internal/private use of ares_strdup to any
- system that lacks the strdup function.
-
-Version 1.5.3 (Aug 29, 2008)
-
-* Aug 25 2008 (Yang Tse)
-- Improvement by Brad House:
-
- This patch addresses an issue in which a response could be sent back to the
- source port of a client from a different address than the request was made to.
- This is one form of a DNS cache poisoning attack.
-
- The patch simply uses recvfrom() rather than recv() and validates that the
- address returned from recvfrom() matches the address of the server we have
- connected to. Only necessary on UDP sockets as they are connection-less, TCP
- is unaffected.
-
-- Fix by George Neill:
- Fixed compilation of acountry sample application failure on some systems.
-
-* Aug 4 2008 (Daniel Stenberg)
-- Fix by Tofu Linden:
-
- The symptom:
- * Users (usually, but not always) on 2-Wire routers and the Comcast service
- and a wired connection to their router would find that the second and
- subsequent DNS lookups from fresh processes using c-ares to resolve the same
- address would cause the process to never see a reply (it keeps polling for
- around 1m15s before giving up).
-
- The repro:
- * On such a machine (and yeah, it took us a lot of QA to find the systems
- that reproduce such a specific problem!), do 'ahost www.secondlife.com',
- then do it again. The first process's lookup will work, subsequent lookups
- will time-out and fail.
-
- The cause:
- * init_id_key() was calling randomize_key() *before* it initialized
- key->state, meaning that the randomness generated by randomize_key() is
- immediately overwritten with deterministic values. (/dev/urandom was also
- being read incorrectly in the c-ares version we were using, but this was
- fixed in a later version.)
- * This makes the stream of generated query-IDs from any new c-ares process
- be an identical and predictable sequence of IDs.
- * This makes the 2-Wire's default built-in DNS server detect these queries
- as probable-duplicates and (erroneously) not respond at all.
-
-
-* Aug 4 2008 (Yang Tse)
-- Autoconf 2.62 has changed the behaviour of the AC_AIX macro which we use.
- Prior versions of autoconf defined _ALL_SOURCE if _AIX was defined. 2.62
- version of AC_AIX defines _ALL_SOURCE and other four preprocessor symbols
- no matter if the system is AIX or not. To keep the traditional behaviour,
- and an uniform one across autoconf versions AC_AIX is replaced with our
- own internal macro CARES_CHECK_AIX_ALL_SOURCE.
-
-* Aug 1 2008 (Yang Tse)
-- Configure process now checks if the preprocessor _REENTRANT symbol is already
- defined. If it isn't currently defined a set of checks are performed to test
- if its definition is required to make visible to the compiler a set of *_r
- functions. Finally, if _REENTRANT is already defined or needed it takes care
- of making adjustments necessary to ensure that it is defined equally for the
- configure process tests and generated config file.
-
-* Jul 20 2008 (Yang Tse)
-- When recvfrom prototype uses a void pointer for arguments 2, 5 or 6 this will
- now cause the definition, as appropriate, of RECVFROM_TYPE_ARG2_IS_VOID,
- RECVFROM_TYPE_ARG5_IS_VOID or RECVFROM_TYPE_ARG6_IS_VOID.
-
-* Jul 17 2008 (Yang Tse)
-- RECVFROM_TYPE_ARG2, RECVFROM_TYPE_ARG5 and RECVFROM_TYPE_ARG6 are now defined
- to the data type pointed by its respective argument and not the pointer type.
-
-* Jul 16 2008 (Yang Tse)
-- Improved configure detection of number of arguments for getservbyport_r.
- Detection is now based on compilation checks instead of linker ones.
-
-- Configure process now checks availability of recvfrom() socket function and
- finds out its return type and the types of its arguments. Added definitions
- for non-configure systems config files, and introduced macro sreadfrom which
- will be used on udp sockets as a recvfrom() wrapper in the future.
-
-* Jul 15 2008 (Yang Tse)
-- Introduce definition of _REENTRANT symbol in setup.h to improve library
- usability. Previously the configure process only used the AC_SYS_LARGEFILE
- macro for debug builds, now it is also used for non-debug ones enabling the
- use of configure options --enable-largefile and --disable-largefile which
- might be needed for library compatibility. Remove checking the size of
- curl_off_t, it is no longer needed.
-
-* Jul 3 2008 (Daniel Stenberg)
-- Phil Blundell: If you ask ares_gethostbyname() to do an AF_INET6 lookup and
- the target host has only A records, it automatically falls back to an
- AF_INET lookup and gives you the A results. However, if the target host has
- a CNAME record, this behaviour is defeated since the original query does
- return some data even though ares_parse_aaa_reply() doesn't consider it
- relevant. Here's a small patch to make it behave the same with and without
- the CNAME.
-
-* Jul 2 2008 (Yang Tse)
-- Fallback to gettimeofday when monotonic clock is unavailable at run-time.
-
-* Jun 30 2008 (Daniel Stenberg)
-
-- As was pointed out to me by Andreas Schuldei, the MAXHOSTNAMELEN define is
- not posix or anything and thus c-ares failed to build on hurd (and possibly
- elsewhere). The define was also somewhat artificially used in the windows
- port. Now, I instead rewrote the use of gethostbyname to enlarge the host
- name buffer in case of need and totally avoid the use of the MAXHOSTNAMELEN
- define. I thus also removed the defien from the namser.h file where it was
- once added for the windows build.
-
- I also fixed init_by_defaults() function to not leak memory in case if
- error.
-
-* Jun 9 2008 (Yang Tse)
-
-- Make libcares.pc generated file for pkg-config include information relative
- to the libraries needed for the static linking of c-ares.
-
-* May 30 2008 (Yang Tse)
-
-- Brad House fixed a missing header file inclusion in adig sample program.
-
-Version 1.5.2 (May 29, 2008)
-
-* May 13 2008 (Daniel Stenberg)
-
-- Introducing millisecond resolution support for the timeout option. See
- ares_init_options()'s ARES_OPT_TIMEOUTMS.
-
-* May 9 2008 (Yang Tse)
-
-- Use monotonic time source if available, for private function ares__tvnow()
-
-* May 7 2008 (Daniel Stenberg)
-
-- Sebastian made c-ares able to return all PTR-records when doing reverse
- lookups. It is not common practice to have multiple PTR-Records for a single
- IP, but its perfectly legal and some sites have those.
-
-- Doug Goldstein provided a configure patch: updates autoconf 2.13 usage to
- autoconf 2.57 usage (which is the version you have specified as the minimum
- version). It's a minor change but it does clean up some warnings with newer
- autoconf (specifically 2.62).
-
-* May 5 2008 (Yang Tse)
-
-- Improved parsing of resolver configuration files.
-
-* April 4 2008 (Daniel Stenberg)
-
-- Eino Tuominen improved the code when a file is used to seed the randomizer.
-
-- Alexey Simak made adig support NAPTR records
-
-- Alexey Simak fixed the VC dsp file by adding the missing source file
- ares_expand_string.c
-
-* December 11 2007 (Gisle Vanem)
-
-- Added another sample application; acountry.c which converts an
- IPv4-address(es) and/or host-name(s) to country-name and country-code.
- This uses the service of the DNSBL at countries.nerd.dk.
-
-* December 3 2007 (Daniel Stenberg)
-
-- Brad Spencer fixed the configure script to assume that there's no
- /dev/urandom when built cross-compiled as then the script cannot check for
- it.
-
-- Erik Kline cleaned up ares_gethostbyaddr.c:next_lookup() somewhat
-
-Version 1.5.1 (Nov 21, 2007)
-
-* November 21 2007 (Daniel Stenberg)
-
-- Robin Cornelius pointed out that ares_llist.h was missing in the release
- archive for 1.5.0
-
-Version 1.5.0 (Nov 21, 2007)
-
-* October 2 2007 (Daniel Stenberg)
-
-- ares_strerror() segfaulted if the input error number was out of the currently
- supported range.
-
-- Yang Tse: Avoid a segfault when generating a DNS "Transaction ID" in
- internal function init_id_key() under low memory conditions.
-
-* September 28 2007 (Daniel Stenberg)
-
-- Bumped version to 1.5.0 for next release and soname bumped to 2 due to ABI
- and API changes in the progress callback (and possibly more coming up from
- Steinar)
-
-* September 28 2007 (Steinar H. Gunderson)
-
-- Don't skip a server if it's the only one. (Bugfix from the Google tree.)
-
-- Made the query callbacks receive the number of timeouts that happened during
- the execution of a query, and updated documentation accordingly. (Patch from
- the Google tree.)
-
-- Support a few more socket options: ARES_OPT_SOCK_SNDBUF and
- ARES_OPT_SOCK_RCVBUF
-
-- Always register for TCP events even if there are no outstanding queries, as
- the other side could always close the connection, which is a valid event
- which should be responded to.
-
-* September 22 2007 (Daniel Stenberg)
-
-- Steinar H. Gunderson fixed: Correctly clear sockets from the fd_set on in
- several functions (write_tcp_data, read_tcp_data, read_udp_packets) so that
- if it fails and the socket is closed the following code doesn't try to use
- the file descriptor.
-
-- Steinar H. Gunderson modified c-ares to now also do to DNS retries even when
- TCP is used since there are several edge cases where it still makes sense.
-
-- Brad House provided a fix for ares_save_options():
-
- Apparently I overlooked something with the ares_save_options() where it
- would try to do a malloc(0) when no options of that type needed to be saved.
- On most platforms, this was fine because malloc(0) doesn't actually return
- NULL, but on AIX it does, so ares_save_options would return ARES_ENOMEM.
-
-* July 14 2007 (Daniel Stenberg)
-
-- Vlad Dinulescu fixed two outstanding valgrind reports:
-
- 1. In ares_query.c , in find_query_by_id we compare q->qid (which is a short
- int variable) with qid, which is declared as an int variable. Moreover,
- DNS_HEADER_SET_QID is used to set the value of qid, but DNS_HEADER_SET_QID
- sets only the first two bytes of qid. I think that qid should be declared as
- "unsigned short" in this function.
-
- 2. The same problem occurs in ares_process.c, process_answer() . query->qid
- (an unsigned short integer variable) is compared with id, which is an
- integer variable. Moreover, id is initialized from DNS_HEADER_QID which sets
- only the first two bytes of id. I think that the id variable should be
- declared as "unsigned short" in this function.
-
- Even after declaring these variables as "unsigned short", the valgrind
- errors are still there. Which brings us to the third problem.
-
- 3. The third problem is that Valgrind assumes that query->qid is not
- initialised correctly. And it does that because query->qid is set from
- DNS_HEADER_QID(qbuf); Valgrind says that qbuf has unitialised bytes. And
- qbuf has uninitialised bytes because of channel->next_id . And next_id is
- set by ares_init.c:ares__generate_new_id() . I found that putting short r=0
- in this function (instead of short r) makes all Valgrind warnings go away.
- I have studied ares__rc4() too, and this is the offending line:
-
- buffer_ptr[counter] ^= state[xorIndex]; (ares_query.c:62)
-
- This is what triggers Valgrind.. buffer_ptr is unitialised in this function,
- and by applying ^= on it, it remains unitialised.
-
-Version 1.4.0 (June 8, 2007)
-
-* June 4 2007 (Daniel Stenberg)
-
-- James Bursa reported a major memory problem when resolving multi-IP names
- and I found and fixed the problem. It was added by Ashish Sharma's patch
- two days ago.
-
- When I then tried to verify multiple entries in /etc/hosts after my fix, I
- got another segfault and decided this code was not ripe for inclusion and I
- reverted the patch.
-
-* June 2 2007
-
-- Brad Spencer found and fixed three flaws in the code, found with the new
- gcc 4.2.0 warning: -Waddress
-
-- Brad House fixed VS2005 compiler warnings due to time_t being 64bit.
- He also made recent Microsoft compilers use _strdup() instead of strdup().
-
-- Brad House's man pages for ares_save_options() and ares_destroy_options()
- were added.
-
-- Ashish Sharma provided a patch for supporting multiple entries in the
- /etc/hosts file. Patch edited for coding style and functionality by me
- (Daniel).
-
-* May 30 2007
-
-- Shmulik Regev brought cryptographically secure transaction IDs:
-
- The c-ares library implementation uses a DNS "Transaction ID" field that is
- seeded with a pseudo random number (based on gettimeofday) which is
- incremented (++) between consecutive calls and is therefore rather
- predictable. In general, predictability of DNS Transaction ID is a well
- known security problem (e.g.
- http://bak.spc.org/dms/archive/dns_id_attack.txt) and makes a c-ares based
- implementation vulnerable to DNS poisoning. Credit goes to Amit Klein
- (Trusteer) for identifying this problem.
-
- The patch I wrote changes the implementation to use a more secure way of
- generating unique IDs. It starts by obtaining a key with reasonable entropy
- which is used with an RC4 stream to generate the cryptographically secure
- transaction IDs.
-
- Note that the key generation code (in ares_init:randomize_key) has two
- versions, the Windows specific one uses a cryptographically safe function
- provided (but undocumented :) by the operating system (described at
- http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx). The
- default implementation is a bit naive and uses the standard 'rand'
- function. Surely a better way to generate random keys exists for other
- platforms.
-
- The patch can be tested by using the adig utility and using the '-s' option.
-
-- Brad House added ares_save_options() and ares_destroy_options() that can be
- used to keep options for later re-usal when ares_init_options() is used.
-
- Problem: Calling ares_init() for each lookup can be unnecessarily resource
- intensive. On windows, it must LoadLibrary() or search the registry
- on each call to ares_init(). On unix, it must read and parse
- multiple files to obtain the necessary configuration information. In
- a single-threaded environment, it would make sense to only
- ares_init() once, but in a heavily multi-threaded environment, it is
- undesirable to ares_init() and ares_destroy() for each thread created
- and track that.
-
- Solution: Create ares_save_options() and ares_destroy_options() functions to
- retrieve and free options obtained from an initialized channel. The
- options populated can be used to pass back into ares_init_options(),
- it should populate all needed fields and not retrieve any information
- from the system. Probably wise to destroy the cache every minute or
- so to prevent the data from becoming stale.
-
-- Daniel S added ares_process_fd() to allow applications to ask for processing
- on specific sockets and thus avoiding select() and associated
- functions/macros. This function will be used by upcoming libcurl releases
- for this very reason. It also made me export the ares_socket_t type in the
- public ares.h header file, since ares_process_fd() uses that type for two of
- the arguments.
-
-* May 25 2007
-
-- Ravi Pratap fixed a flaw in the init_by_resolv_conf() function for windows
- that could cause it to return a bad return code.
-
-* April 16 2007
-
-- Yang Tse: Provide ares_getopt() command-line parser function as a source
- code helper function, not belonging to the actual c-ares library.
-
-* February 19 2007
-
-- Vlad Dinulescu added ares_parse_ns_reply().
-
-* February 13 2007
-
-- Yang Tse: Fix failure to get the search sequence of /etc/hosts and
- DNS from /etc/nsswitch.conf, /etc/host.conf or /etc/svc.conf when
- /etc/resolv.conf did not exist or was unable to read it.
-
-* November 22 2006
-
-- Install ares_dns.h too
-
-- Michael Wallner fixed this problem: When I set domains in the options
- struct, and there are domain/search entries in /etc/resolv.conf, the domains
- of the options struct will be overridden.
-
-* November 6 2006
-
-- Yang Tse removed a couple of potential zero size memory allocations.
-
-- Andreas Rieke fixed the line endings in the areslib.dsp file that I (Daniel)
- broke in the 1.3.2 release. We should switch to a system where that file is
- auto-generated. We could rip some code for that from curl...
-
-Version 1.3.2 (November 3, 2006)
-
-* October 12 2006
-
-- Prevent ares_getsock() to overflow if more than 16 sockets are used.
-
-* September 11 2006
-
-- Guilherme Balena Versiani: I noted a strange BUG in Win32 port
- (ares_init.c/get_iphlpapi_dns_info() function): when I disable the network
- by hand or disconnect the network cable in Windows 2000 or Windows XP, my
- application gets 127.0.0.1 as the only name server. The problem comes from
- 'GetNetworkParams' function, that returns the empty string "" as the only
- name server in that case. Moreover, the Windows implementation of
- inet_addr() returns INADDR_LOOPBACK instead of INADDR_NONE.
-
-* August 29 2006
-
-- Brad Spencer did
-
- o made ares_version.h use extern "C" for c++ compilers
- o fixed compiler warnings in ares_getnameinfo.c
- o fixed a buffer position init for TCP reads
-
-* August 3 2006
-
-- Ravi Pratap fixed ares_getsock() to actually return the proper bitmap and
- not always zero!
-
-Version 1.3.1 (June 24, 2006)
-
-* July 23, 2006
-
-- Gisle Vanem added getopt() to the ahost program. Currently accepts
- only [-t {a|aaaa}] to specify address family in ares_gethostbyname().
-
-* June 19, 2006
-
-- (wahern) Removed "big endian" DNS section and RR data integer parser
- macros from ares_dns.h, which break c-ares on my Sparc64. Bit-wise
- operations in C operate on logical values. And in any event the octets are
- already in big-endian (aka network) byte order so they're being reversed
- (thus the source of the breakage).
-
-* June 18, 2006
-
-- William Ahern handles EAGAIN/EWOULDBLOCK errors in most of the I/O calls
- from area_process.c.
-
- TODO: Handle one last EAGAIN for a UDP socket send(2) in
- ares__send_query().
-
-* May 10, 2006
-
-- Bram Matthys brought my attention to a libtool peculiarity where detecting
- things such as C++ compiler actually is a bad thing and since we don't need
- that detection I added a work-around, much inspired by a previous patch by
- Paolo Bonzini. This also shortens the configure script quite a lot.
-
-* May 3, 2006
-
-- Nick Mathewson added the ARES_OPT_SOCK_STATE_CB option that when set makes
- c-ares call a callback on socket state changes. A better way than the
- ares_getsock() to get full control over the socket state.
-
-* January 9, 2006
-
-- Alexander Lazic improved the getservbyport_r() configure check.
-
-* January 6, 2006
-
-- Alexander Lazic pointed out that the buildconf should use the ACLOCAL_FLAGS
- variable for easier controlling what it does and how it runs.
-
-* January 5, 2006
-
-- James Bursa fixed c-ares to find the hosts file on RISC OS, and made it
- build with newer gcc versions that no longer defines "riscos".
-
-* December 22
-
-- Daniel Stenberg added ares_getsock() that extracts the set of sockets to
- wait for action on. Similar to ares_fds() but not restricted to using
- select() for the waiting.
-
-* November 25
-
-- Yang Tse fixed some send() / recv() compiler warnings
-
-* September 18
-
-- Added constants that will be used by ares_getaddrinfo
-
-- Made ares_getnameinfo use the reentrant getservbyport (getservbyport_r) if it
- is available to ensure it works properly in a threaded environment.
-
-* September 10
-
-- configure fix for detecting a member in the sockaddr_in6 struct which failed
- on ipv6-enabled HP-UX 11.00
-
-Version 1.3.0 (August 29, 2005)
-
-* August 21
-
-- Alfredo Tupone provided a fix for the Windows code in get_iphlpapi_dns_info()
- when getting the DNS server etc.
-
-* June 19
-
-- Added some checks for the addrinfo structure.
-
-* June 2
-
-- William Ahern:
-
- Make UDP sockets non-blocking. I've confirmed that at least on Linux 2.4 a
- read event can come back from poll() on a valid SOCK_DGRAM socket but
- recv(2) will still block. This patch doesn't ignore EAGAIN in
- read_udp_packets(), though maybe it should. (This patch was edited by Daniel
- Stenberg and a new configure test was added (imported from curl's configure)
- to properly detect what non-blocking socket approach to use.)
-
- I'm not quite sure how this was happening, but I've been seeing PTR queries
- which seem to return empty responses. At least, they were empty when calling
- ares_expand_name() on the record. Here's a patch which guarantees to
- NUL-terminate the expanded name. The old behavior failed to NUL-terminate if
- len was 0, and this was causing strlen() to run past the end of the buffer
- after calling ares_expand_name() and getting ARES_SUCCESS as the return
- value. If q is not greater than *s then it's equal and *s is always
- allocated with at least one byte.
-
-* May 16
-
-- Added ares_getnameinfo which mimics the getnameinfo API (another feature
- that could use testing).
-
-* May 14
-
-- Added an inet_ntop function from BIND for systems that do not have it.
-
-* April 9
-
-- Made sortlist support IPv6 (this can probably use some testing).
-
-- Made sortlist support CIDR matching for IPv4.
-
-* April 8
-
-- Added preliminary IPv6 support to ares_gethostbyname. Currently, sortlist
- does not work with IPv6. Also provided an implementation of bitncmp from
- BIND for systems that do not supply this function. This will be used to add
- IPv6 support to sortlist.
-
-- Made ares_gethostbyaddr support IPv6 by specifying AF_INET6 as the family.
- The function can lookup IPv6 addresses both from files (/etc/hosts) and
- DNS lookups.
-
-* April 7
-
-- Tupone Alfredo fixed includes of arpa/nameser_compat.h to build fine on Mac
- OS X.
-
-* April 5
-
-- Dominick Meglio: Provided implementations of inet_net_pton and inet_pton
- from BIND for systems that do not include these functions.
-
-* March 11, 2005
-
-- Dominick Meglio added ares_parse_aaaa_reply.c and did various
- adjustments. The first little steps towards IPv6 support!
-
-* November 7
-
-- Fixed the VC project and makefile to use ares_cancel and ares_version
-
-* October 24
-
-- The released ares_version.h from 1.2.1 says 1.2.0 due to a maketgz flaw.
- This is now fixed.
-
-Version 1.2.1 (October 20, 2004)
-
-* September 29
-
-- Henrik Stoerner fix: got a report that Tru64 Unix (the unix from Digital
- when they made Alpha's) uses /etc/svc.conf for the purpose fixed below for
- other OSes. He made c-ares check for and understand it if present.
-
-- Now c-ares will use local host name lookup _before_ DNS resolving by default
- if nothing else is told.
-
-* September 26
-
-- Henrik Stoerner: found out that c-ares does not look at the /etc/host.conf
- file to determine the sequence in which to search /etc/hosts and DNS. So on
- systems where this order is defined by /etc/host.conf instead of a "lookup"
- entry in /etc/resolv.conf, c-ares will always default to looking in DNS
- first, and /etc/hosts second.
-
- c-ares now looks at
-
- 1) resolv.conf (for the "lookup" line);
- 2) nsswitch.fon (for the "hosts:" line);
- 3) host.conf (for the "order" line).
-
- First match wins.
-
-- Dominick Meglio patched: C-ares on Windows assumed that the HOSTS file is
- located in a static location. It assumed
- C:\Windows\System32\Drivers\Etc. This is a poor assumption to make. In fact,
- the location of the HOSTS file can be changed via a registry setting.
-
- There is a key called DatabasePath which specifies the path to the HOSTS
- file:
- http://www.microsoft.com/technet/itsolutions/network/deploy/depovg/tcpip2k.mspx
-
- The patch will make c-ares correctly consult the registry for the location
- of this file.
-
-* August 29
-
-- Gisle Vanem fixed the MSVC build files.
-
-* August 20
-
-- Gisle Vanem made c-ares build and work with his Watt-32 TCP/IP stack.
-
-* August 13
-
-- Harshal Pradhan made a minor syntax change in ares_init.c to make it build
- fine with MSVC 7.1
-
-* July 24
-
-- Made the lib get built static only if --enable-debug is used.
-
-- Gisle Vanem fixed:
-
- Basically in loops like handle_errors(), 'query->next' was assigned a local
- variable and then query was referenced after the memory was freed by
- next_server(). I've changed that so next_server() and end_query() returns
- the next query. So callers should use this ret-value.
-
- The next problem was that 'server->tcp_buffer_pos' had a random value at
- entry to 1st recv() (luckily causing Winsock to return ENOBUFS).
-
- I've also added a ares_writev() for Windows to streamline the code a bit
- more.
-
-* July 20
-- Fixed a few variable return types for some system calls. Made configure
- check for ssize_t to make it possible to use that when receiving the send()
- error code. This is necessary to prevent compiler warnings on some systems.
-
-- Made configure create config.h, and all source files now include setup.h that
- might include the proper config.h (or a handicrafted alternative).
-
-- Switched to 'ares_socket_t' type for sockets in ares, since Windows don't
- use 'int' for that.
-
-- automake-ified and libool-ified c-ares. Now it builds libcares as a shared
- lib on most platforms if wanted. (This bloated the size of the release
- archive with another 200K!)
-
-- Makefile.am now uses Makefile.inc for the c sources, h headers and man
- pages, to make it easier for other makefiles to use the exact same set of
- files.
-
-- Adjusted 'maketgz' to use the new automake magic when building distribution
- archives.
-
-- Anyone desires HTML and/or PDF versions of the man pages in the release
- archives?
-
-* July 3
-- Günter Knauf made c-ares build and run on Novell Netware.
-
-* July 1
-- Gisle Vanem provided Makefile.dj to build with djgpp, added a few more djgpp
- fixes and made ares not use 'errno' to provide further info on Windows.
-
-* June 30
-- Gisle Vanem made it build with djgpp and run fine with the Watt-32 stack.
-
-* June 10
-- Gisle Vanem's init patch for Windows:
-
- The init_by_resolv_conf() function fetches the DNS-server(s)
- from a series of registry branches.
-
- This can be wrong in the case where DHCP has assigned nameservers, but the
- user has overridden these servers with other prefered settings. Then it's
- wrong to use the DHCPNAMESERVER setting in registry.
-
- In the case of no global DHCP-assigned or fixed servers, but DNS server(s)
- per adapter, one has to query the adapter branches. But how can c-ares know
- which adapter is valid for use? AFAICS it can't. There could be one adapter
- that is down (e.g. a VPN adapter).
-
- So it's better to leave this to the IP Helper API (iphlapi) available in
- Win-98/2000 and later. My patch falls-back to the old way if not available.
-
-* June 8
-- James Bursa fixed an init issue for RISC OS.
-
-* May 11
-- Nico Stappenbelt reported that when processing domain and search lines in
- the resolv.conf file, the first entry encountered is processed and used as
- the search list. According to the manual pages for both Linux, Solaris and
- Tru64, the last entry of either a domain or a search field is used.
-
- This is now adjusted in the code
-
-Version 1.2.0 (April 13, 2004)
-
-* April 2, 2004
-- Updated various man pages to look nicer when converted to HTML on the web
- site.
-
-* April 1, 2004
-- Dirk Manske provided a new function that is now named ares_cancel(). It is
- used to cancel/cleanup a resolve/request made using ares functions on the
- given ares channel. It does not destroy/kill the ares channel itself.
-
-- Dominick Meglio cleaned up the formatting in several man pages.
-
-* March 30, 2004
-- Dominick Meglio's new ares_expand_string. A helper function when decoding
- incoming DNS packages.
-
-- Daniel Stenberg modified the Makefile.in to use a for loop for the man page
- installation to improve overview and make it easier to add man pages.
-
-Version 1.1.0 (March 11, 2004)
-
-* March 9, 2004
-- Gisle Vanem improved build on Windows.
-
-* February 25, 2004
-- Dan Fandrich found a flaw in the Feb 22 fix.
-
-- Added better configure --enable-debug logic (taken from the curl configure
- script). Added acinclude.m4 to the tarball.
-
-* February 23, 2004
-- Removed ares_free_errmem(), the function, the file and the man page. It was
- not used and it did nothing.
-
-- Fixed a lot of code that wasn't "64bit clean" and thus caused a lot of
- compiler warnings on picky compilers.
-
-* February 22, 2004
-- Dominick Meglio made ares init support multiple name servers in the
- NameServer key on Windows.
-
-* February 16, 2004
-- Modified ares_private.h to include libcurl's memory debug header if
- CURLDEBUG is set. This makes all the ares-functions supervised properly by
- the curl test suite. This also forced me to add inclusion of the
- ares_private.h header in a few more files that are using some kind of
- memory-related resources.
-
-- Made the makefile only build ahost and adig if 'make demos' is used.
-
-* February 10, 2004
-- Dirk Manske made ares_version.h installed with 'make install'
-
-* February 4, 2004
-- ares_free_errmem() is subject for removal, it is simply present for future
- purposes, and since we removed the extra parameter in strerror() it won't
- be used by c-ares!
-- configure --enable-debug now enables picky compiler options if gcc is used
-- fixed several compiler warnings --enable-debug showed and Joerg Mueller-Tolk
- reported
-
-Version 1.0.0 (February 3, 2004)
-
-* February 3, 2004
-- now we produce the libcares.a library instead of the previous libares.a
- since we are no longer compatible
-
-* February 2, 2004
-
-- ares_strerror() has one argument less. This is the first official
- modification of the existing provided ares API.
-
-* January 29, 2004
-
-- Dirk Manske fixed how the socket is set non-blocking.
-
-* January 4, 2004
-
-- Dominick Meglio made the private gettimeofday() become ares_gettimeofday()
- instead in order to not pollute the name space and risk colliding with
- other libraries' versions of this function.
-
-* October 24, 2003. Daniel Stenberg
-
- Added ares_version().
-
-Version 1.0-pre1 (8 October 2003)
-
-- James Bursa made it run on RISC OS
-
-- Dominick Meglio made it run fine on NT4
-
-- Duncan Wilcox made it work fine on Mac OS X
-
-- Daniel Stenberg adjusted the windows port
-
-- liren at vivisimo.com made the initial windows port
-
-* Imported the sources from ares 1.1.1
diff --git a/deps/uv/src/ares/CMakeLists.txt b/deps/uv/src/ares/CMakeLists.txt
deleted file mode 100644
index 7bbb95b87..000000000
--- a/deps/uv/src/ares/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${node_platform}-${cares_arch})
-add_definitions(-DHAVE_CONFIG_H=1)
-
-include(CheckLibraryExists)
-check_library_exists(socket socket "" HAVE_SOCKET_LIB)
-check_library_exists(nsl gethostbyname "" HAVE_NSL_LIB)
-
-file(GLOB lib_sources *.c)
-add_library(cares ${lib_sources})
-
-if(${HAVE_SOCKET_LIB})
- set(cares_libs ${cares_libs} socket)
-endif()
-
-if(${HAVE_NSL_LIB})
- set(cares_libs ${cares_libs} nsl)
-endif()
-
-if(cares_libs)
- target_link_libraries(cares ${cares_libs})
-endif()
diff --git a/deps/uv/src/ares/README.node b/deps/uv/src/ares/README.node
deleted file mode 100644
index 17503096f..000000000
--- a/deps/uv/src/ares/README.node
+++ /dev/null
@@ -1,21 +0,0 @@
-Library: c-ares, DNS resolver
-
-Version: 1.7.3 (11 June, 2010)
-
-Authors: Greg Hudson, Daniel Stenberg
-
-License: MIT
-
-Notes:
-
-Just use waf instead of the autoconf based configure script. Delete most of
-the documentation and other files distributed with it. To upgrade, run
-./configure on linux, macintosh, solaris (and other supported platforms) and
-copy
-- ares_config.h
-- ares_setup.h
-- ares_build.h
-into the appropriate directory.
-
-
-
diff --git a/deps/uv/src/ares/RELEASE-NOTES b/deps/uv/src/ares/RELEASE-NOTES
deleted file mode 100644
index 06d7856bc..000000000
--- a/deps/uv/src/ares/RELEASE-NOTES
+++ /dev/null
@@ -1,26 +0,0 @@
-c-ares version 1.7.5
-
-Fixed:
-
- o detection of semicolon comments in resolv.conf
- o avoid using system's inet_net_pton affected by the WLB-2008080064 advisory
- o replacement ares_inet_net_pton affected by the WLB-2008080064 advisory
- o replacement ares_inet_ntop affected by potential out of bounds write
- o added install target to Makefile.msvc
- o only fall back to AF_INET searches when looking for AF_UNSPEC addresses
- o fixed ares_parse_*_reply memory leaks
- o Use correct sizeof in ares_getnameinfo()
- o IPv6-on-windows: find DNS servers correctly
- o man pages: docs for the c-ares utility programs
- o getservbyport replacement for Win CE
- o config_sortlist: (win32) missing else
- o advance_tcp_send_queue: avoid NULL ptr dereference
- o configure: fix a bashism
- o ares_expand_name: Fix encoded length for indirect root
-
-Thanks go to these friendly people for their efforts and contributions:
-
- Yang Tse, Jakub Hrozek, Gisle Vanem, Tom Hughes, David Stuart, Dima Tisnek,
- Peter Pentchev, Stefan Buhler
-
-Have fun!
diff --git a/deps/uv/src/ares/ares__get_hostent.c b/deps/uv/src/ares/ares__get_hostent.c
deleted file mode 100644
index 298df0918..000000000
--- a/deps/uv/src/ares/ares__get_hostent.c
+++ /dev/null
@@ -1,263 +0,0 @@
-
-/* Copyright 1998, 2010 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.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-
-#include "ares.h"
-#include "inet_net_pton.h"
-#include "ares_private.h"
-
-int ares__get_hostent(FILE *fp, int family, struct hostent **host)
-{
- char *line = NULL, *p, *q, **alias;
- char *txtaddr, *txthost, *txtalias;
- int status;
- size_t addrlen, linesize, naliases;
- struct ares_addr addr;
- struct hostent *hostent = NULL;
-
- *host = NULL; /* Assume failure */
-
- /* Validate family */
- switch (family) {
- case AF_INET:
- case AF_INET6:
- case AF_UNSPEC:
- break;
- default:
- return ARES_EBADFAMILY;
- }
-
- while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
- {
-
- /* Trim line comment. */
- p = line;
- while (*p && (*p != '#'))
- p++;
- *p = '\0';
-
- /* Trim trailing whitespace. */
- q = p - 1;
- while ((q >= line) && ISSPACE(*q))
- q--;
- *++q = '\0';
-
- /* Skip leading whitespace. */
- p = line;
- while (*p && ISSPACE(*p))
- p++;
- if (!*p)
- /* Ignore line if empty. */
- continue;
-
- /* Pointer to start of IPv4 or IPv6 address part. */
- txtaddr = p;
-
- /* Advance past address part. */
- while (*p && !ISSPACE(*p))
- p++;
- if (!*p)
- /* Ignore line if reached end of line. */
- continue;
-
- /* Null terminate address part. */
- *p = '\0';
-
- /* Advance to host name */
- p++;
- while (*p && ISSPACE(*p))
- p++;
- if (!*p)
- /* Ignore line if reached end of line. */
- continue;
-
- /* Pointer to start of host name. */
- txthost = p;
-
- /* Advance past host name. */
- while (*p && !ISSPACE(*p))
- p++;
-
- /* Pointer to start of first alias. */
- txtalias = NULL;
- if (*p)
- {
- q = p + 1;
- while (*q && ISSPACE(*q))
- q++;
- if (*q)
- txtalias = q;
- }
-
- /* Null terminate host name. */
- *p = '\0';
-
- /* find out number of aliases. */
- naliases = 0;
- if (txtalias)
- {
- p = txtalias;
- while (*p)
- {
- while (*p && !ISSPACE(*p))
- p++;
- while (*p && ISSPACE(*p))
- p++;
- naliases++;
- }
- }
-
- /* Convert address string to network address for the requested family. */
- addrlen = 0;
- addr.family = AF_UNSPEC;
- addr.addrV4.s_addr = INADDR_NONE;
- if ((family == AF_INET) || (family == AF_UNSPEC))
- {
- addr.addrV4.s_addr = inet_addr(txtaddr);
- if (addr.addrV4.s_addr != INADDR_NONE)
- {
- /* Actual network address family and length. */
- addr.family = AF_INET;
- addrlen = sizeof(addr.addrV4);
- }
- }
- if ((family == AF_INET6) || ((family == AF_UNSPEC) && (!addrlen)))
- {
- if (ares_inet_pton(AF_INET6, txtaddr, &addr.addrV6) > 0)
- {
- /* Actual network address family and length. */
- addr.family = AF_INET6;
- addrlen = sizeof(addr.addrV6);
- }
- }
- if (!addrlen)
- /* Ignore line if invalid address string for the requested family. */
- continue;
-
- /*
- ** Actual address family possible values are AF_INET and AF_INET6 only.
- */
-
- /* Allocate memory for the hostent structure. */
- hostent = malloc(sizeof(struct hostent));
- if (!hostent)
- break;
-
- /* Initialize fields for out of memory condition. */
- hostent->h_aliases = NULL;
- hostent->h_addr_list = NULL;
-
- /* Copy official host name. */
- hostent->h_name = strdup(txthost);
- if (!hostent->h_name)
- break;
-
- /* Copy network address. */
- hostent->h_addr_list = malloc(2 * sizeof(char *));
- if (!hostent->h_addr_list)
- break;
- hostent->h_addr_list[1] = NULL;
- hostent->h_addr_list[0] = malloc(addrlen);
- if (!hostent->h_addr_list[0])
- break;
- if (addr.family == AF_INET)
- memcpy(hostent->h_addr_list[0], &addr.addrV4, sizeof(addr.addrV4));
- else
- memcpy(hostent->h_addr_list[0], &addr.addrV6, sizeof(addr.addrV6));
-
- /* Copy aliases. */
- hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
- if (!hostent->h_aliases)
- break;
- alias = hostent->h_aliases;
- while (naliases)
- *(alias + naliases--) = NULL;
- *alias = NULL;
- while (txtalias)
- {
- p = txtalias;
- while (*p && !ISSPACE(*p))
- p++;
- q = p;
- while (*q && ISSPACE(*q))
- q++;
- *p = '\0';
- if ((*alias = strdup(txtalias)) == NULL)
- break;
- alias++;
- txtalias = *q ? q : NULL;
- }
- if (txtalias)
- /* Alias memory allocation failure. */
- break;
-
- /* Copy actual network address family and length. */
- hostent->h_addrtype = addr.family;
- hostent->h_length = (int)addrlen;
-
- /* Free line buffer. */
- free(line);
-
- /* Return hostent successfully */
- *host = hostent;
- return ARES_SUCCESS;
-
- }
-
- /* If allocated, free line buffer. */
- if (line)
- free(line);
-
- if (status == ARES_SUCCESS)
- {
- /* Memory allocation failure; clean up. */
- if (hostent)
- {
- if (hostent->h_name)
- free((char *) hostent->h_name);
- if (hostent->h_aliases)
- {
- for (alias = hostent->h_aliases; *alias; alias++)
- free(*alias);
- free(hostent->h_aliases);
- }
- if (hostent->h_addr_list)
- {
- if (hostent->h_addr_list[0])
- free(hostent->h_addr_list[0]);
- free(hostent->h_addr_list);
- }
- free(hostent);
- }
- return ARES_ENOMEM;
- }
-
- return status;
-}
diff --git a/deps/uv/src/ares/ares_data.c b/deps/uv/src/ares/ares_data.c
deleted file mode 100644
index a2477be19..000000000
--- a/deps/uv/src/ares/ares_data.c
+++ /dev/null
@@ -1,190 +0,0 @@
-
-/* Copyright (C) 2009-2010 by Daniel Stenberg
- *
- * 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.
- */
-
-
-#include "ares_setup.h"
-
-#include <stddef.h>
-
-#include "ares.h"
-#include "ares_data.h"
-#include "ares_private.h"
-
-
-/*
-** ares_free_data() - c-ares external API function.
-**
-** This function must be used by the application to free data memory that
-** has been internally allocated by some c-ares function and for which a
-** pointer has already been returned to the calling application. The list
-** of c-ares functions returning pointers that must be free'ed using this
-** function is:
-**
-** ares_get_servers()
-** ares_parse_srv_reply()
-** ares_parse_txt_reply()
-*/
-
-void ares_free_data(void *dataptr)
-{
- struct ares_data *ptr;
-
- if (!dataptr)
- return;
-
-#ifdef __INTEL_COMPILER
-# pragma warning(push)
-# pragma warning(disable:1684)
- /* 1684: conversion from pointer to same-sized integral type */
-#endif
-
- ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
-
-#ifdef __INTEL_COMPILER
-# pragma warning(pop)
-#endif
-
- if (ptr->mark != ARES_DATATYPE_MARK)
- return;
-
- switch (ptr->type)
- {
- case ARES_DATATYPE_MX_REPLY:
-
- if (ptr->data.mx_reply.next)
- ares_free_data(ptr->data.mx_reply.next);
- if (ptr->data.mx_reply.host)
- free(ptr->data.mx_reply.host);
- break;
-
- case ARES_DATATYPE_SRV_REPLY:
-
- if (ptr->data.srv_reply.next)
- ares_free_data(ptr->data.srv_reply.next);
- if (ptr->data.srv_reply.host)
- free(ptr->data.srv_reply.host);
- break;
-
- case ARES_DATATYPE_TXT_REPLY:
-
- if (ptr->data.txt_reply.next)
- ares_free_data(ptr->data.txt_reply.next);
- if (ptr->data.txt_reply.txt)
- free(ptr->data.txt_reply.txt);
- break;
-
- case ARES_DATATYPE_ADDR_NODE:
-
- if (ptr->data.addr_node.next)
- ares_free_data(ptr->data.addr_node.next);
- break;
-
- default:
- return;
- }
-
- free(ptr);
-}
-
-
-/*
-** ares_malloc_data() - c-ares internal helper function.
-**
-** This function allocates memory for a c-ares private ares_data struct
-** for the specified ares_datatype, initializes c-ares private fields
-** and zero initializes those which later might be used from the public
-** API. It returns an interior pointer which can be passed by c-ares
-** functions to the calling application, and that must be free'ed using
-** c-ares external API function ares_free_data().
-*/
-
-void *ares_malloc_data(ares_datatype type)
-{
- struct ares_data *ptr;
-
- ptr = malloc(sizeof(struct ares_data));
- if (!ptr)
- return NULL;
-
- switch (type)
- {
- case ARES_DATATYPE_MX_REPLY:
- ptr->data.mx_reply.next = NULL;
- ptr->data.mx_reply.host = NULL;
- ptr->data.mx_reply.priority = 0;
- break;
-
- case ARES_DATATYPE_SRV_REPLY:
- ptr->data.srv_reply.next = NULL;
- ptr->data.srv_reply.host = NULL;
- ptr->data.srv_reply.priority = 0;
- ptr->data.srv_reply.weight = 0;
- ptr->data.srv_reply.port = 0;
- break;
-
- case ARES_DATATYPE_TXT_REPLY:
- ptr->data.txt_reply.next = NULL;
- ptr->data.txt_reply.txt = NULL;
- ptr->data.txt_reply.length = 0;
- break;
-
- case ARES_DATATYPE_ADDR_NODE:
- ptr->data.addr_node.next = NULL;
- ptr->data.addr_node.family = 0;
- memset(&ptr->data.addr_node.addrV6, 0,
- sizeof(ptr->data.addr_node.addrV6));
- break;
-
- default:
- free(ptr);
- return NULL;
- }
-
- ptr->mark = ARES_DATATYPE_MARK;
- ptr->type = type;
-
- return &ptr->data;
-}
-
-
-/*
-** ares_get_datatype() - c-ares internal helper function.
-**
-** This function returns the ares_datatype of the data stored in a
-** private ares_data struct when given the public API pointer.
-*/
-
-ares_datatype ares_get_datatype(void * dataptr)
-{
- struct ares_data *ptr;
-
-#ifdef __INTEL_COMPILER
-# pragma warning(push)
-# pragma warning(disable:1684)
- /* 1684: conversion from pointer to same-sized integral type */
-#endif
-
- ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
-
-#ifdef __INTEL_COMPILER
-# pragma warning(pop)
-#endif
-
- if (ptr->mark == ARES_DATATYPE_MARK)
- return ptr->type;
-
- return ARES_DATATYPE_UNKNOWN;
-}
diff --git a/deps/uv/src/ares/ares_data.h b/deps/uv/src/ares/ares_data.h
deleted file mode 100644
index de1608be5..000000000
--- a/deps/uv/src/ares/ares_data.h
+++ /dev/null
@@ -1,65 +0,0 @@
-
-/* Copyright (C) 2009-2010 by Daniel Stenberg
- *
- * 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.
- */
-
-typedef enum {
- ARES_DATATYPE_UNKNOWN = 1, /* unknown data type - introduced in 1.7.0 */
- ARES_DATATYPE_SRV_REPLY, /* struct ares_srv_reply - introduced in 1.7.0 */
- ARES_DATATYPE_TXT_REPLY, /* struct ares_txt_reply - introduced in 1.7.0 */
- ARES_DATATYPE_ADDR_NODE, /* struct ares_addr_node - introduced in 1.7.1 */
- ARES_DATATYPE_MX_REPLY, /* struct ares_mx_reply - introduced in 1.7.2 */
-#if 0
- ARES_DATATYPE_ADDR6TTL, /* struct ares_addrttl */
- ARES_DATATYPE_ADDRTTL, /* struct ares_addr6ttl */
- ARES_DATATYPE_HOSTENT, /* struct hostent */
- ARES_DATATYPE_OPTIONS, /* struct ares_options */
-#endif
- ARES_DATATYPE_LAST /* not used - introduced in 1.7.0 */
-} ares_datatype;
-
-#define ARES_DATATYPE_MARK 0xbead
-
-/*
- * ares_data struct definition is internal to c-ares and shall not
- * be exposed by the public API in order to allow future changes
- * and extensions to it without breaking ABI. This will be used
- * internally by c-ares as the container of multiple types of data
- * dynamically allocated for which a reference will be returned
- * to the calling application.
- *
- * c-ares API functions returning a pointer to c-ares internally
- * allocated data will actually be returning an interior pointer
- * into this ares_data struct.
- *
- * All this is 'invisible' to the calling application, the only
- * requirement is that this kind of data must be free'ed by the
- * calling application using ares_free_data() with the pointer
- * it has received from a previous c-ares function call.
- */
-
-struct ares_data {
- ares_datatype type; /* Actual data type identifier. */
- unsigned int mark; /* Private ares_data signature. */
- union {
- struct ares_txt_reply txt_reply;
- struct ares_srv_reply srv_reply;
- struct ares_addr_node addr_node;
- struct ares_mx_reply mx_reply;
- } data;
-};
-
-void *ares_malloc_data(ares_datatype type);
-
-ares_datatype ares_get_datatype(void * dataptr);
diff --git a/deps/uv/src/ares/ares_destroy.c b/deps/uv/src/ares/ares_destroy.c
deleted file mode 100644
index 5e274daee..000000000
--- a/deps/uv/src/ares/ares_destroy.c
+++ /dev/null
@@ -1,105 +0,0 @@
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright (C) 2004-2010 by Daniel Stenberg
- *
- * 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.
- */
-
-#include "ares_setup.h"
-#include <assert.h>
-#include <stdlib.h>
-#include "ares.h"
-#include "ares_private.h"
-
-void ares_destroy_options(struct ares_options *options)
-{
- int i;
-
- if(options->servers)
- free(options->servers);
- for (i = 0; i < options->ndomains; i++)
- free(options->domains[i]);
- free(options->domains);
- if(options->sortlist)
- free(options->sortlist);
- free(options->lookups);
-}
-
-void ares_destroy(ares_channel channel)
-{
- int i;
- struct query *query;
- struct list_node* list_head;
- struct list_node* list_node;
-
- if (!channel)
- return;
-
- list_head = &(channel->all_queries);
- for (list_node = list_head->next; list_node != list_head; )
- {
- query = list_node->data;
- list_node = list_node->next; /* since we're deleting the query */
- query->callback(query->arg, ARES_EDESTRUCTION, 0, NULL, 0);
- ares__free_query(query);
- }
-#ifndef NDEBUG
- /* Freeing the query should remove it from all the lists in which it sits,
- * so all query lists should be empty now.
- */
- assert(ares__is_list_empty(&(channel->all_queries)));
- for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
- {
- assert(ares__is_list_empty(&(channel->queries_by_qid[i])));
- }
- for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
- {
- assert(ares__is_list_empty(&(channel->queries_by_timeout[i])));
- }
-#endif
-
- ares__destroy_servers_state(channel);
-
- if (channel->domains) {
- for (i = 0; i < channel->ndomains; i++)
- free(channel->domains[i]);
- free(channel->domains);
- }
-
- if(channel->sortlist)
- free(channel->sortlist);
-
- if (channel->lookups)
- free(channel->lookups);
-
- free(channel);
-}
-
-void ares__destroy_servers_state(ares_channel channel)
-{
- struct server_state *server;
- int i;
-
- if (channel->servers)
- {
- for (i = 0; i < channel->nservers; i++)
- {
- server = &channel->servers[i];
- ares__close_sockets(channel, server);
- assert(ares__is_list_empty(&server->queries_to_server));
- }
- free(channel->servers);
- channel->servers = NULL;
- }
- channel->nservers = -1;
-}
diff --git a/deps/uv/src/ares/ares_dns.h b/deps/uv/src/ares/ares_dns.h
deleted file mode 100644
index 6893c024c..000000000
--- a/deps/uv/src/ares/ares_dns.h
+++ /dev/null
@@ -1,90 +0,0 @@
-
-/* 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.
- */
-
-#ifndef ARES__DNS_H
-#define ARES__DNS_H
-
-#define DNS__16BIT(p) (((p)[0] << 8) | (p)[1])
-#define DNS__32BIT(p) (((p)[0] << 24) | ((p)[1] << 16) | \
- ((p)[2] << 8) | (p)[3])
-
-#define DNS__SET16BIT(p, v) (((p)[0] = (unsigned char)(((v) >> 8) & 0xff)), \
- ((p)[1] = (unsigned char)((v) & 0xff)))
-#define DNS__SET32BIT(p, v) (((p)[0] = (unsigned char)(((v) >> 24) & 0xff)), \
- ((p)[1] = (unsigned char)(((v) >> 16) & 0xff)), \
- ((p)[2] = (unsigned char)(((v) >> 8) & 0xff)), \
- ((p)[3] = (unsigned char)((v) & 0xff)))
-
-#if 0
-/* we cannot use this approach on systems where we can't access 16/32 bit
- data on un-aligned addresses */
-#define DNS__16BIT(p) ntohs(*(unsigned short*)(p))
-#define DNS__32BIT(p) ntohl(*(unsigned long*)(p))
-#define DNS__SET16BIT(p, v) *(unsigned short*)(p) = htons(v)
-#define DNS__SET32BIT(p, v) *(unsigned long*)(p) = htonl(v)
-#endif
-
-/* Macros for parsing a DNS header */
-#define DNS_HEADER_QID(h) DNS__16BIT(h)
-#define DNS_HEADER_QR(h) (((h)[2] >> 7) & 0x1)
-#define DNS_HEADER_OPCODE(h) (((h)[2] >> 3) & 0xf)
-#define DNS_HEADER_AA(h) (((h)[2] >> 2) & 0x1)
-#define DNS_HEADER_TC(h) (((h)[2] >> 1) & 0x1)
-#define DNS_HEADER_RD(h) ((h)[2] & 0x1)
-#define DNS_HEADER_RA(h) (((h)[3] >> 7) & 0x1)
-#define DNS_HEADER_Z(h) (((h)[3] >> 4) & 0x7)
-#define DNS_HEADER_RCODE(h) ((h)[3] & 0xf)
-#define DNS_HEADER_QDCOUNT(h) DNS__16BIT((h) + 4)
-#define DNS_HEADER_ANCOUNT(h) DNS__16BIT((h) + 6)
-#define DNS_HEADER_NSCOUNT(h) DNS__16BIT((h) + 8)
-#define DNS_HEADER_ARCOUNT(h) DNS__16BIT((h) + 10)
-
-/* Macros for constructing a DNS header */
-#define DNS_HEADER_SET_QID(h, v) DNS__SET16BIT(h, v)
-#define DNS_HEADER_SET_QR(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 7))
-#define DNS_HEADER_SET_OPCODE(h, v) ((h)[2] |= (unsigned char)(((v) & 0xf) << 3))
-#define DNS_HEADER_SET_AA(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 2))
-#define DNS_HEADER_SET_TC(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 1))
-#define DNS_HEADER_SET_RD(h, v) ((h)[2] |= (unsigned char)((v) & 0x1))
-#define DNS_HEADER_SET_RA(h, v) ((h)[3] |= (unsigned char)(((v) & 0x1) << 7))
-#define DNS_HEADER_SET_Z(h, v) ((h)[3] |= (unsigned char)(((v) & 0x7) << 4))
-#define DNS_HEADER_SET_RCODE(h, v) ((h)[3] |= (unsigned char)((v) & 0xf))
-#define DNS_HEADER_SET_QDCOUNT(h, v) DNS__SET16BIT((h) + 4, v)
-#define DNS_HEADER_SET_ANCOUNT(h, v) DNS__SET16BIT((h) + 6, v)
-#define DNS_HEADER_SET_NSCOUNT(h, v) DNS__SET16BIT((h) + 8, v)
-#define DNS_HEADER_SET_ARCOUNT(h, v) DNS__SET16BIT((h) + 10, v)
-
-/* Macros for parsing the fixed part of a DNS question */
-#define DNS_QUESTION_TYPE(q) DNS__16BIT(q)
-#define DNS_QUESTION_CLASS(q) DNS__16BIT((q) + 2)
-
-/* Macros for constructing the fixed part of a DNS question */
-#define DNS_QUESTION_SET_TYPE(q, v) DNS__SET16BIT(q, v)
-#define DNS_QUESTION_SET_CLASS(q, v) DNS__SET16BIT((q) + 2, v)
-
-/* Macros for parsing the fixed part of a DNS resource record */
-#define DNS_RR_TYPE(r) DNS__16BIT(r)
-#define DNS_RR_CLASS(r) DNS__16BIT((r) + 2)
-#define DNS_RR_TTL(r) DNS__32BIT((r) + 4)
-#define DNS_RR_LEN(r) DNS__16BIT((r) + 8)
-
-/* Macros for constructing the fixed part of a DNS resource record */
-#define DNS_RR_SET_TYPE(r) DNS__SET16BIT(r, v)
-#define DNS_RR_SET_CLASS(r) DNS__SET16BIT((r) + 2, v)
-#define DNS_RR_SET_TTL(r) DNS__SET32BIT((r) + 4, v)
-#define DNS_RR_SET_LEN(r) DNS__SET16BIT((r) + 8, v)
-
-#endif /* ARES__DNS_H */
diff --git a/deps/uv/src/ares/ares_expand_name.c b/deps/uv/src/ares/ares_expand_name.c
deleted file mode 100644
index e3eccd2f7..000000000
--- a/deps/uv/src/ares/ares_expand_name.c
+++ /dev/null
@@ -1,200 +0,0 @@
-
-/* 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.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#include <stdlib.h>
-#include "ares.h"
-#include "ares_private.h" /* for the memdebug */
-
-static int name_length(const unsigned char *encoded, const unsigned char *abuf,
- int alen);
-
-/* Expand an RFC1035-encoded domain name given by encoded. The
- * containing message is given by abuf and alen. The result given by
- * *s, which is set to a NUL-terminated allocated buffer. *enclen is
- * set to the length of the encoded name (not the length of the
- * expanded name; the goal is to tell the caller how many bytes to
- * move forward to get past the encoded name).
- *
- * In the simple case, an encoded name is a series of labels, each
- * composed of a one-byte length (limited to values between 0 and 63
- * inclusive) followed by the label contents. The name is terminated
- * by a zero-length label.
- *
- * In the more complicated case, a label may be terminated by an
- * indirection pointer, specified by two bytes with the high bits of
- * the first byte (corresponding to INDIR_MASK) set to 11. With the
- * two high bits of the first byte stripped off, the indirection
- * pointer gives an offset from the beginning of the containing
- * message with more labels to decode. Indirection can happen an
- * arbitrary number of times, so we have to detect loops.
- *
- * Since the expanded name uses '.' as a label separator, we use
- * backslashes to escape periods or backslashes in the expanded name.
- */
-
-int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
- int alen, char **s, long *enclen)
-{
- int len, indir = 0;
- char *q;
- const unsigned char *p;
- union {
- ssize_t sig;
- size_t uns;
- } nlen;
-
- nlen.sig = name_length(encoded, abuf, alen);
- if (nlen.sig < 0)
- return ARES_EBADNAME;
-
- *s = malloc(nlen.uns + 1);
- if (!*s)
- return ARES_ENOMEM;
- q = *s;
-
- if (nlen.uns == 0) {
- /* RFC2181 says this should be ".": the root of the DNS tree.
- * Since this function strips trailing dots though, it becomes ""
- */
- q[0] = '\0';
-
- /* indirect root label (like 0xc0 0x0c) is 2 bytes long (stupid, but
- valid) */
- if ((*encoded & INDIR_MASK) == INDIR_MASK)
- *enclen = 2;
- else
- *enclen = 1; /* the caller should move one byte to get past this */
-
- return ARES_SUCCESS;
- }
-
- /* No error-checking necessary; it was all done by name_length(). */
- p = encoded;
- while (*p)
- {
- if ((*p & INDIR_MASK) == INDIR_MASK)
- {
- if (!indir)
- {
- *enclen = p + 2 - encoded;
- indir = 1;
- }
- p = abuf + ((*p & ~INDIR_MASK) << 8 | *(p + 1));
- }
- else
- {
- len = *p;
- p++;
- while (len--)
- {
- if (*p == '.' || *p == '\\')
- *q++ = '\\';
- *q++ = *p;
- p++;
- }
- *q++ = '.';
- }
- }
- if (!indir)
- *enclen = p + 1 - encoded;
-
- /* Nuke the trailing period if we wrote one. */
- if (q > *s)
- *(q - 1) = 0;
- else
- *q = 0; /* zero terminate */
-
- return ARES_SUCCESS;
-}
-
-/* Return the length of the expansion of an encoded domain name, or
- * -1 if the encoding is invalid.
- */
-static int name_length(const unsigned char *encoded, const unsigned char *abuf,
- int alen)
-{
- int n = 0, offset, indir = 0;
-
- /* Allow the caller to pass us abuf + alen and have us check for it. */
- if (encoded == abuf + alen)
- return -1;
-
- while (*encoded)
- {
- if ((*encoded & INDIR_MASK) == INDIR_MASK)
- {
- /* Check the offset and go there. */
- if (encoded + 1 >= abuf + alen)
- return -1;
- offset = (*encoded & ~INDIR_MASK) << 8 | *(encoded + 1);
- if (offset >= alen)
- return -1;
- encoded = abuf + offset;
-
- /* If we've seen more indirects than the message length,
- * then there's a loop.
- */
- if (++indir > alen)
- return -1;
- }
- else
- {
- offset = *encoded;
- if (encoded + offset + 1 >= abuf + alen)
- return -1;
- encoded++;
- while (offset--)
- {
- n += (*encoded == '.' || *encoded == '\\') ? 2 : 1;
- encoded++;
- }
- n++;
- }
- }
-
- /* If there were any labels at all, then the number of dots is one
- * less than the number of labels, so subtract one.
- */
- return (n) ? n - 1 : n;
-}
-
-/* Like ares_expand_name but returns EBADRESP in case of invalid input. */
-int ares__expand_name_for_response(const unsigned char *encoded,
- const unsigned char *abuf, int alen,
- char **s, long *enclen)
-{
- int status = ares_expand_name(encoded, abuf, alen, s, enclen);
- if (status == ARES_EBADNAME)
- status = ARES_EBADRESP;
- return status;
-}
diff --git a/deps/uv/src/ares/ares_gethostbyname.c b/deps/uv/src/ares/ares_gethostbyname.c
deleted file mode 100644
index ad89dc27b..000000000
--- a/deps/uv/src/ares/ares_gethostbyname.c
+++ /dev/null
@@ -1,523 +0,0 @@
-
-/* 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.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#include "ares.h"
-#include "inet_net_pton.h"
-#include "bitncmp.h"
-#include "ares_platform.h"
-#include "ares_private.h"
-
-#ifdef WATT32
-#undef WIN32
-#endif
-
-struct host_query {
- /* Arguments passed to ares_gethostbyname() */
- ares_channel channel;
- char *name;
- ares_host_callback callback;
- void *arg;
- int sent_family; /* this family is what was is being used */
- int want_family; /* this family is what is asked for in the API */
- const char *remaining_lookups;
- int timeouts;
-};
-
-static void next_lookup(struct host_query *hquery, int status_code);
-static void host_callback(void *arg, int status, int timeouts,
- unsigned char *abuf, int alen);
-static void end_hquery(struct host_query *hquery, int status,
- struct hostent *host);
-static int fake_hostent(const char *name, int family,
- ares_host_callback callback, void *arg);
-static int file_lookup(const char *name, int family, struct hostent **host);
-static void sort_addresses(struct hostent *host,
- const struct apattern *sortlist, int nsort);
-static void sort6_addresses(struct hostent *host,
- const struct apattern *sortlist, int nsort);
-static int get_address_index(const struct in_addr *addr,
- const struct apattern *sortlist, int nsort);
-static int get6_address_index(const struct ares_in6_addr *addr,
- const struct apattern *sortlist, int nsort);
-
-void ares_gethostbyname(ares_channel channel, const char *name, int family,
- ares_host_callback callback, void *arg)
-{
- struct host_query *hquery;
-
- /* Right now we only know how to look up Internet addresses - and unspec
- means try both basically. */
- switch (family) {
- case AF_INET:
- case AF_INET6:
- case AF_UNSPEC:
- break;
- default:
- callback(arg, ARES_ENOTIMP, 0, NULL);
- return;
- }
-
- if (fake_hostent(name, family, callback, arg))
- return;
-
- /* Allocate and fill in the host query structure. */
- hquery = malloc(sizeof(struct host_query));
- if (!hquery)
- {
- callback(arg, ARES_ENOMEM, 0, NULL);
- return;
- }
- hquery->channel = channel;
- hquery->name = strdup(name);
- hquery->want_family = family;
- hquery->sent_family = -1; /* nothing is sent yet */
- if (!hquery->name) {
- free(hquery);
- callback(arg, ARES_ENOMEM, 0, NULL);
- return;
- }
- hquery->callback = callback;
- hquery->arg = arg;
- hquery->remaining_lookups = channel->lookups;
- hquery->timeouts = 0;
-
- /* Start performing lookups according to channel->lookups. */
- next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */);
-}
-
-static void next_lookup(struct host_query *hquery, int status_code)
-{
- const char *p;
- struct hostent *host;
- int status = status_code;
-
- for (p = hquery->remaining_lookups; *p; p++)
- {
- switch (*p)
- {
- case 'b':
- /* DNS lookup */
- hquery->remaining_lookups = p + 1;
- if ((hquery->want_family == AF_INET6) ||
- (hquery->want_family == AF_UNSPEC)) {
- /* if inet6 or unspec, start out with AAAA */
- hquery->sent_family = AF_INET6;
- ares_search(hquery->channel, hquery->name, C_IN, T_AAAA,
- host_callback, hquery);
- }
- else {
- hquery->sent_family = AF_INET;
- ares_search(hquery->channel, hquery->name, C_IN, T_A,
- host_callback, hquery);
- }
- return;
-
- case 'f':
- /* Host file lookup */
- status = file_lookup(hquery->name, hquery->want_family, &host);
-
- /* this status check below previously checked for !ARES_ENOTFOUND,
- but we should not assume that this single error code is the one
- that can occur, as that is in fact no longer the case */
- if (status == ARES_SUCCESS)
- {
- end_hquery(hquery, status, host);
- return;
- }
- status = status_code; /* Use original status code */
- break;
- }
- }
- end_hquery(hquery, status, NULL);
-}
-
-static void host_callback(void *arg, int status, int timeouts,
- unsigned char *abuf, int alen)
-{
- struct host_query *hquery = (struct host_query *) arg;
- ares_channel channel = hquery->channel;
- struct hostent *host = NULL;
-
- hquery->timeouts += timeouts;
- if (status == ARES_SUCCESS)
- {
- if (hquery->sent_family == AF_INET)
- {
- status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL);
- if (host && channel->nsort)
- sort_addresses(host, channel->sortlist, channel->nsort);
- }
- else if (hquery->sent_family == AF_INET6)
- {
- status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL);
- if ((status == ARES_ENODATA || status == ARES_EBADRESP) &&
- hquery->want_family == AF_UNSPEC) {
- /* The query returned something but either there were no AAAA
- records (e.g. just CNAME) or the response was malformed. Try
- looking up A instead. */
- hquery->sent_family = AF_INET;
- ares_search(hquery->channel, hquery->name, C_IN, T_A,
- host_callback, hquery);
- return;
- }
- if (host && channel->nsort)
- sort6_addresses(host, channel->sortlist, channel->nsort);
- }
- end_hquery(hquery, status, host);
- }
- else if ((status == ARES_ENODATA || status == ARES_EBADRESP ||
- status == ARES_ETIMEOUT) && (hquery->sent_family == AF_INET6 &&
- hquery->want_family == AF_UNSPEC))
- {
- /* The AAAA query yielded no useful result. Now look up an A instead. */
- hquery->sent_family = AF_INET;
- ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
- hquery);
- }
- else if (status == ARES_EDESTRUCTION)
- end_hquery(hquery, status, NULL);
- else
- next_lookup(hquery, status);
-}
-
-static void end_hquery(struct host_query *hquery, int status,
- struct hostent *host)
-{
- hquery->callback(hquery->arg, status, hquery->timeouts, host);
- if (host)
- ares_free_hostent(host);
- free(hquery->name);
- free(hquery);
-}
-
-/* If the name looks like an IP address, fake up a host entry, end the
- * query immediately, and return true. Otherwise return false.
- */
-static int fake_hostent(const char *name, int family,
- ares_host_callback callback, void *arg)
-{
- struct hostent hostent;
- char *aliases[1] = { NULL };
- char *addrs[2];
- int result = 0;
- struct in_addr in;
- struct ares_in6_addr in6;
-
- if (family == AF_INET || family == AF_INET6)
- {
- /* It only looks like an IP address if it's all numbers and dots. */
- int numdots = 0, valid = 1;
- const char *p;
- for (p = name; *p; p++)
- {
- if (!ISDIGIT(*p) && *p != '.') {
- valid = 0;
- break;
- } else if (*p == '.') {
- numdots++;
- }
- }
-
- /* if we don't have 3 dots, it is illegal
- * (although inet_addr doesn't think so).
- */
- if (numdots != 3 || !valid)
- result = 0;
- else
- result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1);
-
- if (result)
- family = AF_INET;
- }
- if (family == AF_INET6)
- result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1);
-
- if (!result)
- return 0;
-
- if (family == AF_INET)
- {
- hostent.h_length = (int)sizeof(struct in_addr);
- addrs[0] = (char *)&in;
- }
- else if (family == AF_INET6)
- {
- hostent.h_length = (int)sizeof(struct ares_in6_addr);
- addrs[0] = (char *)&in6;
- }
- /* Duplicate the name, to avoid a constness violation. */
- hostent.h_name = strdup(name);
- if (!hostent.h_name)
- {
- callback(arg, ARES_ENOMEM, 0, NULL);
- return 1;
- }
-
- /* Fill in the rest of the host structure and terminate the query. */
- addrs[1] = NULL;
- hostent.h_aliases = aliases;
- hostent.h_addrtype = family;
- hostent.h_addr_list = addrs;
- callback(arg, ARES_SUCCESS, 0, &hostent);
-
- free((char *)(hostent.h_name));
- return 1;
-}
-
-/* This is an API method */
-int ares_gethostbyname_file(ares_channel channel, const char *name,
- int family, struct hostent **host)
-{
- int result;
-
- /* We only take the channel to ensure that ares_init() been called. */
- if(channel == NULL)
- {
- /* Anything will do, really. This seems fine, and is consistent with
- other error cases. */
- *host = NULL;
- return ARES_ENOTFOUND;
- }
-
- /* Just chain to the internal implementation we use here; it's exactly
- * what we want.
- */
- result = file_lookup(name, family, host);
- if(result != ARES_SUCCESS)
- {
- /* We guarantee a NULL hostent on failure. */
- *host = NULL;
- }
- return result;
-}
-
-static int file_lookup(const char *name, int family, struct hostent **host)
-{
- FILE *fp;
- char **alias;
- int status;
- int error;
-
-#ifdef WIN32
- char PATH_HOSTS[MAX_PATH];
- win_platform platform;
-
- PATH_HOSTS[0] = '\0';
-
- platform = ares__getplatform();
-
- if (platform == WIN_NT) {
- char tmp[MAX_PATH];
- HKEY hkeyHosts;
-
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
- &hkeyHosts) == ERROR_SUCCESS)
- {
- DWORD dwLength = MAX_PATH;
- RegQueryValueEx(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp,
- &dwLength);
- ExpandEnvironmentStrings(tmp, PATH_HOSTS, MAX_PATH);
- RegCloseKey(hkeyHosts);
- }
- }
- else if (platform == WIN_9X)
- GetWindowsDirectory(PATH_HOSTS, MAX_PATH);
- else
- return ARES_ENOTFOUND;
-
- strcat(PATH_HOSTS, WIN_PATH_HOSTS);
-
-#elif defined(WATT32)
- extern const char *_w32_GetHostsFile (void);
- const char *PATH_HOSTS = _w32_GetHostsFile();
-
- if (!PATH_HOSTS)
- return ARES_ENOTFOUND;
-#endif
-
- fp = fopen(PATH_HOSTS, "r");
- if (!fp)
- {
- error = ERRNO;
- switch(error)
- {
- case ENOENT:
- case ESRCH:
- return ARES_ENOTFOUND;
- default:
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
- error, strerror(error)));
- DEBUGF(fprintf(stderr, "Error opening file: %s\n",
- PATH_HOSTS));
- *host = NULL;
- return ARES_EFILE;
- }
- }
- while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
- {
- if (strcasecmp((*host)->h_name, name) == 0)
- break;
- for (alias = (*host)->h_aliases; *alias; alias++)
- {
- if (strcasecmp(*alias, name) == 0)
- break;
- }
- if (*alias)
- break;
- ares_free_hostent(*host);
- }
- fclose(fp);
- if (status == ARES_EOF)
- status = ARES_ENOTFOUND;
- if (status != ARES_SUCCESS)
- *host = NULL;
- return status;
-}
-
-static void sort_addresses(struct hostent *host,
- const struct apattern *sortlist, int nsort)
-{
- struct in_addr a1, a2;
- int i1, i2, ind1, ind2;
-
- /* This is a simple insertion sort, not optimized at all. i1 walks
- * through the address list, with the loop invariant that everything
- * to the left of i1 is sorted. In the loop body, the value at i1 is moved
- * back through the list (via i2) until it is in sorted order.
- */
- for (i1 = 0; host->h_addr_list[i1]; i1++)
- {
- memcpy(&a1, host->h_addr_list[i1], sizeof(struct in_addr));
- ind1 = get_address_index(&a1, sortlist, nsort);
- for (i2 = i1 - 1; i2 >= 0; i2--)
- {
- memcpy(&a2, host->h_addr_list[i2], sizeof(struct in_addr));
- ind2 = get_address_index(&a2, sortlist, nsort);
- if (ind2 <= ind1)
- break;
- memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in_addr));
- }
- memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in_addr));
- }
-}
-
-/* Find the first entry in sortlist which matches addr. Return nsort
- * if none of them match.
- */
-static int get_address_index(const struct in_addr *addr,
- const struct apattern *sortlist,
- int nsort)
-{
- int i;
-
- for (i = 0; i < nsort; i++)
- {
- if (sortlist[i].family != AF_INET)
- continue;
- if (sortlist[i].type == PATTERN_MASK)
- {
- if ((addr->s_addr & sortlist[i].mask.addr4.s_addr)
- == sortlist[i].addrV4.s_addr)
- break;
- }
- else
- {
- if (!ares_bitncmp(&addr->s_addr, &sortlist[i].addrV4.s_addr,
- sortlist[i].mask.bits))
- break;
- }
- }
- return i;
-}
-
-static void sort6_addresses(struct hostent *host,
- const struct apattern *sortlist, int nsort)
-{
- struct ares_in6_addr a1, a2;
- int i1, i2, ind1, ind2;
-
- /* This is a simple insertion sort, not optimized at all. i1 walks
- * through the address list, with the loop invariant that everything
- * to the left of i1 is sorted. In the loop body, the value at i1 is moved
- * back through the list (via i2) until it is in sorted order.
- */
- for (i1 = 0; host->h_addr_list[i1]; i1++)
- {
- memcpy(&a1, host->h_addr_list[i1], sizeof(struct ares_in6_addr));
- ind1 = get6_address_index(&a1, sortlist, nsort);
- for (i2 = i1 - 1; i2 >= 0; i2--)
- {
- memcpy(&a2, host->h_addr_list[i2], sizeof(struct ares_in6_addr));
- ind2 = get6_address_index(&a2, sortlist, nsort);
- if (ind2 <= ind1)
- break;
- memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct ares_in6_addr));
- }
- memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct ares_in6_addr));
- }
-}
-
-/* Find the first entry in sortlist which matches addr. Return nsort
- * if none of them match.
- */
-static int get6_address_index(const struct ares_in6_addr *addr,
- const struct apattern *sortlist,
- int nsort)
-{
- int i;
-
- for (i = 0; i < nsort; i++)
- {
- if (sortlist[i].family != AF_INET6)
- continue;
- if (!ares_bitncmp(addr,
- &sortlist[i].addrV6,
- sortlist[i].mask.bits))
- break;
- }
- return i;
-}
diff --git a/deps/uv/src/ares/ares_getnameinfo.c b/deps/uv/src/ares/ares_getnameinfo.c
deleted file mode 100644
index 82e261dae..000000000
--- a/deps/uv/src/ares/ares_getnameinfo.c
+++ /dev/null
@@ -1,427 +0,0 @@
-
-/* Copyright 2005 by Dominick Meglio
- *
- * 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.
- */
-#include "ares_setup.h"
-
-#ifdef HAVE_GETSERVBYPORT_R
-# if !defined(GETSERVBYPORT_R_ARGS) || \
- (GETSERVBYPORT_R_ARGS < 4) || (GETSERVBYPORT_R_ARGS > 6)
-# error "you MUST specifiy a valid number of arguments for getservbyport_r"
-# endif
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "ares.h"
-#include "ares_ipv6.h"
-#include "inet_ntop.h"
-#include "ares_nowarn.h"
-#include "ares_private.h"
-
-struct nameinfo_query {
- ares_nameinfo_callback callback;
- void *arg;
- union {
- struct sockaddr_in addr4;
- struct sockaddr_in6 addr6;
- } addr;
- int family;
- int flags;
- int timeouts;
-};
-
-#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
-#define IPBUFSIZ \
- (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") + IF_NAMESIZE)
-#else
-#define IPBUFSIZ \
- (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))
-#endif
-
-static void nameinfo_callback(void *arg, int status, int timeouts,
- struct hostent *host);
-static char *lookup_service(unsigned short port, int flags,
- char *buf, size_t buflen);
-#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
-static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid,
- char *buf, size_t buflen);
-#endif
-static char *ares_striendstr(const char *s1, const char *s2);
-
-void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
- ares_socklen_t salen,
- int flags, ares_nameinfo_callback callback, void *arg)
-{
- struct sockaddr_in *addr = NULL;
- struct sockaddr_in6 *addr6 = NULL;
- struct nameinfo_query *niquery;
- unsigned int port = 0;
-
- /* Validate socket address family and length */
- if ((sa->sa_family == AF_INET) &&
- (salen == sizeof(struct sockaddr_in)))
- {
- addr = (struct sockaddr_in *)sa;
- port = addr->sin_port;
- }
- else if ((sa->sa_family == AF_INET6) &&
- (salen == sizeof(struct sockaddr_in6)))
- {
- addr6 = (struct sockaddr_in6 *)sa;
- port = addr6->sin6_port;
- }
- else
- {
- callback(arg, ARES_ENOTIMP, 0, NULL, NULL);
- return;
- }
-
- /* If neither, assume they want a host */
- if (!(flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST))
- flags |= ARES_NI_LOOKUPHOST;
-
- /* All they want is a service, no need for DNS */
- if ((flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST))
- {
- char buf[33], *service;
-
- service = lookup_service((unsigned short)(port & 0xffff),
- flags, buf, sizeof(buf));
- callback(arg, ARES_SUCCESS, 0, NULL, service);
- return;
- }
-
- /* They want a host lookup */
- if ((flags & ARES_NI_LOOKUPHOST))
- {
- /* A numeric host can be handled without DNS */
- if ((flags & ARES_NI_NUMERICHOST))
- {
- char ipbuf[IPBUFSIZ];
- char srvbuf[33];
- char *service = NULL;
- ipbuf[0] = 0;
-
- /* Specifying not to lookup a host, but then saying a host
- * is required has to be illegal.
- */
- if (flags & ARES_NI_NAMEREQD)
- {
- callback(arg, ARES_EBADFLAGS, 0, NULL, NULL);
- return;
- }
- if (salen == sizeof(struct sockaddr_in6))
- {
- ares_inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, IPBUFSIZ);
- /* If the system supports scope IDs, use it */
-#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
- append_scopeid(addr6, flags, ipbuf, sizeof(ipbuf));
-#endif
- }
- else
- {
- ares_inet_ntop(AF_INET, &addr->sin_addr, ipbuf, IPBUFSIZ);
- }
- /* They also want a service */
- if (flags & ARES_NI_LOOKUPSERVICE)
- service = lookup_service((unsigned short)(port & 0xffff),
- flags, srvbuf, sizeof(srvbuf));
- callback(arg, ARES_SUCCESS, 0, ipbuf, service);
- return;
- }
- /* This is where a DNS lookup becomes necessary */
- else
- {
- niquery = malloc(sizeof(struct nameinfo_query));
- if (!niquery)
- {
- callback(arg, ARES_ENOMEM, 0, NULL, NULL);
- return;
- }
- niquery->callback = callback;
- niquery->arg = arg;
- niquery->flags = flags;
- niquery->timeouts = 0;
- if (sa->sa_family == AF_INET)
- {
- niquery->family = AF_INET;
- memcpy(&niquery->addr.addr4, addr, sizeof(struct in_addr));
- ares_gethostbyaddr(channel, &addr->sin_addr,
- sizeof(struct in_addr), AF_INET,
- nameinfo_callback, niquery);
- }
- else
- {
- niquery->family = AF_INET6;
- memcpy(&niquery->addr.addr6, addr6, sizeof(struct ares_in6_addr));
- ares_gethostbyaddr(channel, &addr6->sin6_addr,
- sizeof(struct ares_in6_addr), AF_INET6,
- nameinfo_callback, niquery);
- }
- }
- }
-}
-
-static void nameinfo_callback(void *arg, int status, int timeouts,
- struct hostent *host)
-{
- struct nameinfo_query *niquery = (struct nameinfo_query *) arg;
- char srvbuf[33];
- char *service = NULL;
-
- niquery->timeouts += timeouts;
- if (status == ARES_SUCCESS)
- {
- /* They want a service too */
- if (niquery->flags & ARES_NI_LOOKUPSERVICE)
- {
- if (niquery->family == AF_INET)
- service = lookup_service(niquery->addr.addr4.sin_port,
- niquery->flags, srvbuf, sizeof(srvbuf));
- else
- service = lookup_service(niquery->addr.addr6.sin6_port,
- niquery->flags, srvbuf, sizeof(srvbuf));
- }
- /* NOFQDN means we have to strip off the domain name portion. We do
- this by determining our own domain name, then searching the string
- for this domain name and removing it.
- */
-#ifdef HAVE_GETHOSTNAME
- if (niquery->flags & ARES_NI_NOFQDN)
- {
- char buf[255];
- char *domain;
- gethostname(buf, 255);
- if ((domain = strchr(buf, '.')) != NULL)
- {
- char *end = ares_striendstr(host->h_name, domain);
- if (end)
- *end = 0;
- }
- }
-#endif
- niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts,
- (char *)(host->h_name),
- service);
- free(niquery);
- return;
- }
- /* We couldn't find the host, but it's OK, we can use the IP */
- else if (status == ARES_ENOTFOUND && !(niquery->flags & ARES_NI_NAMEREQD))
- {
- char ipbuf[IPBUFSIZ];
- if (niquery->family == AF_INET)
- ares_inet_ntop(AF_INET, &niquery->addr.addr4.sin_addr, ipbuf,
- IPBUFSIZ);
- else
- {
- ares_inet_ntop(AF_INET6, &niquery->addr.addr6.sin6_addr, ipbuf,
- IPBUFSIZ);
-#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
- append_scopeid(&niquery->addr.addr6, niquery->flags, ipbuf,
- sizeof(ipbuf));
-#endif
- }
- /* They want a service too */
- if (niquery->flags & ARES_NI_LOOKUPSERVICE)
- {
- if (niquery->family == AF_INET)
- service = lookup_service(niquery->addr.addr4.sin_port,
- niquery->flags, srvbuf, sizeof(srvbuf));
- else
- service = lookup_service(niquery->addr.addr6.sin6_port,
- niquery->flags, srvbuf, sizeof(srvbuf));
- }
- niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, ipbuf,
- service);
- free(niquery);
- return;
- }
- niquery->callback(niquery->arg, status, niquery->timeouts, NULL, NULL);
- free(niquery);
-}
-
-static char *lookup_service(unsigned short port, int flags,
- char *buf, size_t buflen)
-{
- const char *proto;
- struct servent *sep;
-#ifdef HAVE_GETSERVBYPORT_R
- struct servent se;
-#endif
- char tmpbuf[4096];
-
- if (port)
- {
- if (flags & ARES_NI_NUMERICSERV)
- sep = NULL;
- else
- {
- if (flags & ARES_NI_UDP)
- proto = "udp";
- else if (flags & ARES_NI_SCTP)
- proto = "sctp";
- else if (flags & ARES_NI_DCCP)
- proto = "dccp";
- else
- proto = "tcp";
-#ifdef HAVE_GETSERVBYPORT_R
- sep = &se;
- memset(tmpbuf, 0, sizeof(tmpbuf));
-#if GETSERVBYPORT_R_ARGS == 6
- if (getservbyport_r(port, proto, &se, (void *)tmpbuf,
- sizeof(tmpbuf), &sep) != 0)
- sep = NULL;
-#elif GETSERVBYPORT_R_ARGS == 5
- sep = getservbyport_r(port, proto, &se, (void *)tmpbuf,
- sizeof(tmpbuf));
-#elif GETSERVBYPORT_R_ARGS == 4
- if (getservbyport_r(port, proto, &se, (void *)tmpbuf) != 0)
- sep = NULL;
-#else
- /* Lets just hope the OS uses TLS! */
- sep = getservbyport(port, proto);
-#endif
-#else
- /* Lets just hope the OS uses TLS! */
-#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
- sep = getservbyport(port, (char*)proto);
-#else
- sep = getservbyport(port, proto);
-#endif
-#endif
- }
- if (sep && sep->s_name)
- /* get service name */
- strcpy(tmpbuf, sep->s_name);
- else
- /* get port as a string */
- sprintf(tmpbuf, "%u", (unsigned int)ntohs(port));
- if (strlen(tmpbuf) < buflen)
- /* return it if buffer big enough */
- strcpy(buf, tmpbuf);
- else
- /* avoid reusing previous one */
- buf[0] = '\0';
- return buf;
- }
- buf[0] = '\0';
- return NULL;
-}
-
-#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
-static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
- char *buf, size_t buflen)
-{
-#ifdef HAVE_IF_INDEXTONAME
- int is_ll, is_mcll;
-#endif
- static const char fmt_u[] = "%u";
- static const char fmt_lu[] = "%lu";
- char tmpbuf[IF_NAMESIZE + 2];
- size_t bufl;
- const char *fmt = (sizeof(addr6->sin6_scope_id) > sizeof(unsigned int))?
- fmt_lu:fmt_u;
-
- tmpbuf[0] = '%';
-
-#ifdef HAVE_IF_INDEXTONAME
- is_ll = IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr);
- is_mcll = IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr);
- if ((flags & ARES_NI_NUMERICSCOPE) ||
- (!is_ll && !is_mcll))
- {
- sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
- }
- else
- {
- if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL)
- sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
- }
-#else
- sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
- (void) flags;
-#endif
- tmpbuf[IF_NAMESIZE + 1] = '\0';
- bufl = strlen(buf);
-
- if(bufl + strlen(tmpbuf) < buflen)
- /* only append the scopeid string if it fits in the target buffer */
- strcpy(&buf[bufl], tmpbuf);
-}
-#endif
-
-/* Determines if s1 ends with the string in s2 (case-insensitive) */
-static char *ares_striendstr(const char *s1, const char *s2)
-{
- const char *c1, *c2, *c1_begin;
- int lo1, lo2;
- size_t s1_len = strlen(s1), s2_len = strlen(s2);
-
- /* If the substr is longer than the full str, it can't match */
- if (s2_len > s1_len)
- return NULL;
-
- /* Jump to the end of s1 minus the length of s2 */
- c1_begin = s1+s1_len-s2_len;
- c1 = (const char *)c1_begin;
- c2 = s2;
- while (c2 < s2+s2_len)
- {
- lo1 = TOLOWER(*c1);
- lo2 = TOLOWER(*c2);
- if (lo1 != lo2)
- return NULL;
- else
- {
- c1++;
- c2++;
- }
- }
- if (c2 == c1 && c2 == NULL)
- return (char *)c1_begin;
- return NULL;
-}
diff --git a/deps/uv/src/ares/ares_init.c b/deps/uv/src/ares/ares_init.c
deleted file mode 100644
index 52bb4d6c8..000000000
--- a/deps/uv/src/ares/ares_init.c
+++ /dev/null
@@ -1,1809 +0,0 @@
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright (C) 2007-2011 by Daniel Stenberg
- *
- * 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.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <time.h>
-
-#ifdef ANDROID
-#include <sys/system_properties.h>
-#endif
-
-#include "ares.h"
-#include "inet_net_pton.h"
-#include "ares_library_init.h"
-#include "ares_nowarn.h"
-#include "ares_platform.h"
-#include "inet_ntop.h"
-#include "ares_private.h"
-
-#ifdef WATT32
-#undef WIN32 /* Redefined in MingW/MSVC headers */
-#endif
-
-static int init_by_options(ares_channel channel, const struct ares_options *options,
- int optmask);
-static int init_by_environment(ares_channel channel);
-static int init_by_resolv_conf(ares_channel channel);
-static int init_by_defaults(ares_channel channel);
-
-#ifndef WATT32
-static int config_nameserver(struct server_state **servers, int *nservers,
- char *str);
-#endif
-static int set_search(ares_channel channel, const char *str);
-static int set_options(ares_channel channel, const char *str);
-static const char *try_option(const char *p, const char *q, const char *opt);
-static int init_id_key(rc4_key* key,int key_data_len);
-
-#if !defined(WIN32) && !defined(WATT32)
-static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
-static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
-static void natural_mask(struct apattern *pat);
-static int config_domain(ares_channel channel, char *str);
-static int config_lookup(ares_channel channel, const char *str,
- const char *bindch, const char *filech);
-static int config_sortlist(struct apattern **sortlist, int *nsort,
- const char *str);
-static char *try_config(char *s, const char *opt, char scc);
-#endif
-
-#define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
- x->nservers > -1 && \
- x->ndomains > -1 && \
- x->ndots > -1 && x->timeout > -1 && \
- x->tries > -1)
-
-int ares_init(ares_channel *channelptr)
-{
- return ares_init_options(channelptr, NULL, 0);
-}
-
-int ares_init_options(ares_channel *channelptr, struct ares_options *options,
- int optmask)
-{
- ares_channel channel;
- int i;
- int status = ARES_SUCCESS;
- struct timeval now;
-
-#ifdef CURLDEBUG
- const char *env = getenv("CARES_MEMDEBUG");
-
- if (env)
- curl_memdebug(env);
- env = getenv("CARES_MEMLIMIT");
- if (env) {
- char *endptr;
- long num = strtol(env, &endptr, 10);
- if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
- curl_memlimit(num);
- }
-#endif
-
- if (ares_library_initialized() != ARES_SUCCESS)
- return ARES_ENOTINITIALIZED;
-
- channel = malloc(sizeof(struct ares_channeldata));
- if (!channel) {
- *channelptr = NULL;
- return ARES_ENOMEM;
- }
-
- now = ares__tvnow();
-
- /* Set everything to distinguished values so we know they haven't
- * been set yet.
- */
- channel->flags = -1;
- channel->timeout = -1;
- channel->tries = -1;
- channel->ndots = -1;
- channel->rotate = -1;
- channel->udp_port = -1;
- channel->tcp_port = -1;
- channel->socket_send_buffer_size = -1;
- channel->socket_receive_buffer_size = -1;
- channel->nservers = -1;
- channel->ndomains = -1;
- channel->nsort = -1;
- channel->tcp_connection_generation = 0;
- channel->lookups = NULL;
- channel->domains = NULL;
- channel->sortlist = NULL;
- channel->servers = NULL;
- channel->sock_state_cb = NULL;
- channel->sock_state_cb_data = NULL;
- channel->sock_create_cb = NULL;
- channel->sock_create_cb_data = NULL;
-
- channel->last_server = 0;
- channel->last_timeout_processed = (time_t)now.tv_sec;
-
- memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
- channel->local_ip4 = 0;
- memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
-
- /* Initialize our lists of queries */
- ares__init_list_head(&(channel->all_queries));
- for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
- {
- ares__init_list_head(&(channel->queries_by_qid[i]));
- }
- for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
- {
- ares__init_list_head(&(channel->queries_by_timeout[i]));
- }
-
- /* Initialize configuration by each of the four sources, from highest
- * precedence to lowest.
- */
-
- if (status == ARES_SUCCESS) {
- status = init_by_options(channel, options, optmask);
- if (status != ARES_SUCCESS)
- DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
- ares_strerror(status)));
- }
- if (status == ARES_SUCCESS) {
- status = init_by_environment(channel);
- if (status != ARES_SUCCESS)
- DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
- ares_strerror(status)));
- }
- if (status == ARES_SUCCESS) {
- status = init_by_resolv_conf(channel);
- if (status != ARES_SUCCESS)
- DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
- ares_strerror(status)));
- }
-
- /*
- * No matter what failed or succeeded, seed defaults to provide
- * useful behavior for things that we missed.
- */
- status = init_by_defaults(channel);
- if (status != ARES_SUCCESS)
- DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
- ares_strerror(status)));
-
- /* Generate random key */
-
- if (status == ARES_SUCCESS) {
- status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
- if (status == ARES_SUCCESS)
- channel->next_id = ares__generate_new_id(&channel->id_key);
- else
- DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
- ares_strerror(status)));
- }
-
- if (status != ARES_SUCCESS)
- {
- /* Something failed; clean up memory we may have allocated. */
- if (channel->servers)
- free(channel->servers);
- if (channel->domains)
- {
- for (i = 0; i < channel->ndomains; i++)
- free(channel->domains[i]);
- free(channel->domains);
- }
- if (channel->sortlist)
- free(channel->sortlist);
- if(channel->lookups)
- free(channel->lookups);
- free(channel);
- return status;
- }
-
- /* Trim to one server if ARES_FLAG_PRIMARY is set. */
- if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
- channel->nservers = 1;
-
- ares__init_servers_state(channel);
-
- *channelptr = channel;
- return ARES_SUCCESS;
-}
-
-/* ares_dup() duplicates a channel handle with all its options and returns a
- new channel handle */
-int ares_dup(ares_channel *dest, ares_channel src)
-{
- struct ares_options opts;
- struct ares_addr_node *servers;
- int ipv6_nservers = 0;
- int i, rc;
- int optmask;
-
- *dest = NULL; /* in case of failure return NULL explicitly */
-
- /* First get the options supported by the old ares_save_options() function,
- which is most of them */
- rc = ares_save_options(src, &opts, &optmask);
- if(rc)
- return rc;
-
- /* Then create the new channel with those options */
- rc = ares_init_options(dest, &opts, optmask);
-
- /* destroy the options copy to not leak any memory */
- ares_destroy_options(&opts);
-
- if(rc)
- return rc;
-
- /* Now clone the options that ares_save_options() doesn't support. */
- (*dest)->sock_create_cb = src->sock_create_cb;
- (*dest)->sock_create_cb_data = src->sock_create_cb_data;
-
- strncpy((*dest)->local_dev_name, src->local_dev_name, sizeof(src->local_dev_name));
- (*dest)->local_ip4 = src->local_ip4;
- memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
-
- /* Full name server cloning required when not all are IPv4 */
- for (i = 0; i < src->nservers; i++)
- {
- if (src->servers[i].addr.family != AF_INET) {
- ipv6_nservers++;
- break;
- }
- }
- if (ipv6_nservers) {
- rc = ares_get_servers(src, &servers);
- if (rc != ARES_SUCCESS)
- return rc;
- rc = ares_set_servers(*dest, servers);
- ares_free_data(servers);
- if (rc != ARES_SUCCESS)
- return rc;
- }
-
- return ARES_SUCCESS; /* everything went fine */
-}
-
-/* Save options from initialized channel */
-int ares_save_options(ares_channel channel, struct ares_options *options,
- int *optmask)
-{
- int i, j;
- int ipv4_nservers = 0;
-
- /* Zero everything out */
- memset(options, 0, sizeof(struct ares_options));
-
- if (!ARES_CONFIG_CHECK(channel))
- return ARES_ENODATA;
-
- /* Traditionally the optmask wasn't saved in the channel struct so it was
- recreated here. ROTATE is the first option that has no struct field of
- its own in the public config struct */
- (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
- ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
- ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
- ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
- (channel->optmask & ARES_OPT_ROTATE);
-
- /* Copy easy stuff */
- options->flags = channel->flags;
-
- /* We return full millisecond resolution but that's only because we don't
- set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
- options->timeout = channel->timeout;
- options->tries = channel->tries;
- options->ndots = channel->ndots;
- options->udp_port = (unsigned short)channel->udp_port;
- options->tcp_port = (unsigned short)channel->tcp_port;
- options->sock_state_cb = channel->sock_state_cb;
- options->sock_state_cb_data = channel->sock_state_cb_data;
-
- /* Copy IPv4 servers */
- if (channel->nservers) {
- for (i = 0; i < channel->nservers; i++)
- {
- if (channel->servers[i].addr.family == AF_INET)
- ipv4_nservers++;
- }
- if (ipv4_nservers) {
- options->servers = malloc(ipv4_nservers * sizeof(struct in_addr));
- if (!options->servers)
- return ARES_ENOMEM;
- for (i = j = 0; i < channel->nservers; i++)
- {
- if (channel->servers[i].addr.family == AF_INET)
- memcpy(&options->servers[j++],
- &channel->servers[i].addr.addrV4,
- sizeof(channel->servers[i].addr.addrV4));
- }
- }
- }
- options->nservers = ipv4_nservers;
-
- /* copy domains */
- if (channel->ndomains) {
- options->domains = malloc(channel->ndomains * sizeof(char *));
- if (!options->domains)
- return ARES_ENOMEM;
-
- for (i = 0; i < channel->ndomains; i++)
- {
- options->ndomains = i;
- options->domains[i] = strdup(channel->domains[i]);
- if (!options->domains[i])
- return ARES_ENOMEM;
- }
- }
- options->ndomains = channel->ndomains;
-
- /* copy lookups */
- if (channel->lookups) {
- options->lookups = strdup(channel->lookups);
- if (!options->lookups && channel->lookups)
- return ARES_ENOMEM;
- }
-
- /* copy sortlist */
- if (channel->nsort) {
- options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
- if (!options->sortlist)
- return ARES_ENOMEM;
- for (i = 0; i < channel->nsort; i++)
- options->sortlist[i] = channel->sortlist[i];
- }
- options->nsort = channel->nsort;
-
- return ARES_SUCCESS;
-}
-
-static int init_by_options(ares_channel channel,
- const struct ares_options *options,
- int optmask)
-{
- int i;
-
- /* Easy stuff. */
- if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
- channel->flags = options->flags;
- if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
- channel->timeout = options->timeout;
- else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
- channel->timeout = options->timeout * 1000;
- if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
- channel->tries = options->tries;
- if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
- channel->ndots = options->ndots;
- if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
- channel->rotate = 1;
- if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
- channel->udp_port = options->udp_port;
- if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
- channel->tcp_port = options->tcp_port;
- if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
- {
- channel->sock_state_cb = options->sock_state_cb;
- channel->sock_state_cb_data = options->sock_state_cb_data;
- }
- if ((optmask & ARES_OPT_SOCK_SNDBUF)
- && channel->socket_send_buffer_size == -1)
- channel->socket_send_buffer_size = options->socket_send_buffer_size;
- if ((optmask & ARES_OPT_SOCK_RCVBUF)
- && channel->socket_receive_buffer_size == -1)
- channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
-
- /* Copy the IPv4 servers, if given. */
- if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
- {
- /* Avoid zero size allocations at any cost */
- if (options->nservers > 0)
- {
- channel->servers =
- malloc(options->nservers * sizeof(struct server_state));
- if (!channel->servers)
- return ARES_ENOMEM;
- for (i = 0; i < options->nservers; i++)
- {
- channel->servers[i].addr.family = AF_INET;
- memcpy(&channel->servers[i].addr.addrV4,
- &options->servers[i],
- sizeof(channel->servers[i].addr.addrV4));
- }
- }
- channel->nservers = options->nservers;
- }
-
- /* Copy the domains, if given. Keep channel->ndomains consistent so
- * we can clean up in case of error.
- */
- if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
- {
- /* Avoid zero size allocations at any cost */
- if (options->ndomains > 0)
- {
- channel->domains = malloc(options->ndomains * sizeof(char *));
- if (!channel->domains)
- return ARES_ENOMEM;
- for (i = 0; i < options->ndomains; i++)
- {
- channel->ndomains = i;
- channel->domains[i] = strdup(options->domains[i]);
- if (!channel->domains[i])
- return ARES_ENOMEM;
- }
- }
- channel->ndomains = options->ndomains;
- }
-
- /* Set lookups, if given. */
- if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
- {
- channel->lookups = strdup(options->lookups);
- if (!channel->lookups)
- return ARES_ENOMEM;
- }
-
- /* copy sortlist */
- if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
- (options->nsort>0)) {
- channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
- if (!channel->sortlist)
- return ARES_ENOMEM;
- for (i = 0; i < options->nsort; i++)
- channel->sortlist[i] = options->sortlist[i];
- channel->nsort = options->nsort;
- }
-
- channel->optmask = optmask;
-
- return ARES_SUCCESS;
-}
-
-static int init_by_environment(ares_channel channel)
-{
- const char *localdomain, *res_options;
- int status;
-
- localdomain = getenv("LOCALDOMAIN");
- if (localdomain && channel->ndomains == -1)
- {
- status = set_search(channel, localdomain);
- if (status != ARES_SUCCESS)
- return status;
- }
-
- res_options = getenv("RES_OPTIONS");
- if (res_options)
- {
- status = set_options(channel, res_options);
- if (status != ARES_SUCCESS)
- return status;
- }
-
- return ARES_SUCCESS;
-}
-
-#ifdef WIN32
-/*
- * Warning: returns a dynamically allocated buffer, the user MUST
- * use free() if the function returns 1
- */
-static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
-{
- /* Test for the size we need */
- DWORD size = 0;
- int result;
-
- result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
- if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
- return 0;
- *obuf = malloc(size+1);
- if (!*obuf)
- return 0;
-
- if (RegQueryValueEx(hKey, subkey, 0, NULL,
- (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
- {
- free(*obuf);
- return 0;
- }
- if (size == 1)
- {
- free(*obuf);
- return 0;
- }
- return 1;
-}
-
-static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
-{
- char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
- DWORD enum_size = 39;
- int idx = 0;
- HKEY hVal;
-
- while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
- NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
- {
- int rc;
-
- enum_size = 39;
- if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
- ERROR_SUCCESS)
- continue;
- rc = get_res_nt(hVal, subkey, obuf);
- RegCloseKey(hVal);
- if (rc)
- return 1;
- }
- return 0;
-}
-
-/**
- * The desired output for this method is that we set "ret_buf" to
- * something like:
- *
- * 192.168.0.1,dns01.my.domain,fe80::200:f8ff:fe21:67cf
- *
- * The only ordering requirement is that primary servers are listed
- * before secondary. There is no requirement that IPv4 addresses should
- * necessarily be before IPv6.
- *
- * Note that ret_size should ideally be big enough to hold around
- * 2-3 IPv4 and 2-3 IPv6 addresses.
- *
- * Finally, we need to return the total number of DNS servers located.
- */
-static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
-{
- const size_t ipv4_size = INET_ADDRSTRLEN + 1; /* +1 for ',' at end */
- const size_t ipv6_size = INET6_ADDRSTRLEN + 12; /* +12 for "%0123456789," at end */
- size_t left = ret_size;
- char *ret = ret_buf;
- int count = 0;
-
- /* Use the GetAdaptersAddresses method if it's available, otherwise
- fall back to GetNetworkParams. */
- if (ares_fpGetAdaptersAddresses != ZERO_NULL)
- {
- const ULONG working_buf_size = 15000;
- IP_ADAPTER_ADDRESSES *pFirstEntry = NULL;
- IP_ADAPTER_ADDRESSES *pEntry = NULL;
- ULONG bufSize = 0;
- ULONG result = 0;
-
- /* According to MSDN, the recommended way to do this is to use a temporary
- buffer of 15K, to "dramatically reduce the chance that the GetAdaptersAddresses
- method returns ERROR_BUFFER_OVERFLOW" */
- pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) malloc( working_buf_size );
- bufSize = working_buf_size;
- if( !pFirstEntry )
- return 0;
-
- /* Call the method one time */
- result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
- if( result == ERROR_BUFFER_OVERFLOW )
- {
- /* Reallocate, bufSize should now be set to the required size */
- pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
- if( !pFirstEntry )
- return 0;
-
- /* Call the method a second time */
- result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
- if( result == ERROR_BUFFER_OVERFLOW )
- {
- /* Reallocate, bufSize should now be set to the required size */
- pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
- if( !pFirstEntry )
- return 0;
-
- /* Call the method a third time. The maximum number of times we're going to do
- this is 3. Three shall be the number thou shalt count, and the number of the
- counting shall be three. Five is right out. */
- result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
- }
- }
-
- /* Check the current result for failure */
- if( result != ERROR_SUCCESS )
- {
- free( pFirstEntry );
- return 0;
- }
-
- /* process the results */
- for( pEntry = pFirstEntry ; pEntry != NULL ; pEntry = pEntry->Next )
- {
- IP_ADAPTER_DNS_SERVER_ADDRESS* pDNSAddr = pEntry->FirstDnsServerAddress;
- for( ; pDNSAddr != NULL ; pDNSAddr = pDNSAddr->Next )
- {
- struct sockaddr *pGenericAddr = pDNSAddr->Address.lpSockaddr;
- size_t stringlen = 0;
-
- if( pGenericAddr->sa_family == AF_INET && left > ipv4_size )
- {
- /* Handle the v4 case */
- struct sockaddr_in *pIPv4Addr = ( struct sockaddr_in * ) pGenericAddr;
- ares_inet_ntop( AF_INET, &pIPv4Addr->sin_addr, ret, ipv4_size - 1 ); /* -1 for comma */
-
- /* Append a comma to the end, THEN NULL. Should be OK because we
- already tested the size at the top of the if statement. */
- stringlen = strlen( ret );
- ret[ stringlen ] = ',';
- ret[ stringlen + 1 ] = '\0';
- ret += stringlen + 1;
- left -= ret - ret_buf;
- ++count;
- }
- else if( pGenericAddr->sa_family == AF_INET6 && left > ipv6_size )
- {
- /* Handle the v6 case */
- struct sockaddr_in6 *pIPv6Addr = ( struct sockaddr_in6 * ) pGenericAddr;
- ares_inet_ntop( AF_INET6, &pIPv6Addr->sin6_addr, ret, ipv6_size - 1 ); /* -1 for comma */
-
- stringlen = strlen( ret );
-
- /* Windows apparently always reports some IPv6 DNS servers that
- prefixed with fec0:0:0:ffff. These ususally do not point to
- working DNS servers, so we ignore them. */
- if (strncmp(ret, "fec0:0:0:ffff:", 14) != 0) {
- /* Append a comma to the end, THEN NULL. Should be OK because we
- already tested the size at the top of the if statement. */
- ret[ stringlen ] = ',';
- ret[ stringlen + 1 ] = '\0';
- ret += stringlen + 1;
- left -= ret - ret_buf;
- ++count;
- }
- }
- }
- }
-
- if( pFirstEntry )
- free( pFirstEntry );
- if (ret > ret_buf)
- ret[-1] = '\0';
- return count;
- }
- else
- {
- FIXED_INFO *fi, *newfi;
- DWORD size = sizeof (*fi);
- IP_ADDR_STRING *ipAddr;
- int i;
- int debug = 0;
- HRESULT res;
-
- fi = malloc(size);
- if (!fi)
- return 0;
-
- res = (*ares_fpGetNetworkParams) (fi, &size);
- if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
- goto quit;
-
- newfi = realloc(fi, size);
- if (!newfi)
- goto quit;
-
- fi = newfi;
- res = (*ares_fpGetNetworkParams) (fi, &size);
- if (res != ERROR_SUCCESS)
- goto quit;
-
- if (debug)
- {
- printf ("Host Name: %s\n", fi->HostName);
- printf ("Domain Name: %s\n", fi->DomainName);
- printf ("DNS Servers:\n"
- " %s (primary)\n", fi->DnsServerList.IpAddress.String);
- }
- if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
- inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
- left > ipv4_size)
- {
- ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
- left -= ret - ret_buf;
- ++count;
- }
-
- for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ipv4_size;
- ipAddr = ipAddr->Next, i++)
- {
- if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
- {
- ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
- left -= ret - ret_buf;
- ++count;
- }
- if (debug)
- printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
- }
-
-quit:
- if (fi)
- free(fi);
-
- if (debug && left <= ipv4_size)
- printf ("Too many nameservers. Truncating to %d addressess", count);
- if (ret > ret_buf)
- ret[-1] = '\0';
- return count;
- }
-}
-#endif
-
-static int init_by_resolv_conf(ares_channel channel)
-{
-#ifndef WATT32
- char *line = NULL;
-#endif
- int status = -1, nservers = 0, nsort = 0;
- struct server_state *servers = NULL;
- struct apattern *sortlist = NULL;
-
-#ifdef WIN32
-
- /*
- NameServer info via IPHLPAPI (IP helper API):
- GetNetworkParams() should be the trusted source for this.
- Available in Win-98/2000 and later. If that fail, fall-back to
- registry information.
-
- NameServer Registry:
-
- On Windows 9X, the DNS server can be found in:
-HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
-
- On Windows NT/2000/XP/2003:
-HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
- or
-HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
- or
-HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
-NameServer
- or
-HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
-DhcpNameServer
- */
-
- HKEY mykey;
- HKEY subkey;
- DWORD data_type;
- DWORD bytes;
- DWORD result;
- char buf[512];
- win_platform platform;
-
- if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
- return ARES_SUCCESS;
-
- if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
- {
- status = config_nameserver(&servers, &nservers, buf);
- if (status == ARES_SUCCESS)
- goto okay;
- }
-
- platform = ares__getplatform();
-
- if (platform == WIN_NT)
- {
- if (RegOpenKeyEx(
- HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
- KEY_READ, &mykey
- ) == ERROR_SUCCESS)
- {
- RegOpenKeyEx(mykey, "Interfaces", 0,
- KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
- if (get_res_nt(mykey, NAMESERVER, &line))
- {
- status = config_nameserver(&servers, &nservers, line);
- free(line);
- }
- else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
- {
- status = config_nameserver(&servers, &nservers, line);
- free(line);
- }
- /* Try the interfaces */
- else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
- {
- status = config_nameserver(&servers, &nservers, line);
- free(line);
- }
- else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
- {
- status = config_nameserver(&servers, &nservers, line);
- free(line);
- }
- RegCloseKey(subkey);
- RegCloseKey(mykey);
- }
- }
- else if (platform == WIN_9X)
- {
- if (RegOpenKeyEx(
- HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
- KEY_READ, &mykey
- ) == ERROR_SUCCESS)
- {
- if ((result = RegQueryValueEx(
- mykey, NAMESERVER, NULL, &data_type,
- NULL, &bytes
- )
- ) == ERROR_SUCCESS ||
- result == ERROR_MORE_DATA)
- {
- if (bytes)
- {
- line = malloc(bytes+1);
- if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
- (unsigned char *)line, &bytes) ==
- ERROR_SUCCESS)
- {
- status = config_nameserver(&servers, &nservers, line);
- }
- free(line);
- }
- }
- }
- RegCloseKey(mykey);
- }
-
- if (status == ARES_SUCCESS)
- status = ARES_EOF;
- else
- /* Catch the case when all the above checks fail (which happens when there
- is no network card or the cable is unplugged) */
- status = ARES_EFILE;
-
-#elif defined(__riscos__)
-
- /* Under RISC OS, name servers are listed in the
- system variable Inet$Resolvers, space separated. */
-
- line = getenv("Inet$Resolvers");
- status = ARES_EOF;
- if (line) {
- char *resolvers = strdup(line), *pos, *space;
-
- if (!resolvers)
- return ARES_ENOMEM;
-
- pos = resolvers;
- do {
- space = strchr(pos, ' ');
- if (space)
- *space = '\0';
- status = config_nameserver(&servers, &nservers, pos);
- if (status != ARES_SUCCESS)
- break;
- pos = space + 1;
- } while (space);
-
- if (status == ARES_SUCCESS)
- status = ARES_EOF;
-
- free(resolvers);
- }
-
-#elif defined(WATT32)
- int i;
-
- sock_init();
- for (i = 0; def_nameservers[i]; i++)
- ;
- if (i == 0)
- return ARES_SUCCESS; /* use localhost DNS server */
-
- nservers = i;
- servers = calloc(i, sizeof(struct server_state));
- if (!servers)
- return ARES_ENOMEM;
-
- for (i = 0; def_nameservers[i]; i++)
- {
- servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
- servers[i].addr.family = AF_INET;
- }
- status = ARES_EOF;
-
-#elif defined(ANDROID)
- char value[PROP_VALUE_MAX]="";
- __system_property_get("net.dns1", value);
- status = config_nameserver(&servers, &nservers, value);
- if (status == ARES_SUCCESS)
- status = ARES_EOF;
-#else
- {
- char *p;
- FILE *fp;
- size_t linesize;
- int error;
-
- /* Don't read resolv.conf and friends if we don't have to */
- if (ARES_CONFIG_CHECK(channel))
- return ARES_SUCCESS;
-
- fp = fopen(PATH_RESOLV_CONF, "r");
- if (fp) {
- while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
- {
- if ((p = try_config(line, "domain", ';')))
- status = config_domain(channel, p);
- else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
- status = config_lookup(channel, p, "bind", "file");
- else if ((p = try_config(line, "search", ';')))
- status = set_search(channel, p);
- else if ((p = try_config(line, "nameserver", ';')) &&
- channel->nservers == -1)
- status = config_nameserver(&servers, &nservers, p);
- else if ((p = try_config(line, "sortlist", ';')) &&
- channel->nsort == -1)
- status = config_sortlist(&sortlist, &nsort, p);
- else if ((p = try_config(line, "options", ';')))
- status = set_options(channel, p);
- else
- status = ARES_SUCCESS;
- if (status != ARES_SUCCESS)
- break;
- }
- fclose(fp);
- }
- else {
- error = ERRNO;
- switch(error) {
- case ENOENT:
- case ESRCH:
- status = ARES_EOF;
- break;
- default:
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
- error, strerror(error)));
- DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
- status = ARES_EFILE;
- }
- }
-
- if ((status == ARES_EOF) && (!channel->lookups)) {
- /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
- fp = fopen("/etc/nsswitch.conf", "r");
- if (fp) {
- while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
- {
- if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
- /* ignore errors */
- (void)config_lookup(channel, p, "dns", "files");
- }
- fclose(fp);
- }
- else {
- error = ERRNO;
- switch(error) {
- case ENOENT:
- case ESRCH:
- status = ARES_EOF;
- break;
- default:
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
- error, strerror(error)));
- DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
- status = ARES_EFILE;
- }
- }
- }
-
- if ((status == ARES_EOF) && (!channel->lookups)) {
- /* Linux / GNU libc 2.x and possibly others have host.conf */
- fp = fopen("/etc/host.conf", "r");
- if (fp) {
- while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
- {
- if ((p = try_config(line, "order", '\0')) && !channel->lookups)
- /* ignore errors */
- (void)config_lookup(channel, p, "bind", "hosts");
- }
- fclose(fp);
- }
- else {
- error = ERRNO;
- switch(error) {
- case ENOENT:
- case ESRCH:
- status = ARES_EOF;
- break;
- default:
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
- error, strerror(error)));
- DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
- status = ARES_EFILE;
- }
- }
- }
-
- if ((status == ARES_EOF) && (!channel->lookups)) {
- /* Tru64 uses /etc/svc.conf */
- fp = fopen("/etc/svc.conf", "r");
- if (fp) {
- while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
- {
- if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
- /* ignore errors */
- (void)config_lookup(channel, p, "bind", "local");
- }
- fclose(fp);
- }
- else {
- error = ERRNO;
- switch(error) {
- case ENOENT:
- case ESRCH:
- status = ARES_EOF;
- break;
- default:
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
- error, strerror(error)));
- DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
- status = ARES_EFILE;
- }
- }
- }
-
- if(line)
- free(line);
- }
-
-#endif
-
- /* Handle errors. */
- if (status != ARES_EOF)
- {
- if (servers != NULL)
- free(servers);
- if (sortlist != NULL)
- free(sortlist);
- return status;
- }
-
- /* If we got any name server entries, fill them in. */
-#ifdef WIN32
-okay:
-#endif
- if (servers)
- {
- channel->servers = servers;
- channel->nservers = nservers;
- }
-
- /* If we got any sortlist entries, fill them in. */
- if (sortlist)
- {
- channel->sortlist = sortlist;
- channel->nsort = nsort;
- }
-
- return ARES_SUCCESS;
-}
-
-static int init_by_defaults(ares_channel channel)
-{
- char *hostname = NULL;
- int rc = ARES_SUCCESS;
-#ifdef HAVE_GETHOSTNAME
- char *dot;
-#endif
-
- if (channel->flags == -1)
- channel->flags = 0;
- if (channel->timeout == -1)
- channel->timeout = DEFAULT_TIMEOUT;
- if (channel->tries == -1)
- channel->tries = DEFAULT_TRIES;
- if (channel->ndots == -1)
- channel->ndots = 1;
- if (channel->rotate == -1)
- channel->rotate = 0;
- if (channel->udp_port == -1)
- channel->udp_port = htons(NAMESERVER_PORT);
- if (channel->tcp_port == -1)
- channel->tcp_port = htons(NAMESERVER_PORT);
-
- if (channel->nservers == -1) {
- /* If nobody specified servers, try a local named. */
- channel->servers = malloc(sizeof(struct server_state));
- if (!channel->servers) {
- rc = ARES_ENOMEM;
- goto error;
- }
- channel->servers[0].addr.family = AF_INET;
- channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
- channel->nservers = 1;
- }
-
-#if defined(USE_WINSOCK)
-#define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
-#elif defined(ENAMETOOLONG)
-#define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
- (SOCKERRNO == EINVAL))
-#else
-#define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
-#endif
-
- if (channel->ndomains == -1) {
- /* Derive a default domain search list from the kernel hostname,
- * or set it to empty if the hostname isn't helpful.
- */
- size_t len = 64;
- int res;
- channel->ndomains = 0; /* default to none */
-
-#ifdef HAVE_GETHOSTNAME
- hostname = malloc(len);
- if(!hostname) {
- rc = ARES_ENOMEM;
- goto error;
- }
-
- do {
- res = gethostname(hostname, len);
-
- if(toolong(res)) {
- char *p;
- len *= 2;
- p = realloc(hostname, len);
- if(!p) {
- rc = ARES_ENOMEM;
- goto error;
- }
- hostname = p;
- continue;
- }
- else if(res) {
- rc = ARES_EBADNAME;
- goto error;
- }
-
- } while(0);
-
- dot = strchr(hostname, '.');
- if (dot) {
- /* a dot was found */
- channel->domains = malloc(sizeof(char *));
- if (!channel->domains) {
- rc = ARES_ENOMEM;
- goto error;
- }
- channel->domains[0] = strdup(dot + 1);
- if (!channel->domains[0]) {
- rc = ARES_ENOMEM;
- goto error;
- }
- channel->ndomains = 1;
- }
-#endif
- }
-
- if (channel->nsort == -1) {
- channel->sortlist = NULL;
- channel->nsort = 0;
- }
-
- if (!channel->lookups) {
- channel->lookups = strdup("fb");
- if (!channel->lookups)
- rc = ARES_ENOMEM;
- }
-
- error:
- if(rc) {
- if(channel->servers)
- free(channel->servers);
-
- if(channel->domains && channel->domains[0])
- free(channel->domains[0]);
- if(channel->domains)
- free(channel->domains);
- if(channel->lookups)
- free(channel->lookups);
- }
-
- if(hostname)
- free(hostname);
-
- return rc;
-}
-
-#if !defined(WIN32) && !defined(WATT32)
-static int config_domain(ares_channel channel, char *str)
-{
- char *q;
-
- /* Set a single search domain. */
- q = str;
- while (*q && !ISSPACE(*q))
- q++;
- *q = '\0';
- return set_search(channel, str);
-}
-
-#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
- defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
- /* workaround icc 9.1 optimizer issue */
-# define vqualifier volatile
-#else
-# define vqualifier
-#endif
-
-static int config_lookup(ares_channel channel, const char *str,
- const char *bindch, const char *filech)
-{
- char lookups[3], *l;
- const char *vqualifier p;
-
- /* Set the lookup order. Only the first letter of each work
- * is relevant, and it has to be "b" for DNS or "f" for the
- * host file. Ignore everything else.
- */
- l = lookups;
- p = str;
- while (*p)
- {
- if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
- if (*p == *bindch) *l++ = 'b';
- else *l++ = 'f';
- }
- while (*p && !ISSPACE(*p) && (*p != ','))
- p++;
- while (*p && (ISSPACE(*p) || (*p == ',')))
- p++;
- }
- *l = '\0';
- channel->lookups = strdup(lookups);
- return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
-}
-#endif /* !WIN32 & !WATT32 */
-
-#ifndef WATT32
-static int config_nameserver(struct server_state **servers, int *nservers,
- char *str)
-{
- struct ares_addr host;
- struct server_state *newserv;
- char *p, *txtaddr;
- /* On Windows, there may be more than one nameserver specified in the same
- * registry key, so we parse input as a space or comma seperated list.
- */
- for (p = str; p;)
- {
- /* Skip whitespace and commas. */
- while (*p && (ISSPACE(*p) || (*p == ',')))
- p++;
- if (!*p)
- /* No more input, done. */
- break;
-
- /* Pointer to start of IPv4 or IPv6 address part. */
- txtaddr = p;
-
- /* Advance past this address. */
- while (*p && !ISSPACE(*p) && (*p != ','))
- p++;
- if (*p)
- /* Null terminate this address. */
- *p++ = '\0';
- else
- /* Reached end of input, done when this address is processed. */
- p = NULL;
-
- /* Convert textual address to binary format. */
- if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
- host.family = AF_INET;
- else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
- host.family = AF_INET6;
- else
- continue;
-
- /* Resize servers state array. */
- newserv = realloc(*servers, (*nservers + 1) *
- sizeof(struct server_state));
- if (!newserv)
- return ARES_ENOMEM;
-
- /* Store address data. */
- newserv[*nservers].addr.family = host.family;
- if (host.family == AF_INET)
- memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
- sizeof(host.addrV4));
- else
- memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
- sizeof(host.addrV6));
-
- /* Update arguments. */
- *servers = newserv;
- *nservers += 1;
- }
-
- return ARES_SUCCESS;
-}
-
-#ifndef WIN32
-static int config_sortlist(struct apattern **sortlist, int *nsort,
- const char *str)
-{
- struct apattern pat;
- const char *q;
-
- /* Add sortlist entries. */
- while (*str && *str != ';')
- {
- int bits;
- char ipbuf[16], ipbufpfx[32];
- /* Find just the IP */
- q = str;
- while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
- q++;
- memcpy(ipbuf, str, q-str);
- ipbuf[q-str] = '\0';
- /* Find the prefix */
- if (*q == '/')
- {
- const char *str2 = q+1;
- while (*q && *q != ';' && !ISSPACE(*q))
- q++;
- memcpy(ipbufpfx, str, q-str);
- ipbufpfx[q-str] = '\0';
- str = str2;
- }
- else
- ipbufpfx[0] = '\0';
- /* Lets see if it is CIDR */
- /* First we'll try IPv6 */
- if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
- &pat.addrV6,
- sizeof(pat.addrV6))) > 0)
- {
- pat.type = PATTERN_CIDR;
- pat.mask.bits = (unsigned short)bits;
- pat.family = AF_INET6;
- if (!sortlist_alloc(sortlist, nsort, &pat))
- return ARES_ENOMEM;
- }
- else if (ipbufpfx[0] &&
- (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
- sizeof(pat.addrV4))) > 0)
- {
- pat.type = PATTERN_CIDR;
- pat.mask.bits = (unsigned short)bits;
- pat.family = AF_INET;
- if (!sortlist_alloc(sortlist, nsort, &pat))
- return ARES_ENOMEM;
- }
- /* See if it is just a regular IP */
- else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
- {
- if (ipbufpfx[0])
- {
- memcpy(ipbuf, str, q-str);
- ipbuf[q-str] = '\0';
- if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
- natural_mask(&pat);
- }
- else
- natural_mask(&pat);
- pat.family = AF_INET;
- pat.type = PATTERN_MASK;
- if (!sortlist_alloc(sortlist, nsort, &pat))
- return ARES_ENOMEM;
- }
- else
- {
- while (*q && *q != ';' && !ISSPACE(*q))
- q++;
- }
- str = q;
- while (ISSPACE(*str))
- str++;
- }
-
- return ARES_SUCCESS;
-}
-#endif /* !WIN32 */
-#endif /* !WATT32 */
-
-static int set_search(ares_channel channel, const char *str)
-{
- int n;
- const char *p, *q;
-
- if(channel->ndomains != -1) {
- /* if we already have some domains present, free them first */
- for(n=0; n < channel->ndomains; n++)
- free(channel->domains[n]);
- free(channel->domains);
- channel->domains = NULL;
- channel->ndomains = -1;
- }
-
- /* Count the domains given. */
- n = 0;
- p = str;
- while (*p)
- {
- while (*p && !ISSPACE(*p))
- p++;
- while (ISSPACE(*p))
- p++;
- n++;
- }
-
- if (!n)
- {
- channel->ndomains = 0;
- return ARES_SUCCESS;
- }
-
- channel->domains = malloc(n * sizeof(char *));
- if (!channel->domains)
- return ARES_ENOMEM;
-
- /* Now copy the domains. */
- n = 0;
- p = str;
- while (*p)
- {
- channel->ndomains = n;
- q = p;
- while (*q && !ISSPACE(*q))
- q++;
- channel->domains[n] = malloc(q - p + 1);
- if (!channel->domains[n])
- return ARES_ENOMEM;
- memcpy(channel->domains[n], p, q - p);
- channel->domains[n][q - p] = 0;
- p = q;
- while (ISSPACE(*p))
- p++;
- n++;
- }
- channel->ndomains = n;
-
- return ARES_SUCCESS;
-}
-
-static int set_options(ares_channel channel, const char *str)
-{
- const char *p, *q, *val;
-
- p = str;
- while (*p)
- {
- q = p;
- while (*q && !ISSPACE(*q))
- q++;
- val = try_option(p, q, "ndots:");
- if (val && channel->ndots == -1)
- channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
- val = try_option(p, q, "retrans:");
- if (val && channel->timeout == -1)
- channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
- val = try_option(p, q, "retry:");
- if (val && channel->tries == -1)
- channel->tries = aresx_sltosi(strtol(val, NULL, 10));
- val = try_option(p, q, "rotate");
- if (val && channel->rotate == -1)
- channel->rotate = 1;
- p = q;
- while (ISSPACE(*p))
- p++;
- }
-
- return ARES_SUCCESS;
-}
-
-static const char *try_option(const char *p, const char *q, const char *opt)
-{
- size_t len = strlen(opt);
- return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
-}
-
-#if !defined(WIN32) && !defined(WATT32)
-static char *try_config(char *s, const char *opt, char scc)
-{
- size_t len;
- char *p;
- char *q;
-
- if (!s || !opt)
- /* no line or no option */
- return NULL;
-
- /* Hash '#' character is always used as primary comment char, additionally
- a not-NUL secondary comment char will be considered when specified. */
-
- /* trim line comment */
- p = s;
- if(scc)
- while (*p && (*p != '#') && (*p != scc))
- p++;
- else
- while (*p && (*p != '#'))
- p++;
- *p = '\0';
-
- /* trim trailing whitespace */
- q = p - 1;
- while ((q >= s) && ISSPACE(*q))
- q--;
- *++q = '\0';
-
- /* skip leading whitespace */
- p = s;
- while (*p && ISSPACE(*p))
- p++;
-
- if (!*p)
- /* empty line */
- return NULL;
-
- if ((len = strlen(opt)) == 0)
- /* empty option */
- return NULL;
-
- if (strncmp(p, opt, len) != 0)
- /* line and option do not match */
- return NULL;
-
- /* skip over given option name */
- p += len;
-
- if (!*p)
- /* no option value */
- return NULL;
-
- if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
- /* whitespace between option name and value is mandatory
- for given option names which do not end with ':' or '=' */
- return NULL;
-
- /* skip over whitespace */
- while (*p && ISSPACE(*p))
- p++;
-
- if (!*p)
- /* no option value */
- return NULL;
-
- /* return pointer to option value */
- return p;
-}
-
-static int sortlist_alloc(struct apattern **sortlist, int *nsort,
- struct apattern *pat)
-{
- struct apattern *newsort;
- newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
- if (!newsort)
- return 0;
- newsort[*nsort] = *pat;
- *sortlist = newsort;
- (*nsort)++;
- return 1;
-}
-
-static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
-{
-
- /* Four octets and three periods yields at most 15 characters. */
- if (len > 15)
- return -1;
-
- addr->s_addr = inet_addr(ipbuf);
- if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
- return -1;
- return 0;
-}
-
-static void natural_mask(struct apattern *pat)
-{
- struct in_addr addr;
-
- /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
- * but portable.
- */
- addr.s_addr = ntohl(pat->addrV4.s_addr);
-
- /* This is out of date in the CIDR world, but some people might
- * still rely on it.
- */
- if (IN_CLASSA(addr.s_addr))
- pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
- else if (IN_CLASSB(addr.s_addr))
- pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
- else
- pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
-}
-#endif /* !WIN32 && !WATT32 */
-
-/* initialize an rc4 key. If possible a cryptographically secure random key
- is generated using a suitable function (for example win32's RtlGenRandom as
- described in
- http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
- otherwise the code defaults to cross-platform albeit less secure mechanism
- using rand
-*/
-static void randomize_key(unsigned char* key,int key_data_len)
-{
- int randomized = 0;
- int counter=0;
-#ifdef WIN32
- BOOLEAN res;
- if (ares_fpSystemFunction036)
- {
- res = (*ares_fpSystemFunction036) (key, key_data_len);
- if (res)
- randomized = 1;
- }
-#else /* !WIN32 */
-#ifdef RANDOM_FILE
- FILE *f = fopen(RANDOM_FILE, "rb");
- if(f) {
- counter = aresx_uztosi(fread(key, 1, key_data_len, f));
- fclose(f);
- }
-#endif
-#endif /* WIN32 */
-
- if ( !randomized ) {
- for (;counter<key_data_len;counter++)
- key[counter]=(unsigned char)(rand() % 256);
- }
-}
-
-static int init_id_key(rc4_key* key,int key_data_len)
-{
- unsigned char index1;
- unsigned char index2;
- unsigned char* state;
- short counter;
- unsigned char *key_data_ptr = 0;
-
- key_data_ptr = calloc(1,key_data_len);
- if (!key_data_ptr)
- return ARES_ENOMEM;
-
- state = &key->state[0];
- for(counter = 0; counter < 256; counter++)
- /* unnecessary AND but it keeps some compilers happier */
- state[counter] = (unsigned char)(counter & 0xff);
- randomize_key(key->state,key_data_len);
- key->x = 0;
- key->y = 0;
- index1 = 0;
- index2 = 0;
- for(counter = 0; counter < 256; counter++)
- {
- index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
- index2) % 256);
- ARES_SWAP_BYTE(&state[counter], &state[index2]);
-
- index1 = (unsigned char)((index1 + 1) % key_data_len);
- }
- free(key_data_ptr);
- return ARES_SUCCESS;
-}
-
-unsigned short ares__generate_new_id(rc4_key* key)
-{
- unsigned short r=0;
- ares__rc4(key, (unsigned char *)&r, sizeof(r));
- return r;
-}
-
-void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
-{
- channel->local_ip4 = local_ip;
-}
-
-/* local_ip6 should be 16 bytes in length */
-void ares_set_local_ip6(ares_channel channel,
- const unsigned char* local_ip6)
-{
- memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
-}
-
-/* local_dev_name should be null terminated. */
-void ares_set_local_dev(ares_channel channel,
- const char* local_dev_name)
-{
- strncpy(channel->local_dev_name, local_dev_name,
- sizeof(channel->local_dev_name));
- channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
-}
-
-
-void ares_set_socket_callback(ares_channel channel,
- ares_sock_create_callback cb,
- void *data)
-{
- channel->sock_create_cb = cb;
- channel->sock_create_cb_data = data;
-}
-
-void ares__init_servers_state(ares_channel channel)
-{
- struct server_state *server;
- int i;
-
- for (i = 0; i < channel->nservers; i++)
- {
- server = &channel->servers[i];
- server->udp_socket = ARES_SOCKET_BAD;
- server->tcp_socket = ARES_SOCKET_BAD;
- server->tcp_connection_generation = ++channel->tcp_connection_generation;
- server->tcp_lenbuf_pos = 0;
- server->tcp_buffer_pos = 0;
- server->tcp_buffer = NULL;
- server->tcp_length = 0;
- server->qhead = NULL;
- server->qtail = NULL;
- ares__init_list_head(&server->queries_to_server);
- server->channel = channel;
- server->is_broken = 0;
- }
-}
diff --git a/deps/uv/src/ares/ares_library_init.h b/deps/uv/src/ares/ares_library_init.h
deleted file mode 100644
index cbbfc6afb..000000000
--- a/deps/uv/src/ares/ares_library_init.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef HEADER_CARES_LIBRARY_INIT_H
-#define HEADER_CARES_LIBRARY_INIT_H
-
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright (C) 2004-2011 by Daniel Stenberg
- *
- * 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.
- */
-
-#include "ares_setup.h"
-
-#ifdef USE_WINSOCK
-
-#include <iphlpapi.h>
-#include "ares_iphlpapi.h"
-
-typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*);
-typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG);
-typedef ULONG (WINAPI *fpGetAdaptersAddresses_t) ( ULONG, ULONG, void*, IP_ADAPTER_ADDRESSES*, ULONG* );
-
-/* Forward-declaration of variables defined in ares_library_init.c */
-/* that are global and unique instances for whole c-ares library. */
-
-extern fpGetNetworkParams_t ares_fpGetNetworkParams;
-extern fpSystemFunction036_t ares_fpSystemFunction036;
-extern fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses;
-
-#endif /* USE_WINSOCK */
-
-#endif /* HEADER_CARES_LIBRARY_INIT_H */
-
diff --git a/deps/uv/src/ares/ares_nowarn.c b/deps/uv/src/ares/ares_nowarn.c
deleted file mode 100644
index 701add58c..000000000
--- a/deps/uv/src/ares/ares_nowarn.c
+++ /dev/null
@@ -1,181 +0,0 @@
-
-/* Copyright (C) 2010-2011 by Daniel Stenberg
- *
- * 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.
- */
-
-
-#include "ares_setup.h"
-
-#ifdef HAVE_ASSERT_H
-# include <assert.h>
-#endif
-
-#if defined(__INTEL_COMPILER) && defined(__unix__)
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-
-#endif /* __INTEL_COMPILER && __unix__ */
-
-#define BUILDING_ARES_NOWARN_C 1
-
-#include "ares_nowarn.h"
-
-#if (SIZEOF_INT == 2)
-# define CARES_MASK_SINT 0x7FFF
-# define CARES_MASK_UINT 0xFFFF
-#elif (SIZEOF_INT == 4)
-# define CARES_MASK_SINT 0x7FFFFFFF
-# define CARES_MASK_UINT 0xFFFFFFFF
-#elif (SIZEOF_INT == 8)
-# define CARES_MASK_SINT 0x7FFFFFFFFFFFFFFF
-# define CARES_MASK_UINT 0xFFFFFFFFFFFFFFFF
-#elif (SIZEOF_INT == 16)
-# define CARES_MASK_SINT 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
-# define CARES_MASK_UINT 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
-#endif
-
-/*
-** unsigned size_t to signed int
-*/
-
-int aresx_uztosi(size_t uznum)
-{
-#ifdef __INTEL_COMPILER
-# pragma warning(push)
-# pragma warning(disable:810) /* conversion may lose significant bits */
-#endif
-
- return (int)(uznum & (size_t) CARES_MASK_SINT);
-
-#ifdef __INTEL_COMPILER
-# pragma warning(pop)
-#endif
-}
-
-/*
-** signed long to signed int
-*/
-
-int aresx_sltosi(long slnum)
-{
-#ifdef __INTEL_COMPILER
-# pragma warning(push)
-# pragma warning(disable:810) /* conversion may lose significant bits */
-#endif
-
- DEBUGASSERT(slnum >= 0);
- return (int)(slnum & (long) CARES_MASK_SINT);
-
-#ifdef __INTEL_COMPILER
-# pragma warning(pop)
-#endif
-}
-
-/*
-** signed ssize_t to signed int
-*/
-
-int aresx_sztosi(ssize_t sznum)
-{
-#ifdef __INTEL_COMPILER
-# pragma warning(push)
-# pragma warning(disable:810) /* conversion may lose significant bits */
-#endif
-
- DEBUGASSERT(sznum >= 0);
- return (int)(sznum & (ssize_t) CARES_MASK_SINT);
-
-#ifdef __INTEL_COMPILER
-# pragma warning(pop)
-#endif
-}
-
-/*
-** signed ssize_t to unsigned int
-*/
-
-unsigned int aresx_sztoui(ssize_t sznum)
-{
-#ifdef __INTEL_COMPILER
-# pragma warning(push)
-# pragma warning(disable:810) /* conversion may lose significant bits */
-#endif
-
- DEBUGASSERT(sznum >= 0);
- return (unsigned int)(sznum & (ssize_t) CARES_MASK_UINT);
-
-#ifdef __INTEL_COMPILER
-# pragma warning(pop)
-#endif
-}
-
-#if defined(__INTEL_COMPILER) && defined(__unix__)
-
-int aresx_FD_ISSET(int fd, fd_set *fdset)
-{
- #pragma warning(push)
- #pragma warning(disable:1469) /* clobber ignored */
- return FD_ISSET(fd, fdset);
- #pragma warning(pop)
-}
-
-void aresx_FD_SET(int fd, fd_set *fdset)
-{
- #pragma warning(push)
- #pragma warning(disable:1469) /* clobber ignored */
- FD_SET(fd, fdset);
- #pragma warning(pop)
-}
-
-void aresx_FD_ZERO(fd_set *fdset)
-{
- #pragma warning(push)
- #pragma warning(disable:593) /* variable was set but never used */
- FD_ZERO(fdset);
- #pragma warning(pop)
-}
-
-unsigned short aresx_htons(unsigned short usnum)
-{
-#if (__INTEL_COMPILER == 910) && defined(__i386__)
- return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
-#else
- #pragma warning(push)
- #pragma warning(disable:810) /* conversion may lose significant bits */
- return htons(usnum);
- #pragma warning(pop)
-#endif
-}
-
-unsigned short aresx_ntohs(unsigned short usnum)
-{
-#if (__INTEL_COMPILER == 910) && defined(__i386__)
- return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
-#else
- #pragma warning(push)
- #pragma warning(disable:810) /* conversion may lose significant bits */
- return ntohs(usnum);
- #pragma warning(pop)
-#endif
-}
-
-#endif /* __INTEL_COMPILER && __unix__ */
diff --git a/deps/uv/src/ares/ares_nowarn.h b/deps/uv/src/ares/ares_nowarn.h
deleted file mode 100644
index bcaa22721..000000000
--- a/deps/uv/src/ares/ares_nowarn.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef HEADER_CARES_NOWARN_H
-#define HEADER_CARES_NOWARN_H
-
-
-/* Copyright (C) 2010-2011 by Daniel Stenberg
- *
- * 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.
- */
-
-int aresx_uztosi(size_t uznum);
-
-int aresx_sltosi(long slnum);
-
-int aresx_sztosi(ssize_t sznum);
-
-unsigned int aresx_sztoui(ssize_t sznum);
-
-#if defined(__INTEL_COMPILER) && defined(__unix__)
-
-int aresx_FD_ISSET(int fd, fd_set *fdset);
-
-void aresx_FD_SET(int fd, fd_set *fdset);
-
-void aresx_FD_ZERO(fd_set *fdset);
-
-unsigned short aresx_htons(unsigned short usnum);
-
-unsigned short aresx_ntohs(unsigned short usnum);
-
-#ifndef BUILDING_ARES_NOWARN_C
-# undef FD_ISSET
-# define FD_ISSET(a,b) aresx_FD_ISSET((a),(b))
-# undef FD_SET
-# define FD_SET(a,b) aresx_FD_SET((a),(b))
-# undef FD_ZERO
-# define FD_ZERO(a) aresx_FD_ZERO((a))
-# undef htons
-# define htons(a) aresx_htons((a))
-# undef ntohs
-# define ntohs(a) aresx_ntohs((a))
-#endif
-
-#endif /* __INTEL_COMPILER && __unix__ */
-
-#endif /* HEADER_CARES_NOWARN_H */
diff --git a/deps/uv/src/ares/ares_parse_aaaa_reply.c b/deps/uv/src/ares/ares_parse_aaaa_reply.c
deleted file mode 100644
index 1fbe8389f..000000000
--- a/deps/uv/src/ares/ares_parse_aaaa_reply.c
+++ /dev/null
@@ -1,259 +0,0 @@
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright 2005 Dominick Meglio
- *
- * 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.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#include "ares.h"
-#include "ares_dns.h"
-#include "inet_net_pton.h"
-#include "ares_private.h"
-
-int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
- struct hostent **host, struct ares_addr6ttl *addrttls,
- int *naddrttls)
-{
- unsigned int qdcount, ancount;
- int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs;
- int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */
- int naliases;
- long len;
- const unsigned char *aptr;
- char *hostname, *rr_name, *rr_data, **aliases;
- struct ares_in6_addr *addrs;
- struct hostent *hostent;
- const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0;
-
- /* Set *host to NULL for all failure cases. */
- if (host)
- *host = NULL;
- /* Same with *naddrttls. */
- if (naddrttls)
- *naddrttls = 0;
-
- /* Give up if abuf doesn't have room for a header. */
- if (alen < HFIXEDSZ)
- return ARES_EBADRESP;
-
- /* Fetch the question and answer count from the header. */
- qdcount = DNS_HEADER_QDCOUNT(abuf);
- ancount = DNS_HEADER_ANCOUNT(abuf);
- if (qdcount != 1)
- return ARES_EBADRESP;
-
- /* Expand the name from the question, and skip past the question. */
- aptr = abuf + HFIXEDSZ;
- status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len);
- if (status != ARES_SUCCESS)
- return status;
- if (aptr + len + QFIXEDSZ > abuf + alen)
- {
- free(hostname);
- return ARES_EBADRESP;
- }
- aptr += len + QFIXEDSZ;
-
- /* Allocate addresses and aliases; ancount gives an upper bound for both. */
- if (host)
- {
- addrs = malloc(ancount * sizeof(struct ares_in6_addr));
- if (!addrs)
- {
- free(hostname);
- return ARES_ENOMEM;
- }
- aliases = malloc((ancount + 1) * sizeof(char *));
- if (!aliases)
- {
- free(hostname);
- free(addrs);
- return ARES_ENOMEM;
- }
- }
- else
- {
- addrs = NULL;
- aliases = NULL;
- }
- naddrs = 0;
- naliases = 0;
-
- /* Examine each answer resource record (RR) in turn. */
- for (i = 0; i < (int)ancount; i++)
- {
- /* Decode the RR up to the data field. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
- if (status != ARES_SUCCESS)
- break;
- aptr += len;
- if (aptr + RRFIXEDSZ > abuf + alen)
- {
- free(rr_name);
- status = ARES_EBADRESP;
- break;
- }
- rr_type = DNS_RR_TYPE(aptr);
- rr_class = DNS_RR_CLASS(aptr);
- rr_len = DNS_RR_LEN(aptr);
- rr_ttl = DNS_RR_TTL(aptr);
- aptr += RRFIXEDSZ;
-
- if (rr_class == C_IN && rr_type == T_AAAA
- && rr_len == sizeof(struct ares_in6_addr)
- && strcasecmp(rr_name, hostname) == 0)
- {
- if (addrs)
- {
- if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
- {
- free(rr_name);
- status = ARES_EBADRESP;
- break;
- }
- memcpy(&addrs[naddrs], aptr, sizeof(struct ares_in6_addr));
- }
- if (naddrs < max_addr_ttls)
- {
- struct ares_addr6ttl * const at = &addrttls[naddrs];
- if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
- {
- free(rr_name);
- status = ARES_EBADRESP;
- break;
- }
- memcpy(&at->ip6addr, aptr, sizeof(struct ares_in6_addr));
- at->ttl = rr_ttl;
- }
- naddrs++;
- status = ARES_SUCCESS;
- }
-
- if (rr_class == C_IN && rr_type == T_CNAME)
- {
- /* Record the RR name as an alias. */
- if (aliases)
- aliases[naliases] = rr_name;
- else
- free(rr_name);
- naliases++;
-
- /* Decode the RR data and replace the hostname with it. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
- if (status != ARES_SUCCESS)
- break;
- free(hostname);
- hostname = rr_data;
-
- /* Take the min of the TTLs we see in the CNAME chain. */
- if (cname_ttl > rr_ttl)
- cname_ttl = rr_ttl;
- }
- else
- free(rr_name);
-
- aptr += rr_len;
- if (aptr > abuf + alen)
- {
- status = ARES_EBADRESP;
- break;
- }
- }
-
- if (status == ARES_SUCCESS && naddrs == 0)
- status = ARES_ENODATA;
- if (status == ARES_SUCCESS)
- {
- /* We got our answer. */
- if (naddrttls)
- {
- const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls;
- for (i = 0; i < n; i++)
- {
- /* Ensure that each A TTL is no larger than the CNAME TTL. */
- if (addrttls[i].ttl > cname_ttl)
- addrttls[i].ttl = cname_ttl;
- }
- *naddrttls = n;
- }
- if (aliases)
- aliases[naliases] = NULL;
- if (host)
- {
- /* Allocate memory to build the host entry. */
- hostent = malloc(sizeof(struct hostent));
- if (hostent)
- {
- hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *));
- if (hostent->h_addr_list)
- {
- /* Fill in the hostent and return successfully. */
- hostent->h_name = hostname;
- hostent->h_aliases = aliases;
- hostent->h_addrtype = AF_INET6;
- hostent->h_length = sizeof(struct ares_in6_addr);
- for (i = 0; i < naddrs; i++)
- hostent->h_addr_list[i] = (char *) &addrs[i];
- hostent->h_addr_list[naddrs] = NULL;
- *host = hostent;
- return ARES_SUCCESS;
- }
- free(hostent);
- }
- status = ARES_ENOMEM;
- }
- }
- if (aliases)
- {
- for (i = 0; i < naliases; i++)
- free(aliases[i]);
- free(aliases);
- }
- free(addrs);
- free(hostname);
- return status;
-}
diff --git a/deps/uv/src/ares/ares_parse_ptr_reply.c b/deps/uv/src/ares/ares_parse_ptr_reply.c
deleted file mode 100644
index 3b6dbc32e..000000000
--- a/deps/uv/src/ares/ares_parse_ptr_reply.c
+++ /dev/null
@@ -1,217 +0,0 @@
-
-/* 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.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include "ares.h"
-#include "ares_dns.h"
-#include "ares_private.h"
-
-int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
- int addrlen, int family, struct hostent **host)
-{
- unsigned int qdcount, ancount;
- int status, i, rr_type, rr_class, rr_len;
- long len;
- const unsigned char *aptr;
- char *ptrname, *hostname, *rr_name, *rr_data;
- struct hostent *hostent;
- int aliascnt = 0;
- int alias_alloc = 8;
- char ** aliases;
-
- /* Set *host to NULL for all failure cases. */
- *host = NULL;
-
- /* Give up if abuf doesn't have room for a header. */
- if (alen < HFIXEDSZ)
- return ARES_EBADRESP;
-
- /* Fetch the question and answer count from the header. */
- qdcount = DNS_HEADER_QDCOUNT(abuf);
- ancount = DNS_HEADER_ANCOUNT(abuf);
- if (qdcount != 1)
- return ARES_EBADRESP;
-
- /* Expand the name from the question, and skip past the question. */
- aptr = abuf + HFIXEDSZ;
- status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len);
- if (status != ARES_SUCCESS)
- return status;
- if (aptr + len + QFIXEDSZ > abuf + alen)
- {
- free(ptrname);
- return ARES_EBADRESP;
- }
- aptr += len + QFIXEDSZ;
-
- /* Examine each answer resource record (RR) in turn. */
- hostname = NULL;
- aliases = malloc(alias_alloc * sizeof(char *));
- if (!aliases)
- {
- free(ptrname);
- return ARES_ENOMEM;
- }
- for (i = 0; i < (int)ancount; i++)
- {
- /* Decode the RR up to the data field. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
- if (status != ARES_SUCCESS)
- break;
- aptr += len;
- if (aptr + RRFIXEDSZ > abuf + alen)
- {
- free(rr_name);
- status = ARES_EBADRESP;
- break;
- }
- rr_type = DNS_RR_TYPE(aptr);
- rr_class = DNS_RR_CLASS(aptr);
- rr_len = DNS_RR_LEN(aptr);
- aptr += RRFIXEDSZ;
-
- if (rr_class == C_IN && rr_type == T_PTR
- && strcasecmp(rr_name, ptrname) == 0)
- {
- /* Decode the RR data and set hostname to it. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
- if (status != ARES_SUCCESS)
- {
- free(rr_name);
- break;
- }
- if (hostname)
- free(hostname);
- hostname = rr_data;
- aliases[aliascnt] = malloc((strlen(rr_data)+1) * sizeof(char));
- if (!aliases[aliascnt])
- {
- free(rr_name);
- status = ARES_ENOMEM;
- break;
- }
- strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1);
- aliascnt++;
- if (aliascnt >= alias_alloc) {
- char **ptr;
- alias_alloc *= 2;
- ptr = realloc(aliases, alias_alloc * sizeof(char *));
- if(!ptr) {
- free(rr_name);
- status = ARES_ENOMEM;
- break;
- }
- aliases = ptr;
- }
- }
-
- if (rr_class == C_IN && rr_type == T_CNAME)
- {
- /* Decode the RR data and replace ptrname with it. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
- if (status != ARES_SUCCESS)
- {
- free(rr_name);
- break;
- }
- free(ptrname);
- ptrname = rr_data;
- }
-
- free(rr_name);
- aptr += rr_len;
- if (aptr > abuf + alen)
- {
- status = ARES_EBADRESP;
- break;
- }
- }
-
- if (status == ARES_SUCCESS && !hostname)
- status = ARES_ENODATA;
- if (status == ARES_SUCCESS)
- {
- /* We got our answer. Allocate memory to build the host entry. */
- hostent = malloc(sizeof(struct hostent));
- if (hostent)
- {
- hostent->h_addr_list = malloc(2 * sizeof(char *));
- if (hostent->h_addr_list)
- {
- hostent->h_addr_list[0] = malloc(addrlen);
- if (hostent->h_addr_list[0])
- {
- hostent->h_aliases = malloc((aliascnt+1) * sizeof (char *));
- if (hostent->h_aliases)
- {
- /* Fill in the hostent and return successfully. */
- hostent->h_name = hostname;
- for (i=0 ; i<aliascnt ; i++)
- hostent->h_aliases[i] = aliases[i];
- hostent->h_aliases[aliascnt] = NULL;
- hostent->h_addrtype = family;
- hostent->h_length = addrlen;
- memcpy(hostent->h_addr_list[0], addr, addrlen);
- hostent->h_addr_list[1] = NULL;
- *host = hostent;
- free(aliases);
- free(ptrname);
- return ARES_SUCCESS;
- }
- free(hostent->h_addr_list[0]);
- }
- free(hostent->h_addr_list);
- }
- free(hostent);
- }
- status = ARES_ENOMEM;
- }
- for (i=0 ; i<aliascnt ; i++)
- if (aliases[i])
- free(aliases[i]);
- free(aliases);
- if (hostname)
- free(hostname);
- free(ptrname);
- return status;
-}
diff --git a/deps/uv/src/ares/ares_private.h b/deps/uv/src/ares/ares_private.h
deleted file mode 100644
index ff45ba7e5..000000000
--- a/deps/uv/src/ares/ares_private.h
+++ /dev/null
@@ -1,355 +0,0 @@
-#ifndef __ARES_PRIVATE_H
-#define __ARES_PRIVATE_H
-
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright (C) 2004-2010 by Daniel Stenberg
- *
- * 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.
- */
-
-/*
- * Define WIN32 when build target is Win32 API
- */
-
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-#define WIN32
-#endif
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#ifdef WATT32
-#include <tcp.h>
-#include <sys/ioctl.h>
-#define writev(s,v,c) writev_s(s,v,c)
-#define HAVE_WRITEV 1
-#endif
-
-#ifdef NETWARE
-#include <time.h>
-#endif
-
-#define DEFAULT_TIMEOUT 5000 /* milliseconds */
-#define DEFAULT_TRIES 4
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
-#if defined(WIN32) && !defined(WATT32)
-
-#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
-#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
-#define NAMESERVER "NameServer"
-#define DHCPNAMESERVER "DhcpNameServer"
-#define DATABASEPATH "DatabasePath"
-#define WIN_PATH_HOSTS "\\hosts"
-
-#elif defined(WATT32)
-
-#define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf"
-
-#elif defined(NETWARE)
-
-#define PATH_RESOLV_CONF "sys:/etc/resolv.cfg"
-#define PATH_HOSTS "sys:/etc/hosts"
-
-#elif defined(__riscos__)
-
-#define PATH_HOSTS "InetDBase:Hosts"
-
-#else
-
-#define PATH_RESOLV_CONF "/etc/resolv.conf"
-#ifdef ETC_INET
-#define PATH_HOSTS "/etc/inet/hosts"
-#else
-#define PATH_HOSTS "/etc/hosts"
-#endif
-
-#endif
-
-#define ARES_ID_KEY_LEN 31
-
-#include "ares_ipv6.h"
-#include "ares_llist.h"
-
-#ifndef HAVE_GETENV
-# include "ares_getenv.h"
-# define getenv(ptr) ares_getenv(ptr)
-#endif
-
-#ifndef HAVE_STRDUP
-# include "ares_strdup.h"
-# define strdup(ptr) ares_strdup(ptr)
-#endif
-
-#ifndef HAVE_STRCASECMP
-# include "ares_strcasecmp.h"
-# define strcasecmp(p1,p2) ares_strcasecmp(p1,p2)
-#endif
-
-#ifndef HAVE_STRNCASECMP
-# include "ares_strcasecmp.h"
-# define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n)
-#endif
-
-#ifndef HAVE_WRITEV
-# include "ares_writev.h"
-# define writev(s,ptr,cnt) ares_writev(s,ptr,cnt)
-#endif
-
-struct ares_addr {
- int family;
- union {
- struct in_addr addr4;
- struct ares_in6_addr addr6;
- } addr;
-};
-#define addrV4 addr.addr4
-#define addrV6 addr.addr6
-
-struct query;
-
-struct send_request {
- /* Remaining data to send */
- const unsigned char *data;
- size_t len;
-
- /* The query for which we're sending this data */
- struct query* owner_query;
- /* The buffer we're using, if we have our own copy of the packet */
- unsigned char *data_storage;
-
- /* Next request in queue */
- struct send_request *next;
-};
-
-struct server_state {
- struct ares_addr addr;
- ares_socket_t udp_socket;
- ares_socket_t tcp_socket;
-
- /* Mini-buffer for reading the length word */
- unsigned char tcp_lenbuf[2];
- int tcp_lenbuf_pos;
- int tcp_length;
-
- /* Buffer for reading actual TCP data */
- unsigned char *tcp_buffer;
- int tcp_buffer_pos;
-
- /* TCP output queue */
- struct send_request *qhead;
- struct send_request *qtail;
-
- /* Which incarnation of this connection is this? We don't want to
- * retransmit requests into the very same socket, but if the server
- * closes on us and we re-open the connection, then we do want to
- * re-send. */
- int tcp_connection_generation;
-
- /* Circular, doubly-linked list of outstanding queries to this server */
- struct list_node queries_to_server;
-
- /* Link back to owning channel */
- ares_channel channel;
-
- /* Is this server broken? We mark connections as broken when a
- * request that is queued for sending times out.
- */
- int is_broken;
-};
-
-/* State to represent a DNS query */
-struct query {
- /* Query ID from qbuf, for faster lookup, and current timeout */
- unsigned short qid;
- struct timeval timeout;
-
- /*
- * Links for the doubly-linked lists in which we insert a query.
- * These circular, doubly-linked lists that are hash-bucketed based
- * the attributes we care about, help making most important
- * operations O(1).
- */
- struct list_node queries_by_qid; /* hopefully in same cache line as qid */
- struct list_node queries_by_timeout;
- struct list_node queries_to_server;
- struct list_node all_queries;
-
- /* Query buf with length at beginning, for TCP transmission */
- unsigned char *tcpbuf;
- int tcplen;
-
- /* Arguments passed to ares_send() (qbuf points into tcpbuf) */
- const unsigned char *qbuf;
- int qlen;
- ares_callback callback;
- void *arg;
-
- /* Query status */
- int try_count; /* Number of times we tried this query already. */
- int server; /* Server this query has last been sent to. */
- struct query_server_info *server_info; /* per-server state */
- int using_tcp;
- int error_status;
- int timeouts; /* number of timeouts we saw for this request */
-};
-
-/* Per-server state for a query */
-struct query_server_info {
- int skip_server; /* should we skip server, due to errors, etc? */
- int tcp_connection_generation; /* into which TCP connection did we send? */
-};
-
-/* An IP address pattern; matches an IP address X if X & mask == addr */
-#define PATTERN_MASK 0x1
-#define PATTERN_CIDR 0x2
-
-struct apattern {
- union
- {
- struct in_addr addr4;
- struct ares_in6_addr addr6;
- } addr;
- union
- {
- struct in_addr addr4;
- struct ares_in6_addr addr6;
- unsigned short bits;
- } mask;
- int family;
- unsigned short type;
-};
-
-typedef struct rc4_key
-{
- unsigned char state[256];
- unsigned char x;
- unsigned char y;
-} rc4_key;
-
-struct ares_channeldata {
- /* Configuration data */
- int flags;
- int timeout; /* in milliseconds */
- int tries;
- int ndots;
- int rotate; /* if true, all servers specified are used */
- int udp_port;
- int tcp_port;
- int socket_send_buffer_size;
- int socket_receive_buffer_size;
- char **domains;
- int ndomains;
- struct apattern *sortlist;
- int nsort;
- char *lookups;
-
- /* For binding to local devices and/or IP addresses. Leave
- * them null/zero for no binding.
- */
- char local_dev_name[32];
- unsigned int local_ip4;
- unsigned char local_ip6[16];
-
- int optmask; /* the option bitfield passed in at init time */
-
- /* Server addresses and communications state */
- struct server_state *servers;
- int nservers;
-
- /* ID to use for next query */
- unsigned short next_id;
- /* key to use when generating new ids */
- rc4_key id_key;
-
- /* Generation number to use for the next TCP socket open/close */
- int tcp_connection_generation;
-
- /* The time at which we last called process_timeouts(). Uses integer seconds
- just to draw the line somewhere. */
- time_t last_timeout_processed;
-
- /* Last server we sent a query to. */
- int last_server;
-
- /* Circular, doubly-linked list of queries, bucketed various ways.... */
- /* All active queries in a single list: */
- struct list_node all_queries;
- /* Queries bucketed by qid, for quickly dispatching DNS responses: */
-#define ARES_QID_TABLE_SIZE 2048
- struct list_node queries_by_qid[ARES_QID_TABLE_SIZE];
- /* Queries bucketed by timeout, for quickly handling timeouts: */
-#define ARES_TIMEOUT_TABLE_SIZE 1024
- struct list_node queries_by_timeout[ARES_TIMEOUT_TABLE_SIZE];
-
- ares_sock_state_cb sock_state_cb;
- void *sock_state_cb_data;
-
- ares_sock_create_callback sock_create_cb;
- void *sock_create_cb_data;
-};
-
-/* return true if now is exactly check time or later */
-int ares__timedout(struct timeval *now,
- struct timeval *check);
-/* add the specific number of milliseconds to the time in the first argument */
-int ares__timeadd(struct timeval *now,
- int millisecs);
-/* return time offset between now and (future) check, in milliseconds */
-long ares__timeoffset(struct timeval *now,
- struct timeval *check);
-/* returns ARES_SUCCESS if library has been initialized */
-int ares_library_initialized(void);
-void ares__rc4(rc4_key* key,unsigned char *buffer_ptr, int buffer_len);
-void ares__send_query(ares_channel channel, struct query *query,
- struct timeval *now);
-void ares__close_sockets(ares_channel channel, struct server_state *server);
-int ares__get_hostent(FILE *fp, int family, struct hostent **host);
-int ares__read_line(FILE *fp, char **buf, size_t *bufsize);
-void ares__free_query(struct query *query);
-unsigned short ares__generate_new_id(rc4_key* key);
-struct timeval ares__tvnow(void);
-int ares__expand_name_for_response(const unsigned char *encoded,
- const unsigned char *abuf, int alen,
- char **s, long *enclen);
-void ares__init_servers_state(ares_channel channel);
-void ares__destroy_servers_state(ares_channel channel);
-#if 0 /* Not used */
-long ares__tvdiff(struct timeval t1, struct timeval t2);
-#endif
-
-#define ARES_SWAP_BYTE(a,b) \
- { unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; }
-
-#define SOCK_STATE_CALLBACK(c, s, r, w) \
- do { \
- if ((c)->sock_state_cb) \
- (c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \
- } while (0)
-
-#ifdef CURLDEBUG
-/* This is low-level hard-hacking memory leak tracking and similar. Using the
- libcurl lowlevel code from within library is ugly and only works when
- c-ares is built and linked with a similarly curldebug-enabled libcurl,
- but we do this anyway for convenience. */
-#include "../lib/memdebug.h"
-#endif
-
-#endif /* __ARES_PRIVATE_H */
diff --git a/deps/uv/src/ares/ares_process.c b/deps/uv/src/ares/ares_process.c
deleted file mode 100644
index e5efa5fb3..000000000
--- a/deps/uv/src/ares/ares_process.c
+++ /dev/null
@@ -1,1295 +0,0 @@
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright (C) 2004-2010 by Daniel Stenberg
- *
- * 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.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_UIO_H
-# include <sys/uio.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETINET_TCP_H
-# include <netinet/tcp.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#ifdef NETWARE
-# include <sys/filio.h>
-#endif
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <time.h>
-
-#include "ares.h"
-#include "ares_dns.h"
-#include "ares_nowarn.h"
-#include "ares_private.h"
-
-
-static int try_again(int errnum);
-static void write_tcp_data(ares_channel channel, fd_set *write_fds,
- ares_socket_t write_fd, struct timeval *now);
-static void read_tcp_data(ares_channel channel, fd_set *read_fds,
- ares_socket_t read_fd, struct timeval *now);
-static void read_udp_packets(ares_channel channel, fd_set *read_fds,
- ares_socket_t read_fd, struct timeval *now);
-static void advance_tcp_send_queue(ares_channel channel, int whichserver,
- ssize_t num_bytes);
-static void process_timeouts(ares_channel channel, struct timeval *now);
-static void process_broken_connections(ares_channel channel,
- struct timeval *now);
-static void process_answer(ares_channel channel, unsigned char *abuf,
- int alen, int whichserver, int tcp,
- struct timeval *now);
-static void handle_error(ares_channel channel, int whichserver,
- struct timeval *now);
-static void skip_server(ares_channel channel, struct query *query,
- int whichserver);
-static void next_server(ares_channel channel, struct query *query,
- struct timeval *now);
-static int open_tcp_socket(ares_channel channel, struct server_state *server);
-static int open_udp_socket(ares_channel channel, struct server_state *server);
-static int same_questions(const unsigned char *qbuf, int qlen,
- const unsigned char *abuf, int alen);
-static int same_address(struct sockaddr *sa, struct ares_addr *aa);
-static void end_query(ares_channel channel, struct query *query, int status,
- unsigned char *abuf, int alen);
-
-/* return true if now is exactly check time or later */
-int ares__timedout(struct timeval *now,
- struct timeval *check)
-{
- long secs = (now->tv_sec - check->tv_sec);
-
- if(secs > 0)
- return 1; /* yes, timed out */
- if(secs < 0)
- return 0; /* nope, not timed out */
-
- /* if the full seconds were identical, check the sub second parts */
- return (now->tv_usec - check->tv_usec >= 0);
-}
-
-/* add the specific number of milliseconds to the time in the first argument */
-int ares__timeadd(struct timeval *now,
- int millisecs)
-{
- now->tv_sec += millisecs/1000;
- now->tv_usec += (millisecs%1000)*1000;
-
- if(now->tv_usec >= 1000000) {
- ++(now->tv_sec);
- now->tv_usec -= 1000000;
- }
-
- return 0;
-}
-
-/* return time offset between now and (future) check, in milliseconds */
-long ares__timeoffset(struct timeval *now,
- struct timeval *check)
-{
- return (check->tv_sec - now->tv_sec)*1000 +
- (check->tv_usec - now->tv_usec)/1000;
-}
-
-
-/*
- * generic process function
- */
-static void processfds(ares_channel channel,
- fd_set *read_fds, ares_socket_t read_fd,
- fd_set *write_fds, ares_socket_t write_fd)
-{
- struct timeval now = ares__tvnow();
-
- write_tcp_data(channel, write_fds, write_fd, &now);
- read_tcp_data(channel, read_fds, read_fd, &now);
- read_udp_packets(channel, read_fds, read_fd, &now);
- process_timeouts(channel, &now);
- process_broken_connections(channel, &now);
-}
-
-/* Something interesting happened on the wire, or there was a timeout.
- * See what's up and respond accordingly.
- */
-void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
-{
- processfds(channel, read_fds, ARES_SOCKET_BAD, write_fds, ARES_SOCKET_BAD);
-}
-
-/* Something interesting happened on the wire, or there was a timeout.
- * See what's up and respond accordingly.
- */
-void ares_process_fd(ares_channel channel,
- ares_socket_t read_fd, /* use ARES_SOCKET_BAD or valid
- file descriptors */
- ares_socket_t write_fd)
-{
- processfds(channel, NULL, read_fd, NULL, write_fd);
-}
-
-
-/* Return 1 if the specified error number describes a readiness error, or 0
- * otherwise. This is mostly for HP-UX, which could return EAGAIN or
- * EWOULDBLOCK. See this man page
- *
- * http://devrsrc1.external.hp.com/STKS/cgi-bin/man2html?
- * manpage=/usr/share/man/man2.Z/send.2
- */
-static int try_again(int errnum)
-{
-#if !defined EWOULDBLOCK && !defined EAGAIN
-#error "Neither EWOULDBLOCK nor EAGAIN defined"
-#endif
- switch (errnum)
- {
-#ifdef EWOULDBLOCK
- case EWOULDBLOCK:
- return 1;
-#endif
-#if defined EAGAIN && EAGAIN != EWOULDBLOCK
- case EAGAIN:
- return 1;
-#endif
- }
- return 0;
-}
-
-/* If any TCP sockets select true for writing, write out queued data
- * we have for them.
- */
-static void write_tcp_data(ares_channel channel,
- fd_set *write_fds,
- ares_socket_t write_fd,
- struct timeval *now)
-{
- struct server_state *server;
- struct send_request *sendreq;
- struct iovec *vec;
- int i;
- ssize_t scount;
- ssize_t wcount;
- size_t n;
-
- if(!write_fds && (write_fd == ARES_SOCKET_BAD))
- /* no possible action */
- return;
-
- for (i = 0; i < channel->nservers; i++)
- {
- /* Make sure server has data to send and is selected in write_fds or
- write_fd. */
- server = &channel->servers[i];
- if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD ||
- server->is_broken)
- continue;
-
- if(write_fds) {
- if(!FD_ISSET(server->tcp_socket, write_fds))
- continue;
- }
- else {
- if(server->tcp_socket != write_fd)
- continue;
- }
-
- if(write_fds)
- /* If there's an error and we close this socket, then open
- * another with the same fd to talk to another server, then we
- * don't want to think that it was the new socket that was
- * ready. This is not disastrous, but is likely to result in
- * extra system calls and confusion. */
- FD_CLR(server->tcp_socket, write_fds);
-
- /* Count the number of send queue items. */
- n = 0;
- for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
- n++;
-
- /* Allocate iovecs so we can send all our data at once. */
- vec = malloc(n * sizeof(struct iovec));
- if (vec)
- {
- /* Fill in the iovecs and send. */
- n = 0;
- for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
- {
- vec[n].iov_base = (char *) sendreq->data;
- vec[n].iov_len = sendreq->len;
- n++;
- }
- wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n);
- free(vec);
- if (wcount < 0)
- {
- if (!try_again(SOCKERRNO))
- handle_error(channel, i, now);
- continue;
- }
-
- /* Advance the send queue by as many bytes as we sent. */
- advance_tcp_send_queue(channel, i, wcount);
- }
- else
- {
- /* Can't allocate iovecs; just send the first request. */
- sendreq = server->qhead;
-
- scount = swrite(server->tcp_socket, sendreq->data, sendreq->len);
- if (scount < 0)
- {
- if (!try_again(SOCKERRNO))
- handle_error(channel, i, now);
- continue;
- }
-
- /* Advance the send queue by as many bytes as we sent. */
- advance_tcp_send_queue(channel, i, scount);
- }
- }
-}
-
-/* Consume the given number of bytes from the head of the TCP send queue. */
-static void advance_tcp_send_queue(ares_channel channel, int whichserver,
- ssize_t num_bytes)
-{
- struct send_request *sendreq;
- struct server_state *server = &channel->servers[whichserver];
- while (num_bytes > 0) {
- sendreq = server->qhead;
- if ((size_t)num_bytes >= sendreq->len) {
- num_bytes -= sendreq->len;
- server->qhead = sendreq->next;
- if (sendreq->data_storage)
- free(sendreq->data_storage);
- free(sendreq);
- if (server->qhead == NULL) {
- SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
- server->qtail = NULL;
-
- /* qhead is NULL so we cannot continue this loop */
- break;
- }
- }
- else {
- sendreq->data += num_bytes;
- sendreq->len -= num_bytes;
- num_bytes = 0;
- }
- }
-}
-
-/* If any TCP socket selects true for reading, read some data,
- * allocate a buffer if we finish reading the length word, and process
- * a packet if we finish reading one.
- */
-static void read_tcp_data(ares_channel channel, fd_set *read_fds,
- ares_socket_t read_fd, struct timeval *now)
-{
- struct server_state *server;
- int i;
- ssize_t count;
-
- if(!read_fds && (read_fd == ARES_SOCKET_BAD))
- /* no possible action */
- return;
-
- for (i = 0; i < channel->nservers; i++)
- {
- /* Make sure the server has a socket and is selected in read_fds. */
- server = &channel->servers[i];
- if (server->tcp_socket == ARES_SOCKET_BAD || server->is_broken)
- continue;
-
- if(read_fds) {
- if(!FD_ISSET(server->tcp_socket, read_fds))
- continue;
- }
- else {
- if(server->tcp_socket != read_fd)
- continue;
- }
-
- if(read_fds)
- /* If there's an error and we close this socket, then open
- * another with the same fd to talk to another server, then we
- * don't want to think that it was the new socket that was
- * ready. This is not disastrous, but is likely to result in
- * extra system calls and confusion. */
- FD_CLR(server->tcp_socket, read_fds);
-
- if (server->tcp_lenbuf_pos != 2)
- {
- /* We haven't yet read a length word, so read that (or
- * what's left to read of it).
- */
- count = sread(server->tcp_socket,
- server->tcp_lenbuf + server->tcp_lenbuf_pos,
- 2 - server->tcp_lenbuf_pos);
- if (count <= 0)
- {
- if (!(count == -1 && try_again(SOCKERRNO)))
- handle_error(channel, i, now);
- continue;
- }
-
- server->tcp_lenbuf_pos += (int)count;
- if (server->tcp_lenbuf_pos == 2)
- {
- /* We finished reading the length word. Decode the
- * length and allocate a buffer for the data.
- */
- server->tcp_length = server->tcp_lenbuf[0] << 8
- | server->tcp_lenbuf[1];
- server->tcp_buffer = malloc(server->tcp_length);
- if (!server->tcp_buffer)
- handle_error(channel, i, now);
- server->tcp_buffer_pos = 0;
- }
- }
- else
- {
- /* Read data into the allocated buffer. */
- count = sread(server->tcp_socket,
- server->tcp_buffer + server->tcp_buffer_pos,
- server->tcp_length - server->tcp_buffer_pos);
- if (count <= 0)
- {
- if (!(count == -1 && try_again(SOCKERRNO)))
- handle_error(channel, i, now);
- continue;
- }
-
- server->tcp_buffer_pos += (int)count;
- if (server->tcp_buffer_pos == server->tcp_length)
- {
- /* We finished reading this answer; process it and
- * prepare to read another length word.
- */
- process_answer(channel, server->tcp_buffer, server->tcp_length,
- i, 1, now);
- if (server->tcp_buffer)
- free(server->tcp_buffer);
- server->tcp_buffer = NULL;
- server->tcp_lenbuf_pos = 0;
- server->tcp_buffer_pos = 0;
- }
- }
- }
-}
-
-/* If any UDP sockets select true for reading, process them. */
-static void read_udp_packets(ares_channel channel, fd_set *read_fds,
- ares_socket_t read_fd, struct timeval *now)
-{
- struct server_state *server;
- int i;
- ssize_t count;
- unsigned char buf[PACKETSZ + 1];
-#ifdef HAVE_RECVFROM
- ares_socklen_t fromlen;
- union {
- struct sockaddr sa;
- struct sockaddr_in sa4;
- struct sockaddr_in6 sa6;
- } from;
-#endif
-
- if(!read_fds && (read_fd == ARES_SOCKET_BAD))
- /* no possible action */
- return;
-
- for (i = 0; i < channel->nservers; i++)
- {
- /* Make sure the server has a socket and is selected in read_fds. */
- server = &channel->servers[i];
-
- if (server->udp_socket == ARES_SOCKET_BAD || server->is_broken)
- continue;
-
- if(read_fds) {
- if(!FD_ISSET(server->udp_socket, read_fds))
- continue;
- }
- else {
- if(server->udp_socket != read_fd)
- continue;
- }
-
- if(read_fds)
- /* If there's an error and we close this socket, then open
- * another with the same fd to talk to another server, then we
- * don't want to think that it was the new socket that was
- * ready. This is not disastrous, but is likely to result in
- * extra system calls and confusion. */
- FD_CLR(server->udp_socket, read_fds);
-
- /* To reduce event loop overhead, read and process as many
- * packets as we can. */
- do {
-#ifdef HAVE_RECVFROM
- if (server->addr.family == AF_INET)
- fromlen = sizeof(from.sa4);
- else
- fromlen = sizeof(from.sa6);
- count = (ssize_t)recvfrom(server->udp_socket, (void *)buf, sizeof(buf),
- 0, &from.sa, &fromlen);
-#else
- count = sread(server->udp_socket, buf, sizeof(buf));
-#endif
- if (count == -1 && try_again(SOCKERRNO))
- continue;
- else if (count <= 0)
- handle_error(channel, i, now);
-#ifdef HAVE_RECVFROM
- else if (!same_address(&from.sa, &server->addr))
- /* The address the response comes from does not match
- * the address we sent the request to. Someone may be
- * attempting to perform a cache poisoning attack. */
- break;
-#endif
- else
- process_answer(channel, buf, (int)count, i, 0, now);
- } while (count > 0);
- }
-}
-
-/* If any queries have timed out, note the timeout and move them on. */
-static void process_timeouts(ares_channel channel, struct timeval *now)
-{
- time_t t; /* the time of the timeouts we're processing */
- struct query *query;
- struct list_node* list_head;
- struct list_node* list_node;
-
- /* Process all the timeouts that have fired since the last time we
- * processed timeouts. If things are going well, then we'll have
- * hundreds/thousands of queries that fall into future buckets, and
- * only a handful of requests that fall into the "now" bucket, so
- * this should be quite quick.
- */
- for (t = channel->last_timeout_processed; t <= now->tv_sec; t++)
- {
- list_head = &(channel->queries_by_timeout[t % ARES_TIMEOUT_TABLE_SIZE]);
- for (list_node = list_head->next; list_node != list_head; )
- {
- query = list_node->data;
- list_node = list_node->next; /* in case the query gets deleted */
- if (query->timeout.tv_sec && ares__timedout(now, &query->timeout))
- {
- query->error_status = ARES_ETIMEOUT;
- ++query->timeouts;
- next_server(channel, query, now);
- }
- }
- }
- channel->last_timeout_processed = now->tv_sec;
-}
-
-/* Handle an answer from a server. */
-static void process_answer(ares_channel channel, unsigned char *abuf,
- int alen, int whichserver, int tcp,
- struct timeval *now)
-{
- int tc, rcode;
- unsigned short id;
- struct query *query;
- struct list_node* list_head;
- struct list_node* list_node;
-
- /* If there's no room in the answer for a header, we can't do much
- * with it. */
- if (alen < HFIXEDSZ)
- return;
-
- /* Grab the query ID, truncate bit, and response code from the packet. */
- id = DNS_HEADER_QID(abuf);
- tc = DNS_HEADER_TC(abuf);
- rcode = DNS_HEADER_RCODE(abuf);
-
- /* Find the query corresponding to this packet. The queries are
- * hashed/bucketed by query id, so this lookup should be quick.
- * Note that both the query id and the questions must be the same;
- * when the query id wraps around we can have multiple outstanding
- * queries with the same query id, so we need to check both the id and
- * question.
- */
- query = NULL;
- list_head = &(channel->queries_by_qid[id % ARES_QID_TABLE_SIZE]);
- for (list_node = list_head->next; list_node != list_head;
- list_node = list_node->next)
- {
- struct query *q = list_node->data;
- if ((q->qid == id) && same_questions(q->qbuf, q->qlen, abuf, alen))
- {
- query = q;
- break;
- }
- }
- if (!query)
- return;
-
- /* If we got a truncated UDP packet and are not ignoring truncation,
- * don't accept the packet, and switch the query to TCP if we hadn't
- * done so already.
- */
- if ((tc || alen > PACKETSZ) && !tcp && !(channel->flags & ARES_FLAG_IGNTC))
- {
- if (!query->using_tcp)
- {
- query->using_tcp = 1;
- ares__send_query(channel, query, now);
- }
- return;
- }
-
- /* Limit alen to PACKETSZ if we aren't using TCP (only relevant if we
- * are ignoring truncation.
- */
- if (alen > PACKETSZ && !tcp)
- alen = PACKETSZ;
-
- /* If we aren't passing through all error packets, discard packets
- * with SERVFAIL, NOTIMP, or REFUSED response codes.
- */
- if (!(channel->flags & ARES_FLAG_NOCHECKRESP))
- {
- if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED)
- {
- skip_server(channel, query, whichserver);
- if (query->server == whichserver)
- next_server(channel, query, now);
- return;
- }
- }
-
- end_query(channel, query, ARES_SUCCESS, abuf, alen);
-}
-
-/* Close all the connections that are no longer usable. */
-static void process_broken_connections(ares_channel channel,
- struct timeval *now)
-{
- int i;
- for (i = 0; i < channel->nservers; i++)
- {
- struct server_state *server = &channel->servers[i];
- if (server->is_broken)
- {
- handle_error(channel, i, now);
- }
- }
-}
-
-static void handle_error(ares_channel channel, int whichserver,
- struct timeval *now)
-{
- struct server_state *server;
- struct query *query;
- struct list_node list_head;
- struct list_node* list_node;
-
- server = &channel->servers[whichserver];
-
- /* Reset communications with this server. */
- ares__close_sockets(channel, server);
-
- /* Tell all queries talking to this server to move on and not try
- * this server again. We steal the current list of queries that were
- * in-flight to this server, since when we call next_server this can
- * cause the queries to be re-sent to this server, which will
- * re-insert these queries in that same server->queries_to_server
- * list.
- */
- ares__init_list_head(&list_head);
- ares__swap_lists(&list_head, &(server->queries_to_server));
- for (list_node = list_head.next; list_node != &list_head; )
- {
- query = list_node->data;
- list_node = list_node->next; /* in case the query gets deleted */
- assert(query->server == whichserver);
- skip_server(channel, query, whichserver);
- next_server(channel, query, now);
- }
- /* Each query should have removed itself from our temporary list as
- * it re-sent itself or finished up...
- */
- assert(ares__is_list_empty(&list_head));
-}
-
-static void skip_server(ares_channel channel, struct query *query,
- int whichserver) {
- /* The given server gave us problems with this query, so if we have
- * the luxury of using other servers, then let's skip the
- * potentially broken server and just use the others. If we only
- * have one server and we need to retry then we should just go ahead
- * and re-use that server, since it's our only hope; perhaps we
- * just got unlucky, and retrying will work (eg, the server timed
- * out our TCP connection just as we were sending another request).
- */
- if (channel->nservers > 1)
- {
- query->server_info[whichserver].skip_server = 1;
- }
-}
-
-static void next_server(ares_channel channel, struct query *query,
- struct timeval *now)
-{
- /* We need to try each server channel->tries times. We have channel->nservers
- * servers to try. In total, we need to do channel->nservers * channel->tries
- * attempts. Use query->try to remember how many times we already attempted
- * this query. Use modular arithmetic to find the next server to try. */
- while (++(query->try_count) < (channel->nservers * channel->tries))
- {
- struct server_state *server;
-
- /* Move on to the next server. */
- query->server = (query->server + 1) % channel->nservers;
- server = &channel->servers[query->server];
-
- /* We don't want to use this server if (1) we decided this
- * connection is broken, and thus about to be closed, (2)
- * we've decided to skip this server because of earlier
- * errors we encountered, or (3) we already sent this query
- * over this exact connection.
- */
- if (!server->is_broken &&
- !query->server_info[query->server].skip_server &&
- !(query->using_tcp &&
- (query->server_info[query->server].tcp_connection_generation ==
- server->tcp_connection_generation)))
- {
- ares__send_query(channel, query, now);
- return;
- }
-
- /* You might think that with TCP we only need one try. However,
- * even when using TCP, servers can time-out our connection just
- * as we're sending a request, or close our connection because
- * they die, or never send us a reply because they get wedged or
- * tickle a bug that drops our request.
- */
- }
-
- /* If we are here, all attempts to perform query failed. */
- end_query(channel, query, query->error_status, NULL, 0);
-}
-
-void ares__send_query(ares_channel channel, struct query *query,
- struct timeval *now)
-{
- struct send_request *sendreq;
- struct server_state *server;
- int timeplus;
-
- server = &channel->servers[query->server];
- if (query->using_tcp)
- {
- /* Make sure the TCP socket for this server is set up and queue
- * a send request.
- */
- if (server->tcp_socket == ARES_SOCKET_BAD)
- {
- if (open_tcp_socket(channel, server) == -1)
- {
- skip_server(channel, query, query->server);
- next_server(channel, query, now);
- return;
- }
- }
- sendreq = calloc(1, sizeof(struct send_request));
- if (!sendreq)
- {
- end_query(channel, query, ARES_ENOMEM, NULL, 0);
- return;
- }
- /* To make the common case fast, we avoid copies by using the
- * query's tcpbuf for as long as the query is alive. In the rare
- * case where the query ends while it's queued for transmission,
- * then we give the sendreq its own copy of the request packet
- * and put it in sendreq->data_storage.
- */
- sendreq->data_storage = NULL;
- sendreq->data = query->tcpbuf;
- sendreq->len = query->tcplen;
- sendreq->owner_query = query;
- sendreq->next = NULL;
- if (server->qtail)
- server->qtail->next = sendreq;
- else
- {
- SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 1);
- server->qhead = sendreq;
- }
- server->qtail = sendreq;
- query->server_info[query->server].tcp_connection_generation =
- server->tcp_connection_generation;
- }
- else
- {
- if (server->udp_socket == ARES_SOCKET_BAD)
- {
- if (open_udp_socket(channel, server) == -1)
- {
- skip_server(channel, query, query->server);
- next_server(channel, query, now);
- return;
- }
- }
- if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1)
- {
- /* FIXME: Handle EAGAIN here since it likely can happen. */
- skip_server(channel, query, query->server);
- next_server(channel, query, now);
- return;
- }
- }
- timeplus = channel->timeout << (query->try_count / channel->nservers);
- timeplus = (timeplus * (9 + (rand () & 7))) / 16;
- query->timeout = *now;
- ares__timeadd(&query->timeout,
- timeplus);
- /* Keep track of queries bucketed by timeout, so we can process
- * timeout events quickly.
- */
- ares__remove_from_list(&(query->queries_by_timeout));
- ares__insert_in_list(
- &(query->queries_by_timeout),
- &(channel->queries_by_timeout[query->timeout.tv_sec %
- ARES_TIMEOUT_TABLE_SIZE]));
-
- /* Keep track of queries bucketed by server, so we can process server
- * errors quickly.
- */
- ares__remove_from_list(&(query->queries_to_server));
- ares__insert_in_list(&(query->queries_to_server),
- &(server->queries_to_server));
-}
-
-/*
- * setsocknonblock sets the given socket to either blocking or non-blocking
- * mode based on the 'nonblock' boolean argument. This function is highly
- * portable.
- */
-static int setsocknonblock(ares_socket_t sockfd, /* operate on this */
- int nonblock /* TRUE or FALSE */)
-{
-#if defined(USE_BLOCKING_SOCKETS)
-
- return 0; /* returns success */
-
-#elif defined(HAVE_FCNTL_O_NONBLOCK)
-
- /* most recent unix versions */
- int flags;
- flags = fcntl(sockfd, F_GETFL, 0);
- if (FALSE != nonblock)
- return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
- else
- return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
-
-#elif defined(HAVE_IOCTL_FIONBIO)
-
- /* older unix versions */
- int flags;
- flags = nonblock;
- return ioctl(sockfd, FIONBIO, &flags);
-
-#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
-
-#ifdef WATT32
- char flags;
-#else
- /* Windows */
- unsigned long flags;
-#endif
- flags = nonblock;
- return ioctlsocket(sockfd, FIONBIO, &flags);
-
-#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
-
- /* Amiga */
- return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
-
-#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
-
- /* BeOS */
- long b = nonblock ? 1 : 0;
- return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
-
-#else
-# error "no non-blocking method was found/used/set"
-#endif
-}
-
-static int configure_socket(ares_socket_t s, int family, ares_channel channel)
-{
- union {
- struct sockaddr sa;
- struct sockaddr_in sa4;
- struct sockaddr_in6 sa6;
- } local;
-
- setsocknonblock(s, TRUE);
-
-#if defined(FD_CLOEXEC) && !defined(MSDOS)
- /* Configure the socket fd as close-on-exec. */
- if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1)
- return -1;
-#endif
-
- /* Set the socket's send and receive buffer sizes. */
- if ((channel->socket_send_buffer_size > 0) &&
- setsockopt(s, SOL_SOCKET, SO_SNDBUF,
- (void *)&channel->socket_send_buffer_size,
- sizeof(channel->socket_send_buffer_size)) == -1)
- return -1;
-
- if ((channel->socket_receive_buffer_size > 0) &&
- setsockopt(s, SOL_SOCKET, SO_RCVBUF,
- (void *)&channel->socket_receive_buffer_size,
- sizeof(channel->socket_receive_buffer_size)) == -1)
- return -1;
-
-#ifdef SO_BINDTODEVICE
- if (channel->local_dev_name[0]) {
- if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
- channel->local_dev_name, sizeof(channel->local_dev_name))) {
- /* Only root can do this, and usually not fatal if it doesn't work, so */
- /* just continue on. */
- }
- }
-#endif
-
- if (family == AF_INET) {
- if (channel->local_ip4) {
- memset(&local.sa4, 0, sizeof(local.sa4));
- local.sa4.sin_family = AF_INET;
- local.sa4.sin_addr.s_addr = htonl(channel->local_ip4);
- if (bind(s, &local.sa, sizeof(local.sa4)) < 0)
- return -1;
- }
- }
- else if (family == AF_INET6) {
- if (memcmp(channel->local_ip6, &ares_in6addr_any, sizeof(channel->local_ip6)) != 0) {
- memset(&local.sa6, 0, sizeof(local.sa6));
- local.sa6.sin6_family = AF_INET6;
- memcpy(&local.sa6.sin6_addr, channel->local_ip6, sizeof(channel->local_ip6));
- if (bind(s, &local.sa, sizeof(local.sa6)) < 0)
- return -1;
- }
- }
-
- return 0;
-}
-
-static int open_tcp_socket(ares_channel channel, struct server_state *server)
-{
- ares_socket_t s;
- int opt;
- ares_socklen_t salen;
- union {
- struct sockaddr_in sa4;
- struct sockaddr_in6 sa6;
- } saddr;
- struct sockaddr *sa;
-
- switch (server->addr.family)
- {
- case AF_INET:
- sa = (void *)&saddr.sa4;
- salen = sizeof(saddr.sa4);
- memset(sa, 0, salen);
- saddr.sa4.sin_family = AF_INET;
- saddr.sa4.sin_port = (unsigned short)(channel->tcp_port & 0xffff);
- memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4,
- sizeof(server->addr.addrV4));
- break;
- case AF_INET6:
- sa = (void *)&saddr.sa6;
- salen = sizeof(saddr.sa6);
- memset(sa, 0, salen);
- saddr.sa6.sin6_family = AF_INET6;
- saddr.sa6.sin6_port = (unsigned short)(channel->tcp_port & 0xffff);
- memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6,
- sizeof(server->addr.addrV6));
- break;
- default:
- return -1;
- }
-
- /* Acquire a socket. */
- s = socket(server->addr.family, SOCK_STREAM, 0);
- if (s == ARES_SOCKET_BAD)
- return -1;
-
- /* Configure it. */
- if (configure_socket(s, server->addr.family, channel) < 0)
- {
- sclose(s);
- return -1;
- }
-
-#ifdef TCP_NODELAY
- /*
- * Disable the Nagle algorithm (only relevant for TCP sockets, and thus not
- * in configure_socket). In general, in DNS lookups we're pretty much
- * interested in firing off a single request and then waiting for a reply,
- * so batching isn't very interesting.
- */
- opt = 1;
- if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
- (void *)&opt, sizeof(opt)) == -1)
- {
- sclose(s);
- return -1;
- }
-#endif
-
- /* Connect to the server. */
- if (connect(s, sa, salen) == -1)
- {
- int err = SOCKERRNO;
-
- if (err != EINPROGRESS && err != EWOULDBLOCK)
- {
- sclose(s);
- return -1;
- }
- }
-
- if (channel->sock_create_cb)
- {
- int err = channel->sock_create_cb(s, SOCK_STREAM,
- channel->sock_create_cb_data);
- if (err < 0)
- {
- sclose(s);
- return err;
- }
- }
-
- SOCK_STATE_CALLBACK(channel, s, 1, 0);
- server->tcp_buffer_pos = 0;
- server->tcp_socket = s;
- server->tcp_connection_generation = ++channel->tcp_connection_generation;
- return 0;
-}
-
-static int open_udp_socket(ares_channel channel, struct server_state *server)
-{
- ares_socket_t s;
- ares_socklen_t salen;
- union {
- struct sockaddr_in sa4;
- struct sockaddr_in6 sa6;
- } saddr;
- struct sockaddr *sa;
-
- switch (server->addr.family)
- {
- case AF_INET:
- sa = (void *)&saddr.sa4;
- salen = sizeof(saddr.sa4);
- memset(sa, 0, salen);
- saddr.sa4.sin_family = AF_INET;
- saddr.sa4.sin_port = (unsigned short)(channel->udp_port & 0xffff);
- memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4,
- sizeof(server->addr.addrV4));
- break;
- case AF_INET6:
- sa = (void *)&saddr.sa6;
- salen = sizeof(saddr.sa6);
- memset(sa, 0, salen);
- saddr.sa6.sin6_family = AF_INET6;
- saddr.sa6.sin6_port = (unsigned short)(channel->udp_port & 0xffff);
- memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6,
- sizeof(server->addr.addrV6));
- break;
- default:
- return -1;
- }
-
- /* Acquire a socket. */
- s = socket(server->addr.family, SOCK_DGRAM, 0);
- if (s == ARES_SOCKET_BAD)
- return -1;
-
- /* Set the socket non-blocking. */
- if (configure_socket(s, server->addr.family, channel) < 0)
- {
- sclose(s);
- return -1;
- }
-
- /* Connect to the server. */
- if (connect(s, sa, salen) == -1)
- {
- int err = SOCKERRNO;
-
- if (err != EINPROGRESS && err != EWOULDBLOCK)
- {
- sclose(s);
- return -1;
- }
- }
-
- if (channel->sock_create_cb)
- {
- int err = channel->sock_create_cb(s, SOCK_DGRAM,
- channel->sock_create_cb_data);
- if (err < 0)
- {
- sclose(s);
- return err;
- }
- }
-
- SOCK_STATE_CALLBACK(channel, s, 1, 0);
-
- server->udp_socket = s;
- return 0;
-}
-
-static int same_questions(const unsigned char *qbuf, int qlen,
- const unsigned char *abuf, int alen)
-{
- struct {
- const unsigned char *p;
- int qdcount;
- char *name;
- long namelen;
- int type;
- int dnsclass;
- } q, a;
- int i, j;
-
- if (qlen < HFIXEDSZ || alen < HFIXEDSZ)
- return 0;
-
- /* Extract qdcount from the request and reply buffers and compare them. */
- q.qdcount = DNS_HEADER_QDCOUNT(qbuf);
- a.qdcount = DNS_HEADER_QDCOUNT(abuf);
- if (q.qdcount != a.qdcount)
- return 0;
-
- /* For each question in qbuf, find it in abuf. */
- q.p = qbuf + HFIXEDSZ;
- for (i = 0; i < q.qdcount; i++)
- {
- /* Decode the question in the query. */
- if (ares_expand_name(q.p, qbuf, qlen, &q.name, &q.namelen)
- != ARES_SUCCESS)
- return 0;
- q.p += q.namelen;
- if (q.p + QFIXEDSZ > qbuf + qlen)
- {
- free(q.name);
- return 0;
- }
- q.type = DNS_QUESTION_TYPE(q.p);
- q.dnsclass = DNS_QUESTION_CLASS(q.p);
- q.p += QFIXEDSZ;
-
- /* Search for this question in the answer. */
- a.p = abuf + HFIXEDSZ;
- for (j = 0; j < a.qdcount; j++)
- {
- /* Decode the question in the answer. */
- if (ares_expand_name(a.p, abuf, alen, &a.name, &a.namelen)
- != ARES_SUCCESS)
- {
- free(q.name);
- return 0;
- }
- a.p += a.namelen;
- if (a.p + QFIXEDSZ > abuf + alen)
- {
- free(q.name);
- free(a.name);
- return 0;
- }
- a.type = DNS_QUESTION_TYPE(a.p);
- a.dnsclass = DNS_QUESTION_CLASS(a.p);
- a.p += QFIXEDSZ;
-
- /* Compare the decoded questions. */
- if (strcasecmp(q.name, a.name) == 0 && q.type == a.type
- && q.dnsclass == a.dnsclass)
- {
- free(a.name);
- break;
- }
- free(a.name);
- }
-
- free(q.name);
- if (j == a.qdcount)
- return 0;
- }
- return 1;
-}
-
-static int same_address(struct sockaddr *sa, struct ares_addr *aa)
-{
- void *addr1;
- void *addr2;
-
- if (sa->sa_family == aa->family)
- {
- switch (aa->family)
- {
- case AF_INET:
- addr1 = &aa->addrV4;
- addr2 = &((struct sockaddr_in *)sa)->sin_addr;
- if (memcmp(addr1, addr2, sizeof(aa->addrV4)) == 0)
- return 1; /* match */
- break;
- case AF_INET6:
- addr1 = &aa->addrV6;
- addr2 = &((struct sockaddr_in6 *)sa)->sin6_addr;
- if (memcmp(addr1, addr2, sizeof(aa->addrV6)) == 0)
- return 1; /* match */
- break;
- default:
- break;
- }
- }
- return 0; /* different */
-}
-
-static void end_query (ares_channel channel, struct query *query, int status,
- unsigned char *abuf, int alen)
-{
- int i;
-
- /* First we check to see if this query ended while one of our send
- * queues still has pointers to it.
- */
- for (i = 0; i < channel->nservers; i++)
- {
- struct server_state *server = &channel->servers[i];
- struct send_request *sendreq;
- for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
- if (sendreq->owner_query == query)
- {
- sendreq->owner_query = NULL;
- assert(sendreq->data_storage == NULL);
- if (status == ARES_SUCCESS)
- {
- /* We got a reply for this query, but this queued
- * sendreq points into this soon-to-be-gone query's
- * tcpbuf. Probably this means we timed out and queued
- * the query for retransmission, then received a
- * response before actually retransmitting. This is
- * perfectly fine, so we want to keep the connection
- * running smoothly if we can. But in the worst case
- * we may have sent only some prefix of the query,
- * with some suffix of the query left to send. Also,
- * the buffer may be queued on multiple queues. To
- * prevent dangling pointers to the query's tcpbuf and
- * handle these cases, we just give such sendreqs
- * their own copy of the query packet.
- */
- sendreq->data_storage = malloc(sendreq->len);
- if (sendreq->data_storage != NULL)
- {
- memcpy(sendreq->data_storage, sendreq->data, sendreq->len);
- sendreq->data = sendreq->data_storage;
- }
- }
- if ((status != ARES_SUCCESS) || (sendreq->data_storage == NULL))
- {
- /* We encountered an error (probably a timeout,
- * suggesting the DNS server we're talking to is
- * probably unreachable, wedged, or severely
- * overloaded) or we couldn't copy the request, so
- * mark the connection as broken. When we get to
- * process_broken_connections() we'll close the
- * connection and try to re-send requests to another
- * server.
- */
- server->is_broken = 1;
- /* Just to be paranoid, zero out this sendreq... */
- sendreq->data = NULL;
- sendreq->len = 0;
- }
- }
- }
-
- /* Invoke the callback */
- query->callback(query->arg, status, query->timeouts, abuf, alen);
- ares__free_query(query);
-
- /* Simple cleanup policy: if no queries are remaining, close all
- * network sockets unless STAYOPEN is set.
- */
- if (!(channel->flags & ARES_FLAG_STAYOPEN) &&
- ares__is_list_empty(&(channel->all_queries)))
- {
- for (i = 0; i < channel->nservers; i++)
- ares__close_sockets(channel, &channel->servers[i]);
- }
-}
-
-void ares__free_query(struct query *query)
-{
- /* Remove the query from all the lists in which it is linked */
- ares__remove_from_list(&(query->queries_by_qid));
- ares__remove_from_list(&(query->queries_by_timeout));
- ares__remove_from_list(&(query->queries_to_server));
- ares__remove_from_list(&(query->all_queries));
- /* Zero out some important stuff, to help catch bugs */
- query->callback = NULL;
- query->arg = NULL;
- /* Deallocate the memory associated with the query */
- free(query->tcpbuf);
- free(query->server_info);
- free(query);
-}
diff --git a/deps/uv/src/ares/ares_send.c b/deps/uv/src/ares/ares_send.c
deleted file mode 100644
index 37b070457..000000000
--- a/deps/uv/src/ares/ares_send.c
+++ /dev/null
@@ -1,134 +0,0 @@
-
-/* 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.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "ares.h"
-#include "ares_dns.h"
-#include "ares_private.h"
-
-void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
- ares_callback callback, void *arg)
-{
- struct query *query;
- int i;
- struct timeval now;
-
- /* Verify that the query is at least long enough to hold the header. */
- if (qlen < HFIXEDSZ || qlen >= (1 << 16))
- {
- callback(arg, ARES_EBADQUERY, 0, NULL, 0);
- return;
- }
-
- /* Allocate space for query and allocated fields. */
- query = malloc(sizeof(struct query));
- if (!query)
- {
- callback(arg, ARES_ENOMEM, 0, NULL, 0);
- return;
- }
- query->tcpbuf = malloc(qlen + 2);
- if (!query->tcpbuf)
- {
- free(query);
- callback(arg, ARES_ENOMEM, 0, NULL, 0);
- return;
- }
- query->server_info = malloc(channel->nservers *
- sizeof(query->server_info[0]));
- if (!query->server_info)
- {
- free(query->tcpbuf);
- free(query);
- callback(arg, ARES_ENOMEM, 0, NULL, 0);
- return;
- }
-
- /* Compute the query ID. Start with no timeout. */
- query->qid = (unsigned short)DNS_HEADER_QID(qbuf);
- query->timeout.tv_sec = 0;
- query->timeout.tv_usec = 0;
-
- /* Form the TCP query buffer by prepending qlen (as two
- * network-order bytes) to qbuf.
- */
- query->tcpbuf[0] = (unsigned char)((qlen >> 8) & 0xff);
- query->tcpbuf[1] = (unsigned char)(qlen & 0xff);
- memcpy(query->tcpbuf + 2, qbuf, qlen);
- query->tcplen = qlen + 2;
-
- /* Fill in query arguments. */
- query->qbuf = query->tcpbuf + 2;
- query->qlen = qlen;
- query->callback = callback;
- query->arg = arg;
-
- /* Initialize query status. */
- query->try_count = 0;
-
- /* Choose the server to send the query to. If rotation is enabled, keep track
- * of the next server we want to use. */
- query->server = channel->last_server;
- if (channel->rotate == 1)
- channel->last_server = (channel->last_server + 1) % channel->nservers;
-
- for (i = 0; i < channel->nservers; i++)
- {
- query->server_info[i].skip_server = 0;
- query->server_info[i].tcp_connection_generation = 0;
- }
- query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > PACKETSZ;
- query->error_status = ARES_ECONNREFUSED;
- query->timeouts = 0;
-
- /* Initialize our list nodes. */
- ares__init_list_node(&(query->queries_by_qid), query);
- ares__init_list_node(&(query->queries_by_timeout), query);
- ares__init_list_node(&(query->queries_to_server), query);
- ares__init_list_node(&(query->all_queries), query);
-
- /* Chain the query into the list of all queries. */
- ares__insert_in_list(&(query->all_queries), &(channel->all_queries));
- /* Keep track of queries bucketed by qid, so we can process DNS
- * responses quickly.
- */
- ares__insert_in_list(
- &(query->queries_by_qid),
- &(channel->queries_by_qid[query->qid % ARES_QID_TABLE_SIZE]));
-
- /* Perform the first query action. */
- now = ares__tvnow();
- ares__send_query(channel, query, &now);
-}
diff --git a/deps/uv/src/ares/ares_setup.h b/deps/uv/src/ares/ares_setup.h
deleted file mode 100644
index 254cccbb8..000000000
--- a/deps/uv/src/ares/ares_setup.h
+++ /dev/null
@@ -1,199 +0,0 @@
-#ifndef HEADER_CARES_SETUP_H
-#define HEADER_CARES_SETUP_H
-
-
-/* Copyright (C) 2004 - 2009 by Daniel Stenberg et al
- *
- * 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.
- */
-
-/*
- * Define WIN32 when build target is Win32 API
- */
-
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-#define WIN32
-#endif
-
-/*
- * Include configuration script results or hand-crafted
- * configuration file for platforms which lack config tool.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "ares_config.h"
-#else
-
-#ifdef WIN32
-#include "config-win32.h"
-#endif
-
-#endif /* HAVE_CONFIG_H */
-
-/* ================================================================ */
-/* Definition of preprocessor macros/symbols which modify compiler */
-/* behaviour or generated code characteristics must be done here, */
-/* as appropriate, before any system header file is included. It is */
-/* also possible to have them defined in the config file included */
-/* before this point. As a result of all this we frown inclusion of */
-/* system header files in our config files, avoid this at any cost. */
-/* ================================================================ */
-
-/*
- * AIX 4.3 and newer needs _THREAD_SAFE defined to build
- * proper reentrant code. Others may also need it.
- */
-
-#ifdef NEED_THREAD_SAFE
-# ifndef _THREAD_SAFE
-# define _THREAD_SAFE
-# endif
-#endif
-
-/*
- * Tru64 needs _REENTRANT set for a few function prototypes and
- * things to appear in the system header files. Unixware needs it
- * to build proper reentrant code. Others may also need it.
- */
-
-#ifdef NEED_REENTRANT
-# ifndef _REENTRANT
-# define _REENTRANT
-# endif
-#endif
-
-/* ================================================================ */
-/* If you need to include a system header file for your platform, */
-/* please, do it beyond the point further indicated in this file. */
-/* ================================================================ */
-
-#if 0 /* libuv hack */
-/*
- * c-ares external interface definitions are also used internally,
- * and might also include required system header files to define them.
- */
-
-#include <ares_build.h>
-
-/*
- * Compile time sanity checks must also be done when building the library.
- */
-
-#include <ares_rules.h>
-#endif /* libuv hack */
-
-/* ================================================================= */
-/* No system header file shall be included in this file before this */
-/* point. The only allowed ones are those included from ares_build.h */
-/* ================================================================= */
-
-/*
- * Include header files for windows builds before redefining anything.
- * Use this preproessor block only to include or exclude windows.h,
- * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
- * to any other further and independent block. Under Cygwin things work
- * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
- * never be included when __CYGWIN__ is defined. configure script takes
- * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
- * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
- */
-
-#ifdef HAVE_WINDOWS_H
-# ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-# endif
-# include <windows.h>
-# ifdef HAVE_WINSOCK2_H
-# include <winsock2.h>
-# ifdef HAVE_WS2TCPIP_H
-# include <ws2tcpip.h>
-# endif
-# else
-# ifdef HAVE_WINSOCK_H
-# include <winsock.h>
-# endif
-# endif
-#endif
-
-/*
- * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
- * define USE_WINSOCK to 1 if we have and use WINSOCK API, else
- * undefine USE_WINSOCK.
- */
-
-#undef USE_WINSOCK
-
-#ifdef HAVE_WINSOCK2_H
-# define USE_WINSOCK 2
-#else
-# ifdef HAVE_WINSOCK_H
-# define USE_WINSOCK 1
-# endif
-#endif
-
-/*
- * Work-arounds for systems without configure support
- */
-
-#ifndef HAVE_CONFIG_H
-
-#if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER) && !defined(__WATCOMC__)
-#define HAVE_SYS_TIME_H
-#endif
-
-#if !defined(HAVE_UNISTD_H) && !defined(_MSC_VER)
-#define HAVE_UNISTD_H 1
-#endif
-
-#if !defined(HAVE_SYS_UIO_H) && !defined(WIN32) && !defined(MSDOS)
-#define HAVE_SYS_UIO_H
-#endif
-
-#endif /* HAVE_CONFIG_H */
-
-#ifdef __POCC__
-# include <sys/types.h>
-# include <unistd.h>
-# define ESRCH 3
-#endif
-
-/*
- * Recent autoconf versions define these symbols in ares_config.h. We don't
- * want them (since they collide with the libcurl ones when we build
- * --enable-debug) so we undef them again here.
- */
-
-#undef PACKAGE_STRING
-#undef PACKAGE_TARNAME
-#undef PACKAGE_VERSION
-#undef PACKAGE_BUGREPORT
-#undef PACKAGE_NAME
-#undef VERSION
-#undef PACKAGE
-
-/* IPv6 compatibility */
-#if !defined(HAVE_AF_INET6)
-#if defined(HAVE_PF_INET6)
-#define AF_INET6 PF_INET6
-#else
-#define AF_INET6 AF_MAX+1
-#endif
-#endif
-
-/*
- * Include macros and defines that should only be processed once.
- */
-
-#ifndef __SETUP_ONCE_H
-#include "setup_once.h"
-#endif
-
-#endif /* HEADER_CARES_SETUP_H */
diff --git a/deps/uv/src/ares/ares_timeout.c b/deps/uv/src/ares/ares_timeout.c
deleted file mode 100644
index 2da4f5f4a..000000000
--- a/deps/uv/src/ares/ares_timeout.c
+++ /dev/null
@@ -1,80 +0,0 @@
-
-/* 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.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#include <time.h>
-
-#include "ares.h"
-#include "ares_private.h"
-
-/* WARNING: Beware that this is linear in the number of outstanding
- * requests! You are probably far better off just calling ares_process()
- * once per second, rather than calling ares_timeout() to figure out
- * when to next call ares_process().
- */
-struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
- struct timeval *tvbuf)
-{
- struct query *query;
- struct list_node* list_head;
- struct list_node* list_node;
- struct timeval now;
- struct timeval nextstop;
- long offset, min_offset;
-
- /* No queries, no timeout (and no fetch of the current time). */
- if (ares__is_list_empty(&(channel->all_queries)))
- return maxtv;
-
- /* Find the minimum timeout for the current set of queries. */
- now = ares__tvnow();
- min_offset = -1;
-
- list_head = &(channel->all_queries);
- for (list_node = list_head->next; list_node != list_head;
- list_node = list_node->next)
- {
- query = list_node->data;
- if (query->timeout.tv_sec == 0)
- continue;
- offset = ares__timeoffset(&now, &query->timeout);
- if (offset < 0)
- offset = 0;
- if (min_offset == -1 || offset < min_offset)
- min_offset = offset;
- }
-
- if(min_offset != -1) {
- nextstop.tv_sec = min_offset/1000;
- nextstop.tv_usec = (min_offset%1000)*1000;
- }
-
- /* If we found a minimum timeout and it's sooner than the one specified in
- * maxtv (if any), return it. Otherwise go with maxtv.
- */
- if (min_offset != -1 && (!maxtv || ares__timedout(maxtv, &nextstop)))
- {
- *tvbuf = nextstop;
- return tvbuf;
- }
- else
- return maxtv;
-}
diff --git a/deps/uv/src/ares/setup_once.h b/deps/uv/src/ares/setup_once.h
deleted file mode 100644
index a333f54a7..000000000
--- a/deps/uv/src/ares/setup_once.h
+++ /dev/null
@@ -1,504 +0,0 @@
-#ifndef __SETUP_ONCE_H
-#define __SETUP_ONCE_H
-
-
-/* Copyright (C) 2004 - 2011 by Daniel Stenberg et al
- *
- * 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.
- */
-
-
-/********************************************************************
- * NOTICE *
- * ======== *
- * *
- * Content of header files lib/setup_once.h and ares/setup_once.h *
- * must be kept in sync. Modify the other one if you change this. *
- * *
- ********************************************************************/
-
-
-/*
- * Inclusion of common header files.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef NEED_MALLOC_H
-#include <malloc.h>
-#endif
-
-#ifdef NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#ifdef TIME_WITH_SYS_TIME
-#include <time.h>
-#endif
-#else
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-#endif
-
-#ifdef WIN32
-#include <io.h>
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_STDBOOL_H
-#include <stdbool.h>
-#endif
-
-
-/*
- * Definition of timeval struct for platforms that don't have it.
- */
-
-#ifndef HAVE_STRUCT_TIMEVAL
-struct timeval {
- long tv_sec;
- long tv_usec;
-};
-#endif
-
-
-/*
- * If we have the MSG_NOSIGNAL define, make sure we use
- * it as the fourth argument of function send()
- */
-
-#ifdef HAVE_MSG_NOSIGNAL
-#define SEND_4TH_ARG MSG_NOSIGNAL
-#else
-#define SEND_4TH_ARG 0
-#endif
-
-
-#if defined(__minix)
-/* Minix doesn't support recv on TCP sockets */
-#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
- (RECV_TYPE_ARG2)(y), \
- (RECV_TYPE_ARG3)(z))
-
-#elif defined(HAVE_RECV)
-/*
- * The definitions for the return type and arguments types
- * of functions recv() and send() belong and come from the
- * configuration file. Do not define them in any other place.
- *
- * HAVE_RECV is defined if you have a function named recv()
- * which is used to read incoming data from sockets. If your
- * function has another name then don't define HAVE_RECV.
- *
- * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
- * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
- * be defined.
- *
- * HAVE_SEND is defined if you have a function named send()
- * which is used to write outgoing data on a connected socket.
- * If yours has another name then don't define HAVE_SEND.
- *
- * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
- * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
- * SEND_TYPE_RETV must also be defined.
- */
-
-#if !defined(RECV_TYPE_ARG1) || \
- !defined(RECV_TYPE_ARG2) || \
- !defined(RECV_TYPE_ARG3) || \
- !defined(RECV_TYPE_ARG4) || \
- !defined(RECV_TYPE_RETV)
- /* */
- Error Missing_definition_of_return_and_arguments_types_of_recv
- /* */
-#else
-#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
- (RECV_TYPE_ARG2)(y), \
- (RECV_TYPE_ARG3)(z), \
- (RECV_TYPE_ARG4)(0))
-#endif
-#else /* HAVE_RECV */
-#ifndef sread
- /* */
- Error Missing_definition_of_macro_sread
- /* */
-#endif
-#endif /* HAVE_RECV */
-
-
-#if defined(__minix)
-/* Minix doesn't support send on TCP sockets */
-#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
- (SEND_TYPE_ARG2)(y), \
- (SEND_TYPE_ARG3)(z))
-
-#elif defined(HAVE_SEND)
-#if !defined(SEND_TYPE_ARG1) || \
- !defined(SEND_QUAL_ARG2) || \
- !defined(SEND_TYPE_ARG2) || \
- !defined(SEND_TYPE_ARG3) || \
- !defined(SEND_TYPE_ARG4) || \
- !defined(SEND_TYPE_RETV)
- /* */
- Error Missing_definition_of_return_and_arguments_types_of_send
- /* */
-#else
-#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
- (SEND_TYPE_ARG2)(y), \
- (SEND_TYPE_ARG3)(z), \
- (SEND_TYPE_ARG4)(SEND_4TH_ARG))
-#endif
-#else /* HAVE_SEND */
-#ifndef swrite
- /* */
- Error Missing_definition_of_macro_swrite
- /* */
-#endif
-#endif /* HAVE_SEND */
-
-
-#if 0
-#if defined(HAVE_RECVFROM)
-/*
- * Currently recvfrom is only used on udp sockets.
- */
-#if !defined(RECVFROM_TYPE_ARG1) || \
- !defined(RECVFROM_TYPE_ARG2) || \
- !defined(RECVFROM_TYPE_ARG3) || \
- !defined(RECVFROM_TYPE_ARG4) || \
- !defined(RECVFROM_TYPE_ARG5) || \
- !defined(RECVFROM_TYPE_ARG6) || \
- !defined(RECVFROM_TYPE_RETV)
- /* */
- Error Missing_definition_of_return_and_arguments_types_of_recvfrom
- /* */
-#else
-#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \
- (RECVFROM_TYPE_ARG2 *)(b), \
- (RECVFROM_TYPE_ARG3) (bl), \
- (RECVFROM_TYPE_ARG4) (0), \
- (RECVFROM_TYPE_ARG5 *)(f), \
- (RECVFROM_TYPE_ARG6 *)(fl))
-#endif
-#else /* HAVE_RECVFROM */
-#ifndef sreadfrom
- /* */
- Error Missing_definition_of_macro_sreadfrom
- /* */
-#endif
-#endif /* HAVE_RECVFROM */
-
-
-#ifdef RECVFROM_TYPE_ARG6_IS_VOID
-# define RECVFROM_ARG6_T int
-#else
-# define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6
-#endif
-#endif /* if 0 */
-
-
-/*
- * Function-like macro definition used to close a socket.
- */
-
-#if defined(HAVE_CLOSESOCKET)
-# define sclose(x) closesocket((x))
-#elif defined(HAVE_CLOSESOCKET_CAMEL)
-# define sclose(x) CloseSocket((x))
-#else
-# define sclose(x) close((x))
-#endif
-
-
-/*
- * Uppercase macro versions of ANSI/ISO is*() functions/macros which
- * avoid negative number inputs with argument byte codes > 127.
- */
-
-#define ISSPACE(x) (isspace((int) ((unsigned char)x)))
-#define ISDIGIT(x) (isdigit((int) ((unsigned char)x)))
-#define ISALNUM(x) (isalnum((int) ((unsigned char)x)))
-#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
-#define ISGRAPH(x) (isgraph((int) ((unsigned char)x)))
-#define ISALPHA(x) (isalpha((int) ((unsigned char)x)))
-#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
-#define ISUPPER(x) (isupper((int) ((unsigned char)x)))
-#define ISLOWER(x) (islower((int) ((unsigned char)x)))
-#define ISASCII(x) (isascii((int) ((unsigned char)x)))
-
-#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \
- (((unsigned char)x) == '\t'))
-
-#define TOLOWER(x) (tolower((int) ((unsigned char)x)))
-
-
-/*
- * 'bool' exists on platforms with <stdbool.h>, i.e. C99 platforms.
- * On non-C99 platforms there's no bool, so define an enum for that.
- * On C99 platforms 'false' and 'true' also exist. Enum uses a
- * global namespace though, so use bool_false and bool_true.
- */
-
-#ifndef HAVE_BOOL_T
- typedef enum {
- bool_false = 0,
- bool_true = 1
- } bool;
-
-/*
- * Use a define to let 'true' and 'false' use those enums. There
- * are currently no use of true and false in libcurl proper, but
- * there are some in the examples. This will cater for any later
- * code happening to use true and false.
- */
-# define false bool_false
-# define true bool_true
-# define HAVE_BOOL_T
-#endif
-
-
-/*
- * Redefine TRUE and FALSE too, to catch current use. With this
- * change, 'bool found = 1' will give a warning on MIPSPro, but
- * 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro,
- * AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too.
- */
-
-#ifndef TRUE
-#define TRUE true
-#endif
-#ifndef FALSE
-#define FALSE false
-#endif
-
-
-/*
- * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
- */
-
-#ifndef HAVE_SIG_ATOMIC_T
-typedef int sig_atomic_t;
-#define HAVE_SIG_ATOMIC_T
-#endif
-
-
-/*
- * Convenience SIG_ATOMIC_T definition
- */
-
-#ifdef HAVE_SIG_ATOMIC_T_VOLATILE
-#define SIG_ATOMIC_T static sig_atomic_t
-#else
-#define SIG_ATOMIC_T static volatile sig_atomic_t
-#endif
-
-
-/*
- * Default return type for signal handlers.
- */
-
-#ifndef RETSIGTYPE
-#define RETSIGTYPE void
-#endif
-
-
-/*
- * Macro used to include code only in debug builds.
- */
-
-#ifdef DEBUGBUILD
-#define DEBUGF(x) x
-#else
-#define DEBUGF(x) do { } while (0)
-#endif
-
-
-/*
- * Macro used to include assertion code only in debug builds.
- */
-
-#if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H)
-#define DEBUGASSERT(x) assert(x)
-#else
-#define DEBUGASSERT(x) do { } while (0)
-#endif
-
-
-/*
- * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno
- * (or equivalent) on this platform to hide platform details to code using it.
- */
-
-#ifdef USE_WINSOCK
-#define SOCKERRNO ((int)WSAGetLastError())
-#define SET_SOCKERRNO(x) (WSASetLastError((int)(x)))
-#else
-#define SOCKERRNO (errno)
-#define SET_SOCKERRNO(x) (errno = (x))
-#endif
-
-
-/*
- * Macro ERRNO / SET_ERRNO() returns / sets the NOT *socket-related* errno
- * (or equivalent) on this platform to hide platform details to code using it.
- */
-
-#if defined(WIN32) && !defined(WATT32)
-#define ERRNO ((int)GetLastError())
-#define SET_ERRNO(x) (SetLastError((DWORD)(x)))
-#else
-#define ERRNO (errno)
-#define SET_ERRNO(x) (errno = (x))
-#endif
-
-
-/*
- * Portable error number symbolic names defined to Winsock error codes.
- */
-
-#ifdef USE_WINSOCK
-#undef EBADF /* override definition in errno.h */
-#define EBADF WSAEBADF
-#undef EINTR /* override definition in errno.h */
-#define EINTR WSAEINTR
-#undef EINVAL /* override definition in errno.h */
-#define EINVAL WSAEINVAL
-#undef EWOULDBLOCK /* override definition in errno.h */
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#undef EINPROGRESS /* override definition in errno.h */
-#define EINPROGRESS WSAEINPROGRESS
-#undef EALREADY /* override definition in errno.h */
-#define EALREADY WSAEALREADY
-#undef ENOTSOCK /* override definition in errno.h */
-#define ENOTSOCK WSAENOTSOCK
-#undef EDESTADDRREQ /* override definition in errno.h */
-#define EDESTADDRREQ WSAEDESTADDRREQ
-#undef EMSGSIZE /* override definition in errno.h */
-#define EMSGSIZE WSAEMSGSIZE
-#undef EPROTOTYPE /* override definition in errno.h */
-#define EPROTOTYPE WSAEPROTOTYPE
-#undef ENOPROTOOPT /* override definition in errno.h */
-#define ENOPROTOOPT WSAENOPROTOOPT
-#undef EPROTONOSUPPORT /* override definition in errno.h */
-#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
-#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
-#undef EOPNOTSUPP /* override definition in errno.h */
-#define EOPNOTSUPP WSAEOPNOTSUPP
-#define EPFNOSUPPORT WSAEPFNOSUPPORT
-#undef EAFNOSUPPORT /* override definition in errno.h */
-#define EAFNOSUPPORT WSAEAFNOSUPPORT
-#undef EADDRINUSE /* override definition in errno.h */
-#define EADDRINUSE WSAEADDRINUSE
-#undef EADDRNOTAVAIL /* override definition in errno.h */
-#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
-#undef ENETDOWN /* override definition in errno.h */
-#define ENETDOWN WSAENETDOWN
-#undef ENETUNREACH /* override definition in errno.h */
-#define ENETUNREACH WSAENETUNREACH
-#undef ENETRESET /* override definition in errno.h */
-#define ENETRESET WSAENETRESET
-#undef ECONNABORTED /* override definition in errno.h */
-#define ECONNABORTED WSAECONNABORTED
-#undef ECONNRESET /* override definition in errno.h */
-#define ECONNRESET WSAECONNRESET
-#undef ENOBUFS /* override definition in errno.h */
-#define ENOBUFS WSAENOBUFS
-#undef EISCONN /* override definition in errno.h */
-#define EISCONN WSAEISCONN
-#undef ENOTCONN /* override definition in errno.h */
-#define ENOTCONN WSAENOTCONN
-#define ESHUTDOWN WSAESHUTDOWN
-#define ETOOMANYREFS WSAETOOMANYREFS
-#undef ETIMEDOUT /* override definition in errno.h */
-#define ETIMEDOUT WSAETIMEDOUT
-#undef ECONNREFUSED /* override definition in errno.h */
-#define ECONNREFUSED WSAECONNREFUSED
-#undef ELOOP /* override definition in errno.h */
-#define ELOOP WSAELOOP
-#ifndef ENAMETOOLONG /* possible previous definition in errno.h */
-#define ENAMETOOLONG WSAENAMETOOLONG
-#endif
-#define EHOSTDOWN WSAEHOSTDOWN
-#undef EHOSTUNREACH /* override definition in errno.h */
-#define EHOSTUNREACH WSAEHOSTUNREACH
-#ifndef ENOTEMPTY /* possible previous definition in errno.h */
-#define ENOTEMPTY WSAENOTEMPTY
-#endif
-#define EPROCLIM WSAEPROCLIM
-#define EUSERS WSAEUSERS
-#define EDQUOT WSAEDQUOT
-#define ESTALE WSAESTALE
-#define EREMOTE WSAEREMOTE
-#endif
-
-
-/*
- * System error codes for Windows CE
- */
-
-#if defined(WIN32) && !defined(HAVE_ERRNO_H)
-#define ENOENT ERROR_FILE_NOT_FOUND
-#define ESRCH ERROR_PATH_NOT_FOUND
-#define ENOMEM ERROR_NOT_ENOUGH_MEMORY
-#define ENOSPC ERROR_INVALID_PARAMETER
-#endif
-
-
-/*
- * Actually use __32_getpwuid() on 64-bit VMS builds for getpwuid()
- */
-
-#if defined(__VMS) && \
- defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
-#define getpwuid __32_getpwuid
-#endif
-
-
-/*
- * Macro argv_item_t hides platform details to code using it.
- */
-
-#ifdef __VMS
-#define argv_item_t __char_ptr32
-#else
-#define argv_item_t char *
-#endif
-
-
-/*
- * We use this ZERO_NULL to avoid picky compiler warnings,
- * when assigning a NULL pointer to a function pointer var.
- */
-
-#define ZERO_NULL 0
-
-
-#endif /* __SETUP_ONCE_H */
-
diff --git a/deps/uv/src/cares.c b/deps/uv/src/cares.c
deleted file mode 100644
index c0acbec84..000000000
--- a/deps/uv/src/cares.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* 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.
- */
-
-#include "uv.h"
-#include "tree.h"
-#include "uv-common.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-struct uv_ares_task_s {
- UV_HANDLE_FIELDS
- ares_socket_t sock;
- uv_poll_t poll_watcher;
- RB_ENTRY(uv_ares_task_s) node;
-};
-
-
-static int cmp_ares_tasks(const uv_ares_task_t* a, const uv_ares_task_t* b) {
- if (a->sock < b->sock) return -1;
- if (a->sock > b->sock) return 1;
- return 0;
-}
-
-
-RB_GENERATE_STATIC(uv__ares_tasks, uv_ares_task_s, node, cmp_ares_tasks)
-
-
-/* Add ares handle to list. */
-static void uv_add_ares_handle(uv_loop_t* loop, uv_ares_task_t* handle) {
- assert(loop == handle->loop);
- RB_INSERT(uv__ares_tasks, &loop->ares_handles, handle);
-}
-
-
-/* Find matching ares handle in list. */
-static uv_ares_task_t* uv_find_ares_handle(uv_loop_t* loop, ares_socket_t sock) {
- uv_ares_task_t handle;
- handle.sock = sock;
- return RB_FIND(uv__ares_tasks, &loop->ares_handles, &handle);
-}
-
-
-/* Remove ares handle from list. */
-static void uv_remove_ares_handle(uv_ares_task_t* handle) {
- RB_REMOVE(uv__ares_tasks, &handle->loop->ares_handles, handle);
-}
-
-
-/* Returns 1 if the ares_handles list is empty, 0 otherwise. */
-static int uv_ares_handles_empty(uv_loop_t* loop) {
- return RB_EMPTY(&loop->ares_handles);
-}
-
-
-/* This is called once per second by loop->timer. It is used to constantly */
-/* call back into c-ares for possibly processing timeouts. */
-static void uv__ares_timeout(uv_timer_t* handle, int status) {
- assert(!uv_ares_handles_empty(handle->loop));
- ares_process_fd(handle->loop->channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
-}
-
-
-static void uv__ares_poll_cb(uv_poll_t* watcher, int status, int events) {
- uv_loop_t* loop = watcher->loop;
- uv_ares_task_t* task = container_of(watcher, uv_ares_task_t, poll_watcher);
-
- /* Reset the idle timer */
- uv_timer_again(&loop->ares_timer);
-
- if (status < 0) {
- /* An error happened. Just pretend that the socket is both readable and */
- /* writable. */
- ares_process_fd(loop->channel, task->sock, task->sock);
- return;
- }
-
- /* Process DNS responses */
- ares_process_fd(loop->channel,
- events & UV_READABLE ? task->sock : ARES_SOCKET_BAD,
- events & UV_WRITABLE ? task->sock : ARES_SOCKET_BAD);
-}
-
-
-static void uv__ares_poll_close_cb(uv_handle_t* watcher) {
- uv_ares_task_t* task = container_of(watcher, uv_ares_task_t, poll_watcher);
- free(task);
-}
-
-
-/* Allocates and returns a new uv_ares_task_t */
-static uv_ares_task_t* uv__ares_task_create(uv_loop_t* loop, ares_socket_t sock) {
- uv_ares_task_t* task = (uv_ares_task_t*) malloc(sizeof *task);
-
- if (task == NULL) {
- /* Out of memory. */
- return NULL;
- }
-
- task->loop = loop;
- task->sock = sock;
-
- if (uv_poll_init_socket(loop, &task->poll_watcher, sock) < 0) {
- /* This should never happen. */
- free(task);
- return NULL;
- }
-
- return task;
-}
-
-
-/* Callback from ares when socket operation is started */
-static void uv__ares_sockstate_cb(void* data, ares_socket_t sock,
- int read, int write) {
- uv_loop_t* loop = (uv_loop_t*) data;
- uv_ares_task_t* task;
-
- task = uv_find_ares_handle(loop, sock);
-
- if (read || write) {
- if (!task) {
- /* New socket */
-
- /* If this is the first socket then start the timer. */
- if (!uv_is_active((uv_handle_t*) &loop->ares_timer)) {
- assert(uv_ares_handles_empty(loop));
- uv_timer_start(&loop->ares_timer, uv__ares_timeout, 1000, 1000);
- }
-
- task = uv__ares_task_create(loop, sock);
- if (task == NULL) {
- /* This should never happen unless we're out of memory or something */
- /* is seriously wrong. The socket won't be polled, but the the query */
- /* will eventually time out. */
- return;
- }
-
- uv_add_ares_handle(loop, task);
- }
-
- /* This should never fail. If it fails anyway, the query will eventually */
- /* time out. */
- uv_poll_start(&task->poll_watcher,
- (read ? UV_READABLE : 0) | (write ? UV_WRITABLE : 0),
- uv__ares_poll_cb);
-
- } else {
- /* read == 0 and write == 0 this is c-ares's way of notifying us that */
- /* the socket is now closed. We must free the data associated with */
- /* socket. */
- assert(task &&
- "When an ares socket is closed we should have a handle for it");
-
- uv_remove_ares_handle(task);
- uv_close((uv_handle_t*) &task->poll_watcher, uv__ares_poll_close_cb);
-
- if (uv_ares_handles_empty(loop)) {
- uv_timer_stop(&loop->ares_timer);
- }
- }
-}
-
-
-/* C-ares integration initialize and terminate */
-int uv_ares_init_options(uv_loop_t* loop, ares_channel *channelptr,
- struct ares_options *options, int optmask) {
- int rc;
-
- /* only allow single init at a time */
- if (loop->channel != NULL) {
- uv__set_artificial_error(loop, UV_EALREADY);
- return -1;
- }
-
- /* set our callback as an option */
- options->sock_state_cb = uv__ares_sockstate_cb;
- options->sock_state_cb_data = loop;
- optmask |= ARES_OPT_SOCK_STATE_CB;
-
- /* We do the call to ares_init_option for caller. */
- rc = ares_init_options(channelptr, options, optmask);
-
- /* if success, save channel */
- if (rc == ARES_SUCCESS) {
- loop->channel = *channelptr;
- }
-
- /* Initialize the timeout timer. The timer won't be started until the */
- /* first socket is opened. */
- uv_timer_init(loop, &loop->ares_timer);
-
- return rc;
-}
-
-
-void uv_ares_destroy(uv_loop_t* loop, ares_channel channel) {
- /* Only allow destroy if did init. */
- if (loop->channel) {
- uv_timer_stop(&loop->ares_timer);
- ares_destroy(channel);
- loop->channel = NULL;
- }
-}
diff --git a/deps/uv/src/fs-poll.c b/deps/uv/src/fs-poll.c
index 71eaebc0a..ad27f1843 100644
--- a/deps/uv/src/fs-poll.c
+++ b/deps/uv/src/fs-poll.c
@@ -49,7 +49,6 @@ static uv_statbuf_t zero_statbuf;
int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) {
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_POLL);
- loop->counters.fs_poll_init++;
return 0;
}
@@ -104,11 +103,15 @@ int uv_fs_poll_stop(uv_fs_poll_t* handle) {
ctx = handle->poll_ctx;
assert(ctx != NULL);
assert(ctx->parent_handle != NULL);
-
ctx->parent_handle = NULL;
- uv_timer_stop(&ctx->timer_handle);
-
handle->poll_ctx = NULL;
+
+ /* Close the timer if it's active. If it's inactive, there's a stat request
+ * in progress and poll_cb will take care of the cleanup.
+ */
+ if (uv__is_active(&ctx->timer_handle))
+ uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
+
uv__handle_stop(handle);
return 0;
@@ -124,12 +127,7 @@ static void timer_cb(uv_timer_t* timer, int status) {
struct poll_ctx* ctx;
ctx = container_of(timer, struct poll_ctx, timer_handle);
-
- if (ctx->parent_handle == NULL) { /* handle has been stopped or closed */
- uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
- return;
- }
-
+ assert(ctx->parent_handle != NULL);
assert(ctx->parent_handle->poll_ctx == ctx);
ctx->start_time = uv_now(ctx->loop);
@@ -160,7 +158,7 @@ static void poll_cb(uv_fs_t* req) {
goto out;
}
- statbuf = req->ptr;
+ statbuf = &req->statbuf;
if (ctx->busy_polling != 0)
if (ctx->busy_polling < 0 || !statbuf_eq(&ctx->statbuf, statbuf))
@@ -172,6 +170,11 @@ static void poll_cb(uv_fs_t* req) {
out:
uv_fs_req_cleanup(req);
+ if (ctx->parent_handle == NULL) { /* handle has been stopped by callback */
+ uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
+ return;
+ }
+
/* Reschedule timer, subtract the delay from doing the stat(). */
interval = ctx->interval;
interval -= (uv_now(ctx->loop) - ctx->start_time) % interval;
@@ -187,15 +190,15 @@ static void timer_close_cb(uv_handle_t* handle) {
static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b) {
-#ifdef _WIN32
+#if defined(_WIN32)
return a->st_mtime == b->st_mtime
&& a->st_size == b->st_size
&& a->st_mode == b->st_mode;
#else
/* Jump through a few hoops to get sub-second granularity on Linux. */
-# if __linux__
-# if __USE_MISC /* _BSD_SOURCE || _SVID_SOURCE */
+# if defined(__linux__)
+# if defined(__USE_MISC) /* _BSD_SOURCE || _SVID_SOURCE */
if (a->st_ctim.tv_nsec != b->st_ctim.tv_nsec) return 0;
if (a->st_mtim.tv_nsec != b->st_mtim.tv_nsec) return 0;
# else
@@ -205,7 +208,7 @@ static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b) {
# endif
/* Jump through different hoops on OS X. */
-# if __APPLE__
+# if defined(__APPLE__)
# if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
if (a->st_ctimespec.tv_nsec != b->st_ctimespec.tv_nsec) return 0;
if (a->st_mtimespec.tv_nsec != b->st_mtimespec.tv_nsec) return 0;
@@ -231,15 +234,14 @@ static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b) {
}
-#ifdef _WIN32
+#if defined(_WIN32)
#include "win/internal.h"
#include "win/handle-inl.h"
void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle) {
- assert(handle->flags & UV_HANDLE_CLOSING);
+ assert(handle->flags & UV__HANDLE_CLOSING);
assert(!(handle->flags & UV_HANDLE_CLOSED));
- uv__handle_stop(handle);
uv__handle_close(handle);
}
diff --git a/deps/uv/src/inet.c b/deps/uv/src/inet.c
new file mode 100644
index 000000000..939a9fa57
--- /dev/null
+++ b/deps/uv/src/inet.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
+#include "uv.h"
+#include "uv-common.h"
+
+
+static const uv_err_t uv_eafnosupport_ = { UV_EAFNOSUPPORT, 0 };
+static const uv_err_t uv_enospc_ = { UV_ENOSPC, 0 };
+static const uv_err_t uv_einval_ = { UV_EINVAL, 0 };
+
+static uv_err_t inet_ntop4(const unsigned char *src, char *dst, size_t size);
+static uv_err_t inet_ntop6(const unsigned char *src, char *dst, size_t size);
+static uv_err_t inet_pton4(const char *src, unsigned char *dst);
+static uv_err_t inet_pton6(const char *src, unsigned char *dst);
+
+
+uv_err_t uv_inet_ntop(int af, const void* src, char* dst, size_t size) {
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+ default:
+ return uv_eafnosupport_;
+ }
+ /* NOTREACHED */
+}
+
+
+static uv_err_t inet_ntop4(const unsigned char *src, char *dst, size_t size) {
+ static const char fmt[] = "%u.%u.%u.%u";
+ char tmp[sizeof "255.255.255.255"];
+ size_t l;
+
+#ifndef _WIN32
+ l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
+#else
+ l = _snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
+#endif
+ if (l <= 0 || l >= size) {
+ return uv_enospc_;
+ }
+ strncpy(dst, tmp, size);
+ dst[size - 1] = '\0';
+ return uv_ok_;
+}
+
+
+static uv_err_t inet_ntop6(const unsigned char *src, char *dst, size_t size) {
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ struct { int base, len; } best, cur;
+ unsigned int words[sizeof(struct in6_addr) / sizeof(uint16_t)];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof words);
+ for (i = 0; i < (int) sizeof(struct in6_addr); i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ best.len = 0;
+ cur.base = -1;
+ cur.len = 0;
+ for (i = 0; i < (int) ARRAY_SIZE(words); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (int) ARRAY_SIZE(words); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 && (best.len == 6 ||
+ (best.len == 7 && words[7] != 0x0001) ||
+ (best.len == 5 && words[5] == 0xffff))) {
+ uv_err_t err = inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp));
+ if (err.code != UV_OK)
+ return err;
+ tp += strlen(tp);
+ break;
+ }
+ tp += sprintf(tp, "%x", words[i]);
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((size_t)(tp - tmp) > size) {
+ return uv_enospc_;
+ }
+ strcpy(dst, tmp);
+ return uv_ok_;
+}
+
+
+uv_err_t uv_inet_pton(int af, const char* src, void* dst) {
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+ default:
+ return uv_eafnosupport_;
+ }
+ /* NOTREACHED */
+}
+
+
+static uv_err_t inet_pton4(const char *src, unsigned char *dst) {
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ unsigned char tmp[sizeof(struct in_addr)], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ unsigned int nw = *tp * 10 + (pch - digits);
+
+ if (saw_digit && *tp == 0)
+ return uv_einval_;
+ if (nw > 255)
+ return uv_einval_;
+ *tp = nw;
+ if (!saw_digit) {
+ if (++octets > 4)
+ return uv_einval_;
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return uv_einval_;
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return uv_einval_;
+ }
+ if (octets < 4)
+ return uv_einval_;
+ memcpy(dst, tmp, sizeof(struct in_addr));
+ return uv_ok_;
+}
+
+
+static uv_err_t inet_pton6(const char *src, unsigned char *dst) {
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ unsigned char tmp[sizeof(struct in6_addr)], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, seen_xdigits;
+ unsigned int val;
+
+ memset((tp = tmp), '\0', sizeof tmp);
+ endp = tp + sizeof tmp;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return uv_einval_;
+ curtok = src;
+ seen_xdigits = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (++seen_xdigits > 4)
+ return uv_einval_;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!seen_xdigits) {
+ if (colonp)
+ return uv_einval_;
+ colonp = tp;
+ continue;
+ } else if (*src == '\0') {
+ return uv_einval_;
+ }
+ if (tp + sizeof(uint16_t) > endp)
+ return uv_einval_;
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ seen_xdigits = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + sizeof(struct in_addr)) <= endp)) {
+ uv_err_t err = inet_pton4(curtok, tp);
+ if (err.code == 0) {
+ tp += sizeof(struct in_addr);
+ seen_xdigits = 0;
+ break; /*%< '\\0' was seen by inet_pton4(). */
+ }
+ }
+ return uv_einval_;
+ }
+ if (seen_xdigits) {
+ if (tp + sizeof(uint16_t) > endp)
+ return uv_einval_;
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ if (tp == endp)
+ return uv_einval_;
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return uv_einval_;
+ memcpy(dst, tmp, sizeof tmp);
+ return uv_ok_;
+}
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
new file mode 100644
index 000000000..5ea33bbcd
--- /dev/null
+++ b/deps/uv/src/unix/aix.c
@@ -0,0 +1,393 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <utmp.h>
+
+#include <sys/protosw.h>
+#include <libperfstat.h>
+#include <sys/proc.h>
+#include <sys/procfs.h>
+
+uint64_t uv__hrtime(void) {
+ uint64_t G = 1000000000;
+ timebasestruct_t t;
+ read_wall_time(&t, TIMEBASE_SZ);
+ time_base_to_time(&t, TIMEBASE_SZ);
+ return (uint64_t) t.tb_high * G + t.tb_low;
+}
+
+
+/*
+ * We could use a static buffer for the path manipulations that we need outside
+ * of the function, but this function could be called by multiple consumers and
+ * we don't want to potentially create a race condition in the use of snprintf.
+ */
+int uv_exepath(char* buffer, size_t* size) {
+ ssize_t res;
+ char pp[64], cwdl[PATH_MAX];
+ size_t cwdl_len;
+ struct psinfo ps;
+ int fd;
+
+ if (buffer == NULL)
+ return (-1);
+
+ if (size == NULL)
+ return (-1);
+
+ (void) snprintf(pp, sizeof(pp), "/proc/%lu/cwd", (unsigned long) getpid());
+
+ res = readlink(pp, cwdl, sizeof(cwdl) - 1);
+ if (res < 0)
+ return res;
+
+ cwdl[res] = '\0';
+ cwdl_len = res;
+
+ (void) snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid());
+ fd = open(pp, O_RDONLY);
+ if (fd < 0)
+ return fd;
+
+ res = read(fd, &ps, sizeof(ps));
+ close(fd);
+ if (res < 0)
+ return res;
+
+ (void) snprintf(buffer, *size, "%s%s", cwdl, ps.pr_fname);
+ *size = strlen(buffer);
+ return 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ perfstat_memory_total_t mem_total;
+ int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1);
+ if (result == -1) {
+ return 0;
+ }
+ return mem_total.real_free * 4096;
+}
+
+
+uint64_t uv_get_total_memory(void) {
+ perfstat_memory_total_t mem_total;
+ int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1);
+ if (result == -1) {
+ return 0;
+ }
+ return mem_total.real_total * 4096;
+}
+
+
+void uv_loadavg(double avg[3]) {
+ perfstat_cpu_total_t ps_total;
+ int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
+ if (result == -1) {
+ avg[0] = 0.; avg[1] = 0.; avg[2] = 0.;
+ return;
+ }
+ avg[0] = ps_total.loadavg[0] / (double)(1 << SBITS);
+ avg[1] = ps_total.loadavg[1] / (double)(1 << SBITS);
+ avg[2] = ps_total.loadavg[2] / (double)(1 << SBITS);
+}
+
+
+int uv_fs_event_init(uv_loop_t* loop,
+ uv_fs_event_t* handle,
+ const char* filename,
+ uv_fs_event_cb cb,
+ int flags) {
+ loop->counters.fs_event_init++;
+ uv__set_sys_error(loop, ENOSYS);
+ return -1;
+}
+
+
+void uv__fs_event_close(uv_fs_event_t* handle) {
+ UNREACHABLE();
+}
+
+
+char** uv_setup_args(int argc, char** argv) {
+ return argv;
+}
+
+
+uv_err_t uv_set_process_title(const char* title) {
+ return uv_ok_;
+}
+
+
+uv_err_t uv_get_process_title(char* buffer, size_t size) {
+ if (size > 0) {
+ buffer[0] = '\0';
+ }
+ return uv_ok_;
+}
+
+
+uv_err_t uv_resident_set_memory(size_t* rss) {
+ char pp[64];
+ psinfo_t psinfo;
+ uv_err_t err;
+ int fd;
+
+ (void) snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid());
+
+ fd = open(pp, O_RDONLY);
+ if (fd == -1)
+ return uv__new_sys_error(errno);
+
+ err = uv_ok_;
+
+ if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo))
+ *rss = (size_t)psinfo.pr_rssize * 1024;
+ else
+ err = uv__new_sys_error(EINVAL);
+
+ close(fd);
+
+ return err;
+}
+
+
+uv_err_t uv_uptime(double* uptime) {
+ struct utmp *utmp_buf;
+ size_t entries = 0;
+ time_t boot_time;
+
+ utmpname(UTMP_FILE);
+
+ setutent();
+
+ while ((utmp_buf = getutent()) != NULL) {
+ if (utmp_buf->ut_user[0] && utmp_buf->ut_type == USER_PROCESS)
+ ++entries;
+ if (utmp_buf->ut_type == BOOT_TIME)
+ boot_time = utmp_buf->ut_time;
+ }
+
+ endutent();
+
+ if (boot_time == 0)
+ return uv__new_artificial_error(UV_ENOSYS);
+
+ *uptime = time(NULL) - boot_time;
+ return uv_ok_;
+}
+
+
+uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ uv_cpu_info_t* cpu_info;
+ perfstat_cpu_total_t ps_total;
+ perfstat_cpu_t* ps_cpus;
+ perfstat_id_t cpu_id;
+ int result, ncpus, idx = 0;
+
+ result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
+ if (result == -1) {
+ return uv__new_artificial_error(UV_ENOSYS);
+ }
+
+ ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0);
+ if (result == -1) {
+ return uv__new_artificial_error(UV_ENOSYS);
+ }
+
+ ps_cpus = (perfstat_cpu_t*) malloc(ncpus * sizeof(perfstat_cpu_t));
+ if (!ps_cpus) {
+ return uv__new_artificial_error(UV_ENOMEM);
+ }
+
+ strcpy(cpu_id.name, FIRST_CPU);
+ result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus);
+ if (result == -1) {
+ free(ps_cpus);
+ return uv__new_artificial_error(UV_ENOSYS);
+ }
+
+ *cpu_infos = (uv_cpu_info_t*) malloc(ncpus * sizeof(uv_cpu_info_t));
+ if (!*cpu_infos) {
+ free(ps_cpus);
+ return uv__new_artificial_error(UV_ENOMEM);
+ }
+
+ *count = ncpus;
+
+ cpu_info = *cpu_infos;
+ while (idx < ncpus) {
+ cpu_info->speed = (int)(ps_total.processorHZ / 1000000);
+ cpu_info->model = strdup(ps_total.description);
+ cpu_info->cpu_times.user = ps_cpus[idx].user;
+ cpu_info->cpu_times.sys = ps_cpus[idx].sys;
+ cpu_info->cpu_times.idle = ps_cpus[idx].idle;
+ cpu_info->cpu_times.irq = ps_cpus[idx].wait;
+ cpu_info->cpu_times.nice = 0;
+ cpu_info++;
+ idx++;
+ }
+
+ free(ps_cpus);
+ return uv_ok_;
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
+ int* count) {
+ uv_interface_address_t* address;
+ int sockfd, size = 1;
+ struct ifconf ifc;
+ struct ifreq *ifr, *p, flg;
+
+ *count = 0;
+
+ if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
+ return uv__new_artificial_error(UV_ENOSYS);
+ }
+
+ if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
+ close(sockfd);
+ return uv__new_artificial_error(UV_ENOSYS);
+ }
+
+ ifc.ifc_req = (struct ifreq*)malloc(size);
+ ifc.ifc_len = size;
+ if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
+ close(sockfd);
+ return uv__new_artificial_error(UV_ENOSYS);
+ }
+
+#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
+
+ /* Count all up and running ipv4/ipv6 addresses */
+ ifr = ifc.ifc_req;
+ while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
+ p = ifr;
+ ifr = (struct ifreq*)
+ ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
+
+ if (!(p->ifr_addr.sa_family == AF_INET6 ||
+ p->ifr_addr.sa_family == AF_INET))
+ continue;
+
+ memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
+ if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
+ close(sockfd);
+ return uv__new_artificial_error(UV_ENOSYS);
+ }
+
+ if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
+ continue;
+
+ (*count)++;
+ }
+
+ /* Alloc the return interface structs */
+ *addresses = (uv_interface_address_t*)
+ malloc(*count * sizeof(uv_interface_address_t));
+ if (!(*addresses)) {
+ close(sockfd);
+ return uv__new_artificial_error(UV_ENOMEM);
+ }
+ address = *addresses;
+
+ ifr = ifc.ifc_req;
+ while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
+ p = ifr;
+ ifr = (struct ifreq*)
+ ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
+
+ if (!(p->ifr_addr.sa_family == AF_INET6 ||
+ p->ifr_addr.sa_family == AF_INET))
+ continue;
+
+ memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
+ if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
+ close(sockfd);
+ return uv__new_artificial_error(UV_ENOSYS);
+ }
+
+ if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
+ continue;
+
+ /* All conditions above must match count loop */
+
+ address->name = strdup(p->ifr_name);
+
+ if (p->ifr_addr.sa_family == AF_INET6) {
+ address->address.address6 = *((struct sockaddr_in6 *)&p->ifr_addr);
+ } else {
+ address->address.address4 = *((struct sockaddr_in *)&p->ifr_addr);
+ }
+
+ address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
+
+ address++;
+ }
+
+#undef ADDR_SIZE
+
+ close(sockfd);
+ return uv_ok_;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+ int count) {
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ free(addresses[i].name);
+ }
+
+ free(addresses);
+}
diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c
index f782e158a..43f54ed4b 100644
--- a/deps/uv/src/unix/async.c
+++ b/deps/uv/src/unix/async.c
@@ -18,25 +18,31 @@
* IN THE SOFTWARE.
*/
+/* This file contains both the uv__async internal infrastructure and the
+ * user-facing uv_async_t functions.
+ */
+
#include "uv.h"
#include "internal.h"
#include <errno.h>
#include <assert.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
-static int uv__async_init(uv_loop_t* loop);
-static void uv__async_io(uv_loop_t* loop, uv__io_t* handle, int events);
+static void uv__async_event(uv_loop_t* loop,
+ struct uv__async* w,
+ unsigned int nevents);
+static int uv__async_make_pending(int* pending);
+static int uv__async_eventfd(void);
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
- if (uv__async_init(loop))
+ if (uv__async_start(loop, &loop->async_watcher, uv__async_event))
return uv__set_sys_error(loop, errno);
uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC);
- loop->counters.async_init++;
-
handle->async_cb = async_cb;
handle->pending = 0;
@@ -48,16 +54,8 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
int uv_async_send(uv_async_t* handle) {
- int r;
-
- handle->pending = 1; /* XXX needs a memory barrier? */
-
- do
- r = write(handle->loop->async_pipefd[1], "x", 1);
- while (r == -1 && errno == EINTR);
-
- if (r == -1 && errno != EAGAIN && errno != EWOULDBLOCK)
- return uv__set_sys_error(handle->loop, errno);
+ if (uv__async_make_pending(&handle->pending) == 0)
+ uv__async_send(&handle->loop->async_watcher);
return 0;
}
@@ -69,31 +67,64 @@ void uv__async_close(uv_async_t* handle) {
}
-static int uv__async_init(uv_loop_t* loop) {
- if (loop->async_pipefd[0] != -1)
- return 0;
+static void uv__async_event(uv_loop_t* loop,
+ struct uv__async* w,
+ unsigned int nevents) {
+ ngx_queue_t* q;
+ uv_async_t* h;
+
+ ngx_queue_foreach(q, &loop->async_handles) {
+ h = ngx_queue_data(q, uv_async_t, queue);
+ if (!h->pending) continue;
+ h->pending = 0;
+ h->async_cb(h, 0);
+ }
+}
- if (uv__make_pipe(loop->async_pipefd, UV__F_NONBLOCK))
- return -1;
- uv__io_init(&loop->async_watcher,
- uv__async_io,
- loop->async_pipefd[0],
- UV__IO_READ);
- uv__io_start(loop, &loop->async_watcher);
+static int uv__async_make_pending(int* pending) {
+ /* Do a cheap read first. */
+ if (ACCESS_ONCE(int, *pending) != 0)
+ return 1;
+ /* Micro-optimization: use atomic memory operations to detect if we've been
+ * preempted by another thread and don't have to make an expensive syscall.
+ * This speeds up the heavily contended case by about 1-2% and has little
+ * if any impact on the non-contended case.
+ *
+ * Use XCHG instead of the CMPXCHG that __sync_val_compare_and_swap() emits
+ * on x86, it's about 4x faster. It probably makes zero difference in the
+ * grand scheme of things but I'm OCD enough not to let this one pass.
+ */
+#if defined(__i386__) || defined(__x86_64__)
+ {
+ unsigned int val = 1;
+ __asm__ __volatile__ ("xchgl %0, %1"
+ : "+r" (val)
+ : "m" (*pending));
+ return val != 0;
+ }
+#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0)
+ return __sync_val_compare_and_swap(pending, 0, 1) != 0;
+#else
+ ACCESS_ONCE(int, *pending) = 1;
return 0;
+#endif
}
-static void uv__async_io(uv_loop_t* loop, uv__io_t* handle, int events) {
+static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ struct uv__async* wa;
char buf[1024];
- ngx_queue_t* q;
- uv_async_t* h;
+ unsigned n;
ssize_t r;
- while (1) {
- r = read(loop->async_pipefd[0], buf, sizeof(buf));
+ n = 0;
+ for (;;) {
+ r = read(w->fd, buf, sizeof(buf));
+
+ if (r > 0)
+ n += r;
if (r == sizeof(buf))
continue;
@@ -110,10 +141,141 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* handle, int events) {
abort();
}
- ngx_queue_foreach(q, &loop->async_handles) {
- h = ngx_queue_data(q, uv_async_t, queue);
- if (!h->pending) continue;
- h->pending = 0;
- h->async_cb(h, 0);
+ wa = container_of(w, struct uv__async, io_watcher);
+
+#if defined(__linux__)
+ if (wa->wfd == -1) {
+ uint64_t val;
+ assert(n == sizeof(val));
+ memcpy(&val, buf, sizeof(val)); /* Avoid alignment issues. */
+ wa->cb(loop, wa, val);
+ return;
}
+#endif
+
+ wa->cb(loop, wa, n);
+}
+
+
+void uv__async_send(struct uv__async* wa) {
+ const void* buf;
+ ssize_t len;
+ int fd;
+ int r;
+
+ buf = "";
+ len = 1;
+ fd = wa->wfd;
+
+#if defined(__linux__)
+ if (fd == -1) {
+ static const uint64_t val = 1;
+ buf = &val;
+ len = sizeof(val);
+ fd = wa->io_watcher.fd; /* eventfd */
+ }
+#endif
+
+ do
+ r = write(fd, buf, len);
+ while (r == -1 && errno == EINTR);
+
+ if (r == len)
+ return;
+
+ if (r == -1)
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ return;
+
+ abort();
+}
+
+
+void uv__async_init(struct uv__async* wa) {
+ wa->io_watcher.fd = -1;
+ wa->wfd = -1;
+}
+
+
+int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
+ int pipefd[2];
+ int fd;
+
+ if (wa->io_watcher.fd != -1)
+ return 0;
+
+ fd = uv__async_eventfd();
+ if (fd >= 0) {
+ pipefd[0] = fd;
+ pipefd[1] = -1;
+ }
+ else if (fd != -ENOSYS)
+ return -1;
+ else if (uv__make_pipe(pipefd, UV__F_NONBLOCK))
+ return -1;
+
+ uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]);
+ uv__io_start(loop, &wa->io_watcher, UV__POLLIN);
+ wa->wfd = pipefd[1];
+ wa->cb = cb;
+
+ return 0;
+}
+
+
+void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) {
+ if (wa->io_watcher.fd == -1)
+ return;
+
+ uv__io_stop(loop, &wa->io_watcher, UV__POLLIN);
+ close(wa->io_watcher.fd);
+ wa->io_watcher.fd = -1;
+
+ if (wa->wfd != -1) {
+ close(wa->wfd);
+ wa->wfd = -1;
+ }
+}
+
+
+static int uv__async_eventfd() {
+#if defined(__linux__)
+ static int no_eventfd2;
+ static int no_eventfd;
+ int fd;
+
+ if (no_eventfd2)
+ goto skip_eventfd2;
+
+ fd = uv__eventfd2(0, UV__EFD_CLOEXEC | UV__EFD_NONBLOCK);
+ if (fd != -1)
+ return fd;
+
+ if (errno != ENOSYS)
+ return -errno;
+
+ no_eventfd2 = 1;
+
+skip_eventfd2:
+
+ if (no_eventfd)
+ goto skip_eventfd;
+
+ fd = uv__eventfd(0);
+ if (fd != -1) {
+ uv__cloexec(fd, 1);
+ uv__nonblock(fd, 1);
+ return fd;
+ }
+
+ if (errno != ENOSYS)
+ return -errno;
+
+ no_eventfd = 1;
+
+skip_eventfd:
+
+#endif
+
+ return -ENOSYS;
}
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index f3636e285..a281f2e08 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -35,7 +35,7 @@
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#include <limits.h> /* PATH_MAX */
+#include <limits.h> /* INT_MAX, PATH_MAX */
#include <sys/uio.h> /* writev */
#ifdef __linux__
@@ -49,18 +49,32 @@
#ifdef __APPLE__
# include <mach-o/dyld.h> /* _NSGetExecutablePath */
+# include <sys/filio.h>
+# include <sys/ioctl.h>
#endif
#ifdef __FreeBSD__
# include <sys/sysctl.h>
+# include <sys/filio.h>
+# include <sys/ioctl.h>
# include <sys/wait.h>
#endif
+static void uv__run_pending(uv_loop_t* loop);
+
static uv_loop_t default_loop_struct;
static uv_loop_t* default_loop_ptr;
+uint64_t uv_hrtime(void) {
+ return uv__hrtime();
+}
+
+
void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
+ assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
+
+ handle->flags |= UV_CLOSING;
handle->close_cb = close_cb;
switch (handle->type) {
@@ -69,10 +83,13 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
break;
case UV_TTY:
- case UV_TCP:
uv__stream_close((uv_stream_t*)handle);
break;
+ case UV_TCP:
+ uv__tcp_close((uv_tcp_t*)handle);
+ break;
+
case UV_UDP:
uv__udp_close((uv_udp_t*)handle);
break;
@@ -113,12 +130,23 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
uv__fs_poll_close((uv_fs_poll_t*)handle);
break;
+ case UV_SIGNAL:
+ uv__signal_close((uv_signal_t*) handle);
+ /* Signal handles may not be closed immediately. The signal code will */
+ /* itself close uv__make_close_pending whenever appropriate. */
+ return;
+
default:
assert(0);
}
- handle->flags |= UV_CLOSING;
+ uv__make_close_pending(handle);
+}
+
+void uv__make_close_pending(uv_handle_t* handle) {
+ assert(handle->flags & UV_CLOSING);
+ assert(!(handle->flags & UV_CLOSED));
handle->next_closing = handle->loop->closing_handles;
handle->loop->closing_handles = handle;
}
@@ -140,14 +168,12 @@ static void uv__finish_close(uv_handle_t* handle) {
case UV_FS_EVENT:
case UV_FS_POLL:
case UV_POLL:
+ case UV_SIGNAL:
break;
case UV_NAMED_PIPE:
case UV_TCP:
case UV_TTY:
- assert(!uv__io_active(&((uv_stream_t*)handle)->read_watcher));
- assert(!uv__io_active(&((uv_stream_t*)handle)->write_watcher));
- assert(((uv_stream_t*)handle)->fd == -1);
uv__stream_destroy((uv_stream_t*)handle);
break;
@@ -227,7 +253,15 @@ void uv_loop_delete(uv_loop_t* loop) {
}
-static unsigned int uv__poll_timeout(uv_loop_t* loop) {
+int uv_backend_fd(const uv_loop_t* loop) {
+ return loop->backend_fd;
+}
+
+
+int uv_backend_timeout(const uv_loop_t* loop) {
+ if (loop->stop_flag != 0)
+ return 0;
+
if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop))
return 0;
@@ -241,43 +275,54 @@ static unsigned int uv__poll_timeout(uv_loop_t* loop) {
}
-static void uv__poll(uv_loop_t* loop) {
- void ev__run(EV_P_ ev_tstamp waittime);
- ev_invoke_pending(loop->ev);
- ev__run(loop->ev, uv__poll_timeout(loop) / 1000.);
- ev_invoke_pending(loop->ev);
+static int uv__loop_alive(uv_loop_t* loop) {
+ return uv__has_active_handles(loop) ||
+ uv__has_active_reqs(loop) ||
+ loop->closing_handles != NULL;
}
-static int uv__run(uv_loop_t* loop) {
- uv_update_time(loop);
- uv__run_timers(loop);
- uv__run_idle(loop);
- uv__run_prepare(loop);
- uv__poll(loop);
- uv__run_check(loop);
- uv__run_closing_handles(loop);
- return uv__has_active_handles(loop) || uv__has_active_reqs(loop);
-}
+int uv_run(uv_loop_t* loop, uv_run_mode mode) {
+ int timeout;
+ int r;
+ r = uv__loop_alive(loop);
+ while (r != 0 && loop->stop_flag == 0) {
+ uv__update_time(loop);
+ uv__run_timers(loop);
+ uv__run_idle(loop);
+ uv__run_prepare(loop);
+ uv__run_pending(loop);
-int uv_run(uv_loop_t* loop) {
- while (uv__run(loop));
- return 0;
-}
+ timeout = 0;
+ if ((mode & UV_RUN_NOWAIT) == 0)
+ timeout = uv_backend_timeout(loop);
+ uv__io_poll(loop, timeout);
+ uv__run_check(loop);
+ uv__run_closing_handles(loop);
+ r = uv__loop_alive(loop);
-int uv_run_once(uv_loop_t* loop) {
- return uv__run(loop);
+ if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
+ break;
+ }
+
+ /* The if statement lets gcc compile it to a conditional store. Avoids
+ * dirtying a cache line.
+ */
+ if (loop->stop_flag != 0)
+ loop->stop_flag = 0;
+
+ return r;
}
void uv_update_time(uv_loop_t* loop) {
- loop->time = uv_hrtime() / 1000000;
+ uv__update_time(loop);
}
-int64_t uv_now(uv_loop_t* loop) {
+uint64_t uv_now(uv_loop_t* loop) {
return loop->time;
}
@@ -287,114 +332,6 @@ int uv_is_active(const uv_handle_t* handle) {
}
-static int uv_getaddrinfo_done(eio_req* req_) {
- uv_getaddrinfo_t* req = req_->data;
- struct addrinfo *res = req->res;
-#if __sun
- size_t hostlen;
-
- if (req->hostname)
- hostlen = strlen(req->hostname);
- else
- hostlen = 0;
-#endif
-
- req->res = NULL;
-
- uv__req_unregister(req->loop, req);
-
- free(req->hints);
- free(req->service);
- free(req->hostname);
-
- if (req->retcode == 0) {
- /* OK */
-#if EAI_NODATA /* FreeBSD deprecated EAI_NODATA */
- } else if (req->retcode == EAI_NONAME || req->retcode == EAI_NODATA) {
-#else
- } else if (req->retcode == EAI_NONAME) {
-#endif
- uv__set_sys_error(req->loop, ENOENT); /* FIXME compatibility hack */
-#if __sun
- } else if (req->retcode == EAI_MEMORY && hostlen >= MAXHOSTNAMELEN) {
- uv__set_sys_error(req->loop, ENOENT);
-#endif
- } else {
- req->loop->last_err.code = UV_EADDRINFO;
- req->loop->last_err.sys_errno_ = req->retcode;
- }
-
- req->cb(req, req->retcode, res);
-
- return 0;
-}
-
-
-static void getaddrinfo_thread_proc(eio_req *req) {
- uv_getaddrinfo_t* handle = req->data;
-
- handle->retcode = getaddrinfo(handle->hostname,
- handle->service,
- handle->hints,
- &handle->res);
-}
-
-
-/* stub implementation of uv_getaddrinfo */
-int uv_getaddrinfo(uv_loop_t* loop,
- uv_getaddrinfo_t* handle,
- uv_getaddrinfo_cb cb,
- const char* hostname,
- const char* service,
- const struct addrinfo* hints) {
- eio_req* req;
- uv_eio_init(loop);
-
- if (handle == NULL || cb == NULL ||
- (hostname == NULL && service == NULL)) {
- uv__set_artificial_error(loop, UV_EINVAL);
- return -1;
- }
-
- uv__req_init(loop, handle, UV_GETADDRINFO);
- handle->loop = loop;
- handle->cb = cb;
-
- /* TODO don't alloc so much. */
-
- if (hints) {
- handle->hints = malloc(sizeof(struct addrinfo));
- memcpy(handle->hints, hints, sizeof(struct addrinfo));
- }
- else {
- handle->hints = NULL;
- }
-
- /* TODO security! check lengths, check return values. */
-
- handle->hostname = hostname ? strdup(hostname) : NULL;
- handle->service = service ? strdup(service) : NULL;
- handle->res = NULL;
- handle->retcode = 0;
-
- /* TODO check handle->hostname == NULL */
- /* TODO check handle->service == NULL */
-
- req = eio_custom(getaddrinfo_thread_proc, EIO_PRI_DEFAULT,
- uv_getaddrinfo_done, handle, &loop->uv_eio_channel);
- assert(req);
- assert(req->data == handle);
-
- return 0;
-}
-
-
-void uv_freeaddrinfo(struct addrinfo* ai) {
- if (ai)
- freeaddrinfo(ai);
-}
-
-
/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
int uv__socket(int domain, int type, int protocol) {
int sockfd;
@@ -419,6 +356,13 @@ int uv__socket(int domain, int type, int protocol) {
sockfd = -1;
}
+#if defined(SO_NOSIGPIPE)
+ {
+ int on = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
+ }
+#endif
+
out:
return sockfd;
}
@@ -430,7 +374,7 @@ int uv__accept(int sockfd) {
assert(sockfd >= 0);
while (1) {
-#if __linux__
+#if defined(__linux__)
static int no_accept4;
if (no_accept4)
@@ -475,17 +419,34 @@ skip:
}
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
+
int uv__nonblock(int fd, int set) {
int r;
-#if FIONBIO
do
r = ioctl(fd, FIONBIO, &set);
while (r == -1 && errno == EINTR);
return r;
-#else
+}
+
+
+int uv__cloexec(int fd, int set) {
+ int r;
+
+ do
+ r = ioctl(fd, set ? FIOCLEX : FIONCLEX);
+ while (r == -1 && errno == EINTR);
+
+ return r;
+}
+
+#else /* !(defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) */
+
+int uv__nonblock(int fd, int set) {
int flags;
+ int r;
do
r = fcntl(fd, F_GETFL);
@@ -494,6 +455,10 @@ int uv__nonblock(int fd, int set) {
if (r == -1)
return -1;
+ /* Bail out now if already set/clear. */
+ if (!!(r & O_NONBLOCK) == !!set)
+ return 0;
+
if (set)
flags = r | O_NONBLOCK;
else
@@ -504,7 +469,6 @@ int uv__nonblock(int fd, int set) {
while (r == -1 && errno == EINTR);
return r;
-#endif
}
@@ -512,15 +476,6 @@ int uv__cloexec(int fd, int set) {
int flags;
int r;
-#if __linux__
- /* Linux knows only FD_CLOEXEC so we can safely omit the fcntl(F_GETFD)
- * syscall. CHECKME: That's probably true for other Unices as well.
- */
- if (set)
- flags = FD_CLOEXEC;
- else
- flags = 0;
-#else
do
r = fcntl(fd, F_GETFD);
while (r == -1 && errno == EINTR);
@@ -528,11 +483,14 @@ int uv__cloexec(int fd, int set) {
if (r == -1)
return -1;
+ /* Bail out now if already set/clear. */
+ if (!!(r & FD_CLOEXEC) == !!set)
+ return 0;
+
if (set)
flags = r | FD_CLOEXEC;
else
flags = r & ~FD_CLOEXEC;
-#endif
do
r = fcntl(fd, F_SETFD, flags);
@@ -541,6 +499,8 @@ int uv__cloexec(int fd, int set) {
return r;
}
+#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) */
+
/* This function is not execve-safe, there is a race window
* between the call to dup() and fcntl(FD_CLOEXEC).
@@ -560,24 +520,6 @@ int uv__dup(int fd) {
}
-/* TODO move to uv-common.c? */
-size_t uv__strlcpy(char* dst, const char* src, size_t size) {
- const char *org;
-
- if (size == 0) {
- return 0;
- }
-
- org = src;
- while (--size && *src) {
- *dst++ = *src++;
- }
- *dst = '\0';
-
- return src - org;
-}
-
-
uv_err_t uv_cwd(char* buffer, size_t size) {
if (!buffer || !size) {
return uv__new_artificial_error(UV_EINVAL);
@@ -612,49 +554,150 @@ void uv_disable_stdio_inheritance(void) {
}
-static void uv__io_set_cb(uv__io_t* handle, uv__io_cb cb) {
- union { void* data; uv__io_cb cb; } u;
- u.cb = cb;
- handle->io_watcher.data = u.data;
+static void uv__run_pending(uv_loop_t* loop) {
+ ngx_queue_t* q;
+ uv__io_t* w;
+
+ while (!ngx_queue_empty(&loop->pending_queue)) {
+ q = ngx_queue_head(&loop->pending_queue);
+ ngx_queue_remove(q);
+ ngx_queue_init(q);
+
+ w = ngx_queue_data(q, uv__io_t, pending_queue);
+ w->cb(loop, w, UV__POLLOUT);
+ }
}
-static void uv__io_rw(struct ev_loop* ev, ev_io* w, int events) {
- union { void* data; uv__io_cb cb; } u;
- uv_loop_t* loop = ev_userdata(ev);
- uv__io_t* handle = container_of(w, uv__io_t, io_watcher);
- u.data = handle->io_watcher.data;
- u.cb(loop, handle, events & (EV_READ|EV_WRITE|EV_ERROR));
+static unsigned int next_power_of_two(unsigned int val) {
+ val -= 1;
+ val |= val >> 1;
+ val |= val >> 2;
+ val |= val >> 4;
+ val |= val >> 8;
+ val |= val >> 16;
+ val += 1;
+ return val;
}
+static void maybe_resize(uv_loop_t* loop, unsigned int len) {
+ uv__io_t** watchers;
+ unsigned int nwatchers;
+ unsigned int i;
+
+ if (len <= loop->nwatchers)
+ return;
+
+ nwatchers = next_power_of_two(len);
+ watchers = realloc(loop->watchers, nwatchers * sizeof(loop->watchers[0]));
+
+ if (watchers == NULL)
+ abort();
+
+ for (i = loop->nwatchers; i < nwatchers; i++)
+ watchers[i] = NULL;
+
+ loop->watchers = watchers;
+ loop->nwatchers = nwatchers;
+}
+
+
+void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
+ assert(cb != NULL);
+ assert(fd >= -1);
+ ngx_queue_init(&w->pending_queue);
+ ngx_queue_init(&w->watcher_queue);
+ w->cb = cb;
+ w->fd = fd;
+ w->events = 0;
+ w->pevents = 0;
-void uv__io_init(uv__io_t* handle, uv__io_cb cb, int fd, int events) {
- ev_io_init(&handle->io_watcher, uv__io_rw, fd, events & (EV_READ|EV_WRITE));
- uv__io_set_cb(handle, cb);
+#if defined(UV_HAVE_KQUEUE)
+ w->rcount = 0;
+ w->wcount = 0;
+#endif /* defined(UV_HAVE_KQUEUE) */
}
-void uv__io_set(uv__io_t* handle, uv__io_cb cb, int fd, int events) {
- ev_io_set(&handle->io_watcher, fd, events);
- uv__io_set_cb(handle, cb);
+void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
+ assert(0 != events);
+ assert(w->fd >= 0);
+ assert(w->fd < INT_MAX);
+
+ w->pevents |= events;
+ maybe_resize(loop, w->fd + 1);
+
+#if !defined(__sun)
+ /* The event ports backend needs to rearm all file descriptors on each and
+ * every tick of the event loop but the other backends allow us to
+ * short-circuit here if the event mask is unchanged.
+ */
+ if (w->events == w->pevents) {
+ if (w->events == 0 && !ngx_queue_empty(&w->watcher_queue)) {
+ ngx_queue_remove(&w->watcher_queue);
+ ngx_queue_init(&w->watcher_queue);
+ }
+ return;
+ }
+#endif
+
+ if (ngx_queue_empty(&w->watcher_queue))
+ ngx_queue_insert_tail(&loop->watcher_queue, &w->watcher_queue);
+
+ if (loop->watchers[w->fd] == NULL) {
+ loop->watchers[w->fd] = w;
+ loop->nfds++;
+ }
}
-void uv__io_start(uv_loop_t* loop, uv__io_t* handle) {
- ev_io_start(loop->ev, &handle->io_watcher);
+void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
+ assert(0 != events);
+
+ if (w->fd == -1)
+ return;
+
+ assert(w->fd >= 0);
+
+ /* Happens when uv__io_stop() is called on a handle that was never started. */
+ if ((unsigned) w->fd >= loop->nwatchers)
+ return;
+
+ w->pevents &= ~events;
+
+ if (w->pevents == 0) {
+ ngx_queue_remove(&w->watcher_queue);
+ ngx_queue_init(&w->watcher_queue);
+
+ if (loop->watchers[w->fd] != NULL) {
+ assert(loop->watchers[w->fd] == w);
+ assert(loop->nfds > 0);
+ loop->watchers[w->fd] = NULL;
+ loop->nfds--;
+ w->events = 0;
+ }
+ }
+ else if (ngx_queue_empty(&w->watcher_queue))
+ ngx_queue_insert_tail(&loop->watcher_queue, &w->watcher_queue);
}
-void uv__io_stop(uv_loop_t* loop, uv__io_t* handle) {
- ev_io_stop(loop->ev, &handle->io_watcher);
+void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
+ uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT);
+ ngx_queue_remove(&w->pending_queue);
}
-void uv__io_feed(uv_loop_t* loop, uv__io_t* handle, int event) {
- ev_feed_event(loop->ev, &handle->io_watcher, event);
+void uv__io_feed(uv_loop_t* loop, uv__io_t* w) {
+ if (ngx_queue_empty(&w->pending_queue))
+ ngx_queue_insert_tail(&loop->pending_queue, &w->pending_queue);
}
-int uv__io_active(uv__io_t* handle) {
- return ev_is_active(&handle->io_watcher);
+int uv__io_active(const uv__io_t* w, unsigned int events) {
+ assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
+ assert(0 != events);
+ return 0 != (w->pevents & events);
}
diff --git a/deps/uv/src/unix/cygwin.c b/deps/uv/src/unix/cygwin.c
index 183beb322..974645411 100644
--- a/deps/uv/src/unix/cygwin.c
+++ b/deps/uv/src/unix/cygwin.c
@@ -19,7 +19,7 @@
*/
#include "uv.h"
-#include "../uv-common.h"
+#include "internal.h"
#include <assert.h>
#include <stdint.h>
@@ -32,12 +32,22 @@
#define NANOSEC ((uint64_t) 1e9)
-uint64_t uv_hrtime() {
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ return 0;
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+}
+
+
+uint64_t uv__hrtime(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
}
+
void uv_loadavg(double avg[3]) {
/* Unsupported as of cygwin 1.7.7 */
avg[0] = avg[1] = avg[2] = 0;
@@ -73,7 +83,6 @@ int uv_fs_event_init(uv_loop_t* loop,
const char* filename,
uv_fs_event_cb cb,
int flags) {
- loop->counters.fs_event_init++;
uv__set_sys_error(loop, ENOSYS);
return -1;
}
diff --git a/deps/uv/src/unix/darwin-proctitle.m b/deps/uv/src/unix/darwin-proctitle.m
new file mode 100644
index 000000000..d0ee95b49
--- /dev/null
+++ b/deps/uv/src/unix/darwin-proctitle.m
@@ -0,0 +1,78 @@
+/* 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.
+ */
+
+#include <Cocoa/Cocoa.h>
+
+
+int uv__set_process_title(const char* title) {
+ typedef CFTypeRef (*LSGetCurrentApplicationASNType)(void);
+ typedef OSStatus (*LSSetApplicationInformationItemType)(int,
+ CFTypeRef,
+ CFStringRef,
+ CFStringRef,
+ CFDictionaryRef*);
+ CFBundleRef launch_services_bundle;
+ LSGetCurrentApplicationASNType ls_get_current_application_asn;
+ LSSetApplicationInformationItemType ls_set_application_information_item;
+ CFStringRef* display_name_key;
+ ProcessSerialNumber psn;
+ CFTypeRef asn;
+ CFStringRef display_name;
+ OSStatus err;
+
+ launch_services_bundle =
+ CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices"));
+
+ if (launch_services_bundle == NULL)
+ return -1;
+
+ ls_get_current_application_asn =
+ CFBundleGetFunctionPointerForName(launch_services_bundle,
+ CFSTR("_LSGetCurrentApplicationASN"));
+
+ if (ls_get_current_application_asn == NULL)
+ return -1;
+
+ ls_set_application_information_item =
+ CFBundleGetFunctionPointerForName(launch_services_bundle,
+ CFSTR("_LSSetApplicationInformationItem"));
+
+ if (ls_set_application_information_item == NULL)
+ return -1;
+
+ display_name_key = CFBundleGetDataPointerForName(launch_services_bundle,
+ CFSTR("_kLSDisplayNameKey"));
+
+ if (display_name_key == NULL || *display_name_key == NULL)
+ return -1;
+
+ /* Force the process manager to initialize. */
+ GetCurrentProcess(&psn);
+
+ display_name = CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8);
+ asn = ls_get_current_application_asn();
+ err = ls_set_application_information_item(-2, /* Magic value. */
+ asn,
+ *display_name_key,
+ display_name,
+ NULL);
+
+ return (err == noErr) ? 0 : -1;
+}
diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c
index e6deb3017..82a640a84 100644
--- a/deps/uv/src/unix/darwin.c
+++ b/deps/uv/src/unix/darwin.c
@@ -28,11 +28,7 @@
#include <ifaddrs.h>
#include <net/if.h>
-#include <TargetConditionals.h>
-
-#if !TARGET_OS_IPHONE
-#include <CoreServices/CoreServices.h>
-#endif
+#include <CoreFoundation/CFRunLoop.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
@@ -41,34 +37,152 @@
#include <sys/sysctl.h>
#include <unistd.h> /* sysconf */
-static char *process_title;
+/* Forward declarations */
+void uv__cf_loop_runner(void* arg);
+void uv__cf_loop_cb(void* arg);
-#if TARGET_OS_IPHONE
-/* see: http://developer.apple.com/library/mac/#qa/qa1398/_index.html */
-uint64_t uv_hrtime() {
- uint64_t time;
- uint64_t enano;
- static mach_timebase_info_data_t sTimebaseInfo;
+typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
+struct uv__cf_loop_signal_s {
+ void* arg;
+ cf_loop_signal_cb cb;
+ ngx_queue_t member;
+};
- time = mach_absolute_time();
- if (0 == sTimebaseInfo.denom) {
- (void)mach_timebase_info(&sTimebaseInfo);
- }
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ CFRunLoopSourceContext ctx;
+ int r;
+
+ if (uv__kqueue_init(loop))
+ return -1;
- enano = time * sTimebaseInfo.numer / sTimebaseInfo.denom;
+ loop->cf_loop = NULL;
+ if ((r = uv_mutex_init(&loop->cf_mutex)))
+ return r;
+ if ((r = uv_sem_init(&loop->cf_sem, 0)))
+ return r;
+ ngx_queue_init(&loop->cf_signals);
- return enano;
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.info = loop;
+ ctx.perform = uv__cf_loop_cb;
+ loop->cf_cb = CFRunLoopSourceCreate(NULL, 0, &ctx);
+
+ if ((r = uv_thread_create(&loop->cf_thread, uv__cf_loop_runner, loop)))
+ return r;
+
+ /* Synchronize threads */
+ uv_sem_wait(&loop->cf_sem);
+ assert(((volatile CFRunLoopRef) loop->cf_loop) != NULL);
+
+ return 0;
}
-#else
-uint64_t uv_hrtime() {
- uint64_t time;
- Nanoseconds enano;
- time = mach_absolute_time();
- enano = AbsoluteToNanoseconds(*(AbsoluteTime *)&time);
- return (*(uint64_t *)&enano);
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+ ngx_queue_t* item;
+ uv__cf_loop_signal_t* s;
+
+ assert(loop->cf_loop != NULL);
+ CFRunLoopStop(loop->cf_loop);
+ uv_thread_join(&loop->cf_thread);
+ loop->cf_loop = NULL;
+
+ uv_sem_destroy(&loop->cf_sem);
+ uv_mutex_destroy(&loop->cf_mutex);
+
+ /* Free any remaining data */
+ while (!ngx_queue_empty(&loop->cf_signals)) {
+ item = ngx_queue_head(&loop->cf_signals);
+
+ s = ngx_queue_data(item, uv__cf_loop_signal_t, member);
+
+ ngx_queue_remove(item);
+ free(s);
+ }
}
-#endif
+
+
+void uv__cf_loop_runner(void* arg) {
+ uv_loop_t* loop;
+
+ loop = arg;
+
+ /* Get thread's loop */
+ *((volatile CFRunLoopRef*)&loop->cf_loop) = CFRunLoopGetCurrent();
+
+ CFRunLoopAddSource(loop->cf_loop,
+ loop->cf_cb,
+ kCFRunLoopDefaultMode);
+
+ uv_sem_post(&loop->cf_sem);
+
+ CFRunLoopRun();
+
+ CFRunLoopRemoveSource(loop->cf_loop,
+ loop->cf_cb,
+ kCFRunLoopDefaultMode);
+}
+
+
+void uv__cf_loop_cb(void* arg) {
+ uv_loop_t* loop;
+ ngx_queue_t* item;
+ ngx_queue_t split_head;
+ uv__cf_loop_signal_t* s;
+
+ loop = arg;
+
+ uv_mutex_lock(&loop->cf_mutex);
+ ngx_queue_init(&split_head);
+ if (!ngx_queue_empty(&loop->cf_signals)) {
+ ngx_queue_t* split_pos = ngx_queue_next(&loop->cf_signals);
+ ngx_queue_split(&loop->cf_signals, split_pos, &split_head);
+ }
+ uv_mutex_unlock(&loop->cf_mutex);
+
+ while (!ngx_queue_empty(&split_head)) {
+ item = ngx_queue_head(&split_head);
+
+ s = ngx_queue_data(item, uv__cf_loop_signal_t, member);
+ s->cb(s->arg);
+
+ ngx_queue_remove(item);
+ free(s);
+ }
+}
+
+
+void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg) {
+ uv__cf_loop_signal_t* item;
+
+ item = malloc(sizeof(*item));
+ /* XXX: Fail */
+ if (item == NULL)
+ abort();
+
+ item->arg = arg;
+ item->cb = cb;
+
+ uv_mutex_lock(&loop->cf_mutex);
+ ngx_queue_insert_tail(&loop->cf_signals, &item->member);
+ uv_mutex_unlock(&loop->cf_mutex);
+
+ assert(loop->cf_loop != NULL);
+ CFRunLoopSourceSignal(loop->cf_cb);
+ CFRunLoopWakeUp(loop->cf_loop);
+}
+
+
+uint64_t uv__hrtime(void) {
+ mach_timebase_info_data_t info;
+
+ if (mach_timebase_info(&info) != KERN_SUCCESS)
+ abort();
+
+ return mach_absolute_time() * info.numer / info.denom;
+}
+
int uv_exepath(char* buffer, size_t* size) {
uint32_t usize;
@@ -138,31 +252,6 @@ void uv_loadavg(double avg[3]) {
}
-char** uv_setup_args(int argc, char** argv) {
- process_title = argc ? strdup(argv[0]) : NULL;
- return argv;
-}
-
-
-uv_err_t uv_set_process_title(const char* title) {
- /* TODO implement me */
- return uv__new_artificial_error(UV_ENOSYS);
-}
-
-
-uv_err_t uv_get_process_title(char* buffer, size_t size) {
- if (process_title) {
- strncpy(buffer, process_title, size);
- } else {
- if (size > 0) {
- buffer[0] = '\0';
- }
- }
-
- return uv_ok_;
-}
-
-
uv_err_t uv_resident_set_memory(size_t* rss) {
struct task_basic_info t_info;
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
@@ -211,7 +300,8 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
uv_cpu_info_t* cpu_info;
size = sizeof(model);
- if (sysctlbyname("hw.model", &model, &size, NULL, 0) < 0) {
+ if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) < 0 &&
+ sysctlbyname("hw.model", &model, &size, NULL, 0) < 0) {
return uv__new_sys_error(errno);
}
size = sizeof(cpuspeed);
diff --git a/deps/uv/src/unix/eio/Changes b/deps/uv/src/unix/eio/Changes
deleted file mode 100644
index 9d3e3231c..000000000
--- a/deps/uv/src/unix/eio/Changes
+++ /dev/null
@@ -1,63 +0,0 @@
-Revision history for libeio
-
-TODO: maybe add mincore support? available on at least darwin, solaris, linux, freebsd
-TODO: openbsd requires stdint.h for intptr_t - why posix?
-
-TODO: make mtouch/readdir maybe others cancellable in-request
-TODO: fadvise request
-1.0
- - fix a deadlock where a wakeup signal could be missed when
- a timeout occured at the same time.
- - use nonstandard but maybe-working-on-bsd fork technique.
- - use fewer time() syscalls when waiting for new requests.
- - fix a path-memory-leak in readdir when using the wrappers
- (reported by Thomas L. Shinnick).
- - support a max_idle value of 0.
- - support setting of idle timeout value (eio_set_idle_timeout).
- - readdir: correctly handle malloc failures.
- - readdir: new flags argument, can return inode
- and possibly filetype, can sort in various ways.
- - readdir: stop immediately when cancelled, do
- not continue reading the directory.
- - fix return value of eio_sendfile_sync.
- - include sys/mman.h for msync.
- - added EIO_STACKSIZE.
- - added msync, mtouch support (untested).
- - added sync_file_range (untested).
- - fixed custom support.
- - use a more robust feed-add detection method.
- - "outbundled" from IO::AIO.
- - eio_set_max_polltime did not properly convert time to ticks.
- - tentatively support darwin in sendfile.
- - fix freebsd/darwin sendfile.
- - also use sendfile emulation for ENOTSUP and EOPNOTSUPP
- error codes.
- - add OS-independent EIO_MT_* and EIO_MS_* flag enums.
- - add eio_statvfs/eio_fstatvfs.
- - add eio_mlock/eio_mlockall and OS-independent MCL_* flag enums.
- - no longer set errno to 0 before making syscalls, this only lures
- people into the trap of believing errno shows success or failure.
- - "fix" demo.c so that it works as non-root.
- - suppoert utimes seperately from futimes, as some systems have
- utimes but not futimes.
- - use _POSIX_MEMLOCK_RANGE for mlock.
- - do not (errornously) overwrite CFLAGS in configure.ac.
- - mknod used int3 for dev_t (§2 bit), not offs (64 bit).
- - fix memory corruption in eio_readdirx for the flags
- combination EIO_READDIR_STAT_ORDER | EIO_READDIR_DIRS_FIRST.
- - port to openbsd (another blatantly broken non-UNIX/POSIX platform).
- - fix eio_custom prototype.
- - work around a Linux (and likely FreeBSD and other kernels) bug
- where sendfile would not transfer all the requested bytes on
- large transfers, using a heuristic.
- - use libecb, and apply lots of minor space optimisations.
- - disable sendfile on darwin, broken as everything else.
- - add realpath request and implementation.
- - cancelled requests will still invoke their request callbacks.
- - add fallocate.
- - do not acquire any locks when forking.
- - incorporated some mingw32 changes by traviscline.
- - added syncfs support, using direct syscall.
- - set thread name on linux (ps -L/Hcx, top, gdb).
- - remove useless use of volatile variables.
-
diff --git a/deps/uv/src/unix/eio/LICENSE b/deps/uv/src/unix/eio/LICENSE
deleted file mode 100644
index 1ed1324d3..000000000
--- a/deps/uv/src/unix/eio/LICENSE
+++ /dev/null
@@ -1,36 +0,0 @@
-All files in libeio are Copyright (C)2007,2008 Marc Alexander Lehmann.
-
-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.
-
-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.
-
-Alternatively, the contents of this package may be used under the terms
-of the GNU General Public License ("GPL") version 2 or any later version,
-in which case the provisions of the GPL are applicable instead of the
-above. If you wish to allow the use of your version of this package only
-under the terms of the GPL and not to allow others to use your version of
-this file under the BSD license, indicate your decision by deleting the
-provisions above and replace them with the notice and other provisions
-required by the GPL in this and the other files of this package. If you do
-not delete the provisions above, a recipient may use your version of this
-file under either the BSD or the GPL.
diff --git a/deps/uv/src/unix/eio/Makefile.am b/deps/uv/src/unix/eio/Makefile.am
deleted file mode 100644
index e9866c0d5..000000000
--- a/deps/uv/src/unix/eio/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-AUTOMAKE_OPTIONS = foreign no-dependencies
-
-VERSION_INFO = 1:0
-
-EXTRA_DIST = LICENSE Changes autogen.sh
-
-#man_MANS = ev.3
-
-include_HEADERS = eio.h
-
-lib_LTLIBRARIES = libeio.la
-
-libeio_la_SOURCES = eio.c ecb.h xthread.h config.h
-libeio_la_LDFLAGS = -version-info $(VERSION_INFO)
-
diff --git a/deps/uv/src/unix/eio/aclocal.m4 b/deps/uv/src/unix/eio/aclocal.m4
deleted file mode 100644
index 18abb7368..000000000
--- a/deps/uv/src/unix/eio/aclocal.m4
+++ /dev/null
@@ -1,8957 +0,0 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],,
-[m4_warning([this file was generated for autoconf 2.67.
-You have another version of autoconf. It may work, but is not guaranteed to.
-If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
-
-# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008 Free Software Foundation, Inc.
-# Written by Gordon Matzigkeit, 1996
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-
-m4_define([_LT_COPYING], [dnl
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008 Free Software Foundation, Inc.
-# Written by Gordon Matzigkeit, 1996
-#
-# This file is part of GNU Libtool.
-#
-# GNU Libtool is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# As a special exception to the GNU General Public License,
-# if you distribute this file as part of a program or library that
-# is built using GNU Libtool, you may include this file under the
-# same distribution terms that you use for the rest of that program.
-#
-# GNU Libtool is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Libtool; see the file COPYING. If not, a copy
-# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
-# obtained by writing to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-])
-
-# serial 56 LT_INIT
-
-
-# LT_PREREQ(VERSION)
-# ------------------
-# Complain and exit if this libtool version is less that VERSION.
-m4_defun([LT_PREREQ],
-[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
- [m4_default([$3],
- [m4_fatal([Libtool version $1 or higher is required],
- 63)])],
- [$2])])
-
-
-# _LT_CHECK_BUILDDIR
-# ------------------
-# Complain if the absolute build directory name contains unusual characters
-m4_defun([_LT_CHECK_BUILDDIR],
-[case `pwd` in
- *\ * | *\ *)
- AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
-esac
-])
-
-
-# LT_INIT([OPTIONS])
-# ------------------
-AC_DEFUN([LT_INIT],
-[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
-AC_BEFORE([$0], [LT_LANG])dnl
-AC_BEFORE([$0], [LT_OUTPUT])dnl
-AC_BEFORE([$0], [LTDL_INIT])dnl
-m4_require([_LT_CHECK_BUILDDIR])dnl
-
-dnl Autoconf doesn't catch unexpanded LT_ macros by default:
-m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
-m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
-dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
-dnl unless we require an AC_DEFUNed macro:
-AC_REQUIRE([LTOPTIONS_VERSION])dnl
-AC_REQUIRE([LTSUGAR_VERSION])dnl
-AC_REQUIRE([LTVERSION_VERSION])dnl
-AC_REQUIRE([LTOBSOLETE_VERSION])dnl
-m4_require([_LT_PROG_LTMAIN])dnl
-
-dnl Parse OPTIONS
-_LT_SET_OPTIONS([$0], [$1])
-
-# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ltmain"
-
-# Always use our own libtool.
-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
-AC_SUBST(LIBTOOL)dnl
-
-_LT_SETUP
-
-# Only expand once:
-m4_define([LT_INIT])
-])# LT_INIT
-
-# Old names:
-AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
-AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
-dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
-
-
-# _LT_CC_BASENAME(CC)
-# -------------------
-# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
-m4_defun([_LT_CC_BASENAME],
-[for cc_temp in $1""; do
- case $cc_temp in
- compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
- distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-])
-
-
-# _LT_FILEUTILS_DEFAULTS
-# ----------------------
-# It is okay to use these file commands and assume they have been set
-# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
-m4_defun([_LT_FILEUTILS_DEFAULTS],
-[: ${CP="cp -f"}
-: ${MV="mv -f"}
-: ${RM="rm -f"}
-])# _LT_FILEUTILS_DEFAULTS
-
-
-# _LT_SETUP
-# ---------
-m4_defun([_LT_SETUP],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-_LT_DECL([], [host_alias], [0], [The host system])dnl
-_LT_DECL([], [host], [0])dnl
-_LT_DECL([], [host_os], [0])dnl
-dnl
-_LT_DECL([], [build_alias], [0], [The build system])dnl
-_LT_DECL([], [build], [0])dnl
-_LT_DECL([], [build_os], [0])dnl
-dnl
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([LT_PATH_LD])dnl
-AC_REQUIRE([LT_PATH_NM])dnl
-dnl
-AC_REQUIRE([AC_PROG_LN_S])dnl
-test -z "$LN_S" && LN_S="ln -s"
-_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
-dnl
-AC_REQUIRE([LT_CMD_MAX_LEN])dnl
-_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
-_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
-dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_CHECK_SHELL_FEATURES])dnl
-m4_require([_LT_CMD_RELOAD])dnl
-m4_require([_LT_CHECK_MAGIC_METHOD])dnl
-m4_require([_LT_CMD_OLD_ARCHIVE])dnl
-m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
-
-_LT_CONFIG_LIBTOOL_INIT([
-# See if we are running on zsh, and set the options which allow our
-# commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
-fi
-])
-if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
-fi
-
-_LT_CHECK_OBJDIR
-
-m4_require([_LT_TAG_COMPILER])dnl
-_LT_PROG_ECHO_BACKSLASH
-
-case $host_os in
-aix3*)
- # AIX sometimes has problems with the GCC collect2 program. For some
- # reason, if we set the COLLECT_NAMES environment variable, the problems
- # vanish in a puff of smoke.
- if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
- fi
- ;;
-esac
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\([["`\\]]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
-# Global variables:
-ofile=libtool
-can_build_shared=yes
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-
-with_gnu_ld="$lt_cv_prog_gnu_ld"
-
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
-
-# Set sane defaults for various variables
-test -z "$CC" && CC=cc
-test -z "$LTCC" && LTCC=$CC
-test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
-test -z "$LD" && LD=ld
-test -z "$ac_objext" && ac_objext=o
-
-_LT_CC_BASENAME([$compiler])
-
-# Only perform the check for file, if the check method requires it
-test -z "$MAGIC_CMD" && MAGIC_CMD=file
-case $deplibs_check_method in
-file_magic*)
- if test "$file_magic_cmd" = '$MAGIC_CMD'; then
- _LT_PATH_MAGIC
- fi
- ;;
-esac
-
-# Use C for the default configuration in the libtool script
-LT_SUPPORTED_TAG([CC])
-_LT_LANG_C_CONFIG
-_LT_LANG_DEFAULT_CONFIG
-_LT_CONFIG_COMMANDS
-])# _LT_SETUP
-
-
-# _LT_PROG_LTMAIN
-# ---------------
-# Note that this code is called both from `configure', and `config.status'
-# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
-# `config.status' has no value for ac_aux_dir unless we are using Automake,
-# so we pass a copy along to make sure it has a sensible value anyway.
-m4_defun([_LT_PROG_LTMAIN],
-[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
-_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
-ltmain="$ac_aux_dir/ltmain.sh"
-])# _LT_PROG_LTMAIN
-
-
-
-# So that we can recreate a full libtool script including additional
-# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
-# in macros and then make a single call at the end using the `libtool'
-# label.
-
-
-# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
-# ----------------------------------------
-# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
-m4_define([_LT_CONFIG_LIBTOOL_INIT],
-[m4_ifval([$1],
- [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
- [$1
-])])])
-
-# Initialize.
-m4_define([_LT_OUTPUT_LIBTOOL_INIT])
-
-
-# _LT_CONFIG_LIBTOOL([COMMANDS])
-# ------------------------------
-# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
-m4_define([_LT_CONFIG_LIBTOOL],
-[m4_ifval([$1],
- [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
- [$1
-])])])
-
-# Initialize.
-m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
-
-
-# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
-# -----------------------------------------------------
-m4_defun([_LT_CONFIG_SAVE_COMMANDS],
-[_LT_CONFIG_LIBTOOL([$1])
-_LT_CONFIG_LIBTOOL_INIT([$2])
-])
-
-
-# _LT_FORMAT_COMMENT([COMMENT])
-# -----------------------------
-# Add leading comment marks to the start of each line, and a trailing
-# full-stop to the whole comment if one is not present already.
-m4_define([_LT_FORMAT_COMMENT],
-[m4_ifval([$1], [
-m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
- [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
-)])
-
-
-
-
-
-# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
-# -------------------------------------------------------------------
-# CONFIGNAME is the name given to the value in the libtool script.
-# VARNAME is the (base) name used in the configure script.
-# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
-# VARNAME. Any other value will be used directly.
-m4_define([_LT_DECL],
-[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
- [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
- [m4_ifval([$1], [$1], [$2])])
- lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
- m4_ifval([$4],
- [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
- lt_dict_add_subkey([lt_decl_dict], [$2],
- [tagged?], [m4_ifval([$5], [yes], [no])])])
-])
-
-
-# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
-# --------------------------------------------------------
-m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
-
-
-# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
-# ------------------------------------------------
-m4_define([lt_decl_tag_varnames],
-[_lt_decl_filter([tagged?], [yes], $@)])
-
-
-# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
-# ---------------------------------------------------------
-m4_define([_lt_decl_filter],
-[m4_case([$#],
- [0], [m4_fatal([$0: too few arguments: $#])],
- [1], [m4_fatal([$0: too few arguments: $#: $1])],
- [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
- [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
- [lt_dict_filter([lt_decl_dict], $@)])[]dnl
-])
-
-
-# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
-# --------------------------------------------------
-m4_define([lt_decl_quote_varnames],
-[_lt_decl_filter([value], [1], $@)])
-
-
-# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
-# ---------------------------------------------------
-m4_define([lt_decl_dquote_varnames],
-[_lt_decl_filter([value], [2], $@)])
-
-
-# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
-# ---------------------------------------------------
-m4_define([lt_decl_varnames_tagged],
-[m4_assert([$# <= 2])dnl
-_$0(m4_quote(m4_default([$1], [[, ]])),
- m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
- m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
-m4_define([_lt_decl_varnames_tagged],
-[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
-
-
-# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
-# ------------------------------------------------
-m4_define([lt_decl_all_varnames],
-[_$0(m4_quote(m4_default([$1], [[, ]])),
- m4_if([$2], [],
- m4_quote(lt_decl_varnames),
- m4_quote(m4_shift($@))))[]dnl
-])
-m4_define([_lt_decl_all_varnames],
-[lt_join($@, lt_decl_varnames_tagged([$1],
- lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
-])
-
-
-# _LT_CONFIG_STATUS_DECLARE([VARNAME])
-# ------------------------------------
-# Quote a variable value, and forward it to `config.status' so that its
-# declaration there will have the same value as in `configure'. VARNAME
-# must have a single quote delimited value for this to work.
-m4_define([_LT_CONFIG_STATUS_DECLARE],
-[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
-
-
-# _LT_CONFIG_STATUS_DECLARATIONS
-# ------------------------------
-# We delimit libtool config variables with single quotes, so when
-# we write them to config.status, we have to be sure to quote all
-# embedded single quotes properly. In configure, this macro expands
-# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
-#
-# <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
-m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
-[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
- [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
-
-
-# _LT_LIBTOOL_TAGS
-# ----------------
-# Output comment and list of tags supported by the script
-m4_defun([_LT_LIBTOOL_TAGS],
-[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
-available_tags="_LT_TAGS"dnl
-])
-
-
-# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
-# -----------------------------------
-# Extract the dictionary values for VARNAME (optionally with TAG) and
-# expand to a commented shell variable setting:
-#
-# # Some comment about what VAR is for.
-# visible_name=$lt_internal_name
-m4_define([_LT_LIBTOOL_DECLARE],
-[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
- [description])))[]dnl
-m4_pushdef([_libtool_name],
- m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
-m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
- [0], [_libtool_name=[$]$1],
- [1], [_libtool_name=$lt_[]$1],
- [2], [_libtool_name=$lt_[]$1],
- [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
-m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
-])
-
-
-# _LT_LIBTOOL_CONFIG_VARS
-# -----------------------
-# Produce commented declarations of non-tagged libtool config variables
-# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
-# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
-# section) are produced by _LT_LIBTOOL_TAG_VARS.
-m4_defun([_LT_LIBTOOL_CONFIG_VARS],
-[m4_foreach([_lt_var],
- m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
- [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
-
-
-# _LT_LIBTOOL_TAG_VARS(TAG)
-# -------------------------
-m4_define([_LT_LIBTOOL_TAG_VARS],
-[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
- [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
-
-
-# _LT_TAGVAR(VARNAME, [TAGNAME])
-# ------------------------------
-m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
-
-
-# _LT_CONFIG_COMMANDS
-# -------------------
-# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
-# variables for single and double quote escaping we saved from calls
-# to _LT_DECL, we can put quote escaped variables declarations
-# into `config.status', and then the shell code to quote escape them in
-# for loops in `config.status'. Finally, any additional code accumulated
-# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
-m4_defun([_LT_CONFIG_COMMANDS],
-[AC_PROVIDE_IFELSE([LT_OUTPUT],
- dnl If the libtool generation code has been placed in $CONFIG_LT,
- dnl instead of duplicating it all over again into config.status,
- dnl then we will have config.status run $CONFIG_LT later, so it
- dnl needs to know what name is stored there:
- [AC_CONFIG_COMMANDS([libtool],
- [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
- dnl If the libtool generation code is destined for config.status,
- dnl expand the accumulated commands and init code now:
- [AC_CONFIG_COMMANDS([libtool],
- [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
-])#_LT_CONFIG_COMMANDS
-
-
-# Initialize.
-m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
-[
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-sed_quote_subst='$sed_quote_subst'
-double_quote_subst='$double_quote_subst'
-delay_variable_subst='$delay_variable_subst'
-_LT_CONFIG_STATUS_DECLARATIONS
-LTCC='$LTCC'
-LTCFLAGS='$LTCFLAGS'
-compiler='$compiler_DEFAULT'
-
-# Quote evaled strings.
-for var in lt_decl_all_varnames([[ \
-]], lt_decl_quote_varnames); do
- case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
- *[[\\\\\\\`\\"\\\$]]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
- ;;
- *)
- eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
- ;;
- esac
-done
-
-# Double-quote double-evaled strings.
-for var in lt_decl_all_varnames([[ \
-]], lt_decl_dquote_varnames); do
- case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
- *[[\\\\\\\`\\"\\\$]]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
- ;;
- *)
- eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
- ;;
- esac
-done
-
-# Fix-up fallback echo if it was mangled by the above quoting rules.
-case \$lt_ECHO in
-*'\\\[$]0 --fallback-echo"')dnl "
- lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
- ;;
-esac
-
-_LT_OUTPUT_LIBTOOL_INIT
-])
-
-
-# LT_OUTPUT
-# ---------
-# This macro allows early generation of the libtool script (before
-# AC_OUTPUT is called), incase it is used in configure for compilation
-# tests.
-AC_DEFUN([LT_OUTPUT],
-[: ${CONFIG_LT=./config.lt}
-AC_MSG_NOTICE([creating $CONFIG_LT])
-cat >"$CONFIG_LT" <<_LTEOF
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate a libtool stub with the current configuration.
-
-lt_cl_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_LTEOF
-
-cat >>"$CONFIG_LT" <<\_LTEOF
-AS_SHELL_SANITIZE
-_AS_PREPARE
-
-exec AS_MESSAGE_FD>&1
-exec AS_MESSAGE_LOG_FD>>config.log
-{
- echo
- AS_BOX([Running $as_me.])
-} >&AS_MESSAGE_LOG_FD
-
-lt_cl_help="\
-\`$as_me' creates a local libtool stub from the current configuration,
-for use in further configure time tests before the real libtool is
-generated.
-
-Usage: $[0] [[OPTIONS]]
-
- -h, --help print this help, then exit
- -V, --version print version number, then exit
- -q, --quiet do not print progress messages
- -d, --debug don't remove temporary files
-
-Report bugs to <bug-libtool@gnu.org>."
-
-lt_cl_version="\
-m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
-m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
-configured by $[0], generated by m4_PACKAGE_STRING.
-
-Copyright (C) 2008 Free Software Foundation, Inc.
-This config.lt script is free software; the Free Software Foundation
-gives unlimited permision to copy, distribute and modify it."
-
-while test $[#] != 0
-do
- case $[1] in
- --version | --v* | -V )
- echo "$lt_cl_version"; exit 0 ;;
- --help | --h* | -h )
- echo "$lt_cl_help"; exit 0 ;;
- --debug | --d* | -d )
- debug=: ;;
- --quiet | --q* | --silent | --s* | -q )
- lt_cl_silent=: ;;
-
- -*) AC_MSG_ERROR([unrecognized option: $[1]
-Try \`$[0] --help' for more information.]) ;;
-
- *) AC_MSG_ERROR([unrecognized argument: $[1]
-Try \`$[0] --help' for more information.]) ;;
- esac
- shift
-done
-
-if $lt_cl_silent; then
- exec AS_MESSAGE_FD>/dev/null
-fi
-_LTEOF
-
-cat >>"$CONFIG_LT" <<_LTEOF
-_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
-_LTEOF
-
-cat >>"$CONFIG_LT" <<\_LTEOF
-AC_MSG_NOTICE([creating $ofile])
-_LT_OUTPUT_LIBTOOL_COMMANDS
-AS_EXIT(0)
-_LTEOF
-chmod +x "$CONFIG_LT"
-
-# configure is writing to config.log, but config.lt does its own redirection,
-# appending to config.log, which fails on DOS, as config.log is still kept
-# open by configure. Here we exec the FD to /dev/null, effectively closing
-# config.log, so it can be properly (re)opened and appended to by config.lt.
-if test "$no_create" != yes; then
- lt_cl_success=:
- test "$silent" = yes &&
- lt_config_lt_args="$lt_config_lt_args --quiet"
- exec AS_MESSAGE_LOG_FD>/dev/null
- $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
- exec AS_MESSAGE_LOG_FD>>config.log
- $lt_cl_success || AS_EXIT(1)
-fi
-])# LT_OUTPUT
-
-
-# _LT_CONFIG(TAG)
-# ---------------
-# If TAG is the built-in tag, create an initial libtool script with a
-# default configuration from the untagged config vars. Otherwise add code
-# to config.status for appending the configuration named by TAG from the
-# matching tagged config vars.
-m4_defun([_LT_CONFIG],
-[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-_LT_CONFIG_SAVE_COMMANDS([
- m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
- m4_if(_LT_TAG, [C], [
- # See if we are running on zsh, and set the options which allow our
- # commands through without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
-
- cfgfile="${ofile}T"
- trap "$RM \"$cfgfile\"; exit 1" 1 2 15
- $RM "$cfgfile"
-
- cat <<_LT_EOF >> "$cfgfile"
-#! $SHELL
-
-# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
-# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-#
-_LT_COPYING
-_LT_LIBTOOL_TAGS
-
-# ### BEGIN LIBTOOL CONFIG
-_LT_LIBTOOL_CONFIG_VARS
-_LT_LIBTOOL_TAG_VARS
-# ### END LIBTOOL CONFIG
-
-_LT_EOF
-
- case $host_os in
- aix3*)
- cat <<\_LT_EOF >> "$cfgfile"
-# AIX sometimes has problems with the GCC collect2 program. For some
-# reason, if we set the COLLECT_NAMES environment variable, the problems
-# vanish in a puff of smoke.
-if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
-fi
-_LT_EOF
- ;;
- esac
-
- _LT_PROG_LTMAIN
-
- # We use sed instead of cat because bash on DJGPP gets confused if
- # if finds mixed CR/LF and LF-only lines. Since sed operates in
- # text mode, it properly converts lines to CR/LF. This bash problem
- # is reportedly fixed, but why not run on old versions too?
- sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- _LT_PROG_XSI_SHELLFNS
-
- sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- mv -f "$cfgfile" "$ofile" ||
- (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
- chmod +x "$ofile"
-],
-[cat <<_LT_EOF >> "$ofile"
-
-dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
-dnl in a comment (ie after a #).
-# ### BEGIN LIBTOOL TAG CONFIG: $1
-_LT_LIBTOOL_TAG_VARS(_LT_TAG)
-# ### END LIBTOOL TAG CONFIG: $1
-_LT_EOF
-])dnl /m4_if
-],
-[m4_if([$1], [], [
- PACKAGE='$PACKAGE'
- VERSION='$VERSION'
- TIMESTAMP='$TIMESTAMP'
- RM='$RM'
- ofile='$ofile'], [])
-])dnl /_LT_CONFIG_SAVE_COMMANDS
-])# _LT_CONFIG
-
-
-# LT_SUPPORTED_TAG(TAG)
-# ---------------------
-# Trace this macro to discover what tags are supported by the libtool
-# --tag option, using:
-# autoconf --trace 'LT_SUPPORTED_TAG:$1'
-AC_DEFUN([LT_SUPPORTED_TAG], [])
-
-
-# C support is built-in for now
-m4_define([_LT_LANG_C_enabled], [])
-m4_define([_LT_TAGS], [])
-
-
-# LT_LANG(LANG)
-# -------------
-# Enable libtool support for the given language if not already enabled.
-AC_DEFUN([LT_LANG],
-[AC_BEFORE([$0], [LT_OUTPUT])dnl
-m4_case([$1],
- [C], [_LT_LANG(C)],
- [C++], [_LT_LANG(CXX)],
- [Java], [_LT_LANG(GCJ)],
- [Fortran 77], [_LT_LANG(F77)],
- [Fortran], [_LT_LANG(FC)],
- [Windows Resource], [_LT_LANG(RC)],
- [m4_ifdef([_LT_LANG_]$1[_CONFIG],
- [_LT_LANG($1)],
- [m4_fatal([$0: unsupported language: "$1"])])])dnl
-])# LT_LANG
-
-
-# _LT_LANG(LANGNAME)
-# ------------------
-m4_defun([_LT_LANG],
-[m4_ifdef([_LT_LANG_]$1[_enabled], [],
- [LT_SUPPORTED_TAG([$1])dnl
- m4_append([_LT_TAGS], [$1 ])dnl
- m4_define([_LT_LANG_]$1[_enabled], [])dnl
- _LT_LANG_$1_CONFIG($1)])dnl
-])# _LT_LANG
-
-
-# _LT_LANG_DEFAULT_CONFIG
-# -----------------------
-m4_defun([_LT_LANG_DEFAULT_CONFIG],
-[AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [LT_LANG(CXX)],
- [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
-
-AC_PROVIDE_IFELSE([AC_PROG_F77],
- [LT_LANG(F77)],
- [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
-
-AC_PROVIDE_IFELSE([AC_PROG_FC],
- [LT_LANG(FC)],
- [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
-
-dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
-dnl pulling things in needlessly.
-AC_PROVIDE_IFELSE([AC_PROG_GCJ],
- [LT_LANG(GCJ)],
- [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
- [LT_LANG(GCJ)],
- [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
- [LT_LANG(GCJ)],
- [m4_ifdef([AC_PROG_GCJ],
- [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
- m4_ifdef([A][M_PROG_GCJ],
- [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
- m4_ifdef([LT_PROG_GCJ],
- [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
-
-AC_PROVIDE_IFELSE([LT_PROG_RC],
- [LT_LANG(RC)],
- [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
-])# _LT_LANG_DEFAULT_CONFIG
-
-# Obsolete macros:
-AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
-AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
-AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
-AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
-dnl AC_DEFUN([AC_LIBTOOL_F77], [])
-dnl AC_DEFUN([AC_LIBTOOL_FC], [])
-dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
-
-
-# _LT_TAG_COMPILER
-# ----------------
-m4_defun([_LT_TAG_COMPILER],
-[AC_REQUIRE([AC_PROG_CC])dnl
-
-_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
-_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
-_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
-_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-])# _LT_TAG_COMPILER
-
-
-# _LT_COMPILER_BOILERPLATE
-# ------------------------
-# Check for compiler boilerplate output or warnings with
-# the simple compiler test code.
-m4_defun([_LT_COMPILER_BOILERPLATE],
-[m4_require([_LT_DECL_SED])dnl
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$RM conftest*
-])# _LT_COMPILER_BOILERPLATE
-
-
-# _LT_LINKER_BOILERPLATE
-# ----------------------
-# Check for linker boilerplate output or warnings with
-# the simple link test code.
-m4_defun([_LT_LINKER_BOILERPLATE],
-[m4_require([_LT_DECL_SED])dnl
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$RM -r conftest*
-])# _LT_LINKER_BOILERPLATE
-
-# _LT_REQUIRED_DARWIN_CHECKS
-# -------------------------
-m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
- case $host_os in
- rhapsody* | darwin*)
- AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
- AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
- AC_CHECK_TOOL([LIPO], [lipo], [:])
- AC_CHECK_TOOL([OTOOL], [otool], [:])
- AC_CHECK_TOOL([OTOOL64], [otool64], [:])
- _LT_DECL([], [DSYMUTIL], [1],
- [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
- _LT_DECL([], [NMEDIT], [1],
- [Tool to change global to local symbols on Mac OS X])
- _LT_DECL([], [LIPO], [1],
- [Tool to manipulate fat objects and archives on Mac OS X])
- _LT_DECL([], [OTOOL], [1],
- [ldd/readelf like tool for Mach-O binaries on Mac OS X])
- _LT_DECL([], [OTOOL64], [1],
- [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
-
- AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
- [lt_cv_apple_cc_single_mod=no
- if test -z "${LT_MULTI_MODULE}"; then
- # By default we will add the -single_module flag. You can override
- # by either setting the environment variable LT_MULTI_MODULE
- # non-empty at configure time, or by adding -multi_module to the
- # link flags.
- rm -rf libconftest.dylib*
- echo "int foo(void){return 1;}" > conftest.c
- echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
--dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
- $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
- -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
- _lt_result=$?
- if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
- lt_cv_apple_cc_single_mod=yes
- else
- cat conftest.err >&AS_MESSAGE_LOG_FD
- fi
- rm -rf libconftest.dylib*
- rm -f conftest.*
- fi])
- AC_CACHE_CHECK([for -exported_symbols_list linker flag],
- [lt_cv_ld_exported_symbols_list],
- [lt_cv_ld_exported_symbols_list=no
- save_LDFLAGS=$LDFLAGS
- echo "_main" > conftest.sym
- LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
- AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
- [lt_cv_ld_exported_symbols_list=yes],
- [lt_cv_ld_exported_symbols_list=no])
- LDFLAGS="$save_LDFLAGS"
- ])
- case $host_os in
- rhapsody* | darwin1.[[012]])
- _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
- darwin1.*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- darwin*) # darwin 5.x on
- # if running on 10.5 or later, the deployment target defaults
- # to the OS version, if on x86, and 10.4, the deployment
- # target defaults to 10.4. Don't you love it?
- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
- 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- 10.[[012]]*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- 10.*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- esac
- ;;
- esac
- if test "$lt_cv_apple_cc_single_mod" = "yes"; then
- _lt_dar_single_mod='$single_module'
- fi
- if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
- _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
- else
- _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
- fi
- if test "$DSYMUTIL" != ":"; then
- _lt_dsymutil='~$DSYMUTIL $lib || :'
- else
- _lt_dsymutil=
- fi
- ;;
- esac
-])
-
-
-# _LT_DARWIN_LINKER_FEATURES
-# --------------------------
-# Checks for linker and compiler features on darwin
-m4_defun([_LT_DARWIN_LINKER_FEATURES],
-[
- m4_require([_LT_REQUIRED_DARWIN_CHECKS])
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_automatic, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_TAGVAR(whole_archive_flag_spec, $1)=''
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
- case $cc_basename in
- ifort*) _lt_dar_can_shared=yes ;;
- *) _lt_dar_can_shared=$GCC ;;
- esac
- if test "$_lt_dar_can_shared" = "yes"; then
- output_verbose_link_cmd=echo
- _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- m4_if([$1], [CXX],
-[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
- _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
- _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
- fi
-],[])
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
-])
-
-# _LT_SYS_MODULE_PATH_AIX
-# -----------------------
-# Links a minimal program and checks the executable
-# for the system default hardcoded library path. In most cases,
-# this is /usr/lib:/lib, but when the MPI compilers are used
-# the location of the communication and MPI libs are included too.
-# If we don't find anything, use the default library path according
-# to the aix ld manual.
-m4_defun([_LT_SYS_MODULE_PATH_AIX],
-[m4_require([_LT_DECL_SED])dnl
-AC_LINK_IFELSE(AC_LANG_PROGRAM,[
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi],[])
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-])# _LT_SYS_MODULE_PATH_AIX
-
-
-# _LT_SHELL_INIT(ARG)
-# -------------------
-m4_define([_LT_SHELL_INIT],
-[ifdef([AC_DIVERSION_NOTICE],
- [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
- [AC_DIVERT_PUSH(NOTICE)])
-$1
-AC_DIVERT_POP
-])# _LT_SHELL_INIT
-
-
-# _LT_PROG_ECHO_BACKSLASH
-# -----------------------
-# Add some code to the start of the generated configure script which
-# will find an echo command which doesn't interpret backslashes.
-m4_defun([_LT_PROG_ECHO_BACKSLASH],
-[_LT_SHELL_INIT([
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$lt_ECHO in
-X*--fallback-echo)
- # Remove one level of quotation (which was required for Make).
- ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
- ;;
-esac
-
-ECHO=${lt_ECHO-echo}
-if test "X[$]1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X[$]1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
- # Yippee, $ECHO works!
- :
-else
- # Restart under the correct shell.
- exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
-fi
-
-if test "X[$]1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<_LT_EOF
-[$]*
-_LT_EOF
- exit 0
-fi
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$lt_ECHO"; then
- if test "X${echo_test_string+set}" != Xset; then
- # find a string as large as possible, as long as the shell can cope with it
- for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
- { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
- then
- break
- fi
- done
- fi
-
- if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- :
- else
- # The Solaris, AIX, and Digital Unix default echo programs unquote
- # backslashes. This makes it impossible to quote backslashes using
- # echo "$something" | sed 's/\\/\\\\/g'
- #
- # So, first we look for a working echo in the user's PATH.
-
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for dir in $PATH /usr/ucb; do
- IFS="$lt_save_ifs"
- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- ECHO="$dir/echo"
- break
- fi
- done
- IFS="$lt_save_ifs"
-
- if test "X$ECHO" = Xecho; then
- # We didn't find a better echo, so look for alternatives.
- if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # This shell has a builtin print -r that does the trick.
- ECHO='print -r'
- elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
- test "X$CONFIG_SHELL" != X/bin/ksh; then
- # If we have ksh, try running configure again with it.
- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
- export ORIGINAL_CONFIG_SHELL
- CONFIG_SHELL=/bin/ksh
- export CONFIG_SHELL
- exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
- else
- # Try using printf.
- ECHO='printf %s\n'
- if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # Cool, printf works
- :
- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
- export CONFIG_SHELL
- SHELL="$CONFIG_SHELL"
- export SHELL
- ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
- elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
- else
- # maybe with a smaller string...
- prev=:
-
- for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
- if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
- then
- break
- fi
- prev="$cmd"
- done
-
- if test "$prev" != 'sed 50q "[$]0"'; then
- echo_test_string=`eval $prev`
- export echo_test_string
- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
- else
- # Oops. We lost completely, so just stick with echo.
- ECHO=echo
- fi
- fi
- fi
- fi
- fi
-fi
-
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-lt_ECHO=$ECHO
-if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
- lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
-fi
-
-AC_SUBST(lt_ECHO)
-])
-_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
-_LT_DECL([], [ECHO], [1],
- [An echo program that does not interpret backslashes])
-])# _LT_PROG_ECHO_BACKSLASH
-
-
-# _LT_ENABLE_LOCK
-# ---------------
-m4_defun([_LT_ENABLE_LOCK],
-[AC_ARG_ENABLE([libtool-lock],
- [AS_HELP_STRING([--disable-libtool-lock],
- [avoid locking (might break parallel builds)])])
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-# Some flags need to be propagated to the compiler or linker for good
-# libtool support.
-case $host in
-ia64-*-hpux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- case `/usr/bin/file conftest.$ac_objext` in
- *ELF-32*)
- HPUX_IA64_MODE="32"
- ;;
- *ELF-64*)
- HPUX_IA64_MODE="64"
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-*-*-irix6*)
- # Find out which ABI we are using.
- echo '[#]line __oline__ "configure"' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- if test "$lt_cv_prog_gnu_ld" = yes; then
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -melf32bsmip"
- ;;
- *N32*)
- LD="${LD-ld} -melf32bmipn32"
- ;;
- *64-bit*)
- LD="${LD-ld} -melf64bmip"
- ;;
- esac
- else
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -32"
- ;;
- *N32*)
- LD="${LD-ld} -n32"
- ;;
- *64-bit*)
- LD="${LD-ld} -64"
- ;;
- esac
- fi
- fi
- rm -rf conftest*
- ;;
-
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
-s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- case `/usr/bin/file conftest.o` in
- *32-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_i386_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
- ;;
- ppc64-*linux*|powerpc64-*linux*)
- LD="${LD-ld} -m elf32ppclinux"
- ;;
- s390x-*linux*)
- LD="${LD-ld} -m elf_s390"
- ;;
- sparc64-*linux*)
- LD="${LD-ld} -m elf32_sparc"
- ;;
- esac
- ;;
- *64-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_x86_64_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_x86_64"
- ;;
- ppc*-*linux*|powerpc*-*linux*)
- LD="${LD-ld} -m elf64ppc"
- ;;
- s390*-*linux*|s390*-*tpf*)
- LD="${LD-ld} -m elf64_s390"
- ;;
- sparc*-*linux*)
- LD="${LD-ld} -m elf64_sparc"
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-*-*-sco3.2v5*)
- # On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -belf"
- AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
- [AC_LANG_PUSH(C)
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
- AC_LANG_POP])
- if test x"$lt_cv_cc_needs_belf" != x"yes"; then
- # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
- CFLAGS="$SAVE_CFLAGS"
- fi
- ;;
-sparc*-*solaris*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- case `/usr/bin/file conftest.o` in
- *64-bit*)
- case $lt_cv_prog_gnu_ld in
- yes*) LD="${LD-ld} -m elf64_sparc" ;;
- *)
- if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
- LD="${LD-ld} -64"
- fi
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-esac
-
-need_locks="$enable_libtool_lock"
-])# _LT_ENABLE_LOCK
-
-
-# _LT_CMD_OLD_ARCHIVE
-# -------------------
-m4_defun([_LT_CMD_OLD_ARCHIVE],
-[AC_CHECK_TOOL(AR, ar, false)
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-_LT_DECL([], [AR], [1], [The archiver])
-_LT_DECL([], [AR_FLAGS], [1])
-
-AC_CHECK_TOOL(STRIP, strip, :)
-test -z "$STRIP" && STRIP=:
-_LT_DECL([], [STRIP], [1], [A symbol stripping program])
-
-AC_CHECK_TOOL(RANLIB, ranlib, :)
-test -z "$RANLIB" && RANLIB=:
-_LT_DECL([], [RANLIB], [1],
- [Commands used to install an old-style archive])
-
-# Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
-old_postinstall_cmds='chmod 644 $oldlib'
-old_postuninstall_cmds=
-
-if test -n "$RANLIB"; then
- case $host_os in
- openbsd*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
- ;;
- *)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
- ;;
- esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
-fi
-_LT_DECL([], [old_postinstall_cmds], [2])
-_LT_DECL([], [old_postuninstall_cmds], [2])
-_LT_TAGDECL([], [old_archive_cmds], [2],
- [Commands used to build an old-style archive])
-])# _LT_CMD_OLD_ARCHIVE
-
-
-# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
-# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
-# ----------------------------------------------------------------
-# Check whether the given compiler option works
-AC_DEFUN([_LT_COMPILER_OPTION],
-[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_DECL_SED])dnl
-AC_CACHE_CHECK([$1], [$2],
- [$2=no
- m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$3"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&AS_MESSAGE_LOG_FD
- echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- $2=yes
- fi
- fi
- $RM conftest*
-])
-
-if test x"[$]$2" = xyes; then
- m4_if([$5], , :, [$5])
-else
- m4_if([$6], , :, [$6])
-fi
-])# _LT_COMPILER_OPTION
-
-# Old name:
-AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
-
-
-# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
-# [ACTION-SUCCESS], [ACTION-FAILURE])
-# ----------------------------------------------------
-# Check whether the given linker option works
-AC_DEFUN([_LT_LINKER_OPTION],
-[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_DECL_SED])dnl
-AC_CACHE_CHECK([$1], [$2],
- [$2=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $3"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&AS_MESSAGE_LOG_FD
- $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- $2=yes
- fi
- else
- $2=yes
- fi
- fi
- $RM -r conftest*
- LDFLAGS="$save_LDFLAGS"
-])
-
-if test x"[$]$2" = xyes; then
- m4_if([$4], , :, [$4])
-else
- m4_if([$5], , :, [$5])
-fi
-])# _LT_LINKER_OPTION
-
-# Old name:
-AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
-
-
-# LT_CMD_MAX_LEN
-#---------------
-AC_DEFUN([LT_CMD_MAX_LEN],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-# find the maximum length of command line arguments
-AC_MSG_CHECKING([the maximum length of command line arguments])
-AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
- i=0
- teststring="ABCD"
-
- case $build_os in
- msdosdjgpp*)
- # On DJGPP, this test can blow up pretty badly due to problems in libc
- # (any single argument exceeding 2000 bytes causes a buffer overrun
- # during glob expansion). Even if it were fixed, the result of this
- # check would be larger than it should be.
- lt_cv_sys_max_cmd_len=12288; # 12K is about right
- ;;
-
- gnu*)
- # Under GNU Hurd, this test is not required because there is
- # no limit to the length of command line arguments.
- # Libtool will interpret -1 as no limit whatsoever
- lt_cv_sys_max_cmd_len=-1;
- ;;
-
- cygwin* | mingw* | cegcc*)
- # On Win9x/ME, this test blows up -- it succeeds, but takes
- # about 5 minutes as the teststring grows exponentially.
- # Worse, since 9x/ME are not pre-emptively multitasking,
- # you end up with a "frozen" computer, even though with patience
- # the test eventually succeeds (with a max line length of 256k).
- # Instead, let's just punt: use the minimum linelength reported by
- # all of the supported platforms: 8192 (on NT/2K/XP).
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- amigaos*)
- # On AmigaOS with pdksh, this test takes hours, literally.
- # So we just punt and use a minimum line length of 8192.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
- # This has been around since 386BSD, at least. Likely further.
- if test -x /sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
- elif test -x /usr/sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
- else
- lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
- fi
- # And add a safety zone
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- ;;
-
- interix*)
- # We know the value 262144 and hardcode it with a safety zone (like BSD)
- lt_cv_sys_max_cmd_len=196608
- ;;
-
- osf*)
- # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
- # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
- # nice to cause kernel panics so lets avoid the loop below.
- # First set a reasonable default.
- lt_cv_sys_max_cmd_len=16384
- #
- if test -x /sbin/sysconfig; then
- case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
- *1*) lt_cv_sys_max_cmd_len=-1 ;;
- esac
- fi
- ;;
- sco3.2v5*)
- lt_cv_sys_max_cmd_len=102400
- ;;
- sysv5* | sco5v6* | sysv4.2uw2*)
- kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
- if test -n "$kargmax"; then
- lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
- else
- lt_cv_sys_max_cmd_len=32768
- fi
- ;;
- *)
- lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- else
- # Make teststring a little bigger before we do anything with it.
- # a 1K string should be a reasonable start.
- for i in 1 2 3 4 5 6 7 8 ; do
- teststring=$teststring$teststring
- done
- SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
- # If test is not a shell built-in, we'll probably end up computing a
- # maximum length that is only half of the actual maximum length, but
- # we can't tell.
- while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
- = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
- test $i != 17 # 1/2 MB should be enough
- do
- i=`expr $i + 1`
- teststring=$teststring$teststring
- done
- # Only check the string length outside the loop.
- lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
- teststring=
- # Add a significant safety factor because C++ compilers can tack on
- # massive amounts of additional arguments before passing them to the
- # linker. It appears as though 1/2 is a usable value.
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
- fi
- ;;
- esac
-])
-if test -n $lt_cv_sys_max_cmd_len ; then
- AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
-else
- AC_MSG_RESULT(none)
-fi
-max_cmd_len=$lt_cv_sys_max_cmd_len
-_LT_DECL([], [max_cmd_len], [0],
- [What is the maximum length of a command?])
-])# LT_CMD_MAX_LEN
-
-# Old name:
-AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
-
-
-# _LT_HEADER_DLFCN
-# ----------------
-m4_defun([_LT_HEADER_DLFCN],
-[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
-])# _LT_HEADER_DLFCN
-
-
-# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
-# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
-# ----------------------------------------------------------------
-m4_defun([_LT_TRY_DLOPEN_SELF],
-[m4_require([_LT_HEADER_DLFCN])dnl
-if test "$cross_compiling" = yes; then :
- [$4]
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
-[#line __oline__ "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- return status;
-}]
-_LT_EOF
- if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) $1 ;;
- x$lt_dlneed_uscore) $2 ;;
- x$lt_dlunknown|x*) $3 ;;
- esac
- else :
- # compilation failed
- $3
- fi
-fi
-rm -fr conftest*
-])# _LT_TRY_DLOPEN_SELF
-
-
-# LT_SYS_DLOPEN_SELF
-# ------------------
-AC_DEFUN([LT_SYS_DLOPEN_SELF],
-[m4_require([_LT_HEADER_DLFCN])dnl
-if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- mingw* | pw32* | cegcc*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- cygwin*)
- lt_cv_dlopen="dlopen"
- lt_cv_dlopen_libs=
- ;;
-
- darwin*)
- # if libdl is installed we need to link against it
- AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
- lt_cv_dlopen="dyld"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ])
- ;;
-
- *)
- AC_CHECK_FUNC([shl_load],
- [lt_cv_dlopen="shl_load"],
- [AC_CHECK_LIB([dld], [shl_load],
- [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
- [AC_CHECK_FUNC([dlopen],
- [lt_cv_dlopen="dlopen"],
- [AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
- [AC_CHECK_LIB([svld], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
- [AC_CHECK_LIB([dld], [dld_link],
- [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
- ])
- ])
- ])
- ])
- ])
- ;;
- esac
-
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
- else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- AC_CACHE_CHECK([whether a program can dlopen itself],
- lt_cv_dlopen_self, [dnl
- _LT_TRY_DLOPEN_SELF(
- lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
- lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
- ])
-
- if test "x$lt_cv_dlopen_self" = xyes; then
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
- AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
- lt_cv_dlopen_self_static, [dnl
- _LT_TRY_DLOPEN_SELF(
- lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
- lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
- ])
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
-
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
-fi
-_LT_DECL([dlopen_support], [enable_dlopen], [0],
- [Whether dlopen is supported])
-_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
- [Whether dlopen of programs is supported])
-_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
- [Whether dlopen of statically linked programs is supported])
-])# LT_SYS_DLOPEN_SELF
-
-# Old name:
-AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
-
-
-# _LT_COMPILER_C_O([TAGNAME])
-# ---------------------------
-# Check to see if options -c and -o are simultaneously supported by compiler.
-# This macro does not hard code the compiler like AC_PROG_CC_C_O.
-m4_defun([_LT_COMPILER_C_O],
-[m4_require([_LT_DECL_SED])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_TAG_COMPILER])dnl
-AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
- [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
- [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
- $RM -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&AS_MESSAGE_LOG_FD
- echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
- fi
- fi
- chmod u+w . 2>&AS_MESSAGE_LOG_FD
- $RM conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
- $RM out/* && rmdir out
- cd ..
- $RM -r conftest
- $RM conftest*
-])
-_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
- [Does compiler simultaneously support -c and -o options?])
-])# _LT_COMPILER_C_O
-
-
-# _LT_COMPILER_FILE_LOCKS([TAGNAME])
-# ----------------------------------
-# Check to see if we can do hard links to lock some files if needed
-m4_defun([_LT_COMPILER_FILE_LOCKS],
-[m4_require([_LT_ENABLE_LOCK])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-_LT_COMPILER_C_O([$1])
-
-hard_links="nottested"
-if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- AC_MSG_CHECKING([if we can lock with hard links])
- hard_links=yes
- $RM conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- AC_MSG_RESULT([$hard_links])
- if test "$hard_links" = no; then
- AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
-])# _LT_COMPILER_FILE_LOCKS
-
-
-# _LT_CHECK_OBJDIR
-# ----------------
-m4_defun([_LT_CHECK_OBJDIR],
-[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
-[rm -f .libs 2>/dev/null
-mkdir .libs 2>/dev/null
-if test -d .libs; then
- lt_cv_objdir=.libs
-else
- # MS-DOS does not allow filenames that begin with a dot.
- lt_cv_objdir=_libs
-fi
-rmdir .libs 2>/dev/null])
-objdir=$lt_cv_objdir
-_LT_DECL([], [objdir], [0],
- [The name of the directory that contains temporary libtool files])dnl
-m4_pattern_allow([LT_OBJDIR])dnl
-AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
- [Define to the sub-directory in which libtool stores uninstalled libraries.])
-])# _LT_CHECK_OBJDIR
-
-
-# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
-# --------------------------------------
-# Check hardcoding attributes.
-m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
-[AC_MSG_CHECKING([how to hardcode library paths into programs])
-_LT_TAGVAR(hardcode_action, $1)=
-if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
- test -n "$_LT_TAGVAR(runpath_var, $1)" ||
- test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
-
- # We can hardcode non-existent directories.
- if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
- test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
- # Linking always hardcodes the temporary library directory.
- _LT_TAGVAR(hardcode_action, $1)=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- _LT_TAGVAR(hardcode_action, $1)=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- _LT_TAGVAR(hardcode_action, $1)=unsupported
-fi
-AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
-
-if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
- test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-_LT_TAGDECL([], [hardcode_action], [0],
- [How to hardcode a shared library path into an executable])
-])# _LT_LINKER_HARDCODE_LIBPATH
-
-
-# _LT_CMD_STRIPLIB
-# ----------------
-m4_defun([_LT_CMD_STRIPLIB],
-[m4_require([_LT_DECL_EGREP])
-striplib=
-old_striplib=
-AC_MSG_CHECKING([whether stripping libraries is possible])
-if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- AC_MSG_RESULT([yes])
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- old_striplib="$STRIP -S"
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- ;;
- *)
- AC_MSG_RESULT([no])
- ;;
- esac
-fi
-_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
-_LT_DECL([], [striplib], [1])
-])# _LT_CMD_STRIPLIB
-
-
-# _LT_SYS_DYNAMIC_LINKER([TAG])
-# -----------------------------
-# PORTME Fill in your ld.so characteristics
-m4_defun([_LT_SYS_DYNAMIC_LINKER],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-m4_require([_LT_DECL_EGREP])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_DECL_OBJDUMP])dnl
-m4_require([_LT_DECL_SED])dnl
-AC_MSG_CHECKING([dynamic linker characteristics])
-m4_if([$1],
- [], [
-if test "$GCC" = yes; then
- case $host_os in
- darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
- *) lt_awk_arg="/^libraries:/" ;;
- esac
- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
- else
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- # Ok, now we have the path, separated by spaces, we can step through it
- # and add multilib dir if necessary.
- lt_tmp_lt_search_path_spec=
- lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
- for lt_sys_path in $lt_search_path_spec; do
- if test -d "$lt_sys_path/$lt_multi_os_dir"; then
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
- else
- test -d "$lt_sys_path" && \
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
- fi
- done
- lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
-BEGIN {RS=" "; FS="/|\n";} {
- lt_foo="";
- lt_count=0;
- for (lt_i = NF; lt_i > 0; lt_i--) {
- if ($lt_i != "" && $lt_i != ".") {
- if ($lt_i == "..") {
- lt_count++;
- } else {
- if (lt_count == 0) {
- lt_foo="/" $lt_i lt_foo;
- } else {
- lt_count--;
- }
- }
- }
- }
- if (lt_foo != "") { lt_freq[[lt_foo]]++; }
- if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
-}'`
- sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi])
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[[4-9]]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[[01]] | aix4.[[01]].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- case $host_cpu in
- powerpc)
- # Since July 2007 AmigaOS4 officially supports .so libraries.
- # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- ;;
- m68k)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
- esac
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[[45]]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32* | cegcc*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname~
- if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
- eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
- fi'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $RM \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw* | cegcc*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-m4_if([$1], [],[
- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[[123]]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[[01]]* | freebsdelf3.[[01]]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
- freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix[[3-9]]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # Some binutils ld are patched to set DT_RUNPATH
- save_LDFLAGS=$LDFLAGS
- save_libdir=$libdir
- eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
- LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
- AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
- [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
- [shlibpath_overrides_runpath=yes])])
- LDFLAGS=$save_LDFLAGS
- libdir=$save_libdir
-
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsdelf*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='NetBSD ld.elf_so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-*nto* | *qnx*)
- version_type=qnx
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='ldqnx.so'
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[[89]] | openbsd2.[[89]].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-tpf*)
- # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-AC_MSG_RESULT([$dynamic_linker])
-test "$dynamic_linker" = no && can_build_shared=no
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-fi
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-fi
-
-_LT_DECL([], [variables_saved_for_relink], [1],
- [Variables whose values should be saved in libtool wrapper scripts and
- restored at link time])
-_LT_DECL([], [need_lib_prefix], [0],
- [Do we need the "lib" prefix for modules?])
-_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
-_LT_DECL([], [version_type], [0], [Library versioning type])
-_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
-_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
-_LT_DECL([], [shlibpath_overrides_runpath], [0],
- [Is shlibpath searched before the hard-coded library search path?])
-_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
-_LT_DECL([], [library_names_spec], [1],
- [[List of archive names. First name is the real one, the rest are links.
- The last name is the one that the linker finds with -lNAME]])
-_LT_DECL([], [soname_spec], [1],
- [[The coded name of the library, if different from the real name]])
-_LT_DECL([], [postinstall_cmds], [2],
- [Command to use after installation of a shared archive])
-_LT_DECL([], [postuninstall_cmds], [2],
- [Command to use after uninstallation of a shared archive])
-_LT_DECL([], [finish_cmds], [2],
- [Commands used to finish a libtool library installation in a directory])
-_LT_DECL([], [finish_eval], [1],
- [[As "finish_cmds", except a single script fragment to be evaled but
- not shown]])
-_LT_DECL([], [hardcode_into_libs], [0],
- [Whether we should hardcode library paths into libraries])
-_LT_DECL([], [sys_lib_search_path_spec], [2],
- [Compile-time system search path for libraries])
-_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
- [Run-time system search path for libraries])
-])# _LT_SYS_DYNAMIC_LINKER
-
-
-# _LT_PATH_TOOL_PREFIX(TOOL)
-# --------------------------
-# find a file program which can recognize shared library
-AC_DEFUN([_LT_PATH_TOOL_PREFIX],
-[m4_require([_LT_DECL_EGREP])dnl
-AC_MSG_CHECKING([for $1])
-AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
-[case $MAGIC_CMD in
-[[\\/*] | ?:[\\/]*])
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-dnl $ac_dummy forces splitting on constant user-supplied paths.
-dnl POSIX.2 word splitting is done only on the output of word expansions,
-dnl not every word. This closes a longstanding sh security hole.
- ac_dummy="m4_if([$2], , $PATH, [$2])"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$1; then
- lt_cv_path_MAGIC_CMD="$ac_dir/$1"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<_LT_EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-_LT_EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac])
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- AC_MSG_RESULT($MAGIC_CMD)
-else
- AC_MSG_RESULT(no)
-fi
-_LT_DECL([], [MAGIC_CMD], [0],
- [Used to examine libraries when file_magic_cmd begins with "file"])dnl
-])# _LT_PATH_TOOL_PREFIX
-
-# Old name:
-AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
-
-
-# _LT_PATH_MAGIC
-# --------------
-# find a file program which can recognize a shared library
-m4_defun([_LT_PATH_MAGIC],
-[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
-if test -z "$lt_cv_path_MAGIC_CMD"; then
- if test -n "$ac_tool_prefix"; then
- _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
- else
- MAGIC_CMD=:
- fi
-fi
-])# _LT_PATH_MAGIC
-
-
-# LT_PATH_LD
-# ----------
-# find the pathname to the GNU or non-GNU linker
-AC_DEFUN([LT_PATH_LD],
-[AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-m4_require([_LT_DECL_SED])dnl
-m4_require([_LT_DECL_EGREP])dnl
-
-AC_ARG_WITH([gnu-ld],
- [AS_HELP_STRING([--with-gnu-ld],
- [assume the C compiler uses GNU ld @<:@default=no@:>@])],
- [test "$withval" = no || with_gnu_ld=yes],
- [with_gnu_ld=no])dnl
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- AC_MSG_CHECKING([for ld used by $CC])
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [[\\/]]* | ?:[[\\/]]*)
- re_direlt='/[[^/]][[^/]]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
- while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- AC_MSG_CHECKING([for GNU ld])
-else
- AC_MSG_CHECKING([for non-GNU ld])
-fi
-AC_CACHE_VAL(lt_cv_path_LD,
-[if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi])
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- AC_MSG_RESULT($LD)
-else
- AC_MSG_RESULT(no)
-fi
-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-_LT_PATH_LD_GNU
-AC_SUBST([LD])
-
-_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
-])# LT_PATH_LD
-
-# Old names:
-AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
-AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AM_PROG_LD], [])
-dnl AC_DEFUN([AC_PROG_LD], [])
-
-
-# _LT_PATH_LD_GNU
-#- --------------
-m4_defun([_LT_PATH_LD_GNU],
-[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac])
-with_gnu_ld=$lt_cv_prog_gnu_ld
-])# _LT_PATH_LD_GNU
-
-
-# _LT_CMD_RELOAD
-# --------------
-# find reload flag for linker
-# -- PORTME Some linkers may need a different reload flag.
-m4_defun([_LT_CMD_RELOAD],
-[AC_CACHE_CHECK([for $LD option to reload object files],
- lt_cv_ld_reload_flag,
- [lt_cv_ld_reload_flag='-r'])
-reload_flag=$lt_cv_ld_reload_flag
-case $reload_flag in
-"" | " "*) ;;
-*) reload_flag=" $reload_flag" ;;
-esac
-reload_cmds='$LD$reload_flag -o $output$reload_objs'
-case $host_os in
- darwin*)
- if test "$GCC" = yes; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
- else
- reload_cmds='$LD$reload_flag -o $output$reload_objs'
- fi
- ;;
-esac
-_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
-_LT_DECL([], [reload_cmds], [2])dnl
-])# _LT_CMD_RELOAD
-
-
-# _LT_CHECK_MAGIC_METHOD
-# ----------------------
-# how to check for library dependencies
-# -- PORTME fill in with the dynamic library characteristics
-m4_defun([_LT_CHECK_MAGIC_METHOD],
-[m4_require([_LT_DECL_EGREP])
-m4_require([_LT_DECL_OBJDUMP])
-AC_CACHE_CHECK([how to recognize dependent libraries],
-lt_cv_deplibs_check_method,
-[lt_cv_file_magic_cmd='$MAGIC_CMD'
-lt_cv_file_magic_test_file=
-lt_cv_deplibs_check_method='unknown'
-# Need to set the preceding variable on all platforms that support
-# interlibrary dependencies.
-# 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
-# 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
-# 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
-
-case $host_os in
-aix[[4-9]]*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-beos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-bsdi[[45]]*)
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- lt_cv_file_magic_test_file=/shlib/libc.so
- ;;
-
-cygwin*)
- # func_win32_libid is a shell function defined in ltmain.sh
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- ;;
-
-mingw* | pw32*)
- # Base MSYS/MinGW do not provide the 'file' command needed by
- # func_win32_libid shell function, so use a weaker test based on 'objdump',
- # unless we find 'file', for example because we are cross-compiling.
- if ( file / ) >/dev/null 2>&1; then
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- else
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- fi
- ;;
-
-cegcc)
- # use the weaker test based on 'objdump'. See mingw*.
- lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- ;;
-
-darwin* | rhapsody*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-freebsd* | dragonfly*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
- case $host_cpu in
- i*86 )
- # Not sure whether the presence of OpenBSD here was a mistake.
- # Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
- ;;
- esac
- else
- lt_cv_deplibs_check_method=pass_all
- fi
- ;;
-
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-hpux10.20* | hpux11*)
- lt_cv_file_magic_cmd=/usr/bin/file
- case $host_cpu in
- ia64*)
- lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
- lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
- ;;
- hppa*64*)
- [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
- lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
- ;;
- *)
- lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
- lt_cv_file_magic_test_file=/usr/lib/libc.sl
- ;;
- esac
- ;;
-
-interix[[3-9]]*)
- # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-netbsd* | netbsdelf*-gnu)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
- fi
- ;;
-
-newos6*)
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=/usr/lib/libnls.so
- ;;
-
-*nto* | *qnx*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-openbsd*)
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
- fi
- ;;
-
-osf3* | osf4* | osf5*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-rdos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-solaris*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv4 | sysv4.3*)
- case $host_vendor in
- motorola)
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
- ;;
- ncr)
- lt_cv_deplibs_check_method=pass_all
- ;;
- sequent)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
- ;;
- sni)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
- lt_cv_file_magic_test_file=/lib/libc.so
- ;;
- siemens)
- lt_cv_deplibs_check_method=pass_all
- ;;
- pc)
- lt_cv_deplibs_check_method=pass_all
- ;;
- esac
- ;;
-
-tpf*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-esac
-])
-file_magic_cmd=$lt_cv_file_magic_cmd
-deplibs_check_method=$lt_cv_deplibs_check_method
-test -z "$deplibs_check_method" && deplibs_check_method=unknown
-
-_LT_DECL([], [deplibs_check_method], [1],
- [Method to check whether dependent libraries are shared objects])
-_LT_DECL([], [file_magic_cmd], [1],
- [Command to use when deplibs_check_method == "file_magic"])
-])# _LT_CHECK_MAGIC_METHOD
-
-
-# LT_PATH_NM
-# ----------
-# find the pathname to a BSD- or MS-compatible name lister
-AC_DEFUN([LT_PATH_NM],
-[AC_REQUIRE([AC_PROG_CC])dnl
-AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
-[if test -n "$NM"; then
- # Let the user override the test.
- lt_cv_path_NM="$NM"
-else
- lt_nm_to_check="${ac_tool_prefix}nm"
- if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
- lt_nm_to_check="$lt_nm_to_check nm"
- fi
- for lt_tmp_nm in $lt_nm_to_check; do
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- tmp_nm="$ac_dir/$lt_tmp_nm"
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
- # Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
- # nm: unknown option "B" ignored
- # Tru64's nm complains that /dev/null is an invalid object file
- case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
- */dev/null* | *'Invalid file or object type'*)
- lt_cv_path_NM="$tmp_nm -B"
- break
- ;;
- *)
- case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
- */dev/null*)
- lt_cv_path_NM="$tmp_nm -p"
- break
- ;;
- *)
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
- continue # so that we can try to find one that supports BSD flags
- ;;
- esac
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
- done
- : ${lt_cv_path_NM=no}
-fi])
-if test "$lt_cv_path_NM" != "no"; then
- NM="$lt_cv_path_NM"
-else
- # Didn't find any BSD compatible name lister, look for dumpbin.
- AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
- AC_SUBST([DUMPBIN])
- if test "$DUMPBIN" != ":"; then
- NM="$DUMPBIN"
- fi
-fi
-test -z "$NM" && NM=nm
-AC_SUBST([NM])
-_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
-
-AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
- [lt_cv_nm_interface="BSD nm"
- echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
- (eval "$ac_compile" 2>conftest.err)
- cat conftest.err >&AS_MESSAGE_LOG_FD
- (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
- (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
- cat conftest.err >&AS_MESSAGE_LOG_FD
- (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
- cat conftest.out >&AS_MESSAGE_LOG_FD
- if $GREP 'External.*some_variable' conftest.out > /dev/null; then
- lt_cv_nm_interface="MS dumpbin"
- fi
- rm -f conftest*])
-])# LT_PATH_NM
-
-# Old names:
-AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
-AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AM_PROG_NM], [])
-dnl AC_DEFUN([AC_PROG_NM], [])
-
-
-# LT_LIB_M
-# --------
-# check for math library
-AC_DEFUN([LT_LIB_M],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-LIBM=
-case $host in
-*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
- # These system don't have libm, or don't need it
- ;;
-*-ncr-sysv4.3*)
- AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
- AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
- ;;
-*)
- AC_CHECK_LIB(m, cos, LIBM="-lm")
- ;;
-esac
-AC_SUBST([LIBM])
-])# LT_LIB_M
-
-# Old name:
-AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_CHECK_LIBM], [])
-
-
-# _LT_COMPILER_NO_RTTI([TAGNAME])
-# -------------------------------
-m4_defun([_LT_COMPILER_NO_RTTI],
-[m4_require([_LT_TAG_COMPILER])dnl
-
-_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
-
-if test "$GCC" = yes; then
- _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
-
- _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
- lt_cv_prog_compiler_rtti_exceptions,
- [-fno-rtti -fno-exceptions], [],
- [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
-fi
-_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
- [Compiler flag to turn off builtin functions])
-])# _LT_COMPILER_NO_RTTI
-
-
-# _LT_CMD_GLOBAL_SYMBOLS
-# ----------------------
-m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([LT_PATH_NM])dnl
-AC_REQUIRE([LT_PATH_LD])dnl
-m4_require([_LT_DECL_SED])dnl
-m4_require([_LT_DECL_EGREP])dnl
-m4_require([_LT_TAG_COMPILER])dnl
-
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-AC_MSG_CHECKING([command to parse $NM output from $compiler object])
-AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
-[
-# These are sane defaults that work on at least a few old systems.
-# [They come from Ultrix. What could be older than Ultrix?!! ;)]
-
-# Character class describing NM global symbol codes.
-symcode='[[BCDEGRST]]'
-
-# Regexp to match symbols that can be accessed directly from C.
-sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
-
-# Define system-specific variables.
-case $host_os in
-aix*)
- symcode='[[BCDT]]'
- ;;
-cygwin* | mingw* | pw32* | cegcc*)
- symcode='[[ABCDGISTW]]'
- ;;
-hpux*)
- if test "$host_cpu" = ia64; then
- symcode='[[ABCDEGRST]]'
- fi
- ;;
-irix* | nonstopux*)
- symcode='[[BCDEGRST]]'
- ;;
-osf*)
- symcode='[[BCDEGQRST]]'
- ;;
-solaris*)
- symcode='[[BDRT]]'
- ;;
-sco3.2v5*)
- symcode='[[DT]]'
- ;;
-sysv4.2uw2*)
- symcode='[[DT]]'
- ;;
-sysv5* | sco5v6* | unixware* | OpenUNIX*)
- symcode='[[ABDT]]'
- ;;
-sysv4)
- symcode='[[DFNSTU]]'
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-case `$NM -V 2>&1` in
-*GNU* | *'with BFD'*)
- symcode='[[ABCDGIRSTW]]' ;;
-esac
-
-# Transform an extracted symbol line into a proper C declaration.
-# Some systems (esp. on ia64) link data and code symbols differently,
-# so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
-
-# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
-
-# Handle CRLF in mingw tool chain
-opt_cr=
-case $build_os in
-mingw*)
- opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
- ;;
-esac
-
-# Try without a prefix underscore, then with it.
-for ac_symprfx in "" "_"; do
-
- # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
- symxfrm="\\1 $ac_symprfx\\2 \\2"
-
- # Write the raw and C identifiers.
- if test "$lt_cv_nm_interface" = "MS dumpbin"; then
- # Fake it for dumpbin and say T for any non-static function
- # and D for any global variable.
- # Also find C++ and __fastcall symbols from MSVC++,
- # which start with @ or ?.
- lt_cv_sys_global_symbol_pipe="$AWK ['"\
-" {last_section=section; section=\$ 3};"\
-" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-" \$ 0!~/External *\|/{next};"\
-" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
-" {if(hide[section]) next};"\
-" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
-" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
-" s[1]~/^[@?]/{print s[1], s[1]; next};"\
-" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
-" ' prfx=^$ac_symprfx]"
- else
- lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
- fi
-
- # Check to see that the pipe works correctly.
- pipe_works=no
-
- rm -f conftest*
- cat > conftest.$ac_ext <<_LT_EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(void);
-void nm_test_func(void){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func();return(0);}
-_LT_EOF
-
- if AC_TRY_EVAL(ac_compile); then
- # Now try to grab the symbols.
- nlist=conftest.nm
- if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
- # Try sorting and uniquifying the output.
- if sort "$nlist" | uniq > "$nlist"T; then
- mv -f "$nlist"T "$nlist"
- else
- rm -f "$nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
- if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
- cat <<_LT_EOF > conftest.$ac_ext
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-_LT_EOF
- # Now generate the symbol file.
- eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
-
- cat <<_LT_EOF >> conftest.$ac_ext
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- void *address;
-}
-lt__PROGRAM__LTX_preloaded_symbols[[]] =
-{
- { "@PROGRAM@", (void *) 0 },
-_LT_EOF
- $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
- cat <<\_LT_EOF >> conftest.$ac_ext
- {0, (void *) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
- return lt__PROGRAM__LTX_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-_LT_EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- lt_save_LIBS="$LIBS"
- lt_save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
- if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
- pipe_works=yes
- fi
- LIBS="$lt_save_LIBS"
- CFLAGS="$lt_save_CFLAGS"
- else
- echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
- fi
- else
- echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
- fi
- else
- echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
- fi
- else
- echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
- cat conftest.$ac_ext >&5
- fi
- rm -rf conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$pipe_works" = yes; then
- break
- else
- lt_cv_sys_global_symbol_pipe=
- fi
-done
-])
-if test -z "$lt_cv_sys_global_symbol_pipe"; then
- lt_cv_sys_global_symbol_to_cdecl=
-fi
-if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
- AC_MSG_RESULT(failed)
-else
- AC_MSG_RESULT(ok)
-fi
-
-_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
- [Take the output of nm and produce a listing of raw symbols and C names])
-_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
- [Transform the output of nm in a proper C declaration])
-_LT_DECL([global_symbol_to_c_name_address],
- [lt_cv_sys_global_symbol_to_c_name_address], [1],
- [Transform the output of nm in a C name address pair])
-_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
- [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
- [Transform the output of nm in a C name address pair when lib prefix is needed])
-]) # _LT_CMD_GLOBAL_SYMBOLS
-
-
-# _LT_COMPILER_PIC([TAGNAME])
-# ---------------------------
-m4_defun([_LT_COMPILER_PIC],
-[m4_require([_LT_TAG_COMPILER])dnl
-_LT_TAGVAR(lt_prog_compiler_wl, $1)=
-_LT_TAGVAR(lt_prog_compiler_pic, $1)=
-_LT_TAGVAR(lt_prog_compiler_static, $1)=
-
-AC_MSG_CHECKING([for $compiler option to produce PIC])
-m4_if([$1], [CXX], [
- # C++ specific cases for pic, static, wl, etc.
- if test "$GXX" = yes; then
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- m68k)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
- ;;
- esac
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
- mingw* | cygwin* | os2* | pw32* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- m4_if([$1], [GCJ], [],
- [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- ;;
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
- ;;
- *djgpp*)
- # DJGPP does not support shared libraries at all
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=
- ;;
- interix[[3-9]]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
- fi
- ;;
- hpux*)
- # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
- # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
- # sets the default TLS model and affects inlining.
- case $host_cpu in
- hppa*64*)
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- ;;
- *qnx* | *nto*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- else
- case $host_os in
- aix[[4-9]]*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- else
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- chorus*)
- case $cc_basename in
- cxch68*)
- # Green Hills C++ Compiler
- # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
- ;;
- esac
- ;;
- dgux*)
- case $cc_basename in
- ec++*)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- freebsd* | dragonfly*)
- # FreeBSD uses GNU C++
- ;;
- hpux9* | hpux10* | hpux11*)
- case $cc_basename in
- CC*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
- if test "$host_cpu" != ia64; then
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
- fi
- ;;
- aCC*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
- ;;
- esac
- ;;
- *)
- ;;
- esac
- ;;
- interix*)
- # This is c89, which is MS Visual C++ (no shared libs)
- # Anyone wants to do a port?
- ;;
- irix5* | irix6* | nonstopux*)
- case $cc_basename in
- CC*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- # CC pic flag -KPIC is the default.
- ;;
- *)
- ;;
- esac
- ;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- KCC*)
- # KAI C++ Compiler
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- ecpc* )
- # old Intel C++ for x86_64 which still supported -KPIC.
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- icpc* )
- # Intel C++, used to be incompatible with GCC.
- # ICC 10 doesn't accept -KPIC any more.
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- pgCC* | pgcpp*)
- # Portland Group C++ compiler
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- cxx*)
- # Compaq C++
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
- xlc* | xlC*)
- # IBM XL 8.0 on PPC
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
- ;;
- esac
- ;;
- esac
- ;;
- lynxos*)
- ;;
- m88k*)
- ;;
- mvs*)
- case $cc_basename in
- cxx*)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
- ;;
- *)
- ;;
- esac
- ;;
- netbsd* | netbsdelf*-gnu)
- ;;
- *qnx* | *nto*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
- ;;
- osf3* | osf4* | osf5*)
- case $cc_basename in
- KCC*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
- ;;
- RCC*)
- # Rational C++ 2.4.1
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- ;;
- cxx*)
- # Digital/Compaq C++
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
- *)
- ;;
- esac
- ;;
- psos*)
- ;;
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
- ;;
- gcx*)
- # Green Hills C++ Compiler
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
- ;;
- *)
- ;;
- esac
- ;;
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- lcc*)
- # Lucid
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- case $cc_basename in
- CC*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- esac
- ;;
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- ;;
- *)
- ;;
- esac
- ;;
- vxworks*)
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- ;;
- esac
- fi
-],
-[
- if test "$GCC" = yes; then
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- m68k)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
- ;;
- esac
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- m4_if([$1], [GCJ], [],
- [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
- ;;
-
- hpux*)
- # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
- # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
- # sets the default TLS model and affects inlining.
- case $host_cpu in
- hppa*64*)
- # +Z the default
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- ;;
-
- interix[[3-9]]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- enable_shared=no
- ;;
-
- *nto* | *qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
- fi
- ;;
-
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- else
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
-
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- m4_if([$1], [GCJ], [],
- [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- ;;
-
- hpux9* | hpux10* | hpux11*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # PIC (with -KPIC) is the default.
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
-
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- # old Intel for x86_64 which still supported -KPIC.
- ecc*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- # icc used to be incompatible with GCC.
- # ICC 10 doesn't accept -KPIC any more.
- icc* | ifort*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- # Lahey Fortran 8.1.
- lf95*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- ccc*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # All Alpha code is PIC.
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
- xl*)
- # IBM XL C 8.0/Fortran 10.1 on PPC
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C 5.9
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- ;;
- *Sun\ F*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
- ;;
- esac
- ;;
- esac
- ;;
-
- newsos6)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- *nto* | *qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
- ;;
-
- osf3* | osf4* | osf5*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # All OSF/1 code is PIC.
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
-
- rdos*)
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
-
- solaris*)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
- *)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
- esac
- ;;
-
- sunos4*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- unicos*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- ;;
-
- uts4*)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- *)
- _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- ;;
- esac
- fi
-])
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
- ;;
-esac
-AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
-_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
- [How to pass a linker flag through the compiler])
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
- _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
- [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
- [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
- [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
- "" | " "*) ;;
- *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
- esac],
- [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
- _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
-fi
-_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
- [Additional compiler flags for building library objects])
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
-_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
- _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
- $lt_tmp_static_flag,
- [],
- [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
-_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
- [Compiler flag to prevent dynamic linking])
-])# _LT_COMPILER_PIC
-
-
-# _LT_LINKER_SHLIBS([TAGNAME])
-# ----------------------------
-# See if the linker supports building shared libraries.
-m4_defun([_LT_LINKER_SHLIBS],
-[AC_REQUIRE([LT_PATH_LD])dnl
-AC_REQUIRE([LT_PATH_NM])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_DECL_EGREP])dnl
-m4_require([_LT_DECL_SED])dnl
-m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
-m4_require([_LT_TAG_COMPILER])dnl
-AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
-m4_if([$1], [CXX], [
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- case $host_os in
- aix[[4-9]]*)
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- else
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- fi
- ;;
- pw32*)
- _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
- ;;
- cygwin* | mingw* | cegcc*)
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
- linux* | k*bsd*-gnu)
- _LT_TAGVAR(link_all_deplibs, $1)=no
- ;;
- *)
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
- esac
- _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
-], [
- runpath_var=
- _LT_TAGVAR(allow_undefined_flag, $1)=
- _LT_TAGVAR(always_export_symbols, $1)=no
- _LT_TAGVAR(archive_cmds, $1)=
- _LT_TAGVAR(archive_expsym_cmds, $1)=
- _LT_TAGVAR(compiler_needs_object, $1)=no
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
- _LT_TAGVAR(export_dynamic_flag_spec, $1)=
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- _LT_TAGVAR(hardcode_automatic, $1)=no
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_direct_absolute, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
- _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
- _LT_TAGVAR(hardcode_libdir_separator, $1)=
- _LT_TAGVAR(hardcode_minus_L, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_TAGVAR(inherit_rpath, $1)=no
- _LT_TAGVAR(link_all_deplibs, $1)=unknown
- _LT_TAGVAR(module_cmds, $1)=
- _LT_TAGVAR(module_expsym_cmds, $1)=
- _LT_TAGVAR(old_archive_from_new_cmds, $1)=
- _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
- _LT_TAGVAR(thread_safe_flag_spec, $1)=
- _LT_TAGVAR(whole_archive_flag_spec, $1)=
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- _LT_TAGVAR(include_expsyms, $1)=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- # Exclude shared library initialization/finalization symbols.
-dnl Note also adjust exclude_expsyms for C++ above.
- extract_expsyms_cmds=
-
- case $host_os in
- cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- linux* | k*bsd*-gnu)
- _LT_TAGVAR(link_all_deplibs, $1)=no
- ;;
- esac
-
- _LT_TAGVAR(ld_shlibs, $1)=yes
- if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- _LT_TAGVAR(whole_archive_flag_spec, $1)=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>&1` in
- *GNU\ gold*) supports_anon_versioning=yes ;;
- *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix[[3-9]]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- _LT_TAGVAR(ld_shlibs, $1)=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-_LT_EOF
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)=''
- ;;
- m68k)
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- ;;
- esac
- ;;
-
- beos*)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
- # as there is no search path for DLLs.
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(always_export_symbols, $1)=no
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- interix[[3-9]]*)
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
- tmp_diet=no
- if test "$host_os" = linux-dietlibc; then
- case $cc_basename in
- diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
- esac
- fi
- if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
- && test "$tmp_diet" = no
- then
- tmp_addflag=
- tmp_sharedflag='-shared'
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- lf95*) # Lahey Fortran 8.1
- _LT_TAGVAR(whole_archive_flag_spec, $1)=
- tmp_sharedflag='--shared' ;;
- xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
- tmp_sharedflag='-qmkshrobj'
- tmp_addflag= ;;
- esac
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*) # Sun C 5.9
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- _LT_TAGVAR(compiler_needs_object, $1)=yes
- tmp_sharedflag='-G' ;;
- *Sun\ F*) # Sun Fortran 8.3
- tmp_sharedflag='-G' ;;
- esac
- _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test "x$supports_anon_versioning" = xyes; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
-
- case $cc_basename in
- xlf*)
- # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
- _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
- _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
- _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
- fi
- ;;
- esac
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- netbsd* | netbsdelf*-gnu)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
- _LT_TAGVAR(ld_shlibs, $1)=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
- _LT_TAGVAR(ld_shlibs, $1)=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- # For security reasons, it is highly recommended that you always
- # use absolute paths for naming shared libraries, and exclude the
- # DT_RUNPATH tag from executables and libraries. But doing so
- # requires that you compile everything twice, which is a pain.
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- *)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
-
- if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
- runpath_var=
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
- _LT_TAGVAR(export_dynamic_flag_spec, $1)=
- _LT_TAGVAR(whole_archive_flag_spec, $1)=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(always_export_symbols, $1)=yes
- _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- _LT_TAGVAR(hardcode_direct, $1)=unsupported
- fi
- ;;
-
- aix[[4-9]]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- else
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- _LT_TAGVAR(archive_cmds, $1)=''
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[[012]]|aix4.[[012]].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" &&
- strings "$collect2name" | $GREP resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- _LT_TAGVAR(hardcode_direct, $1)=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- _LT_TAGVAR(link_all_deplibs, $1)=no
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- _LT_TAGVAR(always_export_symbols, $1)=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
- # Determine the default libpath from the value encoded in an
- # empty executable.
- _LT_SYS_MODULE_PATH_AIX
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
- _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an
- # empty executable.
- _LT_SYS_MODULE_PATH_AIX
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)=''
- ;;
- m68k)
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- ;;
- esac
- ;;
-
- bsdi[[45]]*)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
- # FIXME: Should let the user specify the lib program.
- _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
- _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- ;;
-
- darwin* | rhapsody*)
- _LT_DARWIN_LINKER_FEATURES($1)
- ;;
-
- dgux*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- freebsd1*)
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | dragonfly*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(hardcode_direct, $1)=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
- *)
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- # Try to use the -exported_symbol ld option, if it does not
- # work, assume that -exports_file does not work either and
- # implicitly export all symbols.
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
- AC_LINK_IFELSE(int foo(void) {},
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
- )
- LDFLAGS="$save_LDFLAGS"
- else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
- fi
- _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(inherit_rpath, $1)=yes
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- ;;
-
- netbsd* | netbsdelf*-gnu)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- newsos6)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- *nto* | *qnx*)
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- else
- case $host_os in
- openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- os2*)
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- else
- _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
- fi
- _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- ;;
-
- solaris*)
- _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
- else
- case `$CC -V 2>&1` in
- *"Compilers 5.0"*)
- wlarc=''
- _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
- ;;
- *)
- wlarc='${wl}'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
- ;;
- esac
- fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- case $host_os in
- solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'. GCC discards it without `$wl',
- # but is careful enough not to reorder.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- if test "$GCC" = yes; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- else
- _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
- fi
- ;;
- esac
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
- _LT_TAGVAR(hardcode_direct, $1)=no
- ;;
- motorola)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- sysv4.3*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- _LT_TAGVAR(ld_shlibs, $1)=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- *)
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
-
- if test x$host_vendor = xsni; then
- case $host in
- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
- ;;
- esac
- fi
- fi
-])
-AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
-
-_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
-
-_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
-_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
-_LT_DECL([], [extract_expsyms_cmds], [2],
- [The commands to extract the exported symbol list from a shared archive])
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
-x|xyes)
- # Assume -lc should be added
- _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $_LT_TAGVAR(archive_cmds, $1) in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- AC_MSG_CHECKING([whether -lc should be explicitly linked in])
- $RM conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
- pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
- _LT_TAGVAR(allow_undefined_flag, $1)=
- if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
- then
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- else
- _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- fi
- _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $RM conftest*
- AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
- ;;
- esac
- fi
- ;;
-esac
-
-_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
- [Whether or not to add -lc for building shared libraries])
-_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
- [enable_shared_with_static_runtimes], [0],
- [Whether or not to disallow shared libs when runtime libs are static])
-_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
- [Compiler flag to allow reflexive dlopens])
-_LT_TAGDECL([], [whole_archive_flag_spec], [1],
- [Compiler flag to generate shared objects directly from archives])
-_LT_TAGDECL([], [compiler_needs_object], [1],
- [Whether the compiler copes with passing no objects directly])
-_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
- [Create an old-style archive from a shared archive])
-_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
- [Create a temporary old-style archive to link instead of a shared archive])
-_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
-_LT_TAGDECL([], [archive_expsym_cmds], [2])
-_LT_TAGDECL([], [module_cmds], [2],
- [Commands used to build a loadable module if different from building
- a shared archive.])
-_LT_TAGDECL([], [module_expsym_cmds], [2])
-_LT_TAGDECL([], [with_gnu_ld], [1],
- [Whether we are building with GNU ld or not])
-_LT_TAGDECL([], [allow_undefined_flag], [1],
- [Flag that allows shared libraries with undefined symbols to be built])
-_LT_TAGDECL([], [no_undefined_flag], [1],
- [Flag that enforces no undefined symbols])
-_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
- [Flag to hardcode $libdir into a binary during linking.
- This must work even if $libdir does not exist])
-_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
- [[If ld is used when linking, flag to hardcode $libdir into a binary
- during linking. This must work even if $libdir does not exist]])
-_LT_TAGDECL([], [hardcode_libdir_separator], [1],
- [Whether we need a single "-rpath" flag with a separated argument])
-_LT_TAGDECL([], [hardcode_direct], [0],
- [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
- DIR into the resulting binary])
-_LT_TAGDECL([], [hardcode_direct_absolute], [0],
- [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
- DIR into the resulting binary and the resulting library dependency is
- "absolute", i.e impossible to change by setting ${shlibpath_var} if the
- library is relocated])
-_LT_TAGDECL([], [hardcode_minus_L], [0],
- [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
- into the resulting binary])
-_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
- [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
- into the resulting binary])
-_LT_TAGDECL([], [hardcode_automatic], [0],
- [Set to "yes" if building a shared library automatically hardcodes DIR
- into the library and all subsequent libraries and executables linked
- against it])
-_LT_TAGDECL([], [inherit_rpath], [0],
- [Set to yes if linker adds runtime paths of dependent libraries
- to runtime path list])
-_LT_TAGDECL([], [link_all_deplibs], [0],
- [Whether libtool must link a program against all its dependency libraries])
-_LT_TAGDECL([], [fix_srcfile_path], [1],
- [Fix the shell variable $srcfile for the compiler])
-_LT_TAGDECL([], [always_export_symbols], [0],
- [Set to "yes" if exported symbols are required])
-_LT_TAGDECL([], [export_symbols_cmds], [2],
- [The commands to list exported symbols])
-_LT_TAGDECL([], [exclude_expsyms], [1],
- [Symbols that should not be listed in the preloaded symbols])
-_LT_TAGDECL([], [include_expsyms], [1],
- [Symbols that must always be exported])
-_LT_TAGDECL([], [prelink_cmds], [2],
- [Commands necessary for linking programs (against libraries) with templates])
-_LT_TAGDECL([], [file_list_spec], [1],
- [Specify filename containing input files])
-dnl FIXME: Not yet implemented
-dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
-dnl [Compiler flag to generate thread safe objects])
-])# _LT_LINKER_SHLIBS
-
-
-# _LT_LANG_C_CONFIG([TAG])
-# ------------------------
-# Ensure that the configuration variables for a C compiler are suitably
-# defined. These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_C_CONFIG],
-[m4_require([_LT_DECL_EGREP])dnl
-lt_save_CC="$CC"
-AC_LANG_PUSH(C)
-
-# Source file extension for C test sources.
-ac_ext=c
-
-# Object file extension for compiled C test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}'
-
-_LT_TAG_COMPILER
-# Save the default compiler, since it gets overwritten when the other
-# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
-compiler_DEFAULT=$CC
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-if test -n "$compiler"; then
- _LT_COMPILER_NO_RTTI($1)
- _LT_COMPILER_PIC($1)
- _LT_COMPILER_C_O($1)
- _LT_COMPILER_FILE_LOCKS($1)
- _LT_LINKER_SHLIBS($1)
- _LT_SYS_DYNAMIC_LINKER($1)
- _LT_LINKER_HARDCODE_LIBPATH($1)
- LT_SYS_DLOPEN_SELF
- _LT_CMD_STRIPLIB
-
- # Report which library types will actually be built
- AC_MSG_CHECKING([if libtool supports shared libraries])
- AC_MSG_RESULT([$can_build_shared])
-
- AC_MSG_CHECKING([whether to build shared libraries])
- test "$can_build_shared" = "no" && enable_shared=no
-
- # On AIX, shared libraries and static libraries use the same namespace, and
- # are all built from PIC.
- case $host_os in
- aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-
- aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
- esac
- AC_MSG_RESULT([$enable_shared])
-
- AC_MSG_CHECKING([whether to build static libraries])
- # Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
- AC_MSG_RESULT([$enable_static])
-
- _LT_CONFIG($1)
-fi
-AC_LANG_POP
-CC="$lt_save_CC"
-])# _LT_LANG_C_CONFIG
-
-
-# _LT_PROG_CXX
-# ------------
-# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
-# compiler, we have our own version here.
-m4_defun([_LT_PROG_CXX],
-[
-pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
-AC_PROG_CXX
-if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- AC_PROG_CXXCPP
-else
- _lt_caught_CXX_error=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_CXX
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_CXX], [])
-
-
-# _LT_LANG_CXX_CONFIG([TAG])
-# --------------------------
-# Ensure that the configuration variables for a C++ compiler are suitably
-# defined. These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_CXX_CONFIG],
-[AC_REQUIRE([_LT_PROG_CXX])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_DECL_EGREP])dnl
-
-AC_LANG_PUSH(C++)
-_LT_TAGVAR(archive_cmds_need_lc, $1)=no
-_LT_TAGVAR(allow_undefined_flag, $1)=
-_LT_TAGVAR(always_export_symbols, $1)=no
-_LT_TAGVAR(archive_expsym_cmds, $1)=
-_LT_TAGVAR(compiler_needs_object, $1)=no
-_LT_TAGVAR(export_dynamic_flag_spec, $1)=
-_LT_TAGVAR(hardcode_direct, $1)=no
-_LT_TAGVAR(hardcode_direct_absolute, $1)=no
-_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
-_LT_TAGVAR(hardcode_libdir_separator, $1)=
-_LT_TAGVAR(hardcode_minus_L, $1)=no
-_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-_LT_TAGVAR(hardcode_automatic, $1)=no
-_LT_TAGVAR(inherit_rpath, $1)=no
-_LT_TAGVAR(module_cmds, $1)=
-_LT_TAGVAR(module_expsym_cmds, $1)=
-_LT_TAGVAR(link_all_deplibs, $1)=unknown
-_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-_LT_TAGVAR(no_undefined_flag, $1)=
-_LT_TAGVAR(whole_archive_flag_spec, $1)=
-_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
-
-# Source file extension for C++ test sources.
-ac_ext=cpp
-
-# Object file extension for compiled C++ test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# No sense in running all these tests if we already determined that
-# the CXX compiler isn't working. Some variables (like enable_shared)
-# are currently assumed to apply to all compilers on this platform,
-# and will be corrupted by setting them based on a non-working compiler.
-if test "$_lt_caught_CXX_error" != yes; then
- # Code to be used in simple compile tests
- lt_simple_compile_test_code="int some_variable = 0;"
-
- # Code to be used in simple link tests
- lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
-
- # ltmain only uses $CC for tagged configurations so make sure $CC is set.
- _LT_TAG_COMPILER
-
- # save warnings/boilerplate of simple test code
- _LT_COMPILER_BOILERPLATE
- _LT_LINKER_BOILERPLATE
-
- # Allow CC to be a program name with arguments.
- lt_save_CC=$CC
- lt_save_LD=$LD
- lt_save_GCC=$GCC
- GCC=$GXX
- lt_save_with_gnu_ld=$with_gnu_ld
- lt_save_path_LD=$lt_cv_path_LD
- if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
- lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
- else
- $as_unset lt_cv_prog_gnu_ld
- fi
- if test -n "${lt_cv_path_LDCXX+set}"; then
- lt_cv_path_LD=$lt_cv_path_LDCXX
- else
- $as_unset lt_cv_path_LD
- fi
- test -z "${LDCXX+set}" || LD=$LDCXX
- CC=${CXX-"c++"}
- compiler=$CC
- _LT_TAGVAR(compiler, $1)=$CC
- _LT_CC_BASENAME([$compiler])
-
- if test -n "$compiler"; then
- # We don't want -fno-exception when compiling C++ code, so set the
- # no_builtin_flag separately
- if test "$GXX" = yes; then
- _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
- else
- _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
- fi
-
- if test "$GXX" = yes; then
- # Set up default GNU C++ configuration
-
- LT_PATH_LD
-
- # Check if GNU C++ uses GNU ld as the underlying linker, since the
- # archiving commands below assume that GNU ld is being used.
- if test "$with_gnu_ld" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-
- # If archive_cmds runs LD, not CC, wlarc should be empty
- # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
- # investigate it a little bit more. (MM)
- wlarc='${wl}'
-
- # ancient GNU ld didn't support --whole-archive et. al.
- if eval "`$CC -print-prog-name=ld` --help 2>&1" |
- $GREP 'no-whole-archive' > /dev/null; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- _LT_TAGVAR(whole_archive_flag_spec, $1)=
- fi
- else
- with_gnu_ld=no
- wlarc=
-
- # A generic and very simple default shared library creation
- # command for GNU C++ for the case where it uses the native
- # linker, instead of GNU ld. If possible, this setting should
- # overridden to take advantage of the native linker features on
- # the platform it is being used on.
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- fi
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
-
- else
- GXX=no
- with_gnu_ld=no
- wlarc=
- fi
-
- # PORTME: fill in a description of your system's C++ link characteristics
- AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
- _LT_TAGVAR(ld_shlibs, $1)=yes
- case $host_os in
- aix3*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- aix[[4-9]]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
- for ld_flag in $LDFLAGS; do
- case $ld_flag in
- *-brtl*)
- aix_use_runtimelinking=yes
- break
- ;;
- esac
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- _LT_TAGVAR(archive_cmds, $1)=''
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
-
- if test "$GXX" = yes; then
- case $host_os in aix4.[[012]]|aix4.[[012]].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" &&
- strings "$collect2name" | $GREP resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- _LT_TAGVAR(hardcode_direct, $1)=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=
- fi
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to
- # export.
- _LT_TAGVAR(always_export_symbols, $1)=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
- # Determine the default libpath from the value encoded in an empty
- # executable.
- _LT_SYS_MODULE_PATH_AIX
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
-
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
- _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an
- # empty executable.
- _LT_SYS_MODULE_PATH_AIX
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds its shared
- # libraries.
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- beos*)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- chorus*)
- case $cc_basename in
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
- # as there is no search path for DLLs.
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(always_export_symbols, $1)=no
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-
- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- darwin* | rhapsody*)
- _LT_DARWIN_LINKER_FEATURES($1)
- ;;
-
- dgux*)
- case $cc_basename in
- ec++*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- freebsd[[12]]*)
- # C++ shared libraries reported to be fairly broken before
- # switch to ELF
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- freebsd-elf*)
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- ;;
-
- freebsd* | dragonfly*)
- # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
- # conventions
- _LT_TAGVAR(ld_shlibs, $1)=yes
- ;;
-
- gnu*)
- ;;
-
- hpux9*)
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
- # but as the default
- # location of the library.
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- aCC*)
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
- ;;
- *)
- if test "$GXX" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
-
- hpux10*|hpux11*)
- if test $with_gnu_ld = no; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- ;;
- *)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- ;;
- esac
- fi
- case $host_cpu in
- hppa*64*|ia64*)
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
- *)
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
- # but as the default
- # location of the library.
- ;;
- esac
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- aCC*)
- case $host_cpu in
- hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
- ;;
- *)
- if test "$GXX" = yes; then
- if test $with_gnu_ld = no; then
- case $host_cpu in
- hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- fi
- else
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
-
- interix[[3-9]]*)
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
- irix5* | irix6*)
- case $cc_basename in
- CC*)
- # SGI C++
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
-
- # Archives containing C++ object files must be created using
- # "CC -ar", where "CC" is the IRIX C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
- ;;
- *)
- if test "$GXX" = yes; then
- if test "$with_gnu_ld" = no; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
- fi
- fi
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- ;;
- esac
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(inherit_rpath, $1)=yes
- ;;
-
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-
- # Archives containing C++ object files must be created using
- # "CC -Bstatic", where "CC" is the KAI C++ compiler.
- _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
- ;;
- icpc* | ecpc* )
- # Intel C++
- with_gnu_ld=yes
- # version 8.0 and above of icpc choke on multiply defined symbols
- # if we add $predep_objects and $postdep_objects, however 7.1 and
- # earlier do not add the objects themselves.
- case `$CC -V 2>&1` in
- *"Version 7."*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- *) # Version 8.0 or newer
- tmp_idyn=
- case $host_cpu in
- ia64*) tmp_idyn=' -i_dynamic';;
- esac
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- esac
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
- ;;
- pgCC* | pgcpp*)
- # Portland Group C++ compiler
- case `$CC -V` in
- *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
- _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
- compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
- _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
- $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
- $RANLIB $oldlib'
- _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
- ;;
- *) # Version 6 will use weak symbols
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
- ;;
- esac
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- ;;
- cxx*)
- # Compaq C++
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
-
- runpath_var=LD_RUN_PATH
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
- ;;
- xl*)
- # IBM XL 8.0 on PPC, with GNU ld
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- _LT_TAGVAR(compiler_needs_object, $1)=yes
-
- # Not sure whether something based on
- # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
- # would be better.
- output_verbose_link_cmd='echo'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
- ;;
- esac
- ;;
- esac
- ;;
-
- lynxos*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- m88k*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- mvs*)
- case $cc_basename in
- cxx*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
- wlarc=
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- fi
- # Workaround some broken pre-1.5 toolchains
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
- ;;
-
- *nto* | *qnx*)
- _LT_TAGVAR(ld_shlibs, $1)=yes
- ;;
-
- openbsd2*)
- # C++ shared libraries are fairly broken
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- fi
- output_verbose_link_cmd=echo
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- osf3* | osf4* | osf5*)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Archives containing C++ object files must be created using
- # the KAI C++ compiler.
- case $host in
- osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
- *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
- esac
- ;;
- RCC*)
- # Rational C++ 2.4.1
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- cxx*)
- case $host in
- osf3*)
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- ;;
- *)
- _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
- echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
- $RM $lib.exp'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
- ;;
- esac
-
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
- ;;
- *)
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- case $host in
- osf3*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- ;;
- esac
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
-
- else
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
-
- psos*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- lcc*)
- # Lucid
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
- _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- case $host_os in
- solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
- ;;
- esac
- _LT_TAGVAR(link_all_deplibs, $1)=yes
-
- output_verbose_link_cmd='echo'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
- ;;
- gcx*)
- # Green Hills C++ Compiler
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
-
- # The C++ compiler must be used to create the archive.
- _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
- ;;
- *)
- # GNU C++ compiler with Solaris linker
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
- if $CC --version | $GREP -v '^2\.7' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
- else
- # g++ 2.7 appears to require `-G' NOT `-shared' on this
- # platform.
- _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
- fi
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
- case $host_os in
- solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *)
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- ;;
- esac
- fi
- ;;
- esac
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
-
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- vxworks*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
-
- AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
- test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
-
- _LT_TAGVAR(GCC, $1)="$GXX"
- _LT_TAGVAR(LD, $1)="$LD"
-
- ## CAVEAT EMPTOR:
- ## There is no encapsulation within the following macros, do not change
- ## the running order or otherwise move them around unless you know exactly
- ## what you are doing...
- _LT_SYS_HIDDEN_LIBDEPS($1)
- _LT_COMPILER_PIC($1)
- _LT_COMPILER_C_O($1)
- _LT_COMPILER_FILE_LOCKS($1)
- _LT_LINKER_SHLIBS($1)
- _LT_SYS_DYNAMIC_LINKER($1)
- _LT_LINKER_HARDCODE_LIBPATH($1)
-
- _LT_CONFIG($1)
- fi # test -n "$compiler"
-
- CC=$lt_save_CC
- LDCXX=$LD
- LD=$lt_save_LD
- GCC=$lt_save_GCC
- with_gnu_ld=$lt_save_with_gnu_ld
- lt_cv_path_LDCXX=$lt_cv_path_LD
- lt_cv_path_LD=$lt_save_path_LD
- lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
- lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test "$_lt_caught_CXX_error" != yes
-
-AC_LANG_POP
-])# _LT_LANG_CXX_CONFIG
-
-
-# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
-# ---------------------------------
-# Figure out "hidden" library dependencies from verbose
-# compiler output when linking a shared library.
-# Parse the compiler output and extract the necessary
-# objects, libraries and library flags.
-m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
-[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-# Dependencies to place before and after the object being linked:
-_LT_TAGVAR(predep_objects, $1)=
-_LT_TAGVAR(postdep_objects, $1)=
-_LT_TAGVAR(predeps, $1)=
-_LT_TAGVAR(postdeps, $1)=
-_LT_TAGVAR(compiler_lib_search_path, $1)=
-
-dnl we can't use the lt_simple_compile_test_code here,
-dnl because it contains code intended for an executable,
-dnl not a library. It's possible we should let each
-dnl tag define a new lt_????_link_test_code variable,
-dnl but it's only used here...
-m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
-int a;
-void foo (void) { a = 0; }
-_LT_EOF
-], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
-class Foo
-{
-public:
- Foo (void) { a = 0; }
-private:
- int a;
-};
-_LT_EOF
-], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
- subroutine foo
- implicit none
- integer*4 a
- a=0
- return
- end
-_LT_EOF
-], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
- subroutine foo
- implicit none
- integer a
- a=0
- return
- end
-_LT_EOF
-], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
-public class foo {
- private int a;
- public void bar (void) {
- a = 0;
- }
-};
-_LT_EOF
-])
-dnl Parse the compiler output and extract the necessary
-dnl objects, libraries and library flags.
-if AC_TRY_EVAL(ac_compile); then
- # Parse the compiler output and extract the necessary
- # objects, libraries and library flags.
-
- # Sentinel used to keep track of whether or not we are before
- # the conftest object file.
- pre_test_object_deps_done=no
-
- for p in `eval "$output_verbose_link_cmd"`; do
- case $p in
-
- -L* | -R* | -l*)
- # Some compilers place space between "-{L,R}" and the path.
- # Remove the space.
- if test $p = "-L" ||
- test $p = "-R"; then
- prev=$p
- continue
- else
- prev=
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- case $p in
- -L* | -R*)
- # Internal compiler library paths should come after those
- # provided the user. The postdeps already come after the
- # user supplied libs so there is no need to process them.
- if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
- _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
- else
- _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
- fi
- ;;
- # The "-l" case would never come before the object being
- # linked, so don't bother handling this case.
- esac
- else
- if test -z "$_LT_TAGVAR(postdeps, $1)"; then
- _LT_TAGVAR(postdeps, $1)="${prev}${p}"
- else
- _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
- fi
- fi
- ;;
-
- *.$objext)
- # This assumes that the test object file only shows up
- # once in the compiler output.
- if test "$p" = "conftest.$objext"; then
- pre_test_object_deps_done=yes
- continue
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
- _LT_TAGVAR(predep_objects, $1)="$p"
- else
- _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
- fi
- else
- if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
- _LT_TAGVAR(postdep_objects, $1)="$p"
- else
- _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
- fi
- fi
- ;;
-
- *) ;; # Ignore the rest.
-
- esac
- done
-
- # Clean up.
- rm -f a.out a.exe
-else
- echo "libtool.m4: error: problem compiling $1 test program"
-fi
-
-$RM -f confest.$objext
-
-# PORTME: override above test on systems where it is broken
-m4_if([$1], [CXX],
-[case $host_os in
-interix[[3-9]]*)
- # Interix 3.5 installs completely hosed .la files for C++, so rather than
- # hack all around it, let's just trust "g++" to DTRT.
- _LT_TAGVAR(predep_objects,$1)=
- _LT_TAGVAR(postdep_objects,$1)=
- _LT_TAGVAR(postdeps,$1)=
- ;;
-
-linux*)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
-
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
-
- if test "$solaris_use_stlport4" != yes; then
- _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-
-solaris*)
- case $cc_basename in
- CC*)
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
-
- # Adding this requires a known-good setup of shared libraries for
- # Sun compiler versions before 5.6, else PIC objects from an old
- # archive will be linked into the output, leading to subtle bugs.
- if test "$solaris_use_stlport4" != yes; then
- _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-esac
-])
-
-case " $_LT_TAGVAR(postdeps, $1) " in
-*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
-esac
- _LT_TAGVAR(compiler_lib_search_dirs, $1)=
-if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
- _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
-fi
-_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
- [The directories searched by this compiler when creating a shared library])
-_LT_TAGDECL([], [predep_objects], [1],
- [Dependencies to place before and after the objects being linked to
- create a shared library])
-_LT_TAGDECL([], [postdep_objects], [1])
-_LT_TAGDECL([], [predeps], [1])
-_LT_TAGDECL([], [postdeps], [1])
-_LT_TAGDECL([], [compiler_lib_search_path], [1],
- [The library search path used internally by the compiler when linking
- a shared library])
-])# _LT_SYS_HIDDEN_LIBDEPS
-
-
-# _LT_PROG_F77
-# ------------
-# Since AC_PROG_F77 is broken, in that it returns the empty string
-# if there is no fortran compiler, we have our own version here.
-m4_defun([_LT_PROG_F77],
-[
-pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
-AC_PROG_F77
-if test -z "$F77" || test "X$F77" = "Xno"; then
- _lt_disable_F77=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_F77
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_F77], [])
-
-
-# _LT_LANG_F77_CONFIG([TAG])
-# --------------------------
-# Ensure that the configuration variables for a Fortran 77 compiler are
-# suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_F77_CONFIG],
-[AC_REQUIRE([_LT_PROG_F77])dnl
-AC_LANG_PUSH(Fortran 77)
-
-_LT_TAGVAR(archive_cmds_need_lc, $1)=no
-_LT_TAGVAR(allow_undefined_flag, $1)=
-_LT_TAGVAR(always_export_symbols, $1)=no
-_LT_TAGVAR(archive_expsym_cmds, $1)=
-_LT_TAGVAR(export_dynamic_flag_spec, $1)=
-_LT_TAGVAR(hardcode_direct, $1)=no
-_LT_TAGVAR(hardcode_direct_absolute, $1)=no
-_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
-_LT_TAGVAR(hardcode_libdir_separator, $1)=
-_LT_TAGVAR(hardcode_minus_L, $1)=no
-_LT_TAGVAR(hardcode_automatic, $1)=no
-_LT_TAGVAR(inherit_rpath, $1)=no
-_LT_TAGVAR(module_cmds, $1)=
-_LT_TAGVAR(module_expsym_cmds, $1)=
-_LT_TAGVAR(link_all_deplibs, $1)=unknown
-_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-_LT_TAGVAR(no_undefined_flag, $1)=
-_LT_TAGVAR(whole_archive_flag_spec, $1)=
-_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
-
-# Source file extension for f77 test sources.
-ac_ext=f
-
-# Object file extension for compiled f77 test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# No sense in running all these tests if we already determined that
-# the F77 compiler isn't working. Some variables (like enable_shared)
-# are currently assumed to apply to all compilers on this platform,
-# and will be corrupted by setting them based on a non-working compiler.
-if test "$_lt_disable_F77" != yes; then
- # Code to be used in simple compile tests
- lt_simple_compile_test_code="\
- subroutine t
- return
- end
-"
-
- # Code to be used in simple link tests
- lt_simple_link_test_code="\
- program t
- end
-"
-
- # ltmain only uses $CC for tagged configurations so make sure $CC is set.
- _LT_TAG_COMPILER
-
- # save warnings/boilerplate of simple test code
- _LT_COMPILER_BOILERPLATE
- _LT_LINKER_BOILERPLATE
-
- # Allow CC to be a program name with arguments.
- lt_save_CC="$CC"
- lt_save_GCC=$GCC
- CC=${F77-"f77"}
- compiler=$CC
- _LT_TAGVAR(compiler, $1)=$CC
- _LT_CC_BASENAME([$compiler])
- GCC=$G77
- if test -n "$compiler"; then
- AC_MSG_CHECKING([if libtool supports shared libraries])
- AC_MSG_RESULT([$can_build_shared])
-
- AC_MSG_CHECKING([whether to build shared libraries])
- test "$can_build_shared" = "no" && enable_shared=no
-
- # On AIX, shared libraries and static libraries use the same namespace, and
- # are all built from PIC.
- case $host_os in
- aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
- aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
- esac
- AC_MSG_RESULT([$enable_shared])
-
- AC_MSG_CHECKING([whether to build static libraries])
- # Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
- AC_MSG_RESULT([$enable_static])
-
- _LT_TAGVAR(GCC, $1)="$G77"
- _LT_TAGVAR(LD, $1)="$LD"
-
- ## CAVEAT EMPTOR:
- ## There is no encapsulation within the following macros, do not change
- ## the running order or otherwise move them around unless you know exactly
- ## what you are doing...
- _LT_COMPILER_PIC($1)
- _LT_COMPILER_C_O($1)
- _LT_COMPILER_FILE_LOCKS($1)
- _LT_LINKER_SHLIBS($1)
- _LT_SYS_DYNAMIC_LINKER($1)
- _LT_LINKER_HARDCODE_LIBPATH($1)
-
- _LT_CONFIG($1)
- fi # test -n "$compiler"
-
- GCC=$lt_save_GCC
- CC="$lt_save_CC"
-fi # test "$_lt_disable_F77" != yes
-
-AC_LANG_POP
-])# _LT_LANG_F77_CONFIG
-
-
-# _LT_PROG_FC
-# -----------
-# Since AC_PROG_FC is broken, in that it returns the empty string
-# if there is no fortran compiler, we have our own version here.
-m4_defun([_LT_PROG_FC],
-[
-pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
-AC_PROG_FC
-if test -z "$FC" || test "X$FC" = "Xno"; then
- _lt_disable_FC=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_FC
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_FC], [])
-
-
-# _LT_LANG_FC_CONFIG([TAG])
-# -------------------------
-# Ensure that the configuration variables for a Fortran compiler are
-# suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_FC_CONFIG],
-[AC_REQUIRE([_LT_PROG_FC])dnl
-AC_LANG_PUSH(Fortran)
-
-_LT_TAGVAR(archive_cmds_need_lc, $1)=no
-_LT_TAGVAR(allow_undefined_flag, $1)=
-_LT_TAGVAR(always_export_symbols, $1)=no
-_LT_TAGVAR(archive_expsym_cmds, $1)=
-_LT_TAGVAR(export_dynamic_flag_spec, $1)=
-_LT_TAGVAR(hardcode_direct, $1)=no
-_LT_TAGVAR(hardcode_direct_absolute, $1)=no
-_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
-_LT_TAGVAR(hardcode_libdir_separator, $1)=
-_LT_TAGVAR(hardcode_minus_L, $1)=no
-_LT_TAGVAR(hardcode_automatic, $1)=no
-_LT_TAGVAR(inherit_rpath, $1)=no
-_LT_TAGVAR(module_cmds, $1)=
-_LT_TAGVAR(module_expsym_cmds, $1)=
-_LT_TAGVAR(link_all_deplibs, $1)=unknown
-_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-_LT_TAGVAR(no_undefined_flag, $1)=
-_LT_TAGVAR(whole_archive_flag_spec, $1)=
-_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
-
-# Source file extension for fc test sources.
-ac_ext=${ac_fc_srcext-f}
-
-# Object file extension for compiled fc test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# No sense in running all these tests if we already determined that
-# the FC compiler isn't working. Some variables (like enable_shared)
-# are currently assumed to apply to all compilers on this platform,
-# and will be corrupted by setting them based on a non-working compiler.
-if test "$_lt_disable_FC" != yes; then
- # Code to be used in simple compile tests
- lt_simple_compile_test_code="\
- subroutine t
- return
- end
-"
-
- # Code to be used in simple link tests
- lt_simple_link_test_code="\
- program t
- end
-"
-
- # ltmain only uses $CC for tagged configurations so make sure $CC is set.
- _LT_TAG_COMPILER
-
- # save warnings/boilerplate of simple test code
- _LT_COMPILER_BOILERPLATE
- _LT_LINKER_BOILERPLATE
-
- # Allow CC to be a program name with arguments.
- lt_save_CC="$CC"
- lt_save_GCC=$GCC
- CC=${FC-"f95"}
- compiler=$CC
- GCC=$ac_cv_fc_compiler_gnu
-
- _LT_TAGVAR(compiler, $1)=$CC
- _LT_CC_BASENAME([$compiler])
-
- if test -n "$compiler"; then
- AC_MSG_CHECKING([if libtool supports shared libraries])
- AC_MSG_RESULT([$can_build_shared])
-
- AC_MSG_CHECKING([whether to build shared libraries])
- test "$can_build_shared" = "no" && enable_shared=no
-
- # On AIX, shared libraries and static libraries use the same namespace, and
- # are all built from PIC.
- case $host_os in
- aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
- aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
- esac
- AC_MSG_RESULT([$enable_shared])
-
- AC_MSG_CHECKING([whether to build static libraries])
- # Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
- AC_MSG_RESULT([$enable_static])
-
- _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
- _LT_TAGVAR(LD, $1)="$LD"
-
- ## CAVEAT EMPTOR:
- ## There is no encapsulation within the following macros, do not change
- ## the running order or otherwise move them around unless you know exactly
- ## what you are doing...
- _LT_SYS_HIDDEN_LIBDEPS($1)
- _LT_COMPILER_PIC($1)
- _LT_COMPILER_C_O($1)
- _LT_COMPILER_FILE_LOCKS($1)
- _LT_LINKER_SHLIBS($1)
- _LT_SYS_DYNAMIC_LINKER($1)
- _LT_LINKER_HARDCODE_LIBPATH($1)
-
- _LT_CONFIG($1)
- fi # test -n "$compiler"
-
- GCC=$lt_save_GCC
- CC="$lt_save_CC"
-fi # test "$_lt_disable_FC" != yes
-
-AC_LANG_POP
-])# _LT_LANG_FC_CONFIG
-
-
-# _LT_LANG_GCJ_CONFIG([TAG])
-# --------------------------
-# Ensure that the configuration variables for the GNU Java Compiler compiler
-# are suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_GCJ_CONFIG],
-[AC_REQUIRE([LT_PROG_GCJ])dnl
-AC_LANG_SAVE
-
-# Source file extension for Java test sources.
-ac_ext=java
-
-# Object file extension for compiled Java test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="class foo {}"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-_LT_TAG_COMPILER
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-lt_save_GCC=$GCC
-GCC=yes
-CC=${GCJ-"gcj"}
-compiler=$CC
-_LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)="$LD"
-_LT_CC_BASENAME([$compiler])
-
-# GCJ did not exist at the time GCC didn't implicitly link libc in.
-_LT_TAGVAR(archive_cmds_need_lc, $1)=no
-
-_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-
-if test -n "$compiler"; then
- _LT_COMPILER_NO_RTTI($1)
- _LT_COMPILER_PIC($1)
- _LT_COMPILER_C_O($1)
- _LT_COMPILER_FILE_LOCKS($1)
- _LT_LINKER_SHLIBS($1)
- _LT_LINKER_HARDCODE_LIBPATH($1)
-
- _LT_CONFIG($1)
-fi
-
-AC_LANG_RESTORE
-
-GCC=$lt_save_GCC
-CC="$lt_save_CC"
-])# _LT_LANG_GCJ_CONFIG
-
-
-# _LT_LANG_RC_CONFIG([TAG])
-# -------------------------
-# Ensure that the configuration variables for the Windows resource compiler
-# are suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_RC_CONFIG],
-[AC_REQUIRE([LT_PROG_RC])dnl
-AC_LANG_SAVE
-
-# Source file extension for RC test sources.
-ac_ext=rc
-
-# Object file extension for compiled RC test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
-
-# Code to be used in simple link tests
-lt_simple_link_test_code="$lt_simple_compile_test_code"
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-_LT_TAG_COMPILER
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-lt_save_GCC=$GCC
-GCC=
-CC=${RC-"windres"}
-compiler=$CC
-_LT_TAGVAR(compiler, $1)=$CC
-_LT_CC_BASENAME([$compiler])
-_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
-
-if test -n "$compiler"; then
- :
- _LT_CONFIG($1)
-fi
-
-GCC=$lt_save_GCC
-AC_LANG_RESTORE
-CC="$lt_save_CC"
-])# _LT_LANG_RC_CONFIG
-
-
-# LT_PROG_GCJ
-# -----------
-AC_DEFUN([LT_PROG_GCJ],
-[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
- [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
- [AC_CHECK_TOOL(GCJ, gcj,)
- test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
- AC_SUBST(GCJFLAGS)])])[]dnl
-])
-
-# Old name:
-AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
-
-
-# LT_PROG_RC
-# ----------
-AC_DEFUN([LT_PROG_RC],
-[AC_CHECK_TOOL(RC, windres,)
-])
-
-# Old name:
-AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([LT_AC_PROG_RC], [])
-
-
-# _LT_DECL_EGREP
-# --------------
-# If we don't have a new enough Autoconf to choose the best grep
-# available, choose the one first in the user's PATH.
-m4_defun([_LT_DECL_EGREP],
-[AC_REQUIRE([AC_PROG_EGREP])dnl
-AC_REQUIRE([AC_PROG_FGREP])dnl
-test -z "$GREP" && GREP=grep
-_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
-_LT_DECL([], [EGREP], [1], [An ERE matcher])
-_LT_DECL([], [FGREP], [1], [A literal string matcher])
-dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
-AC_SUBST([GREP])
-])
-
-
-# _LT_DECL_OBJDUMP
-# --------------
-# If we don't have a new enough Autoconf to choose the best objdump
-# available, choose the one first in the user's PATH.
-m4_defun([_LT_DECL_OBJDUMP],
-[AC_CHECK_TOOL(OBJDUMP, objdump, false)
-test -z "$OBJDUMP" && OBJDUMP=objdump
-_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
-AC_SUBST([OBJDUMP])
-])
-
-
-# _LT_DECL_SED
-# ------------
-# Check for a fully-functional sed program, that truncates
-# as few characters as possible. Prefer GNU sed if found.
-m4_defun([_LT_DECL_SED],
-[AC_PROG_SED
-test -z "$SED" && SED=sed
-Xsed="$SED -e 1s/^X//"
-_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
-_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
- [Sed that helps us avoid accidentally triggering echo(1) options like -n])
-])# _LT_DECL_SED
-
-m4_ifndef([AC_PROG_SED], [
-# NOTE: This macro has been submitted for inclusion into #
-# GNU Autoconf as AC_PROG_SED. When it is available in #
-# a released version of Autoconf we should remove this #
-# macro and use it instead. #
-
-m4_defun([AC_PROG_SED],
-[AC_MSG_CHECKING([for a sed that does not truncate output])
-AC_CACHE_VAL(lt_cv_path_SED,
-[# Loop through the user's path and test for sed and gsed.
-# Then use that list of sed's as ones to test for truncation.
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for lt_ac_prog in sed gsed; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
- lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
- fi
- done
- done
-done
-IFS=$as_save_IFS
-lt_ac_max=0
-lt_ac_count=0
-# Add /usr/xpg4/bin/sed as it is typically found on Solaris
-# along with /bin/sed that truncates output.
-for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
- test ! -f $lt_ac_sed && continue
- cat /dev/null > conftest.in
- lt_ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >conftest.in
- # Check for GNU sed and select it if it is found.
- if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
- lt_cv_path_SED=$lt_ac_sed
- break
- fi
- while true; do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo >>conftest.nl
- $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
- cmp -s conftest.out conftest.nl || break
- # 10000 chars as input seems more than enough
- test $lt_ac_count -gt 10 && break
- lt_ac_count=`expr $lt_ac_count + 1`
- if test $lt_ac_count -gt $lt_ac_max; then
- lt_ac_max=$lt_ac_count
- lt_cv_path_SED=$lt_ac_sed
- fi
- done
-done
-])
-SED=$lt_cv_path_SED
-AC_SUBST([SED])
-AC_MSG_RESULT([$SED])
-])#AC_PROG_SED
-])#m4_ifndef
-
-# Old name:
-AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([LT_AC_PROG_SED], [])
-
-
-# _LT_CHECK_SHELL_FEATURES
-# ------------------------
-# Find out whether the shell is Bourne or XSI compatible,
-# or has some other useful features.
-m4_defun([_LT_CHECK_SHELL_FEATURES],
-[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
-# Try some XSI features
-xsi_shell=no
-( _lt_dummy="a/b/c"
- test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
- = c,a/b,, \
- && eval 'test $(( 1 + 1 )) -eq 2 \
- && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
- && xsi_shell=yes
-AC_MSG_RESULT([$xsi_shell])
-_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
-
-AC_MSG_CHECKING([whether the shell understands "+="])
-lt_shell_append=no
-( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
- >/dev/null 2>&1 \
- && lt_shell_append=yes
-AC_MSG_RESULT([$lt_shell_append])
-_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
-
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- lt_unset=unset
-else
- lt_unset=false
-fi
-_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
-
-# test EBCDIC or ASCII
-case `echo X|tr X '\101'` in
- A) # ASCII based system
- # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
- lt_SP2NL='tr \040 \012'
- lt_NL2SP='tr \015\012 \040\040'
- ;;
- *) # EBCDIC based system
- lt_SP2NL='tr \100 \n'
- lt_NL2SP='tr \r\n \100\100'
- ;;
-esac
-_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
-_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
-])# _LT_CHECK_SHELL_FEATURES
-
-
-# _LT_PROG_XSI_SHELLFNS
-# ---------------------
-# Bourne and XSI compatible variants of some useful shell functions.
-m4_defun([_LT_PROG_XSI_SHELLFNS],
-[case $xsi_shell in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result="${1##*/}"
-}
-
-# func_dirname_and_basename file append nondir_replacement
-# perform func_basename and func_dirname in a single function
-# call:
-# dirname: Compute the dirname of FILE. If nonempty,
-# add APPEND to the result, otherwise set result
-# to NONDIR_REPLACEMENT.
-# value returned in "$func_dirname_result"
-# basename: Compute filename of FILE.
-# value retuned in "$func_basename_result"
-# Implementation must be kept synchronized with func_dirname
-# and func_basename. For efficiency, we do not delegate to
-# those functions but instead duplicate the functionality here.
-func_dirname_and_basename ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
- func_basename_result="${1##*/}"
-}
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-func_stripname ()
-{
- # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
- # positional parameters, so assign one to ordinary parameter first.
- func_stripname_result=${3}
- func_stripname_result=${func_stripname_result#"${1}"}
- func_stripname_result=${func_stripname_result%"${2}"}
-}
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=${1%%=*}
- func_opt_split_arg=${1#*=}
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- case ${1} in
- *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
- *) func_lo2o_result=${1} ;;
- esac
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=${1%.*}.lo
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=$(( $[*] ))
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=${#1}
-}
-
-_LT_EOF
- ;;
- *) # Bourne compatible functions.
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- # Extract subdirectory from the argument.
- func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
- if test "X$func_dirname_result" = "X${1}"; then
- func_dirname_result="${3}"
- else
- func_dirname_result="$func_dirname_result${2}"
- fi
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
-}
-
-dnl func_dirname_and_basename
-dnl A portable version of this function is already defined in general.m4sh
-dnl so there is no need for it here.
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-# func_strip_suffix prefix name
-func_stripname ()
-{
- case ${2} in
- .*) func_stripname_result=`$ECHO "X${3}" \
- | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
- *) func_stripname_result=`$ECHO "X${3}" \
- | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
- esac
-}
-
-# sed scripts:
-my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
-my_sed_long_arg='1s/^-[[^=]]*=//'
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
- func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=`expr "$[@]"`
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
-}
-
-_LT_EOF
-esac
-
-case $lt_shell_append in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$[1]+=\$[2]"
-}
-_LT_EOF
- ;;
- *)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$[1]=\$$[1]\$[2]"
-}
-
-_LT_EOF
- ;;
- esac
-])
-
-# Helper functions for option handling. -*- Autoconf -*-
-#
-# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
-# Written by Gary V. Vaughan, 2004
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-
-# serial 6 ltoptions.m4
-
-# This is to help aclocal find these macros, as it can't see m4_define.
-AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
-
-
-# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
-# ------------------------------------------
-m4_define([_LT_MANGLE_OPTION],
-[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
-
-
-# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
-# ---------------------------------------
-# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
-# matching handler defined, dispatch to it. Other OPTION-NAMEs are
-# saved as a flag.
-m4_define([_LT_SET_OPTION],
-[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
-m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
- _LT_MANGLE_DEFUN([$1], [$2]),
- [m4_warning([Unknown $1 option `$2'])])[]dnl
-])
-
-
-# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
-# ------------------------------------------------------------
-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
-m4_define([_LT_IF_OPTION],
-[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
-
-
-# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
-# -------------------------------------------------------
-# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
-# are set.
-m4_define([_LT_UNLESS_OPTIONS],
-[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
- [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
- [m4_define([$0_found])])])[]dnl
-m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
-])[]dnl
-])
-
-
-# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
-# ----------------------------------------
-# OPTION-LIST is a space-separated list of Libtool options associated
-# with MACRO-NAME. If any OPTION has a matching handler declared with
-# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
-# the unknown option and exit.
-m4_defun([_LT_SET_OPTIONS],
-[# Set options
-m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
- [_LT_SET_OPTION([$1], _LT_Option)])
-
-m4_if([$1],[LT_INIT],[
- dnl
- dnl Simply set some default values (i.e off) if boolean options were not
- dnl specified:
- _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
- ])
- _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
- ])
- dnl
- dnl If no reference was made to various pairs of opposing options, then
- dnl we run the default mode handler for the pair. For example, if neither
- dnl `shared' nor `disable-shared' was passed, we enable building of shared
- dnl archives by default:
- _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
- _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
- _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
- _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
- [_LT_ENABLE_FAST_INSTALL])
- ])
-])# _LT_SET_OPTIONS
-
-
-
-# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
-# -----------------------------------------
-m4_define([_LT_MANGLE_DEFUN],
-[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
-
-
-# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
-# -----------------------------------------------
-m4_define([LT_OPTION_DEFINE],
-[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
-])# LT_OPTION_DEFINE
-
-
-# dlopen
-# ------
-LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
-])
-
-AU_DEFUN([AC_LIBTOOL_DLOPEN],
-[_LT_SET_OPTION([LT_INIT], [dlopen])
-AC_DIAGNOSE([obsolete],
-[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the `dlopen' option into LT_INIT's first parameter.])
-])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
-
-
-# win32-dll
-# ---------
-# Declare package support for building win32 dll's.
-LT_OPTION_DEFINE([LT_INIT], [win32-dll],
-[enable_win32_dll=yes
-
-case $host in
-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
- AC_CHECK_TOOL(AS, as, false)
- AC_CHECK_TOOL(DLLTOOL, dlltool, false)
- AC_CHECK_TOOL(OBJDUMP, objdump, false)
- ;;
-esac
-
-test -z "$AS" && AS=as
-_LT_DECL([], [AS], [0], [Assembler program])dnl
-
-test -z "$DLLTOOL" && DLLTOOL=dlltool
-_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
-
-test -z "$OBJDUMP" && OBJDUMP=objdump
-_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
-])# win32-dll
-
-AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-_LT_SET_OPTION([LT_INIT], [win32-dll])
-AC_DIAGNOSE([obsolete],
-[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the `win32-dll' option into LT_INIT's first parameter.])
-])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
-
-
-# _LT_ENABLE_SHARED([DEFAULT])
-# ----------------------------
-# implement the --enable-shared flag, and supports the `shared' and
-# `disable-shared' LT_INIT options.
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
-m4_define([_LT_ENABLE_SHARED],
-[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
-AC_ARG_ENABLE([shared],
- [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
- [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
- [p=${PACKAGE-default}
- case $enableval in
- yes) enable_shared=yes ;;
- no) enable_shared=no ;;
- *)
- enable_shared=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_shared=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac],
- [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
-
- _LT_DECL([build_libtool_libs], [enable_shared], [0],
- [Whether or not to build shared libraries])
-])# _LT_ENABLE_SHARED
-
-LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
-LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
-
-# Old names:
-AC_DEFUN([AC_ENABLE_SHARED],
-[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
-])
-
-AC_DEFUN([AC_DISABLE_SHARED],
-[_LT_SET_OPTION([LT_INIT], [disable-shared])
-])
-
-AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
-AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AM_ENABLE_SHARED], [])
-dnl AC_DEFUN([AM_DISABLE_SHARED], [])
-
-
-
-# _LT_ENABLE_STATIC([DEFAULT])
-# ----------------------------
-# implement the --enable-static flag, and support the `static' and
-# `disable-static' LT_INIT options.
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
-m4_define([_LT_ENABLE_STATIC],
-[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
-AC_ARG_ENABLE([static],
- [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
- [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
- [p=${PACKAGE-default}
- case $enableval in
- yes) enable_static=yes ;;
- no) enable_static=no ;;
- *)
- enable_static=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_static=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac],
- [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
-
- _LT_DECL([build_old_libs], [enable_static], [0],
- [Whether or not to build static libraries])
-])# _LT_ENABLE_STATIC
-
-LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
-LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
-
-# Old names:
-AC_DEFUN([AC_ENABLE_STATIC],
-[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
-])
-
-AC_DEFUN([AC_DISABLE_STATIC],
-[_LT_SET_OPTION([LT_INIT], [disable-static])
-])
-
-AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
-AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AM_ENABLE_STATIC], [])
-dnl AC_DEFUN([AM_DISABLE_STATIC], [])
-
-
-
-# _LT_ENABLE_FAST_INSTALL([DEFAULT])
-# ----------------------------------
-# implement the --enable-fast-install flag, and support the `fast-install'
-# and `disable-fast-install' LT_INIT options.
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
-m4_define([_LT_ENABLE_FAST_INSTALL],
-[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
-AC_ARG_ENABLE([fast-install],
- [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
- [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
- [p=${PACKAGE-default}
- case $enableval in
- yes) enable_fast_install=yes ;;
- no) enable_fast_install=no ;;
- *)
- enable_fast_install=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_fast_install=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac],
- [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
-
-_LT_DECL([fast_install], [enable_fast_install], [0],
- [Whether or not to optimize for fast installation])dnl
-])# _LT_ENABLE_FAST_INSTALL
-
-LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
-LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
-
-# Old names:
-AU_DEFUN([AC_ENABLE_FAST_INSTALL],
-[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
-AC_DIAGNOSE([obsolete],
-[$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the `fast-install' option into LT_INIT's first parameter.])
-])
-
-AU_DEFUN([AC_DISABLE_FAST_INSTALL],
-[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
-AC_DIAGNOSE([obsolete],
-[$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the `disable-fast-install' option into LT_INIT's first parameter.])
-])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
-dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
-
-
-# _LT_WITH_PIC([MODE])
-# --------------------
-# implement the --with-pic flag, and support the `pic-only' and `no-pic'
-# LT_INIT options.
-# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
-m4_define([_LT_WITH_PIC],
-[AC_ARG_WITH([pic],
- [AS_HELP_STRING([--with-pic],
- [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
- [pic_mode="$withval"],
- [pic_mode=default])
-
-test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
-
-_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
-])# _LT_WITH_PIC
-
-LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
-LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
-
-# Old name:
-AU_DEFUN([AC_LIBTOOL_PICMODE],
-[_LT_SET_OPTION([LT_INIT], [pic-only])
-AC_DIAGNOSE([obsolete],
-[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the `pic-only' option into LT_INIT's first parameter.])
-])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
-
-
-m4_define([_LTDL_MODE], [])
-LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
- [m4_define([_LTDL_MODE], [nonrecursive])])
-LT_OPTION_DEFINE([LTDL_INIT], [recursive],
- [m4_define([_LTDL_MODE], [recursive])])
-LT_OPTION_DEFINE([LTDL_INIT], [subproject],
- [m4_define([_LTDL_MODE], [subproject])])
-
-m4_define([_LTDL_TYPE], [])
-LT_OPTION_DEFINE([LTDL_INIT], [installable],
- [m4_define([_LTDL_TYPE], [installable])])
-LT_OPTION_DEFINE([LTDL_INIT], [convenience],
- [m4_define([_LTDL_TYPE], [convenience])])
-
-# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
-#
-# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
-# Written by Gary V. Vaughan, 2004
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-
-# serial 6 ltsugar.m4
-
-# This is to help aclocal find these macros, as it can't see m4_define.
-AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
-
-
-# lt_join(SEP, ARG1, [ARG2...])
-# -----------------------------
-# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
-# associated separator.
-# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
-# versions in m4sugar had bugs.
-m4_define([lt_join],
-[m4_if([$#], [1], [],
- [$#], [2], [[$2]],
- [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
-m4_define([_lt_join],
-[m4_if([$#$2], [2], [],
- [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
-
-
-# lt_car(LIST)
-# lt_cdr(LIST)
-# ------------
-# Manipulate m4 lists.
-# These macros are necessary as long as will still need to support
-# Autoconf-2.59 which quotes differently.
-m4_define([lt_car], [[$1]])
-m4_define([lt_cdr],
-[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
- [$#], 1, [],
- [m4_dquote(m4_shift($@))])])
-m4_define([lt_unquote], $1)
-
-
-# lt_append(MACRO-NAME, STRING, [SEPARATOR])
-# ------------------------------------------
-# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
-# Note that neither SEPARATOR nor STRING are expanded; they are appended
-# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
-# No SEPARATOR is output if MACRO-NAME was previously undefined (different
-# than defined and empty).
-#
-# This macro is needed until we can rely on Autoconf 2.62, since earlier
-# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
-m4_define([lt_append],
-[m4_define([$1],
- m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
-
-
-
-# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
-# ----------------------------------------------------------
-# Produce a SEP delimited list of all paired combinations of elements of
-# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
-# has the form PREFIXmINFIXSUFFIXn.
-# Needed until we can rely on m4_combine added in Autoconf 2.62.
-m4_define([lt_combine],
-[m4_if(m4_eval([$# > 3]), [1],
- [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
-[[m4_foreach([_Lt_prefix], [$2],
- [m4_foreach([_Lt_suffix],
- ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
- [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
-
-
-# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
-# -----------------------------------------------------------------------
-# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
-# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
-m4_define([lt_if_append_uniq],
-[m4_ifdef([$1],
- [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
- [lt_append([$1], [$2], [$3])$4],
- [$5])],
- [lt_append([$1], [$2], [$3])$4])])
-
-
-# lt_dict_add(DICT, KEY, VALUE)
-# -----------------------------
-m4_define([lt_dict_add],
-[m4_define([$1($2)], [$3])])
-
-
-# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
-# --------------------------------------------
-m4_define([lt_dict_add_subkey],
-[m4_define([$1($2:$3)], [$4])])
-
-
-# lt_dict_fetch(DICT, KEY, [SUBKEY])
-# ----------------------------------
-m4_define([lt_dict_fetch],
-[m4_ifval([$3],
- m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
- m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
-
-
-# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
-# -----------------------------------------------------------------
-m4_define([lt_if_dict_fetch],
-[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
- [$5],
- [$6])])
-
-
-# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
-# --------------------------------------------------------------
-m4_define([lt_dict_filter],
-[m4_if([$5], [], [],
- [lt_join(m4_quote(m4_default([$4], [[, ]])),
- lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
- [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
-])
-
-# ltversion.m4 -- version numbers -*- Autoconf -*-
-#
-# Copyright (C) 2004 Free Software Foundation, Inc.
-# Written by Scott James Remnant, 2004
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-
-# Generated from ltversion.in.
-
-# serial 3017 ltversion.m4
-# This file is part of GNU Libtool
-
-m4_define([LT_PACKAGE_VERSION], [2.2.6b])
-m4_define([LT_PACKAGE_REVISION], [1.3017])
-
-AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.2.6b'
-macro_revision='1.3017'
-_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
-_LT_DECL(, macro_revision, 0)
-])
-
-# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
-#
-# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
-# Written by Scott James Remnant, 2004.
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-
-# serial 4 lt~obsolete.m4
-
-# These exist entirely to fool aclocal when bootstrapping libtool.
-#
-# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
-# which have later been changed to m4_define as they aren't part of the
-# exported API, or moved to Autoconf or Automake where they belong.
-#
-# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
-# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
-# using a macro with the same name in our local m4/libtool.m4 it'll
-# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
-# and doesn't know about Autoconf macros at all.)
-#
-# So we provide this file, which has a silly filename so it's always
-# included after everything else. This provides aclocal with the
-# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
-# because those macros already exist, or will be overwritten later.
-# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
-#
-# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
-# Yes, that means every name once taken will need to remain here until
-# we give up compatibility with versions before 1.7, at which point
-# we need to keep only those names which we still refer to.
-
-# This is to help aclocal find these macros, as it can't see m4_define.
-AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
-
-m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
-m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
-m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
-m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
-m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
-m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
-m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
-m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
-m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
-m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
-m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
-m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
-m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
-m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
-m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
-m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
-m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
-m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
-m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
-m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
-m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
-m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
-m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
-m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
-m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
-m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
-m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
-m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
-m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
-m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
-m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
-m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
-m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
-m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
-m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
-m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
-m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
-m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
-m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
-m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
-m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
-m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
-m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])])
-m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
-m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
-m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
-m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
-m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
-m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
-m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
-m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
-m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
-m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
-m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
-m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
-
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_AUTOMAKE_VERSION(VERSION)
-# ----------------------------
-# Automake X.Y traces this macro to ensure aclocal.m4 has been
-# generated from the m4 files accompanying Automake X.Y.
-# (This private macro should not be called outside this file.)
-AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.11'
-dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
-dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.1], [],
- [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
-])
-
-# _AM_AUTOCONF_VERSION(VERSION)
-# -----------------------------
-# aclocal traces this macro to find the Autoconf version.
-# This is a private macro too. Using m4_define simplifies
-# the logic in aclocal, which can simply ignore this definition.
-m4_define([_AM_AUTOCONF_VERSION], [])
-
-# AM_SET_CURRENT_AUTOMAKE_VERSION
-# -------------------------------
-# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
-# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
-
-# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
-#
-# Of course, Automake must honor this variable whenever it calls a
-# tool from the auxiliary directory. The problem is that $srcdir (and
-# therefore $ac_aux_dir as well) can be either absolute or relative,
-# depending on how configure is run. This is pretty annoying, since
-# it makes $ac_aux_dir quite unusable in subdirectories: in the top
-# source directory, any form will work fine, but in subdirectories a
-# relative path needs to be adjusted first.
-#
-# $ac_aux_dir/missing
-# fails when called from a subdirectory if $ac_aux_dir is relative
-# $top_srcdir/$ac_aux_dir/missing
-# fails if $ac_aux_dir is absolute,
-# fails when called from a subdirectory in a VPATH build with
-# a relative $ac_aux_dir
-#
-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
-# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
-# start a VPATH build or use an absolute $srcdir.
-#
-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
-# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
-# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
-# and then we would define $MISSING as
-# MISSING="\${SHELL} $am_aux_dir/missing"
-# This will work as long as MISSING is not called from configure, because
-# unfortunately $(top_srcdir) has no meaning in configure.
-# However there are other variables, like CC, which are often used in
-# configure, and could therefore not use this "fixed" $ac_aux_dir.
-#
-# Another solution, used here, is to always expand $ac_aux_dir to an
-# absolute PATH. The drawback is that using absolute paths prevent a
-# configured tree to be moved without reconfiguration.
-
-AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-])
-
-# AM_CONDITIONAL -*- Autoconf -*-
-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 9
-
-# AM_CONDITIONAL(NAME, SHELL-CONDITION)
-# -------------------------------------
-# Define a conditional.
-AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ(2.52)dnl
- ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
-AC_SUBST([$1_TRUE])dnl
-AC_SUBST([$1_FALSE])dnl
-_AM_SUBST_NOTMAKE([$1_TRUE])dnl
-_AM_SUBST_NOTMAKE([$1_FALSE])dnl
-m4_define([_AM_COND_VALUE_$1], [$2])dnl
-if $2; then
- $1_TRUE=
- $1_FALSE='#'
-else
- $1_TRUE='#'
- $1_FALSE=
-fi
-AC_CONFIG_COMMANDS_PRE(
-[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
- AC_MSG_ERROR([[conditional "$1" was never defined.
-Usually this means the macro was only invoked conditionally.]])
-fi])])
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 10
-
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
-# written in clear, in which case automake, when reading aclocal.m4,
-# will think it sees a *use*, and therefore will trigger all it's
-# C support machinery. Also note that it means that autoscan, seeing
-# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
-
-# _AM_DEPENDENCIES(NAME)
-# ----------------------
-# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
-# We try a few techniques and use that to set a single cache variable.
-#
-# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
-# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
-# dependency, and given that the user is not expected to run this macro,
-# just rely on AC_PROG_CC.
-AC_DEFUN([_AM_DEPENDENCIES],
-[AC_REQUIRE([AM_SET_DEPDIR])dnl
-AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
-AC_REQUIRE([AM_MAKE_INCLUDE])dnl
-AC_REQUIRE([AM_DEP_TRACK])dnl
-
-ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
- [$1], CXX, [depcc="$CXX" am_compiler_list=],
- [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], UPC, [depcc="$UPC" am_compiler_list=],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
-
-AC_CACHE_CHECK([dependency style of $depcc],
- [am_cv_$1_dependencies_compiler_type],
-[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_$1_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
- fi
- am__universal=false
- m4_case([$1], [CC],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac],
- [CXX],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac])
-
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
- am__obj=sub/conftest.${OBJEXT-o}
- am__minus_obj="-o $am__obj"
- case $depmode in
- gcc)
- # This depmode causes a compiler race in universal mode.
- test "$am__universal" = false || continue
- ;;
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
- # not run yet. These depmodes are late enough in the game, and
- # so weak that their functioning should not be impacted.
- am__obj=conftest.${OBJEXT-o}
- am__minus_obj=
- ;;
- none) break ;;
- esac
- if depmode=$depmode \
- source=sub/conftest.c object=$am__obj \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_$1_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_$1_dependencies_compiler_type=none
-fi
-])
-AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
-AM_CONDITIONAL([am__fastdep$1], [
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
-])
-
-
-# AM_SET_DEPDIR
-# -------------
-# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
-AC_DEFUN([AM_SET_DEPDIR],
-[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
-])
-
-
-# AM_DEP_TRACK
-# ------------
-AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[ --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors])
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
-fi
-AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
-AC_SUBST([AMDEPBACKSLASH])dnl
-_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
-])
-
-# Generate code to set up dependency tracking. -*- Autoconf -*-
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-#serial 5
-
-# _AM_OUTPUT_DEPENDENCY_COMMANDS
-# ------------------------------
-AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
-[{
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
- # are listed without --file. Let's play safe and only enable the eval
- # if we detect the quoting.
- case $CONFIG_FILES in
- *\'*) eval set x "$CONFIG_FILES" ;;
- *) set x $CONFIG_FILES ;;
- esac
- shift
- for mf
- do
- # Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`AS_DIRNAME("$mf")`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`AS_DIRNAME(["$file"])`
- AS_MKDIR_P([$dirpart/$fdir])
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
- done
-}
-])# _AM_OUTPUT_DEPENDENCY_COMMANDS
-
-
-# AM_OUTPUT_DEPENDENCY_COMMANDS
-# -----------------------------
-# This macro should only be invoked once -- use via AC_REQUIRE.
-#
-# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each `.P' file that we will
-# need in order to bootstrap the dependency handling code.
-AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
-[AC_CONFIG_COMMANDS([depfiles],
- [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
-
-# Do all the work for Automake. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 16
-
-# This macro actually does too much. Some checks are only needed if
-# your package does certain things. But this isn't really a big deal.
-
-# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
-# AM_INIT_AUTOMAKE([OPTIONS])
-# -----------------------------------------------
-# The call with PACKAGE and VERSION arguments is the old style
-# call (pre autoconf-2.50), which is being phased out. PACKAGE
-# and VERSION should now be passed to AC_INIT and removed from
-# the call to AM_INIT_AUTOMAKE.
-# We support both call styles for the transition. After
-# the next Automake release, Autoconf can make the AC_INIT
-# arguments mandatory, and then we can depend on a new Autoconf
-# release and drop the old call support.
-AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
-dnl Autoconf wants to disallow AM_ names. We explicitly allow
-dnl the ones we care about.
-m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
-AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
-AC_REQUIRE([AC_PROG_INSTALL])dnl
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-AC_SUBST([CYGPATH_W])
-
-# Define the identity of the package.
-dnl Distinguish between old-style and new-style calls.
-m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
- AC_SUBST([PACKAGE], [$1])dnl
- AC_SUBST([VERSION], [$2])],
-[_AM_SET_OPTIONS([$1])dnl
-dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
- [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
-
-_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
-
-# Some tools Automake needs.
-AC_REQUIRE([AM_SANITY_CHECK])dnl
-AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
-AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
-AC_REQUIRE([AC_PROG_AWK])dnl
-AC_REQUIRE([AC_PROG_MAKE_SET])dnl
-AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
- [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
- [_AM_PROG_TAR([v7])])])
-_AM_IF_OPTION([no-dependencies],,
-[AC_PROVIDE_IFELSE([AC_PROG_CC],
- [_AM_DEPENDENCIES(CC)],
- [define([AC_PROG_CC],
- defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [_AM_DEPENDENCIES(CXX)],
- [define([AC_PROG_CXX],
- defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES(OBJC)],
- [define([AC_PROG_OBJC],
- defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
-])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
-dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
-AC_CONFIG_COMMANDS_PRE(dnl
-[m4_provide_if([_AM_COMPILER_EXEEXT],
- [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-])
-
-dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
-dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
-dnl mangled by Autoconf and run in a shell conditional statement.
-m4_define([_AC_COMPILER_EXEEXT],
-m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
-
-# When config.status generates a header, we must update the stamp-h file.
-# This file resides in the same directory as the config header
-# that is generated. The stamp files are numbered to have different names.
-
-# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
-# loop where config.status creates the headers, so we can generate
-# our stamp files there.
-AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
-[# Compute $1's index in $config_headers.
-_am_arg=$1
-_am_stamp_count=1
-for _am_header in $config_headers :; do
- case $_am_header in
- $_am_arg | $_am_arg:* )
- break ;;
- * )
- _am_stamp_count=`expr $_am_stamp_count + 1` ;;
- esac
-done
-echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-
-# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_SH
-# ------------------
-# Define $install_sh.
-AC_DEFUN([AM_PROG_INSTALL_SH],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
- *)
- install_sh="\${SHELL} $am_aux_dir/install-sh"
- esac
-fi
-AC_SUBST(install_sh)])
-
-# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# Check whether the underlying file-system supports filenames
-# with a leading dot. For instance MS-DOS doesn't.
-AC_DEFUN([AM_SET_LEADING_DOT],
-[rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-AC_SUBST([am__leading_dot])])
-
-# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
-# From Jim Meyering
-
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 5
-
-# AM_MAINTAINER_MODE([DEFAULT-MODE])
-# ----------------------------------
-# Control maintainer-specific portions of Makefiles.
-# Default is to disable them, unless `enable' is passed literally.
-# For symmetry, `disable' may be passed as well. Anyway, the user
-# can override the default with the --enable/--disable switch.
-AC_DEFUN([AM_MAINTAINER_MODE],
-[m4_case(m4_default([$1], [disable]),
- [enable], [m4_define([am_maintainer_other], [disable])],
- [disable], [m4_define([am_maintainer_other], [enable])],
- [m4_define([am_maintainer_other], [enable])
- m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
-AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
- dnl maintainer-mode's default is 'disable' unless 'enable' is passed
- AC_ARG_ENABLE([maintainer-mode],
-[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
- (and sometimes confusing) to the casual installer],
- [USE_MAINTAINER_MODE=$enableval],
- [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
- AC_MSG_RESULT([$USE_MAINTAINER_MODE])
- AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
- MAINT=$MAINTAINER_MODE_TRUE
- AC_SUBST([MAINT])dnl
-]
-)
-
-AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-
-# Check to see how 'make' treats includes. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# AM_MAKE_INCLUDE()
-# -----------------
-# Check to see how make treats includes.
-AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo this is the am__doit target
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
- am__include=include
- am__quote=
- _am_result=GNU
- ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- case `$am_make -s -f confmf 2> /dev/null` in #(
- *the\ am__doit\ target*)
- am__include=.include
- am__quote="\""
- _am_result=BSD
- ;;
- esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
-
-# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 6
-
-# AM_MISSING_PROG(NAME, PROGRAM)
-# ------------------------------
-AC_DEFUN([AM_MISSING_PROG],
-[AC_REQUIRE([AM_MISSING_HAS_RUN])
-$1=${$1-"${am_missing_run}$2"}
-AC_SUBST($1)])
-
-
-# AM_MISSING_HAS_RUN
-# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
-AC_DEFUN([AM_MISSING_HAS_RUN],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([missing])dnl
-if test x"${MISSING+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
- *)
- MISSING="\${SHELL} $am_aux_dir/missing" ;;
- esac
-fi
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
-else
- am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
-fi
-])
-
-# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_MKDIR_P
-# ---------------
-# Check for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
- [[\\/$]]* | ?:[[\\/]]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
-# Helper functions for option handling. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# _AM_MANGLE_OPTION(NAME)
-# -----------------------
-AC_DEFUN([_AM_MANGLE_OPTION],
-[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
-
-# _AM_SET_OPTION(NAME)
-# ------------------------------
-# Set option NAME. Presently that only means defining a flag for this option.
-AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
-
-# _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
-# OPTIONS is a space-separated list of Automake options.
-AC_DEFUN([_AM_SET_OPTIONS],
-[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
-
-# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
-# -------------------------------------------
-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
-AC_DEFUN([_AM_IF_OPTION],
-[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-
-# Check to make sure that the build environment is sane. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 5
-
-# AM_SANITY_CHECK
-# ---------------
-AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
-# Reject unsafe characters in $srcdir or the absolute working directory
-# name. Accept space and tab only in the latter.
-am_lf='
-'
-case `pwd` in
- *[[\\\"\#\$\&\'\`$am_lf]]*)
- AC_MSG_ERROR([unsafe absolute working directory name]);;
-esac
-case $srcdir in
- *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
- AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
-esac
-
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
-alias in your environment])
- fi
-
- test "$[2]" = conftest.file
- )
-then
- # Ok.
- :
-else
- AC_MSG_ERROR([newly created file is older than distributed files!
-Check your system clock])
-fi
-AC_MSG_RESULT(yes)])
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_STRIP
-# ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
-# specify the program used to strip binaries. This is especially
-# annoying in cross-compiling environments, where the build's strip
-# is unlikely to handle the host's binaries.
-# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
-# STRIPPROG with the value of the STRIP variable (set by the user).
-AC_DEFUN([AM_PROG_INSTALL_STRIP],
-[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
-if test "$cross_compiling" != no; then
- AC_CHECK_TOOL([STRIP], [strip], :)
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-AC_SUBST([INSTALL_STRIP_PROGRAM])])
-
-# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
-# This macro is traced by Automake.
-AC_DEFUN([_AM_SUBST_NOTMAKE])
-
-# AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Public sister of _AM_SUBST_NOTMAKE.
-AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
-
-# Check how to create a tarball. -*- Autoconf -*-
-
-# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_PROG_TAR(FORMAT)
-# --------------------
-# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
-#
-# Substitute a variable $(am__tar) that is a command
-# writing to stdout a FORMAT-tarball containing the directory
-# $tardir.
-# tardir=directory && $(am__tar) > result.tar
-#
-# Substitute a variable $(am__untar) that extract such
-# a tarball read from stdin.
-# $(am__untar) < result.tar
-AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
-m4_if([$1], [v7],
- [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
- [m4_case([$1], [ustar],, [pax],,
- [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
-_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar;
- do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
-
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
-
- # tar/untar a dummy directory, and stop if the command works
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
- rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
-done
-rm -rf conftest.dir
-
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
-AC_SUBST([am__tar])
-AC_SUBST([am__untar])
-]) # _AM_PROG_TAR
-
diff --git a/deps/uv/src/unix/eio/autogen.sh b/deps/uv/src/unix/eio/autogen.sh
deleted file mode 100755
index 8056ee7f9..000000000
--- a/deps/uv/src/unix/eio/autogen.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-autoreconf --install --symlink --force
diff --git a/deps/uv/src/unix/eio/config.h.in b/deps/uv/src/unix/eio/config.h.in
deleted file mode 100644
index 73e9dd07d..000000000
--- a/deps/uv/src/unix/eio/config.h.in
+++ /dev/null
@@ -1,86 +0,0 @@
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* fdatasync(2) is available */
-#undef HAVE_FDATASYNC
-
-/* futimes(2) is available */
-#undef HAVE_FUTIMES
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* posix_fadvise(2) is available */
-#undef HAVE_POSIX_FADVISE
-
-/* posix_madvise(2) is available */
-#undef HAVE_POSIX_MADVISE
-
-/* pread(2) and pwrite(2) are available */
-#undef HAVE_PREADWRITE
-
-/* readahead(2) is available (linux) */
-#undef HAVE_READAHEAD
-
-/* sendfile(2) is available and supported */
-#undef HAVE_SENDFILE
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* sync_file_range(2) is available */
-#undef HAVE_SYNC_FILE_RANGE
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* utimes(2) is available */
-#undef HAVE_UTIMES
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#undef LT_OBJDIR
-
-/* Name of package */
-#undef PACKAGE
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
diff --git a/deps/uv/src/unix/eio/config_cygwin.h b/deps/uv/src/unix/eio/config_cygwin.h
deleted file mode 100644
index f64e7fe44..000000000
--- a/deps/uv/src/unix/eio/config_cygwin.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* fdatasync(2) is available */
-#define HAVE_FDATASYNC 1
-
-/* utimes(2) is available */
-#define HAVE_UTIMES 1
-
-/* futimes(2) is available */
-#define HAVE_FUTIMES 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* pread(2) and pwrite(2) are available */
-#define HAVE_PREADWRITE 1
-
-/* readahead(2) is available (linux) */
-/* #undef HAVE_READAHEAD */
-
-/* sendfile(2) is available and supported */
-/* #undef HAVE_SENDFILE */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* sync_file_range(2) is available */
-/* #undef HAVE_SYNC_FILE_RANGE */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Name of package */
-#define PACKAGE "libeio"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "1.0"
diff --git a/deps/uv/src/unix/eio/config_darwin.h b/deps/uv/src/unix/eio/config_darwin.h
deleted file mode 100644
index f406759e0..000000000
--- a/deps/uv/src/unix/eio/config_darwin.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* fallocate(2) is available */
-/* #undef HAVE_FALLOCATE */
-
-/* fdatasync(2) is available */
-#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060
-#define HAVE_FDATASYNC 1
-#else
-#define HAVE_FDATASYNC 0
-#endif
-
-/* futimes(2) is available */
-#define HAVE_FUTIMES 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* posix_fadvise(2) is available */
-/* #undef HAVE_POSIX_FADVISE */
-
-/* posix_madvise(2) is available */
-#define HAVE_POSIX_MADVISE 1
-
-/* prctl(PR_SET_NAME) is available */
-/* #undef HAVE_PRCTL_SET_NAME */
-
-/* pread(2) and pwrite(2) are available */
-#define HAVE_PREADWRITE 1
-
-/* readahead(2) is available (linux) */
-/* #undef HAVE_READAHEAD */
-
-/* sendfile(2) is available and supported */
-#define HAVE_SENDFILE 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* sync_file_range(2) is available */
-/* #undef HAVE_SYNC_FILE_RANGE */
-
-/* Define to 1 if you have the <sys/prctl.h> header file. */
-/* #undef HAVE_SYS_PRCTL_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* syscall(__NR_syncfs) is available */
-/* #undef HAVE_SYS_SYNCFS */
-
-/* Define to 1 if you have the <sys/syscall.h> header file. */
-#define HAVE_SYS_SYSCALL_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* utimes(2) is available */
-#define HAVE_UTIMES 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libeio"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Enable extensions on AIX 3, Interix. */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris. */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop. */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-
-/* Version number of package */
-#define VERSION "1.0"
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
diff --git a/deps/uv/src/unix/eio/config_freebsd.h b/deps/uv/src/unix/eio/config_freebsd.h
deleted file mode 100644
index 3c93d260f..000000000
--- a/deps/uv/src/unix/eio/config_freebsd.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* fdatasync(2) is available */
-/* #undef HAVE_FDATASYNC */
-
-/* utimes(2) is available */
-#define HAVE_UTIMES 1
-
-/* futimes(2) is available */
-#define HAVE_FUTIMES 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* pread(2) and pwrite(2) are available */
-#define HAVE_PREADWRITE 1
-
-/* readahead(2) is available (linux) */
-/* #undef HAVE_READAHEAD */
-
-/* sendfile(2) is available and supported */
-#define HAVE_SENDFILE 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* sync_file_range(2) is available */
-/* #undef HAVE_SYNC_FILE_RANGE */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libeio"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "1.0"
diff --git a/deps/uv/src/unix/eio/config_linux.h b/deps/uv/src/unix/eio/config_linux.h
deleted file mode 100644
index e7a0d6e7a..000000000
--- a/deps/uv/src/unix/eio/config_linux.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-#include <linux/version.h>
-#include <features.h>
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* fdatasync(2) is available */
-#define HAVE_FDATASYNC 1
-
-/* utimes(2) is available */
-#define HAVE_UTIMES 1
-
-/* futimes(2) is available but we make the syscall directly. */
-#undef HAVE_FUTIMES
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* pread(2) and pwrite(2) are available */
-#define HAVE_PREADWRITE 1
-
-/* readahead(2) is available (linux) */
-#define HAVE_READAHEAD 1
-
-/* sendfile(2) is available and supported */
-#define HAVE_SENDFILE 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* sync_file_range(2) is available if kernel >= 2.6.17 and glibc >= 2.6 */
-#if LINUX_VERSION_CODE >= 0x020611 && __GLIBC_PREREQ(2, 6)
-#define HAVE_SYNC_FILE_RANGE 1
-#else
-#define HAVE_SYNC_FILE_RANGE 0
-#endif
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/syscall.h> header file. */
-#define HAVE_SYS_SYSCALL_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libeio"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "1.0"
diff --git a/deps/uv/src/unix/eio/config_netbsd.h b/deps/uv/src/unix/eio/config_netbsd.h
deleted file mode 100644
index 31f18e604..000000000
--- a/deps/uv/src/unix/eio/config_netbsd.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* fdatasync(2) is available */
-/* #undef HAVE_FDATASYNC */
-
-/* utimes(2) is available */
-#define HAVE_UTIMES 1
-
-/* futimes(2) is available */
-#define HAVE_FUTIMES 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* pread(2) and pwrite(2) are available */
-#define HAVE_PREADWRITE 1
-
-/* readahead(2) is available (linux) */
-/* #undef HAVE_READAHEAD */
-
-/* sendfile(2) is available and supported */
-#define HAVE_SENDFILE 0
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* sync_file_range(2) is available */
-/* #undef HAVE_SYNC_FILE_RANGE */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libeio"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "1.0"
diff --git a/deps/uv/src/unix/eio/config_openbsd.h b/deps/uv/src/unix/eio/config_openbsd.h
deleted file mode 100644
index a73b8a883..000000000
--- a/deps/uv/src/unix/eio/config_openbsd.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* fallocate(2) is available */
-/* #undef HAVE_FALLOCATE */
-
-/* fdatasync(2) is available */
-/* #undef HAVE_FDATASYNC */
-
-/* futimes(2) is available */
-#define HAVE_FUTIMES 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* posix_fadvise(2) is available */
-/* #undef HAVE_POSIX_FADVISE */
-
-/* posix_madvise(2) is available */
-#define HAVE_POSIX_MADVISE 1
-
-/* prctl(PR_SET_NAME) is available */
-/* #undef HAVE_PRCTL_SET_NAME */
-
-/* pread(2) and pwrite(2) are available */
-#define HAVE_PREADWRITE 1
-
-/* readahead(2) is available (linux) */
-/* #undef HAVE_READAHEAD */
-
-/* sendfile(2) is available and supported */
-/* #undef HAVE_SENDFILE */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* sync_file_range(2) is available */
-/* #undef HAVE_SYNC_FILE_RANGE */
-
-/* Define to 1 if you have the <sys/prctl.h> header file. */
-/* #undef HAVE_SYS_PRCTL_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* syscall(__NR_syncfs) is available */
-/* #undef HAVE_SYS_SYNCFS */
-
-/* Define to 1 if you have the <sys/syscall.h> header file. */
-#define HAVE_SYS_SYSCALL_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* utimes(2) is available */
-#define HAVE_UTIMES 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libeio"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Enable extensions on AIX 3, Interix. */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris. */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop. */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-
-/* Version number of package */
-#define VERSION "1.0"
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
diff --git a/deps/uv/src/unix/eio/config_sunos.h b/deps/uv/src/unix/eio/config_sunos.h
deleted file mode 100644
index 546926fcb..000000000
--- a/deps/uv/src/unix/eio/config_sunos.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* fdatasync(2) is available */
-#define HAVE_FDATASYNC 1
-
-/* utimes(2) is available */
-#define HAVE_UTIMES 1
-
-/* futimes(2) is available */
-#define HAVE_FUTIMES 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* pread(2) and pwrite(2) are available */
-#define HAVE_PREADWRITE 1
-
-/* readahead(2) is available (linux) */
-/* #undef HAVE_READAHEAD */
-
-/* sendfile(2) is available and supported */
-/* #undef HAVE_SENDFILE */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* sync_file_range(2) is available */
-/* #undef HAVE_SYNC_FILE_RANGE */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libeio"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "1.0"
diff --git a/deps/uv/src/unix/eio/configure.ac b/deps/uv/src/unix/eio/configure.ac
deleted file mode 100644
index 9faffad53..000000000
--- a/deps/uv/src/unix/eio/configure.ac
+++ /dev/null
@@ -1,22 +0,0 @@
-AC_PREREQ(2.59)
-AC_INIT
-AC_CONFIG_SRCDIR([eio.h])
-AC_CONFIG_HEADERS([config.h])
-
-AM_INIT_AUTOMAKE(libeio,1.0)
-AM_MAINTAINER_MODE
-
-AC_GNU_SOURCE
-
-AC_PROG_LIBTOOL
-
-AC_PROG_CC
-
-if test "x$GCC" = xyes ; then
- CFLAGS="-O3 $CFLAGS"
-fi
-
-m4_include([libeio.m4])
-
-AC_CONFIG_FILES([Makefile])
-AC_OUTPUT
diff --git a/deps/uv/src/unix/eio/demo.c b/deps/uv/src/unix/eio/demo.c
deleted file mode 100644
index cbef59557..000000000
--- a/deps/uv/src/unix/eio/demo.c
+++ /dev/null
@@ -1,194 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <poll.h>
-#include <string.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "eio.h"
-
-int respipe [2];
-
-void
-want_poll (void)
-{
- char dummy;
- printf ("want_poll ()\n");
- write (respipe [1], &dummy, 1);
-}
-
-void
-done_poll (void)
-{
- char dummy;
- printf ("done_poll ()\n");
- read (respipe [0], &dummy, 1);
-}
-
-void
-event_loop (void)
-{
- // an event loop. yeah.
- struct pollfd pfd;
- pfd.fd = respipe [0];
- pfd.events = POLLIN;
-
- printf ("\nentering event loop\n");
- while (eio_nreqs ())
- {
- poll (&pfd, 1, -1);
- printf ("eio_poll () = %d\n", eio_poll ());
- }
- printf ("leaving event loop\n");
-}
-
-int
-res_cb (eio_req *req)
-{
- printf ("res_cb(%d|%s) = %d\n", req->type, req->data ? req->data : "?", EIO_RESULT (req));
-
- if (req->result < 0)
- abort ();
-
- return 0;
-}
-
-int
-readdir_cb (eio_req *req)
-{
- char *buf = (char *)EIO_BUF (req);
-
- printf ("readdir_cb = %d\n", EIO_RESULT (req));
-
- if (EIO_RESULT (req) < 0)
- return 0;
-
- while (EIO_RESULT (req)--)
- {
- printf ("readdir = <%s>\n", buf);
- buf += strlen (buf) + 1;
- }
-
- return 0;
-}
-
-int
-stat_cb (eio_req *req)
-{
- struct stat *buf = EIO_STAT_BUF (req);
-
- if (req->type == EIO_FSTAT)
- printf ("fstat_cb = %d\n", EIO_RESULT (req));
- else
- printf ("stat_cb(%s) = %d\n", EIO_PATH (req), EIO_RESULT (req));
-
- if (!EIO_RESULT (req))
- printf ("stat size %d perm 0%o\n", buf->st_size, buf->st_mode & 0777);
-
- return 0;
-}
-
-int
-read_cb (eio_req *req)
-{
- unsigned char *buf = (unsigned char *)EIO_BUF (req);
-
- printf ("read_cb = %d (%02x%02x%02x%02x %02x%02x%02x%02x)\n",
- EIO_RESULT (req),
- buf [0], buf [1], buf [2], buf [3],
- buf [4], buf [5], buf [6], buf [7]);
-
- return 0;
-}
-
-int last_fd;
-
-int
-open_cb (eio_req *req)
-{
- printf ("open_cb = %d\n", EIO_RESULT (req));
-
- last_fd = EIO_RESULT (req);
-
- return 0;
-}
-
-int
-main (void)
-{
- printf ("pipe ()\n");
- if (pipe (respipe)) abort ();
-
- printf ("eio_init ()\n");
- if (eio_init (want_poll, done_poll)) abort ();
-
- do
- {
- /* avoid relative paths yourself(!) */
- eio_mkdir ("eio-test-dir", 0777, 0, res_cb, "mkdir");
- eio_nop (0, res_cb, "nop");
- event_loop ();
-
- eio_stat ("eio-test-dir", 0, stat_cb, "stat");
- eio_lstat ("eio-test-dir", 0, stat_cb, "stat");
- eio_open ("eio-test-dir/eio-test-file", O_RDWR | O_CREAT, 0777, 0, open_cb, "open");
- eio_symlink ("test", "eio-test-dir/eio-symlink", 0, res_cb, "symlink");
- eio_mknod ("eio-test-dir/eio-fifo", S_IFIFO, 0, 0, res_cb, "mknod");
- event_loop ();
-
- eio_utime ("eio-test-dir", 12345.678, 23456.789, 0, res_cb, "utime");
- eio_futime (last_fd, 92345.678, 93456.789, 0, res_cb, "futime");
- eio_chown ("eio-test-dir", getuid (), getgid (), 0, res_cb, "chown");
- eio_fchown (last_fd, getuid (), getgid (), 0, res_cb, "fchown");
- eio_fchmod (last_fd, 0723, 0, res_cb, "fchmod");
- eio_readdir ("eio-test-dir", 0, 0, readdir_cb, "readdir");
- eio_readdir ("/nonexistant", 0, 0, readdir_cb, "readdir");
- eio_fstat (last_fd, 0, stat_cb, "stat");
- eio_write (last_fd, "test\nfail\n", 10, 4, 0, res_cb, "write");
- event_loop ();
-
- eio_read (last_fd, 0, 8, 0, EIO_PRI_DEFAULT, read_cb, "read");
- eio_readlink ("eio-test-dir/eio-symlink", 0, res_cb, "readlink");
- event_loop ();
-
- eio_dup2 (1, 2, EIO_PRI_DEFAULT, res_cb, "dup"); // dup stdout to stderr
- eio_chmod ("eio-test-dir", 0765, 0, res_cb, "chmod");
- eio_ftruncate (last_fd, 9, 0, res_cb, "ftruncate");
- eio_fdatasync (last_fd, 0, res_cb, "fdatasync");
- eio_fsync (last_fd, 0, res_cb, "fsync");
- eio_sync (0, res_cb, "sync");
- eio_busy (0.5, 0, res_cb, "busy");
- event_loop ();
-
- eio_sendfile (1, last_fd, 4, 5, 0, res_cb, "sendfile"); // write "test\n" to stdout
- eio_fstat (last_fd, 0, stat_cb, "stat");
- event_loop ();
-
- eio_truncate ("eio-test-dir/eio-test-file", 6, 0, res_cb, "truncate");
- eio_readahead (last_fd, 0, 64, 0, res_cb, "readahead");
- event_loop ();
-
- eio_close (last_fd, 0, res_cb, "close");
- eio_link ("eio-test-dir/eio-test-file", "eio-test-dir/eio-test-file-2", 0, res_cb, "link");
- event_loop ();
-
- eio_rename ("eio-test-dir/eio-test-file", "eio-test-dir/eio-test-file-renamed", 0, res_cb, "rename");
- event_loop ();
-
- eio_unlink ("eio-test-dir/eio-fifo", 0, res_cb, "unlink");
- eio_unlink ("eio-test-dir/eio-symlink", 0, res_cb, "unlink");
- eio_unlink ("eio-test-dir/eio-test-file-2", 0, res_cb, "unlink");
- eio_unlink ("eio-test-dir/eio-test-file-renamed", 0, res_cb, "unlink");
- event_loop ();
-
- eio_rmdir ("eio-test-dir", 0, res_cb, "rmdir");
- event_loop ();
- }
- while (0);
-
- return 0;
-}
-
diff --git a/deps/uv/src/unix/eio/ecb.h b/deps/uv/src/unix/eio/ecb.h
deleted file mode 100644
index a4aabc109..000000000
--- a/deps/uv/src/unix/eio/ecb.h
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * libecb - http://software.schmorp.de/pkg/libecb
- *
- * Copyright (©) 2009-2011 Marc Alexander Lehmann <libecb@schmorp.de>
- * Copyright (©) 2011 Emanuele Giaquinta
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ECB_H
-#define ECB_H
-
-#ifdef _WIN32
- typedef signed char int8_t;
- typedef unsigned char uint8_t;
- typedef signed short int16_t;
- typedef unsigned short uint16_t;
- typedef signed int int32_t;
- typedef unsigned int uint32_t;
- #if __GNUC__
- typedef signed long long int64_t;
- typedef unsigned long long uint64_t;
- #else /* _MSC_VER || __BORLANDC__ */
- typedef signed __int64 int64_t;
- typedef unsigned __int64 uint64_t;
- #endif
-#else
- #include <inttypes.h>
-#endif
-
-/* many compilers define _GNUC_ to some versions but then only implement
- * what their idiot authors think are the "more important" extensions,
- * causing enourmous grief in return for some better fake benchmark numbers.
- * or so.
- * we try to detect these and simply assume they are not gcc - if they have
- * an issue with that they should have done it right in the first place.
- */
-#ifndef ECB_GCC_VERSION
- #if !defined(__GNUC_MINOR__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__llvm__) || defined(__clang__)
- #define ECB_GCC_VERSION(major,minor) 0
- #else
- #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
- #endif
-#endif
-
-/*****************************************************************************/
-
-#ifndef ECB_MEMORY_FENCE
- #if ECB_GCC_VERSION(2,5)
- #if defined(__x86) || defined(__i386)
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
- #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE /* non-lock xchg might be enough */
- #define ECB_MEMORY_FENCE_RELEASE do { } while (0) /* unlikely to change in future cpus */
- #elif __amd64
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
- #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("lfence" : : : "memory")
- #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("sfence") /* play safe - not needed in any current cpu */
- #endif
- #endif
-#endif
-
-#ifndef ECB_MEMORY_FENCE
- #if ECB_GCC_VERSION(4,4)
- #define ECB_MEMORY_FENCE __sync_synchronize ()
- #define ECB_MEMORY_FENCE_ACQUIRE ({ char dummy = 0; __sync_lock_test_and_set (&dummy, 1); })
- #define ECB_MEMORY_FENCE_RELEASE ({ char dummy = 1; __sync_lock_release (&dummy ); })
- #elif _MSC_VER >= 1400 /* VC++ 2005 */
- #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
- #define ECB_MEMORY_FENCE _ReadWriteBarrier ()
- #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */
- #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier ()
- #elif defined(_WIN32)
- #include <WinNT.h>
- #define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */
- #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
- #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
- #endif
-#endif
-
-#ifndef ECB_MEMORY_FENCE
- /*
- * if you get undefined symbol references to pthread_mutex_lock,
- * or failure to find pthread.h, then you should implement
- * the ECB_MEMORY_FENCE operations for your cpu/compiler
- * OR proide pthread.h and link against the posix thread library
- * of your system.
- */
- #include <pthread.h>
-
- static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER;
- #define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0)
- #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
- #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
-#endif
-
-/*****************************************************************************/
-
-#define ECB_C99 (__STDC_VERSION__ >= 199901L)
-
-#if __cplusplus
- #define ecb_inline static inline
-#elif ECB_GCC_VERSION(2,5)
- #define ecb_inline static __inline__
-#elif ECB_C99
- #define ecb_inline static inline
-#else
- #define ecb_inline static
-#endif
-
-#if ECB_GCC_VERSION(3,3)
- #define ecb_restrict __restrict__
-#elif ECB_C99
- #define ecb_restrict restrict
-#else
- #define ecb_restrict
-#endif
-
-typedef int ecb_bool;
-
-#define ECB_CONCAT_(a, b) a ## b
-#define ECB_CONCAT(a, b) ECB_CONCAT_(a, b)
-#define ECB_STRINGIFY_(a) # a
-#define ECB_STRINGIFY(a) ECB_STRINGIFY_(a)
-
-#define ecb_function_ ecb_inline
-
-#if ECB_GCC_VERSION(3,1)
- #define ecb_attribute(attrlist) __attribute__(attrlist)
- #define ecb_is_constant(expr) __builtin_constant_p (expr)
- #define ecb_expect(expr,value) __builtin_expect ((expr),(value))
- #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
-#else
- #define ecb_attribute(attrlist)
- #define ecb_is_constant(expr) 0
- #define ecb_expect(expr,value) (expr)
- #define ecb_prefetch(addr,rw,locality)
-#endif
-
-/* no emulation for ecb_decltype */
-#if ECB_GCC_VERSION(4,5)
- #define ecb_decltype(x) __decltype(x)
-#elif ECB_GCC_VERSION(3,0)
- #define ecb_decltype(x) __typeof(x)
-#endif
-
-#define ecb_noinline ecb_attribute ((__noinline__))
-#define ecb_noreturn ecb_attribute ((__noreturn__))
-#define ecb_unused ecb_attribute ((__unused__))
-#define ecb_const ecb_attribute ((__const__))
-#define ecb_pure ecb_attribute ((__pure__))
-
-#if ECB_GCC_VERSION(4,3)
- #define ecb_artificial ecb_attribute ((__artificial__))
- #define ecb_hot ecb_attribute ((__hot__))
- #define ecb_cold ecb_attribute ((__cold__))
-#else
- #define ecb_artificial
- #define ecb_hot
- #define ecb_cold
-#endif
-
-/* put around conditional expressions if you are very sure that the */
-/* expression is mostly true or mostly false. note that these return */
-/* booleans, not the expression. */
-#define ecb_expect_false(expr) ecb_expect (!!(expr), 0)
-#define ecb_expect_true(expr) ecb_expect (!!(expr), 1)
-/* for compatibility to the rest of the world */
-#define ecb_likely(expr) ecb_expect_true (expr)
-#define ecb_unlikely(expr) ecb_expect_false (expr)
-
-/* count trailing zero bits and count # of one bits */
-#if ECB_GCC_VERSION(3,4)
- /* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */
- #define ecb_ld32(x) (__builtin_clz (x) ^ 31)
- #define ecb_ld64(x) (__builtin_clzll (x) ^ 63)
- #define ecb_ctz32(x) __builtin_ctz (x)
- #define ecb_ctz64(x) __builtin_ctzll (x)
- #define ecb_popcount32(x) __builtin_popcount (x)
- /* no popcountll */
-#else
- ecb_function_ int ecb_ctz32 (uint32_t x) ecb_const;
- ecb_function_ int
- ecb_ctz32 (uint32_t x)
- {
- int r = 0;
-
- x &= ~x + 1; /* this isolates the lowest bit */
-
-#if ECB_branchless_on_i386
- r += !!(x & 0xaaaaaaaa) << 0;
- r += !!(x & 0xcccccccc) << 1;
- r += !!(x & 0xf0f0f0f0) << 2;
- r += !!(x & 0xff00ff00) << 3;
- r += !!(x & 0xffff0000) << 4;
-#else
- if (x & 0xaaaaaaaa) r += 1;
- if (x & 0xcccccccc) r += 2;
- if (x & 0xf0f0f0f0) r += 4;
- if (x & 0xff00ff00) r += 8;
- if (x & 0xffff0000) r += 16;
-#endif
-
- return r;
- }
-
- ecb_function_ int ecb_ctz64 (uint64_t x) ecb_const;
- ecb_function_ int
- ecb_ctz64 (uint64_t x)
- {
- int shift = x & 0xffffffffU ? 0 : 32;
- return ecb_ctz32 (x >> shift) + shift;
- }
-
- ecb_function_ int ecb_popcount32 (uint32_t x) ecb_const;
- ecb_function_ int
- ecb_popcount32 (uint32_t x)
- {
- x -= (x >> 1) & 0x55555555;
- x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
- x = ((x >> 4) + x) & 0x0f0f0f0f;
- x *= 0x01010101;
-
- return x >> 24;
- }
-
- /* you have the choice beetween something with a table lookup, */
- /* something using lots of bit arithmetic and a simple loop */
- /* we went for the loop */
- ecb_function_ int ecb_ld32 (uint32_t x) ecb_const;
- ecb_function_ int ecb_ld32 (uint32_t x)
- {
- int r = 0;
-
- if (x >> 16) { x >>= 16; r += 16; }
- if (x >> 8) { x >>= 8; r += 8; }
- if (x >> 4) { x >>= 4; r += 4; }
- if (x >> 2) { x >>= 2; r += 2; }
- if (x >> 1) { r += 1; }
-
- return r;
- }
-
- ecb_function_ int ecb_ld64 (uint64_t x) ecb_const;
- ecb_function_ int ecb_ld64 (uint64_t x)
- {
- int r = 0;
-
- if (x >> 32) { x >>= 32; r += 32; }
-
- return r + ecb_ld32 (x);
- }
-#endif
-
-/* popcount64 is only available on 64 bit cpus as gcc builtin */
-/* so for this version we are lazy */
-ecb_function_ int ecb_popcount64 (uint64_t x) ecb_const;
-ecb_function_ int
-ecb_popcount64 (uint64_t x)
-{
- return ecb_popcount32 (x) + ecb_popcount32 (x >> 32);
-}
-
-ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) ecb_const;
-ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) ecb_const;
-ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) ecb_const;
-ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) ecb_const;
-ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) ecb_const;
-ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) ecb_const;
-ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) ecb_const;
-ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) ecb_const;
-
-ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); }
-ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); }
-ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); }
-ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); }
-ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
-ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
-ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
-ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
-
-#if ECB_GCC_VERSION(4,3)
- #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16)
- #define ecb_bswap32(x) __builtin_bswap32 (x)
- #define ecb_bswap64(x) __builtin_bswap64 (x)
-#else
- ecb_function_ uint16_t ecb_bswap16 (uint16_t x) ecb_const;
- ecb_function_ uint16_t
- ecb_bswap16 (uint16_t x)
- {
- return ecb_rotl16 (x, 8);
- }
-
- ecb_function_ uint32_t ecb_bswap32 (uint32_t x) ecb_const;
- ecb_function_ uint32_t
- ecb_bswap32 (uint32_t x)
- {
- return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16);
- }
-
- ecb_function_ uint64_t ecb_bswap64 (uint64_t x) ecb_const;
- ecb_function_ uint64_t
- ecb_bswap64 (uint64_t x)
- {
- return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32);
- }
-#endif
-
-#if ECB_GCC_VERSION(4,5)
- #define ecb_unreachable() __builtin_unreachable ()
-#else
- /* this seems to work fine, but gcc always emits a warning for it :/ */
- ecb_function_ void ecb_unreachable (void) ecb_noreturn;
- ecb_function_ void ecb_unreachable (void) { }
-#endif
-
-/* try to tell the compiler that some condition is definitely true */
-#define ecb_assume(cond) do { if (!(cond)) ecb_unreachable (); } while (0)
-
-ecb_function_ unsigned char ecb_byteorder_helper (void) ecb_const;
-ecb_function_ unsigned char
-ecb_byteorder_helper (void)
-{
- const uint32_t u = 0x11223344;
- return *(unsigned char *)&u;
-}
-
-ecb_function_ ecb_bool ecb_big_endian (void) ecb_const;
-ecb_function_ ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; }
-ecb_function_ ecb_bool ecb_little_endian (void) ecb_const;
-ecb_function_ ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; }
-
-#if ECB_GCC_VERSION(3,0) || ECB_C99
- #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))
-#else
- #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n)))
-#endif
-
-#if ecb_cplusplus_does_not_suck
- /* does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) */
- template<typename T, int N>
- static inline int ecb_array_length (const T (&arr)[N])
- {
- return N;
- }
-#else
- #define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
-#endif
-
-#endif
-
diff --git a/deps/uv/src/unix/eio/eio.3 b/deps/uv/src/unix/eio/eio.3
deleted file mode 100644
index ec5bde33e..000000000
--- a/deps/uv/src/unix/eio/eio.3
+++ /dev/null
@@ -1,3428 +0,0 @@
-.\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.05)
-.\"
-.\" Standard preamble:
-.\" ========================================================================
-.de Sh \" Subsection heading
-.br
-.if t .Sp
-.ne 5
-.PP
-\fB\\$1\fR
-.PP
-..
-.de Sp \" Vertical space (when we can't use .PP)
-.if t .sp .5v
-.if n .sp
-..
-.de Vb \" Begin verbatim text
-.ft CW
-.nf
-.ne \\$1
-..
-.de Ve \" End verbatim text
-.ft R
-.fi
-..
-.\" Set up some character translations and predefined strings. \*(-- will
-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
-.\" double quote, and \*(R" will give a right double quote. \*(C+ will
-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
-.\" nothing in troff, for use with C<>.
-.tr \(*W-
-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
-.ie n \{\
-. ds -- \(*W-
-. ds PI pi
-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
-. ds L" ""
-. ds R" ""
-. ds C` ""
-. ds C' ""
-'br\}
-.el\{\
-. ds -- \|\(em\|
-. ds PI \(*p
-. ds L" ``
-. ds R" ''
-'br\}
-.\"
-.\" Escape single quotes in literal strings from groff's Unicode transform.
-.ie \n(.g .ds Aq \(aq
-.el .ds Aq '
-.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
-.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
-.\" entries marked with X<> in POD. Of course, you'll have to process the
-.\" output yourself in some meaningful fashion.
-.ie \nF \{\
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
-..
-. nr % 0
-. rr F
-.\}
-.el \{\
-. de IX
-..
-.\}
-.\"
-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
-.\" Fear. Run. Save yourself. No user-serviceable parts.
-. \" fudge factors for nroff and troff
-.if n \{\
-. ds #H 0
-. ds #V .8m
-. ds #F .3m
-. ds #[ \f1
-. ds #] \fP
-.\}
-.if t \{\
-. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
-. ds #V .6m
-. ds #F 0
-. ds #[ \&
-. ds #] \&
-.\}
-. \" simple accents for nroff and troff
-.if n \{\
-. ds ' \&
-. ds ` \&
-. ds ^ \&
-. ds , \&
-. ds ~ ~
-. ds /
-.\}
-.if t \{\
-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
-.\}
-. \" troff and (daisy-wheel) nroff accents
-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
-.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
-.ds ae a\h'-(\w'a'u*4/10)'e
-.ds Ae A\h'-(\w'A'u*4/10)'E
-. \" corrections for vroff
-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
-. \" for low resolution devices (crt and lpr)
-.if \n(.H>23 .if \n(.V>19 \
-\{\
-. ds : e
-. ds 8 ss
-. ds o a
-. ds d- d\h'-1'\(ga
-. ds D- D\h'-1'\(hy
-. ds th \o'bp'
-. ds Th \o'LP'
-. ds ae ae
-. ds Ae AE
-.\}
-.rm #[ #] #H #V #F C
-.\" ========================================================================
-.\"
-.IX Title "LIBEIO 3"
-.TH LIBEIO 3 "2008-05-11" "libeio-1.0" "libeio - truly asynchronous POSIX I/O"
-.\" For nroff, turn off justification. Always turn off hyphenation; it makes
-.\" way too many mistakes in technical documents.
-.if n .ad l
-.nh
-.SH "NAME"
-libev \- a high performance full\-featured event loop written in C
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-.Vb 1
-\& #include <ev.h>
-.Ve
-.Sh "\s-1EXAMPLE\s0 \s-1PROGRAM\s0"
-.IX Subsection "EXAMPLE PROGRAM"
-.Vb 2
-\& // a single header file is required
-\& #include <ev.h>
-\&
-\& // every watcher type has its own typedef\*(Aqd struct
-\& // with the name ev_<type>
-\& ev_io stdin_watcher;
-\& ev_timer timeout_watcher;
-\&
-\& // all watcher callbacks have a similar signature
-\& // this callback is called when data is readable on stdin
-\& static void
-\& stdin_cb (EV_P_ struct ev_io *w, int revents)
-\& {
-\& puts ("stdin ready");
-\& // for one\-shot events, one must manually stop the watcher
-\& // with its corresponding stop function.
-\& ev_io_stop (EV_A_ w);
-\&
-\& // this causes all nested ev_loop\*(Aqs to stop iterating
-\& ev_unloop (EV_A_ EVUNLOOP_ALL);
-\& }
-\&
-\& // another callback, this time for a time\-out
-\& static void
-\& timeout_cb (EV_P_ struct ev_timer *w, int revents)
-\& {
-\& puts ("timeout");
-\& // this causes the innermost ev_loop to stop iterating
-\& ev_unloop (EV_A_ EVUNLOOP_ONE);
-\& }
-\&
-\& int
-\& main (void)
-\& {
-\& // use the default event loop unless you have special needs
-\& struct ev_loop *loop = ev_default_loop (0);
-\&
-\& // initialise an io watcher, then start it
-\& // this one will watch for stdin to become readable
-\& ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
-\& ev_io_start (loop, &stdin_watcher);
-\&
-\& // initialise a timer watcher, then start it
-\& // simple non\-repeating 5.5 second timeout
-\& ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
-\& ev_timer_start (loop, &timeout_watcher);
-\&
-\& // now wait for events to arrive
-\& ev_loop (loop, 0);
-\&
-\& // unloop was called, so exit
-\& return 0;
-\& }
-.Ve
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The newest version of this document is also available as an html-formatted
-web page you might find easier to navigate when reading it for the first
-time: <http://cvs.schmorp.de/libev/ev.html>.
-.PP
-Libev is an event loop: you register interest in certain events (such as a
-file descriptor being readable or a timeout occurring), and it will manage
-these event sources and provide your program with events.
-.PP
-To do this, it must take more or less complete control over your process
-(or thread) by executing the \fIevent loop\fR handler, and will then
-communicate events via a callback mechanism.
-.PP
-You register interest in certain events by registering so-called \fIevent
-watchers\fR, which are relatively small C structures you initialise with the
-details of the event, and then hand it over to libev by \fIstarting\fR the
-watcher.
-.Sh "\s-1FEATURES\s0"
-.IX Subsection "FEATURES"
-Libev supports \f(CW\*(C`select\*(C'\fR, \f(CW\*(C`poll\*(C'\fR, the Linux-specific \f(CW\*(C`epoll\*(C'\fR, the
-BSD-specific \f(CW\*(C`kqueue\*(C'\fR and the Solaris-specific event port mechanisms
-for file descriptor events (\f(CW\*(C`ev_io\*(C'\fR), the Linux \f(CW\*(C`inotify\*(C'\fR interface
-(for \f(CW\*(C`ev_stat\*(C'\fR), relative timers (\f(CW\*(C`ev_timer\*(C'\fR), absolute timers
-with customised rescheduling (\f(CW\*(C`ev_periodic\*(C'\fR), synchronous signals
-(\f(CW\*(C`ev_signal\*(C'\fR), process status change events (\f(CW\*(C`ev_child\*(C'\fR), and event
-watchers dealing with the event loop mechanism itself (\f(CW\*(C`ev_idle\*(C'\fR,
-\&\f(CW\*(C`ev_embed\*(C'\fR, \f(CW\*(C`ev_prepare\*(C'\fR and \f(CW\*(C`ev_check\*(C'\fR watchers) as well as
-file watchers (\f(CW\*(C`ev_stat\*(C'\fR) and even limited support for fork events
-(\f(CW\*(C`ev_fork\*(C'\fR).
-.PP
-It also is quite fast (see this
-benchmark comparing it to libevent
-for example).
-.Sh "\s-1CONVENTIONS\s0"
-.IX Subsection "CONVENTIONS"
-Libev is very configurable. In this manual the default (and most common)
-configuration will be described, which supports multiple event loops. For
-more info about various configuration options please have a look at
-\&\fB\s-1EMBED\s0\fR section in this manual. If libev was configured without support
-for multiple event loops, then all functions taking an initial argument of
-name \f(CW\*(C`loop\*(C'\fR (which is always of type \f(CW\*(C`struct ev_loop *\*(C'\fR) will not have
-this argument.
-.Sh "\s-1TIME\s0 \s-1REPRESENTATION\s0"
-.IX Subsection "TIME REPRESENTATION"
-Libev represents time as a single floating point number, representing the
-(fractional) number of seconds since the (\s-1POSIX\s0) epoch (somewhere near
-the beginning of 1970, details are complicated, don't ask). This type is
-called \f(CW\*(C`ev_tstamp\*(C'\fR, which is what you should use too. It usually aliases
-to the \f(CW\*(C`double\*(C'\fR type in C, and when you need to do any calculations on
-it, you should treat it as some floatingpoint value. Unlike the name
-component \f(CW\*(C`stamp\*(C'\fR might indicate, it is also used for time differences
-throughout libev.
-.SH "GLOBAL FUNCTIONS"
-.IX Header "GLOBAL FUNCTIONS"
-These functions can be called anytime, even before initialising the
-library in any way.
-.IP "ev_tstamp ev_time ()" 4
-.IX Item "ev_tstamp ev_time ()"
-Returns the current time as libev would use it. Please note that the
-\&\f(CW\*(C`ev_now\*(C'\fR function is usually faster and also often returns the timestamp
-you actually want to know.
-.IP "ev_sleep (ev_tstamp interval)" 4
-.IX Item "ev_sleep (ev_tstamp interval)"
-Sleep for the given interval: The current thread will be blocked until
-either it is interrupted or the given time interval has passed. Basically
-this is a subsecond-resolution \f(CW\*(C`sleep ()\*(C'\fR.
-.IP "int ev_version_major ()" 4
-.IX Item "int ev_version_major ()"
-.PD 0
-.IP "int ev_version_minor ()" 4
-.IX Item "int ev_version_minor ()"
-.PD
-You can find out the major and minor \s-1ABI\s0 version numbers of the library
-you linked against by calling the functions \f(CW\*(C`ev_version_major\*(C'\fR and
-\&\f(CW\*(C`ev_version_minor\*(C'\fR. If you want, you can compare against the global
-symbols \f(CW\*(C`EV_VERSION_MAJOR\*(C'\fR and \f(CW\*(C`EV_VERSION_MINOR\*(C'\fR, which specify the
-version of the library your program was compiled against.
-.Sp
-These version numbers refer to the \s-1ABI\s0 version of the library, not the
-release version.
-.Sp
-Usually, it's a good idea to terminate if the major versions mismatch,
-as this indicates an incompatible change. Minor versions are usually
-compatible to older versions, so a larger minor version alone is usually
-not a problem.
-.Sp
-Example: Make sure we haven't accidentally been linked against the wrong
-version.
-.Sp
-.Vb 3
-\& assert (("libev version mismatch",
-\& ev_version_major () == EV_VERSION_MAJOR
-\& && ev_version_minor () >= EV_VERSION_MINOR));
-.Ve
-.IP "unsigned int ev_supported_backends ()" 4
-.IX Item "unsigned int ev_supported_backends ()"
-Return the set of all backends (i.e. their corresponding \f(CW\*(C`EV_BACKEND_*\*(C'\fR
-value) compiled into this binary of libev (independent of their
-availability on the system you are running on). See \f(CW\*(C`ev_default_loop\*(C'\fR for
-a description of the set values.
-.Sp
-Example: make sure we have the epoll method, because yeah this is cool and
-a must have and can we have a torrent of it please!!!11
-.Sp
-.Vb 2
-\& assert (("sorry, no epoll, no sex",
-\& ev_supported_backends () & EVBACKEND_EPOLL));
-.Ve
-.IP "unsigned int ev_recommended_backends ()" 4
-.IX Item "unsigned int ev_recommended_backends ()"
-Return the set of all backends compiled into this binary of libev and also
-recommended for this platform. This set is often smaller than the one
-returned by \f(CW\*(C`ev_supported_backends\*(C'\fR, as for example kqueue is broken on
-most BSDs and will not be autodetected unless you explicitly request it
-(assuming you know what you are doing). This is the set of backends that
-libev will probe for if you specify no backends explicitly.
-.IP "unsigned int ev_embeddable_backends ()" 4
-.IX Item "unsigned int ev_embeddable_backends ()"
-Returns the set of backends that are embeddable in other event loops. This
-is the theoretical, all-platform, value. To find which backends
-might be supported on the current system, you would need to look at
-\&\f(CW\*(C`ev_embeddable_backends () & ev_supported_backends ()\*(C'\fR, likewise for
-recommended ones.
-.Sp
-See the description of \f(CW\*(C`ev_embed\*(C'\fR watchers for more info.
-.IP "ev_set_allocator (void *(*cb)(void *ptr, long size))" 4
-.IX Item "ev_set_allocator (void *(*cb)(void *ptr, long size))"
-Sets the allocation function to use (the prototype is similar \- the
-semantics are identical to the \f(CW\*(C`realloc\*(C'\fR C89/SuS/POSIX function). It is
-used to allocate and free memory (no surprises here). If it returns zero
-when memory needs to be allocated (\f(CW\*(C`size != 0\*(C'\fR), the library might abort
-or take some potentially destructive action.
-.Sp
-Since some systems (at least OpenBSD and Darwin) fail to implement
-correct \f(CW\*(C`realloc\*(C'\fR semantics, libev will use a wrapper around the system
-\&\f(CW\*(C`realloc\*(C'\fR and \f(CW\*(C`free\*(C'\fR functions by default.
-.Sp
-You could override this function in high-availability programs to, say,
-free some memory if it cannot allocate memory, to use a special allocator,
-or even to sleep a while and retry until some memory is available.
-.Sp
-Example: Replace the libev allocator with one that waits a bit and then
-retries (example requires a standards-compliant \f(CW\*(C`realloc\*(C'\fR).
-.Sp
-.Vb 6
-\& static void *
-\& persistent_realloc (void *ptr, size_t size)
-\& {
-\& for (;;)
-\& {
-\& void *newptr = realloc (ptr, size);
-\&
-\& if (newptr)
-\& return newptr;
-\&
-\& sleep (60);
-\& }
-\& }
-\&
-\& ...
-\& ev_set_allocator (persistent_realloc);
-.Ve
-.IP "ev_set_syserr_cb (void (*cb)(const char *msg));" 4
-.IX Item "ev_set_syserr_cb (void (*cb)(const char *msg));"
-Set the callback function to call on a retryable syscall error (such
-as failed select, poll, epoll_wait). The message is a printable string
-indicating the system call or subsystem causing the problem. If this
-callback is set, then libev will expect it to remedy the sitution, no
-matter what, when it returns. That is, libev will generally retry the
-requested operation, or, if the condition doesn't go away, do bad stuff
-(such as abort).
-.Sp
-Example: This is basically the same thing that libev does internally, too.
-.Sp
-.Vb 6
-\& static void
-\& fatal_error (const char *msg)
-\& {
-\& perror (msg);
-\& abort ();
-\& }
-\&
-\& ...
-\& ev_set_syserr_cb (fatal_error);
-.Ve
-.SH "FUNCTIONS CONTROLLING THE EVENT LOOP"
-.IX Header "FUNCTIONS CONTROLLING THE EVENT LOOP"
-An event loop is described by a \f(CW\*(C`struct ev_loop *\*(C'\fR. The library knows two
-types of such loops, the \fIdefault\fR loop, which supports signals and child
-events, and dynamically created loops which do not.
-.IP "struct ev_loop *ev_default_loop (unsigned int flags)" 4
-.IX Item "struct ev_loop *ev_default_loop (unsigned int flags)"
-This will initialise the default event loop if it hasn't been initialised
-yet and return it. If the default loop could not be initialised, returns
-false. If it already was initialised it simply returns it (and ignores the
-flags. If that is troubling you, check \f(CW\*(C`ev_backend ()\*(C'\fR afterwards).
-.Sp
-If you don't know what event loop to use, use the one returned from this
-function.
-.Sp
-Note that this function is \fInot\fR thread-safe, so if you want to use it
-from multiple threads, you have to lock (note also that this is unlikely,
-as loops cannot bes hared easily between threads anyway).
-.Sp
-The default loop is the only loop that can handle \f(CW\*(C`ev_signal\*(C'\fR and
-\&\f(CW\*(C`ev_child\*(C'\fR watchers, and to do this, it always registers a handler
-for \f(CW\*(C`SIGCHLD\*(C'\fR. If this is a problem for your app you can either
-create a dynamic loop with \f(CW\*(C`ev_loop_new\*(C'\fR that doesn't do that, or you
-can simply overwrite the \f(CW\*(C`SIGCHLD\*(C'\fR signal handler \fIafter\fR calling
-\&\f(CW\*(C`ev_default_init\*(C'\fR.
-.Sp
-The flags argument can be used to specify special behaviour or specific
-backends to use, and is usually specified as \f(CW0\fR (or \f(CW\*(C`EVFLAG_AUTO\*(C'\fR).
-.Sp
-The following flags are supported:
-.RS 4
-.ie n .IP """EVFLAG_AUTO""" 4
-.el .IP "\f(CWEVFLAG_AUTO\fR" 4
-.IX Item "EVFLAG_AUTO"
-The default flags value. Use this if you have no clue (it's the right
-thing, believe me).
-.ie n .IP """EVFLAG_NOENV""" 4
-.el .IP "\f(CWEVFLAG_NOENV\fR" 4
-.IX Item "EVFLAG_NOENV"
-If this flag bit is ored into the flag value (or the program runs setuid
-or setgid) then libev will \fInot\fR look at the environment variable
-\&\f(CW\*(C`LIBEV_FLAGS\*(C'\fR. Otherwise (the default), this environment variable will
-override the flags completely if it is found in the environment. This is
-useful to try out specific backends to test their performance, or to work
-around bugs.
-.ie n .IP """EVFLAG_FORKCHECK""" 4
-.el .IP "\f(CWEVFLAG_FORKCHECK\fR" 4
-.IX Item "EVFLAG_FORKCHECK"
-Instead of calling \f(CW\*(C`ev_default_fork\*(C'\fR or \f(CW\*(C`ev_loop_fork\*(C'\fR manually after
-a fork, you can also make libev check for a fork in each iteration by
-enabling this flag.
-.Sp
-This works by calling \f(CW\*(C`getpid ()\*(C'\fR on every iteration of the loop,
-and thus this might slow down your event loop if you do a lot of loop
-iterations and little real work, but is usually not noticeable (on my
-GNU/Linux system for example, \f(CW\*(C`getpid\*(C'\fR is actually a simple 5\-insn sequence
-without a syscall and thus \fIvery\fR fast, but my GNU/Linux system also has
-\&\f(CW\*(C`pthread_atfork\*(C'\fR which is even faster).
-.Sp
-The big advantage of this flag is that you can forget about fork (and
-forget about forgetting to tell libev about forking) when you use this
-flag.
-.Sp
-This flag setting cannot be overriden or specified in the \f(CW\*(C`LIBEV_FLAGS\*(C'\fR
-environment variable.
-.ie n .IP """EVBACKEND_SELECT"" (value 1, portable select backend)" 4
-.el .IP "\f(CWEVBACKEND_SELECT\fR (value 1, portable select backend)" 4
-.IX Item "EVBACKEND_SELECT (value 1, portable select backend)"
-This is your standard \fIselect\fR\|(2) backend. Not \fIcompletely\fR standard, as
-libev tries to roll its own fd_set with no limits on the number of fds,
-but if that fails, expect a fairly low limit on the number of fds when
-using this backend. It doesn't scale too well (O(highest_fd)), but its
-usually the fastest backend for a low number of (low-numbered :) fds.
-.Sp
-To get good performance out of this backend you need a high amount of
-parallelity (most of the file descriptors should be busy). If you are
-writing a server, you should \f(CW\*(C`accept ()\*(C'\fR in a loop to accept as many
-connections as possible during one iteration. You might also want to have
-a look at \f(CW\*(C`ev_set_io_collect_interval ()\*(C'\fR to increase the amount of
-readyness notifications you get per iteration.
-.ie n .IP """EVBACKEND_POLL"" (value 2, poll backend, available everywhere except on windows)" 4
-.el .IP "\f(CWEVBACKEND_POLL\fR (value 2, poll backend, available everywhere except on windows)" 4
-.IX Item "EVBACKEND_POLL (value 2, poll backend, available everywhere except on windows)"
-And this is your standard \fIpoll\fR\|(2) backend. It's more complicated
-than select, but handles sparse fds better and has no artificial
-limit on the number of fds you can use (except it will slow down
-considerably with a lot of inactive fds). It scales similarly to select,
-i.e. O(total_fds). See the entry for \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR, above, for
-performance tips.
-.ie n .IP """EVBACKEND_EPOLL"" (value 4, Linux)" 4
-.el .IP "\f(CWEVBACKEND_EPOLL\fR (value 4, Linux)" 4
-.IX Item "EVBACKEND_EPOLL (value 4, Linux)"
-For few fds, this backend is a bit little slower than poll and select,
-but it scales phenomenally better. While poll and select usually scale
-like O(total_fds) where n is the total number of fds (or the highest fd),
-epoll scales either O(1) or O(active_fds). The epoll design has a number
-of shortcomings, such as silently dropping events in some hard-to-detect
-cases and requiring a syscall per fd change, no fork support and bad
-support for dup.
-.Sp
-While stopping, setting and starting an I/O watcher in the same iteration
-will result in some caching, there is still a syscall per such incident
-(because the fd could point to a different file description now), so its
-best to avoid that. Also, \f(CW\*(C`dup ()\*(C'\fR'ed file descriptors might not work
-very well if you register events for both fds.
-.Sp
-Please note that epoll sometimes generates spurious notifications, so you
-need to use non-blocking I/O or other means to avoid blocking when no data
-(or space) is available.
-.Sp
-Best performance from this backend is achieved by not unregistering all
-watchers for a file descriptor until it has been closed, if possible, i.e.
-keep at least one watcher active per fd at all times.
-.Sp
-While nominally embeddeble in other event loops, this feature is broken in
-all kernel versions tested so far.
-.ie n .IP """EVBACKEND_KQUEUE"" (value 8, most \s-1BSD\s0 clones)" 4
-.el .IP "\f(CWEVBACKEND_KQUEUE\fR (value 8, most \s-1BSD\s0 clones)" 4
-.IX Item "EVBACKEND_KQUEUE (value 8, most BSD clones)"
-Kqueue deserves special mention, as at the time of this writing, it
-was broken on all BSDs except NetBSD (usually it doesn't work reliably
-with anything but sockets and pipes, except on Darwin, where of course
-it's completely useless). For this reason it's not being \*(L"autodetected\*(R"
-unless you explicitly specify it explicitly in the flags (i.e. using
-\&\f(CW\*(C`EVBACKEND_KQUEUE\*(C'\fR) or libev was compiled on a known-to-be-good (\-enough)
-system like NetBSD.
-.Sp
-You still can embed kqueue into a normal poll or select backend and use it
-only for sockets (after having made sure that sockets work with kqueue on
-the target platform). See \f(CW\*(C`ev_embed\*(C'\fR watchers for more info.
-.Sp
-It scales in the same way as the epoll backend, but the interface to the
-kernel is more efficient (which says nothing about its actual speed, of
-course). While stopping, setting and starting an I/O watcher does never
-cause an extra syscall as with \f(CW\*(C`EVBACKEND_EPOLL\*(C'\fR, it still adds up to
-two event changes per incident, support for \f(CW\*(C`fork ()\*(C'\fR is very bad and it
-drops fds silently in similarly hard-to-detect cases.
-.Sp
-This backend usually performs well under most conditions.
-.Sp
-While nominally embeddable in other event loops, this doesn't work
-everywhere, so you might need to test for this. And since it is broken
-almost everywhere, you should only use it when you have a lot of sockets
-(for which it usually works), by embedding it into another event loop
-(e.g. \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR) and using it only for
-sockets.
-.ie n .IP """EVBACKEND_DEVPOLL"" (value 16, Solaris 8)" 4
-.el .IP "\f(CWEVBACKEND_DEVPOLL\fR (value 16, Solaris 8)" 4
-.IX Item "EVBACKEND_DEVPOLL (value 16, Solaris 8)"
-This is not implemented yet (and might never be, unless you send me an
-implementation). According to reports, \f(CW\*(C`/dev/poll\*(C'\fR only supports sockets
-and is not embeddable, which would limit the usefulness of this backend
-immensely.
-.ie n .IP """EVBACKEND_PORT"" (value 32, Solaris 10)" 4
-.el .IP "\f(CWEVBACKEND_PORT\fR (value 32, Solaris 10)" 4
-.IX Item "EVBACKEND_PORT (value 32, Solaris 10)"
-This uses the Solaris 10 event port mechanism. As with everything on Solaris,
-it's really slow, but it still scales very well (O(active_fds)).
-.Sp
-Please note that solaris event ports can deliver a lot of spurious
-notifications, so you need to use non-blocking I/O or other means to avoid
-blocking when no data (or space) is available.
-.Sp
-While this backend scales well, it requires one system call per active
-file descriptor per loop iteration. For small and medium numbers of file
-descriptors a \*(L"slow\*(R" \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR backend
-might perform better.
-.Sp
-On the positive side, ignoring the spurious readyness notifications, this
-backend actually performed to specification in all tests and is fully
-embeddable, which is a rare feat among the OS-specific backends.
-.ie n .IP """EVBACKEND_ALL""" 4
-.el .IP "\f(CWEVBACKEND_ALL\fR" 4
-.IX Item "EVBACKEND_ALL"
-Try all backends (even potentially broken ones that wouldn't be tried
-with \f(CW\*(C`EVFLAG_AUTO\*(C'\fR). Since this is a mask, you can do stuff such as
-\&\f(CW\*(C`EVBACKEND_ALL & ~EVBACKEND_KQUEUE\*(C'\fR.
-.Sp
-It is definitely not recommended to use this flag.
-.RE
-.RS 4
-.Sp
-If one or more of these are ored into the flags value, then only these
-backends will be tried (in the reverse order as listed here). If none are
-specified, all backends in \f(CW\*(C`ev_recommended_backends ()\*(C'\fR will be tried.
-.Sp
-The most typical usage is like this:
-.Sp
-.Vb 2
-\& if (!ev_default_loop (0))
-\& fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?");
-.Ve
-.Sp
-Restrict libev to the select and poll backends, and do not allow
-environment settings to be taken into account:
-.Sp
-.Vb 1
-\& ev_default_loop (EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV);
-.Ve
-.Sp
-Use whatever libev has to offer, but make sure that kqueue is used if
-available (warning, breaks stuff, best use only with your own private
-event loop and only if you know the \s-1OS\s0 supports your types of fds):
-.Sp
-.Vb 1
-\& ev_default_loop (ev_recommended_backends () | EVBACKEND_KQUEUE);
-.Ve
-.RE
-.IP "struct ev_loop *ev_loop_new (unsigned int flags)" 4
-.IX Item "struct ev_loop *ev_loop_new (unsigned int flags)"
-Similar to \f(CW\*(C`ev_default_loop\*(C'\fR, but always creates a new event loop that is
-always distinct from the default loop. Unlike the default loop, it cannot
-handle signal and child watchers, and attempts to do so will be greeted by
-undefined behaviour (or a failed assertion if assertions are enabled).
-.Sp
-Note that this function \fIis\fR thread-safe, and the recommended way to use
-libev with threads is indeed to create one loop per thread, and using the
-default loop in the \*(L"main\*(R" or \*(L"initial\*(R" thread.
-.Sp
-Example: Try to create a event loop that uses epoll and nothing else.
-.Sp
-.Vb 3
-\& struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV);
-\& if (!epoller)
-\& fatal ("no epoll found here, maybe it hides under your chair");
-.Ve
-.IP "ev_default_destroy ()" 4
-.IX Item "ev_default_destroy ()"
-Destroys the default loop again (frees all memory and kernel state
-etc.). None of the active event watchers will be stopped in the normal
-sense, so e.g. \f(CW\*(C`ev_is_active\*(C'\fR might still return true. It is your
-responsibility to either stop all watchers cleanly yoursef \fIbefore\fR
-calling this function, or cope with the fact afterwards (which is usually
-the easiest thing, you can just ignore the watchers and/or \f(CW\*(C`free ()\*(C'\fR them
-for example).
-.Sp
-Note that certain global state, such as signal state, will not be freed by
-this function, and related watchers (such as signal and child watchers)
-would need to be stopped manually.
-.Sp
-In general it is not advisable to call this function except in the
-rare occasion where you really need to free e.g. the signal handling
-pipe fds. If you need dynamically allocated loops it is better to use
-\&\f(CW\*(C`ev_loop_new\*(C'\fR and \f(CW\*(C`ev_loop_destroy\*(C'\fR).
-.IP "ev_loop_destroy (loop)" 4
-.IX Item "ev_loop_destroy (loop)"
-Like \f(CW\*(C`ev_default_destroy\*(C'\fR, but destroys an event loop created by an
-earlier call to \f(CW\*(C`ev_loop_new\*(C'\fR.
-.IP "ev_default_fork ()" 4
-.IX Item "ev_default_fork ()"
-This function sets a flag that causes subsequent \f(CW\*(C`ev_loop\*(C'\fR iterations
-to reinitialise the kernel state for backends that have one. Despite the
-name, you can call it anytime, but it makes most sense after forking, in
-the child process (or both child and parent, but that again makes little
-sense). You \fImust\fR call it in the child before using any of the libev
-functions, and it will only take effect at the next \f(CW\*(C`ev_loop\*(C'\fR iteration.
-.Sp
-On the other hand, you only need to call this function in the child
-process if and only if you want to use the event library in the child. If
-you just fork+exec, you don't have to call it at all.
-.Sp
-The function itself is quite fast and it's usually not a problem to call
-it just in case after a fork. To make this easy, the function will fit in
-quite nicely into a call to \f(CW\*(C`pthread_atfork\*(C'\fR:
-.Sp
-.Vb 1
-\& pthread_atfork (0, 0, ev_default_fork);
-.Ve
-.IP "ev_loop_fork (loop)" 4
-.IX Item "ev_loop_fork (loop)"
-Like \f(CW\*(C`ev_default_fork\*(C'\fR, but acts on an event loop created by
-\&\f(CW\*(C`ev_loop_new\*(C'\fR. Yes, you have to call this on every allocated event loop
-after fork, and how you do this is entirely your own problem.
-.IP "int ev_is_default_loop (loop)" 4
-.IX Item "int ev_is_default_loop (loop)"
-Returns true when the given loop actually is the default loop, false otherwise.
-.IP "unsigned int ev_loop_count (loop)" 4
-.IX Item "unsigned int ev_loop_count (loop)"
-Returns the count of loop iterations for the loop, which is identical to
-the number of times libev did poll for new events. It starts at \f(CW0\fR and
-happily wraps around with enough iterations.
-.Sp
-This value can sometimes be useful as a generation counter of sorts (it
-\&\*(L"ticks\*(R" the number of loop iterations), as it roughly corresponds with
-\&\f(CW\*(C`ev_prepare\*(C'\fR and \f(CW\*(C`ev_check\*(C'\fR calls.
-.IP "unsigned int ev_backend (loop)" 4
-.IX Item "unsigned int ev_backend (loop)"
-Returns one of the \f(CW\*(C`EVBACKEND_*\*(C'\fR flags indicating the event backend in
-use.
-.IP "ev_tstamp ev_now (loop)" 4
-.IX Item "ev_tstamp ev_now (loop)"
-Returns the current \*(L"event loop time\*(R", which is the time the event loop
-received events and started processing them. This timestamp does not
-change as long as callbacks are being processed, and this is also the base
-time used for relative timers. You can treat it as the timestamp of the
-event occurring (or more correctly, libev finding out about it).
-.IP "ev_loop (loop, int flags)" 4
-.IX Item "ev_loop (loop, int flags)"
-Finally, this is it, the event handler. This function usually is called
-after you initialised all your watchers and you want to start handling
-events.
-.Sp
-If the flags argument is specified as \f(CW0\fR, it will not return until
-either no event watchers are active anymore or \f(CW\*(C`ev_unloop\*(C'\fR was called.
-.Sp
-Please note that an explicit \f(CW\*(C`ev_unloop\*(C'\fR is usually better than
-relying on all watchers to be stopped when deciding when a program has
-finished (especially in interactive programs), but having a program that
-automatically loops as long as it has to and no longer by virtue of
-relying on its watchers stopping correctly is a thing of beauty.
-.Sp
-A flags value of \f(CW\*(C`EVLOOP_NONBLOCK\*(C'\fR will look for new events, will handle
-those events and any outstanding ones, but will not block your process in
-case there are no events and will return after one iteration of the loop.
-.Sp
-A flags value of \f(CW\*(C`EVLOOP_ONESHOT\*(C'\fR will look for new events (waiting if
-neccessary) and will handle those and any outstanding ones. It will block
-your process until at least one new event arrives, and will return after
-one iteration of the loop. This is useful if you are waiting for some
-external event in conjunction with something not expressible using other
-libev watchers. However, a pair of \f(CW\*(C`ev_prepare\*(C'\fR/\f(CW\*(C`ev_check\*(C'\fR watchers is
-usually a better approach for this kind of thing.
-.Sp
-Here are the gory details of what \f(CW\*(C`ev_loop\*(C'\fR does:
-.Sp
-.Vb 10
-\& \- Before the first iteration, call any pending watchers.
-\& * If EVFLAG_FORKCHECK was used, check for a fork.
-\& \- If a fork was detected, queue and call all fork watchers.
-\& \- Queue and call all prepare watchers.
-\& \- If we have been forked, recreate the kernel state.
-\& \- Update the kernel state with all outstanding changes.
-\& \- Update the "event loop time".
-\& \- Calculate for how long to sleep or block, if at all
-\& (active idle watchers, EVLOOP_NONBLOCK or not having
-\& any active watchers at all will result in not sleeping).
-\& \- Sleep if the I/O and timer collect interval say so.
-\& \- Block the process, waiting for any events.
-\& \- Queue all outstanding I/O (fd) events.
-\& \- Update the "event loop time" and do time jump handling.
-\& \- Queue all outstanding timers.
-\& \- Queue all outstanding periodics.
-\& \- If no events are pending now, queue all idle watchers.
-\& \- Queue all check watchers.
-\& \- Call all queued watchers in reverse order (i.e. check watchers first).
-\& Signals and child watchers are implemented as I/O watchers, and will
-\& be handled here by queueing them when their watcher gets executed.
-\& \- If ev_unloop has been called, or EVLOOP_ONESHOT or EVLOOP_NONBLOCK
-\& were used, or there are no active watchers, return, otherwise
-\& continue with step *.
-.Ve
-.Sp
-Example: Queue some jobs and then loop until no events are outstanding
-anymore.
-.Sp
-.Vb 4
-\& ... queue jobs here, make sure they register event watchers as long
-\& ... as they still have work to do (even an idle watcher will do..)
-\& ev_loop (my_loop, 0);
-\& ... jobs done. yeah!
-.Ve
-.IP "ev_unloop (loop, how)" 4
-.IX Item "ev_unloop (loop, how)"
-Can be used to make a call to \f(CW\*(C`ev_loop\*(C'\fR return early (but only after it
-has processed all outstanding events). The \f(CW\*(C`how\*(C'\fR argument must be either
-\&\f(CW\*(C`EVUNLOOP_ONE\*(C'\fR, which will make the innermost \f(CW\*(C`ev_loop\*(C'\fR call return, or
-\&\f(CW\*(C`EVUNLOOP_ALL\*(C'\fR, which will make all nested \f(CW\*(C`ev_loop\*(C'\fR calls return.
-.Sp
-This \*(L"unloop state\*(R" will be cleared when entering \f(CW\*(C`ev_loop\*(C'\fR again.
-.IP "ev_ref (loop)" 4
-.IX Item "ev_ref (loop)"
-.PD 0
-.IP "ev_unref (loop)" 4
-.IX Item "ev_unref (loop)"
-.PD
-Ref/unref can be used to add or remove a reference count on the event
-loop: Every watcher keeps one reference, and as long as the reference
-count is nonzero, \f(CW\*(C`ev_loop\*(C'\fR will not return on its own. If you have
-a watcher you never unregister that should not keep \f(CW\*(C`ev_loop\*(C'\fR from
-returning, \fIev_unref()\fR after starting, and \fIev_ref()\fR before stopping it. For
-example, libev itself uses this for its internal signal pipe: It is not
-visible to the libev user and should not keep \f(CW\*(C`ev_loop\*(C'\fR from exiting if
-no event watchers registered by it are active. It is also an excellent
-way to do this for generic recurring timers or from within third-party
-libraries. Just remember to \fIunref after start\fR and \fIref before stop\fR
-(but only if the watcher wasn't active before, or was active before,
-respectively).
-.Sp
-Example: Create a signal watcher, but keep it from keeping \f(CW\*(C`ev_loop\*(C'\fR
-running when nothing else is active.
-.Sp
-.Vb 4
-\& struct ev_signal exitsig;
-\& ev_signal_init (&exitsig, sig_cb, SIGINT);
-\& ev_signal_start (loop, &exitsig);
-\& evf_unref (loop);
-.Ve
-.Sp
-Example: For some weird reason, unregister the above signal handler again.
-.Sp
-.Vb 2
-\& ev_ref (loop);
-\& ev_signal_stop (loop, &exitsig);
-.Ve
-.IP "ev_set_io_collect_interval (loop, ev_tstamp interval)" 4
-.IX Item "ev_set_io_collect_interval (loop, ev_tstamp interval)"
-.PD 0
-.IP "ev_set_timeout_collect_interval (loop, ev_tstamp interval)" 4
-.IX Item "ev_set_timeout_collect_interval (loop, ev_tstamp interval)"
-.PD
-These advanced functions influence the time that libev will spend waiting
-for events. Both are by default \f(CW0\fR, meaning that libev will try to
-invoke timer/periodic callbacks and I/O callbacks with minimum latency.
-.Sp
-Setting these to a higher value (the \f(CW\*(C`interval\*(C'\fR \fImust\fR be >= \f(CW0\fR)
-allows libev to delay invocation of I/O and timer/periodic callbacks to
-increase efficiency of loop iterations.
-.Sp
-The background is that sometimes your program runs just fast enough to
-handle one (or very few) event(s) per loop iteration. While this makes
-the program responsive, it also wastes a lot of \s-1CPU\s0 time to poll for new
-events, especially with backends like \f(CW\*(C`select ()\*(C'\fR which have a high
-overhead for the actual polling but can deliver many events at once.
-.Sp
-By setting a higher \fIio collect interval\fR you allow libev to spend more
-time collecting I/O events, so you can handle more events per iteration,
-at the cost of increasing latency. Timeouts (both \f(CW\*(C`ev_periodic\*(C'\fR and
-\&\f(CW\*(C`ev_timer\*(C'\fR) will be not affected. Setting this to a non-null value will
-introduce an additional \f(CW\*(C`ev_sleep ()\*(C'\fR call into most loop iterations.
-.Sp
-Likewise, by setting a higher \fItimeout collect interval\fR you allow libev
-to spend more time collecting timeouts, at the expense of increased
-latency (the watcher callback will be called later). \f(CW\*(C`ev_io\*(C'\fR watchers
-will not be affected. Setting this to a non-null value will not introduce
-any overhead in libev.
-.Sp
-Many (busy) programs can usually benefit by setting the io collect
-interval to a value near \f(CW0.1\fR or so, which is often enough for
-interactive servers (of course not for games), likewise for timeouts. It
-usually doesn't make much sense to set it to a lower value than \f(CW0.01\fR,
-as this approsaches the timing granularity of most systems.
-.SH "ANATOMY OF A WATCHER"
-.IX Header "ANATOMY OF A WATCHER"
-A watcher is a structure that you create and register to record your
-interest in some event. For instance, if you want to wait for \s-1STDIN\s0 to
-become readable, you would create an \f(CW\*(C`ev_io\*(C'\fR watcher for that:
-.PP
-.Vb 5
-\& static void my_cb (struct ev_loop *loop, struct ev_io *w, int revents)
-\& {
-\& ev_io_stop (w);
-\& ev_unloop (loop, EVUNLOOP_ALL);
-\& }
-\&
-\& struct ev_loop *loop = ev_default_loop (0);
-\& struct ev_io stdin_watcher;
-\& ev_init (&stdin_watcher, my_cb);
-\& ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ);
-\& ev_io_start (loop, &stdin_watcher);
-\& ev_loop (loop, 0);
-.Ve
-.PP
-As you can see, you are responsible for allocating the memory for your
-watcher structures (and it is usually a bad idea to do this on the stack,
-although this can sometimes be quite valid).
-.PP
-Each watcher structure must be initialised by a call to \f(CW\*(C`ev_init
-(watcher *, callback)\*(C'\fR, which expects a callback to be provided. This
-callback gets invoked each time the event occurs (or, in the case of io
-watchers, each time the event loop detects that the file descriptor given
-is readable and/or writable).
-.PP
-Each watcher type has its own \f(CW\*(C`ev_<type>_set (watcher *, ...)\*(C'\fR macro
-with arguments specific to this watcher type. There is also a macro
-to combine initialisation and setting in one call: \f(CW\*(C`ev_<type>_init
-(watcher *, callback, ...)\*(C'\fR.
-.PP
-To make the watcher actually watch out for events, you have to start it
-with a watcher-specific start function (\f(CW\*(C`ev_<type>_start (loop, watcher
-*)\*(C'\fR), and you can stop watching for events at any time by calling the
-corresponding stop function (\f(CW\*(C`ev_<type>_stop (loop, watcher *)\*(C'\fR.
-.PP
-As long as your watcher is active (has been started but not stopped) you
-must not touch the values stored in it. Most specifically you must never
-reinitialise it or call its \f(CW\*(C`set\*(C'\fR macro.
-.PP
-Each and every callback receives the event loop pointer as first, the
-registered watcher structure as second, and a bitset of received events as
-third argument.
-.PP
-The received events usually include a single bit per event type received
-(you can receive multiple events at the same time). The possible bit masks
-are:
-.ie n .IP """EV_READ""" 4
-.el .IP "\f(CWEV_READ\fR" 4
-.IX Item "EV_READ"
-.PD 0
-.ie n .IP """EV_WRITE""" 4
-.el .IP "\f(CWEV_WRITE\fR" 4
-.IX Item "EV_WRITE"
-.PD
-The file descriptor in the \f(CW\*(C`ev_io\*(C'\fR watcher has become readable and/or
-writable.
-.ie n .IP """EV_TIMEOUT""" 4
-.el .IP "\f(CWEV_TIMEOUT\fR" 4
-.IX Item "EV_TIMEOUT"
-The \f(CW\*(C`ev_timer\*(C'\fR watcher has timed out.
-.ie n .IP """EV_PERIODIC""" 4
-.el .IP "\f(CWEV_PERIODIC\fR" 4
-.IX Item "EV_PERIODIC"
-The \f(CW\*(C`ev_periodic\*(C'\fR watcher has timed out.
-.ie n .IP """EV_SIGNAL""" 4
-.el .IP "\f(CWEV_SIGNAL\fR" 4
-.IX Item "EV_SIGNAL"
-The signal specified in the \f(CW\*(C`ev_signal\*(C'\fR watcher has been received by a thread.
-.ie n .IP """EV_CHILD""" 4
-.el .IP "\f(CWEV_CHILD\fR" 4
-.IX Item "EV_CHILD"
-The pid specified in the \f(CW\*(C`ev_child\*(C'\fR watcher has received a status change.
-.ie n .IP """EV_STAT""" 4
-.el .IP "\f(CWEV_STAT\fR" 4
-.IX Item "EV_STAT"
-The path specified in the \f(CW\*(C`ev_stat\*(C'\fR watcher changed its attributes somehow.
-.ie n .IP """EV_IDLE""" 4
-.el .IP "\f(CWEV_IDLE\fR" 4
-.IX Item "EV_IDLE"
-The \f(CW\*(C`ev_idle\*(C'\fR watcher has determined that you have nothing better to do.
-.ie n .IP """EV_PREPARE""" 4
-.el .IP "\f(CWEV_PREPARE\fR" 4
-.IX Item "EV_PREPARE"
-.PD 0
-.ie n .IP """EV_CHECK""" 4
-.el .IP "\f(CWEV_CHECK\fR" 4
-.IX Item "EV_CHECK"
-.PD
-All \f(CW\*(C`ev_prepare\*(C'\fR watchers are invoked just \fIbefore\fR \f(CW\*(C`ev_loop\*(C'\fR starts
-to gather new events, and all \f(CW\*(C`ev_check\*(C'\fR watchers are invoked just after
-\&\f(CW\*(C`ev_loop\*(C'\fR has gathered them, but before it invokes any callbacks for any
-received events. Callbacks of both watcher types can start and stop as
-many watchers as they want, and all of them will be taken into account
-(for example, a \f(CW\*(C`ev_prepare\*(C'\fR watcher might start an idle watcher to keep
-\&\f(CW\*(C`ev_loop\*(C'\fR from blocking).
-.ie n .IP """EV_EMBED""" 4
-.el .IP "\f(CWEV_EMBED\fR" 4
-.IX Item "EV_EMBED"
-The embedded event loop specified in the \f(CW\*(C`ev_embed\*(C'\fR watcher needs attention.
-.ie n .IP """EV_FORK""" 4
-.el .IP "\f(CWEV_FORK\fR" 4
-.IX Item "EV_FORK"
-The event loop has been resumed in the child process after fork (see
-\&\f(CW\*(C`ev_fork\*(C'\fR).
-.ie n .IP """EV_ASYNC""" 4
-.el .IP "\f(CWEV_ASYNC\fR" 4
-.IX Item "EV_ASYNC"
-The given async watcher has been asynchronously notified (see \f(CW\*(C`ev_async\*(C'\fR).
-.ie n .IP """EV_ERROR""" 4
-.el .IP "\f(CWEV_ERROR\fR" 4
-.IX Item "EV_ERROR"
-An unspecified error has occured, the watcher has been stopped. This might
-happen because the watcher could not be properly started because libev
-ran out of memory, a file descriptor was found to be closed or any other
-problem. You best act on it by reporting the problem and somehow coping
-with the watcher being stopped.
-.Sp
-Libev will usually signal a few \*(L"dummy\*(R" events together with an error,
-for example it might indicate that a fd is readable or writable, and if
-your callbacks is well-written it can just attempt the operation and cope
-with the error from \fIread()\fR or \fIwrite()\fR. This will not work in multithreaded
-programs, though, so beware.
-.Sh "\s-1GENERIC\s0 \s-1WATCHER\s0 \s-1FUNCTIONS\s0"
-.IX Subsection "GENERIC WATCHER FUNCTIONS"
-In the following description, \f(CW\*(C`TYPE\*(C'\fR stands for the watcher type,
-e.g. \f(CW\*(C`timer\*(C'\fR for \f(CW\*(C`ev_timer\*(C'\fR watchers and \f(CW\*(C`io\*(C'\fR for \f(CW\*(C`ev_io\*(C'\fR watchers.
-.ie n .IP """ev_init"" (ev_TYPE *watcher, callback)" 4
-.el .IP "\f(CWev_init\fR (ev_TYPE *watcher, callback)" 4
-.IX Item "ev_init (ev_TYPE *watcher, callback)"
-This macro initialises the generic portion of a watcher. The contents
-of the watcher object can be arbitrary (so \f(CW\*(C`malloc\*(C'\fR will do). Only
-the generic parts of the watcher are initialised, you \fIneed\fR to call
-the type-specific \f(CW\*(C`ev_TYPE_set\*(C'\fR macro afterwards to initialise the
-type-specific parts. For each type there is also a \f(CW\*(C`ev_TYPE_init\*(C'\fR macro
-which rolls both calls into one.
-.Sp
-You can reinitialise a watcher at any time as long as it has been stopped
-(or never started) and there are no pending events outstanding.
-.Sp
-The callback is always of type \f(CW\*(C`void (*)(ev_loop *loop, ev_TYPE *watcher,
-int revents)\*(C'\fR.
-.ie n .IP """ev_TYPE_set"" (ev_TYPE *, [args])" 4
-.el .IP "\f(CWev_TYPE_set\fR (ev_TYPE *, [args])" 4
-.IX Item "ev_TYPE_set (ev_TYPE *, [args])"
-This macro initialises the type-specific parts of a watcher. You need to
-call \f(CW\*(C`ev_init\*(C'\fR at least once before you call this macro, but you can
-call \f(CW\*(C`ev_TYPE_set\*(C'\fR any number of times. You must not, however, call this
-macro on a watcher that is active (it can be pending, however, which is a
-difference to the \f(CW\*(C`ev_init\*(C'\fR macro).
-.Sp
-Although some watcher types do not have type-specific arguments
-(e.g. \f(CW\*(C`ev_prepare\*(C'\fR) you still need to call its \f(CW\*(C`set\*(C'\fR macro.
-.ie n .IP """ev_TYPE_init"" (ev_TYPE *watcher, callback, [args])" 4
-.el .IP "\f(CWev_TYPE_init\fR (ev_TYPE *watcher, callback, [args])" 4
-.IX Item "ev_TYPE_init (ev_TYPE *watcher, callback, [args])"
-This convinience macro rolls both \f(CW\*(C`ev_init\*(C'\fR and \f(CW\*(C`ev_TYPE_set\*(C'\fR macro
-calls into a single call. This is the most convinient method to initialise
-a watcher. The same limitations apply, of course.
-.ie n .IP """ev_TYPE_start"" (loop *, ev_TYPE *watcher)" 4
-.el .IP "\f(CWev_TYPE_start\fR (loop *, ev_TYPE *watcher)" 4
-.IX Item "ev_TYPE_start (loop *, ev_TYPE *watcher)"
-Starts (activates) the given watcher. Only active watchers will receive
-events. If the watcher is already active nothing will happen.
-.ie n .IP """ev_TYPE_stop"" (loop *, ev_TYPE *watcher)" 4
-.el .IP "\f(CWev_TYPE_stop\fR (loop *, ev_TYPE *watcher)" 4
-.IX Item "ev_TYPE_stop (loop *, ev_TYPE *watcher)"
-Stops the given watcher again (if active) and clears the pending
-status. It is possible that stopped watchers are pending (for example,
-non-repeating timers are being stopped when they become pending), but
-\&\f(CW\*(C`ev_TYPE_stop\*(C'\fR ensures that the watcher is neither active nor pending. If
-you want to free or reuse the memory used by the watcher it is therefore a
-good idea to always call its \f(CW\*(C`ev_TYPE_stop\*(C'\fR function.
-.IP "bool ev_is_active (ev_TYPE *watcher)" 4
-.IX Item "bool ev_is_active (ev_TYPE *watcher)"
-Returns a true value iff the watcher is active (i.e. it has been started
-and not yet been stopped). As long as a watcher is active you must not modify
-it.
-.IP "bool ev_is_pending (ev_TYPE *watcher)" 4
-.IX Item "bool ev_is_pending (ev_TYPE *watcher)"
-Returns a true value iff the watcher is pending, (i.e. it has outstanding
-events but its callback has not yet been invoked). As long as a watcher
-is pending (but not active) you must not call an init function on it (but
-\&\f(CW\*(C`ev_TYPE_set\*(C'\fR is safe), you must not change its priority, and you must
-make sure the watcher is available to libev (e.g. you cannot \f(CW\*(C`free ()\*(C'\fR
-it).
-.IP "callback ev_cb (ev_TYPE *watcher)" 4
-.IX Item "callback ev_cb (ev_TYPE *watcher)"
-Returns the callback currently set on the watcher.
-.IP "ev_cb_set (ev_TYPE *watcher, callback)" 4
-.IX Item "ev_cb_set (ev_TYPE *watcher, callback)"
-Change the callback. You can change the callback at virtually any time
-(modulo threads).
-.IP "ev_set_priority (ev_TYPE *watcher, priority)" 4
-.IX Item "ev_set_priority (ev_TYPE *watcher, priority)"
-.PD 0
-.IP "int ev_priority (ev_TYPE *watcher)" 4
-.IX Item "int ev_priority (ev_TYPE *watcher)"
-.PD
-Set and query the priority of the watcher. The priority is a small
-integer between \f(CW\*(C`EV_MAXPRI\*(C'\fR (default: \f(CW2\fR) and \f(CW\*(C`EV_MINPRI\*(C'\fR
-(default: \f(CW\*(C`\-2\*(C'\fR). Pending watchers with higher priority will be invoked
-before watchers with lower priority, but priority will not keep watchers
-from being executed (except for \f(CW\*(C`ev_idle\*(C'\fR watchers).
-.Sp
-This means that priorities are \fIonly\fR used for ordering callback
-invocation after new events have been received. This is useful, for
-example, to reduce latency after idling, or more often, to bind two
-watchers on the same event and make sure one is called first.
-.Sp
-If you need to suppress invocation when higher priority events are pending
-you need to look at \f(CW\*(C`ev_idle\*(C'\fR watchers, which provide this functionality.
-.Sp
-You \fImust not\fR change the priority of a watcher as long as it is active or
-pending.
-.Sp
-The default priority used by watchers when no priority has been set is
-always \f(CW0\fR, which is supposed to not be too high and not be too low :).
-.Sp
-Setting a priority outside the range of \f(CW\*(C`EV_MINPRI\*(C'\fR to \f(CW\*(C`EV_MAXPRI\*(C'\fR is
-fine, as long as you do not mind that the priority value you query might
-or might not have been adjusted to be within valid range.
-.IP "ev_invoke (loop, ev_TYPE *watcher, int revents)" 4
-.IX Item "ev_invoke (loop, ev_TYPE *watcher, int revents)"
-Invoke the \f(CW\*(C`watcher\*(C'\fR with the given \f(CW\*(C`loop\*(C'\fR and \f(CW\*(C`revents\*(C'\fR. Neither
-\&\f(CW\*(C`loop\*(C'\fR nor \f(CW\*(C`revents\*(C'\fR need to be valid as long as the watcher callback
-can deal with that fact.
-.IP "int ev_clear_pending (loop, ev_TYPE *watcher)" 4
-.IX Item "int ev_clear_pending (loop, ev_TYPE *watcher)"
-If the watcher is pending, this function returns clears its pending status
-and returns its \f(CW\*(C`revents\*(C'\fR bitset (as if its callback was invoked). If the
-watcher isn't pending it does nothing and returns \f(CW0\fR.
-.Sh "\s-1ASSOCIATING\s0 \s-1CUSTOM\s0 \s-1DATA\s0 \s-1WITH\s0 A \s-1WATCHER\s0"
-.IX Subsection "ASSOCIATING CUSTOM DATA WITH A WATCHER"
-Each watcher has, by default, a member \f(CW\*(C`void *data\*(C'\fR that you can change
-and read at any time, libev will completely ignore it. This can be used
-to associate arbitrary data with your watcher. If you need more data and
-don't want to allocate memory and store a pointer to it in that data
-member, you can also \*(L"subclass\*(R" the watcher type and provide your own
-data:
-.PP
-.Vb 7
-\& struct my_io
-\& {
-\& struct ev_io io;
-\& int otherfd;
-\& void *somedata;
-\& struct whatever *mostinteresting;
-\& }
-.Ve
-.PP
-And since your callback will be called with a pointer to the watcher, you
-can cast it back to your own type:
-.PP
-.Vb 5
-\& static void my_cb (struct ev_loop *loop, struct ev_io *w_, int revents)
-\& {
-\& struct my_io *w = (struct my_io *)w_;
-\& ...
-\& }
-.Ve
-.PP
-More interesting and less C\-conformant ways of casting your callback type
-instead have been omitted.
-.PP
-Another common scenario is having some data structure with multiple
-watchers:
-.PP
-.Vb 6
-\& struct my_biggy
-\& {
-\& int some_data;
-\& ev_timer t1;
-\& ev_timer t2;
-\& }
-.Ve
-.PP
-In this case getting the pointer to \f(CW\*(C`my_biggy\*(C'\fR is a bit more complicated,
-you need to use \f(CW\*(C`offsetof\*(C'\fR:
-.PP
-.Vb 1
-\& #include <stddef.h>
-\&
-\& static void
-\& t1_cb (EV_P_ struct ev_timer *w, int revents)
-\& {
-\& struct my_biggy big = (struct my_biggy *
-\& (((char *)w) \- offsetof (struct my_biggy, t1));
-\& }
-\&
-\& static void
-\& t2_cb (EV_P_ struct ev_timer *w, int revents)
-\& {
-\& struct my_biggy big = (struct my_biggy *
-\& (((char *)w) \- offsetof (struct my_biggy, t2));
-\& }
-.Ve
-.SH "WATCHER TYPES"
-.IX Header "WATCHER TYPES"
-This section describes each watcher in detail, but will not repeat
-information given in the last section. Any initialisation/set macros,
-functions and members specific to the watcher type are explained.
-.PP
-Members are additionally marked with either \fI[read\-only]\fR, meaning that,
-while the watcher is active, you can look at the member and expect some
-sensible content, but you must not modify it (you can modify it while the
-watcher is stopped to your hearts content), or \fI[read\-write]\fR, which
-means you can expect it to have some sensible content while the watcher
-is active, but you can also modify it. Modifying it may not do something
-sensible or take immediate effect (or do anything at all), but libev will
-not crash or malfunction in any way.
-.ie n .Sh """ev_io"" \- is this file descriptor readable or writable?"
-.el .Sh "\f(CWev_io\fP \- is this file descriptor readable or writable?"
-.IX Subsection "ev_io - is this file descriptor readable or writable?"
-I/O watchers check whether a file descriptor is readable or writable
-in each iteration of the event loop, or, more precisely, when reading
-would not block the process and writing would at least be able to write
-some data. This behaviour is called level-triggering because you keep
-receiving events as long as the condition persists. Remember you can stop
-the watcher if you don't want to act on the event and neither want to
-receive future events.
-.PP
-In general you can register as many read and/or write event watchers per
-fd as you want (as long as you don't confuse yourself). Setting all file
-descriptors to non-blocking mode is also usually a good idea (but not
-required if you know what you are doing).
-.PP
-If you must do this, then force the use of a known-to-be-good backend
-(at the time of this writing, this includes only \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR and
-\&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR).
-.PP
-Another thing you have to watch out for is that it is quite easy to
-receive \*(L"spurious\*(R" readyness notifications, that is your callback might
-be called with \f(CW\*(C`EV_READ\*(C'\fR but a subsequent \f(CW\*(C`read\*(C'\fR(2) will actually block
-because there is no data. Not only are some backends known to create a
-lot of those (for example solaris ports), it is very easy to get into
-this situation even with a relatively standard program structure. Thus
-it is best to always use non-blocking I/O: An extra \f(CW\*(C`read\*(C'\fR(2) returning
-\&\f(CW\*(C`EAGAIN\*(C'\fR is far preferable to a program hanging until some data arrives.
-.PP
-If you cannot run the fd in non-blocking mode (for example you should not
-play around with an Xlib connection), then you have to seperately re-test
-whether a file descriptor is really ready with a known-to-be good interface
-such as poll (fortunately in our Xlib example, Xlib already does this on
-its own, so its quite safe to use).
-.PP
-\fIThe special problem of disappearing file descriptors\fR
-.IX Subsection "The special problem of disappearing file descriptors"
-.PP
-Some backends (e.g. kqueue, epoll) need to be told about closing a file
-descriptor (either by calling \f(CW\*(C`close\*(C'\fR explicitly or by any other means,
-such as \f(CW\*(C`dup\*(C'\fR). The reason is that you register interest in some file
-descriptor, but when it goes away, the operating system will silently drop
-this interest. If another file descriptor with the same number then is
-registered with libev, there is no efficient way to see that this is, in
-fact, a different file descriptor.
-.PP
-To avoid having to explicitly tell libev about such cases, libev follows
-the following policy: Each time \f(CW\*(C`ev_io_set\*(C'\fR is being called, libev
-will assume that this is potentially a new file descriptor, otherwise
-it is assumed that the file descriptor stays the same. That means that
-you \fIhave\fR to call \f(CW\*(C`ev_io_set\*(C'\fR (or \f(CW\*(C`ev_io_init\*(C'\fR) when you change the
-descriptor even if the file descriptor number itself did not change.
-.PP
-This is how one would do it normally anyway, the important point is that
-the libev application should not optimise around libev but should leave
-optimisations to libev.
-.PP
-\fIThe special problem of dup'ed file descriptors\fR
-.IX Subsection "The special problem of dup'ed file descriptors"
-.PP
-Some backends (e.g. epoll), cannot register events for file descriptors,
-but only events for the underlying file descriptions. That means when you
-have \f(CW\*(C`dup ()\*(C'\fR'ed file descriptors or weirder constellations, and register
-events for them, only one file descriptor might actually receive events.
-.PP
-There is no workaround possible except not registering events
-for potentially \f(CW\*(C`dup ()\*(C'\fR'ed file descriptors, or to resort to
-\&\f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
-.PP
-\fIThe special problem of fork\fR
-.IX Subsection "The special problem of fork"
-.PP
-Some backends (epoll, kqueue) do not support \f(CW\*(C`fork ()\*(C'\fR at all or exhibit
-useless behaviour. Libev fully supports fork, but needs to be told about
-it in the child.
-.PP
-To support fork in your programs, you either have to call
-\&\f(CW\*(C`ev_default_fork ()\*(C'\fR or \f(CW\*(C`ev_loop_fork ()\*(C'\fR after a fork in the child,
-enable \f(CW\*(C`EVFLAG_FORKCHECK\*(C'\fR, or resort to \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or
-\&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
-.PP
-\fIThe special problem of \s-1SIGPIPE\s0\fR
-.IX Subsection "The special problem of SIGPIPE"
-.PP
-While not really specific to libev, it is easy to forget about \s-1SIGPIPE:\s0
-when reading from a pipe whose other end has been closed, your program
-gets send a \s-1SIGPIPE\s0, which, by default, aborts your program. For most
-programs this is sensible behaviour, for daemons, this is usually
-undesirable.
-.PP
-So when you encounter spurious, unexplained daemon exits, make sure you
-ignore \s-1SIGPIPE\s0 (and maybe make sure you log the exit status of your daemon
-somewhere, as that would have given you a big clue).
-.PP
-\fIWatcher-Specific Functions\fR
-.IX Subsection "Watcher-Specific Functions"
-.IP "ev_io_init (ev_io *, callback, int fd, int events)" 4
-.IX Item "ev_io_init (ev_io *, callback, int fd, int events)"
-.PD 0
-.IP "ev_io_set (ev_io *, int fd, int events)" 4
-.IX Item "ev_io_set (ev_io *, int fd, int events)"
-.PD
-Configures an \f(CW\*(C`ev_io\*(C'\fR watcher. The \f(CW\*(C`fd\*(C'\fR is the file descriptor to
-rceeive events for and events is either \f(CW\*(C`EV_READ\*(C'\fR, \f(CW\*(C`EV_WRITE\*(C'\fR or
-\&\f(CW\*(C`EV_READ | EV_WRITE\*(C'\fR to receive the given events.
-.IP "int fd [read\-only]" 4
-.IX Item "int fd [read-only]"
-The file descriptor being watched.
-.IP "int events [read\-only]" 4
-.IX Item "int events [read-only]"
-The events being watched.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Call \f(CW\*(C`stdin_readable_cb\*(C'\fR when \s-1STDIN_FILENO\s0 has become, well
-readable, but only once. Since it is likely line-buffered, you could
-attempt to read a whole line in the callback.
-.PP
-.Vb 6
-\& static void
-\& stdin_readable_cb (struct ev_loop *loop, struct ev_io *w, int revents)
-\& {
-\& ev_io_stop (loop, w);
-\& .. read from stdin here (or from w\->fd) and haqndle any I/O errors
-\& }
-\&
-\& ...
-\& struct ev_loop *loop = ev_default_init (0);
-\& struct ev_io stdin_readable;
-\& ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ);
-\& ev_io_start (loop, &stdin_readable);
-\& ev_loop (loop, 0);
-.Ve
-.ie n .Sh """ev_timer"" \- relative and optionally repeating timeouts"
-.el .Sh "\f(CWev_timer\fP \- relative and optionally repeating timeouts"
-.IX Subsection "ev_timer - relative and optionally repeating timeouts"
-Timer watchers are simple relative timers that generate an event after a
-given time, and optionally repeating in regular intervals after that.
-.PP
-The timers are based on real time, that is, if you register an event that
-times out after an hour and you reset your system clock to last years
-time, it will still time out after (roughly) and hour. \*(L"Roughly\*(R" because
-detecting time jumps is hard, and some inaccuracies are unavoidable (the
-monotonic clock option helps a lot here).
-.PP
-The relative timeouts are calculated relative to the \f(CW\*(C`ev_now ()\*(C'\fR
-time. This is usually the right thing as this timestamp refers to the time
-of the event triggering whatever timeout you are modifying/starting. If
-you suspect event processing to be delayed and you \fIneed\fR to base the timeout
-on the current time, use something like this to adjust for this:
-.PP
-.Vb 1
-\& ev_timer_set (&timer, after + ev_now () \- ev_time (), 0.);
-.Ve
-.PP
-The callback is guarenteed to be invoked only when its timeout has passed,
-but if multiple timers become ready during the same loop iteration then
-order of execution is undefined.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_timer_init (ev_timer *, callback, ev_tstamp after, ev_tstamp repeat)" 4
-.IX Item "ev_timer_init (ev_timer *, callback, ev_tstamp after, ev_tstamp repeat)"
-.PD 0
-.IP "ev_timer_set (ev_timer *, ev_tstamp after, ev_tstamp repeat)" 4
-.IX Item "ev_timer_set (ev_timer *, ev_tstamp after, ev_tstamp repeat)"
-.PD
-Configure the timer to trigger after \f(CW\*(C`after\*(C'\fR seconds. If \f(CW\*(C`repeat\*(C'\fR is
-\&\f(CW0.\fR, then it will automatically be stopped. If it is positive, then the
-timer will automatically be configured to trigger again \f(CW\*(C`repeat\*(C'\fR seconds
-later, again, and again, until stopped manually.
-.Sp
-The timer itself will do a best-effort at avoiding drift, that is, if you
-configure a timer to trigger every 10 seconds, then it will trigger at
-exactly 10 second intervals. If, however, your program cannot keep up with
-the timer (because it takes longer than those 10 seconds to do stuff) the
-timer will not fire more than once per event loop iteration.
-.IP "ev_timer_again (loop, ev_timer *)" 4
-.IX Item "ev_timer_again (loop, ev_timer *)"
-This will act as if the timer timed out and restart it again if it is
-repeating. The exact semantics are:
-.Sp
-If the timer is pending, its pending status is cleared.
-.Sp
-If the timer is started but nonrepeating, stop it (as if it timed out).
-.Sp
-If the timer is repeating, either start it if necessary (with the
-\&\f(CW\*(C`repeat\*(C'\fR value), or reset the running timer to the \f(CW\*(C`repeat\*(C'\fR value.
-.Sp
-This sounds a bit complicated, but here is a useful and typical
-example: Imagine you have a tcp connection and you want a so-called idle
-timeout, that is, you want to be called when there have been, say, 60
-seconds of inactivity on the socket. The easiest way to do this is to
-configure an \f(CW\*(C`ev_timer\*(C'\fR with a \f(CW\*(C`repeat\*(C'\fR value of \f(CW60\fR and then call
-\&\f(CW\*(C`ev_timer_again\*(C'\fR each time you successfully read or write some data. If
-you go into an idle state where you do not expect data to travel on the
-socket, you can \f(CW\*(C`ev_timer_stop\*(C'\fR the timer, and \f(CW\*(C`ev_timer_again\*(C'\fR will
-automatically restart it if need be.
-.Sp
-That means you can ignore the \f(CW\*(C`after\*(C'\fR value and \f(CW\*(C`ev_timer_start\*(C'\fR
-altogether and only ever use the \f(CW\*(C`repeat\*(C'\fR value and \f(CW\*(C`ev_timer_again\*(C'\fR:
-.Sp
-.Vb 8
-\& ev_timer_init (timer, callback, 0., 5.);
-\& ev_timer_again (loop, timer);
-\& ...
-\& timer\->again = 17.;
-\& ev_timer_again (loop, timer);
-\& ...
-\& timer\->again = 10.;
-\& ev_timer_again (loop, timer);
-.Ve
-.Sp
-This is more slightly efficient then stopping/starting the timer each time
-you want to modify its timeout value.
-.IP "ev_tstamp repeat [read\-write]" 4
-.IX Item "ev_tstamp repeat [read-write]"
-The current \f(CW\*(C`repeat\*(C'\fR value. Will be used each time the watcher times out
-or \f(CW\*(C`ev_timer_again\*(C'\fR is called and determines the next timeout (if any),
-which is also when any modifications are taken into account.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Create a timer that fires after 60 seconds.
-.PP
-.Vb 5
-\& static void
-\& one_minute_cb (struct ev_loop *loop, struct ev_timer *w, int revents)
-\& {
-\& .. one minute over, w is actually stopped right here
-\& }
-\&
-\& struct ev_timer mytimer;
-\& ev_timer_init (&mytimer, one_minute_cb, 60., 0.);
-\& ev_timer_start (loop, &mytimer);
-.Ve
-.PP
-Example: Create a timeout timer that times out after 10 seconds of
-inactivity.
-.PP
-.Vb 5
-\& static void
-\& timeout_cb (struct ev_loop *loop, struct ev_timer *w, int revents)
-\& {
-\& .. ten seconds without any activity
-\& }
-\&
-\& struct ev_timer mytimer;
-\& ev_timer_init (&mytimer, timeout_cb, 0., 10.); /* note, only repeat used */
-\& ev_timer_again (&mytimer); /* start timer */
-\& ev_loop (loop, 0);
-\&
-\& // and in some piece of code that gets executed on any "activity":
-\& // reset the timeout to start ticking again at 10 seconds
-\& ev_timer_again (&mytimer);
-.Ve
-.ie n .Sh """ev_periodic"" \- to cron or not to cron?"
-.el .Sh "\f(CWev_periodic\fP \- to cron or not to cron?"
-.IX Subsection "ev_periodic - to cron or not to cron?"
-Periodic watchers are also timers of a kind, but they are very versatile
-(and unfortunately a bit complex).
-.PP
-Unlike \f(CW\*(C`ev_timer\*(C'\fR's, they are not based on real time (or relative time)
-but on wallclock time (absolute time). You can tell a periodic watcher
-to trigger \*(L"at\*(R" some specific point in time. For example, if you tell a
-periodic watcher to trigger in 10 seconds (by specifiying e.g. \f(CW\*(C`ev_now ()
-+ 10.\*(C'\fR) and then reset your system clock to the last year, then it will
-take a year to trigger the event (unlike an \f(CW\*(C`ev_timer\*(C'\fR, which would trigger
-roughly 10 seconds later).
-.PP
-They can also be used to implement vastly more complex timers, such as
-triggering an event on each midnight, local time or other, complicated,
-rules.
-.PP
-As with timers, the callback is guarenteed to be invoked only when the
-time (\f(CW\*(C`at\*(C'\fR) has been passed, but if multiple periodic timers become ready
-during the same loop iteration then order of execution is undefined.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_periodic_init (ev_periodic *, callback, ev_tstamp at, ev_tstamp interval, reschedule_cb)" 4
-.IX Item "ev_periodic_init (ev_periodic *, callback, ev_tstamp at, ev_tstamp interval, reschedule_cb)"
-.PD 0
-.IP "ev_periodic_set (ev_periodic *, ev_tstamp after, ev_tstamp repeat, reschedule_cb)" 4
-.IX Item "ev_periodic_set (ev_periodic *, ev_tstamp after, ev_tstamp repeat, reschedule_cb)"
-.PD
-Lots of arguments, lets sort it out... There are basically three modes of
-operation, and we will explain them from simplest to complex:
-.RS 4
-.IP "\(bu" 4
-absolute timer (at = time, interval = reschedule_cb = 0)
-.Sp
-In this configuration the watcher triggers an event at the wallclock time
-\&\f(CW\*(C`at\*(C'\fR and doesn't repeat. It will not adjust when a time jump occurs,
-that is, if it is to be run at January 1st 2011 then it will run when the
-system time reaches or surpasses this time.
-.IP "\(bu" 4
-repeating interval timer (at = offset, interval > 0, reschedule_cb = 0)
-.Sp
-In this mode the watcher will always be scheduled to time out at the next
-\&\f(CW\*(C`at + N * interval\*(C'\fR time (for some integer N, which can also be negative)
-and then repeat, regardless of any time jumps.
-.Sp
-This can be used to create timers that do not drift with respect to system
-time:
-.Sp
-.Vb 1
-\& ev_periodic_set (&periodic, 0., 3600., 0);
-.Ve
-.Sp
-This doesn't mean there will always be 3600 seconds in between triggers,
-but only that the the callback will be called when the system time shows a
-full hour (\s-1UTC\s0), or more correctly, when the system time is evenly divisible
-by 3600.
-.Sp
-Another way to think about it (for the mathematically inclined) is that
-\&\f(CW\*(C`ev_periodic\*(C'\fR will try to run the callback in this mode at the next possible
-time where \f(CW\*(C`time = at (mod interval)\*(C'\fR, regardless of any time jumps.
-.Sp
-For numerical stability it is preferable that the \f(CW\*(C`at\*(C'\fR value is near
-\&\f(CW\*(C`ev_now ()\*(C'\fR (the current time), but there is no range requirement for
-this value.
-.IP "\(bu" 4
-manual reschedule mode (at and interval ignored, reschedule_cb = callback)
-.Sp
-In this mode the values for \f(CW\*(C`interval\*(C'\fR and \f(CW\*(C`at\*(C'\fR are both being
-ignored. Instead, each time the periodic watcher gets scheduled, the
-reschedule callback will be called with the watcher as first, and the
-current time as second argument.
-.Sp
-\&\s-1NOTE:\s0 \fIThis callback \s-1MUST\s0 \s-1NOT\s0 stop or destroy any periodic watcher,
-ever, or make any event loop modifications\fR. If you need to stop it,
-return \f(CW\*(C`now + 1e30\*(C'\fR (or so, fudge fudge) and stop it afterwards (e.g. by
-starting an \f(CW\*(C`ev_prepare\*(C'\fR watcher, which is legal).
-.Sp
-Its prototype is \f(CW\*(C`ev_tstamp (*reschedule_cb)(struct ev_periodic *w,
-ev_tstamp now)\*(C'\fR, e.g.:
-.Sp
-.Vb 4
-\& static ev_tstamp my_rescheduler (struct ev_periodic *w, ev_tstamp now)
-\& {
-\& return now + 60.;
-\& }
-.Ve
-.Sp
-It must return the next time to trigger, based on the passed time value
-(that is, the lowest time value larger than to the second argument). It
-will usually be called just before the callback will be triggered, but
-might be called at other times, too.
-.Sp
-\&\s-1NOTE:\s0 \fIThis callback must always return a time that is later than the
-passed \f(CI\*(C`now\*(C'\fI value\fR. Not even \f(CW\*(C`now\*(C'\fR itself will do, it \fImust\fR be larger.
-.Sp
-This can be used to create very complex timers, such as a timer that
-triggers on each midnight, local time. To do this, you would calculate the
-next midnight after \f(CW\*(C`now\*(C'\fR and return the timestamp value for this. How
-you do this is, again, up to you (but it is not trivial, which is the main
-reason I omitted it as an example).
-.RE
-.RS 4
-.RE
-.IP "ev_periodic_again (loop, ev_periodic *)" 4
-.IX Item "ev_periodic_again (loop, ev_periodic *)"
-Simply stops and restarts the periodic watcher again. This is only useful
-when you changed some parameters or the reschedule callback would return
-a different time than the last time it was called (e.g. in a crond like
-program when the crontabs have changed).
-.IP "ev_tstamp ev_periodic_at (ev_periodic *)" 4
-.IX Item "ev_tstamp ev_periodic_at (ev_periodic *)"
-When active, returns the absolute time that the watcher is supposed to
-trigger next.
-.IP "ev_tstamp offset [read\-write]" 4
-.IX Item "ev_tstamp offset [read-write]"
-When repeating, this contains the offset value, otherwise this is the
-absolute point in time (the \f(CW\*(C`at\*(C'\fR value passed to \f(CW\*(C`ev_periodic_set\*(C'\fR).
-.Sp
-Can be modified any time, but changes only take effect when the periodic
-timer fires or \f(CW\*(C`ev_periodic_again\*(C'\fR is being called.
-.IP "ev_tstamp interval [read\-write]" 4
-.IX Item "ev_tstamp interval [read-write]"
-The current interval value. Can be modified any time, but changes only
-take effect when the periodic timer fires or \f(CW\*(C`ev_periodic_again\*(C'\fR is being
-called.
-.IP "ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) [read\-write]" 4
-.IX Item "ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) [read-write]"
-The current reschedule callback, or \f(CW0\fR, if this functionality is
-switched off. Can be changed any time, but changes only take effect when
-the periodic timer fires or \f(CW\*(C`ev_periodic_again\*(C'\fR is being called.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Call a callback every hour, or, more precisely, whenever the
-system clock is divisible by 3600. The callback invocation times have
-potentially a lot of jittering, but good long-term stability.
-.PP
-.Vb 5
-\& static void
-\& clock_cb (struct ev_loop *loop, struct ev_io *w, int revents)
-\& {
-\& ... its now a full hour (UTC, or TAI or whatever your clock follows)
-\& }
-\&
-\& struct ev_periodic hourly_tick;
-\& ev_periodic_init (&hourly_tick, clock_cb, 0., 3600., 0);
-\& ev_periodic_start (loop, &hourly_tick);
-.Ve
-.PP
-Example: The same as above, but use a reschedule callback to do it:
-.PP
-.Vb 1
-\& #include <math.h>
-\&
-\& static ev_tstamp
-\& my_scheduler_cb (struct ev_periodic *w, ev_tstamp now)
-\& {
-\& return fmod (now, 3600.) + 3600.;
-\& }
-\&
-\& ev_periodic_init (&hourly_tick, clock_cb, 0., 0., my_scheduler_cb);
-.Ve
-.PP
-Example: Call a callback every hour, starting now:
-.PP
-.Vb 4
-\& struct ev_periodic hourly_tick;
-\& ev_periodic_init (&hourly_tick, clock_cb,
-\& fmod (ev_now (loop), 3600.), 3600., 0);
-\& ev_periodic_start (loop, &hourly_tick);
-.Ve
-.ie n .Sh """ev_signal"" \- signal me when a signal gets signalled!"
-.el .Sh "\f(CWev_signal\fP \- signal me when a signal gets signalled!"
-.IX Subsection "ev_signal - signal me when a signal gets signalled!"
-Signal watchers will trigger an event when the process receives a specific
-signal one or more times. Even though signals are very asynchronous, libev
-will try it's best to deliver signals synchronously, i.e. as part of the
-normal event processing, like any other event.
-.PP
-You can configure as many watchers as you like per signal. Only when the
-first watcher gets started will libev actually register a signal watcher
-with the kernel (thus it coexists with your own signal handlers as long
-as you don't register any with libev). Similarly, when the last signal
-watcher for a signal is stopped libev will reset the signal handler to
-\&\s-1SIG_DFL\s0 (regardless of what it was set to before).
-.PP
-If possible and supported, libev will install its handlers with
-\&\f(CW\*(C`SA_RESTART\*(C'\fR behaviour enabled, so syscalls should not be unduly
-interrupted. If you have a problem with syscalls getting interrupted by
-signals you can block all signals in an \f(CW\*(C`ev_check\*(C'\fR watcher and unblock
-them in an \f(CW\*(C`ev_prepare\*(C'\fR watcher.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_signal_init (ev_signal *, callback, int signum)" 4
-.IX Item "ev_signal_init (ev_signal *, callback, int signum)"
-.PD 0
-.IP "ev_signal_set (ev_signal *, int signum)" 4
-.IX Item "ev_signal_set (ev_signal *, int signum)"
-.PD
-Configures the watcher to trigger on the given signal number (usually one
-of the \f(CW\*(C`SIGxxx\*(C'\fR constants).
-.IP "int signum [read\-only]" 4
-.IX Item "int signum [read-only]"
-The signal the watcher watches out for.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Try to exit cleanly on \s-1SIGINT\s0 and \s-1SIGTERM\s0.
-.PP
-.Vb 5
-\& static void
-\& sigint_cb (struct ev_loop *loop, struct ev_signal *w, int revents)
-\& {
-\& ev_unloop (loop, EVUNLOOP_ALL);
-\& }
-\&
-\& struct ev_signal signal_watcher;
-\& ev_signal_init (&signal_watcher, sigint_cb, SIGINT);
-\& ev_signal_start (loop, &sigint_cb);
-.Ve
-.ie n .Sh """ev_child"" \- watch out for process status changes"
-.el .Sh "\f(CWev_child\fP \- watch out for process status changes"
-.IX Subsection "ev_child - watch out for process status changes"
-Child watchers trigger when your process receives a \s-1SIGCHLD\s0 in response to
-some child status changes (most typically when a child of yours dies). It
-is permissible to install a child watcher \fIafter\fR the child has been
-forked (which implies it might have already exited), as long as the event
-loop isn't entered (or is continued from a watcher).
-.PP
-Only the default event loop is capable of handling signals, and therefore
-you can only rgeister child watchers in the default event loop.
-.PP
-\fIProcess Interaction\fR
-.IX Subsection "Process Interaction"
-.PP
-Libev grabs \f(CW\*(C`SIGCHLD\*(C'\fR as soon as the default event loop is
-initialised. This is necessary to guarantee proper behaviour even if
-the first child watcher is started after the child exits. The occurance
-of \f(CW\*(C`SIGCHLD\*(C'\fR is recorded asynchronously, but child reaping is done
-synchronously as part of the event loop processing. Libev always reaps all
-children, even ones not watched.
-.PP
-\fIOverriding the Built-In Processing\fR
-.IX Subsection "Overriding the Built-In Processing"
-.PP
-Libev offers no special support for overriding the built-in child
-processing, but if your application collides with libev's default child
-handler, you can override it easily by installing your own handler for
-\&\f(CW\*(C`SIGCHLD\*(C'\fR after initialising the default loop, and making sure the
-default loop never gets destroyed. You are encouraged, however, to use an
-event-based approach to child reaping and thus use libev's support for
-that, so other libev users can use \f(CW\*(C`ev_child\*(C'\fR watchers freely.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_child_init (ev_child *, callback, int pid, int trace)" 4
-.IX Item "ev_child_init (ev_child *, callback, int pid, int trace)"
-.PD 0
-.IP "ev_child_set (ev_child *, int pid, int trace)" 4
-.IX Item "ev_child_set (ev_child *, int pid, int trace)"
-.PD
-Configures the watcher to wait for status changes of process \f(CW\*(C`pid\*(C'\fR (or
-\&\fIany\fR process if \f(CW\*(C`pid\*(C'\fR is specified as \f(CW0\fR). The callback can look
-at the \f(CW\*(C`rstatus\*(C'\fR member of the \f(CW\*(C`ev_child\*(C'\fR watcher structure to see
-the status word (use the macros from \f(CW\*(C`sys/wait.h\*(C'\fR and see your systems
-\&\f(CW\*(C`waitpid\*(C'\fR documentation). The \f(CW\*(C`rpid\*(C'\fR member contains the pid of the
-process causing the status change. \f(CW\*(C`trace\*(C'\fR must be either \f(CW0\fR (only
-activate the watcher when the process terminates) or \f(CW1\fR (additionally
-activate the watcher when the process is stopped or continued).
-.IP "int pid [read\-only]" 4
-.IX Item "int pid [read-only]"
-The process id this watcher watches out for, or \f(CW0\fR, meaning any process id.
-.IP "int rpid [read\-write]" 4
-.IX Item "int rpid [read-write]"
-The process id that detected a status change.
-.IP "int rstatus [read\-write]" 4
-.IX Item "int rstatus [read-write]"
-The process exit/trace status caused by \f(CW\*(C`rpid\*(C'\fR (see your systems
-\&\f(CW\*(C`waitpid\*(C'\fR and \f(CW\*(C`sys/wait.h\*(C'\fR documentation for details).
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: \f(CW\*(C`fork()\*(C'\fR a new process and install a child handler to wait for
-its completion.
-.PP
-.Vb 1
-\& ev_child cw;
-\&
-\& static void
-\& child_cb (EV_P_ struct ev_child *w, int revents)
-\& {
-\& ev_child_stop (EV_A_ w);
-\& printf ("process %d exited with status %x\en", w\->rpid, w\->rstatus);
-\& }
-\&
-\& pid_t pid = fork ();
-\&
-\& if (pid < 0)
-\& // error
-\& else if (pid == 0)
-\& {
-\& // the forked child executes here
-\& exit (1);
-\& }
-\& else
-\& {
-\& ev_child_init (&cw, child_cb, pid, 0);
-\& ev_child_start (EV_DEFAULT_ &cw);
-\& }
-.Ve
-.ie n .Sh """ev_stat"" \- did the file attributes just change?"
-.el .Sh "\f(CWev_stat\fP \- did the file attributes just change?"
-.IX Subsection "ev_stat - did the file attributes just change?"
-This watches a filesystem path for attribute changes. That is, it calls
-\&\f(CW\*(C`stat\*(C'\fR regularly (or when the \s-1OS\s0 says it changed) and sees if it changed
-compared to the last time, invoking the callback if it did.
-.PP
-The path does not need to exist: changing from \*(L"path exists\*(R" to \*(L"path does
-not exist\*(R" is a status change like any other. The condition \*(L"path does
-not exist\*(R" is signified by the \f(CW\*(C`st_nlink\*(C'\fR field being zero (which is
-otherwise always forced to be at least one) and all the other fields of
-the stat buffer having unspecified contents.
-.PP
-The path \fIshould\fR be absolute and \fImust not\fR end in a slash. If it is
-relative and your working directory changes, the behaviour is undefined.
-.PP
-Since there is no standard to do this, the portable implementation simply
-calls \f(CW\*(C`stat (2)\*(C'\fR regularly on the path to see if it changed somehow. You
-can specify a recommended polling interval for this case. If you specify
-a polling interval of \f(CW0\fR (highly recommended!) then a \fIsuitable,
-unspecified default\fR value will be used (which you can expect to be around
-five seconds, although this might change dynamically). Libev will also
-impose a minimum interval which is currently around \f(CW0.1\fR, but thats
-usually overkill.
-.PP
-This watcher type is not meant for massive numbers of stat watchers,
-as even with OS-supported change notifications, this can be
-resource-intensive.
-.PP
-At the time of this writing, only the Linux inotify interface is
-implemented (implementing kqueue support is left as an exercise for the
-reader, note, however, that the author sees no way of implementing ev_stat
-semantics with kqueue). Inotify will be used to give hints only and should
-not change the semantics of \f(CW\*(C`ev_stat\*(C'\fR watchers, which means that libev
-sometimes needs to fall back to regular polling again even with inotify,
-but changes are usually detected immediately, and if the file exists there
-will be no polling.
-.PP
-\fI\s-1ABI\s0 Issues (Largefile Support)\fR
-.IX Subsection "ABI Issues (Largefile Support)"
-.PP
-Libev by default (unless the user overrides this) uses the default
-compilation environment, which means that on systems with optionally
-disabled large file support, you get the 32 bit version of the stat
-structure. When using the library from programs that change the \s-1ABI\s0 to
-use 64 bit file offsets the programs will fail. In that case you have to
-compile libev with the same flags to get binary compatibility. This is
-obviously the case with any flags that change the \s-1ABI\s0, but the problem is
-most noticably with ev_stat and largefile support.
-.PP
-\fIInotify\fR
-.IX Subsection "Inotify"
-.PP
-When \f(CW\*(C`inotify (7)\*(C'\fR support has been compiled into libev (generally only
-available on Linux) and present at runtime, it will be used to speed up
-change detection where possible. The inotify descriptor will be created lazily
-when the first \f(CW\*(C`ev_stat\*(C'\fR watcher is being started.
-.PP
-Inotify presence does not change the semantics of \f(CW\*(C`ev_stat\*(C'\fR watchers
-except that changes might be detected earlier, and in some cases, to avoid
-making regular \f(CW\*(C`stat\*(C'\fR calls. Even in the presence of inotify support
-there are many cases where libev has to resort to regular \f(CW\*(C`stat\*(C'\fR polling.
-.PP
-(There is no support for kqueue, as apparently it cannot be used to
-implement this functionality, due to the requirement of having a file
-descriptor open on the object at all times).
-.PP
-\fIThe special problem of stat time resolution\fR
-.IX Subsection "The special problem of stat time resolution"
-.PP
-The \f(CW\*(C`stat ()\*(C'\fR syscall only supports full-second resolution portably, and
-even on systems where the resolution is higher, many filesystems still
-only support whole seconds.
-.PP
-That means that, if the time is the only thing that changes, you can
-easily miss updates: on the first update, \f(CW\*(C`ev_stat\*(C'\fR detects a change and
-calls your callback, which does something. When there is another update
-within the same second, \f(CW\*(C`ev_stat\*(C'\fR will be unable to detect it as the stat
-data does not change.
-.PP
-The solution to this is to delay acting on a change for slightly more
-than second (or till slightly after the next full second boundary), using
-a roughly one-second-delay \f(CW\*(C`ev_timer\*(C'\fR (e.g. \f(CW\*(C`ev_timer_set (w, 0., 1.02);
-ev_timer_again (loop, w)\*(C'\fR).
-.PP
-The \f(CW.02\fR offset is added to work around small timing inconsistencies
-of some operating systems (where the second counter of the current time
-might be be delayed. One such system is the Linux kernel, where a call to
-\&\f(CW\*(C`gettimeofday\*(C'\fR might return a timestamp with a full second later than
-a subsequent \f(CW\*(C`time\*(C'\fR call \- if the equivalent of \f(CW\*(C`time ()\*(C'\fR is used to
-update file times then there will be a small window where the kernel uses
-the previous second to update file times but libev might already execute
-the timer callback).
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_stat_init (ev_stat *, callback, const char *path, ev_tstamp interval)" 4
-.IX Item "ev_stat_init (ev_stat *, callback, const char *path, ev_tstamp interval)"
-.PD 0
-.IP "ev_stat_set (ev_stat *, const char *path, ev_tstamp interval)" 4
-.IX Item "ev_stat_set (ev_stat *, const char *path, ev_tstamp interval)"
-.PD
-Configures the watcher to wait for status changes of the given
-\&\f(CW\*(C`path\*(C'\fR. The \f(CW\*(C`interval\*(C'\fR is a hint on how quickly a change is expected to
-be detected and should normally be specified as \f(CW0\fR to let libev choose
-a suitable value. The memory pointed to by \f(CW\*(C`path\*(C'\fR must point to the same
-path for as long as the watcher is active.
-.Sp
-The callback will receive \f(CW\*(C`EV_STAT\*(C'\fR when a change was detected, relative
-to the attributes at the time the watcher was started (or the last change
-was detected).
-.IP "ev_stat_stat (loop, ev_stat *)" 4
-.IX Item "ev_stat_stat (loop, ev_stat *)"
-Updates the stat buffer immediately with new values. If you change the
-watched path in your callback, you could call this function to avoid
-detecting this change (while introducing a race condition if you are not
-the only one changing the path). Can also be useful simply to find out the
-new values.
-.IP "ev_statdata attr [read\-only]" 4
-.IX Item "ev_statdata attr [read-only]"
-The most-recently detected attributes of the file. Although the type is
-\&\f(CW\*(C`ev_statdata\*(C'\fR, this is usually the (or one of the) \f(CW\*(C`struct stat\*(C'\fR types
-suitable for your system, but you can only rely on the POSIX-standardised
-members to be present. If the \f(CW\*(C`st_nlink\*(C'\fR member is \f(CW0\fR, then there was
-some error while \f(CW\*(C`stat\*(C'\fRing the file.
-.IP "ev_statdata prev [read\-only]" 4
-.IX Item "ev_statdata prev [read-only]"
-The previous attributes of the file. The callback gets invoked whenever
-\&\f(CW\*(C`prev\*(C'\fR != \f(CW\*(C`attr\*(C'\fR, or, more precisely, one or more of these members
-differ: \f(CW\*(C`st_dev\*(C'\fR, \f(CW\*(C`st_ino\*(C'\fR, \f(CW\*(C`st_mode\*(C'\fR, \f(CW\*(C`st_nlink\*(C'\fR, \f(CW\*(C`st_uid\*(C'\fR,
-\&\f(CW\*(C`st_gid\*(C'\fR, \f(CW\*(C`st_rdev\*(C'\fR, \f(CW\*(C`st_size\*(C'\fR, \f(CW\*(C`st_atime\*(C'\fR, \f(CW\*(C`st_mtime\*(C'\fR, \f(CW\*(C`st_ctime\*(C'\fR.
-.IP "ev_tstamp interval [read\-only]" 4
-.IX Item "ev_tstamp interval [read-only]"
-The specified interval.
-.IP "const char *path [read\-only]" 4
-.IX Item "const char *path [read-only]"
-The filesystem path that is being watched.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Watch \f(CW\*(C`/etc/passwd\*(C'\fR for attribute changes.
-.PP
-.Vb 10
-\& static void
-\& passwd_cb (struct ev_loop *loop, ev_stat *w, int revents)
-\& {
-\& /* /etc/passwd changed in some way */
-\& if (w\->attr.st_nlink)
-\& {
-\& printf ("passwd current size %ld\en", (long)w\->attr.st_size);
-\& printf ("passwd current atime %ld\en", (long)w\->attr.st_mtime);
-\& printf ("passwd current mtime %ld\en", (long)w\->attr.st_mtime);
-\& }
-\& else
-\& /* you shalt not abuse printf for puts */
-\& puts ("wow, /etc/passwd is not there, expect problems. "
-\& "if this is windows, they already arrived\en");
-\& }
-\&
-\& ...
-\& ev_stat passwd;
-\&
-\& ev_stat_init (&passwd, passwd_cb, "/etc/passwd", 0.);
-\& ev_stat_start (loop, &passwd);
-.Ve
-.PP
-Example: Like above, but additionally use a one-second delay so we do not
-miss updates (however, frequent updates will delay processing, too, so
-one might do the work both on \f(CW\*(C`ev_stat\*(C'\fR callback invocation \fIand\fR on
-\&\f(CW\*(C`ev_timer\*(C'\fR callback invocation).
-.PP
-.Vb 2
-\& static ev_stat passwd;
-\& static ev_timer timer;
-\&
-\& static void
-\& timer_cb (EV_P_ ev_timer *w, int revents)
-\& {
-\& ev_timer_stop (EV_A_ w);
-\&
-\& /* now it\*(Aqs one second after the most recent passwd change */
-\& }
-\&
-\& static void
-\& stat_cb (EV_P_ ev_stat *w, int revents)
-\& {
-\& /* reset the one\-second timer */
-\& ev_timer_again (EV_A_ &timer);
-\& }
-\&
-\& ...
-\& ev_stat_init (&passwd, stat_cb, "/etc/passwd", 0.);
-\& ev_stat_start (loop, &passwd);
-\& ev_timer_init (&timer, timer_cb, 0., 1.02);
-.Ve
-.ie n .Sh """ev_idle"" \- when you've got nothing better to do..."
-.el .Sh "\f(CWev_idle\fP \- when you've got nothing better to do..."
-.IX Subsection "ev_idle - when you've got nothing better to do..."
-Idle watchers trigger events when no other events of the same or higher
-priority are pending (prepare, check and other idle watchers do not
-count).
-.PP
-That is, as long as your process is busy handling sockets or timeouts
-(or even signals, imagine) of the same or higher priority it will not be
-triggered. But when your process is idle (or only lower-priority watchers
-are pending), the idle watchers are being called once per event loop
-iteration \- until stopped, that is, or your process receives more events
-and becomes busy again with higher priority stuff.
-.PP
-The most noteworthy effect is that as long as any idle watchers are
-active, the process will not block when waiting for new events.
-.PP
-Apart from keeping your process non-blocking (which is a useful
-effect on its own sometimes), idle watchers are a good place to do
-\&\*(L"pseudo-background processing\*(R", or delay processing stuff to after the
-event loop has handled all outstanding events.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_idle_init (ev_signal *, callback)" 4
-.IX Item "ev_idle_init (ev_signal *, callback)"
-Initialises and configures the idle watcher \- it has no parameters of any
-kind. There is a \f(CW\*(C`ev_idle_set\*(C'\fR macro, but using it is utterly pointless,
-believe me.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Dynamically allocate an \f(CW\*(C`ev_idle\*(C'\fR watcher, start it, and in the
-callback, free it. Also, use no error checking, as usual.
-.PP
-.Vb 7
-\& static void
-\& idle_cb (struct ev_loop *loop, struct ev_idle *w, int revents)
-\& {
-\& free (w);
-\& // now do something you wanted to do when the program has
-\& // no longer anything immediate to do.
-\& }
-\&
-\& struct ev_idle *idle_watcher = malloc (sizeof (struct ev_idle));
-\& ev_idle_init (idle_watcher, idle_cb);
-\& ev_idle_start (loop, idle_cb);
-.Ve
-.ie n .Sh """ev_prepare""\fP and \f(CW""ev_check"" \- customise your event loop!"
-.el .Sh "\f(CWev_prepare\fP and \f(CWev_check\fP \- customise your event loop!"
-.IX Subsection "ev_prepare and ev_check - customise your event loop!"
-Prepare and check watchers are usually (but not always) used in tandem:
-prepare watchers get invoked before the process blocks and check watchers
-afterwards.
-.PP
-You \fImust not\fR call \f(CW\*(C`ev_loop\*(C'\fR or similar functions that enter
-the current event loop from either \f(CW\*(C`ev_prepare\*(C'\fR or \f(CW\*(C`ev_check\*(C'\fR
-watchers. Other loops than the current one are fine, however. The
-rationale behind this is that you do not need to check for recursion in
-those watchers, i.e. the sequence will always be \f(CW\*(C`ev_prepare\*(C'\fR, blocking,
-\&\f(CW\*(C`ev_check\*(C'\fR so if you have one watcher of each kind they will always be
-called in pairs bracketing the blocking call.
-.PP
-Their main purpose is to integrate other event mechanisms into libev and
-their use is somewhat advanced. This could be used, for example, to track
-variable changes, implement your own watchers, integrate net-snmp or a
-coroutine library and lots more. They are also occasionally useful if
-you cache some data and want to flush it before blocking (for example,
-in X programs you might want to do an \f(CW\*(C`XFlush ()\*(C'\fR in an \f(CW\*(C`ev_prepare\*(C'\fR
-watcher).
-.PP
-This is done by examining in each prepare call which file descriptors need
-to be watched by the other library, registering \f(CW\*(C`ev_io\*(C'\fR watchers for
-them and starting an \f(CW\*(C`ev_timer\*(C'\fR watcher for any timeouts (many libraries
-provide just this functionality). Then, in the check watcher you check for
-any events that occured (by checking the pending status of all watchers
-and stopping them) and call back into the library. The I/O and timer
-callbacks will never actually be called (but must be valid nevertheless,
-because you never know, you know?).
-.PP
-As another example, the Perl Coro module uses these hooks to integrate
-coroutines into libev programs, by yielding to other active coroutines
-during each prepare and only letting the process block if no coroutines
-are ready to run (it's actually more complicated: it only runs coroutines
-with priority higher than or equal to the event loop and one coroutine
-of lower priority, but only once, using idle watchers to keep the event
-loop from blocking if lower-priority coroutines are active, thus mapping
-low-priority coroutines to idle/background tasks).
-.PP
-It is recommended to give \f(CW\*(C`ev_check\*(C'\fR watchers highest (\f(CW\*(C`EV_MAXPRI\*(C'\fR)
-priority, to ensure that they are being run before any other watchers
-after the poll. Also, \f(CW\*(C`ev_check\*(C'\fR watchers (and \f(CW\*(C`ev_prepare\*(C'\fR watchers,
-too) should not activate (\*(L"feed\*(R") events into libev. While libev fully
-supports this, they might get executed before other \f(CW\*(C`ev_check\*(C'\fR watchers
-did their job. As \f(CW\*(C`ev_check\*(C'\fR watchers are often used to embed other
-(non-libev) event loops those other event loops might be in an unusable
-state until their \f(CW\*(C`ev_check\*(C'\fR watcher ran (always remind yourself to
-coexist peacefully with others).
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_prepare_init (ev_prepare *, callback)" 4
-.IX Item "ev_prepare_init (ev_prepare *, callback)"
-.PD 0
-.IP "ev_check_init (ev_check *, callback)" 4
-.IX Item "ev_check_init (ev_check *, callback)"
-.PD
-Initialises and configures the prepare or check watcher \- they have no
-parameters of any kind. There are \f(CW\*(C`ev_prepare_set\*(C'\fR and \f(CW\*(C`ev_check_set\*(C'\fR
-macros, but using them is utterly, utterly and completely pointless.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-There are a number of principal ways to embed other event loops or modules
-into libev. Here are some ideas on how to include libadns into libev
-(there is a Perl module named \f(CW\*(C`EV::ADNS\*(C'\fR that does this, which you could
-use as a working example. Another Perl module named \f(CW\*(C`EV::Glib\*(C'\fR embeds a
-Glib main context into libev, and finally, \f(CW\*(C`Glib::EV\*(C'\fR embeds \s-1EV\s0 into the
-Glib event loop).
-.PP
-Method 1: Add \s-1IO\s0 watchers and a timeout watcher in a prepare handler,
-and in a check watcher, destroy them and call into libadns. What follows
-is pseudo-code only of course. This requires you to either use a low
-priority for the check watcher or use \f(CW\*(C`ev_clear_pending\*(C'\fR explicitly, as
-the callbacks for the IO/timeout watchers might not have been called yet.
-.PP
-.Vb 2
-\& static ev_io iow [nfd];
-\& static ev_timer tw;
-\&
-\& static void
-\& io_cb (ev_loop *loop, ev_io *w, int revents)
-\& {
-\& }
-\&
-\& // create io watchers for each fd and a timer before blocking
-\& static void
-\& adns_prepare_cb (ev_loop *loop, ev_prepare *w, int revents)
-\& {
-\& int timeout = 3600000;
-\& struct pollfd fds [nfd];
-\& // actual code will need to loop here and realloc etc.
-\& adns_beforepoll (ads, fds, &nfd, &timeout, timeval_from (ev_time ()));
-\&
-\& /* the callback is illegal, but won\*(Aqt be called as we stop during check */
-\& ev_timer_init (&tw, 0, timeout * 1e\-3);
-\& ev_timer_start (loop, &tw);
-\&
-\& // create one ev_io per pollfd
-\& for (int i = 0; i < nfd; ++i)
-\& {
-\& ev_io_init (iow + i, io_cb, fds [i].fd,
-\& ((fds [i].events & POLLIN ? EV_READ : 0)
-\& | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
-\&
-\& fds [i].revents = 0;
-\& ev_io_start (loop, iow + i);
-\& }
-\& }
-\&
-\& // stop all watchers after blocking
-\& static void
-\& adns_check_cb (ev_loop *loop, ev_check *w, int revents)
-\& {
-\& ev_timer_stop (loop, &tw);
-\&
-\& for (int i = 0; i < nfd; ++i)
-\& {
-\& // set the relevant poll flags
-\& // could also call adns_processreadable etc. here
-\& struct pollfd *fd = fds + i;
-\& int revents = ev_clear_pending (iow + i);
-\& if (revents & EV_READ ) fd\->revents |= fd\->events & POLLIN;
-\& if (revents & EV_WRITE) fd\->revents |= fd\->events & POLLOUT;
-\&
-\& // now stop the watcher
-\& ev_io_stop (loop, iow + i);
-\& }
-\&
-\& adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop));
-\& }
-.Ve
-.PP
-Method 2: This would be just like method 1, but you run \f(CW\*(C`adns_afterpoll\*(C'\fR
-in the prepare watcher and would dispose of the check watcher.
-.PP
-Method 3: If the module to be embedded supports explicit event
-notification (adns does), you can also make use of the actual watcher
-callbacks, and only destroy/create the watchers in the prepare watcher.
-.PP
-.Vb 5
-\& static void
-\& timer_cb (EV_P_ ev_timer *w, int revents)
-\& {
-\& adns_state ads = (adns_state)w\->data;
-\& update_now (EV_A);
-\&
-\& adns_processtimeouts (ads, &tv_now);
-\& }
-\&
-\& static void
-\& io_cb (EV_P_ ev_io *w, int revents)
-\& {
-\& adns_state ads = (adns_state)w\->data;
-\& update_now (EV_A);
-\&
-\& if (revents & EV_READ ) adns_processreadable (ads, w\->fd, &tv_now);
-\& if (revents & EV_WRITE) adns_processwriteable (ads, w\->fd, &tv_now);
-\& }
-\&
-\& // do not ever call adns_afterpoll
-.Ve
-.PP
-Method 4: Do not use a prepare or check watcher because the module you
-want to embed is too inflexible to support it. Instead, youc na override
-their poll function. The drawback with this solution is that the main
-loop is now no longer controllable by \s-1EV\s0. The \f(CW\*(C`Glib::EV\*(C'\fR module does
-this.
-.PP
-.Vb 4
-\& static gint
-\& event_poll_func (GPollFD *fds, guint nfds, gint timeout)
-\& {
-\& int got_events = 0;
-\&
-\& for (n = 0; n < nfds; ++n)
-\& // create/start io watcher that sets the relevant bits in fds[n] and increment got_events
-\&
-\& if (timeout >= 0)
-\& // create/start timer
-\&
-\& // poll
-\& ev_loop (EV_A_ 0);
-\&
-\& // stop timer again
-\& if (timeout >= 0)
-\& ev_timer_stop (EV_A_ &to);
-\&
-\& // stop io watchers again \- their callbacks should have set
-\& for (n = 0; n < nfds; ++n)
-\& ev_io_stop (EV_A_ iow [n]);
-\&
-\& return got_events;
-\& }
-.Ve
-.ie n .Sh """ev_embed"" \- when one backend isn't enough..."
-.el .Sh "\f(CWev_embed\fP \- when one backend isn't enough..."
-.IX Subsection "ev_embed - when one backend isn't enough..."
-This is a rather advanced watcher type that lets you embed one event loop
-into another (currently only \f(CW\*(C`ev_io\*(C'\fR events are supported in the embedded
-loop, other types of watchers might be handled in a delayed or incorrect
-fashion and must not be used).
-.PP
-There are primarily two reasons you would want that: work around bugs and
-prioritise I/O.
-.PP
-As an example for a bug workaround, the kqueue backend might only support
-sockets on some platform, so it is unusable as generic backend, but you
-still want to make use of it because you have many sockets and it scales
-so nicely. In this case, you would create a kqueue-based loop and embed it
-into your default loop (which might use e.g. poll). Overall operation will
-be a bit slower because first libev has to poll and then call kevent, but
-at least you can use both at what they are best.
-.PP
-As for prioritising I/O: rarely you have the case where some fds have
-to be watched and handled very quickly (with low latency), and even
-priorities and idle watchers might have too much overhead. In this case
-you would put all the high priority stuff in one loop and all the rest in
-a second one, and embed the second one in the first.
-.PP
-As long as the watcher is active, the callback will be invoked every time
-there might be events pending in the embedded loop. The callback must then
-call \f(CW\*(C`ev_embed_sweep (mainloop, watcher)\*(C'\fR to make a single sweep and invoke
-their callbacks (you could also start an idle watcher to give the embedded
-loop strictly lower priority for example). You can also set the callback
-to \f(CW0\fR, in which case the embed watcher will automatically execute the
-embedded loop sweep.
-.PP
-As long as the watcher is started it will automatically handle events. The
-callback will be invoked whenever some events have been handled. You can
-set the callback to \f(CW0\fR to avoid having to specify one if you are not
-interested in that.
-.PP
-Also, there have not currently been made special provisions for forking:
-when you fork, you not only have to call \f(CW\*(C`ev_loop_fork\*(C'\fR on both loops,
-but you will also have to stop and restart any \f(CW\*(C`ev_embed\*(C'\fR watchers
-yourself.
-.PP
-Unfortunately, not all backends are embeddable, only the ones returned by
-\&\f(CW\*(C`ev_embeddable_backends\*(C'\fR are, which, unfortunately, does not include any
-portable one.
-.PP
-So when you want to use this feature you will always have to be prepared
-that you cannot get an embeddable loop. The recommended way to get around
-this is to have a separate variables for your embeddable loop, try to
-create it, and if that fails, use the normal loop for everything.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)" 4
-.IX Item "ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)"
-.PD 0
-.IP "ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)" 4
-.IX Item "ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)"
-.PD
-Configures the watcher to embed the given loop, which must be
-embeddable. If the callback is \f(CW0\fR, then \f(CW\*(C`ev_embed_sweep\*(C'\fR will be
-invoked automatically, otherwise it is the responsibility of the callback
-to invoke it (it will continue to be called until the sweep has been done,
-if you do not want thta, you need to temporarily stop the embed watcher).
-.IP "ev_embed_sweep (loop, ev_embed *)" 4
-.IX Item "ev_embed_sweep (loop, ev_embed *)"
-Make a single, non-blocking sweep over the embedded loop. This works
-similarly to \f(CW\*(C`ev_loop (embedded_loop, EVLOOP_NONBLOCK)\*(C'\fR, but in the most
-apropriate way for embedded loops.
-.IP "struct ev_loop *other [read\-only]" 4
-.IX Item "struct ev_loop *other [read-only]"
-The embedded event loop.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Try to get an embeddable event loop and embed it into the default
-event loop. If that is not possible, use the default loop. The default
-loop is stored in \f(CW\*(C`loop_hi\*(C'\fR, while the mebeddable loop is stored in
-\&\f(CW\*(C`loop_lo\*(C'\fR (which is \f(CW\*(C`loop_hi\*(C'\fR in the acse no embeddable loop can be
-used).
-.PP
-.Vb 3
-\& struct ev_loop *loop_hi = ev_default_init (0);
-\& struct ev_loop *loop_lo = 0;
-\& struct ev_embed embed;
-\&
-\& // see if there is a chance of getting one that works
-\& // (remember that a flags value of 0 means autodetection)
-\& loop_lo = ev_embeddable_backends () & ev_recommended_backends ()
-\& ? ev_loop_new (ev_embeddable_backends () & ev_recommended_backends ())
-\& : 0;
-\&
-\& // if we got one, then embed it, otherwise default to loop_hi
-\& if (loop_lo)
-\& {
-\& ev_embed_init (&embed, 0, loop_lo);
-\& ev_embed_start (loop_hi, &embed);
-\& }
-\& else
-\& loop_lo = loop_hi;
-.Ve
-.PP
-Example: Check if kqueue is available but not recommended and create
-a kqueue backend for use with sockets (which usually work with any
-kqueue implementation). Store the kqueue/socket\-only event loop in
-\&\f(CW\*(C`loop_socket\*(C'\fR. (One might optionally use \f(CW\*(C`EVFLAG_NOENV\*(C'\fR, too).
-.PP
-.Vb 3
-\& struct ev_loop *loop = ev_default_init (0);
-\& struct ev_loop *loop_socket = 0;
-\& struct ev_embed embed;
-\&
-\& if (ev_supported_backends () & ~ev_recommended_backends () & EVBACKEND_KQUEUE)
-\& if ((loop_socket = ev_loop_new (EVBACKEND_KQUEUE))
-\& {
-\& ev_embed_init (&embed, 0, loop_socket);
-\& ev_embed_start (loop, &embed);
-\& }
-\&
-\& if (!loop_socket)
-\& loop_socket = loop;
-\&
-\& // now use loop_socket for all sockets, and loop for everything else
-.Ve
-.ie n .Sh """ev_fork"" \- the audacity to resume the event loop after a fork"
-.el .Sh "\f(CWev_fork\fP \- the audacity to resume the event loop after a fork"
-.IX Subsection "ev_fork - the audacity to resume the event loop after a fork"
-Fork watchers are called when a \f(CW\*(C`fork ()\*(C'\fR was detected (usually because
-whoever is a good citizen cared to tell libev about it by calling
-\&\f(CW\*(C`ev_default_fork\*(C'\fR or \f(CW\*(C`ev_loop_fork\*(C'\fR). The invocation is done before the
-event loop blocks next and before \f(CW\*(C`ev_check\*(C'\fR watchers are being called,
-and only in the child after the fork. If whoever good citizen calling
-\&\f(CW\*(C`ev_default_fork\*(C'\fR cheats and calls it in the wrong process, the fork
-handlers will be invoked, too, of course.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_fork_init (ev_signal *, callback)" 4
-.IX Item "ev_fork_init (ev_signal *, callback)"
-Initialises and configures the fork watcher \- it has no parameters of any
-kind. There is a \f(CW\*(C`ev_fork_set\*(C'\fR macro, but using it is utterly pointless,
-believe me.
-.ie n .Sh """ev_async"" \- how to wake up another event loop"
-.el .Sh "\f(CWev_async\fP \- how to wake up another event loop"
-.IX Subsection "ev_async - how to wake up another event loop"
-In general, you cannot use an \f(CW\*(C`ev_loop\*(C'\fR from multiple threads or other
-asynchronous sources such as signal handlers (as opposed to multiple event
-loops \- those are of course safe to use in different threads).
-.PP
-Sometimes, however, you need to wake up another event loop you do not
-control, for example because it belongs to another thread. This is what
-\&\f(CW\*(C`ev_async\*(C'\fR watchers do: as long as the \f(CW\*(C`ev_async\*(C'\fR watcher is active, you
-can signal it by calling \f(CW\*(C`ev_async_send\*(C'\fR, which is thread\- and signal
-safe.
-.PP
-This functionality is very similar to \f(CW\*(C`ev_signal\*(C'\fR watchers, as signals,
-too, are asynchronous in nature, and signals, too, will be compressed
-(i.e. the number of callback invocations may be less than the number of
-\&\f(CW\*(C`ev_async_sent\*(C'\fR calls).
-.PP
-Unlike \f(CW\*(C`ev_signal\*(C'\fR watchers, \f(CW\*(C`ev_async\*(C'\fR works with any event loop, not
-just the default loop.
-.PP
-\fIQueueing\fR
-.IX Subsection "Queueing"
-.PP
-\&\f(CW\*(C`ev_async\*(C'\fR does not support queueing of data in any way. The reason
-is that the author does not know of a simple (or any) algorithm for a
-multiple-writer-single-reader queue that works in all cases and doesn't
-need elaborate support such as pthreads.
-.PP
-That means that if you want to queue data, you have to provide your own
-queue. But at least I can tell you would implement locking around your
-queue:
-.IP "queueing from a signal handler context" 4
-.IX Item "queueing from a signal handler context"
-To implement race-free queueing, you simply add to the queue in the signal
-handler but you block the signal handler in the watcher callback. Here is an example that does that for
-some fictitiuous \s-1SIGUSR1\s0 handler:
-.Sp
-.Vb 1
-\& static ev_async mysig;
-\&
-\& static void
-\& sigusr1_handler (void)
-\& {
-\& sometype data;
-\&
-\& // no locking etc.
-\& queue_put (data);
-\& ev_async_send (EV_DEFAULT_ &mysig);
-\& }
-\&
-\& static void
-\& mysig_cb (EV_P_ ev_async *w, int revents)
-\& {
-\& sometype data;
-\& sigset_t block, prev;
-\&
-\& sigemptyset (&block);
-\& sigaddset (&block, SIGUSR1);
-\& sigprocmask (SIG_BLOCK, &block, &prev);
-\&
-\& while (queue_get (&data))
-\& process (data);
-\&
-\& if (sigismember (&prev, SIGUSR1)
-\& sigprocmask (SIG_UNBLOCK, &block, 0);
-\& }
-.Ve
-.Sp
-(Note: pthreads in theory requires you to use \f(CW\*(C`pthread_setmask\*(C'\fR
-instead of \f(CW\*(C`sigprocmask\*(C'\fR when you use threads, but libev doesn't do it
-either...).
-.IP "queueing from a thread context" 4
-.IX Item "queueing from a thread context"
-The strategy for threads is different, as you cannot (easily) block
-threads but you can easily preempt them, so to queue safely you need to
-employ a traditional mutex lock, such as in this pthread example:
-.Sp
-.Vb 2
-\& static ev_async mysig;
-\& static pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
-\&
-\& static void
-\& otherthread (void)
-\& {
-\& // only need to lock the actual queueing operation
-\& pthread_mutex_lock (&mymutex);
-\& queue_put (data);
-\& pthread_mutex_unlock (&mymutex);
-\&
-\& ev_async_send (EV_DEFAULT_ &mysig);
-\& }
-\&
-\& static void
-\& mysig_cb (EV_P_ ev_async *w, int revents)
-\& {
-\& pthread_mutex_lock (&mymutex);
-\&
-\& while (queue_get (&data))
-\& process (data);
-\&
-\& pthread_mutex_unlock (&mymutex);
-\& }
-.Ve
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_async_init (ev_async *, callback)" 4
-.IX Item "ev_async_init (ev_async *, callback)"
-Initialises and configures the async watcher \- it has no parameters of any
-kind. There is a \f(CW\*(C`ev_asynd_set\*(C'\fR macro, but using it is utterly pointless,
-believe me.
-.IP "ev_async_send (loop, ev_async *)" 4
-.IX Item "ev_async_send (loop, ev_async *)"
-Sends/signals/activates the given \f(CW\*(C`ev_async\*(C'\fR watcher, that is, feeds
-an \f(CW\*(C`EV_ASYNC\*(C'\fR event on the watcher into the event loop. Unlike
-\&\f(CW\*(C`ev_feed_event\*(C'\fR, this call is safe to do in other threads, signal or
-similar contexts (see the dicusssion of \f(CW\*(C`EV_ATOMIC_T\*(C'\fR in the embedding
-section below on what exactly this means).
-.Sp
-This call incurs the overhead of a syscall only once per loop iteration,
-so while the overhead might be noticable, it doesn't apply to repeated
-calls to \f(CW\*(C`ev_async_send\*(C'\fR.
-.IP "bool = ev_async_pending (ev_async *)" 4
-.IX Item "bool = ev_async_pending (ev_async *)"
-Returns a non-zero value when \f(CW\*(C`ev_async_send\*(C'\fR has been called on the
-watcher but the event has not yet been processed (or even noted) by the
-event loop.
-.Sp
-\&\f(CW\*(C`ev_async_send\*(C'\fR sets a flag in the watcher and wakes up the loop. When
-the loop iterates next and checks for the watcher to have become active,
-it will reset the flag again. \f(CW\*(C`ev_async_pending\*(C'\fR can be used to very
-quickly check wether invoking the loop might be a good idea.
-.Sp
-Not that this does \fInot\fR check wether the watcher itself is pending, only
-wether it has been requested to make this watcher pending.
-.SH "OTHER FUNCTIONS"
-.IX Header "OTHER FUNCTIONS"
-There are some other functions of possible interest. Described. Here. Now.
-.IP "ev_once (loop, int fd, int events, ev_tstamp timeout, callback)" 4
-.IX Item "ev_once (loop, int fd, int events, ev_tstamp timeout, callback)"
-This function combines a simple timer and an I/O watcher, calls your
-callback on whichever event happens first and automatically stop both
-watchers. This is useful if you want to wait for a single event on an fd
-or timeout without having to allocate/configure/start/stop/free one or
-more watchers yourself.
-.Sp
-If \f(CW\*(C`fd\*(C'\fR is less than 0, then no I/O watcher will be started and events
-is being ignored. Otherwise, an \f(CW\*(C`ev_io\*(C'\fR watcher for the given \f(CW\*(C`fd\*(C'\fR and
-\&\f(CW\*(C`events\*(C'\fR set will be craeted and started.
-.Sp
-If \f(CW\*(C`timeout\*(C'\fR is less than 0, then no timeout watcher will be
-started. Otherwise an \f(CW\*(C`ev_timer\*(C'\fR watcher with after = \f(CW\*(C`timeout\*(C'\fR (and
-repeat = 0) will be started. While \f(CW0\fR is a valid timeout, it is of
-dubious value.
-.Sp
-The callback has the type \f(CW\*(C`void (*cb)(int revents, void *arg)\*(C'\fR and gets
-passed an \f(CW\*(C`revents\*(C'\fR set like normal event callbacks (a combination of
-\&\f(CW\*(C`EV_ERROR\*(C'\fR, \f(CW\*(C`EV_READ\*(C'\fR, \f(CW\*(C`EV_WRITE\*(C'\fR or \f(CW\*(C`EV_TIMEOUT\*(C'\fR) and the \f(CW\*(C`arg\*(C'\fR
-value passed to \f(CW\*(C`ev_once\*(C'\fR:
-.Sp
-.Vb 7
-\& static void stdin_ready (int revents, void *arg)
-\& {
-\& if (revents & EV_TIMEOUT)
-\& /* doh, nothing entered */;
-\& else if (revents & EV_READ)
-\& /* stdin might have data for us, joy! */;
-\& }
-\&
-\& ev_once (STDIN_FILENO, EV_READ, 10., stdin_ready, 0);
-.Ve
-.IP "ev_feed_event (ev_loop *, watcher *, int revents)" 4
-.IX Item "ev_feed_event (ev_loop *, watcher *, int revents)"
-Feeds the given event set into the event loop, as if the specified event
-had happened for the specified watcher (which must be a pointer to an
-initialised but not necessarily started event watcher).
-.IP "ev_feed_fd_event (ev_loop *, int fd, int revents)" 4
-.IX Item "ev_feed_fd_event (ev_loop *, int fd, int revents)"
-Feed an event on the given fd, as if a file descriptor backend detected
-the given events it.
-.IP "ev_feed_signal_event (ev_loop *loop, int signum)" 4
-.IX Item "ev_feed_signal_event (ev_loop *loop, int signum)"
-Feed an event as if the given signal occured (\f(CW\*(C`loop\*(C'\fR must be the default
-loop!).
-.SH "LIBEVENT EMULATION"
-.IX Header "LIBEVENT EMULATION"
-Libev offers a compatibility emulation layer for libevent. It cannot
-emulate the internals of libevent, so here are some usage hints:
-.IP "\(bu" 4
-Use it by including <event.h>, as usual.
-.IP "\(bu" 4
-The following members are fully supported: ev_base, ev_callback,
-ev_arg, ev_fd, ev_res, ev_events.
-.IP "\(bu" 4
-Avoid using ev_flags and the EVLIST_*\-macros, while it is
-maintained by libev, it does not work exactly the same way as in libevent (consider
-it a private \s-1API\s0).
-.IP "\(bu" 4
-Priorities are not currently supported. Initialising priorities
-will fail and all watchers will have the same priority, even though there
-is an ev_pri field.
-.IP "\(bu" 4
-In libevent, the last base created gets the signals, in libev, the
-first base created (== the default loop) gets the signals.
-.IP "\(bu" 4
-Other members are not supported.
-.IP "\(bu" 4
-The libev emulation is \fInot\fR \s-1ABI\s0 compatible to libevent, you need
-to use the libev header file and library.
-.SH "\*(C+ SUPPORT"
-.IX Header " SUPPORT"
-Libev comes with some simplistic wrapper classes for \*(C+ that mainly allow
-you to use some convinience methods to start/stop watchers and also change
-the callback model to a model using method callbacks on objects.
-.PP
-To use it,
-.PP
-.Vb 1
-\& #include <ev++.h>
-.Ve
-.PP
-This automatically includes \fIev.h\fR and puts all of its definitions (many
-of them macros) into the global namespace. All \*(C+ specific things are
-put into the \f(CW\*(C`ev\*(C'\fR namespace. It should support all the same embedding
-options as \fIev.h\fR, most notably \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR.
-.PP
-Care has been taken to keep the overhead low. The only data member the \*(C+
-classes add (compared to plain C\-style watchers) is the event loop pointer
-that the watcher is associated with (or no additional members at all if
-you disable \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR when embedding libev).
-.PP
-Currently, functions, and static and non-static member functions can be
-used as callbacks. Other types should be easy to add as long as they only
-need one additional pointer for context. If you need support for other
-types of functors please contact the author (preferably after implementing
-it).
-.PP
-Here is a list of things available in the \f(CW\*(C`ev\*(C'\fR namespace:
-.ie n .IP """ev::READ""\fR, \f(CW""ev::WRITE"" etc." 4
-.el .IP "\f(CWev::READ\fR, \f(CWev::WRITE\fR etc." 4
-.IX Item "ev::READ, ev::WRITE etc."
-These are just enum values with the same values as the \f(CW\*(C`EV_READ\*(C'\fR etc.
-macros from \fIev.h\fR.
-.ie n .IP """ev::tstamp""\fR, \f(CW""ev::now""" 4
-.el .IP "\f(CWev::tstamp\fR, \f(CWev::now\fR" 4
-.IX Item "ev::tstamp, ev::now"
-Aliases to the same types/functions as with the \f(CW\*(C`ev_\*(C'\fR prefix.
-.ie n .IP """ev::io""\fR, \f(CW""ev::timer""\fR, \f(CW""ev::periodic""\fR, \f(CW""ev::idle""\fR, \f(CW""ev::sig"" etc." 4
-.el .IP "\f(CWev::io\fR, \f(CWev::timer\fR, \f(CWev::periodic\fR, \f(CWev::idle\fR, \f(CWev::sig\fR etc." 4
-.IX Item "ev::io, ev::timer, ev::periodic, ev::idle, ev::sig etc."
-For each \f(CW\*(C`ev_TYPE\*(C'\fR watcher in \fIev.h\fR there is a corresponding class of
-the same name in the \f(CW\*(C`ev\*(C'\fR namespace, with the exception of \f(CW\*(C`ev_signal\*(C'\fR
-which is called \f(CW\*(C`ev::sig\*(C'\fR to avoid clashes with the \f(CW\*(C`signal\*(C'\fR macro
-defines by many implementations.
-.Sp
-All of those classes have these methods:
-.RS 4
-.IP "ev::TYPE::TYPE ()" 4
-.IX Item "ev::TYPE::TYPE ()"
-.PD 0
-.IP "ev::TYPE::TYPE (struct ev_loop *)" 4
-.IX Item "ev::TYPE::TYPE (struct ev_loop *)"
-.IP "ev::TYPE::~TYPE" 4
-.IX Item "ev::TYPE::~TYPE"
-.PD
-The constructor (optionally) takes an event loop to associate the watcher
-with. If it is omitted, it will use \f(CW\*(C`EV_DEFAULT\*(C'\fR.
-.Sp
-The constructor calls \f(CW\*(C`ev_init\*(C'\fR for you, which means you have to call the
-\&\f(CW\*(C`set\*(C'\fR method before starting it.
-.Sp
-It will not set a callback, however: You have to call the templated \f(CW\*(C`set\*(C'\fR
-method to set a callback before you can start the watcher.
-.Sp
-(The reason why you have to use a method is a limitation in \*(C+ which does
-not allow explicit template arguments for constructors).
-.Sp
-The destructor automatically stops the watcher if it is active.
-.IP "w\->set<class, &class::method> (object *)" 4
-.IX Item "w->set<class, &class::method> (object *)"
-This method sets the callback method to call. The method has to have a
-signature of \f(CW\*(C`void (*)(ev_TYPE &, int)\*(C'\fR, it receives the watcher as
-first argument and the \f(CW\*(C`revents\*(C'\fR as second. The object must be given as
-parameter and is stored in the \f(CW\*(C`data\*(C'\fR member of the watcher.
-.Sp
-This method synthesizes efficient thunking code to call your method from
-the C callback that libev requires. If your compiler can inline your
-callback (i.e. it is visible to it at the place of the \f(CW\*(C`set\*(C'\fR call and
-your compiler is good :), then the method will be fully inlined into the
-thunking function, making it as fast as a direct C callback.
-.Sp
-Example: simple class declaration and watcher initialisation
-.Sp
-.Vb 4
-\& struct myclass
-\& {
-\& void io_cb (ev::io &w, int revents) { }
-\& }
-\&
-\& myclass obj;
-\& ev::io iow;
-\& iow.set <myclass, &myclass::io_cb> (&obj);
-.Ve
-.IP "w\->set<function> (void *data = 0)" 4
-.IX Item "w->set<function> (void *data = 0)"
-Also sets a callback, but uses a static method or plain function as
-callback. The optional \f(CW\*(C`data\*(C'\fR argument will be stored in the watcher's
-\&\f(CW\*(C`data\*(C'\fR member and is free for you to use.
-.Sp
-The prototype of the \f(CW\*(C`function\*(C'\fR must be \f(CW\*(C`void (*)(ev::TYPE &w, int)\*(C'\fR.
-.Sp
-See the method\-\f(CW\*(C`set\*(C'\fR above for more details.
-.Sp
-Example:
-.Sp
-.Vb 2
-\& static void io_cb (ev::io &w, int revents) { }
-\& iow.set <io_cb> ();
-.Ve
-.IP "w\->set (struct ev_loop *)" 4
-.IX Item "w->set (struct ev_loop *)"
-Associates a different \f(CW\*(C`struct ev_loop\*(C'\fR with this watcher. You can only
-do this when the watcher is inactive (and not pending either).
-.IP "w\->set ([args])" 4
-.IX Item "w->set ([args])"
-Basically the same as \f(CW\*(C`ev_TYPE_set\*(C'\fR, with the same args. Must be
-called at least once. Unlike the C counterpart, an active watcher gets
-automatically stopped and restarted when reconfiguring it with this
-method.
-.IP "w\->start ()" 4
-.IX Item "w->start ()"
-Starts the watcher. Note that there is no \f(CW\*(C`loop\*(C'\fR argument, as the
-constructor already stores the event loop.
-.IP "w\->stop ()" 4
-.IX Item "w->stop ()"
-Stops the watcher if it is active. Again, no \f(CW\*(C`loop\*(C'\fR argument.
-.ie n .IP "w\->again () (""ev::timer""\fR, \f(CW""ev::periodic"" only)" 4
-.el .IP "w\->again () (\f(CWev::timer\fR, \f(CWev::periodic\fR only)" 4
-.IX Item "w->again () (ev::timer, ev::periodic only)"
-For \f(CW\*(C`ev::timer\*(C'\fR and \f(CW\*(C`ev::periodic\*(C'\fR, this invokes the corresponding
-\&\f(CW\*(C`ev_TYPE_again\*(C'\fR function.
-.ie n .IP "w\->sweep () (""ev::embed"" only)" 4
-.el .IP "w\->sweep () (\f(CWev::embed\fR only)" 4
-.IX Item "w->sweep () (ev::embed only)"
-Invokes \f(CW\*(C`ev_embed_sweep\*(C'\fR.
-.ie n .IP "w\->update () (""ev::stat"" only)" 4
-.el .IP "w\->update () (\f(CWev::stat\fR only)" 4
-.IX Item "w->update () (ev::stat only)"
-Invokes \f(CW\*(C`ev_stat_stat\*(C'\fR.
-.RE
-.RS 4
-.RE
-.PP
-Example: Define a class with an \s-1IO\s0 and idle watcher, start one of them in
-the constructor.
-.PP
-.Vb 4
-\& class myclass
-\& {
-\& ev::io io; void io_cb (ev::io &w, int revents);
-\& ev:idle idle void idle_cb (ev::idle &w, int revents);
-\&
-\& myclass (int fd)
-\& {
-\& io .set <myclass, &myclass::io_cb > (this);
-\& idle.set <myclass, &myclass::idle_cb> (this);
-\&
-\& io.start (fd, ev::READ);
-\& }
-\& };
-.Ve
-.SH "OTHER LANGUAGE BINDINGS"
-.IX Header "OTHER LANGUAGE BINDINGS"
-Libev does not offer other language bindings itself, but bindings for a
-numbe rof languages exist in the form of third-party packages. If you know
-any interesting language binding in addition to the ones listed here, drop
-me a note.
-.IP "Perl" 4
-.IX Item "Perl"
-The \s-1EV\s0 module implements the full libev \s-1API\s0 and is actually used to test
-libev. \s-1EV\s0 is developed together with libev. Apart from the \s-1EV\s0 core module,
-there are additional modules that implement libev-compatible interfaces
-to \f(CW\*(C`libadns\*(C'\fR (\f(CW\*(C`EV::ADNS\*(C'\fR), \f(CW\*(C`Net::SNMP\*(C'\fR (\f(CW\*(C`Net::SNMP::EV\*(C'\fR) and the
-\&\f(CW\*(C`libglib\*(C'\fR event core (\f(CW\*(C`Glib::EV\*(C'\fR and \f(CW\*(C`EV::Glib\*(C'\fR).
-.Sp
-It can be found and installed via \s-1CPAN\s0, its homepage is found at
-<http://software.schmorp.de/pkg/EV>.
-.IP "Ruby" 4
-.IX Item "Ruby"
-Tony Arcieri has written a ruby extension that offers access to a subset
-of the libev \s-1API\s0 and adds filehandle abstractions, asynchronous \s-1DNS\s0 and
-more on top of it. It can be found via gem servers. Its homepage is at
-<http://rev.rubyforge.org/>.
-.IP "D" 4
-.IX Item "D"
-Leandro Lucarella has written a D language binding (\fIev.d\fR) for libev, to
-be found at <http://git.llucax.com.ar/?p=software/ev.d.git;a=summary>.
-.SH "MACRO MAGIC"
-.IX Header "MACRO MAGIC"
-Libev can be compiled with a variety of options, the most fundamantal
-of which is \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR. This option determines whether (most)
-functions and callbacks have an initial \f(CW\*(C`struct ev_loop *\*(C'\fR argument.
-.PP
-To make it easier to write programs that cope with either variant, the
-following macros are defined:
-.ie n .IP """EV_A""\fR, \f(CW""EV_A_""" 4
-.el .IP "\f(CWEV_A\fR, \f(CWEV_A_\fR" 4
-.IX Item "EV_A, EV_A_"
-This provides the loop \fIargument\fR for functions, if one is required (\*(L"ev
-loop argument\*(R"). The \f(CW\*(C`EV_A\*(C'\fR form is used when this is the sole argument,
-\&\f(CW\*(C`EV_A_\*(C'\fR is used when other arguments are following. Example:
-.Sp
-.Vb 3
-\& ev_unref (EV_A);
-\& ev_timer_add (EV_A_ watcher);
-\& ev_loop (EV_A_ 0);
-.Ve
-.Sp
-It assumes the variable \f(CW\*(C`loop\*(C'\fR of type \f(CW\*(C`struct ev_loop *\*(C'\fR is in scope,
-which is often provided by the following macro.
-.ie n .IP """EV_P""\fR, \f(CW""EV_P_""" 4
-.el .IP "\f(CWEV_P\fR, \f(CWEV_P_\fR" 4
-.IX Item "EV_P, EV_P_"
-This provides the loop \fIparameter\fR for functions, if one is required (\*(L"ev
-loop parameter\*(R"). The \f(CW\*(C`EV_P\*(C'\fR form is used when this is the sole parameter,
-\&\f(CW\*(C`EV_P_\*(C'\fR is used when other parameters are following. Example:
-.Sp
-.Vb 2
-\& // this is how ev_unref is being declared
-\& static void ev_unref (EV_P);
-\&
-\& // this is how you can declare your typical callback
-\& static void cb (EV_P_ ev_timer *w, int revents)
-.Ve
-.Sp
-It declares a parameter \f(CW\*(C`loop\*(C'\fR of type \f(CW\*(C`struct ev_loop *\*(C'\fR, quite
-suitable for use with \f(CW\*(C`EV_A\*(C'\fR.
-.ie n .IP """EV_DEFAULT""\fR, \f(CW""EV_DEFAULT_""" 4
-.el .IP "\f(CWEV_DEFAULT\fR, \f(CWEV_DEFAULT_\fR" 4
-.IX Item "EV_DEFAULT, EV_DEFAULT_"
-Similar to the other two macros, this gives you the value of the default
-loop, if multiple loops are supported (\*(L"ev loop default\*(R").
-.ie n .IP """EV_DEFAULT_UC""\fR, \f(CW""EV_DEFAULT_UC_""" 4
-.el .IP "\f(CWEV_DEFAULT_UC\fR, \f(CWEV_DEFAULT_UC_\fR" 4
-.IX Item "EV_DEFAULT_UC, EV_DEFAULT_UC_"
-Usage identical to \f(CW\*(C`EV_DEFAULT\*(C'\fR and \f(CW\*(C`EV_DEFAULT_\*(C'\fR, but requires that the
-default loop has been initialised (\f(CW\*(C`UC\*(C'\fR == unchecked). Their behaviour
-is undefined when the default loop has not been initialised by a previous
-execution of \f(CW\*(C`EV_DEFAULT\*(C'\fR, \f(CW\*(C`EV_DEFAULT_\*(C'\fR or \f(CW\*(C`ev_default_init (...)\*(C'\fR.
-.Sp
-It is often prudent to use \f(CW\*(C`EV_DEFAULT\*(C'\fR when initialising the first
-watcher in a function but use \f(CW\*(C`EV_DEFAULT_UC\*(C'\fR afterwards.
-.PP
-Example: Declare and initialise a check watcher, utilising the above
-macros so it will work regardless of whether multiple loops are supported
-or not.
-.PP
-.Vb 5
-\& static void
-\& check_cb (EV_P_ ev_timer *w, int revents)
-\& {
-\& ev_check_stop (EV_A_ w);
-\& }
-\&
-\& ev_check check;
-\& ev_check_init (&check, check_cb);
-\& ev_check_start (EV_DEFAULT_ &check);
-\& ev_loop (EV_DEFAULT_ 0);
-.Ve
-.SH "EMBEDDING"
-.IX Header "EMBEDDING"
-Libev can (and often is) directly embedded into host
-applications. Examples of applications that embed it include the Deliantra
-Game Server, the \s-1EV\s0 perl module, the \s-1GNU\s0 Virtual Private Ethernet (gvpe)
-and rxvt-unicode.
-.PP
-The goal is to enable you to just copy the necessary files into your
-source directory without having to change even a single line in them, so
-you can easily upgrade by simply copying (or having a checked-out copy of
-libev somewhere in your source tree).
-.Sh "\s-1FILESETS\s0"
-.IX Subsection "FILESETS"
-Depending on what features you need you need to include one or more sets of files
-in your app.
-.PP
-\fI\s-1CORE\s0 \s-1EVENT\s0 \s-1LOOP\s0\fR
-.IX Subsection "CORE EVENT LOOP"
-.PP
-To include only the libev core (all the \f(CW\*(C`ev_*\*(C'\fR functions), with manual
-configuration (no autoconf):
-.PP
-.Vb 2
-\& #define EV_STANDALONE 1
-\& #include "ev.c"
-.Ve
-.PP
-This will automatically include \fIev.h\fR, too, and should be done in a
-single C source file only to provide the function implementations. To use
-it, do the same for \fIev.h\fR in all files wishing to use this \s-1API\s0 (best
-done by writing a wrapper around \fIev.h\fR that you can include instead and
-where you can put other configuration options):
-.PP
-.Vb 2
-\& #define EV_STANDALONE 1
-\& #include "ev.h"
-.Ve
-.PP
-Both header files and implementation files can be compiled with a \*(C+
-compiler (at least, thats a stated goal, and breakage will be treated
-as a bug).
-.PP
-You need the following files in your source tree, or in a directory
-in your include path (e.g. in libev/ when using \-Ilibev):
-.PP
-.Vb 4
-\& ev.h
-\& ev.c
-\& ev_vars.h
-\& ev_wrap.h
-\&
-\& ev_win32.c required on win32 platforms only
-\&
-\& ev_select.c only when select backend is enabled (which is enabled by default)
-\& ev_poll.c only when poll backend is enabled (disabled by default)
-\& ev_epoll.c only when the epoll backend is enabled (disabled by default)
-\& ev_kqueue.c only when the kqueue backend is enabled (disabled by default)
-\& ev_port.c only when the solaris port backend is enabled (disabled by default)
-.Ve
-.PP
-\&\fIev.c\fR includes the backend files directly when enabled, so you only need
-to compile this single file.
-.PP
-\fI\s-1LIBEVENT\s0 \s-1COMPATIBILITY\s0 \s-1API\s0\fR
-.IX Subsection "LIBEVENT COMPATIBILITY API"
-.PP
-To include the libevent compatibility \s-1API\s0, also include:
-.PP
-.Vb 1
-\& #include "event.c"
-.Ve
-.PP
-in the file including \fIev.c\fR, and:
-.PP
-.Vb 1
-\& #include "event.h"
-.Ve
-.PP
-in the files that want to use the libevent \s-1API\s0. This also includes \fIev.h\fR.
-.PP
-You need the following additional files for this:
-.PP
-.Vb 2
-\& event.h
-\& event.c
-.Ve
-.PP
-\fI\s-1AUTOCONF\s0 \s-1SUPPORT\s0\fR
-.IX Subsection "AUTOCONF SUPPORT"
-.PP
-Instead of using \f(CW\*(C`EV_STANDALONE=1\*(C'\fR and providing your config in
-whatever way you want, you can also \f(CW\*(C`m4_include([libev.m4])\*(C'\fR in your
-\&\fIconfigure.ac\fR and leave \f(CW\*(C`EV_STANDALONE\*(C'\fR undefined. \fIev.c\fR will then
-include \fIconfig.h\fR and configure itself accordingly.
-.PP
-For this of course you need the m4 file:
-.PP
-.Vb 1
-\& libev.m4
-.Ve
-.Sh "\s-1PREPROCESSOR\s0 \s-1SYMBOLS/MACROS\s0"
-.IX Subsection "PREPROCESSOR SYMBOLS/MACROS"
-Libev can be configured via a variety of preprocessor symbols you have to
-define before including any of its files. The default in the absense of
-autoconf is noted for every option.
-.IP "\s-1EV_STANDALONE\s0" 4
-.IX Item "EV_STANDALONE"
-Must always be \f(CW1\fR if you do not use autoconf configuration, which
-keeps libev from including \fIconfig.h\fR, and it also defines dummy
-implementations for some libevent functions (such as logging, which is not
-supported). It will also not define any of the structs usually found in
-\&\fIevent.h\fR that are not directly supported by the libev core alone.
-.IP "\s-1EV_USE_MONOTONIC\s0" 4
-.IX Item "EV_USE_MONOTONIC"
-If defined to be \f(CW1\fR, libev will try to detect the availability of the
-monotonic clock option at both compiletime and runtime. Otherwise no use
-of the monotonic clock option will be attempted. If you enable this, you
-usually have to link against librt or something similar. Enabling it when
-the functionality isn't available is safe, though, although you have
-to make sure you link against any libraries where the \f(CW\*(C`clock_gettime\*(C'\fR
-function is hiding in (often \fI\-lrt\fR).
-.IP "\s-1EV_USE_REALTIME\s0" 4
-.IX Item "EV_USE_REALTIME"
-If defined to be \f(CW1\fR, libev will try to detect the availability of the
-realtime clock option at compiletime (and assume its availability at
-runtime if successful). Otherwise no use of the realtime clock option will
-be attempted. This effectively replaces \f(CW\*(C`gettimeofday\*(C'\fR by \f(CW\*(C`clock_get
-(CLOCK_REALTIME, ...)\*(C'\fR and will not normally affect correctness. See the
-note about libraries in the description of \f(CW\*(C`EV_USE_MONOTONIC\*(C'\fR, though.
-.IP "\s-1EV_USE_NANOSLEEP\s0" 4
-.IX Item "EV_USE_NANOSLEEP"
-If defined to be \f(CW1\fR, libev will assume that \f(CW\*(C`nanosleep ()\*(C'\fR is available
-and will use it for delays. Otherwise it will use \f(CW\*(C`select ()\*(C'\fR.
-.IP "\s-1EV_USE_EVENTFD\s0" 4
-.IX Item "EV_USE_EVENTFD"
-If defined to be \f(CW1\fR, then libev will assume that \f(CW\*(C`eventfd ()\*(C'\fR is
-available and will probe for kernel support at runtime. This will improve
-\&\f(CW\*(C`ev_signal\*(C'\fR and \f(CW\*(C`ev_async\*(C'\fR performance and reduce resource consumption.
-If undefined, it will be enabled if the headers indicate GNU/Linux + Glibc
-2.7 or newer, otherwise disabled.
-.IP "\s-1EV_USE_SELECT\s0" 4
-.IX Item "EV_USE_SELECT"
-If undefined or defined to be \f(CW1\fR, libev will compile in support for the
-\&\f(CW\*(C`select\*(C'\fR(2) backend. No attempt at autodetection will be done: if no
-other method takes over, select will be it. Otherwise the select backend
-will not be compiled in.
-.IP "\s-1EV_SELECT_USE_FD_SET\s0" 4
-.IX Item "EV_SELECT_USE_FD_SET"
-If defined to \f(CW1\fR, then the select backend will use the system \f(CW\*(C`fd_set\*(C'\fR
-structure. This is useful if libev doesn't compile due to a missing
-\&\f(CW\*(C`NFDBITS\*(C'\fR or \f(CW\*(C`fd_mask\*(C'\fR definition or it misguesses the bitset layout on
-exotic systems. This usually limits the range of file descriptors to some
-low limit such as 1024 or might have other limitations (winsocket only
-allows 64 sockets). The \f(CW\*(C`FD_SETSIZE\*(C'\fR macro, set before compilation, might
-influence the size of the \f(CW\*(C`fd_set\*(C'\fR used.
-.IP "\s-1EV_SELECT_IS_WINSOCKET\s0" 4
-.IX Item "EV_SELECT_IS_WINSOCKET"
-When defined to \f(CW1\fR, the select backend will assume that
-select/socket/connect etc. don't understand file descriptors but
-wants osf handles on win32 (this is the case when the select to
-be used is the winsock select). This means that it will call
-\&\f(CW\*(C`_get_osfhandle\*(C'\fR on the fd to convert it to an \s-1OS\s0 handle. Otherwise,
-it is assumed that all these functions actually work on fds, even
-on win32. Should not be defined on non\-win32 platforms.
-.IP "\s-1EV_FD_TO_WIN32_HANDLE\s0" 4
-.IX Item "EV_FD_TO_WIN32_HANDLE"
-If \f(CW\*(C`EV_SELECT_IS_WINSOCKET\*(C'\fR is enabled, then libev needs a way to map
-file descriptors to socket handles. When not defining this symbol (the
-default), then libev will call \f(CW\*(C`_get_osfhandle\*(C'\fR, which is usually
-correct. In some cases, programs use their own file descriptor management,
-in which case they can provide this function to map fds to socket handles.
-.IP "\s-1EV_USE_POLL\s0" 4
-.IX Item "EV_USE_POLL"
-If defined to be \f(CW1\fR, libev will compile in support for the \f(CW\*(C`poll\*(C'\fR(2)
-backend. Otherwise it will be enabled on non\-win32 platforms. It
-takes precedence over select.
-.IP "\s-1EV_USE_EPOLL\s0" 4
-.IX Item "EV_USE_EPOLL"
-If defined to be \f(CW1\fR, libev will compile in support for the Linux
-\&\f(CW\*(C`epoll\*(C'\fR(7) backend. Its availability will be detected at runtime,
-otherwise another method will be used as fallback. This is the preferred
-backend for GNU/Linux systems. If undefined, it will be enabled if the
-headers indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled.
-.IP "\s-1EV_USE_KQUEUE\s0" 4
-.IX Item "EV_USE_KQUEUE"
-If defined to be \f(CW1\fR, libev will compile in support for the \s-1BSD\s0 style
-\&\f(CW\*(C`kqueue\*(C'\fR(2) backend. Its actual availability will be detected at runtime,
-otherwise another method will be used as fallback. This is the preferred
-backend for \s-1BSD\s0 and BSD-like systems, although on most BSDs kqueue only
-supports some types of fds correctly (the only platform we found that
-supports ptys for example was NetBSD), so kqueue might be compiled in, but
-not be used unless explicitly requested. The best way to use it is to find
-out whether kqueue supports your type of fd properly and use an embedded
-kqueue loop.
-.IP "\s-1EV_USE_PORT\s0" 4
-.IX Item "EV_USE_PORT"
-If defined to be \f(CW1\fR, libev will compile in support for the Solaris
-10 port style backend. Its availability will be detected at runtime,
-otherwise another method will be used as fallback. This is the preferred
-backend for Solaris 10 systems.
-.IP "\s-1EV_USE_DEVPOLL\s0" 4
-.IX Item "EV_USE_DEVPOLL"
-reserved for future expansion, works like the \s-1USE\s0 symbols above.
-.IP "\s-1EV_USE_INOTIFY\s0" 4
-.IX Item "EV_USE_INOTIFY"
-If defined to be \f(CW1\fR, libev will compile in support for the Linux inotify
-interface to speed up \f(CW\*(C`ev_stat\*(C'\fR watchers. Its actual availability will
-be detected at runtime. If undefined, it will be enabled if the headers
-indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled.
-.IP "\s-1EV_ATOMIC_T\s0" 4
-.IX Item "EV_ATOMIC_T"
-Libev requires an integer type (suitable for storing \f(CW0\fR or \f(CW1\fR) whose
-access is atomic with respect to other threads or signal contexts. No such
-type is easily found in the C language, so you can provide your own type
-that you know is safe for your purposes. It is used both for signal handler \*(L"locking\*(R"
-as well as for signal and thread safety in \f(CW\*(C`ev_async\*(C'\fR watchers.
-.Sp
-In the absense of this define, libev will use \f(CW\*(C`sig_atomic_t volatile\*(C'\fR
-(from \fIsignal.h\fR), which is usually good enough on most platforms.
-.IP "\s-1EV_H\s0" 4
-.IX Item "EV_H"
-The name of the \fIev.h\fR header file used to include it. The default if
-undefined is \f(CW"ev.h"\fR in \fIevent.h\fR, \fIev.c\fR and \fIev++.h\fR. This can be
-used to virtually rename the \fIev.h\fR header file in case of conflicts.
-.IP "\s-1EV_CONFIG_H\s0" 4
-.IX Item "EV_CONFIG_H"
-If \f(CW\*(C`EV_STANDALONE\*(C'\fR isn't \f(CW1\fR, this variable can be used to override
-\&\fIev.c\fR's idea of where to find the \fIconfig.h\fR file, similarly to
-\&\f(CW\*(C`EV_H\*(C'\fR, above.
-.IP "\s-1EV_EVENT_H\s0" 4
-.IX Item "EV_EVENT_H"
-Similarly to \f(CW\*(C`EV_H\*(C'\fR, this macro can be used to override \fIevent.c\fR's idea
-of how the \fIevent.h\fR header can be found, the default is \f(CW"event.h"\fR.
-.IP "\s-1EV_PROTOTYPES\s0" 4
-.IX Item "EV_PROTOTYPES"
-If defined to be \f(CW0\fR, then \fIev.h\fR will not define any function
-prototypes, but still define all the structs and other symbols. This is
-occasionally useful if you want to provide your own wrapper functions
-around libev functions.
-.IP "\s-1EV_MULTIPLICITY\s0" 4
-.IX Item "EV_MULTIPLICITY"
-If undefined or defined to \f(CW1\fR, then all event-loop-specific functions
-will have the \f(CW\*(C`struct ev_loop *\*(C'\fR as first argument, and you can create
-additional independent event loops. Otherwise there will be no support
-for multiple event loops and there is no first event loop pointer
-argument. Instead, all functions act on the single default loop.
-.IP "\s-1EV_MINPRI\s0" 4
-.IX Item "EV_MINPRI"
-.PD 0
-.IP "\s-1EV_MAXPRI\s0" 4
-.IX Item "EV_MAXPRI"
-.PD
-The range of allowed priorities. \f(CW\*(C`EV_MINPRI\*(C'\fR must be smaller or equal to
-\&\f(CW\*(C`EV_MAXPRI\*(C'\fR, but otherwise there are no non-obvious limitations. You can
-provide for more priorities by overriding those symbols (usually defined
-to be \f(CW\*(C`\-2\*(C'\fR and \f(CW2\fR, respectively).
-.Sp
-When doing priority-based operations, libev usually has to linearly search
-all the priorities, so having many of them (hundreds) uses a lot of space
-and time, so using the defaults of five priorities (\-2 .. +2) is usually
-fine.
-.Sp
-If your embedding app does not need any priorities, defining these both to
-\&\f(CW0\fR will save some memory and cpu.
-.IP "\s-1EV_PERIODIC_ENABLE\s0" 4
-.IX Item "EV_PERIODIC_ENABLE"
-If undefined or defined to be \f(CW1\fR, then periodic timers are supported. If
-defined to be \f(CW0\fR, then they are not. Disabling them saves a few kB of
-code.
-.IP "\s-1EV_IDLE_ENABLE\s0" 4
-.IX Item "EV_IDLE_ENABLE"
-If undefined or defined to be \f(CW1\fR, then idle watchers are supported. If
-defined to be \f(CW0\fR, then they are not. Disabling them saves a few kB of
-code.
-.IP "\s-1EV_EMBED_ENABLE\s0" 4
-.IX Item "EV_EMBED_ENABLE"
-If undefined or defined to be \f(CW1\fR, then embed watchers are supported. If
-defined to be \f(CW0\fR, then they are not.
-.IP "\s-1EV_STAT_ENABLE\s0" 4
-.IX Item "EV_STAT_ENABLE"
-If undefined or defined to be \f(CW1\fR, then stat watchers are supported. If
-defined to be \f(CW0\fR, then they are not.
-.IP "\s-1EV_FORK_ENABLE\s0" 4
-.IX Item "EV_FORK_ENABLE"
-If undefined or defined to be \f(CW1\fR, then fork watchers are supported. If
-defined to be \f(CW0\fR, then they are not.
-.IP "\s-1EV_ASYNC_ENABLE\s0" 4
-.IX Item "EV_ASYNC_ENABLE"
-If undefined or defined to be \f(CW1\fR, then async watchers are supported. If
-defined to be \f(CW0\fR, then they are not.
-.IP "\s-1EV_MINIMAL\s0" 4
-.IX Item "EV_MINIMAL"
-If you need to shave off some kilobytes of code at the expense of some
-speed, define this symbol to \f(CW1\fR. Currently this is used to override some
-inlining decisions, saves roughly 30% codesize of amd64. It also selects a
-much smaller 2\-heap for timer management over the default 4\-heap.
-.IP "\s-1EV_PID_HASHSIZE\s0" 4
-.IX Item "EV_PID_HASHSIZE"
-\&\f(CW\*(C`ev_child\*(C'\fR watchers use a small hash table to distribute workload by
-pid. The default size is \f(CW16\fR (or \f(CW1\fR with \f(CW\*(C`EV_MINIMAL\*(C'\fR), usually more
-than enough. If you need to manage thousands of children you might want to
-increase this value (\fImust\fR be a power of two).
-.IP "\s-1EV_INOTIFY_HASHSIZE\s0" 4
-.IX Item "EV_INOTIFY_HASHSIZE"
-\&\f(CW\*(C`ev_stat\*(C'\fR watchers use a small hash table to distribute workload by
-inotify watch id. The default size is \f(CW16\fR (or \f(CW1\fR with \f(CW\*(C`EV_MINIMAL\*(C'\fR),
-usually more than enough. If you need to manage thousands of \f(CW\*(C`ev_stat\*(C'\fR
-watchers you might want to increase this value (\fImust\fR be a power of
-two).
-.IP "\s-1EV_USE_4HEAP\s0" 4
-.IX Item "EV_USE_4HEAP"
-Heaps are not very cache-efficient. To improve the cache-efficiency of the
-timer and periodics heap, libev uses a 4\-heap when this symbol is defined
-to \f(CW1\fR. The 4\-heap uses more complicated (longer) code but has a
-noticable after performance with many (thousands) of watchers.
-.Sp
-The default is \f(CW1\fR unless \f(CW\*(C`EV_MINIMAL\*(C'\fR is set in which case it is \f(CW0\fR
-(disabled).
-.IP "\s-1EV_HEAP_CACHE_AT\s0" 4
-.IX Item "EV_HEAP_CACHE_AT"
-Heaps are not very cache-efficient. To improve the cache-efficiency of the
-timer and periodics heap, libev can cache the timestamp (\fIat\fR) within
-the heap structure (selected by defining \f(CW\*(C`EV_HEAP_CACHE_AT\*(C'\fR to \f(CW1\fR),
-which uses 8\-12 bytes more per watcher and a few hundred bytes more code,
-but avoids random read accesses on heap changes. This noticably improves
-performance noticably with with many (hundreds) of watchers.
-.Sp
-The default is \f(CW1\fR unless \f(CW\*(C`EV_MINIMAL\*(C'\fR is set in which case it is \f(CW0\fR
-(disabled).
-.IP "\s-1EV_COMMON\s0" 4
-.IX Item "EV_COMMON"
-By default, all watchers have a \f(CW\*(C`void *data\*(C'\fR member. By redefining
-this macro to a something else you can include more and other types of
-members. You have to define it each time you include one of the files,
-though, and it must be identical each time.
-.Sp
-For example, the perl \s-1EV\s0 module uses something like this:
-.Sp
-.Vb 3
-\& #define EV_COMMON \e
-\& SV *self; /* contains this struct */ \e
-\& SV *cb_sv, *fh /* note no trailing ";" */
-.Ve
-.IP "\s-1EV_CB_DECLARE\s0 (type)" 4
-.IX Item "EV_CB_DECLARE (type)"
-.PD 0
-.IP "\s-1EV_CB_INVOKE\s0 (watcher, revents)" 4
-.IX Item "EV_CB_INVOKE (watcher, revents)"
-.IP "ev_set_cb (ev, cb)" 4
-.IX Item "ev_set_cb (ev, cb)"
-.PD
-Can be used to change the callback member declaration in each watcher,
-and the way callbacks are invoked and set. Must expand to a struct member
-definition and a statement, respectively. See the \fIev.h\fR header file for
-their default definitions. One possible use for overriding these is to
-avoid the \f(CW\*(C`struct ev_loop *\*(C'\fR as first argument in all cases, or to use
-method calls instead of plain function calls in \*(C+.
-.Sh "\s-1EXPORTED\s0 \s-1API\s0 \s-1SYMBOLS\s0"
-.IX Subsection "EXPORTED API SYMBOLS"
-If you need to re-export the \s-1API\s0 (e.g. via a dll) and you need a list of
-exported symbols, you can use the provided \fISymbol.*\fR files which list
-all public symbols, one per line:
-.PP
-.Vb 2
-\& Symbols.ev for libev proper
-\& Symbols.event for the libevent emulation
-.Ve
-.PP
-This can also be used to rename all public symbols to avoid clashes with
-multiple versions of libev linked together (which is obviously bad in
-itself, but sometimes it is inconvinient to avoid this).
-.PP
-A sed command like this will create wrapper \f(CW\*(C`#define\*(C'\fR's that you need to
-include before including \fIev.h\fR:
-.PP
-.Vb 1
-\& <Symbols.ev sed \-e "s/.*/#define & myprefix_&/" >wrap.h
-.Ve
-.PP
-This would create a file \fIwrap.h\fR which essentially looks like this:
-.PP
-.Vb 4
-\& #define ev_backend myprefix_ev_backend
-\& #define ev_check_start myprefix_ev_check_start
-\& #define ev_check_stop myprefix_ev_check_stop
-\& ...
-.Ve
-.Sh "\s-1EXAMPLES\s0"
-.IX Subsection "EXAMPLES"
-For a real-world example of a program the includes libev
-verbatim, you can have a look at the \s-1EV\s0 perl module
-(<http://software.schmorp.de/pkg/EV.html>). It has the libev files in
-the \fIlibev/\fR subdirectory and includes them in the \fI\s-1EV/EVAPI\s0.h\fR (public
-interface) and \fI\s-1EV\s0.xs\fR (implementation) files. Only the \fI\s-1EV\s0.xs\fR file
-will be compiled. It is pretty complex because it provides its own header
-file.
-.PP
-The usage in rxvt-unicode is simpler. It has a \fIev_cpp.h\fR header file
-that everybody includes and which overrides some configure choices:
-.PP
-.Vb 9
-\& #define EV_MINIMAL 1
-\& #define EV_USE_POLL 0
-\& #define EV_MULTIPLICITY 0
-\& #define EV_PERIODIC_ENABLE 0
-\& #define EV_STAT_ENABLE 0
-\& #define EV_FORK_ENABLE 0
-\& #define EV_CONFIG_H <config.h>
-\& #define EV_MINPRI 0
-\& #define EV_MAXPRI 0
-\&
-\& #include "ev++.h"
-.Ve
-.PP
-And a \fIev_cpp.C\fR implementation file that contains libev proper and is compiled:
-.PP
-.Vb 2
-\& #include "ev_cpp.h"
-\& #include "ev.c"
-.Ve
-.SH "THREADS AND COROUTINES"
-.IX Header "THREADS AND COROUTINES"
-.Sh "\s-1THREADS\s0"
-.IX Subsection "THREADS"
-Libev itself is completely threadsafe, but it uses no locking. This
-means that you can use as many loops as you want in parallel, as long as
-only one thread ever calls into one libev function with the same loop
-parameter.
-.PP
-Or put differently: calls with different loop parameters can be done in
-parallel from multiple threads, calls with the same loop parameter must be
-done serially (but can be done from different threads, as long as only one
-thread ever is inside a call at any point in time, e.g. by using a mutex
-per loop).
-.PP
-If you want to know which design is best for your problem, then I cannot
-help you but by giving some generic advice:
-.IP "\(bu" 4
-most applications have a main thread: use the default libev loop
-in that thread, or create a seperate thread running only the default loop.
-.Sp
-This helps integrating other libraries or software modules that use libev
-themselves and don't care/know about threading.
-.IP "\(bu" 4
-one loop per thread is usually a good model.
-.Sp
-Doing this is almost never wrong, sometimes a better-performance model
-exists, but it is always a good start.
-.IP "\(bu" 4
-other models exist, such as the leader/follower pattern, where one
-loop is handed through multiple threads in a kind of round-robbin fashion.
-.Sp
-Chosing a model is hard \- look around, learn, know that usually you cna do
-better than you currently do :\-)
-.IP "\(bu" 4
-often you need to talk to some other thread which blocks in the
-event loop \- \f(CW\*(C`ev_async\*(C'\fR watchers can be used to wake them up from other
-threads safely (or from signal contexts...).
-.Sh "\s-1COROUTINES\s0"
-.IX Subsection "COROUTINES"
-Libev is much more accomodating to coroutines (\*(L"cooperative threads\*(R"):
-libev fully supports nesting calls to it's functions from different
-coroutines (e.g. you can call \f(CW\*(C`ev_loop\*(C'\fR on the same loop from two
-different coroutines and switch freely between both coroutines running the
-loop, as long as you don't confuse yourself). The only exception is that
-you must not do this from \f(CW\*(C`ev_periodic\*(C'\fR reschedule callbacks.
-.PP
-Care has been invested into making sure that libev does not keep local
-state inside \f(CW\*(C`ev_loop\*(C'\fR, and other calls do not usually allow coroutine
-switches.
-.SH "COMPLEXITIES"
-.IX Header "COMPLEXITIES"
-In this section the complexities of (many of) the algorithms used inside
-libev will be explained. For complexity discussions about backends see the
-documentation for \f(CW\*(C`ev_default_init\*(C'\fR.
-.PP
-All of the following are about amortised time: If an array needs to be
-extended, libev needs to realloc and move the whole array, but this
-happens asymptotically never with higher number of elements, so O(1) might
-mean it might do a lengthy realloc operation in rare cases, but on average
-it is much faster and asymptotically approaches constant time.
-.IP "Starting and stopping timer/periodic watchers: O(log skipped_other_timers)" 4
-.IX Item "Starting and stopping timer/periodic watchers: O(log skipped_other_timers)"
-This means that, when you have a watcher that triggers in one hour and
-there are 100 watchers that would trigger before that then inserting will
-have to skip roughly seven (\f(CW\*(C`ld 100\*(C'\fR) of these watchers.
-.IP "Changing timer/periodic watchers (by autorepeat or calling again): O(log skipped_other_timers)" 4
-.IX Item "Changing timer/periodic watchers (by autorepeat or calling again): O(log skipped_other_timers)"
-That means that changing a timer costs less than removing/adding them
-as only the relative motion in the event queue has to be paid for.
-.IP "Starting io/check/prepare/idle/signal/child/fork/async watchers: O(1)" 4
-.IX Item "Starting io/check/prepare/idle/signal/child/fork/async watchers: O(1)"
-These just add the watcher into an array or at the head of a list.
-.IP "Stopping check/prepare/idle/fork/async watchers: O(1)" 4
-.IX Item "Stopping check/prepare/idle/fork/async watchers: O(1)"
-.PD 0
-.IP "Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % \s-1EV_PID_HASHSIZE\s0))" 4
-.IX Item "Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % EV_PID_HASHSIZE))"
-.PD
-These watchers are stored in lists then need to be walked to find the
-correct watcher to remove. The lists are usually short (you don't usually
-have many watchers waiting for the same fd or signal).
-.IP "Finding the next timer in each loop iteration: O(1)" 4
-.IX Item "Finding the next timer in each loop iteration: O(1)"
-By virtue of using a binary or 4\-heap, the next timer is always found at a
-fixed position in the storage array.
-.IP "Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd)" 4
-.IX Item "Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd)"
-A change means an I/O watcher gets started or stopped, which requires
-libev to recalculate its status (and possibly tell the kernel, depending
-on backend and wether \f(CW\*(C`ev_io_set\*(C'\fR was used).
-.IP "Activating one watcher (putting it into the pending state): O(1)" 4
-.IX Item "Activating one watcher (putting it into the pending state): O(1)"
-.PD 0
-.IP "Priority handling: O(number_of_priorities)" 4
-.IX Item "Priority handling: O(number_of_priorities)"
-.PD
-Priorities are implemented by allocating some space for each
-priority. When doing priority-based operations, libev usually has to
-linearly search all the priorities, but starting/stopping and activating
-watchers becomes O(1) w.r.t. priority handling.
-.IP "Sending an ev_async: O(1)" 4
-.IX Item "Sending an ev_async: O(1)"
-.PD 0
-.IP "Processing ev_async_send: O(number_of_async_watchers)" 4
-.IX Item "Processing ev_async_send: O(number_of_async_watchers)"
-.IP "Processing signals: O(max_signal_number)" 4
-.IX Item "Processing signals: O(max_signal_number)"
-.PD
-Sending involves a syscall \fIiff\fR there were no other \f(CW\*(C`ev_async_send\*(C'\fR
-calls in the current loop iteration. Checking for async and signal events
-involves iterating over all running async watchers or all signal numbers.
-.SH "Win32 platform limitations and workarounds"
-.IX Header "Win32 platform limitations and workarounds"
-Win32 doesn't support any of the standards (e.g. \s-1POSIX\s0) that libev
-requires, and its I/O model is fundamentally incompatible with the \s-1POSIX\s0
-model. Libev still offers limited functionality on this platform in
-the form of the \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR backend, and only supports socket
-descriptors. This only applies when using Win32 natively, not when using
-e.g. cygwin.
-.PP
-Lifting these limitations would basically require the full
-re-implementation of the I/O system. If you are into these kinds of
-things, then note that glib does exactly that for you in a very portable
-way (note also that glib is the slowest event library known to man).
-.PP
-There is no supported compilation method available on windows except
-embedding it into other applications.
-.PP
-Due to the many, low, and arbitrary limits on the win32 platform and
-the abysmal performance of winsockets, using a large number of sockets
-is not recommended (and not reasonable). If your program needs to use
-more than a hundred or so sockets, then likely it needs to use a totally
-different implementation for windows, as libev offers the \s-1POSIX\s0 readyness
-notification model, which cannot be implemented efficiently on windows
-(microsoft monopoly games).
-.IP "The winsocket select function" 4
-.IX Item "The winsocket select function"
-The winsocket \f(CW\*(C`select\*(C'\fR function doesn't follow \s-1POSIX\s0 in that it requires
-socket \fIhandles\fR and not socket \fIfile descriptors\fR. This makes select
-very inefficient, and also requires a mapping from file descriptors
-to socket handles. See the discussion of the \f(CW\*(C`EV_SELECT_USE_FD_SET\*(C'\fR,
-\&\f(CW\*(C`EV_SELECT_IS_WINSOCKET\*(C'\fR and \f(CW\*(C`EV_FD_TO_WIN32_HANDLE\*(C'\fR preprocessor
-symbols for more info.
-.Sp
-The configuration for a \*(L"naked\*(R" win32 using the microsoft runtime
-libraries and raw winsocket select is:
-.Sp
-.Vb 2
-\& #define EV_USE_SELECT 1
-\& #define EV_SELECT_IS_WINSOCKET 1 /* forces EV_SELECT_USE_FD_SET, too */
-.Ve
-.Sp
-Note that winsockets handling of fd sets is O(n), so you can easily get a
-complexity in the O(nA\*^X) range when using win32.
-.IP "Limited number of file descriptors" 4
-.IX Item "Limited number of file descriptors"
-Windows has numerous arbitrary (and low) limits on things.
-.Sp
-Early versions of winsocket's select only supported waiting for a maximum
-of \f(CW64\fR handles (probably owning to the fact that all windows kernels
-can only wait for \f(CW64\fR things at the same time internally; microsoft
-recommends spawning a chain of threads and wait for 63 handles and the
-previous thread in each. Great).
-.Sp
-Newer versions support more handles, but you need to define \f(CW\*(C`FD_SETSIZE\*(C'\fR
-to some high number (e.g. \f(CW2048\fR) before compiling the winsocket select
-call (which might be in libev or elsewhere, for example, perl does its own
-select emulation on windows).
-.Sp
-Another limit is the number of file descriptors in the microsoft runtime
-libraries, which by default is \f(CW64\fR (there must be a hidden \fI64\fR fetish
-or something like this inside microsoft). You can increase this by calling
-\&\f(CW\*(C`_setmaxstdio\*(C'\fR, which can increase this limit to \f(CW2048\fR (another
-arbitrary limit), but is broken in many versions of the microsoft runtime
-libraries.
-.Sp
-This might get you to about \f(CW512\fR or \f(CW2048\fR sockets (depending on
-windows version and/or the phase of the moon). To get more, you need to
-wrap all I/O functions and provide your own fd management, but the cost of
-calling select (O(nA\*^X)) will likely make this unworkable.
-.SH "PORTABILITY REQUIREMENTS"
-.IX Header "PORTABILITY REQUIREMENTS"
-In addition to a working ISO-C implementation, libev relies on a few
-additional extensions:
-.ie n .IP """sig_atomic_t volatile"" must be thread-atomic as well" 4
-.el .IP "\f(CWsig_atomic_t volatile\fR must be thread-atomic as well" 4
-.IX Item "sig_atomic_t volatile must be thread-atomic as well"
-The type \f(CW\*(C`sig_atomic_t volatile\*(C'\fR (or whatever is defined as
-\&\f(CW\*(C`EV_ATOMIC_T\*(C'\fR) must be atomic w.r.t. accesses from different
-threads. This is not part of the specification for \f(CW\*(C`sig_atomic_t\*(C'\fR, but is
-believed to be sufficiently portable.
-.ie n .IP """sigprocmask"" must work in a threaded environment" 4
-.el .IP "\f(CWsigprocmask\fR must work in a threaded environment" 4
-.IX Item "sigprocmask must work in a threaded environment"
-Libev uses \f(CW\*(C`sigprocmask\*(C'\fR to temporarily block signals. This is not
-allowed in a threaded program (\f(CW\*(C`pthread_sigmask\*(C'\fR has to be used). Typical
-pthread implementations will either allow \f(CW\*(C`sigprocmask\*(C'\fR in the \*(L"main
-thread\*(R" or will block signals process-wide, both behaviours would
-be compatible with libev. Interaction between \f(CW\*(C`sigprocmask\*(C'\fR and
-\&\f(CW\*(C`pthread_sigmask\*(C'\fR could complicate things, however.
-.Sp
-The most portable way to handle signals is to block signals in all threads
-except the initial one, and run the default loop in the initial thread as
-well.
-.ie n .IP """long"" must be large enough for common memory allocation sizes" 4
-.el .IP "\f(CWlong\fR must be large enough for common memory allocation sizes" 4
-.IX Item "long must be large enough for common memory allocation sizes"
-To improve portability and simplify using libev, libev uses \f(CW\*(C`long\*(C'\fR
-internally instead of \f(CW\*(C`size_t\*(C'\fR when allocating its data structures. On
-non-POSIX systems (Microsoft...) this might be unexpectedly low, but
-is still at least 31 bits everywhere, which is enough for hundreds of
-millions of watchers.
-.ie n .IP """double"" must hold a time value in seconds with enough accuracy" 4
-.el .IP "\f(CWdouble\fR must hold a time value in seconds with enough accuracy" 4
-.IX Item "double must hold a time value in seconds with enough accuracy"
-The type \f(CW\*(C`double\*(C'\fR is used to represent timestamps. It is required to
-have at least 51 bits of mantissa (and 9 bits of exponent), which is good
-enough for at least into the year 4000. This requirement is fulfilled by
-implementations implementing \s-1IEEE\s0 754 (basically all existing ones).
-.PP
-If you know of other additional requirements drop me a note.
-.SH "AUTHOR"
-.IX Header "AUTHOR"
-Marc Lehmann <libev@schmorp.de>.
-.SH "POD ERRORS"
-.IX Header "POD ERRORS"
-Hey! \fBThe above document had some coding errors, which are explained below:\fR
-.IP "Around line 3052:" 4
-.IX Item "Around line 3052:"
-You forgot a '=back' before '=head2'
diff --git a/deps/uv/src/unix/eio/eio.c b/deps/uv/src/unix/eio/eio.c
deleted file mode 100644
index 248af9e2f..000000000
--- a/deps/uv/src/unix/eio/eio.c
+++ /dev/null
@@ -1,2593 +0,0 @@
-/*
- * libeio implementation
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libeio@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifdef EIO_CONFIG_H
-# include EIO_CONFIG_H
-#endif
-
-/* Undone by libuv for easy build scripts.
- * #ifndef _WIN32
- * # include "config.h"
- * #endif
- */
-
-#include "eio.h"
-#include "ecb.h"
-
-#ifdef EIO_STACKSIZE
-# define X_STACKSIZE EIO_STACKSIZE
-#endif
-#include "xthread.h"
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <assert.h>
-
-/* intptr_t comes from unistd.h, says POSIX/UNIX/tradition */
-/* intptr_t only comes from stdint.h, says idiot openbsd coder */
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-
-#ifndef ECANCELED
-# define ECANCELED EDOM
-#endif
-#ifndef ELOOP
-# define ELOOP EDOM
-#endif
-
-#if !defined(ENOTSOCK) && defined(WSAENOTSOCK)
-# define ENOTSOCK WSAENOTSOCK
-#endif
-
-static void eio_destroy (eio_req *req);
-
-#ifndef EIO_FINISH
-# define EIO_FINISH(req) ((req)->finish) && !EIO_CANCELLED (req) ? (req)->finish (req) : 0
-#endif
-
-#ifndef EIO_DESTROY
-# define EIO_DESTROY(req) do { if ((req)->destroy) (req)->destroy (req); } while (0)
-#endif
-
-#ifndef EIO_FEED
-# define EIO_FEED(req) do { if ((req)->feed ) (req)->feed (req); } while (0)
-#endif
-
-#ifndef EIO_FD_TO_WIN32_HANDLE
-# define EIO_FD_TO_WIN32_HANDLE(fd) _get_osfhandle (fd)
-#endif
-#ifndef EIO_WIN32_HANDLE_TO_FD
-# define EIO_WIN32_HANDLE_TO_FD(handle) _open_osfhandle (handle, 0)
-#endif
-
-#define EIO_ERRNO(errval,retval) ((errno = errval), retval)
-
-#define EIO_ENOSYS() EIO_ERRNO (ENOSYS, -1)
-
-#ifdef __sun
-# define futimes(fd, times) futimesat (fd, NULL, times)
-#endif
-
-#ifdef _WIN32
-
- #include <direct.h>
-
- #undef PAGESIZE
- #define PAGESIZE 4096 /* GetSystemInfo? */
-
- /* TODO: look at how perl does stat (non-sloppy), unlink (ro-files), utime, link */
-
- #ifdef EIO_STRUCT_STATI64
- /* look at perl's non-sloppy stat */
- #define stat(path,buf) _stati64 (path,buf)
- #define fstat(fd,buf) _fstati64 (fd,buf)
- #endif
- #define lstat(path,buf) stat (path,buf)
- #define fsync(fd) (FlushFileBuffers ((HANDLE)EIO_FD_TO_WIN32_HANDLE (fd)) ? 0 : EIO_ERRNO (EBADF, -1))
- #define mkdir(path,mode) _mkdir (path)
- #define link(old,neu) (CreateHardLink (neu, old, 0) ? 0 : EIO_ERRNO (ENOENT, -1))
-
- #define chmod(path,mode) _chmod (path, mode)
- #define dup(fd) _dup (fd)
- #define dup2(fd1,fd2) _dup2 (fd1, fd2)
-
- #define fchmod(fd,mode) EIO_ENOSYS ()
- #define chown(path,uid,gid) EIO_ENOSYS ()
- #define fchown(fd,uid,gid) EIO_ENOSYS ()
- #define truncate(path,offs) EIO_ENOSYS () /* far-miss: SetEndOfFile */
- #define ftruncate(fd,offs) EIO_ENOSYS () /* near-miss: SetEndOfFile */
- #define mknod(path,mode,dev) EIO_ENOSYS ()
- #define sync() EIO_ENOSYS ()
- #define readlink(path,buf,s) EIO_ENOSYS ()
- #define statvfs(path,buf) EIO_ENOSYS ()
- #define fstatvfs(fd,buf) EIO_ENOSYS ()
-
- #define getcwd(buf,s) _getcwd(buf, s)
- #define rmdir(path) _rmdir(path)
-
- /* rename() uses MoveFile, which fails to overwrite */
- #define rename(old,neu) eio__rename (old, neu)
-
- static int
- eio__rename (const char *old, const char *neu)
- {
- if (MoveFileEx (old, neu, MOVEFILE_REPLACE_EXISTING))
- return 0;
-
- /* should steal _dosmaperr */
- switch (GetLastError ())
- {
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- case ERROR_INVALID_DRIVE:
- case ERROR_NO_MORE_FILES:
- case ERROR_BAD_NETPATH:
- case ERROR_BAD_NET_NAME:
- case ERROR_BAD_PATHNAME:
- case ERROR_FILENAME_EXCED_RANGE:
- errno = ENOENT;
- break;
-
- default:
- errno = EACCES;
- break;
- }
-
- return -1;
- }
-
- /* we could even stat and see if it exists */
- static int
- symlink (const char *old, const char *neu)
- {
- #if WINVER >= 0x0600
- if (CreateSymbolicLink (neu, old, 1))
- return 0;
-
- if (CreateSymbolicLink (neu, old, 0))
- return 0;
- #endif
-
- return EIO_ERRNO (ENOENT, -1);
- }
-
- /* POSIX API only */
- #ifndef CreateHardLink
- # define CreateHardLink(neu,old,flags) 0
- #endif
- #define CreateSymbolicLink(neu,old,flags) 0
-
- struct statvfs
- {
- int dummy;
- };
-
- #define DT_DIR EIO_DT_DIR
- #define DT_REG EIO_DT_REG
- #define D_NAME(entp) entp.cFileName
- #define D_TYPE(entp) (entp.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? DT_DIR : DT_REG)
-
-#include <sys/utime.h>
-#define utime(path, times) _utime(path, times)
-#define utimbuf _utimbuf
-
-#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
- #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
-#else
- #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
-#endif
-
-struct timezone
-{
- int tz_minuteswest; /* minutes W of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-
-static int gettimeofday(struct timeval *tv, struct timezone *tz)
-{
- FILETIME ft;
- unsigned __int64 tmpres = 0;
- static int tzflag;
-
- if (NULL != tv)
- {
- GetSystemTimeAsFileTime(&ft);
-
- tmpres |= ft.dwHighDateTime;
- tmpres <<= 32;
- tmpres |= ft.dwLowDateTime;
-
- /*converting file time to unix epoch*/
- tmpres -= DELTA_EPOCH_IN_MICROSECS;
- tmpres /= 10; /*convert into microseconds*/
- tv->tv_sec = (long)(tmpres / 1000000UL);
- tv->tv_usec = (long)(tmpres % 1000000UL);
- }
-
- if (NULL != tz)
- {
- if (!tzflag)
- {
- _tzset();
- tzflag++;
- }
- tz->tz_minuteswest = _timezone / 60;
- tz->tz_dsttime = _daylight;
- }
-
- return 0;
-}
-
-#else
-
- #include <sys/time.h>
- #include <sys/select.h>
- #include <sys/statvfs.h>
- #include <unistd.h>
- #include <signal.h>
- #include <dirent.h>
-
- #if _POSIX_MEMLOCK || _POSIX_MEMLOCK_RANGE || _POSIX_MAPPED_FILES
- #include <sys/mman.h>
- #endif
-
- #define D_NAME(entp) entp->d_name
-
- /* POSIX_SOURCE is useless on bsd's, and XOPEN_SOURCE is unreliable there, too */
- #if __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
- #define _DIRENT_HAVE_D_TYPE /* sigh */
- #define D_INO(de) (de)->d_fileno
- #define D_NAMLEN(de) (de)->d_namlen
- #elif __linux || defined d_ino || _XOPEN_SOURCE >= 600
- #define D_INO(de) (de)->d_ino
- #endif
-
- #ifdef _D_EXACT_NAMLEN
- #undef D_NAMLEN
- #define D_NAMLEN(de) _D_EXACT_NAMLEN (de)
- #endif
-
- #ifdef _DIRENT_HAVE_D_TYPE
- #define D_TYPE(de) (de)->d_type
- #endif
-
- #ifndef EIO_STRUCT_DIRENT
- #define EIO_STRUCT_DIRENT struct dirent
- #endif
-
-#endif
-
-#if HAVE_UTIMES
-# include <utime.h>
-#endif
-
-#if HAVE_SYS_SYSCALL_H
-# include <sys/syscall.h>
-#endif
-
-#if HAVE_SYS_PRCTL_H
-# include <sys/prctl.h>
-#endif
-
-#if HAVE_SENDFILE
-# if __linux
-# include <sys/sendfile.h>
-# elif __FreeBSD__ || __DragonFly__ || defined __APPLE__
-# include <sys/socket.h>
-# include <sys/uio.h>
-# elif __hpux
-# include <sys/socket.h>
-# elif __solaris
-# include <sys/sendfile.h>
-# else
-# error sendfile support requested but not available
-# endif
-#endif
-
-#ifndef D_TYPE
-# define D_TYPE(de) 0
-#endif
-#ifndef D_INO
-# define D_INO(de) 0
-#endif
-#ifndef D_NAMLEN
-# define D_NAMLEN(entp) strlen (D_NAME (entp))
-#endif
-
-/* used for struct dirent, AIX doesn't provide it */
-#ifndef NAME_MAX
-# define NAME_MAX 4096
-#endif
-
-/* used for readlink etc. */
-#ifndef PATH_MAX
-# define PATH_MAX 4096
-#endif
-
-/* buffer size for various temporary buffers */
-#define EIO_BUFSIZE 65536
-
-#define dBUF \
- char *eio_buf = malloc (EIO_BUFSIZE); \
- errno = ENOMEM; \
- if (!eio_buf) \
- return -1
-
-#define FUBd \
- free (eio_buf)
-
-#define EIO_TICKS ((1000000 + 1023) >> 10)
-
-struct etp_worker;
-
-#define ETP_DESTROY(req) eio_destroy (req)
-static int eio_finish (eio_req *req);
-#define ETP_FINISH(req) eio_finish (req)
-static void eio_execute (struct etp_worker *self, eio_req *req);
-#define ETP_EXECUTE(wrk,req) eio_execute (wrk,req)
-
-/*****************************************************************************/
-
-/* calculate time difference in ~1/EIO_TICKS of a second */
-ecb_inline int
-tvdiff (struct timeval *tv1, struct timeval *tv2)
-{
- return (tv2->tv_sec - tv1->tv_sec ) * EIO_TICKS
- + ((tv2->tv_usec - tv1->tv_usec) >> 10);
-}
-
-static unsigned int started, idle, wanted = 4;
-
-static void (*want_poll_cb) (eio_channel *);
-static void (*done_poll_cb) (eio_channel *);
-
-static unsigned int max_poll_time; /* reslock */
-static unsigned int max_poll_reqs; /* reslock */
-
-static unsigned int nreqs; /* reqlock */
-static unsigned int nready; /* reqlock */
-static unsigned int npending; /* reqlock */
-static unsigned int max_idle = 4; /* maximum number of threads that can idle indefinitely */
-static unsigned int idle_timeout = 10; /* number of seconds after which an idle threads exit */
-
-static xmutex_t wrklock;
-static xmutex_t reslock;
-static xmutex_t reqlock;
-static xcond_t reqwait;
-
-/* Fix for test-fs-sir-writes-alot */
-/* Apple's OSX can't safely write() concurrently from 2 threads */
-/* for more info see the thread "fs.write Data Munging" in the nodejs google group */
-/* http://groups.google.com/group/nodejs/browse_thread/thread/c11f8b683f37cef/b18ad9e0a15314c5 */
-/* And the thread "write()s and pwrite()s from multiple threads in OSX" in libev@lists.schmorp.de */
-/* http://lists.schmorp.de/pipermail/libev/2010q4/001185.html */
-#if defined (__APPLE__)
-static xmutex_t apple_bug_writelock = X_MUTEX_INIT;
-#endif
-
-#if !HAVE_PREADWRITE
-/*
- * make our pread/pwrite emulation safe against themselves, but not against
- * normal read/write by using a mutex. slows down execution a lot,
- * but that's your problem, not mine.
- */
-static xmutex_t preadwritelock;
-#endif
-
-typedef struct etp_worker
-{
- /* locked by wrklock */
- struct etp_worker *prev, *next;
-
- xthread_t tid;
-
- /* locked by reslock, reqlock or wrklock */
- ETP_REQ *req; /* currently processed request */
-
-#ifdef ETP_WORKER_COMMON
- ETP_WORKER_COMMON
-#endif
-} etp_worker;
-
-static etp_worker wrk_first; /* NOT etp */
-
-#define ETP_WORKER_LOCK(wrk) X_LOCK (wrklock)
-#define ETP_WORKER_UNLOCK(wrk) X_UNLOCK (wrklock)
-
-/* worker threads management */
-
-static void ecb_cold
-etp_worker_clear (etp_worker *wrk)
-{
-}
-
-static void ecb_cold
-etp_worker_free (etp_worker *wrk)
-{
- wrk->next->prev = wrk->prev;
- wrk->prev->next = wrk->next;
-
- free (wrk);
-}
-
-static unsigned int
-etp_nreqs (void)
-{
- int retval;
- if (WORDACCESS_UNSAFE) X_LOCK (reqlock);
- retval = nreqs;
- if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
- return retval;
-}
-
-static unsigned int
-etp_nready (void)
-{
- unsigned int retval;
-
- if (WORDACCESS_UNSAFE) X_LOCK (reqlock);
- retval = nready;
- if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-
- return retval;
-}
-
-static unsigned int
-etp_npending (void)
-{
- unsigned int retval;
-
- if (WORDACCESS_UNSAFE) X_LOCK (reqlock);
- retval = npending;
- if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-
- return retval;
-}
-
-static unsigned int
-etp_nthreads (void)
-{
- unsigned int retval;
-
- if (WORDACCESS_UNSAFE) X_LOCK (reqlock);
- retval = started;
- if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-
- return retval;
-}
-
-static etp_reqq req_queue;
-static eio_channel default_channel;
-
-static void ecb_noinline ecb_cold
-reqq_init (etp_reqq *q)
-{
- int pri;
-
- for (pri = 0; pri < ETP_NUM_PRI; ++pri)
- q->qs[pri] = q->qe[pri] = 0;
-
- q->size = 0;
-}
-
-static int ecb_noinline
-reqq_push (etp_reqq *q, ETP_REQ *req)
-{
- int pri = req->pri;
- req->next = 0;
-
- if (q->qe[pri])
- {
- q->qe[pri]->next = req;
- q->qe[pri] = req;
- }
- else
- q->qe[pri] = q->qs[pri] = req;
-
- return q->size++;
-}
-
-static ETP_REQ * ecb_noinline
-reqq_shift (etp_reqq *q)
-{
- int pri;
-
- if (!q->size)
- return 0;
-
- --q->size;
-
- for (pri = ETP_NUM_PRI; pri--; )
- {
- eio_req *req = q->qs[pri];
-
- if (req)
- {
- if (!(q->qs[pri] = (eio_req *)req->next))
- q->qe[pri] = 0;
-
- return req;
- }
- }
-
- abort ();
-}
-
-static int ecb_cold
-etp_init (void (*want_poll)(eio_channel *), void (*done_poll)(eio_channel *))
-{
- X_MUTEX_CREATE (wrklock);
- X_MUTEX_CREATE (reslock);
- X_MUTEX_CREATE (reqlock);
- X_COND_CREATE (reqwait);
-
- reqq_init (&req_queue);
- eio_channel_init (&default_channel, 0);
-
- wrk_first.next =
- wrk_first.prev = &wrk_first;
-
- started = 0;
- idle = 0;
- nreqs = 0;
- nready = 0;
- npending = 0;
-
- want_poll_cb = want_poll;
- done_poll_cb = done_poll;
-
- return 0;
-}
-
-X_THREAD_PROC (etp_proc);
-
-static void ecb_cold
-etp_start_thread (void)
-{
- etp_worker *wrk = calloc (1, sizeof (etp_worker));
-
- /*TODO*/
- assert (("unable to allocate worker thread data", wrk));
-
- X_LOCK (wrklock);
-
- if (thread_create (&wrk->tid, etp_proc, (void *)wrk))
- {
- wrk->prev = &wrk_first;
- wrk->next = wrk_first.next;
- wrk_first.next->prev = wrk;
- wrk_first.next = wrk;
- ++started;
- }
- else
- free (wrk);
-
- X_UNLOCK (wrklock);
-}
-
-static void
-etp_maybe_start_thread (void)
-{
- if (ecb_expect_true (etp_nthreads () >= wanted))
- return;
-
- /* todo: maybe use idle here, but might be less exact */
- if (ecb_expect_true (0 <= (int)etp_nthreads () + (int)etp_npending () - (int)etp_nreqs ()))
- return;
-
- etp_start_thread ();
-}
-
-static void ecb_cold
-etp_end_thread (void)
-{
- eio_req *req = calloc (1, sizeof (eio_req));
-
- req->type = -1;
- req->pri = ETP_PRI_MAX - ETP_PRI_MIN;
-
- X_LOCK (reqlock);
- reqq_push (&req_queue, req);
- X_COND_SIGNAL (reqwait);
- X_UNLOCK (reqlock);
-
- X_LOCK (wrklock);
- --started;
- X_UNLOCK (wrklock);
-}
-
-void
-eio_channel_init(eio_channel *channel, void *data) {
- reqq_init(&channel->res_queue);
- channel->data = data;
-}
-
-static int
-etp_poll (eio_channel *channel)
-{
- unsigned int maxreqs;
- unsigned int maxtime;
- struct timeval tv_start, tv_now;
- if(!channel) channel = &default_channel;
-
- X_LOCK (reslock);
- maxreqs = max_poll_reqs;
- maxtime = max_poll_time;
- X_UNLOCK (reslock);
-
- if (maxtime)
- gettimeofday (&tv_start, 0);
-
- for (;;)
- {
- ETP_REQ *req;
-
- etp_maybe_start_thread ();
-
- X_LOCK (reslock);
- req = reqq_shift (&channel->res_queue);
-
- if (req)
- {
- --npending;
-
- if (!channel->res_queue.size && done_poll_cb)
- done_poll_cb (channel);
- }
-
- X_UNLOCK (reslock);
-
- if (!req)
- return 0;
-
- X_LOCK (reqlock);
- --nreqs;
- X_UNLOCK (reqlock);
-
- if (ecb_expect_false (req->type == EIO_GROUP && req->size))
- {
- req->int1 = 1; /* mark request as delayed */
- continue;
- }
- else
- {
- int res = ETP_FINISH (req);
- if (ecb_expect_false (res))
- return res;
- }
-
- if (ecb_expect_false (maxreqs && !--maxreqs))
- break;
-
- if (maxtime)
- {
- gettimeofday (&tv_now, 0);
-
- if (tvdiff (&tv_start, &tv_now) >= maxtime)
- break;
- }
- }
-
- errno = EAGAIN;
- return -1;
-}
-
-static void
-etp_cancel (ETP_REQ *req)
-{
- req->cancelled = 1;
-
- eio_grp_cancel (req);
-}
-
-static void
-etp_submit (ETP_REQ *req)
-{
- req->pri -= ETP_PRI_MIN;
-
- if (ecb_expect_false (req->pri < ETP_PRI_MIN - ETP_PRI_MIN)) req->pri = ETP_PRI_MIN - ETP_PRI_MIN;
- if (ecb_expect_false (req->pri > ETP_PRI_MAX - ETP_PRI_MIN)) req->pri = ETP_PRI_MAX - ETP_PRI_MIN;
-
- if (ecb_expect_false (req->type == EIO_GROUP))
- {
- /* I hope this is worth it :/ */
- X_LOCK (reqlock);
- ++nreqs;
- X_UNLOCK (reqlock);
-
- X_LOCK (reslock);
-
- ++npending;
-
- if (!reqq_push (&req->channel->res_queue, req) && want_poll_cb)
- want_poll_cb (req->channel);
-
- X_UNLOCK (reslock);
- }
- else
- {
- X_LOCK (reqlock);
- ++nreqs;
- ++nready;
- reqq_push (&req_queue, req);
- X_COND_SIGNAL (reqwait);
- X_UNLOCK (reqlock);
-
- etp_maybe_start_thread ();
- }
-}
-
-static void ecb_cold
-etp_set_max_poll_time (double nseconds)
-{
- if (WORDACCESS_UNSAFE) X_LOCK (reslock);
- max_poll_time = nseconds * EIO_TICKS;
- if (WORDACCESS_UNSAFE) X_UNLOCK (reslock);
-}
-
-static void ecb_cold
-etp_set_max_poll_reqs (unsigned int maxreqs)
-{
- if (WORDACCESS_UNSAFE) X_LOCK (reslock);
- max_poll_reqs = maxreqs;
- if (WORDACCESS_UNSAFE) X_UNLOCK (reslock);
-}
-
-static void ecb_cold
-etp_set_max_idle (unsigned int nthreads)
-{
- if (WORDACCESS_UNSAFE) X_LOCK (reqlock);
- max_idle = nthreads;
- if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-}
-
-static void ecb_cold
-etp_set_idle_timeout (unsigned int seconds)
-{
- if (WORDACCESS_UNSAFE) X_LOCK (reqlock);
- idle_timeout = seconds;
- if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-}
-
-static void ecb_cold
-etp_set_min_parallel (unsigned int nthreads)
-{
- if (wanted < nthreads)
- wanted = nthreads;
-}
-
-static void ecb_cold
-etp_set_max_parallel (unsigned int nthreads)
-{
- if (wanted > nthreads)
- wanted = nthreads;
-
- while (started > wanted)
- etp_end_thread ();
-}
-
-/*****************************************************************************/
-
-static void
-grp_try_feed (eio_req *grp)
-{
- while (grp->size < grp->int2 && !EIO_CANCELLED (grp))
- {
- grp->flags &= ~EIO_FLAG_GROUPADD;
-
- EIO_FEED (grp);
-
- /* stop if no progress has been made */
- if (!(grp->flags & EIO_FLAG_GROUPADD))
- {
- grp->feed = 0;
- break;
- }
- }
-}
-
-static int
-grp_dec (eio_req *grp)
-{
- --grp->size;
-
- /* call feeder, if applicable */
- grp_try_feed (grp);
-
- /* finish, if done */
- if (!grp->size && grp->int1)
- return eio_finish (grp);
- else
- return 0;
-}
-
-static void
-eio_destroy (eio_req *req)
-{
- if ((req)->flags & EIO_FLAG_PTR1_FREE) free (req->ptr1);
- if ((req)->flags & EIO_FLAG_PTR2_FREE) free (req->ptr2);
-
- EIO_DESTROY (req);
-}
-
-static int
-eio_finish (eio_req *req)
-{
- int res = EIO_FINISH (req);
-
- if (req->grp)
- {
- int res2;
- eio_req *grp = req->grp;
-
- /* unlink request */
- if (req->grp_next) req->grp_next->grp_prev = req->grp_prev;
- if (req->grp_prev) req->grp_prev->grp_next = req->grp_next;
-
- if (grp->grp_first == req)
- grp->grp_first = req->grp_next;
-
- res2 = grp_dec (grp);
-
- if (!res)
- res = res2;
- }
-
- eio_destroy (req);
-
- return res;
-}
-
-void
-eio_grp_cancel (eio_req *grp)
-{
- for (grp = grp->grp_first; grp; grp = grp->grp_next)
- eio_cancel (grp);
-}
-
-void
-eio_cancel (eio_req *req)
-{
- etp_cancel (req);
-}
-
-void
-eio_submit (eio_req *req)
-{
- etp_submit (req);
-}
-
-unsigned int
-eio_nreqs (void)
-{
- return etp_nreqs ();
-}
-
-unsigned int
-eio_nready (void)
-{
- return etp_nready ();
-}
-
-unsigned int
-eio_npending (void)
-{
- return etp_npending ();
-}
-
-unsigned int ecb_cold
-eio_nthreads (void)
-{
- return etp_nthreads ();
-}
-
-void ecb_cold
-eio_set_max_poll_time (double nseconds)
-{
- etp_set_max_poll_time (nseconds);
-}
-
-void ecb_cold
-eio_set_max_poll_reqs (unsigned int maxreqs)
-{
- etp_set_max_poll_reqs (maxreqs);
-}
-
-void ecb_cold
-eio_set_max_idle (unsigned int nthreads)
-{
- etp_set_max_idle (nthreads);
-}
-
-void ecb_cold
-eio_set_idle_timeout (unsigned int seconds)
-{
- etp_set_idle_timeout (seconds);
-}
-
-void ecb_cold
-eio_set_min_parallel (unsigned int nthreads)
-{
- etp_set_min_parallel (nthreads);
-}
-
-void ecb_cold
-eio_set_max_parallel (unsigned int nthreads)
-{
- etp_set_max_parallel (nthreads);
-}
-
-int eio_poll (eio_channel *channel)
-{
- return etp_poll (channel);
-}
-
-/*****************************************************************************/
-/* work around various missing functions */
-
-#if !HAVE_PREADWRITE
-# undef pread
-# undef pwrite
-# define pread eio__pread
-# define pwrite eio__pwrite
-
-eio_ssize_t
-eio__pread (int fd, void *buf, size_t count, off_t offset)
-{
- eio_ssize_t res;
- off_t ooffset;
-
- X_LOCK (preadwritelock);
- ooffset = lseek (fd, 0, SEEK_CUR);
- lseek (fd, offset, SEEK_SET);
- res = read (fd, buf, count);
- lseek (fd, ooffset, SEEK_SET);
- X_UNLOCK (preadwritelock);
-
- return res;
-}
-
-eio_ssize_t
-eio__pwrite (int fd, void *buf, size_t count, off_t offset)
-{
- eio_ssize_t res;
- off_t ooffset;
-
- X_LOCK (preadwritelock);
- ooffset = lseek (fd, 0, SEEK_CUR);
- lseek (fd, offset, SEEK_SET);
- res = write (fd, buf, count);
- lseek (fd, ooffset, SEEK_SET);
- X_UNLOCK (preadwritelock);
-
- return res;
-}
-#endif
-
-#ifndef HAVE_UTIMES
-
-# undef utimes
-# define utimes(path,times) eio__utimes (path, times)
-
-static int
-eio__utimes (const char *filename, const struct timeval times[2])
-{
- if (times)
- {
- struct utimbuf buf;
-
- buf.actime = times[0].tv_sec;
- buf.modtime = times[1].tv_sec;
-
- return utime (filename, &buf);
- }
- else
- return utime (filename, 0);
-}
-
-#endif
-
-#ifndef HAVE_FUTIMES
-
-# undef futimes
-# define futimes(fd,times) eio__futimes (fd, times)
-
-static int
-eio__futimes (int fd, const struct timeval tv[2])
-{
-#if defined(__linux) && defined(__NR_utimensat)
- struct timespec ts[2];
- ts[0].tv_sec = tv[0].tv_sec, ts[0].tv_nsec = tv[0].tv_usec * 1000;
- ts[1].tv_sec = tv[1].tv_sec, ts[1].tv_nsec = tv[1].tv_usec * 1000;
- return syscall(__NR_utimensat, fd, NULL, ts, 0);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-#endif
-
-#if !HAVE_FDATASYNC
-# undef fdatasync
-# define fdatasync(fd) fsync (fd)
-#endif
-
-static int
-eio__syncfs (int fd)
-{
- int res;
-
-#if HAVE_SYS_SYNCFS
- res = (int)syscall (__NR_syncfs, (int)(fd));
-#else
- res = -1;
- errno = ENOSYS;
-#endif
-
- if (res < 0 && errno == ENOSYS && fd >= 0)
- sync ();
-
- return res;
-}
-
-/* sync_file_range always needs emulation */
-static int
-eio__sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags)
-{
-#if HAVE_SYNC_FILE_RANGE
- int res;
-
- if (EIO_SYNC_FILE_RANGE_WAIT_BEFORE != SYNC_FILE_RANGE_WAIT_BEFORE
- || EIO_SYNC_FILE_RANGE_WRITE != SYNC_FILE_RANGE_WRITE
- || EIO_SYNC_FILE_RANGE_WAIT_AFTER != SYNC_FILE_RANGE_WAIT_AFTER)
- {
- flags = 0
- | (flags & EIO_SYNC_FILE_RANGE_WAIT_BEFORE ? SYNC_FILE_RANGE_WAIT_BEFORE : 0)
- | (flags & EIO_SYNC_FILE_RANGE_WRITE ? SYNC_FILE_RANGE_WRITE : 0)
- | (flags & EIO_SYNC_FILE_RANGE_WAIT_AFTER ? SYNC_FILE_RANGE_WAIT_AFTER : 0);
- }
-
- res = sync_file_range (fd, offset, nbytes, flags);
-
- if (!res || errno != ENOSYS)
- return res;
-#endif
-
- /* even though we could play tricks with the flags, it's better to always
- * call fdatasync, as that matches the expectation of its users best */
- return fdatasync (fd);
-}
-
-static int
-eio__fallocate (int fd, int mode, off_t offset, size_t len)
-{
-#if HAVE_FALLOCATE
- return fallocate (fd, mode, offset, len);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-#if !HAVE_READAHEAD
-# undef readahead
-# define readahead(fd,offset,count) eio__readahead (fd, offset, count, self)
-
-static eio_ssize_t
-eio__readahead (int fd, off_t offset, size_t count, etp_worker *self)
-{
- size_t todo = count;
- dBUF;
-
- while (todo > 0)
- {
- size_t len = todo < EIO_BUFSIZE ? todo : EIO_BUFSIZE;
-
- pread (fd, eio_buf, len, offset);
- offset += len;
- todo -= len;
- }
-
- FUBd;
-
- errno = 0;
- return count;
-}
-
-#endif
-
-/* sendfile always needs emulation */
-static eio_ssize_t
-eio__sendfile (int ofd, int ifd, off_t offset, size_t count)
-{
- eio_ssize_t written = 0;
- eio_ssize_t res;
-
- if (!count)
- return 0;
-
- for (;;)
- {
-#ifdef __APPLE__
-# undef HAVE_SENDFILE /* broken, as everything on os x */
-#endif
-#if HAVE_SENDFILE
-# if __linux
- off_t soffset = offset;
- res = sendfile (ofd, ifd, &soffset, count);
-
-# elif __FreeBSD__
- /*
- * Of course, the freebsd sendfile is a dire hack with no thoughts
- * wasted on making it similar to other I/O functions.
- */
- off_t sbytes;
- res = sendfile (ifd, ofd, offset, count, 0, &sbytes, 0);
-
- #if 0 /* according to the manpage, this is correct, but broken behaviour */
- /* freebsd' sendfile will return 0 on success */
- /* freebsd 8 documents it as only setting *sbytes on EINTR and EAGAIN, but */
- /* not on e.g. EIO or EPIPE - sounds broken */
- if ((res < 0 && (errno == EAGAIN || errno == EINTR) && sbytes) || res == 0)
- res = sbytes;
- #endif
-
- /* according to source inspection, this is correct, and useful behaviour */
- if (sbytes)
- res = sbytes;
-
-# elif defined (__APPLE__)
- off_t sbytes = count;
- res = sendfile (ifd, ofd, offset, &sbytes, 0, 0);
-
- /* according to the manpage, sbytes is always valid */
- if (sbytes)
- res = sbytes;
-
-# elif __hpux
- res = sendfile (ofd, ifd, offset, count, 0, 0);
-
-# elif __solaris
- struct sendfilevec vec;
- size_t sbytes;
-
- vec.sfv_fd = ifd;
- vec.sfv_flag = 0;
- vec.sfv_off = offset;
- vec.sfv_len = count;
-
- res = sendfilev (ofd, &vec, 1, &sbytes);
-
- if (res < 0 && sbytes)
- res = sbytes;
-
-# endif
-
-#elif defined (_WIN32) && 0
- /* does not work, just for documentation of what would need to be done */
- /* actually, cannot be done like this, as TransmitFile changes the file offset, */
- /* libeio guarantees that the file offset does not change, and windows */
- /* has no way to get an independent handle to the same file description */
- HANDLE h = TO_SOCKET (ifd);
- SetFilePointer (h, offset, 0, FILE_BEGIN);
- res = TransmitFile (TO_SOCKET (ofd), h, count, 0, 0, 0, 0);
-
-#else
- res = -1;
- errno = ENOSYS;
-#endif
-
- /* we assume sendfile can copy at least 128mb in one go */
- if (res <= 128 * 1024 * 1024)
- {
- if (res > 0)
- written += res;
-
- if (written)
- return written;
-
- break;
- }
- else
- {
- /* if we requested more, then probably the kernel was lazy */
- written += res;
- offset += res;
- count -= res;
-
- if (!count)
- return written;
- }
- }
-
- if (res < 0
- && (errno == ENOSYS || errno == EINVAL || errno == ENOTSOCK
- /* BSDs */
-#ifdef ENOTSUP /* sigh, if the steenking pile called openbsd would only try to at least compile posix code... */
- || errno == ENOTSUP
-#endif
-#ifdef EOPNOTSUPP /* windows */
- || errno == EOPNOTSUPP /* BSDs */
-#endif
-#if __solaris
- || errno == EAFNOSUPPORT || errno == EPROTOTYPE
-#endif
- )
- )
- {
- /* emulate sendfile. this is a major pain in the ass */
- dBUF;
-
- res = 0;
-
- while (count)
- {
- eio_ssize_t cnt;
-
- cnt = pread (ifd, eio_buf, count > EIO_BUFSIZE ? EIO_BUFSIZE : count, offset);
-
- if (cnt <= 0)
- {
- if (cnt && !res) res = -1;
- break;
- }
-
- cnt = write (ofd, eio_buf, cnt);
-
- if (cnt <= 0)
- {
- if (cnt && !res) res = -1;
- break;
- }
-
- offset += cnt;
- res += cnt;
- count -= cnt;
- }
-
- FUBd;
- }
-
- return res;
-}
-
-#ifdef PAGESIZE
-# define eio_pagesize() PAGESIZE
-#else
-static intptr_t
-eio_pagesize (void)
-{
- static intptr_t page;
-
- if (!page)
- page = sysconf (_SC_PAGESIZE);
-
- return page;
-}
-#endif
-
-static void
-eio_page_align (void **addr, size_t *length)
-{
- intptr_t mask = eio_pagesize () - 1;
-
- /* round down addr */
- intptr_t adj = mask & (intptr_t)*addr;
-
- *addr = (void *)((intptr_t)*addr - adj);
- *length += adj;
-
- /* round up length */
- *length = (*length + mask) & ~mask;
-}
-
-#if !_POSIX_MEMLOCK
-# define eio__mlockall(a) EIO_ENOSYS ()
-#else
-
-static int
-eio__mlockall (int flags)
-{
- #if __GLIBC__ == 2 && __GLIBC_MINOR__ <= 7
- extern int mallopt (int, int);
- mallopt (-6, 238); /* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=473812 */
- #endif
-
- if (EIO_MCL_CURRENT != MCL_CURRENT
- || EIO_MCL_FUTURE != MCL_FUTURE)
- {
- flags = 0
- | (flags & EIO_MCL_CURRENT ? MCL_CURRENT : 0)
- | (flags & EIO_MCL_FUTURE ? MCL_FUTURE : 0);
- }
-
- return mlockall (flags);
-}
-#endif
-
-#if !_POSIX_MEMLOCK_RANGE
-# define eio__mlock(a,b) EIO_ENOSYS ()
-#else
-
-static int
-eio__mlock (void *addr, size_t length)
-{
- eio_page_align (&addr, &length);
-
- return mlock (addr, length);
-}
-
-#endif
-
-#if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO)
-# define eio__msync(a,b,c) EIO_ENOSYS ()
-#else
-
-static int
-eio__msync (void *mem, size_t len, int flags)
-{
- eio_page_align (&mem, &len);
-
- if (EIO_MS_ASYNC != MS_SYNC
- || EIO_MS_INVALIDATE != MS_INVALIDATE
- || EIO_MS_SYNC != MS_SYNC)
- {
- flags = 0
- | (flags & EIO_MS_ASYNC ? MS_ASYNC : 0)
- | (flags & EIO_MS_INVALIDATE ? MS_INVALIDATE : 0)
- | (flags & EIO_MS_SYNC ? MS_SYNC : 0);
- }
-
- return msync (mem, len, flags);
-}
-
-#endif
-
-static int
-eio__mtouch (eio_req *req)
-{
- void *mem = req->ptr2;
- size_t len = req->size;
- int flags = req->int1;
-
- eio_page_align (&mem, &len);
-
- {
- intptr_t addr = (intptr_t)mem;
- intptr_t end = addr + len;
- intptr_t page = eio_pagesize ();
-
- if (addr < end)
- if (flags & EIO_MT_MODIFY) /* modify */
- do { *((volatile sig_atomic_t *)addr) |= 0; } while ((addr += page) < len && !EIO_CANCELLED (req));
- else
- do { *((volatile sig_atomic_t *)addr) ; } while ((addr += page) < len && !EIO_CANCELLED (req));
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-/* requests implemented outside eio_execute, because they are so large */
-
-static void
-eio__realpath (eio_req *req, etp_worker *self)
-{
- char *rel = req->ptr1;
- char *res;
- char *tmp1, *tmp2;
-#if SYMLOOP_MAX > 32
- int symlinks = SYMLOOP_MAX;
-#else
- int symlinks = 32;
-#endif
-
- req->result = -1;
-
- errno = EINVAL;
- if (!rel)
- return;
-
- errno = ENOENT;
- if (!*rel)
- return;
-
- if (!req->ptr2)
- {
- X_LOCK (wrklock);
- req->flags |= EIO_FLAG_PTR2_FREE;
- X_UNLOCK (wrklock);
- req->ptr2 = malloc (PATH_MAX * 3);
-
- errno = ENOMEM;
- if (!req->ptr2)
- return;
- }
-
- res = req->ptr2;
- tmp1 = res + PATH_MAX;
- tmp2 = tmp1 + PATH_MAX;
-
-#if 0 /* disabled, the musl way to do things is just too racy */
-#if __linux && defined(O_NONBLOCK) && defined(O_NOATIME)
- /* on linux we may be able to ask the kernel */
- {
- int fd = open (rel, O_RDONLY | O_NONBLOCK | O_NOCTTY | O_NOATIME);
-
- if (fd >= 0)
- {
- sprintf (tmp1, "/proc/self/fd/%d", fd);
- req->result = readlink (tmp1, res, PATH_MAX);
- close (fd);
-
- /* here we should probably stat the open file and the disk file, to make sure they still match */
-
- if (req->result > 0)
- goto done;
- }
- else if (errno == ELOOP || errno == ENAMETOOLONG || errno == ENOENT || errno == ENOTDIR || errno == EIO)
- return;
- }
-#endif
-#endif
-
- if (*rel != '/')
- {
- if (!getcwd (res, PATH_MAX))
- return;
-
- if (res [1]) /* only use if not / */
- res += strlen (res);
- }
-
- while (*rel)
- {
- eio_ssize_t len, linklen;
- char *beg = rel;
-
- while (*rel && *rel != '/')
- ++rel;
-
- len = rel - beg;
-
- if (!len) /* skip slashes */
- {
- ++rel;
- continue;
- }
-
- if (beg [0] == '.')
- {
- if (len == 1)
- continue; /* . - nop */
-
- if (beg [1] == '.' && len == 2)
- {
- /* .. - back up one component, if possible */
-
- while (res != req->ptr2)
- if (*--res == '/')
- break;
-
- continue;
- }
- }
-
- errno = ENAMETOOLONG;
- if (res + 1 + len + 1 >= tmp1)
- return;
-
- /* copy one component */
- *res = '/';
- memcpy (res + 1, beg, len);
-
- /* zero-terminate, for readlink */
- res [len + 1] = 0;
-
- /* now check if it's a symlink */
- linklen = readlink (req->ptr2, tmp1, PATH_MAX);
-
- if (linklen < 0)
- {
- if (errno != EINVAL)
- return;
-
- /* it's a normal directory. hopefully */
- res += len + 1;
- }
- else
- {
- /* yay, it was a symlink - build new path in tmp2 */
- int rellen = strlen (rel);
-
- errno = ENAMETOOLONG;
- if (linklen + 1 + rellen >= PATH_MAX)
- return;
-
- errno = ELOOP;
- if (!--symlinks)
- return;
-
- if (*tmp1 == '/')
- res = req->ptr2; /* symlink resolves to an absolute path */
-
- /* we need to be careful, as rel might point into tmp2 already */
- memmove (tmp2 + linklen + 1, rel, rellen + 1);
- tmp2 [linklen] = '/';
- memcpy (tmp2, tmp1, linklen);
-
- rel = tmp2;
- }
- }
-
- /* special case for the lone root path */
- if (res == req->ptr2)
- *res++ = '/';
-
- req->result = res - (char *)req->ptr2;
-
-done:
- req->ptr2 = realloc (req->ptr2, req->result); /* trade time for space savings */
-}
-
-static signed char
-eio_dent_cmp (const eio_dirent *a, const eio_dirent *b)
-{
- return a->score - b->score ? a->score - b->score /* works because our signed char is always 0..100 */
- : a->inode < b->inode ? -1
- : a->inode > b->inode ? 1
- : 0;
-}
-
-#define EIO_DENT_CMP(i,op,j) eio_dent_cmp (&i, &j) op 0
-
-#define EIO_SORT_CUTOFF 30 /* quite high, but performs well on many filesystems */
-#define EIO_SORT_FAST 60 /* when to only use insertion sort */
-
-static void
-eio_dent_radix_sort (eio_dirent *dents, int size, signed char score_bits, eio_ino_t inode_bits)
-{
- unsigned char bits [9 + sizeof (eio_ino_t) * 8];
- unsigned char *bit = bits;
-
- assert (CHAR_BIT == 8);
- assert (sizeof (eio_dirent) * 8 < 256);
- assert (offsetof (eio_dirent, inode)); /* we use bit #0 as sentinel */
- assert (offsetof (eio_dirent, score)); /* we use bit #0 as sentinel */
-
- if (size <= EIO_SORT_FAST)
- return;
-
- /* first prepare an array of bits to test in our radix sort */
- /* try to take endianness into account, as well as differences in eio_ino_t sizes */
- /* inode_bits must contain all inodes ORed together */
- /* which is used to skip bits that are 0 everywhere, which is very common */
- {
- eio_ino_t endianness;
- int i, j;
-
- /* we store the byte offset of byte n into byte n of "endianness" */
- for (i = 0; i < sizeof (eio_ino_t); ++i)
- ((unsigned char *)&endianness)[i] = i;
-
- *bit++ = 0;
-
- for (i = 0; i < sizeof (eio_ino_t); ++i)
- {
- /* shifting off the byte offsets out of "endianness" */
- int offs = (offsetof (eio_dirent, inode) + (endianness & 0xff)) * 8;
- endianness >>= 8;
-
- for (j = 0; j < 8; ++j)
- if (inode_bits & (((eio_ino_t)1) << (i * 8 + j)))
- *bit++ = offs + j;
- }
-
- for (j = 0; j < 8; ++j)
- if (score_bits & (1 << j))
- *bit++ = offsetof (eio_dirent, score) * 8 + j;
- }
-
- /* now actually do the sorting (a variant of MSD radix sort) */
- {
- eio_dirent *base_stk [9 + sizeof (eio_ino_t) * 8], *base;
- eio_dirent *end_stk [9 + sizeof (eio_ino_t) * 8], *end;
- unsigned char *bit_stk [9 + sizeof (eio_ino_t) * 8];
- int stk_idx = 0;
-
- base_stk [stk_idx] = dents;
- end_stk [stk_idx] = dents + size;
- bit_stk [stk_idx] = bit - 1;
-
- do
- {
- base = base_stk [stk_idx];
- end = end_stk [stk_idx];
- bit = bit_stk [stk_idx];
-
- for (;;)
- {
- unsigned char O = *bit >> 3;
- unsigned char M = 1 << (*bit & 7);
-
- eio_dirent *a = base;
- eio_dirent *b = end;
-
- if (b - a < EIO_SORT_CUTOFF)
- break;
-
- /* now bit-partition the array on the bit */
- /* this ugly asymmetric loop seems to perform much better than typical */
- /* partition algos found in the literature */
- do
- if (!(((unsigned char *)a)[O] & M))
- ++a;
- else if (!(((unsigned char *)--b)[O] & M))
- {
- eio_dirent tmp = *a; *a = *b; *b = tmp;
- ++a;
- }
- while (b > a);
-
- /* next bit, or stop, if no bits left in this path */
- if (!*--bit)
- break;
-
- base_stk [stk_idx] = a;
- end_stk [stk_idx] = end;
- bit_stk [stk_idx] = bit;
- ++stk_idx;
-
- end = a;
- }
- }
- while (stk_idx--);
- }
-}
-
-static void
-eio_dent_insertion_sort (eio_dirent *dents, int size)
-{
- /* first move the smallest element to the front, to act as a sentinel */
- {
- int i;
- eio_dirent *min = dents;
-
- /* the radix pre-pass ensures that the minimum element is in the first EIO_SORT_CUTOFF + 1 elements */
- for (i = size > EIO_SORT_FAST ? EIO_SORT_CUTOFF + 1 : size; --i; )
- if (EIO_DENT_CMP (dents [i], <, *min))
- min = &dents [i];
-
- /* swap elements 0 and j (minimum) */
- {
- eio_dirent tmp = *dents; *dents = *min; *min = tmp;
- }
- }
-
- /* then do standard insertion sort, assuming that all elements are >= dents [0] */
- {
- eio_dirent *i, *j;
-
- for (i = dents + 1; i < dents + size; ++i)
- {
- eio_dirent value = *i;
-
- for (j = i - 1; EIO_DENT_CMP (*j, >, value); --j)
- j [1] = j [0];
-
- j [1] = value;
- }
- }
-}
-
-static void
-eio_dent_sort (eio_dirent *dents, int size, signed char score_bits, eio_ino_t inode_bits)
-{
- if (size <= 1)
- return; /* our insertion sort relies on size > 0 */
-
- /* first we use a radix sort, but only for dirs >= EIO_SORT_FAST */
- /* and stop sorting when the partitions are <= EIO_SORT_CUTOFF */
- eio_dent_radix_sort (dents, size, score_bits, inode_bits);
-
- /* use an insertion sort at the end, or for small arrays, */
- /* as insertion sort is more efficient for small partitions */
- eio_dent_insertion_sort (dents, size);
-}
-
-/* read a full directory */
-static void
-eio__scandir (eio_req *req, etp_worker *self)
-{
- char *name, *names;
- int namesalloc = 4096 - sizeof (void *) * 4;
- int namesoffs = 0;
- int flags = req->int1;
- eio_dirent *dents = 0;
- int dentalloc = 128;
- int dentoffs = 0;
- eio_ino_t inode_bits = 0;
-#ifdef _WIN32
- HANDLE dirp;
- WIN32_FIND_DATA entp;
-#else
- DIR *dirp;
- EIO_STRUCT_DIRENT *entp;
-#endif
-
- req->result = -1;
-
- if (!(flags & EIO_READDIR_DENTS))
- flags &= ~(EIO_READDIR_DIRS_FIRST | EIO_READDIR_STAT_ORDER);
-
-#ifdef _WIN32
- {
- int len = strlen ((const char *)req->ptr1);
- char *path = malloc (MAX_PATH);
- const char *fmt;
-
- if (!len)
- fmt = "./*";
- else if (((const char *)req->ptr1)[len - 1] == '/' || ((const char *)req->ptr1)[len - 1] == '\\')
- fmt = "%s*";
- else
- fmt = "%s/*";
-
- _snprintf (path, MAX_PATH, fmt, (const char *)req->ptr1);
- dirp = FindFirstFile (path, &entp);
- free (path);
-
- if (dirp == INVALID_HANDLE_VALUE)
- {
- dirp = 0;
-
- /* should steal _dosmaperr */
- switch (GetLastError ())
- {
- case ERROR_FILE_NOT_FOUND:
- req->result = 0;
- break;
-
- case ERROR_INVALID_NAME:
- case ERROR_PATH_NOT_FOUND:
- case ERROR_NO_MORE_FILES:
- errno = ENOENT;
- break;
-
- case ERROR_NOT_ENOUGH_MEMORY:
- errno = ENOMEM;
- break;
-
- default:
- errno = EINVAL;
- break;
- }
- }
- }
-#else
- dirp = opendir (req->ptr1);
-#endif
-
- if (req->flags & EIO_FLAG_PTR1_FREE)
- free (req->ptr1);
-
- req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE;
- req->ptr1 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0;
- req->ptr2 = names = malloc (namesalloc);
-
- if (dirp && names && (!flags || dents))
- for (;;)
- {
- int done;
-
-#ifdef _WIN32
- done = !dirp;
-#else
- errno = 0;
- entp = readdir (dirp);
- done = !entp;
-#endif
-
- if (done)
- {
-#ifndef _WIN32
- int old_errno = errno;
- closedir (dirp);
- errno = old_errno;
-
- if (errno)
- break;
-#endif
-
- /* sort etc. */
- req->int1 = flags;
- req->result = dentoffs;
-
- if (flags & EIO_READDIR_STAT_ORDER)
- eio_dent_sort (dents, dentoffs, flags & EIO_READDIR_DIRS_FIRST ? 7 : 0, inode_bits);
- else if (flags & EIO_READDIR_DIRS_FIRST)
- if (flags & EIO_READDIR_FOUND_UNKNOWN)
- eio_dent_sort (dents, dentoffs, 7, inode_bits); /* sort by score and inode */
- else
- {
- /* in this case, all is known, and we just put dirs first and sort them */
- eio_dirent *oth = dents + dentoffs;
- eio_dirent *dir = dents;
-
- /* now partition dirs to the front, and non-dirs to the back */
- /* by walking from both sides and swapping if necessary */
- while (oth > dir)
- {
- if (dir->type == EIO_DT_DIR)
- ++dir;
- else if ((--oth)->type == EIO_DT_DIR)
- {
- eio_dirent tmp = *dir; *dir = *oth; *oth = tmp;
-
- ++dir;
- }
- }
-
- /* now sort the dirs only (dirs all have the same score) */
- eio_dent_sort (dents, dir - dents, 0, inode_bits);
- }
-
- break;
- }
-
- /* now add the entry to our list(s) */
- name = D_NAME (entp);
-
- /* skip . and .. entries */
- if (name [0] != '.' || (name [1] && (name [1] != '.' || name [2])))
- {
- int len = D_NAMLEN (entp) + 1;
-
- while (ecb_expect_false (namesoffs + len > namesalloc))
- {
- namesalloc *= 2;
- req->ptr2 = names = realloc (names, namesalloc);
-
- if (!names)
- break;
- }
-
- memcpy (names + namesoffs, name, len);
-
- if (dents)
- {
- struct eio_dirent *ent;
-
- if (ecb_expect_false (dentoffs == dentalloc))
- {
- dentalloc *= 2;
- req->ptr1 = dents = realloc (dents, dentalloc * sizeof (eio_dirent));
-
- if (!dents)
- break;
- }
-
- ent = dents + dentoffs;
-
- ent->nameofs = namesoffs; /* rather dirtily we store the offset in the pointer */
- ent->namelen = len - 1;
- ent->inode = D_INO (entp);
-
- inode_bits |= ent->inode;
-
- switch (D_TYPE (entp))
- {
- default:
- ent->type = EIO_DT_UNKNOWN;
- flags |= EIO_READDIR_FOUND_UNKNOWN;
- break;
-
- #ifdef DT_FIFO
- case DT_FIFO: ent->type = EIO_DT_FIFO; break;
- #endif
- #ifdef DT_CHR
- case DT_CHR: ent->type = EIO_DT_CHR; break;
- #endif
- #ifdef DT_MPC
- case DT_MPC: ent->type = EIO_DT_MPC; break;
- #endif
- #ifdef DT_DIR
- case DT_DIR: ent->type = EIO_DT_DIR; break;
- #endif
- #ifdef DT_NAM
- case DT_NAM: ent->type = EIO_DT_NAM; break;
- #endif
- #ifdef DT_BLK
- case DT_BLK: ent->type = EIO_DT_BLK; break;
- #endif
- #ifdef DT_MPB
- case DT_MPB: ent->type = EIO_DT_MPB; break;
- #endif
- #ifdef DT_REG
- case DT_REG: ent->type = EIO_DT_REG; break;
- #endif
- #ifdef DT_NWK
- case DT_NWK: ent->type = EIO_DT_NWK; break;
- #endif
- #ifdef DT_CMP
- case DT_CMP: ent->type = EIO_DT_CMP; break;
- #endif
- #ifdef DT_LNK
- case DT_LNK: ent->type = EIO_DT_LNK; break;
- #endif
- #ifdef DT_SOCK
- case DT_SOCK: ent->type = EIO_DT_SOCK; break;
- #endif
- #ifdef DT_DOOR
- case DT_DOOR: ent->type = EIO_DT_DOOR; break;
- #endif
- #ifdef DT_WHT
- case DT_WHT: ent->type = EIO_DT_WHT; break;
- #endif
- }
-
- ent->score = 7;
-
- if (flags & EIO_READDIR_DIRS_FIRST)
- {
- if (ent->type == EIO_DT_UNKNOWN)
- {
- if (*name == '.') /* leading dots are likely directories, and, in any case, rare */
- ent->score = 1;
- else if (!strchr (name, '.')) /* absense of dots indicate likely dirs */
- ent->score = len <= 2 ? 4 - len : len <= 4 ? 4 : len <= 7 ? 5 : 6; /* shorter == more likely dir, but avoid too many classes */
- }
- else if (ent->type == EIO_DT_DIR)
- ent->score = 0;
- }
- }
-
- namesoffs += len;
- ++dentoffs;
- }
-
- if (EIO_CANCELLED (req))
- {
- errno = ECANCELED;
- break;
- }
-
-#ifdef _WIN32
- if (!FindNextFile (dirp, &entp))
- {
- FindClose (dirp);
- dirp = 0;
- }
-#endif
- }
-}
-
-/*****************************************************************************/
-
-#define ALLOC(len) \
- if (!req->ptr2) \
- { \
- X_LOCK (wrklock); \
- req->flags |= EIO_FLAG_PTR2_FREE; \
- X_UNLOCK (wrklock); \
- req->ptr2 = malloc (len); \
- if (!req->ptr2) \
- { \
- errno = ENOMEM; \
- req->result = -1; \
- break; \
- } \
- }
-
-X_THREAD_PROC (etp_proc)
-{
- ETP_REQ *req;
- struct timespec ts;
- etp_worker *self = (etp_worker *)thr_arg;
-
-#if HAVE_PRCTL_SET_NAME
- prctl (PR_SET_NAME, (unsigned long)"eio_thread", 0, 0, 0);
-#endif
-
- /* try to distribute timeouts somewhat evenly */
- ts.tv_nsec = ((unsigned long)self & 1023UL) * (1000000000UL / 1024UL);
-
- for (;;)
- {
- ts.tv_sec = 0;
-
- X_LOCK (reqlock);
-
- for (;;)
- {
- self->req = req = reqq_shift (&req_queue);
-
- if (req)
- break;
-
- if (ts.tv_sec == 1) /* no request, but timeout detected, let's quit */
- {
- X_UNLOCK (reqlock);
- X_LOCK (wrklock);
- --started;
- X_UNLOCK (wrklock);
- goto quit;
- }
-
- ++idle;
-
- if (idle <= max_idle)
- /* we are allowed to idle, so do so without any timeout */
- X_COND_WAIT (reqwait, reqlock);
- else
- {
- /* initialise timeout once */
- if (!ts.tv_sec)
- ts.tv_sec = time (0) + idle_timeout;
-
- if (X_COND_TIMEDWAIT (reqwait, reqlock, ts) == ETIMEDOUT)
- ts.tv_sec = 1; /* assuming this is not a value computed above.,.. */
- }
-
- --idle;
- }
-
- --nready;
-
- X_UNLOCK (reqlock);
-
- if (req->type < 0)
- goto quit;
-
- ETP_EXECUTE (self, req);
-
- X_LOCK (reslock);
-
- ++npending;
-
- if (!reqq_push (&req->channel->res_queue, req) && want_poll_cb)
- want_poll_cb (req->channel);
-
- self->req = 0;
- etp_worker_clear (self);
-
- X_UNLOCK (reslock);
- }
-
-quit:
- X_LOCK (wrklock);
- etp_worker_free (self);
- X_UNLOCK (wrklock);
-
- return 0;
-}
-
-/*****************************************************************************/
-
-int ecb_cold
-eio_init (void (*want_poll)(eio_channel *), void (*done_poll)(eio_channel *))
-{
-#if !HAVE_PREADWRITE
- X_MUTEX_CREATE (preadwritelock);
-#endif
-
- return etp_init (want_poll, done_poll);
-}
-
-ecb_inline void
-eio_api_destroy (eio_req *req)
-{
- free (req);
-}
-
-#define REQ(rtype) \
- eio_req *req; \
- \
- req = (eio_req *)calloc (1, sizeof *req); \
- if (!req) \
- return 0; \
- \
- req->type = rtype; \
- req->pri = pri; \
- req->finish = cb; \
- req->data = data; \
- req->destroy = eio_api_destroy; \
- req->channel = channel
-
-#define SEND eio_submit (req); return req
-
-#define PATH \
- req->flags |= EIO_FLAG_PTR1_FREE; \
- req->ptr1 = strdup (path); \
- if (!req->ptr1) \
- { \
- eio_api_destroy (req); \
- return 0; \
- }
-
-static void
-eio_execute (etp_worker *self, eio_req *req)
-{
- if (ecb_expect_false (EIO_CANCELLED (req)))
- {
- req->result = -1;
- req->errorno = ECANCELED;
- return;
- }
-
- switch (req->type)
- {
- case EIO_READ: ALLOC (req->size);
- req->result = req->offs >= 0
- ? pread (req->int1, req->ptr2, req->size, req->offs)
- : read (req->int1, req->ptr2, req->size); break;
-
- case EIO_WRITE:
-#if defined (__APPLE__)
- pthread_mutex_lock (&apple_bug_writelock);
-#endif
-
- req->result = req->offs >= 0
- ? pwrite (req->int1, req->ptr2, req->size, req->offs)
- : write (req->int1, req->ptr2, req->size);
-
-#if defined (__APPLE__)
- pthread_mutex_unlock (&apple_bug_writelock);
-#endif
- break;
-
- case EIO_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break;
- case EIO_SENDFILE: req->result = eio__sendfile (req->int1, req->int2, req->offs, req->size); break;
-
- case EIO_STAT: ALLOC (sizeof (EIO_STRUCT_STAT));
- req->result = stat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break;
- case EIO_LSTAT: ALLOC (sizeof (EIO_STRUCT_STAT));
- req->result = lstat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break;
- case EIO_FSTAT: ALLOC (sizeof (EIO_STRUCT_STAT));
- req->result = fstat (req->int1, (EIO_STRUCT_STAT *)req->ptr2); break;
-
- case EIO_STATVFS: ALLOC (sizeof (EIO_STRUCT_STATVFS));
- req->result = statvfs (req->ptr1, (EIO_STRUCT_STATVFS *)req->ptr2); break;
- case EIO_FSTATVFS: ALLOC (sizeof (EIO_STRUCT_STATVFS));
- req->result = fstatvfs (req->int1, (EIO_STRUCT_STATVFS *)req->ptr2); break;
-
- case EIO_CHOWN: req->result = chown (req->ptr1, req->int2, req->int3); break;
- case EIO_FCHOWN: req->result = fchown (req->int1, req->int2, req->int3); break;
- case EIO_CHMOD: req->result = chmod (req->ptr1, (eio_mode_t)req->int2); break;
- case EIO_FCHMOD: req->result = fchmod (req->int1, (eio_mode_t)req->int2); break;
- case EIO_TRUNCATE: req->result = truncate (req->ptr1, req->offs); break;
- case EIO_FTRUNCATE: req->result = ftruncate (req->int1, req->offs); break;
-
- case EIO_OPEN: req->result = open (req->ptr1, req->int1, (eio_mode_t)req->int2); break;
- case EIO_CLOSE: req->result = close (req->int1); break;
- case EIO_DUP2: req->result = dup2 (req->int1, req->int2); break;
- case EIO_UNLINK: req->result = unlink (req->ptr1); break;
- case EIO_RMDIR: req->result = rmdir (req->ptr1); break;
- case EIO_MKDIR: req->result = mkdir (req->ptr1, (eio_mode_t)req->int2); break;
- case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break;
- case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break;
- case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break;
- case EIO_MKNOD: req->result = mknod (req->ptr1, (eio_mode_t)req->int2, (dev_t)req->offs); break;
-
- case EIO_REALPATH: eio__realpath (req, self); break;
-
- case EIO_READLINK: ALLOC (PATH_MAX);
- req->result = readlink (req->ptr1, req->ptr2, PATH_MAX); break;
-
- case EIO_SYNC: req->result = 0; sync (); break;
- case EIO_FSYNC: req->result = fsync (req->int1); break;
- case EIO_FDATASYNC: req->result = fdatasync (req->int1); break;
- case EIO_SYNCFS: req->result = eio__syncfs (req->int1); break;
- case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break;
- case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break;
- case EIO_MTOUCH: req->result = eio__mtouch (req); break;
- case EIO_MLOCK: req->result = eio__mlock (req->ptr2, req->size); break;
- case EIO_MLOCKALL: req->result = eio__mlockall (req->int1); break;
- case EIO_FALLOCATE: req->result = eio__fallocate (req->int1, req->int2, req->offs, req->size); break;
-
- case EIO_READDIR: eio__scandir (req, self); break;
-
- case EIO_BUSY:
-#ifdef _WIN32
- Sleep (req->nv1 * 1e3);
-#else
- {
- struct timeval tv;
-
- tv.tv_sec = req->nv1;
- tv.tv_usec = (req->nv1 - tv.tv_sec) * 1e6;
-
- req->result = select (0, 0, 0, 0, &tv);
- }
-#endif
- break;
-
- case EIO_UTIME:
- case EIO_FUTIME:
- {
- struct timeval tv[2];
- struct timeval *times;
-
- if (req->nv1 != -1. || req->nv2 != -1.)
- {
- tv[0].tv_sec = req->nv1;
- tv[0].tv_usec = (req->nv1 - tv[0].tv_sec) * 1000000.;
- tv[1].tv_sec = req->nv2;
- tv[1].tv_usec = (req->nv2 - tv[1].tv_sec) * 1000000.;
-
- times = tv;
- }
- else
- times = 0;
-
- req->result = req->type == EIO_FUTIME
- ? futimes (req->int1, times)
- : utimes (req->ptr1, times);
- }
- break;
-
- case EIO_GROUP:
- abort (); /* handled in eio_request */
-
- case EIO_NOP:
- req->result = 0;
- break;
-
- case EIO_CUSTOM:
- req->feed (req);
- break;
-
- default:
- errno = ENOSYS;
- req->result = -1;
- break;
- }
-
- req->errorno = errno;
-}
-
-#ifndef EIO_NO_WRAPPERS
-
-eio_req *eio_nop (int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_NOP); SEND;
-}
-
-eio_req *eio_busy (double delay, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_BUSY); req->nv1 = delay; SEND;
-}
-
-eio_req *eio_sync (int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_SYNC); SEND;
-}
-
-eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_FSYNC); req->int1 = fd; SEND;
-}
-
-eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_MSYNC); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
-}
-
-eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_FDATASYNC); req->int1 = fd; SEND;
-}
-
-eio_req *eio_syncfs (int fd, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_SYNCFS); req->int1 = fd; SEND;
-}
-
-eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_SYNC_FILE_RANGE); req->int1 = fd; req->offs = offset; req->size = nbytes; req->int2 = flags; SEND;
-}
-
-eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_MTOUCH); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
-}
-
-eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_MLOCK); req->ptr2 = addr; req->size = length; SEND;
-}
-
-eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_MLOCKALL); req->int1 = flags; SEND;
-}
-
-eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_FALLOCATE); req->int1 = fd; req->int2 = mode; req->offs = offset; req->size = len; SEND;
-}
-
-eio_req *eio_close (int fd, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_CLOSE); req->int1 = fd; SEND;
-}
-
-eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_READAHEAD); req->int1 = fd; req->offs = offset; req->size = length; SEND;
-}
-
-eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_READ); req->int1 = fd; req->offs = offset; req->size = length; req->ptr2 = buf; SEND;
-}
-
-eio_req *eio_write (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_WRITE); req->int1 = fd; req->offs = offset; req->size = length; req->ptr2 = buf; SEND;
-}
-
-eio_req *eio_fstat (int fd, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_FSTAT); req->int1 = fd; SEND;
-}
-
-eio_req *eio_fstatvfs (int fd, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_FSTATVFS); req->int1 = fd; SEND;
-}
-
-eio_req *eio_futime (int fd, double atime, double mtime, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_FUTIME); req->int1 = fd; req->nv1 = atime; req->nv2 = mtime; SEND;
-}
-
-eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_FTRUNCATE); req->int1 = fd; req->offs = offset; SEND;
-}
-
-eio_req *eio_fchmod (int fd, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_FCHMOD); req->int1 = fd; req->int2 = (long)mode; SEND;
-}
-
-eio_req *eio_fchown (int fd, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_FCHOWN); req->int1 = fd; req->int2 = (long)uid; req->int3 = (long)gid; SEND;
-}
-
-eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_DUP2); req->int1 = fd; req->int2 = fd2; SEND;
-}
-
-eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_SENDFILE); req->int1 = out_fd; req->int2 = in_fd; req->offs = in_offset; req->size = length; SEND;
-}
-
-eio_req *eio_open (const char *path, int flags, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_OPEN); PATH; req->int1 = flags; req->int2 = (long)mode; SEND;
-}
-
-eio_req *eio_utime (const char *path, double atime, double mtime, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_UTIME); PATH; req->nv1 = atime; req->nv2 = mtime; SEND;
-}
-
-eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_TRUNCATE); PATH; req->offs = offset; SEND;
-}
-
-eio_req *eio_chown (const char *path, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_CHOWN); PATH; req->int2 = (long)uid; req->int3 = (long)gid; SEND;
-}
-
-eio_req *eio_chmod (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_CHMOD); PATH; req->int2 = (long)mode; SEND;
-}
-
-eio_req *eio_mkdir (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_MKDIR); PATH; req->int2 = (long)mode; SEND;
-}
-
-static eio_req *
-eio__1path (int type, const char *path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (type); PATH; SEND;
-}
-
-eio_req *eio_readlink (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- return eio__1path (EIO_READLINK, path, pri, cb, data, channel);
-}
-
-eio_req *eio_realpath (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- return eio__1path (EIO_REALPATH, path, pri, cb, data, channel);
-}
-
-eio_req *eio_stat (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- return eio__1path (EIO_STAT, path, pri, cb, data, channel);
-}
-
-eio_req *eio_lstat (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- return eio__1path (EIO_LSTAT, path, pri, cb, data, channel);
-}
-
-eio_req *eio_statvfs (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- return eio__1path (EIO_STATVFS, path, pri, cb, data, channel);
-}
-
-eio_req *eio_unlink (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- return eio__1path (EIO_UNLINK, path, pri, cb, data, channel);
-}
-
-eio_req *eio_rmdir (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- return eio__1path (EIO_RMDIR, path, pri, cb, data, channel);
-}
-
-eio_req *eio_readdir (const char *path, int flags, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_READDIR); PATH; req->int1 = flags; SEND;
-}
-
-eio_req *eio_mknod (const char *path, eio_mode_t mode, dev_t dev, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_MKNOD); PATH; req->int2 = (long)mode; req->offs = (off_t)dev; SEND;
-}
-
-static eio_req *
-eio__2path (int type, const char *path, const char *new_path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (type); PATH;
-
- req->flags |= EIO_FLAG_PTR2_FREE;
- req->ptr2 = strdup (new_path);
- if (!req->ptr2)
- {
- eio_api_destroy (req);
- return 0;
- }
-
- SEND;
-}
-
-eio_req *eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- return eio__2path (EIO_LINK, path, new_path, pri, cb, data, channel);
-}
-
-eio_req *eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- return eio__2path (EIO_SYMLINK, path, new_path, pri, cb, data, channel);
-}
-
-eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- return eio__2path (EIO_RENAME, path, new_path, pri, cb, data, channel);
-}
-
-eio_req *eio_custom (void (*execute)(eio_req *), int pri, eio_cb cb, void *data, eio_channel *channel)
-{
- REQ (EIO_CUSTOM); req->feed = execute; SEND;
-}
-
-#endif
-
-eio_req *eio_grp (eio_cb cb, void *data, eio_channel *channel)
-{
- const int pri = EIO_PRI_MAX;
-
- REQ (EIO_GROUP); SEND;
-}
-
-#undef REQ
-#undef PATH
-#undef SEND
-
-/*****************************************************************************/
-/* grp functions */
-
-void
-eio_grp_feed (eio_req *grp, void (*feed)(eio_req *req), int limit)
-{
- grp->int2 = limit;
- grp->feed = feed;
-
- grp_try_feed (grp);
-}
-
-void
-eio_grp_limit (eio_req *grp, int limit)
-{
- grp->int2 = limit;
-
- grp_try_feed (grp);
-}
-
-void
-eio_grp_add (eio_req *grp, eio_req *req)
-{
- assert (("cannot add requests to IO::AIO::GRP after the group finished", grp->int1 != 2));
-
- grp->flags |= EIO_FLAG_GROUPADD;
-
- ++grp->size;
- req->grp = grp;
-
- req->grp_prev = 0;
- req->grp_next = grp->grp_first;
-
- if (grp->grp_first)
- grp->grp_first->grp_prev = req;
-
- grp->grp_first = req;
-}
-
-/*****************************************************************************/
-/* misc garbage */
-
-eio_ssize_t
-eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count)
-{
- return eio__sendfile (ofd, ifd, offset, count);
-}
-
diff --git a/deps/uv/src/unix/eio/eio.pod b/deps/uv/src/unix/eio/eio.pod
deleted file mode 100644
index da5f33c01..000000000
--- a/deps/uv/src/unix/eio/eio.pod
+++ /dev/null
@@ -1,969 +0,0 @@
-=head1 NAME
-
-libeio - truly asynchronous POSIX I/O
-
-=head1 SYNOPSIS
-
- #include <eio.h>
-
-=head1 DESCRIPTION
-
-The newest version of this document is also available as an html-formatted
-web page you might find easier to navigate when reading it for the first
-time: L<http://pod.tst.eu/http://cvs.schmorp.de/libeio/eio.pod>.
-
-Note that this library is a by-product of the C<IO::AIO> perl
-module, and many of the subtler points regarding requests lifetime
-and so on are only documented in its documentation at the
-moment: L<http://pod.tst.eu/http://cvs.schmorp.de/IO-AIO/AIO.pm>.
-
-=head2 FEATURES
-
-This library provides fully asynchronous versions of most POSIX functions
-dealing with I/O. Unlike most asynchronous libraries, this not only
-includes C<read> and C<write>, but also C<open>, C<stat>, C<unlink> and
-similar functions, as well as less rarely ones such as C<mknod>, C<futime>
-or C<readlink>.
-
-It also offers wrappers around C<sendfile> (Solaris, Linux, HP-UX and
-FreeBSD, with emulation on other platforms) and C<readahead> (Linux, with
-emulation elsewhere>).
-
-The goal is to enable you to write fully non-blocking programs. For
-example, in a game server, you would not want to freeze for a few seconds
-just because the server is running a backup and you happen to call
-C<readdir>.
-
-=head2 TIME REPRESENTATION
-
-Libeio represents time as a single floating point number, representing the
-(fractional) number of seconds since the (POSIX) epoch (somewhere near
-the beginning of 1970, details are complicated, don't ask). This type is
-called C<eio_tstamp>, but it is guaranteed to be of type C<double> (or
-better), so you can freely use C<double> yourself.
-
-Unlike the name component C<stamp> might indicate, it is also used for
-time differences throughout libeio.
-
-=head2 FORK SUPPORT
-
-Usage of pthreads in a program changes the semantics of fork
-considerably. Specifically, only async-safe functions can be called after
-fork. Libeio uses pthreads, so this applies, and makes using fork hard for
-anything but relatively fork + exec uses.
-
-This library only works in the process that initialised it: Forking is
-fully supported, but using libeio in any other process than the one that
-called C<eio_init> is not.
-
-You might get around by not I<using> libeio before (or after) forking in
-the parent, and using it in the child afterwards. You could also try to
-call the L<eio_init> function again in the child, which will brutally
-reinitialise all data structures, which isn't POSIX conformant, but
-typically works.
-
-Otherwise, the only recommendation you should follow is: treat fork code
-the same way you treat signal handlers, and only ever call C<eio_init> in
-the process that uses it, and only once ever.
-
-=head1 INITIALISATION/INTEGRATION
-
-Before you can call any eio functions you first have to initialise the
-library. The library integrates into any event loop, but can also be used
-without one, including in polling mode.
-
-You have to provide the necessary glue yourself, however.
-
-=over 4
-
-=item int eio_init (void (*want_poll)(void), void (*done_poll)(void))
-
-This function initialises the library. On success it returns C<0>, on
-failure it returns C<-1> and sets C<errno> appropriately.
-
-It accepts two function pointers specifying callbacks as argument, both of
-which can be C<0>, in which case the callback isn't called.
-
-There is currently no way to change these callbacks later, or to
-"uninitialise" the library again.
-
-=item want_poll callback
-
-The C<want_poll> callback is invoked whenever libeio wants attention (i.e.
-it wants to be polled by calling C<eio_poll>). It is "edge-triggered",
-that is, it will only be called once when eio wants attention, until all
-pending requests have been handled.
-
-This callback is called while locks are being held, so I<you must
-not call any libeio functions inside this callback>. That includes
-C<eio_poll>. What you should do is notify some other thread, or wake up
-your event loop, and then call C<eio_poll>.
-
-=item done_poll callback
-
-This callback is invoked when libeio detects that all pending requests
-have been handled. It is "edge-triggered", that is, it will only be
-called once after C<want_poll>. To put it differently, C<want_poll> and
-C<done_poll> are invoked in pairs: after C<want_poll> you have to call
-C<eio_poll ()> until either C<eio_poll> indicates that everything has been
-handled or C<done_poll> has been called, which signals the same.
-
-Note that C<eio_poll> might return after C<done_poll> and C<want_poll>
-have been called again, so watch out for races in your code.
-
-As with C<want_poll>, this callback is called while locks are being held,
-so you I<must not call any libeio functions form within this callback>.
-
-=item int eio_poll ()
-
-This function has to be called whenever there are pending requests that
-need finishing. You usually call this after C<want_poll> has indicated
-that you should do so, but you can also call this function regularly to
-poll for new results.
-
-If any request invocation returns a non-zero value, then C<eio_poll ()>
-immediately returns with that value as return value.
-
-Otherwise, if all requests could be handled, it returns C<0>. If for some
-reason not all requests have been handled, i.e. some are still pending, it
-returns C<-1>.
-
-=back
-
-For libev, you would typically use an C<ev_async> watcher: the
-C<want_poll> callback would invoke C<ev_async_send> to wake up the event
-loop. Inside the callback set for the watcher, one would call C<eio_poll
-()>.
-
-If C<eio_poll ()> is configured to not handle all results in one go
-(i.e. it returns C<-1>) then you should start an idle watcher that calls
-C<eio_poll> until it returns something C<!= -1>.
-
-A full-featured connector between libeio and libev would look as follows
-(if C<eio_poll> is handling all requests, it can of course be simplified a
-lot by removing the idle watcher logic):
-
- static struct ev_loop *loop;
- static ev_idle repeat_watcher;
- static ev_async ready_watcher;
-
- /* idle watcher callback, only used when eio_poll */
- /* didn't handle all results in one call */
- static void
- repeat (EV_P_ ev_idle *w, int revents)
- {
- if (eio_poll () != -1)
- ev_idle_stop (EV_A_ w);
- }
-
- /* eio has some results, process them */
- static void
- ready (EV_P_ ev_async *w, int revents)
- {
- if (eio_poll () == -1)
- ev_idle_start (EV_A_ &repeat_watcher);
- }
-
- /* wake up the event loop */
- static void
- want_poll (void)
- {
- ev_async_send (loop, &ready_watcher)
- }
-
- void
- my_init_eio ()
- {
- loop = EV_DEFAULT;
-
- ev_idle_init (&repeat_watcher, repeat);
- ev_async_init (&ready_watcher, ready);
- ev_async_start (loop &watcher);
-
- eio_init (want_poll, 0);
- }
-
-For most other event loops, you would typically use a pipe - the event
-loop should be told to wait for read readiness on the read end. In
-C<want_poll> you would write a single byte, in C<done_poll> you would try
-to read that byte, and in the callback for the read end, you would call
-C<eio_poll>.
-
-You don't have to take special care in the case C<eio_poll> doesn't handle
-all requests, as the done callback will not be invoked, so the event loop
-will still signal readiness for the pipe until I<all> results have been
-processed.
-
-
-=head1 HIGH LEVEL REQUEST API
-
-Libeio has both a high-level API, which consists of calling a request
-function with a callback to be called on completion, and a low-level API
-where you fill out request structures and submit them.
-
-This section describes the high-level API.
-
-=head2 REQUEST SUBMISSION AND RESULT PROCESSING
-
-You submit a request by calling the relevant C<eio_TYPE> function with the
-required parameters, a callback of type C<int (*eio_cb)(eio_req *req)>
-(called C<eio_cb> below) and a freely usable C<void *data> argument.
-
-The return value will either be 0, in case something went really wrong
-(which can basically only happen on very fatal errors, such as C<malloc>
-returning 0, which is rather unlikely), or a pointer to the newly-created
-and submitted C<eio_req *>.
-
-The callback will be called with an C<eio_req *> which contains the
-results of the request. The members you can access inside that structure
-vary from request to request, except for:
-
-=over 4
-
-=item C<ssize_t result>
-
-This contains the result value from the call (usually the same as the
-syscall of the same name).
-
-=item C<int errorno>
-
-This contains the value of C<errno> after the call.
-
-=item C<void *data>
-
-The C<void *data> member simply stores the value of the C<data> argument.
-
-=back
-
-The return value of the callback is normally C<0>, which tells libeio to
-continue normally. If a callback returns a nonzero value, libeio will
-stop processing results (in C<eio_poll>) and will return the value to its
-caller.
-
-Memory areas passed to libeio must stay valid as long as a request
-executes, with the exception of paths, which are being copied
-internally. Any memory libeio itself allocates will be freed after the
-finish callback has been called. If you want to manage all memory passed
-to libeio yourself you can use the low-level API.
-
-For example, to open a file, you could do this:
-
- static int
- file_open_done (eio_req *req)
- {
- if (req->result < 0)
- {
- /* open() returned -1 */
- errno = req->errorno;
- perror ("open");
- }
- else
- {
- int fd = req->result;
- /* now we have the new fd in fd */
- }
-
- return 0;
- }
-
- /* the first three arguments are passed to open(2) */
- /* the remaining are priority, callback and data */
- if (!eio_open ("/etc/passwd", O_RDONLY, 0, 0, file_open_done, 0))
- abort (); /* something went wrong, we will all die!!! */
-
-Note that you additionally need to call C<eio_poll> when the C<want_cb>
-indicates that requests are ready to be processed.
-
-=head2 CANCELLING REQUESTS
-
-Sometimes the need for a request goes away before the request is
-finished. In that case, one can cancel the request by a call to
-C<eio_cancel>:
-
-=over 4
-
-=item eio_cancel (eio_req *req)
-
-Cancel the request (and all its subrequests). If the request is currently
-executing it might still continue to execute, and in other cases it might
-still take a while till the request is cancelled.
-
-Even if cancelled, the finish callback will still be invoked - the
-callbacks of all cancellable requests need to check whether the request
-has been cancelled by calling C<EIO_CANCELLED (req)>:
-
- static int
- my_eio_cb (eio_req *req)
- {
- if (EIO_CANCELLED (req))
- return 0;
- }
-
-In addition, cancelled requests will I<either> have C<< req->result >>
-set to C<-1> and C<errno> to C<ECANCELED>, or I<otherwise> they were
-successfully executed, despite being cancelled (e.g. when they have
-already been executed at the time they were cancelled).
-
-C<EIO_CANCELLED> is still true for requests that have successfully
-executed, as long as C<eio_cancel> was called on them at some point.
-
-=back
-
-=head2 AVAILABLE REQUESTS
-
-The following request functions are available. I<All> of them return the
-C<eio_req *> on success and C<0> on failure, and I<all> of them have the
-same three trailing arguments: C<pri>, C<cb> and C<data>. The C<cb> is
-mandatory, but in most cases, you pass in C<0> as C<pri> and C<0> or some
-custom data value as C<data>.
-
-=head3 POSIX API WRAPPERS
-
-These requests simply wrap the POSIX call of the same name, with the same
-arguments. If a function is not implemented by the OS and cannot be emulated
-in some way, then all of these return C<-1> and set C<errorno> to C<ENOSYS>.
-
-=over 4
-
-=item eio_open (const char *path, int flags, mode_t mode, int pri, eio_cb cb, void *data)
-
-=item eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data)
-
-=item eio_chown (const char *path, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data)
-
-=item eio_chmod (const char *path, mode_t mode, int pri, eio_cb cb, void *data)
-
-=item eio_mkdir (const char *path, mode_t mode, int pri, eio_cb cb, void *data)
-
-=item eio_rmdir (const char *path, int pri, eio_cb cb, void *data)
-
-=item eio_unlink (const char *path, int pri, eio_cb cb, void *data)
-
-=item eio_utime (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data)
-
-=item eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data)
-
-=item eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data)
-
-=item eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data)
-
-=item eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data)
-
-=item eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data)
-
-=item eio_close (int fd, int pri, eio_cb cb, void *data)
-
-=item eio_sync (int pri, eio_cb cb, void *data)
-
-=item eio_fsync (int fd, int pri, eio_cb cb, void *data)
-
-=item eio_fdatasync (int fd, int pri, eio_cb cb, void *data)
-
-=item eio_futime (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data)
-
-=item eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data)
-
-=item eio_fchmod (int fd, mode_t mode, int pri, eio_cb cb, void *data)
-
-=item eio_fchown (int fd, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data)
-
-=item eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data)
-
-These have the same semantics as the syscall of the same name, their
-return value is available as C<< req->result >> later.
-
-=item eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data)
-
-=item eio_write (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data)
-
-These two requests are called C<read> and C<write>, but actually wrap
-C<pread> and C<pwrite>. On systems that lack these calls (such as cygwin),
-libeio uses lseek/read_or_write/lseek and a mutex to serialise the
-requests, so all these requests run serially and do not disturb each
-other. However, they still disturb the file offset while they run, so it's
-not safe to call these functions concurrently with non-libeio functions on
-the same fd on these systems.
-
-Not surprisingly, pread and pwrite are not thread-safe on Darwin (OS/X),
-so it is advised not to submit multiple requests on the same fd on this
-horrible pile of garbage.
-
-=item eio_mlockall (int flags, int pri, eio_cb cb, void *data)
-
-Like C<mlockall>, but the flag value constants are called
-C<EIO_MCL_CURRENT> and C<EIO_MCL_FUTURE>.
-
-=item eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
-
-Just like msync, except that the flag values are called C<EIO_MS_ASYNC>,
-C<EIO_MS_INVALIDATE> and C<EIO_MS_SYNC>.
-
-=item eio_readlink (const char *path, int pri, eio_cb cb, void *data)
-
-If successful, the path read by C<readlink(2)> can be accessed via C<<
-req->ptr2 >> and is I<NOT> null-terminated, with the length specified as
-C<< req->result >>.
-
- if (req->result >= 0)
- {
- char *target = strndup ((char *)req->ptr2, req->result);
-
- free (target);
- }
-
-=item eio_realpath (const char *path, int pri, eio_cb cb, void *data)
-
-Similar to the realpath libc function, but unlike that one, C<<
-req->result >> is C<-1> on failure. On success, the result is the length
-of the returned path in C<ptr2> (which is I<NOT> 0-terminated) - this is
-similar to readlink.
-
-=item eio_stat (const char *path, int pri, eio_cb cb, void *data)
-
-=item eio_lstat (const char *path, int pri, eio_cb cb, void *data)
-
-=item eio_fstat (int fd, int pri, eio_cb cb, void *data)
-
-Stats a file - if C<< req->result >> indicates success, then you can
-access the C<struct stat>-like structure via C<< req->ptr2 >>:
-
- EIO_STRUCT_STAT *statdata = (EIO_STRUCT_STAT *)req->ptr2;
-
-=item eio_statvfs (const char *path, int pri, eio_cb cb, void *data)
-
-=item eio_fstatvfs (int fd, int pri, eio_cb cb, void *data)
-
-Stats a filesystem - if C<< req->result >> indicates success, then you can
-access the C<struct statvfs>-like structure via C<< req->ptr2 >>:
-
- EIO_STRUCT_STATVFS *statdata = (EIO_STRUCT_STATVFS *)req->ptr2;
-
-=back
-
-=head3 READING DIRECTORIES
-
-Reading directories sounds simple, but can be rather demanding, especially
-if you want to do stuff such as traversing a directory hierarchy or
-processing all files in a directory. Libeio can assist these complex tasks
-with it's C<eio_readdir> call.
-
-=over 4
-
-=item eio_readdir (const char *path, int flags, int pri, eio_cb cb, void *data)
-
-This is a very complex call. It basically reads through a whole directory
-(via the C<opendir>, C<readdir> and C<closedir> calls) and returns either
-the names or an array of C<struct eio_dirent>, depending on the C<flags>
-argument.
-
-The C<< req->result >> indicates either the number of files found, or
-C<-1> on error. On success, null-terminated names can be found as C<< req->ptr2 >>,
-and C<struct eio_dirents>, if requested by C<flags>, can be found via C<<
-req->ptr1 >>.
-
-Here is an example that prints all the names:
-
- int i;
- char *names = (char *)req->ptr2;
-
- for (i = 0; i < req->result; ++i)
- {
- printf ("name #%d: %s\n", i, names);
-
- /* move to next name */
- names += strlen (names) + 1;
- }
-
-Pseudo-entries such as F<.> and F<..> are never returned by C<eio_readdir>.
-
-C<flags> can be any combination of:
-
-=over 4
-
-=item EIO_READDIR_DENTS
-
-If this flag is specified, then, in addition to the names in C<ptr2>,
-also an array of C<struct eio_dirent> is returned, in C<ptr1>. A C<struct
-eio_dirent> looks like this:
-
- struct eio_dirent
- {
- int nameofs; /* offset of null-terminated name string in (char *)req->ptr2 */
- unsigned short namelen; /* size of filename without trailing 0 */
- unsigned char type; /* one of EIO_DT_* */
- signed char score; /* internal use */
- ino_t inode; /* the inode number, if available, otherwise unspecified */
- };
-
-The only members you normally would access are C<nameofs>, which is the
-byte-offset from C<ptr2> to the start of the name, C<namelen> and C<type>.
-
-C<type> can be one of:
-
-C<EIO_DT_UNKNOWN> - if the type is not known (very common) and you have to C<stat>
-the name yourself if you need to know,
-one of the "standard" POSIX file types (C<EIO_DT_REG>, C<EIO_DT_DIR>, C<EIO_DT_LNK>,
-C<EIO_DT_FIFO>, C<EIO_DT_SOCK>, C<EIO_DT_CHR>, C<EIO_DT_BLK>)
-or some OS-specific type (currently
-C<EIO_DT_MPC> - multiplexed char device (v7+coherent),
-C<EIO_DT_NAM> - xenix special named file,
-C<EIO_DT_MPB> - multiplexed block device (v7+coherent),
-C<EIO_DT_NWK> - HP-UX network special,
-C<EIO_DT_CMP> - VxFS compressed,
-C<EIO_DT_DOOR> - solaris door, or
-C<EIO_DT_WHT>).
-
-This example prints all names and their type:
-
- int i;
- struct eio_dirent *ents = (struct eio_dirent *)req->ptr1;
- char *names = (char *)req->ptr2;
-
- for (i = 0; i < req->result; ++i)
- {
- struct eio_dirent *ent = ents + i;
- char *name = names + ent->nameofs;
-
- printf ("name #%d: %s (type %d)\n", i, name, ent->type);
- }
-
-=item EIO_READDIR_DIRS_FIRST
-
-When this flag is specified, then the names will be returned in an order
-where likely directories come first, in optimal C<stat> order. This is
-useful when you need to quickly find directories, or you want to find all
-directories while avoiding to stat() each entry.
-
-If the system returns type information in readdir, then this is used
-to find directories directly. Otherwise, likely directories are names
-beginning with ".", or otherwise names with no dots, of which names with
-short names are tried first.
-
-=item EIO_READDIR_STAT_ORDER
-
-When this flag is specified, then the names will be returned in an order
-suitable for stat()'ing each one. That is, when you plan to stat()
-all files in the given directory, then the returned order will likely
-be fastest.
-
-If both this flag and C<EIO_READDIR_DIRS_FIRST> are specified, then the
-likely directories come first, resulting in a less optimal stat order.
-
-=item EIO_READDIR_FOUND_UNKNOWN
-
-This flag should not be specified when calling C<eio_readdir>. Instead,
-it is being set by C<eio_readdir> (you can access the C<flags> via C<<
-req->int1 >>, when any of the C<type>'s found were C<EIO_DT_UNKNOWN>. The
-absence of this flag therefore indicates that all C<type>'s are known,
-which can be used to speed up some algorithms.
-
-A typical use case would be to identify all subdirectories within a
-directory - you would ask C<eio_readdir> for C<EIO_READDIR_DIRS_FIRST>. If
-then this flag is I<NOT> set, then all the entries at the beginning of the
-returned array of type C<EIO_DT_DIR> are the directories. Otherwise, you
-should start C<stat()>'ing the entries starting at the beginning of the
-array, stopping as soon as you found all directories (the count can be
-deduced by the link count of the directory).
-
-=back
-
-=back
-
-=head3 OS-SPECIFIC CALL WRAPPERS
-
-These wrap OS-specific calls (usually Linux ones), and might or might not
-be emulated on other operating systems. Calls that are not emulated will
-return C<-1> and set C<errno> to C<ENOSYS>.
-
-=over 4
-
-=item eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data)
-
-Wraps the C<sendfile> syscall. The arguments follow the Linux version, but
-libeio supports and will use similar calls on FreeBSD, HP/UX, Solaris and
-Darwin.
-
-If the OS doesn't support some sendfile-like call, or the call fails,
-indicating support for the given file descriptor type (for example,
-Linux's sendfile might not support file to file copies), then libeio will
-emulate the call in userspace, so there are almost no limitations on its
-use.
-
-=item eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data)
-
-Calls C<readahead(2)>. If the syscall is missing, then the call is
-emulated by simply reading the data (currently in 64kiB chunks).
-
-=item eio_syncfs (int fd, int pri, eio_cb cb, void *data)
-
-Calls Linux' C<syncfs> syscall, if available. Returns C<-1> and sets
-C<errno> to C<ENOSYS> if the call is missing I<but still calls sync()>,
-if the C<fd> is C<< >= 0 >>, so you can probe for the availability of the
-syscall with a negative C<fd> argument and checking for C<-1/ENOSYS>.
-
-=item eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data)
-
-Calls C<sync_file_range>. If the syscall is missing, then this is the same
-as calling C<fdatasync>.
-
-Flags can be any combination of C<EIO_SYNC_FILE_RANGE_WAIT_BEFORE>,
-C<EIO_SYNC_FILE_RANGE_WRITE> and C<EIO_SYNC_FILE_RANGE_WAIT_AFTER>.
-
-=item eio_fallocate (int fd, int mode, off_t offset, off_t len, int pri, eio_cb cb, void *data)
-
-Calls C<fallocate> (note: I<NOT> C<posix_fallocate>!). If the syscall is
-missing, then it returns failure and sets C<errno> to C<ENOSYS>.
-
-The C<mode> argument can be C<0> (for behaviour similar to
-C<posix_fallocate>), or C<EIO_FALLOC_FL_KEEP_SIZE>, which keeps the size
-of the file unchanged (but still preallocates space beyond end of file).
-
-=back
-
-=head3 LIBEIO-SPECIFIC REQUESTS
-
-These requests are specific to libeio and do not correspond to any OS call.
-
-=over 4
-
-=item eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
-
-Reads (C<flags == 0>) or modifies (C<flags == EIO_MT_MODIFY) the given
-memory area, page-wise, that is, it reads (or reads and writes back) the
-first octet of every page that spans the memory area.
-
-This can be used to page in some mmapped file, or dirty some pages. Note
-that dirtying is an unlocked read-write access, so races can ensue when
-the some other thread modifies the data stored in that memory area.
-
-=item eio_custom (void (*)(eio_req *) execute, int pri, eio_cb cb, void *data)
-
-Executes a custom request, i.e., a user-specified callback.
-
-The callback gets the C<eio_req *> as parameter and is expected to read
-and modify any request-specific members. Specifically, it should set C<<
-req->result >> to the result value, just like other requests.
-
-Here is an example that simply calls C<open>, like C<eio_open>, but it
-uses the C<data> member as filename and uses a hardcoded C<O_RDONLY>. If
-you want to pass more/other parameters, you either need to pass some
-struct or so via C<data> or provide your own wrapper using the low-level
-API.
-
- static int
- my_open_done (eio_req *req)
- {
- int fd = req->result;
-
- return 0;
- }
-
- static void
- my_open (eio_req *req)
- {
- req->result = open (req->data, O_RDONLY);
- }
-
- eio_custom (my_open, 0, my_open_done, "/etc/passwd");
-
-=item eio_busy (eio_tstamp delay, int pri, eio_cb cb, void *data)
-
-This is a request that takes C<delay> seconds to execute, but otherwise
-does nothing - it simply puts one of the worker threads to sleep for this
-long.
-
-This request can be used to artificially increase load, e.g. for debugging
-or benchmarking reasons.
-
-=item eio_nop (int pri, eio_cb cb, void *data)
-
-This request does nothing, except go through the whole request cycle. This
-can be used to measure latency or in some cases to simplify code, but is
-not really of much use.
-
-=back
-
-=head3 GROUPING AND LIMITING REQUESTS
-
-There is one more rather special request, C<eio_grp>. It is a very special
-aio request: Instead of doing something, it is a container for other eio
-requests.
-
-There are two primary use cases for this: a) bundle many requests into a
-single, composite, request with a definite callback and the ability to
-cancel the whole request with its subrequests and b) limiting the number
-of "active" requests.
-
-Further below you will find more discussion of these topics - first
-follows the reference section detailing the request generator and other
-methods.
-
-=over 4
-
-=item eio_req *grp = eio_grp (eio_cb cb, void *data)
-
-Creates, submits and returns a group request. Note that it doesn't have a
-priority, unlike all other requests.
-
-=item eio_grp_add (eio_req *grp, eio_req *req)
-
-Adds a request to the request group.
-
-=item eio_grp_cancel (eio_req *grp)
-
-Cancels all requests I<in> the group, but I<not> the group request
-itself. You can cancel the group request I<and> all subrequests via a
-normal C<eio_cancel> call.
-
-=back
-
-=head4 GROUP REQUEST LIFETIME
-
-Left alone, a group request will instantly move to the pending state and
-will be finished at the next call of C<eio_poll>.
-
-The usefulness stems from the fact that, if a subrequest is added to a
-group I<before> a call to C<eio_poll>, via C<eio_grp_add>, then the group
-will not finish until all the subrequests have finished.
-
-So the usage cycle of a group request is like this: after it is created,
-you normally instantly add a subrequest. If none is added, the group
-request will finish on it's own. As long as subrequests are added before
-the group request is finished it will be kept from finishing, that is the
-callbacks of any subrequests can, in turn, add more requests to the group,
-and as long as any requests are active, the group request itself will not
-finish.
-
-=head4 CREATING COMPOSITE REQUESTS
-
-Imagine you wanted to create an C<eio_load> request that opens a file,
-reads it and closes it. This means it has to execute at least three eio
-requests, but for various reasons it might be nice if that request looked
-like any other eio request.
-
-This can be done with groups:
-
-=over 4
-
-=item 1) create the request object
-
-Create a group that contains all further requests. This is the request you
-can return as "the load request".
-
-=item 2) open the file, maybe
-
-Next, open the file with C<eio_open> and add the request to the group
-request and you are finished setting up the request.
-
-If, for some reason, you cannot C<eio_open> (path is a null ptr?) you
-can set C<< grp->result >> to C<-1> to signal an error and let the group
-request finish on its own.
-
-=item 3) open callback adds more requests
-
-In the open callback, if the open was not successful, copy C<<
-req->errorno >> to C<< grp->errorno >> and set C<< grp->errorno >> to
-C<-1> to signal an error.
-
-Otherwise, malloc some memory or so and issue a read request, adding the
-read request to the group.
-
-=item 4) continue issuing requests till finished
-
-In the real callback, check for errors and possibly continue with
-C<eio_close> or any other eio request in the same way.
-
-As soon as no new requests are added the group request will finish. Make
-sure you I<always> set C<< grp->result >> to some sensible value.
-
-=back
-
-=head4 REQUEST LIMITING
-
-
-#TODO
-
-void eio_grp_limit (eio_req *grp, int limit);
-
-
-=back
-
-
-=head1 LOW LEVEL REQUEST API
-
-#TODO
-
-
-=head1 ANATOMY AND LIFETIME OF AN EIO REQUEST
-
-A request is represented by a structure of type C<eio_req>. To initialise
-it, clear it to all zero bytes:
-
- eio_req req;
-
- memset (&req, 0, sizeof (req));
-
-A more common way to initialise a new C<eio_req> is to use C<calloc>:
-
- eio_req *req = calloc (1, sizeof (*req));
-
-In either case, libeio neither allocates, initialises or frees the
-C<eio_req> structure for you - it merely uses it.
-
-zero
-
-#TODO
-
-=head2 CONFIGURATION
-
-The functions in this section can sometimes be useful, but the default
-configuration will do in most case, so you should skip this section on
-first reading.
-
-=over 4
-
-=item eio_set_max_poll_time (eio_tstamp nseconds)
-
-This causes C<eio_poll ()> to return after it has detected that it was
-running for C<nsecond> seconds or longer (this number can be fractional).
-
-This can be used to limit the amount of time spent handling eio requests,
-for example, in interactive programs, you might want to limit this time to
-C<0.01> seconds or so.
-
-Note that:
-
-=over 4
-
-=item a) libeio doesn't know how long your request callbacks take, so the
-time spent in C<eio_poll> is up to one callback invocation longer then
-this interval.
-
-=item b) this is implemented by calling C<gettimeofday> after each
-request, which can be costly.
-
-=item c) at least one request will be handled.
-
-=back
-
-=item eio_set_max_poll_reqs (unsigned int nreqs)
-
-When C<nreqs> is non-zero, then C<eio_poll> will not handle more than
-C<nreqs> requests per invocation. This is a less costly way to limit the
-amount of work done by C<eio_poll> then setting a time limit.
-
-If you know your callbacks are generally fast, you could use this to
-encourage interactiveness in your programs by setting it to C<10>, C<100>
-or even C<1000>.
-
-=item eio_set_min_parallel (unsigned int nthreads)
-
-Make sure libeio can handle at least this many requests in parallel. It
-might be able handle more.
-
-=item eio_set_max_parallel (unsigned int nthreads)
-
-Set the maximum number of threads that libeio will spawn.
-
-=item eio_set_max_idle (unsigned int nthreads)
-
-Libeio uses threads internally to handle most requests, and will start and stop threads on demand.
-
-This call can be used to limit the number of idle threads (threads without
-work to do): libeio will keep some threads idle in preparation for more
-requests, but never longer than C<nthreads> threads.
-
-In addition to this, libeio will also stop threads when they are idle for
-a few seconds, regardless of this setting.
-
-=item unsigned int eio_nthreads ()
-
-Return the number of worker threads currently running.
-
-=item unsigned int eio_nreqs ()
-
-Return the number of requests currently handled by libeio. This is the
-total number of requests that have been submitted to libeio, but not yet
-destroyed.
-
-=item unsigned int eio_nready ()
-
-Returns the number of ready requests, i.e. requests that have been
-submitted but have not yet entered the execution phase.
-
-=item unsigned int eio_npending ()
-
-Returns the number of pending requests, i.e. requests that have been
-executed and have results, but have not been finished yet by a call to
-C<eio_poll>).
-
-=back
-
-=head1 EMBEDDING
-
-Libeio can be embedded directly into programs. This functionality is not
-documented and not (yet) officially supported.
-
-Note that, when including C<libeio.m4>, you are responsible for defining
-the compilation environment (C<_LARGEFILE_SOURCE>, C<_GNU_SOURCE> etc.).
-
-If you need to know how, check the C<IO::AIO> perl module, which does
-exactly that.
-
-
-=head1 COMPILETIME CONFIGURATION
-
-These symbols, if used, must be defined when compiling F<eio.c>.
-
-=over 4
-
-=item EIO_STACKSIZE
-
-This symbol governs the stack size for each eio thread. Libeio itself
-was written to use very little stackspace, but when using C<EIO_CUSTOM>
-requests, you might want to increase this.
-
-If this symbol is undefined (the default) then libeio will use its default
-stack size (C<sizeof (void *) * 4096> currently). If it is defined, but
-C<0>, then the default operating system stack size will be used. In all
-other cases, the value must be an expression that evaluates to the desired
-stack size.
-
-=back
-
-
-=head1 PORTABILITY REQUIREMENTS
-
-In addition to a working ISO-C implementation, libeio relies on a few
-additional extensions:
-
-=over 4
-
-=item POSIX threads
-
-To be portable, this module uses threads, specifically, the POSIX threads
-library must be available (and working, which partially excludes many xBSD
-systems, where C<fork ()> is buggy).
-
-=item POSIX-compatible filesystem API
-
-This is actually a harder portability requirement: The libeio API is quite
-demanding regarding POSIX API calls (symlinks, user/group management
-etc.).
-
-=item C<double> must hold a time value in seconds with enough accuracy
-
-The type C<double> is used to represent timestamps. It is required to
-have at least 51 bits of mantissa (and 9 bits of exponent), which is good
-enough for at least into the year 4000. This requirement is fulfilled by
-implementations implementing IEEE 754 (basically all existing ones).
-
-=back
-
-If you know of other additional requirements drop me a note.
-
-
-=head1 AUTHOR
-
-Marc Lehmann <libeio@schmorp.de>.
-
diff --git a/deps/uv/src/unix/eio/libeio.m4 b/deps/uv/src/unix/eio/libeio.m4
deleted file mode 100644
index 59151f534..000000000
--- a/deps/uv/src/unix/eio/libeio.m4
+++ /dev/null
@@ -1,195 +0,0 @@
-dnl openbsd in it's neverending brokenness requires stdint.h for intptr_t,
-dnl but that header isn't very portable...
-AC_CHECK_HEADERS([stdint.h sys/syscall.h sys/prctl.h])
-
-AC_SEARCH_LIBS(
- pthread_create,
- [pthread pthreads pthreadVC2],
- ,
- [AC_MSG_ERROR(pthread functions not found)]
-)
-
-AC_CACHE_CHECK(for utimes, ac_cv_utimes, [AC_LINK_IFELSE([[
-#include <sys/types.h>
-#include <sys/time.h>
-#include <utime.h>
-struct timeval tv[2];
-int res;
-int main (void)
-{
- res = utimes ("/", tv);
- return 0;
-}
-]],ac_cv_utimes=yes,ac_cv_utimes=no)])
-test $ac_cv_utimes = yes && AC_DEFINE(HAVE_UTIMES, 1, utimes(2) is available)
-
-AC_CACHE_CHECK(for futimes, ac_cv_futimes, [AC_LINK_IFELSE([[
-#include <sys/types.h>
-#include <sys/time.h>
-#include <utime.h>
-struct timeval tv[2];
-int res;
-int fd;
-int main (void)
-{
- res = futimes (fd, tv);
- return 0;
-}
-]],ac_cv_futimes=yes,ac_cv_futimes=no)])
-test $ac_cv_futimes = yes && AC_DEFINE(HAVE_FUTIMES, 1, futimes(2) is available)
-
-AC_CACHE_CHECK(for readahead, ac_cv_readahead, [AC_LINK_IFELSE([
-#include <fcntl.h>
-int main (void)
-{
- int fd = 0;
- size_t count = 2;
- ssize_t res;
- res = readahead (fd, 0, count);
- return 0;
-}
-],ac_cv_readahead=yes,ac_cv_readahead=no)])
-test $ac_cv_readahead = yes && AC_DEFINE(HAVE_READAHEAD, 1, readahead(2) is available (linux))
-
-AC_CACHE_CHECK(for fdatasync, ac_cv_fdatasync, [AC_LINK_IFELSE([
-#include <unistd.h>
-int main (void)
-{
- int fd = 0;
- fdatasync (fd);
- return 0;
-}
-],ac_cv_fdatasync=yes,ac_cv_fdatasync=no)])
-test $ac_cv_fdatasync = yes && AC_DEFINE(HAVE_FDATASYNC, 1, fdatasync(2) is available)
-
-AC_CACHE_CHECK(for pread and pwrite, ac_cv_preadwrite, [AC_LINK_IFELSE([
-#include <unistd.h>
-int main (void)
-{
- int fd = 0;
- size_t count = 1;
- char buf;
- off_t offset = 1;
- ssize_t res;
- res = pread (fd, &buf, count, offset);
- res = pwrite (fd, &buf, count, offset);
- return 0;
-}
-],ac_cv_preadwrite=yes,ac_cv_preadwrite=no)])
-test $ac_cv_preadwrite = yes && AC_DEFINE(HAVE_PREADWRITE, 1, pread(2) and pwrite(2) are available)
-
-AC_CACHE_CHECK(for sendfile, ac_cv_sendfile, [AC_LINK_IFELSE([
-# include <sys/types.h>
-#if __linux
-# include <sys/sendfile.h>
-#elif __FreeBSD__ || defined __APPLE__
-# include <sys/socket.h>
-# include <sys/uio.h>
-#elif __hpux
-# include <sys/socket.h>
-#else
-# error unsupported architecture
-#endif
-int main (void)
-{
- int fd = 0;
- off_t offset = 1;
- size_t count = 2;
- ssize_t res;
-#if __linux
- res = sendfile (fd, fd, offset, count);
-#elif __FreeBSD__
- res = sendfile (fd, fd, offset, count, 0, &offset, 0);
-#elif __hpux
- res = sendfile (fd, fd, offset, count, 0, 0);
-#endif
- return 0;
-}
-],ac_cv_sendfile=yes,ac_cv_sendfile=no)])
-test $ac_cv_sendfile = yes && AC_DEFINE(HAVE_SENDFILE, 1, sendfile(2) is available and supported)
-
-AC_CACHE_CHECK(for sync_file_range, ac_cv_sync_file_range, [AC_LINK_IFELSE([
-#include <fcntl.h>
-int main (void)
-{
- int fd = 0;
- off64_t offset = 1;
- off64_t nbytes = 1;
- unsigned int flags = SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER;
- ssize_t res;
- res = sync_file_range (fd, offset, nbytes, flags);
- return 0;
-}
-],ac_cv_sync_file_range=yes,ac_cv_sync_file_range=no)])
-test $ac_cv_sync_file_range = yes && AC_DEFINE(HAVE_SYNC_FILE_RANGE, 1, sync_file_range(2) is available)
-
-AC_CACHE_CHECK(for fallocate, ac_cv_fallocate, [AC_LINK_IFELSE([
-#include <fcntl.h>
-int main (void)
-{
- int fd = 0;
- int mode = 0;
- off_t offset = 1;
- off_t len = 1;
- int res;
- res = fallocate (fd, mode, offset, len);
- return 0;
-}
-],ac_cv_fallocate=yes,ac_cv_fallocate=no)])
-test $ac_cv_fallocate = yes && AC_DEFINE(HAVE_FALLOCATE, 1, fallocate(2) is available)
-
-AC_CACHE_CHECK(for sys_syncfs, ac_cv_sys_syncfs, [AC_LINK_IFELSE([
-#include <unistd.h>
-#include <sys/syscall.h>
-int main (void)
-{
- int res = syscall (__NR_syncfs, (int)0);
-}
-],ac_cv_sys_syncfs=yes,ac_cv_sys_syncfs=no)])
-test $ac_cv_sys_syncfs = yes && AC_DEFINE(HAVE_SYS_SYNCFS, 1, syscall(__NR_syncfs) is available)
-
-AC_CACHE_CHECK(for prctl_set_name, ac_cv_prctl_set_name, [AC_LINK_IFELSE([
-#include <sys/prctl.h>
-int main (void)
-{
- char name[] = "test123";
- int res = prctl (PR_SET_NAME, (unsigned long)name, 0, 0, 0);
-}
-],ac_cv_prctl_set_name=yes,ac_cv_prctl_set_name=no)])
-test $ac_cv_prctl_set_name = yes && AC_DEFINE(HAVE_PRCTL_SET_NAME, 1, prctl(PR_SET_NAME) is available)
-
-dnl #############################################################################
-dnl # these checks exist for the benefit of IO::AIO
-
-dnl at least uclibc defines _POSIX_ADVISORY_INFO without *any* of the required
-dnl functionality actually being present. ugh.
-AC_CACHE_CHECK(for posix_madvise, ac_cv_posix_madvise, [AC_LINK_IFELSE([
-#include <sys/mman.h>
-int main (void)
-{
- int res = posix_madvise ((void *)0, (size_t)0, POSIX_MADV_NORMAL);
- int a = POSIX_MADV_SEQUENTIAL;
- int b = POSIX_MADV_RANDOM;
- int c = POSIX_MADV_WILLNEED;
- int d = POSIX_MADV_DONTNEED;
- return 0;
-}
-],ac_cv_posix_madvise=yes,ac_cv_posix_madvise=no)])
-test $ac_cv_posix_madvise = yes && AC_DEFINE(HAVE_POSIX_MADVISE, 1, posix_madvise(2) is available)
-
-AC_CACHE_CHECK(for posix_fadvise, ac_cv_posix_fadvise, [AC_LINK_IFELSE([
-#define _XOPEN_SOURCE 600
-#include <fcntl.h>
-int main (void)
-{
- int res = posix_fadvise ((int)0, (off_t)0, (off_t)0, POSIX_FADV_NORMAL);
- int a = POSIX_FADV_SEQUENTIAL;
- int b = POSIX_FADV_NOREUSE;
- int c = POSIX_FADV_RANDOM;
- int d = POSIX_FADV_WILLNEED;
- int e = POSIX_FADV_DONTNEED;
- return 0;
-}
-],ac_cv_posix_fadvise=yes,ac_cv_posix_fadvise=no)])
-test $ac_cv_posix_fadvise = yes && AC_DEFINE(HAVE_POSIX_FADVISE, 1, posix_fadvise(2) is available)
-
diff --git a/deps/uv/src/unix/eio/xthread.h b/deps/uv/src/unix/eio/xthread.h
deleted file mode 100644
index 7184c7bb7..000000000
--- a/deps/uv/src/unix/eio/xthread.h
+++ /dev/null
@@ -1,164 +0,0 @@
-#ifndef XTHREAD_H_
-#define XTHREAD_H_
-
-/* whether word reads are potentially non-atomic.
- * this is conservative, likely most arches this runs
- * on have atomic word read/writes.
- */
-#ifndef WORDACCESS_UNSAFE
-# if __i386 || __x86_64
-# define WORDACCESS_UNSAFE 0
-# else
-# define WORDACCESS_UNSAFE 1
-# endif
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-
-#ifdef _WIN32
-
-#include <stdio.h>//D
-#include <fcntl.h>
-#include <io.h>
-#include <time.h>
-#include <winsock2.h>
-#include <process.h>
-#include <windows.h>
-#include <pthread.h>
-#define sigset_t int
-#define sigfillset(a)
-#define pthread_sigmask(a,b,c)
-#define sigaddset(a,b)
-#define sigemptyset(s)
-
-typedef pthread_mutex_t xmutex_t;
-#define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
-#define X_MUTEX_CREATE(mutex) pthread_mutex_init (&(mutex), 0)
-#define X_LOCK(mutex) pthread_mutex_lock (&(mutex))
-#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
-
-typedef pthread_cond_t xcond_t;
-#define X_COND_INIT PTHREAD_COND_INITIALIZER
-#define X_COND_CREATE(cond) pthread_cond_init (&(cond), 0)
-#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond))
-#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex))
-#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to))
-
-typedef pthread_t xthread_t;
-#define X_THREAD_PROC(name) void *name (void *thr_arg)
-#define X_THREAD_ATFORK(a,b,c)
-
-static int
-thread_create (xthread_t *tid, void *(*proc)(void *), void *arg)
-{
- int retval;
- pthread_attr_t attr;
-
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
-
- retval = pthread_create (tid, &attr, proc, arg) == 0;
-
- pthread_attr_destroy (&attr);
-
- return retval;
-}
-
-#define respipe_read(a,b,c) PerlSock_recv ((a), (b), (c), 0)
-#define respipe_write(a,b,c) send ((a), (b), (c), 0)
-#define respipe_close(a) PerlSock_closesocket ((a))
-
-#else
-/////////////////////////////////////////////////////////////////////////////
-
-#if __linux && !defined(_GNU_SOURCE)
-# define _GNU_SOURCE
-#endif
-
-/* just in case */
-#define _REENTRANT 1
-
-#if __solaris
-# define _POSIX_PTHREAD_SEMANTICS 1
-/* try to bribe solaris headers into providing a current pthread API
- * despite environment being configured for an older version.
- */
-# define __EXTENSIONS__ 1
-#endif
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <limits.h>
-#include <pthread.h>
-
-typedef pthread_mutex_t xmutex_t;
-#if __linux && defined (PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP)
-# define X_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
-# define X_MUTEX_CREATE(mutex) \
- do { \
- pthread_mutexattr_t attr; \
- pthread_mutexattr_init (&attr); \
- pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP); \
- pthread_mutex_init (&(mutex), &attr); \
- } while (0)
-#else
-# define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
-# define X_MUTEX_CREATE(mutex) pthread_mutex_init (&(mutex), 0)
-#endif
-#define X_LOCK(mutex) pthread_mutex_lock (&(mutex))
-#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
-
-typedef pthread_cond_t xcond_t;
-#define X_COND_INIT PTHREAD_COND_INITIALIZER
-#define X_COND_CREATE(cond) pthread_cond_init (&(cond), 0)
-#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond))
-#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex))
-#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to))
-
-typedef pthread_t xthread_t;
-#define X_THREAD_PROC(name) static void *name (void *thr_arg)
-#define X_THREAD_ATFORK(prepare,parent,child) pthread_atfork (prepare, parent, child)
-
-// the broken bsd's once more
-#ifndef PTHREAD_STACK_MIN
-# define PTHREAD_STACK_MIN 0
-#endif
-
-#ifndef XTHREAD_STACKSIZE
-# define XTHREAD_STACKSIZE sizeof (void *) * 4096
-#endif
-
-static int
-thread_create (xthread_t *tid, void *(*proc)(void *), void *arg)
-{
- int retval;
- sigset_t fullsigset, oldsigset;
- pthread_attr_t attr;
-
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN < X_STACKSIZE ? X_STACKSIZE : PTHREAD_STACK_MIN);
-#ifdef PTHREAD_SCOPE_PROCESS
- pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS);
-#endif
-
- sigfillset (&fullsigset);
-
- pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset);
- retval = pthread_create (tid, &attr, proc, arg) == 0;
- pthread_sigmask (SIG_SETMASK, &oldsigset, 0);
-
- pthread_attr_destroy (&attr);
-
- return retval;
-}
-
-#define respipe_read(a,b,c) read ((a), (b), (c))
-#define respipe_write(a,b,c) write ((a), (b), (c))
-#define respipe_close(a) close ((a))
-
-#endif
-
-#endif
-
diff --git a/deps/uv/src/unix/error.c b/deps/uv/src/unix/error.c
index e5ef3a011..9e3e84ad9 100644
--- a/deps/uv/src/unix/error.c
+++ b/deps/uv/src/unix/error.c
@@ -96,7 +96,9 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ETIMEDOUT: return UV_ETIMEDOUT;
case EXDEV: return UV_EXDEV;
case EBUSY: return UV_EBUSY;
+#if ENOTEMPTY != EEXIST
case ENOTEMPTY: return UV_ENOTEMPTY;
+#endif
case ENOSPC: return UV_ENOSPC;
case EROFS: return UV_EROFS;
case ENOMEM: return UV_ENOMEM;
diff --git a/deps/uv/src/unix/ev/Changes b/deps/uv/src/unix/ev/Changes
deleted file mode 100644
index d6fca2f67..000000000
--- a/deps/uv/src/unix/ev/Changes
+++ /dev/null
@@ -1,388 +0,0 @@
-Revision history for libev, a high-performance and full-featured event loop.
-
-4.04 Wed Feb 16 09:01:51 CET 2011
- - fix two problems in the native win32 backend, where reuse of fd's
- with different underlying handles caused handles not to be removed
- or added to the select set (analyzed and tested by Bert Belder).
- - do no rely on ceil() in ev_e?poll.c.
- - backport libev to HP-UX versions before 11 v3.
- - configure did not detect nanosleep and clock_gettime properly when
- they are available in the libc (as opposed to -lrt).
-
-4.03 Tue Jan 11 14:37:25 CET 2011
- - officially support polling files with all backends.
- - support files, /dev/zero etc. the same way as select in the epoll
- backend, by generating events on our own.
- - ports backend: work around solaris bug 6874410 and many related ones
- (EINTR, maybe more), with no performance loss (note that the solaris
- bug report is actually wrong, reality is far more bizarre and broken
- than that).
- - define EV_READ/EV_WRITE as macros in event.h, as some programs use
- #ifdef to test for them.
- - new (experimental) function: ev_feed_signal.
- - new (to become default) EVFLAG_NOSIGMASK flag.
- - new EVBACKEND_MASK symbol.
- - updated COMMON IDIOMS SECTION.
-
-4.01 Fri Nov 5 21:51:29 CET 2010
- - automake fucked it up, apparently, --add-missing -f is not quite enough
- to make it update its files, so 4.00 didn't install ev++.h and
- event.h on make install. grrr.
- - ev_loop(count|depth) didn't return anything (Robin Haberkorn).
- - change EV_UNDEF to 0xffffffff to silence some overzealous compilers.
- - use "(libev) " prefix for all libev error messages now.
-
-4.00 Mon Oct 25 12:32:12 CEST 2010
- - "PORTING FROM LIBEV 3.X TO 4.X" (in ev.pod) is recommended reading.
- - ev_embed_stop did not correctly stop the watcher (very good
- testcase by Vladimir Timofeev).
- - ev_run will now always update the current loop time - it erroneously
- didn't when idle watchers were active, causing timers not to fire.
- - fix a bug where a timeout of zero caused the timer not to fire
- in the libevent emulation (testcase by Péter Szabó).
- - applied win32 fixes by Michael Lenaghan (also James Mansion).
- - replace EV_MINIMAL by EV_FEATURES.
- - prefer EPOLL_CTL_ADD over EPOLL_CTL_MOD in some more cases, as it
- seems the former is *much* faster than the latter.
- - linux kernel version detection (for inotify bug workarounds)
- did not work properly.
- - reduce the number of spurious wake-ups with the ports backend.
- - remove dependency on sys/queue.h on freebsd (patch by Vanilla Hsu).
- - do async init within ev_async_start, not ev_async_set, which avoids
- an API quirk where the set function must be called in the C++ API
- even when there is nothing to set.
- - add (undocumented) EV_ENABLE when adding events with kqueue,
- this might help with OS X, which seems to need it despite documenting
- not to need it (helpfully pointed out by Tilghman Lesher).
- - do not use poll by default on freebsd, it's broken (what isn't
- on freebsd...).
- - allow to embed epoll on kernels >= 2.6.32.
- - configure now prepends -O3, not appends it, so one can still
- override it.
- - ev.pod: greatly expanded the portability section, added a porting
- section, a description of watcher states and made lots of minor fixes.
- - disable poll backend on AIX, the poll header spams the namespace
- and it's not worth working around dead platforms (reported
- and analyzed by Aivars Kalvans).
- - improve header file compatibility of the standalone eventfd code
- in an obscure case.
- - implement EV_AVOID_STDIO option.
- - do not use sscanf to parse linux version number (smaller, faster,
- no sscanf dependency).
- - new EV_CHILD_ENABLE and EV_SIGNAL_ENABLE configurable settings.
- - update libev.m4 HAVE_CLOCK_SYSCALL test for newer glibcs.
- - add section on accept() problems to the manpage.
- - rename EV_TIMEOUT to EV_TIMER.
- - rename ev_loop_count/depth/verify/loop/unloop.
- - remove ev_default_destroy and ev_default_fork.
- - switch to two-digit minor version.
- - work around an apparent gentoo compiler bug.
- - define _DARWIN_UNLIMITED_SELECT. just so.
- - use enum instead of #define for most constants.
- - improve compatibility to older C++ compilers.
- - (experimental) ev_run/ev_default_loop/ev_break/ev_loop_new have now
- default arguments when compiled as C++.
- - enable automake dependency tracking.
- - ev_loop_new no longer leaks memory when loop creation failed.
- - new ev_cleanup watcher type.
-
-3.9 Thu Dec 31 07:59:59 CET 2009
- - signalfd is no longer used by default and has to be requested
- explicitly - this means that easy to catch bugs become hard to
- catch race conditions, but the users have spoken.
- - point out the unspecified signal mask in the documentation, and
- that this is a race condition regardless of EV_SIGNALFD.
- - backport inotify code to C89.
- - inotify file descriptors could leak into child processes.
- - ev_stat watchers could keep an errornous extra ref on the loop,
- preventing exit when unregistering all watchers (testcases
- provided by ry@tinyclouds.org).
- - implement EV_WIN32_HANDLE_TO_FD and EV_WIN32_CLOSE_FD configuration
- symbols to make it easier for apps to do their own fd management.
- - support EV_IDLE_ENABLE being disabled in ev++.h
- (patch by Didier Spezia).
- - take advantage of inotify_init1, if available, to set cloexec/nonblock
- on fd creation, to avoid races.
- - the signal handling pipe wasn't always initialised under windows
- (analysed by lekma).
- - changed minimum glibc requirement from glibc 2.9 to 2.7, for
- signalfd.
- - add missing string.h include (Denis F. Latypoff).
- - only replace ev_stat.prev when we detect an actual difference,
- so prev is (almost) always different to attr. this might
- have caused the problems with 04_stat.t.
- - add ev::timer->remaining () method to C++ API.
-
-3.8 Sun Aug 9 14:30:45 CEST 2009
- - incompatible change: do not necessarily reset signal handler
- to SIG_DFL when a sighandler is stopped.
- - ev_default_destroy did not properly free or zero some members,
- potentially causing crashes and memory corruption on repeated
- ev_default_destroy/ev_default_loop calls.
- - take advantage of signalfd on GNU/Linux systems.
- - document that the signal mask might be in an unspecified
- state when using libev's signal handling.
- - take advantage of some GNU/Linux calls to set cloexec/nonblock
- on fd creation, to avoid race conditions.
-
-3.7 Fri Jul 17 16:36:32 CEST 2009
- - ev_unloop and ev_loop wrongly used a global variable to exit loops,
- instead of using a per-loop variable (bug caught by accident...).
- - the ev_set_io_collect_interval interpretation has changed.
- - add new functionality: ev_set_userdata, ev_userdata,
- ev_set_invoke_pending_cb, ev_set_loop_release_cb,
- ev_invoke_pending, ev_pending_count, together with a long example
- about thread locking.
- - add ev_timer_remaining (as requested by Denis F. Latypoff).
- - add ev_loop_depth.
- - calling ev_unloop in fork/prepare watchers will no longer poll
- for new events.
- - Denis F. Latypoff corrected many typos in example code snippets.
- - honor autoconf detection of EV_USE_CLOCK_SYSCALL, also double-
- check that the syscall number is available before trying to
- use it (reported by ry@tinyclouds).
- - use GetSystemTimeAsFileTime instead of _timeb on windows, for
- slightly higher accuracy.
- - properly declare ev_loop_verify and ev_now_update even when
- !EV_MULTIPLICITY.
- - do not compile in any priority code when EV_MAXPRI == EV_MINPRI.
- - support EV_MINIMAL==2 for a reduced API.
- - actually 0-initialise struct sigaction when installing signals.
- - add section on hibernate and stopped processes to ev_timer docs.
-
-3.6 Tue Apr 28 02:49:30 CEST 2009
- - multiple timers becoming ready within an event loop iteration
- will be invoked in the "correct" order now.
- - do not leave the event loop early just because we have no active
- watchers, fixing a problem when embedding a kqueue loop
- that has active kernel events but no registered watchers
- (reported by blacksand blacksand).
- - correctly zero the idx values for arrays, so destroying and
- reinitialising the default loop actually works (patch by
- Malek Hadj-Ali).
- - implement ev_suspend and ev_resume.
- - new EV_CUSTOM revents flag for use by applications.
- - add documentation section about priorites.
- - add a glossary to the dcoumentation.
- - extend the ev_fork description slightly.
- - optimize a jump out of call_pending.
-
-3.53 Sun Feb 15 02:38:20 CET 2009
- - fix a bug in event pipe creation on win32 that would cause a
- failed assertion on event loop creation (patch by Malek Hadj-Ali).
- - probe for CLOCK_REALTIME support at runtime as well and fall
- back to gettimeofday if there is an error, to support older
- operating systems with newer header files/libraries.
- - prefer gettimeofday over clock_gettime with USE_CLOCK_SYSCALL
- (default most everywhere), otherwise not.
-
-3.52 Wed Jan 7 21:43:02 CET 2009
- - fix compilation of select backend in fd_set mode when NFDBITS is
- missing (to get it to compile on QNX, reported by Rodrigo Campos).
- - better select-nfds handling when select backend is in fd_set mode.
- - diagnose fd_set overruns when select backend is in fd_set mode.
- - due to a thinko, instead of disabling everything but
- select on the borked OS X platform, everything but select was
- allowed (reported by Emanuele Giaquinta).
- - actually verify that local and remote port are matching in
- libev's socketpair emulation, which makes denial-of-service
- attacks harder (but not impossible - it's windows). Make sure
- it even works under vista, which thinks that getpeer/sockname
- should return fantasy port numbers.
- - include "libev" in all assertion messages for potentially
- clearer diagnostics.
- - event_get_version (libevent compatibility) returned
- a useless string instead of the expected version string
- (patch by W.C.A. Wijngaards).
-
-3.51 Wed Dec 24 23:00:11 CET 2008
- - fix a bug where an inotify watcher was added twice, causing
- freezes on hash collisions (reported and analysed by Graham Leggett).
- - new config symbol, EV_USE_CLOCK_SYSCALL, to make libev use
- a direct syscall - slower, but no dependency on librt et al.
- - assume negative return values != -1 signals success of port_getn
- (http://cvs.epicsol.org/cgi/viewcvs.cgi/epic5/source/newio.c?rev=1.52)
- (no known failure reports, but it doesn't hurt).
- - fork detection in ev_embed now stops and restarts the watcher
- automatically.
- - EXPERIMENTAL: default the method to operator () in ev++.h,
- to make it nicer to use functors (requested by Benedek László).
- - fixed const object callbacks in ev++.h.
- - replaced loop_ref argument of watcher.set (loop) by a direct
- ev_loop * in ev++.h, to avoid clashes with functor patch.
- - do not try to watch the empty string via inotify.
- - inotify watchers could be leaked under certain circumstances.
- - OS X 10.5 is actually even more broken than earlier versions,
- so fall back to select on that piece of garbage.
- - fixed some weirdness in the ev_embed documentation.
-
-3.49 Wed Nov 19 11:26:53 CET 2008
- - ev_stat watchers will now use inotify as a mere hint on
- kernels <2.6.25, or if the filesystem is not in the
- "known to be good" list.
- - better mingw32 compatibility (it's not as borked as native win32)
- (analysed by Roger Pack).
- - include stdio.h in the example program, as too many people are
- confused by the weird C language otherwise. I guess the next thing
- I get told is that the "..." ellipses in the examples don't compile
- with their C compiler.
-
-3.48 Thu Oct 30 09:02:37 CET 2008
- - further optimise away the EPOLL_CTL_ADD/MOD combo in the epoll
- backend by assuming the kernel event mask hasn't changed if
- ADD fails with EEXIST.
- - work around spurious event notification bugs in epoll by using
- a 32-bit generation counter. recreate kernel state if we receive
- spurious notifications or unwanted events. this is very costly,
- but I didn't come up with this horrible design.
- - use memset to initialise most arrays now and do away with the
- init functions.
- - expand time-out strategies into a "Be smart about timeouts" section.
- - drop the "struct" from all ev_watcher declarations in the
- documentation and did other clarifications (yeah, it was a mistake
- to have a struct AND a function called ev_loop).
- - fix a bug where ev_default would not initialise the default
- loop again after it was destroyed with ev_default_destroy.
- - rename syserr to ev_syserr to avoid name clashes when embedding,
- do similar changes for event.c.
-
-3.45 Tue Oct 21 21:59:26 CEST 2008
- - disable inotify usage on linux <2.6.25, as it is broken
- (reported by Yoann Vandoorselaere).
- - ev_stat erroneously would try to add inotify watchers
- even when inotify wasn't available (this should only
- have a performance impact).
- - ev_once now passes both timeout and io to the callback if both
- occur concurrently, instead of giving timeouts precedence.
- - disable EV_USE_INOTIFY when sys/inotify.h is too old.
-
-3.44 Mon Sep 29 05:18:39 CEST 2008
- - embed watchers now automatically invoke ev_loop_fork on the
- embedded loop when the parent loop forks.
- - new function: ev_now_update (loop).
- - verify_watcher was not marked static.
- - improve the "associating..." manpage section.
- - documentation tweaks here and there.
-
-3.43 Sun Jul 6 05:34:41 CEST 2008
- - include more include files on windows to get struct _stati64
- (reported by Chris Hulbert, but doesn't quite fix his issue).
- - add missing #include <io.h> in ev.c on windows (reported by
- Matt Tolton).
-
-3.42 Tue Jun 17 12:12:07 CEST 2008
- - work around yet another windows bug: FD_SET actually adds fd's
- multiple times to the fd_*SET*, despite official MSN docs claiming
- otherwise. Reported and well-analysed by Matt Tolton.
- - define NFDBITS to 0 when EV_SELECT_IS_WINSOCKET to make it compile
- (reported any analysed by Chris Hulbert).
- - fix a bug in ev_ebadf (this function is only used to catch
- programming errors in the libev user). reported by Matt Tolton.
- - fix a bug in fd_intern on win32 (could lead to compile errors
- under some circumstances, but would work correctly if it compiles).
- reported by Matt Tolton.
- - (try to) work around missing lstat on windows.
- - pass in the write fd set as except fd set under windows. windows
- is so uncontrollably lame that it requires this. this means that
- switching off oobinline is not supported (but tcp/ip doesn't
- have oob, so that would be stupid anyways.
- - use posix module symbol to auto-detect monotonic clock presence
- and some other default values.
-
-3.41 Fri May 23 18:42:54 CEST 2008
- - work around an obscure bug in winsocket select: if you
- provide only empty fd sets then select returns WSAEINVAL. how sucky.
- - improve timer scheduling stability and reduce use of time_epsilon.
- - use 1-based 2-heap for EV_MINIMAL, simplifies code, reduces
- codesize and makes for better cache-efficiency.
- - use 3-based 4-heap for !EV_MINIMAL. this makes better use
- of cpu cache lines and gives better growth behaviour than
- 2-based heaps.
- - cache timestamp within heap for !EV_MINIMAL, to avoid random
- memory accesses.
- - document/add EV_USE_4HEAP and EV_HEAP_CACHE_AT.
- - fix a potential aliasing issue in ev_timer_again.
- - add/document ev_periodic_at, retract direct access to ->at.
- - improve ev_stat docs.
- - add portability requirements section.
- - fix manpage headers etc.
- - normalise WSA error codes to lower range on windows.
- - add consistency check code that can be called automatically
- or on demand to check for internal structures (ev_loop_verify).
-
-3.31 Wed Apr 16 20:45:04 CEST 2008
- - added last minute fix for ev_poll.c by Brandon Black.
-
-3.3 Wed Apr 16 19:04:10 CEST 2008
- - event_base_loopexit should return 0 on success
- (W.C.A. Wijngaards).
- - added linux eventfd support.
- - try to autodetect epoll and inotify support
- by libc header version if not using autoconf.
- - new symbols: EV_DEFAULT_UC and EV_DEFAULT_UC_.
- - declare functions defined in ev.h as inline if
- C99 or gcc are available.
- - enable inlining with gcc versions 2 and 3.
- - work around broken poll implementations potentially
- not clearing revents field in ev_poll (Brandon Black)
- (no such systems are known at this time).
- - work around a bug in realloc on openbsd and darwin,
- also makes the erroneous valgrind complaints
- go away (noted by various people).
- - fix ev_async_pending, add c++ wrapper for ev_async
- (based on patch sent by Johannes Deisenhofer).
- - add sensible set method to ev::embed.
- - made integer constants type int in ev.h.
-
-3.2 Wed Apr 2 17:11:19 CEST 2008
- - fix a 64 bit overflow issue in the select backend,
- by using fd_mask instead of int for the mask.
- - rename internal sighandler to avoid clash with very old perls.
- - entering ev_loop will not clear the ONESHOT or NONBLOCKING
- flags of any outer loops anymore.
- - add ev_async_pending.
-
-3.1 Thu Mar 13 13:45:22 CET 2008
- - implement ev_async watchers.
- - only initialise signal pipe on demand.
- - make use of sig_atomic_t configurable.
- - improved documentation.
-
-3.0 Mon Jan 28 13:14:47 CET 2008
- - API/ABI bump to version 3.0.
- - ev++.h includes "ev.h" by default now, not <ev.h>.
- - slightly improved documentation.
- - speed up signal detection after a fork.
- - only optionally return trace status changed in ev_child
- watchers.
- - experimental (and undocumented) loop wrappers for ev++.h.
-
-2.01 Tue Dec 25 08:04:41 CET 2007
- - separate Changes file.
- - fix ev_path_set => ev_stat_set typo.
- - remove event_compat.h from the libev tarball.
- - change how include files are found.
- - doc updates.
- - update licenses, explicitly allow for GPL relicensing.
-
-2.0 Sat Dec 22 17:47:03 CET 2007
- - new ev_sleep, ev_set_(io|timeout)_collect_interval.
- - removed epoll from embeddable fd set.
- - fix embed watchers.
- - renamed ev_embed.loop to other.
- - added exported Symbol tables.
- - undefine member wrapper macros at the end of ev.c.
- - respect EV_H in ev++.h.
-
-1.86 Tue Dec 18 02:36:57 CET 2007
- - fix memleak on loop destroy (not relevant for perl).
-
-1.85 Fri Dec 14 20:32:40 CET 2007
- - fix some aliasing issues w.r.t. timers and periodics
- (not relevant for perl).
-
-(for historic versions refer to EV/Changes, found in the Perl interface)
-
-0.1 Wed Oct 31 21:31:48 CET 2007
- - original version; hacked together in <24h.
-
diff --git a/deps/uv/src/unix/ev/LICENSE b/deps/uv/src/unix/ev/LICENSE
deleted file mode 100644
index 7fa0e9f84..000000000
--- a/deps/uv/src/unix/ev/LICENSE
+++ /dev/null
@@ -1,36 +0,0 @@
-All files in libev are Copyright (C)2007,2008,2009 Marc Alexander Lehmann.
-
-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.
-
-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.
-
-Alternatively, the contents of this package may be used under the terms
-of the GNU General Public License ("GPL") version 2 or any later version,
-in which case the provisions of the GPL are applicable instead of the
-above. If you wish to allow the use of your version of this package only
-under the terms of the GPL and not to allow others to use your version of
-this file under the BSD license, indicate your decision by deleting the
-provisions above and replace them with the notice and other provisions
-required by the GPL in this and the other files of this package. If you do
-not delete the provisions above, a recipient may use your version of this
-file under either the BSD or the GPL.
diff --git a/deps/uv/src/unix/ev/Makefile.am b/deps/uv/src/unix/ev/Makefile.am
deleted file mode 100644
index 058c2cb0c..000000000
--- a/deps/uv/src/unix/ev/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-AUTOMAKE_OPTIONS = foreign
-
-VERSION_INFO = 4:0:0
-
-EXTRA_DIST = LICENSE Changes libev.m4 autogen.sh \
- ev_vars.h ev_wrap.h \
- ev_epoll.c ev_select.c ev_poll.c ev_kqueue.c ev_port.c ev_win32.c \
- ev.3 ev.pod
-
-man_MANS = ev.3
-
-include_HEADERS = ev.h ev++.h event.h
-
-lib_LTLIBRARIES = libev.la
-
-libev_la_SOURCES = ev.c event.c
-libev_la_LDFLAGS = -version-info $(VERSION_INFO)
-
diff --git a/deps/uv/src/unix/ev/Makefile.in b/deps/uv/src/unix/ev/Makefile.in
deleted file mode 100644
index 9817a7ebd..000000000
--- a/deps/uv/src/unix/ev/Makefile.in
+++ /dev/null
@@ -1,771 +0,0 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = .
-DIST_COMMON = README $(am__configure_deps) $(include_HEADERS) \
- $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
- $(srcdir)/config.h.in $(top_srcdir)/configure config.guess \
- config.sub depcomp install-sh ltmain.sh missing mkinstalldirs
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/libev.m4 \
- $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
- configure.lineno config.status.lineno
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" \
- "$(DESTDIR)$(includedir)"
-LTLIBRARIES = $(lib_LTLIBRARIES)
-libev_la_LIBADD =
-am_libev_la_OBJECTS = ev.lo event.lo
-libev_la_OBJECTS = $(am_libev_la_OBJECTS)
-libev_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(libev_la_LDFLAGS) \
- $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I.@am__isrc@
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-SOURCES = $(libev_la_SOURCES)
-DIST_SOURCES = $(libev_la_SOURCES)
-man3dir = $(mandir)/man3
-NROFF = nroff
-MANS = $(man_MANS)
-HEADERS = $(include_HEADERS)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-distdir = $(PACKAGE)-$(VERSION)
-top_distdir = $(distdir)
-am__remove_distdir = \
- { test ! -d "$(distdir)" \
- || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
- && rm -fr "$(distdir)"; }; }
-DIST_ARCHIVES = $(distdir).tar.gz
-GZIP_ENV = --best
-distuninstallcheck_listfiles = find . -type f -print
-distcleancheck_listfiles = find . -type f -print
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-AUTOMAKE_OPTIONS = foreign
-VERSION_INFO = 4:0:0
-EXTRA_DIST = LICENSE Changes libev.m4 autogen.sh \
- ev_vars.h ev_wrap.h \
- ev_epoll.c ev_select.c ev_poll.c ev_kqueue.c ev_port.c ev_win32.c \
- ev.3 ev.pod
-
-man_MANS = ev.3
-include_HEADERS = ev.h ev++.h event.h
-lib_LTLIBRARIES = libev.la
-libev_la_SOURCES = ev.c event.c
-libev_la_LDFLAGS = -version-info $(VERSION_INFO)
-all: config.h
- $(MAKE) $(AM_MAKEFLAGS) all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-am--refresh:
- @:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
- $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- echo ' $(SHELL) ./config.status'; \
- $(SHELL) ./config.status;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- $(SHELL) ./config.status --recheck
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- $(am__cd) $(srcdir) && $(AUTOCONF)
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
-$(am__aclocal_m4_deps):
-
-config.h: stamp-h1
- @if test ! -f $@; then \
- rm -f stamp-h1; \
- $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
- else :; fi
-
-stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
- @rm -f stamp-h1
- cd $(top_builddir) && $(SHELL) ./config.status config.h
-$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
- rm -f stamp-h1
- touch $@
-
-distclean-hdr:
- -rm -f config.h stamp-h1
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
- @$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
- list2=; for p in $$list; do \
- if test -f $$p; then \
- list2="$$list2 $$p"; \
- else :; fi; \
- done; \
- test -z "$$list2" || { \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
- }
-
-uninstall-libLTLIBRARIES:
- @$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
- for p in $$list; do \
- $(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
- done
-
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
-libev.la: $(libev_la_OBJECTS) $(libev_la_DEPENDENCIES)
- $(libev_la_LINK) -rpath $(libdir) $(libev_la_OBJECTS) $(libev_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Plo@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-
-distclean-libtool:
- -rm -f libtool config.lt
-install-man3: $(man_MANS)
- @$(NORMAL_INSTALL)
- test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
- @list=''; test -n "$(man3dir)" || exit 0; \
- { for i in $$list; do echo "$$i"; done; \
- l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
- sed -n '/\.3[a-z]*$$/p'; \
- } | while read p; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; echo "$$p"; \
- done | \
- sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
- sed 'N;N;s,\n, ,g' | { \
- list=; while read file base inst; do \
- if test "$$base" = "$$inst"; then list="$$list $$file"; else \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
- fi; \
- done; \
- for i in $$list; do echo "$$i"; done | $(am__base_list) | \
- while read files; do \
- test -z "$$files" || { \
- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
- $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
- done; }
-
-uninstall-man3:
- @$(NORMAL_UNINSTALL)
- @list=''; test -n "$(man3dir)" || exit 0; \
- files=`{ for i in $$list; do echo "$$i"; done; \
- l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
- sed -n '/\.3[a-z]*$$/p'; \
- } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
- test -z "$$files" || { \
- echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(man3dir)" && rm -f $$files; }
-install-includeHEADERS: $(include_HEADERS)
- @$(NORMAL_INSTALL)
- test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
- @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; \
- done | $(am__base_list) | \
- while read files; do \
- echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
- $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
- done
-
-uninstall-includeHEADERS:
- @$(NORMAL_UNINSTALL)
- @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
- files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
- test -n "$$files" || exit 0; \
- echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(includedir)" && rm -f $$files
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- set x; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- shift; \
- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- if test $$# -gt 0; then \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- "$$@" $$unique; \
- else \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$unique; \
- fi; \
- fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && $(am__cd) $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) "$$here"
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @list='$(MANS)'; if test -n "$$list"; then \
- list=`for p in $$list; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
- if test -n "$$list" && \
- grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
- echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
- grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
- echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
- echo " typically \`make maintainer-clean' will remove them" >&2; \
- exit 1; \
- else :; fi; \
- else :; fi
- $(am__remove_distdir)
- test -d "$(distdir)" || mkdir "$(distdir)"
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
- -test -n "$(am__skip_mode_fix)" \
- || find "$(distdir)" -type d ! -perm -755 \
- -exec chmod u+rwx,go+rx {} \; -o \
- ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
- || chmod -R a+r "$(distdir)"
-dist-gzip: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-
-dist-bzip2: distdir
- tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
- $(am__remove_distdir)
-
-dist-lzma: distdir
- tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
- $(am__remove_distdir)
-
-dist-xz: distdir
- tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
- $(am__remove_distdir)
-
-dist-tarZ: distdir
- tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
- $(am__remove_distdir)
-
-dist-shar: distdir
- shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
- $(am__remove_distdir)
-
-dist-zip: distdir
- -rm -f $(distdir).zip
- zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
-
-dist dist-all: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-
-# This target untars the dist file and tries a VPATH configuration. Then
-# it guarantees that the distribution is self-contained by making another
-# tarfile.
-distcheck: dist
- case '$(DIST_ARCHIVES)' in \
- *.tar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
- *.tar.bz2*) \
- bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
- *.tar.lzma*) \
- lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
- *.tar.xz*) \
- xz -dc $(distdir).tar.xz | $(am__untar) ;;\
- *.tar.Z*) \
- uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
- *.shar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
- *.zip*) \
- unzip $(distdir).zip ;;\
- esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
- chmod a-w $(distdir)
- test -d $(distdir)/_build || exit 0; \
- dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
- && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
- && am__cwd=`pwd` \
- && $(am__cd) $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
- $(DISTCHECK_CONFIGURE_FLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) dvi \
- && $(MAKE) $(AM_MAKEFLAGS) check \
- && $(MAKE) $(AM_MAKEFLAGS) install \
- && $(MAKE) $(AM_MAKEFLAGS) installcheck \
- && $(MAKE) $(AM_MAKEFLAGS) uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
- distuninstallcheck \
- && chmod -R a-w "$$dc_install_base" \
- && ({ \
- (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
- distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
- } || { rm -rf "$$dc_destdir"; exit 1; }) \
- && rm -rf "$$dc_destdir" \
- && $(MAKE) $(AM_MAKEFLAGS) dist \
- && rm -rf $(DIST_ARCHIVES) \
- && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
- && cd "$$am__cwd" \
- || exit 1
- $(am__remove_distdir)
- @(echo "$(distdir) archives ready for distribution: "; \
- list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
- sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
-distuninstallcheck:
- @$(am__cd) '$(distuninstallcheck_dir)' \
- && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
- || { echo "ERROR: files left after uninstall:" ; \
- if test -n "$(DESTDIR)"; then \
- echo " (check DESTDIR support)"; \
- fi ; \
- $(distuninstallcheck_listfiles) ; \
- exit 1; } >&2
-distcleancheck: distclean
- @if test '$(srcdir)' = . ; then \
- echo "ERROR: distcleancheck can only run from a VPATH build" ; \
- exit 1 ; \
- fi
- @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
- || { echo "ERROR: files left in build directory after distclean:" ; \
- $(distcleancheck_listfiles) ; \
- exit 1; } >&2
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(MANS) $(HEADERS) config.h
-installdirs:
- for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(includedir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
- mostlyclean-am
-
-distclean: distclean-am
- -rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-hdr distclean-libtool distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-includeHEADERS install-man
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am: install-libLTLIBRARIES
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man: install-man3
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf $(top_srcdir)/autom4te.cache
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \
- uninstall-man
-
-uninstall-man: uninstall-man3
-
-.MAKE: all install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
- clean-generic clean-libLTLIBRARIES clean-libtool ctags dist \
- dist-all dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ \
- dist-xz dist-zip distcheck distclean distclean-compile \
- distclean-generic distclean-hdr distclean-libtool \
- distclean-tags distcleancheck distdir distuninstallcheck dvi \
- dvi-am html html-am info info-am install install-am \
- install-data install-data-am install-dvi install-dvi-am \
- install-exec install-exec-am install-html install-html-am \
- install-includeHEADERS install-info install-info-am \
- install-libLTLIBRARIES install-man install-man3 install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags uninstall uninstall-am uninstall-includeHEADERS \
- uninstall-libLTLIBRARIES uninstall-man uninstall-man3
-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/deps/uv/src/unix/ev/README b/deps/uv/src/unix/ev/README
deleted file mode 100644
index ca403c6f4..000000000
--- a/deps/uv/src/unix/ev/README
+++ /dev/null
@@ -1,58 +0,0 @@
-libev is a high-performance event loop/event model with lots of features.
-(see benchmark at http://libev.schmorp.de/bench.html)
-
-
-ABOUT
-
- Homepage: http://software.schmorp.de/pkg/libev
- Mailinglist: libev@lists.schmorp.de
- http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
- Library Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
-
- Libev is modelled (very losely) after libevent and the Event perl
- module, but is faster, scales better and is more correct, and also more
- featureful. And also smaller. Yay.
-
- Some of the specialties of libev not commonly found elsewhere are:
-
- - extensive and detailed, readable documentation (not doxygen garbage).
- - fully supports fork, can detect fork in various ways and automatically
- re-arms kernel mechanisms that do not support fork.
- - highly optimised select, poll, epoll, kqueue and event ports backends.
- - filesystem object (path) watching (with optional linux inotify support).
- - wallclock-based times (using absolute time, cron-like).
- - relative timers/timeouts (handle time jumps).
- - fast intra-thread communication between multiple
- event loops (with optional fast linux eventfd backend).
- - extremely easy to embed.
- - very small codebase, no bloated library.
- - fully extensible by being able to plug into the event loop,
- integrate other event loops, integrate other event loop users.
- - very little memory use (small watchers, small event loop data).
- - optional C++ interface allowing method and function callbacks
- at no extra memory or runtime overhead.
- - optional Perl interface with similar characteristics (capable
- of running Glib/Gtk2 on libev, interfaces with Net::SNMP and
- libadns).
- - support for other languages (multiple C++ interfaces, D, Ruby,
- Python) available from third-parties.
-
- Examples of programs that embed libev: the EV perl module,
- rxvt-unicode, gvpe (GNU Virtual Private Ethernet), the Deliantra MMORPG
- server (http://www.deliantra.net/), Rubinius (a next-generation Ruby
- VM), the Ebb web server, the Rev event toolkit.
-
-
-CONTRIBUTORS
-
- libev was written and designed by Marc Lehmann and Emanuele Giaquinta.
-
- The following people sent in patches or made other noteworthy
- contributions to the design (for minor patches, see the Changes
- file. If I forgot to include you, please shout at me, it was an
- accident):
-
- W.C.A. Wijngaards
- Christopher Layne
- Chris Brody
-
diff --git a/deps/uv/src/unix/ev/aclocal.m4 b/deps/uv/src/unix/ev/aclocal.m4
deleted file mode 100644
index 18abb7368..000000000
--- a/deps/uv/src/unix/ev/aclocal.m4
+++ /dev/null
@@ -1,8957 +0,0 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],,
-[m4_warning([this file was generated for autoconf 2.67.
-You have another version of autoconf. It may work, but is not guaranteed to.
-If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
-
-# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008 Free Software Foundation, Inc.
-# Written by Gordon Matzigkeit, 1996
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-
-m4_define([_LT_COPYING], [dnl
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008 Free Software Foundation, Inc.
-# Written by Gordon Matzigkeit, 1996
-#
-# This file is part of GNU Libtool.
-#
-# GNU Libtool is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# As a special exception to the GNU General Public License,
-# if you distribute this file as part of a program or library that
-# is built using GNU Libtool, you may include this file under the
-# same distribution terms that you use for the rest of that program.
-#
-# GNU Libtool is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Libtool; see the file COPYING. If not, a copy
-# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
-# obtained by writing to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-])
-
-# serial 56 LT_INIT
-
-
-# LT_PREREQ(VERSION)
-# ------------------
-# Complain and exit if this libtool version is less that VERSION.
-m4_defun([LT_PREREQ],
-[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
- [m4_default([$3],
- [m4_fatal([Libtool version $1 or higher is required],
- 63)])],
- [$2])])
-
-
-# _LT_CHECK_BUILDDIR
-# ------------------
-# Complain if the absolute build directory name contains unusual characters
-m4_defun([_LT_CHECK_BUILDDIR],
-[case `pwd` in
- *\ * | *\ *)
- AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
-esac
-])
-
-
-# LT_INIT([OPTIONS])
-# ------------------
-AC_DEFUN([LT_INIT],
-[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
-AC_BEFORE([$0], [LT_LANG])dnl
-AC_BEFORE([$0], [LT_OUTPUT])dnl
-AC_BEFORE([$0], [LTDL_INIT])dnl
-m4_require([_LT_CHECK_BUILDDIR])dnl
-
-dnl Autoconf doesn't catch unexpanded LT_ macros by default:
-m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
-m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
-dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
-dnl unless we require an AC_DEFUNed macro:
-AC_REQUIRE([LTOPTIONS_VERSION])dnl
-AC_REQUIRE([LTSUGAR_VERSION])dnl
-AC_REQUIRE([LTVERSION_VERSION])dnl
-AC_REQUIRE([LTOBSOLETE_VERSION])dnl
-m4_require([_LT_PROG_LTMAIN])dnl
-
-dnl Parse OPTIONS
-_LT_SET_OPTIONS([$0], [$1])
-
-# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ltmain"
-
-# Always use our own libtool.
-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
-AC_SUBST(LIBTOOL)dnl
-
-_LT_SETUP
-
-# Only expand once:
-m4_define([LT_INIT])
-])# LT_INIT
-
-# Old names:
-AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
-AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
-dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
-
-
-# _LT_CC_BASENAME(CC)
-# -------------------
-# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
-m4_defun([_LT_CC_BASENAME],
-[for cc_temp in $1""; do
- case $cc_temp in
- compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
- distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-])
-
-
-# _LT_FILEUTILS_DEFAULTS
-# ----------------------
-# It is okay to use these file commands and assume they have been set
-# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
-m4_defun([_LT_FILEUTILS_DEFAULTS],
-[: ${CP="cp -f"}
-: ${MV="mv -f"}
-: ${RM="rm -f"}
-])# _LT_FILEUTILS_DEFAULTS
-
-
-# _LT_SETUP
-# ---------
-m4_defun([_LT_SETUP],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-_LT_DECL([], [host_alias], [0], [The host system])dnl
-_LT_DECL([], [host], [0])dnl
-_LT_DECL([], [host_os], [0])dnl
-dnl
-_LT_DECL([], [build_alias], [0], [The build system])dnl
-_LT_DECL([], [build], [0])dnl
-_LT_DECL([], [build_os], [0])dnl
-dnl
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([LT_PATH_LD])dnl
-AC_REQUIRE([LT_PATH_NM])dnl
-dnl
-AC_REQUIRE([AC_PROG_LN_S])dnl
-test -z "$LN_S" && LN_S="ln -s"
-_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
-dnl
-AC_REQUIRE([LT_CMD_MAX_LEN])dnl
-_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
-_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
-dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_CHECK_SHELL_FEATURES])dnl
-m4_require([_LT_CMD_RELOAD])dnl
-m4_require([_LT_CHECK_MAGIC_METHOD])dnl
-m4_require([_LT_CMD_OLD_ARCHIVE])dnl
-m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
-
-_LT_CONFIG_LIBTOOL_INIT([
-# See if we are running on zsh, and set the options which allow our
-# commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
-fi
-])
-if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
-fi
-
-_LT_CHECK_OBJDIR
-
-m4_require([_LT_TAG_COMPILER])dnl
-_LT_PROG_ECHO_BACKSLASH
-
-case $host_os in
-aix3*)
- # AIX sometimes has problems with the GCC collect2 program. For some
- # reason, if we set the COLLECT_NAMES environment variable, the problems
- # vanish in a puff of smoke.
- if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
- fi
- ;;
-esac
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\([["`\\]]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
-# Global variables:
-ofile=libtool
-can_build_shared=yes
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-
-with_gnu_ld="$lt_cv_prog_gnu_ld"
-
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
-
-# Set sane defaults for various variables
-test -z "$CC" && CC=cc
-test -z "$LTCC" && LTCC=$CC
-test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
-test -z "$LD" && LD=ld
-test -z "$ac_objext" && ac_objext=o
-
-_LT_CC_BASENAME([$compiler])
-
-# Only perform the check for file, if the check method requires it
-test -z "$MAGIC_CMD" && MAGIC_CMD=file
-case $deplibs_check_method in
-file_magic*)
- if test "$file_magic_cmd" = '$MAGIC_CMD'; then
- _LT_PATH_MAGIC
- fi
- ;;
-esac
-
-# Use C for the default configuration in the libtool script
-LT_SUPPORTED_TAG([CC])
-_LT_LANG_C_CONFIG
-_LT_LANG_DEFAULT_CONFIG
-_LT_CONFIG_COMMANDS
-])# _LT_SETUP
-
-
-# _LT_PROG_LTMAIN
-# ---------------
-# Note that this code is called both from `configure', and `config.status'
-# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
-# `config.status' has no value for ac_aux_dir unless we are using Automake,
-# so we pass a copy along to make sure it has a sensible value anyway.
-m4_defun([_LT_PROG_LTMAIN],
-[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
-_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
-ltmain="$ac_aux_dir/ltmain.sh"
-])# _LT_PROG_LTMAIN
-
-
-
-# So that we can recreate a full libtool script including additional
-# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
-# in macros and then make a single call at the end using the `libtool'
-# label.
-
-
-# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
-# ----------------------------------------
-# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
-m4_define([_LT_CONFIG_LIBTOOL_INIT],
-[m4_ifval([$1],
- [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
- [$1
-])])])
-
-# Initialize.
-m4_define([_LT_OUTPUT_LIBTOOL_INIT])
-
-
-# _LT_CONFIG_LIBTOOL([COMMANDS])
-# ------------------------------
-# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
-m4_define([_LT_CONFIG_LIBTOOL],
-[m4_ifval([$1],
- [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
- [$1
-])])])
-
-# Initialize.
-m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
-
-
-# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
-# -----------------------------------------------------
-m4_defun([_LT_CONFIG_SAVE_COMMANDS],
-[_LT_CONFIG_LIBTOOL([$1])
-_LT_CONFIG_LIBTOOL_INIT([$2])
-])
-
-
-# _LT_FORMAT_COMMENT([COMMENT])
-# -----------------------------
-# Add leading comment marks to the start of each line, and a trailing
-# full-stop to the whole comment if one is not present already.
-m4_define([_LT_FORMAT_COMMENT],
-[m4_ifval([$1], [
-m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
- [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
-)])
-
-
-
-
-
-# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
-# -------------------------------------------------------------------
-# CONFIGNAME is the name given to the value in the libtool script.
-# VARNAME is the (base) name used in the configure script.
-# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
-# VARNAME. Any other value will be used directly.
-m4_define([_LT_DECL],
-[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
- [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
- [m4_ifval([$1], [$1], [$2])])
- lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
- m4_ifval([$4],
- [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
- lt_dict_add_subkey([lt_decl_dict], [$2],
- [tagged?], [m4_ifval([$5], [yes], [no])])])
-])
-
-
-# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
-# --------------------------------------------------------
-m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
-
-
-# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
-# ------------------------------------------------
-m4_define([lt_decl_tag_varnames],
-[_lt_decl_filter([tagged?], [yes], $@)])
-
-
-# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
-# ---------------------------------------------------------
-m4_define([_lt_decl_filter],
-[m4_case([$#],
- [0], [m4_fatal([$0: too few arguments: $#])],
- [1], [m4_fatal([$0: too few arguments: $#: $1])],
- [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
- [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
- [lt_dict_filter([lt_decl_dict], $@)])[]dnl
-])
-
-
-# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
-# --------------------------------------------------
-m4_define([lt_decl_quote_varnames],
-[_lt_decl_filter([value], [1], $@)])
-
-
-# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
-# ---------------------------------------------------
-m4_define([lt_decl_dquote_varnames],
-[_lt_decl_filter([value], [2], $@)])
-
-
-# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
-# ---------------------------------------------------
-m4_define([lt_decl_varnames_tagged],
-[m4_assert([$# <= 2])dnl
-_$0(m4_quote(m4_default([$1], [[, ]])),
- m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
- m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
-m4_define([_lt_decl_varnames_tagged],
-[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
-
-
-# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
-# ------------------------------------------------
-m4_define([lt_decl_all_varnames],
-[_$0(m4_quote(m4_default([$1], [[, ]])),
- m4_if([$2], [],
- m4_quote(lt_decl_varnames),
- m4_quote(m4_shift($@))))[]dnl
-])
-m4_define([_lt_decl_all_varnames],
-[lt_join($@, lt_decl_varnames_tagged([$1],
- lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
-])
-
-
-# _LT_CONFIG_STATUS_DECLARE([VARNAME])
-# ------------------------------------
-# Quote a variable value, and forward it to `config.status' so that its
-# declaration there will have the same value as in `configure'. VARNAME
-# must have a single quote delimited value for this to work.
-m4_define([_LT_CONFIG_STATUS_DECLARE],
-[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
-
-
-# _LT_CONFIG_STATUS_DECLARATIONS
-# ------------------------------
-# We delimit libtool config variables with single quotes, so when
-# we write them to config.status, we have to be sure to quote all
-# embedded single quotes properly. In configure, this macro expands
-# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
-#
-# <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
-m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
-[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
- [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
-
-
-# _LT_LIBTOOL_TAGS
-# ----------------
-# Output comment and list of tags supported by the script
-m4_defun([_LT_LIBTOOL_TAGS],
-[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
-available_tags="_LT_TAGS"dnl
-])
-
-
-# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
-# -----------------------------------
-# Extract the dictionary values for VARNAME (optionally with TAG) and
-# expand to a commented shell variable setting:
-#
-# # Some comment about what VAR is for.
-# visible_name=$lt_internal_name
-m4_define([_LT_LIBTOOL_DECLARE],
-[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
- [description])))[]dnl
-m4_pushdef([_libtool_name],
- m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
-m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
- [0], [_libtool_name=[$]$1],
- [1], [_libtool_name=$lt_[]$1],
- [2], [_libtool_name=$lt_[]$1],
- [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
-m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
-])
-
-
-# _LT_LIBTOOL_CONFIG_VARS
-# -----------------------
-# Produce commented declarations of non-tagged libtool config variables
-# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
-# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
-# section) are produced by _LT_LIBTOOL_TAG_VARS.
-m4_defun([_LT_LIBTOOL_CONFIG_VARS],
-[m4_foreach([_lt_var],
- m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
- [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
-
-
-# _LT_LIBTOOL_TAG_VARS(TAG)
-# -------------------------
-m4_define([_LT_LIBTOOL_TAG_VARS],
-[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
- [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
-
-
-# _LT_TAGVAR(VARNAME, [TAGNAME])
-# ------------------------------
-m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
-
-
-# _LT_CONFIG_COMMANDS
-# -------------------
-# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
-# variables for single and double quote escaping we saved from calls
-# to _LT_DECL, we can put quote escaped variables declarations
-# into `config.status', and then the shell code to quote escape them in
-# for loops in `config.status'. Finally, any additional code accumulated
-# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
-m4_defun([_LT_CONFIG_COMMANDS],
-[AC_PROVIDE_IFELSE([LT_OUTPUT],
- dnl If the libtool generation code has been placed in $CONFIG_LT,
- dnl instead of duplicating it all over again into config.status,
- dnl then we will have config.status run $CONFIG_LT later, so it
- dnl needs to know what name is stored there:
- [AC_CONFIG_COMMANDS([libtool],
- [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
- dnl If the libtool generation code is destined for config.status,
- dnl expand the accumulated commands and init code now:
- [AC_CONFIG_COMMANDS([libtool],
- [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
-])#_LT_CONFIG_COMMANDS
-
-
-# Initialize.
-m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
-[
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-sed_quote_subst='$sed_quote_subst'
-double_quote_subst='$double_quote_subst'
-delay_variable_subst='$delay_variable_subst'
-_LT_CONFIG_STATUS_DECLARATIONS
-LTCC='$LTCC'
-LTCFLAGS='$LTCFLAGS'
-compiler='$compiler_DEFAULT'
-
-# Quote evaled strings.
-for var in lt_decl_all_varnames([[ \
-]], lt_decl_quote_varnames); do
- case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
- *[[\\\\\\\`\\"\\\$]]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
- ;;
- *)
- eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
- ;;
- esac
-done
-
-# Double-quote double-evaled strings.
-for var in lt_decl_all_varnames([[ \
-]], lt_decl_dquote_varnames); do
- case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
- *[[\\\\\\\`\\"\\\$]]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
- ;;
- *)
- eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
- ;;
- esac
-done
-
-# Fix-up fallback echo if it was mangled by the above quoting rules.
-case \$lt_ECHO in
-*'\\\[$]0 --fallback-echo"')dnl "
- lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
- ;;
-esac
-
-_LT_OUTPUT_LIBTOOL_INIT
-])
-
-
-# LT_OUTPUT
-# ---------
-# This macro allows early generation of the libtool script (before
-# AC_OUTPUT is called), incase it is used in configure for compilation
-# tests.
-AC_DEFUN([LT_OUTPUT],
-[: ${CONFIG_LT=./config.lt}
-AC_MSG_NOTICE([creating $CONFIG_LT])
-cat >"$CONFIG_LT" <<_LTEOF
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate a libtool stub with the current configuration.
-
-lt_cl_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_LTEOF
-
-cat >>"$CONFIG_LT" <<\_LTEOF
-AS_SHELL_SANITIZE
-_AS_PREPARE
-
-exec AS_MESSAGE_FD>&1
-exec AS_MESSAGE_LOG_FD>>config.log
-{
- echo
- AS_BOX([Running $as_me.])
-} >&AS_MESSAGE_LOG_FD
-
-lt_cl_help="\
-\`$as_me' creates a local libtool stub from the current configuration,
-for use in further configure time tests before the real libtool is
-generated.
-
-Usage: $[0] [[OPTIONS]]
-
- -h, --help print this help, then exit
- -V, --version print version number, then exit
- -q, --quiet do not print progress messages
- -d, --debug don't remove temporary files
-
-Report bugs to <bug-libtool@gnu.org>."
-
-lt_cl_version="\
-m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
-m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
-configured by $[0], generated by m4_PACKAGE_STRING.
-
-Copyright (C) 2008 Free Software Foundation, Inc.
-This config.lt script is free software; the Free Software Foundation
-gives unlimited permision to copy, distribute and modify it."
-
-while test $[#] != 0
-do
- case $[1] in
- --version | --v* | -V )
- echo "$lt_cl_version"; exit 0 ;;
- --help | --h* | -h )
- echo "$lt_cl_help"; exit 0 ;;
- --debug | --d* | -d )
- debug=: ;;
- --quiet | --q* | --silent | --s* | -q )
- lt_cl_silent=: ;;
-
- -*) AC_MSG_ERROR([unrecognized option: $[1]
-Try \`$[0] --help' for more information.]) ;;
-
- *) AC_MSG_ERROR([unrecognized argument: $[1]
-Try \`$[0] --help' for more information.]) ;;
- esac
- shift
-done
-
-if $lt_cl_silent; then
- exec AS_MESSAGE_FD>/dev/null
-fi
-_LTEOF
-
-cat >>"$CONFIG_LT" <<_LTEOF
-_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
-_LTEOF
-
-cat >>"$CONFIG_LT" <<\_LTEOF
-AC_MSG_NOTICE([creating $ofile])
-_LT_OUTPUT_LIBTOOL_COMMANDS
-AS_EXIT(0)
-_LTEOF
-chmod +x "$CONFIG_LT"
-
-# configure is writing to config.log, but config.lt does its own redirection,
-# appending to config.log, which fails on DOS, as config.log is still kept
-# open by configure. Here we exec the FD to /dev/null, effectively closing
-# config.log, so it can be properly (re)opened and appended to by config.lt.
-if test "$no_create" != yes; then
- lt_cl_success=:
- test "$silent" = yes &&
- lt_config_lt_args="$lt_config_lt_args --quiet"
- exec AS_MESSAGE_LOG_FD>/dev/null
- $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
- exec AS_MESSAGE_LOG_FD>>config.log
- $lt_cl_success || AS_EXIT(1)
-fi
-])# LT_OUTPUT
-
-
-# _LT_CONFIG(TAG)
-# ---------------
-# If TAG is the built-in tag, create an initial libtool script with a
-# default configuration from the untagged config vars. Otherwise add code
-# to config.status for appending the configuration named by TAG from the
-# matching tagged config vars.
-m4_defun([_LT_CONFIG],
-[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-_LT_CONFIG_SAVE_COMMANDS([
- m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
- m4_if(_LT_TAG, [C], [
- # See if we are running on zsh, and set the options which allow our
- # commands through without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
-
- cfgfile="${ofile}T"
- trap "$RM \"$cfgfile\"; exit 1" 1 2 15
- $RM "$cfgfile"
-
- cat <<_LT_EOF >> "$cfgfile"
-#! $SHELL
-
-# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
-# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-#
-_LT_COPYING
-_LT_LIBTOOL_TAGS
-
-# ### BEGIN LIBTOOL CONFIG
-_LT_LIBTOOL_CONFIG_VARS
-_LT_LIBTOOL_TAG_VARS
-# ### END LIBTOOL CONFIG
-
-_LT_EOF
-
- case $host_os in
- aix3*)
- cat <<\_LT_EOF >> "$cfgfile"
-# AIX sometimes has problems with the GCC collect2 program. For some
-# reason, if we set the COLLECT_NAMES environment variable, the problems
-# vanish in a puff of smoke.
-if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
-fi
-_LT_EOF
- ;;
- esac
-
- _LT_PROG_LTMAIN
-
- # We use sed instead of cat because bash on DJGPP gets confused if
- # if finds mixed CR/LF and LF-only lines. Since sed operates in
- # text mode, it properly converts lines to CR/LF. This bash problem
- # is reportedly fixed, but why not run on old versions too?
- sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- _LT_PROG_XSI_SHELLFNS
-
- sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- mv -f "$cfgfile" "$ofile" ||
- (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
- chmod +x "$ofile"
-],
-[cat <<_LT_EOF >> "$ofile"
-
-dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
-dnl in a comment (ie after a #).
-# ### BEGIN LIBTOOL TAG CONFIG: $1
-_LT_LIBTOOL_TAG_VARS(_LT_TAG)
-# ### END LIBTOOL TAG CONFIG: $1
-_LT_EOF
-])dnl /m4_if
-],
-[m4_if([$1], [], [
- PACKAGE='$PACKAGE'
- VERSION='$VERSION'
- TIMESTAMP='$TIMESTAMP'
- RM='$RM'
- ofile='$ofile'], [])
-])dnl /_LT_CONFIG_SAVE_COMMANDS
-])# _LT_CONFIG
-
-
-# LT_SUPPORTED_TAG(TAG)
-# ---------------------
-# Trace this macro to discover what tags are supported by the libtool
-# --tag option, using:
-# autoconf --trace 'LT_SUPPORTED_TAG:$1'
-AC_DEFUN([LT_SUPPORTED_TAG], [])
-
-
-# C support is built-in for now
-m4_define([_LT_LANG_C_enabled], [])
-m4_define([_LT_TAGS], [])
-
-
-# LT_LANG(LANG)
-# -------------
-# Enable libtool support for the given language if not already enabled.
-AC_DEFUN([LT_LANG],
-[AC_BEFORE([$0], [LT_OUTPUT])dnl
-m4_case([$1],
- [C], [_LT_LANG(C)],
- [C++], [_LT_LANG(CXX)],
- [Java], [_LT_LANG(GCJ)],
- [Fortran 77], [_LT_LANG(F77)],
- [Fortran], [_LT_LANG(FC)],
- [Windows Resource], [_LT_LANG(RC)],
- [m4_ifdef([_LT_LANG_]$1[_CONFIG],
- [_LT_LANG($1)],
- [m4_fatal([$0: unsupported language: "$1"])])])dnl
-])# LT_LANG
-
-
-# _LT_LANG(LANGNAME)
-# ------------------
-m4_defun([_LT_LANG],
-[m4_ifdef([_LT_LANG_]$1[_enabled], [],
- [LT_SUPPORTED_TAG([$1])dnl
- m4_append([_LT_TAGS], [$1 ])dnl
- m4_define([_LT_LANG_]$1[_enabled], [])dnl
- _LT_LANG_$1_CONFIG($1)])dnl
-])# _LT_LANG
-
-
-# _LT_LANG_DEFAULT_CONFIG
-# -----------------------
-m4_defun([_LT_LANG_DEFAULT_CONFIG],
-[AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [LT_LANG(CXX)],
- [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
-
-AC_PROVIDE_IFELSE([AC_PROG_F77],
- [LT_LANG(F77)],
- [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
-
-AC_PROVIDE_IFELSE([AC_PROG_FC],
- [LT_LANG(FC)],
- [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
-
-dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
-dnl pulling things in needlessly.
-AC_PROVIDE_IFELSE([AC_PROG_GCJ],
- [LT_LANG(GCJ)],
- [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
- [LT_LANG(GCJ)],
- [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
- [LT_LANG(GCJ)],
- [m4_ifdef([AC_PROG_GCJ],
- [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
- m4_ifdef([A][M_PROG_GCJ],
- [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
- m4_ifdef([LT_PROG_GCJ],
- [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
-
-AC_PROVIDE_IFELSE([LT_PROG_RC],
- [LT_LANG(RC)],
- [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
-])# _LT_LANG_DEFAULT_CONFIG
-
-# Obsolete macros:
-AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
-AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
-AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
-AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
-dnl AC_DEFUN([AC_LIBTOOL_F77], [])
-dnl AC_DEFUN([AC_LIBTOOL_FC], [])
-dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
-
-
-# _LT_TAG_COMPILER
-# ----------------
-m4_defun([_LT_TAG_COMPILER],
-[AC_REQUIRE([AC_PROG_CC])dnl
-
-_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
-_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
-_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
-_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-])# _LT_TAG_COMPILER
-
-
-# _LT_COMPILER_BOILERPLATE
-# ------------------------
-# Check for compiler boilerplate output or warnings with
-# the simple compiler test code.
-m4_defun([_LT_COMPILER_BOILERPLATE],
-[m4_require([_LT_DECL_SED])dnl
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$RM conftest*
-])# _LT_COMPILER_BOILERPLATE
-
-
-# _LT_LINKER_BOILERPLATE
-# ----------------------
-# Check for linker boilerplate output or warnings with
-# the simple link test code.
-m4_defun([_LT_LINKER_BOILERPLATE],
-[m4_require([_LT_DECL_SED])dnl
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$RM -r conftest*
-])# _LT_LINKER_BOILERPLATE
-
-# _LT_REQUIRED_DARWIN_CHECKS
-# -------------------------
-m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
- case $host_os in
- rhapsody* | darwin*)
- AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
- AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
- AC_CHECK_TOOL([LIPO], [lipo], [:])
- AC_CHECK_TOOL([OTOOL], [otool], [:])
- AC_CHECK_TOOL([OTOOL64], [otool64], [:])
- _LT_DECL([], [DSYMUTIL], [1],
- [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
- _LT_DECL([], [NMEDIT], [1],
- [Tool to change global to local symbols on Mac OS X])
- _LT_DECL([], [LIPO], [1],
- [Tool to manipulate fat objects and archives on Mac OS X])
- _LT_DECL([], [OTOOL], [1],
- [ldd/readelf like tool for Mach-O binaries on Mac OS X])
- _LT_DECL([], [OTOOL64], [1],
- [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
-
- AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
- [lt_cv_apple_cc_single_mod=no
- if test -z "${LT_MULTI_MODULE}"; then
- # By default we will add the -single_module flag. You can override
- # by either setting the environment variable LT_MULTI_MODULE
- # non-empty at configure time, or by adding -multi_module to the
- # link flags.
- rm -rf libconftest.dylib*
- echo "int foo(void){return 1;}" > conftest.c
- echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
--dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
- $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
- -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
- _lt_result=$?
- if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
- lt_cv_apple_cc_single_mod=yes
- else
- cat conftest.err >&AS_MESSAGE_LOG_FD
- fi
- rm -rf libconftest.dylib*
- rm -f conftest.*
- fi])
- AC_CACHE_CHECK([for -exported_symbols_list linker flag],
- [lt_cv_ld_exported_symbols_list],
- [lt_cv_ld_exported_symbols_list=no
- save_LDFLAGS=$LDFLAGS
- echo "_main" > conftest.sym
- LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
- AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
- [lt_cv_ld_exported_symbols_list=yes],
- [lt_cv_ld_exported_symbols_list=no])
- LDFLAGS="$save_LDFLAGS"
- ])
- case $host_os in
- rhapsody* | darwin1.[[012]])
- _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
- darwin1.*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- darwin*) # darwin 5.x on
- # if running on 10.5 or later, the deployment target defaults
- # to the OS version, if on x86, and 10.4, the deployment
- # target defaults to 10.4. Don't you love it?
- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
- 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- 10.[[012]]*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- 10.*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- esac
- ;;
- esac
- if test "$lt_cv_apple_cc_single_mod" = "yes"; then
- _lt_dar_single_mod='$single_module'
- fi
- if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
- _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
- else
- _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
- fi
- if test "$DSYMUTIL" != ":"; then
- _lt_dsymutil='~$DSYMUTIL $lib || :'
- else
- _lt_dsymutil=
- fi
- ;;
- esac
-])
-
-
-# _LT_DARWIN_LINKER_FEATURES
-# --------------------------
-# Checks for linker and compiler features on darwin
-m4_defun([_LT_DARWIN_LINKER_FEATURES],
-[
- m4_require([_LT_REQUIRED_DARWIN_CHECKS])
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_automatic, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_TAGVAR(whole_archive_flag_spec, $1)=''
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
- case $cc_basename in
- ifort*) _lt_dar_can_shared=yes ;;
- *) _lt_dar_can_shared=$GCC ;;
- esac
- if test "$_lt_dar_can_shared" = "yes"; then
- output_verbose_link_cmd=echo
- _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- m4_if([$1], [CXX],
-[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
- _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
- _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
- fi
-],[])
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
-])
-
-# _LT_SYS_MODULE_PATH_AIX
-# -----------------------
-# Links a minimal program and checks the executable
-# for the system default hardcoded library path. In most cases,
-# this is /usr/lib:/lib, but when the MPI compilers are used
-# the location of the communication and MPI libs are included too.
-# If we don't find anything, use the default library path according
-# to the aix ld manual.
-m4_defun([_LT_SYS_MODULE_PATH_AIX],
-[m4_require([_LT_DECL_SED])dnl
-AC_LINK_IFELSE(AC_LANG_PROGRAM,[
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi],[])
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-])# _LT_SYS_MODULE_PATH_AIX
-
-
-# _LT_SHELL_INIT(ARG)
-# -------------------
-m4_define([_LT_SHELL_INIT],
-[ifdef([AC_DIVERSION_NOTICE],
- [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
- [AC_DIVERT_PUSH(NOTICE)])
-$1
-AC_DIVERT_POP
-])# _LT_SHELL_INIT
-
-
-# _LT_PROG_ECHO_BACKSLASH
-# -----------------------
-# Add some code to the start of the generated configure script which
-# will find an echo command which doesn't interpret backslashes.
-m4_defun([_LT_PROG_ECHO_BACKSLASH],
-[_LT_SHELL_INIT([
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$lt_ECHO in
-X*--fallback-echo)
- # Remove one level of quotation (which was required for Make).
- ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
- ;;
-esac
-
-ECHO=${lt_ECHO-echo}
-if test "X[$]1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X[$]1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
- # Yippee, $ECHO works!
- :
-else
- # Restart under the correct shell.
- exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
-fi
-
-if test "X[$]1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<_LT_EOF
-[$]*
-_LT_EOF
- exit 0
-fi
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$lt_ECHO"; then
- if test "X${echo_test_string+set}" != Xset; then
- # find a string as large as possible, as long as the shell can cope with it
- for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
- { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
- then
- break
- fi
- done
- fi
-
- if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- :
- else
- # The Solaris, AIX, and Digital Unix default echo programs unquote
- # backslashes. This makes it impossible to quote backslashes using
- # echo "$something" | sed 's/\\/\\\\/g'
- #
- # So, first we look for a working echo in the user's PATH.
-
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for dir in $PATH /usr/ucb; do
- IFS="$lt_save_ifs"
- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- ECHO="$dir/echo"
- break
- fi
- done
- IFS="$lt_save_ifs"
-
- if test "X$ECHO" = Xecho; then
- # We didn't find a better echo, so look for alternatives.
- if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # This shell has a builtin print -r that does the trick.
- ECHO='print -r'
- elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
- test "X$CONFIG_SHELL" != X/bin/ksh; then
- # If we have ksh, try running configure again with it.
- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
- export ORIGINAL_CONFIG_SHELL
- CONFIG_SHELL=/bin/ksh
- export CONFIG_SHELL
- exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
- else
- # Try using printf.
- ECHO='printf %s\n'
- if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # Cool, printf works
- :
- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
- export CONFIG_SHELL
- SHELL="$CONFIG_SHELL"
- export SHELL
- ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
- elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
- else
- # maybe with a smaller string...
- prev=:
-
- for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
- if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
- then
- break
- fi
- prev="$cmd"
- done
-
- if test "$prev" != 'sed 50q "[$]0"'; then
- echo_test_string=`eval $prev`
- export echo_test_string
- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
- else
- # Oops. We lost completely, so just stick with echo.
- ECHO=echo
- fi
- fi
- fi
- fi
- fi
-fi
-
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-lt_ECHO=$ECHO
-if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
- lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
-fi
-
-AC_SUBST(lt_ECHO)
-])
-_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
-_LT_DECL([], [ECHO], [1],
- [An echo program that does not interpret backslashes])
-])# _LT_PROG_ECHO_BACKSLASH
-
-
-# _LT_ENABLE_LOCK
-# ---------------
-m4_defun([_LT_ENABLE_LOCK],
-[AC_ARG_ENABLE([libtool-lock],
- [AS_HELP_STRING([--disable-libtool-lock],
- [avoid locking (might break parallel builds)])])
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-# Some flags need to be propagated to the compiler or linker for good
-# libtool support.
-case $host in
-ia64-*-hpux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- case `/usr/bin/file conftest.$ac_objext` in
- *ELF-32*)
- HPUX_IA64_MODE="32"
- ;;
- *ELF-64*)
- HPUX_IA64_MODE="64"
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-*-*-irix6*)
- # Find out which ABI we are using.
- echo '[#]line __oline__ "configure"' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- if test "$lt_cv_prog_gnu_ld" = yes; then
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -melf32bsmip"
- ;;
- *N32*)
- LD="${LD-ld} -melf32bmipn32"
- ;;
- *64-bit*)
- LD="${LD-ld} -melf64bmip"
- ;;
- esac
- else
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -32"
- ;;
- *N32*)
- LD="${LD-ld} -n32"
- ;;
- *64-bit*)
- LD="${LD-ld} -64"
- ;;
- esac
- fi
- fi
- rm -rf conftest*
- ;;
-
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
-s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- case `/usr/bin/file conftest.o` in
- *32-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_i386_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
- ;;
- ppc64-*linux*|powerpc64-*linux*)
- LD="${LD-ld} -m elf32ppclinux"
- ;;
- s390x-*linux*)
- LD="${LD-ld} -m elf_s390"
- ;;
- sparc64-*linux*)
- LD="${LD-ld} -m elf32_sparc"
- ;;
- esac
- ;;
- *64-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_x86_64_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_x86_64"
- ;;
- ppc*-*linux*|powerpc*-*linux*)
- LD="${LD-ld} -m elf64ppc"
- ;;
- s390*-*linux*|s390*-*tpf*)
- LD="${LD-ld} -m elf64_s390"
- ;;
- sparc*-*linux*)
- LD="${LD-ld} -m elf64_sparc"
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-*-*-sco3.2v5*)
- # On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -belf"
- AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
- [AC_LANG_PUSH(C)
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
- AC_LANG_POP])
- if test x"$lt_cv_cc_needs_belf" != x"yes"; then
- # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
- CFLAGS="$SAVE_CFLAGS"
- fi
- ;;
-sparc*-*solaris*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- case `/usr/bin/file conftest.o` in
- *64-bit*)
- case $lt_cv_prog_gnu_ld in
- yes*) LD="${LD-ld} -m elf64_sparc" ;;
- *)
- if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
- LD="${LD-ld} -64"
- fi
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-esac
-
-need_locks="$enable_libtool_lock"
-])# _LT_ENABLE_LOCK
-
-
-# _LT_CMD_OLD_ARCHIVE
-# -------------------
-m4_defun([_LT_CMD_OLD_ARCHIVE],
-[AC_CHECK_TOOL(AR, ar, false)
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-_LT_DECL([], [AR], [1], [The archiver])
-_LT_DECL([], [AR_FLAGS], [1])
-
-AC_CHECK_TOOL(STRIP, strip, :)
-test -z "$STRIP" && STRIP=:
-_LT_DECL([], [STRIP], [1], [A symbol stripping program])
-
-AC_CHECK_TOOL(RANLIB, ranlib, :)
-test -z "$RANLIB" && RANLIB=:
-_LT_DECL([], [RANLIB], [1],
- [Commands used to install an old-style archive])
-
-# Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
-old_postinstall_cmds='chmod 644 $oldlib'
-old_postuninstall_cmds=
-
-if test -n "$RANLIB"; then
- case $host_os in
- openbsd*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
- ;;
- *)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
- ;;
- esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
-fi
-_LT_DECL([], [old_postinstall_cmds], [2])
-_LT_DECL([], [old_postuninstall_cmds], [2])
-_LT_TAGDECL([], [old_archive_cmds], [2],
- [Commands used to build an old-style archive])
-])# _LT_CMD_OLD_ARCHIVE
-
-
-# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
-# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
-# ----------------------------------------------------------------
-# Check whether the given compiler option works
-AC_DEFUN([_LT_COMPILER_OPTION],
-[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_DECL_SED])dnl
-AC_CACHE_CHECK([$1], [$2],
- [$2=no
- m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$3"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&AS_MESSAGE_LOG_FD
- echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- $2=yes
- fi
- fi
- $RM conftest*
-])
-
-if test x"[$]$2" = xyes; then
- m4_if([$5], , :, [$5])
-else
- m4_if([$6], , :, [$6])
-fi
-])# _LT_COMPILER_OPTION
-
-# Old name:
-AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
-
-
-# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
-# [ACTION-SUCCESS], [ACTION-FAILURE])
-# ----------------------------------------------------
-# Check whether the given linker option works
-AC_DEFUN([_LT_LINKER_OPTION],
-[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_DECL_SED])dnl
-AC_CACHE_CHECK([$1], [$2],
- [$2=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $3"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&AS_MESSAGE_LOG_FD
- $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- $2=yes
- fi
- else
- $2=yes
- fi
- fi
- $RM -r conftest*
- LDFLAGS="$save_LDFLAGS"
-])
-
-if test x"[$]$2" = xyes; then
- m4_if([$4], , :, [$4])
-else
- m4_if([$5], , :, [$5])
-fi
-])# _LT_LINKER_OPTION
-
-# Old name:
-AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
-
-
-# LT_CMD_MAX_LEN
-#---------------
-AC_DEFUN([LT_CMD_MAX_LEN],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-# find the maximum length of command line arguments
-AC_MSG_CHECKING([the maximum length of command line arguments])
-AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
- i=0
- teststring="ABCD"
-
- case $build_os in
- msdosdjgpp*)
- # On DJGPP, this test can blow up pretty badly due to problems in libc
- # (any single argument exceeding 2000 bytes causes a buffer overrun
- # during glob expansion). Even if it were fixed, the result of this
- # check would be larger than it should be.
- lt_cv_sys_max_cmd_len=12288; # 12K is about right
- ;;
-
- gnu*)
- # Under GNU Hurd, this test is not required because there is
- # no limit to the length of command line arguments.
- # Libtool will interpret -1 as no limit whatsoever
- lt_cv_sys_max_cmd_len=-1;
- ;;
-
- cygwin* | mingw* | cegcc*)
- # On Win9x/ME, this test blows up -- it succeeds, but takes
- # about 5 minutes as the teststring grows exponentially.
- # Worse, since 9x/ME are not pre-emptively multitasking,
- # you end up with a "frozen" computer, even though with patience
- # the test eventually succeeds (with a max line length of 256k).
- # Instead, let's just punt: use the minimum linelength reported by
- # all of the supported platforms: 8192 (on NT/2K/XP).
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- amigaos*)
- # On AmigaOS with pdksh, this test takes hours, literally.
- # So we just punt and use a minimum line length of 8192.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
- # This has been around since 386BSD, at least. Likely further.
- if test -x /sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
- elif test -x /usr/sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
- else
- lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
- fi
- # And add a safety zone
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- ;;
-
- interix*)
- # We know the value 262144 and hardcode it with a safety zone (like BSD)
- lt_cv_sys_max_cmd_len=196608
- ;;
-
- osf*)
- # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
- # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
- # nice to cause kernel panics so lets avoid the loop below.
- # First set a reasonable default.
- lt_cv_sys_max_cmd_len=16384
- #
- if test -x /sbin/sysconfig; then
- case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
- *1*) lt_cv_sys_max_cmd_len=-1 ;;
- esac
- fi
- ;;
- sco3.2v5*)
- lt_cv_sys_max_cmd_len=102400
- ;;
- sysv5* | sco5v6* | sysv4.2uw2*)
- kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
- if test -n "$kargmax"; then
- lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
- else
- lt_cv_sys_max_cmd_len=32768
- fi
- ;;
- *)
- lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- else
- # Make teststring a little bigger before we do anything with it.
- # a 1K string should be a reasonable start.
- for i in 1 2 3 4 5 6 7 8 ; do
- teststring=$teststring$teststring
- done
- SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
- # If test is not a shell built-in, we'll probably end up computing a
- # maximum length that is only half of the actual maximum length, but
- # we can't tell.
- while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
- = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
- test $i != 17 # 1/2 MB should be enough
- do
- i=`expr $i + 1`
- teststring=$teststring$teststring
- done
- # Only check the string length outside the loop.
- lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
- teststring=
- # Add a significant safety factor because C++ compilers can tack on
- # massive amounts of additional arguments before passing them to the
- # linker. It appears as though 1/2 is a usable value.
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
- fi
- ;;
- esac
-])
-if test -n $lt_cv_sys_max_cmd_len ; then
- AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
-else
- AC_MSG_RESULT(none)
-fi
-max_cmd_len=$lt_cv_sys_max_cmd_len
-_LT_DECL([], [max_cmd_len], [0],
- [What is the maximum length of a command?])
-])# LT_CMD_MAX_LEN
-
-# Old name:
-AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
-
-
-# _LT_HEADER_DLFCN
-# ----------------
-m4_defun([_LT_HEADER_DLFCN],
-[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
-])# _LT_HEADER_DLFCN
-
-
-# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
-# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
-# ----------------------------------------------------------------
-m4_defun([_LT_TRY_DLOPEN_SELF],
-[m4_require([_LT_HEADER_DLFCN])dnl
-if test "$cross_compiling" = yes; then :
- [$4]
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
-[#line __oline__ "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- return status;
-}]
-_LT_EOF
- if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) $1 ;;
- x$lt_dlneed_uscore) $2 ;;
- x$lt_dlunknown|x*) $3 ;;
- esac
- else :
- # compilation failed
- $3
- fi
-fi
-rm -fr conftest*
-])# _LT_TRY_DLOPEN_SELF
-
-
-# LT_SYS_DLOPEN_SELF
-# ------------------
-AC_DEFUN([LT_SYS_DLOPEN_SELF],
-[m4_require([_LT_HEADER_DLFCN])dnl
-if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- mingw* | pw32* | cegcc*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- cygwin*)
- lt_cv_dlopen="dlopen"
- lt_cv_dlopen_libs=
- ;;
-
- darwin*)
- # if libdl is installed we need to link against it
- AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
- lt_cv_dlopen="dyld"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ])
- ;;
-
- *)
- AC_CHECK_FUNC([shl_load],
- [lt_cv_dlopen="shl_load"],
- [AC_CHECK_LIB([dld], [shl_load],
- [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
- [AC_CHECK_FUNC([dlopen],
- [lt_cv_dlopen="dlopen"],
- [AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
- [AC_CHECK_LIB([svld], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
- [AC_CHECK_LIB([dld], [dld_link],
- [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
- ])
- ])
- ])
- ])
- ])
- ;;
- esac
-
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
- else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- AC_CACHE_CHECK([whether a program can dlopen itself],
- lt_cv_dlopen_self, [dnl
- _LT_TRY_DLOPEN_SELF(
- lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
- lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
- ])
-
- if test "x$lt_cv_dlopen_self" = xyes; then
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
- AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
- lt_cv_dlopen_self_static, [dnl
- _LT_TRY_DLOPEN_SELF(
- lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
- lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
- ])
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
-
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
-fi
-_LT_DECL([dlopen_support], [enable_dlopen], [0],
- [Whether dlopen is supported])
-_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
- [Whether dlopen of programs is supported])
-_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
- [Whether dlopen of statically linked programs is supported])
-])# LT_SYS_DLOPEN_SELF
-
-# Old name:
-AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
-
-
-# _LT_COMPILER_C_O([TAGNAME])
-# ---------------------------
-# Check to see if options -c and -o are simultaneously supported by compiler.
-# This macro does not hard code the compiler like AC_PROG_CC_C_O.
-m4_defun([_LT_COMPILER_C_O],
-[m4_require([_LT_DECL_SED])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_TAG_COMPILER])dnl
-AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
- [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
- [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
- $RM -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&AS_MESSAGE_LOG_FD
- echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
- fi
- fi
- chmod u+w . 2>&AS_MESSAGE_LOG_FD
- $RM conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
- $RM out/* && rmdir out
- cd ..
- $RM -r conftest
- $RM conftest*
-])
-_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
- [Does compiler simultaneously support -c and -o options?])
-])# _LT_COMPILER_C_O
-
-
-# _LT_COMPILER_FILE_LOCKS([TAGNAME])
-# ----------------------------------
-# Check to see if we can do hard links to lock some files if needed
-m4_defun([_LT_COMPILER_FILE_LOCKS],
-[m4_require([_LT_ENABLE_LOCK])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-_LT_COMPILER_C_O([$1])
-
-hard_links="nottested"
-if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- AC_MSG_CHECKING([if we can lock with hard links])
- hard_links=yes
- $RM conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- AC_MSG_RESULT([$hard_links])
- if test "$hard_links" = no; then
- AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
-])# _LT_COMPILER_FILE_LOCKS
-
-
-# _LT_CHECK_OBJDIR
-# ----------------
-m4_defun([_LT_CHECK_OBJDIR],
-[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
-[rm -f .libs 2>/dev/null
-mkdir .libs 2>/dev/null
-if test -d .libs; then
- lt_cv_objdir=.libs
-else
- # MS-DOS does not allow filenames that begin with a dot.
- lt_cv_objdir=_libs
-fi
-rmdir .libs 2>/dev/null])
-objdir=$lt_cv_objdir
-_LT_DECL([], [objdir], [0],
- [The name of the directory that contains temporary libtool files])dnl
-m4_pattern_allow([LT_OBJDIR])dnl
-AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
- [Define to the sub-directory in which libtool stores uninstalled libraries.])
-])# _LT_CHECK_OBJDIR
-
-
-# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
-# --------------------------------------
-# Check hardcoding attributes.
-m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
-[AC_MSG_CHECKING([how to hardcode library paths into programs])
-_LT_TAGVAR(hardcode_action, $1)=
-if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
- test -n "$_LT_TAGVAR(runpath_var, $1)" ||
- test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
-
- # We can hardcode non-existent directories.
- if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
- test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
- # Linking always hardcodes the temporary library directory.
- _LT_TAGVAR(hardcode_action, $1)=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- _LT_TAGVAR(hardcode_action, $1)=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- _LT_TAGVAR(hardcode_action, $1)=unsupported
-fi
-AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
-
-if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
- test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-_LT_TAGDECL([], [hardcode_action], [0],
- [How to hardcode a shared library path into an executable])
-])# _LT_LINKER_HARDCODE_LIBPATH
-
-
-# _LT_CMD_STRIPLIB
-# ----------------
-m4_defun([_LT_CMD_STRIPLIB],
-[m4_require([_LT_DECL_EGREP])
-striplib=
-old_striplib=
-AC_MSG_CHECKING([whether stripping libraries is possible])
-if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- AC_MSG_RESULT([yes])
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- old_striplib="$STRIP -S"
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- ;;
- *)
- AC_MSG_RESULT([no])
- ;;
- esac
-fi
-_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
-_LT_DECL([], [striplib], [1])
-])# _LT_CMD_STRIPLIB
-
-
-# _LT_SYS_DYNAMIC_LINKER([TAG])
-# -----------------------------
-# PORTME Fill in your ld.so characteristics
-m4_defun([_LT_SYS_DYNAMIC_LINKER],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-m4_require([_LT_DECL_EGREP])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_DECL_OBJDUMP])dnl
-m4_require([_LT_DECL_SED])dnl
-AC_MSG_CHECKING([dynamic linker characteristics])
-m4_if([$1],
- [], [
-if test "$GCC" = yes; then
- case $host_os in
- darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
- *) lt_awk_arg="/^libraries:/" ;;
- esac
- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
- else
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- # Ok, now we have the path, separated by spaces, we can step through it
- # and add multilib dir if necessary.
- lt_tmp_lt_search_path_spec=
- lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
- for lt_sys_path in $lt_search_path_spec; do
- if test -d "$lt_sys_path/$lt_multi_os_dir"; then
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
- else
- test -d "$lt_sys_path" && \
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
- fi
- done
- lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
-BEGIN {RS=" "; FS="/|\n";} {
- lt_foo="";
- lt_count=0;
- for (lt_i = NF; lt_i > 0; lt_i--) {
- if ($lt_i != "" && $lt_i != ".") {
- if ($lt_i == "..") {
- lt_count++;
- } else {
- if (lt_count == 0) {
- lt_foo="/" $lt_i lt_foo;
- } else {
- lt_count--;
- }
- }
- }
- }
- if (lt_foo != "") { lt_freq[[lt_foo]]++; }
- if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
-}'`
- sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi])
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[[4-9]]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[[01]] | aix4.[[01]].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- case $host_cpu in
- powerpc)
- # Since July 2007 AmigaOS4 officially supports .so libraries.
- # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- ;;
- m68k)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
- esac
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[[45]]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32* | cegcc*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname~
- if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
- eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
- fi'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $RM \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw* | cegcc*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-m4_if([$1], [],[
- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[[123]]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[[01]]* | freebsdelf3.[[01]]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
- freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix[[3-9]]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # Some binutils ld are patched to set DT_RUNPATH
- save_LDFLAGS=$LDFLAGS
- save_libdir=$libdir
- eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
- LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
- AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
- [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
- [shlibpath_overrides_runpath=yes])])
- LDFLAGS=$save_LDFLAGS
- libdir=$save_libdir
-
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsdelf*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='NetBSD ld.elf_so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-*nto* | *qnx*)
- version_type=qnx
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='ldqnx.so'
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[[89]] | openbsd2.[[89]].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-tpf*)
- # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-AC_MSG_RESULT([$dynamic_linker])
-test "$dynamic_linker" = no && can_build_shared=no
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-fi
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-fi
-
-_LT_DECL([], [variables_saved_for_relink], [1],
- [Variables whose values should be saved in libtool wrapper scripts and
- restored at link time])
-_LT_DECL([], [need_lib_prefix], [0],
- [Do we need the "lib" prefix for modules?])
-_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
-_LT_DECL([], [version_type], [0], [Library versioning type])
-_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
-_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
-_LT_DECL([], [shlibpath_overrides_runpath], [0],
- [Is shlibpath searched before the hard-coded library search path?])
-_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
-_LT_DECL([], [library_names_spec], [1],
- [[List of archive names. First name is the real one, the rest are links.
- The last name is the one that the linker finds with -lNAME]])
-_LT_DECL([], [soname_spec], [1],
- [[The coded name of the library, if different from the real name]])
-_LT_DECL([], [postinstall_cmds], [2],
- [Command to use after installation of a shared archive])
-_LT_DECL([], [postuninstall_cmds], [2],
- [Command to use after uninstallation of a shared archive])
-_LT_DECL([], [finish_cmds], [2],
- [Commands used to finish a libtool library installation in a directory])
-_LT_DECL([], [finish_eval], [1],
- [[As "finish_cmds", except a single script fragment to be evaled but
- not shown]])
-_LT_DECL([], [hardcode_into_libs], [0],
- [Whether we should hardcode library paths into libraries])
-_LT_DECL([], [sys_lib_search_path_spec], [2],
- [Compile-time system search path for libraries])
-_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
- [Run-time system search path for libraries])
-])# _LT_SYS_DYNAMIC_LINKER
-
-
-# _LT_PATH_TOOL_PREFIX(TOOL)
-# --------------------------
-# find a file program which can recognize shared library
-AC_DEFUN([_LT_PATH_TOOL_PREFIX],
-[m4_require([_LT_DECL_EGREP])dnl
-AC_MSG_CHECKING([for $1])
-AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
-[case $MAGIC_CMD in
-[[\\/*] | ?:[\\/]*])
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-dnl $ac_dummy forces splitting on constant user-supplied paths.
-dnl POSIX.2 word splitting is done only on the output of word expansions,
-dnl not every word. This closes a longstanding sh security hole.
- ac_dummy="m4_if([$2], , $PATH, [$2])"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$1; then
- lt_cv_path_MAGIC_CMD="$ac_dir/$1"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<_LT_EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-_LT_EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac])
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- AC_MSG_RESULT($MAGIC_CMD)
-else
- AC_MSG_RESULT(no)
-fi
-_LT_DECL([], [MAGIC_CMD], [0],
- [Used to examine libraries when file_magic_cmd begins with "file"])dnl
-])# _LT_PATH_TOOL_PREFIX
-
-# Old name:
-AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
-
-
-# _LT_PATH_MAGIC
-# --------------
-# find a file program which can recognize a shared library
-m4_defun([_LT_PATH_MAGIC],
-[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
-if test -z "$lt_cv_path_MAGIC_CMD"; then
- if test -n "$ac_tool_prefix"; then
- _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
- else
- MAGIC_CMD=:
- fi
-fi
-])# _LT_PATH_MAGIC
-
-
-# LT_PATH_LD
-# ----------
-# find the pathname to the GNU or non-GNU linker
-AC_DEFUN([LT_PATH_LD],
-[AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-m4_require([_LT_DECL_SED])dnl
-m4_require([_LT_DECL_EGREP])dnl
-
-AC_ARG_WITH([gnu-ld],
- [AS_HELP_STRING([--with-gnu-ld],
- [assume the C compiler uses GNU ld @<:@default=no@:>@])],
- [test "$withval" = no || with_gnu_ld=yes],
- [with_gnu_ld=no])dnl
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- AC_MSG_CHECKING([for ld used by $CC])
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [[\\/]]* | ?:[[\\/]]*)
- re_direlt='/[[^/]][[^/]]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
- while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- AC_MSG_CHECKING([for GNU ld])
-else
- AC_MSG_CHECKING([for non-GNU ld])
-fi
-AC_CACHE_VAL(lt_cv_path_LD,
-[if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi])
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- AC_MSG_RESULT($LD)
-else
- AC_MSG_RESULT(no)
-fi
-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-_LT_PATH_LD_GNU
-AC_SUBST([LD])
-
-_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
-])# LT_PATH_LD
-
-# Old names:
-AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
-AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AM_PROG_LD], [])
-dnl AC_DEFUN([AC_PROG_LD], [])
-
-
-# _LT_PATH_LD_GNU
-#- --------------
-m4_defun([_LT_PATH_LD_GNU],
-[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac])
-with_gnu_ld=$lt_cv_prog_gnu_ld
-])# _LT_PATH_LD_GNU
-
-
-# _LT_CMD_RELOAD
-# --------------
-# find reload flag for linker
-# -- PORTME Some linkers may need a different reload flag.
-m4_defun([_LT_CMD_RELOAD],
-[AC_CACHE_CHECK([for $LD option to reload object files],
- lt_cv_ld_reload_flag,
- [lt_cv_ld_reload_flag='-r'])
-reload_flag=$lt_cv_ld_reload_flag
-case $reload_flag in
-"" | " "*) ;;
-*) reload_flag=" $reload_flag" ;;
-esac
-reload_cmds='$LD$reload_flag -o $output$reload_objs'
-case $host_os in
- darwin*)
- if test "$GCC" = yes; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
- else
- reload_cmds='$LD$reload_flag -o $output$reload_objs'
- fi
- ;;
-esac
-_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
-_LT_DECL([], [reload_cmds], [2])dnl
-])# _LT_CMD_RELOAD
-
-
-# _LT_CHECK_MAGIC_METHOD
-# ----------------------
-# how to check for library dependencies
-# -- PORTME fill in with the dynamic library characteristics
-m4_defun([_LT_CHECK_MAGIC_METHOD],
-[m4_require([_LT_DECL_EGREP])
-m4_require([_LT_DECL_OBJDUMP])
-AC_CACHE_CHECK([how to recognize dependent libraries],
-lt_cv_deplibs_check_method,
-[lt_cv_file_magic_cmd='$MAGIC_CMD'
-lt_cv_file_magic_test_file=
-lt_cv_deplibs_check_method='unknown'
-# Need to set the preceding variable on all platforms that support
-# interlibrary dependencies.
-# 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
-# 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
-# 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
-
-case $host_os in
-aix[[4-9]]*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-beos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-bsdi[[45]]*)
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- lt_cv_file_magic_test_file=/shlib/libc.so
- ;;
-
-cygwin*)
- # func_win32_libid is a shell function defined in ltmain.sh
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- ;;
-
-mingw* | pw32*)
- # Base MSYS/MinGW do not provide the 'file' command needed by
- # func_win32_libid shell function, so use a weaker test based on 'objdump',
- # unless we find 'file', for example because we are cross-compiling.
- if ( file / ) >/dev/null 2>&1; then
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- else
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- fi
- ;;
-
-cegcc)
- # use the weaker test based on 'objdump'. See mingw*.
- lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- ;;
-
-darwin* | rhapsody*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-freebsd* | dragonfly*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
- case $host_cpu in
- i*86 )
- # Not sure whether the presence of OpenBSD here was a mistake.
- # Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
- ;;
- esac
- else
- lt_cv_deplibs_check_method=pass_all
- fi
- ;;
-
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-hpux10.20* | hpux11*)
- lt_cv_file_magic_cmd=/usr/bin/file
- case $host_cpu in
- ia64*)
- lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
- lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
- ;;
- hppa*64*)
- [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
- lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
- ;;
- *)
- lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
- lt_cv_file_magic_test_file=/usr/lib/libc.sl
- ;;
- esac
- ;;
-
-interix[[3-9]]*)
- # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-netbsd* | netbsdelf*-gnu)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
- fi
- ;;
-
-newos6*)
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=/usr/lib/libnls.so
- ;;
-
-*nto* | *qnx*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-openbsd*)
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
- fi
- ;;
-
-osf3* | osf4* | osf5*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-rdos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-solaris*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv4 | sysv4.3*)
- case $host_vendor in
- motorola)
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
- ;;
- ncr)
- lt_cv_deplibs_check_method=pass_all
- ;;
- sequent)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
- ;;
- sni)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
- lt_cv_file_magic_test_file=/lib/libc.so
- ;;
- siemens)
- lt_cv_deplibs_check_method=pass_all
- ;;
- pc)
- lt_cv_deplibs_check_method=pass_all
- ;;
- esac
- ;;
-
-tpf*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-esac
-])
-file_magic_cmd=$lt_cv_file_magic_cmd
-deplibs_check_method=$lt_cv_deplibs_check_method
-test -z "$deplibs_check_method" && deplibs_check_method=unknown
-
-_LT_DECL([], [deplibs_check_method], [1],
- [Method to check whether dependent libraries are shared objects])
-_LT_DECL([], [file_magic_cmd], [1],
- [Command to use when deplibs_check_method == "file_magic"])
-])# _LT_CHECK_MAGIC_METHOD
-
-
-# LT_PATH_NM
-# ----------
-# find the pathname to a BSD- or MS-compatible name lister
-AC_DEFUN([LT_PATH_NM],
-[AC_REQUIRE([AC_PROG_CC])dnl
-AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
-[if test -n "$NM"; then
- # Let the user override the test.
- lt_cv_path_NM="$NM"
-else
- lt_nm_to_check="${ac_tool_prefix}nm"
- if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
- lt_nm_to_check="$lt_nm_to_check nm"
- fi
- for lt_tmp_nm in $lt_nm_to_check; do
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- tmp_nm="$ac_dir/$lt_tmp_nm"
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
- # Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
- # nm: unknown option "B" ignored
- # Tru64's nm complains that /dev/null is an invalid object file
- case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
- */dev/null* | *'Invalid file or object type'*)
- lt_cv_path_NM="$tmp_nm -B"
- break
- ;;
- *)
- case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
- */dev/null*)
- lt_cv_path_NM="$tmp_nm -p"
- break
- ;;
- *)
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
- continue # so that we can try to find one that supports BSD flags
- ;;
- esac
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
- done
- : ${lt_cv_path_NM=no}
-fi])
-if test "$lt_cv_path_NM" != "no"; then
- NM="$lt_cv_path_NM"
-else
- # Didn't find any BSD compatible name lister, look for dumpbin.
- AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
- AC_SUBST([DUMPBIN])
- if test "$DUMPBIN" != ":"; then
- NM="$DUMPBIN"
- fi
-fi
-test -z "$NM" && NM=nm
-AC_SUBST([NM])
-_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
-
-AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
- [lt_cv_nm_interface="BSD nm"
- echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
- (eval "$ac_compile" 2>conftest.err)
- cat conftest.err >&AS_MESSAGE_LOG_FD
- (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
- (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
- cat conftest.err >&AS_MESSAGE_LOG_FD
- (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
- cat conftest.out >&AS_MESSAGE_LOG_FD
- if $GREP 'External.*some_variable' conftest.out > /dev/null; then
- lt_cv_nm_interface="MS dumpbin"
- fi
- rm -f conftest*])
-])# LT_PATH_NM
-
-# Old names:
-AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
-AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AM_PROG_NM], [])
-dnl AC_DEFUN([AC_PROG_NM], [])
-
-
-# LT_LIB_M
-# --------
-# check for math library
-AC_DEFUN([LT_LIB_M],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-LIBM=
-case $host in
-*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
- # These system don't have libm, or don't need it
- ;;
-*-ncr-sysv4.3*)
- AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
- AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
- ;;
-*)
- AC_CHECK_LIB(m, cos, LIBM="-lm")
- ;;
-esac
-AC_SUBST([LIBM])
-])# LT_LIB_M
-
-# Old name:
-AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_CHECK_LIBM], [])
-
-
-# _LT_COMPILER_NO_RTTI([TAGNAME])
-# -------------------------------
-m4_defun([_LT_COMPILER_NO_RTTI],
-[m4_require([_LT_TAG_COMPILER])dnl
-
-_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
-
-if test "$GCC" = yes; then
- _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
-
- _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
- lt_cv_prog_compiler_rtti_exceptions,
- [-fno-rtti -fno-exceptions], [],
- [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
-fi
-_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
- [Compiler flag to turn off builtin functions])
-])# _LT_COMPILER_NO_RTTI
-
-
-# _LT_CMD_GLOBAL_SYMBOLS
-# ----------------------
-m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([LT_PATH_NM])dnl
-AC_REQUIRE([LT_PATH_LD])dnl
-m4_require([_LT_DECL_SED])dnl
-m4_require([_LT_DECL_EGREP])dnl
-m4_require([_LT_TAG_COMPILER])dnl
-
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-AC_MSG_CHECKING([command to parse $NM output from $compiler object])
-AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
-[
-# These are sane defaults that work on at least a few old systems.
-# [They come from Ultrix. What could be older than Ultrix?!! ;)]
-
-# Character class describing NM global symbol codes.
-symcode='[[BCDEGRST]]'
-
-# Regexp to match symbols that can be accessed directly from C.
-sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
-
-# Define system-specific variables.
-case $host_os in
-aix*)
- symcode='[[BCDT]]'
- ;;
-cygwin* | mingw* | pw32* | cegcc*)
- symcode='[[ABCDGISTW]]'
- ;;
-hpux*)
- if test "$host_cpu" = ia64; then
- symcode='[[ABCDEGRST]]'
- fi
- ;;
-irix* | nonstopux*)
- symcode='[[BCDEGRST]]'
- ;;
-osf*)
- symcode='[[BCDEGQRST]]'
- ;;
-solaris*)
- symcode='[[BDRT]]'
- ;;
-sco3.2v5*)
- symcode='[[DT]]'
- ;;
-sysv4.2uw2*)
- symcode='[[DT]]'
- ;;
-sysv5* | sco5v6* | unixware* | OpenUNIX*)
- symcode='[[ABDT]]'
- ;;
-sysv4)
- symcode='[[DFNSTU]]'
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-case `$NM -V 2>&1` in
-*GNU* | *'with BFD'*)
- symcode='[[ABCDGIRSTW]]' ;;
-esac
-
-# Transform an extracted symbol line into a proper C declaration.
-# Some systems (esp. on ia64) link data and code symbols differently,
-# so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
-
-# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
-
-# Handle CRLF in mingw tool chain
-opt_cr=
-case $build_os in
-mingw*)
- opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
- ;;
-esac
-
-# Try without a prefix underscore, then with it.
-for ac_symprfx in "" "_"; do
-
- # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
- symxfrm="\\1 $ac_symprfx\\2 \\2"
-
- # Write the raw and C identifiers.
- if test "$lt_cv_nm_interface" = "MS dumpbin"; then
- # Fake it for dumpbin and say T for any non-static function
- # and D for any global variable.
- # Also find C++ and __fastcall symbols from MSVC++,
- # which start with @ or ?.
- lt_cv_sys_global_symbol_pipe="$AWK ['"\
-" {last_section=section; section=\$ 3};"\
-" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-" \$ 0!~/External *\|/{next};"\
-" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
-" {if(hide[section]) next};"\
-" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
-" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
-" s[1]~/^[@?]/{print s[1], s[1]; next};"\
-" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
-" ' prfx=^$ac_symprfx]"
- else
- lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
- fi
-
- # Check to see that the pipe works correctly.
- pipe_works=no
-
- rm -f conftest*
- cat > conftest.$ac_ext <<_LT_EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(void);
-void nm_test_func(void){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func();return(0);}
-_LT_EOF
-
- if AC_TRY_EVAL(ac_compile); then
- # Now try to grab the symbols.
- nlist=conftest.nm
- if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
- # Try sorting and uniquifying the output.
- if sort "$nlist" | uniq > "$nlist"T; then
- mv -f "$nlist"T "$nlist"
- else
- rm -f "$nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
- if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
- cat <<_LT_EOF > conftest.$ac_ext
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-_LT_EOF
- # Now generate the symbol file.
- eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
-
- cat <<_LT_EOF >> conftest.$ac_ext
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- void *address;
-}
-lt__PROGRAM__LTX_preloaded_symbols[[]] =
-{
- { "@PROGRAM@", (void *) 0 },
-_LT_EOF
- $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
- cat <<\_LT_EOF >> conftest.$ac_ext
- {0, (void *) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
- return lt__PROGRAM__LTX_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-_LT_EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- lt_save_LIBS="$LIBS"
- lt_save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
- if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
- pipe_works=yes
- fi
- LIBS="$lt_save_LIBS"
- CFLAGS="$lt_save_CFLAGS"
- else
- echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
- fi
- else
- echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
- fi
- else
- echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
- fi
- else
- echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
- cat conftest.$ac_ext >&5
- fi
- rm -rf conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$pipe_works" = yes; then
- break
- else
- lt_cv_sys_global_symbol_pipe=
- fi
-done
-])
-if test -z "$lt_cv_sys_global_symbol_pipe"; then
- lt_cv_sys_global_symbol_to_cdecl=
-fi
-if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
- AC_MSG_RESULT(failed)
-else
- AC_MSG_RESULT(ok)
-fi
-
-_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
- [Take the output of nm and produce a listing of raw symbols and C names])
-_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
- [Transform the output of nm in a proper C declaration])
-_LT_DECL([global_symbol_to_c_name_address],
- [lt_cv_sys_global_symbol_to_c_name_address], [1],
- [Transform the output of nm in a C name address pair])
-_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
- [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
- [Transform the output of nm in a C name address pair when lib prefix is needed])
-]) # _LT_CMD_GLOBAL_SYMBOLS
-
-
-# _LT_COMPILER_PIC([TAGNAME])
-# ---------------------------
-m4_defun([_LT_COMPILER_PIC],
-[m4_require([_LT_TAG_COMPILER])dnl
-_LT_TAGVAR(lt_prog_compiler_wl, $1)=
-_LT_TAGVAR(lt_prog_compiler_pic, $1)=
-_LT_TAGVAR(lt_prog_compiler_static, $1)=
-
-AC_MSG_CHECKING([for $compiler option to produce PIC])
-m4_if([$1], [CXX], [
- # C++ specific cases for pic, static, wl, etc.
- if test "$GXX" = yes; then
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- m68k)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
- ;;
- esac
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
- mingw* | cygwin* | os2* | pw32* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- m4_if([$1], [GCJ], [],
- [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- ;;
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
- ;;
- *djgpp*)
- # DJGPP does not support shared libraries at all
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=
- ;;
- interix[[3-9]]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
- fi
- ;;
- hpux*)
- # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
- # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
- # sets the default TLS model and affects inlining.
- case $host_cpu in
- hppa*64*)
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- ;;
- *qnx* | *nto*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- else
- case $host_os in
- aix[[4-9]]*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- else
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- chorus*)
- case $cc_basename in
- cxch68*)
- # Green Hills C++ Compiler
- # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
- ;;
- esac
- ;;
- dgux*)
- case $cc_basename in
- ec++*)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- freebsd* | dragonfly*)
- # FreeBSD uses GNU C++
- ;;
- hpux9* | hpux10* | hpux11*)
- case $cc_basename in
- CC*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
- if test "$host_cpu" != ia64; then
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
- fi
- ;;
- aCC*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
- ;;
- esac
- ;;
- *)
- ;;
- esac
- ;;
- interix*)
- # This is c89, which is MS Visual C++ (no shared libs)
- # Anyone wants to do a port?
- ;;
- irix5* | irix6* | nonstopux*)
- case $cc_basename in
- CC*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- # CC pic flag -KPIC is the default.
- ;;
- *)
- ;;
- esac
- ;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- KCC*)
- # KAI C++ Compiler
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- ecpc* )
- # old Intel C++ for x86_64 which still supported -KPIC.
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- icpc* )
- # Intel C++, used to be incompatible with GCC.
- # ICC 10 doesn't accept -KPIC any more.
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- pgCC* | pgcpp*)
- # Portland Group C++ compiler
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- cxx*)
- # Compaq C++
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
- xlc* | xlC*)
- # IBM XL 8.0 on PPC
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
- ;;
- esac
- ;;
- esac
- ;;
- lynxos*)
- ;;
- m88k*)
- ;;
- mvs*)
- case $cc_basename in
- cxx*)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
- ;;
- *)
- ;;
- esac
- ;;
- netbsd* | netbsdelf*-gnu)
- ;;
- *qnx* | *nto*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
- ;;
- osf3* | osf4* | osf5*)
- case $cc_basename in
- KCC*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
- ;;
- RCC*)
- # Rational C++ 2.4.1
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- ;;
- cxx*)
- # Digital/Compaq C++
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
- *)
- ;;
- esac
- ;;
- psos*)
- ;;
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
- ;;
- gcx*)
- # Green Hills C++ Compiler
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
- ;;
- *)
- ;;
- esac
- ;;
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- lcc*)
- # Lucid
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- case $cc_basename in
- CC*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- esac
- ;;
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- ;;
- *)
- ;;
- esac
- ;;
- vxworks*)
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- ;;
- esac
- fi
-],
-[
- if test "$GCC" = yes; then
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- m68k)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
- ;;
- esac
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- m4_if([$1], [GCJ], [],
- [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
- ;;
-
- hpux*)
- # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
- # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
- # sets the default TLS model and affects inlining.
- case $host_cpu in
- hppa*64*)
- # +Z the default
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- ;;
-
- interix[[3-9]]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- enable_shared=no
- ;;
-
- *nto* | *qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
- fi
- ;;
-
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- else
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
-
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- m4_if([$1], [GCJ], [],
- [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- ;;
-
- hpux9* | hpux10* | hpux11*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # PIC (with -KPIC) is the default.
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
-
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- # old Intel for x86_64 which still supported -KPIC.
- ecc*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- # icc used to be incompatible with GCC.
- # ICC 10 doesn't accept -KPIC any more.
- icc* | ifort*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- # Lahey Fortran 8.1.
- lf95*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- ccc*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # All Alpha code is PIC.
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
- xl*)
- # IBM XL C 8.0/Fortran 10.1 on PPC
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C 5.9
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- ;;
- *Sun\ F*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
- ;;
- esac
- ;;
- esac
- ;;
-
- newsos6)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- *nto* | *qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
- ;;
-
- osf3* | osf4* | osf5*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # All OSF/1 code is PIC.
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
-
- rdos*)
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
-
- solaris*)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
- *)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
- esac
- ;;
-
- sunos4*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- unicos*)
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- ;;
-
- uts4*)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- *)
- _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- ;;
- esac
- fi
-])
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)=
- ;;
- *)
- _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
- ;;
-esac
-AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
-_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
- [How to pass a linker flag through the compiler])
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
- _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
- [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
- [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
- [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
- "" | " "*) ;;
- *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
- esac],
- [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
- _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
-fi
-_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
- [Additional compiler flags for building library objects])
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
-_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
- _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
- $lt_tmp_static_flag,
- [],
- [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
-_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
- [Compiler flag to prevent dynamic linking])
-])# _LT_COMPILER_PIC
-
-
-# _LT_LINKER_SHLIBS([TAGNAME])
-# ----------------------------
-# See if the linker supports building shared libraries.
-m4_defun([_LT_LINKER_SHLIBS],
-[AC_REQUIRE([LT_PATH_LD])dnl
-AC_REQUIRE([LT_PATH_NM])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_DECL_EGREP])dnl
-m4_require([_LT_DECL_SED])dnl
-m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
-m4_require([_LT_TAG_COMPILER])dnl
-AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
-m4_if([$1], [CXX], [
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- case $host_os in
- aix[[4-9]]*)
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- else
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- fi
- ;;
- pw32*)
- _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
- ;;
- cygwin* | mingw* | cegcc*)
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
- linux* | k*bsd*-gnu)
- _LT_TAGVAR(link_all_deplibs, $1)=no
- ;;
- *)
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
- esac
- _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
-], [
- runpath_var=
- _LT_TAGVAR(allow_undefined_flag, $1)=
- _LT_TAGVAR(always_export_symbols, $1)=no
- _LT_TAGVAR(archive_cmds, $1)=
- _LT_TAGVAR(archive_expsym_cmds, $1)=
- _LT_TAGVAR(compiler_needs_object, $1)=no
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
- _LT_TAGVAR(export_dynamic_flag_spec, $1)=
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- _LT_TAGVAR(hardcode_automatic, $1)=no
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_direct_absolute, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
- _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
- _LT_TAGVAR(hardcode_libdir_separator, $1)=
- _LT_TAGVAR(hardcode_minus_L, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_TAGVAR(inherit_rpath, $1)=no
- _LT_TAGVAR(link_all_deplibs, $1)=unknown
- _LT_TAGVAR(module_cmds, $1)=
- _LT_TAGVAR(module_expsym_cmds, $1)=
- _LT_TAGVAR(old_archive_from_new_cmds, $1)=
- _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
- _LT_TAGVAR(thread_safe_flag_spec, $1)=
- _LT_TAGVAR(whole_archive_flag_spec, $1)=
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- _LT_TAGVAR(include_expsyms, $1)=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- # Exclude shared library initialization/finalization symbols.
-dnl Note also adjust exclude_expsyms for C++ above.
- extract_expsyms_cmds=
-
- case $host_os in
- cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- linux* | k*bsd*-gnu)
- _LT_TAGVAR(link_all_deplibs, $1)=no
- ;;
- esac
-
- _LT_TAGVAR(ld_shlibs, $1)=yes
- if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- _LT_TAGVAR(whole_archive_flag_spec, $1)=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>&1` in
- *GNU\ gold*) supports_anon_versioning=yes ;;
- *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix[[3-9]]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- _LT_TAGVAR(ld_shlibs, $1)=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-_LT_EOF
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)=''
- ;;
- m68k)
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- ;;
- esac
- ;;
-
- beos*)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
- # as there is no search path for DLLs.
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(always_export_symbols, $1)=no
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- interix[[3-9]]*)
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
- tmp_diet=no
- if test "$host_os" = linux-dietlibc; then
- case $cc_basename in
- diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
- esac
- fi
- if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
- && test "$tmp_diet" = no
- then
- tmp_addflag=
- tmp_sharedflag='-shared'
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- lf95*) # Lahey Fortran 8.1
- _LT_TAGVAR(whole_archive_flag_spec, $1)=
- tmp_sharedflag='--shared' ;;
- xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
- tmp_sharedflag='-qmkshrobj'
- tmp_addflag= ;;
- esac
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*) # Sun C 5.9
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- _LT_TAGVAR(compiler_needs_object, $1)=yes
- tmp_sharedflag='-G' ;;
- *Sun\ F*) # Sun Fortran 8.3
- tmp_sharedflag='-G' ;;
- esac
- _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test "x$supports_anon_versioning" = xyes; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
-
- case $cc_basename in
- xlf*)
- # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
- _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
- _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
- _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
- fi
- ;;
- esac
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- netbsd* | netbsdelf*-gnu)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
- _LT_TAGVAR(ld_shlibs, $1)=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
- _LT_TAGVAR(ld_shlibs, $1)=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- # For security reasons, it is highly recommended that you always
- # use absolute paths for naming shared libraries, and exclude the
- # DT_RUNPATH tag from executables and libraries. But doing so
- # requires that you compile everything twice, which is a pain.
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- *)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
-
- if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
- runpath_var=
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
- _LT_TAGVAR(export_dynamic_flag_spec, $1)=
- _LT_TAGVAR(whole_archive_flag_spec, $1)=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(always_export_symbols, $1)=yes
- _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- _LT_TAGVAR(hardcode_direct, $1)=unsupported
- fi
- ;;
-
- aix[[4-9]]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- else
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- _LT_TAGVAR(archive_cmds, $1)=''
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[[012]]|aix4.[[012]].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" &&
- strings "$collect2name" | $GREP resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- _LT_TAGVAR(hardcode_direct, $1)=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- _LT_TAGVAR(link_all_deplibs, $1)=no
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- _LT_TAGVAR(always_export_symbols, $1)=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
- # Determine the default libpath from the value encoded in an
- # empty executable.
- _LT_SYS_MODULE_PATH_AIX
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
- _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an
- # empty executable.
- _LT_SYS_MODULE_PATH_AIX
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)=''
- ;;
- m68k)
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- ;;
- esac
- ;;
-
- bsdi[[45]]*)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
- # FIXME: Should let the user specify the lib program.
- _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
- _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- ;;
-
- darwin* | rhapsody*)
- _LT_DARWIN_LINKER_FEATURES($1)
- ;;
-
- dgux*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- freebsd1*)
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | dragonfly*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(hardcode_direct, $1)=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
- *)
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- # Try to use the -exported_symbol ld option, if it does not
- # work, assume that -exports_file does not work either and
- # implicitly export all symbols.
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
- AC_LINK_IFELSE(int foo(void) {},
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
- )
- LDFLAGS="$save_LDFLAGS"
- else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
- fi
- _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(inherit_rpath, $1)=yes
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- ;;
-
- netbsd* | netbsdelf*-gnu)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- newsos6)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- *nto* | *qnx*)
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- else
- case $host_os in
- openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- os2*)
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- else
- _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
- fi
- _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- ;;
-
- solaris*)
- _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
- else
- case `$CC -V 2>&1` in
- *"Compilers 5.0"*)
- wlarc=''
- _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
- ;;
- *)
- wlarc='${wl}'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
- ;;
- esac
- fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- case $host_os in
- solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'. GCC discards it without `$wl',
- # but is careful enough not to reorder.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- if test "$GCC" = yes; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- else
- _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
- fi
- ;;
- esac
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
- _LT_TAGVAR(hardcode_direct, $1)=no
- ;;
- motorola)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- sysv4.3*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- _LT_TAGVAR(ld_shlibs, $1)=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- *)
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
-
- if test x$host_vendor = xsni; then
- case $host in
- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
- ;;
- esac
- fi
- fi
-])
-AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
-
-_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
-
-_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
-_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
-_LT_DECL([], [extract_expsyms_cmds], [2],
- [The commands to extract the exported symbol list from a shared archive])
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
-x|xyes)
- # Assume -lc should be added
- _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $_LT_TAGVAR(archive_cmds, $1) in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- AC_MSG_CHECKING([whether -lc should be explicitly linked in])
- $RM conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
- pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
- _LT_TAGVAR(allow_undefined_flag, $1)=
- if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
- then
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- else
- _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- fi
- _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $RM conftest*
- AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
- ;;
- esac
- fi
- ;;
-esac
-
-_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
- [Whether or not to add -lc for building shared libraries])
-_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
- [enable_shared_with_static_runtimes], [0],
- [Whether or not to disallow shared libs when runtime libs are static])
-_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
- [Compiler flag to allow reflexive dlopens])
-_LT_TAGDECL([], [whole_archive_flag_spec], [1],
- [Compiler flag to generate shared objects directly from archives])
-_LT_TAGDECL([], [compiler_needs_object], [1],
- [Whether the compiler copes with passing no objects directly])
-_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
- [Create an old-style archive from a shared archive])
-_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
- [Create a temporary old-style archive to link instead of a shared archive])
-_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
-_LT_TAGDECL([], [archive_expsym_cmds], [2])
-_LT_TAGDECL([], [module_cmds], [2],
- [Commands used to build a loadable module if different from building
- a shared archive.])
-_LT_TAGDECL([], [module_expsym_cmds], [2])
-_LT_TAGDECL([], [with_gnu_ld], [1],
- [Whether we are building with GNU ld or not])
-_LT_TAGDECL([], [allow_undefined_flag], [1],
- [Flag that allows shared libraries with undefined symbols to be built])
-_LT_TAGDECL([], [no_undefined_flag], [1],
- [Flag that enforces no undefined symbols])
-_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
- [Flag to hardcode $libdir into a binary during linking.
- This must work even if $libdir does not exist])
-_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
- [[If ld is used when linking, flag to hardcode $libdir into a binary
- during linking. This must work even if $libdir does not exist]])
-_LT_TAGDECL([], [hardcode_libdir_separator], [1],
- [Whether we need a single "-rpath" flag with a separated argument])
-_LT_TAGDECL([], [hardcode_direct], [0],
- [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
- DIR into the resulting binary])
-_LT_TAGDECL([], [hardcode_direct_absolute], [0],
- [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
- DIR into the resulting binary and the resulting library dependency is
- "absolute", i.e impossible to change by setting ${shlibpath_var} if the
- library is relocated])
-_LT_TAGDECL([], [hardcode_minus_L], [0],
- [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
- into the resulting binary])
-_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
- [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
- into the resulting binary])
-_LT_TAGDECL([], [hardcode_automatic], [0],
- [Set to "yes" if building a shared library automatically hardcodes DIR
- into the library and all subsequent libraries and executables linked
- against it])
-_LT_TAGDECL([], [inherit_rpath], [0],
- [Set to yes if linker adds runtime paths of dependent libraries
- to runtime path list])
-_LT_TAGDECL([], [link_all_deplibs], [0],
- [Whether libtool must link a program against all its dependency libraries])
-_LT_TAGDECL([], [fix_srcfile_path], [1],
- [Fix the shell variable $srcfile for the compiler])
-_LT_TAGDECL([], [always_export_symbols], [0],
- [Set to "yes" if exported symbols are required])
-_LT_TAGDECL([], [export_symbols_cmds], [2],
- [The commands to list exported symbols])
-_LT_TAGDECL([], [exclude_expsyms], [1],
- [Symbols that should not be listed in the preloaded symbols])
-_LT_TAGDECL([], [include_expsyms], [1],
- [Symbols that must always be exported])
-_LT_TAGDECL([], [prelink_cmds], [2],
- [Commands necessary for linking programs (against libraries) with templates])
-_LT_TAGDECL([], [file_list_spec], [1],
- [Specify filename containing input files])
-dnl FIXME: Not yet implemented
-dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
-dnl [Compiler flag to generate thread safe objects])
-])# _LT_LINKER_SHLIBS
-
-
-# _LT_LANG_C_CONFIG([TAG])
-# ------------------------
-# Ensure that the configuration variables for a C compiler are suitably
-# defined. These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_C_CONFIG],
-[m4_require([_LT_DECL_EGREP])dnl
-lt_save_CC="$CC"
-AC_LANG_PUSH(C)
-
-# Source file extension for C test sources.
-ac_ext=c
-
-# Object file extension for compiled C test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}'
-
-_LT_TAG_COMPILER
-# Save the default compiler, since it gets overwritten when the other
-# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
-compiler_DEFAULT=$CC
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-if test -n "$compiler"; then
- _LT_COMPILER_NO_RTTI($1)
- _LT_COMPILER_PIC($1)
- _LT_COMPILER_C_O($1)
- _LT_COMPILER_FILE_LOCKS($1)
- _LT_LINKER_SHLIBS($1)
- _LT_SYS_DYNAMIC_LINKER($1)
- _LT_LINKER_HARDCODE_LIBPATH($1)
- LT_SYS_DLOPEN_SELF
- _LT_CMD_STRIPLIB
-
- # Report which library types will actually be built
- AC_MSG_CHECKING([if libtool supports shared libraries])
- AC_MSG_RESULT([$can_build_shared])
-
- AC_MSG_CHECKING([whether to build shared libraries])
- test "$can_build_shared" = "no" && enable_shared=no
-
- # On AIX, shared libraries and static libraries use the same namespace, and
- # are all built from PIC.
- case $host_os in
- aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-
- aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
- esac
- AC_MSG_RESULT([$enable_shared])
-
- AC_MSG_CHECKING([whether to build static libraries])
- # Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
- AC_MSG_RESULT([$enable_static])
-
- _LT_CONFIG($1)
-fi
-AC_LANG_POP
-CC="$lt_save_CC"
-])# _LT_LANG_C_CONFIG
-
-
-# _LT_PROG_CXX
-# ------------
-# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
-# compiler, we have our own version here.
-m4_defun([_LT_PROG_CXX],
-[
-pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
-AC_PROG_CXX
-if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- AC_PROG_CXXCPP
-else
- _lt_caught_CXX_error=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_CXX
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_CXX], [])
-
-
-# _LT_LANG_CXX_CONFIG([TAG])
-# --------------------------
-# Ensure that the configuration variables for a C++ compiler are suitably
-# defined. These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_CXX_CONFIG],
-[AC_REQUIRE([_LT_PROG_CXX])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-m4_require([_LT_DECL_EGREP])dnl
-
-AC_LANG_PUSH(C++)
-_LT_TAGVAR(archive_cmds_need_lc, $1)=no
-_LT_TAGVAR(allow_undefined_flag, $1)=
-_LT_TAGVAR(always_export_symbols, $1)=no
-_LT_TAGVAR(archive_expsym_cmds, $1)=
-_LT_TAGVAR(compiler_needs_object, $1)=no
-_LT_TAGVAR(export_dynamic_flag_spec, $1)=
-_LT_TAGVAR(hardcode_direct, $1)=no
-_LT_TAGVAR(hardcode_direct_absolute, $1)=no
-_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
-_LT_TAGVAR(hardcode_libdir_separator, $1)=
-_LT_TAGVAR(hardcode_minus_L, $1)=no
-_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-_LT_TAGVAR(hardcode_automatic, $1)=no
-_LT_TAGVAR(inherit_rpath, $1)=no
-_LT_TAGVAR(module_cmds, $1)=
-_LT_TAGVAR(module_expsym_cmds, $1)=
-_LT_TAGVAR(link_all_deplibs, $1)=unknown
-_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-_LT_TAGVAR(no_undefined_flag, $1)=
-_LT_TAGVAR(whole_archive_flag_spec, $1)=
-_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
-
-# Source file extension for C++ test sources.
-ac_ext=cpp
-
-# Object file extension for compiled C++ test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# No sense in running all these tests if we already determined that
-# the CXX compiler isn't working. Some variables (like enable_shared)
-# are currently assumed to apply to all compilers on this platform,
-# and will be corrupted by setting them based on a non-working compiler.
-if test "$_lt_caught_CXX_error" != yes; then
- # Code to be used in simple compile tests
- lt_simple_compile_test_code="int some_variable = 0;"
-
- # Code to be used in simple link tests
- lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
-
- # ltmain only uses $CC for tagged configurations so make sure $CC is set.
- _LT_TAG_COMPILER
-
- # save warnings/boilerplate of simple test code
- _LT_COMPILER_BOILERPLATE
- _LT_LINKER_BOILERPLATE
-
- # Allow CC to be a program name with arguments.
- lt_save_CC=$CC
- lt_save_LD=$LD
- lt_save_GCC=$GCC
- GCC=$GXX
- lt_save_with_gnu_ld=$with_gnu_ld
- lt_save_path_LD=$lt_cv_path_LD
- if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
- lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
- else
- $as_unset lt_cv_prog_gnu_ld
- fi
- if test -n "${lt_cv_path_LDCXX+set}"; then
- lt_cv_path_LD=$lt_cv_path_LDCXX
- else
- $as_unset lt_cv_path_LD
- fi
- test -z "${LDCXX+set}" || LD=$LDCXX
- CC=${CXX-"c++"}
- compiler=$CC
- _LT_TAGVAR(compiler, $1)=$CC
- _LT_CC_BASENAME([$compiler])
-
- if test -n "$compiler"; then
- # We don't want -fno-exception when compiling C++ code, so set the
- # no_builtin_flag separately
- if test "$GXX" = yes; then
- _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
- else
- _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
- fi
-
- if test "$GXX" = yes; then
- # Set up default GNU C++ configuration
-
- LT_PATH_LD
-
- # Check if GNU C++ uses GNU ld as the underlying linker, since the
- # archiving commands below assume that GNU ld is being used.
- if test "$with_gnu_ld" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-
- # If archive_cmds runs LD, not CC, wlarc should be empty
- # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
- # investigate it a little bit more. (MM)
- wlarc='${wl}'
-
- # ancient GNU ld didn't support --whole-archive et. al.
- if eval "`$CC -print-prog-name=ld` --help 2>&1" |
- $GREP 'no-whole-archive' > /dev/null; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- _LT_TAGVAR(whole_archive_flag_spec, $1)=
- fi
- else
- with_gnu_ld=no
- wlarc=
-
- # A generic and very simple default shared library creation
- # command for GNU C++ for the case where it uses the native
- # linker, instead of GNU ld. If possible, this setting should
- # overridden to take advantage of the native linker features on
- # the platform it is being used on.
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- fi
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
-
- else
- GXX=no
- with_gnu_ld=no
- wlarc=
- fi
-
- # PORTME: fill in a description of your system's C++ link characteristics
- AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
- _LT_TAGVAR(ld_shlibs, $1)=yes
- case $host_os in
- aix3*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- aix[[4-9]]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
- for ld_flag in $LDFLAGS; do
- case $ld_flag in
- *-brtl*)
- aix_use_runtimelinking=yes
- break
- ;;
- esac
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- _LT_TAGVAR(archive_cmds, $1)=''
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
-
- if test "$GXX" = yes; then
- case $host_os in aix4.[[012]]|aix4.[[012]].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" &&
- strings "$collect2name" | $GREP resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- _LT_TAGVAR(hardcode_direct, $1)=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=
- fi
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to
- # export.
- _LT_TAGVAR(always_export_symbols, $1)=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
- # Determine the default libpath from the value encoded in an empty
- # executable.
- _LT_SYS_MODULE_PATH_AIX
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
-
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
- _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an
- # empty executable.
- _LT_SYS_MODULE_PATH_AIX
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds its shared
- # libraries.
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- beos*)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- chorus*)
- case $cc_basename in
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
- # as there is no search path for DLLs.
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(always_export_symbols, $1)=no
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-
- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- darwin* | rhapsody*)
- _LT_DARWIN_LINKER_FEATURES($1)
- ;;
-
- dgux*)
- case $cc_basename in
- ec++*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- freebsd[[12]]*)
- # C++ shared libraries reported to be fairly broken before
- # switch to ELF
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- freebsd-elf*)
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- ;;
-
- freebsd* | dragonfly*)
- # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
- # conventions
- _LT_TAGVAR(ld_shlibs, $1)=yes
- ;;
-
- gnu*)
- ;;
-
- hpux9*)
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
- # but as the default
- # location of the library.
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- aCC*)
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
- ;;
- *)
- if test "$GXX" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
-
- hpux10*|hpux11*)
- if test $with_gnu_ld = no; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- ;;
- *)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- ;;
- esac
- fi
- case $host_cpu in
- hppa*64*|ia64*)
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
- *)
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
- # but as the default
- # location of the library.
- ;;
- esac
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- aCC*)
- case $host_cpu in
- hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
- ;;
- *)
- if test "$GXX" = yes; then
- if test $with_gnu_ld = no; then
- case $host_cpu in
- hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- fi
- else
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
-
- interix[[3-9]]*)
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
- irix5* | irix6*)
- case $cc_basename in
- CC*)
- # SGI C++
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
-
- # Archives containing C++ object files must be created using
- # "CC -ar", where "CC" is the IRIX C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
- ;;
- *)
- if test "$GXX" = yes; then
- if test "$with_gnu_ld" = no; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
- fi
- fi
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- ;;
- esac
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(inherit_rpath, $1)=yes
- ;;
-
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-
- # Archives containing C++ object files must be created using
- # "CC -Bstatic", where "CC" is the KAI C++ compiler.
- _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
- ;;
- icpc* | ecpc* )
- # Intel C++
- with_gnu_ld=yes
- # version 8.0 and above of icpc choke on multiply defined symbols
- # if we add $predep_objects and $postdep_objects, however 7.1 and
- # earlier do not add the objects themselves.
- case `$CC -V 2>&1` in
- *"Version 7."*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- *) # Version 8.0 or newer
- tmp_idyn=
- case $host_cpu in
- ia64*) tmp_idyn=' -i_dynamic';;
- esac
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- esac
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
- ;;
- pgCC* | pgcpp*)
- # Portland Group C++ compiler
- case `$CC -V` in
- *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
- _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
- compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
- _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
- $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
- $RANLIB $oldlib'
- _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
- ;;
- *) # Version 6 will use weak symbols
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
- ;;
- esac
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- ;;
- cxx*)
- # Compaq C++
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
-
- runpath_var=LD_RUN_PATH
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
- ;;
- xl*)
- # IBM XL 8.0 on PPC, with GNU ld
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- _LT_TAGVAR(compiler_needs_object, $1)=yes
-
- # Not sure whether something based on
- # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
- # would be better.
- output_verbose_link_cmd='echo'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
- ;;
- esac
- ;;
- esac
- ;;
-
- lynxos*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- m88k*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- mvs*)
- case $cc_basename in
- cxx*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
- wlarc=
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- fi
- # Workaround some broken pre-1.5 toolchains
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
- ;;
-
- *nto* | *qnx*)
- _LT_TAGVAR(ld_shlibs, $1)=yes
- ;;
-
- openbsd2*)
- # C++ shared libraries are fairly broken
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- _LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- fi
- output_verbose_link_cmd=echo
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- osf3* | osf4* | osf5*)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Archives containing C++ object files must be created using
- # the KAI C++ compiler.
- case $host in
- osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
- *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
- esac
- ;;
- RCC*)
- # Rational C++ 2.4.1
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- cxx*)
- case $host in
- osf3*)
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- ;;
- *)
- _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
- echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
- $RM $lib.exp'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
- ;;
- esac
-
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
- ;;
- *)
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- case $host in
- osf3*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- ;;
- esac
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
-
- else
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
-
- psos*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- lcc*)
- # Lucid
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
- _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- case $host_os in
- solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
- ;;
- esac
- _LT_TAGVAR(link_all_deplibs, $1)=yes
-
- output_verbose_link_cmd='echo'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
- ;;
- gcx*)
- # Green Hills C++ Compiler
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
-
- # The C++ compiler must be used to create the archive.
- _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
- ;;
- *)
- # GNU C++ compiler with Solaris linker
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
- if $CC --version | $GREP -v '^2\.7' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
- else
- # g++ 2.7 appears to require `-G' NOT `-shared' on this
- # platform.
- _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
- fi
-
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
- case $host_os in
- solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *)
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- ;;
- esac
- fi
- ;;
- esac
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
- _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
-
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- vxworks*)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- *)
- # FIXME: insert proper C++ library support
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
-
- AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
- test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
-
- _LT_TAGVAR(GCC, $1)="$GXX"
- _LT_TAGVAR(LD, $1)="$LD"
-
- ## CAVEAT EMPTOR:
- ## There is no encapsulation within the following macros, do not change
- ## the running order or otherwise move them around unless you know exactly
- ## what you are doing...
- _LT_SYS_HIDDEN_LIBDEPS($1)
- _LT_COMPILER_PIC($1)
- _LT_COMPILER_C_O($1)
- _LT_COMPILER_FILE_LOCKS($1)
- _LT_LINKER_SHLIBS($1)
- _LT_SYS_DYNAMIC_LINKER($1)
- _LT_LINKER_HARDCODE_LIBPATH($1)
-
- _LT_CONFIG($1)
- fi # test -n "$compiler"
-
- CC=$lt_save_CC
- LDCXX=$LD
- LD=$lt_save_LD
- GCC=$lt_save_GCC
- with_gnu_ld=$lt_save_with_gnu_ld
- lt_cv_path_LDCXX=$lt_cv_path_LD
- lt_cv_path_LD=$lt_save_path_LD
- lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
- lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test "$_lt_caught_CXX_error" != yes
-
-AC_LANG_POP
-])# _LT_LANG_CXX_CONFIG
-
-
-# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
-# ---------------------------------
-# Figure out "hidden" library dependencies from verbose
-# compiler output when linking a shared library.
-# Parse the compiler output and extract the necessary
-# objects, libraries and library flags.
-m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
-[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
-# Dependencies to place before and after the object being linked:
-_LT_TAGVAR(predep_objects, $1)=
-_LT_TAGVAR(postdep_objects, $1)=
-_LT_TAGVAR(predeps, $1)=
-_LT_TAGVAR(postdeps, $1)=
-_LT_TAGVAR(compiler_lib_search_path, $1)=
-
-dnl we can't use the lt_simple_compile_test_code here,
-dnl because it contains code intended for an executable,
-dnl not a library. It's possible we should let each
-dnl tag define a new lt_????_link_test_code variable,
-dnl but it's only used here...
-m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
-int a;
-void foo (void) { a = 0; }
-_LT_EOF
-], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
-class Foo
-{
-public:
- Foo (void) { a = 0; }
-private:
- int a;
-};
-_LT_EOF
-], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
- subroutine foo
- implicit none
- integer*4 a
- a=0
- return
- end
-_LT_EOF
-], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
- subroutine foo
- implicit none
- integer a
- a=0
- return
- end
-_LT_EOF
-], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
-public class foo {
- private int a;
- public void bar (void) {
- a = 0;
- }
-};
-_LT_EOF
-])
-dnl Parse the compiler output and extract the necessary
-dnl objects, libraries and library flags.
-if AC_TRY_EVAL(ac_compile); then
- # Parse the compiler output and extract the necessary
- # objects, libraries and library flags.
-
- # Sentinel used to keep track of whether or not we are before
- # the conftest object file.
- pre_test_object_deps_done=no
-
- for p in `eval "$output_verbose_link_cmd"`; do
- case $p in
-
- -L* | -R* | -l*)
- # Some compilers place space between "-{L,R}" and the path.
- # Remove the space.
- if test $p = "-L" ||
- test $p = "-R"; then
- prev=$p
- continue
- else
- prev=
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- case $p in
- -L* | -R*)
- # Internal compiler library paths should come after those
- # provided the user. The postdeps already come after the
- # user supplied libs so there is no need to process them.
- if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
- _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
- else
- _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
- fi
- ;;
- # The "-l" case would never come before the object being
- # linked, so don't bother handling this case.
- esac
- else
- if test -z "$_LT_TAGVAR(postdeps, $1)"; then
- _LT_TAGVAR(postdeps, $1)="${prev}${p}"
- else
- _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
- fi
- fi
- ;;
-
- *.$objext)
- # This assumes that the test object file only shows up
- # once in the compiler output.
- if test "$p" = "conftest.$objext"; then
- pre_test_object_deps_done=yes
- continue
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
- _LT_TAGVAR(predep_objects, $1)="$p"
- else
- _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
- fi
- else
- if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
- _LT_TAGVAR(postdep_objects, $1)="$p"
- else
- _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
- fi
- fi
- ;;
-
- *) ;; # Ignore the rest.
-
- esac
- done
-
- # Clean up.
- rm -f a.out a.exe
-else
- echo "libtool.m4: error: problem compiling $1 test program"
-fi
-
-$RM -f confest.$objext
-
-# PORTME: override above test on systems where it is broken
-m4_if([$1], [CXX],
-[case $host_os in
-interix[[3-9]]*)
- # Interix 3.5 installs completely hosed .la files for C++, so rather than
- # hack all around it, let's just trust "g++" to DTRT.
- _LT_TAGVAR(predep_objects,$1)=
- _LT_TAGVAR(postdep_objects,$1)=
- _LT_TAGVAR(postdeps,$1)=
- ;;
-
-linux*)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
-
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
-
- if test "$solaris_use_stlport4" != yes; then
- _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-
-solaris*)
- case $cc_basename in
- CC*)
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
-
- # Adding this requires a known-good setup of shared libraries for
- # Sun compiler versions before 5.6, else PIC objects from an old
- # archive will be linked into the output, leading to subtle bugs.
- if test "$solaris_use_stlport4" != yes; then
- _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-esac
-])
-
-case " $_LT_TAGVAR(postdeps, $1) " in
-*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
-esac
- _LT_TAGVAR(compiler_lib_search_dirs, $1)=
-if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
- _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
-fi
-_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
- [The directories searched by this compiler when creating a shared library])
-_LT_TAGDECL([], [predep_objects], [1],
- [Dependencies to place before and after the objects being linked to
- create a shared library])
-_LT_TAGDECL([], [postdep_objects], [1])
-_LT_TAGDECL([], [predeps], [1])
-_LT_TAGDECL([], [postdeps], [1])
-_LT_TAGDECL([], [compiler_lib_search_path], [1],
- [The library search path used internally by the compiler when linking
- a shared library])
-])# _LT_SYS_HIDDEN_LIBDEPS
-
-
-# _LT_PROG_F77
-# ------------
-# Since AC_PROG_F77 is broken, in that it returns the empty string
-# if there is no fortran compiler, we have our own version here.
-m4_defun([_LT_PROG_F77],
-[
-pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
-AC_PROG_F77
-if test -z "$F77" || test "X$F77" = "Xno"; then
- _lt_disable_F77=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_F77
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_F77], [])
-
-
-# _LT_LANG_F77_CONFIG([TAG])
-# --------------------------
-# Ensure that the configuration variables for a Fortran 77 compiler are
-# suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_F77_CONFIG],
-[AC_REQUIRE([_LT_PROG_F77])dnl
-AC_LANG_PUSH(Fortran 77)
-
-_LT_TAGVAR(archive_cmds_need_lc, $1)=no
-_LT_TAGVAR(allow_undefined_flag, $1)=
-_LT_TAGVAR(always_export_symbols, $1)=no
-_LT_TAGVAR(archive_expsym_cmds, $1)=
-_LT_TAGVAR(export_dynamic_flag_spec, $1)=
-_LT_TAGVAR(hardcode_direct, $1)=no
-_LT_TAGVAR(hardcode_direct_absolute, $1)=no
-_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
-_LT_TAGVAR(hardcode_libdir_separator, $1)=
-_LT_TAGVAR(hardcode_minus_L, $1)=no
-_LT_TAGVAR(hardcode_automatic, $1)=no
-_LT_TAGVAR(inherit_rpath, $1)=no
-_LT_TAGVAR(module_cmds, $1)=
-_LT_TAGVAR(module_expsym_cmds, $1)=
-_LT_TAGVAR(link_all_deplibs, $1)=unknown
-_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-_LT_TAGVAR(no_undefined_flag, $1)=
-_LT_TAGVAR(whole_archive_flag_spec, $1)=
-_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
-
-# Source file extension for f77 test sources.
-ac_ext=f
-
-# Object file extension for compiled f77 test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# No sense in running all these tests if we already determined that
-# the F77 compiler isn't working. Some variables (like enable_shared)
-# are currently assumed to apply to all compilers on this platform,
-# and will be corrupted by setting them based on a non-working compiler.
-if test "$_lt_disable_F77" != yes; then
- # Code to be used in simple compile tests
- lt_simple_compile_test_code="\
- subroutine t
- return
- end
-"
-
- # Code to be used in simple link tests
- lt_simple_link_test_code="\
- program t
- end
-"
-
- # ltmain only uses $CC for tagged configurations so make sure $CC is set.
- _LT_TAG_COMPILER
-
- # save warnings/boilerplate of simple test code
- _LT_COMPILER_BOILERPLATE
- _LT_LINKER_BOILERPLATE
-
- # Allow CC to be a program name with arguments.
- lt_save_CC="$CC"
- lt_save_GCC=$GCC
- CC=${F77-"f77"}
- compiler=$CC
- _LT_TAGVAR(compiler, $1)=$CC
- _LT_CC_BASENAME([$compiler])
- GCC=$G77
- if test -n "$compiler"; then
- AC_MSG_CHECKING([if libtool supports shared libraries])
- AC_MSG_RESULT([$can_build_shared])
-
- AC_MSG_CHECKING([whether to build shared libraries])
- test "$can_build_shared" = "no" && enable_shared=no
-
- # On AIX, shared libraries and static libraries use the same namespace, and
- # are all built from PIC.
- case $host_os in
- aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
- aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
- esac
- AC_MSG_RESULT([$enable_shared])
-
- AC_MSG_CHECKING([whether to build static libraries])
- # Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
- AC_MSG_RESULT([$enable_static])
-
- _LT_TAGVAR(GCC, $1)="$G77"
- _LT_TAGVAR(LD, $1)="$LD"
-
- ## CAVEAT EMPTOR:
- ## There is no encapsulation within the following macros, do not change
- ## the running order or otherwise move them around unless you know exactly
- ## what you are doing...
- _LT_COMPILER_PIC($1)
- _LT_COMPILER_C_O($1)
- _LT_COMPILER_FILE_LOCKS($1)
- _LT_LINKER_SHLIBS($1)
- _LT_SYS_DYNAMIC_LINKER($1)
- _LT_LINKER_HARDCODE_LIBPATH($1)
-
- _LT_CONFIG($1)
- fi # test -n "$compiler"
-
- GCC=$lt_save_GCC
- CC="$lt_save_CC"
-fi # test "$_lt_disable_F77" != yes
-
-AC_LANG_POP
-])# _LT_LANG_F77_CONFIG
-
-
-# _LT_PROG_FC
-# -----------
-# Since AC_PROG_FC is broken, in that it returns the empty string
-# if there is no fortran compiler, we have our own version here.
-m4_defun([_LT_PROG_FC],
-[
-pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
-AC_PROG_FC
-if test -z "$FC" || test "X$FC" = "Xno"; then
- _lt_disable_FC=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_FC
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_FC], [])
-
-
-# _LT_LANG_FC_CONFIG([TAG])
-# -------------------------
-# Ensure that the configuration variables for a Fortran compiler are
-# suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_FC_CONFIG],
-[AC_REQUIRE([_LT_PROG_FC])dnl
-AC_LANG_PUSH(Fortran)
-
-_LT_TAGVAR(archive_cmds_need_lc, $1)=no
-_LT_TAGVAR(allow_undefined_flag, $1)=
-_LT_TAGVAR(always_export_symbols, $1)=no
-_LT_TAGVAR(archive_expsym_cmds, $1)=
-_LT_TAGVAR(export_dynamic_flag_spec, $1)=
-_LT_TAGVAR(hardcode_direct, $1)=no
-_LT_TAGVAR(hardcode_direct_absolute, $1)=no
-_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
-_LT_TAGVAR(hardcode_libdir_separator, $1)=
-_LT_TAGVAR(hardcode_minus_L, $1)=no
-_LT_TAGVAR(hardcode_automatic, $1)=no
-_LT_TAGVAR(inherit_rpath, $1)=no
-_LT_TAGVAR(module_cmds, $1)=
-_LT_TAGVAR(module_expsym_cmds, $1)=
-_LT_TAGVAR(link_all_deplibs, $1)=unknown
-_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-_LT_TAGVAR(no_undefined_flag, $1)=
-_LT_TAGVAR(whole_archive_flag_spec, $1)=
-_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
-
-# Source file extension for fc test sources.
-ac_ext=${ac_fc_srcext-f}
-
-# Object file extension for compiled fc test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# No sense in running all these tests if we already determined that
-# the FC compiler isn't working. Some variables (like enable_shared)
-# are currently assumed to apply to all compilers on this platform,
-# and will be corrupted by setting them based on a non-working compiler.
-if test "$_lt_disable_FC" != yes; then
- # Code to be used in simple compile tests
- lt_simple_compile_test_code="\
- subroutine t
- return
- end
-"
-
- # Code to be used in simple link tests
- lt_simple_link_test_code="\
- program t
- end
-"
-
- # ltmain only uses $CC for tagged configurations so make sure $CC is set.
- _LT_TAG_COMPILER
-
- # save warnings/boilerplate of simple test code
- _LT_COMPILER_BOILERPLATE
- _LT_LINKER_BOILERPLATE
-
- # Allow CC to be a program name with arguments.
- lt_save_CC="$CC"
- lt_save_GCC=$GCC
- CC=${FC-"f95"}
- compiler=$CC
- GCC=$ac_cv_fc_compiler_gnu
-
- _LT_TAGVAR(compiler, $1)=$CC
- _LT_CC_BASENAME([$compiler])
-
- if test -n "$compiler"; then
- AC_MSG_CHECKING([if libtool supports shared libraries])
- AC_MSG_RESULT([$can_build_shared])
-
- AC_MSG_CHECKING([whether to build shared libraries])
- test "$can_build_shared" = "no" && enable_shared=no
-
- # On AIX, shared libraries and static libraries use the same namespace, and
- # are all built from PIC.
- case $host_os in
- aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
- aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
- esac
- AC_MSG_RESULT([$enable_shared])
-
- AC_MSG_CHECKING([whether to build static libraries])
- # Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
- AC_MSG_RESULT([$enable_static])
-
- _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
- _LT_TAGVAR(LD, $1)="$LD"
-
- ## CAVEAT EMPTOR:
- ## There is no encapsulation within the following macros, do not change
- ## the running order or otherwise move them around unless you know exactly
- ## what you are doing...
- _LT_SYS_HIDDEN_LIBDEPS($1)
- _LT_COMPILER_PIC($1)
- _LT_COMPILER_C_O($1)
- _LT_COMPILER_FILE_LOCKS($1)
- _LT_LINKER_SHLIBS($1)
- _LT_SYS_DYNAMIC_LINKER($1)
- _LT_LINKER_HARDCODE_LIBPATH($1)
-
- _LT_CONFIG($1)
- fi # test -n "$compiler"
-
- GCC=$lt_save_GCC
- CC="$lt_save_CC"
-fi # test "$_lt_disable_FC" != yes
-
-AC_LANG_POP
-])# _LT_LANG_FC_CONFIG
-
-
-# _LT_LANG_GCJ_CONFIG([TAG])
-# --------------------------
-# Ensure that the configuration variables for the GNU Java Compiler compiler
-# are suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_GCJ_CONFIG],
-[AC_REQUIRE([LT_PROG_GCJ])dnl
-AC_LANG_SAVE
-
-# Source file extension for Java test sources.
-ac_ext=java
-
-# Object file extension for compiled Java test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="class foo {}"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-_LT_TAG_COMPILER
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-lt_save_GCC=$GCC
-GCC=yes
-CC=${GCJ-"gcj"}
-compiler=$CC
-_LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)="$LD"
-_LT_CC_BASENAME([$compiler])
-
-# GCJ did not exist at the time GCC didn't implicitly link libc in.
-_LT_TAGVAR(archive_cmds_need_lc, $1)=no
-
-_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-
-if test -n "$compiler"; then
- _LT_COMPILER_NO_RTTI($1)
- _LT_COMPILER_PIC($1)
- _LT_COMPILER_C_O($1)
- _LT_COMPILER_FILE_LOCKS($1)
- _LT_LINKER_SHLIBS($1)
- _LT_LINKER_HARDCODE_LIBPATH($1)
-
- _LT_CONFIG($1)
-fi
-
-AC_LANG_RESTORE
-
-GCC=$lt_save_GCC
-CC="$lt_save_CC"
-])# _LT_LANG_GCJ_CONFIG
-
-
-# _LT_LANG_RC_CONFIG([TAG])
-# -------------------------
-# Ensure that the configuration variables for the Windows resource compiler
-# are suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
-m4_defun([_LT_LANG_RC_CONFIG],
-[AC_REQUIRE([LT_PROG_RC])dnl
-AC_LANG_SAVE
-
-# Source file extension for RC test sources.
-ac_ext=rc
-
-# Object file extension for compiled RC test sources.
-objext=o
-_LT_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
-
-# Code to be used in simple link tests
-lt_simple_link_test_code="$lt_simple_compile_test_code"
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-_LT_TAG_COMPILER
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-lt_save_GCC=$GCC
-GCC=
-CC=${RC-"windres"}
-compiler=$CC
-_LT_TAGVAR(compiler, $1)=$CC
-_LT_CC_BASENAME([$compiler])
-_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
-
-if test -n "$compiler"; then
- :
- _LT_CONFIG($1)
-fi
-
-GCC=$lt_save_GCC
-AC_LANG_RESTORE
-CC="$lt_save_CC"
-])# _LT_LANG_RC_CONFIG
-
-
-# LT_PROG_GCJ
-# -----------
-AC_DEFUN([LT_PROG_GCJ],
-[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
- [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
- [AC_CHECK_TOOL(GCJ, gcj,)
- test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
- AC_SUBST(GCJFLAGS)])])[]dnl
-])
-
-# Old name:
-AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
-
-
-# LT_PROG_RC
-# ----------
-AC_DEFUN([LT_PROG_RC],
-[AC_CHECK_TOOL(RC, windres,)
-])
-
-# Old name:
-AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([LT_AC_PROG_RC], [])
-
-
-# _LT_DECL_EGREP
-# --------------
-# If we don't have a new enough Autoconf to choose the best grep
-# available, choose the one first in the user's PATH.
-m4_defun([_LT_DECL_EGREP],
-[AC_REQUIRE([AC_PROG_EGREP])dnl
-AC_REQUIRE([AC_PROG_FGREP])dnl
-test -z "$GREP" && GREP=grep
-_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
-_LT_DECL([], [EGREP], [1], [An ERE matcher])
-_LT_DECL([], [FGREP], [1], [A literal string matcher])
-dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
-AC_SUBST([GREP])
-])
-
-
-# _LT_DECL_OBJDUMP
-# --------------
-# If we don't have a new enough Autoconf to choose the best objdump
-# available, choose the one first in the user's PATH.
-m4_defun([_LT_DECL_OBJDUMP],
-[AC_CHECK_TOOL(OBJDUMP, objdump, false)
-test -z "$OBJDUMP" && OBJDUMP=objdump
-_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
-AC_SUBST([OBJDUMP])
-])
-
-
-# _LT_DECL_SED
-# ------------
-# Check for a fully-functional sed program, that truncates
-# as few characters as possible. Prefer GNU sed if found.
-m4_defun([_LT_DECL_SED],
-[AC_PROG_SED
-test -z "$SED" && SED=sed
-Xsed="$SED -e 1s/^X//"
-_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
-_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
- [Sed that helps us avoid accidentally triggering echo(1) options like -n])
-])# _LT_DECL_SED
-
-m4_ifndef([AC_PROG_SED], [
-# NOTE: This macro has been submitted for inclusion into #
-# GNU Autoconf as AC_PROG_SED. When it is available in #
-# a released version of Autoconf we should remove this #
-# macro and use it instead. #
-
-m4_defun([AC_PROG_SED],
-[AC_MSG_CHECKING([for a sed that does not truncate output])
-AC_CACHE_VAL(lt_cv_path_SED,
-[# Loop through the user's path and test for sed and gsed.
-# Then use that list of sed's as ones to test for truncation.
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for lt_ac_prog in sed gsed; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
- lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
- fi
- done
- done
-done
-IFS=$as_save_IFS
-lt_ac_max=0
-lt_ac_count=0
-# Add /usr/xpg4/bin/sed as it is typically found on Solaris
-# along with /bin/sed that truncates output.
-for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
- test ! -f $lt_ac_sed && continue
- cat /dev/null > conftest.in
- lt_ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >conftest.in
- # Check for GNU sed and select it if it is found.
- if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
- lt_cv_path_SED=$lt_ac_sed
- break
- fi
- while true; do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo >>conftest.nl
- $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
- cmp -s conftest.out conftest.nl || break
- # 10000 chars as input seems more than enough
- test $lt_ac_count -gt 10 && break
- lt_ac_count=`expr $lt_ac_count + 1`
- if test $lt_ac_count -gt $lt_ac_max; then
- lt_ac_max=$lt_ac_count
- lt_cv_path_SED=$lt_ac_sed
- fi
- done
-done
-])
-SED=$lt_cv_path_SED
-AC_SUBST([SED])
-AC_MSG_RESULT([$SED])
-])#AC_PROG_SED
-])#m4_ifndef
-
-# Old name:
-AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([LT_AC_PROG_SED], [])
-
-
-# _LT_CHECK_SHELL_FEATURES
-# ------------------------
-# Find out whether the shell is Bourne or XSI compatible,
-# or has some other useful features.
-m4_defun([_LT_CHECK_SHELL_FEATURES],
-[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
-# Try some XSI features
-xsi_shell=no
-( _lt_dummy="a/b/c"
- test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
- = c,a/b,, \
- && eval 'test $(( 1 + 1 )) -eq 2 \
- && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
- && xsi_shell=yes
-AC_MSG_RESULT([$xsi_shell])
-_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
-
-AC_MSG_CHECKING([whether the shell understands "+="])
-lt_shell_append=no
-( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
- >/dev/null 2>&1 \
- && lt_shell_append=yes
-AC_MSG_RESULT([$lt_shell_append])
-_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
-
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- lt_unset=unset
-else
- lt_unset=false
-fi
-_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
-
-# test EBCDIC or ASCII
-case `echo X|tr X '\101'` in
- A) # ASCII based system
- # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
- lt_SP2NL='tr \040 \012'
- lt_NL2SP='tr \015\012 \040\040'
- ;;
- *) # EBCDIC based system
- lt_SP2NL='tr \100 \n'
- lt_NL2SP='tr \r\n \100\100'
- ;;
-esac
-_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
-_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
-])# _LT_CHECK_SHELL_FEATURES
-
-
-# _LT_PROG_XSI_SHELLFNS
-# ---------------------
-# Bourne and XSI compatible variants of some useful shell functions.
-m4_defun([_LT_PROG_XSI_SHELLFNS],
-[case $xsi_shell in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result="${1##*/}"
-}
-
-# func_dirname_and_basename file append nondir_replacement
-# perform func_basename and func_dirname in a single function
-# call:
-# dirname: Compute the dirname of FILE. If nonempty,
-# add APPEND to the result, otherwise set result
-# to NONDIR_REPLACEMENT.
-# value returned in "$func_dirname_result"
-# basename: Compute filename of FILE.
-# value retuned in "$func_basename_result"
-# Implementation must be kept synchronized with func_dirname
-# and func_basename. For efficiency, we do not delegate to
-# those functions but instead duplicate the functionality here.
-func_dirname_and_basename ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
- func_basename_result="${1##*/}"
-}
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-func_stripname ()
-{
- # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
- # positional parameters, so assign one to ordinary parameter first.
- func_stripname_result=${3}
- func_stripname_result=${func_stripname_result#"${1}"}
- func_stripname_result=${func_stripname_result%"${2}"}
-}
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=${1%%=*}
- func_opt_split_arg=${1#*=}
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- case ${1} in
- *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
- *) func_lo2o_result=${1} ;;
- esac
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=${1%.*}.lo
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=$(( $[*] ))
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=${#1}
-}
-
-_LT_EOF
- ;;
- *) # Bourne compatible functions.
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- # Extract subdirectory from the argument.
- func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
- if test "X$func_dirname_result" = "X${1}"; then
- func_dirname_result="${3}"
- else
- func_dirname_result="$func_dirname_result${2}"
- fi
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
-}
-
-dnl func_dirname_and_basename
-dnl A portable version of this function is already defined in general.m4sh
-dnl so there is no need for it here.
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-# func_strip_suffix prefix name
-func_stripname ()
-{
- case ${2} in
- .*) func_stripname_result=`$ECHO "X${3}" \
- | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
- *) func_stripname_result=`$ECHO "X${3}" \
- | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
- esac
-}
-
-# sed scripts:
-my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
-my_sed_long_arg='1s/^-[[^=]]*=//'
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
- func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=`expr "$[@]"`
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
-}
-
-_LT_EOF
-esac
-
-case $lt_shell_append in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$[1]+=\$[2]"
-}
-_LT_EOF
- ;;
- *)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$[1]=\$$[1]\$[2]"
-}
-
-_LT_EOF
- ;;
- esac
-])
-
-# Helper functions for option handling. -*- Autoconf -*-
-#
-# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
-# Written by Gary V. Vaughan, 2004
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-
-# serial 6 ltoptions.m4
-
-# This is to help aclocal find these macros, as it can't see m4_define.
-AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
-
-
-# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
-# ------------------------------------------
-m4_define([_LT_MANGLE_OPTION],
-[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
-
-
-# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
-# ---------------------------------------
-# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
-# matching handler defined, dispatch to it. Other OPTION-NAMEs are
-# saved as a flag.
-m4_define([_LT_SET_OPTION],
-[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
-m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
- _LT_MANGLE_DEFUN([$1], [$2]),
- [m4_warning([Unknown $1 option `$2'])])[]dnl
-])
-
-
-# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
-# ------------------------------------------------------------
-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
-m4_define([_LT_IF_OPTION],
-[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
-
-
-# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
-# -------------------------------------------------------
-# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
-# are set.
-m4_define([_LT_UNLESS_OPTIONS],
-[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
- [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
- [m4_define([$0_found])])])[]dnl
-m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
-])[]dnl
-])
-
-
-# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
-# ----------------------------------------
-# OPTION-LIST is a space-separated list of Libtool options associated
-# with MACRO-NAME. If any OPTION has a matching handler declared with
-# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
-# the unknown option and exit.
-m4_defun([_LT_SET_OPTIONS],
-[# Set options
-m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
- [_LT_SET_OPTION([$1], _LT_Option)])
-
-m4_if([$1],[LT_INIT],[
- dnl
- dnl Simply set some default values (i.e off) if boolean options were not
- dnl specified:
- _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
- ])
- _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
- ])
- dnl
- dnl If no reference was made to various pairs of opposing options, then
- dnl we run the default mode handler for the pair. For example, if neither
- dnl `shared' nor `disable-shared' was passed, we enable building of shared
- dnl archives by default:
- _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
- _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
- _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
- _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
- [_LT_ENABLE_FAST_INSTALL])
- ])
-])# _LT_SET_OPTIONS
-
-
-
-# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
-# -----------------------------------------
-m4_define([_LT_MANGLE_DEFUN],
-[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
-
-
-# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
-# -----------------------------------------------
-m4_define([LT_OPTION_DEFINE],
-[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
-])# LT_OPTION_DEFINE
-
-
-# dlopen
-# ------
-LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
-])
-
-AU_DEFUN([AC_LIBTOOL_DLOPEN],
-[_LT_SET_OPTION([LT_INIT], [dlopen])
-AC_DIAGNOSE([obsolete],
-[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the `dlopen' option into LT_INIT's first parameter.])
-])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
-
-
-# win32-dll
-# ---------
-# Declare package support for building win32 dll's.
-LT_OPTION_DEFINE([LT_INIT], [win32-dll],
-[enable_win32_dll=yes
-
-case $host in
-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
- AC_CHECK_TOOL(AS, as, false)
- AC_CHECK_TOOL(DLLTOOL, dlltool, false)
- AC_CHECK_TOOL(OBJDUMP, objdump, false)
- ;;
-esac
-
-test -z "$AS" && AS=as
-_LT_DECL([], [AS], [0], [Assembler program])dnl
-
-test -z "$DLLTOOL" && DLLTOOL=dlltool
-_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
-
-test -z "$OBJDUMP" && OBJDUMP=objdump
-_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
-])# win32-dll
-
-AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-_LT_SET_OPTION([LT_INIT], [win32-dll])
-AC_DIAGNOSE([obsolete],
-[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the `win32-dll' option into LT_INIT's first parameter.])
-])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
-
-
-# _LT_ENABLE_SHARED([DEFAULT])
-# ----------------------------
-# implement the --enable-shared flag, and supports the `shared' and
-# `disable-shared' LT_INIT options.
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
-m4_define([_LT_ENABLE_SHARED],
-[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
-AC_ARG_ENABLE([shared],
- [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
- [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
- [p=${PACKAGE-default}
- case $enableval in
- yes) enable_shared=yes ;;
- no) enable_shared=no ;;
- *)
- enable_shared=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_shared=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac],
- [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
-
- _LT_DECL([build_libtool_libs], [enable_shared], [0],
- [Whether or not to build shared libraries])
-])# _LT_ENABLE_SHARED
-
-LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
-LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
-
-# Old names:
-AC_DEFUN([AC_ENABLE_SHARED],
-[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
-])
-
-AC_DEFUN([AC_DISABLE_SHARED],
-[_LT_SET_OPTION([LT_INIT], [disable-shared])
-])
-
-AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
-AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AM_ENABLE_SHARED], [])
-dnl AC_DEFUN([AM_DISABLE_SHARED], [])
-
-
-
-# _LT_ENABLE_STATIC([DEFAULT])
-# ----------------------------
-# implement the --enable-static flag, and support the `static' and
-# `disable-static' LT_INIT options.
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
-m4_define([_LT_ENABLE_STATIC],
-[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
-AC_ARG_ENABLE([static],
- [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
- [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
- [p=${PACKAGE-default}
- case $enableval in
- yes) enable_static=yes ;;
- no) enable_static=no ;;
- *)
- enable_static=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_static=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac],
- [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
-
- _LT_DECL([build_old_libs], [enable_static], [0],
- [Whether or not to build static libraries])
-])# _LT_ENABLE_STATIC
-
-LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
-LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
-
-# Old names:
-AC_DEFUN([AC_ENABLE_STATIC],
-[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
-])
-
-AC_DEFUN([AC_DISABLE_STATIC],
-[_LT_SET_OPTION([LT_INIT], [disable-static])
-])
-
-AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
-AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AM_ENABLE_STATIC], [])
-dnl AC_DEFUN([AM_DISABLE_STATIC], [])
-
-
-
-# _LT_ENABLE_FAST_INSTALL([DEFAULT])
-# ----------------------------------
-# implement the --enable-fast-install flag, and support the `fast-install'
-# and `disable-fast-install' LT_INIT options.
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
-m4_define([_LT_ENABLE_FAST_INSTALL],
-[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
-AC_ARG_ENABLE([fast-install],
- [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
- [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
- [p=${PACKAGE-default}
- case $enableval in
- yes) enable_fast_install=yes ;;
- no) enable_fast_install=no ;;
- *)
- enable_fast_install=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_fast_install=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac],
- [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
-
-_LT_DECL([fast_install], [enable_fast_install], [0],
- [Whether or not to optimize for fast installation])dnl
-])# _LT_ENABLE_FAST_INSTALL
-
-LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
-LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
-
-# Old names:
-AU_DEFUN([AC_ENABLE_FAST_INSTALL],
-[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
-AC_DIAGNOSE([obsolete],
-[$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the `fast-install' option into LT_INIT's first parameter.])
-])
-
-AU_DEFUN([AC_DISABLE_FAST_INSTALL],
-[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
-AC_DIAGNOSE([obsolete],
-[$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the `disable-fast-install' option into LT_INIT's first parameter.])
-])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
-dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
-
-
-# _LT_WITH_PIC([MODE])
-# --------------------
-# implement the --with-pic flag, and support the `pic-only' and `no-pic'
-# LT_INIT options.
-# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
-m4_define([_LT_WITH_PIC],
-[AC_ARG_WITH([pic],
- [AS_HELP_STRING([--with-pic],
- [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
- [pic_mode="$withval"],
- [pic_mode=default])
-
-test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
-
-_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
-])# _LT_WITH_PIC
-
-LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
-LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
-
-# Old name:
-AU_DEFUN([AC_LIBTOOL_PICMODE],
-[_LT_SET_OPTION([LT_INIT], [pic-only])
-AC_DIAGNOSE([obsolete],
-[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the `pic-only' option into LT_INIT's first parameter.])
-])
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
-
-
-m4_define([_LTDL_MODE], [])
-LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
- [m4_define([_LTDL_MODE], [nonrecursive])])
-LT_OPTION_DEFINE([LTDL_INIT], [recursive],
- [m4_define([_LTDL_MODE], [recursive])])
-LT_OPTION_DEFINE([LTDL_INIT], [subproject],
- [m4_define([_LTDL_MODE], [subproject])])
-
-m4_define([_LTDL_TYPE], [])
-LT_OPTION_DEFINE([LTDL_INIT], [installable],
- [m4_define([_LTDL_TYPE], [installable])])
-LT_OPTION_DEFINE([LTDL_INIT], [convenience],
- [m4_define([_LTDL_TYPE], [convenience])])
-
-# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
-#
-# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
-# Written by Gary V. Vaughan, 2004
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-
-# serial 6 ltsugar.m4
-
-# This is to help aclocal find these macros, as it can't see m4_define.
-AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
-
-
-# lt_join(SEP, ARG1, [ARG2...])
-# -----------------------------
-# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
-# associated separator.
-# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
-# versions in m4sugar had bugs.
-m4_define([lt_join],
-[m4_if([$#], [1], [],
- [$#], [2], [[$2]],
- [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
-m4_define([_lt_join],
-[m4_if([$#$2], [2], [],
- [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
-
-
-# lt_car(LIST)
-# lt_cdr(LIST)
-# ------------
-# Manipulate m4 lists.
-# These macros are necessary as long as will still need to support
-# Autoconf-2.59 which quotes differently.
-m4_define([lt_car], [[$1]])
-m4_define([lt_cdr],
-[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
- [$#], 1, [],
- [m4_dquote(m4_shift($@))])])
-m4_define([lt_unquote], $1)
-
-
-# lt_append(MACRO-NAME, STRING, [SEPARATOR])
-# ------------------------------------------
-# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
-# Note that neither SEPARATOR nor STRING are expanded; they are appended
-# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
-# No SEPARATOR is output if MACRO-NAME was previously undefined (different
-# than defined and empty).
-#
-# This macro is needed until we can rely on Autoconf 2.62, since earlier
-# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
-m4_define([lt_append],
-[m4_define([$1],
- m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
-
-
-
-# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
-# ----------------------------------------------------------
-# Produce a SEP delimited list of all paired combinations of elements of
-# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
-# has the form PREFIXmINFIXSUFFIXn.
-# Needed until we can rely on m4_combine added in Autoconf 2.62.
-m4_define([lt_combine],
-[m4_if(m4_eval([$# > 3]), [1],
- [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
-[[m4_foreach([_Lt_prefix], [$2],
- [m4_foreach([_Lt_suffix],
- ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
- [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
-
-
-# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
-# -----------------------------------------------------------------------
-# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
-# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
-m4_define([lt_if_append_uniq],
-[m4_ifdef([$1],
- [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
- [lt_append([$1], [$2], [$3])$4],
- [$5])],
- [lt_append([$1], [$2], [$3])$4])])
-
-
-# lt_dict_add(DICT, KEY, VALUE)
-# -----------------------------
-m4_define([lt_dict_add],
-[m4_define([$1($2)], [$3])])
-
-
-# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
-# --------------------------------------------
-m4_define([lt_dict_add_subkey],
-[m4_define([$1($2:$3)], [$4])])
-
-
-# lt_dict_fetch(DICT, KEY, [SUBKEY])
-# ----------------------------------
-m4_define([lt_dict_fetch],
-[m4_ifval([$3],
- m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
- m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
-
-
-# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
-# -----------------------------------------------------------------
-m4_define([lt_if_dict_fetch],
-[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
- [$5],
- [$6])])
-
-
-# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
-# --------------------------------------------------------------
-m4_define([lt_dict_filter],
-[m4_if([$5], [], [],
- [lt_join(m4_quote(m4_default([$4], [[, ]])),
- lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
- [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
-])
-
-# ltversion.m4 -- version numbers -*- Autoconf -*-
-#
-# Copyright (C) 2004 Free Software Foundation, Inc.
-# Written by Scott James Remnant, 2004
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-
-# Generated from ltversion.in.
-
-# serial 3017 ltversion.m4
-# This file is part of GNU Libtool
-
-m4_define([LT_PACKAGE_VERSION], [2.2.6b])
-m4_define([LT_PACKAGE_REVISION], [1.3017])
-
-AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.2.6b'
-macro_revision='1.3017'
-_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
-_LT_DECL(, macro_revision, 0)
-])
-
-# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
-#
-# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
-# Written by Scott James Remnant, 2004.
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-
-# serial 4 lt~obsolete.m4
-
-# These exist entirely to fool aclocal when bootstrapping libtool.
-#
-# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
-# which have later been changed to m4_define as they aren't part of the
-# exported API, or moved to Autoconf or Automake where they belong.
-#
-# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
-# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
-# using a macro with the same name in our local m4/libtool.m4 it'll
-# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
-# and doesn't know about Autoconf macros at all.)
-#
-# So we provide this file, which has a silly filename so it's always
-# included after everything else. This provides aclocal with the
-# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
-# because those macros already exist, or will be overwritten later.
-# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
-#
-# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
-# Yes, that means every name once taken will need to remain here until
-# we give up compatibility with versions before 1.7, at which point
-# we need to keep only those names which we still refer to.
-
-# This is to help aclocal find these macros, as it can't see m4_define.
-AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
-
-m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
-m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
-m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
-m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
-m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
-m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
-m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
-m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
-m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
-m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
-m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
-m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
-m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
-m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
-m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
-m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
-m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
-m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
-m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
-m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
-m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
-m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
-m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
-m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
-m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
-m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
-m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
-m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
-m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
-m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
-m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
-m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
-m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
-m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
-m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
-m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
-m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
-m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
-m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
-m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
-m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
-m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
-m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])])
-m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
-m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
-m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
-m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
-m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
-m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
-m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
-m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
-m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
-m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
-m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
-m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
-
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_AUTOMAKE_VERSION(VERSION)
-# ----------------------------
-# Automake X.Y traces this macro to ensure aclocal.m4 has been
-# generated from the m4 files accompanying Automake X.Y.
-# (This private macro should not be called outside this file.)
-AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.11'
-dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
-dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.1], [],
- [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
-])
-
-# _AM_AUTOCONF_VERSION(VERSION)
-# -----------------------------
-# aclocal traces this macro to find the Autoconf version.
-# This is a private macro too. Using m4_define simplifies
-# the logic in aclocal, which can simply ignore this definition.
-m4_define([_AM_AUTOCONF_VERSION], [])
-
-# AM_SET_CURRENT_AUTOMAKE_VERSION
-# -------------------------------
-# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
-# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
-
-# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
-#
-# Of course, Automake must honor this variable whenever it calls a
-# tool from the auxiliary directory. The problem is that $srcdir (and
-# therefore $ac_aux_dir as well) can be either absolute or relative,
-# depending on how configure is run. This is pretty annoying, since
-# it makes $ac_aux_dir quite unusable in subdirectories: in the top
-# source directory, any form will work fine, but in subdirectories a
-# relative path needs to be adjusted first.
-#
-# $ac_aux_dir/missing
-# fails when called from a subdirectory if $ac_aux_dir is relative
-# $top_srcdir/$ac_aux_dir/missing
-# fails if $ac_aux_dir is absolute,
-# fails when called from a subdirectory in a VPATH build with
-# a relative $ac_aux_dir
-#
-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
-# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
-# start a VPATH build or use an absolute $srcdir.
-#
-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
-# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
-# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
-# and then we would define $MISSING as
-# MISSING="\${SHELL} $am_aux_dir/missing"
-# This will work as long as MISSING is not called from configure, because
-# unfortunately $(top_srcdir) has no meaning in configure.
-# However there are other variables, like CC, which are often used in
-# configure, and could therefore not use this "fixed" $ac_aux_dir.
-#
-# Another solution, used here, is to always expand $ac_aux_dir to an
-# absolute PATH. The drawback is that using absolute paths prevent a
-# configured tree to be moved without reconfiguration.
-
-AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-])
-
-# AM_CONDITIONAL -*- Autoconf -*-
-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 9
-
-# AM_CONDITIONAL(NAME, SHELL-CONDITION)
-# -------------------------------------
-# Define a conditional.
-AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ(2.52)dnl
- ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
-AC_SUBST([$1_TRUE])dnl
-AC_SUBST([$1_FALSE])dnl
-_AM_SUBST_NOTMAKE([$1_TRUE])dnl
-_AM_SUBST_NOTMAKE([$1_FALSE])dnl
-m4_define([_AM_COND_VALUE_$1], [$2])dnl
-if $2; then
- $1_TRUE=
- $1_FALSE='#'
-else
- $1_TRUE='#'
- $1_FALSE=
-fi
-AC_CONFIG_COMMANDS_PRE(
-[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
- AC_MSG_ERROR([[conditional "$1" was never defined.
-Usually this means the macro was only invoked conditionally.]])
-fi])])
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 10
-
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
-# written in clear, in which case automake, when reading aclocal.m4,
-# will think it sees a *use*, and therefore will trigger all it's
-# C support machinery. Also note that it means that autoscan, seeing
-# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
-
-# _AM_DEPENDENCIES(NAME)
-# ----------------------
-# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
-# We try a few techniques and use that to set a single cache variable.
-#
-# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
-# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
-# dependency, and given that the user is not expected to run this macro,
-# just rely on AC_PROG_CC.
-AC_DEFUN([_AM_DEPENDENCIES],
-[AC_REQUIRE([AM_SET_DEPDIR])dnl
-AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
-AC_REQUIRE([AM_MAKE_INCLUDE])dnl
-AC_REQUIRE([AM_DEP_TRACK])dnl
-
-ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
- [$1], CXX, [depcc="$CXX" am_compiler_list=],
- [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], UPC, [depcc="$UPC" am_compiler_list=],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
-
-AC_CACHE_CHECK([dependency style of $depcc],
- [am_cv_$1_dependencies_compiler_type],
-[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_$1_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
- fi
- am__universal=false
- m4_case([$1], [CC],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac],
- [CXX],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac])
-
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
- am__obj=sub/conftest.${OBJEXT-o}
- am__minus_obj="-o $am__obj"
- case $depmode in
- gcc)
- # This depmode causes a compiler race in universal mode.
- test "$am__universal" = false || continue
- ;;
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
- # not run yet. These depmodes are late enough in the game, and
- # so weak that their functioning should not be impacted.
- am__obj=conftest.${OBJEXT-o}
- am__minus_obj=
- ;;
- none) break ;;
- esac
- if depmode=$depmode \
- source=sub/conftest.c object=$am__obj \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_$1_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_$1_dependencies_compiler_type=none
-fi
-])
-AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
-AM_CONDITIONAL([am__fastdep$1], [
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
-])
-
-
-# AM_SET_DEPDIR
-# -------------
-# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
-AC_DEFUN([AM_SET_DEPDIR],
-[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
-])
-
-
-# AM_DEP_TRACK
-# ------------
-AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[ --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors])
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
-fi
-AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
-AC_SUBST([AMDEPBACKSLASH])dnl
-_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
-])
-
-# Generate code to set up dependency tracking. -*- Autoconf -*-
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-#serial 5
-
-# _AM_OUTPUT_DEPENDENCY_COMMANDS
-# ------------------------------
-AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
-[{
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
- # are listed without --file. Let's play safe and only enable the eval
- # if we detect the quoting.
- case $CONFIG_FILES in
- *\'*) eval set x "$CONFIG_FILES" ;;
- *) set x $CONFIG_FILES ;;
- esac
- shift
- for mf
- do
- # Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`AS_DIRNAME("$mf")`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`AS_DIRNAME(["$file"])`
- AS_MKDIR_P([$dirpart/$fdir])
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
- done
-}
-])# _AM_OUTPUT_DEPENDENCY_COMMANDS
-
-
-# AM_OUTPUT_DEPENDENCY_COMMANDS
-# -----------------------------
-# This macro should only be invoked once -- use via AC_REQUIRE.
-#
-# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each `.P' file that we will
-# need in order to bootstrap the dependency handling code.
-AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
-[AC_CONFIG_COMMANDS([depfiles],
- [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
-
-# Do all the work for Automake. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 16
-
-# This macro actually does too much. Some checks are only needed if
-# your package does certain things. But this isn't really a big deal.
-
-# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
-# AM_INIT_AUTOMAKE([OPTIONS])
-# -----------------------------------------------
-# The call with PACKAGE and VERSION arguments is the old style
-# call (pre autoconf-2.50), which is being phased out. PACKAGE
-# and VERSION should now be passed to AC_INIT and removed from
-# the call to AM_INIT_AUTOMAKE.
-# We support both call styles for the transition. After
-# the next Automake release, Autoconf can make the AC_INIT
-# arguments mandatory, and then we can depend on a new Autoconf
-# release and drop the old call support.
-AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
-dnl Autoconf wants to disallow AM_ names. We explicitly allow
-dnl the ones we care about.
-m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
-AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
-AC_REQUIRE([AC_PROG_INSTALL])dnl
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-AC_SUBST([CYGPATH_W])
-
-# Define the identity of the package.
-dnl Distinguish between old-style and new-style calls.
-m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
- AC_SUBST([PACKAGE], [$1])dnl
- AC_SUBST([VERSION], [$2])],
-[_AM_SET_OPTIONS([$1])dnl
-dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
- [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
-
-_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
-
-# Some tools Automake needs.
-AC_REQUIRE([AM_SANITY_CHECK])dnl
-AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
-AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
-AC_REQUIRE([AC_PROG_AWK])dnl
-AC_REQUIRE([AC_PROG_MAKE_SET])dnl
-AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
- [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
- [_AM_PROG_TAR([v7])])])
-_AM_IF_OPTION([no-dependencies],,
-[AC_PROVIDE_IFELSE([AC_PROG_CC],
- [_AM_DEPENDENCIES(CC)],
- [define([AC_PROG_CC],
- defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [_AM_DEPENDENCIES(CXX)],
- [define([AC_PROG_CXX],
- defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES(OBJC)],
- [define([AC_PROG_OBJC],
- defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
-])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
-dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
-AC_CONFIG_COMMANDS_PRE(dnl
-[m4_provide_if([_AM_COMPILER_EXEEXT],
- [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-])
-
-dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
-dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
-dnl mangled by Autoconf and run in a shell conditional statement.
-m4_define([_AC_COMPILER_EXEEXT],
-m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
-
-# When config.status generates a header, we must update the stamp-h file.
-# This file resides in the same directory as the config header
-# that is generated. The stamp files are numbered to have different names.
-
-# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
-# loop where config.status creates the headers, so we can generate
-# our stamp files there.
-AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
-[# Compute $1's index in $config_headers.
-_am_arg=$1
-_am_stamp_count=1
-for _am_header in $config_headers :; do
- case $_am_header in
- $_am_arg | $_am_arg:* )
- break ;;
- * )
- _am_stamp_count=`expr $_am_stamp_count + 1` ;;
- esac
-done
-echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-
-# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_SH
-# ------------------
-# Define $install_sh.
-AC_DEFUN([AM_PROG_INSTALL_SH],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
- *)
- install_sh="\${SHELL} $am_aux_dir/install-sh"
- esac
-fi
-AC_SUBST(install_sh)])
-
-# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# Check whether the underlying file-system supports filenames
-# with a leading dot. For instance MS-DOS doesn't.
-AC_DEFUN([AM_SET_LEADING_DOT],
-[rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-AC_SUBST([am__leading_dot])])
-
-# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
-# From Jim Meyering
-
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 5
-
-# AM_MAINTAINER_MODE([DEFAULT-MODE])
-# ----------------------------------
-# Control maintainer-specific portions of Makefiles.
-# Default is to disable them, unless `enable' is passed literally.
-# For symmetry, `disable' may be passed as well. Anyway, the user
-# can override the default with the --enable/--disable switch.
-AC_DEFUN([AM_MAINTAINER_MODE],
-[m4_case(m4_default([$1], [disable]),
- [enable], [m4_define([am_maintainer_other], [disable])],
- [disable], [m4_define([am_maintainer_other], [enable])],
- [m4_define([am_maintainer_other], [enable])
- m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
-AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
- dnl maintainer-mode's default is 'disable' unless 'enable' is passed
- AC_ARG_ENABLE([maintainer-mode],
-[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
- (and sometimes confusing) to the casual installer],
- [USE_MAINTAINER_MODE=$enableval],
- [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
- AC_MSG_RESULT([$USE_MAINTAINER_MODE])
- AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
- MAINT=$MAINTAINER_MODE_TRUE
- AC_SUBST([MAINT])dnl
-]
-)
-
-AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-
-# Check to see how 'make' treats includes. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# AM_MAKE_INCLUDE()
-# -----------------
-# Check to see how make treats includes.
-AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo this is the am__doit target
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
- am__include=include
- am__quote=
- _am_result=GNU
- ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- case `$am_make -s -f confmf 2> /dev/null` in #(
- *the\ am__doit\ target*)
- am__include=.include
- am__quote="\""
- _am_result=BSD
- ;;
- esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
-
-# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 6
-
-# AM_MISSING_PROG(NAME, PROGRAM)
-# ------------------------------
-AC_DEFUN([AM_MISSING_PROG],
-[AC_REQUIRE([AM_MISSING_HAS_RUN])
-$1=${$1-"${am_missing_run}$2"}
-AC_SUBST($1)])
-
-
-# AM_MISSING_HAS_RUN
-# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
-AC_DEFUN([AM_MISSING_HAS_RUN],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([missing])dnl
-if test x"${MISSING+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
- *)
- MISSING="\${SHELL} $am_aux_dir/missing" ;;
- esac
-fi
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
-else
- am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
-fi
-])
-
-# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_MKDIR_P
-# ---------------
-# Check for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
- [[\\/$]]* | ?:[[\\/]]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
-# Helper functions for option handling. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# _AM_MANGLE_OPTION(NAME)
-# -----------------------
-AC_DEFUN([_AM_MANGLE_OPTION],
-[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
-
-# _AM_SET_OPTION(NAME)
-# ------------------------------
-# Set option NAME. Presently that only means defining a flag for this option.
-AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
-
-# _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
-# OPTIONS is a space-separated list of Automake options.
-AC_DEFUN([_AM_SET_OPTIONS],
-[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
-
-# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
-# -------------------------------------------
-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
-AC_DEFUN([_AM_IF_OPTION],
-[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-
-# Check to make sure that the build environment is sane. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 5
-
-# AM_SANITY_CHECK
-# ---------------
-AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
-# Reject unsafe characters in $srcdir or the absolute working directory
-# name. Accept space and tab only in the latter.
-am_lf='
-'
-case `pwd` in
- *[[\\\"\#\$\&\'\`$am_lf]]*)
- AC_MSG_ERROR([unsafe absolute working directory name]);;
-esac
-case $srcdir in
- *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
- AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
-esac
-
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
-alias in your environment])
- fi
-
- test "$[2]" = conftest.file
- )
-then
- # Ok.
- :
-else
- AC_MSG_ERROR([newly created file is older than distributed files!
-Check your system clock])
-fi
-AC_MSG_RESULT(yes)])
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_STRIP
-# ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
-# specify the program used to strip binaries. This is especially
-# annoying in cross-compiling environments, where the build's strip
-# is unlikely to handle the host's binaries.
-# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
-# STRIPPROG with the value of the STRIP variable (set by the user).
-AC_DEFUN([AM_PROG_INSTALL_STRIP],
-[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
-if test "$cross_compiling" != no; then
- AC_CHECK_TOOL([STRIP], [strip], :)
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-AC_SUBST([INSTALL_STRIP_PROGRAM])])
-
-# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
-# This macro is traced by Automake.
-AC_DEFUN([_AM_SUBST_NOTMAKE])
-
-# AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Public sister of _AM_SUBST_NOTMAKE.
-AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
-
-# Check how to create a tarball. -*- Autoconf -*-
-
-# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_PROG_TAR(FORMAT)
-# --------------------
-# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
-#
-# Substitute a variable $(am__tar) that is a command
-# writing to stdout a FORMAT-tarball containing the directory
-# $tardir.
-# tardir=directory && $(am__tar) > result.tar
-#
-# Substitute a variable $(am__untar) that extract such
-# a tarball read from stdin.
-# $(am__untar) < result.tar
-AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
-m4_if([$1], [v7],
- [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
- [m4_case([$1], [ustar],, [pax],,
- [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
-_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar;
- do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
-
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
-
- # tar/untar a dummy directory, and stop if the command works
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
- rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
-done
-rm -rf conftest.dir
-
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
-AC_SUBST([am__tar])
-AC_SUBST([am__untar])
-]) # _AM_PROG_TAR
-
diff --git a/deps/uv/src/unix/ev/autogen.sh b/deps/uv/src/unix/ev/autogen.sh
deleted file mode 100644
index 087d2aa4e..000000000
--- a/deps/uv/src/unix/ev/autogen.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-libtoolize --force
-automake --add-missing --force-missing
-autoreconf
-
diff --git a/deps/uv/src/unix/ev/config.guess b/deps/uv/src/unix/ev/config.guess
deleted file mode 100755
index f32079abd..000000000
--- a/deps/uv/src/unix/ev/config.guess
+++ /dev/null
@@ -1,1526 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
-
-timestamp='2008-01-23'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- sh5el) machine=sh5le-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit ;;
- *:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- exit ;;
- *:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit ;;
- *:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
- exit ;;
- macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- *:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- alpha:OSF1:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- # OSF/1 and Tru64 systems produced since 1995. I hope that
- # covers most systems running today. This code pipes the CPU
- # types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
- "EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
- "EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
- "LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
- "EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
- "EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
- "EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
- "EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
- "EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
- "EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
- "EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
- "EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
- "EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
- esac
- # A Pn.n version is a patched version.
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
- *:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
- *:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
- DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
- exit ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
- then
- echo "$SYSTEM_NAME"
- else
- echo rs6000-ibm-aix3.2.5
- fi
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit ;;
- *:AIX:*:[456])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- fi ;;
- esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- eval $set_cc_for_build
-
- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
- # generating 64-bit code. GNU and HP use different nomenclature:
- #
- # $ CC_FOR_BUILD=cc ./config.guess
- # => hppa2.0w-hp-hpux11.23
- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
- # => hppa64-hp-hpux11.23
-
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep __LP64__ >/dev/null
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- *:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- 5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- *:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
- *:Interix*:[3456]*)
- case ${UNAME_MACHINE} in
- x86)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
- EM64T | authenticamd)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
- IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
- exit ;;
- esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- arm*:Linux:*:*)
- eval $set_cc_for_build
- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_EABI__
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
- fi
- exit ;;
- avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- cris:Linux:*:*)
- echo cris-axis-linux-gnu
- exit ;;
- crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
- exit ;;
- frv:Linux:*:*)
- echo frv-unknown-linux-gnu
- exit ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- mips:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips64
- #undef mips64el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- or32:Linux:*:*)
- echo or32-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
- exit ;;
- x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
- exit ;;
- xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^LIBC/{
- s: ::g
- p
- }'`"
- test x"${LIBC}" != x && {
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit
- }
- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit ;;
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit ;;
- i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
- M68*:*:R3V[5678]*:*)
- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <hewes@openmarket.com>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- # From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
- i*86:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
- *:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
- exit ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
- SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
- *:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
- esac ;;
- *:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
- i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
- exit ;;
- i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/deps/uv/src/unix/ev/config.h.in b/deps/uv/src/unix/ev/config.h.in
deleted file mode 100644
index 75da15cce..000000000
--- a/deps/uv/src/unix/ev/config.h.in
+++ /dev/null
@@ -1,125 +0,0 @@
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the `clock_gettime' function. */
-#undef HAVE_CLOCK_GETTIME
-
-/* "use syscall interface for clock_gettime" */
-#undef HAVE_CLOCK_SYSCALL
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* Define to 1 if you have the `epoll_ctl' function. */
-#undef HAVE_EPOLL_CTL
-
-/* Define to 1 if you have the `eventfd' function. */
-#undef HAVE_EVENTFD
-
-/* Define to 1 if you have the `inotify_init' function. */
-#undef HAVE_INOTIFY_INIT
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the `kqueue' function. */
-#undef HAVE_KQUEUE
-
-/* Define to 1 if you have the `m' library (-lm). */
-#undef HAVE_LIBM
-
-/* Define to 1 if you have the `rt' library (-lrt). */
-#undef HAVE_LIBRT
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the `nanosleep' function. */
-#undef HAVE_NANOSLEEP
-
-/* Define to 1 if you have the `poll' function. */
-#undef HAVE_POLL
-
-/* Define to 1 if you have the <poll.h> header file. */
-#undef HAVE_POLL_H
-
-/* Define to 1 if you have the `port_create' function. */
-#undef HAVE_PORT_CREATE
-
-/* Define to 1 if you have the <port.h> header file. */
-#undef HAVE_PORT_H
-
-/* Define to 1 if you have the `select' function. */
-#undef HAVE_SELECT
-
-/* Define to 1 if you have the `signalfd' function. */
-#undef HAVE_SIGNALFD
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <sys/epoll.h> header file. */
-#undef HAVE_SYS_EPOLL_H
-
-/* Define to 1 if you have the <sys/eventfd.h> header file. */
-#undef HAVE_SYS_EVENTFD_H
-
-/* Define to 1 if you have the <sys/event.h> header file. */
-#undef HAVE_SYS_EVENT_H
-
-/* Define to 1 if you have the <sys/inotify.h> header file. */
-#undef HAVE_SYS_INOTIFY_H
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#undef HAVE_SYS_SELECT_H
-
-/* Define to 1 if you have the <sys/signalfd.h> header file. */
-#undef HAVE_SYS_SIGNALFD_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#undef LT_OBJDIR
-
-/* Name of package */
-#undef PACKAGE
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Version number of package */
-#undef VERSION
diff --git a/deps/uv/src/unix/ev/config.sub b/deps/uv/src/unix/ev/config.sub
deleted file mode 100755
index 6759825a5..000000000
--- a/deps/uv/src/unix/ev/config.sub
+++ /dev/null
@@ -1,1658 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
-
-timestamp='2008-01-16'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit ;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray)
- os=
- basic_machine=$1
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
- | bfin \
- | c4x | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | fido | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | mcore | mep \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64vr | mips64vrel \
- | mips64orion | mips64orionel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | mt \
- | msp430 \
- | nios | nios2 \
- | ns16k | ns32k \
- | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
- | pyramid \
- | score \
- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
- | v850 | v850e \
- | we32k \
- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k)
- basic_machine=$basic_machine-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
- ms1)
- basic_machine=mt-unknown
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nios-* | nios2-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
- | pyramid-* \
- | romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tron-* \
- | v850-* | v850e-* | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa*-* \
- | ymp-* \
- | z8k-*)
- ;;
- # Recognize the basic CPU types without company name, with glob match.
- xtensa*)
- basic_machine=$basic_machine-unknown
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
- ;;
- blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
- ;;
- m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
- ;;
- parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc) basic_machine=powerpc-unknown
- ;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
- sde)
- basic_machine=mipsisa32-sde
- os=-elf
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sh5el)
- basic_machine=sh5le-unknown
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tic55x | c55x*)
- basic_machine=tic55x-unknown
- os=-coff
- ;;
- tic6x | c6x*)
- basic_machine=tic6x-unknown
- os=-coff
- ;;
- tile*)
- basic_machine=tile-unknown
- os=-linux-gnu
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- mmix)
- basic_machine=mmix-knuth
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto-qnx*)
- ;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux-dietlibc)
- os=-linux-dietlibc
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -os400*)
- os=-os400
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -atheos*)
- os=-atheos
- ;;
- -syllable*)
- os=-syllable
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -nova*)
- os=-rtmk-nova
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -tpf*)
- os=-tpf
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -aros*)
- os=-aros
- ;;
- -kaos*)
- os=-kaos
- ;;
- -zvmoe)
- os=-zvmoe
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- score-*)
- os=-elf
- ;;
- spu-*)
- os=-elf
- ;;
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mep-*)
- os=-elf
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- or32-*)
- os=-coff
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-haiku)
- os=-haiku
- ;;
- *-ibm)
- os=-aix
- ;;
- *-knuth)
- os=-mmixware
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -os400*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -tpf*)
- vendor=ibm
- ;;
- -vxsim* | -vxworks* | -windiss*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/deps/uv/src/unix/ev/config_cygwin.h b/deps/uv/src/unix/ev/config_cygwin.h
deleted file mode 100644
index 1f6f6d98c..000000000
--- a/deps/uv/src/unix/ev/config_cygwin.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the `clock_gettime' function. */
-/* #undef HAVE_CLOCK_GETTIME */
-
-/* "use syscall interface for clock_gettime" */
-/* #undef HAVE_CLOCK_SYSCALL */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `epoll_ctl' function. */
-/* #undef HAVE_EPOLL_CTL */
-
-/* Define to 1 if you have the `eventfd' function. */
-/* #undef HAVE_EVENTFD */
-
-/* Define to 1 if you have the `inotify_init' function. */
-/* #undef HAVE_INOTIFY_INIT */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `kqueue' function. */
-/* #undef HAVE_KQUEUE */
-
-/* Define to 1 if you have the `m' library (-lm). */
-#define HAVE_LIBM 1
-
-/* Define to 1 if you have the `rt' library (-lrt). */
-/* #undef HAVE_LIBRT */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `nanosleep' function. */
-/* #undef HAVE_NANOSLEEP */
-
-/* Define to 1 if you have the `poll' function. */
-#define HAVE_POLL 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-#define HAVE_POLL_H 1
-
-/* Define to 1 if you have the `port_create' function. */
-/* #undef HAVE_PORT_CREATE */
-
-/* Define to 1 if you have the <port.h> header file. */
-/* #undef HAVE_PORT_H */
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/epoll.h> header file. */
-/* #undef HAVE_SYS_EPOLL_H */
-
-/* Define to 1 if you have the <sys/eventfd.h> header file. */
-/* #undef HAVE_SYS_EVENTFD_H */
-
-/* Define to 1 if you have the <sys/event.h> header file. */
-/* #undef HAVE_SYS_EVENT_H */
-
-/* Define to 1 if you have the <sys/inotify.h> header file. */
-/* #undef HAVE_SYS_INOTIFY_H */
-
-/* Define to 1 if you have the <sys/queue.h> header file. */
-#define HAVE_SYS_QUEUE_H 1
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libev"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "3.9"
diff --git a/deps/uv/src/unix/ev/config_darwin.h b/deps/uv/src/unix/ev/config_darwin.h
deleted file mode 100644
index 03e3b219e..000000000
--- a/deps/uv/src/unix/ev/config_darwin.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the `clock_gettime' function. */
-/* #undef HAVE_CLOCK_GETTIME */
-
-/* "use syscall interface for clock_gettime" */
-/* #undef HAVE_CLOCK_SYSCALL */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `epoll_ctl' function. */
-/* #undef HAVE_EPOLL_CTL */
-
-/* Define to 1 if you have the `eventfd' function. */
-/* #undef HAVE_EVENTFD */
-
-/* Define to 1 if you have the `inotify_init' function. */
-/* #undef HAVE_INOTIFY_INIT */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `kqueue' function. */
-#define HAVE_KQUEUE 1
-
-/* Define to 1 if you have the `m' library (-lm). */
-#define HAVE_LIBM 1
-
-/* Define to 1 if you have the `rt' library (-lrt). */
-/* #undef HAVE_LIBRT */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `nanosleep' function. */
-/* #undef HAVE_NANOSLEEP */
-
-/* Define to 1 if you have the `poll' function. */
-#define HAVE_POLL 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-#define HAVE_POLL_H 1
-
-/* Define to 1 if you have the `port_create' function. */
-/* #undef HAVE_PORT_CREATE */
-
-/* Define to 1 if you have the <port.h> header file. */
-/* #undef HAVE_PORT_H */
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the `signalfd' function. */
-/* #undef HAVE_SIGNALFD */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/epoll.h> header file. */
-/* #undef HAVE_SYS_EPOLL_H */
-
-/* Define to 1 if you have the <sys/eventfd.h> header file. */
-/* #undef HAVE_SYS_EVENTFD_H */
-
-/* Define to 1 if you have the <sys/event.h> header file. */
-#define HAVE_SYS_EVENT_H 1
-
-/* Define to 1 if you have the <sys/inotify.h> header file. */
-/* #undef HAVE_SYS_INOTIFY_H */
-
-/* Define to 1 if you have the <sys/queue.h> header file. */
-#define HAVE_SYS_QUEUE_H 1
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/signalfd.h> header file. */
-/* #undef HAVE_SYS_SIGNALFD_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Name of package */
-#define PACKAGE "libev"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "3.9"
diff --git a/deps/uv/src/unix/ev/config_freebsd.h b/deps/uv/src/unix/ev/config_freebsd.h
deleted file mode 100644
index ebebd4156..000000000
--- a/deps/uv/src/unix/ev/config_freebsd.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the `clock_gettime' function. */
-/* #undef HAVE_CLOCK_GETTIME */
-
-/* "use syscall interface for clock_gettime" */
-/* #undef HAVE_CLOCK_SYSCALL */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `epoll_ctl' function. */
-/* #undef HAVE_EPOLL_CTL */
-
-/* Define to 1 if you have the `eventfd' function. */
-/* #undef HAVE_EVENTFD */
-
-/* Define to 1 if you have the `inotify_init' function. */
-/* #undef HAVE_INOTIFY_INIT */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `kqueue' function. */
-#define HAVE_KQUEUE 1
-
-/* Define to 1 if you have the `m' library (-lm). */
-#define HAVE_LIBM 1
-
-/* Define to 1 if you have the `rt' library (-lrt). */
-/* #undef HAVE_LIBRT */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `nanosleep' function. */
-/* #undef HAVE_NANOSLEEP */
-
-/* Define to 1 if you have the `poll' function. */
-#define HAVE_POLL 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-#define HAVE_POLL_H 1
-
-/* Define to 1 if you have the `port_create' function. */
-/* #undef HAVE_PORT_CREATE */
-
-/* Define to 1 if you have the <port.h> header file. */
-/* #undef HAVE_PORT_H */
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/epoll.h> header file. */
-/* #undef HAVE_SYS_EPOLL_H */
-
-/* Define to 1 if you have the <sys/eventfd.h> header file. */
-/* #undef HAVE_SYS_EVENTFD_H */
-
-/* Define to 1 if you have the <sys/event.h> header file. */
-#define HAVE_SYS_EVENT_H 1
-
-/* Define to 1 if you have the <sys/inotify.h> header file. */
-/* #undef HAVE_SYS_INOTIFY_H */
-
-/* Define to 1 if you have the <sys/queue.h> header file. */
-#define HAVE_SYS_QUEUE_H 1
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libev"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "3.9"
diff --git a/deps/uv/src/unix/ev/config_linux.h b/deps/uv/src/unix/ev/config_linux.h
deleted file mode 100644
index a13b179f2..000000000
--- a/deps/uv/src/unix/ev/config_linux.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-#include <linux/version.h>
-#include <features.h>
-
-/* Define to 1 if you have the `clock_gettime' function. */
-/* #undef HAVE_CLOCK_GETTIME */
-
-/* "use syscall interface for clock_gettime" */
-#define HAVE_CLOCK_SYSCALL 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* epoll_ctl(2) is available if kernel >= 2.6.9 and glibc >= 2.4 */
-#if LINUX_VERSION_CODE >= 0x020609 && __GLIBC_PREREQ(2, 4)
-#define HAVE_EPOLL_CTL 1
-#else
-#define HAVE_EPOLL_CTL 0
-#endif
-
-/* eventfd(2) is available if kernel >= 2.6.22 and glibc >= 2.8 */
-#if LINUX_VERSION_CODE >= 0x020616 && __GLIBC_PREREQ(2, 8)
-#define HAVE_EVENTFD 1
-#else
-#define HAVE_EVENTFD 0
-#endif
-
-/* inotify_init(2) is available if kernel >= 2.6.13 and glibc >= 2.4 */
-#if LINUX_VERSION_CODE >= 0x02060d && __GLIBC_PREREQ(2, 4)
-#define HAVE_INOTIFY_INIT 1
-#else
-#define HAVE_INOTIFY_INIT 0
-#endif
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `kqueue' function. */
-/* #undef HAVE_KQUEUE */
-
-/* Define to 1 if you have the `m' library (-lm). */
-#define HAVE_LIBM 1
-
-/* Define to 1 if you have the `rt' library (-lrt). */
-/* #undef HAVE_LIBRT */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `nanosleep' function. */
-/* #undef HAVE_NANOSLEEP */
-
-/* Define to 1 if you have the `poll' function. */
-#define HAVE_POLL 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-#define HAVE_POLL_H 1
-
-/* Define to 1 if you have the `port_create' function. */
-/* #undef HAVE_PORT_CREATE */
-
-/* Define to 1 if you have the <port.h> header file. */
-/* #undef HAVE_PORT_H */
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* signalfd(2) is available if kernel >= 2.6.22 and glibc >= 2.8 */
-#if LINUX_VERSION_CODE >= 0x020616 && __GLIBC_PREREQ(2, 8)
-#define HAVE_SIGNALFD 1
-#else
-#define HAVE_SIGNALFD 0
-#endif
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/epoll.h> header file. */
-#define HAVE_SYS_EPOLL_H 1
-
-/* Define to 1 if you have the <sys/eventfd.h> header file. */
-#define HAVE_SYS_EVENTFD_H 1
-
-/* Define to 1 if you have the <sys/event.h> header file. */
-/* #undef HAVE_SYS_EVENT_H */
-
-/* Define to 1 if you have the <sys/inotify.h> header file. */
-#define HAVE_SYS_INOTIFY_H 1
-
-/* Define to 1 if you have the <sys/queue.h> header file. */
-#define HAVE_SYS_QUEUE_H 1
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/signalfd.h> header file. */
-#define HAVE_SYS_SIGNALFD_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Name of package */
-#define PACKAGE "libev"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "3.9"
diff --git a/deps/uv/src/unix/ev/config_netbsd.h b/deps/uv/src/unix/ev/config_netbsd.h
deleted file mode 100644
index ebebd4156..000000000
--- a/deps/uv/src/unix/ev/config_netbsd.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the `clock_gettime' function. */
-/* #undef HAVE_CLOCK_GETTIME */
-
-/* "use syscall interface for clock_gettime" */
-/* #undef HAVE_CLOCK_SYSCALL */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `epoll_ctl' function. */
-/* #undef HAVE_EPOLL_CTL */
-
-/* Define to 1 if you have the `eventfd' function. */
-/* #undef HAVE_EVENTFD */
-
-/* Define to 1 if you have the `inotify_init' function. */
-/* #undef HAVE_INOTIFY_INIT */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `kqueue' function. */
-#define HAVE_KQUEUE 1
-
-/* Define to 1 if you have the `m' library (-lm). */
-#define HAVE_LIBM 1
-
-/* Define to 1 if you have the `rt' library (-lrt). */
-/* #undef HAVE_LIBRT */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `nanosleep' function. */
-/* #undef HAVE_NANOSLEEP */
-
-/* Define to 1 if you have the `poll' function. */
-#define HAVE_POLL 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-#define HAVE_POLL_H 1
-
-/* Define to 1 if you have the `port_create' function. */
-/* #undef HAVE_PORT_CREATE */
-
-/* Define to 1 if you have the <port.h> header file. */
-/* #undef HAVE_PORT_H */
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/epoll.h> header file. */
-/* #undef HAVE_SYS_EPOLL_H */
-
-/* Define to 1 if you have the <sys/eventfd.h> header file. */
-/* #undef HAVE_SYS_EVENTFD_H */
-
-/* Define to 1 if you have the <sys/event.h> header file. */
-#define HAVE_SYS_EVENT_H 1
-
-/* Define to 1 if you have the <sys/inotify.h> header file. */
-/* #undef HAVE_SYS_INOTIFY_H */
-
-/* Define to 1 if you have the <sys/queue.h> header file. */
-#define HAVE_SYS_QUEUE_H 1
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libev"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "3.9"
diff --git a/deps/uv/src/unix/ev/config_openbsd.h b/deps/uv/src/unix/ev/config_openbsd.h
deleted file mode 100644
index 8bc9b8904..000000000
--- a/deps/uv/src/unix/ev/config_openbsd.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the `clock_gettime' function. */
-#define HAVE_CLOCK_GETTIME 1
-
-/* "use syscall interface for clock_gettime" */
-/* #undef HAVE_CLOCK_SYSCALL */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `epoll_ctl' function. */
-/* #undef HAVE_EPOLL_CTL */
-
-/* Define to 1 if you have the `eventfd' function. */
-/* #undef HAVE_EVENTFD */
-
-/* Define to 1 if you have the `inotify_init' function. */
-/* #undef HAVE_INOTIFY_INIT */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `kqueue' function. */
-#define HAVE_KQUEUE 1
-
-/* Define to 1 if you have the `m' library (-lm). */
-#define HAVE_LIBM 1
-
-/* Define to 1 if you have the `rt' library (-lrt). */
-/* #undef HAVE_LIBRT */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `nanosleep' function. */
-#define HAVE_NANOSLEEP 1
-
-/* Define to 1 if you have the `poll' function. */
-#define HAVE_POLL 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-#define HAVE_POLL_H 1
-
-/* Define to 1 if you have the `port_create' function. */
-/* #undef HAVE_PORT_CREATE */
-
-/* Define to 1 if you have the <port.h> header file. */
-/* #undef HAVE_PORT_H */
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the `signalfd' function. */
-/* #undef HAVE_SIGNALFD */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/epoll.h> header file. */
-/* #undef HAVE_SYS_EPOLL_H */
-
-/* Define to 1 if you have the <sys/eventfd.h> header file. */
-/* #undef HAVE_SYS_EVENTFD_H */
-
-/* Define to 1 if you have the <sys/event.h> header file. */
-#define HAVE_SYS_EVENT_H 1
-
-/* Define to 1 if you have the <sys/inotify.h> header file. */
-/* #undef HAVE_SYS_INOTIFY_H */
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/signalfd.h> header file. */
-/* #undef HAVE_SYS_SIGNALFD_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libev"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "4.04"
diff --git a/deps/uv/src/unix/ev/config_sunos.h b/deps/uv/src/unix/ev/config_sunos.h
deleted file mode 100644
index 9f8861d8a..000000000
--- a/deps/uv/src/unix/ev/config_sunos.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the `clock_gettime' function. */
-/* #undef HAVE_CLOCK_GETTIME */
-
-/* "use syscall interface for clock_gettime" */
-/* #undef HAVE_CLOCK_SYSCALL */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `epoll_ctl' function. */
-/* #undef HAVE_EPOLL_CTL */
-
-/* Define to 1 if you have the `eventfd' function. */
-/* #undef HAVE_EVENTFD */
-
-/* Define to 1 if you have the `inotify_init' function. */
-/* #undef HAVE_INOTIFY_INIT */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `kqueue' function. */
-/* #undef HAVE_KQUEUE */
-
-/* Define to 1 if you have the `m' library (-lm). */
-#define HAVE_LIBM 1
-
-/* Define to 1 if you have the `rt' library (-lrt). */
-/* #undef HAVE_LIBRT */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `nanosleep' function. */
-/* #undef HAVE_NANOSLEEP */
-
-/* Define to 1 if you have the `poll' function. */
-#define HAVE_POLL 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-#define HAVE_POLL_H 1
-
-/* Define to 1 if you have the `port_create' function. */
-#define HAVE_PORT_CREATE 1
-
-/* Define to 1 if you have the <port.h> header file. */
-#define HAVE_PORT_H 1
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the `signalfd' function. */
-/* #undef HAVE_SIGNALFD */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/epoll.h> header file. */
-/* #undef HAVE_SYS_EPOLL_H */
-
-/* Define to 1 if you have the <sys/eventfd.h> header file. */
-/* #undef HAVE_SYS_EVENTFD_H */
-
-/* Define to 1 if you have the <sys/event.h> header file. */
-/* #undef HAVE_SYS_EVENT_H */
-
-/* Define to 1 if you have the <sys/inotify.h> header file. */
-/* #undef HAVE_SYS_INOTIFY_H */
-
-/* Define to 1 if you have the <sys/queue.h> header file. */
-#define HAVE_SYS_QUEUE_H 1
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/signalfd.h> header file. */
-/* #undef HAVE_SYS_SIGNALFD_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Name of package */
-#define PACKAGE "libev"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "3.9"
diff --git a/deps/uv/src/unix/ev/configure b/deps/uv/src/unix/ev/configure
deleted file mode 100755
index 98f102f1e..000000000
--- a/deps/uv/src/unix/ev/configure
+++ /dev/null
@@ -1,13037 +0,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.67.
-#
-#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
-#
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='print -r --'
- as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in #(
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in #((
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test "x$CONFIG_SHELL" = x; then
- as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '\${1+\"\$@\"}'='\"\$@\"'
- setopt NO_GLOB_SUBST
-else
- case \`(set -o) 2>/dev/null\` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-"
- as_required="as_fn_return () { (exit \$1); }
-as_fn_success () { as_fn_return 0; }
-as_fn_failure () { as_fn_return 1; }
-as_fn_ret_success () { return 0; }
-as_fn_ret_failure () { return 1; }
-
-exitcode=0
-as_fn_success || { exitcode=1; echo as_fn_success failed.; }
-as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
-as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
-as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
-
-else
- exitcode=1; echo positional parameters were not saved.
-fi
-test x\$exitcode = x0 || exit 1"
- as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
- as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
- eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
- test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1"
- if (eval "$as_required") 2>/dev/null; then :
- as_have_required=yes
-else
- as_have_required=no
-fi
- if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
-
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_found=false
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- as_found=:
- case $as_dir in #(
- /*)
- for as_base in sh bash ksh sh5; do
- # Try only shells that exist, to save several forks.
- as_shell=$as_dir/$as_base
- if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
- CONFIG_SHELL=$as_shell as_have_required=yes
- if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
- break 2
-fi
-fi
- done;;
- esac
- as_found=false
-done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
- CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
-IFS=$as_save_IFS
-
-
- if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
-
- if test x$as_have_required = xno; then :
- $as_echo "$0: This script requires a shell more modern than all"
- $as_echo "$0: the shells that I found on your system."
- if test x${ZSH_VERSION+set} = xset ; then
- $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
- $as_echo "$0: be upgraded to zsh 4.3.4 or later."
- else
- $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
-$0: including any error possibly output before this
-$0: message. Then install a modern shell, or manually run
-$0: the script under such a shell if you do have one."
- fi
- exit 1
-fi
-fi
-fi
-SHELL=${CONFIG_SHELL-/bin/sh}
-export SHELL
-# Unset more variables known to interfere with behavior of common tools.
-CLICOLOR_FORCE= GREP_OPTIONS=
-unset CLICOLOR_FORCE GREP_OPTIONS
-
-## --------------------- ##
-## M4sh Shell Functions. ##
-## --------------------- ##
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
- { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || eval $as_mkdir_p || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
- eval 'as_fn_append ()
- {
- eval $1+=\$2
- }'
-else
- as_fn_append ()
- {
- eval $1=\$$1\$2
- }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
- as_status=$1; test $as_status -eq 0 && as_status=1
- if test "$4"; then
- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
- fi
- $as_echo "$as_me: error: $2" >&2
- as_fn_exit $as_status
-} # as_fn_error
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
- case `echo 'xy\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- xy) ECHO_C='\c';;
- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
- ECHO_T=' ';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -p'
- fi
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p='mkdir -p "$as_dir"'
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$lt_ECHO in
-X*--fallback-echo)
- # Remove one level of quotation (which was required for Make).
- ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','`
- ;;
-esac
-
-ECHO=${lt_ECHO-echo}
-if test "X$1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X$1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
- # Yippee, $ECHO works!
- :
-else
- # Restart under the correct shell.
- exec $SHELL "$0" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<_LT_EOF
-$*
-_LT_EOF
- exit 0
-fi
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$lt_ECHO"; then
- if test "X${echo_test_string+set}" != Xset; then
- # find a string as large as possible, as long as the shell can cope with it
- for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
- { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
- then
- break
- fi
- done
- fi
-
- if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- :
- else
- # The Solaris, AIX, and Digital Unix default echo programs unquote
- # backslashes. This makes it impossible to quote backslashes using
- # echo "$something" | sed 's/\\/\\\\/g'
- #
- # So, first we look for a working echo in the user's PATH.
-
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for dir in $PATH /usr/ucb; do
- IFS="$lt_save_ifs"
- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- ECHO="$dir/echo"
- break
- fi
- done
- IFS="$lt_save_ifs"
-
- if test "X$ECHO" = Xecho; then
- # We didn't find a better echo, so look for alternatives.
- if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # This shell has a builtin print -r that does the trick.
- ECHO='print -r'
- elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
- test "X$CONFIG_SHELL" != X/bin/ksh; then
- # If we have ksh, try running configure again with it.
- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
- export ORIGINAL_CONFIG_SHELL
- CONFIG_SHELL=/bin/ksh
- export CONFIG_SHELL
- exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
- else
- # Try using printf.
- ECHO='printf %s\n'
- if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # Cool, printf works
- :
- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
- export CONFIG_SHELL
- SHELL="$CONFIG_SHELL"
- export SHELL
- ECHO="$CONFIG_SHELL $0 --fallback-echo"
- elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- ECHO="$CONFIG_SHELL $0 --fallback-echo"
- else
- # maybe with a smaller string...
- prev=:
-
- for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
- if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
- then
- break
- fi
- prev="$cmd"
- done
-
- if test "$prev" != 'sed 50q "$0"'; then
- echo_test_string=`eval $prev`
- export echo_test_string
- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
- else
- # Oops. We lost completely, so just stick with echo.
- ECHO=echo
- fi
- fi
- fi
- fi
- fi
-fi
-
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-lt_ECHO=$ECHO
-if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
- lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
-fi
-
-
-
-
-test -n "$DJDIR" || exec 7<&0 </dev/null
-exec 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-
-# Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
-PACKAGE_URL=
-
-ac_unique_file="ev_epoll.c"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-# include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_subst_vars='am__EXEEXT_FALSE
-am__EXEEXT_TRUE
-LTLIBOBJS
-LIBOBJS
-CPP
-OTOOL64
-OTOOL
-LIPO
-NMEDIT
-DSYMUTIL
-lt_ECHO
-RANLIB
-AR
-OBJDUMP
-LN_S
-NM
-ac_ct_DUMPBIN
-DUMPBIN
-LD
-FGREP
-EGREP
-GREP
-SED
-am__fastdepCC_FALSE
-am__fastdepCC_TRUE
-CCDEPMODE
-AMDEPBACKSLASH
-AMDEP_FALSE
-AMDEP_TRUE
-am__quote
-am__include
-DEPDIR
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
-host_os
-host_vendor
-host_cpu
-host
-build_os
-build_vendor
-build_cpu
-build
-LIBTOOL
-MAINT
-MAINTAINER_MODE_FALSE
-MAINTAINER_MODE_TRUE
-am__untar
-am__tar
-AMTAR
-am__leading_dot
-SET_MAKE
-AWK
-mkdir_p
-MKDIR_P
-INSTALL_STRIP_PROGRAM
-STRIP
-install_sh
-MAKEINFO
-AUTOHEADER
-AUTOMAKE
-AUTOCONF
-ACLOCAL
-VERSION
-PACKAGE
-CYGPATH_W
-am__isrc
-INSTALL_DATA
-INSTALL_SCRIPT
-INSTALL_PROGRAM
-target_alias
-host_alias
-build_alias
-LIBS
-ECHO_T
-ECHO_N
-ECHO_C
-DEFS
-mandir
-localedir
-libdir
-psdir
-pdfdir
-dvidir
-htmldir
-infodir
-docdir
-oldincludedir
-includedir
-localstatedir
-sharedstatedir
-sysconfdir
-datadir
-datarootdir
-libexecdir
-sbindir
-bindir
-program_transform_name
-prefix
-exec_prefix
-PACKAGE_URL
-PACKAGE_BUGREPORT
-PACKAGE_STRING
-PACKAGE_VERSION
-PACKAGE_TARNAME
-PACKAGE_NAME
-PATH_SEPARATOR
-SHELL'
-ac_subst_files=''
-ac_user_opts='
-enable_option_checking
-enable_maintainer_mode
-enable_shared
-enable_static
-with_pic
-enable_fast_install
-enable_dependency_tracking
-with_gnu_ld
-enable_libtool_lock
-'
- ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS
-CPP'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-ac_unrecognized_opts=
-ac_unrecognized_sep=
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval $ac_prev=\$ac_option
- ac_prev=
- continue
- fi
-
- case $ac_option in
- *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *=) ac_optarg= ;;
- *) ac_optarg=yes ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case $ac_dashdash$ac_option in
- --)
- ac_dashdash=yes ;;
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir=$ac_optarg ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build_alias ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build_alias=$ac_optarg ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file=$ac_optarg ;;
-
- --config-cache | -C)
- cache_file=config.cache ;;
-
- -datadir | --datadir | --datadi | --datad)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=*)
- datadir=$ac_optarg ;;
-
- -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
- | --dataroo | --dataro | --datar)
- ac_prev=datarootdir ;;
- -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
- | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
- datarootdir=$ac_optarg ;;
-
- -disable-* | --disable-*)
- ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"enable_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval enable_$ac_useropt=no ;;
-
- -docdir | --docdir | --docdi | --doc | --do)
- ac_prev=docdir ;;
- -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
- docdir=$ac_optarg ;;
-
- -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
- ac_prev=dvidir ;;
- -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
- dvidir=$ac_optarg ;;
-
- -enable-* | --enable-*)
- ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"enable_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval enable_$ac_useropt=\$ac_optarg ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix=$ac_optarg ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he | -h)
- ac_init_help=long ;;
- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
- ac_init_help=recursive ;;
- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
- ac_init_help=short ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host_alias ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host_alias=$ac_optarg ;;
-
- -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
- ac_prev=htmldir ;;
- -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
- | --ht=*)
- htmldir=$ac_optarg ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir=$ac_optarg ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir=$ac_optarg ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir=$ac_optarg ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir=$ac_optarg ;;
-
- -localedir | --localedir | --localedi | --localed | --locale)
- ac_prev=localedir ;;
- -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
- localedir=$ac_optarg ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst | --locals)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
- localstatedir=$ac_optarg ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir=$ac_optarg ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir=$ac_optarg ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix=$ac_optarg ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix=$ac_optarg ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix=$ac_optarg ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name=$ac_optarg ;;
-
- -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
- ac_prev=pdfdir ;;
- -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
- pdfdir=$ac_optarg ;;
-
- -psdir | --psdir | --psdi | --psd | --ps)
- ac_prev=psdir ;;
- -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
- psdir=$ac_optarg ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir=$ac_optarg ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site=$ac_optarg ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir=$ac_optarg ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir=$ac_optarg ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target_alias ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target_alias=$ac_optarg ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers | -V)
- ac_init_version=: ;;
-
- -with-* | --with-*)
- ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"with_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval with_$ac_useropt=\$ac_optarg ;;
-
- -without-* | --without-*)
- ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"with_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval with_$ac_useropt=no ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes=$ac_optarg ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries=$ac_optarg ;;
-
- -*) as_fn_error $? "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information"
- ;;
-
- *=*)
- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
- # Reject names that are not valid shell variable names.
- case $ac_envvar in #(
- '' | [0-9]* | *[!_$as_cr_alnum]* )
- as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
- esac
- eval $ac_envvar=\$ac_optarg
- export $ac_envvar ;;
-
- *)
- # FIXME: should be removed in autoconf 3.0.
- $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- as_fn_error $? "missing argument to $ac_option"
-fi
-
-if test -n "$ac_unrecognized_opts"; then
- case $enable_option_checking in
- no) ;;
- fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
- *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
- esac
-fi
-
-# Check all directory arguments for consistency.
-for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
- datadir sysconfdir sharedstatedir localstatedir includedir \
- oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
-do
- eval ac_val=\$$ac_var
- # Remove trailing slashes.
- case $ac_val in
- */ )
- ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
- eval $ac_var=\$ac_val;;
- esac
- # Be sure to have absolute directory names.
- case $ac_val in
- [\\/$]* | ?:[\\/]* ) continue;;
- NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
- esac
- as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
- if test "x$build_alias" = x; then
- cross_compiling=maybe
- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used" >&2
- elif test "x$build_alias" != "x$host_alias"; then
- cross_compiling=yes
- fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- as_fn_error $? "working directory cannot be determined"
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- as_fn_error $? "pwd does not report name of working directory"
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then the parent directory.
- ac_confdir=`$as_dirname -- "$as_myself" ||
-$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_myself" : 'X\(//\)[^/]' \| \
- X"$as_myself" : 'X\(//\)$' \| \
- X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- srcdir=$ac_confdir
- if test ! -r "$srcdir/$ac_unique_file"; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
- test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
- pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
- srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
- eval ac_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_env_${ac_var}_value=\$${ac_var}
- eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --help=short display options specific to this package
- --help=recursive display the short help of all the included packages
- -V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking ...' messages
- --cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for \`--cache-file=config.cache'
- -n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
- --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
- --infodir=DIR info documentation [DATAROOTDIR/info]
- --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
- --mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
- --htmldir=DIR html documentation [DOCDIR]
- --dvidir=DIR dvi documentation [DOCDIR]
- --pdfdir=DIR pdf documentation [DOCDIR]
- --psdir=DIR ps documentation [DOCDIR]
-_ACEOF
-
- cat <<\_ACEOF
-
-Program names:
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM run sed PROGRAM on installed program names
-
-System types:
- --build=BUILD configure for building on BUILD [guessed]
- --host=HOST cross-compile to build programs to run on HOST [BUILD]
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
-
- cat <<\_ACEOF
-
-Optional Features:
- --disable-option-checking ignore unrecognized --enable/--with options
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-maintainer-mode enable make rules and dependencies not useful
- (and sometimes confusing) to the casual installer
- --enable-shared[=PKGS] build shared libraries [default=yes]
- --enable-static[=PKGS] build static libraries [default=yes]
- --enable-fast-install[=PKGS]
- optimize for fast installation [default=yes]
- --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors
- --disable-libtool-lock avoid locking (might break parallel builds)
-
-Optional Packages:
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --with-pic try to use only PIC/non-PIC objects [default=use
- both]
- --with-gnu-ld assume the C compiler uses GNU ld [default=no]
-
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- LIBS libraries to pass to the linker, e.g. -l<library>
- CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
- you have headers in a nonstandard directory <include dir>
- CPP C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to the package provider.
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
- # If there are subdirs, report their specific --help.
- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d "$ac_dir" ||
- { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
- continue
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
- cd "$ac_dir" || { ac_status=$?; continue; }
- # Check for guested configure.
- if test -f "$ac_srcdir/configure.gnu"; then
- echo &&
- $SHELL "$ac_srcdir/configure.gnu" --help=recursive
- elif test -f "$ac_srcdir/configure"; then
- echo &&
- $SHELL "$ac_srcdir/configure" --help=recursive
- else
- $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi || ac_status=$?
- cd "$ac_pwd" || { ac_status=$?; break; }
- done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
- cat <<\_ACEOF
-configure
-generated by GNU Autoconf 2.67
-
-Copyright (C) 2010 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
- exit
-fi
-
-## ------------------------ ##
-## Autoconf initialization. ##
-## ------------------------ ##
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
-
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext && {
- test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
- # interfere with the next link command; also delete a directory that is
- # left behind by Apple's compiler. We do this before executing the actions.
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_header_compile
-
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } > conftest.i && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_cpp
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then :
- ac_retval=0
-else
- $as_echo "$as_me: program exited with status $ac_status" >&5
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=$ac_status
-fi
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
-
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $2 (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_func
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if eval "test \"\${$3+set}\"" = set; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
- $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
- # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_header_compiler=yes
-else
- ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- ac_header_preproc=yes
-else
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
- yes:no: )
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
- ;;
- no:yes:* )
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
- ;;
-esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_header_mongrel
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by $as_me, which was
-generated by GNU Autoconf 2.67. Invocation command line was
-
- $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
-
-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- $as_echo "PATH: $as_dir"
- done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
- for ac_arg
- do
- case $ac_arg in
- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- continue ;;
- *\'*)
- ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case $ac_pass in
- 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
- 2)
- as_fn_append ac_configure_args1 " '$ac_arg'"
- if test $ac_must_keep_next = true; then
- ac_must_keep_next=false # Got value, back to normal.
- else
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
- fi
- as_fn_append ac_configure_args " '$ac_arg'"
- ;;
- esac
- done
-done
-{ ac_configure_args0=; unset ac_configure_args0;}
-{ ac_configure_args1=; unset ac_configure_args1;}
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log. We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
- # Save into config.log some information that might help in debugging.
- {
- echo
-
- $as_echo "## ---------------- ##
-## Cache variables. ##
-## ---------------- ##"
- echo
- # The following way of writing the cache mishandles newlines in values,
-(
- for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
- *) { eval $ac_var=; unset $ac_var;} ;;
- esac ;;
- esac
- done
- (set) 2>&1 |
- case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- sed -n \
- "s/'\''/'\''\\\\'\'''\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
- ;; #(
- *)
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-)
- echo
-
- $as_echo "## ----------------- ##
-## Output variables. ##
-## ----------------- ##"
- echo
- for ac_var in $ac_subst_vars
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- $as_echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
-
- if test -n "$ac_subst_files"; then
- $as_echo "## ------------------- ##
-## File substitutions. ##
-## ------------------- ##"
- echo
- for ac_var in $ac_subst_files
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- $as_echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
- fi
-
- if test -s confdefs.h; then
- $as_echo "## ----------- ##
-## confdefs.h. ##
-## ----------- ##"
- echo
- cat confdefs.h
- echo
- fi
- test "$ac_signal" != 0 &&
- $as_echo "$as_me: caught signal $ac_signal"
- $as_echo "$as_me: exit $exit_status"
- } >&5
- rm -f core *.core core.conftest.* &&
- rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
- exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-$as_echo "/* confdefs.h */" > confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
-if test -n "$CONFIG_SITE"; then
- # We do not want a PATH search for config.site.
- case $CONFIG_SITE in #((
- -*) ac_site_file1=./$CONFIG_SITE;;
- */*) ac_site_file1=$CONFIG_SITE;;
- *) ac_site_file1=./$CONFIG_SITE;;
- esac
-elif test "x$prefix" != xNONE; then
- ac_site_file1=$prefix/share/config.site
- ac_site_file2=$prefix/etc/config.site
-else
- ac_site_file1=$ac_default_prefix/share/config.site
- ac_site_file2=$ac_default_prefix/etc/config.site
-fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
-do
- test "x$ac_site_file" = xNONE && continue
- if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
- sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file" \
- || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5 ; }
- fi
-done
-
-if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special files
- # actually), so we avoid doing that. DJGPP emulates it as a regular file.
- if test /dev/null != "$cache_file" && test -f "$cache_file"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . "$cache_file";;
- *) . "./$cache_file";;
- esac
- fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val=\$ac_cv_env_${ac_var}_value
- eval ac_new_val=\$ac_env_${ac_var}_value
- case $ac_old_set,$ac_new_set in
- set,)
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- # differences in whitespace do not lead to failure.
- ac_old_val_w=`echo x $ac_old_val`
- ac_new_val_w=`echo x $ac_new_val`
- if test "$ac_old_val_w" != "$ac_new_val_w"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- ac_cache_corrupted=:
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
- eval $ac_var=\$ac_old_val
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
-$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
-$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) as_fn_append ac_configure_args " '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-am__api_version='1.11'
-
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- if test -f "$ac_dir/install-sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f "$ac_dir/install.sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- elif test -f "$ac_dir/shtool"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/shtool install -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
-
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AmigaOS /C/install, which installs bootblocks on floppy discs
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# OS/2's system install, which has a completely different semantic
-# ./install, which can be erroneously created by make from ./install.sh.
-# Reject install programs that cannot install multiple files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
-$as_echo_n "checking for a BSD-compatible install... " >&6; }
-if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in #((
- ./ | .// | /[cC]/* | \
- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
- ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
- /usr/ucb/* ) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- # Don't use installbsd from OSF since it installs stuff as root
- # by default.
- for ac_prog in ginstall scoinst install; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
- if test $ac_prog = install &&
- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- :
- elif test $ac_prog = install &&
- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # program-specific install script used by HP pwplus--don't use.
- :
- else
- rm -rf conftest.one conftest.two conftest.dir
- echo one > conftest.one
- echo two > conftest.two
- mkdir conftest.dir
- if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
- test -s conftest.one && test -s conftest.two &&
- test -s conftest.dir/conftest.one &&
- test -s conftest.dir/conftest.two
- then
- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
- break 3
- fi
- fi
- fi
- done
- done
- ;;
-esac
-
- done
-IFS=$as_save_IFS
-
-rm -rf conftest.one conftest.two conftest.dir
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL=$ac_cv_path_install
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- INSTALL=$ac_install_sh
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
-$as_echo "$INSTALL" >&6; }
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
-$as_echo_n "checking whether build environment is sane... " >&6; }
-# Just in case
-sleep 1
-echo timestamp > conftest.file
-# Reject unsafe characters in $srcdir or the absolute working directory
-# name. Accept space and tab only in the latter.
-am_lf='
-'
-case `pwd` in
- *[\\\"\#\$\&\'\`$am_lf]*)
- as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5 ;;
-esac
-case $srcdir in
- *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
- as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5 ;;
-esac
-
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$*" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$*" != "X $srcdir/configure conftest.file" \
- && test "$*" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
-alias in your environment" "$LINENO" 5
- fi
-
- test "$2" = conftest.file
- )
-then
- # Ok.
- :
-else
- as_fn_error $? "newly created file is older than distributed files!
-Check your system clock" "$LINENO" 5
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-test "$program_prefix" != NONE &&
- program_transform_name="s&^&$program_prefix&;$program_transform_name"
-# Use a double $ so make ignores it.
-test "$program_suffix" != NONE &&
- program_transform_name="s&\$&$program_suffix&;$program_transform_name"
-# Double any \ or $.
-# By default was `s,x,x', remove it if useless.
-ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
-program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
-
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-
-if test x"${MISSING+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
- *)
- MISSING="\${SHELL} $am_aux_dir/missing" ;;
- esac
-fi
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
-else
- am_missing_run=
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
-$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
-fi
-
-if test x"${install_sh}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
- *)
- install_sh="\${SHELL} $am_aux_dir/install-sh"
- esac
-fi
-
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-if test "$cross_compiling" != no; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
-set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$STRIP"; then
- ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_STRIP="${ac_tool_prefix}strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-STRIP=$ac_cv_prog_STRIP
-if test -n "$STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
-$as_echo "$STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_STRIP"; then
- ac_ct_STRIP=$STRIP
- # Extract the first word of "strip", so it can be a program name with args.
-set dummy strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_STRIP"; then
- ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_STRIP="strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
-if test -n "$ac_ct_STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
-$as_echo "$ac_ct_STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_STRIP" = x; then
- STRIP=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- STRIP=$ac_ct_STRIP
- fi
-else
- STRIP="$ac_cv_prog_STRIP"
-fi
-
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
-$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
-if test -z "$MKDIR_P"; then
- if test "${ac_cv_path_mkdir+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in mkdir gmkdir; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
- case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
- 'mkdir (GNU coreutils) '* | \
- 'mkdir (coreutils) '* | \
- 'mkdir (fileutils) '4.1*)
- ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
- break 3;;
- esac
- done
- done
- done
-IFS=$as_save_IFS
-
-fi
-
- test -d ./--version && rmdir ./--version
- if test "${ac_cv_path_mkdir+set}" = set; then
- MKDIR_P="$ac_cv_path_mkdir -p"
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for MKDIR_P within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- MKDIR_P="$ac_install_sh -d"
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
-$as_echo "$MKDIR_P" >&6; }
-
-mkdir_p="$MKDIR_P"
-case $mkdir_p in
- [\\/$]* | ?:[\\/]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-
-for ac_prog in gawk mawk nawk awk
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$AWK"; then
- ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AWK="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-AWK=$ac_cv_prog_AWK
-if test -n "$AWK"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
-$as_echo "$AWK" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$AWK" && break
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
-set x ${MAKE-make}
-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat >conftest.make <<\_ACEOF
-SHELL = /bin/sh
-all:
- @echo '@@@%%%=$(MAKE)=@@@%%%'
-_ACEOF
-# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
-case `${MAKE-make} -f conftest.make 2>/dev/null` in
- *@@@%%%=?*=@@@%%%*)
- eval ac_cv_prog_make_${ac_make}_set=yes;;
- *)
- eval ac_cv_prog_make_${ac_make}_set=no;;
-esac
-rm -f conftest.make
-fi
-if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- SET_MAKE=
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- am__isrc=' -I$(srcdir)'
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-
-
-# Define the identity of the package.
- PACKAGE=libev
- VERSION=4.04
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE "$PACKAGE"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define VERSION "$VERSION"
-_ACEOF
-
-# Some tools Automake needs.
-
-ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
-
-
-AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
-
-
-AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
-
-
-AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
-
-
-MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
-
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
-# Always define AMTAR for backward compatibility.
-
-AMTAR=${AMTAR-"${am_missing_run}tar"}
-
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
-
-
-
-
- ac_config_headers="$ac_config_headers config.h"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
-$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
- # Check whether --enable-maintainer-mode was given.
-if test "${enable_maintainer_mode+set}" = set; then :
- enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
-else
- USE_MAINTAINER_MODE=no
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
-$as_echo "$USE_MAINTAINER_MODE" >&6; }
- if test $USE_MAINTAINER_MODE = yes; then
- MAINTAINER_MODE_TRUE=
- MAINTAINER_MODE_FALSE='#'
-else
- MAINTAINER_MODE_TRUE='#'
- MAINTAINER_MODE_FALSE=
-fi
-
- MAINT=$MAINTAINER_MODE_TRUE
-
-
-
-
-case `pwd` in
- *\ * | *\ *)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
-$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
-esac
-
-
-
-macro_version='2.2.6b'
-macro_revision='1.3017'
-
-
-
-
-
-
-
-
-
-
-
-
-
-ltmain="$ac_aux_dir/ltmain.sh"
-
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
- as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if test "${ac_cv_build+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
- ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
- as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if test "${ac_cv_host+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "x$host_alias" = x; then
- ac_cv_host=$ac_cv_build
-else
- ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-
-
-DEPDIR="${am__leading_dot}deps"
-
-ac_config_commands="$ac_config_commands depfiles"
-
-
-am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo this is the am__doit target
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
- am__include=include
- am__quote=
- _am_result=GNU
- ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- case `$am_make -s -f confmf 2> /dev/null` in #(
- *the\ am__doit\ target*)
- am__include=.include
- am__quote="\""
- _am_result=BSD
- ;;
- esac
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
-
-# Check whether --enable-dependency-tracking was given.
-if test "${enable_dependency_tracking+set}" = set; then :
- enableval=$enable_dependency_tracking;
-fi
-
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
-fi
- if test "x$enable_dependency_tracking" != xno; then
- AMDEP_TRUE=
- AMDEP_FALSE='#'
-else
- AMDEP_TRUE='#'
- AMDEP_FALSE=
-fi
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="gcc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- fi
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl.exe
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl.exe
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_CC" && break
-done
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-fi
-
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5 ; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
- { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compiler $ac_option >&5") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- sed '10a\
-... rest of stderr output deleted ...
- 10q' conftest.err >conftest.er1
- cat conftest.er1 >&5
- fi
- rm -f conftest.er1 conftest.err
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-done
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
-
-ac_rmfiles=
-for ac_file in $ac_files
-do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- * ) ac_rmfiles="$ac_rmfiles $ac_file";;
- esac
-done
-rm -f $ac_rmfiles
-
-if { { ac_try="$ac_link_default"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link_default") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile. We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
- then :; else
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- fi
- # We set ac_cv_exeext here because the later test for it is not
- # safe: cross compilers may not add the suffix if given an `-o'
- # argument, so we may need to know it at that point already.
- # Even if this section looks crufty: it has the advantage of
- # actually working.
- break;;
- * )
- break;;
- esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
- ac_file=''
-fi
-if test -z "$ac_file"; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5 ; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-ac_exeext=$ac_cv_exeext
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- break;;
- * ) break;;
- esac
-done
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5 ; }
-fi
-rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdio.h>
-int
-main ()
-{
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files="$ac_clean_files conftest.out"
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-if test "$cross_compiling" != yes; then
- { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
- if { ac_try='./conftest$ac_cv_exeext'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5 ; }
- fi
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
-rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if test "${ac_cv_objext+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- for ac_file in conftest.o conftest.obj conftest.*; do
- test -f "$ac_file" || continue;
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5 ; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_compiler_gnu=yes
-else
- ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
- GCC=yes
-else
- GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_save_c_werror_flag=$ac_c_werror_flag
- ac_c_werror_flag=yes
- ac_cv_prog_cc_g=no
- CFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_g=yes
-else
- CFLAGS=""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- ac_c_werror_flag=$ac_save_c_werror_flag
- CFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
- inside strings and character constants. */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
- test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
- x)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
- xno)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c89"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-depcc="$CC" am_compiler_list=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
-$as_echo_n "checking dependency style of $depcc... " >&6; }
-if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_CC_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
- fi
- am__universal=false
- case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac
-
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
- am__obj=sub/conftest.${OBJEXT-o}
- am__minus_obj="-o $am__obj"
- case $depmode in
- gcc)
- # This depmode causes a compiler race in universal mode.
- test "$am__universal" = false || continue
- ;;
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
- # not run yet. These depmodes are late enough in the game, and
- # so weak that their functioning should not be impacted.
- am__obj=conftest.${OBJEXT-o}
- am__minus_obj=
- ;;
- none) break ;;
- esac
- if depmode=$depmode \
- source=sub/conftest.c object=$am__obj \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_CC_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_CC_dependencies_compiler_type=none
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
-$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
-CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
-
- if
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
- am__fastdepCC_TRUE=
- am__fastdepCC_FALSE='#'
-else
- am__fastdepCC_TRUE='#'
- am__fastdepCC_FALSE=
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
-$as_echo_n "checking for a sed that does not truncate output... " >&6; }
-if test "${ac_cv_path_SED+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
- for ac_i in 1 2 3 4 5 6 7; do
- ac_script="$ac_script$as_nl$ac_script"
- done
- echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
- { ac_script=; unset ac_script;}
- if test -z "$SED"; then
- ac_path_SED_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in sed gsed; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
-# Check for GNU ac_path_SED and select it if it is found.
- # Check for GNU $ac_path_SED
-case `"$ac_path_SED" --version 2>&1` in
-*GNU*)
- ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo '' >> "conftest.nl"
- "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_SED_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_SED="$ac_path_SED"
- ac_path_SED_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_SED_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_SED"; then
- as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
- fi
-else
- ac_cv_path_SED=$SED
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
-$as_echo "$ac_cv_path_SED" >&6; }
- SED="$ac_cv_path_SED"
- rm -f conftest.sed
-
-test -z "$SED" && SED=sed
-Xsed="$SED -e 1s/^X//"
-
-
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$GREP"; then
- ac_path_GREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in grep ggrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
-# Check for GNU ac_path_GREP and select it if it is found.
- # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'GREP' >> "conftest.nl"
- "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_GREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_GREP="$ac_path_GREP"
- ac_path_GREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_GREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_GREP"; then
- as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_GREP=$GREP
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
- then ac_cv_path_EGREP="$GREP -E"
- else
- if test -z "$EGREP"; then
- ac_path_EGREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in egrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
- # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'EGREP' >> "conftest.nl"
- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_EGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_EGREP="$ac_path_EGREP"
- ac_path_EGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_EGREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_EGREP"; then
- as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_EGREP=$EGREP
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
-$as_echo_n "checking for fgrep... " >&6; }
-if test "${ac_cv_path_FGREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
- then ac_cv_path_FGREP="$GREP -F"
- else
- if test -z "$FGREP"; then
- ac_path_FGREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in fgrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
-# Check for GNU ac_path_FGREP and select it if it is found.
- # Check for GNU $ac_path_FGREP
-case `"$ac_path_FGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'FGREP' >> "conftest.nl"
- "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_FGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_FGREP="$ac_path_FGREP"
- ac_path_FGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_FGREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_FGREP"; then
- as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_FGREP=$FGREP
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
-$as_echo "$ac_cv_path_FGREP" >&6; }
- FGREP="$ac_cv_path_FGREP"
-
-
-test -z "$GREP" && GREP=grep
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
- with_gnu_ld=no
-fi
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
-$as_echo_n "checking for ld used by $CC... " >&6; }
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [\\/]* | ?:[\\/]*)
- re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
- while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
-$as_echo_n "checking for GNU ld... " >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
-$as_echo_n "checking for non-GNU ld... " >&6; }
-fi
-if test "${lt_cv_path_LD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
-$as_echo "$LD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
-$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
-$as_echo "$lt_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$lt_cv_prog_gnu_ld
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
-$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
-if test "${lt_cv_path_NM+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$NM"; then
- # Let the user override the test.
- lt_cv_path_NM="$NM"
-else
- lt_nm_to_check="${ac_tool_prefix}nm"
- if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
- lt_nm_to_check="$lt_nm_to_check nm"
- fi
- for lt_tmp_nm in $lt_nm_to_check; do
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- tmp_nm="$ac_dir/$lt_tmp_nm"
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
- # Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
- # nm: unknown option "B" ignored
- # Tru64's nm complains that /dev/null is an invalid object file
- case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
- */dev/null* | *'Invalid file or object type'*)
- lt_cv_path_NM="$tmp_nm -B"
- break
- ;;
- *)
- case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
- */dev/null*)
- lt_cv_path_NM="$tmp_nm -p"
- break
- ;;
- *)
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
- continue # so that we can try to find one that supports BSD flags
- ;;
- esac
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
- done
- : ${lt_cv_path_NM=no}
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
-$as_echo "$lt_cv_path_NM" >&6; }
-if test "$lt_cv_path_NM" != "no"; then
- NM="$lt_cv_path_NM"
-else
- # Didn't find any BSD compatible name lister, look for dumpbin.
- if test -n "$ac_tool_prefix"; then
- for ac_prog in "dumpbin -symbols" "link -dump -symbols"
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$DUMPBIN"; then
- ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-DUMPBIN=$ac_cv_prog_DUMPBIN
-if test -n "$DUMPBIN"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
-$as_echo "$DUMPBIN" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$DUMPBIN" && break
- done
-fi
-if test -z "$DUMPBIN"; then
- ac_ct_DUMPBIN=$DUMPBIN
- for ac_prog in "dumpbin -symbols" "link -dump -symbols"
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_DUMPBIN"; then
- ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
-if test -n "$ac_ct_DUMPBIN"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
-$as_echo "$ac_ct_DUMPBIN" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_DUMPBIN" && break
-done
-
- if test "x$ac_ct_DUMPBIN" = x; then
- DUMPBIN=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- DUMPBIN=$ac_ct_DUMPBIN
- fi
-fi
-
-
- if test "$DUMPBIN" != ":"; then
- NM="$DUMPBIN"
- fi
-fi
-test -z "$NM" && NM=nm
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
-$as_echo_n "checking the name lister ($NM) interface... " >&6; }
-if test "${lt_cv_nm_interface+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_nm_interface="BSD nm"
- echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:4494: $ac_compile\"" >&5)
- (eval "$ac_compile" 2>conftest.err)
- cat conftest.err >&5
- (eval echo "\"\$as_me:4497: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
- (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
- cat conftest.err >&5
- (eval echo "\"\$as_me:4500: output\"" >&5)
- cat conftest.out >&5
- if $GREP 'External.*some_variable' conftest.out > /dev/null; then
- lt_cv_nm_interface="MS dumpbin"
- fi
- rm -f conftest*
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
-$as_echo "$lt_cv_nm_interface" >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
-$as_echo_n "checking whether ln -s works... " >&6; }
-LN_S=$as_ln_s
-if test "$LN_S" = "ln -s"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
-$as_echo "no, using $LN_S" >&6; }
-fi
-
-# find the maximum length of command line arguments
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
-$as_echo_n "checking the maximum length of command line arguments... " >&6; }
-if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- i=0
- teststring="ABCD"
-
- case $build_os in
- msdosdjgpp*)
- # On DJGPP, this test can blow up pretty badly due to problems in libc
- # (any single argument exceeding 2000 bytes causes a buffer overrun
- # during glob expansion). Even if it were fixed, the result of this
- # check would be larger than it should be.
- lt_cv_sys_max_cmd_len=12288; # 12K is about right
- ;;
-
- gnu*)
- # Under GNU Hurd, this test is not required because there is
- # no limit to the length of command line arguments.
- # Libtool will interpret -1 as no limit whatsoever
- lt_cv_sys_max_cmd_len=-1;
- ;;
-
- cygwin* | mingw* | cegcc*)
- # On Win9x/ME, this test blows up -- it succeeds, but takes
- # about 5 minutes as the teststring grows exponentially.
- # Worse, since 9x/ME are not pre-emptively multitasking,
- # you end up with a "frozen" computer, even though with patience
- # the test eventually succeeds (with a max line length of 256k).
- # Instead, let's just punt: use the minimum linelength reported by
- # all of the supported platforms: 8192 (on NT/2K/XP).
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- amigaos*)
- # On AmigaOS with pdksh, this test takes hours, literally.
- # So we just punt and use a minimum line length of 8192.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
- # This has been around since 386BSD, at least. Likely further.
- if test -x /sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
- elif test -x /usr/sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
- else
- lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
- fi
- # And add a safety zone
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- ;;
-
- interix*)
- # We know the value 262144 and hardcode it with a safety zone (like BSD)
- lt_cv_sys_max_cmd_len=196608
- ;;
-
- osf*)
- # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
- # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
- # nice to cause kernel panics so lets avoid the loop below.
- # First set a reasonable default.
- lt_cv_sys_max_cmd_len=16384
- #
- if test -x /sbin/sysconfig; then
- case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
- *1*) lt_cv_sys_max_cmd_len=-1 ;;
- esac
- fi
- ;;
- sco3.2v5*)
- lt_cv_sys_max_cmd_len=102400
- ;;
- sysv5* | sco5v6* | sysv4.2uw2*)
- kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
- if test -n "$kargmax"; then
- lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
- else
- lt_cv_sys_max_cmd_len=32768
- fi
- ;;
- *)
- lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- else
- # Make teststring a little bigger before we do anything with it.
- # a 1K string should be a reasonable start.
- for i in 1 2 3 4 5 6 7 8 ; do
- teststring=$teststring$teststring
- done
- SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
- # If test is not a shell built-in, we'll probably end up computing a
- # maximum length that is only half of the actual maximum length, but
- # we can't tell.
- while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
- = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
- test $i != 17 # 1/2 MB should be enough
- do
- i=`expr $i + 1`
- teststring=$teststring$teststring
- done
- # Only check the string length outside the loop.
- lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
- teststring=
- # Add a significant safety factor because C++ compilers can tack on
- # massive amounts of additional arguments before passing them to the
- # linker. It appears as though 1/2 is a usable value.
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
- fi
- ;;
- esac
-
-fi
-
-if test -n $lt_cv_sys_max_cmd_len ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
-$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
-$as_echo "none" >&6; }
-fi
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-
-
-
-
-
-: ${CP="cp -f"}
-: ${MV="mv -f"}
-: ${RM="rm -f"}
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
-$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
-# Try some XSI features
-xsi_shell=no
-( _lt_dummy="a/b/c"
- test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
- = c,a/b,, \
- && eval 'test $(( 1 + 1 )) -eq 2 \
- && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
- && xsi_shell=yes
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
-$as_echo "$xsi_shell" >&6; }
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
-$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
-lt_shell_append=no
-( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
- >/dev/null 2>&1 \
- && lt_shell_append=yes
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
-$as_echo "$lt_shell_append" >&6; }
-
-
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- lt_unset=unset
-else
- lt_unset=false
-fi
-
-
-
-
-
-# test EBCDIC or ASCII
-case `echo X|tr X '\101'` in
- A) # ASCII based system
- # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
- lt_SP2NL='tr \040 \012'
- lt_NL2SP='tr \015\012 \040\040'
- ;;
- *) # EBCDIC based system
- lt_SP2NL='tr \100 \n'
- lt_NL2SP='tr \r\n \100\100'
- ;;
-esac
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
-$as_echo_n "checking for $LD option to reload object files... " >&6; }
-if test "${lt_cv_ld_reload_flag+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_ld_reload_flag='-r'
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
-$as_echo "$lt_cv_ld_reload_flag" >&6; }
-reload_flag=$lt_cv_ld_reload_flag
-case $reload_flag in
-"" | " "*) ;;
-*) reload_flag=" $reload_flag" ;;
-esac
-reload_cmds='$LD$reload_flag -o $output$reload_objs'
-case $host_os in
- darwin*)
- if test "$GCC" = yes; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
- else
- reload_cmds='$LD$reload_flag -o $output$reload_objs'
- fi
- ;;
-esac
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
-set dummy ${ac_tool_prefix}objdump; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$OBJDUMP"; then
- ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-OBJDUMP=$ac_cv_prog_OBJDUMP
-if test -n "$OBJDUMP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
-$as_echo "$OBJDUMP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OBJDUMP"; then
- ac_ct_OBJDUMP=$OBJDUMP
- # Extract the first word of "objdump", so it can be a program name with args.
-set dummy objdump; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_OBJDUMP"; then
- ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_OBJDUMP="objdump"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
-if test -n "$ac_ct_OBJDUMP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
-$as_echo "$ac_ct_OBJDUMP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_OBJDUMP" = x; then
- OBJDUMP="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- OBJDUMP=$ac_ct_OBJDUMP
- fi
-else
- OBJDUMP="$ac_cv_prog_OBJDUMP"
-fi
-
-test -z "$OBJDUMP" && OBJDUMP=objdump
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
-$as_echo_n "checking how to recognize dependent libraries... " >&6; }
-if test "${lt_cv_deplibs_check_method+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_file_magic_cmd='$MAGIC_CMD'
-lt_cv_file_magic_test_file=
-lt_cv_deplibs_check_method='unknown'
-# Need to set the preceding variable on all platforms that support
-# interlibrary dependencies.
-# 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
-# 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
-# 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
-
-case $host_os in
-aix[4-9]*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-beos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-bsdi[45]*)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- lt_cv_file_magic_test_file=/shlib/libc.so
- ;;
-
-cygwin*)
- # func_win32_libid is a shell function defined in ltmain.sh
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- ;;
-
-mingw* | pw32*)
- # Base MSYS/MinGW do not provide the 'file' command needed by
- # func_win32_libid shell function, so use a weaker test based on 'objdump',
- # unless we find 'file', for example because we are cross-compiling.
- if ( file / ) >/dev/null 2>&1; then
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- else
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- fi
- ;;
-
-cegcc)
- # use the weaker test based on 'objdump'. See mingw*.
- lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- ;;
-
-darwin* | rhapsody*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-freebsd* | dragonfly*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
- case $host_cpu in
- i*86 )
- # Not sure whether the presence of OpenBSD here was a mistake.
- # Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
- ;;
- esac
- else
- lt_cv_deplibs_check_method=pass_all
- fi
- ;;
-
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-hpux10.20* | hpux11*)
- lt_cv_file_magic_cmd=/usr/bin/file
- case $host_cpu in
- ia64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
- lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
- ;;
- hppa*64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
- lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
- ;;
- *)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
- lt_cv_file_magic_test_file=/usr/lib/libc.sl
- ;;
- esac
- ;;
-
-interix[3-9]*)
- # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-netbsd* | netbsdelf*-gnu)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
- fi
- ;;
-
-newos6*)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=/usr/lib/libnls.so
- ;;
-
-*nto* | *qnx*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-openbsd*)
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
- fi
- ;;
-
-osf3* | osf4* | osf5*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-rdos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-solaris*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv4 | sysv4.3*)
- case $host_vendor in
- motorola)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
- ;;
- ncr)
- lt_cv_deplibs_check_method=pass_all
- ;;
- sequent)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
- ;;
- sni)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
- lt_cv_file_magic_test_file=/lib/libc.so
- ;;
- siemens)
- lt_cv_deplibs_check_method=pass_all
- ;;
- pc)
- lt_cv_deplibs_check_method=pass_all
- ;;
- esac
- ;;
-
-tpf*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-esac
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
-$as_echo "$lt_cv_deplibs_check_method" >&6; }
-file_magic_cmd=$lt_cv_file_magic_cmd
-deplibs_check_method=$lt_cv_deplibs_check_method
-test -z "$deplibs_check_method" && deplibs_check_method=unknown
-
-
-
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ar; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$AR"; then
- ac_cv_prog_AR="$AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AR="${ac_tool_prefix}ar"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-AR=$ac_cv_prog_AR
-if test -n "$AR"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
-$as_echo "$AR" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_AR"; then
- ac_ct_AR=$AR
- # Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_AR"; then
- ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_AR="ar"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_AR=$ac_cv_prog_ac_ct_AR
-if test -n "$ac_ct_AR"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
-$as_echo "$ac_ct_AR" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_AR" = x; then
- AR="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- AR=$ac_ct_AR
- fi
-else
- AR="$ac_cv_prog_AR"
-fi
-
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-
-
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
-set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$STRIP"; then
- ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_STRIP="${ac_tool_prefix}strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-STRIP=$ac_cv_prog_STRIP
-if test -n "$STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
-$as_echo "$STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_STRIP"; then
- ac_ct_STRIP=$STRIP
- # Extract the first word of "strip", so it can be a program name with args.
-set dummy strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_STRIP"; then
- ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_STRIP="strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
-if test -n "$ac_ct_STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
-$as_echo "$ac_ct_STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_STRIP" = x; then
- STRIP=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- STRIP=$ac_ct_STRIP
- fi
-else
- STRIP="$ac_cv_prog_STRIP"
-fi
-
-test -z "$STRIP" && STRIP=:
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
-$as_echo "$RANLIB" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
-$as_echo "$ac_ct_RANLIB" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_RANLIB" = x; then
- RANLIB=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- RANLIB=$ac_ct_RANLIB
- fi
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-test -z "$RANLIB" && RANLIB=:
-
-
-
-
-
-
-# Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
-old_postinstall_cmds='chmod 644 $oldlib'
-old_postuninstall_cmds=
-
-if test -n "$RANLIB"; then
- case $host_os in
- openbsd*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
- ;;
- *)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
- ;;
- esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
-$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
-if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
-
-# These are sane defaults that work on at least a few old systems.
-# [They come from Ultrix. What could be older than Ultrix?!! ;)]
-
-# Character class describing NM global symbol codes.
-symcode='[BCDEGRST]'
-
-# Regexp to match symbols that can be accessed directly from C.
-sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
-
-# Define system-specific variables.
-case $host_os in
-aix*)
- symcode='[BCDT]'
- ;;
-cygwin* | mingw* | pw32* | cegcc*)
- symcode='[ABCDGISTW]'
- ;;
-hpux*)
- if test "$host_cpu" = ia64; then
- symcode='[ABCDEGRST]'
- fi
- ;;
-irix* | nonstopux*)
- symcode='[BCDEGRST]'
- ;;
-osf*)
- symcode='[BCDEGQRST]'
- ;;
-solaris*)
- symcode='[BDRT]'
- ;;
-sco3.2v5*)
- symcode='[DT]'
- ;;
-sysv4.2uw2*)
- symcode='[DT]'
- ;;
-sysv5* | sco5v6* | unixware* | OpenUNIX*)
- symcode='[ABDT]'
- ;;
-sysv4)
- symcode='[DFNSTU]'
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-case `$NM -V 2>&1` in
-*GNU* | *'with BFD'*)
- symcode='[ABCDGIRSTW]' ;;
-esac
-
-# Transform an extracted symbol line into a proper C declaration.
-# Some systems (esp. on ia64) link data and code symbols differently,
-# so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
-
-# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
-
-# Handle CRLF in mingw tool chain
-opt_cr=
-case $build_os in
-mingw*)
- opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
- ;;
-esac
-
-# Try without a prefix underscore, then with it.
-for ac_symprfx in "" "_"; do
-
- # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
- symxfrm="\\1 $ac_symprfx\\2 \\2"
-
- # Write the raw and C identifiers.
- if test "$lt_cv_nm_interface" = "MS dumpbin"; then
- # Fake it for dumpbin and say T for any non-static function
- # and D for any global variable.
- # Also find C++ and __fastcall symbols from MSVC++,
- # which start with @ or ?.
- lt_cv_sys_global_symbol_pipe="$AWK '"\
-" {last_section=section; section=\$ 3};"\
-" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-" \$ 0!~/External *\|/{next};"\
-" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
-" {if(hide[section]) next};"\
-" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
-" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
-" s[1]~/^[@?]/{print s[1], s[1]; next};"\
-" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
-" ' prfx=^$ac_symprfx"
- else
- lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
- fi
-
- # Check to see that the pipe works correctly.
- pipe_works=no
-
- rm -f conftest*
- cat > conftest.$ac_ext <<_LT_EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(void);
-void nm_test_func(void){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func();return(0);}
-_LT_EOF
-
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- # Now try to grab the symbols.
- nlist=conftest.nm
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5
- (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s "$nlist"; then
- # Try sorting and uniquifying the output.
- if sort "$nlist" | uniq > "$nlist"T; then
- mv -f "$nlist"T "$nlist"
- else
- rm -f "$nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
- if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
- cat <<_LT_EOF > conftest.$ac_ext
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-_LT_EOF
- # Now generate the symbol file.
- eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
-
- cat <<_LT_EOF >> conftest.$ac_ext
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- void *address;
-}
-lt__PROGRAM__LTX_preloaded_symbols[] =
-{
- { "@PROGRAM@", (void *) 0 },
-_LT_EOF
- $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
- cat <<\_LT_EOF >> conftest.$ac_ext
- {0, (void *) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
- return lt__PROGRAM__LTX_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-_LT_EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- lt_save_LIBS="$LIBS"
- lt_save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s conftest${ac_exeext}; then
- pipe_works=yes
- fi
- LIBS="$lt_save_LIBS"
- CFLAGS="$lt_save_CFLAGS"
- else
- echo "cannot find nm_test_func in $nlist" >&5
- fi
- else
- echo "cannot find nm_test_var in $nlist" >&5
- fi
- else
- echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
- fi
- else
- echo "$progname: failed program was:" >&5
- cat conftest.$ac_ext >&5
- fi
- rm -rf conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$pipe_works" = yes; then
- break
- else
- lt_cv_sys_global_symbol_pipe=
- fi
-done
-
-fi
-
-if test -z "$lt_cv_sys_global_symbol_pipe"; then
- lt_cv_sys_global_symbol_to_cdecl=
-fi
-if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
-$as_echo "failed" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
-$as_echo "ok" >&6; }
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --enable-libtool-lock was given.
-if test "${enable_libtool_lock+set}" = set; then :
- enableval=$enable_libtool_lock;
-fi
-
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-# Some flags need to be propagated to the compiler or linker for good
-# libtool support.
-case $host in
-ia64-*-hpux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- case `/usr/bin/file conftest.$ac_objext` in
- *ELF-32*)
- HPUX_IA64_MODE="32"
- ;;
- *ELF-64*)
- HPUX_IA64_MODE="64"
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-*-*-irix6*)
- # Find out which ABI we are using.
- echo '#line 5706 "configure"' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- if test "$lt_cv_prog_gnu_ld" = yes; then
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -melf32bsmip"
- ;;
- *N32*)
- LD="${LD-ld} -melf32bmipn32"
- ;;
- *64-bit*)
- LD="${LD-ld} -melf64bmip"
- ;;
- esac
- else
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -32"
- ;;
- *N32*)
- LD="${LD-ld} -n32"
- ;;
- *64-bit*)
- LD="${LD-ld} -64"
- ;;
- esac
- fi
- fi
- rm -rf conftest*
- ;;
-
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
-s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- case `/usr/bin/file conftest.o` in
- *32-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_i386_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
- ;;
- ppc64-*linux*|powerpc64-*linux*)
- LD="${LD-ld} -m elf32ppclinux"
- ;;
- s390x-*linux*)
- LD="${LD-ld} -m elf_s390"
- ;;
- sparc64-*linux*)
- LD="${LD-ld} -m elf32_sparc"
- ;;
- esac
- ;;
- *64-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_x86_64_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_x86_64"
- ;;
- ppc*-*linux*|powerpc*-*linux*)
- LD="${LD-ld} -m elf64ppc"
- ;;
- s390*-*linux*|s390*-*tpf*)
- LD="${LD-ld} -m elf64_s390"
- ;;
- sparc*-*linux*)
- LD="${LD-ld} -m elf64_sparc"
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-*-*-sco3.2v5*)
- # On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -belf"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
-$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
-if test "${lt_cv_cc_needs_belf+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- lt_cv_cc_needs_belf=yes
-else
- lt_cv_cc_needs_belf=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
-$as_echo "$lt_cv_cc_needs_belf" >&6; }
- if test x"$lt_cv_cc_needs_belf" != x"yes"; then
- # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
- CFLAGS="$SAVE_CFLAGS"
- fi
- ;;
-sparc*-*solaris*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- case `/usr/bin/file conftest.o` in
- *64-bit*)
- case $lt_cv_prog_gnu_ld in
- yes*) LD="${LD-ld} -m elf64_sparc" ;;
- *)
- if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
- LD="${LD-ld} -64"
- fi
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-esac
-
-need_locks="$enable_libtool_lock"
-
-
- case $host_os in
- rhapsody* | darwin*)
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
-set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$DSYMUTIL"; then
- ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-DSYMUTIL=$ac_cv_prog_DSYMUTIL
-if test -n "$DSYMUTIL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
-$as_echo "$DSYMUTIL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_DSYMUTIL"; then
- ac_ct_DSYMUTIL=$DSYMUTIL
- # Extract the first word of "dsymutil", so it can be a program name with args.
-set dummy dsymutil; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_DSYMUTIL"; then
- ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
-if test -n "$ac_ct_DSYMUTIL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
-$as_echo "$ac_ct_DSYMUTIL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_DSYMUTIL" = x; then
- DSYMUTIL=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- DSYMUTIL=$ac_ct_DSYMUTIL
- fi
-else
- DSYMUTIL="$ac_cv_prog_DSYMUTIL"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
-set dummy ${ac_tool_prefix}nmedit; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_NMEDIT+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$NMEDIT"; then
- ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-NMEDIT=$ac_cv_prog_NMEDIT
-if test -n "$NMEDIT"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
-$as_echo "$NMEDIT" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_NMEDIT"; then
- ac_ct_NMEDIT=$NMEDIT
- # Extract the first word of "nmedit", so it can be a program name with args.
-set dummy nmedit; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_NMEDIT"; then
- ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_NMEDIT="nmedit"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
-if test -n "$ac_ct_NMEDIT"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
-$as_echo "$ac_ct_NMEDIT" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_NMEDIT" = x; then
- NMEDIT=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- NMEDIT=$ac_ct_NMEDIT
- fi
-else
- NMEDIT="$ac_cv_prog_NMEDIT"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
-set dummy ${ac_tool_prefix}lipo; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_LIPO+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$LIPO"; then
- ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-LIPO=$ac_cv_prog_LIPO
-if test -n "$LIPO"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
-$as_echo "$LIPO" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_LIPO"; then
- ac_ct_LIPO=$LIPO
- # Extract the first word of "lipo", so it can be a program name with args.
-set dummy lipo; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_LIPO"; then
- ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_LIPO="lipo"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
-if test -n "$ac_ct_LIPO"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
-$as_echo "$ac_ct_LIPO" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_LIPO" = x; then
- LIPO=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- LIPO=$ac_ct_LIPO
- fi
-else
- LIPO="$ac_cv_prog_LIPO"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
-set dummy ${ac_tool_prefix}otool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OTOOL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$OTOOL"; then
- ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-OTOOL=$ac_cv_prog_OTOOL
-if test -n "$OTOOL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
-$as_echo "$OTOOL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OTOOL"; then
- ac_ct_OTOOL=$OTOOL
- # Extract the first word of "otool", so it can be a program name with args.
-set dummy otool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_OTOOL"; then
- ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_OTOOL="otool"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
-if test -n "$ac_ct_OTOOL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
-$as_echo "$ac_ct_OTOOL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_OTOOL" = x; then
- OTOOL=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- OTOOL=$ac_ct_OTOOL
- fi
-else
- OTOOL="$ac_cv_prog_OTOOL"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
-set dummy ${ac_tool_prefix}otool64; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OTOOL64+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$OTOOL64"; then
- ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-OTOOL64=$ac_cv_prog_OTOOL64
-if test -n "$OTOOL64"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
-$as_echo "$OTOOL64" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OTOOL64"; then
- ac_ct_OTOOL64=$OTOOL64
- # Extract the first word of "otool64", so it can be a program name with args.
-set dummy otool64; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_OTOOL64"; then
- ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_OTOOL64="otool64"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
-if test -n "$ac_ct_OTOOL64"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
-$as_echo "$ac_ct_OTOOL64" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_OTOOL64" = x; then
- OTOOL64=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- OTOOL64=$ac_ct_OTOOL64
- fi
-else
- OTOOL64="$ac_cv_prog_OTOOL64"
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
-$as_echo_n "checking for -single_module linker flag... " >&6; }
-if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_apple_cc_single_mod=no
- if test -z "${LT_MULTI_MODULE}"; then
- # By default we will add the -single_module flag. You can override
- # by either setting the environment variable LT_MULTI_MODULE
- # non-empty at configure time, or by adding -multi_module to the
- # link flags.
- rm -rf libconftest.dylib*
- echo "int foo(void){return 1;}" > conftest.c
- echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
--dynamiclib -Wl,-single_module conftest.c" >&5
- $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
- -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
- _lt_result=$?
- if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
- lt_cv_apple_cc_single_mod=yes
- else
- cat conftest.err >&5
- fi
- rm -rf libconftest.dylib*
- rm -f conftest.*
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
-$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
-$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
-if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_ld_exported_symbols_list=no
- save_LDFLAGS=$LDFLAGS
- echo "_main" > conftest.sym
- LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- lt_cv_ld_exported_symbols_list=yes
-else
- lt_cv_ld_exported_symbols_list=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
-$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
- case $host_os in
- rhapsody* | darwin1.[012])
- _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
- darwin1.*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- darwin*) # darwin 5.x on
- # if running on 10.5 or later, the deployment target defaults
- # to the OS version, if on x86, and 10.4, the deployment
- # target defaults to 10.4. Don't you love it?
- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
- 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- 10.[012]*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- 10.*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- esac
- ;;
- esac
- if test "$lt_cv_apple_cc_single_mod" = "yes"; then
- _lt_dar_single_mod='$single_module'
- fi
- if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
- _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
- else
- _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
- fi
- if test "$DSYMUTIL" != ":"; then
- _lt_dsymutil='~$DSYMUTIL $lib || :'
- else
- _lt_dsymutil=
- fi
- ;;
- esac
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5 ; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_stdc=yes
-else
- ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then :
- :
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_header in dlfcn.h
-do :
- ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
-"
-if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_DLFCN_H 1
-_ACEOF
-
-fi
-
-done
-
-
-
-# Set options
-
-
-
- enable_dlopen=no
-
-
- enable_win32_dll=no
-
-
- # Check whether --enable-shared was given.
-if test "${enable_shared+set}" = set; then :
- enableval=$enable_shared; p=${PACKAGE-default}
- case $enableval in
- yes) enable_shared=yes ;;
- no) enable_shared=no ;;
- *)
- enable_shared=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_shared=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_shared=yes
-fi
-
-
-
-
-
-
-
-
-
- # Check whether --enable-static was given.
-if test "${enable_static+set}" = set; then :
- enableval=$enable_static; p=${PACKAGE-default}
- case $enableval in
- yes) enable_static=yes ;;
- no) enable_static=no ;;
- *)
- enable_static=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_static=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_static=yes
-fi
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-pic was given.
-if test "${with_pic+set}" = set; then :
- withval=$with_pic; pic_mode="$withval"
-else
- pic_mode=default
-fi
-
-
-test -z "$pic_mode" && pic_mode=default
-
-
-
-
-
-
-
- # Check whether --enable-fast-install was given.
-if test "${enable_fast_install+set}" = set; then :
- enableval=$enable_fast_install; p=${PACKAGE-default}
- case $enableval in
- yes) enable_fast_install=yes ;;
- no) enable_fast_install=no ;;
- *)
- enable_fast_install=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_fast_install=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_fast_install=yes
-fi
-
-
-
-
-
-
-
-
-
-
-
-# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ltmain"
-
-# Always use our own libtool.
-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-test -z "$LN_S" && LN_S="ln -s"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
-$as_echo_n "checking for objdir... " >&6; }
-if test "${lt_cv_objdir+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- rm -f .libs 2>/dev/null
-mkdir .libs 2>/dev/null
-if test -d .libs; then
- lt_cv_objdir=.libs
-else
- # MS-DOS does not allow filenames that begin with a dot.
- lt_cv_objdir=_libs
-fi
-rmdir .libs 2>/dev/null
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
-$as_echo "$lt_cv_objdir" >&6; }
-objdir=$lt_cv_objdir
-
-
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define LT_OBJDIR "$lt_cv_objdir/"
-_ACEOF
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-case $host_os in
-aix3*)
- # AIX sometimes has problems with the GCC collect2 program. For some
- # reason, if we set the COLLECT_NAMES environment variable, the problems
- # vanish in a puff of smoke.
- if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
- fi
- ;;
-esac
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\(["`\\]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
-# Global variables:
-ofile=libtool
-can_build_shared=yes
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-
-with_gnu_ld="$lt_cv_prog_gnu_ld"
-
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
-
-# Set sane defaults for various variables
-test -z "$CC" && CC=cc
-test -z "$LTCC" && LTCC=$CC
-test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
-test -z "$LD" && LD=ld
-test -z "$ac_objext" && ac_objext=o
-
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-
-# Only perform the check for file, if the check method requires it
-test -z "$MAGIC_CMD" && MAGIC_CMD=file
-case $deplibs_check_method in
-file_magic*)
- if test "$file_magic_cmd" = '$MAGIC_CMD'; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
-$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $MAGIC_CMD in
-[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/${ac_tool_prefix}file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<_LT_EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-_LT_EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
-$as_echo "$MAGIC_CMD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-
-
-
-if test -z "$lt_cv_path_MAGIC_CMD"; then
- if test -n "$ac_tool_prefix"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
-$as_echo_n "checking for file... " >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $MAGIC_CMD in
-[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<_LT_EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-_LT_EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
-$as_echo "$MAGIC_CMD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- else
- MAGIC_CMD=:
- fi
-fi
-
- fi
- ;;
-esac
-
-# Use C for the default configuration in the libtool script
-
-lt_save_CC="$CC"
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# Source file extension for C test sources.
-ac_ext=c
-
-# Object file extension for compiled C test sources.
-objext=o
-objext=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}'
-
-
-
-
-
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-# Save the default compiler, since it gets overwritten when the other
-# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
-compiler_DEFAULT=$CC
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$RM conftest*
-
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$RM -r conftest*
-
-
-if test -n "$compiler"; then
-
-lt_prog_compiler_no_builtin_flag=
-
-if test "$GCC" = yes; then
- lt_prog_compiler_no_builtin_flag=' -fno-builtin'
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
-$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
-if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_rtti_exceptions=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="-fno-rtti -fno-exceptions"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7231: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:7235: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_rtti_exceptions=yes
- fi
- fi
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
-$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
-
-if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
- lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
-else
- :
-fi
-
-fi
-
-
-
-
-
-
- lt_prog_compiler_wl=
-lt_prog_compiler_pic=
-lt_prog_compiler_static=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
-
- if test "$GCC" = yes; then
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_static='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- lt_prog_compiler_pic='-fPIC'
- ;;
- m68k)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
- ;;
- esac
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- lt_prog_compiler_pic='-DDLL_EXPORT'
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic='-fno-common'
- ;;
-
- hpux*)
- # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
- # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
- # sets the default TLS model and affects inlining.
- case $host_cpu in
- hppa*64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic='-fPIC'
- ;;
- esac
- ;;
-
- interix[3-9]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- lt_prog_compiler_can_build_shared=no
- enable_shared=no
- ;;
-
- *nto* | *qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- lt_prog_compiler_pic='-fPIC -shared'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic=-Kconform_pic
- fi
- ;;
-
- *)
- lt_prog_compiler_pic='-fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- lt_prog_compiler_wl='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- else
- lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
-
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic='-DDLL_EXPORT'
- ;;
-
- hpux9* | hpux10* | hpux11*)
- lt_prog_compiler_wl='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- lt_prog_compiler_static='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- lt_prog_compiler_wl='-Wl,'
- # PIC (with -KPIC) is the default.
- lt_prog_compiler_static='-non_shared'
- ;;
-
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- # old Intel for x86_64 which still supported -KPIC.
- ecc*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-static'
- ;;
- # icc used to be incompatible with GCC.
- # ICC 10 doesn't accept -KPIC any more.
- icc* | ifort*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-fPIC'
- lt_prog_compiler_static='-static'
- ;;
- # Lahey Fortran 8.1.
- lf95*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='--shared'
- lt_prog_compiler_static='--static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-fpic'
- lt_prog_compiler_static='-Bstatic'
- ;;
- ccc*)
- lt_prog_compiler_wl='-Wl,'
- # All Alpha code is PIC.
- lt_prog_compiler_static='-non_shared'
- ;;
- xl*)
- # IBM XL C 8.0/Fortran 10.1 on PPC
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-qpic'
- lt_prog_compiler_static='-qstaticlink'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C 5.9
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- lt_prog_compiler_wl='-Wl,'
- ;;
- *Sun\ F*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- lt_prog_compiler_wl=''
- ;;
- esac
- ;;
- esac
- ;;
-
- newsos6)
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- *nto* | *qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- lt_prog_compiler_pic='-fPIC -shared'
- ;;
-
- osf3* | osf4* | osf5*)
- lt_prog_compiler_wl='-Wl,'
- # All OSF/1 code is PIC.
- lt_prog_compiler_static='-non_shared'
- ;;
-
- rdos*)
- lt_prog_compiler_static='-non_shared'
- ;;
-
- solaris*)
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- lt_prog_compiler_wl='-Qoption ld ';;
- *)
- lt_prog_compiler_wl='-Wl,';;
- esac
- ;;
-
- sunos4*)
- lt_prog_compiler_wl='-Qoption ld '
- lt_prog_compiler_pic='-PIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- lt_prog_compiler_pic='-Kconform_pic'
- lt_prog_compiler_static='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- unicos*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_can_build_shared=no
- ;;
-
- uts4*)
- lt_prog_compiler_pic='-pic'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- *)
- lt_prog_compiler_can_build_shared=no
- ;;
- esac
- fi
-
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic=
- ;;
- *)
- lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
- ;;
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
-$as_echo "$lt_prog_compiler_pic" >&6; }
-
-
-
-
-
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
-$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
-if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_pic_works=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7570: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:7574: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_pic_works=yes
- fi
- fi
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
-$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
-
-if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
- case $lt_prog_compiler_pic in
- "" | " "*) ;;
- *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
- esac
-else
- lt_prog_compiler_pic=
- lt_prog_compiler_can_build_shared=no
-fi
-
-fi
-
-
-
-
-
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
-if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_static_works=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_static_works=yes
- fi
- else
- lt_cv_prog_compiler_static_works=yes
- fi
- fi
- $RM -r conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
-$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
-
-if test x"$lt_cv_prog_compiler_static_works" = xyes; then
- :
-else
- lt_prog_compiler_static=
-fi
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_c_o=no
- $RM -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7675: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:7679: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o=yes
- fi
- fi
- chmod u+w . 2>&5
- $RM conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
- $RM out/* && rmdir out
- cd ..
- $RM -r conftest
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
-$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_c_o=no
- $RM -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7730: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:7734: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o=yes
- fi
- fi
- chmod u+w . 2>&5
- $RM conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
- $RM out/* && rmdir out
- cd ..
- $RM -r conftest
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
-$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
-
-
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
-$as_echo_n "checking if we can lock with hard links... " >&6; }
- hard_links=yes
- $RM conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
-$as_echo "$hard_links" >&6; }
- if test "$hard_links" = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
-
- runpath_var=
- allow_undefined_flag=
- always_export_symbols=no
- archive_cmds=
- archive_expsym_cmds=
- compiler_needs_object=no
- enable_shared_with_static_runtimes=no
- export_dynamic_flag_spec=
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- hardcode_automatic=no
- hardcode_direct=no
- hardcode_direct_absolute=no
- hardcode_libdir_flag_spec=
- hardcode_libdir_flag_spec_ld=
- hardcode_libdir_separator=
- hardcode_minus_L=no
- hardcode_shlibpath_var=unsupported
- inherit_rpath=no
- link_all_deplibs=unknown
- module_cmds=
- module_expsym_cmds=
- old_archive_from_new_cmds=
- old_archive_from_expsyms_cmds=
- thread_safe_flag_spec=
- whole_archive_flag_spec=
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- include_expsyms=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- # Exclude shared library initialization/finalization symbols.
- extract_expsyms_cmds=
-
- case $host_os in
- cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- linux* | k*bsd*-gnu)
- link_all_deplibs=no
- ;;
- esac
-
- ld_shlibs=yes
- if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- export_dynamic_flag_spec='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>&1` in
- *GNU\ gold*) supports_anon_versioning=yes ;;
- *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix[3-9]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-_LT_EOF
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds=''
- ;;
- m68k)
- archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- ;;
- esac
- ;;
-
- beos*)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec='-L$libdir'
- allow_undefined_flag=unsupported
- always_export_symbols=no
- enable_shared_with_static_runtimes=yes
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- interix[3-9]*)
- hardcode_direct=no
- hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
- tmp_diet=no
- if test "$host_os" = linux-dietlibc; then
- case $cc_basename in
- diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
- esac
- fi
- if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
- && test "$tmp_diet" = no
- then
- tmp_addflag=
- tmp_sharedflag='-shared'
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- lf95*) # Lahey Fortran 8.1
- whole_archive_flag_spec=
- tmp_sharedflag='--shared' ;;
- xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
- tmp_sharedflag='-qmkshrobj'
- tmp_addflag= ;;
- esac
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*) # Sun C 5.9
- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
- compiler_needs_object=yes
- tmp_sharedflag='-G' ;;
- *Sun\ F*) # Sun Fortran 8.3
- tmp_sharedflag='-G' ;;
- esac
- archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test "x$supports_anon_versioning" = xyes; then
- archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
-
- case $cc_basename in
- xlf*)
- # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
- whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
- hardcode_libdir_flag_spec=
- hardcode_libdir_flag_spec_ld='-rpath $libdir'
- archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
- archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
- fi
- ;;
- esac
- else
- ld_shlibs=no
- fi
- ;;
-
- netbsd* | netbsdelf*-gnu)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- # For security reasons, it is highly recommended that you always
- # use absolute paths for naming shared libraries, and exclude the
- # DT_RUNPATH tag from executables and libraries. But doing so
- # requires that you compile everything twice, which is a pain.
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- *)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
-
- if test "$ld_shlibs" = no; then
- runpath_var=
- hardcode_libdir_flag_spec=
- export_dynamic_flag_spec=
- whole_archive_flag_spec=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- allow_undefined_flag=unsupported
- always_export_symbols=yes
- archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct=unsupported
- fi
- ;;
-
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds=''
- hardcode_direct=yes
- hardcode_direct_absolute=yes
- hardcode_libdir_separator=':'
- link_all_deplibs=yes
- file_list_spec='${wl}-f,'
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" &&
- strings "$collect2name" | $GREP resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L=yes
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_libdir_separator=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- link_all_deplibs=no
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- export_dynamic_flag_spec='${wl}-bexpall'
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag='-berok'
- # Determine the default libpath from the value encoded in an
- # empty executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag="-z nodefs"
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an
- # empty executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag=' ${wl}-bernotok'
- allow_undefined_flag=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec='$convenience'
- archive_cmds_need_lc=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds=''
- ;;
- m68k)
- archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- ;;
- esac
- ;;
-
- bsdi[45]*)
- export_dynamic_flag_spec=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- allow_undefined_flag=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_from_new_cmds='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path='`cygpath -w "$srcfile"`'
- enable_shared_with_static_runtimes=yes
- ;;
-
- darwin* | rhapsody*)
-
-
- archive_cmds_need_lc=no
- hardcode_direct=no
- hardcode_automatic=yes
- hardcode_shlibpath_var=unsupported
- whole_archive_flag_spec=''
- link_all_deplibs=yes
- allow_undefined_flag="$_lt_dar_allow_undefined"
- case $cc_basename in
- ifort*) _lt_dar_can_shared=yes ;;
- *) _lt_dar_can_shared=$GCC ;;
- esac
- if test "$_lt_dar_can_shared" = "yes"; then
- output_verbose_link_cmd=echo
- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
-
- else
- ld_shlibs=no
- fi
-
- ;;
-
- dgux*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- freebsd1*)
- ld_shlibs=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | dragonfly*)
- archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- export_dynamic_flag_spec='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_flag_spec_ld='+b $libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- hardcode_direct_absolute=yes
- export_dynamic_flag_spec='${wl}-E'
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_direct=no
- hardcode_shlibpath_var=no
- ;;
- *)
- hardcode_direct=yes
- hardcode_direct_absolute=yes
- export_dynamic_flag_spec='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- # Try to use the -exported_symbol ld option, if it does not
- # work, assume that -exports_file does not work either and
- # implicitly export all symbols.
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-int foo(void) {}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
-
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS="$save_LDFLAGS"
- else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
- fi
- archive_cmds_need_lc='no'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- inherit_rpath=yes
- link_all_deplibs=yes
- ;;
-
- netbsd* | netbsdelf*-gnu)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- newsos6)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_shlibpath_var=no
- ;;
-
- *nto* | *qnx*)
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- hardcode_direct_absolute=yes
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- else
- case $host_os in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- *)
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- ld_shlibs=no
- fi
- ;;
-
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- allow_undefined_flag=unsupported
- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- archive_cmds_need_lc='no'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec='-rpath $libdir'
- fi
- archive_cmds_need_lc='no'
- hardcode_libdir_separator=:
- ;;
-
- solaris*)
- no_undefined_flag=' -z defs'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
- else
- case `$CC -V 2>&1` in
- *"Compilers 5.0"*)
- wlarc=''
- archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
- ;;
- *)
- wlarc='${wl}'
- archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
- ;;
- esac
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_shlibpath_var=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'. GCC discards it without `$wl',
- # but is careful enough not to reorder.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- if test "$GCC" = yes; then
- whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- else
- whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
- fi
- ;;
- esac
- link_all_deplibs=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- reload_cmds='$CC -r -o $output$reload_objs'
- hardcode_direct=no
- ;;
- motorola)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var=no
- ;;
-
- sysv4.3*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- export_dynamic_flag_spec='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ld_shlibs=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- no_undefined_flag='${wl}-z,text'
- archive_cmds_need_lc=no
- hardcode_shlibpath_var=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- no_undefined_flag='${wl}-z,text'
- allow_undefined_flag='${wl}-z,nodefs'
- archive_cmds_need_lc=no
- hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='${wl}-R,$libdir'
- hardcode_libdir_separator=':'
- link_all_deplibs=yes
- export_dynamic_flag_spec='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- *)
- ld_shlibs=no
- ;;
- esac
-
- if test x$host_vendor = xsni; then
- case $host in
- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- ;;
- esac
- fi
- fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
-$as_echo "$ld_shlibs" >&6; }
-test "$ld_shlibs" = no && can_build_shared=no
-
-with_gnu_ld=$with_gnu_ld
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
-$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
- $RM conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl
- pic_flag=$lt_prog_compiler_pic
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag
- allow_undefined_flag=
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
- (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
- then
- archive_cmds_need_lc=no
- else
- archive_cmds_need_lc=yes
- fi
- allow_undefined_flag=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $RM conftest*
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5
-$as_echo "$archive_cmds_need_lc" >&6; }
- ;;
- esac
- fi
- ;;
-esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
-$as_echo_n "checking dynamic linker characteristics... " >&6; }
-
-if test "$GCC" = yes; then
- case $host_os in
- darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
- *) lt_awk_arg="/^libraries:/" ;;
- esac
- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
- else
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- # Ok, now we have the path, separated by spaces, we can step through it
- # and add multilib dir if necessary.
- lt_tmp_lt_search_path_spec=
- lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
- for lt_sys_path in $lt_search_path_spec; do
- if test -d "$lt_sys_path/$lt_multi_os_dir"; then
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
- else
- test -d "$lt_sys_path" && \
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
- fi
- done
- lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
-BEGIN {RS=" "; FS="/|\n";} {
- lt_foo="";
- lt_count=0;
- for (lt_i = NF; lt_i > 0; lt_i--) {
- if ($lt_i != "" && $lt_i != ".") {
- if ($lt_i == "..") {
- lt_count++;
- } else {
- if (lt_count == 0) {
- lt_foo="/" $lt_i lt_foo;
- } else {
- lt_count--;
- }
- }
- }
- }
- if (lt_foo != "") { lt_freq[lt_foo]++; }
- if (lt_freq[lt_foo] == 1) { print lt_foo; }
-}'`
- sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[4-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- case $host_cpu in
- powerpc)
- # Since July 2007 AmigaOS4 officially supports .so libraries.
- # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- ;;
- m68k)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
- esac
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32* | cegcc*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname~
- if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
- eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
- fi'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $RM \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw* | cegcc*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-
- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[123]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix[3-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # Some binutils ld are patched to set DT_RUNPATH
- save_LDFLAGS=$LDFLAGS
- save_libdir=$libdir
- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
- shlibpath_overrides_runpath=yes
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS=$save_LDFLAGS
- libdir=$save_libdir
-
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsdelf*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='NetBSD ld.elf_so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-*nto* | *qnx*)
- version_type=qnx
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='ldqnx.so'
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-tpf*)
- # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
-$as_echo "$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-fi
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
-$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
-hardcode_action=
-if test -n "$hardcode_libdir_flag_spec" ||
- test -n "$runpath_var" ||
- test "X$hardcode_automatic" = "Xyes" ; then
-
- # We can hardcode non-existent directories.
- if test "$hardcode_direct" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
- test "$hardcode_minus_L" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action=unsupported
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
-$as_echo "$hardcode_action" >&6; }
-
-if test "$hardcode_action" = relink ||
- test "$inherit_rpath" = yes; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-
-
-
-
-
- if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- mingw* | pw32* | cegcc*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- cygwin*)
- lt_cv_dlopen="dlopen"
- lt_cv_dlopen_libs=
- ;;
-
- darwin*)
- # if libdl is installed we need to link against it
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
-$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dl_dlopen=yes
-else
- ac_cv_lib_dl_dlopen=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
-$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-
- lt_cv_dlopen="dyld"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
-
-fi
-
- ;;
-
- *)
- ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
-if test "x$ac_cv_func_shl_load" = x""yes; then :
- lt_cv_dlopen="shl_load"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
-$as_echo_n "checking for shl_load in -ldld... " >&6; }
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char shl_load ();
-int
-main ()
-{
-return shl_load ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dld_shl_load=yes
-else
- ac_cv_lib_dld_shl_load=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
-$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
-if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
- lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
-else
- ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
-if test "x$ac_cv_func_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
-$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dl_dlopen=yes
-else
- ac_cv_lib_dl_dlopen=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
-$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
-$as_echo_n "checking for dlopen in -lsvld... " >&6; }
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsvld $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_svld_dlopen=yes
-else
- ac_cv_lib_svld_dlopen=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
-$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
-if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
-$as_echo_n "checking for dld_link in -ldld... " >&6; }
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dld_link ();
-int
-main ()
-{
-return dld_link ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dld_dld_link=yes
-else
- ac_cv_lib_dld_dld_link=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
-$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
-if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
- lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
- ;;
- esac
-
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
- else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
-$as_echo_n "checking whether a program can dlopen itself... " >&6; }
-if test "${lt_cv_dlopen_self+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
-#line 10114 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- return status;
-}
-_LT_EOF
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&5 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self=no
- fi
-fi
-rm -fr conftest*
-
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
-$as_echo "$lt_cv_dlopen_self" >&6; }
-
- if test "x$lt_cv_dlopen_self" = xyes; then
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
-$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
-if test "${lt_cv_dlopen_self_static+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self_static=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
-#line 10210 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- return status;
-}
-_LT_EOF
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&5 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self_static=no
- fi
-fi
-rm -fr conftest*
-
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
-$as_echo "$lt_cv_dlopen_self_static" >&6; }
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
-
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-striplib=
-old_striplib=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
-$as_echo_n "checking whether stripping libraries is possible... " >&6; }
-if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- old_striplib="$STRIP -S"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- fi
- ;;
- *)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- ;;
- esac
-fi
-
-
-
-
-
-
-
-
-
-
-
-
- # Report which library types will actually be built
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
-$as_echo_n "checking if libtool supports shared libraries... " >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
-$as_echo "$can_build_shared" >&6; }
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
-$as_echo_n "checking whether to build shared libraries... " >&6; }
- test "$can_build_shared" = "no" && enable_shared=no
-
- # On AIX, shared libraries and static libraries use the same namespace, and
- # are all built from PIC.
- case $host_os in
- aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-
- aix[4-9]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
-$as_echo "$enable_shared" >&6; }
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
-$as_echo_n "checking whether to build static libraries... " >&6; }
- # Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
-$as_echo "$enable_static" >&6; }
-
-
-
-
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-CC="$lt_save_CC"
-
-
-
-
-
-
-
-
-
-
-
-
-
- ac_config_commands="$ac_config_commands libtool"
-
-
-
-
-# Only expand once:
-
-
-
-if test "x$GCC" = xyes ; then
- CFLAGS="-O3 $CFLAGS"
-fi
-
-
-for ac_header in sys/inotify.h sys/epoll.h sys/event.h port.h poll.h sys/select.h sys/eventfd.h sys/signalfd.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_func in inotify_init epoll_ctl kqueue port_create poll select eventfd signalfd
-do :
- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-
-for ac_func in clock_gettime
-do :
- ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
-if test "x$ac_cv_func_clock_gettime" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_CLOCK_GETTIME 1
-_ACEOF
-
-else
-
- if test $(uname) = Linux; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime syscall" >&5
-$as_echo_n "checking for clock_gettime syscall... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <unistd.h>
- #include <sys/syscall.h>
- #include <time.h>
-int
-main ()
-{
-struct timespec ts; int status = syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts)
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_have_clock_syscall=1
-
-$as_echo "#define HAVE_CLOCK_SYSCALL 1" >>confdefs.h
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- fi
- if test -z "$LIBEV_M4_AVOID_LIBRT" && test -z "$ac_have_clock_syscall"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
-$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
-if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lrt $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char clock_gettime ();
-int
-main ()
-{
-return clock_gettime ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_rt_clock_gettime=yes
-else
- ac_cv_lib_rt_clock_gettime=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
-$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
-if test "x$ac_cv_lib_rt_clock_gettime" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBRT 1
-_ACEOF
-
- LIBS="-lrt $LIBS"
-
-fi
-
- unset ac_cv_func_clock_gettime
- for ac_func in clock_gettime
-do :
- ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
-if test "x$ac_cv_func_clock_gettime" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_CLOCK_GETTIME 1
-_ACEOF
-
-fi
-done
-
- fi
-
-fi
-done
-
-
-for ac_func in nanosleep
-do :
- ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep"
-if test "x$ac_cv_func_nanosleep" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_NANOSLEEP 1
-_ACEOF
-
-else
-
- if test -z "$LIBEV_M4_AVOID_LIBRT"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5
-$as_echo_n "checking for nanosleep in -lrt... " >&6; }
-if test "${ac_cv_lib_rt_nanosleep+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lrt $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char nanosleep ();
-int
-main ()
-{
-return nanosleep ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_rt_nanosleep=yes
-else
- ac_cv_lib_rt_nanosleep=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_nanosleep" >&5
-$as_echo "$ac_cv_lib_rt_nanosleep" >&6; }
-if test "x$ac_cv_lib_rt_nanosleep" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBRT 1
-_ACEOF
-
- LIBS="-lrt $LIBS"
-
-fi
-
- unset ac_cv_func_nanosleep
- for ac_func in nanosleep
-do :
- ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep"
-if test "x$ac_cv_func_nanosleep" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_NANOSLEEP 1
-_ACEOF
-
-fi
-done
-
- fi
-
-fi
-done
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ceil in -lm" >&5
-$as_echo_n "checking for ceil in -lm... " >&6; }
-if test "${ac_cv_lib_m_ceil+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lm $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ceil ();
-int
-main ()
-{
-return ceil ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_m_ceil=yes
-else
- ac_cv_lib_m_ceil=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_ceil" >&5
-$as_echo "$ac_cv_lib_m_ceil" >&6; }
-if test "x$ac_cv_lib_m_ceil" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBM 1
-_ACEOF
-
- LIBS="-lm $LIBS"
-
-fi
-
-
-
-
-ac_config_files="$ac_config_files Makefile"
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
- for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
- *) { eval $ac_var=; unset $ac_var;} ;;
- esac ;;
- esac
- done
-
- (set) 2>&1 |
- case $as_nl`(ac_space=' '; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- # `set' does not quote correctly, so add quotes: double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \.
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;; #(
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-) |
- sed '
- /^ac_cv_env_/b end
- t clear
- :clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
- if test -w "$cache_file"; then
- test "x$cache_file" != "x/dev/null" &&
- { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
- cat confcache >$cache_file
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
- fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-DEFS=-DHAVE_CONFIG_H
-
-ac_libobjs=
-ac_ltlibobjs=
-U=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
- # 1. Remove the extension, and $U if already installed.
- ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
- ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
- # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
- # will be set to the directory where LIBOBJS objects are built.
- as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
- as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
- if test -n "$EXEEXT"; then
- am__EXEEXT_TRUE=
- am__EXEEXT_FALSE='#'
-else
- am__EXEEXT_TRUE='#'
- am__EXEEXT_FALSE=
-fi
-
-if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
- as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
- as_fn_error $? "conditional \"AMDEP\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
- as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-
-: ${CONFIG_STATUS=./config.status}
-ac_write_fail=0
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
-as_write_fail=0
-cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-
-SHELL=\${CONFIG_SHELL-$SHELL}
-export SHELL
-_ASEOF
-cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='print -r --'
- as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in #(
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in #((
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
- as_status=$1; test $as_status -eq 0 && as_status=1
- if test "$4"; then
- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
- fi
- $as_echo "$as_me: error: $2" >&2
- as_fn_exit $as_status
-} # as_fn_error
-
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
- { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
- eval 'as_fn_append ()
- {
- eval $1+=\$2
- }'
-else
- as_fn_append ()
- {
- eval $1=\$$1\$2
- }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
- case `echo 'xy\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- xy) ECHO_C='\c';;
- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
- ECHO_T=' ';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -p'
- fi
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || eval $as_mkdir_p || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p='mkdir -p "$as_dir"'
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-## ----------------------------------- ##
-## Main body of $CONFIG_STATUS script. ##
-## ----------------------------------- ##
-_ASEOF
-test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# Save the log message, to keep $0 and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
-This file was extended by $as_me, which was
-generated by GNU Autoconf 2.67. Invocation command line was
-
- CONFIG_FILES = $CONFIG_FILES
- CONFIG_HEADERS = $CONFIG_HEADERS
- CONFIG_LINKS = $CONFIG_LINKS
- CONFIG_COMMANDS = $CONFIG_COMMANDS
- $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-case $ac_config_files in *"
-"*) set x $ac_config_files; shift; ac_config_files=$*;;
-esac
-
-case $ac_config_headers in *"
-"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
-esac
-
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-# Files that config.status was made for.
-config_files="$ac_config_files"
-config_headers="$ac_config_headers"
-config_commands="$ac_config_commands"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-ac_cs_usage="\
-\`$as_me' instantiates files and other configuration actions
-from templates according to the current configuration. Unless the files
-and actions are specified as TAGs, all are instantiated by default.
-
-Usage: $0 [OPTION]... [TAG]...
-
- -h, --help print this help, then exit
- -V, --version print version number and configuration settings, then exit
- --config print configuration, then exit
- -q, --quiet, --silent
- do not print progress messages
- -d, --debug don't remove temporary files
- --recheck update $as_me by reconfiguring in the same conditions
- --file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
- --header=FILE[:TEMPLATE]
- instantiate the configuration header FILE
-
-Configuration files:
-$config_files
-
-Configuration headers:
-$config_headers
-
-Configuration commands:
-$config_commands
-
-Report bugs to the package provider."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
-ac_cs_version="\\
-config.status
-configured by $0, generated by GNU Autoconf 2.67,
- with options \\"\$ac_cs_config\\"
-
-Copyright (C) 2010 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-INSTALL='$INSTALL'
-MKDIR_P='$MKDIR_P'
-AWK='$AWK'
-test -n "\$AWK" || AWK=awk
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# The default lists apply if the user does not specify any file.
-ac_need_defaults=:
-while test $# != 0
-do
- case $1 in
- --*=?*)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
- ac_shift=:
- ;;
- --*=)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=
- ac_shift=:
- ;;
- *)
- ac_option=$1
- ac_optarg=$2
- ac_shift=shift
- ;;
- esac
-
- case $ac_option in
- # Handling of the options.
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- ac_cs_recheck=: ;;
- --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
- $as_echo "$ac_cs_version"; exit ;;
- --config | --confi | --conf | --con | --co | --c )
- $as_echo "$ac_cs_config"; exit ;;
- --debug | --debu | --deb | --de | --d | -d )
- debug=: ;;
- --file | --fil | --fi | --f )
- $ac_shift
- case $ac_optarg in
- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
- '') as_fn_error $? "missing file argument" ;;
- esac
- as_fn_append CONFIG_FILES " '$ac_optarg'"
- ac_need_defaults=false;;
- --header | --heade | --head | --hea )
- $ac_shift
- case $ac_optarg in
- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- as_fn_append CONFIG_HEADERS " '$ac_optarg'"
- ac_need_defaults=false;;
- --he | --h)
- # Conflict between --help and --header
- as_fn_error $? "ambiguous option: \`$1'
-Try \`$0 --help' for more information.";;
- --help | --hel | -h )
- $as_echo "$ac_cs_usage"; exit ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil | --si | --s)
- ac_cs_silent=: ;;
-
- # This is an error.
- -*) as_fn_error $? "unrecognized option: \`$1'
-Try \`$0 --help' for more information." ;;
-
- *) as_fn_append ac_config_targets " $1"
- ac_need_defaults=false ;;
-
- esac
- shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
- exec 6>/dev/null
- ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
- shift
- \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
- CONFIG_SHELL='$SHELL'
- export CONFIG_SHELL
- exec "\$@"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
- $as_echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-#
-# INIT-COMMANDS
-#
-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
-
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-sed_quote_subst='$sed_quote_subst'
-double_quote_subst='$double_quote_subst'
-delay_variable_subst='$delay_variable_subst'
-macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`'
-macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`'
-enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`'
-enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`'
-pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`'
-enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`'
-host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`'
-host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`'
-host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`'
-build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`'
-build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`'
-build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`'
-SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`'
-Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`'
-GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`'
-EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`'
-FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`'
-LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`'
-NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`'
-LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`'
-max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`'
-ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`'
-exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`'
-lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`'
-lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`'
-lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
-reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
-reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`'
-deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
-file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
-AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
-AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`'
-STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`'
-RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`'
-old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`'
-CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`'
-compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`'
-GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
-objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`'
-SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`'
-ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`'
-MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`'
-need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`'
-DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`'
-NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`'
-LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`'
-OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`'
-OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`'
-libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`'
-shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`'
-enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`'
-export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
-whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`'
-allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
-no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`'
-inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`'
-link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`'
-fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`'
-always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`'
-export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
-include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
-prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`'
-variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`'
-need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
-need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`'
-version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`'
-runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`'
-shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
-shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`'
-libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`'
-library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`'
-soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`'
-postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`'
-sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
-sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`'
-enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`'
-enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`'
-enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`'
-old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`'
-striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`'
-
-LTCC='$LTCC'
-LTCFLAGS='$LTCFLAGS'
-compiler='$compiler_DEFAULT'
-
-# Quote evaled strings.
-for var in SED \
-GREP \
-EGREP \
-FGREP \
-LD \
-NM \
-LN_S \
-lt_SP2NL \
-lt_NL2SP \
-reload_flag \
-OBJDUMP \
-deplibs_check_method \
-file_magic_cmd \
-AR \
-AR_FLAGS \
-STRIP \
-RANLIB \
-CC \
-CFLAGS \
-compiler \
-lt_cv_sys_global_symbol_pipe \
-lt_cv_sys_global_symbol_to_cdecl \
-lt_cv_sys_global_symbol_to_c_name_address \
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
-SHELL \
-ECHO \
-lt_prog_compiler_no_builtin_flag \
-lt_prog_compiler_wl \
-lt_prog_compiler_pic \
-lt_prog_compiler_static \
-lt_cv_prog_compiler_c_o \
-need_locks \
-DSYMUTIL \
-NMEDIT \
-LIPO \
-OTOOL \
-OTOOL64 \
-shrext_cmds \
-export_dynamic_flag_spec \
-whole_archive_flag_spec \
-compiler_needs_object \
-with_gnu_ld \
-allow_undefined_flag \
-no_undefined_flag \
-hardcode_libdir_flag_spec \
-hardcode_libdir_flag_spec_ld \
-hardcode_libdir_separator \
-fix_srcfile_path \
-exclude_expsyms \
-include_expsyms \
-file_list_spec \
-variables_saved_for_relink \
-libname_spec \
-library_names_spec \
-soname_spec \
-finish_eval \
-old_striplib \
-striplib; do
- case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
- *[\\\\\\\`\\"\\\$]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
- ;;
- *)
- eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
- ;;
- esac
-done
-
-# Double-quote double-evaled strings.
-for var in reload_cmds \
-old_postinstall_cmds \
-old_postuninstall_cmds \
-old_archive_cmds \
-extract_expsyms_cmds \
-old_archive_from_new_cmds \
-old_archive_from_expsyms_cmds \
-archive_cmds \
-archive_expsym_cmds \
-module_cmds \
-module_expsym_cmds \
-export_symbols_cmds \
-prelink_cmds \
-postinstall_cmds \
-postuninstall_cmds \
-finish_cmds \
-sys_lib_search_path_spec \
-sys_lib_dlsearch_path_spec; do
- case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
- *[\\\\\\\`\\"\\\$]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
- ;;
- *)
- eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
- ;;
- esac
-done
-
-# Fix-up fallback echo if it was mangled by the above quoting rules.
-case \$lt_ECHO in
-*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\`
- ;;
-esac
-
-ac_aux_dir='$ac_aux_dir'
-xsi_shell='$xsi_shell'
-lt_shell_append='$lt_shell_append'
-
-# See if we are running on zsh, and set the options which allow our
-# commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
-fi
-
-
- PACKAGE='$PACKAGE'
- VERSION='$VERSION'
- TIMESTAMP='$TIMESTAMP'
- RM='$RM'
- ofile='$ofile'
-
-
-
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-
-# Handling of arguments.
-for ac_config_target in $ac_config_targets
-do
- case $ac_config_target in
- "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
- "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
- "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
- "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-
- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
- esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used. Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
- test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
- test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
-fi
-
-# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
- tmp=
- trap 'exit_status=$?
- { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
-' 0
- trap 'as_fn_exit 1' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
- tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
-} ||
-{
- tmp=./conf$$-$RANDOM
- (umask 077 && mkdir "$tmp")
-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
-
-# Set up the scripts for CONFIG_FILES section.
-# No need to generate them if there are no CONFIG_FILES.
-# This happens for instance with `./config.status config.h'.
-if test -n "$CONFIG_FILES"; then
-
-
-ac_cr=`echo X | tr X '\015'`
-# On cygwin, bash can eat \r inside `` if the user requested igncr.
-# But we know of no other shell where ac_cr would be empty at this
-# point, so we can use a bashism as a fallback.
-if test "x$ac_cr" = x; then
- eval ac_cr=\$\'\\r\'
-fi
-ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
-if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
- ac_cs_awk_cr='\\r'
-else
- ac_cs_awk_cr=$ac_cr
-fi
-
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
-_ACEOF
-
-
-{
- echo "cat >conf$$subs.awk <<_ACEOF" &&
- echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
- echo "_ACEOF"
-} >conf$$subs.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- . ./conf$$subs.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
-
- ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
- if test $ac_delim_n = $ac_delim_num; then
- break
- elif $ac_last_try; then
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-rm -f conf$$subs.sh
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
-_ACEOF
-sed -n '
-h
-s/^/S["/; s/!.*/"]=/
-p
-g
-s/^[^!]*!//
-:repl
-t repl
-s/'"$ac_delim"'$//
-t delim
-:nl
-h
-s/\(.\{148\}\)..*/\1/
-t more1
-s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
-p
-n
-b repl
-:more1
-s/["\\]/\\&/g; s/^/"/; s/$/"\\/
-p
-g
-s/.\{148\}//
-t nl
-:delim
-h
-s/\(.\{148\}\)..*/\1/
-t more2
-s/["\\]/\\&/g; s/^/"/; s/$/"/
-p
-b
-:more2
-s/["\\]/\\&/g; s/^/"/; s/$/"\\/
-p
-g
-s/.\{148\}//
-t delim
-' <conf$$subs.awk | sed '
-/^[^""]/{
- N
- s/\n//
-}
-' >>$CONFIG_STATUS || ac_write_fail=1
-rm -f conf$$subs.awk
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-_ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
- for (key in S) S_is_set[key] = 1
- FS = ""
-
-}
-{
- line = $ 0
- nfields = split(line, field, "@")
- substed = 0
- len = length(field[1])
- for (i = 2; i < nfields; i++) {
- key = field[i]
- keylen = length(key)
- if (S_is_set[key]) {
- value = S[key]
- line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
- len += length(value) + length(field[++i])
- substed = 1
- } else
- len += 1 + keylen
- }
-
- print line
-}
-
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
- sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
-else
- cat
-fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
- || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
-_ACEOF
-
-# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
-# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
-h
-s///
-s/^/:/
-s/[ ]*$/:/
-s/:\$(srcdir):/:/g
-s/:\${srcdir}:/:/g
-s/:@srcdir@:/:/g
-s/^:*//
-s/:*$//
-x
-s/\(=[ ]*\).*/\1/
-G
-s/\n//
-s/^[^=]*=[ ]*$//
-}'
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-fi # test -n "$CONFIG_FILES"
-
-# Set up the scripts for CONFIG_HEADERS section.
-# No need to generate them if there are no CONFIG_HEADERS.
-# This happens for instance with `./config.status Makefile'.
-if test -n "$CONFIG_HEADERS"; then
-cat >"$tmp/defines.awk" <<\_ACAWK ||
-BEGIN {
-_ACEOF
-
-# Transform confdefs.h into an awk script `defines.awk', embedded as
-# here-document in config.status, that substitutes the proper values into
-# config.h.in to produce config.h.
-
-# Create a delimiter string that does not exist in confdefs.h, to ease
-# handling of long lines.
-ac_delim='%!_!# '
-for ac_last_try in false false :; do
- ac_t=`sed -n "/$ac_delim/p" confdefs.h`
- if test -z "$ac_t"; then
- break
- elif $ac_last_try; then
- as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-# For the awk script, D is an array of macro values keyed by name,
-# likewise P contains macro parameters if any. Preserve backslash
-# newline sequences.
-
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-sed -n '
-s/.\{148\}/&'"$ac_delim"'/g
-t rset
-:rset
-s/^[ ]*#[ ]*define[ ][ ]*/ /
-t def
-d
-:def
-s/\\$//
-t bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3"/p
-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
-d
-:bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3\\\\\\n"\\/p
-t cont
-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
-t cont
-d
-:cont
-n
-s/.\{148\}/&'"$ac_delim"'/g
-t clear
-:clear
-s/\\$//
-t bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/"/p
-d
-:bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
-b cont
-' <confdefs.h | sed '
-s/'"$ac_delim"'/"\\\
-"/g' >>$CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
- for (key in D) D_is_set[key] = 1
- FS = ""
-}
-/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
- line = \$ 0
- split(line, arg, " ")
- if (arg[1] == "#") {
- defundef = arg[2]
- mac1 = arg[3]
- } else {
- defundef = substr(arg[1], 2)
- mac1 = arg[2]
- }
- split(mac1, mac2, "(") #)
- macro = mac2[1]
- prefix = substr(line, 1, index(line, defundef) - 1)
- if (D_is_set[macro]) {
- # Preserve the white space surrounding the "#".
- print prefix "define", macro P[macro] D[macro]
- next
- } else {
- # Replace #undef with comments. This is necessary, for example,
- # in the case of _POSIX_SOURCE, which is predefined and required
- # on some systems where configure will not decide to define it.
- if (defundef == "undef") {
- print "/*", prefix defundef, macro, "*/"
- next
- }
- }
-}
-{ print }
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
- as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
-fi # test -n "$CONFIG_HEADERS"
-
-
-eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
-shift
-for ac_tag
-do
- case $ac_tag in
- :[FHLC]) ac_mode=$ac_tag; continue;;
- esac
- case $ac_mode$ac_tag in
- :[FHL]*:*);;
- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
- :[FH]-) ac_tag=-:-;;
- :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
- esac
- ac_save_IFS=$IFS
- IFS=:
- set x $ac_tag
- IFS=$ac_save_IFS
- shift
- ac_file=$1
- shift
-
- case $ac_mode in
- :L) ac_source=$1;;
- :[FH])
- ac_file_inputs=
- for ac_f
- do
- case $ac_f in
- -) ac_f="$tmp/stdin";;
- *) # Look for the file first in the build tree, then in the source tree
- # (if the path is not absolute). The absolute path cannot be DOS-style,
- # because $ac_f cannot contain `:'.
- test -f "$ac_f" ||
- case $ac_f in
- [\\/$]*) false;;
- *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
- esac ||
- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
- esac
- case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
- as_fn_append ac_file_inputs " '$ac_f'"
- done
-
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- configure_input='Generated from '`
- $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
- `' by configure.'
- if test x"$ac_file" != x-; then
- configure_input="$ac_file. $configure_input"
- { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
- fi
- # Neutralize special characters interpreted by sed in replacement strings.
- case $configure_input in #(
- *\&* | *\|* | *\\* )
- ac_sed_conf_input=`$as_echo "$configure_input" |
- sed 's/[\\\\&|]/\\\\&/g'`;; #(
- *) ac_sed_conf_input=$configure_input;;
- esac
-
- case $ac_tag in
- *:-:* | *:-) cat >"$tmp/stdin" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
- esac
- ;;
- esac
-
- ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- as_dir="$ac_dir"; as_fn_mkdir_p
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
- case $ac_mode in
- :F)
- #
- # CONFIG_FILE
- #
-
- case $INSTALL in
- [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
- *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
- esac
- ac_MKDIR_P=$MKDIR_P
- case $MKDIR_P in
- [\\/$]* | ?:[\\/]* ) ;;
- */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
- esac
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# If the template does not know about datarootdir, expand it.
-# FIXME: This hack should be removed a few years after 2.60.
-ac_datarootdir_hack=; ac_datarootdir_seen=
-ac_sed_dataroot='
-/datarootdir/ {
- p
- q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p'
-case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
-*datarootdir*) ac_datarootdir_seen=yes;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
- ac_datarootdir_hack='
- s&@datadir@&$datadir&g
- s&@docdir@&$docdir&g
- s&@infodir@&$infodir&g
- s&@localedir@&$localedir&g
- s&@mandir@&$mandir&g
- s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
-_ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_sed_extra="$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s|@configure_input@|$ac_sed_conf_input|;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@top_build_prefix@&$ac_top_build_prefix&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-s&@INSTALL@&$ac_INSTALL&;t t
-s&@MKDIR_P@&$ac_MKDIR_P&;t t
-$ac_datarootdir_hack
-"
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
-
-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
- { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
- { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined" >&5
-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined" >&2;}
-
- rm -f "$tmp/stdin"
- case $ac_file in
- -) cat "$tmp/out" && rm -f "$tmp/out";;
- *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
- esac \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
- ;;
- :H)
- #
- # CONFIG_HEADER
- #
- if test x"$ac_file" != x-; then
- {
- $as_echo "/* $configure_input */" \
- && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
- } >"$tmp/config.h" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
- if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
- else
- rm -f "$ac_file"
- mv "$tmp/config.h" "$ac_file" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
- fi
- else
- $as_echo "/* $configure_input */" \
- && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
- || as_fn_error $? "could not create -" "$LINENO" 5
- fi
-# Compute "$ac_file"'s index in $config_headers.
-_am_arg="$ac_file"
-_am_stamp_count=1
-for _am_header in $config_headers :; do
- case $_am_header in
- $_am_arg | $_am_arg:* )
- break ;;
- * )
- _am_stamp_count=`expr $_am_stamp_count + 1` ;;
- esac
-done
-echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
-$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$_am_arg" : 'X\(//\)[^/]' \| \
- X"$_am_arg" : 'X\(//\)$' \| \
- X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$_am_arg" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`/stamp-h$_am_stamp_count
- ;;
-
- :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
-$as_echo "$as_me: executing $ac_file commands" >&6;}
- ;;
- esac
-
-
- case $ac_file$ac_mode in
- "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
- # are listed without --file. Let's play safe and only enable the eval
- # if we detect the quoting.
- case $CONFIG_FILES in
- *\'*) eval set x "$CONFIG_FILES" ;;
- *) set x $CONFIG_FILES ;;
- esac
- shift
- for mf
- do
- # Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`$as_dirname -- "$mf" ||
-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$mf" : 'X\(//\)[^/]' \| \
- X"$mf" : 'X\(//\)$' \| \
- X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$mf" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`$as_dirname -- "$file" ||
-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$file" : 'X\(//\)[^/]' \| \
- X"$file" : 'X\(//\)$' \| \
- X"$file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- as_dir=$dirpart/$fdir; as_fn_mkdir_p
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
- done
-}
- ;;
- "libtool":C)
-
- # See if we are running on zsh, and set the options which allow our
- # commands through without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
-
- cfgfile="${ofile}T"
- trap "$RM \"$cfgfile\"; exit 1" 1 2 15
- $RM "$cfgfile"
-
- cat <<_LT_EOF >> "$cfgfile"
-#! $SHELL
-
-# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
-# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008 Free Software Foundation, Inc.
-# Written by Gordon Matzigkeit, 1996
-#
-# This file is part of GNU Libtool.
-#
-# GNU Libtool is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# As a special exception to the GNU General Public License,
-# if you distribute this file as part of a program or library that
-# is built using GNU Libtool, you may include this file under the
-# same distribution terms that you use for the rest of that program.
-#
-# GNU Libtool is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Libtool; see the file COPYING. If not, a copy
-# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
-# obtained by writing to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-
-# The names of the tagged configurations supported by this script.
-available_tags=""
-
-# ### BEGIN LIBTOOL CONFIG
-
-# Which release of libtool.m4 was used?
-macro_version=$macro_version
-macro_revision=$macro_revision
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# What type of objects to build.
-pic_mode=$pic_mode
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# A sed program that does not truncate output.
-SED=$lt_SED
-
-# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="\$SED -e 1s/^X//"
-
-# A grep program that handles long lines.
-GREP=$lt_GREP
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# A literal string matcher.
-FGREP=$lt_FGREP
-
-# A BSD- or MS-compatible name lister.
-NM=$lt_NM
-
-# Whether we need soft or hard links.
-LN_S=$lt_LN_S
-
-# What is the maximum length of a command?
-max_cmd_len=$max_cmd_len
-
-# Object file suffix (normally "o").
-objext=$ac_objext
-
-# Executable file suffix (normally "").
-exeext=$exeext
-
-# whether the shell understands "unset".
-lt_unset=$lt_unset
-
-# turn spaces into newlines.
-SP2NL=$lt_lt_SP2NL
-
-# turn newlines into spaces.
-NL2SP=$lt_lt_NL2SP
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# An object symbol dumper.
-OBJDUMP=$lt_OBJDUMP
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == "file_magic".
-file_magic_cmd=$lt_file_magic_cmd
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A symbol stripping program.
-STRIP=$lt_STRIP
-
-# Commands used to install an old-style archive.
-RANLIB=$lt_RANLIB
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# A C compiler.
-LTCC=$lt_CC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_CFLAGS
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration.
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair.
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# Transform the output of nm in a C name address pair when lib prefix is needed.
-global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# An echo program that does not interpret backslashes.
-ECHO=$lt_ECHO
-
-# Used to examine libraries when file_magic_cmd begins with "file".
-MAGIC_CMD=$MAGIC_CMD
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
-DSYMUTIL=$lt_DSYMUTIL
-
-# Tool to change global to local symbols on Mac OS X.
-NMEDIT=$lt_NMEDIT
-
-# Tool to manipulate fat objects and archives on Mac OS X.
-LIPO=$lt_LIPO
-
-# ldd/readelf like tool for Mach-O binaries on Mac OS X.
-OTOOL=$lt_OTOOL
-
-# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
-OTOOL64=$lt_OTOOL64
-
-# Old archive suffix (normally "a").
-libext=$libext
-
-# Shared library suffix (normally ".so").
-shrext_cmds=$lt_shrext_cmds
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at link time.
-variables_saved_for_relink=$lt_variables_saved_for_relink
-
-# Do we need the "lib" prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Library versioning type.
-version_type=$version_type
-
-# Shared library runtime path variable.
-runpath_var=$runpath_var
-
-# Shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Command to use after installation of a shared archive.
-postinstall_cmds=$lt_postinstall_cmds
-
-# Command to use after uninstallation of a shared archive.
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# As "finish_cmds", except a single script fragment to be evaled but
-# not shown.
-finish_eval=$lt_finish_eval
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Compile-time system search path for libraries.
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries.
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-
-# The linker used to build libraries.
-LD=$lt_LD
-
-# Commands used to build an old-style archive.
-old_archive_cmds=$lt_old_archive_cmds
-
-# A language specific compiler.
-CC=$lt_compiler
-
-# Is the compiler the GNU compiler?
-with_gcc=$GCC
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc
-
-# Whether or not to disallow shared libs when runtime libs are static.
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec
-
-# Whether the compiler copes with passing no objects directly.
-compiler_needs_object=$lt_compiler_needs_object
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
-
-# Commands used to build a shared archive.
-archive_cmds=$lt_archive_cmds
-archive_expsym_cmds=$lt_archive_expsym_cmds
-
-# Commands used to build a loadable module if different from building
-# a shared archive.
-module_cmds=$lt_module_cmds
-module_expsym_cmds=$lt_module_expsym_cmds
-
-# Whether we are building with GNU ld or not.
-with_gnu_ld=$lt_with_gnu_ld
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag
-
-# Flag that enforces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
-
-# If ld is used when linking, flag to hardcode \$libdir into a binary
-# during linking. This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
-
-# Whether we need a single "-rpath" flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator
-
-# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
-# DIR into the resulting binary.
-hardcode_direct=$hardcode_direct
-
-# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
-# DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
-# library is relocated.
-hardcode_direct_absolute=$hardcode_direct_absolute
-
-# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
-# into the resulting binary.
-hardcode_minus_L=$hardcode_minus_L
-
-# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
-# into the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var
-
-# Set to "yes" if building a shared library automatically hardcodes DIR
-# into the library and all subsequent libraries and executables linked
-# against it.
-hardcode_automatic=$hardcode_automatic
-
-# Set to yes if linker adds runtime paths of dependent libraries
-# to runtime path list.
-inherit_rpath=$inherit_rpath
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
-
-# Set to "yes" if exported symbols are required.
-always_export_symbols=$always_export_symbols
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms
-
-# Commands necessary for linking programs (against libraries) with templates.
-prelink_cmds=$lt_prelink_cmds
-
-# Specify filename containing input files.
-file_list_spec=$lt_file_list_spec
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action
-
-# ### END LIBTOOL CONFIG
-
-_LT_EOF
-
- case $host_os in
- aix3*)
- cat <<\_LT_EOF >> "$cfgfile"
-# AIX sometimes has problems with the GCC collect2 program. For some
-# reason, if we set the COLLECT_NAMES environment variable, the problems
-# vanish in a puff of smoke.
-if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
-fi
-_LT_EOF
- ;;
- esac
-
-
-ltmain="$ac_aux_dir/ltmain.sh"
-
-
- # We use sed instead of cat because bash on DJGPP gets confused if
- # if finds mixed CR/LF and LF-only lines. Since sed operates in
- # text mode, it properly converts lines to CR/LF. This bash problem
- # is reportedly fixed, but why not run on old versions too?
- sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- case $xsi_shell in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result="${1##*/}"
-}
-
-# func_dirname_and_basename file append nondir_replacement
-# perform func_basename and func_dirname in a single function
-# call:
-# dirname: Compute the dirname of FILE. If nonempty,
-# add APPEND to the result, otherwise set result
-# to NONDIR_REPLACEMENT.
-# value returned in "$func_dirname_result"
-# basename: Compute filename of FILE.
-# value retuned in "$func_basename_result"
-# Implementation must be kept synchronized with func_dirname
-# and func_basename. For efficiency, we do not delegate to
-# those functions but instead duplicate the functionality here.
-func_dirname_and_basename ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
- func_basename_result="${1##*/}"
-}
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-func_stripname ()
-{
- # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
- # positional parameters, so assign one to ordinary parameter first.
- func_stripname_result=${3}
- func_stripname_result=${func_stripname_result#"${1}"}
- func_stripname_result=${func_stripname_result%"${2}"}
-}
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=${1%%=*}
- func_opt_split_arg=${1#*=}
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- case ${1} in
- *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
- *) func_lo2o_result=${1} ;;
- esac
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=${1%.*}.lo
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=$(( $* ))
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=${#1}
-}
-
-_LT_EOF
- ;;
- *) # Bourne compatible functions.
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- # Extract subdirectory from the argument.
- func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
- if test "X$func_dirname_result" = "X${1}"; then
- func_dirname_result="${3}"
- else
- func_dirname_result="$func_dirname_result${2}"
- fi
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
-}
-
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-# func_strip_suffix prefix name
-func_stripname ()
-{
- case ${2} in
- .*) func_stripname_result=`$ECHO "X${3}" \
- | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
- *) func_stripname_result=`$ECHO "X${3}" \
- | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
- esac
-}
-
-# sed scripts:
-my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
-my_sed_long_arg='1s/^-[^=]*=//'
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
- func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'`
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=`expr "$@"`
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
-}
-
-_LT_EOF
-esac
-
-case $lt_shell_append in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$1+=\$2"
-}
-_LT_EOF
- ;;
- *)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$1=\$$1\$2"
-}
-
-_LT_EOF
- ;;
- esac
-
-
- sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- mv -f "$cfgfile" "$ofile" ||
- (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
- chmod +x "$ofile"
-
- ;;
-
- esac
-done # for ac_tag
-
-
-as_fn_exit 0
-_ACEOF
-ac_clean_files=$ac_clean_files_save
-
-test $ac_write_fail = 0 ||
- as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded. So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status. When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
- ac_cs_success=:
- ac_config_status_args=
- test "$silent" = yes &&
- ac_config_status_args="$ac_config_status_args --quiet"
- exec 5>/dev/null
- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
- exec 5>>config.log
- # Use ||, not &&, to avoid exiting from the if with $? = 1, which
- # would make configure fail if this is the last instruction.
- $ac_cs_success || as_fn_exit 1
-fi
-if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
-fi
-
diff --git a/deps/uv/src/unix/ev/configure.ac b/deps/uv/src/unix/ev/configure.ac
deleted file mode 100644
index 03a784f2e..000000000
--- a/deps/uv/src/unix/ev/configure.ac
+++ /dev/null
@@ -1,18 +0,0 @@
-AC_INIT
-AC_CONFIG_SRCDIR([ev_epoll.c])
-
-AM_INIT_AUTOMAKE(libev,4.04) dnl also update ev.h!
-AC_CONFIG_HEADERS([config.h])
-AM_MAINTAINER_MODE
-
-AC_PROG_INSTALL
-AC_PROG_LIBTOOL
-
-if test "x$GCC" = xyes ; then
- CFLAGS="-O3 $CFLAGS"
-fi
-
-m4_include([libev.m4])
-
-AC_CONFIG_FILES([Makefile])
-AC_OUTPUT
diff --git a/deps/uv/src/unix/ev/depcomp b/deps/uv/src/unix/ev/depcomp
deleted file mode 100755
index df8eea7e4..000000000
--- a/deps/uv/src/unix/ev/depcomp
+++ /dev/null
@@ -1,630 +0,0 @@
-#! /bin/sh
-# depcomp - compile a program generating dependencies as side-effects
-
-scriptversion=2009-04-28.21; # UTC
-
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
-# Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
-
-case $1 in
- '')
- echo "$0: No command. Try \`$0 --help' for more information." 1>&2
- exit 1;
- ;;
- -h | --h*)
- cat <<\EOF
-Usage: depcomp [--help] [--version] PROGRAM [ARGS]
-
-Run PROGRAMS ARGS to compile a file, generating dependencies
-as side-effects.
-
-Environment variables:
- depmode Dependency tracking mode.
- source Source file read by `PROGRAMS ARGS'.
- object Object file output by `PROGRAMS ARGS'.
- DEPDIR directory where to store dependencies.
- depfile Dependency file to output.
- tmpdepfile Temporary file to use when outputing dependencies.
- libtool Whether libtool is used (yes/no).
-
-Report bugs to <bug-automake@gnu.org>.
-EOF
- exit $?
- ;;
- -v | --v*)
- echo "depcomp $scriptversion"
- exit $?
- ;;
-esac
-
-if test -z "$depmode" || test -z "$source" || test -z "$object"; then
- echo "depcomp: Variables source, object and depmode must be set" 1>&2
- exit 1
-fi
-
-# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
-depfile=${depfile-`echo "$object" |
- sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
-tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
-
-rm -f "$tmpdepfile"
-
-# Some modes work just like other modes, but use different flags. We
-# parameterize here, but still list the modes in the big case below,
-# to make depend.m4 easier to write. Note that we *cannot* use a case
-# here, because this file can only contain one case statement.
-if test "$depmode" = hp; then
- # HP compiler uses -M and no extra arg.
- gccflag=-M
- depmode=gcc
-fi
-
-if test "$depmode" = dashXmstdout; then
- # This is just like dashmstdout with a different argument.
- dashmflag=-xM
- depmode=dashmstdout
-fi
-
-cygpath_u="cygpath -u -f -"
-if test "$depmode" = msvcmsys; then
- # This is just like msvisualcpp but w/o cygpath translation.
- # Just convert the backslash-escaped backslashes to single forward
- # slashes to satisfy depend.m4
- cygpath_u="sed s,\\\\\\\\,/,g"
- depmode=msvisualcpp
-fi
-
-case "$depmode" in
-gcc3)
-## gcc 3 implements dependency tracking that does exactly what
-## we want. Yay! Note: for some reason libtool 1.4 doesn't like
-## it if -MD -MP comes after the -MF stuff. Hmm.
-## Unfortunately, FreeBSD c89 acceptance of flags depends upon
-## the command line argument order; so add the flags where they
-## appear in depend2.am. Note that the slowdown incurred here
-## affects only configure: in makefiles, %FASTDEP% shortcuts this.
- for arg
- do
- case $arg in
- -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
- *) set fnord "$@" "$arg" ;;
- esac
- shift # fnord
- shift # $arg
- done
- "$@"
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- mv "$tmpdepfile" "$depfile"
- ;;
-
-gcc)
-## There are various ways to get dependency output from gcc. Here's
-## why we pick this rather obscure method:
-## - Don't want to use -MD because we'd like the dependencies to end
-## up in a subdir. Having to rename by hand is ugly.
-## (We might end up doing this anyway to support other compilers.)
-## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
-## -MM, not -M (despite what the docs say).
-## - Using -M directly means running the compiler twice (even worse
-## than renaming).
- if test -z "$gccflag"; then
- gccflag=-MD,
- fi
- "$@" -Wp,"$gccflag$tmpdepfile"
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- rm -f "$depfile"
- echo "$object : \\" > "$depfile"
- alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-## The second -e expression handles DOS-style file names with drive letters.
- sed -e 's/^[^:]*: / /' \
- -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
-## This next piece of magic avoids the `deleted header file' problem.
-## The problem is that when a header file which appears in a .P file
-## is deleted, the dependency causes make to die (because there is
-## typically no way to rebuild the header). We avoid this by adding
-## dummy dependencies for each header file. Too bad gcc doesn't do
-## this for us directly.
- tr ' ' '
-' < "$tmpdepfile" |
-## Some versions of gcc put a space before the `:'. On the theory
-## that the space means something, we add a space to the output as
-## well.
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-hp)
- # This case exists only to let depend.m4 do its work. It works by
- # looking at the text of this script. This case will never be run,
- # since it is checked for above.
- exit 1
- ;;
-
-sgi)
- if test "$libtool" = yes; then
- "$@" "-Wp,-MDupdate,$tmpdepfile"
- else
- "$@" -MDupdate "$tmpdepfile"
- fi
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- rm -f "$depfile"
-
- if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
- echo "$object : \\" > "$depfile"
-
- # Clip off the initial element (the dependent). Don't try to be
- # clever and replace this with sed code, as IRIX sed won't handle
- # lines with more than a fixed number of characters (4096 in
- # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
- # the IRIX cc adds comments like `#:fec' to the end of the
- # dependency line.
- tr ' ' '
-' < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
- tr '
-' ' ' >> "$depfile"
- echo >> "$depfile"
-
- # The second pass generates a dummy entry for each header file.
- tr ' ' '
-' < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
- >> "$depfile"
- else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
-
-aix)
- # The C for AIX Compiler uses -M and outputs the dependencies
- # in a .u file. In older versions, this file always lives in the
- # current directory. Also, the AIX compiler puts `$object:' at the
- # start of each line; $object doesn't have directory information.
- # Version 6 uses the directory in both cases.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
- if test "$libtool" = yes; then
- tmpdepfile1=$dir$base.u
- tmpdepfile2=$base.u
- tmpdepfile3=$dir.libs/$base.u
- "$@" -Wc,-M
- else
- tmpdepfile1=$dir$base.u
- tmpdepfile2=$dir$base.u
- tmpdepfile3=$dir$base.u
- "$@" -M
- fi
- stat=$?
-
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- # Each line is of the form `foo.o: dependent.h'.
- # Do two passes, one to just change these to
- # `$object: dependent.h' and one to simply `dependent.h:'.
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
-
-icc)
- # Intel's C compiler understands `-MD -MF file'. However on
- # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
- # ICC 7.0 will fill foo.d with something like
- # foo.o: sub/foo.c
- # foo.o: sub/foo.h
- # which is wrong. We want:
- # sub/foo.o: sub/foo.c
- # sub/foo.o: sub/foo.h
- # sub/foo.c:
- # sub/foo.h:
- # ICC 7.1 will output
- # foo.o: sub/foo.c sub/foo.h
- # and will wrap long lines using \ :
- # foo.o: sub/foo.c ... \
- # sub/foo.h ... \
- # ...
-
- "$@" -MD -MF "$tmpdepfile"
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- rm -f "$depfile"
- # Each line is of the form `foo.o: dependent.h',
- # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
- # Do two passes, one to just change these to
- # `$object: dependent.h' and one to simply `dependent.h:'.
- sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
- # Some versions of the HPUX 10.20 sed can't process this invocation
- # correctly. Breaking it into two sed invocations is a workaround.
- sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
- sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-hp2)
- # The "hp" stanza above does not work with aCC (C++) and HP's ia64
- # compilers, which have integrated preprocessors. The correct option
- # to use with these is +Maked; it writes dependencies to a file named
- # 'foo.d', which lands next to the object file, wherever that
- # happens to be.
- # Much of this is similar to the tru64 case; see comments there.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
- if test "$libtool" = yes; then
- tmpdepfile1=$dir$base.d
- tmpdepfile2=$dir.libs/$base.d
- "$@" -Wc,+Maked
- else
- tmpdepfile1=$dir$base.d
- tmpdepfile2=$dir$base.d
- "$@" +Maked
- fi
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
- # Add `dependent.h:' lines.
- sed -ne '2,${
- s/^ *//
- s/ \\*$//
- s/$/:/
- p
- }' "$tmpdepfile" >> "$depfile"
- else
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile" "$tmpdepfile2"
- ;;
-
-tru64)
- # The Tru64 compiler uses -MD to generate dependencies as a side
- # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
- # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
- # dependencies in `foo.d' instead, so we check for that too.
- # Subdirectories are respected.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
-
- if test "$libtool" = yes; then
- # With Tru64 cc, shared objects can also be used to make a
- # static library. This mechanism is used in libtool 1.4 series to
- # handle both shared and static libraries in a single compilation.
- # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
- #
- # With libtool 1.5 this exception was removed, and libtool now
- # generates 2 separate objects for the 2 libraries. These two
- # compilations output dependencies in $dir.libs/$base.o.d and
- # in $dir$base.o.d. We have to check for both files, because
- # one of the two compilations can be disabled. We should prefer
- # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
- # automatically cleaned when .libs/ is deleted, while ignoring
- # the former would cause a distcleancheck panic.
- tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
- tmpdepfile2=$dir$base.o.d # libtool 1.5
- tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
- tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
- "$@" -Wc,-MD
- else
- tmpdepfile1=$dir$base.o.d
- tmpdepfile2=$dir$base.d
- tmpdepfile3=$dir$base.d
- tmpdepfile4=$dir$base.d
- "$@" -MD
- fi
-
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
-
-#nosideeffect)
- # This comment above is used by automake to tell side-effect
- # dependency tracking mechanisms from slower ones.
-
-dashmstdout)
- # Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout, regardless of -o.
- "$@" || exit $?
-
- # Remove the call to Libtool.
- if test "$libtool" = yes; then
- while test "X$1" != 'X--mode=compile'; do
- shift
- done
- shift
- fi
-
- # Remove `-o $object'.
- IFS=" "
- for arg
- do
- case $arg in
- -o)
- shift
- ;;
- $object)
- shift
- ;;
- *)
- set fnord "$@" "$arg"
- shift # fnord
- shift # $arg
- ;;
- esac
- done
-
- test -z "$dashmflag" && dashmflag=-M
- # Require at least two characters before searching for `:'
- # in the target name. This is to cope with DOS-style filenames:
- # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
- "$@" $dashmflag |
- sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
- rm -f "$depfile"
- cat < "$tmpdepfile" > "$depfile"
- tr ' ' '
-' < "$tmpdepfile" | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-dashXmstdout)
- # This case only exists to satisfy depend.m4. It is never actually
- # run, as this mode is specially recognized in the preamble.
- exit 1
- ;;
-
-makedepend)
- "$@" || exit $?
- # Remove any Libtool call
- if test "$libtool" = yes; then
- while test "X$1" != 'X--mode=compile'; do
- shift
- done
- shift
- fi
- # X makedepend
- shift
- cleared=no eat=no
- for arg
- do
- case $cleared in
- no)
- set ""; shift
- cleared=yes ;;
- esac
- if test $eat = yes; then
- eat=no
- continue
- fi
- case "$arg" in
- -D*|-I*)
- set fnord "$@" "$arg"; shift ;;
- # Strip any option that makedepend may not understand. Remove
- # the object too, otherwise makedepend will parse it as a source file.
- -arch)
- eat=yes ;;
- -*|$object)
- ;;
- *)
- set fnord "$@" "$arg"; shift ;;
- esac
- done
- obj_suffix=`echo "$object" | sed 's/^.*\././'`
- touch "$tmpdepfile"
- ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
- rm -f "$depfile"
- cat < "$tmpdepfile" > "$depfile"
- sed '1,2d' "$tmpdepfile" | tr ' ' '
-' | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile" "$tmpdepfile".bak
- ;;
-
-cpp)
- # Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout.
- "$@" || exit $?
-
- # Remove the call to Libtool.
- if test "$libtool" = yes; then
- while test "X$1" != 'X--mode=compile'; do
- shift
- done
- shift
- fi
-
- # Remove `-o $object'.
- IFS=" "
- for arg
- do
- case $arg in
- -o)
- shift
- ;;
- $object)
- shift
- ;;
- *)
- set fnord "$@" "$arg"
- shift # fnord
- shift # $arg
- ;;
- esac
- done
-
- "$@" -E |
- sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
- -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
- sed '$ s: \\$::' > "$tmpdepfile"
- rm -f "$depfile"
- echo "$object : \\" > "$depfile"
- cat < "$tmpdepfile" >> "$depfile"
- sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-msvisualcpp)
- # Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout.
- "$@" || exit $?
-
- # Remove the call to Libtool.
- if test "$libtool" = yes; then
- while test "X$1" != 'X--mode=compile'; do
- shift
- done
- shift
- fi
-
- IFS=" "
- for arg
- do
- case "$arg" in
- -o)
- shift
- ;;
- $object)
- shift
- ;;
- "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
- set fnord "$@"
- shift
- shift
- ;;
- *)
- set fnord "$@" "$arg"
- shift
- shift
- ;;
- esac
- done
- "$@" -E 2>/dev/null |
- sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
- rm -f "$depfile"
- echo "$object : \\" > "$depfile"
- sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
- echo " " >> "$depfile"
- sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-msvcmsys)
- # This case exists only to let depend.m4 do its work. It works by
- # looking at the text of this script. This case will never be run,
- # since it is checked for above.
- exit 1
- ;;
-
-none)
- exec "$@"
- ;;
-
-*)
- echo "Unknown depmode $depmode" 1>&2
- exit 1
- ;;
-esac
-
-exit 0
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
-# End:
diff --git a/deps/uv/src/unix/ev/ev++.h b/deps/uv/src/unix/ev/ev++.h
deleted file mode 100644
index ce42b5f2d..000000000
--- a/deps/uv/src/unix/ev/ev++.h
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- * libev simple C++ wrapper classes
- *
- * Copyright (c) 2007,2008,2010 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifndef EVPP_H__
-#define EVPP_H__
-
-#ifdef EV_H
-# include EV_H
-#else
-# include "ev.h"
-#endif
-
-#ifndef EV_USE_STDEXCEPT
-# define EV_USE_STDEXCEPT 1
-#endif
-
-#if EV_USE_STDEXCEPT
-# include <stdexcept>
-#endif
-
-namespace ev {
-
- typedef ev_tstamp tstamp;
-
- enum {
- UNDEF = EV_UNDEF,
- NONE = EV_NONE,
- READ = EV_READ,
- WRITE = EV_WRITE,
-#if EV_COMPAT3
- TIMEOUT = EV_TIMEOUT,
-#endif
- TIMER = EV_TIMER,
- PERIODIC = EV_PERIODIC,
- SIGNAL = EV_SIGNAL,
- CHILD = EV_CHILD,
- STAT = EV_STAT,
- IDLE = EV_IDLE,
- CHECK = EV_CHECK,
- PREPARE = EV_PREPARE,
- FORK = EV_FORK,
- ASYNC = EV_ASYNC,
- EMBED = EV_EMBED,
-# undef ERROR // some systems stupidly #define ERROR
- ERROR = EV_ERROR
- };
-
- enum
- {
- AUTO = EVFLAG_AUTO,
- NOENV = EVFLAG_NOENV,
- FORKCHECK = EVFLAG_FORKCHECK,
-
- SELECT = EVBACKEND_SELECT,
- POLL = EVBACKEND_POLL,
- EPOLL = EVBACKEND_EPOLL,
- KQUEUE = EVBACKEND_KQUEUE,
- DEVPOLL = EVBACKEND_DEVPOLL,
- PORT = EVBACKEND_PORT
- };
-
- enum
- {
-#if EV_COMPAT3
- NONBLOCK = EVLOOP_NONBLOCK,
- ONESHOT = EVLOOP_ONESHOT,
-#endif
- NOWAIT = EVRUN_NOWAIT,
- ONCE = EVRUN_ONCE
- };
-
- enum how_t
- {
- ONE = EVBREAK_ONE,
- ALL = EVBREAK_ALL
- };
-
- struct bad_loop
-#if EV_USE_STDEXCEPT
- : std::runtime_error
-#endif
- {
-#if EV_USE_STDEXCEPT
- bad_loop ()
- : std::runtime_error ("libev event loop cannot be initialized, bad value of LIBEV_FLAGS?")
- {
- }
-#endif
- };
-
-#ifdef EV_AX
-# undef EV_AX
-#endif
-
-#ifdef EV_AX_
-# undef EV_AX_
-#endif
-
-#if EV_MULTIPLICITY
-# define EV_AX raw_loop
-# define EV_AX_ raw_loop,
-#else
-# define EV_AX
-# define EV_AX_
-#endif
-
- struct loop_ref
- {
- loop_ref (EV_P) throw ()
-#if EV_MULTIPLICITY
- : EV_AX (EV_A)
-#endif
- {
- }
-
- bool operator == (const loop_ref &other) const throw ()
- {
-#if EV_MULTIPLICITY
- return EV_AX == other.EV_AX;
-#else
- return true;
-#endif
- }
-
- bool operator != (const loop_ref &other) const throw ()
- {
-#if EV_MULTIPLICITY
- return ! (*this == other);
-#else
- return false;
-#endif
- }
-
-#if EV_MULTIPLICITY
- bool operator == (const EV_P) const throw ()
- {
- return this->EV_AX == EV_A;
- }
-
- bool operator != (const EV_P) const throw ()
- {
- return (*this == EV_A);
- }
-
- operator struct ev_loop * () const throw ()
- {
- return EV_AX;
- }
-
- operator const struct ev_loop * () const throw ()
- {
- return EV_AX;
- }
-
- bool is_default () const throw ()
- {
- return EV_AX == ev_default_loop (0);
- }
-#endif
-
-#if EV_COMPAT3
- void loop (int flags = 0)
- {
- ev_run (EV_AX_ flags);
- }
-
- void unloop (how_t how = ONE) throw ()
- {
- ev_break (EV_AX_ how);
- }
-#endif
-
- void run (int flags = 0)
- {
- ev_run (EV_AX_ flags);
- }
-
- void break_loop (how_t how = ONE) throw ()
- {
- ev_break (EV_AX_ how);
- }
-
- void post_fork () throw ()
- {
- ev_loop_fork (EV_AX);
- }
-
- unsigned int backend () const throw ()
- {
- return ev_backend (EV_AX);
- }
-
- tstamp now () const throw ()
- {
- return ev_now (EV_AX);
- }
-
- void ref () throw ()
- {
- ev_ref (EV_AX);
- }
-
- void unref () throw ()
- {
- ev_unref (EV_AX);
- }
-
-#if EV_FEATURE_API
- unsigned int iteration () const throw ()
- {
- return ev_iteration (EV_AX);
- }
-
- unsigned int depth () const throw ()
- {
- return ev_depth (EV_AX);
- }
-
- void set_io_collect_interval (tstamp interval) throw ()
- {
- ev_set_io_collect_interval (EV_AX_ interval);
- }
-
- void set_timeout_collect_interval (tstamp interval) throw ()
- {
- ev_set_timeout_collect_interval (EV_AX_ interval);
- }
-#endif
-
- // function callback
- void once (int fd, int events, tstamp timeout, void (*cb)(int, void *), void *arg = 0) throw ()
- {
- ev_once (EV_AX_ fd, events, timeout, cb, arg);
- }
-
- // method callback
- template<class K, void (K::*method)(int)>
- void once (int fd, int events, tstamp timeout, K *object) throw ()
- {
- once (fd, events, timeout, method_thunk<K, method>, object);
- }
-
- // default method == operator ()
- template<class K>
- void once (int fd, int events, tstamp timeout, K *object) throw ()
- {
- once (fd, events, timeout, method_thunk<K, &K::operator ()>, object);
- }
-
- template<class K, void (K::*method)(int)>
- static void method_thunk (int revents, void *arg)
- {
- static_cast<K *>(arg)->*method
- (revents);
- }
-
- // no-argument method callback
- template<class K, void (K::*method)()>
- void once (int fd, int events, tstamp timeout, K *object) throw ()
- {
- once (fd, events, timeout, method_noargs_thunk<K, method>, object);
- }
-
- template<class K, void (K::*method)()>
- static void method_noargs_thunk (int revents, void *arg)
- {
- static_cast<K *>(arg)->*method
- ();
- }
-
- // simpler function callback
- template<void (*cb)(int)>
- void once (int fd, int events, tstamp timeout) throw ()
- {
- once (fd, events, timeout, simpler_func_thunk<cb>);
- }
-
- template<void (*cb)(int)>
- static void simpler_func_thunk (int revents, void *arg)
- {
- (*cb)
- (revents);
- }
-
- // simplest function callback
- template<void (*cb)()>
- void once (int fd, int events, tstamp timeout) throw ()
- {
- once (fd, events, timeout, simplest_func_thunk<cb>);
- }
-
- template<void (*cb)()>
- static void simplest_func_thunk (int revents, void *arg)
- {
- (*cb)
- ();
- }
-
- void feed_fd_event (int fd, int revents) throw ()
- {
- ev_feed_fd_event (EV_AX_ fd, revents);
- }
-
- void feed_signal_event (int signum) throw ()
- {
- ev_feed_signal_event (EV_AX_ signum);
- }
-
-#if EV_MULTIPLICITY
- struct ev_loop* EV_AX;
-#endif
-
- };
-
-#if EV_MULTIPLICITY
- struct dynamic_loop : loop_ref
- {
-
- dynamic_loop (unsigned int flags = AUTO) throw (bad_loop)
- : loop_ref (ev_loop_new (flags))
- {
- if (!EV_AX)
- throw bad_loop ();
- }
-
- ~dynamic_loop () throw ()
- {
- ev_loop_destroy (EV_AX);
- EV_AX = 0;
- }
-
- private:
-
- dynamic_loop (const dynamic_loop &);
-
- dynamic_loop & operator= (const dynamic_loop &);
-
- };
-#endif
-
- struct default_loop : loop_ref
- {
- default_loop (unsigned int flags = AUTO) throw (bad_loop)
-#if EV_MULTIPLICITY
- : loop_ref (ev_default_loop (flags))
-#endif
- {
- if (
-#if EV_MULTIPLICITY
- !EV_AX
-#else
- !ev_default_loop (flags)
-#endif
- )
- throw bad_loop ();
- }
-
- private:
- default_loop (const default_loop &);
- default_loop &operator = (const default_loop &);
- };
-
- inline loop_ref get_default_loop () throw ()
- {
-#if EV_MULTIPLICITY
- return ev_default_loop (0);
-#else
- return loop_ref ();
-#endif
- }
-
-#undef EV_AX
-#undef EV_AX_
-
-#undef EV_PX
-#undef EV_PX_
-#if EV_MULTIPLICITY
-# define EV_PX loop_ref EV_A
-# define EV_PX_ loop_ref EV_A_
-#else
-# define EV_PX
-# define EV_PX_
-#endif
-
- template<class ev_watcher, class watcher>
- struct base : ev_watcher
- {
- #if EV_MULTIPLICITY
- EV_PX;
-
- // loop set
- void set (EV_P) throw ()
- {
- this->EV_A = EV_A;
- }
- #endif
-
- base (EV_PX) throw ()
- #if EV_MULTIPLICITY
- : EV_A (EV_A)
- #endif
- {
- ev_init (this, 0);
- }
-
- void set_ (const void *data, void (*cb)(EV_P_ ev_watcher *w, int revents)) throw ()
- {
- this->data = (void *)data;
- ev_set_cb (static_cast<ev_watcher *>(this), cb);
- }
-
- // function callback
- template<void (*function)(watcher &w, int)>
- void set (void *data = 0) throw ()
- {
- set_ (data, function_thunk<function>);
- }
-
- template<void (*function)(watcher &w, int)>
- static void function_thunk (EV_P_ ev_watcher *w, int revents)
- {
- function
- (*static_cast<watcher *>(w), revents);
- }
-
- // method callback
- template<class K, void (K::*method)(watcher &w, int)>
- void set (K *object) throw ()
- {
- set_ (object, method_thunk<K, method>);
- }
-
- // default method == operator ()
- template<class K>
- void set (K *object) throw ()
- {
- set_ (object, method_thunk<K, &K::operator ()>);
- }
-
- template<class K, void (K::*method)(watcher &w, int)>
- static void method_thunk (EV_P_ ev_watcher *w, int revents)
- {
- (static_cast<K *>(w->data)->*method)
- (*static_cast<watcher *>(w), revents);
- }
-
- // no-argument callback
- template<class K, void (K::*method)()>
- void set (K *object) throw ()
- {
- set_ (object, method_noargs_thunk<K, method>);
- }
-
- template<class K, void (K::*method)()>
- static void method_noargs_thunk (EV_P_ ev_watcher *w, int revents)
- {
- (static_cast<K *>(w->data)->*method)
- ();
- }
-
- void operator ()(int events = EV_UNDEF)
- {
- return
- ev_cb (static_cast<ev_watcher *>(this))
- (static_cast<ev_watcher *>(this), events);
- }
-
- bool is_active () const throw ()
- {
- return ev_is_active (static_cast<const ev_watcher *>(this));
- }
-
- bool is_pending () const throw ()
- {
- return ev_is_pending (static_cast<const ev_watcher *>(this));
- }
-
- void feed_event (int revents) throw ()
- {
- ev_feed_event (EV_A_ static_cast<const ev_watcher *>(this), revents);
- }
- };
-
- inline tstamp now () throw ()
- {
- return ev_time ();
- }
-
- inline void delay (tstamp interval) throw ()
- {
- ev_sleep (interval);
- }
-
- inline int version_major () throw ()
- {
- return ev_version_major ();
- }
-
- inline int version_minor () throw ()
- {
- return ev_version_minor ();
- }
-
- inline unsigned int supported_backends () throw ()
- {
- return ev_supported_backends ();
- }
-
- inline unsigned int recommended_backends () throw ()
- {
- return ev_recommended_backends ();
- }
-
- inline unsigned int embeddable_backends () throw ()
- {
- return ev_embeddable_backends ();
- }
-
- inline void set_allocator (void *(*cb)(void *ptr, long size)) throw ()
- {
- ev_set_allocator (cb);
- }
-
- inline void set_syserr_cb (void (*cb)(const char *msg)) throw ()
- {
- ev_set_syserr_cb (cb);
- }
-
- #if EV_MULTIPLICITY
- #define EV_CONSTRUCT(cppstem,cstem) \
- (EV_PX = get_default_loop ()) throw () \
- : base<ev_ ## cstem, cppstem> (EV_A) \
- { \
- }
- #else
- #define EV_CONSTRUCT(cppstem,cstem) \
- () throw () \
- { \
- }
- #endif
-
- /* using a template here would require quite a bit more lines,
- * so a macro solution was chosen */
- #define EV_BEGIN_WATCHER(cppstem,cstem) \
- \
- struct cppstem : base<ev_ ## cstem, cppstem> \
- { \
- void start () throw () \
- { \
- ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this)); \
- } \
- \
- void stop () throw () \
- { \
- ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this)); \
- } \
- \
- cppstem EV_CONSTRUCT(cppstem,cstem) \
- \
- ~cppstem () throw () \
- { \
- stop (); \
- } \
- \
- using base<ev_ ## cstem, cppstem>::set; \
- \
- private: \
- \
- cppstem (const cppstem &o); \
- \
- cppstem &operator =(const cppstem &o); \
- \
- public:
-
- #define EV_END_WATCHER(cppstem,cstem) \
- };
-
- EV_BEGIN_WATCHER (io, io)
- void set (int fd, int events) throw ()
- {
- int active = is_active ();
- if (active) stop ();
- ev_io_set (static_cast<ev_io *>(this), fd, events);
- if (active) start ();
- }
-
- void set (int events) throw ()
- {
- int active = is_active ();
- if (active) stop ();
- ev_io_set (static_cast<ev_io *>(this), fd, events);
- if (active) start ();
- }
-
- void start (int fd, int events) throw ()
- {
- set (fd, events);
- start ();
- }
- EV_END_WATCHER (io, io)
-
- EV_BEGIN_WATCHER (timer, timer)
- void set (ev_tstamp after, ev_tstamp repeat = 0.) throw ()
- {
- int active = is_active ();
- if (active) stop ();
- ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
- if (active) start ();
- }
-
- void start (ev_tstamp after, ev_tstamp repeat = 0.) throw ()
- {
- set (after, repeat);
- start ();
- }
-
- void again () throw ()
- {
- ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
- }
-
- ev_tstamp remaining ()
- {
- return ev_timer_remaining (EV_A_ static_cast<ev_timer *>(this));
- }
- EV_END_WATCHER (timer, timer)
-
- #if EV_PERIODIC_ENABLE
- EV_BEGIN_WATCHER (periodic, periodic)
- void set (ev_tstamp at, ev_tstamp interval = 0.) throw ()
- {
- int active = is_active ();
- if (active) stop ();
- ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
- if (active) start ();
- }
-
- void start (ev_tstamp at, ev_tstamp interval = 0.) throw ()
- {
- set (at, interval);
- start ();
- }
-
- void again () throw ()
- {
- ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
- }
- EV_END_WATCHER (periodic, periodic)
- #endif
-
- #if EV_SIGNAL_ENABLE
- EV_BEGIN_WATCHER (sig, signal)
- void set (int signum) throw ()
- {
- int active = is_active ();
- if (active) stop ();
- ev_signal_set (static_cast<ev_signal *>(this), signum);
- if (active) start ();
- }
-
- void start (int signum) throw ()
- {
- set (signum);
- start ();
- }
- EV_END_WATCHER (sig, signal)
- #endif
-
- #if EV_CHILD_ENABLE
- EV_BEGIN_WATCHER (child, child)
- void set (int pid, int trace = 0) throw ()
- {
- int active = is_active ();
- if (active) stop ();
- ev_child_set (static_cast<ev_child *>(this), pid, trace);
- if (active) start ();
- }
-
- void start (int pid, int trace = 0) throw ()
- {
- set (pid, trace);
- start ();
- }
- EV_END_WATCHER (child, child)
- #endif
-
- #if EV_STAT_ENABLE
- EV_BEGIN_WATCHER (stat, stat)
- void set (const char *path, ev_tstamp interval = 0.) throw ()
- {
- int active = is_active ();
- if (active) stop ();
- ev_stat_set (static_cast<ev_stat *>(this), path, interval);
- if (active) start ();
- }
-
- void start (const char *path, ev_tstamp interval = 0.) throw ()
- {
- stop ();
- set (path, interval);
- start ();
- }
-
- void update () throw ()
- {
- ev_stat_stat (EV_A_ static_cast<ev_stat *>(this));
- }
- EV_END_WATCHER (stat, stat)
- #endif
-
- #if EV_IDLE_ENABLE
- EV_BEGIN_WATCHER (idle, idle)
- void set () throw () { }
- EV_END_WATCHER (idle, idle)
- #endif
-
- #if EV_PREPARE_ENABLE
- EV_BEGIN_WATCHER (prepare, prepare)
- void set () throw () { }
- EV_END_WATCHER (prepare, prepare)
- #endif
-
- #if EV_CHECK_ENABLE
- EV_BEGIN_WATCHER (check, check)
- void set () throw () { }
- EV_END_WATCHER (check, check)
- #endif
-
- #if EV_EMBED_ENABLE
- EV_BEGIN_WATCHER (embed, embed)
- void set (struct ev_loop *embedded_loop) throw ()
- {
- int active = is_active ();
- if (active) stop ();
- ev_embed_set (static_cast<ev_embed *>(this), embedded_loop);
- if (active) start ();
- }
-
- void start (struct ev_loop *embedded_loop) throw ()
- {
- set (embedded_loop);
- start ();
- }
-
- void sweep ()
- {
- ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
- }
- EV_END_WATCHER (embed, embed)
- #endif
-
- #if EV_FORK_ENABLE
- EV_BEGIN_WATCHER (fork, fork)
- void set () throw () { }
- EV_END_WATCHER (fork, fork)
- #endif
-
- #if EV_ASYNC_ENABLE
- EV_BEGIN_WATCHER (async, async)
- void send () throw ()
- {
- ev_async_send (EV_A_ static_cast<ev_async *>(this));
- }
-
- bool async_pending () throw ()
- {
- return ev_async_pending (static_cast<ev_async *>(this));
- }
- EV_END_WATCHER (async, async)
- #endif
-
- #undef EV_PX
- #undef EV_PX_
- #undef EV_CONSTRUCT
- #undef EV_BEGIN_WATCHER
- #undef EV_END_WATCHER
-}
-
-#endif
-
diff --git a/deps/uv/src/unix/ev/ev.3 b/deps/uv/src/unix/ev/ev.3
deleted file mode 100644
index f2a451458..000000000
--- a/deps/uv/src/unix/ev/ev.3
+++ /dev/null
@@ -1,5311 +0,0 @@
-.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07)
-.\"
-.\" Standard preamble:
-.\" ========================================================================
-.de Sp \" Vertical space (when we can't use .PP)
-.if t .sp .5v
-.if n .sp
-..
-.de Vb \" Begin verbatim text
-.ft CW
-.nf
-.ne \\$1
-..
-.de Ve \" End verbatim text
-.ft R
-.fi
-..
-.\" Set up some character translations and predefined strings. \*(-- will
-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
-.\" double quote, and \*(R" will give a right double quote. \*(C+ will
-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
-.\" nothing in troff, for use with C<>.
-.tr \(*W-
-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
-.ie n \{\
-. ds -- \(*W-
-. ds PI pi
-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
-. ds L" ""
-. ds R" ""
-. ds C` ""
-. ds C' ""
-'br\}
-.el\{\
-. ds -- \|\(em\|
-. ds PI \(*p
-. ds L" ``
-. ds R" ''
-'br\}
-.\"
-.\" Escape single quotes in literal strings from groff's Unicode transform.
-.ie \n(.g .ds Aq \(aq
-.el .ds Aq '
-.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
-.\" entries marked with X<> in POD. Of course, you'll have to process the
-.\" output yourself in some meaningful fashion.
-.ie \nF \{\
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
-..
-. nr % 0
-. rr F
-.\}
-.el \{\
-. de IX
-..
-.\}
-.\"
-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
-.\" Fear. Run. Save yourself. No user-serviceable parts.
-. \" fudge factors for nroff and troff
-.if n \{\
-. ds #H 0
-. ds #V .8m
-. ds #F .3m
-. ds #[ \f1
-. ds #] \fP
-.\}
-.if t \{\
-. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
-. ds #V .6m
-. ds #F 0
-. ds #[ \&
-. ds #] \&
-.\}
-. \" simple accents for nroff and troff
-.if n \{\
-. ds ' \&
-. ds ` \&
-. ds ^ \&
-. ds , \&
-. ds ~ ~
-. ds /
-.\}
-.if t \{\
-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
-.\}
-. \" troff and (daisy-wheel) nroff accents
-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
-.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
-.ds ae a\h'-(\w'a'u*4/10)'e
-.ds Ae A\h'-(\w'A'u*4/10)'E
-. \" corrections for vroff
-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
-. \" for low resolution devices (crt and lpr)
-.if \n(.H>23 .if \n(.V>19 \
-\{\
-. ds : e
-. ds 8 ss
-. ds o a
-. ds d- d\h'-1'\(ga
-. ds D- D\h'-1'\(hy
-. ds th \o'bp'
-. ds Th \o'LP'
-. ds ae ae
-. ds Ae AE
-.\}
-.rm #[ #] #H #V #F C
-.\" ========================================================================
-.\"
-.IX Title "LIBEV 3"
-.TH LIBEV 3 "2011-02-16" "libev-4.04" "libev - high performance full featured event loop"
-.\" For nroff, turn off justification. Always turn off hyphenation; it makes
-.\" way too many mistakes in technical documents.
-.if n .ad l
-.nh
-.SH "NAME"
-libev \- a high performance full\-featured event loop written in C
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-.Vb 1
-\& #include <ev.h>
-.Ve
-.SS "\s-1EXAMPLE\s0 \s-1PROGRAM\s0"
-.IX Subsection "EXAMPLE PROGRAM"
-.Vb 2
-\& // a single header file is required
-\& #include <ev.h>
-\&
-\& #include <stdio.h> // for puts
-\&
-\& // every watcher type has its own typedef\*(Aqd struct
-\& // with the name ev_TYPE
-\& ev_io stdin_watcher;
-\& ev_timer timeout_watcher;
-\&
-\& // all watcher callbacks have a similar signature
-\& // this callback is called when data is readable on stdin
-\& static void
-\& stdin_cb (EV_P_ ev_io *w, int revents)
-\& {
-\& puts ("stdin ready");
-\& // for one\-shot events, one must manually stop the watcher
-\& // with its corresponding stop function.
-\& ev_io_stop (EV_A_ w);
-\&
-\& // this causes all nested ev_run\*(Aqs to stop iterating
-\& ev_break (EV_A_ EVBREAK_ALL);
-\& }
-\&
-\& // another callback, this time for a time\-out
-\& static void
-\& timeout_cb (EV_P_ ev_timer *w, int revents)
-\& {
-\& puts ("timeout");
-\& // this causes the innermost ev_run to stop iterating
-\& ev_break (EV_A_ EVBREAK_ONE);
-\& }
-\&
-\& int
-\& main (void)
-\& {
-\& // use the default event loop unless you have special needs
-\& struct ev_loop *loop = EV_DEFAULT;
-\&
-\& // initialise an io watcher, then start it
-\& // this one will watch for stdin to become readable
-\& ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
-\& ev_io_start (loop, &stdin_watcher);
-\&
-\& // initialise a timer watcher, then start it
-\& // simple non\-repeating 5.5 second timeout
-\& ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
-\& ev_timer_start (loop, &timeout_watcher);
-\&
-\& // now wait for events to arrive
-\& ev_run (loop, 0);
-\&
-\& // break was called, so exit
-\& return 0;
-\& }
-.Ve
-.SH "ABOUT THIS DOCUMENT"
-.IX Header "ABOUT THIS DOCUMENT"
-This document documents the libev software package.
-.PP
-The newest version of this document is also available as an html-formatted
-web page you might find easier to navigate when reading it for the first
-time: <http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod>.
-.PP
-While this document tries to be as complete as possible in documenting
-libev, its usage and the rationale behind its design, it is not a tutorial
-on event-based programming, nor will it introduce event-based programming
-with libev.
-.PP
-Familiarity with event based programming techniques in general is assumed
-throughout this document.
-.SH "WHAT TO READ WHEN IN A HURRY"
-.IX Header "WHAT TO READ WHEN IN A HURRY"
-This manual tries to be very detailed, but unfortunately, this also makes
-it very long. If you just want to know the basics of libev, I suggest
-reading \*(L"\s-1ANATOMY\s0 \s-1OF\s0 A \s-1WATCHER\s0\*(R", then the \*(L"\s-1EXAMPLE\s0 \s-1PROGRAM\s0\*(R" above and
-look up the missing functions in \*(L"\s-1GLOBAL\s0 \s-1FUNCTIONS\s0\*(R" and the \f(CW\*(C`ev_io\*(C'\fR and
-\&\f(CW\*(C`ev_timer\*(C'\fR sections in \*(L"\s-1WATCHER\s0 \s-1TYPES\s0\*(R".
-.SH "ABOUT LIBEV"
-.IX Header "ABOUT LIBEV"
-Libev is an event loop: you register interest in certain events (such as a
-file descriptor being readable or a timeout occurring), and it will manage
-these event sources and provide your program with events.
-.PP
-To do this, it must take more or less complete control over your process
-(or thread) by executing the \fIevent loop\fR handler, and will then
-communicate events via a callback mechanism.
-.PP
-You register interest in certain events by registering so-called \fIevent
-watchers\fR, which are relatively small C structures you initialise with the
-details of the event, and then hand it over to libev by \fIstarting\fR the
-watcher.
-.SS "\s-1FEATURES\s0"
-.IX Subsection "FEATURES"
-Libev supports \f(CW\*(C`select\*(C'\fR, \f(CW\*(C`poll\*(C'\fR, the Linux-specific \f(CW\*(C`epoll\*(C'\fR, the
-BSD-specific \f(CW\*(C`kqueue\*(C'\fR and the Solaris-specific event port mechanisms
-for file descriptor events (\f(CW\*(C`ev_io\*(C'\fR), the Linux \f(CW\*(C`inotify\*(C'\fR interface
-(for \f(CW\*(C`ev_stat\*(C'\fR), Linux eventfd/signalfd (for faster and cleaner
-inter-thread wakeup (\f(CW\*(C`ev_async\*(C'\fR)/signal handling (\f(CW\*(C`ev_signal\*(C'\fR)) relative
-timers (\f(CW\*(C`ev_timer\*(C'\fR), absolute timers with customised rescheduling
-(\f(CW\*(C`ev_periodic\*(C'\fR), synchronous signals (\f(CW\*(C`ev_signal\*(C'\fR), process status
-change events (\f(CW\*(C`ev_child\*(C'\fR), and event watchers dealing with the event
-loop mechanism itself (\f(CW\*(C`ev_idle\*(C'\fR, \f(CW\*(C`ev_embed\*(C'\fR, \f(CW\*(C`ev_prepare\*(C'\fR and
-\&\f(CW\*(C`ev_check\*(C'\fR watchers) as well as file watchers (\f(CW\*(C`ev_stat\*(C'\fR) and even
-limited support for fork events (\f(CW\*(C`ev_fork\*(C'\fR).
-.PP
-It also is quite fast (see this
-<benchmark> comparing it to libevent
-for example).
-.SS "\s-1CONVENTIONS\s0"
-.IX Subsection "CONVENTIONS"
-Libev is very configurable. In this manual the default (and most common)
-configuration will be described, which supports multiple event loops. For
-more info about various configuration options please have a look at
-\&\fB\s-1EMBED\s0\fR section in this manual. If libev was configured without support
-for multiple event loops, then all functions taking an initial argument of
-name \f(CW\*(C`loop\*(C'\fR (which is always of type \f(CW\*(C`struct ev_loop *\*(C'\fR) will not have
-this argument.
-.SS "\s-1TIME\s0 \s-1REPRESENTATION\s0"
-.IX Subsection "TIME REPRESENTATION"
-Libev represents time as a single floating point number, representing
-the (fractional) number of seconds since the (\s-1POSIX\s0) epoch (in practice
-somewhere near the beginning of 1970, details are complicated, don't
-ask). This type is called \f(CW\*(C`ev_tstamp\*(C'\fR, which is what you should use
-too. It usually aliases to the \f(CW\*(C`double\*(C'\fR type in C. When you need to do
-any calculations on it, you should treat it as some floating point value.
-.PP
-Unlike the name component \f(CW\*(C`stamp\*(C'\fR might indicate, it is also used for
-time differences (e.g. delays) throughout libev.
-.SH "ERROR HANDLING"
-.IX Header "ERROR HANDLING"
-Libev knows three classes of errors: operating system errors, usage errors
-and internal errors (bugs).
-.PP
-When libev catches an operating system error it cannot handle (for example
-a system call indicating a condition libev cannot fix), it calls the callback
-set via \f(CW\*(C`ev_set_syserr_cb\*(C'\fR, which is supposed to fix the problem or
-abort. The default is to print a diagnostic message and to call \f(CW\*(C`abort
-()\*(C'\fR.
-.PP
-When libev detects a usage error such as a negative timer interval, then
-it will print a diagnostic message and abort (via the \f(CW\*(C`assert\*(C'\fR mechanism,
-so \f(CW\*(C`NDEBUG\*(C'\fR will disable this checking): these are programming errors in
-the libev caller and need to be fixed there.
-.PP
-Libev also has a few internal error-checking \f(CW\*(C`assert\*(C'\fRions, and also has
-extensive consistency checking code. These do not trigger under normal
-circumstances, as they indicate either a bug in libev or worse.
-.SH "GLOBAL FUNCTIONS"
-.IX Header "GLOBAL FUNCTIONS"
-These functions can be called anytime, even before initialising the
-library in any way.
-.IP "ev_tstamp ev_time ()" 4
-.IX Item "ev_tstamp ev_time ()"
-Returns the current time as libev would use it. Please note that the
-\&\f(CW\*(C`ev_now\*(C'\fR function is usually faster and also often returns the timestamp
-you actually want to know. Also interesting is the combination of
-\&\f(CW\*(C`ev_update_now\*(C'\fR and \f(CW\*(C`ev_now\*(C'\fR.
-.IP "ev_sleep (ev_tstamp interval)" 4
-.IX Item "ev_sleep (ev_tstamp interval)"
-Sleep for the given interval: The current thread will be blocked until
-either it is interrupted or the given time interval has passed. Basically
-this is a sub-second-resolution \f(CW\*(C`sleep ()\*(C'\fR.
-.IP "int ev_version_major ()" 4
-.IX Item "int ev_version_major ()"
-.PD 0
-.IP "int ev_version_minor ()" 4
-.IX Item "int ev_version_minor ()"
-.PD
-You can find out the major and minor \s-1ABI\s0 version numbers of the library
-you linked against by calling the functions \f(CW\*(C`ev_version_major\*(C'\fR and
-\&\f(CW\*(C`ev_version_minor\*(C'\fR. If you want, you can compare against the global
-symbols \f(CW\*(C`EV_VERSION_MAJOR\*(C'\fR and \f(CW\*(C`EV_VERSION_MINOR\*(C'\fR, which specify the
-version of the library your program was compiled against.
-.Sp
-These version numbers refer to the \s-1ABI\s0 version of the library, not the
-release version.
-.Sp
-Usually, it's a good idea to terminate if the major versions mismatch,
-as this indicates an incompatible change. Minor versions are usually
-compatible to older versions, so a larger minor version alone is usually
-not a problem.
-.Sp
-Example: Make sure we haven't accidentally been linked against the wrong
-version (note, however, that this will not detect other \s-1ABI\s0 mismatches,
-such as \s-1LFS\s0 or reentrancy).
-.Sp
-.Vb 3
-\& assert (("libev version mismatch",
-\& ev_version_major () == EV_VERSION_MAJOR
-\& && ev_version_minor () >= EV_VERSION_MINOR));
-.Ve
-.IP "unsigned int ev_supported_backends ()" 4
-.IX Item "unsigned int ev_supported_backends ()"
-Return the set of all backends (i.e. their corresponding \f(CW\*(C`EV_BACKEND_*\*(C'\fR
-value) compiled into this binary of libev (independent of their
-availability on the system you are running on). See \f(CW\*(C`ev_default_loop\*(C'\fR for
-a description of the set values.
-.Sp
-Example: make sure we have the epoll method, because yeah this is cool and
-a must have and can we have a torrent of it please!!!11
-.Sp
-.Vb 2
-\& assert (("sorry, no epoll, no sex",
-\& ev_supported_backends () & EVBACKEND_EPOLL));
-.Ve
-.IP "unsigned int ev_recommended_backends ()" 4
-.IX Item "unsigned int ev_recommended_backends ()"
-Return the set of all backends compiled into this binary of libev and
-also recommended for this platform, meaning it will work for most file
-descriptor types. This set is often smaller than the one returned by
-\&\f(CW\*(C`ev_supported_backends\*(C'\fR, as for example kqueue is broken on most BSDs
-and will not be auto-detected unless you explicitly request it (assuming
-you know what you are doing). This is the set of backends that libev will
-probe for if you specify no backends explicitly.
-.IP "unsigned int ev_embeddable_backends ()" 4
-.IX Item "unsigned int ev_embeddable_backends ()"
-Returns the set of backends that are embeddable in other event loops. This
-value is platform-specific but can include backends not available on the
-current system. To find which embeddable backends might be supported on
-the current system, you would need to look at \f(CW\*(C`ev_embeddable_backends ()
-& ev_supported_backends ()\*(C'\fR, likewise for recommended ones.
-.Sp
-See the description of \f(CW\*(C`ev_embed\*(C'\fR watchers for more info.
-.IP "ev_set_allocator (void *(*cb)(void *ptr, long size))" 4
-.IX Item "ev_set_allocator (void *(*cb)(void *ptr, long size))"
-Sets the allocation function to use (the prototype is similar \- the
-semantics are identical to the \f(CW\*(C`realloc\*(C'\fR C89/SuS/POSIX function). It is
-used to allocate and free memory (no surprises here). If it returns zero
-when memory needs to be allocated (\f(CW\*(C`size != 0\*(C'\fR), the library might abort
-or take some potentially destructive action.
-.Sp
-Since some systems (at least OpenBSD and Darwin) fail to implement
-correct \f(CW\*(C`realloc\*(C'\fR semantics, libev will use a wrapper around the system
-\&\f(CW\*(C`realloc\*(C'\fR and \f(CW\*(C`free\*(C'\fR functions by default.
-.Sp
-You could override this function in high-availability programs to, say,
-free some memory if it cannot allocate memory, to use a special allocator,
-or even to sleep a while and retry until some memory is available.
-.Sp
-Example: Replace the libev allocator with one that waits a bit and then
-retries (example requires a standards-compliant \f(CW\*(C`realloc\*(C'\fR).
-.Sp
-.Vb 6
-\& static void *
-\& persistent_realloc (void *ptr, size_t size)
-\& {
-\& for (;;)
-\& {
-\& void *newptr = realloc (ptr, size);
-\&
-\& if (newptr)
-\& return newptr;
-\&
-\& sleep (60);
-\& }
-\& }
-\&
-\& ...
-\& ev_set_allocator (persistent_realloc);
-.Ve
-.IP "ev_set_syserr_cb (void (*cb)(const char *msg))" 4
-.IX Item "ev_set_syserr_cb (void (*cb)(const char *msg))"
-Set the callback function to call on a retryable system call error (such
-as failed select, poll, epoll_wait). The message is a printable string
-indicating the system call or subsystem causing the problem. If this
-callback is set, then libev will expect it to remedy the situation, no
-matter what, when it returns. That is, libev will generally retry the
-requested operation, or, if the condition doesn't go away, do bad stuff
-(such as abort).
-.Sp
-Example: This is basically the same thing that libev does internally, too.
-.Sp
-.Vb 6
-\& static void
-\& fatal_error (const char *msg)
-\& {
-\& perror (msg);
-\& abort ();
-\& }
-\&
-\& ...
-\& ev_set_syserr_cb (fatal_error);
-.Ve
-.IP "ev_feed_signal (int signum)" 4
-.IX Item "ev_feed_signal (int signum)"
-This function can be used to \*(L"simulate\*(R" a signal receive. It is completely
-safe to call this function at any time, from any context, including signal
-handlers or random threads.
-.Sp
-Its main use is to customise signal handling in your process, especially
-in the presence of threads. For example, you could block signals
-by default in all threads (and specifying \f(CW\*(C`EVFLAG_NOSIGMASK\*(C'\fR when
-creating any loops), and in one thread, use \f(CW\*(C`sigwait\*(C'\fR or any other
-mechanism to wait for signals, then \*(L"deliver\*(R" them to libev by calling
-\&\f(CW\*(C`ev_feed_signal\*(C'\fR.
-.SH "FUNCTIONS CONTROLLING EVENT LOOPS"
-.IX Header "FUNCTIONS CONTROLLING EVENT LOOPS"
-An event loop is described by a \f(CW\*(C`struct ev_loop *\*(C'\fR (the \f(CW\*(C`struct\*(C'\fR is
-\&\fInot\fR optional in this case unless libev 3 compatibility is disabled, as
-libev 3 had an \f(CW\*(C`ev_loop\*(C'\fR function colliding with the struct name).
-.PP
-The library knows two types of such loops, the \fIdefault\fR loop, which
-supports child process events, and dynamically created event loops which
-do not.
-.IP "struct ev_loop *ev_default_loop (unsigned int flags)" 4
-.IX Item "struct ev_loop *ev_default_loop (unsigned int flags)"
-This returns the \*(L"default\*(R" event loop object, which is what you should
-normally use when you just need \*(L"the event loop\*(R". Event loop objects and
-the \f(CW\*(C`flags\*(C'\fR parameter are described in more detail in the entry for
-\&\f(CW\*(C`ev_loop_new\*(C'\fR.
-.Sp
-If the default loop is already initialised then this function simply
-returns it (and ignores the flags. If that is troubling you, check
-\&\f(CW\*(C`ev_backend ()\*(C'\fR afterwards). Otherwise it will create it with the given
-flags, which should almost always be \f(CW0\fR, unless the caller is also the
-one calling \f(CW\*(C`ev_run\*(C'\fR or otherwise qualifies as \*(L"the main program\*(R".
-.Sp
-If you don't know what event loop to use, use the one returned from this
-function (or via the \f(CW\*(C`EV_DEFAULT\*(C'\fR macro).
-.Sp
-Note that this function is \fInot\fR thread-safe, so if you want to use it
-from multiple threads, you have to employ some kind of mutex (note also
-that this case is unlikely, as loops cannot be shared easily between
-threads anyway).
-.Sp
-The default loop is the only loop that can handle \f(CW\*(C`ev_child\*(C'\fR watchers,
-and to do this, it always registers a handler for \f(CW\*(C`SIGCHLD\*(C'\fR. If this is
-a problem for your application you can either create a dynamic loop with
-\&\f(CW\*(C`ev_loop_new\*(C'\fR which doesn't do that, or you can simply overwrite the
-\&\f(CW\*(C`SIGCHLD\*(C'\fR signal handler \fIafter\fR calling \f(CW\*(C`ev_default_init\*(C'\fR.
-.Sp
-Example: This is the most typical usage.
-.Sp
-.Vb 2
-\& if (!ev_default_loop (0))
-\& fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?");
-.Ve
-.Sp
-Example: Restrict libev to the select and poll backends, and do not allow
-environment settings to be taken into account:
-.Sp
-.Vb 1
-\& ev_default_loop (EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV);
-.Ve
-.IP "struct ev_loop *ev_loop_new (unsigned int flags)" 4
-.IX Item "struct ev_loop *ev_loop_new (unsigned int flags)"
-This will create and initialise a new event loop object. If the loop
-could not be initialised, returns false.
-.Sp
-This function is thread-safe, and one common way to use libev with
-threads is indeed to create one loop per thread, and using the default
-loop in the \*(L"main\*(R" or \*(L"initial\*(R" thread.
-.Sp
-The flags argument can be used to specify special behaviour or specific
-backends to use, and is usually specified as \f(CW0\fR (or \f(CW\*(C`EVFLAG_AUTO\*(C'\fR).
-.Sp
-The following flags are supported:
-.RS 4
-.ie n .IP """EVFLAG_AUTO""" 4
-.el .IP "\f(CWEVFLAG_AUTO\fR" 4
-.IX Item "EVFLAG_AUTO"
-The default flags value. Use this if you have no clue (it's the right
-thing, believe me).
-.ie n .IP """EVFLAG_NOENV""" 4
-.el .IP "\f(CWEVFLAG_NOENV\fR" 4
-.IX Item "EVFLAG_NOENV"
-If this flag bit is or'ed into the flag value (or the program runs setuid
-or setgid) then libev will \fInot\fR look at the environment variable
-\&\f(CW\*(C`LIBEV_FLAGS\*(C'\fR. Otherwise (the default), this environment variable will
-override the flags completely if it is found in the environment. This is
-useful to try out specific backends to test their performance, or to work
-around bugs.
-.ie n .IP """EVFLAG_FORKCHECK""" 4
-.el .IP "\f(CWEVFLAG_FORKCHECK\fR" 4
-.IX Item "EVFLAG_FORKCHECK"
-Instead of calling \f(CW\*(C`ev_loop_fork\*(C'\fR manually after a fork, you can also
-make libev check for a fork in each iteration by enabling this flag.
-.Sp
-This works by calling \f(CW\*(C`getpid ()\*(C'\fR on every iteration of the loop,
-and thus this might slow down your event loop if you do a lot of loop
-iterations and little real work, but is usually not noticeable (on my
-GNU/Linux system for example, \f(CW\*(C`getpid\*(C'\fR is actually a simple 5\-insn sequence
-without a system call and thus \fIvery\fR fast, but my GNU/Linux system also has
-\&\f(CW\*(C`pthread_atfork\*(C'\fR which is even faster).
-.Sp
-The big advantage of this flag is that you can forget about fork (and
-forget about forgetting to tell libev about forking) when you use this
-flag.
-.Sp
-This flag setting cannot be overridden or specified in the \f(CW\*(C`LIBEV_FLAGS\*(C'\fR
-environment variable.
-.ie n .IP """EVFLAG_NOINOTIFY""" 4
-.el .IP "\f(CWEVFLAG_NOINOTIFY\fR" 4
-.IX Item "EVFLAG_NOINOTIFY"
-When this flag is specified, then libev will not attempt to use the
-\&\fIinotify\fR \s-1API\s0 for its \f(CW\*(C`ev_stat\*(C'\fR watchers. Apart from debugging and
-testing, this flag can be useful to conserve inotify file descriptors, as
-otherwise each loop using \f(CW\*(C`ev_stat\*(C'\fR watchers consumes one inotify handle.
-.ie n .IP """EVFLAG_SIGNALFD""" 4
-.el .IP "\f(CWEVFLAG_SIGNALFD\fR" 4
-.IX Item "EVFLAG_SIGNALFD"
-When this flag is specified, then libev will attempt to use the
-\&\fIsignalfd\fR \s-1API\s0 for its \f(CW\*(C`ev_signal\*(C'\fR (and \f(CW\*(C`ev_child\*(C'\fR) watchers. This \s-1API\s0
-delivers signals synchronously, which makes it both faster and might make
-it possible to get the queued signal data. It can also simplify signal
-handling with threads, as long as you properly block signals in your
-threads that are not interested in handling them.
-.Sp
-Signalfd will not be used by default as this changes your signal mask, and
-there are a lot of shoddy libraries and programs (glib's threadpool for
-example) that can't properly initialise their signal masks.
-.ie n .IP """EVFLAG_NOSIGMASK""" 4
-.el .IP "\f(CWEVFLAG_NOSIGMASK\fR" 4
-.IX Item "EVFLAG_NOSIGMASK"
-When this flag is specified, then libev will avoid to modify the signal
-mask. Specifically, this means you ahve to make sure signals are unblocked
-when you want to receive them.
-.Sp
-This behaviour is useful when you want to do your own signal handling, or
-want to handle signals only in specific threads and want to avoid libev
-unblocking the signals.
-.Sp
-It's also required by \s-1POSIX\s0 in a threaded program, as libev calls
-\&\f(CW\*(C`sigprocmask\*(C'\fR, whose behaviour is officially unspecified.
-.Sp
-This flag's behaviour will become the default in future versions of libev.
-.ie n .IP """EVBACKEND_SELECT"" (value 1, portable select backend)" 4
-.el .IP "\f(CWEVBACKEND_SELECT\fR (value 1, portable select backend)" 4
-.IX Item "EVBACKEND_SELECT (value 1, portable select backend)"
-This is your standard \fIselect\fR\|(2) backend. Not \fIcompletely\fR standard, as
-libev tries to roll its own fd_set with no limits on the number of fds,
-but if that fails, expect a fairly low limit on the number of fds when
-using this backend. It doesn't scale too well (O(highest_fd)), but its
-usually the fastest backend for a low number of (low-numbered :) fds.
-.Sp
-To get good performance out of this backend you need a high amount of
-parallelism (most of the file descriptors should be busy). If you are
-writing a server, you should \f(CW\*(C`accept ()\*(C'\fR in a loop to accept as many
-connections as possible during one iteration. You might also want to have
-a look at \f(CW\*(C`ev_set_io_collect_interval ()\*(C'\fR to increase the amount of
-readiness notifications you get per iteration.
-.Sp
-This backend maps \f(CW\*(C`EV_READ\*(C'\fR to the \f(CW\*(C`readfds\*(C'\fR set and \f(CW\*(C`EV_WRITE\*(C'\fR to the
-\&\f(CW\*(C`writefds\*(C'\fR set (and to work around Microsoft Windows bugs, also onto the
-\&\f(CW\*(C`exceptfds\*(C'\fR set on that platform).
-.ie n .IP """EVBACKEND_POLL"" (value 2, poll backend, available everywhere except on windows)" 4
-.el .IP "\f(CWEVBACKEND_POLL\fR (value 2, poll backend, available everywhere except on windows)" 4
-.IX Item "EVBACKEND_POLL (value 2, poll backend, available everywhere except on windows)"
-And this is your standard \fIpoll\fR\|(2) backend. It's more complicated
-than select, but handles sparse fds better and has no artificial
-limit on the number of fds you can use (except it will slow down
-considerably with a lot of inactive fds). It scales similarly to select,
-i.e. O(total_fds). See the entry for \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR, above, for
-performance tips.
-.Sp
-This backend maps \f(CW\*(C`EV_READ\*(C'\fR to \f(CW\*(C`POLLIN | POLLERR | POLLHUP\*(C'\fR, and
-\&\f(CW\*(C`EV_WRITE\*(C'\fR to \f(CW\*(C`POLLOUT | POLLERR | POLLHUP\*(C'\fR.
-.ie n .IP """EVBACKEND_EPOLL"" (value 4, Linux)" 4
-.el .IP "\f(CWEVBACKEND_EPOLL\fR (value 4, Linux)" 4
-.IX Item "EVBACKEND_EPOLL (value 4, Linux)"
-Use the linux-specific \fIepoll\fR\|(7) interface (for both pre\- and post\-2.6.9
-kernels).
-.Sp
-For few fds, this backend is a bit little slower than poll and select,
-but it scales phenomenally better. While poll and select usually scale
-like O(total_fds) where n is the total number of fds (or the highest fd),
-epoll scales either O(1) or O(active_fds).
-.Sp
-The epoll mechanism deserves honorable mention as the most misdesigned
-of the more advanced event mechanisms: mere annoyances include silently
-dropping file descriptors, requiring a system call per change per file
-descriptor (and unnecessary guessing of parameters), problems with dup,
-returning before the timeout value, resulting in additional iterations
-(and only giving 5ms accuracy while select on the same platform gives
-0.1ms) and so on. The biggest issue is fork races, however \- if a program
-forks then \fIboth\fR parent and child process have to recreate the epoll
-set, which can take considerable time (one syscall per file descriptor)
-and is of course hard to detect.
-.Sp
-Epoll is also notoriously buggy \- embedding epoll fds \fIshould\fR work, but
-of course \fIdoesn't\fR, and epoll just loves to report events for totally
-\&\fIdifferent\fR file descriptors (even already closed ones, so one cannot
-even remove them from the set) than registered in the set (especially
-on \s-1SMP\s0 systems). Libev tries to counter these spurious notifications by
-employing an additional generation counter and comparing that against the
-events to filter out spurious ones, recreating the set when required. Last
-not least, it also refuses to work with some file descriptors which work
-perfectly fine with \f(CW\*(C`select\*(C'\fR (files, many character devices...).
-.Sp
-Epoll is truly the train wreck analog among event poll mechanisms,
-a frankenpoll, cobbled together in a hurry, no thought to design or
-interaction with others.
-.Sp
-While stopping, setting and starting an I/O watcher in the same iteration
-will result in some caching, there is still a system call per such
-incident (because the same \fIfile descriptor\fR could point to a different
-\&\fIfile description\fR now), so its best to avoid that. Also, \f(CW\*(C`dup ()\*(C'\fR'ed
-file descriptors might not work very well if you register events for both
-file descriptors.
-.Sp
-Best performance from this backend is achieved by not unregistering all
-watchers for a file descriptor until it has been closed, if possible,
-i.e. keep at least one watcher active per fd at all times. Stopping and
-starting a watcher (without re-setting it) also usually doesn't cause
-extra overhead. A fork can both result in spurious notifications as well
-as in libev having to destroy and recreate the epoll object, which can
-take considerable time and thus should be avoided.
-.Sp
-All this means that, in practice, \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR can be as fast or
-faster than epoll for maybe up to a hundred file descriptors, depending on
-the usage. So sad.
-.Sp
-While nominally embeddable in other event loops, this feature is broken in
-all kernel versions tested so far.
-.Sp
-This backend maps \f(CW\*(C`EV_READ\*(C'\fR and \f(CW\*(C`EV_WRITE\*(C'\fR in the same way as
-\&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
-.ie n .IP """EVBACKEND_KQUEUE"" (value 8, most \s-1BSD\s0 clones)" 4
-.el .IP "\f(CWEVBACKEND_KQUEUE\fR (value 8, most \s-1BSD\s0 clones)" 4
-.IX Item "EVBACKEND_KQUEUE (value 8, most BSD clones)"
-Kqueue deserves special mention, as at the time of this writing, it
-was broken on all BSDs except NetBSD (usually it doesn't work reliably
-with anything but sockets and pipes, except on Darwin, where of course
-it's completely useless). Unlike epoll, however, whose brokenness
-is by design, these kqueue bugs can (and eventually will) be fixed
-without \s-1API\s0 changes to existing programs. For this reason it's not being
-\&\*(L"auto-detected\*(R" unless you explicitly specify it in the flags (i.e. using
-\&\f(CW\*(C`EVBACKEND_KQUEUE\*(C'\fR) or libev was compiled on a known-to-be-good (\-enough)
-system like NetBSD.
-.Sp
-You still can embed kqueue into a normal poll or select backend and use it
-only for sockets (after having made sure that sockets work with kqueue on
-the target platform). See \f(CW\*(C`ev_embed\*(C'\fR watchers for more info.
-.Sp
-It scales in the same way as the epoll backend, but the interface to the
-kernel is more efficient (which says nothing about its actual speed, of
-course). While stopping, setting and starting an I/O watcher does never
-cause an extra system call as with \f(CW\*(C`EVBACKEND_EPOLL\*(C'\fR, it still adds up to
-two event changes per incident. Support for \f(CW\*(C`fork ()\*(C'\fR is very bad (but
-sane, unlike epoll) and it drops fds silently in similarly hard-to-detect
-cases
-.Sp
-This backend usually performs well under most conditions.
-.Sp
-While nominally embeddable in other event loops, this doesn't work
-everywhere, so you might need to test for this. And since it is broken
-almost everywhere, you should only use it when you have a lot of sockets
-(for which it usually works), by embedding it into another event loop
-(e.g. \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR (but \f(CW\*(C`poll\*(C'\fR is of course
-also broken on \s-1OS\s0 X)) and, did I mention it, using it only for sockets.
-.Sp
-This backend maps \f(CW\*(C`EV_READ\*(C'\fR into an \f(CW\*(C`EVFILT_READ\*(C'\fR kevent with
-\&\f(CW\*(C`NOTE_EOF\*(C'\fR, and \f(CW\*(C`EV_WRITE\*(C'\fR into an \f(CW\*(C`EVFILT_WRITE\*(C'\fR kevent with
-\&\f(CW\*(C`NOTE_EOF\*(C'\fR.
-.ie n .IP """EVBACKEND_DEVPOLL"" (value 16, Solaris 8)" 4
-.el .IP "\f(CWEVBACKEND_DEVPOLL\fR (value 16, Solaris 8)" 4
-.IX Item "EVBACKEND_DEVPOLL (value 16, Solaris 8)"
-This is not implemented yet (and might never be, unless you send me an
-implementation). According to reports, \f(CW\*(C`/dev/poll\*(C'\fR only supports sockets
-and is not embeddable, which would limit the usefulness of this backend
-immensely.
-.ie n .IP """EVBACKEND_PORT"" (value 32, Solaris 10)" 4
-.el .IP "\f(CWEVBACKEND_PORT\fR (value 32, Solaris 10)" 4
-.IX Item "EVBACKEND_PORT (value 32, Solaris 10)"
-This uses the Solaris 10 event port mechanism. As with everything on Solaris,
-it's really slow, but it still scales very well (O(active_fds)).
-.Sp
-While this backend scales well, it requires one system call per active
-file descriptor per loop iteration. For small and medium numbers of file
-descriptors a \*(L"slow\*(R" \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR backend
-might perform better.
-.Sp
-On the positive side, this backend actually performed fully to
-specification in all tests and is fully embeddable, which is a rare feat
-among the OS-specific backends (I vastly prefer correctness over speed
-hacks).
-.Sp
-On the negative side, the interface is \fIbizarre\fR \- so bizarre that
-even sun itself gets it wrong in their code examples: The event polling
-function sometimes returning events to the caller even though an error
-occurred, but with no indication whether it has done so or not (yes, it's
-even documented that way) \- deadly for edge-triggered interfaces where
-you absolutely have to know whether an event occurred or not because you
-have to re-arm the watcher.
-.Sp
-Fortunately libev seems to be able to work around these idiocies.
-.Sp
-This backend maps \f(CW\*(C`EV_READ\*(C'\fR and \f(CW\*(C`EV_WRITE\*(C'\fR in the same way as
-\&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
-.ie n .IP """EVBACKEND_ALL""" 4
-.el .IP "\f(CWEVBACKEND_ALL\fR" 4
-.IX Item "EVBACKEND_ALL"
-Try all backends (even potentially broken ones that wouldn't be tried
-with \f(CW\*(C`EVFLAG_AUTO\*(C'\fR). Since this is a mask, you can do stuff such as
-\&\f(CW\*(C`EVBACKEND_ALL & ~EVBACKEND_KQUEUE\*(C'\fR.
-.Sp
-It is definitely not recommended to use this flag, use whatever
-\&\f(CW\*(C`ev_recommended_backends ()\*(C'\fR returns, or simply do not specify a backend
-at all.
-.ie n .IP """EVBACKEND_MASK""" 4
-.el .IP "\f(CWEVBACKEND_MASK\fR" 4
-.IX Item "EVBACKEND_MASK"
-Not a backend at all, but a mask to select all backend bits from a
-\&\f(CW\*(C`flags\*(C'\fR value, in case you want to mask out any backends from a flags
-value (e.g. when modifying the \f(CW\*(C`LIBEV_FLAGS\*(C'\fR environment variable).
-.RE
-.RS 4
-.Sp
-If one or more of the backend flags are or'ed into the flags value,
-then only these backends will be tried (in the reverse order as listed
-here). If none are specified, all backends in \f(CW\*(C`ev_recommended_backends
-()\*(C'\fR will be tried.
-.Sp
-Example: Try to create a event loop that uses epoll and nothing else.
-.Sp
-.Vb 3
-\& struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV);
-\& if (!epoller)
-\& fatal ("no epoll found here, maybe it hides under your chair");
-.Ve
-.Sp
-Example: Use whatever libev has to offer, but make sure that kqueue is
-used if available.
-.Sp
-.Vb 1
-\& struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_KQUEUE);
-.Ve
-.RE
-.IP "ev_loop_destroy (loop)" 4
-.IX Item "ev_loop_destroy (loop)"
-Destroys an event loop object (frees all memory and kernel state
-etc.). None of the active event watchers will be stopped in the normal
-sense, so e.g. \f(CW\*(C`ev_is_active\*(C'\fR might still return true. It is your
-responsibility to either stop all watchers cleanly yourself \fIbefore\fR
-calling this function, or cope with the fact afterwards (which is usually
-the easiest thing, you can just ignore the watchers and/or \f(CW\*(C`free ()\*(C'\fR them
-for example).
-.Sp
-Note that certain global state, such as signal state (and installed signal
-handlers), will not be freed by this function, and related watchers (such
-as signal and child watchers) would need to be stopped manually.
-.Sp
-This function is normally used on loop objects allocated by
-\&\f(CW\*(C`ev_loop_new\*(C'\fR, but it can also be used on the default loop returned by
-\&\f(CW\*(C`ev_default_loop\*(C'\fR, in which case it is not thread-safe.
-.Sp
-Note that it is not advisable to call this function on the default loop
-except in the rare occasion where you really need to free its resources.
-If you need dynamically allocated loops it is better to use \f(CW\*(C`ev_loop_new\*(C'\fR
-and \f(CW\*(C`ev_loop_destroy\*(C'\fR.
-.IP "ev_loop_fork (loop)" 4
-.IX Item "ev_loop_fork (loop)"
-This function sets a flag that causes subsequent \f(CW\*(C`ev_run\*(C'\fR iterations to
-reinitialise the kernel state for backends that have one. Despite the
-name, you can call it anytime, but it makes most sense after forking, in
-the child process. You \fImust\fR call it (or use \f(CW\*(C`EVFLAG_FORKCHECK\*(C'\fR) in the
-child before resuming or calling \f(CW\*(C`ev_run\*(C'\fR.
-.Sp
-Again, you \fIhave\fR to call it on \fIany\fR loop that you want to re-use after
-a fork, \fIeven if you do not plan to use the loop in the parent\fR. This is
-because some kernel interfaces *cough* \fIkqueue\fR *cough* do funny things
-during fork.
-.Sp
-On the other hand, you only need to call this function in the child
-process if and only if you want to use the event loop in the child. If
-you just fork+exec or create a new loop in the child, you don't have to
-call it at all (in fact, \f(CW\*(C`epoll\*(C'\fR is so badly broken that it makes a
-difference, but libev will usually detect this case on its own and do a
-costly reset of the backend).
-.Sp
-The function itself is quite fast and it's usually not a problem to call
-it just in case after a fork.
-.Sp
-Example: Automate calling \f(CW\*(C`ev_loop_fork\*(C'\fR on the default loop when
-using pthreads.
-.Sp
-.Vb 5
-\& static void
-\& post_fork_child (void)
-\& {
-\& ev_loop_fork (EV_DEFAULT);
-\& }
-\&
-\& ...
-\& pthread_atfork (0, 0, post_fork_child);
-.Ve
-.IP "int ev_is_default_loop (loop)" 4
-.IX Item "int ev_is_default_loop (loop)"
-Returns true when the given loop is, in fact, the default loop, and false
-otherwise.
-.IP "unsigned int ev_iteration (loop)" 4
-.IX Item "unsigned int ev_iteration (loop)"
-Returns the current iteration count for the event loop, which is identical
-to the number of times libev did poll for new events. It starts at \f(CW0\fR
-and happily wraps around with enough iterations.
-.Sp
-This value can sometimes be useful as a generation counter of sorts (it
-\&\*(L"ticks\*(R" the number of loop iterations), as it roughly corresponds with
-\&\f(CW\*(C`ev_prepare\*(C'\fR and \f(CW\*(C`ev_check\*(C'\fR calls \- and is incremented between the
-prepare and check phases.
-.IP "unsigned int ev_depth (loop)" 4
-.IX Item "unsigned int ev_depth (loop)"
-Returns the number of times \f(CW\*(C`ev_run\*(C'\fR was entered minus the number of
-times \f(CW\*(C`ev_run\*(C'\fR was exited normally, in other words, the recursion depth.
-.Sp
-Outside \f(CW\*(C`ev_run\*(C'\fR, this number is zero. In a callback, this number is
-\&\f(CW1\fR, unless \f(CW\*(C`ev_run\*(C'\fR was invoked recursively (or from another thread),
-in which case it is higher.
-.Sp
-Leaving \f(CW\*(C`ev_run\*(C'\fR abnormally (setjmp/longjmp, cancelling the thread,
-throwing an exception etc.), doesn't count as \*(L"exit\*(R" \- consider this
-as a hint to avoid such ungentleman-like behaviour unless it's really
-convenient, in which case it is fully supported.
-.IP "unsigned int ev_backend (loop)" 4
-.IX Item "unsigned int ev_backend (loop)"
-Returns one of the \f(CW\*(C`EVBACKEND_*\*(C'\fR flags indicating the event backend in
-use.
-.IP "ev_tstamp ev_now (loop)" 4
-.IX Item "ev_tstamp ev_now (loop)"
-Returns the current \*(L"event loop time\*(R", which is the time the event loop
-received events and started processing them. This timestamp does not
-change as long as callbacks are being processed, and this is also the base
-time used for relative timers. You can treat it as the timestamp of the
-event occurring (or more correctly, libev finding out about it).
-.IP "ev_now_update (loop)" 4
-.IX Item "ev_now_update (loop)"
-Establishes the current time by querying the kernel, updating the time
-returned by \f(CW\*(C`ev_now ()\*(C'\fR in the progress. This is a costly operation and
-is usually done automatically within \f(CW\*(C`ev_run ()\*(C'\fR.
-.Sp
-This function is rarely useful, but when some event callback runs for a
-very long time without entering the event loop, updating libev's idea of
-the current time is a good idea.
-.Sp
-See also \*(L"The special problem of time updates\*(R" in the \f(CW\*(C`ev_timer\*(C'\fR section.
-.IP "ev_suspend (loop)" 4
-.IX Item "ev_suspend (loop)"
-.PD 0
-.IP "ev_resume (loop)" 4
-.IX Item "ev_resume (loop)"
-.PD
-These two functions suspend and resume an event loop, for use when the
-loop is not used for a while and timeouts should not be processed.
-.Sp
-A typical use case would be an interactive program such as a game: When
-the user presses \f(CW\*(C`^Z\*(C'\fR to suspend the game and resumes it an hour later it
-would be best to handle timeouts as if no time had actually passed while
-the program was suspended. This can be achieved by calling \f(CW\*(C`ev_suspend\*(C'\fR
-in your \f(CW\*(C`SIGTSTP\*(C'\fR handler, sending yourself a \f(CW\*(C`SIGSTOP\*(C'\fR and calling
-\&\f(CW\*(C`ev_resume\*(C'\fR directly afterwards to resume timer processing.
-.Sp
-Effectively, all \f(CW\*(C`ev_timer\*(C'\fR watchers will be delayed by the time spend
-between \f(CW\*(C`ev_suspend\*(C'\fR and \f(CW\*(C`ev_resume\*(C'\fR, and all \f(CW\*(C`ev_periodic\*(C'\fR watchers
-will be rescheduled (that is, they will lose any events that would have
-occurred while suspended).
-.Sp
-After calling \f(CW\*(C`ev_suspend\*(C'\fR you \fBmust not\fR call \fIany\fR function on the
-given loop other than \f(CW\*(C`ev_resume\*(C'\fR, and you \fBmust not\fR call \f(CW\*(C`ev_resume\*(C'\fR
-without a previous call to \f(CW\*(C`ev_suspend\*(C'\fR.
-.Sp
-Calling \f(CW\*(C`ev_suspend\*(C'\fR/\f(CW\*(C`ev_resume\*(C'\fR has the side effect of updating the
-event loop time (see \f(CW\*(C`ev_now_update\*(C'\fR).
-.IP "ev_run (loop, int flags)" 4
-.IX Item "ev_run (loop, int flags)"
-Finally, this is it, the event handler. This function usually is called
-after you have initialised all your watchers and you want to start
-handling events. It will ask the operating system for any new events, call
-the watcher callbacks, an then repeat the whole process indefinitely: This
-is why event loops are called \fIloops\fR.
-.Sp
-If the flags argument is specified as \f(CW0\fR, it will keep handling events
-until either no event watchers are active anymore or \f(CW\*(C`ev_break\*(C'\fR was
-called.
-.Sp
-Please note that an explicit \f(CW\*(C`ev_break\*(C'\fR is usually better than
-relying on all watchers to be stopped when deciding when a program has
-finished (especially in interactive programs), but having a program
-that automatically loops as long as it has to and no longer by virtue
-of relying on its watchers stopping correctly, that is truly a thing of
-beauty.
-.Sp
-This function is also \fImostly\fR exception-safe \- you can break out of
-a \f(CW\*(C`ev_run\*(C'\fR call by calling \f(CW\*(C`longjmp\*(C'\fR in a callback, throwing a \*(C+
-exception and so on. This does not decrement the \f(CW\*(C`ev_depth\*(C'\fR value, nor
-will it clear any outstanding \f(CW\*(C`EVBREAK_ONE\*(C'\fR breaks.
-.Sp
-A flags value of \f(CW\*(C`EVRUN_NOWAIT\*(C'\fR will look for new events, will handle
-those events and any already outstanding ones, but will not wait and
-block your process in case there are no events and will return after one
-iteration of the loop. This is sometimes useful to poll and handle new
-events while doing lengthy calculations, to keep the program responsive.
-.Sp
-A flags value of \f(CW\*(C`EVRUN_ONCE\*(C'\fR will look for new events (waiting if
-necessary) and will handle those and any already outstanding ones. It
-will block your process until at least one new event arrives (which could
-be an event internal to libev itself, so there is no guarantee that a
-user-registered callback will be called), and will return after one
-iteration of the loop.
-.Sp
-This is useful if you are waiting for some external event in conjunction
-with something not expressible using other libev watchers (i.e. "roll your
-own \f(CW\*(C`ev_run\*(C'\fR"). However, a pair of \f(CW\*(C`ev_prepare\*(C'\fR/\f(CW\*(C`ev_check\*(C'\fR watchers is
-usually a better approach for this kind of thing.
-.Sp
-Here are the gory details of what \f(CW\*(C`ev_run\*(C'\fR does:
-.Sp
-.Vb 10
-\& \- Increment loop depth.
-\& \- Reset the ev_break status.
-\& \- Before the first iteration, call any pending watchers.
-\& LOOP:
-\& \- If EVFLAG_FORKCHECK was used, check for a fork.
-\& \- If a fork was detected (by any means), queue and call all fork watchers.
-\& \- Queue and call all prepare watchers.
-\& \- If ev_break was called, goto FINISH.
-\& \- If we have been forked, detach and recreate the kernel state
-\& as to not disturb the other process.
-\& \- Update the kernel state with all outstanding changes.
-\& \- Update the "event loop time" (ev_now ()).
-\& \- Calculate for how long to sleep or block, if at all
-\& (active idle watchers, EVRUN_NOWAIT or not having
-\& any active watchers at all will result in not sleeping).
-\& \- Sleep if the I/O and timer collect interval say so.
-\& \- Increment loop iteration counter.
-\& \- Block the process, waiting for any events.
-\& \- Queue all outstanding I/O (fd) events.
-\& \- Update the "event loop time" (ev_now ()), and do time jump adjustments.
-\& \- Queue all expired timers.
-\& \- Queue all expired periodics.
-\& \- Queue all idle watchers with priority higher than that of pending events.
-\& \- Queue all check watchers.
-\& \- Call all queued watchers in reverse order (i.e. check watchers first).
-\& Signals and child watchers are implemented as I/O watchers, and will
-\& be handled here by queueing them when their watcher gets executed.
-\& \- If ev_break has been called, or EVRUN_ONCE or EVRUN_NOWAIT
-\& were used, or there are no active watchers, goto FINISH, otherwise
-\& continue with step LOOP.
-\& FINISH:
-\& \- Reset the ev_break status iff it was EVBREAK_ONE.
-\& \- Decrement the loop depth.
-\& \- Return.
-.Ve
-.Sp
-Example: Queue some jobs and then loop until no events are outstanding
-anymore.
-.Sp
-.Vb 4
-\& ... queue jobs here, make sure they register event watchers as long
-\& ... as they still have work to do (even an idle watcher will do..)
-\& ev_run (my_loop, 0);
-\& ... jobs done or somebody called break. yeah!
-.Ve
-.IP "ev_break (loop, how)" 4
-.IX Item "ev_break (loop, how)"
-Can be used to make a call to \f(CW\*(C`ev_run\*(C'\fR return early (but only after it
-has processed all outstanding events). The \f(CW\*(C`how\*(C'\fR argument must be either
-\&\f(CW\*(C`EVBREAK_ONE\*(C'\fR, which will make the innermost \f(CW\*(C`ev_run\*(C'\fR call return, or
-\&\f(CW\*(C`EVBREAK_ALL\*(C'\fR, which will make all nested \f(CW\*(C`ev_run\*(C'\fR calls return.
-.Sp
-This \*(L"break state\*(R" will be cleared on the next call to \f(CW\*(C`ev_run\*(C'\fR.
-.Sp
-It is safe to call \f(CW\*(C`ev_break\*(C'\fR from outside any \f(CW\*(C`ev_run\*(C'\fR calls, too, in
-which case it will have no effect.
-.IP "ev_ref (loop)" 4
-.IX Item "ev_ref (loop)"
-.PD 0
-.IP "ev_unref (loop)" 4
-.IX Item "ev_unref (loop)"
-.PD
-Ref/unref can be used to add or remove a reference count on the event
-loop: Every watcher keeps one reference, and as long as the reference
-count is nonzero, \f(CW\*(C`ev_run\*(C'\fR will not return on its own.
-.Sp
-This is useful when you have a watcher that you never intend to
-unregister, but that nevertheless should not keep \f(CW\*(C`ev_run\*(C'\fR from
-returning. In such a case, call \f(CW\*(C`ev_unref\*(C'\fR after starting, and \f(CW\*(C`ev_ref\*(C'\fR
-before stopping it.
-.Sp
-As an example, libev itself uses this for its internal signal pipe: It
-is not visible to the libev user and should not keep \f(CW\*(C`ev_run\*(C'\fR from
-exiting if no event watchers registered by it are active. It is also an
-excellent way to do this for generic recurring timers or from within
-third-party libraries. Just remember to \fIunref after start\fR and \fIref
-before stop\fR (but only if the watcher wasn't active before, or was active
-before, respectively. Note also that libev might stop watchers itself
-(e.g. non-repeating timers) in which case you have to \f(CW\*(C`ev_ref\*(C'\fR
-in the callback).
-.Sp
-Example: Create a signal watcher, but keep it from keeping \f(CW\*(C`ev_run\*(C'\fR
-running when nothing else is active.
-.Sp
-.Vb 4
-\& ev_signal exitsig;
-\& ev_signal_init (&exitsig, sig_cb, SIGINT);
-\& ev_signal_start (loop, &exitsig);
-\& ev_unref (loop);
-.Ve
-.Sp
-Example: For some weird reason, unregister the above signal handler again.
-.Sp
-.Vb 2
-\& ev_ref (loop);
-\& ev_signal_stop (loop, &exitsig);
-.Ve
-.IP "ev_set_io_collect_interval (loop, ev_tstamp interval)" 4
-.IX Item "ev_set_io_collect_interval (loop, ev_tstamp interval)"
-.PD 0
-.IP "ev_set_timeout_collect_interval (loop, ev_tstamp interval)" 4
-.IX Item "ev_set_timeout_collect_interval (loop, ev_tstamp interval)"
-.PD
-These advanced functions influence the time that libev will spend waiting
-for events. Both time intervals are by default \f(CW0\fR, meaning that libev
-will try to invoke timer/periodic callbacks and I/O callbacks with minimum
-latency.
-.Sp
-Setting these to a higher value (the \f(CW\*(C`interval\*(C'\fR \fImust\fR be >= \f(CW0\fR)
-allows libev to delay invocation of I/O and timer/periodic callbacks
-to increase efficiency of loop iterations (or to increase power-saving
-opportunities).
-.Sp
-The idea is that sometimes your program runs just fast enough to handle
-one (or very few) event(s) per loop iteration. While this makes the
-program responsive, it also wastes a lot of \s-1CPU\s0 time to poll for new
-events, especially with backends like \f(CW\*(C`select ()\*(C'\fR which have a high
-overhead for the actual polling but can deliver many events at once.
-.Sp
-By setting a higher \fIio collect interval\fR you allow libev to spend more
-time collecting I/O events, so you can handle more events per iteration,
-at the cost of increasing latency. Timeouts (both \f(CW\*(C`ev_periodic\*(C'\fR and
-\&\f(CW\*(C`ev_timer\*(C'\fR) will be not affected. Setting this to a non-null value will
-introduce an additional \f(CW\*(C`ev_sleep ()\*(C'\fR call into most loop iterations. The
-sleep time ensures that libev will not poll for I/O events more often then
-once per this interval, on average.
-.Sp
-Likewise, by setting a higher \fItimeout collect interval\fR you allow libev
-to spend more time collecting timeouts, at the expense of increased
-latency/jitter/inexactness (the watcher callback will be called
-later). \f(CW\*(C`ev_io\*(C'\fR watchers will not be affected. Setting this to a non-null
-value will not introduce any overhead in libev.
-.Sp
-Many (busy) programs can usually benefit by setting the I/O collect
-interval to a value near \f(CW0.1\fR or so, which is often enough for
-interactive servers (of course not for games), likewise for timeouts. It
-usually doesn't make much sense to set it to a lower value than \f(CW0.01\fR,
-as this approaches the timing granularity of most systems. Note that if
-you do transactions with the outside world and you can't increase the
-parallelity, then this setting will limit your transaction rate (if you
-need to poll once per transaction and the I/O collect interval is 0.01,
-then you can't do more than 100 transactions per second).
-.Sp
-Setting the \fItimeout collect interval\fR can improve the opportunity for
-saving power, as the program will \*(L"bundle\*(R" timer callback invocations that
-are \*(L"near\*(R" in time together, by delaying some, thus reducing the number of
-times the process sleeps and wakes up again. Another useful technique to
-reduce iterations/wake\-ups is to use \f(CW\*(C`ev_periodic\*(C'\fR watchers and make sure
-they fire on, say, one-second boundaries only.
-.Sp
-Example: we only need 0.1s timeout granularity, and we wish not to poll
-more often than 100 times per second:
-.Sp
-.Vb 2
-\& ev_set_timeout_collect_interval (EV_DEFAULT_UC_ 0.1);
-\& ev_set_io_collect_interval (EV_DEFAULT_UC_ 0.01);
-.Ve
-.IP "ev_invoke_pending (loop)" 4
-.IX Item "ev_invoke_pending (loop)"
-This call will simply invoke all pending watchers while resetting their
-pending state. Normally, \f(CW\*(C`ev_run\*(C'\fR does this automatically when required,
-but when overriding the invoke callback this call comes handy. This
-function can be invoked from a watcher \- this can be useful for example
-when you want to do some lengthy calculation and want to pass further
-event handling to another thread (you still have to make sure only one
-thread executes within \f(CW\*(C`ev_invoke_pending\*(C'\fR or \f(CW\*(C`ev_run\*(C'\fR of course).
-.IP "int ev_pending_count (loop)" 4
-.IX Item "int ev_pending_count (loop)"
-Returns the number of pending watchers \- zero indicates that no watchers
-are pending.
-.IP "ev_set_invoke_pending_cb (loop, void (*invoke_pending_cb)(\s-1EV_P\s0))" 4
-.IX Item "ev_set_invoke_pending_cb (loop, void (*invoke_pending_cb)(EV_P))"
-This overrides the invoke pending functionality of the loop: Instead of
-invoking all pending watchers when there are any, \f(CW\*(C`ev_run\*(C'\fR will call
-this callback instead. This is useful, for example, when you want to
-invoke the actual watchers inside another context (another thread etc.).
-.Sp
-If you want to reset the callback, use \f(CW\*(C`ev_invoke_pending\*(C'\fR as new
-callback.
-.IP "ev_set_loop_release_cb (loop, void (*release)(\s-1EV_P\s0), void (*acquire)(\s-1EV_P\s0))" 4
-.IX Item "ev_set_loop_release_cb (loop, void (*release)(EV_P), void (*acquire)(EV_P))"
-Sometimes you want to share the same loop between multiple threads. This
-can be done relatively simply by putting mutex_lock/unlock calls around
-each call to a libev function.
-.Sp
-However, \f(CW\*(C`ev_run\*(C'\fR can run an indefinite time, so it is not feasible
-to wait for it to return. One way around this is to wake up the event
-loop via \f(CW\*(C`ev_break\*(C'\fR and \f(CW\*(C`av_async_send\*(C'\fR, another way is to set these
-\&\fIrelease\fR and \fIacquire\fR callbacks on the loop.
-.Sp
-When set, then \f(CW\*(C`release\*(C'\fR will be called just before the thread is
-suspended waiting for new events, and \f(CW\*(C`acquire\*(C'\fR is called just
-afterwards.
-.Sp
-Ideally, \f(CW\*(C`release\*(C'\fR will just call your mutex_unlock function, and
-\&\f(CW\*(C`acquire\*(C'\fR will just call the mutex_lock function again.
-.Sp
-While event loop modifications are allowed between invocations of
-\&\f(CW\*(C`release\*(C'\fR and \f(CW\*(C`acquire\*(C'\fR (that's their only purpose after all), no
-modifications done will affect the event loop, i.e. adding watchers will
-have no effect on the set of file descriptors being watched, or the time
-waited. Use an \f(CW\*(C`ev_async\*(C'\fR watcher to wake up \f(CW\*(C`ev_run\*(C'\fR when you want it
-to take note of any changes you made.
-.Sp
-In theory, threads executing \f(CW\*(C`ev_run\*(C'\fR will be async-cancel safe between
-invocations of \f(CW\*(C`release\*(C'\fR and \f(CW\*(C`acquire\*(C'\fR.
-.Sp
-See also the locking example in the \f(CW\*(C`THREADS\*(C'\fR section later in this
-document.
-.IP "ev_set_userdata (loop, void *data)" 4
-.IX Item "ev_set_userdata (loop, void *data)"
-.PD 0
-.IP "void *ev_userdata (loop)" 4
-.IX Item "void *ev_userdata (loop)"
-.PD
-Set and retrieve a single \f(CW\*(C`void *\*(C'\fR associated with a loop. When
-\&\f(CW\*(C`ev_set_userdata\*(C'\fR has never been called, then \f(CW\*(C`ev_userdata\*(C'\fR returns
-\&\f(CW0\fR.
-.Sp
-These two functions can be used to associate arbitrary data with a loop,
-and are intended solely for the \f(CW\*(C`invoke_pending_cb\*(C'\fR, \f(CW\*(C`release\*(C'\fR and
-\&\f(CW\*(C`acquire\*(C'\fR callbacks described above, but of course can be (ab\-)used for
-any other purpose as well.
-.IP "ev_verify (loop)" 4
-.IX Item "ev_verify (loop)"
-This function only does something when \f(CW\*(C`EV_VERIFY\*(C'\fR support has been
-compiled in, which is the default for non-minimal builds. It tries to go
-through all internal structures and checks them for validity. If anything
-is found to be inconsistent, it will print an error message to standard
-error and call \f(CW\*(C`abort ()\*(C'\fR.
-.Sp
-This can be used to catch bugs inside libev itself: under normal
-circumstances, this function will never abort as of course libev keeps its
-data structures consistent.
-.SH "ANATOMY OF A WATCHER"
-.IX Header "ANATOMY OF A WATCHER"
-In the following description, uppercase \f(CW\*(C`TYPE\*(C'\fR in names stands for the
-watcher type, e.g. \f(CW\*(C`ev_TYPE_start\*(C'\fR can mean \f(CW\*(C`ev_timer_start\*(C'\fR for timer
-watchers and \f(CW\*(C`ev_io_start\*(C'\fR for I/O watchers.
-.PP
-A watcher is an opaque structure that you allocate and register to record
-your interest in some event. To make a concrete example, imagine you want
-to wait for \s-1STDIN\s0 to become readable, you would create an \f(CW\*(C`ev_io\*(C'\fR watcher
-for that:
-.PP
-.Vb 5
-\& static void my_cb (struct ev_loop *loop, ev_io *w, int revents)
-\& {
-\& ev_io_stop (w);
-\& ev_break (loop, EVBREAK_ALL);
-\& }
-\&
-\& struct ev_loop *loop = ev_default_loop (0);
-\&
-\& ev_io stdin_watcher;
-\&
-\& ev_init (&stdin_watcher, my_cb);
-\& ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ);
-\& ev_io_start (loop, &stdin_watcher);
-\&
-\& ev_run (loop, 0);
-.Ve
-.PP
-As you can see, you are responsible for allocating the memory for your
-watcher structures (and it is \fIusually\fR a bad idea to do this on the
-stack).
-.PP
-Each watcher has an associated watcher structure (called \f(CW\*(C`struct ev_TYPE\*(C'\fR
-or simply \f(CW\*(C`ev_TYPE\*(C'\fR, as typedefs are provided for all watcher structs).
-.PP
-Each watcher structure must be initialised by a call to \f(CW\*(C`ev_init (watcher
-*, callback)\*(C'\fR, which expects a callback to be provided. This callback is
-invoked each time the event occurs (or, in the case of I/O watchers, each
-time the event loop detects that the file descriptor given is readable
-and/or writable).
-.PP
-Each watcher type further has its own \f(CW\*(C`ev_TYPE_set (watcher *, ...)\*(C'\fR
-macro to configure it, with arguments specific to the watcher type. There
-is also a macro to combine initialisation and setting in one call: \f(CW\*(C`ev_TYPE_init (watcher *, callback, ...)\*(C'\fR.
-.PP
-To make the watcher actually watch out for events, you have to start it
-with a watcher-specific start function (\f(CW\*(C`ev_TYPE_start (loop, watcher
-*)\*(C'\fR), and you can stop watching for events at any time by calling the
-corresponding stop function (\f(CW\*(C`ev_TYPE_stop (loop, watcher *)\*(C'\fR.
-.PP
-As long as your watcher is active (has been started but not stopped) you
-must not touch the values stored in it. Most specifically you must never
-reinitialise it or call its \f(CW\*(C`ev_TYPE_set\*(C'\fR macro.
-.PP
-Each and every callback receives the event loop pointer as first, the
-registered watcher structure as second, and a bitset of received events as
-third argument.
-.PP
-The received events usually include a single bit per event type received
-(you can receive multiple events at the same time). The possible bit masks
-are:
-.ie n .IP """EV_READ""" 4
-.el .IP "\f(CWEV_READ\fR" 4
-.IX Item "EV_READ"
-.PD 0
-.ie n .IP """EV_WRITE""" 4
-.el .IP "\f(CWEV_WRITE\fR" 4
-.IX Item "EV_WRITE"
-.PD
-The file descriptor in the \f(CW\*(C`ev_io\*(C'\fR watcher has become readable and/or
-writable.
-.ie n .IP """EV_TIMER""" 4
-.el .IP "\f(CWEV_TIMER\fR" 4
-.IX Item "EV_TIMER"
-The \f(CW\*(C`ev_timer\*(C'\fR watcher has timed out.
-.ie n .IP """EV_PERIODIC""" 4
-.el .IP "\f(CWEV_PERIODIC\fR" 4
-.IX Item "EV_PERIODIC"
-The \f(CW\*(C`ev_periodic\*(C'\fR watcher has timed out.
-.ie n .IP """EV_SIGNAL""" 4
-.el .IP "\f(CWEV_SIGNAL\fR" 4
-.IX Item "EV_SIGNAL"
-The signal specified in the \f(CW\*(C`ev_signal\*(C'\fR watcher has been received by a thread.
-.ie n .IP """EV_CHILD""" 4
-.el .IP "\f(CWEV_CHILD\fR" 4
-.IX Item "EV_CHILD"
-The pid specified in the \f(CW\*(C`ev_child\*(C'\fR watcher has received a status change.
-.ie n .IP """EV_STAT""" 4
-.el .IP "\f(CWEV_STAT\fR" 4
-.IX Item "EV_STAT"
-The path specified in the \f(CW\*(C`ev_stat\*(C'\fR watcher changed its attributes somehow.
-.ie n .IP """EV_IDLE""" 4
-.el .IP "\f(CWEV_IDLE\fR" 4
-.IX Item "EV_IDLE"
-The \f(CW\*(C`ev_idle\*(C'\fR watcher has determined that you have nothing better to do.
-.ie n .IP """EV_PREPARE""" 4
-.el .IP "\f(CWEV_PREPARE\fR" 4
-.IX Item "EV_PREPARE"
-.PD 0
-.ie n .IP """EV_CHECK""" 4
-.el .IP "\f(CWEV_CHECK\fR" 4
-.IX Item "EV_CHECK"
-.PD
-All \f(CW\*(C`ev_prepare\*(C'\fR watchers are invoked just \fIbefore\fR \f(CW\*(C`ev_run\*(C'\fR starts
-to gather new events, and all \f(CW\*(C`ev_check\*(C'\fR watchers are invoked just after
-\&\f(CW\*(C`ev_run\*(C'\fR has gathered them, but before it invokes any callbacks for any
-received events. Callbacks of both watcher types can start and stop as
-many watchers as they want, and all of them will be taken into account
-(for example, a \f(CW\*(C`ev_prepare\*(C'\fR watcher might start an idle watcher to keep
-\&\f(CW\*(C`ev_run\*(C'\fR from blocking).
-.ie n .IP """EV_EMBED""" 4
-.el .IP "\f(CWEV_EMBED\fR" 4
-.IX Item "EV_EMBED"
-The embedded event loop specified in the \f(CW\*(C`ev_embed\*(C'\fR watcher needs attention.
-.ie n .IP """EV_FORK""" 4
-.el .IP "\f(CWEV_FORK\fR" 4
-.IX Item "EV_FORK"
-The event loop has been resumed in the child process after fork (see
-\&\f(CW\*(C`ev_fork\*(C'\fR).
-.ie n .IP """EV_CLEANUP""" 4
-.el .IP "\f(CWEV_CLEANUP\fR" 4
-.IX Item "EV_CLEANUP"
-The event loop is about to be destroyed (see \f(CW\*(C`ev_cleanup\*(C'\fR).
-.ie n .IP """EV_ASYNC""" 4
-.el .IP "\f(CWEV_ASYNC\fR" 4
-.IX Item "EV_ASYNC"
-The given async watcher has been asynchronously notified (see \f(CW\*(C`ev_async\*(C'\fR).
-.ie n .IP """EV_CUSTOM""" 4
-.el .IP "\f(CWEV_CUSTOM\fR" 4
-.IX Item "EV_CUSTOM"
-Not ever sent (or otherwise used) by libev itself, but can be freely used
-by libev users to signal watchers (e.g. via \f(CW\*(C`ev_feed_event\*(C'\fR).
-.ie n .IP """EV_ERROR""" 4
-.el .IP "\f(CWEV_ERROR\fR" 4
-.IX Item "EV_ERROR"
-An unspecified error has occurred, the watcher has been stopped. This might
-happen because the watcher could not be properly started because libev
-ran out of memory, a file descriptor was found to be closed or any other
-problem. Libev considers these application bugs.
-.Sp
-You best act on it by reporting the problem and somehow coping with the
-watcher being stopped. Note that well-written programs should not receive
-an error ever, so when your watcher receives it, this usually indicates a
-bug in your program.
-.Sp
-Libev will usually signal a few \*(L"dummy\*(R" events together with an error, for
-example it might indicate that a fd is readable or writable, and if your
-callbacks is well-written it can just attempt the operation and cope with
-the error from \fIread()\fR or \fIwrite()\fR. This will not work in multi-threaded
-programs, though, as the fd could already be closed and reused for another
-thing, so beware.
-.SS "\s-1GENERIC\s0 \s-1WATCHER\s0 \s-1FUNCTIONS\s0"
-.IX Subsection "GENERIC WATCHER FUNCTIONS"
-.ie n .IP """ev_init"" (ev_TYPE *watcher, callback)" 4
-.el .IP "\f(CWev_init\fR (ev_TYPE *watcher, callback)" 4
-.IX Item "ev_init (ev_TYPE *watcher, callback)"
-This macro initialises the generic portion of a watcher. The contents
-of the watcher object can be arbitrary (so \f(CW\*(C`malloc\*(C'\fR will do). Only
-the generic parts of the watcher are initialised, you \fIneed\fR to call
-the type-specific \f(CW\*(C`ev_TYPE_set\*(C'\fR macro afterwards to initialise the
-type-specific parts. For each type there is also a \f(CW\*(C`ev_TYPE_init\*(C'\fR macro
-which rolls both calls into one.
-.Sp
-You can reinitialise a watcher at any time as long as it has been stopped
-(or never started) and there are no pending events outstanding.
-.Sp
-The callback is always of type \f(CW\*(C`void (*)(struct ev_loop *loop, ev_TYPE *watcher,
-int revents)\*(C'\fR.
-.Sp
-Example: Initialise an \f(CW\*(C`ev_io\*(C'\fR watcher in two steps.
-.Sp
-.Vb 3
-\& ev_io w;
-\& ev_init (&w, my_cb);
-\& ev_io_set (&w, STDIN_FILENO, EV_READ);
-.Ve
-.ie n .IP """ev_TYPE_set"" (ev_TYPE *watcher, [args])" 4
-.el .IP "\f(CWev_TYPE_set\fR (ev_TYPE *watcher, [args])" 4
-.IX Item "ev_TYPE_set (ev_TYPE *watcher, [args])"
-This macro initialises the type-specific parts of a watcher. You need to
-call \f(CW\*(C`ev_init\*(C'\fR at least once before you call this macro, but you can
-call \f(CW\*(C`ev_TYPE_set\*(C'\fR any number of times. You must not, however, call this
-macro on a watcher that is active (it can be pending, however, which is a
-difference to the \f(CW\*(C`ev_init\*(C'\fR macro).
-.Sp
-Although some watcher types do not have type-specific arguments
-(e.g. \f(CW\*(C`ev_prepare\*(C'\fR) you still need to call its \f(CW\*(C`set\*(C'\fR macro.
-.Sp
-See \f(CW\*(C`ev_init\*(C'\fR, above, for an example.
-.ie n .IP """ev_TYPE_init"" (ev_TYPE *watcher, callback, [args])" 4
-.el .IP "\f(CWev_TYPE_init\fR (ev_TYPE *watcher, callback, [args])" 4
-.IX Item "ev_TYPE_init (ev_TYPE *watcher, callback, [args])"
-This convenience macro rolls both \f(CW\*(C`ev_init\*(C'\fR and \f(CW\*(C`ev_TYPE_set\*(C'\fR macro
-calls into a single call. This is the most convenient method to initialise
-a watcher. The same limitations apply, of course.
-.Sp
-Example: Initialise and set an \f(CW\*(C`ev_io\*(C'\fR watcher in one step.
-.Sp
-.Vb 1
-\& ev_io_init (&w, my_cb, STDIN_FILENO, EV_READ);
-.Ve
-.ie n .IP """ev_TYPE_start"" (loop, ev_TYPE *watcher)" 4
-.el .IP "\f(CWev_TYPE_start\fR (loop, ev_TYPE *watcher)" 4
-.IX Item "ev_TYPE_start (loop, ev_TYPE *watcher)"
-Starts (activates) the given watcher. Only active watchers will receive
-events. If the watcher is already active nothing will happen.
-.Sp
-Example: Start the \f(CW\*(C`ev_io\*(C'\fR watcher that is being abused as example in this
-whole section.
-.Sp
-.Vb 1
-\& ev_io_start (EV_DEFAULT_UC, &w);
-.Ve
-.ie n .IP """ev_TYPE_stop"" (loop, ev_TYPE *watcher)" 4
-.el .IP "\f(CWev_TYPE_stop\fR (loop, ev_TYPE *watcher)" 4
-.IX Item "ev_TYPE_stop (loop, ev_TYPE *watcher)"
-Stops the given watcher if active, and clears the pending status (whether
-the watcher was active or not).
-.Sp
-It is possible that stopped watchers are pending \- for example,
-non-repeating timers are being stopped when they become pending \- but
-calling \f(CW\*(C`ev_TYPE_stop\*(C'\fR ensures that the watcher is neither active nor
-pending. If you want to free or reuse the memory used by the watcher it is
-therefore a good idea to always call its \f(CW\*(C`ev_TYPE_stop\*(C'\fR function.
-.IP "bool ev_is_active (ev_TYPE *watcher)" 4
-.IX Item "bool ev_is_active (ev_TYPE *watcher)"
-Returns a true value iff the watcher is active (i.e. it has been started
-and not yet been stopped). As long as a watcher is active you must not modify
-it.
-.IP "bool ev_is_pending (ev_TYPE *watcher)" 4
-.IX Item "bool ev_is_pending (ev_TYPE *watcher)"
-Returns a true value iff the watcher is pending, (i.e. it has outstanding
-events but its callback has not yet been invoked). As long as a watcher
-is pending (but not active) you must not call an init function on it (but
-\&\f(CW\*(C`ev_TYPE_set\*(C'\fR is safe), you must not change its priority, and you must
-make sure the watcher is available to libev (e.g. you cannot \f(CW\*(C`free ()\*(C'\fR
-it).
-.IP "callback ev_cb (ev_TYPE *watcher)" 4
-.IX Item "callback ev_cb (ev_TYPE *watcher)"
-Returns the callback currently set on the watcher.
-.IP "ev_cb_set (ev_TYPE *watcher, callback)" 4
-.IX Item "ev_cb_set (ev_TYPE *watcher, callback)"
-Change the callback. You can change the callback at virtually any time
-(modulo threads).
-.IP "ev_set_priority (ev_TYPE *watcher, int priority)" 4
-.IX Item "ev_set_priority (ev_TYPE *watcher, int priority)"
-.PD 0
-.IP "int ev_priority (ev_TYPE *watcher)" 4
-.IX Item "int ev_priority (ev_TYPE *watcher)"
-.PD
-Set and query the priority of the watcher. The priority is a small
-integer between \f(CW\*(C`EV_MAXPRI\*(C'\fR (default: \f(CW2\fR) and \f(CW\*(C`EV_MINPRI\*(C'\fR
-(default: \f(CW\*(C`\-2\*(C'\fR). Pending watchers with higher priority will be invoked
-before watchers with lower priority, but priority will not keep watchers
-from being executed (except for \f(CW\*(C`ev_idle\*(C'\fR watchers).
-.Sp
-If you need to suppress invocation when higher priority events are pending
-you need to look at \f(CW\*(C`ev_idle\*(C'\fR watchers, which provide this functionality.
-.Sp
-You \fImust not\fR change the priority of a watcher as long as it is active or
-pending.
-.Sp
-Setting a priority outside the range of \f(CW\*(C`EV_MINPRI\*(C'\fR to \f(CW\*(C`EV_MAXPRI\*(C'\fR is
-fine, as long as you do not mind that the priority value you query might
-or might not have been clamped to the valid range.
-.Sp
-The default priority used by watchers when no priority has been set is
-always \f(CW0\fR, which is supposed to not be too high and not be too low :).
-.Sp
-See \*(L"\s-1WATCHER\s0 \s-1PRIORITY\s0 \s-1MODELS\s0\*(R", below, for a more thorough treatment of
-priorities.
-.IP "ev_invoke (loop, ev_TYPE *watcher, int revents)" 4
-.IX Item "ev_invoke (loop, ev_TYPE *watcher, int revents)"
-Invoke the \f(CW\*(C`watcher\*(C'\fR with the given \f(CW\*(C`loop\*(C'\fR and \f(CW\*(C`revents\*(C'\fR. Neither
-\&\f(CW\*(C`loop\*(C'\fR nor \f(CW\*(C`revents\*(C'\fR need to be valid as long as the watcher callback
-can deal with that fact, as both are simply passed through to the
-callback.
-.IP "int ev_clear_pending (loop, ev_TYPE *watcher)" 4
-.IX Item "int ev_clear_pending (loop, ev_TYPE *watcher)"
-If the watcher is pending, this function clears its pending status and
-returns its \f(CW\*(C`revents\*(C'\fR bitset (as if its callback was invoked). If the
-watcher isn't pending it does nothing and returns \f(CW0\fR.
-.Sp
-Sometimes it can be useful to \*(L"poll\*(R" a watcher instead of waiting for its
-callback to be invoked, which can be accomplished with this function.
-.IP "ev_feed_event (loop, ev_TYPE *watcher, int revents)" 4
-.IX Item "ev_feed_event (loop, ev_TYPE *watcher, int revents)"
-Feeds the given event set into the event loop, as if the specified event
-had happened for the specified watcher (which must be a pointer to an
-initialised but not necessarily started event watcher). Obviously you must
-not free the watcher as long as it has pending events.
-.Sp
-Stopping the watcher, letting libev invoke it, or calling
-\&\f(CW\*(C`ev_clear_pending\*(C'\fR will clear the pending event, even if the watcher was
-not started in the first place.
-.Sp
-See also \f(CW\*(C`ev_feed_fd_event\*(C'\fR and \f(CW\*(C`ev_feed_signal_event\*(C'\fR for related
-functions that do not need a watcher.
-.PP
-See also the \*(L"\s-1ASSOCIATING\s0 \s-1CUSTOM\s0 \s-1DATA\s0 \s-1WITH\s0 A \s-1WATCHER\s0\*(R" and \*(L"\s-1BUILDING\s0 \s-1YOUR\s0
-\&\s-1OWN\s0 \s-1COMPOSITE\s0 \s-1WATCHERS\s0\*(R" idioms.
-.SS "\s-1WATCHER\s0 \s-1STATES\s0"
-.IX Subsection "WATCHER STATES"
-There are various watcher states mentioned throughout this manual \-
-active, pending and so on. In this section these states and the rules to
-transition between them will be described in more detail \- and while these
-rules might look complicated, they usually do \*(L"the right thing\*(R".
-.IP "initialiased" 4
-.IX Item "initialiased"
-Before a watcher can be registered with the event looop it has to be
-initialised. This can be done with a call to \f(CW\*(C`ev_TYPE_init\*(C'\fR, or calls to
-\&\f(CW\*(C`ev_init\*(C'\fR followed by the watcher-specific \f(CW\*(C`ev_TYPE_set\*(C'\fR function.
-.Sp
-In this state it is simply some block of memory that is suitable for
-use in an event loop. It can be moved around, freed, reused etc. at
-will \- as long as you either keep the memory contents intact, or call
-\&\f(CW\*(C`ev_TYPE_init\*(C'\fR again.
-.IP "started/running/active" 4
-.IX Item "started/running/active"
-Once a watcher has been started with a call to \f(CW\*(C`ev_TYPE_start\*(C'\fR it becomes
-property of the event loop, and is actively waiting for events. While in
-this state it cannot be accessed (except in a few documented ways), moved,
-freed or anything else \- the only legal thing is to keep a pointer to it,
-and call libev functions on it that are documented to work on active watchers.
-.IP "pending" 4
-.IX Item "pending"
-If a watcher is active and libev determines that an event it is interested
-in has occurred (such as a timer expiring), it will become pending. It will
-stay in this pending state until either it is stopped or its callback is
-about to be invoked, so it is not normally pending inside the watcher
-callback.
-.Sp
-The watcher might or might not be active while it is pending (for example,
-an expired non-repeating timer can be pending but no longer active). If it
-is stopped, it can be freely accessed (e.g. by calling \f(CW\*(C`ev_TYPE_set\*(C'\fR),
-but it is still property of the event loop at this time, so cannot be
-moved, freed or reused. And if it is active the rules described in the
-previous item still apply.
-.Sp
-It is also possible to feed an event on a watcher that is not active (e.g.
-via \f(CW\*(C`ev_feed_event\*(C'\fR), in which case it becomes pending without being
-active.
-.IP "stopped" 4
-.IX Item "stopped"
-A watcher can be stopped implicitly by libev (in which case it might still
-be pending), or explicitly by calling its \f(CW\*(C`ev_TYPE_stop\*(C'\fR function. The
-latter will clear any pending state the watcher might be in, regardless
-of whether it was active or not, so stopping a watcher explicitly before
-freeing it is often a good idea.
-.Sp
-While stopped (and not pending) the watcher is essentially in the
-initialised state, that is, it can be reused, moved, modified in any way
-you wish (but when you trash the memory block, you need to \f(CW\*(C`ev_TYPE_init\*(C'\fR
-it again).
-.SS "\s-1WATCHER\s0 \s-1PRIORITY\s0 \s-1MODELS\s0"
-.IX Subsection "WATCHER PRIORITY MODELS"
-Many event loops support \fIwatcher priorities\fR, which are usually small
-integers that influence the ordering of event callback invocation
-between watchers in some way, all else being equal.
-.PP
-In libev, Watcher priorities can be set using \f(CW\*(C`ev_set_priority\*(C'\fR. See its
-description for the more technical details such as the actual priority
-range.
-.PP
-There are two common ways how these these priorities are being interpreted
-by event loops:
-.PP
-In the more common lock-out model, higher priorities \*(L"lock out\*(R" invocation
-of lower priority watchers, which means as long as higher priority
-watchers receive events, lower priority watchers are not being invoked.
-.PP
-The less common only-for-ordering model uses priorities solely to order
-callback invocation within a single event loop iteration: Higher priority
-watchers are invoked before lower priority ones, but they all get invoked
-before polling for new events.
-.PP
-Libev uses the second (only-for-ordering) model for all its watchers
-except for idle watchers (which use the lock-out model).
-.PP
-The rationale behind this is that implementing the lock-out model for
-watchers is not well supported by most kernel interfaces, and most event
-libraries will just poll for the same events again and again as long as
-their callbacks have not been executed, which is very inefficient in the
-common case of one high-priority watcher locking out a mass of lower
-priority ones.
-.PP
-Static (ordering) priorities are most useful when you have two or more
-watchers handling the same resource: a typical usage example is having an
-\&\f(CW\*(C`ev_io\*(C'\fR watcher to receive data, and an associated \f(CW\*(C`ev_timer\*(C'\fR to handle
-timeouts. Under load, data might be received while the program handles
-other jobs, but since timers normally get invoked first, the timeout
-handler will be executed before checking for data. In that case, giving
-the timer a lower priority than the I/O watcher ensures that I/O will be
-handled first even under adverse conditions (which is usually, but not
-always, what you want).
-.PP
-Since idle watchers use the \*(L"lock-out\*(R" model, meaning that idle watchers
-will only be executed when no same or higher priority watchers have
-received events, they can be used to implement the \*(L"lock-out\*(R" model when
-required.
-.PP
-For example, to emulate how many other event libraries handle priorities,
-you can associate an \f(CW\*(C`ev_idle\*(C'\fR watcher to each such watcher, and in
-the normal watcher callback, you just start the idle watcher. The real
-processing is done in the idle watcher callback. This causes libev to
-continuously poll and process kernel event data for the watcher, but when
-the lock-out case is known to be rare (which in turn is rare :), this is
-workable.
-.PP
-Usually, however, the lock-out model implemented that way will perform
-miserably under the type of load it was designed to handle. In that case,
-it might be preferable to stop the real watcher before starting the
-idle watcher, so the kernel will not have to process the event in case
-the actual processing will be delayed for considerable time.
-.PP
-Here is an example of an I/O watcher that should run at a strictly lower
-priority than the default, and which should only process data when no
-other events are pending:
-.PP
-.Vb 2
-\& ev_idle idle; // actual processing watcher
-\& ev_io io; // actual event watcher
-\&
-\& static void
-\& io_cb (EV_P_ ev_io *w, int revents)
-\& {
-\& // stop the I/O watcher, we received the event, but
-\& // are not yet ready to handle it.
-\& ev_io_stop (EV_A_ w);
-\&
-\& // start the idle watcher to handle the actual event.
-\& // it will not be executed as long as other watchers
-\& // with the default priority are receiving events.
-\& ev_idle_start (EV_A_ &idle);
-\& }
-\&
-\& static void
-\& idle_cb (EV_P_ ev_idle *w, int revents)
-\& {
-\& // actual processing
-\& read (STDIN_FILENO, ...);
-\&
-\& // have to start the I/O watcher again, as
-\& // we have handled the event
-\& ev_io_start (EV_P_ &io);
-\& }
-\&
-\& // initialisation
-\& ev_idle_init (&idle, idle_cb);
-\& ev_io_init (&io, io_cb, STDIN_FILENO, EV_READ);
-\& ev_io_start (EV_DEFAULT_ &io);
-.Ve
-.PP
-In the \*(L"real\*(R" world, it might also be beneficial to start a timer, so that
-low-priority connections can not be locked out forever under load. This
-enables your program to keep a lower latency for important connections
-during short periods of high load, while not completely locking out less
-important ones.
-.SH "WATCHER TYPES"
-.IX Header "WATCHER TYPES"
-This section describes each watcher in detail, but will not repeat
-information given in the last section. Any initialisation/set macros,
-functions and members specific to the watcher type are explained.
-.PP
-Members are additionally marked with either \fI[read\-only]\fR, meaning that,
-while the watcher is active, you can look at the member and expect some
-sensible content, but you must not modify it (you can modify it while the
-watcher is stopped to your hearts content), or \fI[read\-write]\fR, which
-means you can expect it to have some sensible content while the watcher
-is active, but you can also modify it. Modifying it may not do something
-sensible or take immediate effect (or do anything at all), but libev will
-not crash or malfunction in any way.
-.ie n .SS """ev_io"" \- is this file descriptor readable or writable?"
-.el .SS "\f(CWev_io\fP \- is this file descriptor readable or writable?"
-.IX Subsection "ev_io - is this file descriptor readable or writable?"
-I/O watchers check whether a file descriptor is readable or writable
-in each iteration of the event loop, or, more precisely, when reading
-would not block the process and writing would at least be able to write
-some data. This behaviour is called level-triggering because you keep
-receiving events as long as the condition persists. Remember you can stop
-the watcher if you don't want to act on the event and neither want to
-receive future events.
-.PP
-In general you can register as many read and/or write event watchers per
-fd as you want (as long as you don't confuse yourself). Setting all file
-descriptors to non-blocking mode is also usually a good idea (but not
-required if you know what you are doing).
-.PP
-Another thing you have to watch out for is that it is quite easy to
-receive \*(L"spurious\*(R" readiness notifications, that is, your callback might
-be called with \f(CW\*(C`EV_READ\*(C'\fR but a subsequent \f(CW\*(C`read\*(C'\fR(2) will actually block
-because there is no data. It is very easy to get into this situation even
-with a relatively standard program structure. Thus it is best to always
-use non-blocking I/O: An extra \f(CW\*(C`read\*(C'\fR(2) returning \f(CW\*(C`EAGAIN\*(C'\fR is far
-preferable to a program hanging until some data arrives.
-.PP
-If you cannot run the fd in non-blocking mode (for example you should
-not play around with an Xlib connection), then you have to separately
-re-test whether a file descriptor is really ready with a known-to-be good
-interface such as poll (fortunately in the case of Xlib, it already does
-this on its own, so its quite safe to use). Some people additionally
-use \f(CW\*(C`SIGALRM\*(C'\fR and an interval timer, just to be sure you won't block
-indefinitely.
-.PP
-But really, best use non-blocking mode.
-.PP
-\fIThe special problem of disappearing file descriptors\fR
-.IX Subsection "The special problem of disappearing file descriptors"
-.PP
-Some backends (e.g. kqueue, epoll) need to be told about closing a file
-descriptor (either due to calling \f(CW\*(C`close\*(C'\fR explicitly or any other means,
-such as \f(CW\*(C`dup2\*(C'\fR). The reason is that you register interest in some file
-descriptor, but when it goes away, the operating system will silently drop
-this interest. If another file descriptor with the same number then is
-registered with libev, there is no efficient way to see that this is, in
-fact, a different file descriptor.
-.PP
-To avoid having to explicitly tell libev about such cases, libev follows
-the following policy: Each time \f(CW\*(C`ev_io_set\*(C'\fR is being called, libev
-will assume that this is potentially a new file descriptor, otherwise
-it is assumed that the file descriptor stays the same. That means that
-you \fIhave\fR to call \f(CW\*(C`ev_io_set\*(C'\fR (or \f(CW\*(C`ev_io_init\*(C'\fR) when you change the
-descriptor even if the file descriptor number itself did not change.
-.PP
-This is how one would do it normally anyway, the important point is that
-the libev application should not optimise around libev but should leave
-optimisations to libev.
-.PP
-\fIThe special problem of dup'ed file descriptors\fR
-.IX Subsection "The special problem of dup'ed file descriptors"
-.PP
-Some backends (e.g. epoll), cannot register events for file descriptors,
-but only events for the underlying file descriptions. That means when you
-have \f(CW\*(C`dup ()\*(C'\fR'ed file descriptors or weirder constellations, and register
-events for them, only one file descriptor might actually receive events.
-.PP
-There is no workaround possible except not registering events
-for potentially \f(CW\*(C`dup ()\*(C'\fR'ed file descriptors, or to resort to
-\&\f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
-.PP
-\fIThe special problem of files\fR
-.IX Subsection "The special problem of files"
-.PP
-Many people try to use \f(CW\*(C`select\*(C'\fR (or libev) on file descriptors
-representing files, and expect it to become ready when their program
-doesn't block on disk accesses (which can take a long time on their own).
-.PP
-However, this cannot ever work in the \*(L"expected\*(R" way \- you get a readiness
-notification as soon as the kernel knows whether and how much data is
-there, and in the case of open files, that's always the case, so you
-always get a readiness notification instantly, and your read (or possibly
-write) will still block on the disk I/O.
-.PP
-Another way to view it is that in the case of sockets, pipes, character
-devices and so on, there is another party (the sender) that delivers data
-on its own, but in the case of files, there is no such thing: the disk
-will not send data on its own, simply because it doesn't know what you
-wish to read \- you would first have to request some data.
-.PP
-Since files are typically not-so-well supported by advanced notification
-mechanism, libev tries hard to emulate \s-1POSIX\s0 behaviour with respect
-to files, even though you should not use it. The reason for this is
-convenience: sometimes you want to watch \s-1STDIN\s0 or \s-1STDOUT\s0, which is
-usually a tty, often a pipe, but also sometimes files or special devices
-(for example, \f(CW\*(C`epoll\*(C'\fR on Linux works with \fI/dev/random\fR but not with
-\&\fI/dev/urandom\fR), and even though the file might better be served with
-asynchronous I/O instead of with non-blocking I/O, it is still useful when
-it \*(L"just works\*(R" instead of freezing.
-.PP
-So avoid file descriptors pointing to files when you know it (e.g. use
-libeio), but use them when it is convenient, e.g. for \s-1STDIN/STDOUT\s0, or
-when you rarely read from a file instead of from a socket, and want to
-reuse the same code path.
-.PP
-\fIThe special problem of fork\fR
-.IX Subsection "The special problem of fork"
-.PP
-Some backends (epoll, kqueue) do not support \f(CW\*(C`fork ()\*(C'\fR at all or exhibit
-useless behaviour. Libev fully supports fork, but needs to be told about
-it in the child if you want to continue to use it in the child.
-.PP
-To support fork in your child processes, you have to call \f(CW\*(C`ev_loop_fork
-()\*(C'\fR after a fork in the child, enable \f(CW\*(C`EVFLAG_FORKCHECK\*(C'\fR, or resort to
-\&\f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
-.PP
-\fIThe special problem of \s-1SIGPIPE\s0\fR
-.IX Subsection "The special problem of SIGPIPE"
-.PP
-While not really specific to libev, it is easy to forget about \f(CW\*(C`SIGPIPE\*(C'\fR:
-when writing to a pipe whose other end has been closed, your program gets
-sent a \s-1SIGPIPE\s0, which, by default, aborts your program. For most programs
-this is sensible behaviour, for daemons, this is usually undesirable.
-.PP
-So when you encounter spurious, unexplained daemon exits, make sure you
-ignore \s-1SIGPIPE\s0 (and maybe make sure you log the exit status of your daemon
-somewhere, as that would have given you a big clue).
-.PP
-\fIThe special problem of \fIaccept()\fIing when you can't\fR
-.IX Subsection "The special problem of accept()ing when you can't"
-.PP
-Many implementations of the \s-1POSIX\s0 \f(CW\*(C`accept\*(C'\fR function (for example,
-found in post\-2004 Linux) have the peculiar behaviour of not removing a
-connection from the pending queue in all error cases.
-.PP
-For example, larger servers often run out of file descriptors (because
-of resource limits), causing \f(CW\*(C`accept\*(C'\fR to fail with \f(CW\*(C`ENFILE\*(C'\fR but not
-rejecting the connection, leading to libev signalling readiness on
-the next iteration again (the connection still exists after all), and
-typically causing the program to loop at 100% \s-1CPU\s0 usage.
-.PP
-Unfortunately, the set of errors that cause this issue differs between
-operating systems, there is usually little the app can do to remedy the
-situation, and no known thread-safe method of removing the connection to
-cope with overload is known (to me).
-.PP
-One of the easiest ways to handle this situation is to just ignore it
-\&\- when the program encounters an overload, it will just loop until the
-situation is over. While this is a form of busy waiting, no \s-1OS\s0 offers an
-event-based way to handle this situation, so it's the best one can do.
-.PP
-A better way to handle the situation is to log any errors other than
-\&\f(CW\*(C`EAGAIN\*(C'\fR and \f(CW\*(C`EWOULDBLOCK\*(C'\fR, making sure not to flood the log with such
-messages, and continue as usual, which at least gives the user an idea of
-what could be wrong (\*(L"raise the ulimit!\*(R"). For extra points one could stop
-the \f(CW\*(C`ev_io\*(C'\fR watcher on the listening fd \*(L"for a while\*(R", which reduces \s-1CPU\s0
-usage.
-.PP
-If your program is single-threaded, then you could also keep a dummy file
-descriptor for overload situations (e.g. by opening \fI/dev/null\fR), and
-when you run into \f(CW\*(C`ENFILE\*(C'\fR or \f(CW\*(C`EMFILE\*(C'\fR, close it, run \f(CW\*(C`accept\*(C'\fR,
-close that fd, and create a new dummy fd. This will gracefully refuse
-clients under typical overload conditions.
-.PP
-The last way to handle it is to simply log the error and \f(CW\*(C`exit\*(C'\fR, as
-is often done with \f(CW\*(C`malloc\*(C'\fR failures, but this results in an easy
-opportunity for a DoS attack.
-.PP
-\fIWatcher-Specific Functions\fR
-.IX Subsection "Watcher-Specific Functions"
-.IP "ev_io_init (ev_io *, callback, int fd, int events)" 4
-.IX Item "ev_io_init (ev_io *, callback, int fd, int events)"
-.PD 0
-.IP "ev_io_set (ev_io *, int fd, int events)" 4
-.IX Item "ev_io_set (ev_io *, int fd, int events)"
-.PD
-Configures an \f(CW\*(C`ev_io\*(C'\fR watcher. The \f(CW\*(C`fd\*(C'\fR is the file descriptor to
-receive events for and \f(CW\*(C`events\*(C'\fR is either \f(CW\*(C`EV_READ\*(C'\fR, \f(CW\*(C`EV_WRITE\*(C'\fR or
-\&\f(CW\*(C`EV_READ | EV_WRITE\*(C'\fR, to express the desire to receive the given events.
-.IP "int fd [read\-only]" 4
-.IX Item "int fd [read-only]"
-The file descriptor being watched.
-.IP "int events [read\-only]" 4
-.IX Item "int events [read-only]"
-The events being watched.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Call \f(CW\*(C`stdin_readable_cb\*(C'\fR when \s-1STDIN_FILENO\s0 has become, well
-readable, but only once. Since it is likely line-buffered, you could
-attempt to read a whole line in the callback.
-.PP
-.Vb 6
-\& static void
-\& stdin_readable_cb (struct ev_loop *loop, ev_io *w, int revents)
-\& {
-\& ev_io_stop (loop, w);
-\& .. read from stdin here (or from w\->fd) and handle any I/O errors
-\& }
-\&
-\& ...
-\& struct ev_loop *loop = ev_default_init (0);
-\& ev_io stdin_readable;
-\& ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ);
-\& ev_io_start (loop, &stdin_readable);
-\& ev_run (loop, 0);
-.Ve
-.ie n .SS """ev_timer"" \- relative and optionally repeating timeouts"
-.el .SS "\f(CWev_timer\fP \- relative and optionally repeating timeouts"
-.IX Subsection "ev_timer - relative and optionally repeating timeouts"
-Timer watchers are simple relative timers that generate an event after a
-given time, and optionally repeating in regular intervals after that.
-.PP
-The timers are based on real time, that is, if you register an event that
-times out after an hour and you reset your system clock to January last
-year, it will still time out after (roughly) one hour. \*(L"Roughly\*(R" because
-detecting time jumps is hard, and some inaccuracies are unavoidable (the
-monotonic clock option helps a lot here).
-.PP
-The callback is guaranteed to be invoked only \fIafter\fR its timeout has
-passed (not \fIat\fR, so on systems with very low-resolution clocks this
-might introduce a small delay). If multiple timers become ready during the
-same loop iteration then the ones with earlier time-out values are invoked
-before ones of the same priority with later time-out values (but this is
-no longer true when a callback calls \f(CW\*(C`ev_run\*(C'\fR recursively).
-.PP
-\fIBe smart about timeouts\fR
-.IX Subsection "Be smart about timeouts"
-.PP
-Many real-world problems involve some kind of timeout, usually for error
-recovery. A typical example is an \s-1HTTP\s0 request \- if the other side hangs,
-you want to raise some error after a while.
-.PP
-What follows are some ways to handle this problem, from obvious and
-inefficient to smart and efficient.
-.PP
-In the following, a 60 second activity timeout is assumed \- a timeout that
-gets reset to 60 seconds each time there is activity (e.g. each time some
-data or other life sign was received).
-.IP "1. Use a timer and stop, reinitialise and start it on activity." 4
-.IX Item "1. Use a timer and stop, reinitialise and start it on activity."
-This is the most obvious, but not the most simple way: In the beginning,
-start the watcher:
-.Sp
-.Vb 2
-\& ev_timer_init (timer, callback, 60., 0.);
-\& ev_timer_start (loop, timer);
-.Ve
-.Sp
-Then, each time there is some activity, \f(CW\*(C`ev_timer_stop\*(C'\fR it, initialise it
-and start it again:
-.Sp
-.Vb 3
-\& ev_timer_stop (loop, timer);
-\& ev_timer_set (timer, 60., 0.);
-\& ev_timer_start (loop, timer);
-.Ve
-.Sp
-This is relatively simple to implement, but means that each time there is
-some activity, libev will first have to remove the timer from its internal
-data structure and then add it again. Libev tries to be fast, but it's
-still not a constant-time operation.
-.ie n .IP "2. Use a timer and re-start it with ""ev_timer_again"" inactivity." 4
-.el .IP "2. Use a timer and re-start it with \f(CWev_timer_again\fR inactivity." 4
-.IX Item "2. Use a timer and re-start it with ev_timer_again inactivity."
-This is the easiest way, and involves using \f(CW\*(C`ev_timer_again\*(C'\fR instead of
-\&\f(CW\*(C`ev_timer_start\*(C'\fR.
-.Sp
-To implement this, configure an \f(CW\*(C`ev_timer\*(C'\fR with a \f(CW\*(C`repeat\*(C'\fR value
-of \f(CW60\fR and then call \f(CW\*(C`ev_timer_again\*(C'\fR at start and each time you
-successfully read or write some data. If you go into an idle state where
-you do not expect data to travel on the socket, you can \f(CW\*(C`ev_timer_stop\*(C'\fR
-the timer, and \f(CW\*(C`ev_timer_again\*(C'\fR will automatically restart it if need be.
-.Sp
-That means you can ignore both the \f(CW\*(C`ev_timer_start\*(C'\fR function and the
-\&\f(CW\*(C`after\*(C'\fR argument to \f(CW\*(C`ev_timer_set\*(C'\fR, and only ever use the \f(CW\*(C`repeat\*(C'\fR
-member and \f(CW\*(C`ev_timer_again\*(C'\fR.
-.Sp
-At start:
-.Sp
-.Vb 3
-\& ev_init (timer, callback);
-\& timer\->repeat = 60.;
-\& ev_timer_again (loop, timer);
-.Ve
-.Sp
-Each time there is some activity:
-.Sp
-.Vb 1
-\& ev_timer_again (loop, timer);
-.Ve
-.Sp
-It is even possible to change the time-out on the fly, regardless of
-whether the watcher is active or not:
-.Sp
-.Vb 2
-\& timer\->repeat = 30.;
-\& ev_timer_again (loop, timer);
-.Ve
-.Sp
-This is slightly more efficient then stopping/starting the timer each time
-you want to modify its timeout value, as libev does not have to completely
-remove and re-insert the timer from/into its internal data structure.
-.Sp
-It is, however, even simpler than the \*(L"obvious\*(R" way to do it.
-.IP "3. Let the timer time out, but then re-arm it as required." 4
-.IX Item "3. Let the timer time out, but then re-arm it as required."
-This method is more tricky, but usually most efficient: Most timeouts are
-relatively long compared to the intervals between other activity \- in
-our example, within 60 seconds, there are usually many I/O events with
-associated activity resets.
-.Sp
-In this case, it would be more efficient to leave the \f(CW\*(C`ev_timer\*(C'\fR alone,
-but remember the time of last activity, and check for a real timeout only
-within the callback:
-.Sp
-.Vb 1
-\& ev_tstamp last_activity; // time of last activity
-\&
-\& static void
-\& callback (EV_P_ ev_timer *w, int revents)
-\& {
-\& ev_tstamp now = ev_now (EV_A);
-\& ev_tstamp timeout = last_activity + 60.;
-\&
-\& // if last_activity + 60. is older than now, we did time out
-\& if (timeout < now)
-\& {
-\& // timeout occurred, take action
-\& }
-\& else
-\& {
-\& // callback was invoked, but there was some activity, re\-arm
-\& // the watcher to fire in last_activity + 60, which is
-\& // guaranteed to be in the future, so "again" is positive:
-\& w\->repeat = timeout \- now;
-\& ev_timer_again (EV_A_ w);
-\& }
-\& }
-.Ve
-.Sp
-To summarise the callback: first calculate the real timeout (defined
-as \*(L"60 seconds after the last activity\*(R"), then check if that time has
-been reached, which means something \fIdid\fR, in fact, time out. Otherwise
-the callback was invoked too early (\f(CW\*(C`timeout\*(C'\fR is in the future), so
-re-schedule the timer to fire at that future time, to see if maybe we have
-a timeout then.
-.Sp
-Note how \f(CW\*(C`ev_timer_again\*(C'\fR is used, taking advantage of the
-\&\f(CW\*(C`ev_timer_again\*(C'\fR optimisation when the timer is already running.
-.Sp
-This scheme causes more callback invocations (about one every 60 seconds
-minus half the average time between activity), but virtually no calls to
-libev to change the timeout.
-.Sp
-To start the timer, simply initialise the watcher and set \f(CW\*(C`last_activity\*(C'\fR
-to the current time (meaning we just have some activity :), then call the
-callback, which will \*(L"do the right thing\*(R" and start the timer:
-.Sp
-.Vb 3
-\& ev_init (timer, callback);
-\& last_activity = ev_now (loop);
-\& callback (loop, timer, EV_TIMER);
-.Ve
-.Sp
-And when there is some activity, simply store the current time in
-\&\f(CW\*(C`last_activity\*(C'\fR, no libev calls at all:
-.Sp
-.Vb 1
-\& last_activity = ev_now (loop);
-.Ve
-.Sp
-This technique is slightly more complex, but in most cases where the
-time-out is unlikely to be triggered, much more efficient.
-.Sp
-Changing the timeout is trivial as well (if it isn't hard-coded in the
-callback :) \- just change the timeout and invoke the callback, which will
-fix things for you.
-.IP "4. Wee, just use a double-linked list for your timeouts." 4
-.IX Item "4. Wee, just use a double-linked list for your timeouts."
-If there is not one request, but many thousands (millions...), all
-employing some kind of timeout with the same timeout value, then one can
-do even better:
-.Sp
-When starting the timeout, calculate the timeout value and put the timeout
-at the \fIend\fR of the list.
-.Sp
-Then use an \f(CW\*(C`ev_timer\*(C'\fR to fire when the timeout at the \fIbeginning\fR of
-the list is expected to fire (for example, using the technique #3).
-.Sp
-When there is some activity, remove the timer from the list, recalculate
-the timeout, append it to the end of the list again, and make sure to
-update the \f(CW\*(C`ev_timer\*(C'\fR if it was taken from the beginning of the list.
-.Sp
-This way, one can manage an unlimited number of timeouts in O(1) time for
-starting, stopping and updating the timers, at the expense of a major
-complication, and having to use a constant timeout. The constant timeout
-ensures that the list stays sorted.
-.PP
-So which method the best?
-.PP
-Method #2 is a simple no-brain-required solution that is adequate in most
-situations. Method #3 requires a bit more thinking, but handles many cases
-better, and isn't very complicated either. In most case, choosing either
-one is fine, with #3 being better in typical situations.
-.PP
-Method #1 is almost always a bad idea, and buys you nothing. Method #4 is
-rather complicated, but extremely efficient, something that really pays
-off after the first million or so of active timers, i.e. it's usually
-overkill :)
-.PP
-\fIThe special problem of time updates\fR
-.IX Subsection "The special problem of time updates"
-.PP
-Establishing the current time is a costly operation (it usually takes at
-least two system calls): \s-1EV\s0 therefore updates its idea of the current
-time only before and after \f(CW\*(C`ev_run\*(C'\fR collects new events, which causes a
-growing difference between \f(CW\*(C`ev_now ()\*(C'\fR and \f(CW\*(C`ev_time ()\*(C'\fR when handling
-lots of events in one iteration.
-.PP
-The relative timeouts are calculated relative to the \f(CW\*(C`ev_now ()\*(C'\fR
-time. This is usually the right thing as this timestamp refers to the time
-of the event triggering whatever timeout you are modifying/starting. If
-you suspect event processing to be delayed and you \fIneed\fR to base the
-timeout on the current time, use something like this to adjust for this:
-.PP
-.Vb 1
-\& ev_timer_set (&timer, after + ev_now () \- ev_time (), 0.);
-.Ve
-.PP
-If the event loop is suspended for a long time, you can also force an
-update of the time returned by \f(CW\*(C`ev_now ()\*(C'\fR by calling \f(CW\*(C`ev_now_update
-()\*(C'\fR.
-.PP
-\fIThe special problems of suspended animation\fR
-.IX Subsection "The special problems of suspended animation"
-.PP
-When you leave the server world it is quite customary to hit machines that
-can suspend/hibernate \- what happens to the clocks during such a suspend?
-.PP
-Some quick tests made with a Linux 2.6.28 indicate that a suspend freezes
-all processes, while the clocks (\f(CW\*(C`times\*(C'\fR, \f(CW\*(C`CLOCK_MONOTONIC\*(C'\fR) continue
-to run until the system is suspended, but they will not advance while the
-system is suspended. That means, on resume, it will be as if the program
-was frozen for a few seconds, but the suspend time will not be counted
-towards \f(CW\*(C`ev_timer\*(C'\fR when a monotonic clock source is used. The real time
-clock advanced as expected, but if it is used as sole clocksource, then a
-long suspend would be detected as a time jump by libev, and timers would
-be adjusted accordingly.
-.PP
-I would not be surprised to see different behaviour in different between
-operating systems, \s-1OS\s0 versions or even different hardware.
-.PP
-The other form of suspend (job control, or sending a \s-1SIGSTOP\s0) will see a
-time jump in the monotonic clocks and the realtime clock. If the program
-is suspended for a very long time, and monotonic clock sources are in use,
-then you can expect \f(CW\*(C`ev_timer\*(C'\fRs to expire as the full suspension time
-will be counted towards the timers. When no monotonic clock source is in
-use, then libev will again assume a timejump and adjust accordingly.
-.PP
-It might be beneficial for this latter case to call \f(CW\*(C`ev_suspend\*(C'\fR
-and \f(CW\*(C`ev_resume\*(C'\fR in code that handles \f(CW\*(C`SIGTSTP\*(C'\fR, to at least get
-deterministic behaviour in this case (you can do nothing against
-\&\f(CW\*(C`SIGSTOP\*(C'\fR).
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_timer_init (ev_timer *, callback, ev_tstamp after, ev_tstamp repeat)" 4
-.IX Item "ev_timer_init (ev_timer *, callback, ev_tstamp after, ev_tstamp repeat)"
-.PD 0
-.IP "ev_timer_set (ev_timer *, ev_tstamp after, ev_tstamp repeat)" 4
-.IX Item "ev_timer_set (ev_timer *, ev_tstamp after, ev_tstamp repeat)"
-.PD
-Configure the timer to trigger after \f(CW\*(C`after\*(C'\fR seconds. If \f(CW\*(C`repeat\*(C'\fR
-is \f(CW0.\fR, then it will automatically be stopped once the timeout is
-reached. If it is positive, then the timer will automatically be
-configured to trigger again \f(CW\*(C`repeat\*(C'\fR seconds later, again, and again,
-until stopped manually.
-.Sp
-The timer itself will do a best-effort at avoiding drift, that is, if
-you configure a timer to trigger every 10 seconds, then it will normally
-trigger at exactly 10 second intervals. If, however, your program cannot
-keep up with the timer (because it takes longer than those 10 seconds to
-do stuff) the timer will not fire more than once per event loop iteration.
-.IP "ev_timer_again (loop, ev_timer *)" 4
-.IX Item "ev_timer_again (loop, ev_timer *)"
-This will act as if the timer timed out and restart it again if it is
-repeating. The exact semantics are:
-.Sp
-If the timer is pending, its pending status is cleared.
-.Sp
-If the timer is started but non-repeating, stop it (as if it timed out).
-.Sp
-If the timer is repeating, either start it if necessary (with the
-\&\f(CW\*(C`repeat\*(C'\fR value), or reset the running timer to the \f(CW\*(C`repeat\*(C'\fR value.
-.Sp
-This sounds a bit complicated, see \*(L"Be smart about timeouts\*(R", above, for a
-usage example.
-.IP "ev_tstamp ev_timer_remaining (loop, ev_timer *)" 4
-.IX Item "ev_tstamp ev_timer_remaining (loop, ev_timer *)"
-Returns the remaining time until a timer fires. If the timer is active,
-then this time is relative to the current event loop time, otherwise it's
-the timeout value currently configured.
-.Sp
-That is, after an \f(CW\*(C`ev_timer_set (w, 5, 7)\*(C'\fR, \f(CW\*(C`ev_timer_remaining\*(C'\fR returns
-\&\f(CW5\fR. When the timer is started and one second passes, \f(CW\*(C`ev_timer_remaining\*(C'\fR
-will return \f(CW4\fR. When the timer expires and is restarted, it will return
-roughly \f(CW7\fR (likely slightly less as callback invocation takes some time,
-too), and so on.
-.IP "ev_tstamp repeat [read\-write]" 4
-.IX Item "ev_tstamp repeat [read-write]"
-The current \f(CW\*(C`repeat\*(C'\fR value. Will be used each time the watcher times out
-or \f(CW\*(C`ev_timer_again\*(C'\fR is called, and determines the next timeout (if any),
-which is also when any modifications are taken into account.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Create a timer that fires after 60 seconds.
-.PP
-.Vb 5
-\& static void
-\& one_minute_cb (struct ev_loop *loop, ev_timer *w, int revents)
-\& {
-\& .. one minute over, w is actually stopped right here
-\& }
-\&
-\& ev_timer mytimer;
-\& ev_timer_init (&mytimer, one_minute_cb, 60., 0.);
-\& ev_timer_start (loop, &mytimer);
-.Ve
-.PP
-Example: Create a timeout timer that times out after 10 seconds of
-inactivity.
-.PP
-.Vb 5
-\& static void
-\& timeout_cb (struct ev_loop *loop, ev_timer *w, int revents)
-\& {
-\& .. ten seconds without any activity
-\& }
-\&
-\& ev_timer mytimer;
-\& ev_timer_init (&mytimer, timeout_cb, 0., 10.); /* note, only repeat used */
-\& ev_timer_again (&mytimer); /* start timer */
-\& ev_run (loop, 0);
-\&
-\& // and in some piece of code that gets executed on any "activity":
-\& // reset the timeout to start ticking again at 10 seconds
-\& ev_timer_again (&mytimer);
-.Ve
-.ie n .SS """ev_periodic"" \- to cron or not to cron?"
-.el .SS "\f(CWev_periodic\fP \- to cron or not to cron?"
-.IX Subsection "ev_periodic - to cron or not to cron?"
-Periodic watchers are also timers of a kind, but they are very versatile
-(and unfortunately a bit complex).
-.PP
-Unlike \f(CW\*(C`ev_timer\*(C'\fR, periodic watchers are not based on real time (or
-relative time, the physical time that passes) but on wall clock time
-(absolute time, the thing you can read on your calender or clock). The
-difference is that wall clock time can run faster or slower than real
-time, and time jumps are not uncommon (e.g. when you adjust your
-wrist-watch).
-.PP
-You can tell a periodic watcher to trigger after some specific point
-in time: for example, if you tell a periodic watcher to trigger \*(L"in 10
-seconds\*(R" (by specifying e.g. \f(CW\*(C`ev_now () + 10.\*(C'\fR, that is, an absolute time
-not a delay) and then reset your system clock to January of the previous
-year, then it will take a year or more to trigger the event (unlike an
-\&\f(CW\*(C`ev_timer\*(C'\fR, which would still trigger roughly 10 seconds after starting
-it, as it uses a relative timeout).
-.PP
-\&\f(CW\*(C`ev_periodic\*(C'\fR watchers can also be used to implement vastly more complex
-timers, such as triggering an event on each \*(L"midnight, local time\*(R", or
-other complicated rules. This cannot be done with \f(CW\*(C`ev_timer\*(C'\fR watchers, as
-those cannot react to time jumps.
-.PP
-As with timers, the callback is guaranteed to be invoked only when the
-point in time where it is supposed to trigger has passed. If multiple
-timers become ready during the same loop iteration then the ones with
-earlier time-out values are invoked before ones with later time-out values
-(but this is no longer true when a callback calls \f(CW\*(C`ev_run\*(C'\fR recursively).
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_periodic_init (ev_periodic *, callback, ev_tstamp offset, ev_tstamp interval, reschedule_cb)" 4
-.IX Item "ev_periodic_init (ev_periodic *, callback, ev_tstamp offset, ev_tstamp interval, reschedule_cb)"
-.PD 0
-.IP "ev_periodic_set (ev_periodic *, ev_tstamp offset, ev_tstamp interval, reschedule_cb)" 4
-.IX Item "ev_periodic_set (ev_periodic *, ev_tstamp offset, ev_tstamp interval, reschedule_cb)"
-.PD
-Lots of arguments, let's sort it out... There are basically three modes of
-operation, and we will explain them from simplest to most complex:
-.RS 4
-.IP "\(bu" 4
-absolute timer (offset = absolute time, interval = 0, reschedule_cb = 0)
-.Sp
-In this configuration the watcher triggers an event after the wall clock
-time \f(CW\*(C`offset\*(C'\fR has passed. It will not repeat and will not adjust when a
-time jump occurs, that is, if it is to be run at January 1st 2011 then it
-will be stopped and invoked when the system clock reaches or surpasses
-this point in time.
-.IP "\(bu" 4
-repeating interval timer (offset = offset within interval, interval > 0, reschedule_cb = 0)
-.Sp
-In this mode the watcher will always be scheduled to time out at the next
-\&\f(CW\*(C`offset + N * interval\*(C'\fR time (for some integer N, which can also be
-negative) and then repeat, regardless of any time jumps. The \f(CW\*(C`offset\*(C'\fR
-argument is merely an offset into the \f(CW\*(C`interval\*(C'\fR periods.
-.Sp
-This can be used to create timers that do not drift with respect to the
-system clock, for example, here is an \f(CW\*(C`ev_periodic\*(C'\fR that triggers each
-hour, on the hour (with respect to \s-1UTC\s0):
-.Sp
-.Vb 1
-\& ev_periodic_set (&periodic, 0., 3600., 0);
-.Ve
-.Sp
-This doesn't mean there will always be 3600 seconds in between triggers,
-but only that the callback will be called when the system time shows a
-full hour (\s-1UTC\s0), or more correctly, when the system time is evenly divisible
-by 3600.
-.Sp
-Another way to think about it (for the mathematically inclined) is that
-\&\f(CW\*(C`ev_periodic\*(C'\fR will try to run the callback in this mode at the next possible
-time where \f(CW\*(C`time = offset (mod interval)\*(C'\fR, regardless of any time jumps.
-.Sp
-For numerical stability it is preferable that the \f(CW\*(C`offset\*(C'\fR value is near
-\&\f(CW\*(C`ev_now ()\*(C'\fR (the current time), but there is no range requirement for
-this value, and in fact is often specified as zero.
-.Sp
-Note also that there is an upper limit to how often a timer can fire (\s-1CPU\s0
-speed for example), so if \f(CW\*(C`interval\*(C'\fR is very small then timing stability
-will of course deteriorate. Libev itself tries to be exact to be about one
-millisecond (if the \s-1OS\s0 supports it and the machine is fast enough).
-.IP "\(bu" 4
-manual reschedule mode (offset ignored, interval ignored, reschedule_cb = callback)
-.Sp
-In this mode the values for \f(CW\*(C`interval\*(C'\fR and \f(CW\*(C`offset\*(C'\fR are both being
-ignored. Instead, each time the periodic watcher gets scheduled, the
-reschedule callback will be called with the watcher as first, and the
-current time as second argument.
-.Sp
-\&\s-1NOTE:\s0 \fIThis callback \s-1MUST\s0 \s-1NOT\s0 stop or destroy any periodic watcher, ever,
-or make \s-1ANY\s0 other event loop modifications whatsoever, unless explicitly
-allowed by documentation here\fR.
-.Sp
-If you need to stop it, return \f(CW\*(C`now + 1e30\*(C'\fR (or so, fudge fudge) and stop
-it afterwards (e.g. by starting an \f(CW\*(C`ev_prepare\*(C'\fR watcher, which is the
-only event loop modification you are allowed to do).
-.Sp
-The callback prototype is \f(CW\*(C`ev_tstamp (*reschedule_cb)(ev_periodic
-*w, ev_tstamp now)\*(C'\fR, e.g.:
-.Sp
-.Vb 5
-\& static ev_tstamp
-\& my_rescheduler (ev_periodic *w, ev_tstamp now)
-\& {
-\& return now + 60.;
-\& }
-.Ve
-.Sp
-It must return the next time to trigger, based on the passed time value
-(that is, the lowest time value larger than to the second argument). It
-will usually be called just before the callback will be triggered, but
-might be called at other times, too.
-.Sp
-\&\s-1NOTE:\s0 \fIThis callback must always return a time that is higher than or
-equal to the passed \f(CI\*(C`now\*(C'\fI value\fR.
-.Sp
-This can be used to create very complex timers, such as a timer that
-triggers on \*(L"next midnight, local time\*(R". To do this, you would calculate the
-next midnight after \f(CW\*(C`now\*(C'\fR and return the timestamp value for this. How
-you do this is, again, up to you (but it is not trivial, which is the main
-reason I omitted it as an example).
-.RE
-.RS 4
-.RE
-.IP "ev_periodic_again (loop, ev_periodic *)" 4
-.IX Item "ev_periodic_again (loop, ev_periodic *)"
-Simply stops and restarts the periodic watcher again. This is only useful
-when you changed some parameters or the reschedule callback would return
-a different time than the last time it was called (e.g. in a crond like
-program when the crontabs have changed).
-.IP "ev_tstamp ev_periodic_at (ev_periodic *)" 4
-.IX Item "ev_tstamp ev_periodic_at (ev_periodic *)"
-When active, returns the absolute time that the watcher is supposed
-to trigger next. This is not the same as the \f(CW\*(C`offset\*(C'\fR argument to
-\&\f(CW\*(C`ev_periodic_set\*(C'\fR, but indeed works even in interval and manual
-rescheduling modes.
-.IP "ev_tstamp offset [read\-write]" 4
-.IX Item "ev_tstamp offset [read-write]"
-When repeating, this contains the offset value, otherwise this is the
-absolute point in time (the \f(CW\*(C`offset\*(C'\fR value passed to \f(CW\*(C`ev_periodic_set\*(C'\fR,
-although libev might modify this value for better numerical stability).
-.Sp
-Can be modified any time, but changes only take effect when the periodic
-timer fires or \f(CW\*(C`ev_periodic_again\*(C'\fR is being called.
-.IP "ev_tstamp interval [read\-write]" 4
-.IX Item "ev_tstamp interval [read-write]"
-The current interval value. Can be modified any time, but changes only
-take effect when the periodic timer fires or \f(CW\*(C`ev_periodic_again\*(C'\fR is being
-called.
-.IP "ev_tstamp (*reschedule_cb)(ev_periodic *w, ev_tstamp now) [read\-write]" 4
-.IX Item "ev_tstamp (*reschedule_cb)(ev_periodic *w, ev_tstamp now) [read-write]"
-The current reschedule callback, or \f(CW0\fR, if this functionality is
-switched off. Can be changed any time, but changes only take effect when
-the periodic timer fires or \f(CW\*(C`ev_periodic_again\*(C'\fR is being called.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Call a callback every hour, or, more precisely, whenever the
-system time is divisible by 3600. The callback invocation times have
-potentially a lot of jitter, but good long-term stability.
-.PP
-.Vb 5
-\& static void
-\& clock_cb (struct ev_loop *loop, ev_periodic *w, int revents)
-\& {
-\& ... its now a full hour (UTC, or TAI or whatever your clock follows)
-\& }
-\&
-\& ev_periodic hourly_tick;
-\& ev_periodic_init (&hourly_tick, clock_cb, 0., 3600., 0);
-\& ev_periodic_start (loop, &hourly_tick);
-.Ve
-.PP
-Example: The same as above, but use a reschedule callback to do it:
-.PP
-.Vb 1
-\& #include <math.h>
-\&
-\& static ev_tstamp
-\& my_scheduler_cb (ev_periodic *w, ev_tstamp now)
-\& {
-\& return now + (3600. \- fmod (now, 3600.));
-\& }
-\&
-\& ev_periodic_init (&hourly_tick, clock_cb, 0., 0., my_scheduler_cb);
-.Ve
-.PP
-Example: Call a callback every hour, starting now:
-.PP
-.Vb 4
-\& ev_periodic hourly_tick;
-\& ev_periodic_init (&hourly_tick, clock_cb,
-\& fmod (ev_now (loop), 3600.), 3600., 0);
-\& ev_periodic_start (loop, &hourly_tick);
-.Ve
-.ie n .SS """ev_signal"" \- signal me when a signal gets signalled!"
-.el .SS "\f(CWev_signal\fP \- signal me when a signal gets signalled!"
-.IX Subsection "ev_signal - signal me when a signal gets signalled!"
-Signal watchers will trigger an event when the process receives a specific
-signal one or more times. Even though signals are very asynchronous, libev
-will try its best to deliver signals synchronously, i.e. as part of the
-normal event processing, like any other event.
-.PP
-If you want signals to be delivered truly asynchronously, just use
-\&\f(CW\*(C`sigaction\*(C'\fR as you would do without libev and forget about sharing
-the signal. You can even use \f(CW\*(C`ev_async\*(C'\fR from a signal handler to
-synchronously wake up an event loop.
-.PP
-You can configure as many watchers as you like for the same signal, but
-only within the same loop, i.e. you can watch for \f(CW\*(C`SIGINT\*(C'\fR in your
-default loop and for \f(CW\*(C`SIGIO\*(C'\fR in another loop, but you cannot watch for
-\&\f(CW\*(C`SIGINT\*(C'\fR in both the default loop and another loop at the same time. At
-the moment, \f(CW\*(C`SIGCHLD\*(C'\fR is permanently tied to the default loop.
-.PP
-When the first watcher gets started will libev actually register something
-with the kernel (thus it coexists with your own signal handlers as long as
-you don't register any with libev for the same signal).
-.PP
-If possible and supported, libev will install its handlers with
-\&\f(CW\*(C`SA_RESTART\*(C'\fR (or equivalent) behaviour enabled, so system calls should
-not be unduly interrupted. If you have a problem with system calls getting
-interrupted by signals you can block all signals in an \f(CW\*(C`ev_check\*(C'\fR watcher
-and unblock them in an \f(CW\*(C`ev_prepare\*(C'\fR watcher.
-.PP
-\fIThe special problem of inheritance over fork/execve/pthread_create\fR
-.IX Subsection "The special problem of inheritance over fork/execve/pthread_create"
-.PP
-Both the signal mask (\f(CW\*(C`sigprocmask\*(C'\fR) and the signal disposition
-(\f(CW\*(C`sigaction\*(C'\fR) are unspecified after starting a signal watcher (and after
-stopping it again), that is, libev might or might not block the signal,
-and might or might not set or restore the installed signal handler (but
-see \f(CW\*(C`EVFLAG_NOSIGMASK\*(C'\fR).
-.PP
-While this does not matter for the signal disposition (libev never
-sets signals to \f(CW\*(C`SIG_IGN\*(C'\fR, so handlers will be reset to \f(CW\*(C`SIG_DFL\*(C'\fR on
-\&\f(CW\*(C`execve\*(C'\fR), this matters for the signal mask: many programs do not expect
-certain signals to be blocked.
-.PP
-This means that before calling \f(CW\*(C`exec\*(C'\fR (from the child) you should reset
-the signal mask to whatever \*(L"default\*(R" you expect (all clear is a good
-choice usually).
-.PP
-The simplest way to ensure that the signal mask is reset in the child is
-to install a fork handler with \f(CW\*(C`pthread_atfork\*(C'\fR that resets it. That will
-catch fork calls done by libraries (such as the libc) as well.
-.PP
-In current versions of libev, the signal will not be blocked indefinitely
-unless you use the \f(CW\*(C`signalfd\*(C'\fR \s-1API\s0 (\f(CW\*(C`EV_SIGNALFD\*(C'\fR). While this reduces
-the window of opportunity for problems, it will not go away, as libev
-\&\fIhas\fR to modify the signal mask, at least temporarily.
-.PP
-So I can't stress this enough: \fIIf you do not reset your signal mask when
-you expect it to be empty, you have a race condition in your code\fR. This
-is not a libev-specific thing, this is true for most event libraries.
-.PP
-\fIThe special problem of threads signal handling\fR
-.IX Subsection "The special problem of threads signal handling"
-.PP
-\&\s-1POSIX\s0 threads has problematic signal handling semantics, specifically,
-a lot of functionality (sigfd, sigwait etc.) only really works if all
-threads in a process block signals, which is hard to achieve.
-.PP
-When you want to use sigwait (or mix libev signal handling with your own
-for the same signals), you can tackle this problem by globally blocking
-all signals before creating any threads (or creating them with a fully set
-sigprocmask) and also specifying the \f(CW\*(C`EVFLAG_NOSIGMASK\*(C'\fR when creating
-loops. Then designate one thread as \*(L"signal receiver thread\*(R" which handles
-these signals. You can pass on any signals that libev might be interested
-in by calling \f(CW\*(C`ev_feed_signal\*(C'\fR.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_signal_init (ev_signal *, callback, int signum)" 4
-.IX Item "ev_signal_init (ev_signal *, callback, int signum)"
-.PD 0
-.IP "ev_signal_set (ev_signal *, int signum)" 4
-.IX Item "ev_signal_set (ev_signal *, int signum)"
-.PD
-Configures the watcher to trigger on the given signal number (usually one
-of the \f(CW\*(C`SIGxxx\*(C'\fR constants).
-.IP "int signum [read\-only]" 4
-.IX Item "int signum [read-only]"
-The signal the watcher watches out for.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Try to exit cleanly on \s-1SIGINT\s0.
-.PP
-.Vb 5
-\& static void
-\& sigint_cb (struct ev_loop *loop, ev_signal *w, int revents)
-\& {
-\& ev_break (loop, EVBREAK_ALL);
-\& }
-\&
-\& ev_signal signal_watcher;
-\& ev_signal_init (&signal_watcher, sigint_cb, SIGINT);
-\& ev_signal_start (loop, &signal_watcher);
-.Ve
-.ie n .SS """ev_child"" \- watch out for process status changes"
-.el .SS "\f(CWev_child\fP \- watch out for process status changes"
-.IX Subsection "ev_child - watch out for process status changes"
-Child watchers trigger when your process receives a \s-1SIGCHLD\s0 in response to
-some child status changes (most typically when a child of yours dies or
-exits). It is permissible to install a child watcher \fIafter\fR the child
-has been forked (which implies it might have already exited), as long
-as the event loop isn't entered (or is continued from a watcher), i.e.,
-forking and then immediately registering a watcher for the child is fine,
-but forking and registering a watcher a few event loop iterations later or
-in the next callback invocation is not.
-.PP
-Only the default event loop is capable of handling signals, and therefore
-you can only register child watchers in the default event loop.
-.PP
-Due to some design glitches inside libev, child watchers will always be
-handled at maximum priority (their priority is set to \f(CW\*(C`EV_MAXPRI\*(C'\fR by
-libev)
-.PP
-\fIProcess Interaction\fR
-.IX Subsection "Process Interaction"
-.PP
-Libev grabs \f(CW\*(C`SIGCHLD\*(C'\fR as soon as the default event loop is
-initialised. This is necessary to guarantee proper behaviour even if the
-first child watcher is started after the child exits. The occurrence
-of \f(CW\*(C`SIGCHLD\*(C'\fR is recorded asynchronously, but child reaping is done
-synchronously as part of the event loop processing. Libev always reaps all
-children, even ones not watched.
-.PP
-\fIOverriding the Built-In Processing\fR
-.IX Subsection "Overriding the Built-In Processing"
-.PP
-Libev offers no special support for overriding the built-in child
-processing, but if your application collides with libev's default child
-handler, you can override it easily by installing your own handler for
-\&\f(CW\*(C`SIGCHLD\*(C'\fR after initialising the default loop, and making sure the
-default loop never gets destroyed. You are encouraged, however, to use an
-event-based approach to child reaping and thus use libev's support for
-that, so other libev users can use \f(CW\*(C`ev_child\*(C'\fR watchers freely.
-.PP
-\fIStopping the Child Watcher\fR
-.IX Subsection "Stopping the Child Watcher"
-.PP
-Currently, the child watcher never gets stopped, even when the
-child terminates, so normally one needs to stop the watcher in the
-callback. Future versions of libev might stop the watcher automatically
-when a child exit is detected (calling \f(CW\*(C`ev_child_stop\*(C'\fR twice is not a
-problem).
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_child_init (ev_child *, callback, int pid, int trace)" 4
-.IX Item "ev_child_init (ev_child *, callback, int pid, int trace)"
-.PD 0
-.IP "ev_child_set (ev_child *, int pid, int trace)" 4
-.IX Item "ev_child_set (ev_child *, int pid, int trace)"
-.PD
-Configures the watcher to wait for status changes of process \f(CW\*(C`pid\*(C'\fR (or
-\&\fIany\fR process if \f(CW\*(C`pid\*(C'\fR is specified as \f(CW0\fR). The callback can look
-at the \f(CW\*(C`rstatus\*(C'\fR member of the \f(CW\*(C`ev_child\*(C'\fR watcher structure to see
-the status word (use the macros from \f(CW\*(C`sys/wait.h\*(C'\fR and see your systems
-\&\f(CW\*(C`waitpid\*(C'\fR documentation). The \f(CW\*(C`rpid\*(C'\fR member contains the pid of the
-process causing the status change. \f(CW\*(C`trace\*(C'\fR must be either \f(CW0\fR (only
-activate the watcher when the process terminates) or \f(CW1\fR (additionally
-activate the watcher when the process is stopped or continued).
-.IP "int pid [read\-only]" 4
-.IX Item "int pid [read-only]"
-The process id this watcher watches out for, or \f(CW0\fR, meaning any process id.
-.IP "int rpid [read\-write]" 4
-.IX Item "int rpid [read-write]"
-The process id that detected a status change.
-.IP "int rstatus [read\-write]" 4
-.IX Item "int rstatus [read-write]"
-The process exit/trace status caused by \f(CW\*(C`rpid\*(C'\fR (see your systems
-\&\f(CW\*(C`waitpid\*(C'\fR and \f(CW\*(C`sys/wait.h\*(C'\fR documentation for details).
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: \f(CW\*(C`fork()\*(C'\fR a new process and install a child handler to wait for
-its completion.
-.PP
-.Vb 1
-\& ev_child cw;
-\&
-\& static void
-\& child_cb (EV_P_ ev_child *w, int revents)
-\& {
-\& ev_child_stop (EV_A_ w);
-\& printf ("process %d exited with status %x\en", w\->rpid, w\->rstatus);
-\& }
-\&
-\& pid_t pid = fork ();
-\&
-\& if (pid < 0)
-\& // error
-\& else if (pid == 0)
-\& {
-\& // the forked child executes here
-\& exit (1);
-\& }
-\& else
-\& {
-\& ev_child_init (&cw, child_cb, pid, 0);
-\& ev_child_start (EV_DEFAULT_ &cw);
-\& }
-.Ve
-.ie n .SS """ev_stat"" \- did the file attributes just change?"
-.el .SS "\f(CWev_stat\fP \- did the file attributes just change?"
-.IX Subsection "ev_stat - did the file attributes just change?"
-This watches a file system path for attribute changes. That is, it calls
-\&\f(CW\*(C`stat\*(C'\fR on that path in regular intervals (or when the \s-1OS\s0 says it changed)
-and sees if it changed compared to the last time, invoking the callback if
-it did.
-.PP
-The path does not need to exist: changing from \*(L"path exists\*(R" to \*(L"path does
-not exist\*(R" is a status change like any other. The condition \*(L"path does not
-exist\*(R" (or more correctly \*(L"path cannot be stat'ed\*(R") is signified by the
-\&\f(CW\*(C`st_nlink\*(C'\fR field being zero (which is otherwise always forced to be at
-least one) and all the other fields of the stat buffer having unspecified
-contents.
-.PP
-The path \fImust not\fR end in a slash or contain special components such as
-\&\f(CW\*(C`.\*(C'\fR or \f(CW\*(C`..\*(C'\fR. The path \fIshould\fR be absolute: If it is relative and
-your working directory changes, then the behaviour is undefined.
-.PP
-Since there is no portable change notification interface available, the
-portable implementation simply calls \f(CWstat(2)\fR regularly on the path
-to see if it changed somehow. You can specify a recommended polling
-interval for this case. If you specify a polling interval of \f(CW0\fR (highly
-recommended!) then a \fIsuitable, unspecified default\fR value will be used
-(which you can expect to be around five seconds, although this might
-change dynamically). Libev will also impose a minimum interval which is
-currently around \f(CW0.1\fR, but that's usually overkill.
-.PP
-This watcher type is not meant for massive numbers of stat watchers,
-as even with OS-supported change notifications, this can be
-resource-intensive.
-.PP
-At the time of this writing, the only OS-specific interface implemented
-is the Linux inotify interface (implementing kqueue support is left as an
-exercise for the reader. Note, however, that the author sees no way of
-implementing \f(CW\*(C`ev_stat\*(C'\fR semantics with kqueue, except as a hint).
-.PP
-\fI\s-1ABI\s0 Issues (Largefile Support)\fR
-.IX Subsection "ABI Issues (Largefile Support)"
-.PP
-Libev by default (unless the user overrides this) uses the default
-compilation environment, which means that on systems with large file
-support disabled by default, you get the 32 bit version of the stat
-structure. When using the library from programs that change the \s-1ABI\s0 to
-use 64 bit file offsets the programs will fail. In that case you have to
-compile libev with the same flags to get binary compatibility. This is
-obviously the case with any flags that change the \s-1ABI\s0, but the problem is
-most noticeably displayed with ev_stat and large file support.
-.PP
-The solution for this is to lobby your distribution maker to make large
-file interfaces available by default (as e.g. FreeBSD does) and not
-optional. Libev cannot simply switch on large file support because it has
-to exchange stat structures with application programs compiled using the
-default compilation environment.
-.PP
-\fIInotify and Kqueue\fR
-.IX Subsection "Inotify and Kqueue"
-.PP
-When \f(CW\*(C`inotify (7)\*(C'\fR support has been compiled into libev and present at
-runtime, it will be used to speed up change detection where possible. The
-inotify descriptor will be created lazily when the first \f(CW\*(C`ev_stat\*(C'\fR
-watcher is being started.
-.PP
-Inotify presence does not change the semantics of \f(CW\*(C`ev_stat\*(C'\fR watchers
-except that changes might be detected earlier, and in some cases, to avoid
-making regular \f(CW\*(C`stat\*(C'\fR calls. Even in the presence of inotify support
-there are many cases where libev has to resort to regular \f(CW\*(C`stat\*(C'\fR polling,
-but as long as kernel 2.6.25 or newer is used (2.6.24 and older have too
-many bugs), the path exists (i.e. stat succeeds), and the path resides on
-a local filesystem (libev currently assumes only ext2/3, jfs, reiserfs and
-xfs are fully working) libev usually gets away without polling.
-.PP
-There is no support for kqueue, as apparently it cannot be used to
-implement this functionality, due to the requirement of having a file
-descriptor open on the object at all times, and detecting renames, unlinks
-etc. is difficult.
-.PP
-\fI\f(CI\*(C`stat ()\*(C'\fI is a synchronous operation\fR
-.IX Subsection "stat () is a synchronous operation"
-.PP
-Libev doesn't normally do any kind of I/O itself, and so is not blocking
-the process. The exception are \f(CW\*(C`ev_stat\*(C'\fR watchers \- those call \f(CW\*(C`stat
-()\*(C'\fR, which is a synchronous operation.
-.PP
-For local paths, this usually doesn't matter: unless the system is very
-busy or the intervals between stat's are large, a stat call will be fast,
-as the path data is usually in memory already (except when starting the
-watcher).
-.PP
-For networked file systems, calling \f(CW\*(C`stat ()\*(C'\fR can block an indefinite
-time due to network issues, and even under good conditions, a stat call
-often takes multiple milliseconds.
-.PP
-Therefore, it is best to avoid using \f(CW\*(C`ev_stat\*(C'\fR watchers on networked
-paths, although this is fully supported by libev.
-.PP
-\fIThe special problem of stat time resolution\fR
-.IX Subsection "The special problem of stat time resolution"
-.PP
-The \f(CW\*(C`stat ()\*(C'\fR system call only supports full-second resolution portably,
-and even on systems where the resolution is higher, most file systems
-still only support whole seconds.
-.PP
-That means that, if the time is the only thing that changes, you can
-easily miss updates: on the first update, \f(CW\*(C`ev_stat\*(C'\fR detects a change and
-calls your callback, which does something. When there is another update
-within the same second, \f(CW\*(C`ev_stat\*(C'\fR will be unable to detect unless the
-stat data does change in other ways (e.g. file size).
-.PP
-The solution to this is to delay acting on a change for slightly more
-than a second (or till slightly after the next full second boundary), using
-a roughly one-second-delay \f(CW\*(C`ev_timer\*(C'\fR (e.g. \f(CW\*(C`ev_timer_set (w, 0., 1.02);
-ev_timer_again (loop, w)\*(C'\fR).
-.PP
-The \f(CW.02\fR offset is added to work around small timing inconsistencies
-of some operating systems (where the second counter of the current time
-might be be delayed. One such system is the Linux kernel, where a call to
-\&\f(CW\*(C`gettimeofday\*(C'\fR might return a timestamp with a full second later than
-a subsequent \f(CW\*(C`time\*(C'\fR call \- if the equivalent of \f(CW\*(C`time ()\*(C'\fR is used to
-update file times then there will be a small window where the kernel uses
-the previous second to update file times but libev might already execute
-the timer callback).
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_stat_init (ev_stat *, callback, const char *path, ev_tstamp interval)" 4
-.IX Item "ev_stat_init (ev_stat *, callback, const char *path, ev_tstamp interval)"
-.PD 0
-.IP "ev_stat_set (ev_stat *, const char *path, ev_tstamp interval)" 4
-.IX Item "ev_stat_set (ev_stat *, const char *path, ev_tstamp interval)"
-.PD
-Configures the watcher to wait for status changes of the given
-\&\f(CW\*(C`path\*(C'\fR. The \f(CW\*(C`interval\*(C'\fR is a hint on how quickly a change is expected to
-be detected and should normally be specified as \f(CW0\fR to let libev choose
-a suitable value. The memory pointed to by \f(CW\*(C`path\*(C'\fR must point to the same
-path for as long as the watcher is active.
-.Sp
-The callback will receive an \f(CW\*(C`EV_STAT\*(C'\fR event when a change was detected,
-relative to the attributes at the time the watcher was started (or the
-last change was detected).
-.IP "ev_stat_stat (loop, ev_stat *)" 4
-.IX Item "ev_stat_stat (loop, ev_stat *)"
-Updates the stat buffer immediately with new values. If you change the
-watched path in your callback, you could call this function to avoid
-detecting this change (while introducing a race condition if you are not
-the only one changing the path). Can also be useful simply to find out the
-new values.
-.IP "ev_statdata attr [read\-only]" 4
-.IX Item "ev_statdata attr [read-only]"
-The most-recently detected attributes of the file. Although the type is
-\&\f(CW\*(C`ev_statdata\*(C'\fR, this is usually the (or one of the) \f(CW\*(C`struct stat\*(C'\fR types
-suitable for your system, but you can only rely on the POSIX-standardised
-members to be present. If the \f(CW\*(C`st_nlink\*(C'\fR member is \f(CW0\fR, then there was
-some error while \f(CW\*(C`stat\*(C'\fRing the file.
-.IP "ev_statdata prev [read\-only]" 4
-.IX Item "ev_statdata prev [read-only]"
-The previous attributes of the file. The callback gets invoked whenever
-\&\f(CW\*(C`prev\*(C'\fR != \f(CW\*(C`attr\*(C'\fR, or, more precisely, one or more of these members
-differ: \f(CW\*(C`st_dev\*(C'\fR, \f(CW\*(C`st_ino\*(C'\fR, \f(CW\*(C`st_mode\*(C'\fR, \f(CW\*(C`st_nlink\*(C'\fR, \f(CW\*(C`st_uid\*(C'\fR,
-\&\f(CW\*(C`st_gid\*(C'\fR, \f(CW\*(C`st_rdev\*(C'\fR, \f(CW\*(C`st_size\*(C'\fR, \f(CW\*(C`st_atime\*(C'\fR, \f(CW\*(C`st_mtime\*(C'\fR, \f(CW\*(C`st_ctime\*(C'\fR.
-.IP "ev_tstamp interval [read\-only]" 4
-.IX Item "ev_tstamp interval [read-only]"
-The specified interval.
-.IP "const char *path [read\-only]" 4
-.IX Item "const char *path [read-only]"
-The file system path that is being watched.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Watch \f(CW\*(C`/etc/passwd\*(C'\fR for attribute changes.
-.PP
-.Vb 10
-\& static void
-\& passwd_cb (struct ev_loop *loop, ev_stat *w, int revents)
-\& {
-\& /* /etc/passwd changed in some way */
-\& if (w\->attr.st_nlink)
-\& {
-\& printf ("passwd current size %ld\en", (long)w\->attr.st_size);
-\& printf ("passwd current atime %ld\en", (long)w\->attr.st_mtime);
-\& printf ("passwd current mtime %ld\en", (long)w\->attr.st_mtime);
-\& }
-\& else
-\& /* you shalt not abuse printf for puts */
-\& puts ("wow, /etc/passwd is not there, expect problems. "
-\& "if this is windows, they already arrived\en");
-\& }
-\&
-\& ...
-\& ev_stat passwd;
-\&
-\& ev_stat_init (&passwd, passwd_cb, "/etc/passwd", 0.);
-\& ev_stat_start (loop, &passwd);
-.Ve
-.PP
-Example: Like above, but additionally use a one-second delay so we do not
-miss updates (however, frequent updates will delay processing, too, so
-one might do the work both on \f(CW\*(C`ev_stat\*(C'\fR callback invocation \fIand\fR on
-\&\f(CW\*(C`ev_timer\*(C'\fR callback invocation).
-.PP
-.Vb 2
-\& static ev_stat passwd;
-\& static ev_timer timer;
-\&
-\& static void
-\& timer_cb (EV_P_ ev_timer *w, int revents)
-\& {
-\& ev_timer_stop (EV_A_ w);
-\&
-\& /* now it\*(Aqs one second after the most recent passwd change */
-\& }
-\&
-\& static void
-\& stat_cb (EV_P_ ev_stat *w, int revents)
-\& {
-\& /* reset the one\-second timer */
-\& ev_timer_again (EV_A_ &timer);
-\& }
-\&
-\& ...
-\& ev_stat_init (&passwd, stat_cb, "/etc/passwd", 0.);
-\& ev_stat_start (loop, &passwd);
-\& ev_timer_init (&timer, timer_cb, 0., 1.02);
-.Ve
-.ie n .SS """ev_idle"" \- when you've got nothing better to do..."
-.el .SS "\f(CWev_idle\fP \- when you've got nothing better to do..."
-.IX Subsection "ev_idle - when you've got nothing better to do..."
-Idle watchers trigger events when no other events of the same or higher
-priority are pending (prepare, check and other idle watchers do not count
-as receiving \*(L"events\*(R").
-.PP
-That is, as long as your process is busy handling sockets or timeouts
-(or even signals, imagine) of the same or higher priority it will not be
-triggered. But when your process is idle (or only lower-priority watchers
-are pending), the idle watchers are being called once per event loop
-iteration \- until stopped, that is, or your process receives more events
-and becomes busy again with higher priority stuff.
-.PP
-The most noteworthy effect is that as long as any idle watchers are
-active, the process will not block when waiting for new events.
-.PP
-Apart from keeping your process non-blocking (which is a useful
-effect on its own sometimes), idle watchers are a good place to do
-\&\*(L"pseudo-background processing\*(R", or delay processing stuff to after the
-event loop has handled all outstanding events.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_idle_init (ev_idle *, callback)" 4
-.IX Item "ev_idle_init (ev_idle *, callback)"
-Initialises and configures the idle watcher \- it has no parameters of any
-kind. There is a \f(CW\*(C`ev_idle_set\*(C'\fR macro, but using it is utterly pointless,
-believe me.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Dynamically allocate an \f(CW\*(C`ev_idle\*(C'\fR watcher, start it, and in the
-callback, free it. Also, use no error checking, as usual.
-.PP
-.Vb 7
-\& static void
-\& idle_cb (struct ev_loop *loop, ev_idle *w, int revents)
-\& {
-\& free (w);
-\& // now do something you wanted to do when the program has
-\& // no longer anything immediate to do.
-\& }
-\&
-\& ev_idle *idle_watcher = malloc (sizeof (ev_idle));
-\& ev_idle_init (idle_watcher, idle_cb);
-\& ev_idle_start (loop, idle_watcher);
-.Ve
-.ie n .SS """ev_prepare"" and ""ev_check"" \- customise your event loop!"
-.el .SS "\f(CWev_prepare\fP and \f(CWev_check\fP \- customise your event loop!"
-.IX Subsection "ev_prepare and ev_check - customise your event loop!"
-Prepare and check watchers are usually (but not always) used in pairs:
-prepare watchers get invoked before the process blocks and check watchers
-afterwards.
-.PP
-You \fImust not\fR call \f(CW\*(C`ev_run\*(C'\fR or similar functions that enter
-the current event loop from either \f(CW\*(C`ev_prepare\*(C'\fR or \f(CW\*(C`ev_check\*(C'\fR
-watchers. Other loops than the current one are fine, however. The
-rationale behind this is that you do not need to check for recursion in
-those watchers, i.e. the sequence will always be \f(CW\*(C`ev_prepare\*(C'\fR, blocking,
-\&\f(CW\*(C`ev_check\*(C'\fR so if you have one watcher of each kind they will always be
-called in pairs bracketing the blocking call.
-.PP
-Their main purpose is to integrate other event mechanisms into libev and
-their use is somewhat advanced. They could be used, for example, to track
-variable changes, implement your own watchers, integrate net-snmp or a
-coroutine library and lots more. They are also occasionally useful if
-you cache some data and want to flush it before blocking (for example,
-in X programs you might want to do an \f(CW\*(C`XFlush ()\*(C'\fR in an \f(CW\*(C`ev_prepare\*(C'\fR
-watcher).
-.PP
-This is done by examining in each prepare call which file descriptors
-need to be watched by the other library, registering \f(CW\*(C`ev_io\*(C'\fR watchers
-for them and starting an \f(CW\*(C`ev_timer\*(C'\fR watcher for any timeouts (many
-libraries provide exactly this functionality). Then, in the check watcher,
-you check for any events that occurred (by checking the pending status
-of all watchers and stopping them) and call back into the library. The
-I/O and timer callbacks will never actually be called (but must be valid
-nevertheless, because you never know, you know?).
-.PP
-As another example, the Perl Coro module uses these hooks to integrate
-coroutines into libev programs, by yielding to other active coroutines
-during each prepare and only letting the process block if no coroutines
-are ready to run (it's actually more complicated: it only runs coroutines
-with priority higher than or equal to the event loop and one coroutine
-of lower priority, but only once, using idle watchers to keep the event
-loop from blocking if lower-priority coroutines are active, thus mapping
-low-priority coroutines to idle/background tasks).
-.PP
-It is recommended to give \f(CW\*(C`ev_check\*(C'\fR watchers highest (\f(CW\*(C`EV_MAXPRI\*(C'\fR)
-priority, to ensure that they are being run before any other watchers
-after the poll (this doesn't matter for \f(CW\*(C`ev_prepare\*(C'\fR watchers).
-.PP
-Also, \f(CW\*(C`ev_check\*(C'\fR watchers (and \f(CW\*(C`ev_prepare\*(C'\fR watchers, too) should not
-activate (\*(L"feed\*(R") events into libev. While libev fully supports this, they
-might get executed before other \f(CW\*(C`ev_check\*(C'\fR watchers did their job. As
-\&\f(CW\*(C`ev_check\*(C'\fR watchers are often used to embed other (non-libev) event
-loops those other event loops might be in an unusable state until their
-\&\f(CW\*(C`ev_check\*(C'\fR watcher ran (always remind yourself to coexist peacefully with
-others).
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_prepare_init (ev_prepare *, callback)" 4
-.IX Item "ev_prepare_init (ev_prepare *, callback)"
-.PD 0
-.IP "ev_check_init (ev_check *, callback)" 4
-.IX Item "ev_check_init (ev_check *, callback)"
-.PD
-Initialises and configures the prepare or check watcher \- they have no
-parameters of any kind. There are \f(CW\*(C`ev_prepare_set\*(C'\fR and \f(CW\*(C`ev_check_set\*(C'\fR
-macros, but using them is utterly, utterly, utterly and completely
-pointless.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-There are a number of principal ways to embed other event loops or modules
-into libev. Here are some ideas on how to include libadns into libev
-(there is a Perl module named \f(CW\*(C`EV::ADNS\*(C'\fR that does this, which you could
-use as a working example. Another Perl module named \f(CW\*(C`EV::Glib\*(C'\fR embeds a
-Glib main context into libev, and finally, \f(CW\*(C`Glib::EV\*(C'\fR embeds \s-1EV\s0 into the
-Glib event loop).
-.PP
-Method 1: Add \s-1IO\s0 watchers and a timeout watcher in a prepare handler,
-and in a check watcher, destroy them and call into libadns. What follows
-is pseudo-code only of course. This requires you to either use a low
-priority for the check watcher or use \f(CW\*(C`ev_clear_pending\*(C'\fR explicitly, as
-the callbacks for the IO/timeout watchers might not have been called yet.
-.PP
-.Vb 2
-\& static ev_io iow [nfd];
-\& static ev_timer tw;
-\&
-\& static void
-\& io_cb (struct ev_loop *loop, ev_io *w, int revents)
-\& {
-\& }
-\&
-\& // create io watchers for each fd and a timer before blocking
-\& static void
-\& adns_prepare_cb (struct ev_loop *loop, ev_prepare *w, int revents)
-\& {
-\& int timeout = 3600000;
-\& struct pollfd fds [nfd];
-\& // actual code will need to loop here and realloc etc.
-\& adns_beforepoll (ads, fds, &nfd, &timeout, timeval_from (ev_time ()));
-\&
-\& /* the callback is illegal, but won\*(Aqt be called as we stop during check */
-\& ev_timer_init (&tw, 0, timeout * 1e\-3, 0.);
-\& ev_timer_start (loop, &tw);
-\&
-\& // create one ev_io per pollfd
-\& for (int i = 0; i < nfd; ++i)
-\& {
-\& ev_io_init (iow + i, io_cb, fds [i].fd,
-\& ((fds [i].events & POLLIN ? EV_READ : 0)
-\& | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
-\&
-\& fds [i].revents = 0;
-\& ev_io_start (loop, iow + i);
-\& }
-\& }
-\&
-\& // stop all watchers after blocking
-\& static void
-\& adns_check_cb (struct ev_loop *loop, ev_check *w, int revents)
-\& {
-\& ev_timer_stop (loop, &tw);
-\&
-\& for (int i = 0; i < nfd; ++i)
-\& {
-\& // set the relevant poll flags
-\& // could also call adns_processreadable etc. here
-\& struct pollfd *fd = fds + i;
-\& int revents = ev_clear_pending (iow + i);
-\& if (revents & EV_READ ) fd\->revents |= fd\->events & POLLIN;
-\& if (revents & EV_WRITE) fd\->revents |= fd\->events & POLLOUT;
-\&
-\& // now stop the watcher
-\& ev_io_stop (loop, iow + i);
-\& }
-\&
-\& adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop));
-\& }
-.Ve
-.PP
-Method 2: This would be just like method 1, but you run \f(CW\*(C`adns_afterpoll\*(C'\fR
-in the prepare watcher and would dispose of the check watcher.
-.PP
-Method 3: If the module to be embedded supports explicit event
-notification (libadns does), you can also make use of the actual watcher
-callbacks, and only destroy/create the watchers in the prepare watcher.
-.PP
-.Vb 5
-\& static void
-\& timer_cb (EV_P_ ev_timer *w, int revents)
-\& {
-\& adns_state ads = (adns_state)w\->data;
-\& update_now (EV_A);
-\&
-\& adns_processtimeouts (ads, &tv_now);
-\& }
-\&
-\& static void
-\& io_cb (EV_P_ ev_io *w, int revents)
-\& {
-\& adns_state ads = (adns_state)w\->data;
-\& update_now (EV_A);
-\&
-\& if (revents & EV_READ ) adns_processreadable (ads, w\->fd, &tv_now);
-\& if (revents & EV_WRITE) adns_processwriteable (ads, w\->fd, &tv_now);
-\& }
-\&
-\& // do not ever call adns_afterpoll
-.Ve
-.PP
-Method 4: Do not use a prepare or check watcher because the module you
-want to embed is not flexible enough to support it. Instead, you can
-override their poll function. The drawback with this solution is that the
-main loop is now no longer controllable by \s-1EV\s0. The \f(CW\*(C`Glib::EV\*(C'\fR module uses
-this approach, effectively embedding \s-1EV\s0 as a client into the horrible
-libglib event loop.
-.PP
-.Vb 4
-\& static gint
-\& event_poll_func (GPollFD *fds, guint nfds, gint timeout)
-\& {
-\& int got_events = 0;
-\&
-\& for (n = 0; n < nfds; ++n)
-\& // create/start io watcher that sets the relevant bits in fds[n] and increment got_events
-\&
-\& if (timeout >= 0)
-\& // create/start timer
-\&
-\& // poll
-\& ev_run (EV_A_ 0);
-\&
-\& // stop timer again
-\& if (timeout >= 0)
-\& ev_timer_stop (EV_A_ &to);
-\&
-\& // stop io watchers again \- their callbacks should have set
-\& for (n = 0; n < nfds; ++n)
-\& ev_io_stop (EV_A_ iow [n]);
-\&
-\& return got_events;
-\& }
-.Ve
-.ie n .SS """ev_embed"" \- when one backend isn't enough..."
-.el .SS "\f(CWev_embed\fP \- when one backend isn't enough..."
-.IX Subsection "ev_embed - when one backend isn't enough..."
-This is a rather advanced watcher type that lets you embed one event loop
-into another (currently only \f(CW\*(C`ev_io\*(C'\fR events are supported in the embedded
-loop, other types of watchers might be handled in a delayed or incorrect
-fashion and must not be used).
-.PP
-There are primarily two reasons you would want that: work around bugs and
-prioritise I/O.
-.PP
-As an example for a bug workaround, the kqueue backend might only support
-sockets on some platform, so it is unusable as generic backend, but you
-still want to make use of it because you have many sockets and it scales
-so nicely. In this case, you would create a kqueue-based loop and embed
-it into your default loop (which might use e.g. poll). Overall operation
-will be a bit slower because first libev has to call \f(CW\*(C`poll\*(C'\fR and then
-\&\f(CW\*(C`kevent\*(C'\fR, but at least you can use both mechanisms for what they are
-best: \f(CW\*(C`kqueue\*(C'\fR for scalable sockets and \f(CW\*(C`poll\*(C'\fR if you want it to work :)
-.PP
-As for prioritising I/O: under rare circumstances you have the case where
-some fds have to be watched and handled very quickly (with low latency),
-and even priorities and idle watchers might have too much overhead. In
-this case you would put all the high priority stuff in one loop and all
-the rest in a second one, and embed the second one in the first.
-.PP
-As long as the watcher is active, the callback will be invoked every
-time there might be events pending in the embedded loop. The callback
-must then call \f(CW\*(C`ev_embed_sweep (mainloop, watcher)\*(C'\fR to make a single
-sweep and invoke their callbacks (the callback doesn't need to invoke the
-\&\f(CW\*(C`ev_embed_sweep\*(C'\fR function directly, it could also start an idle watcher
-to give the embedded loop strictly lower priority for example).
-.PP
-You can also set the callback to \f(CW0\fR, in which case the embed watcher
-will automatically execute the embedded loop sweep whenever necessary.
-.PP
-Fork detection will be handled transparently while the \f(CW\*(C`ev_embed\*(C'\fR watcher
-is active, i.e., the embedded loop will automatically be forked when the
-embedding loop forks. In other cases, the user is responsible for calling
-\&\f(CW\*(C`ev_loop_fork\*(C'\fR on the embedded loop.
-.PP
-Unfortunately, not all backends are embeddable: only the ones returned by
-\&\f(CW\*(C`ev_embeddable_backends\*(C'\fR are, which, unfortunately, does not include any
-portable one.
-.PP
-So when you want to use this feature you will always have to be prepared
-that you cannot get an embeddable loop. The recommended way to get around
-this is to have a separate variables for your embeddable loop, try to
-create it, and if that fails, use the normal loop for everything.
-.PP
-\fI\f(CI\*(C`ev_embed\*(C'\fI and fork\fR
-.IX Subsection "ev_embed and fork"
-.PP
-While the \f(CW\*(C`ev_embed\*(C'\fR watcher is running, forks in the embedding loop will
-automatically be applied to the embedded loop as well, so no special
-fork handling is required in that case. When the watcher is not running,
-however, it is still the task of the libev user to call \f(CW\*(C`ev_loop_fork ()\*(C'\fR
-as applicable.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)" 4
-.IX Item "ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)"
-.PD 0
-.IP "ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)" 4
-.IX Item "ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)"
-.PD
-Configures the watcher to embed the given loop, which must be
-embeddable. If the callback is \f(CW0\fR, then \f(CW\*(C`ev_embed_sweep\*(C'\fR will be
-invoked automatically, otherwise it is the responsibility of the callback
-to invoke it (it will continue to be called until the sweep has been done,
-if you do not want that, you need to temporarily stop the embed watcher).
-.IP "ev_embed_sweep (loop, ev_embed *)" 4
-.IX Item "ev_embed_sweep (loop, ev_embed *)"
-Make a single, non-blocking sweep over the embedded loop. This works
-similarly to \f(CW\*(C`ev_run (embedded_loop, EVRUN_NOWAIT)\*(C'\fR, but in the most
-appropriate way for embedded loops.
-.IP "struct ev_loop *other [read\-only]" 4
-.IX Item "struct ev_loop *other [read-only]"
-The embedded event loop.
-.PP
-\fIExamples\fR
-.IX Subsection "Examples"
-.PP
-Example: Try to get an embeddable event loop and embed it into the default
-event loop. If that is not possible, use the default loop. The default
-loop is stored in \f(CW\*(C`loop_hi\*(C'\fR, while the embeddable loop is stored in
-\&\f(CW\*(C`loop_lo\*(C'\fR (which is \f(CW\*(C`loop_hi\*(C'\fR in the case no embeddable loop can be
-used).
-.PP
-.Vb 3
-\& struct ev_loop *loop_hi = ev_default_init (0);
-\& struct ev_loop *loop_lo = 0;
-\& ev_embed embed;
-\&
-\& // see if there is a chance of getting one that works
-\& // (remember that a flags value of 0 means autodetection)
-\& loop_lo = ev_embeddable_backends () & ev_recommended_backends ()
-\& ? ev_loop_new (ev_embeddable_backends () & ev_recommended_backends ())
-\& : 0;
-\&
-\& // if we got one, then embed it, otherwise default to loop_hi
-\& if (loop_lo)
-\& {
-\& ev_embed_init (&embed, 0, loop_lo);
-\& ev_embed_start (loop_hi, &embed);
-\& }
-\& else
-\& loop_lo = loop_hi;
-.Ve
-.PP
-Example: Check if kqueue is available but not recommended and create
-a kqueue backend for use with sockets (which usually work with any
-kqueue implementation). Store the kqueue/socket\-only event loop in
-\&\f(CW\*(C`loop_socket\*(C'\fR. (One might optionally use \f(CW\*(C`EVFLAG_NOENV\*(C'\fR, too).
-.PP
-.Vb 3
-\& struct ev_loop *loop = ev_default_init (0);
-\& struct ev_loop *loop_socket = 0;
-\& ev_embed embed;
-\&
-\& if (ev_supported_backends () & ~ev_recommended_backends () & EVBACKEND_KQUEUE)
-\& if ((loop_socket = ev_loop_new (EVBACKEND_KQUEUE))
-\& {
-\& ev_embed_init (&embed, 0, loop_socket);
-\& ev_embed_start (loop, &embed);
-\& }
-\&
-\& if (!loop_socket)
-\& loop_socket = loop;
-\&
-\& // now use loop_socket for all sockets, and loop for everything else
-.Ve
-.ie n .SS """ev_fork"" \- the audacity to resume the event loop after a fork"
-.el .SS "\f(CWev_fork\fP \- the audacity to resume the event loop after a fork"
-.IX Subsection "ev_fork - the audacity to resume the event loop after a fork"
-Fork watchers are called when a \f(CW\*(C`fork ()\*(C'\fR was detected (usually because
-whoever is a good citizen cared to tell libev about it by calling
-\&\f(CW\*(C`ev_default_fork\*(C'\fR or \f(CW\*(C`ev_loop_fork\*(C'\fR). The invocation is done before the
-event loop blocks next and before \f(CW\*(C`ev_check\*(C'\fR watchers are being called,
-and only in the child after the fork. If whoever good citizen calling
-\&\f(CW\*(C`ev_default_fork\*(C'\fR cheats and calls it in the wrong process, the fork
-handlers will be invoked, too, of course.
-.PP
-\fIThe special problem of life after fork \- how is it possible?\fR
-.IX Subsection "The special problem of life after fork - how is it possible?"
-.PP
-Most uses of \f(CW\*(C`fork()\*(C'\fR consist of forking, then some simple calls to set
-up/change the process environment, followed by a call to \f(CW\*(C`exec()\*(C'\fR. This
-sequence should be handled by libev without any problems.
-.PP
-This changes when the application actually wants to do event handling
-in the child, or both parent in child, in effect \*(L"continuing\*(R" after the
-fork.
-.PP
-The default mode of operation (for libev, with application help to detect
-forks) is to duplicate all the state in the child, as would be expected
-when \fIeither\fR the parent \fIor\fR the child process continues.
-.PP
-When both processes want to continue using libev, then this is usually the
-wrong result. In that case, usually one process (typically the parent) is
-supposed to continue with all watchers in place as before, while the other
-process typically wants to start fresh, i.e. without any active watchers.
-.PP
-The cleanest and most efficient way to achieve that with libev is to
-simply create a new event loop, which of course will be \*(L"empty\*(R", and
-use that for new watchers. This has the advantage of not touching more
-memory than necessary, and thus avoiding the copy-on-write, and the
-disadvantage of having to use multiple event loops (which do not support
-signal watchers).
-.PP
-When this is not possible, or you want to use the default loop for
-other reasons, then in the process that wants to start \*(L"fresh\*(R", call
-\&\f(CW\*(C`ev_loop_destroy (EV_DEFAULT)\*(C'\fR followed by \f(CW\*(C`ev_default_loop (...)\*(C'\fR.
-Destroying the default loop will \*(L"orphan\*(R" (not stop) all registered
-watchers, so you have to be careful not to execute code that modifies
-those watchers. Note also that in that case, you have to re-register any
-signal watchers.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_fork_init (ev_fork *, callback)" 4
-.IX Item "ev_fork_init (ev_fork *, callback)"
-Initialises and configures the fork watcher \- it has no parameters of any
-kind. There is a \f(CW\*(C`ev_fork_set\*(C'\fR macro, but using it is utterly pointless,
-really.
-.ie n .SS """ev_cleanup"" \- even the best things end"
-.el .SS "\f(CWev_cleanup\fP \- even the best things end"
-.IX Subsection "ev_cleanup - even the best things end"
-Cleanup watchers are called just before the event loop is being destroyed
-by a call to \f(CW\*(C`ev_loop_destroy\*(C'\fR.
-.PP
-While there is no guarantee that the event loop gets destroyed, cleanup
-watchers provide a convenient method to install cleanup hooks for your
-program, worker threads and so on \- you just to make sure to destroy the
-loop when you want them to be invoked.
-.PP
-Cleanup watchers are invoked in the same way as any other watcher. Unlike
-all other watchers, they do not keep a reference to the event loop (which
-makes a lot of sense if you think about it). Like all other watchers, you
-can call libev functions in the callback, except \f(CW\*(C`ev_cleanup_start\*(C'\fR.
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_cleanup_init (ev_cleanup *, callback)" 4
-.IX Item "ev_cleanup_init (ev_cleanup *, callback)"
-Initialises and configures the cleanup watcher \- it has no parameters of
-any kind. There is a \f(CW\*(C`ev_cleanup_set\*(C'\fR macro, but using it is utterly
-pointless, I assure you.
-.PP
-Example: Register an atexit handler to destroy the default loop, so any
-cleanup functions are called.
-.PP
-.Vb 5
-\& static void
-\& program_exits (void)
-\& {
-\& ev_loop_destroy (EV_DEFAULT_UC);
-\& }
-\&
-\& ...
-\& atexit (program_exits);
-.Ve
-.ie n .SS """ev_async"" \- how to wake up an event loop"
-.el .SS "\f(CWev_async\fP \- how to wake up an event loop"
-.IX Subsection "ev_async - how to wake up an event loop"
-In general, you cannot use an \f(CW\*(C`ev_loop\*(C'\fR from multiple threads or other
-asynchronous sources such as signal handlers (as opposed to multiple event
-loops \- those are of course safe to use in different threads).
-.PP
-Sometimes, however, you need to wake up an event loop you do not control,
-for example because it belongs to another thread. This is what \f(CW\*(C`ev_async\*(C'\fR
-watchers do: as long as the \f(CW\*(C`ev_async\*(C'\fR watcher is active, you can signal
-it by calling \f(CW\*(C`ev_async_send\*(C'\fR, which is thread\- and signal safe.
-.PP
-This functionality is very similar to \f(CW\*(C`ev_signal\*(C'\fR watchers, as signals,
-too, are asynchronous in nature, and signals, too, will be compressed
-(i.e. the number of callback invocations may be less than the number of
-\&\f(CW\*(C`ev_async_sent\*(C'\fR calls). In fact, you could use signal watchers as a kind
-of \*(L"global async watchers\*(R" by using a watcher on an otherwise unused
-signal, and \f(CW\*(C`ev_feed_signal\*(C'\fR to signal this watcher from another thread,
-even without knowing which loop owns the signal.
-.PP
-Unlike \f(CW\*(C`ev_signal\*(C'\fR watchers, \f(CW\*(C`ev_async\*(C'\fR works with any event loop, not
-just the default loop.
-.PP
-\fIQueueing\fR
-.IX Subsection "Queueing"
-.PP
-\&\f(CW\*(C`ev_async\*(C'\fR does not support queueing of data in any way. The reason
-is that the author does not know of a simple (or any) algorithm for a
-multiple-writer-single-reader queue that works in all cases and doesn't
-need elaborate support such as pthreads or unportable memory access
-semantics.
-.PP
-That means that if you want to queue data, you have to provide your own
-queue. But at least I can tell you how to implement locking around your
-queue:
-.IP "queueing from a signal handler context" 4
-.IX Item "queueing from a signal handler context"
-To implement race-free queueing, you simply add to the queue in the signal
-handler but you block the signal handler in the watcher callback. Here is
-an example that does that for some fictitious \s-1SIGUSR1\s0 handler:
-.Sp
-.Vb 1
-\& static ev_async mysig;
-\&
-\& static void
-\& sigusr1_handler (void)
-\& {
-\& sometype data;
-\&
-\& // no locking etc.
-\& queue_put (data);
-\& ev_async_send (EV_DEFAULT_ &mysig);
-\& }
-\&
-\& static void
-\& mysig_cb (EV_P_ ev_async *w, int revents)
-\& {
-\& sometype data;
-\& sigset_t block, prev;
-\&
-\& sigemptyset (&block);
-\& sigaddset (&block, SIGUSR1);
-\& sigprocmask (SIG_BLOCK, &block, &prev);
-\&
-\& while (queue_get (&data))
-\& process (data);
-\&
-\& if (sigismember (&prev, SIGUSR1)
-\& sigprocmask (SIG_UNBLOCK, &block, 0);
-\& }
-.Ve
-.Sp
-(Note: pthreads in theory requires you to use \f(CW\*(C`pthread_setmask\*(C'\fR
-instead of \f(CW\*(C`sigprocmask\*(C'\fR when you use threads, but libev doesn't do it
-either...).
-.IP "queueing from a thread context" 4
-.IX Item "queueing from a thread context"
-The strategy for threads is different, as you cannot (easily) block
-threads but you can easily preempt them, so to queue safely you need to
-employ a traditional mutex lock, such as in this pthread example:
-.Sp
-.Vb 2
-\& static ev_async mysig;
-\& static pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
-\&
-\& static void
-\& otherthread (void)
-\& {
-\& // only need to lock the actual queueing operation
-\& pthread_mutex_lock (&mymutex);
-\& queue_put (data);
-\& pthread_mutex_unlock (&mymutex);
-\&
-\& ev_async_send (EV_DEFAULT_ &mysig);
-\& }
-\&
-\& static void
-\& mysig_cb (EV_P_ ev_async *w, int revents)
-\& {
-\& pthread_mutex_lock (&mymutex);
-\&
-\& while (queue_get (&data))
-\& process (data);
-\&
-\& pthread_mutex_unlock (&mymutex);
-\& }
-.Ve
-.PP
-\fIWatcher-Specific Functions and Data Members\fR
-.IX Subsection "Watcher-Specific Functions and Data Members"
-.IP "ev_async_init (ev_async *, callback)" 4
-.IX Item "ev_async_init (ev_async *, callback)"
-Initialises and configures the async watcher \- it has no parameters of any
-kind. There is a \f(CW\*(C`ev_async_set\*(C'\fR macro, but using it is utterly pointless,
-trust me.
-.IP "ev_async_send (loop, ev_async *)" 4
-.IX Item "ev_async_send (loop, ev_async *)"
-Sends/signals/activates the given \f(CW\*(C`ev_async\*(C'\fR watcher, that is, feeds
-an \f(CW\*(C`EV_ASYNC\*(C'\fR event on the watcher into the event loop, and instantly
-returns.
-.Sp
-Unlike \f(CW\*(C`ev_feed_event\*(C'\fR, this call is safe to do from other threads,
-signal or similar contexts (see the discussion of \f(CW\*(C`EV_ATOMIC_T\*(C'\fR in the
-embedding section below on what exactly this means).
-.Sp
-Note that, as with other watchers in libev, multiple events might get
-compressed into a single callback invocation (another way to look at this
-is that \f(CW\*(C`ev_async\*(C'\fR watchers are level-triggered, set on \f(CW\*(C`ev_async_send\*(C'\fR,
-reset when the event loop detects that).
-.Sp
-This call incurs the overhead of a system call only once per event loop
-iteration, so while the overhead might be noticeable, it doesn't apply to
-repeated calls to \f(CW\*(C`ev_async_send\*(C'\fR for the same event loop.
-.IP "bool = ev_async_pending (ev_async *)" 4
-.IX Item "bool = ev_async_pending (ev_async *)"
-Returns a non-zero value when \f(CW\*(C`ev_async_send\*(C'\fR has been called on the
-watcher but the event has not yet been processed (or even noted) by the
-event loop.
-.Sp
-\&\f(CW\*(C`ev_async_send\*(C'\fR sets a flag in the watcher and wakes up the loop. When
-the loop iterates next and checks for the watcher to have become active,
-it will reset the flag again. \f(CW\*(C`ev_async_pending\*(C'\fR can be used to very
-quickly check whether invoking the loop might be a good idea.
-.Sp
-Not that this does \fInot\fR check whether the watcher itself is pending,
-only whether it has been requested to make this watcher pending: there
-is a time window between the event loop checking and resetting the async
-notification, and the callback being invoked.
-.SH "OTHER FUNCTIONS"
-.IX Header "OTHER FUNCTIONS"
-There are some other functions of possible interest. Described. Here. Now.
-.IP "ev_once (loop, int fd, int events, ev_tstamp timeout, callback)" 4
-.IX Item "ev_once (loop, int fd, int events, ev_tstamp timeout, callback)"
-This function combines a simple timer and an I/O watcher, calls your
-callback on whichever event happens first and automatically stops both
-watchers. This is useful if you want to wait for a single event on an fd
-or timeout without having to allocate/configure/start/stop/free one or
-more watchers yourself.
-.Sp
-If \f(CW\*(C`fd\*(C'\fR is less than 0, then no I/O watcher will be started and the
-\&\f(CW\*(C`events\*(C'\fR argument is being ignored. Otherwise, an \f(CW\*(C`ev_io\*(C'\fR watcher for
-the given \f(CW\*(C`fd\*(C'\fR and \f(CW\*(C`events\*(C'\fR set will be created and started.
-.Sp
-If \f(CW\*(C`timeout\*(C'\fR is less than 0, then no timeout watcher will be
-started. Otherwise an \f(CW\*(C`ev_timer\*(C'\fR watcher with after = \f(CW\*(C`timeout\*(C'\fR (and
-repeat = 0) will be started. \f(CW0\fR is a valid timeout.
-.Sp
-The callback has the type \f(CW\*(C`void (*cb)(int revents, void *arg)\*(C'\fR and is
-passed an \f(CW\*(C`revents\*(C'\fR set like normal event callbacks (a combination of
-\&\f(CW\*(C`EV_ERROR\*(C'\fR, \f(CW\*(C`EV_READ\*(C'\fR, \f(CW\*(C`EV_WRITE\*(C'\fR or \f(CW\*(C`EV_TIMER\*(C'\fR) and the \f(CW\*(C`arg\*(C'\fR
-value passed to \f(CW\*(C`ev_once\*(C'\fR. Note that it is possible to receive \fIboth\fR
-a timeout and an io event at the same time \- you probably should give io
-events precedence.
-.Sp
-Example: wait up to ten seconds for data to appear on \s-1STDIN_FILENO\s0.
-.Sp
-.Vb 7
-\& static void stdin_ready (int revents, void *arg)
-\& {
-\& if (revents & EV_READ)
-\& /* stdin might have data for us, joy! */;
-\& else if (revents & EV_TIMER)
-\& /* doh, nothing entered */;
-\& }
-\&
-\& ev_once (STDIN_FILENO, EV_READ, 10., stdin_ready, 0);
-.Ve
-.IP "ev_feed_fd_event (loop, int fd, int revents)" 4
-.IX Item "ev_feed_fd_event (loop, int fd, int revents)"
-Feed an event on the given fd, as if a file descriptor backend detected
-the given events it.
-.IP "ev_feed_signal_event (loop, int signum)" 4
-.IX Item "ev_feed_signal_event (loop, int signum)"
-Feed an event as if the given signal occurred. See also \f(CW\*(C`ev_feed_signal\*(C'\fR,
-which is async-safe.
-.SH "COMMON OR USEFUL IDIOMS (OR BOTH)"
-.IX Header "COMMON OR USEFUL IDIOMS (OR BOTH)"
-This section explains some common idioms that are not immediately
-obvious. Note that examples are sprinkled over the whole manual, and this
-section only contains stuff that wouldn't fit anywhere else.
-.SS "\s-1ASSOCIATING\s0 \s-1CUSTOM\s0 \s-1DATA\s0 \s-1WITH\s0 A \s-1WATCHER\s0"
-.IX Subsection "ASSOCIATING CUSTOM DATA WITH A WATCHER"
-Each watcher has, by default, a \f(CW\*(C`void *data\*(C'\fR member that you can read
-or modify at any time: libev will completely ignore it. This can be used
-to associate arbitrary data with your watcher. If you need more data and
-don't want to allocate memory separately and store a pointer to it in that
-data member, you can also \*(L"subclass\*(R" the watcher type and provide your own
-data:
-.PP
-.Vb 7
-\& struct my_io
-\& {
-\& ev_io io;
-\& int otherfd;
-\& void *somedata;
-\& struct whatever *mostinteresting;
-\& };
-\&
-\& ...
-\& struct my_io w;
-\& ev_io_init (&w.io, my_cb, fd, EV_READ);
-.Ve
-.PP
-And since your callback will be called with a pointer to the watcher, you
-can cast it back to your own type:
-.PP
-.Vb 5
-\& static void my_cb (struct ev_loop *loop, ev_io *w_, int revents)
-\& {
-\& struct my_io *w = (struct my_io *)w_;
-\& ...
-\& }
-.Ve
-.PP
-More interesting and less C\-conformant ways of casting your callback
-function type instead have been omitted.
-.SS "\s-1BUILDING\s0 \s-1YOUR\s0 \s-1OWN\s0 \s-1COMPOSITE\s0 \s-1WATCHERS\s0"
-.IX Subsection "BUILDING YOUR OWN COMPOSITE WATCHERS"
-Another common scenario is to use some data structure with multiple
-embedded watchers, in effect creating your own watcher that combines
-multiple libev event sources into one \*(L"super-watcher\*(R":
-.PP
-.Vb 6
-\& struct my_biggy
-\& {
-\& int some_data;
-\& ev_timer t1;
-\& ev_timer t2;
-\& }
-.Ve
-.PP
-In this case getting the pointer to \f(CW\*(C`my_biggy\*(C'\fR is a bit more
-complicated: Either you store the address of your \f(CW\*(C`my_biggy\*(C'\fR struct in
-the \f(CW\*(C`data\*(C'\fR member of the watcher (for woozies or \*(C+ coders), or you need
-to use some pointer arithmetic using \f(CW\*(C`offsetof\*(C'\fR inside your watchers (for
-real programmers):
-.PP
-.Vb 1
-\& #include <stddef.h>
-\&
-\& static void
-\& t1_cb (EV_P_ ev_timer *w, int revents)
-\& {
-\& struct my_biggy big = (struct my_biggy *)
-\& (((char *)w) \- offsetof (struct my_biggy, t1));
-\& }
-\&
-\& static void
-\& t2_cb (EV_P_ ev_timer *w, int revents)
-\& {
-\& struct my_biggy big = (struct my_biggy *)
-\& (((char *)w) \- offsetof (struct my_biggy, t2));
-\& }
-.Ve
-.SS "\s-1MODEL/NESTED\s0 \s-1EVENT\s0 \s-1LOOP\s0 \s-1INVOCATIONS\s0 \s-1AND\s0 \s-1EXIT\s0 \s-1CONDITIONS\s0"
-.IX Subsection "MODEL/NESTED EVENT LOOP INVOCATIONS AND EXIT CONDITIONS"
-Often (especially in \s-1GUI\s0 toolkits) there are places where you have
-\&\fImodal\fR interaction, which is most easily implemented by recursively
-invoking \f(CW\*(C`ev_run\*(C'\fR.
-.PP
-This brings the problem of exiting \- a callback might want to finish the
-main \f(CW\*(C`ev_run\*(C'\fR call, but not the nested one (e.g. user clicked \*(L"Quit\*(R", but
-a modal \*(L"Are you sure?\*(R" dialog is still waiting), or just the nested one
-and not the main one (e.g. user clocked \*(L"Ok\*(R" in a modal dialog), or some
-other combination: In these cases, \f(CW\*(C`ev_break\*(C'\fR will not work alone.
-.PP
-The solution is to maintain \*(L"break this loop\*(R" variable for each \f(CW\*(C`ev_run\*(C'\fR
-invocation, and use a loop around \f(CW\*(C`ev_run\*(C'\fR until the condition is
-triggered, using \f(CW\*(C`EVRUN_ONCE\*(C'\fR:
-.PP
-.Vb 2
-\& // main loop
-\& int exit_main_loop = 0;
-\&
-\& while (!exit_main_loop)
-\& ev_run (EV_DEFAULT_ EVRUN_ONCE);
-\&
-\& // in a model watcher
-\& int exit_nested_loop = 0;
-\&
-\& while (!exit_nested_loop)
-\& ev_run (EV_A_ EVRUN_ONCE);
-.Ve
-.PP
-To exit from any of these loops, just set the corresponding exit variable:
-.PP
-.Vb 2
-\& // exit modal loop
-\& exit_nested_loop = 1;
-\&
-\& // exit main program, after modal loop is finished
-\& exit_main_loop = 1;
-\&
-\& // exit both
-\& exit_main_loop = exit_nested_loop = 1;
-.Ve
-.SS "\s-1THREAD\s0 \s-1LOCKING\s0 \s-1EXAMPLE\s0"
-.IX Subsection "THREAD LOCKING EXAMPLE"
-Here is a fictitious example of how to run an event loop in a different
-thread from where callbacks are being invoked and watchers are
-created/added/removed.
-.PP
-For a real-world example, see the \f(CW\*(C`EV::Loop::Async\*(C'\fR perl module,
-which uses exactly this technique (which is suited for many high-level
-languages).
-.PP
-The example uses a pthread mutex to protect the loop data, a condition
-variable to wait for callback invocations, an async watcher to notify the
-event loop thread and an unspecified mechanism to wake up the main thread.
-.PP
-First, you need to associate some data with the event loop:
-.PP
-.Vb 6
-\& typedef struct {
-\& mutex_t lock; /* global loop lock */
-\& ev_async async_w;
-\& thread_t tid;
-\& cond_t invoke_cv;
-\& } userdata;
-\&
-\& void prepare_loop (EV_P)
-\& {
-\& // for simplicity, we use a static userdata struct.
-\& static userdata u;
-\&
-\& ev_async_init (&u\->async_w, async_cb);
-\& ev_async_start (EV_A_ &u\->async_w);
-\&
-\& pthread_mutex_init (&u\->lock, 0);
-\& pthread_cond_init (&u\->invoke_cv, 0);
-\&
-\& // now associate this with the loop
-\& ev_set_userdata (EV_A_ u);
-\& ev_set_invoke_pending_cb (EV_A_ l_invoke);
-\& ev_set_loop_release_cb (EV_A_ l_release, l_acquire);
-\&
-\& // then create the thread running ev_run
-\& pthread_create (&u\->tid, 0, l_run, EV_A);
-\& }
-.Ve
-.PP
-The callback for the \f(CW\*(C`ev_async\*(C'\fR watcher does nothing: the watcher is used
-solely to wake up the event loop so it takes notice of any new watchers
-that might have been added:
-.PP
-.Vb 5
-\& static void
-\& async_cb (EV_P_ ev_async *w, int revents)
-\& {
-\& // just used for the side effects
-\& }
-.Ve
-.PP
-The \f(CW\*(C`l_release\*(C'\fR and \f(CW\*(C`l_acquire\*(C'\fR callbacks simply unlock/lock the mutex
-protecting the loop data, respectively.
-.PP
-.Vb 6
-\& static void
-\& l_release (EV_P)
-\& {
-\& userdata *u = ev_userdata (EV_A);
-\& pthread_mutex_unlock (&u\->lock);
-\& }
-\&
-\& static void
-\& l_acquire (EV_P)
-\& {
-\& userdata *u = ev_userdata (EV_A);
-\& pthread_mutex_lock (&u\->lock);
-\& }
-.Ve
-.PP
-The event loop thread first acquires the mutex, and then jumps straight
-into \f(CW\*(C`ev_run\*(C'\fR:
-.PP
-.Vb 4
-\& void *
-\& l_run (void *thr_arg)
-\& {
-\& struct ev_loop *loop = (struct ev_loop *)thr_arg;
-\&
-\& l_acquire (EV_A);
-\& pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
-\& ev_run (EV_A_ 0);
-\& l_release (EV_A);
-\&
-\& return 0;
-\& }
-.Ve
-.PP
-Instead of invoking all pending watchers, the \f(CW\*(C`l_invoke\*(C'\fR callback will
-signal the main thread via some unspecified mechanism (signals? pipe
-writes? \f(CW\*(C`Async::Interrupt\*(C'\fR?) and then waits until all pending watchers
-have been called (in a while loop because a) spurious wakeups are possible
-and b) skipping inter-thread-communication when there are no pending
-watchers is very beneficial):
-.PP
-.Vb 4
-\& static void
-\& l_invoke (EV_P)
-\& {
-\& userdata *u = ev_userdata (EV_A);
-\&
-\& while (ev_pending_count (EV_A))
-\& {
-\& wake_up_other_thread_in_some_magic_or_not_so_magic_way ();
-\& pthread_cond_wait (&u\->invoke_cv, &u\->lock);
-\& }
-\& }
-.Ve
-.PP
-Now, whenever the main thread gets told to invoke pending watchers, it
-will grab the lock, call \f(CW\*(C`ev_invoke_pending\*(C'\fR and then signal the loop
-thread to continue:
-.PP
-.Vb 4
-\& static void
-\& real_invoke_pending (EV_P)
-\& {
-\& userdata *u = ev_userdata (EV_A);
-\&
-\& pthread_mutex_lock (&u\->lock);
-\& ev_invoke_pending (EV_A);
-\& pthread_cond_signal (&u\->invoke_cv);
-\& pthread_mutex_unlock (&u\->lock);
-\& }
-.Ve
-.PP
-Whenever you want to start/stop a watcher or do other modifications to an
-event loop, you will now have to lock:
-.PP
-.Vb 2
-\& ev_timer timeout_watcher;
-\& userdata *u = ev_userdata (EV_A);
-\&
-\& ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
-\&
-\& pthread_mutex_lock (&u\->lock);
-\& ev_timer_start (EV_A_ &timeout_watcher);
-\& ev_async_send (EV_A_ &u\->async_w);
-\& pthread_mutex_unlock (&u\->lock);
-.Ve
-.PP
-Note that sending the \f(CW\*(C`ev_async\*(C'\fR watcher is required because otherwise
-an event loop currently blocking in the kernel will have no knowledge
-about the newly added timer. By waking up the loop it will pick up any new
-watchers in the next event loop iteration.
-.SS "\s-1THREADS\s0, \s-1COROUTINES\s0, \s-1CONTINUATIONS\s0, \s-1QUEUES\s0... \s-1INSTEAD\s0 \s-1OF\s0 \s-1CALLBACKS\s0"
-.IX Subsection "THREADS, COROUTINES, CONTINUATIONS, QUEUES... INSTEAD OF CALLBACKS"
-While the overhead of a callback that e.g. schedules a thread is small, it
-is still an overhead. If you embed libev, and your main usage is with some
-kind of threads or coroutines, you might want to customise libev so that
-doesn't need callbacks anymore.
-.PP
-Imagine you have coroutines that you can switch to using a function
-\&\f(CW\*(C`switch_to (coro)\*(C'\fR, that libev runs in a coroutine called \f(CW\*(C`libev_coro\*(C'\fR
-and that due to some magic, the currently active coroutine is stored in a
-global called \f(CW\*(C`current_coro\*(C'\fR. Then you can build your own \*(L"wait for libev
-event\*(R" primitive by changing \f(CW\*(C`EV_CB_DECLARE\*(C'\fR and \f(CW\*(C`EV_CB_INVOKE\*(C'\fR (note
-the differing \f(CW\*(C`;\*(C'\fR conventions):
-.PP
-.Vb 2
-\& #define EV_CB_DECLARE(type) struct my_coro *cb;
-\& #define EV_CB_INVOKE(watcher) switch_to ((watcher)\->cb)
-.Ve
-.PP
-That means instead of having a C callback function, you store the
-coroutine to switch to in each watcher, and instead of having libev call
-your callback, you instead have it switch to that coroutine.
-.PP
-A coroutine might now wait for an event with a function called
-\&\f(CW\*(C`wait_for_event\*(C'\fR. (the watcher needs to be started, as always, but it doesn't
-matter when, or whether the watcher is active or not when this function is
-called):
-.PP
-.Vb 6
-\& void
-\& wait_for_event (ev_watcher *w)
-\& {
-\& ev_cb_set (w) = current_coro;
-\& switch_to (libev_coro);
-\& }
-.Ve
-.PP
-That basically suspends the coroutine inside \f(CW\*(C`wait_for_event\*(C'\fR and
-continues the libev coroutine, which, when appropriate, switches back to
-this or any other coroutine. I am sure if you sue this your own :)
-.PP
-You can do similar tricks if you have, say, threads with an event queue \-
-instead of storing a coroutine, you store the queue object and instead of
-switching to a coroutine, you push the watcher onto the queue and notify
-any waiters.
-.PP
-To embed libev, see \s-1EMBEDDING\s0, but in short, it's easiest to create two
-files, \fImy_ev.h\fR and \fImy_ev.c\fR that include the respective libev files:
-.PP
-.Vb 4
-\& // my_ev.h
-\& #define EV_CB_DECLARE(type) struct my_coro *cb;
-\& #define EV_CB_INVOKE(watcher) switch_to ((watcher)\->cb);
-\& #include "../libev/ev.h"
-\&
-\& // my_ev.c
-\& #define EV_H "my_ev.h"
-\& #include "../libev/ev.c"
-.Ve
-.PP
-And then use \fImy_ev.h\fR when you would normally use \fIev.h\fR, and compile
-\&\fImy_ev.c\fR into your project. When properly specifying include paths, you
-can even use \fIev.h\fR as header file name directly.
-.SH "LIBEVENT EMULATION"
-.IX Header "LIBEVENT EMULATION"
-Libev offers a compatibility emulation layer for libevent. It cannot
-emulate the internals of libevent, so here are some usage hints:
-.IP "\(bu" 4
-Only the libevent\-1.4.1\-beta \s-1API\s0 is being emulated.
-.Sp
-This was the newest libevent version available when libev was implemented,
-and is still mostly unchanged in 2010.
-.IP "\(bu" 4
-Use it by including <event.h>, as usual.
-.IP "\(bu" 4
-The following members are fully supported: ev_base, ev_callback,
-ev_arg, ev_fd, ev_res, ev_events.
-.IP "\(bu" 4
-Avoid using ev_flags and the EVLIST_*\-macros, while it is
-maintained by libev, it does not work exactly the same way as in libevent (consider
-it a private \s-1API\s0).
-.IP "\(bu" 4
-Priorities are not currently supported. Initialising priorities
-will fail and all watchers will have the same priority, even though there
-is an ev_pri field.
-.IP "\(bu" 4
-In libevent, the last base created gets the signals, in libev, the
-base that registered the signal gets the signals.
-.IP "\(bu" 4
-Other members are not supported.
-.IP "\(bu" 4
-The libev emulation is \fInot\fR \s-1ABI\s0 compatible to libevent, you need
-to use the libev header file and library.
-.SH "\*(C+ SUPPORT"
-.IX Header " SUPPORT"
-Libev comes with some simplistic wrapper classes for \*(C+ that mainly allow
-you to use some convenience methods to start/stop watchers and also change
-the callback model to a model using method callbacks on objects.
-.PP
-To use it,
-.PP
-.Vb 1
-\& #include <ev++.h>
-.Ve
-.PP
-This automatically includes \fIev.h\fR and puts all of its definitions (many
-of them macros) into the global namespace. All \*(C+ specific things are
-put into the \f(CW\*(C`ev\*(C'\fR namespace. It should support all the same embedding
-options as \fIev.h\fR, most notably \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR.
-.PP
-Care has been taken to keep the overhead low. The only data member the \*(C+
-classes add (compared to plain C\-style watchers) is the event loop pointer
-that the watcher is associated with (or no additional members at all if
-you disable \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR when embedding libev).
-.PP
-Currently, functions, static and non-static member functions and classes
-with \f(CW\*(C`operator ()\*(C'\fR can be used as callbacks. Other types should be easy
-to add as long as they only need one additional pointer for context. If
-you need support for other types of functors please contact the author
-(preferably after implementing it).
-.PP
-Here is a list of things available in the \f(CW\*(C`ev\*(C'\fR namespace:
-.ie n .IP """ev::READ"", ""ev::WRITE"" etc." 4
-.el .IP "\f(CWev::READ\fR, \f(CWev::WRITE\fR etc." 4
-.IX Item "ev::READ, ev::WRITE etc."
-These are just enum values with the same values as the \f(CW\*(C`EV_READ\*(C'\fR etc.
-macros from \fIev.h\fR.
-.ie n .IP """ev::tstamp"", ""ev::now""" 4
-.el .IP "\f(CWev::tstamp\fR, \f(CWev::now\fR" 4
-.IX Item "ev::tstamp, ev::now"
-Aliases to the same types/functions as with the \f(CW\*(C`ev_\*(C'\fR prefix.
-.ie n .IP """ev::io"", ""ev::timer"", ""ev::periodic"", ""ev::idle"", ""ev::sig"" etc." 4
-.el .IP "\f(CWev::io\fR, \f(CWev::timer\fR, \f(CWev::periodic\fR, \f(CWev::idle\fR, \f(CWev::sig\fR etc." 4
-.IX Item "ev::io, ev::timer, ev::periodic, ev::idle, ev::sig etc."
-For each \f(CW\*(C`ev_TYPE\*(C'\fR watcher in \fIev.h\fR there is a corresponding class of
-the same name in the \f(CW\*(C`ev\*(C'\fR namespace, with the exception of \f(CW\*(C`ev_signal\*(C'\fR
-which is called \f(CW\*(C`ev::sig\*(C'\fR to avoid clashes with the \f(CW\*(C`signal\*(C'\fR macro
-defines by many implementations.
-.Sp
-All of those classes have these methods:
-.RS 4
-.IP "ev::TYPE::TYPE ()" 4
-.IX Item "ev::TYPE::TYPE ()"
-.PD 0
-.IP "ev::TYPE::TYPE (loop)" 4
-.IX Item "ev::TYPE::TYPE (loop)"
-.IP "ev::TYPE::~TYPE" 4
-.IX Item "ev::TYPE::~TYPE"
-.PD
-The constructor (optionally) takes an event loop to associate the watcher
-with. If it is omitted, it will use \f(CW\*(C`EV_DEFAULT\*(C'\fR.
-.Sp
-The constructor calls \f(CW\*(C`ev_init\*(C'\fR for you, which means you have to call the
-\&\f(CW\*(C`set\*(C'\fR method before starting it.
-.Sp
-It will not set a callback, however: You have to call the templated \f(CW\*(C`set\*(C'\fR
-method to set a callback before you can start the watcher.
-.Sp
-(The reason why you have to use a method is a limitation in \*(C+ which does
-not allow explicit template arguments for constructors).
-.Sp
-The destructor automatically stops the watcher if it is active.
-.IP "w\->set<class, &class::method> (object *)" 4
-.IX Item "w->set<class, &class::method> (object *)"
-This method sets the callback method to call. The method has to have a
-signature of \f(CW\*(C`void (*)(ev_TYPE &, int)\*(C'\fR, it receives the watcher as
-first argument and the \f(CW\*(C`revents\*(C'\fR as second. The object must be given as
-parameter and is stored in the \f(CW\*(C`data\*(C'\fR member of the watcher.
-.Sp
-This method synthesizes efficient thunking code to call your method from
-the C callback that libev requires. If your compiler can inline your
-callback (i.e. it is visible to it at the place of the \f(CW\*(C`set\*(C'\fR call and
-your compiler is good :), then the method will be fully inlined into the
-thunking function, making it as fast as a direct C callback.
-.Sp
-Example: simple class declaration and watcher initialisation
-.Sp
-.Vb 4
-\& struct myclass
-\& {
-\& void io_cb (ev::io &w, int revents) { }
-\& }
-\&
-\& myclass obj;
-\& ev::io iow;
-\& iow.set <myclass, &myclass::io_cb> (&obj);
-.Ve
-.IP "w\->set (object *)" 4
-.IX Item "w->set (object *)"
-This is a variation of a method callback \- leaving out the method to call
-will default the method to \f(CW\*(C`operator ()\*(C'\fR, which makes it possible to use
-functor objects without having to manually specify the \f(CW\*(C`operator ()\*(C'\fR all
-the time. Incidentally, you can then also leave out the template argument
-list.
-.Sp
-The \f(CW\*(C`operator ()\*(C'\fR method prototype must be \f(CW\*(C`void operator ()(watcher &w,
-int revents)\*(C'\fR.
-.Sp
-See the method\-\f(CW\*(C`set\*(C'\fR above for more details.
-.Sp
-Example: use a functor object as callback.
-.Sp
-.Vb 7
-\& struct myfunctor
-\& {
-\& void operator() (ev::io &w, int revents)
-\& {
-\& ...
-\& }
-\& }
-\&
-\& myfunctor f;
-\&
-\& ev::io w;
-\& w.set (&f);
-.Ve
-.IP "w\->set<function> (void *data = 0)" 4
-.IX Item "w->set<function> (void *data = 0)"
-Also sets a callback, but uses a static method or plain function as
-callback. The optional \f(CW\*(C`data\*(C'\fR argument will be stored in the watcher's
-\&\f(CW\*(C`data\*(C'\fR member and is free for you to use.
-.Sp
-The prototype of the \f(CW\*(C`function\*(C'\fR must be \f(CW\*(C`void (*)(ev::TYPE &w, int)\*(C'\fR.
-.Sp
-See the method\-\f(CW\*(C`set\*(C'\fR above for more details.
-.Sp
-Example: Use a plain function as callback.
-.Sp
-.Vb 2
-\& static void io_cb (ev::io &w, int revents) { }
-\& iow.set <io_cb> ();
-.Ve
-.IP "w\->set (loop)" 4
-.IX Item "w->set (loop)"
-Associates a different \f(CW\*(C`struct ev_loop\*(C'\fR with this watcher. You can only
-do this when the watcher is inactive (and not pending either).
-.IP "w\->set ([arguments])" 4
-.IX Item "w->set ([arguments])"
-Basically the same as \f(CW\*(C`ev_TYPE_set\*(C'\fR, with the same arguments. Either this
-method or a suitable start method must be called at least once. Unlike the
-C counterpart, an active watcher gets automatically stopped and restarted
-when reconfiguring it with this method.
-.IP "w\->start ()" 4
-.IX Item "w->start ()"
-Starts the watcher. Note that there is no \f(CW\*(C`loop\*(C'\fR argument, as the
-constructor already stores the event loop.
-.IP "w\->start ([arguments])" 4
-.IX Item "w->start ([arguments])"
-Instead of calling \f(CW\*(C`set\*(C'\fR and \f(CW\*(C`start\*(C'\fR methods separately, it is often
-convenient to wrap them in one call. Uses the same type of arguments as
-the configure \f(CW\*(C`set\*(C'\fR method of the watcher.
-.IP "w\->stop ()" 4
-.IX Item "w->stop ()"
-Stops the watcher if it is active. Again, no \f(CW\*(C`loop\*(C'\fR argument.
-.ie n .IP "w\->again () (""ev::timer"", ""ev::periodic"" only)" 4
-.el .IP "w\->again () (\f(CWev::timer\fR, \f(CWev::periodic\fR only)" 4
-.IX Item "w->again () (ev::timer, ev::periodic only)"
-For \f(CW\*(C`ev::timer\*(C'\fR and \f(CW\*(C`ev::periodic\*(C'\fR, this invokes the corresponding
-\&\f(CW\*(C`ev_TYPE_again\*(C'\fR function.
-.ie n .IP "w\->sweep () (""ev::embed"" only)" 4
-.el .IP "w\->sweep () (\f(CWev::embed\fR only)" 4
-.IX Item "w->sweep () (ev::embed only)"
-Invokes \f(CW\*(C`ev_embed_sweep\*(C'\fR.
-.ie n .IP "w\->update () (""ev::stat"" only)" 4
-.el .IP "w\->update () (\f(CWev::stat\fR only)" 4
-.IX Item "w->update () (ev::stat only)"
-Invokes \f(CW\*(C`ev_stat_stat\*(C'\fR.
-.RE
-.RS 4
-.RE
-.PP
-Example: Define a class with two I/O and idle watchers, start the I/O
-watchers in the constructor.
-.PP
-.Vb 5
-\& class myclass
-\& {
-\& ev::io io ; void io_cb (ev::io &w, int revents);
-\& ev::io2 io2 ; void io2_cb (ev::io &w, int revents);
-\& ev::idle idle; void idle_cb (ev::idle &w, int revents);
-\&
-\& myclass (int fd)
-\& {
-\& io .set <myclass, &myclass::io_cb > (this);
-\& io2 .set <myclass, &myclass::io2_cb > (this);
-\& idle.set <myclass, &myclass::idle_cb> (this);
-\&
-\& io.set (fd, ev::WRITE); // configure the watcher
-\& io.start (); // start it whenever convenient
-\&
-\& io2.start (fd, ev::READ); // set + start in one call
-\& }
-\& };
-.Ve
-.SH "OTHER LANGUAGE BINDINGS"
-.IX Header "OTHER LANGUAGE BINDINGS"
-Libev does not offer other language bindings itself, but bindings for a
-number of languages exist in the form of third-party packages. If you know
-any interesting language binding in addition to the ones listed here, drop
-me a note.
-.IP "Perl" 4
-.IX Item "Perl"
-The \s-1EV\s0 module implements the full libev \s-1API\s0 and is actually used to test
-libev. \s-1EV\s0 is developed together with libev. Apart from the \s-1EV\s0 core module,
-there are additional modules that implement libev-compatible interfaces
-to \f(CW\*(C`libadns\*(C'\fR (\f(CW\*(C`EV::ADNS\*(C'\fR, but \f(CW\*(C`AnyEvent::DNS\*(C'\fR is preferred nowadays),
-\&\f(CW\*(C`Net::SNMP\*(C'\fR (\f(CW\*(C`Net::SNMP::EV\*(C'\fR) and the \f(CW\*(C`libglib\*(C'\fR event core (\f(CW\*(C`Glib::EV\*(C'\fR
-and \f(CW\*(C`EV::Glib\*(C'\fR).
-.Sp
-It can be found and installed via \s-1CPAN\s0, its homepage is at
-<http://software.schmorp.de/pkg/EV>.
-.IP "Python" 4
-.IX Item "Python"
-Python bindings can be found at <http://code.google.com/p/pyev/>. It
-seems to be quite complete and well-documented.
-.IP "Ruby" 4
-.IX Item "Ruby"
-Tony Arcieri has written a ruby extension that offers access to a subset
-of the libev \s-1API\s0 and adds file handle abstractions, asynchronous \s-1DNS\s0 and
-more on top of it. It can be found via gem servers. Its homepage is at
-<http://rev.rubyforge.org/>.
-.Sp
-Roger Pack reports that using the link order \f(CW\*(C`\-lws2_32 \-lmsvcrt\-ruby\-190\*(C'\fR
-makes rev work even on mingw.
-.IP "Haskell" 4
-.IX Item "Haskell"
-A haskell binding to libev is available at
-<http://hackage.haskell.org/cgi\-bin/hackage\-scripts/package/hlibev>.
-.IP "D" 4
-.IX Item "D"
-Leandro Lucarella has written a D language binding (\fIev.d\fR) for libev, to
-be found at <http://proj.llucax.com.ar/wiki/evd>.
-.IP "Ocaml" 4
-.IX Item "Ocaml"
-Erkki Seppala has written Ocaml bindings for libev, to be found at
-<http://modeemi.cs.tut.fi/~flux/software/ocaml\-ev/>.
-.IP "Lua" 4
-.IX Item "Lua"
-Brian Maher has written a partial interface to libev for lua (at the
-time of this writing, only \f(CW\*(C`ev_io\*(C'\fR and \f(CW\*(C`ev_timer\*(C'\fR), to be found at
-<http://github.com/brimworks/lua\-ev>.
-.SH "MACRO MAGIC"
-.IX Header "MACRO MAGIC"
-Libev can be compiled with a variety of options, the most fundamental
-of which is \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR. This option determines whether (most)
-functions and callbacks have an initial \f(CW\*(C`struct ev_loop *\*(C'\fR argument.
-.PP
-To make it easier to write programs that cope with either variant, the
-following macros are defined:
-.ie n .IP """EV_A"", ""EV_A_""" 4
-.el .IP "\f(CWEV_A\fR, \f(CWEV_A_\fR" 4
-.IX Item "EV_A, EV_A_"
-This provides the loop \fIargument\fR for functions, if one is required (\*(L"ev
-loop argument\*(R"). The \f(CW\*(C`EV_A\*(C'\fR form is used when this is the sole argument,
-\&\f(CW\*(C`EV_A_\*(C'\fR is used when other arguments are following. Example:
-.Sp
-.Vb 3
-\& ev_unref (EV_A);
-\& ev_timer_add (EV_A_ watcher);
-\& ev_run (EV_A_ 0);
-.Ve
-.Sp
-It assumes the variable \f(CW\*(C`loop\*(C'\fR of type \f(CW\*(C`struct ev_loop *\*(C'\fR is in scope,
-which is often provided by the following macro.
-.ie n .IP """EV_P"", ""EV_P_""" 4
-.el .IP "\f(CWEV_P\fR, \f(CWEV_P_\fR" 4
-.IX Item "EV_P, EV_P_"
-This provides the loop \fIparameter\fR for functions, if one is required (\*(L"ev
-loop parameter\*(R"). The \f(CW\*(C`EV_P\*(C'\fR form is used when this is the sole parameter,
-\&\f(CW\*(C`EV_P_\*(C'\fR is used when other parameters are following. Example:
-.Sp
-.Vb 2
-\& // this is how ev_unref is being declared
-\& static void ev_unref (EV_P);
-\&
-\& // this is how you can declare your typical callback
-\& static void cb (EV_P_ ev_timer *w, int revents)
-.Ve
-.Sp
-It declares a parameter \f(CW\*(C`loop\*(C'\fR of type \f(CW\*(C`struct ev_loop *\*(C'\fR, quite
-suitable for use with \f(CW\*(C`EV_A\*(C'\fR.
-.ie n .IP """EV_DEFAULT"", ""EV_DEFAULT_""" 4
-.el .IP "\f(CWEV_DEFAULT\fR, \f(CWEV_DEFAULT_\fR" 4
-.IX Item "EV_DEFAULT, EV_DEFAULT_"
-Similar to the other two macros, this gives you the value of the default
-loop, if multiple loops are supported (\*(L"ev loop default\*(R").
-.ie n .IP """EV_DEFAULT_UC"", ""EV_DEFAULT_UC_""" 4
-.el .IP "\f(CWEV_DEFAULT_UC\fR, \f(CWEV_DEFAULT_UC_\fR" 4
-.IX Item "EV_DEFAULT_UC, EV_DEFAULT_UC_"
-Usage identical to \f(CW\*(C`EV_DEFAULT\*(C'\fR and \f(CW\*(C`EV_DEFAULT_\*(C'\fR, but requires that the
-default loop has been initialised (\f(CW\*(C`UC\*(C'\fR == unchecked). Their behaviour
-is undefined when the default loop has not been initialised by a previous
-execution of \f(CW\*(C`EV_DEFAULT\*(C'\fR, \f(CW\*(C`EV_DEFAULT_\*(C'\fR or \f(CW\*(C`ev_default_init (...)\*(C'\fR.
-.Sp
-It is often prudent to use \f(CW\*(C`EV_DEFAULT\*(C'\fR when initialising the first
-watcher in a function but use \f(CW\*(C`EV_DEFAULT_UC\*(C'\fR afterwards.
-.PP
-Example: Declare and initialise a check watcher, utilising the above
-macros so it will work regardless of whether multiple loops are supported
-or not.
-.PP
-.Vb 5
-\& static void
-\& check_cb (EV_P_ ev_timer *w, int revents)
-\& {
-\& ev_check_stop (EV_A_ w);
-\& }
-\&
-\& ev_check check;
-\& ev_check_init (&check, check_cb);
-\& ev_check_start (EV_DEFAULT_ &check);
-\& ev_run (EV_DEFAULT_ 0);
-.Ve
-.SH "EMBEDDING"
-.IX Header "EMBEDDING"
-Libev can (and often is) directly embedded into host
-applications. Examples of applications that embed it include the Deliantra
-Game Server, the \s-1EV\s0 perl module, the \s-1GNU\s0 Virtual Private Ethernet (gvpe)
-and rxvt-unicode.
-.PP
-The goal is to enable you to just copy the necessary files into your
-source directory without having to change even a single line in them, so
-you can easily upgrade by simply copying (or having a checked-out copy of
-libev somewhere in your source tree).
-.SS "\s-1FILESETS\s0"
-.IX Subsection "FILESETS"
-Depending on what features you need you need to include one or more sets of files
-in your application.
-.PP
-\fI\s-1CORE\s0 \s-1EVENT\s0 \s-1LOOP\s0\fR
-.IX Subsection "CORE EVENT LOOP"
-.PP
-To include only the libev core (all the \f(CW\*(C`ev_*\*(C'\fR functions), with manual
-configuration (no autoconf):
-.PP
-.Vb 2
-\& #define EV_STANDALONE 1
-\& #include "ev.c"
-.Ve
-.PP
-This will automatically include \fIev.h\fR, too, and should be done in a
-single C source file only to provide the function implementations. To use
-it, do the same for \fIev.h\fR in all files wishing to use this \s-1API\s0 (best
-done by writing a wrapper around \fIev.h\fR that you can include instead and
-where you can put other configuration options):
-.PP
-.Vb 2
-\& #define EV_STANDALONE 1
-\& #include "ev.h"
-.Ve
-.PP
-Both header files and implementation files can be compiled with a \*(C+
-compiler (at least, that's a stated goal, and breakage will be treated
-as a bug).
-.PP
-You need the following files in your source tree, or in a directory
-in your include path (e.g. in libev/ when using \-Ilibev):
-.PP
-.Vb 4
-\& ev.h
-\& ev.c
-\& ev_vars.h
-\& ev_wrap.h
-\&
-\& ev_win32.c required on win32 platforms only
-\&
-\& ev_select.c only when select backend is enabled (which is enabled by default)
-\& ev_poll.c only when poll backend is enabled (disabled by default)
-\& ev_epoll.c only when the epoll backend is enabled (disabled by default)
-\& ev_kqueue.c only when the kqueue backend is enabled (disabled by default)
-\& ev_port.c only when the solaris port backend is enabled (disabled by default)
-.Ve
-.PP
-\&\fIev.c\fR includes the backend files directly when enabled, so you only need
-to compile this single file.
-.PP
-\fI\s-1LIBEVENT\s0 \s-1COMPATIBILITY\s0 \s-1API\s0\fR
-.IX Subsection "LIBEVENT COMPATIBILITY API"
-.PP
-To include the libevent compatibility \s-1API\s0, also include:
-.PP
-.Vb 1
-\& #include "event.c"
-.Ve
-.PP
-in the file including \fIev.c\fR, and:
-.PP
-.Vb 1
-\& #include "event.h"
-.Ve
-.PP
-in the files that want to use the libevent \s-1API\s0. This also includes \fIev.h\fR.
-.PP
-You need the following additional files for this:
-.PP
-.Vb 2
-\& event.h
-\& event.c
-.Ve
-.PP
-\fI\s-1AUTOCONF\s0 \s-1SUPPORT\s0\fR
-.IX Subsection "AUTOCONF SUPPORT"
-.PP
-Instead of using \f(CW\*(C`EV_STANDALONE=1\*(C'\fR and providing your configuration in
-whatever way you want, you can also \f(CW\*(C`m4_include([libev.m4])\*(C'\fR in your
-\&\fIconfigure.ac\fR and leave \f(CW\*(C`EV_STANDALONE\*(C'\fR undefined. \fIev.c\fR will then
-include \fIconfig.h\fR and configure itself accordingly.
-.PP
-For this of course you need the m4 file:
-.PP
-.Vb 1
-\& libev.m4
-.Ve
-.SS "\s-1PREPROCESSOR\s0 \s-1SYMBOLS/MACROS\s0"
-.IX Subsection "PREPROCESSOR SYMBOLS/MACROS"
-Libev can be configured via a variety of preprocessor symbols you have to
-define before including (or compiling) any of its files. The default in
-the absence of autoconf is documented for every option.
-.PP
-Symbols marked with \*(L"(h)\*(R" do not change the \s-1ABI\s0, and can have different
-values when compiling libev vs. including \fIev.h\fR, so it is permissible
-to redefine them before including \fIev.h\fR without breaking compatibility
-to a compiled library. All other symbols change the \s-1ABI\s0, which means all
-users of libev and the libev code itself must be compiled with compatible
-settings.
-.IP "\s-1EV_COMPAT3\s0 (h)" 4
-.IX Item "EV_COMPAT3 (h)"
-Backwards compatibility is a major concern for libev. This is why this
-release of libev comes with wrappers for the functions and symbols that
-have been renamed between libev version 3 and 4.
-.Sp
-You can disable these wrappers (to test compatibility with future
-versions) by defining \f(CW\*(C`EV_COMPAT3\*(C'\fR to \f(CW0\fR when compiling your
-sources. This has the additional advantage that you can drop the \f(CW\*(C`struct\*(C'\fR
-from \f(CW\*(C`struct ev_loop\*(C'\fR declarations, as libev will provide an \f(CW\*(C`ev_loop\*(C'\fR
-typedef in that case.
-.Sp
-In some future version, the default for \f(CW\*(C`EV_COMPAT3\*(C'\fR will become \f(CW0\fR,
-and in some even more future version the compatibility code will be
-removed completely.
-.IP "\s-1EV_STANDALONE\s0 (h)" 4
-.IX Item "EV_STANDALONE (h)"
-Must always be \f(CW1\fR if you do not use autoconf configuration, which
-keeps libev from including \fIconfig.h\fR, and it also defines dummy
-implementations for some libevent functions (such as logging, which is not
-supported). It will also not define any of the structs usually found in
-\&\fIevent.h\fR that are not directly supported by the libev core alone.
-.Sp
-In standalone mode, libev will still try to automatically deduce the
-configuration, but has to be more conservative.
-.IP "\s-1EV_USE_MONOTONIC\s0" 4
-.IX Item "EV_USE_MONOTONIC"
-If defined to be \f(CW1\fR, libev will try to detect the availability of the
-monotonic clock option at both compile time and runtime. Otherwise no
-use of the monotonic clock option will be attempted. If you enable this,
-you usually have to link against librt or something similar. Enabling it
-when the functionality isn't available is safe, though, although you have
-to make sure you link against any libraries where the \f(CW\*(C`clock_gettime\*(C'\fR
-function is hiding in (often \fI\-lrt\fR). See also \f(CW\*(C`EV_USE_CLOCK_SYSCALL\*(C'\fR.
-.IP "\s-1EV_USE_REALTIME\s0" 4
-.IX Item "EV_USE_REALTIME"
-If defined to be \f(CW1\fR, libev will try to detect the availability of the
-real-time clock option at compile time (and assume its availability
-at runtime if successful). Otherwise no use of the real-time clock
-option will be attempted. This effectively replaces \f(CW\*(C`gettimeofday\*(C'\fR
-by \f(CW\*(C`clock_get (CLOCK_REALTIME, ...)\*(C'\fR and will not normally affect
-correctness. See the note about libraries in the description of
-\&\f(CW\*(C`EV_USE_MONOTONIC\*(C'\fR, though. Defaults to the opposite value of
-\&\f(CW\*(C`EV_USE_CLOCK_SYSCALL\*(C'\fR.
-.IP "\s-1EV_USE_CLOCK_SYSCALL\s0" 4
-.IX Item "EV_USE_CLOCK_SYSCALL"
-If defined to be \f(CW1\fR, libev will try to use a direct syscall instead
-of calling the system-provided \f(CW\*(C`clock_gettime\*(C'\fR function. This option
-exists because on GNU/Linux, \f(CW\*(C`clock_gettime\*(C'\fR is in \f(CW\*(C`librt\*(C'\fR, but \f(CW\*(C`librt\*(C'\fR
-unconditionally pulls in \f(CW\*(C`libpthread\*(C'\fR, slowing down single-threaded
-programs needlessly. Using a direct syscall is slightly slower (in
-theory), because no optimised vdso implementation can be used, but avoids
-the pthread dependency. Defaults to \f(CW1\fR on GNU/Linux with glibc 2.x or
-higher, as it simplifies linking (no need for \f(CW\*(C`\-lrt\*(C'\fR).
-.IP "\s-1EV_USE_NANOSLEEP\s0" 4
-.IX Item "EV_USE_NANOSLEEP"
-If defined to be \f(CW1\fR, libev will assume that \f(CW\*(C`nanosleep ()\*(C'\fR is available
-and will use it for delays. Otherwise it will use \f(CW\*(C`select ()\*(C'\fR.
-.IP "\s-1EV_USE_EVENTFD\s0" 4
-.IX Item "EV_USE_EVENTFD"
-If defined to be \f(CW1\fR, then libev will assume that \f(CW\*(C`eventfd ()\*(C'\fR is
-available and will probe for kernel support at runtime. This will improve
-\&\f(CW\*(C`ev_signal\*(C'\fR and \f(CW\*(C`ev_async\*(C'\fR performance and reduce resource consumption.
-If undefined, it will be enabled if the headers indicate GNU/Linux + Glibc
-2.7 or newer, otherwise disabled.
-.IP "\s-1EV_USE_SELECT\s0" 4
-.IX Item "EV_USE_SELECT"
-If undefined or defined to be \f(CW1\fR, libev will compile in support for the
-\&\f(CW\*(C`select\*(C'\fR(2) backend. No attempt at auto-detection will be done: if no
-other method takes over, select will be it. Otherwise the select backend
-will not be compiled in.
-.IP "\s-1EV_SELECT_USE_FD_SET\s0" 4
-.IX Item "EV_SELECT_USE_FD_SET"
-If defined to \f(CW1\fR, then the select backend will use the system \f(CW\*(C`fd_set\*(C'\fR
-structure. This is useful if libev doesn't compile due to a missing
-\&\f(CW\*(C`NFDBITS\*(C'\fR or \f(CW\*(C`fd_mask\*(C'\fR definition or it mis-guesses the bitset layout
-on exotic systems. This usually limits the range of file descriptors to
-some low limit such as 1024 or might have other limitations (winsocket
-only allows 64 sockets). The \f(CW\*(C`FD_SETSIZE\*(C'\fR macro, set before compilation,
-configures the maximum size of the \f(CW\*(C`fd_set\*(C'\fR.
-.IP "\s-1EV_SELECT_IS_WINSOCKET\s0" 4
-.IX Item "EV_SELECT_IS_WINSOCKET"
-When defined to \f(CW1\fR, the select backend will assume that
-select/socket/connect etc. don't understand file descriptors but
-wants osf handles on win32 (this is the case when the select to
-be used is the winsock select). This means that it will call
-\&\f(CW\*(C`_get_osfhandle\*(C'\fR on the fd to convert it to an \s-1OS\s0 handle. Otherwise,
-it is assumed that all these functions actually work on fds, even
-on win32. Should not be defined on non\-win32 platforms.
-.IP "\s-1EV_FD_TO_WIN32_HANDLE\s0(fd)" 4
-.IX Item "EV_FD_TO_WIN32_HANDLE(fd)"
-If \f(CW\*(C`EV_SELECT_IS_WINSOCKET\*(C'\fR is enabled, then libev needs a way to map
-file descriptors to socket handles. When not defining this symbol (the
-default), then libev will call \f(CW\*(C`_get_osfhandle\*(C'\fR, which is usually
-correct. In some cases, programs use their own file descriptor management,
-in which case they can provide this function to map fds to socket handles.
-.IP "\s-1EV_WIN32_HANDLE_TO_FD\s0(handle)" 4
-.IX Item "EV_WIN32_HANDLE_TO_FD(handle)"
-If \f(CW\*(C`EV_SELECT_IS_WINSOCKET\*(C'\fR then libev maps handles to file descriptors
-using the standard \f(CW\*(C`_open_osfhandle\*(C'\fR function. For programs implementing
-their own fd to handle mapping, overwriting this function makes it easier
-to do so. This can be done by defining this macro to an appropriate value.
-.IP "\s-1EV_WIN32_CLOSE_FD\s0(fd)" 4
-.IX Item "EV_WIN32_CLOSE_FD(fd)"
-If programs implement their own fd to handle mapping on win32, then this
-macro can be used to override the \f(CW\*(C`close\*(C'\fR function, useful to unregister
-file descriptors again. Note that the replacement function has to close
-the underlying \s-1OS\s0 handle.
-.IP "\s-1EV_USE_POLL\s0" 4
-.IX Item "EV_USE_POLL"
-If defined to be \f(CW1\fR, libev will compile in support for the \f(CW\*(C`poll\*(C'\fR(2)
-backend. Otherwise it will be enabled on non\-win32 platforms. It
-takes precedence over select.
-.IP "\s-1EV_USE_EPOLL\s0" 4
-.IX Item "EV_USE_EPOLL"
-If defined to be \f(CW1\fR, libev will compile in support for the Linux
-\&\f(CW\*(C`epoll\*(C'\fR(7) backend. Its availability will be detected at runtime,
-otherwise another method will be used as fallback. This is the preferred
-backend for GNU/Linux systems. If undefined, it will be enabled if the
-headers indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled.
-.IP "\s-1EV_USE_KQUEUE\s0" 4
-.IX Item "EV_USE_KQUEUE"
-If defined to be \f(CW1\fR, libev will compile in support for the \s-1BSD\s0 style
-\&\f(CW\*(C`kqueue\*(C'\fR(2) backend. Its actual availability will be detected at runtime,
-otherwise another method will be used as fallback. This is the preferred
-backend for \s-1BSD\s0 and BSD-like systems, although on most BSDs kqueue only
-supports some types of fds correctly (the only platform we found that
-supports ptys for example was NetBSD), so kqueue might be compiled in, but
-not be used unless explicitly requested. The best way to use it is to find
-out whether kqueue supports your type of fd properly and use an embedded
-kqueue loop.
-.IP "\s-1EV_USE_PORT\s0" 4
-.IX Item "EV_USE_PORT"
-If defined to be \f(CW1\fR, libev will compile in support for the Solaris
-10 port style backend. Its availability will be detected at runtime,
-otherwise another method will be used as fallback. This is the preferred
-backend for Solaris 10 systems.
-.IP "\s-1EV_USE_DEVPOLL\s0" 4
-.IX Item "EV_USE_DEVPOLL"
-Reserved for future expansion, works like the \s-1USE\s0 symbols above.
-.IP "\s-1EV_USE_INOTIFY\s0" 4
-.IX Item "EV_USE_INOTIFY"
-If defined to be \f(CW1\fR, libev will compile in support for the Linux inotify
-interface to speed up \f(CW\*(C`ev_stat\*(C'\fR watchers. Its actual availability will
-be detected at runtime. If undefined, it will be enabled if the headers
-indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled.
-.IP "\s-1EV_ATOMIC_T\s0" 4
-.IX Item "EV_ATOMIC_T"
-Libev requires an integer type (suitable for storing \f(CW0\fR or \f(CW1\fR) whose
-access is atomic with respect to other threads or signal contexts. No such
-type is easily found in the C language, so you can provide your own type
-that you know is safe for your purposes. It is used both for signal handler \*(L"locking\*(R"
-as well as for signal and thread safety in \f(CW\*(C`ev_async\*(C'\fR watchers.
-.Sp
-In the absence of this define, libev will use \f(CW\*(C`sig_atomic_t volatile\*(C'\fR
-(from \fIsignal.h\fR), which is usually good enough on most platforms.
-.IP "\s-1EV_H\s0 (h)" 4
-.IX Item "EV_H (h)"
-The name of the \fIev.h\fR header file used to include it. The default if
-undefined is \f(CW"ev.h"\fR in \fIevent.h\fR, \fIev.c\fR and \fIev++.h\fR. This can be
-used to virtually rename the \fIev.h\fR header file in case of conflicts.
-.IP "\s-1EV_CONFIG_H\s0 (h)" 4
-.IX Item "EV_CONFIG_H (h)"
-If \f(CW\*(C`EV_STANDALONE\*(C'\fR isn't \f(CW1\fR, this variable can be used to override
-\&\fIev.c\fR's idea of where to find the \fIconfig.h\fR file, similarly to
-\&\f(CW\*(C`EV_H\*(C'\fR, above.
-.IP "\s-1EV_EVENT_H\s0 (h)" 4
-.IX Item "EV_EVENT_H (h)"
-Similarly to \f(CW\*(C`EV_H\*(C'\fR, this macro can be used to override \fIevent.c\fR's idea
-of how the \fIevent.h\fR header can be found, the default is \f(CW"event.h"\fR.
-.IP "\s-1EV_PROTOTYPES\s0 (h)" 4
-.IX Item "EV_PROTOTYPES (h)"
-If defined to be \f(CW0\fR, then \fIev.h\fR will not define any function
-prototypes, but still define all the structs and other symbols. This is
-occasionally useful if you want to provide your own wrapper functions
-around libev functions.
-.IP "\s-1EV_MULTIPLICITY\s0" 4
-.IX Item "EV_MULTIPLICITY"
-If undefined or defined to \f(CW1\fR, then all event-loop-specific functions
-will have the \f(CW\*(C`struct ev_loop *\*(C'\fR as first argument, and you can create
-additional independent event loops. Otherwise there will be no support
-for multiple event loops and there is no first event loop pointer
-argument. Instead, all functions act on the single default loop.
-.IP "\s-1EV_MINPRI\s0" 4
-.IX Item "EV_MINPRI"
-.PD 0
-.IP "\s-1EV_MAXPRI\s0" 4
-.IX Item "EV_MAXPRI"
-.PD
-The range of allowed priorities. \f(CW\*(C`EV_MINPRI\*(C'\fR must be smaller or equal to
-\&\f(CW\*(C`EV_MAXPRI\*(C'\fR, but otherwise there are no non-obvious limitations. You can
-provide for more priorities by overriding those symbols (usually defined
-to be \f(CW\*(C`\-2\*(C'\fR and \f(CW2\fR, respectively).
-.Sp
-When doing priority-based operations, libev usually has to linearly search
-all the priorities, so having many of them (hundreds) uses a lot of space
-and time, so using the defaults of five priorities (\-2 .. +2) is usually
-fine.
-.Sp
-If your embedding application does not need any priorities, defining these
-both to \f(CW0\fR will save some memory and \s-1CPU\s0.
-.IP "\s-1EV_PERIODIC_ENABLE\s0, \s-1EV_IDLE_ENABLE\s0, \s-1EV_EMBED_ENABLE\s0, \s-1EV_STAT_ENABLE\s0, \s-1EV_PREPARE_ENABLE\s0, \s-1EV_CHECK_ENABLE\s0, \s-1EV_FORK_ENABLE\s0, \s-1EV_SIGNAL_ENABLE\s0, \s-1EV_ASYNC_ENABLE\s0, \s-1EV_CHILD_ENABLE\s0." 4
-.IX Item "EV_PERIODIC_ENABLE, EV_IDLE_ENABLE, EV_EMBED_ENABLE, EV_STAT_ENABLE, EV_PREPARE_ENABLE, EV_CHECK_ENABLE, EV_FORK_ENABLE, EV_SIGNAL_ENABLE, EV_ASYNC_ENABLE, EV_CHILD_ENABLE."
-If undefined or defined to be \f(CW1\fR (and the platform supports it), then
-the respective watcher type is supported. If defined to be \f(CW0\fR, then it
-is not. Disabling watcher types mainly saves code size.
-.IP "\s-1EV_FEATURES\s0" 4
-.IX Item "EV_FEATURES"
-If you need to shave off some kilobytes of code at the expense of some
-speed (but with the full \s-1API\s0), you can define this symbol to request
-certain subsets of functionality. The default is to enable all features
-that can be enabled on the platform.
-.Sp
-A typical way to use this symbol is to define it to \f(CW0\fR (or to a bitset
-with some broad features you want) and then selectively re-enable
-additional parts you want, for example if you want everything minimal,
-but multiple event loop support, async and child watchers and the poll
-backend, use this:
-.Sp
-.Vb 5
-\& #define EV_FEATURES 0
-\& #define EV_MULTIPLICITY 1
-\& #define EV_USE_POLL 1
-\& #define EV_CHILD_ENABLE 1
-\& #define EV_ASYNC_ENABLE 1
-.Ve
-.Sp
-The actual value is a bitset, it can be a combination of the following
-values:
-.RS 4
-.ie n .IP "1 \- faster/larger code" 4
-.el .IP "\f(CW1\fR \- faster/larger code" 4
-.IX Item "1 - faster/larger code"
-Use larger code to speed up some operations.
-.Sp
-Currently this is used to override some inlining decisions (enlarging the
-code size by roughly 30% on amd64).
-.Sp
-When optimising for size, use of compiler flags such as \f(CW\*(C`\-Os\*(C'\fR with
-gcc is recommended, as well as \f(CW\*(C`\-DNDEBUG\*(C'\fR, as libev contains a number of
-assertions.
-.ie n .IP "2 \- faster/larger data structures" 4
-.el .IP "\f(CW2\fR \- faster/larger data structures" 4
-.IX Item "2 - faster/larger data structures"
-Replaces the small 2\-heap for timer management by a faster 4\-heap, larger
-hash table sizes and so on. This will usually further increase code size
-and can additionally have an effect on the size of data structures at
-runtime.
-.ie n .IP "4 \- full \s-1API\s0 configuration" 4
-.el .IP "\f(CW4\fR \- full \s-1API\s0 configuration" 4
-.IX Item "4 - full API configuration"
-This enables priorities (sets \f(CW\*(C`EV_MAXPRI\*(C'\fR=2 and \f(CW\*(C`EV_MINPRI\*(C'\fR=\-2), and
-enables multiplicity (\f(CW\*(C`EV_MULTIPLICITY\*(C'\fR=1).
-.ie n .IP "8 \- full \s-1API\s0" 4
-.el .IP "\f(CW8\fR \- full \s-1API\s0" 4
-.IX Item "8 - full API"
-This enables a lot of the \*(L"lesser used\*(R" \s-1API\s0 functions. See \f(CW\*(C`ev.h\*(C'\fR for
-details on which parts of the \s-1API\s0 are still available without this
-feature, and do not complain if this subset changes over time.
-.ie n .IP "16 \- enable all optional watcher types" 4
-.el .IP "\f(CW16\fR \- enable all optional watcher types" 4
-.IX Item "16 - enable all optional watcher types"
-Enables all optional watcher types. If you want to selectively enable
-only some watcher types other than I/O and timers (e.g. prepare,
-embed, async, child...) you can enable them manually by defining
-\&\f(CW\*(C`EV_watchertype_ENABLE\*(C'\fR to \f(CW1\fR instead.
-.ie n .IP "32 \- enable all backends" 4
-.el .IP "\f(CW32\fR \- enable all backends" 4
-.IX Item "32 - enable all backends"
-This enables all backends \- without this feature, you need to enable at
-least one backend manually (\f(CW\*(C`EV_USE_SELECT\*(C'\fR is a good choice).
-.ie n .IP "64 \- enable OS-specific ""helper"" APIs" 4
-.el .IP "\f(CW64\fR \- enable OS-specific ``helper'' APIs" 4
-.IX Item "64 - enable OS-specific helper APIs"
-Enable inotify, eventfd, signalfd and similar OS-specific helper APIs by
-default.
-.RE
-.RS 4
-.Sp
-Compiling with \f(CW\*(C`gcc \-Os \-DEV_STANDALONE \-DEV_USE_EPOLL=1 \-DEV_FEATURES=0\*(C'\fR
-reduces the compiled size of libev from 24.7Kb code/2.8Kb data to 6.5Kb
-code/0.3Kb data on my GNU/Linux amd64 system, while still giving you I/O
-watchers, timers and monotonic clock support.
-.Sp
-With an intelligent-enough linker (gcc+binutils are intelligent enough
-when you use \f(CW\*(C`\-Wl,\-\-gc\-sections \-ffunction\-sections\*(C'\fR) functions unused by
-your program might be left out as well \- a binary starting a timer and an
-I/O watcher then might come out at only 5Kb.
-.RE
-.IP "\s-1EV_AVOID_STDIO\s0" 4
-.IX Item "EV_AVOID_STDIO"
-If this is set to \f(CW1\fR at compiletime, then libev will avoid using stdio
-functions (printf, scanf, perror etc.). This will increase the code size
-somewhat, but if your program doesn't otherwise depend on stdio and your
-libc allows it, this avoids linking in the stdio library which is quite
-big.
-.Sp
-Note that error messages might become less precise when this option is
-enabled.
-.IP "\s-1EV_NSIG\s0" 4
-.IX Item "EV_NSIG"
-The highest supported signal number, +1 (or, the number of
-signals): Normally, libev tries to deduce the maximum number of signals
-automatically, but sometimes this fails, in which case it can be
-specified. Also, using a lower number than detected (\f(CW32\fR should be
-good for about any system in existence) can save some memory, as libev
-statically allocates some 12\-24 bytes per signal number.
-.IP "\s-1EV_PID_HASHSIZE\s0" 4
-.IX Item "EV_PID_HASHSIZE"
-\&\f(CW\*(C`ev_child\*(C'\fR watchers use a small hash table to distribute workload by
-pid. The default size is \f(CW16\fR (or \f(CW1\fR with \f(CW\*(C`EV_FEATURES\*(C'\fR disabled),
-usually more than enough. If you need to manage thousands of children you
-might want to increase this value (\fImust\fR be a power of two).
-.IP "\s-1EV_INOTIFY_HASHSIZE\s0" 4
-.IX Item "EV_INOTIFY_HASHSIZE"
-\&\f(CW\*(C`ev_stat\*(C'\fR watchers use a small hash table to distribute workload by
-inotify watch id. The default size is \f(CW16\fR (or \f(CW1\fR with \f(CW\*(C`EV_FEATURES\*(C'\fR
-disabled), usually more than enough. If you need to manage thousands of
-\&\f(CW\*(C`ev_stat\*(C'\fR watchers you might want to increase this value (\fImust\fR be a
-power of two).
-.IP "\s-1EV_USE_4HEAP\s0" 4
-.IX Item "EV_USE_4HEAP"
-Heaps are not very cache-efficient. To improve the cache-efficiency of the
-timer and periodics heaps, libev uses a 4\-heap when this symbol is defined
-to \f(CW1\fR. The 4\-heap uses more complicated (longer) code but has noticeably
-faster performance with many (thousands) of watchers.
-.Sp
-The default is \f(CW1\fR, unless \f(CW\*(C`EV_FEATURES\*(C'\fR overrides it, in which case it
-will be \f(CW0\fR.
-.IP "\s-1EV_HEAP_CACHE_AT\s0" 4
-.IX Item "EV_HEAP_CACHE_AT"
-Heaps are not very cache-efficient. To improve the cache-efficiency of the
-timer and periodics heaps, libev can cache the timestamp (\fIat\fR) within
-the heap structure (selected by defining \f(CW\*(C`EV_HEAP_CACHE_AT\*(C'\fR to \f(CW1\fR),
-which uses 8\-12 bytes more per watcher and a few hundred bytes more code,
-but avoids random read accesses on heap changes. This improves performance
-noticeably with many (hundreds) of watchers.
-.Sp
-The default is \f(CW1\fR, unless \f(CW\*(C`EV_FEATURES\*(C'\fR overrides it, in which case it
-will be \f(CW0\fR.
-.IP "\s-1EV_VERIFY\s0" 4
-.IX Item "EV_VERIFY"
-Controls how much internal verification (see \f(CW\*(C`ev_verify ()\*(C'\fR) will
-be done: If set to \f(CW0\fR, no internal verification code will be compiled
-in. If set to \f(CW1\fR, then verification code will be compiled in, but not
-called. If set to \f(CW2\fR, then the internal verification code will be
-called once per loop, which can slow down libev. If set to \f(CW3\fR, then the
-verification code will be called very frequently, which will slow down
-libev considerably.
-.Sp
-The default is \f(CW1\fR, unless \f(CW\*(C`EV_FEATURES\*(C'\fR overrides it, in which case it
-will be \f(CW0\fR.
-.IP "\s-1EV_COMMON\s0" 4
-.IX Item "EV_COMMON"
-By default, all watchers have a \f(CW\*(C`void *data\*(C'\fR member. By redefining
-this macro to something else you can include more and other types of
-members. You have to define it each time you include one of the files,
-though, and it must be identical each time.
-.Sp
-For example, the perl \s-1EV\s0 module uses something like this:
-.Sp
-.Vb 3
-\& #define EV_COMMON \e
-\& SV *self; /* contains this struct */ \e
-\& SV *cb_sv, *fh /* note no trailing ";" */
-.Ve
-.IP "\s-1EV_CB_DECLARE\s0 (type)" 4
-.IX Item "EV_CB_DECLARE (type)"
-.PD 0
-.IP "\s-1EV_CB_INVOKE\s0 (watcher, revents)" 4
-.IX Item "EV_CB_INVOKE (watcher, revents)"
-.IP "ev_set_cb (ev, cb)" 4
-.IX Item "ev_set_cb (ev, cb)"
-.PD
-Can be used to change the callback member declaration in each watcher,
-and the way callbacks are invoked and set. Must expand to a struct member
-definition and a statement, respectively. See the \fIev.h\fR header file for
-their default definitions. One possible use for overriding these is to
-avoid the \f(CW\*(C`struct ev_loop *\*(C'\fR as first argument in all cases, or to use
-method calls instead of plain function calls in \*(C+.
-.SS "\s-1EXPORTED\s0 \s-1API\s0 \s-1SYMBOLS\s0"
-.IX Subsection "EXPORTED API SYMBOLS"
-If you need to re-export the \s-1API\s0 (e.g. via a \s-1DLL\s0) and you need a list of
-exported symbols, you can use the provided \fISymbol.*\fR files which list
-all public symbols, one per line:
-.PP
-.Vb 2
-\& Symbols.ev for libev proper
-\& Symbols.event for the libevent emulation
-.Ve
-.PP
-This can also be used to rename all public symbols to avoid clashes with
-multiple versions of libev linked together (which is obviously bad in
-itself, but sometimes it is inconvenient to avoid this).
-.PP
-A sed command like this will create wrapper \f(CW\*(C`#define\*(C'\fR's that you need to
-include before including \fIev.h\fR:
-.PP
-.Vb 1
-\& <Symbols.ev sed \-e "s/.*/#define & myprefix_&/" >wrap.h
-.Ve
-.PP
-This would create a file \fIwrap.h\fR which essentially looks like this:
-.PP
-.Vb 4
-\& #define ev_backend myprefix_ev_backend
-\& #define ev_check_start myprefix_ev_check_start
-\& #define ev_check_stop myprefix_ev_check_stop
-\& ...
-.Ve
-.SS "\s-1EXAMPLES\s0"
-.IX Subsection "EXAMPLES"
-For a real-world example of a program the includes libev
-verbatim, you can have a look at the \s-1EV\s0 perl module
-(<http://software.schmorp.de/pkg/EV.html>). It has the libev files in
-the \fIlibev/\fR subdirectory and includes them in the \fI\s-1EV/EVAPI\s0.h\fR (public
-interface) and \fI\s-1EV\s0.xs\fR (implementation) files. Only the \fI\s-1EV\s0.xs\fR file
-will be compiled. It is pretty complex because it provides its own header
-file.
-.PP
-The usage in rxvt-unicode is simpler. It has a \fIev_cpp.h\fR header file
-that everybody includes and which overrides some configure choices:
-.PP
-.Vb 8
-\& #define EV_FEATURES 8
-\& #define EV_USE_SELECT 1
-\& #define EV_PREPARE_ENABLE 1
-\& #define EV_IDLE_ENABLE 1
-\& #define EV_SIGNAL_ENABLE 1
-\& #define EV_CHILD_ENABLE 1
-\& #define EV_USE_STDEXCEPT 0
-\& #define EV_CONFIG_H <config.h>
-\&
-\& #include "ev++.h"
-.Ve
-.PP
-And a \fIev_cpp.C\fR implementation file that contains libev proper and is compiled:
-.PP
-.Vb 2
-\& #include "ev_cpp.h"
-\& #include "ev.c"
-.Ve
-.SH "INTERACTION WITH OTHER PROGRAMS, LIBRARIES OR THE ENVIRONMENT"
-.IX Header "INTERACTION WITH OTHER PROGRAMS, LIBRARIES OR THE ENVIRONMENT"
-.SS "\s-1THREADS\s0 \s-1AND\s0 \s-1COROUTINES\s0"
-.IX Subsection "THREADS AND COROUTINES"
-\fI\s-1THREADS\s0\fR
-.IX Subsection "THREADS"
-.PP
-All libev functions are reentrant and thread-safe unless explicitly
-documented otherwise, but libev implements no locking itself. This means
-that you can use as many loops as you want in parallel, as long as there
-are no concurrent calls into any libev function with the same loop
-parameter (\f(CW\*(C`ev_default_*\*(C'\fR calls have an implicit default loop parameter,
-of course): libev guarantees that different event loops share no data
-structures that need any locking.
-.PP
-Or to put it differently: calls with different loop parameters can be done
-concurrently from multiple threads, calls with the same loop parameter
-must be done serially (but can be done from different threads, as long as
-only one thread ever is inside a call at any point in time, e.g. by using
-a mutex per loop).
-.PP
-Specifically to support threads (and signal handlers), libev implements
-so-called \f(CW\*(C`ev_async\*(C'\fR watchers, which allow some limited form of
-concurrency on the same event loop, namely waking it up \*(L"from the
-outside\*(R".
-.PP
-If you want to know which design (one loop, locking, or multiple loops
-without or something else still) is best for your problem, then I cannot
-help you, but here is some generic advice:
-.IP "\(bu" 4
-most applications have a main thread: use the default libev loop
-in that thread, or create a separate thread running only the default loop.
-.Sp
-This helps integrating other libraries or software modules that use libev
-themselves and don't care/know about threading.
-.IP "\(bu" 4
-one loop per thread is usually a good model.
-.Sp
-Doing this is almost never wrong, sometimes a better-performance model
-exists, but it is always a good start.
-.IP "\(bu" 4
-other models exist, such as the leader/follower pattern, where one
-loop is handed through multiple threads in a kind of round-robin fashion.
-.Sp
-Choosing a model is hard \- look around, learn, know that usually you can do
-better than you currently do :\-)
-.IP "\(bu" 4
-often you need to talk to some other thread which blocks in the
-event loop.
-.Sp
-\&\f(CW\*(C`ev_async\*(C'\fR watchers can be used to wake them up from other threads safely
-(or from signal contexts...).
-.Sp
-An example use would be to communicate signals or other events that only
-work in the default loop by registering the signal watcher with the
-default loop and triggering an \f(CW\*(C`ev_async\*(C'\fR watcher from the default loop
-watcher callback into the event loop interested in the signal.
-.PP
-See also \*(L"\s-1THREAD\s0 \s-1LOCKING\s0 \s-1EXAMPLE\s0\*(R".
-.PP
-\fI\s-1COROUTINES\s0\fR
-.IX Subsection "COROUTINES"
-.PP
-Libev is very accommodating to coroutines (\*(L"cooperative threads\*(R"):
-libev fully supports nesting calls to its functions from different
-coroutines (e.g. you can call \f(CW\*(C`ev_run\*(C'\fR on the same loop from two
-different coroutines, and switch freely between both coroutines running
-the loop, as long as you don't confuse yourself). The only exception is
-that you must not do this from \f(CW\*(C`ev_periodic\*(C'\fR reschedule callbacks.
-.PP
-Care has been taken to ensure that libev does not keep local state inside
-\&\f(CW\*(C`ev_run\*(C'\fR, and other calls do not usually allow for coroutine switches as
-they do not call any callbacks.
-.SS "\s-1COMPILER\s0 \s-1WARNINGS\s0"
-.IX Subsection "COMPILER WARNINGS"
-Depending on your compiler and compiler settings, you might get no or a
-lot of warnings when compiling libev code. Some people are apparently
-scared by this.
-.PP
-However, these are unavoidable for many reasons. For one, each compiler
-has different warnings, and each user has different tastes regarding
-warning options. \*(L"Warn-free\*(R" code therefore cannot be a goal except when
-targeting a specific compiler and compiler-version.
-.PP
-Another reason is that some compiler warnings require elaborate
-workarounds, or other changes to the code that make it less clear and less
-maintainable.
-.PP
-And of course, some compiler warnings are just plain stupid, or simply
-wrong (because they don't actually warn about the condition their message
-seems to warn about). For example, certain older gcc versions had some
-warnings that resulted in an extreme number of false positives. These have
-been fixed, but some people still insist on making code warn-free with
-such buggy versions.
-.PP
-While libev is written to generate as few warnings as possible,
-\&\*(L"warn-free\*(R" code is not a goal, and it is recommended not to build libev
-with any compiler warnings enabled unless you are prepared to cope with
-them (e.g. by ignoring them). Remember that warnings are just that:
-warnings, not errors, or proof of bugs.
-.SS "\s-1VALGRIND\s0"
-.IX Subsection "VALGRIND"
-Valgrind has a special section here because it is a popular tool that is
-highly useful. Unfortunately, valgrind reports are very hard to interpret.
-.PP
-If you think you found a bug (memory leak, uninitialised data access etc.)
-in libev, then check twice: If valgrind reports something like:
-.PP
-.Vb 3
-\& ==2274== definitely lost: 0 bytes in 0 blocks.
-\& ==2274== possibly lost: 0 bytes in 0 blocks.
-\& ==2274== still reachable: 256 bytes in 1 blocks.
-.Ve
-.PP
-Then there is no memory leak, just as memory accounted to global variables
-is not a memleak \- the memory is still being referenced, and didn't leak.
-.PP
-Similarly, under some circumstances, valgrind might report kernel bugs
-as if it were a bug in libev (e.g. in realloc or in the poll backend,
-although an acceptable workaround has been found here), or it might be
-confused.
-.PP
-Keep in mind that valgrind is a very good tool, but only a tool. Don't
-make it into some kind of religion.
-.PP
-If you are unsure about something, feel free to contact the mailing list
-with the full valgrind report and an explanation on why you think this
-is a bug in libev (best check the archives, too :). However, don't be
-annoyed when you get a brisk \*(L"this is no bug\*(R" answer and take the chance
-of learning how to interpret valgrind properly.
-.PP
-If you need, for some reason, empty reports from valgrind for your project
-I suggest using suppression lists.
-.SH "PORTABILITY NOTES"
-.IX Header "PORTABILITY NOTES"
-.SS "\s-1GNU/LINUX\s0 32 \s-1BIT\s0 \s-1LIMITATIONS\s0"
-.IX Subsection "GNU/LINUX 32 BIT LIMITATIONS"
-GNU/Linux is the only common platform that supports 64 bit file/large file
-interfaces but \fIdisables\fR them by default.
-.PP
-That means that libev compiled in the default environment doesn't support
-files larger than 2GiB or so, which mainly affects \f(CW\*(C`ev_stat\*(C'\fR watchers.
-.PP
-Unfortunately, many programs try to work around this GNU/Linux issue
-by enabling the large file \s-1API\s0, which makes them incompatible with the
-standard libev compiled for their system.
-.PP
-Likewise, libev cannot enable the large file \s-1API\s0 itself as this would
-suddenly make it incompatible to the default compile time environment,
-i.e. all programs not using special compile switches.
-.SS "\s-1OS/X\s0 \s-1AND\s0 \s-1DARWIN\s0 \s-1BUGS\s0"
-.IX Subsection "OS/X AND DARWIN BUGS"
-The whole thing is a bug if you ask me \- basically any system interface
-you touch is broken, whether it is locales, poll, kqueue or even the
-OpenGL drivers.
-.PP
-\fI\f(CI\*(C`kqueue\*(C'\fI is buggy\fR
-.IX Subsection "kqueue is buggy"
-.PP
-The kqueue syscall is broken in all known versions \- most versions support
-only sockets, many support pipes.
-.PP
-Libev tries to work around this by not using \f(CW\*(C`kqueue\*(C'\fR by default on this
-rotten platform, but of course you can still ask for it when creating a
-loop \- embedding a socket-only kqueue loop into a select-based one is
-probably going to work well.
-.PP
-\fI\f(CI\*(C`poll\*(C'\fI is buggy\fR
-.IX Subsection "poll is buggy"
-.PP
-Instead of fixing \f(CW\*(C`kqueue\*(C'\fR, Apple replaced their (working) \f(CW\*(C`poll\*(C'\fR
-implementation by something calling \f(CW\*(C`kqueue\*(C'\fR internally around the 10.5.6
-release, so now \f(CW\*(C`kqueue\*(C'\fR \fIand\fR \f(CW\*(C`poll\*(C'\fR are broken.
-.PP
-Libev tries to work around this by not using \f(CW\*(C`poll\*(C'\fR by default on
-this rotten platform, but of course you can still ask for it when creating
-a loop.
-.PP
-\fI\f(CI\*(C`select\*(C'\fI is buggy\fR
-.IX Subsection "select is buggy"
-.PP
-All that's left is \f(CW\*(C`select\*(C'\fR, and of course Apple found a way to fuck this
-one up as well: On \s-1OS/X\s0, \f(CW\*(C`select\*(C'\fR actively limits the number of file
-descriptors you can pass in to 1024 \- your program suddenly crashes when
-you use more.
-.PP
-There is an undocumented \*(L"workaround\*(R" for this \- defining
-\&\f(CW\*(C`_DARWIN_UNLIMITED_SELECT\*(C'\fR, which libev tries to use, so select \fIshould\fR
-work on \s-1OS/X\s0.
-.SS "\s-1SOLARIS\s0 \s-1PROBLEMS\s0 \s-1AND\s0 \s-1WORKAROUNDS\s0"
-.IX Subsection "SOLARIS PROBLEMS AND WORKAROUNDS"
-\fI\f(CI\*(C`errno\*(C'\fI reentrancy\fR
-.IX Subsection "errno reentrancy"
-.PP
-The default compile environment on Solaris is unfortunately so
-thread-unsafe that you can't even use components/libraries compiled
-without \f(CW\*(C`\-D_REENTRANT\*(C'\fR in a threaded program, which, of course, isn't
-defined by default. A valid, if stupid, implementation choice.
-.PP
-If you want to use libev in threaded environments you have to make sure
-it's compiled with \f(CW\*(C`_REENTRANT\*(C'\fR defined.
-.PP
-\fIEvent port backend\fR
-.IX Subsection "Event port backend"
-.PP
-The scalable event interface for Solaris is called \*(L"event
-ports\*(R". Unfortunately, this mechanism is very buggy in all major
-releases. If you run into high \s-1CPU\s0 usage, your program freezes or you get
-a large number of spurious wakeups, make sure you have all the relevant
-and latest kernel patches applied. No, I don't know which ones, but there
-are multiple ones to apply, and afterwards, event ports actually work
-great.
-.PP
-If you can't get it to work, you can try running the program by setting
-the environment variable \f(CW\*(C`LIBEV_FLAGS=3\*(C'\fR to only allow \f(CW\*(C`poll\*(C'\fR and
-\&\f(CW\*(C`select\*(C'\fR backends.
-.SS "\s-1AIX\s0 \s-1POLL\s0 \s-1BUG\s0"
-.IX Subsection "AIX POLL BUG"
-\&\s-1AIX\s0 unfortunately has a broken \f(CW\*(C`poll.h\*(C'\fR header. Libev works around
-this by trying to avoid the poll backend altogether (i.e. it's not even
-compiled in), which normally isn't a big problem as \f(CW\*(C`select\*(C'\fR works fine
-with large bitsets on \s-1AIX\s0, and \s-1AIX\s0 is dead anyway.
-.SS "\s-1WIN32\s0 \s-1PLATFORM\s0 \s-1LIMITATIONS\s0 \s-1AND\s0 \s-1WORKAROUNDS\s0"
-.IX Subsection "WIN32 PLATFORM LIMITATIONS AND WORKAROUNDS"
-\fIGeneral issues\fR
-.IX Subsection "General issues"
-.PP
-Win32 doesn't support any of the standards (e.g. \s-1POSIX\s0) that libev
-requires, and its I/O model is fundamentally incompatible with the \s-1POSIX\s0
-model. Libev still offers limited functionality on this platform in
-the form of the \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR backend, and only supports socket
-descriptors. This only applies when using Win32 natively, not when using
-e.g. cygwin. Actually, it only applies to the microsofts own compilers,
-as every compielr comes with a slightly differently broken/incompatible
-environment.
-.PP
-Lifting these limitations would basically require the full
-re-implementation of the I/O system. If you are into this kind of thing,
-then note that glib does exactly that for you in a very portable way (note
-also that glib is the slowest event library known to man).
-.PP
-There is no supported compilation method available on windows except
-embedding it into other applications.
-.PP
-Sensible signal handling is officially unsupported by Microsoft \- libev
-tries its best, but under most conditions, signals will simply not work.
-.PP
-Not a libev limitation but worth mentioning: windows apparently doesn't
-accept large writes: instead of resulting in a partial write, windows will
-either accept everything or return \f(CW\*(C`ENOBUFS\*(C'\fR if the buffer is too large,
-so make sure you only write small amounts into your sockets (less than a
-megabyte seems safe, but this apparently depends on the amount of memory
-available).
-.PP
-Due to the many, low, and arbitrary limits on the win32 platform and
-the abysmal performance of winsockets, using a large number of sockets
-is not recommended (and not reasonable). If your program needs to use
-more than a hundred or so sockets, then likely it needs to use a totally
-different implementation for windows, as libev offers the \s-1POSIX\s0 readiness
-notification model, which cannot be implemented efficiently on windows
-(due to Microsoft monopoly games).
-.PP
-A typical way to use libev under windows is to embed it (see the embedding
-section for details) and use the following \fIevwrap.h\fR header file instead
-of \fIev.h\fR:
-.PP
-.Vb 2
-\& #define EV_STANDALONE /* keeps ev from requiring config.h */
-\& #define EV_SELECT_IS_WINSOCKET 1 /* configure libev for windows select */
-\&
-\& #include "ev.h"
-.Ve
-.PP
-And compile the following \fIevwrap.c\fR file into your project (make sure
-you do \fInot\fR compile the \fIev.c\fR or any other embedded source files!):
-.PP
-.Vb 2
-\& #include "evwrap.h"
-\& #include "ev.c"
-.Ve
-.PP
-\fIThe winsocket \f(CI\*(C`select\*(C'\fI function\fR
-.IX Subsection "The winsocket select function"
-.PP
-The winsocket \f(CW\*(C`select\*(C'\fR function doesn't follow \s-1POSIX\s0 in that it
-requires socket \fIhandles\fR and not socket \fIfile descriptors\fR (it is
-also extremely buggy). This makes select very inefficient, and also
-requires a mapping from file descriptors to socket handles (the Microsoft
-C runtime provides the function \f(CW\*(C`_open_osfhandle\*(C'\fR for this). See the
-discussion of the \f(CW\*(C`EV_SELECT_USE_FD_SET\*(C'\fR, \f(CW\*(C`EV_SELECT_IS_WINSOCKET\*(C'\fR and
-\&\f(CW\*(C`EV_FD_TO_WIN32_HANDLE\*(C'\fR preprocessor symbols for more info.
-.PP
-The configuration for a \*(L"naked\*(R" win32 using the Microsoft runtime
-libraries and raw winsocket select is:
-.PP
-.Vb 2
-\& #define EV_USE_SELECT 1
-\& #define EV_SELECT_IS_WINSOCKET 1 /* forces EV_SELECT_USE_FD_SET, too */
-.Ve
-.PP
-Note that winsockets handling of fd sets is O(n), so you can easily get a
-complexity in the O(nA\*^X) range when using win32.
-.PP
-\fILimited number of file descriptors\fR
-.IX Subsection "Limited number of file descriptors"
-.PP
-Windows has numerous arbitrary (and low) limits on things.
-.PP
-Early versions of winsocket's select only supported waiting for a maximum
-of \f(CW64\fR handles (probably owning to the fact that all windows kernels
-can only wait for \f(CW64\fR things at the same time internally; Microsoft
-recommends spawning a chain of threads and wait for 63 handles and the
-previous thread in each. Sounds great!).
-.PP
-Newer versions support more handles, but you need to define \f(CW\*(C`FD_SETSIZE\*(C'\fR
-to some high number (e.g. \f(CW2048\fR) before compiling the winsocket select
-call (which might be in libev or elsewhere, for example, perl and many
-other interpreters do their own select emulation on windows).
-.PP
-Another limit is the number of file descriptors in the Microsoft runtime
-libraries, which by default is \f(CW64\fR (there must be a hidden \fI64\fR
-fetish or something like this inside Microsoft). You can increase this
-by calling \f(CW\*(C`_setmaxstdio\*(C'\fR, which can increase this limit to \f(CW2048\fR
-(another arbitrary limit), but is broken in many versions of the Microsoft
-runtime libraries. This might get you to about \f(CW512\fR or \f(CW2048\fR sockets
-(depending on windows version and/or the phase of the moon). To get more,
-you need to wrap all I/O functions and provide your own fd management, but
-the cost of calling select (O(nA\*^X)) will likely make this unworkable.
-.SS "\s-1PORTABILITY\s0 \s-1REQUIREMENTS\s0"
-.IX Subsection "PORTABILITY REQUIREMENTS"
-In addition to a working ISO-C implementation and of course the
-backend-specific APIs, libev relies on a few additional extensions:
-.ie n .IP """void (*)(ev_watcher_type *, int revents)"" must have compatible calling conventions regardless of ""ev_watcher_type *""." 4
-.el .IP "\f(CWvoid (*)(ev_watcher_type *, int revents)\fR must have compatible calling conventions regardless of \f(CWev_watcher_type *\fR." 4
-.IX Item "void (*)(ev_watcher_type *, int revents) must have compatible calling conventions regardless of ev_watcher_type *."
-Libev assumes not only that all watcher pointers have the same internal
-structure (guaranteed by \s-1POSIX\s0 but not by \s-1ISO\s0 C for example), but it also
-assumes that the same (machine) code can be used to call any watcher
-callback: The watcher callbacks have different type signatures, but libev
-calls them using an \f(CW\*(C`ev_watcher *\*(C'\fR internally.
-.IP "pointer accesses must be thread-atomic" 4
-.IX Item "pointer accesses must be thread-atomic"
-Accessing a pointer value must be atomic, it must both be readable and
-writable in one piece \- this is the case on all current architectures.
-.ie n .IP """sig_atomic_t volatile"" must be thread-atomic as well" 4
-.el .IP "\f(CWsig_atomic_t volatile\fR must be thread-atomic as well" 4
-.IX Item "sig_atomic_t volatile must be thread-atomic as well"
-The type \f(CW\*(C`sig_atomic_t volatile\*(C'\fR (or whatever is defined as
-\&\f(CW\*(C`EV_ATOMIC_T\*(C'\fR) must be atomic with respect to accesses from different
-threads. This is not part of the specification for \f(CW\*(C`sig_atomic_t\*(C'\fR, but is
-believed to be sufficiently portable.
-.ie n .IP """sigprocmask"" must work in a threaded environment" 4
-.el .IP "\f(CWsigprocmask\fR must work in a threaded environment" 4
-.IX Item "sigprocmask must work in a threaded environment"
-Libev uses \f(CW\*(C`sigprocmask\*(C'\fR to temporarily block signals. This is not
-allowed in a threaded program (\f(CW\*(C`pthread_sigmask\*(C'\fR has to be used). Typical
-pthread implementations will either allow \f(CW\*(C`sigprocmask\*(C'\fR in the \*(L"main
-thread\*(R" or will block signals process-wide, both behaviours would
-be compatible with libev. Interaction between \f(CW\*(C`sigprocmask\*(C'\fR and
-\&\f(CW\*(C`pthread_sigmask\*(C'\fR could complicate things, however.
-.Sp
-The most portable way to handle signals is to block signals in all threads
-except the initial one, and run the default loop in the initial thread as
-well.
-.ie n .IP """long"" must be large enough for common memory allocation sizes" 4
-.el .IP "\f(CWlong\fR must be large enough for common memory allocation sizes" 4
-.IX Item "long must be large enough for common memory allocation sizes"
-To improve portability and simplify its \s-1API\s0, libev uses \f(CW\*(C`long\*(C'\fR internally
-instead of \f(CW\*(C`size_t\*(C'\fR when allocating its data structures. On non-POSIX
-systems (Microsoft...) this might be unexpectedly low, but is still at
-least 31 bits everywhere, which is enough for hundreds of millions of
-watchers.
-.ie n .IP """double"" must hold a time value in seconds with enough accuracy" 4
-.el .IP "\f(CWdouble\fR must hold a time value in seconds with enough accuracy" 4
-.IX Item "double must hold a time value in seconds with enough accuracy"
-The type \f(CW\*(C`double\*(C'\fR is used to represent timestamps. It is required to
-have at least 51 bits of mantissa (and 9 bits of exponent), which is
-good enough for at least into the year 4000 with millisecond accuracy
-(the design goal for libev). This requirement is overfulfilled by
-implementations using \s-1IEEE\s0 754, which is basically all existing ones. With
-\&\s-1IEEE\s0 754 doubles, you get microsecond accuracy until at least 2200.
-.PP
-If you know of other additional requirements drop me a note.
-.SH "ALGORITHMIC COMPLEXITIES"
-.IX Header "ALGORITHMIC COMPLEXITIES"
-In this section the complexities of (many of) the algorithms used inside
-libev will be documented. For complexity discussions about backends see
-the documentation for \f(CW\*(C`ev_default_init\*(C'\fR.
-.PP
-All of the following are about amortised time: If an array needs to be
-extended, libev needs to realloc and move the whole array, but this
-happens asymptotically rarer with higher number of elements, so O(1) might
-mean that libev does a lengthy realloc operation in rare cases, but on
-average it is much faster and asymptotically approaches constant time.
-.IP "Starting and stopping timer/periodic watchers: O(log skipped_other_timers)" 4
-.IX Item "Starting and stopping timer/periodic watchers: O(log skipped_other_timers)"
-This means that, when you have a watcher that triggers in one hour and
-there are 100 watchers that would trigger before that, then inserting will
-have to skip roughly seven (\f(CW\*(C`ld 100\*(C'\fR) of these watchers.
-.IP "Changing timer/periodic watchers (by autorepeat or calling again): O(log skipped_other_timers)" 4
-.IX Item "Changing timer/periodic watchers (by autorepeat or calling again): O(log skipped_other_timers)"
-That means that changing a timer costs less than removing/adding them,
-as only the relative motion in the event queue has to be paid for.
-.IP "Starting io/check/prepare/idle/signal/child/fork/async watchers: O(1)" 4
-.IX Item "Starting io/check/prepare/idle/signal/child/fork/async watchers: O(1)"
-These just add the watcher into an array or at the head of a list.
-.IP "Stopping check/prepare/idle/fork/async watchers: O(1)" 4
-.IX Item "Stopping check/prepare/idle/fork/async watchers: O(1)"
-.PD 0
-.IP "Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % \s-1EV_PID_HASHSIZE\s0))" 4
-.IX Item "Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % EV_PID_HASHSIZE))"
-.PD
-These watchers are stored in lists, so they need to be walked to find the
-correct watcher to remove. The lists are usually short (you don't usually
-have many watchers waiting for the same fd or signal: one is typical, two
-is rare).
-.IP "Finding the next timer in each loop iteration: O(1)" 4
-.IX Item "Finding the next timer in each loop iteration: O(1)"
-By virtue of using a binary or 4\-heap, the next timer is always found at a
-fixed position in the storage array.
-.IP "Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd)" 4
-.IX Item "Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd)"
-A change means an I/O watcher gets started or stopped, which requires
-libev to recalculate its status (and possibly tell the kernel, depending
-on backend and whether \f(CW\*(C`ev_io_set\*(C'\fR was used).
-.IP "Activating one watcher (putting it into the pending state): O(1)" 4
-.IX Item "Activating one watcher (putting it into the pending state): O(1)"
-.PD 0
-.IP "Priority handling: O(number_of_priorities)" 4
-.IX Item "Priority handling: O(number_of_priorities)"
-.PD
-Priorities are implemented by allocating some space for each
-priority. When doing priority-based operations, libev usually has to
-linearly search all the priorities, but starting/stopping and activating
-watchers becomes O(1) with respect to priority handling.
-.IP "Sending an ev_async: O(1)" 4
-.IX Item "Sending an ev_async: O(1)"
-.PD 0
-.IP "Processing ev_async_send: O(number_of_async_watchers)" 4
-.IX Item "Processing ev_async_send: O(number_of_async_watchers)"
-.IP "Processing signals: O(max_signal_number)" 4
-.IX Item "Processing signals: O(max_signal_number)"
-.PD
-Sending involves a system call \fIiff\fR there were no other \f(CW\*(C`ev_async_send\*(C'\fR
-calls in the current loop iteration. Checking for async and signal events
-involves iterating over all running async watchers or all signal numbers.
-.SH "PORTING FROM LIBEV 3.X TO 4.X"
-.IX Header "PORTING FROM LIBEV 3.X TO 4.X"
-The major version 4 introduced some incompatible changes to the \s-1API\s0.
-.PP
-At the moment, the \f(CW\*(C`ev.h\*(C'\fR header file provides compatibility definitions
-for all changes, so most programs should still compile. The compatibility
-layer might be removed in later versions of libev, so better update to the
-new \s-1API\s0 early than late.
-.ie n .IP """EV_COMPAT3"" backwards compatibility mechanism" 4
-.el .IP "\f(CWEV_COMPAT3\fR backwards compatibility mechanism" 4
-.IX Item "EV_COMPAT3 backwards compatibility mechanism"
-The backward compatibility mechanism can be controlled by
-\&\f(CW\*(C`EV_COMPAT3\*(C'\fR. See \*(L"\s-1MACROS\s0\*(R" in \s-1PREPROCESSOR\s0 \s-1SYMBOLS\s0 in the \s-1EMBEDDING\s0
-section.
-.ie n .IP """ev_default_destroy"" and ""ev_default_fork"" have been removed" 4
-.el .IP "\f(CWev_default_destroy\fR and \f(CWev_default_fork\fR have been removed" 4
-.IX Item "ev_default_destroy and ev_default_fork have been removed"
-These calls can be replaced easily by their \f(CW\*(C`ev_loop_xxx\*(C'\fR counterparts:
-.Sp
-.Vb 2
-\& ev_loop_destroy (EV_DEFAULT_UC);
-\& ev_loop_fork (EV_DEFAULT);
-.Ve
-.IP "function/symbol renames" 4
-.IX Item "function/symbol renames"
-A number of functions and symbols have been renamed:
-.Sp
-.Vb 3
-\& ev_loop => ev_run
-\& EVLOOP_NONBLOCK => EVRUN_NOWAIT
-\& EVLOOP_ONESHOT => EVRUN_ONCE
-\&
-\& ev_unloop => ev_break
-\& EVUNLOOP_CANCEL => EVBREAK_CANCEL
-\& EVUNLOOP_ONE => EVBREAK_ONE
-\& EVUNLOOP_ALL => EVBREAK_ALL
-\&
-\& EV_TIMEOUT => EV_TIMER
-\&
-\& ev_loop_count => ev_iteration
-\& ev_loop_depth => ev_depth
-\& ev_loop_verify => ev_verify
-.Ve
-.Sp
-Most functions working on \f(CW\*(C`struct ev_loop\*(C'\fR objects don't have an
-\&\f(CW\*(C`ev_loop_\*(C'\fR prefix, so it was removed; \f(CW\*(C`ev_loop\*(C'\fR, \f(CW\*(C`ev_unloop\*(C'\fR and
-associated constants have been renamed to not collide with the \f(CW\*(C`struct
-ev_loop\*(C'\fR anymore and \f(CW\*(C`EV_TIMER\*(C'\fR now follows the same naming scheme
-as all other watcher types. Note that \f(CW\*(C`ev_loop_fork\*(C'\fR is still called
-\&\f(CW\*(C`ev_loop_fork\*(C'\fR because it would otherwise clash with the \f(CW\*(C`ev_fork\*(C'\fR
-typedef.
-.ie n .IP """EV_MINIMAL"" mechanism replaced by ""EV_FEATURES""" 4
-.el .IP "\f(CWEV_MINIMAL\fR mechanism replaced by \f(CWEV_FEATURES\fR" 4
-.IX Item "EV_MINIMAL mechanism replaced by EV_FEATURES"
-The preprocessor symbol \f(CW\*(C`EV_MINIMAL\*(C'\fR has been replaced by a different
-mechanism, \f(CW\*(C`EV_FEATURES\*(C'\fR. Programs using \f(CW\*(C`EV_MINIMAL\*(C'\fR usually compile
-and work, but the library code will of course be larger.
-.SH "GLOSSARY"
-.IX Header "GLOSSARY"
-.IP "active" 4
-.IX Item "active"
-A watcher is active as long as it has been started and not yet stopped.
-See \*(L"\s-1WATCHER\s0 \s-1STATES\s0\*(R" for details.
-.IP "application" 4
-.IX Item "application"
-In this document, an application is whatever is using libev.
-.IP "backend" 4
-.IX Item "backend"
-The part of the code dealing with the operating system interfaces.
-.IP "callback" 4
-.IX Item "callback"
-The address of a function that is called when some event has been
-detected. Callbacks are being passed the event loop, the watcher that
-received the event, and the actual event bitset.
-.IP "callback/watcher invocation" 4
-.IX Item "callback/watcher invocation"
-The act of calling the callback associated with a watcher.
-.IP "event" 4
-.IX Item "event"
-A change of state of some external event, such as data now being available
-for reading on a file descriptor, time having passed or simply not having
-any other events happening anymore.
-.Sp
-In libev, events are represented as single bits (such as \f(CW\*(C`EV_READ\*(C'\fR or
-\&\f(CW\*(C`EV_TIMER\*(C'\fR).
-.IP "event library" 4
-.IX Item "event library"
-A software package implementing an event model and loop.
-.IP "event loop" 4
-.IX Item "event loop"
-An entity that handles and processes external events and converts them
-into callback invocations.
-.IP "event model" 4
-.IX Item "event model"
-The model used to describe how an event loop handles and processes
-watchers and events.
-.IP "pending" 4
-.IX Item "pending"
-A watcher is pending as soon as the corresponding event has been
-detected. See \*(L"\s-1WATCHER\s0 \s-1STATES\s0\*(R" for details.
-.IP "real time" 4
-.IX Item "real time"
-The physical time that is observed. It is apparently strictly monotonic :)
-.IP "wall-clock time" 4
-.IX Item "wall-clock time"
-The time and date as shown on clocks. Unlike real time, it can actually
-be wrong and jump forwards and backwards, e.g. when you adjust your
-clock.
-.IP "watcher" 4
-.IX Item "watcher"
-A data structure that describes interest in certain events. Watchers need
-to be started (attached to an event loop) before they can receive events.
-.SH "AUTHOR"
-.IX Header "AUTHOR"
-Marc Lehmann <libev@schmorp.de>, with repeated corrections by Mikael
-Magnusson and Emanuele Giaquinta, and minor corrections by many others.
diff --git a/deps/uv/src/unix/ev/ev.c b/deps/uv/src/unix/ev/ev.c
deleted file mode 100644
index efd2ab991..000000000
--- a/deps/uv/src/unix/ev/ev.c
+++ /dev/null
@@ -1,3925 +0,0 @@
-/*
- * libev event processing core, watcher management
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-/* this big block deduces configuration from config.h */
-#ifndef EV_STANDALONE
-# ifdef EV_CONFIG_H
-# include EV_CONFIG_H
-# else
-# include "config.h"
-# endif
-
-# if HAVE_CLOCK_SYSCALL
-# ifndef EV_USE_CLOCK_SYSCALL
-# define EV_USE_CLOCK_SYSCALL 1
-# ifndef EV_USE_REALTIME
-# define EV_USE_REALTIME 0
-# endif
-# ifndef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 1
-# endif
-# endif
-# elif !defined(EV_USE_CLOCK_SYSCALL)
-# define EV_USE_CLOCK_SYSCALL 0
-# endif
-
-# if HAVE_CLOCK_GETTIME
-# ifndef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 1
-# endif
-# ifndef EV_USE_REALTIME
-# define EV_USE_REALTIME 0
-# endif
-# else
-# ifndef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 0
-# endif
-# ifndef EV_USE_REALTIME
-# define EV_USE_REALTIME 0
-# endif
-# endif
-
-# if HAVE_NANOSLEEP
-# ifndef EV_USE_NANOSLEEP
-# define EV_USE_NANOSLEEP EV_FEATURE_OS
-# endif
-# else
-# undef EV_USE_NANOSLEEP
-# define EV_USE_NANOSLEEP 0
-# endif
-
-# if HAVE_SELECT && HAVE_SYS_SELECT_H
-# ifndef EV_USE_SELECT
-# define EV_USE_SELECT EV_FEATURE_BACKENDS
-# endif
-# else
-# undef EV_USE_SELECT
-# define EV_USE_SELECT 0
-# endif
-
-# if HAVE_POLL && HAVE_POLL_H
-# ifndef EV_USE_POLL
-# define EV_USE_POLL EV_FEATURE_BACKENDS
-# endif
-# else
-# undef EV_USE_POLL
-# define EV_USE_POLL 0
-# endif
-
-# if HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H
-# ifndef EV_USE_EPOLL
-# define EV_USE_EPOLL EV_FEATURE_BACKENDS
-# endif
-# else
-# undef EV_USE_EPOLL
-# define EV_USE_EPOLL 0
-# endif
-
-# if HAVE_KQUEUE && HAVE_SYS_EVENT_H
-# ifndef EV_USE_KQUEUE
-# define EV_USE_KQUEUE EV_FEATURE_BACKENDS
-# endif
-# else
-# undef EV_USE_KQUEUE
-# define EV_USE_KQUEUE 0
-# endif
-
-# if HAVE_PORT_H && HAVE_PORT_CREATE
-# ifndef EV_USE_PORT
-# define EV_USE_PORT EV_FEATURE_BACKENDS
-# endif
-# else
-# undef EV_USE_PORT
-# define EV_USE_PORT 0
-# endif
-
-# if HAVE_INOTIFY_INIT && HAVE_SYS_INOTIFY_H
-# ifndef EV_USE_INOTIFY
-# define EV_USE_INOTIFY EV_FEATURE_OS
-# endif
-# else
-# undef EV_USE_INOTIFY
-# define EV_USE_INOTIFY 0
-# endif
-
-# if HAVE_SIGNALFD && HAVE_SYS_SIGNALFD_H
-# ifndef EV_USE_SIGNALFD
-# define EV_USE_SIGNALFD EV_FEATURE_OS
-# endif
-# else
-# undef EV_USE_SIGNALFD
-# define EV_USE_SIGNALFD 0
-# endif
-
-# if HAVE_EVENTFD
-# ifndef EV_USE_EVENTFD
-# define EV_USE_EVENTFD EV_FEATURE_OS
-# endif
-# else
-# undef EV_USE_EVENTFD
-# define EV_USE_EVENTFD 0
-# endif
-
-#endif
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stddef.h>
-
-#include <stdio.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <time.h>
-#include <limits.h>
-
-#include <signal.h>
-
-#ifdef EV_H
-# include EV_H
-#else
-# include "ev.h"
-#endif
-
-EV_CPP(extern "C" {)
-
-#ifndef _WIN32
-# include <sys/time.h>
-# include <sys/wait.h>
-# include <unistd.h>
-#else
-# include <io.h>
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# ifndef EV_SELECT_IS_WINSOCKET
-# define EV_SELECT_IS_WINSOCKET 1
-# endif
-# undef EV_AVOID_STDIO
-#endif
-
-/* OS X, in its infinite idiocy, actually HARDCODES
- * a limit of 1024 into their select. Where people have brains,
- * OS X engineers apparently have a vacuum. Or maybe they were
- * ordered to have a vacuum, or they do anything for money.
- * This might help. Or not.
- */
-#define _DARWIN_UNLIMITED_SELECT 1
-
-/* this block tries to deduce configuration from header-defined symbols and defaults */
-
-/* try to deduce the maximum number of signals on this platform */
-#if defined (EV_NSIG)
-/* use what's provided */
-#elif defined (NSIG)
-# define EV_NSIG (NSIG)
-#elif defined(_NSIG)
-# define EV_NSIG (_NSIG)
-#elif defined (SIGMAX)
-# define EV_NSIG (SIGMAX+1)
-#elif defined (SIG_MAX)
-# define EV_NSIG (SIG_MAX+1)
-#elif defined (_SIG_MAX)
-# define EV_NSIG (_SIG_MAX+1)
-#elif defined (MAXSIG)
-# define EV_NSIG (MAXSIG+1)
-#elif defined (MAX_SIG)
-# define EV_NSIG (MAX_SIG+1)
-#elif defined (SIGARRAYSIZE)
-# define EV_NSIG (SIGARRAYSIZE) /* Assume ary[SIGARRAYSIZE] */
-#elif defined (_sys_nsig)
-# define EV_NSIG (_sys_nsig) /* Solaris 2.5 */
-#else
-# error "unable to find value for NSIG, please report"
-/* to make it compile regardless, just remove the above line, */
-/* but consider reporting it, too! :) */
-# define EV_NSIG 65
-#endif
-
-#ifndef EV_USE_CLOCK_SYSCALL
-# if __linux && __GLIBC__ >= 2
-# define EV_USE_CLOCK_SYSCALL EV_FEATURE_OS
-# else
-# define EV_USE_CLOCK_SYSCALL 0
-# endif
-#endif
-
-#ifndef EV_USE_MONOTONIC
-# if defined (_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
-# define EV_USE_MONOTONIC EV_FEATURE_OS
-# else
-# define EV_USE_MONOTONIC 0
-# endif
-#endif
-
-#ifndef EV_USE_REALTIME
-# define EV_USE_REALTIME !EV_USE_CLOCK_SYSCALL
-#endif
-
-#ifndef EV_USE_NANOSLEEP
-# if _POSIX_C_SOURCE >= 199309L
-# define EV_USE_NANOSLEEP EV_FEATURE_OS
-# else
-# define EV_USE_NANOSLEEP 0
-# endif
-#endif
-
-#ifndef EV_USE_SELECT
-# define EV_USE_SELECT EV_FEATURE_BACKENDS
-#endif
-
-#ifndef EV_USE_POLL
-# ifdef _WIN32
-# define EV_USE_POLL 0
-# else
-# define EV_USE_POLL EV_FEATURE_BACKENDS
-# endif
-#endif
-
-#ifndef EV_USE_EPOLL
-# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
-# define EV_USE_EPOLL EV_FEATURE_BACKENDS
-# else
-# define EV_USE_EPOLL 0
-# endif
-#endif
-
-#ifndef EV_USE_KQUEUE
-# define EV_USE_KQUEUE 0
-#endif
-
-#ifndef EV_USE_PORT
-# define EV_USE_PORT 0
-#endif
-
-#ifndef EV_USE_INOTIFY
-# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
-# define EV_USE_INOTIFY EV_FEATURE_OS
-# else
-# define EV_USE_INOTIFY 0
-# endif
-#endif
-
-#ifndef EV_PID_HASHSIZE
-# define EV_PID_HASHSIZE EV_FEATURE_DATA ? 16 : 1
-#endif
-
-#ifndef EV_INOTIFY_HASHSIZE
-# define EV_INOTIFY_HASHSIZE EV_FEATURE_DATA ? 16 : 1
-#endif
-
-#ifndef EV_USE_EVENTFD
-# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
-# define EV_USE_EVENTFD EV_FEATURE_OS
-# else
-# define EV_USE_EVENTFD 0
-# endif
-#endif
-
-#ifndef EV_USE_SIGNALFD
-# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
-# define EV_USE_SIGNALFD EV_FEATURE_OS
-# else
-# define EV_USE_SIGNALFD 0
-# endif
-#endif
-
-#if 0 /* debugging */
-# define EV_VERIFY 3
-# define EV_USE_4HEAP 1
-# define EV_HEAP_CACHE_AT 1
-#endif
-
-#ifndef EV_VERIFY
-# define EV_VERIFY (EV_FEATURE_API ? 1 : 0)
-#endif
-
-#ifndef EV_USE_4HEAP
-# define EV_USE_4HEAP EV_FEATURE_DATA
-#endif
-
-#ifndef EV_HEAP_CACHE_AT
-# define EV_HEAP_CACHE_AT EV_FEATURE_DATA
-#endif
-
-/* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */
-/* which makes programs even slower. might work on other unices, too. */
-#if EV_USE_CLOCK_SYSCALL
-# include <syscall.h>
-# ifdef SYS_clock_gettime
-# define clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts))
-# undef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 1
-# else
-# undef EV_USE_CLOCK_SYSCALL
-# define EV_USE_CLOCK_SYSCALL 0
-# endif
-#endif
-
-/* this block fixes any misconfiguration where we know we run into trouble otherwise */
-
-#ifdef _AIX
-/* AIX has a completely broken poll.h header */
-# undef EV_USE_POLL
-# define EV_USE_POLL 0
-#endif
-
-#ifndef CLOCK_MONOTONIC
-# undef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 0
-#endif
-
-#ifndef CLOCK_REALTIME
-# undef EV_USE_REALTIME
-# define EV_USE_REALTIME 0
-#endif
-
-#if !EV_STAT_ENABLE
-# undef EV_USE_INOTIFY
-# define EV_USE_INOTIFY 0
-#endif
-
-#if !EV_USE_NANOSLEEP
-/* hp-ux has it in sys/time.h, which we unconditionally include above */
-# if !defined(_WIN32) && !defined(__hpux)
-# include <sys/select.h>
-# endif
-#endif
-
-#if EV_USE_INOTIFY
-# include <sys/statfs.h>
-# include <sys/inotify.h>
-/* some very old inotify.h headers don't have IN_DONT_FOLLOW */
-# ifndef IN_DONT_FOLLOW
-# undef EV_USE_INOTIFY
-# define EV_USE_INOTIFY 0
-# endif
-#endif
-
-#if EV_SELECT_IS_WINSOCKET
-# include <winsock.h>
-#endif
-
-#if EV_USE_EVENTFD
-/* our minimum requirement is glibc 2.7 which has the stub, but not the header */
-# include <stdint.h>
-# ifndef EFD_NONBLOCK
-# define EFD_NONBLOCK O_NONBLOCK
-# endif
-# ifndef EFD_CLOEXEC
-# ifdef O_CLOEXEC
-# define EFD_CLOEXEC O_CLOEXEC
-# else
-# define EFD_CLOEXEC 02000000
-# endif
-# endif
-EV_CPP(extern "C") int (eventfd) (unsigned int initval, int flags);
-#endif
-
-#if EV_USE_SIGNALFD
-/* our minimum requirement is glibc 2.7 which has the stub, but not the header */
-# include <stdint.h>
-# ifndef SFD_NONBLOCK
-# define SFD_NONBLOCK O_NONBLOCK
-# endif
-# ifndef SFD_CLOEXEC
-# ifdef O_CLOEXEC
-# define SFD_CLOEXEC O_CLOEXEC
-# else
-# define SFD_CLOEXEC 02000000
-# endif
-# endif
-EV_CPP (extern "C") int signalfd (int fd, const sigset_t *mask, int flags);
-
-struct signalfd_siginfo
-{
- uint32_t ssi_signo;
- char pad[128 - sizeof (uint32_t)];
-};
-#endif
-
-/**/
-
-#if EV_VERIFY >= 3
-# define EV_FREQUENT_CHECK ev_verify (EV_A)
-#else
-# define EV_FREQUENT_CHECK do { } while (0)
-#endif
-
-/*
- * This is used to avoid floating point rounding problems.
- * It is added to ev_rt_now when scheduling periodics
- * to ensure progress, time-wise, even when rounding
- * errors are against us.
- * This value is good at least till the year 4000.
- * Better solutions welcome.
- */
-#define TIME_EPSILON 0.0001220703125 /* 1/8192 */
-
-#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
-#define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */
-
-#define EV_TV_SET(tv,t) do { tv.tv_sec = (long)t; tv.tv_usec = (long)((t - tv.tv_sec) * 1e6); } while (0)
-#define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0)
-
-#if __GNUC__ >= 4
-# define expect(expr,value) __builtin_expect ((expr),(value))
-# define noinline __attribute__ ((noinline))
-#else
-# define expect(expr,value) (expr)
-# define noinline
-# if __STDC_VERSION__ < 199901L && __GNUC__ < 2
-# define inline
-# endif
-#endif
-
-#define expect_false(expr) expect ((expr) != 0, 0)
-#define expect_true(expr) expect ((expr) != 0, 1)
-#define inline_size static inline
-
-#if EV_FEATURE_CODE
-# define inline_speed static inline
-#else
-# define inline_speed static noinline
-#endif
-
-#define NUMPRI (EV_MAXPRI - EV_MINPRI + 1)
-
-#if EV_MINPRI == EV_MAXPRI
-# define ABSPRI(w) (((W)w), 0)
-#else
-# define ABSPRI(w) (((W)w)->priority - EV_MINPRI)
-#endif
-
-#define EMPTY /* required for microsofts broken pseudo-c compiler */
-#define EMPTY2(a,b) /* used to suppress some warnings */
-
-typedef ev_watcher *W;
-typedef ev_watcher_list *WL;
-typedef ev_watcher_time *WT;
-
-#define ev_active(w) ((W)(w))->active
-#define ev_at(w) ((WT)(w))->at
-
-#if EV_USE_REALTIME
-/* sig_atomic_t is used to avoid per-thread variables or locking but still */
-/* giving it a reasonably high chance of working on typical architectures */
-static EV_ATOMIC_T have_realtime; /* did clock_gettime (CLOCK_REALTIME) work? */
-#endif
-
-#if EV_USE_MONOTONIC
-static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
-#endif
-
-#ifndef EV_FD_TO_WIN32_HANDLE
-# define EV_FD_TO_WIN32_HANDLE(fd) _get_osfhandle (fd)
-#endif
-#ifndef EV_WIN32_HANDLE_TO_FD
-# define EV_WIN32_HANDLE_TO_FD(handle) _open_osfhandle (handle, 0)
-#endif
-#ifndef EV_WIN32_CLOSE_FD
-# define EV_WIN32_CLOSE_FD(fd) close (fd)
-#endif
-
-#ifdef _WIN32
-# include "ev_win32.c"
-#endif
-
-/*****************************************************************************/
-
-#ifdef __linux
-# include <sys/utsname.h>
-#endif
-
-static unsigned int noinline
-ev_linux_version (void)
-{
-#ifdef __linux
- unsigned int v = 0;
- struct utsname buf;
- int i;
- char *p = buf.release;
-
- if (uname (&buf))
- return 0;
-
- for (i = 3+1; --i; )
- {
- unsigned int c = 0;
-
- for (;;)
- {
- if (*p >= '0' && *p <= '9')
- c = c * 10 + *p++ - '0';
- else
- {
- p += *p == '.';
- break;
- }
- }
-
- v = (v << 8) | c;
- }
-
- return v;
-#else
- return 0;
-#endif
-}
-
-/*****************************************************************************/
-
-#if EV_AVOID_STDIO
-static void noinline
-ev_printerr (const char *msg)
-{
- write (STDERR_FILENO, msg, strlen (msg));
-}
-#endif
-
-static void (*syserr_cb)(const char *msg);
-
-void
-ev_set_syserr_cb (void (*cb)(const char *msg))
-{
- syserr_cb = cb;
-}
-
-static void noinline
-ev_syserr (const char *msg)
-{
- if (!msg)
- msg = "(libev) system error";
-
- if (syserr_cb)
- syserr_cb (msg);
- else
- {
-#if EV_AVOID_STDIO
- ev_printerr (msg);
- ev_printerr (": ");
- ev_printerr (strerror (errno));
- ev_printerr ("\n");
-#else
- perror (msg);
-#endif
- abort ();
- }
-}
-
-static void *
-ev_realloc_emul (void *ptr, long size)
-{
- /* some systems, notably openbsd and darwin, fail to properly
- * implement realloc (x, 0) (as required by both ansi c-89 and
- * the single unix specification, so work around them here.
- */
-
- if (size)
- return realloc (ptr, size);
-
- free (ptr);
- return 0;
-}
-
-static void *(*alloc)(void *ptr, long size) = ev_realloc_emul;
-
-void
-ev_set_allocator (void *(*cb)(void *ptr, long size))
-{
- alloc = cb;
-}
-
-inline_speed void *
-ev_realloc (void *ptr, long size)
-{
- ptr = alloc (ptr, size);
-
- if (!ptr && size)
- {
-#if EV_AVOID_STDIO
- ev_printerr ("(libev) memory allocation failed, aborting.\n");
-#else
- fprintf (stderr, "(libev) cannot allocate %ld bytes, aborting.", size);
-#endif
- abort ();
- }
-
- return ptr;
-}
-
-#define ev_malloc(size) ev_realloc (0, (size))
-#define ev_free(ptr) ev_realloc ((ptr), 0)
-
-/*****************************************************************************/
-
-/* set in reify when reification needed */
-#define EV_ANFD_REIFY 1
-
-/* file descriptor info structure */
-typedef struct
-{
- WL head;
- unsigned char events; /* the events watched for */
- unsigned char reify; /* flag set when this ANFD needs reification (EV_ANFD_REIFY, EV__IOFDSET) */
- unsigned char emask; /* the epoll backend stores the actual kernel mask in here */
- unsigned char unused;
-#if EV_USE_EPOLL
- unsigned int egen; /* generation counter to counter epoll bugs */
-#endif
-#if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP
- SOCKET handle;
-#endif
-#if EV_USE_IOCP
- OVERLAPPED or, ow;
-#endif
-} ANFD;
-
-/* stores the pending event set for a given watcher */
-typedef struct
-{
- W w;
- int events; /* the pending event set for the given watcher */
-} ANPENDING;
-
-#if EV_USE_INOTIFY
-/* hash table entry per inotify-id */
-typedef struct
-{
- WL head;
-} ANFS;
-#endif
-
-/* Heap Entry */
-#if EV_HEAP_CACHE_AT
- /* a heap element */
- typedef struct {
- ev_tstamp at;
- WT w;
- } ANHE;
-
- #define ANHE_w(he) (he).w /* access watcher, read-write */
- #define ANHE_at(he) (he).at /* access cached at, read-only */
- #define ANHE_at_cache(he) (he).at = (he).w->at /* update at from watcher */
-#else
- /* a heap element */
- typedef WT ANHE;
-
- #define ANHE_w(he) (he)
- #define ANHE_at(he) (he)->at
- #define ANHE_at_cache(he)
-#endif
-
-#if EV_MULTIPLICITY
-
- struct ev_loop
- {
- ev_tstamp ev_rt_now;
- #define ev_rt_now ((loop)->ev_rt_now)
- #define VAR(name,decl) decl;
- #include "ev_vars.h"
- #undef VAR
- };
- #include "ev_wrap.h"
-
- static struct ev_loop default_loop_struct;
- struct ev_loop *ev_default_loop_ptr;
-
-#else
-
- ev_tstamp ev_rt_now;
- #define VAR(name,decl) static decl;
- #include "ev_vars.h"
- #undef VAR
-
- static int ev_default_loop_ptr;
-
-#endif
-
-#if EV_FEATURE_API
-# define EV_RELEASE_CB if (expect_false (release_cb)) release_cb (EV_A)
-# define EV_ACQUIRE_CB if (expect_false (acquire_cb)) acquire_cb (EV_A)
-# define EV_INVOKE_PENDING invoke_cb (EV_A)
-#else
-# define EV_RELEASE_CB (void)0
-# define EV_ACQUIRE_CB (void)0
-# define EV_INVOKE_PENDING ev_invoke_pending (EV_A)
-#endif
-
-#define EVBREAK_RECURSE 0x80
-
-/*****************************************************************************/
-
-#ifndef EV_HAVE_EV_TIME
-ev_tstamp
-ev_time (void)
-{
-#if EV_USE_REALTIME
- if (expect_true (have_realtime))
- {
- struct timespec ts;
- clock_gettime (CLOCK_REALTIME, &ts);
- return ts.tv_sec + ts.tv_nsec * 1e-9;
- }
-#endif
-
- struct timeval tv;
- gettimeofday (&tv, 0);
- return tv.tv_sec + tv.tv_usec * 1e-6;
-}
-#endif
-
-inline_size ev_tstamp
-get_clock (void)
-{
-#if EV_USE_MONOTONIC
- if (expect_true (have_monotonic))
- {
- struct timespec ts;
- clock_gettime (CLOCK_MONOTONIC, &ts);
- return ts.tv_sec + ts.tv_nsec * 1e-9;
- }
-#endif
-
- return ev_time ();
-}
-
-#if EV_MULTIPLICITY
-ev_tstamp
-ev_now (EV_P)
-{
- return ev_rt_now;
-}
-#endif
-
-void
-ev_sleep (ev_tstamp delay)
-{
- if (delay > 0.)
- {
-#if EV_USE_NANOSLEEP
- struct timespec ts;
-
- EV_TS_SET (ts, delay);
- nanosleep (&ts, 0);
-#elif defined(_WIN32)
- Sleep ((unsigned long)(delay * 1e3));
-#else
- struct timeval tv;
-
- /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */
- /* something not guaranteed by newer posix versions, but guaranteed */
- /* by older ones */
- EV_TV_SET (tv, delay);
- select (0, 0, 0, 0, &tv);
-#endif
- }
-}
-
-inline_speed int
-ev_timeout_to_ms (ev_tstamp timeout)
-{
- int ms = timeout * 1000. + .999999;
-
- return expect_true (ms) ? ms : timeout < 1e-6 ? 0 : 1;
-}
-
-/*****************************************************************************/
-
-#define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */
-
-/* find a suitable new size for the given array, */
-/* hopefully by rounding to a nice-to-malloc size */
-inline_size int
-array_nextsize (int elem, int cur, int cnt)
-{
- int ncur = cur + 1;
-
- do
- ncur <<= 1;
- while (cnt > ncur);
-
- /* if size is large, round to MALLOC_ROUND - 4 * longs to accomodate malloc overhead */
- if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4)
- {
- ncur *= elem;
- ncur = (ncur + elem + (MALLOC_ROUND - 1) + sizeof (void *) * 4) & ~(MALLOC_ROUND - 1);
- ncur = ncur - sizeof (void *) * 4;
- ncur /= elem;
- }
-
- return ncur;
-}
-
-static noinline void *
-array_realloc (int elem, void *base, int *cur, int cnt)
-{
- *cur = array_nextsize (elem, *cur, cnt);
- return ev_realloc (base, elem * *cur);
-}
-
-#define array_init_zero(base,count) \
- memset ((void *)(base), 0, sizeof (*(base)) * (count))
-
-#define array_needsize(type,base,cur,cnt,init) \
- if (expect_false ((cnt) > (cur))) \
- { \
- int ocur_ = (cur); \
- (base) = (type *)array_realloc \
- (sizeof (type), (base), &(cur), (cnt)); \
- init ((base) + (ocur_), (cur) - ocur_); \
- }
-
-#if 0
-#define array_slim(type,stem) \
- if (stem ## max < array_roundsize (stem ## cnt >> 2)) \
- { \
- stem ## max = array_roundsize (stem ## cnt >> 1); \
- base = (type *)ev_realloc (base, sizeof (type) * (stem ## max));\
- fprintf (stderr, "slimmed down " # stem " to %d\n", stem ## max);/*D*/\
- }
-#endif
-
-#define array_free(stem, idx) \
- ev_free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0; stem ## s idx = 0
-
-/*****************************************************************************/
-
-/* dummy callback for pending events */
-static void noinline
-pendingcb (EV_P_ ev_prepare *w, int revents)
-{
-}
-
-void noinline
-ev_feed_event (EV_P_ void *w, int revents)
-{
- W w_ = (W)w;
- int pri = ABSPRI (w_);
-
- if (expect_false (w_->pending))
- pendings [pri][w_->pending - 1].events |= revents;
- else
- {
- w_->pending = ++pendingcnt [pri];
- array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, EMPTY2);
- pendings [pri][w_->pending - 1].w = w_;
- pendings [pri][w_->pending - 1].events = revents;
- }
-}
-
-inline_speed void
-feed_reverse (EV_P_ W w)
-{
- array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1, EMPTY2);
- rfeeds [rfeedcnt++] = w;
-}
-
-inline_size void
-feed_reverse_done (EV_P_ int revents)
-{
- do
- ev_feed_event (EV_A_ rfeeds [--rfeedcnt], revents);
- while (rfeedcnt);
-}
-
-inline_speed void
-queue_events (EV_P_ W *events, int eventcnt, int type)
-{
- int i;
-
- for (i = 0; i < eventcnt; ++i)
- ev_feed_event (EV_A_ events [i], type);
-}
-
-/*****************************************************************************/
-
-inline_speed void
-fd_event_nocheck (EV_P_ int fd, int revents)
-{
- ANFD *anfd = anfds + fd;
- ev_io *w;
-
- for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next)
- {
- int ev = w->events & revents;
-
- if (ev)
- ev_feed_event (EV_A_ (W)w, ev);
- }
-}
-
-/* do not submit kernel events for fds that have reify set */
-/* because that means they changed while we were polling for new events */
-inline_speed void
-fd_event (EV_P_ int fd, int revents)
-{
- ANFD *anfd = anfds + fd;
-
- if (expect_true (!anfd->reify))
- fd_event_nocheck (EV_A_ fd, revents);
-}
-
-void
-ev_feed_fd_event (EV_P_ int fd, int revents)
-{
- if (fd >= 0 && fd < anfdmax)
- fd_event_nocheck (EV_A_ fd, revents);
-}
-
-/* make sure the external fd watch events are in-sync */
-/* with the kernel/libev internal state */
-inline_size void
-fd_reify (EV_P)
-{
- int i;
-
-#if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP
- for (i = 0; i < fdchangecnt; ++i)
- {
- int fd = fdchanges [i];
- ANFD *anfd = anfds + fd;
-
- if (anfd->reify & EV__IOFDSET)
- {
- SOCKET handle = EV_FD_TO_WIN32_HANDLE (fd);
-
- if (handle != anfd->handle)
- {
- unsigned long arg;
-
- assert (("libev: only socket fds supported in this configuration", ioctlsocket (handle, FIONREAD, &arg) == 0));
-
- /* handle changed, but fd didn't - we need to do it in two steps */
- backend_modify (EV_A_ fd, anfd->events, 0);
- anfd->events = 0;
- anfd->handle = handle;
- }
- }
- }
-#endif
-
- for (i = 0; i < fdchangecnt; ++i)
- {
- int fd = fdchanges [i];
- ANFD *anfd = anfds + fd;
- ev_io *w;
-
- unsigned char o_events = anfd->events;
- unsigned char o_reify = anfd->reify;
-
- anfd->reify = 0;
-
- /*if (expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */
- {
- anfd->events = 0;
-
- for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next)
- anfd->events |= (unsigned char)w->events;
-
- if (o_events != anfd->events)
- o_reify = EV__IOFDSET; /* actually |= */
- }
-
- if (o_reify & EV__IOFDSET)
- backend_modify (EV_A_ fd, o_events, anfd->events);
- }
-
- fdchangecnt = 0;
-}
-
-/* something about the given fd changed */
-inline_size void
-fd_change (EV_P_ int fd, int flags)
-{
- unsigned char reify = anfds [fd].reify;
- anfds [fd].reify |= flags;
-
- if (expect_true (!reify))
- {
- ++fdchangecnt;
- array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2);
- fdchanges [fdchangecnt - 1] = fd;
- }
-}
-
-/* the given fd is invalid/unusable, so make sure it doesn't hurt us anymore */
-inline_speed void
-fd_kill (EV_P_ int fd)
-{
- ev_io *w;
-
- while ((w = (ev_io *)anfds [fd].head))
- {
- ev_io_stop (EV_A_ w);
- ev_feed_event (EV_A_ (W)w, EV_ERROR | EV_READ | EV_WRITE);
- }
-}
-
-/* check whether the given fd is actually valid, for error recovery */
-inline_size int
-fd_valid (int fd)
-{
-#ifdef _WIN32
- return EV_FD_TO_WIN32_HANDLE (fd) != -1;
-#else
- return fcntl (fd, F_GETFD) != -1;
-#endif
-}
-
-/* called on EBADF to verify fds */
-static void noinline
-fd_ebadf (EV_P)
-{
- int fd;
-
- for (fd = 0; fd < anfdmax; ++fd)
- if (anfds [fd].events)
- if (!fd_valid (fd) && errno == EBADF)
- fd_kill (EV_A_ fd);
-}
-
-/* called on ENOMEM in select/poll to kill some fds and retry */
-static void noinline
-fd_enomem (EV_P)
-{
- int fd;
-
- for (fd = anfdmax; fd--; )
- if (anfds [fd].events)
- {
- fd_kill (EV_A_ fd);
- break;
- }
-}
-
-/* usually called after fork if backend needs to re-arm all fds from scratch */
-static void noinline
-fd_rearm_all (EV_P)
-{
- int fd;
-
- for (fd = 0; fd < anfdmax; ++fd)
- if (anfds [fd].events)
- {
- anfds [fd].events = 0;
- anfds [fd].emask = 0;
- fd_change (EV_A_ fd, EV__IOFDSET | EV_ANFD_REIFY);
- }
-}
-
-/* used to prepare libev internal fd's */
-/* this is not fork-safe */
-inline_speed void
-fd_intern (int fd)
-{
-#ifdef _WIN32
- unsigned long arg = 1;
- ioctlsocket (EV_FD_TO_WIN32_HANDLE (fd), FIONBIO, &arg);
-#else
- fcntl (fd, F_SETFD, FD_CLOEXEC);
- fcntl (fd, F_SETFL, O_NONBLOCK);
-#endif
-}
-
-/*****************************************************************************/
-
-/*
- * the heap functions want a real array index. array index 0 is guaranteed to not
- * be in-use at any time. the first heap entry is at array [HEAP0]. DHEAP gives
- * the branching factor of the d-tree.
- */
-
-/*
- * at the moment we allow libev the luxury of two heaps,
- * a small-code-size 2-heap one and a ~1.5kb larger 4-heap
- * which is more cache-efficient.
- * the difference is about 5% with 50000+ watchers.
- */
-#if EV_USE_4HEAP
-
-#define DHEAP 4
-#define HEAP0 (DHEAP - 1) /* index of first element in heap */
-#define HPARENT(k) ((((k) - HEAP0 - 1) / DHEAP) + HEAP0)
-#define UPHEAP_DONE(p,k) ((p) == (k))
-
-/* away from the root */
-inline_speed void
-downheap (ANHE *heap, int N, int k)
-{
- ANHE he = heap [k];
- ANHE *E = heap + N + HEAP0;
-
- for (;;)
- {
- ev_tstamp minat;
- ANHE *minpos;
- ANHE *pos = heap + DHEAP * (k - HEAP0) + HEAP0 + 1;
-
- /* find minimum child */
- if (expect_true (pos + DHEAP - 1 < E))
- {
- /* fast path */ (minpos = pos + 0), (minat = ANHE_at (*minpos));
- if ( ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos));
- if ( ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos));
- if ( ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos));
- }
- else if (pos < E)
- {
- /* slow path */ (minpos = pos + 0), (minat = ANHE_at (*minpos));
- if (pos + 1 < E && ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos));
- if (pos + 2 < E && ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos));
- if (pos + 3 < E && ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos));
- }
- else
- break;
-
- if (ANHE_at (he) <= minat)
- break;
-
- heap [k] = *minpos;
- ev_active (ANHE_w (*minpos)) = k;
-
- k = minpos - heap;
- }
-
- heap [k] = he;
- ev_active (ANHE_w (he)) = k;
-}
-
-#else /* 4HEAP */
-
-#define HEAP0 1
-#define HPARENT(k) ((k) >> 1)
-#define UPHEAP_DONE(p,k) (!(p))
-
-/* away from the root */
-inline_speed void
-downheap (ANHE *heap, int N, int k)
-{
- ANHE he = heap [k];
-
- for (;;)
- {
- int c = k << 1;
-
- if (c >= N + HEAP0)
- break;
-
- c += c + 1 < N + HEAP0 && ANHE_at (heap [c]) > ANHE_at (heap [c + 1])
- ? 1 : 0;
-
- if (ANHE_at (he) <= ANHE_at (heap [c]))
- break;
-
- heap [k] = heap [c];
- ev_active (ANHE_w (heap [k])) = k;
-
- k = c;
- }
-
- heap [k] = he;
- ev_active (ANHE_w (he)) = k;
-}
-#endif
-
-/* towards the root */
-inline_speed void
-upheap (ANHE *heap, int k)
-{
- ANHE he = heap [k];
-
- for (;;)
- {
- int p = HPARENT (k);
-
- if (UPHEAP_DONE (p, k) || ANHE_at (heap [p]) <= ANHE_at (he))
- break;
-
- heap [k] = heap [p];
- ev_active (ANHE_w (heap [k])) = k;
- k = p;
- }
-
- heap [k] = he;
- ev_active (ANHE_w (he)) = k;
-}
-
-/* move an element suitably so it is in a correct place */
-inline_size void
-adjustheap (ANHE *heap, int N, int k)
-{
- if (k > HEAP0 && ANHE_at (heap [k]) <= ANHE_at (heap [HPARENT (k)]))
- upheap (heap, k);
- else
- downheap (heap, N, k);
-}
-
-/* rebuild the heap: this function is used only once and executed rarely */
-inline_size void
-reheap (ANHE *heap, int N)
-{
- int i;
-
- /* we don't use floyds algorithm, upheap is simpler and is more cache-efficient */
- /* also, this is easy to implement and correct for both 2-heaps and 4-heaps */
- for (i = 0; i < N; ++i)
- upheap (heap, i + HEAP0);
-}
-
-/*****************************************************************************/
-
-/* associate signal watchers to a signal signal */
-typedef struct
-{
- EV_ATOMIC_T pending;
-#if EV_MULTIPLICITY
- EV_P;
-#endif
- WL head;
-} ANSIG;
-
-static ANSIG signals [EV_NSIG - 1];
-
-/*****************************************************************************/
-
-#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
-
-static void noinline
-evpipe_init (EV_P)
-{
- if (!ev_is_active (&pipe_w))
- {
-# if EV_USE_EVENTFD
- evfd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
- if (evfd < 0 && errno == EINVAL)
- evfd = eventfd (0, 0);
-
- if (evfd >= 0)
- {
- evpipe [0] = -1;
- fd_intern (evfd); /* doing it twice doesn't hurt */
- ev_io_set (&pipe_w, evfd, EV_READ);
- }
- else
-# endif
- {
- while (pipe (evpipe))
- ev_syserr ("(libev) error creating signal/async pipe");
-
- fd_intern (evpipe [0]);
- fd_intern (evpipe [1]);
- ev_io_set (&pipe_w, evpipe [0], EV_READ);
- }
-
- ev_io_start (EV_A_ &pipe_w);
- ev_unref (EV_A); /* watcher should not keep loop alive */
- }
-}
-
-inline_size void
-evpipe_write (EV_P_ EV_ATOMIC_T *flag)
-{
- if (!*flag)
- {
- int old_errno = errno; /* save errno because write might clobber it */
- char dummy;
-
- *flag = 1;
-
-#if EV_USE_EVENTFD
- if (evfd >= 0)
- {
- uint64_t counter = 1;
- write (evfd, &counter, sizeof (uint64_t));
- }
- else
-#endif
- /* win32 people keep sending patches that change this write() to send() */
- /* and then run away. but send() is wrong, it wants a socket handle on win32 */
- /* so when you think this write should be a send instead, please find out */
- /* where your send() is from - it's definitely not the microsoft send, and */
- /* tell me. thank you. */
- write (evpipe [1], &dummy, 1);
-
- errno = old_errno;
- }
-}
-
-/* called whenever the libev signal pipe */
-/* got some events (signal, async) */
-static void
-pipecb (EV_P_ ev_io *iow, int revents)
-{
- int i;
-
-#if EV_USE_EVENTFD
- if (evfd >= 0)
- {
- uint64_t counter;
- read (evfd, &counter, sizeof (uint64_t));
- }
- else
-#endif
- {
- char dummy;
- /* see discussion in evpipe_write when you think this read should be recv in win32 */
- read (evpipe [0], &dummy, 1);
- }
-
-#if EV_SIGNAL_ENABLE
- if (sig_pending)
- {
- sig_pending = 0;
-
- for (i = EV_NSIG - 1; i--; )
- if (expect_false (signals [i].pending))
- ev_feed_signal_event (EV_A_ i + 1);
- }
-#endif
-
-#if EV_ASYNC_ENABLE
- if (async_pending)
- {
- async_pending = 0;
-
- for (i = asynccnt; i--; )
- if (asyncs [i]->sent)
- {
- asyncs [i]->sent = 0;
- ev_feed_event (EV_A_ asyncs [i], EV_ASYNC);
- }
- }
-#endif
-}
-
-/*****************************************************************************/
-
-void
-ev_feed_signal (int signum)
-{
-#if EV_MULTIPLICITY
- EV_P = signals [signum - 1].loop;
-
- if (!EV_A)
- return;
-#endif
-
- signals [signum - 1].pending = 1;
- evpipe_write (EV_A_ &sig_pending);
-}
-
-static void
-ev_sighandler (int signum)
-{
-#ifdef _WIN32
- signal (signum, ev_sighandler);
-#endif
-
- ev_feed_signal (signum);
-}
-
-void noinline
-ev_feed_signal_event (EV_P_ int signum)
-{
- WL w;
-
- if (expect_false (signum <= 0 || signum > EV_NSIG))
- return;
-
- --signum;
-
-#if EV_MULTIPLICITY
- /* it is permissible to try to feed a signal to the wrong loop */
- /* or, likely more useful, feeding a signal nobody is waiting for */
-
- if (expect_false (signals [signum].loop != EV_A))
- return;
-#endif
-
- signals [signum].pending = 0;
-
- for (w = signals [signum].head; w; w = w->next)
- ev_feed_event (EV_A_ (W)w, EV_SIGNAL);
-}
-
-#if EV_USE_SIGNALFD
-static void
-sigfdcb (EV_P_ ev_io *iow, int revents)
-{
- struct signalfd_siginfo si[2], *sip; /* these structs are big */
-
- for (;;)
- {
- ssize_t res = read (sigfd, si, sizeof (si));
-
- /* not ISO-C, as res might be -1, but works with SuS */
- for (sip = si; (char *)sip < (char *)si + res; ++sip)
- ev_feed_signal_event (EV_A_ sip->ssi_signo);
-
- if (res < (ssize_t)sizeof (si))
- break;
- }
-}
-#endif
-
-#endif
-
-/*****************************************************************************/
-
-#if EV_CHILD_ENABLE
-static WL childs [EV_PID_HASHSIZE];
-
-static ev_signal childev;
-
-#ifndef WIFCONTINUED
-# define WIFCONTINUED(status) 0
-#endif
-
-/* handle a single child status event */
-inline_speed void
-child_reap (EV_P_ int chain, int pid, int status)
-{
- ev_child *w;
- int traced = WIFSTOPPED (status) || WIFCONTINUED (status);
-
- for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next)
- {
- if ((w->pid == pid || !w->pid)
- && (!traced || (w->flags & 1)))
- {
- ev_set_priority (w, EV_MAXPRI); /* need to do it *now*, this *must* be the same prio as the signal watcher itself */
- w->rpid = pid;
- w->rstatus = status;
- ev_feed_event (EV_A_ (W)w, EV_CHILD);
- }
- }
-}
-
-#ifndef WCONTINUED
-# define WCONTINUED 0
-#endif
-
-/* called on sigchld etc., calls waitpid */
-static void
-childcb (EV_P_ ev_signal *sw, int revents)
-{
- int pid, status;
-
- /* some systems define WCONTINUED but then fail to support it (linux 2.4) */
- if (0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED)))
- if (!WCONTINUED
- || errno != EINVAL
- || 0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED)))
- return;
-
- /* make sure we are called again until all children have been reaped */
- /* we need to do it this way so that the callback gets called before we continue */
- ev_feed_event (EV_A_ (W)sw, EV_SIGNAL);
-
- child_reap (EV_A_ pid, pid, status);
- if ((EV_PID_HASHSIZE) > 1)
- child_reap (EV_A_ 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */
-}
-
-#endif
-
-/*****************************************************************************/
-
-#if EV_USE_IOCP
-# include "ev_iocp.c"
-#endif
-#if EV_USE_PORT
-# include "ev_port.c"
-#endif
-#if EV_USE_KQUEUE
-# include "ev_kqueue.c"
-#endif
-#if EV_USE_EPOLL
-# include "ev_epoll.c"
-#endif
-#if EV_USE_POLL
-# include "ev_poll.c"
-#endif
-#if EV_USE_SELECT
-# include "ev_select.c"
-#endif
-
-int
-ev_version_major (void)
-{
- return EV_VERSION_MAJOR;
-}
-
-int
-ev_version_minor (void)
-{
- return EV_VERSION_MINOR;
-}
-
-/* return true if we are running with elevated privileges and should ignore env variables */
-int inline_size
-enable_secure (void)
-{
-#ifdef _WIN32
- return 0;
-#else
- return getuid () != geteuid ()
- || getgid () != getegid ();
-#endif
-}
-
-unsigned int
-ev_supported_backends (void)
-{
- unsigned int flags = 0;
-
- if (EV_USE_PORT ) flags |= EVBACKEND_PORT;
- if (EV_USE_KQUEUE) flags |= EVBACKEND_KQUEUE;
- if (EV_USE_EPOLL ) flags |= EVBACKEND_EPOLL;
- if (EV_USE_POLL ) flags |= EVBACKEND_POLL;
- if (EV_USE_SELECT) flags |= EVBACKEND_SELECT;
-
- return flags;
-}
-
-unsigned int
-ev_recommended_backends (void)
-{
- unsigned int flags = ev_supported_backends ();
-
-#ifndef __NetBSD__
- /* kqueue is borked on everything but netbsd apparently */
- /* it usually doesn't work correctly on anything but sockets and pipes */
- flags &= ~EVBACKEND_KQUEUE;
-#endif
-#ifdef __APPLE__
- /* only select works correctly on that "unix-certified" platform */
- flags &= ~EVBACKEND_KQUEUE; /* horribly broken, even for sockets */
- flags &= ~EVBACKEND_POLL; /* poll is based on kqueue from 10.5 onwards */
-#endif
-#ifdef __FreeBSD__
- flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */
-#endif
-
- return flags;
-}
-
-unsigned int
-ev_embeddable_backends (void)
-{
- int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT;
-
- /* epoll embeddability broken on all linux versions up to at least 2.6.23 */
- if (ev_linux_version () < 0x020620) /* disable it on linux < 2.6.32 */
- flags &= ~EVBACKEND_EPOLL;
-
- return flags;
-}
-
-unsigned int
-ev_backend (EV_P)
-{
- return backend;
-}
-
-#if EV_FEATURE_API
-unsigned int
-ev_iteration (EV_P)
-{
- return loop_count;
-}
-
-unsigned int
-ev_depth (EV_P)
-{
- return loop_depth;
-}
-
-void
-ev_set_io_collect_interval (EV_P_ ev_tstamp interval)
-{
- io_blocktime = interval;
-}
-
-void
-ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval)
-{
- timeout_blocktime = interval;
-}
-
-void
-ev_set_userdata (EV_P_ void *data)
-{
- userdata = data;
-}
-
-void *
-ev_userdata (EV_P)
-{
- return userdata;
-}
-
-void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P))
-{
- invoke_cb = invoke_pending_cb;
-}
-
-void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P))
-{
- release_cb = release;
- acquire_cb = acquire;
-}
-#endif
-
-/* initialise a loop structure, must be zero-initialised */
-static void noinline
-loop_init (EV_P_ unsigned int flags)
-{
- if (!backend)
- {
- origflags = flags;
-
-#if EV_USE_REALTIME
- if (!have_realtime)
- {
- struct timespec ts;
-
- if (!clock_gettime (CLOCK_REALTIME, &ts))
- have_realtime = 1;
- }
-#endif
-
-#if EV_USE_MONOTONIC
- if (!have_monotonic)
- {
- struct timespec ts;
-
- if (!clock_gettime (CLOCK_MONOTONIC, &ts))
- have_monotonic = 1;
- }
-#endif
-
- /* pid check not overridable via env */
-#ifndef _WIN32
- if (flags & EVFLAG_FORKCHECK)
- curpid = getpid ();
-#endif
-
- if (!(flags & EVFLAG_NOENV)
- && !enable_secure ()
- && getenv ("LIBEV_FLAGS"))
- flags = atoi (getenv ("LIBEV_FLAGS"));
-
- ev_rt_now = ev_time ();
- mn_now = get_clock ();
- now_floor = mn_now;
- rtmn_diff = ev_rt_now - mn_now;
-#if EV_FEATURE_API
- invoke_cb = ev_invoke_pending;
-#endif
-
- io_blocktime = 0.;
- timeout_blocktime = 0.;
- backend = 0;
- backend_fd = -1;
- sig_pending = 0;
-#if EV_ASYNC_ENABLE
- async_pending = 0;
-#endif
-#if EV_USE_INOTIFY
- fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
-#endif
-#if EV_USE_SIGNALFD
- sigfd = flags & EVFLAG_SIGNALFD ? -2 : -1;
-#endif
-
- if (!(flags & EVBACKEND_MASK))
- flags |= ev_recommended_backends ();
-
-#if EV_USE_IOCP
- if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags);
-#endif
-#if EV_USE_PORT
- if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
-#endif
-#if EV_USE_KQUEUE
- if (!backend && (flags & EVBACKEND_KQUEUE)) backend = kqueue_init (EV_A_ flags);
-#endif
-#if EV_USE_EPOLL
- if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags);
-#endif
-#if EV_USE_POLL
- if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags);
-#endif
-#if EV_USE_SELECT
- if (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags);
-#endif
-
- ev_prepare_init (&pending_w, pendingcb);
-
-#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
- ev_init (&pipe_w, pipecb);
- ev_set_priority (&pipe_w, EV_MAXPRI);
-#endif
- }
-}
-
-/* free up a loop structure */
-void
-ev_loop_destroy (EV_P)
-{
- int i;
-
-#if EV_MULTIPLICITY
- /* mimic free (0) */
- if (!EV_A)
- return;
-#endif
-
-#if EV_CLEANUP_ENABLE
- /* queue cleanup watchers (and execute them) */
- if (expect_false (cleanupcnt))
- {
- queue_events (EV_A_ (W *)cleanups, cleanupcnt, EV_CLEANUP);
- EV_INVOKE_PENDING;
- }
-#endif
-
-#if EV_CHILD_ENABLE
- if (ev_is_active (&childev))
- {
- ev_ref (EV_A); /* child watcher */
- ev_signal_stop (EV_A_ &childev);
- }
-#endif
-
- if (ev_is_active (&pipe_w))
- {
- /*ev_ref (EV_A);*/
- /*ev_io_stop (EV_A_ &pipe_w);*/
-
-#if EV_USE_EVENTFD
- if (evfd >= 0)
- close (evfd);
-#endif
-
- if (evpipe [0] >= 0)
- {
- EV_WIN32_CLOSE_FD (evpipe [0]);
- EV_WIN32_CLOSE_FD (evpipe [1]);
- }
- }
-
-#if EV_USE_SIGNALFD
- if (ev_is_active (&sigfd_w))
- close (sigfd);
-#endif
-
-#if EV_USE_INOTIFY
- if (fs_fd >= 0)
- close (fs_fd);
-#endif
-
- if (backend_fd >= 0)
- close (backend_fd);
-
-#if EV_USE_IOCP
- if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A);
-#endif
-#if EV_USE_PORT
- if (backend == EVBACKEND_PORT ) port_destroy (EV_A);
-#endif
-#if EV_USE_KQUEUE
- if (backend == EVBACKEND_KQUEUE) kqueue_destroy (EV_A);
-#endif
-#if EV_USE_EPOLL
- if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A);
-#endif
-#if EV_USE_POLL
- if (backend == EVBACKEND_POLL ) poll_destroy (EV_A);
-#endif
-#if EV_USE_SELECT
- if (backend == EVBACKEND_SELECT) select_destroy (EV_A);
-#endif
-
- for (i = NUMPRI; i--; )
- {
- array_free (pending, [i]);
-#if EV_IDLE_ENABLE
- array_free (idle, [i]);
-#endif
- }
-
- ev_free (anfds); anfds = 0; anfdmax = 0;
-
- /* have to use the microsoft-never-gets-it-right macro */
- array_free (rfeed, EMPTY);
- array_free (fdchange, EMPTY);
- array_free (timer, EMPTY);
-#if EV_PERIODIC_ENABLE
- array_free (periodic, EMPTY);
-#endif
-#if EV_FORK_ENABLE
- array_free (fork, EMPTY);
-#endif
-#if EV_CLEANUP_ENABLE
- array_free (cleanup, EMPTY);
-#endif
- array_free (prepare, EMPTY);
- array_free (check, EMPTY);
-#if EV_ASYNC_ENABLE
- array_free (async, EMPTY);
-#endif
-
- backend = 0;
-
-#if EV_MULTIPLICITY
- if (ev_is_default_loop (EV_A))
-#endif
- ev_default_loop_ptr = 0;
-#if EV_MULTIPLICITY
- else
- ev_free (EV_A);
-#endif
-}
-
-#if EV_USE_INOTIFY
-inline_size void infy_fork (EV_P);
-#endif
-
-inline_size void
-loop_fork (EV_P)
-{
-#if EV_USE_PORT
- if (backend == EVBACKEND_PORT ) port_fork (EV_A);
-#endif
-#if EV_USE_KQUEUE
- if (backend == EVBACKEND_KQUEUE) kqueue_fork (EV_A);
-#endif
-#if EV_USE_EPOLL
- if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A);
-#endif
-#if EV_USE_INOTIFY
- infy_fork (EV_A);
-#endif
-
- if (ev_is_active (&pipe_w))
- {
- /* this "locks" the handlers against writing to the pipe */
- /* while we modify the fd vars */
- sig_pending = 1;
-#if EV_ASYNC_ENABLE
- async_pending = 1;
-#endif
-
- ev_ref (EV_A);
- ev_io_stop (EV_A_ &pipe_w);
-
-#if EV_USE_EVENTFD
- if (evfd >= 0)
- close (evfd);
-#endif
-
- if (evpipe [0] >= 0)
- {
- EV_WIN32_CLOSE_FD (evpipe [0]);
- EV_WIN32_CLOSE_FD (evpipe [1]);
- }
-
-#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
- evpipe_init (EV_A);
- /* now iterate over everything, in case we missed something */
- pipecb (EV_A_ &pipe_w, EV_READ);
-#endif
- }
-
- postfork = 0;
-}
-
-#if EV_MULTIPLICITY
-
-struct ev_loop *
-ev_loop_new (unsigned int flags)
-{
- EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
-
- memset (EV_A, 0, sizeof (struct ev_loop));
- loop_init (EV_A_ flags);
-
- if (ev_backend (EV_A))
- return EV_A;
-
- ev_free (EV_A);
- return 0;
-}
-
-#endif /* multiplicity */
-
-int
-ev_loop_refcount (EV_P)
-{
- return activecnt;
-}
-
-#if EV_VERIFY
-static void noinline
-verify_watcher (EV_P_ W w)
-{
- assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI));
-
- if (w->pending)
- assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w));
-}
-
-static void noinline
-verify_heap (EV_P_ ANHE *heap, int N)
-{
- int i;
-
- for (i = HEAP0; i < N + HEAP0; ++i)
- {
- assert (("libev: active index mismatch in heap", ev_active (ANHE_w (heap [i])) == i));
- assert (("libev: heap condition violated", i == HEAP0 || ANHE_at (heap [HPARENT (i)]) <= ANHE_at (heap [i])));
- assert (("libev: heap at cache mismatch", ANHE_at (heap [i]) == ev_at (ANHE_w (heap [i]))));
-
- verify_watcher (EV_A_ (W)ANHE_w (heap [i]));
- }
-}
-
-static void noinline
-array_verify (EV_P_ W *ws, int cnt)
-{
- while (cnt--)
- {
- assert (("libev: active index mismatch", ev_active (ws [cnt]) == cnt + 1));
- verify_watcher (EV_A_ ws [cnt]);
- }
-}
-#endif
-
-#if EV_FEATURE_API
-void
-ev_verify (EV_P)
-{
-#if EV_VERIFY
- int i;
- WL w;
-
- assert (activecnt >= -1);
-
- assert (fdchangemax >= fdchangecnt);
- for (i = 0; i < fdchangecnt; ++i)
- assert (("libev: negative fd in fdchanges", fdchanges [i] >= 0));
-
- assert (anfdmax >= 0);
- for (i = 0; i < anfdmax; ++i)
- for (w = anfds [i].head; w; w = w->next)
- {
- verify_watcher (EV_A_ (W)w);
- assert (("libev: inactive fd watcher on anfd list", ev_active (w) == 1));
- assert (("libev: fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i));
- }
-
- assert (timermax >= timercnt);
- verify_heap (EV_A_ timers, timercnt);
-
-#if EV_PERIODIC_ENABLE
- assert (periodicmax >= periodiccnt);
- verify_heap (EV_A_ periodics, periodiccnt);
-#endif
-
- for (i = NUMPRI; i--; )
- {
- assert (pendingmax [i] >= pendingcnt [i]);
-#if EV_IDLE_ENABLE
- assert (idleall >= 0);
- assert (idlemax [i] >= idlecnt [i]);
- array_verify (EV_A_ (W *)idles [i], idlecnt [i]);
-#endif
- }
-
-#if EV_FORK_ENABLE
- assert (forkmax >= forkcnt);
- array_verify (EV_A_ (W *)forks, forkcnt);
-#endif
-
-#if EV_CLEANUP_ENABLE
- assert (cleanupmax >= cleanupcnt);
- array_verify (EV_A_ (W *)cleanups, cleanupcnt);
-#endif
-
-#if EV_ASYNC_ENABLE
- assert (asyncmax >= asynccnt);
- array_verify (EV_A_ (W *)asyncs, asynccnt);
-#endif
-
-#if EV_PREPARE_ENABLE
- assert (preparemax >= preparecnt);
- array_verify (EV_A_ (W *)prepares, preparecnt);
-#endif
-
-#if EV_CHECK_ENABLE
- assert (checkmax >= checkcnt);
- array_verify (EV_A_ (W *)checks, checkcnt);
-#endif
-
-# if 0
-#if EV_CHILD_ENABLE
- for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next)
- for (signum = EV_NSIG; signum--; ) if (signals [signum].pending)
-#endif
-# endif
-#endif
-}
-#endif
-
-#if EV_MULTIPLICITY
-struct ev_loop *
-#else
-int
-#endif
-ev_default_loop (unsigned int flags)
-{
- if (!ev_default_loop_ptr)
- {
-#if EV_MULTIPLICITY
- EV_P = ev_default_loop_ptr = &default_loop_struct;
-#else
- ev_default_loop_ptr = 1;
-#endif
-
- loop_init (EV_A_ flags);
-
- if (ev_backend (EV_A))
- {
-#if EV_CHILD_ENABLE
- ev_signal_init (&childev, childcb, SIGCHLD);
- ev_set_priority (&childev, EV_MAXPRI);
- ev_signal_start (EV_A_ &childev);
- ev_unref (EV_A); /* child watcher should not keep loop alive */
-#endif
- }
- else
- ev_default_loop_ptr = 0;
- }
-
- return ev_default_loop_ptr;
-}
-
-void
-ev_loop_fork (EV_P)
-{
- postfork = 1; /* must be in line with ev_default_fork */
-}
-
-/*****************************************************************************/
-
-void
-ev_invoke (EV_P_ void *w, int revents)
-{
- EV_CB_INVOKE ((W)w, revents);
-}
-
-unsigned int
-ev_pending_count (EV_P)
-{
- int pri;
- unsigned int count = 0;
-
- for (pri = NUMPRI; pri--; )
- count += pendingcnt [pri];
-
- return count;
-}
-
-void noinline
-ev_invoke_pending (EV_P)
-{
- int pri;
-
- for (pri = NUMPRI; pri--; )
- while (pendingcnt [pri])
- {
- ANPENDING *p = pendings [pri] + --pendingcnt [pri];
-
- p->w->pending = 0;
- EV_CB_INVOKE (p->w, p->events);
- EV_FREQUENT_CHECK;
- }
-}
-
-#if EV_IDLE_ENABLE
-/* make idle watchers pending. this handles the "call-idle */
-/* only when higher priorities are idle" logic */
-inline_size void
-idle_reify (EV_P)
-{
- if (expect_false (idleall))
- {
- int pri;
-
- for (pri = NUMPRI; pri--; )
- {
- if (pendingcnt [pri])
- break;
-
- if (idlecnt [pri])
- {
- queue_events (EV_A_ (W *)idles [pri], idlecnt [pri], EV_IDLE);
- break;
- }
- }
- }
-}
-#endif
-
-/* make timers pending */
-inline_size void
-timers_reify (EV_P)
-{
- EV_FREQUENT_CHECK;
-
- if (timercnt && ANHE_at (timers [HEAP0]) < mn_now)
- {
- do
- {
- ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]);
-
- /*assert (("libev: inactive timer on timer heap detected", ev_is_active (w)));*/
-
- /* first reschedule or stop timer */
- if (w->repeat)
- {
- ev_at (w) += w->repeat;
- if (ev_at (w) < mn_now)
- ev_at (w) = mn_now;
-
- assert (("libev: negative ev_timer repeat value found while processing timers", w->repeat > 0.));
-
- ANHE_at_cache (timers [HEAP0]);
- downheap (timers, timercnt, HEAP0);
- }
- else
- ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
-
- EV_FREQUENT_CHECK;
- feed_reverse (EV_A_ (W)w);
- }
- while (timercnt && ANHE_at (timers [HEAP0]) < mn_now);
-
- feed_reverse_done (EV_A_ EV_TIMER);
- }
-}
-
-#if EV_PERIODIC_ENABLE
-
-inline_speed void
-periodic_recalc (EV_P_ ev_periodic *w)
-{
- /* TODO: use slow but potentially more correct incremental algo, */
- /* also do not rely on ceil */
- ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
-}
-
-/* make periodics pending */
-inline_size void
-periodics_reify (EV_P)
-{
- EV_FREQUENT_CHECK;
-
- while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now)
- {
- int feed_count = 0;
-
- do
- {
- ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]);
-
- /*assert (("libev: inactive timer on periodic heap detected", ev_is_active (w)));*/
-
- /* first reschedule or stop timer */
- if (w->reschedule_cb)
- {
- ev_at (w) = w->reschedule_cb (w, ev_rt_now);
-
- assert (("libev: ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now));
-
- ANHE_at_cache (periodics [HEAP0]);
- downheap (periodics, periodiccnt, HEAP0);
- }
- else if (w->interval)
- {
- periodic_recalc (EV_A_ w);
-
- /* if next trigger time is not sufficiently in the future, put it there */
- /* this might happen because of floating point inexactness */
- if (ev_at (w) - ev_rt_now < TIME_EPSILON)
- {
- ev_at (w) += w->interval;
-
- /* if interval is unreasonably low we might still have a time in the past */
- /* so correct this. this will make the periodic very inexact, but the user */
- /* has effectively asked to get triggered more often than possible */
- if (ev_at (w) < ev_rt_now)
- ev_at (w) = ev_rt_now;
- }
-
- ANHE_at_cache (periodics [HEAP0]);
- downheap (periodics, periodiccnt, HEAP0);
- }
- else
- ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */
-
- EV_FREQUENT_CHECK;
- feed_reverse (EV_A_ (W)w);
- }
- while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now);
-
- feed_reverse_done (EV_A_ EV_PERIODIC);
- }
-}
-
-/* simply recalculate all periodics */
-/* TODO: maybe ensure that at least one event happens when jumping forward? */
-static void noinline
-periodics_reschedule (EV_P)
-{
- int i;
-
- /* adjust periodics after time jump */
- for (i = HEAP0; i < periodiccnt + HEAP0; ++i)
- {
- ev_periodic *w = (ev_periodic *)ANHE_w (periodics [i]);
-
- if (w->reschedule_cb)
- ev_at (w) = w->reschedule_cb (w, ev_rt_now);
- else if (w->interval)
- periodic_recalc (EV_A_ w);
-
- ANHE_at_cache (periodics [i]);
- }
-
- reheap (periodics, periodiccnt);
-}
-#endif
-
-/* adjust all timers by a given offset */
-static void noinline
-timers_reschedule (EV_P_ ev_tstamp adjust)
-{
- int i;
-
- for (i = 0; i < timercnt; ++i)
- {
- ANHE *he = timers + i + HEAP0;
- ANHE_w (*he)->at += adjust;
- ANHE_at_cache (*he);
- }
-}
-
-/* fetch new monotonic and realtime times from the kernel */
-/* also detect if there was a timejump, and act accordingly */
-inline_speed void
-time_update (EV_P_ ev_tstamp max_block)
-{
-#if EV_USE_MONOTONIC
- if (expect_true (have_monotonic))
- {
- int i;
- ev_tstamp odiff = rtmn_diff;
-
- mn_now = get_clock ();
-
- /* only fetch the realtime clock every 0.5*MIN_TIMEJUMP seconds */
- /* interpolate in the meantime */
- if (expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5))
- {
- ev_rt_now = rtmn_diff + mn_now;
- return;
- }
-
- now_floor = mn_now;
- ev_rt_now = ev_time ();
-
- /* loop a few times, before making important decisions.
- * on the choice of "4": one iteration isn't enough,
- * in case we get preempted during the calls to
- * ev_time and get_clock. a second call is almost guaranteed
- * to succeed in that case, though. and looping a few more times
- * doesn't hurt either as we only do this on time-jumps or
- * in the unlikely event of having been preempted here.
- */
- for (i = 4; --i; )
- {
- rtmn_diff = ev_rt_now - mn_now;
-
- if (expect_true (fabs (odiff - rtmn_diff) < MIN_TIMEJUMP))
- return; /* all is well */
-
- ev_rt_now = ev_time ();
- mn_now = get_clock ();
- now_floor = mn_now;
- }
-
- /* no timer adjustment, as the monotonic clock doesn't jump */
- /* timers_reschedule (EV_A_ rtmn_diff - odiff) */
-# if EV_PERIODIC_ENABLE
- periodics_reschedule (EV_A);
-# endif
- }
- else
-#endif
- {
- ev_rt_now = ev_time ();
-
- if (expect_false (mn_now > ev_rt_now || ev_rt_now > mn_now + max_block + MIN_TIMEJUMP))
- {
- /* adjust timers. this is easy, as the offset is the same for all of them */
- timers_reschedule (EV_A_ ev_rt_now - mn_now);
-#if EV_PERIODIC_ENABLE
- periodics_reschedule (EV_A);
-#endif
- }
-
- mn_now = ev_rt_now;
- }
-}
-
-void
-ev_run (EV_P_ int flags)
-{
-#if EV_FEATURE_API
- ++loop_depth;
-#endif
-
- assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE));
-
- loop_done = EVBREAK_CANCEL;
-
- EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */
-
- do
- {
-#if EV_VERIFY >= 2
- ev_verify (EV_A);
-#endif
-
-#ifndef _WIN32
- if (expect_false (curpid)) /* penalise the forking check even more */
- if (expect_false (getpid () != curpid))
- {
- curpid = getpid ();
- postfork = 1;
- }
-#endif
-
-#if EV_FORK_ENABLE
- /* we might have forked, so queue fork handlers */
- if (expect_false (postfork))
- if (forkcnt)
- {
- queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK);
- EV_INVOKE_PENDING;
- }
-#endif
-
-#if EV_PREPARE_ENABLE
- /* queue prepare watchers (and execute them) */
- if (expect_false (preparecnt))
- {
- queue_events (EV_A_ (W *)prepares, preparecnt, EV_PREPARE);
- EV_INVOKE_PENDING;
- }
-#endif
-
- if (expect_false (loop_done))
- break;
-
- /* we might have forked, so reify kernel state if necessary */
- if (expect_false (postfork))
- loop_fork (EV_A);
-
- /* update fd-related kernel structures */
- fd_reify (EV_A);
-
- /* calculate blocking time */
- {
- ev_tstamp waittime = 0.;
- ev_tstamp sleeptime = 0.;
-
- /* remember old timestamp for io_blocktime calculation */
- ev_tstamp prev_mn_now = mn_now;
-
- /* update time to cancel out callback processing overhead */
- time_update (EV_A_ 1e100);
-
- if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt)))
- {
- waittime = MAX_BLOCKTIME;
-
- if (timercnt)
- {
- ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now + backend_fudge;
- if (waittime > to) waittime = to;
- }
-
-#if EV_PERIODIC_ENABLE
- if (periodiccnt)
- {
- ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now + backend_fudge;
- if (waittime > to) waittime = to;
- }
-#endif
-
- /* don't let timeouts decrease the waittime below timeout_blocktime */
- if (expect_false (waittime < timeout_blocktime))
- waittime = timeout_blocktime;
-
- /* extra check because io_blocktime is commonly 0 */
- if (expect_false (io_blocktime))
- {
- sleeptime = io_blocktime - (mn_now - prev_mn_now);
-
- if (sleeptime > waittime - backend_fudge)
- sleeptime = waittime - backend_fudge;
-
- if (expect_true (sleeptime > 0.))
- {
- ev_sleep (sleeptime);
- waittime -= sleeptime;
- }
- }
- }
-
-#if EV_FEATURE_API
- ++loop_count;
-#endif
- assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */
- backend_poll (EV_A_ waittime);
- assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */
-
- /* update ev_rt_now, do magic */
- time_update (EV_A_ waittime + sleeptime);
- }
-
- /* queue pending timers and reschedule them */
- timers_reify (EV_A); /* relative timers called last */
-#if EV_PERIODIC_ENABLE
- periodics_reify (EV_A); /* absolute timers called first */
-#endif
-
-#if EV_IDLE_ENABLE
- /* queue idle watchers unless other events are pending */
- idle_reify (EV_A);
-#endif
-
-#if EV_CHECK_ENABLE
- /* queue check watchers, to be executed first */
- if (expect_false (checkcnt))
- queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK);
-#endif
-
- EV_INVOKE_PENDING;
- }
- while (expect_true (
- activecnt
- && !loop_done
- && !(flags & (EVRUN_ONCE | EVRUN_NOWAIT))
- ));
-
- if (loop_done == EVBREAK_ONE)
- loop_done = EVBREAK_CANCEL;
-
-#if EV_FEATURE_API
- --loop_depth;
-#endif
-}
-
-/* libuv special */
-void
-ev__run (EV_P_ ev_tstamp waittime)
-{
- fd_reify (EV_A);
- backend_poll (EV_A_ waittime);
-}
-
-void
-ev_break (EV_P_ int how)
-{
- loop_done = how;
-}
-
-void
-ev_ref (EV_P)
-{
- ++activecnt;
-}
-
-void
-ev_unref (EV_P)
-{
- --activecnt;
- if (activecnt < 0) abort();
-}
-
-void
-ev_now_update (EV_P)
-{
- time_update (EV_A_ 1e100);
-}
-
-void
-ev_suspend (EV_P)
-{
- ev_now_update (EV_A);
-}
-
-void
-ev_resume (EV_P)
-{
- ev_tstamp mn_prev = mn_now;
-
- ev_now_update (EV_A);
- timers_reschedule (EV_A_ mn_now - mn_prev);
-#if EV_PERIODIC_ENABLE
- /* TODO: really do this? */
- periodics_reschedule (EV_A);
-#endif
-}
-
-/*****************************************************************************/
-/* singly-linked list management, used when the expected list length is short */
-
-inline_size void
-wlist_add (WL *head, WL elem)
-{
- elem->next = *head;
- *head = elem;
-}
-
-inline_size void
-wlist_del (WL *head, WL elem)
-{
- while (*head)
- {
- if (expect_true (*head == elem))
- {
- *head = elem->next;
- break;
- }
-
- head = &(*head)->next;
- }
-}
-
-/* internal, faster, version of ev_clear_pending */
-inline_speed void
-clear_pending (EV_P_ W w)
-{
- if (w->pending)
- {
- pendings [ABSPRI (w)][w->pending - 1].w = (W)&pending_w;
- w->pending = 0;
- }
-}
-
-int
-ev_clear_pending (EV_P_ void *w)
-{
- W w_ = (W)w;
- int pending = w_->pending;
-
- if (expect_true (pending))
- {
- ANPENDING *p = pendings [ABSPRI (w_)] + pending - 1;
- p->w = (W)&pending_w;
- w_->pending = 0;
- return p->events;
- }
- else
- return 0;
-}
-
-inline_size void
-pri_adjust (EV_P_ W w)
-{
- int pri = ev_priority (w);
- pri = pri < EV_MINPRI ? EV_MINPRI : pri;
- pri = pri > EV_MAXPRI ? EV_MAXPRI : pri;
- ev_set_priority (w, pri);
-}
-
-inline_speed void
-ev_start (EV_P_ W w, int active)
-{
- pri_adjust (EV_A_ w);
- w->active = active;
- ev_ref (EV_A);
-}
-
-inline_size void
-ev_stop (EV_P_ W w)
-{
- ev_unref (EV_A);
- w->active = 0;
-}
-
-/*****************************************************************************/
-
-void noinline
-ev_io_start (EV_P_ ev_io *w)
-{
- int fd = w->fd;
-
- if (expect_false (ev_is_active (w)))
- return;
-
- assert (("libev: ev_io_start called with negative fd", fd >= 0));
- assert (("libev: ev_io_start called with illegal event mask",
- !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE | EV_LIBUV_KQUEUE_HACK))));
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, 1);
- array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero);
- wlist_add (&anfds[fd].head, (WL)w);
-
- fd_change (EV_A_ fd, w->events & EV__IOFDSET | EV_ANFD_REIFY);
- w->events &= ~EV__IOFDSET;
-
- EV_FREQUENT_CHECK;
-}
-
-void noinline
-ev_io_stop (EV_P_ ev_io *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
-
- EV_FREQUENT_CHECK;
-
- wlist_del (&anfds[w->fd].head, (WL)w);
- ev_stop (EV_A_ (W)w);
-
- fd_change (EV_A_ w->fd, EV_ANFD_REIFY);
-
- EV_FREQUENT_CHECK;
-}
-
-void noinline
-ev_timer_start (EV_P_ ev_timer *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- ev_at (w) += mn_now;
-
- assert (("libev: ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
-
- EV_FREQUENT_CHECK;
-
- ++timercnt;
- ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1);
- array_needsize (ANHE, timers, timermax, ev_active (w) + 1, EMPTY2);
- ANHE_w (timers [ev_active (w)]) = (WT)w;
- ANHE_at_cache (timers [ev_active (w)]);
- upheap (timers, ev_active (w));
-
- EV_FREQUENT_CHECK;
-
- /*assert (("libev: internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/
-}
-
-void noinline
-ev_timer_stop (EV_P_ ev_timer *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- assert (("libev: internal timer heap corruption", ANHE_w (timers [active]) == (WT)w));
-
- --timercnt;
-
- if (expect_true (active < timercnt + HEAP0))
- {
- timers [active] = timers [timercnt + HEAP0];
- adjustheap (timers, timercnt, active);
- }
- }
-
- ev_at (w) -= mn_now;
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-
-void noinline
-ev_timer_again (EV_P_ ev_timer *w)
-{
- EV_FREQUENT_CHECK;
-
- if (ev_is_active (w))
- {
- if (w->repeat)
- {
- ev_at (w) = mn_now + w->repeat;
- ANHE_at_cache (timers [ev_active (w)]);
- adjustheap (timers, timercnt, ev_active (w));
- }
- else
- ev_timer_stop (EV_A_ w);
- }
- else if (w->repeat)
- {
- ev_at (w) = w->repeat;
- ev_timer_start (EV_A_ w);
- }
-
- EV_FREQUENT_CHECK;
-}
-
-ev_tstamp
-ev_timer_remaining (EV_P_ ev_timer *w)
-{
- return ev_at (w) - (ev_is_active (w) ? mn_now : 0.);
-}
-
-#if EV_PERIODIC_ENABLE
-void noinline
-ev_periodic_start (EV_P_ ev_periodic *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- if (w->reschedule_cb)
- ev_at (w) = w->reschedule_cb (w, ev_rt_now);
- else if (w->interval)
- {
- assert (("libev: ev_periodic_start called with negative interval value", w->interval >= 0.));
- periodic_recalc (EV_A_ w);
- }
- else
- ev_at (w) = w->offset;
-
- EV_FREQUENT_CHECK;
-
- ++periodiccnt;
- ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1);
- array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, EMPTY2);
- ANHE_w (periodics [ev_active (w)]) = (WT)w;
- ANHE_at_cache (periodics [ev_active (w)]);
- upheap (periodics, ev_active (w));
-
- EV_FREQUENT_CHECK;
-
- /*assert (("libev: internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/
-}
-
-void noinline
-ev_periodic_stop (EV_P_ ev_periodic *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- assert (("libev: internal periodic heap corruption", ANHE_w (periodics [active]) == (WT)w));
-
- --periodiccnt;
-
- if (expect_true (active < periodiccnt + HEAP0))
- {
- periodics [active] = periodics [periodiccnt + HEAP0];
- adjustheap (periodics, periodiccnt, active);
- }
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-
-void noinline
-ev_periodic_again (EV_P_ ev_periodic *w)
-{
- /* TODO: use adjustheap and recalculation */
- ev_periodic_stop (EV_A_ w);
- ev_periodic_start (EV_A_ w);
-}
-#endif
-
-#ifndef SA_RESTART
-# define SA_RESTART 0
-#endif
-
-#if EV_SIGNAL_ENABLE
-
-void noinline
-ev_signal_start (EV_P_ ev_signal *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- assert (("libev: ev_signal_start called with illegal signal number", w->signum > 0 && w->signum < EV_NSIG));
-
-#if EV_MULTIPLICITY
- assert (("libev: a signal must not be attached to two different loops",
- !signals [w->signum - 1].loop || signals [w->signum - 1].loop == loop));
-
- signals [w->signum - 1].loop = EV_A;
-#endif
-
- EV_FREQUENT_CHECK;
-
-#if EV_USE_SIGNALFD
- if (sigfd == -2)
- {
- sigfd = signalfd (-1, &sigfd_set, SFD_NONBLOCK | SFD_CLOEXEC);
- if (sigfd < 0 && errno == EINVAL)
- sigfd = signalfd (-1, &sigfd_set, 0); /* retry without flags */
-
- if (sigfd >= 0)
- {
- fd_intern (sigfd); /* doing it twice will not hurt */
-
- sigemptyset (&sigfd_set);
-
- ev_io_init (&sigfd_w, sigfdcb, sigfd, EV_READ);
- ev_set_priority (&sigfd_w, EV_MAXPRI);
- ev_io_start (EV_A_ &sigfd_w);
- ev_unref (EV_A); /* signalfd watcher should not keep loop alive */
- }
- }
-
- if (sigfd >= 0)
- {
- /* TODO: check .head */
- sigaddset (&sigfd_set, w->signum);
- sigprocmask (SIG_BLOCK, &sigfd_set, 0);
-
- signalfd (sigfd, &sigfd_set, 0);
- }
-#endif
-
- ev_start (EV_A_ (W)w, 1);
- wlist_add (&signals [w->signum - 1].head, (WL)w);
-
- if (!((WL)w)->next)
-# if EV_USE_SIGNALFD
- if (sigfd < 0) /*TODO*/
-# endif
- {
-# ifdef _WIN32
- evpipe_init (EV_A);
-
- signal (w->signum, ev_sighandler);
-# else
- struct sigaction sa;
-
- evpipe_init (EV_A);
-
- sa.sa_handler = ev_sighandler;
- sigfillset (&sa.sa_mask);
- sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */
- sigaction (w->signum, &sa, 0);
-
- if (origflags & EVFLAG_NOSIGMASK)
- {
- sigemptyset (&sa.sa_mask);
- sigaddset (&sa.sa_mask, w->signum);
- sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
- }
-#endif
- }
-
- EV_FREQUENT_CHECK;
-}
-
-void noinline
-ev_signal_stop (EV_P_ ev_signal *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- wlist_del (&signals [w->signum - 1].head, (WL)w);
- ev_stop (EV_A_ (W)w);
-
- if (!signals [w->signum - 1].head)
- {
-#if EV_MULTIPLICITY
- signals [w->signum - 1].loop = 0; /* unattach from signal */
-#endif
-#if EV_USE_SIGNALFD
- if (sigfd >= 0)
- {
- sigset_t ss;
-
- sigemptyset (&ss);
- sigaddset (&ss, w->signum);
- sigdelset (&sigfd_set, w->signum);
-
- signalfd (sigfd, &sigfd_set, 0);
- sigprocmask (SIG_UNBLOCK, &ss, 0);
- }
- else
-#endif
- signal (w->signum, SIG_DFL);
- }
-
- EV_FREQUENT_CHECK;
-}
-
-#endif
-
-#if EV_CHILD_ENABLE
-
-void
-ev_child_start (EV_P_ ev_child *w)
-{
-#if EV_MULTIPLICITY
- assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr));
-#endif
- if (expect_false (ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, 1);
- wlist_add (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w);
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_child_stop (EV_P_ ev_child *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- wlist_del (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w);
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-
-#endif
-
-#if EV_STAT_ENABLE
-
-# ifdef _WIN32
-# undef lstat
-# define lstat(a,b) _stati64 (a,b)
-# endif
-
-#define DEF_STAT_INTERVAL 5.0074891
-#define NFS_STAT_INTERVAL 30.1074891 /* for filesystems potentially failing inotify */
-#define MIN_STAT_INTERVAL 0.1074891
-
-static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents);
-
-#if EV_USE_INOTIFY
-
-/* the * 2 is to allow for alignment padding, which for some reason is >> 8 */
-# define EV_INOTIFY_BUFSIZE (sizeof (struct inotify_event) * 2 + NAME_MAX)
-
-static void noinline
-infy_add (EV_P_ ev_stat *w)
-{
- w->wd = inotify_add_watch (fs_fd, w->path, IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY | IN_DONT_FOLLOW | IN_MASK_ADD);
-
- if (w->wd >= 0)
- {
- struct statfs sfs;
-
- /* now local changes will be tracked by inotify, but remote changes won't */
- /* unless the filesystem is known to be local, we therefore still poll */
- /* also do poll on <2.6.25, but with normal frequency */
-
- if (!fs_2625)
- w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
- else if (!statfs (w->path, &sfs)
- && (sfs.f_type == 0x1373 /* devfs */
- || sfs.f_type == 0xEF53 /* ext2/3 */
- || sfs.f_type == 0x3153464a /* jfs */
- || sfs.f_type == 0x52654973 /* reiser3 */
- || sfs.f_type == 0x01021994 /* tempfs */
- || sfs.f_type == 0x58465342 /* xfs */))
- w->timer.repeat = 0.; /* filesystem is local, kernel new enough */
- else
- w->timer.repeat = w->interval ? w->interval : NFS_STAT_INTERVAL; /* remote, use reduced frequency */
- }
- else
- {
- /* can't use inotify, continue to stat */
- w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
-
- /* if path is not there, monitor some parent directory for speedup hints */
- /* note that exceeding the hardcoded path limit is not a correctness issue, */
- /* but an efficiency issue only */
- if ((errno == ENOENT || errno == EACCES) && strlen (w->path) < 4096)
- {
- char path [4096];
- strcpy (path, w->path);
-
- do
- {
- int mask = IN_MASK_ADD | IN_DELETE_SELF | IN_MOVE_SELF
- | (errno == EACCES ? IN_ATTRIB : IN_CREATE | IN_MOVED_TO);
-
- char *pend = strrchr (path, '/');
-
- if (!pend || pend == path)
- break;
-
- *pend = 0;
- w->wd = inotify_add_watch (fs_fd, path, mask);
- }
- while (w->wd < 0 && (errno == ENOENT || errno == EACCES));
- }
- }
-
- if (w->wd >= 0)
- wlist_add (&fs_hash [w->wd & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w);
-
- /* now re-arm timer, if required */
- if (ev_is_active (&w->timer)) ev_ref (EV_A);
- ev_timer_again (EV_A_ &w->timer);
- if (ev_is_active (&w->timer)) ev_unref (EV_A);
-}
-
-static void noinline
-infy_del (EV_P_ ev_stat *w)
-{
- int slot;
- int wd = w->wd;
-
- if (wd < 0)
- return;
-
- w->wd = -2;
- slot = wd & ((EV_INOTIFY_HASHSIZE) - 1);
- wlist_del (&fs_hash [slot].head, (WL)w);
-
- /* remove this watcher, if others are watching it, they will rearm */
- inotify_rm_watch (fs_fd, wd);
-}
-
-static void noinline
-infy_wd (EV_P_ int slot, int wd, struct inotify_event *ev)
-{
- if (slot < 0)
- /* overflow, need to check for all hash slots */
- for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot)
- infy_wd (EV_A_ slot, wd, ev);
- else
- {
- WL w_;
-
- for (w_ = fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head; w_; )
- {
- ev_stat *w = (ev_stat *)w_;
- w_ = w_->next; /* lets us remove this watcher and all before it */
-
- if (w->wd == wd || wd == -1)
- {
- if (ev->mask & (IN_IGNORED | IN_UNMOUNT | IN_DELETE_SELF))
- {
- wlist_del (&fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w);
- w->wd = -1;
- infy_add (EV_A_ w); /* re-add, no matter what */
- }
-
- stat_timer_cb (EV_A_ &w->timer, 0);
- }
- }
- }
-}
-
-static void
-infy_cb (EV_P_ ev_io *w, int revents)
-{
- char buf [EV_INOTIFY_BUFSIZE];
- int ofs;
- int len = read (fs_fd, buf, sizeof (buf));
-
- for (ofs = 0; ofs < len; )
- {
- struct inotify_event *ev = (struct inotify_event *)(buf + ofs);
- infy_wd (EV_A_ ev->wd, ev->wd, ev);
- ofs += sizeof (struct inotify_event) + ev->len;
- }
-}
-
-inline_size void
-ev_check_2625 (EV_P)
-{
- /* kernels < 2.6.25 are borked
- * http://www.ussg.indiana.edu/hypermail/linux/kernel/0711.3/1208.html
- */
- if (ev_linux_version () < 0x020619)
- return;
-
- fs_2625 = 1;
-}
-
-inline_size int
-infy_newfd (void)
-{
-#if defined (IN_CLOEXEC) && defined (IN_NONBLOCK)
- int fd = inotify_init1 (IN_CLOEXEC | IN_NONBLOCK);
- if (fd >= 0)
- return fd;
-#endif
- return inotify_init ();
-}
-
-inline_size void
-infy_init (EV_P)
-{
- if (fs_fd != -2)
- return;
-
- fs_fd = -1;
-
- ev_check_2625 (EV_A);
-
- fs_fd = infy_newfd ();
-
- if (fs_fd >= 0)
- {
- fd_intern (fs_fd);
- ev_io_init (&fs_w, infy_cb, fs_fd, EV_READ);
- ev_set_priority (&fs_w, EV_MAXPRI);
- ev_io_start (EV_A_ &fs_w);
- ev_unref (EV_A);
- }
-}
-
-inline_size void
-infy_fork (EV_P)
-{
- int slot;
-
- if (fs_fd < 0)
- return;
-
- ev_ref (EV_A);
- ev_io_stop (EV_A_ &fs_w);
- close (fs_fd);
- fs_fd = infy_newfd ();
-
- if (fs_fd >= 0)
- {
- fd_intern (fs_fd);
- ev_io_set (&fs_w, fs_fd, EV_READ);
- ev_io_start (EV_A_ &fs_w);
- ev_unref (EV_A);
- }
-
- for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot)
- {
- WL w_ = fs_hash [slot].head;
- fs_hash [slot].head = 0;
-
- while (w_)
- {
- ev_stat *w = (ev_stat *)w_;
- w_ = w_->next; /* lets us add this watcher */
-
- w->wd = -1;
-
- if (fs_fd >= 0)
- infy_add (EV_A_ w); /* re-add, no matter what */
- else
- {
- w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
- if (ev_is_active (&w->timer)) ev_ref (EV_A);
- ev_timer_again (EV_A_ &w->timer);
- if (ev_is_active (&w->timer)) ev_unref (EV_A);
- }
- }
- }
-}
-
-#endif
-
-#ifdef _WIN32
-# define EV_LSTAT(p,b) _stati64 (p, b)
-#else
-# define EV_LSTAT(p,b) lstat (p, b)
-#endif
-
-void
-ev_stat_stat (EV_P_ ev_stat *w)
-{
- if (lstat (w->path, &w->attr) < 0)
- w->attr.st_nlink = 0;
- else if (!w->attr.st_nlink)
- w->attr.st_nlink = 1;
-}
-
-static void noinline
-stat_timer_cb (EV_P_ ev_timer *w_, int revents)
-{
- ev_stat *w = (ev_stat *)(((char *)w_) - offsetof (ev_stat, timer));
-
- ev_statdata prev = w->attr;
- ev_stat_stat (EV_A_ w);
-
- /* memcmp doesn't work on netbsd, they.... do stuff to their struct stat */
- if (
- prev.st_dev != w->attr.st_dev
- || prev.st_ino != w->attr.st_ino
- || prev.st_mode != w->attr.st_mode
- || prev.st_nlink != w->attr.st_nlink
- || prev.st_uid != w->attr.st_uid
- || prev.st_gid != w->attr.st_gid
- || prev.st_rdev != w->attr.st_rdev
- || prev.st_size != w->attr.st_size
- || prev.st_atime != w->attr.st_atime
- || prev.st_mtime != w->attr.st_mtime
- || prev.st_ctime != w->attr.st_ctime
- ) {
- /* we only update w->prev on actual differences */
- /* in case we test more often than invoke the callback, */
- /* to ensure that prev is always different to attr */
- w->prev = prev;
-
- #if EV_USE_INOTIFY
- if (fs_fd >= 0)
- {
- infy_del (EV_A_ w);
- infy_add (EV_A_ w);
- ev_stat_stat (EV_A_ w); /* avoid race... */
- }
- #endif
-
- ev_feed_event (EV_A_ w, EV_STAT);
- }
-}
-
-void
-ev_stat_start (EV_P_ ev_stat *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- ev_stat_stat (EV_A_ w);
-
- if (w->interval < MIN_STAT_INTERVAL && w->interval)
- w->interval = MIN_STAT_INTERVAL;
-
- ev_timer_init (&w->timer, stat_timer_cb, 0., w->interval ? w->interval : DEF_STAT_INTERVAL);
- ev_set_priority (&w->timer, ev_priority (w));
-
-#if EV_USE_INOTIFY
- infy_init (EV_A);
-
- if (fs_fd >= 0)
- infy_add (EV_A_ w);
- else
-#endif
- {
- ev_timer_again (EV_A_ &w->timer);
- ev_unref (EV_A);
- }
-
- ev_start (EV_A_ (W)w, 1);
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_stat_stop (EV_P_ ev_stat *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
-#if EV_USE_INOTIFY
- infy_del (EV_A_ w);
-#endif
-
- if (ev_is_active (&w->timer))
- {
- ev_ref (EV_A);
- ev_timer_stop (EV_A_ &w->timer);
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_IDLE_ENABLE
-void
-ev_idle_start (EV_P_ ev_idle *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- pri_adjust (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ++idlecnt [ABSPRI (w)];
-
- ++idleall;
- ev_start (EV_A_ (W)w, active);
-
- array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, EMPTY2);
- idles [ABSPRI (w)][active - 1] = w;
- }
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_idle_stop (EV_P_ ev_idle *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- idles [ABSPRI (w)][active - 1] = idles [ABSPRI (w)][--idlecnt [ABSPRI (w)]];
- ev_active (idles [ABSPRI (w)][active - 1]) = active;
-
- ev_stop (EV_A_ (W)w);
- --idleall;
- }
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_PREPARE_ENABLE
-void
-ev_prepare_start (EV_P_ ev_prepare *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, ++preparecnt);
- array_needsize (ev_prepare *, prepares, preparemax, preparecnt, EMPTY2);
- prepares [preparecnt - 1] = w;
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_prepare_stop (EV_P_ ev_prepare *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- prepares [active - 1] = prepares [--preparecnt];
- ev_active (prepares [active - 1]) = active;
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_CHECK_ENABLE
-void
-ev_check_start (EV_P_ ev_check *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, ++checkcnt);
- array_needsize (ev_check *, checks, checkmax, checkcnt, EMPTY2);
- checks [checkcnt - 1] = w;
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_check_stop (EV_P_ ev_check *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- checks [active - 1] = checks [--checkcnt];
- ev_active (checks [active - 1]) = active;
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_EMBED_ENABLE
-void noinline
-ev_embed_sweep (EV_P_ ev_embed *w)
-{
- ev_run (w->other, EVRUN_NOWAIT);
-}
-
-static void
-embed_io_cb (EV_P_ ev_io *io, int revents)
-{
- ev_embed *w = (ev_embed *)(((char *)io) - offsetof (ev_embed, io));
-
- if (ev_cb (w))
- ev_feed_event (EV_A_ (W)w, EV_EMBED);
- else
- ev_run (w->other, EVRUN_NOWAIT);
-}
-
-static void
-embed_prepare_cb (EV_P_ ev_prepare *prepare, int revents)
-{
- ev_embed *w = (ev_embed *)(((char *)prepare) - offsetof (ev_embed, prepare));
-
- {
- EV_P = w->other;
-
- while (fdchangecnt)
- {
- fd_reify (EV_A);
- ev_run (EV_A_ EVRUN_NOWAIT);
- }
- }
-}
-
-static void
-embed_fork_cb (EV_P_ ev_fork *fork_w, int revents)
-{
- ev_embed *w = (ev_embed *)(((char *)fork_w) - offsetof (ev_embed, fork));
-
- ev_embed_stop (EV_A_ w);
-
- {
- EV_P = w->other;
-
- ev_loop_fork (EV_A);
- ev_run (EV_A_ EVRUN_NOWAIT);
- }
-
- ev_embed_start (EV_A_ w);
-}
-
-#if 0
-static void
-embed_idle_cb (EV_P_ ev_idle *idle, int revents)
-{
- ev_idle_stop (EV_A_ idle);
-}
-#endif
-
-void
-ev_embed_start (EV_P_ ev_embed *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- {
- EV_P = w->other;
- assert (("libev: loop to be embedded is not embeddable", backend & ev_embeddable_backends ()));
- ev_io_init (&w->io, embed_io_cb, backend_fd, EV_READ);
- }
-
- EV_FREQUENT_CHECK;
-
- ev_set_priority (&w->io, ev_priority (w));
- ev_io_start (EV_A_ &w->io);
-
- ev_prepare_init (&w->prepare, embed_prepare_cb);
- ev_set_priority (&w->prepare, EV_MINPRI);
- ev_prepare_start (EV_A_ &w->prepare);
-
- ev_fork_init (&w->fork, embed_fork_cb);
- ev_fork_start (EV_A_ &w->fork);
-
- /*ev_idle_init (&w->idle, e,bed_idle_cb);*/
-
- ev_start (EV_A_ (W)w, 1);
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_embed_stop (EV_P_ ev_embed *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_io_stop (EV_A_ &w->io);
- ev_prepare_stop (EV_A_ &w->prepare);
- ev_fork_stop (EV_A_ &w->fork);
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_FORK_ENABLE
-void
-ev_fork_start (EV_P_ ev_fork *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, ++forkcnt);
- array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2);
- forks [forkcnt - 1] = w;
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_fork_stop (EV_P_ ev_fork *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- forks [active - 1] = forks [--forkcnt];
- ev_active (forks [active - 1]) = active;
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_CLEANUP_ENABLE
-void
-ev_cleanup_start (EV_P_ ev_cleanup *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, ++cleanupcnt);
- array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, EMPTY2);
- cleanups [cleanupcnt - 1] = w;
-
- /* cleanup watchers should never keep a refcount on the loop */
- ev_unref (EV_A);
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_cleanup_stop (EV_P_ ev_cleanup *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
- ev_ref (EV_A);
-
- {
- int active = ev_active (w);
-
- cleanups [active - 1] = cleanups [--cleanupcnt];
- ev_active (cleanups [active - 1]) = active;
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_ASYNC_ENABLE
-void
-ev_async_start (EV_P_ ev_async *w)
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- w->sent = 0;
-
- evpipe_init (EV_A);
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, ++asynccnt);
- array_needsize (ev_async *, asyncs, asyncmax, asynccnt, EMPTY2);
- asyncs [asynccnt - 1] = w;
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_async_stop (EV_P_ ev_async *w)
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- asyncs [active - 1] = asyncs [--asynccnt];
- ev_active (asyncs [active - 1]) = active;
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_async_send (EV_P_ ev_async *w)
-{
- w->sent = 1;
- evpipe_write (EV_A_ &async_pending);
-}
-#endif
-
-/*****************************************************************************/
-
-struct ev_once
-{
- ev_io io;
- ev_timer to;
- void (*cb)(int revents, void *arg);
- void *arg;
-};
-
-static void
-once_cb (EV_P_ struct ev_once *once, int revents)
-{
- void (*cb)(int revents, void *arg) = once->cb;
- void *arg = once->arg;
-
- ev_io_stop (EV_A_ &once->io);
- ev_timer_stop (EV_A_ &once->to);
- ev_free (once);
-
- cb (revents, arg);
-}
-
-static void
-once_cb_io (EV_P_ ev_io *w, int revents)
-{
- struct ev_once *once = (struct ev_once *)(((char *)w) - offsetof (struct ev_once, io));
-
- once_cb (EV_A_ once, revents | ev_clear_pending (EV_A_ &once->to));
-}
-
-static void
-once_cb_to (EV_P_ ev_timer *w, int revents)
-{
- struct ev_once *once = (struct ev_once *)(((char *)w) - offsetof (struct ev_once, to));
-
- once_cb (EV_A_ once, revents | ev_clear_pending (EV_A_ &once->io));
-}
-
-void
-ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg)
-{
- struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once));
-
- if (expect_false (!once))
- {
- cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMER, arg);
- return;
- }
-
- once->cb = cb;
- once->arg = arg;
-
- ev_init (&once->io, once_cb_io);
- if (fd >= 0)
- {
- ev_io_set (&once->io, fd, events);
- ev_io_start (EV_A_ &once->io);
- }
-
- ev_init (&once->to, once_cb_to);
- if (timeout >= 0.)
- {
- ev_timer_set (&once->to, timeout, 0.);
- ev_timer_start (EV_A_ &once->to);
- }
-}
-
-/*****************************************************************************/
-
-#if EV_WALK_ENABLE
-void
-ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
-{
- int i, j;
- ev_watcher_list *wl, *wn;
-
- if (types & (EV_IO | EV_EMBED))
- for (i = 0; i < anfdmax; ++i)
- for (wl = anfds [i].head; wl; )
- {
- wn = wl->next;
-
-#if EV_EMBED_ENABLE
- if (ev_cb ((ev_io *)wl) == embed_io_cb)
- {
- if (types & EV_EMBED)
- cb (EV_A_ EV_EMBED, ((char *)wl) - offsetof (struct ev_embed, io));
- }
- else
-#endif
-#if EV_USE_INOTIFY
- if (ev_cb ((ev_io *)wl) == infy_cb)
- ;
- else
-#endif
- if ((ev_io *)wl != &pipe_w)
- if (types & EV_IO)
- cb (EV_A_ EV_IO, wl);
-
- wl = wn;
- }
-
- if (types & (EV_TIMER | EV_STAT))
- for (i = timercnt + HEAP0; i-- > HEAP0; )
-#if EV_STAT_ENABLE
- /*TODO: timer is not always active*/
- if (ev_cb ((ev_timer *)ANHE_w (timers [i])) == stat_timer_cb)
- {
- if (types & EV_STAT)
- cb (EV_A_ EV_STAT, ((char *)ANHE_w (timers [i])) - offsetof (struct ev_stat, timer));
- }
- else
-#endif
- if (types & EV_TIMER)
- cb (EV_A_ EV_TIMER, ANHE_w (timers [i]));
-
-#if EV_PERIODIC_ENABLE
- if (types & EV_PERIODIC)
- for (i = periodiccnt + HEAP0; i-- > HEAP0; )
- cb (EV_A_ EV_PERIODIC, ANHE_w (periodics [i]));
-#endif
-
-#if EV_IDLE_ENABLE
- if (types & EV_IDLE)
- for (j = NUMPRI; j--; )
- for (i = idlecnt [j]; i--; )
- cb (EV_A_ EV_IDLE, idles [j][i]);
-#endif
-
-#if EV_FORK_ENABLE
- if (types & EV_FORK)
- for (i = forkcnt; i--; )
- if (ev_cb (forks [i]) != embed_fork_cb)
- cb (EV_A_ EV_FORK, forks [i]);
-#endif
-
-#if EV_ASYNC_ENABLE
- if (types & EV_ASYNC)
- for (i = asynccnt; i--; )
- cb (EV_A_ EV_ASYNC, asyncs [i]);
-#endif
-
-#if EV_PREPARE_ENABLE
- if (types & EV_PREPARE)
- for (i = preparecnt; i--; )
-# if EV_EMBED_ENABLE
- if (ev_cb (prepares [i]) != embed_prepare_cb)
-# endif
- cb (EV_A_ EV_PREPARE, prepares [i]);
-#endif
-
-#if EV_CHECK_ENABLE
- if (types & EV_CHECK)
- for (i = checkcnt; i--; )
- cb (EV_A_ EV_CHECK, checks [i]);
-#endif
-
-#if EV_SIGNAL_ENABLE
- if (types & EV_SIGNAL)
- for (i = 0; i < EV_NSIG - 1; ++i)
- for (wl = signals [i].head; wl; )
- {
- wn = wl->next;
- cb (EV_A_ EV_SIGNAL, wl);
- wl = wn;
- }
-#endif
-
-#if EV_CHILD_ENABLE
- if (types & EV_CHILD)
- for (i = (EV_PID_HASHSIZE); i--; )
- for (wl = childs [i]; wl; )
- {
- wn = wl->next;
- cb (EV_A_ EV_CHILD, wl);
- wl = wn;
- }
-#endif
-/* EV_STAT 0x00001000 /* stat data changed */
-/* EV_EMBED 0x00010000 /* embedded event loop needs sweep */
-}
-#endif
-
-#if EV_MULTIPLICITY
- #include "ev_wrap.h"
-#endif
-
-EV_CPP(})
-
diff --git a/deps/uv/src/unix/ev/ev.pod b/deps/uv/src/unix/ev/ev.pod
deleted file mode 100644
index 4bbef1fcf..000000000
--- a/deps/uv/src/unix/ev/ev.pod
+++ /dev/null
@@ -1,5243 +0,0 @@
-=head1 NAME
-
-libev - a high performance full-featured event loop written in C
-
-=head1 SYNOPSIS
-
- #include <ev.h>
-
-=head2 EXAMPLE PROGRAM
-
- // a single header file is required
- #include <ev.h>
-
- #include <stdio.h> // for puts
-
- // every watcher type has its own typedef'd struct
- // with the name ev_TYPE
- ev_io stdin_watcher;
- ev_timer timeout_watcher;
-
- // all watcher callbacks have a similar signature
- // this callback is called when data is readable on stdin
- static void
- stdin_cb (EV_P_ ev_io *w, int revents)
- {
- puts ("stdin ready");
- // for one-shot events, one must manually stop the watcher
- // with its corresponding stop function.
- ev_io_stop (EV_A_ w);
-
- // this causes all nested ev_run's to stop iterating
- ev_break (EV_A_ EVBREAK_ALL);
- }
-
- // another callback, this time for a time-out
- static void
- timeout_cb (EV_P_ ev_timer *w, int revents)
- {
- puts ("timeout");
- // this causes the innermost ev_run to stop iterating
- ev_break (EV_A_ EVBREAK_ONE);
- }
-
- int
- main (void)
- {
- // use the default event loop unless you have special needs
- struct ev_loop *loop = EV_DEFAULT;
-
- // initialise an io watcher, then start it
- // this one will watch for stdin to become readable
- ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
- ev_io_start (loop, &stdin_watcher);
-
- // initialise a timer watcher, then start it
- // simple non-repeating 5.5 second timeout
- ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
- ev_timer_start (loop, &timeout_watcher);
-
- // now wait for events to arrive
- ev_run (loop, 0);
-
- // break was called, so exit
- return 0;
- }
-
-=head1 ABOUT THIS DOCUMENT
-
-This document documents the libev software package.
-
-The newest version of this document is also available as an html-formatted
-web page you might find easier to navigate when reading it for the first
-time: L<http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod>.
-
-While this document tries to be as complete as possible in documenting
-libev, its usage and the rationale behind its design, it is not a tutorial
-on event-based programming, nor will it introduce event-based programming
-with libev.
-
-Familiarity with event based programming techniques in general is assumed
-throughout this document.
-
-=head1 WHAT TO READ WHEN IN A HURRY
-
-This manual tries to be very detailed, but unfortunately, this also makes
-it very long. If you just want to know the basics of libev, I suggest
-reading L<ANATOMY OF A WATCHER>, then the L<EXAMPLE PROGRAM> above and
-look up the missing functions in L<GLOBAL FUNCTIONS> and the C<ev_io> and
-C<ev_timer> sections in L<WATCHER TYPES>.
-
-=head1 ABOUT LIBEV
-
-Libev is an event loop: you register interest in certain events (such as a
-file descriptor being readable or a timeout occurring), and it will manage
-these event sources and provide your program with events.
-
-To do this, it must take more or less complete control over your process
-(or thread) by executing the I<event loop> handler, and will then
-communicate events via a callback mechanism.
-
-You register interest in certain events by registering so-called I<event
-watchers>, which are relatively small C structures you initialise with the
-details of the event, and then hand it over to libev by I<starting> the
-watcher.
-
-=head2 FEATURES
-
-Libev supports C<select>, C<poll>, the Linux-specific C<epoll>, the
-BSD-specific C<kqueue> and the Solaris-specific event port mechanisms
-for file descriptor events (C<ev_io>), the Linux C<inotify> interface
-(for C<ev_stat>), Linux eventfd/signalfd (for faster and cleaner
-inter-thread wakeup (C<ev_async>)/signal handling (C<ev_signal>)) relative
-timers (C<ev_timer>), absolute timers with customised rescheduling
-(C<ev_periodic>), synchronous signals (C<ev_signal>), process status
-change events (C<ev_child>), and event watchers dealing with the event
-loop mechanism itself (C<ev_idle>, C<ev_embed>, C<ev_prepare> and
-C<ev_check> watchers) as well as file watchers (C<ev_stat>) and even
-limited support for fork events (C<ev_fork>).
-
-It also is quite fast (see this
-L<benchmark|http://libev.schmorp.de/bench.html> comparing it to libevent
-for example).
-
-=head2 CONVENTIONS
-
-Libev is very configurable. In this manual the default (and most common)
-configuration will be described, which supports multiple event loops. For
-more info about various configuration options please have a look at
-B<EMBED> section in this manual. If libev was configured without support
-for multiple event loops, then all functions taking an initial argument of
-name C<loop> (which is always of type C<struct ev_loop *>) will not have
-this argument.
-
-=head2 TIME REPRESENTATION
-
-Libev represents time as a single floating point number, representing
-the (fractional) number of seconds since the (POSIX) epoch (in practice
-somewhere near the beginning of 1970, details are complicated, don't
-ask). This type is called C<ev_tstamp>, which is what you should use
-too. It usually aliases to the C<double> type in C. When you need to do
-any calculations on it, you should treat it as some floating point value.
-
-Unlike the name component C<stamp> might indicate, it is also used for
-time differences (e.g. delays) throughout libev.
-
-=head1 ERROR HANDLING
-
-Libev knows three classes of errors: operating system errors, usage errors
-and internal errors (bugs).
-
-When libev catches an operating system error it cannot handle (for example
-a system call indicating a condition libev cannot fix), it calls the callback
-set via C<ev_set_syserr_cb>, which is supposed to fix the problem or
-abort. The default is to print a diagnostic message and to call C<abort
-()>.
-
-When libev detects a usage error such as a negative timer interval, then
-it will print a diagnostic message and abort (via the C<assert> mechanism,
-so C<NDEBUG> will disable this checking): these are programming errors in
-the libev caller and need to be fixed there.
-
-Libev also has a few internal error-checking C<assert>ions, and also has
-extensive consistency checking code. These do not trigger under normal
-circumstances, as they indicate either a bug in libev or worse.
-
-
-=head1 GLOBAL FUNCTIONS
-
-These functions can be called anytime, even before initialising the
-library in any way.
-
-=over 4
-
-=item ev_tstamp ev_time ()
-
-Returns the current time as libev would use it. Please note that the
-C<ev_now> function is usually faster and also often returns the timestamp
-you actually want to know. Also interesting is the combination of
-C<ev_update_now> and C<ev_now>.
-
-=item ev_sleep (ev_tstamp interval)
-
-Sleep for the given interval: The current thread will be blocked until
-either it is interrupted or the given time interval has passed. Basically
-this is a sub-second-resolution C<sleep ()>.
-
-=item int ev_version_major ()
-
-=item int ev_version_minor ()
-
-You can find out the major and minor ABI version numbers of the library
-you linked against by calling the functions C<ev_version_major> and
-C<ev_version_minor>. If you want, you can compare against the global
-symbols C<EV_VERSION_MAJOR> and C<EV_VERSION_MINOR>, which specify the
-version of the library your program was compiled against.
-
-These version numbers refer to the ABI version of the library, not the
-release version.
-
-Usually, it's a good idea to terminate if the major versions mismatch,
-as this indicates an incompatible change. Minor versions are usually
-compatible to older versions, so a larger minor version alone is usually
-not a problem.
-
-Example: Make sure we haven't accidentally been linked against the wrong
-version (note, however, that this will not detect other ABI mismatches,
-such as LFS or reentrancy).
-
- assert (("libev version mismatch",
- ev_version_major () == EV_VERSION_MAJOR
- && ev_version_minor () >= EV_VERSION_MINOR));
-
-=item unsigned int ev_supported_backends ()
-
-Return the set of all backends (i.e. their corresponding C<EV_BACKEND_*>
-value) compiled into this binary of libev (independent of their
-availability on the system you are running on). See C<ev_default_loop> for
-a description of the set values.
-
-Example: make sure we have the epoll method, because yeah this is cool and
-a must have and can we have a torrent of it please!!!11
-
- assert (("sorry, no epoll, no sex",
- ev_supported_backends () & EVBACKEND_EPOLL));
-
-=item unsigned int ev_recommended_backends ()
-
-Return the set of all backends compiled into this binary of libev and
-also recommended for this platform, meaning it will work for most file
-descriptor types. This set is often smaller than the one returned by
-C<ev_supported_backends>, as for example kqueue is broken on most BSDs
-and will not be auto-detected unless you explicitly request it (assuming
-you know what you are doing). This is the set of backends that libev will
-probe for if you specify no backends explicitly.
-
-=item unsigned int ev_embeddable_backends ()
-
-Returns the set of backends that are embeddable in other event loops. This
-value is platform-specific but can include backends not available on the
-current system. To find which embeddable backends might be supported on
-the current system, you would need to look at C<ev_embeddable_backends ()
-& ev_supported_backends ()>, likewise for recommended ones.
-
-See the description of C<ev_embed> watchers for more info.
-
-=item ev_set_allocator (void *(*cb)(void *ptr, long size))
-
-Sets the allocation function to use (the prototype is similar - the
-semantics are identical to the C<realloc> C89/SuS/POSIX function). It is
-used to allocate and free memory (no surprises here). If it returns zero
-when memory needs to be allocated (C<size != 0>), the library might abort
-or take some potentially destructive action.
-
-Since some systems (at least OpenBSD and Darwin) fail to implement
-correct C<realloc> semantics, libev will use a wrapper around the system
-C<realloc> and C<free> functions by default.
-
-You could override this function in high-availability programs to, say,
-free some memory if it cannot allocate memory, to use a special allocator,
-or even to sleep a while and retry until some memory is available.
-
-Example: Replace the libev allocator with one that waits a bit and then
-retries (example requires a standards-compliant C<realloc>).
-
- static void *
- persistent_realloc (void *ptr, size_t size)
- {
- for (;;)
- {
- void *newptr = realloc (ptr, size);
-
- if (newptr)
- return newptr;
-
- sleep (60);
- }
- }
-
- ...
- ev_set_allocator (persistent_realloc);
-
-=item ev_set_syserr_cb (void (*cb)(const char *msg))
-
-Set the callback function to call on a retryable system call error (such
-as failed select, poll, epoll_wait). The message is a printable string
-indicating the system call or subsystem causing the problem. If this
-callback is set, then libev will expect it to remedy the situation, no
-matter what, when it returns. That is, libev will generally retry the
-requested operation, or, if the condition doesn't go away, do bad stuff
-(such as abort).
-
-Example: This is basically the same thing that libev does internally, too.
-
- static void
- fatal_error (const char *msg)
- {
- perror (msg);
- abort ();
- }
-
- ...
- ev_set_syserr_cb (fatal_error);
-
-=item ev_feed_signal (int signum)
-
-This function can be used to "simulate" a signal receive. It is completely
-safe to call this function at any time, from any context, including signal
-handlers or random threads.
-
-Its main use is to customise signal handling in your process, especially
-in the presence of threads. For example, you could block signals
-by default in all threads (and specifying C<EVFLAG_NOSIGMASK> when
-creating any loops), and in one thread, use C<sigwait> or any other
-mechanism to wait for signals, then "deliver" them to libev by calling
-C<ev_feed_signal>.
-
-=back
-
-=head1 FUNCTIONS CONTROLLING EVENT LOOPS
-
-An event loop is described by a C<struct ev_loop *> (the C<struct> is
-I<not> optional in this case unless libev 3 compatibility is disabled, as
-libev 3 had an C<ev_loop> function colliding with the struct name).
-
-The library knows two types of such loops, the I<default> loop, which
-supports child process events, and dynamically created event loops which
-do not.
-
-=over 4
-
-=item struct ev_loop *ev_default_loop (unsigned int flags)
-
-This returns the "default" event loop object, which is what you should
-normally use when you just need "the event loop". Event loop objects and
-the C<flags> parameter are described in more detail in the entry for
-C<ev_loop_new>.
-
-If the default loop is already initialised then this function simply
-returns it (and ignores the flags. If that is troubling you, check
-C<ev_backend ()> afterwards). Otherwise it will create it with the given
-flags, which should almost always be C<0>, unless the caller is also the
-one calling C<ev_run> or otherwise qualifies as "the main program".
-
-If you don't know what event loop to use, use the one returned from this
-function (or via the C<EV_DEFAULT> macro).
-
-Note that this function is I<not> thread-safe, so if you want to use it
-from multiple threads, you have to employ some kind of mutex (note also
-that this case is unlikely, as loops cannot be shared easily between
-threads anyway).
-
-The default loop is the only loop that can handle C<ev_child> watchers,
-and to do this, it always registers a handler for C<SIGCHLD>. If this is
-a problem for your application you can either create a dynamic loop with
-C<ev_loop_new> which doesn't do that, or you can simply overwrite the
-C<SIGCHLD> signal handler I<after> calling C<ev_default_init>.
-
-Example: This is the most typical usage.
-
- if (!ev_default_loop (0))
- fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?");
-
-Example: Restrict libev to the select and poll backends, and do not allow
-environment settings to be taken into account:
-
- ev_default_loop (EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV);
-
-=item struct ev_loop *ev_loop_new (unsigned int flags)
-
-This will create and initialise a new event loop object. If the loop
-could not be initialised, returns false.
-
-This function is thread-safe, and one common way to use libev with
-threads is indeed to create one loop per thread, and using the default
-loop in the "main" or "initial" thread.
-
-The flags argument can be used to specify special behaviour or specific
-backends to use, and is usually specified as C<0> (or C<EVFLAG_AUTO>).
-
-The following flags are supported:
-
-=over 4
-
-=item C<EVFLAG_AUTO>
-
-The default flags value. Use this if you have no clue (it's the right
-thing, believe me).
-
-=item C<EVFLAG_NOENV>
-
-If this flag bit is or'ed into the flag value (or the program runs setuid
-or setgid) then libev will I<not> look at the environment variable
-C<LIBEV_FLAGS>. Otherwise (the default), this environment variable will
-override the flags completely if it is found in the environment. This is
-useful to try out specific backends to test their performance, or to work
-around bugs.
-
-=item C<EVFLAG_FORKCHECK>
-
-Instead of calling C<ev_loop_fork> manually after a fork, you can also
-make libev check for a fork in each iteration by enabling this flag.
-
-This works by calling C<getpid ()> on every iteration of the loop,
-and thus this might slow down your event loop if you do a lot of loop
-iterations and little real work, but is usually not noticeable (on my
-GNU/Linux system for example, C<getpid> is actually a simple 5-insn sequence
-without a system call and thus I<very> fast, but my GNU/Linux system also has
-C<pthread_atfork> which is even faster).
-
-The big advantage of this flag is that you can forget about fork (and
-forget about forgetting to tell libev about forking) when you use this
-flag.
-
-This flag setting cannot be overridden or specified in the C<LIBEV_FLAGS>
-environment variable.
-
-=item C<EVFLAG_NOINOTIFY>
-
-When this flag is specified, then libev will not attempt to use the
-I<inotify> API for its C<ev_stat> watchers. Apart from debugging and
-testing, this flag can be useful to conserve inotify file descriptors, as
-otherwise each loop using C<ev_stat> watchers consumes one inotify handle.
-
-=item C<EVFLAG_SIGNALFD>
-
-When this flag is specified, then libev will attempt to use the
-I<signalfd> API for its C<ev_signal> (and C<ev_child>) watchers. This API
-delivers signals synchronously, which makes it both faster and might make
-it possible to get the queued signal data. It can also simplify signal
-handling with threads, as long as you properly block signals in your
-threads that are not interested in handling them.
-
-Signalfd will not be used by default as this changes your signal mask, and
-there are a lot of shoddy libraries and programs (glib's threadpool for
-example) that can't properly initialise their signal masks.
-
-=item C<EVFLAG_NOSIGMASK>
-
-When this flag is specified, then libev will avoid to modify the signal
-mask. Specifically, this means you ahve to make sure signals are unblocked
-when you want to receive them.
-
-This behaviour is useful when you want to do your own signal handling, or
-want to handle signals only in specific threads and want to avoid libev
-unblocking the signals.
-
-It's also required by POSIX in a threaded program, as libev calls
-C<sigprocmask>, whose behaviour is officially unspecified.
-
-This flag's behaviour will become the default in future versions of libev.
-
-=item C<EVBACKEND_SELECT> (value 1, portable select backend)
-
-This is your standard select(2) backend. Not I<completely> standard, as
-libev tries to roll its own fd_set with no limits on the number of fds,
-but if that fails, expect a fairly low limit on the number of fds when
-using this backend. It doesn't scale too well (O(highest_fd)), but its
-usually the fastest backend for a low number of (low-numbered :) fds.
-
-To get good performance out of this backend you need a high amount of
-parallelism (most of the file descriptors should be busy). If you are
-writing a server, you should C<accept ()> in a loop to accept as many
-connections as possible during one iteration. You might also want to have
-a look at C<ev_set_io_collect_interval ()> to increase the amount of
-readiness notifications you get per iteration.
-
-This backend maps C<EV_READ> to the C<readfds> set and C<EV_WRITE> to the
-C<writefds> set (and to work around Microsoft Windows bugs, also onto the
-C<exceptfds> set on that platform).
-
-=item C<EVBACKEND_POLL> (value 2, poll backend, available everywhere except on windows)
-
-And this is your standard poll(2) backend. It's more complicated
-than select, but handles sparse fds better and has no artificial
-limit on the number of fds you can use (except it will slow down
-considerably with a lot of inactive fds). It scales similarly to select,
-i.e. O(total_fds). See the entry for C<EVBACKEND_SELECT>, above, for
-performance tips.
-
-This backend maps C<EV_READ> to C<POLLIN | POLLERR | POLLHUP>, and
-C<EV_WRITE> to C<POLLOUT | POLLERR | POLLHUP>.
-
-=item C<EVBACKEND_EPOLL> (value 4, Linux)
-
-Use the linux-specific epoll(7) interface (for both pre- and post-2.6.9
-kernels).
-
-For few fds, this backend is a bit little slower than poll and select,
-but it scales phenomenally better. While poll and select usually scale
-like O(total_fds) where n is the total number of fds (or the highest fd),
-epoll scales either O(1) or O(active_fds).
-
-The epoll mechanism deserves honorable mention as the most misdesigned
-of the more advanced event mechanisms: mere annoyances include silently
-dropping file descriptors, requiring a system call per change per file
-descriptor (and unnecessary guessing of parameters), problems with dup,
-returning before the timeout value, resulting in additional iterations
-(and only giving 5ms accuracy while select on the same platform gives
-0.1ms) and so on. The biggest issue is fork races, however - if a program
-forks then I<both> parent and child process have to recreate the epoll
-set, which can take considerable time (one syscall per file descriptor)
-and is of course hard to detect.
-
-Epoll is also notoriously buggy - embedding epoll fds I<should> work, but
-of course I<doesn't>, and epoll just loves to report events for totally
-I<different> file descriptors (even already closed ones, so one cannot
-even remove them from the set) than registered in the set (especially
-on SMP systems). Libev tries to counter these spurious notifications by
-employing an additional generation counter and comparing that against the
-events to filter out spurious ones, recreating the set when required. Last
-not least, it also refuses to work with some file descriptors which work
-perfectly fine with C<select> (files, many character devices...).
-
-Epoll is truly the train wreck analog among event poll mechanisms,
-a frankenpoll, cobbled together in a hurry, no thought to design or
-interaction with others.
-
-While stopping, setting and starting an I/O watcher in the same iteration
-will result in some caching, there is still a system call per such
-incident (because the same I<file descriptor> could point to a different
-I<file description> now), so its best to avoid that. Also, C<dup ()>'ed
-file descriptors might not work very well if you register events for both
-file descriptors.
-
-Best performance from this backend is achieved by not unregistering all
-watchers for a file descriptor until it has been closed, if possible,
-i.e. keep at least one watcher active per fd at all times. Stopping and
-starting a watcher (without re-setting it) also usually doesn't cause
-extra overhead. A fork can both result in spurious notifications as well
-as in libev having to destroy and recreate the epoll object, which can
-take considerable time and thus should be avoided.
-
-All this means that, in practice, C<EVBACKEND_SELECT> can be as fast or
-faster than epoll for maybe up to a hundred file descriptors, depending on
-the usage. So sad.
-
-While nominally embeddable in other event loops, this feature is broken in
-all kernel versions tested so far.
-
-This backend maps C<EV_READ> and C<EV_WRITE> in the same way as
-C<EVBACKEND_POLL>.
-
-=item C<EVBACKEND_KQUEUE> (value 8, most BSD clones)
-
-Kqueue deserves special mention, as at the time of this writing, it
-was broken on all BSDs except NetBSD (usually it doesn't work reliably
-with anything but sockets and pipes, except on Darwin, where of course
-it's completely useless). Unlike epoll, however, whose brokenness
-is by design, these kqueue bugs can (and eventually will) be fixed
-without API changes to existing programs. For this reason it's not being
-"auto-detected" unless you explicitly specify it in the flags (i.e. using
-C<EVBACKEND_KQUEUE>) or libev was compiled on a known-to-be-good (-enough)
-system like NetBSD.
-
-You still can embed kqueue into a normal poll or select backend and use it
-only for sockets (after having made sure that sockets work with kqueue on
-the target platform). See C<ev_embed> watchers for more info.
-
-It scales in the same way as the epoll backend, but the interface to the
-kernel is more efficient (which says nothing about its actual speed, of
-course). While stopping, setting and starting an I/O watcher does never
-cause an extra system call as with C<EVBACKEND_EPOLL>, it still adds up to
-two event changes per incident. Support for C<fork ()> is very bad (but
-sane, unlike epoll) and it drops fds silently in similarly hard-to-detect
-cases
-
-This backend usually performs well under most conditions.
-
-While nominally embeddable in other event loops, this doesn't work
-everywhere, so you might need to test for this. And since it is broken
-almost everywhere, you should only use it when you have a lot of sockets
-(for which it usually works), by embedding it into another event loop
-(e.g. C<EVBACKEND_SELECT> or C<EVBACKEND_POLL> (but C<poll> is of course
-also broken on OS X)) and, did I mention it, using it only for sockets.
-
-This backend maps C<EV_READ> into an C<EVFILT_READ> kevent with
-C<NOTE_EOF>, and C<EV_WRITE> into an C<EVFILT_WRITE> kevent with
-C<NOTE_EOF>.
-
-=item C<EVBACKEND_DEVPOLL> (value 16, Solaris 8)
-
-This is not implemented yet (and might never be, unless you send me an
-implementation). According to reports, C</dev/poll> only supports sockets
-and is not embeddable, which would limit the usefulness of this backend
-immensely.
-
-=item C<EVBACKEND_PORT> (value 32, Solaris 10)
-
-This uses the Solaris 10 event port mechanism. As with everything on Solaris,
-it's really slow, but it still scales very well (O(active_fds)).
-
-While this backend scales well, it requires one system call per active
-file descriptor per loop iteration. For small and medium numbers of file
-descriptors a "slow" C<EVBACKEND_SELECT> or C<EVBACKEND_POLL> backend
-might perform better.
-
-On the positive side, this backend actually performed fully to
-specification in all tests and is fully embeddable, which is a rare feat
-among the OS-specific backends (I vastly prefer correctness over speed
-hacks).
-
-On the negative side, the interface is I<bizarre> - so bizarre that
-even sun itself gets it wrong in their code examples: The event polling
-function sometimes returning events to the caller even though an error
-occurred, but with no indication whether it has done so or not (yes, it's
-even documented that way) - deadly for edge-triggered interfaces where
-you absolutely have to know whether an event occurred or not because you
-have to re-arm the watcher.
-
-Fortunately libev seems to be able to work around these idiocies.
-
-This backend maps C<EV_READ> and C<EV_WRITE> in the same way as
-C<EVBACKEND_POLL>.
-
-=item C<EVBACKEND_ALL>
-
-Try all backends (even potentially broken ones that wouldn't be tried
-with C<EVFLAG_AUTO>). Since this is a mask, you can do stuff such as
-C<EVBACKEND_ALL & ~EVBACKEND_KQUEUE>.
-
-It is definitely not recommended to use this flag, use whatever
-C<ev_recommended_backends ()> returns, or simply do not specify a backend
-at all.
-
-=item C<EVBACKEND_MASK>
-
-Not a backend at all, but a mask to select all backend bits from a
-C<flags> value, in case you want to mask out any backends from a flags
-value (e.g. when modifying the C<LIBEV_FLAGS> environment variable).
-
-=back
-
-If one or more of the backend flags are or'ed into the flags value,
-then only these backends will be tried (in the reverse order as listed
-here). If none are specified, all backends in C<ev_recommended_backends
-()> will be tried.
-
-Example: Try to create a event loop that uses epoll and nothing else.
-
- struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV);
- if (!epoller)
- fatal ("no epoll found here, maybe it hides under your chair");
-
-Example: Use whatever libev has to offer, but make sure that kqueue is
-used if available.
-
- struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_KQUEUE);
-
-=item ev_loop_destroy (loop)
-
-Destroys an event loop object (frees all memory and kernel state
-etc.). None of the active event watchers will be stopped in the normal
-sense, so e.g. C<ev_is_active> might still return true. It is your
-responsibility to either stop all watchers cleanly yourself I<before>
-calling this function, or cope with the fact afterwards (which is usually
-the easiest thing, you can just ignore the watchers and/or C<free ()> them
-for example).
-
-Note that certain global state, such as signal state (and installed signal
-handlers), will not be freed by this function, and related watchers (such
-as signal and child watchers) would need to be stopped manually.
-
-This function is normally used on loop objects allocated by
-C<ev_loop_new>, but it can also be used on the default loop returned by
-C<ev_default_loop>, in which case it is not thread-safe.
-
-Note that it is not advisable to call this function on the default loop
-except in the rare occasion where you really need to free its resources.
-If you need dynamically allocated loops it is better to use C<ev_loop_new>
-and C<ev_loop_destroy>.
-
-=item ev_loop_fork (loop)
-
-This function sets a flag that causes subsequent C<ev_run> iterations to
-reinitialise the kernel state for backends that have one. Despite the
-name, you can call it anytime, but it makes most sense after forking, in
-the child process. You I<must> call it (or use C<EVFLAG_FORKCHECK>) in the
-child before resuming or calling C<ev_run>.
-
-Again, you I<have> to call it on I<any> loop that you want to re-use after
-a fork, I<even if you do not plan to use the loop in the parent>. This is
-because some kernel interfaces *cough* I<kqueue> *cough* do funny things
-during fork.
-
-On the other hand, you only need to call this function in the child
-process if and only if you want to use the event loop in the child. If
-you just fork+exec or create a new loop in the child, you don't have to
-call it at all (in fact, C<epoll> is so badly broken that it makes a
-difference, but libev will usually detect this case on its own and do a
-costly reset of the backend).
-
-The function itself is quite fast and it's usually not a problem to call
-it just in case after a fork.
-
-Example: Automate calling C<ev_loop_fork> on the default loop when
-using pthreads.
-
- static void
- post_fork_child (void)
- {
- ev_loop_fork (EV_DEFAULT);
- }
-
- ...
- pthread_atfork (0, 0, post_fork_child);
-
-=item int ev_is_default_loop (loop)
-
-Returns true when the given loop is, in fact, the default loop, and false
-otherwise.
-
-=item unsigned int ev_iteration (loop)
-
-Returns the current iteration count for the event loop, which is identical
-to the number of times libev did poll for new events. It starts at C<0>
-and happily wraps around with enough iterations.
-
-This value can sometimes be useful as a generation counter of sorts (it
-"ticks" the number of loop iterations), as it roughly corresponds with
-C<ev_prepare> and C<ev_check> calls - and is incremented between the
-prepare and check phases.
-
-=item unsigned int ev_depth (loop)
-
-Returns the number of times C<ev_run> was entered minus the number of
-times C<ev_run> was exited normally, in other words, the recursion depth.
-
-Outside C<ev_run>, this number is zero. In a callback, this number is
-C<1>, unless C<ev_run> was invoked recursively (or from another thread),
-in which case it is higher.
-
-Leaving C<ev_run> abnormally (setjmp/longjmp, cancelling the thread,
-throwing an exception etc.), doesn't count as "exit" - consider this
-as a hint to avoid such ungentleman-like behaviour unless it's really
-convenient, in which case it is fully supported.
-
-=item unsigned int ev_backend (loop)
-
-Returns one of the C<EVBACKEND_*> flags indicating the event backend in
-use.
-
-=item ev_tstamp ev_now (loop)
-
-Returns the current "event loop time", which is the time the event loop
-received events and started processing them. This timestamp does not
-change as long as callbacks are being processed, and this is also the base
-time used for relative timers. You can treat it as the timestamp of the
-event occurring (or more correctly, libev finding out about it).
-
-=item ev_now_update (loop)
-
-Establishes the current time by querying the kernel, updating the time
-returned by C<ev_now ()> in the progress. This is a costly operation and
-is usually done automatically within C<ev_run ()>.
-
-This function is rarely useful, but when some event callback runs for a
-very long time without entering the event loop, updating libev's idea of
-the current time is a good idea.
-
-See also L<The special problem of time updates> in the C<ev_timer> section.
-
-=item ev_suspend (loop)
-
-=item ev_resume (loop)
-
-These two functions suspend and resume an event loop, for use when the
-loop is not used for a while and timeouts should not be processed.
-
-A typical use case would be an interactive program such as a game: When
-the user presses C<^Z> to suspend the game and resumes it an hour later it
-would be best to handle timeouts as if no time had actually passed while
-the program was suspended. This can be achieved by calling C<ev_suspend>
-in your C<SIGTSTP> handler, sending yourself a C<SIGSTOP> and calling
-C<ev_resume> directly afterwards to resume timer processing.
-
-Effectively, all C<ev_timer> watchers will be delayed by the time spend
-between C<ev_suspend> and C<ev_resume>, and all C<ev_periodic> watchers
-will be rescheduled (that is, they will lose any events that would have
-occurred while suspended).
-
-After calling C<ev_suspend> you B<must not> call I<any> function on the
-given loop other than C<ev_resume>, and you B<must not> call C<ev_resume>
-without a previous call to C<ev_suspend>.
-
-Calling C<ev_suspend>/C<ev_resume> has the side effect of updating the
-event loop time (see C<ev_now_update>).
-
-=item ev_run (loop, int flags)
-
-Finally, this is it, the event handler. This function usually is called
-after you have initialised all your watchers and you want to start
-handling events. It will ask the operating system for any new events, call
-the watcher callbacks, an then repeat the whole process indefinitely: This
-is why event loops are called I<loops>.
-
-If the flags argument is specified as C<0>, it will keep handling events
-until either no event watchers are active anymore or C<ev_break> was
-called.
-
-Please note that an explicit C<ev_break> is usually better than
-relying on all watchers to be stopped when deciding when a program has
-finished (especially in interactive programs), but having a program
-that automatically loops as long as it has to and no longer by virtue
-of relying on its watchers stopping correctly, that is truly a thing of
-beauty.
-
-This function is also I<mostly> exception-safe - you can break out of
-a C<ev_run> call by calling C<longjmp> in a callback, throwing a C++
-exception and so on. This does not decrement the C<ev_depth> value, nor
-will it clear any outstanding C<EVBREAK_ONE> breaks.
-
-A flags value of C<EVRUN_NOWAIT> will look for new events, will handle
-those events and any already outstanding ones, but will not wait and
-block your process in case there are no events and will return after one
-iteration of the loop. This is sometimes useful to poll and handle new
-events while doing lengthy calculations, to keep the program responsive.
-
-A flags value of C<EVRUN_ONCE> will look for new events (waiting if
-necessary) and will handle those and any already outstanding ones. It
-will block your process until at least one new event arrives (which could
-be an event internal to libev itself, so there is no guarantee that a
-user-registered callback will be called), and will return after one
-iteration of the loop.
-
-This is useful if you are waiting for some external event in conjunction
-with something not expressible using other libev watchers (i.e. "roll your
-own C<ev_run>"). However, a pair of C<ev_prepare>/C<ev_check> watchers is
-usually a better approach for this kind of thing.
-
-Here are the gory details of what C<ev_run> does:
-
- - Increment loop depth.
- - Reset the ev_break status.
- - Before the first iteration, call any pending watchers.
- LOOP:
- - If EVFLAG_FORKCHECK was used, check for a fork.
- - If a fork was detected (by any means), queue and call all fork watchers.
- - Queue and call all prepare watchers.
- - If ev_break was called, goto FINISH.
- - If we have been forked, detach and recreate the kernel state
- as to not disturb the other process.
- - Update the kernel state with all outstanding changes.
- - Update the "event loop time" (ev_now ()).
- - Calculate for how long to sleep or block, if at all
- (active idle watchers, EVRUN_NOWAIT or not having
- any active watchers at all will result in not sleeping).
- - Sleep if the I/O and timer collect interval say so.
- - Increment loop iteration counter.
- - Block the process, waiting for any events.
- - Queue all outstanding I/O (fd) events.
- - Update the "event loop time" (ev_now ()), and do time jump adjustments.
- - Queue all expired timers.
- - Queue all expired periodics.
- - Queue all idle watchers with priority higher than that of pending events.
- - Queue all check watchers.
- - Call all queued watchers in reverse order (i.e. check watchers first).
- Signals and child watchers are implemented as I/O watchers, and will
- be handled here by queueing them when their watcher gets executed.
- - If ev_break has been called, or EVRUN_ONCE or EVRUN_NOWAIT
- were used, or there are no active watchers, goto FINISH, otherwise
- continue with step LOOP.
- FINISH:
- - Reset the ev_break status iff it was EVBREAK_ONE.
- - Decrement the loop depth.
- - Return.
-
-Example: Queue some jobs and then loop until no events are outstanding
-anymore.
-
- ... queue jobs here, make sure they register event watchers as long
- ... as they still have work to do (even an idle watcher will do..)
- ev_run (my_loop, 0);
- ... jobs done or somebody called break. yeah!
-
-=item ev_break (loop, how)
-
-Can be used to make a call to C<ev_run> return early (but only after it
-has processed all outstanding events). The C<how> argument must be either
-C<EVBREAK_ONE>, which will make the innermost C<ev_run> call return, or
-C<EVBREAK_ALL>, which will make all nested C<ev_run> calls return.
-
-This "break state" will be cleared on the next call to C<ev_run>.
-
-It is safe to call C<ev_break> from outside any C<ev_run> calls, too, in
-which case it will have no effect.
-
-=item ev_ref (loop)
-
-=item ev_unref (loop)
-
-Ref/unref can be used to add or remove a reference count on the event
-loop: Every watcher keeps one reference, and as long as the reference
-count is nonzero, C<ev_run> will not return on its own.
-
-This is useful when you have a watcher that you never intend to
-unregister, but that nevertheless should not keep C<ev_run> from
-returning. In such a case, call C<ev_unref> after starting, and C<ev_ref>
-before stopping it.
-
-As an example, libev itself uses this for its internal signal pipe: It
-is not visible to the libev user and should not keep C<ev_run> from
-exiting if no event watchers registered by it are active. It is also an
-excellent way to do this for generic recurring timers or from within
-third-party libraries. Just remember to I<unref after start> and I<ref
-before stop> (but only if the watcher wasn't active before, or was active
-before, respectively. Note also that libev might stop watchers itself
-(e.g. non-repeating timers) in which case you have to C<ev_ref>
-in the callback).
-
-Example: Create a signal watcher, but keep it from keeping C<ev_run>
-running when nothing else is active.
-
- ev_signal exitsig;
- ev_signal_init (&exitsig, sig_cb, SIGINT);
- ev_signal_start (loop, &exitsig);
- ev_unref (loop);
-
-Example: For some weird reason, unregister the above signal handler again.
-
- ev_ref (loop);
- ev_signal_stop (loop, &exitsig);
-
-=item ev_set_io_collect_interval (loop, ev_tstamp interval)
-
-=item ev_set_timeout_collect_interval (loop, ev_tstamp interval)
-
-These advanced functions influence the time that libev will spend waiting
-for events. Both time intervals are by default C<0>, meaning that libev
-will try to invoke timer/periodic callbacks and I/O callbacks with minimum
-latency.
-
-Setting these to a higher value (the C<interval> I<must> be >= C<0>)
-allows libev to delay invocation of I/O and timer/periodic callbacks
-to increase efficiency of loop iterations (or to increase power-saving
-opportunities).
-
-The idea is that sometimes your program runs just fast enough to handle
-one (or very few) event(s) per loop iteration. While this makes the
-program responsive, it also wastes a lot of CPU time to poll for new
-events, especially with backends like C<select ()> which have a high
-overhead for the actual polling but can deliver many events at once.
-
-By setting a higher I<io collect interval> you allow libev to spend more
-time collecting I/O events, so you can handle more events per iteration,
-at the cost of increasing latency. Timeouts (both C<ev_periodic> and
-C<ev_timer>) will be not affected. Setting this to a non-null value will
-introduce an additional C<ev_sleep ()> call into most loop iterations. The
-sleep time ensures that libev will not poll for I/O events more often then
-once per this interval, on average.
-
-Likewise, by setting a higher I<timeout collect interval> you allow libev
-to spend more time collecting timeouts, at the expense of increased
-latency/jitter/inexactness (the watcher callback will be called
-later). C<ev_io> watchers will not be affected. Setting this to a non-null
-value will not introduce any overhead in libev.
-
-Many (busy) programs can usually benefit by setting the I/O collect
-interval to a value near C<0.1> or so, which is often enough for
-interactive servers (of course not for games), likewise for timeouts. It
-usually doesn't make much sense to set it to a lower value than C<0.01>,
-as this approaches the timing granularity of most systems. Note that if
-you do transactions with the outside world and you can't increase the
-parallelity, then this setting will limit your transaction rate (if you
-need to poll once per transaction and the I/O collect interval is 0.01,
-then you can't do more than 100 transactions per second).
-
-Setting the I<timeout collect interval> can improve the opportunity for
-saving power, as the program will "bundle" timer callback invocations that
-are "near" in time together, by delaying some, thus reducing the number of
-times the process sleeps and wakes up again. Another useful technique to
-reduce iterations/wake-ups is to use C<ev_periodic> watchers and make sure
-they fire on, say, one-second boundaries only.
-
-Example: we only need 0.1s timeout granularity, and we wish not to poll
-more often than 100 times per second:
-
- ev_set_timeout_collect_interval (EV_DEFAULT_UC_ 0.1);
- ev_set_io_collect_interval (EV_DEFAULT_UC_ 0.01);
-
-=item ev_invoke_pending (loop)
-
-This call will simply invoke all pending watchers while resetting their
-pending state. Normally, C<ev_run> does this automatically when required,
-but when overriding the invoke callback this call comes handy. This
-function can be invoked from a watcher - this can be useful for example
-when you want to do some lengthy calculation and want to pass further
-event handling to another thread (you still have to make sure only one
-thread executes within C<ev_invoke_pending> or C<ev_run> of course).
-
-=item int ev_pending_count (loop)
-
-Returns the number of pending watchers - zero indicates that no watchers
-are pending.
-
-=item ev_set_invoke_pending_cb (loop, void (*invoke_pending_cb)(EV_P))
-
-This overrides the invoke pending functionality of the loop: Instead of
-invoking all pending watchers when there are any, C<ev_run> will call
-this callback instead. This is useful, for example, when you want to
-invoke the actual watchers inside another context (another thread etc.).
-
-If you want to reset the callback, use C<ev_invoke_pending> as new
-callback.
-
-=item ev_set_loop_release_cb (loop, void (*release)(EV_P), void (*acquire)(EV_P))
-
-Sometimes you want to share the same loop between multiple threads. This
-can be done relatively simply by putting mutex_lock/unlock calls around
-each call to a libev function.
-
-However, C<ev_run> can run an indefinite time, so it is not feasible
-to wait for it to return. One way around this is to wake up the event
-loop via C<ev_break> and C<av_async_send>, another way is to set these
-I<release> and I<acquire> callbacks on the loop.
-
-When set, then C<release> will be called just before the thread is
-suspended waiting for new events, and C<acquire> is called just
-afterwards.
-
-Ideally, C<release> will just call your mutex_unlock function, and
-C<acquire> will just call the mutex_lock function again.
-
-While event loop modifications are allowed between invocations of
-C<release> and C<acquire> (that's their only purpose after all), no
-modifications done will affect the event loop, i.e. adding watchers will
-have no effect on the set of file descriptors being watched, or the time
-waited. Use an C<ev_async> watcher to wake up C<ev_run> when you want it
-to take note of any changes you made.
-
-In theory, threads executing C<ev_run> will be async-cancel safe between
-invocations of C<release> and C<acquire>.
-
-See also the locking example in the C<THREADS> section later in this
-document.
-
-=item ev_set_userdata (loop, void *data)
-
-=item void *ev_userdata (loop)
-
-Set and retrieve a single C<void *> associated with a loop. When
-C<ev_set_userdata> has never been called, then C<ev_userdata> returns
-C<0>.
-
-These two functions can be used to associate arbitrary data with a loop,
-and are intended solely for the C<invoke_pending_cb>, C<release> and
-C<acquire> callbacks described above, but of course can be (ab-)used for
-any other purpose as well.
-
-=item ev_verify (loop)
-
-This function only does something when C<EV_VERIFY> support has been
-compiled in, which is the default for non-minimal builds. It tries to go
-through all internal structures and checks them for validity. If anything
-is found to be inconsistent, it will print an error message to standard
-error and call C<abort ()>.
-
-This can be used to catch bugs inside libev itself: under normal
-circumstances, this function will never abort as of course libev keeps its
-data structures consistent.
-
-=back
-
-
-=head1 ANATOMY OF A WATCHER
-
-In the following description, uppercase C<TYPE> in names stands for the
-watcher type, e.g. C<ev_TYPE_start> can mean C<ev_timer_start> for timer
-watchers and C<ev_io_start> for I/O watchers.
-
-A watcher is an opaque structure that you allocate and register to record
-your interest in some event. To make a concrete example, imagine you want
-to wait for STDIN to become readable, you would create an C<ev_io> watcher
-for that:
-
- static void my_cb (struct ev_loop *loop, ev_io *w, int revents)
- {
- ev_io_stop (w);
- ev_break (loop, EVBREAK_ALL);
- }
-
- struct ev_loop *loop = ev_default_loop (0);
-
- ev_io stdin_watcher;
-
- ev_init (&stdin_watcher, my_cb);
- ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ);
- ev_io_start (loop, &stdin_watcher);
-
- ev_run (loop, 0);
-
-As you can see, you are responsible for allocating the memory for your
-watcher structures (and it is I<usually> a bad idea to do this on the
-stack).
-
-Each watcher has an associated watcher structure (called C<struct ev_TYPE>
-or simply C<ev_TYPE>, as typedefs are provided for all watcher structs).
-
-Each watcher structure must be initialised by a call to C<ev_init (watcher
-*, callback)>, which expects a callback to be provided. This callback is
-invoked each time the event occurs (or, in the case of I/O watchers, each
-time the event loop detects that the file descriptor given is readable
-and/or writable).
-
-Each watcher type further has its own C<< ev_TYPE_set (watcher *, ...) >>
-macro to configure it, with arguments specific to the watcher type. There
-is also a macro to combine initialisation and setting in one call: C<<
-ev_TYPE_init (watcher *, callback, ...) >>.
-
-To make the watcher actually watch out for events, you have to start it
-with a watcher-specific start function (C<< ev_TYPE_start (loop, watcher
-*) >>), and you can stop watching for events at any time by calling the
-corresponding stop function (C<< ev_TYPE_stop (loop, watcher *) >>.
-
-As long as your watcher is active (has been started but not stopped) you
-must not touch the values stored in it. Most specifically you must never
-reinitialise it or call its C<ev_TYPE_set> macro.
-
-Each and every callback receives the event loop pointer as first, the
-registered watcher structure as second, and a bitset of received events as
-third argument.
-
-The received events usually include a single bit per event type received
-(you can receive multiple events at the same time). The possible bit masks
-are:
-
-=over 4
-
-=item C<EV_READ>
-
-=item C<EV_WRITE>
-
-The file descriptor in the C<ev_io> watcher has become readable and/or
-writable.
-
-=item C<EV_TIMER>
-
-The C<ev_timer> watcher has timed out.
-
-=item C<EV_PERIODIC>
-
-The C<ev_periodic> watcher has timed out.
-
-=item C<EV_SIGNAL>
-
-The signal specified in the C<ev_signal> watcher has been received by a thread.
-
-=item C<EV_CHILD>
-
-The pid specified in the C<ev_child> watcher has received a status change.
-
-=item C<EV_STAT>
-
-The path specified in the C<ev_stat> watcher changed its attributes somehow.
-
-=item C<EV_IDLE>
-
-The C<ev_idle> watcher has determined that you have nothing better to do.
-
-=item C<EV_PREPARE>
-
-=item C<EV_CHECK>
-
-All C<ev_prepare> watchers are invoked just I<before> C<ev_run> starts
-to gather new events, and all C<ev_check> watchers are invoked just after
-C<ev_run> has gathered them, but before it invokes any callbacks for any
-received events. Callbacks of both watcher types can start and stop as
-many watchers as they want, and all of them will be taken into account
-(for example, a C<ev_prepare> watcher might start an idle watcher to keep
-C<ev_run> from blocking).
-
-=item C<EV_EMBED>
-
-The embedded event loop specified in the C<ev_embed> watcher needs attention.
-
-=item C<EV_FORK>
-
-The event loop has been resumed in the child process after fork (see
-C<ev_fork>).
-
-=item C<EV_CLEANUP>
-
-The event loop is about to be destroyed (see C<ev_cleanup>).
-
-=item C<EV_ASYNC>
-
-The given async watcher has been asynchronously notified (see C<ev_async>).
-
-=item C<EV_CUSTOM>
-
-Not ever sent (or otherwise used) by libev itself, but can be freely used
-by libev users to signal watchers (e.g. via C<ev_feed_event>).
-
-=item C<EV_ERROR>
-
-An unspecified error has occurred, the watcher has been stopped. This might
-happen because the watcher could not be properly started because libev
-ran out of memory, a file descriptor was found to be closed or any other
-problem. Libev considers these application bugs.
-
-You best act on it by reporting the problem and somehow coping with the
-watcher being stopped. Note that well-written programs should not receive
-an error ever, so when your watcher receives it, this usually indicates a
-bug in your program.
-
-Libev will usually signal a few "dummy" events together with an error, for
-example it might indicate that a fd is readable or writable, and if your
-callbacks is well-written it can just attempt the operation and cope with
-the error from read() or write(). This will not work in multi-threaded
-programs, though, as the fd could already be closed and reused for another
-thing, so beware.
-
-=back
-
-=head2 GENERIC WATCHER FUNCTIONS
-
-=over 4
-
-=item C<ev_init> (ev_TYPE *watcher, callback)
-
-This macro initialises the generic portion of a watcher. The contents
-of the watcher object can be arbitrary (so C<malloc> will do). Only
-the generic parts of the watcher are initialised, you I<need> to call
-the type-specific C<ev_TYPE_set> macro afterwards to initialise the
-type-specific parts. For each type there is also a C<ev_TYPE_init> macro
-which rolls both calls into one.
-
-You can reinitialise a watcher at any time as long as it has been stopped
-(or never started) and there are no pending events outstanding.
-
-The callback is always of type C<void (*)(struct ev_loop *loop, ev_TYPE *watcher,
-int revents)>.
-
-Example: Initialise an C<ev_io> watcher in two steps.
-
- ev_io w;
- ev_init (&w, my_cb);
- ev_io_set (&w, STDIN_FILENO, EV_READ);
-
-=item C<ev_TYPE_set> (ev_TYPE *watcher, [args])
-
-This macro initialises the type-specific parts of a watcher. You need to
-call C<ev_init> at least once before you call this macro, but you can
-call C<ev_TYPE_set> any number of times. You must not, however, call this
-macro on a watcher that is active (it can be pending, however, which is a
-difference to the C<ev_init> macro).
-
-Although some watcher types do not have type-specific arguments
-(e.g. C<ev_prepare>) you still need to call its C<set> macro.
-
-See C<ev_init>, above, for an example.
-
-=item C<ev_TYPE_init> (ev_TYPE *watcher, callback, [args])
-
-This convenience macro rolls both C<ev_init> and C<ev_TYPE_set> macro
-calls into a single call. This is the most convenient method to initialise
-a watcher. The same limitations apply, of course.
-
-Example: Initialise and set an C<ev_io> watcher in one step.
-
- ev_io_init (&w, my_cb, STDIN_FILENO, EV_READ);
-
-=item C<ev_TYPE_start> (loop, ev_TYPE *watcher)
-
-Starts (activates) the given watcher. Only active watchers will receive
-events. If the watcher is already active nothing will happen.
-
-Example: Start the C<ev_io> watcher that is being abused as example in this
-whole section.
-
- ev_io_start (EV_DEFAULT_UC, &w);
-
-=item C<ev_TYPE_stop> (loop, ev_TYPE *watcher)
-
-Stops the given watcher if active, and clears the pending status (whether
-the watcher was active or not).
-
-It is possible that stopped watchers are pending - for example,
-non-repeating timers are being stopped when they become pending - but
-calling C<ev_TYPE_stop> ensures that the watcher is neither active nor
-pending. If you want to free or reuse the memory used by the watcher it is
-therefore a good idea to always call its C<ev_TYPE_stop> function.
-
-=item bool ev_is_active (ev_TYPE *watcher)
-
-Returns a true value iff the watcher is active (i.e. it has been started
-and not yet been stopped). As long as a watcher is active you must not modify
-it.
-
-=item bool ev_is_pending (ev_TYPE *watcher)
-
-Returns a true value iff the watcher is pending, (i.e. it has outstanding
-events but its callback has not yet been invoked). As long as a watcher
-is pending (but not active) you must not call an init function on it (but
-C<ev_TYPE_set> is safe), you must not change its priority, and you must
-make sure the watcher is available to libev (e.g. you cannot C<free ()>
-it).
-
-=item callback ev_cb (ev_TYPE *watcher)
-
-Returns the callback currently set on the watcher.
-
-=item ev_cb_set (ev_TYPE *watcher, callback)
-
-Change the callback. You can change the callback at virtually any time
-(modulo threads).
-
-=item ev_set_priority (ev_TYPE *watcher, int priority)
-
-=item int ev_priority (ev_TYPE *watcher)
-
-Set and query the priority of the watcher. The priority is a small
-integer between C<EV_MAXPRI> (default: C<2>) and C<EV_MINPRI>
-(default: C<-2>). Pending watchers with higher priority will be invoked
-before watchers with lower priority, but priority will not keep watchers
-from being executed (except for C<ev_idle> watchers).
-
-If you need to suppress invocation when higher priority events are pending
-you need to look at C<ev_idle> watchers, which provide this functionality.
-
-You I<must not> change the priority of a watcher as long as it is active or
-pending.
-
-Setting a priority outside the range of C<EV_MINPRI> to C<EV_MAXPRI> is
-fine, as long as you do not mind that the priority value you query might
-or might not have been clamped to the valid range.
-
-The default priority used by watchers when no priority has been set is
-always C<0>, which is supposed to not be too high and not be too low :).
-
-See L<WATCHER PRIORITY MODELS>, below, for a more thorough treatment of
-priorities.
-
-=item ev_invoke (loop, ev_TYPE *watcher, int revents)
-
-Invoke the C<watcher> with the given C<loop> and C<revents>. Neither
-C<loop> nor C<revents> need to be valid as long as the watcher callback
-can deal with that fact, as both are simply passed through to the
-callback.
-
-=item int ev_clear_pending (loop, ev_TYPE *watcher)
-
-If the watcher is pending, this function clears its pending status and
-returns its C<revents> bitset (as if its callback was invoked). If the
-watcher isn't pending it does nothing and returns C<0>.
-
-Sometimes it can be useful to "poll" a watcher instead of waiting for its
-callback to be invoked, which can be accomplished with this function.
-
-=item ev_feed_event (loop, ev_TYPE *watcher, int revents)
-
-Feeds the given event set into the event loop, as if the specified event
-had happened for the specified watcher (which must be a pointer to an
-initialised but not necessarily started event watcher). Obviously you must
-not free the watcher as long as it has pending events.
-
-Stopping the watcher, letting libev invoke it, or calling
-C<ev_clear_pending> will clear the pending event, even if the watcher was
-not started in the first place.
-
-See also C<ev_feed_fd_event> and C<ev_feed_signal_event> for related
-functions that do not need a watcher.
-
-=back
-
-See also the L<ASSOCIATING CUSTOM DATA WITH A WATCHER> and L<BUILDING YOUR
-OWN COMPOSITE WATCHERS> idioms.
-
-=head2 WATCHER STATES
-
-There are various watcher states mentioned throughout this manual -
-active, pending and so on. In this section these states and the rules to
-transition between them will be described in more detail - and while these
-rules might look complicated, they usually do "the right thing".
-
-=over 4
-
-=item initialiased
-
-Before a watcher can be registered with the event looop it has to be
-initialised. This can be done with a call to C<ev_TYPE_init>, or calls to
-C<ev_init> followed by the watcher-specific C<ev_TYPE_set> function.
-
-In this state it is simply some block of memory that is suitable for
-use in an event loop. It can be moved around, freed, reused etc. at
-will - as long as you either keep the memory contents intact, or call
-C<ev_TYPE_init> again.
-
-=item started/running/active
-
-Once a watcher has been started with a call to C<ev_TYPE_start> it becomes
-property of the event loop, and is actively waiting for events. While in
-this state it cannot be accessed (except in a few documented ways), moved,
-freed or anything else - the only legal thing is to keep a pointer to it,
-and call libev functions on it that are documented to work on active watchers.
-
-=item pending
-
-If a watcher is active and libev determines that an event it is interested
-in has occurred (such as a timer expiring), it will become pending. It will
-stay in this pending state until either it is stopped or its callback is
-about to be invoked, so it is not normally pending inside the watcher
-callback.
-
-The watcher might or might not be active while it is pending (for example,
-an expired non-repeating timer can be pending but no longer active). If it
-is stopped, it can be freely accessed (e.g. by calling C<ev_TYPE_set>),
-but it is still property of the event loop at this time, so cannot be
-moved, freed or reused. And if it is active the rules described in the
-previous item still apply.
-
-It is also possible to feed an event on a watcher that is not active (e.g.
-via C<ev_feed_event>), in which case it becomes pending without being
-active.
-
-=item stopped
-
-A watcher can be stopped implicitly by libev (in which case it might still
-be pending), or explicitly by calling its C<ev_TYPE_stop> function. The
-latter will clear any pending state the watcher might be in, regardless
-of whether it was active or not, so stopping a watcher explicitly before
-freeing it is often a good idea.
-
-While stopped (and not pending) the watcher is essentially in the
-initialised state, that is, it can be reused, moved, modified in any way
-you wish (but when you trash the memory block, you need to C<ev_TYPE_init>
-it again).
-
-=back
-
-=head2 WATCHER PRIORITY MODELS
-
-Many event loops support I<watcher priorities>, which are usually small
-integers that influence the ordering of event callback invocation
-between watchers in some way, all else being equal.
-
-In libev, Watcher priorities can be set using C<ev_set_priority>. See its
-description for the more technical details such as the actual priority
-range.
-
-There are two common ways how these these priorities are being interpreted
-by event loops:
-
-In the more common lock-out model, higher priorities "lock out" invocation
-of lower priority watchers, which means as long as higher priority
-watchers receive events, lower priority watchers are not being invoked.
-
-The less common only-for-ordering model uses priorities solely to order
-callback invocation within a single event loop iteration: Higher priority
-watchers are invoked before lower priority ones, but they all get invoked
-before polling for new events.
-
-Libev uses the second (only-for-ordering) model for all its watchers
-except for idle watchers (which use the lock-out model).
-
-The rationale behind this is that implementing the lock-out model for
-watchers is not well supported by most kernel interfaces, and most event
-libraries will just poll for the same events again and again as long as
-their callbacks have not been executed, which is very inefficient in the
-common case of one high-priority watcher locking out a mass of lower
-priority ones.
-
-Static (ordering) priorities are most useful when you have two or more
-watchers handling the same resource: a typical usage example is having an
-C<ev_io> watcher to receive data, and an associated C<ev_timer> to handle
-timeouts. Under load, data might be received while the program handles
-other jobs, but since timers normally get invoked first, the timeout
-handler will be executed before checking for data. In that case, giving
-the timer a lower priority than the I/O watcher ensures that I/O will be
-handled first even under adverse conditions (which is usually, but not
-always, what you want).
-
-Since idle watchers use the "lock-out" model, meaning that idle watchers
-will only be executed when no same or higher priority watchers have
-received events, they can be used to implement the "lock-out" model when
-required.
-
-For example, to emulate how many other event libraries handle priorities,
-you can associate an C<ev_idle> watcher to each such watcher, and in
-the normal watcher callback, you just start the idle watcher. The real
-processing is done in the idle watcher callback. This causes libev to
-continuously poll and process kernel event data for the watcher, but when
-the lock-out case is known to be rare (which in turn is rare :), this is
-workable.
-
-Usually, however, the lock-out model implemented that way will perform
-miserably under the type of load it was designed to handle. In that case,
-it might be preferable to stop the real watcher before starting the
-idle watcher, so the kernel will not have to process the event in case
-the actual processing will be delayed for considerable time.
-
-Here is an example of an I/O watcher that should run at a strictly lower
-priority than the default, and which should only process data when no
-other events are pending:
-
- ev_idle idle; // actual processing watcher
- ev_io io; // actual event watcher
-
- static void
- io_cb (EV_P_ ev_io *w, int revents)
- {
- // stop the I/O watcher, we received the event, but
- // are not yet ready to handle it.
- ev_io_stop (EV_A_ w);
-
- // start the idle watcher to handle the actual event.
- // it will not be executed as long as other watchers
- // with the default priority are receiving events.
- ev_idle_start (EV_A_ &idle);
- }
-
- static void
- idle_cb (EV_P_ ev_idle *w, int revents)
- {
- // actual processing
- read (STDIN_FILENO, ...);
-
- // have to start the I/O watcher again, as
- // we have handled the event
- ev_io_start (EV_P_ &io);
- }
-
- // initialisation
- ev_idle_init (&idle, idle_cb);
- ev_io_init (&io, io_cb, STDIN_FILENO, EV_READ);
- ev_io_start (EV_DEFAULT_ &io);
-
-In the "real" world, it might also be beneficial to start a timer, so that
-low-priority connections can not be locked out forever under load. This
-enables your program to keep a lower latency for important connections
-during short periods of high load, while not completely locking out less
-important ones.
-
-
-=head1 WATCHER TYPES
-
-This section describes each watcher in detail, but will not repeat
-information given in the last section. Any initialisation/set macros,
-functions and members specific to the watcher type are explained.
-
-Members are additionally marked with either I<[read-only]>, meaning that,
-while the watcher is active, you can look at the member and expect some
-sensible content, but you must not modify it (you can modify it while the
-watcher is stopped to your hearts content), or I<[read-write]>, which
-means you can expect it to have some sensible content while the watcher
-is active, but you can also modify it. Modifying it may not do something
-sensible or take immediate effect (or do anything at all), but libev will
-not crash or malfunction in any way.
-
-
-=head2 C<ev_io> - is this file descriptor readable or writable?
-
-I/O watchers check whether a file descriptor is readable or writable
-in each iteration of the event loop, or, more precisely, when reading
-would not block the process and writing would at least be able to write
-some data. This behaviour is called level-triggering because you keep
-receiving events as long as the condition persists. Remember you can stop
-the watcher if you don't want to act on the event and neither want to
-receive future events.
-
-In general you can register as many read and/or write event watchers per
-fd as you want (as long as you don't confuse yourself). Setting all file
-descriptors to non-blocking mode is also usually a good idea (but not
-required if you know what you are doing).
-
-Another thing you have to watch out for is that it is quite easy to
-receive "spurious" readiness notifications, that is, your callback might
-be called with C<EV_READ> but a subsequent C<read>(2) will actually block
-because there is no data. It is very easy to get into this situation even
-with a relatively standard program structure. Thus it is best to always
-use non-blocking I/O: An extra C<read>(2) returning C<EAGAIN> is far
-preferable to a program hanging until some data arrives.
-
-If you cannot run the fd in non-blocking mode (for example you should
-not play around with an Xlib connection), then you have to separately
-re-test whether a file descriptor is really ready with a known-to-be good
-interface such as poll (fortunately in the case of Xlib, it already does
-this on its own, so its quite safe to use). Some people additionally
-use C<SIGALRM> and an interval timer, just to be sure you won't block
-indefinitely.
-
-But really, best use non-blocking mode.
-
-=head3 The special problem of disappearing file descriptors
-
-Some backends (e.g. kqueue, epoll) need to be told about closing a file
-descriptor (either due to calling C<close> explicitly or any other means,
-such as C<dup2>). The reason is that you register interest in some file
-descriptor, but when it goes away, the operating system will silently drop
-this interest. If another file descriptor with the same number then is
-registered with libev, there is no efficient way to see that this is, in
-fact, a different file descriptor.
-
-To avoid having to explicitly tell libev about such cases, libev follows
-the following policy: Each time C<ev_io_set> is being called, libev
-will assume that this is potentially a new file descriptor, otherwise
-it is assumed that the file descriptor stays the same. That means that
-you I<have> to call C<ev_io_set> (or C<ev_io_init>) when you change the
-descriptor even if the file descriptor number itself did not change.
-
-This is how one would do it normally anyway, the important point is that
-the libev application should not optimise around libev but should leave
-optimisations to libev.
-
-=head3 The special problem of dup'ed file descriptors
-
-Some backends (e.g. epoll), cannot register events for file descriptors,
-but only events for the underlying file descriptions. That means when you
-have C<dup ()>'ed file descriptors or weirder constellations, and register
-events for them, only one file descriptor might actually receive events.
-
-There is no workaround possible except not registering events
-for potentially C<dup ()>'ed file descriptors, or to resort to
-C<EVBACKEND_SELECT> or C<EVBACKEND_POLL>.
-
-=head3 The special problem of files
-
-Many people try to use C<select> (or libev) on file descriptors
-representing files, and expect it to become ready when their program
-doesn't block on disk accesses (which can take a long time on their own).
-
-However, this cannot ever work in the "expected" way - you get a readiness
-notification as soon as the kernel knows whether and how much data is
-there, and in the case of open files, that's always the case, so you
-always get a readiness notification instantly, and your read (or possibly
-write) will still block on the disk I/O.
-
-Another way to view it is that in the case of sockets, pipes, character
-devices and so on, there is another party (the sender) that delivers data
-on its own, but in the case of files, there is no such thing: the disk
-will not send data on its own, simply because it doesn't know what you
-wish to read - you would first have to request some data.
-
-Since files are typically not-so-well supported by advanced notification
-mechanism, libev tries hard to emulate POSIX behaviour with respect
-to files, even though you should not use it. The reason for this is
-convenience: sometimes you want to watch STDIN or STDOUT, which is
-usually a tty, often a pipe, but also sometimes files or special devices
-(for example, C<epoll> on Linux works with F</dev/random> but not with
-F</dev/urandom>), and even though the file might better be served with
-asynchronous I/O instead of with non-blocking I/O, it is still useful when
-it "just works" instead of freezing.
-
-So avoid file descriptors pointing to files when you know it (e.g. use
-libeio), but use them when it is convenient, e.g. for STDIN/STDOUT, or
-when you rarely read from a file instead of from a socket, and want to
-reuse the same code path.
-
-=head3 The special problem of fork
-
-Some backends (epoll, kqueue) do not support C<fork ()> at all or exhibit
-useless behaviour. Libev fully supports fork, but needs to be told about
-it in the child if you want to continue to use it in the child.
-
-To support fork in your child processes, you have to call C<ev_loop_fork
-()> after a fork in the child, enable C<EVFLAG_FORKCHECK>, or resort to
-C<EVBACKEND_SELECT> or C<EVBACKEND_POLL>.
-
-=head3 The special problem of SIGPIPE
-
-While not really specific to libev, it is easy to forget about C<SIGPIPE>:
-when writing to a pipe whose other end has been closed, your program gets
-sent a SIGPIPE, which, by default, aborts your program. For most programs
-this is sensible behaviour, for daemons, this is usually undesirable.
-
-So when you encounter spurious, unexplained daemon exits, make sure you
-ignore SIGPIPE (and maybe make sure you log the exit status of your daemon
-somewhere, as that would have given you a big clue).
-
-=head3 The special problem of accept()ing when you can't
-
-Many implementations of the POSIX C<accept> function (for example,
-found in post-2004 Linux) have the peculiar behaviour of not removing a
-connection from the pending queue in all error cases.
-
-For example, larger servers often run out of file descriptors (because
-of resource limits), causing C<accept> to fail with C<ENFILE> but not
-rejecting the connection, leading to libev signalling readiness on
-the next iteration again (the connection still exists after all), and
-typically causing the program to loop at 100% CPU usage.
-
-Unfortunately, the set of errors that cause this issue differs between
-operating systems, there is usually little the app can do to remedy the
-situation, and no known thread-safe method of removing the connection to
-cope with overload is known (to me).
-
-One of the easiest ways to handle this situation is to just ignore it
-- when the program encounters an overload, it will just loop until the
-situation is over. While this is a form of busy waiting, no OS offers an
-event-based way to handle this situation, so it's the best one can do.
-
-A better way to handle the situation is to log any errors other than
-C<EAGAIN> and C<EWOULDBLOCK>, making sure not to flood the log with such
-messages, and continue as usual, which at least gives the user an idea of
-what could be wrong ("raise the ulimit!"). For extra points one could stop
-the C<ev_io> watcher on the listening fd "for a while", which reduces CPU
-usage.
-
-If your program is single-threaded, then you could also keep a dummy file
-descriptor for overload situations (e.g. by opening F</dev/null>), and
-when you run into C<ENFILE> or C<EMFILE>, close it, run C<accept>,
-close that fd, and create a new dummy fd. This will gracefully refuse
-clients under typical overload conditions.
-
-The last way to handle it is to simply log the error and C<exit>, as
-is often done with C<malloc> failures, but this results in an easy
-opportunity for a DoS attack.
-
-=head3 Watcher-Specific Functions
-
-=over 4
-
-=item ev_io_init (ev_io *, callback, int fd, int events)
-
-=item ev_io_set (ev_io *, int fd, int events)
-
-Configures an C<ev_io> watcher. The C<fd> is the file descriptor to
-receive events for and C<events> is either C<EV_READ>, C<EV_WRITE> or
-C<EV_READ | EV_WRITE>, to express the desire to receive the given events.
-
-=item int fd [read-only]
-
-The file descriptor being watched.
-
-=item int events [read-only]
-
-The events being watched.
-
-=back
-
-=head3 Examples
-
-Example: Call C<stdin_readable_cb> when STDIN_FILENO has become, well
-readable, but only once. Since it is likely line-buffered, you could
-attempt to read a whole line in the callback.
-
- static void
- stdin_readable_cb (struct ev_loop *loop, ev_io *w, int revents)
- {
- ev_io_stop (loop, w);
- .. read from stdin here (or from w->fd) and handle any I/O errors
- }
-
- ...
- struct ev_loop *loop = ev_default_init (0);
- ev_io stdin_readable;
- ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ);
- ev_io_start (loop, &stdin_readable);
- ev_run (loop, 0);
-
-
-=head2 C<ev_timer> - relative and optionally repeating timeouts
-
-Timer watchers are simple relative timers that generate an event after a
-given time, and optionally repeating in regular intervals after that.
-
-The timers are based on real time, that is, if you register an event that
-times out after an hour and you reset your system clock to January last
-year, it will still time out after (roughly) one hour. "Roughly" because
-detecting time jumps is hard, and some inaccuracies are unavoidable (the
-monotonic clock option helps a lot here).
-
-The callback is guaranteed to be invoked only I<after> its timeout has
-passed (not I<at>, so on systems with very low-resolution clocks this
-might introduce a small delay). If multiple timers become ready during the
-same loop iteration then the ones with earlier time-out values are invoked
-before ones of the same priority with later time-out values (but this is
-no longer true when a callback calls C<ev_run> recursively).
-
-=head3 Be smart about timeouts
-
-Many real-world problems involve some kind of timeout, usually for error
-recovery. A typical example is an HTTP request - if the other side hangs,
-you want to raise some error after a while.
-
-What follows are some ways to handle this problem, from obvious and
-inefficient to smart and efficient.
-
-In the following, a 60 second activity timeout is assumed - a timeout that
-gets reset to 60 seconds each time there is activity (e.g. each time some
-data or other life sign was received).
-
-=over 4
-
-=item 1. Use a timer and stop, reinitialise and start it on activity.
-
-This is the most obvious, but not the most simple way: In the beginning,
-start the watcher:
-
- ev_timer_init (timer, callback, 60., 0.);
- ev_timer_start (loop, timer);
-
-Then, each time there is some activity, C<ev_timer_stop> it, initialise it
-and start it again:
-
- ev_timer_stop (loop, timer);
- ev_timer_set (timer, 60., 0.);
- ev_timer_start (loop, timer);
-
-This is relatively simple to implement, but means that each time there is
-some activity, libev will first have to remove the timer from its internal
-data structure and then add it again. Libev tries to be fast, but it's
-still not a constant-time operation.
-
-=item 2. Use a timer and re-start it with C<ev_timer_again> inactivity.
-
-This is the easiest way, and involves using C<ev_timer_again> instead of
-C<ev_timer_start>.
-
-To implement this, configure an C<ev_timer> with a C<repeat> value
-of C<60> and then call C<ev_timer_again> at start and each time you
-successfully read or write some data. If you go into an idle state where
-you do not expect data to travel on the socket, you can C<ev_timer_stop>
-the timer, and C<ev_timer_again> will automatically restart it if need be.
-
-That means you can ignore both the C<ev_timer_start> function and the
-C<after> argument to C<ev_timer_set>, and only ever use the C<repeat>
-member and C<ev_timer_again>.
-
-At start:
-
- ev_init (timer, callback);
- timer->repeat = 60.;
- ev_timer_again (loop, timer);
-
-Each time there is some activity:
-
- ev_timer_again (loop, timer);
-
-It is even possible to change the time-out on the fly, regardless of
-whether the watcher is active or not:
-
- timer->repeat = 30.;
- ev_timer_again (loop, timer);
-
-This is slightly more efficient then stopping/starting the timer each time
-you want to modify its timeout value, as libev does not have to completely
-remove and re-insert the timer from/into its internal data structure.
-
-It is, however, even simpler than the "obvious" way to do it.
-
-=item 3. Let the timer time out, but then re-arm it as required.
-
-This method is more tricky, but usually most efficient: Most timeouts are
-relatively long compared to the intervals between other activity - in
-our example, within 60 seconds, there are usually many I/O events with
-associated activity resets.
-
-In this case, it would be more efficient to leave the C<ev_timer> alone,
-but remember the time of last activity, and check for a real timeout only
-within the callback:
-
- ev_tstamp last_activity; // time of last activity
-
- static void
- callback (EV_P_ ev_timer *w, int revents)
- {
- ev_tstamp now = ev_now (EV_A);
- ev_tstamp timeout = last_activity + 60.;
-
- // if last_activity + 60. is older than now, we did time out
- if (timeout < now)
- {
- // timeout occurred, take action
- }
- else
- {
- // callback was invoked, but there was some activity, re-arm
- // the watcher to fire in last_activity + 60, which is
- // guaranteed to be in the future, so "again" is positive:
- w->repeat = timeout - now;
- ev_timer_again (EV_A_ w);
- }
- }
-
-To summarise the callback: first calculate the real timeout (defined
-as "60 seconds after the last activity"), then check if that time has
-been reached, which means something I<did>, in fact, time out. Otherwise
-the callback was invoked too early (C<timeout> is in the future), so
-re-schedule the timer to fire at that future time, to see if maybe we have
-a timeout then.
-
-Note how C<ev_timer_again> is used, taking advantage of the
-C<ev_timer_again> optimisation when the timer is already running.
-
-This scheme causes more callback invocations (about one every 60 seconds
-minus half the average time between activity), but virtually no calls to
-libev to change the timeout.
-
-To start the timer, simply initialise the watcher and set C<last_activity>
-to the current time (meaning we just have some activity :), then call the
-callback, which will "do the right thing" and start the timer:
-
- ev_init (timer, callback);
- last_activity = ev_now (loop);
- callback (loop, timer, EV_TIMER);
-
-And when there is some activity, simply store the current time in
-C<last_activity>, no libev calls at all:
-
- last_activity = ev_now (loop);
-
-This technique is slightly more complex, but in most cases where the
-time-out is unlikely to be triggered, much more efficient.
-
-Changing the timeout is trivial as well (if it isn't hard-coded in the
-callback :) - just change the timeout and invoke the callback, which will
-fix things for you.
-
-=item 4. Wee, just use a double-linked list for your timeouts.
-
-If there is not one request, but many thousands (millions...), all
-employing some kind of timeout with the same timeout value, then one can
-do even better:
-
-When starting the timeout, calculate the timeout value and put the timeout
-at the I<end> of the list.
-
-Then use an C<ev_timer> to fire when the timeout at the I<beginning> of
-the list is expected to fire (for example, using the technique #3).
-
-When there is some activity, remove the timer from the list, recalculate
-the timeout, append it to the end of the list again, and make sure to
-update the C<ev_timer> if it was taken from the beginning of the list.
-
-This way, one can manage an unlimited number of timeouts in O(1) time for
-starting, stopping and updating the timers, at the expense of a major
-complication, and having to use a constant timeout. The constant timeout
-ensures that the list stays sorted.
-
-=back
-
-So which method the best?
-
-Method #2 is a simple no-brain-required solution that is adequate in most
-situations. Method #3 requires a bit more thinking, but handles many cases
-better, and isn't very complicated either. In most case, choosing either
-one is fine, with #3 being better in typical situations.
-
-Method #1 is almost always a bad idea, and buys you nothing. Method #4 is
-rather complicated, but extremely efficient, something that really pays
-off after the first million or so of active timers, i.e. it's usually
-overkill :)
-
-=head3 The special problem of time updates
-
-Establishing the current time is a costly operation (it usually takes at
-least two system calls): EV therefore updates its idea of the current
-time only before and after C<ev_run> collects new events, which causes a
-growing difference between C<ev_now ()> and C<ev_time ()> when handling
-lots of events in one iteration.
-
-The relative timeouts are calculated relative to the C<ev_now ()>
-time. This is usually the right thing as this timestamp refers to the time
-of the event triggering whatever timeout you are modifying/starting. If
-you suspect event processing to be delayed and you I<need> to base the
-timeout on the current time, use something like this to adjust for this:
-
- ev_timer_set (&timer, after + ev_now () - ev_time (), 0.);
-
-If the event loop is suspended for a long time, you can also force an
-update of the time returned by C<ev_now ()> by calling C<ev_now_update
-()>.
-
-=head3 The special problems of suspended animation
-
-When you leave the server world it is quite customary to hit machines that
-can suspend/hibernate - what happens to the clocks during such a suspend?
-
-Some quick tests made with a Linux 2.6.28 indicate that a suspend freezes
-all processes, while the clocks (C<times>, C<CLOCK_MONOTONIC>) continue
-to run until the system is suspended, but they will not advance while the
-system is suspended. That means, on resume, it will be as if the program
-was frozen for a few seconds, but the suspend time will not be counted
-towards C<ev_timer> when a monotonic clock source is used. The real time
-clock advanced as expected, but if it is used as sole clocksource, then a
-long suspend would be detected as a time jump by libev, and timers would
-be adjusted accordingly.
-
-I would not be surprised to see different behaviour in different between
-operating systems, OS versions or even different hardware.
-
-The other form of suspend (job control, or sending a SIGSTOP) will see a
-time jump in the monotonic clocks and the realtime clock. If the program
-is suspended for a very long time, and monotonic clock sources are in use,
-then you can expect C<ev_timer>s to expire as the full suspension time
-will be counted towards the timers. When no monotonic clock source is in
-use, then libev will again assume a timejump and adjust accordingly.
-
-It might be beneficial for this latter case to call C<ev_suspend>
-and C<ev_resume> in code that handles C<SIGTSTP>, to at least get
-deterministic behaviour in this case (you can do nothing against
-C<SIGSTOP>).
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_timer_init (ev_timer *, callback, ev_tstamp after, ev_tstamp repeat)
-
-=item ev_timer_set (ev_timer *, ev_tstamp after, ev_tstamp repeat)
-
-Configure the timer to trigger after C<after> seconds. If C<repeat>
-is C<0.>, then it will automatically be stopped once the timeout is
-reached. If it is positive, then the timer will automatically be
-configured to trigger again C<repeat> seconds later, again, and again,
-until stopped manually.
-
-The timer itself will do a best-effort at avoiding drift, that is, if
-you configure a timer to trigger every 10 seconds, then it will normally
-trigger at exactly 10 second intervals. If, however, your program cannot
-keep up with the timer (because it takes longer than those 10 seconds to
-do stuff) the timer will not fire more than once per event loop iteration.
-
-=item ev_timer_again (loop, ev_timer *)
-
-This will act as if the timer timed out and restart it again if it is
-repeating. The exact semantics are:
-
-If the timer is pending, its pending status is cleared.
-
-If the timer is started but non-repeating, stop it (as if it timed out).
-
-If the timer is repeating, either start it if necessary (with the
-C<repeat> value), or reset the running timer to the C<repeat> value.
-
-This sounds a bit complicated, see L<Be smart about timeouts>, above, for a
-usage example.
-
-=item ev_tstamp ev_timer_remaining (loop, ev_timer *)
-
-Returns the remaining time until a timer fires. If the timer is active,
-then this time is relative to the current event loop time, otherwise it's
-the timeout value currently configured.
-
-That is, after an C<ev_timer_set (w, 5, 7)>, C<ev_timer_remaining> returns
-C<5>. When the timer is started and one second passes, C<ev_timer_remaining>
-will return C<4>. When the timer expires and is restarted, it will return
-roughly C<7> (likely slightly less as callback invocation takes some time,
-too), and so on.
-
-=item ev_tstamp repeat [read-write]
-
-The current C<repeat> value. Will be used each time the watcher times out
-or C<ev_timer_again> is called, and determines the next timeout (if any),
-which is also when any modifications are taken into account.
-
-=back
-
-=head3 Examples
-
-Example: Create a timer that fires after 60 seconds.
-
- static void
- one_minute_cb (struct ev_loop *loop, ev_timer *w, int revents)
- {
- .. one minute over, w is actually stopped right here
- }
-
- ev_timer mytimer;
- ev_timer_init (&mytimer, one_minute_cb, 60., 0.);
- ev_timer_start (loop, &mytimer);
-
-Example: Create a timeout timer that times out after 10 seconds of
-inactivity.
-
- static void
- timeout_cb (struct ev_loop *loop, ev_timer *w, int revents)
- {
- .. ten seconds without any activity
- }
-
- ev_timer mytimer;
- ev_timer_init (&mytimer, timeout_cb, 0., 10.); /* note, only repeat used */
- ev_timer_again (&mytimer); /* start timer */
- ev_run (loop, 0);
-
- // and in some piece of code that gets executed on any "activity":
- // reset the timeout to start ticking again at 10 seconds
- ev_timer_again (&mytimer);
-
-
-=head2 C<ev_periodic> - to cron or not to cron?
-
-Periodic watchers are also timers of a kind, but they are very versatile
-(and unfortunately a bit complex).
-
-Unlike C<ev_timer>, periodic watchers are not based on real time (or
-relative time, the physical time that passes) but on wall clock time
-(absolute time, the thing you can read on your calender or clock). The
-difference is that wall clock time can run faster or slower than real
-time, and time jumps are not uncommon (e.g. when you adjust your
-wrist-watch).
-
-You can tell a periodic watcher to trigger after some specific point
-in time: for example, if you tell a periodic watcher to trigger "in 10
-seconds" (by specifying e.g. C<ev_now () + 10.>, that is, an absolute time
-not a delay) and then reset your system clock to January of the previous
-year, then it will take a year or more to trigger the event (unlike an
-C<ev_timer>, which would still trigger roughly 10 seconds after starting
-it, as it uses a relative timeout).
-
-C<ev_periodic> watchers can also be used to implement vastly more complex
-timers, such as triggering an event on each "midnight, local time", or
-other complicated rules. This cannot be done with C<ev_timer> watchers, as
-those cannot react to time jumps.
-
-As with timers, the callback is guaranteed to be invoked only when the
-point in time where it is supposed to trigger has passed. If multiple
-timers become ready during the same loop iteration then the ones with
-earlier time-out values are invoked before ones with later time-out values
-(but this is no longer true when a callback calls C<ev_run> recursively).
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_periodic_init (ev_periodic *, callback, ev_tstamp offset, ev_tstamp interval, reschedule_cb)
-
-=item ev_periodic_set (ev_periodic *, ev_tstamp offset, ev_tstamp interval, reschedule_cb)
-
-Lots of arguments, let's sort it out... There are basically three modes of
-operation, and we will explain them from simplest to most complex:
-
-=over 4
-
-=item * absolute timer (offset = absolute time, interval = 0, reschedule_cb = 0)
-
-In this configuration the watcher triggers an event after the wall clock
-time C<offset> has passed. It will not repeat and will not adjust when a
-time jump occurs, that is, if it is to be run at January 1st 2011 then it
-will be stopped and invoked when the system clock reaches or surpasses
-this point in time.
-
-=item * repeating interval timer (offset = offset within interval, interval > 0, reschedule_cb = 0)
-
-In this mode the watcher will always be scheduled to time out at the next
-C<offset + N * interval> time (for some integer N, which can also be
-negative) and then repeat, regardless of any time jumps. The C<offset>
-argument is merely an offset into the C<interval> periods.
-
-This can be used to create timers that do not drift with respect to the
-system clock, for example, here is an C<ev_periodic> that triggers each
-hour, on the hour (with respect to UTC):
-
- ev_periodic_set (&periodic, 0., 3600., 0);
-
-This doesn't mean there will always be 3600 seconds in between triggers,
-but only that the callback will be called when the system time shows a
-full hour (UTC), or more correctly, when the system time is evenly divisible
-by 3600.
-
-Another way to think about it (for the mathematically inclined) is that
-C<ev_periodic> will try to run the callback in this mode at the next possible
-time where C<time = offset (mod interval)>, regardless of any time jumps.
-
-For numerical stability it is preferable that the C<offset> value is near
-C<ev_now ()> (the current time), but there is no range requirement for
-this value, and in fact is often specified as zero.
-
-Note also that there is an upper limit to how often a timer can fire (CPU
-speed for example), so if C<interval> is very small then timing stability
-will of course deteriorate. Libev itself tries to be exact to be about one
-millisecond (if the OS supports it and the machine is fast enough).
-
-=item * manual reschedule mode (offset ignored, interval ignored, reschedule_cb = callback)
-
-In this mode the values for C<interval> and C<offset> are both being
-ignored. Instead, each time the periodic watcher gets scheduled, the
-reschedule callback will be called with the watcher as first, and the
-current time as second argument.
-
-NOTE: I<This callback MUST NOT stop or destroy any periodic watcher, ever,
-or make ANY other event loop modifications whatsoever, unless explicitly
-allowed by documentation here>.
-
-If you need to stop it, return C<now + 1e30> (or so, fudge fudge) and stop
-it afterwards (e.g. by starting an C<ev_prepare> watcher, which is the
-only event loop modification you are allowed to do).
-
-The callback prototype is C<ev_tstamp (*reschedule_cb)(ev_periodic
-*w, ev_tstamp now)>, e.g.:
-
- static ev_tstamp
- my_rescheduler (ev_periodic *w, ev_tstamp now)
- {
- return now + 60.;
- }
-
-It must return the next time to trigger, based on the passed time value
-(that is, the lowest time value larger than to the second argument). It
-will usually be called just before the callback will be triggered, but
-might be called at other times, too.
-
-NOTE: I<< This callback must always return a time that is higher than or
-equal to the passed C<now> value >>.
-
-This can be used to create very complex timers, such as a timer that
-triggers on "next midnight, local time". To do this, you would calculate the
-next midnight after C<now> and return the timestamp value for this. How
-you do this is, again, up to you (but it is not trivial, which is the main
-reason I omitted it as an example).
-
-=back
-
-=item ev_periodic_again (loop, ev_periodic *)
-
-Simply stops and restarts the periodic watcher again. This is only useful
-when you changed some parameters or the reschedule callback would return
-a different time than the last time it was called (e.g. in a crond like
-program when the crontabs have changed).
-
-=item ev_tstamp ev_periodic_at (ev_periodic *)
-
-When active, returns the absolute time that the watcher is supposed
-to trigger next. This is not the same as the C<offset> argument to
-C<ev_periodic_set>, but indeed works even in interval and manual
-rescheduling modes.
-
-=item ev_tstamp offset [read-write]
-
-When repeating, this contains the offset value, otherwise this is the
-absolute point in time (the C<offset> value passed to C<ev_periodic_set>,
-although libev might modify this value for better numerical stability).
-
-Can be modified any time, but changes only take effect when the periodic
-timer fires or C<ev_periodic_again> is being called.
-
-=item ev_tstamp interval [read-write]
-
-The current interval value. Can be modified any time, but changes only
-take effect when the periodic timer fires or C<ev_periodic_again> is being
-called.
-
-=item ev_tstamp (*reschedule_cb)(ev_periodic *w, ev_tstamp now) [read-write]
-
-The current reschedule callback, or C<0>, if this functionality is
-switched off. Can be changed any time, but changes only take effect when
-the periodic timer fires or C<ev_periodic_again> is being called.
-
-=back
-
-=head3 Examples
-
-Example: Call a callback every hour, or, more precisely, whenever the
-system time is divisible by 3600. The callback invocation times have
-potentially a lot of jitter, but good long-term stability.
-
- static void
- clock_cb (struct ev_loop *loop, ev_periodic *w, int revents)
- {
- ... its now a full hour (UTC, or TAI or whatever your clock follows)
- }
-
- ev_periodic hourly_tick;
- ev_periodic_init (&hourly_tick, clock_cb, 0., 3600., 0);
- ev_periodic_start (loop, &hourly_tick);
-
-Example: The same as above, but use a reschedule callback to do it:
-
- #include <math.h>
-
- static ev_tstamp
- my_scheduler_cb (ev_periodic *w, ev_tstamp now)
- {
- return now + (3600. - fmod (now, 3600.));
- }
-
- ev_periodic_init (&hourly_tick, clock_cb, 0., 0., my_scheduler_cb);
-
-Example: Call a callback every hour, starting now:
-
- ev_periodic hourly_tick;
- ev_periodic_init (&hourly_tick, clock_cb,
- fmod (ev_now (loop), 3600.), 3600., 0);
- ev_periodic_start (loop, &hourly_tick);
-
-
-=head2 C<ev_signal> - signal me when a signal gets signalled!
-
-Signal watchers will trigger an event when the process receives a specific
-signal one or more times. Even though signals are very asynchronous, libev
-will try its best to deliver signals synchronously, i.e. as part of the
-normal event processing, like any other event.
-
-If you want signals to be delivered truly asynchronously, just use
-C<sigaction> as you would do without libev and forget about sharing
-the signal. You can even use C<ev_async> from a signal handler to
-synchronously wake up an event loop.
-
-You can configure as many watchers as you like for the same signal, but
-only within the same loop, i.e. you can watch for C<SIGINT> in your
-default loop and for C<SIGIO> in another loop, but you cannot watch for
-C<SIGINT> in both the default loop and another loop at the same time. At
-the moment, C<SIGCHLD> is permanently tied to the default loop.
-
-When the first watcher gets started will libev actually register something
-with the kernel (thus it coexists with your own signal handlers as long as
-you don't register any with libev for the same signal).
-
-If possible and supported, libev will install its handlers with
-C<SA_RESTART> (or equivalent) behaviour enabled, so system calls should
-not be unduly interrupted. If you have a problem with system calls getting
-interrupted by signals you can block all signals in an C<ev_check> watcher
-and unblock them in an C<ev_prepare> watcher.
-
-=head3 The special problem of inheritance over fork/execve/pthread_create
-
-Both the signal mask (C<sigprocmask>) and the signal disposition
-(C<sigaction>) are unspecified after starting a signal watcher (and after
-stopping it again), that is, libev might or might not block the signal,
-and might or might not set or restore the installed signal handler (but
-see C<EVFLAG_NOSIGMASK>).
-
-While this does not matter for the signal disposition (libev never
-sets signals to C<SIG_IGN>, so handlers will be reset to C<SIG_DFL> on
-C<execve>), this matters for the signal mask: many programs do not expect
-certain signals to be blocked.
-
-This means that before calling C<exec> (from the child) you should reset
-the signal mask to whatever "default" you expect (all clear is a good
-choice usually).
-
-The simplest way to ensure that the signal mask is reset in the child is
-to install a fork handler with C<pthread_atfork> that resets it. That will
-catch fork calls done by libraries (such as the libc) as well.
-
-In current versions of libev, the signal will not be blocked indefinitely
-unless you use the C<signalfd> API (C<EV_SIGNALFD>). While this reduces
-the window of opportunity for problems, it will not go away, as libev
-I<has> to modify the signal mask, at least temporarily.
-
-So I can't stress this enough: I<If you do not reset your signal mask when
-you expect it to be empty, you have a race condition in your code>. This
-is not a libev-specific thing, this is true for most event libraries.
-
-=head3 The special problem of threads signal handling
-
-POSIX threads has problematic signal handling semantics, specifically,
-a lot of functionality (sigfd, sigwait etc.) only really works if all
-threads in a process block signals, which is hard to achieve.
-
-When you want to use sigwait (or mix libev signal handling with your own
-for the same signals), you can tackle this problem by globally blocking
-all signals before creating any threads (or creating them with a fully set
-sigprocmask) and also specifying the C<EVFLAG_NOSIGMASK> when creating
-loops. Then designate one thread as "signal receiver thread" which handles
-these signals. You can pass on any signals that libev might be interested
-in by calling C<ev_feed_signal>.
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_signal_init (ev_signal *, callback, int signum)
-
-=item ev_signal_set (ev_signal *, int signum)
-
-Configures the watcher to trigger on the given signal number (usually one
-of the C<SIGxxx> constants).
-
-=item int signum [read-only]
-
-The signal the watcher watches out for.
-
-=back
-
-=head3 Examples
-
-Example: Try to exit cleanly on SIGINT.
-
- static void
- sigint_cb (struct ev_loop *loop, ev_signal *w, int revents)
- {
- ev_break (loop, EVBREAK_ALL);
- }
-
- ev_signal signal_watcher;
- ev_signal_init (&signal_watcher, sigint_cb, SIGINT);
- ev_signal_start (loop, &signal_watcher);
-
-
-=head2 C<ev_child> - watch out for process status changes
-
-Child watchers trigger when your process receives a SIGCHLD in response to
-some child status changes (most typically when a child of yours dies or
-exits). It is permissible to install a child watcher I<after> the child
-has been forked (which implies it might have already exited), as long
-as the event loop isn't entered (or is continued from a watcher), i.e.,
-forking and then immediately registering a watcher for the child is fine,
-but forking and registering a watcher a few event loop iterations later or
-in the next callback invocation is not.
-
-Only the default event loop is capable of handling signals, and therefore
-you can only register child watchers in the default event loop.
-
-Due to some design glitches inside libev, child watchers will always be
-handled at maximum priority (their priority is set to C<EV_MAXPRI> by
-libev)
-
-=head3 Process Interaction
-
-Libev grabs C<SIGCHLD> as soon as the default event loop is
-initialised. This is necessary to guarantee proper behaviour even if the
-first child watcher is started after the child exits. The occurrence
-of C<SIGCHLD> is recorded asynchronously, but child reaping is done
-synchronously as part of the event loop processing. Libev always reaps all
-children, even ones not watched.
-
-=head3 Overriding the Built-In Processing
-
-Libev offers no special support for overriding the built-in child
-processing, but if your application collides with libev's default child
-handler, you can override it easily by installing your own handler for
-C<SIGCHLD> after initialising the default loop, and making sure the
-default loop never gets destroyed. You are encouraged, however, to use an
-event-based approach to child reaping and thus use libev's support for
-that, so other libev users can use C<ev_child> watchers freely.
-
-=head3 Stopping the Child Watcher
-
-Currently, the child watcher never gets stopped, even when the
-child terminates, so normally one needs to stop the watcher in the
-callback. Future versions of libev might stop the watcher automatically
-when a child exit is detected (calling C<ev_child_stop> twice is not a
-problem).
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_child_init (ev_child *, callback, int pid, int trace)
-
-=item ev_child_set (ev_child *, int pid, int trace)
-
-Configures the watcher to wait for status changes of process C<pid> (or
-I<any> process if C<pid> is specified as C<0>). The callback can look
-at the C<rstatus> member of the C<ev_child> watcher structure to see
-the status word (use the macros from C<sys/wait.h> and see your systems
-C<waitpid> documentation). The C<rpid> member contains the pid of the
-process causing the status change. C<trace> must be either C<0> (only
-activate the watcher when the process terminates) or C<1> (additionally
-activate the watcher when the process is stopped or continued).
-
-=item int pid [read-only]
-
-The process id this watcher watches out for, or C<0>, meaning any process id.
-
-=item int rpid [read-write]
-
-The process id that detected a status change.
-
-=item int rstatus [read-write]
-
-The process exit/trace status caused by C<rpid> (see your systems
-C<waitpid> and C<sys/wait.h> documentation for details).
-
-=back
-
-=head3 Examples
-
-Example: C<fork()> a new process and install a child handler to wait for
-its completion.
-
- ev_child cw;
-
- static void
- child_cb (EV_P_ ev_child *w, int revents)
- {
- ev_child_stop (EV_A_ w);
- printf ("process %d exited with status %x\n", w->rpid, w->rstatus);
- }
-
- pid_t pid = fork ();
-
- if (pid < 0)
- // error
- else if (pid == 0)
- {
- // the forked child executes here
- exit (1);
- }
- else
- {
- ev_child_init (&cw, child_cb, pid, 0);
- ev_child_start (EV_DEFAULT_ &cw);
- }
-
-
-=head2 C<ev_stat> - did the file attributes just change?
-
-This watches a file system path for attribute changes. That is, it calls
-C<stat> on that path in regular intervals (or when the OS says it changed)
-and sees if it changed compared to the last time, invoking the callback if
-it did.
-
-The path does not need to exist: changing from "path exists" to "path does
-not exist" is a status change like any other. The condition "path does not
-exist" (or more correctly "path cannot be stat'ed") is signified by the
-C<st_nlink> field being zero (which is otherwise always forced to be at
-least one) and all the other fields of the stat buffer having unspecified
-contents.
-
-The path I<must not> end in a slash or contain special components such as
-C<.> or C<..>. The path I<should> be absolute: If it is relative and
-your working directory changes, then the behaviour is undefined.
-
-Since there is no portable change notification interface available, the
-portable implementation simply calls C<stat(2)> regularly on the path
-to see if it changed somehow. You can specify a recommended polling
-interval for this case. If you specify a polling interval of C<0> (highly
-recommended!) then a I<suitable, unspecified default> value will be used
-(which you can expect to be around five seconds, although this might
-change dynamically). Libev will also impose a minimum interval which is
-currently around C<0.1>, but that's usually overkill.
-
-This watcher type is not meant for massive numbers of stat watchers,
-as even with OS-supported change notifications, this can be
-resource-intensive.
-
-At the time of this writing, the only OS-specific interface implemented
-is the Linux inotify interface (implementing kqueue support is left as an
-exercise for the reader. Note, however, that the author sees no way of
-implementing C<ev_stat> semantics with kqueue, except as a hint).
-
-=head3 ABI Issues (Largefile Support)
-
-Libev by default (unless the user overrides this) uses the default
-compilation environment, which means that on systems with large file
-support disabled by default, you get the 32 bit version of the stat
-structure. When using the library from programs that change the ABI to
-use 64 bit file offsets the programs will fail. In that case you have to
-compile libev with the same flags to get binary compatibility. This is
-obviously the case with any flags that change the ABI, but the problem is
-most noticeably displayed with ev_stat and large file support.
-
-The solution for this is to lobby your distribution maker to make large
-file interfaces available by default (as e.g. FreeBSD does) and not
-optional. Libev cannot simply switch on large file support because it has
-to exchange stat structures with application programs compiled using the
-default compilation environment.
-
-=head3 Inotify and Kqueue
-
-When C<inotify (7)> support has been compiled into libev and present at
-runtime, it will be used to speed up change detection where possible. The
-inotify descriptor will be created lazily when the first C<ev_stat>
-watcher is being started.
-
-Inotify presence does not change the semantics of C<ev_stat> watchers
-except that changes might be detected earlier, and in some cases, to avoid
-making regular C<stat> calls. Even in the presence of inotify support
-there are many cases where libev has to resort to regular C<stat> polling,
-but as long as kernel 2.6.25 or newer is used (2.6.24 and older have too
-many bugs), the path exists (i.e. stat succeeds), and the path resides on
-a local filesystem (libev currently assumes only ext2/3, jfs, reiserfs and
-xfs are fully working) libev usually gets away without polling.
-
-There is no support for kqueue, as apparently it cannot be used to
-implement this functionality, due to the requirement of having a file
-descriptor open on the object at all times, and detecting renames, unlinks
-etc. is difficult.
-
-=head3 C<stat ()> is a synchronous operation
-
-Libev doesn't normally do any kind of I/O itself, and so is not blocking
-the process. The exception are C<ev_stat> watchers - those call C<stat
-()>, which is a synchronous operation.
-
-For local paths, this usually doesn't matter: unless the system is very
-busy or the intervals between stat's are large, a stat call will be fast,
-as the path data is usually in memory already (except when starting the
-watcher).
-
-For networked file systems, calling C<stat ()> can block an indefinite
-time due to network issues, and even under good conditions, a stat call
-often takes multiple milliseconds.
-
-Therefore, it is best to avoid using C<ev_stat> watchers on networked
-paths, although this is fully supported by libev.
-
-=head3 The special problem of stat time resolution
-
-The C<stat ()> system call only supports full-second resolution portably,
-and even on systems where the resolution is higher, most file systems
-still only support whole seconds.
-
-That means that, if the time is the only thing that changes, you can
-easily miss updates: on the first update, C<ev_stat> detects a change and
-calls your callback, which does something. When there is another update
-within the same second, C<ev_stat> will be unable to detect unless the
-stat data does change in other ways (e.g. file size).
-
-The solution to this is to delay acting on a change for slightly more
-than a second (or till slightly after the next full second boundary), using
-a roughly one-second-delay C<ev_timer> (e.g. C<ev_timer_set (w, 0., 1.02);
-ev_timer_again (loop, w)>).
-
-The C<.02> offset is added to work around small timing inconsistencies
-of some operating systems (where the second counter of the current time
-might be be delayed. One such system is the Linux kernel, where a call to
-C<gettimeofday> might return a timestamp with a full second later than
-a subsequent C<time> call - if the equivalent of C<time ()> is used to
-update file times then there will be a small window where the kernel uses
-the previous second to update file times but libev might already execute
-the timer callback).
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_stat_init (ev_stat *, callback, const char *path, ev_tstamp interval)
-
-=item ev_stat_set (ev_stat *, const char *path, ev_tstamp interval)
-
-Configures the watcher to wait for status changes of the given
-C<path>. The C<interval> is a hint on how quickly a change is expected to
-be detected and should normally be specified as C<0> to let libev choose
-a suitable value. The memory pointed to by C<path> must point to the same
-path for as long as the watcher is active.
-
-The callback will receive an C<EV_STAT> event when a change was detected,
-relative to the attributes at the time the watcher was started (or the
-last change was detected).
-
-=item ev_stat_stat (loop, ev_stat *)
-
-Updates the stat buffer immediately with new values. If you change the
-watched path in your callback, you could call this function to avoid
-detecting this change (while introducing a race condition if you are not
-the only one changing the path). Can also be useful simply to find out the
-new values.
-
-=item ev_statdata attr [read-only]
-
-The most-recently detected attributes of the file. Although the type is
-C<ev_statdata>, this is usually the (or one of the) C<struct stat> types
-suitable for your system, but you can only rely on the POSIX-standardised
-members to be present. If the C<st_nlink> member is C<0>, then there was
-some error while C<stat>ing the file.
-
-=item ev_statdata prev [read-only]
-
-The previous attributes of the file. The callback gets invoked whenever
-C<prev> != C<attr>, or, more precisely, one or more of these members
-differ: C<st_dev>, C<st_ino>, C<st_mode>, C<st_nlink>, C<st_uid>,
-C<st_gid>, C<st_rdev>, C<st_size>, C<st_atime>, C<st_mtime>, C<st_ctime>.
-
-=item ev_tstamp interval [read-only]
-
-The specified interval.
-
-=item const char *path [read-only]
-
-The file system path that is being watched.
-
-=back
-
-=head3 Examples
-
-Example: Watch C</etc/passwd> for attribute changes.
-
- static void
- passwd_cb (struct ev_loop *loop, ev_stat *w, int revents)
- {
- /* /etc/passwd changed in some way */
- if (w->attr.st_nlink)
- {
- printf ("passwd current size %ld\n", (long)w->attr.st_size);
- printf ("passwd current atime %ld\n", (long)w->attr.st_mtime);
- printf ("passwd current mtime %ld\n", (long)w->attr.st_mtime);
- }
- else
- /* you shalt not abuse printf for puts */
- puts ("wow, /etc/passwd is not there, expect problems. "
- "if this is windows, they already arrived\n");
- }
-
- ...
- ev_stat passwd;
-
- ev_stat_init (&passwd, passwd_cb, "/etc/passwd", 0.);
- ev_stat_start (loop, &passwd);
-
-Example: Like above, but additionally use a one-second delay so we do not
-miss updates (however, frequent updates will delay processing, too, so
-one might do the work both on C<ev_stat> callback invocation I<and> on
-C<ev_timer> callback invocation).
-
- static ev_stat passwd;
- static ev_timer timer;
-
- static void
- timer_cb (EV_P_ ev_timer *w, int revents)
- {
- ev_timer_stop (EV_A_ w);
-
- /* now it's one second after the most recent passwd change */
- }
-
- static void
- stat_cb (EV_P_ ev_stat *w, int revents)
- {
- /* reset the one-second timer */
- ev_timer_again (EV_A_ &timer);
- }
-
- ...
- ev_stat_init (&passwd, stat_cb, "/etc/passwd", 0.);
- ev_stat_start (loop, &passwd);
- ev_timer_init (&timer, timer_cb, 0., 1.02);
-
-
-=head2 C<ev_idle> - when you've got nothing better to do...
-
-Idle watchers trigger events when no other events of the same or higher
-priority are pending (prepare, check and other idle watchers do not count
-as receiving "events").
-
-That is, as long as your process is busy handling sockets or timeouts
-(or even signals, imagine) of the same or higher priority it will not be
-triggered. But when your process is idle (or only lower-priority watchers
-are pending), the idle watchers are being called once per event loop
-iteration - until stopped, that is, or your process receives more events
-and becomes busy again with higher priority stuff.
-
-The most noteworthy effect is that as long as any idle watchers are
-active, the process will not block when waiting for new events.
-
-Apart from keeping your process non-blocking (which is a useful
-effect on its own sometimes), idle watchers are a good place to do
-"pseudo-background processing", or delay processing stuff to after the
-event loop has handled all outstanding events.
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_idle_init (ev_idle *, callback)
-
-Initialises and configures the idle watcher - it has no parameters of any
-kind. There is a C<ev_idle_set> macro, but using it is utterly pointless,
-believe me.
-
-=back
-
-=head3 Examples
-
-Example: Dynamically allocate an C<ev_idle> watcher, start it, and in the
-callback, free it. Also, use no error checking, as usual.
-
- static void
- idle_cb (struct ev_loop *loop, ev_idle *w, int revents)
- {
- free (w);
- // now do something you wanted to do when the program has
- // no longer anything immediate to do.
- }
-
- ev_idle *idle_watcher = malloc (sizeof (ev_idle));
- ev_idle_init (idle_watcher, idle_cb);
- ev_idle_start (loop, idle_watcher);
-
-
-=head2 C<ev_prepare> and C<ev_check> - customise your event loop!
-
-Prepare and check watchers are usually (but not always) used in pairs:
-prepare watchers get invoked before the process blocks and check watchers
-afterwards.
-
-You I<must not> call C<ev_run> or similar functions that enter
-the current event loop from either C<ev_prepare> or C<ev_check>
-watchers. Other loops than the current one are fine, however. The
-rationale behind this is that you do not need to check for recursion in
-those watchers, i.e. the sequence will always be C<ev_prepare>, blocking,
-C<ev_check> so if you have one watcher of each kind they will always be
-called in pairs bracketing the blocking call.
-
-Their main purpose is to integrate other event mechanisms into libev and
-their use is somewhat advanced. They could be used, for example, to track
-variable changes, implement your own watchers, integrate net-snmp or a
-coroutine library and lots more. They are also occasionally useful if
-you cache some data and want to flush it before blocking (for example,
-in X programs you might want to do an C<XFlush ()> in an C<ev_prepare>
-watcher).
-
-This is done by examining in each prepare call which file descriptors
-need to be watched by the other library, registering C<ev_io> watchers
-for them and starting an C<ev_timer> watcher for any timeouts (many
-libraries provide exactly this functionality). Then, in the check watcher,
-you check for any events that occurred (by checking the pending status
-of all watchers and stopping them) and call back into the library. The
-I/O and timer callbacks will never actually be called (but must be valid
-nevertheless, because you never know, you know?).
-
-As another example, the Perl Coro module uses these hooks to integrate
-coroutines into libev programs, by yielding to other active coroutines
-during each prepare and only letting the process block if no coroutines
-are ready to run (it's actually more complicated: it only runs coroutines
-with priority higher than or equal to the event loop and one coroutine
-of lower priority, but only once, using idle watchers to keep the event
-loop from blocking if lower-priority coroutines are active, thus mapping
-low-priority coroutines to idle/background tasks).
-
-It is recommended to give C<ev_check> watchers highest (C<EV_MAXPRI>)
-priority, to ensure that they are being run before any other watchers
-after the poll (this doesn't matter for C<ev_prepare> watchers).
-
-Also, C<ev_check> watchers (and C<ev_prepare> watchers, too) should not
-activate ("feed") events into libev. While libev fully supports this, they
-might get executed before other C<ev_check> watchers did their job. As
-C<ev_check> watchers are often used to embed other (non-libev) event
-loops those other event loops might be in an unusable state until their
-C<ev_check> watcher ran (always remind yourself to coexist peacefully with
-others).
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_prepare_init (ev_prepare *, callback)
-
-=item ev_check_init (ev_check *, callback)
-
-Initialises and configures the prepare or check watcher - they have no
-parameters of any kind. There are C<ev_prepare_set> and C<ev_check_set>
-macros, but using them is utterly, utterly, utterly and completely
-pointless.
-
-=back
-
-=head3 Examples
-
-There are a number of principal ways to embed other event loops or modules
-into libev. Here are some ideas on how to include libadns into libev
-(there is a Perl module named C<EV::ADNS> that does this, which you could
-use as a working example. Another Perl module named C<EV::Glib> embeds a
-Glib main context into libev, and finally, C<Glib::EV> embeds EV into the
-Glib event loop).
-
-Method 1: Add IO watchers and a timeout watcher in a prepare handler,
-and in a check watcher, destroy them and call into libadns. What follows
-is pseudo-code only of course. This requires you to either use a low
-priority for the check watcher or use C<ev_clear_pending> explicitly, as
-the callbacks for the IO/timeout watchers might not have been called yet.
-
- static ev_io iow [nfd];
- static ev_timer tw;
-
- static void
- io_cb (struct ev_loop *loop, ev_io *w, int revents)
- {
- }
-
- // create io watchers for each fd and a timer before blocking
- static void
- adns_prepare_cb (struct ev_loop *loop, ev_prepare *w, int revents)
- {
- int timeout = 3600000;
- struct pollfd fds [nfd];
- // actual code will need to loop here and realloc etc.
- adns_beforepoll (ads, fds, &nfd, &timeout, timeval_from (ev_time ()));
-
- /* the callback is illegal, but won't be called as we stop during check */
- ev_timer_init (&tw, 0, timeout * 1e-3, 0.);
- ev_timer_start (loop, &tw);
-
- // create one ev_io per pollfd
- for (int i = 0; i < nfd; ++i)
- {
- ev_io_init (iow + i, io_cb, fds [i].fd,
- ((fds [i].events & POLLIN ? EV_READ : 0)
- | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
-
- fds [i].revents = 0;
- ev_io_start (loop, iow + i);
- }
- }
-
- // stop all watchers after blocking
- static void
- adns_check_cb (struct ev_loop *loop, ev_check *w, int revents)
- {
- ev_timer_stop (loop, &tw);
-
- for (int i = 0; i < nfd; ++i)
- {
- // set the relevant poll flags
- // could also call adns_processreadable etc. here
- struct pollfd *fd = fds + i;
- int revents = ev_clear_pending (iow + i);
- if (revents & EV_READ ) fd->revents |= fd->events & POLLIN;
- if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT;
-
- // now stop the watcher
- ev_io_stop (loop, iow + i);
- }
-
- adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop));
- }
-
-Method 2: This would be just like method 1, but you run C<adns_afterpoll>
-in the prepare watcher and would dispose of the check watcher.
-
-Method 3: If the module to be embedded supports explicit event
-notification (libadns does), you can also make use of the actual watcher
-callbacks, and only destroy/create the watchers in the prepare watcher.
-
- static void
- timer_cb (EV_P_ ev_timer *w, int revents)
- {
- adns_state ads = (adns_state)w->data;
- update_now (EV_A);
-
- adns_processtimeouts (ads, &tv_now);
- }
-
- static void
- io_cb (EV_P_ ev_io *w, int revents)
- {
- adns_state ads = (adns_state)w->data;
- update_now (EV_A);
-
- if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now);
- if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now);
- }
-
- // do not ever call adns_afterpoll
-
-Method 4: Do not use a prepare or check watcher because the module you
-want to embed is not flexible enough to support it. Instead, you can
-override their poll function. The drawback with this solution is that the
-main loop is now no longer controllable by EV. The C<Glib::EV> module uses
-this approach, effectively embedding EV as a client into the horrible
-libglib event loop.
-
- static gint
- event_poll_func (GPollFD *fds, guint nfds, gint timeout)
- {
- int got_events = 0;
-
- for (n = 0; n < nfds; ++n)
- // create/start io watcher that sets the relevant bits in fds[n] and increment got_events
-
- if (timeout >= 0)
- // create/start timer
-
- // poll
- ev_run (EV_A_ 0);
-
- // stop timer again
- if (timeout >= 0)
- ev_timer_stop (EV_A_ &to);
-
- // stop io watchers again - their callbacks should have set
- for (n = 0; n < nfds; ++n)
- ev_io_stop (EV_A_ iow [n]);
-
- return got_events;
- }
-
-
-=head2 C<ev_embed> - when one backend isn't enough...
-
-This is a rather advanced watcher type that lets you embed one event loop
-into another (currently only C<ev_io> events are supported in the embedded
-loop, other types of watchers might be handled in a delayed or incorrect
-fashion and must not be used).
-
-There are primarily two reasons you would want that: work around bugs and
-prioritise I/O.
-
-As an example for a bug workaround, the kqueue backend might only support
-sockets on some platform, so it is unusable as generic backend, but you
-still want to make use of it because you have many sockets and it scales
-so nicely. In this case, you would create a kqueue-based loop and embed
-it into your default loop (which might use e.g. poll). Overall operation
-will be a bit slower because first libev has to call C<poll> and then
-C<kevent>, but at least you can use both mechanisms for what they are
-best: C<kqueue> for scalable sockets and C<poll> if you want it to work :)
-
-As for prioritising I/O: under rare circumstances you have the case where
-some fds have to be watched and handled very quickly (with low latency),
-and even priorities and idle watchers might have too much overhead. In
-this case you would put all the high priority stuff in one loop and all
-the rest in a second one, and embed the second one in the first.
-
-As long as the watcher is active, the callback will be invoked every
-time there might be events pending in the embedded loop. The callback
-must then call C<ev_embed_sweep (mainloop, watcher)> to make a single
-sweep and invoke their callbacks (the callback doesn't need to invoke the
-C<ev_embed_sweep> function directly, it could also start an idle watcher
-to give the embedded loop strictly lower priority for example).
-
-You can also set the callback to C<0>, in which case the embed watcher
-will automatically execute the embedded loop sweep whenever necessary.
-
-Fork detection will be handled transparently while the C<ev_embed> watcher
-is active, i.e., the embedded loop will automatically be forked when the
-embedding loop forks. In other cases, the user is responsible for calling
-C<ev_loop_fork> on the embedded loop.
-
-Unfortunately, not all backends are embeddable: only the ones returned by
-C<ev_embeddable_backends> are, which, unfortunately, does not include any
-portable one.
-
-So when you want to use this feature you will always have to be prepared
-that you cannot get an embeddable loop. The recommended way to get around
-this is to have a separate variables for your embeddable loop, try to
-create it, and if that fails, use the normal loop for everything.
-
-=head3 C<ev_embed> and fork
-
-While the C<ev_embed> watcher is running, forks in the embedding loop will
-automatically be applied to the embedded loop as well, so no special
-fork handling is required in that case. When the watcher is not running,
-however, it is still the task of the libev user to call C<ev_loop_fork ()>
-as applicable.
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)
-
-=item ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)
-
-Configures the watcher to embed the given loop, which must be
-embeddable. If the callback is C<0>, then C<ev_embed_sweep> will be
-invoked automatically, otherwise it is the responsibility of the callback
-to invoke it (it will continue to be called until the sweep has been done,
-if you do not want that, you need to temporarily stop the embed watcher).
-
-=item ev_embed_sweep (loop, ev_embed *)
-
-Make a single, non-blocking sweep over the embedded loop. This works
-similarly to C<ev_run (embedded_loop, EVRUN_NOWAIT)>, but in the most
-appropriate way for embedded loops.
-
-=item struct ev_loop *other [read-only]
-
-The embedded event loop.
-
-=back
-
-=head3 Examples
-
-Example: Try to get an embeddable event loop and embed it into the default
-event loop. If that is not possible, use the default loop. The default
-loop is stored in C<loop_hi>, while the embeddable loop is stored in
-C<loop_lo> (which is C<loop_hi> in the case no embeddable loop can be
-used).
-
- struct ev_loop *loop_hi = ev_default_init (0);
- struct ev_loop *loop_lo = 0;
- ev_embed embed;
-
- // see if there is a chance of getting one that works
- // (remember that a flags value of 0 means autodetection)
- loop_lo = ev_embeddable_backends () & ev_recommended_backends ()
- ? ev_loop_new (ev_embeddable_backends () & ev_recommended_backends ())
- : 0;
-
- // if we got one, then embed it, otherwise default to loop_hi
- if (loop_lo)
- {
- ev_embed_init (&embed, 0, loop_lo);
- ev_embed_start (loop_hi, &embed);
- }
- else
- loop_lo = loop_hi;
-
-Example: Check if kqueue is available but not recommended and create
-a kqueue backend for use with sockets (which usually work with any
-kqueue implementation). Store the kqueue/socket-only event loop in
-C<loop_socket>. (One might optionally use C<EVFLAG_NOENV>, too).
-
- struct ev_loop *loop = ev_default_init (0);
- struct ev_loop *loop_socket = 0;
- ev_embed embed;
-
- if (ev_supported_backends () & ~ev_recommended_backends () & EVBACKEND_KQUEUE)
- if ((loop_socket = ev_loop_new (EVBACKEND_KQUEUE))
- {
- ev_embed_init (&embed, 0, loop_socket);
- ev_embed_start (loop, &embed);
- }
-
- if (!loop_socket)
- loop_socket = loop;
-
- // now use loop_socket for all sockets, and loop for everything else
-
-
-=head2 C<ev_fork> - the audacity to resume the event loop after a fork
-
-Fork watchers are called when a C<fork ()> was detected (usually because
-whoever is a good citizen cared to tell libev about it by calling
-C<ev_default_fork> or C<ev_loop_fork>). The invocation is done before the
-event loop blocks next and before C<ev_check> watchers are being called,
-and only in the child after the fork. If whoever good citizen calling
-C<ev_default_fork> cheats and calls it in the wrong process, the fork
-handlers will be invoked, too, of course.
-
-=head3 The special problem of life after fork - how is it possible?
-
-Most uses of C<fork()> consist of forking, then some simple calls to set
-up/change the process environment, followed by a call to C<exec()>. This
-sequence should be handled by libev without any problems.
-
-This changes when the application actually wants to do event handling
-in the child, or both parent in child, in effect "continuing" after the
-fork.
-
-The default mode of operation (for libev, with application help to detect
-forks) is to duplicate all the state in the child, as would be expected
-when I<either> the parent I<or> the child process continues.
-
-When both processes want to continue using libev, then this is usually the
-wrong result. In that case, usually one process (typically the parent) is
-supposed to continue with all watchers in place as before, while the other
-process typically wants to start fresh, i.e. without any active watchers.
-
-The cleanest and most efficient way to achieve that with libev is to
-simply create a new event loop, which of course will be "empty", and
-use that for new watchers. This has the advantage of not touching more
-memory than necessary, and thus avoiding the copy-on-write, and the
-disadvantage of having to use multiple event loops (which do not support
-signal watchers).
-
-When this is not possible, or you want to use the default loop for
-other reasons, then in the process that wants to start "fresh", call
-C<ev_loop_destroy (EV_DEFAULT)> followed by C<ev_default_loop (...)>.
-Destroying the default loop will "orphan" (not stop) all registered
-watchers, so you have to be careful not to execute code that modifies
-those watchers. Note also that in that case, you have to re-register any
-signal watchers.
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_fork_init (ev_fork *, callback)
-
-Initialises and configures the fork watcher - it has no parameters of any
-kind. There is a C<ev_fork_set> macro, but using it is utterly pointless,
-really.
-
-=back
-
-
-=head2 C<ev_cleanup> - even the best things end
-
-Cleanup watchers are called just before the event loop is being destroyed
-by a call to C<ev_loop_destroy>.
-
-While there is no guarantee that the event loop gets destroyed, cleanup
-watchers provide a convenient method to install cleanup hooks for your
-program, worker threads and so on - you just to make sure to destroy the
-loop when you want them to be invoked.
-
-Cleanup watchers are invoked in the same way as any other watcher. Unlike
-all other watchers, they do not keep a reference to the event loop (which
-makes a lot of sense if you think about it). Like all other watchers, you
-can call libev functions in the callback, except C<ev_cleanup_start>.
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_cleanup_init (ev_cleanup *, callback)
-
-Initialises and configures the cleanup watcher - it has no parameters of
-any kind. There is a C<ev_cleanup_set> macro, but using it is utterly
-pointless, I assure you.
-
-=back
-
-Example: Register an atexit handler to destroy the default loop, so any
-cleanup functions are called.
-
- static void
- program_exits (void)
- {
- ev_loop_destroy (EV_DEFAULT_UC);
- }
-
- ...
- atexit (program_exits);
-
-
-=head2 C<ev_async> - how to wake up an event loop
-
-In general, you cannot use an C<ev_loop> from multiple threads or other
-asynchronous sources such as signal handlers (as opposed to multiple event
-loops - those are of course safe to use in different threads).
-
-Sometimes, however, you need to wake up an event loop you do not control,
-for example because it belongs to another thread. This is what C<ev_async>
-watchers do: as long as the C<ev_async> watcher is active, you can signal
-it by calling C<ev_async_send>, which is thread- and signal safe.
-
-This functionality is very similar to C<ev_signal> watchers, as signals,
-too, are asynchronous in nature, and signals, too, will be compressed
-(i.e. the number of callback invocations may be less than the number of
-C<ev_async_sent> calls). In fact, you could use signal watchers as a kind
-of "global async watchers" by using a watcher on an otherwise unused
-signal, and C<ev_feed_signal> to signal this watcher from another thread,
-even without knowing which loop owns the signal.
-
-Unlike C<ev_signal> watchers, C<ev_async> works with any event loop, not
-just the default loop.
-
-=head3 Queueing
-
-C<ev_async> does not support queueing of data in any way. The reason
-is that the author does not know of a simple (or any) algorithm for a
-multiple-writer-single-reader queue that works in all cases and doesn't
-need elaborate support such as pthreads or unportable memory access
-semantics.
-
-That means that if you want to queue data, you have to provide your own
-queue. But at least I can tell you how to implement locking around your
-queue:
-
-=over 4
-
-=item queueing from a signal handler context
-
-To implement race-free queueing, you simply add to the queue in the signal
-handler but you block the signal handler in the watcher callback. Here is
-an example that does that for some fictitious SIGUSR1 handler:
-
- static ev_async mysig;
-
- static void
- sigusr1_handler (void)
- {
- sometype data;
-
- // no locking etc.
- queue_put (data);
- ev_async_send (EV_DEFAULT_ &mysig);
- }
-
- static void
- mysig_cb (EV_P_ ev_async *w, int revents)
- {
- sometype data;
- sigset_t block, prev;
-
- sigemptyset (&block);
- sigaddset (&block, SIGUSR1);
- sigprocmask (SIG_BLOCK, &block, &prev);
-
- while (queue_get (&data))
- process (data);
-
- if (sigismember (&prev, SIGUSR1)
- sigprocmask (SIG_UNBLOCK, &block, 0);
- }
-
-(Note: pthreads in theory requires you to use C<pthread_setmask>
-instead of C<sigprocmask> when you use threads, but libev doesn't do it
-either...).
-
-=item queueing from a thread context
-
-The strategy for threads is different, as you cannot (easily) block
-threads but you can easily preempt them, so to queue safely you need to
-employ a traditional mutex lock, such as in this pthread example:
-
- static ev_async mysig;
- static pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
-
- static void
- otherthread (void)
- {
- // only need to lock the actual queueing operation
- pthread_mutex_lock (&mymutex);
- queue_put (data);
- pthread_mutex_unlock (&mymutex);
-
- ev_async_send (EV_DEFAULT_ &mysig);
- }
-
- static void
- mysig_cb (EV_P_ ev_async *w, int revents)
- {
- pthread_mutex_lock (&mymutex);
-
- while (queue_get (&data))
- process (data);
-
- pthread_mutex_unlock (&mymutex);
- }
-
-=back
-
-
-=head3 Watcher-Specific Functions and Data Members
-
-=over 4
-
-=item ev_async_init (ev_async *, callback)
-
-Initialises and configures the async watcher - it has no parameters of any
-kind. There is a C<ev_async_set> macro, but using it is utterly pointless,
-trust me.
-
-=item ev_async_send (loop, ev_async *)
-
-Sends/signals/activates the given C<ev_async> watcher, that is, feeds
-an C<EV_ASYNC> event on the watcher into the event loop, and instantly
-returns.
-
-Unlike C<ev_feed_event>, this call is safe to do from other threads,
-signal or similar contexts (see the discussion of C<EV_ATOMIC_T> in the
-embedding section below on what exactly this means).
-
-Note that, as with other watchers in libev, multiple events might get
-compressed into a single callback invocation (another way to look at this
-is that C<ev_async> watchers are level-triggered, set on C<ev_async_send>,
-reset when the event loop detects that).
-
-This call incurs the overhead of a system call only once per event loop
-iteration, so while the overhead might be noticeable, it doesn't apply to
-repeated calls to C<ev_async_send> for the same event loop.
-
-=item bool = ev_async_pending (ev_async *)
-
-Returns a non-zero value when C<ev_async_send> has been called on the
-watcher but the event has not yet been processed (or even noted) by the
-event loop.
-
-C<ev_async_send> sets a flag in the watcher and wakes up the loop. When
-the loop iterates next and checks for the watcher to have become active,
-it will reset the flag again. C<ev_async_pending> can be used to very
-quickly check whether invoking the loop might be a good idea.
-
-Not that this does I<not> check whether the watcher itself is pending,
-only whether it has been requested to make this watcher pending: there
-is a time window between the event loop checking and resetting the async
-notification, and the callback being invoked.
-
-=back
-
-
-=head1 OTHER FUNCTIONS
-
-There are some other functions of possible interest. Described. Here. Now.
-
-=over 4
-
-=item ev_once (loop, int fd, int events, ev_tstamp timeout, callback)
-
-This function combines a simple timer and an I/O watcher, calls your
-callback on whichever event happens first and automatically stops both
-watchers. This is useful if you want to wait for a single event on an fd
-or timeout without having to allocate/configure/start/stop/free one or
-more watchers yourself.
-
-If C<fd> is less than 0, then no I/O watcher will be started and the
-C<events> argument is being ignored. Otherwise, an C<ev_io> watcher for
-the given C<fd> and C<events> set will be created and started.
-
-If C<timeout> is less than 0, then no timeout watcher will be
-started. Otherwise an C<ev_timer> watcher with after = C<timeout> (and
-repeat = 0) will be started. C<0> is a valid timeout.
-
-The callback has the type C<void (*cb)(int revents, void *arg)> and is
-passed an C<revents> set like normal event callbacks (a combination of
-C<EV_ERROR>, C<EV_READ>, C<EV_WRITE> or C<EV_TIMER>) and the C<arg>
-value passed to C<ev_once>. Note that it is possible to receive I<both>
-a timeout and an io event at the same time - you probably should give io
-events precedence.
-
-Example: wait up to ten seconds for data to appear on STDIN_FILENO.
-
- static void stdin_ready (int revents, void *arg)
- {
- if (revents & EV_READ)
- /* stdin might have data for us, joy! */;
- else if (revents & EV_TIMER)
- /* doh, nothing entered */;
- }
-
- ev_once (STDIN_FILENO, EV_READ, 10., stdin_ready, 0);
-
-=item ev_feed_fd_event (loop, int fd, int revents)
-
-Feed an event on the given fd, as if a file descriptor backend detected
-the given events it.
-
-=item ev_feed_signal_event (loop, int signum)
-
-Feed an event as if the given signal occurred. See also C<ev_feed_signal>,
-which is async-safe.
-
-=back
-
-
-=head1 COMMON OR USEFUL IDIOMS (OR BOTH)
-
-This section explains some common idioms that are not immediately
-obvious. Note that examples are sprinkled over the whole manual, and this
-section only contains stuff that wouldn't fit anywhere else.
-
-=head2 ASSOCIATING CUSTOM DATA WITH A WATCHER
-
-Each watcher has, by default, a C<void *data> member that you can read
-or modify at any time: libev will completely ignore it. This can be used
-to associate arbitrary data with your watcher. If you need more data and
-don't want to allocate memory separately and store a pointer to it in that
-data member, you can also "subclass" the watcher type and provide your own
-data:
-
- struct my_io
- {
- ev_io io;
- int otherfd;
- void *somedata;
- struct whatever *mostinteresting;
- };
-
- ...
- struct my_io w;
- ev_io_init (&w.io, my_cb, fd, EV_READ);
-
-And since your callback will be called with a pointer to the watcher, you
-can cast it back to your own type:
-
- static void my_cb (struct ev_loop *loop, ev_io *w_, int revents)
- {
- struct my_io *w = (struct my_io *)w_;
- ...
- }
-
-More interesting and less C-conformant ways of casting your callback
-function type instead have been omitted.
-
-=head2 BUILDING YOUR OWN COMPOSITE WATCHERS
-
-Another common scenario is to use some data structure with multiple
-embedded watchers, in effect creating your own watcher that combines
-multiple libev event sources into one "super-watcher":
-
- struct my_biggy
- {
- int some_data;
- ev_timer t1;
- ev_timer t2;
- }
-
-In this case getting the pointer to C<my_biggy> is a bit more
-complicated: Either you store the address of your C<my_biggy> struct in
-the C<data> member of the watcher (for woozies or C++ coders), or you need
-to use some pointer arithmetic using C<offsetof> inside your watchers (for
-real programmers):
-
- #include <stddef.h>
-
- static void
- t1_cb (EV_P_ ev_timer *w, int revents)
- {
- struct my_biggy big = (struct my_biggy *)
- (((char *)w) - offsetof (struct my_biggy, t1));
- }
-
- static void
- t2_cb (EV_P_ ev_timer *w, int revents)
- {
- struct my_biggy big = (struct my_biggy *)
- (((char *)w) - offsetof (struct my_biggy, t2));
- }
-
-=head2 MODEL/NESTED EVENT LOOP INVOCATIONS AND EXIT CONDITIONS
-
-Often (especially in GUI toolkits) there are places where you have
-I<modal> interaction, which is most easily implemented by recursively
-invoking C<ev_run>.
-
-This brings the problem of exiting - a callback might want to finish the
-main C<ev_run> call, but not the nested one (e.g. user clicked "Quit", but
-a modal "Are you sure?" dialog is still waiting), or just the nested one
-and not the main one (e.g. user clocked "Ok" in a modal dialog), or some
-other combination: In these cases, C<ev_break> will not work alone.
-
-The solution is to maintain "break this loop" variable for each C<ev_run>
-invocation, and use a loop around C<ev_run> until the condition is
-triggered, using C<EVRUN_ONCE>:
-
- // main loop
- int exit_main_loop = 0;
-
- while (!exit_main_loop)
- ev_run (EV_DEFAULT_ EVRUN_ONCE);
-
- // in a model watcher
- int exit_nested_loop = 0;
-
- while (!exit_nested_loop)
- ev_run (EV_A_ EVRUN_ONCE);
-
-To exit from any of these loops, just set the corresponding exit variable:
-
- // exit modal loop
- exit_nested_loop = 1;
-
- // exit main program, after modal loop is finished
- exit_main_loop = 1;
-
- // exit both
- exit_main_loop = exit_nested_loop = 1;
-
-=head2 THREAD LOCKING EXAMPLE
-
-Here is a fictitious example of how to run an event loop in a different
-thread from where callbacks are being invoked and watchers are
-created/added/removed.
-
-For a real-world example, see the C<EV::Loop::Async> perl module,
-which uses exactly this technique (which is suited for many high-level
-languages).
-
-The example uses a pthread mutex to protect the loop data, a condition
-variable to wait for callback invocations, an async watcher to notify the
-event loop thread and an unspecified mechanism to wake up the main thread.
-
-First, you need to associate some data with the event loop:
-
- typedef struct {
- mutex_t lock; /* global loop lock */
- ev_async async_w;
- thread_t tid;
- cond_t invoke_cv;
- } userdata;
-
- void prepare_loop (EV_P)
- {
- // for simplicity, we use a static userdata struct.
- static userdata u;
-
- ev_async_init (&u->async_w, async_cb);
- ev_async_start (EV_A_ &u->async_w);
-
- pthread_mutex_init (&u->lock, 0);
- pthread_cond_init (&u->invoke_cv, 0);
-
- // now associate this with the loop
- ev_set_userdata (EV_A_ u);
- ev_set_invoke_pending_cb (EV_A_ l_invoke);
- ev_set_loop_release_cb (EV_A_ l_release, l_acquire);
-
- // then create the thread running ev_run
- pthread_create (&u->tid, 0, l_run, EV_A);
- }
-
-The callback for the C<ev_async> watcher does nothing: the watcher is used
-solely to wake up the event loop so it takes notice of any new watchers
-that might have been added:
-
- static void
- async_cb (EV_P_ ev_async *w, int revents)
- {
- // just used for the side effects
- }
-
-The C<l_release> and C<l_acquire> callbacks simply unlock/lock the mutex
-protecting the loop data, respectively.
-
- static void
- l_release (EV_P)
- {
- userdata *u = ev_userdata (EV_A);
- pthread_mutex_unlock (&u->lock);
- }
-
- static void
- l_acquire (EV_P)
- {
- userdata *u = ev_userdata (EV_A);
- pthread_mutex_lock (&u->lock);
- }
-
-The event loop thread first acquires the mutex, and then jumps straight
-into C<ev_run>:
-
- void *
- l_run (void *thr_arg)
- {
- struct ev_loop *loop = (struct ev_loop *)thr_arg;
-
- l_acquire (EV_A);
- pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
- ev_run (EV_A_ 0);
- l_release (EV_A);
-
- return 0;
- }
-
-Instead of invoking all pending watchers, the C<l_invoke> callback will
-signal the main thread via some unspecified mechanism (signals? pipe
-writes? C<Async::Interrupt>?) and then waits until all pending watchers
-have been called (in a while loop because a) spurious wakeups are possible
-and b) skipping inter-thread-communication when there are no pending
-watchers is very beneficial):
-
- static void
- l_invoke (EV_P)
- {
- userdata *u = ev_userdata (EV_A);
-
- while (ev_pending_count (EV_A))
- {
- wake_up_other_thread_in_some_magic_or_not_so_magic_way ();
- pthread_cond_wait (&u->invoke_cv, &u->lock);
- }
- }
-
-Now, whenever the main thread gets told to invoke pending watchers, it
-will grab the lock, call C<ev_invoke_pending> and then signal the loop
-thread to continue:
-
- static void
- real_invoke_pending (EV_P)
- {
- userdata *u = ev_userdata (EV_A);
-
- pthread_mutex_lock (&u->lock);
- ev_invoke_pending (EV_A);
- pthread_cond_signal (&u->invoke_cv);
- pthread_mutex_unlock (&u->lock);
- }
-
-Whenever you want to start/stop a watcher or do other modifications to an
-event loop, you will now have to lock:
-
- ev_timer timeout_watcher;
- userdata *u = ev_userdata (EV_A);
-
- ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
-
- pthread_mutex_lock (&u->lock);
- ev_timer_start (EV_A_ &timeout_watcher);
- ev_async_send (EV_A_ &u->async_w);
- pthread_mutex_unlock (&u->lock);
-
-Note that sending the C<ev_async> watcher is required because otherwise
-an event loop currently blocking in the kernel will have no knowledge
-about the newly added timer. By waking up the loop it will pick up any new
-watchers in the next event loop iteration.
-
-=head2 THREADS, COROUTINES, CONTINUATIONS, QUEUES... INSTEAD OF CALLBACKS
-
-While the overhead of a callback that e.g. schedules a thread is small, it
-is still an overhead. If you embed libev, and your main usage is with some
-kind of threads or coroutines, you might want to customise libev so that
-doesn't need callbacks anymore.
-
-Imagine you have coroutines that you can switch to using a function
-C<switch_to (coro)>, that libev runs in a coroutine called C<libev_coro>
-and that due to some magic, the currently active coroutine is stored in a
-global called C<current_coro>. Then you can build your own "wait for libev
-event" primitive by changing C<EV_CB_DECLARE> and C<EV_CB_INVOKE> (note
-the differing C<;> conventions):
-
- #define EV_CB_DECLARE(type) struct my_coro *cb;
- #define EV_CB_INVOKE(watcher) switch_to ((watcher)->cb)
-
-That means instead of having a C callback function, you store the
-coroutine to switch to in each watcher, and instead of having libev call
-your callback, you instead have it switch to that coroutine.
-
-A coroutine might now wait for an event with a function called
-C<wait_for_event>. (the watcher needs to be started, as always, but it doesn't
-matter when, or whether the watcher is active or not when this function is
-called):
-
- void
- wait_for_event (ev_watcher *w)
- {
- ev_cb_set (w) = current_coro;
- switch_to (libev_coro);
- }
-
-That basically suspends the coroutine inside C<wait_for_event> and
-continues the libev coroutine, which, when appropriate, switches back to
-this or any other coroutine. I am sure if you sue this your own :)
-
-You can do similar tricks if you have, say, threads with an event queue -
-instead of storing a coroutine, you store the queue object and instead of
-switching to a coroutine, you push the watcher onto the queue and notify
-any waiters.
-
-To embed libev, see L<EMBEDDING>, but in short, it's easiest to create two
-files, F<my_ev.h> and F<my_ev.c> that include the respective libev files:
-
- // my_ev.h
- #define EV_CB_DECLARE(type) struct my_coro *cb;
- #define EV_CB_INVOKE(watcher) switch_to ((watcher)->cb);
- #include "../libev/ev.h"
-
- // my_ev.c
- #define EV_H "my_ev.h"
- #include "../libev/ev.c"
-
-And then use F<my_ev.h> when you would normally use F<ev.h>, and compile
-F<my_ev.c> into your project. When properly specifying include paths, you
-can even use F<ev.h> as header file name directly.
-
-
-=head1 LIBEVENT EMULATION
-
-Libev offers a compatibility emulation layer for libevent. It cannot
-emulate the internals of libevent, so here are some usage hints:
-
-=over 4
-
-=item * Only the libevent-1.4.1-beta API is being emulated.
-
-This was the newest libevent version available when libev was implemented,
-and is still mostly unchanged in 2010.
-
-=item * Use it by including <event.h>, as usual.
-
-=item * The following members are fully supported: ev_base, ev_callback,
-ev_arg, ev_fd, ev_res, ev_events.
-
-=item * Avoid using ev_flags and the EVLIST_*-macros, while it is
-maintained by libev, it does not work exactly the same way as in libevent (consider
-it a private API).
-
-=item * Priorities are not currently supported. Initialising priorities
-will fail and all watchers will have the same priority, even though there
-is an ev_pri field.
-
-=item * In libevent, the last base created gets the signals, in libev, the
-base that registered the signal gets the signals.
-
-=item * Other members are not supported.
-
-=item * The libev emulation is I<not> ABI compatible to libevent, you need
-to use the libev header file and library.
-
-=back
-
-=head1 C++ SUPPORT
-
-Libev comes with some simplistic wrapper classes for C++ that mainly allow
-you to use some convenience methods to start/stop watchers and also change
-the callback model to a model using method callbacks on objects.
-
-To use it,
-
- #include <ev++.h>
-
-This automatically includes F<ev.h> and puts all of its definitions (many
-of them macros) into the global namespace. All C++ specific things are
-put into the C<ev> namespace. It should support all the same embedding
-options as F<ev.h>, most notably C<EV_MULTIPLICITY>.
-
-Care has been taken to keep the overhead low. The only data member the C++
-classes add (compared to plain C-style watchers) is the event loop pointer
-that the watcher is associated with (or no additional members at all if
-you disable C<EV_MULTIPLICITY> when embedding libev).
-
-Currently, functions, static and non-static member functions and classes
-with C<operator ()> can be used as callbacks. Other types should be easy
-to add as long as they only need one additional pointer for context. If
-you need support for other types of functors please contact the author
-(preferably after implementing it).
-
-Here is a list of things available in the C<ev> namespace:
-
-=over 4
-
-=item C<ev::READ>, C<ev::WRITE> etc.
-
-These are just enum values with the same values as the C<EV_READ> etc.
-macros from F<ev.h>.
-
-=item C<ev::tstamp>, C<ev::now>
-
-Aliases to the same types/functions as with the C<ev_> prefix.
-
-=item C<ev::io>, C<ev::timer>, C<ev::periodic>, C<ev::idle>, C<ev::sig> etc.
-
-For each C<ev_TYPE> watcher in F<ev.h> there is a corresponding class of
-the same name in the C<ev> namespace, with the exception of C<ev_signal>
-which is called C<ev::sig> to avoid clashes with the C<signal> macro
-defines by many implementations.
-
-All of those classes have these methods:
-
-=over 4
-
-=item ev::TYPE::TYPE ()
-
-=item ev::TYPE::TYPE (loop)
-
-=item ev::TYPE::~TYPE
-
-The constructor (optionally) takes an event loop to associate the watcher
-with. If it is omitted, it will use C<EV_DEFAULT>.
-
-The constructor calls C<ev_init> for you, which means you have to call the
-C<set> method before starting it.
-
-It will not set a callback, however: You have to call the templated C<set>
-method to set a callback before you can start the watcher.
-
-(The reason why you have to use a method is a limitation in C++ which does
-not allow explicit template arguments for constructors).
-
-The destructor automatically stops the watcher if it is active.
-
-=item w->set<class, &class::method> (object *)
-
-This method sets the callback method to call. The method has to have a
-signature of C<void (*)(ev_TYPE &, int)>, it receives the watcher as
-first argument and the C<revents> as second. The object must be given as
-parameter and is stored in the C<data> member of the watcher.
-
-This method synthesizes efficient thunking code to call your method from
-the C callback that libev requires. If your compiler can inline your
-callback (i.e. it is visible to it at the place of the C<set> call and
-your compiler is good :), then the method will be fully inlined into the
-thunking function, making it as fast as a direct C callback.
-
-Example: simple class declaration and watcher initialisation
-
- struct myclass
- {
- void io_cb (ev::io &w, int revents) { }
- }
-
- myclass obj;
- ev::io iow;
- iow.set <myclass, &myclass::io_cb> (&obj);
-
-=item w->set (object *)
-
-This is a variation of a method callback - leaving out the method to call
-will default the method to C<operator ()>, which makes it possible to use
-functor objects without having to manually specify the C<operator ()> all
-the time. Incidentally, you can then also leave out the template argument
-list.
-
-The C<operator ()> method prototype must be C<void operator ()(watcher &w,
-int revents)>.
-
-See the method-C<set> above for more details.
-
-Example: use a functor object as callback.
-
- struct myfunctor
- {
- void operator() (ev::io &w, int revents)
- {
- ...
- }
- }
-
- myfunctor f;
-
- ev::io w;
- w.set (&f);
-
-=item w->set<function> (void *data = 0)
-
-Also sets a callback, but uses a static method or plain function as
-callback. The optional C<data> argument will be stored in the watcher's
-C<data> member and is free for you to use.
-
-The prototype of the C<function> must be C<void (*)(ev::TYPE &w, int)>.
-
-See the method-C<set> above for more details.
-
-Example: Use a plain function as callback.
-
- static void io_cb (ev::io &w, int revents) { }
- iow.set <io_cb> ();
-
-=item w->set (loop)
-
-Associates a different C<struct ev_loop> with this watcher. You can only
-do this when the watcher is inactive (and not pending either).
-
-=item w->set ([arguments])
-
-Basically the same as C<ev_TYPE_set>, with the same arguments. Either this
-method or a suitable start method must be called at least once. Unlike the
-C counterpart, an active watcher gets automatically stopped and restarted
-when reconfiguring it with this method.
-
-=item w->start ()
-
-Starts the watcher. Note that there is no C<loop> argument, as the
-constructor already stores the event loop.
-
-=item w->start ([arguments])
-
-Instead of calling C<set> and C<start> methods separately, it is often
-convenient to wrap them in one call. Uses the same type of arguments as
-the configure C<set> method of the watcher.
-
-=item w->stop ()
-
-Stops the watcher if it is active. Again, no C<loop> argument.
-
-=item w->again () (C<ev::timer>, C<ev::periodic> only)
-
-For C<ev::timer> and C<ev::periodic>, this invokes the corresponding
-C<ev_TYPE_again> function.
-
-=item w->sweep () (C<ev::embed> only)
-
-Invokes C<ev_embed_sweep>.
-
-=item w->update () (C<ev::stat> only)
-
-Invokes C<ev_stat_stat>.
-
-=back
-
-=back
-
-Example: Define a class with two I/O and idle watchers, start the I/O
-watchers in the constructor.
-
- class myclass
- {
- ev::io io ; void io_cb (ev::io &w, int revents);
- ev::io2 io2 ; void io2_cb (ev::io &w, int revents);
- ev::idle idle; void idle_cb (ev::idle &w, int revents);
-
- myclass (int fd)
- {
- io .set <myclass, &myclass::io_cb > (this);
- io2 .set <myclass, &myclass::io2_cb > (this);
- idle.set <myclass, &myclass::idle_cb> (this);
-
- io.set (fd, ev::WRITE); // configure the watcher
- io.start (); // start it whenever convenient
-
- io2.start (fd, ev::READ); // set + start in one call
- }
- };
-
-
-=head1 OTHER LANGUAGE BINDINGS
-
-Libev does not offer other language bindings itself, but bindings for a
-number of languages exist in the form of third-party packages. If you know
-any interesting language binding in addition to the ones listed here, drop
-me a note.
-
-=over 4
-
-=item Perl
-
-The EV module implements the full libev API and is actually used to test
-libev. EV is developed together with libev. Apart from the EV core module,
-there are additional modules that implement libev-compatible interfaces
-to C<libadns> (C<EV::ADNS>, but C<AnyEvent::DNS> is preferred nowadays),
-C<Net::SNMP> (C<Net::SNMP::EV>) and the C<libglib> event core (C<Glib::EV>
-and C<EV::Glib>).
-
-It can be found and installed via CPAN, its homepage is at
-L<http://software.schmorp.de/pkg/EV>.
-
-=item Python
-
-Python bindings can be found at L<http://code.google.com/p/pyev/>. It
-seems to be quite complete and well-documented.
-
-=item Ruby
-
-Tony Arcieri has written a ruby extension that offers access to a subset
-of the libev API and adds file handle abstractions, asynchronous DNS and
-more on top of it. It can be found via gem servers. Its homepage is at
-L<http://rev.rubyforge.org/>.
-
-Roger Pack reports that using the link order C<-lws2_32 -lmsvcrt-ruby-190>
-makes rev work even on mingw.
-
-=item Haskell
-
-A haskell binding to libev is available at
-L<http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hlibev>.
-
-=item D
-
-Leandro Lucarella has written a D language binding (F<ev.d>) for libev, to
-be found at L<http://proj.llucax.com.ar/wiki/evd>.
-
-=item Ocaml
-
-Erkki Seppala has written Ocaml bindings for libev, to be found at
-L<http://modeemi.cs.tut.fi/~flux/software/ocaml-ev/>.
-
-=item Lua
-
-Brian Maher has written a partial interface to libev for lua (at the
-time of this writing, only C<ev_io> and C<ev_timer>), to be found at
-L<http://github.com/brimworks/lua-ev>.
-
-=back
-
-
-=head1 MACRO MAGIC
-
-Libev can be compiled with a variety of options, the most fundamental
-of which is C<EV_MULTIPLICITY>. This option determines whether (most)
-functions and callbacks have an initial C<struct ev_loop *> argument.
-
-To make it easier to write programs that cope with either variant, the
-following macros are defined:
-
-=over 4
-
-=item C<EV_A>, C<EV_A_>
-
-This provides the loop I<argument> for functions, if one is required ("ev
-loop argument"). The C<EV_A> form is used when this is the sole argument,
-C<EV_A_> is used when other arguments are following. Example:
-
- ev_unref (EV_A);
- ev_timer_add (EV_A_ watcher);
- ev_run (EV_A_ 0);
-
-It assumes the variable C<loop> of type C<struct ev_loop *> is in scope,
-which is often provided by the following macro.
-
-=item C<EV_P>, C<EV_P_>
-
-This provides the loop I<parameter> for functions, if one is required ("ev
-loop parameter"). The C<EV_P> form is used when this is the sole parameter,
-C<EV_P_> is used when other parameters are following. Example:
-
- // this is how ev_unref is being declared
- static void ev_unref (EV_P);
-
- // this is how you can declare your typical callback
- static void cb (EV_P_ ev_timer *w, int revents)
-
-It declares a parameter C<loop> of type C<struct ev_loop *>, quite
-suitable for use with C<EV_A>.
-
-=item C<EV_DEFAULT>, C<EV_DEFAULT_>
-
-Similar to the other two macros, this gives you the value of the default
-loop, if multiple loops are supported ("ev loop default").
-
-=item C<EV_DEFAULT_UC>, C<EV_DEFAULT_UC_>
-
-Usage identical to C<EV_DEFAULT> and C<EV_DEFAULT_>, but requires that the
-default loop has been initialised (C<UC> == unchecked). Their behaviour
-is undefined when the default loop has not been initialised by a previous
-execution of C<EV_DEFAULT>, C<EV_DEFAULT_> or C<ev_default_init (...)>.
-
-It is often prudent to use C<EV_DEFAULT> when initialising the first
-watcher in a function but use C<EV_DEFAULT_UC> afterwards.
-
-=back
-
-Example: Declare and initialise a check watcher, utilising the above
-macros so it will work regardless of whether multiple loops are supported
-or not.
-
- static void
- check_cb (EV_P_ ev_timer *w, int revents)
- {
- ev_check_stop (EV_A_ w);
- }
-
- ev_check check;
- ev_check_init (&check, check_cb);
- ev_check_start (EV_DEFAULT_ &check);
- ev_run (EV_DEFAULT_ 0);
-
-=head1 EMBEDDING
-
-Libev can (and often is) directly embedded into host
-applications. Examples of applications that embed it include the Deliantra
-Game Server, the EV perl module, the GNU Virtual Private Ethernet (gvpe)
-and rxvt-unicode.
-
-The goal is to enable you to just copy the necessary files into your
-source directory without having to change even a single line in them, so
-you can easily upgrade by simply copying (or having a checked-out copy of
-libev somewhere in your source tree).
-
-=head2 FILESETS
-
-Depending on what features you need you need to include one or more sets of files
-in your application.
-
-=head3 CORE EVENT LOOP
-
-To include only the libev core (all the C<ev_*> functions), with manual
-configuration (no autoconf):
-
- #define EV_STANDALONE 1
- #include "ev.c"
-
-This will automatically include F<ev.h>, too, and should be done in a
-single C source file only to provide the function implementations. To use
-it, do the same for F<ev.h> in all files wishing to use this API (best
-done by writing a wrapper around F<ev.h> that you can include instead and
-where you can put other configuration options):
-
- #define EV_STANDALONE 1
- #include "ev.h"
-
-Both header files and implementation files can be compiled with a C++
-compiler (at least, that's a stated goal, and breakage will be treated
-as a bug).
-
-You need the following files in your source tree, or in a directory
-in your include path (e.g. in libev/ when using -Ilibev):
-
- ev.h
- ev.c
- ev_vars.h
- ev_wrap.h
-
- ev_win32.c required on win32 platforms only
-
- ev_select.c only when select backend is enabled (which is enabled by default)
- ev_poll.c only when poll backend is enabled (disabled by default)
- ev_epoll.c only when the epoll backend is enabled (disabled by default)
- ev_kqueue.c only when the kqueue backend is enabled (disabled by default)
- ev_port.c only when the solaris port backend is enabled (disabled by default)
-
-F<ev.c> includes the backend files directly when enabled, so you only need
-to compile this single file.
-
-=head3 LIBEVENT COMPATIBILITY API
-
-To include the libevent compatibility API, also include:
-
- #include "event.c"
-
-in the file including F<ev.c>, and:
-
- #include "event.h"
-
-in the files that want to use the libevent API. This also includes F<ev.h>.
-
-You need the following additional files for this:
-
- event.h
- event.c
-
-=head3 AUTOCONF SUPPORT
-
-Instead of using C<EV_STANDALONE=1> and providing your configuration in
-whatever way you want, you can also C<m4_include([libev.m4])> in your
-F<configure.ac> and leave C<EV_STANDALONE> undefined. F<ev.c> will then
-include F<config.h> and configure itself accordingly.
-
-For this of course you need the m4 file:
-
- libev.m4
-
-=head2 PREPROCESSOR SYMBOLS/MACROS
-
-Libev can be configured via a variety of preprocessor symbols you have to
-define before including (or compiling) any of its files. The default in
-the absence of autoconf is documented for every option.
-
-Symbols marked with "(h)" do not change the ABI, and can have different
-values when compiling libev vs. including F<ev.h>, so it is permissible
-to redefine them before including F<ev.h> without breaking compatibility
-to a compiled library. All other symbols change the ABI, which means all
-users of libev and the libev code itself must be compiled with compatible
-settings.
-
-=over 4
-
-=item EV_COMPAT3 (h)
-
-Backwards compatibility is a major concern for libev. This is why this
-release of libev comes with wrappers for the functions and symbols that
-have been renamed between libev version 3 and 4.
-
-You can disable these wrappers (to test compatibility with future
-versions) by defining C<EV_COMPAT3> to C<0> when compiling your
-sources. This has the additional advantage that you can drop the C<struct>
-from C<struct ev_loop> declarations, as libev will provide an C<ev_loop>
-typedef in that case.
-
-In some future version, the default for C<EV_COMPAT3> will become C<0>,
-and in some even more future version the compatibility code will be
-removed completely.
-
-=item EV_STANDALONE (h)
-
-Must always be C<1> if you do not use autoconf configuration, which
-keeps libev from including F<config.h>, and it also defines dummy
-implementations for some libevent functions (such as logging, which is not
-supported). It will also not define any of the structs usually found in
-F<event.h> that are not directly supported by the libev core alone.
-
-In standalone mode, libev will still try to automatically deduce the
-configuration, but has to be more conservative.
-
-=item EV_USE_MONOTONIC
-
-If defined to be C<1>, libev will try to detect the availability of the
-monotonic clock option at both compile time and runtime. Otherwise no
-use of the monotonic clock option will be attempted. If you enable this,
-you usually have to link against librt or something similar. Enabling it
-when the functionality isn't available is safe, though, although you have
-to make sure you link against any libraries where the C<clock_gettime>
-function is hiding in (often F<-lrt>). See also C<EV_USE_CLOCK_SYSCALL>.
-
-=item EV_USE_REALTIME
-
-If defined to be C<1>, libev will try to detect the availability of the
-real-time clock option at compile time (and assume its availability
-at runtime if successful). Otherwise no use of the real-time clock
-option will be attempted. This effectively replaces C<gettimeofday>
-by C<clock_get (CLOCK_REALTIME, ...)> and will not normally affect
-correctness. See the note about libraries in the description of
-C<EV_USE_MONOTONIC>, though. Defaults to the opposite value of
-C<EV_USE_CLOCK_SYSCALL>.
-
-=item EV_USE_CLOCK_SYSCALL
-
-If defined to be C<1>, libev will try to use a direct syscall instead
-of calling the system-provided C<clock_gettime> function. This option
-exists because on GNU/Linux, C<clock_gettime> is in C<librt>, but C<librt>
-unconditionally pulls in C<libpthread>, slowing down single-threaded
-programs needlessly. Using a direct syscall is slightly slower (in
-theory), because no optimised vdso implementation can be used, but avoids
-the pthread dependency. Defaults to C<1> on GNU/Linux with glibc 2.x or
-higher, as it simplifies linking (no need for C<-lrt>).
-
-=item EV_USE_NANOSLEEP
-
-If defined to be C<1>, libev will assume that C<nanosleep ()> is available
-and will use it for delays. Otherwise it will use C<select ()>.
-
-=item EV_USE_EVENTFD
-
-If defined to be C<1>, then libev will assume that C<eventfd ()> is
-available and will probe for kernel support at runtime. This will improve
-C<ev_signal> and C<ev_async> performance and reduce resource consumption.
-If undefined, it will be enabled if the headers indicate GNU/Linux + Glibc
-2.7 or newer, otherwise disabled.
-
-=item EV_USE_SELECT
-
-If undefined or defined to be C<1>, libev will compile in support for the
-C<select>(2) backend. No attempt at auto-detection will be done: if no
-other method takes over, select will be it. Otherwise the select backend
-will not be compiled in.
-
-=item EV_SELECT_USE_FD_SET
-
-If defined to C<1>, then the select backend will use the system C<fd_set>
-structure. This is useful if libev doesn't compile due to a missing
-C<NFDBITS> or C<fd_mask> definition or it mis-guesses the bitset layout
-on exotic systems. This usually limits the range of file descriptors to
-some low limit such as 1024 or might have other limitations (winsocket
-only allows 64 sockets). The C<FD_SETSIZE> macro, set before compilation,
-configures the maximum size of the C<fd_set>.
-
-=item EV_SELECT_IS_WINSOCKET
-
-When defined to C<1>, the select backend will assume that
-select/socket/connect etc. don't understand file descriptors but
-wants osf handles on win32 (this is the case when the select to
-be used is the winsock select). This means that it will call
-C<_get_osfhandle> on the fd to convert it to an OS handle. Otherwise,
-it is assumed that all these functions actually work on fds, even
-on win32. Should not be defined on non-win32 platforms.
-
-=item EV_FD_TO_WIN32_HANDLE(fd)
-
-If C<EV_SELECT_IS_WINSOCKET> is enabled, then libev needs a way to map
-file descriptors to socket handles. When not defining this symbol (the
-default), then libev will call C<_get_osfhandle>, which is usually
-correct. In some cases, programs use their own file descriptor management,
-in which case they can provide this function to map fds to socket handles.
-
-=item EV_WIN32_HANDLE_TO_FD(handle)
-
-If C<EV_SELECT_IS_WINSOCKET> then libev maps handles to file descriptors
-using the standard C<_open_osfhandle> function. For programs implementing
-their own fd to handle mapping, overwriting this function makes it easier
-to do so. This can be done by defining this macro to an appropriate value.
-
-=item EV_WIN32_CLOSE_FD(fd)
-
-If programs implement their own fd to handle mapping on win32, then this
-macro can be used to override the C<close> function, useful to unregister
-file descriptors again. Note that the replacement function has to close
-the underlying OS handle.
-
-=item EV_USE_POLL
-
-If defined to be C<1>, libev will compile in support for the C<poll>(2)
-backend. Otherwise it will be enabled on non-win32 platforms. It
-takes precedence over select.
-
-=item EV_USE_EPOLL
-
-If defined to be C<1>, libev will compile in support for the Linux
-C<epoll>(7) backend. Its availability will be detected at runtime,
-otherwise another method will be used as fallback. This is the preferred
-backend for GNU/Linux systems. If undefined, it will be enabled if the
-headers indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled.
-
-=item EV_USE_KQUEUE
-
-If defined to be C<1>, libev will compile in support for the BSD style
-C<kqueue>(2) backend. Its actual availability will be detected at runtime,
-otherwise another method will be used as fallback. This is the preferred
-backend for BSD and BSD-like systems, although on most BSDs kqueue only
-supports some types of fds correctly (the only platform we found that
-supports ptys for example was NetBSD), so kqueue might be compiled in, but
-not be used unless explicitly requested. The best way to use it is to find
-out whether kqueue supports your type of fd properly and use an embedded
-kqueue loop.
-
-=item EV_USE_PORT
-
-If defined to be C<1>, libev will compile in support for the Solaris
-10 port style backend. Its availability will be detected at runtime,
-otherwise another method will be used as fallback. This is the preferred
-backend for Solaris 10 systems.
-
-=item EV_USE_DEVPOLL
-
-Reserved for future expansion, works like the USE symbols above.
-
-=item EV_USE_INOTIFY
-
-If defined to be C<1>, libev will compile in support for the Linux inotify
-interface to speed up C<ev_stat> watchers. Its actual availability will
-be detected at runtime. If undefined, it will be enabled if the headers
-indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled.
-
-=item EV_ATOMIC_T
-
-Libev requires an integer type (suitable for storing C<0> or C<1>) whose
-access is atomic with respect to other threads or signal contexts. No such
-type is easily found in the C language, so you can provide your own type
-that you know is safe for your purposes. It is used both for signal handler "locking"
-as well as for signal and thread safety in C<ev_async> watchers.
-
-In the absence of this define, libev will use C<sig_atomic_t volatile>
-(from F<signal.h>), which is usually good enough on most platforms.
-
-=item EV_H (h)
-
-The name of the F<ev.h> header file used to include it. The default if
-undefined is C<"ev.h"> in F<event.h>, F<ev.c> and F<ev++.h>. This can be
-used to virtually rename the F<ev.h> header file in case of conflicts.
-
-=item EV_CONFIG_H (h)
-
-If C<EV_STANDALONE> isn't C<1>, this variable can be used to override
-F<ev.c>'s idea of where to find the F<config.h> file, similarly to
-C<EV_H>, above.
-
-=item EV_EVENT_H (h)
-
-Similarly to C<EV_H>, this macro can be used to override F<event.c>'s idea
-of how the F<event.h> header can be found, the default is C<"event.h">.
-
-=item EV_PROTOTYPES (h)
-
-If defined to be C<0>, then F<ev.h> will not define any function
-prototypes, but still define all the structs and other symbols. This is
-occasionally useful if you want to provide your own wrapper functions
-around libev functions.
-
-=item EV_MULTIPLICITY
-
-If undefined or defined to C<1>, then all event-loop-specific functions
-will have the C<struct ev_loop *> as first argument, and you can create
-additional independent event loops. Otherwise there will be no support
-for multiple event loops and there is no first event loop pointer
-argument. Instead, all functions act on the single default loop.
-
-=item EV_MINPRI
-
-=item EV_MAXPRI
-
-The range of allowed priorities. C<EV_MINPRI> must be smaller or equal to
-C<EV_MAXPRI>, but otherwise there are no non-obvious limitations. You can
-provide for more priorities by overriding those symbols (usually defined
-to be C<-2> and C<2>, respectively).
-
-When doing priority-based operations, libev usually has to linearly search
-all the priorities, so having many of them (hundreds) uses a lot of space
-and time, so using the defaults of five priorities (-2 .. +2) is usually
-fine.
-
-If your embedding application does not need any priorities, defining these
-both to C<0> will save some memory and CPU.
-
-=item EV_PERIODIC_ENABLE, EV_IDLE_ENABLE, EV_EMBED_ENABLE, EV_STAT_ENABLE,
-EV_PREPARE_ENABLE, EV_CHECK_ENABLE, EV_FORK_ENABLE, EV_SIGNAL_ENABLE,
-EV_ASYNC_ENABLE, EV_CHILD_ENABLE.
-
-If undefined or defined to be C<1> (and the platform supports it), then
-the respective watcher type is supported. If defined to be C<0>, then it
-is not. Disabling watcher types mainly saves code size.
-
-=item EV_FEATURES
-
-If you need to shave off some kilobytes of code at the expense of some
-speed (but with the full API), you can define this symbol to request
-certain subsets of functionality. The default is to enable all features
-that can be enabled on the platform.
-
-A typical way to use this symbol is to define it to C<0> (or to a bitset
-with some broad features you want) and then selectively re-enable
-additional parts you want, for example if you want everything minimal,
-but multiple event loop support, async and child watchers and the poll
-backend, use this:
-
- #define EV_FEATURES 0
- #define EV_MULTIPLICITY 1
- #define EV_USE_POLL 1
- #define EV_CHILD_ENABLE 1
- #define EV_ASYNC_ENABLE 1
-
-The actual value is a bitset, it can be a combination of the following
-values:
-
-=over 4
-
-=item C<1> - faster/larger code
-
-Use larger code to speed up some operations.
-
-Currently this is used to override some inlining decisions (enlarging the
-code size by roughly 30% on amd64).
-
-When optimising for size, use of compiler flags such as C<-Os> with
-gcc is recommended, as well as C<-DNDEBUG>, as libev contains a number of
-assertions.
-
-=item C<2> - faster/larger data structures
-
-Replaces the small 2-heap for timer management by a faster 4-heap, larger
-hash table sizes and so on. This will usually further increase code size
-and can additionally have an effect on the size of data structures at
-runtime.
-
-=item C<4> - full API configuration
-
-This enables priorities (sets C<EV_MAXPRI>=2 and C<EV_MINPRI>=-2), and
-enables multiplicity (C<EV_MULTIPLICITY>=1).
-
-=item C<8> - full API
-
-This enables a lot of the "lesser used" API functions. See C<ev.h> for
-details on which parts of the API are still available without this
-feature, and do not complain if this subset changes over time.
-
-=item C<16> - enable all optional watcher types
-
-Enables all optional watcher types. If you want to selectively enable
-only some watcher types other than I/O and timers (e.g. prepare,
-embed, async, child...) you can enable them manually by defining
-C<EV_watchertype_ENABLE> to C<1> instead.
-
-=item C<32> - enable all backends
-
-This enables all backends - without this feature, you need to enable at
-least one backend manually (C<EV_USE_SELECT> is a good choice).
-
-=item C<64> - enable OS-specific "helper" APIs
-
-Enable inotify, eventfd, signalfd and similar OS-specific helper APIs by
-default.
-
-=back
-
-Compiling with C<gcc -Os -DEV_STANDALONE -DEV_USE_EPOLL=1 -DEV_FEATURES=0>
-reduces the compiled size of libev from 24.7Kb code/2.8Kb data to 6.5Kb
-code/0.3Kb data on my GNU/Linux amd64 system, while still giving you I/O
-watchers, timers and monotonic clock support.
-
-With an intelligent-enough linker (gcc+binutils are intelligent enough
-when you use C<-Wl,--gc-sections -ffunction-sections>) functions unused by
-your program might be left out as well - a binary starting a timer and an
-I/O watcher then might come out at only 5Kb.
-
-=item EV_AVOID_STDIO
-
-If this is set to C<1> at compiletime, then libev will avoid using stdio
-functions (printf, scanf, perror etc.). This will increase the code size
-somewhat, but if your program doesn't otherwise depend on stdio and your
-libc allows it, this avoids linking in the stdio library which is quite
-big.
-
-Note that error messages might become less precise when this option is
-enabled.
-
-=item EV_NSIG
-
-The highest supported signal number, +1 (or, the number of
-signals): Normally, libev tries to deduce the maximum number of signals
-automatically, but sometimes this fails, in which case it can be
-specified. Also, using a lower number than detected (C<32> should be
-good for about any system in existence) can save some memory, as libev
-statically allocates some 12-24 bytes per signal number.
-
-=item EV_PID_HASHSIZE
-
-C<ev_child> watchers use a small hash table to distribute workload by
-pid. The default size is C<16> (or C<1> with C<EV_FEATURES> disabled),
-usually more than enough. If you need to manage thousands of children you
-might want to increase this value (I<must> be a power of two).
-
-=item EV_INOTIFY_HASHSIZE
-
-C<ev_stat> watchers use a small hash table to distribute workload by
-inotify watch id. The default size is C<16> (or C<1> with C<EV_FEATURES>
-disabled), usually more than enough. If you need to manage thousands of
-C<ev_stat> watchers you might want to increase this value (I<must> be a
-power of two).
-
-=item EV_USE_4HEAP
-
-Heaps are not very cache-efficient. To improve the cache-efficiency of the
-timer and periodics heaps, libev uses a 4-heap when this symbol is defined
-to C<1>. The 4-heap uses more complicated (longer) code but has noticeably
-faster performance with many (thousands) of watchers.
-
-The default is C<1>, unless C<EV_FEATURES> overrides it, in which case it
-will be C<0>.
-
-=item EV_HEAP_CACHE_AT
-
-Heaps are not very cache-efficient. To improve the cache-efficiency of the
-timer and periodics heaps, libev can cache the timestamp (I<at>) within
-the heap structure (selected by defining C<EV_HEAP_CACHE_AT> to C<1>),
-which uses 8-12 bytes more per watcher and a few hundred bytes more code,
-but avoids random read accesses on heap changes. This improves performance
-noticeably with many (hundreds) of watchers.
-
-The default is C<1>, unless C<EV_FEATURES> overrides it, in which case it
-will be C<0>.
-
-=item EV_VERIFY
-
-Controls how much internal verification (see C<ev_verify ()>) will
-be done: If set to C<0>, no internal verification code will be compiled
-in. If set to C<1>, then verification code will be compiled in, but not
-called. If set to C<2>, then the internal verification code will be
-called once per loop, which can slow down libev. If set to C<3>, then the
-verification code will be called very frequently, which will slow down
-libev considerably.
-
-The default is C<1>, unless C<EV_FEATURES> overrides it, in which case it
-will be C<0>.
-
-=item EV_COMMON
-
-By default, all watchers have a C<void *data> member. By redefining
-this macro to something else you can include more and other types of
-members. You have to define it each time you include one of the files,
-though, and it must be identical each time.
-
-For example, the perl EV module uses something like this:
-
- #define EV_COMMON \
- SV *self; /* contains this struct */ \
- SV *cb_sv, *fh /* note no trailing ";" */
-
-=item EV_CB_DECLARE (type)
-
-=item EV_CB_INVOKE (watcher, revents)
-
-=item ev_set_cb (ev, cb)
-
-Can be used to change the callback member declaration in each watcher,
-and the way callbacks are invoked and set. Must expand to a struct member
-definition and a statement, respectively. See the F<ev.h> header file for
-their default definitions. One possible use for overriding these is to
-avoid the C<struct ev_loop *> as first argument in all cases, or to use
-method calls instead of plain function calls in C++.
-
-=back
-
-=head2 EXPORTED API SYMBOLS
-
-If you need to re-export the API (e.g. via a DLL) and you need a list of
-exported symbols, you can use the provided F<Symbol.*> files which list
-all public symbols, one per line:
-
- Symbols.ev for libev proper
- Symbols.event for the libevent emulation
-
-This can also be used to rename all public symbols to avoid clashes with
-multiple versions of libev linked together (which is obviously bad in
-itself, but sometimes it is inconvenient to avoid this).
-
-A sed command like this will create wrapper C<#define>'s that you need to
-include before including F<ev.h>:
-
- <Symbols.ev sed -e "s/.*/#define & myprefix_&/" >wrap.h
-
-This would create a file F<wrap.h> which essentially looks like this:
-
- #define ev_backend myprefix_ev_backend
- #define ev_check_start myprefix_ev_check_start
- #define ev_check_stop myprefix_ev_check_stop
- ...
-
-=head2 EXAMPLES
-
-For a real-world example of a program the includes libev
-verbatim, you can have a look at the EV perl module
-(L<http://software.schmorp.de/pkg/EV.html>). It has the libev files in
-the F<libev/> subdirectory and includes them in the F<EV/EVAPI.h> (public
-interface) and F<EV.xs> (implementation) files. Only the F<EV.xs> file
-will be compiled. It is pretty complex because it provides its own header
-file.
-
-The usage in rxvt-unicode is simpler. It has a F<ev_cpp.h> header file
-that everybody includes and which overrides some configure choices:
-
- #define EV_FEATURES 8
- #define EV_USE_SELECT 1
- #define EV_PREPARE_ENABLE 1
- #define EV_IDLE_ENABLE 1
- #define EV_SIGNAL_ENABLE 1
- #define EV_CHILD_ENABLE 1
- #define EV_USE_STDEXCEPT 0
- #define EV_CONFIG_H <config.h>
-
- #include "ev++.h"
-
-And a F<ev_cpp.C> implementation file that contains libev proper and is compiled:
-
- #include "ev_cpp.h"
- #include "ev.c"
-
-=head1 INTERACTION WITH OTHER PROGRAMS, LIBRARIES OR THE ENVIRONMENT
-
-=head2 THREADS AND COROUTINES
-
-=head3 THREADS
-
-All libev functions are reentrant and thread-safe unless explicitly
-documented otherwise, but libev implements no locking itself. This means
-that you can use as many loops as you want in parallel, as long as there
-are no concurrent calls into any libev function with the same loop
-parameter (C<ev_default_*> calls have an implicit default loop parameter,
-of course): libev guarantees that different event loops share no data
-structures that need any locking.
-
-Or to put it differently: calls with different loop parameters can be done
-concurrently from multiple threads, calls with the same loop parameter
-must be done serially (but can be done from different threads, as long as
-only one thread ever is inside a call at any point in time, e.g. by using
-a mutex per loop).
-
-Specifically to support threads (and signal handlers), libev implements
-so-called C<ev_async> watchers, which allow some limited form of
-concurrency on the same event loop, namely waking it up "from the
-outside".
-
-If you want to know which design (one loop, locking, or multiple loops
-without or something else still) is best for your problem, then I cannot
-help you, but here is some generic advice:
-
-=over 4
-
-=item * most applications have a main thread: use the default libev loop
-in that thread, or create a separate thread running only the default loop.
-
-This helps integrating other libraries or software modules that use libev
-themselves and don't care/know about threading.
-
-=item * one loop per thread is usually a good model.
-
-Doing this is almost never wrong, sometimes a better-performance model
-exists, but it is always a good start.
-
-=item * other models exist, such as the leader/follower pattern, where one
-loop is handed through multiple threads in a kind of round-robin fashion.
-
-Choosing a model is hard - look around, learn, know that usually you can do
-better than you currently do :-)
-
-=item * often you need to talk to some other thread which blocks in the
-event loop.
-
-C<ev_async> watchers can be used to wake them up from other threads safely
-(or from signal contexts...).
-
-An example use would be to communicate signals or other events that only
-work in the default loop by registering the signal watcher with the
-default loop and triggering an C<ev_async> watcher from the default loop
-watcher callback into the event loop interested in the signal.
-
-=back
-
-See also L<THREAD LOCKING EXAMPLE>.
-
-=head3 COROUTINES
-
-Libev is very accommodating to coroutines ("cooperative threads"):
-libev fully supports nesting calls to its functions from different
-coroutines (e.g. you can call C<ev_run> on the same loop from two
-different coroutines, and switch freely between both coroutines running
-the loop, as long as you don't confuse yourself). The only exception is
-that you must not do this from C<ev_periodic> reschedule callbacks.
-
-Care has been taken to ensure that libev does not keep local state inside
-C<ev_run>, and other calls do not usually allow for coroutine switches as
-they do not call any callbacks.
-
-=head2 COMPILER WARNINGS
-
-Depending on your compiler and compiler settings, you might get no or a
-lot of warnings when compiling libev code. Some people are apparently
-scared by this.
-
-However, these are unavoidable for many reasons. For one, each compiler
-has different warnings, and each user has different tastes regarding
-warning options. "Warn-free" code therefore cannot be a goal except when
-targeting a specific compiler and compiler-version.
-
-Another reason is that some compiler warnings require elaborate
-workarounds, or other changes to the code that make it less clear and less
-maintainable.
-
-And of course, some compiler warnings are just plain stupid, or simply
-wrong (because they don't actually warn about the condition their message
-seems to warn about). For example, certain older gcc versions had some
-warnings that resulted in an extreme number of false positives. These have
-been fixed, but some people still insist on making code warn-free with
-such buggy versions.
-
-While libev is written to generate as few warnings as possible,
-"warn-free" code is not a goal, and it is recommended not to build libev
-with any compiler warnings enabled unless you are prepared to cope with
-them (e.g. by ignoring them). Remember that warnings are just that:
-warnings, not errors, or proof of bugs.
-
-
-=head2 VALGRIND
-
-Valgrind has a special section here because it is a popular tool that is
-highly useful. Unfortunately, valgrind reports are very hard to interpret.
-
-If you think you found a bug (memory leak, uninitialised data access etc.)
-in libev, then check twice: If valgrind reports something like:
-
- ==2274== definitely lost: 0 bytes in 0 blocks.
- ==2274== possibly lost: 0 bytes in 0 blocks.
- ==2274== still reachable: 256 bytes in 1 blocks.
-
-Then there is no memory leak, just as memory accounted to global variables
-is not a memleak - the memory is still being referenced, and didn't leak.
-
-Similarly, under some circumstances, valgrind might report kernel bugs
-as if it were a bug in libev (e.g. in realloc or in the poll backend,
-although an acceptable workaround has been found here), or it might be
-confused.
-
-Keep in mind that valgrind is a very good tool, but only a tool. Don't
-make it into some kind of religion.
-
-If you are unsure about something, feel free to contact the mailing list
-with the full valgrind report and an explanation on why you think this
-is a bug in libev (best check the archives, too :). However, don't be
-annoyed when you get a brisk "this is no bug" answer and take the chance
-of learning how to interpret valgrind properly.
-
-If you need, for some reason, empty reports from valgrind for your project
-I suggest using suppression lists.
-
-
-=head1 PORTABILITY NOTES
-
-=head2 GNU/LINUX 32 BIT LIMITATIONS
-
-GNU/Linux is the only common platform that supports 64 bit file/large file
-interfaces but I<disables> them by default.
-
-That means that libev compiled in the default environment doesn't support
-files larger than 2GiB or so, which mainly affects C<ev_stat> watchers.
-
-Unfortunately, many programs try to work around this GNU/Linux issue
-by enabling the large file API, which makes them incompatible with the
-standard libev compiled for their system.
-
-Likewise, libev cannot enable the large file API itself as this would
-suddenly make it incompatible to the default compile time environment,
-i.e. all programs not using special compile switches.
-
-=head2 OS/X AND DARWIN BUGS
-
-The whole thing is a bug if you ask me - basically any system interface
-you touch is broken, whether it is locales, poll, kqueue or even the
-OpenGL drivers.
-
-=head3 C<kqueue> is buggy
-
-The kqueue syscall is broken in all known versions - most versions support
-only sockets, many support pipes.
-
-Libev tries to work around this by not using C<kqueue> by default on this
-rotten platform, but of course you can still ask for it when creating a
-loop - embedding a socket-only kqueue loop into a select-based one is
-probably going to work well.
-
-=head3 C<poll> is buggy
-
-Instead of fixing C<kqueue>, Apple replaced their (working) C<poll>
-implementation by something calling C<kqueue> internally around the 10.5.6
-release, so now C<kqueue> I<and> C<poll> are broken.
-
-Libev tries to work around this by not using C<poll> by default on
-this rotten platform, but of course you can still ask for it when creating
-a loop.
-
-=head3 C<select> is buggy
-
-All that's left is C<select>, and of course Apple found a way to fuck this
-one up as well: On OS/X, C<select> actively limits the number of file
-descriptors you can pass in to 1024 - your program suddenly crashes when
-you use more.
-
-There is an undocumented "workaround" for this - defining
-C<_DARWIN_UNLIMITED_SELECT>, which libev tries to use, so select I<should>
-work on OS/X.
-
-=head2 SOLARIS PROBLEMS AND WORKAROUNDS
-
-=head3 C<errno> reentrancy
-
-The default compile environment on Solaris is unfortunately so
-thread-unsafe that you can't even use components/libraries compiled
-without C<-D_REENTRANT> in a threaded program, which, of course, isn't
-defined by default. A valid, if stupid, implementation choice.
-
-If you want to use libev in threaded environments you have to make sure
-it's compiled with C<_REENTRANT> defined.
-
-=head3 Event port backend
-
-The scalable event interface for Solaris is called "event
-ports". Unfortunately, this mechanism is very buggy in all major
-releases. If you run into high CPU usage, your program freezes or you get
-a large number of spurious wakeups, make sure you have all the relevant
-and latest kernel patches applied. No, I don't know which ones, but there
-are multiple ones to apply, and afterwards, event ports actually work
-great.
-
-If you can't get it to work, you can try running the program by setting
-the environment variable C<LIBEV_FLAGS=3> to only allow C<poll> and
-C<select> backends.
-
-=head2 AIX POLL BUG
-
-AIX unfortunately has a broken C<poll.h> header. Libev works around
-this by trying to avoid the poll backend altogether (i.e. it's not even
-compiled in), which normally isn't a big problem as C<select> works fine
-with large bitsets on AIX, and AIX is dead anyway.
-
-=head2 WIN32 PLATFORM LIMITATIONS AND WORKAROUNDS
-
-=head3 General issues
-
-Win32 doesn't support any of the standards (e.g. POSIX) that libev
-requires, and its I/O model is fundamentally incompatible with the POSIX
-model. Libev still offers limited functionality on this platform in
-the form of the C<EVBACKEND_SELECT> backend, and only supports socket
-descriptors. This only applies when using Win32 natively, not when using
-e.g. cygwin. Actually, it only applies to the microsofts own compilers,
-as every compielr comes with a slightly differently broken/incompatible
-environment.
-
-Lifting these limitations would basically require the full
-re-implementation of the I/O system. If you are into this kind of thing,
-then note that glib does exactly that for you in a very portable way (note
-also that glib is the slowest event library known to man).
-
-There is no supported compilation method available on windows except
-embedding it into other applications.
-
-Sensible signal handling is officially unsupported by Microsoft - libev
-tries its best, but under most conditions, signals will simply not work.
-
-Not a libev limitation but worth mentioning: windows apparently doesn't
-accept large writes: instead of resulting in a partial write, windows will
-either accept everything or return C<ENOBUFS> if the buffer is too large,
-so make sure you only write small amounts into your sockets (less than a
-megabyte seems safe, but this apparently depends on the amount of memory
-available).
-
-Due to the many, low, and arbitrary limits on the win32 platform and
-the abysmal performance of winsockets, using a large number of sockets
-is not recommended (and not reasonable). If your program needs to use
-more than a hundred or so sockets, then likely it needs to use a totally
-different implementation for windows, as libev offers the POSIX readiness
-notification model, which cannot be implemented efficiently on windows
-(due to Microsoft monopoly games).
-
-A typical way to use libev under windows is to embed it (see the embedding
-section for details) and use the following F<evwrap.h> header file instead
-of F<ev.h>:
-
- #define EV_STANDALONE /* keeps ev from requiring config.h */
- #define EV_SELECT_IS_WINSOCKET 1 /* configure libev for windows select */
-
- #include "ev.h"
-
-And compile the following F<evwrap.c> file into your project (make sure
-you do I<not> compile the F<ev.c> or any other embedded source files!):
-
- #include "evwrap.h"
- #include "ev.c"
-
-=head3 The winsocket C<select> function
-
-The winsocket C<select> function doesn't follow POSIX in that it
-requires socket I<handles> and not socket I<file descriptors> (it is
-also extremely buggy). This makes select very inefficient, and also
-requires a mapping from file descriptors to socket handles (the Microsoft
-C runtime provides the function C<_open_osfhandle> for this). See the
-discussion of the C<EV_SELECT_USE_FD_SET>, C<EV_SELECT_IS_WINSOCKET> and
-C<EV_FD_TO_WIN32_HANDLE> preprocessor symbols for more info.
-
-The configuration for a "naked" win32 using the Microsoft runtime
-libraries and raw winsocket select is:
-
- #define EV_USE_SELECT 1
- #define EV_SELECT_IS_WINSOCKET 1 /* forces EV_SELECT_USE_FD_SET, too */
-
-Note that winsockets handling of fd sets is O(n), so you can easily get a
-complexity in the O(n²) range when using win32.
-
-=head3 Limited number of file descriptors
-
-Windows has numerous arbitrary (and low) limits on things.
-
-Early versions of winsocket's select only supported waiting for a maximum
-of C<64> handles (probably owning to the fact that all windows kernels
-can only wait for C<64> things at the same time internally; Microsoft
-recommends spawning a chain of threads and wait for 63 handles and the
-previous thread in each. Sounds great!).
-
-Newer versions support more handles, but you need to define C<FD_SETSIZE>
-to some high number (e.g. C<2048>) before compiling the winsocket select
-call (which might be in libev or elsewhere, for example, perl and many
-other interpreters do their own select emulation on windows).
-
-Another limit is the number of file descriptors in the Microsoft runtime
-libraries, which by default is C<64> (there must be a hidden I<64>
-fetish or something like this inside Microsoft). You can increase this
-by calling C<_setmaxstdio>, which can increase this limit to C<2048>
-(another arbitrary limit), but is broken in many versions of the Microsoft
-runtime libraries. This might get you to about C<512> or C<2048> sockets
-(depending on windows version and/or the phase of the moon). To get more,
-you need to wrap all I/O functions and provide your own fd management, but
-the cost of calling select (O(n²)) will likely make this unworkable.
-
-=head2 PORTABILITY REQUIREMENTS
-
-In addition to a working ISO-C implementation and of course the
-backend-specific APIs, libev relies on a few additional extensions:
-
-=over 4
-
-=item C<void (*)(ev_watcher_type *, int revents)> must have compatible
-calling conventions regardless of C<ev_watcher_type *>.
-
-Libev assumes not only that all watcher pointers have the same internal
-structure (guaranteed by POSIX but not by ISO C for example), but it also
-assumes that the same (machine) code can be used to call any watcher
-callback: The watcher callbacks have different type signatures, but libev
-calls them using an C<ev_watcher *> internally.
-
-=item pointer accesses must be thread-atomic
-
-Accessing a pointer value must be atomic, it must both be readable and
-writable in one piece - this is the case on all current architectures.
-
-=item C<sig_atomic_t volatile> must be thread-atomic as well
-
-The type C<sig_atomic_t volatile> (or whatever is defined as
-C<EV_ATOMIC_T>) must be atomic with respect to accesses from different
-threads. This is not part of the specification for C<sig_atomic_t>, but is
-believed to be sufficiently portable.
-
-=item C<sigprocmask> must work in a threaded environment
-
-Libev uses C<sigprocmask> to temporarily block signals. This is not
-allowed in a threaded program (C<pthread_sigmask> has to be used). Typical
-pthread implementations will either allow C<sigprocmask> in the "main
-thread" or will block signals process-wide, both behaviours would
-be compatible with libev. Interaction between C<sigprocmask> and
-C<pthread_sigmask> could complicate things, however.
-
-The most portable way to handle signals is to block signals in all threads
-except the initial one, and run the default loop in the initial thread as
-well.
-
-=item C<long> must be large enough for common memory allocation sizes
-
-To improve portability and simplify its API, libev uses C<long> internally
-instead of C<size_t> when allocating its data structures. On non-POSIX
-systems (Microsoft...) this might be unexpectedly low, but is still at
-least 31 bits everywhere, which is enough for hundreds of millions of
-watchers.
-
-=item C<double> must hold a time value in seconds with enough accuracy
-
-The type C<double> is used to represent timestamps. It is required to
-have at least 51 bits of mantissa (and 9 bits of exponent), which is
-good enough for at least into the year 4000 with millisecond accuracy
-(the design goal for libev). This requirement is overfulfilled by
-implementations using IEEE 754, which is basically all existing ones. With
-IEEE 754 doubles, you get microsecond accuracy until at least 2200.
-
-=back
-
-If you know of other additional requirements drop me a note.
-
-
-=head1 ALGORITHMIC COMPLEXITIES
-
-In this section the complexities of (many of) the algorithms used inside
-libev will be documented. For complexity discussions about backends see
-the documentation for C<ev_default_init>.
-
-All of the following are about amortised time: If an array needs to be
-extended, libev needs to realloc and move the whole array, but this
-happens asymptotically rarer with higher number of elements, so O(1) might
-mean that libev does a lengthy realloc operation in rare cases, but on
-average it is much faster and asymptotically approaches constant time.
-
-=over 4
-
-=item Starting and stopping timer/periodic watchers: O(log skipped_other_timers)
-
-This means that, when you have a watcher that triggers in one hour and
-there are 100 watchers that would trigger before that, then inserting will
-have to skip roughly seven (C<ld 100>) of these watchers.
-
-=item Changing timer/periodic watchers (by autorepeat or calling again): O(log skipped_other_timers)
-
-That means that changing a timer costs less than removing/adding them,
-as only the relative motion in the event queue has to be paid for.
-
-=item Starting io/check/prepare/idle/signal/child/fork/async watchers: O(1)
-
-These just add the watcher into an array or at the head of a list.
-
-=item Stopping check/prepare/idle/fork/async watchers: O(1)
-
-=item Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % EV_PID_HASHSIZE))
-
-These watchers are stored in lists, so they need to be walked to find the
-correct watcher to remove. The lists are usually short (you don't usually
-have many watchers waiting for the same fd or signal: one is typical, two
-is rare).
-
-=item Finding the next timer in each loop iteration: O(1)
-
-By virtue of using a binary or 4-heap, the next timer is always found at a
-fixed position in the storage array.
-
-=item Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd)
-
-A change means an I/O watcher gets started or stopped, which requires
-libev to recalculate its status (and possibly tell the kernel, depending
-on backend and whether C<ev_io_set> was used).
-
-=item Activating one watcher (putting it into the pending state): O(1)
-
-=item Priority handling: O(number_of_priorities)
-
-Priorities are implemented by allocating some space for each
-priority. When doing priority-based operations, libev usually has to
-linearly search all the priorities, but starting/stopping and activating
-watchers becomes O(1) with respect to priority handling.
-
-=item Sending an ev_async: O(1)
-
-=item Processing ev_async_send: O(number_of_async_watchers)
-
-=item Processing signals: O(max_signal_number)
-
-Sending involves a system call I<iff> there were no other C<ev_async_send>
-calls in the current loop iteration. Checking for async and signal events
-involves iterating over all running async watchers or all signal numbers.
-
-=back
-
-
-=head1 PORTING FROM LIBEV 3.X TO 4.X
-
-The major version 4 introduced some incompatible changes to the API.
-
-At the moment, the C<ev.h> header file provides compatibility definitions
-for all changes, so most programs should still compile. The compatibility
-layer might be removed in later versions of libev, so better update to the
-new API early than late.
-
-=over 4
-
-=item C<EV_COMPAT3> backwards compatibility mechanism
-
-The backward compatibility mechanism can be controlled by
-C<EV_COMPAT3>. See L<PREPROCESSOR SYMBOLS/MACROS> in the L<EMBEDDING>
-section.
-
-=item C<ev_default_destroy> and C<ev_default_fork> have been removed
-
-These calls can be replaced easily by their C<ev_loop_xxx> counterparts:
-
- ev_loop_destroy (EV_DEFAULT_UC);
- ev_loop_fork (EV_DEFAULT);
-
-=item function/symbol renames
-
-A number of functions and symbols have been renamed:
-
- ev_loop => ev_run
- EVLOOP_NONBLOCK => EVRUN_NOWAIT
- EVLOOP_ONESHOT => EVRUN_ONCE
-
- ev_unloop => ev_break
- EVUNLOOP_CANCEL => EVBREAK_CANCEL
- EVUNLOOP_ONE => EVBREAK_ONE
- EVUNLOOP_ALL => EVBREAK_ALL
-
- EV_TIMEOUT => EV_TIMER
-
- ev_loop_count => ev_iteration
- ev_loop_depth => ev_depth
- ev_loop_verify => ev_verify
-
-Most functions working on C<struct ev_loop> objects don't have an
-C<ev_loop_> prefix, so it was removed; C<ev_loop>, C<ev_unloop> and
-associated constants have been renamed to not collide with the C<struct
-ev_loop> anymore and C<EV_TIMER> now follows the same naming scheme
-as all other watcher types. Note that C<ev_loop_fork> is still called
-C<ev_loop_fork> because it would otherwise clash with the C<ev_fork>
-typedef.
-
-=item C<EV_MINIMAL> mechanism replaced by C<EV_FEATURES>
-
-The preprocessor symbol C<EV_MINIMAL> has been replaced by a different
-mechanism, C<EV_FEATURES>. Programs using C<EV_MINIMAL> usually compile
-and work, but the library code will of course be larger.
-
-=back
-
-
-=head1 GLOSSARY
-
-=over 4
-
-=item active
-
-A watcher is active as long as it has been started and not yet stopped.
-See L<WATCHER STATES> for details.
-
-=item application
-
-In this document, an application is whatever is using libev.
-
-=item backend
-
-The part of the code dealing with the operating system interfaces.
-
-=item callback
-
-The address of a function that is called when some event has been
-detected. Callbacks are being passed the event loop, the watcher that
-received the event, and the actual event bitset.
-
-=item callback/watcher invocation
-
-The act of calling the callback associated with a watcher.
-
-=item event
-
-A change of state of some external event, such as data now being available
-for reading on a file descriptor, time having passed or simply not having
-any other events happening anymore.
-
-In libev, events are represented as single bits (such as C<EV_READ> or
-C<EV_TIMER>).
-
-=item event library
-
-A software package implementing an event model and loop.
-
-=item event loop
-
-An entity that handles and processes external events and converts them
-into callback invocations.
-
-=item event model
-
-The model used to describe how an event loop handles and processes
-watchers and events.
-
-=item pending
-
-A watcher is pending as soon as the corresponding event has been
-detected. See L<WATCHER STATES> for details.
-
-=item real time
-
-The physical time that is observed. It is apparently strictly monotonic :)
-
-=item wall-clock time
-
-The time and date as shown on clocks. Unlike real time, it can actually
-be wrong and jump forwards and backwards, e.g. when you adjust your
-clock.
-
-=item watcher
-
-A data structure that describes interest in certain events. Watchers need
-to be started (attached to an event loop) before they can receive events.
-
-=back
-
-=head1 AUTHOR
-
-Marc Lehmann <libev@schmorp.de>, with repeated corrections by Mikael
-Magnusson and Emanuele Giaquinta, and minor corrections by many others.
-
diff --git a/deps/uv/src/unix/ev/ev_epoll.c b/deps/uv/src/unix/ev/ev_epoll.c
deleted file mode 100644
index e8101e562..000000000
--- a/deps/uv/src/unix/ev/ev_epoll.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * libev epoll fd activity backend
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-/*
- * general notes about epoll:
- *
- * a) epoll silently removes fds from the fd set. as nothing tells us
- * that an fd has been removed otherwise, we have to continually
- * "rearm" fds that we suspect *might* have changed (same
- * problem with kqueue, but much less costly there).
- * b) the fact that ADD != MOD creates a lot of extra syscalls due to a)
- * and seems not to have any advantage.
- * c) the inability to handle fork or file descriptors (think dup)
- * limits the applicability over poll, so this is not a generic
- * poll replacement.
- * d) epoll doesn't work the same as select with many file descriptors
- * (such as files). while not critical, no other advanced interface
- * seems to share this (rather non-unixy) limitation.
- * e) epoll claims to be embeddable, but in practise you never get
- * a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32).
- * f) epoll_ctl returning EPERM means the fd is always ready.
- *
- * lots of "weird code" and complication handling in this file is due
- * to these design problems with epoll, as we try very hard to avoid
- * epoll_ctl syscalls for common usage patterns and handle the breakage
- * ensuing from receiving events for closed and otherwise long gone
- * file descriptors.
- */
-
-#include <sys/epoll.h>
-
-#define EV_EMASK_EPERM 0x80
-
-static void
-epoll_modify (EV_P_ int fd, int oev, int nev)
-{
- struct epoll_event ev;
- unsigned char oldmask;
-
- /*
- * we handle EPOLL_CTL_DEL by ignoring it here
- * on the assumption that the fd is gone anyways
- * if that is wrong, we have to handle the spurious
- * event in epoll_poll.
- * if the fd is added again, we try to ADD it, and, if that
- * fails, we assume it still has the same eventmask.
- */
- if (!nev)
- return;
-
- oldmask = anfds [fd].emask;
- anfds [fd].emask = nev;
-
- /* store the generation counter in the upper 32 bits, the fd in the lower 32 bits */
- ev.data.u64 = (uint64_t)(uint32_t)fd
- | ((uint64_t)(uint32_t)++anfds [fd].egen << 32);
- ev.events = (nev & EV_READ ? EPOLLIN : 0)
- | (nev & EV_WRITE ? EPOLLOUT : 0);
-
- if (expect_true (!epoll_ctl (backend_fd, oev && oldmask != nev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev)))
- return;
-
- if (expect_true (errno == ENOENT))
- {
- /* if ENOENT then the fd went away, so try to do the right thing */
- if (!nev)
- goto dec_egen;
-
- if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev))
- return;
- }
- else if (expect_true (errno == EEXIST))
- {
- /* EEXIST means we ignored a previous DEL, but the fd is still active */
- /* if the kernel mask is the same as the new mask, we assume it hasn't changed */
- if (oldmask == nev)
- goto dec_egen;
-
- if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev))
- return;
- }
- else if (expect_true (errno == EPERM))
- {
- /* EPERM means the fd is always ready, but epoll is too snobbish */
- /* to handle it, unlike select or poll. */
- anfds [fd].emask = EV_EMASK_EPERM;
-
- /* add fd to epoll_eperms, if not already inside */
- if (!(oldmask & EV_EMASK_EPERM))
- {
- array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, EMPTY2);
- epoll_eperms [epoll_epermcnt++] = fd;
- }
-
- return;
- }
-
- fd_kill (EV_A_ fd);
-
-dec_egen:
- /* we didn't successfully call epoll_ctl, so decrement the generation counter again */
- --anfds [fd].egen;
-}
-
-static void
-epoll_poll (EV_P_ ev_tstamp timeout)
-{
- int i;
- int eventcnt;
-
- /* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */
- /* the default libev max wait time, however. */
- EV_RELEASE_CB;
- eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax,
- epoll_epermcnt ? 0 : ev_timeout_to_ms (timeout));
- EV_ACQUIRE_CB;
-
- if (expect_false (eventcnt < 0))
- {
- if (errno != EINTR)
- ev_syserr ("(libev) epoll_wait");
-
- return;
- }
-
- for (i = 0; i < eventcnt; ++i)
- {
- struct epoll_event *ev = epoll_events + i;
-
- int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */
- int want = anfds [fd].events;
- int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)
- | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0);
-
- /* check for spurious notification */
- /* we assume that fd is always in range, as we never shrink the anfds array */
- if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32)))
- {
- /* recreate kernel state */
- postfork = 1;
- continue;
- }
-
- if (expect_false (got & ~want))
- {
- anfds [fd].emask = want;
-
- /* we received an event but are not interested in it, try mod or del */
- /* I don't think we ever need MOD, but let's handle it anyways */
- ev->events = (want & EV_READ ? EPOLLIN : 0)
- | (want & EV_WRITE ? EPOLLOUT : 0);
-
- /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */
- /* which is fortunately easy to do for us. */
- if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev))
- {
- postfork = 1; /* an error occurred, recreate kernel state */
- continue;
- }
- }
-
- fd_event (EV_A_ fd, got);
- }
-
- /* if the receive array was full, increase its size */
- if (expect_false (eventcnt == epoll_eventmax))
- {
- ev_free (epoll_events);
- epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1);
- epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
- }
-
- /* now synthesize events for all fds where epoll fails, while select works... */
- for (i = epoll_epermcnt; i--; )
- {
- int fd = epoll_eperms [i];
- unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE);
-
- if (anfds [fd].emask & EV_EMASK_EPERM && events)
- fd_event (EV_A_ fd, events);
- else
- epoll_eperms [i] = epoll_eperms [--epoll_epermcnt];
- }
-}
-
-int inline_size
-epoll_init (EV_P_ int flags)
-{
-#ifdef EPOLL_CLOEXEC
- backend_fd = epoll_create1 (EPOLL_CLOEXEC);
-
- if (backend_fd < 0)
-#endif
- backend_fd = epoll_create (256);
-
- if (backend_fd < 0)
- return 0;
-
- fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
-
- backend_fudge = 0.; /* kernel sources seem to indicate this to be zero */
- backend_modify = epoll_modify;
- backend_poll = epoll_poll;
-
- epoll_eventmax = 64; /* initial number of events receivable per poll */
- epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
-
- return EVBACKEND_EPOLL;
-}
-
-void inline_size
-epoll_destroy (EV_P)
-{
- ev_free (epoll_events);
- array_free (epoll_eperm, EMPTY);
-}
-
-void inline_size
-epoll_fork (EV_P)
-{
- close (backend_fd);
-
- while ((backend_fd = epoll_create (256)) < 0)
- ev_syserr ("(libev) epoll_create");
-
- fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
-
- fd_rearm_all (EV_A);
-}
-
diff --git a/deps/uv/src/unix/ev/ev_kqueue.c b/deps/uv/src/unix/ev/ev_kqueue.c
deleted file mode 100644
index 871e771bc..000000000
--- a/deps/uv/src/unix/ev/ev_kqueue.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * libev kqueue backend
- *
- * Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/event.h>
-#include <string.h>
-#include <errno.h>
-
-/* These are the same on OS X and the BSDs. */
-#ifndef NOTE_DELETE
-# define NOTE_DELETE 0x01
-#endif
-#ifndef NOTE_WRITE
-# define NOTE_WRITE 0x02
-#endif
-#ifndef NOTE_EXTEND
-# define NOTE_EXTEND 0x04
-#endif
-#ifndef NOTE_ATTRIB
-# define NOTE_ATTRIB 0x08
-#endif
-#ifndef NOTE_LINK
-# define NOTE_LINK 0x10
-#endif
-#ifndef NOTE_RENAME
-# define NOTE_RENAME 0x20
-#endif
-#ifndef NOTE_REVOKE
-# define NOTE_REVOKE 0x40
-#endif
-
-
-extern void
-uv__kqueue_hack (EV_P_ int fflags, ev_io *w);
-
-void inline_speed
-kqueue_change (EV_P_ int fd, int filter, int flags, int fflags)
-{
- ++kqueue_changecnt;
- array_needsize (struct kevent, kqueue_changes, kqueue_changemax, kqueue_changecnt, EMPTY2);
-
- EV_SET (&kqueue_changes [kqueue_changecnt - 1], fd, filter, flags, fflags, 0, 0);
-}
-
-/* OS X at least needs this */
-#ifndef EV_ENABLE
-# define EV_ENABLE 0
-#endif
-#ifndef NOTE_EOF
-# define NOTE_EOF 0
-#endif
-
-static void
-kqueue_modify (EV_P_ int fd, int oev, int nev)
-{
- if (oev != nev)
- {
- if (oev & EV_READ)
- kqueue_change (EV_A_ fd, EVFILT_READ , EV_DELETE, 0);
-
- if (oev & EV_WRITE)
- kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_DELETE, 0);
- }
-
- /* to detect close/reopen reliably, we have to re-add */
- /* event requests even when oev == nev */
-
- if (nev & EV_READ)
- kqueue_change (EV_A_ fd, EVFILT_READ , EV_ADD | EV_ENABLE, NOTE_EOF);
-
- if (nev & EV_WRITE)
- kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, NOTE_EOF);
-
- if (nev & EV_LIBUV_KQUEUE_HACK)
- kqueue_change (EV_A_ fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
- NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE);
-}
-
-static void
-kqueue_poll (EV_P_ ev_tstamp timeout)
-{
- int res, i;
- struct timespec ts;
-
- /* need to resize so there is enough space for errors */
- if (kqueue_changecnt > kqueue_eventmax)
- {
- ev_free (kqueue_events);
- kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_changecnt);
- kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
- }
-
- EV_RELEASE_CB;
- EV_TS_SET (ts, timeout);
- res = kevent (backend_fd, kqueue_changes, kqueue_changecnt, kqueue_events, kqueue_eventmax, &ts);
- EV_ACQUIRE_CB;
- kqueue_changecnt = 0;
-
- if (expect_false (res < 0))
- {
- if (errno != EINTR)
- ev_syserr ("(libev) kevent");
-
- return;
- }
-
- for (i = 0; i < res; ++i)
- {
- int fd = kqueue_events [i].ident;
-
- if (kqueue_events [i].filter == EVFILT_VNODE)
- {
- /* pass kqueue filter flags to libuv */
- ev_io *w = (ev_io *)(anfds [fd].head);
- uv__kqueue_hack (EV_A_ kqueue_events [i].fflags, w);
- }
-
- if (expect_false (kqueue_events [i].flags & EV_ERROR))
- {
- int err = kqueue_events [i].data;
-
- /* we are only interested in errors for fds that we are interested in :) */
- if (anfds [fd].events)
- {
- if (err == ENOENT) /* resubmit changes on ENOENT */
- kqueue_modify (EV_A_ fd, 0, anfds [fd].events);
- else if (err == EBADF) /* on EBADF, we re-check the fd */
- {
- if (fd_valid (fd))
- kqueue_modify (EV_A_ fd, 0, anfds [fd].events);
- else
- fd_kill (EV_A_ fd);
- }
- else /* on all other errors, we error out on the fd */
- fd_kill (EV_A_ fd);
- }
- }
- else
- fd_event (
- EV_A_
- fd,
- kqueue_events [i].filter == EVFILT_READ ? EV_READ
- : kqueue_events [i].filter == EVFILT_WRITE ? EV_WRITE
- : kqueue_events [i].filter == EVFILT_VNODE ? EV_LIBUV_KQUEUE_HACK
- : 0
- );
- }
-
- if (expect_false (res == kqueue_eventmax))
- {
- ev_free (kqueue_events);
- kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_eventmax + 1);
- kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
- }
-}
-
-int inline_size
-kqueue_init (EV_P_ int flags)
-{
- /* Initialize the kernel queue */
- if ((backend_fd = kqueue ()) < 0)
- return 0;
-
- fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
-
- backend_fudge = 0.;
- backend_modify = kqueue_modify;
- backend_poll = kqueue_poll;
-
- kqueue_eventmax = 64; /* initial number of events receivable per poll */
- kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
-
- kqueue_changes = 0;
- kqueue_changemax = 0;
- kqueue_changecnt = 0;
-
- return EVBACKEND_KQUEUE;
-}
-
-void inline_size
-kqueue_destroy (EV_P)
-{
- ev_free (kqueue_events);
- ev_free (kqueue_changes);
-}
-
-void inline_size
-kqueue_fork (EV_P)
-{
- while ((backend_fd = kqueue ()) < 0)
- ev_syserr ("(libev) kqueue");
-
- fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
-
- /* re-register interest in fds */
- fd_rearm_all (EV_A);
-}
-
diff --git a/deps/uv/src/unix/ev/ev_poll.c b/deps/uv/src/unix/ev/ev_poll.c
deleted file mode 100644
index e53ae0de9..000000000
--- a/deps/uv/src/unix/ev/ev_poll.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * libev poll fd activity backend
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#include <poll.h>
-
-void inline_size
-pollidx_init (int *base, int count)
-{
- /* consider using memset (.., -1, ...), which is practically guaranteed
- * to work on all systems implementing poll */
- while (count--)
- *base++ = -1;
-}
-
-static void
-poll_modify (EV_P_ int fd, int oev, int nev)
-{
- int idx;
-
- if (oev == nev)
- return;
-
- array_needsize (int, pollidxs, pollidxmax, fd + 1, pollidx_init);
-
- idx = pollidxs [fd];
-
- if (idx < 0) /* need to allocate a new pollfd */
- {
- pollidxs [fd] = idx = pollcnt++;
- array_needsize (struct pollfd, polls, pollmax, pollcnt, EMPTY2);
- polls [idx].fd = fd;
- }
-
- assert (polls [idx].fd == fd);
-
- if (nev)
- polls [idx].events =
- (nev & EV_READ ? POLLIN : 0)
- | (nev & EV_WRITE ? POLLOUT : 0);
- else /* remove pollfd */
- {
- pollidxs [fd] = -1;
-
- if (expect_true (idx < --pollcnt))
- {
- polls [idx] = polls [pollcnt];
- pollidxs [polls [idx].fd] = idx;
- }
- }
-}
-
-static void
-poll_poll (EV_P_ ev_tstamp timeout)
-{
- struct pollfd *p;
- int res;
-
- EV_RELEASE_CB;
- res = poll (polls, pollcnt, ev_timeout_to_ms (timeout));
- EV_ACQUIRE_CB;
-
- if (expect_false (res < 0))
- {
- if (errno == EBADF)
- fd_ebadf (EV_A);
- else if (errno == ENOMEM && !syserr_cb)
- fd_enomem (EV_A);
- else if (errno != EINTR)
- ev_syserr ("(libev) poll");
- }
- else
- for (p = polls; res; ++p)
- {
- assert (("libev: poll() returned illegal result, broken BSD kernel?", p < polls + pollcnt));
-
- if (expect_false (p->revents)) /* this expect is debatable */
- {
- --res;
-
- if (expect_false (p->revents & POLLNVAL))
- fd_kill (EV_A_ p->fd);
- else
- fd_event (
- EV_A_
- p->fd,
- (p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
- | (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
- );
- }
- }
-}
-
-int inline_size
-poll_init (EV_P_ int flags)
-{
- backend_fudge = 0.; /* posix says this is zero */
- backend_modify = poll_modify;
- backend_poll = poll_poll;
-
- pollidxs = 0; pollidxmax = 0;
- polls = 0; pollmax = 0; pollcnt = 0;
-
- return EVBACKEND_POLL;
-}
-
-void inline_size
-poll_destroy (EV_P)
-{
- ev_free (pollidxs);
- ev_free (polls);
-}
-
diff --git a/deps/uv/src/unix/ev/ev_port.c b/deps/uv/src/unix/ev/ev_port.c
deleted file mode 100644
index 0ffebc372..000000000
--- a/deps/uv/src/unix/ev/ev_port.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * libev solaris event port backend
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-/* useful reading:
- *
- * http://bugs.opensolaris.org/view_bug.do?bug_id=6268715 (random results)
- * http://bugs.opensolaris.org/view_bug.do?bug_id=6455223 (just totally broken)
- * http://bugs.opensolaris.org/view_bug.do?bug_id=6873782 (manpage ETIME)
- * http://bugs.opensolaris.org/view_bug.do?bug_id=6874410 (implementation ETIME)
- * http://www.mail-archive.com/networking-discuss@opensolaris.org/msg11898.html ETIME vs. nget
- * http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/event_port.c (libc)
- * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/portfs/port.c#1325 (kernel)
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <poll.h>
-#include <port.h>
-#include <string.h>
-#include <errno.h>
-
-void inline_speed
-port_associate_and_check (EV_P_ int fd, int ev)
-{
- if (0 >
- port_associate (
- backend_fd, PORT_SOURCE_FD, fd,
- (ev & EV_READ ? POLLIN : 0)
- | (ev & EV_WRITE ? POLLOUT : 0),
- 0
- )
- )
- {
- if (errno == EBADFD)
- fd_kill (EV_A_ fd);
- else
- ev_syserr ("(libev) port_associate");
- }
-}
-
-static void
-port_modify (EV_P_ int fd, int oev, int nev)
-{
- /* we need to reassociate no matter what, as closes are
- * once more silently being discarded.
- */
- if (!nev)
- {
- if (oev)
- port_dissociate (backend_fd, PORT_SOURCE_FD, fd);
- }
- else
- port_associate_and_check (EV_A_ fd, nev);
-}
-
-static void
-port_poll (EV_P_ ev_tstamp timeout)
-{
- int res, i;
- struct timespec ts;
- uint_t nget = 1;
-
- /* we initialise this to something we will skip in the loop, as */
- /* port_getn can return with nget unchanged, but no indication */
- /* whether it was the original value or has been updated :/ */
- port_events [0].portev_source = 0;
-
- EV_RELEASE_CB;
- EV_TS_SET (ts, timeout);
- res = port_getn (backend_fd, port_events, port_eventmax, &nget, &ts);
- EV_ACQUIRE_CB;
-
- /* port_getn may or may not set nget on error */
- /* so we rely on port_events [0].portev_source not being updated */
- if (res == -1 && errno != ETIME && errno != EINTR)
- ev_syserr ("(libev) port_getn (see http://bugs.opensolaris.org/view_bug.do?bug_id=6268715, try LIBEV_FLAGS=3 env variable)");
-
- for (i = 0; i < nget; ++i)
- {
- if (port_events [i].portev_source == PORT_SOURCE_FD)
- {
- int fd = port_events [i].portev_object;
-
- fd_event (
- EV_A_
- fd,
- (port_events [i].portev_events & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
- | (port_events [i].portev_events & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
- );
-
- fd_change (EV_A_ fd, EV__IOFDSET);
- }
- }
-
- if (expect_false (nget == port_eventmax))
- {
- ev_free (port_events);
- port_eventmax = array_nextsize (sizeof (port_event_t), port_eventmax, port_eventmax + 1);
- port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
- }
-}
-
-int inline_size
-port_init (EV_P_ int flags)
-{
- /* Initialize the kernel queue */
- if ((backend_fd = port_create ()) < 0)
- return 0;
-
- assert (("libev: PORT_SOURCE_FD must not be zero", PORT_SOURCE_FD));
-
- fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
-
- backend_fudge = 1e-3; /* needed to compensate for port_getn returning early */
- backend_modify = port_modify;
- backend_poll = port_poll;
-
- port_eventmax = 64; /* initial number of events receivable per poll */
- port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
-
- return EVBACKEND_PORT;
-}
-
-void inline_size
-port_destroy (EV_P)
-{
- ev_free (port_events);
-}
-
-void inline_size
-port_fork (EV_P)
-{
- close (backend_fd);
-
- while ((backend_fd = port_create ()) < 0)
- ev_syserr ("(libev) port");
-
- fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
-
- /* re-register interest in fds */
- fd_rearm_all (EV_A);
-}
-
diff --git a/deps/uv/src/unix/ev/ev_select.c b/deps/uv/src/unix/ev/ev_select.c
deleted file mode 100644
index 0ea9467e4..000000000
--- a/deps/uv/src/unix/ev/ev_select.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * libev select fd activity backend
- *
- * Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifndef _WIN32
-/* for unix systems */
-# include <inttypes.h>
-# ifndef __hpux
-/* for REAL unix systems */
-# include <sys/select.h>
-# endif
-#endif
-
-#ifndef EV_SELECT_USE_FD_SET
-# ifdef NFDBITS
-# define EV_SELECT_USE_FD_SET 0
-# else
-# define EV_SELECT_USE_FD_SET 1
-# endif
-#endif
-
-#if EV_SELECT_IS_WINSOCKET
-# undef EV_SELECT_USE_FD_SET
-# define EV_SELECT_USE_FD_SET 1
-# undef NFDBITS
-# define NFDBITS 0
-#endif
-
-#if !EV_SELECT_USE_FD_SET
-# define NFDBYTES (NFDBITS / 8)
-#endif
-
-#include <string.h>
-
-static void
-select_modify (EV_P_ int fd, int oev, int nev)
-{
- if (oev == nev)
- return;
-
- {
-#if EV_SELECT_USE_FD_SET
-
- #if EV_SELECT_IS_WINSOCKET
- SOCKET handle = anfds [fd].handle;
- #else
- int handle = fd;
- #endif
-
- assert (("libev: fd >= FD_SETSIZE passed to fd_set-based select backend", fd < FD_SETSIZE));
-
- /* FD_SET is broken on windows (it adds the fd to a set twice or more,
- * which eventually leads to overflows). Need to call it only on changes.
- */
- #if EV_SELECT_IS_WINSOCKET
- if ((oev ^ nev) & EV_READ)
- #endif
- if (nev & EV_READ)
- FD_SET (handle, (fd_set *)vec_ri);
- else
- FD_CLR (handle, (fd_set *)vec_ri);
-
- #if EV_SELECT_IS_WINSOCKET
- if ((oev ^ nev) & EV_WRITE)
- #endif
- if (nev & EV_WRITE)
- FD_SET (handle, (fd_set *)vec_wi);
- else
- FD_CLR (handle, (fd_set *)vec_wi);
-
-#else
-
- int word = fd / NFDBITS;
- fd_mask mask = 1UL << (fd % NFDBITS);
-
- if (expect_false (vec_max <= word))
- {
- int new_max = word + 1;
-
- vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES);
- vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */
- vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES);
- vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */
- #ifdef _WIN32
- vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */
- #endif
-
- for (; vec_max < new_max; ++vec_max)
- ((fd_mask *)vec_ri) [vec_max] =
- ((fd_mask *)vec_wi) [vec_max] = 0;
- }
-
- ((fd_mask *)vec_ri) [word] |= mask;
- if (!(nev & EV_READ))
- ((fd_mask *)vec_ri) [word] &= ~mask;
-
- ((fd_mask *)vec_wi) [word] |= mask;
- if (!(nev & EV_WRITE))
- ((fd_mask *)vec_wi) [word] &= ~mask;
-#endif
- }
-}
-
-static void
-select_poll (EV_P_ ev_tstamp timeout)
-{
- struct timeval tv;
- int res;
- int fd_setsize;
-
- EV_RELEASE_CB;
- EV_TV_SET (tv, timeout);
-
-#if EV_SELECT_USE_FD_SET
- fd_setsize = sizeof (fd_set);
-#else
- fd_setsize = vec_max * NFDBYTES;
-#endif
-
- memcpy (vec_ro, vec_ri, fd_setsize);
- memcpy (vec_wo, vec_wi, fd_setsize);
-
-#ifdef _WIN32
- /* pass in the write set as except set.
- * the idea behind this is to work around a windows bug that causes
- * errors to be reported as an exception and not by setting
- * the writable bit. this is so uncontrollably lame.
- */
- memcpy (vec_eo, vec_wi, fd_setsize);
- res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv);
-#elif EV_SELECT_USE_FD_SET
- fd_setsize = anfdmax < FD_SETSIZE ? anfdmax : FD_SETSIZE;
- res = select (fd_setsize, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
-#else
- res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
-#endif
- EV_ACQUIRE_CB;
-
- if (expect_false (res < 0))
- {
- #if EV_SELECT_IS_WINSOCKET
- errno = WSAGetLastError ();
- #endif
- #ifdef WSABASEERR
- /* on windows, select returns incompatible error codes, fix this */
- if (errno >= WSABASEERR && errno < WSABASEERR + 1000)
- if (errno == WSAENOTSOCK)
- errno = EBADF;
- else
- errno -= WSABASEERR;
- #endif
-
- #ifdef _WIN32
- /* select on windows erroneously returns EINVAL when no fd sets have been
- * provided (this is documented). what microsoft doesn't tell you that this bug
- * exists even when the fd sets _are_ provided, so we have to check for this bug
- * here and emulate by sleeping manually.
- * we also get EINVAL when the timeout is invalid, but we ignore this case here
- * and assume that EINVAL always means: you have to wait manually.
- */
- if (errno == EINVAL)
- {
- ev_sleep (timeout);
- return;
- }
- #endif
-
- if (errno == EBADF)
- fd_ebadf (EV_A);
- else if (errno == ENOMEM && !syserr_cb)
- fd_enomem (EV_A);
- else if (errno != EINTR)
- ev_syserr ("(libev) select");
-
- return;
- }
-
-#if EV_SELECT_USE_FD_SET
-
- {
- int fd;
-
- for (fd = 0; fd < anfdmax; ++fd)
- if (anfds [fd].events)
- {
- int events = 0;
- #if EV_SELECT_IS_WINSOCKET
- SOCKET handle = anfds [fd].handle;
- #else
- int handle = fd;
- #endif
-
- if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
- if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
- #ifdef _WIN32
- if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
- #endif
-
- if (expect_true (events))
- fd_event (EV_A_ fd, events);
- }
- }
-
-#else
-
- {
- int word, bit;
- for (word = vec_max; word--; )
- {
- fd_mask word_r = ((fd_mask *)vec_ro) [word];
- fd_mask word_w = ((fd_mask *)vec_wo) [word];
- #ifdef _WIN32
- word_w |= ((fd_mask *)vec_eo) [word];
- #endif
-
- if (word_r || word_w)
- for (bit = NFDBITS; bit--; )
- {
- fd_mask mask = 1UL << bit;
- int events = 0;
-
- events |= word_r & mask ? EV_READ : 0;
- events |= word_w & mask ? EV_WRITE : 0;
-
- if (expect_true (events))
- fd_event (EV_A_ word * NFDBITS + bit, events);
- }
- }
- }
-
-#endif
-}
-
-int inline_size
-select_init (EV_P_ int flags)
-{
- backend_fudge = 0.; /* posix says this is zero */
- backend_modify = select_modify;
- backend_poll = select_poll;
-
-#if EV_SELECT_USE_FD_SET
- vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri);
- vec_ro = ev_malloc (sizeof (fd_set));
- vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi);
- vec_wo = ev_malloc (sizeof (fd_set));
- #ifdef _WIN32
- vec_eo = ev_malloc (sizeof (fd_set));
- #endif
-#else
- vec_max = 0;
- vec_ri = 0;
- vec_ro = 0;
- vec_wi = 0;
- vec_wo = 0;
- #ifdef _WIN32
- vec_eo = 0;
- #endif
-#endif
-
- return EVBACKEND_SELECT;
-}
-
-void inline_size
-select_destroy (EV_P)
-{
- ev_free (vec_ri);
- ev_free (vec_ro);
- ev_free (vec_wi);
- ev_free (vec_wo);
- #ifdef _WIN32
- ev_free (vec_eo);
- #endif
-}
-
-
diff --git a/deps/uv/src/unix/ev/ev_vars.h b/deps/uv/src/unix/ev/ev_vars.h
deleted file mode 100644
index 5ee3ed1b2..000000000
--- a/deps/uv/src/unix/ev/ev_vars.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * loop member variable declarations
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#define VARx(type,name) VAR(name, type name)
-
-VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */
-VARx(ev_tstamp, mn_now) /* monotonic clock "now" */
-VARx(ev_tstamp, rtmn_diff) /* difference realtime - monotonic time */
-
-VARx(ev_tstamp, io_blocktime)
-VARx(ev_tstamp, timeout_blocktime)
-
-VARx(int, backend)
-VARx(int, activecnt) /* total number of active events ("refcount") */
-VARx(EV_ATOMIC_T, loop_done) /* signal by ev_break */
-
-VARx(int, backend_fd)
-VARx(ev_tstamp, backend_fudge) /* assumed typical timer resolution */
-VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev))
-VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout))
-
-VARx(ANFD *, anfds)
-VARx(int, anfdmax)
-
-VAR (pendings, ANPENDING *pendings [NUMPRI])
-VAR (pendingmax, int pendingmax [NUMPRI])
-VAR (pendingcnt, int pendingcnt [NUMPRI])
-VARx(ev_prepare, pending_w) /* dummy pending watcher */
-
-/* for reverse feeding of events */
-VARx(W *, rfeeds)
-VARx(int, rfeedmax)
-VARx(int, rfeedcnt)
-
-#if EV_USE_EVENTFD || EV_GENWRAP
-VARx(int, evfd)
-#endif
-VAR (evpipe, int evpipe [2])
-VARx(ev_io, pipe_w)
-
-#if !defined(_WIN32) || EV_GENWRAP
-VARx(pid_t, curpid)
-#endif
-
-VARx(char, postfork) /* true if we need to recreate kernel state after fork */
-
-#if EV_USE_SELECT || EV_GENWRAP
-VARx(void *, vec_ri)
-VARx(void *, vec_ro)
-VARx(void *, vec_wi)
-VARx(void *, vec_wo)
-#if defined(_WIN32) || EV_GENWRAP
-VARx(void *, vec_eo)
-#endif
-VARx(int, vec_max)
-#endif
-
-#if EV_USE_POLL || EV_GENWRAP
-VARx(struct pollfd *, polls)
-VARx(int, pollmax)
-VARx(int, pollcnt)
-VARx(int *, pollidxs) /* maps fds into structure indices */
-VARx(int, pollidxmax)
-#endif
-
-#if EV_USE_EPOLL || EV_GENWRAP
-VARx(struct epoll_event *, epoll_events)
-VARx(int, epoll_eventmax)
-VARx(int *, epoll_eperms)
-VARx(int, epoll_epermcnt)
-VARx(int, epoll_epermmax)
-#endif
-
-#if EV_USE_KQUEUE || EV_GENWRAP
-VARx(struct kevent *, kqueue_changes)
-VARx(int, kqueue_changemax)
-VARx(int, kqueue_changecnt)
-VARx(struct kevent *, kqueue_events)
-VARx(int, kqueue_eventmax)
-#endif
-
-#if EV_USE_PORT || EV_GENWRAP
-VARx(struct port_event *, port_events)
-VARx(int, port_eventmax)
-#endif
-
-#if EV_USE_IOCP || EV_GENWRAP
-VARx(HANDLE, iocp)
-#endif
-
-VARx(int *, fdchanges)
-VARx(int, fdchangemax)
-VARx(int, fdchangecnt)
-
-VARx(ANHE *, timers)
-VARx(int, timermax)
-VARx(int, timercnt)
-
-#if EV_PERIODIC_ENABLE || EV_GENWRAP
-VARx(ANHE *, periodics)
-VARx(int, periodicmax)
-VARx(int, periodiccnt)
-#endif
-
-#if EV_IDLE_ENABLE || EV_GENWRAP
-VAR (idles, ev_idle **idles [NUMPRI])
-VAR (idlemax, int idlemax [NUMPRI])
-VAR (idlecnt, int idlecnt [NUMPRI])
-#endif
-VARx(int, idleall) /* total number */
-
-VARx(struct ev_prepare **, prepares)
-VARx(int, preparemax)
-VARx(int, preparecnt)
-
-VARx(struct ev_check **, checks)
-VARx(int, checkmax)
-VARx(int, checkcnt)
-
-#if EV_FORK_ENABLE || EV_GENWRAP
-VARx(struct ev_fork **, forks)
-VARx(int, forkmax)
-VARx(int, forkcnt)
-#endif
-
-#if EV_CLEANUP_ENABLE || EV_GENWRAP
-VARx(struct ev_cleanup **, cleanups)
-VARx(int, cleanupmax)
-VARx(int, cleanupcnt)
-#endif
-
-#if EV_ASYNC_ENABLE || EV_GENWRAP
-VARx(EV_ATOMIC_T, async_pending)
-VARx(struct ev_async **, asyncs)
-VARx(int, asyncmax)
-VARx(int, asynccnt)
-#endif
-
-#if EV_USE_INOTIFY || EV_GENWRAP
-VARx(int, fs_fd)
-VARx(ev_io, fs_w)
-VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */
-VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE])
-#endif
-
-VARx(EV_ATOMIC_T, sig_pending)
-VARx(int, nosigmask)
-#if EV_USE_SIGNALFD || EV_GENWRAP
-VARx(int, sigfd)
-VARx(ev_io, sigfd_w)
-VARx(sigset_t, sigfd_set)
-#endif
-
-VARx(unsigned int, origflags) /* original loop flags */
-
-#if EV_FEATURE_API || EV_GENWRAP
-VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */
-VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */
-
-VARx(void *, userdata)
-VAR (release_cb, void (*release_cb)(EV_P))
-VAR (acquire_cb, void (*acquire_cb)(EV_P))
-VAR (invoke_cb , void (*invoke_cb) (EV_P))
-#endif
-
-#undef VARx
-
diff --git a/deps/uv/src/unix/ev/ev_win32.c b/deps/uv/src/unix/ev/ev_win32.c
deleted file mode 100644
index 338886efe..000000000
--- a/deps/uv/src/unix/ev/ev_win32.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * libev win32 compatibility cruft (_not_ a backend)
- *
- * Copyright (c) 2007,2008,2009 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifdef _WIN32
-
-/* timeb.h is actually xsi legacy functionality */
-#include <sys/timeb.h>
-
-/* note: the comment below could not be substantiated, but what would I care */
-/* MSDN says this is required to handle SIGFPE */
-/* my wild guess would be that using something floating-pointy is required */
-/* for the crt to do something about it */
-volatile double SIGFPE_REQ = 0.0f;
-
-/* oh, the humanity! */
-static int
-ev_pipe (int filedes [2])
-{
- struct sockaddr_in addr = { 0 };
- int addr_size = sizeof (addr);
- struct sockaddr_in adr2;
- int adr2_size = sizeof (adr2);
- SOCKET listener;
- SOCKET sock [2] = { -1, -1 };
-
- if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
- return -1;
-
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
- addr.sin_port = 0;
-
- if (bind (listener, (struct sockaddr *)&addr, addr_size))
- goto fail;
-
- if (getsockname (listener, (struct sockaddr *)&addr, &addr_size))
- goto fail;
-
- if (listen (listener, 1))
- goto fail;
-
- if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
- goto fail;
-
- if (connect (sock [0], (struct sockaddr *)&addr, addr_size))
- goto fail;
-
- if ((sock [1] = accept (listener, 0, 0)) < 0)
- goto fail;
-
- /* windows vista returns fantasy port numbers for sockets:
- * example for two interconnected tcp sockets:
- *
- * (Socket::unpack_sockaddr_in getsockname $sock0)[0] == 53364
- * (Socket::unpack_sockaddr_in getpeername $sock0)[0] == 53363
- * (Socket::unpack_sockaddr_in getsockname $sock1)[0] == 53363
- * (Socket::unpack_sockaddr_in getpeername $sock1)[0] == 53365
- *
- * wow! tridirectional sockets!
- *
- * this way of checking ports seems to work:
- */
- if (getpeername (sock [0], (struct sockaddr *)&addr, &addr_size))
- goto fail;
-
- if (getsockname (sock [1], (struct sockaddr *)&adr2, &adr2_size))
- goto fail;
-
- errno = WSAEINVAL;
- if (addr_size != adr2_size
- || addr.sin_addr.s_addr != adr2.sin_addr.s_addr /* just to be sure, I mean, it's windows */
- || addr.sin_port != adr2.sin_port)
- goto fail;
-
- closesocket (listener);
-
-#if EV_SELECT_IS_WINSOCKET
- filedes [0] = EV_WIN32_HANDLE_TO_FD (sock [0]);
- filedes [1] = EV_WIN32_HANDLE_TO_FD (sock [1]);
-#else
- /* when select isn't winsocket, we also expect socket, connect, accept etc.
- * to work on fds */
- filedes [0] = sock [0];
- filedes [1] = sock [1];
-#endif
-
- return 0;
-
-fail:
- closesocket (listener);
-
- if (sock [0] != INVALID_SOCKET) closesocket (sock [0]);
- if (sock [1] != INVALID_SOCKET) closesocket (sock [1]);
-
- return -1;
-}
-
-#undef pipe
-#define pipe(filedes) ev_pipe (filedes)
-
-#define EV_HAVE_EV_TIME 1
-ev_tstamp
-ev_time (void)
-{
- FILETIME ft;
- ULARGE_INTEGER ui;
-
- GetSystemTimeAsFileTime (&ft);
- ui.u.LowPart = ft.dwLowDateTime;
- ui.u.HighPart = ft.dwHighDateTime;
-
- /* msvc cannot convert ulonglong to double... yes, it is that sucky */
- return (LONGLONG)(ui.QuadPart - 116444736000000000) * 1e-7;
-}
-
-#endif
-
diff --git a/deps/uv/src/unix/ev/ev_wrap.h b/deps/uv/src/unix/ev/ev_wrap.h
deleted file mode 100644
index 2c195c5db..000000000
--- a/deps/uv/src/unix/ev/ev_wrap.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/* DO NOT EDIT, automatically generated by update_ev_wrap */
-#ifndef EV_WRAP_H
-#define EV_WRAP_H
-#define now_floor ((loop)->now_floor)
-#define mn_now ((loop)->mn_now)
-#define rtmn_diff ((loop)->rtmn_diff)
-#define io_blocktime ((loop)->io_blocktime)
-#define timeout_blocktime ((loop)->timeout_blocktime)
-#define backend ((loop)->backend)
-#define activecnt ((loop)->activecnt)
-#define loop_done ((loop)->loop_done)
-#define backend_fd ((loop)->backend_fd)
-#define backend_fudge ((loop)->backend_fudge)
-#define backend_modify ((loop)->backend_modify)
-#define backend_poll ((loop)->backend_poll)
-#define anfds ((loop)->anfds)
-#define anfdmax ((loop)->anfdmax)
-#define pendings ((loop)->pendings)
-#define pendingmax ((loop)->pendingmax)
-#define pendingcnt ((loop)->pendingcnt)
-#define pending_w ((loop)->pending_w)
-#define rfeeds ((loop)->rfeeds)
-#define rfeedmax ((loop)->rfeedmax)
-#define rfeedcnt ((loop)->rfeedcnt)
-#define evfd ((loop)->evfd)
-#define evpipe ((loop)->evpipe)
-#define pipe_w ((loop)->pipe_w)
-#define curpid ((loop)->curpid)
-#define postfork ((loop)->postfork)
-#define vec_ri ((loop)->vec_ri)
-#define vec_ro ((loop)->vec_ro)
-#define vec_wi ((loop)->vec_wi)
-#define vec_wo ((loop)->vec_wo)
-#define vec_eo ((loop)->vec_eo)
-#define vec_max ((loop)->vec_max)
-#define polls ((loop)->polls)
-#define pollmax ((loop)->pollmax)
-#define pollcnt ((loop)->pollcnt)
-#define pollidxs ((loop)->pollidxs)
-#define pollidxmax ((loop)->pollidxmax)
-#define epoll_events ((loop)->epoll_events)
-#define epoll_eventmax ((loop)->epoll_eventmax)
-#define epoll_eperms ((loop)->epoll_eperms)
-#define epoll_epermcnt ((loop)->epoll_epermcnt)
-#define epoll_epermmax ((loop)->epoll_epermmax)
-#define kqueue_changes ((loop)->kqueue_changes)
-#define kqueue_changemax ((loop)->kqueue_changemax)
-#define kqueue_changecnt ((loop)->kqueue_changecnt)
-#define kqueue_events ((loop)->kqueue_events)
-#define kqueue_eventmax ((loop)->kqueue_eventmax)
-#define port_events ((loop)->port_events)
-#define port_eventmax ((loop)->port_eventmax)
-#define iocp ((loop)->iocp)
-#define fdchanges ((loop)->fdchanges)
-#define fdchangemax ((loop)->fdchangemax)
-#define fdchangecnt ((loop)->fdchangecnt)
-#define timers ((loop)->timers)
-#define timermax ((loop)->timermax)
-#define timercnt ((loop)->timercnt)
-#define periodics ((loop)->periodics)
-#define periodicmax ((loop)->periodicmax)
-#define periodiccnt ((loop)->periodiccnt)
-#define idles ((loop)->idles)
-#define idlemax ((loop)->idlemax)
-#define idlecnt ((loop)->idlecnt)
-#define idleall ((loop)->idleall)
-#define prepares ((loop)->prepares)
-#define preparemax ((loop)->preparemax)
-#define preparecnt ((loop)->preparecnt)
-#define checks ((loop)->checks)
-#define checkmax ((loop)->checkmax)
-#define checkcnt ((loop)->checkcnt)
-#define forks ((loop)->forks)
-#define forkmax ((loop)->forkmax)
-#define forkcnt ((loop)->forkcnt)
-#define cleanups ((loop)->cleanups)
-#define cleanupmax ((loop)->cleanupmax)
-#define cleanupcnt ((loop)->cleanupcnt)
-#define async_pending ((loop)->async_pending)
-#define asyncs ((loop)->asyncs)
-#define asyncmax ((loop)->asyncmax)
-#define asynccnt ((loop)->asynccnt)
-#define fs_fd ((loop)->fs_fd)
-#define fs_w ((loop)->fs_w)
-#define fs_2625 ((loop)->fs_2625)
-#define fs_hash ((loop)->fs_hash)
-#define sig_pending ((loop)->sig_pending)
-#define nosigmask ((loop)->nosigmask)
-#define sigfd ((loop)->sigfd)
-#define sigfd_w ((loop)->sigfd_w)
-#define sigfd_set ((loop)->sigfd_set)
-#define origflags ((loop)->origflags)
-#define loop_count ((loop)->loop_count)
-#define loop_depth ((loop)->loop_depth)
-#define userdata ((loop)->userdata)
-#define release_cb ((loop)->release_cb)
-#define acquire_cb ((loop)->acquire_cb)
-#define invoke_cb ((loop)->invoke_cb)
-#else
-#undef EV_WRAP_H
-#undef now_floor
-#undef mn_now
-#undef rtmn_diff
-#undef io_blocktime
-#undef timeout_blocktime
-#undef backend
-#undef activecnt
-#undef loop_done
-#undef backend_fd
-#undef backend_fudge
-#undef backend_modify
-#undef backend_poll
-#undef anfds
-#undef anfdmax
-#undef pendings
-#undef pendingmax
-#undef pendingcnt
-#undef pending_w
-#undef rfeeds
-#undef rfeedmax
-#undef rfeedcnt
-#undef evfd
-#undef evpipe
-#undef pipe_w
-#undef curpid
-#undef postfork
-#undef vec_ri
-#undef vec_ro
-#undef vec_wi
-#undef vec_wo
-#undef vec_eo
-#undef vec_max
-#undef polls
-#undef pollmax
-#undef pollcnt
-#undef pollidxs
-#undef pollidxmax
-#undef epoll_events
-#undef epoll_eventmax
-#undef epoll_eperms
-#undef epoll_epermcnt
-#undef epoll_epermmax
-#undef kqueue_changes
-#undef kqueue_changemax
-#undef kqueue_changecnt
-#undef kqueue_events
-#undef kqueue_eventmax
-#undef port_events
-#undef port_eventmax
-#undef iocp
-#undef fdchanges
-#undef fdchangemax
-#undef fdchangecnt
-#undef timers
-#undef timermax
-#undef timercnt
-#undef periodics
-#undef periodicmax
-#undef periodiccnt
-#undef idles
-#undef idlemax
-#undef idlecnt
-#undef idleall
-#undef prepares
-#undef preparemax
-#undef preparecnt
-#undef checks
-#undef checkmax
-#undef checkcnt
-#undef forks
-#undef forkmax
-#undef forkcnt
-#undef cleanups
-#undef cleanupmax
-#undef cleanupcnt
-#undef async_pending
-#undef asyncs
-#undef asyncmax
-#undef asynccnt
-#undef fs_fd
-#undef fs_w
-#undef fs_2625
-#undef fs_hash
-#undef sig_pending
-#undef nosigmask
-#undef sigfd
-#undef sigfd_w
-#undef sigfd_set
-#undef origflags
-#undef loop_count
-#undef loop_depth
-#undef userdata
-#undef release_cb
-#undef acquire_cb
-#undef invoke_cb
-#endif
diff --git a/deps/uv/src/unix/ev/event.c b/deps/uv/src/unix/ev/event.c
deleted file mode 100644
index aaf6d534c..000000000
--- a/deps/uv/src/unix/ev/event.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * libevent compatibility layer
- *
- * Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#ifdef EV_EVENT_H
-# include EV_EVENT_H
-#else
-# include "event.h"
-#endif
-
-#if EV_MULTIPLICITY
-# define dLOOPev struct ev_loop *loop = (struct ev_loop *)ev->ev_base
-# define dLOOPbase struct ev_loop *loop = (struct ev_loop *)base
-#else
-# define dLOOPev
-# define dLOOPbase
-#endif
-
-/* never accessed, will always be cast from/to ev_loop */
-struct event_base
-{
- int dummy;
-};
-
-static struct event_base *ev_x_cur;
-
-static ev_tstamp
-ev_tv_get (struct timeval *tv)
-{
- if (tv)
- {
- ev_tstamp after = tv->tv_sec + tv->tv_usec * 1e-6;
- return after ? after : 1e-6;
- }
- else
- return -1.;
-}
-
-#define EVENT_STRINGIFY(s) # s
-#define EVENT_VERSION(a,b) EVENT_STRINGIFY (a) "." EVENT_STRINGIFY (b)
-
-const char *event_get_version (void)
-{
- /* returns ABI, not API or library, version */
- return EVENT_VERSION (EV_VERSION_MAJOR, EV_VERSION_MINOR);
-}
-
-const char *event_get_method (void)
-{
- return "libev";
-}
-
-void *event_init (void)
-{
-#if EV_MULTIPLICITY
- if (ev_x_cur)
- ev_x_cur = (struct event_base *)ev_loop_new (EVFLAG_AUTO);
- else
- ev_x_cur = (struct event_base *)ev_default_loop (EVFLAG_AUTO);
-#else
- assert (("libev: multiple event bases not supported when not compiled with EV_MULTIPLICITY", !ev_x_cur));
-
- ev_x_cur = (struct event_base *)(long)ev_default_loop (EVFLAG_AUTO);
-#endif
-
- return ev_x_cur;
-}
-
-void event_base_free (struct event_base *base)
-{
- dLOOPbase;
-
-#if EV_MULTIPLICITY
- if (!ev_is_default_loop (loop))
- ev_loop_destroy (loop);
-#endif
-}
-
-int event_dispatch (void)
-{
- return event_base_dispatch (ev_x_cur);
-}
-
-#ifdef EV_STANDALONE
-void event_set_log_callback (event_log_cb cb)
-{
- /* nop */
-}
-#endif
-
-int event_loop (int flags)
-{
- return event_base_loop (ev_x_cur, flags);
-}
-
-int event_loopexit (struct timeval *tv)
-{
- return event_base_loopexit (ev_x_cur, tv);
-}
-
-static void
-ev_x_cb (struct event *ev, int revents)
-{
- revents &= EV_READ | EV_WRITE | EV_TIMER | EV_SIGNAL;
-
- ev->ev_res = revents;
- ev->ev_callback (ev->ev_fd, (short)revents, ev->ev_arg);
-}
-
-static void
-ev_x_cb_sig (EV_P_ struct ev_signal *w, int revents)
-{
- struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.sig));
-
- if (revents & EV_ERROR)
- event_del (ev);
-
- ev_x_cb (ev, revents);
-}
-
-static void
-ev_x_cb_io (EV_P_ struct ev_io *w, int revents)
-{
- struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.io));
-
- if ((revents & EV_ERROR) || !(ev->ev_events & EV_PERSIST))
- event_del (ev);
-
- ev_x_cb (ev, revents);
-}
-
-static void
-ev_x_cb_to (EV_P_ struct ev_timer *w, int revents)
-{
- struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, to));
-
- event_del (ev);
-
- ev_x_cb (ev, revents);
-}
-
-void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg)
-{
- if (events & EV_SIGNAL)
- ev_init (&ev->iosig.sig, ev_x_cb_sig);
- else
- ev_init (&ev->iosig.io, ev_x_cb_io);
-
- ev_init (&ev->to, ev_x_cb_to);
-
- ev->ev_base = ev_x_cur; /* not threadsafe, but it's how libevent works */
- ev->ev_fd = fd;
- ev->ev_events = events;
- ev->ev_pri = 0;
- ev->ev_callback = cb;
- ev->ev_arg = arg;
- ev->ev_res = 0;
- ev->ev_flags = EVLIST_INIT;
-}
-
-int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
-{
- return event_base_once (ev_x_cur, fd, events, cb, arg, tv);
-}
-
-int event_add (struct event *ev, struct timeval *tv)
-{
- dLOOPev;
-
- if (ev->ev_events & EV_SIGNAL)
- {
- if (!ev_is_active (&ev->iosig.sig))
- {
- ev_signal_set (&ev->iosig.sig, ev->ev_fd);
- ev_signal_start (EV_A_ &ev->iosig.sig);
-
- ev->ev_flags |= EVLIST_SIGNAL;
- }
- }
- else if (ev->ev_events & (EV_READ | EV_WRITE))
- {
- if (!ev_is_active (&ev->iosig.io))
- {
- ev_io_set (&ev->iosig.io, ev->ev_fd, ev->ev_events & (EV_READ | EV_WRITE));
- ev_io_start (EV_A_ &ev->iosig.io);
-
- ev->ev_flags |= EVLIST_INSERTED;
- }
- }
-
- if (tv)
- {
- ev->to.repeat = ev_tv_get (tv);
- ev_timer_again (EV_A_ &ev->to);
- ev->ev_flags |= EVLIST_TIMEOUT;
- }
- else
- {
- ev_timer_stop (EV_A_ &ev->to);
- ev->ev_flags &= ~EVLIST_TIMEOUT;
- }
-
- ev->ev_flags |= EVLIST_ACTIVE;
-
- return 0;
-}
-
-int event_del (struct event *ev)
-{
- dLOOPev;
-
- if (ev->ev_events & EV_SIGNAL)
- ev_signal_stop (EV_A_ &ev->iosig.sig);
- else if (ev->ev_events & (EV_READ | EV_WRITE))
- ev_io_stop (EV_A_ &ev->iosig.io);
-
- if (ev_is_active (&ev->to))
- ev_timer_stop (EV_A_ &ev->to);
-
- ev->ev_flags = EVLIST_INIT;
-
- return 0;
-}
-
-void event_active (struct event *ev, int res, short ncalls)
-{
- dLOOPev;
-
- if (res & EV_TIMEOUT)
- ev_feed_event (EV_A_ &ev->to, res & EV_TIMEOUT);
-
- if (res & EV_SIGNAL)
- ev_feed_event (EV_A_ &ev->iosig.sig, res & EV_SIGNAL);
-
- if (res & (EV_READ | EV_WRITE))
- ev_feed_event (EV_A_ &ev->iosig.io, res & (EV_READ | EV_WRITE));
-}
-
-int event_pending (struct event *ev, short events, struct timeval *tv)
-{
- short revents = 0;
- dLOOPev;
-
- if (ev->ev_events & EV_SIGNAL)
- {
- /* sig */
- if (ev_is_active (&ev->iosig.sig) || ev_is_pending (&ev->iosig.sig))
- revents |= EV_SIGNAL;
- }
- else if (ev->ev_events & (EV_READ | EV_WRITE))
- {
- /* io */
- if (ev_is_active (&ev->iosig.io) || ev_is_pending (&ev->iosig.io))
- revents |= ev->ev_events & (EV_READ | EV_WRITE);
- }
-
- if (ev->ev_events & EV_TIMEOUT || ev_is_active (&ev->to) || ev_is_pending (&ev->to))
- {
- revents |= EV_TIMEOUT;
-
- if (tv)
- {
- ev_tstamp at = ev_now (EV_A);
-
- tv->tv_sec = (long)at;
- tv->tv_usec = (long)((at - (ev_tstamp)tv->tv_sec) * 1e6);
- }
- }
-
- return events & revents;
-}
-
-int event_priority_init (int npri)
-{
- return event_base_priority_init (ev_x_cur, npri);
-}
-
-int event_priority_set (struct event *ev, int pri)
-{
- ev->ev_pri = pri;
-
- return 0;
-}
-
-int event_base_set (struct event_base *base, struct event *ev)
-{
- ev->ev_base = base;
-
- return 0;
-}
-
-int event_base_loop (struct event_base *base, int flags)
-{
- dLOOPbase;
-
- ev_run (EV_A_ flags);
-
- return 0;
-}
-
-int event_base_dispatch (struct event_base *base)
-{
- return event_base_loop (base, 0);
-}
-
-static void
-ev_x_loopexit_cb (int revents, void *base)
-{
- dLOOPbase;
-
- ev_break (EV_A_ EVBREAK_ONE);
-}
-
-int event_base_loopexit (struct event_base *base, struct timeval *tv)
-{
- ev_tstamp after = ev_tv_get (tv);
- dLOOPbase;
-
- ev_once (EV_A_ -1, 0, after >= 0. ? after : 0., ev_x_loopexit_cb, (void *)base);
-
- return 0;
-}
-
-struct ev_x_once
-{
- int fd;
- void (*cb)(int, short, void *);
- void *arg;
-};
-
-static void
-ev_x_once_cb (int revents, void *arg)
-{
- struct ev_x_once *once = (struct ev_x_once *)arg;
-
- once->cb (once->fd, (short)revents, once->arg);
- free (once);
-}
-
-int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
-{
- struct ev_x_once *once = (struct ev_x_once *)malloc (sizeof (struct ev_x_once));
- dLOOPbase;
-
- if (!once)
- return -1;
-
- once->fd = fd;
- once->cb = cb;
- once->arg = arg;
-
- ev_once (EV_A_ fd, events & (EV_READ | EV_WRITE), ev_tv_get (tv), ev_x_once_cb, (void *)once);
-
- return 0;
-}
-
-int event_base_priority_init (struct event_base *base, int npri)
-{
- /*dLOOPbase;*/
-
- return 0;
-}
-
diff --git a/deps/uv/src/unix/ev/event.h b/deps/uv/src/unix/ev/event.h
deleted file mode 100644
index 10ff05a3c..000000000
--- a/deps/uv/src/unix/ev/event.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * libevent compatibility header, only core events supported
- *
- * Copyright (c) 2007,2008,2010 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, 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 OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifndef EVENT_H_
-#define EVENT_H_
-
-#ifdef EV_H
-# include EV_H
-#else
-# include "ev.h"
-#endif
-
-#ifndef EVLOOP_NONBLOCK
-# define EVLOOP_NONBLOCK EVRUN_NOWAIT
-#endif
-#ifndef EVLOOP_ONESHOT
-# define EVLOOP_ONESHOT EVRUN_ONCE
-#endif
-#ifndef EV_TIMEOUT
-# define EV_TIMEOUT EV_TIMER
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* we need sys/time.h for struct timeval only */
-#if !defined (WIN32) || defined (__MINGW32__)
-# include <time.h> /* mingw seems to need this, for whatever reason */
-# include <sys/time.h>
-#endif
-
-struct event_base;
-
-#define EVLIST_TIMEOUT 0x01
-#define EVLIST_INSERTED 0x02
-#define EVLIST_SIGNAL 0x04
-#define EVLIST_ACTIVE 0x08
-#define EVLIST_INTERNAL 0x10
-#define EVLIST_INIT 0x80
-
-struct event
-{
- /* libev watchers we map onto */
- union {
- struct ev_io io;
- struct ev_signal sig;
- } iosig;
- struct ev_timer to;
-
- /* compatibility slots */
- struct event_base *ev_base;
- void (*ev_callback)(int, short, void *arg);
- void *ev_arg;
- int ev_fd;
- int ev_pri;
- int ev_res;
- int ev_flags;
- short ev_events;
-};
-
-#define EV_READ EV_READ
-#define EV_WRITE EV_WRITE
-#define EV_PERSIST 0x10
-
-#define EVENT_SIGNAL(ev) ((int) (ev)->ev_fd)
-#define EVENT_FD(ev) ((int) (ev)->ev_fd)
-
-#define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT)
-
-#define evtimer_add(ev,tv) event_add (ev, tv)
-#define evtimer_set(ev,cb,data) event_set (ev, -1, 0, cb, data)
-#define evtimer_del(ev) event_del (ev)
-#define evtimer_pending(ev,tv) event_pending (ev, EV_TIMEOUT, tv)
-#define evtimer_initialized(ev) event_initialized (ev)
-
-#define timeout_add(ev,tv) evtimer_add (ev, tv)
-#define timeout_set(ev,cb,data) evtimer_set (ev, cb, data)
-#define timeout_del(ev) evtimer_del (ev)
-#define timeout_pending(ev,tv) evtimer_pending (ev, tv)
-#define timeout_initialized(ev) evtimer_initialized (ev)
-
-#define signal_add(ev,tv) event_add (ev, tv)
-#define signal_set(ev,sig,cb,data) event_set (ev, sig, EV_SIGNAL | EV_PERSIST, cb, data)
-#define signal_del(ev) event_del (ev)
-#define signal_pending(ev,tv) event_pending (ev, EV_SIGNAL, tv)
-#define signal_initialized(ev) event_initialized (ev)
-
-const char *event_get_version (void);
-const char *event_get_method (void);
-
-void *event_init (void);
-void event_base_free (struct event_base *base);
-
-#define EVLOOP_ONCE EVLOOP_ONESHOT
-int event_loop (int);
-int event_loopexit (struct timeval *tv);
-int event_dispatch (void);
-
-#define _EVENT_LOG_DEBUG 0
-#define _EVENT_LOG_MSG 1
-#define _EVENT_LOG_WARN 2
-#define _EVENT_LOG_ERR 3
-typedef void (*event_log_cb)(int severity, const char *msg);
-void event_set_log_callback(event_log_cb cb);
-
-void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg);
-int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv);
-
-int event_add (struct event *ev, struct timeval *tv);
-int event_del (struct event *ev);
-void event_active (struct event *ev, int res, short ncalls); /* ncalls is being ignored */
-
-int event_pending (struct event *ev, short, struct timeval *tv);
-
-int event_priority_init (int npri);
-int event_priority_set (struct event *ev, int pri);
-
-int event_base_set (struct event_base *base, struct event *ev);
-int event_base_loop (struct event_base *base, int);
-int event_base_loopexit (struct event_base *base, struct timeval *tv);
-int event_base_dispatch (struct event_base *base);
-int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv);
-int event_base_priority_init (struct event_base *base, int fd);
-
-/* next line is different in the libevent+libev version */
-/*libevent-include*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/deps/uv/src/unix/ev/install-sh b/deps/uv/src/unix/ev/install-sh
deleted file mode 100755
index 6ce63b9f7..000000000
--- a/deps/uv/src/unix/ev/install-sh
+++ /dev/null
@@ -1,294 +0,0 @@
-#!/bin/sh
-#
-# install - install a program, script, or datafile
-#
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# 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
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch. It can only install one file at a time, a restriction
-# shared with many OS's install programs.
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd=$cpprog
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd=$stripprog
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "$0: no input file specified" >&2
- exit 1
-else
- :
-fi
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d "$dst" ]; then
- instcmd=:
- chmodcmd=""
- else
- instcmd=$mkdirprog
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f "$src" ] || [ -d "$src" ]
- then
- :
- else
- echo "$0: $src does not exist" >&2
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "$0: no destination specified" >&2
- exit 1
- else
- :
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d "$dst" ]
- then
- dst=$dst/`basename "$src"`
- else
- :
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
- '
-IFS="${IFS-$defaultIFS}"
-
-oIFS=$IFS
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS=$oIFS
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp=$pathcomp$1
- shift
-
- if [ ! -d "$pathcomp" ] ;
- then
- $mkdirprog "$pathcomp"
- else
- :
- fi
-
- pathcomp=$pathcomp/
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd "$dst" &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename "$dst"`
- else
- dstfile=`basename "$dst" $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename "$dst"`
- else
- :
- fi
-
-# Make a couple of temp file names in the proper directory.
-
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
-
-# Trap to clean up temp files at exit.
-
- trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
- trap '(exit $?); exit' 1 2 13 15
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd "$src" "$dsttmp" &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
-
-# Now remove or move aside any old file at destination location. We try this
-# two ways since rm can't unlink itself on some systems and the destination
-# file might be busy for other reasons. In this case, the final cleanup
-# might fail but the new file should still install successfully.
-
-{
- if [ -f "$dstdir/$dstfile" ]
- then
- $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
- $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
- {
- echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
- (exit 1); exit
- }
- else
- :
- fi
-} &&
-
-# Now rename the file to the real destination.
-
- $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
-
-fi &&
-
-# The final little trick to "correctly" pass the exit status to the exit trap.
-
-{
- (exit 0); exit
-}
diff --git a/deps/uv/src/unix/ev/libev.m4 b/deps/uv/src/unix/ev/libev.m4
deleted file mode 100644
index e3f4c81b2..000000000
--- a/deps/uv/src/unix/ev/libev.m4
+++ /dev/null
@@ -1,39 +0,0 @@
-dnl this file is part of libev, do not make local modifications
-dnl http://software.schmorp.de/pkg/libev
-
-dnl libev support
-AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h port.h poll.h sys/select.h sys/eventfd.h sys/signalfd.h)
-
-AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select eventfd signalfd)
-
-AC_CHECK_FUNCS(clock_gettime, [], [
- dnl on linux, try syscall wrapper first
- if test $(uname) = Linux; then
- AC_MSG_CHECKING(for clock_gettime syscall)
- AC_LINK_IFELSE([AC_LANG_PROGRAM(
- [#include <unistd.h>
- #include <sys/syscall.h>
- #include <time.h>],
- [struct timespec ts; int status = syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts)])],
- [ac_have_clock_syscall=1
- AC_DEFINE(HAVE_CLOCK_SYSCALL, 1, "use syscall interface for clock_gettime")
- AC_MSG_RESULT(yes)],
- [AC_MSG_RESULT(no)])
- fi
- if test -z "$LIBEV_M4_AVOID_LIBRT" && test -z "$ac_have_clock_syscall"; then
- AC_CHECK_LIB(rt, clock_gettime)
- unset ac_cv_func_clock_gettime
- AC_CHECK_FUNCS(clock_gettime)
- fi
-])
-
-AC_CHECK_FUNCS(nanosleep, [], [
- if test -z "$LIBEV_M4_AVOID_LIBRT"; then
- AC_CHECK_LIB(rt, nanosleep)
- unset ac_cv_func_nanosleep
- AC_CHECK_FUNCS(nanosleep)
- fi
-])
-
-AC_CHECK_LIB(m, ceil)
-
diff --git a/deps/uv/src/unix/ev/ltmain.sh b/deps/uv/src/unix/ev/ltmain.sh
deleted file mode 100755
index d88da2c26..000000000
--- a/deps/uv/src/unix/ev/ltmain.sh
+++ /dev/null
@@ -1,8413 +0,0 @@
-# Generated from ltmain.m4sh.
-
-# ltmain.sh (GNU libtool) 2.2.6b
-# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# GNU Libtool is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# As a special exception to the GNU General Public License,
-# if you distribute this file as part of a program or library that
-# is built using GNU Libtool, you may include this file under the
-# same distribution terms that you use for the rest of that program.
-#
-# GNU Libtool is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Libtool; see the file COPYING. If not, a copy
-# can be downloaded from http://www.gnu.org/licenses/gpl.html,
-# or obtained by writing to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-# Usage: $progname [OPTION]... [MODE-ARG]...
-#
-# Provide generalized library-building support services.
-#
-# --config show all configuration variables
-# --debug enable verbose shell tracing
-# -n, --dry-run display commands without modifying any files
-# --features display basic configuration information and exit
-# --mode=MODE use operation mode MODE
-# --preserve-dup-deps don't remove duplicate dependency libraries
-# --quiet, --silent don't print informational messages
-# --tag=TAG use configuration variables from tag TAG
-# -v, --verbose print informational messages (default)
-# --version print version information
-# -h, --help print short or long help message
-#
-# MODE must be one of the following:
-#
-# clean remove files from the build directory
-# compile compile a source file into a libtool object
-# execute automatically set library path, then run a program
-# finish complete the installation of libtool libraries
-# install install libraries or executables
-# link create a library or an executable
-# uninstall remove libraries from an installed directory
-#
-# MODE-ARGS vary depending on the MODE.
-# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
-#
-# When reporting a bug, please describe a test case to reproduce it and
-# include the following information:
-#
-# host-triplet: $host
-# shell: $SHELL
-# compiler: $LTCC
-# compiler flags: $LTCFLAGS
-# linker: $LD (gnu? $with_gnu_ld)
-# $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2
-# automake: $automake_version
-# autoconf: $autoconf_version
-#
-# Report bugs to <bug-libtool@gnu.org>.
-
-PROGRAM=ltmain.sh
-PACKAGE=libtool
-VERSION="2.2.6b Debian-2.2.6b-2"
-TIMESTAMP=""
-package_revision=1.3017
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-# NLS nuisances: We save the old values to restore during execute mode.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-lt_user_locale=
-lt_safe_locale=
-for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
-do
- eval "if test \"\${$lt_var+set}\" = set; then
- save_$lt_var=\$$lt_var
- $lt_var=C
- export $lt_var
- lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
- lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
- fi"
-done
-
-$lt_unset CDPATH
-
-
-
-
-
-: ${CP="cp -f"}
-: ${ECHO="echo"}
-: ${EGREP="/bin/grep -E"}
-: ${FGREP="/bin/grep -F"}
-: ${GREP="/bin/grep"}
-: ${LN_S="ln -s"}
-: ${MAKE="make"}
-: ${MKDIR="mkdir"}
-: ${MV="mv -f"}
-: ${RM="rm -f"}
-: ${SED="/bin/sed"}
-: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
-: ${Xsed="$SED -e 1s/^X//"}
-
-# Global variables:
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
-EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
-EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
-
-exit_status=$EXIT_SUCCESS
-
-# Make sure IFS has a sensible default
-lt_nl='
-'
-IFS=" $lt_nl"
-
-dirname="s,/[^/]*$,,"
-basename="s,^.*/,,"
-
-# func_dirname_and_basename file append nondir_replacement
-# perform func_basename and func_dirname in a single function
-# call:
-# dirname: Compute the dirname of FILE. If nonempty,
-# add APPEND to the result, otherwise set result
-# to NONDIR_REPLACEMENT.
-# value returned in "$func_dirname_result"
-# basename: Compute filename of FILE.
-# value retuned in "$func_basename_result"
-# Implementation must be kept synchronized with func_dirname
-# and func_basename. For efficiency, we do not delegate to
-# those functions but instead duplicate the functionality here.
-func_dirname_and_basename ()
-{
- # Extract subdirectory from the argument.
- func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
- if test "X$func_dirname_result" = "X${1}"; then
- func_dirname_result="${3}"
- else
- func_dirname_result="$func_dirname_result${2}"
- fi
- func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
-}
-
-# Generated shell functions inserted here.
-
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath="$0"
-
-# The name of this program:
-# In the unlikely event $progname began with a '-', it would play havoc with
-# func_echo (imagine progname=-n), so we prepend ./ in that case:
-func_dirname_and_basename "$progpath"
-progname=$func_basename_result
-case $progname in
- -*) progname=./$progname ;;
-esac
-
-# Make sure we have an absolute path for reexecution:
-case $progpath in
- [\\/]*|[A-Za-z]:\\*) ;;
- *[\\/]*)
- progdir=$func_dirname_result
- progdir=`cd "$progdir" && pwd`
- progpath="$progdir/$progname"
- ;;
- *)
- save_IFS="$IFS"
- IFS=:
- for progdir in $PATH; do
- IFS="$save_IFS"
- test -x "$progdir/$progname" && break
- done
- IFS="$save_IFS"
- test -n "$progdir" || progdir=`pwd`
- progpath="$progdir/$progname"
- ;;
-esac
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed="${SED}"' -e 1s/^X//'
-sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\(["`\\]\)/\\\1/g'
-
-# Re-`\' parameter expansions in output of double_quote_subst that were
-# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
-# in input to double_quote_subst, that '$' was protected from expansion.
-# Since each input `\' is now two `\'s, look for any number of runs of
-# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
-bs='\\'
-bs2='\\\\'
-bs4='\\\\\\\\'
-dollar='\$'
-sed_double_backslash="\
- s/$bs4/&\\
-/g
- s/^$bs2$dollar/$bs&/
- s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
- s/\n//g"
-
-# Standard options:
-opt_dry_run=false
-opt_help=false
-opt_quiet=false
-opt_verbose=false
-opt_warning=:
-
-# func_echo arg...
-# Echo program name prefixed message, along with the current mode
-# name if it has been set yet.
-func_echo ()
-{
- $ECHO "$progname${mode+: }$mode: $*"
-}
-
-# func_verbose arg...
-# Echo program name prefixed message in verbose mode only.
-func_verbose ()
-{
- $opt_verbose && func_echo ${1+"$@"}
-
- # A bug in bash halts the script if the last line of a function
- # fails when set -e is in force, so we need another command to
- # work around that:
- :
-}
-
-# func_error arg...
-# Echo program name prefixed message to standard error.
-func_error ()
-{
- $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
-}
-
-# func_warning arg...
-# Echo program name prefixed warning message to standard error.
-func_warning ()
-{
- $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
-
- # bash bug again:
- :
-}
-
-# func_fatal_error arg...
-# Echo program name prefixed message to standard error, and exit.
-func_fatal_error ()
-{
- func_error ${1+"$@"}
- exit $EXIT_FAILURE
-}
-
-# func_fatal_help arg...
-# Echo program name prefixed message to standard error, followed by
-# a help hint, and exit.
-func_fatal_help ()
-{
- func_error ${1+"$@"}
- func_fatal_error "$help"
-}
-help="Try \`$progname --help' for more information." ## default
-
-
-# func_grep expression filename
-# Check whether EXPRESSION matches any line of FILENAME, without output.
-func_grep ()
-{
- $GREP "$1" "$2" >/dev/null 2>&1
-}
-
-
-# func_mkdir_p directory-path
-# Make sure the entire path to DIRECTORY-PATH is available.
-func_mkdir_p ()
-{
- my_directory_path="$1"
- my_dir_list=
-
- if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
-
- # Protect directory names starting with `-'
- case $my_directory_path in
- -*) my_directory_path="./$my_directory_path" ;;
- esac
-
- # While some portion of DIR does not yet exist...
- while test ! -d "$my_directory_path"; do
- # ...make a list in topmost first order. Use a colon delimited
- # list incase some portion of path contains whitespace.
- my_dir_list="$my_directory_path:$my_dir_list"
-
- # If the last portion added has no slash in it, the list is done
- case $my_directory_path in */*) ;; *) break ;; esac
-
- # ...otherwise throw away the child directory and loop
- my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
- done
- my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
-
- save_mkdir_p_IFS="$IFS"; IFS=':'
- for my_dir in $my_dir_list; do
- IFS="$save_mkdir_p_IFS"
- # mkdir can fail with a `File exist' error if two processes
- # try to create one of the directories concurrently. Don't
- # stop in that case!
- $MKDIR "$my_dir" 2>/dev/null || :
- done
- IFS="$save_mkdir_p_IFS"
-
- # Bail out if we (or some other process) failed to create a directory.
- test -d "$my_directory_path" || \
- func_fatal_error "Failed to create \`$1'"
- fi
-}
-
-
-# func_mktempdir [string]
-# Make a temporary directory that won't clash with other running
-# libtool processes, and avoids race conditions if possible. If
-# given, STRING is the basename for that directory.
-func_mktempdir ()
-{
- my_template="${TMPDIR-/tmp}/${1-$progname}"
-
- if test "$opt_dry_run" = ":"; then
- # Return a directory name, but don't create it in dry-run mode
- my_tmpdir="${my_template}-$$"
- else
-
- # If mktemp works, use that first and foremost
- my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
-
- if test ! -d "$my_tmpdir"; then
- # Failing that, at least try and use $RANDOM to avoid a race
- my_tmpdir="${my_template}-${RANDOM-0}$$"
-
- save_mktempdir_umask=`umask`
- umask 0077
- $MKDIR "$my_tmpdir"
- umask $save_mktempdir_umask
- fi
-
- # If we're not in dry-run mode, bomb out on failure
- test -d "$my_tmpdir" || \
- func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
- fi
-
- $ECHO "X$my_tmpdir" | $Xsed
-}
-
-
-# func_quote_for_eval arg
-# Aesthetically quote ARG to be evaled later.
-# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
-# is double-quoted, suitable for a subsequent eval, whereas
-# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
-# which are still active within double quotes backslashified.
-func_quote_for_eval ()
-{
- case $1 in
- *[\\\`\"\$]*)
- func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
- *)
- func_quote_for_eval_unquoted_result="$1" ;;
- esac
-
- case $func_quote_for_eval_unquoted_result in
- # Double-quote args containing shell metacharacters to delay
- # word splitting, command substitution and and variable
- # expansion for a subsequent eval.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
- ;;
- *)
- func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
- esac
-}
-
-
-# func_quote_for_expand arg
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
-{
- case $1 in
- *[\\\`\"]*)
- my_arg=`$ECHO "X$1" | $Xsed \
- -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
- *)
- my_arg="$1" ;;
- esac
-
- case $my_arg in
- # Double-quote args containing shell metacharacters to delay
- # word splitting and command substitution for a subsequent eval.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- my_arg="\"$my_arg\""
- ;;
- esac
-
- func_quote_for_expand_result="$my_arg"
-}
-
-
-# func_show_eval cmd [fail_exp]
-# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
-# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.
-func_show_eval ()
-{
- my_cmd="$1"
- my_fail_exp="${2-:}"
-
- ${opt_silent-false} || {
- func_quote_for_expand "$my_cmd"
- eval "func_echo $func_quote_for_expand_result"
- }
-
- if ${opt_dry_run-false}; then :; else
- eval "$my_cmd"
- my_status=$?
- if test "$my_status" -eq 0; then :; else
- eval "(exit $my_status); $my_fail_exp"
- fi
- fi
-}
-
-
-# func_show_eval_locale cmd [fail_exp]
-# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
-# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it. Use the saved locale for evaluation.
-func_show_eval_locale ()
-{
- my_cmd="$1"
- my_fail_exp="${2-:}"
-
- ${opt_silent-false} || {
- func_quote_for_expand "$my_cmd"
- eval "func_echo $func_quote_for_expand_result"
- }
-
- if ${opt_dry_run-false}; then :; else
- eval "$lt_user_locale
- $my_cmd"
- my_status=$?
- eval "$lt_safe_locale"
- if test "$my_status" -eq 0; then :; else
- eval "(exit $my_status); $my_fail_exp"
- fi
- fi
-}
-
-
-
-
-
-# func_version
-# Echo version message to standard output and exit.
-func_version ()
-{
- $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {
- s/^# //
- s/^# *$//
- s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
- p
- }' < "$progpath"
- exit $?
-}
-
-# func_usage
-# Echo short help message to standard output and exit.
-func_usage ()
-{
- $SED -n '/^# Usage:/,/# -h/ {
- s/^# //
- s/^# *$//
- s/\$progname/'$progname'/
- p
- }' < "$progpath"
- $ECHO
- $ECHO "run \`$progname --help | more' for full usage"
- exit $?
-}
-
-# func_help
-# Echo long help message to standard output and exit.
-func_help ()
-{
- $SED -n '/^# Usage:/,/# Report bugs to/ {
- s/^# //
- s/^# *$//
- s*\$progname*'$progname'*
- s*\$host*'"$host"'*
- s*\$SHELL*'"$SHELL"'*
- s*\$LTCC*'"$LTCC"'*
- s*\$LTCFLAGS*'"$LTCFLAGS"'*
- s*\$LD*'"$LD"'*
- s/\$with_gnu_ld/'"$with_gnu_ld"'/
- s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
- s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
- p
- }' < "$progpath"
- exit $?
-}
-
-# func_missing_arg argname
-# Echo program name prefixed message to standard error and set global
-# exit_cmd.
-func_missing_arg ()
-{
- func_error "missing argument for $1"
- exit_cmd=exit
-}
-
-exit_cmd=:
-
-
-
-
-
-# Check that we have a working $ECHO.
-if test "X$1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X$1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
- # Yippee, $ECHO works!
- :
-else
- # Restart under the correct shell, and then maybe $ECHO will work.
- exec $SHELL "$progpath" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<EOF
-$*
-EOF
- exit $EXIT_SUCCESS
-fi
-
-magic="%%%MAGIC variable%%%"
-magic_exe="%%%MAGIC EXE variable%%%"
-
-# Global variables.
-# $mode is unset
-nonopt=
-execute_dlfiles=
-preserve_args=
-lo2o="s/\\.lo\$/.${objext}/"
-o2lo="s/\\.${objext}\$/.lo/"
-extracted_archives=
-extracted_serial=0
-
-opt_dry_run=false
-opt_duplicate_deps=false
-opt_silent=false
-opt_debug=:
-
-# If this variable is set in any of the actions, the command in it
-# will be execed at the end. This prevents here-documents from being
-# left over by shells.
-exec_cmd=
-
-# func_fatal_configuration arg...
-# Echo program name prefixed message to standard error, followed by
-# a configuration failure hint, and exit.
-func_fatal_configuration ()
-{
- func_error ${1+"$@"}
- func_error "See the $PACKAGE documentation for more information."
- func_fatal_error "Fatal configuration error."
-}
-
-
-# func_config
-# Display the configuration for all the tags in this script.
-func_config ()
-{
- re_begincf='^# ### BEGIN LIBTOOL'
- re_endcf='^# ### END LIBTOOL'
-
- # Default configuration.
- $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
-
- # Now print the configurations for the tags.
- for tagname in $taglist; do
- $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
- done
-
- exit $?
-}
-
-# func_features
-# Display the features supported by this script.
-func_features ()
-{
- $ECHO "host: $host"
- if test "$build_libtool_libs" = yes; then
- $ECHO "enable shared libraries"
- else
- $ECHO "disable shared libraries"
- fi
- if test "$build_old_libs" = yes; then
- $ECHO "enable static libraries"
- else
- $ECHO "disable static libraries"
- fi
-
- exit $?
-}
-
-# func_enable_tag tagname
-# Verify that TAGNAME is valid, and either flag an error and exit, or
-# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
-# variable here.
-func_enable_tag ()
-{
- # Global variable:
- tagname="$1"
-
- re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
- re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
- sed_extractcf="/$re_begincf/,/$re_endcf/p"
-
- # Validate tagname.
- case $tagname in
- *[!-_A-Za-z0-9,/]*)
- func_fatal_error "invalid tag name: $tagname"
- ;;
- esac
-
- # Don't test for the "default" C tag, as we know it's
- # there but not specially marked.
- case $tagname in
- CC) ;;
- *)
- if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
- taglist="$taglist $tagname"
-
- # Evaluate the configuration. Be careful to quote the path
- # and the sed script, to avoid splitting on whitespace, but
- # also don't use non-portable quotes within backquotes within
- # quotes we have to do it in 2 steps:
- extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
- eval "$extractedcf"
- else
- func_error "ignoring unknown tag $tagname"
- fi
- ;;
- esac
-}
-
-# Parse options once, thoroughly. This comes as soon as possible in
-# the script to make things like `libtool --version' happen quickly.
-{
-
- # Shorthand for --mode=foo, only valid as the first argument
- case $1 in
- clean|clea|cle|cl)
- shift; set dummy --mode clean ${1+"$@"}; shift
- ;;
- compile|compil|compi|comp|com|co|c)
- shift; set dummy --mode compile ${1+"$@"}; shift
- ;;
- execute|execut|execu|exec|exe|ex|e)
- shift; set dummy --mode execute ${1+"$@"}; shift
- ;;
- finish|finis|fini|fin|fi|f)
- shift; set dummy --mode finish ${1+"$@"}; shift
- ;;
- install|instal|insta|inst|ins|in|i)
- shift; set dummy --mode install ${1+"$@"}; shift
- ;;
- link|lin|li|l)
- shift; set dummy --mode link ${1+"$@"}; shift
- ;;
- uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
- shift; set dummy --mode uninstall ${1+"$@"}; shift
- ;;
- esac
-
- # Parse non-mode specific arguments:
- while test "$#" -gt 0; do
- opt="$1"
- shift
-
- case $opt in
- --config) func_config ;;
-
- --debug) preserve_args="$preserve_args $opt"
- func_echo "enabling shell trace mode"
- opt_debug='set -x'
- $opt_debug
- ;;
-
- -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break
- execute_dlfiles="$execute_dlfiles $1"
- shift
- ;;
-
- --dry-run | -n) opt_dry_run=: ;;
- --features) func_features ;;
- --finish) mode="finish" ;;
-
- --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break
- case $1 in
- # Valid mode arguments:
- clean) ;;
- compile) ;;
- execute) ;;
- finish) ;;
- install) ;;
- link) ;;
- relink) ;;
- uninstall) ;;
-
- # Catch anything else as an error
- *) func_error "invalid argument for $opt"
- exit_cmd=exit
- break
- ;;
- esac
-
- mode="$1"
- shift
- ;;
-
- --preserve-dup-deps)
- opt_duplicate_deps=: ;;
-
- --quiet|--silent) preserve_args="$preserve_args $opt"
- opt_silent=:
- ;;
-
- --verbose| -v) preserve_args="$preserve_args $opt"
- opt_silent=false
- ;;
-
- --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break
- preserve_args="$preserve_args $opt $1"
- func_enable_tag "$1" # tagname is set here
- shift
- ;;
-
- # Separate optargs to long options:
- -dlopen=*|--mode=*|--tag=*)
- func_opt_split "$opt"
- set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
- shift
- ;;
-
- -\?|-h) func_usage ;;
- --help) opt_help=: ;;
- --version) func_version ;;
-
- -*) func_fatal_help "unrecognized option \`$opt'" ;;
-
- *) nonopt="$opt"
- break
- ;;
- esac
- done
-
-
- case $host in
- *cygwin* | *mingw* | *pw32* | *cegcc*)
- # don't eliminate duplications in $postdeps and $predeps
- opt_duplicate_compiler_generated_deps=:
- ;;
- *)
- opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
- ;;
- esac
-
- # Having warned about all mis-specified options, bail out if
- # anything was wrong.
- $exit_cmd $EXIT_FAILURE
-}
-
-# func_check_version_match
-# Ensure that we are using m4 macros, and libtool script from the same
-# release of libtool.
-func_check_version_match ()
-{
- if test "$package_revision" != "$macro_revision"; then
- if test "$VERSION" != "$macro_version"; then
- if test -z "$macro_version"; then
- cat >&2 <<_LT_EOF
-$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
-$progname: definition of this LT_INIT comes from an older release.
-$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
-$progname: and run autoconf again.
-_LT_EOF
- else
- cat >&2 <<_LT_EOF
-$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
-$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
-$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
-$progname: and run autoconf again.
-_LT_EOF
- fi
- else
- cat >&2 <<_LT_EOF
-$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
-$progname: but the definition of this LT_INIT comes from revision $macro_revision.
-$progname: You should recreate aclocal.m4 with macros from revision $package_revision
-$progname: of $PACKAGE $VERSION and run autoconf again.
-_LT_EOF
- fi
-
- exit $EXIT_MISMATCH
- fi
-}
-
-
-## ----------- ##
-## Main. ##
-## ----------- ##
-
-$opt_help || {
- # Sanity checks first:
- func_check_version_match
-
- if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
- func_fatal_configuration "not configured to build any kind of library"
- fi
-
- test -z "$mode" && func_fatal_error "error: you must specify a MODE."
-
-
- # Darwin sucks
- eval std_shrext=\"$shrext_cmds\"
-
-
- # Only execute mode is allowed to have -dlopen flags.
- if test -n "$execute_dlfiles" && test "$mode" != execute; then
- func_error "unrecognized option \`-dlopen'"
- $ECHO "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # Change the help message to a mode-specific one.
- generic_help="$help"
- help="Try \`$progname --help --mode=$mode' for more information."
-}
-
-
-# func_lalib_p file
-# True iff FILE is a libtool `.la' library or `.lo' object file.
-# This function is only a basic sanity check; it will hardly flush out
-# determined imposters.
-func_lalib_p ()
-{
- test -f "$1" &&
- $SED -e 4q "$1" 2>/dev/null \
- | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
-}
-
-# func_lalib_unsafe_p file
-# True iff FILE is a libtool `.la' library or `.lo' object file.
-# This function implements the same check as func_lalib_p without
-# resorting to external programs. To this end, it redirects stdin and
-# closes it afterwards, without saving the original file descriptor.
-# As a safety measure, use it only where a negative result would be
-# fatal anyway. Works if `file' does not exist.
-func_lalib_unsafe_p ()
-{
- lalib_p=no
- if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
- for lalib_p_l in 1 2 3 4
- do
- read lalib_p_line
- case "$lalib_p_line" in
- \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
- esac
- done
- exec 0<&5 5<&-
- fi
- test "$lalib_p" = yes
-}
-
-# func_ltwrapper_script_p file
-# True iff FILE is a libtool wrapper script
-# This function is only a basic sanity check; it will hardly flush out
-# determined imposters.
-func_ltwrapper_script_p ()
-{
- func_lalib_p "$1"
-}
-
-# func_ltwrapper_executable_p file
-# True iff FILE is a libtool wrapper executable
-# This function is only a basic sanity check; it will hardly flush out
-# determined imposters.
-func_ltwrapper_executable_p ()
-{
- func_ltwrapper_exec_suffix=
- case $1 in
- *.exe) ;;
- *) func_ltwrapper_exec_suffix=.exe ;;
- esac
- $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
-}
-
-# func_ltwrapper_scriptname file
-# Assumes file is an ltwrapper_executable
-# uses $file to determine the appropriate filename for a
-# temporary ltwrapper_script.
-func_ltwrapper_scriptname ()
-{
- func_ltwrapper_scriptname_result=""
- if func_ltwrapper_executable_p "$1"; then
- func_dirname_and_basename "$1" "" "."
- func_stripname '' '.exe' "$func_basename_result"
- func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
- fi
-}
-
-# func_ltwrapper_p file
-# True iff FILE is a libtool wrapper script or wrapper executable
-# This function is only a basic sanity check; it will hardly flush out
-# determined imposters.
-func_ltwrapper_p ()
-{
- func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
-}
-
-
-# func_execute_cmds commands fail_cmd
-# Execute tilde-delimited COMMANDS.
-# If FAIL_CMD is given, eval that upon failure.
-# FAIL_CMD may read-access the current command in variable CMD!
-func_execute_cmds ()
-{
- $opt_debug
- save_ifs=$IFS; IFS='~'
- for cmd in $1; do
- IFS=$save_ifs
- eval cmd=\"$cmd\"
- func_show_eval "$cmd" "${2-:}"
- done
- IFS=$save_ifs
-}
-
-
-# func_source file
-# Source FILE, adding directory component if necessary.
-# Note that it is not necessary on cygwin/mingw to append a dot to
-# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
-# behavior happens only for exec(3), not for open(2)! Also, sourcing
-# `FILE.' does not work on cygwin managed mounts.
-func_source ()
-{
- $opt_debug
- case $1 in
- */* | *\\*) . "$1" ;;
- *) . "./$1" ;;
- esac
-}
-
-
-# func_infer_tag arg
-# Infer tagged configuration to use if any are available and
-# if one wasn't chosen via the "--tag" command line option.
-# Only attempt this if the compiler in the base compile
-# command doesn't match the default compiler.
-# arg is usually of the form 'gcc ...'
-func_infer_tag ()
-{
- $opt_debug
- if test -n "$available_tags" && test -z "$tagname"; then
- CC_quoted=
- for arg in $CC; do
- func_quote_for_eval "$arg"
- CC_quoted="$CC_quoted $func_quote_for_eval_result"
- done
- case $@ in
- # Blanks in the command may have been stripped by the calling shell,
- # but not from the CC environment variable when configure was run.
- " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;;
- # Blanks at the start of $base_compile will cause this to fail
- # if we don't check for them as well.
- *)
- for z in $available_tags; do
- if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
- # Evaluate the configuration.
- eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
- CC_quoted=
- for arg in $CC; do
- # Double-quote args containing other shell metacharacters.
- func_quote_for_eval "$arg"
- CC_quoted="$CC_quoted $func_quote_for_eval_result"
- done
- case "$@ " in
- " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*)
- # The compiler in the base compile command matches
- # the one in the tagged configuration.
- # Assume this is the tagged configuration we want.
- tagname=$z
- break
- ;;
- esac
- fi
- done
- # If $tagname still isn't set, then no tagged configuration
- # was found and let the user know that the "--tag" command
- # line option must be used.
- if test -z "$tagname"; then
- func_echo "unable to infer tagged configuration"
- func_fatal_error "specify a tag with \`--tag'"
-# else
-# func_verbose "using $tagname tagged configuration"
- fi
- ;;
- esac
- fi
-}
-
-
-
-# func_write_libtool_object output_name pic_name nonpic_name
-# Create a libtool object file (analogous to a ".la" file),
-# but don't create it if we're doing a dry run.
-func_write_libtool_object ()
-{
- write_libobj=${1}
- if test "$build_libtool_libs" = yes; then
- write_lobj=\'${2}\'
- else
- write_lobj=none
- fi
-
- if test "$build_old_libs" = yes; then
- write_oldobj=\'${3}\'
- else
- write_oldobj=none
- fi
-
- $opt_dry_run || {
- cat >${write_libobj}T <<EOF
-# $write_libobj - a libtool object file
-# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# Name of the PIC object.
-pic_object=$write_lobj
-
-# Name of the non-PIC object
-non_pic_object=$write_oldobj
-
-EOF
- $MV "${write_libobj}T" "${write_libobj}"
- }
-}
-
-# func_mode_compile arg...
-func_mode_compile ()
-{
- $opt_debug
- # Get the compilation command and the source file.
- base_compile=
- srcfile="$nonopt" # always keep a non-empty value in "srcfile"
- suppress_opt=yes
- suppress_output=
- arg_mode=normal
- libobj=
- later=
- pie_flag=
-
- for arg
- do
- case $arg_mode in
- arg )
- # do not "continue". Instead, add this to base_compile
- lastarg="$arg"
- arg_mode=normal
- ;;
-
- target )
- libobj="$arg"
- arg_mode=normal
- continue
- ;;
-
- normal )
- # Accept any command-line options.
- case $arg in
- -o)
- test -n "$libobj" && \
- func_fatal_error "you cannot specify \`-o' more than once"
- arg_mode=target
- continue
- ;;
-
- -pie | -fpie | -fPIE)
- pie_flag="$pie_flag $arg"
- continue
- ;;
-
- -shared | -static | -prefer-pic | -prefer-non-pic)
- later="$later $arg"
- continue
- ;;
-
- -no-suppress)
- suppress_opt=no
- continue
- ;;
-
- -Xcompiler)
- arg_mode=arg # the next one goes into the "base_compile" arg list
- continue # The current "srcfile" will either be retained or
- ;; # replaced later. I would guess that would be a bug.
-
- -Wc,*)
- func_stripname '-Wc,' '' "$arg"
- args=$func_stripname_result
- lastarg=
- save_ifs="$IFS"; IFS=','
- for arg in $args; do
- IFS="$save_ifs"
- func_quote_for_eval "$arg"
- lastarg="$lastarg $func_quote_for_eval_result"
- done
- IFS="$save_ifs"
- func_stripname ' ' '' "$lastarg"
- lastarg=$func_stripname_result
-
- # Add the arguments to base_compile.
- base_compile="$base_compile $lastarg"
- continue
- ;;
-
- *)
- # Accept the current argument as the source file.
- # The previous "srcfile" becomes the current argument.
- #
- lastarg="$srcfile"
- srcfile="$arg"
- ;;
- esac # case $arg
- ;;
- esac # case $arg_mode
-
- # Aesthetically quote the previous argument.
- func_quote_for_eval "$lastarg"
- base_compile="$base_compile $func_quote_for_eval_result"
- done # for arg
-
- case $arg_mode in
- arg)
- func_fatal_error "you must specify an argument for -Xcompile"
- ;;
- target)
- func_fatal_error "you must specify a target with \`-o'"
- ;;
- *)
- # Get the name of the library object.
- test -z "$libobj" && {
- func_basename "$srcfile"
- libobj="$func_basename_result"
- }
- ;;
- esac
-
- # Recognize several different file suffixes.
- # If the user specifies -o file.o, it is replaced with file.lo
- case $libobj in
- *.[cCFSifmso] | \
- *.ada | *.adb | *.ads | *.asm | \
- *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
- *.[fF][09]? | *.for | *.java | *.obj | *.sx)
- func_xform "$libobj"
- libobj=$func_xform_result
- ;;
- esac
-
- case $libobj in
- *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
- *)
- func_fatal_error "cannot determine name of library object from \`$libobj'"
- ;;
- esac
-
- func_infer_tag $base_compile
-
- for arg in $later; do
- case $arg in
- -shared)
- test "$build_libtool_libs" != yes && \
- func_fatal_configuration "can not build a shared library"
- build_old_libs=no
- continue
- ;;
-
- -static)
- build_libtool_libs=no
- build_old_libs=yes
- continue
- ;;
-
- -prefer-pic)
- pic_mode=yes
- continue
- ;;
-
- -prefer-non-pic)
- pic_mode=no
- continue
- ;;
- esac
- done
-
- func_quote_for_eval "$libobj"
- test "X$libobj" != "X$func_quote_for_eval_result" \
- && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
- && func_warning "libobj name \`$libobj' may not contain shell special characters."
- func_dirname_and_basename "$obj" "/" ""
- objname="$func_basename_result"
- xdir="$func_dirname_result"
- lobj=${xdir}$objdir/$objname
-
- test -z "$base_compile" && \
- func_fatal_help "you must specify a compilation command"
-
- # Delete any leftover library objects.
- if test "$build_old_libs" = yes; then
- removelist="$obj $lobj $libobj ${libobj}T"
- else
- removelist="$lobj $libobj ${libobj}T"
- fi
-
- # On Cygwin there's no "real" PIC flag so we must build both object types
- case $host_os in
- cygwin* | mingw* | pw32* | os2* | cegcc*)
- pic_mode=default
- ;;
- esac
- if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
- # non-PIC code in shared libraries is not supported
- pic_mode=default
- fi
-
- # Calculate the filename of the output object if compiler does
- # not support -o with -c
- if test "$compiler_c_o" = no; then
- output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
- lockfile="$output_obj.lock"
- else
- output_obj=
- need_locks=no
- lockfile=
- fi
-
- # Lock this critical section if it is needed
- # We use this script file to make the link, it avoids creating a new file
- if test "$need_locks" = yes; then
- until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
- func_echo "Waiting for $lockfile to be removed"
- sleep 2
- done
- elif test "$need_locks" = warn; then
- if test -f "$lockfile"; then
- $ECHO "\
-*** ERROR, $lockfile exists and contains:
-`cat $lockfile 2>/dev/null`
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together. If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
- $opt_dry_run || $RM $removelist
- exit $EXIT_FAILURE
- fi
- removelist="$removelist $output_obj"
- $ECHO "$srcfile" > "$lockfile"
- fi
-
- $opt_dry_run || $RM $removelist
- removelist="$removelist $lockfile"
- trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
-
- if test -n "$fix_srcfile_path"; then
- eval srcfile=\"$fix_srcfile_path\"
- fi
- func_quote_for_eval "$srcfile"
- qsrcfile=$func_quote_for_eval_result
-
- # Only build a PIC object if we are building libtool libraries.
- if test "$build_libtool_libs" = yes; then
- # Without this assignment, base_compile gets emptied.
- fbsd_hideous_sh_bug=$base_compile
-
- if test "$pic_mode" != no; then
- command="$base_compile $qsrcfile $pic_flag"
- else
- # Don't build PIC code
- command="$base_compile $qsrcfile"
- fi
-
- func_mkdir_p "$xdir$objdir"
-
- if test -z "$output_obj"; then
- # Place PIC objects in $objdir
- command="$command -o $lobj"
- fi
-
- func_show_eval_locale "$command" \
- 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
-
- if test "$need_locks" = warn &&
- test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
- $ECHO "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
-
-but it should contain:
-$srcfile
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together. If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
- $opt_dry_run || $RM $removelist
- exit $EXIT_FAILURE
- fi
-
- # Just move the object if needed, then go on to compile the next one
- if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
- func_show_eval '$MV "$output_obj" "$lobj"' \
- 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
- fi
-
- # Allow error messages only from the first compilation.
- if test "$suppress_opt" = yes; then
- suppress_output=' >/dev/null 2>&1'
- fi
- fi
-
- # Only build a position-dependent object if we build old libraries.
- if test "$build_old_libs" = yes; then
- if test "$pic_mode" != yes; then
- # Don't build PIC code
- command="$base_compile $qsrcfile$pie_flag"
- else
- command="$base_compile $qsrcfile $pic_flag"
- fi
- if test "$compiler_c_o" = yes; then
- command="$command -o $obj"
- fi
-
- # Suppress compiler output if we already did a PIC compilation.
- command="$command$suppress_output"
- func_show_eval_locale "$command" \
- '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
-
- if test "$need_locks" = warn &&
- test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
- $ECHO "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
-
-but it should contain:
-$srcfile
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together. If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
- $opt_dry_run || $RM $removelist
- exit $EXIT_FAILURE
- fi
-
- # Just move the object if needed
- if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
- func_show_eval '$MV "$output_obj" "$obj"' \
- 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
- fi
- fi
-
- $opt_dry_run || {
- func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
-
- # Unlock the critical section if it was locked
- if test "$need_locks" != no; then
- removelist=$lockfile
- $RM "$lockfile"
- fi
- }
-
- exit $EXIT_SUCCESS
-}
-
-$opt_help || {
-test "$mode" = compile && func_mode_compile ${1+"$@"}
-}
-
-func_mode_help ()
-{
- # We need to display help for each of the modes.
- case $mode in
- "")
- # Generic help is extracted from the usage comments
- # at the start of this file.
- func_help
- ;;
-
- clean)
- $ECHO \
-"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
-
-Remove files from the build directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, object or program, all the files associated
-with it are deleted. Otherwise, only FILE itself is deleted using RM."
- ;;
-
- compile)
- $ECHO \
-"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
-
-Compile a source file into a libtool library object.
-
-This mode accepts the following additional options:
-
- -o OUTPUT-FILE set the output file name to OUTPUT-FILE
- -no-suppress do not suppress compiler output for multiple passes
- -prefer-pic try to building PIC objects only
- -prefer-non-pic try to building non-PIC objects only
- -shared do not build a \`.o' file suitable for static linking
- -static only build a \`.o' file suitable for static linking
-
-COMPILE-COMMAND is a command to be used in creating a \`standard' object file
-from the given SOURCEFILE.
-
-The output file name is determined by removing the directory component from
-SOURCEFILE, then substituting the C source code suffix \`.c' with the
-library object suffix, \`.lo'."
- ;;
-
- execute)
- $ECHO \
-"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
-
-Automatically set library path, then run a program.
-
-This mode accepts the following additional options:
-
- -dlopen FILE add the directory containing FILE to the library path
-
-This mode sets the library path environment variable according to \`-dlopen'
-flags.
-
-If any of the ARGS are libtool executable wrappers, then they are translated
-into their corresponding uninstalled binary, and any of their required library
-directories are added to the library path.
-
-Then, COMMAND is executed, with ARGS as arguments."
- ;;
-
- finish)
- $ECHO \
-"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
-
-Complete the installation of libtool libraries.
-
-Each LIBDIR is a directory that contains libtool libraries.
-
-The commands that this mode executes may require superuser privileges. Use
-the \`--dry-run' option if you just want to see what would be executed."
- ;;
-
- install)
- $ECHO \
-"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
-
-Install executables or libraries.
-
-INSTALL-COMMAND is the installation command. The first component should be
-either the \`install' or \`cp' program.
-
-The following components of INSTALL-COMMAND are treated specially:
-
- -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation
-
-The rest of the components are interpreted as arguments to that command (only
-BSD-compatible install options are recognized)."
- ;;
-
- link)
- $ECHO \
-"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
-
-Link object files or libraries together to form another library, or to
-create an executable program.
-
-LINK-COMMAND is a command using the C compiler that you would use to create
-a program from several object files.
-
-The following components of LINK-COMMAND are treated specially:
-
- -all-static do not do any dynamic linking at all
- -avoid-version do not add a version suffix if possible
- -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
- -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
- -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
- -export-symbols SYMFILE
- try to export only the symbols listed in SYMFILE
- -export-symbols-regex REGEX
- try to export only the symbols matching REGEX
- -LLIBDIR search LIBDIR for required installed libraries
- -lNAME OUTPUT-FILE requires the installed library libNAME
- -module build a library that can dlopened
- -no-fast-install disable the fast-install mode
- -no-install link a not-installable executable
- -no-undefined declare that a library does not refer to external symbols
- -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
- -objectlist FILE Use a list of object files found in FILE to specify objects
- -precious-files-regex REGEX
- don't remove output files matching REGEX
- -release RELEASE specify package release information
- -rpath LIBDIR the created library will eventually be installed in LIBDIR
- -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
- -shared only do dynamic linking of libtool libraries
- -shrext SUFFIX override the standard shared library file extension
- -static do not do any dynamic linking of uninstalled libtool libraries
- -static-libtool-libs
- do not do any dynamic linking of libtool libraries
- -version-info CURRENT[:REVISION[:AGE]]
- specify library version info [each variable defaults to 0]
- -weak LIBNAME declare that the target provides the LIBNAME interface
-
-All other options (arguments beginning with \`-') are ignored.
-
-Every other argument is treated as a filename. Files ending in \`.la' are
-treated as uninstalled libtool libraries, other files are standard or library
-object files.
-
-If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
-only library objects (\`.lo' files) may be specified, and \`-rpath' is
-required, except when creating a convenience library.
-
-If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
-using \`ar' and \`ranlib', or on Windows using \`lib'.
-
-If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
-is created, otherwise an executable program is created."
- ;;
-
- uninstall)
- $ECHO \
-"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
-
-Remove libraries from an installation directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, all the files associated with it are deleted.
-Otherwise, only FILE itself is deleted using RM."
- ;;
-
- *)
- func_fatal_help "invalid operation mode \`$mode'"
- ;;
- esac
-
- $ECHO
- $ECHO "Try \`$progname --help' for more information about other modes."
-
- exit $?
-}
-
- # Now that we've collected a possible --mode arg, show help if necessary
- $opt_help && func_mode_help
-
-
-# func_mode_execute arg...
-func_mode_execute ()
-{
- $opt_debug
- # The first argument is the command name.
- cmd="$nonopt"
- test -z "$cmd" && \
- func_fatal_help "you must specify a COMMAND"
-
- # Handle -dlopen flags immediately.
- for file in $execute_dlfiles; do
- test -f "$file" \
- || func_fatal_help "\`$file' is not a file"
-
- dir=
- case $file in
- *.la)
- # Check to see that this really is a libtool archive.
- func_lalib_unsafe_p "$file" \
- || func_fatal_help "\`$lib' is not a valid libtool archive"
-
- # Read the libtool library.
- dlname=
- library_names=
- func_source "$file"
-
- # Skip this library if it cannot be dlopened.
- if test -z "$dlname"; then
- # Warn if it was a shared library.
- test -n "$library_names" && \
- func_warning "\`$file' was not linked with \`-export-dynamic'"
- continue
- fi
-
- func_dirname "$file" "" "."
- dir="$func_dirname_result"
-
- if test -f "$dir/$objdir/$dlname"; then
- dir="$dir/$objdir"
- else
- if test ! -f "$dir/$dlname"; then
- func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
- fi
- fi
- ;;
-
- *.lo)
- # Just add the directory containing the .lo file.
- func_dirname "$file" "" "."
- dir="$func_dirname_result"
- ;;
-
- *)
- func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
- continue
- ;;
- esac
-
- # Get the absolute pathname.
- absdir=`cd "$dir" && pwd`
- test -n "$absdir" && dir="$absdir"
-
- # Now add the directory to shlibpath_var.
- if eval "test -z \"\$$shlibpath_var\""; then
- eval "$shlibpath_var=\"\$dir\""
- else
- eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
- fi
- done
-
- # This variable tells wrapper scripts just to set shlibpath_var
- # rather than running their programs.
- libtool_execute_magic="$magic"
-
- # Check if any of the arguments is a wrapper script.
- args=
- for file
- do
- case $file in
- -*) ;;
- *)
- # Do a test to see if this is really a libtool program.
- if func_ltwrapper_script_p "$file"; then
- func_source "$file"
- # Transform arg to wrapped name.
- file="$progdir/$program"
- elif func_ltwrapper_executable_p "$file"; then
- func_ltwrapper_scriptname "$file"
- func_source "$func_ltwrapper_scriptname_result"
- # Transform arg to wrapped name.
- file="$progdir/$program"
- fi
- ;;
- esac
- # Quote arguments (to preserve shell metacharacters).
- func_quote_for_eval "$file"
- args="$args $func_quote_for_eval_result"
- done
-
- if test "X$opt_dry_run" = Xfalse; then
- if test -n "$shlibpath_var"; then
- # Export the shlibpath_var.
- eval "export $shlibpath_var"
- fi
-
- # Restore saved environment variables
- for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
- do
- eval "if test \"\${save_$lt_var+set}\" = set; then
- $lt_var=\$save_$lt_var; export $lt_var
- else
- $lt_unset $lt_var
- fi"
- done
-
- # Now prepare to actually exec the command.
- exec_cmd="\$cmd$args"
- else
- # Display what would be done.
- if test -n "$shlibpath_var"; then
- eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
- $ECHO "export $shlibpath_var"
- fi
- $ECHO "$cmd$args"
- exit $EXIT_SUCCESS
- fi
-}
-
-test "$mode" = execute && func_mode_execute ${1+"$@"}
-
-
-# func_mode_finish arg...
-func_mode_finish ()
-{
- $opt_debug
- libdirs="$nonopt"
- admincmds=
-
- if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
- for dir
- do
- libdirs="$libdirs $dir"
- done
-
- for libdir in $libdirs; do
- if test -n "$finish_cmds"; then
- # Do each command in the finish commands.
- func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
-'"$cmd"'"'
- fi
- if test -n "$finish_eval"; then
- # Do the single finish_eval.
- eval cmds=\"$finish_eval\"
- $opt_dry_run || eval "$cmds" || admincmds="$admincmds
- $cmds"
- fi
- done
- fi
-
- # Exit here if they wanted silent mode.
- $opt_silent && exit $EXIT_SUCCESS
-
- $ECHO "X----------------------------------------------------------------------" | $Xsed
- $ECHO "Libraries have been installed in:"
- for libdir in $libdirs; do
- $ECHO " $libdir"
- done
- $ECHO
- $ECHO "If you ever happen to want to link against installed libraries"
- $ECHO "in a given directory, LIBDIR, you must either use libtool, and"
- $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'"
- $ECHO "flag during linking and do at least one of the following:"
- if test -n "$shlibpath_var"; then
- $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable"
- $ECHO " during execution"
- fi
- if test -n "$runpath_var"; then
- $ECHO " - add LIBDIR to the \`$runpath_var' environment variable"
- $ECHO " during linking"
- fi
- if test -n "$hardcode_libdir_flag_spec"; then
- libdir=LIBDIR
- eval flag=\"$hardcode_libdir_flag_spec\"
-
- $ECHO " - use the \`$flag' linker flag"
- fi
- if test -n "$admincmds"; then
- $ECHO " - have your system administrator run these commands:$admincmds"
- fi
- if test -f /etc/ld.so.conf; then
- $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
- fi
- $ECHO
-
- $ECHO "See any operating system documentation about shared libraries for"
- case $host in
- solaris2.[6789]|solaris2.1[0-9])
- $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual"
- $ECHO "pages."
- ;;
- *)
- $ECHO "more information, such as the ld(1) and ld.so(8) manual pages."
- ;;
- esac
- $ECHO "X----------------------------------------------------------------------" | $Xsed
- exit $EXIT_SUCCESS
-}
-
-test "$mode" = finish && func_mode_finish ${1+"$@"}
-
-
-# func_mode_install arg...
-func_mode_install ()
-{
- $opt_debug
- # There may be an optional sh(1) argument at the beginning of
- # install_prog (especially on Windows NT).
- if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
- # Allow the use of GNU shtool's install command.
- $ECHO "X$nonopt" | $GREP shtool >/dev/null; then
- # Aesthetically quote it.
- func_quote_for_eval "$nonopt"
- install_prog="$func_quote_for_eval_result "
- arg=$1
- shift
- else
- install_prog=
- arg=$nonopt
- fi
-
- # The real first argument should be the name of the installation program.
- # Aesthetically quote it.
- func_quote_for_eval "$arg"
- install_prog="$install_prog$func_quote_for_eval_result"
-
- # We need to accept at least all the BSD install flags.
- dest=
- files=
- opts=
- prev=
- install_type=
- isdir=no
- stripme=
- for arg
- do
- if test -n "$dest"; then
- files="$files $dest"
- dest=$arg
- continue
- fi
-
- case $arg in
- -d) isdir=yes ;;
- -f)
- case " $install_prog " in
- *[\\\ /]cp\ *) ;;
- *) prev=$arg ;;
- esac
- ;;
- -g | -m | -o)
- prev=$arg
- ;;
- -s)
- stripme=" -s"
- continue
- ;;
- -*)
- ;;
- *)
- # If the previous option needed an argument, then skip it.
- if test -n "$prev"; then
- prev=
- else
- dest=$arg
- continue
- fi
- ;;
- esac
-
- # Aesthetically quote the argument.
- func_quote_for_eval "$arg"
- install_prog="$install_prog $func_quote_for_eval_result"
- done
-
- test -z "$install_prog" && \
- func_fatal_help "you must specify an install program"
-
- test -n "$prev" && \
- func_fatal_help "the \`$prev' option requires an argument"
-
- if test -z "$files"; then
- if test -z "$dest"; then
- func_fatal_help "no file or destination specified"
- else
- func_fatal_help "you must specify a destination"
- fi
- fi
-
- # Strip any trailing slash from the destination.
- func_stripname '' '/' "$dest"
- dest=$func_stripname_result
-
- # Check to see that the destination is a directory.
- test -d "$dest" && isdir=yes
- if test "$isdir" = yes; then
- destdir="$dest"
- destname=
- else
- func_dirname_and_basename "$dest" "" "."
- destdir="$func_dirname_result"
- destname="$func_basename_result"
-
- # Not a directory, so check to see that there is only one file specified.
- set dummy $files; shift
- test "$#" -gt 1 && \
- func_fatal_help "\`$dest' is not a directory"
- fi
- case $destdir in
- [\\/]* | [A-Za-z]:[\\/]*) ;;
- *)
- for file in $files; do
- case $file in
- *.lo) ;;
- *)
- func_fatal_help "\`$destdir' must be an absolute directory name"
- ;;
- esac
- done
- ;;
- esac
-
- # This variable tells wrapper scripts just to set variables rather
- # than running their programs.
- libtool_install_magic="$magic"
-
- staticlibs=
- future_libdirs=
- current_libdirs=
- for file in $files; do
-
- # Do each installation.
- case $file in
- *.$libext)
- # Do the static libraries later.
- staticlibs="$staticlibs $file"
- ;;
-
- *.la)
- # Check to see that this really is a libtool archive.
- func_lalib_unsafe_p "$file" \
- || func_fatal_help "\`$file' is not a valid libtool archive"
-
- library_names=
- old_library=
- relink_command=
- func_source "$file"
-
- # Add the libdir to current_libdirs if it is the destination.
- if test "X$destdir" = "X$libdir"; then
- case "$current_libdirs " in
- *" $libdir "*) ;;
- *) current_libdirs="$current_libdirs $libdir" ;;
- esac
- else
- # Note the libdir as a future libdir.
- case "$future_libdirs " in
- *" $libdir "*) ;;
- *) future_libdirs="$future_libdirs $libdir" ;;
- esac
- fi
-
- func_dirname "$file" "/" ""
- dir="$func_dirname_result"
- dir="$dir$objdir"
-
- if test -n "$relink_command"; then
- # Determine the prefix the user has applied to our future dir.
- inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"`
-
- # Don't allow the user to place us outside of our expected
- # location b/c this prevents finding dependent libraries that
- # are installed to the same prefix.
- # At present, this check doesn't affect windows .dll's that
- # are installed into $libdir/../bin (currently, that works fine)
- # but it's something to keep an eye on.
- test "$inst_prefix_dir" = "$destdir" && \
- func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
-
- if test -n "$inst_prefix_dir"; then
- # Stick the inst_prefix_dir data into the link command.
- relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
- else
- relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"`
- fi
-
- func_warning "relinking \`$file'"
- func_show_eval "$relink_command" \
- 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
- fi
-
- # See the names of the shared library.
- set dummy $library_names; shift
- if test -n "$1"; then
- realname="$1"
- shift
-
- srcname="$realname"
- test -n "$relink_command" && srcname="$realname"T
-
- # Install the shared library and build the symlinks.
- func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \
- 'exit $?'
- tstripme="$stripme"
- case $host_os in
- cygwin* | mingw* | pw32* | cegcc*)
- case $realname in
- *.dll.a)
- tstripme=""
- ;;
- esac
- ;;
- esac
- if test -n "$tstripme" && test -n "$striplib"; then
- func_show_eval "$striplib $destdir/$realname" 'exit $?'
- fi
-
- if test "$#" -gt 0; then
- # Delete the old symlinks, and create new ones.
- # Try `ln -sf' first, because the `ln' binary might depend on
- # the symlink we replace! Solaris /bin/ln does not understand -f,
- # so we also need to try rm && ln -s.
- for linkname
- do
- test "$linkname" != "$realname" \
- && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
- done
- fi
-
- # Do each command in the postinstall commands.
- lib="$destdir/$realname"
- func_execute_cmds "$postinstall_cmds" 'exit $?'
- fi
-
- # Install the pseudo-library for information purposes.
- func_basename "$file"
- name="$func_basename_result"
- instname="$dir/$name"i
- func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
-
- # Maybe install the static library, too.
- test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
- ;;
-
- *.lo)
- # Install (i.e. copy) a libtool object.
-
- # Figure out destination file name, if it wasn't already specified.
- if test -n "$destname"; then
- destfile="$destdir/$destname"
- else
- func_basename "$file"
- destfile="$func_basename_result"
- destfile="$destdir/$destfile"
- fi
-
- # Deduce the name of the destination old-style object file.
- case $destfile in
- *.lo)
- func_lo2o "$destfile"
- staticdest=$func_lo2o_result
- ;;
- *.$objext)
- staticdest="$destfile"
- destfile=
- ;;
- *)
- func_fatal_help "cannot copy a libtool object to \`$destfile'"
- ;;
- esac
-
- # Install the libtool object if requested.
- test -n "$destfile" && \
- func_show_eval "$install_prog $file $destfile" 'exit $?'
-
- # Install the old object if enabled.
- if test "$build_old_libs" = yes; then
- # Deduce the name of the old-style object file.
- func_lo2o "$file"
- staticobj=$func_lo2o_result
- func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
- fi
- exit $EXIT_SUCCESS
- ;;
-
- *)
- # Figure out destination file name, if it wasn't already specified.
- if test -n "$destname"; then
- destfile="$destdir/$destname"
- else
- func_basename "$file"
- destfile="$func_basename_result"
- destfile="$destdir/$destfile"
- fi
-
- # If the file is missing, and there is a .exe on the end, strip it
- # because it is most likely a libtool script we actually want to
- # install
- stripped_ext=""
- case $file in
- *.exe)
- if test ! -f "$file"; then
- func_stripname '' '.exe' "$file"
- file=$func_stripname_result
- stripped_ext=".exe"
- fi
- ;;
- esac
-
- # Do a test to see if this is really a libtool program.
- case $host in
- *cygwin* | *mingw*)
- if func_ltwrapper_executable_p "$file"; then
- func_ltwrapper_scriptname "$file"
- wrapper=$func_ltwrapper_scriptname_result
- else
- func_stripname '' '.exe' "$file"
- wrapper=$func_stripname_result
- fi
- ;;
- *)
- wrapper=$file
- ;;
- esac
- if func_ltwrapper_script_p "$wrapper"; then
- notinst_deplibs=
- relink_command=
-
- func_source "$wrapper"
-
- # Check the variables that should have been set.
- test -z "$generated_by_libtool_version" && \
- func_fatal_error "invalid libtool wrapper script \`$wrapper'"
-
- finalize=yes
- for lib in $notinst_deplibs; do
- # Check to see that each library is installed.
- libdir=
- if test -f "$lib"; then
- func_source "$lib"
- fi
- libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
- if test -n "$libdir" && test ! -f "$libfile"; then
- func_warning "\`$lib' has not been installed in \`$libdir'"
- finalize=no
- fi
- done
-
- relink_command=
- func_source "$wrapper"
-
- outputname=
- if test "$fast_install" = no && test -n "$relink_command"; then
- $opt_dry_run || {
- if test "$finalize" = yes; then
- tmpdir=`func_mktempdir`
- func_basename "$file$stripped_ext"
- file="$func_basename_result"
- outputname="$tmpdir/$file"
- # Replace the output file specification.
- relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
-
- $opt_silent || {
- func_quote_for_expand "$relink_command"
- eval "func_echo $func_quote_for_expand_result"
- }
- if eval "$relink_command"; then :
- else
- func_error "error: relink \`$file' with the above command before installing it"
- $opt_dry_run || ${RM}r "$tmpdir"
- continue
- fi
- file="$outputname"
- else
- func_warning "cannot relink \`$file'"
- fi
- }
- else
- # Install the binary that we compiled earlier.
- file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
- fi
- fi
-
- # remove .exe since cygwin /usr/bin/install will append another
- # one anyway
- case $install_prog,$host in
- */usr/bin/install*,*cygwin*)
- case $file:$destfile in
- *.exe:*.exe)
- # this is ok
- ;;
- *.exe:*)
- destfile=$destfile.exe
- ;;
- *:*.exe)
- func_stripname '' '.exe' "$destfile"
- destfile=$func_stripname_result
- ;;
- esac
- ;;
- esac
- func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
- $opt_dry_run || if test -n "$outputname"; then
- ${RM}r "$tmpdir"
- fi
- ;;
- esac
- done
-
- for file in $staticlibs; do
- func_basename "$file"
- name="$func_basename_result"
-
- # Set up the ranlib parameters.
- oldlib="$destdir/$name"
-
- func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
-
- if test -n "$stripme" && test -n "$old_striplib"; then
- func_show_eval "$old_striplib $oldlib" 'exit $?'
- fi
-
- # Do each command in the postinstall commands.
- func_execute_cmds "$old_postinstall_cmds" 'exit $?'
- done
-
- test -n "$future_libdirs" && \
- func_warning "remember to run \`$progname --finish$future_libdirs'"
-
- if test -n "$current_libdirs"; then
- # Maybe just do a dry run.
- $opt_dry_run && current_libdirs=" -n$current_libdirs"
- exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
- else
- exit $EXIT_SUCCESS
- fi
-}
-
-test "$mode" = install && func_mode_install ${1+"$@"}
-
-
-# func_generate_dlsyms outputname originator pic_p
-# Extract symbols from dlprefiles and create ${outputname}S.o with
-# a dlpreopen symbol table.
-func_generate_dlsyms ()
-{
- $opt_debug
- my_outputname="$1"
- my_originator="$2"
- my_pic_p="${3-no}"
- my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
- my_dlsyms=
-
- if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
- if test -n "$NM" && test -n "$global_symbol_pipe"; then
- my_dlsyms="${my_outputname}S.c"
- else
- func_error "not configured to extract global symbols from dlpreopened files"
- fi
- fi
-
- if test -n "$my_dlsyms"; then
- case $my_dlsyms in
- "") ;;
- *.c)
- # Discover the nlist of each of the dlfiles.
- nlist="$output_objdir/${my_outputname}.nm"
-
- func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
-
- # Parse the name list into a source file.
- func_verbose "creating $output_objdir/$my_dlsyms"
-
- $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
-/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
-/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
-
-#ifdef __cplusplus
-extern \"C\" {
-#endif
-
-/* External symbol declarations for the compiler. */\
-"
-
- if test "$dlself" = yes; then
- func_verbose "generating symbol list for \`$output'"
-
- $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
-
- # Add our own program objects to the symbol list.
- progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
- for progfile in $progfiles; do
- func_verbose "extracting global C symbols from \`$progfile'"
- $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
- done
-
- if test -n "$exclude_expsyms"; then
- $opt_dry_run || {
- eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
- eval '$MV "$nlist"T "$nlist"'
- }
- fi
-
- if test -n "$export_symbols_regex"; then
- $opt_dry_run || {
- eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
- eval '$MV "$nlist"T "$nlist"'
- }
- fi
-
- # Prepare the list of exported symbols
- if test -z "$export_symbols"; then
- export_symbols="$output_objdir/$outputname.exp"
- $opt_dry_run || {
- $RM $export_symbols
- eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
- case $host in
- *cygwin* | *mingw* | *cegcc* )
- eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
- eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
- ;;
- esac
- }
- else
- $opt_dry_run || {
- eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
- eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
- eval '$MV "$nlist"T "$nlist"'
- case $host in
- *cygwin | *mingw* | *cegcc* )
- eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
- eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
- ;;
- esac
- }
- fi
- fi
-
- for dlprefile in $dlprefiles; do
- func_verbose "extracting global C symbols from \`$dlprefile'"
- func_basename "$dlprefile"
- name="$func_basename_result"
- $opt_dry_run || {
- eval '$ECHO ": $name " >> "$nlist"'
- eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
- }
- done
-
- $opt_dry_run || {
- # Make sure we have at least an empty file.
- test -f "$nlist" || : > "$nlist"
-
- if test -n "$exclude_expsyms"; then
- $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
- $MV "$nlist"T "$nlist"
- fi
-
- # Try sorting and uniquifying the output.
- if $GREP -v "^: " < "$nlist" |
- if sort -k 3 </dev/null >/dev/null 2>&1; then
- sort -k 3
- else
- sort +2
- fi |
- uniq > "$nlist"S; then
- :
- else
- $GREP -v "^: " < "$nlist" > "$nlist"S
- fi
-
- if test -f "$nlist"S; then
- eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
- else
- $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms"
- fi
-
- $ECHO >> "$output_objdir/$my_dlsyms" "\
-
-/* The mapping between symbol names and symbols. */
-typedef struct {
- const char *name;
- void *address;
-} lt_dlsymlist;
-"
- case $host in
- *cygwin* | *mingw* | *cegcc* )
- $ECHO >> "$output_objdir/$my_dlsyms" "\
-/* DATA imports from DLLs on WIN32 con't be const, because
- runtime relocations are performed -- see ld's documentation
- on pseudo-relocs. */"
- lt_dlsym_const= ;;
- *osf5*)
- echo >> "$output_objdir/$my_dlsyms" "\
-/* This system does not cope well with relocations in const data */"
- lt_dlsym_const= ;;
- *)
- lt_dlsym_const=const ;;
- esac
-
- $ECHO >> "$output_objdir/$my_dlsyms" "\
-extern $lt_dlsym_const lt_dlsymlist
-lt_${my_prefix}_LTX_preloaded_symbols[];
-$lt_dlsym_const lt_dlsymlist
-lt_${my_prefix}_LTX_preloaded_symbols[] =
-{\
- { \"$my_originator\", (void *) 0 },"
-
- case $need_lib_prefix in
- no)
- eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
- ;;
- *)
- eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
- ;;
- esac
- $ECHO >> "$output_objdir/$my_dlsyms" "\
- {0, (void *) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
- return lt_${my_prefix}_LTX_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif\
-"
- } # !$opt_dry_run
-
- pic_flag_for_symtable=
- case "$compile_command " in
- *" -static "*) ;;
- *)
- case $host in
- # compiling the symbol table file with pic_flag works around
- # a FreeBSD bug that causes programs to crash when -lm is
- # linked before any other PIC object. But we must not use
- # pic_flag when linking with -static. The problem exists in
- # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
- *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
- pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
- *-*-hpux*)
- pic_flag_for_symtable=" $pic_flag" ;;
- *)
- if test "X$my_pic_p" != Xno; then
- pic_flag_for_symtable=" $pic_flag"
- fi
- ;;
- esac
- ;;
- esac
- symtab_cflags=
- for arg in $LTCFLAGS; do
- case $arg in
- -pie | -fpie | -fPIE) ;;
- *) symtab_cflags="$symtab_cflags $arg" ;;
- esac
- done
-
- # Now compile the dynamic symbol file.
- func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
-
- # Clean up the generated files.
- func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
-
- # Transform the symbol file into the correct name.
- symfileobj="$output_objdir/${my_outputname}S.$objext"
- case $host in
- *cygwin* | *mingw* | *cegcc* )
- if test -f "$output_objdir/$my_outputname.def"; then
- compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
- finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
- else
- compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
- finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
- fi
- ;;
- *)
- compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
- finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
- ;;
- esac
- ;;
- *)
- func_fatal_error "unknown suffix for \`$my_dlsyms'"
- ;;
- esac
- else
- # We keep going just in case the user didn't refer to
- # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
- # really was required.
-
- # Nullify the symbol file.
- compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
- finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
- fi
-}
-
-# func_win32_libid arg
-# return the library type of file 'arg'
-#
-# Need a lot of goo to handle *both* DLLs and import libs
-# Has to be a shell function in order to 'eat' the argument
-# that is supplied when $file_magic_command is called.
-func_win32_libid ()
-{
- $opt_debug
- win32_libid_type="unknown"
- win32_fileres=`file -L $1 2>/dev/null`
- case $win32_fileres in
- *ar\ archive\ import\ library*) # definitely import
- win32_libid_type="x86 archive import"
- ;;
- *ar\ archive*) # could be an import, or static
- if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
- $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
- win32_nmres=`eval $NM -f posix -A $1 |
- $SED -n -e '
- 1,100{
- / I /{
- s,.*,import,
- p
- q
- }
- }'`
- case $win32_nmres in
- import*) win32_libid_type="x86 archive import";;
- *) win32_libid_type="x86 archive static";;
- esac
- fi
- ;;
- *DLL*)
- win32_libid_type="x86 DLL"
- ;;
- *executable*) # but shell scripts are "executable" too...
- case $win32_fileres in
- *MS\ Windows\ PE\ Intel*)
- win32_libid_type="x86 DLL"
- ;;
- esac
- ;;
- esac
- $ECHO "$win32_libid_type"
-}
-
-
-
-# func_extract_an_archive dir oldlib
-func_extract_an_archive ()
-{
- $opt_debug
- f_ex_an_ar_dir="$1"; shift
- f_ex_an_ar_oldlib="$1"
- func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
- if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
- fi
-}
-
-
-# func_extract_archives gentop oldlib ...
-func_extract_archives ()
-{
- $opt_debug
- my_gentop="$1"; shift
- my_oldlibs=${1+"$@"}
- my_oldobjs=""
- my_xlib=""
- my_xabs=""
- my_xdir=""
-
- for my_xlib in $my_oldlibs; do
- # Extract the objects.
- case $my_xlib in
- [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
- *) my_xabs=`pwd`"/$my_xlib" ;;
- esac
- func_basename "$my_xlib"
- my_xlib="$func_basename_result"
- my_xlib_u=$my_xlib
- while :; do
- case " $extracted_archives " in
- *" $my_xlib_u "*)
- func_arith $extracted_serial + 1
- extracted_serial=$func_arith_result
- my_xlib_u=lt$extracted_serial-$my_xlib ;;
- *) break ;;
- esac
- done
- extracted_archives="$extracted_archives $my_xlib_u"
- my_xdir="$my_gentop/$my_xlib_u"
-
- func_mkdir_p "$my_xdir"
-
- case $host in
- *-darwin*)
- func_verbose "Extracting $my_xabs"
- # Do not bother doing anything if just a dry run
- $opt_dry_run || {
- darwin_orig_dir=`pwd`
- cd $my_xdir || exit $?
- darwin_archive=$my_xabs
- darwin_curdir=`pwd`
- darwin_base_archive=`basename "$darwin_archive"`
- darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
- if test -n "$darwin_arches"; then
- darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
- darwin_arch=
- func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
- for darwin_arch in $darwin_arches ; do
- func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
- $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
- cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
- func_extract_an_archive "`pwd`" "${darwin_base_archive}"
- cd "$darwin_curdir"
- $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
- done # $darwin_arches
- ## Okay now we've a bunch of thin objects, gotta fatten them up :)
- darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
- darwin_file=
- darwin_files=
- for darwin_file in $darwin_filelist; do
- darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
- $LIPO -create -output "$darwin_file" $darwin_files
- done # $darwin_filelist
- $RM -rf unfat-$$
- cd "$darwin_orig_dir"
- else
- cd $darwin_orig_dir
- func_extract_an_archive "$my_xdir" "$my_xabs"
- fi # $darwin_arches
- } # !$opt_dry_run
- ;;
- *)
- func_extract_an_archive "$my_xdir" "$my_xabs"
- ;;
- esac
- my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
- done
-
- func_extract_archives_result="$my_oldobjs"
-}
-
-
-
-# func_emit_wrapper_part1 [arg=no]
-#
-# Emit the first part of a libtool wrapper script on stdout.
-# For more information, see the description associated with
-# func_emit_wrapper(), below.
-func_emit_wrapper_part1 ()
-{
- func_emit_wrapper_part1_arg1=no
- if test -n "$1" ; then
- func_emit_wrapper_part1_arg1=$1
- fi
-
- $ECHO "\
-#! $SHELL
-
-# $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
-#
-# The $output program cannot be directly executed until all the libtool
-# libraries that it depends on are installed.
-#
-# This wrapper script should never be moved out of the build directory.
-# If it is, it will not operate correctly.
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='${SED} -e 1s/^X//'
-sed_quote_subst='$sed_quote_subst'
-
-# Be Bourne compatible
-if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '\${1+\"\$@\"}'='\"\$@\"'
- setopt NO_GLOB_SUBST
-else
- case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-relink_command=\"$relink_command\"
-
-# This environment variable determines our operation mode.
-if test \"\$libtool_install_magic\" = \"$magic\"; then
- # install mode needs the following variables:
- generated_by_libtool_version='$macro_version'
- notinst_deplibs='$notinst_deplibs'
-else
- # When we are sourced in execute mode, \$file and \$ECHO are already set.
- if test \"\$libtool_execute_magic\" != \"$magic\"; then
- ECHO=\"$qecho\"
- file=\"\$0\"
- # Make sure echo works.
- if test \"X\$1\" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
- elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
- # Yippee, \$ECHO works!
- :
- else
- # Restart under the correct shell, and then maybe \$ECHO will work.
- exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
- fi
- fi\
-"
- $ECHO "\
-
- # Find the directory that this script lives in.
- thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
- test \"x\$thisdir\" = \"x\$file\" && thisdir=.
-
- # Follow symbolic links until we get to the real thisdir.
- file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
- while test -n \"\$file\"; do
- destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
-
- # If there was a directory component, then change thisdir.
- if test \"x\$destdir\" != \"x\$file\"; then
- case \"\$destdir\" in
- [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
- *) thisdir=\"\$thisdir/\$destdir\" ;;
- esac
- fi
-
- file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
- file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
- done
-"
-}
-# end: func_emit_wrapper_part1
-
-# func_emit_wrapper_part2 [arg=no]
-#
-# Emit the second part of a libtool wrapper script on stdout.
-# For more information, see the description associated with
-# func_emit_wrapper(), below.
-func_emit_wrapper_part2 ()
-{
- func_emit_wrapper_part2_arg1=no
- if test -n "$1" ; then
- func_emit_wrapper_part2_arg1=$1
- fi
-
- $ECHO "\
-
- # Usually 'no', except on cygwin/mingw when embedded into
- # the cwrapper.
- WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1
- if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
- # special case for '.'
- if test \"\$thisdir\" = \".\"; then
- thisdir=\`pwd\`
- fi
- # remove .libs from thisdir
- case \"\$thisdir\" in
- *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
- $objdir ) thisdir=. ;;
- esac
- fi
-
- # Try to get the absolute directory name.
- absdir=\`cd \"\$thisdir\" && pwd\`
- test -n \"\$absdir\" && thisdir=\"\$absdir\"
-"
-
- if test "$fast_install" = yes; then
- $ECHO "\
- program=lt-'$outputname'$exeext
- progdir=\"\$thisdir/$objdir\"
-
- if test ! -f \"\$progdir/\$program\" ||
- { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
- test \"X\$file\" != \"X\$progdir/\$program\"; }; then
-
- file=\"\$\$-\$program\"
-
- if test ! -d \"\$progdir\"; then
- $MKDIR \"\$progdir\"
- else
- $RM \"\$progdir/\$file\"
- fi"
-
- $ECHO "\
-
- # relink executable if necessary
- if test -n \"\$relink_command\"; then
- if relink_command_output=\`eval \$relink_command 2>&1\`; then :
- else
- $ECHO \"\$relink_command_output\" >&2
- $RM \"\$progdir/\$file\"
- exit 1
- fi
- fi
-
- $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
- { $RM \"\$progdir/\$program\";
- $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
- $RM \"\$progdir/\$file\"
- fi"
- else
- $ECHO "\
- program='$outputname'
- progdir=\"\$thisdir/$objdir\"
-"
- fi
-
- $ECHO "\
-
- if test -f \"\$progdir/\$program\"; then"
-
- # Export our shlibpath_var if we have one.
- if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
- $ECHO "\
- # Add our own library path to $shlibpath_var
- $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
-
- # Some systems cannot cope with colon-terminated $shlibpath_var
- # The second colon is a workaround for a bug in BeOS R4 sed
- $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
-
- export $shlibpath_var
-"
- fi
-
- # fixup the dll searchpath if we need to.
- if test -n "$dllsearchpath"; then
- $ECHO "\
- # Add the dll search path components to the executable PATH
- PATH=$dllsearchpath:\$PATH
-"
- fi
-
- $ECHO "\
- if test \"\$libtool_execute_magic\" != \"$magic\"; then
- # Run the actual program with our arguments.
-"
- case $host in
- # Backslashes separate directories on plain windows
- *-*-mingw | *-*-os2* | *-cegcc*)
- $ECHO "\
- exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
-"
- ;;
-
- *)
- $ECHO "\
- exec \"\$progdir/\$program\" \${1+\"\$@\"}
-"
- ;;
- esac
- $ECHO "\
- \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
- exit 1
- fi
- else
- # The program doesn't exist.
- \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
- \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
- $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
- exit 1
- fi
-fi\
-"
-}
-# end: func_emit_wrapper_part2
-
-
-# func_emit_wrapper [arg=no]
-#
-# Emit a libtool wrapper script on stdout.
-# Don't directly open a file because we may want to
-# incorporate the script contents within a cygwin/mingw
-# wrapper executable. Must ONLY be called from within
-# func_mode_link because it depends on a number of variables
-# set therein.
-#
-# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
-# variable will take. If 'yes', then the emitted script
-# will assume that the directory in which it is stored is
-# the $objdir directory. This is a cygwin/mingw-specific
-# behavior.
-func_emit_wrapper ()
-{
- func_emit_wrapper_arg1=no
- if test -n "$1" ; then
- func_emit_wrapper_arg1=$1
- fi
-
- # split this up so that func_emit_cwrapperexe_src
- # can call each part independently.
- func_emit_wrapper_part1 "${func_emit_wrapper_arg1}"
- func_emit_wrapper_part2 "${func_emit_wrapper_arg1}"
-}
-
-
-# func_to_host_path arg
-#
-# Convert paths to host format when used with build tools.
-# Intended for use with "native" mingw (where libtool itself
-# is running under the msys shell), or in the following cross-
-# build environments:
-# $build $host
-# mingw (msys) mingw [e.g. native]
-# cygwin mingw
-# *nix + wine mingw
-# where wine is equipped with the `winepath' executable.
-# In the native mingw case, the (msys) shell automatically
-# converts paths for any non-msys applications it launches,
-# but that facility isn't available from inside the cwrapper.
-# Similar accommodations are necessary for $host mingw and
-# $build cygwin. Calling this function does no harm for other
-# $host/$build combinations not listed above.
-#
-# ARG is the path (on $build) that should be converted to
-# the proper representation for $host. The result is stored
-# in $func_to_host_path_result.
-func_to_host_path ()
-{
- func_to_host_path_result="$1"
- if test -n "$1" ; then
- case $host in
- *mingw* )
- lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
- case $build in
- *mingw* ) # actually, msys
- # awkward: cmd appends spaces to result
- lt_sed_strip_trailing_spaces="s/[ ]*\$//"
- func_to_host_path_tmp1=`( cmd //c echo "$1" |\
- $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
- func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
- $SED -e "$lt_sed_naive_backslashify"`
- ;;
- *cygwin* )
- func_to_host_path_tmp1=`cygpath -w "$1"`
- func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
- $SED -e "$lt_sed_naive_backslashify"`
- ;;
- * )
- # Unfortunately, winepath does not exit with a non-zero
- # error code, so we are forced to check the contents of
- # stdout. On the other hand, if the command is not
- # found, the shell will set an exit code of 127 and print
- # *an error message* to stdout. So we must check for both
- # error code of zero AND non-empty stdout, which explains
- # the odd construction:
- func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
- if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
- func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
- $SED -e "$lt_sed_naive_backslashify"`
- else
- # Allow warning below.
- func_to_host_path_result=""
- fi
- ;;
- esac
- if test -z "$func_to_host_path_result" ; then
- func_error "Could not determine host path corresponding to"
- func_error " '$1'"
- func_error "Continuing, but uninstalled executables may not work."
- # Fallback:
- func_to_host_path_result="$1"
- fi
- ;;
- esac
- fi
-}
-# end: func_to_host_path
-
-# func_to_host_pathlist arg
-#
-# Convert pathlists to host format when used with build tools.
-# See func_to_host_path(), above. This function supports the
-# following $build/$host combinations (but does no harm for
-# combinations not listed here):
-# $build $host
-# mingw (msys) mingw [e.g. native]
-# cygwin mingw
-# *nix + wine mingw
-#
-# Path separators are also converted from $build format to
-# $host format. If ARG begins or ends with a path separator
-# character, it is preserved (but converted to $host format)
-# on output.
-#
-# ARG is a pathlist (on $build) that should be converted to
-# the proper representation on $host. The result is stored
-# in $func_to_host_pathlist_result.
-func_to_host_pathlist ()
-{
- func_to_host_pathlist_result="$1"
- if test -n "$1" ; then
- case $host in
- *mingw* )
- lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
- # Remove leading and trailing path separator characters from
- # ARG. msys behavior is inconsistent here, cygpath turns them
- # into '.;' and ';.', and winepath ignores them completely.
- func_to_host_pathlist_tmp2="$1"
- # Once set for this call, this variable should not be
- # reassigned. It is used in tha fallback case.
- func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
- $SED -e 's|^:*||' -e 's|:*$||'`
- case $build in
- *mingw* ) # Actually, msys.
- # Awkward: cmd appends spaces to result.
- lt_sed_strip_trailing_spaces="s/[ ]*\$//"
- func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\
- $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
- func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
- $SED -e "$lt_sed_naive_backslashify"`
- ;;
- *cygwin* )
- func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"`
- func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
- $SED -e "$lt_sed_naive_backslashify"`
- ;;
- * )
- # unfortunately, winepath doesn't convert pathlists
- func_to_host_pathlist_result=""
- func_to_host_pathlist_oldIFS=$IFS
- IFS=:
- for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
- IFS=$func_to_host_pathlist_oldIFS
- if test -n "$func_to_host_pathlist_f" ; then
- func_to_host_path "$func_to_host_pathlist_f"
- if test -n "$func_to_host_path_result" ; then
- if test -z "$func_to_host_pathlist_result" ; then
- func_to_host_pathlist_result="$func_to_host_path_result"
- else
- func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result"
- fi
- fi
- fi
- IFS=:
- done
- IFS=$func_to_host_pathlist_oldIFS
- ;;
- esac
- if test -z "$func_to_host_pathlist_result" ; then
- func_error "Could not determine the host path(s) corresponding to"
- func_error " '$1'"
- func_error "Continuing, but uninstalled executables may not work."
- # Fallback. This may break if $1 contains DOS-style drive
- # specifications. The fix is not to complicate the expression
- # below, but for the user to provide a working wine installation
- # with winepath so that path translation in the cross-to-mingw
- # case works properly.
- lt_replace_pathsep_nix_to_dos="s|:|;|g"
- func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
- $SED -e "$lt_replace_pathsep_nix_to_dos"`
- fi
- # Now, add the leading and trailing path separators back
- case "$1" in
- :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
- ;;
- esac
- case "$1" in
- *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;"
- ;;
- esac
- ;;
- esac
- fi
-}
-# end: func_to_host_pathlist
-
-# func_emit_cwrapperexe_src
-# emit the source code for a wrapper executable on stdout
-# Must ONLY be called from within func_mode_link because
-# it depends on a number of variable set therein.
-func_emit_cwrapperexe_src ()
-{
- cat <<EOF
-
-/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
- Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
-
- The $output program cannot be directly executed until all the libtool
- libraries that it depends on are installed.
-
- This wrapper executable should never be moved out of the build directory.
- If it is, it will not operate correctly.
-
- Currently, it simply execs the wrapper *script* "$SHELL $output",
- but could eventually absorb all of the scripts functionality and
- exec $objdir/$outputname directly.
-*/
-EOF
- cat <<"EOF"
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef _MSC_VER
-# include <direct.h>
-# include <process.h>
-# include <io.h>
-# define setmode _setmode
-#else
-# include <unistd.h>
-# include <stdint.h>
-# ifdef __CYGWIN__
-# include <io.h>
-# define HAVE_SETENV
-# ifdef __STRICT_ANSI__
-char *realpath (const char *, char *);
-int putenv (char *);
-int setenv (const char *, const char *, int);
-# endif
-# endif
-#endif
-#include <malloc.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#if defined(PATH_MAX)
-# define LT_PATHMAX PATH_MAX
-#elif defined(MAXPATHLEN)
-# define LT_PATHMAX MAXPATHLEN
-#else
-# define LT_PATHMAX 1024
-#endif
-
-#ifndef S_IXOTH
-# define S_IXOTH 0
-#endif
-#ifndef S_IXGRP
-# define S_IXGRP 0
-#endif
-
-#ifdef _MSC_VER
-# define S_IXUSR _S_IEXEC
-# define stat _stat
-# ifndef _INTPTR_T_DEFINED
-# define intptr_t int
-# endif
-#endif
-
-#ifndef DIR_SEPARATOR
-# define DIR_SEPARATOR '/'
-# define PATH_SEPARATOR ':'
-#endif
-
-#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
- defined (__OS2__)
-# define HAVE_DOS_BASED_FILE_SYSTEM
-# define FOPEN_WB "wb"
-# ifndef DIR_SEPARATOR_2
-# define DIR_SEPARATOR_2 '\\'
-# endif
-# ifndef PATH_SEPARATOR_2
-# define PATH_SEPARATOR_2 ';'
-# endif
-#endif
-
-#ifndef DIR_SEPARATOR_2
-# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
-#else /* DIR_SEPARATOR_2 */
-# define IS_DIR_SEPARATOR(ch) \
- (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
-#endif /* DIR_SEPARATOR_2 */
-
-#ifndef PATH_SEPARATOR_2
-# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
-#else /* PATH_SEPARATOR_2 */
-# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
-#endif /* PATH_SEPARATOR_2 */
-
-#ifdef __CYGWIN__
-# define FOPEN_WB "wb"
-#endif
-
-#ifndef FOPEN_WB
-# define FOPEN_WB "w"
-#endif
-#ifndef _O_BINARY
-# define _O_BINARY 0
-#endif
-
-#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
-#define XFREE(stale) do { \
- if (stale) { free ((void *) stale); stale = 0; } \
-} while (0)
-
-#undef LTWRAPPER_DEBUGPRINTF
-#if defined DEBUGWRAPPER
-# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
-static void
-ltwrapper_debugprintf (const char *fmt, ...)
-{
- va_list args;
- va_start (args, fmt);
- (void) vfprintf (stderr, fmt, args);
- va_end (args);
-}
-#else
-# define LTWRAPPER_DEBUGPRINTF(args)
-#endif
-
-const char *program_name = NULL;
-
-void *xmalloc (size_t num);
-char *xstrdup (const char *string);
-const char *base_name (const char *name);
-char *find_executable (const char *wrapper);
-char *chase_symlinks (const char *pathspec);
-int make_executable (const char *path);
-int check_executable (const char *path);
-char *strendzap (char *str, const char *pat);
-void lt_fatal (const char *message, ...);
-void lt_setenv (const char *name, const char *value);
-char *lt_extend_str (const char *orig_value, const char *add, int to_end);
-void lt_opt_process_env_set (const char *arg);
-void lt_opt_process_env_prepend (const char *arg);
-void lt_opt_process_env_append (const char *arg);
-int lt_split_name_value (const char *arg, char** name, char** value);
-void lt_update_exe_path (const char *name, const char *value);
-void lt_update_lib_path (const char *name, const char *value);
-
-static const char *script_text_part1 =
-EOF
-
- func_emit_wrapper_part1 yes |
- $SED -e 's/\([\\"]\)/\\\1/g' \
- -e 's/^/ "/' -e 's/$/\\n"/'
- echo ";"
- cat <<EOF
-
-static const char *script_text_part2 =
-EOF
- func_emit_wrapper_part2 yes |
- $SED -e 's/\([\\"]\)/\\\1/g' \
- -e 's/^/ "/' -e 's/$/\\n"/'
- echo ";"
-
- cat <<EOF
-const char * MAGIC_EXE = "$magic_exe";
-const char * LIB_PATH_VARNAME = "$shlibpath_var";
-EOF
-
- if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
- func_to_host_pathlist "$temp_rpath"
- cat <<EOF
-const char * LIB_PATH_VALUE = "$func_to_host_pathlist_result";
-EOF
- else
- cat <<"EOF"
-const char * LIB_PATH_VALUE = "";
-EOF
- fi
-
- if test -n "$dllsearchpath"; then
- func_to_host_pathlist "$dllsearchpath:"
- cat <<EOF
-const char * EXE_PATH_VARNAME = "PATH";
-const char * EXE_PATH_VALUE = "$func_to_host_pathlist_result";
-EOF
- else
- cat <<"EOF"
-const char * EXE_PATH_VARNAME = "";
-const char * EXE_PATH_VALUE = "";
-EOF
- fi
-
- if test "$fast_install" = yes; then
- cat <<EOF
-const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
-EOF
- else
- cat <<EOF
-const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
-EOF
- fi
-
-
- cat <<"EOF"
-
-#define LTWRAPPER_OPTION_PREFIX "--lt-"
-#define LTWRAPPER_OPTION_PREFIX_LENGTH 5
-
-static const size_t opt_prefix_len = LTWRAPPER_OPTION_PREFIX_LENGTH;
-static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
-
-static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
-
-static const size_t env_set_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;
-static const char *env_set_opt = LTWRAPPER_OPTION_PREFIX "env-set";
- /* argument is putenv-style "foo=bar", value of foo is set to bar */
-
-static const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;
-static const char *env_prepend_opt = LTWRAPPER_OPTION_PREFIX "env-prepend";
- /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
-
-static const size_t env_append_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;
-static const char *env_append_opt = LTWRAPPER_OPTION_PREFIX "env-append";
- /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
-
-int
-main (int argc, char *argv[])
-{
- char **newargz;
- int newargc;
- char *tmp_pathspec;
- char *actual_cwrapper_path;
- char *actual_cwrapper_name;
- char *target_name;
- char *lt_argv_zero;
- intptr_t rval = 127;
-
- int i;
-
- program_name = (char *) xstrdup (base_name (argv[0]));
- LTWRAPPER_DEBUGPRINTF (("(main) argv[0] : %s\n", argv[0]));
- LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
-
- /* very simple arg parsing; don't want to rely on getopt */
- for (i = 1; i < argc; i++)
- {
- if (strcmp (argv[i], dumpscript_opt) == 0)
- {
-EOF
- case "$host" in
- *mingw* | *cygwin* )
- # make stdout use "unix" line endings
- echo " setmode(1,_O_BINARY);"
- ;;
- esac
-
- cat <<"EOF"
- printf ("%s", script_text_part1);
- printf ("%s", script_text_part2);
- return 0;
- }
- }
-
- newargz = XMALLOC (char *, argc + 1);
- tmp_pathspec = find_executable (argv[0]);
- if (tmp_pathspec == NULL)
- lt_fatal ("Couldn't find %s", argv[0]);
- LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
- tmp_pathspec));
-
- actual_cwrapper_path = chase_symlinks (tmp_pathspec);
- LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
- actual_cwrapper_path));
- XFREE (tmp_pathspec);
-
- actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
- strendzap (actual_cwrapper_path, actual_cwrapper_name);
-
- /* wrapper name transforms */
- strendzap (actual_cwrapper_name, ".exe");
- tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
- XFREE (actual_cwrapper_name);
- actual_cwrapper_name = tmp_pathspec;
- tmp_pathspec = 0;
-
- /* target_name transforms -- use actual target program name; might have lt- prefix */
- target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
- strendzap (target_name, ".exe");
- tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
- XFREE (target_name);
- target_name = tmp_pathspec;
- tmp_pathspec = 0;
-
- LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
- target_name));
-EOF
-
- cat <<EOF
- newargz[0] =
- XMALLOC (char, (strlen (actual_cwrapper_path) +
- strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
- strcpy (newargz[0], actual_cwrapper_path);
- strcat (newargz[0], "$objdir");
- strcat (newargz[0], "/");
-EOF
-
- cat <<"EOF"
- /* stop here, and copy so we don't have to do this twice */
- tmp_pathspec = xstrdup (newargz[0]);
-
- /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
- strcat (newargz[0], actual_cwrapper_name);
-
- /* DO want the lt- prefix here if it exists, so use target_name */
- lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
- XFREE (tmp_pathspec);
- tmp_pathspec = NULL;
-EOF
-
- case $host_os in
- mingw*)
- cat <<"EOF"
- {
- char* p;
- while ((p = strchr (newargz[0], '\\')) != NULL)
- {
- *p = '/';
- }
- while ((p = strchr (lt_argv_zero, '\\')) != NULL)
- {
- *p = '/';
- }
- }
-EOF
- ;;
- esac
-
- cat <<"EOF"
- XFREE (target_name);
- XFREE (actual_cwrapper_path);
- XFREE (actual_cwrapper_name);
-
- lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
- lt_setenv ("DUALCASE", "1"); /* for MSK sh */
- lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
- lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
-
- newargc=0;
- for (i = 1; i < argc; i++)
- {
- if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
- {
- if (argv[i][env_set_opt_len] == '=')
- {
- const char *p = argv[i] + env_set_opt_len + 1;
- lt_opt_process_env_set (p);
- }
- else if (argv[i][env_set_opt_len] == '\0' && i + 1 < argc)
- {
- lt_opt_process_env_set (argv[++i]); /* don't copy */
- }
- else
- lt_fatal ("%s missing required argument", env_set_opt);
- continue;
- }
- if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
- {
- if (argv[i][env_prepend_opt_len] == '=')
- {
- const char *p = argv[i] + env_prepend_opt_len + 1;
- lt_opt_process_env_prepend (p);
- }
- else if (argv[i][env_prepend_opt_len] == '\0' && i + 1 < argc)
- {
- lt_opt_process_env_prepend (argv[++i]); /* don't copy */
- }
- else
- lt_fatal ("%s missing required argument", env_prepend_opt);
- continue;
- }
- if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
- {
- if (argv[i][env_append_opt_len] == '=')
- {
- const char *p = argv[i] + env_append_opt_len + 1;
- lt_opt_process_env_append (p);
- }
- else if (argv[i][env_append_opt_len] == '\0' && i + 1 < argc)
- {
- lt_opt_process_env_append (argv[++i]); /* don't copy */
- }
- else
- lt_fatal ("%s missing required argument", env_append_opt);
- continue;
- }
- if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
- {
- /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
- namespace, but it is not one of the ones we know about and
- have already dealt with, above (inluding dump-script), then
- report an error. Otherwise, targets might begin to believe
- they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
- namespace. The first time any user complains about this, we'll
- need to make LTWRAPPER_OPTION_PREFIX a configure-time option
- or a configure.ac-settable value.
- */
- lt_fatal ("Unrecognized option in %s namespace: '%s'",
- ltwrapper_option_prefix, argv[i]);
- }
- /* otherwise ... */
- newargz[++newargc] = xstrdup (argv[i]);
- }
- newargz[++newargc] = NULL;
-
- LTWRAPPER_DEBUGPRINTF (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
- for (i = 0; i < newargc; i++)
- {
- LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
- }
-
-EOF
-
- case $host_os in
- mingw*)
- cat <<"EOF"
- /* execv doesn't actually work on mingw as expected on unix */
- rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
- if (rval == -1)
- {
- /* failed to start process */
- LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
- return 127;
- }
- return rval;
-EOF
- ;;
- *)
- cat <<"EOF"
- execv (lt_argv_zero, newargz);
- return rval; /* =127, but avoids unused variable warning */
-EOF
- ;;
- esac
-
- cat <<"EOF"
-}
-
-void *
-xmalloc (size_t num)
-{
- void *p = (void *) malloc (num);
- if (!p)
- lt_fatal ("Memory exhausted");
-
- return p;
-}
-
-char *
-xstrdup (const char *string)
-{
- return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
- string) : NULL;
-}
-
-const char *
-base_name (const char *name)
-{
- const char *base;
-
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
- /* Skip over the disk name in MSDOS pathnames. */
- if (isalpha ((unsigned char) name[0]) && name[1] == ':')
- name += 2;
-#endif
-
- for (base = name; *name; name++)
- if (IS_DIR_SEPARATOR (*name))
- base = name + 1;
- return base;
-}
-
-int
-check_executable (const char *path)
-{
- struct stat st;
-
- LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n",
- path ? (*path ? path : "EMPTY!") : "NULL!"));
- if ((!path) || (!*path))
- return 0;
-
- if ((stat (path, &st) >= 0)
- && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
- return 1;
- else
- return 0;
-}
-
-int
-make_executable (const char *path)
-{
- int rval = 0;
- struct stat st;
-
- LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n",
- path ? (*path ? path : "EMPTY!") : "NULL!"));
- if ((!path) || (!*path))
- return 0;
-
- if (stat (path, &st) >= 0)
- {
- rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
- }
- return rval;
-}
-
-/* Searches for the full path of the wrapper. Returns
- newly allocated full path name if found, NULL otherwise
- Does not chase symlinks, even on platforms that support them.
-*/
-char *
-find_executable (const char *wrapper)
-{
- int has_slash = 0;
- const char *p;
- const char *p_next;
- /* static buffer for getcwd */
- char tmp[LT_PATHMAX + 1];
- int tmp_len;
- char *concat_name;
-
- LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n",
- wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
-
- if ((wrapper == NULL) || (*wrapper == '\0'))
- return NULL;
-
- /* Absolute path? */
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
- if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
- {
- concat_name = xstrdup (wrapper);
- if (check_executable (concat_name))
- return concat_name;
- XFREE (concat_name);
- }
- else
- {
-#endif
- if (IS_DIR_SEPARATOR (wrapper[0]))
- {
- concat_name = xstrdup (wrapper);
- if (check_executable (concat_name))
- return concat_name;
- XFREE (concat_name);
- }
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
- }
-#endif
-
- for (p = wrapper; *p; p++)
- if (*p == '/')
- {
- has_slash = 1;
- break;
- }
- if (!has_slash)
- {
- /* no slashes; search PATH */
- const char *path = getenv ("PATH");
- if (path != NULL)
- {
- for (p = path; *p; p = p_next)
- {
- const char *q;
- size_t p_len;
- for (q = p; *q; q++)
- if (IS_PATH_SEPARATOR (*q))
- break;
- p_len = q - p;
- p_next = (*q == '\0' ? q : q + 1);
- if (p_len == 0)
- {
- /* empty path: current directory */
- if (getcwd (tmp, LT_PATHMAX) == NULL)
- lt_fatal ("getcwd failed");
- tmp_len = strlen (tmp);
- concat_name =
- XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
- memcpy (concat_name, tmp, tmp_len);
- concat_name[tmp_len] = '/';
- strcpy (concat_name + tmp_len + 1, wrapper);
- }
- else
- {
- concat_name =
- XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
- memcpy (concat_name, p, p_len);
- concat_name[p_len] = '/';
- strcpy (concat_name + p_len + 1, wrapper);
- }
- if (check_executable (concat_name))
- return concat_name;
- XFREE (concat_name);
- }
- }
- /* not found in PATH; assume curdir */
- }
- /* Relative path | not found in path: prepend cwd */
- if (getcwd (tmp, LT_PATHMAX) == NULL)
- lt_fatal ("getcwd failed");
- tmp_len = strlen (tmp);
- concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
- memcpy (concat_name, tmp, tmp_len);
- concat_name[tmp_len] = '/';
- strcpy (concat_name + tmp_len + 1, wrapper);
-
- if (check_executable (concat_name))
- return concat_name;
- XFREE (concat_name);
- return NULL;
-}
-
-char *
-chase_symlinks (const char *pathspec)
-{
-#ifndef S_ISLNK
- return xstrdup (pathspec);
-#else
- char buf[LT_PATHMAX];
- struct stat s;
- char *tmp_pathspec = xstrdup (pathspec);
- char *p;
- int has_symlinks = 0;
- while (strlen (tmp_pathspec) && !has_symlinks)
- {
- LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
- tmp_pathspec));
- if (lstat (tmp_pathspec, &s) == 0)
- {
- if (S_ISLNK (s.st_mode) != 0)
- {
- has_symlinks = 1;
- break;
- }
-
- /* search backwards for last DIR_SEPARATOR */
- p = tmp_pathspec + strlen (tmp_pathspec) - 1;
- while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
- p--;
- if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
- {
- /* no more DIR_SEPARATORS left */
- break;
- }
- *p = '\0';
- }
- else
- {
- char *errstr = strerror (errno);
- lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
- }
- }
- XFREE (tmp_pathspec);
-
- if (!has_symlinks)
- {
- return xstrdup (pathspec);
- }
-
- tmp_pathspec = realpath (pathspec, buf);
- if (tmp_pathspec == 0)
- {
- lt_fatal ("Could not follow symlinks for %s", pathspec);
- }
- return xstrdup (tmp_pathspec);
-#endif
-}
-
-char *
-strendzap (char *str, const char *pat)
-{
- size_t len, patlen;
-
- assert (str != NULL);
- assert (pat != NULL);
-
- len = strlen (str);
- patlen = strlen (pat);
-
- if (patlen <= len)
- {
- str += len - patlen;
- if (strcmp (str, pat) == 0)
- *str = '\0';
- }
- return str;
-}
-
-static void
-lt_error_core (int exit_status, const char *mode,
- const char *message, va_list ap)
-{
- fprintf (stderr, "%s: %s: ", program_name, mode);
- vfprintf (stderr, message, ap);
- fprintf (stderr, ".\n");
-
- if (exit_status >= 0)
- exit (exit_status);
-}
-
-void
-lt_fatal (const char *message, ...)
-{
- va_list ap;
- va_start (ap, message);
- lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
- va_end (ap);
-}
-
-void
-lt_setenv (const char *name, const char *value)
-{
- LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
- (name ? name : "<NULL>"),
- (value ? value : "<NULL>")));
- {
-#ifdef HAVE_SETENV
- /* always make a copy, for consistency with !HAVE_SETENV */
- char *str = xstrdup (value);
- setenv (name, str, 1);
-#else
- int len = strlen (name) + 1 + strlen (value) + 1;
- char *str = XMALLOC (char, len);
- sprintf (str, "%s=%s", name, value);
- if (putenv (str) != EXIT_SUCCESS)
- {
- XFREE (str);
- }
-#endif
- }
-}
-
-char *
-lt_extend_str (const char *orig_value, const char *add, int to_end)
-{
- char *new_value;
- if (orig_value && *orig_value)
- {
- int orig_value_len = strlen (orig_value);
- int add_len = strlen (add);
- new_value = XMALLOC (char, add_len + orig_value_len + 1);
- if (to_end)
- {
- strcpy (new_value, orig_value);
- strcpy (new_value + orig_value_len, add);
- }
- else
- {
- strcpy (new_value, add);
- strcpy (new_value + add_len, orig_value);
- }
- }
- else
- {
- new_value = xstrdup (add);
- }
- return new_value;
-}
-
-int
-lt_split_name_value (const char *arg, char** name, char** value)
-{
- const char *p;
- int len;
- if (!arg || !*arg)
- return 1;
-
- p = strchr (arg, (int)'=');
-
- if (!p)
- return 1;
-
- *value = xstrdup (++p);
-
- len = strlen (arg) - strlen (*value);
- *name = XMALLOC (char, len);
- strncpy (*name, arg, len-1);
- (*name)[len - 1] = '\0';
-
- return 0;
-}
-
-void
-lt_opt_process_env_set (const char *arg)
-{
- char *name = NULL;
- char *value = NULL;
-
- if (lt_split_name_value (arg, &name, &value) != 0)
- {
- XFREE (name);
- XFREE (value);
- lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
- }
-
- lt_setenv (name, value);
- XFREE (name);
- XFREE (value);
-}
-
-void
-lt_opt_process_env_prepend (const char *arg)
-{
- char *name = NULL;
- char *value = NULL;
- char *new_value = NULL;
-
- if (lt_split_name_value (arg, &name, &value) != 0)
- {
- XFREE (name);
- XFREE (value);
- lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
- }
-
- new_value = lt_extend_str (getenv (name), value, 0);
- lt_setenv (name, new_value);
- XFREE (new_value);
- XFREE (name);
- XFREE (value);
-}
-
-void
-lt_opt_process_env_append (const char *arg)
-{
- char *name = NULL;
- char *value = NULL;
- char *new_value = NULL;
-
- if (lt_split_name_value (arg, &name, &value) != 0)
- {
- XFREE (name);
- XFREE (value);
- lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
- }
-
- new_value = lt_extend_str (getenv (name), value, 1);
- lt_setenv (name, new_value);
- XFREE (new_value);
- XFREE (name);
- XFREE (value);
-}
-
-void
-lt_update_exe_path (const char *name, const char *value)
-{
- LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
- (name ? name : "<NULL>"),
- (value ? value : "<NULL>")));
-
- if (name && *name && value && *value)
- {
- char *new_value = lt_extend_str (getenv (name), value, 0);
- /* some systems can't cope with a ':'-terminated path #' */
- int len = strlen (new_value);
- while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
- {
- new_value[len-1] = '\0';
- }
- lt_setenv (name, new_value);
- XFREE (new_value);
- }
-}
-
-void
-lt_update_lib_path (const char *name, const char *value)
-{
- LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
- (name ? name : "<NULL>"),
- (value ? value : "<NULL>")));
-
- if (name && *name && value && *value)
- {
- char *new_value = lt_extend_str (getenv (name), value, 0);
- lt_setenv (name, new_value);
- XFREE (new_value);
- }
-}
-
-
-EOF
-}
-# end: func_emit_cwrapperexe_src
-
-# func_mode_link arg...
-func_mode_link ()
-{
- $opt_debug
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
- # It is impossible to link a dll without this setting, and
- # we shouldn't force the makefile maintainer to figure out
- # which system we are compiling for in order to pass an extra
- # flag for every libtool invocation.
- # allow_undefined=no
-
- # FIXME: Unfortunately, there are problems with the above when trying
- # to make a dll which has undefined symbols, in which case not
- # even a static library is built. For now, we need to specify
- # -no-undefined on the libtool link line when we can be certain
- # that all symbols are satisfied, otherwise we get a static library.
- allow_undefined=yes
- ;;
- *)
- allow_undefined=yes
- ;;
- esac
- libtool_args=$nonopt
- base_compile="$nonopt $@"
- compile_command=$nonopt
- finalize_command=$nonopt
-
- compile_rpath=
- finalize_rpath=
- compile_shlibpath=
- finalize_shlibpath=
- convenience=
- old_convenience=
- deplibs=
- old_deplibs=
- compiler_flags=
- linker_flags=
- dllsearchpath=
- lib_search_path=`pwd`
- inst_prefix_dir=
- new_inherited_linker_flags=
-
- avoid_version=no
- dlfiles=
- dlprefiles=
- dlself=no
- export_dynamic=no
- export_symbols=
- export_symbols_regex=
- generated=
- libobjs=
- ltlibs=
- module=no
- no_install=no
- objs=
- non_pic_objects=
- precious_files_regex=
- prefer_static_libs=no
- preload=no
- prev=
- prevarg=
- release=
- rpath=
- xrpath=
- perm_rpath=
- temp_rpath=
- thread_safe=no
- vinfo=
- vinfo_number=no
- weak_libs=
- single_module="${wl}-single_module"
- func_infer_tag $base_compile
-
- # We need to know -static, to get the right output filenames.
- for arg
- do
- case $arg in
- -shared)
- test "$build_libtool_libs" != yes && \
- func_fatal_configuration "can not build a shared library"
- build_old_libs=no
- break
- ;;
- -all-static | -static | -static-libtool-libs)
- case $arg in
- -all-static)
- if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
- func_warning "complete static linking is impossible in this configuration"
- fi
- if test -n "$link_static_flag"; then
- dlopen_self=$dlopen_self_static
- fi
- prefer_static_libs=yes
- ;;
- -static)
- if test -z "$pic_flag" && test -n "$link_static_flag"; then
- dlopen_self=$dlopen_self_static
- fi
- prefer_static_libs=built
- ;;
- -static-libtool-libs)
- if test -z "$pic_flag" && test -n "$link_static_flag"; then
- dlopen_self=$dlopen_self_static
- fi
- prefer_static_libs=yes
- ;;
- esac
- build_libtool_libs=no
- build_old_libs=yes
- break
- ;;
- esac
- done
-
- # See if our shared archives depend on static archives.
- test -n "$old_archive_from_new_cmds" && build_old_libs=yes
-
- # Go through the arguments, transforming them on the way.
- while test "$#" -gt 0; do
- arg="$1"
- shift
- func_quote_for_eval "$arg"
- qarg=$func_quote_for_eval_unquoted_result
- func_append libtool_args " $func_quote_for_eval_result"
-
- # If the previous option needs an argument, assign it.
- if test -n "$prev"; then
- case $prev in
- output)
- func_append compile_command " @OUTPUT@"
- func_append finalize_command " @OUTPUT@"
- ;;
- esac
-
- case $prev in
- dlfiles|dlprefiles)
- if test "$preload" = no; then
- # Add the symbol object into the linking commands.
- func_append compile_command " @SYMFILE@"
- func_append finalize_command " @SYMFILE@"
- preload=yes
- fi
- case $arg in
- *.la | *.lo) ;; # We handle these cases below.
- force)
- if test "$dlself" = no; then
- dlself=needless
- export_dynamic=yes
- fi
- prev=
- continue
- ;;
- self)
- if test "$prev" = dlprefiles; then
- dlself=yes
- elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
- dlself=yes
- else
- dlself=needless
- export_dynamic=yes
- fi
- prev=
- continue
- ;;
- *)
- if test "$prev" = dlfiles; then
- dlfiles="$dlfiles $arg"
- else
- dlprefiles="$dlprefiles $arg"
- fi
- prev=
- continue
- ;;
- esac
- ;;
- expsyms)
- export_symbols="$arg"
- test -f "$arg" \
- || func_fatal_error "symbol file \`$arg' does not exist"
- prev=
- continue
- ;;
- expsyms_regex)
- export_symbols_regex="$arg"
- prev=
- continue
- ;;
- framework)
- case $host in
- *-*-darwin*)
- case "$deplibs " in
- *" $qarg.ltframework "*) ;;
- *) deplibs="$deplibs $qarg.ltframework" # this is fixed later
- ;;
- esac
- ;;
- esac
- prev=
- continue
- ;;
- inst_prefix)
- inst_prefix_dir="$arg"
- prev=
- continue
- ;;
- objectlist)
- if test -f "$arg"; then
- save_arg=$arg
- moreargs=
- for fil in `cat "$save_arg"`
- do
-# moreargs="$moreargs $fil"
- arg=$fil
- # A libtool-controlled object.
-
- # Check to see that this really is a libtool object.
- if func_lalib_unsafe_p "$arg"; then
- pic_object=
- non_pic_object=
-
- # Read the .lo file
- func_source "$arg"
-
- if test -z "$pic_object" ||
- test -z "$non_pic_object" ||
- test "$pic_object" = none &&
- test "$non_pic_object" = none; then
- func_fatal_error "cannot find name of object for \`$arg'"
- fi
-
- # Extract subdirectory from the argument.
- func_dirname "$arg" "/" ""
- xdir="$func_dirname_result"
-
- if test "$pic_object" != none; then
- # Prepend the subdirectory the object is found in.
- pic_object="$xdir$pic_object"
-
- if test "$prev" = dlfiles; then
- if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
- dlfiles="$dlfiles $pic_object"
- prev=
- continue
- else
- # If libtool objects are unsupported, then we need to preload.
- prev=dlprefiles
- fi
- fi
-
- # CHECK ME: I think I busted this. -Ossama
- if test "$prev" = dlprefiles; then
- # Preload the old-style object.
- dlprefiles="$dlprefiles $pic_object"
- prev=
- fi
-
- # A PIC object.
- func_append libobjs " $pic_object"
- arg="$pic_object"
- fi
-
- # Non-PIC object.
- if test "$non_pic_object" != none; then
- # Prepend the subdirectory the object is found in.
- non_pic_object="$xdir$non_pic_object"
-
- # A standard non-PIC object
- func_append non_pic_objects " $non_pic_object"
- if test -z "$pic_object" || test "$pic_object" = none ; then
- arg="$non_pic_object"
- fi
- else
- # If the PIC object exists, use it instead.
- # $xdir was prepended to $pic_object above.
- non_pic_object="$pic_object"
- func_append non_pic_objects " $non_pic_object"
- fi
- else
- # Only an error if not doing a dry-run.
- if $opt_dry_run; then
- # Extract subdirectory from the argument.
- func_dirname "$arg" "/" ""
- xdir="$func_dirname_result"
-
- func_lo2o "$arg"
- pic_object=$xdir$objdir/$func_lo2o_result
- non_pic_object=$xdir$func_lo2o_result
- func_append libobjs " $pic_object"
- func_append non_pic_objects " $non_pic_object"
- else
- func_fatal_error "\`$arg' is not a valid libtool object"
- fi
- fi
- done
- else
- func_fatal_error "link input file \`$arg' does not exist"
- fi
- arg=$save_arg
- prev=
- continue
- ;;
- precious_regex)
- precious_files_regex="$arg"
- prev=
- continue
- ;;
- release)
- release="-$arg"
- prev=
- continue
- ;;
- rpath | xrpath)
- # We need an absolute path.
- case $arg in
- [\\/]* | [A-Za-z]:[\\/]*) ;;
- *)
- func_fatal_error "only absolute run-paths are allowed"
- ;;
- esac
- if test "$prev" = rpath; then
- case "$rpath " in
- *" $arg "*) ;;
- *) rpath="$rpath $arg" ;;
- esac
- else
- case "$xrpath " in
- *" $arg "*) ;;
- *) xrpath="$xrpath $arg" ;;
- esac
- fi
- prev=
- continue
- ;;
- shrext)
- shrext_cmds="$arg"
- prev=
- continue
- ;;
- weak)
- weak_libs="$weak_libs $arg"
- prev=
- continue
- ;;
- xcclinker)
- linker_flags="$linker_flags $qarg"
- compiler_flags="$compiler_flags $qarg"
- prev=
- func_append compile_command " $qarg"
- func_append finalize_command " $qarg"
- continue
- ;;
- xcompiler)
- compiler_flags="$compiler_flags $qarg"
- prev=
- func_append compile_command " $qarg"
- func_append finalize_command " $qarg"
- continue
- ;;
- xlinker)
- linker_flags="$linker_flags $qarg"
- compiler_flags="$compiler_flags $wl$qarg"
- prev=
- func_append compile_command " $wl$qarg"
- func_append finalize_command " $wl$qarg"
- continue
- ;;
- *)
- eval "$prev=\"\$arg\""
- prev=
- continue
- ;;
- esac
- fi # test -n "$prev"
-
- prevarg="$arg"
-
- case $arg in
- -all-static)
- if test -n "$link_static_flag"; then
- # See comment for -static flag below, for more details.
- func_append compile_command " $link_static_flag"
- func_append finalize_command " $link_static_flag"
- fi
- continue
- ;;
-
- -allow-undefined)
- # FIXME: remove this flag sometime in the future.
- func_fatal_error "\`-allow-undefined' must not be used because it is the default"
- ;;
-
- -avoid-version)
- avoid_version=yes
- continue
- ;;
-
- -dlopen)
- prev=dlfiles
- continue
- ;;
-
- -dlpreopen)
- prev=dlprefiles
- continue
- ;;
-
- -export-dynamic)
- export_dynamic=yes
- continue
- ;;
-
- -export-symbols | -export-symbols-regex)
- if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
- func_fatal_error "more than one -exported-symbols argument is not allowed"
- fi
- if test "X$arg" = "X-export-symbols"; then
- prev=expsyms
- else
- prev=expsyms_regex
- fi
- continue
- ;;
-
- -framework)
- prev=framework
- continue
- ;;
-
- -inst-prefix-dir)
- prev=inst_prefix
- continue
- ;;
-
- # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
- # so, if we see these flags be careful not to treat them like -L
- -L[A-Z][A-Z]*:*)
- case $with_gcc/$host in
- no/*-*-irix* | /*-*-irix*)
- func_append compile_command " $arg"
- func_append finalize_command " $arg"
- ;;
- esac
- continue
- ;;
-
- -L*)
- func_stripname '-L' '' "$arg"
- dir=$func_stripname_result
- if test -z "$dir"; then
- if test "$#" -gt 0; then
- func_fatal_error "require no space between \`-L' and \`$1'"
- else
- func_fatal_error "need path for \`-L' option"
- fi
- fi
- # We need an absolute path.
- case $dir in
- [\\/]* | [A-Za-z]:[\\/]*) ;;
- *)
- absdir=`cd "$dir" && pwd`
- test -z "$absdir" && \
- func_fatal_error "cannot determine absolute directory name of \`$dir'"
- dir="$absdir"
- ;;
- esac
- case "$deplibs " in
- *" -L$dir "*) ;;
- *)
- deplibs="$deplibs -L$dir"
- lib_search_path="$lib_search_path $dir"
- ;;
- esac
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
- testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
- case :$dllsearchpath: in
- *":$dir:"*) ;;
- ::) dllsearchpath=$dir;;
- *) dllsearchpath="$dllsearchpath:$dir";;
- esac
- case :$dllsearchpath: in
- *":$testbindir:"*) ;;
- ::) dllsearchpath=$testbindir;;
- *) dllsearchpath="$dllsearchpath:$testbindir";;
- esac
- ;;
- esac
- continue
- ;;
-
- -l*)
- if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)
- # These systems don't actually have a C or math library (as such)
- continue
- ;;
- *-*-os2*)
- # These systems don't actually have a C library (as such)
- test "X$arg" = "X-lc" && continue
- ;;
- *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
- # Do not include libc due to us having libc/libc_r.
- test "X$arg" = "X-lc" && continue
- ;;
- *-*-rhapsody* | *-*-darwin1.[012])
- # Rhapsody C and math libraries are in the System framework
- deplibs="$deplibs System.ltframework"
- continue
- ;;
- *-*-sco3.2v5* | *-*-sco5v6*)
- # Causes problems with __ctype
- test "X$arg" = "X-lc" && continue
- ;;
- *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
- # Compiler inserts libc in the correct place for threads to work
- test "X$arg" = "X-lc" && continue
- ;;
- esac
- elif test "X$arg" = "X-lc_r"; then
- case $host in
- *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
- # Do not include libc_r directly, use -pthread flag.
- continue
- ;;
- esac
- fi
- deplibs="$deplibs $arg"
- continue
- ;;
-
- -module)
- module=yes
- continue
- ;;
-
- # Tru64 UNIX uses -model [arg] to determine the layout of C++
- # classes, name mangling, and exception handling.
- # Darwin uses the -arch flag to determine output architecture.
- -model|-arch|-isysroot)
- compiler_flags="$compiler_flags $arg"
- func_append compile_command " $arg"
- func_append finalize_command " $arg"
- prev=xcompiler
- continue
- ;;
-
- -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
- compiler_flags="$compiler_flags $arg"
- func_append compile_command " $arg"
- func_append finalize_command " $arg"
- case "$new_inherited_linker_flags " in
- *" $arg "*) ;;
- * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
- esac
- continue
- ;;
-
- -multi_module)
- single_module="${wl}-multi_module"
- continue
- ;;
-
- -no-fast-install)
- fast_install=no
- continue
- ;;
-
- -no-install)
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
- # The PATH hackery in wrapper scripts is required on Windows
- # and Darwin in order for the loader to find any dlls it needs.
- func_warning "\`-no-install' is ignored for $host"
- func_warning "assuming \`-no-fast-install' instead"
- fast_install=no
- ;;
- *) no_install=yes ;;
- esac
- continue
- ;;
-
- -no-undefined)
- allow_undefined=no
- continue
- ;;
-
- -objectlist)
- prev=objectlist
- continue
- ;;
-
- -o) prev=output ;;
-
- -precious-files-regex)
- prev=precious_regex
- continue
- ;;
-
- -release)
- prev=release
- continue
- ;;
-
- -rpath)
- prev=rpath
- continue
- ;;
-
- -R)
- prev=xrpath
- continue
- ;;
-
- -R*)
- func_stripname '-R' '' "$arg"
- dir=$func_stripname_result
- # We need an absolute path.
- case $dir in
- [\\/]* | [A-Za-z]:[\\/]*) ;;
- *)
- func_fatal_error "only absolute run-paths are allowed"
- ;;
- esac
- case "$xrpath " in
- *" $dir "*) ;;
- *) xrpath="$xrpath $dir" ;;
- esac
- continue
- ;;
-
- -shared)
- # The effects of -shared are defined in a previous loop.
- continue
- ;;
-
- -shrext)
- prev=shrext
- continue
- ;;
-
- -static | -static-libtool-libs)
- # The effects of -static are defined in a previous loop.
- # We used to do the same as -all-static on platforms that
- # didn't have a PIC flag, but the assumption that the effects
- # would be equivalent was wrong. It would break on at least
- # Digital Unix and AIX.
- continue
- ;;
-
- -thread-safe)
- thread_safe=yes
- continue
- ;;
-
- -version-info)
- prev=vinfo
- continue
- ;;
-
- -version-number)
- prev=vinfo
- vinfo_number=yes
- continue
- ;;
-
- -weak)
- prev=weak
- continue
- ;;
-
- -Wc,*)
- func_stripname '-Wc,' '' "$arg"
- args=$func_stripname_result
- arg=
- save_ifs="$IFS"; IFS=','
- for flag in $args; do
- IFS="$save_ifs"
- func_quote_for_eval "$flag"
- arg="$arg $wl$func_quote_for_eval_result"
- compiler_flags="$compiler_flags $func_quote_for_eval_result"
- done
- IFS="$save_ifs"
- func_stripname ' ' '' "$arg"
- arg=$func_stripname_result
- ;;
-
- -Wl,*)
- func_stripname '-Wl,' '' "$arg"
- args=$func_stripname_result
- arg=
- save_ifs="$IFS"; IFS=','
- for flag in $args; do
- IFS="$save_ifs"
- func_quote_for_eval "$flag"
- arg="$arg $wl$func_quote_for_eval_result"
- compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
- linker_flags="$linker_flags $func_quote_for_eval_result"
- done
- IFS="$save_ifs"
- func_stripname ' ' '' "$arg"
- arg=$func_stripname_result
- ;;
-
- -Xcompiler)
- prev=xcompiler
- continue
- ;;
-
- -Xlinker)
- prev=xlinker
- continue
- ;;
-
- -XCClinker)
- prev=xcclinker
- continue
- ;;
-
- # -msg_* for osf cc
- -msg_*)
- func_quote_for_eval "$arg"
- arg="$func_quote_for_eval_result"
- ;;
-
- # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
- # -r[0-9][0-9]* specifies the processor on the SGI compiler
- # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
- # +DA*, +DD* enable 64-bit mode on the HP compiler
- # -q* pass through compiler args for the IBM compiler
- # -m*, -t[45]*, -txscale* pass through architecture-specific
- # compiler args for GCC
- # -F/path gives path to uninstalled frameworks, gcc on darwin
- # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
- # @file GCC response files
- -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
- -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
- func_quote_for_eval "$arg"
- arg="$func_quote_for_eval_result"
- func_append compile_command " $arg"
- func_append finalize_command " $arg"
- compiler_flags="$compiler_flags $arg"
- continue
- ;;
-
- # Some other compiler flag.
- -* | +*)
- func_quote_for_eval "$arg"
- arg="$func_quote_for_eval_result"
- ;;
-
- *.$objext)
- # A standard object.
- objs="$objs $arg"
- ;;
-
- *.lo)
- # A libtool-controlled object.
-
- # Check to see that this really is a libtool object.
- if func_lalib_unsafe_p "$arg"; then
- pic_object=
- non_pic_object=
-
- # Read the .lo file
- func_source "$arg"
-
- if test -z "$pic_object" ||
- test -z "$non_pic_object" ||
- test "$pic_object" = none &&
- test "$non_pic_object" = none; then
- func_fatal_error "cannot find name of object for \`$arg'"
- fi
-
- # Extract subdirectory from the argument.
- func_dirname "$arg" "/" ""
- xdir="$func_dirname_result"
-
- if test "$pic_object" != none; then
- # Prepend the subdirectory the object is found in.
- pic_object="$xdir$pic_object"
-
- if test "$prev" = dlfiles; then
- if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
- dlfiles="$dlfiles $pic_object"
- prev=
- continue
- else
- # If libtool objects are unsupported, then we need to preload.
- prev=dlprefiles
- fi
- fi
-
- # CHECK ME: I think I busted this. -Ossama
- if test "$prev" = dlprefiles; then
- # Preload the old-style object.
- dlprefiles="$dlprefiles $pic_object"
- prev=
- fi
-
- # A PIC object.
- func_append libobjs " $pic_object"
- arg="$pic_object"
- fi
-
- # Non-PIC object.
- if test "$non_pic_object" != none; then
- # Prepend the subdirectory the object is found in.
- non_pic_object="$xdir$non_pic_object"
-
- # A standard non-PIC object
- func_append non_pic_objects " $non_pic_object"
- if test -z "$pic_object" || test "$pic_object" = none ; then
- arg="$non_pic_object"
- fi
- else
- # If the PIC object exists, use it instead.
- # $xdir was prepended to $pic_object above.
- non_pic_object="$pic_object"
- func_append non_pic_objects " $non_pic_object"
- fi
- else
- # Only an error if not doing a dry-run.
- if $opt_dry_run; then
- # Extract subdirectory from the argument.
- func_dirname "$arg" "/" ""
- xdir="$func_dirname_result"
-
- func_lo2o "$arg"
- pic_object=$xdir$objdir/$func_lo2o_result
- non_pic_object=$xdir$func_lo2o_result
- func_append libobjs " $pic_object"
- func_append non_pic_objects " $non_pic_object"
- else
- func_fatal_error "\`$arg' is not a valid libtool object"
- fi
- fi
- ;;
-
- *.$libext)
- # An archive.
- deplibs="$deplibs $arg"
- old_deplibs="$old_deplibs $arg"
- continue
- ;;
-
- *.la)
- # A libtool-controlled library.
-
- if test "$prev" = dlfiles; then
- # This library was specified with -dlopen.
- dlfiles="$dlfiles $arg"
- prev=
- elif test "$prev" = dlprefiles; then
- # The library was specified with -dlpreopen.
- dlprefiles="$dlprefiles $arg"
- prev=
- else
- deplibs="$deplibs $arg"
- fi
- continue
- ;;
-
- # Some other compiler argument.
- *)
- # Unknown arguments in both finalize_command and compile_command need
- # to be aesthetically quoted because they are evaled later.
- func_quote_for_eval "$arg"
- arg="$func_quote_for_eval_result"
- ;;
- esac # arg
-
- # Now actually substitute the argument into the commands.
- if test -n "$arg"; then
- func_append compile_command " $arg"
- func_append finalize_command " $arg"
- fi
- done # argument parsing loop
-
- test -n "$prev" && \
- func_fatal_help "the \`$prevarg' option requires an argument"
-
- if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
- eval arg=\"$export_dynamic_flag_spec\"
- func_append compile_command " $arg"
- func_append finalize_command " $arg"
- fi
-
- oldlibs=
- # calculate the name of the file, without its directory
- func_basename "$output"
- outputname="$func_basename_result"
- libobjs_save="$libobjs"
-
- if test -n "$shlibpath_var"; then
- # get the directories listed in $shlibpath_var
- eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
- else
- shlib_search_path=
- fi
- eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
- eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
-
- func_dirname "$output" "/" ""
- output_objdir="$func_dirname_result$objdir"
- # Create the object directory.
- func_mkdir_p "$output_objdir"
-
- # Determine the type of output
- case $output in
- "")
- func_fatal_help "you must specify an output file"
- ;;
- *.$libext) linkmode=oldlib ;;
- *.lo | *.$objext) linkmode=obj ;;
- *.la) linkmode=lib ;;
- *) linkmode=prog ;; # Anything else should be a program.
- esac
-
- specialdeplibs=
-
- libs=
- # Find all interdependent deplibs by searching for libraries
- # that are linked more than once (e.g. -la -lb -la)
- for deplib in $deplibs; do
- if $opt_duplicate_deps ; then
- case "$libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
- fi
- libs="$libs $deplib"
- done
-
- if test "$linkmode" = lib; then
- libs="$predeps $libs $compiler_lib_search_path $postdeps"
-
- # Compute libraries that are listed more than once in $predeps
- # $postdeps and mark them as special (i.e., whose duplicates are
- # not to be eliminated).
- pre_post_deps=
- if $opt_duplicate_compiler_generated_deps; then
- for pre_post_dep in $predeps $postdeps; do
- case "$pre_post_deps " in
- *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
- esac
- pre_post_deps="$pre_post_deps $pre_post_dep"
- done
- fi
- pre_post_deps=
- fi
-
- deplibs=
- newdependency_libs=
- newlib_search_path=
- need_relink=no # whether we're linking any uninstalled libtool libraries
- notinst_deplibs= # not-installed libtool libraries
- notinst_path= # paths that contain not-installed libtool libraries
-
- case $linkmode in
- lib)
- passes="conv dlpreopen link"
- for file in $dlfiles $dlprefiles; do
- case $file in
- *.la) ;;
- *)
- func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
- ;;
- esac
- done
- ;;
- prog)
- compile_deplibs=
- finalize_deplibs=
- alldeplibs=no
- newdlfiles=
- newdlprefiles=
- passes="conv scan dlopen dlpreopen link"
- ;;
- *) passes="conv"
- ;;
- esac
-
- for pass in $passes; do
- # The preopen pass in lib mode reverses $deplibs; put it back here
- # so that -L comes before libs that need it for instance...
- if test "$linkmode,$pass" = "lib,link"; then
- ## FIXME: Find the place where the list is rebuilt in the wrong
- ## order, and fix it there properly
- tmp_deplibs=
- for deplib in $deplibs; do
- tmp_deplibs="$deplib $tmp_deplibs"
- done
- deplibs="$tmp_deplibs"
- fi
-
- if test "$linkmode,$pass" = "lib,link" ||
- test "$linkmode,$pass" = "prog,scan"; then
- libs="$deplibs"
- deplibs=
- fi
- if test "$linkmode" = prog; then
- case $pass in
- dlopen) libs="$dlfiles" ;;
- dlpreopen) libs="$dlprefiles" ;;
- link)
- libs="$deplibs %DEPLIBS%"
- test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
- ;;
- esac
- fi
- if test "$linkmode,$pass" = "lib,dlpreopen"; then
- # Collect and forward deplibs of preopened libtool libs
- for lib in $dlprefiles; do
- # Ignore non-libtool-libs
- dependency_libs=
- case $lib in
- *.la) func_source "$lib" ;;
- esac
-
- # Collect preopened libtool deplibs, except any this library
- # has declared as weak libs
- for deplib in $dependency_libs; do
- deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"`
- case " $weak_libs " in
- *" $deplib_base "*) ;;
- *) deplibs="$deplibs $deplib" ;;
- esac
- done
- done
- libs="$dlprefiles"
- fi
- if test "$pass" = dlopen; then
- # Collect dlpreopened libraries
- save_deplibs="$deplibs"
- deplibs=
- fi
-
- for deplib in $libs; do
- lib=
- found=no
- case $deplib in
- -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
- if test "$linkmode,$pass" = "prog,link"; then
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- compiler_flags="$compiler_flags $deplib"
- if test "$linkmode" = lib ; then
- case "$new_inherited_linker_flags " in
- *" $deplib "*) ;;
- * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
- esac
- fi
- fi
- continue
- ;;
- -l*)
- if test "$linkmode" != lib && test "$linkmode" != prog; then
- func_warning "\`-l' is ignored for archives/objects"
- continue
- fi
- func_stripname '-l' '' "$deplib"
- name=$func_stripname_result
- if test "$linkmode" = lib; then
- searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
- else
- searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
- fi
- for searchdir in $searchdirs; do
- for search_ext in .la $std_shrext .so .a; do
- # Search the libtool library
- lib="$searchdir/lib${name}${search_ext}"
- if test -f "$lib"; then
- if test "$search_ext" = ".la"; then
- found=yes
- else
- found=no
- fi
- break 2
- fi
- done
- done
- if test "$found" != yes; then
- # deplib doesn't seem to be a libtool library
- if test "$linkmode,$pass" = "prog,link"; then
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- deplibs="$deplib $deplibs"
- test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
- fi
- continue
- else # deplib is a libtool library
- # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
- # We need to do some special things here, and not later.
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- case " $predeps $postdeps " in
- *" $deplib "*)
- if func_lalib_p "$lib"; then
- library_names=
- old_library=
- func_source "$lib"
- for l in $old_library $library_names; do
- ll="$l"
- done
- if test "X$ll" = "X$old_library" ; then # only static version available
- found=no
- func_dirname "$lib" "" "."
- ladir="$func_dirname_result"
- lib=$ladir/$old_library
- if test "$linkmode,$pass" = "prog,link"; then
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- deplibs="$deplib $deplibs"
- test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
- fi
- continue
- fi
- fi
- ;;
- *) ;;
- esac
- fi
- fi
- ;; # -l
- *.ltframework)
- if test "$linkmode,$pass" = "prog,link"; then
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- deplibs="$deplib $deplibs"
- if test "$linkmode" = lib ; then
- case "$new_inherited_linker_flags " in
- *" $deplib "*) ;;
- * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
- esac
- fi
- fi
- continue
- ;;
- -L*)
- case $linkmode in
- lib)
- deplibs="$deplib $deplibs"
- test "$pass" = conv && continue
- newdependency_libs="$deplib $newdependency_libs"
- func_stripname '-L' '' "$deplib"
- newlib_search_path="$newlib_search_path $func_stripname_result"
- ;;
- prog)
- if test "$pass" = conv; then
- deplibs="$deplib $deplibs"
- continue
- fi
- if test "$pass" = scan; then
- deplibs="$deplib $deplibs"
- else
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- fi
- func_stripname '-L' '' "$deplib"
- newlib_search_path="$newlib_search_path $func_stripname_result"
- ;;
- *)
- func_warning "\`-L' is ignored for archives/objects"
- ;;
- esac # linkmode
- continue
- ;; # -L
- -R*)
- if test "$pass" = link; then
- func_stripname '-R' '' "$deplib"
- dir=$func_stripname_result
- # Make sure the xrpath contains only unique directories.
- case "$xrpath " in
- *" $dir "*) ;;
- *) xrpath="$xrpath $dir" ;;
- esac
- fi
- deplibs="$deplib $deplibs"
- continue
- ;;
- *.la) lib="$deplib" ;;
- *.$libext)
- if test "$pass" = conv; then
- deplibs="$deplib $deplibs"
- continue
- fi
- case $linkmode in
- lib)
- # Linking convenience modules into shared libraries is allowed,
- # but linking other static libraries is non-portable.
- case " $dlpreconveniencelibs " in
- *" $deplib "*) ;;
- *)
- valid_a_lib=no
- case $deplibs_check_method in
- match_pattern*)
- set dummy $deplibs_check_method; shift
- match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
- if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
- | $EGREP "$match_pattern_regex" > /dev/null; then
- valid_a_lib=yes
- fi
- ;;
- pass_all)
- valid_a_lib=yes
- ;;
- esac
- if test "$valid_a_lib" != yes; then
- $ECHO
- $ECHO "*** Warning: Trying to link with static lib archive $deplib."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which you do not appear to have"
- $ECHO "*** because the file extensions .$libext of this argument makes me believe"
- $ECHO "*** that it is just a static archive that I should not use here."
- else
- $ECHO
- $ECHO "*** Warning: Linking the shared library $output against the"
- $ECHO "*** static library $deplib is not portable!"
- deplibs="$deplib $deplibs"
- fi
- ;;
- esac
- continue
- ;;
- prog)
- if test "$pass" != link; then
- deplibs="$deplib $deplibs"
- else
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- fi
- continue
- ;;
- esac # linkmode
- ;; # *.$libext
- *.lo | *.$objext)
- if test "$pass" = conv; then
- deplibs="$deplib $deplibs"
- elif test "$linkmode" = prog; then
- if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
- # If there is no dlopen support or we're linking statically,
- # we need to preload.
- newdlprefiles="$newdlprefiles $deplib"
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- newdlfiles="$newdlfiles $deplib"
- fi
- fi
- continue
- ;;
- %DEPLIBS%)
- alldeplibs=yes
- continue
- ;;
- esac # case $deplib
-
- if test "$found" = yes || test -f "$lib"; then :
- else
- func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
- fi
-
- # Check to see that this really is a libtool archive.
- func_lalib_unsafe_p "$lib" \
- || func_fatal_error "\`$lib' is not a valid libtool archive"
-
- func_dirname "$lib" "" "."
- ladir="$func_dirname_result"
-
- dlname=
- dlopen=
- dlpreopen=
- libdir=
- library_names=
- old_library=
- inherited_linker_flags=
- # If the library was installed with an old release of libtool,
- # it will not redefine variables installed, or shouldnotlink
- installed=yes
- shouldnotlink=no
- avoidtemprpath=
-
-
- # Read the .la file
- func_source "$lib"
-
- # Convert "-framework foo" to "foo.ltframework"
- if test -n "$inherited_linker_flags"; then
- tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'`
- for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
- case " $new_inherited_linker_flags " in
- *" $tmp_inherited_linker_flag "*) ;;
- *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
- esac
- done
- fi
- dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
- if test "$linkmode,$pass" = "lib,link" ||
- test "$linkmode,$pass" = "prog,scan" ||
- { test "$linkmode" != prog && test "$linkmode" != lib; }; then
- test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
- test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
- fi
-
- if test "$pass" = conv; then
- # Only check for convenience libraries
- deplibs="$lib $deplibs"
- if test -z "$libdir"; then
- if test -z "$old_library"; then
- func_fatal_error "cannot find name of link library for \`$lib'"
- fi
- # It is a libtool convenience library, so add in its objects.
- convenience="$convenience $ladir/$objdir/$old_library"
- old_convenience="$old_convenience $ladir/$objdir/$old_library"
- tmp_libs=
- for deplib in $dependency_libs; do
- deplibs="$deplib $deplibs"
- if $opt_duplicate_deps ; then
- case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
- fi
- tmp_libs="$tmp_libs $deplib"
- done
- elif test "$linkmode" != prog && test "$linkmode" != lib; then
- func_fatal_error "\`$lib' is not a convenience library"
- fi
- continue
- fi # $pass = conv
-
-
- # Get the name of the library we link against.
- linklib=
- for l in $old_library $library_names; do
- linklib="$l"
- done
- if test -z "$linklib"; then
- func_fatal_error "cannot find name of link library for \`$lib'"
- fi
-
- # This library was specified with -dlopen.
- if test "$pass" = dlopen; then
- if test -z "$libdir"; then
- func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
- fi
- if test -z "$dlname" ||
- test "$dlopen_support" != yes ||
- test "$build_libtool_libs" = no; then
- # If there is no dlname, no dlopen support or we're linking
- # statically, we need to preload. We also need to preload any
- # dependent libraries so libltdl's deplib preloader doesn't
- # bomb out in the load deplibs phase.
- dlprefiles="$dlprefiles $lib $dependency_libs"
- else
- newdlfiles="$newdlfiles $lib"
- fi
- continue
- fi # $pass = dlopen
-
- # We need an absolute path.
- case $ladir in
- [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
- *)
- abs_ladir=`cd "$ladir" && pwd`
- if test -z "$abs_ladir"; then
- func_warning "cannot determine absolute directory name of \`$ladir'"
- func_warning "passing it literally to the linker, although it might fail"
- abs_ladir="$ladir"
- fi
- ;;
- esac
- func_basename "$lib"
- laname="$func_basename_result"
-
- # Find the relevant object directory and library name.
- if test "X$installed" = Xyes; then
- if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
- func_warning "library \`$lib' was moved."
- dir="$ladir"
- absdir="$abs_ladir"
- libdir="$abs_ladir"
- else
- dir="$libdir"
- absdir="$libdir"
- fi
- test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
- else
- if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
- dir="$ladir"
- absdir="$abs_ladir"
- # Remove this search path later
- notinst_path="$notinst_path $abs_ladir"
- else
- dir="$ladir/$objdir"
- absdir="$abs_ladir/$objdir"
- # Remove this search path later
- notinst_path="$notinst_path $abs_ladir"
- fi
- fi # $installed = yes
- func_stripname 'lib' '.la' "$laname"
- name=$func_stripname_result
-
- # This library was specified with -dlpreopen.
- if test "$pass" = dlpreopen; then
- if test -z "$libdir" && test "$linkmode" = prog; then
- func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
- fi
- # Prefer using a static library (so that no silly _DYNAMIC symbols
- # are required to link).
- if test -n "$old_library"; then
- newdlprefiles="$newdlprefiles $dir/$old_library"
- # Keep a list of preopened convenience libraries to check
- # that they are being used correctly in the link pass.
- test -z "$libdir" && \
- dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
- # Otherwise, use the dlname, so that lt_dlopen finds it.
- elif test -n "$dlname"; then
- newdlprefiles="$newdlprefiles $dir/$dlname"
- else
- newdlprefiles="$newdlprefiles $dir/$linklib"
- fi
- fi # $pass = dlpreopen
-
- if test -z "$libdir"; then
- # Link the convenience library
- if test "$linkmode" = lib; then
- deplibs="$dir/$old_library $deplibs"
- elif test "$linkmode,$pass" = "prog,link"; then
- compile_deplibs="$dir/$old_library $compile_deplibs"
- finalize_deplibs="$dir/$old_library $finalize_deplibs"
- else
- deplibs="$lib $deplibs" # used for prog,scan pass
- fi
- continue
- fi
-
-
- if test "$linkmode" = prog && test "$pass" != link; then
- newlib_search_path="$newlib_search_path $ladir"
- deplibs="$lib $deplibs"
-
- linkalldeplibs=no
- if test "$link_all_deplibs" != no || test -z "$library_names" ||
- test "$build_libtool_libs" = no; then
- linkalldeplibs=yes
- fi
-
- tmp_libs=
- for deplib in $dependency_libs; do
- case $deplib in
- -L*) func_stripname '-L' '' "$deplib"
- newlib_search_path="$newlib_search_path $func_stripname_result"
- ;;
- esac
- # Need to link against all dependency_libs?
- if test "$linkalldeplibs" = yes; then
- deplibs="$deplib $deplibs"
- else
- # Need to hardcode shared library paths
- # or/and link against static libraries
- newdependency_libs="$deplib $newdependency_libs"
- fi
- if $opt_duplicate_deps ; then
- case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
- fi
- tmp_libs="$tmp_libs $deplib"
- done # for deplib
- continue
- fi # $linkmode = prog...
-
- if test "$linkmode,$pass" = "prog,link"; then
- if test -n "$library_names" &&
- { { test "$prefer_static_libs" = no ||
- test "$prefer_static_libs,$installed" = "built,yes"; } ||
- test -z "$old_library"; }; then
- # We need to hardcode the library path
- if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
- # Make sure the rpath contains only unique directories.
- case "$temp_rpath:" in
- *"$absdir:"*) ;;
- *) temp_rpath="$temp_rpath$absdir:" ;;
- esac
- fi
-
- # Hardcode the library path.
- # Skip directories that are in the system default run-time
- # search path.
- case " $sys_lib_dlsearch_path " in
- *" $absdir "*) ;;
- *)
- case "$compile_rpath " in
- *" $absdir "*) ;;
- *) compile_rpath="$compile_rpath $absdir"
- esac
- ;;
- esac
- case " $sys_lib_dlsearch_path " in
- *" $libdir "*) ;;
- *)
- case "$finalize_rpath " in
- *" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir"
- esac
- ;;
- esac
- fi # $linkmode,$pass = prog,link...
-
- if test "$alldeplibs" = yes &&
- { test "$deplibs_check_method" = pass_all ||
- { test "$build_libtool_libs" = yes &&
- test -n "$library_names"; }; }; then
- # We only need to search for static libraries
- continue
- fi
- fi
-
- link_static=no # Whether the deplib will be linked statically
- use_static_libs=$prefer_static_libs
- if test "$use_static_libs" = built && test "$installed" = yes; then
- use_static_libs=no
- fi
- if test -n "$library_names" &&
- { test "$use_static_libs" = no || test -z "$old_library"; }; then
- case $host in
- *cygwin* | *mingw* | *cegcc*)
- # No point in relinking DLLs because paths are not encoded
- notinst_deplibs="$notinst_deplibs $lib"
- need_relink=no
- ;;
- *)
- if test "$installed" = no; then
- notinst_deplibs="$notinst_deplibs $lib"
- need_relink=yes
- fi
- ;;
- esac
- # This is a shared library
-
- # Warn about portability, can't link against -module's on some
- # systems (darwin). Don't bleat about dlopened modules though!
- dlopenmodule=""
- for dlpremoduletest in $dlprefiles; do
- if test "X$dlpremoduletest" = "X$lib"; then
- dlopenmodule="$dlpremoduletest"
- break
- fi
- done
- if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
- $ECHO
- if test "$linkmode" = prog; then
- $ECHO "*** Warning: Linking the executable $output against the loadable module"
- else
- $ECHO "*** Warning: Linking the shared library $output against the loadable module"
- fi
- $ECHO "*** $linklib is not portable!"
- fi
- if test "$linkmode" = lib &&
- test "$hardcode_into_libs" = yes; then
- # Hardcode the library path.
- # Skip directories that are in the system default run-time
- # search path.
- case " $sys_lib_dlsearch_path " in
- *" $absdir "*) ;;
- *)
- case "$compile_rpath " in
- *" $absdir "*) ;;
- *) compile_rpath="$compile_rpath $absdir"
- esac
- ;;
- esac
- case " $sys_lib_dlsearch_path " in
- *" $libdir "*) ;;
- *)
- case "$finalize_rpath " in
- *" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir"
- esac
- ;;
- esac
- fi
-
- if test -n "$old_archive_from_expsyms_cmds"; then
- # figure out the soname
- set dummy $library_names
- shift
- realname="$1"
- shift
- libname=`eval "\\$ECHO \"$libname_spec\""`
- # use dlname if we got it. it's perfectly good, no?
- if test -n "$dlname"; then
- soname="$dlname"
- elif test -n "$soname_spec"; then
- # bleh windows
- case $host in
- *cygwin* | mingw* | *cegcc*)
- func_arith $current - $age
- major=$func_arith_result
- versuffix="-$major"
- ;;
- esac
- eval soname=\"$soname_spec\"
- else
- soname="$realname"
- fi
-
- # Make a new name for the extract_expsyms_cmds to use
- soroot="$soname"
- func_basename "$soroot"
- soname="$func_basename_result"
- func_stripname 'lib' '.dll' "$soname"
- newlib=libimp-$func_stripname_result.a
-
- # If the library has no export list, then create one now
- if test -f "$output_objdir/$soname-def"; then :
- else
- func_verbose "extracting exported symbol list from \`$soname'"
- func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
- fi
-
- # Create $newlib
- if test -f "$output_objdir/$newlib"; then :; else
- func_verbose "generating import library for \`$soname'"
- func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
- fi
- # make sure the library variables are pointing to the new library
- dir=$output_objdir
- linklib=$newlib
- fi # test -n "$old_archive_from_expsyms_cmds"
-
- if test "$linkmode" = prog || test "$mode" != relink; then
- add_shlibpath=
- add_dir=
- add=
- lib_linked=yes
- case $hardcode_action in
- immediate | unsupported)
- if test "$hardcode_direct" = no; then
- add="$dir/$linklib"
- case $host in
- *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
- *-*-sysv4*uw2*) add_dir="-L$dir" ;;
- *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
- *-*-unixware7*) add_dir="-L$dir" ;;
- *-*-darwin* )
- # if the lib is a (non-dlopened) module then we can not
- # link against it, someone is ignoring the earlier warnings
- if /usr/bin/file -L $add 2> /dev/null |
- $GREP ": [^:]* bundle" >/dev/null ; then
- if test "X$dlopenmodule" != "X$lib"; then
- $ECHO "*** Warning: lib $linklib is a module, not a shared library"
- if test -z "$old_library" ; then
- $ECHO
- $ECHO "*** And there doesn't seem to be a static archive available"
- $ECHO "*** The link will probably fail, sorry"
- else
- add="$dir/$old_library"
- fi
- elif test -n "$old_library"; then
- add="$dir/$old_library"
- fi
- fi
- esac
- elif test "$hardcode_minus_L" = no; then
- case $host in
- *-*-sunos*) add_shlibpath="$dir" ;;
- esac
- add_dir="-L$dir"
- add="-l$name"
- elif test "$hardcode_shlibpath_var" = no; then
- add_shlibpath="$dir"
- add="-l$name"
- else
- lib_linked=no
- fi
- ;;
- relink)
- if test "$hardcode_direct" = yes &&
- test "$hardcode_direct_absolute" = no; then
- add="$dir/$linklib"
- elif test "$hardcode_minus_L" = yes; then
- add_dir="-L$dir"
- # Try looking first in the location we're being installed to.
- if test -n "$inst_prefix_dir"; then
- case $libdir in
- [\\/]*)
- add_dir="$add_dir -L$inst_prefix_dir$libdir"
- ;;
- esac
- fi
- add="-l$name"
- elif test "$hardcode_shlibpath_var" = yes; then
- add_shlibpath="$dir"
- add="-l$name"
- else
- lib_linked=no
- fi
- ;;
- *) lib_linked=no ;;
- esac
-
- if test "$lib_linked" != yes; then
- func_fatal_configuration "unsupported hardcode properties"
- fi
-
- if test -n "$add_shlibpath"; then
- case :$compile_shlibpath: in
- *":$add_shlibpath:"*) ;;
- *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
- esac
- fi
- if test "$linkmode" = prog; then
- test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
- test -n "$add" && compile_deplibs="$add $compile_deplibs"
- else
- test -n "$add_dir" && deplibs="$add_dir $deplibs"
- test -n "$add" && deplibs="$add $deplibs"
- if test "$hardcode_direct" != yes &&
- test "$hardcode_minus_L" != yes &&
- test "$hardcode_shlibpath_var" = yes; then
- case :$finalize_shlibpath: in
- *":$libdir:"*) ;;
- *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
- esac
- fi
- fi
- fi
-
- if test "$linkmode" = prog || test "$mode" = relink; then
- add_shlibpath=
- add_dir=
- add=
- # Finalize command for both is simple: just hardcode it.
- if test "$hardcode_direct" = yes &&
- test "$hardcode_direct_absolute" = no; then
- add="$libdir/$linklib"
- elif test "$hardcode_minus_L" = yes; then
- add_dir="-L$libdir"
- add="-l$name"
- elif test "$hardcode_shlibpath_var" = yes; then
- case :$finalize_shlibpath: in
- *":$libdir:"*) ;;
- *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
- esac
- add="-l$name"
- elif test "$hardcode_automatic" = yes; then
- if test -n "$inst_prefix_dir" &&
- test -f "$inst_prefix_dir$libdir/$linklib" ; then
- add="$inst_prefix_dir$libdir/$linklib"
- else
- add="$libdir/$linklib"
- fi
- else
- # We cannot seem to hardcode it, guess we'll fake it.
- add_dir="-L$libdir"
- # Try looking first in the location we're being installed to.
- if test -n "$inst_prefix_dir"; then
- case $libdir in
- [\\/]*)
- add_dir="$add_dir -L$inst_prefix_dir$libdir"
- ;;
- esac
- fi
- add="-l$name"
- fi
-
- if test "$linkmode" = prog; then
- test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
- test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
- else
- test -n "$add_dir" && deplibs="$add_dir $deplibs"
- test -n "$add" && deplibs="$add $deplibs"
- fi
- fi
- elif test "$linkmode" = prog; then
- # Here we assume that one of hardcode_direct or hardcode_minus_L
- # is not unsupported. This is valid on all known static and
- # shared platforms.
- if test "$hardcode_direct" != unsupported; then
- test -n "$old_library" && linklib="$old_library"
- compile_deplibs="$dir/$linklib $compile_deplibs"
- finalize_deplibs="$dir/$linklib $finalize_deplibs"
- else
- compile_deplibs="-l$name -L$dir $compile_deplibs"
- finalize_deplibs="-l$name -L$dir $finalize_deplibs"
- fi
- elif test "$build_libtool_libs" = yes; then
- # Not a shared library
- if test "$deplibs_check_method" != pass_all; then
- # We're trying link a shared library against a static one
- # but the system doesn't support it.
-
- # Just print a warning and add the library to dependency_libs so
- # that the program can be linked against the static library.
- $ECHO
- $ECHO "*** Warning: This system can not link to static lib archive $lib."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which you do not appear to have."
- if test "$module" = yes; then
- $ECHO "*** But as you try to build a module library, libtool will still create "
- $ECHO "*** a static module, that should work as long as the dlopening application"
- $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime."
- if test -z "$global_symbol_pipe"; then
- $ECHO
- $ECHO "*** However, this would only work if libtool was able to extract symbol"
- $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
- $ECHO "*** not find such a program. So, this module is probably useless."
- $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
- fi
- if test "$build_old_libs" = no; then
- build_libtool_libs=module
- build_old_libs=yes
- else
- build_libtool_libs=no
- fi
- fi
- else
- deplibs="$dir/$old_library $deplibs"
- link_static=yes
- fi
- fi # link shared/static library?
-
- if test "$linkmode" = lib; then
- if test -n "$dependency_libs" &&
- { test "$hardcode_into_libs" != yes ||
- test "$build_old_libs" = yes ||
- test "$link_static" = yes; }; then
- # Extract -R from dependency_libs
- temp_deplibs=
- for libdir in $dependency_libs; do
- case $libdir in
- -R*) func_stripname '-R' '' "$libdir"
- temp_xrpath=$func_stripname_result
- case " $xrpath " in
- *" $temp_xrpath "*) ;;
- *) xrpath="$xrpath $temp_xrpath";;
- esac;;
- *) temp_deplibs="$temp_deplibs $libdir";;
- esac
- done
- dependency_libs="$temp_deplibs"
- fi
-
- newlib_search_path="$newlib_search_path $absdir"
- # Link against this library
- test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
- # ... and its dependency_libs
- tmp_libs=
- for deplib in $dependency_libs; do
- newdependency_libs="$deplib $newdependency_libs"
- if $opt_duplicate_deps ; then
- case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
- fi
- tmp_libs="$tmp_libs $deplib"
- done
-
- if test "$link_all_deplibs" != no; then
- # Add the search paths of all dependency libraries
- for deplib in $dependency_libs; do
- path=
- case $deplib in
- -L*) path="$deplib" ;;
- *.la)
- func_dirname "$deplib" "" "."
- dir="$func_dirname_result"
- # We need an absolute path.
- case $dir in
- [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
- *)
- absdir=`cd "$dir" && pwd`
- if test -z "$absdir"; then
- func_warning "cannot determine absolute directory name of \`$dir'"
- absdir="$dir"
- fi
- ;;
- esac
- if $GREP "^installed=no" $deplib > /dev/null; then
- case $host in
- *-*-darwin*)
- depdepl=
- eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
- if test -n "$deplibrary_names" ; then
- for tmp in $deplibrary_names ; do
- depdepl=$tmp
- done
- if test -f "$absdir/$objdir/$depdepl" ; then
- depdepl="$absdir/$objdir/$depdepl"
- darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
- if test -z "$darwin_install_name"; then
- darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
- fi
- compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
- linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
- path=
- fi
- fi
- ;;
- *)
- path="-L$absdir/$objdir"
- ;;
- esac
- else
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
- test -z "$libdir" && \
- func_fatal_error "\`$deplib' is not a valid libtool archive"
- test "$absdir" != "$libdir" && \
- func_warning "\`$deplib' seems to be moved"
-
- path="-L$absdir"
- fi
- ;;
- esac
- case " $deplibs " in
- *" $path "*) ;;
- *) deplibs="$path $deplibs" ;;
- esac
- done
- fi # link_all_deplibs != no
- fi # linkmode = lib
- done # for deplib in $libs
- if test "$pass" = link; then
- if test "$linkmode" = "prog"; then
- compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
- finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
- else
- compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
- fi
- fi
- dependency_libs="$newdependency_libs"
- if test "$pass" = dlpreopen; then
- # Link the dlpreopened libraries before other libraries
- for deplib in $save_deplibs; do
- deplibs="$deplib $deplibs"
- done
- fi
- if test "$pass" != dlopen; then
- if test "$pass" != conv; then
- # Make sure lib_search_path contains only unique directories.
- lib_search_path=
- for dir in $newlib_search_path; do
- case "$lib_search_path " in
- *" $dir "*) ;;
- *) lib_search_path="$lib_search_path $dir" ;;
- esac
- done
- newlib_search_path=
- fi
-
- if test "$linkmode,$pass" != "prog,link"; then
- vars="deplibs"
- else
- vars="compile_deplibs finalize_deplibs"
- fi
- for var in $vars dependency_libs; do
- # Add libraries to $var in reverse order
- eval tmp_libs=\"\$$var\"
- new_libs=
- for deplib in $tmp_libs; do
- # FIXME: Pedantically, this is the right thing to do, so
- # that some nasty dependency loop isn't accidentally
- # broken:
- #new_libs="$deplib $new_libs"
- # Pragmatically, this seems to cause very few problems in
- # practice:
- case $deplib in
- -L*) new_libs="$deplib $new_libs" ;;
- -R*) ;;
- *)
- # And here is the reason: when a library appears more
- # than once as an explicit dependence of a library, or
- # is implicitly linked in more than once by the
- # compiler, it is considered special, and multiple
- # occurrences thereof are not removed. Compare this
- # with having the same library being listed as a
- # dependency of multiple other libraries: in this case,
- # we know (pedantically, we assume) the library does not
- # need to be listed more than once, so we keep only the
- # last copy. This is not always right, but it is rare
- # enough that we require users that really mean to play
- # such unportable linking tricks to link the library
- # using -Wl,-lname, so that libtool does not consider it
- # for duplicate removal.
- case " $specialdeplibs " in
- *" $deplib "*) new_libs="$deplib $new_libs" ;;
- *)
- case " $new_libs " in
- *" $deplib "*) ;;
- *) new_libs="$deplib $new_libs" ;;
- esac
- ;;
- esac
- ;;
- esac
- done
- tmp_libs=
- for deplib in $new_libs; do
- case $deplib in
- -L*)
- case " $tmp_libs " in
- *" $deplib "*) ;;
- *) tmp_libs="$tmp_libs $deplib" ;;
- esac
- ;;
- *) tmp_libs="$tmp_libs $deplib" ;;
- esac
- done
- eval $var=\"$tmp_libs\"
- done # for var
- fi
- # Last step: remove runtime libs from dependency_libs
- # (they stay in deplibs)
- tmp_libs=
- for i in $dependency_libs ; do
- case " $predeps $postdeps $compiler_lib_search_path " in
- *" $i "*)
- i=""
- ;;
- esac
- if test -n "$i" ; then
- tmp_libs="$tmp_libs $i"
- fi
- done
- dependency_libs=$tmp_libs
- done # for pass
- if test "$linkmode" = prog; then
- dlfiles="$newdlfiles"
- fi
- if test "$linkmode" = prog || test "$linkmode" = lib; then
- dlprefiles="$newdlprefiles"
- fi
-
- case $linkmode in
- oldlib)
- if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
- func_warning "\`-dlopen' is ignored for archives"
- fi
-
- case " $deplibs" in
- *\ -l* | *\ -L*)
- func_warning "\`-l' and \`-L' are ignored for archives" ;;
- esac
-
- test -n "$rpath" && \
- func_warning "\`-rpath' is ignored for archives"
-
- test -n "$xrpath" && \
- func_warning "\`-R' is ignored for archives"
-
- test -n "$vinfo" && \
- func_warning "\`-version-info/-version-number' is ignored for archives"
-
- test -n "$release" && \
- func_warning "\`-release' is ignored for archives"
-
- test -n "$export_symbols$export_symbols_regex" && \
- func_warning "\`-export-symbols' is ignored for archives"
-
- # Now set the variables for building old libraries.
- build_libtool_libs=no
- oldlibs="$output"
- objs="$objs$old_deplibs"
- ;;
-
- lib)
- # Make sure we only generate libraries of the form `libNAME.la'.
- case $outputname in
- lib*)
- func_stripname 'lib' '.la' "$outputname"
- name=$func_stripname_result
- eval shared_ext=\"$shrext_cmds\"
- eval libname=\"$libname_spec\"
- ;;
- *)
- test "$module" = no && \
- func_fatal_help "libtool library \`$output' must begin with \`lib'"
-
- if test "$need_lib_prefix" != no; then
- # Add the "lib" prefix for modules if required
- func_stripname '' '.la' "$outputname"
- name=$func_stripname_result
- eval shared_ext=\"$shrext_cmds\"
- eval libname=\"$libname_spec\"
- else
- func_stripname '' '.la' "$outputname"
- libname=$func_stripname_result
- fi
- ;;
- esac
-
- if test -n "$objs"; then
- if test "$deplibs_check_method" != pass_all; then
- func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
- else
- $ECHO
- $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
- $ECHO "*** objects $objs is not portable!"
- libobjs="$libobjs $objs"
- fi
- fi
-
- test "$dlself" != no && \
- func_warning "\`-dlopen self' is ignored for libtool libraries"
-
- set dummy $rpath
- shift
- test "$#" -gt 1 && \
- func_warning "ignoring multiple \`-rpath's for a libtool library"
-
- install_libdir="$1"
-
- oldlibs=
- if test -z "$rpath"; then
- if test "$build_libtool_libs" = yes; then
- # Building a libtool convenience library.
- # Some compilers have problems with a `.al' extension so
- # convenience libraries should have the same extension an
- # archive normally would.
- oldlibs="$output_objdir/$libname.$libext $oldlibs"
- build_libtool_libs=convenience
- build_old_libs=yes
- fi
-
- test -n "$vinfo" && \
- func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
-
- test -n "$release" && \
- func_warning "\`-release' is ignored for convenience libraries"
- else
-
- # Parse the version information argument.
- save_ifs="$IFS"; IFS=':'
- set dummy $vinfo 0 0 0
- shift
- IFS="$save_ifs"
-
- test -n "$7" && \
- func_fatal_help "too many parameters to \`-version-info'"
-
- # convert absolute version numbers to libtool ages
- # this retains compatibility with .la files and attempts
- # to make the code below a bit more comprehensible
-
- case $vinfo_number in
- yes)
- number_major="$1"
- number_minor="$2"
- number_revision="$3"
- #
- # There are really only two kinds -- those that
- # use the current revision as the major version
- # and those that subtract age and use age as
- # a minor version. But, then there is irix
- # which has an extra 1 added just for fun
- #
- case $version_type in
- darwin|linux|osf|windows|none)
- func_arith $number_major + $number_minor
- current=$func_arith_result
- age="$number_minor"
- revision="$number_revision"
- ;;
- freebsd-aout|freebsd-elf|sunos)
- current="$number_major"
- revision="$number_minor"
- age="0"
- ;;
- irix|nonstopux)
- func_arith $number_major + $number_minor
- current=$func_arith_result
- age="$number_minor"
- revision="$number_minor"
- lt_irix_increment=no
- ;;
- *)
- func_fatal_configuration "$modename: unknown library version type \`$version_type'"
- ;;
- esac
- ;;
- no)
- current="$1"
- revision="$2"
- age="$3"
- ;;
- esac
-
- # Check that each of the things are valid numbers.
- case $current in
- 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
- *)
- func_error "CURRENT \`$current' must be a nonnegative integer"
- func_fatal_error "\`$vinfo' is not valid version information"
- ;;
- esac
-
- case $revision in
- 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
- *)
- func_error "REVISION \`$revision' must be a nonnegative integer"
- func_fatal_error "\`$vinfo' is not valid version information"
- ;;
- esac
-
- case $age in
- 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
- *)
- func_error "AGE \`$age' must be a nonnegative integer"
- func_fatal_error "\`$vinfo' is not valid version information"
- ;;
- esac
-
- if test "$age" -gt "$current"; then
- func_error "AGE \`$age' is greater than the current interface number \`$current'"
- func_fatal_error "\`$vinfo' is not valid version information"
- fi
-
- # Calculate the version variables.
- major=
- versuffix=
- verstring=
- case $version_type in
- none) ;;
-
- darwin)
- # Like Linux, but with the current version available in
- # verstring for coding it into the library header
- func_arith $current - $age
- major=.$func_arith_result
- versuffix="$major.$age.$revision"
- # Darwin ld doesn't like 0 for these options...
- func_arith $current + 1
- minor_current=$func_arith_result
- xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
- verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
- ;;
-
- freebsd-aout)
- major=".$current"
- versuffix=".$current.$revision";
- ;;
-
- freebsd-elf)
- major=".$current"
- versuffix=".$current"
- ;;
-
- irix | nonstopux)
- if test "X$lt_irix_increment" = "Xno"; then
- func_arith $current - $age
- else
- func_arith $current - $age + 1
- fi
- major=$func_arith_result
-
- case $version_type in
- nonstopux) verstring_prefix=nonstopux ;;
- *) verstring_prefix=sgi ;;
- esac
- verstring="$verstring_prefix$major.$revision"
-
- # Add in all the interfaces that we are compatible with.
- loop=$revision
- while test "$loop" -ne 0; do
- func_arith $revision - $loop
- iface=$func_arith_result
- func_arith $loop - 1
- loop=$func_arith_result
- verstring="$verstring_prefix$major.$iface:$verstring"
- done
-
- # Before this point, $major must not contain `.'.
- major=.$major
- versuffix="$major.$revision"
- ;;
-
- linux)
- func_arith $current - $age
- major=.$func_arith_result
- versuffix="$major.$age.$revision"
- ;;
-
- osf)
- func_arith $current - $age
- major=.$func_arith_result
- versuffix=".$current.$age.$revision"
- verstring="$current.$age.$revision"
-
- # Add in all the interfaces that we are compatible with.
- loop=$age
- while test "$loop" -ne 0; do
- func_arith $current - $loop
- iface=$func_arith_result
- func_arith $loop - 1
- loop=$func_arith_result
- verstring="$verstring:${iface}.0"
- done
-
- # Make executables depend on our current version.
- verstring="$verstring:${current}.0"
- ;;
-
- qnx)
- major=".$current"
- versuffix=".$current"
- ;;
-
- sunos)
- major=".$current"
- versuffix=".$current.$revision"
- ;;
-
- windows)
- # Use '-' rather than '.', since we only want one
- # extension on DOS 8.3 filesystems.
- func_arith $current - $age
- major=$func_arith_result
- versuffix="-$major"
- ;;
-
- *)
- func_fatal_configuration "unknown library version type \`$version_type'"
- ;;
- esac
-
- # Clear the version info if we defaulted, and they specified a release.
- if test -z "$vinfo" && test -n "$release"; then
- major=
- case $version_type in
- darwin)
- # we can't check for "0.0" in archive_cmds due to quoting
- # problems, so we reset it completely
- verstring=
- ;;
- *)
- verstring="0.0"
- ;;
- esac
- if test "$need_version" = no; then
- versuffix=
- else
- versuffix=".0.0"
- fi
- fi
-
- # Remove version info from name if versioning should be avoided
- if test "$avoid_version" = yes && test "$need_version" = no; then
- major=
- versuffix=
- verstring=""
- fi
-
- # Check to see if the archive will have undefined symbols.
- if test "$allow_undefined" = yes; then
- if test "$allow_undefined_flag" = unsupported; then
- func_warning "undefined symbols not allowed in $host shared libraries"
- build_libtool_libs=no
- build_old_libs=yes
- fi
- else
- # Don't allow undefined symbols.
- allow_undefined_flag="$no_undefined_flag"
- fi
-
- fi
-
- func_generate_dlsyms "$libname" "$libname" "yes"
- libobjs="$libobjs $symfileobj"
- test "X$libobjs" = "X " && libobjs=
-
- if test "$mode" != relink; then
- # Remove our outputs, but don't remove object files since they
- # may have been created when compiling PIC objects.
- removelist=
- tempremovelist=`$ECHO "$output_objdir/*"`
- for p in $tempremovelist; do
- case $p in
- *.$objext | *.gcno)
- ;;
- $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
- if test "X$precious_files_regex" != "X"; then
- if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
- then
- continue
- fi
- fi
- removelist="$removelist $p"
- ;;
- *) ;;
- esac
- done
- test -n "$removelist" && \
- func_show_eval "${RM}r \$removelist"
- fi
-
- # Now set the variables for building old libraries.
- if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
- oldlibs="$oldlibs $output_objdir/$libname.$libext"
-
- # Transform .lo files to .o files.
- oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
- fi
-
- # Eliminate all temporary directories.
- #for path in $notinst_path; do
- # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"`
- # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"`
- # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"`
- #done
-
- if test -n "$xrpath"; then
- # If the user specified any rpath flags, then add them.
- temp_xrpath=
- for libdir in $xrpath; do
- temp_xrpath="$temp_xrpath -R$libdir"
- case "$finalize_rpath " in
- *" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir" ;;
- esac
- done
- if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
- dependency_libs="$temp_xrpath $dependency_libs"
- fi
- fi
-
- # Make sure dlfiles contains only unique files that won't be dlpreopened
- old_dlfiles="$dlfiles"
- dlfiles=
- for lib in $old_dlfiles; do
- case " $dlprefiles $dlfiles " in
- *" $lib "*) ;;
- *) dlfiles="$dlfiles $lib" ;;
- esac
- done
-
- # Make sure dlprefiles contains only unique files
- old_dlprefiles="$dlprefiles"
- dlprefiles=
- for lib in $old_dlprefiles; do
- case "$dlprefiles " in
- *" $lib "*) ;;
- *) dlprefiles="$dlprefiles $lib" ;;
- esac
- done
-
- if test "$build_libtool_libs" = yes; then
- if test -n "$rpath"; then
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)
- # these systems don't actually have a c library (as such)!
- ;;
- *-*-rhapsody* | *-*-darwin1.[012])
- # Rhapsody C library is in the System framework
- deplibs="$deplibs System.ltframework"
- ;;
- *-*-netbsd*)
- # Don't link with libc until the a.out ld.so is fixed.
- ;;
- *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
- # Do not include libc due to us having libc/libc_r.
- ;;
- *-*-sco3.2v5* | *-*-sco5v6*)
- # Causes problems with __ctype
- ;;
- *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
- # Compiler inserts libc in the correct place for threads to work
- ;;
- *)
- # Add libc to deplibs on all other systems if necessary.
- if test "$build_libtool_need_lc" = "yes"; then
- deplibs="$deplibs -lc"
- fi
- ;;
- esac
- fi
-
- # Transform deplibs into only deplibs that can be linked in shared.
- name_save=$name
- libname_save=$libname
- release_save=$release
- versuffix_save=$versuffix
- major_save=$major
- # I'm not sure if I'm treating the release correctly. I think
- # release should show up in the -l (ie -lgmp5) so we don't want to
- # add it in twice. Is that correct?
- release=""
- versuffix=""
- major=""
- newdeplibs=
- droppeddeps=no
- case $deplibs_check_method in
- pass_all)
- # Don't check for shared/static. Everything works.
- # This might be a little naive. We might want to check
- # whether the library exists or not. But this is on
- # osf3 & osf4 and I'm not really sure... Just
- # implementing what was already the behavior.
- newdeplibs=$deplibs
- ;;
- test_compile)
- # This code stresses the "libraries are programs" paradigm to its
- # limits. Maybe even breaks it. We compile a program, linking it
- # against the deplibs as a proxy for the library. Then we can check
- # whether they linked in statically or dynamically with ldd.
- $opt_dry_run || $RM conftest.c
- cat > conftest.c <<EOF
- int main() { return 0; }
-EOF
- $opt_dry_run || $RM conftest
- if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
- ldd_output=`ldd conftest`
- for i in $deplibs; do
- case $i in
- -l*)
- func_stripname -l '' "$i"
- name=$func_stripname_result
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- case " $predeps $postdeps " in
- *" $i "*)
- newdeplibs="$newdeplibs $i"
- i=""
- ;;
- esac
- fi
- if test -n "$i" ; then
- libname=`eval "\\$ECHO \"$libname_spec\""`
- deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
- set dummy $deplib_matches; shift
- deplib_match=$1
- if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
- newdeplibs="$newdeplibs $i"
- else
- droppeddeps=yes
- $ECHO
- $ECHO "*** Warning: dynamic linker does not accept needed library $i."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which I believe you do not have"
- $ECHO "*** because a test_compile did reveal that the linker did not use it for"
- $ECHO "*** its dynamic dependency list that programs get resolved with at runtime."
- fi
- fi
- ;;
- *)
- newdeplibs="$newdeplibs $i"
- ;;
- esac
- done
- else
- # Error occurred in the first compile. Let's try to salvage
- # the situation: Compile a separate program for each library.
- for i in $deplibs; do
- case $i in
- -l*)
- func_stripname -l '' "$i"
- name=$func_stripname_result
- $opt_dry_run || $RM conftest
- if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
- ldd_output=`ldd conftest`
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- case " $predeps $postdeps " in
- *" $i "*)
- newdeplibs="$newdeplibs $i"
- i=""
- ;;
- esac
- fi
- if test -n "$i" ; then
- libname=`eval "\\$ECHO \"$libname_spec\""`
- deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
- set dummy $deplib_matches; shift
- deplib_match=$1
- if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
- newdeplibs="$newdeplibs $i"
- else
- droppeddeps=yes
- $ECHO
- $ECHO "*** Warning: dynamic linker does not accept needed library $i."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which you do not appear to have"
- $ECHO "*** because a test_compile did reveal that the linker did not use this one"
- $ECHO "*** as a dynamic dependency that programs can get resolved with at runtime."
- fi
- fi
- else
- droppeddeps=yes
- $ECHO
- $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
- $ECHO "*** make it link in! You will probably need to install it or some"
- $ECHO "*** library that it depends on before this library will be fully"
- $ECHO "*** functional. Installing it before continuing would be even better."
- fi
- ;;
- *)
- newdeplibs="$newdeplibs $i"
- ;;
- esac
- done
- fi
- ;;
- file_magic*)
- set dummy $deplibs_check_method; shift
- file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
- for a_deplib in $deplibs; do
- case $a_deplib in
- -l*)
- func_stripname -l '' "$a_deplib"
- name=$func_stripname_result
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- case " $predeps $postdeps " in
- *" $a_deplib "*)
- newdeplibs="$newdeplibs $a_deplib"
- a_deplib=""
- ;;
- esac
- fi
- if test -n "$a_deplib" ; then
- libname=`eval "\\$ECHO \"$libname_spec\""`
- for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
- potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
- for potent_lib in $potential_libs; do
- # Follow soft links.
- if ls -lLd "$potent_lib" 2>/dev/null |
- $GREP " -> " >/dev/null; then
- continue
- fi
- # The statement above tries to avoid entering an
- # endless loop below, in case of cyclic links.
- # We might still enter an endless loop, since a link
- # loop can be closed while we follow links,
- # but so what?
- potlib="$potent_lib"
- while test -h "$potlib" 2>/dev/null; do
- potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
- case $potliblink in
- [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
- *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
- esac
- done
- if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
- $SED -e 10q |
- $EGREP "$file_magic_regex" > /dev/null; then
- newdeplibs="$newdeplibs $a_deplib"
- a_deplib=""
- break 2
- fi
- done
- done
- fi
- if test -n "$a_deplib" ; then
- droppeddeps=yes
- $ECHO
- $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which you do not appear to have"
- $ECHO "*** because I did check the linker path looking for a file starting"
- if test -z "$potlib" ; then
- $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
- else
- $ECHO "*** with $libname and none of the candidates passed a file format test"
- $ECHO "*** using a file magic. Last file checked: $potlib"
- fi
- fi
- ;;
- *)
- # Add a -L argument.
- newdeplibs="$newdeplibs $a_deplib"
- ;;
- esac
- done # Gone through all deplibs.
- ;;
- match_pattern*)
- set dummy $deplibs_check_method; shift
- match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
- for a_deplib in $deplibs; do
- case $a_deplib in
- -l*)
- func_stripname -l '' "$a_deplib"
- name=$func_stripname_result
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- case " $predeps $postdeps " in
- *" $a_deplib "*)
- newdeplibs="$newdeplibs $a_deplib"
- a_deplib=""
- ;;
- esac
- fi
- if test -n "$a_deplib" ; then
- libname=`eval "\\$ECHO \"$libname_spec\""`
- for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
- potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
- for potent_lib in $potential_libs; do
- potlib="$potent_lib" # see symlink-check above in file_magic test
- if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \
- $EGREP "$match_pattern_regex" > /dev/null; then
- newdeplibs="$newdeplibs $a_deplib"
- a_deplib=""
- break 2
- fi
- done
- done
- fi
- if test -n "$a_deplib" ; then
- droppeddeps=yes
- $ECHO
- $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which you do not appear to have"
- $ECHO "*** because I did check the linker path looking for a file starting"
- if test -z "$potlib" ; then
- $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
- else
- $ECHO "*** with $libname and none of the candidates passed a file format test"
- $ECHO "*** using a regex pattern. Last file checked: $potlib"
- fi
- fi
- ;;
- *)
- # Add a -L argument.
- newdeplibs="$newdeplibs $a_deplib"
- ;;
- esac
- done # Gone through all deplibs.
- ;;
- none | unknown | *)
- newdeplibs=""
- tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \
- -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- for i in $predeps $postdeps ; do
- # can't use Xsed below, because $i might contain '/'
- tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"`
- done
- fi
- if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' |
- $GREP . >/dev/null; then
- $ECHO
- if test "X$deplibs_check_method" = "Xnone"; then
- $ECHO "*** Warning: inter-library dependencies are not supported in this platform."
- else
- $ECHO "*** Warning: inter-library dependencies are not known to be supported."
- fi
- $ECHO "*** All declared inter-library dependencies are being dropped."
- droppeddeps=yes
- fi
- ;;
- esac
- versuffix=$versuffix_save
- major=$major_save
- release=$release_save
- libname=$libname_save
- name=$name_save
-
- case $host in
- *-*-rhapsody* | *-*-darwin1.[012])
- # On Rhapsody replace the C library with the System framework
- newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
- ;;
- esac
-
- if test "$droppeddeps" = yes; then
- if test "$module" = yes; then
- $ECHO
- $ECHO "*** Warning: libtool could not satisfy all declared inter-library"
- $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
- $ECHO "*** a static module, that should work as long as the dlopening"
- $ECHO "*** application is linked with the -dlopen flag."
- if test -z "$global_symbol_pipe"; then
- $ECHO
- $ECHO "*** However, this would only work if libtool was able to extract symbol"
- $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
- $ECHO "*** not find such a program. So, this module is probably useless."
- $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
- fi
- if test "$build_old_libs" = no; then
- oldlibs="$output_objdir/$libname.$libext"
- build_libtool_libs=module
- build_old_libs=yes
- else
- build_libtool_libs=no
- fi
- else
- $ECHO "*** The inter-library dependencies that have been dropped here will be"
- $ECHO "*** automatically added whenever a program is linked with this library"
- $ECHO "*** or is declared to -dlopen it."
-
- if test "$allow_undefined" = no; then
- $ECHO
- $ECHO "*** Since this library must not contain undefined symbols,"
- $ECHO "*** because either the platform does not support them or"
- $ECHO "*** it was explicitly requested with -no-undefined,"
- $ECHO "*** libtool will only create a static version of it."
- if test "$build_old_libs" = no; then
- oldlibs="$output_objdir/$libname.$libext"
- build_libtool_libs=module
- build_old_libs=yes
- else
- build_libtool_libs=no
- fi
- fi
- fi
- fi
- # Done checking deplibs!
- deplibs=$newdeplibs
- fi
- # Time to change all our "foo.ltframework" stuff back to "-framework foo"
- case $host in
- *-*-darwin*)
- newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
- new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
- deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
- ;;
- esac
-
- # move library search paths that coincide with paths to not yet
- # installed libraries to the beginning of the library search list
- new_libs=
- for path in $notinst_path; do
- case " $new_libs " in
- *" -L$path/$objdir "*) ;;
- *)
- case " $deplibs " in
- *" -L$path/$objdir "*)
- new_libs="$new_libs -L$path/$objdir" ;;
- esac
- ;;
- esac
- done
- for deplib in $deplibs; do
- case $deplib in
- -L*)
- case " $new_libs " in
- *" $deplib "*) ;;
- *) new_libs="$new_libs $deplib" ;;
- esac
- ;;
- *) new_libs="$new_libs $deplib" ;;
- esac
- done
- deplibs="$new_libs"
-
- # All the library-specific variables (install_libdir is set above).
- library_names=
- old_library=
- dlname=
-
- # Test again, we may have decided not to build it any more
- if test "$build_libtool_libs" = yes; then
- if test "$hardcode_into_libs" = yes; then
- # Hardcode the library paths
- hardcode_libdirs=
- dep_rpath=
- rpath="$finalize_rpath"
- test "$mode" != relink && rpath="$compile_rpath$rpath"
- for libdir in $rpath; do
- if test -n "$hardcode_libdir_flag_spec"; then
- if test -n "$hardcode_libdir_separator"; then
- if test -z "$hardcode_libdirs"; then
- hardcode_libdirs="$libdir"
- else
- # Just accumulate the unique libdirs.
- case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
- *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
- ;;
- *)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
- ;;
- esac
- fi
- else
- eval flag=\"$hardcode_libdir_flag_spec\"
- dep_rpath="$dep_rpath $flag"
- fi
- elif test -n "$runpath_var"; then
- case "$perm_rpath " in
- *" $libdir "*) ;;
- *) perm_rpath="$perm_rpath $libdir" ;;
- esac
- fi
- done
- # Substitute the hardcoded libdirs into the rpath.
- if test -n "$hardcode_libdir_separator" &&
- test -n "$hardcode_libdirs"; then
- libdir="$hardcode_libdirs"
- if test -n "$hardcode_libdir_flag_spec_ld"; then
- eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
- else
- eval dep_rpath=\"$hardcode_libdir_flag_spec\"
- fi
- fi
- if test -n "$runpath_var" && test -n "$perm_rpath"; then
- # We should set the runpath_var.
- rpath=
- for dir in $perm_rpath; do
- rpath="$rpath$dir:"
- done
- eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
- fi
- test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
- fi
-
- shlibpath="$finalize_shlibpath"
- test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
- if test -n "$shlibpath"; then
- eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
- fi
-
- # Get the real and link names of the library.
- eval shared_ext=\"$shrext_cmds\"
- eval library_names=\"$library_names_spec\"
- set dummy $library_names
- shift
- realname="$1"
- shift
-
- if test -n "$soname_spec"; then
- eval soname=\"$soname_spec\"
- else
- soname="$realname"
- fi
- if test -z "$dlname"; then
- dlname=$soname
- fi
-
- lib="$output_objdir/$realname"
- linknames=
- for link
- do
- linknames="$linknames $link"
- done
-
- # Use standard objects if they are pic
- test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
- test "X$libobjs" = "X " && libobjs=
-
- delfiles=
- if test -n "$export_symbols" && test -n "$include_expsyms"; then
- $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
- export_symbols="$output_objdir/$libname.uexp"
- delfiles="$delfiles $export_symbols"
- fi
-
- orig_export_symbols=
- case $host_os in
- cygwin* | mingw* | cegcc*)
- if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
- # exporting using user supplied symfile
- if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
- # and it's NOT already a .def file. Must figure out
- # which of the given symbols are data symbols and tag
- # them as such. So, trigger use of export_symbols_cmds.
- # export_symbols gets reassigned inside the "prepare
- # the list of exported symbols" if statement, so the
- # include_expsyms logic still works.
- orig_export_symbols="$export_symbols"
- export_symbols=
- always_export_symbols=yes
- fi
- fi
- ;;
- esac
-
- # Prepare the list of exported symbols
- if test -z "$export_symbols"; then
- if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
- func_verbose "generating symbol list for \`$libname.la'"
- export_symbols="$output_objdir/$libname.exp"
- $opt_dry_run || $RM $export_symbols
- cmds=$export_symbols_cmds
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- func_len " $cmd"
- len=$func_len_result
- if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
- func_show_eval "$cmd" 'exit $?'
- skipped_export=false
- else
- # The command line is too long to execute in one step.
- func_verbose "using reloadable object file for export list..."
- skipped_export=:
- # Break out early, otherwise skipped_export may be
- # set to false by a later but shorter cmd.
- break
- fi
- done
- IFS="$save_ifs"
- if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
- func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
- func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
- fi
- fi
- fi
-
- if test -n "$export_symbols" && test -n "$include_expsyms"; then
- tmp_export_symbols="$export_symbols"
- test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
- $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
- fi
-
- if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
- # The given exports_symbols file has to be filtered, so filter it.
- func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
- # FIXME: $output_objdir/$libname.filter potentially contains lots of
- # 's' commands which not all seds can handle. GNU sed should be fine
- # though. Also, the filter scales superlinearly with the number of
- # global variables. join(1) would be nice here, but unfortunately
- # isn't a blessed tool.
- $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
- delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
- export_symbols=$output_objdir/$libname.def
- $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
- fi
-
- tmp_deplibs=
- for test_deplib in $deplibs; do
- case " $convenience " in
- *" $test_deplib "*) ;;
- *)
- tmp_deplibs="$tmp_deplibs $test_deplib"
- ;;
- esac
- done
- deplibs="$tmp_deplibs"
-
- if test -n "$convenience"; then
- if test -n "$whole_archive_flag_spec" &&
- test "$compiler_needs_object" = yes &&
- test -z "$libobjs"; then
- # extract the archives, so we have objects to list.
- # TODO: could optimize this to just extract one archive.
- whole_archive_flag_spec=
- fi
- if test -n "$whole_archive_flag_spec"; then
- save_libobjs=$libobjs
- eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
- test "X$libobjs" = "X " && libobjs=
- else
- gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
-
- func_extract_archives $gentop $convenience
- libobjs="$libobjs $func_extract_archives_result"
- test "X$libobjs" = "X " && libobjs=
- fi
- fi
-
- if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
- eval flag=\"$thread_safe_flag_spec\"
- linker_flags="$linker_flags $flag"
- fi
-
- # Make a backup of the uninstalled library when relinking
- if test "$mode" = relink; then
- $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
- fi
-
- # Do each of the archive commands.
- if test "$module" = yes && test -n "$module_cmds" ; then
- if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
- eval test_cmds=\"$module_expsym_cmds\"
- cmds=$module_expsym_cmds
- else
- eval test_cmds=\"$module_cmds\"
- cmds=$module_cmds
- fi
- else
- if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
- eval test_cmds=\"$archive_expsym_cmds\"
- cmds=$archive_expsym_cmds
- else
- eval test_cmds=\"$archive_cmds\"
- cmds=$archive_cmds
- fi
- fi
-
- if test "X$skipped_export" != "X:" &&
- func_len " $test_cmds" &&
- len=$func_len_result &&
- test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
- :
- else
- # The command line is too long to link in one step, link piecewise
- # or, if using GNU ld and skipped_export is not :, use a linker
- # script.
-
- # Save the value of $output and $libobjs because we want to
- # use them later. If we have whole_archive_flag_spec, we
- # want to use save_libobjs as it was before
- # whole_archive_flag_spec was expanded, because we can't
- # assume the linker understands whole_archive_flag_spec.
- # This may have to be revisited, in case too many
- # convenience libraries get linked in and end up exceeding
- # the spec.
- if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
- save_libobjs=$libobjs
- fi
- save_output=$output
- output_la=`$ECHO "X$output" | $Xsed -e "$basename"`
-
- # Clear the reloadable object creation command queue and
- # initialize k to one.
- test_cmds=
- concat_cmds=
- objlist=
- last_robj=
- k=1
-
- if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
- output=${output_objdir}/${output_la}.lnkscript
- func_verbose "creating GNU ld script: $output"
- $ECHO 'INPUT (' > $output
- for obj in $save_libobjs
- do
- $ECHO "$obj" >> $output
- done
- $ECHO ')' >> $output
- delfiles="$delfiles $output"
- elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
- output=${output_objdir}/${output_la}.lnk
- func_verbose "creating linker input file list: $output"
- : > $output
- set x $save_libobjs
- shift
- firstobj=
- if test "$compiler_needs_object" = yes; then
- firstobj="$1 "
- shift
- fi
- for obj
- do
- $ECHO "$obj" >> $output
- done
- delfiles="$delfiles $output"
- output=$firstobj\"$file_list_spec$output\"
- else
- if test -n "$save_libobjs"; then
- func_verbose "creating reloadable object files..."
- output=$output_objdir/$output_la-${k}.$objext
- eval test_cmds=\"$reload_cmds\"
- func_len " $test_cmds"
- len0=$func_len_result
- len=$len0
-
- # Loop over the list of objects to be linked.
- for obj in $save_libobjs
- do
- func_len " $obj"
- func_arith $len + $func_len_result
- len=$func_arith_result
- if test "X$objlist" = X ||
- test "$len" -lt "$max_cmd_len"; then
- func_append objlist " $obj"
- else
- # The command $test_cmds is almost too long, add a
- # command to the queue.
- if test "$k" -eq 1 ; then
- # The first file doesn't have a previous command to add.
- eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
- else
- # All subsequent reloadable object files will link in
- # the last one created.
- eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
- fi
- last_robj=$output_objdir/$output_la-${k}.$objext
- func_arith $k + 1
- k=$func_arith_result
- output=$output_objdir/$output_la-${k}.$objext
- objlist=$obj
- func_len " $last_robj"
- func_arith $len0 + $func_len_result
- len=$func_arith_result
- fi
- done
- # Handle the remaining objects by creating one last
- # reloadable object file. All subsequent reloadable object
- # files will link in the last one created.
- test -z "$concat_cmds" || concat_cmds=$concat_cmds~
- eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
- if test -n "$last_robj"; then
- eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
- fi
- delfiles="$delfiles $output"
-
- else
- output=
- fi
-
- if ${skipped_export-false}; then
- func_verbose "generating symbol list for \`$libname.la'"
- export_symbols="$output_objdir/$libname.exp"
- $opt_dry_run || $RM $export_symbols
- libobjs=$output
- # Append the command to create the export file.
- test -z "$concat_cmds" || concat_cmds=$concat_cmds~
- eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
- if test -n "$last_robj"; then
- eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
- fi
- fi
-
- test -n "$save_libobjs" &&
- func_verbose "creating a temporary reloadable object file: $output"
-
- # Loop through the commands generated above and execute them.
- save_ifs="$IFS"; IFS='~'
- for cmd in $concat_cmds; do
- IFS="$save_ifs"
- $opt_silent || {
- func_quote_for_expand "$cmd"
- eval "func_echo $func_quote_for_expand_result"
- }
- $opt_dry_run || eval "$cmd" || {
- lt_exit=$?
-
- # Restore the uninstalled library and exit
- if test "$mode" = relink; then
- ( cd "$output_objdir" && \
- $RM "${realname}T" && \
- $MV "${realname}U" "$realname" )
- fi
-
- exit $lt_exit
- }
- done
- IFS="$save_ifs"
-
- if test -n "$export_symbols_regex" && ${skipped_export-false}; then
- func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
- func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
- fi
- fi
-
- if ${skipped_export-false}; then
- if test -n "$export_symbols" && test -n "$include_expsyms"; then
- tmp_export_symbols="$export_symbols"
- test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
- $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
- fi
-
- if test -n "$orig_export_symbols"; then
- # The given exports_symbols file has to be filtered, so filter it.
- func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
- # FIXME: $output_objdir/$libname.filter potentially contains lots of
- # 's' commands which not all seds can handle. GNU sed should be fine
- # though. Also, the filter scales superlinearly with the number of
- # global variables. join(1) would be nice here, but unfortunately
- # isn't a blessed tool.
- $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
- delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
- export_symbols=$output_objdir/$libname.def
- $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
- fi
- fi
-
- libobjs=$output
- # Restore the value of output.
- output=$save_output
-
- if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
- eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
- test "X$libobjs" = "X " && libobjs=
- fi
- # Expand the library linking commands again to reset the
- # value of $libobjs for piecewise linking.
-
- # Do each of the archive commands.
- if test "$module" = yes && test -n "$module_cmds" ; then
- if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
- cmds=$module_expsym_cmds
- else
- cmds=$module_cmds
- fi
- else
- if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
- cmds=$archive_expsym_cmds
- else
- cmds=$archive_cmds
- fi
- fi
- fi
-
- if test -n "$delfiles"; then
- # Append the command to remove temporary files to $cmds.
- eval cmds=\"\$cmds~\$RM $delfiles\"
- fi
-
- # Add any objects from preloaded convenience libraries
- if test -n "$dlprefiles"; then
- gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
-
- func_extract_archives $gentop $dlprefiles
- libobjs="$libobjs $func_extract_archives_result"
- test "X$libobjs" = "X " && libobjs=
- fi
-
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $opt_silent || {
- func_quote_for_expand "$cmd"
- eval "func_echo $func_quote_for_expand_result"
- }
- $opt_dry_run || eval "$cmd" || {
- lt_exit=$?
-
- # Restore the uninstalled library and exit
- if test "$mode" = relink; then
- ( cd "$output_objdir" && \
- $RM "${realname}T" && \
- $MV "${realname}U" "$realname" )
- fi
-
- exit $lt_exit
- }
- done
- IFS="$save_ifs"
-
- # Restore the uninstalled library and exit
- if test "$mode" = relink; then
- $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
-
- if test -n "$convenience"; then
- if test -z "$whole_archive_flag_spec"; then
- func_show_eval '${RM}r "$gentop"'
- fi
- fi
-
- exit $EXIT_SUCCESS
- fi
-
- # Create links to the real library.
- for linkname in $linknames; do
- if test "$realname" != "$linkname"; then
- func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
- fi
- done
-
- # If -module or -export-dynamic was specified, set the dlname.
- if test "$module" = yes || test "$export_dynamic" = yes; then
- # On all known operating systems, these are identical.
- dlname="$soname"
- fi
- fi
- ;;
-
- obj)
- if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
- func_warning "\`-dlopen' is ignored for objects"
- fi
-
- case " $deplibs" in
- *\ -l* | *\ -L*)
- func_warning "\`-l' and \`-L' are ignored for objects" ;;
- esac
-
- test -n "$rpath" && \
- func_warning "\`-rpath' is ignored for objects"
-
- test -n "$xrpath" && \
- func_warning "\`-R' is ignored for objects"
-
- test -n "$vinfo" && \
- func_warning "\`-version-info' is ignored for objects"
-
- test -n "$release" && \
- func_warning "\`-release' is ignored for objects"
-
- case $output in
- *.lo)
- test -n "$objs$old_deplibs" && \
- func_fatal_error "cannot build library object \`$output' from non-libtool objects"
-
- libobj=$output
- func_lo2o "$libobj"
- obj=$func_lo2o_result
- ;;
- *)
- libobj=
- obj="$output"
- ;;
- esac
-
- # Delete the old objects.
- $opt_dry_run || $RM $obj $libobj
-
- # Objects from convenience libraries. This assumes
- # single-version convenience libraries. Whenever we create
- # different ones for PIC/non-PIC, this we'll have to duplicate
- # the extraction.
- reload_conv_objs=
- gentop=
- # reload_cmds runs $LD directly, so let us get rid of
- # -Wl from whole_archive_flag_spec and hope we can get by with
- # turning comma into space..
- wl=
-
- if test -n "$convenience"; then
- if test -n "$whole_archive_flag_spec"; then
- eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
- reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
- else
- gentop="$output_objdir/${obj}x"
- generated="$generated $gentop"
-
- func_extract_archives $gentop $convenience
- reload_conv_objs="$reload_objs $func_extract_archives_result"
- fi
- fi
-
- # Create the old-style object.
- reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
-
- output="$obj"
- func_execute_cmds "$reload_cmds" 'exit $?'
-
- # Exit if we aren't doing a library object file.
- if test -z "$libobj"; then
- if test -n "$gentop"; then
- func_show_eval '${RM}r "$gentop"'
- fi
-
- exit $EXIT_SUCCESS
- fi
-
- if test "$build_libtool_libs" != yes; then
- if test -n "$gentop"; then
- func_show_eval '${RM}r "$gentop"'
- fi
-
- # Create an invalid libtool object if no PIC, so that we don't
- # accidentally link it into a program.
- # $show "echo timestamp > $libobj"
- # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
- exit $EXIT_SUCCESS
- fi
-
- if test -n "$pic_flag" || test "$pic_mode" != default; then
- # Only do commands if we really have different PIC objects.
- reload_objs="$libobjs $reload_conv_objs"
- output="$libobj"
- func_execute_cmds "$reload_cmds" 'exit $?'
- fi
-
- if test -n "$gentop"; then
- func_show_eval '${RM}r "$gentop"'
- fi
-
- exit $EXIT_SUCCESS
- ;;
-
- prog)
- case $host in
- *cygwin*) func_stripname '' '.exe' "$output"
- output=$func_stripname_result.exe;;
- esac
- test -n "$vinfo" && \
- func_warning "\`-version-info' is ignored for programs"
-
- test -n "$release" && \
- func_warning "\`-release' is ignored for programs"
-
- test "$preload" = yes \
- && test "$dlopen_support" = unknown \
- && test "$dlopen_self" = unknown \
- && test "$dlopen_self_static" = unknown && \
- func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
-
- case $host in
- *-*-rhapsody* | *-*-darwin1.[012])
- # On Rhapsody replace the C library is the System framework
- compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
- finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
- ;;
- esac
-
- case $host in
- *-*-darwin*)
- # Don't allow lazy linking, it breaks C++ global constructors
- # But is supposedly fixed on 10.4 or later (yay!).
- if test "$tagname" = CXX ; then
- case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
- 10.[0123])
- compile_command="$compile_command ${wl}-bind_at_load"
- finalize_command="$finalize_command ${wl}-bind_at_load"
- ;;
- esac
- fi
- # Time to change all our "foo.ltframework" stuff back to "-framework foo"
- compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
- finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
- ;;
- esac
-
-
- # move library search paths that coincide with paths to not yet
- # installed libraries to the beginning of the library search list
- new_libs=
- for path in $notinst_path; do
- case " $new_libs " in
- *" -L$path/$objdir "*) ;;
- *)
- case " $compile_deplibs " in
- *" -L$path/$objdir "*)
- new_libs="$new_libs -L$path/$objdir" ;;
- esac
- ;;
- esac
- done
- for deplib in $compile_deplibs; do
- case $deplib in
- -L*)
- case " $new_libs " in
- *" $deplib "*) ;;
- *) new_libs="$new_libs $deplib" ;;
- esac
- ;;
- *) new_libs="$new_libs $deplib" ;;
- esac
- done
- compile_deplibs="$new_libs"
-
-
- compile_command="$compile_command $compile_deplibs"
- finalize_command="$finalize_command $finalize_deplibs"
-
- if test -n "$rpath$xrpath"; then
- # If the user specified any rpath flags, then add them.
- for libdir in $rpath $xrpath; do
- # This is the magic to use -rpath.
- case "$finalize_rpath " in
- *" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir" ;;
- esac
- done
- fi
-
- # Now hardcode the library paths
- rpath=
- hardcode_libdirs=
- for libdir in $compile_rpath $finalize_rpath; do
- if test -n "$hardcode_libdir_flag_spec"; then
- if test -n "$hardcode_libdir_separator"; then
- if test -z "$hardcode_libdirs"; then
- hardcode_libdirs="$libdir"
- else
- # Just accumulate the unique libdirs.
- case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
- *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
- ;;
- *)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
- ;;
- esac
- fi
- else
- eval flag=\"$hardcode_libdir_flag_spec\"
- rpath="$rpath $flag"
- fi
- elif test -n "$runpath_var"; then
- case "$perm_rpath " in
- *" $libdir "*) ;;
- *) perm_rpath="$perm_rpath $libdir" ;;
- esac
- fi
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
- testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
- case :$dllsearchpath: in
- *":$libdir:"*) ;;
- ::) dllsearchpath=$libdir;;
- *) dllsearchpath="$dllsearchpath:$libdir";;
- esac
- case :$dllsearchpath: in
- *":$testbindir:"*) ;;
- ::) dllsearchpath=$testbindir;;
- *) dllsearchpath="$dllsearchpath:$testbindir";;
- esac
- ;;
- esac
- done
- # Substitute the hardcoded libdirs into the rpath.
- if test -n "$hardcode_libdir_separator" &&
- test -n "$hardcode_libdirs"; then
- libdir="$hardcode_libdirs"
- eval rpath=\" $hardcode_libdir_flag_spec\"
- fi
- compile_rpath="$rpath"
-
- rpath=
- hardcode_libdirs=
- for libdir in $finalize_rpath; do
- if test -n "$hardcode_libdir_flag_spec"; then
- if test -n "$hardcode_libdir_separator"; then
- if test -z "$hardcode_libdirs"; then
- hardcode_libdirs="$libdir"
- else
- # Just accumulate the unique libdirs.
- case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
- *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
- ;;
- *)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
- ;;
- esac
- fi
- else
- eval flag=\"$hardcode_libdir_flag_spec\"
- rpath="$rpath $flag"
- fi
- elif test -n "$runpath_var"; then
- case "$finalize_perm_rpath " in
- *" $libdir "*) ;;
- *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
- esac
- fi
- done
- # Substitute the hardcoded libdirs into the rpath.
- if test -n "$hardcode_libdir_separator" &&
- test -n "$hardcode_libdirs"; then
- libdir="$hardcode_libdirs"
- eval rpath=\" $hardcode_libdir_flag_spec\"
- fi
- finalize_rpath="$rpath"
-
- if test -n "$libobjs" && test "$build_old_libs" = yes; then
- # Transform all the library objects into standard objects.
- compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
- finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
- fi
-
- func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
-
- # template prelinking step
- if test -n "$prelink_cmds"; then
- func_execute_cmds "$prelink_cmds" 'exit $?'
- fi
-
- wrappers_required=yes
- case $host in
- *cygwin* | *mingw* )
- if test "$build_libtool_libs" != yes; then
- wrappers_required=no
- fi
- ;;
- *cegcc)
- # Disable wrappers for cegcc, we are cross compiling anyway.
- wrappers_required=no
- ;;
- *)
- if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
- wrappers_required=no
- fi
- ;;
- esac
- if test "$wrappers_required" = no; then
- # Replace the output file specification.
- compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
- link_command="$compile_command$compile_rpath"
-
- # We have no uninstalled library dependencies, so finalize right now.
- exit_status=0
- func_show_eval "$link_command" 'exit_status=$?'
-
- # Delete the generated files.
- if test -f "$output_objdir/${outputname}S.${objext}"; then
- func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
- fi
-
- exit $exit_status
- fi
-
- if test -n "$compile_shlibpath$finalize_shlibpath"; then
- compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
- fi
- if test -n "$finalize_shlibpath"; then
- finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
- fi
-
- compile_var=
- finalize_var=
- if test -n "$runpath_var"; then
- if test -n "$perm_rpath"; then
- # We should set the runpath_var.
- rpath=
- for dir in $perm_rpath; do
- rpath="$rpath$dir:"
- done
- compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
- fi
- if test -n "$finalize_perm_rpath"; then
- # We should set the runpath_var.
- rpath=
- for dir in $finalize_perm_rpath; do
- rpath="$rpath$dir:"
- done
- finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
- fi
- fi
-
- if test "$no_install" = yes; then
- # We don't need to create a wrapper script.
- link_command="$compile_var$compile_command$compile_rpath"
- # Replace the output file specification.
- link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
- # Delete the old output file.
- $opt_dry_run || $RM $output
- # Link the executable and exit
- func_show_eval "$link_command" 'exit $?'
- exit $EXIT_SUCCESS
- fi
-
- if test "$hardcode_action" = relink; then
- # Fast installation is not supported
- link_command="$compile_var$compile_command$compile_rpath"
- relink_command="$finalize_var$finalize_command$finalize_rpath"
-
- func_warning "this platform does not like uninstalled shared libraries"
- func_warning "\`$output' will be relinked during installation"
- else
- if test "$fast_install" != no; then
- link_command="$finalize_var$compile_command$finalize_rpath"
- if test "$fast_install" = yes; then
- relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
- else
- # fast_install is set to needless
- relink_command=
- fi
- else
- link_command="$compile_var$compile_command$compile_rpath"
- relink_command="$finalize_var$finalize_command$finalize_rpath"
- fi
- fi
-
- # Replace the output file specification.
- link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
-
- # Delete the old output files.
- $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
-
- func_show_eval "$link_command" 'exit $?'
-
- # Now create the wrapper script.
- func_verbose "creating $output"
-
- # Quote the relink command for shipping.
- if test -n "$relink_command"; then
- # Preserve any variables that may affect compiler behavior
- for var in $variables_saved_for_relink; do
- if eval test -z \"\${$var+set}\"; then
- relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
- elif eval var_value=\$$var; test -z "$var_value"; then
- relink_command="$var=; export $var; $relink_command"
- else
- func_quote_for_eval "$var_value"
- relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
- fi
- done
- relink_command="(cd `pwd`; $relink_command)"
- relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
- fi
-
- # Quote $ECHO for shipping.
- if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
- case $progpath in
- [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
- *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
- esac
- qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
- else
- qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
- fi
-
- # Only actually do things if not in dry run mode.
- $opt_dry_run || {
- # win32 will think the script is a binary if it has
- # a .exe suffix, so we strip it off here.
- case $output in
- *.exe) func_stripname '' '.exe' "$output"
- output=$func_stripname_result ;;
- esac
- # test for cygwin because mv fails w/o .exe extensions
- case $host in
- *cygwin*)
- exeext=.exe
- func_stripname '' '.exe' "$outputname"
- outputname=$func_stripname_result ;;
- *) exeext= ;;
- esac
- case $host in
- *cygwin* | *mingw* )
- func_dirname_and_basename "$output" "" "."
- output_name=$func_basename_result
- output_path=$func_dirname_result
- cwrappersource="$output_path/$objdir/lt-$output_name.c"
- cwrapper="$output_path/$output_name.exe"
- $RM $cwrappersource $cwrapper
- trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
-
- func_emit_cwrapperexe_src > $cwrappersource
-
- # The wrapper executable is built using the $host compiler,
- # because it contains $host paths and files. If cross-
- # compiling, it, like the target executable, must be
- # executed on the $host or under an emulation environment.
- $opt_dry_run || {
- $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
- $STRIP $cwrapper
- }
-
- # Now, create the wrapper script for func_source use:
- func_ltwrapper_scriptname $cwrapper
- $RM $func_ltwrapper_scriptname_result
- trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
- $opt_dry_run || {
- # note: this script will not be executed, so do not chmod.
- if test "x$build" = "x$host" ; then
- $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
- else
- func_emit_wrapper no > $func_ltwrapper_scriptname_result
- fi
- }
- ;;
- * )
- $RM $output
- trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
-
- func_emit_wrapper no > $output
- chmod +x $output
- ;;
- esac
- }
- exit $EXIT_SUCCESS
- ;;
- esac
-
- # See if we need to build an old-fashioned archive.
- for oldlib in $oldlibs; do
-
- if test "$build_libtool_libs" = convenience; then
- oldobjs="$libobjs_save $symfileobj"
- addlibs="$convenience"
- build_libtool_libs=no
- else
- if test "$build_libtool_libs" = module; then
- oldobjs="$libobjs_save"
- build_libtool_libs=no
- else
- oldobjs="$old_deplibs $non_pic_objects"
- if test "$preload" = yes && test -f "$symfileobj"; then
- oldobjs="$oldobjs $symfileobj"
- fi
- fi
- addlibs="$old_convenience"
- fi
-
- if test -n "$addlibs"; then
- gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
-
- func_extract_archives $gentop $addlibs
- oldobjs="$oldobjs $func_extract_archives_result"
- fi
-
- # Do each command in the archive commands.
- if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
- cmds=$old_archive_from_new_cmds
- else
-
- # Add any objects from preloaded convenience libraries
- if test -n "$dlprefiles"; then
- gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
-
- func_extract_archives $gentop $dlprefiles
- oldobjs="$oldobjs $func_extract_archives_result"
- fi
-
- # POSIX demands no paths to be encoded in archives. We have
- # to avoid creating archives with duplicate basenames if we
- # might have to extract them afterwards, e.g., when creating a
- # static archive out of a convenience library, or when linking
- # the entirety of a libtool archive into another (currently
- # not supported by libtool).
- if (for obj in $oldobjs
- do
- func_basename "$obj"
- $ECHO "$func_basename_result"
- done | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- $ECHO "copying selected object files to avoid basename conflicts..."
- gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
- func_mkdir_p "$gentop"
- save_oldobjs=$oldobjs
- oldobjs=
- counter=1
- for obj in $save_oldobjs
- do
- func_basename "$obj"
- objbase="$func_basename_result"
- case " $oldobjs " in
- " ") oldobjs=$obj ;;
- *[\ /]"$objbase "*)
- while :; do
- # Make sure we don't pick an alternate name that also
- # overlaps.
- newobj=lt$counter-$objbase
- func_arith $counter + 1
- counter=$func_arith_result
- case " $oldobjs " in
- *[\ /]"$newobj "*) ;;
- *) if test ! -f "$gentop/$newobj"; then break; fi ;;
- esac
- done
- func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
- oldobjs="$oldobjs $gentop/$newobj"
- ;;
- *) oldobjs="$oldobjs $obj" ;;
- esac
- done
- fi
- eval cmds=\"$old_archive_cmds\"
-
- func_len " $cmds"
- len=$func_len_result
- if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
- cmds=$old_archive_cmds
- else
- # the command line is too long to link in one step, link in parts
- func_verbose "using piecewise archive linking..."
- save_RANLIB=$RANLIB
- RANLIB=:
- objlist=
- concat_cmds=
- save_oldobjs=$oldobjs
- oldobjs=
- # Is there a better way of finding the last object in the list?
- for obj in $save_oldobjs
- do
- last_oldobj=$obj
- done
- eval test_cmds=\"$old_archive_cmds\"
- func_len " $test_cmds"
- len0=$func_len_result
- len=$len0
- for obj in $save_oldobjs
- do
- func_len " $obj"
- func_arith $len + $func_len_result
- len=$func_arith_result
- func_append objlist " $obj"
- if test "$len" -lt "$max_cmd_len"; then
- :
- else
- # the above command should be used before it gets too long
- oldobjs=$objlist
- if test "$obj" = "$last_oldobj" ; then
- RANLIB=$save_RANLIB
- fi
- test -z "$concat_cmds" || concat_cmds=$concat_cmds~
- eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
- objlist=
- len=$len0
- fi
- done
- RANLIB=$save_RANLIB
- oldobjs=$objlist
- if test "X$oldobjs" = "X" ; then
- eval cmds=\"\$concat_cmds\"
- else
- eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
- fi
- fi
- fi
- func_execute_cmds "$cmds" 'exit $?'
- done
-
- test -n "$generated" && \
- func_show_eval "${RM}r$generated"
-
- # Now create the libtool archive.
- case $output in
- *.la)
- old_library=
- test "$build_old_libs" = yes && old_library="$libname.$libext"
- func_verbose "creating $output"
-
- # Preserve any variables that may affect compiler behavior
- for var in $variables_saved_for_relink; do
- if eval test -z \"\${$var+set}\"; then
- relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
- elif eval var_value=\$$var; test -z "$var_value"; then
- relink_command="$var=; export $var; $relink_command"
- else
- func_quote_for_eval "$var_value"
- relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
- fi
- done
- # Quote the link command for shipping.
- relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
- relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
- if test "$hardcode_automatic" = yes ; then
- relink_command=
- fi
-
- # Only create the output if not a dry run.
- $opt_dry_run || {
- for installed in no yes; do
- if test "$installed" = yes; then
- if test -z "$install_libdir"; then
- break
- fi
- output="$output_objdir/$outputname"i
- # Replace all uninstalled libtool libraries with the installed ones
- newdependency_libs=
- for deplib in $dependency_libs; do
- case $deplib in
- *.la)
- func_basename "$deplib"
- name="$func_basename_result"
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
- test -z "$libdir" && \
- func_fatal_error "\`$deplib' is not a valid libtool archive"
- newdependency_libs="$newdependency_libs $libdir/$name"
- ;;
- *) newdependency_libs="$newdependency_libs $deplib" ;;
- esac
- done
- dependency_libs="$newdependency_libs"
- newdlfiles=
-
- for lib in $dlfiles; do
- case $lib in
- *.la)
- func_basename "$lib"
- name="$func_basename_result"
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
- test -z "$libdir" && \
- func_fatal_error "\`$lib' is not a valid libtool archive"
- newdlfiles="$newdlfiles $libdir/$name"
- ;;
- *) newdlfiles="$newdlfiles $lib" ;;
- esac
- done
- dlfiles="$newdlfiles"
- newdlprefiles=
- for lib in $dlprefiles; do
- case $lib in
- *.la)
- # Only pass preopened files to the pseudo-archive (for
- # eventual linking with the app. that links it) if we
- # didn't already link the preopened objects directly into
- # the library:
- func_basename "$lib"
- name="$func_basename_result"
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
- test -z "$libdir" && \
- func_fatal_error "\`$lib' is not a valid libtool archive"
- newdlprefiles="$newdlprefiles $libdir/$name"
- ;;
- esac
- done
- dlprefiles="$newdlprefiles"
- else
- newdlfiles=
- for lib in $dlfiles; do
- case $lib in
- [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
- *) abs=`pwd`"/$lib" ;;
- esac
- newdlfiles="$newdlfiles $abs"
- done
- dlfiles="$newdlfiles"
- newdlprefiles=
- for lib in $dlprefiles; do
- case $lib in
- [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
- *) abs=`pwd`"/$lib" ;;
- esac
- newdlprefiles="$newdlprefiles $abs"
- done
- dlprefiles="$newdlprefiles"
- fi
- $RM $output
- # place dlname in correct position for cygwin
- tdlname=$dlname
- case $host,$output,$installed,$module,$dlname in
- *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
- esac
- $ECHO > $output "\
-# $outputname - a libtool library file
-# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# The name that we can dlopen(3).
-dlname='$tdlname'
-
-# Names of this library.
-library_names='$library_names'
-
-# The name of the static archive.
-old_library='$old_library'
-
-# Linker flags that can not go in dependency_libs.
-inherited_linker_flags='$new_inherited_linker_flags'
-
-# Libraries that this one depends upon.
-dependency_libs='$dependency_libs'
-
-# Names of additional weak libraries provided by this library
-weak_library_names='$weak_libs'
-
-# Version information for $libname.
-current=$current
-age=$age
-revision=$revision
-
-# Is this an already installed library?
-installed=$installed
-
-# Should we warn about portability when linking against -modules?
-shouldnotlink=$module
-
-# Files to dlopen/dlpreopen
-dlopen='$dlfiles'
-dlpreopen='$dlprefiles'
-
-# Directory that this library needs to be installed in:
-libdir='$install_libdir'"
- if test "$installed" = no && test "$need_relink" = yes; then
- $ECHO >> $output "\
-relink_command=\"$relink_command\""
- fi
- done
- }
-
- # Do a symbolic link so that the libtool archive can be found in
- # LD_LIBRARY_PATH before the program is installed.
- func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
- ;;
- esac
- exit $EXIT_SUCCESS
-}
-
-{ test "$mode" = link || test "$mode" = relink; } &&
- func_mode_link ${1+"$@"}
-
-
-# func_mode_uninstall arg...
-func_mode_uninstall ()
-{
- $opt_debug
- RM="$nonopt"
- files=
- rmforce=
- exit_status=0
-
- # This variable tells wrapper scripts just to set variables rather
- # than running their programs.
- libtool_install_magic="$magic"
-
- for arg
- do
- case $arg in
- -f) RM="$RM $arg"; rmforce=yes ;;
- -*) RM="$RM $arg" ;;
- *) files="$files $arg" ;;
- esac
- done
-
- test -z "$RM" && \
- func_fatal_help "you must specify an RM program"
-
- rmdirs=
-
- origobjdir="$objdir"
- for file in $files; do
- func_dirname "$file" "" "."
- dir="$func_dirname_result"
- if test "X$dir" = X.; then
- objdir="$origobjdir"
- else
- objdir="$dir/$origobjdir"
- fi
- func_basename "$file"
- name="$func_basename_result"
- test "$mode" = uninstall && objdir="$dir"
-
- # Remember objdir for removal later, being careful to avoid duplicates
- if test "$mode" = clean; then
- case " $rmdirs " in
- *" $objdir "*) ;;
- *) rmdirs="$rmdirs $objdir" ;;
- esac
- fi
-
- # Don't error if the file doesn't exist and rm -f was used.
- if { test -L "$file"; } >/dev/null 2>&1 ||
- { test -h "$file"; } >/dev/null 2>&1 ||
- test -f "$file"; then
- :
- elif test -d "$file"; then
- exit_status=1
- continue
- elif test "$rmforce" = yes; then
- continue
- fi
-
- rmfiles="$file"
-
- case $name in
- *.la)
- # Possibly a libtool archive, so verify it.
- if func_lalib_p "$file"; then
- func_source $dir/$name
-
- # Delete the libtool libraries and symlinks.
- for n in $library_names; do
- rmfiles="$rmfiles $objdir/$n"
- done
- test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
-
- case "$mode" in
- clean)
- case " $library_names " in
- # " " in the beginning catches empty $dlname
- *" $dlname "*) ;;
- *) rmfiles="$rmfiles $objdir/$dlname" ;;
- esac
- test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
- ;;
- uninstall)
- if test -n "$library_names"; then
- # Do each command in the postuninstall commands.
- func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
- fi
-
- if test -n "$old_library"; then
- # Do each command in the old_postuninstall commands.
- func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
- fi
- # FIXME: should reinstall the best remaining shared library.
- ;;
- esac
- fi
- ;;
-
- *.lo)
- # Possibly a libtool object, so verify it.
- if func_lalib_p "$file"; then
-
- # Read the .lo file
- func_source $dir/$name
-
- # Add PIC object to the list of files to remove.
- if test -n "$pic_object" &&
- test "$pic_object" != none; then
- rmfiles="$rmfiles $dir/$pic_object"
- fi
-
- # Add non-PIC object to the list of files to remove.
- if test -n "$non_pic_object" &&
- test "$non_pic_object" != none; then
- rmfiles="$rmfiles $dir/$non_pic_object"
- fi
- fi
- ;;
-
- *)
- if test "$mode" = clean ; then
- noexename=$name
- case $file in
- *.exe)
- func_stripname '' '.exe' "$file"
- file=$func_stripname_result
- func_stripname '' '.exe' "$name"
- noexename=$func_stripname_result
- # $file with .exe has already been added to rmfiles,
- # add $file without .exe
- rmfiles="$rmfiles $file"
- ;;
- esac
- # Do a test to see if this is a libtool program.
- if func_ltwrapper_p "$file"; then
- if func_ltwrapper_executable_p "$file"; then
- func_ltwrapper_scriptname "$file"
- relink_command=
- func_source $func_ltwrapper_scriptname_result
- rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
- else
- relink_command=
- func_source $dir/$noexename
- fi
-
- # note $name still contains .exe if it was in $file originally
- # as does the version of $file that was added into $rmfiles
- rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
- if test "$fast_install" = yes && test -n "$relink_command"; then
- rmfiles="$rmfiles $objdir/lt-$name"
- fi
- if test "X$noexename" != "X$name" ; then
- rmfiles="$rmfiles $objdir/lt-${noexename}.c"
- fi
- fi
- fi
- ;;
- esac
- func_show_eval "$RM $rmfiles" 'exit_status=1'
- done
- objdir="$origobjdir"
-
- # Try to remove the ${objdir}s in the directories where we deleted files
- for dir in $rmdirs; do
- if test -d "$dir"; then
- func_show_eval "rmdir $dir >/dev/null 2>&1"
- fi
- done
-
- exit $exit_status
-}
-
-{ test "$mode" = uninstall || test "$mode" = clean; } &&
- func_mode_uninstall ${1+"$@"}
-
-test -z "$mode" && {
- help="$generic_help"
- func_fatal_help "you must specify a MODE"
-}
-
-test -z "$exec_cmd" && \
- func_fatal_help "invalid operation mode \`$mode'"
-
-if test -n "$exec_cmd"; then
- eval exec "$exec_cmd"
- exit $EXIT_FAILURE
-fi
-
-exit $exit_status
-
-
-# The TAGs below are defined such that we never get into a situation
-# in which we disable both kinds of libraries. Given conflicting
-# choices, we go for a static library, that is the most portable,
-# since we can't tell whether shared libraries were disabled because
-# the user asked for that or because the platform doesn't support
-# them. This is particularly important on AIX, because we don't
-# support having both static and shared libraries enabled at the same
-# time on that platform, so we default to a shared-only configuration.
-# If a disable-shared tag is given, we'll fallback to a static-only
-# configuration. But we'll never go from static-only to shared-only.
-
-# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
-build_libtool_libs=no
-build_old_libs=yes
-# ### END LIBTOOL TAG CONFIG: disable-shared
-
-# ### BEGIN LIBTOOL TAG CONFIG: disable-static
-build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
-# ### END LIBTOOL TAG CONFIG: disable-static
-
-# Local Variables:
-# mode:shell-script
-# sh-indentation:2
-# End:
-# vi:sw=2
-
diff --git a/deps/uv/src/unix/ev/missing b/deps/uv/src/unix/ev/missing
deleted file mode 100755
index fc54c64ec..000000000
--- a/deps/uv/src/unix/ev/missing
+++ /dev/null
@@ -1,336 +0,0 @@
-#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-if test $# -eq 0; then
- echo 1>&2 "Try \`$0 --help' for more information"
- exit 1
-fi
-
-run=:
-
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.ac; then
- configure_ac=configure.ac
-else
- configure_ac=configure.in
-fi
-
-case "$1" in
---run)
- # Try to run requested program, and just exit if it succeeds.
- run=
- shift
- "$@" && exit 0
- ;;
-esac
-
-# If it does not exist, or fails to run (possibly an outdated version),
-# try to emulate it.
-case "$1" in
-
- -h|--h|--he|--hel|--help)
- echo "\
-$0 [OPTION]... PROGRAM [ARGUMENT]...
-
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
-
-Options:
- -h, --help display this help and exit
- -v, --version output version information and exit
- --run try to run the given command, and emulate it if it fails
-
-Supported PROGRAM values:
- aclocal touch file \`aclocal.m4'
- autoconf touch file \`configure'
- autoheader touch file \`config.h.in'
- automake touch all \`Makefile.in' files
- bison create \`y.tab.[ch]', if possible, from existing .[ch]
- flex create \`lex.yy.c', if possible, from existing .c
- help2man touch the output file
- lex create \`lex.yy.c', if possible, from existing .c
- makeinfo touch the output file
- tar try tar, gnutar, gtar, then tar without non-portable flags
- yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
- ;;
-
- -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
- echo "missing 0.4 - GNU automake"
- ;;
-
- -*)
- echo 1>&2 "$0: Unknown \`$1' option"
- echo 1>&2 "Try \`$0 --help' for more information"
- exit 1
- ;;
-
- aclocal*)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- fi
-
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified \`acinclude.m4' or \`${configure_ac}'. You might want
- to install the \`Automake' and \`Perl' packages. Grab them from
- any GNU archive site."
- touch aclocal.m4
- ;;
-
- autoconf)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- fi
-
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified \`${configure_ac}'. You might want to install the
- \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
- archive site."
- touch configure
- ;;
-
- autoheader)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- fi
-
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified \`acconfig.h' or \`${configure_ac}'. You might want
- to install the \`Autoconf' and \`GNU m4' packages. Grab them
- from any GNU archive site."
- files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
- test -z "$files" && files="config.h"
- touch_files=
- for f in $files; do
- case "$f" in
- *:*) touch_files="$touch_files "`echo "$f" |
- sed -e 's/^[^:]*://' -e 's/:.*//'`;;
- *) touch_files="$touch_files $f.in";;
- esac
- done
- touch $touch_files
- ;;
-
- automake*)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- fi
-
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
- You might want to install the \`Automake' and \`Perl' packages.
- Grab them from any GNU archive site."
- find . -type f -name Makefile.am -print |
- sed 's/\.am$/.in/' |
- while read f; do touch "$f"; done
- ;;
-
- autom4te)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- fi
-
- echo 1>&2 "\
-WARNING: \`$1' is needed, and you do not seem to have it handy on your
- system. You might have modified some files without having the
- proper tools for further handling them.
- You can get \`$1' as part of \`Autoconf' from any GNU
- archive site."
-
- file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
- test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo "#! /bin/sh"
- echo "# Created by GNU Automake missing as a replacement of"
- echo "# $ $@"
- echo "exit 0"
- chmod +x $file
- exit 1
- fi
- ;;
-
- bison|yacc)
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified a \`.y' file. You may need the \`Bison' package
- in order for those modifications to take effect. You can get
- \`Bison' from any GNU archive site."
- rm -f y.tab.c y.tab.h
- if [ $# -ne 1 ]; then
- eval LASTARG="\${$#}"
- case "$LASTARG" in
- *.y)
- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if [ -f "$SRCFILE" ]; then
- cp "$SRCFILE" y.tab.c
- fi
- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if [ -f "$SRCFILE" ]; then
- cp "$SRCFILE" y.tab.h
- fi
- ;;
- esac
- fi
- if [ ! -f y.tab.h ]; then
- echo >y.tab.h
- fi
- if [ ! -f y.tab.c ]; then
- echo 'main() { return 0; }' >y.tab.c
- fi
- ;;
-
- lex|flex)
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified a \`.l' file. You may need the \`Flex' package
- in order for those modifications to take effect. You can get
- \`Flex' from any GNU archive site."
- rm -f lex.yy.c
- if [ $# -ne 1 ]; then
- eval LASTARG="\${$#}"
- case "$LASTARG" in
- *.l)
- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if [ -f "$SRCFILE" ]; then
- cp "$SRCFILE" lex.yy.c
- fi
- ;;
- esac
- fi
- if [ ! -f lex.yy.c ]; then
- echo 'main() { return 0; }' >lex.yy.c
- fi
- ;;
-
- help2man)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- fi
-
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified a dependency of a manual page. You may need the
- \`Help2man' package in order for those modifications to take
- effect. You can get \`Help2man' from any GNU archive site."
-
- file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
- if test -z "$file"; then
- file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
- fi
- if [ -f "$file" ]; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo ".ab help2man is required to generate this page"
- exit 1
- fi
- ;;
-
- makeinfo)
- if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
- # We have makeinfo, but it failed.
- exit 1
- fi
-
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified a \`.texi' or \`.texinfo' file, or any other file
- indirectly affecting the aspect of the manual. The spurious
- call might also be the consequence of using a buggy \`make' (AIX,
- DU, IRIX). You might want to install the \`Texinfo' package or
- the \`GNU make' package. Grab either from any GNU archive site."
- file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
- if test -z "$file"; then
- file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
- file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
- fi
- touch $file
- ;;
-
- tar)
- shift
- if test -n "$run"; then
- echo 1>&2 "ERROR: \`tar' requires --run"
- exit 1
- fi
-
- # We have already tried tar in the generic part.
- # Look for gnutar/gtar before invocation to avoid ugly error
- # messages.
- if (gnutar --version > /dev/null 2>&1); then
- gnutar "$@" && exit 0
- fi
- if (gtar --version > /dev/null 2>&1); then
- gtar "$@" && exit 0
- fi
- firstarg="$1"
- if shift; then
- case "$firstarg" in
- *o*)
- firstarg=`echo "$firstarg" | sed s/o//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- case "$firstarg" in
- *h*)
- firstarg=`echo "$firstarg" | sed s/h//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- fi
-
- echo 1>&2 "\
-WARNING: I can't seem to be able to run \`tar' with the given arguments.
- You may want to install GNU tar or Free paxutils, or check the
- command line arguments."
- exit 1
- ;;
-
- *)
- echo 1>&2 "\
-WARNING: \`$1' is needed, and you do not seem to have it handy on your
- system. You might have modified some files without having the
- proper tools for further handling them. Check the \`README' file,
- it often tells you about the needed prerequisites for installing
- this package. You may also peek at any GNU archive site, in case
- some other package would contain this missing \`$1' program."
- exit 1
- ;;
-esac
-
-exit 0
diff --git a/deps/uv/src/unix/ev/mkinstalldirs b/deps/uv/src/unix/ev/mkinstalldirs
deleted file mode 100755
index d2d5f21b6..000000000
--- a/deps/uv/src/unix/ev/mkinstalldirs
+++ /dev/null
@@ -1,111 +0,0 @@
-#! /bin/sh
-# mkinstalldirs --- make directory hierarchy
-# Author: Noah Friedman <friedman@prep.ai.mit.edu>
-# Created: 1993-05-16
-# Public domain
-
-errstatus=0
-dirmode=""
-
-usage="\
-Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
-
-# process command line arguments
-while test $# -gt 0 ; do
- case $1 in
- -h | --help | --h*) # -h for help
- echo "$usage" 1>&2
- exit 0
- ;;
- -m) # -m PERM arg
- shift
- test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
- dirmode=$1
- shift
- ;;
- --) # stop option processing
- shift
- break
- ;;
- -*) # unknown option
- echo "$usage" 1>&2
- exit 1
- ;;
- *) # first non-opt arg
- break
- ;;
- esac
-done
-
-for file
-do
- if test -d "$file"; then
- shift
- else
- break
- fi
-done
-
-case $# in
- 0) exit 0 ;;
-esac
-
-case $dirmode in
- '')
- if mkdir -p -- . 2>/dev/null; then
- echo "mkdir -p -- $*"
- exec mkdir -p -- "$@"
- fi
- ;;
- *)
- if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
- echo "mkdir -m $dirmode -p -- $*"
- exec mkdir -m "$dirmode" -p -- "$@"
- fi
- ;;
-esac
-
-for file
-do
- set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
- shift
-
- pathcomp=
- for d
- do
- pathcomp="$pathcomp$d"
- case $pathcomp in
- -*) pathcomp=./$pathcomp ;;
- esac
-
- if test ! -d "$pathcomp"; then
- echo "mkdir $pathcomp"
-
- mkdir "$pathcomp" || lasterr=$?
-
- if test ! -d "$pathcomp"; then
- errstatus=$lasterr
- else
- if test ! -z "$dirmode"; then
- echo "chmod $dirmode $pathcomp"
- lasterr=""
- chmod "$dirmode" "$pathcomp" || lasterr=$?
-
- if test ! -z "$lasterr"; then
- errstatus=$lasterr
- fi
- fi
- fi
- fi
-
- pathcomp="$pathcomp/"
- done
-done
-
-exit $errstatus
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# End:
-# mkinstalldirs ends here
diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c
index 0528835f9..44b1ef3d2 100644
--- a/deps/uv/src/unix/freebsd.c
+++ b/deps/uv/src/unix/freebsd.c
@@ -54,7 +54,16 @@
static char *process_title;
-uint64_t uv_hrtime(void) {
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ return uv__kqueue_init(loop);
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+}
+
+
+uint64_t uv__hrtime(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
@@ -226,12 +235,26 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
multiplier = ((uint64_t)1000L / ticks), cpuspeed, maxcpus,
cur = 0;
uv_cpu_info_t* cpu_info;
+ const char* maxcpus_key;
+ const char* cptimes_key;
char model[512];
long* cp_times;
int numcpus;
size_t size;
int i;
+#if defined(__DragonFly__)
+ /* This is not quite correct but DragonFlyBSD doesn't seem to have anything
+ * comparable to kern.smp.maxcpus or kern.cp_times (kern.cp_time is a total,
+ * not per CPU). At least this stops uv_cpu_info() from failing completely.
+ */
+ maxcpus_key = "hw.ncpu";
+ cptimes_key = "kern.cp_time";
+#else
+ maxcpus_key = "kern.smp.maxcpus";
+ cptimes_key = "kern.cp_times";
+#endif
+
size = sizeof(model);
if (sysctlbyname("hw.model", &model, &size, NULL, 0) < 0) {
return uv__new_sys_error(errno);
@@ -253,19 +276,13 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
free(*cpu_infos);
return uv__new_sys_error(errno);
}
+
/* kern.cp_times on FreeBSD i386 gives an array up to maxcpus instead of ncpu */
size = sizeof(maxcpus);
-#ifdef __DragonFly__
- if (sysctlbyname("hw.ncpu", &maxcpus, &size, NULL, 0) < 0) {
- free(*cpu_infos);
- return uv__new_sys_error(errno);
- }
-#else
- if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
+ if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0) < 0) {
free(*cpu_infos);
return uv__new_sys_error(errno);
}
-#endif
size = maxcpus * CPUSTATES * sizeof(long);
@@ -275,7 +292,7 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
return uv__new_sys_error(ENOMEM);
}
- if (sysctlbyname("kern.cp_times", cp_times, &size, NULL, 0) < 0) {
+ if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0) < 0) {
free(cp_times);
free(*cpu_infos);
return uv__new_sys_error(errno);
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index c43c19f23..53f46ce7c 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -21,679 +21,849 @@
#include "uv.h"
#include "internal.h"
-#include "eio.h"
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <pthread.h>
#include <dirent.h>
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
#include <unistd.h>
+#include <fcntl.h>
#include <utime.h>
-#include <sys/time.h>
-
-
-#define ARGS1(a) (a)
-#define ARGS2(a,b) (a), (b)
-#define ARGS3(a,b,c) (a), (b), (c)
-#define ARGS4(a,b,c,d) (a), (b), (c), (d)
-
-#define WRAP_EIO(type, eiofunc, func, args) \
- uv_fs_req_init(loop, req, type, path, cb); \
- if (cb) { \
- /* async */ \
- req->eio = eiofunc(args, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel); \
- if (!req->eio) { \
- uv__set_sys_error(loop, ENOMEM); \
- return -1; \
- } \
- } else { \
- /* sync */ \
- req->result = func(args); \
- if (req->result) { \
- uv__set_sys_error(loop, errno); \
- } \
- return req->result; \
- } \
- return 0;
-
-
-static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type,
- const char* path, uv_fs_cb cb) {
- /* Make sure the thread pool is initialized. */
- uv_eio_init(loop);
+#include <poll.h>
- uv__req_init(loop, req, UV_FS);
- req->loop = loop;
- req->fs_type = fs_type;
- req->cb = cb;
- req->result = 0;
- req->ptr = NULL;
- req->path = path ? strdup(path) : NULL;
- req->errorno = 0;
- req->eio = NULL;
+#if defined(__linux__) || defined(__sun)
+# include <sys/sendfile.h>
+#elif defined(__APPLE__) || defined(__FreeBSD__)
+# include <sys/socket.h>
+# include <sys/uio.h>
+#endif
- /* synchronous requests don't increase the reference count */
- if (!req->cb)
- uv__req_unregister(req->loop, req);
+#define INIT(type) \
+ do { \
+ uv__req_init((loop), (req), UV_FS); \
+ (req)->fs_type = UV_FS_ ## type; \
+ (req)->errorno = 0; \
+ (req)->result = 0; \
+ (req)->ptr = NULL; \
+ (req)->loop = loop; \
+ (req)->path = NULL; \
+ (req)->new_path = NULL; \
+ (req)->cb = (cb); \
+ } \
+ while (0)
+
+#define PATH \
+ do { \
+ if (NULL == ((req)->path = strdup((path)))) \
+ return uv__set_sys_error((loop), ENOMEM); \
+ } \
+ while (0)
+
+#define PATH2 \
+ do { \
+ size_t path_len; \
+ size_t new_path_len; \
+ \
+ path_len = strlen((path)) + 1; \
+ new_path_len = strlen((new_path)) + 1; \
+ \
+ if (NULL == ((req)->path = malloc(path_len + new_path_len))) \
+ return uv__set_sys_error((loop), ENOMEM); \
+ \
+ (req)->new_path = (req)->path + path_len; \
+ memcpy((void*) (req)->path, (path), path_len); \
+ memcpy((void*) (req)->new_path, (new_path), new_path_len); \
+ } \
+ while (0)
+
+#define POST \
+ do { \
+ if ((cb) != NULL) { \
+ uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \
+ return 0; \
+ } \
+ else { \
+ uv__fs_work(&(req)->work_req); \
+ uv__fs_done(&(req)->work_req, 0); \
+ return (req)->result; \
+ } \
+ } \
+ while (0)
+
+
+static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
+#if defined(__linux__) || defined(__sun) || defined(__NetBSD__)
+ return fdatasync(req->file);
+#elif defined(__APPLE__) && defined(F_FULLFSYNC)
+ return fcntl(req->file, F_FULLFSYNC);
+#else
+ return fsync(req->file);
+#endif
}
-void uv_fs_req_cleanup(uv_fs_t* req) {
- if (req->cb)
- uv__req_unregister(req->loop, req);
-
- free((void*)req->path);
- req->path = NULL;
-
- switch (req->fs_type) {
- case UV_FS_READDIR:
- assert(req->result > 0 ? (req->ptr != NULL) : (req->ptr == NULL));
- free(req->ptr);
- req->ptr = NULL;
- break;
+static ssize_t uv__fs_futime(uv_fs_t* req) {
+#if defined(__linux__)
+ /* utimesat() has nanosecond resolution but we stick to microseconds
+ * for the sake of consistency with other platforms.
+ */
+ static int no_utimesat;
+ struct timespec ts[2];
+ struct timeval tv[2];
+ char path[sizeof("/proc/self/fd/") + 3 * sizeof(int)];
+ int r;
- case UV_FS_STAT:
- case UV_FS_LSTAT:
- req->ptr = NULL;
- break;
+ if (no_utimesat)
+ goto skip;
- default:
- break;
- }
-}
+ ts[0].tv_sec = req->atime;
+ ts[0].tv_nsec = (unsigned long)(req->atime * 1000000) % 1000000 * 1000;
+ ts[1].tv_sec = req->mtime;
+ ts[1].tv_nsec = (unsigned long)(req->mtime * 1000000) % 1000000 * 1000;
+ r = uv__utimesat(req->file, NULL, ts, 0);
+ if (r == 0)
+ return r;
-static int uv__fs_after(eio_req* eio) {
- char* name;
- int namelen;
- int buflen = 0;
- uv_fs_t* req = eio->data;
- int i;
+ if (errno != ENOSYS)
+ return r;
- assert(req->cb);
-
- req->result = req->eio->result;
- req->errorno = uv_translate_sys_error(req->eio->errorno);
-
- switch (req->fs_type) {
- case UV_FS_READDIR:
- /*
- * XXX This is pretty bad.
- * We alloc and copy the large null terminated string list from libeio.
- * This is done because libeio is going to free eio->ptr2 after this
- * callback. We must keep it until uv_fs_req_cleanup. If we get rid of
- * libeio this can be avoided.
- */
- buflen = 0;
- name = req->eio->ptr2;
-
- for (i = 0; i < req->result; i++) {
- namelen = strlen(name);
- buflen += namelen + 1;
- name += namelen;
- assert(*name == '\0');
- name++;
- }
+ no_utimesat = 1;
- if (buflen) {
- if ((req->ptr = malloc(buflen)))
- memcpy(req->ptr, req->eio->ptr2, buflen);
- else
- uv__set_sys_error(req->loop, ENOMEM);
- }
- break;
+skip:
- case UV_FS_STAT:
- case UV_FS_LSTAT:
- case UV_FS_FSTAT:
- req->ptr = req->eio->ptr2;
- break;
+ tv[0].tv_sec = req->atime;
+ tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000;
+ tv[1].tv_sec = req->mtime;
+ tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000;
+ snprintf(path, sizeof(path), "/proc/self/fd/%d", (int) req->file);
- case UV_FS_READLINK:
- if (req->result == -1) {
- req->ptr = NULL;
- break;
- }
- assert(req->result > 0);
+ r = utimes(path, tv);
+ if (r == 0)
+ return r;
- /* Make zero-terminated copy of req->eio->ptr2 */
- if ((req->ptr = name = malloc(req->result + 1))) {
- memcpy(name, req->eio->ptr2, req->result);
- name[req->result] = '\0';
- req->result = 0;
- }
- else {
- req->errorno = ENOMEM;
- req->result = -1;
- }
+ switch (errno) {
+ case ENOENT:
+ if (fcntl(req->file, F_GETFL) == -1 && errno == EBADF)
break;
+ /* Fall through. */
- default:
- break;
+ case EACCES:
+ case ENOTDIR:
+ errno = ENOSYS;
+ break;
}
- req->eio = NULL; /* Freed by libeio */
- req->cb(req);
+ return r;
- return 0;
+#elif defined(__APPLE__) \
+ || defined(__DragonFly__) \
+ || defined(__FreeBSD__) \
+ || defined(__sun)
+ struct timeval tv[2];
+ tv[0].tv_sec = req->atime;
+ tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000;
+ tv[1].tv_sec = req->mtime;
+ tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000;
+ return futimes(req->file, tv);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
}
-int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
- char* path = NULL;
- WRAP_EIO(UV_FS_CLOSE, eio_close, close, ARGS1(file));
+static ssize_t uv__fs_read(uv_fs_t* req) {
+ if (req->off < 0)
+ return read(req->file, req->buf, req->len);
+ else
+ return pread(req->file, req->buf, req->len, req->off);
}
-int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
- int mode, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_OPEN, path, cb);
+static int uv__fs_readdir_filter(const struct dirent* dent) {
+ return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0;
+}
- if (cb) {
- /* async */
- req->eio = eio_open(path, flags, mode, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
- if (!req->eio) {
- uv__set_sys_error(loop, ENOMEM);
- return -1;
- }
- } else {
- /* sync */
- req->result = open(path, flags, mode);
- if (req->result < 0) {
- uv__set_sys_error(loop, errno);
- return -1;
- }
+/* This should have been called uv__fs_scandir(). */
+static ssize_t uv__fs_readdir(uv_fs_t* req) {
+ struct dirent **dents;
+ int saved_errno;
+ size_t off;
+ size_t len;
+ char *buf;
+ int i;
+ int n;
- uv__cloexec(req->result, 1);
+ n = scandir(req->path, &dents, uv__fs_readdir_filter, alphasort);
- return req->result;
- }
+ if (n == -1 || n == 0)
+ return n;
- return 0;
-}
+ len = 0;
+ for (i = 0; i < n; i++)
+ len += strlen(dents[i]->d_name) + 1;
-int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
- size_t length, int64_t offset, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_READ, NULL, cb);
+ buf = malloc(len);
- if (cb) {
- /* async */
- req->eio = eio_read(fd, buf, length, offset, EIO_PRI_DEFAULT,
- uv__fs_after, req, &loop->uv_eio_channel);
+ if (buf == NULL) {
+ errno = ENOMEM;
+ n = -1;
+ goto out;
+ }
- if (!req->eio) {
- uv__set_sys_error(loop, ENOMEM);
- return -1;
- }
+ off = 0;
- } else {
- /* sync */
- req->result = offset < 0 ?
- read(fd, buf, length) :
- pread(fd, buf, length, offset);
+ for (i = 0; i < n; i++) {
+ len = strlen(dents[i]->d_name) + 1;
+ memcpy(buf + off, dents[i]->d_name, len);
+ off += len;
+ }
- if (req->result < 0) {
- uv__set_sys_error(loop, errno);
- return -1;
- }
+ req->ptr = buf;
- return req->result;
+out:
+ saved_errno = errno;
+ {
+ for (i = 0; i < n; i++)
+ free(dents[i]);
+ free(dents);
}
+ errno = saved_errno;
- return 0;
+ return n;
}
-int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
- WRAP_EIO(UV_FS_UNLINK, eio_unlink, unlink, ARGS1(path))
-}
+static ssize_t uv__fs_readlink(uv_fs_t* req) {
+ ssize_t len;
+ char* buf;
+ len = pathconf(req->path, _PC_PATH_MAX);
-int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
- size_t length, int64_t offset, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_WRITE, NULL, cb);
+ if (len == -1) {
+#if defined(PATH_MAX)
+ len = PATH_MAX;
+#else
+ len = 4096;
+#endif
+ }
- if (cb) {
- /* async */
- req->eio = eio_write(file, buf, length, offset, EIO_PRI_DEFAULT,
- uv__fs_after, req, &loop->uv_eio_channel);
- if (!req->eio) {
- uv__set_sys_error(loop, ENOMEM);
- return -1;
- }
+ buf = malloc(len + 1);
- } else {
- /* sync */
- req->result = offset < 0 ?
- write(file, buf, length) :
- pwrite(file, buf, length, offset);
+ if (buf == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
- if (req->result < 0) {
- uv__set_sys_error(loop, errno);
- return -1;
- }
+ len = readlink(req->path, buf, len);
- return req->result;
+ if (len == -1) {
+ free(buf);
+ return -1;
}
+ buf[len] = '\0';
+ req->ptr = buf;
+
return 0;
}
-int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
- uv_fs_cb cb) {
- WRAP_EIO(UV_FS_MKDIR, eio_mkdir, mkdir, ARGS2(path, mode))
-}
+static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) {
+ struct pollfd pfd;
+ int use_pread;
+ off_t offset;
+ ssize_t nsent;
+ ssize_t nread;
+ ssize_t nwritten;
+ size_t buflen;
+ size_t len;
+ ssize_t n;
+ int in_fd;
+ int out_fd;
+ char buf[8192];
+
+ len = req->len;
+ in_fd = req->flags;
+ out_fd = req->file;
+ offset = req->off;
+ use_pread = 1;
+
+ /* Here are the rules regarding errors:
+ *
+ * 1. Read errors are reported only if nsent==0, otherwise we return nsent.
+ * The user needs to know that some data has already been sent, to stop
+ * him from sending it twice.
+ *
+ * 2. Write errors are always reported. Write errors are bad because they
+ * mean data loss: we've read data but now we can't write it out.
+ *
+ * We try to use pread() and fall back to regular read() if the source fd
+ * doesn't support positional reads, for example when it's a pipe fd.
+ *
+ * If we get EAGAIN when writing to the target fd, we poll() on it until
+ * it becomes writable again.
+ *
+ * FIXME: If we get a write error when use_pread==1, it should be safe to
+ * return the number of sent bytes instead of an error because pread()
+ * is, in theory, idempotent. However, special files in /dev or /proc
+ * may support pread() but not necessarily return the same data on
+ * successive reads.
+ *
+ * FIXME: There is no way now to signal that we managed to send *some* data
+ * before a write error.
+ */
+ for (nsent = 0; (size_t) nsent < len; ) {
+ buflen = len - nsent;
+ if (buflen > sizeof(buf))
+ buflen = sizeof(buf);
-int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
- WRAP_EIO(UV_FS_RMDIR, eio_rmdir, rmdir, ARGS1(path))
-}
+ do
+ if (use_pread)
+ nread = pread(in_fd, buf, buflen, offset);
+ else
+ nread = read(in_fd, buf, buflen);
+ while (nread == -1 && errno == EINTR);
+ if (nread == 0)
+ goto out;
-int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
- uv_fs_cb cb) {
- int r;
- struct dirent* entry;
- size_t size = 0;
- size_t d_namlen = 0;
-
- uv_fs_req_init(loop, req, UV_FS_READDIR, path, cb);
-
- if (cb) {
- /* async */
- req->eio = eio_readdir(path, flags, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
- if (!req->eio) {
- uv__set_sys_error(loop, ENOMEM);
- return -1;
- }
+ if (nread == -1) {
+ if (use_pread && nsent == 0 && (errno == EIO || errno == ESPIPE)) {
+ use_pread = 0;
+ continue;
+ }
- } else {
- /* sync */
- DIR* dir = opendir(path);
- if (!dir) {
- uv__set_sys_error(loop, errno);
- req->result = -1;
- return -1;
- }
+ if (nsent == 0)
+ nsent = -1;
- /* req->result stores number of entries */
- req->result = 0;
+ goto out;
+ }
- while ((entry = readdir(dir))) {
- d_namlen = strlen(entry->d_name);
+ for (nwritten = 0; nwritten < nread; ) {
+ do
+ n = write(out_fd, buf + nwritten, nread - nwritten);
+ while (n == -1 && errno == EINTR);
- /* Skip . and .. */
- if ((d_namlen == 1 && entry->d_name[0] == '.') ||
- (d_namlen == 2 && entry->d_name[0] == '.' &&
- entry->d_name[1] == '.')) {
+ if (n != -1) {
+ nwritten += n;
continue;
}
- req->ptr = realloc(req->ptr, size + d_namlen + 1);
- /* TODO check ENOMEM */
- memcpy((char*)req->ptr + size, entry->d_name, d_namlen);
- size += d_namlen;
- ((char*)req->ptr)[size] = '\0';
- size++;
- req->result++;
- }
+ if (errno != EAGAIN && errno != EWOULDBLOCK) {
+ nsent = -1;
+ goto out;
+ }
+
+ pfd.fd = out_fd;
+ pfd.events = POLLOUT;
+ pfd.revents = 0;
- r = closedir(dir);
- if (r) {
- uv__set_sys_error(loop, errno);
- req->result = -1;
- return -1;
+ do
+ n = poll(&pfd, 1, -1);
+ while (n == -1 && errno == EINTR);
+
+ if (n == -1 || (pfd.revents & ~POLLOUT) != 0) {
+ errno = EIO;
+ nsent = -1;
+ goto out;
+ }
}
- return req->result;
+ offset += nread;
+ nsent += nread;
}
- return 0;
+out:
+ if (nsent != -1)
+ req->off = offset;
+
+ return nsent;
}
-int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
- char* pathdup;
- int pathlen;
+static ssize_t uv__fs_sendfile(uv_fs_t* req) {
+ int in_fd;
+ int out_fd;
- uv_fs_req_init(loop, req, UV_FS_STAT, path, cb);
+ in_fd = req->flags;
+ out_fd = req->file;
- /* TODO do this without duplicating the string. */
- /* TODO security */
- pathdup = strdup(path);
- pathlen = strlen(path);
+#if defined(__linux__) || defined(__sun)
+ {
+ off_t off;
+ ssize_t r;
- if (pathlen > 0 && path[pathlen - 1] == '\\') {
- /* TODO do not modify input string */
- pathdup[pathlen - 1] = '\0';
- }
+ off = req->off;
+ r = sendfile(out_fd, in_fd, &off, req->len);
- if (cb) {
- /* async */
- req->eio = eio_stat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
-
- free(pathdup);
+ /* sendfile() on SunOS returns EINVAL if the target fd is not a socket but
+ * it still writes out data. Fortunately, we can detect it by checking if
+ * the offset has been updated.
+ */
+ if (r != -1 || off > req->off) {
+ r = off - req->off;
+ req->off = off;
+ return r;
+ }
- if (!req->eio) {
- uv__set_sys_error(loop, ENOMEM);
- return -1;
+ if (errno == EINVAL ||
+ errno == EIO ||
+ errno == ENOTSOCK ||
+ errno == EXDEV) {
+ errno = 0;
+ return uv__fs_sendfile_emul(req);
}
- } else {
- /* sync */
- req->result = stat(pathdup, &req->statbuf);
+ return -1;
+ }
+#elif defined(__FreeBSD__) || defined(__APPLE__)
+ {
+ off_t len;
+ ssize_t r;
+
+ /* sendfile() on FreeBSD and Darwin returns EAGAIN if the target fd is in
+ * non-blocking mode and not all data could be written. If a non-zero
+ * number of bytes have been sent, we don't consider it an error.
+ */
+ len = 0;
+
+#if defined(__FreeBSD__)
+ r = sendfile(in_fd, out_fd, req->off, req->len, NULL, &len, 0);
+#else
+ r = sendfile(in_fd, out_fd, req->off, &len, NULL, 0);
+#endif
- free(pathdup);
+ if (r != -1 || len != 0) {
+ req->off += len;
+ return (ssize_t) len;
+ }
- if (req->result < 0) {
- uv__set_sys_error(loop, errno);
- return -1;
+ if (errno == EINVAL ||
+ errno == EIO ||
+ errno == ENOTSOCK ||
+ errno == EXDEV) {
+ errno = 0;
+ return uv__fs_sendfile_emul(req);
}
- req->ptr = &req->statbuf;
- return req->result;
+ return -1;
}
+#else
+ return uv__fs_sendfile_emul(req);
+#endif
+}
- return 0;
+
+static ssize_t uv__fs_utime(uv_fs_t* req) {
+ struct utimbuf buf;
+ buf.actime = req->atime;
+ buf.modtime = req->mtime;
+ return utime(req->path, &buf); /* TODO use utimes() where available */
}
-int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_FSTAT, NULL, cb);
+static ssize_t uv__fs_write(uv_fs_t* req) {
+ ssize_t r;
- if (cb) {
- /* async */
- req->eio = eio_fstat(file, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
+ /* Serialize writes on OS X, concurrent write() and pwrite() calls result in
+ * data loss. We can't use a per-file descriptor lock, the descriptor may be
+ * a dup().
+ */
+#if defined(__APPLE__)
+ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_lock(&lock);
+#endif
- if (!req->eio) {
- uv__set_sys_error(loop, ENOMEM);
- return -1;
- }
+ if (req->off < 0)
+ r = write(req->file, req->buf, req->len);
+ else
+ r = pwrite(req->file, req->buf, req->len, req->off);
- } else {
- /* sync */
- req->result = fstat(file, &req->statbuf);
+#if defined(__APPLE__)
+ pthread_mutex_unlock(&lock);
+#endif
- if (req->result < 0) {
- uv__set_sys_error(loop, errno);
- return -1;
+ return r;
+}
+
+
+static void uv__fs_work(struct uv__work* w) {
+ int retry_on_eintr;
+ uv_fs_t* req;
+ ssize_t r;
+
+ req = container_of(w, uv_fs_t, work_req);
+ retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);
+
+ do {
+ errno = 0;
+
+#define X(type, action) \
+ case UV_FS_ ## type: \
+ r = action; \
+ break;
+
+ switch (req->fs_type) {
+ X(CHMOD, chmod(req->path, req->mode));
+ X(CHOWN, chown(req->path, req->uid, req->gid));
+ X(CLOSE, close(req->file));
+ X(FCHMOD, fchmod(req->file, req->mode));
+ X(FCHOWN, fchown(req->file, req->uid, req->gid));
+ X(FDATASYNC, uv__fs_fdatasync(req));
+ X(FSTAT, fstat(req->file, &req->statbuf));
+ X(FSYNC, fsync(req->file));
+ X(FTRUNCATE, ftruncate(req->file, req->off));
+ X(FUTIME, uv__fs_futime(req));
+ X(LSTAT, lstat(req->path, &req->statbuf));
+ X(LINK, link(req->path, req->new_path));
+ X(MKDIR, mkdir(req->path, req->mode));
+ X(OPEN, open(req->path, req->flags, req->mode));
+ X(READ, uv__fs_read(req));
+ X(READDIR, uv__fs_readdir(req));
+ X(READLINK, uv__fs_readlink(req));
+ X(RENAME, rename(req->path, req->new_path));
+ X(RMDIR, rmdir(req->path));
+ X(SENDFILE, uv__fs_sendfile(req));
+ X(STAT, stat(req->path, &req->statbuf));
+ X(SYMLINK, symlink(req->path, req->new_path));
+ X(UNLINK, unlink(req->path));
+ X(UTIME, uv__fs_utime(req));
+ X(WRITE, uv__fs_write(req));
+ default: abort();
}
- req->ptr = &req->statbuf;
- return req->result;
+#undef X
}
+ while (r == -1 && errno == EINTR && retry_on_eintr);
- return 0;
-}
-
+ req->errorno = errno;
+ req->result = r;
-int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path,
- uv_fs_cb cb) {
- WRAP_EIO(UV_FS_RENAME, eio_rename, rename, ARGS2(path, new_path))
+ if (r == 0 && (req->fs_type == UV_FS_STAT ||
+ req->fs_type == UV_FS_FSTAT ||
+ req->fs_type == UV_FS_LSTAT)) {
+ req->ptr = &req->statbuf;
+ }
}
-int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
- char* path = NULL;
- WRAP_EIO(UV_FS_FSYNC, eio_fsync, fsync, ARGS1(file))
-}
+static void uv__fs_done(struct uv__work* w, int status) {
+ uv_fs_t* req;
+ req = container_of(w, uv_fs_t, work_req);
+ uv__req_unregister(req->loop, req);
-int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
- char* path = NULL;
-#if defined(__FreeBSD__) \
- || (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060)
- /* freebsd and pre-10.6 darwin don't have fdatasync,
- * do a full fsync instead.
- */
- WRAP_EIO(UV_FS_FDATASYNC, eio_fdatasync, fsync, ARGS1(file))
-#else
- WRAP_EIO(UV_FS_FDATASYNC, eio_fdatasync, fdatasync, ARGS1(file))
-#endif
-}
+ if (req->errorno != 0) {
+ req->errorno = uv_translate_sys_error(req->errorno);
+ uv__set_artificial_error(req->loop, req->errorno);
+ }
+ if (status == -UV_ECANCELED) {
+ assert(req->errorno == 0);
+ req->errorno = UV_ECANCELED;
+ uv__set_artificial_error(req->loop, UV_ECANCELED);
+ }
-int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset,
- uv_fs_cb cb) {
- char* path = NULL;
- WRAP_EIO(UV_FS_FTRUNCATE, eio_ftruncate, ftruncate, ARGS2(file, offset))
+ if (req->cb != NULL)
+ req->cb(req);
}
-int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd,
- int64_t in_offset, size_t length, uv_fs_cb cb) {
- char* path = NULL;
- WRAP_EIO(UV_FS_SENDFILE, eio_sendfile, eio_sendfile_sync,
- ARGS4(out_fd, in_fd, in_offset, length))
+int uv_fs_chmod(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int mode,
+ uv_fs_cb cb) {
+ INIT(CHMOD);
+ PATH;
+ req->mode = mode;
+ POST;
}
-int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
- uv_fs_cb cb) {
- WRAP_EIO(UV_FS_CHMOD, eio_chmod, chmod, ARGS2(path, mode))
+int uv_fs_chown(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int uid,
+ int gid,
+ uv_fs_cb cb) {
+ INIT(CHOWN);
+ PATH;
+ req->uid = uid;
+ req->gid = gid;
+ POST;
}
-static int _utime(const char* path, double atime, double mtime) {
- struct utimbuf buf;
- buf.actime = atime;
- buf.modtime = mtime;
- return utime(path, &buf);
+int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+ INIT(CLOSE);
+ req->file = file;
+ POST;
}
-int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
- double mtime, uv_fs_cb cb) {
- WRAP_EIO(UV_FS_UTIME, eio_utime, _utime, ARGS3(path, atime, mtime))
+int uv_fs_fchmod(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ int mode,
+ uv_fs_cb cb) {
+ INIT(FCHMOD);
+ req->file = file;
+ req->mode = mode;
+ POST;
}
-static int _futime(const uv_file fd, double atime, double mtime) {
-#if __linux__
- /* utimesat() has nanosecond resolution but we stick to microseconds
- * for the sake of consistency with other platforms.
- */
- struct timespec ts[2];
- ts[0].tv_sec = atime;
- ts[0].tv_nsec = (unsigned long)(atime * 1000000) % 1000000 * 1000;
- ts[1].tv_sec = mtime;
- ts[1].tv_nsec = (unsigned long)(mtime * 1000000) % 1000000 * 1000;
- return uv__utimesat(fd, NULL, ts, 0);
-#elif HAVE_FUTIMES
- struct timeval tv[2];
- tv[0].tv_sec = atime;
- tv[0].tv_usec = (unsigned long)(atime * 1000000) % 1000000;
- tv[1].tv_sec = mtime;
- tv[1].tv_usec = (unsigned long)(mtime * 1000000) % 1000000;
- return futimes(fd, tv);
-#else /* !HAVE_FUTIMES */
- errno = ENOSYS;
- return -1;
-#endif
+int uv_fs_fchown(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ int uid,
+ int gid,
+ uv_fs_cb cb) {
+ INIT(FCHOWN);
+ req->file = file;
+ req->uid = uid;
+ req->gid = gid;
+ POST;
}
-int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
- double mtime, uv_fs_cb cb) {
- const char* path = NULL;
- WRAP_EIO(UV_FS_FUTIME, eio_futime, _futime, ARGS3(file, atime, mtime))
+int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+ INIT(FDATASYNC);
+ req->file = file;
+ POST;
}
-int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
- char* pathdup;
- int pathlen;
-
- uv_fs_req_init(loop, req, UV_FS_LSTAT, path, cb);
+int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+ INIT(FSTAT);
+ req->file = file;
+ POST;
+}
- /* TODO do this without duplicating the string. */
- /* TODO security */
- pathdup = strdup(path);
- pathlen = strlen(path);
- if (pathlen > 0 && path[pathlen - 1] == '\\') {
- /* TODO do not modify input string */
- pathdup[pathlen - 1] = '\0';
- }
+int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+ INIT(FSYNC);
+ req->file = file;
+ POST;
+}
- if (cb) {
- /* async */
- req->eio = eio_lstat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
- free(pathdup);
+int uv_fs_ftruncate(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ int64_t off,
+ uv_fs_cb cb) {
+ INIT(FTRUNCATE);
+ req->file = file;
+ req->off = off;
+ POST;
+}
- if (!req->eio) {
- uv__set_sys_error(loop, ENOMEM);
- return -1;
- }
- } else {
- /* sync */
- req->result = lstat(pathdup, &req->statbuf);
+int uv_fs_futime(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ double atime,
+ double mtime,
+ uv_fs_cb cb) {
+ INIT(FUTIME);
+ req->file = file;
+ req->atime = atime;
+ req->mtime = mtime;
+ POST;
+}
- free(pathdup);
- if (req->result < 0) {
- uv__set_sys_error(loop, errno);
- return -1;
- }
+int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ INIT(LSTAT);
+ PATH;
+ POST;
+}
- req->ptr = &req->statbuf;
- return req->result;
- }
- return 0;
+int uv_fs_link(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ uv_fs_cb cb) {
+ INIT(LINK);
+ PATH2;
+ POST;
}
-int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
- const char* new_path, uv_fs_cb cb) {
- WRAP_EIO(UV_FS_LINK, eio_link, link, ARGS2(path, new_path))
+int uv_fs_mkdir(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int mode,
+ uv_fs_cb cb) {
+ INIT(MKDIR);
+ PATH;
+ req->mode = mode;
+ POST;
}
-int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
- const char* new_path, int flags, uv_fs_cb cb) {
- WRAP_EIO(UV_FS_SYMLINK, eio_symlink, symlink, ARGS2(path, new_path))
+int uv_fs_open(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int flags,
+ int mode,
+ uv_fs_cb cb) {
+ INIT(OPEN);
+ PATH;
+ req->flags = flags;
+ req->mode = mode;
+ POST;
}
-int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
- uv_fs_cb cb) {
- ssize_t size;
- char* buf;
+int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
+ uv_file file,
+ void* buf,
+ size_t len,
+ int64_t off,
+ uv_fs_cb cb) {
+ INIT(READ);
+ req->file = file;
+ req->buf = buf;
+ req->len = len;
+ req->off = off;
+ POST;
+}
- uv_fs_req_init(loop, req, UV_FS_READLINK, path, cb);
- if (cb) {
- if ((req->eio = eio_readlink(path, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel))) {
- return 0;
- } else {
- uv__set_sys_error(loop, ENOMEM);
- return -1;
- }
- } else {
- /* pathconf(_PC_PATH_MAX) may return -1 to signify that path
- * lengths have no upper limit or aren't suitable for malloc'ing.
- */
- if ((size = pathconf(path, _PC_PATH_MAX)) == -1) {
-#if defined(PATH_MAX)
- size = PATH_MAX;
-#else
- size = 4096;
-#endif
- }
+int uv_fs_readdir(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int flags,
+ uv_fs_cb cb) {
+ INIT(READDIR);
+ PATH;
+ req->flags = flags;
+ POST;
+}
- if ((buf = malloc(size + 1)) == NULL) {
- uv__set_sys_error(loop, ENOMEM);
- return -1;
- }
- if ((size = readlink(path, buf, size)) == -1) {
- req->errorno = errno;
- req->result = -1;
- free(buf);
- } else {
- /* Cannot conceivably fail since it shrinks the buffer. */
- buf = realloc(buf, size + 1);
- buf[size] = '\0';
- req->result = 0;
- req->ptr = buf;
- }
+int uv_fs_readlink(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_fs_cb cb) {
+ INIT(READLINK);
+ PATH;
+ POST;
+}
- return req->result;
- }
- assert(0 && "unreachable");
+int uv_fs_rename(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ uv_fs_cb cb) {
+ INIT(RENAME);
+ PATH2;
+ POST;
}
-int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
- uv_fs_cb cb) {
- char* path = NULL;
- WRAP_EIO(UV_FS_FCHMOD, eio_fchmod, fchmod, ARGS2(file, mode))
+int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ INIT(RMDIR);
+ PATH;
+ POST;
}
-int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
- int gid, uv_fs_cb cb) {
- WRAP_EIO(UV_FS_CHOWN, eio_chown, chown, ARGS3(path, uid, gid))
+int uv_fs_sendfile(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file out_fd,
+ uv_file in_fd,
+ int64_t off,
+ size_t len,
+ uv_fs_cb cb) {
+ INIT(SENDFILE);
+ req->flags = in_fd; /* hack */
+ req->file = out_fd;
+ req->off = off;
+ req->len = len;
+ POST;
}
-int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid, int gid,
- uv_fs_cb cb) {
- char* path = NULL;
- WRAP_EIO(UV_FS_FCHOWN, eio_fchown, fchown, ARGS3(file, uid, gid))
+int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ INIT(STAT);
+ PATH;
+ POST;
}
-static void uv__work(eio_req* eio) {
- uv_work_t* req = eio->data;
- if (req->work_cb) {
- req->work_cb(req);
- }
+int uv_fs_symlink(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ int flags,
+ uv_fs_cb cb) {
+ INIT(SYMLINK);
+ PATH2;
+ req->flags = flags;
+ POST;
}
-static int uv__after_work(eio_req *eio) {
- uv_work_t* req = eio->data;
- uv__req_unregister(req->loop, req);
- if (req->after_work_cb) {
- req->after_work_cb(req);
- }
- return 0;
+int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ INIT(UNLINK);
+ PATH;
+ POST;
}
-int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
- uv_after_work_cb after_work_cb) {
- void* data = req->data;
+int uv_fs_utime(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ double atime,
+ double mtime,
+ uv_fs_cb cb) {
+ INIT(UTIME);
+ PATH;
+ req->atime = atime;
+ req->mtime = mtime;
+ POST;
+}
- uv_eio_init(loop);
- uv__req_init(loop, req, UV_WORK);
- req->loop = loop;
- req->data = data;
- req->work_cb = work_cb;
- req->after_work_cb = after_work_cb;
+int uv_fs_write(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ void* buf,
+ size_t len,
+ int64_t off,
+ uv_fs_cb cb) {
+ INIT(WRITE);
+ req->file = file;
+ req->buf = buf;
+ req->len = len;
+ req->off = off;
+ POST;
+}
- req->eio = eio_custom(uv__work,
- EIO_PRI_DEFAULT,
- uv__after_work,
- req,
- &loop->uv_eio_channel);
- if (!req->eio) {
- uv__set_sys_error(loop, ENOMEM);
- return -1;
- }
+void uv_fs_req_cleanup(uv_fs_t* req) {
+ free((void*) req->path);
+ req->path = NULL;
+ req->new_path = NULL;
- return 0;
+ if (req->ptr != &req->statbuf)
+ free(req->ptr);
+ req->ptr = NULL;
}
diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c
new file mode 100644
index 000000000..b6d274675
--- /dev/null
+++ b/deps/uv/src/unix/fsevents.c
@@ -0,0 +1,299 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#if TARGET_OS_IPHONE
+
+/* iOS (currently) doesn't provide the FSEvents-API (nor CoreServices) */
+
+int uv__fsevents_init(uv_fs_event_t* handle) {
+ return 0;
+}
+
+
+int uv__fsevents_close(uv_fs_event_t* handle) {
+ return 0;
+}
+
+#else /* TARGET_OS_IPHONE */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <CoreServices/CoreServices.h>
+
+typedef struct uv__fsevents_event_s uv__fsevents_event_t;
+
+struct uv__fsevents_event_s {
+ int events;
+ ngx_queue_t member;
+ char path[1];
+};
+
+
+#define UV__FSEVENTS_WALK(handle, block) \
+ { \
+ ngx_queue_t* curr; \
+ ngx_queue_t split_head; \
+ uv__fsevents_event_t* event; \
+ uv_mutex_lock(&(handle)->cf_mutex); \
+ ngx_queue_init(&split_head); \
+ if (!ngx_queue_empty(&(handle)->cf_events)) { \
+ ngx_queue_t* split_pos = ngx_queue_next(&(handle)->cf_events); \
+ ngx_queue_split(&(handle)->cf_events, split_pos, &split_head); \
+ } \
+ uv_mutex_unlock(&(handle)->cf_mutex); \
+ while (!ngx_queue_empty(&split_head)) { \
+ curr = ngx_queue_head(&split_head); \
+ /* Invoke callback */ \
+ event = ngx_queue_data(curr, uv__fsevents_event_t, member); \
+ ngx_queue_remove(curr); \
+ /* Invoke block code, but only if handle wasn't closed */ \
+ if (((handle)->flags & (UV_CLOSING | UV_CLOSED)) == 0) \
+ block \
+ /* Free allocated data */ \
+ free(event); \
+ } \
+ }
+
+
+void uv__fsevents_cb(uv_async_t* cb, int status) {
+ uv_fs_event_t* handle;
+
+ handle = cb->data;
+
+ UV__FSEVENTS_WALK(handle, {
+ if (handle->event_watcher.fd != -1)
+ handle->cb(handle, event->path[0] ? event->path : NULL, event->events, 0);
+ });
+
+ if ((handle->flags & (UV_CLOSING | UV_CLOSED)) == 0 &&
+ handle->event_watcher.fd == -1) {
+ uv__fsevents_close(handle);
+ }
+}
+
+
+void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
+ void* info,
+ size_t numEvents,
+ void* eventPaths,
+ const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[]) {
+ size_t i;
+ int len;
+ char** paths;
+ char* path;
+ char* pos;
+ uv_fs_event_t* handle;
+ uv__fsevents_event_t* event;
+ ngx_queue_t add_list;
+ int kFSEventsModified;
+ int kFSEventsRenamed;
+
+ kFSEventsModified = kFSEventStreamEventFlagItemFinderInfoMod |
+ kFSEventStreamEventFlagItemModified |
+ kFSEventStreamEventFlagItemInodeMetaMod |
+ kFSEventStreamEventFlagItemChangeOwner |
+ kFSEventStreamEventFlagItemXattrMod;
+ kFSEventsRenamed = kFSEventStreamEventFlagItemCreated |
+ kFSEventStreamEventFlagItemRemoved |
+ kFSEventStreamEventFlagItemRenamed;
+
+ handle = info;
+ paths = eventPaths;
+ ngx_queue_init(&add_list);
+
+ for (i = 0; i < numEvents; i++) {
+ /* Ignore system events */
+ if (eventFlags[i] & (kFSEventStreamEventFlagUserDropped |
+ kFSEventStreamEventFlagKernelDropped |
+ kFSEventStreamEventFlagEventIdsWrapped |
+ kFSEventStreamEventFlagHistoryDone |
+ kFSEventStreamEventFlagMount |
+ kFSEventStreamEventFlagUnmount |
+ kFSEventStreamEventFlagRootChanged)) {
+ continue;
+ }
+
+ /* TODO: Report errors */
+ path = paths[i];
+ len = strlen(path);
+
+ /* Remove absolute path prefix */
+ if (strstr(path, handle->realpath) == path) {
+ path += handle->realpath_len;
+ len -= handle->realpath_len;
+
+ /* Skip back slash */
+ if (*path != 0) {
+ path++;
+ len--;
+ }
+ }
+
+#ifdef MAC_OS_X_VERSION_10_7
+ /* Ignore events with path equal to directory itself */
+ if (len == 0)
+ continue;
+#endif /* MAC_OS_X_VERSION_10_7 */
+
+ /* Do not emit events from subdirectories (without option set) */
+ pos = strchr(path, '/');
+ if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 &&
+ pos != NULL &&
+ pos != path + 1)
+ continue;
+
+#ifndef MAC_OS_X_VERSION_10_7
+ path = "";
+ len = 0;
+#endif /* MAC_OS_X_VERSION_10_7 */
+
+ event = malloc(sizeof(*event) + len);
+ if (event == NULL)
+ break;
+
+ memcpy(event->path, path, len + 1);
+
+ if ((eventFlags[i] & kFSEventsModified) != 0 &&
+ (eventFlags[i] & kFSEventsRenamed) == 0)
+ event->events = UV_CHANGE;
+ else
+ event->events = UV_RENAME;
+
+ ngx_queue_insert_tail(&add_list, &event->member);
+ }
+ uv_mutex_lock(&handle->cf_mutex);
+ ngx_queue_add(&handle->cf_events, &add_list);
+ uv_mutex_unlock(&handle->cf_mutex);
+
+ uv_async_send(handle->cf_cb);
+}
+
+
+void uv__fsevents_schedule(void* arg) {
+ uv_fs_event_t* handle;
+
+ handle = arg;
+ FSEventStreamScheduleWithRunLoop(handle->cf_eventstream,
+ handle->loop->cf_loop,
+ kCFRunLoopDefaultMode);
+ FSEventStreamStart(handle->cf_eventstream);
+ uv_sem_post(&handle->cf_sem);
+}
+
+
+int uv__fsevents_init(uv_fs_event_t* handle) {
+ FSEventStreamContext ctx;
+ FSEventStreamRef ref;
+ CFStringRef path;
+ CFArrayRef paths;
+ CFAbsoluteTime latency;
+ FSEventStreamCreateFlags flags;
+
+ /* Initialize context */
+ ctx.version = 0;
+ ctx.info = handle;
+ ctx.retain = NULL;
+ ctx.release = NULL;
+ ctx.copyDescription = NULL;
+
+ /* Get absolute path to file */
+ handle->realpath = realpath(handle->filename, NULL);
+ if (handle->realpath != NULL)
+ handle->realpath_len = strlen(handle->realpath);
+
+ /* Initialize paths array */
+ path = CFStringCreateWithCString(NULL,
+ handle->filename,
+ CFStringGetSystemEncoding());
+ paths = CFArrayCreate(NULL, (const void**)&path, 1, NULL);
+
+ latency = 0.15;
+
+ /* Set appropriate flags */
+ flags = kFSEventStreamCreateFlagFileEvents;
+
+ ref = FSEventStreamCreate(NULL,
+ &uv__fsevents_event_cb,
+ &ctx,
+ paths,
+ kFSEventStreamEventIdSinceNow,
+ latency,
+ flags);
+ handle->cf_eventstream = ref;
+
+ /*
+ * Events will occur in other thread.
+ * Initialize callback for getting them back into event loop's thread
+ */
+ handle->cf_cb = malloc(sizeof(*handle->cf_cb));
+ if (handle->cf_cb == NULL)
+ return uv__set_sys_error(handle->loop, ENOMEM);
+
+ handle->cf_cb->data = handle;
+ uv_async_init(handle->loop, handle->cf_cb, uv__fsevents_cb);
+ handle->cf_cb->flags |= UV__HANDLE_INTERNAL;
+ uv_unref((uv_handle_t*) handle->cf_cb);
+
+ uv_mutex_init(&handle->cf_mutex);
+ uv_sem_init(&handle->cf_sem, 0);
+ ngx_queue_init(&handle->cf_events);
+
+ uv__cf_loop_signal(handle->loop, uv__fsevents_schedule, handle);
+
+ return 0;
+}
+
+
+int uv__fsevents_close(uv_fs_event_t* handle) {
+ if (handle->cf_eventstream == NULL)
+ return -1;
+
+ /* Ensure that event stream was scheduled */
+ uv_sem_wait(&handle->cf_sem);
+
+ /* Stop emitting events */
+ FSEventStreamStop(handle->cf_eventstream);
+
+ /* Release stream */
+ FSEventStreamInvalidate(handle->cf_eventstream);
+ FSEventStreamRelease(handle->cf_eventstream);
+ handle->cf_eventstream = NULL;
+
+ uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) free);
+
+ /* Free data in queue */
+ UV__FSEVENTS_WALK(handle, {
+ /* NOP */
+ })
+
+ uv_mutex_destroy(&handle->cf_mutex);
+ uv_sem_destroy(&handle->cf_sem);
+ free(handle->realpath);
+ handle->realpath = NULL;
+ handle->realpath_len = 0;
+
+ return 0;
+}
+
+#endif /* TARGET_OS_IPHONE */
diff --git a/deps/uv/src/unix/getaddrinfo.c b/deps/uv/src/unix/getaddrinfo.c
new file mode 100644
index 000000000..283d295f5
--- /dev/null
+++ b/deps/uv/src/unix/getaddrinfo.c
@@ -0,0 +1,159 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <errno.h>
+#include <stddef.h> /* NULL */
+#include <stdlib.h>
+#include <string.h>
+
+
+static void uv__getaddrinfo_work(struct uv__work* w) {
+ uv_getaddrinfo_t* req = container_of(w, uv_getaddrinfo_t, work_req);
+
+ req->retcode = getaddrinfo(req->hostname,
+ req->service,
+ req->hints,
+ &req->res);
+}
+
+
+static void uv__getaddrinfo_done(struct uv__work* w, int status) {
+ uv_getaddrinfo_t* req = container_of(w, uv_getaddrinfo_t, work_req);
+ struct addrinfo *res = req->res;
+#if defined(__sun)
+ size_t hostlen;
+
+ if (req->hostname)
+ hostlen = strlen(req->hostname);
+ else
+ hostlen = 0;
+#endif
+
+ req->res = NULL;
+
+ uv__req_unregister(req->loop, req);
+
+ /* see initialization in uv_getaddrinfo() */
+ if (req->hints)
+ free(req->hints);
+ else if (req->service)
+ free(req->service);
+ else if (req->hostname)
+ free(req->hostname);
+ else
+ assert(0);
+
+ req->hints = NULL;
+ req->service = NULL;
+ req->hostname = NULL;
+
+ if (req->retcode == 0) {
+ /* OK */
+#if defined(EAI_NODATA) /* FreeBSD deprecated EAI_NODATA */
+ } else if (req->retcode == EAI_NONAME || req->retcode == EAI_NODATA) {
+#else
+ } else if (req->retcode == EAI_NONAME) {
+#endif
+ uv__set_sys_error(req->loop, ENOENT); /* FIXME compatibility hack */
+#if defined(__sun)
+ } else if (req->retcode == EAI_MEMORY && hostlen >= MAXHOSTNAMELEN) {
+ uv__set_sys_error(req->loop, ENOENT);
+#endif
+ } else {
+ req->loop->last_err.code = UV_EADDRINFO;
+ req->loop->last_err.sys_errno_ = req->retcode;
+ }
+
+ if (status == -UV_ECANCELED) {
+ assert(req->retcode == 0);
+ req->retcode = UV_ECANCELED;
+ uv__set_artificial_error(req->loop, UV_ECANCELED);
+ }
+
+ req->cb(req, req->retcode, res);
+}
+
+
+int uv_getaddrinfo(uv_loop_t* loop,
+ uv_getaddrinfo_t* req,
+ uv_getaddrinfo_cb cb,
+ const char* hostname,
+ const char* service,
+ const struct addrinfo* hints) {
+ size_t hostname_len;
+ size_t service_len;
+ size_t hints_len;
+ size_t len;
+ char* buf;
+
+ if (req == NULL || cb == NULL || (hostname == NULL && service == NULL))
+ return uv__set_artificial_error(loop, UV_EINVAL);
+
+ hostname_len = hostname ? strlen(hostname) + 1 : 0;
+ service_len = service ? strlen(service) + 1 : 0;
+ hints_len = hints ? sizeof(*hints) : 0;
+ buf = malloc(hostname_len + service_len + hints_len);
+
+ if (buf == NULL)
+ return uv__set_artificial_error(loop, UV_ENOMEM);
+
+ uv__req_init(loop, req, UV_GETADDRINFO);
+ req->loop = loop;
+ req->cb = cb;
+ req->res = NULL;
+ req->hints = NULL;
+ req->service = NULL;
+ req->hostname = NULL;
+ req->retcode = 0;
+
+ /* order matters, see uv_getaddrinfo_done() */
+ len = 0;
+
+ if (hints) {
+ req->hints = memcpy(buf + len, hints, sizeof(*hints));
+ len += sizeof(*hints);
+ }
+
+ if (service) {
+ req->service = memcpy(buf + len, service, service_len);
+ len += service_len;
+ }
+
+ if (hostname) {
+ req->hostname = memcpy(buf + len, hostname, hostname_len);
+ len += hostname_len;
+ }
+
+ uv__work_submit(loop,
+ &req->work_req,
+ uv__getaddrinfo_work,
+ uv__getaddrinfo_done);
+
+ return 0;
+}
+
+
+void uv_freeaddrinfo(struct addrinfo* ai) {
+ if (ai)
+ freeaddrinfo(ai);
+}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index dd46c95ed..7d08c1dac 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -23,45 +23,30 @@
#define UV_UNIX_INTERNAL_H_
#include "uv-common.h"
-#include "uv-eio.h"
#include <assert.h>
#include <stdlib.h> /* abort */
-#if __STRICT_ANSI__
+#if defined(__STRICT_ANSI__)
# define inline __inline
#endif
-#undef HAVE_FUTIMES
-#undef HAVE_KQUEUE
-#undef HAVE_PORTS_FS
-
-#if __linux__
-# include "linux/syscalls.h"
-# define HAVE_FUTIMES 1 /* emulated with utimesat() */
+#if defined(__linux__)
+# include "linux-syscalls.h"
#endif /* __linux__ */
#if defined(__sun)
# include <sys/port.h>
# include <port.h>
-# ifdef PORT_SOURCE_FILE
-# define HAVE_PORTS_FS 1
-# endif
-# define HAVE_FUTIMES 1
# define futimes(fd, tv) futimesat(fd, (void*)0, tv)
#endif /* __sun */
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun)
-# define HAVE_FUTIMES 1
+#if defined(__APPLE__) && !TARGET_OS_IPHONE
+# include <CoreServices/CoreServices.h>
#endif
-/* FIXME exact copy of the #ifdef guard in uv-unix.h */
-#if defined(__APPLE__) \
- || defined(__FreeBSD__) \
- || defined(__OpenBSD__) \
- || defined(__NetBSD__)
-# define HAVE_KQUEUE 1
-#endif
+#define ACCESS_ONCE(type, var) \
+ (*(volatile type*) &(var))
#define UNREACHABLE() \
do { \
@@ -78,11 +63,37 @@
} \
while (0)
-#define UV__IO_READ EV_READ
-#define UV__IO_WRITE EV_WRITE
-#define UV__IO_ERROR EV_ERROR
+#if defined(__linux__)
+# define UV__POLLIN UV__EPOLLIN
+# define UV__POLLOUT UV__EPOLLOUT
+# define UV__POLLERR UV__EPOLLERR
+# define UV__POLLHUP UV__EPOLLHUP
+#endif
+
+#if defined(__sun)
+# define UV__POLLIN POLLIN
+# define UV__POLLOUT POLLOUT
+# define UV__POLLERR POLLERR
+# define UV__POLLHUP POLLHUP
+#endif
+
+#ifndef UV__POLLIN
+# define UV__POLLIN 1
+#endif
+
+#ifndef UV__POLLOUT
+# define UV__POLLOUT 2
+#endif
-/* flags */
+#ifndef UV__POLLERR
+# define UV__POLLERR 4
+#endif
+
+#ifndef UV__POLLHUP
+# define UV__POLLHUP 8
+#endif
+
+/* handle flags */
enum {
UV_CLOSING = 0x01, /* uv_close() called but not finished. */
UV_CLOSED = 0x02, /* close(2) finished. */
@@ -93,33 +104,31 @@ enum {
UV_STREAM_WRITABLE = 0x40, /* The stream is writable */
UV_STREAM_BLOCKING = 0x80, /* Synchronous writes. */
UV_TCP_NODELAY = 0x100, /* Disable Nagle. */
- UV_TCP_KEEPALIVE = 0x200 /* Turn on keep-alive. */
+ UV_TCP_KEEPALIVE = 0x200, /* Turn on keep-alive. */
+ UV_TCP_SINGLE_ACCEPT = 0x400 /* Only accept() when idle. */
};
-inline static void uv__req_init(uv_loop_t* loop,
- uv_req_t* req,
- uv_req_type type) {
- loop->counters.req_init++;
- req->type = type;
- uv__req_register(loop, req);
-}
-#define uv__req_init(loop, req, type) \
- uv__req_init((loop), (uv_req_t*)(req), (type))
-
/* core */
void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle, uv_handle_type type);
int uv__nonblock(int fd, int set);
int uv__cloexec(int fd, int set);
int uv__socket(int domain, int type, int protocol);
int uv__dup(int fd);
-int uv_async_stop(uv_async_t* handle);
-
-void uv__io_init(uv__io_t* handle, uv__io_cb cb, int fd, int events);
-void uv__io_set(uv__io_t* handle, uv__io_cb cb, int fd, int events);
-void uv__io_start(uv_loop_t* loop, uv__io_t* handle);
-void uv__io_stop(uv_loop_t* loop, uv__io_t* handle);
-void uv__io_feed(uv_loop_t* loop, uv__io_t* handle, int event);
-int uv__io_active(uv__io_t* handle);
+void uv__make_close_pending(uv_handle_t* handle);
+
+void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
+void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
+void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events);
+void uv__io_close(uv_loop_t* loop, uv__io_t* w);
+void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
+int uv__io_active(const uv__io_t* w, unsigned int events);
+void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
+
+/* async */
+void uv__async_send(struct uv__async* wa);
+void uv__async_init(struct uv__async* wa);
+int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb);
+void uv__async_stop(uv_loop_t* loop, struct uv__async* wa);
/* loop */
int uv__loop_init(uv_loop_t* loop, int default_loop);
@@ -137,20 +146,38 @@ void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream,
uv_handle_type type);
int uv__stream_open(uv_stream_t*, int fd, int flags);
void uv__stream_destroy(uv_stream_t* stream);
-void uv__server_io(uv_loop_t* loop, uv__io_t* watcher, int events);
+void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
int uv__accept(int sockfd);
/* tcp */
int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
-int uv__tcp_nodelay(uv_tcp_t* handle, int enable);
-int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay);
+int uv__tcp_nodelay(int fd, int on);
+int uv__tcp_keepalive(int fd, int on, unsigned int delay);
/* pipe */
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
/* timer */
void uv__run_timers(uv_loop_t* loop);
-unsigned int uv__next_timeout(uv_loop_t* loop);
+int uv__next_timeout(const uv_loop_t* loop);
+
+/* signal */
+void uv__signal_close(uv_signal_t* handle);
+void uv__signal_global_once_init(void);
+void uv__signal_loop_cleanup(uv_loop_t* loop);
+
+/* thread pool */
+void uv__work_submit(uv_loop_t* loop,
+ struct uv__work *w,
+ void (*work)(struct uv__work *w),
+ void (*done)(struct uv__work *w, int status));
+void uv__work_done(uv_async_t* handle, int status);
+
+/* platform specific */
+uint64_t uv__hrtime(void);
+int uv__kqueue_init(uv_loop_t* loop);
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop);
+void uv__platform_loop_delete(uv_loop_t* loop);
/* various */
void uv__async_close(uv_async_t* handle);
@@ -162,10 +189,18 @@ void uv__poll_close(uv_poll_t* handle);
void uv__prepare_close(uv_prepare_t* handle);
void uv__process_close(uv_process_t* handle);
void uv__stream_close(uv_stream_t* handle);
+void uv__tcp_close(uv_tcp_t* handle);
void uv__timer_close(uv_timer_t* handle);
void uv__udp_close(uv_udp_t* handle);
void uv__udp_finish_close(uv_udp_t* handle);
+#if defined(__APPLE__)
+int uv___stream_fd(uv_stream_t* handle);
+#define uv__stream_fd(handle) (uv___stream_fd((uv_stream_t*) (handle)))
+#else
+#define uv__stream_fd(handle) ((handle)->io_watcher.fd)
+#endif /* defined(__APPLE__) */
+
#ifdef UV__O_NONBLOCK
# define UV__F_NONBLOCK UV__O_NONBLOCK
#else
@@ -175,4 +210,45 @@ void uv__udp_finish_close(uv_udp_t* handle);
int uv__make_socketpair(int fds[2], int flags);
int uv__make_pipe(int fds[2], int flags);
+#if defined(__APPLE__)
+typedef void (*cf_loop_signal_cb)(void*);
+
+void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg);
+
+int uv__fsevents_init(uv_fs_event_t* handle);
+int uv__fsevents_close(uv_fs_event_t* handle);
+
+/* OSX < 10.7 has no file events, polyfill them */
+#ifndef MAC_OS_X_VERSION_10_7
+
+static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
+static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
+static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;
+static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400;
+static const int kFSEventStreamEventFlagItemRenamed = 0x00000800;
+static const int kFSEventStreamEventFlagItemModified = 0x00001000;
+static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000;
+static const int kFSEventStreamEventFlagItemChangeOwner = 0x00004000;
+static const int kFSEventStreamEventFlagItemXattrMod = 0x00008000;
+static const int kFSEventStreamEventFlagItemIsFile = 0x00010000;
+static const int kFSEventStreamEventFlagItemIsDir = 0x00020000;
+static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
+
+#endif /* __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070 */
+
+#endif /* defined(__APPLE__) */
+
+__attribute__((unused))
+static void uv__req_init(uv_loop_t* loop, uv_req_t* req, uv_req_type type) {
+ req->type = type;
+ uv__req_register(loop, req);
+}
+#define uv__req_init(loop, req, type) \
+ uv__req_init((loop), (uv_req_t*)(req), (type))
+
+__attribute__((unused))
+static void uv__update_time(uv_loop_t* loop) {
+ loop->time = uv__hrtime() / 1000000;
+}
+
#endif /* UV_UNIX_INTERNAL_H_ */
diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c
index ee1bbd174..378903a62 100644
--- a/deps/uv/src/unix/kqueue.c
+++ b/deps/uv/src/unix/kqueue.c
@@ -29,57 +29,257 @@
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/event.h>
+#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
-static void uv__fs_event(EV_P_ ev_io* w, int revents);
+static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags);
-static void uv__fs_event_start(uv_fs_event_t* handle) {
- ev_io_init(&handle->event_watcher,
- uv__fs_event,
- handle->fd,
- EV_LIBUV_KQUEUE_HACK);
- ev_io_start(handle->loop->ev, &handle->event_watcher);
+int uv__kqueue_init(uv_loop_t* loop) {
+ loop->backend_fd = kqueue();
+
+ if (loop->backend_fd == -1)
+ return -1;
+
+ uv__cloexec(loop->backend_fd, 1);
+
+ return 0;
}
-static void uv__fs_event_stop(uv_fs_event_t* handle) {
- ev_io_stop(handle->loop->ev, &handle->event_watcher);
+void uv__io_poll(uv_loop_t* loop, int timeout) {
+ struct kevent events[1024];
+ struct kevent* ev;
+ struct timespec spec;
+ unsigned int nevents;
+ unsigned int revents;
+ ngx_queue_t* q;
+ uint64_t base;
+ uint64_t diff;
+ uv__io_t* w;
+ int filter;
+ int fflags;
+ int count;
+ int nfds;
+ int fd;
+ int op;
+ int i;
+
+ if (loop->nfds == 0) {
+ assert(ngx_queue_empty(&loop->watcher_queue));
+ return;
+ }
+
+ nevents = 0;
+
+ while (!ngx_queue_empty(&loop->watcher_queue)) {
+ q = ngx_queue_head(&loop->watcher_queue);
+ ngx_queue_remove(q);
+ ngx_queue_init(q);
+
+ w = ngx_queue_data(q, uv__io_t, watcher_queue);
+ assert(w->pevents != 0);
+ assert(w->fd >= 0);
+ assert(w->fd < (int) loop->nwatchers);
+
+ if ((w->events & UV__POLLIN) == 0 && (w->pevents & UV__POLLIN) != 0) {
+ filter = EVFILT_READ;
+ fflags = 0;
+ op = EV_ADD;
+
+ if (w->cb == uv__fs_event) {
+ filter = EVFILT_VNODE;
+ fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME
+ | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
+ op = EV_ADD | EV_ONESHOT; /* Stop the event from firing repeatedly. */
+ }
+
+ EV_SET(events + nevents, w->fd, filter, op, fflags, 0, 0);
+
+ if (++nevents == ARRAY_SIZE(events)) {
+ if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
+ abort();
+ nevents = 0;
+ }
+ }
+
+ if ((w->events & UV__POLLOUT) == 0 && (w->pevents & UV__POLLOUT) != 0) {
+ EV_SET(events + nevents, w->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
+
+ if (++nevents == ARRAY_SIZE(events)) {
+ if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
+ abort();
+ nevents = 0;
+ }
+ }
+
+ w->events = w->pevents;
+ }
+
+ assert(timeout >= -1);
+ base = loop->time;
+ count = 48; /* Benchmarks suggest this gives the best throughput. */
+
+ for (;; nevents = 0) {
+ if (timeout != -1) {
+ spec.tv_sec = timeout / 1000;
+ spec.tv_nsec = (timeout % 1000) * 1000000;
+ }
+
+ nfds = kevent(loop->backend_fd,
+ events,
+ nevents,
+ events,
+ ARRAY_SIZE(events),
+ timeout == -1 ? NULL : &spec);
+
+ /* Update loop->time unconditionally. It's tempting to skip the update when
+ * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
+ * operating system didn't reschedule our process while in the syscall.
+ */
+ SAVE_ERRNO(uv__update_time(loop));
+
+ if (nfds == 0) {
+ assert(timeout != -1);
+ return;
+ }
+
+ if (nfds == -1) {
+ if (errno != EINTR)
+ abort();
+
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+ /* Interrupted by a signal. Update timeout and poll again. */
+ goto update_timeout;
+ }
+
+ nevents = 0;
+
+ for (i = 0; i < nfds; i++) {
+ ev = events + i;
+ fd = ev->ident;
+ w = loop->watchers[fd];
+
+ if (w == NULL) {
+ /* File descriptor that we've stopped watching, disarm it. */
+ /* TODO batch up */
+ struct kevent events[1];
+
+ EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
+ if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
+ if (errno != EBADF && errno != ENOENT)
+ abort();
+
+ continue;
+ }
+
+ if (ev->filter == EVFILT_VNODE) {
+ assert(w->events == UV__POLLIN);
+ assert(w->pevents == UV__POLLIN);
+ w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */
+ nevents++;
+ continue;
+ }
+
+ revents = 0;
+
+ if (ev->filter == EVFILT_READ) {
+ if (w->events & UV__POLLIN) {
+ revents |= UV__POLLIN;
+ w->rcount = ev->data;
+ } else {
+ /* TODO batch up */
+ struct kevent events[1];
+ EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
+ if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
+ if (errno != ENOENT)
+ abort();
+ }
+ }
+
+ if (ev->filter == EVFILT_WRITE) {
+ if (w->events & UV__POLLOUT) {
+ revents |= UV__POLLOUT;
+ w->wcount = ev->data;
+ } else {
+ /* TODO batch up */
+ struct kevent events[1];
+ EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
+ if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
+ if (errno != ENOENT)
+ abort();
+ }
+ }
+
+ if (ev->flags & EV_ERROR)
+ revents |= UV__POLLERR;
+
+ if (revents == 0)
+ continue;
+
+ w->cb(loop, w, revents);
+ nevents++;
+ }
+
+ if (nevents != 0) {
+ if (nfds == ARRAY_SIZE(events) && --count != 0) {
+ /* Poll for more events but don't block this time. */
+ timeout = 0;
+ continue;
+ }
+ return;
+ }
+
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+update_timeout:
+ assert(timeout > 0);
+
+ diff = loop->time - base;
+ if (diff >= (uint64_t) timeout)
+ return;
+
+ timeout -= diff;
+ }
}
-static void uv__fs_event(EV_P_ ev_io* w, int revents) {
+static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
uv_fs_event_t* handle;
+ struct kevent ev;
int events;
- assert(revents == EV_LIBUV_KQUEUE_HACK);
-
handle = container_of(w, uv_fs_event_t, event_watcher);
- if (handle->fflags & (NOTE_ATTRIB | NOTE_EXTEND))
+ if (fflags & (NOTE_ATTRIB | NOTE_EXTEND))
events = UV_CHANGE;
else
events = UV_RENAME;
handle->cb(handle, NULL, events, 0);
- if (handle->fd == -1)
+ if (handle->event_watcher.fd == -1)
return;
- /* File watcher operates in one-shot mode, re-arm it. */
- uv__fs_event_stop(handle);
- uv__fs_event_start(handle);
-}
-
+ /* Watcher operates in one-shot mode, re-arm it. */
+ fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME
+ | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
-/* Called by libev, don't touch. */
-void uv__kqueue_hack(EV_P_ int fflags, ev_io *w) {
- uv_fs_event_t* handle;
+ EV_SET(&ev, w->fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, fflags, 0, 0);
- handle = container_of(w, uv_fs_event_t, event_watcher);
- handle->fflags = fflags;
+ if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
+ abort();
}
@@ -88,13 +288,11 @@ int uv_fs_event_init(uv_loop_t* loop,
const char* filename,
uv_fs_event_cb cb,
int flags) {
+#if defined(__APPLE__)
+ struct stat statbuf;
+#endif /* defined(__APPLE__) */
int fd;
- loop->counters.fs_event_init++;
-
- /* We don't support any flags yet. */
- assert(!flags);
-
/* TODO open asynchronously - but how do we report back errors? */
if ((fd = open(filename, O_RDONLY)) == -1) {
uv__set_sys_error(loop, errno);
@@ -103,20 +301,47 @@ int uv_fs_event_init(uv_loop_t* loop,
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
uv__handle_start(handle); /* FIXME shouldn't start automatically */
+ uv__io_init(&handle->event_watcher, uv__fs_event, fd);
handle->filename = strdup(filename);
- handle->fflags = 0;
handle->cb = cb;
- handle->fd = fd;
- uv__fs_event_start(handle);
+
+#if defined(__APPLE__)
+ /* Nullify field to perform checks later */
+ handle->cf_eventstream = NULL;
+ handle->realpath = NULL;
+ handle->realpath_len = 0;
+ handle->cf_flags = flags;
+
+ if (fstat(fd, &statbuf))
+ goto fallback;
+ /* FSEvents works only with directories */
+ if (!(statbuf.st_mode & S_IFDIR))
+ goto fallback;
+
+ return uv__fsevents_init(handle);
+
+fallback:
+#endif /* defined(__APPLE__) */
+
+ uv__io_start(loop, &handle->event_watcher, UV__POLLIN);
return 0;
}
void uv__fs_event_close(uv_fs_event_t* handle) {
- uv__fs_event_stop(handle);
+#if defined(__APPLE__)
+ if (uv__fsevents_close(handle))
+ uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN);
+#else
+ uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN);
+#endif /* defined(__APPLE__) */
+
uv__handle_stop(handle);
+
free(handle->filename);
- close(handle->fd);
- handle->fd = -1;
+ handle->filename = NULL;
+
+ close(handle->event_watcher.fd);
+ handle->event_watcher.fd = -1;
}
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
new file mode 100644
index 000000000..0b0f58d12
--- /dev/null
+++ b/deps/uv/src/unix/linux-core.c
@@ -0,0 +1,711 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <net/if.h>
+#include <sys/param.h>
+#include <sys/prctl.h>
+#include <sys/sysinfo.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+
+#define HAVE_IFADDRS_H 1
+#ifdef __UCLIBC__
+# if __UCLIBC_MAJOR__ < 0 || __UCLIBC_MINOR__ < 9 || __UCLIBC_SUBLEVEL__ < 32
+# undef HAVE_IFADDRS_H
+# endif
+#endif
+#ifdef HAVE_IFADDRS_H
+# include <ifaddrs.h>
+#endif
+
+#undef NANOSEC
+#define NANOSEC ((uint64_t) 1e9)
+
+/* This is rather annoying: CLOCK_BOOTTIME lives in <linux/time.h> but we can't
+ * include that file because it conflicts with <time.h>. We'll just have to
+ * define it ourselves.
+ */
+#ifndef CLOCK_BOOTTIME
+# define CLOCK_BOOTTIME 7
+#endif
+
+static void read_models(unsigned int numcpus, uv_cpu_info_t* ci);
+static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
+static void read_times(unsigned int numcpus, uv_cpu_info_t* ci);
+static unsigned long read_cpufreq(unsigned int cpunum);
+
+
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ int fd;
+
+ fd = uv__epoll_create1(UV__EPOLL_CLOEXEC);
+
+ /* epoll_create1() can fail either because it's not implemented (old kernel)
+ * or because it doesn't understand the EPOLL_CLOEXEC flag.
+ */
+ if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
+ fd = uv__epoll_create(256);
+
+ if (fd != -1)
+ uv__cloexec(fd, 1);
+ }
+
+ loop->backend_fd = fd;
+ loop->inotify_fd = -1;
+ loop->inotify_watchers = NULL;
+
+ if (fd == -1)
+ return -1;
+
+ return 0;
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+ if (loop->inotify_fd == -1) return;
+ uv__io_stop(loop, &loop->inotify_read_watcher, UV__POLLIN);
+ close(loop->inotify_fd);
+ loop->inotify_fd = -1;
+}
+
+
+void uv__io_poll(uv_loop_t* loop, int timeout) {
+ struct uv__epoll_event events[1024];
+ struct uv__epoll_event* pe;
+ struct uv__epoll_event e;
+ ngx_queue_t* q;
+ uv__io_t* w;
+ uint64_t base;
+ uint64_t diff;
+ int nevents;
+ int count;
+ int nfds;
+ int fd;
+ int op;
+ int i;
+
+ if (loop->nfds == 0) {
+ assert(ngx_queue_empty(&loop->watcher_queue));
+ return;
+ }
+
+ while (!ngx_queue_empty(&loop->watcher_queue)) {
+ q = ngx_queue_head(&loop->watcher_queue);
+ ngx_queue_remove(q);
+ ngx_queue_init(q);
+
+ w = ngx_queue_data(q, uv__io_t, watcher_queue);
+ assert(w->pevents != 0);
+ assert(w->fd >= 0);
+ assert(w->fd < (int) loop->nwatchers);
+
+ e.events = w->pevents;
+ e.data = w->fd;
+
+ if (w->events == 0)
+ op = UV__EPOLL_CTL_ADD;
+ else
+ op = UV__EPOLL_CTL_MOD;
+
+ /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
+ * events, skip the syscall and squelch the events after epoll_wait().
+ */
+ if (uv__epoll_ctl(loop->backend_fd, op, w->fd, &e)) {
+ if (errno != EEXIST)
+ abort();
+
+ assert(op == UV__EPOLL_CTL_ADD);
+
+ /* We've reactivated a file descriptor that's been watched before. */
+ if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_MOD, w->fd, &e))
+ abort();
+ }
+
+ w->events = w->pevents;
+ }
+
+ assert(timeout >= -1);
+ base = loop->time;
+ count = 48; /* Benchmarks suggest this gives the best throughput. */
+
+ for (;;) {
+ nfds = uv__epoll_wait(loop->backend_fd,
+ events,
+ ARRAY_SIZE(events),
+ timeout);
+
+ /* Update loop->time unconditionally. It's tempting to skip the update when
+ * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
+ * operating system didn't reschedule our process while in the syscall.
+ */
+ SAVE_ERRNO(uv__update_time(loop));
+
+ if (nfds == 0) {
+ assert(timeout != -1);
+ return;
+ }
+
+ if (nfds == -1) {
+ if (errno != EINTR)
+ abort();
+
+ if (timeout == -1)
+ continue;
+
+ if (timeout == 0)
+ return;
+
+ /* Interrupted by a signal. Update timeout and poll again. */
+ goto update_timeout;
+ }
+
+ nevents = 0;
+
+ for (i = 0; i < nfds; i++) {
+ pe = events + i;
+ fd = pe->data;
+
+ assert(fd >= 0);
+ assert((unsigned) fd < loop->nwatchers);
+
+ w = loop->watchers[fd];
+
+ if (w == NULL) {
+ /* File descriptor that we've stopped watching, disarm it.
+ *
+ * Ignore all errors because we may be racing with another thread
+ * when the file descriptor is closed.
+ */
+ uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, pe);
+ continue;
+ }
+
+ w->cb(loop, w, pe->events);
+ nevents++;
+ }
+
+ if (nevents != 0) {
+ if (nfds == ARRAY_SIZE(events) && --count != 0) {
+ /* Poll for more events but don't block this time. */
+ timeout = 0;
+ continue;
+ }
+ return;
+ }
+
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+update_timeout:
+ assert(timeout > 0);
+
+ diff = loop->time - base;
+ if (diff >= (uint64_t) timeout)
+ return;
+
+ timeout -= diff;
+ }
+}
+
+
+uint64_t uv__hrtime(void) {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
+}
+
+
+void uv_loadavg(double avg[3]) {
+ struct sysinfo info;
+
+ if (sysinfo(&info) < 0) return;
+
+ avg[0] = (double) info.loads[0] / 65536.0;
+ avg[1] = (double) info.loads[1] / 65536.0;
+ avg[2] = (double) info.loads[2] / 65536.0;
+}
+
+
+int uv_exepath(char* buffer, size_t* size) {
+ ssize_t n;
+
+ if (!buffer || !size) {
+ return -1;
+ }
+
+ n = readlink("/proc/self/exe", buffer, *size - 1);
+ if (n <= 0) return -1;
+ buffer[n] = '\0';
+ *size = n;
+
+ return 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES);
+}
+
+
+uint64_t uv_get_total_memory(void) {
+ return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES);
+}
+
+
+uv_err_t uv_resident_set_memory(size_t* rss) {
+ FILE* f;
+ int itmp;
+ char ctmp;
+ unsigned int utmp;
+ size_t page_size = getpagesize();
+ char *cbuf;
+ int foundExeEnd;
+ char buf[PATH_MAX + 1];
+
+ f = fopen("/proc/self/stat", "r");
+ if (!f) return uv__new_sys_error(errno);
+
+ /* PID */
+ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Exec file */
+ cbuf = buf;
+ foundExeEnd = 0;
+ if (fscanf (f, "%c", cbuf++) == 0) goto error;
+ while (1) {
+ if (fscanf(f, "%c", cbuf) == 0) goto error;
+ if (*cbuf == ')') {
+ foundExeEnd = 1;
+ } else if (foundExeEnd && *cbuf == ' ') {
+ *cbuf = 0;
+ break;
+ }
+
+ cbuf++;
+ }
+ /* State */
+ if (fscanf (f, "%c ", &ctmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Parent process */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Process group */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Session id */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* TTY */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* TTY owner process group */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Flags */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Minor faults (no memory page) */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Minor faults, children */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Major faults (memory page faults) */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Major faults, children */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ /* utime */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* stime */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* utime, children */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* stime, children */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* jiffies remaining in current time slice */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* 'nice' value */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+ /* jiffies until next timeout */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ /* jiffies until next SIGALRM */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ /* start time (jiffies since system boot) */
+ if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+
+ /* Virtual memory size */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+
+ /* Resident set size */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ *rss = (size_t) utmp * page_size;
+
+ /* rlim */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Start of text */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ /* End of text */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+ /* Start of stack */
+ if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+
+ fclose (f);
+ return uv_ok_;
+
+error:
+ fclose (f);
+ return uv__new_sys_error(errno);
+}
+
+
+uv_err_t uv_uptime(double* uptime) {
+ static volatile int no_clock_boottime;
+ struct timespec now;
+ int r;
+
+ /* Try CLOCK_BOOTTIME first, fall back to CLOCK_MONOTONIC if not available
+ * (pre-2.6.39 kernels). CLOCK_MONOTONIC doesn't increase when the system
+ * is suspended.
+ */
+ if (no_clock_boottime) {
+ retry: r = clock_gettime(CLOCK_MONOTONIC, &now);
+ }
+ else if ((r = clock_gettime(CLOCK_BOOTTIME, &now)) && errno == EINVAL) {
+ no_clock_boottime = 1;
+ goto retry;
+ }
+
+ if (r)
+ return uv__new_sys_error(errno);
+
+ *uptime = now.tv_sec;
+ *uptime += (double)now.tv_nsec / 1000000000.0;
+ return uv_ok_;
+}
+
+
+uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ unsigned int numcpus;
+ uv_cpu_info_t* ci;
+
+ *cpu_infos = NULL;
+ *count = 0;
+
+ numcpus = sysconf(_SC_NPROCESSORS_ONLN);
+ assert(numcpus != (unsigned int) -1);
+ assert(numcpus != 0);
+
+ ci = calloc(numcpus, sizeof(*ci));
+ if (ci == NULL)
+ return uv__new_sys_error(ENOMEM);
+
+ read_models(numcpus, ci);
+ read_times(numcpus, ci);
+
+ /* read_models() on x86 also reads the CPU speed from /proc/cpuinfo */
+ if (ci[0].speed == 0)
+ read_speeds(numcpus, ci);
+
+ *cpu_infos = ci;
+ *count = numcpus;
+
+ return uv_ok_;
+}
+
+
+static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) {
+ unsigned int num;
+
+ for (num = 0; num < numcpus; num++)
+ ci[num].speed = read_cpufreq(num) / 1000;
+}
+
+
+/* Also reads the CPU frequency on x86. The other architectures only have
+ * a BogoMIPS field, which may not be very accurate.
+ */
+static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
+#if defined(__i386__) || defined(__x86_64__)
+ static const char model_marker[] = "model name\t: ";
+ static const char speed_marker[] = "cpu MHz\t\t: ";
+#elif defined(__arm__)
+ static const char model_marker[] = "Processor\t: ";
+ static const char speed_marker[] = "";
+#elif defined(__mips__)
+ static const char model_marker[] = "cpu model\t\t: ";
+ static const char speed_marker[] = "";
+#else
+# warning uv_cpu_info() is not supported on this architecture.
+ static const char model_marker[] = "";
+ static const char speed_marker[] = "";
+#endif
+ static const char bogus_model[] = "unknown";
+ unsigned int model_idx;
+ unsigned int speed_idx;
+ char buf[1024];
+ char* model;
+ FILE* fp;
+ char* inferred_model;
+
+ fp = fopen("/proc/cpuinfo", "r");
+ if (fp == NULL)
+ return;
+
+ model_idx = 0;
+ speed_idx = 0;
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (model_marker[0] != '\0' &&
+ model_idx < numcpus &&
+ strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0)
+ {
+ model = buf + sizeof(model_marker) - 1;
+ model = strndup(model, strlen(model) - 1); /* strip newline */
+ ci[model_idx++].model = model;
+ continue;
+ }
+
+ if (speed_marker[0] != '\0' &&
+ speed_idx < numcpus &&
+ strncmp(buf, speed_marker, sizeof(speed_marker) - 1) == 0)
+ {
+ ci[speed_idx++].speed = atoi(buf + sizeof(speed_marker) - 1);
+ continue;
+ }
+ }
+ fclose(fp);
+
+ /* Now we want to make sure that all the models contain *something*:
+ * it's not safe to leave them as null.
+ */
+ if (model_idx == 0) {
+ /* No models at all: fake up the first one. */
+ ci[0].model = strndup(bogus_model, sizeof(bogus_model) - 1);
+ model_idx = 1;
+ }
+
+ /* Not enough models, but we do have at least one. So we'll just
+ * copy the rest down: it might be better to indicate somehow that
+ * the remaining ones have been guessed.
+ */
+ inferred_model = ci[model_idx - 1].model;
+
+ while (model_idx < numcpus) {
+ ci[model_idx].model = strndup(inferred_model, strlen(inferred_model));
+ model_idx++;
+ }
+}
+
+
+static void read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
+ unsigned long clock_ticks;
+ struct uv_cpu_times_s ts;
+ unsigned long user;
+ unsigned long nice;
+ unsigned long sys;
+ unsigned long idle;
+ unsigned long dummy;
+ unsigned long irq;
+ unsigned int num;
+ unsigned int len;
+ char buf[1024];
+ FILE* fp;
+
+ clock_ticks = sysconf(_SC_CLK_TCK);
+ assert(clock_ticks != (unsigned long) -1);
+ assert(clock_ticks != 0);
+
+ fp = fopen("/proc/stat", "r");
+ if (fp == NULL)
+ return;
+
+ if (!fgets(buf, sizeof(buf), fp))
+ abort();
+
+ num = 0;
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (num >= numcpus)
+ break;
+
+ if (strncmp(buf, "cpu", 3))
+ break;
+
+ /* skip "cpu<num> " marker */
+ {
+ unsigned int n = num;
+ for (len = sizeof("cpu0"); n /= 10; len++);
+ assert(sscanf(buf, "cpu%u ", &n) == 1 && n == num);
+ }
+
+ /* Line contains user, nice, system, idle, iowait, irq, softirq, steal,
+ * guest, guest_nice but we're only interested in the first four + irq.
+ *
+ * Don't use %*s to skip fields or %ll to read straight into the uint64_t
+ * fields, they're not allowed in C89 mode.
+ */
+ if (6 != sscanf(buf + len,
+ "%lu %lu %lu %lu %lu %lu",
+ &user,
+ &nice,
+ &sys,
+ &idle,
+ &dummy,
+ &irq))
+ abort();
+
+ ts.user = clock_ticks * user;
+ ts.nice = clock_ticks * nice;
+ ts.sys = clock_ticks * sys;
+ ts.idle = clock_ticks * idle;
+ ts.irq = clock_ticks * irq;
+ ci[num++].cpu_times = ts;
+ }
+ fclose(fp);
+}
+
+
+static unsigned long read_cpufreq(unsigned int cpunum) {
+ unsigned long val;
+ char buf[1024];
+ FILE* fp;
+
+ snprintf(buf,
+ sizeof(buf),
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq",
+ cpunum);
+
+ fp = fopen(buf, "r");
+ if (fp == NULL)
+ return 0;
+
+ if (fscanf(fp, "%lu", &val) != 1)
+ val = 0;
+
+ fclose(fp);
+
+ return val;
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
+ int* count) {
+#ifndef HAVE_IFADDRS_H
+ return uv__new_artificial_error(UV_ENOSYS);
+#else
+ struct ifaddrs *addrs, *ent;
+ char ip[INET6_ADDRSTRLEN];
+ uv_interface_address_t* address;
+
+ if (getifaddrs(&addrs) != 0) {
+ return uv__new_sys_error(errno);
+ }
+
+ *count = 0;
+
+ /* Count the number of interfaces */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family == PF_PACKET)) {
+ continue;
+ }
+
+ (*count)++;
+ }
+
+ *addresses = (uv_interface_address_t*)
+ malloc(*count * sizeof(uv_interface_address_t));
+ if (!(*addresses)) {
+ return uv__new_artificial_error(UV_ENOMEM);
+ }
+
+ address = *addresses;
+
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ bzero(&ip, sizeof (ip));
+ if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
+ continue;
+ }
+
+ if (ent->ifa_addr == NULL) {
+ continue;
+ }
+
+ /*
+ * On Linux getifaddrs returns information related to the raw underlying
+ * devices. We're not interested in this information.
+ */
+ if (ent->ifa_addr->sa_family == PF_PACKET) {
+ continue;
+ }
+
+ address->name = strdup(ent->ifa_name);
+
+ if (ent->ifa_addr->sa_family == AF_INET6) {
+ address->address.address6 = *((struct sockaddr_in6 *)ent->ifa_addr);
+ } else {
+ address->address.address4 = *((struct sockaddr_in *)ent->ifa_addr);
+ }
+
+ address->is_internal = ent->ifa_flags & IFF_LOOPBACK ? 1 : 0;
+
+ address++;
+ }
+
+ freeifaddrs(addrs);
+
+ return uv_ok_;
+#endif
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+ int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(addresses[i].name);
+ }
+
+ free(addresses);
+}
+
+
+void uv__set_process_title(const char* title) {
+#if defined(PR_SET_NAME)
+ prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
+#endif
+}
diff --git a/deps/uv/src/unix/linux-inotify.c b/deps/uv/src/unix/linux-inotify.c
new file mode 100644
index 000000000..108345aa8
--- /dev/null
+++ b/deps/uv/src/unix/linux-inotify.c
@@ -0,0 +1,236 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "tree.h"
+#include "internal.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+struct watcher_list {
+ RB_ENTRY(watcher_list) entry;
+ ngx_queue_t watchers;
+ char* path;
+ int wd;
+};
+
+struct watcher_root {
+ struct watcher_list* rbh_root;
+};
+#define CAST(p) ((struct watcher_root*)(p))
+
+
+/* Don't look aghast, this is exactly how glibc's basename() works. */
+static char* basename_r(const char* path) {
+ char* s = strrchr(path, '/');
+ return s ? (s + 1) : (char*)path;
+}
+
+
+static int compare_watchers(const struct watcher_list* a,
+ const struct watcher_list* b) {
+ if (a->wd < b->wd) return -1;
+ if (a->wd > b->wd) return 1;
+ return 0;
+}
+
+
+RB_GENERATE_STATIC(watcher_root, watcher_list, entry, compare_watchers)
+
+
+static void uv__inotify_read(uv_loop_t* loop,
+ uv__io_t* w,
+ unsigned int revents);
+
+
+static int new_inotify_fd(void) {
+ int fd;
+
+ fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC);
+ if (fd != -1)
+ return fd;
+ if (errno != ENOSYS)
+ return -1;
+
+ if ((fd = uv__inotify_init()) == -1)
+ return -1;
+
+ if (uv__cloexec(fd, 1) || uv__nonblock(fd, 1)) {
+ SAVE_ERRNO(close(fd));
+ return -1;
+ }
+
+ return fd;
+}
+
+
+static int init_inotify(uv_loop_t* loop) {
+ if (loop->inotify_fd != -1)
+ return 0;
+
+ loop->inotify_fd = new_inotify_fd();
+ if (loop->inotify_fd == -1) {
+ uv__set_sys_error(loop, errno);
+ return -1;
+ }
+
+ uv__io_init(&loop->inotify_read_watcher, uv__inotify_read, loop->inotify_fd);
+ uv__io_start(loop, &loop->inotify_read_watcher, UV__POLLIN);
+
+ return 0;
+}
+
+
+static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) {
+ struct watcher_list w;
+ w.wd = wd;
+ return RB_FIND(watcher_root, CAST(&loop->inotify_watchers), &w);
+}
+
+
+static void uv__inotify_read(uv_loop_t* loop,
+ uv__io_t* dummy,
+ unsigned int events) {
+ const struct uv__inotify_event* e;
+ struct watcher_list* w;
+ uv_fs_event_t* h;
+ ngx_queue_t* q;
+ const char* path;
+ ssize_t size;
+ const char *p;
+ /* needs to be large enough for sizeof(inotify_event) + strlen(filename) */
+ char buf[4096];
+
+ while (1) {
+ do
+ size = read(loop->inotify_fd, buf, sizeof(buf));
+ while (size == -1 && errno == EINTR);
+
+ if (size == -1) {
+ assert(errno == EAGAIN || errno == EWOULDBLOCK);
+ break;
+ }
+
+ assert(size > 0); /* pre-2.6.21 thing, size=0 == read buffer too small */
+
+ /* Now we have one or more inotify_event structs. */
+ for (p = buf; p < buf + size; p += sizeof(*e) + e->len) {
+ e = (const struct uv__inotify_event*)p;
+
+ events = 0;
+ if (e->mask & (UV__IN_ATTRIB|UV__IN_MODIFY))
+ events |= UV_CHANGE;
+ if (e->mask & ~(UV__IN_ATTRIB|UV__IN_MODIFY))
+ events |= UV_RENAME;
+
+ w = find_watcher(loop, e->wd);
+ if (w == NULL)
+ continue; /* Stale event, no watchers left. */
+
+ /* inotify does not return the filename when monitoring a single file
+ * for modifications. Repurpose the filename for API compatibility.
+ * I'm not convinced this is a good thing, maybe it should go.
+ */
+ path = e->len ? (const char*) (e + 1) : basename_r(w->path);
+
+ ngx_queue_foreach(q, &w->watchers) {
+ h = ngx_queue_data(q, uv_fs_event_t, watchers);
+ h->cb(h, path, events, 0);
+ }
+ }
+ }
+}
+
+
+int uv_fs_event_init(uv_loop_t* loop,
+ uv_fs_event_t* handle,
+ const char* path,
+ uv_fs_event_cb cb,
+ int flags) {
+ struct watcher_list* w;
+ int events;
+ int wd;
+
+ if (init_inotify(loop)) return -1;
+
+ events = UV__IN_ATTRIB
+ | UV__IN_CREATE
+ | UV__IN_MODIFY
+ | UV__IN_DELETE
+ | UV__IN_DELETE_SELF
+ | UV__IN_MOVE_SELF
+ | UV__IN_MOVED_FROM
+ | UV__IN_MOVED_TO;
+
+ wd = uv__inotify_add_watch(loop->inotify_fd, path, events);
+ if (wd == -1)
+ return uv__set_sys_error(loop, errno);
+
+ w = find_watcher(loop, wd);
+ if (w)
+ goto no_insert;
+
+ w = malloc(sizeof(*w) + strlen(path) + 1);
+ if (w == NULL)
+ return uv__set_sys_error(loop, ENOMEM);
+
+ w->wd = wd;
+ w->path = strcpy((char*)(w + 1), path);
+ ngx_queue_init(&w->watchers);
+ RB_INSERT(watcher_root, CAST(&loop->inotify_watchers), w);
+
+no_insert:
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
+ uv__handle_start(handle); /* FIXME shouldn't start automatically */
+ ngx_queue_insert_tail(&w->watchers, &handle->watchers);
+ handle->filename = w->path;
+ handle->cb = cb;
+ handle->wd = wd;
+
+ return 0;
+}
+
+
+void uv__fs_event_close(uv_fs_event_t* handle) {
+ struct watcher_list* w;
+
+ w = find_watcher(handle->loop, handle->wd);
+ assert(w != NULL);
+
+ handle->wd = -1;
+ handle->filename = NULL;
+ uv__handle_stop(handle);
+ ngx_queue_remove(&handle->watchers);
+
+ if (ngx_queue_empty(&w->watchers)) {
+ /* No watchers left for this path. Clean up. */
+ RB_REMOVE(watcher_root, CAST(&handle->loop->inotify_watchers), w);
+ uv__inotify_rm_watch(handle->loop->inotify_fd, w->wd);
+ free(w);
+ }
+}
diff --git a/deps/uv/src/unix/linux-syscalls.c b/deps/uv/src/unix/linux-syscalls.c
new file mode 100644
index 000000000..06cc5943c
--- /dev/null
+++ b/deps/uv/src/unix/linux-syscalls.c
@@ -0,0 +1,388 @@
+/* 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.
+ */
+
+#include "linux-syscalls.h"
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#if defined(__i386__)
+# ifndef __NR_socketcall
+# define __NR_socketcall 102
+# endif
+#endif
+
+#if defined(__arm__)
+# if defined(__thumb__) || defined(__ARM_EABI__)
+# define UV_SYSCALL_BASE 0
+# else
+# define UV_SYSCALL_BASE 0x900000
+# endif
+#endif /* __arm__ */
+
+#ifndef __NR_accept4
+# if defined(__x86_64__)
+# define __NR_accept4 288
+# elif defined(__i386__)
+ /* Nothing. Handled through socketcall(). */
+# elif defined(__arm__)
+# define __NR_accept4 (UV_SYSCALL_BASE + 366)
+# endif
+#endif /* __NR_accept4 */
+
+#ifndef __NR_eventfd
+# if defined(__x86_64__)
+# define __NR_eventfd 284
+# elif defined(__i386__)
+# define __NR_eventfd 323
+# elif defined(__arm__)
+# define __NR_eventfd (UV_SYSCALL_BASE + 351)
+# endif
+#endif /* __NR_eventfd */
+
+#ifndef __NR_eventfd2
+# if defined(__x86_64__)
+# define __NR_eventfd2 290
+# elif defined(__i386__)
+# define __NR_eventfd2 328
+# elif defined(__arm__)
+# define __NR_eventfd2 (UV_SYSCALL_BASE + 356)
+# endif
+#endif /* __NR_eventfd2 */
+
+#ifndef __NR_epoll_create
+# if defined(__x86_64__)
+# define __NR_epoll_create 213
+# elif defined(__i386__)
+# define __NR_epoll_create 254
+# elif defined(__arm__)
+# define __NR_epoll_create (UV_SYSCALL_BASE + 250)
+# endif
+#endif /* __NR_epoll_create */
+
+#ifndef __NR_epoll_create1
+# if defined(__x86_64__)
+# define __NR_epoll_create1 291
+# elif defined(__i386__)
+# define __NR_epoll_create1 329
+# elif defined(__arm__)
+# define __NR_epoll_create1 (UV_SYSCALL_BASE + 357)
+# endif
+#endif /* __NR_epoll_create1 */
+
+#ifndef __NR_epoll_ctl
+# if defined(__x86_64__)
+# define __NR_epoll_ctl 233 /* used to be 214 */
+# elif defined(__i386__)
+# define __NR_epoll_ctl 255
+# elif defined(__arm__)
+# define __NR_epoll_ctl (UV_SYSCALL_BASE + 251)
+# endif
+#endif /* __NR_epoll_ctl */
+
+#ifndef __NR_epoll_wait
+# if defined(__x86_64__)
+# define __NR_epoll_wait 232 /* used to be 215 */
+# elif defined(__i386__)
+# define __NR_epoll_wait 256
+# elif defined(__arm__)
+# define __NR_epoll_wait (UV_SYSCALL_BASE + 252)
+# endif
+#endif /* __NR_epoll_wait */
+
+#ifndef __NR_epoll_pwait
+# if defined(__x86_64__)
+# define __NR_epoll_pwait 281
+# elif defined(__i386__)
+# define __NR_epoll_pwait 319
+# elif defined(__arm__)
+# define __NR_epoll_pwait (UV_SYSCALL_BASE + 346)
+# endif
+#endif /* __NR_epoll_pwait */
+
+#ifndef __NR_inotify_init
+# if defined(__x86_64__)
+# define __NR_inotify_init 253
+# elif defined(__i386__)
+# define __NR_inotify_init 291
+# elif defined(__arm__)
+# define __NR_inotify_init (UV_SYSCALL_BASE + 316)
+# endif
+#endif /* __NR_inotify_init */
+
+#ifndef __NR_inotify_init1
+# if defined(__x86_64__)
+# define __NR_inotify_init1 294
+# elif defined(__i386__)
+# define __NR_inotify_init1 332
+# elif defined(__arm__)
+# define __NR_inotify_init1 (UV_SYSCALL_BASE + 360)
+# endif
+#endif /* __NR_inotify_init1 */
+
+#ifndef __NR_inotify_add_watch
+# if defined(__x86_64__)
+# define __NR_inotify_add_watch 254
+# elif defined(__i386__)
+# define __NR_inotify_add_watch 292
+# elif defined(__arm__)
+# define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317)
+# endif
+#endif /* __NR_inotify_add_watch */
+
+#ifndef __NR_inotify_rm_watch
+# if defined(__x86_64__)
+# define __NR_inotify_rm_watch 255
+# elif defined(__i386__)
+# define __NR_inotify_rm_watch 293
+# elif defined(__arm__)
+# define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318)
+# endif
+#endif /* __NR_inotify_rm_watch */
+
+#ifndef __NR_pipe2
+# if defined(__x86_64__)
+# define __NR_pipe2 293
+# elif defined(__i386__)
+# define __NR_pipe2 331
+# elif defined(__arm__)
+# define __NR_pipe2 (UV_SYSCALL_BASE + 359)
+# endif
+#endif /* __NR_pipe2 */
+
+#ifndef __NR_recvmmsg
+# if defined(__x86_64__)
+# define __NR_recvmmsg 299
+# elif defined(__i386__)
+# define __NR_recvmmsg 337
+# elif defined(__arm__)
+# define __NR_recvmmsg (UV_SYSCALL_BASE + 365)
+# endif
+#endif /* __NR_recvmsg */
+
+#ifndef __NR_sendmmsg
+# if defined(__x86_64__)
+# define __NR_sendmmsg 307
+# elif defined(__i386__)
+# define __NR_sendmmsg 345
+# elif defined(__arm__)
+# define __NR_sendmmsg (UV_SYSCALL_BASE + 374)
+# endif
+#endif /* __NR_sendmmsg */
+
+#ifndef __NR_utimensat
+# if defined(__x86_64__)
+# define __NR_utimensat 280
+# elif defined(__i386__)
+# define __NR_utimensat 320
+# elif defined(__arm__)
+# define __NR_utimensat (UV_SYSCALL_BASE + 348)
+# endif
+#endif /* __NR_utimensat */
+
+
+int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
+#if defined(__i386__)
+ unsigned long args[4];
+ int r;
+
+ args[0] = (unsigned long) fd;
+ args[1] = (unsigned long) addr;
+ args[2] = (unsigned long) addrlen;
+ args[3] = (unsigned long) flags;
+
+ r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args);
+
+ /* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does
+ * a bad flags argument. Try to distinguish between the two cases.
+ */
+ if (r == -1)
+ if (errno == EINVAL)
+ if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0)
+ errno = ENOSYS;
+
+ return r;
+#elif defined(__NR_accept4)
+ return syscall(__NR_accept4, fd, addr, addrlen, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__eventfd(unsigned int count) {
+#if defined(__NR_eventfd)
+ return syscall(__NR_eventfd, count);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__eventfd2(unsigned int count, int flags) {
+#if defined(__NR_eventfd2)
+ return syscall(__NR_eventfd2, count, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__epoll_create(int size) {
+#if defined(__NR_epoll_create)
+ return syscall(__NR_epoll_create, size);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__epoll_create1(int flags) {
+#if defined(__NR_epoll_create1)
+ return syscall(__NR_epoll_create1, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event* events) {
+#if defined(__NR_epoll_ctl)
+ return syscall(__NR_epoll_ctl, epfd, op, fd, events);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__epoll_wait(int epfd,
+ struct uv__epoll_event* events,
+ int nevents,
+ int timeout) {
+#if defined(__NR_epoll_wait)
+ return syscall(__NR_epoll_wait, epfd, events, nevents, timeout);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__epoll_pwait(int epfd,
+ struct uv__epoll_event* events,
+ int nevents,
+ int timeout,
+ const sigset_t* sigmask) {
+#if defined(__NR_epoll_pwait)
+ return syscall(__NR_epoll_pwait,
+ epfd,
+ events,
+ nevents,
+ timeout,
+ sigmask,
+ sizeof(*sigmask));
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_init(void) {
+#if defined(__NR_inotify_init)
+ return syscall(__NR_inotify_init);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_init1(int flags) {
+#if defined(__NR_inotify_init1)
+ return syscall(__NR_inotify_init1, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_add_watch(int fd, const char* path, uint32_t mask) {
+#if defined(__NR_inotify_add_watch)
+ return syscall(__NR_inotify_add_watch, fd, path, mask);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_rm_watch(int fd, int32_t wd) {
+#if defined(__NR_inotify_rm_watch)
+ return syscall(__NR_inotify_rm_watch, fd, wd);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__pipe2(int pipefd[2], int flags) {
+#if defined(__NR_pipe2)
+ return syscall(__NR_pipe2, pipefd, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__sendmmsg(int fd,
+ struct uv__mmsghdr* mmsg,
+ unsigned int vlen,
+ unsigned int flags) {
+#if defined(__NR_sendmmsg)
+ return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__recvmmsg(int fd,
+ struct uv__mmsghdr* mmsg,
+ unsigned int vlen,
+ unsigned int flags,
+ struct timespec* timeout) {
+#if defined(__NR_recvmmsg)
+ return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__utimesat(int dirfd,
+ const char* path,
+ const struct timespec times[2],
+ int flags)
+{
+#if defined(__NR_utimensat)
+ return syscall(__NR_utimensat, dirfd, path, times, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
diff --git a/deps/uv/src/unix/linux-syscalls.h b/deps/uv/src/unix/linux-syscalls.h
new file mode 100644
index 000000000..ba44974a0
--- /dev/null
+++ b/deps/uv/src/unix/linux-syscalls.h
@@ -0,0 +1,150 @@
+/* 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.
+ */
+
+#ifndef UV_LINUX_SYSCALL_H_
+#define UV_LINUX_SYSCALL_H_
+
+#undef _GNU_SOURCE
+#define _GNU_SOURCE
+
+#include <stdint.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#if defined(__alpha__)
+# define UV__O_CLOEXEC 0x200000
+#elif defined(__hppa__)
+# define UV__O_CLOEXEC 0x200000
+#elif defined(__sparc__)
+# define UV__O_CLOEXEC 0x400000
+#else
+# define UV__O_CLOEXEC 0x80000
+#endif
+
+#if defined(__alpha__)
+# define UV__O_NONBLOCK 0x4
+#elif defined(__hppa__)
+# define UV__O_NONBLOCK 0x10004
+#elif defined(__mips__)
+# define UV__O_NONBLOCK 0x80
+#elif defined(__sparc__)
+# define UV__O_NONBLOCK 0x4000
+#else
+# define UV__O_NONBLOCK 0x800
+#endif
+
+#define UV__EFD_CLOEXEC UV__O_CLOEXEC
+#define UV__EFD_NONBLOCK UV__O_NONBLOCK
+
+#define UV__IN_CLOEXEC UV__O_CLOEXEC
+#define UV__IN_NONBLOCK UV__O_NONBLOCK
+
+#define UV__SOCK_CLOEXEC UV__O_CLOEXEC
+#define UV__SOCK_NONBLOCK UV__O_NONBLOCK
+
+/* epoll flags */
+#define UV__EPOLL_CLOEXEC UV__O_CLOEXEC
+#define UV__EPOLL_CTL_ADD 1
+#define UV__EPOLL_CTL_DEL 2
+#define UV__EPOLL_CTL_MOD 3
+
+#define UV__EPOLLIN 1
+#define UV__EPOLLOUT 4
+#define UV__EPOLLERR 8
+#define UV__EPOLLHUP 16
+#define UV__EPOLLONESHOT 0x40000000
+#define UV__EPOLLET 0x80000000
+
+/* inotify flags */
+#define UV__IN_ACCESS 0x001
+#define UV__IN_MODIFY 0x002
+#define UV__IN_ATTRIB 0x004
+#define UV__IN_CLOSE_WRITE 0x008
+#define UV__IN_CLOSE_NOWRITE 0x010
+#define UV__IN_OPEN 0x020
+#define UV__IN_MOVED_FROM 0x040
+#define UV__IN_MOVED_TO 0x080
+#define UV__IN_CREATE 0x100
+#define UV__IN_DELETE 0x200
+#define UV__IN_DELETE_SELF 0x400
+#define UV__IN_MOVE_SELF 0x800
+
+#if defined(__x86_64__)
+struct uv__epoll_event {
+ uint32_t events;
+ uint64_t data;
+} __attribute__((packed));
+#else
+struct uv__epoll_event {
+ uint32_t events;
+ uint64_t data;
+};
+#endif
+
+struct uv__inotify_event {
+ int32_t wd;
+ uint32_t mask;
+ uint32_t cookie;
+ uint32_t len;
+ /* char name[0]; */
+};
+
+struct uv__mmsghdr {
+ struct msghdr msg_hdr;
+ unsigned int msg_len;
+};
+
+int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags);
+int uv__eventfd(unsigned int count);
+int uv__epoll_create(int size);
+int uv__epoll_create1(int flags);
+int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event *ev);
+int uv__epoll_wait(int epfd,
+ struct uv__epoll_event* events,
+ int nevents,
+ int timeout);
+int uv__epoll_pwait(int epfd,
+ struct uv__epoll_event* events,
+ int nevents,
+ int timeout,
+ const sigset_t* sigmask);
+int uv__eventfd2(unsigned int count, int flags);
+int uv__inotify_init(void);
+int uv__inotify_init1(int flags);
+int uv__inotify_add_watch(int fd, const char* path, uint32_t mask);
+int uv__inotify_rm_watch(int fd, int32_t wd);
+int uv__pipe2(int pipefd[2], int flags);
+int uv__recvmmsg(int fd,
+ struct uv__mmsghdr* mmsg,
+ unsigned int vlen,
+ unsigned int flags,
+ struct timespec* timeout);
+int uv__sendmmsg(int fd,
+ struct uv__mmsghdr* mmsg,
+ unsigned int vlen,
+ unsigned int flags);
+int uv__utimesat(int dirfd,
+ const char* path,
+ const struct timespec times[2],
+ int flags);
+
+#endif /* UV_LINUX_SYSCALL_H_ */
diff --git a/deps/uv/src/unix/linux/inotify.c b/deps/uv/src/unix/linux/inotify.c
deleted file mode 100644
index 51ea996ae..000000000
--- a/deps/uv/src/unix/linux/inotify.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* 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.
- */
-
-#include "uv.h"
-#include "tree.h"
-#include "../internal.h"
-#include "syscalls.h"
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <sys/types.h>
-#include <unistd.h>
-
-struct watcher_list {
- RB_ENTRY(watcher_list) entry;
- ngx_queue_t watchers;
- char* path;
- int wd;
-};
-
-struct watcher_root {
- struct watcher_list* rbh_root;
-};
-#define CAST(p) ((struct watcher_root*)(p))
-
-
-/* Don't look aghast, this is exactly how glibc's basename() works. */
-static char* basename_r(const char* path) {
- char* s = strrchr(path, '/');
- return s ? (s + 1) : (char*)path;
-}
-
-
-static int compare_watchers(const struct watcher_list* a,
- const struct watcher_list* b) {
- if (a->wd < b->wd) return -1;
- if (a->wd > b->wd) return 1;
- return 0;
-}
-
-
-RB_GENERATE_STATIC(watcher_root, watcher_list, entry, compare_watchers)
-
-
-static void uv__inotify_read(uv_loop_t* loop, uv__io_t* w, int revents);
-
-
-static int new_inotify_fd(void) {
- int fd;
-
- fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC);
- if (fd != -1)
- return fd;
- if (errno != ENOSYS)
- return -1;
-
- if ((fd = uv__inotify_init()) == -1)
- return -1;
-
- if (uv__cloexec(fd, 1) || uv__nonblock(fd, 1)) {
- SAVE_ERRNO(close(fd));
- return -1;
- }
-
- return fd;
-}
-
-
-static int init_inotify(uv_loop_t* loop) {
- if (loop->inotify_fd != -1)
- return 0;
-
- loop->inotify_fd = new_inotify_fd();
- if (loop->inotify_fd == -1) {
- uv__set_sys_error(loop, errno);
- return -1;
- }
-
- uv__io_init(&loop->inotify_read_watcher,
- uv__inotify_read,
- loop->inotify_fd,
- UV__IO_READ);
- uv__io_start(loop, &loop->inotify_read_watcher);
-
- return 0;
-}
-
-
-static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) {
- struct watcher_list w;
- w.wd = wd;
- return RB_FIND(watcher_root, CAST(&loop->inotify_watchers), &w);
-}
-
-
-static void uv__inotify_read(uv_loop_t* loop, uv__io_t* dummy, int events) {
- const struct uv__inotify_event* e;
- struct watcher_list* w;
- uv_fs_event_t* h;
- ngx_queue_t* q;
- const char* path;
- ssize_t size;
- const char *p;
- /* needs to be large enough for sizeof(inotify_event) + strlen(filename) */
- char buf[4096];
-
- while (1) {
- do
- size = read(loop->inotify_fd, buf, sizeof(buf));
- while (size == -1 && errno == EINTR);
-
- if (size == -1) {
- assert(errno == EAGAIN || errno == EWOULDBLOCK);
- break;
- }
-
- assert(size > 0); /* pre-2.6.21 thing, size=0 == read buffer too small */
-
- /* Now we have one or more inotify_event structs. */
- for (p = buf; p < buf + size; p += sizeof(*e) + e->len) {
- e = (const struct uv__inotify_event*)p;
-
- events = 0;
- if (e->mask & (UV__IN_ATTRIB|UV__IN_MODIFY))
- events |= UV_CHANGE;
- if (e->mask & ~(UV__IN_ATTRIB|UV__IN_MODIFY))
- events |= UV_RENAME;
-
- w = find_watcher(loop, e->wd);
- if (w == NULL)
- continue; /* Stale event, no watchers left. */
-
- /* inotify does not return the filename when monitoring a single file
- * for modifications. Repurpose the filename for API compatibility.
- * I'm not convinced this is a good thing, maybe it should go.
- */
- path = e->len ? (const char*) (e + 1) : basename_r(w->path);
-
- ngx_queue_foreach(q, &w->watchers) {
- h = ngx_queue_data(q, uv_fs_event_t, watchers);
- h->cb(h, path, events, 0);
- }
- }
- }
-}
-
-
-int uv_fs_event_init(uv_loop_t* loop,
- uv_fs_event_t* handle,
- const char* path,
- uv_fs_event_cb cb,
- int flags) {
- struct watcher_list* w;
- int events;
- int wd;
-
- loop->counters.fs_event_init++;
-
- /* We don't support any flags yet. */
- assert(!flags);
-
- if (init_inotify(loop)) return -1;
-
- events = UV__IN_ATTRIB
- | UV__IN_CREATE
- | UV__IN_MODIFY
- | UV__IN_DELETE
- | UV__IN_DELETE_SELF
- | UV__IN_MOVE_SELF
- | UV__IN_MOVED_FROM
- | UV__IN_MOVED_TO;
-
- wd = uv__inotify_add_watch(loop->inotify_fd, path, events);
- if (wd == -1)
- return uv__set_sys_error(loop, errno);
-
- w = find_watcher(loop, wd);
- if (w)
- goto no_insert;
-
- w = malloc(sizeof(*w) + strlen(path) + 1);
- if (w == NULL)
- return uv__set_sys_error(loop, ENOMEM);
-
- w->wd = wd;
- w->path = strcpy((char*)(w + 1), path);
- ngx_queue_init(&w->watchers);
- RB_INSERT(watcher_root, CAST(&loop->inotify_watchers), w);
-
-no_insert:
- uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
- uv__handle_start(handle); /* FIXME shouldn't start automatically */
- ngx_queue_insert_tail(&w->watchers, &handle->watchers);
- handle->filename = w->path;
- handle->cb = cb;
- handle->wd = wd;
-
- return 0;
-}
-
-
-void uv__fs_event_close(uv_fs_event_t* handle) {
- struct watcher_list* w;
-
- w = find_watcher(handle->loop, handle->wd);
- assert(w != NULL);
-
- handle->wd = -1;
- handle->filename = NULL;
- uv__handle_stop(handle);
- ngx_queue_remove(&handle->watchers);
-
- if (ngx_queue_empty(&w->watchers)) {
- /* No watchers left for this path. Clean up. */
- RB_REMOVE(watcher_root, CAST(&handle->loop->inotify_watchers), w);
- uv__inotify_rm_watch(handle->loop->inotify_fd, w->wd);
- free(w);
- }
-}
diff --git a/deps/uv/src/unix/linux/linux-core.c b/deps/uv/src/unix/linux/linux-core.c
deleted file mode 100644
index 4259d1711..000000000
--- a/deps/uv/src/unix/linux/linux-core.c
+++ /dev/null
@@ -1,586 +0,0 @@
-/* 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.
- */
-
-#include "uv.h"
-#include "../internal.h"
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <net/if.h>
-#include <sys/param.h>
-#include <sys/prctl.h>
-#include <sys/sysinfo.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-
-#define HAVE_IFADDRS_H 1
-#ifdef __UCLIBC__
-# if __UCLIBC_MAJOR__ < 0 || __UCLIBC_MINOR__ < 9 || __UCLIBC_SUBLEVEL__ < 32
-# undef HAVE_IFADDRS_H
-# endif
-#endif
-#ifdef HAVE_IFADDRS_H
-# include <ifaddrs.h>
-#endif
-
-#undef NANOSEC
-#define NANOSEC ((uint64_t) 1e9)
-
-/* This is rather annoying: CLOCK_BOOTTIME lives in <linux/time.h> but we can't
- * include that file because it conflicts with <time.h>. We'll just have to
- * define it ourselves.
- */
-#ifndef CLOCK_BOOTTIME
-# define CLOCK_BOOTTIME 7
-#endif
-
-static char buf[MAXPATHLEN + 1];
-
-static struct {
- char *str;
- size_t len;
-} process_title;
-
-static void read_models(unsigned int numcpus, uv_cpu_info_t* ci);
-static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
-static void read_times(unsigned int numcpus, uv_cpu_info_t* ci);
-static unsigned long read_cpufreq(unsigned int cpunum);
-
-
-/*
- * There's probably some way to get time from Linux than gettimeofday(). What
- * it is, I don't know.
- */
-uint64_t uv_hrtime() {
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
-}
-
-
-void uv_loadavg(double avg[3]) {
- struct sysinfo info;
-
- if (sysinfo(&info) < 0) return;
-
- avg[0] = (double) info.loads[0] / 65536.0;
- avg[1] = (double) info.loads[1] / 65536.0;
- avg[2] = (double) info.loads[2] / 65536.0;
-}
-
-
-int uv_exepath(char* buffer, size_t* size) {
- ssize_t n;
-
- if (!buffer || !size) {
- return -1;
- }
-
- n = readlink("/proc/self/exe", buffer, *size - 1);
- if (n <= 0) return -1;
- buffer[n] = '\0';
- *size = n;
-
- return 0;
-}
-
-
-uint64_t uv_get_free_memory(void) {
- return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES);
-}
-
-
-uint64_t uv_get_total_memory(void) {
- return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES);
-}
-
-
-char** uv_setup_args(int argc, char** argv) {
- char **new_argv;
- char **new_env;
- size_t size;
- int envc;
- char *s;
- int i;
-
- for (envc = 0; environ[envc]; envc++);
-
- s = envc ? environ[envc - 1] : argv[argc - 1];
-
- process_title.str = argv[0];
- process_title.len = s + strlen(s) + 1 - argv[0];
-
- size = process_title.len;
- size += (argc + 1) * sizeof(char **);
- size += (envc + 1) * sizeof(char **);
-
- if ((s = (char *) malloc(size)) == NULL) {
- process_title.str = NULL;
- process_title.len = 0;
- return argv;
- }
-
- new_argv = (char **) s;
- new_env = new_argv + argc + 1;
- s = (char *) (new_env + envc + 1);
- memcpy(s, process_title.str, process_title.len);
-
- for (i = 0; i < argc; i++)
- new_argv[i] = s + (argv[i] - argv[0]);
- new_argv[argc] = NULL;
-
- s += environ[0] - argv[0];
-
- for (i = 0; i < envc; i++)
- new_env[i] = s + (environ[i] - environ[0]);
- new_env[envc] = NULL;
-
- environ = new_env;
- return new_argv;
-}
-
-
-uv_err_t uv_set_process_title(const char* title) {
- /* No need to terminate, last char is always '\0'. */
- if (process_title.len)
- strncpy(process_title.str, title, process_title.len - 1);
-
-#if defined(PR_SET_NAME)
- prctl(PR_SET_NAME, title);
-#endif
-
- return uv_ok_;
-}
-
-
-uv_err_t uv_get_process_title(char* buffer, size_t size) {
- if (process_title.str) {
- strncpy(buffer, process_title.str, size);
- } else {
- if (size > 0) {
- buffer[0] = '\0';
- }
- }
-
- return uv_ok_;
-}
-
-
-uv_err_t uv_resident_set_memory(size_t* rss) {
- FILE* f;
- int itmp;
- char ctmp;
- unsigned int utmp;
- size_t page_size = getpagesize();
- char *cbuf;
- int foundExeEnd;
-
- f = fopen("/proc/self/stat", "r");
- if (!f) return uv__new_sys_error(errno);
-
- /* PID */
- if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* Exec file */
- cbuf = buf;
- foundExeEnd = 0;
- if (fscanf (f, "%c", cbuf++) == 0) goto error;
- while (1) {
- if (fscanf(f, "%c", cbuf) == 0) goto error;
- if (*cbuf == ')') {
- foundExeEnd = 1;
- } else if (foundExeEnd && *cbuf == ' ') {
- *cbuf = 0;
- break;
- }
-
- cbuf++;
- }
- /* State */
- if (fscanf (f, "%c ", &ctmp) == 0) goto error; /* coverity[secure_coding] */
- /* Parent process */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* Process group */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* Session id */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* TTY */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* TTY owner process group */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* Flags */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- /* Minor faults (no memory page) */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- /* Minor faults, children */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- /* Major faults (memory page faults) */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- /* Major faults, children */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- /* utime */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* stime */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* utime, children */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* stime, children */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* jiffies remaining in current time slice */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* 'nice' value */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
- /* jiffies until next timeout */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- /* jiffies until next SIGALRM */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- /* start time (jiffies since system boot) */
- if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
-
- /* Virtual memory size */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
-
- /* Resident set size */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- *rss = (size_t) utmp * page_size;
-
- /* rlim */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- /* Start of text */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- /* End of text */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
- /* Start of stack */
- if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
-
- fclose (f);
- return uv_ok_;
-
-error:
- fclose (f);
- return uv__new_sys_error(errno);
-}
-
-
-uv_err_t uv_uptime(double* uptime) {
- static volatile int no_clock_boottime;
- struct timespec now;
- int r;
-
- /* Try CLOCK_BOOTTIME first, fall back to CLOCK_MONOTONIC if not available
- * (pre-2.6.39 kernels). CLOCK_MONOTONIC doesn't increase when the system
- * is suspended.
- */
- if (no_clock_boottime) {
- retry: r = clock_gettime(CLOCK_MONOTONIC, &now);
- }
- else if ((r = clock_gettime(CLOCK_BOOTTIME, &now)) && errno == EINVAL) {
- no_clock_boottime = 1;
- goto retry;
- }
-
- if (r)
- return uv__new_sys_error(errno);
-
- *uptime = now.tv_sec;
- *uptime += (double)now.tv_nsec / 1000000000.0;
- return uv_ok_;
-}
-
-
-uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
- unsigned int numcpus;
- uv_cpu_info_t* ci;
-
- *cpu_infos = NULL;
- *count = 0;
-
- numcpus = sysconf(_SC_NPROCESSORS_ONLN);
- assert(numcpus != (unsigned int) -1);
- assert(numcpus != 0);
-
- ci = calloc(numcpus, sizeof(*ci));
- if (ci == NULL)
- return uv__new_sys_error(ENOMEM);
-
- read_models(numcpus, ci);
- read_times(numcpus, ci);
-
- /* read_models() on x86 also reads the CPU speed from /proc/cpuinfo */
- if (ci[0].speed == 0)
- read_speeds(numcpus, ci);
-
- *cpu_infos = ci;
- *count = numcpus;
-
- return uv_ok_;
-}
-
-
-static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) {
- unsigned int num;
-
- for (num = 0; num < numcpus; num++)
- ci[num].speed = read_cpufreq(num) / 1000;
-}
-
-
-/* Also reads the CPU frequency on x86. The other architectures only have
- * a BogoMIPS field, which may not be very accurate.
- */
-static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
-#if defined(__i386__) || defined(__x86_64__)
- static const char model_marker[] = "model name\t: ";
- static const char speed_marker[] = "cpu MHz\t\t: ";
-#elif defined(__arm__)
- static const char model_marker[] = "Processor\t: ";
- static const char speed_marker[] = "";
-#elif defined(__mips__)
- static const char model_marker[] = "cpu model\t\t: ";
- static const char speed_marker[] = "";
-#else
-# warning uv_cpu_info() is not supported on this architecture.
- static const char model_marker[] = "";
- static const char speed_marker[] = "";
-#endif
- unsigned int model_idx;
- unsigned int speed_idx;
- char buf[1024];
- char* model;
- FILE* fp;
-
- fp = fopen("/proc/cpuinfo", "r");
- if (fp == NULL)
- return;
-
- model_idx = 0;
- speed_idx = 0;
-
- while (fgets(buf, sizeof(buf), fp)) {
- if (model_marker[0] != '\0' &&
- model_idx < numcpus &&
- strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0)
- {
- model = buf + sizeof(model_marker) - 1;
- model = strndup(model, strlen(model) - 1); /* strip newline */
- ci[model_idx++].model = model;
- continue;
- }
-
- if (speed_marker[0] != '\0' &&
- speed_idx < numcpus &&
- strncmp(buf, speed_marker, sizeof(speed_marker) - 1) == 0)
- {
- ci[speed_idx++].speed = atoi(buf + sizeof(speed_marker) - 1);
- continue;
- }
- }
- fclose(fp);
-}
-
-
-static void read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
- unsigned long clock_ticks;
- struct uv_cpu_times_s ts;
- unsigned long user;
- unsigned long nice;
- unsigned long sys;
- unsigned long idle;
- unsigned long dummy;
- unsigned long irq;
- unsigned int num;
- unsigned int len;
- char buf[1024];
- FILE* fp;
-
- clock_ticks = sysconf(_SC_CLK_TCK);
- assert(clock_ticks != (unsigned long) -1);
- assert(clock_ticks != 0);
-
- fp = fopen("/proc/stat", "r");
- if (fp == NULL)
- return;
-
- if (!fgets(buf, sizeof(buf), fp))
- abort();
-
- num = 0;
-
- while (fgets(buf, sizeof(buf), fp)) {
- if (num >= numcpus)
- break;
-
- if (strncmp(buf, "cpu", 3))
- break;
-
- /* skip "cpu<num> " marker */
- {
- unsigned int n = num;
- for (len = sizeof("cpu0"); n /= 10; len++);
- assert(sscanf(buf, "cpu%u ", &n) == 1 && n == num);
- }
-
- /* Line contains user, nice, system, idle, iowait, irq, softirq, steal,
- * guest, guest_nice but we're only interested in the first four + irq.
- *
- * Don't use %*s to skip fields or %ll to read straight into the uint64_t
- * fields, they're not allowed in C89 mode.
- */
- if (6 != sscanf(buf + len,
- "%lu %lu %lu %lu %lu %lu",
- &user,
- &nice,
- &sys,
- &idle,
- &dummy,
- &irq))
- abort();
-
- ts.user = clock_ticks * user;
- ts.nice = clock_ticks * nice;
- ts.sys = clock_ticks * sys;
- ts.idle = clock_ticks * idle;
- ts.irq = clock_ticks * irq;
- ci[num++].cpu_times = ts;
- }
- fclose(fp);
-}
-
-
-static unsigned long read_cpufreq(unsigned int cpunum) {
- unsigned long val;
- char buf[1024];
- FILE* fp;
-
- snprintf(buf,
- sizeof(buf),
- "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq",
- cpunum);
-
- fp = fopen(buf, "r");
- if (fp == NULL)
- return 0;
-
- val = 0;
- fscanf(fp, "%lu", &val);
- fclose(fp);
-
- return val;
-}
-
-
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
- int i;
-
- for (i = 0; i < count; i++) {
- free(cpu_infos[i].model);
- }
-
- free(cpu_infos);
-}
-
-
-uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
- int* count) {
-#ifndef HAVE_IFADDRS_H
- return uv__new_artificial_error(UV_ENOSYS);
-#else
- struct ifaddrs *addrs, *ent;
- char ip[INET6_ADDRSTRLEN];
- uv_interface_address_t* address;
-
- if (getifaddrs(&addrs) != 0) {
- return uv__new_sys_error(errno);
- }
-
- *count = 0;
-
- /* Count the number of interfaces */
- for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
- if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
- (ent->ifa_addr == NULL) ||
- (ent->ifa_addr->sa_family == PF_PACKET)) {
- continue;
- }
-
- (*count)++;
- }
-
- *addresses = (uv_interface_address_t*)
- malloc(*count * sizeof(uv_interface_address_t));
- if (!(*addresses)) {
- return uv__new_artificial_error(UV_ENOMEM);
- }
-
- address = *addresses;
-
- for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
- bzero(&ip, sizeof (ip));
- if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
- continue;
- }
-
- if (ent->ifa_addr == NULL) {
- continue;
- }
-
- /*
- * On Linux getifaddrs returns information related to the raw underlying
- * devices. We're not interested in this information.
- */
- if (ent->ifa_addr->sa_family == PF_PACKET) {
- continue;
- }
-
- address->name = strdup(ent->ifa_name);
-
- if (ent->ifa_addr->sa_family == AF_INET6) {
- address->address.address6 = *((struct sockaddr_in6 *)ent->ifa_addr);
- } else {
- address->address.address4 = *((struct sockaddr_in *)ent->ifa_addr);
- }
-
- address->is_internal = ent->ifa_flags & IFF_LOOPBACK ? 1 : 0;
-
- address++;
- }
-
- freeifaddrs(addrs);
-
- return uv_ok_;
-#endif
-}
-
-
-void uv_free_interface_addresses(uv_interface_address_t* addresses,
- int count) {
- int i;
-
- for (i = 0; i < count; i++) {
- free(addresses[i].name);
- }
-
- free(addresses);
-}
diff --git a/deps/uv/src/unix/linux/syscalls.c b/deps/uv/src/unix/linux/syscalls.c
deleted file mode 100644
index cbf2bbbde..000000000
--- a/deps/uv/src/unix/linux/syscalls.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* 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.
- */
-
-#include "syscalls.h"
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <errno.h>
-
-#if __i386__
-# ifndef __NR_socketcall
-# define __NR_socketcall 102
-# endif
-#endif
-
-#if __arm__
-# if __thumb__ || __ARM_EABI__
-# define UV_SYSCALL_BASE 0
-# else
-# define UV_SYSCALL_BASE 0x900000
-# endif
-#endif /* __arm__ */
-
-#ifndef __NR_accept4
-# if __x86_64__
-# define __NR_accept4 288
-# elif __i386__
- /* Nothing. Handled through socketcall(). */
-# elif __arm__
-# define __NR_accept4 (UV_SYSCALL_BASE + 366)
-# endif
-#endif /* __NR_accept4 */
-
-#ifndef __NR_eventfd
-# if __x86_64__
-# define __NR_eventfd 284
-# elif __i386__
-# define __NR_eventfd 323
-# elif __arm__
-# define __NR_eventfd (UV_SYSCALL_BASE + 351)
-# endif
-#endif /* __NR_eventfd */
-
-#ifndef __NR_eventfd2
-# if __x86_64__
-# define __NR_eventfd2 290
-# elif __i386__
-# define __NR_eventfd2 328
-# elif __arm__
-# define __NR_eventfd2 (UV_SYSCALL_BASE + 356)
-# endif
-#endif /* __NR_eventfd2 */
-
-#ifndef __NR_inotify_init
-# if __x86_64__
-# define __NR_inotify_init 253
-# elif __i386__
-# define __NR_inotify_init 291
-# elif __arm__
-# define __NR_inotify_init (UV_SYSCALL_BASE + 316)
-# endif
-#endif /* __NR_inotify_init */
-
-#ifndef __NR_inotify_init1
-# if __x86_64__
-# define __NR_inotify_init1 294
-# elif __i386__
-# define __NR_inotify_init1 332
-# elif __arm__
-# define __NR_inotify_init1 (UV_SYSCALL_BASE + 360)
-# endif
-#endif /* __NR_inotify_init1 */
-
-#ifndef __NR_inotify_add_watch
-# if __x86_64__
-# define __NR_inotify_add_watch 254
-# elif __i386__
-# define __NR_inotify_add_watch 292
-# elif __arm__
-# define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317)
-# endif
-#endif /* __NR_inotify_add_watch */
-
-#ifndef __NR_inotify_rm_watch
-# if __x86_64__
-# define __NR_inotify_rm_watch 255
-# elif __i386__
-# define __NR_inotify_rm_watch 293
-# elif __arm__
-# define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318)
-# endif
-#endif /* __NR_inotify_rm_watch */
-
-#ifndef __NR_pipe2
-# if __x86_64__
-# define __NR_pipe2 293
-# elif __i386__
-# define __NR_pipe2 331
-# elif __arm__
-# define __NR_pipe2 (UV_SYSCALL_BASE + 359)
-# endif
-#endif /* __NR_pipe2 */
-
-#ifndef __NR_recvmmsg
-# if __x86_64__
-# define __NR_recvmmsg 299
-# elif __i386__
-# define __NR_recvmmsg 337
-# elif __arm__
-# define __NR_recvmmsg (UV_SYSCALL_BASE + 365)
-# endif
-#endif /* __NR_recvmsg */
-
-#ifndef __NR_sendmmsg
-# if __x86_64__
-# define __NR_sendmmsg 307
-# elif __i386__
-# define __NR_sendmmsg 345
-# elif __arm__
-# define __NR_sendmmsg (UV_SYSCALL_BASE + 374)
-# endif
-#endif /* __NR_sendmmsg */
-
-#ifndef __NR_utimensat
-# if __x86_64__
-# define __NR_utimensat 280
-# elif __i386__
-# define __NR_utimensat 320
-# elif __arm__
-# define __NR_utimensat (UV_SYSCALL_BASE + 348)
-# endif
-#endif /* __NR_utimensat */
-
-
-int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
-#if __i386__
- unsigned long args[4];
- int r;
-
- args[0] = (unsigned long) fd;
- args[1] = (unsigned long) addr;
- args[2] = (unsigned long) addrlen;
- args[3] = (unsigned long) flags;
-
- r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args);
-
- /* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does
- * a bad flags argument. Try to distinguish between the two cases.
- */
- if (r == -1)
- if (errno == EINVAL)
- if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0)
- errno = ENOSYS;
-
- return r;
-#elif __NR_accept4
- return syscall(__NR_accept4, fd, addr, addrlen, flags);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__eventfd(unsigned int count) {
-#if __NR_eventfd
- return syscall(__NR_eventfd, count);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__eventfd2(unsigned int count, int flags) {
-#if __NR_eventfd2
- return syscall(__NR_eventfd2, count, flags);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__inotify_init(void) {
-#if __NR_inotify_init
- return syscall(__NR_inotify_init);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__inotify_init1(int flags) {
-#if __NR_inotify_init1
- return syscall(__NR_inotify_init1, flags);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__inotify_add_watch(int fd, const char* path, __u32 mask) {
-#if __NR_inotify_add_watch
- return syscall(__NR_inotify_add_watch, fd, path, mask);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__inotify_rm_watch(int fd, __s32 wd) {
-#if __NR_inotify_rm_watch
- return syscall(__NR_inotify_rm_watch, fd, wd);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__pipe2(int pipefd[2], int flags) {
-#if __NR_pipe2
- return syscall(__NR_pipe2, pipefd, flags);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__sendmmsg(int fd,
- struct uv__mmsghdr* mmsg,
- unsigned int vlen,
- unsigned int flags) {
-#if __NR_sendmmsg
- return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__recvmmsg(int fd,
- struct uv__mmsghdr* mmsg,
- unsigned int vlen,
- unsigned int flags,
- struct timespec* timeout) {
-#if __NR_recvmmsg
- return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__utimesat(int dirfd,
- const char* path,
- const struct timespec times[2],
- int flags)
-{
-#if __NR_utimensat
- return syscall(__NR_utimensat, dirfd, path, times, flags);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
diff --git a/deps/uv/src/unix/linux/syscalls.h b/deps/uv/src/unix/linux/syscalls.h
deleted file mode 100644
index ec70fd962..000000000
--- a/deps/uv/src/unix/linux/syscalls.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* 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.
- */
-
-#ifndef UV_LINUX_SYSCALL_H_
-#define UV_LINUX_SYSCALL_H_
-
-#undef _GNU_SOURCE
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <linux/types.h>
-
-#define UV__O_NONBLOCK 0x800
-#define UV__O_CLOEXEC 0x80000
-
-#define UV__EFD_CLOEXEC UV__O_CLOEXEC
-#define UV__EFD_NONBLOCK UV__O_NONBLOCK
-
-#define UV__IN_CLOEXEC UV__O_CLOEXEC
-#define UV__IN_NONBLOCK UV__O_NONBLOCK
-
-#define UV__SOCK_CLOEXEC UV__O_CLOEXEC
-#define UV__SOCK_NONBLOCK UV__O_NONBLOCK
-
-/* inotify flags */
-#define UV__IN_ACCESS 0x001
-#define UV__IN_MODIFY 0x002
-#define UV__IN_ATTRIB 0x004
-#define UV__IN_CLOSE_WRITE 0x008
-#define UV__IN_CLOSE_NOWRITE 0x010
-#define UV__IN_OPEN 0x020
-#define UV__IN_MOVED_FROM 0x040
-#define UV__IN_MOVED_TO 0x080
-#define UV__IN_CREATE 0x100
-#define UV__IN_DELETE 0x200
-#define UV__IN_DELETE_SELF 0x400
-#define UV__IN_MOVE_SELF 0x800
-
-struct uv__inotify_event {
- __s32 wd;
- __u32 mask;
- __u32 cookie;
- __u32 len;
- /* char name[0]; */
-};
-
-struct uv__mmsghdr {
- struct msghdr msg_hdr;
- unsigned int msg_len;
-};
-
-int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags);
-int uv__eventfd(unsigned int count);
-int uv__eventfd2(unsigned int count, int flags);
-int uv__inotify_init(void);
-int uv__inotify_init1(int flags);
-int uv__inotify_add_watch(int fd, const char* path, __u32 mask);
-int uv__inotify_rm_watch(int fd, __s32 wd);
-int uv__pipe2(int pipefd[2], int flags);
-int uv__recvmmsg(int fd,
- struct uv__mmsghdr* mmsg,
- unsigned int vlen,
- unsigned int flags,
- struct timespec* timeout);
-int uv__sendmmsg(int fd,
- struct uv__mmsghdr* mmsg,
- unsigned int vlen,
- unsigned int flags);
-int uv__utimesat(int dirfd,
- const char* path,
- const struct timespec times[2],
- int flags);
-
-#endif /* UV_LINUX_SYSCALL_H_ */
diff --git a/deps/uv/src/unix/loop-watcher.c b/deps/uv/src/unix/loop-watcher.c
index 6e6a68903..a07569e40 100644
--- a/deps/uv/src/unix/loop-watcher.c
+++ b/deps/uv/src/unix/loop-watcher.c
@@ -25,13 +25,14 @@
#define UV_LOOP_WATCHER_DEFINE(name, type) \
int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
uv__handle_init(loop, (uv_handle_t*)handle, UV_##type); \
- loop->counters.name##_init++; \
handle->name##_cb = NULL; \
return 0; \
} \
\
int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \
if (uv__is_active(handle)) return 0; \
+ if (cb == NULL) \
+ return uv__set_artificial_error(handle->loop, UV_EINVAL); \
ngx_queue_insert_head(&handle->loop->name##_handles, &handle->queue); \
handle->name##_cb = cb; \
uv__handle_start(handle); \
@@ -50,7 +51,7 @@
ngx_queue_t* q; \
ngx_queue_foreach(q, &loop->name##_handles) { \
h = ngx_queue_data(q, uv_##name##_t, queue); \
- if (h->name##_cb) h->name##_cb(h, 0); \
+ h->name##_cb(h, 0); \
} \
} \
\
diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c
index fcf9faf30..75b0702a3 100644
--- a/deps/uv/src/unix/loop.c
+++ b/deps/uv/src/unix/loop.c
@@ -28,54 +28,87 @@
int uv__loop_init(uv_loop_t* loop, int default_loop) {
-#if HAVE_KQUEUE
- int flags = EVBACKEND_KQUEUE;
-#else
- int flags = EVFLAG_AUTO;
-#endif
+ unsigned int i;
- memset(loop, 0, sizeof(*loop));
+ uv__signal_global_once_init();
- RB_INIT(&loop->ares_handles);
+ memset(loop, 0, sizeof(*loop));
RB_INIT(&loop->timer_handles);
+ ngx_queue_init(&loop->wq);
ngx_queue_init(&loop->active_reqs);
ngx_queue_init(&loop->idle_handles);
ngx_queue_init(&loop->async_handles);
ngx_queue_init(&loop->check_handles);
ngx_queue_init(&loop->prepare_handles);
ngx_queue_init(&loop->handle_queue);
+
+ loop->nfds = 0;
+ loop->watchers = NULL;
+ loop->nwatchers = 0;
+ ngx_queue_init(&loop->pending_queue);
+ ngx_queue_init(&loop->watcher_queue);
+
loop->closing_handles = NULL;
- loop->channel = NULL;
- loop->time = uv_hrtime() / 1000000;
- loop->async_pipefd[0] = -1;
- loop->async_pipefd[1] = -1;
- loop->ev = (default_loop ? ev_default_loop : ev_loop_new)(flags);
- ev_set_userdata(loop->ev, loop);
- eio_channel_init(&loop->uv_eio_channel, loop);
-
-#if __linux__
- loop->inotify_watchers = NULL;
- loop->inotify_fd = -1;
-#endif
-#if HAVE_PORTS_FS
- loop->fs_fd = -1;
-#endif
+ loop->time = uv__hrtime() / 1000000;
+ uv__async_init(&loop->async_watcher);
+ loop->signal_pipefd[0] = -1;
+ loop->signal_pipefd[1] = -1;
+ loop->backend_fd = -1;
+ loop->emfile_fd = -1;
+
+ loop->timer_counter = 0;
+ loop->stop_flag = 0;
+
+ if (uv__platform_loop_init(loop, default_loop))
+ return -1;
+
+ uv_signal_init(loop, &loop->child_watcher);
+ uv__handle_unref(&loop->child_watcher);
+ loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
+
+ for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++)
+ ngx_queue_init(loop->process_handles + i);
+
+ if (uv_mutex_init(&loop->wq_mutex))
+ abort();
+
+ if (uv_async_init(loop, &loop->wq_async, uv__work_done))
+ abort();
+
+ uv__handle_unref(&loop->wq_async);
+ loop->wq_async.flags |= UV__HANDLE_INTERNAL;
+
return 0;
}
void uv__loop_delete(uv_loop_t* loop) {
- uv_ares_destroy(loop, loop->channel);
- ev_loop_destroy(loop->ev);
-#if __linux__
- if (loop->inotify_fd != -1) {
- uv__io_stop(loop, &loop->inotify_read_watcher);
- close(loop->inotify_fd);
- loop->inotify_fd = -1;
+ uv__signal_loop_cleanup(loop);
+ uv__platform_loop_delete(loop);
+ uv__async_stop(loop, &loop->async_watcher);
+
+ if (loop->emfile_fd != -1) {
+ close(loop->emfile_fd);
+ loop->emfile_fd = -1;
}
+
+ if (loop->backend_fd != -1) {
+ close(loop->backend_fd);
+ loop->backend_fd = -1;
+ }
+
+ uv_mutex_lock(&loop->wq_mutex);
+ assert(ngx_queue_empty(&loop->wq) && "thread pool work queue not empty!");
+ uv_mutex_unlock(&loop->wq_mutex);
+ uv_mutex_destroy(&loop->wq_mutex);
+
+#if 0
+ assert(ngx_queue_empty(&loop->pending_queue));
+ assert(ngx_queue_empty(&loop->watcher_queue));
+ assert(loop->nfds == 0);
#endif
-#if HAVE_PORTS_FS
- if (loop->fs_fd != -1)
- close(loop->fs_fd);
-#endif
+
+ free(loop->watchers);
+ loop->watchers = NULL;
+ loop->nwatchers = 0;
}
diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c
index 5f7a84849..0fbcf108c 100644
--- a/deps/uv/src/unix/netbsd.c
+++ b/deps/uv/src/unix/netbsd.c
@@ -19,11 +19,21 @@
*/
#include "uv.h"
+#include "internal.h"
#include <assert.h>
#include <string.h>
#include <errno.h>
+#include <kvm.h>
+#include <paths.h>
+#include <ifaddrs.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include <net/if.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/sysctl.h>
@@ -34,25 +44,38 @@
#undef NANOSEC
#define NANOSEC ((uint64_t) 1e9)
+static char *process_title;
+
+
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ return uv__kqueue_init(loop);
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+}
+
-uint64_t uv_hrtime(void) {
+uint64_t uv__hrtime(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
}
+
void uv_loadavg(double avg[3]) {
struct loadavg info;
size_t size = sizeof(info);
int which[] = {CTL_VM, VM_LOADAVG};
- if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
+ if (sysctl(which, 2, &info, &size, NULL, 0) == -1) return;
avg[0] = (double) info.ldavg[0] / info.fscale;
avg[1] = (double) info.ldavg[1] / info.fscale;
avg[2] = (double) info.ldavg[2] / info.fscale;
}
+
int uv_exepath(char* buffer, size_t* size) {
int mib[4];
size_t cb;
@@ -69,7 +92,7 @@ int uv_exepath(char* buffer, size_t* size) {
mib[3] = KERN_PROC_ARGV;
cb = *size;
- if (sysctl(mib, 4, buffer, &cb, NULL, 0) < 0) {
+ if (sysctl(mib, 4, buffer, &cb, NULL, 0) == -1) {
*size = 0;
return -1;
}
@@ -78,18 +101,20 @@ int uv_exepath(char* buffer, size_t* size) {
return 0;
}
+
uint64_t uv_get_free_memory(void) {
struct uvmexp info;
size_t size = sizeof(info);
int which[] = {CTL_VM, VM_UVMEXP};
- if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
+ if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
return -1;
}
return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
}
+
uint64_t uv_get_total_memory(void) {
#if defined(HW_PHYSMEM64)
uint64_t info;
@@ -100,9 +125,229 @@ uint64_t uv_get_total_memory(void) {
#endif
size_t size = sizeof(info);
- if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
+ if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
return -1;
}
return (uint64_t) info;
}
+
+
+char** uv_setup_args(int argc, char** argv) {
+ process_title = argc ? strdup(argv[0]) : NULL;
+ return argv;
+}
+
+
+uv_err_t uv_set_process_title(const char* title) {
+ if (process_title) free(process_title);
+
+ process_title = strdup(title);
+ setproctitle("%s", title);
+
+ return uv_ok_;
+}
+
+
+uv_err_t uv_get_process_title(char* buffer, size_t size) {
+ if (process_title) {
+ strncpy(buffer, process_title, size);
+ } else {
+ if (size > 0) {
+ buffer[0] = '\0';
+ }
+ }
+
+ return uv_ok_;
+}
+
+
+uv_err_t uv_resident_set_memory(size_t* rss) {
+ kvm_t *kd = NULL;
+ struct kinfo_proc2 *kinfo = NULL;
+ pid_t pid;
+ int nprocs;
+ int max_size = sizeof(struct kinfo_proc2);
+ int page_size;
+
+ page_size = getpagesize();
+ pid = getpid();
+
+ kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open");
+
+ if (kd == NULL) goto error;
+
+ kinfo = kvm_getproc2(kd, KERN_PROC_PID, pid, max_size, &nprocs);
+ if (kinfo == NULL) goto error;
+
+ *rss = kinfo->p_vm_rssize * page_size;
+
+ kvm_close(kd);
+
+ return uv_ok_;
+
+error:
+ if (kd) kvm_close(kd);
+ return uv__new_sys_error(errno);
+}
+
+
+uv_err_t uv_uptime(double* uptime) {
+ time_t now;
+ struct timeval info;
+ size_t size = sizeof(info);
+ static int which[] = {CTL_KERN, KERN_BOOTTIME};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
+ return uv__new_sys_error(errno);
+ }
+
+ now = time(NULL);
+
+ *uptime = (double)(now - info.tv_sec);
+ return uv_ok_;
+}
+
+
+uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK);
+ unsigned int multiplier = ((uint64_t)1000L / ticks);
+ unsigned int cur = 0;
+ uv_cpu_info_t* cpu_info;
+ u_int64_t* cp_times;
+ char model[512];
+ u_int64_t cpuspeed;
+ int numcpus;
+ size_t size;
+ int i;
+
+ size = sizeof(model);
+ if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) == -1 &&
+ sysctlbyname("hw.model", &model, &size, NULL, 0) == -1) {
+ return uv__new_sys_error(errno);
+ }
+
+ size = sizeof(numcpus);
+ if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0) == -1) {
+ return uv__new_sys_error(errno);
+ }
+ *count = numcpus;
+
+ /* Only i386 and amd64 have machdep.tsc_freq */
+ size = sizeof(cpuspeed);
+ if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &size, NULL, 0) == -1) {
+ cpuspeed = 0;
+ }
+
+ size = numcpus * CPUSTATES * sizeof(*cp_times);
+ cp_times = malloc(size);
+ if (cp_times == NULL) {
+ return uv__new_artificial_error(UV_ENOMEM);
+ }
+ if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0) == -1) {
+ return uv__new_sys_error(errno);
+ }
+
+ *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
+ if (!(*cpu_infos)) {
+ free(cp_times);
+ free(*cpu_infos);
+ return uv__new_artificial_error(UV_ENOMEM);
+ }
+
+ for (i = 0; i < numcpus; i++) {
+ cpu_info = &(*cpu_infos)[i];
+ cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier;
+ cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier;
+ cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier;
+ cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier;
+ cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier;
+ cpu_info->model = strdup(model);
+ cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6);
+ cur += CPUSTATES;
+ }
+ free(cp_times);
+ return uv_ok_;
+}
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+uv_err_t uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+ struct ifaddrs *addrs;
+ struct ifaddrs *ent;
+ uv_interface_address_t* address;
+
+ if (getifaddrs(&addrs) != 0) {
+ return uv__new_sys_error(errno);
+ }
+
+ *count = 0;
+
+ /* Count the number of interfaces */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family != PF_INET)) {
+ continue;
+ }
+ (*count)++;
+ }
+
+ *addresses = malloc(*count * sizeof(**addresses));
+
+ if (!(*addresses)) {
+ return uv__new_artificial_error(UV_ENOMEM);
+ }
+
+ address = *addresses;
+
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
+ continue;
+ }
+
+ if (ent->ifa_addr == NULL) {
+ continue;
+ }
+
+ if (ent->ifa_addr->sa_family != PF_INET) {
+ continue;
+ }
+
+ address->name = strdup(ent->ifa_name);
+
+ if (ent->ifa_addr->sa_family == AF_INET6) {
+ address->address.address6 = *((struct sockaddr_in6 *)ent->ifa_addr);
+ } else {
+ address->address.address4 = *((struct sockaddr_in *)ent->ifa_addr);
+ }
+
+ address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK) ? 1 : 0;
+
+ address++;
+ }
+
+ freeifaddrs(addrs);
+
+ return uv_ok_;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(addresses[i].name);
+ }
+
+ free(addresses);
+}
diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c
index a18674fab..4dfcd76b5 100644
--- a/deps/uv/src/unix/openbsd.c
+++ b/deps/uv/src/unix/openbsd.c
@@ -43,7 +43,16 @@
static char *process_title;
-uint64_t uv_hrtime(void) {
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ return uv__kqueue_init(loop);
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+}
+
+
+uint64_t uv__hrtime(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c
index e0502b03d..1185b91a1 100644
--- a/deps/uv/src/unix/pipe.c
+++ b/deps/uv/src/unix/pipe.c
@@ -29,12 +29,11 @@
#include <unistd.h>
#include <stdlib.h>
-static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, int events);
+static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, unsigned int events);
int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
- loop->counters.pipe_init++;
handle->shutdown_req = NULL;
handle->connect_req = NULL;
handle->pipe_fname = NULL;
@@ -58,7 +57,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
bound = 0;
/* Already bound? */
- if (handle->fd >= 0) {
+ if (uv__stream_fd(handle) >= 0) {
uv__set_artificial_error(handle->loop, UV_EINVAL);
goto out;
}
@@ -90,7 +89,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
/* Success. */
handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
- handle->fd = sockfd;
+ handle->io_watcher.fd = sockfd;
status = 0;
out:
@@ -118,21 +117,18 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
saved_errno = errno;
status = -1;
- if (handle->fd == -1) {
+ if (uv__stream_fd(handle) == -1) {
uv__set_artificial_error(handle->loop, UV_EINVAL);
goto out;
}
- assert(handle->fd >= 0);
+ assert(uv__stream_fd(handle) >= 0);
- if ((status = listen(handle->fd, backlog)) == -1) {
+ if ((status = listen(uv__stream_fd(handle), backlog)) == -1) {
uv__set_sys_error(handle->loop, errno);
} else {
handle->connection_cb = cb;
- uv__io_init(&handle->read_watcher,
- uv__pipe_accept,
- handle->fd,
- UV__IO_READ);
- uv__io_start(handle->loop, &handle->read_watcher);
+ handle->io_watcher.cb = uv__pipe_accept;
+ uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN);
}
out:
@@ -151,16 +147,17 @@ void uv__pipe_close(uv_pipe_t* handle) {
*/
unlink(handle->pipe_fname);
free((void*)handle->pipe_fname);
+ handle->pipe_fname = NULL;
}
uv__stream_close((uv_stream_t*)handle);
}
-void uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
- uv__stream_open((uv_stream_t*)handle,
- fd,
- UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+int uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
+ return uv__stream_open((uv_stream_t*)handle,
+ fd,
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE);
}
@@ -175,11 +172,11 @@ void uv_pipe_connect(uv_connect_t* req,
int r;
saved_errno = errno;
- new_sock = (handle->fd == -1);
+ new_sock = (uv__stream_fd(handle) == -1);
err = -1;
if (new_sock)
- if ((handle->fd = uv__socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
+ if ((handle->io_watcher.fd = uv__socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
goto out;
memset(&saddr, 0, sizeof saddr);
@@ -187,7 +184,8 @@ void uv_pipe_connect(uv_connect_t* req,
saddr.sun_family = AF_UNIX;
do {
- r = connect(handle->fd, (struct sockaddr*)&saddr, sizeof saddr);
+ r = connect(uv__stream_fd(handle),
+ (struct sockaddr*)&saddr, sizeof saddr);
}
while (r == -1 && errno == EINTR);
@@ -197,12 +195,11 @@ void uv_pipe_connect(uv_connect_t* req,
if (new_sock)
if (uv__stream_open((uv_stream_t*)handle,
- handle->fd,
+ uv__stream_fd(handle),
UV_STREAM_READABLE | UV_STREAM_WRITABLE))
goto out;
- uv__io_start(handle->loop, &handle->read_watcher);
- uv__io_start(handle->loop, &handle->write_watcher);
+ uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT);
err = 0;
out:
@@ -216,7 +213,7 @@ out:
/* Force callback to run on next tick in case of error. */
if (err != 0)
- uv__io_feed(handle->loop, &handle->write_watcher, UV__IO_WRITE);
+ uv__io_feed(handle->loop, &handle->io_watcher);
/* Mimic the Windows pipe implementation, always
* return 0 and let the callback handle errors.
@@ -226,17 +223,17 @@ out:
/* TODO merge with uv__server_io()? */
-static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, int events) {
+static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
uv_pipe_t* pipe;
int saved_errno;
int sockfd;
saved_errno = errno;
- pipe = container_of(w, uv_pipe_t, read_watcher);
+ pipe = container_of(w, uv_pipe_t, io_watcher);
assert(pipe->type == UV_NAMED_PIPE);
- sockfd = uv__accept(pipe->fd);
+ sockfd = uv__accept(uv__stream_fd(pipe));
if (sockfd == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
uv__set_sys_error(pipe->loop, errno);
@@ -247,7 +244,7 @@ static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, int events) {
pipe->connection_cb((uv_stream_t*)pipe, 0);
if (pipe->accepted_fd == sockfd) {
/* The user hasn't called uv_accept() yet */
- uv__io_stop(pipe->loop, &pipe->read_watcher);
+ uv__io_stop(pipe->loop, &pipe->io_watcher, UV__POLLIN);
}
}
diff --git a/deps/uv/src/unix/poll.c b/deps/uv/src/unix/poll.c
index 13796ab57..b37a99bec 100644
--- a/deps/uv/src/unix/poll.c
+++ b/deps/uv/src/unix/poll.c
@@ -27,15 +27,14 @@
#include <errno.h>
-static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, int events) {
+static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
uv_poll_t* handle;
int pevents;
handle = container_of(w, uv_poll_t, io_watcher);
- if (events & UV__IO_ERROR) {
- /* An error happened. Libev has implicitly stopped the watcher, but we */
- /* need to fix the refcount. */
+ if (events & UV__POLLERR) {
+ uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT);
uv__handle_stop(handle);
uv__set_sys_error(handle->loop, EBADF);
handle->poll_cb(handle, -1, 0);
@@ -43,9 +42,9 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, int events) {
}
pevents = 0;
- if (events & UV__IO_READ)
+ if (events & UV__POLLIN)
pevents |= UV_READABLE;
- if (events & UV__IO_WRITE)
+ if (events & UV__POLLOUT)
pevents |= UV_WRITABLE;
handle->poll_cb(handle, 0, pevents);
@@ -54,12 +53,8 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, int events) {
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
- loop->counters.poll_init++;
-
- handle->fd = fd;
+ uv__io_init(&handle->io_watcher, uv__poll_io, fd);
handle->poll_cb = NULL;
- uv__io_init(&handle->io_watcher, uv__poll_io, fd, 0);
-
return 0;
}
@@ -71,7 +66,7 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
static void uv__poll_stop(uv_poll_t* handle) {
- uv__io_stop(handle->loop, &handle->io_watcher);
+ uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT);
uv__handle_stop(handle);
}
@@ -89,23 +84,20 @@ int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
assert((pevents & ~(UV_READABLE | UV_WRITABLE)) == 0);
assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
- if (pevents == 0) {
- uv__poll_stop(handle);
+ uv__poll_stop(handle);
+
+ if (pevents == 0)
return 0;
- }
events = 0;
if (pevents & UV_READABLE)
- events |= UV__IO_READ;
+ events |= UV__POLLIN;
if (pevents & UV_WRITABLE)
- events |= UV__IO_WRITE;
-
- uv__io_stop(handle->loop, &handle->io_watcher);
- uv__io_set(&handle->io_watcher, uv__poll_io, handle->fd, events);
- uv__io_start(handle->loop, &handle->io_watcher);
+ events |= UV__POLLOUT;
- handle->poll_cb = poll_cb;
+ uv__io_start(handle->loop, &handle->io_watcher, events);
uv__handle_start(handle);
+ handle->poll_cb = poll_cb;
return 0;
}
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index 9b1747950..267ecb64c 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -22,17 +22,16 @@
#include "uv.h"
#include "internal.h"
+#include <stdio.h>
+#include <stdlib.h>
#include <assert.h>
#include <errno.h>
+
+#include <sys/types.h>
#include <sys/wait.h>
-#include <poll.h>
#include <unistd.h>
-#include <stdio.h>
#include <fcntl.h>
-
-#ifdef __APPLE__
-# include <TargetConditionals.h>
-#endif
+#include <poll.h>
#if defined(__APPLE__) && !TARGET_OS_IPHONE
# include <crt_externs.h>
@@ -42,33 +41,85 @@ extern char **environ;
#endif
-static void uv__chld(EV_P_ ev_child* watcher, int revents) {
- int status = watcher->rstatus;
- int exit_status = 0;
- int term_signal = 0;
- uv_process_t *process = watcher->data;
+static ngx_queue_t* uv__process_queue(uv_loop_t* loop, int pid) {
+ assert(pid > 0);
+ return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles);
+}
- assert(&process->child_watcher == watcher);
- assert(revents & EV_CHILD);
- ev_child_stop(EV_A_ &process->child_watcher);
+static uv_process_t* uv__process_find(uv_loop_t* loop, int pid) {
+ uv_process_t* handle;
+ ngx_queue_t* h;
+ ngx_queue_t* q;
- if (WIFEXITED(status)) {
- exit_status = WEXITSTATUS(status);
- }
+ h = uv__process_queue(loop, pid);
- if (WIFSIGNALED(status)) {
- term_signal = WTERMSIG(status);
+ ngx_queue_foreach(q, h) {
+ handle = ngx_queue_data(q, uv_process_t, queue);
+ if (handle->pid == pid) return handle;
}
- if (process->exit_cb) {
+ return NULL;
+}
+
+
+static void uv__chld(uv_signal_t* handle, int signum) {
+ uv_process_t* process;
+ int exit_status;
+ int term_signal;
+ int status;
+ pid_t pid;
+
+ assert(signum == SIGCHLD);
+
+ for (;;) {
+ pid = waitpid(-1, &status, WNOHANG);
+
+ if (pid == 0)
+ return;
+
+ if (pid == -1) {
+ if (errno == ECHILD)
+ return; /* XXX stop signal watcher? */
+ else
+ abort();
+ }
+
+ process = uv__process_find(handle->loop, pid);
+ if (process == NULL)
+ continue; /* XXX bug? abort? */
+
+ uv__handle_stop(process);
+
+ if (process->exit_cb == NULL)
+ continue;
+
+ exit_status = 0;
+ term_signal = 0;
+
+ if (WIFEXITED(status))
+ exit_status = WEXITSTATUS(status);
+
+ if (WIFSIGNALED(status))
+ term_signal = WTERMSIG(status);
+
+ if (process->errorno) {
+ uv__set_sys_error(process->loop, process->errorno);
+ exit_status = -1; /* execve() failed */
+ }
+
process->exit_cb(process, exit_status, term_signal);
}
}
int uv__make_socketpair(int fds[2], int flags) {
-#if __linux__
+#if defined(__linux__)
+ static int no_cloexec;
+
+ if (no_cloexec)
+ goto skip;
+
if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0)
return 0;
@@ -77,6 +128,10 @@ int uv__make_socketpair(int fds[2], int flags) {
*/
if (errno != EINVAL)
return -1;
+
+ no_cloexec = 1;
+
+skip:
#endif
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
@@ -95,12 +150,21 @@ int uv__make_socketpair(int fds[2], int flags) {
int uv__make_pipe(int fds[2], int flags) {
-#if __linux__
+#if defined(__linux__)
+ static int no_pipe2;
+
+ if (no_pipe2)
+ goto skip;
+
if (uv__pipe2(fds, flags | UV__O_CLOEXEC) == 0)
return 0;
if (errno != ENOSYS)
return -1;
+
+ no_pipe2 = 1;
+
+skip:
#endif
if (pipe(fds))
@@ -122,123 +186,130 @@ int uv__make_pipe(int fds[2], int flags) {
* Used for initializing stdio streams like options.stdin_stream. Returns
* zero on success.
*/
-static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2],
- int writable) {
- int fd = -1;
- switch (container->flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
- UV_INHERIT_STREAM)) {
- case UV_IGNORE:
- return 0;
- case UV_CREATE_PIPE:
- assert(container->data.stream != NULL);
-
- if (container->data.stream->type != UV_NAMED_PIPE) {
- errno = EINVAL;
- return -1;
- }
+static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
+ int mask;
+ int fd;
- return uv__make_socketpair(fds, 0);
- case UV_INHERIT_FD:
- case UV_INHERIT_STREAM:
- if (container->flags & UV_INHERIT_FD) {
- fd = container->data.fd;
- } else {
- fd = container->data.stream->fd;
- }
+ mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM;
- if (fd == -1) {
- errno = EINVAL;
- return -1;
- }
+ switch (container->flags & mask) {
+ case UV_IGNORE:
+ return 0;
- fds[writable ? 1 : 0] = fd;
+ case UV_CREATE_PIPE:
+ assert(container->data.stream != NULL);
+ if (container->data.stream->type != UV_NAMED_PIPE) {
+ errno = EINVAL;
+ return -1;
+ }
+ return uv__make_socketpair(fds, 0);
- return 0;
- default:
- assert(0 && "Unexpected flags");
+ case UV_INHERIT_FD:
+ case UV_INHERIT_STREAM:
+ if (container->flags & UV_INHERIT_FD)
+ fd = container->data.fd;
+ else
+ fd = uv__stream_fd(container->data.stream);
+
+ if (fd == -1) {
+ errno = EINVAL;
return -1;
- }
-}
+ }
+ fds[1] = fd;
+ return 0;
-static int uv__process_stdio_flags(uv_stdio_container_t* container,
- int writable) {
- if (container->data.stream->type == UV_NAMED_PIPE &&
- ((uv_pipe_t*)container->data.stream)->ipc) {
- return UV_STREAM_READABLE | UV_STREAM_WRITABLE;
- } else if (writable) {
- return UV_STREAM_WRITABLE;
- } else {
- return UV_STREAM_READABLE;
+ default:
+ assert(0 && "Unexpected flags");
+ return -1;
}
}
-static int uv__process_open_stream(uv_stdio_container_t* container, int fds[2],
+static int uv__process_open_stream(uv_stdio_container_t* container,
+ int pipefds[2],
int writable) {
- int fd = fds[writable ? 1 : 0];
- int child_fd = fds[writable ? 0 : 1];
int flags;
- /* No need to create stream */
- if (!(container->flags & UV_CREATE_PIPE) || fd < 0) {
+ if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0)
return 0;
- }
- assert(child_fd >= 0);
- close(child_fd);
+ if (close(pipefds[1]))
+ if (errno != EINTR && errno != EINPROGRESS)
+ abort();
- uv__nonblock(fd, 1);
- flags = uv__process_stdio_flags(container, writable);
+ pipefds[1] = -1;
+ uv__nonblock(pipefds[0], 1);
- return uv__stream_open((uv_stream_t*)container->data.stream, fd, flags);
+ if (container->data.stream->type == UV_NAMED_PIPE &&
+ ((uv_pipe_t*)container->data.stream)->ipc)
+ flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE;
+ else if (writable)
+ flags = UV_STREAM_WRITABLE;
+ else
+ flags = UV_STREAM_READABLE;
+
+ return uv__stream_open(container->data.stream, pipefds[0], flags);
}
static void uv__process_close_stream(uv_stdio_container_t* container) {
if (!(container->flags & UV_CREATE_PIPE)) return;
-
uv__stream_close((uv_stream_t*)container->data.stream);
}
+static void uv__write_int(int fd, int val) {
+ ssize_t n;
+
+ do
+ n = write(fd, &val, sizeof(val));
+ while (n == -1 && errno == EINTR);
+
+ if (n == -1 && errno == EPIPE)
+ return; /* parent process has quit */
+
+ assert(n == sizeof(val));
+}
+
+
static void uv__process_child_init(uv_process_options_t options,
int stdio_count,
- int* pipes) {
+ int (*pipes)[2],
+ int error_fd) {
+ int close_fd;
+ int use_fd;
int fd;
- if (options.flags & UV_PROCESS_DETACHED) {
+ if (options.flags & UV_PROCESS_DETACHED)
setsid();
- }
- /* Dup fds */
for (fd = 0; fd < stdio_count; fd++) {
- /*
- * stdin has swapped ends of pipe
- * (it's the only one readable stream)
- */
- int close_fd = fd == 0 ? pipes[fd * 2 + 1] : pipes[fd * 2];
- int use_fd = fd == 0 ? pipes[fd * 2] : pipes[fd * 2 + 1];
-
- if (use_fd >= 0) {
+ close_fd = pipes[fd][0];
+ use_fd = pipes[fd][1];
+
+ if (use_fd >= 0)
close(close_fd);
- } else if (fd < 3) {
- /* `/dev/null` stdin, stdout, stderr even if they've flag UV_IGNORE */
+ else if (fd >= 3)
+ continue;
+ else {
+ /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
+ * set
+ */
use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
- if (use_fd < 0) {
+ if (use_fd == -1) {
+ uv__write_int(error_fd, errno);
perror("failed to open stdio");
_exit(127);
}
- } else {
- continue;
}
- if (fd != use_fd) {
+ if (fd == use_fd)
+ uv__cloexec(use_fd, 0);
+ else {
dup2(use_fd, fd);
close(use_fd);
- } else {
- uv__cloexec(use_fd, 0);
}
if (fd <= 2)
@@ -246,16 +317,19 @@ static void uv__process_child_init(uv_process_options_t options,
}
if (options.cwd && chdir(options.cwd)) {
+ uv__write_int(error_fd, errno);
perror("chdir()");
_exit(127);
}
if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
+ uv__write_int(error_fd, errno);
perror("setgid()");
_exit(127);
}
if ((options.flags & UV_PROCESS_SETUID) && setuid(options.uid)) {
+ uv__write_int(error_fd, errno);
perror("setuid()");
_exit(127);
}
@@ -265,64 +339,51 @@ static void uv__process_child_init(uv_process_options_t options,
}
execvp(options.file, options.args);
+ uv__write_int(error_fd, errno);
perror("execvp()");
_exit(127);
}
-#ifndef SPAWN_WAIT_EXEC
-# define SPAWN_WAIT_EXEC 1
-#endif
-
-int uv_spawn(uv_loop_t* loop, uv_process_t* process,
- uv_process_options_t options) {
- /*
- * Save environ in the case that we get it clobbered
- * by the child process.
- */
- char** save_our_env = environ;
-
- int stdio_count = options.stdio_count < 3 ? 3 : options.stdio_count;
- int* pipes = malloc(2 * stdio_count * sizeof(int));
-
-#if SPAWN_WAIT_EXEC
+int uv_spawn(uv_loop_t* loop,
+ uv_process_t* process,
+ const uv_process_options_t options) {
int signal_pipe[2] = { -1, -1 };
- struct pollfd pfd;
-#endif
- int status;
+ int (*pipes)[2];
+ int stdio_count;
+ ngx_queue_t* q;
+ ssize_t r;
pid_t pid;
int i;
- if (pipes == NULL) {
- errno = ENOMEM;
- goto error;
- }
-
assert(options.file != NULL);
- assert(!(options.flags & ~(UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
- UV_PROCESS_DETACHED |
+ assert(!(options.flags & ~(UV_PROCESS_DETACHED |
UV_PROCESS_SETGID |
- UV_PROCESS_SETUID)));
-
+ UV_PROCESS_SETUID |
+ UV_PROCESS_WINDOWS_HIDE |
+ UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
- loop->counters.process_init++;
- uv__handle_start(process);
+ ngx_queue_init(&process->queue);
- process->exit_cb = options.exit_cb;
+ stdio_count = options.stdio_count;
+ if (stdio_count < 3)
+ stdio_count = 3;
+
+ pipes = malloc(stdio_count * sizeof(*pipes));
+ if (pipes == NULL) {
+ errno = ENOMEM;
+ goto error;
+ }
- /* Init pipe pairs */
for (i = 0; i < stdio_count; i++) {
- pipes[i * 2] = -1;
- pipes[i * 2 + 1] = -1;
+ pipes[i][0] = -1;
+ pipes[i][1] = -1;
}
- /* Create socketpairs/pipes, or use raw fd */
- for (i = 0; i < options.stdio_count; i++) {
- if (uv__process_init_stdio(&options.stdio[i], pipes + i * 2, i != 0)) {
+ for (i = 0; i < options.stdio_count; i++)
+ if (uv__process_init_stdio(options.stdio + i, pipes[i]))
goto error;
- }
- }
/* This pipe is used by the parent to wait until
* the child has called `execve()`. We need this
@@ -342,81 +403,68 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
*
* To avoid ambiguity, we create a pipe with both ends
* marked close-on-exec. Then, after the call to `fork()`,
- * the parent polls the read end until it sees POLLHUP.
+ * the parent polls the read end until it EOFs or errors with EPIPE.
*/
-#if SPAWN_WAIT_EXEC
- if (uv__make_pipe(signal_pipe, UV__F_NONBLOCK))
+ if (uv__make_pipe(signal_pipe, 0))
goto error;
-#endif
+
+ uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
pid = fork();
if (pid == -1) {
-#if SPAWN_WAIT_EXEC
close(signal_pipe[0]);
close(signal_pipe[1]);
-#endif
- environ = save_our_env;
goto error;
}
if (pid == 0) {
- /* Child */
- uv__process_child_init(options, stdio_count, pipes);
-
- /* Execution never reaches here. */
+ uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]);
+ abort();
}
- /* Parent. */
-
- /* Restore environment. */
- environ = save_our_env;
-
-#if SPAWN_WAIT_EXEC
- /* POLLHUP signals child has exited or execve()'d. */
close(signal_pipe[1]);
- do {
- pfd.fd = signal_pipe[0];
- pfd.events = POLLIN|POLLHUP;
- pfd.revents = 0;
- errno = 0, status = poll(&pfd, 1, -1);
- }
- while (status == -1 && (errno == EINTR || errno == ENOMEM));
- assert((status == 1) && "poll() on pipe read end failed");
- close(signal_pipe[0]);
-#endif
+ process->errorno = 0;
+ do
+ r = read(signal_pipe[0], &process->errorno, sizeof(process->errorno));
+ while (r == -1 && errno == EINTR);
- process->pid = pid;
+ if (r == 0)
+ ; /* okay, EOF */
+ else if (r == sizeof(process->errorno))
+ ; /* okay, read errorno */
+ else if (r == -1 && errno == EPIPE)
+ ; /* okay, got EPIPE */
+ else
+ abort();
- ev_child_init(&process->child_watcher, uv__chld, pid, 0);
- ev_child_start(process->loop->ev, &process->child_watcher);
- process->child_watcher.data = process;
+ close(signal_pipe[0]);
for (i = 0; i < options.stdio_count; i++) {
- if (uv__process_open_stream(&options.stdio[i], pipes + i * 2, i == 0)) {
- int j;
- /* Close all opened streams */
- for (j = 0; j < i; j++) {
- uv__process_close_stream(&options.stdio[j]);
- }
-
+ if (uv__process_open_stream(options.stdio + i, pipes[i], i == 0)) {
+ while (i--) uv__process_close_stream(options.stdio + i);
goto error;
}
}
- free(pipes);
+ q = uv__process_queue(loop, pid);
+ ngx_queue_insert_tail(q, &process->queue);
+ process->pid = pid;
+ process->exit_cb = options.exit_cb;
+ uv__handle_start(process);
+
+ free(pipes);
return 0;
error:
uv__set_sys_error(process->loop, errno);
for (i = 0; i < stdio_count; i++) {
- close(pipes[i * 2]);
- close(pipes[i * 2 + 1]);
+ close(pipes[i][0]);
+ close(pipes[i][1]);
}
-
free(pipes);
return -1;
@@ -447,6 +495,7 @@ uv_err_t uv_kill(int pid, int signum) {
void uv__process_close(uv_process_t* handle) {
- ev_child_stop(handle->loop->ev, &handle->child_watcher);
+ /* TODO stop signal watcher when this is the last handle */
+ ngx_queue_remove(&handle->queue);
uv__handle_stop(handle);
}
diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c
new file mode 100644
index 000000000..6728e2387
--- /dev/null
+++ b/deps/uv/src/unix/proctitle.c
@@ -0,0 +1,103 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+extern void uv__set_process_title(const char* title);
+
+static void* args_mem;
+
+static struct {
+ char* str;
+ size_t len;
+} process_title;
+
+
+char** uv_setup_args(int argc, char** argv) {
+ char** new_argv;
+ size_t size;
+ char* s;
+ int i;
+
+ if (argc <= 0)
+ return argv;
+
+ /* Calculate how much memory we need for the argv strings. */
+ size = 0;
+ for (i = 0; i < argc; i++)
+ size += strlen(argv[i]) + 1;
+
+ process_title.str = argv[0];
+ process_title.len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[0];
+ assert(process_title.len + 1 == size); /* argv memory should be adjacent. */
+
+ /* Add space for the argv pointers. */
+ size += (argc + 1) * sizeof(char*);
+
+ new_argv = malloc(size);
+ if (new_argv == NULL)
+ return argv;
+ args_mem = new_argv;
+
+ /* Copy over the strings and set up the pointer table. */
+ s = (char*) &new_argv[argc + 1];
+ for (i = 0; i < argc; i++) {
+ size = strlen(argv[i]) + 1;
+ memcpy(s, argv[i], size);
+ new_argv[i] = s;
+ s += size;
+ }
+ new_argv[i] = NULL;
+
+ return new_argv;
+}
+
+
+uv_err_t uv_set_process_title(const char* title) {
+ if (process_title.len == 0)
+ return uv_ok_;
+
+ /* No need to terminate, byte after is always '\0'. */
+ strncpy(process_title.str, title, process_title.len);
+ uv__set_process_title(title);
+
+ return uv_ok_;
+}
+
+
+uv_err_t uv_get_process_title(char* buffer, size_t size) {
+ if (process_title.len > 0)
+ strncpy(buffer, process_title.str, size);
+ else if (size > 0)
+ buffer[0] = '\0';
+
+ return uv_ok_;
+}
+
+
+__attribute__((destructor))
+static void free_args_mem(void) {
+ free(args_mem); /* Keep valgrind happy. */
+ args_mem = NULL;
+}
diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c
new file mode 100644
index 000000000..f7fd2e5e4
--- /dev/null
+++ b/deps/uv/src/unix/signal.c
@@ -0,0 +1,455 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+typedef struct {
+ uv_signal_t* handle;
+ int signum;
+} uv__signal_msg_t;
+
+RB_HEAD(uv__signal_tree_s, uv_signal_s);
+
+
+static int uv__signal_unlock();
+static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
+static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
+static void uv__signal_stop(uv_signal_t* handle);
+
+
+static pthread_once_t uv__signal_global_init_guard = PTHREAD_ONCE_INIT;
+static struct uv__signal_tree_s uv__signal_tree =
+ RB_INITIALIZER(uv__signal_tree);
+static int uv__signal_lock_pipefd[2];
+
+
+RB_GENERATE_STATIC(uv__signal_tree_s,
+ uv_signal_s, tree_entry,
+ uv__signal_compare)
+
+
+static void uv__signal_global_init(void) {
+ if (uv__make_pipe(uv__signal_lock_pipefd, 0))
+ abort();
+
+ if (uv__signal_unlock())
+ abort();
+}
+
+
+void uv__signal_global_once_init(void) {
+ pthread_once(&uv__signal_global_init_guard, uv__signal_global_init);
+}
+
+
+
+static int uv__signal_lock(void) {
+ int r;
+ char data;
+
+ do {
+ r = read(uv__signal_lock_pipefd[0], &data, sizeof data);
+ } while (r < 0 && errno == EINTR);
+
+ return (r < 0) ? -1 : 0;
+}
+
+
+static int uv__signal_unlock(void) {
+ int r;
+ char data = 42;
+
+ do {
+ r = write(uv__signal_lock_pipefd[1], &data, sizeof data);
+ } while (r < 0 && errno == EINTR);
+
+ return (r < 0) ? -1 : 0;
+}
+
+
+static void uv__signal_block_and_lock(sigset_t* saved_sigmask) {
+ sigset_t new_mask;
+
+ if (sigfillset(&new_mask))
+ abort();
+
+ if (pthread_sigmask(SIG_SETMASK, &new_mask, saved_sigmask))
+ abort();
+
+ if (uv__signal_lock())
+ abort();
+}
+
+
+static void uv__signal_unlock_and_unblock(sigset_t* saved_sigmask) {
+ if (uv__signal_unlock())
+ abort();
+
+ if (pthread_sigmask(SIG_SETMASK, saved_sigmask, NULL))
+ abort();
+}
+
+
+inline static uv_signal_t* uv__signal_first_handle(int signum) {
+ /* This function must be called with the signal lock held. */
+ uv_signal_t lookup;
+ uv_signal_t* handle;
+
+ lookup.signum = signum;
+ lookup.loop = NULL;
+
+ handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup);
+
+ if (handle != NULL && handle->signum == signum)
+ return handle;
+
+ return NULL;
+}
+
+
+static void uv__signal_handler(int signum) {
+ uv__signal_msg_t msg;
+ uv_signal_t* handle;
+ int saved_errno;
+
+ saved_errno = errno;
+ memset(&msg, 0, sizeof msg);
+
+ uv__signal_lock();
+
+ for (handle = uv__signal_first_handle(signum);
+ handle != NULL && handle->signum == signum;
+ handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) {
+ int r;
+
+ msg.signum = signum;
+ msg.handle = handle;
+
+ /* write() should be atomic for small data chunks, so the entire message
+ * should be written at once. In theory the pipe could become full, in
+ * which case the user is out of luck.
+ */
+ do {
+ r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg);
+ } while (r == -1 && errno == EINTR);
+
+ assert(r == sizeof msg ||
+ (r == -1 && errno != EAGAIN && errno != EWOULDBLOCK));
+
+ if (r != -1)
+ handle->caught_signals++;
+ }
+
+ uv__signal_unlock();
+ errno = saved_errno;
+}
+
+
+static uv_err_t uv__signal_register_handler(int signum) {
+ /* When this function is called, the signal lock must be held. */
+ struct sigaction sa;
+
+ /* XXX use a separate signal stack? */
+ memset(&sa, 0, sizeof(sa));
+ if (sigfillset(&sa.sa_mask))
+ abort();
+ sa.sa_handler = uv__signal_handler;
+
+ /* XXX save old action so we can restore it later on? */
+ if (sigaction(signum, &sa, NULL))
+ return uv__new_sys_error(errno);
+
+ return uv_ok_;
+}
+
+
+static void uv__signal_unregister_handler(int signum) {
+ /* When this function is called, the signal lock must be held. */
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_DFL;
+
+ /* sigaction can only fail with EINVAL or EFAULT; an attempt to deregister a
+ * signal implies that it was successfully registered earlier, so EINVAL
+ * should never happen.
+ */
+ if (sigaction(signum, &sa, NULL))
+ abort();
+}
+
+
+static int uv__signal_loop_once_init(uv_loop_t* loop) {
+ /* Return if already initialized. */
+ if (loop->signal_pipefd[0] != -1)
+ return 0;
+
+ if (uv__make_pipe(loop->signal_pipefd, UV__F_NONBLOCK))
+ return -1;
+
+ uv__io_init(&loop->signal_io_watcher,
+ uv__signal_event,
+ loop->signal_pipefd[0]);
+ uv__io_start(loop, &loop->signal_io_watcher, UV__POLLIN);
+
+ return 0;
+}
+
+
+void uv__signal_loop_cleanup(uv_loop_t* loop) {
+ ngx_queue_t* q;
+
+ /* Stop all the signal watchers that are still attached to this loop. This
+ * ensures that the (shared) signal tree doesn't contain any invalid entries
+ * entries, and that signal handlers are removed when appropriate.
+ */
+ ngx_queue_foreach(q, &loop->handle_queue) {
+ uv_handle_t* handle = ngx_queue_data(q, uv_handle_t, handle_queue);
+
+ if (handle->type == UV_SIGNAL)
+ uv__signal_stop((uv_signal_t*) handle);
+ }
+
+ if (loop->signal_pipefd[0] != -1) {
+ close(loop->signal_pipefd[0]);
+ loop->signal_pipefd[0] = -1;
+ }
+
+ if (loop->signal_pipefd[1] != -1) {
+ close(loop->signal_pipefd[1]);
+ loop->signal_pipefd[1] = -1;
+ }
+}
+
+
+int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
+ if (uv__signal_loop_once_init(loop))
+ return uv__set_sys_error(loop, errno);
+
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
+ handle->signum = 0;
+ handle->caught_signals = 0;
+ handle->dispatched_signals = 0;
+
+ return 0;
+}
+
+
+void uv__signal_close(uv_signal_t* handle) {
+
+ uv__signal_stop(handle);
+
+ /* If there are any caught signals "trapped" in the signal pipe, we can't
+ * call the close callback yet. Otherwise, add the handle to the finish_close
+ * queue.
+ */
+ if (handle->caught_signals == handle->dispatched_signals) {
+ uv__make_close_pending((uv_handle_t*) handle);
+ }
+}
+
+
+int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
+ sigset_t saved_sigmask;
+
+ assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
+
+ /* If the user supplies signum == 0, then return an error already. If the
+ * signum is otherwise invalid then uv__signal_register will find out
+ * eventually.
+ */
+ if (signum == 0) {
+ uv__set_artificial_error(handle->loop, UV_EINVAL);
+ return -1;
+ }
+
+ /* Short circuit: if the signal watcher is already watching {signum} don't
+ * go through the process of deregistering and registering the handler.
+ * Additionally, this avoids pending signals getting lost in the small time
+ * time frame that handle->signum == 0.
+ */
+ if (signum == handle->signum) {
+ handle->signal_cb = signal_cb;
+ return 0;
+ }
+
+ /* If the signal handler was already active, stop it first. */
+ if (handle->signum != 0) {
+ uv__signal_stop(handle);
+ }
+
+ uv__signal_block_and_lock(&saved_sigmask);
+
+ /* If at this point there are no active signal watchers for this signum (in
+ * any of the loops), it's time to try and register a handler for it here.
+ */
+ if (uv__signal_first_handle(signum) == NULL) {
+ uv_err_t err = uv__signal_register_handler(signum);
+ if (err.code != UV_OK) {
+ /* Registering the signal handler failed. Must be an invalid signal. */
+ handle->loop->last_err = err;
+ uv__signal_unlock_and_unblock(&saved_sigmask);
+ return -1;
+ }
+ }
+
+ handle->signum = signum;
+ RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle);
+
+ uv__signal_unlock_and_unblock(&saved_sigmask);
+
+ handle->signal_cb = signal_cb;
+ uv__handle_start(handle);
+
+ return 0;
+}
+
+
+static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ uv__signal_msg_t* msg;
+ uv_signal_t* handle;
+ char buf[sizeof(uv__signal_msg_t) * 32];
+ size_t bytes, end, i;
+ int r;
+
+ bytes = 0;
+
+ do {
+ r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes);
+
+ if (r == -1 && errno == EINTR)
+ continue;
+
+ if (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ /* If there are bytes in the buffer already (which really is extremely
+ * unlikely if possible at all) we can't exit the function here. We'll
+ * spin until more bytes are read instead.
+ */
+ if (bytes > 0)
+ continue;
+
+ /* Otherwise, there was nothing there. */
+ return;
+ }
+
+ /* Other errors really should never happen. */
+ if (r == -1)
+ abort();
+
+ bytes += r;
+
+ /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */
+ end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t);
+
+ for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) {
+ msg = (uv__signal_msg_t*) (buf + i);
+ handle = msg->handle;
+
+ if (msg->signum == handle->signum) {
+ assert(!(handle->flags & UV_CLOSING));
+ handle->signal_cb(handle, handle->signum);
+ }
+
+ handle->dispatched_signals++;
+
+ /* If uv_close was called while there were caught signals that were not
+ * yet dispatched, the uv__finish_close was deferred. Make close pending
+ * now if this has happened.
+ */
+ if ((handle->flags & UV_CLOSING) &&
+ (handle->caught_signals == handle->dispatched_signals)) {
+ uv__make_close_pending((uv_handle_t*) handle);
+ }
+ }
+
+ bytes -= end;
+
+ /* If there are any "partial" messages left, move them to the start of the
+ * the buffer, and spin. This should not happen.
+ */
+ if (bytes) {
+ memmove(buf, buf + end, bytes);
+ continue;
+ }
+ } while (end == sizeof buf);
+}
+
+
+static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
+ /* Compare signums first so all watchers with the same signnum end up
+ * adjacent.
+ */
+ if (w1->signum < w2->signum) return -1;
+ if (w1->signum > w2->signum) return 1;
+
+ /* Sort by loop pointer, so we can easily look up the first item after
+ * { .signum = x, .loop = NULL }.
+ */
+ if (w1->loop < w2->loop) return -1;
+ if (w1->loop > w2->loop) return 1;
+
+ if (w1 < w2) return -1;
+ if (w1 > w2) return 1;
+
+ return 0;
+}
+
+
+int uv_signal_stop(uv_signal_t* handle) {
+ assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
+ uv__signal_stop(handle);
+ return 0;
+}
+
+
+static void uv__signal_stop(uv_signal_t* handle) {
+ uv_signal_t* removed_handle;
+ sigset_t saved_sigmask;
+
+ /* If the watcher wasn't started, this is a no-op. */
+ if (handle->signum == 0)
+ return;
+
+ uv__signal_block_and_lock(&saved_sigmask);
+
+ removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle);
+ assert(removed_handle == handle);
+ (void) removed_handle;
+
+ /* Check if there are other active signal watchers observing this signal. If
+ * not, unregister the signal handler.
+ */
+ if (uv__signal_first_handle(handle->signum) == NULL)
+ uv__signal_unregister_handler(handle->signum);
+
+ uv__signal_unlock_and_unblock(&saved_sigmask);
+
+ handle->signum = 0;
+ uv__handle_stop(handle);
+}
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index ce8a1c185..ff420db23 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -34,11 +34,54 @@
#include <sys/un.h>
#include <unistd.h>
+#if defined(__APPLE__)
+# include <sys/event.h>
+# include <sys/time.h>
+# include <sys/select.h>
+
+/* Forward declaration */
+typedef struct uv__stream_select_s uv__stream_select_t;
+
+struct uv__stream_select_s {
+ uv_stream_t* stream;
+ uv_thread_t thread;
+ uv_sem_t sem;
+ uv_mutex_t mutex;
+ uv_async_t async;
+ int events;
+ int fake_fd;
+ int int_fd;
+ int fd;
+};
+#endif /* defined(__APPLE__) */
static void uv__stream_connect(uv_stream_t*);
static void uv__write(uv_stream_t* stream);
static void uv__read(uv_stream_t* stream);
-static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, int events);
+static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
+
+
+/* Used by the accept() EMFILE party trick. */
+static int uv__open_cloexec(const char* path, int flags) {
+ int fd;
+
+#if defined(__linux__)
+ fd = open(path, flags | UV__O_CLOEXEC);
+ if (fd != -1)
+ return fd;
+
+ if (errno != EINVAL)
+ return -1;
+
+ /* O_CLOEXEC not supported. */
+#endif
+
+ fd = open(path, flags);
+ if (fd != -1)
+ uv__cloexec(fd, 1);
+
+ return fd;
+}
static size_t uv__buf_count(uv_buf_t bufs[], int bufcnt) {
@@ -57,56 +100,290 @@ void uv__stream_init(uv_loop_t* loop,
uv_stream_t* stream,
uv_handle_type type) {
uv__handle_init(loop, (uv_handle_t*)stream, type);
- loop->counters.stream_init++;
-
+ stream->read_cb = NULL;
+ stream->read2_cb = NULL;
stream->alloc_cb = NULL;
stream->close_cb = NULL;
stream->connection_cb = NULL;
stream->connect_req = NULL;
stream->shutdown_req = NULL;
stream->accepted_fd = -1;
- stream->fd = -1;
stream->delayed_error = 0;
ngx_queue_init(&stream->write_queue);
ngx_queue_init(&stream->write_completed_queue);
stream->write_queue_size = 0;
- uv__io_init(&stream->read_watcher, uv__stream_io, -1, 0);
- uv__io_init(&stream->write_watcher, uv__stream_io, -1, 0);
+ if (loop->emfile_fd == -1)
+ loop->emfile_fd = uv__open_cloexec("/", O_RDONLY);
+
+#if defined(__APPLE__)
+ stream->select = NULL;
+#endif /* defined(__APPLE_) */
+
+ uv__io_init(&stream->io_watcher, uv__stream_io, -1);
}
-int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
- socklen_t yes;
+#if defined(__APPLE__)
+void uv__stream_osx_select(void* arg) {
+ uv_stream_t* stream;
+ uv__stream_select_t* s;
+ char buf[1024];
+ fd_set sread;
+ fd_set swrite;
+ fd_set serror;
+ int events;
+ int fd;
+ int r;
+ int max_fd;
- assert(fd >= 0);
- stream->fd = fd;
+ stream = arg;
+ s = stream->select;
+ fd = stream->io_watcher.fd;
- stream->flags |= flags;
+ if (fd > s->int_fd)
+ max_fd = fd;
+ else
+ max_fd = s->int_fd;
- if (stream->type == UV_TCP) {
- /* Reuse the port address if applicable. */
- yes = 1;
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) {
- uv__set_sys_error(stream->loop, errno);
- return -1;
- }
+ while (1) {
+ /* Terminate on semaphore */
+ if (uv_sem_trywait(&s->sem) == 0)
+ break;
- if ((stream->flags & UV_TCP_NODELAY) &&
- uv__tcp_nodelay((uv_tcp_t*)stream, 1)) {
- return -1;
+ /* Watch fd using select(2) */
+ FD_ZERO(&sread);
+ FD_ZERO(&swrite);
+ FD_ZERO(&serror);
+
+ if (uv_is_readable(stream))
+ FD_SET(fd, &sread);
+ if (uv_is_writable(stream))
+ FD_SET(fd, &swrite);
+ FD_SET(fd, &serror);
+ FD_SET(s->int_fd, &sread);
+
+ /* Wait indefinitely for fd events */
+ r = select(max_fd + 1, &sread, &swrite, &serror, NULL);
+ if (r == -1) {
+ if (errno == EINTR)
+ continue;
+
+ /* XXX: Possible?! */
+ abort();
}
+ /* Ignore timeouts */
+ if (r == 0)
+ continue;
+
+ /* Empty socketpair's buffer in case of interruption */
+ if (FD_ISSET(s->int_fd, &sread))
+ while (1) {
+ r = read(s->int_fd, buf, sizeof(buf));
+
+ if (r == sizeof(buf))
+ continue;
+
+ if (r != -1)
+ break;
+
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ break;
+
+ if (errno == EINTR)
+ continue;
+
+ abort();
+ }
+
+ /* Handle events */
+ events = 0;
+ if (FD_ISSET(fd, &sread))
+ events |= UV__POLLIN;
+ if (FD_ISSET(fd, &swrite))
+ events |= UV__POLLOUT;
+ if (FD_ISSET(fd, &serror))
+ events |= UV__POLLERR;
+
+ uv_mutex_lock(&s->mutex);
+ s->events |= events;
+ uv_mutex_unlock(&s->mutex);
+
+ if (events != 0)
+ uv_async_send(&s->async);
+ }
+}
+
+
+void uv__stream_osx_interrupt_select(uv_stream_t* stream) {
+ /* Notify select() thread about state change */
+ uv__stream_select_t* s;
+ int r;
+
+ s = stream->select;
+
+ /* Interrupt select() loop
+ * NOTE: fake_fd and int_fd are socketpair(), thus writing to one will
+ * emit read event on other side
+ */
+ do
+ r = write(s->fake_fd, "x", 1);
+ while (r == -1 && errno == EINTR);
+
+ assert(r == 1);
+}
+
+
+void uv__stream_osx_select_cb(uv_async_t* handle, int status) {
+ uv__stream_select_t* s;
+ uv_stream_t* stream;
+ int events;
+
+ s = container_of(handle, uv__stream_select_t, async);
+ stream = s->stream;
+
+ /* Get and reset stream's events */
+ uv_mutex_lock(&s->mutex);
+ events = s->events;
+ s->events = 0;
+ uv_mutex_unlock(&s->mutex);
+
+ assert(0 == (events & UV__POLLERR));
+
+ /* Invoke callback on event-loop */
+ if ((events & UV__POLLIN) && uv__io_active(&stream->io_watcher, UV__POLLIN))
+ uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLIN);
+
+ if ((events & UV__POLLOUT) && uv__io_active(&stream->io_watcher, UV__POLLOUT))
+ uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLOUT);
+}
+
+
+void uv__stream_osx_cb_close(uv_handle_t* async) {
+ uv__stream_select_t* s;
+
+ s = container_of(async, uv__stream_select_t, async);
+ free(s);
+}
+
+
+int uv__stream_try_select(uv_stream_t* stream, int fd) {
+ /*
+ * kqueue doesn't work with some files from /dev mount on osx.
+ * select(2) in separate thread for those fds
+ */
+
+ struct kevent filter[1];
+ struct kevent events[1];
+ struct timespec timeout;
+ uv__stream_select_t* s;
+ int fds[2];
+ int ret;
+ int kq;
+
+ kq = kqueue();
+ if (kq == -1) {
+ fprintf(stderr, "(libuv) Failed to create kqueue (%d)\n", errno);
+ return uv__set_sys_error(stream->loop, errno);
+ }
+
+ EV_SET(&filter[0], fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
+
+ /* Use small timeout, because we only want to capture EINVALs */
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 1;
+
+ ret = kevent(kq, filter, 1, events, 1, &timeout);
+ SAVE_ERRNO(close(kq));
+
+ if (ret == -1)
+ return uv__set_sys_error(stream->loop, errno);
+
+ if ((events[0].flags & EV_ERROR) == 0 || events[0].data != EINVAL)
+ return 0;
+
+ /* At this point we definitely know that this fd won't work with kqueue */
+ s = malloc(sizeof(*s));
+ if (s == NULL)
+ return uv__set_artificial_error(stream->loop, UV_ENOMEM);
+
+ s->fd = fd;
+
+ if (uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb)) {
+ SAVE_ERRNO(free(s));
+ return uv__set_sys_error(stream->loop, errno);
+ }
+
+ s->async.flags |= UV__HANDLE_INTERNAL;
+ uv__handle_unref(&s->async);
+
+ if (uv_sem_init(&s->sem, 0))
+ goto fatal1;
+
+ if (uv_mutex_init(&s->mutex))
+ goto fatal2;
+
+ /* Create fds for io watcher and to interrupt the select() loop. */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
+ goto fatal3;
+
+ s->fake_fd = fds[0];
+ s->int_fd = fds[1];
+
+ if (uv_thread_create(&s->thread, uv__stream_osx_select, stream))
+ goto fatal4;
+
+ s->stream = stream;
+ stream->select = s;
+
+ return 0;
+
+fatal4:
+ close(s->fake_fd);
+ close(s->int_fd);
+ s->fake_fd = -1;
+ s->int_fd = -1;
+fatal3:
+ uv_mutex_destroy(&s->mutex);
+fatal2:
+ uv_sem_destroy(&s->sem);
+fatal1:
+ uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
+ return uv__set_sys_error(stream->loop, errno);
+}
+#endif /* defined(__APPLE__) */
+
+
+int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
+ assert(fd >= 0);
+ stream->flags |= flags;
+
+ if (stream->type == UV_TCP) {
+ if ((stream->flags & UV_TCP_NODELAY) && uv__tcp_nodelay(fd, 1))
+ return uv__set_sys_error(stream->loop, errno);
+
/* TODO Use delay the user passed in. */
- if ((stream->flags & UV_TCP_KEEPALIVE) &&
- uv__tcp_keepalive((uv_tcp_t*)stream, 1, 60)) {
- return -1;
- }
+ if ((stream->flags & UV_TCP_KEEPALIVE) && uv__tcp_keepalive(fd, 1, 60))
+ return uv__set_sys_error(stream->loop, errno);
}
- /* Associate the fd with each watcher. */
- uv__io_set(&stream->read_watcher, uv__stream_io, fd, UV__IO_READ);
- uv__io_set(&stream->write_watcher, uv__stream_io, fd, UV__IO_WRITE);
+#if defined(__APPLE__)
+ {
+ uv__stream_select_t* s;
+ int r;
+
+ r = uv__stream_try_select(stream, fd);
+ if (r == -1)
+ return r;
+
+ s = stream->select;
+ if (s != NULL)
+ fd = s->fake_fd;
+ }
+#endif /* defined(__APPLE__) */
+
+ stream->io_watcher.fd = fd;
return 0;
}
@@ -116,11 +393,12 @@ void uv__stream_destroy(uv_stream_t* stream) {
uv_write_t* req;
ngx_queue_t* q;
+ assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT));
assert(stream->flags & UV_CLOSED);
if (stream->connect_req) {
uv__req_unregister(stream->loop, stream->connect_req);
- uv__set_artificial_error(stream->loop, UV_EINTR);
+ uv__set_artificial_error(stream->loop, UV_ECANCELED);
stream->connect_req->cb(stream->connect_req, -1);
stream->connect_req = NULL;
}
@@ -136,7 +414,7 @@ void uv__stream_destroy(uv_stream_t* stream) {
free(req->bufs);
if (req->cb) {
- uv__set_artificial_error(req->handle->loop, UV_EINTR);
+ uv__set_artificial_error(req->handle->loop, UV_ECANCELED);
req->cb(req, -1);
}
}
@@ -156,56 +434,147 @@ void uv__stream_destroy(uv_stream_t* stream) {
if (stream->shutdown_req) {
uv__req_unregister(stream->loop, stream->shutdown_req);
- uv__set_artificial_error(stream->loop, UV_EINTR);
+ uv__set_artificial_error(stream->loop, UV_ECANCELED);
stream->shutdown_req->cb(stream->shutdown_req, -1);
stream->shutdown_req = NULL;
}
}
-void uv__server_io(uv_loop_t* loop, uv__io_t* w, int events) {
+/* Implements a best effort approach to mitigating accept() EMFILE errors.
+ * We have a spare file descriptor stashed away that we close to get below
+ * the EMFILE limit. Next, we accept all pending connections and close them
+ * immediately to signal the clients that we're overloaded - and we are, but
+ * we still keep on trucking.
+ *
+ * There is one caveat: it's not reliable in a multi-threaded environment.
+ * The file descriptor limit is per process. Our party trick fails if another
+ * thread opens a file or creates a socket in the time window between us
+ * calling close() and accept().
+ */
+static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
int fd;
- uv_stream_t* stream = container_of(w, uv_stream_t, read_watcher);
+ int r;
- assert(events == UV__IO_READ);
- assert(!(stream->flags & UV_CLOSING));
+ if (loop->emfile_fd == -1)
+ return -1;
- if (stream->accepted_fd >= 0) {
- uv__io_stop(loop, &stream->read_watcher);
- return;
+ close(loop->emfile_fd);
+
+ for (;;) {
+ fd = uv__accept(accept_fd);
+
+ if (fd != -1) {
+ close(fd);
+ continue;
+ }
+
+ if (errno == EINTR)
+ continue;
+
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ r = 0;
+ else
+ r = -1;
+
+ loop->emfile_fd = uv__open_cloexec("/", O_RDONLY);
+
+ return r;
}
+}
+
+
+#if defined(UV_HAVE_KQUEUE)
+# define UV_DEC_BACKLOG(w) w->rcount--;
+#else
+# define UV_DEC_BACKLOG(w) /* no-op */
+#endif /* defined(UV_HAVE_KQUEUE) */
+
+
+void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ static int use_emfile_trick = -1;
+ uv_stream_t* stream;
+ int fd;
+ int r;
+
+ stream = container_of(w, uv_stream_t, io_watcher);
+ assert(events == UV__POLLIN);
+ assert(stream->accepted_fd == -1);
+ assert(!(stream->flags & UV_CLOSING));
+
+ if (stream->accepted_fd == -1)
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN);
/* connection_cb can close the server socket while we're
* in the loop so check it on each iteration.
*/
- while (stream->fd != -1) {
- assert(stream->accepted_fd < 0);
- fd = uv__accept(stream->fd);
+ while (uv__stream_fd(stream) != -1) {
+ assert(stream->accepted_fd == -1);
+#if defined(UV_HAVE_KQUEUE)
+ if (w->rcount <= 0)
+ return;
+#endif /* defined(UV_HAVE_KQUEUE) */
+ fd = uv__accept(uv__stream_fd(stream));
+
+ if (fd == -1) {
+ switch (errno) {
+#if EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
+#endif
+ case EAGAIN:
+ return; /* Not an error. */
+
+ case ECONNABORTED:
+ UV_DEC_BACKLOG(w)
+ continue; /* Ignore. */
+
+ case EMFILE:
+ case ENFILE:
+ if (use_emfile_trick == -1) {
+ const char* val = getenv("UV_ACCEPT_EMFILE_TRICK");
+ use_emfile_trick = (val == NULL || atoi(val) != 0);
+ }
- if (fd < 0) {
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- /* No problem. */
- return;
- } else if (errno == ECONNABORTED) {
- /* ignore */
+ if (use_emfile_trick) {
+ SAVE_ERRNO(r = uv__emfile_trick(loop, uv__stream_fd(stream)));
+ if (r == 0) {
+ UV_DEC_BACKLOG(w)
+ continue;
+ }
+ }
+
+ /* Fall through. */
+
+ default:
+ uv__set_sys_error(loop, errno);
+ stream->connection_cb(stream, -1);
continue;
- } else {
- uv__set_sys_error(stream->loop, errno);
- stream->connection_cb((uv_stream_t*)stream, -1);
- }
- } else {
- stream->accepted_fd = fd;
- stream->connection_cb((uv_stream_t*)stream, 0);
- if (stream->accepted_fd >= 0) {
- /* The user hasn't yet accepted called uv_accept() */
- uv__io_stop(stream->loop, &stream->read_watcher);
- return;
}
}
+
+ UV_DEC_BACKLOG(w)
+
+ stream->accepted_fd = fd;
+ stream->connection_cb(stream, 0);
+
+ if (stream->accepted_fd != -1) {
+ /* The user hasn't yet accepted called uv_accept() */
+ uv__io_stop(loop, &stream->io_watcher, UV__POLLIN);
+ return;
+ }
+
+ if (stream->type == UV_TCP && (stream->flags & UV_TCP_SINGLE_ACCEPT)) {
+ /* Give other processes a chance to accept connections. */
+ struct timespec timeout = { 0, 1 };
+ nanosleep(&timeout, NULL);
+ }
}
}
+#undef UV_DEC_BACKLOG
+
+
int uv_accept(uv_stream_t* server, uv_stream_t* client) {
uv_stream_t* streamServer;
uv_stream_t* streamClient;
@@ -226,15 +595,31 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
goto out;
}
- if (uv__stream_open(streamClient, streamServer->accepted_fd,
- UV_STREAM_READABLE | UV_STREAM_WRITABLE)) {
- /* TODO handle error */
- close(streamServer->accepted_fd);
- streamServer->accepted_fd = -1;
- goto out;
+ switch (streamClient->type) {
+ case UV_NAMED_PIPE:
+ case UV_TCP:
+ if (uv__stream_open(streamClient, streamServer->accepted_fd,
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE)) {
+ /* TODO handle error */
+ close(streamServer->accepted_fd);
+ streamServer->accepted_fd = -1;
+ goto out;
+ }
+ break;
+
+ case UV_UDP:
+ if (uv_udp_open((uv_udp_t*) client, streamServer->accepted_fd)) {
+ close(streamServer->accepted_fd);
+ streamServer->accepted_fd = -1;
+ goto out;
+ }
+ break;
+
+ default:
+ assert(0);
}
- uv__io_start(streamServer->loop, &streamServer->read_watcher);
+ uv__io_start(streamServer->loop, &streamServer->io_watcher, UV__POLLIN);
streamServer->accepted_fd = -1;
status = 0;
@@ -268,33 +653,13 @@ int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
}
-uv_write_t* uv_write_queue_head(uv_stream_t* stream) {
- ngx_queue_t* q;
- uv_write_t* req;
-
- if (ngx_queue_empty(&stream->write_queue)) {
- return NULL;
- }
-
- q = ngx_queue_head(&stream->write_queue);
- if (!q) {
- return NULL;
- }
-
- req = ngx_queue_data(q, struct uv_write_s, queue);
- assert(req);
-
- return req;
-}
-
-
static void uv__drain(uv_stream_t* stream) {
uv_shutdown_t* req;
- assert(!uv_write_queue_head(stream));
+ assert(ngx_queue_empty(&stream->write_queue));
assert(stream->write_queue_size == 0);
- uv__io_stop(stream->loop, &stream->write_watcher);
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
/* Shutdown? */
if ((stream->flags & UV_STREAM_SHUTTING) &&
@@ -306,7 +671,7 @@ static void uv__drain(uv_stream_t* stream) {
stream->shutdown_req = NULL;
uv__req_unregister(stream->loop, req);
- if (shutdown(stream->fd, SHUT_WR)) {
+ if (shutdown(uv__stream_fd(stream), SHUT_WR)) {
/* Error. Report it. User should call uv_close(). */
uv__set_sys_error(stream->loop, errno);
if (req->cb) {
@@ -348,37 +713,43 @@ static void uv__write_req_finish(uv_write_t* req) {
* callback called in the near future.
*/
ngx_queue_insert_tail(&stream->write_completed_queue, &req->queue);
- uv__io_feed(stream->loop, &stream->write_watcher, UV__IO_WRITE);
+ uv__io_feed(stream->loop, &stream->io_watcher);
+}
+
+
+static int uv__handle_fd(uv_handle_t* handle) {
+ switch (handle->type) {
+ case UV_NAMED_PIPE:
+ case UV_TCP:
+ return ((uv_stream_t*) handle)->io_watcher.fd;
+
+ case UV_UDP:
+ return ((uv_udp_t*) handle)->io_watcher.fd;
+
+ default:
+ return -1;
+ }
}
-/* On success returns NULL. On error returns a pointer to the write request
- * which had the error.
- */
static void uv__write(uv_stream_t* stream) {
- uv_write_t* req;
struct iovec* iov;
+ ngx_queue_t* q;
+ uv_write_t* req;
int iovcnt;
ssize_t n;
- if (stream->flags & UV_CLOSING) {
- /* Handle was closed this tick. We've received a stale
- * 'is writable' callback from the event loop, ignore.
- */
- return;
- }
-
start:
- assert(stream->fd >= 0);
+ assert(uv__stream_fd(stream) >= 0);
- /* Get the request at the head of the queue. */
- req = uv_write_queue_head(stream);
- if (!req) {
+ if (ngx_queue_empty(&stream->write_queue)) {
assert(stream->write_queue_size == 0);
return;
}
+ q = ngx_queue_head(&stream->write_queue);
+ req = ngx_queue_data(q, uv_write_t, queue);
assert(req->handle == stream);
/*
@@ -398,7 +769,7 @@ start:
struct msghdr msg;
char scratch[64];
struct cmsghdr *cmsg;
- int fd_to_send = req->send_handle->fd;
+ int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle);
assert(fd_to_send >= 0);
@@ -415,18 +786,24 @@ start:
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = msg.msg_controllen;
- *(int*) CMSG_DATA(cmsg) = fd_to_send;
+
+ /* silence aliasing warning */
+ {
+ void* pv = CMSG_DATA(cmsg);
+ int* pi = pv;
+ *pi = fd_to_send;
+ }
do {
- n = sendmsg(stream->fd, &msg, 0);
+ n = sendmsg(uv__stream_fd(stream), &msg, 0);
}
while (n == -1 && errno == EINTR);
} else {
do {
if (iovcnt == 1) {
- n = write(stream->fd, iov[0].iov_base, iov[0].iov_len);
+ n = write(uv__stream_fd(stream), iov[0].iov_base, iov[0].iov_len);
} else {
- n = writev(stream->fd, iov, iovcnt);
+ n = writev(uv__stream_fd(stream), iov, iovcnt);
}
}
while (n == -1 && errno == EINTR);
@@ -446,7 +823,6 @@ start:
} else {
/* Successful write */
- /* Update the counters. */
while (n >= 0) {
uv_buf_t* buf = &(req->bufs[req->write_index]);
size_t len = buf->len;
@@ -499,7 +875,7 @@ start:
assert(!(stream->flags & UV_STREAM_BLOCKING));
/* We're not done. */
- uv__io_start(stream->loop, &stream->write_watcher);
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT);
}
@@ -524,15 +900,15 @@ static void uv__write_callbacks(uv_stream_t* stream) {
assert(ngx_queue_empty(&stream->write_completed_queue));
/* Write queue drained. */
- if (!uv_write_queue_head(stream)) {
+ if (ngx_queue_empty(&stream->write_queue))
uv__drain(stream);
- }
}
static uv_handle_type uv__handle_type(int fd) {
struct sockaddr_storage ss;
socklen_t len;
+ int type;
memset(&ss, 0, sizeof(ss));
len = sizeof(ss);
@@ -540,14 +916,25 @@ static uv_handle_type uv__handle_type(int fd) {
if (getsockname(fd, (struct sockaddr*)&ss, &len))
return UV_UNKNOWN_HANDLE;
- switch (ss.ss_family) {
- case AF_UNIX:
- return UV_NAMED_PIPE;
- case AF_INET:
- case AF_INET6:
- return UV_TCP;
+ len = sizeof type;
+
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len))
+ return UV_UNKNOWN_HANDLE;
+
+ if (type == SOCK_STREAM) {
+ switch (ss.ss_family) {
+ case AF_UNIX:
+ return UV_NAMED_PIPE;
+ case AF_INET:
+ case AF_INET6:
+ return UV_TCP;
+ }
}
+ if (type == SOCK_DGRAM &&
+ (ss.ss_family == AF_INET || ss.ss_family == AF_INET6))
+ return UV_UDP;
+
return UV_UNKNOWN_HANDLE;
}
@@ -576,11 +963,11 @@ static void uv__read(uv_stream_t* stream) {
assert(buf.len > 0);
assert(buf.base);
- assert(stream->fd >= 0);
+ assert(uv__stream_fd(stream) >= 0);
if (stream->read_cb) {
do {
- nread = read(stream->fd, buf.base, buf.len);
+ nread = read(uv__stream_fd(stream), buf.base, buf.len);
}
while (nread < 0 && errno == EINTR);
} else {
@@ -596,54 +983,44 @@ static void uv__read(uv_stream_t* stream) {
msg.msg_control = (void *) cmsg_space;
do {
- nread = recvmsg(stream->fd, &msg, 0);
+ nread = recvmsg(uv__stream_fd(stream), &msg, 0);
}
while (nread < 0 && errno == EINTR);
}
+#define INVOKE_READ_CB(stream, status, buf, type) \
+ do { \
+ if ((stream)->read_cb != NULL) \
+ (stream)->read_cb((stream), (status), (buf)); \
+ else \
+ (stream)->read2_cb((uv_pipe_t*) (stream), (status), (buf), (type)); \
+ } \
+ while (0)
if (nread < 0) {
/* Error */
if (errno == EAGAIN || errno == EWOULDBLOCK) {
/* Wait for the next one. */
if (stream->flags & UV_STREAM_READING) {
- uv__io_start(stream->loop, &stream->read_watcher);
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN);
}
uv__set_sys_error(stream->loop, EAGAIN);
-
- if (stream->read_cb) {
- stream->read_cb(stream, 0, buf);
- } else {
- stream->read2_cb((uv_pipe_t*)stream, 0, buf, UV_UNKNOWN_HANDLE);
- }
-
- return;
+ INVOKE_READ_CB(stream, 0, buf, UV_UNKNOWN_HANDLE);
} else {
/* Error. User should call uv_close(). */
uv__set_sys_error(stream->loop, errno);
-
- if (stream->read_cb) {
- stream->read_cb(stream, -1, buf);
- } else {
- stream->read2_cb((uv_pipe_t*)stream, -1, buf, UV_UNKNOWN_HANDLE);
- }
-
- assert(!uv__io_active(&stream->read_watcher));
- return;
+ INVOKE_READ_CB(stream, -1, buf, UV_UNKNOWN_HANDLE);
+ assert(!uv__io_active(&stream->io_watcher, UV__POLLIN) &&
+ "stream->read_cb(status=-1) did not call uv_close()");
}
-
+ return;
} else if (nread == 0) {
/* EOF */
- uv__set_artificial_error(stream->loop, UV_EOF);
- uv__io_stop(stream->loop, &stream->read_watcher);
- if (!uv__io_active(&stream->write_watcher))
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN);
+ if (!uv__io_active(&stream->io_watcher, UV__POLLOUT))
uv__handle_stop(stream);
-
- if (stream->read_cb) {
- stream->read_cb(stream, -1, buf);
- } else {
- stream->read2_cb((uv_pipe_t*)stream, -1, buf, UV_UNKNOWN_HANDLE);
- }
+ uv__set_artificial_error(stream->loop, UV_EOF);
+ INVOKE_READ_CB(stream, -1, buf, UV_UNKNOWN_HANDLE);
return;
} else {
/* Successful read */
@@ -670,7 +1047,12 @@ static void uv__read(uv_stream_t* stream) {
fprintf(stderr, "(libuv) ignoring extra FD received\n");
}
- stream->accepted_fd = *(int *) CMSG_DATA(cmsg);
+ /* silence aliasing warning */
+ {
+ void* pv = CMSG_DATA(cmsg);
+ int* pi = pv;
+ stream->accepted_fd = *pi;
+ }
} else {
fprintf(stderr, "ignoring non-SCM_RIGHTS ancillary data: %d\n",
@@ -699,7 +1081,7 @@ static void uv__read(uv_stream_t* stream) {
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE) &&
"uv_shutdown (unix) only supports uv_handle_t right now");
- assert(stream->fd >= 0);
+ assert(uv__stream_fd(stream) >= 0);
if (!(stream->flags & UV_STREAM_WRITABLE) ||
stream->flags & UV_STREAM_SHUT ||
@@ -716,36 +1098,38 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
stream->shutdown_req = req;
stream->flags |= UV_STREAM_SHUTTING;
- uv__io_start(stream->loop, &stream->write_watcher);
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT);
return 0;
}
-static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, int events) {
+static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
uv_stream_t* stream;
- /* either UV__IO_READ or UV__IO_WRITE but not both */
- assert(!!(events & UV__IO_READ) ^ !!(events & UV__IO_WRITE));
-
- if (events & UV__IO_READ)
- stream = container_of(w, uv_stream_t, read_watcher);
- else
- stream = container_of(w, uv_stream_t, write_watcher);
+ stream = container_of(w, uv_stream_t, io_watcher);
assert(stream->type == UV_TCP ||
stream->type == UV_NAMED_PIPE ||
stream->type == UV_TTY);
assert(!(stream->flags & UV_CLOSING));
- if (stream->connect_req)
+ if (stream->connect_req) {
uv__stream_connect(stream);
- else if (events & UV__IO_READ) {
- assert(stream->fd >= 0);
+ return;
+ }
+
+ if (events & UV__POLLIN) {
+ assert(uv__stream_fd(stream) >= 0);
+
uv__read(stream);
+
+ if (uv__stream_fd(stream) == -1)
+ return; /* read_cb closed stream. */
}
- else {
- assert(stream->fd >= 0);
+
+ if (events & UV__POLLOUT) {
+ assert(uv__stream_fd(stream) >= 0);
uv__write(stream);
uv__write_callbacks(stream);
}
@@ -774,8 +1158,12 @@ static void uv__stream_connect(uv_stream_t* stream) {
stream->delayed_error = 0;
} else {
/* Normal situation: we need to get the socket error from the kernel. */
- assert(stream->fd >= 0);
- getsockopt(stream->fd, SOL_SOCKET, SO_ERROR, &error, &errorsize);
+ assert(uv__stream_fd(stream) >= 0);
+ getsockopt(uv__stream_fd(stream),
+ SOL_SOCKET,
+ SO_ERROR,
+ &error,
+ &errorsize);
}
if (error == EINPROGRESS)
@@ -791,24 +1179,29 @@ static void uv__stream_connect(uv_stream_t* stream) {
}
-int uv_write2(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
- uv_stream_t* send_handle, uv_write_cb cb) {
+int uv_write2(uv_write_t* req,
+ uv_stream_t* stream,
+ uv_buf_t bufs[],
+ int bufcnt,
+ uv_stream_t* send_handle,
+ uv_write_cb cb) {
int empty_queue;
- assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
- stream->type == UV_TTY) &&
- "uv_write (unix) does not yet support other types of streams");
+ assert(bufcnt > 0);
+ assert((stream->type == UV_TCP ||
+ stream->type == UV_NAMED_PIPE ||
+ stream->type == UV_TTY) &&
+ "uv_write (unix) does not yet support other types of streams");
- if (stream->fd < 0) {
- uv__set_sys_error(stream->loop, EBADF);
- return -1;
- }
+ if (uv__stream_fd(stream) < 0)
+ return uv__set_artificial_error(stream->loop, UV_EBADF);
if (send_handle) {
- if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) {
- uv__set_sys_error(stream->loop, EOPNOTSUPP);
- return -1;
- }
+ if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc)
+ return uv__set_artificial_error(stream->loop, UV_EINVAL);
+
+ if (uv__stream_fd(send_handle) < 0)
+ return uv__set_artificial_error(stream->loop, UV_EBADF);
}
empty_queue = (stream->write_queue_size == 0);
@@ -821,7 +1214,7 @@ int uv_write2(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
req->send_handle = send_handle;
ngx_queue_init(&req->queue);
- if (bufcnt <= UV_REQ_BUFSML_SIZE)
+ if (bufcnt <= (int) ARRAY_SIZE(req->bufsml))
req->bufs = req->bufsml;
else
req->bufs = malloc(sizeof(uv_buf_t) * bufcnt);
@@ -851,7 +1244,7 @@ int uv_write2(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
* sufficiently flushed in uv__write.
*/
assert(!(stream->flags & UV_STREAM_BLOCKING));
- uv__io_start(stream->loop, &stream->write_watcher);
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT);
}
return 0;
@@ -867,33 +1260,39 @@ int uv_write(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
}
-int uv__read_start_common(uv_stream_t* stream, uv_alloc_cb alloc_cb,
- uv_read_cb read_cb, uv_read2_cb read2_cb) {
+static int uv__read_start_common(uv_stream_t* stream,
+ uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb,
+ uv_read2_cb read2_cb) {
assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
stream->type == UV_TTY);
- if (stream->flags & UV_CLOSING) {
- uv__set_sys_error(stream->loop, EINVAL);
- return -1;
- }
+ if (stream->flags & UV_CLOSING)
+ return uv__set_sys_error(stream->loop, EINVAL);
/* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just
* expresses the desired state of the user.
*/
stream->flags |= UV_STREAM_READING;
+#if defined(__APPLE__)
+ /* Notify select() thread about state change */
+ if (stream->select != NULL)
+ uv__stream_osx_interrupt_select(stream);
+#endif /* defined(__APPLE__) */
+
/* TODO: try to do the read inline? */
/* TODO: keep track of tcp state. If we've gotten a EOF then we should
* not start the IO watcher.
*/
- assert(stream->fd >= 0);
+ assert(uv__stream_fd(stream) >= 0);
assert(alloc_cb);
stream->read_cb = read_cb;
stream->read2_cb = read2_cb;
stream->alloc_cb = alloc_cb;
- uv__io_start(stream->loop, &stream->read_watcher);
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN);
uv__handle_start(stream);
return 0;
@@ -913,9 +1312,16 @@ int uv_read2_start(uv_stream_t* stream, uv_alloc_cb alloc_cb,
int uv_read_stop(uv_stream_t* stream) {
- uv__io_stop(stream->loop, &stream->read_watcher);
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN);
uv__handle_stop(stream);
stream->flags &= ~UV_STREAM_READING;
+
+#if defined(__APPLE__)
+ /* Notify select() thread about state change */
+ if (stream->select != NULL)
+ uv__stream_osx_interrupt_select(stream);
+#endif /* defined(__APPLE__) */
+
stream->read_cb = NULL;
stream->read2_cb = NULL;
stream->alloc_cb = NULL;
@@ -933,18 +1339,50 @@ int uv_is_writable(const uv_stream_t* stream) {
}
+#if defined(__APPLE__)
+int uv___stream_fd(uv_stream_t* handle) {
+ uv__stream_select_t* s;
+
+ s = handle->select;
+ if (s != NULL)
+ return s->fd;
+
+ return handle->io_watcher.fd;
+}
+#endif /* defined(__APPLE__) */
+
+
void uv__stream_close(uv_stream_t* handle) {
+#if defined(__APPLE__)
+ /* Terminate select loop first */
+ if (handle->select != NULL) {
+ uv__stream_select_t* s;
+
+ s = handle->select;
+
+ uv_sem_post(&s->sem);
+ uv__stream_osx_interrupt_select(handle);
+ uv_thread_join(&s->thread);
+ uv_sem_destroy(&s->sem);
+ uv_mutex_destroy(&s->mutex);
+ close(s->fake_fd);
+ close(s->int_fd);
+ uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
+
+ handle->select = NULL;
+ }
+#endif /* defined(__APPLE__) */
+
uv_read_stop(handle);
- uv__io_stop(handle->loop, &handle->write_watcher);
+ uv__io_close(handle->loop, &handle->io_watcher);
- close(handle->fd);
- handle->fd = -1;
+ close(handle->io_watcher.fd);
+ handle->io_watcher.fd = -1;
if (handle->accepted_fd >= 0) {
close(handle->accepted_fd);
handle->accepted_fd = -1;
}
- assert(!uv__io_active(&handle->read_watcher));
- assert(!uv__io_active(&handle->write_watcher));
+ assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT));
}
diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c
index 0dbbe72aa..3fbb50c9b 100644
--- a/deps/uv/src/unix/sunos.c
+++ b/deps/uv/src/unix/sunos.c
@@ -39,15 +39,13 @@
#include <kstat.h>
#include <fcntl.h>
-#if HAVE_PORTS_FS
-# include <sys/port.h>
-# include <port.h>
-
-# define PORT_FIRED 0x69
-# define PORT_UNUSED 0x0
-# define PORT_LOADED 0x99
-# define PORT_DELETED -1
-#endif
+#include <sys/port.h>
+#include <port.h>
+
+#define PORT_FIRED 0x69
+#define PORT_UNUSED 0x0
+#define PORT_LOADED 0x99
+#define PORT_DELETED -1
#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64)
#define PROCFS_FILE_OFFSET_BITS_HACK 1
@@ -63,8 +61,173 @@
#endif
-uint64_t uv_hrtime() {
- return (gethrtime());
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ loop->fs_fd = -1;
+ loop->backend_fd = port_create();
+
+ if (loop->backend_fd == -1)
+ return -1;
+
+ uv__cloexec(loop->backend_fd, 1);
+
+ return 0;
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+ if (loop->fs_fd != -1) {
+ close(loop->fs_fd);
+ loop->fs_fd = -1;
+ }
+
+ if (loop->backend_fd != -1) {
+ close(loop->backend_fd);
+ loop->backend_fd = -1;
+ }
+}
+
+
+void uv__io_poll(uv_loop_t* loop, int timeout) {
+ struct port_event events[1024];
+ struct port_event* pe;
+ struct timespec spec;
+ ngx_queue_t* q;
+ uv__io_t* w;
+ uint64_t base;
+ uint64_t diff;
+ unsigned int nfds;
+ unsigned int i;
+ int saved_errno;
+ int nevents;
+ int count;
+ int fd;
+
+ if (loop->nfds == 0) {
+ assert(ngx_queue_empty(&loop->watcher_queue));
+ return;
+ }
+
+ while (!ngx_queue_empty(&loop->watcher_queue)) {
+ q = ngx_queue_head(&loop->watcher_queue);
+ ngx_queue_remove(q);
+ ngx_queue_init(q);
+
+ w = ngx_queue_data(q, uv__io_t, watcher_queue);
+ assert(w->pevents != 0);
+
+ if (port_associate(loop->backend_fd, PORT_SOURCE_FD, w->fd, w->pevents, 0))
+ abort();
+
+ w->events = w->pevents;
+ }
+
+ assert(timeout >= -1);
+ base = loop->time;
+ count = 48; /* Benchmarks suggest this gives the best throughput. */
+
+ for (;;) {
+ if (timeout != -1) {
+ spec.tv_sec = timeout / 1000;
+ spec.tv_nsec = (timeout % 1000) * 1000000;
+ }
+
+ /* Work around a kernel bug where nfds is not updated. */
+ events[0].portev_source = 0;
+
+ nfds = 1;
+ saved_errno = 0;
+ if (port_getn(loop->backend_fd,
+ events,
+ ARRAY_SIZE(events),
+ &nfds,
+ timeout == -1 ? NULL : &spec)) {
+ /* Work around another kernel bug: port_getn() may return events even
+ * on error.
+ */
+ if (errno == EINTR || errno == ETIME)
+ saved_errno = errno;
+ else
+ abort();
+ }
+
+ /* Update loop->time unconditionally. It's tempting to skip the update when
+ * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
+ * operating system didn't reschedule our process while in the syscall.
+ */
+ SAVE_ERRNO(uv__update_time(loop));
+
+ if (events[0].portev_source == 0) {
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+ goto update_timeout;
+ }
+
+ if (nfds == 0) {
+ assert(timeout != -1);
+ return;
+ }
+
+ nevents = 0;
+
+ for (i = 0; i < nfds; i++) {
+ pe = events + i;
+ fd = pe->portev_object;
+
+ assert(fd >= 0);
+ assert((unsigned) fd < loop->nwatchers);
+
+ w = loop->watchers[fd];
+
+ /* File descriptor that we've stopped watching, ignore. */
+ if (w == NULL)
+ continue;
+
+ w->cb(loop, w, pe->portev_events);
+ nevents++;
+
+ /* Events Ports operates in oneshot mode, rearm timer on next run. */
+ if (w->pevents != 0 && ngx_queue_empty(&w->watcher_queue))
+ ngx_queue_insert_tail(&loop->watcher_queue, &w->watcher_queue);
+ }
+
+ if (nevents != 0) {
+ if (nfds == ARRAY_SIZE(events) && --count != 0) {
+ /* Poll for more events but don't block this time. */
+ timeout = 0;
+ continue;
+ }
+ return;
+ }
+
+ if (saved_errno == ETIME) {
+ assert(timeout != -1);
+ return;
+ }
+
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+update_timeout:
+ assert(timeout > 0);
+
+ diff = loop->time - base;
+ if (diff >= (uint64_t) timeout)
+ return;
+
+ timeout -= diff;
+ }
+}
+
+
+uint64_t uv__hrtime(void) {
+ return gethrtime();
}
@@ -75,7 +238,6 @@ uint64_t uv_hrtime() {
*/
int uv_exepath(char* buffer, size_t* size) {
ssize_t res;
- pid_t pid;
char buf[128];
if (buffer == NULL)
@@ -84,8 +246,7 @@ int uv_exepath(char* buffer, size_t* size) {
if (size == NULL)
return (-1);
- pid = getpid();
- (void) snprintf(buf, sizeof (buf), "/proc/%d/path/a.out", pid);
+ (void) snprintf(buf, sizeof(buf), "/proc/%lu/path/a.out", (unsigned long) getpid());
res = readlink(buf, buffer, *size - 1);
if (res < 0)
@@ -112,7 +273,8 @@ void uv_loadavg(double avg[3]) {
}
-#if HAVE_PORTS_FS
+#if defined(PORT_SOURCE_FILE)
+
static void uv__fs_event_rearm(uv_fs_event_t *handle) {
if (handle->fd == -1)
return;
@@ -128,15 +290,17 @@ static void uv__fs_event_rearm(uv_fs_event_t *handle) {
}
-static void uv__fs_event_read(EV_P_ ev_io* w, int revents) {
+static void uv__fs_event_read(uv_loop_t* loop,
+ uv__io_t* w,
+ unsigned int revents) {
uv_fs_event_t *handle = NULL;
- uv_loop_t *loop_;
timespec_t timeout;
port_event_t pe;
int events;
int r;
- loop_ = container_of(w, uv_loop_t, fs_event_watcher);
+ (void) w;
+ (void) revents;
do {
uint_t n = 1;
@@ -151,7 +315,7 @@ static void uv__fs_event_read(EV_P_ ev_io* w, int revents) {
*/
do {
memset(&timeout, 0, sizeof timeout);
- r = port_getn(loop_->fs_fd, &pe, 1, &n, &timeout);
+ r = port_getn(loop->fs_fd, &pe, 1, &n, &timeout);
}
while (r == -1 && errno == EINTR);
@@ -185,10 +349,6 @@ int uv_fs_event_init(uv_loop_t* loop,
int portfd;
int first_run = 0;
- loop->counters.fs_event_init++;
-
- /* We don't support any flags yet. */
- assert(!flags);
if (loop->fs_fd == -1) {
if ((portfd = port_create()) == -1) {
uv__set_sys_error(loop, errno);
@@ -209,8 +369,8 @@ int uv_fs_event_init(uv_loop_t* loop,
uv__fs_event_rearm(handle);
if (first_run) {
- ev_io_init(&loop->fs_event_watcher, uv__fs_event_read, portfd, EV_READ);
- ev_io_start(loop->ev, &loop->fs_event_watcher);
+ uv__io_init(&loop->fs_event_watcher, uv__fs_event_read, portfd);
+ uv__io_start(loop, &loop->fs_event_watcher, UV__POLLIN);
}
return 0;
@@ -228,14 +388,13 @@ void uv__fs_event_close(uv_fs_event_t* handle) {
uv__handle_stop(handle);
}
-#else /* !HAVE_PORTS_FS */
+#else /* !defined(PORT_SOURCE_FILE) */
int uv_fs_event_init(uv_loop_t* loop,
uv_fs_event_t* handle,
const char* filename,
uv_fs_event_cb cb,
int flags) {
- loop->counters.fs_event_init++;
uv__set_sys_error(loop, ENOSYS);
return -1;
}
@@ -245,7 +404,7 @@ void uv__fs_event_close(uv_fs_event_t* handle) {
UNREACHABLE();
}
-#endif /* HAVE_PORTS_FS */
+#endif /* defined(PORT_SOURCE_FILE) */
char** uv_setup_args(int argc, char** argv) {
@@ -445,7 +604,8 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
address = *addresses;
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
- bzero(&ip, sizeof (ip));
+ memset(&ip, 0, sizeof(ip));
+
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
continue;
}
diff --git a/deps/uv/src/unix/tcp.c b/deps/uv/src/unix/tcp.c
index e6db3b516..a51576ba1 100644
--- a/deps/uv/src/unix/tcp.c
+++ b/deps/uv/src/unix/tcp.c
@@ -22,6 +22,7 @@
#include "uv.h"
#include "internal.h"
+#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
@@ -29,7 +30,6 @@
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP);
- loop->counters.tcp_init++;
return 0;
}
@@ -37,7 +37,7 @@ int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
static int maybe_new_socket(uv_tcp_t* handle, int domain, int flags) {
int sockfd;
- if (handle->fd != -1)
+ if (uv__stream_fd(handle) != -1)
return 0;
sockfd = uv__socket(domain, SOCK_STREAM, 0);
@@ -58,29 +58,21 @@ static int uv__bind(uv_tcp_t* tcp,
int domain,
struct sockaddr* addr,
int addrsize) {
- int saved_errno;
- int status;
-
- saved_errno = errno;
- status = -1;
+ int on;
if (maybe_new_socket(tcp, domain, UV_STREAM_READABLE|UV_STREAM_WRITABLE))
return -1;
- tcp->delayed_error = 0;
- if (bind(tcp->fd, addr, addrsize) == -1) {
- if (errno == EADDRINUSE) {
- tcp->delayed_error = errno;
- } else {
- uv__set_sys_error(tcp->loop, errno);
- goto out;
- }
- }
- status = 0;
+ on = 1;
+ if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
+ return uv__set_sys_error(tcp->loop, errno);
-out:
- errno = saved_errno;
- return status;
+ errno = 0;
+ if (bind(tcp->io_watcher.fd, addr, addrsize) && errno != EADDRINUSE)
+ return uv__set_sys_error(tcp->loop, errno);
+
+ tcp->delayed_error = errno;
+ return 0;
}
@@ -105,7 +97,7 @@ static int uv__connect(uv_connect_t* req,
handle->delayed_error = 0;
do
- r = connect(handle->fd, addr, addrlen);
+ r = connect(uv__stream_fd(handle), addr, addrlen);
while (r == -1 && errno == EINTR);
if (r == -1) {
@@ -127,10 +119,10 @@ static int uv__connect(uv_connect_t* req,
ngx_queue_init(&req->queue);
handle->connect_req = req;
- uv__io_start(handle->loop, &handle->write_watcher);
+ uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT);
if (handle->delayed_error)
- uv__io_feed(handle->loop, &handle->write_watcher, UV__IO_WRITE);
+ uv__io_feed(handle->loop, &handle->io_watcher);
return 0;
}
@@ -152,6 +144,13 @@ int uv__tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
}
+int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
+ return uv__stream_open((uv_stream_t*)handle,
+ sock,
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+}
+
+
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
int* namelen) {
socklen_t socklen;
@@ -167,7 +166,7 @@ int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
goto out;
}
- if (handle->fd < 0) {
+ if (uv__stream_fd(handle) < 0) {
uv__set_sys_error(handle->loop, EINVAL);
rv = -1;
goto out;
@@ -176,7 +175,7 @@ int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
/* sizeof(socklen_t) != sizeof(int) on some systems. */
socklen = (socklen_t)*namelen;
- if (getsockname(handle->fd, name, &socklen) == -1) {
+ if (getsockname(uv__stream_fd(handle), name, &socklen) == -1) {
uv__set_sys_error(handle->loop, errno);
rv = -1;
} else {
@@ -204,7 +203,7 @@ int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
goto out;
}
- if (handle->fd < 0) {
+ if (uv__stream_fd(handle) < 0) {
uv__set_sys_error(handle->loop, EINVAL);
rv = -1;
goto out;
@@ -213,7 +212,7 @@ int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
/* sizeof(socklen_t) != sizeof(int) on some systems. */
socklen = (socklen_t)*namelen;
- if (getpeername(handle->fd, name, &socklen) == -1) {
+ if (getpeername(uv__stream_fd(handle), name, &socklen) == -1) {
uv__set_sys_error(handle->loop, errno);
rv = -1;
} else {
@@ -227,20 +226,30 @@ out:
int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
+ static int single_accept = -1;
+
if (tcp->delayed_error)
return uv__set_sys_error(tcp->loop, tcp->delayed_error);
+ if (single_accept == -1) {
+ const char* val = getenv("UV_TCP_SINGLE_ACCEPT");
+ single_accept = (val != NULL && atoi(val) != 0); /* Off by default. */
+ }
+
+ if (single_accept)
+ tcp->flags |= UV_TCP_SINGLE_ACCEPT;
+
if (maybe_new_socket(tcp, AF_INET, UV_STREAM_READABLE))
return -1;
- if (listen(tcp->fd, backlog))
+ if (listen(tcp->io_watcher.fd, backlog))
return uv__set_sys_error(tcp->loop, errno);
tcp->connection_cb = cb;
/* Start listening for connections. */
- uv__io_set(&tcp->read_watcher, uv__server_io, tcp->fd, UV__IO_READ);
- uv__io_start(tcp->loop, &tcp->read_watcher);
+ tcp->io_watcher.cb = uv__server_io;
+ uv__io_start(tcp->loop, &tcp->io_watcher, UV__POLLIN);
return 0;
}
@@ -276,63 +285,38 @@ int uv__tcp_connect6(uv_connect_t* req,
}
-int uv__tcp_nodelay(uv_tcp_t* handle, int enable) {
- if (setsockopt(handle->fd,
- IPPROTO_TCP,
- TCP_NODELAY,
- &enable,
- sizeof enable) == -1) {
- uv__set_sys_error(handle->loop, errno);
- return -1;
- }
- return 0;
+int uv__tcp_nodelay(int fd, int on) {
+ return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
}
-int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
- if (setsockopt(handle->fd,
- SOL_SOCKET,
- SO_KEEPALIVE,
- &enable,
- sizeof enable) == -1) {
- uv__set_sys_error(handle->loop, errno);
+int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
+ if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
return -1;
- }
#ifdef TCP_KEEPIDLE
- if (enable && setsockopt(handle->fd,
- IPPROTO_TCP,
- TCP_KEEPIDLE,
- &delay,
- sizeof delay) == -1) {
- uv__set_sys_error(handle->loop, errno);
+ if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
return -1;
- }
#endif
/* Solaris/SmartOS, if you don't support keep-alive,
* then don't advertise it in your system headers...
*/
#if defined(TCP_KEEPALIVE) && !defined(__sun)
- if (enable && setsockopt(handle->fd,
- IPPROTO_TCP,
- TCP_KEEPALIVE,
- &delay,
- sizeof delay) == -1) {
- uv__set_sys_error(handle->loop, errno);
+ if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay)))
return -1;
- }
#endif
return 0;
}
-int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
- if (handle->fd != -1 && uv__tcp_nodelay(handle, enable))
- return -1;
+int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
+ if (uv__stream_fd(handle) != -1)
+ if (uv__tcp_nodelay(uv__stream_fd(handle), on))
+ return -1;
- if (enable)
+ if (on)
handle->flags |= UV_TCP_NODELAY;
else
handle->flags &= ~UV_TCP_NODELAY;
@@ -341,23 +325,33 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
}
-int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
- if (handle->fd != -1 && uv__tcp_keepalive(handle, enable, delay))
- return -1;
+int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
+ if (uv__stream_fd(handle) != -1)
+ if (uv__tcp_keepalive(uv__stream_fd(handle), on, delay))
+ return -1;
- if (enable)
+ if (on)
handle->flags |= UV_TCP_KEEPALIVE;
else
handle->flags &= ~UV_TCP_KEEPALIVE;
- /* TODO Store delay if handle->fd == -1 but don't want to enlarge
- * uv_tcp_t with an int that's almost never used...
+ /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge
+ * uv_tcp_t with an int that's almost never used...
*/
return 0;
}
-int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
+int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int on) {
+ if (on)
+ handle->flags |= UV_TCP_SINGLE_ACCEPT;
+ else
+ handle->flags &= ~UV_TCP_SINGLE_ACCEPT;
return 0;
}
+
+
+void uv__tcp_close(uv_tcp_t* handle) {
+ uv__stream_close((uv_stream_t*)handle);
+}
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index 67c787698..e44a77ffc 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -26,6 +26,12 @@
#include <assert.h>
#include <errno.h>
+#if defined(__APPLE__) && defined(__MACH__)
+#include <sys/time.h>
+#endif /* defined(__APPLE__) && defined(__MACH__) */
+
+#undef NANOSEC
+#define NANOSEC ((uint64_t) 1e9)
int uv_thread_join(uv_thread_t *tid) {
if (pthread_join(*tid, NULL))
@@ -170,7 +176,10 @@ void uv_once(uv_once_t* guard, void (*callback)(void)) {
#if defined(__APPLE__) && defined(__MACH__)
int uv_sem_init(uv_sem_t* sem, unsigned int value) {
- return semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, value);
+ if (semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, value))
+ return -1;
+ else
+ return 0;
}
@@ -187,7 +196,13 @@ void uv_sem_post(uv_sem_t* sem) {
void uv_sem_wait(uv_sem_t* sem) {
- if (semaphore_wait(*sem))
+ int r;
+
+ do
+ r = semaphore_wait(*sem);
+ while (r == KERN_ABORTED);
+
+ if (r != KERN_SUCCESS)
abort();
}
@@ -249,3 +264,168 @@ int uv_sem_trywait(uv_sem_t* sem) {
}
#endif /* defined(__APPLE__) && defined(__MACH__) */
+
+
+#if defined(__APPLE__) && defined(__MACH__)
+
+int uv_cond_init(uv_cond_t* cond) {
+ if (pthread_cond_init(cond, NULL))
+ return -1;
+ else
+ return 0;
+}
+
+#else /* !(defined(__APPLE__) && defined(__MACH__)) */
+
+int uv_cond_init(uv_cond_t* cond) {
+ pthread_condattr_t attr;
+
+ if (pthread_condattr_init(&attr))
+ return -1;
+
+ if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
+ goto error2;
+
+ if (pthread_cond_init(cond, &attr))
+ goto error2;
+
+ if (pthread_condattr_destroy(&attr))
+ goto error;
+
+ return 0;
+
+error:
+ pthread_cond_destroy(cond);
+error2:
+ pthread_condattr_destroy(&attr);
+ return -1;
+}
+
+#endif /* defined(__APPLE__) && defined(__MACH__) */
+
+void uv_cond_destroy(uv_cond_t* cond) {
+ if (pthread_cond_destroy(cond))
+ abort();
+}
+
+void uv_cond_signal(uv_cond_t* cond) {
+ if (pthread_cond_signal(cond))
+ abort();
+}
+
+void uv_cond_broadcast(uv_cond_t* cond) {
+ if (pthread_cond_broadcast(cond))
+ abort();
+}
+
+void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+ if (pthread_cond_wait(cond, mutex))
+ abort();
+}
+
+
+int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
+ int r;
+ struct timespec ts;
+
+#if defined(__APPLE__) && defined(__MACH__)
+ ts.tv_sec = timeout / NANOSEC;
+ ts.tv_nsec = timeout % NANOSEC;
+ r = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
+#else
+ timeout += uv__hrtime();
+ ts.tv_sec = timeout / NANOSEC;
+ ts.tv_nsec = timeout % NANOSEC;
+ r = pthread_cond_timedwait(cond, mutex, &ts);
+#endif
+
+
+ if (r == 0)
+ return 0;
+
+ if (r == ETIMEDOUT)
+ return -1;
+
+ abort();
+ return -1; /* Satisfy the compiler. */
+}
+
+
+#if defined(__APPLE__) && defined(__MACH__)
+
+int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+ barrier->n = count;
+ barrier->count = 0;
+
+ if (uv_mutex_init(&barrier->mutex))
+ return -1;
+
+ if (uv_sem_init(&barrier->turnstile1, 0))
+ goto error2;
+
+ if (uv_sem_init(&barrier->turnstile2, 1))
+ goto error;
+
+ return 0;
+
+error:
+ uv_sem_destroy(&barrier->turnstile1);
+error2:
+ uv_mutex_destroy(&barrier->mutex);
+ return -1;
+
+}
+
+
+void uv_barrier_destroy(uv_barrier_t* barrier) {
+ uv_sem_destroy(&barrier->turnstile2);
+ uv_sem_destroy(&barrier->turnstile1);
+ uv_mutex_destroy(&barrier->mutex);
+}
+
+
+void uv_barrier_wait(uv_barrier_t* barrier) {
+ uv_mutex_lock(&barrier->mutex);
+ if (++barrier->count == barrier->n) {
+ uv_sem_wait(&barrier->turnstile2);
+ uv_sem_post(&barrier->turnstile1);
+ }
+ uv_mutex_unlock(&barrier->mutex);
+
+ uv_sem_wait(&barrier->turnstile1);
+ uv_sem_post(&barrier->turnstile1);
+
+ uv_mutex_lock(&barrier->mutex);
+ if (--barrier->count == 0) {
+ uv_sem_wait(&barrier->turnstile1);
+ uv_sem_post(&barrier->turnstile2);
+ }
+ uv_mutex_unlock(&barrier->mutex);
+
+ uv_sem_wait(&barrier->turnstile2);
+ uv_sem_post(&barrier->turnstile2);
+}
+
+#else /* !(defined(__APPLE__) && defined(__MACH__)) */
+
+int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+ if (pthread_barrier_init(barrier, NULL, count))
+ return -1;
+ else
+ return 0;
+}
+
+
+void uv_barrier_destroy(uv_barrier_t* barrier) {
+ if (pthread_barrier_destroy(barrier))
+ abort();
+}
+
+
+void uv_barrier_wait(uv_barrier_t* barrier) {
+ int r = pthread_barrier_wait(barrier);
+ if (r && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ abort();
+}
+
+#endif /* defined(__APPLE__) && defined(__MACH__) */
diff --git a/deps/uv/src/unix/threadpool.c b/deps/uv/src/unix/threadpool.c
new file mode 100644
index 000000000..b071e4a56
--- /dev/null
+++ b/deps/uv/src/unix/threadpool.c
@@ -0,0 +1,257 @@
+/* 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.
+ */
+
+#include "internal.h"
+#include <stdlib.h>
+
+static uv_once_t once = UV_ONCE_INIT;
+static uv_cond_t cond;
+static uv_mutex_t mutex;
+static uv_thread_t threads[4];
+static ngx_queue_t exit_message;
+static ngx_queue_t wq;
+static volatile int initialized;
+
+
+static void uv__cancelled(struct uv__work* w) {
+ abort();
+}
+
+
+/* To avoid deadlock with uv_cancel() it's crucial that the worker
+ * never holds the global mutex and the loop-local mutex at the same time.
+ */
+static void worker(void* arg) {
+ struct uv__work* w;
+ ngx_queue_t* q;
+
+ (void) arg;
+
+ for (;;) {
+ uv_mutex_lock(&mutex);
+
+ while (ngx_queue_empty(&wq))
+ uv_cond_wait(&cond, &mutex);
+
+ q = ngx_queue_head(&wq);
+
+ if (q == &exit_message)
+ uv_cond_signal(&cond);
+ else {
+ ngx_queue_remove(q);
+ ngx_queue_init(q); /* Signal uv_cancel() that the work req is
+ executing. */
+ }
+
+ uv_mutex_unlock(&mutex);
+
+ if (q == &exit_message)
+ break;
+
+ w = ngx_queue_data(q, struct uv__work, wq);
+ w->work(w);
+
+ uv_mutex_lock(&w->loop->wq_mutex);
+ w->work = NULL; /* Signal uv_cancel() that the work req is done
+ executing. */
+ ngx_queue_insert_tail(&w->loop->wq, &w->wq);
+ uv_async_send(&w->loop->wq_async);
+ uv_mutex_unlock(&w->loop->wq_mutex);
+ }
+}
+
+
+static void post(ngx_queue_t* q) {
+ uv_mutex_lock(&mutex);
+ ngx_queue_insert_tail(&wq, q);
+ uv_cond_signal(&cond);
+ uv_mutex_unlock(&mutex);
+}
+
+
+static void init_once(void) {
+ unsigned int i;
+
+ if (uv_cond_init(&cond))
+ abort();
+
+ if (uv_mutex_init(&mutex))
+ abort();
+
+ ngx_queue_init(&wq);
+
+ for (i = 0; i < ARRAY_SIZE(threads); i++)
+ if (uv_thread_create(threads + i, worker, NULL))
+ abort();
+
+ initialized = 1;
+}
+
+
+#if defined(__GNUC__)
+__attribute__((destructor))
+static void cleanup(void) {
+ unsigned int i;
+
+ if (initialized == 0)
+ return;
+
+ post(&exit_message);
+
+ for (i = 0; i < ARRAY_SIZE(threads); i++)
+ if (uv_thread_join(threads + i))
+ abort();
+
+ uv_mutex_destroy(&mutex);
+ uv_cond_destroy(&cond);
+ initialized = 0;
+}
+#endif
+
+
+void uv__work_submit(uv_loop_t* loop,
+ struct uv__work* w,
+ void (*work)(struct uv__work* w),
+ void (*done)(struct uv__work* w, int status)) {
+ uv_once(&once, init_once);
+ w->loop = loop;
+ w->work = work;
+ w->done = done;
+ post(&w->wq);
+}
+
+
+static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
+ int cancelled;
+
+ uv_mutex_lock(&mutex);
+ uv_mutex_lock(&w->loop->wq_mutex);
+
+ cancelled = !ngx_queue_empty(&w->wq) && w->work != NULL;
+ if (cancelled)
+ ngx_queue_remove(&w->wq);
+
+ uv_mutex_unlock(&w->loop->wq_mutex);
+ uv_mutex_unlock(&mutex);
+
+ if (!cancelled)
+ return -1;
+
+ w->work = uv__cancelled;
+ uv_mutex_lock(&loop->wq_mutex);
+ ngx_queue_insert_tail(&loop->wq, &w->wq);
+ uv_async_send(&loop->wq_async);
+ uv_mutex_unlock(&loop->wq_mutex);
+
+ return 0;
+}
+
+
+void uv__work_done(uv_async_t* handle, int status) {
+ struct uv__work* w;
+ uv_loop_t* loop;
+ ngx_queue_t* q;
+ ngx_queue_t wq;
+ int err;
+
+ loop = container_of(handle, uv_loop_t, wq_async);
+ ngx_queue_init(&wq);
+
+ uv_mutex_lock(&loop->wq_mutex);
+ if (!ngx_queue_empty(&loop->wq)) {
+ q = ngx_queue_head(&loop->wq);
+ ngx_queue_split(&loop->wq, q, &wq);
+ }
+ uv_mutex_unlock(&loop->wq_mutex);
+
+ while (!ngx_queue_empty(&wq)) {
+ q = ngx_queue_head(&wq);
+ ngx_queue_remove(q);
+
+ w = container_of(q, struct uv__work, wq);
+ err = (w->work == uv__cancelled) ? -UV_ECANCELED : 0;
+ w->done(w, err);
+ }
+}
+
+
+static void uv__queue_work(struct uv__work* w) {
+ uv_work_t* req = container_of(w, uv_work_t, work_req);
+
+ req->work_cb(req);
+}
+
+
+static void uv__queue_done(struct uv__work* w, int status) {
+ uv_work_t* req;
+
+ req = container_of(w, uv_work_t, work_req);
+ uv__req_unregister(req->loop, req);
+
+ if (req->after_work_cb == NULL)
+ return;
+
+ if (status == -UV_ECANCELED)
+ uv__set_artificial_error(req->loop, UV_ECANCELED);
+
+ req->after_work_cb(req, status ? -1 : 0);
+}
+
+
+int uv_queue_work(uv_loop_t* loop,
+ uv_work_t* req,
+ uv_work_cb work_cb,
+ uv_after_work_cb after_work_cb) {
+ if (work_cb == NULL)
+ return uv__set_artificial_error(loop, UV_EINVAL);
+
+ uv__req_init(loop, req, UV_WORK);
+ req->loop = loop;
+ req->work_cb = work_cb;
+ req->after_work_cb = after_work_cb;
+ uv__work_submit(loop, &req->work_req, uv__queue_work, uv__queue_done);
+ return 0;
+}
+
+
+int uv_cancel(uv_req_t* req) {
+ struct uv__work* wreq;
+ uv_loop_t* loop;
+
+ switch (req->type) {
+ case UV_FS:
+ loop = ((uv_fs_t*) req)->loop;
+ wreq = &((uv_fs_t*) req)->work_req;
+ break;
+ case UV_GETADDRINFO:
+ loop = ((uv_getaddrinfo_t*) req)->loop;
+ wreq = &((uv_getaddrinfo_t*) req)->work_req;
+ break;
+ case UV_WORK:
+ loop = ((uv_work_t*) req)->loop;
+ wreq = &((uv_work_t*) req)->work_req;
+ break;
+ default:
+ return -1;
+ }
+
+ return uv__work_cancel(loop, req, wreq);
+}
diff --git a/deps/uv/src/unix/timer.c b/deps/uv/src/unix/timer.c
index 0d81997bc..41038c8ac 100644
--- a/deps/uv/src/unix/timer.c
+++ b/deps/uv/src/unix/timer.c
@@ -27,9 +27,13 @@ static int uv__timer_cmp(const uv_timer_t* a, const uv_timer_t* b) {
return -1;
if (a->timeout > b->timeout)
return 1;
- if (a < b)
+ /*
+ * compare start_id when both has the same timeout. start_id is
+ * allocated with loop->timer_counter in uv_timer_start().
+ */
+ if (a->start_id < b->start_id)
return -1;
- if (a > b)
+ if (a->start_id > b->start_id)
return 1;
return 0;
}
@@ -39,8 +43,6 @@ RB_GENERATE_STATIC(uv__timers, uv_timer_s, tree_entry, uv__timer_cmp)
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
- loop->counters.timer_init++;
-
uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);
handle->timer_cb = NULL;
@@ -50,17 +52,16 @@ int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
int uv_timer_start(uv_timer_t* handle,
uv_timer_cb cb,
- int64_t timeout,
- int64_t repeat) {
- assert(timeout >= 0);
- assert(repeat >= 0);
-
+ uint64_t timeout,
+ uint64_t repeat) {
if (uv__is_active(handle))
uv_timer_stop(handle);
handle->timer_cb = cb;
handle->timeout = handle->loop->time + timeout;
handle->repeat = repeat;
+ /* start_id is the second index to be compared in uv__timer_cmp() */
+ handle->start_id = handle->loop->timer_counter++;
RB_INSERT(uv__timers, &handle->loop->timer_handles, handle);
uv__handle_start(handle);
@@ -93,24 +94,24 @@ int uv_timer_again(uv_timer_t* handle) {
}
-void uv_timer_set_repeat(uv_timer_t* handle, int64_t repeat) {
- assert(repeat >= 0);
+void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) {
handle->repeat = repeat;
}
-int64_t uv_timer_get_repeat(uv_timer_t* handle) {
+uint64_t uv_timer_get_repeat(const uv_timer_t* handle) {
return handle->repeat;
}
-unsigned int uv__next_timeout(uv_loop_t* loop) {
- uv_timer_t* handle;
+int uv__next_timeout(const uv_loop_t* loop) {
+ const uv_timer_t* handle;
- handle = RB_MIN(uv__timers, &loop->timer_handles);
+ /* RB_MIN expects a non-const tree root. That's okay, it doesn't modify it. */
+ handle = RB_MIN(uv__timers, (struct uv__timers*) &loop->timer_handles);
if (handle == NULL)
- return (unsigned int) -1; /* block indefinitely */
+ return -1; /* block indefinitely */
if (handle->timeout <= loop->time)
return 0;
diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c
index 7193db8bc..49efee7f5 100644
--- a/deps/uv/src/unix/tty.c
+++ b/deps/uv/src/unix/tty.c
@@ -45,15 +45,16 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
tty->flags |= UV_STREAM_BLOCKING;
}
- loop->counters.tty_init++;
tty->mode = 0;
return 0;
}
int uv_tty_set_mode(uv_tty_t* tty, int mode) {
- int fd = tty->fd;
struct termios raw;
+ int fd;
+
+ fd = uv__stream_fd(tty);
if (mode && tty->mode == 0) {
/* on */
@@ -104,7 +105,7 @@ fatal:
int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) {
struct winsize ws;
- if (ioctl(tty->fd, TIOCGWINSZ, &ws) < 0) {
+ if (ioctl(uv__stream_fd(tty), TIOCGWINSZ, &ws) < 0) {
uv__set_sys_error(tty->loop, errno);
return -1;
}
@@ -139,7 +140,7 @@ uv_handle_type uv_guess_handle(uv_file file) {
}
-void uv_tty_reset_mode() {
+void uv_tty_reset_mode(void) {
if (orig_termios_fd >= 0) {
tcsetattr(orig_termios_fd, TCSANOW, &orig_termios);
}
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index 634d4a061..49028985d 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -31,41 +31,24 @@
static void uv__udp_run_completed(uv_udp_t* handle);
static void uv__udp_run_pending(uv_udp_t* handle);
-static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, int revents);
-static void uv__udp_sendmsg(uv_loop_t* loop, uv__io_t* w, int revents);
+static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
+static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
+static void uv__udp_sendmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain);
-static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
- int bufcnt, struct sockaddr* addr, socklen_t addrlen, uv_udp_send_cb send_cb);
-
-
-static void uv__udp_start_watcher(uv_udp_t* handle,
- uv__io_t* w,
- uv__io_cb cb,
- int events) {
- if (uv__io_active(w)) return;
- uv__io_init(w, cb, handle->fd, events);
- uv__io_start(handle->loop, w);
- uv__handle_start(handle);
-}
-
-
-static void uv__udp_stop_watcher(uv_udp_t* handle, uv__io_t* w) {
- if (!uv__io_active(w)) return;
- uv__io_stop(handle->loop, w);
-
- if (!uv__io_active(&handle->read_watcher) &&
- !uv__io_active(&handle->write_watcher))
- {
- uv__handle_stop(handle);
- }
-}
+static int uv__send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ uv_buf_t bufs[],
+ int bufcnt,
+ struct sockaddr* addr,
+ socklen_t addrlen,
+ uv_udp_send_cb send_cb);
void uv__udp_close(uv_udp_t* handle) {
- uv__udp_stop_watcher(handle, &handle->write_watcher);
- uv__udp_stop_watcher(handle, &handle->read_watcher);
- close(handle->fd);
- handle->fd = -1;
+ uv__io_close(handle->loop, &handle->io_watcher);
+ uv__handle_stop(handle);
+ close(handle->io_watcher.fd);
+ handle->io_watcher.fd = -1;
}
@@ -73,9 +56,8 @@ void uv__udp_finish_close(uv_udp_t* handle) {
uv_udp_send_t* req;
ngx_queue_t* q;
- assert(!uv__io_active(&handle->write_watcher));
- assert(!uv__io_active(&handle->read_watcher));
- assert(handle->fd == -1);
+ assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT));
+ assert(handle->io_watcher.fd == -1);
uv__udp_run_completed(handle);
@@ -91,8 +73,7 @@ void uv__udp_finish_close(uv_udp_t* handle) {
req->bufs = NULL;
if (req->send_cb) {
- /* FIXME proper error code like UV_EABORTED */
- uv__set_artificial_error(handle->loop, UV_EINTR);
+ uv__set_artificial_error(handle->loop, UV_ECANCELED);
req->send_cb(req, -1);
}
}
@@ -126,7 +107,7 @@ static void uv__udp_run_pending(uv_udp_t* handle) {
h.msg_iovlen = req->bufcnt;
do {
- size = sendmsg(handle->fd, &h, 0);
+ size = sendmsg(handle->io_watcher.fd, &h, 0);
}
while (size == -1 && errno == EINTR);
@@ -194,7 +175,18 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
}
-static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, int revents) {
+static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
+ if (revents & UV__POLLIN)
+ uv__udp_recvmsg(loop, w, revents);
+
+ if (revents & UV__POLLOUT)
+ uv__udp_sendmsg(loop, w, revents);
+}
+
+
+static void uv__udp_recvmsg(uv_loop_t* loop,
+ uv__io_t* w,
+ unsigned int revents) {
struct sockaddr_storage peer;
struct msghdr h;
uv_udp_t* handle;
@@ -203,9 +195,9 @@ static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, int revents) {
int flags;
int count;
- handle = container_of(w, uv_udp_t, read_watcher);
+ handle = container_of(w, uv_udp_t, io_watcher);
assert(handle->type == UV_UDP);
- assert(revents & UV__IO_READ);
+ assert(revents & UV__POLLIN);
assert(handle->recv_cb != NULL);
assert(handle->alloc_cb != NULL);
@@ -228,7 +220,7 @@ static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, int revents) {
h.msg_iovlen = 1;
do {
- nread = recvmsg(handle->fd, &h, 0);
+ nread = recvmsg(handle->io_watcher.fd, &h, 0);
}
while (nread == -1 && errno == EINTR);
@@ -258,17 +250,19 @@ static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, int revents) {
/* recv_cb callback may decide to pause or close the handle */
while (nread != -1
&& count-- > 0
- && handle->fd != -1
+ && handle->io_watcher.fd != -1
&& handle->recv_cb != NULL);
}
-static void uv__udp_sendmsg(uv_loop_t* loop, uv__io_t* w, int revents) {
+static void uv__udp_sendmsg(uv_loop_t* loop,
+ uv__io_t* w,
+ unsigned int revents) {
uv_udp_t* handle;
- handle = container_of(w, uv_udp_t, write_watcher);
+ handle = container_of(w, uv_udp_t, io_watcher);
assert(handle->type == UV_UDP);
- assert(revents & UV__IO_WRITE);
+ assert(revents & UV__POLLOUT);
assert(!ngx_queue_empty(&handle->write_queue)
|| !ngx_queue_empty(&handle->write_completed_queue));
@@ -281,11 +275,14 @@ static void uv__udp_sendmsg(uv_loop_t* loop, uv__io_t* w, int revents) {
if (!ngx_queue_empty(&handle->write_completed_queue)) {
/* Schedule completion callbacks. */
- uv__io_feed(handle->loop, &handle->write_watcher, UV__IO_WRITE);
+ uv__io_feed(handle->loop, &handle->io_watcher);
}
else if (ngx_queue_empty(&handle->write_queue)) {
/* Pending queue and completion queue empty, stop watcher. */
- uv__udp_stop_watcher(handle, &handle->write_watcher);
+ uv__io_stop(loop, &handle->io_watcher, UV__POLLOUT);
+
+ if (!uv__io_active(&handle->io_watcher, UV__POLLIN))
+ uv__handle_stop(handle);
}
}
@@ -316,17 +313,15 @@ static int uv__bind(uv_udp_t* handle,
goto out;
}
- /* Check for already active socket. */
- if (handle->fd != -1) {
- uv__set_artificial_error(handle->loop, UV_EALREADY);
- goto out;
- }
-
- if ((fd = uv__socket(domain, SOCK_DGRAM, 0)) == -1) {
- uv__set_sys_error(handle->loop, errno);
- goto out;
+ if (handle->io_watcher.fd == -1) {
+ if ((fd = uv__socket(domain, SOCK_DGRAM, 0)) == -1) {
+ uv__set_sys_error(handle->loop, errno);
+ goto out;
+ }
+ handle->io_watcher.fd = fd;
}
+ fd = handle->io_watcher.fd;
yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) {
uv__set_sys_error(handle->loop, errno);
@@ -367,12 +362,14 @@ static int uv__bind(uv_udp_t* handle,
goto out;
}
- handle->fd = fd;
+ handle->io_watcher.fd = fd;
status = 0;
out:
- if (status)
- close(fd);
+ if (status) {
+ close(handle->io_watcher.fd);
+ handle->io_watcher.fd = -1;
+ }
errno = saved_errno;
return status;
@@ -380,12 +377,12 @@ out:
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain) {
- struct sockaddr_storage taddr;
+ unsigned char taddr[sizeof(struct sockaddr_in6)];
socklen_t addrlen;
assert(domain == AF_INET || domain == AF_INET6);
- if (handle->fd != -1)
+ if (handle->io_watcher.fd != -1)
return 0;
switch (domain) {
@@ -416,13 +413,15 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain) {
}
-static int uv__udp_send(uv_udp_send_t* req,
- uv_udp_t* handle,
- uv_buf_t bufs[],
- int bufcnt,
- struct sockaddr* addr,
- socklen_t addrlen,
- uv_udp_send_cb send_cb) {
+static int uv__send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ uv_buf_t bufs[],
+ int bufcnt,
+ struct sockaddr* addr,
+ socklen_t addrlen,
+ uv_udp_send_cb send_cb) {
+ assert(bufcnt > 0);
+
if (uv__udp_maybe_deferred_bind(handle, addr->sa_family))
return -1;
@@ -434,36 +433,30 @@ static int uv__udp_send(uv_udp_send_t* req,
req->handle = handle;
req->bufcnt = bufcnt;
- if (bufcnt <= UV_REQ_BUFSML_SIZE) {
+ if (bufcnt <= (int) ARRAY_SIZE(req->bufsml)) {
req->bufs = req->bufsml;
}
else if ((req->bufs = malloc(bufcnt * sizeof(bufs[0]))) == NULL) {
uv__set_sys_error(handle->loop, ENOMEM);
return -1;
}
- memcpy(req->bufs, bufs, bufcnt * sizeof(bufs[0]));
+ memcpy(req->bufs, bufs, bufcnt * sizeof(bufs[0]));
ngx_queue_insert_tail(&handle->write_queue, &req->queue);
-
- uv__udp_start_watcher(handle,
- &handle->write_watcher,
- uv__udp_sendmsg,
- UV__IO_WRITE);
+ uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT);
+ uv__handle_start(handle);
return 0;
}
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
- memset(handle, 0, sizeof *handle);
-
uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP);
- loop->counters.udp_init++;
-
- handle->fd = -1;
+ handle->alloc_cb = NULL;
+ handle->recv_cb = NULL;
+ uv__io_init(&handle->io_watcher, uv__udp_io, -1);
ngx_queue_init(&handle->write_queue);
ngx_queue_init(&handle->write_completed_queue);
-
return 0;
}
@@ -486,11 +479,58 @@ int uv__udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned flags) {
}
-int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
- const char* interface_addr, uv_membership membership) {
+int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
+ int saved_errno;
+ int status;
+ int yes;
- int optname;
+ saved_errno = errno;
+ status = -1;
+
+ /* Check for already active socket. */
+ if (handle->io_watcher.fd != -1) {
+ uv__set_artificial_error(handle->loop, UV_EALREADY);
+ goto out;
+ }
+
+ yes = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) {
+ uv__set_sys_error(handle->loop, errno);
+ goto out;
+ }
+
+ /* On the BSDs, SO_REUSEADDR lets you reuse an address that's in the TIME_WAIT
+ * state (i.e. was until recently tied to a socket) while SO_REUSEPORT lets
+ * multiple processes bind to the same address. Yes, it's something of a
+ * misnomer but then again, SO_REUSEADDR was already taken.
+ *
+ * None of the above applies to Linux: SO_REUSEADDR implies SO_REUSEPORT on
+ * Linux and hence it does not have SO_REUSEPORT at all.
+ */
+#ifdef SO_REUSEPORT
+ yes = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof yes) == -1) {
+ uv__set_sys_error(handle->loop, errno);
+ goto out;
+ }
+#endif
+
+ handle->io_watcher.fd = sock;
+ status = 0;
+
+out:
+ errno = saved_errno;
+ return status;
+}
+
+
+int uv_udp_set_membership(uv_udp_t* handle,
+ const char* multicast_addr,
+ const char* interface_addr,
+ uv_membership membership) {
struct ip_mreq mreq;
+ int optname;
+
memset(&mreq, 0, sizeof mreq);
if (interface_addr) {
@@ -509,13 +549,15 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
optname = IP_DROP_MEMBERSHIP;
break;
default:
- uv__set_sys_error(handle->loop, EFAULT);
- return -1;
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
}
- if (setsockopt(handle->fd, IPPROTO_IP, optname, (void*) &mreq, sizeof mreq) == -1) {
- uv__set_sys_error(handle->loop, errno);
- return -1;
+ if (setsockopt(handle->io_watcher.fd,
+ IPPROTO_IP,
+ optname,
+ &mreq,
+ sizeof(mreq))) {
+ return uv__set_sys_error(handle->loop, errno);
}
return 0;
@@ -523,7 +565,7 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
-#if __sun
+#if defined(__sun)
char arg = val;
#else
int arg = val;
@@ -532,7 +574,7 @@ static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
if (val < 0 || val > 255)
return uv__set_sys_error(handle->loop, EINVAL);
- if (setsockopt(handle->fd, IPPROTO_IP, option, &arg, sizeof(arg)))
+ if (setsockopt(handle->io_watcher.fd, IPPROTO_IP, option, &arg, sizeof(arg)))
return uv__set_sys_error(handle->loop, errno);
return 0;
@@ -540,8 +582,13 @@ static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
int uv_udp_set_broadcast(uv_udp_t* handle, int on) {
- if (setsockopt(handle->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)))
+ if (setsockopt(handle->io_watcher.fd,
+ SOL_SOCKET,
+ SO_BROADCAST,
+ &on,
+ sizeof(on))) {
return uv__set_sys_error(handle->loop, errno);
+ }
return 0;
}
@@ -551,7 +598,7 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
if (ttl < 1 || ttl > 255)
return uv__set_sys_error(handle->loop, EINVAL);
- if (setsockopt(handle->fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)))
+ if (setsockopt(handle->io_watcher.fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)))
return uv__set_sys_error(handle->loop, errno);
return 0;
@@ -576,7 +623,7 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
/* Don't clobber errno. */
saved_errno = errno;
- if (handle->fd < 0) {
+ if (handle->io_watcher.fd == -1) {
uv__set_sys_error(handle->loop, EINVAL);
rv = -1;
goto out;
@@ -585,7 +632,7 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
/* sizeof(socklen_t) != sizeof(int) on some systems. */
socklen = (socklen_t)*namelen;
- if (getsockname(handle->fd, name, &socklen) == -1) {
+ if (getsockname(handle->io_watcher.fd, name, &socklen) == -1) {
uv__set_sys_error(handle->loop, errno);
rv = -1;
} else {
@@ -598,47 +645,47 @@ out:
}
-int uv_udp_send(uv_udp_send_t* req,
- uv_udp_t* handle,
- uv_buf_t bufs[],
- int bufcnt,
- struct sockaddr_in addr,
- uv_udp_send_cb send_cb) {
- return uv__udp_send(req,
- handle,
- bufs,
- bufcnt,
- (struct sockaddr*)&addr,
- sizeof addr,
- send_cb);
-}
-
-
-int uv_udp_send6(uv_udp_send_t* req,
+int uv__udp_send(uv_udp_send_t* req,
uv_udp_t* handle,
uv_buf_t bufs[],
int bufcnt,
- struct sockaddr_in6 addr,
+ struct sockaddr_in addr,
uv_udp_send_cb send_cb) {
- return uv__udp_send(req,
- handle,
- bufs,
- bufcnt,
- (struct sockaddr*)&addr,
- sizeof addr,
- send_cb);
+ return uv__send(req,
+ handle,
+ bufs,
+ bufcnt,
+ (struct sockaddr*)&addr,
+ sizeof addr,
+ send_cb);
+}
+
+
+int uv__udp_send6(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ uv_buf_t bufs[],
+ int bufcnt,
+ struct sockaddr_in6 addr,
+ uv_udp_send_cb send_cb) {
+ return uv__send(req,
+ handle,
+ bufs,
+ bufcnt,
+ (struct sockaddr*)&addr,
+ sizeof addr,
+ send_cb);
}
-int uv_udp_recv_start(uv_udp_t* handle,
- uv_alloc_cb alloc_cb,
- uv_udp_recv_cb recv_cb) {
+int uv__udp_recv_start(uv_udp_t* handle,
+ uv_alloc_cb alloc_cb,
+ uv_udp_recv_cb recv_cb) {
if (alloc_cb == NULL || recv_cb == NULL) {
uv__set_artificial_error(handle->loop, UV_EINVAL);
return -1;
}
- if (uv__io_active(&handle->read_watcher)) {
+ if (uv__io_active(&handle->io_watcher, UV__POLLIN)) {
uv__set_artificial_error(handle->loop, UV_EALREADY);
return -1;
}
@@ -649,18 +696,21 @@ int uv_udp_recv_start(uv_udp_t* handle,
handle->alloc_cb = alloc_cb;
handle->recv_cb = recv_cb;
- uv__udp_start_watcher(handle,
- &handle->read_watcher,
- uv__udp_recvmsg,
- UV__IO_READ);
+ uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN);
+ uv__handle_start(handle);
return 0;
}
-int uv_udp_recv_stop(uv_udp_t* handle) {
- uv__udp_stop_watcher(handle, &handle->read_watcher);
+int uv__udp_recv_stop(uv_udp_t* handle) {
+ uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN);
+
+ if (!uv__io_active(&handle->io_watcher, UV__POLLOUT))
+ uv__handle_stop(handle);
+
handle->alloc_cb = NULL;
handle->recv_cb = NULL;
+
return 0;
}
diff --git a/deps/uv/src/unix/uv-eio.c b/deps/uv/src/unix/uv-eio.c
deleted file mode 100644
index 0d931b884..000000000
--- a/deps/uv/src/unix/uv-eio.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* 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.
- */
-
-/* This file integrates the libuv event loop with the libeio thread pool */
-
-#include "uv.h"
-#include "eio.h"
-#include "internal.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-
-static uv_once_t uv__eio_init_once_guard = UV_ONCE_INIT;
-
-
-static void uv_eio_do_poll(uv_idle_t* watcher, int status) {
- uv_loop_t* loop = watcher->loop;
- assert(watcher == &loop->uv_eio_poller);
- if (eio_poll(&loop->uv_eio_channel) != -1)
- uv_idle_stop(watcher);
-}
-
-
-/* Called from the main thread. */
-static void uv_eio_want_poll_notifier_cb(uv_async_t* watcher, int status) {
- uv_loop_t* loop = watcher->loop;
- assert(watcher == &loop->uv_eio_want_poll_notifier);
- if (eio_poll(&loop->uv_eio_channel) == -1)
- uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll);
-}
-
-
-static void uv_eio_done_poll_notifier_cb(uv_async_t* watcher, int revents) {
- uv_loop_t* loop = watcher->loop;
- assert(watcher == &loop->uv_eio_done_poll_notifier);
- if (eio_poll(&loop->uv_eio_channel) != -1)
- uv_idle_stop(&loop->uv_eio_poller);
-}
-
-
-/*
- * uv_eio_want_poll() is called from the EIO thread pool each time an EIO
- * request (that is, one of the node.fs.* functions) has completed.
- */
-static void uv_eio_want_poll(eio_channel *channel) {
- /* Signal the main thread that eio_poll need to be processed. */
- uv_loop_t* loop = channel->data;
- uv_async_send(&loop->uv_eio_want_poll_notifier);
-}
-
-
-static void uv_eio_done_poll(eio_channel *channel) {
- /*
- * Signal the main thread that we should stop calling eio_poll().
- * from the idle watcher.
- */
- uv_loop_t* loop = channel->data;
- uv_async_send(&loop->uv_eio_done_poll_notifier);
-}
-
-
-static void uv__eio_init(void) {
- eio_init(uv_eio_want_poll, uv_eio_done_poll);
-}
-
-
-void uv_eio_init(uv_loop_t* loop) {
- if (loop->counters.eio_init) return;
- loop->counters.eio_init = 1;
-
- uv_idle_init(loop, &loop->uv_eio_poller);
- uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll);
- loop->uv_eio_poller.flags |= UV__HANDLE_INTERNAL;
-
- loop->uv_eio_want_poll_notifier.data = loop;
- uv_async_init(loop,
- &loop->uv_eio_want_poll_notifier,
- uv_eio_want_poll_notifier_cb);
- loop->uv_eio_want_poll_notifier.flags |= UV__HANDLE_INTERNAL;
- uv__handle_unref(&loop->uv_eio_want_poll_notifier);
-
- uv_async_init(loop,
- &loop->uv_eio_done_poll_notifier,
- uv_eio_done_poll_notifier_cb);
- loop->uv_eio_done_poll_notifier.flags |= UV__HANDLE_INTERNAL;
- uv__handle_unref(&loop->uv_eio_done_poll_notifier);
-
- uv_once(&uv__eio_init_once_guard, uv__eio_init);
-}
diff --git a/deps/uv/src/unix/uv-eio.h b/deps/uv/src/unix/uv-eio.h
deleted file mode 100644
index 711d0cf28..000000000
--- a/deps/uv/src/unix/uv-eio.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This header is private to libuv */
-#ifndef UV_EIO_H_
-#define UV_EIO_H_
-
-#include "eio.h"
-
-/*
- * Call this function to integrate libeio into the libuv event loop. It is
- * safe to call more than once.
- * TODO: uv_eio_deinit
- */
-void uv_eio_init(uv_loop_t*);
-#endif
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index 9639634a1..8c9d323af 100644
--- a/deps/uv/src/uv-common.c
+++ b/deps/uv/src/uv-common.c
@@ -28,10 +28,6 @@
#include <stdlib.h> /* malloc */
#include <string.h> /* memset */
-/* use inet_pton from c-ares if necessary */
-#include "ares_config.h"
-#include "ares/inet_net_pton.h"
-#include "ares/inet_ntop.h"
#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
@@ -182,63 +178,57 @@ struct sockaddr_in6 uv_ip6_addr(const char* ip, int port) {
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(port);
- ares_inet_pton(AF_INET6, ip, &addr.sin6_addr);
+ uv_inet_pton(AF_INET6, ip, &addr.sin6_addr);
return addr;
}
int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
- const char* d = ares_inet_ntop(AF_INET, &src->sin_addr, dst, size);
- return d != dst;
+ uv_err_t err = uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
+ return err.code != UV_OK;
}
int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
- const char* d = ares_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
- return d != dst;
+ uv_err_t err = uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
+ return err.code != UV_OK;
}
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
- if (handle->type != UV_TCP || addr.sin_family != AF_INET) {
- uv__set_artificial_error(handle->loop, UV_EFAULT);
- return -1;
- }
-
- return uv__tcp_bind(handle, addr);
+ if (handle->type != UV_TCP || addr.sin_family != AF_INET)
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
+ else
+ return uv__tcp_bind(handle, addr);
}
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
- if (handle->type != UV_TCP || addr.sin6_family != AF_INET6) {
- uv__set_artificial_error(handle->loop, UV_EFAULT);
- return -1;
- }
-
- return uv__tcp_bind6(handle, addr);
+ if (handle->type != UV_TCP || addr.sin6_family != AF_INET6)
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
+ else
+ return uv__tcp_bind6(handle, addr);
}
-int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr,
- unsigned int flags) {
- if (handle->type != UV_UDP || addr.sin_family != AF_INET) {
- uv__set_artificial_error(handle->loop, UV_EFAULT);
- return -1;
- }
-
- return uv__udp_bind(handle, addr, flags);
+int uv_udp_bind(uv_udp_t* handle,
+ struct sockaddr_in addr,
+ unsigned int flags) {
+ if (handle->type != UV_UDP || addr.sin_family != AF_INET)
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
+ else
+ return uv__udp_bind(handle, addr, flags);
}
-int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
- unsigned int flags) {
- if (handle->type != UV_UDP || addr.sin6_family != AF_INET6) {
- uv__set_artificial_error(handle->loop, UV_EFAULT);
- return -1;
- }
-
- return uv__udp_bind6(handle, addr, flags);
+int uv_udp_bind6(uv_udp_t* handle,
+ struct sockaddr_in6 addr,
+ unsigned int flags) {
+ if (handle->type != UV_UDP || addr.sin6_family != AF_INET6)
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
+ else
+ return uv__udp_bind6(handle, addr, flags);
}
@@ -246,12 +236,10 @@ int uv_tcp_connect(uv_connect_t* req,
uv_tcp_t* handle,
struct sockaddr_in address,
uv_connect_cb cb) {
- if (handle->type != UV_TCP || address.sin_family != AF_INET) {
- uv__set_artificial_error(handle->loop, UV_EINVAL);
- return -1;
- }
-
- return uv__tcp_connect(req, handle, address, cb);
+ if (handle->type != UV_TCP || address.sin_family != AF_INET)
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
+ else
+ return uv__tcp_connect(req, handle, address, cb);
}
@@ -259,15 +247,60 @@ int uv_tcp_connect6(uv_connect_t* req,
uv_tcp_t* handle,
struct sockaddr_in6 address,
uv_connect_cb cb) {
- if (handle->type != UV_TCP || address.sin6_family != AF_INET6) {
- uv__set_artificial_error(handle->loop, UV_EINVAL);
- return -1;
+ if (handle->type != UV_TCP || address.sin6_family != AF_INET6)
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
+ else
+ return uv__tcp_connect6(req, handle, address, cb);
+}
+
+
+int uv_udp_send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ uv_buf_t bufs[],
+ int bufcnt,
+ struct sockaddr_in addr,
+ uv_udp_send_cb send_cb) {
+ if (handle->type != UV_UDP || addr.sin_family != AF_INET) {
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
+ }
+
+ return uv__udp_send(req, handle, bufs, bufcnt, addr, send_cb);
+}
+
+
+int uv_udp_send6(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ uv_buf_t bufs[],
+ int bufcnt,
+ struct sockaddr_in6 addr,
+ uv_udp_send_cb send_cb) {
+ if (handle->type != UV_UDP || addr.sin6_family != AF_INET6) {
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
+ }
+
+ return uv__udp_send6(req, handle, bufs, bufcnt, addr, send_cb);
+}
+
+
+int uv_udp_recv_start(uv_udp_t* handle,
+ uv_alloc_cb alloc_cb,
+ uv_udp_recv_cb recv_cb) {
+ if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL) {
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
}
- return uv__tcp_connect6(req, handle, address, cb);
+ return uv__udp_recv_start(handle, alloc_cb, recv_cb);
}
+int uv_udp_recv_stop(uv_udp_t* handle) {
+ if (handle->type != UV_UDP) {
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
+ }
+
+ return uv__udp_recv_stop(handle);
+}
+
#ifdef _WIN32
static UINT __stdcall uv__thread_start(void *ctx_v)
#else
@@ -318,6 +351,15 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
}
+unsigned long uv_thread_self(void) {
+#ifdef _WIN32
+ return (unsigned long) GetCurrentThreadId();
+#else
+ return (unsigned long) pthread_self();
+#endif
+}
+
+
void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
ngx_queue_t* q;
uv_handle_t* h;
@@ -382,3 +424,8 @@ void uv_ref(uv_handle_t* handle) {
void uv_unref(uv_handle_t* handle) {
uv__handle_unref(handle);
}
+
+
+void uv_stop(uv_loop_t* loop) {
+ loop->stop_flag = 1;
+}
diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h
index d159727d6..4ba851691 100644
--- a/deps/uv/src/uv-common.h
+++ b/deps/uv/src/uv-common.h
@@ -29,7 +29,12 @@
#include <assert.h>
#include <stddef.h>
-#include <stdint.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
#include "uv.h"
#include "tree.h"
@@ -53,12 +58,14 @@
enum {
UV__HANDLE_INTERNAL = 0x8000,
UV__HANDLE_ACTIVE = 0x4000,
- UV__HANDLE_REF = 0x2000
+ UV__HANDLE_REF = 0x2000,
+ UV__HANDLE_CLOSING = 0 /* no-op on unix */
};
#else
# define UV__HANDLE_INTERNAL 0x80
# define UV__HANDLE_ACTIVE 0x40
# define UV__HANDLE_REF 0x20
+# define UV__HANDLE_CLOSING 0x01
#endif
extern const uv_err_t uv_ok_;
@@ -86,6 +93,25 @@ int uv__tcp_connect6(uv_connect_t* req,
struct sockaddr_in6 address,
uv_connect_cb cb);
+int uv__udp_send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ uv_buf_t bufs[],
+ int bufcnt,
+ struct sockaddr_in addr,
+ uv_udp_send_cb send_cb);
+
+int uv__udp_send6(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ uv_buf_t bufs[],
+ int bufcnt,
+ struct sockaddr_in6 addr,
+ uv_udp_send_cb send_cb);
+
+int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloccb,
+ uv_udp_recv_cb recv_cb);
+
+int uv__udp_recv_stop(uv_udp_t* handle);
+
void uv__fs_poll_close(uv_fs_poll_t* handle);
@@ -128,37 +154,50 @@ UNUSED static int uv__is_active(const uv_handle_t* h) {
#define uv__is_active(h) uv__is_active((const uv_handle_t*)(h))
UNUSED static void uv__handle_start(uv_handle_t* h) {
- if (h->flags & UV__HANDLE_ACTIVE) return;
- if (h->flags & UV__HANDLE_REF) uv__active_handle_add(h);
+ assert(!(h->flags & UV__HANDLE_CLOSING));
+ if (h->flags & UV__HANDLE_ACTIVE)
+ return;
h->flags |= UV__HANDLE_ACTIVE;
+ if (h->flags & UV__HANDLE_REF)
+ uv__active_handle_add(h);
}
#define uv__handle_start(h) uv__handle_start((uv_handle_t*)(h))
UNUSED static void uv__handle_stop(uv_handle_t* h) {
- if (!(h->flags & UV__HANDLE_ACTIVE)) return;
- if (h->flags & UV__HANDLE_REF) uv__active_handle_rm(h);
+ assert(!(h->flags & UV__HANDLE_CLOSING));
+ if (!(h->flags & UV__HANDLE_ACTIVE))
+ return;
h->flags &= ~UV__HANDLE_ACTIVE;
+ if (h->flags & UV__HANDLE_REF)
+ uv__active_handle_rm(h);
}
#define uv__handle_stop(h) uv__handle_stop((uv_handle_t*)(h))
UNUSED static void uv__handle_ref(uv_handle_t* h) {
- if (h->flags & UV__HANDLE_REF) return;
- if (h->flags & UV__HANDLE_ACTIVE) uv__active_handle_add(h);
+ if (h->flags & UV__HANDLE_REF)
+ return;
h->flags |= UV__HANDLE_REF;
+ if (h->flags & UV__HANDLE_CLOSING)
+ return;
+ if (h->flags & UV__HANDLE_ACTIVE)
+ uv__active_handle_add(h);
}
#define uv__handle_ref(h) uv__handle_ref((uv_handle_t*)(h))
UNUSED static void uv__handle_unref(uv_handle_t* h) {
- if (!(h->flags & UV__HANDLE_REF)) return;
- if (h->flags & UV__HANDLE_ACTIVE) uv__active_handle_rm(h);
+ if (!(h->flags & UV__HANDLE_REF))
+ return;
h->flags &= ~UV__HANDLE_REF;
+ if (h->flags & UV__HANDLE_CLOSING)
+ return;
+ if (h->flags & UV__HANDLE_ACTIVE)
+ uv__active_handle_rm(h);
}
#define uv__handle_unref(h) uv__handle_unref((uv_handle_t*)(h))
UNUSED static void uv__handle_init(uv_loop_t* loop,
uv_handle_t* handle,
uv_handle_type type) {
- loop->counters.handle_init++;
handle->loop = loop;
handle->type = type;
handle->flags = UV__HANDLE_REF; /* ref the loop when active */
diff --git a/deps/uv/src/win/async.c b/deps/uv/src/win/async.c
index 1b733c400..edf652973 100644
--- a/deps/uv/src/win/async.c
+++ b/deps/uv/src/win/async.c
@@ -23,44 +23,15 @@
#include "uv.h"
#include "internal.h"
+#include "atomicops-inl.h"
#include "handle-inl.h"
#include "req-inl.h"
-/* Atomic set operation on char */
-#ifdef _MSC_VER /* MSVC */
-
-/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */
-/* efficient than InterlockedExchange, but InterlockedExchange8 does not */
-/* exist, and interlocked operations on larger targets might require the */
-/* target to be aligned. */
-#pragma intrinsic(_InterlockedOr8)
-
-static char __declspec(inline) uv_atomic_exchange_set(char volatile* target) {
- return _InterlockedOr8(target, 1);
-}
-
-#else /* GCC */
-
-/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
-static inline char uv_atomic_exchange_set(char volatile* target) {
- const char one = 1;
- char old_value;
- __asm__ __volatile__ ("lock xchgb %0, %1\n\t"
- : "=r"(old_value), "=m"(*target)
- : "0"(one), "m"(*target)
- : "memory");
- return old_value;
-}
-
-#endif
-
-
void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) {
- if (handle->flags & UV_HANDLE_CLOSING &&
+ if (handle->flags & UV__HANDLE_CLOSING &&
!handle->async_sent) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
- uv__handle_stop(handle);
uv__handle_close(handle);
}
}
@@ -78,8 +49,6 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
req->type = UV_WAKEUP;
req->data = handle;
- loop->counters.async_init++;
-
uv__handle_start(handle);
return 0;
@@ -91,7 +60,7 @@ void uv_async_close(uv_loop_t* loop, uv_async_t* handle) {
uv_want_endgame(loop, (uv_handle_t*) handle);
}
- uv__handle_start(handle);
+ uv__handle_closing(handle);
}
@@ -105,9 +74,9 @@ int uv_async_send(uv_async_t* handle) {
/* The user should make sure never to call uv_async_send to a closing */
/* or closed handle. */
- assert(!(handle->flags & UV_HANDLE_CLOSING));
+ assert(!(handle->flags & UV__HANDLE_CLOSING));
- if (!uv_atomic_exchange_set(&handle->async_sent)) {
+ if (!uv__atomic_exchange_set(&handle->async_sent)) {
POST_COMPLETION_FOR_REQ(loop, &handle->async_req);
}
@@ -122,7 +91,7 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
handle->async_sent = 0;
- if (!(handle->flags & UV_HANDLE_CLOSING)) {
+ if (!(handle->flags & UV__HANDLE_CLOSING)) {
handle->async_cb((uv_async_t*) handle, 0);
} else {
uv_want_endgame(loop, (uv_handle_t*)handle);
diff --git a/deps/uv/src/win/atomicops-inl.h b/deps/uv/src/win/atomicops-inl.h
new file mode 100644
index 000000000..61e006026
--- /dev/null
+++ b/deps/uv/src/win/atomicops-inl.h
@@ -0,0 +1,56 @@
+/* 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.
+ */
+
+#ifndef UV_WIN_ATOMICOPS_INL_H_
+#define UV_WIN_ATOMICOPS_INL_H_
+
+#include "uv.h"
+
+
+/* Atomic set operation on char */
+#ifdef _MSC_VER /* MSVC */
+
+/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */
+/* efficient than InterlockedExchange, but InterlockedExchange8 does not */
+/* exist, and interlocked operations on larger targets might require the */
+/* target to be aligned. */
+#pragma intrinsic(_InterlockedOr8)
+
+static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) {
+ return _InterlockedOr8(target, 1);
+}
+
+#else /* GCC */
+
+/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
+static inline char uv__atomic_exchange_set(char volatile* target) {
+ const char one = 1;
+ char old_value;
+ __asm__ __volatile__ ("lock xchgb %0, %1\n\t"
+ : "=r"(old_value), "=m"(*target)
+ : "0"(one), "m"(*target)
+ : "memory");
+ return old_value;
+}
+
+#endif
+
+#endif /* UV_WIN_ATOMICOPS_INL_H_ */
diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c
index d29a1300a..a06c23f3c 100644
--- a/deps/uv/src/win/core.c
+++ b/deps/uv/src/win/core.c
@@ -69,6 +69,9 @@ static void uv_init(void) {
/* Initialize FS */
uv_fs_init();
+ /* Initialize signal stuff */
+ uv_signals_init();
+
/* Initialize console */
uv_console_init();
@@ -109,15 +112,13 @@ static void uv_loop_init(uv_loop_t* loop) {
memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);
- loop->channel = NULL;
- RB_INIT(&loop->ares_handles);
-
loop->active_tcp_streams = 0;
loop->active_udp_streams = 0;
- loop->last_err = uv_ok_;
+ loop->timer_counter = 0;
+ loop->stop_flag = 0;
- memset(&loop->counters, 0, sizeof loop->counters);
+ loop->last_err = uv_ok_;
}
@@ -173,6 +174,16 @@ void uv_loop_delete(uv_loop_t* loop) {
}
+int uv_backend_fd(const uv_loop_t* loop) {
+ return -1;
+}
+
+
+int uv_backend_timeout(const uv_loop_t* loop) {
+ return 0;
+}
+
+
static void uv_poll(uv_loop_t* loop, int block) {
BOOL success;
DWORD bytes, timeout;
@@ -239,62 +250,61 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
}
}
-#define UV_LOOP_ALIVE(loop) \
- ((loop)->active_handles > 0 || \
- !ngx_queue_empty(&(loop)->active_reqs) || \
- (loop)->endgame_handles != NULL)
-
-#define UV_LOOP_ONCE(loop, poll) \
- do { \
- uv_update_time((loop)); \
- uv_process_timers((loop)); \
- \
- /* Call idle callbacks if nothing to do. */ \
- if ((loop)->pending_reqs_tail == NULL && \
- (loop)->endgame_handles == NULL) { \
- uv_idle_invoke((loop)); \
- } \
- \
- uv_process_reqs((loop)); \
- uv_process_endgames((loop)); \
- \
- if (!UV_LOOP_ALIVE((loop))) { \
- break; \
- } \
- \
- uv_prepare_invoke((loop)); \
- \
- poll((loop), (loop)->idle_handles == NULL && \
- (loop)->pending_reqs_tail == NULL && \
- (loop)->endgame_handles == NULL && \
- UV_LOOP_ALIVE((loop))); \
- \
- uv_check_invoke((loop)); \
- } while (0);
-
-#define UV_LOOP(loop, poll) \
- while (UV_LOOP_ALIVE((loop))) { \
- UV_LOOP_ONCE(loop, poll) \
- }
-
-int uv_run_once(uv_loop_t* loop) {
- if (pGetQueuedCompletionStatusEx) {
- UV_LOOP_ONCE(loop, uv_poll_ex);
- } else {
- UV_LOOP_ONCE(loop, uv_poll);
- }
- return UV_LOOP_ALIVE(loop);
+static int uv__loop_alive(uv_loop_t* loop) {
+ return loop->active_handles > 0 ||
+ !ngx_queue_empty(&loop->active_reqs) ||
+ loop->endgame_handles != NULL;
}
-int uv_run(uv_loop_t* loop) {
- if (pGetQueuedCompletionStatusEx) {
- UV_LOOP(loop, uv_poll_ex);
- } else {
- UV_LOOP(loop, uv_poll);
+int uv_run(uv_loop_t *loop, uv_run_mode mode) {
+ int r;
+ void (*poll)(uv_loop_t* loop, int block);
+
+ if (pGetQueuedCompletionStatusEx)
+ poll = &uv_poll_ex;
+ else
+ poll = &uv_poll;
+
+ if (!uv__loop_alive(loop))
+ return 0;
+
+ r = uv__loop_alive(loop);
+ while (r != 0 && loop->stop_flag == 0) {
+ uv_update_time(loop);
+ uv_process_timers(loop);
+
+ /* Call idle callbacks if nothing to do. */
+ if (loop->pending_reqs_tail == NULL &&
+ loop->endgame_handles == NULL) {
+ uv_idle_invoke(loop);
+ }
+
+ uv_process_reqs(loop);
+ uv_process_endgames(loop);
+
+ uv_prepare_invoke(loop);
+
+ (*poll)(loop, loop->idle_handles == NULL &&
+ loop->pending_reqs_tail == NULL &&
+ loop->endgame_handles == NULL &&
+ !loop->stop_flag &&
+ (loop->active_handles > 0 ||
+ !ngx_queue_empty(&loop->active_reqs)) &&
+ !(mode & UV_RUN_NOWAIT));
+
+ uv_check_invoke(loop);
+ r = uv__loop_alive(loop);
+ if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
+ break;
}
- assert(!UV_LOOP_ALIVE((loop)));
- return 0;
+ /* The if statement lets the compiler compile it to a conditional store.
+ * Avoids dirtying a cache line.
+ */
+ if (loop->stop_flag != 0)
+ loop->stop_flag = 0;
+
+ return r;
}
diff --git a/deps/uv/src/win/dl.c b/deps/uv/src/win/dl.c
index 88ddd74b5..d5b8f7c7d 100644
--- a/deps/uv/src/win/dl.c
+++ b/deps/uv/src/win/dl.c
@@ -26,7 +26,7 @@ static int uv__dlerror(uv_lib_t* lib, int errorno);
int uv_dlopen(const char* filename, uv_lib_t* lib) {
- wchar_t filename_w[32768];
+ WCHAR filename_w[32768];
lib->handle = NULL;
lib->errmsg = NULL;
diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c
index 7d7d1ea79..40852cffc 100644
--- a/deps/uv/src/win/error.c
+++ b/deps/uv/src/win/error.c
@@ -79,6 +79,8 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ERROR_LOCK_VIOLATION: return UV_EBUSY;
case ERROR_PIPE_BUSY: return UV_EBUSY;
case ERROR_SHARING_VIOLATION: return UV_EBUSY;
+ case ERROR_OPERATION_ABORTED: return UV_ECANCELED;
+ case WSAEINTR: return UV_ECANCELED;
case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET;
case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED;
case WSAECONNABORTED: return UV_ECONNABORTED;
@@ -92,8 +94,6 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case WSAEFAULT: return UV_EFAULT;
case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH;
case WSAEHOSTUNREACH: return UV_EHOSTUNREACH;
- case ERROR_OPERATION_ABORTED: return UV_EINTR;
- case WSAEINTR: return UV_EINTR;
case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
case ERROR_INVALID_DATA: return UV_EINVAL;
case ERROR_INVALID_PARAMETER: return UV_EINVAL;
diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c
index 68e03e390..1954cb091 100644
--- a/deps/uv/src/win/fs-event.c
+++ b/deps/uv/src/win/fs-event.c
@@ -55,8 +55,6 @@ static void uv_fs_event_init_handle(uv_loop_t* loop, uv_fs_event_t* handle,
}
uv__handle_start(handle);
-
- loop->counters.fs_event_init++;
}
@@ -90,15 +88,15 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
}
-static int uv_split_path(const wchar_t* filename, wchar_t** dir,
- wchar_t** file) {
+static int uv_split_path(const WCHAR* filename, WCHAR** dir,
+ WCHAR** file) {
int len = wcslen(filename);
int i = len;
while (i > 0 && filename[--i] != '\\' && filename[i] != '/');
if (i == 0) {
if (dir) {
- *dir = (wchar_t*)malloc((MAX_PATH + 1) * sizeof(wchar_t));
+ *dir = (WCHAR*)malloc((MAX_PATH + 1) * sizeof(WCHAR));
if (!*dir) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
@@ -113,7 +111,7 @@ static int uv_split_path(const wchar_t* filename, wchar_t** dir,
*file = wcsdup(filename);
} else {
if (dir) {
- *dir = (wchar_t*)malloc((i + 1) * sizeof(wchar_t));
+ *dir = (WCHAR*)malloc((i + 1) * sizeof(WCHAR));
if (!*dir) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
@@ -121,7 +119,7 @@ static int uv_split_path(const wchar_t* filename, wchar_t** dir,
(*dir)[i] = L'\0';
}
- *file = (wchar_t*)malloc((len - i) * sizeof(wchar_t));
+ *file = (WCHAR*)malloc((len - i) * sizeof(WCHAR));
if (!*file) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
@@ -137,23 +135,20 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
const char* filename, uv_fs_event_cb cb, int flags) {
int name_size, is_path_dir;
DWORD attr, last_error;
- wchar_t* dir = NULL, *dir_to_watch, *filenamew = NULL;
- wchar_t short_path[MAX_PATH];
-
- /* We don't support any flags yet. */
- assert(!flags);
+ WCHAR* dir = NULL, *dir_to_watch, *filenamew = NULL;
+ WCHAR short_path[MAX_PATH];
uv_fs_event_init_handle(loop, handle, filename, cb);
/* Convert name to UTF16. */
- name_size = uv_utf8_to_utf16(filename, NULL, 0) * sizeof(wchar_t);
- filenamew = (wchar_t*)malloc(name_size);
+ name_size = uv_utf8_to_utf16(filename, NULL, 0) * sizeof(WCHAR);
+ filenamew = (WCHAR*)malloc(name_size);
if (!filenamew) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
if (!uv_utf8_to_utf16(filename, filenamew,
- name_size / sizeof(wchar_t))) {
+ name_size / sizeof(WCHAR))) {
uv__set_sys_error(loop, GetLastError());
return -1;
}
@@ -294,7 +289,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
FILE_NOTIFY_INFORMATION* file_info;
int sizew, size, result;
char* filename = NULL;
- wchar_t* filenamew, *long_filenamew = NULL;
+ WCHAR* filenamew, *long_filenamew = NULL;
DWORD offset = 0;
assert(req->type == UV_FS_EVENT_REQ);
@@ -303,7 +298,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
/* If we're closing, don't report any callbacks, and just push the handle */
/* onto the endgame queue. */
- if (handle->flags & UV_HANDLE_CLOSING) {
+ if (handle->flags & UV__HANDLE_CLOSING) {
uv_want_endgame(loop, (uv_handle_t*) handle);
return;
};
@@ -323,9 +318,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
*/
if (handle->dirw ||
_wcsnicmp(handle->filew, file_info->FileName,
- file_info->FileNameLength / sizeof(wchar_t)) == 0 ||
+ file_info->FileNameLength / sizeof(WCHAR)) == 0 ||
_wcsnicmp(handle->short_filew, file_info->FileName,
- file_info->FileNameLength / sizeof(wchar_t)) == 0) {
+ file_info->FileNameLength / sizeof(WCHAR)) == 0) {
if (handle->dirw) {
/*
@@ -337,9 +332,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) {
/* Construct a full path to the file. */
size = wcslen(handle->dirw) +
- file_info->FileNameLength / sizeof(wchar_t) + 2;
+ file_info->FileNameLength / sizeof(WCHAR) + 2;
- filenamew = (wchar_t*)malloc(size * sizeof(wchar_t));
+ filenamew = (WCHAR*)malloc(size * sizeof(WCHAR));
if (!filenamew) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
@@ -353,7 +348,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
size = GetLongPathNameW(filenamew, NULL, 0);
if (size) {
- long_filenamew = (wchar_t*)malloc(size * sizeof(wchar_t));
+ long_filenamew = (WCHAR*)malloc(size * sizeof(WCHAR));
if (!long_filenamew) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
@@ -388,7 +383,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
*/
if (!long_filenamew) {
filenamew = file_info->FileName;
- sizew = file_info->FileNameLength / sizeof(wchar_t);
+ sizew = file_info->FileNameLength / sizeof(WCHAR);
}
} else {
/* Removed or renamed callbacks don't provide filename. */
@@ -445,7 +440,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
}
offset = file_info->NextEntryOffset;
- } while (offset && !(handle->flags & UV_HANDLE_CLOSING));
+ } while (offset && !(handle->flags & UV__HANDLE_CLOSING));
} else {
handle->cb(handle, NULL, UV_CHANGE, 0);
}
@@ -454,7 +449,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
handle->cb(handle, NULL, 0, -1);
}
- if (!(handle->flags & UV_HANDLE_CLOSING)) {
+ if (!(handle->flags & UV__HANDLE_CLOSING)) {
uv_fs_event_queue_readdirchanges(loop, handle);
} else {
uv_want_endgame(loop, (uv_handle_t*)handle);
@@ -472,15 +467,14 @@ void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
- uv__handle_start(handle);
+ uv__handle_closing(handle);
}
void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) {
- if (handle->flags & UV_HANDLE_CLOSING &&
+ if (handle->flags & UV__HANDLE_CLOSING &&
!handle->req_pending) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
- uv__handle_stop(handle);
if (handle->buffer) {
_aligned_free(handle->buffer);
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 9b920c817..60e67a41d 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -889,7 +889,7 @@ INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
return;
}
- if (fs__stat_handle(handle, &req->stat) != 0) {
+ if (fs__stat_handle(handle, &req->statbuf) != 0) {
DWORD error = GetLastError();
if (do_lstat && error == ERROR_SYMLINK_NOT_SUPPORTED) {
/* We opened a reparse point but it was not a symlink. Try again. */
@@ -904,7 +904,7 @@ INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
return;
}
- req->ptr = &req->stat;
+ req->ptr = &req->statbuf;
req->result = 0;
CloseHandle(handle);
}
@@ -935,12 +935,12 @@ static void fs__fstat(uv_fs_t* req) {
return;
}
- if (fs__stat_handle(handle, &req->stat) != 0) {
+ if (fs__stat_handle(handle, &req->statbuf) != 0) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
- req->ptr = &req->stat;
+ req->ptr = &req->statbuf;
req->result = 0;
}
diff --git a/deps/uv/src/win/getaddrinfo.c b/deps/uv/src/win/getaddrinfo.c
index 41e7a4aa2..c2017ef76 100644
--- a/deps/uv/src/win/getaddrinfo.c
+++ b/deps/uv/src/win/getaddrinfo.c
@@ -37,13 +37,13 @@
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
- wchar_t* ai_canonname;
+ WCHAR* ai_canonname;
struct sockaddr* ai_addr;
struct addrinfoW* ai_next;
} ADDRINFOW, *PADDRINFOW;
- DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const wchar_t* node,
- const wchar_t* service,
+ DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const WCHAR* node,
+ const WCHAR* service,
const ADDRINFOW* hints,
PADDRINFOW* result);
@@ -271,7 +271,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* calculate required memory size for all input values */
if (node != NULL) {
- nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(wchar_t));
+ nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(WCHAR));
if (nodesize == 0) {
uv__set_sys_error(loop, GetLastError());
goto error;
@@ -280,7 +280,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
if (service != NULL) {
servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) *
- sizeof(wchar_t));
+ sizeof(WCHAR));
if (servicesize == 0) {
uv__set_sys_error(loop, GetLastError());
goto error;
@@ -303,10 +303,10 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* convert node string to UTF16 into allocated memory and save pointer in */
/* the reques. */
if (node != NULL) {
- req->node = (wchar_t*)alloc_ptr;
+ req->node = (WCHAR*)alloc_ptr;
if (uv_utf8_to_utf16(node,
- (wchar_t*) alloc_ptr,
- nodesize / sizeof(wchar_t)) == 0) {
+ (WCHAR*) alloc_ptr,
+ nodesize / sizeof(WCHAR)) == 0) {
uv__set_sys_error(loop, GetLastError());
goto error;
}
@@ -318,10 +318,10 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* convert service string to UTF16 into allocated memory and save pointer */
/* in the req. */
if (service != NULL) {
- req->service = (wchar_t*)alloc_ptr;
+ req->service = (WCHAR*)alloc_ptr;
if (uv_utf8_to_utf16(service,
- (wchar_t*) alloc_ptr,
- servicesize / sizeof(wchar_t)) == 0) {
+ (WCHAR*) alloc_ptr,
+ servicesize / sizeof(WCHAR)) == 0) {
uv__set_sys_error(loop, GetLastError());
goto error;
}
diff --git a/deps/uv/src/win/handle-inl.h b/deps/uv/src/win/handle-inl.h
index 4064c24cf..52dfbbc1a 100644
--- a/deps/uv/src/win/handle-inl.h
+++ b/deps/uv/src/win/handle-inl.h
@@ -31,7 +31,7 @@
#define DECREASE_ACTIVE_COUNT(loop, handle) \
do { \
if (--(handle)->activecnt == 0 && \
- !((handle)->flags & UV_HANDLE_CLOSING)) { \
+ !((handle)->flags & UV__HANDLE_CLOSING)) { \
uv__handle_stop((handle)); \
} \
assert((handle)->activecnt >= 0); \
@@ -52,20 +52,35 @@
assert(handle->reqs_pending > 0); \
handle->reqs_pending--; \
\
- if (handle->flags & UV_HANDLE_CLOSING && \
+ if (handle->flags & UV__HANDLE_CLOSING && \
handle->reqs_pending == 0) { \
uv_want_endgame(loop, (uv_handle_t*)handle); \
} \
} while (0)
+#define uv__handle_closing(handle) \
+ do { \
+ assert(!((handle)->flags & UV__HANDLE_CLOSING)); \
+ \
+ if (!(((handle)->flags & UV__HANDLE_ACTIVE) && \
+ ((handle)->flags & UV__HANDLE_REF))) \
+ uv__active_handle_add((uv_handle_t*) (handle)); \
+ \
+ (handle)->flags |= UV__HANDLE_CLOSING; \
+ (handle)->flags &= ~UV__HANDLE_ACTIVE; \
+ } while (0)
+
+
#define uv__handle_close(handle) \
do { \
ngx_queue_remove(&(handle)->handle_queue); \
+ uv__active_handle_rm((uv_handle_t*) (handle)); \
+ \
(handle)->flags |= UV_HANDLE_CLOSED; \
- if ((handle)->close_cb) { \
- (handle)->close_cb((uv_handle_t*)(handle)); \
- } \
+ \
+ if ((handle)->close_cb) \
+ (handle)->close_cb((uv_handle_t*) (handle)); \
} while (0)
@@ -123,6 +138,10 @@ INLINE static void uv_process_endgames(uv_loop_t* loop) {
uv_async_endgame(loop, (uv_async_t*) handle);
break;
+ case UV_SIGNAL:
+ uv_signal_endgame(loop, (uv_signal_t*) handle);
+ break;
+
case UV_PROCESS:
uv_process_endgame(loop, (uv_process_t*) handle);
break;
diff --git a/deps/uv/src/win/handle.c b/deps/uv/src/win/handle.c
index d4b86de99..64ff1b213 100644
--- a/deps/uv/src/win/handle.c
+++ b/deps/uv/src/win/handle.c
@@ -59,19 +59,18 @@ uv_handle_type uv_guess_handle(uv_file file) {
int uv_is_active(const uv_handle_t* handle) {
return (handle->flags & UV__HANDLE_ACTIVE) &&
- !(handle->flags & UV_HANDLE_CLOSING);
+ !(handle->flags & UV__HANDLE_CLOSING);
}
void uv_close(uv_handle_t* handle, uv_close_cb cb) {
uv_loop_t* loop = handle->loop;
- if (handle->flags & UV_HANDLE_CLOSING) {
+ if (handle->flags & UV__HANDLE_CLOSING) {
assert(0);
return;
}
- handle->flags |= UV_HANDLE_CLOSING;
handle->close_cb = cb;
/* Handle-specific close actions */
@@ -98,25 +97,25 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
case UV_TIMER:
uv_timer_stop((uv_timer_t*)handle);
- uv__handle_start(handle);
+ uv__handle_closing(handle);
uv_want_endgame(loop, handle);
return;
case UV_PREPARE:
uv_prepare_stop((uv_prepare_t*)handle);
- uv__handle_start(handle);
+ uv__handle_closing(handle);
uv_want_endgame(loop, handle);
return;
case UV_CHECK:
uv_check_stop((uv_check_t*)handle);
- uv__handle_start(handle);
+ uv__handle_closing(handle);
uv_want_endgame(loop, handle);
return;
case UV_IDLE:
uv_idle_stop((uv_idle_t*)handle);
- uv__handle_start(handle);
+ uv__handle_closing(handle);
uv_want_endgame(loop, handle);
return;
@@ -124,6 +123,10 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
uv_async_close(loop, (uv_async_t*) handle);
return;
+ case UV_SIGNAL:
+ uv_signal_close(loop, (uv_signal_t*) handle);
+ return;
+
case UV_PROCESS:
uv_process_close(loop, (uv_process_t*) handle);
return;
@@ -134,7 +137,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
case UV_FS_POLL:
uv__fs_poll_close((uv_fs_poll_t*) handle);
- uv__handle_start(handle);
+ uv__handle_closing(handle);
uv_want_endgame(loop, handle);
return;
@@ -146,5 +149,5 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
int uv_is_closing(const uv_handle_t* handle) {
- return handle->flags & (UV_HANDLE_CLOSING | UV_HANDLE_CLOSED);
+ return handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED);
}
diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h
index 9dc58d5d5..9920f704a 100644
--- a/deps/uv/src/win/internal.h
+++ b/deps/uv/src/win/internal.h
@@ -36,14 +36,14 @@
*/
/* Used by all handles. */
-#define UV_HANDLE_CLOSING 0x00000001
#define UV_HANDLE_CLOSED 0x00000002
#define UV_HANDLE_ENDGAME_QUEUED 0x00000004
#define UV_HANDLE_ACTIVE 0x00000010
+/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */
/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */
/* uv-common.h: #define UV__HANDLE_REF 0x00000020 */
-/* reserved: #define UV_HANDLE_INTERNAL 0x00000080 */
+/* uv-common.h: #define UV_HANDLE_INTERNAL 0x00000080 */
/* Used by streams and UDP handles. */
#define UV_HANDLE_READING 0x00000100
@@ -52,9 +52,8 @@
#define UV_HANDLE_LISTENING 0x00000800
#define UV_HANDLE_CONNECTION 0x00001000
#define UV_HANDLE_CONNECTED 0x00002000
-#define UV_HANDLE_EOF 0x00004000
-#define UV_HANDLE_SHUTTING 0x00008000
-#define UV_HANDLE_SHUT 0x00010000
+#define UV_HANDLE_READABLE 0x00008000
+#define UV_HANDLE_WRITABLE 0x00010000
#define UV_HANDLE_READ_PENDING 0x00020000
#define UV_HANDLE_SYNC_BYPASS_IOCP 0x00040000
#define UV_HANDLE_ZERO_READ 0x00080000
@@ -74,9 +73,10 @@
#define UV_HANDLE_PIPESERVER 0x02000000
/* Only used by uv_tty_t handles. */
-#define UV_HANDLE_TTY_RAW 0x01000000
-#define UV_HANDLE_TTY_SAVED_POSITION 0x02000000
-#define UV_HANDLE_TTY_SAVED_ATTRIBUTES 0x04000000
+#define UV_HANDLE_TTY_READABLE 0x01000000
+#define UV_HANDLE_TTY_RAW 0x02000000
+#define UV_HANDLE_TTY_SAVED_POSITION 0x04000000
+#define UV_HANDLE_TTY_SAVED_ATTRIBUTES 0x08000000
/* Only used by uv_poll_t handles. */
#define UV_HANDLE_POLL_SLOW 0x02000000
@@ -134,7 +134,7 @@ void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
/*
* Pipes
*/
-int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
+uv_err_t uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
char* name, size_t nameSize);
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
@@ -232,10 +232,22 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
/*
+ * Signal watcher
+ */
+void uv_signals_init();
+int uv__signal_dispatch(int signum);
+
+void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle);
+void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle);
+
+void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
+ uv_req_t* req);
+
+
+/*
* Spawn
*/
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle);
-void uv_process_proc_close(uv_loop_t* loop, uv_process_t* handle);
void uv_process_close(uv_loop_t* loop, uv_process_t* handle);
void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle);
@@ -287,7 +299,7 @@ uv_err_code uv_translate_sys_error(int sys_errno);
/*
* Process stdio handles.
*/
-int uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
+uv_err_t uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
BYTE** buffer_ptr);
void uv__stdio_destroy(BYTE* buffer);
void uv__stdio_noinherit(BYTE* buffer);
diff --git a/deps/uv/src/win/loop-watcher.c b/deps/uv/src/win/loop-watcher.c
index 615f7cdeb..65080ff66 100644
--- a/deps/uv/src/win/loop-watcher.c
+++ b/deps/uv/src/win/loop-watcher.c
@@ -27,10 +27,9 @@
void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
- if (handle->flags & UV_HANDLE_CLOSING) {
+ if (handle->flags & UV__HANDLE_CLOSING) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
handle->flags |= UV_HANDLE_CLOSED;
- uv__handle_stop(handle);
uv__handle_close(handle);
}
}
@@ -39,7 +38,6 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
#define UV_LOOP_WATCHER_DEFINE(name, NAME) \
int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME); \
- loop->counters.name##_init++; \
\
return 0; \
} \
@@ -54,6 +52,9 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
if (handle->flags & UV_HANDLE_ACTIVE) \
return 0; \
\
+ if (cb == NULL) \
+ return uv__set_artificial_error(handle->loop, UV_EINVAL); \
+ \
old_head = loop->name##_handles; \
\
handle->name##_next = old_head; \
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index 77a1c7b75..2436b036f 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -88,8 +88,6 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
uv_req_init(loop, (uv_req_t*) &handle->ipc_header_write_req);
- loop->counters.pipe_init++;
-
return 0;
}
@@ -116,7 +114,7 @@ static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
FILE_FLAG_OVERLAPPED,
NULL);
if (pipeHandle != INVALID_HANDLE_VALUE) {
- *duplex_flags = 0;
+ *duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
return pipeHandle;
}
@@ -135,7 +133,7 @@ static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
NULL);
if (pipeHandle != INVALID_HANDLE_VALUE) {
- *duplex_flags = UV_HANDLE_SHUTTING;
+ *duplex_flags = UV_HANDLE_READABLE;
return pipeHandle;
}
}
@@ -150,7 +148,7 @@ static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
NULL);
if (pipeHandle != INVALID_HANDLE_VALUE) {
- *duplex_flags = UV_HANDLE_EOF;
+ *duplex_flags = UV_HANDLE_WRITABLE;
return pipeHandle;
}
}
@@ -159,11 +157,11 @@ static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
}
-int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
+uv_err_t uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
char* name, size_t nameSize) {
HANDLE pipeHandle;
int errorno;
- int err;
+ uv_err_t err;
char* ptr = (char*)handle;
for (;;) {
@@ -181,9 +179,8 @@ int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
errorno = GetLastError();
if (errorno != ERROR_PIPE_BUSY && errorno != ERROR_ACCESS_DENIED) {
- uv__set_sys_error(loop, errorno);
- err = -1;
- goto done;
+ err = uv__new_sys_error(errorno);
+ goto error;
}
/* Pipe name collision. Increment the pointer and try again. */
@@ -194,17 +191,17 @@ int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
loop->iocp,
(ULONG_PTR)handle,
0) == NULL) {
- uv__set_sys_error(loop, GetLastError());
- err = -1;
- goto done;
+ err = uv__new_sys_error(GetLastError());
+ goto error;
}
uv_pipe_connection_init(handle);
handle->handle = pipeHandle;
- err = 0;
-done:
- if (err && pipeHandle != INVALID_HANDLE_VALUE) {
+ return uv_ok_;
+
+ error:
+ if (pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(pipeHandle);
}
@@ -295,12 +292,12 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
/* Clear the shutdown_req field so we don't go here again. */
handle->shutdown_req = NULL;
- if (handle->flags & UV_HANDLE_CLOSING) {
+ if (handle->flags & UV__HANDLE_CLOSING) {
UNREGISTER_HANDLE_REQ(loop, handle, req);
/* Already closing. Cancel the shutdown. */
if (req->cb) {
- uv__set_sys_error(loop, WSAEINTR);
+ uv__set_artificial_error(loop, UV_ECANCELED);
req->cb(req, -1);
}
@@ -319,7 +316,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
/* Failure */
UNREGISTER_HANDLE_REQ(loop, handle, req);
- handle->flags &= ~UV_HANDLE_SHUTTING;
+ handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
if (req->cb) {
uv__set_sys_error(loop, pRtlNtStatusToDosError(nt_status));
req->cb(req, -1);
@@ -346,7 +343,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
/* Failure. */
UNREGISTER_HANDLE_REQ(loop, handle, req);
- handle->flags &= ~UV_HANDLE_SHUTTING;
+ handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
if (req->cb) {
uv__set_sys_error(loop, GetLastError());
req->cb(req, -1);
@@ -357,10 +354,9 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
}
}
- if (handle->flags & UV_HANDLE_CLOSING &&
+ if (handle->flags & UV__HANDLE_CLOSING &&
handle->reqs_pending == 0) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
- uv__handle_stop(handle);
if (handle->flags & UV_HANDLE_CONNECTION) {
if (handle->pending_ipc_info.socket_info) {
@@ -433,13 +429,13 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
}
/* Convert name to UTF16. */
- nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(wchar_t);
- handle->name = (wchar_t*)malloc(nameSize);
+ nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
+ handle->name = (WCHAR*)malloc(nameSize);
if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
- if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
+ if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
uv__set_sys_error(loop, GetLastError());
return -1;
}
@@ -545,13 +541,13 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
req->cb = cb;
/* Convert name to UTF16. */
- nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(wchar_t);
- handle->name = (wchar_t*)malloc(nameSize);
+ nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
+ handle->name = (WCHAR*)malloc(nameSize);
if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
- if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
+ if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
errorno = GetLastError();
goto error;
}
@@ -634,7 +630,7 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
}
if (handle->flags & UV_HANDLE_CONNECTION) {
- handle->flags |= UV_HANDLE_SHUTTING;
+ handle->flags &= ~UV_HANDLE_WRITABLE;
eof_timer_destroy(handle);
}
@@ -663,7 +659,8 @@ void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) {
uv_want_endgame(loop, (uv_handle_t*) handle);
}
- uv__handle_start(handle);
+ handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
+ uv__handle_closing(handle);
}
@@ -750,13 +747,14 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
/* Initialize the client handle and copy the pipeHandle to the client */
uv_pipe_connection_init(pipe_client);
pipe_client->handle = req->pipeHandle;
+ pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
/* Prepare the req to pick up a new connection */
server->pending_accepts = req->next_pending;
req->next_pending = NULL;
req->pipeHandle = INVALID_HANDLE_VALUE;
- if (!(server->flags & UV_HANDLE_CLOSING)) {
+ if (!(server->flags & UV__HANDLE_CLOSING)) {
uv_pipe_queue_accept(loop, server, req, FALSE);
}
}
@@ -968,16 +966,6 @@ static int uv_pipe_read_start_impl(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb, uv_read2_cb read2_cb) {
uv_loop_t* loop = handle->loop;
- if (!(handle->flags & UV_HANDLE_CONNECTION)) {
- uv__set_artificial_error(loop, UV_EINVAL);
- return -1;
- }
-
- if (handle->flags & UV_HANDLE_EOF) {
- uv__set_artificial_error(loop, UV_EOF);
- return -1;
- }
-
handle->flags |= UV_HANDLE_READING;
INCREASE_ACTIVE_COUNT(loop, handle);
handle->read_cb = read_cb;
@@ -1076,16 +1064,6 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
assert(handle->handle != INVALID_HANDLE_VALUE);
- if (!(handle->flags & UV_HANDLE_CONNECTION)) {
- uv__set_artificial_error(loop, UV_EINVAL);
- return -1;
- }
-
- if (handle->flags & UV_HANDLE_SHUTTING) {
- uv__set_artificial_error(loop, UV_EOF);
- return -1;
- }
-
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WRITE;
req->handle = (uv_stream_t*) handle;
@@ -1257,7 +1235,7 @@ static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
/* so discard it. */
eof_timer_destroy(handle);
- handle->flags |= UV_HANDLE_EOF;
+ handle->flags &= ~UV_HANDLE_READABLE;
uv_read_stop((uv_stream_t*) handle);
uv__set_artificial_error(loop, UV_EOF);
@@ -1487,8 +1465,8 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_queue_non_overlapped_write(handle);
}
- if (handle->write_reqs_pending == 0 &&
- handle->flags & UV_HANDLE_SHUTTING) {
+ if (handle->shutdown_req != NULL &&
+ handle->write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
@@ -1515,7 +1493,7 @@ void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
CloseHandle(req->pipeHandle);
req->pipeHandle = INVALID_HANDLE_VALUE;
}
- if (!(handle->flags & UV_HANDLE_CLOSING)) {
+ if (!(handle->flags & UV__HANDLE_CLOSING)) {
uv_pipe_queue_accept(loop, handle, req, FALSE);
}
}
@@ -1552,7 +1530,7 @@ void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
/* Initialize and optionally start the eof timer. */
/* This makes no sense if we've already seen EOF. */
- if (!(handle->flags & UV_HANDLE_EOF)) {
+ if (handle->flags & UV_HANDLE_READABLE) {
eof_timer_init(handle);
/* If reading start the timer right now. */
@@ -1656,20 +1634,23 @@ static void eof_timer_close_cb(uv_handle_t* handle) {
}
-void uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
+int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
HANDLE os_handle = (HANDLE)_get_osfhandle(file);
if (os_handle == INVALID_HANDLE_VALUE ||
uv_set_pipe_handle(pipe->loop, pipe, os_handle, 0) == -1) {
- return;
+ uv__set_sys_error(pipe->loop, WSAEINVAL);
+ return -1;
}
uv_pipe_connection_init(pipe);
pipe->handle = os_handle;
+ pipe->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
if (pipe->ipc) {
assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
pipe->ipc_pid = uv_parent_pid();
assert(pipe->ipc_pid != -1);
}
+ return 0;
}
diff --git a/deps/uv/src/win/poll.c b/deps/uv/src/win/poll.c
index 9800b7162..82197241c 100644
--- a/deps/uv/src/win/poll.c
+++ b/deps/uv/src/win/poll.c
@@ -198,7 +198,7 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
if ((handle->events & ~(handle->submitted_events_1 |
handle->submitted_events_2)) != 0) {
uv__fast_poll_submit_poll_req(loop, handle);
- } else if ((handle->flags & UV_HANDLE_CLOSING) &&
+ } else if ((handle->flags & UV__HANDLE_CLOSING) &&
handle->submitted_events_1 == 0 &&
handle->submitted_events_2 == 0) {
uv_want_endgame(loop, (uv_handle_t*) handle);
@@ -208,7 +208,7 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
assert(handle->type == UV_POLL);
- assert(!(handle->flags & UV_HANDLE_CLOSING));
+ assert(!(handle->flags & UV__HANDLE_CLOSING));
assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
handle->events = events;
@@ -230,7 +230,7 @@ static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
static void uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
handle->events = 0;
- uv__handle_start(handle);
+ uv__handle_closing(handle);
if (handle->submitted_events_1 == 0 &&
handle->submitted_events_2 == 0) {
@@ -445,7 +445,7 @@ static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
if ((handle->events & ~(handle->submitted_events_1 |
handle->submitted_events_2)) != 0) {
uv__slow_poll_submit_poll_req(loop, handle);
- } else if ((handle->flags & UV_HANDLE_CLOSING) &&
+ } else if ((handle->flags & UV__HANDLE_CLOSING) &&
handle->submitted_events_1 == 0 &&
handle->submitted_events_2 == 0) {
uv_want_endgame(loop, (uv_handle_t*) handle);
@@ -455,7 +455,7 @@ static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
assert(handle->type == UV_POLL);
- assert(!(handle->flags & UV_HANDLE_CLOSING));
+ assert(!(handle->flags & UV__HANDLE_CLOSING));
assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
handle->events = events;
@@ -477,7 +477,7 @@ static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
static void uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
handle->events = 0;
- uv__handle_start(handle);
+ uv__handle_closing(handle);
if (handle->submitted_events_1 == 0 &&
handle->submitted_events_2 == 0) {
@@ -558,8 +558,6 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
handle->poll_req_2.type = UV_POLL_REQ;
handle->poll_req_2.data = handle;
- loop->counters.poll_init++;
-
return 0;
}
@@ -607,12 +605,11 @@ void uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) {
- assert(handle->flags & UV_HANDLE_CLOSING);
+ assert(handle->flags & UV__HANDLE_CLOSING);
assert(!(handle->flags & UV_HANDLE_CLOSED));
assert(handle->submitted_events_1 == 0);
assert(handle->submitted_events_2 == 0);
- uv__handle_stop(handle);
uv__handle_close(handle);
}
diff --git a/deps/uv/src/win/process-stdio.c b/deps/uv/src/win/process-stdio.c
index ad845a061..89e2cd990 100644
--- a/deps/uv/src/win/process-stdio.c
+++ b/deps/uv/src/win/process-stdio.c
@@ -94,13 +94,14 @@ void uv_disable_stdio_inheritance(void) {
}
-static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
- HANDLE* child_pipe_ptr, unsigned int flags) {
+static uv_err_t uv__create_stdio_pipe_pair(uv_loop_t* loop,
+ uv_pipe_t* server_pipe, HANDLE* child_pipe_ptr, unsigned int flags) {
char pipe_name[64];
SECURITY_ATTRIBUTES sa;
DWORD server_access = 0;
DWORD client_access = 0;
HANDLE child_pipe = INVALID_HANDLE_VALUE;
+ uv_err_t err;
if (flags & UV_READABLE_PIPE) {
server_access |= PIPE_ACCESS_OUTBOUND;
@@ -112,13 +113,13 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
}
/* Create server pipe handle. */
- if (uv_stdio_pipe_server(loop,
- server_pipe,
- server_access,
- pipe_name,
- sizeof(pipe_name)) < 0) {
+ err = uv_stdio_pipe_server(loop,
+ server_pipe,
+ server_access,
+ pipe_name,
+ sizeof(pipe_name));
+ if (err.code != UV_OK)
goto error;
- }
/* Create child pipe handle. */
sa.nLength = sizeof sa;
@@ -133,7 +134,7 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0,
NULL);
if (child_pipe == INVALID_HANDLE_VALUE) {
- uv__set_sys_error(loop, GetLastError());
+ err = uv__new_sys_error(GetLastError());
goto error;
}
@@ -157,13 +158,16 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
/* both ends of the pipe created. */
if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
if (GetLastError() != ERROR_PIPE_CONNECTED) {
- uv__set_sys_error(loop, GetLastError());
+ err = uv__new_sys_error(GetLastError());
goto error;
}
}
+ /* The server end is now readable and writable. */
+ server_pipe->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+
*child_pipe_ptr = child_pipe;
- return 0;
+ return uv_ok_;
error:
if (server_pipe->handle != INVALID_HANDLE_VALUE) {
@@ -174,7 +178,7 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
CloseHandle(child_pipe);
}
- return -1;
+ return err;
}
@@ -227,7 +231,7 @@ static int uv__duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) {
}
-static int uv__create_nul_handle(uv_loop_t* loop, HANDLE* handle_ptr,
+uv_err_t uv__create_nul_handle(HANDLE* handle_ptr,
DWORD access) {
HANDLE handle;
SECURITY_ATTRIBUTES sa;
@@ -244,36 +248,34 @@ static int uv__create_nul_handle(uv_loop_t* loop, HANDLE* handle_ptr,
0,
NULL);
if (handle == INVALID_HANDLE_VALUE) {
- uv__set_sys_error(loop, GetLastError());
- return -1;
+ return uv__new_sys_error(GetLastError());
}
*handle_ptr = handle;
- return 0;
+ return uv_ok_;
}
-int uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
+uv_err_t uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
BYTE** buffer_ptr) {
BYTE* buffer;
int count, i;
+ uv_err_t err;
count = options->stdio_count;
if (count < 0 || count > 255) {
/* Only support FDs 0-255 */
- uv__set_artificial_error(loop, UV_ENOTSUP);
- return -1;
+ return uv__new_artificial_error(UV_ENOTSUP);
} else if (count < 3) {
/* There should always be at least 3 stdio handles. */
count = 3;
}
/* Allocate the child stdio buffer */
- buffer = malloc(CHILD_STDIO_SIZE(count));
+ buffer = (BYTE*) malloc(CHILD_STDIO_SIZE(count));
if (buffer == NULL) {
- uv__set_artificial_error(loop, UV_ENOMEM);
- return -1;
+ return uv__new_artificial_error(UV_ENOMEM);
}
/* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */
@@ -304,11 +306,12 @@ int uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
if (i <= 2) {
DWORD access = (i == 0) ? FILE_GENERIC_READ :
FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES;
- if (uv__create_nul_handle(loop,
- &CHILD_STDIO_HANDLE(buffer, i),
- access) < 0) {
+
+ err = uv__create_nul_handle(&CHILD_STDIO_HANDLE(buffer, i),
+ access);
+ if (err.code != UV_OK)
goto error;
- }
+
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
}
break;
@@ -326,12 +329,12 @@ int uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION));
assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER));
- if (uv__create_stdio_pipe_pair(loop,
- parent_pipe,
- &child_pipe,
- fdopt.flags) < 0) {
+ err = uv__create_stdio_pipe_pair(loop,
+ parent_pipe,
+ &child_pipe,
+ fdopt.flags);
+ if (err.code != UV_OK)
goto error;
- }
CHILD_STDIO_HANDLE(buffer, i) = child_pipe;
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE;
@@ -430,11 +433,11 @@ int uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
}
*buffer_ptr = buffer;
- return 0;
+ return uv_ok_;
error:
uv__stdio_destroy(buffer);
- return -1;
+ return err;
}
diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c
index a8f690d9d..c5649d3ae 100644
--- a/deps/uv/src/win/process.c
+++ b/deps/uv/src/win/process.c
@@ -36,47 +36,61 @@
typedef struct env_var {
const char* narrow;
- const wchar_t* wide;
- int len; /* including null or '=' */
+ const WCHAR* wide;
+ size_t len; /* including null or '=' */
+ DWORD value_len;
int supplied;
- int value_len;
} env_var_t;
#define E_V(str) { str "=", L##str, sizeof(str), 0, 0 }
-#define UTF8_TO_UTF16(s, t) \
- size = uv_utf8_to_utf16(s, NULL, 0) * sizeof(wchar_t); \
- t = (wchar_t*)malloc(size); \
- if (!t) { \
- uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); \
- } \
- if (!uv_utf8_to_utf16(s, t, size / sizeof(wchar_t))) { \
- uv__set_sys_error(loop, GetLastError()); \
- err = -1; \
- goto done; \
+static uv_err_t uv_utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) {
+ int ws_len, r;
+ WCHAR* ws;
+
+ ws_len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ s,
+ -1,
+ NULL,
+ 0);
+ if (ws_len <= 0) {
+ return uv__new_sys_error(GetLastError());
+ }
+
+ ws = (WCHAR*) malloc(ws_len * sizeof(WCHAR));
+ if (ws == NULL) {
+ return uv__new_artificial_error(UV_ENOMEM);
}
+ r = MultiByteToWideChar(CP_UTF8,
+ 0,
+ s,
+ -1,
+ ws,
+ ws_len);
+ assert(r == ws_len);
+
+ *ws_ptr = ws;
+ return uv_ok_;
+}
+
static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
uv__handle_init(loop, (uv_handle_t*) handle, UV_PROCESS);
handle->exit_cb = NULL;
handle->pid = 0;
+ handle->spawn_error = uv_ok_;
handle->exit_signal = 0;
handle->wait_handle = INVALID_HANDLE_VALUE;
handle->process_handle = INVALID_HANDLE_VALUE;
- handle->close_handle = INVALID_HANDLE_VALUE;
handle->child_stdio_buffer = NULL;
+ handle->exit_cb_pending = 0;
uv_req_init(loop, (uv_req_t*)&handle->exit_req);
handle->exit_req.type = UV_PROCESS_EXIT;
handle->exit_req.data = handle;
- uv_req_init(loop, (uv_req_t*)&handle->close_req);
- handle->close_req.type = UV_PROCESS_CLOSE;
- handle->close_req.data = handle;
-
- loop->counters.handle_init++;
- loop->counters.process_init++;
}
@@ -87,15 +101,15 @@ static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
/*
* Helper function for search_path
*/
-static wchar_t* search_path_join_test(const wchar_t* dir,
- int dir_len,
- const wchar_t* name,
- int name_len,
- const wchar_t* ext,
- int ext_len,
- const wchar_t* cwd,
- int cwd_len) {
- wchar_t *result, *result_pos;
+static WCHAR* search_path_join_test(const WCHAR* dir,
+ size_t dir_len,
+ const WCHAR* name,
+ size_t name_len,
+ const WCHAR* ext,
+ size_t ext_len,
+ const WCHAR* cwd,
+ size_t cwd_len) {
+ WCHAR *result, *result_pos;
DWORD attrs;
if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
@@ -121,7 +135,7 @@ static wchar_t* search_path_join_test(const wchar_t* dir,
}
/* Allocate buffer for output */
- result = result_pos = (wchar_t*)malloc(sizeof(wchar_t) *
+ result = result_pos = (WCHAR*)malloc(sizeof(WCHAR) *
(cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1));
/* Copy cwd */
@@ -178,14 +192,14 @@ static wchar_t* search_path_join_test(const wchar_t* dir,
/*
* Helper function for search_path
*/
-static wchar_t* path_search_walk_ext(const wchar_t *dir,
- int dir_len,
- const wchar_t *name,
- int name_len,
- wchar_t *cwd,
- int cwd_len,
- int name_has_ext) {
- wchar_t* result;
+static WCHAR* path_search_walk_ext(const WCHAR *dir,
+ size_t dir_len,
+ const WCHAR *name,
+ size_t name_len,
+ WCHAR *cwd,
+ size_t cwd_len,
+ int name_has_ext) {
+ WCHAR* result;
/* If the name itself has a nonempty extension, try this extension first */
if (name_has_ext) {
@@ -259,19 +273,19 @@ static wchar_t* path_search_walk_ext(const wchar_t *dir,
*
* TODO: correctly interpret UNC paths
*/
-static wchar_t* search_path(const wchar_t *file,
- wchar_t *cwd,
- const wchar_t *path) {
+static WCHAR* search_path(const WCHAR *file,
+ WCHAR *cwd,
+ const WCHAR *path) {
int file_has_dir;
- wchar_t* result = NULL;
- wchar_t *file_name_start;
- wchar_t *dot;
- const wchar_t *dir_start, *dir_end, *dir_path;
- int dir_len;
+ WCHAR* result = NULL;
+ WCHAR *file_name_start;
+ WCHAR *dot;
+ const WCHAR *dir_start, *dir_end, *dir_path;
+ size_t dir_len;
int name_has_ext;
- int file_len = wcslen(file);
- int cwd_len = wcslen(cwd);
+ size_t file_len = wcslen(file);
+ size_t cwd_len = wcslen(cwd);
/* If the caller supplies an empty filename,
* we're not gonna return c:\windows\.exe -- GFY!
@@ -283,7 +297,7 @@ static wchar_t* search_path(const wchar_t *file,
/* Find the start of the filename so we can split the directory from the */
/* name. */
- for (file_name_start = (wchar_t*)file + file_len;
+ for (file_name_start = (WCHAR*)file + file_len;
file_name_start > file
&& file_name_start[-1] != L'\\'
&& file_name_start[-1] != L'/'
@@ -365,10 +379,11 @@ static wchar_t* search_path(const wchar_t *file,
* Quotes command line arguments
* Returns a pointer to the end (next char to be written) of the buffer
*/
-wchar_t* quote_cmd_arg(const wchar_t *source, wchar_t *target) {
- int len = wcslen(source),
- i, quote_hit;
- wchar_t* start;
+WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target) {
+ size_t len = wcslen(source);
+ size_t i;
+ int quote_hit;
+ WCHAR* start;
/*
* Check if the string must be quoted;
@@ -438,61 +453,92 @@ wchar_t* quote_cmd_arg(const wchar_t *source, wchar_t *target) {
}
-wchar_t* make_program_args(char** args, int verbatim_arguments) {
- wchar_t* dst;
- wchar_t* ptr;
+uv_err_t make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
char** arg;
- size_t size = 0;
- size_t len;
+ WCHAR* dst = NULL;
+ WCHAR* temp_buffer = NULL;
+ size_t dst_len = 0;
+ size_t temp_buffer_len = 0;
+ WCHAR* pos;
int arg_count = 0;
- wchar_t* buffer;
- int arg_size;
- int buffer_size = 0;
+ uv_err_t err = uv_ok_;
/* Count the required size. */
for (arg = args; *arg; arg++) {
- arg_size = uv_utf8_to_utf16(*arg, NULL, 0) * sizeof(wchar_t);
- size += arg_size;
- buffer_size = arg_size > buffer_size ? arg_size : buffer_size;
+ DWORD arg_len;
+
+ arg_len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ *arg,
+ -1,
+ NULL,
+ 0);
+ if (arg_len == 0) {
+ return uv__new_sys_error(GetLastError());
+ }
+
+ dst_len += arg_len;
+
+ if (arg_len > temp_buffer_len)
+ temp_buffer_len = arg_len;
+
arg_count++;
}
- /* Adjust for potential quotes. Also assume the worst-case scenario
+ /* Adjust for potential quotes. Also assume the worst-case scenario */
/* that every character needs escaping, so we need twice as much space. */
- size = size * 2 + arg_count * 2;
+ dst_len = dst_len * 2 + arg_count * 2;
- dst = (wchar_t*)malloc(size);
- if (!dst) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ /* Allocate buffer for the final command line. */
+ dst = (WCHAR*) malloc(dst_len * sizeof(WCHAR));
+ if (dst == NULL) {
+ err = uv__new_artificial_error(UV_ENOMEM);
+ goto error;
}
- buffer = (wchar_t*)malloc(buffer_size);
- if (!buffer) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ /* Allocate temporary working buffer. */
+ temp_buffer = (WCHAR*) malloc(temp_buffer_len * sizeof(WCHAR));
+ if (temp_buffer == NULL) {
+ err = uv__new_artificial_error(UV_ENOMEM);
+ goto error;
}
- ptr = dst;
+ pos = dst;
for (arg = args; *arg; arg++) {
- len = uv_utf8_to_utf16(*arg, buffer, (size_t)(size - (ptr - dst)));
- if (!len) {
+ DWORD arg_len;
+
+ /* Convert argument to wide char. */
+ arg_len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ *arg,
+ -1,
+ temp_buffer,
+ (int) (dst + dst_len - pos));
+ if (arg_len == 0) {
goto error;
}
+
if (verbatim_arguments) {
- wcscpy(ptr, buffer);
- ptr += len - 1;
+ /* Copy verbatim. */
+ wcscpy(pos, temp_buffer);
+ pos += arg_len - 1;
} else {
- ptr = quote_cmd_arg(buffer, ptr);
+ /* Quote/escape, if needed. */
+ pos = quote_cmd_arg(temp_buffer, pos);
}
- *ptr++ = *(arg + 1) ? L' ' : L'\0';
+
+ *pos++ = *(arg + 1) ? L' ' : L'\0';
}
- free(buffer);
- return dst;
+ free(temp_buffer);
+
+ *dst_ptr = dst;
+ return uv_ok_;
error:
free(dst);
- free(buffer);
- return NULL;
+ free(temp_buffer);
+ return err;
}
@@ -503,10 +549,10 @@ error:
* issues associated with that solution; this is the caller's
* char**, and modifying it is rude.
*/
-static void check_required_vars_contains_var(env_var_t* required, int size,
+static void check_required_vars_contains_var(env_var_t* required, int count,
const char* var) {
int i;
- for (i = 0; i < size; ++i) {
+ for (i = 0; i < count; ++i) {
if (_strnicmp(required[i].narrow, var, required[i].len) == 0) {
required[i].supplied = 1;
return;
@@ -526,11 +572,11 @@ static void check_required_vars_contains_var(env_var_t* required, int size,
* these get defined if the input environment block does not contain any
* values for them.
*/
-wchar_t* make_program_env(char** env_block) {
- wchar_t* dst;
- wchar_t* ptr;
+uv_err_t make_program_env(char* env_block[], WCHAR** dst_ptr) {
+ WCHAR* dst;
+ WCHAR* ptr;
char** env;
- int env_len = 1 * sizeof(wchar_t); /* room for closing null */
+ size_t env_len = 1; /* room for closing null */
int len;
int i;
DWORD var_size;
@@ -542,36 +588,53 @@ wchar_t* make_program_env(char** env_block) {
};
for (env = env_block; *env; env++) {
+ int len;
check_required_vars_contains_var(required_vars,
ARRAY_SIZE(required_vars),
*env);
- env_len += (uv_utf8_to_utf16(*env, NULL, 0) * sizeof(wchar_t));
+
+ len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ *env,
+ -1,
+ NULL,
+ 0);
+ if (len <= 0) {
+ return uv__new_sys_error(GetLastError());
+ }
+
+ env_len += len;
}
for (i = 0; i < ARRAY_SIZE(required_vars); ++i) {
if (!required_vars[i].supplied) {
- env_len += required_vars[i].len * sizeof(wchar_t);
+ env_len += required_vars[i].len;
var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0);
if (var_size == 0) {
- uv_fatal_error(GetLastError(), "GetEnvironmentVariableW");
+ return uv__new_sys_error(GetLastError());
}
- required_vars[i].value_len = (int)var_size;
- env_len += (int)var_size * sizeof(wchar_t);
+ required_vars[i].value_len = var_size;
+ env_len += var_size;
}
}
- dst = malloc(env_len);
+ dst = malloc(env_len * sizeof(WCHAR));
if (!dst) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ return uv__new_artificial_error(UV_ENOMEM);
}
ptr = dst;
for (env = env_block; *env; env++, ptr += len) {
- len = uv_utf8_to_utf16(*env, ptr, (size_t)(env_len - (ptr - dst)));
- if (!len) {
+ len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ *env,
+ -1,
+ ptr,
+ (int) (env_len - (ptr - dst)));
+ if (len <= 0) {
free(dst);
- return NULL;
+ return uv__new_sys_error(GetLastError());
}
}
@@ -590,8 +653,11 @@ wchar_t* make_program_env(char** env_block) {
}
}
+ /* Terminate with an extra NULL. */
*ptr = L'\0';
- return dst;
+
+ *dst_ptr = dst;
+ return uv_ok_;
}
@@ -600,74 +666,17 @@ wchar_t* make_program_env(char** env_block) {
* a child process has exited.
*/
static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) {
- uv_process_t* process = (uv_process_t*)data;
- uv_loop_t* loop = process->loop;
-
- assert(didTimeout == FALSE);
- assert(process);
-
- /* Post completed */
- POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
-}
-
-
-/*
- * Called on Windows thread-pool thread to indicate that
- * UnregisterWaitEx has completed.
- */
-static void CALLBACK close_wait_callback(void* data, BOOLEAN didTimeout) {
- uv_process_t* process = (uv_process_t*)data;
+ uv_process_t* process = (uv_process_t*) data;
uv_loop_t* loop = process->loop;
assert(didTimeout == FALSE);
assert(process);
+ assert(!process->exit_cb_pending);
- /* Post completed */
- POST_COMPLETION_FOR_REQ(loop, &process->close_req);
-}
-
-
-/*
- * Called on windows thread pool when CreateProcess failed. It writes an error
- * message to the process' intended stderr and then posts a PROCESS_EXIT
- * packet to the completion port.
- */
-static DWORD WINAPI spawn_failure(void* data) {
- char syscall[] = "CreateProcessW: ";
- char unknown[] = "unknown error\n";
- uv_process_t* process = (uv_process_t*) data;
- uv_loop_t* loop = process->loop;
- HANDLE child_stderr = uv__stdio_handle(process->child_stdio_buffer, 2);
- char* buf = NULL;
- DWORD count, written;
-
- if (child_stderr != INVALID_HANDLE_VALUE) {
- WriteFile(child_stderr, syscall, sizeof(syscall) - 1, &written, NULL);
-
- count = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- process->spawn_errno,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPSTR) &buf,
- 0,
- NULL);
-
- if (buf != NULL && count > 0) {
- WriteFile(child_stderr, buf, count, &written, NULL);
- LocalFree(buf);
- } else {
- WriteFile(child_stderr, unknown, sizeof(unknown) - 1, &written, NULL);
- }
-
- FlushFileBuffers(child_stderr);
- }
+ process->exit_cb_pending = 1;
/* Post completed */
POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
-
- return 0;
}
@@ -675,8 +684,13 @@ static DWORD WINAPI spawn_failure(void* data) {
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
DWORD exit_code;
- /* FIXME: race condition. */
- if (handle->flags & UV_HANDLE_CLOSING) {
+ assert(handle->exit_cb_pending);
+ handle->exit_cb_pending = 0;
+
+ /* If we're closing, don't call the exit callback. Just schedule a close */
+ /* callback now. */
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
return;
}
@@ -686,72 +700,67 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
handle->wait_handle = INVALID_HANDLE_VALUE;
}
- if (handle->process_handle == INVALID_HANDLE_VALUE ||
- !GetExitCodeProcess(handle->process_handle, &exit_code)) {
- /* The process never even started in the first place, or we were unable */
- /* to obtain the exit code. */
- exit_code = 127;
- }
-
/* Set the handle to inactive: no callbacks will be made after the exit */
/* callback.*/
uv__handle_stop(handle);
+ if (handle->spawn_error.code != UV_OK) {
+ /* Spawning failed. */
+ exit_code = (DWORD) -1;
+ } else if (!GetExitCodeProcess(handle->process_handle, &exit_code)) {
+ /* Unable to to obtain the exit code. This should never happen. */
+ exit_code = (DWORD) -1;
+ }
+
/* Fire the exit callback. */
if (handle->exit_cb) {
+ loop->last_err = handle->spawn_error;
handle->exit_cb(handle, exit_code, handle->exit_signal);
}
}
-/* Called on main thread after UnregisterWaitEx finishes. */
-void uv_process_proc_close(uv_loop_t* loop, uv_process_t* handle) {
- uv_want_endgame(loop, (uv_handle_t*)handle);
-}
-
-
void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
- uv__handle_start(handle);
+ uv__handle_closing(handle);
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
- handle->close_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
- UnregisterWaitEx(handle->wait_handle, handle->close_handle);
- handle->wait_handle = NULL;
+ /* This blocks until either the wait was cancelled, or the callback has */
+ /* completed. */
+ BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE);
+ if (!r) {
+ /* This should never happen, and if it happens, we can't recover... */
+ uv_fatal_error(GetLastError(), "UnregisterWaitEx");
+ }
- RegisterWaitForSingleObject(&handle->wait_handle, handle->close_handle,
- close_wait_callback, (void*)handle, INFINITE,
- WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
- } else {
+ handle->wait_handle = INVALID_HANDLE_VALUE;
+ }
+
+ if (!handle->exit_cb_pending) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
}
void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) {
- if (handle->flags & UV_HANDLE_CLOSING) {
- assert(!(handle->flags & UV_HANDLE_CLOSED));
- uv__handle_stop(handle);
+ assert(!handle->exit_cb_pending);
+ assert(handle->flags & UV__HANDLE_CLOSING);
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
- /* Clean-up the process handle. */
- CloseHandle(handle->process_handle);
-
- /* Clean up the child stdio ends that may have been left open. */
- if (handle->child_stdio_buffer != NULL) {
- uv__stdio_destroy(handle->child_stdio_buffer);
- }
+ /* Clean-up the process handle. */
+ CloseHandle(handle->process_handle);
- uv__handle_close(handle);
- }
+ uv__handle_close(handle);
}
int uv_spawn(uv_loop_t* loop, uv_process_t* process,
uv_process_options_t options) {
- int i, size, err = 0, keep_child_stdio_open = 0;
- wchar_t* path = NULL;
+ int i;
+ uv_err_t err = uv_ok_;
+ WCHAR* path = NULL;
BOOL result;
- wchar_t* application_path = NULL, *application = NULL, *arguments = NULL,
- *env = NULL, *cwd = NULL;
+ WCHAR* application_path = NULL, *application = NULL, *arguments = NULL,
+ *env = NULL, *cwd = NULL;
STARTUPINFOW startup;
PROCESS_INFORMATION info;
DWORD process_flags;
@@ -761,76 +770,125 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
return -1;
}
+ if (options.file == NULL ||
+ options.args == NULL) {
+ uv__set_artificial_error(loop, UV_EINVAL);
+ return -1;
+ }
+
assert(options.file != NULL);
- assert(!(options.flags & ~(UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
- UV_PROCESS_DETACHED |
+ assert(!(options.flags & ~(UV_PROCESS_DETACHED |
UV_PROCESS_SETGID |
- UV_PROCESS_SETUID)));
+ UV_PROCESS_SETUID |
+ UV_PROCESS_WINDOWS_HIDE |
+ UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
uv_process_init(loop, process);
-
process->exit_cb = options.exit_cb;
- UTF8_TO_UTF16(options.file, application);
- arguments = options.args ? make_program_args(options.args,
- options.flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS) : NULL;
- env = options.env ? make_program_env(options.env) : NULL;
+
+ err = uv_utf8_to_utf16_alloc(options.file, &application);
+ if (err.code != UV_OK)
+ goto done;
+
+ err = make_program_args(options.args,
+ options.flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
+ &arguments);
+ if (err.code != UV_OK)
+ goto done;
+
+ if (options.env) {
+ err = make_program_env(options.env, &env);
+ if (err.code != UV_OK)
+ goto done;
+ }
if (options.cwd) {
- UTF8_TO_UTF16(options.cwd, cwd);
+ /* Explicit cwd */
+ err = uv_utf8_to_utf16_alloc(options.cwd, &cwd);
+ if (err.code != UV_OK)
+ goto done;
+
} else {
- size = GetCurrentDirectoryW(0, NULL) * sizeof(wchar_t);
- if (size) {
- cwd = (wchar_t*)malloc(size);
- if (!cwd) {
- uv__set_artificial_error(loop, UV_ENOMEM);
- err = -1;
- goto done;
- }
+ /* Inherit cwd */
+ DWORD cwd_len, r;
- GetCurrentDirectoryW(size, cwd);
- } else {
- uv__set_sys_error(loop, GetLastError());
- err = -1;
+ cwd_len = GetCurrentDirectoryW(0, NULL);
+ if (!cwd_len) {
+ err = uv__new_sys_error(GetLastError());
+ goto done;
+ }
+
+ cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR));
+ if (cwd == NULL) {
+ err = uv__new_artificial_error(UV_ENOMEM);
+ goto done;
+ }
+
+ r = GetCurrentDirectoryW(cwd_len, cwd);
+ if (r == 0 || r >= cwd_len) {
+ err = uv__new_sys_error(GetLastError());
goto done;
}
}
- /* Get PATH env. variable. */
- size = GetEnvironmentVariableW(L"PATH", NULL, 0) + 1;
- path = (wchar_t*)malloc(size * sizeof(wchar_t));
- if (!path) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ /* Get PATH environment variable. */
+ {
+ DWORD path_len, r;
+
+ path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
+ if (path_len == 0) {
+ err = uv__new_sys_error(GetLastError());
+ goto done;
+ }
+
+
+ path = (WCHAR*) malloc(path_len * sizeof(WCHAR));
+ if (path == NULL) {
+ err = uv__new_artificial_error(UV_ENOMEM);
+ goto done;
+ }
+
+ r = GetEnvironmentVariableW(L"PATH", path, path_len);
+ if (r == 0 || r >= path_len) {
+ err = uv__new_sys_error(GetLastError());
+ goto done;
+ }
}
- GetEnvironmentVariableW(L"PATH", path, size * sizeof(wchar_t));
- path[size - 1] = L'\0';
application_path = search_path(application,
cwd,
path);
-
- if (!application_path) {
- /* CreateProcess will fail, but this allows us to pass this error to */
- /* the user asynchronously. */
- application_path = application;
+ if (application_path == NULL) {
+ /* Not found. */
+ err = uv__new_artificial_error(UV_ENOENT);
+ goto done;
}
- if (uv__stdio_create(loop, &options, &process->child_stdio_buffer) < 0) {
- err = -1;
- goto done;
- }
+ err = uv__stdio_create(loop, &options, &process->child_stdio_buffer);
+ if (err.code != UV_OK)
+ goto done;
startup.cb = sizeof(startup);
startup.lpReserved = NULL;
startup.lpDesktop = NULL;
startup.lpTitle = NULL;
- startup.dwFlags = STARTF_USESTDHANDLES;
+ startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+
startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer);
startup.lpReserved2 = (BYTE*) process->child_stdio_buffer;
+
startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0);
startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1);
startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2);
+ if (options.flags & UV_PROCESS_WINDOWS_HIDE) {
+ /* Use SW_HIDE to avoid any potential process window. */
+ startup.wShowWindow = SW_HIDE;
+ } else {
+ startup.wShowWindow = SW_SHOWDEFAULT;
+ }
+
process_flags = CREATE_UNICODE_ENVIRONMENT;
if (options.flags & UV_PROCESS_DETACHED) {
process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
@@ -871,60 +929,37 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
CloseHandle(info.hThread);
} else {
- /* CreateProcessW failed, but this failure should be delivered */
- /* asynchronously to retain unix compatibility. So pretend spawn */
- /* succeeded, and start a thread instead that prints an error */
- /* to the child's intended stderr. */
- process->spawn_errno = GetLastError();
- keep_child_stdio_open = 1;
- if (!QueueUserWorkItem(spawn_failure, process, WT_EXECUTEDEFAULT)) {
- uv_fatal_error(GetLastError(), "QueueUserWorkItem");
- }
+ /* CreateProcessW failed. */
+ err = uv__new_sys_error(GetLastError());
}
done:
free(application);
- if (application_path != application) {
- free(application_path);
- }
+ free(application_path);
free(arguments);
free(cwd);
free(env);
free(path);
- /* Under normal circumstances we should close the stdio handles now - the */
- /* the child now has its own duplicates, or something went horribly wrong */
- /* The only exception is when CreateProcess has failed, then we actually */
- /* need to keep the stdio handles to report the error asynchronously. */
- if (process->child_stdio_buffer == NULL) {
- /* Something went wrong before child stdio was initialized. */
- } else if (!keep_child_stdio_open) {
+ process->spawn_error = err;
+
+ if (process->child_stdio_buffer != NULL) {
+ /* Clean up child stdio handles. */
uv__stdio_destroy(process->child_stdio_buffer);
process->child_stdio_buffer = NULL;
- } else {
- /* We're keeping the handles open, the thread pool is going to have */
- /* it's way with them. But at least make them non-inheritable. */
- uv__stdio_noinherit(process->child_stdio_buffer);
}
- if (err == 0) {
- /* Spawn was succesful. The handle will be active until the exit */
- /* is made or the handle is closed, whichever happens first. */
- uv__handle_start(process);
- } else {
- /* Spawn was not successful. Clean up. */
- if (process->wait_handle != INVALID_HANDLE_VALUE) {
- UnregisterWait(process->wait_handle);
- process->wait_handle = INVALID_HANDLE_VALUE;
- }
+ /* Make the handle active. It will remain active until the exit callback */
+ /* is made or the handle is closed, whichever happens first. */
+ uv__handle_start(process);
- if (process->process_handle != INVALID_HANDLE_VALUE) {
- CloseHandle(process->process_handle);
- process->process_handle = INVALID_HANDLE_VALUE;
- }
+ /* If an error happened, queue the exit req. */
+ if (err.code != UV_OK) {
+ process->exit_cb_pending = 1;
+ uv_insert_pending_req(loop, (uv_req_t*) &process->exit_req);
}
- return err;
+ return 0;
}
diff --git a/deps/uv/src/win/req-inl.h b/deps/uv/src/win/req-inl.h
index a0d91cb19..353fe90b6 100644
--- a/deps/uv/src/win/req-inl.h
+++ b/deps/uv/src/win/req-inl.h
@@ -80,7 +80,6 @@
INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
- loop->counters.req_init++;
req->type = UV_UNKNOWN_REQ;
SET_REQ_SUCCESS(req);
}
@@ -188,6 +187,10 @@ INLINE static void uv_process_reqs(uv_loop_t* loop) {
uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
break;
+ case UV_SIGNAL_REQ:
+ uv_process_signal_req(loop, (uv_signal_t*) req->data, req);
+ break;
+
case UV_POLL_REQ:
uv_process_poll_req(loop, (uv_poll_t*) req->data, req);
break;
@@ -200,10 +203,6 @@ INLINE static void uv_process_reqs(uv_loop_t* loop) {
uv_process_proc_exit(loop, (uv_process_t*) req->data);
break;
- case UV_PROCESS_CLOSE:
- uv_process_proc_close(loop, (uv_process_t*) req->data);
- break;
-
case UV_FS:
uv_process_fs_req(loop, (uv_fs_t*) req);
break;
diff --git a/deps/uv/src/win/signal.c b/deps/uv/src/win/signal.c
new file mode 100644
index 000000000..e630cd38b
--- /dev/null
+++ b/deps/uv/src/win/signal.c
@@ -0,0 +1,354 @@
+/* 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.
+ */
+
+#include <assert.h>
+#include <signal.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+RB_HEAD(uv_signal_tree_s, uv_signal_s);
+
+static struct uv_signal_tree_s uv__signal_tree = RB_INITIALIZER(uv__signal_tree);
+static ssize_t volatile uv__signal_control_handler_refs = 0;
+static CRITICAL_SECTION uv__signal_lock;
+
+
+void uv_signals_init() {
+ InitializeCriticalSection(&uv__signal_lock);
+}
+
+
+static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
+ /* Compare signums first so all watchers with the same signnum end up */
+ /* adjacent. */
+ if (w1->signum < w2->signum) return -1;
+ if (w1->signum > w2->signum) return 1;
+
+ /* Sort by loop pointer, so we can easily look up the first item after */
+ /* { .signum = x, .loop = NULL } */
+ if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1;
+ if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1;
+
+ if ((uintptr_t) w1 < (uintptr_t) w2) return -1;
+ if ((uintptr_t) w1 > (uintptr_t) w2) return 1;
+
+ return 0;
+}
+
+
+RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare);
+
+
+/*
+ * Dispatches signal {signum} to all active uv_signal_t watchers in all loops.
+ * Returns 1 if the signal was dispatched to any watcher, or 0 if there were
+ * no active signal watchers observing this signal.
+ */
+int uv__signal_dispatch(int signum) {
+ uv_signal_t lookup;
+ uv_signal_t* handle;
+ int dispatched = 0;
+
+ EnterCriticalSection(&uv__signal_lock);
+
+ lookup.signum = signum;
+ lookup.loop = NULL;
+
+ for (handle = RB_NFIND(uv_signal_tree_s, &uv__signal_tree, &lookup);
+ handle != NULL && handle->signum == signum;
+ handle = RB_NEXT(uv_signal_tree_s, &uv__signal_tree, handle)) {
+ unsigned long previous = InterlockedExchange(&handle->pending_signum, signum);
+
+ if (!previous) {
+ POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req);
+ }
+
+ dispatched = 1;
+ }
+
+ LeaveCriticalSection(&uv__signal_lock);
+
+ return dispatched;
+}
+
+
+static BOOL WINAPI uv__signal_control_handler(DWORD type) {
+ switch (type) {
+ case CTRL_C_EVENT:
+ return uv__signal_dispatch(SIGINT);
+
+ case CTRL_BREAK_EVENT:
+ return uv__signal_dispatch(SIGBREAK);
+
+ case CTRL_CLOSE_EVENT:
+ if (uv__signal_dispatch(SIGHUP)) {
+ /* Windows will terminate the process after the control handler */
+ /* returns. After that it will just terminate our process. Therefore */
+ /* block the signal handler so the main loop has some time to pick */
+ /* up the signal and do something for a few seconds. */
+ Sleep(INFINITE);
+ return TRUE;
+ }
+ return FALSE;
+
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ /* These signals are only sent to services. Services have their own */
+ /* notification mechanism, so there's no point in handling these. */
+
+ default:
+ /* We don't handle these. */
+ return FALSE;
+ }
+}
+
+
+static uv_err_t uv__signal_register_control_handler() {
+ /* When this function is called, the uv__signal_lock must be held. */
+
+ /* If the console control handler has already been hooked, just add a */
+ /* reference. */
+ if (uv__signal_control_handler_refs > 0)
+ return uv_ok_;
+
+ if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE))
+ return uv__new_sys_error(GetLastError());
+
+ uv__signal_control_handler_refs++;
+
+ return uv_ok_;
+}
+
+
+static void uv__signal_unregister_control_handler() {
+ /* When this function is called, the uv__signal_lock must be held. */
+ BOOL r;
+
+ /* Don't unregister if the number of console control handlers exceeds one. */
+ /* Just remove a reference in that case. */
+ if (uv__signal_control_handler_refs > 1) {
+ uv__signal_control_handler_refs--;
+ return;
+ }
+
+ assert(uv__signal_control_handler_refs == 1);
+
+ r = SetConsoleCtrlHandler(uv__signal_control_handler, FALSE);
+ /* This should never fail; if it does it is probably a bug in libuv. */
+ assert(r);
+
+ uv__signal_control_handler_refs--;
+}
+
+
+static uv_err_t uv__signal_register(int signum) {
+ switch (signum) {
+ case SIGINT:
+ case SIGBREAK:
+ case SIGHUP:
+ return uv__signal_register_control_handler();
+
+ case SIGWINCH:
+ /* SIGWINCH is generated in tty.c. No need to register anything. */
+ return uv_ok_;
+
+ case SIGILL:
+ case SIGABRT_COMPAT:
+ case SIGFPE:
+ case SIGSEGV:
+ case SIGTERM:
+ case SIGABRT:
+ /* Signal is never raised. */
+ return uv_ok_;
+
+ default:
+ /* Invalid signal. */
+ return uv__new_artificial_error(UV_EINVAL);
+ }
+}
+
+
+static void uv__signal_unregister(int signum) {
+ switch (signum) {
+ case SIGINT:
+ case SIGBREAK:
+ case SIGHUP:
+ uv__signal_unregister_control_handler();
+ return;
+
+ case SIGWINCH:
+ /* SIGWINCH is generated in tty.c. No need to unregister anything. */
+ return;
+
+ case SIGILL:
+ case SIGABRT_COMPAT:
+ case SIGFPE:
+ case SIGSEGV:
+ case SIGTERM:
+ case SIGABRT:
+ /* Nothing is registered for this signal. */
+ return;
+
+ default:
+ /* Libuv bug. */
+ assert(0 && "Invalid signum");
+ return;
+ }
+}
+
+
+int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
+ uv_req_t* req;
+
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
+ handle->pending_signum = 0;
+ handle->signum = 0;
+ handle->signal_cb = NULL;
+
+ req = &handle->signal_req;
+ uv_req_init(loop, req);
+ req->type = UV_SIGNAL_REQ;
+ req->data = handle;
+
+ return 0;
+}
+
+
+int uv_signal_stop(uv_signal_t* handle) {
+ uv_signal_t* removed_handle;
+
+ /* If the watcher wasn't started, this is a no-op. */
+ if (handle->signum == 0)
+ return 0;
+
+ EnterCriticalSection(&uv__signal_lock);
+
+ uv__signal_unregister(handle->signum);
+
+ removed_handle = RB_REMOVE(uv_signal_tree_s, &uv__signal_tree, handle);
+ assert(removed_handle == handle);
+
+ LeaveCriticalSection(&uv__signal_lock);
+
+ handle->signum = 0;
+ uv__handle_stop(handle);
+
+ return 0;
+}
+
+
+int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
+ uv_err_t err;
+
+ /* If the user supplies signum == 0, then return an error already. If the */
+ /* signum is otherwise invalid then uv__signal_register will find out */
+ /* eventually. */
+ if (signum == 0) {
+ uv__set_artificial_error(handle->loop, UV_EINVAL);
+ return -1;
+ }
+
+ /* Short circuit: if the signal watcher is already watching {signum} don't */
+ /* go through the process of deregistering and registering the handler. */
+ /* Additionally, this avoids pending signals getting lost in the (small) */
+ /* time frame that handle->signum == 0. */
+ if (signum == handle->signum) {
+ handle->signal_cb = signal_cb;
+ return 0;
+ }
+
+ /* If the signal handler was already active, stop it first. */
+ if (handle->signum != 0) {
+ int r = uv_signal_stop(handle);
+ /* uv_signal_stop is infallible. */
+ assert(r == 0);
+ }
+
+ EnterCriticalSection(&uv__signal_lock);
+
+ err = uv__signal_register(signum);
+ if (err.code != UV_OK) {
+ /* Uh-oh, didn't work. */
+ handle->loop->last_err = err;
+ LeaveCriticalSection(&uv__signal_lock);
+ return -1;
+ }
+
+ handle->signum = signum;
+ RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle);
+
+ LeaveCriticalSection(&uv__signal_lock);
+
+ handle->signal_cb = signal_cb;
+ uv__handle_start(handle);
+
+ return 0;
+}
+
+
+void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
+ uv_req_t* req) {
+ unsigned long dispatched_signum;
+
+ assert(handle->type == UV_SIGNAL);
+ assert(req->type == UV_SIGNAL_REQ);
+
+ dispatched_signum = InterlockedExchange(&handle->pending_signum, 0);
+ assert(dispatched_signum != 0);
+
+ /* Check if the pending signal equals the signum that we are watching for. */
+ /* These can get out of sync when the handler is stopped and restarted */
+ /* while the signal_req is pending. */
+ if (dispatched_signum == handle->signum)
+ handle->signal_cb(handle, dispatched_signum);
+
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ /* When it is closing, it must be stopped at this point. */
+ assert(handle->signum == 0);
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+}
+
+
+void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) {
+ uv_signal_stop(handle);
+ uv__handle_closing(handle);
+
+ if (handle->pending_signum == 0) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+}
+
+
+void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle) {
+ assert(handle->flags & UV__HANDLE_CLOSING);
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+ assert(handle->signum == 0);
+ assert(handle->pending_signum == 0);
+
+ handle->flags |= UV_HANDLE_CLOSED;
+
+ uv__handle_close(handle);
+}
diff --git a/deps/uv/src/win/stream-inl.h b/deps/uv/src/win/stream-inl.h
index 7e2311c6b..3cde668af 100644
--- a/deps/uv/src/win/stream-inl.h
+++ b/deps/uv/src/win/stream-inl.h
@@ -36,8 +36,6 @@ INLINE static void uv_stream_init(uv_loop_t* loop,
uv__handle_init(loop, (uv_handle_t*) handle, type);
handle->write_queue_size = 0;
handle->activecnt = 0;
-
- loop->counters.stream_init++;
}
diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c
index 195e0b801..097f34979 100644
--- a/deps/uv/src/win/stream.c
+++ b/deps/uv/src/win/stream.c
@@ -55,6 +55,16 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
+ if (handle->flags & UV_HANDLE_READING) {
+ uv__set_sys_error(handle->loop, UV_EALREADY);
+ return -1;
+ }
+
+ if (!(handle->flags & UV_HANDLE_READABLE)) {
+ uv__set_artificial_error(handle->loop, UV_ENOTCONN);
+ return -1;
+ }
+
switch (handle->type) {
case UV_TCP:
return uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb);
@@ -71,6 +81,16 @@ int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
int uv_read2_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
uv_read2_cb read_cb) {
+ if (handle->flags & UV_HANDLE_READING) {
+ uv__set_sys_error(handle->loop, UV_EALREADY);
+ return -1;
+ }
+
+ if (!(handle->flags & UV_HANDLE_READABLE)) {
+ uv__set_artificial_error(handle->loop, UV_ENOTCONN);
+ return -1;
+ }
+
switch (handle->type) {
case UV_NAMED_PIPE:
return uv_pipe_read2_start((uv_pipe_t*)handle, alloc_cb, read_cb);
@@ -82,14 +102,15 @@ int uv_read2_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
int uv_read_stop(uv_stream_t* handle) {
+ if (!(handle->flags & UV_HANDLE_READING))
+ return 0;
+
if (handle->type == UV_TTY) {
return uv_tty_read_stop((uv_tty_t*) handle);
- } else if (handle->flags & UV_HANDLE_READING) {
+ } else {
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(handle->loop, handle);
return 0;
- } else {
- return 0;
}
}
@@ -98,6 +119,11 @@ int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
uv_write_cb cb) {
uv_loop_t* loop = handle->loop;
+ if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+ uv__set_artificial_error(loop, UV_EPIPE);
+ return -1;
+ }
+
switch (handle->type) {
case UV_TCP:
return uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, bufcnt, cb);
@@ -117,6 +143,11 @@ int uv_write2(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
uv_stream_t* send_handle, uv_write_cb cb) {
uv_loop_t* loop = handle->loop;
+ if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+ uv__set_artificial_error(loop, UV_EPIPE);
+ return -1;
+ }
+
switch (handle->type) {
case UV_NAMED_PIPE:
return uv_pipe_write2(loop, req, (uv_pipe_t*) handle, bufs, bufcnt, send_handle, cb);
@@ -131,13 +162,13 @@ int uv_write2(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
uv_loop_t* loop = handle->loop;
- if (!(handle->flags & UV_HANDLE_CONNECTION)) {
- uv__set_sys_error(loop, WSAEINVAL);
+ if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+ uv__set_artificial_error(loop, UV_EPIPE);
return -1;
}
- if (handle->flags & UV_HANDLE_SHUTTING) {
- uv__set_sys_error(loop, WSAESHUTDOWN);
+ if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+ uv__set_artificial_error(loop, UV_EPIPE);
return -1;
}
@@ -146,7 +177,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
req->handle = handle;
req->cb = cb;
- handle->flags |= UV_HANDLE_SHUTTING;
+ handle->flags &= ~UV_HANDLE_WRITABLE;
handle->shutdown_req = req;
handle->reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req);
@@ -158,10 +189,10 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
int uv_is_readable(const uv_stream_t* handle) {
- return !(handle->flags & UV_HANDLE_EOF);
+ return !!(handle->flags & UV_HANDLE_READABLE);
}
int uv_is_writable(const uv_stream_t* handle) {
- return !(handle->flags & UV_HANDLE_SHUTTING);
+ return !!(handle->flags & UV_HANDLE_WRITABLE);
}
diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c
index 8e95c384a..715821613 100644
--- a/deps/uv/src/win/tcp.c
+++ b/deps/uv/src/win/tcp.c
@@ -158,15 +158,12 @@ int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
handle->func_connectex = NULL;
handle->processed_accepts = 0;
- loop->counters.tcp_init++;
-
return 0;
}
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
int status;
- int sys_error;
unsigned int i;
uv_tcp_accept_t* req;
@@ -176,21 +173,17 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
- if (handle->flags & UV_HANDLE_CLOSING) {
+ if (handle->flags & UV__HANDLE_CLOSING) {
status = -1;
- sys_error = WSAEINTR;
+ uv__set_artificial_error(loop, UV_ECANCELED);
} else if (shutdown(handle->socket, SD_SEND) != SOCKET_ERROR) {
status = 0;
- handle->flags |= UV_HANDLE_SHUT;
} else {
status = -1;
- sys_error = WSAGetLastError();
+ uv__set_sys_error(loop, WSAGetLastError());
}
if (handle->shutdown_req->cb) {
- if (status == -1) {
- uv__set_sys_error(loop, sys_error);
- }
handle->shutdown_req->cb(handle->shutdown_req, status);
}
@@ -199,10 +192,9 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
return;
}
- if (handle->flags & UV_HANDLE_CLOSING &&
+ if (handle->flags & UV__HANDLE_CLOSING &&
handle->reqs_pending == 0) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
- uv__handle_stop(handle);
if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
closesocket(handle->socket);
@@ -625,7 +617,7 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
} else {
uv_connection_init((uv_stream_t*) client);
/* AcceptEx() implicitly binds the accepted socket. */
- client->flags |= UV_HANDLE_BOUND;
+ client->flags |= UV_HANDLE_BOUND | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
}
/* Prepare the req to pick up a new connection */
@@ -633,7 +625,7 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
req->next_pending = NULL;
req->accept_socket = INVALID_SOCKET;
- if (!(server->flags & UV_HANDLE_CLOSING)) {
+ if (!(server->flags & UV__HANDLE_CLOSING)) {
/* Check if we're in a middle of changing the number of pending accepts. */
if (!(server->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING)) {
uv_tcp_queue_accept(server, req);
@@ -666,21 +658,6 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
uv_loop_t* loop = handle->loop;
- if (!(handle->flags & UV_HANDLE_CONNECTION)) {
- uv__set_sys_error(loop, WSAEINVAL);
- return -1;
- }
-
- if (handle->flags & UV_HANDLE_READING) {
- uv__set_sys_error(loop, WSAEALREADY);
- return -1;
- }
-
- if (handle->flags & UV_HANDLE_EOF) {
- uv__set_sys_error(loop, WSAESHUTDOWN);
- return -1;
- }
-
handle->flags |= UV_HANDLE_READING;
handle->read_cb = read_cb;
handle->alloc_cb = alloc_cb;
@@ -870,16 +847,6 @@ int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
int result;
DWORD bytes;
- if (!(handle->flags & UV_HANDLE_CONNECTION)) {
- uv__set_sys_error(loop, WSAEINVAL);
- return -1;
- }
-
- if (handle->flags & UV_HANDLE_SHUTTING) {
- uv__set_sys_error(loop, WSAESHUTDOWN);
- return -1;
- }
-
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WRITE;
req->handle = (uv_stream_t*) handle;
@@ -985,7 +952,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle);
}
- handle->flags |= UV_HANDLE_EOF;
+ handle->flags &= ~UV_HANDLE_READABLE;
uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
buf.base = 0;
@@ -1016,9 +983,8 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
}
} else {
/* Connection closed */
- handle->flags &= ~UV_HANDLE_READING;
+ handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE);
DECREASE_ACTIVE_COUNT(loop, handle);
- handle->flags |= UV_HANDLE_EOF;
uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
handle->read_cb((uv_stream_t*)handle, -1, buf);
@@ -1085,7 +1051,7 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
}
handle->write_reqs_pending--;
- if (handle->flags & UV_HANDLE_SHUTTING &&
+ if (handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
@@ -1154,6 +1120,7 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
NULL,
0) == 0) {
uv_connection_init((uv_stream_t*)handle);
+ handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
loop->active_tcp_streams++;
((uv_connect_cb)req->cb)(req, 0);
} else {
@@ -1200,6 +1167,7 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
if (tcp_connection) {
uv_connection_init((uv_stream_t*)tcp);
+ tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
}
tcp->flags |= UV_HANDLE_BOUND;
@@ -1357,7 +1325,6 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) {
/* Just do shutdown on non-shared sockets, which ensures graceful close. */
shutdown(tcp->socket, SD_SEND);
- tcp->flags |= UV_HANDLE_SHUT;
} else if (uv_tcp_try_cancel_io(tcp) == 0) {
/* In case of a shared socket, we try to cancel all outstanding I/O, */
@@ -1412,9 +1379,43 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
}
- uv__handle_start(tcp);
+ tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
+ uv__handle_closing(tcp);
if (tcp->reqs_pending == 0) {
uv_want_endgame(tcp->loop, (uv_handle_t*)tcp);
}
}
+
+
+int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
+ WSAPROTOCOL_INFOW protocol_info;
+ int opt_len;
+
+ /* Detect the address family of the socket. */
+ opt_len = (int) sizeof protocol_info;
+ if (getsockopt(sock,
+ SOL_SOCKET,
+ SO_PROTOCOL_INFOW,
+ (char*) &protocol_info,
+ &opt_len) == SOCKET_ERROR) {
+ uv__set_sys_error(handle->loop, GetLastError());
+ return -1;
+ }
+
+ /* Make the socket non-inheritable */
+ if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
+ uv__set_sys_error(handle->loop, GetLastError());
+ return -1;
+ }
+
+ if (uv_tcp_set_socket(handle->loop,
+ handle,
+ sock,
+ protocol_info.iAddressFamily,
+ 1) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/deps/uv/src/win/thread.c b/deps/uv/src/win/thread.c
index aecfaf4f8..e774fd9cf 100644
--- a/deps/uv/src/win/thread.c
+++ b/deps/uv/src/win/thread.c
@@ -27,6 +27,7 @@
#define HAVE_SRWLOCK_API() (pTryAcquireSRWLockShared != NULL)
+#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL)
#ifdef _MSC_VER /* msvc */
# define inline __inline
@@ -56,15 +57,27 @@ inline static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock);
inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock);
+inline static int uv_cond_fallback_init(uv_cond_t* cond);
+inline static void uv_cond_fallback_destroy(uv_cond_t* cond);
+inline static void uv_cond_fallback_signal(uv_cond_t* cond);
+inline static void uv_cond_fallback_broadcast(uv_cond_t* cond);
+inline static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex);
+inline static int uv_cond_fallback_timedwait(uv_cond_t* cond,
+ uv_mutex_t* mutex, uint64_t timeout);
+
+inline static int uv_cond_condvar_init(uv_cond_t* cond);
+inline static void uv_cond_condvar_destroy(uv_cond_t* cond);
+inline static void uv_cond_condvar_signal(uv_cond_t* cond);
+inline static void uv_cond_condvar_broadcast(uv_cond_t* cond);
+inline static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex);
+inline static int uv_cond_condvar_timedwait(uv_cond_t* cond,
+ uv_mutex_t* mutex, uint64_t timeout);
+
+
static NOINLINE void uv__once_inner(uv_once_t* guard,
void (*callback)(void)) {
DWORD result;
HANDLE existing_event, created_event;
- HANDLE* event_ptr;
-
- /* Fetch and align event_ptr */
- event_ptr = (HANDLE*) (((uintptr_t) &guard->event + (sizeof(HANDLE) - 1)) &
- ~(sizeof(HANDLE) - 1));
created_event = CreateEvent(NULL, 1, 0, NULL);
if (created_event == 0) {
@@ -72,7 +85,7 @@ static NOINLINE void uv__once_inner(uv_once_t* guard,
uv_fatal_error(GetLastError(), "CreateEvent");
}
- existing_event = InterlockedCompareExchangePointer(event_ptr,
+ existing_event = InterlockedCompareExchangePointer(&guard->event,
created_event,
NULL);
@@ -86,7 +99,7 @@ static NOINLINE void uv__once_inner(uv_once_t* guard,
} else {
/* We lost the race. Destroy the event we created and wait for the */
- /* existing one to become signaled. */
+ /* existing one todv become signaled. */
CloseHandle(created_event);
result = WaitForSingleObject(existing_event, INFINITE);
assert(result == WAIT_OBJECT_0);
@@ -145,6 +158,8 @@ void uv_mutex_unlock(uv_mutex_t* mutex) {
int uv_rwlock_init(uv_rwlock_t* rwlock) {
+ uv__once_init();
+
if (HAVE_SRWLOCK_API())
return uv__rwlock_srwlock_init(rwlock);
else
@@ -370,3 +385,282 @@ inline static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock) {
inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock) {
uv_mutex_unlock(&rwlock->fallback_.write_mutex_);
}
+
+
+
+/* This condition variable implementation is based on the SetEvent solution
+ * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ * We could not use the SignalObjectAndWait solution (section 3.4) because
+ * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and
+ * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs.
+ */
+
+inline static int uv_cond_fallback_init(uv_cond_t* cond) {
+ /* Initialize the count to 0. */
+ cond->fallback.waiters_count = 0;
+
+ InitializeCriticalSection(&cond->fallback.waiters_count_lock);
+
+ /* Create an auto-reset event. */
+ cond->fallback.signal_event = CreateEvent(NULL, /* no security */
+ FALSE, /* auto-reset event */
+ FALSE, /* non-signaled initially */
+ NULL); /* unnamed */
+ if (!cond->fallback.signal_event)
+ goto error2;
+
+ /* Create a manual-reset event. */
+ cond->fallback.broadcast_event = CreateEvent(NULL, /* no security */
+ TRUE, /* manual-reset */
+ FALSE, /* non-signaled */
+ NULL); /* unnamed */
+ if (!cond->fallback.broadcast_event)
+ goto error;
+
+ return 0;
+
+error:
+ CloseHandle(cond->fallback.signal_event);
+error2:
+ DeleteCriticalSection(&cond->fallback.waiters_count_lock);
+ return -1;
+}
+
+
+inline static int uv_cond_condvar_init(uv_cond_t* cond) {
+ pInitializeConditionVariable(&cond->cond_var);
+ return 0;
+}
+
+
+int uv_cond_init(uv_cond_t* cond) {
+ uv__once_init();
+
+ if (HAVE_CONDVAR_API())
+ return uv_cond_condvar_init(cond);
+ else
+ return uv_cond_fallback_init(cond);
+}
+
+
+inline static void uv_cond_fallback_destroy(uv_cond_t* cond) {
+ if (!CloseHandle(cond->fallback.broadcast_event))
+ abort();
+ if (!CloseHandle(cond->fallback.signal_event))
+ abort();
+ DeleteCriticalSection(&cond->fallback.waiters_count_lock);
+}
+
+
+inline static void uv_cond_condvar_destroy(uv_cond_t* cond) {
+ /* nothing to do */
+}
+
+
+void uv_cond_destroy(uv_cond_t* cond) {
+ if (HAVE_CONDVAR_API())
+ uv_cond_condvar_destroy(cond);
+ else
+ uv_cond_fallback_destroy(cond);
+}
+
+
+inline static void uv_cond_fallback_signal(uv_cond_t* cond) {
+ int have_waiters;
+
+ /* Avoid race conditions. */
+ EnterCriticalSection(&cond->fallback.waiters_count_lock);
+ have_waiters = cond->fallback.waiters_count > 0;
+ LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+ if (have_waiters)
+ SetEvent(cond->fallback.signal_event);
+}
+
+
+inline static void uv_cond_condvar_signal(uv_cond_t* cond) {
+ pWakeConditionVariable(&cond->cond_var);
+}
+
+
+void uv_cond_signal(uv_cond_t* cond) {
+ if (HAVE_CONDVAR_API())
+ uv_cond_condvar_signal(cond);
+ else
+ uv_cond_fallback_signal(cond);
+}
+
+
+inline static void uv_cond_fallback_broadcast(uv_cond_t* cond) {
+ int have_waiters;
+
+ /* Avoid race conditions. */
+ EnterCriticalSection(&cond->fallback.waiters_count_lock);
+ have_waiters = cond->fallback.waiters_count > 0;
+ LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+ if (have_waiters)
+ SetEvent(cond->fallback.broadcast_event);
+}
+
+
+inline static void uv_cond_condvar_broadcast(uv_cond_t* cond) {
+ pWakeAllConditionVariable(&cond->cond_var);
+}
+
+
+void uv_cond_broadcast(uv_cond_t* cond) {
+ if (HAVE_CONDVAR_API())
+ uv_cond_condvar_broadcast(cond);
+ else
+ uv_cond_fallback_broadcast(cond);
+}
+
+
+inline int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex,
+ DWORD dwMilliseconds) {
+ DWORD result;
+ int last_waiter;
+ HANDLE handles[2] = {
+ cond->fallback.signal_event,
+ cond->fallback.broadcast_event
+ };
+
+ /* Avoid race conditions. */
+ EnterCriticalSection(&cond->fallback.waiters_count_lock);
+ cond->fallback.waiters_count++;
+ LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+ /* It's ok to release the <mutex> here since Win32 manual-reset events */
+ /* maintain state when used with <SetEvent>. This avoids the "lost wakeup" */
+ /* bug. */
+ uv_mutex_unlock(mutex);
+
+ /* Wait for either event to become signaled due to <uv_cond_signal> being */
+ /* called or <uv_cond_broadcast> being called. */
+ result = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
+
+ EnterCriticalSection(&cond->fallback.waiters_count_lock);
+ cond->fallback.waiters_count--;
+ last_waiter = result == WAIT_OBJECT_0 + 1
+ && cond->fallback.waiters_count == 0;
+ LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+ /* Some thread called <pthread_cond_broadcast>. */
+ if (last_waiter) {
+ /* We're the last waiter to be notified or to stop waiting, so reset the */
+ /* the manual-reset event. */
+ ResetEvent(cond->fallback.broadcast_event);
+ }
+
+ /* Reacquire the <mutex>. */
+ uv_mutex_lock(mutex);
+
+ if (result == WAIT_OBJECT_0 || result == WAIT_OBJECT_0 + 1)
+ return 0;
+
+ if (result == WAIT_TIMEOUT)
+ return -1;
+
+ abort();
+ return -1; /* Satisfy the compiler. */
+}
+
+
+inline static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+ if (uv_cond_wait_helper(cond, mutex, INFINITE))
+ abort();
+}
+
+
+inline static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+ if (!pSleepConditionVariableCS(&cond->cond_var, mutex, INFINITE))
+ abort();
+}
+
+
+void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+ if (HAVE_CONDVAR_API())
+ uv_cond_condvar_wait(cond, mutex);
+ else
+ uv_cond_fallback_wait(cond, mutex);
+}
+
+
+inline static int uv_cond_fallback_timedwait(uv_cond_t* cond,
+ uv_mutex_t* mutex, uint64_t timeout) {
+ return uv_cond_wait_helper(cond, mutex, (DWORD)(timeout / 1e6));
+}
+
+
+inline static int uv_cond_condvar_timedwait(uv_cond_t* cond,
+ uv_mutex_t* mutex, uint64_t timeout) {
+ if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
+ return 0;
+ if (GetLastError() != ERROR_TIMEOUT)
+ abort();
+ return -1;
+}
+
+
+int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex,
+ uint64_t timeout) {
+ if (HAVE_CONDVAR_API())
+ return uv_cond_condvar_timedwait(cond, mutex, timeout);
+ else
+ return uv_cond_fallback_timedwait(cond, mutex, timeout);
+}
+
+
+int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+ barrier->n = count;
+ barrier->count = 0;
+
+ if (uv_mutex_init(&barrier->mutex))
+ return -1;
+
+ if (uv_sem_init(&barrier->turnstile1, 0))
+ goto error2;
+
+ if (uv_sem_init(&barrier->turnstile2, 1))
+ goto error;
+
+ return 0;
+
+error:
+ uv_sem_destroy(&barrier->turnstile1);
+error2:
+ uv_mutex_destroy(&barrier->mutex);
+ return -1;
+
+}
+
+
+void uv_barrier_destroy(uv_barrier_t* barrier) {
+ uv_sem_destroy(&barrier->turnstile2);
+ uv_sem_destroy(&barrier->turnstile1);
+ uv_mutex_destroy(&barrier->mutex);
+}
+
+
+void uv_barrier_wait(uv_barrier_t* barrier) {
+ uv_mutex_lock(&barrier->mutex);
+ if (++barrier->count == barrier->n) {
+ uv_sem_wait(&barrier->turnstile2);
+ uv_sem_post(&barrier->turnstile1);
+ }
+ uv_mutex_unlock(&barrier->mutex);
+
+ uv_sem_wait(&barrier->turnstile1);
+ uv_sem_post(&barrier->turnstile1);
+
+ uv_mutex_lock(&barrier->mutex);
+ if (--barrier->count == 0) {
+ uv_sem_wait(&barrier->turnstile1);
+ uv_sem_post(&barrier->turnstile2);
+ }
+ uv_mutex_unlock(&barrier->mutex);
+
+ uv_sem_wait(&barrier->turnstile2);
+ uv_sem_post(&barrier->turnstile2);
+}
diff --git a/deps/uv/src/win/threadpool.c b/deps/uv/src/win/threadpool.c
index 48e00b879..1446878cc 100644
--- a/deps/uv/src/win/threadpool.c
+++ b/deps/uv/src/win/threadpool.c
@@ -55,6 +55,9 @@ static DWORD WINAPI uv_work_thread_proc(void* parameter) {
int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
uv_after_work_cb after_work_cb) {
+ if (work_cb == NULL)
+ return uv__set_artificial_error(loop, UV_EINVAL);
+
uv_work_req_init(loop, req, work_cb, after_work_cb);
if (!QueueUserWorkItem(&uv_work_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
@@ -67,8 +70,13 @@ int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
}
+int uv_cancel(uv_req_t* req) {
+ return -1;
+}
+
+
void uv_process_work_req(uv_loop_t* loop, uv_work_t* req) {
- assert(req->after_work_cb);
uv__req_unregister(loop, req);
- req->after_work_cb(req);
+ if(req->after_work_cb)
+ req->after_work_cb(req, 0);
}
diff --git a/deps/uv/src/win/timer.c b/deps/uv/src/win/timer.c
index 94b7b219c..0c055da94 100644
--- a/deps/uv/src/win/timer.c
+++ b/deps/uv/src/win/timer.c
@@ -45,7 +45,7 @@ void uv_update_time(uv_loop_t* loop) {
}
-int64_t uv_now(uv_loop_t* loop) {
+uint64_t uv_now(uv_loop_t* loop) {
return loop->time;
}
@@ -55,9 +55,13 @@ static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) {
return -1;
if (a->due > b->due)
return 1;
- if ((intptr_t)a < (intptr_t)b)
+ /*
+ * compare start_id when both has the same due. start_id is
+ * allocated with loop->timer_counter in uv_timer_start().
+ */
+ if (a->start_id < b->start_id)
return -1;
- if ((intptr_t)a > (intptr_t)b)
+ if (a->start_id > b->start_id)
return 1;
return 0;
}
@@ -71,23 +75,20 @@ int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
handle->timer_cb = NULL;
handle->repeat = 0;
- loop->counters.timer_init++;
-
return 0;
}
void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) {
- if (handle->flags & UV_HANDLE_CLOSING) {
+ if (handle->flags & UV__HANDLE_CLOSING) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
- uv__handle_stop(handle);
uv__handle_close(handle);
}
}
-int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, int64_t timeout,
- int64_t repeat) {
+int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout,
+ uint64_t repeat) {
uv_loop_t* loop = handle->loop;
uv_timer_t* old;
@@ -101,6 +102,9 @@ int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, int64_t timeout,
handle->flags |= UV_HANDLE_ACTIVE;
uv__handle_start(handle);
+ /* start_id is the second index to be compared in uv__timer_cmp() */
+ handle->start_id = handle->loop->timer_counter++;
+
old = RB_INSERT(uv_timer_tree_s, &loop->timers, handle);
assert(old == NULL);
@@ -153,13 +157,13 @@ int uv_timer_again(uv_timer_t* handle) {
}
-void uv_timer_set_repeat(uv_timer_t* handle, int64_t repeat) {
+void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) {
assert(handle->type == UV_TIMER);
handle->repeat = repeat;
}
-int64_t uv_timer_get_repeat(uv_timer_t* handle) {
+uint64_t uv_timer_get_repeat(const uv_timer_t* handle) {
assert(handle->type == UV_TIMER);
return handle->repeat;
}
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index d290ce2e7..92f4604c2 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -22,7 +22,12 @@
#include <assert.h>
#include <io.h>
#include <string.h>
-#include <stdint.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
#include "uv.h"
#include "internal.h"
@@ -82,6 +87,8 @@ static int uv_tty_virtual_width = -1;
static CRITICAL_SECTION uv_tty_output_lock;
+static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE;
+
void uv_console_init() {
InitializeCriticalSection(&uv_tty_output_lock);
@@ -89,54 +96,79 @@ void uv_console_init() {
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
- HANDLE win_handle;
- CONSOLE_SCREEN_BUFFER_INFO info;
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ DWORD original_console_mode = 0;
+ CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
- loop->counters.tty_init++;
-
- win_handle = (HANDLE) _get_osfhandle(fd);
- if (win_handle == INVALID_HANDLE_VALUE) {
- uv__set_sys_error(loop, ERROR_INVALID_HANDLE);
+ handle = (HANDLE) _get_osfhandle(fd);
+ if (handle == INVALID_HANDLE_VALUE) {
+ uv__set_artificial_error(loop, UV_EBADF);
return -1;
}
- if (!GetConsoleMode(win_handle, &tty->original_console_mode)) {
- uv__set_sys_error(loop, GetLastError());
- return -1;
- }
+ if (readable) {
+ /* Try to obtain the original console mode fromt he input handle. */
+ if (!GetConsoleMode(handle, &original_console_mode)) {
+ uv__set_sys_error(loop, GetLastError());
+ return -1;
+ }
- /* Initialize virtual window size; if it fails, assume that this is stdin. */
- if (GetConsoleScreenBufferInfo(win_handle, &info)) {
+ } else {
+ /* Obtain the screen buffer info with the output handle. */
+ if (!GetConsoleScreenBufferInfo(handle, &screen_buffer_info)) {
+ uv__set_sys_error(loop, GetLastError());
+ return -1;
+ }
+
+ /* Obtain the the tty_output_lock because the virtual window state is */
+ /* shared between all uv_tty_t handles. */
EnterCriticalSection(&uv_tty_output_lock);
- uv_tty_update_virtual_window(&info);
+
+ /* Store the global tty output handle. This handle is used by TTY read */
+ /* streams to update the virtual window when a CONSOLE_BUFFER_SIZE_EVENT */
+ /* is received. */
+ uv_tty_output_handle = handle;
+
+ uv_tty_update_virtual_window(&screen_buffer_info);
+
LeaveCriticalSection(&uv_tty_output_lock);
}
+
uv_stream_init(loop, (uv_stream_t*) tty, UV_TTY);
uv_connection_init((uv_stream_t*) tty);
- tty->handle = win_handle;
- tty->read_line_handle = NULL;
- tty->read_line_buffer = uv_null_buf_;
- tty->read_raw_wait = NULL;
+ tty->handle = handle;
tty->reqs_pending = 0;
tty->flags |= UV_HANDLE_BOUND;
- /* Init keycode-to-vt100 mapper state. */
- tty->last_key_len = 0;
- tty->last_key_offset = 0;
- tty->last_utf16_high_surrogate = 0;
- memset(&tty->last_input_record, 0, sizeof tty->last_input_record);
+ if (readable) {
+ /* Initialize TTY input specific fields. */
+ tty->original_console_mode = original_console_mode;
+ tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE;
+ tty->read_line_handle = NULL;
+ tty->read_line_buffer = uv_null_buf_;
+ tty->read_raw_wait = NULL;
+
+ /* Init keycode-to-vt100 mapper state. */
+ tty->last_key_len = 0;
+ tty->last_key_offset = 0;
+ tty->last_utf16_high_surrogate = 0;
+ memset(&tty->last_input_record, 0, sizeof tty->last_input_record);
+ } else {
+ /* TTY output specific fields. */
+ tty->flags |= UV_HANDLE_WRITABLE;
- /* Init utf8-to-utf16 conversion state. */
- tty->utf8_bytes_left = 0;
- tty->utf8_codepoint = 0;
+ /* Init utf8-to-utf16 conversion state. */
+ tty->utf8_bytes_left = 0;
+ tty->utf8_codepoint = 0;
- /* Initialize eol conversion state */
- tty->previous_eol = 0;
+ /* Initialize eol conversion state */
+ tty->previous_eol = 0;
- /* Init ANSI parser state. */
- tty->ansi_parser_state = ANSI_NORMAL;
+ /* Init ANSI parser state. */
+ tty->ansi_parser_state = ANSI_NORMAL;
+ }
return 0;
}
@@ -148,6 +180,11 @@ int uv_tty_set_mode(uv_tty_t* tty, int mode) {
uv_alloc_cb alloc_cb;
uv_read_cb read_cb;
+ if (!(tty->flags & UV_HANDLE_TTY_READABLE)) {
+ uv__set_artificial_error(tty->loop, UV_EINVAL);
+ return -1;
+ }
+
if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) {
return 0;
}
@@ -444,6 +481,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
off_t buf_used;
assert(handle->type == UV_TTY);
+ assert(handle->flags & UV_HANDLE_TTY_READABLE);
handle->flags &= ~UV_HANDLE_READ_PENDING;
if (!(handle->flags & UV_HANDLE_READING) ||
@@ -491,7 +529,25 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
}
records_left--;
- /* Ignore events that are not keyboard events */
+ /* If the window was resized, recompute the virtual window size. This */
+ /* will trigger a SIGWINCH signal if the window size changed in an */
+ /* way that matters to libuv. */
+ if (handle->last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
+ CONSOLE_SCREEN_BUFFER_INFO info;
+
+ EnterCriticalSection(&uv_tty_output_lock);
+
+ if (uv_tty_output_handle != INVALID_HANDLE_VALUE &&
+ GetConsoleScreenBufferInfo(uv_tty_output_handle, &info)) {
+ uv_tty_update_virtual_window(&info);
+ }
+
+ LeaveCriticalSection(&uv_tty_output_lock);
+
+ continue;
+ }
+
+ /* Ignore other events that are not key or resize events. */
if (handle->last_input_record.EventType != KEY_EVENT) {
continue;
}
@@ -683,6 +739,7 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
uv_buf_t buf;
assert(handle->type == UV_TTY);
+ assert(handle->flags & UV_HANDLE_TTY_READABLE);
buf = handle->read_line_buffer;
@@ -726,6 +783,8 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
uv_req_t* req) {
+ assert(handle->type == UV_TTY);
+ assert(handle->flags & UV_HANDLE_TTY_READABLE);
/* If the read_line_buffer member is zero, it must have been an raw read. */
/* Otherwise it was a line-buffered read. */
@@ -742,6 +801,11 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
uv_loop_t* loop = handle->loop;
+ if (!(handle->flags & UV_HANDLE_TTY_READABLE)) {
+ uv__set_artificial_error(handle->loop, UV_EINVAL);
+ return -1;
+ }
+
handle->flags |= UV_HANDLE_READING;
INCREASE_ACTIVE_COUNT(loop, handle);
handle->read_cb = read_cb;
@@ -770,10 +834,8 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
int uv_tty_read_stop(uv_tty_t* handle) {
uv_loop_t* loop = handle->loop;
- if (handle->flags & UV_HANDLE_READING) {
- handle->flags &= ~UV_HANDLE_READING;
- DECREASE_ACTIVE_COUNT(loop, handle);
- }
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
/* Cancel raw read */
if ((handle->flags & UV_HANDLE_READ_PENDING) &&
@@ -801,8 +863,11 @@ int uv_tty_read_stop(uv_tty_t* handle) {
static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) {
- uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1;
+ int old_virtual_width = uv_tty_virtual_width;
+ int old_virtual_height = uv_tty_virtual_height;
+
uv_tty_virtual_width = info->dwSize.X;
+ uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1;
/* Recompute virtual window offset row. */
if (uv_tty_virtual_offset == -1) {
@@ -820,6 +885,14 @@ static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) {
if (uv_tty_virtual_offset < 0) {
uv_tty_virtual_offset = 0;
}
+
+ /* If the virtual window size changed, emit a SIGWINCH signal. Don't emit */
+ /* if this was the first time the virtual window size was computed. */
+ if (old_virtual_width != -1 && old_virtual_height != -1 &&
+ (uv_tty_virtual_width != old_virtual_width ||
+ uv_tty_virtual_height != old_virtual_height)) {
+ uv__signal_dispatch(SIGWINCH);
+ }
}
@@ -943,10 +1016,10 @@ static int uv_tty_reset(uv_tty_t* handle, DWORD* error) {
count = info.dwSize.X * info.dwSize.Y;
if (!(FillConsoleOutputCharacterW(handle->handle,
- L'\x20',
- count,
- origin,
- &written) &&
+ L'\x20',
+ count,
+ origin,
+ &written) &&
FillConsoleOutputAttribute(handle->handle,
char_attrs,
written,
@@ -1679,12 +1752,6 @@ int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle,
uv_buf_t bufs[], int bufcnt, uv_write_cb cb) {
DWORD error;
- if ((handle->flags & UV_HANDLE_SHUTTING) ||
- (handle->flags & UV_HANDLE_CLOSING)) {
- uv__set_sys_error(loop, WSAESHUTDOWN);
- return -1;
- }
-
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WRITE;
req->handle = (uv_stream_t*) handle;
@@ -1720,7 +1787,7 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
}
handle->write_reqs_pending--;
- if (handle->flags & UV_HANDLE_SHUTTING &&
+ if (handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
@@ -1730,12 +1797,13 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
void uv_tty_close(uv_tty_t* handle) {
- handle->flags |= UV_HANDLE_SHUTTING;
-
- uv_tty_read_stop(handle);
CloseHandle(handle->handle);
- uv__handle_start(handle);
+ if (handle->flags & UV_HANDLE_READING)
+ uv_tty_read_stop(handle);
+
+ handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
+ uv__handle_closing(handle);
if (handle->reqs_pending == 0) {
uv_want_endgame(handle->loop, (uv_handle_t*) handle);
@@ -1744,15 +1812,15 @@ void uv_tty_close(uv_tty_t* handle) {
void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
- if ((handle->flags && UV_HANDLE_CONNECTION) &&
+ if (!(handle->flags && UV_HANDLE_TTY_READABLE) &&
handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
/* TTY shutdown is really just a no-op */
if (handle->shutdown_req->cb) {
- if (handle->flags & UV_HANDLE_CLOSING) {
- uv__set_sys_error(loop, WSAEINTR);
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ uv__set_artificial_error(loop, UV_ECANCELED);
handle->shutdown_req->cb(handle->shutdown_req, -1);
} else {
handle->shutdown_req->cb(handle->shutdown_req, 0);
@@ -1765,18 +1833,19 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
return;
}
- if (handle->flags & UV_HANDLE_CLOSING &&
+ if (handle->flags & UV__HANDLE_CLOSING &&
handle->reqs_pending == 0) {
/* The console handle duplicate used for line reading should be destroyed */
/* by uv_tty_read_stop. */
- assert(handle->read_line_handle == NULL);
+ assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
+ handle->read_line_handle == NULL);
/* The wait handle used for raw reading should be unregistered when the */
/* wait callback runs. */
- assert(handle->read_raw_wait == NULL);
+ assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
+ handle->read_raw_wait == NULL);
assert(!(handle->flags & UV_HANDLE_CLOSED));
- uv__handle_stop(handle);
uv__handle_close(handle);
}
}
@@ -1796,7 +1865,7 @@ void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
}
-void uv_tty_reset_mode() {
+void uv_tty_reset_mode(void) {
/* Not necessary to do anything. */
;
}
diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c
index 212a7823b..b6b6e0f72 100644
--- a/deps/uv/src/win/udp.c
+++ b/deps/uv/src/win/udp.c
@@ -64,6 +64,16 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
assert(handle->socket == INVALID_SOCKET);
+ /* Set SO_REUSEADDR on the socket. */
+ if (setsockopt(socket,
+ SOL_SOCKET,
+ SO_REUSEADDR,
+ (char*) &yes,
+ sizeof yes) == SOCKET_ERROR) {
+ uv__set_sys_error(loop, WSAGetLastError());
+ return -1;
+ }
+
/* Set the socket to nonblocking mode */
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
uv__set_sys_error(loop, WSAGetLastError());
@@ -141,8 +151,6 @@ int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
handle->recv_req.type = UV_UDP_RECV;
handle->recv_req.data = handle;
- loop->counters.udp_init++;
-
return 0;
}
@@ -151,7 +159,7 @@ void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
uv_udp_recv_stop(handle);
closesocket(handle->socket);
- uv__handle_start(handle);
+ uv__handle_closing(handle);
if (handle->reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*) handle);
@@ -160,10 +168,9 @@ void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
- if (handle->flags & UV_HANDLE_CLOSING &&
+ if (handle->flags & UV__HANDLE_CLOSING &&
handle->reqs_pending == 0) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
- uv__handle_stop(handle);
uv__handle_close(handle);
}
}
@@ -213,16 +220,6 @@ static int uv__bind(uv_udp_t* handle,
sizeof no);
}
- r = setsockopt(handle->socket,
- SOL_SOCKET,
- SO_REUSEADDR,
- (char*) &yes,
- sizeof yes);
- if (r == SOCKET_ERROR) {
- uv__set_sys_error(handle->loop, WSAGetLastError());
- return -1;
- }
-
r = bind(handle->socket, addr, addrsize);
if (r == SOCKET_ERROR) {
uv__set_sys_error(handle->loop, WSAGetLastError());
@@ -344,7 +341,7 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
}
-int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
+int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb) {
uv_loop_t* loop = handle->loop;
@@ -374,7 +371,7 @@ int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
}
-int uv_udp_recv_stop(uv_udp_t* handle) {
+int uv__udp_recv_stop(uv_udp_t* handle) {
if (handle->flags & UV_HANDLE_READING) {
handle->flags &= ~UV_HANDLE_READING;
handle->loop->active_udp_streams--;
@@ -385,7 +382,7 @@ int uv_udp_recv_stop(uv_udp_t* handle) {
}
-static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
+static int uv__send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
int bufcnt, struct sockaddr* addr, int addr_len, uv_udp_send_cb cb) {
uv_loop_t* loop = handle->loop;
DWORD result, bytes;
@@ -427,7 +424,7 @@ static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
}
-int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
+int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
int bufcnt, struct sockaddr_in addr, uv_udp_send_cb cb) {
if (!(handle->flags & UV_HANDLE_BOUND) &&
@@ -435,17 +432,17 @@ int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
return -1;
}
- return uv__udp_send(req,
- handle,
- bufs,
- bufcnt,
- (struct sockaddr*) &addr,
- sizeof addr,
- cb);
+ return uv__send(req,
+ handle,
+ bufs,
+ bufcnt,
+ (struct sockaddr*) &addr,
+ sizeof addr,
+ cb);
}
-int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
+int uv__udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
int bufcnt, struct sockaddr_in6 addr, uv_udp_send_cb cb) {
if (!(handle->flags & UV_HANDLE_BOUND) &&
@@ -453,13 +450,13 @@ int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
return -1;
}
- return uv__udp_send(req,
- handle,
- bufs,
- bufcnt,
- (struct sockaddr*) &addr,
- sizeof addr,
- cb);
+ return uv__send(req,
+ handle,
+ bufs,
+ bufcnt,
+ (struct sockaddr*) &addr,
+ sizeof addr,
+ cb);
}
@@ -621,8 +618,7 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
optname = IP_DROP_MEMBERSHIP;
break;
default:
- uv__set_artificial_error(handle->loop, UV_EFAULT);
- return -1;
+ return uv__set_artificial_error(handle->loop, UV_EINVAL);
}
if (setsockopt(handle->socket,
@@ -659,6 +655,33 @@ int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
}
+int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
+ WSAPROTOCOL_INFOW protocol_info;
+ int opt_len;
+ DWORD yes = 1;
+
+ /* Detect the address family of the socket. */
+ opt_len = (int) sizeof protocol_info;
+ if (getsockopt(sock,
+ SOL_SOCKET,
+ SO_PROTOCOL_INFOW,
+ (char*) &protocol_info,
+ &opt_len) == SOCKET_ERROR) {
+ uv__set_sys_error(handle->loop, GetLastError());
+ return -1;
+ }
+
+ if (uv_udp_set_socket(handle->loop,
+ handle,
+ sock,
+ protocol_info.iAddressFamily) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
#define SOCKOPT_SETTER(name, option4, option6, validate) \
int uv_udp_set_##name(uv_udp_t* handle, int value) { \
DWORD optval = (DWORD) value; \
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 2461adc43..96b1abe52 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -74,7 +74,7 @@ void uv__util_init() {
}
-int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
+int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size) {
return WideCharToMultiByte(CP_UTF8,
0,
@@ -87,7 +87,7 @@ int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
}
-int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
+int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
size_t utf16Size) {
return MultiByteToWideChar(CP_UTF8,
0,
@@ -113,7 +113,7 @@ int uv_exepath(char* buffer, size_t* size_ptr) {
utf16_buffer_len = (int) *size_ptr;
}
- utf16_buffer = (wchar_t*) malloc(sizeof(WCHAR) * utf16_buffer_len);
+ utf16_buffer = (WCHAR*) malloc(sizeof(WCHAR) * utf16_buffer_len);
if (!utf16_buffer) {
return -1;
}
@@ -340,7 +340,7 @@ char** uv_setup_args(int argc, char** argv) {
uv_err_t uv_set_process_title(const char* title) {
uv_err_t err;
int length;
- wchar_t* title_w = NULL;
+ WCHAR* title_w = NULL;
uv__once_init();
@@ -352,7 +352,7 @@ uv_err_t uv_set_process_title(const char* title) {
}
/* Convert to wide-char string */
- title_w = (wchar_t*)malloc(sizeof(wchar_t) * length);
+ title_w = (WCHAR*)malloc(sizeof(WCHAR) * length);
if (!title_w) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
@@ -387,7 +387,7 @@ done:
static int uv__get_process_title() {
- wchar_t title_w[MAX_TITLE_LENGTH];
+ WCHAR title_w[MAX_TITLE_LENGTH];
int length;
if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c
index ab5513ab6..ab68bba74 100644
--- a/deps/uv/src/win/winapi.c
+++ b/deps/uv/src/win/winapi.c
@@ -45,6 +45,11 @@ sTryAcquireSRWLockShared pTryAcquireSRWLockShared;
sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive;
sReleaseSRWLockShared pReleaseSRWLockShared;
sReleaseSRWLockExclusive pReleaseSRWLockExclusive;
+sInitializeConditionVariable pInitializeConditionVariable;
+sSleepConditionVariableCS pSleepConditionVariableCS;
+sSleepConditionVariableSRW pSleepConditionVariableSRW;
+sWakeAllConditionVariable pWakeAllConditionVariable;
+sWakeConditionVariable pWakeConditionVariable;
void uv_winapi_init() {
@@ -129,4 +134,19 @@ void uv_winapi_init() {
pReleaseSRWLockExclusive = (sReleaseSRWLockExclusive)
GetProcAddress(kernel32_module, "ReleaseSRWLockExclusive");
+
+ pInitializeConditionVariable = (sInitializeConditionVariable)
+ GetProcAddress(kernel32_module, "InitializeConditionVariable");
+
+ pSleepConditionVariableCS = (sSleepConditionVariableCS)
+ GetProcAddress(kernel32_module, "SleepConditionVariableCS");
+
+ pSleepConditionVariableSRW = (sSleepConditionVariableSRW)
+ GetProcAddress(kernel32_module, "SleepConditionVariableSRW");
+
+ pWakeAllConditionVariable = (sWakeAllConditionVariable)
+ GetProcAddress(kernel32_module, "WakeAllConditionVariable");
+
+ pWakeConditionVariable = (sWakeConditionVariable)
+ GetProcAddress(kernel32_module, "WakeConditionVariable");
}
diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h
index 1bf6304b5..e023beed5 100644
--- a/deps/uv/src/win/winapi.h
+++ b/deps/uv/src/win/winapi.h
@@ -4426,6 +4426,25 @@ typedef VOID (WINAPI* sReleaseSRWLockShared)
typedef VOID (WINAPI* sReleaseSRWLockExclusive)
(PSRWLOCK SRWLock);
+typedef VOID (WINAPI* sInitializeConditionVariable)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+typedef BOOL (WINAPI* sSleepConditionVariableCS)
+ (PCONDITION_VARIABLE ConditionVariable,
+ PCRITICAL_SECTION CriticalSection,
+ DWORD dwMilliseconds);
+
+typedef BOOL (WINAPI* sSleepConditionVariableSRW)
+ (PCONDITION_VARIABLE ConditionVariable,
+ PSRWLOCK SRWLock,
+ DWORD dwMilliseconds,
+ ULONG Flags);
+
+typedef VOID (WINAPI* sWakeAllConditionVariable)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+typedef VOID (WINAPI* sWakeConditionVariable)
+ (PCONDITION_VARIABLE ConditionVariable);
/* Ntdll function pointers */
@@ -4448,5 +4467,10 @@ extern sTryAcquireSRWLockShared pTryAcquireSRWLockShared;
extern sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive;
extern sReleaseSRWLockShared pReleaseSRWLockShared;
extern sReleaseSRWLockExclusive pReleaseSRWLockExclusive;
+extern sInitializeConditionVariable pInitializeConditionVariable;
+extern sSleepConditionVariableCS pSleepConditionVariableCS;
+extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
+extern sWakeAllConditionVariable pWakeAllConditionVariable;
+extern sWakeConditionVariable pWakeConditionVariable;
#endif /* UV_WIN_WINAPI_H_ */
diff --git a/deps/uv/test/benchmark-ares.c b/deps/uv/test/benchmark-ares.c
deleted file mode 100644
index 27084fae2..000000000
--- a/deps/uv/test/benchmark-ares.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/* 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.
- */
-
-#include "uv.h"
-#include "task.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h> /* strlen */
-
-static uv_loop_t* loop;
-
-static ares_channel channel;
-static struct ares_options options;
-static int optmask;
-
-static int ares_callbacks;
-static int ares_errors;
-static int argument;
-
-#define NUM_CALLS_TO_START 1000
-
-static int64_t start_time;
-static int64_t end_time;
-
-
-/* callback method. */
-static void aresbynamecallback(void *arg,
- int status,
- int timeouts,
- struct hostent *hostent) {
- ares_callbacks++;
- if (status != 0) {
- ares_errors++;
- }
-}
-
-
-static void prep_tcploopback()
-{
- /* for test, use echo server - TCP port TEST_PORT on loopback */
- struct sockaddr_in test_server = uv_ip4_addr("127.0.0.1", 0);
- int rc = 0;
- optmask = 0;
-
- optmask = ARES_OPT_SERVERS | ARES_OPT_TCP_PORT | ARES_OPT_FLAGS;
- options.servers = &test_server.sin_addr;
- options.nservers = 1;
- options.tcp_port = htons(TEST_PORT_2);
- options.flags = ARES_FLAG_USEVC;
-
- rc = uv_ares_init_options(loop, &channel, &options, optmask);
-
- ASSERT(rc == ARES_SUCCESS);
-}
-
-
-BENCHMARK_IMPL(gethostbyname) {
-
- int rc = 0;
- int ares_start;;
-
- rc = ares_library_init(ARES_LIB_INIT_ALL);
- if (rc != 0) {
- printf("ares library init fails %d\n", rc);
- return 1;
- }
-
- loop = uv_default_loop();
-
- ares_callbacks = 0;
- ares_errors = 0;
-
- start_time = uv_hrtime();
-
- prep_tcploopback();
-
- for (ares_start = 0; ares_start < NUM_CALLS_TO_START; ares_start++) {
- ares_gethostbyname(channel,
- "echos.srv",
- AF_INET,
- &aresbynamecallback,
- &argument);
- }
-
- uv_run(loop);
-
- uv_ares_destroy(loop, channel);
-
- end_time = uv_hrtime();
-
- if (ares_errors > 0) {
- printf("There were %d failures\n", ares_errors);
- }
- LOGF("ares_gethostbyname: %.0f req/s\n",
- 1e9 * ares_callbacks / (double)(end_time - start_time));
-
- return 0;
-}
diff --git a/deps/uv/test/benchmark-async-pummel.c b/deps/uv/test/benchmark-async-pummel.c
new file mode 100644
index 000000000..4761c1928
--- /dev/null
+++ b/deps/uv/test/benchmark-async-pummel.c
@@ -0,0 +1,119 @@
+/* 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define NUM_PINGS (1000 * 1000)
+#define ACCESS_ONCE(type, var) (*(volatile type*) &(var))
+
+static unsigned int callbacks;
+static volatile int done;
+
+static const char running[] = "running";
+static const char stop[] = "stop";
+static const char stopped[] = "stopped";
+
+
+static void async_cb(uv_async_t* handle, int status) {
+ if (++callbacks == NUM_PINGS) {
+ /* Tell the pummel thread to stop. */
+ ACCESS_ONCE(const char*, handle->data) = stop;
+
+ /* Wait for for the pummel thread to acknowledge that it has stoppped. */
+ while (ACCESS_ONCE(const char*, handle->data) != stopped)
+ uv_sleep(0);
+
+ uv_close((uv_handle_t*) handle, NULL);
+ }
+}
+
+
+static void pummel(void* arg) {
+ uv_async_t* handle = (uv_async_t*) arg;
+
+ while (ACCESS_ONCE(const char*, handle->data) == running)
+ uv_async_send(handle);
+
+ /* Acknowledge that we've seen handle->data change. */
+ ACCESS_ONCE(const char*, handle->data) = stopped;
+}
+
+
+static int test_async_pummel(int nthreads) {
+ uv_thread_t* tids;
+ uv_async_t handle;
+ uint64_t time;
+ int i;
+
+ tids = calloc(nthreads, sizeof(tids[0]));
+ ASSERT(tids != NULL);
+
+ ASSERT(0 == uv_async_init(uv_default_loop(), &handle, async_cb));
+ ACCESS_ONCE(const char*, handle.data) = running;
+
+ for (i = 0; i < nthreads; i++)
+ ASSERT(0 == uv_thread_create(tids + i, pummel, &handle));
+
+ time = uv_hrtime();
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ time = uv_hrtime() - time;
+ done = 1;
+
+ for (i = 0; i < nthreads; i++)
+ ASSERT(0 == uv_thread_join(tids + i));
+
+ printf("async_pummel_%d: %s callbacks in %.2f seconds (%s/sec)\n",
+ nthreads,
+ fmt(callbacks),
+ time / 1e9,
+ fmt(callbacks / (time / 1e9)));
+
+ free(tids);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+BENCHMARK_IMPL(async_pummel_1) {
+ return test_async_pummel(1);
+}
+
+
+BENCHMARK_IMPL(async_pummel_2) {
+ return test_async_pummel(2);
+}
+
+
+BENCHMARK_IMPL(async_pummel_4) {
+ return test_async_pummel(4);
+}
+
+
+BENCHMARK_IMPL(async_pummel_8) {
+ return test_async_pummel(8);
+}
diff --git a/deps/uv/test/benchmark-async.c b/deps/uv/test/benchmark-async.c
new file mode 100644
index 000000000..7d3c936d1
--- /dev/null
+++ b/deps/uv/test/benchmark-async.c
@@ -0,0 +1,139 @@
+/* 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define NUM_PINGS (1000 * 1000)
+
+struct ctx {
+ uv_loop_t* loop;
+ uv_thread_t thread;
+ uv_async_t main_async; /* wake up main thread */
+ uv_async_t worker_async; /* wake up worker */
+ unsigned int nthreads;
+ unsigned int main_sent;
+ unsigned int main_seen;
+ unsigned int worker_sent;
+ unsigned int worker_seen;
+};
+
+
+static void worker_async_cb(uv_async_t* handle, int status) {
+ struct ctx* ctx = container_of(handle, struct ctx, worker_async);
+
+ ASSERT(0 == uv_async_send(&ctx->main_async));
+ ctx->worker_sent++;
+ ctx->worker_seen++;
+
+ if (ctx->worker_sent >= NUM_PINGS)
+ uv_close((uv_handle_t*) &ctx->worker_async, NULL);
+}
+
+
+static void main_async_cb(uv_async_t* handle, int status) {
+ struct ctx* ctx = container_of(handle, struct ctx, main_async);
+
+ ASSERT(0 == uv_async_send(&ctx->worker_async));
+ ctx->main_sent++;
+ ctx->main_seen++;
+
+ if (ctx->main_sent >= NUM_PINGS)
+ uv_close((uv_handle_t*) &ctx->main_async, NULL);
+}
+
+
+static void worker(void* arg) {
+ struct ctx* ctx = arg;
+ ASSERT(0 == uv_async_send(&ctx->main_async));
+ ASSERT(0 == uv_run(ctx->loop, UV_RUN_DEFAULT));
+}
+
+
+static int test_async(int nthreads) {
+ struct ctx* threads;
+ struct ctx* ctx;
+ uint64_t time;
+ int i;
+
+ threads = calloc(nthreads, sizeof(threads[0]));
+ ASSERT(threads != NULL);
+
+ for (i = 0; i < nthreads; i++) {
+ ctx = threads + i;
+ ctx->nthreads = nthreads;
+ ctx->loop = uv_loop_new();
+ ASSERT(ctx->loop != NULL);
+ ASSERT(0 == uv_async_init(ctx->loop, &ctx->worker_async, worker_async_cb));
+ ASSERT(0 == uv_async_init(uv_default_loop(), &ctx->main_async, main_async_cb));
+ ASSERT(0 == uv_thread_create(&ctx->thread, worker, ctx));
+ }
+
+ time = uv_hrtime();
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ for (i = 0; i < nthreads; i++)
+ ASSERT(0 == uv_thread_join(&threads[i].thread));
+
+ time = uv_hrtime() - time;
+
+ for (i = 0; i < nthreads; i++) {
+ ctx = threads + i;
+ ASSERT(ctx->worker_sent == NUM_PINGS);
+ ASSERT(ctx->worker_seen == NUM_PINGS);
+ ASSERT(ctx->main_sent == (unsigned int) NUM_PINGS);
+ ASSERT(ctx->main_seen == (unsigned int) NUM_PINGS);
+ }
+
+ printf("async%d: %.2f sec (%s/sec)\n",
+ nthreads,
+ time / 1e9,
+ fmt(NUM_PINGS / (time / 1e9)));
+
+ free(threads);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+BENCHMARK_IMPL(async1) {
+ return test_async(1);
+}
+
+
+BENCHMARK_IMPL(async2) {
+ return test_async(2);
+}
+
+
+BENCHMARK_IMPL(async4) {
+ return test_async(4);
+}
+
+
+BENCHMARK_IMPL(async8) {
+ return test_async(8);
+}
diff --git a/deps/uv/test/benchmark-fs-stat.c b/deps/uv/test/benchmark-fs-stat.c
index 53aa60b14..5c87de004 100644
--- a/deps/uv/test/benchmark-fs-stat.c
+++ b/deps/uv/test/benchmark-fs-stat.c
@@ -26,7 +26,7 @@
#include <stdlib.h>
#define NUM_SYNC_REQS (10 * 1e5)
-#define NUM_ASYNC_REQS (1 * 1e5)
+#define NUM_ASYNC_REQS (1 * (int) 1e5)
#define MAX_CONCURRENT_REQS 32
#define sync_stat(req, path) \
@@ -43,44 +43,15 @@ struct async_req {
};
-static const char* fmt(double d) {
- uint64_t v;
- char* p;
-
- p = (char *) calloc(1, 32) + 31; /* leaks memory */
- v = d;
-
-#if 0 /* works but we don't care about fractional precision */
- if (d - v >= 0.01) {
- *--p = '0' + (uint64_t) (d * 100) % 10;
- *--p = '0' + (uint64_t) (d * 10) % 10;
- *--p = '.';
- }
-#endif
-
- if (v == 0)
- *--p = '0';
-
- while (v) {
- if (v) *--p = '0' + (v % 10), v /= 10;
- if (v) *--p = '0' + (v % 10), v /= 10;
- if (v) *--p = '0' + (v % 10), v /= 10;
- if (v) *--p = ',';
- }
-
- return p;
-}
-
-
static void warmup(const char* path) {
uv_fs_t reqs[MAX_CONCURRENT_REQS];
- int i;
+ unsigned int i;
/* warm up the thread pool */
for (i = 0; i < ARRAY_SIZE(reqs); i++)
uv_fs_stat(uv_default_loop(), reqs + i, path, uv_fs_req_cleanup);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
/* warm up the OS dirent cache */
for (i = 0; i < 16; i++)
@@ -137,7 +108,7 @@ static void async_bench(const char* path) {
}
before = uv_hrtime();
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
after = uv_hrtime();
printf("%s stats (%d concurrent): %.2fs (%s/s)\n",
@@ -160,5 +131,6 @@ BENCHMARK_IMPL(fs_stat) {
warmup(path);
sync_bench(path);
async_bench(path);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/benchmark-getaddrinfo.c b/deps/uv/test/benchmark-getaddrinfo.c
index 892c14d1e..c7f99a2fc 100644
--- a/deps/uv/test/benchmark-getaddrinfo.c
+++ b/deps/uv/test/benchmark-getaddrinfo.c
@@ -21,16 +21,12 @@
#include "uv.h"
#include "task.h"
-
#include <stdlib.h>
-#include <stdio.h>
-#include <string.h> /* strlen */
-
#define CONCURRENT_CALLS 10
#define TOTAL_CALLS 10000
-const char* name = "localhost";
+static const char* name = "localhost";
static uv_loop_t* loop;
@@ -79,7 +75,7 @@ BENCHMARK_IMPL(getaddrinfo) {
getaddrinfo_initiate(&handles[i]);
}
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
uv_update_time(loop);
end_time = uv_now(loop);
@@ -90,5 +86,6 @@ BENCHMARK_IMPL(getaddrinfo) {
LOGF("getaddrinfo: %.0f req/s\n",
(double) calls_completed / (double) (end_time - start_time) * 1000.0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/benchmark-list.h b/deps/uv/test/benchmark-list.h
index 2e24682f6..1e843071c 100644
--- a/deps/uv/test/benchmark-list.h
+++ b/deps/uv/test/benchmark-list.h
@@ -32,21 +32,48 @@ BENCHMARK_DECLARE (tcp_pump100_client)
BENCHMARK_DECLARE (tcp_pump1_client)
BENCHMARK_DECLARE (pipe_pump100_client)
BENCHMARK_DECLARE (pipe_pump1_client)
-BENCHMARK_DECLARE (udp_packet_storm_1v1)
-BENCHMARK_DECLARE (udp_packet_storm_1v10)
-BENCHMARK_DECLARE (udp_packet_storm_1v100)
-BENCHMARK_DECLARE (udp_packet_storm_1v1000)
-BENCHMARK_DECLARE (udp_packet_storm_10v10)
-BENCHMARK_DECLARE (udp_packet_storm_10v100)
-BENCHMARK_DECLARE (udp_packet_storm_10v1000)
-BENCHMARK_DECLARE (udp_packet_storm_100v100)
-BENCHMARK_DECLARE (udp_packet_storm_100v1000)
-BENCHMARK_DECLARE (udp_packet_storm_1000v1000)
-BENCHMARK_DECLARE (gethostbyname)
+
+BENCHMARK_DECLARE (tcp_multi_accept2)
+BENCHMARK_DECLARE (tcp_multi_accept4)
+BENCHMARK_DECLARE (tcp_multi_accept8)
+
+/* Run until X packets have been sent/received. */
+BENCHMARK_DECLARE (udp_pummel_1v1)
+BENCHMARK_DECLARE (udp_pummel_1v10)
+BENCHMARK_DECLARE (udp_pummel_1v100)
+BENCHMARK_DECLARE (udp_pummel_1v1000)
+BENCHMARK_DECLARE (udp_pummel_10v10)
+BENCHMARK_DECLARE (udp_pummel_10v100)
+BENCHMARK_DECLARE (udp_pummel_10v1000)
+BENCHMARK_DECLARE (udp_pummel_100v100)
+BENCHMARK_DECLARE (udp_pummel_100v1000)
+BENCHMARK_DECLARE (udp_pummel_1000v1000)
+
+/* Run until X seconds have elapsed. */
+BENCHMARK_DECLARE (udp_timed_pummel_1v1)
+BENCHMARK_DECLARE (udp_timed_pummel_1v10)
+BENCHMARK_DECLARE (udp_timed_pummel_1v100)
+BENCHMARK_DECLARE (udp_timed_pummel_1v1000)
+BENCHMARK_DECLARE (udp_timed_pummel_10v10)
+BENCHMARK_DECLARE (udp_timed_pummel_10v100)
+BENCHMARK_DECLARE (udp_timed_pummel_10v1000)
+BENCHMARK_DECLARE (udp_timed_pummel_100v100)
+BENCHMARK_DECLARE (udp_timed_pummel_100v1000)
+BENCHMARK_DECLARE (udp_timed_pummel_1000v1000)
+
BENCHMARK_DECLARE (getaddrinfo)
BENCHMARK_DECLARE (fs_stat)
+BENCHMARK_DECLARE (async1)
+BENCHMARK_DECLARE (async2)
+BENCHMARK_DECLARE (async4)
+BENCHMARK_DECLARE (async8)
+BENCHMARK_DECLARE (async_pummel_1)
+BENCHMARK_DECLARE (async_pummel_2)
+BENCHMARK_DECLARE (async_pummel_4)
+BENCHMARK_DECLARE (async_pummel_8)
BENCHMARK_DECLARE (spawn)
BENCHMARK_DECLARE (thread_create)
+BENCHMARK_DECLARE (million_async)
BENCHMARK_DECLARE (million_timers)
HELPER_DECLARE (tcp4_blackhole_server)
HELPER_DECLARE (tcp_pump_server)
@@ -90,25 +117,47 @@ TASK_LIST_START
BENCHMARK_ENTRY (pipe_pound_1000)
BENCHMARK_HELPER (pipe_pound_1000, pipe_echo_server)
- BENCHMARK_ENTRY (udp_packet_storm_1v1)
- BENCHMARK_ENTRY (udp_packet_storm_1v10)
- BENCHMARK_ENTRY (udp_packet_storm_1v100)
- BENCHMARK_ENTRY (udp_packet_storm_1v1000)
- BENCHMARK_ENTRY (udp_packet_storm_10v10)
- BENCHMARK_ENTRY (udp_packet_storm_10v100)
- BENCHMARK_ENTRY (udp_packet_storm_10v1000)
- BENCHMARK_ENTRY (udp_packet_storm_100v100)
- BENCHMARK_ENTRY (udp_packet_storm_100v1000)
- BENCHMARK_ENTRY (udp_packet_storm_1000v1000)
-
- BENCHMARK_ENTRY (gethostbyname)
- BENCHMARK_HELPER (gethostbyname, dns_server)
+ BENCHMARK_ENTRY (tcp_multi_accept2)
+ BENCHMARK_ENTRY (tcp_multi_accept4)
+ BENCHMARK_ENTRY (tcp_multi_accept8)
+
+ BENCHMARK_ENTRY (udp_pummel_1v1)
+ BENCHMARK_ENTRY (udp_pummel_1v10)
+ BENCHMARK_ENTRY (udp_pummel_1v100)
+ BENCHMARK_ENTRY (udp_pummel_1v1000)
+ BENCHMARK_ENTRY (udp_pummel_10v10)
+ BENCHMARK_ENTRY (udp_pummel_10v100)
+ BENCHMARK_ENTRY (udp_pummel_10v1000)
+ BENCHMARK_ENTRY (udp_pummel_100v100)
+ BENCHMARK_ENTRY (udp_pummel_100v1000)
+ BENCHMARK_ENTRY (udp_pummel_1000v1000)
+
+ BENCHMARK_ENTRY (udp_timed_pummel_1v1)
+ BENCHMARK_ENTRY (udp_timed_pummel_1v10)
+ BENCHMARK_ENTRY (udp_timed_pummel_1v100)
+ BENCHMARK_ENTRY (udp_timed_pummel_1v1000)
+ BENCHMARK_ENTRY (udp_timed_pummel_10v10)
+ BENCHMARK_ENTRY (udp_timed_pummel_10v100)
+ BENCHMARK_ENTRY (udp_timed_pummel_10v1000)
+ BENCHMARK_ENTRY (udp_timed_pummel_100v100)
+ BENCHMARK_ENTRY (udp_timed_pummel_100v1000)
+ BENCHMARK_ENTRY (udp_timed_pummel_1000v1000)
BENCHMARK_ENTRY (getaddrinfo)
BENCHMARK_ENTRY (fs_stat)
+ BENCHMARK_ENTRY (async1)
+ BENCHMARK_ENTRY (async2)
+ BENCHMARK_ENTRY (async4)
+ BENCHMARK_ENTRY (async8)
+ BENCHMARK_ENTRY (async_pummel_1)
+ BENCHMARK_ENTRY (async_pummel_2)
+ BENCHMARK_ENTRY (async_pummel_4)
+ BENCHMARK_ENTRY (async_pummel_8)
+
BENCHMARK_ENTRY (spawn)
BENCHMARK_ENTRY (thread_create)
+ BENCHMARK_ENTRY (million_async)
BENCHMARK_ENTRY (million_timers)
TASK_LIST_END
diff --git a/deps/uv/test/benchmark-loop-count.c b/deps/uv/test/benchmark-loop-count.c
index a58181a2c..b4ee0ed5f 100644
--- a/deps/uv/test/benchmark-loop-count.c
+++ b/deps/uv/test/benchmark-loop-count.c
@@ -57,7 +57,7 @@ BENCHMARK_IMPL(loop_count) {
uv_idle_start(&idle_handle, idle_cb);
ns = uv_hrtime();
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ns = uv_hrtime() - ns;
ASSERT(ticks == NUM_TICKS);
@@ -67,6 +67,7 @@ BENCHMARK_IMPL(loop_count) {
ns / 1e9,
NUM_TICKS / (ns / 1e9));
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -80,9 +81,10 @@ BENCHMARK_IMPL(loop_count_timed) {
uv_timer_init(loop, &timer_handle);
uv_timer_start(&timer_handle, timer_cb, 5000, 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
LOGF("loop_count: %lu ticks (%.0f ticks/s)\n", ticks, ticks / 5.0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/benchmark-million-async.c b/deps/uv/test/benchmark-million-async.c
new file mode 100644
index 000000000..69cc80343
--- /dev/null
+++ b/deps/uv/test/benchmark-million-async.c
@@ -0,0 +1,112 @@
+/* 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+struct async_container {
+ unsigned async_events;
+ unsigned handles_seen;
+ uv_async_t async_handles[1024 * 1024];
+};
+
+static volatile int done;
+static uv_thread_t thread_id;
+static struct async_container* container;
+
+
+static unsigned fastrand(void) {
+ static unsigned g = 0;
+ g = g * 214013 + 2531011;
+ return g;
+}
+
+
+static void thread_cb(void* arg) {
+ unsigned i;
+
+ while (done == 0) {
+ i = fastrand() % ARRAY_SIZE(container->async_handles);
+ uv_async_send(container->async_handles + i);
+ }
+}
+
+
+static void async_cb(uv_async_t* handle, int status) {
+ container->async_events++;
+ handle->data = handle;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ unsigned i;
+
+ done = 1;
+ ASSERT(0 == uv_thread_join(&thread_id));
+
+ for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) {
+ uv_async_t* handle = container->async_handles + i;
+
+ if (handle->data != NULL)
+ container->handles_seen++;
+
+ uv_close((uv_handle_t*) handle, NULL);
+ }
+
+ uv_close((uv_handle_t*) handle, NULL);
+}
+
+
+BENCHMARK_IMPL(million_async) {
+ uv_timer_t timer_handle;
+ uv_async_t* handle;
+ uv_loop_t* loop;
+ int timeout;
+ unsigned i;
+
+ loop = uv_default_loop();
+ timeout = 5000;
+
+ container = malloc(sizeof(*container));
+ ASSERT(container != NULL);
+ container->async_events = 0;
+ container->handles_seen = 0;
+
+ for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) {
+ handle = container->async_handles + i;
+ ASSERT(0 == uv_async_init(loop, handle, async_cb));
+ handle->data = NULL;
+ }
+
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, timeout, 0));
+ ASSERT(0 == uv_thread_create(&thread_id, thread_cb, NULL));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ printf("%s async events in %.1f seconds (%s/s, %s unique handles seen)\n",
+ fmt(container->async_events),
+ timeout / 1000.,
+ fmt(container->async_events / (timeout / 1000.)),
+ fmt(container->handles_seen));
+ free(container);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/benchmark-million-timers.c b/deps/uv/test/benchmark-million-timers.c
index ae56b2bc6..fe887344b 100644
--- a/deps/uv/test/benchmark-million-timers.c
+++ b/deps/uv/test/benchmark-million-timers.c
@@ -25,6 +25,7 @@
#define NUM_TIMERS (1000 * 1000)
static int timer_cb_called;
+static int close_cb_called;
static void timer_cb(uv_timer_t* handle, int status) {
@@ -32,6 +33,11 @@ static void timer_cb(uv_timer_t* handle, int status) {
}
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
BENCHMARK_IMPL(million_timers) {
uv_timer_t* timers;
uv_loop_t* loop;
@@ -53,13 +59,19 @@ BENCHMARK_IMPL(million_timers) {
}
before = uv_hrtime();
- ASSERT(0 == uv_run(loop));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
after = uv_hrtime();
+ for (i = 0; i < NUM_TIMERS; i++)
+ uv_close((uv_handle_t*) (timers + i), close_cb);
+
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(timer_cb_called == NUM_TIMERS);
+ ASSERT(close_cb_called == NUM_TIMERS);
free(timers);
LOGF("%.2f seconds\n", (after - before) / 1e9);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/benchmark-multi-accept.c b/deps/uv/test/benchmark-multi-accept.c
new file mode 100644
index 000000000..c6333e71b
--- /dev/null
+++ b/deps/uv/test/benchmark-multi-accept.c
@@ -0,0 +1,432 @@
+/* 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#define IPC_PIPE_NAME TEST_PIPENAME
+#define NUM_CONNECTS (250 * 1000)
+
+union stream_handle {
+ uv_pipe_t pipe;
+ uv_tcp_t tcp;
+};
+
+/* Use as (uv_stream_t *) &handle_storage -- it's kind of clunky but it
+ * avoids aliasing warnings.
+ */
+typedef unsigned char handle_storage_t[sizeof(union stream_handle)];
+
+/* Used for passing around the listen handle, not part of the benchmark proper.
+ * We have an overabundance of server types here. It works like this:
+ *
+ * 1. The main thread starts an IPC pipe server.
+ * 2. The worker threads connect to the IPC server and obtain a listen handle.
+ * 3. The worker threads start accepting requests on the listen handle.
+ * 4. The main thread starts connecting repeatedly.
+ *
+ * Step #4 should perhaps be farmed out over several threads.
+ */
+struct ipc_server_ctx {
+ handle_storage_t server_handle;
+ unsigned int num_connects;
+ uv_pipe_t ipc_pipe;
+};
+
+struct ipc_peer_ctx {
+ handle_storage_t peer_handle;
+ uv_write_t write_req;
+};
+
+struct ipc_client_ctx {
+ uv_connect_t connect_req;
+ uv_stream_t* server_handle;
+ uv_pipe_t ipc_pipe;
+ char scratch[16];
+};
+
+/* Used in the actual benchmark. */
+struct server_ctx {
+ handle_storage_t server_handle;
+ unsigned int num_connects;
+ uv_async_t async_handle;
+ uv_thread_t thread_id;
+ uv_sem_t semaphore;
+};
+
+struct client_ctx {
+ handle_storage_t client_handle;
+ unsigned int num_connects;
+ uv_connect_t connect_req;
+ uv_idle_t idle_handle;
+};
+
+static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status);
+static void ipc_write_cb(uv_write_t* req, int status);
+static void ipc_close_cb(uv_handle_t* handle);
+static void ipc_connect_cb(uv_connect_t* req, int status);
+static void ipc_read2_cb(uv_pipe_t* ipc_pipe,
+ ssize_t nread,
+ uv_buf_t buf,
+ uv_handle_type type);
+static uv_buf_t ipc_alloc_cb(uv_handle_t* handle, size_t suggested_size);
+
+static void sv_async_cb(uv_async_t* handle, int status);
+static void sv_connection_cb(uv_stream_t* server_handle, int status);
+static void sv_read_cb(uv_stream_t* handle, ssize_t nread, uv_buf_t buf);
+static uv_buf_t sv_alloc_cb(uv_handle_t* handle, size_t suggested_size);
+
+static void cl_connect_cb(uv_connect_t* req, int status);
+static void cl_idle_cb(uv_idle_t* handle, int status);
+static void cl_close_cb(uv_handle_t* handle);
+
+static struct sockaddr_in listen_addr;
+
+
+static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status) {
+ struct ipc_server_ctx* sc;
+ struct ipc_peer_ctx* pc;
+ uv_loop_t* loop;
+ uv_buf_t buf;
+
+ loop = ipc_pipe->loop;
+ buf = uv_buf_init("PING", 4);
+ sc = container_of(ipc_pipe, struct ipc_server_ctx, ipc_pipe);
+ pc = calloc(1, sizeof(*pc));
+ ASSERT(pc != NULL);
+
+ if (ipc_pipe->type == UV_TCP)
+ ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &pc->peer_handle));
+ else if (ipc_pipe->type == UV_NAMED_PIPE)
+ ASSERT(0 == uv_pipe_init(loop, (uv_pipe_t*) &pc->peer_handle, 1));
+ else
+ ASSERT(0);
+
+ ASSERT(0 == uv_accept(ipc_pipe, (uv_stream_t*) &pc->peer_handle));
+ ASSERT(0 == uv_write2(&pc->write_req,
+ (uv_stream_t*) &pc->peer_handle,
+ &buf,
+ 1,
+ (uv_stream_t*) &sc->server_handle,
+ ipc_write_cb));
+
+ if (--sc->num_connects == 0)
+ uv_close((uv_handle_t*) ipc_pipe, NULL);
+}
+
+
+static void ipc_write_cb(uv_write_t* req, int status) {
+ struct ipc_peer_ctx* ctx;
+ ctx = container_of(req, struct ipc_peer_ctx, write_req);
+ uv_close((uv_handle_t*) &ctx->peer_handle, ipc_close_cb);
+}
+
+
+static void ipc_close_cb(uv_handle_t* handle) {
+ struct ipc_peer_ctx* ctx;
+ ctx = container_of(handle, struct ipc_peer_ctx, peer_handle);
+ free(ctx);
+}
+
+
+static void ipc_connect_cb(uv_connect_t* req, int status) {
+ struct ipc_client_ctx* ctx;
+ ctx = container_of(req, struct ipc_client_ctx, connect_req);
+ ASSERT(0 == status);
+ ASSERT(0 == uv_read2_start((uv_stream_t*) &ctx->ipc_pipe,
+ ipc_alloc_cb,
+ ipc_read2_cb));
+}
+
+
+static uv_buf_t ipc_alloc_cb(uv_handle_t* handle, size_t suggested_size) {
+ struct ipc_client_ctx* ctx;
+ ctx = container_of(handle, struct ipc_client_ctx, ipc_pipe);
+ return uv_buf_init(ctx->scratch, sizeof(ctx->scratch));
+}
+
+
+static void ipc_read2_cb(uv_pipe_t* ipc_pipe,
+ ssize_t nread,
+ uv_buf_t buf,
+ uv_handle_type type) {
+ struct ipc_client_ctx* ctx;
+ uv_loop_t* loop;
+
+ ctx = container_of(ipc_pipe, struct ipc_client_ctx, ipc_pipe);
+ loop = ipc_pipe->loop;
+
+ if (type == UV_TCP)
+ ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) ctx->server_handle));
+ else if (type == UV_NAMED_PIPE)
+ ASSERT(0 == uv_pipe_init(loop, (uv_pipe_t*) ctx->server_handle, 0));
+ else
+ ASSERT(0);
+
+ ASSERT(0 == uv_accept((uv_stream_t*) &ctx->ipc_pipe, ctx->server_handle));
+ uv_close((uv_handle_t*) &ctx->ipc_pipe, NULL);
+}
+
+
+/* Set up an IPC pipe server that hands out listen sockets to the worker
+ * threads. It's kind of cumbersome for such a simple operation, maybe we
+ * should revive uv_import() and uv_export().
+ */
+static void send_listen_handles(uv_handle_type type,
+ unsigned int num_servers,
+ struct server_ctx* servers) {
+ struct ipc_server_ctx ctx;
+ uv_loop_t* loop;
+ unsigned int i;
+
+ loop = uv_default_loop();
+ ctx.num_connects = num_servers;
+
+ if (type == UV_TCP) {
+ ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &ctx.server_handle));
+ ASSERT(0 == uv_tcp_bind((uv_tcp_t*) &ctx.server_handle, listen_addr));
+ }
+ else
+ ASSERT(0);
+
+ ASSERT(0 == uv_pipe_init(loop, &ctx.ipc_pipe, 1));
+ ASSERT(0 == uv_pipe_bind(&ctx.ipc_pipe, IPC_PIPE_NAME));
+ ASSERT(0 == uv_listen((uv_stream_t*) &ctx.ipc_pipe, 128, ipc_connection_cb));
+
+ for (i = 0; i < num_servers; i++)
+ uv_sem_post(&servers[i].semaphore);
+
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ uv_close((uv_handle_t*) &ctx.server_handle, NULL);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ for (i = 0; i < num_servers; i++)
+ uv_sem_wait(&servers[i].semaphore);
+}
+
+
+static void get_listen_handle(uv_loop_t* loop, uv_stream_t* server_handle) {
+ struct ipc_client_ctx ctx;
+
+ ctx.server_handle = server_handle;
+ ctx.server_handle->data = "server handle";
+
+ ASSERT(0 == uv_pipe_init(loop, &ctx.ipc_pipe, 1));
+ uv_pipe_connect(&ctx.connect_req,
+ &ctx.ipc_pipe,
+ IPC_PIPE_NAME,
+ ipc_connect_cb);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+}
+
+
+static void server_cb(void *arg) {
+ struct server_ctx *ctx;
+ uv_loop_t* loop;
+
+ ctx = arg;
+ loop = uv_loop_new();
+ ASSERT(loop != NULL);
+
+ ASSERT(0 == uv_async_init(loop, &ctx->async_handle, sv_async_cb));
+ uv_unref((uv_handle_t*) &ctx->async_handle);
+
+ /* Wait until the main thread is ready. */
+ uv_sem_wait(&ctx->semaphore);
+ get_listen_handle(loop, (uv_stream_t*) &ctx->server_handle);
+ uv_sem_post(&ctx->semaphore);
+
+ /* Now start the actual benchmark. */
+ ASSERT(0 == uv_listen((uv_stream_t*) &ctx->server_handle,
+ 128,
+ sv_connection_cb));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ uv_loop_delete(loop);
+}
+
+
+static void sv_async_cb(uv_async_t* handle, int status) {
+ struct server_ctx* ctx;
+ ctx = container_of(handle, struct server_ctx, async_handle);
+ uv_close((uv_handle_t*) &ctx->server_handle, NULL);
+ uv_close((uv_handle_t*) &ctx->async_handle, NULL);
+}
+
+
+static void sv_connection_cb(uv_stream_t* server_handle, int status) {
+ handle_storage_t* storage;
+ struct server_ctx* ctx;
+
+ ctx = container_of(server_handle, struct server_ctx, server_handle);
+ ASSERT(status == 0);
+
+ storage = malloc(sizeof(*storage));
+ ASSERT(storage != NULL);
+
+ if (server_handle->type == UV_TCP)
+ ASSERT(0 == uv_tcp_init(server_handle->loop, (uv_tcp_t*) storage));
+ else if (server_handle->type == UV_NAMED_PIPE)
+ ASSERT(0 == uv_pipe_init(server_handle->loop, (uv_pipe_t*) storage, 0));
+ else
+ ASSERT(0);
+
+ ASSERT(0 == uv_accept(server_handle, (uv_stream_t*) storage));
+ ASSERT(0 == uv_read_start((uv_stream_t*) storage, sv_alloc_cb, sv_read_cb));
+ ctx->num_connects++;
+}
+
+
+static uv_buf_t sv_alloc_cb(uv_handle_t* handle, size_t suggested_size) {
+ static char buf[32];
+ return uv_buf_init(buf, sizeof(buf));
+}
+
+
+static void sv_read_cb(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
+ ASSERT(nread == -1);
+ ASSERT(uv_last_error(handle->loop).code == UV_EOF);
+ uv_close((uv_handle_t*) handle, (uv_close_cb) free);
+}
+
+
+static void cl_connect_cb(uv_connect_t* req, int status) {
+ struct client_ctx* ctx = container_of(req, struct client_ctx, connect_req);
+ uv_idle_start(&ctx->idle_handle, cl_idle_cb);
+ ASSERT(0 == status);
+}
+
+
+static void cl_idle_cb(uv_idle_t* handle, int status) {
+ struct client_ctx* ctx = container_of(handle, struct client_ctx, idle_handle);
+ uv_close((uv_handle_t*) &ctx->client_handle, cl_close_cb);
+ uv_idle_stop(&ctx->idle_handle);
+}
+
+
+static void cl_close_cb(uv_handle_t* handle) {
+ struct client_ctx* ctx;
+
+ ctx = container_of(handle, struct client_ctx, client_handle);
+
+ if (--ctx->num_connects == 0) {
+ uv_close((uv_handle_t*) &ctx->idle_handle, NULL);
+ return;
+ }
+
+ ASSERT(0 == uv_tcp_init(handle->loop, (uv_tcp_t*) &ctx->client_handle));
+ ASSERT(0 == uv_tcp_connect(&ctx->connect_req,
+ (uv_tcp_t*) &ctx->client_handle,
+ listen_addr,
+ cl_connect_cb));
+}
+
+
+static int test_tcp(unsigned int num_servers, unsigned int num_clients) {
+ struct server_ctx* servers;
+ struct client_ctx* clients;
+ uv_loop_t* loop;
+ uv_tcp_t* handle;
+ unsigned int i;
+ double time;
+
+ listen_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
+ loop = uv_default_loop();
+
+ servers = calloc(num_servers, sizeof(servers[0]));
+ clients = calloc(num_clients, sizeof(clients[0]));
+ ASSERT(servers != NULL);
+ ASSERT(clients != NULL);
+
+ /* We're making the assumption here that from the perspective of the
+ * OS scheduler, threads are functionally equivalent to and interchangeable
+ * with full-blown processes.
+ */
+ for (i = 0; i < num_servers; i++) {
+ struct server_ctx* ctx = servers + i;
+ ASSERT(0 == uv_sem_init(&ctx->semaphore, 0));
+ ASSERT(0 == uv_thread_create(&ctx->thread_id, server_cb, ctx));
+ }
+
+ send_listen_handles(UV_TCP, num_servers, servers);
+
+ for (i = 0; i < num_clients; i++) {
+ struct client_ctx* ctx = clients + i;
+ ctx->num_connects = NUM_CONNECTS / num_clients;
+ handle = (uv_tcp_t*) &ctx->client_handle;
+ handle->data = "client handle";
+ ASSERT(0 == uv_tcp_init(loop, handle));
+ ASSERT(0 == uv_tcp_connect(&ctx->connect_req,
+ handle,
+ listen_addr,
+ cl_connect_cb));
+ ASSERT(0 == uv_idle_init(loop, &ctx->idle_handle));
+ }
+
+ {
+ uint64_t t = uv_hrtime();
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ t = uv_hrtime() - t;
+ time = t / 1e9;
+ }
+
+ for (i = 0; i < num_servers; i++) {
+ struct server_ctx* ctx = servers + i;
+ uv_async_send(&ctx->async_handle);
+ ASSERT(0 == uv_thread_join(&ctx->thread_id));
+ uv_sem_destroy(&ctx->semaphore);
+ }
+
+ printf("accept%u: %.0f accepts/sec (%u total)\n",
+ num_servers,
+ NUM_CONNECTS / time,
+ NUM_CONNECTS);
+
+ for (i = 0; i < num_servers; i++) {
+ struct server_ctx* ctx = servers + i;
+ printf(" thread #%u: %.0f accepts/sec (%u total, %.1f%%)\n",
+ i,
+ ctx->num_connects / time,
+ ctx->num_connects,
+ ctx->num_connects * 100.0 / NUM_CONNECTS);
+ }
+
+ free(clients);
+ free(servers);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+BENCHMARK_IMPL(tcp_multi_accept2) {
+ return test_tcp(2, 40);
+}
+
+
+BENCHMARK_IMPL(tcp_multi_accept4) {
+ return test_tcp(4, 40);
+}
+
+
+BENCHMARK_IMPL(tcp_multi_accept8) {
+ return test_tcp(8, 40);
+}
diff --git a/deps/uv/test/benchmark-ping-pongs.c b/deps/uv/test/benchmark-ping-pongs.c
index d42e70630..8db7f963e 100644
--- a/deps/uv/test/benchmark-ping-pongs.c
+++ b/deps/uv/test/benchmark-ping-pongs.c
@@ -24,7 +24,6 @@
#include <stdlib.h>
#include <stdio.h>
-#include <string.h> /* strlen */
/* Run the benchmark for this many ms */
#define TIME 5000
@@ -103,8 +102,7 @@ static void pinger_write_ping(pinger_t* pinger) {
uv_write_t* req;
uv_buf_t buf;
- buf.base = (char*)&PING;
- buf.len = strlen(PING);
+ buf = uv_buf_init(PING, sizeof(PING) - 1);
req = malloc(sizeof *req);
if (uv_write(req, (uv_stream_t*) &pinger->tcp, &buf, 1, pinger_write_cb)) {
@@ -176,7 +174,7 @@ static void pinger_connect_cb(uv_connect_t* req, int status) {
}
-static void pinger_new() {
+static void pinger_new(void) {
int r;
struct sockaddr_in client_addr = uv_ip4_addr("0.0.0.0", 0);
struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
@@ -205,9 +203,10 @@ BENCHMARK_IMPL(ping_pongs) {
start_time = uv_now(loop);
pinger_new();
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(completed_pingers == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/benchmark-pound.c b/deps/uv/test/benchmark-pound.c
index 5c29a05b3..8669a14a2 100644
--- a/deps/uv/test/benchmark-pound.c
+++ b/deps/uv/test/benchmark-pound.c
@@ -287,7 +287,7 @@ static int pound_it(int concurrency,
r = do_connect(concurrency, make_connect, arg);
ASSERT(!r);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
end_time = uv_hrtime();
@@ -300,6 +300,7 @@ static int pound_it(int concurrency,
closed_streams / secs,
conns_failed);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/benchmark-pump.c b/deps/uv/test/benchmark-pump.c
index 52f295727..6d01229c7 100644
--- a/deps/uv/test/benchmark-pump.c
+++ b/deps/uv/test/benchmark-pump.c
@@ -117,7 +117,7 @@ static void show_stats(uv_timer_t* handle, int status) {
}
-static void read_show_stats() {
+static void read_show_stats(void) {
int64_t diff;
uv_update_time(loop);
@@ -129,13 +129,7 @@ static void read_show_stats() {
-void write_sockets_close_cb(uv_handle_t* handle) {
- /* If any client closes, the process is done. */
- exit(0);
-}
-
-
-void read_sockets_close_cb(uv_handle_t* handle) {
+static void read_sockets_close_cb(uv_handle_t* handle) {
free(handle);
read_sockets--;
@@ -149,7 +143,7 @@ void read_sockets_close_cb(uv_handle_t* handle) {
}
-static void start_stats_collection() {
+static void start_stats_collection(void) {
int r;
/* Show-stats timer */
@@ -203,11 +197,9 @@ static void do_write(uv_stream_t* stream) {
buf.base = (char*) &write_buffer;
buf.len = sizeof write_buffer;
- while (stream->write_queue_size == 0) {
- req = (uv_write_t*) req_alloc();
- r = uv_write(req, stream, &buf, 1, write_cb);
- ASSERT(r == 0);
- }
+ req = (uv_write_t*) req_alloc();
+ r = uv_write(req, stream, &buf, 1, write_cb);
+ ASSERT(r == 0);
}
@@ -233,7 +225,7 @@ static void connect_cb(uv_connect_t* req, int status) {
}
-static void maybe_connect_some() {
+static void maybe_connect_some(void) {
uv_connect_t* req;
uv_tcp_t* tcp;
uv_pipe_t* pipe;
@@ -304,7 +296,7 @@ typedef struct req_list_s {
static req_list_t* req_freelist = NULL;
-static uv_req_t* req_alloc() {
+static uv_req_t* req_alloc(void) {
req_list_t* req;
req = req_freelist;
@@ -381,7 +373,7 @@ HELPER_IMPL(tcp_pump_server) {
r = uv_listen((uv_stream_t*)&tcpServer, MAX_WRITE_HANDLES, connection_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
@@ -402,13 +394,14 @@ HELPER_IMPL(pipe_pump_server) {
r = uv_listen((uv_stream_t*)&pipeServer, MAX_WRITE_HANDLES, connection_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
-void tcp_pump(int n) {
+static void tcp_pump(int n) {
ASSERT(n <= MAX_WRITE_HANDLES);
TARGET_CONNECTIONS = n;
type = TCP;
@@ -420,11 +413,13 @@ void tcp_pump(int n) {
/* Start making connections */
maybe_connect_some();
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ MAKE_VALGRIND_HAPPY();
}
-void pipe_pump(int n) {
+static void pipe_pump(int n) {
ASSERT(n <= MAX_WRITE_HANDLES);
TARGET_CONNECTIONS = n;
type = PIPE;
@@ -434,7 +429,9 @@ void pipe_pump(int n) {
/* Start making connections */
maybe_connect_some();
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ MAKE_VALGRIND_HAPPY();
}
diff --git a/deps/uv/test/benchmark-spawn.c b/deps/uv/test/benchmark-spawn.c
index 74cc3d238..b95060641 100644
--- a/deps/uv/test/benchmark-spawn.c
+++ b/deps/uv/test/benchmark-spawn.c
@@ -30,7 +30,7 @@ static int N = 1000;
static int done;
static uv_process_t process;
-static uv_process_options_t options = { 0 };
+static uv_process_options_t options;
static char exepath[1024];
static size_t exepath_size = 1024;
static char* args[3];
@@ -44,10 +44,10 @@ static int process_open;
static int pipe_open;
-static void spawn();
+static void spawn(void);
-void maybe_spawn() {
+static void maybe_spawn(void) {
if (process_open == 0 && pipe_open == 0) {
done++;
if (done < N) {
@@ -71,7 +71,7 @@ static void exit_cb(uv_process_t* process, int exit_status, int term_signal) {
}
-uv_buf_t on_alloc(uv_handle_t* handle, size_t suggested_size) {
+static uv_buf_t on_alloc(uv_handle_t* handle, size_t suggested_size) {
uv_buf_t buf;
buf.base = output + output_used;
buf.len = OUTPUT_SIZE - output_used;
@@ -79,14 +79,14 @@ uv_buf_t on_alloc(uv_handle_t* handle, size_t suggested_size) {
}
-void pipe_close_cb(uv_handle_t* pipe) {
+static void pipe_close_cb(uv_handle_t* pipe) {
ASSERT(pipe_open == 1);
pipe_open = 0;
maybe_spawn();
}
-void on_read(uv_stream_t* pipe, ssize_t nread, uv_buf_t buf) {
+static void on_read(uv_stream_t* pipe, ssize_t nread, uv_buf_t buf) {
uv_err_t err = uv_last_error(loop);
if (nread > 0) {
@@ -100,7 +100,7 @@ void on_read(uv_stream_t* pipe, ssize_t nread, uv_buf_t buf) {
}
-static void spawn() {
+static void spawn(void) {
uv_stdio_container_t stdio[2];
int r;
@@ -149,7 +149,7 @@ BENCHMARK_IMPL(spawn) {
spawn();
- r = uv_run(loop);
+ r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
uv_update_time(loop);
@@ -158,5 +158,6 @@ BENCHMARK_IMPL(spawn) {
LOGF("spawn: %.0f spawns/s\n",
(double) N / (double) (end_time - start_time) * 1000.0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/benchmark-tcp-write-batch.c b/deps/uv/test/benchmark-tcp-write-batch.c
index 0b15f44b0..978cde0fd 100644
--- a/deps/uv/test/benchmark-tcp-write-batch.c
+++ b/deps/uv/test/benchmark-tcp-write-batch.c
@@ -122,7 +122,7 @@ BENCHMARK_IMPL(tcp_write_batch) {
start = uv_hrtime();
- r = uv_run(loop);
+ r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
stop = uv_hrtime();
@@ -134,7 +134,8 @@ BENCHMARK_IMPL(tcp_write_batch) {
printf("%ld write requests in %.2fs.\n",
(long)NUM_WRITE_REQS,
- (stop - start) / 10e8);
+ (stop - start) / 1e9);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/benchmark-udp-packet-storm.c b/deps/uv/test/benchmark-udp-packet-storm.c
deleted file mode 100644
index 594128705..000000000
--- a/deps/uv/test/benchmark-udp-packet-storm.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/* 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.
- */
-
-#include "task.h"
-#include "uv.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define EXPECTED "RANG TANG DING DONG I AM THE JAPANESE SANDMAN" /* "Take eight!" */
-
-#define TEST_DURATION 5000 /* ms */
-
-#define MAX_SENDERS 1000
-#define MAX_RECEIVERS 1000
-
-#define BASE_PORT 12345
-
-static uv_loop_t* loop;
-
-static int n_senders_;
-static int n_receivers_;
-static uv_udp_t senders[MAX_SENDERS];
-static uv_udp_t receivers[MAX_RECEIVERS];
-static uv_buf_t bufs[5];
-
-static int send_cb_called;
-static int recv_cb_called;
-static int close_cb_called;
-static int stopping = 0;
-
-typedef struct {
- struct sockaddr_in addr;
-} sender_state_t;
-
-
-static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
- static char slab[65536];
- ASSERT(suggested_size <= sizeof slab);
- return uv_buf_init(slab, sizeof slab);
-}
-
-
-static void send_cb(uv_udp_send_t* req, int status) {
- sender_state_t* ss;
- int r;
-
- if (stopping) {
- return;
- }
-
- ASSERT(req != NULL);
- ASSERT(status == 0);
-
- ss = req->data;
-
- r = uv_udp_send(req, req->handle, bufs, ARRAY_SIZE(bufs), ss->addr, send_cb);
- ASSERT(r == 0);
-
- req->data = ss;
-
- send_cb_called++;
-}
-
-
-static void recv_cb(uv_udp_t* handle,
- ssize_t nread,
- uv_buf_t buf,
- struct sockaddr* addr,
- unsigned flags) {
- if (nread == 0)
- return;
-
- if (nread == -1) {
- ASSERT(uv_last_error(loop).code == UV_EINTR); /* FIXME change error code */
- return;
- }
-
- ASSERT(addr->sa_family == AF_INET);
- ASSERT(!memcmp(buf.base, EXPECTED, nread));
-
- recv_cb_called++;
-}
-
-
-static void close_cb(uv_handle_t* handle) {
- ASSERT(handle != NULL);
- close_cb_called++;
-}
-
-
-static void timeout_cb(uv_timer_t* timer, int status) {
- int i;
-
- stopping = 1;
-
- for (i = 0; i < n_senders_; i++)
- uv_close((uv_handle_t*)&senders[i], close_cb);
-
- for (i = 0; i < n_receivers_; i++)
- uv_close((uv_handle_t*)&receivers[i], close_cb);
-}
-
-
-static int do_packet_storm(int n_senders, int n_receivers) {
- uv_timer_t timeout;
- sender_state_t *ss;
- uv_udp_send_t* req;
- uv_udp_t* handle;
- int i;
- int r;
-
- ASSERT(n_senders <= MAX_SENDERS);
- ASSERT(n_receivers <= MAX_RECEIVERS);
-
- loop = uv_default_loop();
-
- n_senders_ = n_senders;
- n_receivers_ = n_receivers;
-
- r = uv_timer_init(loop, &timeout);
- ASSERT(r == 0);
-
- r = uv_timer_start(&timeout, timeout_cb, TEST_DURATION, 0);
- ASSERT(r == 0);
-
- /* Timer should not keep loop alive. */
- uv_unref((uv_handle_t*)&timeout);
-
- for (i = 0; i < n_receivers; i++) {
- struct sockaddr_in addr;
- handle = &receivers[i];
-
- r = uv_udp_init(loop, handle);
- ASSERT(r == 0);
-
- addr = uv_ip4_addr("0.0.0.0", BASE_PORT + i);
-
- r = uv_udp_bind(handle, addr, 0);
- ASSERT(r == 0);
-
- r = uv_udp_recv_start(handle, alloc_cb, recv_cb);
- ASSERT(r == 0);
- }
-
- bufs[0] = uv_buf_init(EXPECTED + 0, 10);
- bufs[1] = uv_buf_init(EXPECTED + 10, 10);
- bufs[2] = uv_buf_init(EXPECTED + 20, 10);
- bufs[3] = uv_buf_init(EXPECTED + 30, 10);
- bufs[4] = uv_buf_init(EXPECTED + 40, 5);
-
- for (i = 0; i < n_senders; i++) {
- handle = &senders[i];
-
- r = uv_udp_init(loop, handle);
- ASSERT(r == 0);
-
- req = malloc(sizeof(*req) + sizeof(*ss));
-
- ss = (void*)(req + 1);
- ss->addr = uv_ip4_addr("127.0.0.1", BASE_PORT + (i % n_receivers));
-
- r = uv_udp_send(req, handle, bufs, ARRAY_SIZE(bufs), ss->addr, send_cb);
- ASSERT(r == 0);
-
- req->data = ss;
- }
-
- uv_run(loop);
-
- printf("udp_packet_storm_%dv%d: %.0f/s received, %.0f/s sent\n",
- n_receivers,
- n_senders,
- recv_cb_called / (TEST_DURATION / 1000.0),
- send_cb_called / (TEST_DURATION / 1000.0));
-
- return 0;
-}
-
-
-BENCHMARK_IMPL(udp_packet_storm_1v1) {
- return do_packet_storm(1, 1);
-}
-
-
-BENCHMARK_IMPL(udp_packet_storm_1v10) {
- return do_packet_storm(1, 10);
-}
-
-
-BENCHMARK_IMPL(udp_packet_storm_1v100) {
- return do_packet_storm(1, 100);
-}
-
-
-BENCHMARK_IMPL(udp_packet_storm_1v1000) {
- return do_packet_storm(1, 1000);
-}
-
-
-BENCHMARK_IMPL(udp_packet_storm_10v10) {
- return do_packet_storm(10, 10);
-}
-
-
-BENCHMARK_IMPL(udp_packet_storm_10v100) {
- return do_packet_storm(10, 100);
-}
-
-
-BENCHMARK_IMPL(udp_packet_storm_10v1000) {
- return do_packet_storm(10, 1000);
-}
-
-
-BENCHMARK_IMPL(udp_packet_storm_100v100) {
- return do_packet_storm(100, 100);
-}
-
-
-BENCHMARK_IMPL(udp_packet_storm_100v1000) {
- return do_packet_storm(100, 1000);
-}
-
-
-BENCHMARK_IMPL(udp_packet_storm_1000v1000) {
- return do_packet_storm(1000, 1000);
-}
diff --git a/deps/uv/test/benchmark-udp-pummel.c b/deps/uv/test/benchmark-udp-pummel.c
new file mode 100644
index 000000000..095745393
--- /dev/null
+++ b/deps/uv/test/benchmark-udp-pummel.c
@@ -0,0 +1,238 @@
+/* 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define EXPECTED "RANG TANG DING DONG I AM THE JAPANESE SANDMAN" /* "Take eight!" */
+
+#define TEST_DURATION 5000 /* ms */
+
+#define BASE_PORT 12345
+
+struct sender_state {
+ struct sockaddr_in addr;
+ uv_udp_send_t send_req;
+ uv_udp_t udp_handle;
+};
+
+struct receiver_state {
+ struct sockaddr_in addr;
+ uv_udp_t udp_handle;
+};
+
+/* not used in timed mode */
+static unsigned int packet_counter = (unsigned int) 1e6;
+
+static int n_senders_;
+static int n_receivers_;
+static uv_buf_t bufs[5];
+static struct sender_state senders[1024];
+static struct receiver_state receivers[1024];
+
+static unsigned int send_cb_called;
+static unsigned int recv_cb_called;
+static unsigned int close_cb_called;
+static int timed;
+static int exiting;
+
+
+static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
+ static char slab[65536];
+ ASSERT(suggested_size <= sizeof slab);
+ return uv_buf_init(slab, sizeof slab);
+}
+
+
+static void send_cb(uv_udp_send_t* req, int status) {
+ struct sender_state* s;
+
+ ASSERT(req != NULL);
+
+ if (status != 0) {
+ ASSERT(status == -1);
+ ASSERT(uv_last_error(req->handle->loop).code == UV_ECANCELED);
+ return;
+ }
+
+ if (exiting)
+ return;
+
+ s = container_of(req, struct sender_state, send_req);
+ ASSERT(req->handle == &s->udp_handle);
+
+ if (timed)
+ goto send;
+
+ if (packet_counter == 0) {
+ uv_close((uv_handle_t*)&s->udp_handle, NULL);
+ return;
+ }
+
+ packet_counter--;
+
+send:
+ ASSERT(0 == uv_udp_send(&s->send_req,
+ &s->udp_handle,
+ bufs,
+ ARRAY_SIZE(bufs),
+ s->addr,
+ send_cb));
+ send_cb_called++;
+}
+
+
+static void recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ uv_buf_t buf,
+ struct sockaddr* addr,
+ unsigned flags) {
+ if (nread == 0)
+ return;
+
+ if (nread == -1) {
+ ASSERT(uv_last_error(handle->loop).code == UV_ECANCELED);
+ return;
+ }
+
+ ASSERT(addr->sa_family == AF_INET);
+ ASSERT(!memcmp(buf.base, EXPECTED, nread));
+
+ recv_cb_called++;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void timeout_cb(uv_timer_t* timer, int status) {
+ int i;
+
+ exiting = 1;
+
+ for (i = 0; i < n_senders_; i++)
+ uv_close((uv_handle_t*)&senders[i].udp_handle, close_cb);
+
+ for (i = 0; i < n_receivers_; i++)
+ uv_close((uv_handle_t*)&receivers[i].udp_handle, close_cb);
+}
+
+
+static int pummel(unsigned int n_senders,
+ unsigned int n_receivers,
+ unsigned long timeout) {
+ uv_timer_t timer_handle;
+ uint64_t duration;
+ uv_loop_t* loop;
+ unsigned int i;
+
+ ASSERT(n_senders <= ARRAY_SIZE(senders));
+ ASSERT(n_receivers <= ARRAY_SIZE(receivers));
+
+ loop = uv_default_loop();
+
+ n_senders_ = n_senders;
+ n_receivers_ = n_receivers;
+
+ if (timeout) {
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timeout_cb, timeout, 0));
+ /* Timer should not keep loop alive. */
+ uv_unref((uv_handle_t*)&timer_handle);
+ timed = 1;
+ }
+
+ for (i = 0; i < n_receivers; i++) {
+ struct receiver_state* s = receivers + i;
+ struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", BASE_PORT + i);
+ ASSERT(0 == uv_udp_init(loop, &s->udp_handle));
+ ASSERT(0 == uv_udp_bind(&s->udp_handle, addr, 0));
+ ASSERT(0 == uv_udp_recv_start(&s->udp_handle, alloc_cb, recv_cb));
+ uv_unref((uv_handle_t*)&s->udp_handle);
+ }
+
+ bufs[0] = uv_buf_init(EXPECTED + 0, 10);
+ bufs[1] = uv_buf_init(EXPECTED + 10, 10);
+ bufs[2] = uv_buf_init(EXPECTED + 20, 10);
+ bufs[3] = uv_buf_init(EXPECTED + 30, 10);
+ bufs[4] = uv_buf_init(EXPECTED + 40, 5);
+
+ for (i = 0; i < n_senders; i++) {
+ struct sender_state* s = senders + i;
+ s->addr = uv_ip4_addr("127.0.0.1", BASE_PORT + (i % n_receivers));
+ ASSERT(0 == uv_udp_init(loop, &s->udp_handle));
+ ASSERT(0 == uv_udp_send(&s->send_req,
+ &s->udp_handle,
+ bufs,
+ ARRAY_SIZE(bufs),
+ s->addr,
+ send_cb));
+ }
+
+ duration = uv_hrtime();
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ duration = uv_hrtime() - duration;
+ /* convert from nanoseconds to milliseconds */
+ duration = duration / (uint64_t) 1e6;
+
+ printf("udp_pummel_%dv%d: %.0f/s received, %.0f/s sent. "
+ "%u received, %u sent in %.1f seconds.\n",
+ n_receivers,
+ n_senders,
+ recv_cb_called / (duration / 1000.0),
+ send_cb_called / (duration / 1000.0),
+ recv_cb_called,
+ send_cb_called,
+ duration / 1000.0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+#define X(a, b) \
+ BENCHMARK_IMPL(udp_pummel_##a##v##b) { \
+ return pummel(a, b, 0); \
+ } \
+ BENCHMARK_IMPL(udp_timed_pummel_##a##v##b) { \
+ return pummel(a, b, TEST_DURATION); \
+ }
+
+X(1, 1)
+X(1, 10)
+X(1, 100)
+X(1, 1000)
+X(10, 10)
+X(10, 100)
+X(10, 1000)
+X(100, 10)
+X(100, 100)
+X(100, 1000)
+X(1000, 1000)
+
+#undef X
diff --git a/deps/uv/test/blackhole-server.c b/deps/uv/test/blackhole-server.c
index 765bb3217..cbb936ff4 100644
--- a/deps/uv/test/blackhole-server.c
+++ b/deps/uv/test/blackhole-server.c
@@ -111,7 +111,7 @@ HELPER_IMPL(tcp4_blackhole_server) {
r = uv_listen((uv_stream_t*)&tcp_server, 128, connection_cb);
ASSERT(r == 0);
- r = uv_run(loop);
+ r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(0 && "Blackhole server dropped out of event loop.");
return 0;
diff --git a/deps/uv/test/dns-server.c b/deps/uv/test/dns-server.c
index d885f4c86..ba5327714 100644
--- a/deps/uv/test/dns-server.c
+++ b/deps/uv/test/dns-server.c
@@ -63,9 +63,18 @@ static void on_connection(uv_stream_t*, int status);
#define LEN_OFFSET 0
#define QUERYID_OFFSET 2
-unsigned char DNSRsp[] = {0, 43, 0, 0, 0x81, 0x80, 0, 1, 0, 1, 0, 0, 0, 0 };
-unsigned char qrecord[] = {5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1, 0, 1};
-unsigned char arecord[] = {0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1 };
+
+static unsigned char DNSRsp[] = {
+ 0, 43, 0, 0, 0x81, 0x80, 0, 1, 0, 1, 0, 0, 0, 0
+};
+
+static unsigned char qrecord[] = {
+ 5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1, 0, 1
+};
+
+static unsigned char arecord[] = {
+ 0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1
+};
static void after_write(uv_write_t* req, int status) {
@@ -153,7 +162,6 @@ static void process_req(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
hdrbuf_remaining = DNSREC_LEN - readbuf_remaining;
break;
} else {
- short int reclen_n;
/* save header */
memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], dnsreq, hdrbuf_remaining);
dnsreq += hdrbuf_remaining;
@@ -161,8 +169,8 @@ static void process_req(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
hdrbuf_remaining = 0;
/* get record length */
- reclen_n = *((short int*)hdrbuf);
- rec_remaining = ntohs(reclen_n) - (DNSREC_LEN - 2);
+ rec_remaining = (unsigned) hdrbuf[0] * 256 + (unsigned) hdrbuf[1];
+ rec_remaining -= (DNSREC_LEN - 2);
}
}
@@ -316,6 +324,6 @@ HELPER_IMPL(dns_server) {
if (dns_start(TEST_PORT_2))
return 1;
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
diff --git a/deps/uv/test/echo-server.c b/deps/uv/test/echo-server.c
index d663d605c..79263c7ae 100644
--- a/deps/uv/test/echo-server.c
+++ b/deps/uv/test/echo-server.c
@@ -47,18 +47,24 @@ static void on_connection(uv_stream_t*, int status);
static void after_write(uv_write_t* req, int status) {
write_req_t* wr;
-
- if (status) {
- uv_err_t err = uv_last_error(loop);
- fprintf(stderr, "uv_write error: %s\n", uv_strerror(err));
- ASSERT(0);
- }
-
- wr = (write_req_t*) req;
+ uv_err_t err;
/* Free the read/write buffer and the request */
+ wr = (write_req_t*) req;
free(wr->buf.base);
free(wr);
+
+ if (status == 0)
+ return;
+
+ err = uv_last_error(loop);
+ fprintf(stderr, "uv_write error: %s\n", uv_strerror(err));
+
+ if (err.code == UV_ECANCELED)
+ return;
+
+ ASSERT(err.code == UV_EPIPE);
+ uv_close((uv_handle_t*)req->handle, on_close);
}
@@ -340,7 +346,7 @@ HELPER_IMPL(tcp4_echo_server) {
if (tcp4_echo_start(TEST_PORT))
return 1;
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
@@ -351,7 +357,7 @@ HELPER_IMPL(tcp6_echo_server) {
if (tcp6_echo_start(TEST_PORT))
return 1;
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
@@ -362,7 +368,7 @@ HELPER_IMPL(pipe_echo_server) {
if (pipe_echo_start(TEST_PIPENAME))
return 1;
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
@@ -373,6 +379,6 @@ HELPER_IMPL(udp4_echo_server) {
if (udp4_echo_start(TEST_PORT))
return 1;
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
diff --git a/deps/uv/test/run-benchmarks.c b/deps/uv/test/run-benchmarks.c
index af11beb9b..06732b71d 100644
--- a/deps/uv/test/run-benchmarks.c
+++ b/deps/uv/test/run-benchmarks.c
@@ -60,5 +60,5 @@ static int maybe_run_test(int argc, char **argv) {
return 42;
}
- return run_test(argv[1], BENCHMARK_TIMEOUT, 1);
+ return run_test(argv[1], BENCHMARK_TIMEOUT, 1, 1);
}
diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c
index d0e64f05d..d84be6a1a 100644
--- a/deps/uv/test/run-tests.c
+++ b/deps/uv/test/run-tests.c
@@ -19,6 +19,7 @@
* IN THE SOFTWARE.
*/
+#include <errno.h>
#include <stdio.h>
#include <string.h>
@@ -99,7 +100,7 @@ static int maybe_run_test(int argc, char **argv) {
if (strcmp(argv[1], "spawn_helper3") == 0) {
char buffer[256];
- fgets(buffer, sizeof(buffer) - 1, stdin);
+ ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin));
buffer[sizeof(buffer) - 1] = '\0';
fputs(buffer, stdout);
return 1;
@@ -111,13 +112,20 @@ static int maybe_run_test(int argc, char **argv) {
}
if (strcmp(argv[1], "spawn_helper5") == 0) {
- const char* out = "fourth stdio!\n\0";
+ const char out[] = "fourth stdio!\n";
#ifdef _WIN32
DWORD bytes;
- WriteFile((HANDLE) _get_osfhandle(3), out, strlen(out), &bytes, NULL);
+ WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL);
#else
- write(3, out, strlen(out));
- fsync(3);
+ {
+ ssize_t r;
+
+ do
+ r = write(3, out, sizeof(out) - 1);
+ while (r == -1 && errno == EINTR);
+
+ fsync(3);
+ }
#endif
return 1;
}
@@ -147,5 +155,5 @@ static int maybe_run_test(int argc, char **argv) {
return 1;
}
- return run_test(argv[1], TEST_TIMEOUT, 0);
+ return run_test(argv[1], TEST_TIMEOUT, 0, 1);
}
diff --git a/deps/uv/test/runner-unix.c b/deps/uv/test/runner-unix.c
index d0ebfbf07..ebda5f8f1 100644
--- a/deps/uv/test/runner-unix.c
+++ b/deps/uv/test/runner-unix.c
@@ -24,6 +24,7 @@
#include <stdint.h> /* uintptr_t */
+#include <errno.h>
#include <unistd.h> /* usleep */
#include <string.h> /* strdup */
#include <stdio.h>
@@ -40,6 +41,17 @@
/* Do platform-specific initialization. */
void platform_init(int argc, char **argv) {
+ const char* var = getenv("UV_RUN_AS_ROOT");
+ const char* tap = getenv("UV_TAP_OUTPUT");
+
+ /* Running the tests as root is not smart - don't do it. */
+ if (getuid() == 0 && (var == NULL || atoi(var) <= 0)) {
+ fprintf(stderr, "Running the tests as root is not safe.\n");
+ exit(1);
+ }
+
+ tap_output = (tap != NULL && atoi(tap) > 0);
+
/* Disable stdio output buffering. */
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
@@ -50,8 +62,13 @@ void platform_init(int argc, char **argv) {
/* Invoke "argv[0] test-name [test-part]". Store process info in *p. */
/* Make sure that all stdio output of the processes is buffered up. */
-int process_start(char* name, char* part, process_info_t* p) {
- FILE* stdout_file = tmpfile();
+int process_start(char* name, char* part, process_info_t* p, int is_helper) {
+ FILE* stdout_file;
+ const char* arg;
+ char* args[16];
+ int n;
+
+ stdout_file = tmpfile();
if (!stdout_file) {
perror("tmpfile");
return -1;
@@ -63,17 +80,34 @@ int process_start(char* name, char* part, process_info_t* p) {
pid_t pid = fork();
if (pid < 0) {
- perror("vfork");
+ perror("fork");
return -1;
}
if (pid == 0) {
/* child */
+ arg = getenv("UV_USE_VALGRIND");
+ n = 0;
+
+ /* Disable valgrind for helpers, it complains about helpers leaking memory.
+ * They're killed after the test and as such never get a chance to clean up.
+ */
+ if (is_helper == 0 && arg != NULL && atoi(arg) != 0) {
+ args[n++] = "valgrind";
+ args[n++] = "--quiet";
+ args[n++] = "--leak-check=full";
+ args[n++] = "--show-reachable=yes";
+ args[n++] = "--error-exitcode=125";
+ }
+
+ args[n++] = executable_path;
+ args[n++] = name;
+ args[n++] = part;
+ args[n++] = NULL;
+
dup2(fileno(stdout_file), STDOUT_FILENO);
dup2(fileno(stdout_file), STDERR_FILENO);
-
- char* args[] = { executable_path, name, part, NULL };
- execvp(executable_path, args);
+ execvp(args[0], args);
perror("execvp()");
_exit(127);
}
@@ -116,8 +150,11 @@ static void* dowait(void* data) {
if (args->pipe[1] >= 0) {
/* Write a character to the main thread to notify it about this. */
- char c = 0;
- write(args->pipe[1], &c, 1);
+ ssize_t r;
+
+ do
+ r = write(args->pipe[1], "", 1);
+ while (r == -1 && errno == EINTR);
}
return NULL;
@@ -227,19 +264,26 @@ int process_copy_output(process_info_t *p, int fd) {
return -1;
}
- ssize_t nread, nwritten;
+ ssize_t nwritten;
char buf[1024];
- while ((nread = read(fileno(p->stdout_file), buf, 1024)) > 0) {
- nwritten = write(fd, buf, nread);
- /* TODO: what if write doesn't write the whole buffer... */
+ /* TODO: what if the line is longer than buf */
+ while (fgets(buf, sizeof(buf), p->stdout_file) != NULL) {
+ /* TODO: what if write doesn't write the whole buffer... */
+ nwritten = 0;
+
+ if (tap_output)
+ nwritten += write(fd, "#", 1);
+
+ nwritten += write(fd, buf, strlen(buf));
+
if (nwritten < 0) {
perror("write");
return -1;
}
}
- if (nread < 0) {
+ if (ferror(p->stdout_file)) {
perror("read");
return -1;
}
@@ -279,7 +323,7 @@ void process_cleanup(process_info_t *p) {
/* Move the console cursor one line up and back to the first column. */
-void rewind_cursor() {
+void rewind_cursor(void) {
fprintf(stderr, "\033[2K\r");
}
diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c
index 0a9690e77..8f534bcdb 100644
--- a/deps/uv/test/runner-win.c
+++ b/deps/uv/test/runner-win.c
@@ -24,9 +24,8 @@
#include <malloc.h>
#include <stdio.h>
#include <process.h>
-#include <windows.h>
#if !defined(__MINGW32__)
-#include <crtdbg.h>
+# include <crtdbg.h>
#endif
@@ -65,7 +64,7 @@ void platform_init(int argc, char **argv) {
}
-int process_start(char *name, char *part, process_info_t *p) {
+int process_start(char *name, char *part, process_info_t *p, int is_helper) {
HANDLE file = INVALID_HANDLE_VALUE;
HANDLE nul = INVALID_HANDLE_VALUE;
WCHAR path[MAX_PATH], filename[MAX_PATH];
@@ -111,8 +110,8 @@ int process_start(char *name, char *part, process_info_t *p) {
goto error;
if (part) {
- if (_snwprintf((wchar_t*)args,
- sizeof(args) / sizeof(wchar_t),
+ if (_snwprintf((WCHAR*)args,
+ sizeof(args) / sizeof(WCHAR),
L"\"%s\" %S %S",
image,
name,
@@ -120,8 +119,8 @@ int process_start(char *name, char *part, process_info_t *p) {
goto error;
}
} else {
- if (_snwprintf((wchar_t*)args,
- sizeof(args) / sizeof(wchar_t),
+ if (_snwprintf((WCHAR*)args,
+ sizeof(args) / sizeof(WCHAR),
L"\"%s\" %S",
image,
name) < 0) {
diff --git a/deps/uv/test/runner-win.h b/deps/uv/test/runner-win.h
index f69976e98..c94b89bd5 100644
--- a/deps/uv/test/runner-win.h
+++ b/deps/uv/test/runner-win.h
@@ -26,6 +26,7 @@
#pragma warning(disable : 4996)
+#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
diff --git a/deps/uv/test/runner.c b/deps/uv/test/runner.c
index 214c9a0dd..6e4b4f673 100644
--- a/deps/uv/test/runner.c
+++ b/deps/uv/test/runner.c
@@ -24,9 +24,12 @@
#include "runner.h"
#include "task.h"
+#include "uv.h"
char executable_path[PATHMAX] = { '\0' };
+int tap_output = 0;
+
static void log_progress(int total, int passed, int failed, const char* name) {
if (total == 0)
@@ -37,8 +40,45 @@ static void log_progress(int total, int passed, int failed, const char* name) {
}
+const char* fmt(double d) {
+ static char buf[1024];
+ static char* p;
+ uint64_t v;
+
+ if (p == NULL)
+ p = buf;
+
+ p += 31;
+
+ if (p >= buf + sizeof(buf))
+ return "<buffer too small>";
+
+ v = (uint64_t) d;
+
+#if 0 /* works but we don't care about fractional precision */
+ if (d - v >= 0.01) {
+ *--p = '0' + (uint64_t) (d * 100) % 10;
+ *--p = '0' + (uint64_t) (d * 10) % 10;
+ *--p = '.';
+ }
+#endif
+
+ if (v == 0)
+ *--p = '0';
+
+ while (v) {
+ if (v) *--p = '0' + (v % 10), v /= 10;
+ if (v) *--p = '0' + (v % 10), v /= 10;
+ if (v) *--p = '0' + (v % 10), v /= 10;
+ if (v) *--p = ',';
+ }
+
+ return p;
+}
+
+
int run_tests(int timeout, int benchmark_output) {
- int total, passed, failed;
+ int total, passed, failed, current;
task_entry_t* task;
/* Count the number of tests. */
@@ -49,29 +89,38 @@ int run_tests(int timeout, int benchmark_output) {
}
}
+ if (tap_output) {
+ LOGF("1..%d\n", total);
+ }
+
/* Run all tests. */
passed = 0;
failed = 0;
+ current = 1;
for (task = TASKS; task->main; task++) {
if (task->is_helper) {
continue;
}
- rewind_cursor();
- if (!benchmark_output) {
+ if (!tap_output)
+ rewind_cursor();
+
+ if (!benchmark_output && !tap_output) {
log_progress(total, passed, failed, task->task_name);
}
- if (run_test(task->task_name, timeout, benchmark_output) == 0) {
+ if (run_test(task->task_name, timeout, benchmark_output, current) == 0) {
passed++;
} else {
failed++;
}
+ current++;
}
- rewind_cursor();
+ if (!tap_output)
+ rewind_cursor();
- if (!benchmark_output) {
+ if (!benchmark_output && !tap_output) {
log_progress(total, passed, failed, "Done.\n");
}
@@ -79,7 +128,10 @@ int run_tests(int timeout, int benchmark_output) {
}
-int run_test(const char* test, int timeout, int benchmark_output) {
+int run_test(const char* test,
+ int timeout,
+ int benchmark_output,
+ int test_count) {
char errmsg[1024] = "no error";
process_info_t processes[1024];
process_info_t *main_proc;
@@ -118,7 +170,8 @@ int run_test(const char* test, int timeout, int benchmark_output) {
if (process_start(task->task_name,
task->process_name,
- &processes[process_count]) == -1) {
+ &processes[process_count],
+ 1 /* is_helper */) == -1) {
snprintf(errmsg,
sizeof errmsg,
"Process `%s` failed to start.",
@@ -144,7 +197,8 @@ int run_test(const char* test, int timeout, int benchmark_output) {
if (process_start(task->task_name,
task->process_name,
- &processes[process_count]) == -1) {
+ &processes[process_count],
+ 0 /* !is_helper */) == -1) {
snprintf(errmsg,
sizeof errmsg,
"Process `%s` failed to start.",
@@ -203,7 +257,9 @@ out:
/* Show error and output from processes if the test failed. */
if (status != 0 || task->show_output) {
- if (status != 0) {
+ if (tap_output) {
+ LOGF("not ok %d - %s\n#", test_count, test);
+ } else if (status != 0) {
LOGF("\n`%s` failed: %s\n", test, errmsg);
} else {
LOGF("\n");
@@ -227,7 +283,10 @@ out:
break;
}
}
- LOG("=============================================================\n");
+
+ if (!tap_output) {
+ LOG("=============================================================\n");
+ }
/* In benchmark mode show concise output from the main process. */
} else if (benchmark_output) {
@@ -246,6 +305,8 @@ out:
}
break;
}
+ } else if (tap_output) {
+ LOGF("ok %d - %s\n", test_count, test);
}
/* Clean up all process handles. */
@@ -262,11 +323,13 @@ out:
*/
int run_test_part(const char* test, const char* part) {
task_entry_t* task;
+ int r;
for (task = TASKS; task->main; task++) {
- if (strcmp(test, task->task_name) == 0
- && strcmp(part, task->process_name) == 0) {
- return task->main();
+ if (strcmp(test, task->task_name) == 0 &&
+ strcmp(part, task->process_name) == 0) {
+ r = task->main();
+ return r;
}
}
diff --git a/deps/uv/test/runner.h b/deps/uv/test/runner.h
index 5cee695ed..8be9e39fc 100644
--- a/deps/uv/test/runner.h
+++ b/deps/uv/test/runner.h
@@ -38,7 +38,7 @@
typedef struct {
char *task_name;
char *process_name;
- int (*main)();
+ int (*main)(void);
int is_helper;
int show_output;
} task_entry_t, bench_entry_t;
@@ -51,11 +51,11 @@ typedef struct {
task_entry_t TASKS[] = {
#define TASK_LIST_END \
- { 0, 0, 0, 0 } \
+ { 0, 0, 0, 0, 0 } \
};
#define TEST_DECLARE(name) \
- int run_test_##name();
+ int run_test_##name(void);
#define TEST_ENTRY(name) \
{ #name, #name, &run_test_##name, 0, 0 },
@@ -64,13 +64,13 @@ typedef struct {
{ #name, #name, &run_test_##name, 0, 1 },
#define BENCHMARK_DECLARE(name) \
- int run_benchmark_##name();
+ int run_benchmark_##name(void);
#define BENCHMARK_ENTRY(name) \
{ #name, #name, &run_benchmark_##name, 0, 0 },
#define HELPER_DECLARE(name) \
- int run_helper_##name();
+ int run_helper_##name(void);
#define HELPER_ENTRY(task_name, name) \
{ #task_name, #name, &run_helper_##name, 1, 0 },
@@ -102,7 +102,10 @@ int run_tests(int timeout, int benchmark_output);
/*
* Run a single test. Starts up any helpers.
*/
-int run_test(const char* test, int timeout, int benchmark_output);
+int run_test(const char* test,
+ int timeout,
+ int benchmark_output,
+ int test_count);
/*
* Run a test part, i.e. the test or one of its helpers.
@@ -123,11 +126,11 @@ void print_tests(FILE* stream);
*/
/* Do platform-specific initialization. */
-void platform_init();
+void platform_init(int argc, char** argv);
/* Invoke "argv[0] test-name [test-part]". Store process info in *p. */
/* Make sure that all stdio output of the processes is buffered up. */
-int process_start(char *name, char* part, process_info_t *p);
+int process_start(char *name, char* part, process_info_t *p, int is_helper);
/* Wait for all `n` processes in `vec` to terminate. */
/* Time out after `timeout` msec, or never if timeout == -1 */
@@ -154,6 +157,9 @@ int process_reap(process_info_t *p);
void process_cleanup(process_info_t *p);
/* Move the console cursor one line up and back to the first column. */
-void rewind_cursor();
+void rewind_cursor(void);
+
+/* trigger output as tap */
+extern int tap_output;
#endif /* RUNNER_H_ */
diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h
index 04497342f..de7c80ec3 100644
--- a/deps/uv/test/task.h
+++ b/deps/uv/test/task.h
@@ -24,9 +24,14 @@
#include <stdio.h>
#include <stddef.h>
-#include <stdint.h>
#include <stdlib.h>
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
#define TEST_PORT 9123
#define TEST_PORT_2 9124
@@ -74,8 +79,6 @@ typedef enum {
abort(); \
} while (0)
-
-
/* Have our own assert, so we are sure it does not get optimized away in
* a release build.
*/
@@ -91,19 +94,29 @@ typedef enum {
} \
} while (0)
+/* This macro cleans up the main loop. This is used to avoid valgrind
+ * warnings about memory being "leaked" by the main event loop.
+ */
+#define MAKE_VALGRIND_HAPPY() \
+ uv_loop_delete(uv_default_loop())
/* Just sugar for wrapping the main() for a task or helper. */
-#define TEST_IMPL(name) \
- int run_test_##name()
+#define TEST_IMPL(name) \
+ int run_test_##name(void); \
+ int run_test_##name(void)
-#define BENCHMARK_IMPL(name) \
- int run_benchmark_##name()
-
-#define HELPER_IMPL(name) \
- int run_helper_##name()
+#define BENCHMARK_IMPL(name) \
+ int run_benchmark_##name(void); \
+ int run_benchmark_##name(void)
+#define HELPER_IMPL(name) \
+ int run_helper_##name(void); \
+ int run_helper_##name(void)
/* Pause the calling thread for a number of milliseconds. */
void uv_sleep(int msec);
+/* Format big numbers nicely. WARNING: leaks memory. */
+const char* fmt(double d);
+
#endif /* TASK_H_ */
diff --git a/deps/uv/test/test-active.c b/deps/uv/test/test-active.c
new file mode 100644
index 000000000..1f3d5f1b1
--- /dev/null
+++ b/deps/uv/test/test-active.c
@@ -0,0 +1,83 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static int close_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(0 && "timer_cb should not have been called");
+}
+
+
+TEST_IMPL(active) {
+ int r;
+ uv_timer_t timer;
+
+ r = uv_timer_init(uv_default_loop(), &timer);
+ ASSERT(r == 0);
+
+ ASSERT(!uv_is_active((uv_handle_t*) &timer));
+ ASSERT(!uv_is_closing((uv_handle_t*) &timer));
+
+ r = uv_timer_start(&timer, timer_cb, 1000, 0);
+ ASSERT(r == 0);
+
+ ASSERT(uv_is_active((uv_handle_t*) &timer));
+ ASSERT(!uv_is_closing((uv_handle_t*) &timer));
+
+ r = uv_timer_stop(&timer);
+ ASSERT(r == 0);
+
+ ASSERT(!uv_is_active((uv_handle_t*) &timer));
+ ASSERT(!uv_is_closing((uv_handle_t*) &timer));
+
+ r = uv_timer_start(&timer, timer_cb, 1000, 0);
+ ASSERT(r == 0);
+
+ ASSERT(uv_is_active((uv_handle_t*) &timer));
+ ASSERT(!uv_is_closing((uv_handle_t*) &timer));
+
+ uv_close((uv_handle_t*) &timer, close_cb);
+
+ ASSERT(!uv_is_active((uv_handle_t*) &timer));
+ ASSERT(uv_is_closing((uv_handle_t*) &timer));
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-async.c b/deps/uv/test/test-async.c
index 7cdad0983..d4d94d5fa 100644
--- a/deps/uv/test/test-async.c
+++ b/deps/uv/test/test-async.c
@@ -35,7 +35,7 @@ static int prepare_cb_called;
static int close_cb_called;
-void thread_cb(void *arg) {
+static void thread_cb(void *arg) {
int n;
int r;
@@ -50,6 +50,21 @@ void thread_cb(void *arg) {
r = uv_async_send(&async);
ASSERT(r == 0);
+
+ /* Work around a bug in Valgrind.
+ *
+ * Valgrind runs threads not in parallel but sequentially, i.e. one after
+ * the other. It also doesn't preempt them, instead it depends on threads
+ * yielding voluntarily by making a syscall.
+ *
+ * That never happens here: the pipe that is associated with the async
+ * handle is written to once but that's too early for Valgrind's scheduler
+ * to kick in. Afterwards, the thread busy-loops, starving the main thread.
+ * Therefore, we yield.
+ *
+ * This behavior has been observed with Valgrind 3.7.0 and 3.9.0.
+ */
+ uv_sleep(0);
}
}
@@ -107,12 +122,15 @@ TEST_IMPL(async) {
r = uv_async_init(uv_default_loop(), &async, async_cb);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(prepare_cb_called > 0);
ASSERT(async_cb_called == 3);
ASSERT(close_cb_called == 2);
+ ASSERT(0 == uv_thread_join(&thread));
+
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-barrier.c b/deps/uv/test/test-barrier.c
new file mode 100644
index 000000000..97df704c0
--- /dev/null
+++ b/deps/uv/test/test-barrier.c
@@ -0,0 +1,98 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <string.h>
+#include <errno.h>
+
+typedef struct {
+ uv_barrier_t barrier;
+ int delay;
+ volatile int posted;
+} worker_config;
+
+
+static void worker(void* arg) {
+ worker_config* c = arg;
+
+ if (c->delay)
+ uv_sleep(c->delay);
+
+ uv_barrier_wait(&c->barrier);
+}
+
+
+TEST_IMPL(barrier_1) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+
+ ASSERT(0 == uv_barrier_init(&wc.barrier, 2));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_sleep(100);
+ uv_barrier_wait(&wc.barrier);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_barrier_destroy(&wc.barrier);
+
+ return 0;
+}
+
+
+TEST_IMPL(barrier_2) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.delay = 100;
+
+ ASSERT(0 == uv_barrier_init(&wc.barrier, 2));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_barrier_wait(&wc.barrier);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_barrier_destroy(&wc.barrier);
+
+ return 0;
+}
+
+
+TEST_IMPL(barrier_3) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+
+ ASSERT(0 == uv_barrier_init(&wc.barrier, 2));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_barrier_wait(&wc.barrier);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_barrier_destroy(&wc.barrier);
+
+ return 0;
+}
diff --git a/deps/uv/test/test-callback-order.c b/deps/uv/test/test-callback-order.c
index a6c40cbdf..84231e1b6 100644
--- a/deps/uv/test/test-callback-order.c
+++ b/deps/uv/test/test-callback-order.c
@@ -67,10 +67,11 @@ TEST_IMPL(callback_order) {
ASSERT(idle_cb_called == 0);
ASSERT(timer_cb_called == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(idle_cb_called == 1);
ASSERT(timer_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-callback-stack.c b/deps/uv/test/test-callback-stack.c
index 4983b651c..e8cfcb431 100644
--- a/deps/uv/test/test-callback-stack.c
+++ b/deps/uv/test/test-callback-stack.c
@@ -189,7 +189,7 @@ TEST_IMPL(callback_stack) {
}
nested--;
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(nested == 0);
ASSERT(connect_cb_called == 1 && "connect_cb must be called exactly once");
@@ -199,5 +199,6 @@ TEST_IMPL(callback_stack) {
ASSERT(shutdown_cb_called == 1 && "shutdown_cb must be called exactly once");
ASSERT(close_cb_called == 2 && "close_cb must be called exactly twice");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-condvar.c b/deps/uv/test/test-condvar.c
new file mode 100644
index 000000000..065dd4ec6
--- /dev/null
+++ b/deps/uv/test/test-condvar.c
@@ -0,0 +1,173 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <string.h>
+#include <errno.h>
+
+typedef struct {
+ uv_mutex_t mutex;
+ uv_cond_t cond;
+ int delay;
+ int use_broadcast;
+ volatile int posted;
+} worker_config;
+
+
+static void worker(void* arg) {
+ worker_config* c = arg;
+
+ if (c->delay)
+ uv_sleep(c->delay);
+
+ uv_mutex_lock(&c->mutex);
+ ASSERT(c->posted == 0);
+ c->posted = 1;
+ if (c->use_broadcast)
+ uv_cond_broadcast(&c->cond);
+ else
+ uv_cond_signal(&c->cond);
+ uv_mutex_unlock(&c->mutex);
+}
+
+
+TEST_IMPL(condvar_1) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+
+ ASSERT(0 == uv_cond_init(&wc.cond));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_mutex_lock(&wc.mutex);
+ uv_sleep(100);
+ uv_cond_wait(&wc.cond, &wc.mutex);
+ ASSERT(wc.posted == 1);
+ uv_mutex_unlock(&wc.mutex);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_cond_destroy(&wc.cond);
+
+ return 0;
+}
+
+
+TEST_IMPL(condvar_2) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.delay = 100;
+
+ ASSERT(0 == uv_cond_init(&wc.cond));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_mutex_lock(&wc.mutex);
+ uv_cond_wait(&wc.cond, &wc.mutex);
+ uv_mutex_unlock(&wc.mutex);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_cond_destroy(&wc.cond);
+
+ return 0;
+}
+
+
+TEST_IMPL(condvar_3) {
+ uv_thread_t thread;
+ worker_config wc;
+ int r;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.delay = 100;
+
+ ASSERT(0 == uv_cond_init(&wc.cond));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_mutex_lock(&wc.mutex);
+ r = uv_cond_timedwait(&wc.cond, &wc.mutex, (uint64_t)(50 * 1e6));
+ ASSERT(r == -1);
+ uv_mutex_unlock(&wc.mutex);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_cond_destroy(&wc.cond);
+
+ return 0;
+}
+
+
+TEST_IMPL(condvar_4) {
+ uv_thread_t thread;
+ worker_config wc;
+ int r;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.delay = 100;
+
+ ASSERT(0 == uv_cond_init(&wc.cond));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_mutex_lock(&wc.mutex);
+ r = uv_cond_timedwait(&wc.cond, &wc.mutex, (uint64_t)(150 * 1e6));
+ ASSERT(r == 0);
+ uv_mutex_unlock(&wc.mutex);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_cond_destroy(&wc.cond);
+
+ return 0;
+}
+
+
+TEST_IMPL(condvar_5) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.use_broadcast = 1;
+
+ ASSERT(0 == uv_cond_init(&wc.cond));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_mutex_lock(&wc.mutex);
+ uv_sleep(100);
+ uv_cond_wait(&wc.cond, &wc.mutex);
+ ASSERT(wc.posted == 1);
+ uv_mutex_unlock(&wc.mutex);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_cond_destroy(&wc.cond);
+
+ return 0;
+}
diff --git a/deps/uv/test/test-connection-fail.c b/deps/uv/test/test-connection-fail.c
index 1c5a31d12..e72b4e591 100644
--- a/deps/uv/test/test-connection-fail.c
+++ b/deps/uv/test/test-connection-fail.c
@@ -88,7 +88,7 @@ static void on_connect_without_close(uv_connect_t *req, int status) {
}
-void connection_fail(uv_connect_cb connect_cb) {
+static void connection_fail(uv_connect_cb connect_cb) {
struct sockaddr_in client_addr, server_addr;
int r;
@@ -107,7 +107,7 @@ void connection_fail(uv_connect_cb connect_cb) {
r = uv_tcp_connect(&req, &tcp, server_addr, connect_cb);
ASSERT(!r);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(connect_cb_calls == 1);
ASSERT(close_cb_calls == 1);
@@ -124,6 +124,7 @@ TEST_IMPL(connection_fail) {
ASSERT(timer_close_cb_calls == 0);
ASSERT(timer_cb_calls == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -144,5 +145,6 @@ TEST_IMPL(connection_fail_doesnt_auto_close) {
ASSERT(timer_close_cb_calls == 1);
ASSERT(timer_cb_calls == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-counters-init.c b/deps/uv/test/test-counters-init.c
deleted file mode 100644
index 631868424..000000000
--- a/deps/uv/test/test-counters-init.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* 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.
- */
-#define UNIX (defined(__unix__) || defined(__POSIX__) || defined(__APPLE__))
-#include "task.h"
-#include "uv.h"
-#include <fcntl.h>
-
-#if UNIX
-#include <unistd.h> /* unlink, rmdir, etc. */
-#else
-# include <direct.h>
-# include <io.h>
-# define unlink _unlink
-# define rmdir _rmdir
-# define stat _stati64
-# define open _open
-# define write _write
-# define lseek _lseek
-# define close _close
-#endif
-
-static char exepath[1024];
-static size_t exepath_size = 1024;
-static char* args[3];
-static uv_fs_t open_req;
-static uv_tcp_t tcp;
-static uv_udp_t udp;
-static uv_pipe_t uvpipe;
-static uv_tty_t tty;
-static uv_prepare_t prepare;
-static uv_check_t check;
-static uv_idle_t idle;
-static uv_async_t async;
-static uv_timer_t timer;
-static uv_fs_event_t fs_event;
-static uv_process_t process;
-static uv_process_options_t options;
-static uv_fs_t fs_req;
-
-static void exit_cb(uv_process_t* process, int exit_status, int term_signal) {
- ASSERT(exit_status == 1);
- ASSERT(term_signal == 0);
- uv_close((uv_handle_t*)process, NULL);
-}
-
-static void init_process_options(char* test, uv_exit_cb exit_cb) {
- int r = uv_exepath(exepath, &exepath_size);
- ASSERT(r == 0);
- exepath[exepath_size] = '\0';
- args[0] = exepath;
- args[1] = test;
- args[2] = NULL;
- options.file = exepath;
- options.args = args;
- options.exit_cb = exit_cb;
-}
-
-static void create_dir(uv_loop_t* loop, const char* name) {
- int r;
- uv_fs_t req;
- r = uv_fs_rmdir(loop, &req, name, NULL);
- r = uv_fs_mkdir(loop, &req, name, 0755, NULL);
- ASSERT(r == 0 || uv_last_error(loop).code == UV_EEXIST);
- uv_fs_req_cleanup(&req);
-}
-
-static void create_cb(uv_fs_t* req) {
- ASSERT(req == &open_req);
- ASSERT(req->fs_type == UV_FS_OPEN);
- ASSERT(req->result != -1);
- uv_fs_req_cleanup(req);
- unlink("test_file");
-}
-
-TEST_IMPL(counters_init) {
- int r;
- uint64_t eio_init_prev;
- uint64_t req_init_prev;
- uint64_t handle_init_prev;
- uint64_t stream_init_prev;
- uint64_t tcp_init_prev;
- uint64_t udp_init_prev;
- uint64_t pipe_init_prev;
- uint64_t tty_init_prev;
- uint64_t prepare_init_prev;
- uint64_t check_init_prev;
- uint64_t idle_init_prev;
- uint64_t async_init_prev;
- uint64_t timer_init_prev;
- uint64_t process_init_prev;
- uint64_t fs_event_init_prev;
-
- /* req_init and eio_init test by uv_fs_open() */
- unlink("test_file");
- req_init_prev = uv_default_loop()->counters.req_init;
- eio_init_prev = uv_default_loop()->counters.eio_init;
- r = uv_fs_open(uv_default_loop(), &open_req, "test_file", O_WRONLY | O_CREAT,
- S_IREAD | S_IWRITE, create_cb);
- ASSERT(r == 0);
- ASSERT(open_req.result == 0);
- ASSERT(uv_default_loop()->counters.req_init == ++req_init_prev);
-#ifndef _WIN32
- ASSERT(uv_default_loop()->counters.eio_init == ++eio_init_prev);
-#endif
-
- /* tcp_init, stream_init and handle_init test by uv_tcp_init() */
- tcp_init_prev = uv_default_loop()->counters.tcp_init;
- stream_init_prev = uv_default_loop()->counters.stream_init;
- handle_init_prev = uv_default_loop()->counters.handle_init;
- r = uv_tcp_init(uv_default_loop(), &tcp);
- ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.tcp_init == ++tcp_init_prev);
- ASSERT(uv_default_loop()->counters.stream_init == ++stream_init_prev);
- ASSERT(uv_default_loop()->counters.handle_init == ++handle_init_prev);
- uv_close((uv_handle_t*)&tcp, NULL);
-
- /* udp_init test by uv_udp_init() */
- udp_init_prev = uv_default_loop()->counters.udp_init;
- r = uv_udp_init(uv_default_loop(), &udp);
- ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.udp_init == ++udp_init_prev);
- uv_close((uv_handle_t*)&udp, NULL);
-
- /* pipe_init uv_pipe_init() */
- pipe_init_prev = uv_default_loop()->counters.pipe_init;
- uv_pipe_init(uv_default_loop(), &uvpipe, 0);
- ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.pipe_init == ++pipe_init_prev);
- uv_close((uv_handle_t*)&uvpipe, NULL);
-
- /* tty_init test by uv_tty_init()*/
- tty_init_prev = uv_default_loop()->counters.tty_init;
- r = uv_tty_init(uv_default_loop(), &tty, 1, 0);
- /* uv_tty_init() always returns -1 in run_test in Windows
- so that we avoid to check return value.
- */
-#ifndef _WIN32
- ASSERT(r == 0);
- uv_close((uv_handle_t*)&tty, NULL);
-#endif
- ASSERT(uv_default_loop()->counters.tty_init == ++tty_init_prev);
-
- /* prepare_init test by uv_prepare_init() */
- prepare_init_prev = uv_default_loop()->counters.prepare_init;
- r = uv_prepare_init(uv_default_loop(), &prepare);
- ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.prepare_init == ++prepare_init_prev);
- uv_close((uv_handle_t*)&prepare, NULL);
-
- /* check_init test by uv_check_init() */
- check_init_prev = uv_default_loop()->counters.check_init;
- r = uv_check_init(uv_default_loop(), &check);
- ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.check_init == ++check_init_prev);
- uv_close((uv_handle_t*)&check, NULL);
-
- /* idle_init test by uv_idle_init() */
- idle_init_prev = uv_default_loop()->counters.idle_init;
- r = uv_idle_init(uv_default_loop(), &idle);
- ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.idle_init == ++idle_init_prev);
- uv_close((uv_handle_t*)&idle, NULL);
-
- /* async_init test by uv_async_init() */
- async_init_prev = uv_default_loop()->counters.async_init;
- r = uv_async_init(uv_default_loop(), &async, NULL);
- ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.async_init == ++async_init_prev);
- uv_close((uv_handle_t*)&async, NULL);
-
- /* timer_init test by uv_timer_init() */
- timer_init_prev = uv_default_loop()->counters.timer_init;
- r = uv_timer_init(uv_default_loop(), &timer);
- ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.timer_init == ++timer_init_prev);
- uv_close((uv_handle_t*)&timer, NULL);
-
- /* process_init test by uv_spawn() */
- process_init_prev = uv_default_loop()->counters.process_init;
- init_process_options("spawn_helper1", exit_cb);
- r = uv_spawn(uv_default_loop(), &process, options);
- ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.process_init == ++process_init_prev);
- r = uv_run(uv_default_loop());
- ASSERT(r == 0);
-
- /* fs_event_init test by uv_fs_event_init() */
- create_dir(uv_default_loop(), "watch_dir");
- fs_event_init_prev = uv_default_loop()->counters.fs_event_init;
- r = uv_fs_event_init(uv_default_loop(), &fs_event, "watch_dir", NULL, 0);
- ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.fs_event_init == ++fs_event_init_prev);
- uv_fs_rmdir(uv_default_loop(), &fs_req, "watch_dir", NULL);
- uv_fs_req_cleanup(&fs_req);
-
- return 0;
-}
diff --git a/deps/uv/test/test-delayed-accept.c b/deps/uv/test/test-delayed-accept.c
index 990444ef3..b15d88195 100644
--- a/deps/uv/test/test-delayed-accept.c
+++ b/deps/uv/test/test-delayed-accept.c
@@ -50,7 +50,6 @@ static void close_cb(uv_handle_t* handle) {
static void do_accept(uv_timer_t* timer_handle, int status) {
uv_tcp_t* server;
uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle);
- uint64_t tcpcnt;
int r;
ASSERT(timer_handle != NULL);
@@ -60,15 +59,10 @@ static void do_accept(uv_timer_t* timer_handle, int status) {
r = uv_tcp_init(uv_default_loop(), accepted_handle);
ASSERT(r == 0);
- /* Test to that uv_default_loop()->counters.tcp_init does not increase across the uv_accept. */
- tcpcnt = uv_default_loop()->counters.tcp_init;
-
server = (uv_tcp_t*)timer_handle->data;
r = uv_accept((uv_stream_t*)server, (uv_stream_t*)accepted_handle);
ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.tcp_init == tcpcnt);
-
do_accept_called++;
/* Immediately close the accepted handle. */
@@ -106,7 +100,7 @@ static void connection_cb(uv_stream_t* tcp, int status) {
}
-static void start_server() {
+static void start_server(void) {
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
uv_tcp_t* server = (uv_tcp_t*)malloc(sizeof *server);
int r;
@@ -115,9 +109,6 @@ static void start_server() {
r = uv_tcp_init(uv_default_loop(), server);
ASSERT(r == 0);
- ASSERT(uv_default_loop()->counters.tcp_init == 1);
- ASSERT(uv_default_loop()->counters.handle_init == 1);
-
r = uv_tcp_bind(server, addr);
ASSERT(r == 0);
@@ -162,7 +153,7 @@ static void connect_cb(uv_connect_t* req, int status) {
}
-static void client_connect() {
+static void client_connect(void) {
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client);
uv_connect_t* connect_req = malloc(sizeof *connect_req);
@@ -186,12 +177,13 @@ TEST_IMPL(delayed_accept) {
client_connect();
client_connect();
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(connection_cb_called == 2);
ASSERT(do_accept_called == 2);
ASSERT(connect_cb_called == 2);
ASSERT(close_cb_called == 7);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-embed.c b/deps/uv/test/test-embed.c
new file mode 100644
index 000000000..7f485d1ae
--- /dev/null
+++ b/deps/uv/test/test-embed.c
@@ -0,0 +1,136 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#ifndef HAVE_KQUEUE
+# if defined(__APPLE__) || \
+ defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__)
+# define HAVE_KQUEUE 1
+# endif
+#endif
+
+#ifndef HAVE_EPOLL
+# if defined(__linux__)
+# define HAVE_EPOLL 1
+# endif
+#endif
+
+#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
+
+#if defined(HAVE_KQUEUE)
+# include <sys/types.h>
+# include <sys/event.h>
+# include <sys/time.h>
+#endif
+
+#if defined(HAVE_EPOLL)
+# include <sys/epoll.h>
+#endif
+
+static uv_thread_t embed_thread;
+static uv_sem_t embed_sem;
+static uv_timer_t embed_timer;
+static uv_async_t embed_async;
+static volatile int embed_closed;
+
+static int embed_timer_called;
+
+
+static void embed_thread_runner(void* arg) {
+ int r;
+ int fd;
+ int timeout;
+
+ while (!embed_closed) {
+ fd = uv_backend_fd(uv_default_loop());
+ timeout = uv_backend_timeout(uv_default_loop());
+
+ do {
+#if defined(HAVE_KQUEUE)
+ struct timespec ts;
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000000;
+ r = kevent(fd, NULL, 0, NULL, 0, &ts);
+#elif defined(HAVE_EPOLL)
+ r = epoll_wait(fd, NULL, 0, timeout);
+#endif
+ } while (r == -1 && errno == EINTR);
+ uv_async_send(&embed_async);
+ uv_sem_wait(&embed_sem);
+ }
+}
+
+
+static void embed_cb(uv_async_t* async, int status) {
+ uv_run(uv_default_loop(), UV_RUN_ONCE);
+
+ uv_sem_post(&embed_sem);
+}
+
+
+static void embed_timer_cb(uv_timer_t* timer, int status) {
+ embed_timer_called++;
+ embed_closed = 1;
+
+ uv_close((uv_handle_t*) &embed_async, NULL);
+}
+#endif
+
+
+TEST_IMPL(embed) {
+#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
+ uv_loop_t* external;
+
+ external = uv_loop_new();
+ ASSERT(external != NULL);
+
+ embed_timer_called = 0;
+ embed_closed = 0;
+
+ uv_async_init(external, &embed_async, embed_cb);
+
+ /* Start timer in default loop */
+ uv_timer_init(uv_default_loop(), &embed_timer);
+ uv_timer_start(&embed_timer, embed_timer_cb, 250, 0);
+
+ /* Start worker that will interrupt external loop */
+ uv_sem_init(&embed_sem, 0);
+ uv_thread_create(&embed_thread, embed_thread_runner, NULL);
+
+ /* But run external loop */
+ uv_run(external, UV_RUN_DEFAULT);
+
+ uv_thread_join(&embed_thread);
+ uv_loop_delete(external);
+
+ ASSERT(embed_timer_called == 1);
+#endif
+
+ return 0;
+}
diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c
index 47a53bd3b..37f9cf2e3 100644
--- a/deps/uv/test/test-fs-event.c
+++ b/deps/uv/test/test-fs-event.c
@@ -26,7 +26,11 @@
#include <fcntl.h>
#ifndef HAVE_KQUEUE
-# if __APPLE__ || __FreeBSD__ || __OpenBSD__ || __NetBSD__
+# if defined(__APPLE__) || \
+ defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__)
# define HAVE_KQUEUE 1
# endif
#endif
@@ -112,7 +116,7 @@ static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename,
uv_close((uv_handle_t*)handle, close_cb);
}
-static void timber_cb_close_handle(uv_timer_t* timer, int status) {
+static void timer_cb_close_handle(uv_timer_t* timer, int status) {
uv_handle_t* handle;
ASSERT(timer != NULL);
@@ -138,7 +142,7 @@ static void fs_event_cb_file_current_dir(uv_fs_event_t* handle,
static uv_timer_t timer;
uv_timer_init(handle->loop, &timer);
timer.data = handle;
- uv_timer_start(&timer, timber_cb_close_handle, 250, 0);
+ uv_timer_start(&timer, timer_cb_close_handle, 250, 0);
}
}
@@ -174,14 +178,13 @@ static void timer_cb_watch_twice(uv_timer_t* handle, int status) {
}
TEST_IMPL(fs_event_watch_dir) {
- uv_fs_t fs_req;
uv_loop_t* loop = uv_default_loop();
int r;
/* Setup */
- uv_fs_unlink(loop, &fs_req, "watch_dir/file1", NULL);
- uv_fs_unlink(loop, &fs_req, "watch_dir/file2", NULL);
- uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
+ remove("watch_dir/file2");
+ remove("watch_dir/file1");
+ remove("watch_dir/");
create_dir(loop, "watch_dir");
r = uv_fs_event_init(loop, &fs_event, "watch_dir", fs_event_cb_dir, 0);
@@ -191,29 +194,29 @@ TEST_IMPL(fs_event_watch_dir) {
r = uv_timer_start(&timer, timer_cb_dir, 100, 0);
ASSERT(r != -1);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fs_event_cb_called == 1);
ASSERT(timer_cb_called == 1);
ASSERT(close_cb_called == 2);
/* Cleanup */
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file1", NULL);
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file2", NULL);
- r = uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
+ remove("watch_dir/file2");
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(fs_event_watch_file) {
- uv_fs_t fs_req;
uv_loop_t* loop = uv_default_loop();
int r;
/* Setup */
- uv_fs_unlink(loop, &fs_req, "watch_dir/file1", NULL);
- uv_fs_unlink(loop, &fs_req, "watch_dir/file2", NULL);
- uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
+ remove("watch_dir/file2");
+ remove("watch_dir/file1");
+ remove("watch_dir/");
create_dir(loop, "watch_dir");
create_file(loop, "watch_dir/file1");
create_file(loop, "watch_dir/file2");
@@ -225,17 +228,18 @@ TEST_IMPL(fs_event_watch_file) {
r = uv_timer_start(&timer, timer_cb_file, 100, 100);
ASSERT(r != -1);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fs_event_cb_called == 1);
ASSERT(timer_cb_called == 2);
ASSERT(close_cb_called == 2);
/* Cleanup */
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file1", NULL);
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file2", NULL);
- r = uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
+ remove("watch_dir/file2");
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -252,21 +256,21 @@ TEST_IMPL(fs_event_watch_file_twice) {
ASSERT(0 == uv_fs_event_init(loop, watchers + 1, path, fail_cb, 0));
ASSERT(0 == uv_timer_init(loop, &timer));
ASSERT(0 == uv_timer_start(&timer, timer_cb_watch_twice, 10, 0));
- ASSERT(0 == uv_run(loop));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(fs_event_watch_file_current_dir) {
uv_timer_t timer;
uv_loop_t* loop;
- uv_fs_t fs_req;
int r;
loop = uv_default_loop();
/* Setup */
- uv_fs_unlink(loop, &fs_req, "watch_file", NULL);
+ remove("watch_file");
create_file(loop, "watch_file");
r = uv_fs_event_init(loop, &fs_event, "watch_file",
@@ -283,14 +287,16 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
ASSERT(fs_event_cb_called == 0);
ASSERT(close_cb_called == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(timer_cb_touch_called == 1);
ASSERT(fs_event_cb_called == 1);
ASSERT(close_cb_called == 1);
/* Cleanup */
- r = uv_fs_unlink(loop, &fs_req, "watch_file", NULL);
+ remove("watch_file");
+
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -313,7 +319,7 @@ TEST_IMPL(fs_event_no_callback_after_close) {
uv_close((uv_handle_t*)&fs_event, close_cb);
touch_file(loop, "watch_dir/file1");
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fs_event_cb_called == 0);
ASSERT(close_cb_called == 1);
@@ -322,17 +328,17 @@ TEST_IMPL(fs_event_no_callback_after_close) {
remove("watch_dir/file1");
remove("watch_dir/");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(fs_event_no_callback_on_close) {
- uv_fs_t fs_req;
uv_loop_t* loop = uv_default_loop();
int r;
/* Setup */
- uv_fs_unlink(loop, &fs_req, "watch_dir/file1", NULL);
- uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
+ remove("watch_dir/file1");
+ remove("watch_dir/");
create_dir(loop, "watch_dir");
create_file(loop, "watch_dir/file1");
@@ -345,15 +351,16 @@ TEST_IMPL(fs_event_no_callback_on_close) {
uv_close((uv_handle_t*)&fs_event, close_cb);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fs_event_cb_called == 0);
ASSERT(close_cb_called == 1);
/* Cleanup */
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file1", NULL);
- r = uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -390,17 +397,17 @@ TEST_IMPL(fs_event_immediate_close) {
r = uv_timer_start(&timer, timer_cb, 1, 0);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(close_cb_called == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(fs_event_close_with_pending_event) {
uv_loop_t* loop;
- uv_fs_t fs_req;
int r;
loop = uv_default_loop();
@@ -416,20 +423,19 @@ TEST_IMPL(fs_event_close_with_pending_event) {
uv_close((uv_handle_t*)&fs_event, close_cb);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
/* Clean up */
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file", NULL);
- ASSERT(r == 0);
- r = uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
- ASSERT(r == 0);
+ remove("watch_dir/file");
+ remove("watch_dir/");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
-#if HAVE_KQUEUE
+#if defined(HAVE_KQUEUE)
/* kqueue doesn't register fs events if you don't have an active watcher.
* The file descriptor needs to be part of the kqueue set of interest and
@@ -457,7 +463,6 @@ static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename,
TEST_IMPL(fs_event_close_in_callback) {
uv_loop_t* loop;
- uv_fs_t fs_req;
int r;
loop = uv_default_loop();
@@ -479,25 +484,20 @@ TEST_IMPL(fs_event_close_in_callback) {
touch_file(loop, "watch_dir/file4");
touch_file(loop, "watch_dir/file5");
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
ASSERT(fs_event_cb_called == 3);
/* Clean up */
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file1", NULL);
- ASSERT(r == 0);
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file2", NULL);
- ASSERT(r == 0);
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file3", NULL);
- ASSERT(r == 0);
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file4", NULL);
- ASSERT(r == 0);
- r = uv_fs_unlink(loop, &fs_req, "watch_dir/file5", NULL);
- ASSERT(r == 0);
- r = uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
- ASSERT(r == 0);
+ remove("watch_dir/file1");
+ remove("watch_dir/file2");
+ remove("watch_dir/file3");
+ remove("watch_dir/file4");
+ remove("watch_dir/file5");
+ remove("watch_dir/");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-fs-poll.c b/deps/uv/test/test-fs-poll.c
index 00a73b6c9..f312d87f8 100644
--- a/deps/uv/test/test-fs-poll.c
+++ b/deps/uv/test/test-fs-poll.c
@@ -76,7 +76,9 @@ static void poll_cb(uv_fs_poll_t* handle,
int status,
const uv_statbuf_t* prev,
const uv_statbuf_t* curr) {
- const static uv_statbuf_t zero_statbuf;
+ uv_statbuf_t zero_statbuf;
+
+ memset(&zero_statbuf, 0, sizeof(zero_statbuf));
ASSERT(handle == &poll_handle);
ASSERT(uv_is_active((uv_handle_t*)handle));
@@ -135,12 +137,12 @@ TEST_IMPL(fs_poll) {
ASSERT(0 == uv_timer_init(loop, &timer_handle));
ASSERT(0 == uv_fs_poll_init(loop, &poll_handle));
ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb, FIXTURE, 100));
- ASSERT(0 == uv_run(loop));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(poll_cb_called == 5);
ASSERT(timer_cb_called == 2);
ASSERT(close_cb_called == 1);
- uv_loop_delete(loop);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 4b6d847f4..0016b3bed 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -19,9 +19,6 @@
* IN THE SOFTWARE.
*/
-/* FIXME we shouldn't need to branch in this file */
-#define UNIX (defined(__unix__) || defined(__POSIX__) || defined(__APPLE__))
-
#include "uv.h"
#include "task.h"
@@ -30,8 +27,9 @@
#include <fcntl.h>
#include <sys/stat.h>
-
-#if UNIX
+/* FIXME we shouldn't need to branch in this file */
+#if defined(__unix__) || defined(__POSIX__) || \
+ defined(__APPLE__) || defined(_AIX)
#include <unistd.h> /* unlink, rmdir, etc. */
#else
# include <direct.h>
@@ -55,6 +53,7 @@ typedef struct {
} utime_check_t;
+static int dummy_cb_count;
static int close_cb_count;
static int create_cb_count;
static int open_cb_count;
@@ -105,16 +104,16 @@ static char buf[32];
static char test_buf[] = "test-buffer\n";
-void check_permission(const char* filename, int mode) {
+static void check_permission(const char* filename, int mode) {
int r;
uv_fs_t req;
- struct stat* s;
+ uv_statbuf_t* s;
r = uv_fs_stat(uv_default_loop(), &req, filename, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
- s = req.ptr;
+ s = &req.statbuf;
#ifdef _WIN32
/*
* On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit,
@@ -129,6 +128,12 @@ void check_permission(const char* filename, int mode) {
}
+static void dummy_cb(uv_fs_t* req) {
+ (void) req;
+ dummy_cb_count++;
+}
+
+
static void link_cb(uv_fs_t* req) {
ASSERT(req->fs_type == UV_FS_LINK);
ASSERT(req->result == 0);
@@ -472,11 +477,12 @@ TEST_IMPL(fs_file_noent) {
ASSERT(r == 0);
ASSERT(open_cb_count == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(open_cb_count == 1);
/* TODO add EACCES test */
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -500,9 +506,10 @@ TEST_IMPL(fs_file_nametoolong) {
ASSERT(r == 0);
ASSERT(open_cb_count == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(open_cb_count == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -526,16 +533,17 @@ TEST_IMPL(fs_file_loop) {
ASSERT(r == 0);
ASSERT(open_cb_count == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(open_cb_count == 1);
unlink("test_symlink");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
static void check_utime(const char* path, double atime, double mtime) {
- struct stat* s;
+ uv_statbuf_t* s;
uv_fs_t req;
int r;
@@ -543,9 +551,9 @@ static void check_utime(const char* path, double atime, double mtime) {
ASSERT(r == 0);
ASSERT(req.result == 0);
- s = req.ptr;
+ s = &req.statbuf;
-#if _WIN32
+#if defined(_WIN32) || defined(_AIX)
ASSERT(s->st_atime == atime);
ASSERT(s->st_mtime == mtime);
#elif !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
@@ -602,7 +610,7 @@ TEST_IMPL(fs_file_async) {
r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
S_IREAD | S_IWRITE, create_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(create_cb_count == 1);
ASSERT(write_cb_count == 1);
@@ -613,7 +621,7 @@ TEST_IMPL(fs_file_async) {
r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", rename_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(create_cb_count == 1);
ASSERT(write_cb_count == 1);
ASSERT(close_cb_count == 1);
@@ -622,7 +630,7 @@ TEST_IMPL(fs_file_async) {
r = uv_fs_open(loop, &open_req1, "test_file2", O_RDWR, 0, open_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(open_cb_count == 1);
ASSERT(read_cb_count == 1);
ASSERT(close_cb_count == 2);
@@ -634,7 +642,7 @@ TEST_IMPL(fs_file_async) {
r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, open_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(open_cb_count == 2);
ASSERT(read_cb_count == 2);
ASSERT(close_cb_count == 3);
@@ -648,6 +656,7 @@ TEST_IMPL(fs_file_async) {
unlink("test_file");
unlink("test_file2");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -732,6 +741,7 @@ TEST_IMPL(fs_file_sync) {
unlink("test_file");
unlink("test_file2");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -749,7 +759,7 @@ TEST_IMPL(fs_async_dir) {
r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(mkdir_cb_count == 1);
/* Create 2 files synchronously. */
@@ -772,7 +782,7 @@ TEST_IMPL(fs_async_dir) {
r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, readdir_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(readdir_cb_count == 1);
/* sync uv_fs_readdir */
@@ -787,35 +797,35 @@ TEST_IMPL(fs_async_dir) {
r = uv_fs_stat(loop, &stat_req, "test_dir", stat_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
- r = uv_fs_stat(loop, &stat_req, "test_dir\\", stat_cb);
+ r = uv_fs_stat(loop, &stat_req, "test_dir/", stat_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
r = uv_fs_lstat(loop, &stat_req, "test_dir", stat_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
- r = uv_fs_lstat(loop, &stat_req, "test_dir\\", stat_cb);
+ r = uv_fs_lstat(loop, &stat_req, "test_dir/", stat_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(stat_cb_count == 4);
r = uv_fs_unlink(loop, &unlink_req, "test_dir/file1", unlink_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(unlink_cb_count == 1);
r = uv_fs_unlink(loop, &unlink_req, "test_dir/file2", unlink_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(unlink_cb_count == 2);
r = uv_fs_rmdir(loop, &rmdir_req, "test_dir", rmdir_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(rmdir_cb_count == 1);
/* Cleanup */
@@ -823,6 +833,7 @@ TEST_IMPL(fs_async_dir) {
unlink("test_dir/file2");
rmdir("test_dir");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -867,7 +878,7 @@ TEST_IMPL(fs_async_sendfile) {
r = uv_fs_sendfile(loop, &sendfile_req, open_req2.result, open_req1.result,
0, 131072, sendfile_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(sendfile_cb_count == 1);
@@ -886,6 +897,7 @@ TEST_IMPL(fs_async_sendfile) {
unlink("test_file");
unlink("test_file2");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -923,7 +935,7 @@ TEST_IMPL(fs_fstat) {
/* Now do the uv_fs_fstat call asynchronously */
r = uv_fs_fstat(loop, &req, file, fstat_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fstat_cb_count == 1);
@@ -936,11 +948,12 @@ TEST_IMPL(fs_fstat) {
* Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately.
*/
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
/* Cleanup. */
unlink("test_file");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1001,7 +1014,7 @@ TEST_IMPL(fs_chmod) {
}
r = uv_fs_chmod(loop, &req, "test_file", 0200, chmod_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(chmod_cb_count == 1);
chmod_cb_count = 0; /* reset for the next test */
#endif
@@ -1013,7 +1026,7 @@ TEST_IMPL(fs_chmod) {
}
r = uv_fs_chmod(loop, &req, "test_file", 0400, chmod_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(chmod_cb_count == 1);
/* async fchmod */
@@ -1023,7 +1036,7 @@ TEST_IMPL(fs_chmod) {
}
r = uv_fs_fchmod(loop, &req, file, 0600, fchmod_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fchmod_cb_count == 1);
close(file);
@@ -1032,11 +1045,12 @@ TEST_IMPL(fs_chmod) {
* Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately.
*/
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
/* Cleanup. */
unlink("test_file");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1073,19 +1087,19 @@ TEST_IMPL(fs_chown) {
/* async chown */
r = uv_fs_chown(loop, &req, "test_file", -1, -1, chown_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(chown_cb_count == 1);
/* chown to root (fail) */
chown_cb_count = 0;
r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(chown_cb_count == 1);
/* async fchown */
r = uv_fs_fchown(loop, &req, file, -1, -1, fchown_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fchown_cb_count == 1);
close(file);
@@ -1094,11 +1108,12 @@ TEST_IMPL(fs_chown) {
* Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately.
*/
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
/* Cleanup. */
unlink("test_file");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1153,7 +1168,7 @@ TEST_IMPL(fs_link) {
/* async link */
r = uv_fs_link(loop, &req, "test_file", "test_file_link2", link_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(link_cb_count == 1);
r = uv_fs_open(loop, &req, "test_file_link2", O_RDWR, 0, NULL);
@@ -1174,13 +1189,37 @@ TEST_IMPL(fs_link) {
* Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately.
*/
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
/* Cleanup. */
unlink("test_file");
unlink("test_file_link");
unlink("test_file_link2");
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_readlink) {
+ uv_fs_t req;
+
+ loop = uv_default_loop();
+ ASSERT(0 == uv_fs_readlink(loop, &req, "no_such_file", dummy_cb));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(dummy_cb_count == 1);
+ ASSERT(req.ptr == NULL);
+ ASSERT(req.result == -1);
+ ASSERT(req.errorno == UV_ENOENT);
+ uv_fs_req_cleanup(&req);
+
+ ASSERT(-1 == uv_fs_readlink(loop, &req, "no_such_file", NULL));
+ ASSERT(req.ptr == NULL);
+ ASSERT(req.result == -1);
+ ASSERT(req.errorno == UV_ENOENT);
+ uv_fs_req_cleanup(&req);
+
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1253,6 +1292,8 @@ TEST_IMPL(fs_symlink) {
r = uv_fs_symlink(loop, &req, "test_file_symlink", "test_file_symlink_symlink", 0, NULL);
ASSERT(r != -1);
+ uv_fs_req_cleanup(&req);
+
r = uv_fs_readlink(loop, &req, "test_file_symlink_symlink", NULL);
ASSERT(r != -1);
ASSERT(strcmp(req.ptr, "test_file_symlink") == 0);
@@ -1261,7 +1302,7 @@ TEST_IMPL(fs_symlink) {
/* async link */
r = uv_fs_symlink(loop, &req, "test_file", "test_file_symlink2", 0, symlink_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(symlink_cb_count == 1);
r = uv_fs_open(loop, &req, "test_file_symlink2", O_RDWR, 0, NULL);
@@ -1280,16 +1321,18 @@ TEST_IMPL(fs_symlink) {
r = uv_fs_symlink(loop, &req, "test_file_symlink2", "test_file_symlink2_symlink", 0, NULL);
ASSERT(r != -1);
+ uv_fs_req_cleanup(&req);
+
r = uv_fs_readlink(loop, &req, "test_file_symlink2_symlink", readlink_cb);
ASSERT(r != -1);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(readlink_cb_count == 1);
/*
* Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately.
*/
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
/* Cleanup. */
unlink("test_file");
@@ -1298,6 +1341,7 @@ TEST_IMPL(fs_symlink) {
unlink("test_file_symlink2");
unlink("test_file_symlink2_symlink");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1409,6 +1453,7 @@ TEST_IMPL(fs_symlink_dir) {
rmdir("test_dir");
rmdir("test_dir_symlink");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1453,12 +1498,13 @@ TEST_IMPL(fs_utime) {
utime_req.data = &checkme;
r = uv_fs_utime(loop, &utime_req, path, atime, mtime, utime_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(utime_cb_count == 1);
/* Cleanup. */
unlink(path);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1490,6 +1536,7 @@ TEST_IMPL(fs_stat_root) {
r = uv_fs_stat(loop, &stat_req, "\\\\?\\C:\\", NULL);
ASSERT(r == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
#endif
@@ -1543,12 +1590,13 @@ TEST_IMPL(fs_futime) {
futime_req.data = &checkme;
r = uv_fs_futime(loop, &futime_req, file, atime, mtime, futime_cb);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(futime_cb_count == 1);
/* Cleanup. */
unlink(path);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1565,6 +1613,7 @@ TEST_IMPL(fs_stat_missing_path) {
ASSERT(uv_last_error(loop).code == UV_ENOENT);
uv_fs_req_cleanup(&req);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1590,12 +1639,13 @@ TEST_IMPL(fs_readdir_empty_dir) {
ASSERT(r == 0);
ASSERT(readdir_cb_count == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(readdir_cb_count == 1);
uv_fs_rmdir(loop, &req, path, NULL);
uv_fs_req_cleanup(&req);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1610,14 +1660,16 @@ TEST_IMPL(fs_readdir_file) {
r = uv_fs_readdir(loop, &readdir_req, path, 0, NULL);
ASSERT(r == -1);
ASSERT(uv_last_error(loop).code == UV_ENOTDIR);
+ uv_fs_req_cleanup(&readdir_req);
r = uv_fs_readdir(loop, &readdir_req, path, 0, file_readdir_cb);
ASSERT(r == 0);
ASSERT(readdir_cb_count == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(readdir_cb_count == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1644,9 +1696,10 @@ TEST_IMPL(fs_open_dir) {
ASSERT(r == 0);
ASSERT(open_cb_count == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(open_cb_count == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1715,6 +1768,7 @@ TEST_IMPL(fs_file_open_append) {
/* Cleanup */
unlink("test_file");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1783,6 +1837,7 @@ TEST_IMPL(fs_rename_to_existing_file) {
unlink("test_file");
unlink("test_file2");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -1839,5 +1894,6 @@ TEST_IMPL(fs_read_file_eof) {
/* Cleanup */
unlink("test_file");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-getaddrinfo.c b/deps/uv/test/test-getaddrinfo.c
index 2a8c94e75..dd022072a 100644
--- a/deps/uv/test/test-getaddrinfo.c
+++ b/deps/uv/test/test-getaddrinfo.c
@@ -21,11 +21,7 @@
#include "uv.h"
#include "task.h"
-
#include <stdlib.h>
-#include <stdio.h>
-#include <string.h> /* strlen */
-
#define CONCURRENT_COUNT 10
@@ -84,10 +80,11 @@ TEST_IMPL(getaddrinfo_basic) {
NULL);
ASSERT(r == 0);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(getaddrinfo_cbs == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -112,11 +109,12 @@ TEST_IMPL(getaddrinfo_concurrent) {
ASSERT(r == 0);
}
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
for (i = 0; i < CONCURRENT_COUNT; i++) {
ASSERT(callback_counts[i] == 1);
}
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-gethostbyname.c b/deps/uv/test/test-gethostbyname.c
deleted file mode 100644
index 1df2aaac3..000000000
--- a/deps/uv/test/test-gethostbyname.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/* 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.
- */
-
-#include "uv.h"
-#include "task.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h> /* strlen */
-
-static ares_channel channel;
-
-static int ares_bynamecallbacks;
-static int bynamecallbacksig;
-static int ares_byaddrcallbacks;
-static int byaddrcallbacksig;
-
-static void aresbynamecallback( void *arg,
- int status,
- int timeouts,
- struct hostent *hostent) {
- int * iargs;
- ASSERT(arg != NULL);
- iargs = (int*)arg;
- ASSERT(*iargs == bynamecallbacksig);
- ASSERT(timeouts == 0);
-
- printf("aresbynamecallback %d\n", ares_bynamecallbacks++);
-}
-
-
-static void aresbyaddrcallback( void *arg,
- int status,
- int timeouts,
- struct hostent *hostent) {
- int * iargs;
- ASSERT(arg != NULL);
- iargs = (int*)arg;
- ASSERT(*iargs == byaddrcallbacksig);
- ASSERT(timeouts == 0);
-
- printf("aresbyaddrcallback %d\n", ares_byaddrcallbacks++);
-}
-
-
-static void setup_cares() {
- int r;
- struct ares_options options;
- memset(&options, 0, sizeof options);
- r = uv_ares_init_options(uv_default_loop(), &channel, &options, 0);
- ASSERT(r == ARES_SUCCESS);
-}
-
-
-TEST_IMPL(gethostbyname) {
-
- int rc = 0;
- char addr[4];
-
- rc = ares_library_init(ARES_LIB_INIT_ALL);
- if (rc != 0) {
- printf("ares library init fails %d\n", rc);
- return 1;
- }
-
- printf("Start basic gethostbyname test\n");
- setup_cares();
-
- ares_bynamecallbacks = 0;
- bynamecallbacksig = 7;
-
- ares_gethostbyname(channel,
- "microsoft.com",
- AF_INET,
- &aresbynamecallback,
- &bynamecallbacksig);
- uv_run(uv_default_loop());
-
- ASSERT(ares_bynamecallbacks == 1);
-
- uv_ares_destroy(uv_default_loop(), channel);
- printf("Done basic gethostbyname test\n");
-
-
- /* two sequential call on new channel */
-
- printf("Start gethostbyname and gethostbyaddr sequential test\n");
- setup_cares();
-
- ares_bynamecallbacks = 0;
- bynamecallbacksig = 7;
-
- ares_gethostbyname(channel,
- "microsoft.com",
- AF_INET,
- &aresbynamecallback,
- &bynamecallbacksig);
- uv_run(uv_default_loop());
-
- ASSERT(ares_bynamecallbacks == 1);
-
- ares_byaddrcallbacks = 0;
- byaddrcallbacksig = 8;
- addr[0] = 10;
- addr[1] = 0;
- addr[2] = 1;
- addr[3] = 99;
-
- ares_gethostbyaddr(channel,
- addr,
- 4,
- AF_INET,
- &aresbyaddrcallback,
- &byaddrcallbacksig);
-
- uv_run(uv_default_loop());
-
- ASSERT(ares_byaddrcallbacks == 1);
-
- uv_ares_destroy(uv_default_loop(), channel);
- printf("Done gethostbyname and gethostbyaddr sequential test\n");
-
-
- /* two simultaneous calls on new channel */
-
- printf("Start gethostbyname and gethostbyaddr concurrent test\n");
- setup_cares();
-
- ares_bynamecallbacks = 0;
- bynamecallbacksig = 7;
-
- ares_gethostbyname(channel,
- "microsoft.com",
- AF_INET,
- &aresbynamecallback,
- &bynamecallbacksig);
-
- ares_byaddrcallbacks = 0;
- byaddrcallbacksig = 8;
- addr[0] = 10;
- addr[1] = 0;
- addr[2] = 1;
- addr[3] = 99;
-
- ares_gethostbyaddr(channel,
- addr,
- 4,
- AF_INET,
- &aresbyaddrcallback,
- &byaddrcallbacksig);
-
- uv_run(uv_default_loop());
-
- ASSERT(ares_bynamecallbacks == 1);
- ASSERT(ares_byaddrcallbacks == 1);
-
-
- uv_ares_destroy(uv_default_loop(), channel);
- printf("Done gethostbyname and gethostbyaddr concurrent test\n");
-
- return 0;
-}
diff --git a/deps/uv/test/test-getsockname.c b/deps/uv/test/test-getsockname.c
index ff28beb92..2baa9d757 100644
--- a/deps/uv/test/test-getsockname.c
+++ b/deps/uv/test/test-getsockname.c
@@ -105,7 +105,7 @@ static void check_sockname(struct sockaddr* addr, const char* compare_ip,
static void on_connection(uv_stream_t* server, int status) {
struct sockaddr sockname, peername;
int namelen;
- uv_handle_t* handle;
+ uv_tcp_t* handle;
int r;
if (status != 0) {
@@ -114,10 +114,10 @@ static void on_connection(uv_stream_t* server, int status) {
}
ASSERT(status == 0);
- handle = (uv_handle_t*) malloc(sizeof(uv_tcp_t));
+ handle = malloc(sizeof(*handle));
ASSERT(handle != NULL);
- r = uv_tcp_init(loop, (uv_tcp_t*)handle);
+ r = uv_tcp_init(loop, handle);
ASSERT(r == 0);
/* associate server with stream */
@@ -127,13 +127,13 @@ static void on_connection(uv_stream_t* server, int status) {
ASSERT(r == 0);
namelen = sizeof sockname;
- r = uv_tcp_getsockname((uv_tcp_t*) handle, &sockname, &namelen);
+ r = uv_tcp_getsockname(handle, &sockname, &namelen);
ASSERT(r == 0);
check_sockname(&sockname, "127.0.0.1", server_port, "accepted socket");
getsocknamecount++;
namelen = sizeof peername;
- r = uv_tcp_getpeername((uv_tcp_t*) handle, &peername, &namelen);
+ r = uv_tcp_getpeername(handle, &peername, &namelen);
ASSERT(r == 0);
check_sockname(&peername, "127.0.0.1", connect_port, "accepted socket peer");
getpeernamecount++;
@@ -165,7 +165,7 @@ static void on_connect(uv_connect_t* req, int status) {
}
-static int tcp_listener() {
+static int tcp_listener(void) {
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", server_port);
struct sockaddr sockname, peername;
int namelen;
@@ -206,7 +206,7 @@ static int tcp_listener() {
}
-static void tcp_connector() {
+static void tcp_connector(void) {
struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", server_port);
struct sockaddr sockname;
int r, namelen;
@@ -238,9 +238,9 @@ static void udp_recv(uv_udp_t* handle,
int r;
ASSERT(nread >= 0);
+ free(buf.base);
if (nread == 0) {
- free(buf.base);
return;
}
@@ -261,7 +261,7 @@ static void udp_send(uv_udp_send_t* req, int status) {
}
-static int udp_listener() {
+static int udp_listener(void) {
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", server_port);
struct sockaddr sockname;
int namelen;
@@ -317,11 +317,12 @@ TEST_IMPL(getsockname_tcp) {
tcp_connector();
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(getsocknamecount == 3);
ASSERT(getpeernamecount == 3);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -334,9 +335,10 @@ TEST_IMPL(getsockname_udp) {
udp_sender();
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(getsocknamecount == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-idle.c b/deps/uv/test/test-idle.c
index 95ef3a949..4f0294cfa 100644
--- a/deps/uv/test/test-idle.c
+++ b/deps/uv/test/test-idle.c
@@ -70,12 +70,13 @@ TEST_IMPL(idle_starvation) {
r = uv_timer_start(&timer_handle, timer_cb, 50, 0);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(idle_cb_called > 0);
ASSERT(timer_cb_called == 1);
ASSERT(close_cb_called == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-ipc-send-recv.c b/deps/uv/test/test-ipc-send-recv.c
index 970bf1eff..90ac69f39 100644
--- a/deps/uv/test/test-ipc-send-recv.c
+++ b/deps/uv/test/test-ipc-send-recv.c
@@ -103,7 +103,7 @@ static int run_test(void) {
r = uv_read2_start((uv_stream_t*)&ctx.channel, alloc_cb, recv_cb);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(num_recv_handles == 1);
@@ -123,7 +123,11 @@ TEST_IMPL(ipc_send_recv_pipe) {
r = uv_pipe_bind(&ctx.send.pipe, TEST_PIPENAME);
ASSERT(r == 0);
- return run_test();
+ r = run_test();
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
}
@@ -138,7 +142,11 @@ TEST_IMPL(ipc_send_recv_tcp) {
r = uv_tcp_bind(&ctx.send.tcp, uv_ip4_addr("127.0.0.1", TEST_PORT));
ASSERT(r == 0);
- return run_test();
+ r = run_test();
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
}
@@ -202,8 +210,9 @@ int ipc_send_recv_helper(void) {
r = uv_read2_start((uv_stream_t*)&ctx.channel, alloc_cb, read2_cb);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c
index 61add0b4b..40a48b732 100644
--- a/deps/uv/test/test-ipc.c
+++ b/deps/uv/test/test-ipc.c
@@ -108,7 +108,7 @@ static void connect_cb(uv_connect_t* req, int status) {
}
-static void make_many_connections() {
+static void make_many_connections(void) {
tcp_conn* conn;
struct sockaddr_in addr;
int r, i;
@@ -318,9 +318,10 @@ static int run_ipc_test(const char* helper, uv_read2_cb read_cb) {
spawn_helper(&channel, &process, helper);
uv_read2_start((uv_stream_t*)&channel, on_alloc, read_cb);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -374,6 +375,7 @@ TEST_IMPL(listen_with_simultaneous_accepts) {
ASSERT(r == 0);
ASSERT(server.reqs_pending == 32);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -396,6 +398,7 @@ TEST_IMPL(listen_no_simultaneous_accepts) {
ASSERT(r == 0);
ASSERT(server.reqs_pending == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
#endif
@@ -403,7 +406,7 @@ TEST_IMPL(listen_no_simultaneous_accepts) {
/* Everything here runs in a child process. */
-tcp_conn conn;
+static tcp_conn conn;
static void close_cb(uv_handle_t* handle) {
@@ -564,17 +567,18 @@ int ipc_helper(int listen_after_write) {
ASSERT(r == 0);
}
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(connection_accepted == 1);
ASSERT(close_cb_called == 3);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
-int ipc_helper_tcp_connection() {
+int ipc_helper_tcp_connection(void) {
/*
* This is launched from test-ipc.c. stdin is a duplex channel that we
* over which a handle will be transmitted.
@@ -609,12 +613,13 @@ int ipc_helper_tcp_connection() {
r = uv_tcp_connect(&conn.conn_req, (uv_tcp_t*)&conn.conn, addr, connect_child_process_cb);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(tcp_conn_read_cb_called == 1);
ASSERT(tcp_conn_write_cb_called == 1);
ASSERT(close_cb_called == 4);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 27e9d91c9..2341463a1 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -22,6 +22,16 @@
TEST_DECLARE (platform_output)
TEST_DECLARE (callback_order)
TEST_DECLARE (run_once)
+TEST_DECLARE (run_nowait)
+TEST_DECLARE (loop_stop)
+TEST_DECLARE (barrier_1)
+TEST_DECLARE (barrier_2)
+TEST_DECLARE (barrier_3)
+TEST_DECLARE (condvar_1)
+TEST_DECLARE (condvar_2)
+TEST_DECLARE (condvar_3)
+TEST_DECLARE (condvar_4)
+TEST_DECLARE (condvar_5)
TEST_DECLARE (semaphore_1)
TEST_DECLARE (semaphore_2)
TEST_DECLARE (semaphore_3)
@@ -40,6 +50,7 @@ TEST_DECLARE (pipe_ping_pong)
TEST_DECLARE (delayed_accept)
TEST_DECLARE (multiple_listen)
TEST_DECLARE (tcp_writealot)
+TEST_DECLARE (tcp_open)
TEST_DECLARE (tcp_connect_error_after_write)
TEST_DECLARE (tcp_shutdown_after_write)
TEST_DECLARE (tcp_bind_error_addrinuse)
@@ -54,9 +65,9 @@ TEST_DECLARE (tcp_connect_timeout)
TEST_DECLARE (tcp_close_while_connecting)
TEST_DECLARE (tcp_close)
TEST_DECLARE (tcp_flags)
-TEST_DECLARE (tcp_write_error)
TEST_DECLARE (tcp_write_to_half_open_connection)
TEST_DECLARE (tcp_unexpected_read)
+TEST_DECLARE (tcp_read_stop)
TEST_DECLARE (tcp_bind6_error_addrinuse)
TEST_DECLARE (tcp_bind6_error_addrnotavail)
TEST_DECLARE (tcp_bind6_error_fault)
@@ -69,6 +80,7 @@ TEST_DECLARE (udp_dgram_too_big)
TEST_DECLARE (udp_dual_stack)
TEST_DECLARE (udp_ipv6_only)
TEST_DECLARE (udp_options)
+TEST_DECLARE (udp_open)
TEST_DECLARE (pipe_bind_error_addrinuse)
TEST_DECLARE (pipe_bind_error_addrnotavail)
TEST_DECLARE (pipe_bind_error_inval)
@@ -85,6 +97,7 @@ TEST_DECLARE (error_message)
TEST_DECLARE (timer)
TEST_DECLARE (timer_again)
TEST_DECLARE (timer_start_twice)
+TEST_DECLARE (timer_order)
TEST_DECLARE (idle_starvation)
TEST_DECLARE (loop_handles)
TEST_DECLARE (get_loadavg)
@@ -101,6 +114,7 @@ TEST_DECLARE (fs_event_ref)
TEST_DECLARE (fs_poll_ref)
TEST_DECLARE (tcp_ref)
TEST_DECLARE (tcp_ref2)
+TEST_DECLARE (tcp_ref2b)
TEST_DECLARE (tcp_ref3)
TEST_DECLARE (tcp_ref4)
TEST_DECLARE (udp_ref)
@@ -111,6 +125,8 @@ TEST_DECLARE (pipe_ref2)
TEST_DECLARE (pipe_ref3)
TEST_DECLARE (pipe_ref4)
TEST_DECLARE (process_ref)
+TEST_DECLARE (active)
+TEST_DECLARE (embed)
TEST_DECLARE (async)
TEST_DECLARE (get_currentexe)
TEST_DECLARE (process_title)
@@ -119,11 +135,11 @@ TEST_DECLARE (get_memory)
TEST_DECLARE (hrtime)
TEST_DECLARE (getaddrinfo_basic)
TEST_DECLARE (getaddrinfo_concurrent)
-TEST_DECLARE (gethostbyname)
TEST_DECLARE (getsockname_tcp)
TEST_DECLARE (getsockname_udp)
TEST_DECLARE (fail_always)
TEST_DECLARE (pass_always)
+TEST_DECLARE (spawn_fails)
TEST_DECLARE (spawn_exit_code)
TEST_DECLARE (spawn_stdout)
TEST_DECLARE (spawn_stdin)
@@ -137,6 +153,7 @@ TEST_DECLARE (spawn_preserve_env)
TEST_DECLARE (spawn_setuid_fails)
TEST_DECLARE (spawn_setgid_fails)
TEST_DECLARE (spawn_stdout_to_file)
+TEST_DECLARE (spawn_auto_unref)
TEST_DECLARE (fs_poll)
TEST_DECLARE (kill)
TEST_DECLARE (fs_file_noent)
@@ -150,6 +167,7 @@ TEST_DECLARE (fs_fstat)
TEST_DECLARE (fs_chmod)
TEST_DECLARE (fs_chown)
TEST_DECLARE (fs_link)
+TEST_DECLARE (fs_readlink)
TEST_DECLARE (fs_symlink)
TEST_DECLARE (fs_symlink_dir)
TEST_DECLARE (fs_utime)
@@ -171,13 +189,17 @@ TEST_DECLARE (fs_readdir_file)
TEST_DECLARE (fs_open_dir)
TEST_DECLARE (fs_rename_to_existing_file)
TEST_DECLARE (threadpool_queue_work_simple)
+TEST_DECLARE (threadpool_queue_work_einval)
TEST_DECLARE (threadpool_multiple_event_loops)
+TEST_DECLARE (threadpool_cancel_getaddrinfo)
+TEST_DECLARE (threadpool_cancel_work)
+TEST_DECLARE (threadpool_cancel_fs)
+TEST_DECLARE (threadpool_cancel_single)
TEST_DECLARE (thread_mutex)
TEST_DECLARE (thread_rwlock)
TEST_DECLARE (thread_create)
TEST_DECLARE (strlcpy)
TEST_DECLARE (strlcat)
-TEST_DECLARE (counters_init)
TEST_DECLARE (dlerror)
TEST_DECLARE (poll_duplex)
TEST_DECLARE (poll_unidirectional)
@@ -191,6 +213,9 @@ TEST_DECLARE (listen_no_simultaneous_accepts)
TEST_DECLARE (fs_stat_root)
#else
TEST_DECLARE (spawn_setuid_setgid)
+TEST_DECLARE (we_get_signal)
+TEST_DECLARE (we_get_signals)
+TEST_DECLARE (signal_multiple_loops)
#endif
HELPER_DECLARE (tcp4_echo_server)
HELPER_DECLARE (tcp6_echo_server)
@@ -205,6 +230,16 @@ TASK_LIST_START
TEST_ENTRY (callback_order)
#endif
TEST_ENTRY (run_once)
+ TEST_ENTRY (run_nowait)
+ TEST_ENTRY (loop_stop)
+ TEST_ENTRY (barrier_1)
+ TEST_ENTRY (barrier_2)
+ TEST_ENTRY (barrier_3)
+ TEST_ENTRY (condvar_1)
+ TEST_ENTRY (condvar_2)
+ TEST_ENTRY (condvar_3)
+ TEST_ENTRY (condvar_4)
+ TEST_ENTRY (condvar_5)
TEST_ENTRY (semaphore_1)
TEST_ENTRY (semaphore_2)
TEST_ENTRY (semaphore_3)
@@ -237,6 +272,9 @@ TASK_LIST_START
TEST_ENTRY (tcp_writealot)
TEST_HELPER (tcp_writealot, tcp4_echo_server)
+ TEST_ENTRY (tcp_open)
+ TEST_HELPER (tcp_open, tcp4_echo_server)
+
TEST_ENTRY (tcp_shutdown_after_write)
TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server)
@@ -253,10 +291,12 @@ TASK_LIST_START
TEST_ENTRY (tcp_close_while_connecting)
TEST_ENTRY (tcp_close)
TEST_ENTRY (tcp_flags)
- TEST_ENTRY (tcp_write_error)
TEST_ENTRY (tcp_write_to_half_open_connection)
TEST_ENTRY (tcp_unexpected_read)
+ TEST_ENTRY (tcp_read_stop)
+ TEST_HELPER (tcp_read_stop, tcp4_echo_server)
+
TEST_ENTRY (tcp_bind6_error_addrinuse)
TEST_ENTRY (tcp_bind6_error_addrnotavail)
TEST_ENTRY (tcp_bind6_error_fault)
@@ -271,6 +311,9 @@ TASK_LIST_START
TEST_ENTRY (udp_multicast_join)
TEST_ENTRY (udp_multicast_ttl)
+ TEST_ENTRY (udp_open)
+ TEST_HELPER (udp_open, udp4_echo_server)
+
TEST_ENTRY (pipe_bind_error_addrinuse)
TEST_ENTRY (pipe_bind_error_addrnotavail)
TEST_ENTRY (pipe_bind_error_inval)
@@ -295,6 +338,7 @@ TASK_LIST_START
TEST_ENTRY (timer)
TEST_ENTRY (timer_again)
TEST_ENTRY (timer_start_twice)
+ TEST_ENTRY (timer_order)
TEST_ENTRY (idle_starvation)
@@ -310,6 +354,7 @@ TASK_LIST_START
TEST_ENTRY (fs_event_ref)
TEST_ENTRY (tcp_ref)
TEST_ENTRY (tcp_ref2)
+ TEST_ENTRY (tcp_ref2b)
TEST_ENTRY (tcp_ref3)
TEST_HELPER (tcp_ref3, tcp4_echo_server)
TEST_ENTRY (tcp_ref4)
@@ -329,6 +374,10 @@ TASK_LIST_START
TEST_ENTRY (loop_handles)
TEST_ENTRY (walk_handles)
+ TEST_ENTRY (active)
+
+ TEST_ENTRY (embed)
+
TEST_ENTRY (async)
TEST_ENTRY (get_currentexe)
@@ -346,8 +395,6 @@ TASK_LIST_START
TEST_ENTRY (getaddrinfo_basic)
TEST_ENTRY (getaddrinfo_concurrent)
- TEST_ENTRY (gethostbyname)
-
TEST_ENTRY (getsockname_tcp)
TEST_ENTRY (getsockname_udp)
@@ -355,6 +402,7 @@ TASK_LIST_START
TEST_ENTRY (poll_unidirectional)
TEST_ENTRY (poll_close)
+ TEST_ENTRY (spawn_fails)
TEST_ENTRY (spawn_exit_code)
TEST_ENTRY (spawn_stdout)
TEST_ENTRY (spawn_stdin)
@@ -368,8 +416,10 @@ TASK_LIST_START
TEST_ENTRY (spawn_setuid_fails)
TEST_ENTRY (spawn_setgid_fails)
TEST_ENTRY (spawn_stdout_to_file)
+ TEST_ENTRY (spawn_auto_unref)
TEST_ENTRY (fs_poll)
TEST_ENTRY (kill)
+
#ifdef _WIN32
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
TEST_ENTRY (argument_escaping)
@@ -379,6 +429,9 @@ TASK_LIST_START
TEST_ENTRY (fs_stat_root)
#else
TEST_ENTRY (spawn_setuid_setgid)
+ TEST_ENTRY (we_get_signal)
+ TEST_ENTRY (we_get_signals)
+ TEST_ENTRY (signal_multiple_loops)
#endif
TEST_ENTRY (fs_file_noent)
@@ -393,6 +446,7 @@ TASK_LIST_START
TEST_ENTRY (fs_chown)
TEST_ENTRY (fs_utime)
TEST_ENTRY (fs_futime)
+ TEST_ENTRY (fs_readlink)
TEST_ENTRY (fs_symlink)
TEST_ENTRY (fs_symlink_dir)
TEST_ENTRY (fs_stat_missing_path)
@@ -412,13 +466,17 @@ TASK_LIST_START
TEST_ENTRY (fs_open_dir)
TEST_ENTRY (fs_rename_to_existing_file)
TEST_ENTRY (threadpool_queue_work_simple)
+ TEST_ENTRY (threadpool_queue_work_einval)
TEST_ENTRY (threadpool_multiple_event_loops)
+ TEST_ENTRY (threadpool_cancel_getaddrinfo)
+ TEST_ENTRY (threadpool_cancel_work)
+ TEST_ENTRY (threadpool_cancel_fs)
+ TEST_ENTRY (threadpool_cancel_single)
TEST_ENTRY (thread_mutex)
TEST_ENTRY (thread_rwlock)
TEST_ENTRY (thread_create)
TEST_ENTRY (strlcpy)
TEST_ENTRY (strlcat)
- TEST_ENTRY (counters_init)
TEST_ENTRY (dlerror)
#if 0
/* These are for testing the test runner. */
diff --git a/deps/uv/test/test-loop-handles.c b/deps/uv/test/test-loop-handles.c
index 9972dfa1f..fdf928147 100644
--- a/deps/uv/test/test-loop-handles.c
+++ b/deps/uv/test/test-loop-handles.c
@@ -312,7 +312,7 @@ TEST_IMPL(loop_handles) {
ASSERT(r == 0);
uv_unref((uv_handle_t*)&timer_handle);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(loop_iteration == ITERATIONS);
@@ -332,5 +332,6 @@ TEST_IMPL(loop_handles) {
ASSERT(idle_2_close_cb_called == idle_2_cb_started);
ASSERT(idle_2_is_active == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-loop-stop.c b/deps/uv/test/test-loop-stop.c
new file mode 100644
index 000000000..db52a094e
--- /dev/null
+++ b/deps/uv/test/test-loop-stop.c
@@ -0,0 +1,73 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_prepare_t prepare_handle;
+static uv_timer_t timer_handle;
+static int prepare_called = 0;
+static int timer_called = 0;
+static int num_ticks = 10;
+
+
+static void prepare_cb(uv_prepare_t* handle, int status) {
+ ASSERT(handle == &prepare_handle);
+ ASSERT(status == 0);
+ prepare_called++;
+ if (prepare_called == num_ticks)
+ uv_prepare_stop(handle);
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &timer_handle);
+ ASSERT(status == 0);
+ timer_called++;
+ if (timer_called == 1)
+ uv_stop(uv_default_loop());
+ else if (timer_called == num_ticks)
+ uv_timer_stop(handle);
+}
+
+
+TEST_IMPL(loop_stop) {
+ int r;
+ uv_prepare_init(uv_default_loop(), &prepare_handle);
+ uv_prepare_start(&prepare_handle, prepare_cb);
+ uv_timer_init(uv_default_loop(), &timer_handle);
+ uv_timer_start(&timer_handle, timer_cb, 100, 100);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r != 0);
+ ASSERT(timer_called == 1);
+
+ r = uv_run(uv_default_loop(), UV_RUN_NOWAIT);
+ ASSERT(r != 0);
+ ASSERT(prepare_called == 3);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+ ASSERT(timer_called == 10);
+ ASSERT(prepare_called == 10);
+
+ return 0;
+}
diff --git a/deps/uv/test/test-multiple-listen.c b/deps/uv/test/test-multiple-listen.c
index 0b5c887d6..4d52be12c 100644
--- a/deps/uv/test/test-multiple-listen.c
+++ b/deps/uv/test/test-multiple-listen.c
@@ -44,7 +44,7 @@ static void connection_cb(uv_stream_t* tcp, int status) {
}
-static void start_server() {
+static void start_server(void) {
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
int r;
@@ -71,7 +71,7 @@ static void connect_cb(uv_connect_t* req, int status) {
}
-static void client_connect() {
+static void client_connect(void) {
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
uv_connect_t* connect_req = malloc(sizeof *connect_req);
int r;
@@ -92,11 +92,12 @@ TEST_IMPL(multiple_listen) {
client_connect();
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(connection_cb_called == 1);
ASSERT(connect_cb_called == 1);
ASSERT(close_cb_called == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c
index 1bdcc3bc2..e5bf7c8bf 100644
--- a/deps/uv/test/test-ping-pong.c
+++ b/deps/uv/test/test-ping-pong.c
@@ -24,7 +24,6 @@
#include <stdlib.h>
#include <stdio.h>
-#include <string.h> /* strlen */
static int completed_pingers = 0;
@@ -48,14 +47,9 @@ typedef struct {
char read_buffer[BUFSIZE];
} pinger_t;
-void pinger_try_read(pinger_t* pinger);
-
static uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) {
- uv_buf_t buf;
- buf.base = (char*)malloc(size);
- buf.len = size;
- return buf;
+ return uv_buf_init(malloc(size), size);
}
@@ -80,11 +74,9 @@ static void pinger_write_ping(pinger_t* pinger) {
uv_write_t *req;
uv_buf_t buf;
- buf.base = (char*)&PING;
- buf.len = strlen(PING);
-
- req = malloc(sizeof(uv_write_t));
+ buf = uv_buf_init(PING, sizeof(PING) - 1);
+ req = malloc(sizeof(*req));
if (uv_write(req, (uv_stream_t*)&pinger->stream.tcp, &buf, 1, pinger_after_write)) {
FATAL("uv_write failed");
}
@@ -103,10 +95,7 @@ static void pinger_read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
ASSERT(uv_last_error(uv_default_loop()).code == UV_EOF);
puts("got EOF");
-
- if (buf.base) {
- free(buf.base);
- }
+ free(buf.base);
uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close);
@@ -117,17 +106,22 @@ static void pinger_read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
for (i = 0; i < nread; i++) {
ASSERT(buf.base[i] == PING[pinger->state]);
pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
- if (pinger->state == 0) {
- printf("PONG %d\n", pinger->pongs);
- pinger->pongs++;
- if (pinger->pongs < NUM_PINGS) {
- pinger_write_ping(pinger);
- } else {
- uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close);
- return;
- }
+
+ if (pinger->state != 0)
+ continue;
+
+ printf("PONG %d\n", pinger->pongs);
+ pinger->pongs++;
+
+ if (pinger->pongs < NUM_PINGS) {
+ pinger_write_ping(pinger);
+ } else {
+ uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close);
+ break;
}
}
+
+ free(buf.base);
}
@@ -149,7 +143,7 @@ static void pinger_on_connect(uv_connect_t *req, int status) {
/* same ping-pong test, but using IPv6 connection */
-static void tcp_pinger_v6_new() {
+static void tcp_pinger_v6_new(void) {
int r;
struct sockaddr_in6 server_addr = uv_ip6_addr("::1", TEST_PORT);
pinger_t *pinger;
@@ -174,7 +168,7 @@ static void tcp_pinger_v6_new() {
}
-static void tcp_pinger_new() {
+static void tcp_pinger_new(void) {
int r;
struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
pinger_t *pinger;
@@ -199,7 +193,7 @@ static void tcp_pinger_new() {
}
-static void pipe_pinger_new() {
+static void pipe_pinger_new(void) {
int r;
pinger_t *pinger;
@@ -225,29 +219,32 @@ static void pipe_pinger_new() {
TEST_IMPL(tcp_ping_pong) {
tcp_pinger_new();
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(completed_pingers == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(tcp_ping_pong_v6) {
tcp_pinger_v6_new();
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(completed_pingers == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(pipe_ping_pong) {
pipe_pinger_new();
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(completed_pingers == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-pipe-bind-error.c b/deps/uv/test/test-pipe-bind-error.c
index b84d20f1e..a07fa0f3b 100644
--- a/deps/uv/test/test-pipe-bind-error.c
+++ b/deps/uv/test/test-pipe-bind-error.c
@@ -67,10 +67,11 @@ TEST_IMPL(pipe_bind_error_addrinuse) {
uv_close((uv_handle_t*)&server1, close_cb);
uv_close((uv_handle_t*)&server2, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -88,10 +89,11 @@ TEST_IMPL(pipe_bind_error_addrnotavail) {
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -111,10 +113,11 @@ TEST_IMPL(pipe_bind_error_inval) {
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -132,9 +135,10 @@ TEST_IMPL(pipe_listen_without_bind) {
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-pipe-connect-error.c b/deps/uv/test/test-pipe-connect-error.c
index cc06d4293..fae1e1b29 100644
--- a/deps/uv/test/test-pipe-connect-error.c
+++ b/deps/uv/test/test-pipe-connect-error.c
@@ -68,11 +68,12 @@ TEST_IMPL(pipe_connect_bad_name) {
ASSERT(r == 0);
uv_pipe_connect(&req, &client, BAD_PIPENAME, connect_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
ASSERT(connect_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -87,10 +88,11 @@ TEST_IMPL(pipe_connect_to_file) {
ASSERT(r == 0);
uv_pipe_connect(&req, &client, path, connect_cb_file);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
ASSERT(connect_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-poll-close.c b/deps/uv/test/test-poll-close.c
index 4c3701bc8..70b775f2f 100644
--- a/deps/uv/test/test-poll-close.c
+++ b/deps/uv/test/test-poll-close.c
@@ -36,11 +36,6 @@
static int close_cb_called = 0;
-static void poll_cb_fail(uv_poll_t* handle, int status, int events) {
- ASSERT(0 && "poll_fail_cb should never be called");
-}
-
-
static void close_cb(uv_handle_t* handle) {
close_cb_called++;
}
@@ -69,9 +64,10 @@ TEST_IMPL(poll_close) {
uv_close((uv_handle_t*) &poll_handles[i], close_cb);
}
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == NUM_SOCKETS);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c
index 5a20b9d52..1ca9c9213 100644
--- a/deps/uv/test/test-poll.c
+++ b/deps/uv/test/test-poll.c
@@ -72,7 +72,7 @@ static int valid_writable_wakeups = 0;
static int spurious_writable_wakeups = 0;
-static int got_eagain() {
+static int got_eagain(void) {
#ifdef _WIN32
return WSAGetLastError() == WSAEWOULDBLOCK;
#else
@@ -205,7 +205,7 @@ static void destroy_connection_context(connection_context_t* context) {
static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
connection_context_t* context = (connection_context_t*) handle->data;
- int new_events;
+ unsigned int new_events;
int r;
ASSERT(status == 0);
@@ -495,7 +495,7 @@ static void server_poll_cb(uv_poll_t* handle, int status, int events) {
}
-static void start_server() {
+static void start_server(void) {
uv_os_sock_t sock;
server_context_t* context;
int r;
@@ -511,7 +511,7 @@ static void start_server() {
}
-static void start_client() {
+static void start_client(void) {
uv_os_sock_t sock;
connection_context_t* context;
struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
@@ -531,7 +531,7 @@ static void start_client() {
}
-static void start_poll_test() {
+static void start_poll_test(void) {
int i, r;
#ifdef _WIN32
@@ -547,7 +547,7 @@ static void start_poll_test() {
for (i = 0; i < NUM_CLIENTS; i++)
start_client();
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
/* Assert that at most five percent of the writable wakeups was spurious. */
@@ -556,6 +556,8 @@ static void start_poll_test() {
spurious_writable_wakeups > 20);
ASSERT(closed_connections == NUM_CLIENTS * 2);
+
+ MAKE_VALGRIND_HAPPY();
}
diff --git a/deps/uv/test/test-ref.c b/deps/uv/test/test-ref.c
index e0c38858e..9fc214ab6 100644
--- a/deps/uv/test/test-ref.c
+++ b/deps/uv/test/test-ref.c
@@ -36,6 +36,21 @@ static int req_cb_called;
static int connect_cb_called;
static int write_cb_called;
static int shutdown_cb_called;
+static int close_cb_called;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void do_close(void* handle) {
+ close_cb_called = 0;
+ uv_close((uv_handle_t*)handle, close_cb);
+ ASSERT(close_cb_called == 0);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(close_cb_called == 1);
+}
static void fail_cb(void) {
@@ -43,6 +58,11 @@ static void fail_cb(void) {
}
+static void fail_cb2(void) {
+ ASSERT(0 && "fail_cb2 should not have been called");
+}
+
+
static void req_cb(uv_handle_t* req, int status) {
req_cb_called++;
}
@@ -80,7 +100,8 @@ static void connect_and_shutdown(uv_connect_t* req, int status) {
TEST_IMPL(ref) {
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -88,9 +109,11 @@ TEST_IMPL(ref) {
TEST_IMPL(idle_ref) {
uv_idle_t h;
uv_idle_init(uv_default_loop(), &h);
- uv_idle_start(&h, NULL);
+ uv_idle_start(&h, (uv_idle_cb) fail_cb2);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -99,7 +122,9 @@ TEST_IMPL(async_ref) {
uv_async_t h;
uv_async_init(uv_default_loop(), &h, NULL);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -107,9 +132,11 @@ TEST_IMPL(async_ref) {
TEST_IMPL(prepare_ref) {
uv_prepare_t h;
uv_prepare_init(uv_default_loop(), &h);
- uv_prepare_start(&h, NULL);
+ uv_prepare_start(&h, (uv_prepare_cb) fail_cb2);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -117,9 +144,11 @@ TEST_IMPL(prepare_ref) {
TEST_IMPL(check_ref) {
uv_check_t h;
uv_check_init(uv_default_loop(), &h);
- uv_check_start(&h, NULL);
+ uv_check_start(&h, (uv_check_cb) fail_cb2);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -135,7 +164,9 @@ TEST_IMPL(unref_in_prepare_cb) {
uv_prepare_t h;
uv_prepare_init(uv_default_loop(), &h);
uv_prepare_start(&h, prepare_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -144,7 +175,9 @@ TEST_IMPL(timer_ref) {
uv_timer_t h;
uv_timer_init(uv_default_loop(), &h);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -154,7 +187,9 @@ TEST_IMPL(timer_ref2) {
uv_timer_init(uv_default_loop(), &h);
uv_timer_start(&h, (uv_timer_cb)fail_cb, 42, 42);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -163,7 +198,9 @@ TEST_IMPL(fs_event_ref) {
uv_fs_event_t h;
uv_fs_event_init(uv_default_loop(), &h, ".", (uv_fs_event_cb)fail_cb, 0);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -173,7 +210,9 @@ TEST_IMPL(fs_poll_ref) {
uv_fs_poll_init(uv_default_loop(), &h);
uv_fs_poll_start(&h, NULL, ".", 999);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -182,7 +221,9 @@ TEST_IMPL(tcp_ref) {
uv_tcp_t h;
uv_tcp_init(uv_default_loop(), &h);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -192,7 +233,22 @@ TEST_IMPL(tcp_ref2) {
uv_tcp_init(uv_default_loop(), &h);
uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_ref2b) {
+ uv_tcp_t h;
+ uv_tcp_init(uv_default_loop(), &h);
+ uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
+ uv_unref((uv_handle_t*)&h);
+ uv_close((uv_handle_t*)&h, close_cb);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -203,9 +259,11 @@ TEST_IMPL(tcp_ref3) {
uv_tcp_init(uv_default_loop(), &h);
uv_tcp_connect(&connect_req, &h, addr, connect_and_shutdown);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(connect_cb_called == 1);
ASSERT(shutdown_cb_called == 1);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -216,10 +274,12 @@ TEST_IMPL(tcp_ref4) {
uv_tcp_init(uv_default_loop(), &h);
uv_tcp_connect(&connect_req, &h, addr, connect_and_write);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(connect_cb_called == 1);
ASSERT(write_cb_called == 1);
ASSERT(shutdown_cb_called == 1);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -228,7 +288,9 @@ TEST_IMPL(udp_ref) {
uv_udp_t h;
uv_udp_init(uv_default_loop(), &h);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -240,7 +302,9 @@ TEST_IMPL(udp_ref2) {
uv_udp_bind(&h, addr, 0);
uv_udp_recv_start(&h, (uv_alloc_cb)fail_cb, (uv_udp_recv_cb)fail_cb);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -254,9 +318,11 @@ TEST_IMPL(udp_ref3) {
uv_udp_init(uv_default_loop(), &h);
uv_udp_send(&req, &h, &buf, 1, addr, (uv_udp_send_cb)req_cb);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(req_cb_called == 1);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -265,7 +331,9 @@ TEST_IMPL(pipe_ref) {
uv_pipe_t h;
uv_pipe_init(uv_default_loop(), &h, 0);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -275,7 +343,9 @@ TEST_IMPL(pipe_ref2) {
uv_pipe_init(uv_default_loop(), &h, 0);
uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -285,9 +355,11 @@ TEST_IMPL(pipe_ref3) {
uv_pipe_init(uv_default_loop(), &h, 0);
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_shutdown);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(connect_cb_called == 1);
ASSERT(shutdown_cb_called == 1);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -297,10 +369,12 @@ TEST_IMPL(pipe_ref4) {
uv_pipe_init(uv_default_loop(), &h, 0);
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_write);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(connect_cb_called == 1);
ASSERT(write_cb_called == 1);
ASSERT(shutdown_cb_called == 1);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -329,10 +403,13 @@ TEST_IMPL(process_ref) {
ASSERT(r == 0);
uv_unref((uv_handle_t*)&h);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
r = uv_process_kill(&h, /* SIGTERM */ 15);
ASSERT(r == 0);
+ do_close(&h);
+
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-run-nowait.c b/deps/uv/test/test-run-nowait.c
new file mode 100644
index 000000000..ee4b36ff3
--- /dev/null
+++ b/deps/uv/test/test-run-nowait.c
@@ -0,0 +1,46 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_timer_t timer_handle;
+static int timer_called = 0;
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &timer_handle);
+ ASSERT(status == 0);
+ timer_called = 1;
+}
+
+
+TEST_IMPL(run_nowait) {
+ int r;
+ uv_timer_init(uv_default_loop(), &timer_handle);
+ uv_timer_start(&timer_handle, timer_cb, 100, 100);
+
+ r = uv_run(uv_default_loop(), UV_RUN_NOWAIT);
+ ASSERT(r != 0);
+ ASSERT(timer_called == 0);
+
+ return 0;
+}
diff --git a/deps/uv/test/test-run-once.c b/deps/uv/test/test-run-once.c
index f74e9f37a..e243de0ad 100644
--- a/deps/uv/test/test-run-once.c
+++ b/deps/uv/test/test-run-once.c
@@ -41,8 +41,9 @@ TEST_IMPL(run_once) {
uv_idle_init(uv_default_loop(), &idle_handle);
uv_idle_start(&idle_handle, idle_cb);
- while (uv_run_once(uv_default_loop()));
+ while (uv_run(uv_default_loop(), UV_RUN_ONCE));
ASSERT(idle_counter == NUM_TICKS);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-shutdown-close.c b/deps/uv/test/test-shutdown-close.c
index eabbefc60..62596b930 100644
--- a/deps/uv/test/test-shutdown-close.c
+++ b/deps/uv/test/test-shutdown-close.c
@@ -37,9 +37,9 @@ static int close_cb_called = 0;
static void shutdown_cb(uv_shutdown_t* req, int status) {
+ int err = uv_last_error(uv_default_loop()).code;
ASSERT(req == &shutdown_req);
- ASSERT(status == 0 ||
- (status == -1 && uv_last_error(uv_default_loop()).code == UV_EINTR));
+ ASSERT(status == 0 || (status == -1 && err == UV_ECANCELED));
shutdown_cb_called++;
}
@@ -74,13 +74,14 @@ TEST_IMPL(shutdown_close_tcp) {
ASSERT(r == 0);
r = uv_tcp_connect(&connect_req, &h, addr, connect_cb);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(connect_cb_called == 1);
ASSERT(shutdown_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -92,12 +93,13 @@ TEST_IMPL(shutdown_close_pipe) {
r = uv_pipe_init(uv_default_loop(), &h, 0);
ASSERT(r == 0);
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_cb);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(connect_cb_called == 1);
ASSERT(shutdown_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-shutdown-eof.c b/deps/uv/test/test-shutdown-eof.c
index 9d4f2cce7..017525cda 100644
--- a/deps/uv/test/test-shutdown-eof.c
+++ b/deps/uv/test/test-shutdown-eof.c
@@ -110,7 +110,7 @@ static void connect_cb(uv_connect_t *req, int status) {
}
-void tcp_close_cb(uv_handle_t* handle) {
+static void tcp_close_cb(uv_handle_t* handle) {
ASSERT(handle == (uv_handle_t*) &tcp);
ASSERT(called_connect_cb == 1);
@@ -122,13 +122,13 @@ void tcp_close_cb(uv_handle_t* handle) {
}
-void timer_close_cb(uv_handle_t* handle) {
+static void timer_close_cb(uv_handle_t* handle) {
ASSERT(handle == (uv_handle_t*) &timer);
called_timer_close_cb++;
}
-void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle, int status) {
ASSERT(handle == &timer);
uv_close((uv_handle_t*) handle, timer_close_cb);
@@ -168,7 +168,7 @@ TEST_IMPL(shutdown_eof) {
r = uv_tcp_connect(&connect_req, &tcp, server_addr, connect_cb);
ASSERT(!r);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(called_connect_cb == 1);
ASSERT(called_shutdown_cb == 1);
@@ -178,6 +178,7 @@ TEST_IMPL(shutdown_eof) {
ASSERT(called_timer_close_cb == 1);
ASSERT(called_timer_cb == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-signal-multiple-loops.c b/deps/uv/test/test-signal-multiple-loops.c
new file mode 100644
index 000000000..c43e02b78
--- /dev/null
+++ b/deps/uv/test/test-signal-multiple-loops.c
@@ -0,0 +1,270 @@
+/* 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.
+ */
+
+
+/* This test does not pretend to be cross-platform. */
+#ifndef _WIN32
+
+#include "uv.h"
+#include "task.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#define NUM_SIGNAL_HANDLING_THREADS 25
+#define NUM_LOOP_CREATING_THREADS 10
+
+
+static uv_sem_t sem;
+static uv_mutex_t counter_lock;
+static volatile int stop = 0;
+
+static volatile int signal1_cb_counter = 0;
+static volatile int signal2_cb_counter = 0;
+static volatile int loop_creation_counter = 0;
+
+
+static void increment_counter(volatile int* counter) {
+ uv_mutex_lock(&counter_lock);
+ ++(*counter);
+ uv_mutex_unlock(&counter_lock);
+}
+
+
+static void signal1_cb(uv_signal_t* handle, int signum) {
+ ASSERT(signum == SIGUSR1);
+ increment_counter(&signal1_cb_counter);
+ uv_signal_stop(handle);
+}
+
+
+static void signal2_cb(uv_signal_t* handle, int signum) {
+ ASSERT(signum == SIGUSR2);
+ increment_counter(&signal2_cb_counter);
+ uv_signal_stop(handle);
+}
+
+
+static void signal_handling_worker(void* context) {
+ uintptr_t mask = (uintptr_t) context;
+ uv_loop_t* loop;
+ uv_signal_t signal1a;
+ uv_signal_t signal1b;
+ uv_signal_t signal2;
+ int r;
+
+ loop = uv_loop_new();
+ ASSERT(loop != NULL);
+
+ /* Setup the signal watchers and start them. */
+ if (mask & SIGUSR1) {
+ r = uv_signal_init(loop, &signal1a);
+ ASSERT(r == 0);
+ r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1);
+ ASSERT(r == 0);
+ r = uv_signal_init(loop, &signal1b);
+ ASSERT(r == 0);
+ r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1);
+ ASSERT(r == 0);
+ }
+ if (mask & SIGUSR2) {
+ r = uv_signal_init(loop, &signal2);
+ ASSERT(r == 0);
+ r = uv_signal_start(&signal2, signal2_cb, SIGUSR2);
+ ASSERT(r == 0);
+ }
+
+ /* Signal watchers are now set up. */
+ uv_sem_post(&sem);
+
+ /* Wait for all signals. The signal callbacks stop the watcher, so uv_run
+ * will return when all signal watchers caught a signal.
+ */
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ /* Restart the signal watchers. */
+ if (mask & SIGUSR1) {
+ r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1);
+ ASSERT(r == 0);
+ r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1);
+ ASSERT(r == 0);
+ }
+ if (mask & SIGUSR2) {
+ r = uv_signal_start(&signal2, signal2_cb, SIGUSR2);
+ ASSERT(r == 0);
+ }
+
+ /* Wait for signals once more. */
+ uv_sem_post(&sem);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ /* Close the watchers. */
+ if (mask & SIGUSR1) {
+ uv_close((uv_handle_t*) &signal1a, NULL);
+ uv_close((uv_handle_t*) &signal1b, NULL);
+ }
+ if (mask & SIGUSR2) {
+ uv_close((uv_handle_t*) &signal2, NULL);
+ }
+
+ /* Wait for the signal watchers to close. */
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ uv_loop_delete(loop);
+}
+
+
+static void signal_unexpected_cb(uv_signal_t* handle, int signum) {
+ ASSERT(0 && "signal_unexpected_cb should never be called");
+}
+
+
+static void loop_creating_worker(void* context) {
+ (void) context;
+
+ do {
+ uv_loop_t* loop;
+ uv_signal_t signal;
+ int r;
+
+ loop = uv_loop_new();
+ ASSERT(loop != NULL);
+
+ r = uv_signal_init(loop, &signal);
+ ASSERT(r == 0);
+
+ r = uv_signal_start(&signal, signal_unexpected_cb, SIGTERM);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*) &signal, NULL);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ uv_loop_delete(loop);
+
+ increment_counter(&loop_creation_counter);
+ } while (!stop);
+}
+
+
+TEST_IMPL(signal_multiple_loops) {
+ int i, r;
+ uv_thread_t loop_creating_threads[NUM_LOOP_CREATING_THREADS];
+ uv_thread_t signal_handling_threads[NUM_SIGNAL_HANDLING_THREADS];
+ sigset_t sigset;
+
+ r = uv_sem_init(&sem, 0);
+ ASSERT(r == 0);
+
+ r = uv_mutex_init(&counter_lock);
+ ASSERT(r == 0);
+
+ /* Create a couple of threads that create a destroy loops continuously. */
+ for (i = 0; i < NUM_LOOP_CREATING_THREADS; i++) {
+ r = uv_thread_create(&loop_creating_threads[i],
+ loop_creating_worker,
+ NULL);
+ ASSERT(r == 0);
+ }
+
+ /* Create a couple of threads that actually handle signals. */
+ for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) {
+ uintptr_t mask;
+
+ switch (i % 3) {
+ case 0: mask = SIGUSR1; break;
+ case 1: mask = SIGUSR2; break;
+ case 2: mask = SIGUSR1 | SIGUSR2; break;
+ }
+
+ r = uv_thread_create(&signal_handling_threads[i],
+ signal_handling_worker,
+ (void*) mask);
+ ASSERT(r == 0);
+ }
+
+ /* Wait until all threads have started and set up their signal watchers. */
+ for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++)
+ uv_sem_wait(&sem);
+
+ r = kill(getpid(), SIGUSR1);
+ ASSERT(r == 0);
+ r = kill(getpid(), SIGUSR2);
+ ASSERT(r == 0);
+
+ /* Wait for all threads to handle these signals. */
+ for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++)
+ uv_sem_wait(&sem);
+
+ /* Block all signals to this thread, so we are sure that from here the signal
+ * handler runs in another thread. This is is more likely to catch thread and
+ * signal safety issues if there are any.
+ */
+ sigfillset(&sigset);
+ pthread_sigmask(SIG_SETMASK, &sigset, NULL);
+
+ r = kill(getpid(), SIGUSR1);
+ ASSERT(r == 0);
+ r = kill(getpid(), SIGUSR2);
+ ASSERT(r == 0);
+
+ /* Wait for all signal handling threads to exit. */
+ for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) {
+ r = uv_thread_join(&signal_handling_threads[i]);
+ ASSERT(r == 0);
+ }
+
+ /* Tell all loop creating threads to stop. */
+ stop = 1;
+
+ /* Wait for all loop creating threads to exit. */
+ for (i = 0; i < NUM_LOOP_CREATING_THREADS; i++) {
+ r = uv_thread_join(&loop_creating_threads[i]);
+ ASSERT(r == 0);
+ }
+
+ printf("signal1_cb calls: %d\n", signal1_cb_counter);
+ printf("signal2_cb calls: %d\n", signal2_cb_counter);
+ printf("loops created and destroyed: %d\n", loop_creation_counter);
+
+ ASSERT(signal1_cb_counter == 4 * NUM_SIGNAL_HANDLING_THREADS);
+ ASSERT(signal2_cb_counter == 2 * NUM_SIGNAL_HANDLING_THREADS);
+ /* We don't know exactly how much loops will be created and destroyed, but at
+ * least there should be 1 for every loop creating thread.
+ */
+ ASSERT(loop_creation_counter >= NUM_LOOP_CREATING_THREADS);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* !_WIN32 */
diff --git a/deps/uv/test/test-signal.c b/deps/uv/test/test-signal.c
new file mode 100644
index 000000000..9fb1c7f91
--- /dev/null
+++ b/deps/uv/test/test-signal.c
@@ -0,0 +1,152 @@
+/* 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.
+ */
+
+
+/* This test does not pretend to be cross-platform. */
+#ifndef _WIN32
+
+#include "uv.h"
+#include "task.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define NSIGNALS 10
+
+struct timer_ctx {
+ unsigned int ncalls;
+ uv_timer_t handle;
+ int signum;
+};
+
+struct signal_ctx {
+ enum { CLOSE, STOP } stop_or_close;
+ unsigned int ncalls;
+ uv_signal_t handle;
+ int signum;
+};
+
+
+static void signal_cb(uv_signal_t* handle, int signum) {
+ struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle);
+ ASSERT(signum == ctx->signum);
+
+ if (++ctx->ncalls == NSIGNALS) {
+ if (ctx->stop_or_close == STOP)
+ uv_signal_stop(handle);
+ else if (ctx->stop_or_close == CLOSE)
+ uv_close((uv_handle_t*)handle, NULL);
+ else
+ ASSERT(0);
+ }
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle);
+
+ raise(ctx->signum);
+
+ if (++ctx->ncalls == NSIGNALS)
+ uv_close((uv_handle_t*)handle, NULL);
+}
+
+
+static void start_watcher(uv_loop_t* loop, int signum, struct signal_ctx* ctx) {
+ ctx->ncalls = 0;
+ ctx->signum = signum;
+ ctx->stop_or_close = CLOSE;
+ ASSERT(0 == uv_signal_init(loop, &ctx->handle));
+ ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum));
+}
+
+
+static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) {
+ ctx->ncalls = 0;
+ ctx->signum = signum;
+ ASSERT(0 == uv_timer_init(loop, &ctx->handle));
+ ASSERT(0 == uv_timer_start(&ctx->handle, timer_cb, 5, 5));
+}
+
+
+TEST_IMPL(we_get_signal) {
+ struct signal_ctx sc;
+ struct timer_ctx tc;
+ uv_loop_t* loop;
+
+ loop = uv_default_loop();
+ start_timer(loop, SIGCHLD, &tc);
+ start_watcher(loop, SIGCHLD, &sc);
+ sc.stop_or_close = STOP; /* stop, don't close the signal handle */
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc.ncalls == NSIGNALS);
+
+ start_timer(loop, SIGCHLD, &tc);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc.ncalls == NSIGNALS);
+
+ sc.ncalls = 0;
+ sc.stop_or_close = CLOSE; /* now close it when it's done */
+ uv_signal_start(&sc.handle, signal_cb, SIGCHLD);
+
+ start_timer(loop, SIGCHLD, &tc);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc.ncalls == NSIGNALS);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(we_get_signals) {
+ struct signal_ctx sc[4];
+ struct timer_ctx tc[2];
+ uv_loop_t* loop;
+ unsigned int i;
+
+ loop = uv_default_loop();
+ start_watcher(loop, SIGUSR1, sc + 0);
+ start_watcher(loop, SIGUSR1, sc + 1);
+ start_watcher(loop, SIGUSR2, sc + 2);
+ start_watcher(loop, SIGUSR2, sc + 3);
+ start_timer(loop, SIGUSR1, tc + 0);
+ start_timer(loop, SIGUSR2, tc + 1);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ for (i = 0; i < ARRAY_SIZE(sc); i++)
+ ASSERT(sc[i].ncalls == NSIGNALS);
+
+ for (i = 0; i < ARRAY_SIZE(tc); i++)
+ ASSERT(tc[i].ncalls == NSIGNALS);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* _WIN32 */
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index 43e801007..56eca9c58 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -65,18 +65,12 @@ static void exit_cb_failure_expected(uv_process_t* process, int exit_status,
int term_signal) {
printf("exit_cb\n");
exit_cb_called++;
- ASSERT(exit_status == 127);
+ ASSERT(exit_status == -1);
ASSERT(term_signal == 0);
uv_close((uv_handle_t*)process, close_cb);
}
-static void exit_cb_unexpected(uv_process_t* process, int exit_status,
- int term_signal) {
- ASSERT(0 && "should not have been called");
-}
-
-
static void kill_cb(uv_process_t* process, int exit_status, int term_signal) {
uv_err_t err;
@@ -112,7 +106,7 @@ static uv_buf_t on_alloc(uv_handle_t* handle, size_t suggested_size) {
}
-void on_read(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
+static void on_read(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
uv_err_t err = uv_last_error(uv_default_loop());
if (nread > 0) {
@@ -124,7 +118,7 @@ void on_read(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
}
-void write_cb(uv_write_t* req, int status) {
+static void write_cb(uv_write_t* req, int status) {
ASSERT(status == 0);
uv_close((uv_handle_t*)req->handle, close_cb);
}
@@ -151,6 +145,19 @@ static void timer_cb(uv_timer_t* handle, int status) {
}
+TEST_IMPL(spawn_fails) {
+ init_process_options("", exit_cb_failure_expected);
+ options.file = options.args[0] = "program-that-had-better-not-exist";
+ ASSERT(0 == uv_spawn(uv_default_loop(), &process, options));
+ ASSERT(0 != uv_is_active((uv_handle_t*)&process));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOENT);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(spawn_exit_code) {
int r;
@@ -159,12 +166,13 @@ TEST_IMPL(spawn_exit_code) {
r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -189,7 +197,7 @@ TEST_IMPL(spawn_stdout) {
r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
@@ -197,6 +205,7 @@ TEST_IMPL(spawn_stdout) {
printf("output is: %s", output);
ASSERT(strcmp("hello world\n", output) == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -228,7 +237,7 @@ TEST_IMPL(spawn_stdout_to_file) {
r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
@@ -249,6 +258,7 @@ TEST_IMPL(spawn_stdout_to_file) {
/* Cleanup. */
unlink("stdout_file");
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -284,13 +294,14 @@ TEST_IMPL(spawn_stdin) {
r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 3); /* Once for process twice for the pipe. */
ASSERT(strcmp(buffer, output) == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -317,7 +328,7 @@ TEST_IMPL(spawn_stdio_greater_than_3) {
r = uv_read_start((uv_stream_t*) &pipe, on_alloc, on_read);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
@@ -325,6 +336,7 @@ TEST_IMPL(spawn_stdio_greater_than_3) {
printf("output from stdio[3] is: %s", output);
ASSERT(strcmp("fourth stdio!\n", output) == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -340,12 +352,13 @@ TEST_IMPL(spawn_ignored_stdio) {
r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -364,12 +377,13 @@ TEST_IMPL(spawn_and_kill) {
r = uv_timer_start(&timer, timer_cb, 500, 0);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 2); /* Once for process and once for timer. */
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -400,7 +414,7 @@ TEST_IMPL(spawn_preserve_env) {
r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
@@ -409,6 +423,7 @@ TEST_IMPL(spawn_preserve_env) {
printf("output is: %s", output);
ASSERT(strcmp("testval", output) == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -426,7 +441,7 @@ TEST_IMPL(spawn_detached) {
uv_unref((uv_handle_t*)&process);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 0);
@@ -437,6 +452,7 @@ TEST_IMPL(spawn_detached) {
err = uv_kill(process.pid, 15);
ASSERT(err.code == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -488,12 +504,13 @@ TEST_IMPL(spawn_and_kill_with_std) {
r = uv_timer_start(&timer, timer_cb, 500, 0);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 5); /* process x 1, timer x 1, stdio x 3. */
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -534,12 +551,13 @@ TEST_IMPL(spawn_and_ping) {
ASSERT(exit_cb_called == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(strcmp(output, "TEST") == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -567,12 +585,13 @@ TEST_IMPL(kill) {
err = uv_kill(process.pid, /* SIGTERM */ 15);
ASSERT(err.code == UV_OK);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -612,7 +631,7 @@ TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
@@ -620,15 +639,16 @@ TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
printf("output is: %s", output);
ASSERT(strcmp("hello world\n", output) == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
-wchar_t* make_program_args(char** args, int verbatim_arguments);
-wchar_t* quote_cmd_arg(const wchar_t *source, wchar_t *target);
+uv_err_t make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr);
+WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target);
TEST_IMPL(argument_escaping) {
- const wchar_t* test_str[] = {
+ const WCHAR* test_str[] = {
L"HelloWorld",
L"Hello World",
L"Hello\"World",
@@ -640,12 +660,13 @@ TEST_IMPL(argument_escaping) {
L"c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\""
};
const int count = sizeof(test_str) / sizeof(*test_str);
- wchar_t** test_output;
- wchar_t* command_line;
- wchar_t** cracked;
+ WCHAR** test_output;
+ WCHAR* command_line;
+ WCHAR** cracked;
size_t total_size = 0;
int i;
int num_args;
+ uv_err_t result;
char* verbatim[] = {
"cmd.exe",
@@ -653,18 +674,18 @@ TEST_IMPL(argument_escaping) {
"c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"",
NULL
};
- wchar_t* verbatim_output;
- wchar_t* non_verbatim_output;
+ WCHAR* verbatim_output;
+ WCHAR* non_verbatim_output;
- test_output = calloc(count, sizeof(wchar_t*));
+ test_output = calloc(count, sizeof(WCHAR*));
for (i = 0; i < count; ++i) {
- test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(wchar_t));
+ test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR));
quote_cmd_arg(test_str[i], test_output[i]);
wprintf(L"input : %s\n", test_str[i]);
wprintf(L"output: %s\n", test_output[i]);
total_size += wcslen(test_output[i]) + 1;
}
- command_line = calloc(total_size + 1, sizeof(wchar_t));
+ command_line = calloc(total_size + 1, sizeof(WCHAR));
for (i = 0; i < count; ++i) {
wcscat(command_line, test_output[i]);
wcscat(command_line, L" ");
@@ -684,8 +705,10 @@ TEST_IMPL(argument_escaping) {
free(test_output[i]);
}
- verbatim_output = make_program_args(verbatim, 1);
- non_verbatim_output = make_program_args(verbatim, 0);
+ result = make_program_args(verbatim, 1, &verbatim_output);
+ ASSERT(result.code == UV_OK);
+ result = make_program_args(verbatim, 0, &non_verbatim_output);
+ ASSERT(result.code == UV_OK);
wprintf(L" verbatim_output: %s\n", verbatim_output);
wprintf(L"non_verbatim_output: %s\n", non_verbatim_output);
@@ -699,7 +722,7 @@ TEST_IMPL(argument_escaping) {
return 0;
}
-wchar_t* make_program_env(char** env_block);
+uv_err_t make_program_env(char** env_block, WCHAR** dst_ptr);
TEST_IMPL(environment_creation) {
int i;
@@ -712,33 +735,35 @@ TEST_IMPL(environment_creation) {
NULL
};
- wchar_t expected[512];
- wchar_t* ptr = expected;
- wchar_t* result;
- wchar_t* str;
+ WCHAR expected[512];
+ WCHAR* ptr = expected;
+ uv_err_t result;
+ WCHAR* str;
+ WCHAR* env;
for (i = 0; i < sizeof(environment) / sizeof(environment[0]) - 1; i++) {
ptr += uv_utf8_to_utf16(environment[i], ptr, expected + sizeof(expected) - ptr);
}
memcpy(ptr, L"SYSTEMROOT=", sizeof(L"SYSTEMROOT="));
- ptr += sizeof(L"SYSTEMROOT=")/sizeof(wchar_t) - 1;
+ ptr += sizeof(L"SYSTEMROOT=")/sizeof(WCHAR) - 1;
ptr += GetEnvironmentVariableW(L"SYSTEMROOT", ptr, expected + sizeof(expected) - ptr);
++ptr;
memcpy(ptr, L"SYSTEMDRIVE=", sizeof(L"SYSTEMDRIVE="));
- ptr += sizeof(L"SYSTEMDRIVE=")/sizeof(wchar_t) - 1;
+ ptr += sizeof(L"SYSTEMDRIVE=")/sizeof(WCHAR) - 1;
ptr += GetEnvironmentVariableW(L"SYSTEMDRIVE", ptr, expected + sizeof(expected) - ptr);
++ptr;
*ptr = '\0';
- result = make_program_env(environment);
+ result = make_program_env(environment, &env);
+ ASSERT(result.code == UV_OK);
- for (str = result; *str; str += wcslen(str) + 1) {
+ for (str = env; *str; str += wcslen(str) + 1) {
wprintf(L"%s\n", str);
}
- ASSERT(wcscmp(expected, result) == 0);
+ ASSERT(wcscmp(expected, env) == 0);
return 0;
}
@@ -768,12 +793,13 @@ TEST_IMPL(spawn_setuid_setgid) {
r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
#endif
@@ -801,12 +827,13 @@ TEST_IMPL(spawn_setuid_fails) {
r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -832,18 +859,27 @@ TEST_IMPL(spawn_setgid_fails) {
r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
#endif
#ifdef _WIN32
+
+static void exit_cb_unexpected(uv_process_t* process,
+ int exit_status,
+ int term_signal) {
+ ASSERT(0 && "should not have been called");
+}
+
+
TEST_IMPL(spawn_setuid_fails) {
int r;
@@ -856,11 +892,12 @@ TEST_IMPL(spawn_setuid_fails) {
ASSERT(r == -1);
ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOTSUP);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(close_cb_called == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -877,11 +914,25 @@ TEST_IMPL(spawn_setgid_fails) {
ASSERT(r == -1);
ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOTSUP);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(close_cb_called == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
#endif
+
+
+TEST_IMPL(spawn_auto_unref) {
+ init_process_options("spawn_helper1", NULL);
+ ASSERT(0 == uv_spawn(uv_default_loop(), &process, options));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &process));
+ uv_close((uv_handle_t*) &process, NULL);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(0 != uv_is_closing((uv_handle_t*) &process));
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-stdio-over-pipes.c b/deps/uv/test/test-stdio-over-pipes.c
index 7603027fb..923bf76bf 100644
--- a/deps/uv/test/test-stdio-over-pipes.c
+++ b/deps/uv/test/test-stdio-over-pipes.c
@@ -34,7 +34,8 @@ static int close_cb_called;
static int exit_cb_called;
static int on_read_cb_called;
static int after_write_cb_called;
-uv_pipe_t out, in;
+static uv_pipe_t in;
+static uv_pipe_t out;
static uv_loop_t* loop;
#define OUTPUT_SIZE 1024
static char output[OUTPUT_SIZE];
@@ -137,7 +138,7 @@ TEST_IMPL(stdio_over_pipes) {
r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(on_read_cb_called > 1);
@@ -147,6 +148,7 @@ TEST_IMPL(stdio_over_pipes) {
ASSERT(memcmp("hello world\n", output, 12) == 0);
ASSERT(output_used == 12);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -181,7 +183,7 @@ static uv_buf_t on_read_alloc(uv_handle_t* handle, size_t suggested_size) {
}
-int stdio_over_pipes_helper() {
+int stdio_over_pipes_helper(void) {
/* Write several buffers to test that the write order is preserved. */
char* buffers[] = {
"he",
@@ -195,7 +197,8 @@ int stdio_over_pipes_helper() {
uv_write_t write_req[ARRAY_SIZE(buffers)];
uv_buf_t buf[ARRAY_SIZE(buffers)];
- int r, i;
+ unsigned int i;
+ int r;
uv_loop_t* loop = uv_default_loop();
ASSERT(UV_NAMED_PIPE == uv_guess_handle(0));
@@ -223,7 +226,7 @@ int stdio_over_pipes_helper() {
ASSERT(r == 0);
}
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(after_write_called == 7);
ASSERT(on_pipe_read_called == 0);
@@ -236,11 +239,12 @@ int stdio_over_pipes_helper() {
on_pipe_read);
ASSERT(r == 0);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
ASSERT(after_write_called == 7);
ASSERT(on_pipe_read_called == 1);
ASSERT(close_cb_called == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-bind-error.c b/deps/uv/test/test-tcp-bind-error.c
index 9512519ac..424953568 100644
--- a/deps/uv/test/test-tcp-bind-error.c
+++ b/deps/uv/test/test-tcp-bind-error.c
@@ -59,10 +59,11 @@ TEST_IMPL(tcp_bind_error_addrinuse) {
uv_close((uv_handle_t*)&server1, close_cb);
uv_close((uv_handle_t*)&server2, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -83,10 +84,11 @@ TEST_IMPL(tcp_bind_error_addrnotavail_1) {
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -104,10 +106,11 @@ TEST_IMPL(tcp_bind_error_addrnotavail_2) {
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -125,14 +128,15 @@ TEST_IMPL(tcp_bind_error_fault) {
r = uv_tcp_bind(&server, *garbage_addr);
ASSERT(r == -1);
- ASSERT(uv_last_error(uv_default_loop()).code == UV_EFAULT);
+ ASSERT(uv_last_error(uv_default_loop()).code == UV_EINVAL);
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -155,10 +159,11 @@ TEST_IMPL(tcp_bind_error_inval) {
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -174,6 +179,7 @@ TEST_IMPL(tcp_bind_localhost_ok) {
r = uv_tcp_bind(&server, addr);
ASSERT(r == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -187,5 +193,6 @@ TEST_IMPL(tcp_listen_without_bind) {
r = uv_listen((uv_stream_t*)&server, 128, NULL);
ASSERT(r == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-bind6-error.c b/deps/uv/test/test-tcp-bind6-error.c
index 5a8b76363..61afc7f19 100644
--- a/deps/uv/test/test-tcp-bind6-error.c
+++ b/deps/uv/test/test-tcp-bind6-error.c
@@ -59,10 +59,11 @@ TEST_IMPL(tcp_bind6_error_addrinuse) {
uv_close((uv_handle_t*)&server1, close_cb);
uv_close((uv_handle_t*)&server2, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -80,10 +81,11 @@ TEST_IMPL(tcp_bind6_error_addrnotavail) {
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -101,14 +103,15 @@ TEST_IMPL(tcp_bind6_error_fault) {
r = uv_tcp_bind6(&server, *garbage_addr);
ASSERT(r == -1);
- ASSERT(uv_last_error(uv_default_loop()).code == UV_EFAULT);
+ ASSERT(uv_last_error(uv_default_loop()).code == UV_EINVAL);
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -131,10 +134,11 @@ TEST_IMPL(tcp_bind6_error_inval) {
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -150,5 +154,6 @@ TEST_IMPL(tcp_bind6_localhost_ok) {
r = uv_tcp_bind6(&server, addr);
ASSERT(r == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-close-while-connecting.c b/deps/uv/test/test-tcp-close-while-connecting.c
index 93e331d6d..d19dcbfee 100644
--- a/deps/uv/test/test-tcp-close-while-connecting.c
+++ b/deps/uv/test/test-tcp-close-while-connecting.c
@@ -38,7 +38,7 @@ static void close_cb(uv_handle_t* handle) {
static void connect_cb(uv_connect_t* req, int status) {
ASSERT(status == -1);
- ASSERT(uv_last_error(req->handle->loop).code == UV_EINTR);
+ ASSERT(uv_last_error(req->handle->loop).code == UV_ECANCELED);
uv_timer_stop(&timer2_handle);
connect_cb_called++;
}
@@ -70,11 +70,12 @@ TEST_IMPL(tcp_close_while_connecting) {
ASSERT(0 == uv_timer_start(&timer1_handle, timer1_cb, 50, 0));
ASSERT(0 == uv_timer_init(loop, &timer2_handle));
ASSERT(0 == uv_timer_start(&timer2_handle, timer2_cb, 86400 * 1000, 0));
- ASSERT(0 == uv_run(loop));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(connect_cb_called == 1);
ASSERT(timer1_cb_called == 1);
ASSERT(close_cb_called == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-close.c b/deps/uv/test/test-tcp-close.c
index 33f79974b..590293264 100644
--- a/deps/uv/test/test-tcp-close.c
+++ b/deps/uv/test/test-tcp-close.c
@@ -117,7 +117,7 @@ TEST_IMPL(tcp_close) {
ASSERT(write_cb_called == 0);
ASSERT(close_cb_called == 0);
- r = uv_run(loop);
+ r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
printf("%d of %d write reqs seen\n", write_cb_called, NUM_WRITE_REQS);
@@ -125,5 +125,6 @@ TEST_IMPL(tcp_close) {
ASSERT(write_cb_called == NUM_WRITE_REQS);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-connect-error-after-write.c b/deps/uv/test/test-tcp-connect-error-after-write.c
index a9c020378..e982c90ad 100644
--- a/deps/uv/test/test-tcp-connect-error-after-write.c
+++ b/deps/uv/test/test-tcp-connect-error-after-write.c
@@ -84,12 +84,13 @@ TEST_IMPL(tcp_connect_error_after_write) {
r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(connect_cb_called == 1);
ASSERT(write_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-connect-error.c b/deps/uv/test/test-tcp-connect-error.c
index 5cdacab63..b39eab975 100644
--- a/deps/uv/test/test-tcp-connect-error.c
+++ b/deps/uv/test/test-tcp-connect-error.c
@@ -61,10 +61,11 @@ TEST_IMPL(tcp_connect_error_fault) {
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(connect_cb_called == 0);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-connect-timeout.c b/deps/uv/test/test-tcp-connect-timeout.c
index 32b0dffd8..0569b6b0f 100644
--- a/deps/uv/test/test-tcp-connect-timeout.c
+++ b/deps/uv/test/test-tcp-connect-timeout.c
@@ -78,8 +78,9 @@ TEST_IMPL(tcp_connect_timeout) {
r = uv_tcp_connect(&connect_req, &conn, addr, connect_cb);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-connect6-error.c b/deps/uv/test/test-tcp-connect6-error.c
index 5c158ff87..65f2f80fc 100644
--- a/deps/uv/test/test-tcp-connect6-error.c
+++ b/deps/uv/test/test-tcp-connect6-error.c
@@ -59,10 +59,11 @@ TEST_IMPL(tcp_connect6_error_fault) {
uv_close((uv_handle_t*)&server, close_cb);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(connect_cb_called == 0);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-flags.c b/deps/uv/test/test-tcp-flags.c
index c441b563f..68afb39f4 100644
--- a/deps/uv/test/test-tcp-flags.c
+++ b/deps/uv/test/test-tcp-flags.c
@@ -44,8 +44,9 @@ TEST_IMPL(tcp_flags) {
uv_close((uv_handle_t*)&handle, NULL);
- r = uv_run(loop);
+ r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-open.c b/deps/uv/test/test-tcp-open.c
new file mode 100644
index 000000000..fca3e1111
--- /dev/null
+++ b/deps/uv/test/test-tcp-open.c
@@ -0,0 +1,175 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _WIN32
+# include <unistd.h>
+#endif
+
+static int shutdown_cb_called = 0;
+static int connect_cb_called = 0;
+static int write_cb_called = 0;
+static int close_cb_called = 0;
+
+static uv_connect_t connect_req;
+static uv_shutdown_t shutdown_req;
+static uv_write_t write_req;
+
+
+static void startup(void) {
+#ifdef _WIN32
+ struct WSAData wsa_data;
+ int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+ ASSERT(r == 0);
+#endif
+}
+
+
+static uv_os_sock_t create_tcp_socket(void) {
+ uv_os_sock_t sock;
+
+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+#ifdef _WIN32
+ ASSERT(sock != INVALID_SOCKET);
+#else
+ ASSERT(sock >= 0);
+#endif
+
+#ifndef _WIN32
+ {
+ /* Allow reuse of the port. */
+ int yes = 1;
+ int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
+ ASSERT(r == 0);
+ }
+#endif
+
+ return sock;
+}
+
+
+static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
+ static char slab[65536];
+ ASSERT(suggested_size <= sizeof slab);
+ return uv_buf_init(slab, sizeof slab);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ ASSERT(req == &shutdown_req);
+ ASSERT(status == 0);
+
+ /* Now we wait for the EOF */
+ shutdown_cb_called++;
+}
+
+
+static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
+ ASSERT(tcp != NULL);
+
+ if (nread >= 0) {
+ ASSERT(nread == 4);
+ ASSERT(memcmp("PING", buf.base, nread) == 0);
+ }
+ else {
+ ASSERT(uv_last_error(uv_default_loop()).code == UV_EOF);
+ printf("GOT EOF\n");
+ uv_close((uv_handle_t*)tcp, close_cb);
+ }
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(req != NULL);
+
+ if (status) {
+ uv_err_t err = uv_last_error(uv_default_loop());
+ fprintf(stderr, "uv_write error: %s\n", uv_strerror(err));
+ ASSERT(0);
+ }
+
+ write_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ uv_buf_t buf = uv_buf_init("PING", 4);
+ uv_stream_t* stream;
+ int r;
+
+ ASSERT(req == &connect_req);
+ ASSERT(status == 0);
+
+ stream = req->handle;
+ connect_cb_called++;
+
+ r = uv_write(&write_req, stream, &buf, 1, write_cb);
+ ASSERT(r == 0);
+
+ /* Shutdown on drain. */
+ r = uv_shutdown(&shutdown_req, stream, shutdown_cb);
+ ASSERT(r == 0);
+
+ /* Start reading */
+ r = uv_read_start(stream, alloc_cb, read_cb);
+ ASSERT(r == 0);
+}
+
+
+TEST_IMPL(tcp_open) {
+ struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
+ uv_tcp_t client;
+ uv_os_sock_t sock;
+ int r;
+
+ startup();
+ sock = create_tcp_socket();
+
+ r = uv_tcp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ r = uv_tcp_open(&client, sock);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req, &client, addr, connect_cb);
+ ASSERT(r == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(shutdown_cb_called == 1);
+ ASSERT(connect_cb_called == 1);
+ ASSERT(write_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-tcp-read-stop.c b/deps/uv/test/test-tcp-read-stop.c
new file mode 100644
index 000000000..cc6dd2eae
--- /dev/null
+++ b/deps/uv/test/test-tcp-read-stop.c
@@ -0,0 +1,73 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_timer_t timer_handle;
+static uv_tcp_t tcp_handle;
+static uv_write_t write_req;
+
+
+static void fail_cb(void) {
+ ASSERT(0 && "fail_cb called");
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ uv_close((uv_handle_t*) &timer_handle, NULL);
+ uv_close((uv_handle_t*) &tcp_handle, NULL);
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ uv_buf_t buf = uv_buf_init("PING", 4);
+ ASSERT(0 == uv_write(&write_req,
+ (uv_stream_t*) &tcp_handle,
+ &buf,
+ 1,
+ write_cb));
+ ASSERT(0 == uv_read_stop((uv_stream_t*) &tcp_handle));
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ ASSERT(0 == status);
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0));
+ ASSERT(0 == uv_read_start((uv_stream_t*) &tcp_handle,
+ (uv_alloc_cb) fail_cb,
+ (uv_read_cb) fail_cb));
+}
+
+
+TEST_IMPL(tcp_read_stop) {
+ uv_connect_t connect_req;
+ struct sockaddr_in addr;
+
+ addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp_handle));
+ ASSERT(0 == uv_tcp_connect(&connect_req, &tcp_handle, addr, connect_cb));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ MAKE_VALGRIND_HAPPY();
+
+ return 0;
+}
diff --git a/deps/uv/test/test-tcp-shutdown-after-write.c b/deps/uv/test/test-tcp-shutdown-after-write.c
index 219a3b405..a2e9e0f54 100644
--- a/deps/uv/test/test-tcp-shutdown-after-write.c
+++ b/deps/uv/test/test-tcp-shutdown-after-write.c
@@ -118,7 +118,7 @@ TEST_IMPL(tcp_shutdown_after_write) {
r = uv_tcp_connect(&connect_req, &conn, addr, connect_cb);
ASSERT(r == 0);
- r = uv_run(loop);
+ r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(connect_cb_called == 1);
@@ -127,5 +127,6 @@ TEST_IMPL(tcp_shutdown_after_write) {
ASSERT(conn_close_cb_called == 1);
ASSERT(timer_close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-unexpected-read.c b/deps/uv/test/test-tcp-unexpected-read.c
index 45559c013..e8fc53c34 100644
--- a/deps/uv/test/test-tcp-unexpected-read.c
+++ b/deps/uv/test/test-tcp-unexpected-read.c
@@ -77,7 +77,6 @@ static void connection_cb(uv_stream_t* handle, int status) {
buf = uv_buf_init("PING", 4);
ASSERT(0 == status);
- ASSERT(0 == uv_tcp_init(uv_default_loop(), &peer_handle));
ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle));
ASSERT(0 == uv_read_start((uv_stream_t*) &peer_handle, alloc_cb, read_cb));
ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &peer_handle,
@@ -98,16 +97,18 @@ TEST_IMPL(tcp_unexpected_read) {
ASSERT(0 == uv_check_start(&check_handle, check_cb));
ASSERT(0 == uv_tcp_init(loop, &server_handle));
ASSERT(0 == uv_tcp_init(loop, &client_handle));
+ ASSERT(0 == uv_tcp_init(loop, &peer_handle));
ASSERT(0 == uv_tcp_bind(&server_handle, addr));
ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb));
ASSERT(0 == uv_tcp_connect(&connect_req, &client_handle, addr, connect_cb));
- ASSERT(0 == uv_run(loop));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
/* This is somewhat inexact but the idea is that the event loop should not
* start busy looping when the server sends a message and the client isn't
* reading.
*/
- ASSERT(ticks <= 10);
+ ASSERT(ticks <= 20);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-write-error.c b/deps/uv/test/test-tcp-write-error.c
deleted file mode 100644
index 32207dd23..000000000
--- a/deps/uv/test/test-tcp-write-error.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* 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.
- */
-
-#include "uv.h"
-#include "task.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static void connection_cb(uv_stream_t* server, int status);
-static void connect_cb(uv_connect_t* req, int status);
-static void write_cb(uv_write_t* req, int status);
-static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf);
-static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size);
-
-static uv_tcp_t tcp_server;
-static uv_tcp_t tcp_client;
-static uv_tcp_t tcp_peer; /* client socket as accept()-ed by server */
-static uv_connect_t connect_req;
-
-static int write_cb_called;
-static int write_cb_error_called;
-
-typedef struct {
- uv_write_t req;
- uv_buf_t buf;
-} write_req_t;
-
-
-static void connection_cb(uv_stream_t* server, int status) {
- int r;
-
- ASSERT(server == (uv_stream_t*)&tcp_server);
- ASSERT(status == 0);
-
- r = uv_tcp_init(server->loop, &tcp_peer);
- ASSERT(r == 0);
-
- r = uv_accept(server, (uv_stream_t*)&tcp_peer);
- ASSERT(r == 0);
-
- r = uv_read_start((uv_stream_t*)&tcp_peer, alloc_cb, read_cb);
- ASSERT(r == 0);
-}
-
-
-static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
- static char slab[1024];
- return uv_buf_init(slab, sizeof slab);
-}
-
-
-static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
- uv_close((uv_handle_t*)&tcp_server, NULL);
- uv_close((uv_handle_t*)&tcp_peer, NULL);
-}
-
-
-static void connect_cb(uv_connect_t* req, int status) {
- uv_buf_t buf;
- size_t size;
- char* data;
- int r;
- write_req_t* wr;
-
- ASSERT(req == &connect_req);
- ASSERT(status == 0);
-
- while (1) {
- size = 10 * 1024 * 1024;
- data = malloc(size);
- ASSERT(data != NULL);
-
- memset(data, '$', size);
- buf = uv_buf_init(data, size);
-
- wr = (write_req_t*) malloc(sizeof *wr);
- wr->buf = buf;
- wr->req.data = data;
-
- r = uv_write(&(wr->req), req->handle, &wr->buf, 1, write_cb);
- ASSERT(r == 0);
-
- if (req->handle->write_queue_size >= size * 2) {
- break;
- }
- }
-}
-
-
-static void write_cb(uv_write_t* req, int status) {
- write_req_t* wr;
- wr = (write_req_t*) req;
-
- if (status == -1) {
- write_cb_error_called++;
- }
-
- if (req->handle->write_queue_size == 0) {
- uv_close((uv_handle_t*)&tcp_client, NULL);
- }
-
- free(wr->buf.base);
- free(wr);
-
- write_cb_called++;
-}
-
-
-/*
- * Assert that a failing write does not leave
- * the stream's write_queue_size in an inconsistent state.
- */
-TEST_IMPL(tcp_write_error) {
- uv_loop_t* loop;
- int r;
-
- loop = uv_default_loop();
- ASSERT(loop != NULL);
-
- r = uv_tcp_init(loop, &tcp_server);
- ASSERT(r == 0);
-
- r = uv_tcp_bind(&tcp_server, uv_ip4_addr("127.0.0.1", TEST_PORT));
- ASSERT(r == 0);
-
- r = uv_listen((uv_stream_t*)&tcp_server, 1, connection_cb);
- ASSERT(r == 0);
-
- r = uv_tcp_init(loop, &tcp_client);
- ASSERT(r == 0);
-
- r = uv_tcp_connect(&connect_req,
- &tcp_client,
- uv_ip4_addr("127.0.0.1", TEST_PORT),
- connect_cb);
- ASSERT(r == 0);
-
- ASSERT(write_cb_called == 0);
-
- r = uv_run(loop);
- ASSERT(r == 0);
-
- ASSERT(write_cb_called > 0);
- ASSERT(write_cb_error_called >= 1);
- ASSERT(tcp_client.write_queue_size == 0);
-
- return 0;
-}
diff --git a/deps/uv/test/test-tcp-write-to-half-open-connection.c b/deps/uv/test/test-tcp-write-to-half-open-connection.c
index 26f914b99..0447ac8cb 100644
--- a/deps/uv/test/test-tcp-write-to-half-open-connection.c
+++ b/deps/uv/test/test-tcp-write-to-half-open-connection.c
@@ -125,11 +125,12 @@ TEST_IMPL(tcp_write_to_half_open_connection) {
connect_cb);
ASSERT(r == 0);
- r = uv_run(loop);
+ r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(write_cb_called > 0);
ASSERT(read_cb_called > 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-tcp-writealot.c b/deps/uv/test/test-tcp-writealot.c
index 841df3c0d..3ddcd6d2e 100644
--- a/deps/uv/test/test-tcp-writealot.c
+++ b/deps/uv/test/test-tcp-writealot.c
@@ -145,7 +145,7 @@ TEST_IMPL(tcp_writealot) {
uv_tcp_t client;
int r;
- send_buffer = malloc(TOTAL_BYTES);
+ send_buffer = calloc(1, TOTAL_BYTES);
ASSERT(send_buffer != NULL);
r = uv_tcp_init(uv_default_loop(), &client);
@@ -154,7 +154,7 @@ TEST_IMPL(tcp_writealot) {
r = uv_tcp_connect(&connect_req, &client, addr, connect_cb);
ASSERT(r == 0);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(shutdown_cb_called == 1);
ASSERT(connect_cb_called == 1);
@@ -166,5 +166,6 @@ TEST_IMPL(tcp_writealot) {
free(send_buffer);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-thread.c b/deps/uv/test/test-thread.c
index 176663723..4bec8428f 100644
--- a/deps/uv/test/test-thread.c
+++ b/deps/uv/test/test-thread.c
@@ -42,7 +42,7 @@ struct fs_req {
};
-struct thread {
+struct test_thread {
uv_thread_t thread_id;
volatile int thread_called;
};
@@ -109,7 +109,7 @@ static void do_work(void* arg) {
uv_loop_t* loop;
size_t i;
int r;
- struct thread* thread = arg;
+ struct test_thread* thread = arg;
loop = uv_loop_new();
ASSERT(loop != NULL);
@@ -128,7 +128,7 @@ static void do_work(void* arg) {
fs_do(req);
}
- r = uv_run(loop);
+ r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
uv_loop_delete(loop);
@@ -162,7 +162,7 @@ TEST_IMPL(thread_create) {
* that each "finished" callback is run in its originating thread.
*/
TEST_IMPL(threadpool_multiple_event_loops) {
- struct thread threads[8];
+ struct test_thread threads[8];
size_t i;
int r;
diff --git a/deps/uv/test/test-threadpool-cancel.c b/deps/uv/test/test-threadpool-cancel.c
new file mode 100644
index 000000000..f000c1a86
--- /dev/null
+++ b/deps/uv/test/test-threadpool-cancel.c
@@ -0,0 +1,311 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#define INIT_CANCEL_INFO(ci, what) \
+ do { \
+ (ci)->reqs = (what); \
+ (ci)->nreqs = ARRAY_SIZE(what); \
+ (ci)->stride = sizeof((what)[0]); \
+ } \
+ while (0)
+
+struct cancel_info {
+ void* reqs;
+ unsigned nreqs;
+ unsigned stride;
+ uv_timer_t timer_handle;
+};
+
+static uv_cond_t signal_cond;
+static uv_mutex_t signal_mutex;
+static uv_mutex_t wait_mutex;
+static unsigned num_threads;
+static unsigned fs_cb_called;
+static unsigned work_cb_called;
+static unsigned done_cb_called;
+static unsigned done2_cb_called;
+static unsigned timer_cb_called;
+static unsigned getaddrinfo_cb_called;
+
+
+static void work_cb(uv_work_t* req) {
+ uv_mutex_lock(&signal_mutex);
+ uv_cond_signal(&signal_cond);
+ uv_mutex_unlock(&signal_mutex);
+
+ uv_mutex_lock(&wait_mutex);
+ uv_mutex_unlock(&wait_mutex);
+
+ work_cb_called++;
+}
+
+
+static void done_cb(uv_work_t* req, int status) {
+ done_cb_called++;
+ free(req);
+}
+
+
+static void saturate_threadpool(void) {
+ uv_work_t* req;
+
+ ASSERT(0 == uv_cond_init(&signal_cond));
+ ASSERT(0 == uv_mutex_init(&signal_mutex));
+ ASSERT(0 == uv_mutex_init(&wait_mutex));
+
+ uv_mutex_lock(&signal_mutex);
+ uv_mutex_lock(&wait_mutex);
+
+ for (num_threads = 0; /* empty */; num_threads++) {
+ req = malloc(sizeof(*req));
+ ASSERT(req != NULL);
+ ASSERT(0 == uv_queue_work(uv_default_loop(), req, work_cb, done_cb));
+
+ /* Expect to get signalled within 350 ms, otherwise assume that
+ * the thread pool is saturated. As with any timing dependent test,
+ * this is obviously not ideal.
+ */
+ if (uv_cond_timedwait(&signal_cond, &signal_mutex, 350 * 1e6)) {
+ ASSERT(0 == uv_cancel((uv_req_t*) req));
+ break;
+ }
+ }
+}
+
+
+static void unblock_threadpool(void) {
+ uv_mutex_unlock(&signal_mutex);
+ uv_mutex_unlock(&wait_mutex);
+}
+
+
+static void cleanup_threadpool(void) {
+ ASSERT(done_cb_called == num_threads + 1); /* +1 == cancelled work req. */
+ ASSERT(work_cb_called == num_threads);
+
+ uv_cond_destroy(&signal_cond);
+ uv_mutex_destroy(&signal_mutex);
+ uv_mutex_destroy(&wait_mutex);
+}
+
+
+static void fs_cb(uv_fs_t* req) {
+ ASSERT(req->errorno == UV_ECANCELED);
+ uv_fs_req_cleanup(req);
+ fs_cb_called++;
+}
+
+
+static void getaddrinfo_cb(uv_getaddrinfo_t* req,
+ int status,
+ struct addrinfo* res) {
+ ASSERT(UV_ECANCELED == uv_last_error(req->loop).code);
+ ASSERT(UV_ECANCELED == status);
+ getaddrinfo_cb_called++;
+}
+
+
+static void work2_cb(uv_work_t* req) {
+ ASSERT(0 && "work2_cb called");
+}
+
+
+static void done2_cb(uv_work_t* req, int status) {
+ ASSERT(uv_last_error(req->loop).code == UV_ECANCELED);
+ ASSERT(status == -1);
+ done2_cb_called++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ struct cancel_info* ci;
+ uv_req_t* req;
+ unsigned i;
+
+ ci = container_of(handle, struct cancel_info, timer_handle);
+
+ for (i = 0; i < ci->nreqs; i++) {
+ req = (uv_req_t*) ((char*) ci->reqs + i * ci->stride);
+ ASSERT(0 == uv_cancel(req));
+ }
+
+ uv_close((uv_handle_t*) &ci->timer_handle, NULL);
+ unblock_threadpool();
+ timer_cb_called++;
+}
+
+
+static void nop_work_cb(uv_work_t* req) {
+}
+
+
+static void nop_done_cb(uv_work_t* req, int status) {
+ req->data = "OK";
+}
+
+
+TEST_IMPL(threadpool_cancel_getaddrinfo) {
+ uv_getaddrinfo_t reqs[4];
+ struct cancel_info ci;
+ struct addrinfo hints;
+ uv_loop_t* loop;
+ int r;
+
+ INIT_CANCEL_INFO(&ci, reqs);
+ loop = uv_default_loop();
+ saturate_threadpool();
+
+ r = uv_getaddrinfo(loop, reqs + 0, getaddrinfo_cb, "fail", NULL, NULL);
+ ASSERT(r == 0);
+
+ r = uv_getaddrinfo(loop, reqs + 1, getaddrinfo_cb, NULL, "fail", NULL);
+ ASSERT(r == 0);
+
+ r = uv_getaddrinfo(loop, reqs + 2, getaddrinfo_cb, "fail", "fail", NULL);
+ ASSERT(r == 0);
+
+ r = uv_getaddrinfo(loop, reqs + 3, getaddrinfo_cb, "fail", NULL, &hints);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_timer_init(loop, &ci.timer_handle));
+ ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(1 == timer_cb_called);
+
+ cleanup_threadpool();
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(threadpool_cancel_work) {
+ struct cancel_info ci;
+ uv_work_t reqs[16];
+ uv_loop_t* loop;
+ unsigned i;
+
+ INIT_CANCEL_INFO(&ci, reqs);
+ loop = uv_default_loop();
+ saturate_threadpool();
+
+ for (i = 0; i < ARRAY_SIZE(reqs); i++)
+ ASSERT(0 == uv_queue_work(loop, reqs + i, work2_cb, done2_cb));
+
+ ASSERT(0 == uv_timer_init(loop, &ci.timer_handle));
+ ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(1 == timer_cb_called);
+ ASSERT(ARRAY_SIZE(reqs) == done2_cb_called);
+
+ cleanup_threadpool();
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(threadpool_cancel_fs) {
+ struct cancel_info ci;
+ uv_fs_t reqs[25];
+ uv_loop_t* loop;
+ unsigned n;
+
+ INIT_CANCEL_INFO(&ci, reqs);
+ loop = uv_default_loop();
+ saturate_threadpool();
+
+ /* Needs to match ARRAY_SIZE(fs_reqs). */
+ n = 0;
+ ASSERT(0 == uv_fs_chmod(loop, reqs + n++, "/", 0, fs_cb));
+ ASSERT(0 == uv_fs_chown(loop, reqs + n++, "/", 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_close(loop, reqs + n++, 0, fs_cb));
+ ASSERT(0 == uv_fs_fchmod(loop, reqs + n++, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_fchown(loop, reqs + n++, 0, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_fdatasync(loop, reqs + n++, 0, fs_cb));
+ ASSERT(0 == uv_fs_fstat(loop, reqs + n++, 0, fs_cb));
+ ASSERT(0 == uv_fs_fsync(loop, reqs + n++, 0, fs_cb));
+ ASSERT(0 == uv_fs_ftruncate(loop, reqs + n++, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_futime(loop, reqs + n++, 0, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_link(loop, reqs + n++, "/", "/", fs_cb));
+ ASSERT(0 == uv_fs_lstat(loop, reqs + n++, "/", fs_cb));
+ ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb));
+ ASSERT(0 == uv_fs_open(loop, reqs + n++, "/", 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_read(loop, reqs + n++, 0, NULL, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_readdir(loop, reqs + n++, "/", 0, fs_cb));
+ ASSERT(0 == uv_fs_readlink(loop, reqs + n++, "/", fs_cb));
+ ASSERT(0 == uv_fs_rename(loop, reqs + n++, "/", "/", fs_cb));
+ ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb));
+ ASSERT(0 == uv_fs_sendfile(loop, reqs + n++, 0, 0, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_stat(loop, reqs + n++, "/", fs_cb));
+ ASSERT(0 == uv_fs_symlink(loop, reqs + n++, "/", "/", 0, fs_cb));
+ ASSERT(0 == uv_fs_unlink(loop, reqs + n++, "/", fs_cb));
+ ASSERT(0 == uv_fs_utime(loop, reqs + n++, "/", 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_write(loop, reqs + n++, 0, NULL, 0, 0, fs_cb));
+ ASSERT(n == ARRAY_SIZE(reqs));
+
+ ASSERT(0 == uv_timer_init(loop, &ci.timer_handle));
+ ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(n == fs_cb_called);
+ ASSERT(1 == timer_cb_called);
+
+ cleanup_threadpool();
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(threadpool_cancel_single) {
+ uv_loop_t* loop;
+ uv_work_t req;
+ int cancelled;
+ int i;
+
+ loop = uv_default_loop();
+ for (i = 0; i < 5000; i++) {
+ req.data = NULL;
+ ASSERT(0 == uv_queue_work(loop, &req, nop_work_cb, nop_done_cb));
+
+ cancelled = uv_cancel((uv_req_t*) &req);
+ if (cancelled == 0)
+ break;
+
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ }
+
+ if (cancelled != 0) {
+ fputs("Failed to cancel a work req in 5,000 iterations, giving up.\n",
+ stderr);
+ return 1;
+ }
+
+ ASSERT(req.data == NULL);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(req.data != NULL); /* Should have been updated by nop_done_cb(). */
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-threadpool.c b/deps/uv/test/test-threadpool.c
index 92130b506..8d0964969 100644
--- a/deps/uv/test/test-threadpool.c
+++ b/deps/uv/test/test-threadpool.c
@@ -35,7 +35,8 @@ static void work_cb(uv_work_t* req) {
}
-static void after_work_cb(uv_work_t* req) {
+static void after_work_cb(uv_work_t* req, int status) {
+ ASSERT(status == 0);
ASSERT(req == &work_req);
ASSERT(req->data == &data);
after_work_cb_count++;
@@ -48,10 +49,29 @@ TEST_IMPL(threadpool_queue_work_simple) {
work_req.data = &data;
r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb);
ASSERT(r == 0);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(work_cb_count == 1);
ASSERT(after_work_cb_count == 1);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(threadpool_queue_work_einval) {
+ int r;
+
+ work_req.data = &data;
+ r = uv_queue_work(uv_default_loop(), &work_req, NULL, after_work_cb);
+ ASSERT(r == -1);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(uv_last_error(uv_default_loop()).code == UV_EINVAL);
+
+ ASSERT(work_cb_count == 0);
+ ASSERT(after_work_cb_count == 0);
+
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-timer-again.c b/deps/uv/test/test-timer-again.c
index e492c364e..536ac448e 100644
--- a/deps/uv/test/test-timer-again.c
+++ b/deps/uv/test/test-timer-again.c
@@ -31,7 +31,7 @@ static int repeat_2_cb_allowed = 0;
static uv_timer_t dummy, repeat_1, repeat_2;
-static int64_t start_time;
+static uint64_t start_time;
static void close_cb(uv_handle_t* handle) {
@@ -127,7 +127,7 @@ TEST_IMPL(timer_again) {
ASSERT(r == 0);
ASSERT(uv_timer_get_repeat(&repeat_2) == 100);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(repeat_1_cb_called == 10);
ASSERT(repeat_2_cb_called == 2);
@@ -137,5 +137,6 @@ TEST_IMPL(timer_again) {
(long int)(uv_now(uv_default_loop()) - start_time));
ASSERT(700 <= uv_now(uv_default_loop()) - start_time);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-timer.c b/deps/uv/test/test-timer.c
index c1b629b2f..60b080d28 100644
--- a/deps/uv/test/test-timer.c
+++ b/deps/uv/test/test-timer.c
@@ -27,8 +27,9 @@ static int once_cb_called = 0;
static int once_close_cb_called = 0;
static int repeat_cb_called = 0;
static int repeat_close_cb_called = 0;
+static int order_cb_called = 0;
-static int64_t start_time;
+static uint64_t start_time;
static void once_close_cb(uv_handle_t* handle) {
@@ -90,7 +91,8 @@ TEST_IMPL(timer) {
uv_timer_t once_timers[10];
uv_timer_t *once;
uv_timer_t repeat, never;
- int i, r;
+ unsigned int i;
+ int r;
start_time = uv_now(uv_default_loop());
ASSERT(0 < start_time);
@@ -119,7 +121,7 @@ TEST_IMPL(timer) {
ASSERT(r == 0);
uv_unref((uv_handle_t*)&never);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(once_cb_called == 10);
ASSERT(once_close_cb_called == 10);
@@ -129,6 +131,7 @@ TEST_IMPL(timer) {
ASSERT(500 <= uv_now(uv_default_loop()) - start_time);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -143,10 +146,59 @@ TEST_IMPL(timer_start_twice) {
ASSERT(r == 0);
r = uv_timer_start(&once, once_cb, 10, 0);
ASSERT(r == 0);
- r = uv_run(uv_default_loop());
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(once_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static void order_cb_a(uv_timer_t *handle, int status) {
+ ASSERT(order_cb_called++ == *(int*)handle->data);
+}
+
+
+static void order_cb_b(uv_timer_t *handle, int status) {
+ ASSERT(order_cb_called++ == *(int*)handle->data);
+}
+
+
+TEST_IMPL(timer_order) {
+ int first;
+ int second;
+ uv_timer_t handle_a;
+ uv_timer_t handle_b;
+
+ first = 0;
+ second = 1;
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_a));
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_b));
+
+ /* Test for starting handle_a then handle_b */
+ handle_a.data = &first;
+ ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0));
+ handle_b.data = &second;
+ ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT(order_cb_called == 2);
+
+ ASSERT(0 == uv_timer_stop(&handle_a));
+ ASSERT(0 == uv_timer_stop(&handle_b));
+
+ /* Test for starting handle_b then handle_a */
+ order_cb_called = 0;
+ handle_b.data = &first;
+ ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0));
+
+ handle_a.data = &second;
+ ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT(order_cb_called == 2);
+
return 0;
}
diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c
index ded59c9f7..eb5d5df52 100644
--- a/deps/uv/test/test-tty.c
+++ b/deps/uv/test/test-tty.c
@@ -104,7 +104,8 @@ TEST_IMPL(tty) {
uv_close((uv_handle_t*) &tty_in, NULL);
uv_close((uv_handle_t*) &tty_out, NULL);
- uv_run(loop);
+ uv_run(loop, UV_RUN_DEFAULT);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-udp-dgram-too-big.c b/deps/uv/test/test-udp-dgram-too-big.c
index 2d172c064..f34307646 100644
--- a/deps/uv/test/test-udp-dgram-too-big.c
+++ b/deps/uv/test/test-udp-dgram-too-big.c
@@ -77,10 +77,11 @@ TEST_IMPL(udp_dgram_too_big) {
ASSERT(close_cb_called == 0);
ASSERT(send_cb_called == 0);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(send_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-udp-ipv6.c b/deps/uv/test/test-udp-ipv6.c
index 6ff36b32b..247fe8bf9 100644
--- a/deps/uv/test/test-udp-ipv6.c
+++ b/deps/uv/test/test-udp-ipv6.c
@@ -130,9 +130,11 @@ static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) {
ASSERT(send_cb_called == 0);
ASSERT(recv_cb_called == 0);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 3);
+
+ MAKE_VALGRIND_HAPPY();
}
diff --git a/deps/uv/test/test-udp-multicast-join.c b/deps/uv/test/test-udp-multicast-join.c
index b32ef0737..83ec46b8d 100644
--- a/deps/uv/test/test-udp-multicast-join.c
+++ b/deps/uv/test/test-udp-multicast-join.c
@@ -129,11 +129,12 @@ TEST_IMPL(udp_multicast_join) {
ASSERT(sv_send_cb_called == 0);
/* run the loop till all events are processed */
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(cl_recv_cb_called == 1);
ASSERT(sv_send_cb_called == 1);
ASSERT(close_cb_called == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-udp-multicast-ttl.c b/deps/uv/test/test-udp-multicast-ttl.c
index b2f112514..6d3698367 100644
--- a/deps/uv/test/test-udp-multicast-ttl.c
+++ b/deps/uv/test/test-udp-multicast-ttl.c
@@ -77,10 +77,11 @@ TEST_IMPL(udp_multicast_ttl) {
ASSERT(sv_send_cb_called == 0);
/* run the loop till all events are processed */
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(sv_send_cb_called == 1);
ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-udp-open.c b/deps/uv/test/test-udp-open.c
new file mode 100644
index 000000000..5d27bdc0b
--- /dev/null
+++ b/deps/uv/test/test-udp-open.c
@@ -0,0 +1,154 @@
+/* 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _WIN32
+# include <unistd.h>
+#endif
+
+static int send_cb_called = 0;
+static int close_cb_called = 0;
+
+static uv_udp_send_t send_req;
+
+
+static void startup(void) {
+#ifdef _WIN32
+ struct WSAData wsa_data;
+ int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+ ASSERT(r == 0);
+#endif
+}
+
+
+static uv_os_sock_t create_udp_socket(void) {
+ uv_os_sock_t sock;
+
+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+#ifdef _WIN32
+ ASSERT(sock != INVALID_SOCKET);
+#else
+ ASSERT(sock >= 0);
+#endif
+
+#ifndef _WIN32
+ {
+ /* Allow reuse of the port. */
+ int yes = 1;
+ int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
+ ASSERT(r == 0);
+ }
+#endif
+
+ return sock;
+}
+
+
+static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
+ static char slab[65536];
+ ASSERT(suggested_size <= sizeof slab);
+ return uv_buf_init(slab, sizeof slab);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ uv_buf_t buf,
+ struct sockaddr* addr,
+ unsigned flags) {
+ int r;
+
+ if (nread < 0) {
+ ASSERT(0 && "unexpected error");
+ }
+
+ if (nread == 0) {
+ /* Returning unused buffer */
+ /* Don't count towards sv_recv_cb_called */
+ ASSERT(addr == NULL);
+ return;
+ }
+
+ ASSERT(flags == 0);
+
+ ASSERT(addr != NULL);
+ ASSERT(nread == 4);
+ ASSERT(memcmp("PING", buf.base, nread) == 0);
+
+ r = uv_udp_recv_stop(handle);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*) handle, close_cb);
+}
+
+
+static void send_cb(uv_udp_send_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+
+ send_cb_called++;
+}
+
+
+TEST_IMPL(udp_open) {
+ struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
+ uv_buf_t buf = uv_buf_init("PING", 4);
+ uv_udp_t client;
+ uv_os_sock_t sock;
+ int r;
+
+ startup();
+ sock = create_udp_socket();
+
+ r = uv_udp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ r = uv_udp_open(&client, sock);
+ ASSERT(r == 0);
+
+ r = uv_udp_bind(&client, addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_udp_recv_start(&client, alloc_cb, recv_cb);
+ ASSERT(r == 0);
+
+ r = uv_udp_send(&send_req, &client, &buf, 1, addr, send_cb);
+ ASSERT(r == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(send_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-udp-options.c b/deps/uv/test/test-udp-options.c
index 4ff650dc0..9d26d81c2 100644
--- a/deps/uv/test/test-udp-options.c
+++ b/deps/uv/test/test-udp-options.c
@@ -79,8 +79,9 @@ TEST_IMPL(udp_options) {
ASSERT(uv_last_error(loop).code == UV_EINVAL);
/* don't test ttl=-1, it's a valid value on some platforms */
- r = uv_run(loop);
+ r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-udp-send-and-recv.c b/deps/uv/test/test-udp-send-and-recv.c
index ab47e91c2..37df5b625 100644
--- a/deps/uv/test/test-udp-send-and-recv.c
+++ b/deps/uv/test/test-udp-send-and-recv.c
@@ -196,7 +196,7 @@ TEST_IMPL(udp_send_and_recv) {
ASSERT(sv_send_cb_called == 0);
ASSERT(sv_recv_cb_called == 0);
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(cl_send_cb_called == 1);
ASSERT(cl_recv_cb_called == 1);
@@ -204,5 +204,6 @@ TEST_IMPL(udp_send_and_recv) {
ASSERT(sv_recv_cb_called == 1);
ASSERT(close_cb_called == 2);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-walk-handles.c b/deps/uv/test/test-walk-handles.c
index a72c095bc..f2ae41564 100644
--- a/deps/uv/test/test-walk-handles.c
+++ b/deps/uv/test/test-walk-handles.c
@@ -64,7 +64,7 @@ TEST_IMPL(walk_handles) {
/* Start event loop, expect to see the timer handle in walk_cb. */
ASSERT(seen_timer_handle == 0);
- r = uv_run(loop);
+ r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(seen_timer_handle == 1);
@@ -73,5 +73,6 @@ TEST_IMPL(walk_handles) {
uv_walk(loop, walk_cb, magic_cookie);
ASSERT(seen_timer_handle == 0);
+ MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index f288d92d3..55f1e2394 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -6,7 +6,6 @@
'_LARGEFILE_SOURCE',
'_FILE_OFFSET_BITS=64',
'_GNU_SOURCE',
- 'EIO_STACKSIZE=262144'
],
'conditions': [
['OS=="solaris"', {
@@ -21,7 +20,7 @@
'targets': [
{
- 'target_name': 'uv',
+ 'target_name': 'libuv',
'type': '<(library)',
'include_dirs': [
'include',
@@ -30,104 +29,44 @@
],
'direct_dependent_settings': {
'include_dirs': [ 'include' ],
+ 'conditions': [
+ ['OS != "win"', {
+ 'defines': [
+ '_LARGEFILE_SOURCE',
+ '_FILE_OFFSET_BITS=64',
+ ],
+ }],
+ ['OS == "mac"', {
+ 'defines': [ '_DARWIN_USE_64_BIT_INODE=1' ],
+ }],
+ ['OS == "linux"', {
+ 'defines': [ '_POSIX_C_SOURCE=200112' ],
+ }],
+ ],
},
'defines': [
'HAVE_CONFIG_H'
],
'sources': [
'common.gypi',
- 'include/ares.h',
- 'include/ares_version.h',
'include/uv.h',
'include/uv-private/ngx-queue.h',
'include/uv-private/tree.h',
- 'src/cares.c',
'src/fs-poll.c',
+ 'src/inet.c',
'src/uv-common.c',
'src/uv-common.h',
- 'src/ares/ares_cancel.c',
- 'src/ares/ares__close_sockets.c',
- 'src/ares/ares_data.c',
- 'src/ares/ares_data.h',
- 'src/ares/ares_destroy.c',
- 'src/ares/ares_dns.h',
- 'src/ares/ares_expand_name.c',
- 'src/ares/ares_expand_string.c',
- 'src/ares/ares_fds.c',
- 'src/ares/ares_free_hostent.c',
- 'src/ares/ares_free_string.c',
- 'src/ares/ares_getenv.h',
- 'src/ares/ares_gethostbyaddr.c',
- 'src/ares/ares_gethostbyname.c',
- 'src/ares/ares__get_hostent.c',
- 'src/ares/ares_getnameinfo.c',
- 'src/ares/ares_getopt.c',
- 'src/ares/ares_getopt.h',
- 'src/ares/ares_getsock.c',
- 'src/ares/ares_init.c',
- 'src/ares/ares_ipv6.h',
- 'src/ares/ares_library_init.c',
- 'src/ares/ares_library_init.h',
- 'src/ares/ares_llist.c',
- 'src/ares/ares_llist.h',
- 'src/ares/ares_mkquery.c',
- 'src/ares/ares_nowarn.c',
- 'src/ares/ares_nowarn.h',
- 'src/ares/ares_options.c',
- 'src/ares/ares_parse_aaaa_reply.c',
- 'src/ares/ares_parse_a_reply.c',
- 'src/ares/ares_parse_mx_reply.c',
- 'src/ares/ares_parse_ns_reply.c',
- 'src/ares/ares_parse_ptr_reply.c',
- 'src/ares/ares_parse_srv_reply.c',
- 'src/ares/ares_parse_txt_reply.c',
- 'src/ares/ares_platform.h',
- 'src/ares/ares_private.h',
- 'src/ares/ares_process.c',
- 'src/ares/ares_query.c',
- 'src/ares/ares__read_line.c',
- 'src/ares/ares_rules.h',
- 'src/ares/ares_search.c',
- 'src/ares/ares_send.c',
- 'src/ares/ares_setup.h',
- 'src/ares/ares_strcasecmp.c',
- 'src/ares/ares_strcasecmp.h',
- 'src/ares/ares_strdup.c',
- 'src/ares/ares_strdup.h',
- 'src/ares/ares_strerror.c',
- 'src/ares/ares_timeout.c',
- 'src/ares/ares__timeval.c',
- 'src/ares/ares_version.c',
- 'src/ares/ares_writev.c',
- 'src/ares/ares_writev.h',
- 'src/ares/bitncmp.c',
- 'src/ares/bitncmp.h',
- 'src/ares/inet_net_pton.c',
- 'src/ares/inet_net_pton.h',
- 'src/ares/inet_ntop.c',
- 'src/ares/inet_ntop.h',
- 'src/ares/nameser.h',
- 'src/ares/setup_once.h',
- 'src/ares/windows_port.c',
],
'conditions': [
[ 'OS=="win"', {
- 'include_dirs': [
- 'src/ares/config_win32'
- ],
'defines': [
'_WIN32_WINNT=0x0600',
- 'EIO_STACKSIZE=262144',
'_GNU_SOURCE',
],
'sources': [
'include/uv-private/uv-win.h',
- 'src/ares/config_win32/ares_config.h',
- 'src/ares/windows_port.c',
- 'src/ares/ares_getenv.c',
- 'src/ares/ares_iphlpapi.h',
- 'src/ares/ares_platform.c',
'src/win/async.c',
+ 'src/win/atomicops-inl.h',
'src/win/core.c',
'src/win/dl.c',
'src/win/error.c',
@@ -145,6 +84,7 @@
'src/win/process-stdio.c',
'src/win/req.c',
'src/win/req-inl.h',
+ 'src/win/signal.c',
'src/win/stream.c',
'src/win/stream-inl.h',
'src/win/tcp.c',
@@ -172,40 +112,36 @@
'-pedantic',
'-Wall',
'-Wextra',
- '-Wno-unused-parameter'
+ '-Wstrict-aliasing',
+ '-Wno-unused-parameter',
],
'sources': [
- 'include/uv-private/eio.h',
- 'include/uv-private/ev.h',
'include/uv-private/uv-unix.h',
+ 'include/uv-private/uv-linux.h',
+ 'include/uv-private/uv-sunos.h',
+ 'include/uv-private/uv-darwin.h',
+ 'include/uv-private/uv-bsd.h',
'src/unix/async.c',
'src/unix/core.c',
'src/unix/dl.c',
- 'src/unix/eio/ecb.h',
- 'src/unix/eio/eio.c',
- 'src/unix/eio/xthread.h',
'src/unix/error.c',
- 'src/unix/ev/ev.c',
- 'src/unix/ev/ev_vars.h',
- 'src/unix/ev/ev_wrap.h',
- 'src/unix/ev/event.h',
'src/unix/fs.c',
+ 'src/unix/getaddrinfo.c',
'src/unix/internal.h',
'src/unix/loop.c',
'src/unix/loop-watcher.c',
'src/unix/pipe.c',
'src/unix/poll.c',
'src/unix/process.c',
+ 'src/unix/signal.c',
'src/unix/stream.c',
'src/unix/tcp.c',
'src/unix/thread.c',
+ 'src/unix/threadpool.c',
'src/unix/timer.c',
'src/unix/tty.c',
'src/unix/udp.c',
- 'src/unix/uv-eio.c',
- 'src/unix/uv-eio.h',
],
- 'include_dirs': [ 'src/unix/ev', ],
'link_settings': {
'libraries': [ '-lm' ],
'conditions': [
@@ -216,85 +152,103 @@
}],
],
},
+ 'conditions': [
+ ['"<(library)" == "shared_library"', {
+ 'cflags': [ '-fPIC' ],
+ }],
+ ],
+ }],
+ [ 'OS=="linux" or OS=="mac"', {
+ 'sources': [ 'src/unix/proctitle.c' ],
}],
[ 'OS=="mac"', {
- 'include_dirs': [ 'src/ares/config_darwin' ],
- 'sources': [ 'src/unix/darwin.c' ],
+ 'sources': [
+ 'src/unix/darwin.c',
+ 'src/unix/fsevents.c',
+ 'src/unix/darwin-proctitle.m',
+ ],
'link_settings': {
'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
'$(SDKROOT)/System/Library/Frameworks/CoreServices.framework',
+ '$(SDKROOT)/System/Library/Frameworks/ApplicationServices.framework',
],
},
'defines': [
'_DARWIN_USE_64_BIT_INODE=1',
- 'EV_CONFIG_H="config_darwin.h"',
- 'EIO_CONFIG_H="config_darwin.h"',
]
}],
[ 'OS=="linux"', {
- 'include_dirs': [ 'src/ares/config_linux' ],
'sources': [
- 'src/unix/linux/linux-core.c',
- 'src/unix/linux/inotify.c',
- 'src/unix/linux/syscalls.c',
- 'src/unix/linux/syscalls.h',
- ],
- 'defines': [
- 'EV_CONFIG_H="config_linux.h"',
- 'EIO_CONFIG_H="config_linux.h"',
+ 'src/unix/linux-core.c',
+ 'src/unix/linux-inotify.c',
+ 'src/unix/linux-syscalls.c',
+ 'src/unix/linux-syscalls.h',
],
'link_settings': {
'libraries': [ '-ldl', '-lrt' ],
},
}],
[ 'OS=="solaris"', {
- 'include_dirs': [ 'src/ares/config_sunos' ],
'sources': [ 'src/unix/sunos.c' ],
'defines': [
'__EXTENSIONS__',
'_XOPEN_SOURCE=500',
- 'EV_CONFIG_H="config_sunos.h"',
- 'EIO_CONFIG_H="config_sunos.h"',
],
'link_settings': {
'libraries': [
'-lkstat',
- '-lsocket',
'-lnsl',
+ '-lsendfile',
+ '-lsocket',
],
},
}],
- [ 'OS=="freebsd"', {
- 'include_dirs': [ 'src/ares/config_freebsd' ],
- 'sources': [ 'src/unix/freebsd.c' ],
+ [ 'OS=="aix"', {
+ 'include_dirs': [ 'src/ares/config_aix' ],
+ 'sources': [ 'src/unix/aix.c' ],
'defines': [
- 'EV_CONFIG_H="config_freebsd.h"',
- 'EIO_CONFIG_H="config_freebsd.h"',
+ '_ALL_SOURCE',
+ '_XOPEN_SOURCE=500',
],
'link_settings': {
'libraries': [
+ '-lperfstat',
+ ],
+ },
+ }],
+ [ 'OS=="freebsd" or OS=="dragonflybsd"', {
+ 'sources': [ 'src/unix/freebsd.c' ],
+ 'link_settings': {
+ 'libraries': [
'-lkvm',
],
},
}],
[ 'OS=="openbsd"', {
- 'include_dirs': [ 'src/ares/config_openbsd' ],
'sources': [ 'src/unix/openbsd.c' ],
- 'defines': [
- 'EV_CONFIG_H="config_openbsd.h"',
- 'EIO_CONFIG_H="config_openbsd.h"',
- ],
}],
- [ 'OS=="mac" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
+ [ 'OS=="netbsd"', {
+ 'sources': [ 'src/unix/netbsd.c' ],
+ 'link_settings': {
+ 'libraries': [
+ '-lkvm',
+ ],
+ },
+ }],
+ [ 'OS in "mac freebsd dragonflybsd openbsd netbsd".split()', {
'sources': [ 'src/unix/kqueue.c' ],
}],
+ ['library=="shared_library"', {
+ 'defines': [ 'BUILDING_UV_SHARED=1' ]
+ }]
]
},
{
'target_name': 'run-tests',
'type': 'executable',
- 'dependencies': [ 'uv' ],
+ 'dependencies': [ 'libuv' ],
'sources': [
'test/blackhole-server.c',
'test/echo-server.c',
@@ -304,20 +258,21 @@
'test/test-get-loadavg.c',
'test/task.h',
'test/test-util.c',
+ 'test/test-active.c',
'test/test-async.c',
- 'test/test-error.c',
'test/test-callback-stack.c',
'test/test-callback-order.c',
'test/test-connection-fail.c',
'test/test-cwd-and-chdir.c',
'test/test-delayed-accept.c',
+ 'test/test-error.c',
+ 'test/test-embed.c',
'test/test-fail-always.c',
'test/test-fs.c',
'test/test-fs-event.c',
'test/test-get-currentexe.c',
'test/test-get-memory.c',
'test/test-getaddrinfo.c',
- 'test/test-gethostbyname.c',
'test/test-getsockname.c',
'test/test-hrtime.c',
'test/test-idle.c',
@@ -325,6 +280,7 @@
'test/test-ipc-send-recv.c',
'test/test-list.h',
'test/test-loop-handles.c',
+ 'test/test-loop-stop.c',
'test/test-walk-handles.c',
'test/test-multiple-listen.c',
'test/test-pass-always.c',
@@ -336,10 +292,13 @@
'test/test-poll-close.c',
'test/test-process-title.c',
'test/test-ref.c',
+ 'test/test-run-nowait.c',
'test/test-run-once.c',
'test/test-semaphore.c',
'test/test-shutdown-close.c',
'test/test-shutdown-eof.c',
+ 'test/test-signal.c',
+ 'test/test-signal-multiple-loops.c',
'test/test-spawn.c',
'test/test-fs-poll.c',
'test/test-stdio-over-pipes.c',
@@ -353,22 +312,26 @@
'test/test-tcp-connect-error.c',
'test/test-tcp-connect-timeout.c',
'test/test-tcp-connect6-error.c',
- 'test/test-tcp-write-error.c',
+ 'test/test-tcp-open.c',
'test/test-tcp-write-to-half-open-connection.c',
'test/test-tcp-writealot.c',
'test/test-tcp-unexpected-read.c',
+ 'test/test-tcp-read-stop.c',
'test/test-threadpool.c',
+ 'test/test-threadpool-cancel.c',
'test/test-mutexes.c',
'test/test-thread.c',
+ 'test/test-barrier.c',
+ 'test/test-condvar.c',
'test/test-timer-again.c',
'test/test-timer.c',
'test/test-tty.c',
'test/test-udp-dgram-too-big.c',
'test/test-udp-ipv6.c',
+ 'test/test-udp-open.c',
'test/test-udp-options.c',
'test/test-udp-send-and-recv.c',
'test/test-udp-multicast-join.c',
- 'test/test-counters-init.c',
'test/test-dlerror.c',
'test/test-udp-multicast-ttl.c',
],
@@ -392,6 +355,12 @@
'_XOPEN_SOURCE=500',
],
}],
+ [ 'OS=="aix"', { # make test-fs.c compile, needs _POSIX_C_SOURCE
+ 'defines': [
+ '_ALL_SOURCE',
+ '_XOPEN_SOURCE=500',
+ ],
+ }],
],
'msvs-settings': {
'VCLinkerTool': {
@@ -403,14 +372,17 @@
{
'target_name': 'run-benchmarks',
'type': 'executable',
- 'dependencies': [ 'uv' ],
+ 'dependencies': [ 'libuv' ],
'sources': [
- 'test/benchmark-ares.c',
+ 'test/benchmark-async.c',
+ 'test/benchmark-async-pummel.c',
'test/benchmark-fs-stat.c',
'test/benchmark-getaddrinfo.c',
'test/benchmark-list.h',
'test/benchmark-loop-count.c',
+ 'test/benchmark-million-async.c',
'test/benchmark-million-timers.c',
+ 'test/benchmark-multi-accept.c',
'test/benchmark-ping-pongs.c',
'test/benchmark-pound.c',
'test/benchmark-pump.c',
@@ -418,7 +390,7 @@
'test/benchmark-spawn.c',
'test/benchmark-thread.c',
'test/benchmark-tcp-write-batch.c',
- 'test/benchmark-udp-packet-storm.c',
+ 'test/benchmark-udp-pummel.c',
'test/dns-server.c',
'test/echo-server.c',
'test/blackhole-server.c',
diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat
index 644f574c2..aa8a757c8 100644
--- a/deps/uv/vcbuild.bat
+++ b/deps/uv/vcbuild.bat
@@ -17,6 +17,10 @@ set target=Build
set noprojgen=
set nobuild=
set run=
+set target_arch=ia32
+set vs_toolset=x86
+set platform=WIN32
+set library=static_library
:next-arg
if "%1"=="" goto args-done
@@ -27,11 +31,35 @@ if /i "%1"=="bench" set run=run-benchmarks.exe&goto arg-ok
if /i "%1"=="clean" set target=Clean&goto arg-ok
if /i "%1"=="noprojgen" set noprojgen=1&goto arg-ok
if /i "%1"=="nobuild" set nobuild=1&goto arg-ok
+if /i "%1"=="x86" set target_arch=ia32&set platform=WIN32&set vs_toolset=x86&goto arg-ok
+if /i "%1"=="ia32" set target_arch=ia32&set platform=WIN32&set vs_toolset=x86&goto arg-ok
+if /i "%1"=="x64" set target_arch=x64&set platform=amd64&set vs_toolset=x64&goto arg-ok
+if /i "%1"=="shared" set library=shared_library&goto arg-ok
+if /i "%1"=="static" set library=static_library&goto arg-ok
:arg-ok
shift
goto next-arg
:args-done
+@rem Look for Visual Studio 2010
+if not defined VS100COMNTOOLS goto vc-set-2008
+if not exist "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2008
+call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
+set GYP_MSVS_VERSION=2010
+goto select-target
+
+:vc-set-2008
+@rem Look for Visual Studio 2008
+if not defined VS90COMNTOOLS goto vc-set-notfound
+if not exist "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-notfound
+call "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
+set GYP_MSVS_VERSION=2008
+goto select-target
+
+:vc-set-notfound
+echo Warning: Visual Studio not found
+
+:select-target
if not "%config%"=="" goto project-gen
if "%run%"=="run-tests.exe" set config=Debug& goto project-gen
if "%run%"=="run-benchmarks.exe" set config=Release& goto project-gen
@@ -42,20 +70,19 @@ set config=Debug
if defined noprojgen goto msbuild
@rem Generate the VS project.
-
if exist build\gyp goto have_gyp
-echo svn co http://gyp.googlecode.com/svn/trunk@983 build/gyp
-svn co http://gyp.googlecode.com/svn/trunk@983 build/gyp
+echo git clone https://git.chromium.org/external/gyp.git build/gyp
+git clone https://git.chromium.org/external/gyp.git build/gyp
if errorlevel 1 goto gyp_install_failed
goto have_gyp
:gyp_install_failed
-echo Failed to download gyp. Make sure you have subversion installed, or
+echo Failed to download gyp. Make sure you have git installed, or
echo manually install gyp into %~dp0build\gyp.
goto exit
:have_gyp
-python gyp_uv
+python gyp_uv -Dtarget_arch=%target_arch% -Dlibrary=%library%
if errorlevel 1 goto create-msvs-files-failed
if not exist uv.sln goto create-msvs-files-failed
echo Project files generated.
@@ -64,12 +91,7 @@ echo Project files generated.
@rem Skip project generation if requested.
if defined nobuild goto run
-@rem If not running in the VS build env, try to start it. If that fails, bail
-@rem out.
-if defined VCINSTALLDIR goto msbuild-found
-if not defined VS100COMNTOOLS goto msbuild-not-found
-if not exist "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" goto msbuild-not-found
-call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat"
+@rem Check if VS build env is available
if not defined VCINSTALLDIR goto msbuild-not-found
goto msbuild-found
@@ -79,7 +101,7 @@ goto run
@rem Build the sln with msbuild.
:msbuild-found
-msbuild uv.sln /t:%target% /p:Configuration=%config% /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
+msbuild uv.sln /t:%target% /p:Configuration=%config% /p:Platform="%platform%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
if errorlevel 1 goto exit
:run
@@ -91,11 +113,11 @@ echo running '%config%\%run%'
goto exit
:create-msvs-files-failed
-echo Failed to create vc project files.
+echo Failed to create vc project files.
goto exit
:help
-echo vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild]
+echo vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [x86/x64] [static/shared]
echo Examples:
echo vcbuild.bat : builds debug build
echo vcbuild.bat test : builds debug build and runs tests
diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore
index 088daeabf..0bf931335 100644
--- a/deps/v8/.gitignore
+++ b/deps/v8/.gitignore
@@ -9,9 +9,11 @@
*.pdb
*.pyc
*.scons*
+*.sln
*.so
*.suo
*.user
+*.vcproj
*.xcodeproj
#*#
*~
@@ -20,17 +22,31 @@ d8
d8_g
shell
shell_g
+/build/Debug
/build/gyp
-/obj/
-/out/
+/build/Release
+/obj
+/out
+/test/cctest/cctest.status2
/test/es5conform/data
+/test/message/message.status2
+/test/mjsunit/mjsunit.status2
+/test/mozilla/CHECKED_OUT_VERSION
/test/mozilla/data
+/test/mozilla/downloaded_*
+/test/mozilla/mozilla.status2
+/test/preparser/preparser.status2
/test/sputnik/sputniktests
/test/test262/data
+/test/test262/test262-*
+/test/test262/test262.status2
+/third_party
+/tools/jsfunfuzz
+/tools/jsfunfuzz.zip
/tools/oom_dump/oom_dump
/tools/oom_dump/oom_dump.o
/tools/visual_studio/Debug
/tools/visual_studio/Release
-/xcodebuild/
+/xcodebuild
TAGS
*.Makefile
diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS
index 6e46b3d62..1156d9495 100644
--- a/deps/v8/AUTHORS
+++ b/deps/v8/AUTHORS
@@ -24,9 +24,11 @@ Dineel D Sule <dsule@codeaurora.org>
Erich Ocean <erich.ocean@me.com>
Fedor Indutny <fedor@indutny.com>
Filipe David Manana <fdmanana@gmail.com>
+Haitao Feng <haitao.feng@intel.com>
Ioseb Dzmanashvili <ioseb.dzmanashvili@gmail.com>
Jan de Mooij <jandemooij@gmail.com>
Jay Freeman <saurik@saurik.com>
+James Pike <g00gle@chilon.net>
Joel Stanley <joel.stan@gmail.com>
John Jozwiak <jjozwiak@codeaurora.org>
Jonathan Liu <net147@gmail.com>
@@ -46,6 +48,7 @@ Rene Rebe <rene@exactcode.de>
Robert Mustacchi <rm@fingolfin.org>
Rodolph Perfetta <rodolph.perfetta@arm.com>
Ryan Dahl <coldredlemur@gmail.com>
+Sandro Santilli <strk@keybit.net>
Sanjoy Das <sanjoy@playingwithpointers.com>
Subrato K De <subratokde@codeaurora.org>
Tobias Burnus <burnus@net-b.de>
diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog
index fae15e58e..7c435c8b6 100644
--- a/deps/v8/ChangeLog
+++ b/deps/v8/ChangeLog
@@ -1,3 +1,479 @@
+2012-10-22: Version 3.14.5
+
+ Killed off the SCons based build.
+
+ Added a faster API for creating v8::Integer objects.
+
+ Speeded up function deoptimization by avoiding quadratic pass over
+ optimized function list. (Chromium issue 155270)
+
+ Always invoke the default Array.sort functions from builtin functions.
+ (issue 2372)
+
+ Reverted recent CPU profiler changes because they broke --prof.
+ (issue 2364)
+
+ Switched code flushing to use different JSFunction field.
+ (issue 1609)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-10-15: Version 3.14.4
+
+ Allow evals for debugger even if they are prohibited in the debugee
+ context. (Chromium issue 154733)
+
+ Enabled --verify-heap in release mode (issue 2120)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-10-11: Version 3.14.3
+
+ Use native context to retrieve ErrorMessageForCodeGenerationFromStrings
+ (Chromium issue 155076).
+
+ Bumped variable limit further to 2^17 (Chromium issue 151625).
+
+ Performance and stability improvements on all platforms.
+
+
+2012-10-10: Version 3.14.2
+
+ ARM: allowed VFP3 instructions when hardfloat is enabled.
+ (Chromium issue 152506)
+
+ Fixed instance_descriptors() and PushStackTraceAndDie regressions.
+ (Chromium issue 151749)
+
+ Made GDBJIT interface compile again. (issue 1804)
+
+ Fixed Accessors::FunctionGetPrototype's proto chain traversal.
+ (Chromium issue 143967)
+
+ Made sure that names of temporaries do not clash with real variables.
+ (issue 2322)
+
+ Rejected local module declarations. (Chromium issue 150628)
+
+ Rejected uses of lexical for-loop variable on the RHS. (issue 2322)
+
+ Fixed slot recording of code target patches.
+ (Chromium issue 152615,chromium:144230)
+
+ Changed the Android makefile to use GCC 4.6 instead of GCC 4.4.3.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-10-01: Version 3.14.1
+
+ Don't set -m32 flag when compiling with Android ARM compiler.
+ (Chromium issue 143889)
+
+ Restore the descriptor array before returning allocation failure.
+ (Chromium issue 151750)
+
+ Lowered kMaxVirtualRegisters (v8 issue 2139, Chromium issues 123822 and
+ 128252).
+
+ Pull more recent gyp in 'make dependencies'.
+
+ Made sure that the generic KeyedStoreIC changes length and element_kind
+ atomically (issue 2346).
+
+ Bumped number of allowed variables per scope to 65535, to address GWT.
+ (Chromium issue 151625)
+
+ Support sourceURL for dynamically inserted scripts (issue 2342).
+
+ Performance and stability improvements on all platforms.
+
+
+2012-09-20: Version 3.14.0
+
+ Fixed missing slot recording during clearing of CallICs.
+ (Chromium issue 144230)
+
+ Fixed LBoundsCheck on x64 to handle (stack slot + constant) correctly.
+ (Chromium issue 150729)
+
+ Fixed minus zero test. (Issue 2133)
+
+ Fixed setting array length to zero for slow elements.
+ (Chromium issue 146910)
+
+ Fixed lost arguments dropping in HLeaveInlined.
+ (Chromium issue 150545)
+
+ Fixed casting error for receiver of interceptors.
+ (Chromium issue 149912)
+
+ Throw a more descriptive exception when blocking 'eval' via CSP.
+ (Chromium issue 140191)
+
+ Fixed debugger's eval when close to stack overflow. (issue 2318)
+
+ Added checks to live edit. (issue 2297)
+
+ Switched on code compaction on incremental GCs.
+
+ Fixed caching of optimized code for OSR. (issue 2326)
+
+ Not mask exception thrown by toString in String::UtfValue etc.
+ (issue 2317)
+
+ Fixed API check for length of external arrays. (Chromium issue 148896)
+
+ Ensure correct enumeration indices in the dict (Chromium issue 148376)
+
+ Correctly initialize regexp global cache. (Chromium issue 148378)
+
+ Fixed arguments object materialization during deopt. (issue 2261)
+
+ Introduced new API to expose external string resource regardless of
+ encoding.
+
+ Fixed CHECK failure in LCodeGen::DoWrapReceiver when
+ --deopt-every-n-times flag is present
+ (Chromium issue 148389)
+
+ Fixed edge case of extension with NULL as source string.
+ (Chromium issue 144649)
+
+ Fixed array index dehoisting. (Chromium issue 141395)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-09-11: Version 3.13.7
+
+ Enable/disable LiveEdit using the (C++) debug API.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-09-06: Version 3.13.6
+
+ Added validity checking to API functions and calls.
+
+ Disabled accessor inlining (Chromium issue 134609).
+
+ Fixed bug in Math.min/max in optimized code (Chromium issue 145961).
+
+ Directly use %ObjectKeys in json stringify (Chromium issue 2312).
+
+ Fixed VS2005 build (issue 2313).
+
+ Activated fixed ES5 readonly semantics by default.
+
+ Added hardfp flag to the Makefile.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-08-29: Version 3.13.5
+
+ Release stack trace data after firing Error.stack accessor.
+ (issue 2308)
+
+ Added a new API V8::SetJitCodeEventHandler to push code name and
+ location to users such as profilers.
+
+ Allocate block-scoped global bindings to global context.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-08-28: Version 3.13.4
+
+ Print reason for disabling optimization. Kill --trace-bailout flag.
+
+ Provided option to disable full DEBUG build on Android.
+
+ Introduced global contexts to represent lexical global scope(s).
+
+ Fixed rounding in Uint8ClampedArray setter. (issue 2294)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-08-21: Version 3.13.3
+
+ Performance and stability improvements on all platforms.
+
+
+2012-08-20: Version 3.13.2
+
+ Performance and stability improvements on all platforms.
+
+
+2012-08-16: Version 3.13.1
+
+ Performance and stability improvements on all platforms.
+
+
+2012-08-10: Version 3.13.0
+
+ Added histograms for total allocated/live heap size, as well as
+ allocated size and percentage of total for map and cell space.
+
+ Fixed parseInt's octal parsing behavior (ECMA-262 Annex E 15.1.2.2).
+ (issue 1645)
+
+ Added checks for interceptors to negative lookup code in Crankshaft.
+ (Chromium issue 140473)
+
+ Made incremental marking clear ICs and type feedback cells.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-08-01: Version 3.12.19
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-30: Version 3.12.18
+
+ Forced using bit-pattern for signed zero double. (issue 2239)
+
+ Made sure double to int conversion is correct. (issue 2260)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-27: Version 3.12.17
+
+ Always set the callee's context when calling a function from optimized
+ code.
+ (Chromium issue 138887)
+
+ Fixed building with GCC 3.x
+ (issue 2016, 2017)
+
+ Improved API calls that return empty handles.
+ (issue 2245)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-25: Version 3.12.16
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-24: Version 3.12.15
+
+ Added PRESERVE_ASCII_NULL option to String::WriteAscii.
+ (issue 2252)
+
+ Added dependency to HLoadKeyed* instructions to prevent invalid
+ hoisting. (Chromium issue 137768)
+
+ Enabled building d8 for Android on Mac.
+
+ Interpret negative hexadecimal literals as NaN.
+ (issue 2240)
+
+ Expose counters in javascript when using --track-gc-object-stats.
+
+ Enabled building and testing V8 on Android IA.
+
+ Added --trace-parse flag to parser.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-18: Version 3.12.14
+
+ Deactivated optimization of packed arrays.
+ (Chromium issue 137768)
+
+ Fixed broken accessor transition.
+ (Chromium issue 137689)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-17: Version 3.12.13
+
+ Fixed missing tagging of stack value in finally block.
+ (Chromium issue 137496)
+
+ Added more support for heap analysis.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-16: Version 3.12.12
+
+ Added an option to the tickprocessor to specify the directory for lib
+ lookup.
+
+ Fixed ICs for slow objects with native accessor (Chromium issue 137002).
+
+ Fixed transcendental cache on ARM in optimized code (issue 2234).
+
+ New heap inspection tools: counters for object sizes and counts,
+ histograms for external fragmentation.
+
+ Incorporated constness into inferred interfaces (in preparation for
+ handling imports) (issue 1569).
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-12: Version 3.12.11
+
+ Renamed "mips" arch to "mipsel" in the GYP build.
+
+ Fixed computation of call targets on prototypes in Crankshaft.
+ (Chromium issue 125148)
+
+ Removed use of __lookupGetter__ when generating stack trace.
+ (issue 1591)
+
+ Turned on ES 5.2 globals semantics by default.
+ (issue 1991, Chromium issue 80591)
+
+ Synced preparser and parser wrt syntax error in switch..case.
+ (issue 2210)
+
+ Fixed reporting of octal literals in strict mode when preparsing.
+ (issue 2220)
+
+ Fixed inline constructors for Harmony Proxy prototypes.
+ (issue 2225)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-10: Version 3.12.10
+
+ Re-enabled and fixed issue with array bounds check elimination
+ (Chromium issue 132114).
+
+ Fixed Debug::Break crash. (Chromium issue 131642)
+
+ Added optimizing compiler support for JavaScript getters.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-06: Version 3.12.9
+
+ Correctly advance the scanner when scanning unicode regexp flag.
+ (Chromium issue 136084)
+
+ Fixed unhandlified code calling Harmony Proxy traps.
+ (issue 2219)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-05: Version 3.12.8
+
+ Implemented TypedArray.set and ArrayBuffer.slice in d8.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-07-03: Version 3.12.7
+
+ Fixed lazy compilation for strict eval scopes.
+ (Chromium issue 135066)
+
+ Made MACOSX_DEPLOYMENT_TARGET configurable in GYP.
+ (issue 2151)
+
+ Report "hidden properties" in heap profiler for properties case.
+ (issue 2212)
+
+ Activated optimization of packed arrays by default.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-06-29: Version 3.12.6
+
+ Cleaned up hardfp ABI detection for ARM (V8 issue 2140).
+
+ Extended TypedArray support in d8.
+
+
+2012-06-28: Version 3.12.5
+
+ Fixed lazy parsing heuristics to respect outer scope.
+ (Chromium issue 135008)
+
+ Allow using test-wrapper-gypbuild.py on Windows when no python
+ interpreter is registered.
+
+ Performance and stability improvements on all platforms.
+
+
+2012-06-27: Version 3.12.4
+
+ Removed -fomit-frame-pointer flag from Release builds to make
+ the stack walkable by TCMalloc (Chromium issue 133723).
+
+ Ported r7868 (constant masking) to x64 (issue 1374).
+
+ Expose more detailed memory statistics (issue 2201).
+
+ Fixed Harmony Maps and WeakMaps for undefined values
+ (Chromium issue 132744).
+
+ Correctly throw reference error in strict mode with ICs disabled
+ (issue 2119).
+
+ Performance and stability improvements on all platforms.
+
+
+2012-06-25: Version 3.12.3
+
+ Reverted r11835 'Unify promotion and allocation limit computation' due
+ to V8 Splay performance regression on Mac. (Chromium issue 134183)
+
+ Fixed sharing of literal boilerplates for optimized code. (issue 2193)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-06-22: Version 3.12.2
+
+ Made near-jump check more strict in LoadNamedFieldPolymorphic on
+ ia32/x64. (Chromium issue 134055)
+
+ Fixed lazy sweeping heuristics to prevent old-space expansion.
+ (issue 2194)
+
+ Performance and stability improvements on all platforms.
+
+
+2012-06-21: Version 3.12.1
+
+ Performance and stability improvements on all platforms.
+
+
+2012-06-20: Version 3.12.0
+
+ Fixed Chromium issues:
+ 115100, 129628, 131994, 132727, 132741, 132742, 133211
+
+ Fixed V8 issues:
+ 915, 1914, 2034, 2087, 2094, 2134, 2156, 2166, 2172, 2177, 2179, 2185
+
+ Added --extra-code flag to mksnapshot to load JS code into the VM
+ before creating the snapshot.
+
+ Support 'restart call frame' command in the debugger.
+
+ Performance and stability improvements on all platforms.
+
+
2012-06-13: Version 3.11.10
Implemented heap profiler memory usage reporting.
diff --git a/deps/v8/DEPS b/deps/v8/DEPS
index e50d1d20f..8d66960f2 100644
--- a/deps/v8/DEPS
+++ b/deps/v8/DEPS
@@ -5,7 +5,7 @@
deps = {
# Remember to keep the revision in sync with the Makefile.
"v8/build/gyp":
- "http://gyp.googlecode.com/svn/trunk@1282",
+ "http://gyp.googlecode.com/svn/trunk@1501",
}
deps_os = {
diff --git a/deps/v8/Makefile b/deps/v8/Makefile
index 0d825c079..b65ea4c9f 100644
--- a/deps/v8/Makefile
+++ b/deps/v8/Makefile
@@ -30,11 +30,12 @@
CXX ?= g++
LINK ?= g++
OUTDIR ?= out
-TESTJOBS ?= -j16
+TESTJOBS ?=
GYPFLAGS ?=
TESTFLAGS ?=
ANDROID_NDK_ROOT ?=
-ANDROID_TOOL_PREFIX = $(ANDROID_NDK_ROOT)/toolchain/bin/arm-linux-androideabi
+ANDROID_TOOLCHAIN ?=
+ANDROID_V8 ?= /data/local/v8
# Special build flags. Use them like this: "make library=shared"
@@ -57,10 +58,21 @@ endif
ifeq ($(objectprint), on)
GYPFLAGS += -Dv8_object_print=1
endif
+# verifyheap=on
+ifeq ($(verifyheap), on)
+ GYPFLAGS += -Dv8_enable_verify_heap=1
+endif
# snapshot=off
ifeq ($(snapshot), off)
GYPFLAGS += -Dv8_use_snapshot='false'
endif
+# extrachecks=on/off
+ifeq ($(extrachecks), on)
+ GYPFLAGS += -Dv8_enable_extra_checks=1
+endif
+ifeq ($(extrachecks), off)
+ GYPFLAGS += -Dv8_enable_extra_checks=0
+endif
# gdbjit=on
ifeq ($(gdbjit), on)
GYPFLAGS += -Dv8_enable_gdbjit=1
@@ -71,9 +83,9 @@ ifeq ($(liveobjectlist), on)
endif
# vfp3=off
ifeq ($(vfp3), off)
- GYPFLAGS += -Dv8_can_use_vfp_instructions=false
+ GYPFLAGS += -Dv8_can_use_vfp3_instructions=false
else
- GYPFLAGS += -Dv8_can_use_vfp_instructions=true
+ GYPFLAGS += -Dv8_can_use_vfp3_instructions=true
endif
# debuggersupport=off
ifeq ($(debuggersupport), off)
@@ -95,6 +107,14 @@ endif
ifeq ($(strictaliasing), off)
GYPFLAGS += -Dv8_no_strict_aliasing=1
endif
+# regexp=interpreted
+ifeq ($(regexp), interpreted)
+ GYPFLAGS += -Dv8_interpreted_regexp=1
+endif
+# hardfp=on
+ifeq ($(hardfp), on)
+ GYPFLAGS += -Dv8_use_arm_eabi_hardfloat=true
+endif
# ----------------- available targets: --------------------
# - "dependencies": pulls in external dependencies (currently: GYP)
@@ -103,7 +123,7 @@ endif
# - every combination <arch>.<mode>, e.g. "ia32.release"
# - "native": current host's architecture, release mode
# - any of the above with .check appended, e.g. "ia32.release.check"
-# - "android": cross-compile for Android/ARM (release mode)
+# - "android": cross-compile for Android/ARM
# - default (no target specified): build all DEFAULT_ARCHES and MODES
# - "check": build all targets and run all tests
# - "<arch>.clean" for any <arch> in ARCHES
@@ -113,9 +133,10 @@ endif
# Architectures and modes to be compiled. Consider these to be internal
# variables, don't override them (use the targets instead).
-ARCHES = ia32 x64 arm mips
+ARCHES = ia32 x64 arm mipsel
DEFAULT_ARCHES = ia32 x64 arm
MODES = release debug
+ANDROID_ARCHES = android_ia32 android_arm
# List of files that trigger Makefile regeneration:
GYPFILES = build/all.gyp build/common.gypi build/standalone.gypi \
@@ -124,15 +145,19 @@ GYPFILES = build/all.gyp build/common.gypi build/standalone.gypi \
# Generates all combinations of ARCHES and MODES, e.g. "ia32.release".
BUILDS = $(foreach mode,$(MODES),$(addsuffix .$(mode),$(ARCHES)))
+ANDROID_BUILDS = $(foreach mode,$(MODES), \
+ $(addsuffix .$(mode),$(ANDROID_ARCHES)))
# Generates corresponding test targets, e.g. "ia32.release.check".
CHECKS = $(addsuffix .check,$(BUILDS))
+ANDROID_CHECKS = $(addsuffix .check,$(ANDROID_BUILDS))
# File where previously used GYPFLAGS are stored.
ENVFILE = $(OUTDIR)/environment
.PHONY: all check clean dependencies $(ENVFILE).new native \
$(ARCHES) $(MODES) $(BUILDS) $(CHECKS) $(addsuffix .clean,$(ARCHES)) \
$(addsuffix .check,$(MODES)) $(addsuffix .check,$(ARCHES)) \
- must-set-ANDROID_NDK_ROOT
+ $(ANDROID_ARCHES) $(ANDROID_BUILDS) $(ANDROID_CHECKS) \
+ must-set-ANDROID_NDK_ROOT_OR_TOOLCHAIN
# Target definitions. "all" is the default.
all: $(MODES)
@@ -143,6 +168,10 @@ buildbot:
$(MAKE) -C "$(OUTDIR)" BUILDTYPE=$(BUILDTYPE) \
builddir="$(abspath $(OUTDIR))/$(BUILDTYPE)"
+mips mips.release mips.debug:
+ @echo "V8 does not support big-endian MIPS builds at the moment," \
+ "please use little-endian builds (mipsel)."
+
# Compile targets. MODES and ARCHES are convenience targets.
.SECONDEXPANSION:
$(MODES): $(addsuffix .$$@,$(DEFAULT_ARCHES))
@@ -162,42 +191,53 @@ native: $(OUTDIR)/Makefile.native
CXX="$(CXX)" LINK="$(LINK)" BUILDTYPE=Release \
builddir="$(shell pwd)/$(OUTDIR)/$@"
-# TODO(jkummerow): add "android.debug" when we need it.
-android android.release: $(OUTDIR)/Makefile.android
- @$(MAKE) -C "$(OUTDIR)" -f Makefile.android \
- CXX="$(ANDROID_TOOL_PREFIX)-g++" \
- AR="$(ANDROID_TOOL_PREFIX)-ar" \
- RANLIB="$(ANDROID_TOOL_PREFIX)-ranlib" \
- CC="$(ANDROID_TOOL_PREFIX)-gcc" \
- LD="$(ANDROID_TOOL_PREFIX)-ld" \
- LINK="$(ANDROID_TOOL_PREFIX)-g++" \
- BUILDTYPE=Release \
- builddir="$(shell pwd)/$(OUTDIR)/android.release"
+$(ANDROID_ARCHES): $(addprefix $$@.,$(MODES))
+
+$(ANDROID_BUILDS): $(GYPFILES) $(ENVFILE) build/android.gypi \
+ must-set-ANDROID_NDK_ROOT_OR_TOOLCHAIN Makefile.android
+ @$(MAKE) -f Makefile.android $@ \
+ ARCH="$(basename $@)" \
+ MODE="$(subst .,,$(suffix $@))" \
+ OUTDIR="$(OUTDIR)" \
+ GYPFLAGS="$(GYPFLAGS)"
# Test targets.
check: all
- @tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR) \
+ @tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
--arch=$(shell echo $(DEFAULT_ARCHES) | sed -e 's/ /,/g') \
$(TESTFLAGS)
$(addsuffix .check,$(MODES)): $$(basename $$@)
- @tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR) \
+ @tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
--mode=$(basename $@) $(TESTFLAGS)
$(addsuffix .check,$(ARCHES)): $$(basename $$@)
- @tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR) \
+ @tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
--arch=$(basename $@) $(TESTFLAGS)
$(CHECKS): $$(basename $$@)
- @tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR) \
+ @tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
--arch-and-mode=$(basename $@) $(TESTFLAGS)
+$(addsuffix .sync, $(ANDROID_BUILDS)): $$(basename $$@)
+ @tools/android-sync.sh $(basename $@) $(OUTDIR) \
+ $(shell pwd) $(ANDROID_V8)
+
+$(addsuffix .check, $(ANDROID_BUILDS)): $$(basename $$@).sync
+ @tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
+ --arch-and-mode=$(basename $@) \
+ --timeout=600 \
+ --command-prefix="tools/android-run.py"
+
+$(addsuffix .check, $(ANDROID_ARCHES)): \
+ $(addprefix $$(basename $$@).,$(MODES)).check
+
native.check: native
- @tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR)/native \
+ @tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR)/native \
--arch-and-mode=. $(TESTFLAGS)
# Clean targets. You can clean each architecture individually, or everything.
-$(addsuffix .clean,$(ARCHES)) android.clean:
+$(addsuffix .clean, $(ARCHES) $(ANDROID_ARCHES)):
rm -f $(OUTDIR)/Makefile.$(basename $@)
rm -rf $(OUTDIR)/$(basename $@).release
rm -rf $(OUTDIR)/$(basename $@).debug
@@ -208,11 +248,11 @@ native.clean:
rm -rf $(OUTDIR)/native
find $(OUTDIR) -regex '.*\(host\|target\).native\.mk' -delete
-clean: $(addsuffix .clean,$(ARCHES)) native.clean android.clean
+clean: $(addsuffix .clean, $(ARCHES) $(ANDROID_ARCHES)) native.clean
# GYP file generation targets.
-MAKEFILES = $(addprefix $(OUTDIR)/Makefile.,$(ARCHES))
-$(MAKEFILES): $(GYPFILES) $(ENVFILE)
+OUT_MAKEFILES = $(addprefix $(OUTDIR)/Makefile.,$(ARCHES))
+$(OUT_MAKEFILES): $(GYPFILES) $(ENVFILE)
GYP_GENERATORS=make \
build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \
-Ibuild/standalone.gypi --depth=. \
@@ -224,18 +264,11 @@ $(OUTDIR)/Makefile.native: $(GYPFILES) $(ENVFILE)
build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \
-Ibuild/standalone.gypi --depth=. -S.native $(GYPFLAGS)
-$(OUTDIR)/Makefile.android: $(GYPFILES) $(ENVFILE) build/android.gypi \
- must-set-ANDROID_NDK_ROOT
- GYP_GENERATORS=make \
- CC="${ANDROID_TOOL_PREFIX}-gcc" \
- CXX="${ANDROID_TOOL_PREFIX}-g++" \
- build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \
- -Ibuild/standalone.gypi --depth=. -Ibuild/android.gypi \
- -S.android $(GYPFLAGS)
-
-must-set-ANDROID_NDK_ROOT:
+must-set-ANDROID_NDK_ROOT_OR_TOOLCHAIN:
ifndef ANDROID_NDK_ROOT
- $(error ANDROID_NDK_ROOT is not set)
+ifndef ANDROID_TOOLCHAIN
+ $(error ANDROID_NDK_ROOT or ANDROID_TOOLCHAIN must be set))
+endif
endif
# Replaces the old with the new environment file if they're different, which
@@ -251,6 +284,7 @@ $(ENVFILE).new:
echo "CXX=$(CXX)" >> $(ENVFILE).new
# Dependencies.
+# Remember to keep these in sync with the DEPS file.
dependencies:
svn checkout --force http://gyp.googlecode.com/svn/trunk build/gyp \
- --revision 1282
+ --revision 1501
diff --git a/deps/v8/Makefile.android b/deps/v8/Makefile.android
new file mode 100644
index 000000000..8e4ce0814
--- /dev/null
+++ b/deps/v8/Makefile.android
@@ -0,0 +1,92 @@
+# Copyright 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.
+
+# Those definitions should be consistent with the main Makefile
+ANDROID_ARCHES = android_ia32 android_arm
+MODES = release debug
+
+# Generates all combinations of ANDROID ARCHES and MODES,
+# e.g. "android_ia32.release" or "android_arm.release"
+ANDROID_BUILDS = $(foreach mode,$(MODES), \
+ $(addsuffix .$(mode),$(ANDROID_ARCHES)))
+
+HOST_OS = $(shell uname -s | sed -e 's/Linux/linux/;s/Darwin/mac/')
+ifeq ($(HOST_OS), linux)
+ TOOLCHAIN_DIR = linux-x86
+else
+ ifeq ($(HOST_OS), mac)
+ TOOLCHAIN_DIR = darwin-x86
+ else
+ $(error Host platform "${HOST_OS}" is not supported)
+ endif
+endif
+
+ifeq ($(ARCH), android_arm)
+ DEFINES = target_arch=arm v8_target_arch=arm android_target_arch=arm
+ DEFINES += arm_neon=0 armv7=1
+ TOOLCHAIN_ARCH = arm-linux-androideabi-4.6
+else
+ ifeq ($(ARCH), android_ia32)
+ DEFINES = target_arch=ia32 v8_target_arch=ia32 android_target_arch=x86
+ TOOLCHAIN_ARCH = x86-4.6
+ else
+ $(error Target architecture "${ARCH}" is not supported)
+ endif
+endif
+
+TOOLCHAIN_PATH = ${ANDROID_NDK_ROOT}/toolchains/${TOOLCHAIN_ARCH}/prebuilt
+ANDROID_TOOLCHAIN ?= ${TOOLCHAIN_PATH}/${TOOLCHAIN_DIR}
+ifeq ($(wildcard $(ANDROID_TOOLCHAIN)),)
+ $(error Cannot find Android toolchain in "${ANDROID_TOOLCHAIN}")
+endif
+
+# For mksnapshot host generation.
+DEFINES += host_os=${HOST_OS}
+
+.SECONDEXPANSION:
+$(ANDROID_BUILDS): $(OUTDIR)/Makefile.$$(basename $$@)
+ @$(MAKE) -C "$(OUTDIR)" -f Makefile.$(basename $@) \
+ CXX="$(ANDROID_TOOLCHAIN)/bin/*-g++" \
+ AR="$(ANDROID_TOOLCHAIN)/bin/*-ar" \
+ RANLIB="$(ANDROID_TOOLCHAIN)/bin/*-ranlib" \
+ CC="$(ANDROID_TOOLCHAIN)/bin/*-gcc" \
+ LD="$(ANDROID_TOOLCHAIN)/bin/*-ld" \
+ LINK="$(ANDROID_TOOLCHAIN)/bin/*-g++" \
+ BUILDTYPE=$(shell echo $(subst .,,$(suffix $@)) | \
+ python -c "print raw_input().capitalize()") \
+ builddir="$(shell pwd)/$(OUTDIR)/$@"
+
+# Android GYP file generation targets.
+ANDROID_MAKEFILES = $(addprefix $(OUTDIR)/Makefile.,$(ANDROID_ARCHES))
+$(ANDROID_MAKEFILES):
+ @GYP_GENERATORS=make-android \
+ GYP_DEFINES="${DEFINES}" \
+ CC="${ANDROID_TOOLCHAIN}/bin/*-gcc" \
+ CXX="${ANDROID_TOOLCHAIN}/bin/*-g++" \
+ build/gyp/gyp --generator-output="${OUTDIR}" build/all.gyp \
+ -Ibuild/standalone.gypi --depth=. -Ibuild/android.gypi \
+ -S.${ARCH} ${GYPFLAGS}
diff --git a/deps/v8/OWNERS b/deps/v8/OWNERS
new file mode 100644
index 000000000..941e5fe07
--- /dev/null
+++ b/deps/v8/OWNERS
@@ -0,0 +1,11 @@
+danno@chromium.org
+jkummerow@chromium.org
+mmassi@chromium.org
+mstarzinger@chromium.org
+mvstanton@chromium.org
+rossberg@chromium.org
+svenpanne@chromium.org
+ulan@chromium.org
+vegorov@chromium.org
+verwaest@chromium.org
+yangguo@chromium.org
diff --git a/deps/v8/PRESUBMIT.py b/deps/v8/PRESUBMIT.py
new file mode 100644
index 000000000..0077be941
--- /dev/null
+++ b/deps/v8/PRESUBMIT.py
@@ -0,0 +1,71 @@
+# Copyright 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.
+
+"""Top-level presubmit script for V8.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into gcl.
+"""
+
+def _V8PresubmitChecks(input_api, output_api):
+ """Runs the V8 presubmit checks."""
+ import sys
+ sys.path.append(input_api.os_path.join(
+ input_api.PresubmitLocalPath(), 'tools'))
+ from presubmit import CppLintProcessor
+ from presubmit import SourceProcessor
+
+ results = []
+ if not CppLintProcessor().Run(input_api.PresubmitLocalPath()):
+ results.append(output_api.PresubmitError("C++ lint check failed"))
+ if not SourceProcessor().Run(input_api.PresubmitLocalPath()):
+ results.append(output_api.PresubmitError(
+ "Copyright header and trailing whitespaces check failed"))
+ return results
+
+
+def _CommonChecks(input_api, output_api):
+ """Checks common to both upload and commit."""
+ results = []
+ results.extend(input_api.canned_checks.CheckOwners(
+ input_api, output_api, source_file_filter=None))
+ return results
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ results = []
+ results.extend(_CommonChecks(input_api, output_api))
+ return results
+
+
+def CheckChangeOnCommit(input_api, output_api):
+ results = []
+ results.extend(_CommonChecks(input_api, output_api))
+ results.extend(input_api.canned_checks.CheckChangeHasDescription(
+ input_api, output_api))
+ results.extend(_V8PresubmitChecks(input_api, output_api))
+ return results
diff --git a/deps/v8/SConstruct b/deps/v8/SConstruct
index ebce7ff89..5f8616a6b 100644
--- a/deps/v8/SConstruct
+++ b/deps/v8/SConstruct
@@ -59,7 +59,7 @@ LIBRARY_FLAGS = {
'CPPDEFINES': ['V8_INTERPRETED_REGEXP']
},
'mode:debug': {
- 'CPPDEFINES': ['V8_ENABLE_CHECKS', 'OBJECT_PRINT']
+ 'CPPDEFINES': ['V8_ENABLE_CHECKS', 'OBJECT_PRINT', 'VERIFY_HEAP']
},
'objectprint:on': {
'CPPDEFINES': ['OBJECT_PRINT'],
@@ -1157,6 +1157,11 @@ SIMPLE_OPTIONS = {
'default': 'on',
'help': 'use fpu instructions when building the snapshot [MIPS only]'
},
+ 'I_know_I_should_build_with_GYP': {
+ 'values': ['yes', 'no'],
+ 'default': 'no',
+ 'help': 'grace period: temporarily override SCons deprecation'
+ }
}
@@ -1257,7 +1262,35 @@ def IsLegal(env, option, values):
return True
+def WarnAboutDeprecation():
+ print """
+ #####################################################################
+ # #
+ # LAST WARNING: Building V8 with SCons is deprecated. #
+ # #
+ # This only works because you have overridden the kill switch. #
+ # #
+ # MIGRATE TO THE GYP-BASED BUILD NOW! #
+ # #
+ # Instructions: http://code.google.com/p/v8/wiki/BuildingWithGYP. #
+ # #
+ #####################################################################
+ """
+
+
def VerifyOptions(env):
+ if env['I_know_I_should_build_with_GYP'] != 'yes':
+ Abort("Building V8 with SCons is no longer supported. Please use GYP "
+ "instead; you can find instructions are at "
+ "http://code.google.com/p/v8/wiki/BuildingWithGYP.\n\n"
+ "Quitting.\n\n"
+ "For a limited grace period, you can specify "
+ "\"I_know_I_should_build_with_GYP=yes\" to override.")
+ else:
+ WarnAboutDeprecation()
+ import atexit
+ atexit.register(WarnAboutDeprecation)
+
if not IsLegal(env, 'mode', ['debug', 'release']):
return False
if not IsLegal(env, 'sample', ["shell", "process", "lineprocessor"]):
@@ -1600,18 +1633,4 @@ try:
except:
pass
-
-def WarnAboutDeprecation():
- print """
-#######################################################
-# WARNING: Building V8 with SCons is deprecated and #
-# will not work much longer. Please switch to using #
-# the GYP-based build now. Instructions are at #
-# http://code.google.com/p/v8/wiki/BuildingWithGYP. #
-#######################################################
- """
-
-WarnAboutDeprecation()
-import atexit
-atexit.register(WarnAboutDeprecation)
Build()
diff --git a/deps/v8/build/android.gypi b/deps/v8/build/android.gypi
index ffd06484f..d2d1a3572 100644
--- a/deps/v8/build/android.gypi
+++ b/deps/v8/build/android.gypi
@@ -33,35 +33,40 @@
'variables': {
# Location of Android NDK.
'variables': {
- 'variables': {
- 'android_ndk_root%': '<!(/bin/echo -n $ANDROID_NDK_ROOT)',
- 'android_target_arch%': 'arm', # target_arch in android terms.
-
- # Switch between different build types, currently only '0' is
- # supported.
- 'android_build_type%': 0,
- },
- 'android_ndk_root%': '<(android_ndk_root)',
- 'android_ndk_sysroot': '<(android_ndk_root)/platforms/android-9/arch-<(android_target_arch)',
- 'android_build_type%': '<(android_build_type)',
+ 'android_ndk_root%': '<!(/bin/echo -n $ANDROID_NDK_ROOT)',
+ 'android_toolchain%': '<!(/bin/echo -n $ANDROID_TOOLCHAIN)',
+ # Switch between different build types, currently only '0' is
+ # supported.
+ 'android_build_type%': 0,
},
- 'android_ndk_root%': '<(android_ndk_root)',
- 'android_ndk_sysroot': '<(android_ndk_sysroot)',
- 'android_ndk_include': '<(android_ndk_sysroot)/usr/include',
- 'android_ndk_lib': '<(android_ndk_sysroot)/usr/lib',
+ 'conditions': [
+ ['android_ndk_root==""', {
+ 'variables': {
+ 'android_sysroot': '<(android_toolchain)/sysroot/',
+ 'android_stlport': '<(android_toolchain)/sources/cxx-stl/stlport/',
+ },
+ 'android_include': '<(android_sysroot)/usr/include',
+ 'android_lib': '<(android_sysroot)/usr/lib',
+ 'android_stlport_include': '<(android_stlport)/stlport',
+ 'android_stlport_libs': '<(android_stlport)/libs',
+ }, {
+ 'variables': {
+ 'android_sysroot': '<(android_ndk_root)/platforms/android-9/arch-<(android_target_arch)',
+ 'android_stlport': '<(android_ndk_root)/sources/cxx-stl/stlport/',
+ },
+ 'android_include': '<(android_sysroot)/usr/include',
+ 'android_lib': '<(android_sysroot)/usr/lib',
+ 'android_stlport_include': '<(android_stlport)/stlport',
+ 'android_stlport_libs': '<(android_stlport)/libs',
+ }],
+ ],
# Enable to use the system stlport, otherwise statically
# link the NDK one?
'use_system_stlport%': '<(android_build_type)',
'android_stlport_library': 'stlport_static',
# Copy it out one scope.
'android_build_type%': '<(android_build_type)',
-
'OS': 'android',
- 'target_arch': 'arm',
- 'v8_target_arch': 'arm',
- 'armv7': 1,
- 'arm_neon': 0,
- 'arm_fpu': 'vfpv3',
}, # variables
'target_defaults': {
'defines': [
@@ -100,10 +105,7 @@
'-Wno-error=non-virtual-dtor', # TODO(michaelbai): Fix warnings.
# Note: This include is in cflags to ensure that it comes after
# all of the includes.
- '-I<(android_ndk_include)',
- '-march=armv7-a',
- '-mtune=cortex-a8',
- '-mfpu=vfp3',
+ '-I<(android_include)',
],
'defines': [
'ANDROID',
@@ -120,7 +122,6 @@
'ldflags': [
'-nostdlib',
'-Wl,--no-undefined',
- '-Wl,--icf=safe', # Enable identical code folding to reduce size
# Don't export symbols from statically linked libraries.
'-Wl,--exclude-libs=ALL',
],
@@ -144,8 +145,21 @@
'conditions': [
['android_build_type==0', {
'ldflags': [
- '-Wl,-rpath-link=<(android_ndk_lib)',
- '-L<(android_ndk_lib)',
+ '-Wl,-rpath-link=<(android_lib)',
+ '-L<(android_lib)',
+ ],
+ }],
+ ['target_arch == "arm"', {
+ 'ldflags': [
+ # Enable identical code folding to reduce size.
+ '-Wl,--icf=safe',
+ ],
+ }],
+ ['target_arch=="arm" and armv7==1', {
+ 'cflags': [
+ '-march=armv7-a',
+ '-mtune=cortex-a8',
+ '-mfpu=vfp3',
],
}],
# NOTE: The stlport header include paths below are specified in
@@ -156,22 +170,22 @@
# The include ordering here is important; change with caution.
['use_system_stlport==0', {
'cflags': [
- '-I<(android_ndk_root)/sources/cxx-stl/stlport/stlport',
+ '-I<(android_stlport_include)',
],
'conditions': [
['target_arch=="arm" and armv7==1', {
'ldflags': [
- '-L<(android_ndk_root)/sources/cxx-stl/stlport/libs/armeabi-v7a',
+ '-L<(android_stlport_libs)/armeabi-v7a',
],
}],
['target_arch=="arm" and armv7==0', {
'ldflags': [
- '-L<(android_ndk_root)/sources/cxx-stl/stlport/libs/armeabi',
+ '-L<(android_stlport_libs)/armeabi',
],
}],
['target_arch=="ia32"', {
'ldflags': [
- '-L<(android_ndk_root)/sources/cxx-stl/stlport/libs/x86',
+ '-L<(android_stlport_libs)/x86',
],
}],
],
@@ -194,12 +208,12 @@
'-Wl,--gc-sections',
'-Wl,-z,nocopyreloc',
# crtbegin_dynamic.o should be the last item in ldflags.
- '<(android_ndk_lib)/crtbegin_dynamic.o',
+ '<(android_lib)/crtbegin_dynamic.o',
],
'libraries': [
# crtend_android.o needs to be the last item in libraries.
# Do not add any libraries after this!
- '<(android_ndk_lib)/crtend_android.o',
+ '<(android_lib)/crtend_android.o',
],
}],
['_type=="shared_library"', {
@@ -222,4 +236,4 @@
}],
], # target_conditions
}, # target_defaults
-} \ No newline at end of file
+}
diff --git a/deps/v8/build/common.gypi b/deps/v8/build/common.gypi
index 7a780cccb..6e0ef0c99 100644
--- a/deps/v8/build/common.gypi
+++ b/deps/v8/build/common.gypi
@@ -70,13 +70,18 @@
'v8_enable_disassembler%': 0,
- 'v8_object_print%': 0,
+ # Enable extra checks in API functions and other strategic places.
+ 'v8_enable_extra_checks%': 1,
'v8_enable_gdbjit%': 0,
+ 'v8_object_print%': 0,
+
# Enable profiling support. Only required on Windows.
'v8_enable_prof%': 0,
+ 'v8_enable_verify_heap%': 0,
+
# Some versions of GCC 4.5 seem to need -fno-strict-aliasing.
'v8_no_strict_aliasing%': 0,
@@ -96,6 +101,10 @@
# For a shared library build, results in "libv8-<(soname_version).so".
'soname_version%': '',
+
+ # Interpreted regexp engine exists as platform-independent alternative
+ # based where the regular expression is compiled to a bytecode.
+ 'v8_interpreted_regexp%': 0,
},
'target_defaults': {
'conditions': [
@@ -105,12 +114,21 @@
['v8_enable_disassembler==1', {
'defines': ['ENABLE_DISASSEMBLER',],
}],
- ['v8_object_print==1', {
- 'defines': ['OBJECT_PRINT',],
+ ['v8_enable_extra_checks==1', {
+ 'defines': ['ENABLE_EXTRA_CHECKS',],
}],
['v8_enable_gdbjit==1', {
'defines': ['ENABLE_GDB_JIT_INTERFACE',],
}],
+ ['v8_object_print==1', {
+ 'defines': ['OBJECT_PRINT',],
+ }],
+ ['v8_enable_verify_heap==1', {
+ 'defines': ['VERIFY_HEAP',],
+ }],
+ ['v8_interpreted_regexp==1', {
+ 'defines': ['V8_INTERPRETED_REGEXP',],
+ }],
['v8_target_arch=="arm"', {
'defines': [
'V8_TARGET_ARCH_ARM',
@@ -158,12 +176,12 @@
'V8_TARGET_ARCH_IA32',
],
}], # v8_target_arch=="ia32"
- ['v8_target_arch=="mips"', {
+ ['v8_target_arch=="mipsel"', {
'defines': [
'V8_TARGET_ARCH_MIPS',
],
'variables': {
- 'mipscompiler': '<!($(echo ${CXX:-$(which g++)}) -v 2>&1 | grep -q "^Target: mips-" && echo "yes" || echo "no")',
+ 'mipscompiler': '<!($(echo ${CXX:-$(which g++)}) -v 2>&1 | grep -q "^Target: mips" && echo "yes" || echo "no")',
},
'conditions': [
['mipscompiler=="yes"', {
@@ -213,7 +231,7 @@
'defines': ['_MIPS_ARCH_LOONGSON',],
}],
],
- }], # v8_target_arch=="mips"
+ }], # v8_target_arch=="mipsel"
['v8_target_arch=="x64"', {
'defines': [
'V8_TARGET_ARCH_X64',
@@ -226,6 +244,7 @@
'StackReserveSize': '2097152',
},
},
+ 'msvs_configuration_platform': 'x64',
}], # v8_target_arch=="x64"
['v8_use_liveobjectlist=="true"', {
'defines': [
@@ -271,7 +290,7 @@
['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
or OS=="netbsd" or OS=="mac" or OS=="android") and \
(v8_target_arch=="arm" or v8_target_arch=="ia32" or \
- v8_target_arch=="mips")', {
+ v8_target_arch=="mipsel")', {
# Check whether the host compiler and target compiler support the
# '-m32' option and set it if so.
'target_conditions': [
@@ -288,9 +307,14 @@
['_toolset=="target"', {
'variables': {
'm32flag': '<!((echo | $(echo ${CXX_target:-${CXX:-$(which g++)}}) -m32 -E - > /dev/null 2>&1) && echo "-m32" || true)',
+ 'clang%': 0,
},
- 'cflags': [ '<(m32flag)' ],
- 'ldflags': [ '<(m32flag)' ],
+ 'conditions': [
+ ['OS!="android" or clang==1', {
+ 'cflags': [ '<(m32flag)' ],
+ 'ldflags': [ '<(m32flag)' ],
+ }],
+ ],
'xcode_settings': {
'ARCHS': [ 'i386' ],
},
@@ -311,6 +335,7 @@
'ENABLE_DISASSEMBLER',
'V8_ENABLE_CHECKS',
'OBJECT_PRINT',
+ 'VERIFY_HEAP',
],
'msvs_settings': {
'VCCLCompilerTool': {
@@ -333,6 +358,20 @@
'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter',
'-Wnon-virtual-dtor', '-Woverloaded-virtual' ],
}],
+ ['OS=="android"', {
+ 'variables': {
+ 'android_full_debug%': 1,
+ },
+ 'conditions': [
+ ['android_full_debug==0', {
+ # Disable full debug if we want a faster v8 in a debug build.
+ # TODO(2304): pass DISABLE_DEBUG_ASSERT instead of hiding DEBUG.
+ 'defines!': [
+ 'DEBUG',
+ ],
+ }],
+ ],
+ }],
],
}, # Debug
'Release': {
@@ -366,15 +405,17 @@
'InlineFunctionExpansion': '2',
'EnableIntrinsicFunctions': 'true',
'FavorSizeOrSpeed': '0',
- 'OmitFramePointers': 'true',
'StringPooling': 'true',
-
'conditions': [
['OS=="win" and component=="shared_library"', {
'RuntimeLibrary': '2', #/MD
}, {
'RuntimeLibrary': '0', #/MT
}],
+ ['v8_target_arch=="x64"', {
+ # TODO(2207): remove this option once the bug is fixed.
+ 'WholeProgramOptimization': 'true',
+ }],
],
},
'VCLinkerTool': {
diff --git a/deps/v8/build/standalone.gypi b/deps/v8/build/standalone.gypi
index ebdf55723..7145a16e0 100644
--- a/deps/v8/build/standalone.gypi
+++ b/deps/v8/build/standalone.gypi
@@ -33,6 +33,7 @@
'component%': 'static_library',
'visibility%': 'hidden',
'msvs_multi_core_compile%': '1',
+ 'mac_deployment_target%': '10.5',
'variables': {
'variables': {
'variables': {
@@ -45,7 +46,7 @@
# to gyp.
'host_arch%':
'<!(uname -m | sed -e "s/i.86/ia32/;\
- s/x86_64/x64/;s/amd64/x64/;s/arm.*/arm/;s/mips.*/mips/")',
+ s/x86_64/x64/;s/amd64/x64/;s/arm.*/arm/;s/mips.*/mipsel/")',
}, {
# OS!="linux" and OS!="freebsd" and OS!="openbsd" and
# OS!="netbsd" and OS!="mac"
@@ -66,8 +67,9 @@
'werror%': '-Werror',
'conditions': [
['(v8_target_arch=="arm" and host_arch!="arm") or \
- (v8_target_arch=="mips" and host_arch!="mips") or \
- (v8_target_arch=="x64" and host_arch!="x64")', {
+ (v8_target_arch=="mipsel" and host_arch!="mipsel") or \
+ (v8_target_arch=="x64" and host_arch!="x64") or \
+ (OS=="android")', {
'want_separate_host_toolset': 1,
}, {
'want_separate_host_toolset': 0,
@@ -191,7 +193,8 @@
'GCC_TREAT_WARNINGS_AS_ERRORS': 'YES', # -Werror
'GCC_VERSION': '4.2',
'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof
- 'MACOSX_DEPLOYMENT_TARGET': '10.4', # -mmacosx-version-min=10.4
+ # MACOSX_DEPLOYMENT_TARGET maps to -mmacosx-version-min
+ 'MACOSX_DEPLOYMENT_TARGET': '<(mac_deployment_target)',
'PREBINDING': 'NO', # No -Wl,-prebind
'SYMROOT': '<(DEPTH)/xcodebuild',
'USE_HEADERMAP': 'NO',
diff --git a/deps/v8/include/v8-debug.h b/deps/v8/include/v8-debug.h
index 9e85dc462..f432de0be 100755
--- a/deps/v8/include/v8-debug.h
+++ b/deps/v8/include/v8-debug.h
@@ -321,7 +321,7 @@ class EXPORT Debug {
* \endcode
*/
static Local<Value> Call(v8::Handle<v8::Function> fun,
- Handle<Value> data = Handle<Value>());
+ Handle<Value> data = Handle<Value>());
/**
* Returns a mirror object for the given object.
@@ -388,6 +388,14 @@ class EXPORT Debug {
* to change.
*/
static Local<Context> GetDebugContext();
+
+
+ /**
+ * Enable/disable LiveEdit functionality for the given Isolate
+ * (default Isolate if not provided). V8 will abort if LiveEdit is
+ * unexpectedly used. LiveEdit is enabled by default.
+ */
+ static void SetLiveEditEnabled(bool enable, Isolate* isolate = NULL);
};
diff --git a/deps/v8/include/v8-preparser.h b/deps/v8/include/v8-preparser.h
index f11d05ef7..389949d20 100644
--- a/deps/v8/include/v8-preparser.h
+++ b/deps/v8/include/v8-preparser.h
@@ -55,11 +55,12 @@
// Setup for Linux shared library export. There is no need to distinguish
// between building or using the V8 shared library, but we should not
// export symbols when we are building a static library.
-#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED)
+#if defined(__GNUC__) && ((__GNUC__ >= 4) || \
+ (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(V8_SHARED)
#define V8EXPORT __attribute__ ((visibility("default")))
-#else // defined(__GNUC__) && (__GNUC__ >= 4)
+#else
#define V8EXPORT
-#endif // defined(__GNUC__) && (__GNUC__ >= 4)
+#endif
#endif // _WIN32
diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h
index cda246336..c1e9a9e0b 100644
--- a/deps/v8/include/v8-profiler.h
+++ b/deps/v8/include/v8-profiler.h
@@ -50,11 +50,12 @@
// Setup for Linux shared library export. See v8.h in this directory for
// information on how to build/use V8 as shared library.
-#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED)
+#if defined(__GNUC__) && ((__GNUC__ >= 4) || \
+ (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(V8_SHARED)
#define V8EXPORT __attribute__ ((visibility("default")))
-#else // defined(__GNUC__) && (__GNUC__ >= 4)
+#else
#define V8EXPORT
-#endif // defined(__GNUC__) && (__GNUC__ >= 4)
+#endif
#endif // _WIN32
@@ -280,32 +281,12 @@ class V8EXPORT HeapGraphNode {
/** Returns node's own size, in bytes. */
int GetSelfSize() const;
- /**
- * Returns node's retained size, in bytes. That is, self + sizes of
- * the objects that are reachable only from this object. In other
- * words, the size of memory that will be reclaimed having this node
- * collected.
- */
- int GetRetainedSize() const;
-
/** Returns child nodes count of the node. */
int GetChildrenCount() const;
/** Retrieves a child by index. */
const HeapGraphEdge* GetChild(int index) const;
- /** Returns retainer nodes count of the node. */
- int GetRetainersCount() const;
-
- /** Returns a retainer by index. */
- const HeapGraphEdge* GetRetainer(int index) const;
-
- /**
- * Returns a dominator node. This is the node that participates in every
- * path from the snapshot root to the current node.
- */
- const HeapGraphNode* GetDominatorNode() const;
-
/**
* Finds and returns a value from the heap corresponding to this node,
* if the value is still reachable.
diff --git a/deps/v8/include/v8-testing.h b/deps/v8/include/v8-testing.h
index 245f74d87..59eebf9db 100644
--- a/deps/v8/include/v8-testing.h
+++ b/deps/v8/include/v8-testing.h
@@ -50,11 +50,12 @@
// Setup for Linux shared library export. See v8.h in this directory for
// information on how to build/use V8 as shared library.
-#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED)
+#if defined(__GNUC__) && ((__GNUC__ >= 4) || \
+ (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(V8_SHARED)
#define V8EXPORT __attribute__ ((visibility("default")))
-#else // defined(__GNUC__) && (__GNUC__ >= 4)
+#else
#define V8EXPORT
-#endif // defined(__GNUC__) && (__GNUC__ >= 4)
+#endif
#endif // _WIN32
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h
index 77ffb385a..245dc5a82 100644
--- a/deps/v8/include/v8.h
+++ b/deps/v8/include/v8.h
@@ -63,15 +63,16 @@
#else // _WIN32
// Setup for Linux shared library export.
-#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED)
+#if defined(__GNUC__) && ((__GNUC__ >= 4) || \
+ (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(V8_SHARED)
#ifdef BUILDING_V8_SHARED
#define V8EXPORT __attribute__ ((visibility("default")))
#else
#define V8EXPORT
#endif
-#else // defined(__GNUC__) && (__GNUC__ >= 4)
+#else
#define V8EXPORT
-#endif // defined(__GNUC__) && (__GNUC__ >= 4)
+#endif
#endif // _WIN32
@@ -389,7 +390,7 @@ template <class T> class Persistent : public Handle<T> {
*/
inline void MakeWeak(void* parameters, WeakReferenceCallback callback);
- /** Clears the weak reference to this object.*/
+ /** Clears the weak reference to this object. */
inline void ClearWeak();
/**
@@ -401,14 +402,13 @@ template <class T> class Persistent : public Handle<T> {
*/
inline void MarkIndependent();
- /**
- *Checks if the handle holds the only reference to an object.
- */
+ /** Returns true if this handle was previously marked as independent. */
+ inline bool IsIndependent() const;
+
+ /** Checks if the handle holds the only reference to an object. */
inline bool IsNearDeath() const;
- /**
- * Returns true if the handle's reference is weak.
- */
+ /** Returns true if the handle's reference is weak. */
inline bool IsWeak() const;
/**
@@ -417,6 +417,12 @@ template <class T> class Persistent : public Handle<T> {
*/
inline void SetWrapperClassId(uint16_t class_id);
+ /**
+ * Returns the class ID previously assigned to this handle or 0 if no class
+ * ID was previously assigned.
+ */
+ inline uint16_t WrapperClassId() const;
+
private:
friend class ImplementationUtilities;
friend class ObjectTemplate;
@@ -1017,6 +1023,11 @@ class Boolean : public Primitive {
*/
class String : public Primitive {
public:
+ enum Encoding {
+ UNKNOWN_ENCODING = 0x1,
+ TWO_BYTE_ENCODING = 0x0,
+ ASCII_ENCODING = 0x4
+ };
/**
* Returns the number of characters in this string.
*/
@@ -1064,7 +1075,8 @@ class String : public Primitive {
enum WriteOptions {
NO_OPTIONS = 0,
HINT_MANY_WRITES_EXPECTED = 1,
- NO_NULL_TERMINATION = 2
+ NO_NULL_TERMINATION = 2,
+ PRESERVE_ASCII_NULL = 4
};
// 16-bit character codes.
@@ -1179,6 +1191,14 @@ class String : public Primitive {
};
/**
+ * If the string is an external string, return the ExternalStringResourceBase
+ * regardless of the encoding, otherwise return NULL. The encoding of the
+ * string is returned in encoding_out.
+ */
+ inline ExternalStringResourceBase* GetExternalStringResourceBase(
+ Encoding* encoding_out) const;
+
+ /**
* Get the ExternalStringResource for an external string. Returns
* NULL if IsExternal() doesn't return true.
*/
@@ -1341,6 +1361,8 @@ class String : public Primitive {
};
private:
+ V8EXPORT void VerifyExternalStringResourceBase(ExternalStringResourceBase* v,
+ Encoding encoding) const;
V8EXPORT void VerifyExternalStringResource(ExternalStringResource* val) const;
V8EXPORT static void CheckCast(v8::Value* obj);
};
@@ -1367,6 +1389,8 @@ class Integer : public Number {
public:
V8EXPORT static Local<Integer> New(int32_t value);
V8EXPORT static Local<Integer> NewFromUnsigned(uint32_t value);
+ V8EXPORT static Local<Integer> New(int32_t value, Isolate*);
+ V8EXPORT static Local<Integer> NewFromUnsigned(uint32_t value, Isolate*);
V8EXPORT int64_t Value() const;
static inline Integer* Cast(v8::Value* obj);
private:
@@ -1551,6 +1575,12 @@ class Object : public Value {
V8EXPORT Local<String> ObjectProtoToString();
/**
+ * Returns the function invoked as a constructor for this object.
+ * May be the null value.
+ */
+ V8EXPORT Local<Value> GetConstructor();
+
+ /**
* Returns the name of the function invoked as a constructor for this object.
*/
V8EXPORT Local<String> GetConstructorName();
@@ -2630,7 +2660,7 @@ bool V8EXPORT SetResourceConstraints(ResourceConstraints* constraints);
typedef void (*FatalErrorCallback)(const char* location, const char* message);
-typedef void (*MessageCallback)(Handle<Message> message, Handle<Value> data);
+typedef void (*MessageCallback)(Handle<Message> message, Handle<Value> error);
/**
@@ -2909,17 +2939,86 @@ typedef bool (*EntropySource)(unsigned char* buffer, size_t length);
* resolving the location of a return address on the stack. Profilers that
* change the return address on the stack can use this to resolve the stack
* location to whereever the profiler stashed the original return address.
- * When invoked, return_addr_location will point to a location on stack where
- * a machine return address resides, this function should return either the
- * same pointer, or a pointer to the profiler's copy of the original return
- * address.
+ *
+ * \param return_addr_location points to a location on stack where a machine
+ * return address resides.
+ * \returns either return_addr_location, or else a pointer to the profiler's
+ * copy of the original return address.
+ *
+ * \note the resolver function must not cause garbage collection.
*/
typedef uintptr_t (*ReturnAddressLocationResolver)(
uintptr_t return_addr_location);
/**
- * Interface for iterating though all external resources in the heap.
+ * FunctionEntryHook is the type of the profile entry hook called at entry to
+ * any generated function when function-level profiling is enabled.
+ *
+ * \param function the address of the function that's being entered.
+ * \param return_addr_location points to a location on stack where the machine
+ * return address resides. This can be used to identify the caller of
+ * \p function, and/or modified to divert execution when \p function exits.
+ *
+ * \note the entry hook must not cause garbage collection.
+ */
+typedef void (*FunctionEntryHook)(uintptr_t function,
+ uintptr_t return_addr_location);
+
+
+/**
+ * A JIT code event is issued each time code is added, moved or removed.
+ *
+ * \note removal events are not currently issued.
+ */
+struct JitCodeEvent {
+ enum EventType {
+ CODE_ADDED,
+ CODE_MOVED,
+ CODE_REMOVED
+ };
+
+ // Type of event.
+ EventType type;
+ // Start of the instructions.
+ void* code_start;
+ // Size of the instructions.
+ size_t code_len;
+
+ union {
+ // Only valid for CODE_ADDED.
+ struct {
+ // Name of the object associated with the code, note that the string is
+ // not zero-terminated.
+ const char* str;
+ // Number of chars in str.
+ size_t len;
+ } name;
+ // New location of instructions. Only valid for CODE_MOVED.
+ void* new_code_start;
+ };
+};
+
+/**
+ * Option flags passed to the SetJitCodeEventHandler function.
+ */
+enum JitCodeEventOptions {
+ kJitCodeEventDefault = 0,
+ // Generate callbacks for already existent code.
+ kJitCodeEventEnumExisting = 1
+};
+
+
+/**
+ * Callback function passed to SetJitCodeEventHandler.
+ *
+ * \param event code add, move or removal event.
+ */
+typedef void (*JitCodeEventHandler)(const JitCodeEvent* event);
+
+
+/**
+ * Interface for iterating through all external resources in the heap.
*/
class V8EXPORT ExternalResourceVisitor { // NOLINT
public:
@@ -2929,6 +3028,17 @@ class V8EXPORT ExternalResourceVisitor { // NOLINT
/**
+ * Interface for iterating through all the persistent handles in the heap.
+ */
+class V8EXPORT PersistentHandleVisitor { // NOLINT
+ public:
+ virtual ~PersistentHandleVisitor() {}
+ virtual void VisitPersistentHandle(Persistent<Value> value,
+ uint16_t class_id) {}
+};
+
+
+/**
* Container class for static utility functions.
*/
class V8EXPORT V8 {
@@ -2993,8 +3103,7 @@ class V8EXPORT V8 {
* The same message listener can be added more than once and in that
* case it will be called more than once for each message.
*/
- static bool AddMessageListener(MessageCallback that,
- Handle<Value> data = Handle<Value>());
+ static bool AddMessageListener(MessageCallback that);
/**
* Remove all message listeners from the specified callback function.
@@ -3179,6 +3288,43 @@ class V8EXPORT V8 {
ReturnAddressLocationResolver return_address_resolver);
/**
+ * Allows the host application to provide the address of a function that's
+ * invoked on entry to every V8-generated function.
+ * Note that \p entry_hook is invoked at the very start of each
+ * generated function.
+ *
+ * \param entry_hook a function that will be invoked on entry to every
+ * V8-generated function.
+ * \returns true on success on supported platforms, false on failure.
+ * \note Setting a new entry hook function when one is already active will
+ * fail.
+ */
+ static bool SetFunctionEntryHook(FunctionEntryHook entry_hook);
+
+ /**
+ * Allows the host application to provide the address of a function that is
+ * notified each time code is added, moved or removed.
+ *
+ * \param options options for the JIT code event handler.
+ * \param event_handler the JIT code event handler, which will be invoked
+ * each time code is added, moved or removed.
+ * \note \p event_handler won't get notified of existent code.
+ * \note since code removal notifications are not currently issued, the
+ * \p event_handler may get notifications of code that overlaps earlier
+ * code notifications. This happens when code areas are reused, and the
+ * earlier overlapping code areas should therefore be discarded.
+ * \note the events passed to \p event_handler and the strings they point to
+ * are not guaranteed to live past each call. The \p event_handler must
+ * copy strings and other parameters it needs to keep around.
+ * \note the set of events declared in JitCodeEvent::EventType is expected to
+ * grow over time, and the JitCodeEvent structure is expected to accrue
+ * new members. The \p event_handler function must ignore event codes
+ * it does not recognize to maintain future compatibility.
+ */
+ static void SetJitCodeEventHandler(JitCodeEventOptions options,
+ JitCodeEventHandler event_handler);
+
+ /**
* Adjusts the amount of registered external memory. Used to give
* V8 an indication of the amount of externally allocated memory
* that is kept alive by JavaScript objects. V8 uses this to decide
@@ -3299,6 +3445,12 @@ class V8EXPORT V8 {
static void VisitExternalResources(ExternalResourceVisitor* visitor);
/**
+ * Iterates through all the persistent handles in the current isolate's heap
+ * that have class_ids.
+ */
+ static void VisitHandlesWithClassIds(PersistentHandleVisitor* visitor);
+
+ /**
* Optional notification that the embedder is idle.
* V8 uses the notification to reduce memory footprint.
* This call can be used repeatedly if the embedder remains idle.
@@ -3336,10 +3488,12 @@ class V8EXPORT V8 {
WeakReferenceCallback);
static void ClearWeak(internal::Object** global_handle);
static void MarkIndependent(internal::Object** global_handle);
+ static bool IsGlobalIndependent(internal::Object** global_handle);
static bool IsGlobalNearDeath(internal::Object** global_handle);
static bool IsGlobalWeak(internal::Object** global_handle);
static void SetWrapperClassId(internal::Object** global_handle,
uint16_t class_id);
+ static uint16_t GetWrapperClassId(internal::Object** global_handle);
template <class T> friend class Handle;
template <class T> friend class Local;
@@ -3589,7 +3743,7 @@ class V8EXPORT Context {
* with the debugger to provide additional information on the context through
* the debugger API.
*/
- void SetData(Handle<String> data);
+ void SetData(Handle<Value> data);
Local<Value> GetData();
/**
@@ -3614,6 +3768,13 @@ class V8EXPORT Context {
bool IsCodeGenerationFromStringsAllowed();
/**
+ * Sets the error description for the exception that is thrown when
+ * code generation from strings is not allowed and 'eval' or the 'Function'
+ * constructor are called.
+ */
+ void SetErrorMessageForCodeGenerationFromStrings(Handle<String> message);
+
+ /**
* Stack-allocated class which sets the execution context for all
* operations executed within a local scope.
*/
@@ -3919,7 +4080,9 @@ class Internals {
static const int kForeignAddressOffset = kApiPointerSize;
static const int kJSObjectHeaderSize = 3 * kApiPointerSize;
static const int kFullStringRepresentationMask = 0x07;
+ static const int kStringEncodingMask = 0x4;
static const int kExternalTwoByteRepresentationTag = 0x02;
+ static const int kExternalAsciiRepresentationTag = 0x06;
static const int kIsolateStateOffset = 0;
static const int kIsolateEmbedderDataOffset = 1 * kApiPointerSize;
@@ -3928,7 +4091,7 @@ class Internals {
static const int kNullValueRootIndex = 7;
static const int kTrueValueRootIndex = 8;
static const int kFalseValueRootIndex = 9;
- static const int kEmptySymbolRootIndex = 128;
+ static const int kEmptySymbolRootIndex = 117;
static const int kJSObjectType = 0xaa;
static const int kFirstNonstringType = 0x80;
@@ -4048,6 +4211,13 @@ Persistent<T> Persistent<T>::New(Handle<T> that) {
template <class T>
+bool Persistent<T>::IsIndependent() const {
+ if (this->IsEmpty()) return false;
+ return V8::IsGlobalIndependent(reinterpret_cast<internal::Object**>(**this));
+}
+
+
+template <class T>
bool Persistent<T>::IsNearDeath() const {
if (this->IsEmpty()) return false;
return V8::IsGlobalNearDeath(reinterpret_cast<internal::Object**>(**this));
@@ -4093,6 +4263,11 @@ void Persistent<T>::SetWrapperClassId(uint16_t class_id) {
V8::SetWrapperClassId(reinterpret_cast<internal::Object**>(**this), class_id);
}
+template <class T>
+uint16_t Persistent<T>::WrapperClassId() const {
+ return V8::GetWrapperClassId(reinterpret_cast<internal::Object**>(**this));
+}
+
Arguments::Arguments(internal::Object** implicit_args,
internal::Object** values, int length,
bool is_construct_call)
@@ -4274,6 +4449,26 @@ String::ExternalStringResource* String::GetExternalStringResource() const {
}
+String::ExternalStringResourceBase* String::GetExternalStringResourceBase(
+ String::Encoding* encoding_out) const {
+ typedef internal::Object O;
+ typedef internal::Internals I;
+ O* obj = *reinterpret_cast<O**>(const_cast<String*>(this));
+ int type = I::GetInstanceType(obj) & I::kFullStringRepresentationMask;
+ *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
+ ExternalStringResourceBase* resource = NULL;
+ if (type == I::kExternalAsciiRepresentationTag ||
+ type == I::kExternalTwoByteRepresentationTag) {
+ void* value = I::ReadField<void*>(obj, I::kStringResourceOffset);
+ resource = static_cast<ExternalStringResourceBase*>(value);
+ }
+#ifdef V8_ENABLE_CHECKS
+ VerifyExternalStringResourceBase(resource, *encoding_out);
+#endif
+ return resource;
+}
+
+
bool Value::IsUndefined() const {
#ifdef V8_ENABLE_CHECKS
return FullIsUndefined();
diff --git a/deps/v8/preparser/preparser-process.cc b/deps/v8/preparser/preparser-process.cc
index 368f63f6c..1bcc80492 100644
--- a/deps/v8/preparser/preparser-process.cc
+++ b/deps/v8/preparser/preparser-process.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -202,7 +202,7 @@ void fail(v8::PreParserData* data, const char* message, ...) {
fflush(stderr);
if (data != NULL) {
// Print preparser data to stdout.
- uint32_t size = data->size();
+ uint32_t size = static_cast<uint32_t>(data->size());
fprintf(stderr, "LOG: data size: %u\n", size);
if (!WriteBuffer(stdout, data->data(), size)) {
perror("ERROR: Writing data");
@@ -232,7 +232,7 @@ struct ExceptionExpectation {
void CheckException(v8::PreParserData* data,
ExceptionExpectation* expects) {
- PreparseDataInterpreter reader(data->data(), data->size());
+ PreparseDataInterpreter reader(data->data(), static_cast<int>(data->size()));
if (expects->throws) {
if (!reader.throws()) {
if (expects->type == NULL) {
diff --git a/deps/v8/samples/lineprocessor.cc b/deps/v8/samples/lineprocessor.cc
index 7a84a2a0f..26e787f2b 100644
--- a/deps/v8/samples/lineprocessor.cc
+++ b/deps/v8/samples/lineprocessor.cc
@@ -25,19 +25,11 @@
// (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 controls whether this sample is compiled with debugger support.
-// You may trace its usages in source text to see what parts of program
-// are responsible for debugging support.
-// Note that V8 itself should be compiled with enabled debugger support
-// to have it all working.
-#define SUPPORT_DEBUGGING
-
#include <v8.h>
-#ifdef SUPPORT_DEBUGGING
+#ifdef ENABLE_DEBUGGER_SUPPORT
#include <v8-debug.h>
-#endif
+#endif // ENABLE_DEBUGGER_SUPPORT
#include <fcntl.h>
#include <string.h>
@@ -116,7 +108,7 @@ bool RunCppCycle(v8::Handle<v8::Script> script, v8::Local<v8::Context> context,
bool report_exceptions);
-#ifdef SUPPORT_DEBUGGING
+#ifdef ENABLE_DEBUGGER_SUPPORT
v8::Persistent<v8::Context> debug_message_context;
void DispatchDebugMessages() {
@@ -135,7 +127,7 @@ void DispatchDebugMessages() {
v8::Debug::ProcessDebugMessages();
}
-#endif
+#endif // ENABLE_DEBUGGER_SUPPORT
int RunMain(int argc, char* argv[]) {
@@ -146,11 +138,11 @@ int RunMain(int argc, char* argv[]) {
v8::Handle<v8::Value> script_name(NULL);
int script_param_counter = 0;
-#ifdef SUPPORT_DEBUGGING
+#ifdef ENABLE_DEBUGGER_SUPPORT
int port_number = -1;
bool wait_for_connection = false;
bool support_callback = false;
-#endif
+#endif // ENABLE_DEBUGGER_SUPPORT
MainCycleType cycle_type = CycleInCpp;
@@ -164,7 +156,7 @@ int RunMain(int argc, char* argv[]) {
cycle_type = CycleInCpp;
} else if (strcmp(str, "--main-cycle-in-js") == 0) {
cycle_type = CycleInJs;
-#ifdef SUPPORT_DEBUGGING
+#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (strcmp(str, "--callback") == 0) {
support_callback = true;
} else if (strcmp(str, "--wait-for-connection") == 0) {
@@ -172,7 +164,7 @@ int RunMain(int argc, char* argv[]) {
} else if (strcmp(str, "-p") == 0 && i + 1 < argc) {
port_number = atoi(argv[i + 1]); // NOLINT
i++;
-#endif
+#endif // ENABLE_DEBUGGER_SUPPORT
} else if (strncmp(str, "--", 2) == 0) {
printf("Warning: unknown flag %s.\nTry --help for options\n", str);
} else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
@@ -219,7 +211,7 @@ int RunMain(int argc, char* argv[]) {
// Enter the newly created execution environment.
v8::Context::Scope context_scope(context);
-#ifdef SUPPORT_DEBUGGING
+#ifdef ENABLE_DEBUGGER_SUPPORT
debug_message_context = v8::Persistent<v8::Context>::New(context);
v8::Locker locker;
@@ -231,7 +223,7 @@ int RunMain(int argc, char* argv[]) {
if (port_number != -1) {
v8::Debug::EnableAgent("lineprocessor", port_number, wait_for_connection);
}
-#endif
+#endif // ENABLE_DEBUGGER_SUPPORT
bool report_exceptions = true;
@@ -272,9 +264,9 @@ int RunMain(int argc, char* argv[]) {
bool RunCppCycle(v8::Handle<v8::Script> script, v8::Local<v8::Context> context,
bool report_exceptions) {
-#ifdef SUPPORT_DEBUGGING
+#ifdef ENABLE_DEBUGGER_SUPPORT
v8::Locker lock;
-#endif
+#endif // ENABLE_DEBUGGER_SUPPORT
v8::Handle<v8::String> fun_name = v8::String::New("ProcessLine");
v8::Handle<v8::Value> process_val =
@@ -347,7 +339,7 @@ v8::Handle<v8::String> ReadFile(const char* name) {
char* chars = new char[size + 1];
chars[size] = '\0';
for (int i = 0; i < size;) {
- int read = fread(&chars[i], 1, size - i, file);
+ int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
i += read;
}
fclose(file);
@@ -427,9 +419,9 @@ v8::Handle<v8::String> ReadLine() {
char* res;
{
-#ifdef SUPPORT_DEBUGGING
+#ifdef ENABLE_DEBUGGER_SUPPORT
v8::Unlocker unlocker;
-#endif
+#endif // ENABLE_DEBUGGER_SUPPORT
res = fgets(buffer, kBufferSize, stdin);
}
if (res == NULL) {
diff --git a/deps/v8/samples/process.cc b/deps/v8/samples/process.cc
index c0cee4c28..ae6a5500c 100644
--- a/deps/v8/samples/process.cc
+++ b/deps/v8/samples/process.cc
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -351,7 +351,7 @@ Handle<Value> JsHttpRequestProcessor::MapGet(Local<String> name,
// Otherwise fetch the value and wrap it in a JavaScript string
const string& value = (*iter).second;
- return String::New(value.c_str(), value.length());
+ return String::New(value.c_str(), static_cast<int>(value.length()));
}
@@ -443,7 +443,7 @@ Handle<Value> JsHttpRequestProcessor::GetPath(Local<String> name,
const string& path = request->Path();
// Wrap the result in a JavaScript string and return it.
- return String::New(path.c_str(), path.length());
+ return String::New(path.c_str(), static_cast<int>(path.length()));
}
@@ -451,7 +451,7 @@ Handle<Value> JsHttpRequestProcessor::GetReferrer(Local<String> name,
const AccessorInfo& info) {
HttpRequest* request = UnwrapRequest(info.Holder());
const string& path = request->Referrer();
- return String::New(path.c_str(), path.length());
+ return String::New(path.c_str(), static_cast<int>(path.length()));
}
@@ -459,7 +459,7 @@ Handle<Value> JsHttpRequestProcessor::GetHost(Local<String> name,
const AccessorInfo& info) {
HttpRequest* request = UnwrapRequest(info.Holder());
const string& path = request->Host();
- return String::New(path.c_str(), path.length());
+ return String::New(path.c_str(), static_cast<int>(path.length()));
}
@@ -467,7 +467,7 @@ Handle<Value> JsHttpRequestProcessor::GetUserAgent(Local<String> name,
const AccessorInfo& info) {
HttpRequest* request = UnwrapRequest(info.Holder());
const string& path = request->UserAgent();
- return String::New(path.c_str(), path.length());
+ return String::New(path.c_str(), static_cast<int>(path.length()));
}
@@ -557,7 +557,7 @@ Handle<String> ReadFile(const string& name) {
char* chars = new char[size + 1];
chars[size] = '\0';
for (int i = 0; i < size;) {
- int read = fread(&chars[i], 1, size - i, file);
+ int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
i += read;
}
fclose(file);
diff --git a/deps/v8/samples/shell.cc b/deps/v8/samples/shell.cc
index db0cc1a93..821ef75a7 100644
--- a/deps/v8/samples/shell.cc
+++ b/deps/v8/samples/shell.cc
@@ -205,7 +205,7 @@ v8::Handle<v8::String> ReadFile(const char* name) {
char* chars = new char[size + 1];
chars[size] = '\0';
for (int i = 0; i < size;) {
- int read = fread(&chars[i], 1, size - i, file);
+ int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
i += read;
}
fclose(file);
diff --git a/deps/v8/src/SConscript b/deps/v8/src/SConscript
index 2482b379a..16bfb55b3 100755
--- a/deps/v8/src/SConscript
+++ b/deps/v8/src/SConscript
@@ -43,8 +43,8 @@ SOURCES = {
assembler.cc
ast.cc
atomicops_internals_x86_gcc.cc
- bignum.cc
bignum-dtoa.cc
+ bignum.cc
bootstrapper.cc
builtins.cc
cached-powers.cc
@@ -67,27 +67,30 @@ SOURCES = {
disassembler.cc
diy-fp.cc
dtoa.cc
- elements.cc
elements-kind.cc
+ elements.cc
execution.cc
+ extensions/externalize-string-extension.cc
+ extensions/gc-extension.cc
+ extensions/statistics-extension.cc
factory.cc
+ fast-dtoa.cc
+ fixed-dtoa.cc
flags.cc
frames.cc
full-codegen.cc
func-name-inferrer.cc
gdb-jit.cc
global-handles.cc
- fast-dtoa.cc
- fixed-dtoa.cc
handles.cc
heap-profiler.cc
heap.cc
- hydrogen.cc
hydrogen-instructions.cc
+ hydrogen.cc
ic.cc
incremental-marking.cc
- interface.cc
inspector.cc
+ interface.cc
interpreter-irregexp.cc
isolate.cc
jsregexp.cc
@@ -99,34 +102,37 @@ SOURCES = {
log.cc
mark-compact.cc
messages.cc
- objects.cc
objects-printer.cc
objects-visiting.cc
+ objects.cc
once.cc
+ optimizing-compiler-thread.cc
parser.cc
- preparser.cc
preparse-data.cc
+ preparser.cc
profile-generator.cc
property.cc
regexp-macro-assembler-irregexp.cc
regexp-macro-assembler.cc
regexp-stack.cc
rewriter.cc
- runtime.cc
runtime-profiler.cc
+ runtime.cc
safepoint-table.cc
- scanner.cc
scanner-character-streams.cc
+ scanner.cc
scopeinfo.cc
scopes.cc
serialize.cc
snapshot-common.cc
spaces.cc
+ store-buffer.cc
string-search.cc
string-stream.cc
strtod.cc
stub-cache.cc
token.cc
+ transitions.cc
type-info.cc
unicode.cc
utils.cc
@@ -137,10 +143,7 @@ SOURCES = {
v8utils.cc
variables.cc
version.cc
- store-buffer.cc
zone.cc
- extensions/gc-extension.cc
- extensions/externalize-string-extension.cc
"""),
'arch:arm': Split("""
arm/builtins-arm.cc
diff --git a/deps/v8/src/accessors.cc b/deps/v8/src/accessors.cc
index 8aabad0d0..1bc9221a2 100644
--- a/deps/v8/src/accessors.cc
+++ b/deps/v8/src/accessors.cc
@@ -42,15 +42,11 @@ namespace internal {
template <class C>
-static C* FindInPrototypeChain(Object* obj, bool* found_it) {
- ASSERT(!*found_it);
- Heap* heap = HEAP;
- while (!Is<C>(obj)) {
- if (obj == heap->null_value()) return NULL;
- obj = obj->GetPrototype();
+static C* FindInstanceOf(Object* obj) {
+ for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype()) {
+ if (Is<C>(cur)) return C::cast(cur);
}
- *found_it = true;
- return C::cast(obj);
+ return NULL;
}
@@ -81,10 +77,8 @@ MaybeObject* Accessors::ReadOnlySetAccessor(JSObject*, Object* value, void*) {
MaybeObject* Accessors::ArrayGetLength(Object* object, void*) {
// Traverse the prototype chain until we reach an array.
- bool found_it = false;
- JSArray* holder = FindInPrototypeChain<JSArray>(object, &found_it);
- if (!found_it) return Smi::FromInt(0);
- return holder->length();
+ JSArray* holder = FindInstanceOf<JSArray>(object);
+ return holder == NULL ? Smi::FromInt(0) : holder->length();
}
@@ -92,9 +86,9 @@ MaybeObject* Accessors::ArrayGetLength(Object* object, void*) {
Object* Accessors::FlattenNumber(Object* value) {
if (value->IsNumber() || !value->IsJSValue()) return value;
JSValue* wrapper = JSValue::cast(value);
- ASSERT(Isolate::Current()->context()->global_context()->number_function()->
+ ASSERT(Isolate::Current()->context()->native_context()->number_function()->
has_initial_map());
- Map* number_map = Isolate::Current()->context()->global_context()->
+ Map* number_map = Isolate::Current()->context()->native_context()->
number_function()->initial_map();
if (wrapper->map() == number_map) return wrapper->value();
return value;
@@ -448,15 +442,12 @@ const AccessorDescriptor Accessors::ScriptEvalFromFunctionName = {
MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) {
Heap* heap = Isolate::Current()->heap();
- bool found_it = false;
- JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return heap->undefined_value();
+ JSFunction* function = FindInstanceOf<JSFunction>(object);
+ if (function == NULL) return heap->undefined_value();
while (!function->should_have_prototype()) {
- found_it = false;
- function = FindInPrototypeChain<JSFunction>(object->GetPrototype(),
- &found_it);
+ function = FindInstanceOf<JSFunction>(function->GetPrototype());
// There has to be one because we hit the getter.
- ASSERT(found_it);
+ ASSERT(function != NULL);
}
if (!function->has_prototype()) {
@@ -477,9 +468,8 @@ MaybeObject* Accessors::FunctionSetPrototype(JSObject* object,
Object* value,
void*) {
Heap* heap = object->GetHeap();
- bool found_it = false;
- JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return heap->undefined_value();
+ JSFunction* function = FindInstanceOf<JSFunction>(object);
+ if (function == NULL) return heap->undefined_value();
if (!function->should_have_prototype()) {
// Since we hit this accessor, object will have no prototype property.
return object->SetLocalPropertyIgnoreAttributes(heap->prototype_symbol(),
@@ -509,22 +499,20 @@ const AccessorDescriptor Accessors::FunctionPrototype = {
MaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
- bool found_it = false;
- JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return Smi::FromInt(0);
+ JSFunction* function = FindInstanceOf<JSFunction>(object);
+ if (function == NULL) return Smi::FromInt(0);
// Check if already compiled.
- if (!function->shared()->is_compiled()) {
- // If the function isn't compiled yet, the length is not computed
- // correctly yet. Compile it now and return the right length.
- HandleScope scope;
- Handle<JSFunction> handle(function);
- if (!JSFunction::CompileLazy(handle, KEEP_EXCEPTION)) {
- return Failure::Exception();
- }
- return Smi::FromInt(handle->shared()->length());
- } else {
+ if (function->shared()->is_compiled()) {
return Smi::FromInt(function->shared()->length());
}
+ // If the function isn't compiled yet, the length is not computed correctly
+ // yet. Compile it now and return the right length.
+ HandleScope scope;
+ Handle<JSFunction> handle(function);
+ if (JSFunction::CompileLazy(handle, KEEP_EXCEPTION)) {
+ return Smi::FromInt(handle->shared()->length());
+ }
+ return Failure::Exception();
}
@@ -541,10 +529,8 @@ const AccessorDescriptor Accessors::FunctionLength = {
MaybeObject* Accessors::FunctionGetName(Object* object, void*) {
- bool found_it = false;
- JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return HEAP->undefined_value();
- return holder->shared()->name();
+ JSFunction* holder = FindInstanceOf<JSFunction>(object);
+ return holder == NULL ? HEAP->undefined_value() : holder->shared()->name();
}
@@ -589,9 +575,8 @@ static MaybeObject* ConstructArgumentsObjectForInlinedFunction(
MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) {
Isolate* isolate = Isolate::Current();
HandleScope scope(isolate);
- bool found_it = false;
- JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return isolate->heap()->undefined_value();
+ JSFunction* holder = FindInstanceOf<JSFunction>(object);
+ if (holder == NULL) return isolate->heap()->undefined_value();
Handle<JSFunction> function(holder, isolate);
if (function->shared()->native()) return isolate->heap()->null_value();
@@ -727,9 +712,8 @@ MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) {
Isolate* isolate = Isolate::Current();
HandleScope scope(isolate);
AssertNoAllocation no_alloc;
- bool found_it = false;
- JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return isolate->heap()->undefined_value();
+ JSFunction* holder = FindInstanceOf<JSFunction>(object);
+ if (holder == NULL) return isolate->heap()->undefined_value();
if (holder->shared()->native()) return isolate->heap()->null_value();
Handle<JSFunction> function(holder, isolate);
@@ -805,4 +789,69 @@ const AccessorDescriptor Accessors::ObjectPrototype = {
0
};
+
+//
+// Accessors::MakeModuleExport
+//
+
+static v8::Handle<v8::Value> ModuleGetExport(
+ v8::Local<v8::String> property,
+ const v8::AccessorInfo& info) {
+ JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
+ Context* context = Context::cast(instance->context());
+ ASSERT(context->IsModuleContext());
+ int slot = info.Data()->Int32Value();
+ Object* value = context->get(slot);
+ if (value->IsTheHole()) {
+ Handle<String> name = v8::Utils::OpenHandle(*property);
+ Isolate* isolate = instance->GetIsolate();
+ isolate->ScheduleThrow(
+ *isolate->factory()->NewReferenceError("not_defined",
+ HandleVector(&name, 1)));
+ return v8::Handle<v8::Value>();
+ }
+ return v8::Utils::ToLocal(Handle<Object>(value));
+}
+
+
+static void ModuleSetExport(
+ v8::Local<v8::String> property,
+ v8::Local<v8::Value> value,
+ const v8::AccessorInfo& info) {
+ JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
+ Context* context = Context::cast(instance->context());
+ ASSERT(context->IsModuleContext());
+ int slot = info.Data()->Int32Value();
+ Object* old_value = context->get(slot);
+ if (old_value->IsTheHole()) {
+ Handle<String> name = v8::Utils::OpenHandle(*property);
+ Isolate* isolate = instance->GetIsolate();
+ isolate->ScheduleThrow(
+ *isolate->factory()->NewReferenceError("not_defined",
+ HandleVector(&name, 1)));
+ return;
+ }
+ context->set(slot, *v8::Utils::OpenHandle(*value));
+}
+
+
+Handle<AccessorInfo> Accessors::MakeModuleExport(
+ Handle<String> name,
+ int index,
+ PropertyAttributes attributes) {
+ Factory* factory = name->GetIsolate()->factory();
+ Handle<AccessorInfo> info = factory->NewAccessorInfo();
+ info->set_property_attributes(attributes);
+ info->set_all_can_read(true);
+ info->set_all_can_write(true);
+ info->set_name(*name);
+ info->set_data(Smi::FromInt(index));
+ Handle<Object> getter = v8::FromCData(&ModuleGetExport);
+ Handle<Object> setter = v8::FromCData(&ModuleSetExport);
+ info->set_getter(*getter);
+ if (!(attributes & ReadOnly)) info->set_setter(*setter);
+ return info;
+}
+
+
} } // namespace v8::internal
diff --git a/deps/v8/src/accessors.h b/deps/v8/src/accessors.h
index 36b9a9984..250f742fa 100644
--- a/deps/v8/src/accessors.h
+++ b/deps/v8/src/accessors.h
@@ -85,6 +85,10 @@ class Accessors : public AllStatic {
void*);
static MaybeObject* FunctionGetArguments(Object* object, void*);
+ // Accessor infos.
+ static Handle<AccessorInfo> MakeModuleExport(
+ Handle<String> name, int index, PropertyAttributes attributes);
+
private:
// Accessor functions only used through the descriptor.
static MaybeObject* FunctionGetLength(Object* object, void*);
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 0d88047aa..e0ad29b83 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -33,6 +33,7 @@
#include "../include/v8-profiler.h"
#include "../include/v8-testing.h"
#include "bootstrapper.h"
+#include "code-stubs.h"
#include "compiler.h"
#include "conversions-inl.h"
#include "counters.h"
@@ -540,7 +541,9 @@ Extension::Extension(const char* name,
source_(source, source_length_),
dep_count_(dep_count),
deps_(deps),
- auto_enable_(false) { }
+ auto_enable_(false) {
+ CHECK(source != NULL || source_length_ == 0);
+}
v8::Handle<Primitive> Undefined() {
@@ -645,6 +648,14 @@ void V8::MarkIndependent(i::Object** object) {
}
+bool V8::IsGlobalIndependent(i::Object** obj) {
+ i::Isolate* isolate = i::Isolate::Current();
+ LOG_API(isolate, "IsGlobalIndependent");
+ if (!isolate->IsInitialized()) return false;
+ return i::GlobalHandles::IsIndependent(obj);
+}
+
+
bool V8::IsGlobalNearDeath(i::Object** obj) {
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "IsGlobalNearDeath");
@@ -762,13 +773,13 @@ void Context::Exit() {
}
-void Context::SetData(v8::Handle<String> data) {
+void Context::SetData(v8::Handle<Value> data) {
i::Handle<i::Context> env = Utils::OpenHandle(this);
i::Isolate* isolate = env->GetIsolate();
if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
- ASSERT(env->IsGlobalContext());
- if (env->IsGlobalContext()) {
+ ASSERT(env->IsNativeContext());
+ if (env->IsNativeContext()) {
env->set_data(*raw_data);
}
}
@@ -778,16 +789,13 @@ v8::Local<v8::Value> Context::GetData() {
i::Handle<i::Context> env = Utils::OpenHandle(this);
i::Isolate* isolate = env->GetIsolate();
if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
- return v8::Local<Value>();
+ return Local<Value>();
}
- i::Object* raw_result = NULL;
- ASSERT(env->IsGlobalContext());
- if (env->IsGlobalContext()) {
- raw_result = env->data();
- } else {
+ ASSERT(env->IsNativeContext());
+ if (!env->IsNativeContext()) {
return Local<Value>();
}
- i::Handle<i::Object> result(raw_result, isolate);
+ i::Handle<i::Object> result(env->data(), isolate);
return Utils::ToLocal(result);
}
@@ -1066,7 +1074,6 @@ static i::Handle<i::AccessorInfo> MakeAccessorInfo(
v8::PropertyAttribute attributes,
v8::Handle<AccessorSignature> signature) {
i::Handle<i::AccessorInfo> obj = FACTORY->NewAccessorInfo();
- ASSERT(getter != NULL);
SET_FIELD_WRAPPED(obj, set_getter, getter);
SET_FIELD_WRAPPED(obj, set_setter, setter);
if (data.IsEmpty()) data = v8::Undefined();
@@ -1537,9 +1544,10 @@ Local<Script> Script::New(v8::Handle<String> source,
name_obj,
line_offset,
column_offset,
+ isolate->global_context(),
NULL,
pre_data_impl,
- Utils::OpenHandle(*script_data),
+ Utils::OpenHandle(*script_data, true),
i::NOT_NATIVES_CODE);
has_pending_exception = result.is_null();
EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
@@ -3031,6 +3039,17 @@ Local<String> v8::Object::ObjectProtoToString() {
}
+Local<Value> v8::Object::GetConstructor() {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::GetConstructor()",
+ return Local<v8::Function>());
+ ENTER_V8(isolate);
+ i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ i::Handle<i::Object> constructor(self->GetConstructor());
+ return Utils::ToLocal(constructor);
+}
+
+
Local<String> v8::Object::GetConstructorName() {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
@@ -3223,7 +3242,7 @@ void v8::Object::TurnOnAccessCheck() {
i::Deoptimizer::DeoptimizeGlobalObject(*obj);
i::Handle<i::Map> new_map =
- isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
+ isolate->factory()->CopyMap(i::Handle<i::Map>(obj->map()));
new_map->set_is_access_check_needed(true);
obj->set_map(*new_map);
}
@@ -3258,7 +3277,7 @@ static i::Context* GetCreationContext(i::JSObject* object) {
} else {
function = i::JSFunction::cast(constructor);
}
- return function->context()->global_context();
+ return function->context()->native_context();
}
@@ -3287,13 +3306,15 @@ bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
v8::Handle<v8::Value> value) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
+ if (value.IsEmpty()) return DeleteHiddenValue(key);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
+ i::Handle<i::String> key_symbol = FACTORY->LookupSymbol(key_obj);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
i::Handle<i::Object> result =
- i::JSObject::SetHiddenProperty(self, key_obj, value_obj);
+ i::JSObject::SetHiddenProperty(self, key_symbol, value_obj);
return *result == *self;
}
@@ -3305,7 +3326,8 @@ v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
- i::Handle<i::Object> result(self->GetHiddenProperty(*key_obj));
+ i::Handle<i::String> key_symbol = FACTORY->LookupSymbol(key_obj);
+ i::Handle<i::Object> result(self->GetHiddenProperty(*key_symbol));
if (result->IsUndefined()) return v8::Local<v8::Value>();
return Utils::ToLocal(result);
}
@@ -3318,7 +3340,8 @@ bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
- self->DeleteHiddenProperty(*key_obj);
+ i::Handle<i::String> key_symbol = FACTORY->LookupSymbol(key_obj);
+ self->DeleteHiddenProperty(*key_symbol);
return true;
}
@@ -3386,7 +3409,7 @@ void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
+ if (!ApiCheck(length >= 0 && length <= i::ExternalPixelArray::kMaxLength,
"v8::Object::SetIndexedPropertiesToPixelData()",
"length exceeds max acceptable value")) {
return;
@@ -3442,7 +3465,7 @@ void v8::Object::SetIndexedPropertiesToExternalArrayData(
ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
+ if (!ApiCheck(length >= 0 && length <= i::ExternalArray::kMaxLength,
"v8::Object::SetIndexedPropertiesToExternalArrayData()",
"length exceeds max acceptable value")) {
return;
@@ -3835,6 +3858,9 @@ int String::WriteUtf8(char* buffer,
LOG_API(isolate, "String::WriteUtf8");
ENTER_V8(isolate);
i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (options & HINT_MANY_WRITES_EXPECTED) {
+ FlattenString(str); // Flatten the string for efficiency.
+ }
int string_length = str->length();
if (str->IsAsciiRepresentation()) {
int len;
@@ -3891,11 +3917,7 @@ int String::WriteUtf8(char* buffer,
// Slow case.
i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
isolate->string_tracker()->RecordWrite(str);
- if (options & HINT_MANY_WRITES_EXPECTED) {
- // Flatten the string for efficiency. This applies whether we are
- // using StringInputBuffer or Get(i) to access the characters.
- FlattenString(str);
- }
+
write_input_buffer.Reset(0, *str);
int len = str->length();
// Encode the first K - 3 bytes directly into the buffer since we
@@ -3937,8 +3959,9 @@ int String::WriteUtf8(char* buffer,
c,
unibrow::Utf16::kNoPreviousCharacter);
if (pos + written <= capacity) {
- for (int j = 0; j < written; j++)
+ for (int j = 0; j < written; j++) {
buffer[pos + j] = intermediate[j];
+ }
pos += written;
nchars++;
} else {
@@ -3951,8 +3974,9 @@ int String::WriteUtf8(char* buffer,
}
if (nchars_ref != NULL) *nchars_ref = nchars;
if (!(options & NO_NULL_TERMINATION) &&
- (i == len && (capacity == -1 || pos < capacity)))
+ (i == len && (capacity == -1 || pos < capacity))) {
buffer[pos++] = '\0';
+ }
return pos;
}
@@ -3965,28 +3989,45 @@ int String::WriteAscii(char* buffer,
if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
LOG_API(isolate, "String::WriteAscii");
ENTER_V8(isolate);
- i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(this);
isolate->string_tracker()->RecordWrite(str);
if (options & HINT_MANY_WRITES_EXPECTED) {
- // Flatten the string for efficiency. This applies whether we are
- // using StringInputBuffer or Get(i) to access the characters.
- str->TryFlatten();
+ FlattenString(str); // Flatten the string for efficiency.
+ }
+
+ if (str->IsAsciiRepresentation()) {
+ // WriteToFlat is faster than using the StringInputBuffer.
+ if (length == -1) length = str->length() + 1;
+ int len = i::Min(length, str->length() - start);
+ i::String::WriteToFlat(*str, buffer, start, start + len);
+ if (!(options & PRESERVE_ASCII_NULL)) {
+ for (int i = 0; i < len; i++) {
+ if (buffer[i] == '\0') buffer[i] = ' ';
+ }
+ }
+ if (!(options & NO_NULL_TERMINATION) && length > len) {
+ buffer[len] = '\0';
+ }
+ return len;
}
+
+ i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
int end = length;
- if ( (length == -1) || (length > str->length() - start) )
+ if ((length == -1) || (length > str->length() - start)) {
end = str->length() - start;
+ }
if (end < 0) return 0;
write_input_buffer.Reset(start, *str);
int i;
for (i = 0; i < end; i++) {
char c = static_cast<char>(write_input_buffer.GetNext());
- if (c == '\0') c = ' ';
+ if (c == '\0' && !(options & PRESERVE_ASCII_NULL)) c = ' ';
buffer[i] = c;
}
- if (!(options & NO_NULL_TERMINATION) && (length == -1 || i < length))
+ if (!(options & NO_NULL_TERMINATION) && (length == -1 || i < length)) {
buffer[i] = '\0';
+ }
return i;
}
@@ -4005,7 +4046,7 @@ int String::Write(uint16_t* buffer,
if (options & HINT_MANY_WRITES_EXPECTED) {
// Flatten the string for efficiency. This applies whether we are
// using StringInputBuffer or Get(i) to access the characters.
- str->TryFlatten();
+ FlattenString(str);
}
int end = start + length;
if ((length == -1) || (length > str->length() - start) )
@@ -4053,6 +4094,29 @@ void v8::String::VerifyExternalStringResource(
CHECK_EQ(expected, value);
}
+void v8::String::VerifyExternalStringResourceBase(
+ v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
+ i::Handle<i::String> str = Utils::OpenHandle(this);
+ const v8::String::ExternalStringResourceBase* expected;
+ Encoding expectedEncoding;
+ if (i::StringShape(*str).IsExternalAscii()) {
+ const void* resource =
+ i::Handle<i::ExternalAsciiString>::cast(str)->resource();
+ expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
+ expectedEncoding = ASCII_ENCODING;
+ } else if (i::StringShape(*str).IsExternalTwoByte()) {
+ const void* resource =
+ i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
+ expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
+ expectedEncoding = TWO_BYTE_ENCODING;
+ } else {
+ expected = NULL;
+ expectedEncoding = str->IsAsciiRepresentation() ? ASCII_ENCODING
+ : TWO_BYTE_ENCODING;
+ }
+ CHECK_EQ(expected, value);
+ CHECK_EQ(expectedEncoding, encoding);
+}
const v8::String::ExternalAsciiStringResource*
v8::String::GetExternalAsciiStringResource() const {
@@ -4191,8 +4255,9 @@ void v8::Object::SetPointerInInternalField(int index, void* value) {
i::Handle<i::Foreign> foreign =
isolate->factory()->NewForeign(
reinterpret_cast<i::Address>(value), i::TENURED);
- if (!foreign.is_null())
- Utils::OpenHandle(this)->SetInternalField(index, *foreign);
+ if (!foreign.is_null()) {
+ Utils::OpenHandle(this)->SetInternalField(index, *foreign);
+ }
}
ASSERT_EQ(value, GetPointerFromInternalField(index));
}
@@ -4221,6 +4286,20 @@ void v8::V8::SetReturnAddressLocationResolver(
}
+bool v8::V8::SetFunctionEntryHook(FunctionEntryHook entry_hook) {
+ return i::ProfileEntryHookStub::SetFunctionEntryHook(entry_hook);
+}
+
+
+void v8::V8::SetJitCodeEventHandler(
+ JitCodeEventOptions options, JitCodeEventHandler event_handler) {
+ i::Isolate* isolate = i::Isolate::Current();
+ // Ensure that logging is initialized for our isolate.
+ isolate->InitializeLoggingAndCounters();
+ isolate->logger()->SetCodeEventHandler(options, event_handler);
+}
+
+
bool v8::V8::Dispose() {
i::Isolate* isolate = i::Isolate::Current();
if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
@@ -4265,6 +4344,30 @@ void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
}
+void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
+ i::Isolate* isolate = i::Isolate::Current();
+ IsDeadCheck(isolate, "v8::V8::VisitHandlesWithClassId");
+
+ i::AssertNoAllocation no_allocation;
+
+ class VisitorAdapter : public i::ObjectVisitor {
+ public:
+ explicit VisitorAdapter(PersistentHandleVisitor* visitor)
+ : visitor_(visitor) {}
+ virtual void VisitPointers(i::Object** start, i::Object** end) {
+ UNREACHABLE();
+ }
+ virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
+ visitor_->VisitPersistentHandle(ToApi<Value>(i::Handle<i::Object>(p)),
+ class_id);
+ }
+ private:
+ PersistentHandleVisitor* visitor_;
+ } visitor_adapter(visitor);
+ isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
+}
+
+
bool v8::V8::IdleNotification(int hint) {
// Returning true tells the caller that it need not
// continue to call IdleNotification.
@@ -4355,7 +4458,7 @@ Persistent<Context> v8::Context::New(
// Create the environment.
env = isolate->bootstrapper()->CreateEnvironment(
isolate,
- Utils::OpenHandle(*global_object),
+ Utils::OpenHandle(*global_object, true),
proxy_template,
extensions);
@@ -4399,7 +4502,7 @@ void v8::Context::UseDefaultSecurityToken() {
}
ENTER_V8(isolate);
i::Handle<i::Context> env = Utils::OpenHandle(this);
- env->set_security_token(env->global());
+ env->set_security_token(env->global_object());
}
@@ -4444,7 +4547,7 @@ v8::Local<v8::Context> Context::GetCurrent() {
if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
return Local<Context>();
}
- i::Handle<i::Object> current = isolate->global_context();
+ i::Handle<i::Object> current = isolate->native_context();
if (current.is_null()) return Local<Context>();
i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
return Utils::ToLocal(context);
@@ -4457,7 +4560,7 @@ v8::Local<v8::Context> Context::GetCalling() {
return Local<Context>();
}
i::Handle<i::Object> calling =
- isolate->GetCallingGlobalContext();
+ isolate->GetCallingNativeContext();
if (calling.is_null()) return Local<Context>();
i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
return Utils::ToLocal(context);
@@ -4494,9 +4597,9 @@ void Context::ReattachGlobal(Handle<Object> global_object) {
i::Object** ctx = reinterpret_cast<i::Object**>(this);
i::Handle<i::Context> context =
i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
- isolate->bootstrapper()->ReattachGlobal(
- context,
- Utils::OpenHandle(*global_object));
+ i::Handle<i::JSGlobalProxy> global_proxy =
+ i::Handle<i::JSGlobalProxy>::cast(Utils::OpenHandle(*global_object));
+ isolate->bootstrapper()->ReattachGlobal(context, global_proxy);
}
@@ -4528,11 +4631,32 @@ bool Context::IsCodeGenerationFromStringsAllowed() {
}
+void Context::SetErrorMessageForCodeGenerationFromStrings(
+ Handle<String> error) {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate,
+ "v8::Context::SetErrorMessageForCodeGenerationFromStrings()")) {
+ return;
+ }
+ ENTER_V8(isolate);
+ i::Object** ctx = reinterpret_cast<i::Object**>(this);
+ i::Handle<i::Context> context =
+ i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
+ i::Handle<i::Object> error_handle = Utils::OpenHandle(*error);
+ context->set_error_message_for_code_gen_from_strings(*error_handle);
+}
+
+
void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
}
+uint16_t V8::GetWrapperClassId(internal::Object** global_handle) {
+ return i::GlobalHandles::GetWrapperClassId(global_handle);
+}
+
+
Local<v8::Object> ObjectTemplate::NewInstance() {
i::Isolate* isolate = i::Isolate::Current();
ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
@@ -4750,6 +4874,7 @@ Local<String> v8::String::NewExternal(
EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
LOG_API(isolate, "String::NewExternal");
ENTER_V8(isolate);
+ CHECK(resource && resource->data());
i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
isolate->heap()->external_string_table()->AddString(*result);
return Utils::ToLocal(result);
@@ -4770,6 +4895,7 @@ bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
if (isolate->heap()->IsInGCPostProcessing()) {
return false;
}
+ CHECK(resource && resource->data());
bool result = obj->MakeExternal(resource);
if (result && !obj->IsSymbol()) {
isolate->heap()->external_string_table()->AddString(*obj);
@@ -4784,6 +4910,7 @@ Local<String> v8::String::NewExternal(
EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
LOG_API(isolate, "String::NewExternal");
ENTER_V8(isolate);
+ CHECK(resource && resource->data());
i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
isolate->heap()->external_string_table()->AddString(*result);
return Utils::ToLocal(result);
@@ -4805,6 +4932,7 @@ bool v8::String::MakeExternal(
if (isolate->heap()->IsInGCPostProcessing()) {
return false;
}
+ CHECK(resource && resource->data());
bool result = obj->MakeExternal(resource);
if (result && !obj->IsSymbol()) {
isolate->heap()->external_string_table()->AddString(*obj);
@@ -5100,24 +5228,39 @@ Local<Number> v8::Number::New(double value) {
Local<Integer> v8::Integer::New(int32_t value) {
i::Isolate* isolate = i::Isolate::UncheckedCurrent();
EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
+ return v8::Integer::New(value, reinterpret_cast<Isolate*>(isolate));
+}
+
+
+Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
+ i::Isolate* isolate = i::Isolate::Current();
+ EnsureInitializedForIsolate(isolate, "v8::Integer::NewFromUnsigned()");
+ return Integer::NewFromUnsigned(value, reinterpret_cast<Isolate*>(isolate));
+}
+
+
+Local<Integer> v8::Integer::New(int32_t value, Isolate* isolate) {
+ i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ ASSERT(internal_isolate->IsInitialized());
if (i::Smi::IsValid(value)) {
return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
- isolate));
+ internal_isolate));
}
- ENTER_V8(isolate);
- i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
+ ENTER_V8(internal_isolate);
+ i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
return Utils::IntegerToLocal(result);
}
-Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
+Local<Integer> v8::Integer::NewFromUnsigned(uint32_t value, Isolate* isolate) {
+ i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ ASSERT(internal_isolate->IsInitialized());
bool fits_into_int32_t = (value & (1 << 31)) == 0;
if (fits_into_int32_t) {
- return Integer::New(static_cast<int32_t>(value));
+ return Integer::New(static_cast<int32_t>(value), isolate);
}
- i::Isolate* isolate = i::Isolate::Current();
- ENTER_V8(isolate);
- i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
+ ENTER_V8(internal_isolate);
+ i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
return Utils::IntegerToLocal(result);
}
@@ -5127,19 +5270,14 @@ void V8::IgnoreOutOfMemoryException() {
}
-bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
+bool V8::AddMessageListener(MessageCallback that) {
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
NeanderArray listeners(isolate->factory()->message_listeners());
- NeanderObject obj(2);
- obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
- obj.set(1, data.IsEmpty() ?
- isolate->heap()->undefined_value() :
- *Utils::OpenHandle(*data));
- listeners.add(obj.value());
+ listeners.add(isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
return true;
}
@@ -5154,8 +5292,7 @@ void V8::RemoveMessageListeners(MessageCallback that) {
for (int i = 0; i < listeners.length(); i++) {
if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
- NeanderObject listener(i::JSObject::cast(listeners.get(i)));
- i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
+ i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listeners.get(i)));
if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
listeners.set(i, isolate->heap()->undefined_value());
}
@@ -5184,6 +5321,8 @@ void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
i::Isolate* isolate = EnterIsolateIfNeeded();
if (IsDeadCheck(isolate, "v8::V8::SetCreateHistogramFunction()")) return;
isolate->stats_table()->SetCreateHistogramFunction(callback);
+ isolate->InitializeLoggingAndCounters();
+ isolate->counters()->ResetHistograms();
}
void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
@@ -5233,8 +5372,9 @@ void V8::AddImplicitReferences(Persistent<Object> parent,
intptr_t V8::AdjustAmountOfExternalAllocatedMemory(intptr_t change_in_bytes) {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
+ i::Isolate* isolate = i::Isolate::UncheckedCurrent();
+ if (isolate == NULL || !isolate->IsInitialized() ||
+ IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
return 0;
}
return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
@@ -5586,7 +5726,8 @@ bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
foreign =
isolate->factory()->NewForeign(FUNCTION_ADDR(EventCallbackWrapper));
}
- isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
+ isolate->debugger()->SetEventListener(foreign,
+ Utils::OpenHandle(*data, true));
return true;
}
@@ -5601,7 +5742,8 @@ bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
if (that != NULL) {
foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
}
- isolate->debugger()->SetEventListener(foreign, Utils::OpenHandle(*data));
+ isolate->debugger()->SetEventListener(foreign,
+ Utils::OpenHandle(*data, true));
return true;
}
@@ -5612,7 +5754,7 @@ bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
ENTER_V8(isolate);
isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
- Utils::OpenHandle(*data));
+ Utils::OpenHandle(*data, true));
return true;
}
@@ -5751,7 +5893,7 @@ Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
v8::HandleScope scope;
i::Debug* isolate_debug = isolate->debug();
isolate_debug->Load();
- i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
+ i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
i::Handle<i::String> name =
isolate->factory()->LookupAsciiSymbol("MakeMirror");
i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
@@ -5783,6 +5925,7 @@ void Debug::ProcessDebugMessages() {
i::Execution::ProcessDebugMessages(true);
}
+
Local<Context> Debug::GetDebugContext() {
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
@@ -5790,6 +5933,20 @@ Local<Context> Debug::GetDebugContext() {
return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
}
+
+void Debug::SetLiveEditEnabled(bool enable, Isolate* isolate) {
+ // If no isolate is supplied, use the default isolate.
+ i::Debugger* debugger;
+ if (isolate != NULL) {
+ i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ debugger = internal_isolate->debugger();
+ } else {
+ debugger = i::Isolate::GetDefaultIsolateDebugger();
+ }
+ debugger->set_live_edit_enabled(enable);
+}
+
+
#endif // ENABLE_DEBUGGER_SUPPORT
@@ -6374,12 +6531,28 @@ char* HandleScopeImplementer::RestoreThread(char* storage) {
void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
+#ifdef DEBUG
+ bool found_block_before_deferred = false;
+#endif
// Iterate over all handles in the blocks except for the last.
for (int i = blocks()->length() - 2; i >= 0; --i) {
Object** block = blocks()->at(i);
- v->VisitPointers(block, &block[kHandleBlockSize]);
+ if (last_handle_before_deferred_block_ != NULL &&
+ (last_handle_before_deferred_block_ < &block[kHandleBlockSize]) &&
+ (last_handle_before_deferred_block_ >= block)) {
+ v->VisitPointers(block, last_handle_before_deferred_block_);
+ ASSERT(!found_block_before_deferred);
+#ifdef DEBUG
+ found_block_before_deferred = true;
+#endif
+ } else {
+ v->VisitPointers(block, &block[kHandleBlockSize]);
+ }
}
+ ASSERT(last_handle_before_deferred_block_ == NULL ||
+ found_block_before_deferred);
+
// Iterate over live handles in the last block (if any).
if (!blocks()->is_empty()) {
v->VisitPointers(blocks()->last(), handle_scope_data_.next);
@@ -6407,4 +6580,66 @@ char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
return storage + ArchiveSpacePerThread();
}
+
+DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
+ DeferredHandles* deferred =
+ new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
+
+ while (!blocks_.is_empty()) {
+ Object** block_start = blocks_.last();
+ Object** block_limit = &block_start[kHandleBlockSize];
+ // We should not need to check for NoHandleAllocation here. Assert
+ // this.
+ ASSERT(prev_limit == block_limit ||
+ !(block_start <= prev_limit && prev_limit <= block_limit));
+ if (prev_limit == block_limit) break;
+ deferred->blocks_.Add(blocks_.last());
+ blocks_.RemoveLast();
+ }
+
+ // deferred->blocks_ now contains the blocks installed on the
+ // HandleScope stack since BeginDeferredScope was called, but in
+ // reverse order.
+
+ ASSERT(prev_limit == NULL || !blocks_.is_empty());
+
+ ASSERT(!blocks_.is_empty() && prev_limit != NULL);
+ ASSERT(last_handle_before_deferred_block_ != NULL);
+ last_handle_before_deferred_block_ = NULL;
+ return deferred;
+}
+
+
+void HandleScopeImplementer::BeginDeferredScope() {
+ ASSERT(last_handle_before_deferred_block_ == NULL);
+ last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
+}
+
+
+DeferredHandles::~DeferredHandles() {
+ isolate_->UnlinkDeferredHandles(this);
+
+ for (int i = 0; i < blocks_.length(); i++) {
+#ifdef DEBUG
+ HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
+#endif
+ isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
+ }
+}
+
+
+void DeferredHandles::Iterate(ObjectVisitor* v) {
+ ASSERT(!blocks_.is_empty());
+
+ ASSERT((first_block_limit_ >= blocks_.first()) &&
+ (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
+
+ v->VisitPointers(blocks_.first(), first_block_limit_);
+
+ for (int i = 1; i < blocks_.length(); i++) {
+ v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
+ }
+}
+
+
} } // namespace v8::internal
diff --git a/deps/v8/src/api.h b/deps/v8/src/api.h
index 58e6a6e41..7197b6cb5 100644
--- a/deps/v8/src/api.h
+++ b/deps/v8/src/api.h
@@ -159,6 +159,27 @@ class RegisteredExtension {
};
+#define OPEN_HANDLE_LIST(V) \
+ V(Template, TemplateInfo) \
+ V(FunctionTemplate, FunctionTemplateInfo) \
+ V(ObjectTemplate, ObjectTemplateInfo) \
+ V(Signature, SignatureInfo) \
+ V(AccessorSignature, FunctionTemplateInfo) \
+ V(TypeSwitch, TypeSwitchInfo) \
+ V(Data, Object) \
+ V(RegExp, JSRegExp) \
+ V(Object, JSObject) \
+ V(Array, JSArray) \
+ V(String, String) \
+ V(Script, Object) \
+ V(Function, JSFunction) \
+ V(Message, JSObject) \
+ V(Context, Context) \
+ V(External, Foreign) \
+ V(StackTrace, JSArray) \
+ V(StackFrame, JSObject)
+
+
class Utils {
public:
static bool ReportApiFailure(const char* location, const char* message);
@@ -205,42 +226,13 @@ class Utils {
static inline Local<TypeSwitch> ToLocal(
v8::internal::Handle<v8::internal::TypeSwitchInfo> obj);
- static inline v8::internal::Handle<v8::internal::TemplateInfo>
- OpenHandle(const Template* that);
- static inline v8::internal::Handle<v8::internal::FunctionTemplateInfo>
- OpenHandle(const FunctionTemplate* that);
- static inline v8::internal::Handle<v8::internal::ObjectTemplateInfo>
- OpenHandle(const ObjectTemplate* that);
- static inline v8::internal::Handle<v8::internal::Object>
- OpenHandle(const Data* data);
- static inline v8::internal::Handle<v8::internal::JSRegExp>
- OpenHandle(const RegExp* data);
- static inline v8::internal::Handle<v8::internal::JSObject>
- OpenHandle(const v8::Object* data);
- static inline v8::internal::Handle<v8::internal::JSArray>
- OpenHandle(const v8::Array* data);
- static inline v8::internal::Handle<v8::internal::String>
- OpenHandle(const String* data);
- static inline v8::internal::Handle<v8::internal::Object>
- OpenHandle(const Script* data);
- static inline v8::internal::Handle<v8::internal::JSFunction>
- OpenHandle(const Function* data);
- static inline v8::internal::Handle<v8::internal::JSObject>
- OpenHandle(const Message* message);
- static inline v8::internal::Handle<v8::internal::JSArray>
- OpenHandle(const StackTrace* stack_trace);
- static inline v8::internal::Handle<v8::internal::JSObject>
- OpenHandle(const StackFrame* stack_frame);
- static inline v8::internal::Handle<v8::internal::Context>
- OpenHandle(const v8::Context* context);
- static inline v8::internal::Handle<v8::internal::SignatureInfo>
- OpenHandle(const v8::Signature* sig);
- static inline v8::internal::Handle<v8::internal::FunctionTemplateInfo>
- OpenHandle(const v8::AccessorSignature* sig);
- static inline v8::internal::Handle<v8::internal::TypeSwitchInfo>
- OpenHandle(const v8::TypeSwitch* that);
- static inline v8::internal::Handle<v8::internal::Foreign>
- OpenHandle(const v8::External* that);
+#define DECLARE_OPEN_HANDLE(From, To) \
+ static inline v8::internal::Handle<v8::internal::To> \
+ OpenHandle(const From* that, bool allow_empty_handle = false);
+
+OPEN_HANDLE_LIST(DECLARE_OPEN_HANDLE)
+
+#undef DECLARE_OPEN_HANDLE
};
@@ -257,7 +249,7 @@ v8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom(
if (!is_null()) {
handle = *this;
}
- return Utils::OpenHandle(*scope->Close(Utils::ToLocal(handle)));
+ return Utils::OpenHandle(*scope->Close(Utils::ToLocal(handle)), true);
}
@@ -294,33 +286,18 @@ MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
// Implementations of OpenHandle
-#define MAKE_OPEN_HANDLE(From, To) \
- v8::internal::Handle<v8::internal::To> Utils::OpenHandle(\
- const v8::From* that) { \
- return v8::internal::Handle<v8::internal::To>( \
+#define MAKE_OPEN_HANDLE(From, To) \
+ v8::internal::Handle<v8::internal::To> Utils::OpenHandle( \
+ const v8::From* that, bool allow_empty_handle) { \
+ EXTRA_CHECK(allow_empty_handle || that != NULL); \
+ return v8::internal::Handle<v8::internal::To>( \
reinterpret_cast<v8::internal::To**>(const_cast<v8::From*>(that))); \
}
-MAKE_OPEN_HANDLE(Template, TemplateInfo)
-MAKE_OPEN_HANDLE(FunctionTemplate, FunctionTemplateInfo)
-MAKE_OPEN_HANDLE(ObjectTemplate, ObjectTemplateInfo)
-MAKE_OPEN_HANDLE(Signature, SignatureInfo)
-MAKE_OPEN_HANDLE(AccessorSignature, FunctionTemplateInfo)
-MAKE_OPEN_HANDLE(TypeSwitch, TypeSwitchInfo)
-MAKE_OPEN_HANDLE(Data, Object)
-MAKE_OPEN_HANDLE(RegExp, JSRegExp)
-MAKE_OPEN_HANDLE(Object, JSObject)
-MAKE_OPEN_HANDLE(Array, JSArray)
-MAKE_OPEN_HANDLE(String, String)
-MAKE_OPEN_HANDLE(Script, Object)
-MAKE_OPEN_HANDLE(Function, JSFunction)
-MAKE_OPEN_HANDLE(Message, JSObject)
-MAKE_OPEN_HANDLE(Context, Context)
-MAKE_OPEN_HANDLE(External, Foreign)
-MAKE_OPEN_HANDLE(StackTrace, JSArray)
-MAKE_OPEN_HANDLE(StackFrame, JSObject)
+OPEN_HANDLE_LIST(MAKE_OPEN_HANDLE)
#undef MAKE_OPEN_HANDLE
+#undef OPEN_HANDLE_LIST
namespace internal {
@@ -392,6 +369,32 @@ class StringTracker {
};
+class DeferredHandles {
+ public:
+ ~DeferredHandles();
+
+ private:
+ DeferredHandles(Object** first_block_limit, Isolate* isolate)
+ : next_(NULL),
+ previous_(NULL),
+ first_block_limit_(first_block_limit),
+ isolate_(isolate) {
+ isolate->LinkDeferredHandles(this);
+ }
+
+ void Iterate(ObjectVisitor* v);
+
+ List<Object**> blocks_;
+ DeferredHandles* next_;
+ DeferredHandles* previous_;
+ Object** first_block_limit_;
+ Isolate* isolate_;
+
+ friend class HandleScopeImplementer;
+ friend class Isolate;
+};
+
+
// This class is here in order to be able to declare it a friend of
// HandleScope. Moving these methods to be members of HandleScope would be
// neat in some ways, but it would expose internal implementation details in
@@ -409,7 +412,8 @@ class HandleScopeImplementer {
entered_contexts_(0),
saved_contexts_(0),
spare_(NULL),
- call_depth_(0) { }
+ call_depth_(0),
+ last_handle_before_deferred_block_(NULL) { }
~HandleScopeImplementer() {
DeleteArray(spare_);
@@ -445,6 +449,13 @@ class HandleScopeImplementer {
inline bool HasSavedContexts();
inline List<internal::Object**>* blocks() { return &blocks_; }
+ Isolate* isolate() const { return isolate_; }
+
+ void ReturnBlock(Object** block) {
+ ASSERT(block != NULL);
+ if (spare_ != NULL) DeleteArray(spare_);
+ spare_ = block;
+ }
private:
void ResetAfterArchive() {
@@ -452,6 +463,7 @@ class HandleScopeImplementer {
entered_contexts_.Initialize(0);
saved_contexts_.Initialize(0);
spare_ = NULL;
+ last_handle_before_deferred_block_ = NULL;
call_depth_ = 0;
}
@@ -469,6 +481,9 @@ class HandleScopeImplementer {
ASSERT(call_depth_ == 0);
}
+ void BeginDeferredScope();
+ DeferredHandles* Detach(Object** prev_limit);
+
Isolate* isolate_;
List<internal::Object**> blocks_;
// Used as a stack to keep track of entered contexts.
@@ -477,6 +492,7 @@ class HandleScopeImplementer {
List<Context*> saved_contexts_;
Object** spare_;
int call_depth_;
+ Object** last_handle_before_deferred_block_;
// This is only used for threading support.
v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
@@ -484,6 +500,9 @@ class HandleScopeImplementer {
char* RestoreThreadHelper(char* from);
char* ArchiveThreadHelper(char* to);
+ friend class DeferredHandles;
+ friend class DeferredHandleScope;
+
DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer);
};
diff --git a/deps/v8/src/arm/assembler-arm-inl.h b/deps/v8/src/arm/assembler-arm-inl.h
index d5db686c0..6268c332c 100644
--- a/deps/v8/src/arm/assembler-arm-inl.h
+++ b/deps/v8/src/arm/assembler-arm-inl.h
@@ -75,7 +75,7 @@ Address RelocInfo::target_address_address() {
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY
|| rmode_ == EMBEDDED_OBJECT
|| rmode_ == EXTERNAL_REFERENCE);
- return reinterpret_cast<Address>(Assembler::target_address_address_at(pc_));
+ return reinterpret_cast<Address>(Assembler::target_pointer_address_at(pc_));
}
@@ -86,7 +86,8 @@ int RelocInfo::target_address_size() {
void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
- Assembler::set_target_address_at(pc_, target);
+ Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(
+ reinterpret_cast<intptr_t>(target) & ~3));
if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) {
Object* target_code = Code::GetCodeFromTargetAddress(target);
host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
@@ -97,25 +98,30 @@ void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
Object* RelocInfo::target_object() {
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
- return Memory::Object_at(Assembler::target_address_address_at(pc_));
+ return reinterpret_cast<Object*>(Assembler::target_pointer_at(pc_));
}
Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
- return Memory::Object_Handle_at(Assembler::target_address_address_at(pc_));
+ return Handle<Object>(reinterpret_cast<Object**>(
+ Assembler::target_pointer_at(pc_)));
}
Object** RelocInfo::target_object_address() {
+ // Provide a "natural pointer" to the embedded object,
+ // which can be de-referenced during heap iteration.
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
- return reinterpret_cast<Object**>(Assembler::target_address_address_at(pc_));
+ reconstructed_obj_ptr_ =
+ reinterpret_cast<Object*>(Assembler::target_pointer_at(pc_));
+ return &reconstructed_obj_ptr_;
}
void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
- Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target));
+ Assembler::set_target_pointer_at(pc_, reinterpret_cast<Address>(target));
if (mode == UPDATE_WRITE_BARRIER &&
host() != NULL &&
target->IsHeapObject()) {
@@ -127,7 +133,8 @@ void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) {
Address* RelocInfo::target_reference_address() {
ASSERT(rmode_ == EXTERNAL_REFERENCE);
- return reinterpret_cast<Address*>(Assembler::target_address_address_at(pc_));
+ reconstructed_adr_ptr_ = Assembler::target_address_at(pc_);
+ return &reconstructed_adr_ptr_;
}
@@ -141,10 +148,7 @@ Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
JSGlobalPropertyCell* RelocInfo::target_cell() {
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
- Address address = Memory::Address_at(pc_);
- Object* object = HeapObject::FromAddress(
- address - JSGlobalPropertyCell::kValueOffset);
- return reinterpret_cast<JSGlobalPropertyCell*>(object);
+ return JSGlobalPropertyCell::FromValueAddress(Memory::Address_at(pc_));
}
@@ -329,7 +333,7 @@ void Assembler::emit(Instr x) {
}
-Address Assembler::target_address_address_at(Address pc) {
+Address Assembler::target_pointer_address_at(Address pc) {
Address target_pc = pc;
Instr instr = Memory::int32_at(target_pc);
// If we have a bx instruction, the instruction before the bx is
@@ -359,8 +363,63 @@ Address Assembler::target_address_address_at(Address pc) {
}
-Address Assembler::target_address_at(Address pc) {
- return Memory::Address_at(target_address_address_at(pc));
+Address Assembler::target_pointer_at(Address pc) {
+ if (IsMovW(Memory::int32_at(pc))) {
+ ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)));
+ Instruction* instr = Instruction::At(pc);
+ Instruction* next_instr = Instruction::At(pc + kInstrSize);
+ return reinterpret_cast<Address>(
+ (next_instr->ImmedMovwMovtValue() << 16) |
+ instr->ImmedMovwMovtValue());
+ }
+ return Memory::Address_at(target_pointer_address_at(pc));
+}
+
+
+Address Assembler::target_address_from_return_address(Address pc) {
+ // Returns the address of the call target from the return address that will
+ // be returned to after a call.
+#ifdef USE_BLX
+ // Call sequence on V7 or later is :
+ // movw ip, #... @ call address low 16
+ // movt ip, #... @ call address high 16
+ // blx ip
+ // @ return address
+ // Or pre-V7 or cases that need frequent patching:
+ // ldr ip, [pc, #...] @ call address
+ // blx ip
+ // @ return address
+ Address candidate = pc - 2 * Assembler::kInstrSize;
+ Instr candidate_instr(Memory::int32_at(candidate));
+ if (IsLdrPcImmediateOffset(candidate_instr)) {
+ return candidate;
+ }
+ candidate = pc - 3 * Assembler::kInstrSize;
+ ASSERT(IsMovW(Memory::int32_at(candidate)) &&
+ IsMovT(Memory::int32_at(candidate + kInstrSize)));
+ return candidate;
+#else
+ // Call sequence is:
+ // mov lr, pc
+ // ldr pc, [pc, #...] @ call address
+ // @ return address
+ return pc - kInstrSize;
+#endif
+}
+
+
+Address Assembler::return_address_from_call_start(Address pc) {
+#ifdef USE_BLX
+ if (IsLdrPcImmediateOffset(Memory::int32_at(pc))) {
+ return pc + kInstrSize * 2;
+ } else {
+ ASSERT(IsMovW(Memory::int32_at(pc)));
+ ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)));
+ return pc + kInstrSize * 3;
+ }
+#else
+ return pc + kInstrSize;
+#endif
}
@@ -376,17 +435,55 @@ void Assembler::set_external_target_at(Address constant_pool_entry,
}
+static Instr EncodeMovwImmediate(uint32_t immediate) {
+ ASSERT(immediate < 0x10000);
+ return ((immediate & 0xf000) << 4) | (immediate & 0xfff);
+}
+
+
+void Assembler::set_target_pointer_at(Address pc, Address target) {
+ if (IsMovW(Memory::int32_at(pc))) {
+ ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)));
+ uint32_t* instr_ptr = reinterpret_cast<uint32_t*>(pc);
+ uint32_t immediate = reinterpret_cast<uint32_t>(target);
+ uint32_t intermediate = instr_ptr[0];
+ intermediate &= ~EncodeMovwImmediate(0xFFFF);
+ intermediate |= EncodeMovwImmediate(immediate & 0xFFFF);
+ instr_ptr[0] = intermediate;
+ intermediate = instr_ptr[1];
+ intermediate &= ~EncodeMovwImmediate(0xFFFF);
+ intermediate |= EncodeMovwImmediate(immediate >> 16);
+ instr_ptr[1] = intermediate;
+ ASSERT(IsMovW(Memory::int32_at(pc)));
+ ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)));
+ CPU::FlushICache(pc, 2 * kInstrSize);
+ } else {
+ ASSERT(IsLdrPcImmediateOffset(Memory::int32_at(pc)));
+ Memory::Address_at(target_pointer_address_at(pc)) = target;
+ // Intuitively, we would think it is necessary to always flush the
+ // instruction cache after patching a target address in the code as follows:
+ // CPU::FlushICache(pc, sizeof(target));
+ // However, on ARM, no instruction is actually patched in the case
+ // of embedded constants of the form:
+ // ldr ip, [pc, #...]
+ // since the instruction accessing this address in the constant pool remains
+ // unchanged.
+ }
+}
+
+
+Address Assembler::target_address_at(Address pc) {
+ return reinterpret_cast<Address>(
+ reinterpret_cast<intptr_t>(target_pointer_at(pc)) & ~3);
+}
+
+
void Assembler::set_target_address_at(Address pc, Address target) {
- Memory::Address_at(target_address_address_at(pc)) = target;
- // Intuitively, we would think it is necessary to flush the instruction cache
- // after patching a target address in the code as follows:
- // CPU::FlushICache(pc, sizeof(target));
- // However, on ARM, no instruction was actually patched by the assignment
- // above; the target address is not part of an instruction, it is patched in
- // the constant pool and is read via a data access; the instruction accessing
- // this address in the constant pool remains unchanged.
+ set_target_pointer_at(pc, reinterpret_cast<Address>(
+ reinterpret_cast<intptr_t>(target) & ~3));
}
+
} } // namespace v8::internal
#endif // V8_ARM_ASSEMBLER_ARM_INL_H_
diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc
index 1787d158a..9be62a404 100644
--- a/deps/v8/src/arm/assembler-arm.cc
+++ b/deps/v8/src/arm/assembler-arm.cc
@@ -77,14 +77,17 @@ static unsigned CpuFeaturesImpliedByCompiler() {
#endif // defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__)
// && !defined(__SOFTFP__)
#endif // _arm__
+ if (answer & (1u << ARMv7)) {
+ answer |= 1u << UNALIGNED_ACCESSES;
+ }
return answer;
}
void CpuFeatures::Probe() {
- unsigned standard_features = (OS::CpuFeaturesImpliedByPlatform() |
- CpuFeaturesImpliedByCompiler());
+ unsigned standard_features = static_cast<unsigned>(
+ OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler();
ASSERT(supported_ == 0 || supported_ == standard_features);
#ifdef DEBUG
initialized_ = true;
@@ -110,6 +113,14 @@ void CpuFeatures::Probe() {
if (FLAG_enable_armv7) {
supported_ |= 1u << ARMv7;
}
+
+ if (FLAG_enable_sudiv) {
+ supported_ |= 1u << SUDIV;
+ }
+
+ if (FLAG_enable_movw_movt) {
+ supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
+ }
#else // __arm__
// Probe for additional features not already known to be available.
if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) {
@@ -125,6 +136,19 @@ void CpuFeatures::Probe() {
found_by_runtime_probing_ |= 1u << ARMv7;
}
+ if (!IsSupported(SUDIV) && OS::ArmCpuHasFeature(SUDIV)) {
+ found_by_runtime_probing_ |= 1u << SUDIV;
+ }
+
+ if (!IsSupported(UNALIGNED_ACCESSES) && OS::ArmCpuHasFeature(ARMv7)) {
+ found_by_runtime_probing_ |= 1u << UNALIGNED_ACCESSES;
+ }
+
+ if (OS::GetCpuImplementer() == QUALCOMM_IMPLEMENTER &&
+ OS::ArmCpuHasFeature(ARMv7)) {
+ found_by_runtime_probing_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
+ }
+
supported_ |= found_by_runtime_probing_;
#endif
@@ -300,8 +324,10 @@ static const int kMinimalBufferSize = 4*KB;
Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
: AssemblerBase(arg_isolate),
+ recorded_ast_id_(TypeFeedbackId::None()),
positions_recorder_(this),
- emit_debug_code_(FLAG_debug_code) {
+ emit_debug_code_(FLAG_debug_code),
+ predictable_code_size_(false) {
if (buffer == NULL) {
// Do our own buffer management.
if (buffer_size <= kMinimalBufferSize) {
@@ -713,12 +739,6 @@ void Assembler::next(Label* L) {
}
-static Instr EncodeMovwImmediate(uint32_t immediate) {
- ASSERT(immediate < 0x10000);
- return ((immediate & 0xf000) << 4) | (immediate & 0xfff);
-}
-
-
// Low-level code emission routines depending on the addressing mode.
// If this returns true then you have to use the rotate_imm and immed_8
// that it returns, because it may have already changed the instruction
@@ -754,7 +774,7 @@ static bool fits_shifter(uint32_t imm32,
}
}
} else if ((*instr & kCmpCmnMask) == kCmpCmnPattern) {
- if (fits_shifter(-imm32, rotate_imm, immed_8, NULL)) {
+ if (fits_shifter(-static_cast<int>(imm32), rotate_imm, immed_8, NULL)) {
*instr ^= kCmpCmnFlip;
return true;
}
@@ -762,7 +782,7 @@ static bool fits_shifter(uint32_t imm32,
Instr alu_insn = (*instr & kALUMask);
if (alu_insn == ADD ||
alu_insn == SUB) {
- if (fits_shifter(-imm32, rotate_imm, immed_8, NULL)) {
+ if (fits_shifter(-static_cast<int>(imm32), rotate_imm, immed_8, NULL)) {
*instr ^= kAddSubFlip;
return true;
}
@@ -783,13 +803,14 @@ static bool fits_shifter(uint32_t imm32,
// if they can be encoded in the ARM's 12 bits of immediate-offset instruction
// space. There is no guarantee that the relocated location can be similarly
// encoded.
-bool Operand::must_use_constant_pool() const {
+bool Operand::must_output_reloc_info(const Assembler* assembler) const {
if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
#ifdef DEBUG
if (!Serializer::enabled()) {
Serializer::TooLateToEnableNow();
}
#endif // def DEBUG
+ if (assembler != NULL && assembler->predictable_code_size()) return true;
return Serializer::enabled();
} else if (rmode_ == RelocInfo::NONE) {
return false;
@@ -798,24 +819,28 @@ bool Operand::must_use_constant_pool() const {
}
-bool Operand::is_single_instruction(Instr instr) const {
+static bool use_movw_movt(const Operand& x, const Assembler* assembler) {
+ if (Assembler::use_immediate_embedded_pointer_loads(assembler)) {
+ return true;
+ }
+ if (x.must_output_reloc_info(assembler)) {
+ return false;
+ }
+ return CpuFeatures::IsSupported(ARMv7);
+}
+
+
+bool Operand::is_single_instruction(const Assembler* assembler,
+ Instr instr) const {
if (rm_.is_valid()) return true;
uint32_t dummy1, dummy2;
- if (must_use_constant_pool() ||
+ if (must_output_reloc_info(assembler) ||
!fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
// The immediate operand cannot be encoded as a shifter operand, or use of
// constant pool is required. For a mov instruction not setting the
// condition code additional instruction conventions can be used.
if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
- if (must_use_constant_pool() ||
- !CpuFeatures::IsSupported(ARMv7)) {
- // mov instruction will be an ldr from constant pool (one instruction).
- return true;
- } else {
- // mov instruction will be a mov or movw followed by movt (two
- // instructions).
- return false;
- }
+ return !use_movw_movt(*this, assembler);
} else {
// If this is not a mov or mvn instruction there will always an additional
// instructions - either mov or ldr. The mov might actually be two
@@ -831,6 +856,29 @@ bool Operand::is_single_instruction(Instr instr) const {
}
+void Assembler::move_32_bit_immediate(Condition cond,
+ Register rd,
+ SBit s,
+ const Operand& x) {
+ if (rd.code() != pc.code() && s == LeaveCC) {
+ if (use_movw_movt(x, this)) {
+ if (x.must_output_reloc_info(this)) {
+ RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL);
+ // Make sure the movw/movt doesn't get separated.
+ BlockConstPoolFor(2);
+ }
+ emit(cond | 0x30*B20 | rd.code()*B12 |
+ EncodeMovwImmediate(x.imm32_ & 0xffff));
+ movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond);
+ return;
+ }
+ }
+
+ RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
+ ldr(rd, MemOperand(pc, 0), cond);
+}
+
+
void Assembler::addrmod1(Instr instr,
Register rn,
Register rd,
@@ -841,7 +889,7 @@ void Assembler::addrmod1(Instr instr,
// Immediate.
uint32_t rotate_imm;
uint32_t immed_8;
- if (x.must_use_constant_pool() ||
+ if (x.must_output_reloc_info(this) ||
!fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) {
// The immediate operand cannot be encoded as a shifter operand, so load
// it first to register ip and change the original instruction to use ip.
@@ -850,24 +898,19 @@ void Assembler::addrmod1(Instr instr,
CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed
Condition cond = Instruction::ConditionField(instr);
if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
- if (x.must_use_constant_pool() ||
- !CpuFeatures::IsSupported(ARMv7)) {
- RecordRelocInfo(x.rmode_, x.imm32_);
- ldr(rd, MemOperand(pc, 0), cond);
- } else {
- // Will probably use movw, will certainly not use constant pool.
- mov(rd, Operand(x.imm32_ & 0xffff), LeaveCC, cond);
- movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond);
- }
+ move_32_bit_immediate(cond, rd, LeaveCC, x);
} else {
- // If this is not a mov or mvn instruction we may still be able to avoid
- // a constant pool entry by using mvn or movw.
- if (!x.must_use_constant_pool() &&
- (instr & kMovMvnMask) != kMovMvnPattern) {
- mov(ip, x, LeaveCC, cond);
- } else {
- RecordRelocInfo(x.rmode_, x.imm32_);
+ if ((instr & kMovMvnMask) == kMovMvnPattern) {
+ // Moves need to use a constant pool entry.
+ RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
ldr(ip, MemOperand(pc, 0), cond);
+ } else if (x.must_output_reloc_info(this)) {
+ // Otherwise, use most efficient form of fetching from constant pool.
+ move_32_bit_immediate(cond, ip, LeaveCC, x);
+ } else {
+ // If this is not a mov or mvn instruction we may still be able to
+ // avoid a constant pool entry by using mvn or movw.
+ mov(ip, x, LeaveCC, cond);
}
addrmod1(instr, rn, rd, Operand(ip));
}
@@ -1174,6 +1217,9 @@ void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
void Assembler::movw(Register reg, uint32_t immediate, Condition cond) {
ASSERT(immediate < 0x10000);
+ // May use movw if supported, but on unsupported platforms will try to use
+ // equivalent rotated immed_8 value and other tricks before falling back to a
+ // constant pool load.
mov(reg, Operand(immediate), LeaveCC, cond);
}
@@ -1203,6 +1249,22 @@ void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
}
+void Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
+ Condition cond) {
+ ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
+ emit(cond | B22 | B21 | dst.code()*B16 | srcA.code()*B12 |
+ src2.code()*B8 | B7 | B4 | src1.code());
+}
+
+
+void Assembler::sdiv(Register dst, Register src1, Register src2,
+ Condition cond) {
+ ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
+ emit(cond | B26 | B25| B24 | B20 | dst.code()*B16 | 0xf * B12 |
+ src2.code()*B8 | B4 | src1.code());
+}
+
+
void Assembler::mul(Register dst, Register src1, Register src2,
SBit s, Condition cond) {
ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
@@ -1387,7 +1449,7 @@ void Assembler::msr(SRegisterFieldMask fields, const Operand& src,
// Immediate.
uint32_t rotate_imm;
uint32_t immed_8;
- if (src.must_use_constant_pool() ||
+ if (src.must_output_reloc_info(this) ||
!fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) {
// Immediate operand cannot be encoded, load it first to register ip.
RecordRelocInfo(src.rmode_, src.imm32_);
@@ -1822,7 +1884,7 @@ void Assembler::vstr(const SwVfpRegister src,
const Condition cond) {
ASSERT(!operand.rm().is_valid());
ASSERT(operand.am_ == Offset);
- vldr(src, operand.rn(), operand.offset(), cond);
+ vstr(src, operand.rn(), operand.offset(), cond);
}
@@ -1842,6 +1904,7 @@ void Assembler::vldm(BlockAddrMode am,
int sd, d;
first.split_code(&sd, &d);
int count = last.code() - first.code() + 1;
+ ASSERT(count <= 16);
emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 |
0xB*B8 | count*2);
}
@@ -1863,6 +1926,7 @@ void Assembler::vstm(BlockAddrMode am,
int sd, d;
first.split_code(&sd, &d);
int count = last.code() - first.code() + 1;
+ ASSERT(count <= 16);
emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 |
0xB*B8 | count*2);
}
@@ -1969,6 +2033,7 @@ static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) {
void Assembler::vmov(const DwVfpRegister dst,
double imm,
+ const Register scratch,
const Condition cond) {
// Dd = immediate
// Instruction details available in ARM DDI 0406B, A8-640.
@@ -1983,22 +2048,22 @@ void Assembler::vmov(const DwVfpRegister dst,
// using vldr from a constant pool.
uint32_t lo, hi;
DoubleAsTwoUInt32(imm, &lo, &hi);
+ mov(ip, Operand(lo));
- if (lo == hi) {
- // If the lo and hi parts of the double are equal, the literal is easier
- // to create. This is the case with 0.0.
- mov(ip, Operand(lo));
- vmov(dst, ip, ip);
- } else {
+ if (scratch.is(no_reg)) {
// Move the low part of the double into the lower of the corresponsing S
// registers of D register dst.
- mov(ip, Operand(lo));
vmov(dst.low(), ip, cond);
// Move the high part of the double into the higher of the corresponsing S
// registers of D register dst.
mov(ip, Operand(hi));
vmov(dst.high(), ip, cond);
+ } else {
+ // Move the low and high parts of the double to a D register in one
+ // instruction.
+ mov(scratch, Operand(hi));
+ vmov(dst, ip, scratch, cond);
}
}
}
@@ -2402,15 +2467,35 @@ void Assembler::vsqrt(const DwVfpRegister dst,
// Pseudo instructions.
void Assembler::nop(int type) {
- // This is mov rx, rx.
- ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop.
+ // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes
+ // some of the CPU's pipeline and has to issue. Older ARM chips simply used
+ // MOV Rx, Rx as NOP and it performs better even in newer CPUs.
+ // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode
+ // a type.
+ ASSERT(0 <= type && type <= 14); // mov pc, pc isn't a nop.
emit(al | 13*B21 | type*B12 | type);
}
+bool Assembler::IsMovT(Instr instr) {
+ instr &= ~(((kNumberOfConditions - 1) << 28) | // Mask off conditions
+ ((kNumRegisters-1)*B12) | // mask out register
+ EncodeMovwImmediate(0xFFFF)); // mask out immediate value
+ return instr == 0x34*B20;
+}
+
+
+bool Assembler::IsMovW(Instr instr) {
+ instr &= ~(((kNumberOfConditions - 1) << 28) | // Mask off conditions
+ ((kNumRegisters-1)*B12) | // mask out destination
+ EncodeMovwImmediate(0xFFFF)); // mask out immediate value
+ return instr == 0x30*B20;
+}
+
+
bool Assembler::IsNop(Instr instr, int type) {
+ ASSERT(0 <= type && type <= 14); // mov pc, pc isn't a nop.
// Check for mov rx, rx where x = type.
- ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop.
return instr == (al | 13*B21 | type*B12 | type);
}
@@ -2445,6 +2530,14 @@ void Assembler::RecordComment(const char* msg) {
}
+void Assembler::RecordConstPool(int size) {
+ // We only need this for debugger support, to correctly compute offsets in the
+ // code.
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size));
+#endif
+}
+
void Assembler::GrowBuffer() {
if (!own_buffer_) FATAL("external code buffer is too small");
@@ -2518,15 +2611,21 @@ void Assembler::dd(uint32_t data) {
}
-void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
+void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data,
+ UseConstantPoolMode mode) {
// We do not try to reuse pool constants.
RelocInfo rinfo(pc_, rmode, data, NULL);
- if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::DEBUG_BREAK_SLOT) {
+ if (((rmode >= RelocInfo::JS_RETURN) &&
+ (rmode <= RelocInfo::DEBUG_BREAK_SLOT)) ||
+ (rmode == RelocInfo::CONST_POOL) ||
+ mode == DONT_USE_CONSTANT_POOL) {
// Adjust code for new modes.
ASSERT(RelocInfo::IsDebugBreakSlot(rmode)
|| RelocInfo::IsJSReturn(rmode)
|| RelocInfo::IsComment(rmode)
- || RelocInfo::IsPosition(rmode));
+ || RelocInfo::IsPosition(rmode)
+ || RelocInfo::IsConstPool(rmode)
+ || mode == DONT_USE_CONSTANT_POOL);
// These modes do not need an entry in the constant pool.
} else {
ASSERT(num_pending_reloc_info_ < kMaxNumPendingRelocInfo);
@@ -2552,7 +2651,10 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
}
ASSERT(buffer_space() >= kMaxRelocSize); // too late to grow buffer here
if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
- RelocInfo reloc_info_with_ast_id(pc_, rmode, RecordedAstId(), NULL);
+ RelocInfo reloc_info_with_ast_id(pc_,
+ rmode,
+ RecordedAstId().ToInt(),
+ NULL);
ClearRecordedAstId();
reloc_info_writer.Write(&reloc_info_with_ast_id);
} else {
@@ -2612,13 +2714,15 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
// pool (include the jump over the pool and the constant pool marker and
// the gap to the relocation information).
int jump_instr = require_jump ? kInstrSize : 0;
- int needed_space = jump_instr + kInstrSize +
- num_pending_reloc_info_ * kInstrSize + kGap;
+ int size = jump_instr + kInstrSize + num_pending_reloc_info_ * kPointerSize;
+ int needed_space = size + kGap;
while (buffer_space() <= needed_space) GrowBuffer();
{
// Block recursive calls to CheckConstPool.
BlockConstPoolScope block_const_pool(this);
+ RecordComment("[ Constant Pool");
+ RecordConstPool(size);
// Emit jump over constant pool if necessary.
Label after_pool;
@@ -2626,8 +2730,6 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
b(&after_pool);
}
- RecordComment("[ Constant Pool");
-
// Put down constant pool marker "Undefined instruction" as specified by
// A5.6 (ARMv7) Instruction set encoding.
emit(kConstantPoolMarker | num_pending_reloc_info_);
@@ -2637,21 +2739,24 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
RelocInfo& rinfo = pending_reloc_info_[i];
ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
rinfo.rmode() != RelocInfo::POSITION &&
- rinfo.rmode() != RelocInfo::STATEMENT_POSITION);
+ rinfo.rmode() != RelocInfo::STATEMENT_POSITION &&
+ rinfo.rmode() != RelocInfo::CONST_POOL);
Instr instr = instr_at(rinfo.pc());
// Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0.
- ASSERT(IsLdrPcImmediateOffset(instr) &&
- GetLdrRegisterImmediateOffset(instr) == 0);
-
- int delta = pc_ - rinfo.pc() - kPcLoadDelta;
- // 0 is the smallest delta:
- // ldr rd, [pc, #0]
- // constant pool marker
- // data
- ASSERT(is_uint12(delta));
-
- instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta));
+ if (IsLdrPcImmediateOffset(instr) &&
+ GetLdrRegisterImmediateOffset(instr) == 0) {
+ int delta = pc_ - rinfo.pc() - kPcLoadDelta;
+ // 0 is the smallest delta:
+ // ldr rd, [pc, #0]
+ // constant pool marker
+ // data
+ ASSERT(is_uint12(delta));
+
+ instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta));
+ } else {
+ ASSERT(IsMovW(instr));
+ }
emit(rinfo.data());
}
diff --git a/deps/v8/src/arm/assembler-arm.h b/deps/v8/src/arm/assembler-arm.h
index e0518ef77..dfcce6011 100644
--- a/deps/v8/src/arm/assembler-arm.h
+++ b/deps/v8/src/arm/assembler-arm.h
@@ -424,8 +424,8 @@ class Operand BASE_EMBEDDED {
// the instruction this operand is used for is a MOV or MVN instruction the
// actual instruction to use is required for this calculation. For other
// instructions instr is ignored.
- bool is_single_instruction(Instr instr = 0) const;
- bool must_use_constant_pool() const;
+ bool is_single_instruction(const Assembler* assembler, Instr instr = 0) const;
+ bool must_output_reloc_info(const Assembler* assembler) const;
inline int32_t immediate() const {
ASSERT(!rm_.is_valid());
@@ -511,6 +511,10 @@ class CpuFeatures : public AllStatic {
ASSERT(initialized_);
if (f == VFP3 && !FLAG_enable_vfp3) return false;
if (f == VFP2 && !FLAG_enable_vfp2) return false;
+ if (f == SUDIV && !FLAG_enable_sudiv) return false;
+ if (f == UNALIGNED_ACCESSES && !FLAG_enable_unaligned_accesses) {
+ return false;
+ }
return (supported_ & (1u << f)) != 0;
}
@@ -648,6 +652,11 @@ class Assembler : public AssemblerBase {
// Overrides the default provided by FLAG_debug_code.
void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
+ // Avoids using instructions that vary in size in unpredictable ways between
+ // the snapshot and the running VM. This is needed by the full compiler so
+ // that it can recompile code with debug support and fix the PC.
+ void set_predictable_code_size(bool value) { predictable_code_size_ = value; }
+
// GetCode emits any pending (non-emitted) code and fills the descriptor
// desc. GetCode() is idempotent; it returns the same result if no other
// Assembler functions are invoked in between GetCode() calls.
@@ -680,13 +689,25 @@ class Assembler : public AssemblerBase {
void label_at_put(Label* L, int at_offset);
// Return the address in the constant pool of the code target address used by
- // the branch/call instruction at pc.
- INLINE(static Address target_address_address_at(Address pc));
+ // the branch/call instruction at pc, or the object in a mov.
+ INLINE(static Address target_pointer_address_at(Address pc));
+
+ // Read/Modify the pointer in the branch/call/move instruction at pc.
+ INLINE(static Address target_pointer_at(Address pc));
+ INLINE(static void set_target_pointer_at(Address pc, Address target));
// Read/Modify the code target address in the branch/call instruction at pc.
INLINE(static Address target_address_at(Address pc));
INLINE(static void set_target_address_at(Address pc, Address target));
+ // Return the code target address at a call site from the return address
+ // of that call in the instruction stream.
+ INLINE(static Address target_address_from_return_address(Address pc));
+
+ // Given the address of the beginning of a call, return the address
+ // in the instruction stream that the call will return from.
+ INLINE(static Address return_address_from_call_start(Address pc));
+
// This sets the branch destination (which is in the constant pool on ARM).
// This is for calls and branches within generated code.
inline static void deserialization_set_special_target_at(
@@ -705,22 +726,6 @@ class Assembler : public AssemblerBase {
// Size of an instruction.
static const int kInstrSize = sizeof(Instr);
- // Distance between the instruction referring to the address of the call
- // target and the return address.
-#ifdef USE_BLX
- // Call sequence is:
- // ldr ip, [pc, #...] @ call address
- // blx ip
- // @ return address
- static const int kCallTargetAddressOffset = 2 * kInstrSize;
-#else
- // Call sequence is:
- // mov lr, pc
- // ldr pc, [pc, #...] @ call address
- // @ return address
- static const int kCallTargetAddressOffset = kInstrSize;
-#endif
-
// Distance between start of patched return sequence and the emitted address
// to jump to.
#ifdef USE_BLX
@@ -749,6 +754,12 @@ class Assembler : public AssemblerBase {
static const int kPatchDebugBreakSlotAddressOffset = kInstrSize;
#endif
+#ifdef USE_BLX
+ static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize;
+#else
+ static const int kPatchDebugBreakSlotReturnOffset = kInstrSize;
+#endif
+
// Difference between address of current opcode and value read from pc
// register.
static const int kPcLoadDelta = 8;
@@ -864,6 +875,12 @@ class Assembler : public AssemblerBase {
void mla(Register dst, Register src1, Register src2, Register srcA,
SBit s = LeaveCC, Condition cond = al);
+ void mls(Register dst, Register src1, Register src2, Register srcA,
+ Condition cond = al);
+
+ void sdiv(Register dst, Register src1, Register src2,
+ Condition cond = al);
+
void mul(Register dst, Register src1, Register src2,
SBit s = LeaveCC, Condition cond = al);
@@ -1048,6 +1065,7 @@ class Assembler : public AssemblerBase {
void vmov(const DwVfpRegister dst,
double imm,
+ const Register scratch = no_reg,
const Condition cond = al);
void vmov(const SwVfpRegister dst,
const SwVfpRegister src,
@@ -1167,6 +1185,22 @@ class Assembler : public AssemblerBase {
// Jump unconditionally to given label.
void jmp(Label* L) { b(L, al); }
+ bool predictable_code_size() const { return predictable_code_size_; }
+
+ static bool use_immediate_embedded_pointer_loads(
+ const Assembler* assembler) {
+#ifdef USE_BLX
+ return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
+ (assembler == NULL || !assembler->predictable_code_size());
+#else
+ // If not using BLX, all loads from the constant pool cannot be immediate,
+ // because the ldr pc, [pc + #xxxx] used for calls must be a single
+ // instruction and cannot be easily distinguished out of context from
+ // other loads that could use movw/movt.
+ return false;
+#endif
+ }
+
// Check the code size generated from label to here.
int SizeOfCodeGeneratedSince(Label* label) {
return pc_offset() - label->pos();
@@ -1206,22 +1240,41 @@ class Assembler : public AssemblerBase {
// Record the AST id of the CallIC being compiled, so that it can be placed
// in the relocation information.
- void SetRecordedAstId(unsigned ast_id) {
- ASSERT(recorded_ast_id_ == kNoASTId);
+ void SetRecordedAstId(TypeFeedbackId ast_id) {
+ ASSERT(recorded_ast_id_.IsNone());
recorded_ast_id_ = ast_id;
}
- unsigned RecordedAstId() {
- ASSERT(recorded_ast_id_ != kNoASTId);
+ TypeFeedbackId RecordedAstId() {
+ ASSERT(!recorded_ast_id_.IsNone());
return recorded_ast_id_;
}
- void ClearRecordedAstId() { recorded_ast_id_ = kNoASTId; }
+ void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
// Record a comment relocation entry that can be used by a disassembler.
// Use --code-comments to enable.
void RecordComment(const char* msg);
+ // Record the emission of a constant pool.
+ //
+ // The emission of constant pool depends on the size of the code generated and
+ // the number of RelocInfo recorded.
+ // The Debug mechanism needs to map code offsets between two versions of a
+ // function, compiled with and without debugger support (see for example
+ // Debug::PrepareForBreakPoints()).
+ // Compiling functions with debugger support generates additional code
+ // (Debug::GenerateSlot()). This may affect the emission of the constant
+ // pools and cause the version of the code with debugger support to have
+ // constant pools generated in different places.
+ // Recording the position and size of emitted constant pools allows to
+ // correctly compute the offset mappings between the different versions of a
+ // function in all situations.
+ //
+ // The parameter indicates the size of the constant pool (in bytes), including
+ // the marker and branch over the data.
+ void RecordConstPool(int size);
+
// Writes a single byte or word of data in the code stream. Used
// for inline tables, e.g., jump-tables. The constant pool should be
// emitted before any use of db and dd to ensure that constant pools
@@ -1268,6 +1321,8 @@ class Assembler : public AssemblerBase {
static Register GetCmpImmediateRegister(Instr instr);
static int GetCmpImmediateRawImmediate(Instr instr);
static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
+ static bool IsMovT(Instr instr);
+ static bool IsMovW(Instr instr);
// Constants in pools are accessed via pc relative addressing, which can
// reach +/-4KB thereby defining a maximum distance between the instruction
@@ -1286,7 +1341,7 @@ class Assembler : public AssemblerBase {
// Relocation for a type-recording IC has the AST id added to it. This
// member variable is a way to pass the information from the call site to
// the relocation info.
- unsigned recorded_ast_id_;
+ TypeFeedbackId recorded_ast_id_;
bool emit_debug_code() const { return emit_debug_code_; }
@@ -1406,6 +1461,12 @@ class Assembler : public AssemblerBase {
void GrowBuffer();
inline void emit(Instr x);
+ // 32-bit immediate values
+ void move_32_bit_immediate(Condition cond,
+ Register rd,
+ SBit s,
+ const Operand& x);
+
// Instruction generation
void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
void addrmod2(Instr instr, Register rd, const MemOperand& x);
@@ -1419,8 +1480,14 @@ class Assembler : public AssemblerBase {
void link_to(Label* L, Label* appendix);
void next(Label* L);
+ enum UseConstantPoolMode {
+ USE_CONSTANT_POOL,
+ DONT_USE_CONSTANT_POOL
+ };
+
// Record reloc info for current pc_
- void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
+ void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0,
+ UseConstantPoolMode mode = USE_CONSTANT_POOL);
friend class RegExpMacroAssemblerARM;
friend class RelocInfo;
@@ -1428,7 +1495,10 @@ class Assembler : public AssemblerBase {
friend class BlockConstPoolScope;
PositionsRecorder positions_recorder_;
+
bool emit_debug_code_;
+ bool predictable_code_size_;
+
friend class PositionsRecorder;
friend class EnsureSpace;
};
@@ -1442,6 +1512,26 @@ class EnsureSpace BASE_EMBEDDED {
};
+class PredictableCodeSizeScope {
+ public:
+ explicit PredictableCodeSizeScope(Assembler* assembler)
+ : asm_(assembler) {
+ old_value_ = assembler->predictable_code_size();
+ assembler->set_predictable_code_size(true);
+ }
+
+ ~PredictableCodeSizeScope() {
+ if (!old_value_) {
+ asm_->set_predictable_code_size(false);
+ }
+ }
+
+ private:
+ Assembler* asm_;
+ bool old_value_;
+};
+
+
} } // namespace v8::internal
#endif // V8_ARM_ASSEMBLER_ARM_H_
diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc
index 9cacac0b0..2d1d7b119 100644
--- a/deps/v8/src/arm/builtins-arm.cc
+++ b/deps/v8/src/arm/builtins-arm.cc
@@ -75,12 +75,13 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
// Load the built-in InternalArray function from the current context.
static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
Register result) {
- // Load the global context.
+ // Load the native context.
- __ ldr(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ ldr(result,
- FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
- // Load the InternalArray function from the global context.
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ ldr(result,
+ FieldMemOperand(result, GlobalObject::kNativeContextOffset));
+ // Load the InternalArray function from the native context.
__ ldr(result,
MemOperand(result,
Context::SlotOffset(
@@ -90,12 +91,13 @@ static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
// Load the built-in Array function from the current context.
static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
- // Load the global context.
+ // Load the native context.
- __ ldr(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ ldr(result,
- FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
- // Load the Array function from the global context.
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ ldr(result,
+ FieldMemOperand(result, GlobalObject::kNativeContextOffset));
+ // Load the Array function from the native context.
__ ldr(result,
MemOperand(result,
Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
@@ -697,6 +699,43 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
}
+static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
+ __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
+ __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset));
+ __ add(r2, r2, Operand(Code::kHeaderSize - kHeapObjectTag));
+ __ mov(pc, r2);
+}
+
+
+void Builtins::Generate_InRecompileQueue(MacroAssembler* masm) {
+ GenerateTailCallToSharedCode(masm);
+}
+
+
+void Builtins::Generate_ParallelRecompile(MacroAssembler* masm) {
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ // Push a copy of the function onto the stack.
+ __ push(r1);
+ // Push call kind information.
+ __ push(r5);
+
+ __ push(r1); // Function is also the parameter to the runtime call.
+ __ CallRuntime(Runtime::kParallelRecompile, 1);
+
+ // Restore call kind information.
+ __ pop(r5);
+ // Restore receiver.
+ __ pop(r1);
+
+ // Tear down internal frame.
+ }
+
+ GenerateTailCallToSharedCode(masm);
+}
+
+
static void Generate_JSConstructStubHelper(MacroAssembler* masm,
bool is_api_function,
bool count_constructions) {
@@ -1246,7 +1285,10 @@ void Builtins::Generate_NotifyOSR(MacroAssembler* masm) {
void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
CpuFeatures::TryForceFeatureScope scope(VFP3);
- ASSERT(CPU::SupportsCrankshaft());
+ if (!CPU::SupportsCrankshaft()) {
+ __ Abort("Unreachable code: Cannot optimize without VFP3 support.");
+ return;
+ }
// Lookup the function in the JavaScript frame and push it as an
// argument to the on-stack replacement function.
@@ -1363,9 +1405,9 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// receiver.
__ bind(&use_global_receiver);
const int kGlobalIndex =
- Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
__ ldr(r2, FieldMemOperand(cp, kGlobalIndex));
- __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalContextOffset));
+ __ ldr(r2, FieldMemOperand(r2, GlobalObject::kNativeContextOffset));
__ ldr(r2, FieldMemOperand(r2, kGlobalIndex));
__ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
@@ -1558,9 +1600,9 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Use the current global receiver object as the receiver.
__ bind(&use_global_receiver);
const int kGlobalOffset =
- Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
__ ldr(r0, FieldMemOperand(cp, kGlobalOffset));
- __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset));
+ __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset));
__ ldr(r0, FieldMemOperand(r0, kGlobalOffset));
__ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc
index 0d59eff93..ceb108ffa 100644
--- a/deps/v8/src/arm/code-stubs-arm.cc
+++ b/deps/v8/src/arm/code-stubs-arm.cc
@@ -85,6 +85,8 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
void FastNewClosureStub::Generate(MacroAssembler* masm) {
// Create a new closure from the given function info in new
// space. Set the context to the current context in cp.
+ Counters* counters = masm->isolate()->counters();
+
Label gc;
// Pop the function info from the stack.
@@ -98,32 +100,44 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) {
&gc,
TAG_OBJECT);
+ __ IncrementCounter(counters->fast_new_closure_total(), 1, r6, r7);
+
int map_index = (language_mode_ == CLASSIC_MODE)
? Context::FUNCTION_MAP_INDEX
: Context::STRICT_MODE_FUNCTION_MAP_INDEX;
- // Compute the function map in the current global context and set that
+ // Compute the function map in the current native context and set that
// as the map of the allocated object.
- __ ldr(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalContextOffset));
- __ ldr(r2, MemOperand(r2, Context::SlotOffset(map_index)));
- __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
+ __ ldr(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ ldr(r2, FieldMemOperand(r2, GlobalObject::kNativeContextOffset));
+ __ ldr(r5, MemOperand(r2, Context::SlotOffset(map_index)));
+ __ str(r5, FieldMemOperand(r0, HeapObject::kMapOffset));
// Initialize the rest of the function. We don't have to update the
// write barrier because the allocated object is in new space.
__ LoadRoot(r1, Heap::kEmptyFixedArrayRootIndex);
- __ LoadRoot(r2, Heap::kTheHoleValueRootIndex);
- __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
+ __ LoadRoot(r5, Heap::kTheHoleValueRootIndex);
__ str(r1, FieldMemOperand(r0, JSObject::kPropertiesOffset));
__ str(r1, FieldMemOperand(r0, JSObject::kElementsOffset));
- __ str(r2, FieldMemOperand(r0, JSFunction::kPrototypeOrInitialMapOffset));
+ __ str(r5, FieldMemOperand(r0, JSFunction::kPrototypeOrInitialMapOffset));
__ str(r3, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
__ str(cp, FieldMemOperand(r0, JSFunction::kContextOffset));
__ str(r1, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
- __ str(r4, FieldMemOperand(r0, JSFunction::kNextFunctionLinkOffset));
// Initialize the code pointer in the function to be the one
// found in the shared function info object.
+ // But first check if there is an optimized version for our context.
+ Label check_optimized;
+ Label install_unoptimized;
+ if (FLAG_cache_optimized_code) {
+ __ ldr(r1,
+ FieldMemOperand(r3, SharedFunctionInfo::kOptimizedCodeMapOffset));
+ __ tst(r1, r1);
+ __ b(ne, &check_optimized);
+ }
+ __ bind(&install_unoptimized);
+ __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
+ __ str(r4, FieldMemOperand(r0, JSFunction::kNextFunctionLinkOffset));
__ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kCodeOffset));
__ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
__ str(r3, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
@@ -131,6 +145,72 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) {
// Return result. The argument function info has been popped already.
__ Ret();
+ __ bind(&check_optimized);
+
+ __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1, r6, r7);
+
+ // r2 holds native context, r1 points to fixed array of 3-element entries
+ // (native context, optimized code, literals).
+ // The optimized code map must never be empty, so check the first elements.
+ Label install_optimized;
+ // Speculatively move code object into r4.
+ __ ldr(r4, FieldMemOperand(r1, FixedArray::kHeaderSize + kPointerSize));
+ __ ldr(r5, FieldMemOperand(r1, FixedArray::kHeaderSize));
+ __ cmp(r2, r5);
+ __ b(eq, &install_optimized);
+
+ // Iterate through the rest of map backwards. r4 holds an index as a Smi.
+ Label loop;
+ __ ldr(r4, FieldMemOperand(r1, FixedArray::kLengthOffset));
+ __ bind(&loop);
+ // Do not double check first entry.
+
+ __ cmp(r4, Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
+ __ b(eq, &install_unoptimized);
+ __ sub(r4, r4, Operand(
+ Smi::FromInt(SharedFunctionInfo::kEntryLength))); // Skip an entry.
+ __ add(r5, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ add(r5, r5, Operand(r4, LSL, kPointerSizeLog2 - kSmiTagSize));
+ __ ldr(r5, MemOperand(r5));
+ __ cmp(r2, r5);
+ __ b(ne, &loop);
+ // Hit: fetch the optimized code.
+ __ add(r5, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ add(r5, r5, Operand(r4, LSL, kPointerSizeLog2 - kSmiTagSize));
+ __ add(r5, r5, Operand(kPointerSize));
+ __ ldr(r4, MemOperand(r5));
+
+ __ bind(&install_optimized);
+ __ IncrementCounter(counters->fast_new_closure_install_optimized(),
+ 1, r6, r7);
+
+ // TODO(fschneider): Idea: store proper code pointers in the map and either
+ // unmangle them on marking or do nothing as the whole map is discarded on
+ // major GC anyway.
+ __ add(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
+ __ str(r4, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
+
+ // Now link a function into a list of optimized functions.
+ __ ldr(r4, ContextOperand(r2, Context::OPTIMIZED_FUNCTIONS_LIST));
+
+ __ str(r4, FieldMemOperand(r0, JSFunction::kNextFunctionLinkOffset));
+ // No need for write barrier as JSFunction (eax) is in the new space.
+
+ __ str(r0, ContextOperand(r2, Context::OPTIMIZED_FUNCTIONS_LIST));
+ // Store JSFunction (eax) into edx before issuing write barrier as
+ // it clobbers all the registers passed.
+ __ mov(r4, r0);
+ __ RecordWriteContextSlot(
+ r2,
+ Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
+ r4,
+ r1,
+ kLRHasNotBeenSaved,
+ kDontSaveFPRegs);
+
+ // Return result. The argument function info has been popped already.
+ __ Ret();
+
// Create a new closure through the slower runtime call.
__ bind(&gc);
__ LoadRoot(r4, Heap::kFalseValueRootIndex);
@@ -162,12 +242,12 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
__ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
// Set up the fixed slots, copy the global object from the previous context.
- __ ldr(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ ldr(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ mov(r1, Operand(Smi::FromInt(0)));
__ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX)));
__ str(cp, MemOperand(r0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
__ str(r1, MemOperand(r0, Context::SlotOffset(Context::EXTENSION_INDEX)));
- __ str(r2, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ str(r2, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
// Initialize the rest of the slots to undefined.
__ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
@@ -210,9 +290,9 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ mov(r2, Operand(Smi::FromInt(length)));
__ str(r2, FieldMemOperand(r0, FixedArray::kLengthOffset));
- // If this block context is nested in the global context we get a smi
+ // If this block context is nested in the native context we get a smi
// sentinel instead of a function. The block context should get the
- // canonical empty function of the global context as its closure which
+ // canonical empty function of the native context as its closure which
// we still have to look up.
Label after_sentinel;
__ JumpIfNotSmi(r3, &after_sentinel);
@@ -222,16 +302,16 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ Assert(eq, message);
}
__ ldr(r3, GlobalObjectOperand());
- __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalContextOffset));
+ __ ldr(r3, FieldMemOperand(r3, GlobalObject::kNativeContextOffset));
__ ldr(r3, ContextOperand(r3, Context::CLOSURE_INDEX));
__ bind(&after_sentinel);
// Set up the fixed slots, copy the global object from the previous context.
- __ ldr(r2, ContextOperand(cp, Context::GLOBAL_INDEX));
+ __ ldr(r2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
__ str(r3, ContextOperand(r0, Context::CLOSURE_INDEX));
__ str(cp, ContextOperand(r0, Context::PREVIOUS_INDEX));
__ str(r1, ContextOperand(r0, Context::EXTENSION_INDEX));
- __ str(r2, ContextOperand(r0, Context::GLOBAL_INDEX));
+ __ str(r2, ContextOperand(r0, Context::GLOBAL_OBJECT_INDEX));
// Initialize the rest of the slots to the hole value.
__ LoadRoot(r1, Heap::kTheHoleValueRootIndex);
@@ -575,11 +655,9 @@ void FloatingPointHelper::LoadNumber(MacroAssembler* masm,
Register scratch1,
Register scratch2,
Label* not_number) {
- if (FLAG_debug_code) {
- __ AbortIfNotRootValue(heap_number_map,
- Heap::kHeapNumberMapRootIndex,
- "HeapNumberMap register clobbered.");
- }
+ __ AssertRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
Label is_smi, done;
@@ -636,11 +714,9 @@ void FloatingPointHelper::ConvertNumberToInt32(MacroAssembler* masm,
Register scratch3,
DwVfpRegister double_scratch,
Label* not_number) {
- if (FLAG_debug_code) {
- __ AbortIfNotRootValue(heap_number_map,
- Heap::kHeapNumberMapRootIndex,
- "HeapNumberMap register clobbered.");
- }
+ __ AssertRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
Label done;
Label not_in_int32_range;
@@ -746,6 +822,7 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
Register object,
Destination destination,
DwVfpRegister double_dst,
+ DwVfpRegister double_scratch,
Register dst1,
Register dst2,
Register heap_number_map,
@@ -768,11 +845,9 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
__ b(&done);
__ bind(&obj_is_not_smi);
- if (FLAG_debug_code) {
- __ AbortIfNotRootValue(heap_number_map,
- Heap::kHeapNumberMapRootIndex,
- "HeapNumberMap register clobbered.");
- }
+ __ AssertRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
__ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
// Load the number.
@@ -783,10 +858,10 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
__ vldr(double_dst, scratch1, HeapNumber::kValueOffset);
__ EmitVFPTruncate(kRoundToZero,
- single_scratch,
- double_dst,
scratch1,
+ double_dst,
scratch2,
+ double_scratch,
kCheckForInexactConversion);
// Jump to not_int32 if the operation did not succeed.
@@ -826,7 +901,8 @@ void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
Register scratch1,
Register scratch2,
Register scratch3,
- DwVfpRegister double_scratch,
+ DwVfpRegister double_scratch0,
+ DwVfpRegister double_scratch1,
Label* not_int32) {
ASSERT(!dst.is(object));
ASSERT(!scratch1.is(object) && !scratch2.is(object) && !scratch3.is(object));
@@ -838,34 +914,29 @@ void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
__ UntagAndJumpIfSmi(dst, object, &done);
- if (FLAG_debug_code) {
- __ AbortIfNotRootValue(heap_number_map,
- Heap::kHeapNumberMapRootIndex,
- "HeapNumberMap register clobbered.");
- }
+ __ AssertRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
__ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
// Object is a heap number.
// Convert the floating point value to a 32-bit integer.
if (CpuFeatures::IsSupported(VFP2)) {
CpuFeatures::Scope scope(VFP2);
- SwVfpRegister single_scratch = double_scratch.low();
+
// Load the double value.
__ sub(scratch1, object, Operand(kHeapObjectTag));
- __ vldr(double_scratch, scratch1, HeapNumber::kValueOffset);
+ __ vldr(double_scratch0, scratch1, HeapNumber::kValueOffset);
__ EmitVFPTruncate(kRoundToZero,
- single_scratch,
- double_scratch,
+ dst,
+ double_scratch0,
scratch1,
- scratch2,
+ double_scratch1,
kCheckForInexactConversion);
// Jump to not_int32 if the operation did not succeed.
__ b(ne, not_int32);
- // Get the result in the destination register.
- __ vmov(dst, single_scratch);
-
} else {
// Load the double value in the destination registers.
__ ldr(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
@@ -1779,11 +1850,9 @@ void CompareStub::Generate(MacroAssembler* masm) {
void ToBooleanStub::Generate(MacroAssembler* masm) {
// This stub overrides SometimesSetsUpAFrame() to return false. That means
// we cannot call anything that could cause a GC from this stub.
- // This stub uses VFP3 instructions.
- CpuFeatures::Scope scope(VFP2);
-
Label patch;
const Register map = r9.is(tos_) ? r7 : r9;
+ const Register temp = map;
// undefined -> false.
CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false);
@@ -1836,13 +1905,56 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
Label not_heap_number;
__ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
__ b(ne, &not_heap_number);
- __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset));
- __ VFPCompareAndSetFlags(d1, 0.0);
- // "tos_" is a register, and contains a non zero value by default.
- // Hence we only need to overwrite "tos_" with zero to return false for
- // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true.
- __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); // for FP_ZERO
- __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN
+
+ if (CpuFeatures::IsSupported(VFP2)) {
+ CpuFeatures::Scope scope(VFP2);
+
+ __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset));
+ __ VFPCompareAndSetFlags(d1, 0.0);
+ // "tos_" is a register, and contains a non zero value by default.
+ // Hence we only need to overwrite "tos_" with zero to return false for
+ // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true.
+ __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); // for FP_ZERO
+ __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN
+ } else {
+ Label done, not_nan, not_zero;
+ __ ldr(temp, FieldMemOperand(tos_, HeapNumber::kExponentOffset));
+ // -0 maps to false:
+ __ bic(
+ temp, temp, Operand(HeapNumber::kSignMask, RelocInfo::NONE), SetCC);
+ __ b(ne, &not_zero);
+ // If exponent word is zero then the answer depends on the mantissa word.
+ __ ldr(tos_, FieldMemOperand(tos_, HeapNumber::kMantissaOffset));
+ __ jmp(&done);
+
+ // Check for NaN.
+ __ bind(&not_zero);
+ // We already zeroed the sign bit, now shift out the mantissa so we only
+ // have the exponent left.
+ __ mov(temp, Operand(temp, LSR, HeapNumber::kMantissaBitsInTopWord));
+ unsigned int shifted_exponent_mask =
+ HeapNumber::kExponentMask >> HeapNumber::kMantissaBitsInTopWord;
+ __ cmp(temp, Operand(shifted_exponent_mask, RelocInfo::NONE));
+ __ b(ne, &not_nan); // If exponent is not 0x7ff then it can't be a NaN.
+
+ // Reload exponent word.
+ __ ldr(temp, FieldMemOperand(tos_, HeapNumber::kExponentOffset));
+ __ tst(temp, Operand(HeapNumber::kMantissaMask, RelocInfo::NONE));
+ // If mantissa is not zero then we have a NaN, so return 0.
+ __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, ne);
+ __ b(ne, &done);
+
+ // Load mantissa word.
+ __ ldr(temp, FieldMemOperand(tos_, HeapNumber::kMantissaOffset));
+ __ cmp(temp, Operand(0, RelocInfo::NONE));
+ // If mantissa is not zero then we have a NaN, so return 0.
+ __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, ne);
+ __ b(ne, &done);
+
+ __ bind(&not_nan);
+ __ mov(tos_, Operand(1, RelocInfo::NONE));
+ __ bind(&done);
+ }
__ Ret();
__ bind(&not_heap_number);
}
@@ -2425,9 +2537,9 @@ void BinaryOpStub::GenerateFPOperation(MacroAssembler* masm,
Register scratch3 = r4;
ASSERT(smi_operands || (not_numbers != NULL));
- if (smi_operands && FLAG_debug_code) {
- __ AbortIfNotSmi(left);
- __ AbortIfNotSmi(right);
+ if (smi_operands) {
+ __ AssertSmi(left);
+ __ AssertSmi(right);
}
Register heap_number_map = r6;
@@ -2729,7 +2841,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
Register scratch1 = r7;
Register scratch2 = r9;
DwVfpRegister double_scratch = d0;
- SwVfpRegister single_scratch = s3;
Register heap_number_result = no_reg;
Register heap_number_map = r6;
@@ -2767,6 +2878,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
right,
destination,
d7,
+ d8,
r2,
r3,
heap_number_map,
@@ -2778,6 +2890,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
left,
destination,
d6,
+ d8,
r4,
r5,
heap_number_map,
@@ -2813,10 +2926,10 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
// transition.
__ EmitVFPTruncate(kRoundToZero,
- single_scratch,
- d5,
scratch1,
- scratch2);
+ d5,
+ scratch2,
+ d8);
if (result_type_ <= BinaryOpIC::INT32) {
// If the ne condition is set, result does
@@ -2825,7 +2938,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
}
// Check if the result fits in a smi.
- __ vmov(scratch1, single_scratch);
__ add(scratch2, scratch1, Operand(0x40000000), SetCC);
// If not try to return a heap number.
__ b(mi, &return_heap_number);
@@ -2920,6 +3032,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
scratch2,
scratch3,
d0,
+ d1,
&transition);
FloatingPointHelper::LoadNumberAsInt32(masm,
right,
@@ -2929,6 +3042,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
scratch2,
scratch3,
d0,
+ d1,
&transition);
// The ECMA-262 standard specifies that, for shift operations, only the
@@ -3323,8 +3437,8 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
ExternalReference(RuntimeFunction(), masm->isolate());
__ TailCallExternalReference(runtime_function, 1, 1);
} else {
- ASSERT(CpuFeatures::IsSupported(VFP3));
- CpuFeatures::Scope scope(VFP3);
+ ASSERT(CpuFeatures::IsSupported(VFP2));
+ CpuFeatures::Scope scope(VFP2);
Label no_update;
Label skip_cache;
@@ -3515,13 +3629,13 @@ void MathPowStub::Generate(MacroAssembler* masm) {
Label not_plus_half;
// Test for 0.5.
- __ vmov(double_scratch, 0.5);
+ __ vmov(double_scratch, 0.5, scratch);
__ VFPCompareAndSetFlags(double_exponent, double_scratch);
__ b(ne, &not_plus_half);
// Calculates square root of base. Check for the special case of
// Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
- __ vmov(double_scratch, -V8_INFINITY);
+ __ vmov(double_scratch, -V8_INFINITY, scratch);
__ VFPCompareAndSetFlags(double_base, double_scratch);
__ vneg(double_result, double_scratch, eq);
__ b(eq, &done);
@@ -3532,20 +3646,20 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ jmp(&done);
__ bind(&not_plus_half);
- __ vmov(double_scratch, -0.5);
+ __ vmov(double_scratch, -0.5, scratch);
__ VFPCompareAndSetFlags(double_exponent, double_scratch);
__ b(ne, &call_runtime);
// Calculates square root of base. Check for the special case of
// Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
- __ vmov(double_scratch, -V8_INFINITY);
+ __ vmov(double_scratch, -V8_INFINITY, scratch);
__ VFPCompareAndSetFlags(double_base, double_scratch);
__ vmov(double_result, kDoubleRegZero, eq);
__ b(eq, &done);
// Add +0 to convert -0 to +0.
__ vadd(double_scratch, double_base, kDoubleRegZero);
- __ vmov(double_result, 1.0);
+ __ vmov(double_result, 1.0, scratch);
__ vsqrt(double_scratch, double_scratch);
__ vdiv(double_result, double_result, double_scratch);
__ jmp(&done);
@@ -3580,7 +3694,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ mov(exponent, scratch);
}
__ vmov(double_scratch, double_base); // Back up base.
- __ vmov(double_result, 1.0);
+ __ vmov(double_result, 1.0, scratch2);
// Get absolute value of exponent.
__ cmp(scratch, Operand(0));
@@ -3596,7 +3710,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ cmp(exponent, Operand(0));
__ b(ge, &done);
- __ vmov(double_scratch, 1.0);
+ __ vmov(double_scratch, 1.0, scratch);
__ vdiv(double_result, double_scratch, double_result);
// Test whether result is zero. Bail out to check for subnormal result.
// Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
@@ -4386,14 +4500,14 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
// r0 = address of new object(s) (tagged)
// r2 = argument count (tagged)
- // Get the arguments boilerplate from the current (global) context into r4.
+ // Get the arguments boilerplate from the current native context into r4.
const int kNormalOffset =
Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
const int kAliasedOffset =
Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX);
- __ ldr(r4, MemOperand(r8, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
+ __ ldr(r4, MemOperand(r8, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ ldr(r4, FieldMemOperand(r4, GlobalObject::kNativeContextOffset));
__ cmp(r1, Operand::Zero());
__ ldr(r4, MemOperand(r4, kNormalOffset), eq);
__ ldr(r4, MemOperand(r4, kAliasedOffset), ne);
@@ -4566,9 +4680,9 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
static_cast<AllocationFlags>(TAG_OBJECT |
SIZE_IN_WORDS));
- // Get the arguments boilerplate from the current (global) context.
- __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
+ // Get the arguments boilerplate from the current native context.
+ __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ ldr(r4, FieldMemOperand(r4, GlobalObject::kNativeContextOffset));
__ ldr(r4, MemOperand(r4, Context::SlotOffset(
Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
@@ -4697,7 +4811,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
__ add(r2, r2, Operand(2)); // r2 was a smi.
// Check that the static offsets vector buffer is large enough.
- __ cmp(r2, Operand(OffsetsVector::kStaticOffsetsVectorSize));
+ __ cmp(r2, Operand(Isolate::kJSRegexpStaticOffsetsVectorSize));
__ b(hi, &runtime);
// r2: Number of capture registers
@@ -5083,10 +5197,10 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
// Set empty properties FixedArray.
// Set elements to point to FixedArray allocated right after the JSArray.
// Interleave operations for better latency.
- __ ldr(r2, ContextOperand(cp, Context::GLOBAL_INDEX));
+ __ ldr(r2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
__ add(r3, r0, Operand(JSRegExpResult::kSize));
__ mov(r4, Operand(factory->empty_fixed_array()));
- __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalContextOffset));
+ __ ldr(r2, FieldMemOperand(r2, GlobalObject::kNativeContextOffset));
__ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset));
__ ldr(r2, ContextOperand(r2, Context::REGEXP_RESULT_MAP_INDEX));
__ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset));
@@ -5111,12 +5225,12 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
// Set FixedArray length.
__ mov(r6, Operand(r5, LSL, kSmiTagSize));
__ str(r6, FieldMemOperand(r3, FixedArray::kLengthOffset));
- // Fill contents of fixed-array with the-hole.
- __ mov(r2, Operand(factory->the_hole_value()));
+ // Fill contents of fixed-array with undefined.
+ __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
__ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- // Fill fixed array elements with hole.
+ // Fill fixed array elements with undefined.
// r0: JSArray, tagged.
- // r2: the hole.
+ // r2: undefined.
// r3: Start of elements in FixedArray.
// r5: Number of elements to fill.
Label loop;
@@ -5192,7 +5306,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
__ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
__ b(ne, &call);
// Patch the receiver on the stack with the global receiver object.
- __ ldr(r3, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ ldr(r3,
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalReceiverOffset));
__ str(r3, MemOperand(sp, argc_ * kPointerSize));
__ bind(&call);
@@ -6942,8 +7057,7 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
ASSERT(!name.is(scratch1));
ASSERT(!name.is(scratch2));
- // Assert that name contains a string.
- if (FLAG_debug_code) __ AbortIfNotString(name);
+ __ AssertString(name);
// Compute the capacity mask.
__ ldr(scratch1, FieldMemOperand(elements, kCapacityOffset));
@@ -7132,12 +7246,15 @@ static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
{ REG(r2), REG(r6), REG(r9), EMIT_REMEMBERED_SET },
// StoreArrayLiteralElementStub::Generate
{ REG(r5), REG(r0), REG(r6), EMIT_REMEMBERED_SET },
+ // FastNewClosureStub::Generate
+ { REG(r2), REG(r4), REG(r1), EMIT_REMEMBERED_SET },
// Null termination.
{ REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET}
};
#undef REG
+
bool RecordWriteStub::IsPregenerated() {
for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime;
!entry->object.is(no_reg);
@@ -7179,6 +7296,11 @@ void RecordWriteStub::GenerateFixedRegStubsAheadOfTime() {
}
+bool CodeStub::CanUseFPRegisters() {
+ return CpuFeatures::IsSupported(VFP2);
+}
+
+
// Takes the input in 3 registers: address_ value_ and object_. A pointer to
// the value has just been written into the object, now this stub makes sure
// we keep the GC informed. The word in the object where the value has been
@@ -7307,6 +7429,16 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
Label need_incremental;
Label need_incremental_pop_scratch;
+ __ and_(regs_.scratch0(), regs_.object(), Operand(~Page::kPageAlignmentMask));
+ __ ldr(regs_.scratch1(),
+ MemOperand(regs_.scratch0(),
+ MemoryChunk::kWriteBarrierCounterOffset));
+ __ sub(regs_.scratch1(), regs_.scratch1(), Operand(1), SetCC);
+ __ str(regs_.scratch1(),
+ MemOperand(regs_.scratch0(),
+ MemoryChunk::kWriteBarrierCounterOffset));
+ __ b(mi, &need_incremental);
+
// Let's look at the color of the object: If it is not black we don't have
// to inform the incremental marker.
__ JumpIfBlack(regs_.object(), regs_.scratch0(), regs_.scratch1(), &on_black);
@@ -7427,11 +7559,73 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
// Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS.
__ bind(&double_elements);
__ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset));
- __ StoreNumberToDoubleElements(r0, r3, r1, r5, r6, r7, r9, r2,
+ __ StoreNumberToDoubleElements(r0, r3, r1,
+ // Overwrites all regs after this.
+ r5, r6, r7, r9, r2,
&slow_elements);
__ Ret();
}
+
+void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
+ if (entry_hook_ != NULL) {
+ PredictableCodeSizeScope predictable(masm);
+ ProfileEntryHookStub stub;
+ __ push(lr);
+ __ CallStub(&stub);
+ __ pop(lr);
+ }
+}
+
+
+void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
+ // The entry hook is a "push lr" instruction, followed by a call.
+ const int32_t kReturnAddressDistanceFromFunctionStart =
+ 3 * Assembler::kInstrSize;
+
+ // Save live volatile registers.
+ __ Push(lr, r5, r1);
+ const int32_t kNumSavedRegs = 3;
+
+ // Compute the function's address for the first argument.
+ __ sub(r0, lr, Operand(kReturnAddressDistanceFromFunctionStart));
+
+ // The caller's return address is above the saved temporaries.
+ // Grab that for the second argument to the hook.
+ __ add(r1, sp, Operand(kNumSavedRegs * kPointerSize));
+
+ // Align the stack if necessary.
+ int frame_alignment = masm->ActivationFrameAlignment();
+ if (frame_alignment > kPointerSize) {
+ __ mov(r5, sp);
+ ASSERT(IsPowerOf2(frame_alignment));
+ __ and_(sp, sp, Operand(-frame_alignment));
+ }
+
+#if defined(V8_HOST_ARCH_ARM)
+ __ mov(ip, Operand(reinterpret_cast<int32_t>(&entry_hook_)));
+ __ ldr(ip, MemOperand(ip));
+#else
+ // Under the simulator we need to indirect the entry hook through a
+ // trampoline function at a known address.
+ Address trampoline_address = reinterpret_cast<Address>(
+ reinterpret_cast<intptr_t>(EntryHookTrampoline));
+ ApiFunction dispatcher(trampoline_address);
+ __ mov(ip, Operand(ExternalReference(&dispatcher,
+ ExternalReference::BUILTIN_CALL,
+ masm->isolate())));
+#endif
+ __ Call(ip);
+
+ // Restore the stack pointer if needed.
+ if (frame_alignment > kPointerSize) {
+ __ mov(sp, r5);
+ }
+
+ __ Pop(lr, r5, r1);
+ __ Ret();
+}
+
#undef __
} } // namespace v8::internal
diff --git a/deps/v8/src/arm/code-stubs-arm.h b/deps/v8/src/arm/code-stubs-arm.h
index 3ddc40571..3e796249c 100644
--- a/deps/v8/src/arm/code-stubs-arm.h
+++ b/deps/v8/src/arm/code-stubs-arm.h
@@ -773,6 +773,7 @@ class FloatingPointHelper : public AllStatic {
Register object,
Destination destination,
DwVfpRegister double_dst,
+ DwVfpRegister double_scratch,
Register dst1,
Register dst2,
Register heap_number_map,
@@ -794,7 +795,8 @@ class FloatingPointHelper : public AllStatic {
Register scratch1,
Register scratch2,
Register scratch3,
- DwVfpRegister double_scratch,
+ DwVfpRegister double_scratch0,
+ DwVfpRegister double_scratch1,
Label* not_int32);
// Generate non VFP3 code to check if a double can be exactly represented by a
diff --git a/deps/v8/src/arm/codegen-arm.cc b/deps/v8/src/arm/codegen-arm.cc
index 3bdee1f94..09166c3c0 100644
--- a/deps/v8/src/arm/codegen-arm.cc
+++ b/deps/v8/src/arm/codegen-arm.cc
@@ -121,15 +121,34 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
// r5: number of elements (smi-tagged)
// Allocate new FixedDoubleArray.
- __ mov(lr, Operand(FixedDoubleArray::kHeaderSize));
- __ add(lr, lr, Operand(r5, LSL, 2));
+ // Use lr as a temporary register.
+ __ mov(lr, Operand(r5, LSL, 2));
+ __ add(lr, lr, Operand(FixedDoubleArray::kHeaderSize + kPointerSize));
__ AllocateInNewSpace(lr, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS);
- // r6: destination FixedDoubleArray, not tagged as heap object
+ // r6: destination FixedDoubleArray, not tagged as heap object.
+
+ // Align the array conveniently for doubles.
+ // Store a filler value in the unused memory.
+ Label aligned, aligned_done;
+ __ tst(r6, Operand(kDoubleAlignmentMask));
+ __ mov(ip, Operand(masm->isolate()->factory()->one_pointer_filler_map()));
+ __ b(eq, &aligned);
+ // Store at the beginning of the allocated memory and update the base pointer.
+ __ str(ip, MemOperand(r6, kPointerSize, PostIndex));
+ __ b(&aligned_done);
+
+ __ bind(&aligned);
+ // Store the filler at the end of the allocated memory.
+ __ sub(lr, lr, Operand(kPointerSize));
+ __ str(ip, MemOperand(r6, lr));
+
+ __ bind(&aligned_done);
+
// Set destination FixedDoubleArray's length and map.
__ LoadRoot(r9, Heap::kFixedDoubleArrayMapRootIndex);
__ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset));
- __ str(r9, MemOperand(r6, HeapObject::kMapOffset));
// Update receiver's map.
+ __ str(r9, MemOperand(r6, HeapObject::kMapOffset));
__ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
__ RecordWriteField(r2,
diff --git a/deps/v8/src/arm/constants-arm.h b/deps/v8/src/arm/constants-arm.h
index e767001e1..4fa49e3d3 100644
--- a/deps/v8/src/arm/constants-arm.h
+++ b/deps/v8/src/arm/constants-arm.h
@@ -56,8 +56,9 @@
# define CAN_USE_ARMV6_INSTRUCTIONS 1
#endif
-#if defined(__ARM_ARCH_5T__) || \
- defined(__ARM_ARCH_5TE__) || \
+#if defined(__ARM_ARCH_5T__) || \
+ defined(__ARM_ARCH_5TE__) || \
+ defined(__ARM_ARCH_5TEJ__) || \
defined(CAN_USE_ARMV6_INSTRUCTIONS)
# define CAN_USE_ARMV5_INSTRUCTIONS 1
# define CAN_USE_THUMB_INSTRUCTIONS 1
@@ -74,10 +75,6 @@
#endif
-#if CAN_USE_UNALIGNED_ACCESSES
-#define V8_TARGET_CAN_READ_UNALIGNED 1
-#endif
-
// Using blx may yield better code, so use it when required or when available
#if defined(USE_THUMB_INTERWORK) || defined(CAN_USE_ARMV5_INSTRUCTIONS)
#define USE_BLX 1
@@ -690,6 +687,9 @@ class Instruction {
&& (Bit(20) == 0)
&& ((Bit(7) == 0)); }
+ // Test for a nop instruction, which falls under type 1.
+ inline bool IsNopType1() const { return Bits(24, 0) == 0x0120F000; }
+
// Test for a stop instruction.
inline bool IsStop() const {
return (TypeValue() == 7) && (Bit(24) == 1) && (SvcValue() >= kStopCode);
diff --git a/deps/v8/src/arm/debug-arm.cc b/deps/v8/src/arm/debug-arm.cc
index 3e7a1e9d0..c2941be06 100644
--- a/deps/v8/src/arm/debug-arm.cc
+++ b/deps/v8/src/arm/debug-arm.cc
@@ -48,7 +48,7 @@ void BreakLocationIterator::SetDebugBreakAtReturn() {
// add sp, sp, #4
// bx lr
// to a call to the debug break return code.
- // #if USE_BLX
+ // #ifdef USE_BLX
// ldr ip, [pc, #0]
// blx ip
// #else
@@ -99,7 +99,7 @@ void BreakLocationIterator::SetDebugBreakAtSlot() {
// mov r2, r2
// mov r2, r2
// to a call to the debug break slot code.
- // #if USE_BLX
+ // #ifdef USE_BLX
// ldr ip, [pc, #0]
// blx ip
// #else
diff --git a/deps/v8/src/arm/deoptimizer-arm.cc b/deps/v8/src/arm/deoptimizer-arm.cc
index 699e6aa4b..19667b9d5 100644
--- a/deps/v8/src/arm/deoptimizer-arm.cc
+++ b/deps/v8/src/arm/deoptimizer-arm.cc
@@ -50,6 +50,10 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
if (!function->IsOptimized()) return;
+ // The optimized code is going to be patched, so we cannot use it
+ // any more. Play safe and reset the whole cache.
+ function->shared()->ClearOptimizedCodeMap();
+
// Get the optimized code.
Code* code = function->code();
Address code_start_address = code->instruction_start();
@@ -69,8 +73,11 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
if (deopt_data->Pc(i)->value() == -1) continue;
Address call_address = code_start_address + deopt_data->Pc(i)->value();
Address deopt_entry = GetDeoptimizationEntry(i, LAZY);
- int call_size_in_bytes = MacroAssembler::CallSize(deopt_entry,
- RelocInfo::NONE);
+ // We need calls to have a predictable size in the unoptimized code, but
+ // this is optimized code, so we don't have to have a predictable size.
+ int call_size_in_bytes =
+ MacroAssembler::CallSizeNotPredictableCodeSize(deopt_entry,
+ RelocInfo::NONE);
int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize;
ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0);
ASSERT(call_size_in_bytes <= patch_size());
@@ -97,8 +104,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
// ignore all slots that might have been recorded on it.
isolate->heap()->mark_compact_collector()->InvalidateCode(code);
- // Set the code for the function to non-optimized version.
- function->ReplaceCode(function->shared()->code());
+ ReplaceCodeForRelatedFunctions(function, code);
if (FLAG_trace_deopt) {
PrintF("[forced deoptimization: ");
@@ -196,11 +202,11 @@ void Deoptimizer::RevertStackCheckCodeAt(Code* unoptimized_code,
}
-static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) {
+static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) {
ByteArray* translations = data->TranslationByteArray();
int length = data->DeoptCount();
for (int i = 0; i < length; i++) {
- if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) {
+ if (data->AstId(i) == ast_id) {
TranslationIterator it(translations, data->TranslationIndex(i)->value());
int value = it.Next();
ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value));
@@ -219,7 +225,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
optimized_code_->deoptimization_data());
unsigned ast_id = data->OsrAstId()->value();
- int bailout_id = LookupBailoutId(data, ast_id);
+ int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
unsigned translation_index = data->TranslationIndex(bailout_id)->value();
ByteArray* translations = data->TranslationByteArray();
@@ -239,9 +245,9 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
unsigned node_id = iterator.Next();
USE(node_id);
ASSERT(node_id == ast_id);
- JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next()));
- USE(function);
- ASSERT(function == function_);
+ int closure_id = iterator.Next();
+ USE(closure_id);
+ ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
unsigned height = iterator.Next();
unsigned height_in_bytes = height * kPointerSize;
USE(height_in_bytes);
@@ -352,8 +358,8 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
if (FLAG_trace_osr) {
PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
ok ? "finished" : "aborted",
- reinterpret_cast<intptr_t>(function));
- function->PrintName();
+ reinterpret_cast<intptr_t>(function_));
+ function_->PrintName();
PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
}
}
@@ -577,19 +583,145 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
}
+void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
+ int frame_index,
+ bool is_setter_stub_frame) {
+ JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ // The receiver (and the implicit return value, if any) are expected in
+ // registers by the LoadIC/StoreIC, so they don't belong to the output stack
+ // frame. This means that we have to use a height of 0.
+ unsigned height = 0;
+ unsigned height_in_bytes = height * kPointerSize;
+ const char* kind = is_setter_stub_frame ? "setter" : "getter";
+ if (FLAG_trace_deopt) {
+ PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes);
+ }
+
+ // We need 5 stack entries from StackFrame::INTERNAL (lr, fp, cp, frame type,
+ // code object, see MacroAssembler::EnterFrame). For a setter stub frames we
+ // need one additional entry for the implicit return value, see
+ // StoreStubCompiler::CompileStoreViaSetter.
+ unsigned fixed_frame_entries = 5 + (is_setter_stub_frame ? 1 : 0);
+ unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
+ unsigned output_frame_size = height_in_bytes + fixed_frame_size;
+
+ // Allocate and store the output frame description.
+ FrameDescription* output_frame =
+ new(output_frame_size) FrameDescription(output_frame_size, accessor);
+ output_frame->SetFrameType(StackFrame::INTERNAL);
+
+ // A frame for an accessor stub can not be the topmost or bottommost one.
+ ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
+ ASSERT(output_[frame_index] == NULL);
+ output_[frame_index] = output_frame;
+
+ // The top address of the frame is computed from the previous frame's top and
+ // this frame's size.
+ uint32_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
+ output_frame->SetTop(top_address);
+
+ unsigned output_offset = output_frame_size;
+
+ // Read caller's PC from the previous frame.
+ output_offset -= kPointerSize;
+ intptr_t callers_pc = output_[frame_index - 1]->GetPc();
+ output_frame->SetFrameSlot(output_offset, callers_pc);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; caller's pc\n",
+ top_address + output_offset, output_offset, callers_pc);
+ }
+
+ // Read caller's FP from the previous frame, and set this frame's FP.
+ output_offset -= kPointerSize;
+ intptr_t value = output_[frame_index - 1]->GetFp();
+ output_frame->SetFrameSlot(output_offset, value);
+ intptr_t fp_value = top_address + output_offset;
+ output_frame->SetFp(fp_value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; caller's fp\n",
+ fp_value, output_offset, value);
+ }
+
+ // The context can be gotten from the previous frame.
+ output_offset -= kPointerSize;
+ value = output_[frame_index - 1]->GetContext();
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; context\n",
+ top_address + output_offset, output_offset, value);
+ }
+
+ // A marker value is used in place of the function.
+ output_offset -= kPointerSize;
+ value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; function (%s sentinel)\n",
+ top_address + output_offset, output_offset, value, kind);
+ }
+
+ // Get Code object from accessor stub.
+ output_offset -= kPointerSize;
+ Builtins::Name name = is_setter_stub_frame ?
+ Builtins::kStoreIC_Setter_ForDeopt :
+ Builtins::kLoadIC_Getter_ForDeopt;
+ Code* accessor_stub = isolate_->builtins()->builtin(name);
+ value = reinterpret_cast<intptr_t>(accessor_stub);
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; code object\n",
+ top_address + output_offset, output_offset, value);
+ }
+
+ // Skip receiver.
+ Translation::Opcode opcode =
+ static_cast<Translation::Opcode>(iterator->Next());
+ iterator->Skip(Translation::NumberOfOperandsFor(opcode));
+
+ if (is_setter_stub_frame) {
+ // The implicit return value was part of the artificial setter stub
+ // environment.
+ output_offset -= kPointerSize;
+ DoTranslateCommand(iterator, frame_index, output_offset);
+ }
+
+ ASSERT(0 == output_offset);
+
+ Smi* offset = is_setter_stub_frame ?
+ isolate_->heap()->setter_stub_deopt_pc_offset() :
+ isolate_->heap()->getter_stub_deopt_pc_offset();
+ intptr_t pc = reinterpret_cast<intptr_t>(
+ accessor_stub->instruction_start() + offset->value());
+ output_frame->SetPc(pc);
+}
+
+
// This code is very similar to ia32 code, but relies on register names (fp, sp)
// and how the frame is laid out.
void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
int frame_index) {
// Read the ast node id, function, and frame height for this output frame.
- int node_id = iterator->Next();
- JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ BailoutId node_id = BailoutId(iterator->Next());
+ JSFunction* function;
+ if (frame_index != 0) {
+ function = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ } else {
+ int closure_id = iterator->Next();
+ USE(closure_id);
+ ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
+ function = function_;
+ }
unsigned height = iterator->Next();
unsigned height_in_bytes = height * kPointerSize;
if (FLAG_trace_deopt) {
PrintF(" translating ");
function->PrintName();
- PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes);
+ PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
}
// The 'fixed' part of the frame consists of the incoming parameters and
diff --git a/deps/v8/src/arm/disasm-arm.cc b/deps/v8/src/arm/disasm-arm.cc
index 96a7d3ce6..3c94a46e6 100644
--- a/deps/v8/src/arm/disasm-arm.cc
+++ b/deps/v8/src/arm/disasm-arm.cc
@@ -692,11 +692,19 @@ void Decoder::DecodeType01(Instruction* instr) {
// Rn field to encode it.
Format(instr, "mul'cond's 'rn, 'rm, 'rs");
} else {
- // The MLA instruction description (A 4.1.28) refers to the order
- // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
- // Rn field to encode the Rd register and the Rd field to encode
- // the Rn register.
- Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
+ if (instr->Bit(22) == 0) {
+ // The MLA instruction description (A 4.1.28) refers to the order
+ // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
+ // Rn field to encode the Rd register and the Rd field to encode
+ // the Rn register.
+ Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
+ } else {
+ // The MLS instruction description (A 4.1.29) refers to the order
+ // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
+ // Rn field to encode the Rd register and the Rd field to encode
+ // the Rn register.
+ Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd");
+ }
}
} else {
// The signed/long multiply instructions use the terms RdHi and RdLo
@@ -822,6 +830,8 @@ void Decoder::DecodeType01(Instruction* instr) {
} else {
Unknown(instr); // not used by V8
}
+ } else if ((type == 1) && instr->IsNopType1()) {
+ Format(instr, "nop'cond");
} else {
switch (instr->OpcodeField()) {
case AND: {
@@ -974,6 +984,17 @@ void Decoder::DecodeType3(Instruction* instr) {
break;
}
case db_x: {
+ if (FLAG_enable_sudiv) {
+ if (!instr->HasW()) {
+ if (instr->Bits(5, 4) == 0x1) {
+ if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) {
+ // SDIV (in V8 notation matching ARM ISA format) rn = rm/rs
+ Format(instr, "sdiv'cond'b 'rn, 'rm, 'rs");
+ break;
+ }
+ }
+ }
+ }
Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
break;
}
diff --git a/deps/v8/src/arm/full-codegen-arm.cc b/deps/v8/src/arm/full-codegen-arm.cc
index fbdb93082..be8228377 100644
--- a/deps/v8/src/arm/full-codegen-arm.cc
+++ b/deps/v8/src/arm/full-codegen-arm.cc
@@ -134,6 +134,8 @@ void FullCodeGenerator::Generate() {
SetFunctionPosition(function());
Comment cmnt(masm_, "[ function compiled by full code generator");
+ ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+
#ifdef DEBUG
if (strlen(FLAG_stop_at) > 0 &&
info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
@@ -182,10 +184,13 @@ void FullCodeGenerator::Generate() {
// Possibly allocate a local context.
int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
if (heap_slots > 0) {
- Comment cmnt(masm_, "[ Allocate local context");
- // Argument to NewContext is the function, which is in r1.
+ // Argument to NewContext is the function, which is still in r1.
+ Comment cmnt(masm_, "[ Allocate context");
__ push(r1);
- if (heap_slots <= FastNewContextStub::kMaximumSlots) {
+ if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+ __ Push(info->scope()->GetScopeInfo());
+ __ CallRuntime(Runtime::kNewGlobalContext, 2);
+ } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
FastNewContextStub stub(heap_slots);
__ CallStub(&stub);
} else {
@@ -262,7 +267,7 @@ void FullCodeGenerator::Generate() {
scope()->VisitIllegalRedeclaration(this);
} else {
- PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
+ PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
{ Comment cmnt(masm_, "[ Declarations");
// For named function expressions, declare the function name as a
// constant.
@@ -277,11 +282,12 @@ void FullCodeGenerator::Generate() {
}
{ Comment cmnt(masm_, "[ Stack check");
- PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
+ PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
Label ok;
__ LoadRoot(ip, Heap::kStackLimitRootIndex);
__ cmp(sp, Operand(ip));
__ b(hs, &ok);
+ PredictableCodeSizeScope predictable(masm_);
StackCheckStub stub;
__ CallStub(&stub);
__ bind(&ok);
@@ -328,7 +334,7 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
}
if (isolate()->IsDebuggerActive()) {
// Detect debug break requests as soon as possible.
- reset_value = 10;
+ reset_value = FLAG_interrupt_budget >> 4;
}
__ mov(r2, Operand(profiling_counter_));
__ mov(r3, Operand(Smi::FromInt(reset_value)));
@@ -336,10 +342,6 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
}
-static const int kMaxBackEdgeWeight = 127;
-static const int kBackEdgeDistanceDivisor = 142;
-
-
void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
Label* back_edge_target) {
Comment cmnt(masm_, "[ Stack check");
@@ -353,7 +355,7 @@ void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
ASSERT(back_edge_target->is_bound());
int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kBackEdgeDistanceDivisor));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
__ b(pl, &ok);
@@ -363,6 +365,7 @@ void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
__ LoadRoot(ip, Heap::kStackLimitRootIndex);
__ cmp(sp, Operand(ip));
__ b(hs, &ok);
+ PredictableCodeSizeScope predictable(masm_);
StackCheckStub stub;
__ CallStub(&stub);
}
@@ -405,7 +408,7 @@ void FullCodeGenerator::EmitReturnSequence() {
} else if (FLAG_weighted_back_edges) {
int distance = masm_->pc_offset();
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kBackEdgeDistanceDivisor));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
Label ok;
@@ -436,6 +439,7 @@ void FullCodeGenerator::EmitReturnSequence() {
// tool from instrumenting as we rely on the code size here.
int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize;
CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
+ PredictableCodeSizeScope predictable(masm_);
__ RecordJSReturn();
masm_->mov(sp, fp);
masm_->ldm(ia_w, sp, fp.bit() | lr.bit());
@@ -675,18 +679,9 @@ void FullCodeGenerator::DoTest(Expression* condition,
Label* if_true,
Label* if_false,
Label* fall_through) {
- if (CpuFeatures::IsSupported(VFP2)) {
- ToBooleanStub stub(result_register());
- __ CallStub(&stub);
- __ tst(result_register(), result_register());
- } else {
- // Call the runtime to find the boolean value of the source and then
- // translate it into control flow to the pair of labels.
- __ push(result_register());
- __ CallRuntime(Runtime::kToBool, 1);
- __ LoadRoot(ip, Heap::kFalseValueRootIndex);
- __ cmp(r0, ip);
- }
+ ToBooleanStub stub(result_register());
+ __ CallStub(&stub);
+ __ tst(result_register(), result_register());
Split(ne, if_true, if_false, fall_through);
}
@@ -787,7 +782,7 @@ void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
// The variable in the declaration always resides in the current function
// context.
ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
- if (FLAG_debug_code) {
+ if (generate_debug_code_) {
// Check that we're not inside a with or catch context.
__ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset));
__ CompareRoot(r1, Heap::kWithContextMapRootIndex);
@@ -840,10 +835,9 @@ void FullCodeGenerator::VisitVariableDeclaration(
Comment cmnt(masm_, "[ VariableDeclaration");
__ mov(r2, Operand(variable->name()));
// Declaration nodes are always introduced in one of four modes.
- ASSERT(mode == VAR || mode == LET ||
- mode == CONST || mode == CONST_HARMONY);
- PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
- ? READ_ONLY : NONE;
+ ASSERT(IsDeclaredVariableMode(mode));
+ PropertyAttributes attr =
+ IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
__ mov(r1, Operand(Smi::FromInt(attr)));
// Push initial value, if any.
// Note: For variables we must not push an initial value (such as
@@ -1133,26 +1127,34 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// modification check. Otherwise, we got a fixed array, and we have
// to do a slow check.
Label fixed_array;
- __ mov(r2, r0);
- __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
+ __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
__ LoadRoot(ip, Heap::kMetaMapRootIndex);
- __ cmp(r1, ip);
+ __ cmp(r2, ip);
__ b(ne, &fixed_array);
// We got a map in register r0. Get the enumeration cache from it.
+ Label no_descriptors;
__ bind(&use_cache);
- __ LoadInstanceDescriptors(r0, r1);
- __ ldr(r1, FieldMemOperand(r1, DescriptorArray::kEnumerationIndexOffset));
- __ ldr(r2, FieldMemOperand(r1, DescriptorArray::kEnumCacheBridgeCacheOffset));
+
+ __ EnumLength(r1, r0);
+ __ cmp(r1, Operand(Smi::FromInt(0)));
+ __ b(eq, &no_descriptors);
+
+ __ LoadInstanceDescriptors(r0, r2);
+ __ ldr(r2, FieldMemOperand(r2, DescriptorArray::kEnumCacheOffset));
+ __ ldr(r2, FieldMemOperand(r2, DescriptorArray::kEnumCacheBridgeCacheOffset));
// Set up the four remaining stack slots.
__ push(r0); // Map.
- __ ldr(r1, FieldMemOperand(r2, FixedArray::kLengthOffset));
__ mov(r0, Operand(Smi::FromInt(0)));
// Push enumeration cache, enumeration cache length (as smi) and zero.
__ Push(r2, r1, r0);
__ jmp(&loop);
+ __ bind(&no_descriptors);
+ __ Drop(1);
+ __ jmp(&exit);
+
// We got a fixed array in register r0. Iterate through that.
Label non_proxy;
__ bind(&fixed_array);
@@ -1161,7 +1163,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
isolate()->factory()->NewJSGlobalPropertyCell(
Handle<Object>(
Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker)));
- RecordTypeFeedbackCell(stmt->PrepareId(), cell);
+ RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
__ LoadHeapObject(r1, cell);
__ mov(r2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
__ str(r2, FieldMemOperand(r1, JSGlobalPropertyCell::kValueOffset));
@@ -1317,9 +1319,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
__ Move(next, current);
}
__ bind(&loop);
- // Terminate at global context.
+ // Terminate at native context.
__ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset));
- __ LoadRoot(ip, Heap::kGlobalContextMapRootIndex);
+ __ LoadRoot(ip, Heap::kNativeContextMapRootIndex);
__ cmp(temp, ip);
__ b(eq, &fast);
// Check that extension is NULL.
@@ -1607,7 +1609,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
// marked expressions, no store code is emitted.
expr->CalculateEmitStore(zone());
- AccessorTable accessor_table(isolate()->zone());
+ AccessorTable accessor_table(zone());
for (int i = 0; i < expr->properties()->length(); i++) {
ObjectLiteral::Property* property = expr->properties()->at(i);
if (property->IsCompileTimeValue()) continue;
@@ -1633,7 +1635,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, key->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
VisitForEffect(value);
@@ -1839,11 +1841,11 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
break;
case NAMED_PROPERTY:
EmitNamedPropertyLoad(property);
- PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
+ PrepareForBailoutForId(property->LoadId(), TOS_REG);
break;
case KEYED_PROPERTY:
EmitKeyedPropertyLoad(property);
- PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
+ PrepareForBailoutForId(property->LoadId(), TOS_REG);
break;
}
}
@@ -1900,7 +1902,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ mov(r2, Operand(key->handle()));
// Call load IC. It has arguments receiver and property name r0 and r2.
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
}
@@ -1908,7 +1910,7 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
// Call keyed load IC. It has arguments key and receiver in r0 and r1.
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
- CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
}
@@ -1935,7 +1937,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call);
BinaryOpStub stub(op, mode);
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done);
@@ -2018,7 +2021,8 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
__ pop(r1);
BinaryOpStub stub(op, mode);
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
context()->Plug(r0);
}
@@ -2149,7 +2153,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// in harmony mode.
if (var->IsStackAllocated() || var->IsContextSlot()) {
MemOperand location = VarOperand(var, r1);
- if (FLAG_debug_code && op == Token::INIT_LET) {
+ if (generate_debug_code_ && op == Token::INIT_LET) {
// Check for an uninitialized let binding.
__ ldr(r2, location);
__ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
@@ -2182,43 +2186,16 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
ASSERT(prop != NULL);
ASSERT(prop->key()->AsLiteral() != NULL);
- // If the assignment starts a block of assignments to the same object,
- // change to slow case to avoid the quadratic behavior of repeatedly
- // adding fast properties.
- if (expr->starts_initialization_block()) {
- __ push(result_register());
- __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is now under value.
- __ push(ip);
- __ CallRuntime(Runtime::kToSlowProperties, 1);
- __ pop(result_register());
- }
-
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
- // Load receiver to r1. Leave a copy in the stack if needed for turning the
- // receiver into fast case.
- if (expr->ends_initialization_block()) {
- __ ldr(r1, MemOperand(sp));
- } else {
- __ pop(r1);
- }
+ __ pop(r1);
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
-
- // If the assignment ends an initialization block, revert to fast case.
- if (expr->ends_initialization_block()) {
- __ push(r0); // Result of assignment, saved even if not needed.
- // Receiver is under the result value.
- __ ldr(ip, MemOperand(sp, kPointerSize));
- __ push(ip);
- __ CallRuntime(Runtime::kToFastProperties, 1);
- __ pop(r0);
- __ Drop(1);
- }
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
+
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
context()->Plug(r0);
}
@@ -2227,44 +2204,16 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
- // If the assignment starts a block of assignments to the same object,
- // change to slow case to avoid the quadratic behavior of repeatedly
- // adding fast properties.
- if (expr->starts_initialization_block()) {
- __ push(result_register());
- // Receiver is now under the key and value.
- __ ldr(ip, MemOperand(sp, 2 * kPointerSize));
- __ push(ip);
- __ CallRuntime(Runtime::kToSlowProperties, 1);
- __ pop(result_register());
- }
-
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ pop(r1); // Key.
- // Load receiver to r2. Leave a copy in the stack if needed for turning the
- // receiver into fast case.
- if (expr->ends_initialization_block()) {
- __ ldr(r2, MemOperand(sp));
- } else {
- __ pop(r2);
- }
+ __ pop(r2);
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
-
- // If the assignment ends an initialization block, revert to fast case.
- if (expr->ends_initialization_block()) {
- __ push(r0); // Result of assignment, saved even if not needed.
- // Receiver is under the result value.
- __ ldr(ip, MemOperand(sp, kPointerSize));
- __ push(ip);
- __ CallRuntime(Runtime::kToFastProperties, 1);
- __ pop(r0);
- __ Drop(1);
- }
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
+
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
context()->Plug(r0);
}
@@ -2277,6 +2226,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj());
EmitNamedPropertyLoad(expr);
+ PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(r0);
} else {
VisitForStackValue(expr->obj());
@@ -2290,9 +2240,11 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
void FullCodeGenerator::CallIC(Handle<Code> code,
RelocInfo::Mode rmode,
- unsigned ast_id) {
+ TypeFeedbackId ast_id) {
ic_total_count_++;
- __ Call(code, rmode, ast_id);
+ // All calls must have a predictable size in full-codegen code to ensure that
+ // the debugger can patch them correctly.
+ __ Call(code, rmode, ast_id, al, NEVER_INLINE_TARGET_ADDRESS);
}
void FullCodeGenerator::EmitCallWithIC(Call* expr,
@@ -2312,7 +2264,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
// Call the IC initialization code.
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
- CallIC(ic, mode, expr->id());
+ CallIC(ic, mode, expr->CallFeedbackId());
RecordJSReturnSite(expr);
// Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2345,7 +2297,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
Handle<Code> ic =
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
__ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key.
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId());
RecordJSReturnSite(expr);
// Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2365,16 +2317,14 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
// Record source position for debugger.
SetSourcePosition(expr->position());
- // Record call targets in unoptimized code, but not in the snapshot.
- if (!Serializer::enabled()) {
- flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
- Handle<Object> uninitialized =
- TypeFeedbackCells::UninitializedSentinel(isolate());
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
- RecordTypeFeedbackCell(expr->id(), cell);
- __ mov(r2, Operand(cell));
- }
+ // Record call targets in unoptimized code.
+ flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
+ Handle<Object> uninitialized =
+ TypeFeedbackCells::UninitializedSentinel(isolate());
+ Handle<JSGlobalPropertyCell> cell =
+ isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
+ RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
+ __ mov(r2, Operand(cell));
CallFunctionStub stub(arg_count, flags);
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
@@ -2564,21 +2514,15 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ mov(r0, Operand(arg_count));
__ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
- // Record call targets in unoptimized code, but not in the snapshot.
- CallFunctionFlags flags;
- if (!Serializer::enabled()) {
- flags = RECORD_CALL_TARGET;
- Handle<Object> uninitialized =
- TypeFeedbackCells::UninitializedSentinel(isolate());
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
- RecordTypeFeedbackCell(expr->id(), cell);
- __ mov(r2, Operand(cell));
- } else {
- flags = NO_CALL_FUNCTION_FLAGS;
- }
+ // Record call targets in unoptimized code.
+ Handle<Object> uninitialized =
+ TypeFeedbackCells::UninitializedSentinel(isolate());
+ Handle<JSGlobalPropertyCell> cell =
+ isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
+ RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
+ __ mov(r2, Operand(cell));
- CallConstructStub stub(flags);
+ CallConstructStub stub(RECORD_CALL_TARGET);
__ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
context()->Plug(r0);
@@ -2720,7 +2664,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
- if (FLAG_debug_code) __ AbortIfSmi(r0);
+ __ AssertNotSmi(r0);
__ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
__ ldrb(ip, FieldMemOperand(r1, Map::kBitField2Offset));
@@ -2735,27 +2679,31 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ b(eq, if_false);
// Look for valueOf symbol in the descriptor array, and indicate false if
- // found. The type is not checked, so if it is a transition it is a false
- // negative.
+ // found. Since we omit an enumeration index check, if it is added via a
+ // transition that shares its descriptor array, this is a false positive.
+ Label entry, loop, done;
+
+ // Skip loop if no descriptors are valid.
+ __ NumberOfOwnDescriptors(r3, r1);
+ __ cmp(r3, Operand(0));
+ __ b(eq, &done);
+
__ LoadInstanceDescriptors(r1, r4);
- __ ldr(r3, FieldMemOperand(r4, FixedArray::kLengthOffset));
- // r4: descriptor array
- // r3: length of descriptor array
- // Calculate the end of the descriptor array.
+ // r4: descriptor array.
+ // r3: valid entries in the descriptor array.
STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize == 1);
STATIC_ASSERT(kPointerSize == 4);
- __ add(r2, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ mov(ip, Operand(DescriptorArray::kDescriptorSize));
+ __ mul(r3, r3, ip);
+ // Calculate location of the first key name.
+ __ add(r4, r4, Operand(DescriptorArray::kFirstOffset - kHeapObjectTag));
+ // Calculate the end of the descriptor array.
+ __ mov(r2, r4);
__ add(r2, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize));
- // Calculate location of the first key name.
- __ add(r4,
- r4,
- Operand(FixedArray::kHeaderSize - kHeapObjectTag +
- DescriptorArray::kFirstIndex * kPointerSize));
// Loop through all the keys in the descriptor array. If one of these is the
// symbol valueOf the result is false.
- Label entry, loop;
// The use of ip to store the valueOf symbol asumes that it is not otherwise
// used in the loop below.
__ mov(ip, Operand(FACTORY->value_of_symbol()));
@@ -2764,18 +2712,19 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ ldr(r3, MemOperand(r4, 0));
__ cmp(r3, ip);
__ b(eq, if_false);
- __ add(r4, r4, Operand(kPointerSize));
+ __ add(r4, r4, Operand(DescriptorArray::kDescriptorSize * kPointerSize));
__ bind(&entry);
__ cmp(r4, Operand(r2));
__ b(ne, &loop);
- // If a valueOf property is not found on the object check that it's
+ __ bind(&done);
+ // If a valueOf property is not found on the object check that its
// prototype is the un-modified String prototype. If not result is false.
__ ldr(r2, FieldMemOperand(r1, Map::kPrototypeOffset));
__ JumpIfSmi(r2, if_false);
__ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset));
- __ ldr(r3, ContextOperand(cp, Context::GLOBAL_INDEX));
- __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalContextOffset));
+ __ ldr(r3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+ __ ldr(r3, FieldMemOperand(r3, GlobalObject::kNativeContextOffset));
__ ldr(r3, ContextOperand(r3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
__ cmp(r2, r3);
__ b(ne, if_false);
@@ -3054,8 +3003,9 @@ void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) {
// ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
if (CpuFeatures::IsSupported(VFP2)) {
__ PrepareCallCFunction(1, r0);
- __ ldr(r0, ContextOperand(context_register(), Context::GLOBAL_INDEX));
- __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset));
+ __ ldr(r0,
+ ContextOperand(context_register(), Context::GLOBAL_OBJECT_INDEX));
+ __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset));
__ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
CpuFeatures::Scope scope(VFP2);
@@ -3075,9 +3025,10 @@ void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) {
__ mov(r0, r4);
} else {
__ PrepareCallCFunction(2, r0);
- __ ldr(r1, ContextOperand(context_register(), Context::GLOBAL_INDEX));
+ __ ldr(r1,
+ ContextOperand(context_register(), Context::GLOBAL_OBJECT_INDEX));
__ mov(r0, Operand(r4));
- __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset));
+ __ ldr(r1, FieldMemOperand(r1, GlobalObject::kNativeContextOffset));
__ CallCFunction(
ExternalReference::fill_heap_number_with_random_function(isolate()), 2);
}
@@ -3139,20 +3090,19 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0)); // Load the object.
- Label runtime, done;
+ Label runtime, done, not_date_object;
Register object = r0;
Register result = r0;
Register scratch0 = r9;
Register scratch1 = r1;
-#ifdef DEBUG
- __ AbortIfSmi(object);
+ __ JumpIfSmi(object, &not_date_object);
__ CompareObjectType(object, scratch1, scratch1, JS_DATE_TYPE);
- __ Assert(eq, "Trying to get date field from non-date.");
-#endif
+ __ b(ne, &not_date_object);
if (index->value() == 0) {
__ ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
+ __ jmp(&done);
} else {
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
@@ -3169,8 +3119,12 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
__ PrepareCallCFunction(2, scratch1);
__ mov(r1, Operand(index));
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
- __ bind(&done);
+ __ jmp(&done);
}
+
+ __ bind(&not_date_object);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
+ __ bind(&done);
context()->Plug(r0);
}
@@ -3433,10 +3387,11 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
- // Check for proxy.
- Label proxy, done;
- __ CompareObjectType(r0, r1, r1, JS_FUNCTION_PROXY_TYPE);
- __ b(eq, &proxy);
+ Label runtime, done;
+ // Check for non-function argument (including proxy).
+ __ JumpIfSmi(r0, &runtime);
+ __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
+ __ b(ne, &runtime);
// InvokeFunction requires the function in r1. Move it in there.
__ mov(r1, result_register());
@@ -3446,7 +3401,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ jmp(&done);
- __ bind(&proxy);
+ __ bind(&runtime);
__ push(r0);
__ CallRuntime(Runtime::kCall, args->length());
__ bind(&done);
@@ -3474,7 +3429,7 @@ void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
Handle<FixedArray> jsfunction_result_caches(
- isolate()->global_context()->jsfunction_result_caches());
+ isolate()->native_context()->jsfunction_result_caches());
if (jsfunction_result_caches->length() <= cache_id) {
__ Abort("Attempt to use undefined cache.");
__ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
@@ -3486,8 +3441,8 @@ void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
Register key = r0;
Register cache = r1;
- __ ldr(cache, ContextOperand(cp, Context::GLOBAL_INDEX));
- __ ldr(cache, FieldMemOperand(cache, GlobalObject::kGlobalContextOffset));
+ __ ldr(cache, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+ __ ldr(cache, FieldMemOperand(cache, GlobalObject::kNativeContextOffset));
__ ldr(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX));
__ ldr(cache,
FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id)));
@@ -3584,9 +3539,7 @@ void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
ASSERT(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
- if (FLAG_debug_code) {
- __ AbortIfNotString(r0);
- }
+ __ AssertString(r0);
__ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset));
__ IndexFromHash(r0, r0);
@@ -3658,7 +3611,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
// string_length: Accumulated sum of string lengths (smi).
// element: Current array element.
// elements_end: Array end.
- if (FLAG_debug_code) {
+ if (generate_debug_code_) {
__ cmp(array_length, Operand(0));
__ Assert(gt, "No empty arrays here in EmitFastAsciiArrayJoin");
}
@@ -3856,7 +3809,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
- CallIC(ic, mode, expr->id());
+ CallIC(ic, mode, expr->CallRuntimeFeedbackId());
// Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
} else {
@@ -4011,7 +3964,8 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
// accumulator register r0.
VisitForAccumulatorValue(expr->expression());
SetSourcePosition(expr->position());
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->UnaryOperationFeedbackId());
context()->Plug(r0);
}
@@ -4069,7 +4023,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == VARIABLE) {
PrepareForBailout(expr->expression(), TOS_REG);
} else {
- PrepareForBailoutForId(expr->CountId(), TOS_REG);
+ PrepareForBailoutForId(prop->LoadId(), TOS_REG);
}
// Call ToNumber only if operand is not a smi.
@@ -4122,7 +4076,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
SetSourcePosition(expr->position());
BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4154,7 +4108,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
if (!context()->IsEffect()) {
@@ -4171,7 +4125,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
if (!context()->IsEffect()) {
@@ -4380,7 +4334,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CompareIC::GetUninitialized(op);
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
__ cmp(r0, Operand(0));
@@ -4464,7 +4418,7 @@ void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
Scope* declaration_scope = scope()->DeclarationScope();
if (declaration_scope->is_global_scope() ||
declaration_scope->is_module_scope()) {
- // Contexts nested in the global context have a canonical empty function
+ // Contexts nested in the native context have a canonical empty function
// as their closure, not the anonymous closure containing the global
// code. Pass a smi sentinel and let the runtime look up the empty
// function.
@@ -4509,6 +4463,7 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference::address_of_has_pending_message(isolate());
__ mov(ip, Operand(has_pending_message));
__ ldr(r1, MemOperand(ip));
+ __ SmiTag(r1);
__ push(r1);
ExternalReference pending_message_script =
@@ -4529,6 +4484,7 @@ void FullCodeGenerator::ExitFinallyBlock() {
__ str(r1, MemOperand(ip));
__ pop(r1);
+ __ SmiUntag(r1);
ExternalReference has_pending_message =
ExternalReference::address_of_has_pending_message(isolate());
__ mov(ip, Operand(has_pending_message));
diff --git a/deps/v8/src/arm/ic-arm.cc b/deps/v8/src/arm/ic-arm.cc
index fd9348098..48395897d 100644
--- a/deps/v8/src/arm/ic-arm.cc
+++ b/deps/v8/src/arm/ic-arm.cc
@@ -396,7 +396,7 @@ void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC,
extra_state,
- NORMAL,
+ Code::NORMAL,
argc);
Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, r1, r2, r3, r4, r5, r6);
@@ -1301,6 +1301,144 @@ void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
}
+static void KeyedStoreGenerateGenericHelper(
+ MacroAssembler* masm,
+ Label* fast_object,
+ Label* fast_double,
+ Label* slow,
+ KeyedStoreCheckMap check_map,
+ KeyedStoreIncrementLength increment_length,
+ Register value,
+ Register key,
+ Register receiver,
+ Register receiver_map,
+ Register elements_map,
+ Register elements) {
+ Label transition_smi_elements;
+ Label finish_object_store, non_double_value, transition_double_elements;
+ Label fast_double_without_map_check;
+
+ // Fast case: Do the store, could be either Object or double.
+ __ bind(fast_object);
+ Register scratch_value = r4;
+ Register address = r5;
+ if (check_map == kCheckMap) {
+ __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
+ __ cmp(elements_map,
+ Operand(masm->isolate()->factory()->fixed_array_map()));
+ __ b(ne, fast_double);
+ }
+ // Smi stores don't require further checks.
+ Label non_smi_value;
+ __ JumpIfNotSmi(value, &non_smi_value);
+
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ add(scratch_value, key, Operand(Smi::FromInt(1)));
+ __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
+ }
+ // It's irrelevant whether array is smi-only or not when writing a smi.
+ __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+ __ str(value, MemOperand(address));
+ __ Ret();
+
+ __ bind(&non_smi_value);
+ // Escape to elements kind transition case.
+ __ CheckFastObjectElements(receiver_map, scratch_value,
+ &transition_smi_elements);
+
+ // Fast elements array, store the value to the elements backing store.
+ __ bind(&finish_object_store);
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ add(scratch_value, key, Operand(Smi::FromInt(1)));
+ __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
+ }
+ __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+ __ str(value, MemOperand(address));
+ // Update write barrier for the elements array address.
+ __ mov(scratch_value, value); // Preserve the value which is returned.
+ __ RecordWrite(elements,
+ address,
+ scratch_value,
+ kLRHasNotBeenSaved,
+ kDontSaveFPRegs,
+ EMIT_REMEMBERED_SET,
+ OMIT_SMI_CHECK);
+ __ Ret();
+
+ __ bind(fast_double);
+ if (check_map == kCheckMap) {
+ // Check for fast double array case. If this fails, call through to the
+ // runtime.
+ __ CompareRoot(elements_map, Heap::kFixedDoubleArrayMapRootIndex);
+ __ b(ne, slow);
+ }
+ __ bind(&fast_double_without_map_check);
+ __ StoreNumberToDoubleElements(value,
+ key,
+ receiver,
+ elements, // Overwritten.
+ r3, // Scratch regs...
+ r4,
+ r5,
+ r6,
+ &transition_double_elements);
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ add(scratch_value, key, Operand(Smi::FromInt(1)));
+ __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
+ }
+ __ Ret();
+
+ __ bind(&transition_smi_elements);
+ // Transition the array appropriately depending on the value type.
+ __ ldr(r4, FieldMemOperand(value, HeapObject::kMapOffset));
+ __ CompareRoot(r4, Heap::kHeapNumberMapRootIndex);
+ __ b(ne, &non_double_value);
+
+ // Value is a double. Transition FAST_SMI_ELEMENTS ->
+ // FAST_DOUBLE_ELEMENTS and complete the store.
+ __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
+ FAST_DOUBLE_ELEMENTS,
+ receiver_map,
+ r4,
+ slow);
+ ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
+ ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
+ __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+ __ jmp(&fast_double_without_map_check);
+
+ __ bind(&non_double_value);
+ // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
+ __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
+ FAST_ELEMENTS,
+ receiver_map,
+ r4,
+ slow);
+ ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
+ ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
+ __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+ __ jmp(&finish_object_store);
+
+ __ bind(&transition_double_elements);
+ // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
+ // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
+ // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
+ __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
+ FAST_ELEMENTS,
+ receiver_map,
+ r4,
+ slow);
+ ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
+ ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
+ __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+ __ jmp(&finish_object_store);
+}
+
+
void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
StrictModeFlag strict_mode) {
// ---------- S t a t e --------------
@@ -1309,11 +1447,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// -- r2 : receiver
// -- lr : return address
// -----------------------------------
- Label slow, array, extra, check_if_double_array;
- Label fast_object_with_map_check, fast_object_without_map_check;
- Label fast_double_with_map_check, fast_double_without_map_check;
- Label transition_smi_elements, finish_object_store, non_double_value;
- Label transition_double_elements;
+ Label slow, fast_object, fast_object_grow;
+ Label fast_double, fast_double_grow;
+ Label array, extra, check_if_double_array;
// Register usage.
Register value = r0;
@@ -1348,7 +1484,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// Check array bounds. Both the key and the length of FixedArray are smis.
__ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
__ cmp(key, Operand(ip));
- __ b(lo, &fast_object_with_map_check);
+ __ b(lo, &fast_object);
// Slow case, handle jump to runtime.
__ bind(&slow);
@@ -1373,21 +1509,13 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
__ cmp(elements_map,
Operand(masm->isolate()->factory()->fixed_array_map()));
__ b(ne, &check_if_double_array);
- // Calculate key + 1 as smi.
- STATIC_ASSERT(kSmiTag == 0);
- __ add(r4, key, Operand(Smi::FromInt(1)));
- __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ b(&fast_object_without_map_check);
+ __ jmp(&fast_object_grow);
__ bind(&check_if_double_array);
__ cmp(elements_map,
Operand(masm->isolate()->factory()->fixed_double_array_map()));
__ b(ne, &slow);
- // Add 1 to key, and go to common element store code for doubles.
- STATIC_ASSERT(kSmiTag == 0);
- __ add(r4, key, Operand(Smi::FromInt(1)));
- __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ jmp(&fast_double_without_map_check);
+ __ jmp(&fast_double_grow);
// Array case: Get the length and the elements array from the JS
// array. Check that the array is in fast mode (and writable); if it
@@ -1399,106 +1527,15 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
__ ldr(ip, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ cmp(key, Operand(ip));
__ b(hs, &extra);
- // Fall through to fast case.
-
- __ bind(&fast_object_with_map_check);
- Register scratch_value = r4;
- Register address = r5;
- __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
- __ cmp(elements_map,
- Operand(masm->isolate()->factory()->fixed_array_map()));
- __ b(ne, &fast_double_with_map_check);
- __ bind(&fast_object_without_map_check);
- // Smi stores don't require further checks.
- Label non_smi_value;
- __ JumpIfNotSmi(value, &non_smi_value);
- // It's irrelevant whether array is smi-only or not when writing a smi.
- __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
- __ str(value, MemOperand(address));
- __ Ret();
-
- __ bind(&non_smi_value);
- // Escape to elements kind transition case.
- __ CheckFastObjectElements(receiver_map, scratch_value,
- &transition_smi_elements);
- // Fast elements array, store the value to the elements backing store.
- __ bind(&finish_object_store);
- __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
- __ str(value, MemOperand(address));
- // Update write barrier for the elements array address.
- __ mov(scratch_value, value); // Preserve the value which is returned.
- __ RecordWrite(elements,
- address,
- scratch_value,
- kLRHasNotBeenSaved,
- kDontSaveFPRegs,
- EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ Ret();
- __ bind(&fast_double_with_map_check);
- // Check for fast double array case. If this fails, call through to the
- // runtime.
- __ cmp(elements_map,
- Operand(masm->isolate()->factory()->fixed_double_array_map()));
- __ b(ne, &slow);
- __ bind(&fast_double_without_map_check);
- __ StoreNumberToDoubleElements(value,
- key,
- receiver,
- elements,
- r3,
- r4,
- r5,
- r6,
- &transition_double_elements);
- __ Ret();
-
- __ bind(&transition_smi_elements);
- // Transition the array appropriately depending on the value type.
- __ ldr(r4, FieldMemOperand(value, HeapObject::kMapOffset));
- __ CompareRoot(r4, Heap::kHeapNumberMapRootIndex);
- __ b(ne, &non_double_value);
-
- // Value is a double. Transition FAST_SMI_ELEMENTS ->
- // FAST_DOUBLE_ELEMENTS and complete the store.
- __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
- FAST_DOUBLE_ELEMENTS,
- receiver_map,
- r4,
- &slow);
- ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
- ElementsTransitionGenerator::GenerateSmiToDouble(masm, &slow);
- __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
- __ jmp(&fast_double_without_map_check);
-
- __ bind(&non_double_value);
- // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
- __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
- FAST_ELEMENTS,
- receiver_map,
- r4,
- &slow);
- ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
- __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
- __ jmp(&finish_object_store);
-
- __ bind(&transition_double_elements);
- // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
- // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
- // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
- __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
- FAST_ELEMENTS,
- receiver_map,
- r4,
- &slow);
- ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
- ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow);
- __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
- __ jmp(&finish_object_store);
+ KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
+ &slow, kCheckMap, kDontIncrementLength,
+ value, key, receiver, receiver_map,
+ elements_map, elements);
+ KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
+ &slow, kDontCheckMap, kIncrementLength,
+ value, key, receiver, receiver_map,
+ elements_map, elements);
}
@@ -1697,7 +1734,7 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
Address cmp_instruction_address =
- address + Assembler::kCallTargetAddressOffset;
+ Assembler::return_address_from_call_start(address);
// If the instruction following the call is not a cmp rx, #yyy, nothing
// was inlined.
diff --git a/deps/v8/src/arm/lithium-arm.cc b/deps/v8/src/arm/lithium-arm.cc
index 283862c78..21c549f17 100644
--- a/deps/v8/src/arm/lithium-arm.cc
+++ b/deps/v8/src/arm/lithium-arm.cc
@@ -194,22 +194,22 @@ void LGoto::PrintDataTo(StringStream* stream) {
void LBranch::PrintDataTo(StringStream* stream) {
stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
- InputAt(0)->PrintTo(stream);
+ left()->PrintTo(stream);
stream->Add(" %s ", Token::String(op()));
- InputAt(1)->PrintTo(stream);
+ right()->PrintTo(stream);
stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
}
void LIsNilAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(kind() == kStrictEquality ? " === " : " == ");
stream->Add(nil() == kNullValue ? "null" : "undefined");
stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
@@ -218,57 +218,57 @@ void LIsNilAndBranch::PrintDataTo(StringStream* stream) {
void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_object(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsStringAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_string(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_smi(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsUndetectableAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_undetectable(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LStringCompareAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if string_compare(");
- InputAt(0)->PrintTo(stream);
- InputAt(1)->PrintTo(stream);
+ left()->PrintTo(stream);
+ right()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if has_instance_type(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if has_cached_array_index(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if class_of_test(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(", \"%o\") then B%d else B%d",
*hydrogen()->class_name(),
true_block_id(),
@@ -278,7 +278,7 @@ void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if typeof ");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(" == \"%s\" then B%d else B%d",
*hydrogen()->type_literal()->ToCString(),
true_block_id(), false_block_id());
@@ -292,26 +292,26 @@ void LCallConstantFunction::PrintDataTo(StringStream* stream) {
void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
stream->Add("/%s ", hydrogen()->OpName());
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LLoadContextSlot::PrintDataTo(StringStream* stream) {
- InputAt(0)->PrintTo(stream);
+ context()->PrintTo(stream);
stream->Add("[%d]", slot_index());
}
void LStoreContextSlot::PrintDataTo(StringStream* stream) {
- InputAt(0)->PrintTo(stream);
+ context()->PrintTo(stream);
stream->Add("[%d] <- ", slot_index());
- InputAt(1)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LInvokeFunction::PrintDataTo(StringStream* stream) {
stream->Add("= ");
- InputAt(0)->PrintTo(stream);
+ function()->PrintTo(stream);
stream->Add(" #%d / ", arity());
}
@@ -340,17 +340,15 @@ void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
void LCallNew::PrintDataTo(StringStream* stream) {
stream->Add("= ");
- InputAt(0)->PrintTo(stream);
+ constructor()->PrintTo(stream);
stream->Add(" #%d / ", arity());
}
void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
arguments()->PrintTo(stream);
-
stream->Add(" length ");
length()->PrintTo(stream);
-
stream->Add(" index ");
index()->PrintTo(stream);
}
@@ -407,24 +405,14 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) {
}
-LChunk::LChunk(CompilationInfo* info, HGraph* graph)
- : spill_slot_count_(0),
- info_(info),
- graph_(graph),
- instructions_(32, graph->zone()),
- pointer_maps_(8, graph->zone()),
- inlined_closures_(1, graph->zone()) {
-}
-
-
-int LChunk::GetNextSpillIndex(bool is_double) {
+int LPlatformChunk::GetNextSpillIndex(bool is_double) {
// Skip a slot if for a double-width slot.
if (is_double) spill_slot_count_++;
return spill_slot_count_++;
}
-LOperand* LChunk::GetNextSpillSlot(bool is_double) {
+LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) {
int index = GetNextSpillIndex(is_double);
if (is_double) {
return LDoubleStackSlot::Create(index, zone());
@@ -434,120 +422,9 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) {
}
-void LChunk::MarkEmptyBlocks() {
- HPhase phase("L_Mark empty blocks", this);
- for (int i = 0; i < graph()->blocks()->length(); ++i) {
- HBasicBlock* block = graph()->blocks()->at(i);
- int first = block->first_instruction_index();
- int last = block->last_instruction_index();
- LInstruction* first_instr = instructions()->at(first);
- LInstruction* last_instr = instructions()->at(last);
-
- LLabel* label = LLabel::cast(first_instr);
- if (last_instr->IsGoto()) {
- LGoto* goto_instr = LGoto::cast(last_instr);
- if (label->IsRedundant() &&
- !label->is_loop_header()) {
- bool can_eliminate = true;
- for (int i = first + 1; i < last && can_eliminate; ++i) {
- LInstruction* cur = instructions()->at(i);
- if (cur->IsGap()) {
- LGap* gap = LGap::cast(cur);
- if (!gap->IsRedundant()) {
- can_eliminate = false;
- }
- } else {
- can_eliminate = false;
- }
- }
-
- if (can_eliminate) {
- label->set_replacement(GetLabel(goto_instr->block_id()));
- }
- }
- }
- }
-}
-
-
-void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
- LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
- int index = -1;
- if (instr->IsControl()) {
- instructions_.Add(gap, zone());
- index = instructions_.length();
- instructions_.Add(instr, zone());
- } else {
- index = instructions_.length();
- instructions_.Add(instr, zone());
- instructions_.Add(gap, zone());
- }
- if (instr->HasPointerMap()) {
- pointer_maps_.Add(instr->pointer_map(), zone());
- instr->pointer_map()->set_lithium_position(index);
- }
-}
-
-
-LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
- return LConstantOperand::Create(constant->id(), zone());
-}
-
-
-int LChunk::GetParameterStackSlot(int index) const {
- // The receiver is at index 0, the first parameter at index 1, so we
- // shift all parameter indexes down by the number of parameters, and
- // make sure they end up negative so they are distinguishable from
- // spill slots.
- int result = index - info()->scope()->num_parameters() - 1;
- ASSERT(result < 0);
- return result;
-}
-
-// A parameter relative to ebp in the arguments stub.
-int LChunk::ParameterAt(int index) {
- ASSERT(-1 <= index); // -1 is the receiver.
- return (1 + info()->scope()->num_parameters() - index) *
- kPointerSize;
-}
-
-
-LGap* LChunk::GetGapAt(int index) const {
- return LGap::cast(instructions_[index]);
-}
-
-
-bool LChunk::IsGapAt(int index) const {
- return instructions_[index]->IsGap();
-}
-
-
-int LChunk::NearestGapPos(int index) const {
- while (!IsGapAt(index)) index--;
- return index;
-}
-
-
-void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
- GetGapAt(index)->GetOrCreateParallelMove(
- LGap::START, zone())->AddMove(from, to, zone());
-}
-
-
-Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
- return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
-}
-
-
-Representation LChunk::LookupLiteralRepresentation(
- LConstantOperand* operand) const {
- return graph_->LookupValue(operand->index())->representation();
-}
-
-
-LChunk* LChunkBuilder::Build() {
+LPlatformChunk* LChunkBuilder::Build() {
ASSERT(is_unused());
- chunk_ = new(zone()) LChunk(info(), graph());
+ chunk_ = new(zone()) LPlatformChunk(info(), graph());
HPhase phase("L_Building chunk", chunk_);
status_ = BUILDING;
const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
@@ -562,17 +439,8 @@ LChunk* LChunkBuilder::Build() {
}
-void LChunkBuilder::Abort(const char* format, ...) {
- if (FLAG_trace_bailout) {
- SmartArrayPointer<char> name(
- info()->shared_info()->DebugName()->ToCString());
- PrintF("Aborting LChunk building in @\"%s\": ", *name);
- va_list arguments;
- va_start(arguments, format);
- OS::VPrint(format, arguments);
- va_end(arguments);
- PrintF("\n");
- }
+void LChunkBuilder::Abort(const char* reason) {
+ info()->set_bailout_reason(reason);
status_ = ABORTED;
}
@@ -741,7 +609,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
ASSERT(hinstr->next()->IsSimulate());
HSimulate* sim = HSimulate::cast(hinstr->next());
ASSERT(instruction_pending_deoptimization_environment_ == NULL);
- ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
+ ASSERT(pending_deoptimization_ast_id_.IsNone());
instruction_pending_deoptimization_environment_ = instr;
pending_deoptimization_ast_id_ = sim->ast_id();
}
@@ -836,13 +704,16 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
// Shift operations can only deoptimize if we do a logical shift
// by 0 and the result cannot be truncated to int32.
- bool may_deopt = (op == Token::SHR && constant_value == 0);
bool does_deopt = false;
- if (may_deopt) {
- for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
- if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
- does_deopt = true;
- break;
+ if (op == Token::SHR && constant_value == 0) {
+ if (FLAG_opt_safe_uint32_operations) {
+ does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+ } else {
+ for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
+ if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
+ does_deopt = true;
+ break;
+ }
}
}
}
@@ -975,8 +846,8 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
LEnvironment* outer =
CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator);
- int ast_id = hydrogen_env->ast_id();
- ASSERT(ast_id != AstNode::kNoNumber ||
+ BailoutId ast_id = hydrogen_env->ast_id();
+ ASSERT(!ast_id.IsNone() ||
hydrogen_env->frame_type() != JS_FUNCTION);
int value_count = hydrogen_env->length();
LEnvironment* result = new(zone()) LEnvironment(
@@ -987,6 +858,7 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
argument_count_,
value_count,
outer,
+ hydrogen_env->entry(),
zone());
int argument_index = *argument_index_accumulator;
for (int i = 0; i < value_count; ++i) {
@@ -1001,7 +873,9 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
} else {
op = UseAny(value);
}
- result->AddValue(op, value->representation());
+ result->AddValue(op,
+ value->representation(),
+ value->CheckFlag(HInstruction::kUint32));
}
if (hydrogen_env->frame_type() == JS_FUNCTION) {
@@ -1166,7 +1040,8 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
return DefineFixedDouble(result, d2);
} else {
LOperand* input = UseRegisterAtStart(instr->value());
- LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL;
+
+ LOperand* temp = (op == kMathRound) ? FixedTemp(d3) : NULL;
LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp);
switch (op) {
case kMathAbs:
@@ -1480,6 +1355,25 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
+LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
+ LOperand* left = NULL;
+ LOperand* right = NULL;
+ if (instr->representation().IsInteger32()) {
+ ASSERT(instr->left()->representation().IsInteger32());
+ ASSERT(instr->right()->representation().IsInteger32());
+ left = UseRegisterAtStart(instr->LeastConstantOperand());
+ right = UseOrConstantAtStart(instr->MostConstantOperand());
+ } else {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->left()->representation().IsDouble());
+ ASSERT(instr->right()->representation().IsDouble());
+ left = UseRegisterAtStart(instr->left());
+ right = UseRegisterAtStart(instr->right());
+ }
+ return DefineAsRegister(new(zone()) LMathMinMax(left, right));
+}
+
+
LInstruction* LChunkBuilder::DoPower(HPower* instr) {
ASSERT(instr->representation().IsDouble());
// We call a C function for double power. It can't trigger a GC.
@@ -1645,6 +1539,12 @@ LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
}
+LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
+ LOperand* map = UseRegisterAtStart(instr->value());
+ return DefineAsRegister(new(zone()) LMapEnumLength(map));
+}
+
+
LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
LOperand* object = UseRegisterAtStart(instr->value());
return DefineAsRegister(new(zone()) LElementsKind(object));
@@ -1662,12 +1562,12 @@ LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
LOperand* object = UseFixed(instr->value(), r0);
LDateField* result =
new(zone()) LDateField(object, FixedTemp(r1), instr->index());
- return MarkAsCall(DefineFixed(result, r0), instr);
+ return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
}
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
- LOperand* value = UseRegisterAtStart(instr->index());
+ LOperand* value = UseRegisterOrConstantAtStart(instr->index());
LOperand* length = UseRegister(instr->length());
return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
}
@@ -1717,8 +1617,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
LOperand* temp1 = TempRegister();
LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
: NULL;
- LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d11)
- : NULL;
+ LOperand* temp3 = FixedTemp(d11);
res = DefineSameAsFirst(new(zone()) LTaggedToI(value,
temp1,
temp2,
@@ -1751,7 +1650,10 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
if (to.IsTagged()) {
HValue* val = instr->value();
LOperand* value = UseRegisterAtStart(val);
- if (val->HasRange() && val->range()->IsInSmiRange()) {
+ if (val->CheckFlag(HInstruction::kUint32)) {
+ LNumberTagU* result = new(zone()) LNumberTagU(value);
+ return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
+ } else if (val->HasRange() && val->range()->IsInSmiRange()) {
return DefineAsRegister(new(zone()) LSmiTag(value));
} else {
LNumberTagI* result = new(zone()) LNumberTagI(value);
@@ -1759,8 +1661,13 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
}
} else {
ASSERT(to.IsDouble());
- LOperand* value = Use(instr->value());
- return DefineAsRegister(new(zone()) LInteger32ToDouble(value));
+ if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+ return DefineAsRegister(
+ new(zone()) LUint32ToDouble(UseRegister(instr->value())));
+ } else {
+ return DefineAsRegister(
+ new(zone()) LInteger32ToDouble(Use(instr->value())));
+ }
}
}
UNREACHABLE();
@@ -1956,9 +1863,10 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
HLoadKeyedFastElement* instr) {
ASSERT(instr->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* obj = UseRegisterAtStart(instr->object());
- LOperand* key = UseRegisterAtStart(instr->key());
+ LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key);
if (instr->RequiresHoleCheck()) AssignEnvironment(result);
return DefineAsRegister(result);
@@ -1968,7 +1876,8 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
HLoadKeyedFastDoubleElement* instr) {
ASSERT(instr->representation().IsDouble());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* elements = UseTempRegister(instr->elements());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastDoubleElement* result =
@@ -1987,7 +1896,8 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
(instr->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* key = UseRegisterOrConstant(instr->key());
LLoadKeyedSpecializedArrayElement* result =
@@ -2015,7 +1925,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
bool needs_write_barrier = instr->NeedsWriteBarrier();
ASSERT(instr->value()->representation().IsTagged());
ASSERT(instr->object()->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* obj = UseTempRegister(instr->object());
LOperand* val = needs_write_barrier
@@ -2032,7 +1943,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
HStoreKeyedFastDoubleElement* instr) {
ASSERT(instr->value()->representation().IsDouble());
ASSERT(instr->elements()->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* elements = UseRegisterAtStart(instr->elements());
LOperand* val = UseTempRegister(instr->value());
@@ -2053,7 +1965,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer());
bool val_is_temp_register =
@@ -2212,6 +2125,7 @@ LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
+ ASSERT(argument_count_ == 0);
allocator_->MarkAsOsrEntry();
current_block_->last_environment()->set_ast_id(instr->ast_id());
return AssignEnvironment(new(zone()) LOsrEntry);
@@ -2250,12 +2164,10 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
- LOperand* arguments = UseRegister(instr->arguments());
+ LOperand* args = UseRegister(instr->arguments());
LOperand* length = UseTempRegister(instr->length());
LOperand* index = UseRegister(instr->index());
- LAccessArgumentsAt* result =
- new(zone()) LAccessArgumentsAt(arguments, length, index);
- return AssignEnvironment(DefineAsRegister(result));
+ return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
}
@@ -2309,7 +2221,7 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
instruction_pending_deoptimization_environment_->
SetDeferredLazyDeoptimizationEnvironment(result->environment());
instruction_pending_deoptimization_environment_ = NULL;
- pending_deoptimization_ast_id_ = AstNode::kNoNumber;
+ pending_deoptimization_ast_id_ = BailoutId::None();
return result;
}
@@ -2335,10 +2247,11 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
instr->function(),
undefined,
instr->call_kind(),
- instr->is_construct());
+ instr->inlining_kind());
if (instr->arguments_var() != NULL) {
inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
}
+ inner->set_entry(instr);
current_block_->UpdateEnvironment(inner);
chunk_->AddInlinedClosure(instr->closure());
return NULL;
@@ -2350,7 +2263,7 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
HEnvironment* env = current_block_->last_environment();
- if (instr->arguments_pushed()) {
+ if (env->entry()->arguments_pushed()) {
int argument_count = env->arguments_environment()->parameter_count();
pop = new(zone()) LDrop(argument_count);
argument_count_ -= argument_count;
@@ -2381,8 +2294,7 @@ LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
LOperand* map = UseRegister(instr->map());
- return AssignEnvironment(DefineAsRegister(
- new(zone()) LForInCacheArray(map)));
+ return AssignEnvironment(DefineAsRegister(new(zone()) LForInCacheArray(map)));
}
diff --git a/deps/v8/src/arm/lithium-arm.h b/deps/v8/src/arm/lithium-arm.h
index 869a80a28..fb36fe9c0 100644
--- a/deps/v8/src/arm/lithium-arm.h
+++ b/deps/v8/src/arm/lithium-arm.h
@@ -108,6 +108,7 @@ class LCodeGen;
V(InstanceOfKnownGlobal) \
V(InstructionGap) \
V(Integer32ToDouble) \
+ V(Uint32ToDouble) \
V(InvokeFunction) \
V(IsConstructCallAndBranch) \
V(IsNilAndBranch) \
@@ -115,7 +116,6 @@ class LCodeGen;
V(IsStringAndBranch) \
V(IsSmiAndBranch) \
V(IsUndetectableAndBranch) \
- V(StringCompareAndBranch) \
V(JSArrayLength) \
V(Label) \
V(LazyBailout) \
@@ -132,11 +132,14 @@ class LCodeGen;
V(LoadNamedField) \
V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
+ V(MapEnumLength) \
V(MathFloorOfDiv) \
+ V(MathMinMax) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
V(NumberTagI) \
+ V(NumberTagU) \
V(NumberUntagD) \
V(ObjectLiteral) \
V(OsrEntry) \
@@ -163,6 +166,7 @@ class LCodeGen;
V(StringAdd) \
V(StringCharCodeAt) \
V(StringCharFromCode) \
+ V(StringCompareAndBranch) \
V(StringLength) \
V(SubI) \
V(TaggedToI) \
@@ -257,11 +261,6 @@ class LInstruction: public ZoneObject {
virtual bool HasResult() const = 0;
virtual LOperand* result() = 0;
- virtual int InputCount() = 0;
- virtual LOperand* InputAt(int i) = 0;
- virtual int TempCount() = 0;
- virtual LOperand* TempAt(int i) = 0;
-
LOperand* FirstInput() { return InputAt(0); }
LOperand* Output() { return HasResult() ? result() : NULL; }
@@ -270,6 +269,15 @@ class LInstruction: public ZoneObject {
#endif
private:
+ // Iterator support.
+ friend class InputIterator;
+ virtual int InputCount() = 0;
+ virtual LOperand* InputAt(int i) = 0;
+
+ friend class TempIterator;
+ virtual int TempCount() = 0;
+ virtual LOperand* TempAt(int i) = 0;
+
LEnvironment* environment_;
SetOncePointer<LPointerMap> pointer_map_;
HValue* hydrogen_value_;
@@ -289,16 +297,17 @@ class LTemplateInstruction: public LInstruction {
void set_result(LOperand* operand) { results_[0] = operand; }
LOperand* result() { return results_[0]; }
- int InputCount() { return I; }
- LOperand* InputAt(int i) { return inputs_[i]; }
-
- int TempCount() { return T; }
- LOperand* TempAt(int i) { return temps_[i]; }
-
protected:
EmbeddedContainer<LOperand*, R> results_;
EmbeddedContainer<LOperand*, I> inputs_;
EmbeddedContainer<LOperand*, T> temps_;
+
+ private:
+ virtual int InputCount() { return I; }
+ virtual LOperand* InputAt(int i) { return inputs_[i]; }
+
+ virtual int TempCount() { return T; }
+ virtual LOperand* TempAt(int i) { return temps_[i]; }
};
@@ -516,6 +525,8 @@ class LArgumentsLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = elements;
}
+ LOperand* elements() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
};
@@ -542,16 +553,22 @@ class LModI: public LTemplateInstruction<1, 2, 3> {
// Used for the standard case.
LModI(LOperand* left,
LOperand* right,
- LOperand* temp1,
+ LOperand* temp,
LOperand* temp2,
LOperand* temp3) {
inputs_[0] = left;
inputs_[1] = right;
- temps_[0] = temp1;
+ temps_[0] = temp;
temps_[1] = temp2;
temps_[2] = temp3;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+ LOperand* temp3() { return temps_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
DECLARE_HYDROGEN_ACCESSOR(Mod)
};
@@ -564,6 +581,9 @@ class LDivI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(Div)
};
@@ -579,6 +599,10 @@ class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> {
temps_[0] = temp;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
};
@@ -592,6 +616,10 @@ class LMulI: public LTemplateInstruction<1, 2, 1> {
temps_[0] = temp;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
DECLARE_HYDROGEN_ACCESSOR(Mul)
};
@@ -604,6 +632,9 @@ class LCmpIDAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
@@ -623,6 +654,9 @@ class LUnaryMathOperation: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
@@ -638,6 +672,9 @@ class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch,
"cmp-object-eq-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch)
@@ -650,6 +687,8 @@ class LCmpConstantEqAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = left;
}
+ LOperand* left() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpConstantEqAndBranch,
"cmp-constant-eq-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareConstantEqAndBranch)
@@ -662,6 +701,8 @@ class LIsNilAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch, "is-nil-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsNilAndBranch)
@@ -679,6 +720,9 @@ class LIsObjectAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
@@ -693,6 +737,9 @@ class LIsStringAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
@@ -706,6 +753,8 @@ class LIsSmiAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
@@ -720,6 +769,9 @@ class LIsUndetectableAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
"is-undetectable-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
@@ -735,6 +787,9 @@ class LStringCompareAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
"string-compare-and-branch")
DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
@@ -751,6 +806,8 @@ class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
"has-instance-type-and-branch")
DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
@@ -765,6 +822,8 @@ class LGetCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
};
@@ -776,6 +835,8 @@ class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
"has-cached-array-index-and-branch")
DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
@@ -791,6 +852,9 @@ class LClassOfTestAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
"class-of-test-and-branch")
DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
@@ -806,6 +870,9 @@ class LCmpT: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
@@ -820,6 +887,9 @@ class LInstanceOf: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
};
@@ -831,6 +901,9 @@ class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
"instance-of-known-global")
DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
@@ -859,6 +932,7 @@ class LBoundsCheck: public LTemplateInstruction<0, 2, 0> {
LOperand* length() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
+ DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
};
@@ -869,6 +943,9 @@ class LBitI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
Token::Value op() const { return hydrogen()->op(); }
DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
@@ -885,7 +962,8 @@ class LShiftI: public LTemplateInstruction<1, 2, 0> {
}
Token::Value op() const { return op_; }
-
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
bool can_deopt() const { return can_deopt_; }
DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
@@ -903,6 +981,9 @@ class LSubI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
DECLARE_HYDROGEN_ACCESSOR(Sub)
};
@@ -941,6 +1022,8 @@ class LBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
DECLARE_HYDROGEN_ACCESSOR(Branch)
@@ -955,6 +1038,9 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMap)
@@ -976,6 +1062,8 @@ class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
};
@@ -987,18 +1075,34 @@ class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength,
"fixed-array-base-length")
DECLARE_HYDROGEN_ACCESSOR(FixedArrayBaseLength)
};
+class LMapEnumLength: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LMapEnumLength(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
+};
+
+
class LElementsKind: public LTemplateInstruction<1, 1, 0> {
public:
explicit LElementsKind(LOperand* value) {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
};
@@ -1011,6 +1115,9 @@ class LValueOf: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
DECLARE_HYDROGEN_ACCESSOR(ValueOf)
};
@@ -1023,40 +1130,26 @@ class LDateField: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* date() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ Smi* index() const { return index_; }
+
DECLARE_CONCRETE_INSTRUCTION(ValueOf, "date-field")
DECLARE_HYDROGEN_ACCESSOR(ValueOf)
- Smi* index() const { return index_; }
private:
Smi* index_;
};
-class LSetDateField: public LTemplateInstruction<1, 2, 1> {
- public:
- LSetDateField(LOperand* date, LOperand* value, LOperand* temp, int index)
- : index_(index) {
- inputs_[0] = date;
- inputs_[1] = value;
- temps_[0] = temp;
- }
-
- DECLARE_CONCRETE_INSTRUCTION(DateField, "date-set-field")
- DECLARE_HYDROGEN_ACCESSOR(DateField)
-
- int index() const { return index_; }
-
- private:
- int index_;
-};
-
-
class LThrow: public LTemplateInstruction<0, 1, 0> {
public:
explicit LThrow(LOperand* value) {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
};
@@ -1067,6 +1160,8 @@ class LBitNotI: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
};
@@ -1078,11 +1173,29 @@ class LAddI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
DECLARE_HYDROGEN_ACCESSOR(Add)
};
+class LMathMinMax: public LTemplateInstruction<1, 2, 0> {
+ public:
+ LMathMinMax(LOperand* left, LOperand* right) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ }
+
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "min-max")
+ DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
+};
+
+
class LPower: public LTemplateInstruction<1, 2, 0> {
public:
LPower(LOperand* left, LOperand* right) {
@@ -1090,6 +1203,9 @@ class LPower: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(Power, "power")
DECLARE_HYDROGEN_ACCESSOR(Power)
};
@@ -1101,6 +1217,8 @@ class LRandom: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = global_object;
}
+ LOperand* global_object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Random, "random")
DECLARE_HYDROGEN_ACCESSOR(Random)
};
@@ -1115,6 +1233,8 @@ class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
}
Token::Value op() const { return op_; }
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
virtual Opcode opcode() const { return LInstruction::kArithmeticD; }
virtual void CompileToNative(LCodeGen* generator);
@@ -1133,12 +1253,14 @@ class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ Token::Value op() const { return op_; }
+
virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
- Token::Value op() const { return op_; }
-
private:
Token::Value op_;
};
@@ -1150,6 +1272,8 @@ class LReturn: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Return, "return")
};
@@ -1160,6 +1284,8 @@ class LLoadNamedField: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
};
@@ -1171,10 +1297,10 @@ class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
-
- LOperand* object() { return inputs_[0]; }
};
@@ -1184,10 +1310,11 @@ class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
- LOperand* object() { return inputs_[0]; }
Handle<Object> name() const { return hydrogen()->name(); }
};
@@ -1198,10 +1325,10 @@ class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = function;
}
+ LOperand* function() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
-
- LOperand* function() { return inputs_[0]; }
};
@@ -1211,6 +1338,8 @@ class LLoadElements: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
};
@@ -1221,6 +1350,8 @@ class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
"load-external-array-pointer")
};
@@ -1233,11 +1364,12 @@ class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
+ LOperand* elements() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
- LOperand* elements() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1249,12 +1381,13 @@ class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
+ LOperand* elements() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement,
"load-keyed-fast-double-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastDoubleElement)
- LOperand* elements() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1266,12 +1399,13 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
+ LOperand* external_pointer() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
"load-keyed-specialized-array-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
- LOperand* external_pointer() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
ElementsKind elements_kind() const {
return hydrogen()->elements_kind();
}
@@ -1281,15 +1415,15 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
class LLoadKeyedGeneric: public LTemplateInstruction<1, 2, 0> {
public:
- LLoadKeyedGeneric(LOperand* obj, LOperand* key) {
- inputs_[0] = obj;
+ LLoadKeyedGeneric(LOperand* object, LOperand* key) {
+ inputs_[0] = object;
inputs_[1] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
-
LOperand* object() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
};
@@ -1306,10 +1440,11 @@ class LLoadGlobalGeneric: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = global_object;
}
+ LOperand* global_object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
- LOperand* global_object() { return inputs_[0]; }
Handle<Object> name() const { return hydrogen()->name(); }
bool for_typeof() const { return hydrogen()->for_typeof(); }
};
@@ -1322,10 +1457,11 @@ class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
-
- LOperand* value() { return inputs_[0]; }
};
@@ -1337,12 +1473,13 @@ class LStoreGlobalGeneric: public LTemplateInstruction<0, 2, 0> {
inputs_[1] = value;
}
+ LOperand* global_object() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric)
- LOperand* global_object() { return InputAt(0); }
Handle<Object> name() const { return hydrogen()->name(); }
- LOperand* value() { return InputAt(1); }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1353,10 +1490,11 @@ class LLoadContextSlot: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
+ LOperand* context() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
- LOperand* context() { return InputAt(0); }
int slot_index() { return hydrogen()->slot_index(); }
virtual void PrintDataTo(StringStream* stream);
@@ -1370,11 +1508,12 @@ class LStoreContextSlot: public LTemplateInstruction<0, 2, 0> {
inputs_[1] = value;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
- LOperand* context() { return InputAt(0); }
- LOperand* value() { return InputAt(1); }
int slot_index() { return hydrogen()->slot_index(); }
virtual void PrintDataTo(StringStream* stream);
@@ -1387,6 +1526,8 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
};
@@ -1423,9 +1564,9 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
- DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
+ LOperand* context() { return inputs_[0]; }
- LOperand* context() { return InputAt(0); }
+ DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
};
@@ -1444,7 +1585,7 @@ class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
- LOperand* context() { return InputAt(0); }
+ LOperand* context() { return inputs_[0]; }
};
@@ -1454,9 +1595,9 @@ class LGlobalReceiver: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = global_object;
}
- DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
+ LOperand* global_object() { return inputs_[0]; }
- LOperand* global() { return InputAt(0); }
+ DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
};
@@ -1478,11 +1619,11 @@ class LInvokeFunction: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = function;
}
+ LOperand* function() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
- LOperand* function() { return inputs_[0]; }
-
virtual void PrintDataTo(StringStream* stream);
int arity() const { return hydrogen()->argument_count() - 1; }
@@ -1496,6 +1637,8 @@ class LCallKeyed: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = key;
}
+ LOperand* key() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
@@ -1524,10 +1667,11 @@ class LCallFunction: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = function;
}
+ LOperand* function() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
DECLARE_HYDROGEN_ACCESSOR(CallFunction)
- LOperand* function() { return inputs_[0]; }
int arity() const { return hydrogen()->argument_count() - 1; }
};
@@ -1562,6 +1706,8 @@ class LCallNew: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = constructor;
}
+ LOperand* constructor() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
DECLARE_HYDROGEN_ACCESSOR(CallNew)
@@ -1587,28 +1733,60 @@ class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
};
+class LUint32ToDouble: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LUint32ToDouble(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
+};
+
+
class LNumberTagI: public LTemplateInstruction<1, 1, 0> {
public:
explicit LNumberTagI(LOperand* value) {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
};
+class LNumberTagU: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LNumberTagU(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
+};
+
+
class LNumberTagD: public LTemplateInstruction<1, 1, 2> {
public:
- LNumberTagD(LOperand* value, LOperand* temp1, LOperand* temp2) {
+ LNumberTagD(LOperand* value, LOperand* temp, LOperand* temp2) {
inputs_[0] = value;
- temps_[0] = temp1;
+ temps_[0] = temp;
temps_[1] = temp2;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
};
@@ -1616,12 +1794,16 @@ class LNumberTagD: public LTemplateInstruction<1, 1, 2> {
// Sometimes truncating conversion from a tagged value to an int32.
class LDoubleToI: public LTemplateInstruction<1, 1, 2> {
public:
- LDoubleToI(LOperand* value, LOperand* temp1, LOperand* temp2) {
+ LDoubleToI(LOperand* value, LOperand* temp, LOperand* temp2) {
inputs_[0] = value;
- temps_[0] = temp1;
+ temps_[0] = temp;
temps_[1] = temp2;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
@@ -1633,15 +1815,20 @@ class LDoubleToI: public LTemplateInstruction<1, 1, 2> {
class LTaggedToI: public LTemplateInstruction<1, 1, 3> {
public:
LTaggedToI(LOperand* value,
- LOperand* temp1,
+ LOperand* temp,
LOperand* temp2,
LOperand* temp3) {
inputs_[0] = value;
- temps_[0] = temp1;
+ temps_[0] = temp;
temps_[1] = temp2;
temps_[2] = temp3;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+ LOperand* temp3() { return temps_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
@@ -1655,6 +1842,8 @@ class LSmiTag: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
};
@@ -1665,6 +1854,8 @@ class LNumberUntagD: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
DECLARE_HYDROGEN_ACCESSOR(Change)
};
@@ -1677,10 +1868,11 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
- DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
-
+ LOperand* value() { return inputs_[0]; }
bool needs_check() const { return needs_check_; }
+ DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
+
private:
bool needs_check_;
};
@@ -1688,20 +1880,21 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
public:
- LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp) {
- inputs_[0] = obj;
- inputs_[1] = val;
+ LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
+ inputs_[0] = object;
+ inputs_[1] = value;
temps_[0] = temp;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* value() { return inputs_[1]; }
-
Handle<Object> name() const { return hydrogen()->name(); }
bool is_in_object() { return hydrogen()->is_in_object(); }
int offset() { return hydrogen()->offset(); }
@@ -1711,18 +1904,19 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
public:
- LStoreNamedGeneric(LOperand* obj, LOperand* val) {
- inputs_[0] = obj;
- inputs_[1] = val;
+ LStoreNamedGeneric(LOperand* object, LOperand* value) {
+ inputs_[0] = object;
+ inputs_[1] = value;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* value() { return inputs_[1]; }
Handle<Object> name() const { return hydrogen()->name(); }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1730,21 +1924,22 @@ class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
public:
- LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val) {
- inputs_[0] = obj;
+ LStoreKeyedFastElement(LOperand* object, LOperand* key, LOperand* value) {
+ inputs_[0] = object;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
"store-keyed-fast-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1753,21 +1948,22 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
public:
LStoreKeyedFastDoubleElement(LOperand* elements,
LOperand* key,
- LOperand* val) {
+ LOperand* value) {
inputs_[0] = elements;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* elements() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement,
"store-keyed-fast-double-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastDoubleElement)
virtual void PrintDataTo(StringStream* stream);
- LOperand* elements() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
@@ -1776,20 +1972,21 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> {
public:
- LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val) {
+ LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* value) {
inputs_[0] = obj;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1797,22 +1994,21 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
public:
LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
LOperand* key,
- LOperand* val) {
+ LOperand* value) {
inputs_[0] = external_pointer;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* external_pointer() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
"store-keyed-specialized-array-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
- LOperand* external_pointer() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
- ElementsKind elements_kind() const {
- return hydrogen()->elements_kind();
- }
+ ElementsKind elements_kind() const { return hydrogen()->elements_kind(); }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1821,21 +2017,22 @@ class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> {
public:
LTransitionElementsKind(LOperand* object,
LOperand* new_map_temp,
- LOperand* temp_reg) {
+ LOperand* temp) {
inputs_[0] = object;
temps_[0] = new_map_temp;
- temps_[1] = temp_reg;
+ temps_[1] = temp;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* new_map_temp() { return temps_[0]; }
+ LOperand* temp() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
"transition-elements-kind")
DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* new_map_reg() { return temps_[0]; }
- LOperand* temp_reg() { return temps_[1]; }
Handle<Map> original_map() { return hydrogen()->original_map(); }
Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); }
};
@@ -1848,11 +2045,11 @@ class LStringAdd: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
- DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
- DECLARE_HYDROGEN_ACCESSOR(StringAdd)
-
LOperand* left() { return inputs_[0]; }
LOperand* right() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
+ DECLARE_HYDROGEN_ACCESSOR(StringAdd)
};
@@ -1864,11 +2061,11 @@ class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = index;
}
- DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
- DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
-
LOperand* string() { return inputs_[0]; }
LOperand* index() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
+ DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
};
@@ -1878,10 +2075,10 @@ class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = char_code;
}
+ LOperand* char_code() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
-
- LOperand* char_code() { return inputs_[0]; }
};
@@ -1891,10 +2088,10 @@ class LStringLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = string;
}
+ LOperand* string() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
DECLARE_HYDROGEN_ACCESSOR(StringLength)
-
- LOperand* string() { return inputs_[0]; }
};
@@ -1904,7 +2101,7 @@ class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
- LOperand* value() { return InputAt(0); }
+ LOperand* value() { return inputs_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
@@ -1917,6 +2114,8 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
};
@@ -1928,6 +2127,8 @@ class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
};
@@ -1935,11 +2136,14 @@ class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 2> {
public:
- LCheckPrototypeMaps(LOperand* temp1, LOperand* temp2) {
- temps_[0] = temp1;
+ LCheckPrototypeMaps(LOperand* temp, LOperand* temp2) {
+ temps_[0] = temp;
temps_[1] = temp2;
}
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
@@ -1954,6 +2158,8 @@ class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
};
@@ -1964,18 +2170,21 @@ class LCheckNonSmi: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
};
class LClampDToUint8: public LTemplateInstruction<1, 1, 1> {
public:
- LClampDToUint8(LOperand* value, LOperand* temp) {
- inputs_[0] = value;
+ LClampDToUint8(LOperand* unclamped, LOperand* temp) {
+ inputs_[0] = unclamped;
temps_[0] = temp;
}
LOperand* unclamped() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
};
@@ -1983,8 +2192,8 @@ class LClampDToUint8: public LTemplateInstruction<1, 1, 1> {
class LClampIToUint8: public LTemplateInstruction<1, 1, 0> {
public:
- explicit LClampIToUint8(LOperand* value) {
- inputs_[0] = value;
+ explicit LClampIToUint8(LOperand* unclamped) {
+ inputs_[0] = unclamped;
}
LOperand* unclamped() { return inputs_[0]; }
@@ -1995,12 +2204,13 @@ class LClampIToUint8: public LTemplateInstruction<1, 1, 0> {
class LClampTToUint8: public LTemplateInstruction<1, 1, 1> {
public:
- LClampTToUint8(LOperand* value, LOperand* temp) {
- inputs_[0] = value;
+ LClampTToUint8(LOperand* unclamped, LOperand* temp) {
+ inputs_[0] = unclamped;
temps_[0] = temp;
}
LOperand* unclamped() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
};
@@ -2008,11 +2218,14 @@ class LClampTToUint8: public LTemplateInstruction<1, 1, 1> {
class LAllocateObject: public LTemplateInstruction<1, 0, 2> {
public:
- LAllocateObject(LOperand* temp1, LOperand* temp2) {
- temps_[0] = temp1;
+ LAllocateObject(LOperand* temp, LOperand* temp2) {
+ temps_[0] = temp;
temps_[1] = temp2;
}
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object")
DECLARE_HYDROGEN_ACCESSOR(AllocateObject)
};
@@ -2061,6 +2274,8 @@ class LToFastProperties: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
};
@@ -2072,6 +2287,8 @@ class LTypeof: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
};
@@ -2082,6 +2299,8 @@ class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
@@ -2097,6 +2316,8 @@ class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
temps_[0] = temp;
}
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
"is-construct-call-and-branch")
};
@@ -2104,15 +2325,15 @@ class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
class LDeleteProperty: public LTemplateInstruction<1, 2, 0> {
public:
- LDeleteProperty(LOperand* obj, LOperand* key) {
- inputs_[0] = obj;
+ LDeleteProperty(LOperand* object, LOperand* key) {
+ inputs_[0] = object;
inputs_[1] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
-
LOperand* object() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
};
@@ -2222,65 +2443,13 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> {
class LChunkBuilder;
-class LChunk: public ZoneObject {
+class LPlatformChunk: public LChunk {
public:
- explicit LChunk(CompilationInfo* info, HGraph* graph);
-
- void AddInstruction(LInstruction* instruction, HBasicBlock* block);
- LConstantOperand* DefineConstantOperand(HConstant* constant);
- Handle<Object> LookupLiteral(LConstantOperand* operand) const;
- Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
+ LPlatformChunk(CompilationInfo* info, HGraph* graph)
+ : LChunk(info, graph) { }
int GetNextSpillIndex(bool is_double);
LOperand* GetNextSpillSlot(bool is_double);
-
- int ParameterAt(int index);
- int GetParameterStackSlot(int index) const;
- int spill_slot_count() const { return spill_slot_count_; }
- CompilationInfo* info() const { return info_; }
- HGraph* graph() const { return graph_; }
- const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
- void AddGapMove(int index, LOperand* from, LOperand* to);
- LGap* GetGapAt(int index) const;
- bool IsGapAt(int index) const;
- int NearestGapPos(int index) const;
- void MarkEmptyBlocks();
- const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
- LLabel* GetLabel(int block_id) const {
- HBasicBlock* block = graph_->blocks()->at(block_id);
- int first_instruction = block->first_instruction_index();
- return LLabel::cast(instructions_[first_instruction]);
- }
- int LookupDestination(int block_id) const {
- LLabel* cur = GetLabel(block_id);
- while (cur->replacement() != NULL) {
- cur = cur->replacement();
- }
- return cur->block_id();
- }
- Label* GetAssemblyLabel(int block_id) const {
- LLabel* label = GetLabel(block_id);
- ASSERT(!label->HasReplacement());
- return label->label();
- }
-
- const ZoneList<Handle<JSFunction> >* inlined_closures() const {
- return &inlined_closures_;
- }
-
- void AddInlinedClosure(Handle<JSFunction> closure) {
- inlined_closures_.Add(closure, zone());
- }
-
- Zone* zone() const { return graph_->zone(); }
-
- private:
- int spill_slot_count_;
- CompilationInfo* info_;
- HGraph* const graph_;
- ZoneList<LInstruction*> instructions_;
- ZoneList<LPointerMap*> pointer_maps_;
- ZoneList<Handle<JSFunction> > inlined_closures_;
};
@@ -2299,10 +2468,10 @@ class LChunkBuilder BASE_EMBEDDED {
allocator_(allocator),
position_(RelocInfo::kNoPosition),
instruction_pending_deoptimization_environment_(NULL),
- pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
+ pending_deoptimization_ast_id_(BailoutId::None()) { }
// Build the sequence for the graph.
- LChunk* Build();
+ LPlatformChunk* Build();
// Declare methods that deal with the individual node types.
#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
@@ -2321,7 +2490,7 @@ class LChunkBuilder BASE_EMBEDDED {
ABORTED
};
- LChunk* chunk() const { return chunk_; }
+ LPlatformChunk* chunk() const { return chunk_; }
CompilationInfo* info() const { return info_; }
HGraph* graph() const { return graph_; }
Zone* zone() const { return zone_; }
@@ -2331,7 +2500,7 @@ class LChunkBuilder BASE_EMBEDDED {
bool is_done() const { return status_ == DONE; }
bool is_aborted() const { return status_ == ABORTED; }
- void Abort(const char* format, ...);
+ void Abort(const char* reason);
// Methods for getting operands for Use / Define / Temp.
LUnallocated* ToUnallocated(Register reg);
@@ -2421,7 +2590,7 @@ class LChunkBuilder BASE_EMBEDDED {
LInstruction* DoArithmeticT(Token::Value op,
HArithmeticBinaryOperation* instr);
- LChunk* chunk_;
+ LPlatformChunk* chunk_;
CompilationInfo* info_;
HGraph* const graph_;
Zone* zone_;
@@ -2433,7 +2602,7 @@ class LChunkBuilder BASE_EMBEDDED {
LAllocator* allocator_;
int position_;
LInstruction* instruction_pending_deoptimization_environment_;
- int pending_deoptimization_ast_id_;
+ BailoutId pending_deoptimization_ast_id_;
DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
};
diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc
index e14230d82..6f5aa436a 100644
--- a/deps/v8/src/arm/lithium-codegen-arm.cc
+++ b/deps/v8/src/arm/lithium-codegen-arm.cc
@@ -91,17 +91,8 @@ void LCodeGen::FinishCode(Handle<Code> code) {
}
-void LCodeGen::Abort(const char* format, ...) {
- if (FLAG_trace_bailout) {
- SmartArrayPointer<char> name(
- info()->shared_info()->DebugName()->ToCString());
- PrintF("Aborting LCodeGen in @\"%s\": ", *name);
- va_list arguments;
- va_start(arguments, format);
- OS::VPrint(format, arguments);
- va_end(arguments);
- PrintF("\n");
- }
+void LCodeGen::Abort(const char* reason) {
+ info()->set_bailout_reason(reason);
status_ = ABORTED;
}
@@ -127,6 +118,8 @@ void LCodeGen::Comment(const char* format, ...) {
bool LCodeGen::GeneratePrologue() {
ASSERT(is_generating());
+ ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+
#ifdef DEBUG
if (strlen(FLAG_stop_at) > 0 &&
info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
@@ -322,7 +315,8 @@ Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
return ToRegister(op->index());
} else if (op->IsConstantOperand()) {
LConstantOperand* const_op = LConstantOperand::cast(op);
- Handle<Object> literal = chunk_->LookupLiteral(const_op);
+ HConstant* constant = chunk_->LookupConstant(const_op);
+ Handle<Object> literal = constant->handle();
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
ASSERT(literal->IsNumber());
@@ -360,7 +354,8 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
return ToDoubleRegister(op->index());
} else if (op->IsConstantOperand()) {
LConstantOperand* const_op = LConstantOperand::cast(op);
- Handle<Object> literal = chunk_->LookupLiteral(const_op);
+ HConstant* constant = chunk_->LookupConstant(const_op);
+ Handle<Object> literal = constant->handle();
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
ASSERT(literal->IsNumber());
@@ -386,9 +381,9 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
- Handle<Object> literal = chunk_->LookupLiteral(op);
+ HConstant* constant = chunk_->LookupConstant(op);
ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
- return literal;
+ return constant->handle();
}
@@ -398,33 +393,33 @@ bool LCodeGen::IsInteger32(LConstantOperand* op) const {
int LCodeGen::ToInteger32(LConstantOperand* op) const {
- Handle<Object> value = chunk_->LookupLiteral(op);
+ HConstant* constant = chunk_->LookupConstant(op);
ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32());
- ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) ==
- value->Number());
- return static_cast<int32_t>(value->Number());
+ ASSERT(constant->HasInteger32Value());
+ return constant->Integer32Value();
}
double LCodeGen::ToDouble(LConstantOperand* op) const {
- Handle<Object> value = chunk_->LookupLiteral(op);
- return value->Number();
+ HConstant* constant = chunk_->LookupConstant(op);
+ ASSERT(constant->HasDoubleValue());
+ return constant->DoubleValue();
}
Operand LCodeGen::ToOperand(LOperand* op) {
if (op->IsConstantOperand()) {
LConstantOperand* const_op = LConstantOperand::cast(op);
- Handle<Object> literal = chunk_->LookupLiteral(const_op);
+ HConstant* constant = chunk()->LookupConstant(const_op);
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
- ASSERT(literal->IsNumber());
- return Operand(static_cast<int32_t>(literal->Number()));
+ ASSERT(constant->HasInteger32Value());
+ return Operand(constant->Integer32Value());
} else if (r.IsDouble()) {
Abort("ToOperand Unsupported double immediate.");
}
ASSERT(r.IsTagged());
- return Operand(literal);
+ return Operand(constant->handle());
} else if (op->IsRegister()) {
return Operand(ToRegister(op));
} else if (op->IsDoubleRegister()) {
@@ -469,7 +464,9 @@ MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const {
void LCodeGen::WriteTranslation(LEnvironment* environment,
- Translation* translation) {
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count) {
if (environment == NULL) return;
// The translation includes one command per value in the environment.
@@ -477,8 +474,21 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
// The output frame height does not include the parameters.
int height = translation_size - environment->parameter_count();
- WriteTranslation(environment->outer(), translation);
- int closure_id = DefineDeoptimizationLiteral(environment->closure());
+ // Function parameters are arguments to the outermost environment. The
+ // arguments index points to the first element of a sequence of tagged
+ // values on the stack that represent the arguments. This needs to be
+ // kept in sync with the LArgumentsElements implementation.
+ *arguments_index = -environment->parameter_count();
+ *arguments_count = environment->parameter_count();
+
+ WriteTranslation(environment->outer(),
+ translation,
+ arguments_index,
+ arguments_count);
+ int closure_id = *info()->closure() != *environment->closure()
+ ? DefineDeoptimizationLiteral(environment->closure())
+ : Translation::kSelfLiteralId;
+
switch (environment->frame_type()) {
case JS_FUNCTION:
translation->BeginJSFrame(environment->ast_id(), closure_id, height);
@@ -486,12 +496,31 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
case JS_CONSTRUCT:
translation->BeginConstructStubFrame(closure_id, translation_size);
break;
+ case JS_GETTER:
+ ASSERT(translation_size == 1);
+ ASSERT(height == 0);
+ translation->BeginGetterStubFrame(closure_id);
+ break;
+ case JS_SETTER:
+ ASSERT(translation_size == 2);
+ ASSERT(height == 0);
+ translation->BeginSetterStubFrame(closure_id);
+ break;
case ARGUMENTS_ADAPTOR:
translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
break;
- default:
- UNREACHABLE();
}
+
+ // Inlined frames which push their arguments cause the index to be
+ // bumped and a new stack area to be used for materialization.
+ if (environment->entry() != NULL &&
+ environment->entry()->arguments_pushed()) {
+ *arguments_index = *arguments_index < 0
+ ? GetStackSlotCount()
+ : *arguments_index + *arguments_count;
+ *arguments_count = environment->entry()->arguments_count() + 1;
+ }
+
for (int i = 0; i < translation_size; ++i) {
LOperand* value = environment->values()->at(i);
// spilled_registers_ and spilled_double_registers_ are either
@@ -502,7 +531,10 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
translation->MarkDuplicate();
AddToTranslation(translation,
environment->spilled_registers()[value->index()],
- environment->HasTaggedValueAt(i));
+ environment->HasTaggedValueAt(i),
+ environment->HasUint32ValueAt(i),
+ *arguments_index,
+ *arguments_count);
} else if (
value->IsDoubleRegister() &&
environment->spilled_double_registers()[value->index()] != NULL) {
@@ -510,26 +542,39 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
AddToTranslation(
translation,
environment->spilled_double_registers()[value->index()],
- false);
+ false,
+ false,
+ *arguments_index,
+ *arguments_count);
}
}
- AddToTranslation(translation, value, environment->HasTaggedValueAt(i));
+ AddToTranslation(translation,
+ value,
+ environment->HasTaggedValueAt(i),
+ environment->HasUint32ValueAt(i),
+ *arguments_index,
+ *arguments_count);
}
}
void LCodeGen::AddToTranslation(Translation* translation,
LOperand* op,
- bool is_tagged) {
+ bool is_tagged,
+ bool is_uint32,
+ int arguments_index,
+ int arguments_count) {
if (op == NULL) {
// TODO(twuerthinger): Introduce marker operands to indicate that this value
// is not present and must be reconstructed from the deoptimizer. Currently
// this is only used for the arguments object.
- translation->StoreArgumentsObject();
+ translation->StoreArgumentsObject(arguments_index, arguments_count);
} else if (op->IsStackSlot()) {
if (is_tagged) {
translation->StoreStackSlot(op->index());
+ } else if (is_uint32) {
+ translation->StoreUint32StackSlot(op->index());
} else {
translation->StoreInt32StackSlot(op->index());
}
@@ -543,6 +588,8 @@ void LCodeGen::AddToTranslation(Translation* translation,
Register reg = ToRegister(op);
if (is_tagged) {
translation->StoreRegister(reg);
+ } else if (is_uint32) {
+ translation->StoreUint32Register(reg);
} else {
translation->StoreInt32Register(reg);
}
@@ -550,8 +597,8 @@ void LCodeGen::AddToTranslation(Translation* translation,
DoubleRegister reg = ToDoubleRegister(op);
translation->StoreDoubleRegister(reg);
} else if (op->IsConstantOperand()) {
- Handle<Object> literal = chunk()->LookupLiteral(LConstantOperand::cast(op));
- int src_index = DefineDeoptimizationLiteral(literal);
+ HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
+ int src_index = DefineDeoptimizationLiteral(constant->handle());
translation->StoreLiteral(src_index);
} else {
UNREACHABLE();
@@ -561,22 +608,24 @@ void LCodeGen::AddToTranslation(Translation* translation,
void LCodeGen::CallCode(Handle<Code> code,
RelocInfo::Mode mode,
- LInstruction* instr) {
- CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
+ LInstruction* instr,
+ TargetAddressStorageMode storage_mode) {
+ CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, storage_mode);
}
void LCodeGen::CallCodeGeneric(Handle<Code> code,
RelocInfo::Mode mode,
LInstruction* instr,
- SafepointMode safepoint_mode) {
+ SafepointMode safepoint_mode,
+ TargetAddressStorageMode storage_mode) {
ASSERT(instr != NULL);
// Block literal pool emission to ensure nop indicating no inlined smi code
// is in the correct position.
Assembler::BlockConstPoolScope block_const_pool(masm());
LPointerMap* pointers = instr->pointer_map();
RecordPosition(pointers->position());
- __ Call(code, mode);
+ __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode);
RecordSafepointWithLazyDeopt(instr, safepoint_mode);
// Signal that we don't inline smi code before these stubs in the
@@ -628,15 +677,16 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
int frame_count = 0;
int jsframe_count = 0;
+ int args_index = 0;
+ int args_count = 0;
for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
++frame_count;
if (e->frame_type() == JS_FUNCTION) {
++jsframe_count;
}
}
- Translation translation(&translations_, frame_count, jsframe_count,
- zone());
- WriteTranslation(environment, &translation);
+ Translation translation(&translations_, frame_count, jsframe_count, zone());
+ WriteTranslation(environment, &translation, &args_index, &args_count);
int deoptimization_index = deoptimizations_.length();
int pc_offset = masm()->pc_offset();
environment->Register(deoptimization_index,
@@ -698,13 +748,13 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
}
data->SetLiteralArray(*literals);
- data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id()));
+ data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt()));
data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
// Populate the deoptimization entries.
for (int i = 0; i < length; i++) {
LEnvironment* env = deoptimizations_[i];
- data->SetAstId(i, Smi::FromInt(env->ast_id()));
+ data->SetAstId(i, env->ast_id());
data->SetTranslationIndex(i, Smi::FromInt(env->translation_index()));
data->SetArgumentsStackHeight(i,
Smi::FromInt(env->arguments_stack_height()));
@@ -903,7 +953,7 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
void LCodeGen::DoModI(LModI* instr) {
if (instr->hydrogen()->HasPowerOf2Divisor()) {
- Register dividend = ToRegister(instr->InputAt(0));
+ Register dividend = ToRegister(instr->left());
Register result = ToRegister(instr->result());
int32_t divisor =
@@ -928,112 +978,135 @@ void LCodeGen::DoModI(LModI* instr) {
}
// These registers hold untagged 32 bit values.
- Register left = ToRegister(instr->InputAt(0));
- Register right = ToRegister(instr->InputAt(1));
+ Register left = ToRegister(instr->left());
+ Register right = ToRegister(instr->right());
Register result = ToRegister(instr->result());
+ Label done;
- Register scratch = scratch0();
- Register scratch2 = ToRegister(instr->TempAt(0));
- DwVfpRegister dividend = ToDoubleRegister(instr->TempAt(1));
- DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2));
- DwVfpRegister quotient = double_scratch0();
-
- ASSERT(!dividend.is(divisor));
- ASSERT(!dividend.is(quotient));
- ASSERT(!divisor.is(quotient));
- ASSERT(!scratch.is(left));
- ASSERT(!scratch.is(right));
- ASSERT(!scratch.is(result));
+ if (CpuFeatures::IsSupported(SUDIV)) {
+ CpuFeatures::Scope scope(SUDIV);
+ // Check for x % 0.
+ if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
+ __ cmp(right, Operand(0));
+ DeoptimizeIf(eq, instr->environment());
+ }
- Label done, vfp_modulo, both_positive, right_negative;
+ // For r3 = r1 % r2; we can have the following ARM code
+ // sdiv r3, r1, r2
+ // mls r3, r3, r2, r1
- // Check for x % 0.
- if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
- __ cmp(right, Operand(0));
- DeoptimizeIf(eq, instr->environment());
- }
+ __ sdiv(result, left, right);
+ __ mls(result, result, right, left);
+ __ cmp(result, Operand(0));
+ __ b(ne, &done);
- __ Move(result, left);
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ __ cmp(left, Operand(0));
+ DeoptimizeIf(lt, instr->environment());
+ }
+ } else {
+ Register scratch = scratch0();
+ Register scratch2 = ToRegister(instr->temp());
+ DwVfpRegister dividend = ToDoubleRegister(instr->temp2());
+ DwVfpRegister divisor = ToDoubleRegister(instr->temp3());
+ DwVfpRegister quotient = double_scratch0();
+
+ ASSERT(!dividend.is(divisor));
+ ASSERT(!dividend.is(quotient));
+ ASSERT(!divisor.is(quotient));
+ ASSERT(!scratch.is(left));
+ ASSERT(!scratch.is(right));
+ ASSERT(!scratch.is(result));
+
+ Label vfp_modulo, both_positive, right_negative;
+
+ // Check for x % 0.
+ if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
+ __ cmp(right, Operand(0));
+ DeoptimizeIf(eq, instr->environment());
+ }
- // (0 % x) must yield 0 (if x is finite, which is the case here).
- __ cmp(left, Operand(0));
- __ b(eq, &done);
- // Preload right in a vfp register.
- __ vmov(divisor.low(), right);
- __ b(lt, &vfp_modulo);
+ __ Move(result, left);
- __ cmp(left, Operand(right));
- __ b(lt, &done);
-
- // Check for (positive) power of two on the right hand side.
- __ JumpIfNotPowerOfTwoOrZeroAndNeg(right,
- scratch,
- &right_negative,
- &both_positive);
- // Perform modulo operation (scratch contains right - 1).
- __ and_(result, scratch, Operand(left));
- __ b(&done);
+ // (0 % x) must yield 0 (if x is finite, which is the case here).
+ __ cmp(left, Operand(0));
+ __ b(eq, &done);
+ // Preload right in a vfp register.
+ __ vmov(divisor.low(), right);
+ __ b(lt, &vfp_modulo);
- __ bind(&right_negative);
- // Negate right. The sign of the divisor does not matter.
- __ rsb(right, right, Operand(0));
-
- __ bind(&both_positive);
- const int kUnfolds = 3;
- // If the right hand side is smaller than the (nonnegative)
- // left hand side, the left hand side is the result.
- // Else try a few subtractions of the left hand side.
- __ mov(scratch, left);
- for (int i = 0; i < kUnfolds; i++) {
- // Check if the left hand side is less or equal than the
- // the right hand side.
- __ cmp(scratch, Operand(right));
- __ mov(result, scratch, LeaveCC, lt);
+ __ cmp(left, Operand(right));
__ b(lt, &done);
- // If not, reduce the left hand side by the right hand
- // side and check again.
- if (i < kUnfolds - 1) __ sub(scratch, scratch, right);
- }
-
- __ bind(&vfp_modulo);
- // Load the arguments in VFP registers.
- // The divisor value is preloaded before. Be careful that 'right' is only live
- // on entry.
- __ vmov(dividend.low(), left);
- // From here on don't use right as it may have been reallocated (for example
- // to scratch2).
- right = no_reg;
-
- __ vcvt_f64_s32(dividend, dividend.low());
- __ vcvt_f64_s32(divisor, divisor.low());
-
- // We do not care about the sign of the divisor.
- __ vabs(divisor, divisor);
- // Compute the quotient and round it to a 32bit integer.
- __ vdiv(quotient, dividend, divisor);
- __ vcvt_s32_f64(quotient.low(), quotient);
- __ vcvt_f64_s32(quotient, quotient.low());
-
- // Compute the remainder in result.
- DwVfpRegister double_scratch = dividend;
- __ vmul(double_scratch, divisor, quotient);
- __ vcvt_s32_f64(double_scratch.low(), double_scratch);
- __ vmov(scratch, double_scratch.low());
-
- if (!instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- __ sub(result, left, scratch);
- } else {
- Label ok;
- // Check for -0.
- __ sub(scratch2, left, scratch, SetCC);
- __ b(ne, &ok);
- __ cmp(left, Operand(0));
- DeoptimizeIf(mi, instr->environment());
- __ bind(&ok);
- // Load the result and we are done.
- __ mov(result, scratch2);
- }
+ // Check for (positive) power of two on the right hand side.
+ __ JumpIfNotPowerOfTwoOrZeroAndNeg(right,
+ scratch,
+ &right_negative,
+ &both_positive);
+ // Perform modulo operation (scratch contains right - 1).
+ __ and_(result, scratch, Operand(left));
+ __ b(&done);
+
+ __ bind(&right_negative);
+ // Negate right. The sign of the divisor does not matter.
+ __ rsb(right, right, Operand(0));
+
+ __ bind(&both_positive);
+ const int kUnfolds = 3;
+ // If the right hand side is smaller than the (nonnegative)
+ // left hand side, the left hand side is the result.
+ // Else try a few subtractions of the left hand side.
+ __ mov(scratch, left);
+ for (int i = 0; i < kUnfolds; i++) {
+ // Check if the left hand side is less or equal than the
+ // the right hand side.
+ __ cmp(scratch, Operand(right));
+ __ mov(result, scratch, LeaveCC, lt);
+ __ b(lt, &done);
+ // If not, reduce the left hand side by the right hand
+ // side and check again.
+ if (i < kUnfolds - 1) __ sub(scratch, scratch, right);
+ }
+
+ __ bind(&vfp_modulo);
+ // Load the arguments in VFP registers.
+ // The divisor value is preloaded before. Be careful that 'right'
+ // is only live on entry.
+ __ vmov(dividend.low(), left);
+ // From here on don't use right as it may have been reallocated
+ // (for example to scratch2).
+ right = no_reg;
+
+ __ vcvt_f64_s32(dividend, dividend.low());
+ __ vcvt_f64_s32(divisor, divisor.low());
+
+ // We do not care about the sign of the divisor.
+ __ vabs(divisor, divisor);
+ // Compute the quotient and round it to a 32bit integer.
+ __ vdiv(quotient, dividend, divisor);
+ __ vcvt_s32_f64(quotient.low(), quotient);
+ __ vcvt_f64_s32(quotient, quotient.low());
+
+ // Compute the remainder in result.
+ DwVfpRegister double_scratch = dividend;
+ __ vmul(double_scratch, divisor, quotient);
+ __ vcvt_s32_f64(double_scratch.low(), double_scratch);
+ __ vmov(scratch, double_scratch.low());
+
+ if (!instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ __ sub(result, left, scratch);
+ } else {
+ Label ok;
+ // Check for -0.
+ __ sub(scratch2, left, scratch, SetCC);
+ __ b(ne, &ok);
+ __ cmp(left, Operand(0));
+ DeoptimizeIf(mi, instr->environment());
+ __ bind(&ok);
+ // Load the result and we are done.
+ __ mov(result, scratch2);
+ }
+ }
__ bind(&done);
}
@@ -1138,15 +1211,18 @@ void LCodeGen::DoDivI(LDivI* instr) {
DeferredDivI(LCodeGen* codegen, LDivI* instr)
: LDeferredCode(codegen), instr_(instr) { }
virtual void Generate() {
- codegen()->DoDeferredBinaryOpStub(instr_, Token::DIV);
+ codegen()->DoDeferredBinaryOpStub(instr_->pointer_map(),
+ instr_->left(),
+ instr_->right(),
+ Token::DIV);
}
virtual LInstruction* instr() { return instr_; }
private:
LDivI* instr_;
};
- const Register left = ToRegister(instr->InputAt(0));
- const Register right = ToRegister(instr->InputAt(1));
+ const Register left = ToRegister(instr->left());
+ const Register right = ToRegister(instr->right());
const Register scratch = scratch0();
const Register result = ToRegister(instr->result());
@@ -1215,15 +1291,15 @@ void LCodeGen::DoDivI(LDivI* instr) {
void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
const Register result = ToRegister(instr->result());
- const Register left = ToRegister(instr->InputAt(0));
- const Register remainder = ToRegister(instr->TempAt(0));
+ const Register left = ToRegister(instr->left());
+ const Register remainder = ToRegister(instr->temp());
const Register scratch = scratch0();
// We only optimize this for division by constants, because the standard
// integer division routine is usually slower than transitionning to VFP.
// This could be optimized on processors with SDIV available.
- ASSERT(instr->InputAt(1)->IsConstantOperand());
- int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1)));
+ ASSERT(instr->right()->IsConstantOperand());
+ int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
if (divisor < 0) {
__ cmp(left, Operand(0));
DeoptimizeIf(eq, instr->environment());
@@ -1241,11 +1317,12 @@ void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
}
-template<int T>
-void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
+void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map,
+ LOperand* left_argument,
+ LOperand* right_argument,
Token::Value op) {
- Register left = ToRegister(instr->InputAt(0));
- Register right = ToRegister(instr->InputAt(1));
+ Register left = ToRegister(left_argument);
+ Register right = ToRegister(right_argument);
PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles);
// Move left to r1 and right to r0 for the stub call.
@@ -1264,7 +1341,7 @@ void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
}
BinaryOpStub stub(op, OVERWRITE_LEFT);
__ CallStub(&stub);
- RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
+ RecordSafepointWithRegistersAndDoubles(pointer_map,
0,
Safepoint::kNoLazyDeopt);
// Overwrite the stored value of r0 with the result of the stub.
@@ -1276,8 +1353,8 @@ void LCodeGen::DoMulI(LMulI* instr) {
Register scratch = scratch0();
Register result = ToRegister(instr->result());
// Note that result may alias left.
- Register left = ToRegister(instr->InputAt(0));
- LOperand* right_op = instr->InputAt(1);
+ Register left = ToRegister(instr->left());
+ LOperand* right_op = instr->right();
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
bool bailout_on_minus_zero =
@@ -1344,7 +1421,7 @@ void LCodeGen::DoMulI(LMulI* instr) {
} else {
Register right = EmitLoadRegister(right_op, scratch);
if (bailout_on_minus_zero) {
- __ orr(ToRegister(instr->TempAt(0)), left, right);
+ __ orr(ToRegister(instr->temp()), left, right);
}
if (can_overflow) {
@@ -1361,7 +1438,7 @@ void LCodeGen::DoMulI(LMulI* instr) {
Label done;
__ cmp(result, Operand(0));
__ b(ne, &done);
- __ cmp(ToRegister(instr->TempAt(0)), Operand(0));
+ __ cmp(ToRegister(instr->temp()), Operand(0));
DeoptimizeIf(mi, instr->environment());
__ bind(&done);
}
@@ -1370,8 +1447,8 @@ void LCodeGen::DoMulI(LMulI* instr) {
void LCodeGen::DoBitI(LBitI* instr) {
- LOperand* left_op = instr->InputAt(0);
- LOperand* right_op = instr->InputAt(1);
+ LOperand* left_op = instr->left();
+ LOperand* right_op = instr->right();
ASSERT(left_op->IsRegister());
Register left = ToRegister(left_op);
Register result = ToRegister(instr->result());
@@ -1404,8 +1481,8 @@ void LCodeGen::DoBitI(LBitI* instr) {
void LCodeGen::DoShiftI(LShiftI* instr) {
// Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so
// result may alias either of them.
- LOperand* right_op = instr->InputAt(1);
- Register left = ToRegister(instr->InputAt(0));
+ LOperand* right_op = instr->right();
+ Register left = ToRegister(instr->left());
Register result = ToRegister(instr->result());
Register scratch = scratch0();
if (right_op->IsRegister()) {
@@ -1469,8 +1546,8 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
void LCodeGen::DoSubI(LSubI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
LOperand* result = instr->result();
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
SBit set_cond = can_overflow ? SetCC : LeaveCC;
@@ -1499,7 +1576,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
ASSERT(instr->result()->IsDoubleRegister());
DwVfpRegister result = ToDoubleRegister(instr->result());
double v = instr->value();
- __ Vmov(result, v);
+ __ Vmov(result, v, scratch0());
}
@@ -1516,21 +1593,28 @@ void LCodeGen::DoConstantT(LConstantT* instr) {
void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
+ Register array = ToRegister(instr->value());
__ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
}
void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
+ Register array = ToRegister(instr->value());
__ ldr(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset));
}
+void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
+ Register result = ToRegister(instr->result());
+ Register map = ToRegister(instr->value());
+ __ EnumLength(result, map);
+}
+
+
void LCodeGen::DoElementsKind(LElementsKind* instr) {
Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
// Load map into |result|.
__ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset));
@@ -1543,9 +1627,9 @@ void LCodeGen::DoElementsKind(LElementsKind* instr) {
void LCodeGen::DoValueOf(LValueOf* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
- Register map = ToRegister(instr->TempAt(0));
+ Register map = ToRegister(instr->temp());
Label done;
// If the object is a smi return the object.
@@ -1564,9 +1648,9 @@ void LCodeGen::DoValueOf(LValueOf* instr) {
void LCodeGen::DoDateField(LDateField* instr) {
- Register object = ToRegister(instr->InputAt(0));
+ Register object = ToRegister(instr->date());
Register result = ToRegister(instr->result());
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
Smi* index = instr->index();
Label runtime, done;
ASSERT(object.is(result));
@@ -1574,11 +1658,10 @@ void LCodeGen::DoDateField(LDateField* instr) {
ASSERT(!scratch.is(scratch0()));
ASSERT(!scratch.is(object));
-#ifdef DEBUG
- __ AbortIfSmi(object);
+ __ tst(object, Operand(kSmiTagMask));
+ DeoptimizeIf(eq, instr->environment());
__ CompareObjectType(object, scratch, scratch, JS_DATE_TYPE);
- __ Assert(eq, "Trying to get date field from non-date.");
-#endif
+ DeoptimizeIf(ne, instr->environment());
if (index->value() == 0) {
__ ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
@@ -1604,14 +1687,14 @@ void LCodeGen::DoDateField(LDateField* instr) {
void LCodeGen::DoBitNotI(LBitNotI* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
__ mvn(result, Operand(input));
}
void LCodeGen::DoThrow(LThrow* instr) {
- Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
+ Register input_reg = EmitLoadRegister(instr->value(), ip);
__ push(input_reg);
CallRuntime(Runtime::kThrow, 1, instr);
@@ -1622,8 +1705,8 @@ void LCodeGen::DoThrow(LThrow* instr) {
void LCodeGen::DoAddI(LAddI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
LOperand* result = instr->result();
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
SBit set_cond = can_overflow ? SetCC : LeaveCC;
@@ -1642,9 +1725,71 @@ void LCodeGen::DoAddI(LAddI* instr) {
}
+void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
+ HMathMinMax::Operation operation = instr->hydrogen()->operation();
+ Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
+ if (instr->hydrogen()->representation().IsInteger32()) {
+ Register left_reg = ToRegister(left);
+ Operand right_op = (right->IsRegister() || right->IsConstantOperand())
+ ? ToOperand(right)
+ : Operand(EmitLoadRegister(right, ip));
+ Register result_reg = ToRegister(instr->result());
+ __ cmp(left_reg, right_op);
+ if (!result_reg.is(left_reg)) {
+ __ mov(result_reg, left_reg, LeaveCC, condition);
+ }
+ __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition));
+ } else {
+ ASSERT(instr->hydrogen()->representation().IsDouble());
+ DoubleRegister left_reg = ToDoubleRegister(left);
+ DoubleRegister right_reg = ToDoubleRegister(right);
+ DoubleRegister result_reg = ToDoubleRegister(instr->result());
+ Label check_nan_left, check_zero, return_left, return_right, done;
+ __ VFPCompareAndSetFlags(left_reg, right_reg);
+ __ b(vs, &check_nan_left);
+ __ b(eq, &check_zero);
+ __ b(condition, &return_left);
+ __ b(al, &return_right);
+
+ __ bind(&check_zero);
+ __ VFPCompareAndSetFlags(left_reg, 0.0);
+ __ b(ne, &return_left); // left == right != 0.
+ // At this point, both left and right are either 0 or -0.
+ if (operation == HMathMinMax::kMathMin) {
+ // We could use a single 'vorr' instruction here if we had NEON support.
+ __ vneg(left_reg, left_reg);
+ __ vsub(result_reg, left_reg, right_reg);
+ __ vneg(result_reg, result_reg);
+ } else {
+ // Since we operate on +0 and/or -0, vadd and vand have the same effect;
+ // the decision for vadd is easy because vand is a NEON instruction.
+ __ vadd(result_reg, left_reg, right_reg);
+ }
+ __ b(al, &done);
+
+ __ bind(&check_nan_left);
+ __ VFPCompareAndSetFlags(left_reg, left_reg);
+ __ b(vs, &return_left); // left == NaN.
+ __ bind(&return_right);
+ if (!right_reg.is(result_reg)) {
+ __ vmov(result_reg, right_reg);
+ }
+ __ b(al, &done);
+
+ __ bind(&return_left);
+ if (!left_reg.is(result_reg)) {
+ __ vmov(result_reg, left_reg);
+ }
+ __ bind(&done);
+ }
+}
+
+
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
- DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
- DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
+ DoubleRegister left = ToDoubleRegister(instr->left());
+ DoubleRegister right = ToDoubleRegister(instr->right());
DoubleRegister result = ToDoubleRegister(instr->result());
switch (instr->op()) {
case Token::ADD:
@@ -1683,8 +1828,8 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(r1));
- ASSERT(ToRegister(instr->InputAt(1)).is(r0));
+ ASSERT(ToRegister(instr->left()).is(r1));
+ ASSERT(ToRegister(instr->right()).is(r0));
ASSERT(ToRegister(instr->result()).is(r0));
BinaryOpStub stub(instr->op(), NO_OVERWRITE);
@@ -1729,11 +1874,11 @@ void LCodeGen::DoBranch(LBranch* instr) {
Representation r = instr->hydrogen()->value()->representation();
if (r.IsInteger32()) {
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
__ cmp(reg, Operand(0));
EmitBranch(true_block, false_block, ne);
} else if (r.IsDouble()) {
- DoubleRegister reg = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister reg = ToDoubleRegister(instr->value());
Register scratch = scratch0();
// Test the double value. Zero and NaN are false.
@@ -1742,7 +1887,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
EmitBranch(true_block, false_block, eq);
} else {
ASSERT(r.IsTagged());
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
HType type = instr->hydrogen()->value()->type();
if (type.IsBoolean()) {
__ CompareRoot(reg, Heap::kTrueValueRootIndex);
@@ -1881,8 +2026,8 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
Condition cond = TokenToCondition(instr->op(), false);
@@ -1922,8 +2067,8 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
- Register left = ToRegister(instr->InputAt(0));
- Register right = ToRegister(instr->InputAt(1));
+ Register left = ToRegister(instr->left());
+ Register right = ToRegister(instr->right());
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -1933,7 +2078,7 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
- Register left = ToRegister(instr->InputAt(0));
+ Register left = ToRegister(instr->left());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1944,7 +2089,7 @@ void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
Register scratch = scratch0();
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
int false_block = chunk_->LookupDestination(instr->false_block_id());
// If the expression is known to be untagged or a smi, then it's definitely
@@ -2012,8 +2157,8 @@ Condition LCodeGen::EmitIsObject(Register input,
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
- Register temp1 = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->value());
+ Register temp1 = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -2038,8 +2183,8 @@ Condition LCodeGen::EmitIsString(Register input,
void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
- Register temp1 = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->value());
+ Register temp1 = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -2056,15 +2201,15 @@ void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
- Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
+ Register input_reg = EmitLoadRegister(instr->value(), ip);
__ tst(input_reg, Operand(kSmiTagMask));
EmitBranch(true_block, false_block, eq);
}
void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register input = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -2134,7 +2279,7 @@ static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
Register scratch = scratch0();
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -2149,12 +2294,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
- if (FLAG_debug_code) {
- __ AbortIfNotString(input);
- }
+ __ AssertString(input);
__ ldr(result, FieldMemOperand(input, String::kHashFieldOffset));
__ IndexFromHash(result, result);
@@ -2163,7 +2306,7 @@ void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
void LCodeGen::DoHasCachedArrayIndexAndBranch(
LHasCachedArrayIndexAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register scratch = scratch0();
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -2244,9 +2387,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register temp = scratch0();
- Register temp2 = ToRegister(instr->TempAt(0));
+ Register temp2 = ToRegister(instr->temp());
Handle<String> class_name = instr->hydrogen()->class_name();
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -2262,8 +2405,8 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
int true_block = instr->true_block_id();
int false_block = instr->false_block_id();
@@ -2274,8 +2417,8 @@ void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(r0)); // Object is in r0.
- ASSERT(ToRegister(instr->InputAt(1)).is(r1)); // Function is in r1.
+ ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0.
+ ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1.
InstanceofStub stub(InstanceofStub::kArgsInRegisters);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
@@ -2306,8 +2449,8 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
Label done, false_result;
- Register object = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register object = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
Register result = ToRegister(instr->result());
ASSERT(object.is(r0));
@@ -2330,6 +2473,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
// We use Factory::the_hole_value() on purpose instead of loading from the
// root array to force relocation to be able to later patch with
// the cached map.
+ PredictableCodeSizeScope predictable(masm_);
Handle<JSGlobalPropertyCell> cell =
factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
__ mov(ip, Operand(Handle<Object>(cell)));
@@ -2387,10 +2531,13 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
// Get the temp register reserved by the instruction. This needs to be r4 as
// its slot of the pushing of safepoint registers is used to communicate the
// offset to the location of the map check.
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
ASSERT(temp.is(r4));
__ LoadHeapObject(InstanceofStub::right(), instr->function());
static const int kAdditionalDelta = 5;
+ // Make sure that code size is predicable, since we use specific constants
+ // offsets in the code to find embedded values..
+ PredictableCodeSizeScope predictable(masm_);
int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
Label before_push_delta;
__ bind(&before_push_delta);
@@ -2484,7 +2631,7 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
// it as no longer deleted.
if (instr->hydrogen()->RequiresHoleCheck()) {
// We use a temp to check the payload (CompareRoot might clobber ip).
- Register payload = ToRegister(instr->TempAt(0));
+ Register payload = ToRegister(instr->temp());
__ ldr(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
__ CompareRoot(payload, Heap::kTheHoleValueRootIndex);
DeoptimizeIf(eq, instr->environment());
@@ -2563,7 +2710,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
- Register object = ToRegister(instr->InputAt(0));
+ Register object = ToRegister(instr->object());
Register result = ToRegister(instr->result());
if (instr->hydrogen()->is_in_object()) {
__ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset()));
@@ -2580,9 +2727,9 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
Handle<String> name,
LEnvironment* env) {
LookupResult lookup(isolate());
- type->LookupInDescriptors(NULL, *name, &lookup);
+ type->LookupDescriptor(NULL, *name, &lookup);
ASSERT(lookup.IsFound() || lookup.IsCacheable());
- if (lookup.IsFound() && lookup.type() == FIELD) {
+ if (lookup.IsField()) {
int index = lookup.GetLocalFieldIndexFromMap(*type);
int offset = index * kPointerSize;
if (index < 0) {
@@ -2594,7 +2741,7 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
__ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
__ ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
}
- } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) {
+ } else if (lookup.IsConstantFunction()) {
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
__ LoadHeapObject(result, function);
} else {
@@ -2654,7 +2801,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
if (need_generic) {
__ mov(r2, Operand(name));
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- CallCode(ic, RelocInfo::CODE_TARGET, instr);
+ CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
__ bind(&done);
}
@@ -2667,7 +2814,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
// Name is always in r2.
__ mov(r2, Operand(instr->name()));
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- CallCode(ic, RelocInfo::CODE_TARGET, instr);
+ CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
@@ -2717,7 +2864,7 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
void LCodeGen::DoLoadElements(LLoadElements* instr) {
Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->object());
Register scratch = scratch0();
__ ldr(result, FieldMemOperand(input, JSObject::kElementsOffset));
@@ -2752,7 +2899,7 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
void LCodeGen::DoLoadExternalArrayPointer(
LLoadExternalArrayPointer* instr) {
Register to_reg = ToRegister(instr->result());
- Register from_reg = ToRegister(instr->InputAt(0));
+ Register from_reg = ToRegister(instr->object());
__ ldr(to_reg, FieldMemOperand(from_reg,
ExternalArray::kExternalPointerOffset));
}
@@ -2763,14 +2910,9 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
Register length = ToRegister(instr->length());
Register index = ToRegister(instr->index());
Register result = ToRegister(instr->result());
-
- // Bailout index is not a valid argument index. Use unsigned check to get
- // negative check for free.
- __ sub(length, length, index, SetCC);
- DeoptimizeIf(ls, instr->environment());
-
// There are two words between the frame pointer and the last argument.
// Subtracting from length accounts for one of them add one more.
+ __ sub(length, length, index);
__ add(length, length, Operand(1));
__ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
}
@@ -2778,15 +2920,31 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
Register elements = ToRegister(instr->elements());
- Register key = EmitLoadRegister(instr->key(), scratch0());
Register result = ToRegister(instr->result());
Register scratch = scratch0();
+ Register store_base = scratch;
+ int offset = 0;
- // Load the result.
- __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
- uint32_t offset = FixedArray::kHeaderSize +
- (instr->additional_index() << kPointerSizeLog2);
- __ ldr(result, FieldMemOperand(scratch, offset));
+ if (instr->key()->IsConstantOperand()) {
+ LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
+ offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
+ instr->additional_index());
+ store_base = elements;
+ } else {
+ Register key = EmitLoadRegister(instr->key(), scratch0());
+ // Even though the HLoadKeyedFastElement instruction forces the input
+ // representation for the key to be an integer, the input gets replaced
+ // during bound check elimination with the index argument to the bounds
+ // check, which can be tagged, so that case must be handled here, too.
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ add(scratch, elements,
+ Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+ } else {
+ __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
+ }
+ offset = FixedArray::OffsetOfElementAt(instr->additional_index());
+ }
+ __ ldr(result, FieldMemOperand(store_base, offset));
// Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -2810,8 +2968,9 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
DwVfpRegister result = ToDoubleRegister(instr->result());
Register scratch = scratch0();
- int shift_size =
- ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+ int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+ int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
+ ? (element_size_shift - kSmiTagSize) : element_size_shift;
int constant_key = 0;
if (key_is_constant) {
constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
@@ -2823,14 +2982,15 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
}
Operand operand = key_is_constant
- ? Operand(((constant_key + instr->additional_index()) << shift_size) +
+ ? Operand(((constant_key + instr->additional_index()) <<
+ element_size_shift) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag)
: Operand(key, LSL, shift_size);
__ add(elements, elements, operand);
if (!key_is_constant) {
__ add(elements, elements,
Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
- (instr->additional_index() << shift_size)));
+ (instr->additional_index() << element_size_shift)));
}
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -2843,6 +3003,42 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
}
+MemOperand LCodeGen::PrepareKeyedOperand(Register key,
+ Register base,
+ bool key_is_constant,
+ int constant_key,
+ int element_size,
+ int shift_size,
+ int additional_index,
+ int additional_offset) {
+ if (additional_index != 0 && !key_is_constant) {
+ additional_index *= 1 << (element_size - shift_size);
+ __ add(scratch0(), key, Operand(additional_index));
+ }
+
+ if (key_is_constant) {
+ return MemOperand(base,
+ (constant_key << element_size) + additional_offset);
+ }
+
+ if (additional_index == 0) {
+ if (shift_size >= 0) {
+ return MemOperand(base, key, LSL, shift_size);
+ } else {
+ ASSERT_EQ(-1, shift_size);
+ return MemOperand(base, key, LSR, 1);
+ }
+ }
+
+ if (shift_size >= 0) {
+ return MemOperand(base, scratch0(), LSL, shift_size);
+ } else {
+ ASSERT_EQ(-1, shift_size);
+ return MemOperand(base, scratch0(), LSR, 1);
+ }
+}
+
+
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer());
@@ -2858,15 +3054,17 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
} else {
key = ToRegister(instr->key());
}
- int shift_size = ElementsKindToShiftSize(elements_kind);
- int additional_offset = instr->additional_index() << shift_size;
+ int element_size_shift = ElementsKindToShiftSize(elements_kind);
+ int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
+ ? (element_size_shift - kSmiTagSize) : element_size_shift;
+ int additional_offset = instr->additional_index() << element_size_shift;
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
CpuFeatures::Scope scope(VFP3);
DwVfpRegister result = ToDoubleRegister(instr->result());
Operand operand = key_is_constant
- ? Operand(constant_key << shift_size)
+ ? Operand(constant_key << element_size_shift)
: Operand(key, LSL, shift_size);
__ add(scratch0(), external_pointer, operand);
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
@@ -2877,15 +3075,10 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
}
} else {
Register result = ToRegister(instr->result());
- if (instr->additional_index() != 0 && !key_is_constant) {
- __ add(scratch0(), key, Operand(instr->additional_index()));
- }
- MemOperand mem_operand(key_is_constant
- ? MemOperand(external_pointer,
- (constant_key << shift_size) + additional_offset)
- : (instr->additional_index() == 0
- ? MemOperand(external_pointer, key, LSL, shift_size)
- : MemOperand(external_pointer, scratch0(), LSL, shift_size)));
+ MemOperand mem_operand = PrepareKeyedOperand(
+ key, external_pointer, key_is_constant, constant_key,
+ element_size_shift, shift_size,
+ instr->additional_index(), additional_offset);
switch (elements_kind) {
case EXTERNAL_BYTE_ELEMENTS:
__ ldrsb(result, mem_operand);
@@ -2905,11 +3098,10 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
break;
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ ldr(result, mem_operand);
- __ cmp(result, Operand(0x80000000));
- // TODO(danno): we could be more clever here, perhaps having a special
- // version of the stub that detects if the overflow case actually
- // happens, and generate code that returns a double rather than int.
- DeoptimizeIf(cs, instr->environment());
+ if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
+ __ cmp(result, Operand(0x80000000));
+ DeoptimizeIf(cs, instr->environment());
+ }
break;
case EXTERNAL_FLOAT_ELEMENTS:
case EXTERNAL_DOUBLE_ELEMENTS:
@@ -2933,7 +3125,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
ASSERT(ToRegister(instr->key()).is(r0));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
- CallCode(ic, RelocInfo::CODE_TARGET, instr);
+ CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
@@ -2959,7 +3151,7 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
- Register elem = ToRegister(instr->InputAt(0));
+ Register elem = ToRegister(instr->elements());
Register result = ToRegister(instr->result());
Label done;
@@ -3078,7 +3270,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
void LCodeGen::DoPushArgument(LPushArgument* instr) {
- LOperand* argument = instr->InputAt(0);
+ LOperand* argument = instr->value();
if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
Abort("DoPushArgument not implemented for double type.");
} else {
@@ -3095,7 +3287,7 @@ void LCodeGen::DoDrop(LDrop* instr) {
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
- __ LoadHeapObject(result, instr->hydrogen()->closure());
+ __ ldr(result, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
}
@@ -3125,12 +3317,12 @@ void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
Register result = ToRegister(instr->result());
- __ ldr(result, ContextOperand(cp, Context::GLOBAL_INDEX));
+ __ ldr(result, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
}
void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
- Register global = ToRegister(instr->global());
+ Register global = ToRegister(instr->global_object());
Register result = ToRegister(instr->result());
__ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
}
@@ -3152,14 +3344,8 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
__ LoadHeapObject(r1, function);
}
- // Change context if needed.
- bool change_context =
- (info()->closure()->context() != function->context()) ||
- scope()->contains_with() ||
- (scope()->num_heap_slots() > 0);
- if (change_context) {
- __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
- }
+ // Change context.
+ __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
// Set r0 to arguments count if adaption is not needed. Assumes that r0
// is available to write to at this point.
@@ -3196,7 +3382,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
Register scratch = scratch0();
@@ -3262,7 +3448,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
__ cmp(input, Operand(0));
__ Move(result, input, pl);
@@ -3292,7 +3478,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
Representation r = instr->hydrogen()->value()->representation();
if (r.IsDouble()) {
- DwVfpRegister input = ToDoubleRegister(instr->InputAt(0));
+ DwVfpRegister input = ToDoubleRegister(instr->value());
DwVfpRegister result = ToDoubleRegister(instr->result());
__ vabs(result, input);
} else if (r.IsInteger32()) {
@@ -3301,7 +3487,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
// Representation is tagged.
DeferredMathAbsTaggedHeapNumber* deferred =
new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
// Smi check.
__ JumpIfNotSmi(input, deferred->entry());
// If smi, handle it directly.
@@ -3312,29 +3498,24 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
- DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister input = ToDoubleRegister(instr->value());
Register result = ToRegister(instr->result());
- SwVfpRegister single_scratch = double_scratch0().low();
- Register scratch1 = scratch0();
- Register scratch2 = ToRegister(instr->TempAt(0));
+ Register scratch = scratch0();
__ EmitVFPTruncate(kRoundToMinusInf,
- single_scratch,
+ result,
input,
- scratch1,
- scratch2);
+ scratch,
+ double_scratch0());
DeoptimizeIf(ne, instr->environment());
- // Move the result back to general purpose register r0.
- __ vmov(result, single_scratch);
-
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Test for -0.
Label done;
__ cmp(result, Operand(0));
__ b(ne, &done);
- __ vmov(scratch1, input.high());
- __ tst(scratch1, Operand(HeapNumber::kSignMask));
+ __ vmov(scratch, input.high());
+ __ tst(scratch, Operand(HeapNumber::kSignMask));
DeoptimizeIf(ne, instr->environment());
__ bind(&done);
}
@@ -3342,8 +3523,9 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
- DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister input = ToDoubleRegister(instr->value());
Register result = ToRegister(instr->result());
+ DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp());
Register scratch = scratch0();
Label done, check_sign_on_zero;
@@ -3368,12 +3550,12 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
__ cmp(scratch, Operand(HeapNumber::kExponentBias + 32));
DeoptimizeIf(ge, instr->environment());
+ __ Vmov(double_scratch0(), 0.5, scratch);
+ __ vadd(double_scratch0(), input, double_scratch0());
+
// Save the original sign for later comparison.
__ and_(scratch, result, Operand(HeapNumber::kSignMask));
- __ Vmov(double_scratch0(), 0.5);
- __ vadd(double_scratch0(), input, double_scratch0());
-
// Check sign of the result: if the sign changed, the input
// value was in ]0.5, 0[ and the result should be -0.
__ vmov(result, double_scratch0().high());
@@ -3386,12 +3568,11 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
}
__ EmitVFPTruncate(kRoundToMinusInf,
- double_scratch0().low(),
- double_scratch0(),
result,
- scratch);
+ double_scratch0(),
+ scratch,
+ double_scratch1);
DeoptimizeIf(ne, instr->environment());
- __ vmov(result, double_scratch0().low());
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Test for -0.
@@ -3407,22 +3588,22 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
- DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister input = ToDoubleRegister(instr->value());
DoubleRegister result = ToDoubleRegister(instr->result());
__ vsqrt(result, input);
}
void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
- DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister input = ToDoubleRegister(instr->value());
DoubleRegister result = ToDoubleRegister(instr->result());
- DoubleRegister temp = ToDoubleRegister(instr->TempAt(0));
+ DoubleRegister temp = ToDoubleRegister(instr->temp());
// Note that according to ECMA-262 15.8.2.13:
// Math.pow(-Infinity, 0.5) == Infinity
// Math.sqrt(-Infinity) == NaN
Label done;
- __ vmov(temp, -V8_INFINITY);
+ __ vmov(temp, -V8_INFINITY, scratch0());
__ VFPCompareAndSetFlags(input, temp);
__ vneg(result, temp, eq);
__ b(&done, eq);
@@ -3438,11 +3619,11 @@ void LCodeGen::DoPower(LPower* instr) {
Representation exponent_type = instr->hydrogen()->right()->representation();
// Having marked this as a call, we can use any registers.
// Just make sure that the input/output registers are the expected ones.
- ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
- ToDoubleRegister(instr->InputAt(1)).is(d2));
- ASSERT(!instr->InputAt(1)->IsRegister() ||
- ToRegister(instr->InputAt(1)).is(r2));
- ASSERT(ToDoubleRegister(instr->InputAt(0)).is(d1));
+ ASSERT(!instr->right()->IsDoubleRegister() ||
+ ToDoubleRegister(instr->right()).is(d2));
+ ASSERT(!instr->right()->IsRegister() ||
+ ToRegister(instr->right()).is(r2));
+ ASSERT(ToDoubleRegister(instr->left()).is(d1));
ASSERT(ToDoubleRegister(instr->result()).is(d3));
if (exponent_type.IsTagged()) {
@@ -3482,16 +3663,16 @@ void LCodeGen::DoRandom(LRandom* instr) {
// Having marked this instruction as a call we can use any
// registers.
ASSERT(ToDoubleRegister(instr->result()).is(d7));
- ASSERT(ToRegister(instr->InputAt(0)).is(r0));
+ ASSERT(ToRegister(instr->global_object()).is(r0));
static const int kSeedSize = sizeof(uint32_t);
STATIC_ASSERT(kPointerSize == kSeedSize);
- __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset));
+ __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset));
static const int kRandomSeedOffset =
FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
__ ldr(r2, FieldMemOperand(r0, kRandomSeedOffset));
- // r2: FixedArray of the global context's random seeds
+ // r2: FixedArray of the native context's random seeds
// Load state[0].
__ ldr(r1, FieldMemOperand(r2, ByteArray::kHeaderSize));
@@ -3639,7 +3820,7 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
int arity = instr->arity();
Handle<Code> ic =
isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
- CallCode(ic, RelocInfo::CODE_TARGET, instr);
+ CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
@@ -3652,7 +3833,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) {
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
__ mov(r2, Operand(instr->name()));
- CallCode(ic, mode, instr);
+ CallCode(ic, mode, instr, NEVER_INLINE_TARGET_ADDRESS);
// Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
@@ -3677,7 +3858,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
__ mov(r2, Operand(instr->name()));
- CallCode(ic, mode, instr);
+ CallCode(ic, mode, instr, NEVER_INLINE_TARGET_ADDRESS);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
@@ -3693,7 +3874,7 @@ void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
void LCodeGen::DoCallNew(LCallNew* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(r1));
+ ASSERT(ToRegister(instr->constructor()).is(r1));
ASSERT(ToRegister(instr->result()).is(r0));
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
@@ -3719,7 +3900,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
__ mov(scratch, Operand(instr->transition()));
__ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
// Update the write barrier for the map field.
__ RecordWriteField(object,
HeapObject::kMapOffset,
@@ -3777,12 +3958,44 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
? isolate()->builtins()->StoreIC_Initialize_Strict()
: isolate()->builtins()->StoreIC_Initialize();
- CallCode(ic, RelocInfo::CODE_TARGET, instr);
+ CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
+}
+
+
+void LCodeGen::DeoptIfTaggedButNotSmi(LEnvironment* environment,
+ HValue* value,
+ LOperand* operand) {
+ if (value->representation().IsTagged() && !value->type().IsSmi()) {
+ if (operand->IsRegister()) {
+ __ tst(ToRegister(operand), Operand(kSmiTagMask));
+ } else {
+ __ mov(ip, ToOperand(operand));
+ __ tst(ip, Operand(kSmiTagMask));
+ }
+ DeoptimizeIf(ne, environment);
+ }
}
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
- __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
+ DeoptIfTaggedButNotSmi(instr->environment(),
+ instr->hydrogen()->length(),
+ instr->length());
+ DeoptIfTaggedButNotSmi(instr->environment(),
+ instr->hydrogen()->index(),
+ instr->index());
+ if (instr->index()->IsConstantOperand()) {
+ int constant_index =
+ ToInteger32(LConstantOperand::cast(instr->index()));
+ if (instr->hydrogen()->length()->representation().IsTagged()) {
+ __ mov(ip, Operand(Smi::FromInt(constant_index)));
+ } else {
+ __ mov(ip, Operand(constant_index));
+ }
+ __ cmp(ip, ToRegister(instr->length()));
+ } else {
+ __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
+ }
DeoptimizeIf(hs, instr->environment());
}
@@ -3792,31 +4005,37 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
Register elements = ToRegister(instr->object());
Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
Register scratch = scratch0();
+ Register store_base = scratch;
+ int offset = 0;
// Do the store.
if (instr->key()->IsConstantOperand()) {
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
- int offset =
- (ToInteger32(const_operand) + instr->additional_index()) * kPointerSize
- + FixedArray::kHeaderSize;
- __ str(value, FieldMemOperand(elements, offset));
+ offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
+ instr->additional_index());
+ store_base = elements;
} else {
- __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
- if (instr->additional_index() != 0) {
- __ add(scratch,
- scratch,
- Operand(instr->additional_index() << kPointerSizeLog2));
+ // Even though the HLoadKeyedFastElement instruction forces the input
+ // representation for the key to be an integer, the input gets replaced
+ // during bound check elimination with the index argument to the bounds
+ // check, which can be tagged, so that case must be handled here, too.
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ add(scratch, elements,
+ Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+ } else {
+ __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
}
- __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
+ offset = FixedArray::OffsetOfElementAt(instr->additional_index());
}
+ __ str(value, FieldMemOperand(store_base, offset));
if (instr->hydrogen()->NeedsWriteBarrier()) {
HType type = instr->hydrogen()->value()->type();
SmiCheck check_needed =
type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
// Compute address of modified element and store it into key register.
- __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ add(key, store_base, Operand(offset - kHeapObjectTag));
__ RecordWrite(elements,
key,
value,
@@ -3847,9 +4066,11 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
} else {
key = ToRegister(instr->key());
}
- int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+ int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+ int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
+ ? (element_size_shift - kSmiTagSize) : element_size_shift;
Operand operand = key_is_constant
- ? Operand((constant_key << shift_size) +
+ ? Operand((constant_key << element_size_shift) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag)
: Operand(key, LSL, shift_size);
__ add(scratch, elements, operand);
@@ -3864,10 +4085,10 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
// Only load canonical NaN if the comparison above set the overflow.
__ Vmov(value,
FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
- vs);
+ no_reg, vs);
}
- __ vstr(value, scratch, instr->additional_index() << shift_size);
+ __ vstr(value, scratch, instr->additional_index() << element_size_shift);
}
@@ -3887,15 +4108,18 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
} else {
key = ToRegister(instr->key());
}
- int shift_size = ElementsKindToShiftSize(elements_kind);
- int additional_offset = instr->additional_index() << shift_size;
+ int element_size_shift = ElementsKindToShiftSize(elements_kind);
+ int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
+ ? (element_size_shift - kSmiTagSize) : element_size_shift;
+ int additional_offset = instr->additional_index() << element_size_shift;
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
CpuFeatures::Scope scope(VFP3);
DwVfpRegister value(ToDoubleRegister(instr->value()));
- Operand operand(key_is_constant ? Operand(constant_key << shift_size)
- : Operand(key, LSL, shift_size));
+ Operand operand(key_is_constant
+ ? Operand(constant_key << element_size_shift)
+ : Operand(key, LSL, shift_size));
__ add(scratch0(), external_pointer, operand);
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ vcvt_f32_f64(double_scratch0().low(), value);
@@ -3905,16 +4129,10 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
}
} else {
Register value(ToRegister(instr->value()));
- if (instr->additional_index() != 0 && !key_is_constant) {
- __ add(scratch0(), key, Operand(instr->additional_index()));
- }
- MemOperand mem_operand(key_is_constant
- ? MemOperand(external_pointer,
- ((constant_key + instr->additional_index())
- << shift_size))
- : (instr->additional_index() == 0
- ? MemOperand(external_pointer, key, LSL, shift_size)
- : MemOperand(external_pointer, scratch0(), LSL, shift_size)));
+ MemOperand mem_operand = PrepareKeyedOperand(
+ key, external_pointer, key_is_constant, constant_key,
+ element_size_shift, shift_size,
+ instr->additional_index(), additional_offset);
switch (elements_kind) {
case EXTERNAL_PIXEL_ELEMENTS:
case EXTERNAL_BYTE_ELEMENTS:
@@ -3954,13 +4172,13 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
: isolate()->builtins()->KeyedStoreIC_Initialize();
- CallCode(ic, RelocInfo::CODE_TARGET, instr);
+ CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
Register object_reg = ToRegister(instr->object());
- Register new_map_reg = ToRegister(instr->new_map_reg());
+ Register new_map_reg = ToRegister(instr->new_map_temp());
Register scratch = scratch0();
Handle<Map> from_map = instr->original_map();
@@ -3981,7 +4199,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
scratch, kLRHasBeenSaved, kDontSaveFPRegs);
} else if (IsFastSmiElementsKind(from_kind) &&
IsFastDoubleElementsKind(to_kind)) {
- Register fixed_object_reg = ToRegister(instr->temp_reg());
+ Register fixed_object_reg = ToRegister(instr->temp());
ASSERT(fixed_object_reg.is(r2));
ASSERT(new_map_reg.is(r3));
__ mov(fixed_object_reg, object_reg);
@@ -3989,7 +4207,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
RelocInfo::CODE_TARGET, instr);
} else if (IsFastDoubleElementsKind(from_kind) &&
IsFastObjectElementsKind(to_kind)) {
- Register fixed_object_reg = ToRegister(instr->temp_reg());
+ Register fixed_object_reg = ToRegister(instr->temp());
ASSERT(fixed_object_reg.is(r2));
ASSERT(new_map_reg.is(r3));
__ mov(fixed_object_reg, object_reg);
@@ -4057,9 +4275,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
__ push(index);
}
CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
- if (FLAG_debug_code) {
- __ AbortIfNotSmi(r0);
- }
+ __ AssertSmi(r0);
__ SmiUntag(r0);
__ StoreToSafepointRegisterSlot(r0, result);
}
@@ -4114,14 +4330,14 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
void LCodeGen::DoStringLength(LStringLength* instr) {
- Register string = ToRegister(instr->InputAt(0));
+ Register string = ToRegister(instr->string());
Register result = ToRegister(instr->result());
__ ldr(result, FieldMemOperand(string, String::kLengthOffset));
}
void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister() || input->IsStackSlot());
LOperand* output = instr->result();
ASSERT(output->IsDoubleRegister());
@@ -4137,18 +4353,32 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
}
+void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
+ LOperand* input = instr->value();
+ LOperand* output = instr->result();
+
+ SwVfpRegister flt_scratch = double_scratch0().low();
+ __ vmov(flt_scratch, ToRegister(input));
+ __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch);
+}
+
+
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
class DeferredNumberTagI: public LDeferredCode {
public:
DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
: LDeferredCode(codegen), instr_(instr) { }
- virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); }
+ virtual void Generate() {
+ codegen()->DoDeferredNumberTagI(instr_,
+ instr_->value(),
+ SIGNED_INT32);
+ }
virtual LInstruction* instr() { return instr_; }
private:
LNumberTagI* instr_;
};
- Register src = ToRegister(instr->InputAt(0));
+ Register src = ToRegister(instr->value());
Register dst = ToRegister(instr->result());
DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
@@ -4158,9 +4388,38 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
}
-void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
+void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
+ class DeferredNumberTagU: public LDeferredCode {
+ public:
+ DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
+ : LDeferredCode(codegen), instr_(instr) { }
+ virtual void Generate() {
+ codegen()->DoDeferredNumberTagI(instr_,
+ instr_->value(),
+ UNSIGNED_INT32);
+ }
+ virtual LInstruction* instr() { return instr_; }
+ private:
+ LNumberTagU* instr_;
+ };
+
+ LOperand* input = instr->value();
+ ASSERT(input->IsRegister() && input->Equals(instr->result()));
+ Register reg = ToRegister(input);
+
+ DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
+ __ cmp(reg, Operand(Smi::kMaxValue));
+ __ b(hi, deferred->entry());
+ __ SmiTag(reg, reg);
+ __ bind(deferred->exit());
+}
+
+
+void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
+ LOperand* value,
+ IntegerSignedness signedness) {
Label slow;
- Register src = ToRegister(instr->InputAt(0));
+ Register src = ToRegister(value);
Register dst = ToRegister(instr->result());
DoubleRegister dbl_scratch = double_scratch0();
SwVfpRegister flt_scratch = dbl_scratch.low();
@@ -4168,19 +4427,25 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
// Preserve the value of all registers.
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
- // There was overflow, so bits 30 and 31 of the original integer
- // disagree. Try to allocate a heap number in new space and store
- // the value in there. If that fails, call the runtime system.
Label done;
- if (dst.is(src)) {
- __ SmiUntag(src, dst);
- __ eor(src, src, Operand(0x80000000));
+ if (signedness == SIGNED_INT32) {
+ // There was overflow, so bits 30 and 31 of the original integer
+ // disagree. Try to allocate a heap number in new space and store
+ // the value in there. If that fails, call the runtime system.
+ if (dst.is(src)) {
+ __ SmiUntag(src, dst);
+ __ eor(src, src, Operand(0x80000000));
+ }
+ __ vmov(flt_scratch, src);
+ __ vcvt_f64_s32(dbl_scratch, flt_scratch);
+ } else {
+ __ vmov(flt_scratch, src);
+ __ vcvt_f64_u32(dbl_scratch, flt_scratch);
}
- __ vmov(flt_scratch, src);
- __ vcvt_f64_s32(dbl_scratch, flt_scratch);
+
if (FLAG_inline_new) {
__ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
- __ AllocateHeapNumber(r5, r3, r4, r6, &slow);
+ __ AllocateHeapNumber(r5, r3, r4, r6, &slow, DONT_TAG_RESULT);
__ Move(dst, r5);
__ b(&done);
}
@@ -4195,12 +4460,13 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
__ StoreToSafepointRegisterSlot(ip, dst);
CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
__ Move(dst, r0);
+ __ sub(dst, dst, Operand(kHeapObjectTag));
// Done. Put the value in dbl_scratch into the value of the allocated heap
// number.
__ bind(&done);
- __ sub(ip, dst, Operand(kHeapObjectTag));
- __ vstr(dbl_scratch, ip, HeapNumber::kValueOffset);
+ __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset);
+ __ add(dst, dst, Operand(kHeapObjectTag));
__ StoreToSafepointRegisterSlot(dst, dst);
}
@@ -4216,22 +4482,25 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
LNumberTagD* instr_;
};
- DoubleRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister input_reg = ToDoubleRegister(instr->value());
Register scratch = scratch0();
Register reg = ToRegister(instr->result());
- Register temp1 = ToRegister(instr->TempAt(0));
- Register temp2 = ToRegister(instr->TempAt(1));
+ Register temp1 = ToRegister(instr->temp());
+ Register temp2 = ToRegister(instr->temp2());
DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
if (FLAG_inline_new) {
__ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
- __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry());
+ // We want the untagged address first for performance
+ __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(),
+ DONT_TAG_RESULT);
} else {
__ jmp(deferred->entry());
}
__ bind(deferred->exit());
- __ sub(ip, reg, Operand(kHeapObjectTag));
- __ vstr(input_reg, ip, HeapNumber::kValueOffset);
+ __ vstr(input_reg, reg, HeapNumber::kValueOffset);
+ // Now that we have finished with the object's real address tag it
+ __ add(reg, reg, Operand(kHeapObjectTag));
}
@@ -4244,18 +4513,19 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
+ __ sub(r0, r0, Operand(kHeapObjectTag));
__ StoreToSafepointRegisterSlot(r0, reg);
}
void LCodeGen::DoSmiTag(LSmiTag* instr) {
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
- __ SmiTag(ToRegister(instr->result()), ToRegister(instr->InputAt(0)));
+ __ SmiTag(ToRegister(instr->result()), ToRegister(instr->value()));
}
void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
if (instr->needs_check()) {
STATIC_ASSERT(kHeapObjectTag == 1);
@@ -4327,11 +4597,11 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
- Register input_reg = ToRegister(instr->InputAt(0));
+ Register input_reg = ToRegister(instr->value());
Register scratch1 = scratch0();
- Register scratch2 = ToRegister(instr->TempAt(0));
+ Register scratch2 = ToRegister(instr->temp());
DwVfpRegister double_scratch = double_scratch0();
- SwVfpRegister single_scratch = double_scratch.low();
+ DwVfpRegister double_scratch2 = ToDoubleRegister(instr->temp3());
ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
@@ -4350,8 +4620,8 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
__ cmp(scratch1, Operand(ip));
if (instr->truncating()) {
- Register scratch3 = ToRegister(instr->TempAt(1));
- DwVfpRegister double_scratch2 = ToDoubleRegister(instr->TempAt(2));
+ Register scratch3 = ToRegister(instr->temp2());
+ SwVfpRegister single_scratch = double_scratch.low();
ASSERT(!scratch3.is(input_reg) &&
!scratch3.is(scratch1) &&
!scratch3.is(scratch2));
@@ -4386,14 +4656,12 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
__ sub(ip, input_reg, Operand(kHeapObjectTag));
__ vldr(double_scratch, ip, HeapNumber::kValueOffset);
__ EmitVFPTruncate(kRoundToZero,
- single_scratch,
+ input_reg,
double_scratch,
scratch1,
- scratch2,
+ double_scratch2,
kCheckForInexactConversion);
DeoptimizeIf(ne, instr->environment());
- // Load the result.
- __ vmov(input_reg, single_scratch);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ cmp(input_reg, Operand(0));
@@ -4418,7 +4686,7 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
LTaggedToI* instr_;
};
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
ASSERT(input->Equals(instr->result()));
@@ -4437,7 +4705,7 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
LOperand* result = instr->result();
ASSERT(result->IsDoubleRegister());
@@ -4455,14 +4723,14 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
Register result_reg = ToRegister(instr->result());
Register scratch1 = scratch0();
- Register scratch2 = ToRegister(instr->TempAt(0));
- DwVfpRegister double_input = ToDoubleRegister(instr->InputAt(0));
- SwVfpRegister single_scratch = double_scratch0().low();
+ Register scratch2 = ToRegister(instr->temp());
+ DwVfpRegister double_input = ToDoubleRegister(instr->value());
Label done;
if (instr->truncating()) {
- Register scratch3 = ToRegister(instr->TempAt(1));
+ Register scratch3 = ToRegister(instr->temp2());
+ SwVfpRegister single_scratch = double_scratch0().low();
__ EmitECMATruncate(result_reg,
double_input,
single_scratch,
@@ -4470,39 +4738,38 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
scratch2,
scratch3);
} else {
- VFPRoundingMode rounding_mode = kRoundToMinusInf;
- __ EmitVFPTruncate(rounding_mode,
- single_scratch,
+ DwVfpRegister double_scratch = double_scratch0();
+ __ EmitVFPTruncate(kRoundToMinusInf,
+ result_reg,
double_input,
scratch1,
- scratch2,
+ double_scratch,
kCheckForInexactConversion);
+
// Deoptimize if we had a vfp invalid exception,
// including inexact operation.
DeoptimizeIf(ne, instr->environment());
- // Retrieve the result.
- __ vmov(result_reg, single_scratch);
}
__ bind(&done);
}
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
__ tst(ToRegister(input), Operand(kSmiTagMask));
DeoptimizeIf(ne, instr->environment());
}
void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
__ tst(ToRegister(input), Operand(kSmiTagMask));
DeoptimizeIf(eq, instr->environment());
}
void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register scratch = scratch0();
__ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
@@ -4575,7 +4842,7 @@ void LCodeGen::DoCheckMapCommon(Register reg,
void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
Register scratch = scratch0();
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
@@ -4595,7 +4862,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
Register result_reg = ToRegister(instr->result());
- DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0));
+ DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
__ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
}
@@ -4611,7 +4878,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
Register scratch = scratch0();
Register input_reg = ToRegister(instr->unclamped());
Register result_reg = ToRegister(instr->result());
- DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0));
+ DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
Label is_smi, done, heap_number;
// Both smi and heap number cases are handled.
@@ -4645,8 +4912,8 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
- Register temp1 = ToRegister(instr->TempAt(0));
- Register temp2 = ToRegister(instr->TempAt(1));
+ Register temp1 = ToRegister(instr->temp());
+ Register temp2 = ToRegister(instr->temp2());
Handle<JSObject> holder = instr->holder();
Handle<JSObject> current_prototype = instr->prototype();
@@ -4688,8 +4955,8 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
new(zone()) DeferredAllocateObject(this, instr);
Register result = ToRegister(instr->result());
- Register scratch = ToRegister(instr->TempAt(0));
- Register scratch2 = ToRegister(instr->TempAt(1));
+ Register scratch = ToRegister(instr->temp());
+ Register scratch2 = ToRegister(instr->temp2());
Handle<JSFunction> constructor = instr->hydrogen()->constructor();
Handle<Map> initial_map(constructor->initial_map());
int instance_size = initial_map->instance_size();
@@ -4757,7 +5024,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
- Heap* heap = isolate()->heap();
+ Handle<FixedArray> literals(instr->environment()->closure()->literals());
ElementsKind boilerplate_elements_kind =
instr->hydrogen()->boilerplate_elements_kind();
@@ -4777,12 +5044,12 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
DeoptimizeIf(ne, instr->environment());
}
- __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
+ // Set up the parameters to the stub/runtime call.
+ __ LoadHeapObject(r3, literals);
__ mov(r2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
// Boilerplate already exists, constant elements are never accessed.
// Pass an empty fixed array.
- __ mov(r1, Operand(Handle<FixedArray>(heap->empty_fixed_array())));
+ __ mov(r1, Operand(isolate()->factory()->empty_fixed_array()));
__ Push(r3, r2, r1);
// Pick the right runtime function or stub to call.
@@ -4876,8 +5143,8 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
for (int i = 0; i < elements_length; i++) {
int64_t value = double_array->get_representation(i);
// We only support little endian mode...
- int32_t value_low = value & 0xFFFFFFFF;
- int32_t value_high = value >> 32;
+ int32_t value_low = static_cast<int32_t>(value & 0xFFFFFFFF);
+ int32_t value_high = static_cast<int32_t>(value >> 32);
int total_offset =
elements_offset + FixedDoubleArray::OffsetOfElementAt(i);
__ mov(r2, Operand(value_low));
@@ -4981,7 +5248,7 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(r0));
+ ASSERT(ToRegister(instr->value()).is(r0));
__ push(r0);
CallRuntime(Runtime::kToFastProperties, 1, instr);
}
@@ -4990,15 +5257,13 @@ void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
Label materialized;
// Registers will be used as follows:
- // r3 = JS function.
// r7 = literals array.
// r1 = regexp literal.
// r0 = regexp literal clone.
// r2 and r4-r6 are used as temporaries.
- __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ ldr(r7, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
- int literal_offset = FixedArray::kHeaderSize +
- instr->hydrogen()->literal_index() * kPointerSize;
+ int literal_offset =
+ FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+ __ LoadHeapObject(r7, instr->hydrogen()->literals());
__ ldr(r1, FieldMemOperand(r7, literal_offset));
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
__ cmp(r1, ip);
@@ -5064,14 +5329,14 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
void LCodeGen::DoTypeof(LTypeof* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
__ push(input);
CallRuntime(Runtime::kTypeof, 1, instr);
}
void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* true_label = chunk_->GetAssemblyLabel(true_block);
@@ -5161,7 +5426,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
- Register temp1 = ToRegister(instr->TempAt(0));
+ Register temp1 = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -5282,6 +5547,7 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) {
__ cmp(sp, Operand(ip));
__ b(hs, &done);
StackCheckStub stub;
+ PredictableCodeSizeScope predictable(masm_);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
EnsureSpaceForLazyDeopt();
__ bind(&done);
@@ -5362,13 +5628,23 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
Register map = ToRegister(instr->map());
Register result = ToRegister(instr->result());
+ Label load_cache, done;
+ __ EnumLength(result, map);
+ __ cmp(result, Operand(Smi::FromInt(0)));
+ __ b(ne, &load_cache);
+ __ mov(result, Operand(isolate()->factory()->empty_fixed_array()));
+ __ jmp(&done);
+
+ __ bind(&load_cache);
__ LoadInstanceDescriptors(map, result);
__ ldr(result,
- FieldMemOperand(result, DescriptorArray::kEnumerationIndexOffset));
+ FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
__ ldr(result,
FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
__ cmp(result, Operand(0));
DeoptimizeIf(eq, instr->environment());
+
+ __ bind(&done);
}
diff --git a/deps/v8/src/arm/lithium-codegen-arm.h b/deps/v8/src/arm/lithium-codegen-arm.h
index f35c69b8a..9281537c1 100644
--- a/deps/v8/src/arm/lithium-codegen-arm.h
+++ b/deps/v8/src/arm/lithium-codegen-arm.h
@@ -43,26 +43,25 @@ class SafepointGenerator;
class LCodeGen BASE_EMBEDDED {
public:
- LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info,
- Zone* zone)
- : chunk_(chunk),
+ LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
+ : zone_(info->zone()),
+ chunk_(static_cast<LPlatformChunk*>(chunk)),
masm_(assembler),
info_(info),
current_block_(-1),
current_instruction_(-1),
instructions_(chunk->instructions()),
- deoptimizations_(4, zone),
- deopt_jump_table_(4, zone),
- deoptimization_literals_(8, zone),
+ deoptimizations_(4, info->zone()),
+ deopt_jump_table_(4, info->zone()),
+ deoptimization_literals_(8, info->zone()),
inlined_function_count_(0),
scope_(info->scope()),
status_(UNUSED),
- translations_(zone),
- deferred_(8, zone),
+ translations_(info->zone()),
+ deferred_(8, info->zone()),
osr_pc_offset_(-1),
last_lazy_deopt_pc_(0),
- safepoints_(zone),
- zone_(zone),
+ safepoints_(info->zone()),
resolver_(this),
expected_safepoint_kind_(Safepoint::kSimple) {
PopulateDeoptimizationLiteralsWithInlinedFunctions();
@@ -111,11 +110,17 @@ class LCodeGen BASE_EMBEDDED {
void FinishCode(Handle<Code> code);
// Deferred code support.
- template<int T>
- void DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
+ void DoDeferredBinaryOpStub(LPointerMap* pointer_map,
+ LOperand* left_argument,
+ LOperand* right_argument,
Token::Value op);
void DoDeferredNumberTagD(LNumberTagD* instr);
- void DoDeferredNumberTagI(LNumberTagI* instr);
+
+ enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
+ void DoDeferredNumberTagI(LInstruction* instr,
+ LOperand* value,
+ IntegerSignedness signedness);
+
void DoDeferredTaggedToI(LTaggedToI* instr);
void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
void DoDeferredStackCheck(LStackCheck* instr);
@@ -133,8 +138,20 @@ class LCodeGen BASE_EMBEDDED {
void DoParallelMove(LParallelMove* move);
void DoGap(LGap* instr);
+ MemOperand PrepareKeyedOperand(Register key,
+ Register base,
+ bool key_is_constant,
+ int constant_key,
+ int element_size,
+ int shift_size,
+ int additional_index,
+ int additional_offset);
+
// Emit frame translation commands for an environment.
- void WriteTranslation(LEnvironment* environment, Translation* translation);
+ void WriteTranslation(LEnvironment* environment,
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count);
// Declare methods that deal with the individual node types.
#define DECLARE_DO(type) void Do##type(L##type* node);
@@ -158,7 +175,7 @@ class LCodeGen BASE_EMBEDDED {
return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
}
- LChunk* chunk() const { return chunk_; }
+ LPlatformChunk* chunk() const { return chunk_; }
Scope* scope() const { return scope_; }
HGraph* graph() const { return chunk_->graph(); }
@@ -178,7 +195,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
int GetParameterCount() const { return scope()->num_parameters(); }
- void Abort(const char* format, ...);
+ void Abort(const char* reason);
void Comment(const char* format, ...);
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
@@ -196,14 +213,18 @@ class LCodeGen BASE_EMBEDDED {
RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
};
- void CallCode(Handle<Code> code,
- RelocInfo::Mode mode,
- LInstruction* instr);
+ void CallCode(
+ Handle<Code> code,
+ RelocInfo::Mode mode,
+ LInstruction* instr,
+ TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS);
- void CallCodeGeneric(Handle<Code> code,
- RelocInfo::Mode mode,
- LInstruction* instr,
- SafepointMode safepoint_mode);
+ void CallCodeGeneric(
+ Handle<Code> code,
+ RelocInfo::Mode mode,
+ LInstruction* instr,
+ SafepointMode safepoint_mode,
+ TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS);
void CallRuntime(const Runtime::Function* function,
int num_arguments,
@@ -244,7 +265,10 @@ class LCodeGen BASE_EMBEDDED {
void AddToTranslation(Translation* translation,
LOperand* op,
- bool is_tagged);
+ bool is_tagged,
+ bool is_uint32,
+ int arguments_index,
+ int arguments_count);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
@@ -289,6 +313,10 @@ class LCodeGen BASE_EMBEDDED {
bool deoptimize_on_minus_zero,
LEnvironment* env);
+ void DeoptIfTaggedButNotSmi(LEnvironment* environment,
+ HValue* value,
+ LOperand* operand);
+
// Emits optimized code for typeof x == "y". Modifies input register.
// Returns the condition on which a final split to
// true and false label should be made, to optimize fallthrough.
@@ -350,7 +378,8 @@ class LCodeGen BASE_EMBEDDED {
void EnsureSpaceForLazyDeopt();
- LChunk* const chunk_;
+ Zone* zone_;
+ LPlatformChunk* const chunk_;
MacroAssembler* const masm_;
CompilationInfo* const info_;
@@ -372,8 +401,6 @@ class LCodeGen BASE_EMBEDDED {
// itself is emitted at the end of the generated code.
SafepointTableBuilder safepoints_;
- Zone* zone_;
-
// Compiler from a set of parallel moves to a sequential list of moves.
LGapResolver resolver_;
diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc
index d3bda3960..623bd6a01 100644
--- a/deps/v8/src/arm/macro-assembler-arm.cc
+++ b/deps/v8/src/arm/macro-assembler-arm.cc
@@ -108,7 +108,7 @@ void MacroAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode,
int MacroAssembler::CallSize(Register target, Condition cond) {
-#if USE_BLX
+#ifdef USE_BLX
return kInstrSize;
#else
return 2 * kInstrSize;
@@ -121,7 +121,7 @@ void MacroAssembler::Call(Register target, Condition cond) {
BlockConstPoolScope block_const_pool(this);
Label start;
bind(&start);
-#if USE_BLX
+#ifdef USE_BLX
blx(target, cond);
#else
// set lr for return at current pc + 8
@@ -137,7 +137,19 @@ int MacroAssembler::CallSize(
int size = 2 * kInstrSize;
Instr mov_instr = cond | MOV | LeaveCC;
intptr_t immediate = reinterpret_cast<intptr_t>(target);
- if (!Operand(immediate, rmode).is_single_instruction(mov_instr)) {
+ if (!Operand(immediate, rmode).is_single_instruction(this, mov_instr)) {
+ size += kInstrSize;
+ }
+ return size;
+}
+
+
+int MacroAssembler::CallSizeNotPredictableCodeSize(
+ Address target, RelocInfo::Mode rmode, Condition cond) {
+ int size = 2 * kInstrSize;
+ Instr mov_instr = cond | MOV | LeaveCC;
+ intptr_t immediate = reinterpret_cast<intptr_t>(target);
+ if (!Operand(immediate, rmode).is_single_instruction(NULL, mov_instr)) {
size += kInstrSize;
}
return size;
@@ -146,15 +158,29 @@ int MacroAssembler::CallSize(
void MacroAssembler::Call(Address target,
RelocInfo::Mode rmode,
- Condition cond) {
+ Condition cond,
+ TargetAddressStorageMode mode) {
// Block constant pool for the call instruction sequence.
BlockConstPoolScope block_const_pool(this);
Label start;
bind(&start);
-#if USE_BLX
- // On ARMv5 and after the recommended call sequence is:
- // ldr ip, [pc, #...]
- // blx ip
+
+ bool old_predictable_code_size = predictable_code_size();
+ if (mode == NEVER_INLINE_TARGET_ADDRESS) {
+ set_predictable_code_size(true);
+ }
+
+#ifdef USE_BLX
+ // Call sequence on V7 or later may be :
+ // movw ip, #... @ call address low 16
+ // movt ip, #... @ call address high 16
+ // blx ip
+ // @ return address
+ // Or for pre-V7 or values that may be back-patched
+ // to avoid ICache flushes:
+ // ldr ip, [pc, #...] @ call address
+ // blx ip
+ // @ return address
// Statement positions are expected to be recorded when the target
// address is loaded. The mov method will automatically record
@@ -165,21 +191,22 @@ void MacroAssembler::Call(Address target,
mov(ip, Operand(reinterpret_cast<int32_t>(target), rmode));
blx(ip, cond);
- ASSERT(kCallTargetAddressOffset == 2 * kInstrSize);
#else
// Set lr for return at current pc + 8.
mov(lr, Operand(pc), LeaveCC, cond);
// Emit a ldr<cond> pc, [pc + offset of target in constant pool].
mov(pc, Operand(reinterpret_cast<int32_t>(target), rmode), LeaveCC, cond);
- ASSERT(kCallTargetAddressOffset == kInstrSize);
#endif
ASSERT_EQ(CallSize(target, rmode, cond), SizeOfCodeGeneratedSince(&start));
+ if (mode == NEVER_INLINE_TARGET_ADDRESS) {
+ set_predictable_code_size(old_predictable_code_size);
+ }
}
int MacroAssembler::CallSize(Handle<Code> code,
RelocInfo::Mode rmode,
- unsigned ast_id,
+ TypeFeedbackId ast_id,
Condition cond) {
return CallSize(reinterpret_cast<Address>(code.location()), rmode, cond);
}
@@ -187,19 +214,18 @@ int MacroAssembler::CallSize(Handle<Code> code,
void MacroAssembler::Call(Handle<Code> code,
RelocInfo::Mode rmode,
- unsigned ast_id,
- Condition cond) {
+ TypeFeedbackId ast_id,
+ Condition cond,
+ TargetAddressStorageMode mode) {
Label start;
bind(&start);
ASSERT(RelocInfo::IsCodeTarget(rmode));
- if (rmode == RelocInfo::CODE_TARGET && ast_id != kNoASTId) {
+ if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) {
SetRecordedAstId(ast_id);
rmode = RelocInfo::CODE_TARGET_WITH_ID;
}
// 'code' is always generated ARM code, never THUMB code
- Call(reinterpret_cast<Address>(code.location()), rmode, cond);
- ASSERT_EQ(CallSize(code, rmode, ast_id, cond),
- SizeOfCodeGeneratedSince(&start));
+ Call(reinterpret_cast<Address>(code.location()), rmode, cond, mode);
}
@@ -276,17 +302,15 @@ void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) {
void MacroAssembler::And(Register dst, Register src1, const Operand& src2,
Condition cond) {
if (!src2.is_reg() &&
- !src2.must_use_constant_pool() &&
+ !src2.must_output_reloc_info(this) &&
src2.immediate() == 0) {
mov(dst, Operand(0, RelocInfo::NONE), LeaveCC, cond);
-
- } else if (!src2.is_single_instruction() &&
- !src2.must_use_constant_pool() &&
+ } else if (!src2.is_single_instruction(this) &&
+ !src2.must_output_reloc_info(this) &&
CpuFeatures::IsSupported(ARMv7) &&
IsPowerOf2(src2.immediate() + 1)) {
ubfx(dst, src1, 0,
WhichPowerOf2(static_cast<uint32_t>(src2.immediate()) + 1), cond);
-
} else {
and_(dst, src1, src2, LeaveCC, cond);
}
@@ -296,7 +320,7 @@ void MacroAssembler::And(Register dst, Register src1, const Operand& src2,
void MacroAssembler::Ubfx(Register dst, Register src1, int lsb, int width,
Condition cond) {
ASSERT(lsb < 32);
- if (!CpuFeatures::IsSupported(ARMv7)) {
+ if (!CpuFeatures::IsSupported(ARMv7) || predictable_code_size()) {
int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1);
and_(dst, src1, Operand(mask), LeaveCC, cond);
if (lsb != 0) {
@@ -311,7 +335,7 @@ void MacroAssembler::Ubfx(Register dst, Register src1, int lsb, int width,
void MacroAssembler::Sbfx(Register dst, Register src1, int lsb, int width,
Condition cond) {
ASSERT(lsb < 32);
- if (!CpuFeatures::IsSupported(ARMv7)) {
+ if (!CpuFeatures::IsSupported(ARMv7) || predictable_code_size()) {
int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1);
and_(dst, src1, Operand(mask), LeaveCC, cond);
int shift_up = 32 - lsb - width;
@@ -339,7 +363,7 @@ void MacroAssembler::Bfi(Register dst,
ASSERT(lsb + width < 32);
ASSERT(!scratch.is(dst));
if (width == 0) return;
- if (!CpuFeatures::IsSupported(ARMv7)) {
+ if (!CpuFeatures::IsSupported(ARMv7) || predictable_code_size()) {
int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1);
bic(dst, dst, Operand(mask));
and_(scratch, src, Operand((1 << width) - 1));
@@ -351,12 +375,14 @@ void MacroAssembler::Bfi(Register dst,
}
-void MacroAssembler::Bfc(Register dst, int lsb, int width, Condition cond) {
+void MacroAssembler::Bfc(Register dst, Register src, int lsb, int width,
+ Condition cond) {
ASSERT(lsb < 32);
- if (!CpuFeatures::IsSupported(ARMv7)) {
+ if (!CpuFeatures::IsSupported(ARMv7) || predictable_code_size()) {
int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1);
- bic(dst, dst, Operand(mask));
+ bic(dst, src, Operand(mask));
} else {
+ Move(dst, src, cond);
bfc(dst, lsb, width, cond);
}
}
@@ -364,7 +390,7 @@ void MacroAssembler::Bfc(Register dst, int lsb, int width, Condition cond) {
void MacroAssembler::Usat(Register dst, int satpos, const Operand& src,
Condition cond) {
- if (!CpuFeatures::IsSupported(ARMv7)) {
+ if (!CpuFeatures::IsSupported(ARMv7) || predictable_code_size()) {
ASSERT(!dst.is(pc) && !src.rm().is(pc));
ASSERT((satpos >= 0) && (satpos <= 31));
@@ -672,7 +698,7 @@ void MacroAssembler::Ldrd(Register dst1, Register dst2,
ASSERT((src.am() != PreIndex) && (src.am() != NegPreIndex));
// Generate two ldr instructions if ldrd is not available.
- if (CpuFeatures::IsSupported(ARMv7)) {
+ if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) {
CpuFeatures::Scope scope(ARMv7);
ldrd(dst1, dst2, src, cond);
} else {
@@ -714,7 +740,7 @@ void MacroAssembler::Strd(Register src1, Register src2,
ASSERT((dst.am() != PreIndex) && (dst.am() != NegPreIndex));
// Generate two str instructions if strd is not available.
- if (CpuFeatures::IsSupported(ARMv7)) {
+ if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) {
CpuFeatures::Scope scope(ARMv7);
strd(src1, src2, dst, cond);
} else {
@@ -777,6 +803,7 @@ void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
void MacroAssembler::Vmov(const DwVfpRegister dst,
const double imm,
+ const Register scratch,
const Condition cond) {
ASSERT(CpuFeatures::IsEnabled(VFP2));
static const DoubleRepresentation minus_zero(-0.0);
@@ -788,7 +815,7 @@ void MacroAssembler::Vmov(const DwVfpRegister dst,
} else if (value.bits == minus_zero.bits) {
vneg(dst, kDoubleRegZero, cond);
} else {
- vmov(dst, imm, cond);
+ vmov(dst, imm, scratch, cond);
}
}
@@ -1339,31 +1366,32 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
Check(ne, "we should not have an empty lexical context");
#endif
- // Load the global context of the current context.
- int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ // Load the native context of the current context.
+ int offset =
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
ldr(scratch, FieldMemOperand(scratch, offset));
- ldr(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
+ ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
- // Check the context is a global context.
+ // Check the context is a native context.
if (emit_debug_code()) {
// TODO(119): avoid push(holder_reg)/pop(holder_reg)
// Cannot use ip as a temporary in this verification code. Due to the fact
// that ip is clobbered as part of cmp with an object Operand.
push(holder_reg); // Temporarily save holder on the stack.
- // Read the first word and compare to the global_context_map.
+ // Read the first word and compare to the native_context_map.
ldr(holder_reg, FieldMemOperand(scratch, HeapObject::kMapOffset));
- LoadRoot(ip, Heap::kGlobalContextMapRootIndex);
+ LoadRoot(ip, Heap::kNativeContextMapRootIndex);
cmp(holder_reg, ip);
- Check(eq, "JSGlobalObject::global_context should be a global context.");
+ Check(eq, "JSGlobalObject::native_context should be a native context.");
pop(holder_reg); // Restore holder.
}
// Check if both contexts are the same.
- ldr(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kContextOffset));
+ ldr(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
cmp(scratch, Operand(ip));
b(eq, &same_contexts);
- // Check the context is a global context.
+ // Check the context is a native context.
if (emit_debug_code()) {
// TODO(119): avoid push(holder_reg)/pop(holder_reg)
// Cannot use ip as a temporary in this verification code. Due to the fact
@@ -1375,13 +1403,13 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
Check(ne, "JSGlobalProxy::context() should not be null.");
ldr(holder_reg, FieldMemOperand(holder_reg, HeapObject::kMapOffset));
- LoadRoot(ip, Heap::kGlobalContextMapRootIndex);
+ LoadRoot(ip, Heap::kNativeContextMapRootIndex);
cmp(holder_reg, ip);
- Check(eq, "JSGlobalObject::global_context should be a global context.");
+ Check(eq, "JSGlobalObject::native_context should be a native context.");
// Restore ip is not needed. ip is reloaded below.
pop(holder_reg); // Restore holder.
// Restore ip to holder's context.
- ldr(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kContextOffset));
+ ldr(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
}
// Check that the security token in the calling global object is
@@ -1554,7 +1582,11 @@ void MacroAssembler::AllocateInNewSpace(int object_size,
Register topaddr = scratch1;
Register obj_size_reg = scratch2;
mov(topaddr, Operand(new_space_allocation_top));
- mov(obj_size_reg, Operand(object_size));
+ Operand obj_size_operand = Operand(object_size);
+ if (!obj_size_operand.is_single_instruction(this)) {
+ // We are about to steal IP, so we need to load this value first
+ mov(obj_size_reg, obj_size_operand);
+ }
// This code stores a temporary value in ip. This is OK, as the code below
// does not need ip for implicit literal generation.
@@ -1576,7 +1608,13 @@ void MacroAssembler::AllocateInNewSpace(int object_size,
// Calculate new top and bail out if new space is exhausted. Use result
// to calculate the new top.
- add(scratch2, result, Operand(obj_size_reg), SetCC);
+ if (obj_size_operand.is_single_instruction(this)) {
+ // We can add the size as an immediate
+ add(scratch2, result, obj_size_operand, SetCC);
+ } else {
+ // Doesn't fit in an immediate, we have to use the register
+ add(scratch2, result, obj_size_reg, SetCC);
+ }
b(cs, gc_required);
cmp(scratch2, Operand(ip));
b(hi, gc_required);
@@ -1974,7 +2012,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
destination = FloatingPointHelper::kCoreRegisters;
}
- Register untagged_value = receiver_reg;
+ Register untagged_value = elements_reg;
SmiUntag(untagged_value, value_reg);
FloatingPointHelper::ConvertIntToDouble(this,
untagged_value,
@@ -2136,7 +2174,7 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
void MacroAssembler::CallStub(CodeStub* stub, Condition cond) {
ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
- Call(stub->GetCode(), RelocInfo::CODE_TARGET, kNoASTId, cond);
+ Call(stub->GetCode(), RelocInfo::CODE_TARGET, TypeFeedbackId::None(), cond);
}
@@ -2423,16 +2461,27 @@ void MacroAssembler::ConvertToInt32(Register source,
void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode,
- SwVfpRegister result,
+ Register result,
DwVfpRegister double_input,
- Register scratch1,
- Register scratch2,
+ Register scratch,
+ DwVfpRegister double_scratch,
CheckForInexactConversion check_inexact) {
+ ASSERT(!result.is(scratch));
+ ASSERT(!double_input.is(double_scratch));
+
ASSERT(CpuFeatures::IsSupported(VFP2));
CpuFeatures::Scope scope(VFP2);
- Register prev_fpscr = scratch1;
- Register scratch = scratch2;
+ Register prev_fpscr = result;
+ Label done;
+
+ // Test for values that can be exactly represented as a signed 32-bit integer.
+ vcvt_s32_f64(double_scratch.low(), double_input);
+ vmov(result, double_scratch.low());
+ vcvt_f64_s32(double_scratch, double_scratch.low());
+ VFPCompareAndSetFlags(double_input, double_scratch);
+ b(eq, &done);
+ // Convert to integer, respecting rounding mode.
int32_t check_inexact_conversion =
(check_inexact == kCheckForInexactConversion) ? kVFPInexactExceptionBit : 0;
@@ -2454,7 +2503,7 @@ void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode,
vmsr(scratch);
// Convert the argument to an integer.
- vcvt_s32_f64(result,
+ vcvt_s32_f64(double_scratch.low(),
double_input,
(rounding_mode == kRoundToZero) ? kDefaultRoundToZero
: kFPSCRRounding);
@@ -2463,8 +2512,12 @@ void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode,
vmrs(scratch);
// Restore FPSCR.
vmsr(prev_fpscr);
+ // Move the converted value into the result register.
+ vmov(result, double_scratch.low());
// Check for vfp exceptions.
tst(scratch, Operand(kVFPExceptionMask | check_inexact_conversion));
+
+ bind(&done);
}
@@ -2586,7 +2639,7 @@ void MacroAssembler::EmitECMATruncate(Register result,
void MacroAssembler::GetLeastBitsFromSmi(Register dst,
Register src,
int num_least_bits) {
- if (CpuFeatures::IsSupported(ARMv7)) {
+ if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) {
ubfx(dst, src, kSmiTagSize, num_least_bits);
} else {
mov(dst, Operand(src, ASR, kSmiTagSize));
@@ -2704,7 +2757,8 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
void MacroAssembler::GetBuiltinFunction(Register target,
Builtins::JavaScript id) {
// Load the builtins object into target register.
- ldr(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ ldr(target,
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
ldr(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
// Load the JavaScript builtin function from the builtins object.
ldr(target, FieldMemOperand(target,
@@ -2870,8 +2924,9 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
Register scratch,
Label* no_map_match) {
// Load the global or builtins object from the current context.
- ldr(scratch, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- ldr(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
+ ldr(scratch,
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
// Check that the function's map is the same as the expected cached map.
ldr(scratch,
@@ -2917,11 +2972,12 @@ void MacroAssembler::LoadInitialArrayMap(
void MacroAssembler::LoadGlobalFunction(int index, Register function) {
// Load the global or builtins object from the current context.
- ldr(function, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- // Load the global context from the global or builtins object.
+ ldr(function,
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ // Load the native context from the global or builtins object.
ldr(function, FieldMemOperand(function,
- GlobalObject::kGlobalContextOffset));
- // Load the function from the global context.
+ GlobalObject::kNativeContextOffset));
+ // Load the function from the native context.
ldr(function, MemOperand(function, Context::SlotOffset(index)));
}
@@ -3001,38 +3057,46 @@ void MacroAssembler::JumpIfEitherSmi(Register reg1,
}
-void MacroAssembler::AbortIfSmi(Register object) {
- STATIC_ASSERT(kSmiTag == 0);
- tst(object, Operand(kSmiTagMask));
- Assert(ne, "Operand is a smi");
+void MacroAssembler::AssertNotSmi(Register object) {
+ if (emit_debug_code()) {
+ STATIC_ASSERT(kSmiTag == 0);
+ tst(object, Operand(kSmiTagMask));
+ Check(ne, "Operand is a smi");
+ }
}
-void MacroAssembler::AbortIfNotSmi(Register object) {
- STATIC_ASSERT(kSmiTag == 0);
- tst(object, Operand(kSmiTagMask));
- Assert(eq, "Operand is not smi");
+void MacroAssembler::AssertSmi(Register object) {
+ if (emit_debug_code()) {
+ STATIC_ASSERT(kSmiTag == 0);
+ tst(object, Operand(kSmiTagMask));
+ Check(eq, "Operand is not smi");
+ }
}
-void MacroAssembler::AbortIfNotString(Register object) {
- STATIC_ASSERT(kSmiTag == 0);
- tst(object, Operand(kSmiTagMask));
- Assert(ne, "Operand is not a string");
- push(object);
- ldr(object, FieldMemOperand(object, HeapObject::kMapOffset));
- CompareInstanceType(object, object, FIRST_NONSTRING_TYPE);
- pop(object);
- Assert(lo, "Operand is not a string");
+void MacroAssembler::AssertString(Register object) {
+ if (emit_debug_code()) {
+ STATIC_ASSERT(kSmiTag == 0);
+ tst(object, Operand(kSmiTagMask));
+ Check(ne, "Operand is a smi and not a string");
+ push(object);
+ ldr(object, FieldMemOperand(object, HeapObject::kMapOffset));
+ CompareInstanceType(object, object, FIRST_NONSTRING_TYPE);
+ pop(object);
+ Check(lo, "Operand is not a string");
+ }
}
-void MacroAssembler::AbortIfNotRootValue(Register src,
- Heap::RootListIndex root_value_index,
- const char* message) {
- CompareRoot(src, root_value_index);
- Assert(eq, message);
+void MacroAssembler::AssertRootValue(Register src,
+ Heap::RootListIndex root_value_index,
+ const char* message) {
+ if (emit_debug_code()) {
+ CompareRoot(src, root_value_index);
+ Check(eq, message);
+ }
}
@@ -3090,7 +3154,8 @@ void MacroAssembler::AllocateHeapNumber(Register result,
Register scratch1,
Register scratch2,
Register heap_number_map,
- Label* gc_required) {
+ Label* gc_required,
+ TaggingMode tagging_mode) {
// Allocate an object in the heap for the heap number and tag it as a heap
// object.
AllocateInNewSpace(HeapNumber::kSize,
@@ -3098,11 +3163,16 @@ void MacroAssembler::AllocateHeapNumber(Register result,
scratch1,
scratch2,
gc_required,
- TAG_OBJECT);
+ tagging_mode == TAG_RESULT ? TAG_OBJECT :
+ NO_ALLOCATION_FLAGS);
// Store heap number map in the allocated object.
AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
- str(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset));
+ if (tagging_mode == TAG_RESULT) {
+ str(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset));
+ } else {
+ str(heap_number_map, MemOperand(result, HeapObject::kMapOffset));
+ }
}
@@ -3173,17 +3243,17 @@ void MacroAssembler::CopyBytes(Register src,
cmp(length, Operand(kPointerSize));
b(lt, &byte_loop);
ldr(scratch, MemOperand(src, kPointerSize, PostIndex));
-#if CAN_USE_UNALIGNED_ACCESSES
- str(scratch, MemOperand(dst, kPointerSize, PostIndex));
-#else
- strb(scratch, MemOperand(dst, 1, PostIndex));
- mov(scratch, Operand(scratch, LSR, 8));
- strb(scratch, MemOperand(dst, 1, PostIndex));
- mov(scratch, Operand(scratch, LSR, 8));
- strb(scratch, MemOperand(dst, 1, PostIndex));
- mov(scratch, Operand(scratch, LSR, 8));
- strb(scratch, MemOperand(dst, 1, PostIndex));
-#endif
+ if (CpuFeatures::IsSupported(UNALIGNED_ACCESSES)) {
+ str(scratch, MemOperand(dst, kPointerSize, PostIndex));
+ } else {
+ strb(scratch, MemOperand(dst, 1, PostIndex));
+ mov(scratch, Operand(scratch, LSR, 8));
+ strb(scratch, MemOperand(dst, 1, PostIndex));
+ mov(scratch, Operand(scratch, LSR, 8));
+ strb(scratch, MemOperand(dst, 1, PostIndex));
+ mov(scratch, Operand(scratch, LSR, 8));
+ strb(scratch, MemOperand(dst, 1, PostIndex));
+ }
sub(length, length, Operand(kPointerSize));
b(&word_loop);
@@ -3465,7 +3535,7 @@ void MacroAssembler::CheckPageFlag(
int mask,
Condition cc,
Label* condition_met) {
- and_(scratch, object, Operand(~Page::kPageAlignmentMask));
+ Bfc(scratch, object, 0, kPageSizeBits);
ldr(scratch, MemOperand(scratch, MemoryChunk::kFlagsOffset));
tst(scratch, Operand(mask));
b(cc, condition_met);
@@ -3660,7 +3730,7 @@ void MacroAssembler::ClampDoubleToUint8(Register result_reg,
// Double value is >= 255, return 255.
bind(&above_zero);
- Vmov(temp_double_reg, 255.0);
+ Vmov(temp_double_reg, 255.0, result_reg);
VFPCompareAndSetFlags(input_reg, temp_double_reg);
b(le, &in_bounds);
mov(result_reg, Operand(255));
@@ -3668,67 +3738,72 @@ void MacroAssembler::ClampDoubleToUint8(Register result_reg,
// In 0-255 range, round and truncate.
bind(&in_bounds);
- Vmov(temp_double_reg, 0.5);
- vadd(temp_double_reg, input_reg, temp_double_reg);
- vcvt_u32_f64(temp_double_reg.low(), temp_double_reg);
- vmov(result_reg, temp_double_reg.low());
+ // Save FPSCR.
+ vmrs(ip);
+ // Set rounding mode to round to the nearest integer by clearing bits[23:22].
+ bic(result_reg, ip, Operand(kVFPRoundingModeMask));
+ vmsr(result_reg);
+ vcvt_s32_f64(input_reg.low(), input_reg, kFPSCRRounding);
+ vmov(result_reg, input_reg.low());
+ // Restore FPSCR.
+ vmsr(ip);
bind(&done);
}
void MacroAssembler::LoadInstanceDescriptors(Register map,
Register descriptors) {
- ldr(descriptors,
- FieldMemOperand(map, Map::kInstanceDescriptorsOrBitField3Offset));
- Label not_smi;
- JumpIfNotSmi(descriptors, &not_smi);
- mov(descriptors, Operand(FACTORY->empty_descriptor_array()));
- bind(&not_smi);
+ ldr(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset));
+}
+
+
+void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
+ ldr(dst, FieldMemOperand(map, Map::kBitField3Offset));
+ DecodeField<Map::NumberOfOwnDescriptorsBits>(dst);
+}
+
+
+void MacroAssembler::EnumLength(Register dst, Register map) {
+ STATIC_ASSERT(Map::EnumLengthBits::kShift == 0);
+ ldr(dst, FieldMemOperand(map, Map::kBitField3Offset));
+ and_(dst, dst, Operand(Smi::FromInt(Map::EnumLengthBits::kMask)));
}
void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
- Label next;
- // Preload a couple of values used in the loop.
Register empty_fixed_array_value = r6;
LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
- Register empty_descriptor_array_value = r7;
- LoadRoot(empty_descriptor_array_value,
- Heap::kEmptyDescriptorArrayRootIndex);
- mov(r1, r0);
- bind(&next);
+ Label next, start;
+ mov(r2, r0);
- // Check that there are no elements. Register r1 contains the
- // current JS object we've reached through the prototype chain.
- ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset));
- cmp(r2, empty_fixed_array_value);
- b(ne, call_runtime);
+ // Check if the enum length field is properly initialized, indicating that
+ // there is an enum cache.
+ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
+
+ EnumLength(r3, r1);
+ cmp(r3, Operand(Smi::FromInt(Map::kInvalidEnumCache)));
+ b(eq, call_runtime);
- // Check that instance descriptors are not empty so that we can
- // check for an enum cache. Leave the map in r2 for the subsequent
- // prototype load.
- ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
- ldr(r3, FieldMemOperand(r2, Map::kInstanceDescriptorsOrBitField3Offset));
- JumpIfSmi(r3, call_runtime);
+ jmp(&start);
- // Check that there is an enum cache in the non-empty instance
- // descriptors (r3). This is the case if the next enumeration
- // index field does not contain a smi.
- ldr(r3, FieldMemOperand(r3, DescriptorArray::kEnumerationIndexOffset));
- JumpIfSmi(r3, call_runtime);
+ bind(&next);
+ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
// For all objects but the receiver, check that the cache is empty.
- Label check_prototype;
- cmp(r1, r0);
- b(eq, &check_prototype);
- ldr(r3, FieldMemOperand(r3, DescriptorArray::kEnumCacheBridgeCacheOffset));
- cmp(r3, empty_fixed_array_value);
+ EnumLength(r3, r1);
+ cmp(r3, Operand(Smi::FromInt(0)));
+ b(ne, call_runtime);
+
+ bind(&start);
+
+ // Check that there are no elements. Register r2 contains the current JS
+ // object we've reached through the prototype chain.
+ ldr(r2, FieldMemOperand(r2, JSObject::kElementsOffset));
+ cmp(r2, empty_fixed_array_value);
b(ne, call_runtime);
- // Load the prototype from the map and loop if non-null.
- bind(&check_prototype);
- ldr(r1, FieldMemOperand(r2, Map::kPrototypeOffset));
- cmp(r1, null_value);
+ ldr(r2, FieldMemOperand(r1, Map::kPrototypeOffset));
+ cmp(r2, null_value);
b(ne, &next);
}
diff --git a/deps/v8/src/arm/macro-assembler-arm.h b/deps/v8/src/arm/macro-assembler-arm.h
index 6b7d11635..e3e39a387 100644
--- a/deps/v8/src/arm/macro-assembler-arm.h
+++ b/deps/v8/src/arm/macro-assembler-arm.h
@@ -68,6 +68,13 @@ enum AllocationFlags {
SIZE_IN_WORDS = 1 << 2
};
+// Flags used for AllocateHeapNumber
+enum TaggingMode {
+ // Tag the result.
+ TAG_RESULT,
+ // Don't tag
+ DONT_TAG_RESULT
+};
// Flags used for the ObjectToDoubleVFPRegister function.
enum ObjectToDoubleFlags {
@@ -95,6 +102,11 @@ bool AreAliased(Register reg1,
#endif
+enum TargetAddressStorageMode {
+ CAN_INLINE_TARGET_ADDRESS,
+ NEVER_INLINE_TARGET_ADDRESS
+};
+
// MacroAssembler implements a collection of frequently used macros.
class MacroAssembler: public Assembler {
public:
@@ -110,18 +122,22 @@ class MacroAssembler: public Assembler {
void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
static int CallSize(Register target, Condition cond = al);
void Call(Register target, Condition cond = al);
- static int CallSize(Address target,
- RelocInfo::Mode rmode,
- Condition cond = al);
- void Call(Address target, RelocInfo::Mode rmode, Condition cond = al);
- static int CallSize(Handle<Code> code,
- RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
- unsigned ast_id = kNoASTId,
- Condition cond = al);
+ int CallSize(Address target, RelocInfo::Mode rmode, Condition cond = al);
+ static int CallSizeNotPredictableCodeSize(Address target,
+ RelocInfo::Mode rmode,
+ Condition cond = al);
+ void Call(Address target, RelocInfo::Mode rmode,
+ Condition cond = al,
+ TargetAddressStorageMode mode = CAN_INLINE_TARGET_ADDRESS);
+ int CallSize(Handle<Code> code,
+ RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
+ TypeFeedbackId ast_id = TypeFeedbackId::None(),
+ Condition cond = al);
void Call(Handle<Code> code,
RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
- unsigned ast_id = kNoASTId,
- Condition cond = al);
+ TypeFeedbackId ast_id = TypeFeedbackId::None(),
+ Condition cond = al,
+ TargetAddressStorageMode mode = CAN_INLINE_TARGET_ADDRESS);
void Ret(Condition cond = al);
// Emit code to discard a non-negative number of pointer-sized elements
@@ -153,7 +169,7 @@ class MacroAssembler: public Assembler {
int lsb,
int width,
Condition cond = al);
- void Bfc(Register dst, int lsb, int width, Condition cond = al);
+ void Bfc(Register dst, Register src, int lsb, int width, Condition cond = al);
void Usat(Register dst, int satpos, const Operand& src,
Condition cond = al);
@@ -482,6 +498,7 @@ class MacroAssembler: public Assembler {
void Vmov(const DwVfpRegister dst,
const double imm,
+ const Register scratch = no_reg,
const Condition cond = al);
// Enter exit frame.
@@ -499,8 +516,8 @@ class MacroAssembler: public Assembler {
void LoadContext(Register dst, int context_chain_length);
// Conditionally load the cached Array transitioned map of type
- // transitioned_kind from the global context if the map in register
- // map_in_out is the cached Array map in the global context of
+ // transitioned_kind from the native context if the map in register
+ // map_in_out is the cached Array map in the native context of
// expected_kind.
void LoadTransitionedArrayMapConditional(
ElementsKind expected_kind,
@@ -729,7 +746,8 @@ class MacroAssembler: public Assembler {
Register scratch1,
Register scratch2,
Register heap_number_map,
- Label* gc_required);
+ Label* gc_required,
+ TaggingMode tagging_mode = TAG_RESULT);
void AllocateHeapNumberWithValue(Register result,
DwVfpRegister value,
Register scratch1,
@@ -814,6 +832,7 @@ class MacroAssembler: public Assembler {
void StoreNumberToDoubleElements(Register value_reg,
Register key_reg,
Register receiver_reg,
+ // All regs below here overwritten.
Register elements_reg,
Register scratch1,
Register scratch2,
@@ -936,21 +955,22 @@ class MacroAssembler: public Assembler {
DwVfpRegister double_scratch,
Label *not_int32);
- // Truncates a double using a specific rounding mode.
+ // Truncates a double using a specific rounding mode, and writes the value
+ // to the result register.
// Clears the z flag (ne condition) if an overflow occurs.
- // If exact_conversion is true, the z flag is also cleared if the conversion
- // was inexact, i.e. if the double value could not be converted exactly
- // to a 32bit integer.
+ // If kCheckForInexactConversion is passed, the z flag is also cleared if the
+ // conversion was inexact, i.e. if the double value could not be converted
+ // exactly to a 32-bit integer.
void EmitVFPTruncate(VFPRoundingMode rounding_mode,
- SwVfpRegister result,
+ Register result,
DwVfpRegister double_input,
- Register scratch1,
- Register scratch2,
+ Register scratch,
+ DwVfpRegister double_scratch,
CheckForInexactConversion check
= kDontCheckForInexactConversion);
// Helper for EmitECMATruncate.
- // This will truncate a floating-point value outside of the singed 32bit
+ // This will truncate a floating-point value outside of the signed 32bit
// integer range to a 32bit signed integer.
// Expects the double value loaded in input_high and input_low.
// Exits with the answer in 'result'.
@@ -1197,17 +1217,18 @@ class MacroAssembler: public Assembler {
// Jump if either of the registers contain a smi.
void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
- // Abort execution if argument is a smi. Used in debug code.
- void AbortIfSmi(Register object);
- void AbortIfNotSmi(Register object);
+ // Abort execution if argument is a smi, enabled via --debug-code.
+ void AssertNotSmi(Register object);
+ void AssertSmi(Register object);
- // Abort execution if argument is a string. Used in debug code.
- void AbortIfNotString(Register object);
+ // Abort execution if argument is a string, enabled via --debug-code.
+ void AssertString(Register object);
- // Abort execution if argument is not the root value with the given index.
- void AbortIfNotRootValue(Register src,
- Heap::RootListIndex root_value_index,
- const char* message);
+ // Abort execution if argument is not the root value with the given index,
+ // enabled via --debug-code.
+ void AssertRootValue(Register src,
+ Heap::RootListIndex root_value_index,
+ const char* message);
// ---------------------------------------------------------------------------
// HeapNumber utilities
@@ -1269,6 +1290,16 @@ class MacroAssembler: public Assembler {
void LoadInstanceDescriptors(Register map, Register descriptors);
+ void EnumLength(Register dst, Register map);
+ void NumberOfOwnDescriptors(Register dst, Register map);
+
+ template<typename Field>
+ void DecodeField(Register reg) {
+ static const int shift = Field::kShift;
+ static const int mask = (Field::kMask >> shift) << kSmiTagSize;
+ mov(reg, Operand(reg, LSR, shift));
+ and_(reg, reg, Operand(mask));
+ }
// Activation support.
void EnterFrame(StackFrame::Type type);
@@ -1376,7 +1407,7 @@ inline MemOperand ContextOperand(Register context, int index) {
inline MemOperand GlobalObjectOperand() {
- return ContextOperand(cp, Context::GLOBAL_INDEX);
+ return ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX);
}
diff --git a/deps/v8/src/arm/regexp-macro-assembler-arm.cc b/deps/v8/src/arm/regexp-macro-assembler-arm.cc
index 66cdd8435..17b867784 100644
--- a/deps/v8/src/arm/regexp-macro-assembler-arm.cc
+++ b/deps/v8/src/arm/regexp-macro-assembler-arm.cc
@@ -1358,6 +1358,11 @@ void RegExpMacroAssemblerARM::CallCFunctionUsingStub(
}
+bool RegExpMacroAssemblerARM::CanReadUnaligned() {
+ return CpuFeatures::IsSupported(UNALIGNED_ACCESSES) && !slow_safe();
+}
+
+
void RegExpMacroAssemblerARM::LoadCurrentCharacterUnchecked(int cp_offset,
int characters) {
Register offset = current_input_offset();
@@ -1370,9 +1375,9 @@ void RegExpMacroAssemblerARM::LoadCurrentCharacterUnchecked(int cp_offset,
// and the operating system running on the target allow it.
// If unaligned load/stores are not supported then this function must only
// be used to load a single character at a time.
-#if !V8_TARGET_CAN_READ_UNALIGNED
- ASSERT(characters == 1);
-#endif
+ if (!CanReadUnaligned()) {
+ ASSERT(characters == 1);
+ }
if (mode_ == ASCII) {
if (characters == 4) {
diff --git a/deps/v8/src/arm/regexp-macro-assembler-arm.h b/deps/v8/src/arm/regexp-macro-assembler-arm.h
index 9bebb4d40..c45669ae8 100644
--- a/deps/v8/src/arm/regexp-macro-assembler-arm.h
+++ b/deps/v8/src/arm/regexp-macro-assembler-arm.h
@@ -35,14 +35,7 @@ namespace v8 {
namespace internal {
-#ifdef V8_INTERPRETED_REGEXP
-class RegExpMacroAssemblerARM: public RegExpMacroAssembler {
- public:
- RegExpMacroAssemblerARM();
- virtual ~RegExpMacroAssemblerARM();
-};
-
-#else // V8_INTERPRETED_REGEXP
+#ifndef V8_INTERPRETED_REGEXP
class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler {
public:
RegExpMacroAssemblerARM(Mode mode, int registers_to_save, Zone* zone);
@@ -116,6 +109,7 @@ class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler {
virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
virtual void ClearRegisters(int reg_from, int reg_to);
virtual void WriteStackPointerToRegister(int reg);
+ virtual bool CanReadUnaligned();
// Called from RegExp if the stack-guard is triggered.
// If the code object is relocated, the return address is fixed before
diff --git a/deps/v8/src/arm/simulator-arm.cc b/deps/v8/src/arm/simulator-arm.cc
index 629c209ea..5b8ba2ada 100644
--- a/deps/v8/src/arm/simulator-arm.cc
+++ b/deps/v8/src/arm/simulator-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -276,7 +276,7 @@ void ArmDebugger::Debug() {
// make them invisible to all commands.
UndoBreakpoints();
- while (!done) {
+ while (!done && !sim_->has_bad_pc()) {
if (last_pc != sim_->get_pc()) {
disasm::NameConverter converter;
disasm::Disassembler dasm(converter);
@@ -945,73 +945,31 @@ unsigned int Simulator::get_s_register(int sreg) const {
}
-void Simulator::set_s_register_from_float(int sreg, const float flt) {
- ASSERT((sreg >= 0) && (sreg < num_s_registers));
- // Read the bits from the single precision floating point value
- // into the unsigned integer element of vfp_register[] given by index=sreg.
- char buffer[sizeof(vfp_register[0])];
- memcpy(buffer, &flt, sizeof(vfp_register[0]));
- memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0]));
-}
-
-
-void Simulator::set_s_register_from_sinteger(int sreg, const int sint) {
- ASSERT((sreg >= 0) && (sreg < num_s_registers));
- // Read the bits from the integer value into the unsigned integer element of
- // vfp_register[] given by index=sreg.
- char buffer[sizeof(vfp_register[0])];
- memcpy(buffer, &sint, sizeof(vfp_register[0]));
- memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0]));
-}
-
-
-void Simulator::set_d_register_from_double(int dreg, const double& dbl) {
- ASSERT((dreg >= 0) && (dreg < num_d_registers));
- // Read the bits from the double precision floating point value into the two
- // consecutive unsigned integer elements of vfp_register[] given by index
- // 2*sreg and 2*sreg+1.
- char buffer[2 * sizeof(vfp_register[0])];
- memcpy(buffer, &dbl, 2 * sizeof(vfp_register[0]));
- memcpy(&vfp_register[dreg * 2], buffer, 2 * sizeof(vfp_register[0]));
-}
-
+template<class InputType, int register_size>
+void Simulator::SetVFPRegister(int reg_index, const InputType& value) {
+ ASSERT(reg_index >= 0);
+ if (register_size == 1) ASSERT(reg_index < num_s_registers);
+ if (register_size == 2) ASSERT(reg_index < num_d_registers);
-float Simulator::get_float_from_s_register(int sreg) {
- ASSERT((sreg >= 0) && (sreg < num_s_registers));
-
- float sm_val = 0.0;
- // Read the bits from the unsigned integer vfp_register[] array
- // into the single precision floating point value and return it.
- char buffer[sizeof(vfp_register[0])];
- memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0]));
- memcpy(&sm_val, buffer, sizeof(vfp_register[0]));
- return(sm_val);
+ char buffer[register_size * sizeof(vfp_register[0])];
+ memcpy(buffer, &value, register_size * sizeof(vfp_register[0]));
+ memcpy(&vfp_register[reg_index * register_size], buffer,
+ register_size * sizeof(vfp_register[0]));
}
-int Simulator::get_sinteger_from_s_register(int sreg) {
- ASSERT((sreg >= 0) && (sreg < num_s_registers));
+template<class ReturnType, int register_size>
+ReturnType Simulator::GetFromVFPRegister(int reg_index) {
+ ASSERT(reg_index >= 0);
+ if (register_size == 1) ASSERT(reg_index < num_s_registers);
+ if (register_size == 2) ASSERT(reg_index < num_d_registers);
- int sm_val = 0;
- // Read the bits from the unsigned integer vfp_register[] array
- // into the single precision floating point value and return it.
- char buffer[sizeof(vfp_register[0])];
- memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0]));
- memcpy(&sm_val, buffer, sizeof(vfp_register[0]));
- return(sm_val);
-}
-
-
-double Simulator::get_double_from_d_register(int dreg) {
- ASSERT((dreg >= 0) && (dreg < num_d_registers));
-
- double dm_val = 0.0;
- // Read the bits from the unsigned integer vfp_register[] array
- // into the double precision floating point value and return it.
- char buffer[2 * sizeof(vfp_register[0])];
- memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0]));
- memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0]));
- return(dm_val);
+ ReturnType value = 0;
+ char buffer[register_size * sizeof(vfp_register[0])];
+ memcpy(buffer, &vfp_register[register_size * reg_index],
+ register_size * sizeof(vfp_register[0]));
+ memcpy(&value, buffer, register_size * sizeof(vfp_register[0]));
+ return value;
}
@@ -1108,111 +1066,83 @@ void Simulator::TrashCallerSaveRegisters() {
int Simulator::ReadW(int32_t addr, Instruction* instr) {
-#if V8_TARGET_CAN_READ_UNALIGNED
- intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
- return *ptr;
-#else
- if ((addr & 3) == 0) {
+ if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
return *ptr;
+ } else {
+ PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
+ addr,
+ reinterpret_cast<intptr_t>(instr));
+ UNIMPLEMENTED();
+ return 0;
}
- PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
- addr,
- reinterpret_cast<intptr_t>(instr));
- UNIMPLEMENTED();
- return 0;
-#endif
}
void Simulator::WriteW(int32_t addr, int value, Instruction* instr) {
-#if V8_TARGET_CAN_READ_UNALIGNED
- intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
- *ptr = value;
- return;
-#else
- if ((addr & 3) == 0) {
+ if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
*ptr = value;
- return;
+ } else {
+ PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
+ addr,
+ reinterpret_cast<intptr_t>(instr));
+ UNIMPLEMENTED();
}
- PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
- addr,
- reinterpret_cast<intptr_t>(instr));
- UNIMPLEMENTED();
-#endif
}
uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) {
-#if V8_TARGET_CAN_READ_UNALIGNED
- uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
- return *ptr;
-#else
- if ((addr & 1) == 0) {
+ if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
return *ptr;
+ } else {
+ PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08"
+ V8PRIxPTR "\n",
+ addr,
+ reinterpret_cast<intptr_t>(instr));
+ UNIMPLEMENTED();
+ return 0;
}
- PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
- addr,
- reinterpret_cast<intptr_t>(instr));
- UNIMPLEMENTED();
- return 0;
-#endif
}
int16_t Simulator::ReadH(int32_t addr, Instruction* instr) {
-#if V8_TARGET_CAN_READ_UNALIGNED
- int16_t* ptr = reinterpret_cast<int16_t*>(addr);
- return *ptr;
-#else
- if ((addr & 1) == 0) {
+ if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
int16_t* ptr = reinterpret_cast<int16_t*>(addr);
return *ptr;
+ } else {
+ PrintF("Unaligned signed halfword read at 0x%08x\n", addr);
+ UNIMPLEMENTED();
+ return 0;
}
- PrintF("Unaligned signed halfword read at 0x%08x\n", addr);
- UNIMPLEMENTED();
- return 0;
-#endif
}
void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) {
-#if V8_TARGET_CAN_READ_UNALIGNED
- uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
- *ptr = value;
- return;
-#else
- if ((addr & 1) == 0) {
+ if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
*ptr = value;
- return;
+ } else {
+ PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08"
+ V8PRIxPTR "\n",
+ addr,
+ reinterpret_cast<intptr_t>(instr));
+ UNIMPLEMENTED();
}
- PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
- addr,
- reinterpret_cast<intptr_t>(instr));
- UNIMPLEMENTED();
-#endif
}
void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) {
-#if V8_TARGET_CAN_READ_UNALIGNED
- int16_t* ptr = reinterpret_cast<int16_t*>(addr);
- *ptr = value;
- return;
-#else
- if ((addr & 1) == 0) {
+ if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
int16_t* ptr = reinterpret_cast<int16_t*>(addr);
*ptr = value;
- return;
+ } else {
+ PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
+ addr,
+ reinterpret_cast<intptr_t>(instr));
+ UNIMPLEMENTED();
}
- PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
- addr,
- reinterpret_cast<intptr_t>(instr));
- UNIMPLEMENTED();
-#endif
}
@@ -1241,37 +1171,26 @@ void Simulator::WriteB(int32_t addr, int8_t value) {
int32_t* Simulator::ReadDW(int32_t addr) {
-#if V8_TARGET_CAN_READ_UNALIGNED
- int32_t* ptr = reinterpret_cast<int32_t*>(addr);
- return ptr;
-#else
- if ((addr & 3) == 0) {
+ if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
int32_t* ptr = reinterpret_cast<int32_t*>(addr);
return ptr;
+ } else {
+ PrintF("Unaligned read at 0x%08x\n", addr);
+ UNIMPLEMENTED();
+ return 0;
}
- PrintF("Unaligned read at 0x%08x\n", addr);
- UNIMPLEMENTED();
- return 0;
-#endif
}
void Simulator::WriteDW(int32_t addr, int32_t value1, int32_t value2) {
-#if V8_TARGET_CAN_READ_UNALIGNED
- int32_t* ptr = reinterpret_cast<int32_t*>(addr);
- *ptr++ = value1;
- *ptr = value2;
- return;
-#else
- if ((addr & 3) == 0) {
+ if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
int32_t* ptr = reinterpret_cast<int32_t*>(addr);
*ptr++ = value1;
*ptr = value2;
- return;
+ } else {
+ PrintF("Unaligned write at 0x%08x\n", addr);
+ UNIMPLEMENTED();
}
- PrintF("Unaligned write at 0x%08x\n", addr);
- UNIMPLEMENTED();
-#endif
}
@@ -2028,11 +1947,23 @@ void Simulator::DecodeType01(Instruction* instr) {
SetNZFlags(alu_out);
}
} else {
- // The MLA instruction description (A 4.1.28) refers to the order
- // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
- // Rn field to encode the Rd register and the Rd field to encode
- // the Rn register.
- Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
+ int rd = instr->RdValue();
+ int32_t acc_value = get_register(rd);
+ if (instr->Bit(22) == 0) {
+ // The MLA instruction description (A 4.1.28) refers to the order
+ // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
+ // Rn field to encode the Rd register and the Rd field to encode
+ // the Rn register.
+ // Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
+ int32_t mul_out = rm_val * rs_val;
+ int32_t result = acc_value + mul_out;
+ set_register(rn, result);
+ } else {
+ // Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd");
+ int32_t mul_out = rm_val * rs_val;
+ int32_t result = acc_value - mul_out;
+ set_register(rn, result);
+ }
}
} else {
// The signed/long multiply instructions use the terms RdHi and RdLo
@@ -2252,6 +2183,8 @@ void Simulator::DecodeType01(Instruction* instr) {
PrintF("%08x\n", instr->InstructionBits());
UNIMPLEMENTED();
}
+ } else if ((type == 1) && instr->IsNopType1()) {
+ // NOP.
} else {
int rd = instr->RdValue();
int rn = instr->RnValue();
@@ -2408,7 +2341,7 @@ void Simulator::DecodeType01(Instruction* instr) {
// Format(instr, "cmn'cond 'rn, 'imm");
alu_out = rn_val + shifter_operand;
SetNZFlags(alu_out);
- SetCFlag(!CarryFrom(rn_val, shifter_operand));
+ SetCFlag(CarryFrom(rn_val, shifter_operand));
SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
} else {
// Other instructions matching this pattern are handled in the
@@ -2588,6 +2521,25 @@ void Simulator::DecodeType3(Instruction* instr) {
break;
}
case db_x: {
+ if (FLAG_enable_sudiv) {
+ if (!instr->HasW()) {
+ if (instr->Bits(5, 4) == 0x1) {
+ if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) {
+ // sdiv (in V8 notation matching ARM ISA format) rn = rm/rs
+ // Format(instr, "'sdiv'cond'b 'rn, 'rm, 'rs);
+ int rm = instr->RmValue();
+ int32_t rm_val = get_register(rm);
+ int rs = instr->RsValue();
+ int32_t rs_val = get_register(rs);
+ int32_t ret_val = 0;
+ ASSERT(rs_val != 0);
+ ret_val = rm_val/rs_val;
+ set_register(rn, ret_val);
+ return;
+ }
+ }
+ }
+ }
// Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
addr = rn_val - shifter_operand;
if (instr->HasW()) {
diff --git a/deps/v8/src/arm/simulator-arm.h b/deps/v8/src/arm/simulator-arm.h
index d1cad15bd..abc91bbc4 100644
--- a/deps/v8/src/arm/simulator-arm.h
+++ b/deps/v8/src/arm/simulator-arm.h
@@ -163,12 +163,30 @@ class Simulator {
// Support for VFP.
void set_s_register(int reg, unsigned int value);
unsigned int get_s_register(int reg) const;
- void set_d_register_from_double(int dreg, const double& dbl);
- double get_double_from_d_register(int dreg);
- void set_s_register_from_float(int sreg, const float dbl);
- float get_float_from_s_register(int sreg);
- void set_s_register_from_sinteger(int reg, const int value);
- int get_sinteger_from_s_register(int reg);
+
+ void set_d_register_from_double(int dreg, const double& dbl) {
+ SetVFPRegister<double, 2>(dreg, dbl);
+ }
+
+ double get_double_from_d_register(int dreg) {
+ return GetFromVFPRegister<double, 2>(dreg);
+ }
+
+ void set_s_register_from_float(int sreg, const float flt) {
+ SetVFPRegister<float, 1>(sreg, flt);
+ }
+
+ float get_float_from_s_register(int sreg) {
+ return GetFromVFPRegister<float, 1>(sreg);
+ }
+
+ void set_s_register_from_sinteger(int sreg, const int sint) {
+ SetVFPRegister<int, 1>(sreg, sint);
+ }
+
+ int get_sinteger_from_s_register(int sreg) {
+ return GetFromVFPRegister<int, 1>(sreg);
+ }
// Special case of set_register and get_register to access the raw PC value.
void set_pc(int32_t value);
@@ -332,6 +350,12 @@ class Simulator {
void SetFpResult(const double& result);
void TrashCallerSaveRegisters();
+ template<class ReturnType, int register_size>
+ ReturnType GetFromVFPRegister(int reg_index);
+
+ template<class InputType, int register_size>
+ void SetVFPRegister(int reg_index, const InputType& value);
+
// Architecture state.
// Saturating instructions require a Q flag to indicate saturation.
// There is currently no way to read the CPSR directly, and thus read the Q
diff --git a/deps/v8/src/arm/stub-cache-arm.cc b/deps/v8/src/arm/stub-cache-arm.cc
index d5e312de5..d3b58624c 100644
--- a/deps/v8/src/arm/stub-cache-arm.cc
+++ b/deps/v8/src/arm/stub-cache-arm.cc
@@ -283,11 +283,12 @@ void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
int index,
Register prototype) {
// Load the global or builtins object from the current context.
- __ ldr(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- // Load the global context from the global or builtins object.
__ ldr(prototype,
- FieldMemOperand(prototype, GlobalObject::kGlobalContextOffset));
- // Load the function from the global context.
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ // Load the native context from the global or builtins object.
+ __ ldr(prototype,
+ FieldMemOperand(prototype, GlobalObject::kNativeContextOffset));
+ // Load the function from the native context.
__ ldr(prototype, MemOperand(prototype, Context::SlotOffset(index)));
// Load the initial map. The global functions all have initial maps.
__ ldr(prototype,
@@ -304,13 +305,14 @@ void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
Label* miss) {
Isolate* isolate = masm->isolate();
// Check we're still in the same context.
- __ ldr(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ Move(ip, isolate->global());
+ __ ldr(prototype,
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ Move(ip, isolate->global_object());
__ cmp(prototype, ip);
__ b(ne, miss);
// Get the global function with the given index.
Handle<JSFunction> function(
- JSFunction::cast(isolate->global_context()->get(index)));
+ JSFunction::cast(isolate->native_context()->get(index)));
// Load its initial map. The global functions all have initial maps.
__ Move(prototype, Handle<Map>(function->initial_map()));
// Load the prototype from the initial map.
@@ -1230,6 +1232,45 @@ void StubCompiler::GenerateLoadConstant(Handle<JSObject> object,
}
+void StubCompiler::GenerateDictionaryLoadCallback(Register receiver,
+ Register name_reg,
+ Register scratch1,
+ Register scratch2,
+ Register scratch3,
+ Handle<AccessorInfo> callback,
+ Handle<String> name,
+ Label* miss) {
+ ASSERT(!receiver.is(scratch1));
+ ASSERT(!receiver.is(scratch2));
+ ASSERT(!receiver.is(scratch3));
+
+ // Load the properties dictionary.
+ Register dictionary = scratch1;
+ __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+
+ // Probe the dictionary.
+ Label probe_done;
+ StringDictionaryLookupStub::GeneratePositiveLookup(masm(),
+ miss,
+ &probe_done,
+ dictionary,
+ name_reg,
+ scratch2,
+ scratch3);
+ __ bind(&probe_done);
+
+ // If probing finds an entry in the dictionary, scratch3 contains the
+ // pointer into the dictionary. Check that the value is the callback.
+ Register pointer = scratch3;
+ const int kElementsStartOffset = StringDictionary::kHeaderSize +
+ StringDictionary::kElementsStartIndex * kPointerSize;
+ const int kValueOffset = kElementsStartOffset + kPointerSize;
+ __ ldr(scratch2, FieldMemOperand(pointer, kValueOffset));
+ __ cmp(scratch2, Operand(callback));
+ __ b(ne, miss);
+}
+
+
void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Handle<JSObject> holder,
Register receiver,
@@ -1237,6 +1278,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Register scratch1,
Register scratch2,
Register scratch3,
+ Register scratch4,
Handle<AccessorInfo> callback,
Handle<String> name,
Label* miss) {
@@ -1247,6 +1289,11 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Register reg = CheckPrototypes(object, receiver, holder, scratch1,
scratch2, scratch3, name, miss);
+ if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
+ GenerateDictionaryLoadCallback(
+ reg, name_reg, scratch2, scratch3, scratch4, callback, name, miss);
+ }
+
// Build AccessorInfo::args_ list on the stack and push property name below
// the exit frame to make GC aware of them and store pointers to them.
__ push(receiver);
@@ -1303,7 +1350,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
// later.
bool compile_followup_inline = false;
if (lookup->IsFound() && lookup->IsCacheable()) {
- if (lookup->type() == FIELD) {
+ if (lookup->IsField()) {
compile_followup_inline = true;
} else if (lookup->type() == CALLBACKS &&
lookup->GetCallbackObject()->IsAccessorInfo()) {
@@ -1377,7 +1424,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
miss);
}
- if (lookup->type() == FIELD) {
+ if (lookup->IsField()) {
// We found FIELD property in prototype chain of interceptor's holder.
// Retrieve a field from field's holder.
GenerateFastPropertyLoad(masm(), r0, holder_reg,
@@ -1526,7 +1573,7 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
GenerateMissBranch();
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2071,7 +2118,7 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2217,7 +2264,7 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2316,7 +2363,7 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2533,7 +2580,7 @@ Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
GenerateMissBranch();
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2591,7 +2638,7 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
GenerateMissBranch();
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2619,14 +2666,17 @@ Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
Handle<Code> StoreStubCompiler::CompileStoreCallback(
- Handle<JSObject> object,
- Handle<AccessorInfo> callback,
- Handle<String> name) {
+ Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : receiver
@@ -2634,19 +2684,12 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -- lr : return address
// -----------------------------------
Label miss;
+ // Check that the maps haven't changed.
+ __ JumpIfSmi(r1, &miss);
+ CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss);
- // Check that the map of the object hasn't changed.
- __ CheckMap(r1, r3, Handle<Map>(object->map()), &miss,
- DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
-
- // Perform global security token check if needed.
- if (object->IsJSGlobalProxy()) {
- __ CheckAccessGlobalProxy(r1, r3, &miss);
- }
-
- // Stub never generated for non-global objects that require access
- // checks.
- ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
+ // Stub never generated for non-global objects that require access checks.
+ ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
__ push(r1); // receiver
__ mov(ip, Operand(callback)); // callback info
@@ -2664,37 +2707,40 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
-Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
- Handle<JSObject> receiver,
- Handle<JSFunction> setter,
- Handle<String> name) {
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void StoreStubCompiler::GenerateStoreViaSetter(
+ MacroAssembler* masm,
+ Handle<JSFunction> setter) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : receiver
// -- r2 : name
// -- lr : return address
// -----------------------------------
- Label miss;
-
- // Check that the map of the object hasn't changed.
- __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss, DO_SMI_CHECK,
- ALLOW_ELEMENT_TRANSITION_MAPS);
-
{
- FrameScope scope(masm(), StackFrame::INTERNAL);
+ FrameScope scope(masm, StackFrame::INTERNAL);
// Save value register, so we can restore it later.
__ push(r0);
- // Call the JavaScript getter with the receiver and the value on the stack.
- __ Push(r1, r0);
- ParameterCount actual(1);
- __ InvokeFunction(setter, actual, CALL_FUNCTION, NullCallWrapper(),
- CALL_AS_METHOD);
+ if (!setter.is_null()) {
+ // Call the JavaScript setter with receiver and value on the stack.
+ __ Push(r1, r0);
+ ParameterCount actual(1);
+ __ InvokeFunction(setter, actual, CALL_FUNCTION, NullCallWrapper(),
+ CALL_AS_METHOD);
+ } else {
+ // If we generate a global code snippet for deoptimization only, remember
+ // the place to continue after deoptimization.
+ masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+ }
// We have to return the passed value, not the return value of the setter.
__ pop(r0);
@@ -2703,13 +2749,38 @@ Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
__ Ret();
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
+Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
+ Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<JSFunction> setter) {
+ // ----------- S t a t e -------------
+ // -- r0 : value
+ // -- r1 : receiver
+ // -- r2 : name
+ // -- lr : return address
+ // -----------------------------------
+ Label miss;
+
+ // Check that the maps haven't changed.
+ __ JumpIfSmi(r1, &miss);
+ CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss);
+
+ GenerateStoreViaSetter(masm(), setter);
__ bind(&miss);
Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2754,7 +2825,7 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2800,7 +2871,7 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2835,7 +2906,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NONEXISTENT, factory()->empty_string());
+ return GetCode(Code::NONEXISTENT, factory()->empty_string());
}
@@ -2855,7 +2926,7 @@ Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2870,16 +2941,53 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
// -- lr : return address
// -----------------------------------
Label miss;
- GenerateLoadCallback(object, holder, r0, r2, r3, r1, r4, callback, name,
+ GenerateLoadCallback(object, holder, r0, r2, r3, r1, r4, r5, callback, name,
&miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
+ Handle<JSFunction> getter) {
+ // ----------- S t a t e -------------
+ // -- r0 : receiver
+ // -- r2 : name
+ // -- lr : return address
+ // -----------------------------------
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ if (!getter.is_null()) {
+ // Call the JavaScript getter with the receiver on the stack.
+ __ push(r0);
+ ParameterCount actual(0);
+ __ InvokeFunction(getter, actual, CALL_FUNCTION, NullCallWrapper(),
+ CALL_AS_METHOD);
+ } else {
+ // If we generate a global code snippet for deoptimization only, remember
+ // the place to continue after deoptimization.
+ masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
+ }
+
+ // Restore context register.
+ __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+ }
+ __ Ret();
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
@@ -2896,25 +3004,13 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
__ JumpIfSmi(r0, &miss);
CheckPrototypes(receiver, r0, holder, r3, r4, r1, name, &miss);
- {
- FrameScope scope(masm(), StackFrame::INTERNAL);
-
- // Call the JavaScript getter with the receiver on the stack.
- __ push(r0);
- ParameterCount actual(0);
- __ InvokeFunction(getter, actual, CALL_FUNCTION, NullCallWrapper(),
- CALL_AS_METHOD);
-
- // Restore context register.
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
- }
- __ Ret();
+ GenerateLoadViaGetter(masm(), getter);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2934,7 +3030,7 @@ Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -2956,7 +3052,7 @@ Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> object,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2998,7 +3094,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -3021,7 +3117,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -3041,12 +3137,12 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
__ cmp(r0, Operand(name));
__ b(ne, &miss);
- GenerateLoadCallback(receiver, holder, r1, r0, r2, r3, r4, callback, name,
+ GenerateLoadCallback(receiver, holder, r1, r0, r2, r3, r4, r5, callback, name,
&miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3071,7 +3167,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -3097,7 +3193,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3118,7 +3214,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3144,7 +3240,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3169,7 +3265,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
__ DecrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3189,7 +3285,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3217,7 +3313,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic(
__ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
@@ -3256,7 +3352,9 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -3280,7 +3378,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3319,7 +3417,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
__ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
@@ -3548,6 +3646,7 @@ static void GenerateSmiKeyCheck(MacroAssembler* masm,
Register scratch0,
Register scratch1,
DwVfpRegister double_scratch0,
+ DwVfpRegister double_scratch1,
Label* fail) {
if (CpuFeatures::IsSupported(VFP2)) {
CpuFeatures::Scope scope(VFP2);
@@ -3564,13 +3663,12 @@ static void GenerateSmiKeyCheck(MacroAssembler* masm,
__ sub(ip, key, Operand(kHeapObjectTag));
__ vldr(double_scratch0, ip, HeapNumber::kValueOffset);
__ EmitVFPTruncate(kRoundToZero,
- double_scratch0.low(),
- double_scratch0,
scratch0,
+ double_scratch0,
scratch1,
+ double_scratch1,
kCheckForInexactConversion);
__ b(ne, fail);
- __ vmov(scratch0, double_scratch0.low());
__ TrySmiTag(scratch0, fail, scratch1);
__ mov(key, scratch0);
__ bind(&key_ok);
@@ -3598,7 +3696,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key, r4, r5, d1, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, key, r4, r5, d1, d2, &miss_force_generic);
__ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
// r3: elements array
@@ -3689,22 +3787,28 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
__ Ret();
__ bind(&box_int);
- // Allocate a HeapNumber for the result and perform int-to-double
- // conversion. Don't touch r0 or r1 as they are needed if allocation
- // fails.
- __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
- __ AllocateHeapNumber(r5, r3, r4, r6, &slow);
- // Now we can use r0 for the result as key is not needed any more.
- __ mov(r0, r5);
-
if (CpuFeatures::IsSupported(VFP2)) {
CpuFeatures::Scope scope(VFP2);
+ // Allocate a HeapNumber for the result and perform int-to-double
+ // conversion. Don't touch r0 or r1 as they are needed if allocation
+ // fails.
+ __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
+
+ __ AllocateHeapNumber(r5, r3, r4, r6, &slow, DONT_TAG_RESULT);
+ // Now we can use r0 for the result as key is not needed any more.
+ __ add(r0, r5, Operand(kHeapObjectTag));
__ vmov(s0, value);
__ vcvt_f64_s32(d0, s0);
- __ sub(r3, r0, Operand(kHeapObjectTag));
- __ vstr(d0, r3, HeapNumber::kValueOffset);
+ __ vstr(d0, r5, HeapNumber::kValueOffset);
__ Ret();
} else {
+ // Allocate a HeapNumber for the result and perform int-to-double
+ // conversion. Don't touch r0 or r1 as they are needed if allocation
+ // fails.
+ __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
+ __ AllocateHeapNumber(r5, r3, r4, r6, &slow, TAG_RESULT);
+ // Now we can use r0 for the result as key is not needed any more.
+ __ mov(r0, r5);
Register dst1 = r1;
Register dst2 = r3;
FloatingPointHelper::Destination dest =
@@ -3740,13 +3844,12 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
// conversion. Don't use r0 and r1 as AllocateHeapNumber clobbers all
// registers - also when jumping due to exhausted young space.
__ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
- __ AllocateHeapNumber(r2, r3, r4, r6, &slow);
+ __ AllocateHeapNumber(r2, r3, r4, r6, &slow, DONT_TAG_RESULT);
__ vcvt_f64_u32(d0, s0);
- __ sub(r1, r2, Operand(kHeapObjectTag));
- __ vstr(d0, r1, HeapNumber::kValueOffset);
+ __ vstr(d0, r2, HeapNumber::kValueOffset);
- __ mov(r0, r2);
+ __ add(r0, r2, Operand(kHeapObjectTag));
__ Ret();
} else {
// Check whether unsigned integer fits into smi.
@@ -3778,7 +3881,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
// clobbers all registers - also when jumping due to exhausted young
// space.
__ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
- __ AllocateHeapNumber(r4, r5, r7, r6, &slow);
+ __ AllocateHeapNumber(r4, r5, r7, r6, &slow, TAG_RESULT);
__ str(hiword, FieldMemOperand(r4, HeapNumber::kExponentOffset));
__ str(loword, FieldMemOperand(r4, HeapNumber::kMantissaOffset));
@@ -3795,19 +3898,18 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
// AllocateHeapNumber clobbers all registers - also when jumping due to
// exhausted young space.
__ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
- __ AllocateHeapNumber(r2, r3, r4, r6, &slow);
+ __ AllocateHeapNumber(r2, r3, r4, r6, &slow, DONT_TAG_RESULT);
__ vcvt_f64_f32(d0, s0);
- __ sub(r1, r2, Operand(kHeapObjectTag));
- __ vstr(d0, r1, HeapNumber::kValueOffset);
+ __ vstr(d0, r2, HeapNumber::kValueOffset);
- __ mov(r0, r2);
+ __ add(r0, r2, Operand(kHeapObjectTag));
__ Ret();
} else {
// Allocate a HeapNumber for the result. Don't use r0 and r1 as
// AllocateHeapNumber clobbers all registers - also when jumping due to
// exhausted young space.
__ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
- __ AllocateHeapNumber(r3, r4, r5, r6, &slow);
+ __ AllocateHeapNumber(r3, r4, r5, r6, &slow, TAG_RESULT);
// VFP is not available, do manual single to double conversion.
// r2: floating point value (binary32)
@@ -3863,18 +3965,17 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
// AllocateHeapNumber clobbers all registers - also when jumping due to
// exhausted young space.
__ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
- __ AllocateHeapNumber(r2, r3, r4, r6, &slow);
- __ sub(r1, r2, Operand(kHeapObjectTag));
- __ vstr(d0, r1, HeapNumber::kValueOffset);
+ __ AllocateHeapNumber(r2, r3, r4, r6, &slow, DONT_TAG_RESULT);
+ __ vstr(d0, r2, HeapNumber::kValueOffset);
- __ mov(r0, r2);
+ __ add(r0, r2, Operand(kHeapObjectTag));
__ Ret();
} else {
// Allocate a HeapNumber for the result. Don't use r0 and r1 as
// AllocateHeapNumber clobbers all registers - also when jumping due to
// exhausted young space.
__ LoadRoot(r7, Heap::kHeapNumberMapRootIndex);
- __ AllocateHeapNumber(r4, r5, r6, r7, &slow);
+ __ AllocateHeapNumber(r4, r5, r6, r7, &slow, TAG_RESULT);
__ str(r2, FieldMemOperand(r4, HeapNumber::kMantissaOffset));
__ str(r3, FieldMemOperand(r4, HeapNumber::kExponentOffset));
@@ -3932,7 +4033,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key, r4, r5, d1, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, key, r4, r5, d1, d2, &miss_force_generic);
__ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
@@ -4267,7 +4368,7 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, r0, r4, r5, d1, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, r0, r4, r5, d1, d2, &miss_force_generic);
// Get the elements array.
__ ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset));
@@ -4319,7 +4420,7 @@ void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, d2, &miss_force_generic);
// Get the elements array.
__ ldr(elements_reg,
@@ -4341,7 +4442,7 @@ void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
// Non-NaN. Allocate a new heap number and copy the double value into it.
__ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
__ AllocateHeapNumber(heap_number_reg, scratch2, scratch3,
- heap_number_map, &slow_allocate_heapnumber);
+ heap_number_map, &slow_allocate_heapnumber, TAG_RESULT);
// Don't need to reload the upper 32 bits of the double, it's already in
// scratch.
@@ -4395,7 +4496,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement(
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, d2, &miss_force_generic);
if (IsFastSmiElementsKind(elements_kind)) {
__ JumpIfNotSmi(value_reg, &transition_elements_kind);
@@ -4563,7 +4664,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, d2, &miss_force_generic);
__ ldr(elements_reg,
FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
@@ -4588,6 +4689,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
__ StoreNumberToDoubleElements(value_reg,
key_reg,
receiver_reg,
+ // All registers after this are overwritten.
elements_reg,
scratch1,
scratch2,
diff --git a/deps/v8/src/array.js b/deps/v8/src/array.js
index a1cc5b6a7..250c30c32 100644
--- a/deps/v8/src/array.js
+++ b/deps/v8/src/array.js
@@ -62,7 +62,7 @@ function GetSortedArrayKeys(array, intervals) {
}
}
}
- keys.sort(function(a, b) { return a - b; });
+ %_CallFunction(keys, function(a, b) { return a - b; }, ArraySort);
return keys;
}
@@ -777,78 +777,103 @@ function ArraySort(comparefn) {
}
};
- var QuickSort = function QuickSort(a, from, to) {
- // Insertion sort is faster for short arrays.
- if (to - from <= 10) {
- InsertionSort(a, from, to);
- return;
+ var GetThirdIndex = function(a, from, to) {
+ var t_array = [];
+ // Use both 'from' and 'to' to determine the pivot candidates.
+ var increment = 200 + ((to - from) & 15);
+ for (var i = from + 1; i < to - 1; i += increment) {
+ t_array.push([i, a[i]]);
}
- // Find a pivot as the median of first, last and middle element.
- var v0 = a[from];
- var v1 = a[to - 1];
- var middle_index = from + ((to - from) >> 1);
- var v2 = a[middle_index];
- var c01 = %_CallFunction(receiver, v0, v1, comparefn);
- if (c01 > 0) {
- // v1 < v0, so swap them.
- var tmp = v0;
- v0 = v1;
- v1 = tmp;
- } // v0 <= v1.
- var c02 = %_CallFunction(receiver, v0, v2, comparefn);
- if (c02 >= 0) {
- // v2 <= v0 <= v1.
- var tmp = v0;
- v0 = v2;
- v2 = v1;
- v1 = tmp;
- } else {
- // v0 <= v1 && v0 < v2
- var c12 = %_CallFunction(receiver, v1, v2, comparefn);
- if (c12 > 0) {
- // v0 <= v2 < v1
- var tmp = v1;
- v1 = v2;
- v2 = tmp;
+ t_array.sort(function(a, b) {
+ return %_CallFunction(receiver, a[1], b[1], comparefn) } );
+ var third_index = t_array[t_array.length >> 1][0];
+ return third_index;
+ }
+
+ var QuickSort = function QuickSort(a, from, to) {
+ var third_index = 0;
+ while (true) {
+ // Insertion sort is faster for short arrays.
+ if (to - from <= 10) {
+ InsertionSort(a, from, to);
+ return;
}
- }
- // v0 <= v1 <= v2
- a[from] = v0;
- a[to - 1] = v2;
- var pivot = v1;
- var low_end = from + 1; // Upper bound of elements lower than pivot.
- var high_start = to - 1; // Lower bound of elements greater than pivot.
- a[middle_index] = a[low_end];
- a[low_end] = pivot;
-
- // From low_end to i are elements equal to pivot.
- // From i to high_start are elements that haven't been compared yet.
- partition: for (var i = low_end + 1; i < high_start; i++) {
- var element = a[i];
- var order = %_CallFunction(receiver, element, pivot, comparefn);
- if (order < 0) {
- a[i] = a[low_end];
- a[low_end] = element;
- low_end++;
- } else if (order > 0) {
- do {
- high_start--;
- if (high_start == i) break partition;
- var top_elem = a[high_start];
- order = %_CallFunction(receiver, top_elem, pivot, comparefn);
- } while (order > 0);
- a[i] = a[high_start];
- a[high_start] = element;
+ if (to - from > 1000) {
+ third_index = GetThirdIndex(a, from, to);
+ } else {
+ third_index = from + ((to - from) >> 1);
+ }
+ // Find a pivot as the median of first, last and middle element.
+ var v0 = a[from];
+ var v1 = a[to - 1];
+ var v2 = a[third_index];
+ var c01 = %_CallFunction(receiver, v0, v1, comparefn);
+ if (c01 > 0) {
+ // v1 < v0, so swap them.
+ var tmp = v0;
+ v0 = v1;
+ v1 = tmp;
+ } // v0 <= v1.
+ var c02 = %_CallFunction(receiver, v0, v2, comparefn);
+ if (c02 >= 0) {
+ // v2 <= v0 <= v1.
+ var tmp = v0;
+ v0 = v2;
+ v2 = v1;
+ v1 = tmp;
+ } else {
+ // v0 <= v1 && v0 < v2
+ var c12 = %_CallFunction(receiver, v1, v2, comparefn);
+ if (c12 > 0) {
+ // v0 <= v2 < v1
+ var tmp = v1;
+ v1 = v2;
+ v2 = tmp;
+ }
+ }
+ // v0 <= v1 <= v2
+ a[from] = v0;
+ a[to - 1] = v2;
+ var pivot = v1;
+ var low_end = from + 1; // Upper bound of elements lower than pivot.
+ var high_start = to - 1; // Lower bound of elements greater than pivot.
+ a[third_index] = a[low_end];
+ a[low_end] = pivot;
+
+ // From low_end to i are elements equal to pivot.
+ // From i to high_start are elements that haven't been compared yet.
+ partition: for (var i = low_end + 1; i < high_start; i++) {
+ var element = a[i];
+ var order = %_CallFunction(receiver, element, pivot, comparefn);
if (order < 0) {
- element = a[i];
a[i] = a[low_end];
a[low_end] = element;
low_end++;
+ } else if (order > 0) {
+ do {
+ high_start--;
+ if (high_start == i) break partition;
+ var top_elem = a[high_start];
+ order = %_CallFunction(receiver, top_elem, pivot, comparefn);
+ } while (order > 0);
+ a[i] = a[high_start];
+ a[high_start] = element;
+ if (order < 0) {
+ element = a[i];
+ a[i] = a[low_end];
+ a[low_end] = element;
+ low_end++;
+ }
}
}
+ if (to - high_start < low_end - from) {
+ QuickSort(a, high_start, to);
+ to = low_end;
+ } else {
+ QuickSort(a, from, low_end);
+ from = high_start;
+ }
}
- QuickSort(a, from, low_end);
- QuickSort(a, high_start, to);
};
// Copy elements in the range 0..length from obj's prototype chain
diff --git a/deps/v8/src/assembler.cc b/deps/v8/src/assembler.cc
index d4c49ddd4..d81d4ae61 100644
--- a/deps/v8/src/assembler.cc
+++ b/deps/v8/src/assembler.cc
@@ -141,7 +141,7 @@ int Label::pos() const {
// an iteration.
//
// The encoding relies on the fact that there are fewer than 14
-// different non-compactly encoded relocation modes.
+// different relocation modes using standard non-compact encoding.
//
// The first byte of a relocation record has a tag in its low 2 bits:
// Here are the record schemes, depending on the low tag and optional higher
@@ -173,7 +173,9 @@ int Label::pos() const {
// 00 [4 bit middle_tag] 11 followed by
// 00 [6 bit pc delta]
//
-// 1101: not used (would allow one more relocation mode to be added)
+// 1101: constant pool. Used on ARM only for now.
+// The format is: 11 1101 11
+// signed int (size of the constant pool).
// 1110: long_data_record
// The format is: [2-bit data_type_tag] 1110 11
// signed intptr_t, lowest byte written first
@@ -194,7 +196,7 @@ int Label::pos() const {
// dropped, and last non-zero chunk tagged with 1.)
-const int kMaxRelocModes = 14;
+const int kMaxStandardNonCompactModes = 14;
const int kTagBits = 2;
const int kTagMask = (1 << kTagBits) - 1;
@@ -228,6 +230,9 @@ const int kNonstatementPositionTag = 1;
const int kStatementPositionTag = 2;
const int kCommentTag = 3;
+const int kConstPoolExtraTag = kPCJumpExtraTag - 2;
+const int kConstPoolTag = 3;
+
uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) {
// Return if the pc_delta can fit in kSmallPCDeltaBits bits.
@@ -285,6 +290,15 @@ void RelocInfoWriter::WriteExtraTaggedIntData(int data_delta, int top_tag) {
}
}
+void RelocInfoWriter::WriteExtraTaggedConstPoolData(int data) {
+ WriteExtraTag(kConstPoolExtraTag, kConstPoolTag);
+ for (int i = 0; i < kIntSize; i++) {
+ *--pos_ = static_cast<byte>(data);
+ // Signed right shift is arithmetic shift. Tested in test-utils.cc.
+ data = data >> kBitsPerByte;
+ }
+}
+
void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) {
WriteExtraTag(kDataJumpExtraTag, top_tag);
for (int i = 0; i < kIntptrSize; i++) {
@@ -300,8 +314,8 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) {
byte* begin_pos = pos_;
#endif
ASSERT(rinfo->pc() - last_pc_ >= 0);
- ASSERT(RelocInfo::NUMBER_OF_MODES - RelocInfo::LAST_COMPACT_ENUM <=
- kMaxRelocModes);
+ ASSERT(RelocInfo::LAST_STANDARD_NONCOMPACT_ENUM - RelocInfo::LAST_COMPACT_ENUM
+ <= kMaxStandardNonCompactModes);
// Use unsigned delta-encoding for pc.
uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_);
RelocInfo::Mode rmode = rinfo->rmode();
@@ -347,6 +361,9 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) {
WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
WriteExtraTaggedData(rinfo->data(), kCommentTag);
ASSERT(begin_pos - pos_ >= RelocInfo::kMinRelocCommentSize);
+ } else if (RelocInfo::IsConstPool(rmode)) {
+ WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
+ WriteExtraTaggedConstPoolData(static_cast<int>(rinfo->data()));
} else {
ASSERT(rmode > RelocInfo::LAST_COMPACT_ENUM);
int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM;
@@ -397,6 +414,15 @@ void RelocIterator::AdvanceReadId() {
}
+void RelocIterator::AdvanceReadConstPoolData() {
+ int x = 0;
+ for (int i = 0; i < kIntSize; i++) {
+ x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
+ }
+ rinfo_.data_ = x;
+}
+
+
void RelocIterator::AdvanceReadPosition() {
int x = 0;
for (int i = 0; i < kIntSize; i++) {
@@ -500,8 +526,7 @@ void RelocIterator::next() {
ASSERT(tag == kDefaultTag);
int extra_tag = GetExtraTag();
if (extra_tag == kPCJumpExtraTag) {
- int top_tag = GetTopTag();
- if (top_tag == kVariableLengthPCJumpTopTag) {
+ if (GetTopTag() == kVariableLengthPCJumpTopTag) {
AdvanceReadVariableLengthPCJump();
} else {
AdvanceReadPC();
@@ -531,6 +556,13 @@ void RelocIterator::next() {
}
Advance(kIntptrSize);
}
+ } else if ((extra_tag == kConstPoolExtraTag) &&
+ (GetTopTag() == kConstPoolTag)) {
+ if (SetMode(RelocInfo::CONST_POOL)) {
+ AdvanceReadConstPoolData();
+ return;
+ }
+ Advance(kIntSize);
} else {
AdvanceReadPC();
int rmode = extra_tag + RelocInfo::LAST_COMPACT_ENUM;
@@ -613,6 +645,8 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
return "external reference";
case RelocInfo::INTERNAL_REFERENCE:
return "internal reference";
+ case RelocInfo::CONST_POOL:
+ return "constant pool";
case RelocInfo::DEBUG_BREAK_SLOT:
#ifndef ENABLE_DEBUGGER_SUPPORT
UNREACHABLE();
@@ -663,7 +697,7 @@ void RelocInfo::Print(FILE* out) {
#endif // ENABLE_DISASSEMBLER
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
void RelocInfo::Verify() {
switch (rmode_) {
case EMBEDDED_OBJECT:
@@ -683,12 +717,12 @@ void RelocInfo::Verify() {
case CODE_TARGET: {
// convert inline target address to code object
Address addr = target_address();
- ASSERT(addr != NULL);
+ CHECK(addr != NULL);
// Check that we can find the right code object.
Code* code = Code::GetCodeFromTargetAddress(addr);
Object* found = HEAP->FindCodeObject(addr);
- ASSERT(found->IsCode());
- ASSERT(code->address() == HeapObject::cast(found)->address());
+ CHECK(found->IsCode());
+ CHECK(code->address() == HeapObject::cast(found)->address());
break;
}
case RUNTIME_ENTRY:
@@ -698,6 +732,7 @@ void RelocInfo::Verify() {
case STATEMENT_POSITION:
case EXTERNAL_REFERENCE:
case INTERNAL_REFERENCE:
+ case CONST_POOL:
case DEBUG_BREAK_SLOT:
case NONE:
break;
@@ -706,7 +741,7 @@ void RelocInfo::Verify() {
break;
}
}
-#endif // DEBUG
+#endif // VERIFY_HEAP
// -----------------------------------------------------------------------------
@@ -1057,7 +1092,7 @@ ExternalReference ExternalReference::re_word_character_map() {
ExternalReference ExternalReference::address_of_static_offsets_vector(
Isolate* isolate) {
return ExternalReference(
- OffsetsVector::static_offsets_vector_address(isolate));
+ reinterpret_cast<Address>(isolate->jsregexp_static_offsets_vector()));
}
ExternalReference ExternalReference::address_of_regexp_stack_memory_address(
diff --git a/deps/v8/src/assembler.h b/deps/v8/src/assembler.h
index 619c69c4b..a0e55cc81 100644
--- a/deps/v8/src/assembler.h
+++ b/deps/v8/src/assembler.h
@@ -51,7 +51,6 @@ class ApiFunction;
namespace internal {
struct StatsCounter;
-const unsigned kNoASTId = -1;
// -----------------------------------------------------------------------------
// Platform independent assembler base class.
@@ -204,14 +203,19 @@ class RelocInfo BASE_EMBEDDED {
EXTERNAL_REFERENCE, // The address of an external C++ function.
INTERNAL_REFERENCE, // An address inside the same function.
+ // Marks a constant pool. Only used on ARM.
+ // It uses a custom noncompact encoding.
+ CONST_POOL,
+
// add more as needed
// Pseudo-types
- NUMBER_OF_MODES, // There are at most 14 modes with noncompact encoding.
+ NUMBER_OF_MODES, // There are at most 15 modes with noncompact encoding.
NONE, // never recorded
LAST_CODE_ENUM = DEBUG_BREAK,
LAST_GCED_ENUM = GLOBAL_PROPERTY_CELL,
// Modes <= LAST_COMPACT_ENUM are guaranteed to have compact encoding.
- LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID
+ LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID,
+ LAST_STANDARD_NONCOMPACT_ENUM = INTERNAL_REFERENCE
};
@@ -240,6 +244,9 @@ class RelocInfo BASE_EMBEDDED {
static inline bool IsComment(Mode mode) {
return mode == COMMENT;
}
+ static inline bool IsConstPool(Mode mode) {
+ return mode == CONST_POOL;
+ }
static inline bool IsPosition(Mode mode) {
return mode == POSITION || mode == STATEMENT_POSITION;
}
@@ -342,8 +349,7 @@ class RelocInfo BASE_EMBEDDED {
static const char* RelocModeName(Mode rmode);
void Print(FILE* out);
#endif // ENABLE_DISASSEMBLER
-#ifdef DEBUG
- // Debugging
+#ifdef VERIFY_HEAP
void Verify();
#endif
@@ -362,19 +368,17 @@ class RelocInfo BASE_EMBEDDED {
Mode rmode_;
intptr_t data_;
Code* host_;
-#ifdef V8_TARGET_ARCH_MIPS
- // Code and Embedded Object pointers in mips are stored split
+ // Code and Embedded Object pointers on some platforms are stored split
// across two consecutive 32-bit instructions. Heap management
// routines expect to access these pointers indirectly. The following
- // location provides a place for these pointers to exist natually
+ // location provides a place for these pointers to exist naturally
// when accessed via the Iterator.
Object* reconstructed_obj_ptr_;
// External-reference pointers are also split across instruction-pairs
- // in mips, but are accessed via indirect pointers. This location
+ // on some platforms, but are accessed via indirect pointers. This location
// provides a place for that pointer to exist naturally. Its address
// is returned by RelocInfo::target_reference_address().
Address reconstructed_adr_ptr_;
-#endif // V8_TARGET_ARCH_MIPS
friend class RelocIterator;
};
@@ -416,6 +420,7 @@ class RelocInfoWriter BASE_EMBEDDED {
inline void WriteTaggedPC(uint32_t pc_delta, int tag);
inline void WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag);
inline void WriteExtraTaggedIntData(int data_delta, int top_tag);
+ inline void WriteExtraTaggedConstPoolData(int data);
inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag);
inline void WriteTaggedData(intptr_t data_delta, int tag);
inline void WriteExtraTag(int extra_tag, int top_tag);
@@ -466,6 +471,7 @@ class RelocIterator: public Malloced {
void ReadTaggedPC();
void AdvanceReadPC();
void AdvanceReadId();
+ void AdvanceReadConstPoolData();
void AdvanceReadPosition();
void AdvanceReadData();
void AdvanceReadVariableLengthPCJump();
diff --git a/deps/v8/src/ast.cc b/deps/v8/src/ast.cc
index 9523a3435..52990b8fe 100644
--- a/deps/v8/src/ast.cc
+++ b/deps/v8/src/ast.cc
@@ -85,8 +85,8 @@ VariableProxy::VariableProxy(Isolate* isolate, Variable* var)
VariableProxy::VariableProxy(Isolate* isolate,
Handle<String> name,
bool is_this,
- int position,
- Interface* interface)
+ Interface* interface,
+ int position)
: Expression(isolate),
name_(name),
var_(NULL),
@@ -125,10 +125,7 @@ Assignment::Assignment(Isolate* isolate,
value_(value),
pos_(pos),
binary_operation_(NULL),
- compound_load_id_(kNoNumber),
assignment_id_(GetNextId(isolate)),
- block_start_(false),
- block_end_(false),
is_monomorphic_(false) { }
@@ -156,6 +153,11 @@ bool FunctionLiteral::AllowsLazyCompilation() {
}
+bool FunctionLiteral::AllowsLazyCompilationWithoutContext() {
+ return scope()->AllowsLazyCompilationWithoutContext();
+}
+
+
int FunctionLiteral::start_position() const {
return scope()->start_position();
}
@@ -429,7 +431,7 @@ void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle,
zone);
} else if (oracle->LoadIsMegamorphicWithTypeInfo(this)) {
receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
- oracle->CollectKeyedReceiverTypes(this->id(), &receiver_types_);
+ oracle->CollectKeyedReceiverTypes(PropertyFeedbackId(), &receiver_types_);
}
}
@@ -438,7 +440,8 @@ void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle,
Zone* zone) {
Property* prop = target()->AsProperty();
ASSERT(prop != NULL);
- is_monomorphic_ = oracle->StoreIsMonomorphicNormal(this);
+ TypeFeedbackId id = AssignmentFeedbackId();
+ is_monomorphic_ = oracle->StoreIsMonomorphicNormal(id);
receiver_types_.Clear();
if (prop->key()->IsPropertyName()) {
Literal* lit_key = prop->key()->AsLiteral();
@@ -447,24 +450,26 @@ void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle,
oracle->StoreReceiverTypes(this, name, &receiver_types_);
} else if (is_monomorphic_) {
// Record receiver type for monomorphic keyed stores.
- receiver_types_.Add(oracle->StoreMonomorphicReceiverType(this), zone);
- } else if (oracle->StoreIsMegamorphicWithTypeInfo(this)) {
+ receiver_types_.Add(oracle->StoreMonomorphicReceiverType(id), zone);
+ } else if (oracle->StoreIsMegamorphicWithTypeInfo(id)) {
receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
- oracle->CollectKeyedReceiverTypes(this->id(), &receiver_types_);
+ oracle->CollectKeyedReceiverTypes(id, &receiver_types_);
}
}
void CountOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle,
Zone* zone) {
- is_monomorphic_ = oracle->StoreIsMonomorphicNormal(this);
+ TypeFeedbackId id = CountStoreFeedbackId();
+ is_monomorphic_ = oracle->StoreIsMonomorphicNormal(id);
receiver_types_.Clear();
if (is_monomorphic_) {
// Record receiver type for monomorphic keyed stores.
- receiver_types_.Add(oracle->StoreMonomorphicReceiverType(this), zone);
- } else if (oracle->StoreIsMegamorphicWithTypeInfo(this)) {
+ receiver_types_.Add(
+ oracle->StoreMonomorphicReceiverType(id), zone);
+ } else if (oracle->StoreIsMegamorphicWithTypeInfo(id)) {
receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
- oracle->CollectKeyedReceiverTypes(this->id(), &receiver_types_);
+ oracle->CollectKeyedReceiverTypes(id, &receiver_types_);
}
}
@@ -498,7 +503,7 @@ bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
}
LookupResult lookup(type->GetIsolate());
while (true) {
- type->LookupInDescriptors(NULL, *name, &lookup);
+ type->LookupDescriptor(NULL, *name, &lookup);
if (lookup.IsFound()) {
switch (lookup.type()) {
case CONSTANT_FUNCTION:
@@ -513,10 +518,9 @@ bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
case INTERCEPTOR:
// We don't know the target.
return false;
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
- // Perhaps something interesting is up in the prototype chain...
+ case TRANSITION:
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
}
@@ -1027,6 +1031,14 @@ CaseClause::CaseClause(Isolate* isolate,
increase_node_count(); \
add_flag(kDontSelfOptimize); \
}
+#define DONT_CACHE_NODE(NodeType) \
+ void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
+ increase_node_count(); \
+ add_flag(kDontOptimize); \
+ add_flag(kDontInline); \
+ add_flag(kDontSelfOptimize); \
+ add_flag(kDontCache); \
+ }
REGULAR_NODE(VariableDeclaration)
REGULAR_NODE(FunctionDeclaration)
@@ -1041,6 +1053,7 @@ REGULAR_NODE(SwitchStatement)
REGULAR_NODE(Conditional)
REGULAR_NODE(Literal)
REGULAR_NODE(ObjectLiteral)
+REGULAR_NODE(RegExpLiteral)
REGULAR_NODE(Assignment)
REGULAR_NODE(Throw)
REGULAR_NODE(Property)
@@ -1057,10 +1070,13 @@ REGULAR_NODE(CallNew)
// LOOKUP variables only result from constructs that cannot be inlined anyway.
REGULAR_NODE(VariableProxy)
+// We currently do not optimize any modules. Note in particular, that module
+// instance objects associated with ModuleLiterals are allocated during
+// scope resolution, and references to them are embedded into the code.
+// That code may hence neither be cached nor re-compiled.
DONT_OPTIMIZE_NODE(ModuleDeclaration)
DONT_OPTIMIZE_NODE(ImportDeclaration)
DONT_OPTIMIZE_NODE(ExportDeclaration)
-DONT_OPTIMIZE_NODE(ModuleLiteral)
DONT_OPTIMIZE_NODE(ModuleVariable)
DONT_OPTIMIZE_NODE(ModulePath)
DONT_OPTIMIZE_NODE(ModuleUrl)
@@ -1070,15 +1086,16 @@ DONT_OPTIMIZE_NODE(TryFinallyStatement)
DONT_OPTIMIZE_NODE(DebuggerStatement)
DONT_OPTIMIZE_NODE(SharedFunctionInfoLiteral)
-DONT_INLINE_NODE(FunctionLiteral)
-DONT_INLINE_NODE(RegExpLiteral) // TODO(1322): Allow materialized literals.
DONT_INLINE_NODE(ArrayLiteral) // TODO(1322): Allow materialized literals.
+DONT_INLINE_NODE(FunctionLiteral)
DONT_SELFOPTIMIZE_NODE(DoWhileStatement)
DONT_SELFOPTIMIZE_NODE(WhileStatement)
DONT_SELFOPTIMIZE_NODE(ForStatement)
DONT_SELFOPTIMIZE_NODE(ForInStatement)
+DONT_CACHE_NODE(ModuleLiteral)
+
void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) {
increase_node_count();
if (node->is_jsruntime()) {
@@ -1099,6 +1116,7 @@ void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) {
#undef DONT_OPTIMIZE_NODE
#undef DONT_INLINE_NODE
#undef DONT_SELFOPTIMIZE_NODE
+#undef DONT_CACHE_NODE
Handle<String> Literal::ToString() {
diff --git a/deps/v8/src/ast.h b/deps/v8/src/ast.h
index 02ece7fe6..802ac6596 100644
--- a/deps/v8/src/ast.h
+++ b/deps/v8/src/ast.h
@@ -37,7 +37,7 @@
#include "list-inl.h"
#include "runtime.h"
#include "small-pointer-list.h"
-#include "smart-array-pointer.h"
+#include "smart-pointers.h"
#include "token.h"
#include "utils.h"
#include "variables.h"
@@ -158,14 +158,16 @@ typedef ZoneList<Handle<Object> > ZoneObjectList;
#define DECLARE_NODE_TYPE(type) \
virtual void Accept(AstVisitor* v); \
- virtual AstNode::Type node_type() const { return AstNode::k##type; }
+ virtual AstNode::Type node_type() const { return AstNode::k##type; } \
+ template<class> friend class AstNodeFactory;
enum AstPropertiesFlag {
kDontInline,
kDontOptimize,
kDontSelfOptimize,
- kDontSoftInline
+ kDontSoftInline,
+ kDontCache
};
@@ -194,13 +196,6 @@ class AstNode: public ZoneObject {
};
#undef DECLARE_TYPE_ENUM
- static const int kNoNumber = -1;
- static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
- // This AST id identifies the point after the declarations have been
- // visited. We need it to capture the environment effects of declarations
- // that emit code (function declarations).
- static const int kDeclarationsId = 3;
-
void* operator new(size_t size, Zone* zone) {
return zone->New(static_cast<int>(size));
}
@@ -210,7 +205,7 @@ class AstNode: public ZoneObject {
virtual ~AstNode() { }
virtual void Accept(AstVisitor* v) = 0;
- virtual Type node_type() const { return kInvalid; }
+ virtual Type node_type() const = 0;
// Type testing & conversion functions overridden by concrete subclasses.
#define DECLARE_NODE_FUNCTIONS(type) \
@@ -219,9 +214,6 @@ class AstNode: public ZoneObject {
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
#undef DECLARE_NODE_FUNCTIONS
- virtual Declaration* AsDeclaration() { return NULL; }
- virtual Statement* AsStatement() { return NULL; }
- virtual Expression* AsExpression() { return NULL; }
virtual TargetCollector* AsTargetCollector() { return NULL; }
virtual BreakableStatement* AsBreakableStatement() { return NULL; }
virtual IterationStatement* AsIterationStatement() { return NULL; }
@@ -238,6 +230,12 @@ class AstNode: public ZoneObject {
return tmp;
}
+ // Some nodes re-use bailout IDs for type feedback.
+ static TypeFeedbackId reuse(BailoutId id) {
+ return TypeFeedbackId(id.ToInt());
+ }
+
+
private:
// Hidden to prevent accidental usage. It would have to load the
// current zone from the TLS.
@@ -251,8 +249,6 @@ class Statement: public AstNode {
public:
Statement() : statement_pos_(RelocInfo::kNoPosition) {}
- virtual Statement* AsStatement() { return this; }
-
bool IsEmpty() { return AsEmptyStatement() != NULL; }
void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
@@ -313,8 +309,6 @@ class Expression: public AstNode {
return 0;
}
- virtual Expression* AsExpression() { return this; }
-
virtual bool IsValidLeftHandSide() { return false; }
// Helpers for ToBoolean conversion.
@@ -355,8 +349,8 @@ class Expression: public AstNode {
return types->at(0);
}
- unsigned id() const { return id_; }
- unsigned test_id() const { return test_id_; }
+ BailoutId id() const { return id_; }
+ TypeFeedbackId test_id() const { return test_id_; }
protected:
explicit Expression(Isolate* isolate)
@@ -364,8 +358,8 @@ class Expression: public AstNode {
test_id_(GetNextId(isolate)) {}
private:
- int id_;
- int test_id_;
+ const BailoutId id_;
+ const TypeFeedbackId test_id_;
};
@@ -389,9 +383,8 @@ class BreakableStatement: public Statement {
// Testers.
bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
- // Bailout support.
- int EntryId() const { return entry_id_; }
- int ExitId() const { return exit_id_; }
+ BailoutId EntryId() const { return entry_id_; }
+ BailoutId ExitId() const { return exit_id_; }
protected:
BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type)
@@ -407,8 +400,8 @@ class BreakableStatement: public Statement {
ZoneStringList* labels_;
Type type_;
Label break_target_;
- int entry_id_;
- int exit_id_;
+ const BailoutId entry_id_;
+ const BailoutId exit_id_;
};
@@ -427,8 +420,6 @@ class Block: public BreakableStatement {
void set_scope(Scope* scope) { scope_ = scope; }
protected:
- template<class> friend class AstNodeFactory;
-
Block(Isolate* isolate,
ZoneStringList* labels,
int capacity,
@@ -455,8 +446,6 @@ class Declaration: public AstNode {
virtual InitializationFlag initialization() const = 0;
virtual bool IsInlineable() const;
- virtual Declaration* AsDeclaration() { return this; }
-
protected:
Declaration(VariableProxy* proxy,
VariableMode mode,
@@ -464,10 +453,7 @@ class Declaration: public AstNode {
: proxy_(proxy),
mode_(mode),
scope_(scope) {
- ASSERT(mode == VAR ||
- mode == CONST ||
- mode == CONST_HARMONY ||
- mode == LET);
+ ASSERT(IsDeclaredVariableMode(mode));
}
private:
@@ -488,8 +474,6 @@ class VariableDeclaration: public Declaration {
}
protected:
- template<class> friend class AstNodeFactory;
-
VariableDeclaration(VariableProxy* proxy,
VariableMode mode,
Scope* scope)
@@ -509,8 +493,6 @@ class FunctionDeclaration: public Declaration {
virtual bool IsInlineable() const;
protected:
- template<class> friend class AstNodeFactory;
-
FunctionDeclaration(VariableProxy* proxy,
VariableMode mode,
FunctionLiteral* fun,
@@ -537,8 +519,6 @@ class ModuleDeclaration: public Declaration {
}
protected:
- template<class> friend class AstNodeFactory;
-
ModuleDeclaration(VariableProxy* proxy,
Module* module,
Scope* scope)
@@ -561,8 +541,6 @@ class ImportDeclaration: public Declaration {
}
protected:
- template<class> friend class AstNodeFactory;
-
ImportDeclaration(VariableProxy* proxy,
Module* module,
Scope* scope)
@@ -584,25 +562,27 @@ class ExportDeclaration: public Declaration {
}
protected:
- template<class> friend class AstNodeFactory;
-
- ExportDeclaration(VariableProxy* proxy,
- Scope* scope)
- : Declaration(proxy, LET, scope) {
- }
+ ExportDeclaration(VariableProxy* proxy, Scope* scope)
+ : Declaration(proxy, LET, scope) {}
};
class Module: public AstNode {
public:
Interface* interface() const { return interface_; }
+ Block* body() const { return body_; }
protected:
- explicit Module(Zone* zone) : interface_(Interface::NewModule(zone)) {}
- explicit Module(Interface* interface) : interface_(interface) {}
+ explicit Module(Zone* zone)
+ : interface_(Interface::NewModule(zone)),
+ body_(NULL) {}
+ explicit Module(Interface* interface, Block* body = NULL)
+ : interface_(interface),
+ body_(body) {}
private:
Interface* interface_;
+ Block* body_;
};
@@ -610,20 +590,8 @@ class ModuleLiteral: public Module {
public:
DECLARE_NODE_TYPE(ModuleLiteral)
- Block* body() const { return body_; }
- Handle<Context> context() const { return context_; }
-
protected:
- template<class> friend class AstNodeFactory;
-
- ModuleLiteral(Block* body, Interface* interface)
- : Module(interface),
- body_(body) {
- }
-
- private:
- Block* body_;
- Handle<Context> context_;
+ ModuleLiteral(Block* body, Interface* interface) : Module(interface, body) {}
};
@@ -634,8 +602,6 @@ class ModuleVariable: public Module {
VariableProxy* proxy() const { return proxy_; }
protected:
- template<class> friend class AstNodeFactory;
-
inline explicit ModuleVariable(VariableProxy* proxy);
private:
@@ -651,8 +617,6 @@ class ModulePath: public Module {
Handle<String> name() const { return name_; }
protected:
- template<class> friend class AstNodeFactory;
-
ModulePath(Module* module, Handle<String> name, Zone* zone)
: Module(zone),
module_(module),
@@ -672,8 +636,6 @@ class ModuleUrl: public Module {
Handle<String> url() const { return url_; }
protected:
- template<class> friend class AstNodeFactory;
-
ModuleUrl(Handle<String> url, Zone* zone)
: Module(zone), url_(url) {
}
@@ -690,10 +652,9 @@ class IterationStatement: public BreakableStatement {
Statement* body() const { return body_; }
- // Bailout support.
- int OsrEntryId() const { return osr_entry_id_; }
- virtual int ContinueId() const = 0;
- virtual int StackCheckId() const = 0;
+ BailoutId OsrEntryId() const { return osr_entry_id_; }
+ virtual BailoutId ContinueId() const = 0;
+ virtual BailoutId StackCheckId() const = 0;
// Code generation
Label* continue_target() { return &continue_target_; }
@@ -712,7 +673,7 @@ class IterationStatement: public BreakableStatement {
private:
Statement* body_;
Label continue_target_;
- int osr_entry_id_;
+ const BailoutId osr_entry_id_;
};
@@ -732,14 +693,11 @@ class DoWhileStatement: public IterationStatement {
int condition_position() { return condition_position_; }
void set_condition_position(int pos) { condition_position_ = pos; }
- // Bailout support.
- virtual int ContinueId() const { return continue_id_; }
- virtual int StackCheckId() const { return back_edge_id_; }
- int BackEdgeId() const { return back_edge_id_; }
+ virtual BailoutId ContinueId() const { return continue_id_; }
+ virtual BailoutId StackCheckId() const { return back_edge_id_; }
+ BailoutId BackEdgeId() const { return back_edge_id_; }
protected:
- template<class> friend class AstNodeFactory;
-
DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
: IterationStatement(isolate, labels),
cond_(NULL),
@@ -751,8 +709,8 @@ class DoWhileStatement: public IterationStatement {
private:
Expression* cond_;
int condition_position_;
- int continue_id_;
- int back_edge_id_;
+ const BailoutId continue_id_;
+ const BailoutId back_edge_id_;
};
@@ -773,14 +731,11 @@ class WhileStatement: public IterationStatement {
may_have_function_literal_ = value;
}
- // Bailout support.
- virtual int ContinueId() const { return EntryId(); }
- virtual int StackCheckId() const { return body_id_; }
- int BodyId() const { return body_id_; }
+ virtual BailoutId ContinueId() const { return EntryId(); }
+ virtual BailoutId StackCheckId() const { return body_id_; }
+ BailoutId BodyId() const { return body_id_; }
protected:
- template<class> friend class AstNodeFactory;
-
WhileStatement(Isolate* isolate, ZoneStringList* labels)
: IterationStatement(isolate, labels),
cond_(NULL),
@@ -792,7 +747,7 @@ class WhileStatement: public IterationStatement {
Expression* cond_;
// True if there is a function literal subexpression in the condition.
bool may_have_function_literal_;
- int body_id_;
+ const BailoutId body_id_;
};
@@ -821,18 +776,15 @@ class ForStatement: public IterationStatement {
may_have_function_literal_ = value;
}
- // Bailout support.
- virtual int ContinueId() const { return continue_id_; }
- virtual int StackCheckId() const { return body_id_; }
- int BodyId() const { return body_id_; }
+ virtual BailoutId ContinueId() const { return continue_id_; }
+ virtual BailoutId StackCheckId() const { return body_id_; }
+ BailoutId BodyId() const { return body_id_; }
bool is_fast_smi_loop() { return loop_variable_ != NULL; }
Variable* loop_variable() { return loop_variable_; }
void set_loop_variable(Variable* var) { loop_variable_ = var; }
protected:
- template<class> friend class AstNodeFactory;
-
ForStatement(Isolate* isolate, ZoneStringList* labels)
: IterationStatement(isolate, labels),
init_(NULL),
@@ -851,8 +803,8 @@ class ForStatement: public IterationStatement {
// True if there is a function literal subexpression in the condition.
bool may_have_function_literal_;
Variable* loop_variable_;
- int continue_id_;
- int body_id_;
+ const BailoutId continue_id_;
+ const BailoutId body_id_;
};
@@ -869,14 +821,14 @@ class ForInStatement: public IterationStatement {
Expression* each() const { return each_; }
Expression* enumerable() const { return enumerable_; }
- virtual int ContinueId() const { return EntryId(); }
- virtual int StackCheckId() const { return body_id_; }
- int BodyId() const { return body_id_; }
- int PrepareId() const { return prepare_id_; }
+ virtual BailoutId ContinueId() const { return EntryId(); }
+ virtual BailoutId StackCheckId() const { return body_id_; }
+ BailoutId BodyId() const { return body_id_; }
+ BailoutId PrepareId() const { return prepare_id_; }
- protected:
- template<class> friend class AstNodeFactory;
+ TypeFeedbackId ForInFeedbackId() const { return reuse(PrepareId()); }
+ protected:
ForInStatement(Isolate* isolate, ZoneStringList* labels)
: IterationStatement(isolate, labels),
each_(NULL),
@@ -888,8 +840,8 @@ class ForInStatement: public IterationStatement {
private:
Expression* each_;
Expression* enumerable_;
- int body_id_;
- int prepare_id_;
+ const BailoutId body_id_;
+ const BailoutId prepare_id_;
};
@@ -901,8 +853,6 @@ class ExpressionStatement: public Statement {
Expression* expression() const { return expression_; }
protected:
- template<class> friend class AstNodeFactory;
-
explicit ExpressionStatement(Expression* expression)
: expression_(expression) { }
@@ -918,8 +868,6 @@ class ContinueStatement: public Statement {
IterationStatement* target() const { return target_; }
protected:
- template<class> friend class AstNodeFactory;
-
explicit ContinueStatement(IterationStatement* target)
: target_(target) { }
@@ -935,8 +883,6 @@ class BreakStatement: public Statement {
BreakableStatement* target() const { return target_; }
protected:
- template<class> friend class AstNodeFactory;
-
explicit BreakStatement(BreakableStatement* target)
: target_(target) { }
@@ -952,8 +898,6 @@ class ReturnStatement: public Statement {
Expression* expression() const { return expression_; }
protected:
- template<class> friend class AstNodeFactory;
-
explicit ReturnStatement(Expression* expression)
: expression_(expression) { }
@@ -970,8 +914,6 @@ class WithStatement: public Statement {
Statement* statement() const { return statement_; }
protected:
- template<class> friend class AstNodeFactory;
-
WithStatement(Expression* expression, Statement* statement)
: expression_(expression),
statement_(statement) { }
@@ -1000,10 +942,10 @@ class CaseClause: public ZoneObject {
int position() const { return position_; }
void set_position(int pos) { position_ = pos; }
- int EntryId() { return entry_id_; }
- int CompareId() { return compare_id_; }
+ BailoutId EntryId() const { return entry_id_; }
// Type feedback information.
+ TypeFeedbackId CompareId() { return compare_id_; }
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
bool IsSymbolCompare() { return compare_type_ == SYMBOL_ONLY; }
@@ -1023,8 +965,8 @@ class CaseClause: public ZoneObject {
OBJECT_ONLY
};
CompareTypeFeedback compare_type_;
- int compare_id_;
- int entry_id_;
+ const TypeFeedbackId compare_id_;
+ const BailoutId entry_id_;
};
@@ -1041,8 +983,6 @@ class SwitchStatement: public BreakableStatement {
ZoneList<CaseClause*>* cases() const { return cases_; }
protected:
- template<class> friend class AstNodeFactory;
-
SwitchStatement(Isolate* isolate, ZoneStringList* labels)
: BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
tag_(NULL),
@@ -1070,13 +1010,11 @@ class IfStatement: public Statement {
Statement* then_statement() const { return then_statement_; }
Statement* else_statement() const { return else_statement_; }
- int IfId() const { return if_id_; }
- int ThenId() const { return then_id_; }
- int ElseId() const { return else_id_; }
+ BailoutId IfId() const { return if_id_; }
+ BailoutId ThenId() const { return then_id_; }
+ BailoutId ElseId() const { return else_id_; }
protected:
- template<class> friend class AstNodeFactory;
-
IfStatement(Isolate* isolate,
Expression* condition,
Statement* then_statement,
@@ -1093,9 +1031,9 @@ class IfStatement: public Statement {
Expression* condition_;
Statement* then_statement_;
Statement* else_statement_;
- int if_id_;
- int then_id_;
- int else_id_;
+ const BailoutId if_id_;
+ const BailoutId then_id_;
+ const BailoutId else_id_;
};
@@ -1112,6 +1050,7 @@ class TargetCollector: public AstNode {
// Virtual behaviour. TargetCollectors are never part of the AST.
virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
+ virtual Type node_type() const { return kInvalid; }
virtual TargetCollector* AsTargetCollector() { return this; }
ZoneList<Label*>* targets() { return &targets_; }
@@ -1155,8 +1094,6 @@ class TryCatchStatement: public TryStatement {
Block* catch_block() const { return catch_block_; }
protected:
- template<class> friend class AstNodeFactory;
-
TryCatchStatement(int index,
Block* try_block,
Scope* scope,
@@ -1182,8 +1119,6 @@ class TryFinallyStatement: public TryStatement {
Block* finally_block() const { return finally_block_; }
protected:
- template<class> friend class AstNodeFactory;
-
TryFinallyStatement(int index, Block* try_block, Block* finally_block)
: TryStatement(index, try_block),
finally_block_(finally_block) { }
@@ -1198,8 +1133,6 @@ class DebuggerStatement: public Statement {
DECLARE_NODE_TYPE(DebuggerStatement)
protected:
- template<class> friend class AstNodeFactory;
-
DebuggerStatement() {}
};
@@ -1209,8 +1142,6 @@ class EmptyStatement: public Statement {
DECLARE_NODE_TYPE(EmptyStatement)
protected:
- template<class> friend class AstNodeFactory;
-
EmptyStatement() {}
};
@@ -1261,9 +1192,9 @@ class Literal: public Expression {
return s1->Equals(*s2);
}
- protected:
- template<class> friend class AstNodeFactory;
+ TypeFeedbackId LiteralFeedbackId() const { return reuse(id()); }
+ protected:
Literal(Isolate* isolate, Handle<Object> handle)
: Expression(isolate),
handle_(handle) { }
@@ -1381,8 +1312,6 @@ class ObjectLiteral: public MaterializedLiteral {
};
protected:
- template<class> friend class AstNodeFactory;
-
ObjectLiteral(Isolate* isolate,
Handle<FixedArray> constant_properties,
ZoneList<Property*>* properties,
@@ -1414,8 +1343,6 @@ class RegExpLiteral: public MaterializedLiteral {
Handle<String> flags() const { return flags_; }
protected:
- template<class> friend class AstNodeFactory;
-
RegExpLiteral(Isolate* isolate,
Handle<String> pattern,
Handle<String> flags,
@@ -1439,11 +1366,11 @@ class ArrayLiteral: public MaterializedLiteral {
ZoneList<Expression*>* values() const { return values_; }
// Return an AST id for an element that is used in simulate instructions.
- int GetIdForElement(int i) { return first_element_id_ + i; }
+ BailoutId GetIdForElement(int i) {
+ return BailoutId(first_element_id_.ToInt() + i);
+ }
protected:
- template<class> friend class AstNodeFactory;
-
ArrayLiteral(Isolate* isolate,
Handle<FixedArray> constant_elements,
ZoneList<Expression*>* values,
@@ -1458,7 +1385,7 @@ class ArrayLiteral: public MaterializedLiteral {
private:
Handle<FixedArray> constant_elements_;
ZoneList<Expression*>* values_;
- int first_element_id_;
+ const BailoutId first_element_id_;
};
@@ -1494,15 +1421,13 @@ class VariableProxy: public Expression {
void BindTo(Variable* var);
protected:
- template<class> friend class AstNodeFactory;
-
VariableProxy(Isolate* isolate, Variable* var);
VariableProxy(Isolate* isolate,
Handle<String> name,
bool is_this,
- int position,
- Interface* interface);
+ Interface* interface,
+ int position);
Handle<String> name_;
Variable* var_; // resolved variable, or NULL
@@ -1526,6 +1451,8 @@ class Property: public Expression {
Expression* key() const { return key_; }
virtual int position() const { return pos_; }
+ BailoutId LoadId() const { return load_id_; }
+
bool IsStringLength() const { return is_string_length_; }
bool IsStringAccess() const { return is_string_access_; }
bool IsFunctionPrototype() const { return is_function_prototype_; }
@@ -1536,10 +1463,9 @@ class Property: public Expression {
virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
bool IsArrayLength() { return is_array_length_; }
bool IsUninitialized() { return is_uninitialized_; }
+ TypeFeedbackId PropertyFeedbackId() { return reuse(id()); }
protected:
- template<class> friend class AstNodeFactory;
-
Property(Isolate* isolate,
Expression* obj,
Expression* key,
@@ -1548,6 +1474,7 @@ class Property: public Expression {
obj_(obj),
key_(key),
pos_(pos),
+ load_id_(GetNextId(isolate)),
is_monomorphic_(false),
is_uninitialized_(false),
is_array_length_(false),
@@ -1559,6 +1486,7 @@ class Property: public Expression {
Expression* obj_;
Expression* key_;
int pos_;
+ const BailoutId load_id_;
SmallMapList receiver_types_;
bool is_monomorphic_ : 1;
@@ -1578,20 +1506,25 @@ class Call: public Expression {
ZoneList<Expression*>* arguments() const { return arguments_; }
virtual int position() const { return pos_; }
- void RecordTypeFeedback(TypeFeedbackOracle* oracle,
- CallKind call_kind);
+ // Type feedback information.
+ TypeFeedbackId CallFeedbackId() const { return reuse(id()); }
+ void RecordTypeFeedback(TypeFeedbackOracle* oracle, CallKind call_kind);
virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
virtual bool IsMonomorphic() { return is_monomorphic_; }
CheckType check_type() const { return check_type_; }
Handle<JSFunction> target() { return target_; }
+
+ // A cache for the holder, set as a side effect of computing the target of the
+ // call. Note that it contains the null handle when the receiver is the same
+ // as the holder!
Handle<JSObject> holder() { return holder_; }
+
Handle<JSGlobalPropertyCell> cell() { return cell_; }
bool ComputeTarget(Handle<Map> type, Handle<String> name);
bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
- // Bailout support.
- int ReturnId() const { return return_id_; }
+ BailoutId ReturnId() const { return return_id_; }
#ifdef DEBUG
// Used to assert that the FullCodeGenerator records the return site.
@@ -1599,8 +1532,6 @@ class Call: public Expression {
#endif
protected:
- template<class> friend class AstNodeFactory;
-
Call(Isolate* isolate,
Expression* expression,
ZoneList<Expression*>* arguments,
@@ -1625,7 +1556,7 @@ class Call: public Expression {
Handle<JSObject> holder_;
Handle<JSGlobalPropertyCell> cell_;
- int return_id_;
+ const BailoutId return_id_;
};
@@ -1637,16 +1568,15 @@ class CallNew: public Expression {
ZoneList<Expression*>* arguments() const { return arguments_; }
virtual int position() const { return pos_; }
+ // Type feedback information.
+ TypeFeedbackId CallNewFeedbackId() const { return reuse(id()); }
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
virtual bool IsMonomorphic() { return is_monomorphic_; }
Handle<JSFunction> target() { return target_; }
- // Bailout support.
- int ReturnId() const { return return_id_; }
+ BailoutId ReturnId() const { return return_id_; }
protected:
- template<class> friend class AstNodeFactory;
-
CallNew(Isolate* isolate,
Expression* expression,
ZoneList<Expression*>* arguments,
@@ -1666,7 +1596,7 @@ class CallNew: public Expression {
bool is_monomorphic_;
Handle<JSFunction> target_;
- int return_id_;
+ const BailoutId return_id_;
};
@@ -1683,9 +1613,9 @@ class CallRuntime: public Expression {
ZoneList<Expression*>* arguments() const { return arguments_; }
bool is_jsruntime() const { return function_ == NULL; }
- protected:
- template<class> friend class AstNodeFactory;
+ TypeFeedbackId CallRuntimeFeedbackId() const { return reuse(id()); }
+ protected:
CallRuntime(Isolate* isolate,
Handle<String> name,
const Runtime::Function* function,
@@ -1712,12 +1642,12 @@ class UnaryOperation: public Expression {
Expression* expression() const { return expression_; }
virtual int position() const { return pos_; }
- int MaterializeTrueId() { return materialize_true_id_; }
- int MaterializeFalseId() { return materialize_false_id_; }
+ BailoutId MaterializeTrueId() { return materialize_true_id_; }
+ BailoutId MaterializeFalseId() { return materialize_false_id_; }
- protected:
- template<class> friend class AstNodeFactory;
+ TypeFeedbackId UnaryOperationFeedbackId() const { return reuse(id()); }
+ protected:
UnaryOperation(Isolate* isolate,
Token::Value op,
Expression* expression,
@@ -1726,13 +1656,9 @@ class UnaryOperation: public Expression {
op_(op),
expression_(expression),
pos_(pos),
- materialize_true_id_(AstNode::kNoNumber),
- materialize_false_id_(AstNode::kNoNumber) {
+ materialize_true_id_(GetNextId(isolate)),
+ materialize_false_id_(GetNextId(isolate)) {
ASSERT(Token::IsUnaryOp(op));
- if (op == Token::NOT) {
- materialize_true_id_ = GetNextId(isolate);
- materialize_false_id_ = GetNextId(isolate);
- }
}
private:
@@ -1742,8 +1668,8 @@ class UnaryOperation: public Expression {
// For unary not (Token::NOT), the AST ids where true and false will
// actually be materialized, respectively.
- int materialize_true_id_;
- int materialize_false_id_;
+ const BailoutId materialize_true_id_;
+ const BailoutId materialize_false_id_;
};
@@ -1758,22 +1684,23 @@ class BinaryOperation: public Expression {
Expression* right() const { return right_; }
virtual int position() const { return pos_; }
- // Bailout support.
- int RightId() const { return right_id_; }
+ BailoutId RightId() const { return right_id_; }
- protected:
- template<class> friend class AstNodeFactory;
+ TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); }
+ protected:
BinaryOperation(Isolate* isolate,
Token::Value op,
Expression* left,
Expression* right,
int pos)
- : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
+ : Expression(isolate),
+ op_(op),
+ left_(left),
+ right_(right),
+ pos_(pos),
+ right_id_(GetNextId(isolate)) {
ASSERT(Token::IsBinaryOp(op));
- right_id_ = (op == Token::AND || op == Token::OR)
- ? GetNextId(isolate)
- : AstNode::kNoNumber;
}
private:
@@ -1781,9 +1708,9 @@ class BinaryOperation: public Expression {
Expression* left_;
Expression* right_;
int pos_;
- // The short-circuit logical operations have an AST ID for their
+ // The short-circuit logical operations need an AST ID for their
// right-hand subexpression.
- int right_id_;
+ const BailoutId right_id_;
};
@@ -1808,13 +1735,12 @@ class CountOperation: public Expression {
virtual bool IsMonomorphic() { return is_monomorphic_; }
virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
- // Bailout support.
- int AssignmentId() const { return assignment_id_; }
- int CountId() const { return count_id_; }
+ BailoutId AssignmentId() const { return assignment_id_; }
- protected:
- template<class> friend class AstNodeFactory;
+ TypeFeedbackId CountBinOpFeedbackId() const { return count_id_; }
+ TypeFeedbackId CountStoreFeedbackId() const { return reuse(id()); }
+ protected:
CountOperation(Isolate* isolate,
Token::Value op,
bool is_prefix,
@@ -1834,8 +1760,8 @@ class CountOperation: public Expression {
bool is_monomorphic_;
Expression* expression_;
int pos_;
- int assignment_id_;
- int count_id_;
+ const BailoutId assignment_id_;
+ const TypeFeedbackId count_id_;
SmallMapList receiver_types_;
};
@@ -1850,6 +1776,7 @@ class CompareOperation: public Expression {
virtual int position() const { return pos_; }
// Type feedback information.
+ TypeFeedbackId CompareOperationFeedbackId() const { return reuse(id()); }
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
@@ -1860,8 +1787,6 @@ class CompareOperation: public Expression {
bool IsLiteralCompareNull(Expression** expr);
protected:
- template<class> friend class AstNodeFactory;
-
CompareOperation(Isolate* isolate,
Token::Value op,
Expression* left,
@@ -1898,12 +1823,10 @@ class Conditional: public Expression {
int then_expression_position() const { return then_expression_position_; }
int else_expression_position() const { return else_expression_position_; }
- int ThenId() const { return then_id_; }
- int ElseId() const { return else_id_; }
+ BailoutId ThenId() const { return then_id_; }
+ BailoutId ElseId() const { return else_id_; }
protected:
- template<class> friend class AstNodeFactory;
-
Conditional(Isolate* isolate,
Expression* condition,
Expression* then_expression,
@@ -1925,8 +1848,8 @@ class Conditional: public Expression {
Expression* else_expression_;
int then_expression_position_;
int else_expression_position_;
- int then_id_;
- int else_id_;
+ const BailoutId then_id_;
+ const BailoutId else_id_;
};
@@ -1947,27 +1870,15 @@ class Assignment: public Expression {
// This check relies on the definition order of token in token.h.
bool is_compound() const { return op() > Token::ASSIGN; }
- // An initialization block is a series of statments of the form
- // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
- // ending of these blocks to allow for optimizations of initialization
- // blocks.
- bool starts_initialization_block() { return block_start_; }
- bool ends_initialization_block() { return block_end_; }
- void mark_block_start() { block_start_ = true; }
- void mark_block_end() { block_end_ = true; }
+ BailoutId AssignmentId() const { return assignment_id_; }
// Type feedback information.
+ TypeFeedbackId AssignmentFeedbackId() { return reuse(id()); }
void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone);
virtual bool IsMonomorphic() { return is_monomorphic_; }
virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
- // Bailout support.
- int CompoundLoadId() const { return compound_load_id_; }
- int AssignmentId() const { return assignment_id_; }
-
protected:
- template<class> friend class AstNodeFactory;
-
Assignment(Isolate* isolate,
Token::Value op,
Expression* target,
@@ -1980,7 +1891,6 @@ class Assignment: public Expression {
if (is_compound()) {
binary_operation_ =
factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1);
- compound_load_id_ = GetNextId(isolate);
}
}
@@ -1990,11 +1900,7 @@ class Assignment: public Expression {
Expression* value_;
int pos_;
BinaryOperation* binary_operation_;
- int compound_load_id_;
- int assignment_id_;
-
- bool block_start_;
- bool block_end_;
+ const BailoutId assignment_id_;
bool is_monomorphic_;
SmallMapList receiver_types_;
@@ -2009,8 +1915,6 @@ class Throw: public Expression {
virtual int position() const { return pos_; }
protected:
- template<class> friend class AstNodeFactory;
-
Throw(Isolate* isolate, Expression* exception, int pos)
: Expression(isolate), exception_(exception), pos_(pos) {}
@@ -2038,6 +1942,11 @@ class FunctionLiteral: public Expression {
kIsFunction
};
+ enum IsParenthesizedFlag {
+ kIsParenthesized,
+ kNotParenthesized
+ };
+
DECLARE_NODE_TYPE(FunctionLiteral)
Handle<String> name() const { return name_; }
@@ -2065,6 +1974,7 @@ class FunctionLiteral: public Expression {
int parameter_count() { return parameter_count_; }
bool AllowsLazyCompilation();
+ bool AllowsLazyCompilationWithoutContext();
Handle<String> debug_name() const {
if (name_->length() > 0) return name_;
@@ -2085,6 +1995,18 @@ class FunctionLiteral: public Expression {
bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
+ // This is used as a heuristic on when to eagerly compile a function
+ // literal. We consider the following constructs as hints that the
+ // function will be called immediately:
+ // - (function() { ... })();
+ // - var x = function() { ... }();
+ bool is_parenthesized() {
+ return IsParenthesized::decode(bitfield_) == kIsParenthesized;
+ }
+ void set_parenthesized() {
+ bitfield_ = IsParenthesized::update(bitfield_, kIsParenthesized);
+ }
+
int ast_node_count() { return ast_properties_.node_count(); }
AstProperties::Flags* flags() { return ast_properties_.flags(); }
void set_ast_properties(AstProperties* ast_properties) {
@@ -2092,8 +2014,6 @@ class FunctionLiteral: public Expression {
}
protected:
- template<class> friend class AstNodeFactory;
-
FunctionLiteral(Isolate* isolate,
Handle<String> name,
Scope* scope,
@@ -2106,7 +2026,8 @@ class FunctionLiteral: public Expression {
int parameter_count,
Type type,
ParameterFlag has_duplicate_parameters,
- IsFunctionFlag is_function)
+ IsFunctionFlag is_function,
+ IsParenthesizedFlag is_parenthesized)
: Expression(isolate),
name_(name),
scope_(scope),
@@ -2125,7 +2046,8 @@ class FunctionLiteral: public Expression {
IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
Pretenure::encode(false) |
HasDuplicateParameters::encode(has_duplicate_parameters) |
- IsFunction::encode(is_function);
+ IsFunction::encode(is_function) |
+ IsParenthesized::encode(is_parenthesized);
}
private:
@@ -2149,6 +2071,7 @@ class FunctionLiteral: public Expression {
class Pretenure: public BitField<bool, 3, 1> {};
class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
+ class IsParenthesized: public BitField<IsParenthesizedFlag, 6, 1> {};
};
@@ -2161,8 +2084,6 @@ class SharedFunctionInfoLiteral: public Expression {
}
protected:
- template<class> friend class AstNodeFactory;
-
SharedFunctionInfoLiteral(
Isolate* isolate,
Handle<SharedFunctionInfo> shared_function_info)
@@ -2179,8 +2100,6 @@ class ThisFunction: public Expression {
DECLARE_NODE_TYPE(ThisFunction)
protected:
- template<class> friend class AstNodeFactory;
-
explicit ThisFunction(Isolate* isolate): Expression(isolate) {}
};
@@ -2638,9 +2557,9 @@ class AstNullVisitor BASE_EMBEDDED {
template<class Visitor>
class AstNodeFactory BASE_EMBEDDED {
public:
- explicit AstNodeFactory(Isolate* isolate)
+ AstNodeFactory(Isolate* isolate, Zone* zone)
: isolate_(isolate),
- zone_(isolate_->zone()) { }
+ zone_(zone) { }
Visitor* visitor() { return &visitor_; }
@@ -2710,10 +2629,9 @@ class AstNodeFactory BASE_EMBEDDED {
Block* NewBlock(ZoneStringList* labels,
int capacity,
- bool is_initializer_block,
- Zone* zone) {
+ bool is_initializer_block) {
Block* block = new(zone_) Block(
- isolate_, labels, capacity, is_initializer_block, zone);
+ isolate_, labels, capacity, is_initializer_block, zone_);
VISIT_AND_RETURN(Block, block)
}
@@ -2846,11 +2764,10 @@ class AstNodeFactory BASE_EMBEDDED {
VariableProxy* NewVariableProxy(Handle<String> name,
bool is_this,
- int position = RelocInfo::kNoPosition,
- Interface* interface =
- Interface::NewValue()) {
+ Interface* interface = Interface::NewValue(),
+ int position = RelocInfo::kNoPosition) {
VariableProxy* proxy =
- new(zone_) VariableProxy(isolate_, name, is_this, position, interface);
+ new(zone_) VariableProxy(isolate_, name, is_this, interface, position);
VISIT_AND_RETURN(VariableProxy, proxy)
}
@@ -2954,12 +2871,14 @@ class AstNodeFactory BASE_EMBEDDED {
int parameter_count,
FunctionLiteral::ParameterFlag has_duplicate_parameters,
FunctionLiteral::Type type,
- FunctionLiteral::IsFunctionFlag is_function) {
+ FunctionLiteral::IsFunctionFlag is_function,
+ FunctionLiteral::IsParenthesizedFlag is_parenthesized) {
FunctionLiteral* lit = new(zone_) FunctionLiteral(
isolate_, name, scope, body,
materialized_literal_count, expected_property_count, handler_count,
has_only_simple_this_property_assignments, this_property_assignments,
- parameter_count, type, has_duplicate_parameters, is_function);
+ parameter_count, type, has_duplicate_parameters, is_function,
+ is_parenthesized);
// Top-level literal doesn't count for the AST's properties.
if (is_function == FunctionLiteral::kIsFunction) {
visitor_.VisitFunctionLiteral(lit);
diff --git a/deps/v8/src/atomicops.h b/deps/v8/src/atomicops.h
index e2057ed07..1f0c44a67 100644
--- a/deps/v8/src/atomicops.h
+++ b/deps/v8/src/atomicops.h
@@ -69,7 +69,11 @@ typedef intptr_t Atomic64;
// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or
// Atomic64 routines below, depending on your architecture.
+#if defined(__OpenBSD__) && defined(__i386__)
+typedef Atomic32 AtomicWord;
+#else
typedef intptr_t AtomicWord;
+#endif
// Atomically execute:
// result = *ptr;
diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc
index 33cbb8149..a368eefe7 100644
--- a/deps/v8/src/bootstrapper.cc
+++ b/deps/v8/src/bootstrapper.cc
@@ -42,6 +42,7 @@
#include "snapshot.h"
#include "extensions/externalize-string-extension.h"
#include "extensions/gc-extension.h"
+#include "extensions/statistics-extension.h"
namespace v8 {
namespace internal {
@@ -95,6 +96,7 @@ void Bootstrapper::Initialize(bool create_heap_objects) {
extensions_cache_.Initialize(create_heap_objects);
GCExtension::Register();
ExternalizeStringExtension::Register();
+ StatisticsExtension::Register();
}
@@ -154,7 +156,7 @@ class Genesis BASE_EMBEDDED {
Heap* heap() const { return isolate_->heap(); }
private:
- Handle<Context> global_context_;
+ Handle<Context> native_context_;
Isolate* isolate_;
// There may be more than one active genesis object: When GC is
@@ -162,7 +164,7 @@ class Genesis BASE_EMBEDDED {
// processing callbacks which may create new environments.
Genesis* previous_;
- Handle<Context> global_context() { return global_context_; }
+ Handle<Context> native_context() { return native_context_; }
// Creates some basic objects. Used for creating a context from scratch.
void CreateRoots();
@@ -226,13 +228,13 @@ class Genesis BASE_EMBEDDED {
// Used both for deserialized and from-scratch contexts to add the extensions
// provided.
- static bool InstallExtensions(Handle<Context> global_context,
+ static bool InstallExtensions(Handle<Context> native_context,
v8::ExtensionConfiguration* extensions);
static bool InstallExtension(const char* name,
ExtensionStates* extension_states);
static bool InstallExtension(v8::RegisteredExtension* current,
ExtensionStates* extension_states);
- static void InstallSpecialObjects(Handle<Context> global_context);
+ static void InstallSpecialObjects(Handle<Context> native_context);
bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
bool ConfigureApiObject(Handle<JSObject> object,
Handle<ObjectTemplateInfo> object_template);
@@ -253,16 +255,16 @@ class Genesis BASE_EMBEDDED {
Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);
- Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
- PrototypePropertyMode prototypeMode);
+ void SetFunctionInstanceDescriptor(Handle<Map> map,
+ PrototypePropertyMode prototypeMode);
void MakeFunctionInstancePrototypeWritable();
Handle<Map> CreateStrictModeFunctionMap(
PrototypePropertyMode prototype_mode,
Handle<JSFunction> empty_function);
- Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
- PrototypePropertyMode propertyMode);
+ void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
+ PrototypePropertyMode propertyMode);
static bool CompileBuiltin(Isolate* isolate, int index);
static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
@@ -317,7 +319,7 @@ static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
// object.__proto__ = proto;
Factory* factory = object->GetIsolate()->factory();
Handle<Map> old_to_map = Handle<Map>(object->map());
- Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
+ Handle<Map> new_to_map = factory->CopyMap(old_to_map);
new_to_map->set_prototype(*proto);
object->set_map(*new_to_map);
}
@@ -325,22 +327,20 @@ static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
void Bootstrapper::DetachGlobal(Handle<Context> env) {
Factory* factory = env->GetIsolate()->factory();
- JSGlobalProxy::cast(env->global_proxy())->set_context(*factory->null_value());
- SetObjectPrototype(Handle<JSObject>(env->global_proxy()),
- factory->null_value());
- env->set_global_proxy(env->global());
- env->global()->set_global_receiver(env->global());
+ Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy()));
+ global_proxy->set_native_context(*factory->null_value());
+ SetObjectPrototype(global_proxy, factory->null_value());
+ env->set_global_proxy(env->global_object());
+ env->global_object()->set_global_receiver(env->global_object());
}
void Bootstrapper::ReattachGlobal(Handle<Context> env,
- Handle<Object> global_object) {
- ASSERT(global_object->IsJSGlobalProxy());
- Handle<JSGlobalProxy> global = Handle<JSGlobalProxy>::cast(global_object);
- env->global()->set_global_receiver(*global);
- env->set_global_proxy(*global);
- SetObjectPrototype(global, Handle<JSObject>(env->global()));
- global->set_context(*env);
+ Handle<JSGlobalProxy> global_proxy) {
+ env->global_object()->set_global_receiver(*global_proxy);
+ env->set_global_proxy(*global_proxy);
+ SetObjectPrototype(global_proxy, Handle<JSObject>(env->global_object()));
+ global_proxy->set_native_context(*env);
}
@@ -381,54 +381,54 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
}
-Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
- PrototypePropertyMode prototypeMode) {
+void Genesis::SetFunctionInstanceDescriptor(
+ Handle<Map> map, PrototypePropertyMode prototypeMode) {
int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
- Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(size));
+ Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(0, size));
+ DescriptorArray::WhitenessWitness witness(*descriptors);
+
+ Handle<Foreign> length(factory()->NewForeign(&Accessors::FunctionLength));
+ Handle<Foreign> name(factory()->NewForeign(&Accessors::FunctionName));
+ Handle<Foreign> args(factory()->NewForeign(&Accessors::FunctionArguments));
+ Handle<Foreign> caller(factory()->NewForeign(&Accessors::FunctionCaller));
+ Handle<Foreign> prototype;
+ if (prototypeMode != DONT_ADD_PROTOTYPE) {
+ prototype = factory()->NewForeign(&Accessors::FunctionPrototype);
+ }
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE | READ_ONLY);
-
- DescriptorArray::WhitenessWitness witness(*descriptors);
+ map->set_instance_descriptors(*descriptors);
{ // Add length.
- Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionLength));
- CallbacksDescriptor d(*factory()->length_symbol(), *f, attribs);
- descriptors->Set(0, &d, witness);
+ CallbacksDescriptor d(*factory()->length_symbol(), *length, attribs);
+ map->AppendDescriptor(&d, witness);
}
{ // Add name.
- Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionName));
- CallbacksDescriptor d(*factory()->name_symbol(), *f, attribs);
- descriptors->Set(1, &d, witness);
+ CallbacksDescriptor d(*factory()->name_symbol(), *name, attribs);
+ map->AppendDescriptor(&d, witness);
}
{ // Add arguments.
- Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionArguments));
- CallbacksDescriptor d(*factory()->arguments_symbol(), *f, attribs);
- descriptors->Set(2, &d, witness);
+ CallbacksDescriptor d(*factory()->arguments_symbol(), *args, attribs);
+ map->AppendDescriptor(&d, witness);
}
{ // Add caller.
- Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionCaller));
- CallbacksDescriptor d(*factory()->caller_symbol(), *f, attribs);
- descriptors->Set(3, &d, witness);
+ CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attribs);
+ map->AppendDescriptor(&d, witness);
}
if (prototypeMode != DONT_ADD_PROTOTYPE) {
// Add prototype.
if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
attribs = static_cast<PropertyAttributes>(attribs & ~READ_ONLY);
}
- Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionPrototype));
- CallbacksDescriptor d(*factory()->prototype_symbol(), *f, attribs);
- descriptors->Set(4, &d, witness);
+ CallbacksDescriptor d(*factory()->prototype_symbol(), *prototype, attribs);
+ map->AppendDescriptor(&d, witness);
}
- descriptors->Sort(witness);
- return descriptors;
}
Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
- Handle<DescriptorArray> descriptors =
- ComputeFunctionInstanceDescriptor(prototype_mode);
- map->set_instance_descriptors(*descriptors);
+ SetFunctionInstanceDescriptor(map, prototype_mode);
map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
return map;
}
@@ -442,20 +442,20 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
// writable.
Handle<Map> function_instance_map =
CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
- global_context()->set_function_instance_map(*function_instance_map);
+ native_context()->set_function_instance_map(*function_instance_map);
// Functions with this map will not have a 'prototype' property, and
// can not be used as constructors.
Handle<Map> function_without_prototype_map =
CreateFunctionMap(DONT_ADD_PROTOTYPE);
- global_context()->set_function_without_prototype_map(
+ native_context()->set_function_without_prototype_map(
*function_without_prototype_map);
// Allocate the function map. This map is temporary, used only for processing
// of builtins.
// Later the map is replaced with writable prototype map, allocated below.
Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE);
- global_context()->set_function_map(*function_map);
+ native_context()->set_function_map(*function_map);
// The final map for functions. Writeable prototype.
// This map is installed in MakeFunctionInstancePrototypeWritable.
@@ -475,17 +475,15 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
object_fun->set_initial_map(*object_function_map);
object_function_map->set_constructor(*object_fun);
- global_context()->set_object_function(*object_fun);
+ native_context()->set_object_function(*object_fun);
// Allocate a new prototype for the object function.
Handle<JSObject> prototype = factory->NewJSObject(
isolate->object_function(),
TENURED);
- global_context()->set_initial_object_prototype(*prototype);
+ native_context()->set_initial_object_prototype(*prototype);
SetPrototype(object_fun, prototype);
- object_function_map->set_instance_descriptors(
- heap->empty_descriptor_array());
}
// Allocate the empty function as the prototype for function ECMAScript
@@ -509,63 +507,63 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
empty_function->shared()->DontAdaptArguments();
// Set prototypes for the function maps.
- global_context()->function_map()->set_prototype(*empty_function);
- global_context()->function_instance_map()->set_prototype(*empty_function);
- global_context()->function_without_prototype_map()->
+ native_context()->function_map()->set_prototype(*empty_function);
+ native_context()->function_instance_map()->set_prototype(*empty_function);
+ native_context()->function_without_prototype_map()->
set_prototype(*empty_function);
function_instance_map_writable_prototype_->set_prototype(*empty_function);
// Allocate the function map first and then patch the prototype later
Handle<Map> empty_function_map = CreateFunctionMap(DONT_ADD_PROTOTYPE);
empty_function_map->set_prototype(
- global_context()->object_function()->prototype());
+ native_context()->object_function()->prototype());
empty_function->set_map(*empty_function_map);
return empty_function;
}
-Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
- PrototypePropertyMode prototypeMode) {
+void Genesis::SetStrictFunctionInstanceDescriptor(
+ Handle<Map> map, PrototypePropertyMode prototypeMode) {
int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
- Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(size));
+ Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(0, size));
+ DescriptorArray::WhitenessWitness witness(*descriptors);
+
+ Handle<Foreign> length(factory()->NewForeign(&Accessors::FunctionLength));
+ Handle<Foreign> name(factory()->NewForeign(&Accessors::FunctionName));
+ Handle<AccessorPair> arguments(factory()->NewAccessorPair());
+ Handle<AccessorPair> caller(factory()->NewAccessorPair());
+ Handle<Foreign> prototype;
+ if (prototypeMode != DONT_ADD_PROTOTYPE) {
+ prototype = factory()->NewForeign(&Accessors::FunctionPrototype);
+ }
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE);
-
- DescriptorArray::WhitenessWitness witness(*descriptors);
+ map->set_instance_descriptors(*descriptors);
{ // Add length.
- Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionLength));
- CallbacksDescriptor d(*factory()->length_symbol(), *f, attribs);
- descriptors->Set(0, &d, witness);
+ CallbacksDescriptor d(*factory()->length_symbol(), *length, attribs);
+ map->AppendDescriptor(&d, witness);
}
{ // Add name.
- Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionName));
- CallbacksDescriptor d(*factory()->name_symbol(), *f, attribs);
- descriptors->Set(1, &d, witness);
+ CallbacksDescriptor d(*factory()->name_symbol(), *name, attribs);
+ map->AppendDescriptor(&d, witness);
}
{ // Add arguments.
- Handle<AccessorPair> arguments(factory()->NewAccessorPair());
CallbacksDescriptor d(*factory()->arguments_symbol(), *arguments, attribs);
- descriptors->Set(2, &d, witness);
+ map->AppendDescriptor(&d, witness);
}
{ // Add caller.
- Handle<AccessorPair> caller(factory()->NewAccessorPair());
CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attribs);
- descriptors->Set(3, &d, witness);
+ map->AppendDescriptor(&d, witness);
}
-
if (prototypeMode != DONT_ADD_PROTOTYPE) {
// Add prototype.
if (prototypeMode != ADD_WRITEABLE_PROTOTYPE) {
attribs = static_cast<PropertyAttributes>(attribs | READ_ONLY);
}
- Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionPrototype));
- CallbacksDescriptor d(*factory()->prototype_symbol(), *f, attribs);
- descriptors->Set(4, &d, witness);
+ CallbacksDescriptor d(*factory()->prototype_symbol(), *prototype, attribs);
+ map->AppendDescriptor(&d, witness);
}
-
- descriptors->Sort(witness);
- return descriptors;
}
@@ -578,7 +576,7 @@ Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() {
Handle<Code> code(isolate()->builtins()->builtin(
Builtins::kStrictModePoisonPill));
throw_type_error_function->set_map(
- global_context()->function_map());
+ native_context()->function_map());
throw_type_error_function->set_code(*code);
throw_type_error_function->shared()->set_code(*code);
throw_type_error_function->shared()->DontAdaptArguments();
@@ -593,9 +591,7 @@ Handle<Map> Genesis::CreateStrictModeFunctionMap(
PrototypePropertyMode prototype_mode,
Handle<JSFunction> empty_function) {
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
- Handle<DescriptorArray> descriptors =
- ComputeStrictFunctionInstanceDescriptor(prototype_mode);
- map->set_instance_descriptors(*descriptors);
+ SetStrictFunctionInstanceDescriptor(map, prototype_mode);
map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
map->set_prototype(*empty_function);
return map;
@@ -606,13 +602,13 @@ void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
// Allocate map for the strict mode function instances.
Handle<Map> strict_mode_function_instance_map =
CreateStrictModeFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
- global_context()->set_strict_mode_function_instance_map(
+ native_context()->set_strict_mode_function_instance_map(
*strict_mode_function_instance_map);
// Allocate map for the prototype-less strict mode instances.
Handle<Map> strict_mode_function_without_prototype_map =
CreateStrictModeFunctionMap(DONT_ADD_PROTOTYPE, empty);
- global_context()->set_strict_mode_function_without_prototype_map(
+ native_context()->set_strict_mode_function_without_prototype_map(
*strict_mode_function_without_prototype_map);
// Allocate map for the strict mode functions. This map is temporary, used
@@ -620,7 +616,7 @@ void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
// Later the map is replaced with writable prototype map, allocated below.
Handle<Map> strict_mode_function_map =
CreateStrictModeFunctionMap(ADD_READONLY_PROTOTYPE, empty);
- global_context()->set_strict_mode_function_map(
+ native_context()->set_strict_mode_function_map(
*strict_mode_function_map);
// The final map for the strict mode functions. Writeable prototype.
@@ -641,7 +637,7 @@ static void SetAccessors(Handle<Map> map,
Handle<String> name,
Handle<JSFunction> func) {
DescriptorArray* descs = map->instance_descriptors();
- int number = descs->Search(*name);
+ int number = descs->SearchWithCache(*name, *map);
AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number));
accessors->set_getter(*func);
accessors->set_setter(*func);
@@ -654,39 +650,39 @@ void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) {
}
-static void AddToWeakGlobalContextList(Context* context) {
- ASSERT(context->IsGlobalContext());
+static void AddToWeakNativeContextList(Context* context) {
+ ASSERT(context->IsNativeContext());
Heap* heap = context->GetIsolate()->heap();
#ifdef DEBUG
{ // NOLINT
ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
// Check that context is not in the list yet.
- for (Object* current = heap->global_contexts_list();
+ for (Object* current = heap->native_contexts_list();
!current->IsUndefined();
current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
ASSERT(current != context);
}
}
#endif
- context->set(Context::NEXT_CONTEXT_LINK, heap->global_contexts_list());
- heap->set_global_contexts_list(context);
+ context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list());
+ heap->set_native_contexts_list(context);
}
void Genesis::CreateRoots() {
- // Allocate the global context FixedArray first and then patch the
+ // Allocate the native context FixedArray first and then patch the
// closure and extension object later (we need the empty function
// and the global object, but in order to create those, we need the
- // global context).
- global_context_ = Handle<Context>::cast(isolate()->global_handles()->Create(
- *factory()->NewGlobalContext()));
- AddToWeakGlobalContextList(*global_context_);
- isolate()->set_context(*global_context());
+ // native context).
+ native_context_ = Handle<Context>::cast(isolate()->global_handles()->Create(
+ *factory()->NewNativeContext()));
+ AddToWeakNativeContextList(*native_context_);
+ isolate()->set_context(*native_context());
// Allocate the message listeners object.
{
v8::NeanderArray listeners;
- global_context()->set_message_listeners(*listeners.value());
+ native_context()->set_message_listeners(*listeners.value());
}
}
@@ -749,6 +745,7 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
}
js_global_function->initial_map()->set_is_hidden_prototype();
+ js_global_function->initial_map()->set_dictionary_map(true);
Handle<GlobalObject> inner_global =
factory()->NewGlobalObject(js_global_function);
if (inner_global_out != NULL) {
@@ -795,21 +792,22 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
Handle<JSGlobalProxy> global_proxy) {
- // Set the global context for the global object.
- inner_global->set_global_context(*global_context());
+ // Set the native context for the global object.
+ inner_global->set_native_context(*native_context());
+ inner_global->set_global_context(*native_context());
inner_global->set_global_receiver(*global_proxy);
- global_proxy->set_context(*global_context());
- global_context()->set_global_proxy(*global_proxy);
+ global_proxy->set_native_context(*native_context());
+ native_context()->set_global_proxy(*global_proxy);
}
void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
Handle<GlobalObject> inner_global_from_snapshot(
- GlobalObject::cast(global_context_->extension()));
- Handle<JSBuiltinsObject> builtins_global(global_context_->builtins());
- global_context_->set_extension(*inner_global);
- global_context_->set_global(*inner_global);
- global_context_->set_security_token(*inner_global);
+ GlobalObject::cast(native_context_->extension()));
+ Handle<JSBuiltinsObject> builtins_global(native_context_->builtins());
+ native_context_->set_extension(*inner_global);
+ native_context_->set_global_object(*inner_global);
+ native_context_->set_security_token(*inner_global);
static const PropertyAttributes attributes =
static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
ForceSetProperty(builtins_global,
@@ -829,16 +827,16 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<JSFunction> empty_function) {
// --- G l o b a l C o n t e x t ---
// Use the empty function as closure (no scope info).
- global_context()->set_closure(*empty_function);
- global_context()->set_previous(NULL);
+ native_context()->set_closure(*empty_function);
+ native_context()->set_previous(NULL);
// Set extension and global object.
- global_context()->set_extension(*inner_global);
- global_context()->set_global(*inner_global);
+ native_context()->set_extension(*inner_global);
+ native_context()->set_global_object(*inner_global);
// Security setup: Set the security token of the global object to
// its the inner global. This makes the security check between two
// different contexts fail by default even in case of global
// object reinitialization.
- global_context()->set_security_token(*inner_global);
+ native_context()->set_security_token(*inner_global);
Isolate* isolate = inner_global->GetIsolate();
Factory* factory = isolate->factory();
@@ -850,7 +848,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
inner_global, object_name,
isolate->object_function(), DONT_ENUM));
- Handle<JSObject> global = Handle<JSObject>(global_context()->global());
+ Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
// Install global Function object
InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
@@ -868,19 +866,27 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// This seems a bit hackish, but we need to make sure Array.length
// is 1.
array_function->shared()->set_length(1);
- Handle<DescriptorArray> array_descriptors =
- factory->CopyAppendForeignDescriptor(
- factory->empty_descriptor_array(),
- factory->length_symbol(),
- factory->NewForeign(&Accessors::ArrayLength),
- static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
+
+ Handle<Map> initial_map(array_function->initial_map());
+ Handle<DescriptorArray> array_descriptors(
+ factory->NewDescriptorArray(0, 1));
+ DescriptorArray::WhitenessWitness witness(*array_descriptors);
+
+ Handle<Foreign> array_length(factory->NewForeign(&Accessors::ArrayLength));
+ PropertyAttributes attribs = static_cast<PropertyAttributes>(
+ DONT_ENUM | DONT_DELETE);
+ initial_map->set_instance_descriptors(*array_descriptors);
+
+ { // Add length.
+ CallbacksDescriptor d(*factory->length_symbol(), *array_length, attribs);
+ array_function->initial_map()->AppendDescriptor(&d, witness);
+ }
// array_function is used internally. JS code creating array object should
// search for the 'Array' property on the global object and use that one
// as the constructor. 'Array' property on a global object can be
// overwritten by JS code.
- global_context()->set_array_function(*array_function);
- array_function->initial_map()->set_instance_descriptors(*array_descriptors);
+ native_context()->set_array_function(*array_function);
}
{ // --- N u m b e r ---
@@ -888,7 +894,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
isolate->initial_object_prototype(),
Builtins::kIllegal, true);
- global_context()->set_number_function(*number_fun);
+ native_context()->set_number_function(*number_fun);
}
{ // --- B o o l e a n ---
@@ -896,7 +902,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
isolate->initial_object_prototype(),
Builtins::kIllegal, true);
- global_context()->set_boolean_function(*boolean_fun);
+ native_context()->set_boolean_function(*boolean_fun);
}
{ // --- S t r i n g ---
@@ -906,20 +912,24 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Builtins::kIllegal, true);
string_fun->shared()->set_construct_stub(
isolate->builtins()->builtin(Builtins::kStringConstructCode));
- global_context()->set_string_function(*string_fun);
- // Add 'length' property to strings.
- Handle<DescriptorArray> string_descriptors =
- factory->CopyAppendForeignDescriptor(
- factory->empty_descriptor_array(),
- factory->length_symbol(),
- factory->NewForeign(&Accessors::StringLength),
- static_cast<PropertyAttributes>(DONT_ENUM |
- DONT_DELETE |
- READ_ONLY));
+ native_context()->set_string_function(*string_fun);
Handle<Map> string_map =
- Handle<Map>(global_context()->string_function()->initial_map());
+ Handle<Map>(native_context()->string_function()->initial_map());
+ Handle<DescriptorArray> string_descriptors(
+ factory->NewDescriptorArray(0, 1));
+ DescriptorArray::WhitenessWitness witness(*string_descriptors);
+
+ Handle<Foreign> string_length(
+ factory->NewForeign(&Accessors::StringLength));
+ PropertyAttributes attribs = static_cast<PropertyAttributes>(
+ DONT_ENUM | DONT_DELETE | READ_ONLY);
string_map->set_instance_descriptors(*string_descriptors);
+
+ { // Add length.
+ CallbacksDescriptor d(*factory->length_symbol(), *string_length, attribs);
+ string_map->AppendDescriptor(&d, witness);
+ }
}
{ // --- D a t e ---
@@ -929,7 +939,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
isolate->initial_object_prototype(),
Builtins::kIllegal, true);
- global_context()->set_date_function(*date_fun);
+ native_context()->set_date_function(*date_fun);
}
@@ -939,49 +949,46 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
isolate->initial_object_prototype(),
Builtins::kIllegal, true);
- global_context()->set_regexp_function(*regexp_fun);
+ native_context()->set_regexp_function(*regexp_fun);
ASSERT(regexp_fun->has_initial_map());
Handle<Map> initial_map(regexp_fun->initial_map());
ASSERT_EQ(0, initial_map->inobject_properties());
- Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5);
- DescriptorArray::WhitenessWitness witness(*descriptors);
PropertyAttributes final =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
- int enum_index = 0;
+ Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 5);
+ DescriptorArray::WhitenessWitness witness(*descriptors);
+ initial_map->set_instance_descriptors(*descriptors);
+
{
// ECMA-262, section 15.10.7.1.
FieldDescriptor field(heap->source_symbol(),
JSRegExp::kSourceFieldIndex,
- final,
- enum_index++);
- descriptors->Set(0, &field, witness);
+ final);
+ initial_map->AppendDescriptor(&field, witness);
}
{
// ECMA-262, section 15.10.7.2.
FieldDescriptor field(heap->global_symbol(),
JSRegExp::kGlobalFieldIndex,
- final,
- enum_index++);
- descriptors->Set(1, &field, witness);
+ final);
+ initial_map->AppendDescriptor(&field, witness);
}
{
// ECMA-262, section 15.10.7.3.
FieldDescriptor field(heap->ignore_case_symbol(),
JSRegExp::kIgnoreCaseFieldIndex,
- final,
- enum_index++);
- descriptors->Set(2, &field, witness);
+ final);
+ initial_map->AppendDescriptor(&field, witness);
}
{
// ECMA-262, section 15.10.7.4.
FieldDescriptor field(heap->multiline_symbol(),
JSRegExp::kMultilineFieldIndex,
- final,
- enum_index++);
- descriptors->Set(3, &field, witness);
+ final);
+ initial_map->AppendDescriptor(&field, witness);
}
{
// ECMA-262, section 15.10.7.5.
@@ -989,24 +996,20 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
FieldDescriptor field(heap->last_index_symbol(),
JSRegExp::kLastIndexFieldIndex,
- writable,
- enum_index++);
- descriptors->Set(4, &field, witness);
+ writable);
+ initial_map->AppendDescriptor(&field, witness);
}
- descriptors->SetNextEnumerationIndex(enum_index);
- descriptors->Sort(witness);
initial_map->set_inobject_properties(5);
initial_map->set_pre_allocated_property_fields(5);
initial_map->set_unused_property_fields(0);
initial_map->set_instance_size(
initial_map->instance_size() + 5 * kPointerSize);
- initial_map->set_instance_descriptors(*descriptors);
initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
// RegExp prototype object is itself a RegExp.
- Handle<Map> proto_map = factory->CopyMapDropTransitions(initial_map);
- proto_map->set_prototype(global_context()->initial_object_prototype());
+ Handle<Map> proto_map = factory->CopyMap(initial_map);
+ proto_map->set_prototype(native_context()->initial_object_prototype());
Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
heap->query_colon_symbol());
@@ -1030,7 +1033,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<JSFunction> cons = factory->NewFunction(name,
factory->the_hole_value());
{ MaybeObject* result = cons->SetInstancePrototype(
- global_context()->initial_object_prototype());
+ native_context()->initial_object_prototype());
if (result->IsFailure()) return false;
}
cons->SetInstanceClassName(*name);
@@ -1039,7 +1042,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
CHECK_NOT_EMPTY_HANDLE(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
global, name, json_object, DONT_ENUM));
- global_context()->set_json_object(*json_object);
+ native_context()->set_json_object(*json_object);
}
{ // --- arguments_boilerplate_
@@ -1051,7 +1054,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
isolate->builtins()->builtin(Builtins::kIllegal));
Handle<JSObject> prototype =
Handle<JSObject>(
- JSObject::cast(global_context()->object_function()->prototype()));
+ JSObject::cast(native_context()->object_function()->prototype()));
Handle<JSFunction> function =
factory->NewFunctionWithPrototype(symbol,
@@ -1065,7 +1068,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
function->shared()->set_expected_nof_properties(2);
Handle<JSObject> result = factory->NewJSObject(function);
- global_context()->set_arguments_boilerplate(*result);
+ native_context()->set_arguments_boilerplate(*result);
// Note: length must be added as the first property and
// callee must be added as the second property.
CHECK_NOT_EMPTY_HANDLE(isolate,
@@ -1080,11 +1083,11 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
#ifdef DEBUG
LookupResult lookup(isolate);
result->LocalLookup(heap->callee_symbol(), &lookup);
- ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
+ ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
result->LocalLookup(heap->length_symbol(), &lookup);
- ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
+ ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
@@ -1106,8 +1109,8 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
array = factory->NewFixedArray(0);
elements->set(1, *array);
- Handle<Map> old_map(global_context()->arguments_boilerplate()->map());
- Handle<Map> new_map = factory->CopyMapDropTransitions(old_map);
+ Handle<Map> old_map(native_context()->arguments_boilerplate()->map());
+ Handle<Map> new_map = factory->CopyMap(old_map);
new_map->set_pre_allocated_property_fields(2);
Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
// Set elements kind after allocating the object because
@@ -1115,7 +1118,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
result->set_elements(*elements);
ASSERT(result->HasNonStrictArgumentsElements());
- global_context()->set_aliased_arguments_boilerplate(*result);
+ native_context()->set_aliased_arguments_boilerplate(*result);
}
{ // --- strict mode arguments boilerplate
@@ -1135,39 +1138,43 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
caller->set_getter(*throw_function);
caller->set_setter(*throw_function);
+ // Create the map. Allocate one in-object field for length.
+ Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
+ Heap::kArgumentsObjectSizeStrict);
// Create the descriptor array for the arguments object.
- Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
+ Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 3);
DescriptorArray::WhitenessWitness witness(*descriptors);
+ map->set_instance_descriptors(*descriptors);
+
{ // length
FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
- descriptors->Set(0, &d, witness);
+ map->AppendDescriptor(&d, witness);
}
{ // callee
- CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes);
- descriptors->Set(1, &d, witness);
+ CallbacksDescriptor d(*factory->callee_symbol(),
+ *callee,
+ attributes);
+ map->AppendDescriptor(&d, witness);
}
{ // caller
- CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
- descriptors->Set(2, &d, witness);
+ CallbacksDescriptor d(*factory->caller_symbol(),
+ *caller,
+ attributes);
+ map->AppendDescriptor(&d, witness);
}
- descriptors->Sort(witness);
- // Create the map. Allocate one in-object field for length.
- Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
- Heap::kArgumentsObjectSizeStrict);
- map->set_instance_descriptors(*descriptors);
map->set_function_with_prototype(true);
- map->set_prototype(global_context()->object_function()->prototype());
+ map->set_prototype(native_context()->object_function()->prototype());
map->set_pre_allocated_property_fields(1);
map->set_inobject_properties(1);
// Copy constructor from the non-strict arguments boilerplate.
map->set_constructor(
- global_context()->arguments_boilerplate()->map()->constructor());
+ native_context()->arguments_boilerplate()->map()->constructor());
// Allocate the arguments boilerplate object.
Handle<JSObject> result = factory->NewJSObjectFromMap(map);
- global_context()->set_strict_mode_arguments_boilerplate(*result);
+ native_context()->set_strict_mode_arguments_boilerplate(*result);
// Add length property only for strict mode boilerplate.
CHECK_NOT_EMPTY_HANDLE(isolate,
@@ -1178,7 +1185,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
#ifdef DEBUG
LookupResult lookup(isolate);
result->LocalLookup(heap->length_symbol(), &lookup);
- ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
+ ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
@@ -1202,7 +1209,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<String> name = factory->LookupAsciiSymbol("context_extension");
context_extension_fun->shared()->set_instance_class_name(*name);
- global_context()->set_context_extension_function(*context_extension_fun);
+ native_context()->set_context_extension_function(*context_extension_fun);
}
@@ -1214,7 +1221,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<JSFunction> delegate =
factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
JSObject::kHeaderSize, code, true);
- global_context()->set_call_as_function_delegate(*delegate);
+ native_context()->set_call_as_function_delegate(*delegate);
delegate->shared()->DontAdaptArguments();
}
@@ -1226,21 +1233,21 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<JSFunction> delegate =
factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
JSObject::kHeaderSize, code, true);
- global_context()->set_call_as_constructor_delegate(*delegate);
+ native_context()->set_call_as_constructor_delegate(*delegate);
delegate->shared()->DontAdaptArguments();
}
// Initialize the out of memory slot.
- global_context()->set_out_of_memory(heap->false_value());
+ native_context()->set_out_of_memory(heap->false_value());
// Initialize the data slot.
- global_context()->set_data(heap->undefined_value());
+ native_context()->set_data(heap->undefined_value());
{
// Initialize the random seed slot.
Handle<ByteArray> zeroed_byte_array(
factory->NewByteArray(kRandomStateSize));
- global_context()->set_random_seed(*zeroed_byte_array);
+ native_context()->set_random_seed(*zeroed_byte_array);
memset(zeroed_byte_array->GetDataStartAddress(), 0, kRandomStateSize);
}
return true;
@@ -1248,7 +1255,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
void Genesis::InitializeExperimentalGlobal() {
- Handle<JSObject> global = Handle<JSObject>(global_context()->global());
+ Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
// TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no
// longer need to live behind a flag, so functions get added to the snapshot.
@@ -1340,6 +1347,7 @@ bool Genesis::CompileScriptCached(Vector<const char> name,
script_name,
0,
0,
+ top_context,
extension,
NULL,
Handle<String>::null(),
@@ -1351,7 +1359,7 @@ bool Genesis::CompileScriptCached(Vector<const char> name,
// Set up the function context. Conceptually, we should clone the
// function before overwriting the context but since we're in a
// single-threaded environment it is not strictly necessary.
- ASSERT(top_context->IsGlobalContext());
+ ASSERT(top_context->IsNativeContext());
Handle<Context> context =
Handle<Context>(use_runtime_context
? Handle<Context>(top_context->runtime_context())
@@ -1364,7 +1372,7 @@ bool Genesis::CompileScriptCached(Vector<const char> name,
Handle<Object> receiver =
Handle<Object>(use_runtime_context
? top_context->builtins()
- : top_context->global());
+ : top_context->global_object());
bool has_pending_exception;
Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
if (has_pending_exception) return false;
@@ -1375,9 +1383,9 @@ bool Genesis::CompileScriptCached(Vector<const char> name,
#define INSTALL_NATIVE(Type, name, var) \
Handle<String> var##_name = factory()->LookupAsciiSymbol(name); \
Object* var##_native = \
- global_context()->builtins()->GetPropertyNoExceptionThrown( \
+ native_context()->builtins()->GetPropertyNoExceptionThrown( \
*var##_name); \
- global_context()->set_##var(Type::cast(var##_native));
+ native_context()->set_##var(Type::cast(var##_native));
void Genesis::InstallNativeFunctions() {
@@ -1417,7 +1425,7 @@ bool Genesis::InstallNatives() {
// Create a function for the builtins object. Allocate space for the
// JavaScript builtins, a reference to the builtins object
- // (itself) and a reference to the global_context directly in the object.
+ // (itself) and a reference to the native_context directly in the object.
Handle<Code> code = Handle<Code>(
isolate()->builtins()->builtin(Builtins::kIllegal));
Handle<JSFunction> builtins_fun =
@@ -1427,12 +1435,15 @@ bool Genesis::InstallNatives() {
Handle<String> name = factory()->LookupAsciiSymbol("builtins");
builtins_fun->shared()->set_instance_class_name(*name);
+ builtins_fun->initial_map()->set_dictionary_map(true);
+ builtins_fun->initial_map()->set_prototype(heap()->null_value());
// Allocate the builtins object.
Handle<JSBuiltinsObject> builtins =
Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun));
builtins->set_builtins(*builtins);
- builtins->set_global_context(*global_context());
+ builtins->set_native_context(*native_context());
+ builtins->set_global_context(*native_context());
builtins->set_global_receiver(*builtins);
// Set up the 'global' properties of the builtins object. The
@@ -1442,26 +1453,27 @@ bool Genesis::InstallNatives() {
static const PropertyAttributes attributes =
static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
Handle<String> global_symbol = factory()->LookupAsciiSymbol("global");
- Handle<Object> global_obj(global_context()->global());
+ Handle<Object> global_obj(native_context()->global_object());
CHECK_NOT_EMPTY_HANDLE(isolate(),
JSObject::SetLocalPropertyIgnoreAttributes(
builtins, global_symbol, global_obj, attributes));
// Set up the reference from the global object to the builtins object.
- JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
+ JSGlobalObject::cast(native_context()->global_object())->
+ set_builtins(*builtins);
- // Create a bridge function that has context in the global context.
+ // Create a bridge function that has context in the native context.
Handle<JSFunction> bridge =
factory()->NewFunction(factory()->empty_symbol(),
factory()->undefined_value());
- ASSERT(bridge->context() == *isolate()->global_context());
+ ASSERT(bridge->context() == *isolate()->native_context());
// Allocate the builtins context.
Handle<Context> context =
factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
- context->set_global(*builtins); // override builtins global object
+ context->set_global_object(*builtins); // override builtins global object
- global_context()->set_runtime_context(*context);
+ native_context()->set_runtime_context(*context);
{ // -- S c r i p t
// Builtin functions for Script.
@@ -1472,118 +1484,134 @@ bool Genesis::InstallNatives() {
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
SetPrototype(script_fun, prototype);
- global_context()->set_script_function(*script_fun);
-
- // Add 'source' and 'data' property to scripts.
- PropertyAttributes common_attributes =
- static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
- Handle<Foreign> foreign_source =
- factory()->NewForeign(&Accessors::ScriptSource);
- Handle<DescriptorArray> script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- factory()->empty_descriptor_array(),
- factory()->LookupAsciiSymbol("source"),
- foreign_source,
- common_attributes);
- Handle<Foreign> foreign_name =
- factory()->NewForeign(&Accessors::ScriptName);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("name"),
- foreign_name,
- common_attributes);
- Handle<Foreign> foreign_id = factory()->NewForeign(&Accessors::ScriptId);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("id"),
- foreign_id,
- common_attributes);
- Handle<Foreign> foreign_line_offset =
- factory()->NewForeign(&Accessors::ScriptLineOffset);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("line_offset"),
- foreign_line_offset,
- common_attributes);
- Handle<Foreign> foreign_column_offset =
- factory()->NewForeign(&Accessors::ScriptColumnOffset);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("column_offset"),
- foreign_column_offset,
- common_attributes);
- Handle<Foreign> foreign_data =
- factory()->NewForeign(&Accessors::ScriptData);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("data"),
- foreign_data,
- common_attributes);
- Handle<Foreign> foreign_type =
- factory()->NewForeign(&Accessors::ScriptType);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("type"),
- foreign_type,
- common_attributes);
- Handle<Foreign> foreign_compilation_type =
- factory()->NewForeign(&Accessors::ScriptCompilationType);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("compilation_type"),
- foreign_compilation_type,
- common_attributes);
- Handle<Foreign> foreign_line_ends =
- factory()->NewForeign(&Accessors::ScriptLineEnds);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("line_ends"),
- foreign_line_ends,
- common_attributes);
- Handle<Foreign> foreign_context_data =
- factory()->NewForeign(&Accessors::ScriptContextData);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("context_data"),
- foreign_context_data,
- common_attributes);
- Handle<Foreign> foreign_eval_from_script =
- factory()->NewForeign(&Accessors::ScriptEvalFromScript);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("eval_from_script"),
- foreign_eval_from_script,
- common_attributes);
- Handle<Foreign> foreign_eval_from_script_position =
- factory()->NewForeign(&Accessors::ScriptEvalFromScriptPosition);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("eval_from_script_position"),
- foreign_eval_from_script_position,
- common_attributes);
- Handle<Foreign> foreign_eval_from_function_name =
- factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName);
- script_descriptors =
- factory()->CopyAppendForeignDescriptor(
- script_descriptors,
- factory()->LookupAsciiSymbol("eval_from_function_name"),
- foreign_eval_from_function_name,
- common_attributes);
+ native_context()->set_script_function(*script_fun);
Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
+
+ Handle<DescriptorArray> script_descriptors(
+ factory()->NewDescriptorArray(0, 13));
+ DescriptorArray::WhitenessWitness witness(*script_descriptors);
+
+ Handle<Foreign> script_source(
+ factory()->NewForeign(&Accessors::ScriptSource));
+ Handle<Foreign> script_name(factory()->NewForeign(&Accessors::ScriptName));
+ Handle<String> id_symbol(factory()->LookupAsciiSymbol("id"));
+ Handle<Foreign> script_id(factory()->NewForeign(&Accessors::ScriptId));
+ Handle<String> line_offset_symbol(
+ factory()->LookupAsciiSymbol("line_offset"));
+ Handle<Foreign> script_line_offset(
+ factory()->NewForeign(&Accessors::ScriptLineOffset));
+ Handle<String> column_offset_symbol(
+ factory()->LookupAsciiSymbol("column_offset"));
+ Handle<Foreign> script_column_offset(
+ factory()->NewForeign(&Accessors::ScriptColumnOffset));
+ Handle<String> data_symbol(factory()->LookupAsciiSymbol("data"));
+ Handle<Foreign> script_data(factory()->NewForeign(&Accessors::ScriptData));
+ Handle<String> type_symbol(factory()->LookupAsciiSymbol("type"));
+ Handle<Foreign> script_type(factory()->NewForeign(&Accessors::ScriptType));
+ Handle<String> compilation_type_symbol(
+ factory()->LookupAsciiSymbol("compilation_type"));
+ Handle<Foreign> script_compilation_type(
+ factory()->NewForeign(&Accessors::ScriptCompilationType));
+ Handle<String> line_ends_symbol(factory()->LookupAsciiSymbol("line_ends"));
+ Handle<Foreign> script_line_ends(
+ factory()->NewForeign(&Accessors::ScriptLineEnds));
+ Handle<String> context_data_symbol(
+ factory()->LookupAsciiSymbol("context_data"));
+ Handle<Foreign> script_context_data(
+ factory()->NewForeign(&Accessors::ScriptContextData));
+ Handle<String> eval_from_script_symbol(
+ factory()->LookupAsciiSymbol("eval_from_script"));
+ Handle<Foreign> script_eval_from_script(
+ factory()->NewForeign(&Accessors::ScriptEvalFromScript));
+ Handle<String> eval_from_script_position_symbol(
+ factory()->LookupAsciiSymbol("eval_from_script_position"));
+ Handle<Foreign> script_eval_from_script_position(
+ factory()->NewForeign(&Accessors::ScriptEvalFromScriptPosition));
+ Handle<String> eval_from_function_name_symbol(
+ factory()->LookupAsciiSymbol("eval_from_function_name"));
+ Handle<Foreign> script_eval_from_function_name(
+ factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName));
+ PropertyAttributes attribs =
+ static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
script_map->set_instance_descriptors(*script_descriptors);
+ {
+ CallbacksDescriptor d(
+ *factory()->source_symbol(), *script_source, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(*factory()->name_symbol(), *script_name, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(*id_symbol, *script_id, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(*line_offset_symbol, *script_line_offset, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(
+ *column_offset_symbol, *script_column_offset, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(*data_symbol, *script_data, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(*type_symbol, *script_type, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(
+ *compilation_type_symbol, *script_compilation_type, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(*line_ends_symbol, *script_line_ends, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(
+ *context_data_symbol, *script_context_data, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(
+ *eval_from_script_symbol, *script_eval_from_script, attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(
+ *eval_from_script_position_symbol,
+ *script_eval_from_script_position,
+ attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
+ {
+ CallbacksDescriptor d(
+ *eval_from_function_name_symbol,
+ *script_eval_from_function_name,
+ attribs);
+ script_map->AppendDescriptor(&d, witness);
+ }
+
// Allocate the empty script.
Handle<Script> script = factory()->NewScript(factory()->empty_string());
script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
@@ -1601,7 +1629,7 @@ bool Genesis::InstallNatives() {
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
SetPrototype(opaque_reference_fun, prototype);
- global_context()->set_opaque_reference_function(*opaque_reference_fun);
+ native_context()->set_opaque_reference_function(*opaque_reference_fun);
}
{ // --- I n t e r n a l A r r a y ---
@@ -1631,26 +1659,31 @@ bool Genesis::InstallNatives() {
// elements in InternalArrays can be set to non-Smi values without going
// through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
// transition easy to trap. Moreover, they rarely are smi-only.
- MaybeObject* maybe_map =
- array_function->initial_map()->CopyDropTransitions(
- DescriptorArray::MAY_BE_SHARED);
+ MaybeObject* maybe_map = array_function->initial_map()->Copy();
Map* new_map;
if (!maybe_map->To(&new_map)) return false;
new_map->set_elements_kind(FAST_HOLEY_ELEMENTS);
array_function->set_initial_map(new_map);
// Make "length" magic on instances.
- Handle<DescriptorArray> array_descriptors =
- factory()->CopyAppendForeignDescriptor(
- factory()->empty_descriptor_array(),
- factory()->length_symbol(),
- factory()->NewForeign(&Accessors::ArrayLength),
- static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
-
- array_function->initial_map()->set_instance_descriptors(
- *array_descriptors);
+ Handle<Map> initial_map(array_function->initial_map());
+ Handle<DescriptorArray> array_descriptors(
+ factory()->NewDescriptorArray(0, 1));
+ DescriptorArray::WhitenessWitness witness(*array_descriptors);
+
+ Handle<Foreign> array_length(factory()->NewForeign(
+ &Accessors::ArrayLength));
+ PropertyAttributes attribs = static_cast<PropertyAttributes>(
+ DONT_ENUM | DONT_DELETE);
+ initial_map->set_instance_descriptors(*array_descriptors);
+
+ { // Add length.
+ CallbacksDescriptor d(
+ *factory()->length_symbol(), *array_length, attribs);
+ array_function->initial_map()->AppendDescriptor(&d, witness);
+ }
- global_context()->set_internal_array_function(*array_function);
+ native_context()->set_internal_array_function(*array_function);
}
if (FLAG_disable_native_files) {
@@ -1673,16 +1706,16 @@ bool Genesis::InstallNatives() {
// Store the map for the string prototype after the natives has been compiled
// and the String function has been set up.
- Handle<JSFunction> string_function(global_context()->string_function());
+ Handle<JSFunction> string_function(native_context()->string_function());
ASSERT(JSObject::cast(
string_function->initial_map()->prototype())->HasFastProperties());
- global_context()->set_string_function_prototype_map(
+ native_context()->set_string_function_prototype_map(
HeapObject::cast(string_function->initial_map()->prototype())->map());
// Install Function.prototype.call and apply.
{ Handle<String> key = factory()->function_class_symbol();
Handle<JSFunction> function =
- Handle<JSFunction>::cast(GetProperty(isolate()->global(), key));
+ Handle<JSFunction>::cast(GetProperty(isolate()->global_object(), key));
Handle<JSObject> proto =
Handle<JSObject>(JSObject::cast(function->instance_prototype()));
@@ -1720,7 +1753,7 @@ bool Genesis::InstallNatives() {
// RegExpResult initial map.
// Find global.Array.prototype to inherit from.
- Handle<JSFunction> array_constructor(global_context()->array_function());
+ Handle<JSFunction> array_constructor(native_context()->array_function());
Handle<JSObject> array_prototype(
JSObject::cast(array_constructor->instance_prototype()));
@@ -1735,44 +1768,45 @@ bool Genesis::InstallNatives() {
// Update map with length accessor from Array and add "index" and "input".
Handle<DescriptorArray> reresult_descriptors =
- factory()->NewDescriptorArray(3);
+ factory()->NewDescriptorArray(0, 3);
DescriptorArray::WhitenessWitness witness(*reresult_descriptors);
+ initial_map->set_instance_descriptors(*reresult_descriptors);
- JSFunction* array_function = global_context()->array_function();
- Handle<DescriptorArray> array_descriptors(
- array_function->initial_map()->instance_descriptors());
- int index = array_descriptors->SearchWithCache(heap()->length_symbol());
- MaybeObject* copy_result =
- reresult_descriptors->CopyFrom(0, *array_descriptors, index, witness);
- if (copy_result->IsFailure()) return false;
-
- int enum_index = 0;
+ {
+ JSFunction* array_function = native_context()->array_function();
+ Handle<DescriptorArray> array_descriptors(
+ array_function->initial_map()->instance_descriptors());
+ String* length = heap()->length_symbol();
+ int old = array_descriptors->SearchWithCache(
+ length, array_function->initial_map());
+ ASSERT(old != DescriptorArray::kNotFound);
+ CallbacksDescriptor desc(length,
+ array_descriptors->GetValue(old),
+ array_descriptors->GetDetails(old).attributes());
+ initial_map->AppendDescriptor(&desc, witness);
+ }
{
FieldDescriptor index_field(heap()->index_symbol(),
JSRegExpResult::kIndexIndex,
- NONE,
- enum_index++);
- reresult_descriptors->Set(1, &index_field, witness);
+ NONE);
+ initial_map->AppendDescriptor(&index_field, witness);
}
{
FieldDescriptor input_field(heap()->input_symbol(),
JSRegExpResult::kInputIndex,
- NONE,
- enum_index++);
- reresult_descriptors->Set(2, &input_field, witness);
+ NONE);
+ initial_map->AppendDescriptor(&input_field, witness);
}
- reresult_descriptors->Sort(witness);
initial_map->set_inobject_properties(2);
initial_map->set_pre_allocated_property_fields(2);
initial_map->set_unused_property_fields(0);
- initial_map->set_instance_descriptors(*reresult_descriptors);
- global_context()->set_regexp_result_map(*initial_map);
+ native_context()->set_regexp_result_map(*initial_map);
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
builtins->Verify();
#endif
@@ -1803,10 +1837,10 @@ bool Genesis::InstallExperimentalNatives() {
static Handle<JSObject> ResolveBuiltinIdHolder(
- Handle<Context> global_context,
+ Handle<Context> native_context,
const char* holder_expr) {
- Factory* factory = global_context->GetIsolate()->factory();
- Handle<GlobalObject> global(global_context->global());
+ Factory* factory = native_context->GetIsolate()->factory();
+ Handle<GlobalObject> global(native_context->global_object());
const char* period_pos = strchr(holder_expr, '.');
if (period_pos == NULL) {
return Handle<JSObject>::cast(
@@ -1837,7 +1871,7 @@ void Genesis::InstallBuiltinFunctionIds() {
#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
{ \
Handle<JSObject> holder = ResolveBuiltinIdHolder( \
- global_context(), #holder_expr); \
+ native_context(), #holder_expr); \
BuiltinFunctionId id = k##name; \
InstallBuiltinFunctionId(holder, #fun_name, id); \
}
@@ -1849,7 +1883,7 @@ void Genesis::InstallBuiltinFunctionIds() {
// Do not forget to update macros.py with named constant
// of cache id.
#define JSFUNCTION_RESULT_CACHE_LIST(F) \
- F(16, global_context()->regexp_function())
+ F(16, native_context()->regexp_function())
static FixedArray* CreateCache(int size, Handle<JSFunction> factory_function) {
@@ -1885,34 +1919,35 @@ void Genesis::InstallJSFunctionResultCaches() {
#undef F
- global_context()->set_jsfunction_result_caches(*caches);
+ native_context()->set_jsfunction_result_caches(*caches);
}
void Genesis::InitializeNormalizedMapCaches() {
Handle<FixedArray> array(
FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
- global_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
+ native_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
}
-bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
+bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
v8::ExtensionConfiguration* extensions) {
- Isolate* isolate = global_context->GetIsolate();
+ Isolate* isolate = native_context->GetIsolate();
BootstrapperActive active;
SaveContext saved_context(isolate);
- isolate->set_context(*global_context);
- if (!Genesis::InstallExtensions(global_context, extensions)) return false;
- Genesis::InstallSpecialObjects(global_context);
+ isolate->set_context(*native_context);
+ if (!Genesis::InstallExtensions(native_context, extensions)) return false;
+ Genesis::InstallSpecialObjects(native_context);
return true;
}
-void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
- Isolate* isolate = global_context->GetIsolate();
+void Genesis::InstallSpecialObjects(Handle<Context> native_context) {
+ Isolate* isolate = native_context->GetIsolate();
Factory* factory = isolate->factory();
HandleScope scope;
- Handle<JSGlobalObject> global(JSGlobalObject::cast(global_context->global()));
+ Handle<JSGlobalObject> global(JSGlobalObject::cast(
+ native_context->global_object()));
// Expose the natives in global if a name for it is specified.
if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
Handle<String> natives = factory->LookupAsciiSymbol(FLAG_expose_natives_as);
@@ -1941,10 +1976,10 @@ void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
// debugger but without tanking the whole context.
if (!debug->Load()) return;
// Set the security token for the debugger context to the same as
- // the shell global context to allow calling between these (otherwise
+ // the shell native context to allow calling between these (otherwise
// exposing debug global object doesn't make much sense).
debug->debug_context()->set_security_token(
- global_context->security_token());
+ native_context->security_token());
Handle<String> debug_string =
factory->LookupAsciiSymbol(FLAG_expose_debug_as);
@@ -1983,7 +2018,7 @@ void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
reinterpret_cast<void*>(static_cast<intptr_t>(state));
}
-bool Genesis::InstallExtensions(Handle<Context> global_context,
+bool Genesis::InstallExtensions(Handle<Context> native_context,
v8::ExtensionConfiguration* extensions) {
// TODO(isolates): Extensions on multiple isolates may take a little more
// effort. (The external API reads 'ignore'-- does that mean
@@ -2003,6 +2038,9 @@ bool Genesis::InstallExtensions(Handle<Context> global_context,
if (FLAG_expose_externalize_string) {
InstallExtension("v8/externalize", &extension_states);
}
+ if (FLAG_track_gc_object_stats) {
+ InstallExtension("v8/statistics", &extension_states);
+ }
if (extensions == NULL) return true;
// Install required extensions
@@ -2105,8 +2143,9 @@ bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
bool Genesis::ConfigureGlobalObjects(
v8::Handle<v8::ObjectTemplate> global_proxy_template) {
Handle<JSObject> global_proxy(
- JSObject::cast(global_context()->global_proxy()));
- Handle<JSObject> inner_global(JSObject::cast(global_context()->global()));
+ JSObject::cast(native_context()->global_proxy()));
+ Handle<JSObject> inner_global(
+ JSObject::cast(native_context()->global_object()));
if (!global_proxy_template.IsEmpty()) {
// Configure the global proxy object.
@@ -2180,26 +2219,24 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
LookupResult result(isolate());
to->LocalLookup(descs->GetKey(i), &result);
// If the property is already there we skip it
- if (result.IsProperty()) continue;
+ if (result.IsFound()) continue;
HandleScope inner;
ASSERT(!to->HasFastProperties());
// Add to dictionary.
Handle<String> key = Handle<String>(descs->GetKey(i));
Handle<Object> callbacks(descs->GetCallbacksObject(i));
- PropertyDetails d =
- PropertyDetails(details.attributes(), CALLBACKS, details.index());
+ PropertyDetails d = PropertyDetails(details.attributes(),
+ CALLBACKS,
+ details.descriptor_index());
JSObject::SetNormalizedProperty(to, key, callbacks, d);
break;
}
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
- // Ignore non-properties.
- break;
case NORMAL:
// Do not occur since the from object has fast properties.
case HANDLER:
case INTERCEPTOR:
+ case TRANSITION:
+ case NONEXISTENT:
// No element in instance descriptors have proxy or interceptor type.
UNREACHABLE();
break;
@@ -2216,7 +2253,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
// If the property is already there we skip it.
LookupResult result(isolate());
to->LocalLookup(String::cast(raw_key), &result);
- if (result.IsProperty()) continue;
+ if (result.IsFound()) continue;
// Set the property.
Handle<String> key = Handle<String>(String::cast(raw_key));
Handle<Object> value = Handle<Object>(properties->ValueAt(i));
@@ -2255,7 +2292,7 @@ void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
// Transfer the prototype (new map is needed).
Handle<Map> old_to_map = Handle<Map>(to->map());
- Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
+ Handle<Map> new_to_map = factory->CopyMap(old_to_map);
new_to_map->set_prototype(from->map()->prototype());
to->set_map(*new_to_map);
}
@@ -2269,9 +2306,9 @@ void Genesis::MakeFunctionInstancePrototypeWritable() {
ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null());
// Replace function instance maps to make prototype writable.
- global_context()->set_function_map(
+ native_context()->set_function_map(
*function_instance_map_writable_prototype_);
- global_context()->set_strict_mode_function_map(
+ native_context()->set_strict_mode_function_map(
*strict_mode_function_instance_map_writable_prototype_);
}
@@ -2297,10 +2334,10 @@ Genesis::Genesis(Isolate* isolate,
Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
if (!new_context.is_null()) {
- global_context_ =
+ native_context_ =
Handle<Context>::cast(isolate->global_handles()->Create(*new_context));
- AddToWeakGlobalContextList(*global_context_);
- isolate->set_context(*global_context_);
+ AddToWeakNativeContextList(*native_context_);
+ isolate->set_context(*native_context_);
isolate->counters()->contexts_created_by_snapshot()->Increment();
Handle<GlobalObject> inner_global;
Handle<JSGlobalProxy> global_proxy =
@@ -2336,7 +2373,7 @@ Genesis::Genesis(Isolate* isolate,
InitializeExperimentalGlobal();
if (!InstallExperimentalNatives()) return;
- result_ = global_context_;
+ result_ = native_context_;
}
diff --git a/deps/v8/src/bootstrapper.h b/deps/v8/src/bootstrapper.h
index 101c2e1b1..179e65c35 100644
--- a/deps/v8/src/bootstrapper.h
+++ b/deps/v8/src/bootstrapper.h
@@ -104,7 +104,7 @@ class Bootstrapper {
void DetachGlobal(Handle<Context> env);
// Reattach an outer global object to an environment.
- void ReattachGlobal(Handle<Context> env, Handle<Object> global_object);
+ void ReattachGlobal(Handle<Context> env, Handle<JSGlobalProxy> global_proxy);
// Traverses the pointers for memory management.
void Iterate(ObjectVisitor* v);
@@ -126,7 +126,7 @@ class Bootstrapper {
char* AllocateAutoDeletedArray(int bytes);
// Used for new context creation.
- bool InstallExtensions(Handle<Context> global_context,
+ bool InstallExtensions(Handle<Context> native_context,
v8::ExtensionConfiguration* extensions);
SourceCodeCache* extensions_cache() { return &extensions_cache_; }
diff --git a/deps/v8/src/builtins.cc b/deps/v8/src/builtins.cc
index 64ec3d9fc..df70cd4fc 100644
--- a/deps/v8/src/builtins.cc
+++ b/deps/v8/src/builtins.cc
@@ -35,6 +35,7 @@
#include "ic-inl.h"
#include "heap-profiler.h"
#include "mark-compact.h"
+#include "stub-cache.h"
#include "vm-state-inl.h"
namespace v8 {
@@ -199,11 +200,11 @@ static MaybeObject* ArrayCodeGenericCommon(Arguments* args,
array->set_length(Smi::FromInt(0));
array->set_elements(heap->empty_fixed_array());
if (!FLAG_smi_only_arrays) {
- Context* global_context = isolate->context()->global_context();
+ Context* native_context = isolate->context()->native_context();
if (array->GetElementsKind() == GetInitialFastElementsKind() &&
- !global_context->js_array_maps()->IsUndefined()) {
+ !native_context->js_array_maps()->IsUndefined()) {
FixedArray* map_array =
- FixedArray::cast(global_context->js_array_maps());
+ FixedArray::cast(native_context->js_array_maps());
array->set_map(Map::cast(map_array->
get(TERMINAL_FAST_ELEMENTS_KIND)));
}
@@ -312,7 +313,7 @@ BUILTIN(InternalArrayCodeGeneric) {
return ArrayCodeGenericCommon(
&args,
isolate,
- isolate->context()->global_context()->internal_array_function());
+ isolate->context()->native_context()->internal_array_function());
}
@@ -320,7 +321,7 @@ BUILTIN(ArrayCodeGeneric) {
return ArrayCodeGenericCommon(
&args,
isolate,
- isolate->context()->global_context()->array_function());
+ isolate->context()->native_context()->array_function());
}
@@ -402,7 +403,7 @@ static FixedArray* LeftTrimFixedArray(Heap* heap,
static bool ArrayPrototypeHasNoElements(Heap* heap,
- Context* global_context,
+ Context* native_context,
JSObject* array_proto) {
// This method depends on non writability of Object and Array prototype
// fields.
@@ -411,7 +412,7 @@ static bool ArrayPrototypeHasNoElements(Heap* heap,
Object* proto = array_proto->GetPrototype();
if (proto == heap->null_value()) return false;
array_proto = JSObject::cast(proto);
- if (array_proto != global_context->initial_object_prototype()) return false;
+ if (array_proto != native_context->initial_object_prototype()) return false;
if (array_proto->elements() != heap->empty_fixed_array()) return false;
return array_proto->GetPrototype()->IsNull();
}
@@ -461,11 +462,11 @@ static inline MaybeObject* EnsureJSArrayWithWritableFastElements(
static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
JSArray* receiver) {
if (!FLAG_clever_optimizations) return false;
- Context* global_context = heap->isolate()->context()->global_context();
+ Context* native_context = heap->isolate()->context()->native_context();
JSObject* array_proto =
- JSObject::cast(global_context->array_function()->prototype());
+ JSObject::cast(native_context->array_function()->prototype());
return receiver->GetPrototype() == array_proto &&
- ArrayPrototypeHasNoElements(heap, global_context, array_proto);
+ ArrayPrototypeHasNoElements(heap, native_context, array_proto);
}
@@ -476,7 +477,7 @@ MUST_USE_RESULT static MaybeObject* CallJsBuiltin(
HandleScope handleScope(isolate);
Handle<Object> js_builtin =
- GetProperty(Handle<JSObject>(isolate->global_context()->builtins()),
+ GetProperty(Handle<JSObject>(isolate->native_context()->builtins()),
name);
Handle<JSFunction> function = Handle<JSFunction>::cast(js_builtin);
int argc = args.length() - 1;
@@ -706,7 +707,7 @@ BUILTIN(ArraySlice) {
// Array.slice(arguments, ...) is quite a common idiom (notably more
// than 50% of invocations in Web apps). Treat it in C++ as well.
Map* arguments_map =
- isolate->context()->global_context()->arguments_boilerplate()->map();
+ isolate->context()->native_context()->arguments_boilerplate()->map();
bool is_arguments_object_with_fast_elements =
receiver->IsJSObject()
@@ -943,10 +944,10 @@ BUILTIN(ArraySplice) {
BUILTIN(ArrayConcat) {
Heap* heap = isolate->heap();
- Context* global_context = isolate->context()->global_context();
+ Context* native_context = isolate->context()->native_context();
JSObject* array_proto =
- JSObject::cast(global_context->array_function()->prototype());
- if (!ArrayPrototypeHasNoElements(heap, global_context, array_proto)) {
+ JSObject::cast(native_context->array_function()->prototype());
+ if (!ArrayPrototypeHasNoElements(heap, native_context, array_proto)) {
return CallJsBuiltin(isolate, "ArrayConcat", args);
}
@@ -1148,6 +1149,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
result = heap->undefined_value();
} else {
result = *reinterpret_cast<Object**>(*value);
+ result->VerifyApiCallResultType();
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
@@ -1224,6 +1226,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
result = heap->undefined_value();
} else {
result = *reinterpret_cast<Object**>(*value);
+ result->VerifyApiCallResultType();
}
}
// Check for exceptions and return result.
@@ -1291,6 +1294,11 @@ static void Generate_LoadIC_Normal(MacroAssembler* masm) {
}
+static void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) {
+ LoadStubCompiler::GenerateLoadViaGetter(masm, Handle<JSFunction>());
+}
+
+
static void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) {
KeyedLoadIC::GenerateInitialize(masm);
}
@@ -1388,6 +1396,11 @@ static void Generate_StoreIC_GlobalProxy_Strict(MacroAssembler* masm) {
}
+static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
+ StoreStubCompiler::GenerateStoreViaSetter(masm, Handle<JSFunction>());
+}
+
+
static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
KeyedStoreIC::GenerateGeneric(masm, kNonStrictMode);
}
@@ -1607,7 +1620,7 @@ void Builtins::SetUp(bool create_heap_objects) {
// For now we generate builtin adaptor code into a stack-allocated
// buffer, before copying it into individual code objects. Be careful
// with alignment, some platforms don't like unaligned code.
- union { int force_alignment; byte buffer[4*KB]; } u;
+ union { int force_alignment; byte buffer[8*KB]; } u;
// Traverse the list of builtins and generate an adaptor in a
// separate code object for each one.
diff --git a/deps/v8/src/builtins.h b/deps/v8/src/builtins.h
index 3ea33938e..ca70ae540 100644
--- a/deps/v8/src/builtins.h
+++ b/deps/v8/src/builtins.h
@@ -66,6 +66,8 @@ enum BuiltinExtraArguments {
#define BUILTIN_LIST_A(V) \
V(ArgumentsAdaptorTrampoline, BUILTIN, UNINITIALIZED, \
Code::kNoExtraICState) \
+ V(InRecompileQueue, BUILTIN, UNINITIALIZED, \
+ Code::kNoExtraICState) \
V(JSConstructStubCountdown, BUILTIN, UNINITIALIZED, \
Code::kNoExtraICState) \
V(JSConstructStubGeneric, BUILTIN, UNINITIALIZED, \
@@ -80,6 +82,8 @@ enum BuiltinExtraArguments {
Code::kNoExtraICState) \
V(LazyRecompile, BUILTIN, UNINITIALIZED, \
Code::kNoExtraICState) \
+ V(ParallelRecompile, BUILTIN, UNINITIALIZED, \
+ Code::kNoExtraICState) \
V(NotifyDeoptimized, BUILTIN, UNINITIALIZED, \
Code::kNoExtraICState) \
V(NotifyLazyDeoptimized, BUILTIN, UNINITIALIZED, \
@@ -119,6 +123,8 @@ enum BuiltinExtraArguments {
Code::kNoExtraICState) \
V(LoadIC_Megamorphic, LOAD_IC, MEGAMORPHIC, \
Code::kNoExtraICState) \
+ V(LoadIC_Getter_ForDeopt, LOAD_IC, MONOMORPHIC, \
+ Code::kNoExtraICState) \
\
V(KeyedLoadIC_Initialize, KEYED_LOAD_IC, UNINITIALIZED, \
Code::kNoExtraICState) \
@@ -153,6 +159,8 @@ enum BuiltinExtraArguments {
kStrictMode) \
V(StoreIC_GlobalProxy_Strict, STORE_IC, MEGAMORPHIC, \
kStrictMode) \
+ V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC, \
+ kStrictMode) \
\
V(KeyedStoreIC_Initialize, KEYED_STORE_IC, UNINITIALIZED, \
Code::kNoExtraICState) \
@@ -347,6 +355,8 @@ class Builtins {
static void Generate_Adaptor(MacroAssembler* masm,
CFunctionId id,
BuiltinExtraArguments extra_args);
+ static void Generate_InRecompileQueue(MacroAssembler* masm);
+ static void Generate_ParallelRecompile(MacroAssembler* masm);
static void Generate_JSConstructStubCountdown(MacroAssembler* masm);
static void Generate_JSConstructStubGeneric(MacroAssembler* masm);
static void Generate_JSConstructStubApi(MacroAssembler* masm);
diff --git a/deps/v8/src/checks.h b/deps/v8/src/checks.h
index 608aa1480..d0a0c2b5a 100644
--- a/deps/v8/src/checks.h
+++ b/deps/v8/src/checks.h
@@ -284,4 +284,12 @@ extern bool FLAG_enable_slow_asserts;
#define ASSERT_NOT_NULL(p) ASSERT_NE(NULL, p)
+// "Extra checks" are lightweight checks that are enabled in some release
+// builds.
+#ifdef ENABLE_EXTRA_CHECKS
+#define EXTRA_CHECK(condition) CHECK(condition)
+#else
+#define EXTRA_CHECK(condition) ((void) 0)
+#endif
+
#endif // V8_CHECKS_H_
diff --git a/deps/v8/src/code-stubs.cc b/deps/v8/src/code-stubs.cc
index 7d4f23ce9..7a720592d 100644
--- a/deps/v8/src/code-stubs.cc
+++ b/deps/v8/src/code-stubs.cc
@@ -142,7 +142,9 @@ Handle<Code> CodeStub::GetCode() {
}
Activate(code);
- ASSERT(!NeedsImmovableCode() || heap->lo_space()->Contains(code));
+ ASSERT(!NeedsImmovableCode() ||
+ heap->lo_space()->Contains(code) ||
+ heap->code_space()->FirstPage()->Contains(code->address()));
return Handle<Code>(code, isolate);
}
@@ -194,7 +196,7 @@ bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) {
flags));
if (probe->IsCode()) {
*code_out = Code::cast(*probe);
- ASSERT(op_ == (*code_out)->compare_operation());
+ ASSERT(op_ == (*code_out)->compare_operation() + Token::EQ);
return true;
}
return false;
@@ -478,4 +480,26 @@ void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) {
KeyedStoreIC::GenerateRuntimeSetProperty(masm, strict_mode_);
}
+
+FunctionEntryHook ProfileEntryHookStub::entry_hook_ = NULL;
+
+
+void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function,
+ intptr_t stack_pointer) {
+ if (entry_hook_ != NULL)
+ entry_hook_(function, stack_pointer);
+}
+
+
+bool ProfileEntryHookStub::SetFunctionEntryHook(FunctionEntryHook entry_hook) {
+ // We don't allow setting a new entry hook over one that's
+ // already active, as the hooks won't stack.
+ if (entry_hook != 0 && entry_hook_ != 0)
+ return false;
+
+ entry_hook_ = entry_hook;
+ return true;
+}
+
+
} } // namespace v8::internal
diff --git a/deps/v8/src/code-stubs.h b/deps/v8/src/code-stubs.h
index 5c8717838..a84384172 100644
--- a/deps/v8/src/code-stubs.h
+++ b/deps/v8/src/code-stubs.h
@@ -73,7 +73,8 @@ namespace internal {
V(DebuggerStatement) \
V(StringDictionaryLookup) \
V(ElementsTransitionAndStore) \
- V(StoreArrayLiteralElement)
+ V(StoreArrayLiteralElement) \
+ V(ProfileEntryHook)
// List of code stubs only used on ARM platforms.
#ifdef V8_TARGET_ARCH_ARM
@@ -162,8 +163,7 @@ class CodeStub BASE_EMBEDDED {
bool FindCodeInCache(Code** code_out);
protected:
- static const int kMajorBits = 6;
- static const int kMinorBits = kBitsPerInt - kSmiTagSize - kMajorBits;
+ static bool CanUseFPRegisters();
private:
// Nonvirtual wrapper around the stub-specific Generate function. Call
@@ -222,8 +222,9 @@ class CodeStub BASE_EMBEDDED {
MajorKeyBits::encode(MajorKey());
}
- class MajorKeyBits: public BitField<uint32_t, 0, kMajorBits> {};
- class MinorKeyBits: public BitField<uint32_t, kMajorBits, kMinorBits> {};
+ class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {};
+ class MinorKeyBits: public BitField<uint32_t,
+ kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT
friend class BreakPointIterator;
};
@@ -498,7 +499,7 @@ class ICCompareStub: public CodeStub {
virtual void FinishCode(Handle<Code> code) {
code->set_compare_state(state_);
- code->set_compare_operation(op_);
+ code->set_compare_operation(op_ - Token::EQ);
}
virtual CodeStub::Major MajorKey() { return CompareIC; }
@@ -1000,13 +1001,15 @@ class KeyedStoreElementStub : public CodeStub {
KeyedAccessGrowMode grow_mode)
: is_js_array_(is_js_array),
elements_kind_(elements_kind),
- grow_mode_(grow_mode) { }
+ grow_mode_(grow_mode),
+ fp_registers_(CanUseFPRegisters()) { }
Major MajorKey() { return KeyedStoreElement; }
int MinorKey() {
return ElementsKindBits::encode(elements_kind_) |
IsJSArrayBits::encode(is_js_array_) |
- GrowModeBits::encode(grow_mode_);
+ GrowModeBits::encode(grow_mode_) |
+ FPRegisters::encode(fp_registers_);
}
void Generate(MacroAssembler* masm);
@@ -1015,10 +1018,12 @@ class KeyedStoreElementStub : public CodeStub {
class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
class GrowModeBits: public BitField<KeyedAccessGrowMode, 8, 1> {};
class IsJSArrayBits: public BitField<bool, 9, 1> {};
+ class FPRegisters: public BitField<bool, 10, 1> {};
bool is_js_array_;
ElementsKind elements_kind_;
KeyedAccessGrowMode grow_mode_;
+ bool fp_registers_;
DISALLOW_COPY_AND_ASSIGN(KeyedStoreElementStub);
};
@@ -1134,17 +1139,53 @@ class ElementsTransitionAndStoreStub : public CodeStub {
class StoreArrayLiteralElementStub : public CodeStub {
public:
- explicit StoreArrayLiteralElementStub() {}
+ StoreArrayLiteralElementStub()
+ : fp_registers_(CanUseFPRegisters()) { }
private:
+ class FPRegisters: public BitField<bool, 0, 1> {};
+
Major MajorKey() { return StoreArrayLiteralElement; }
- int MinorKey() { return 0; }
+ int MinorKey() { return FPRegisters::encode(fp_registers_); }
void Generate(MacroAssembler* masm);
+ bool fp_registers_;
+
DISALLOW_COPY_AND_ASSIGN(StoreArrayLiteralElementStub);
};
+
+class ProfileEntryHookStub : public CodeStub {
+ public:
+ explicit ProfileEntryHookStub() {}
+
+ // The profile entry hook function is not allowed to cause a GC.
+ virtual bool SometimesSetsUpAFrame() { return false; }
+
+ // Generates a call to the entry hook if it's enabled.
+ static void MaybeCallEntryHook(MacroAssembler* masm);
+
+ // Sets or unsets the entry hook function. Returns true on success,
+ // false on an attempt to replace a non-NULL entry hook with another
+ // non-NULL hook.
+ static bool SetFunctionEntryHook(FunctionEntryHook entry_hook);
+
+ private:
+ static void EntryHookTrampoline(intptr_t function,
+ intptr_t stack_pointer);
+
+ Major MajorKey() { return ProfileEntryHook; }
+ int MinorKey() { return 0; }
+
+ void Generate(MacroAssembler* masm);
+
+ // The current function entry hook.
+ static FunctionEntryHook entry_hook_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub);
+};
+
} } // namespace v8::internal
#endif // V8_CODE_STUBS_H_
diff --git a/deps/v8/src/collection.js b/deps/v8/src/collection.js
index 75fe3d541..d36fe18fa 100644
--- a/deps/v8/src/collection.js
+++ b/deps/v8/src/collection.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -79,7 +79,12 @@ function SetDelete(key) {
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
- return %SetDelete(this, key);
+ if (%SetHas(this, key)) {
+ %SetDelete(this, key);
+ return true;
+ } else {
+ return false;
+ }
}
@@ -124,7 +129,7 @@ function MapHas(key) {
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
- return !IS_UNDEFINED(%MapGet(this, key));
+ return %MapHas(this, key);
}
@@ -136,12 +141,7 @@ function MapDelete(key) {
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
- if (!IS_UNDEFINED(%MapGet(this, key))) {
- %MapSet(this, key, void 0);
- return true;
- } else {
- return false;
- }
+ return %MapDelete(this, key);
}
@@ -186,7 +186,7 @@ function WeakMapHas(key) {
if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
}
- return !IS_UNDEFINED(%WeakMapGet(this, key));
+ return %WeakMapHas(this, key);
}
@@ -198,12 +198,7 @@ function WeakMapDelete(key) {
if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
}
- if (!IS_UNDEFINED(%WeakMapGet(this, key))) {
- %WeakMapSet(this, key, void 0);
- return true;
- } else {
- return false;
- }
+ return %WeakMapDelete(this, key);
}
// -------------------------------------------------------------------
diff --git a/deps/v8/src/compilation-cache.cc b/deps/v8/src/compilation-cache.cc
index 82cc2231a..c0645760b 100644
--- a/deps/v8/src/compilation-cache.cc
+++ b/deps/v8/src/compilation-cache.cc
@@ -165,10 +165,12 @@ bool CompilationCacheScript::HasOrigin(
// be cached in the same script generation. Currently the first use
// will be cached, but subsequent code from different source / line
// won't.
-Handle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source,
- Handle<Object> name,
- int line_offset,
- int column_offset) {
+Handle<SharedFunctionInfo> CompilationCacheScript::Lookup(
+ Handle<String> source,
+ Handle<Object> name,
+ int line_offset,
+ int column_offset,
+ Handle<Context> context) {
Object* result = NULL;
int generation;
@@ -177,7 +179,7 @@ Handle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source,
{ HandleScope scope(isolate());
for (generation = 0; generation < generations(); generation++) {
Handle<CompilationCacheTable> table = GetTable(generation);
- Handle<Object> probe(table->Lookup(*source), isolate());
+ Handle<Object> probe(table->Lookup(*source, *context), isolate());
if (probe->IsSharedFunctionInfo()) {
Handle<SharedFunctionInfo> function_info =
Handle<SharedFunctionInfo>::cast(probe);
@@ -214,7 +216,7 @@ Handle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source,
ASSERT(HasOrigin(shared, name, line_offset, column_offset));
// If the script was found in a later generation, we promote it to
// the first generation to let it survive longer in the cache.
- if (generation != 0) Put(source, shared);
+ if (generation != 0) Put(source, context, shared);
isolate()->counters()->compilation_cache_hits()->Increment();
return shared;
} else {
@@ -226,25 +228,28 @@ Handle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source,
MaybeObject* CompilationCacheScript::TryTablePut(
Handle<String> source,
+ Handle<Context> context,
Handle<SharedFunctionInfo> function_info) {
Handle<CompilationCacheTable> table = GetFirstTable();
- return table->Put(*source, *function_info);
+ return table->Put(*source, *context, *function_info);
}
Handle<CompilationCacheTable> CompilationCacheScript::TablePut(
Handle<String> source,
+ Handle<Context> context,
Handle<SharedFunctionInfo> function_info) {
CALL_HEAP_FUNCTION(isolate(),
- TryTablePut(source, function_info),
+ TryTablePut(source, context, function_info),
CompilationCacheTable);
}
void CompilationCacheScript::Put(Handle<String> source,
+ Handle<Context> context,
Handle<SharedFunctionInfo> function_info) {
HandleScope scope(isolate());
- SetFirstTable(TablePut(source, function_info));
+ SetFirstTable(TablePut(source, context, function_info));
}
@@ -380,15 +385,17 @@ void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) {
}
-Handle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source,
- Handle<Object> name,
- int line_offset,
- int column_offset) {
+Handle<SharedFunctionInfo> CompilationCache::LookupScript(
+ Handle<String> source,
+ Handle<Object> name,
+ int line_offset,
+ int column_offset,
+ Handle<Context> context) {
if (!IsEnabled()) {
return Handle<SharedFunctionInfo>::null();
}
- return script_.Lookup(source, name, line_offset, column_offset);
+ return script_.Lookup(source, name, line_offset, column_offset, context);
}
@@ -426,12 +433,13 @@ Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
void CompilationCache::PutScript(Handle<String> source,
+ Handle<Context> context,
Handle<SharedFunctionInfo> function_info) {
if (!IsEnabled()) {
return;
}
- script_.Put(source, function_info);
+ script_.Put(source, context, function_info);
}
diff --git a/deps/v8/src/compilation-cache.h b/deps/v8/src/compilation-cache.h
index 2f2fbadb2..7a236e8fb 100644
--- a/deps/v8/src/compilation-cache.h
+++ b/deps/v8/src/compilation-cache.h
@@ -98,16 +98,23 @@ class CompilationCacheScript : public CompilationSubCache {
Handle<SharedFunctionInfo> Lookup(Handle<String> source,
Handle<Object> name,
int line_offset,
- int column_offset);
- void Put(Handle<String> source, Handle<SharedFunctionInfo> function_info);
+ int column_offset,
+ Handle<Context> context);
+ void Put(Handle<String> source,
+ Handle<Context> context,
+ Handle<SharedFunctionInfo> function_info);
private:
MUST_USE_RESULT MaybeObject* TryTablePut(
- Handle<String> source, Handle<SharedFunctionInfo> function_info);
+ Handle<String> source,
+ Handle<Context> context,
+ Handle<SharedFunctionInfo> function_info);
// Note: Returns a new hash table if operation results in expansion.
Handle<CompilationCacheTable> TablePut(
- Handle<String> source, Handle<SharedFunctionInfo> function_info);
+ Handle<String> source,
+ Handle<Context> context,
+ Handle<SharedFunctionInfo> function_info);
bool HasOrigin(Handle<SharedFunctionInfo> function_info,
Handle<Object> name,
@@ -122,7 +129,7 @@ class CompilationCacheScript : public CompilationSubCache {
// Sub-cache for eval scripts. Two caches for eval are used. One for eval calls
-// in global contexts and one for eval calls in other contexts. The cache
+// in native contexts and one for eval calls in other contexts. The cache
// considers the following pieces of information when checking for matching
// entries:
// 1. The source string.
@@ -204,7 +211,8 @@ class CompilationCache {
Handle<SharedFunctionInfo> LookupScript(Handle<String> source,
Handle<Object> name,
int line_offset,
- int column_offset);
+ int column_offset,
+ Handle<Context> context);
// Finds the shared function info for a source string for eval in a
// given context. Returns an empty handle if the cache doesn't
@@ -223,6 +231,7 @@ class CompilationCache {
// Associate the (source, kind) pair to the shared function
// info. This may overwrite an existing mapping.
void PutScript(Handle<String> source,
+ Handle<Context> context,
Handle<SharedFunctionInfo> function_info);
// Associate the (source, context->closure()->shared(), kind) triple
diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc
index d44718bc0..86374371e 100644
--- a/deps/v8/src/compiler.cc
+++ b/deps/v8/src/compiler.cc
@@ -51,7 +51,7 @@ namespace v8 {
namespace internal {
-CompilationInfo::CompilationInfo(Handle<Script> script)
+CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone)
: isolate_(script->GetIsolate()),
flags_(LanguageModeField::encode(CLASSIC_MODE)),
function_(NULL),
@@ -60,12 +60,15 @@ CompilationInfo::CompilationInfo(Handle<Script> script)
script_(script),
extension_(NULL),
pre_parse_data_(NULL),
- osr_ast_id_(AstNode::kNoNumber) {
+ osr_ast_id_(BailoutId::None()),
+ zone_(zone),
+ deferred_handles_(NULL) {
Initialize(BASE);
}
-CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info)
+CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info,
+ Zone* zone)
: isolate_(shared_info->GetIsolate()),
flags_(LanguageModeField::encode(CLASSIC_MODE) |
IsLazy::encode(true)),
@@ -76,12 +79,14 @@ CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info)
script_(Handle<Script>(Script::cast(shared_info->script()))),
extension_(NULL),
pre_parse_data_(NULL),
- osr_ast_id_(AstNode::kNoNumber) {
+ osr_ast_id_(BailoutId::None()),
+ zone_(zone),
+ deferred_handles_(NULL) {
Initialize(BASE);
}
-CompilationInfo::CompilationInfo(Handle<JSFunction> closure)
+CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone)
: isolate_(closure->GetIsolate()),
flags_(LanguageModeField::encode(CLASSIC_MODE) |
IsLazy::encode(true)),
@@ -93,11 +98,19 @@ CompilationInfo::CompilationInfo(Handle<JSFunction> closure)
script_(Handle<Script>(Script::cast(shared_info_->script()))),
extension_(NULL),
pre_parse_data_(NULL),
- osr_ast_id_(AstNode::kNoNumber) {
+ context_(closure->context()),
+ osr_ast_id_(BailoutId::None()),
+ zone_(zone),
+ deferred_handles_(NULL) {
Initialize(BASE);
}
+CompilationInfo::~CompilationInfo() {
+ delete deferred_handles_;
+}
+
+
// Disable optimization for the rest of the compilation pipeline.
void CompilationInfo::DisableOptimization() {
bool is_optimizable_closure =
@@ -118,7 +131,7 @@ bool CompilationInfo::ShouldSelfOptimize() {
FLAG_crankshaft &&
!function()->flags()->Contains(kDontSelfOptimize) &&
!function()->flags()->Contains(kDontOptimize) &&
- function()->scope()->AllowsLazyRecompilation() &&
+ function()->scope()->AllowsLazyCompilation() &&
(shared_info().is_null() || !shared_info()->optimization_disabled());
}
@@ -137,9 +150,8 @@ void CompilationInfo::AbortOptimization() {
// all. However crankshaft support recompilation of functions, so in this case
// the full compiler need not be be used if a debugger is attached, but only if
// break points has actually been set.
-static bool is_debugging_active() {
+static bool IsDebuggerActive(Isolate* isolate) {
#ifdef ENABLE_DEBUGGER_SUPPORT
- Isolate* isolate = Isolate::Current();
return V8::UseCrankshaft() ?
isolate->debug()->has_break_points() :
isolate->debugger()->IsDebuggerActive();
@@ -149,27 +161,32 @@ static bool is_debugging_active() {
}
-static bool AlwaysFullCompiler() {
- return FLAG_always_full_compiler || is_debugging_active();
+static bool AlwaysFullCompiler(Isolate* isolate) {
+ return FLAG_always_full_compiler || IsDebuggerActive(isolate);
}
-static void FinishOptimization(Handle<JSFunction> function, int64_t start) {
+void OptimizingCompiler::RecordOptimizationStats() {
+ Handle<JSFunction> function = info()->closure();
int opt_count = function->shared()->opt_count();
function->shared()->set_opt_count(opt_count + 1);
- double ms = static_cast<double>(OS::Ticks() - start) / 1000;
+ double ms_creategraph =
+ static_cast<double>(time_taken_to_create_graph_) / 1000;
+ double ms_optimize = static_cast<double>(time_taken_to_optimize_) / 1000;
+ double ms_codegen = static_cast<double>(time_taken_to_codegen_) / 1000;
if (FLAG_trace_opt) {
PrintF("[optimizing: ");
function->PrintName();
PrintF(" / %" V8PRIxPTR, reinterpret_cast<intptr_t>(*function));
- PrintF(" - took %0.3f ms]\n", ms);
+ PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize,
+ ms_codegen);
}
if (FLAG_trace_opt_stats) {
static double compilation_time = 0.0;
static int compiled_functions = 0;
static int code_size = 0;
- compilation_time += ms;
+ compilation_time += (ms_creategraph + ms_optimize + ms_codegen);
compiled_functions++;
code_size += function->shared()->SourceSize();
PrintF("Compiled: %d functions with %d byte source size in %fms.\n",
@@ -180,46 +197,54 @@ static void FinishOptimization(Handle<JSFunction> function, int64_t start) {
}
+// A return value of true indicates the compilation pipeline is still
+// going, not necessarily that we optimized the code.
static bool MakeCrankshaftCode(CompilationInfo* info) {
- // Test if we can optimize this function when asked to. We can only
- // do this after the scopes are computed.
- if (!V8::UseCrankshaft()) {
- info->DisableOptimization();
- }
+ OptimizingCompiler compiler(info);
+ OptimizingCompiler::Status status = compiler.CreateGraph();
- // In case we are not optimizing simply return the code from
- // the full code generator.
- if (!info->IsOptimizing()) {
- return FullCodeGenerator::MakeCode(info);
+ if (status != OptimizingCompiler::SUCCEEDED) {
+ return status != OptimizingCompiler::FAILED;
+ }
+ status = compiler.OptimizeGraph();
+ if (status != OptimizingCompiler::SUCCEEDED) {
+ status = compiler.AbortOptimization();
+ return status != OptimizingCompiler::FAILED;
}
+ status = compiler.GenerateAndInstallCode();
+ return status != OptimizingCompiler::FAILED;
+}
- // We should never arrive here if there is not code object on the
+
+OptimizingCompiler::Status OptimizingCompiler::CreateGraph() {
+ ASSERT(V8::UseCrankshaft());
+ ASSERT(info()->IsOptimizing());
+ ASSERT(!info()->IsCompilingForDebugging());
+
+ // We should never arrive here if there is no code object on the
// shared function object.
- Handle<Code> code(info->shared_info()->code());
+ Handle<Code> code(info()->shared_info()->code());
ASSERT(code->kind() == Code::FUNCTION);
// We should never arrive here if optimization has been disabled on the
// shared function info.
- ASSERT(!info->shared_info()->optimization_disabled());
+ ASSERT(!info()->shared_info()->optimization_disabled());
// Fall back to using the full code generator if it's not possible
// to use the Hydrogen-based optimizing compiler. We already have
// generated code for this from the shared function object.
- if (AlwaysFullCompiler()) {
- info->SetCode(code);
- return true;
+ if (AlwaysFullCompiler(info()->isolate())) {
+ info()->SetCode(code);
+ return SetLastStatus(BAILED_OUT);
}
// Limit the number of times we re-compile a functions with
// the optimizing compiler.
const int kMaxOptCount =
- FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000;
- if (info->shared_info()->opt_count() > kMaxOptCount) {
- info->AbortOptimization();
- info->shared_info()->DisableOptimization();
- // True indicates the compilation pipeline is still going, not
- // necessarily that we optimized the code.
- return true;
+ FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000;
+ if (info()->shared_info()->opt_count() > kMaxOptCount) {
+ info()->set_bailout_reason("optimized too many times");
+ return AbortOptimization();
}
// Due to an encoding limit on LUnallocated operands in the Lithium
@@ -230,27 +255,28 @@ static bool MakeCrankshaftCode(CompilationInfo* info) {
// The encoding is as a signed value, with parameters and receiver using
// the negative indices and locals the non-negative ones.
const int parameter_limit = -LUnallocated::kMinFixedIndex;
+ Scope* scope = info()->scope();
+ if ((scope->num_parameters() + 1) > parameter_limit) {
+ info()->set_bailout_reason("too many parameters");
+ return AbortOptimization();
+ }
+
const int locals_limit = LUnallocated::kMaxFixedIndex;
- Scope* scope = info->scope();
- if ((scope->num_parameters() + 1) > parameter_limit ||
- (info->osr_ast_id() != AstNode::kNoNumber &&
- scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit)) {
- info->AbortOptimization();
- info->shared_info()->DisableOptimization();
- // True indicates the compilation pipeline is still going, not
- // necessarily that we optimized the code.
- return true;
+ if (!info()->osr_ast_id().IsNone() &&
+ scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit) {
+ info()->set_bailout_reason("too many parameters/locals");
+ return AbortOptimization();
}
// Take --hydrogen-filter into account.
- Handle<String> name = info->function()->debug_name();
+ Handle<String> name = info()->function()->debug_name();
if (*FLAG_hydrogen_filter != '\0') {
Vector<const char> filter = CStrVector(FLAG_hydrogen_filter);
if ((filter[0] == '-'
&& name->IsEqualTo(filter.SubVector(1, filter.length())))
|| (filter[0] != '-' && !name->IsEqualTo(filter))) {
- info->SetCode(code);
- return true;
+ info()->SetCode(code);
+ return SetLastStatus(BAILED_OUT);
}
}
@@ -258,20 +284,21 @@ static bool MakeCrankshaftCode(CompilationInfo* info) {
// doesn't have deoptimization support. Alternatively, we may decide to
// run the full code generator to get a baseline for the compile-time
// performance of the hydrogen-based compiler.
- int64_t start = OS::Ticks();
- bool should_recompile = !info->shared_info()->has_deoptimization_support();
+ Timer t(this, &time_taken_to_create_graph_);
+ bool should_recompile = !info()->shared_info()->has_deoptimization_support();
if (should_recompile || FLAG_hydrogen_stats) {
HPhase phase(HPhase::kFullCodeGen);
- CompilationInfo unoptimized(info->shared_info());
+ CompilationInfoWithZone unoptimized(info()->shared_info());
// Note that we use the same AST that we will use for generating the
// optimized code.
- unoptimized.SetFunction(info->function());
- unoptimized.SetScope(info->scope());
+ unoptimized.SetFunction(info()->function());
+ unoptimized.SetScope(info()->scope());
+ unoptimized.SetContext(info()->context());
if (should_recompile) unoptimized.EnableDeoptimizationSupport();
bool succeeded = FullCodeGenerator::MakeCode(&unoptimized);
if (should_recompile) {
- if (!succeeded) return false;
- Handle<SharedFunctionInfo> shared = info->shared_info();
+ if (!succeeded) return SetLastStatus(FAILED);
+ Handle<SharedFunctionInfo> shared = info()->shared_info();
shared->EnableDeoptimizationSupport(*unoptimized.code());
// The existing unoptimized code was replaced with the new one.
Compiler::RecordFunctionCompilation(
@@ -285,51 +312,93 @@ static bool MakeCrankshaftCode(CompilationInfo* info) {
// is safe as long as the unoptimized code has deoptimization
// support.
ASSERT(FLAG_always_opt || code->optimizable());
- ASSERT(info->shared_info()->has_deoptimization_support());
+ ASSERT(info()->shared_info()->has_deoptimization_support());
if (FLAG_trace_hydrogen) {
PrintF("-----------------------------------------------------------\n");
PrintF("Compiling method %s using hydrogen\n", *name->ToCString());
- HTracer::Instance()->TraceCompilation(info->function());
+ HTracer::Instance()->TraceCompilation(info()->function());
}
-
- Handle<Context> global_context(info->closure()->context()->global_context());
- TypeFeedbackOracle oracle(code, global_context, info->isolate(),
- info->isolate()->zone());
- HGraphBuilder builder(info, &oracle, info->isolate()->zone());
+ Handle<Context> native_context(
+ info()->closure()->context()->native_context());
+ oracle_ = new(info()->zone()) TypeFeedbackOracle(
+ code, native_context, info()->isolate(), info()->zone());
+ graph_builder_ = new(info()->zone()) HGraphBuilder(info(), oracle_);
HPhase phase(HPhase::kTotal);
- HGraph* graph = builder.CreateGraph();
- if (info->isolate()->has_pending_exception()) {
- info->SetCode(Handle<Code>::null());
- return false;
+ graph_ = graph_builder_->CreateGraph();
+
+ if (info()->isolate()->has_pending_exception()) {
+ info()->SetCode(Handle<Code>::null());
+ return SetLastStatus(FAILED);
}
- if (graph != NULL) {
- Handle<Code> optimized_code = graph->Compile(info, graph->zone());
- if (!optimized_code.is_null()) {
- info->SetCode(optimized_code);
- FinishOptimization(info->closure(), start);
- return true;
+ // The function being compiled may have bailed out due to an inline
+ // candidate bailing out. In such a case, we don't disable
+ // optimization on the shared_info.
+ ASSERT(!graph_builder_->inline_bailout() || graph_ == NULL);
+ if (graph_ == NULL) {
+ if (graph_builder_->inline_bailout()) {
+ info_->AbortOptimization();
+ return SetLastStatus(BAILED_OUT);
+ } else {
+ return AbortOptimization();
+ }
+ }
+
+ return SetLastStatus(SUCCEEDED);
+}
+
+OptimizingCompiler::Status OptimizingCompiler::OptimizeGraph() {
+ AssertNoAllocation no_gc;
+ NoHandleAllocation no_handles;
+
+ ASSERT(last_status() == SUCCEEDED);
+ Timer t(this, &time_taken_to_optimize_);
+ ASSERT(graph_ != NULL);
+ SmartArrayPointer<char> bailout_reason;
+ if (!graph_->Optimize(&bailout_reason)) {
+ if (!bailout_reason.is_empty()) graph_builder_->Bailout(*bailout_reason);
+ return SetLastStatus(BAILED_OUT);
+ } else {
+ chunk_ = LChunk::NewChunk(graph_);
+ if (chunk_ == NULL) {
+ return SetLastStatus(BAILED_OUT);
}
}
+ return SetLastStatus(SUCCEEDED);
+}
+
- // Keep using the shared code.
- info->AbortOptimization();
- if (!builder.inline_bailout()) {
- // Mark the shared code as unoptimizable unless it was an inlined
- // function that bailed out.
- info->shared_info()->DisableOptimization();
+OptimizingCompiler::Status OptimizingCompiler::GenerateAndInstallCode() {
+ ASSERT(last_status() == SUCCEEDED);
+ Timer timer(this, &time_taken_to_codegen_);
+ ASSERT(chunk_ != NULL);
+ ASSERT(graph_ != NULL);
+ Handle<Code> optimized_code = chunk_->Codegen();
+ if (optimized_code.is_null()) {
+ info()->set_bailout_reason("code generation failed");
+ return AbortOptimization();
}
- // True indicates the compilation pipeline is still going, not necessarily
- // that we optimized the code.
- return true;
+ info()->SetCode(optimized_code);
+ RecordOptimizationStats();
+ return SetLastStatus(SUCCEEDED);
}
static bool GenerateCode(CompilationInfo* info) {
- return info->IsCompilingForDebugging() || !V8::UseCrankshaft() ?
- FullCodeGenerator::MakeCode(info) :
- MakeCrankshaftCode(info);
+ bool is_optimizing = V8::UseCrankshaft() &&
+ !info->IsCompilingForDebugging() &&
+ info->IsOptimizing();
+ if (is_optimizing) {
+ return MakeCrankshaftCode(info);
+ } else {
+ if (info->IsOptimizing()) {
+ // Have the CompilationInfo decide if the compilation should be
+ // BASE or NONOPT.
+ info->DisableOptimization();
+ }
+ return FullCodeGenerator::MakeCode(info);
+ }
}
@@ -348,7 +417,7 @@ bool Compiler::MakeCodeForLiveEdit(CompilationInfo* info) {
bool succeeded = MakeCode(info);
if (!info->shared_info().is_null()) {
Handle<ScopeInfo> scope_info = ScopeInfo::Create(info->scope(),
- info->isolate()->zone());
+ info->zone());
info->shared_info()->set_scope_info(*scope_info);
}
return succeeded;
@@ -358,12 +427,12 @@ bool Compiler::MakeCodeForLiveEdit(CompilationInfo* info) {
static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
Isolate* isolate = info->isolate();
- ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
+ ZoneScope zone_scope(info->zone(), DELETE_ON_EXIT);
PostponeInterruptsScope postpone(isolate);
- ASSERT(!isolate->global_context().is_null());
+ ASSERT(!isolate->native_context().is_null());
Handle<Script> script = info->script();
- script->set_context_data((*isolate->global_context())->data());
+ script->set_context_data((*isolate->native_context())->data());
#ifdef ENABLE_DEBUGGER_SUPPORT
if (info->is_eval()) {
@@ -422,7 +491,7 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
lit->name(),
lit->materialized_literal_count(),
info->code(),
- ScopeInfo::Create(info->scope(), info->isolate()->zone()));
+ ScopeInfo::Create(info->scope(), info->zone()));
ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
Compiler::SetFunctionInfo(result, lit, true, script);
@@ -464,7 +533,7 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
script, Debugger::NO_AFTER_COMPILE_FLAGS);
#endif
- live_edit_tracker.RecordFunctionInfo(result, lit, isolate->zone());
+ live_edit_tracker.RecordFunctionInfo(result, lit, info->zone());
return result;
}
@@ -474,6 +543,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
Handle<Object> script_name,
int line_offset,
int column_offset,
+ Handle<Context> context,
v8::Extension* extension,
ScriptDataImpl* pre_data,
Handle<Object> script_data,
@@ -494,7 +564,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
result = compilation_cache->LookupScript(source,
script_name,
line_offset,
- column_offset);
+ column_offset,
+ context);
}
if (result.is_null()) {
@@ -522,16 +593,17 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
: *script_data);
// Compile the function and add it to the cache.
- CompilationInfo info(script);
+ CompilationInfoWithZone info(script);
info.MarkAsGlobal();
info.SetExtension(extension);
info.SetPreParseData(pre_data);
+ info.SetContext(context);
if (FLAG_use_strict) {
info.SetLanguageMode(FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE);
}
result = MakeFunctionInfo(&info);
- if (extension == NULL && !result.is_null()) {
- compilation_cache->PutScript(source, result);
+ if (extension == NULL && !result.is_null() && !result->dont_cache()) {
+ compilation_cache->PutScript(source, context, result);
}
} else {
if (result->ic_age() != HEAP->global_ic_age()) {
@@ -570,16 +642,16 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
if (result.is_null()) {
// Create a script object describing the script to be compiled.
Handle<Script> script = isolate->factory()->NewScript(source);
- CompilationInfo info(script);
+ CompilationInfoWithZone info(script);
info.MarkAsEval();
if (is_global) info.MarkAsGlobal();
info.SetLanguageMode(language_mode);
- info.SetCallingContext(context);
+ info.SetContext(context);
result = MakeFunctionInfo(&info);
if (!result.is_null()) {
// Explicitly disable optimization for eval code. We're not yet prepared
// to handle eval-code in the optimizing compiler.
- result->DisableOptimization();
+ result->DisableOptimization("eval");
// If caller is strict mode, the result must be in strict mode or
// extended mode as well, but not the other way around. Consider:
@@ -589,8 +661,10 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
// extended mode.
ASSERT(language_mode != EXTENDED_MODE ||
result->is_extended_mode());
- compilation_cache->PutEval(
- source, context, is_global, result, scope_position);
+ if (!result->dont_cache()) {
+ compilation_cache->PutEval(
+ source, context, is_global, result, scope_position);
+ }
}
} else {
if (result->ic_age() != HEAP->global_ic_age()) {
@@ -602,10 +676,117 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
}
+static bool InstallFullCode(CompilationInfo* info) {
+ // Update the shared function info with the compiled code and the
+ // scope info. Please note, that the order of the shared function
+ // info initialization is important since set_scope_info might
+ // trigger a GC, causing the ASSERT below to be invalid if the code
+ // was flushed. By setting the code object last we avoid this.
+ Handle<SharedFunctionInfo> shared = info->shared_info();
+ Handle<Code> code = info->code();
+ Handle<JSFunction> function = info->closure();
+ Handle<ScopeInfo> scope_info =
+ ScopeInfo::Create(info->scope(), info->zone());
+ shared->set_scope_info(*scope_info);
+ shared->set_code(*code);
+ if (!function.is_null()) {
+ function->ReplaceCode(*code);
+ ASSERT(!function->IsOptimized());
+ }
+
+ // Set the expected number of properties for instances.
+ FunctionLiteral* lit = info->function();
+ int expected = lit->expected_property_count();
+ SetExpectedNofPropertiesFromEstimate(shared, expected);
+
+ // Set the optimization hints after performing lazy compilation, as
+ // these are not set when the function is set up as a lazily
+ // compiled function.
+ shared->SetThisPropertyAssignmentsInfo(
+ lit->has_only_simple_this_property_assignments(),
+ *lit->this_property_assignments());
+
+ // Check the function has compiled code.
+ ASSERT(shared->is_compiled());
+ shared->set_code_age(0);
+ shared->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
+ shared->set_dont_inline(lit->flags()->Contains(kDontInline));
+ shared->set_ast_node_count(lit->ast_node_count());
+
+ if (V8::UseCrankshaft() &&
+ !function.is_null() &&
+ !shared->optimization_disabled()) {
+ // If we're asked to always optimize, we compile the optimized
+ // version of the function right away - unless the debugger is
+ // active as it makes no sense to compile optimized code then.
+ if (FLAG_always_opt &&
+ !Isolate::Current()->DebuggerHasBreakPoints()) {
+ CompilationInfoWithZone optimized(function);
+ optimized.SetOptimizing(BailoutId::None());
+ return Compiler::CompileLazy(&optimized);
+ }
+ }
+ return true;
+}
+
+
+static void InstallCodeCommon(CompilationInfo* info) {
+ Handle<SharedFunctionInfo> shared = info->shared_info();
+ Handle<Code> code = info->code();
+ ASSERT(!code.is_null());
+
+ // Set optimizable to false if this is disallowed by the shared
+ // function info, e.g., we might have flushed the code and must
+ // reset this bit when lazy compiling the code again.
+ if (shared->optimization_disabled()) code->set_optimizable(false);
+
+ Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
+}
+
+
+static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
+ Handle<Code> code = info->code();
+ if (FLAG_cache_optimized_code &&
+ info->osr_ast_id().IsNone() &&
+ code->kind() == Code::OPTIMIZED_FUNCTION) {
+ Handle<JSFunction> function = info->closure();
+ Handle<SharedFunctionInfo> shared(function->shared());
+ Handle<FixedArray> literals(function->literals());
+ Handle<Context> native_context(function->context()->native_context());
+ SharedFunctionInfo::AddToOptimizedCodeMap(
+ shared, native_context, code, literals);
+ }
+}
+
+
+static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) {
+ if (FLAG_cache_optimized_code &&
+ info->osr_ast_id().IsNone() &&
+ info->IsOptimizing()) {
+ Handle<SharedFunctionInfo> shared = info->shared_info();
+ Handle<JSFunction> function = info->closure();
+ ASSERT(!function.is_null());
+ Handle<Context> native_context(function->context()->native_context());
+ int index = shared->SearchOptimizedCodeMap(*native_context);
+ if (index > 0) {
+ if (FLAG_trace_opt) {
+ PrintF("[found optimized code for: ");
+ function->PrintName();
+ PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(*function));
+ }
+ // Caching of optimized code enabled and optimized code found.
+ shared->InstallFromOptimizedCodeMap(*function, index);
+ return true;
+ }
+ }
+ return false;
+}
+
+
bool Compiler::CompileLazy(CompilationInfo* info) {
Isolate* isolate = info->isolate();
- ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
+ ZoneScope zone_scope(info->zone(), DELETE_ON_EXIT);
// The VM is in the COMPILER state until exiting this function.
VMState state(isolate, COMPILER);
@@ -616,6 +797,8 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
int compiled_size = shared->end_position() - shared->start_position();
isolate->counters()->total_compile_size()->Increment(compiled_size);
+ if (InstallCodeFromOptimizedCodeMap(info)) return true;
+
// Generate the AST for the lazily compiled function.
if (ParserApi::Parse(info, kNoParsingFlags)) {
// Measure how long it takes to do the lazy compilation; only take the
@@ -634,69 +817,17 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
isolate->StackOverflow();
}
} else {
- ASSERT(!info->code().is_null());
- Handle<Code> code = info->code();
- // Set optimizable to false if this is disallowed by the shared
- // function info, e.g., we might have flushed the code and must
- // reset this bit when lazy compiling the code again.
- if (shared->optimization_disabled()) code->set_optimizable(false);
-
- Handle<JSFunction> function = info->closure();
- RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
+ InstallCodeCommon(info);
if (info->IsOptimizing()) {
+ Handle<Code> code = info->code();
ASSERT(shared->scope_info() != ScopeInfo::Empty());
- function->ReplaceCode(*code);
+ info->closure()->ReplaceCode(*code);
+ InsertCodeIntoOptimizedCodeMap(info);
+ return true;
} else {
- // Update the shared function info with the compiled code and the
- // scope info. Please note, that the order of the shared function
- // info initialization is important since set_scope_info might
- // trigger a GC, causing the ASSERT below to be invalid if the code
- // was flushed. By setting the code object last we avoid this.
- Handle<ScopeInfo> scope_info =
- ScopeInfo::Create(info->scope(), info->isolate()->zone());
- shared->set_scope_info(*scope_info);
- shared->set_code(*code);
- if (!function.is_null()) {
- function->ReplaceCode(*code);
- ASSERT(!function->IsOptimized());
- }
-
- // Set the expected number of properties for instances.
- FunctionLiteral* lit = info->function();
- int expected = lit->expected_property_count();
- SetExpectedNofPropertiesFromEstimate(shared, expected);
-
- // Set the optimization hints after performing lazy compilation, as
- // these are not set when the function is set up as a lazily
- // compiled function.
- shared->SetThisPropertyAssignmentsInfo(
- lit->has_only_simple_this_property_assignments(),
- *lit->this_property_assignments());
-
- // Check the function has compiled code.
- ASSERT(shared->is_compiled());
- shared->set_code_age(0);
- shared->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
- shared->set_dont_inline(lit->flags()->Contains(kDontInline));
- shared->set_ast_node_count(lit->ast_node_count());
-
- if (V8::UseCrankshaft()&&
- !function.is_null() &&
- !shared->optimization_disabled()) {
- // If we're asked to always optimize, we compile the optimized
- // version of the function right away - unless the debugger is
- // active as it makes no sense to compile optimized code then.
- if (FLAG_always_opt &&
- !Isolate::Current()->DebuggerHasBreakPoints()) {
- CompilationInfo optimized(function);
- optimized.SetOptimizing(AstNode::kNoNumber);
- return CompileLazy(&optimized);
- }
- }
+ return InstallFullCode(info);
}
-
- return true;
}
}
@@ -705,10 +836,97 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
}
+void Compiler::RecompileParallel(Handle<JSFunction> closure) {
+ if (closure->IsInRecompileQueue()) return;
+ ASSERT(closure->IsMarkedForParallelRecompilation());
+
+ Isolate* isolate = closure->GetIsolate();
+ if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) {
+ if (FLAG_trace_parallel_recompilation) {
+ PrintF(" ** Compilation queue, will retry opting on next run.\n");
+ }
+ return;
+ }
+
+ SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(closure));
+ VMState state(isolate, PARALLEL_COMPILER_PROLOGUE);
+ PostponeInterruptsScope postpone(isolate);
+
+ Handle<SharedFunctionInfo> shared = info->shared_info();
+ int compiled_size = shared->end_position() - shared->start_position();
+ isolate->counters()->total_compile_size()->Increment(compiled_size);
+ info->SetOptimizing(BailoutId::None());
+
+ {
+ CompilationHandleScope handle_scope(*info);
+
+ if (InstallCodeFromOptimizedCodeMap(*info)) return;
+
+ if (ParserApi::Parse(*info, kNoParsingFlags)) {
+ LanguageMode language_mode = info->function()->language_mode();
+ info->SetLanguageMode(language_mode);
+ shared->set_language_mode(language_mode);
+ info->SaveHandles();
+
+ if (Rewriter::Rewrite(*info) && Scope::Analyze(*info)) {
+ OptimizingCompiler* compiler =
+ new(info->zone()) OptimizingCompiler(*info);
+ OptimizingCompiler::Status status = compiler->CreateGraph();
+ if (status == OptimizingCompiler::SUCCEEDED) {
+ isolate->optimizing_compiler_thread()->QueueForOptimization(compiler);
+ shared->code()->set_profiler_ticks(0);
+ closure->ReplaceCode(isolate->builtins()->builtin(
+ Builtins::kInRecompileQueue));
+ info.Detach();
+ } else if (status == OptimizingCompiler::BAILED_OUT) {
+ isolate->clear_pending_exception();
+ InstallFullCode(*info);
+ }
+ }
+ }
+ }
+
+ if (isolate->has_pending_exception()) {
+ isolate->clear_pending_exception();
+ }
+}
+
+
+void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
+ SmartPointer<CompilationInfo> info(optimizing_compiler->info());
+ // If crankshaft succeeded, install the optimized code else install
+ // the unoptimized code.
+ OptimizingCompiler::Status status = optimizing_compiler->last_status();
+ if (status != OptimizingCompiler::SUCCEEDED) {
+ optimizing_compiler->info()->set_bailout_reason(
+ "failed/bailed out last time");
+ status = optimizing_compiler->AbortOptimization();
+ } else {
+ status = optimizing_compiler->GenerateAndInstallCode();
+ ASSERT(status == OptimizingCompiler::SUCCEEDED ||
+ status == OptimizingCompiler::BAILED_OUT);
+ }
+
+ InstallCodeCommon(*info);
+ if (status == OptimizingCompiler::SUCCEEDED) {
+ Handle<Code> code = info->code();
+ ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty());
+ info->closure()->ReplaceCode(*code);
+ if (info->shared_info()->SearchOptimizedCodeMap(
+ info->closure()->context()->native_context()) == -1) {
+ InsertCodeIntoOptimizedCodeMap(*info);
+ }
+ } else {
+ info->SetCode(Handle<Code>(info->shared_info()->code()));
+ InstallFullCode(*info);
+ }
+}
+
+
Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
Handle<Script> script) {
// Precondition: code has been parsed and scopes have been analyzed.
- CompilationInfo info(script);
+ CompilationInfoWithZone info(script);
info.SetFunction(literal);
info.SetScope(literal->scope());
info.SetLanguageMode(literal->scope()->language_mode());
@@ -719,19 +937,24 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
// builtins cannot be handled lazily by the parser, since we have to know
// if a function uses the special natives syntax, which is something the
// parser records.
+ // If the debugger requests compilation for break points, we cannot be
+ // aggressive about lazy compilation, because it might trigger compilation
+ // of functions without an outer context when setting a breakpoint through
+ // Debug::FindSharedFunctionInfoInScript.
+ bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext();
bool allow_lazy = literal->AllowsLazyCompilation() &&
- !LiveEditFunctionTracker::IsActive(info.isolate());
+ !LiveEditFunctionTracker::IsActive(info.isolate()) &&
+ (!info.isolate()->DebuggerHasBreakPoints() || allow_lazy_without_ctx);
Handle<ScopeInfo> scope_info(ScopeInfo::Empty());
// Generate code
- if (FLAG_lazy && allow_lazy) {
+ if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) {
Handle<Code> code = info.isolate()->builtins()->LazyCompile();
info.SetCode(code);
- } else if ((V8::UseCrankshaft() && MakeCrankshaftCode(&info)) ||
- (!V8::UseCrankshaft() && FullCodeGenerator::MakeCode(&info))) {
+ } else if (GenerateCode(&info)) {
ASSERT(!info.code().is_null());
- scope_info = ScopeInfo::Create(info.scope(), info.isolate()->zone());
+ scope_info = ScopeInfo::Create(info.scope(), info.zone());
} else {
return Handle<SharedFunctionInfo>::null();
}
@@ -745,12 +968,13 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
SetFunctionInfo(result, literal, false, script);
RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
result->set_allows_lazy_compilation(allow_lazy);
+ result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx);
// Set the expected number of properties for instances and return
// the resulting function.
SetExpectedNofPropertiesFromEstimate(result,
literal->expected_property_count());
- live_edit_tracker.RecordFunctionInfo(result, literal, info.isolate()->zone());
+ live_edit_tracker.RecordFunctionInfo(result, literal, info.zone());
return result;
}
@@ -777,6 +1001,8 @@ void Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
lit->has_only_simple_this_property_assignments(),
*lit->this_property_assignments());
function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
+ function_info->set_allows_lazy_compilation_without_context(
+ lit->AllowsLazyCompilationWithoutContext());
function_info->set_language_mode(lit->language_mode());
function_info->set_uses_arguments(lit->scope()->arguments() != NULL);
function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
@@ -784,6 +1010,7 @@ void Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
function_info->set_is_function(lit->is_function());
function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
function_info->set_dont_inline(lit->flags()->Contains(kDontInline));
+ function_info->set_dont_cache(lit->flags()->Contains(kDontCache));
}
@@ -796,7 +1023,7 @@ void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
// Log the code generation. If source information is available include
// script name and line number. Check explicitly whether logging is
// enabled as finding the line number is not free.
- if (info->isolate()->logger()->is_logging() ||
+ if (info->isolate()->logger()->is_logging_code_events() ||
CpuProfiler::is_profiling(info->isolate())) {
Handle<Script> script = info->script();
Handle<Code> code = info->code();
diff --git a/deps/v8/src/compiler.h b/deps/v8/src/compiler.h
index 44df9e090..af9459566 100644
--- a/deps/v8/src/compiler.h
+++ b/deps/v8/src/compiler.h
@@ -39,16 +39,21 @@ class ScriptDataImpl;
// CompilationInfo encapsulates some information known at compile time. It
// is constructed based on the resources available at compile-time.
-class CompilationInfo BASE_EMBEDDED {
+class CompilationInfo {
public:
- explicit CompilationInfo(Handle<Script> script);
- explicit CompilationInfo(Handle<SharedFunctionInfo> shared_info);
- explicit CompilationInfo(Handle<JSFunction> closure);
+ CompilationInfo(Handle<Script> script, Zone* zone);
+ CompilationInfo(Handle<SharedFunctionInfo> shared_info, Zone* zone);
+ CompilationInfo(Handle<JSFunction> closure, Zone* zone);
+
+ virtual ~CompilationInfo();
Isolate* isolate() {
ASSERT(Isolate::Current() == isolate_);
return isolate_;
}
+ Zone* zone() {
+ return zone_;
+ }
bool is_lazy() const { return IsLazy::decode(flags_); }
bool is_eval() const { return IsEval::decode(flags_); }
bool is_global() const { return IsGlobal::decode(flags_); }
@@ -67,8 +72,8 @@ class CompilationInfo BASE_EMBEDDED {
Handle<Script> script() const { return script_; }
v8::Extension* extension() const { return extension_; }
ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
- Handle<Context> calling_context() const { return calling_context_; }
- int osr_ast_id() const { return osr_ast_id_; }
+ Handle<Context> context() const { return context_; }
+ BailoutId osr_ast_id() const { return osr_ast_id_; }
void MarkAsEval() {
ASSERT(!is_lazy());
@@ -115,13 +120,8 @@ class CompilationInfo BASE_EMBEDDED {
ASSERT(!is_lazy());
pre_parse_data_ = pre_parse_data;
}
- void SetCallingContext(Handle<Context> context) {
- ASSERT(is_eval());
- calling_context_ = context;
- }
- void SetOsrAstId(int osr_ast_id) {
- ASSERT(IsOptimizing());
- osr_ast_id_ = osr_ast_id;
+ void SetContext(Handle<Context> context) {
+ context_ = context;
}
void MarkCompilingForDebugging(Handle<Code> current_code) {
ASSERT(mode_ != OPTIMIZE);
@@ -138,17 +138,18 @@ class CompilationInfo BASE_EMBEDDED {
}
bool has_global_object() const {
- return !closure().is_null() && (closure()->context()->global() != NULL);
+ return !closure().is_null() &&
+ (closure()->context()->global_object() != NULL);
}
GlobalObject* global_object() const {
- return has_global_object() ? closure()->context()->global() : NULL;
+ return has_global_object() ? closure()->context()->global_object() : NULL;
}
// Accessors for the different compilation modes.
bool IsOptimizing() const { return mode_ == OPTIMIZE; }
bool IsOptimizable() const { return mode_ == BASE; }
- void SetOptimizing(int osr_ast_id) {
+ void SetOptimizing(BailoutId osr_ast_id) {
SetMode(OPTIMIZE);
osr_ast_id_ = osr_ast_id;
}
@@ -170,6 +171,21 @@ class CompilationInfo BASE_EMBEDDED {
// current compilation pipeline.
void AbortOptimization();
+ void set_deferred_handles(DeferredHandles* deferred_handles) {
+ ASSERT(deferred_handles_ == NULL);
+ deferred_handles_ = deferred_handles;
+ }
+
+ void SaveHandles() {
+ SaveHandle(&closure_);
+ SaveHandle(&shared_info_);
+ SaveHandle(&context_);
+ SaveHandle(&script_);
+ }
+
+ const char* bailout_reason() const { return bailout_reason_; }
+ void set_bailout_reason(const char* reason) { bailout_reason_ = reason; }
+
private:
Isolate* isolate_;
@@ -184,8 +200,6 @@ class CompilationInfo BASE_EMBEDDED {
NONOPT
};
- CompilationInfo() : function_(NULL) {}
-
void Initialize(Mode mode) {
mode_ = V8::UseCrankshaft() ? mode : NONOPT;
ASSERT(!script_.is_null());
@@ -196,6 +210,7 @@ class CompilationInfo BASE_EMBEDDED {
ASSERT(language_mode() == CLASSIC_MODE);
SetLanguageMode(shared_info_->language_mode());
}
+ set_bailout_reason("unknown");
}
void SetMode(Mode mode) {
@@ -246,18 +261,148 @@ class CompilationInfo BASE_EMBEDDED {
v8::Extension* extension_;
ScriptDataImpl* pre_parse_data_;
- // The context of the caller is needed for eval code, and will be a null
- // handle otherwise.
- Handle<Context> calling_context_;
+ // The context of the caller for eval code, and the global context for a
+ // global script. Will be a null handle otherwise.
+ Handle<Context> context_;
// Compilation mode flag and whether deoptimization is allowed.
Mode mode_;
- int osr_ast_id_;
+ BailoutId osr_ast_id_;
+
+ // The zone from which the compilation pipeline working on this
+ // CompilationInfo allocates.
+ Zone* zone_;
+
+ DeferredHandles* deferred_handles_;
+
+ template<typename T>
+ void SaveHandle(Handle<T> *object) {
+ if (!object->is_null()) {
+ Handle<T> handle(*(*object));
+ *object = handle;
+ }
+ }
+
+ const char* bailout_reason_;
DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
};
+// Exactly like a CompilationInfo, except also creates and enters a
+// Zone on construction and deallocates it on exit.
+class CompilationInfoWithZone: public CompilationInfo {
+ public:
+ explicit CompilationInfoWithZone(Handle<Script> script)
+ : CompilationInfo(script, &zone_),
+ zone_(script->GetIsolate()),
+ zone_scope_(&zone_, DELETE_ON_EXIT) {}
+ explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info)
+ : CompilationInfo(shared_info, &zone_),
+ zone_(shared_info->GetIsolate()),
+ zone_scope_(&zone_, DELETE_ON_EXIT) {}
+ explicit CompilationInfoWithZone(Handle<JSFunction> closure)
+ : CompilationInfo(closure, &zone_),
+ zone_(closure->GetIsolate()),
+ zone_scope_(&zone_, DELETE_ON_EXIT) {}
+
+ private:
+ Zone zone_;
+ ZoneScope zone_scope_;
+};
+
+
+// A wrapper around a CompilationInfo that detaches the Handles from
+// the underlying DeferredHandleScope and stores them in info_ on
+// destruction.
+class CompilationHandleScope BASE_EMBEDDED {
+ public:
+ explicit CompilationHandleScope(CompilationInfo* info)
+ : deferred_(info->isolate()), info_(info) {}
+ ~CompilationHandleScope() {
+ info_->set_deferred_handles(deferred_.Detach());
+ }
+
+ private:
+ DeferredHandleScope deferred_;
+ CompilationInfo* info_;
+};
+
+
+class HGraph;
+class HGraphBuilder;
+class LChunk;
+
+// A helper class that calls the three compilation phases in
+// Crankshaft and keeps track of its state. The three phases
+// CreateGraph, OptimizeGraph and GenerateAndInstallCode can either
+// fail, bail-out to the full code generator or succeed. Apart from
+// their return value, the status of the phase last run can be checked
+// using last_status().
+class OptimizingCompiler: public ZoneObject {
+ public:
+ explicit OptimizingCompiler(CompilationInfo* info)
+ : info_(info),
+ oracle_(NULL),
+ graph_builder_(NULL),
+ graph_(NULL),
+ chunk_(NULL),
+ time_taken_to_create_graph_(0),
+ time_taken_to_optimize_(0),
+ time_taken_to_codegen_(0),
+ last_status_(FAILED) { }
+
+ enum Status {
+ FAILED, BAILED_OUT, SUCCEEDED
+ };
+
+ MUST_USE_RESULT Status CreateGraph();
+ MUST_USE_RESULT Status OptimizeGraph();
+ MUST_USE_RESULT Status GenerateAndInstallCode();
+
+ Status last_status() const { return last_status_; }
+ CompilationInfo* info() const { return info_; }
+
+ MUST_USE_RESULT Status AbortOptimization() {
+ info_->AbortOptimization();
+ info_->shared_info()->DisableOptimization(info_->bailout_reason());
+ return SetLastStatus(BAILED_OUT);
+ }
+
+ private:
+ CompilationInfo* info_;
+ TypeFeedbackOracle* oracle_;
+ HGraphBuilder* graph_builder_;
+ HGraph* graph_;
+ LChunk* chunk_;
+ int64_t time_taken_to_create_graph_;
+ int64_t time_taken_to_optimize_;
+ int64_t time_taken_to_codegen_;
+ Status last_status_;
+
+ MUST_USE_RESULT Status SetLastStatus(Status status) {
+ last_status_ = status;
+ return last_status_;
+ }
+ void RecordOptimizationStats();
+
+ struct Timer {
+ Timer(OptimizingCompiler* compiler, int64_t* location)
+ : compiler_(compiler),
+ start_(OS::Ticks()),
+ location_(location) { }
+
+ ~Timer() {
+ *location_ += (OS::Ticks() - start_);
+ }
+
+ OptimizingCompiler* compiler_;
+ int64_t start_;
+ int64_t* location_;
+ };
+};
+
+
// The V8 compiler
//
// General strategy: Source code is translated into an anonymous function w/o
@@ -271,10 +416,6 @@ class CompilationInfo BASE_EMBEDDED {
class Compiler : public AllStatic {
public:
- // Default maximum number of function optimization attempts before we
- // give up.
- static const int kDefaultMaxOptCount = 10;
-
static const int kMaxInliningLevels = 3;
// Call count before primitive functions trigger their own optimization.
@@ -289,6 +430,7 @@ class Compiler : public AllStatic {
Handle<Object> script_name,
int line_offset,
int column_offset,
+ Handle<Context> context,
v8::Extension* extension,
ScriptDataImpl* pre_data,
Handle<Object> script_data,
@@ -305,6 +447,8 @@ class Compiler : public AllStatic {
// success and false if the compilation resulted in a stack overflow.
static bool CompileLazy(CompilationInfo* info);
+ static void RecompileParallel(Handle<JSFunction> function);
+
// Compile a shared function info object (the function is possibly lazily
// compiled).
static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
@@ -316,6 +460,8 @@ class Compiler : public AllStatic {
bool is_toplevel,
Handle<Script> script);
+ static void InstallOptimizedCode(OptimizingCompiler* info);
+
#ifdef ENABLE_DEBUGGER_SUPPORT
static bool MakeCodeForLiveEdit(CompilationInfo* info);
#endif
diff --git a/deps/v8/src/contexts.cc b/deps/v8/src/contexts.cc
index 76784bd70..93c979540 100644
--- a/deps/v8/src/contexts.cc
+++ b/deps/v8/src/contexts.cc
@@ -36,7 +36,7 @@ namespace internal {
Context* Context::declaration_context() {
Context* current = this;
- while (!current->IsFunctionContext() && !current->IsGlobalContext()) {
+ while (!current->IsFunctionContext() && !current->IsNativeContext()) {
current = current->previous();
ASSERT(current->closure() == closure());
}
@@ -45,7 +45,7 @@ Context* Context::declaration_context() {
JSBuiltinsObject* Context::builtins() {
- GlobalObject* object = global();
+ GlobalObject* object = global_object();
if (object->IsJSGlobalObject()) {
return JSGlobalObject::cast(object)->builtins();
} else {
@@ -55,19 +55,19 @@ JSBuiltinsObject* Context::builtins() {
}
-Context* Context::global_context() {
+Context* Context::native_context() {
// Fast case: the global object for this context has been set. In
// that case, the global object has a direct pointer to the global
// context.
- if (global()->IsGlobalObject()) {
- return global()->global_context();
+ if (global_object()->IsGlobalObject()) {
+ return global_object()->native_context();
}
// During bootstrapping, the global object might not be set and we
- // have to search the context chain to find the global context.
+ // have to search the context chain to find the native context.
ASSERT(Isolate::Current()->bootstrapper()->IsActive());
Context* current = this;
- while (!current->IsGlobalContext()) {
+ while (!current->IsNativeContext()) {
JSFunction* closure = JSFunction::cast(current->closure());
current = Context::cast(closure->context());
}
@@ -76,11 +76,11 @@ Context* Context::global_context() {
JSObject* Context::global_proxy() {
- return global_context()->global_proxy_object();
+ return native_context()->global_proxy_object();
}
void Context::set_global_proxy(JSObject* object) {
- global_context()->set_global_proxy_object(object);
+ native_context()->set_global_proxy_object(object);
}
@@ -106,12 +106,12 @@ Handle<Object> Context::Lookup(Handle<String> name,
do {
if (FLAG_trace_contexts) {
PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
- if (context->IsGlobalContext()) PrintF(" (global context)");
+ if (context->IsNativeContext()) PrintF(" (native context)");
PrintF("\n");
}
// 1. Check global objects, subjects of with, and extension objects.
- if (context->IsGlobalContext() ||
+ if (context->IsNativeContext() ||
context->IsWithContext() ||
(context->IsFunctionContext() && context->has_extension())) {
Handle<JSObject> object(JSObject::cast(context->extension()), isolate);
@@ -226,7 +226,7 @@ Handle<Object> Context::Lookup(Handle<String> name,
}
// 3. Prepare to continue with the previous (next outermost) context.
- if (context->IsGlobalContext()) {
+ if (context->IsNativeContext()) {
follow_context_chain = false;
} else {
context = Handle<Context>(context->previous(), isolate);
@@ -241,19 +241,21 @@ Handle<Object> Context::Lookup(Handle<String> name,
void Context::AddOptimizedFunction(JSFunction* function) {
- ASSERT(IsGlobalContext());
+ ASSERT(IsNativeContext());
#ifdef DEBUG
- Object* element = get(OPTIMIZED_FUNCTIONS_LIST);
- while (!element->IsUndefined()) {
- CHECK(element != function);
- element = JSFunction::cast(element)->next_function_link();
+ if (FLAG_enable_slow_asserts) {
+ Object* element = get(OPTIMIZED_FUNCTIONS_LIST);
+ while (!element->IsUndefined()) {
+ CHECK(element != function);
+ element = JSFunction::cast(element)->next_function_link();
+ }
}
CHECK(function->next_function_link()->IsUndefined());
- // Check that the context belongs to the weak global contexts list.
+ // Check that the context belongs to the weak native contexts list.
bool found = false;
- Object* context = GetHeap()->global_contexts_list();
+ Object* context = GetHeap()->native_contexts_list();
while (!context->IsUndefined()) {
if (context == this) {
found = true;
@@ -269,7 +271,7 @@ void Context::AddOptimizedFunction(JSFunction* function) {
void Context::RemoveOptimizedFunction(JSFunction* function) {
- ASSERT(IsGlobalContext());
+ ASSERT(IsNativeContext());
Object* element = get(OPTIMIZED_FUNCTIONS_LIST);
JSFunction* prev = NULL;
while (!element->IsUndefined()) {
@@ -293,7 +295,7 @@ void Context::RemoveOptimizedFunction(JSFunction* function) {
Object* Context::OptimizedFunctionsListHead() {
- ASSERT(IsGlobalContext());
+ ASSERT(IsNativeContext());
return get(OPTIMIZED_FUNCTIONS_LIST);
}
@@ -303,11 +305,28 @@ void Context::ClearOptimizedFunctions() {
}
+Handle<Object> Context::ErrorMessageForCodeGenerationFromStrings() {
+ Handle<Object> result(error_message_for_code_gen_from_strings());
+ if (result->IsUndefined()) {
+ const char* error =
+ "Code generation from strings disallowed for this context";
+ Isolate* isolate = Isolate::Current();
+ result = isolate->factory()->NewStringFromAscii(i::CStrVector(error));
+ }
+ return result;
+}
+
+
#ifdef DEBUG
-bool Context::IsBootstrappingOrContext(Object* object) {
+bool Context::IsBootstrappingOrValidParentContext(
+ Object* object, Context* child) {
// During bootstrapping we allow all objects to pass as
// contexts. This is necessary to fix circular dependencies.
- return Isolate::Current()->bootstrapper()->IsActive() || object->IsContext();
+ if (Isolate::Current()->bootstrapper()->IsActive()) return true;
+ if (!object->IsContext()) return false;
+ Context* context = Context::cast(object);
+ return context->IsNativeContext() || context->IsGlobalContext() ||
+ context->IsModuleContext() || !child->IsModuleContext();
}
diff --git a/deps/v8/src/contexts.h b/deps/v8/src/contexts.h
index d154b82ca..28e4af536 100644
--- a/deps/v8/src/contexts.h
+++ b/deps/v8/src/contexts.h
@@ -96,7 +96,7 @@ enum BindingFlags {
// must always be allocated via Heap::AllocateContext() or
// Factory::NewContext.
-#define GLOBAL_CONTEXT_FIELDS(V) \
+#define NATIVE_CONTEXT_FIELDS(V) \
V(GLOBAL_PROXY_INDEX, JSObject, global_proxy_object) \
V(SECURITY_TOKEN_INDEX, Object, security_token) \
V(BOOLEAN_FUNCTION_INDEX, JSFunction, boolean_function) \
@@ -154,6 +154,8 @@ enum BindingFlags {
V(MAP_CACHE_INDEX, Object, map_cache) \
V(CONTEXT_DATA_INDEX, Object, data) \
V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \
+ V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \
+ error_message_for_code_gen_from_strings) \
V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \
to_complete_property_descriptor) \
V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
@@ -190,16 +192,19 @@ enum BindingFlags {
// Dynamically declared variables/functions are also added
// to lazily allocated extension object. Context::Lookup
// searches the extension object for properties.
+// For global and block contexts, contains the respective
+// ScopeInfo.
+// For module contexts, points back to the respective JSModule.
//
-// [ global ] A pointer to the global object. Provided for quick
+// [ global_object ] A pointer to the global object. Provided for quick
// access to the global object from inside the code (since
// we always have a context pointer).
//
// In addition, function contexts may have statically allocated context slots
// to store local variables/functions that are accessed from inner functions
// (via static context addresses) or through 'eval' (dynamic context lookups).
-// Finally, the global context contains additional slots for fast access to
-// global properties.
+// Finally, the native context contains additional slots for fast access to
+// native properties.
class Context: public FixedArray {
public:
@@ -217,15 +222,15 @@ class Context: public FixedArray {
// The extension slot is used for either the global object (in global
// contexts), eval extension object (function contexts), subject of with
// (with contexts), or the variable name (catch contexts), the serialized
- // scope info (block contexts).
+ // scope info (block contexts), or the module instance (module contexts).
EXTENSION_INDEX,
- GLOBAL_INDEX,
+ GLOBAL_OBJECT_INDEX,
MIN_CONTEXT_SLOTS,
// This slot holds the thrown value in catch contexts.
THROWN_OBJECT_INDEX = MIN_CONTEXT_SLOTS,
- // These slots are only in global contexts.
+ // These slots are only in native contexts.
GLOBAL_PROXY_INDEX = MIN_CONTEXT_SLOTS,
SECURITY_TOKEN_INDEX,
ARGUMENTS_BOILERPLATE_INDEX,
@@ -278,6 +283,7 @@ class Context: public FixedArray {
OUT_OF_MEMORY_INDEX,
CONTEXT_DATA_INDEX,
ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
+ ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX,
TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX,
DERIVED_HAS_TRAP_INDEX,
DERIVED_GET_TRAP_INDEX,
@@ -292,7 +298,7 @@ class Context: public FixedArray {
NEXT_CONTEXT_LINK, // Weak.
// Total number of slots.
- GLOBAL_CONTEXT_SLOTS,
+ NATIVE_CONTEXT_SLOTS,
FIRST_WEAK_SLOT = OPTIMIZED_FUNCTIONS_LIST
};
@@ -303,7 +309,7 @@ class Context: public FixedArray {
Context* previous() {
Object* result = unchecked_previous();
- ASSERT(IsBootstrappingOrContext(result));
+ ASSERT(IsBootstrappingOrValidParentContext(result, this));
return reinterpret_cast<Context*>(result);
}
void set_previous(Context* context) { set(PREVIOUS_INDEX, context); }
@@ -312,16 +318,21 @@ class Context: public FixedArray {
Object* extension() { return get(EXTENSION_INDEX); }
void set_extension(Object* object) { set(EXTENSION_INDEX, object); }
+ JSModule* module() { return JSModule::cast(get(EXTENSION_INDEX)); }
+ void set_module(JSModule* module) { set(EXTENSION_INDEX, module); }
+
// Get the context where var declarations will be hoisted to, which
// may be the context itself.
Context* declaration_context();
- GlobalObject* global() {
- Object* result = get(GLOBAL_INDEX);
+ GlobalObject* global_object() {
+ Object* result = get(GLOBAL_OBJECT_INDEX);
ASSERT(IsBootstrappingOrGlobalObject(result));
return reinterpret_cast<GlobalObject*>(result);
}
- void set_global(GlobalObject* global) { set(GLOBAL_INDEX, global); }
+ void set_global_object(GlobalObject* object) {
+ set(GLOBAL_OBJECT_INDEX, object);
+ }
// Returns a JSGlobalProxy object or null.
JSObject* global_proxy();
@@ -330,11 +341,11 @@ class Context: public FixedArray {
// The builtins object.
JSBuiltinsObject* builtins();
- // Compute the global context by traversing the context chain.
- Context* global_context();
+ // Compute the native context by traversing the context chain.
+ Context* native_context();
- // Predicates for context types. IsGlobalContext is defined on Object
- // because we frequently have to know if arbitrary objects are global
+ // Predicates for context types. IsNativeContext is defined on Object
+ // because we frequently have to know if arbitrary objects are natives
// contexts.
bool IsFunctionContext() {
Map* map = this->map();
@@ -356,30 +367,36 @@ class Context: public FixedArray {
Map* map = this->map();
return map == map->GetHeap()->module_context_map();
}
+ bool IsGlobalContext() {
+ Map* map = this->map();
+ return map == map->GetHeap()->global_context_map();
+ }
- // Tells whether the global context is marked with out of memory.
+ // Tells whether the native context is marked with out of memory.
inline bool has_out_of_memory();
- // Mark the global context with out of memory.
+ // Mark the native context with out of memory.
inline void mark_out_of_memory();
- // A global context hold a list of all functions which have been optimized.
+ // A native context hold a list of all functions which have been optimized.
void AddOptimizedFunction(JSFunction* function);
void RemoveOptimizedFunction(JSFunction* function);
Object* OptimizedFunctionsListHead();
void ClearOptimizedFunctions();
-#define GLOBAL_CONTEXT_FIELD_ACCESSORS(index, type, name) \
+ Handle<Object> ErrorMessageForCodeGenerationFromStrings();
+
+#define NATIVE_CONTEXT_FIELD_ACCESSORS(index, type, name) \
void set_##name(type* value) { \
- ASSERT(IsGlobalContext()); \
+ ASSERT(IsNativeContext()); \
set(index, value); \
} \
type* name() { \
- ASSERT(IsGlobalContext()); \
+ ASSERT(IsNativeContext()); \
return type::cast(get(index)); \
}
- GLOBAL_CONTEXT_FIELDS(GLOBAL_CONTEXT_FIELD_ACCESSORS)
-#undef GLOBAL_CONTEXT_FIELD_ACCESSORS
+ NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSORS)
+#undef NATIVE_CONTEXT_FIELD_ACCESSORS
// Lookup the slot called name, starting with the current context.
// There are three possibilities:
@@ -409,7 +426,7 @@ class Context: public FixedArray {
return kHeaderSize + index * kPointerSize - kHeapObjectTag;
}
- static const int kSize = kHeaderSize + GLOBAL_CONTEXT_SLOTS * kPointerSize;
+ static const int kSize = kHeaderSize + NATIVE_CONTEXT_SLOTS * kPointerSize;
// GC support.
typedef FixedBodyDescriptor<
@@ -426,7 +443,7 @@ class Context: public FixedArray {
#ifdef DEBUG
// Bootstrapping-aware type checks.
- static bool IsBootstrappingOrContext(Object* object);
+ static bool IsBootstrappingOrValidParentContext(Object* object, Context* kid);
static bool IsBootstrappingOrGlobalObject(Object* object);
#endif
};
diff --git a/deps/v8/src/conversions-inl.h b/deps/v8/src/conversions-inl.h
index 77b260f03..e272fe6c0 100644
--- a/deps/v8/src/conversions-inl.h
+++ b/deps/v8/src/conversions-inl.h
@@ -51,6 +51,11 @@ inline double JunkStringValue() {
}
+inline double SignedZero(bool negative) {
+ return negative ? uint64_to_double(Double::kSignMask) : 0.0;
+}
+
+
// The fast double-to-unsigned-int conversion routine does not guarantee
// rounding towards zero, or any reasonable value if the argument is larger
// than what fits in an unsigned 32-bit integer.
@@ -263,6 +268,7 @@ double InternalStringToInt(UnicodeCache* unicode_cache,
if (radix == 0) {
// Radix detection.
+ radix = 10;
if (*current == '0') {
++current;
if (current == end) return SignedZero(negative);
@@ -271,11 +277,8 @@ double InternalStringToInt(UnicodeCache* unicode_cache,
++current;
if (current == end) return JunkStringValue();
} else {
- radix = 8;
leading_zero = true;
}
- } else {
- radix = 10;
}
} else if (radix == 16) {
if (*current == '0') {
@@ -459,16 +462,23 @@ double InternalStringToDouble(UnicodeCache* unicode_cache,
int insignificant_digits = 0;
bool nonzero_digit_dropped = false;
- bool negative = false;
+ enum Sign {
+ NONE,
+ NEGATIVE,
+ POSITIVE
+ };
+
+ Sign sign = NONE;
if (*current == '+') {
// Ignore leading sign.
++current;
if (current == end) return JunkStringValue();
+ sign = POSITIVE;
} else if (*current == '-') {
++current;
if (current == end) return JunkStringValue();
- negative = true;
+ sign = NEGATIVE;
}
static const char kInfinitySymbol[] = "Infinity";
@@ -483,34 +493,34 @@ double InternalStringToDouble(UnicodeCache* unicode_cache,
}
ASSERT(buffer_pos == 0);
- return negative ? -V8_INFINITY : V8_INFINITY;
+ return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY;
}
bool leading_zero = false;
if (*current == '0') {
++current;
- if (current == end) return SignedZero(negative);
+ if (current == end) return SignedZero(sign == NEGATIVE);
leading_zero = true;
// It could be hexadecimal value.
if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
++current;
- if (current == end || !isDigit(*current, 16)) {
+ if (current == end || !isDigit(*current, 16) || sign != NONE) {
return JunkStringValue(); // "0x".
}
return InternalStringToIntDouble<4>(unicode_cache,
current,
end,
- negative,
+ false,
allow_trailing_junk);
}
// Ignore leading zeros in the integer part.
while (*current == '0') {
++current;
- if (current == end) return SignedZero(negative);
+ if (current == end) return SignedZero(sign == NEGATIVE);
}
}
@@ -555,7 +565,7 @@ double InternalStringToDouble(UnicodeCache* unicode_cache,
// leading zeros (if any).
while (*current == '0') {
++current;
- if (current == end) return SignedZero(negative);
+ if (current == end) return SignedZero(sign == NEGATIVE);
exponent--; // Move this 0 into the exponent.
}
}
@@ -647,7 +657,7 @@ double InternalStringToDouble(UnicodeCache* unicode_cache,
return InternalStringToIntDouble<3>(unicode_cache,
buffer,
buffer + buffer_pos,
- negative,
+ sign == NEGATIVE,
allow_trailing_junk);
}
@@ -660,7 +670,7 @@ double InternalStringToDouble(UnicodeCache* unicode_cache,
buffer[buffer_pos] = '\0';
double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
- return negative ? -converted : converted;
+ return (sign == NEGATIVE) ? -converted : converted;
}
} } // namespace v8::internal
diff --git a/deps/v8/src/conversions.h b/deps/v8/src/conversions.h
index 70559c9e9..1fbb5f118 100644
--- a/deps/v8/src/conversions.h
+++ b/deps/v8/src/conversions.h
@@ -52,8 +52,13 @@ inline bool isDigit(int x, int radix) {
}
-inline double SignedZero(bool negative) {
- return negative ? -0.0 : 0.0;
+// The fast double-to-(unsigned-)int conversion routine does not guarantee
+// rounding towards zero.
+// For NaN and values outside the int range, return INT_MIN or INT_MAX.
+inline int FastD2IChecked(double x) {
+ if (!(x >= INT_MIN)) return INT_MIN; // Negation to catch NaNs.
+ if (x > INT_MAX) return INT_MAX;
+ return static_cast<int>(x);
}
@@ -62,8 +67,6 @@ inline double SignedZero(bool negative) {
// The result is unspecified if x is infinite or NaN, or if the rounded
// integer value is outside the range of type int.
inline int FastD2I(double x) {
- // The static_cast convertion from double to int used to be slow, but
- // as new benchmarks show, now it is much faster than lrint().
return static_cast<int>(x);
}
diff --git a/deps/v8/src/counters.cc b/deps/v8/src/counters.cc
index faad6d409..811c0aa2e 100644
--- a/deps/v8/src/counters.cc
+++ b/deps/v8/src/counters.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -64,9 +64,20 @@ void StatsCounterTimer::Stop() {
counter_.Increment(milliseconds);
}
+void Histogram::AddSample(int sample) {
+ if (Enabled()) {
+ Isolate::Current()->stats_table()->AddHistogramSample(histogram_, sample);
+ }
+}
+
+void* Histogram::CreateHistogram() const {
+ return Isolate::Current()->stats_table()->
+ CreateHistogram(name_, min_, max_, num_buckets_);
+}
+
// Start the timer.
void HistogramTimer::Start() {
- if (GetHistogram() != NULL) {
+ if (histogram_.Enabled()) {
stop_time_ = 0;
start_time_ = OS::Ticks();
}
@@ -74,20 +85,13 @@ void HistogramTimer::Start() {
// Stop the timer and record the results.
void HistogramTimer::Stop() {
- if (histogram_ != NULL) {
+ if (histogram_.Enabled()) {
stop_time_ = OS::Ticks();
// Compute the delta between start and stop, in milliseconds.
int milliseconds = static_cast<int>(stop_time_ - start_time_) / 1000;
- Isolate::Current()->stats_table()->
- AddHistogramSample(histogram_, milliseconds);
+ histogram_.AddSample(milliseconds);
}
}
-
-void* HistogramTimer::CreateHistogram() const {
- return Isolate::Current()->stats_table()->
- CreateHistogram(name_, 0, 10000, 50);
-}
-
} } // namespace v8::internal
diff --git a/deps/v8/src/counters.h b/deps/v8/src/counters.h
index 6498a0242..577280f44 100644
--- a/deps/v8/src/counters.h
+++ b/deps/v8/src/counters.h
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -169,8 +169,7 @@ struct StatsCounter {
protected:
// Returns the cached address of this counter location.
int* GetPtr() {
- if (lookup_done_)
- return ptr_;
+ if (lookup_done_) return ptr_;
lookup_done_ = true;
ptr_ = FindLocationInStatsTable();
return ptr_;
@@ -199,25 +198,30 @@ struct StatsCounterTimer {
}
};
-// A HistogramTimer allows distributions of results to be created
-// HistogramTimer t = { L"foo", NULL, false, 0, 0 };
-struct HistogramTimer {
+// A Histogram represents a dynamically created histogram in the StatsTable.
+//
+// This class is designed to be POD initialized. It will be registered with
+// the histogram system on first use. For example:
+// Histogram h = { "myhist", 0, 10000, 50, NULL, false };
+struct Histogram {
const char* name_;
+ int min_;
+ int max_;
+ int num_buckets_;
void* histogram_;
bool lookup_done_;
- int64_t start_time_;
- int64_t stop_time_;
-
- // Start the timer.
- void Start();
+ // Add a single sample to this histogram.
+ void AddSample(int sample);
- // Stop the timer and record the results.
- void Stop();
+ // Returns true if this histogram is enabled.
+ bool Enabled() {
+ return GetHistogram() != NULL;
+ }
- // Returns true if the timer is running.
- bool Running() {
- return (histogram_ != NULL) && (start_time_ != 0) && (stop_time_ == 0);
+ // Reset the cached internal pointer.
+ void Reset() {
+ lookup_done_ = false;
}
protected:
@@ -234,6 +238,30 @@ struct HistogramTimer {
void* CreateHistogram() const;
};
+// A HistogramTimer allows distributions of results to be created
+// HistogramTimer t = { {L"foo", 0, 10000, 50, NULL, false}, 0, 0 };
+struct HistogramTimer {
+ Histogram histogram_;
+
+ int64_t start_time_;
+ int64_t stop_time_;
+
+ // Start the timer.
+ void Start();
+
+ // Stop the timer and record the results.
+ void Stop();
+
+ // Returns true if the timer is running.
+ bool Running() {
+ return histogram_.Enabled() && (start_time_ != 0) && (stop_time_ == 0);
+ }
+
+ void Reset() {
+ histogram_.Reset();
+ }
+};
+
// Helper class for scoping a HistogramTimer.
class HistogramTimerScope BASE_EMBEDDED {
public:
diff --git a/deps/v8/src/cpu-profiler.h b/deps/v8/src/cpu-profiler.h
index 6e2e771a4..9cd448420 100644
--- a/deps/v8/src/cpu-profiler.h
+++ b/deps/v8/src/cpu-profiler.h
@@ -188,7 +188,7 @@ class ProfilerEventsProcessor : public Thread {
#define PROFILE(isolate, Call) \
- LOG(isolate, Call); \
+ LOG_CODE_EVENT(isolate, Call); \
do { \
if (v8::internal::CpuProfiler::is_profiling(isolate)) { \
v8::internal::CpuProfiler::Call; \
diff --git a/deps/v8/src/d8.cc b/deps/v8/src/d8.cc
index 7a01d5514..b3b1bb8a1 100644
--- a/deps/v8/src/d8.cc
+++ b/deps/v8/src/d8.cc
@@ -200,7 +200,13 @@ Handle<Value> Shell::Write(const Arguments& args) {
if (i != 0) {
printf(" ");
}
- v8::String::Utf8Value str(args[i]);
+
+ // Explicitly catch potential exceptions in toString().
+ v8::TryCatch try_catch;
+ Handle<String> str_obj = args[i]->ToString();
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+
+ v8::String::Utf8Value str(str_obj);
int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
if (n != str.length()) {
printf("Error in fwrite\n");
@@ -284,9 +290,9 @@ Handle<Value> Shell::Load(const Arguments& args) {
return Undefined();
}
-static size_t convertToUint(Local<Value> value_in, TryCatch* try_catch) {
- if (value_in->IsUint32()) {
- return value_in->Uint32Value();
+static int32_t convertToInt(Local<Value> value_in, TryCatch* try_catch) {
+ if (value_in->IsInt32()) {
+ return value_in->Int32Value();
}
Local<Value> number = value_in->ToNumber();
@@ -296,7 +302,15 @@ static size_t convertToUint(Local<Value> value_in, TryCatch* try_catch) {
Local<Int32> int32 = number->ToInt32();
if (try_catch->HasCaught() || int32.IsEmpty()) return 0;
- int32_t raw_value = int32->Int32Value();
+ int32_t value = int32->Int32Value();
+ if (try_catch->HasCaught()) return 0;
+
+ return value;
+}
+
+
+static int32_t convertToUint(Local<Value> value_in, TryCatch* try_catch) {
+ int32_t raw_value = convertToInt(value_in, try_catch);
if (try_catch->HasCaught()) return 0;
if (raw_value < 0) {
@@ -312,14 +326,18 @@ static size_t convertToUint(Local<Value> value_in, TryCatch* try_catch) {
ThrowException(
String::New("Array length exceeds maximum length."));
}
- return static_cast<size_t>(raw_value);
+ return raw_value;
}
+// TODO(rossberg): should replace these by proper uses of HasInstance,
+// once we figure out a good way to make the templates global.
const char kArrayBufferMarkerPropName[] = "d8::_is_array_buffer_";
+const char kArrayMarkerPropName[] = "d8::_is_typed_array_";
-Handle<Value> Shell::CreateExternalArrayBuffer(int32_t length) {
+Handle<Value> Shell::CreateExternalArrayBuffer(Handle<Object> buffer,
+ int32_t length) {
static const int32_t kMaxSize = 0x7fffffff;
// Make sure the total size fits into a (signed) int.
if (length < 0 || length > kMaxSize) {
@@ -327,11 +345,10 @@ Handle<Value> Shell::CreateExternalArrayBuffer(int32_t length) {
}
uint8_t* data = new uint8_t[length];
if (data == NULL) {
- return ThrowException(String::New("Memory allocation failed."));
+ return ThrowException(String::New("Memory allocation failed"));
}
memset(data, 0, length);
- Handle<Object> buffer = Object::New();
buffer->SetHiddenValue(String::New(kArrayBufferMarkerPropName), True());
Persistent<Object> persistent_array = Persistent<Object>::New(buffer);
persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
@@ -346,28 +363,73 @@ Handle<Value> Shell::CreateExternalArrayBuffer(int32_t length) {
}
-Handle<Value> Shell::CreateExternalArrayBuffer(const Arguments& args) {
+Handle<Value> Shell::ArrayBuffer(const Arguments& args) {
+ if (!args.IsConstructCall()) {
+ Handle<Value>* rec_args = new Handle<Value>[args.Length()];
+ for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i];
+ Handle<Value> result = args.Callee()->NewInstance(args.Length(), rec_args);
+ delete[] rec_args;
+ return result;
+ }
+
if (args.Length() == 0) {
return ThrowException(
- String::New("ArrayBuffer constructor must have one parameter."));
+ String::New("ArrayBuffer constructor must have one argument"));
}
TryCatch try_catch;
int32_t length = convertToUint(args[0], &try_catch);
- if (try_catch.HasCaught()) return try_catch.Exception();
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
- return CreateExternalArrayBuffer(length);
+ return CreateExternalArrayBuffer(args.This(), length);
+}
+
+
+Handle<Object> Shell::CreateExternalArray(Handle<Object> array,
+ Handle<Object> buffer,
+ ExternalArrayType type,
+ int32_t length,
+ int32_t byteLength,
+ int32_t byteOffset,
+ int32_t element_size) {
+ ASSERT(element_size == 1 || element_size == 2 ||
+ element_size == 4 || element_size == 8);
+ ASSERT(byteLength == length * element_size);
+
+ void* data = buffer->GetIndexedPropertiesExternalArrayData();
+ ASSERT(data != NULL);
+
+ array->SetIndexedPropertiesToExternalArrayData(
+ static_cast<uint8_t*>(data) + byteOffset, type, length);
+ array->SetHiddenValue(String::New(kArrayMarkerPropName), Int32::New(type));
+ array->Set(String::New("byteLength"), Int32::New(byteLength), ReadOnly);
+ array->Set(String::New("byteOffset"), Int32::New(byteOffset), ReadOnly);
+ array->Set(String::New("length"), Int32::New(length), ReadOnly);
+ array->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size));
+ array->Set(String::New("buffer"), buffer, ReadOnly);
+
+ return array;
}
Handle<Value> Shell::CreateExternalArray(const Arguments& args,
ExternalArrayType type,
int32_t element_size) {
+ if (!args.IsConstructCall()) {
+ Handle<Value>* rec_args = new Handle<Value>[args.Length()];
+ for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i];
+ Handle<Value> result = args.Callee()->NewInstance(args.Length(), rec_args);
+ delete[] rec_args;
+ return result;
+ }
+
TryCatch try_catch;
ASSERT(element_size == 1 || element_size == 2 ||
element_size == 4 || element_size == 8);
- // Currently, only the following constructors are supported:
+ // All of the following constructors are supported:
// TypedArray(unsigned long length)
+ // TypedArray(type[] array)
+ // TypedArray(TypedArray array)
// TypedArray(ArrayBuffer buffer,
// optional unsigned long byteOffset,
// optional unsigned long length)
@@ -375,29 +437,31 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
int32_t length;
int32_t byteLength;
int32_t byteOffset;
+ bool init_from_array = false;
if (args.Length() == 0) {
return ThrowException(
- String::New("Array constructor must have at least one parameter."));
+ String::New("Array constructor must have at least one argument"));
}
if (args[0]->IsObject() &&
- !args[0]->ToObject()->GetHiddenValue(
- String::New(kArrayBufferMarkerPropName)).IsEmpty()) {
+ !args[0]->ToObject()->GetHiddenValue(
+ String::New(kArrayBufferMarkerPropName)).IsEmpty()) {
+ // Construct from ArrayBuffer.
buffer = args[0]->ToObject();
int32_t bufferLength =
convertToUint(buffer->Get(String::New("byteLength")), &try_catch);
- if (try_catch.HasCaught()) return try_catch.Exception();
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
if (args.Length() < 2 || args[1]->IsUndefined()) {
byteOffset = 0;
} else {
byteOffset = convertToUint(args[1], &try_catch);
- if (try_catch.HasCaught()) return try_catch.Exception();
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
if (byteOffset > bufferLength) {
return ThrowException(String::New("byteOffset out of bounds"));
}
if (byteOffset % element_size != 0) {
return ThrowException(
- String::New("byteOffset must be multiple of element_size"));
+ String::New("byteOffset must be multiple of element size"));
}
}
@@ -406,41 +470,312 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
length = byteLength / element_size;
if (byteLength % element_size != 0) {
return ThrowException(
- String::New("buffer size must be multiple of element_size"));
+ String::New("buffer size must be multiple of element size"));
}
} else {
length = convertToUint(args[2], &try_catch);
- if (try_catch.HasCaught()) return try_catch.Exception();
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
byteLength = length * element_size;
if (byteOffset + byteLength > bufferLength) {
return ThrowException(String::New("length out of bounds"));
}
}
} else {
- length = convertToUint(args[0], &try_catch);
+ if (args[0]->IsObject() &&
+ args[0]->ToObject()->Has(String::New("length"))) {
+ // Construct from array.
+ length = convertToUint(
+ args[0]->ToObject()->Get(String::New("length")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ init_from_array = true;
+ } else {
+ // Construct from size.
+ length = convertToUint(args[0], &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ }
byteLength = length * element_size;
byteOffset = 0;
- Handle<Value> result = CreateExternalArrayBuffer(byteLength);
- if (!result->IsObject()) return result;
+
+ Handle<Object> global = Context::GetCurrent()->Global();
+ Handle<Value> array_buffer = global->Get(String::New("ArrayBuffer"));
+ ASSERT(!try_catch.HasCaught() && array_buffer->IsFunction());
+ Handle<Value> buffer_args[] = { Uint32::New(byteLength) };
+ Handle<Value> result = Handle<Function>::Cast(array_buffer)->NewInstance(
+ 1, buffer_args);
+ if (try_catch.HasCaught()) return result;
buffer = result->ToObject();
}
- void* data = buffer->GetIndexedPropertiesExternalArrayData();
- ASSERT(data != NULL);
+ Handle<Object> array = CreateExternalArray(
+ args.This(), buffer, type, length, byteLength, byteOffset, element_size);
- Handle<Object> array = Object::New();
- array->SetIndexedPropertiesToExternalArrayData(
- static_cast<uint8_t*>(data) + byteOffset, type, length);
- array->Set(String::New("byteLength"), Int32::New(byteLength), ReadOnly);
- array->Set(String::New("byteOffset"), Int32::New(byteOffset), ReadOnly);
- array->Set(String::New("length"), Int32::New(length), ReadOnly);
- array->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size));
- array->Set(String::New("buffer"), buffer, ReadOnly);
+ if (init_from_array) {
+ Handle<Object> init = args[0]->ToObject();
+ for (int i = 0; i < length; ++i) array->Set(i, init->Get(i));
+ }
return array;
}
+Handle<Value> Shell::ArrayBufferSlice(const Arguments& args) {
+ TryCatch try_catch;
+
+ if (!args.This()->IsObject()) {
+ return ThrowException(
+ String::New("'slice' invoked on non-object receiver"));
+ }
+
+ Local<Object> self = args.This();
+ Local<Value> marker =
+ self->GetHiddenValue(String::New(kArrayBufferMarkerPropName));
+ if (marker.IsEmpty()) {
+ return ThrowException(
+ String::New("'slice' invoked on wrong receiver type"));
+ }
+
+ int32_t length =
+ convertToUint(self->Get(String::New("byteLength")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+
+ if (args.Length() == 0) {
+ return ThrowException(
+ String::New("'slice' must have at least one argument"));
+ }
+ int32_t begin = convertToInt(args[0], &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ if (begin < 0) begin += length;
+ if (begin < 0) begin = 0;
+ if (begin > length) begin = length;
+
+ int32_t end;
+ if (args.Length() < 2 || args[1]->IsUndefined()) {
+ end = length;
+ } else {
+ end = convertToInt(args[1], &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ if (end < 0) end += length;
+ if (end < 0) end = 0;
+ if (end > length) end = length;
+ if (end < begin) end = begin;
+ }
+
+ Local<Function> constructor = Local<Function>::Cast(self->GetConstructor());
+ Handle<Value> new_args[] = { Uint32::New(end - begin) };
+ Handle<Value> result = constructor->NewInstance(1, new_args);
+ if (try_catch.HasCaught()) return result;
+ Handle<Object> buffer = result->ToObject();
+ uint8_t* dest =
+ static_cast<uint8_t*>(buffer->GetIndexedPropertiesExternalArrayData());
+ uint8_t* src = begin + static_cast<uint8_t*>(
+ self->GetIndexedPropertiesExternalArrayData());
+ memcpy(dest, src, end - begin);
+
+ return buffer;
+}
+
+
+Handle<Value> Shell::ArraySubArray(const Arguments& args) {
+ TryCatch try_catch;
+
+ if (!args.This()->IsObject()) {
+ return ThrowException(
+ String::New("'subarray' invoked on non-object receiver"));
+ }
+
+ Local<Object> self = args.This();
+ Local<Value> marker = self->GetHiddenValue(String::New(kArrayMarkerPropName));
+ if (marker.IsEmpty()) {
+ return ThrowException(
+ String::New("'subarray' invoked on wrong receiver type"));
+ }
+
+ Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject();
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ int32_t length =
+ convertToUint(self->Get(String::New("length")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ int32_t byteOffset =
+ convertToUint(self->Get(String::New("byteOffset")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ int32_t element_size =
+ convertToUint(self->Get(String::New("BYTES_PER_ELEMENT")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+
+ if (args.Length() == 0) {
+ return ThrowException(
+ String::New("'subarray' must have at least one argument"));
+ }
+ int32_t begin = convertToInt(args[0], &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ if (begin < 0) begin += length;
+ if (begin < 0) begin = 0;
+ if (begin > length) begin = length;
+
+ int32_t end;
+ if (args.Length() < 2 || args[1]->IsUndefined()) {
+ end = length;
+ } else {
+ end = convertToInt(args[1], &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ if (end < 0) end += length;
+ if (end < 0) end = 0;
+ if (end > length) end = length;
+ if (end < begin) end = begin;
+ }
+
+ length = end - begin;
+ byteOffset += begin * element_size;
+
+ Local<Function> constructor = Local<Function>::Cast(self->GetConstructor());
+ Handle<Value> construct_args[] = {
+ buffer, Uint32::New(byteOffset), Uint32::New(length)
+ };
+ return constructor->NewInstance(3, construct_args);
+}
+
+
+Handle<Value> Shell::ArraySet(const Arguments& args) {
+ TryCatch try_catch;
+
+ if (!args.This()->IsObject()) {
+ return ThrowException(
+ String::New("'set' invoked on non-object receiver"));
+ }
+
+ Local<Object> self = args.This();
+ Local<Value> marker = self->GetHiddenValue(String::New(kArrayMarkerPropName));
+ if (marker.IsEmpty()) {
+ return ThrowException(
+ String::New("'set' invoked on wrong receiver type"));
+ }
+ int32_t length =
+ convertToUint(self->Get(String::New("length")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ int32_t element_size =
+ convertToUint(self->Get(String::New("BYTES_PER_ELEMENT")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+
+ if (args.Length() == 0) {
+ return ThrowException(
+ String::New("'set' must have at least one argument"));
+ }
+ if (!args[0]->IsObject() ||
+ !args[0]->ToObject()->Has(String::New("length"))) {
+ return ThrowException(
+ String::New("'set' invoked with non-array argument"));
+ }
+ Handle<Object> source = args[0]->ToObject();
+ int32_t source_length =
+ convertToUint(source->Get(String::New("length")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+
+ int32_t offset;
+ if (args.Length() < 2 || args[1]->IsUndefined()) {
+ offset = 0;
+ } else {
+ offset = convertToUint(args[1], &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ }
+ if (offset + source_length > length) {
+ return ThrowException(String::New("offset or source length out of bounds"));
+ }
+
+ int32_t source_element_size;
+ if (source->GetHiddenValue(String::New(kArrayMarkerPropName)).IsEmpty()) {
+ source_element_size = 0;
+ } else {
+ source_element_size =
+ convertToUint(source->Get(String::New("BYTES_PER_ELEMENT")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ }
+
+ if (element_size == source_element_size &&
+ self->GetConstructor()->StrictEquals(source->GetConstructor())) {
+ // Use memmove on the array buffers.
+ Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject();
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ Handle<Object> source_buffer =
+ source->Get(String::New("buffer"))->ToObject();
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ int32_t byteOffset =
+ convertToUint(self->Get(String::New("byteOffset")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ int32_t source_byteOffset =
+ convertToUint(source->Get(String::New("byteOffset")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+
+ uint8_t* dest = byteOffset + offset * element_size + static_cast<uint8_t*>(
+ buffer->GetIndexedPropertiesExternalArrayData());
+ uint8_t* src = source_byteOffset + static_cast<uint8_t*>(
+ source_buffer->GetIndexedPropertiesExternalArrayData());
+ memmove(dest, src, source_length * element_size);
+ } else if (source_element_size == 0) {
+ // Source is not a typed array, copy element-wise sequentially.
+ for (int i = 0; i < source_length; ++i) {
+ self->Set(offset + i, source->Get(i));
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ }
+ } else {
+ // Need to copy element-wise to make the right conversions.
+ Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject();
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ Handle<Object> source_buffer =
+ source->Get(String::New("buffer"))->ToObject();
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+
+ if (buffer->StrictEquals(source_buffer)) {
+ // Same backing store, need to handle overlap correctly.
+ // This gets a bit tricky in the case of different element sizes
+ // (which, of course, is extremely unlikely to ever occur in practice).
+ int32_t byteOffset =
+ convertToUint(self->Get(String::New("byteOffset")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+ int32_t source_byteOffset =
+ convertToUint(source->Get(String::New("byteOffset")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.ReThrow();
+
+ // Copy as much as we can from left to right.
+ int i = 0;
+ int32_t next_dest_offset = byteOffset + (offset + 1) * element_size;
+ int32_t next_src_offset = source_byteOffset + source_element_size;
+ while (i < length && next_dest_offset <= next_src_offset) {
+ self->Set(offset + i, source->Get(i));
+ ++i;
+ next_dest_offset += element_size;
+ next_src_offset += source_element_size;
+ }
+ // Of what's left, copy as much as we can from right to left.
+ int j = length - 1;
+ int32_t dest_offset = byteOffset + (offset + j) * element_size;
+ int32_t src_offset = source_byteOffset + j * source_element_size;
+ while (j >= i && dest_offset >= src_offset) {
+ self->Set(offset + j, source->Get(j));
+ --j;
+ dest_offset -= element_size;
+ src_offset -= source_element_size;
+ }
+ // There can be at most 8 entries left in the middle that need buffering
+ // (because the largest element_size is 8 times the smallest).
+ ASSERT(j+1 - i <= 8);
+ Handle<Value> temp[8];
+ for (int k = i; k <= j; ++k) {
+ temp[k - i] = source->Get(k);
+ }
+ for (int k = i; k <= j; ++k) {
+ self->Set(offset + k, temp[k - i]);
+ }
+ } else {
+ // Different backing stores, safe to copy element-wise sequentially.
+ for (int i = 0; i < source_length; ++i)
+ self->Set(offset + i, source->Get(i));
+ }
+ }
+
+ return Undefined();
+}
+
+
void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
HandleScope scope;
int32_t length =
@@ -451,11 +786,6 @@ void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
}
-Handle<Value> Shell::ArrayBuffer(const Arguments& args) {
- return CreateExternalArrayBuffer(args);
-}
-
-
Handle<Value> Shell::Int8Array(const Arguments& args) {
return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
}
@@ -472,8 +802,8 @@ Handle<Value> Shell::Int16Array(const Arguments& args) {
Handle<Value> Shell::Uint16Array(const Arguments& args) {
- return CreateExternalArray(args, kExternalUnsignedShortArray,
- sizeof(uint16_t));
+ return CreateExternalArray(
+ args, kExternalUnsignedShortArray, sizeof(uint16_t));
}
@@ -488,18 +818,18 @@ Handle<Value> Shell::Uint32Array(const Arguments& args) {
Handle<Value> Shell::Float32Array(const Arguments& args) {
- return CreateExternalArray(args, kExternalFloatArray,
- sizeof(float)); // NOLINT
+ return CreateExternalArray(
+ args, kExternalFloatArray, sizeof(float)); // NOLINT
}
Handle<Value> Shell::Float64Array(const Arguments& args) {
- return CreateExternalArray(args, kExternalDoubleArray,
- sizeof(double)); // NOLINT
+ return CreateExternalArray(
+ args, kExternalDoubleArray, sizeof(double)); // NOLINT
}
-Handle<Value> Shell::PixelArray(const Arguments& args) {
+Handle<Value> Shell::Uint8ClampedArray(const Arguments& args) {
return CreateExternalArray(args, kExternalPixelArray, sizeof(uint8_t));
}
@@ -729,7 +1059,7 @@ void Shell::InstallUtilityScript() {
i::Debug* debug = i::Isolate::Current()->debug();
debug->Load();
i::Handle<i::JSObject> js_debug
- = i::Handle<i::JSObject>(debug->debug_context()->global());
+ = i::Handle<i::JSObject>(debug->debug_context()->global_object());
utility_context_->Global()->Set(String::New("$debug"),
Utils::ToLocal(js_debug));
debug->debug_context()->set_security_token(HEAP->undefined_value());
@@ -794,6 +1124,27 @@ class BZip2Decompressor : public v8::StartupDataDecompressor {
};
#endif
+
+Handle<FunctionTemplate> Shell::CreateArrayBufferTemplate(
+ InvocationCallback fun) {
+ Handle<FunctionTemplate> buffer_template = FunctionTemplate::New(fun);
+ Local<Template> proto_template = buffer_template->PrototypeTemplate();
+ proto_template->Set(String::New("slice"),
+ FunctionTemplate::New(ArrayBufferSlice));
+ return buffer_template;
+}
+
+
+Handle<FunctionTemplate> Shell::CreateArrayTemplate(InvocationCallback fun) {
+ Handle<FunctionTemplate> array_template = FunctionTemplate::New(fun);
+ Local<Template> proto_template = array_template->PrototypeTemplate();
+ proto_template->Set(String::New("set"), FunctionTemplate::New(ArraySet));
+ proto_template->Set(String::New("subarray"),
+ FunctionTemplate::New(ArraySubArray));
+ return array_template;
+}
+
+
Handle<ObjectTemplate> Shell::CreateGlobalTemplate() {
Handle<ObjectTemplate> global_template = ObjectTemplate::New();
global_template->Set(String::New("print"), FunctionTemplate::New(Print));
@@ -812,26 +1163,28 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate() {
FunctionTemplate::New(DisableProfiler));
// Bind the handlers for external arrays.
+ PropertyAttribute attr =
+ static_cast<PropertyAttribute>(ReadOnly | DontDelete);
global_template->Set(String::New("ArrayBuffer"),
- FunctionTemplate::New(ArrayBuffer));
+ CreateArrayBufferTemplate(ArrayBuffer), attr);
global_template->Set(String::New("Int8Array"),
- FunctionTemplate::New(Int8Array));
+ CreateArrayTemplate(Int8Array), attr);
global_template->Set(String::New("Uint8Array"),
- FunctionTemplate::New(Uint8Array));
+ CreateArrayTemplate(Uint8Array), attr);
global_template->Set(String::New("Int16Array"),
- FunctionTemplate::New(Int16Array));
+ CreateArrayTemplate(Int16Array), attr);
global_template->Set(String::New("Uint16Array"),
- FunctionTemplate::New(Uint16Array));
+ CreateArrayTemplate(Uint16Array), attr);
global_template->Set(String::New("Int32Array"),
- FunctionTemplate::New(Int32Array));
+ CreateArrayTemplate(Int32Array), attr);
global_template->Set(String::New("Uint32Array"),
- FunctionTemplate::New(Uint32Array));
+ CreateArrayTemplate(Uint32Array), attr);
global_template->Set(String::New("Float32Array"),
- FunctionTemplate::New(Float32Array));
+ CreateArrayTemplate(Float32Array), attr);
global_template->Set(String::New("Float64Array"),
- FunctionTemplate::New(Float64Array));
- global_template->Set(String::New("PixelArray"),
- FunctionTemplate::New(PixelArray));
+ CreateArrayTemplate(Float64Array), attr);
+ global_template->Set(String::New("Uint8ClampedArray"),
+ CreateArrayTemplate(Uint8ClampedArray), attr);
#ifdef LIVE_OBJECT_LIST
global_template->Set(String::New("lol_is_enabled"), True());
@@ -864,7 +1217,7 @@ void Shell::Initialize() {
// Set up counters
if (i::StrLength(i::FLAG_map_counters) != 0)
MapCounters(i::FLAG_map_counters);
- if (i::FLAG_dump_counters) {
+ if (i::FLAG_dump_counters || i::FLAG_track_gc_object_stats) {
V8::SetCounterFunction(LookupCounter);
V8::SetCreateHistogramFunction(CreateHistogram);
V8::SetAddHistogramSampleFunction(AddHistogramSample);
@@ -954,20 +1307,24 @@ void Shell::OnExit() {
counters[j].key = i.CurrentKey();
}
qsort(counters, number_of_counters, sizeof(counters[0]), CompareKeys);
- printf("+--------------------------------------------+-------------+\n");
- printf("| Name | Value |\n");
- printf("+--------------------------------------------+-------------+\n");
+ printf("+----------------------------------------------------------------+"
+ "-------------+\n");
+ printf("| Name |"
+ " Value |\n");
+ printf("+----------------------------------------------------------------+"
+ "-------------+\n");
for (j = 0; j < number_of_counters; j++) {
Counter* counter = counters[j].counter;
const char* key = counters[j].key;
if (counter->is_histogram()) {
- printf("| c:%-40s | %11i |\n", key, counter->count());
- printf("| t:%-40s | %11i |\n", key, counter->sample_total());
+ printf("| c:%-60s | %11i |\n", key, counter->count());
+ printf("| t:%-60s | %11i |\n", key, counter->sample_total());
} else {
- printf("| %-42s | %11i |\n", key, counter->count());
+ printf("| %-62s | %11i |\n", key, counter->count());
}
}
- printf("+--------------------------------------------+-------------+\n");
+ printf("+----------------------------------------------------------------+"
+ "-------------+\n");
delete [] counters;
}
delete counters_file_;
@@ -1238,6 +1595,11 @@ void SourceGroup::ExecuteInThread() {
Execute();
}
context.Dispose();
+ if (Shell::options.send_idle_notification) {
+ const int kLongIdlePauseInMs = 1000;
+ V8::ContextDisposedNotification();
+ V8::IdleNotification(kLongIdlePauseInMs);
+ }
}
if (done_semaphore_ != NULL) done_semaphore_->Signal();
} while (!Shell::options.last_run);
@@ -1283,6 +1645,9 @@ bool Shell::SetOptions(int argc, char* argv[]) {
} else if (strcmp(argv[i], "--test") == 0) {
options.test_shell = true;
argv[i] = NULL;
+ } else if (strcmp(argv[i], "--send-idle-notification") == 0) {
+ options.send_idle_notification = true;
+ argv[i] = NULL;
} else if (strcmp(argv[i], "--preemption") == 0) {
#ifdef V8_SHARED
printf("D8 with shared library does not support multi-threading\n");
@@ -1439,13 +1804,11 @@ int Shell::RunMain(int argc, char* argv[]) {
}
if (!options.last_run) {
context.Dispose();
-#if !defined(V8_SHARED)
- if (i::FLAG_send_idle_notification) {
+ if (options.send_idle_notification) {
const int kLongIdlePauseInMs = 1000;
V8::ContextDisposedNotification();
V8::IdleNotification(kLongIdlePauseInMs);
}
-#endif // !V8_SHARED
}
#ifndef V8_SHARED
diff --git a/deps/v8/src/d8.h b/deps/v8/src/d8.h
index 2789c6db3..a62a81fd9 100644
--- a/deps/v8/src/d8.h
+++ b/deps/v8/src/d8.h
@@ -31,7 +31,7 @@
#ifndef V8_SHARED
#include "allocation.h"
#include "hashmap.h"
-#include "smart-array-pointer.h"
+#include "smart-pointers.h"
#include "v8.h"
#else
#include "../include/v8.h"
@@ -67,7 +67,7 @@ class CounterCollection {
CounterCollection();
Counter* GetNextCounter();
private:
- static const unsigned kMaxCounters = 256;
+ static const unsigned kMaxCounters = 512;
uint32_t magic_number_;
uint32_t max_counters_;
uint32_t max_name_size_;
@@ -227,6 +227,7 @@ class ShellOptions {
#endif // V8_SHARED
script_executed(false),
last_run(true),
+ send_idle_notification(false),
stress_opt(false),
stress_deopt(false),
interactive_shell(false),
@@ -249,6 +250,7 @@ class ShellOptions {
#endif // V8_SHARED
bool script_executed;
bool last_run;
+ bool send_idle_notification;
bool stress_opt;
bool stress_deopt;
bool interactive_shell;
@@ -322,7 +324,10 @@ class Shell : public i::AllStatic {
static Handle<Value> Uint32Array(const Arguments& args);
static Handle<Value> Float32Array(const Arguments& args);
static Handle<Value> Float64Array(const Arguments& args);
- static Handle<Value> PixelArray(const Arguments& args);
+ static Handle<Value> Uint8ClampedArray(const Arguments& args);
+ static Handle<Value> ArrayBufferSlice(const Arguments& args);
+ static Handle<Value> ArraySubArray(const Arguments& args);
+ static Handle<Value> ArraySet(const Arguments& args);
// The OS object on the global object contains methods for performing
// operating system calls:
//
@@ -383,8 +388,17 @@ class Shell : public i::AllStatic {
static void RunShell();
static bool SetOptions(int argc, char* argv[]);
static Handle<ObjectTemplate> CreateGlobalTemplate();
- static Handle<Value> CreateExternalArrayBuffer(int32_t size);
- static Handle<Value> CreateExternalArrayBuffer(const Arguments& args);
+ static Handle<FunctionTemplate> CreateArrayBufferTemplate(InvocationCallback);
+ static Handle<FunctionTemplate> CreateArrayTemplate(InvocationCallback);
+ static Handle<Value> CreateExternalArrayBuffer(Handle<Object> buffer,
+ int32_t size);
+ static Handle<Object> CreateExternalArray(Handle<Object> array,
+ Handle<Object> buffer,
+ ExternalArrayType type,
+ int32_t length,
+ int32_t byteLength,
+ int32_t byteOffset,
+ int32_t element_size);
static Handle<Value> CreateExternalArray(const Arguments& args,
ExternalArrayType type,
int32_t element_size);
diff --git a/deps/v8/src/date.js b/deps/v8/src/date.js
index d0e24abc5..a54cb238c 100644
--- a/deps/v8/src/date.js
+++ b/deps/v8/src/date.js
@@ -318,7 +318,6 @@ function DateNow() {
// ECMA 262 - 15.9.5.2
function DateToString() {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this)
if (NUMBER_IS_NAN(t)) return kInvalidDate;
var time_zone_string = LocalTimezoneString(this)
@@ -328,7 +327,6 @@ function DateToString() {
// ECMA 262 - 15.9.5.3
function DateToDateString() {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
if (NUMBER_IS_NAN(t)) return kInvalidDate;
return DateString(this);
@@ -337,7 +335,6 @@ function DateToDateString() {
// ECMA 262 - 15.9.5.4
function DateToTimeString() {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
if (NUMBER_IS_NAN(t)) return kInvalidDate;
var time_zone_string = LocalTimezoneString(this);
@@ -353,7 +350,6 @@ function DateToLocaleString() {
// ECMA 262 - 15.9.5.6
function DateToLocaleDateString() {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
if (NUMBER_IS_NAN(t)) return kInvalidDate;
return LongDateString(this);
@@ -362,7 +358,6 @@ function DateToLocaleDateString() {
// ECMA 262 - 15.9.5.7
function DateToLocaleTimeString() {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
if (NUMBER_IS_NAN(t)) return kInvalidDate;
return TimeString(this);
@@ -371,133 +366,114 @@ function DateToLocaleTimeString() {
// ECMA 262 - 15.9.5.8
function DateValueOf() {
- CHECK_DATE(this);
return UTC_DATE_VALUE(this);
}
// ECMA 262 - 15.9.5.9
function DateGetTime() {
- CHECK_DATE(this);
return UTC_DATE_VALUE(this);
}
// ECMA 262 - 15.9.5.10
function DateGetFullYear() {
- CHECK_DATE(this);
return LOCAL_YEAR(this);
}
// ECMA 262 - 15.9.5.11
function DateGetUTCFullYear() {
- CHECK_DATE(this);
return UTC_YEAR(this);
}
// ECMA 262 - 15.9.5.12
function DateGetMonth() {
- CHECK_DATE(this);
return LOCAL_MONTH(this);
}
// ECMA 262 - 15.9.5.13
function DateGetUTCMonth() {
- CHECK_DATE(this);
return UTC_MONTH(this);
}
// ECMA 262 - 15.9.5.14
function DateGetDate() {
- CHECK_DATE(this);
return LOCAL_DAY(this);
}
// ECMA 262 - 15.9.5.15
function DateGetUTCDate() {
- CHECK_DATE(this);
return UTC_DAY(this);
}
// ECMA 262 - 15.9.5.16
function DateGetDay() {
- CHECK_DATE(this);
return LOCAL_WEEKDAY(this);
}
// ECMA 262 - 15.9.5.17
function DateGetUTCDay() {
- CHECK_DATE(this);
return UTC_WEEKDAY(this);
}
// ECMA 262 - 15.9.5.18
function DateGetHours() {
- CHECK_DATE(this);
return LOCAL_HOUR(this);
}
// ECMA 262 - 15.9.5.19
function DateGetUTCHours() {
- CHECK_DATE(this);
return UTC_HOUR(this);
}
// ECMA 262 - 15.9.5.20
function DateGetMinutes() {
- CHECK_DATE(this);
return LOCAL_MIN(this);
}
// ECMA 262 - 15.9.5.21
function DateGetUTCMinutes() {
- CHECK_DATE(this);
return UTC_MIN(this);
}
// ECMA 262 - 15.9.5.22
function DateGetSeconds() {
- CHECK_DATE(this);
return LOCAL_SEC(this);
}
// ECMA 262 - 15.9.5.23
function DateGetUTCSeconds() {
- CHECK_DATE(this);
return UTC_SEC(this)
}
// ECMA 262 - 15.9.5.24
function DateGetMilliseconds() {
- CHECK_DATE(this);
return LOCAL_MS(this);
}
// ECMA 262 - 15.9.5.25
function DateGetUTCMilliseconds() {
- CHECK_DATE(this);
return UTC_MS(this);
}
// ECMA 262 - 15.9.5.26
function DateGetTimezoneOffset() {
- CHECK_DATE(this);
return TIMEZONE_OFFSET(this);
}
@@ -512,7 +488,6 @@ function DateSetTime(ms) {
// ECMA 262 - 15.9.5.28
function DateSetMilliseconds(ms) {
- CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
ms = ToNumber(ms);
var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), LOCAL_SEC(this), ms);
@@ -522,7 +497,6 @@ function DateSetMilliseconds(ms) {
// ECMA 262 - 15.9.5.29
function DateSetUTCMilliseconds(ms) {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
ms = ToNumber(ms);
var time = MakeTime(UTC_HOUR(this),
@@ -535,7 +509,6 @@ function DateSetUTCMilliseconds(ms) {
// ECMA 262 - 15.9.5.30
function DateSetSeconds(sec, ms) {
- CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
sec = ToNumber(sec);
ms = %_ArgumentsLength() < 2 ? LOCAL_MS(this) : ToNumber(ms);
@@ -546,7 +519,6 @@ function DateSetSeconds(sec, ms) {
// ECMA 262 - 15.9.5.31
function DateSetUTCSeconds(sec, ms) {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
sec = ToNumber(sec);
ms = %_ArgumentsLength() < 2 ? UTC_MS(this) : ToNumber(ms);
@@ -557,7 +529,6 @@ function DateSetUTCSeconds(sec, ms) {
// ECMA 262 - 15.9.5.33
function DateSetMinutes(min, sec, ms) {
- CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
min = ToNumber(min);
var argc = %_ArgumentsLength();
@@ -570,7 +541,6 @@ function DateSetMinutes(min, sec, ms) {
// ECMA 262 - 15.9.5.34
function DateSetUTCMinutes(min, sec, ms) {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
min = ToNumber(min);
var argc = %_ArgumentsLength();
@@ -583,7 +553,6 @@ function DateSetUTCMinutes(min, sec, ms) {
// ECMA 262 - 15.9.5.35
function DateSetHours(hour, min, sec, ms) {
- CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
hour = ToNumber(hour);
var argc = %_ArgumentsLength();
@@ -597,7 +566,6 @@ function DateSetHours(hour, min, sec, ms) {
// ECMA 262 - 15.9.5.34
function DateSetUTCHours(hour, min, sec, ms) {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
hour = ToNumber(hour);
var argc = %_ArgumentsLength();
@@ -611,7 +579,6 @@ function DateSetUTCHours(hour, min, sec, ms) {
// ECMA 262 - 15.9.5.36
function DateSetDate(date) {
- CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
date = ToNumber(date);
var day = MakeDay(LOCAL_YEAR(this), LOCAL_MONTH(this), date);
@@ -621,7 +588,6 @@ function DateSetDate(date) {
// ECMA 262 - 15.9.5.37
function DateSetUTCDate(date) {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
date = ToNumber(date);
var day = MakeDay(UTC_YEAR(this), UTC_MONTH(this), date);
@@ -631,7 +597,6 @@ function DateSetUTCDate(date) {
// ECMA 262 - 15.9.5.38
function DateSetMonth(month, date) {
- CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
month = ToNumber(month);
date = %_ArgumentsLength() < 2 ? LOCAL_DAY(this) : ToNumber(date);
@@ -642,7 +607,6 @@ function DateSetMonth(month, date) {
// ECMA 262 - 15.9.5.39
function DateSetUTCMonth(month, date) {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
month = ToNumber(month);
date = %_ArgumentsLength() < 2 ? UTC_DAY(this) : ToNumber(date);
@@ -653,7 +617,6 @@ function DateSetUTCMonth(month, date) {
// ECMA 262 - 15.9.5.40
function DateSetFullYear(year, month, date) {
- CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
year = ToNumber(year);
var argc = %_ArgumentsLength();
@@ -674,7 +637,6 @@ function DateSetFullYear(year, month, date) {
// ECMA 262 - 15.9.5.41
function DateSetUTCFullYear(year, month, date) {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
year = ToNumber(year);
var argc = %_ArgumentsLength();
@@ -695,7 +657,6 @@ function DateSetUTCFullYear(year, month, date) {
// ECMA 262 - 15.9.5.42
function DateToUTCString() {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
if (NUMBER_IS_NAN(t)) return kInvalidDate;
// Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT
@@ -709,7 +670,6 @@ function DateToUTCString() {
// ECMA 262 - B.2.4
function DateGetYear() {
- CHECK_DATE(this);
return LOCAL_YEAR(this) - 1900;
}
@@ -757,7 +717,6 @@ function PadInt(n, digits) {
// ECMA 262 - 15.9.5.43
function DateToISOString() {
- CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
if (NUMBER_IS_NAN(t)) throw MakeRangeError("invalid_time_value", []);
var year = this.getUTCFullYear();
diff --git a/deps/v8/src/dateparser-inl.h b/deps/v8/src/dateparser-inl.h
index a5c7143bd..3cb36fa43 100644
--- a/deps/v8/src/dateparser-inl.h
+++ b/deps/v8/src/dateparser-inl.h
@@ -62,7 +62,8 @@ bool DateParser::Parse(Vector<Char> str,
// sss is in the range 000..999,
// hh is in the range 00..23,
// mm, ss, and sss default to 00 if missing, and
- // timezone defaults to Z if missing.
+ // timezone defaults to Z if missing
+ // (following Safari, ISO actually demands local time).
// Extensions:
// We also allow sss to have more or less than three digits (but at
// least one).
diff --git a/deps/v8/src/debug-debugger.js b/deps/v8/src/debug-debugger.js
index 91838e8ad..163a0bd82 100644
--- a/deps/v8/src/debug-debugger.js
+++ b/deps/v8/src/debug-debugger.js
@@ -1449,6 +1449,8 @@ DebugCommandProcessor.prototype.processDebugJSONRequest = function(
this.profileRequest_(request, response);
} else if (request.command == 'changelive') {
this.changeLiveRequest_(request, response);
+ } else if (request.command == 'restartframe') {
+ this.restartFrameRequest_(request, response);
} else if (request.command == 'flags') {
this.debuggerFlagsRequest_(request, response);
} else if (request.command == 'v8flags') {
@@ -2076,7 +2078,7 @@ DebugCommandProcessor.prototype.evaluateRequest_ = function(request, response) {
// Global evaluate.
if (global) {
- // Evaluate in the global context.
+ // Evaluate in the native context.
response.body = this.exec_state_.evaluateGlobal(
expression, Boolean(disable_break), additional_context_object);
return;
@@ -2358,9 +2360,6 @@ DebugCommandProcessor.prototype.profileRequest_ = function(request, response) {
DebugCommandProcessor.prototype.changeLiveRequest_ = function(
request, response) {
- if (!Debug.LiveEdit) {
- return response.failed('LiveEdit feature is not supported');
- }
if (!request.arguments) {
return response.failed('Missing arguments');
}
@@ -2398,6 +2397,37 @@ DebugCommandProcessor.prototype.changeLiveRequest_ = function(
};
+DebugCommandProcessor.prototype.restartFrameRequest_ = function(
+ request, response) {
+ if (!request.arguments) {
+ return response.failed('Missing arguments');
+ }
+ var frame = request.arguments.frame;
+
+ // No frames to evaluate in frame.
+ if (this.exec_state_.frameCount() == 0) {
+ return response.failed('No frames');
+ }
+
+ var frame_mirror;
+ // Check whether a frame was specified.
+ if (!IS_UNDEFINED(frame)) {
+ var frame_number = %ToNumber(frame);
+ if (frame_number < 0 || frame_number >= this.exec_state_.frameCount()) {
+ return response.failed('Invalid frame "' + frame + '"');
+ }
+ // Restart specified frame.
+ frame_mirror = this.exec_state_.frame(frame_number);
+ } else {
+ // Restart selected frame.
+ frame_mirror = this.exec_state_.frame();
+ }
+
+ var result_description = Debug.LiveEdit.RestartFrame(frame_mirror);
+ response.body = {result: result_description};
+};
+
+
DebugCommandProcessor.prototype.debuggerFlagsRequest_ = function(request,
response) {
// Check for legal request.
diff --git a/deps/v8/src/debug.cc b/deps/v8/src/debug.cc
index ed70c6a8d..48c5519f7 100644
--- a/deps/v8/src/debug.cc
+++ b/deps/v8/src/debug.cc
@@ -97,8 +97,8 @@ static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
// Isolate::context() may have been NULL when "script collected" event
// occured.
if (context.is_null()) return v8::Local<v8::Context>();
- Handle<Context> global_context(context->global_context());
- return v8::Utils::ToLocal(global_context);
+ Handle<Context> native_context(context->native_context());
+ return v8::Utils::ToLocal(native_context);
}
@@ -698,7 +698,7 @@ void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) {
// We need to clear all breakpoints associated with the function to restore
// original code and avoid patching the code twice later because
// the function will live in the heap until next gc, and can be found by
- // Runtime::FindSharedFunctionInfoInScript.
+ // Debug::FindSharedFunctionInfoInScript.
BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
it.ClearAllDebugBreak();
debug->RemoveDebugInfo(node->debug_info());
@@ -745,12 +745,15 @@ bool Debug::CompileDebuggerScript(int index) {
isolate->bootstrapper()->NativesSourceLookup(index);
Vector<const char> name = Natives::GetScriptName(index);
Handle<String> script_name = factory->NewStringFromAscii(name);
+ Handle<Context> context = isolate->native_context();
// Compile the script.
Handle<SharedFunctionInfo> function_info;
function_info = Compiler::Compile(source_code,
script_name,
- 0, 0, NULL, NULL,
+ 0, 0,
+ context,
+ NULL, NULL,
Handle<String>::null(),
NATIVES_CODE);
@@ -762,13 +765,12 @@ bool Debug::CompileDebuggerScript(int index) {
}
// Execute the shared function in the debugger context.
- Handle<Context> context = isolate->global_context();
bool caught_exception;
Handle<JSFunction> function =
factory->NewFunctionFromSharedFunctionInfo(function_info, context);
Handle<Object> exception =
- Execution::TryCall(function, Handle<Object>(context->global()),
+ Execution::TryCall(function, Handle<Object>(context->global_object()),
0, NULL, &caught_exception);
// Check for caught exceptions.
@@ -829,7 +831,7 @@ bool Debug::Load() {
// Expose the builtins object in the debugger context.
Handle<String> key = isolate_->factory()->LookupAsciiSymbol("builtins");
- Handle<GlobalObject> global = Handle<GlobalObject>(context->global());
+ Handle<GlobalObject> global = Handle<GlobalObject>(context->global_object());
RETURN_IF_EMPTY_HANDLE_VALUE(
isolate_,
JSReceiver::SetProperty(global, key, Handle<Object>(global->builtins()),
@@ -992,12 +994,11 @@ Object* Debug::Break(Arguments args) {
// Check that we indeed found the frame we are looking for.
CHECK(!it.done() && (it.frame()->fp() == thread_local_.last_fp_));
if (step_count > 1) {
- // Save old count and action to continue stepping after
- // StepOut
+ // Save old count and action to continue stepping after StepOut.
thread_local_.queued_step_count_ = step_count - 1;
}
- // Set up for StepOut to reach target frame
+ // Set up for StepOut to reach target frame.
step_action = StepOut;
step_count = count;
}
@@ -1096,7 +1097,7 @@ bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
factory->LookupAsciiSymbol("IsBreakPointTriggered");
Handle<JSFunction> check_break_point =
Handle<JSFunction>(JSFunction::cast(
- debug_context()->global()->GetPropertyNoExceptionThrown(
+ debug_context()->global_object()->GetPropertyNoExceptionThrown(
*is_break_point_triggered_symbol)));
// Get the break id as an object.
@@ -1136,14 +1137,16 @@ Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) {
}
-void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared,
+void Debug::SetBreakPoint(Handle<JSFunction> function,
Handle<Object> break_point_object,
int* source_position) {
HandleScope scope(isolate_);
PrepareForBreakPoints();
- if (!EnsureDebugInfo(shared)) {
+ // Make sure the function is compiled and has set up the debug info.
+ Handle<SharedFunctionInfo> shared(function->shared());
+ if (!EnsureDebugInfo(shared, function)) {
// Return if retrieving debug info failed.
return;
}
@@ -1164,6 +1167,50 @@ void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared,
}
+bool Debug::SetBreakPointForScript(Handle<Script> script,
+ Handle<Object> break_point_object,
+ int* source_position) {
+ HandleScope scope(isolate_);
+
+ PrepareForBreakPoints();
+
+ // Obtain shared function info for the function.
+ Object* result = FindSharedFunctionInfoInScript(script, *source_position);
+ if (result->IsUndefined()) return false;
+
+ // Make sure the function has set up the debug info.
+ Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result));
+ if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
+ // Return if retrieving debug info failed.
+ return false;
+ }
+
+ // Find position within function. The script position might be before the
+ // source position of the first function.
+ int position;
+ if (shared->start_position() > *source_position) {
+ position = 0;
+ } else {
+ position = *source_position - shared->start_position();
+ }
+
+ Handle<DebugInfo> debug_info = GetDebugInfo(shared);
+ // Source positions starts with zero.
+ ASSERT(position >= 0);
+
+ // Find the break point and change it.
+ BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
+ it.FindBreakLocationFromPosition(position);
+ it.SetBreakPoint(break_point_object);
+
+ *source_position = it.position() + shared->start_position();
+
+ // At least one active break point now.
+ ASSERT(debug_info->GetBreakPointCount() > 0);
+ return true;
+}
+
+
void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
HandleScope scope(isolate_);
@@ -1215,10 +1262,12 @@ void Debug::ClearAllBreakPoints() {
}
-void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
+void Debug::FloodWithOneShot(Handle<JSFunction> function) {
PrepareForBreakPoints();
- // Make sure the function has set up the debug info.
- if (!EnsureDebugInfo(shared)) {
+
+ // Make sure the function is compiled and has set up the debug info.
+ Handle<SharedFunctionInfo> shared(function->shared());
+ if (!EnsureDebugInfo(shared, function)) {
// Return if we failed to retrieve the debug info.
return;
}
@@ -1238,8 +1287,8 @@ void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) {
if (!bindee.is_null() && bindee->IsJSFunction() &&
!JSFunction::cast(*bindee)->IsBuiltin()) {
- Handle<SharedFunctionInfo> shared_info(JSFunction::cast(*bindee)->shared());
- Debug::FloodWithOneShot(shared_info);
+ Handle<JSFunction> bindee_function(JSFunction::cast(*bindee));
+ Debug::FloodWithOneShot(bindee_function);
}
}
@@ -1254,11 +1303,9 @@ void Debug::FloodHandlerWithOneShot() {
for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) {
JavaScriptFrame* frame = it.frame();
if (frame->HasHandler()) {
- Handle<SharedFunctionInfo> shared =
- Handle<SharedFunctionInfo>(
- JSFunction::cast(frame->function())->shared());
// Flood the function with the catch block with break points
- FloodWithOneShot(shared);
+ JSFunction* function = JSFunction::cast(frame->function());
+ FloodWithOneShot(Handle<JSFunction>(function));
return;
}
}
@@ -1325,14 +1372,14 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
frames_it.Advance();
// Fill the function to return to with one-shot break points.
JSFunction* function = JSFunction::cast(frames_it.frame()->function());
- FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
+ FloodWithOneShot(Handle<JSFunction>(function));
return;
}
// Get the debug info (create it if it does not exist).
- Handle<SharedFunctionInfo> shared =
- Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
- if (!EnsureDebugInfo(shared)) {
+ Handle<JSFunction> function(JSFunction::cast(frame->function()));
+ Handle<SharedFunctionInfo> shared(function->shared());
+ if (!EnsureDebugInfo(shared, function)) {
// Return if ensuring debug info failed.
return;
}
@@ -1402,7 +1449,7 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
if (!frames_it.done()) {
// Fill the function to return to with one-shot break points.
JSFunction* function = JSFunction::cast(frames_it.frame()->function());
- FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
+ FloodWithOneShot(Handle<JSFunction>(function));
// Set target frame pointer.
ActivateStepOut(frames_it.frame());
}
@@ -1412,7 +1459,7 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
// Step next or step min.
// Fill the current function with one-shot break points.
- FloodWithOneShot(shared);
+ FloodWithOneShot(function);
// Remember source position and frame to handle step next.
thread_local_.last_statement_position_ =
@@ -1424,9 +1471,7 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
if (is_at_restarted_function) {
Handle<JSFunction> restarted_function(
JSFunction::cast(*thread_local_.restarter_frame_function_pointer_));
- Handle<SharedFunctionInfo> restarted_shared(
- restarted_function->shared());
- FloodWithOneShot(restarted_shared);
+ FloodWithOneShot(restarted_function);
} else if (!call_function_stub.is_null()) {
// If it's CallFunction stub ensure target function is compiled and flood
// it with one shot breakpoints.
@@ -1468,7 +1513,7 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
} else if (!js_function->IsBuiltin()) {
// Don't step into builtins.
// It will also compile target function if it's not compiled yet.
- FloodWithOneShot(Handle<SharedFunctionInfo>(js_function->shared()));
+ FloodWithOneShot(js_function);
}
}
}
@@ -1477,7 +1522,7 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
// a call target as the function called might be a native function for
// which step in will not stop. It also prepares for stepping in
// getters/setters.
- FloodWithOneShot(shared);
+ FloodWithOneShot(function);
if (is_load_or_store) {
// Remember source position and frame to handle step in getter/setter. If
@@ -1677,12 +1722,11 @@ void Debug::HandleStepIn(Handle<JSFunction> function,
// function.
if (!holder.is_null() && holder->IsJSFunction() &&
!JSFunction::cast(*holder)->IsBuiltin()) {
- Handle<SharedFunctionInfo> shared_info(
- JSFunction::cast(*holder)->shared());
- Debug::FloodWithOneShot(shared_info);
+ Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
+ Debug::FloodWithOneShot(js_function);
}
} else {
- Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
+ Debug::FloodWithOneShot(function);
}
}
}
@@ -1762,7 +1806,7 @@ static bool CompileFullCodeForDebugging(Handle<JSFunction> function,
Handle<Code> current_code) {
ASSERT(!current_code->has_debug_break_slots());
- CompilationInfo info(function);
+ CompilationInfoWithZone info(function);
info.MarkCompilingForDebugging(current_code);
ASSERT(!info.shared_info()->is_compiled());
ASSERT(!info.isolate()->has_pending_exception());
@@ -1834,29 +1878,48 @@ static void RedirectActivationsToRecompiledCodeOnThread(
continue;
}
- intptr_t delta = frame->pc() - frame_code->instruction_start();
- int debug_break_slot_count = 0;
- int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT);
+ // Iterate over the RelocInfo in the original code to compute the sum of the
+ // constant pools sizes. (See Assembler::CheckConstPool())
+ // Note that this is only useful for architectures using constant pools.
+ int constpool_mask = RelocInfo::ModeMask(RelocInfo::CONST_POOL);
+ int frame_const_pool_size = 0;
+ for (RelocIterator it(*frame_code, constpool_mask); !it.done(); it.next()) {
+ RelocInfo* info = it.rinfo();
+ if (info->pc() >= frame->pc()) break;
+ frame_const_pool_size += static_cast<int>(info->data());
+ }
+ intptr_t frame_offset =
+ frame->pc() - frame_code->instruction_start() - frame_const_pool_size;
+
+ // Iterate over the RelocInfo for new code to find the number of bytes
+ // generated for debug slots and constant pools.
+ int debug_break_slot_bytes = 0;
+ int new_code_const_pool_size = 0;
+ int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
+ RelocInfo::ModeMask(RelocInfo::CONST_POOL);
for (RelocIterator it(*new_code, mask); !it.done(); it.next()) {
// Check if the pc in the new code with debug break
// slots is before this slot.
RelocInfo* info = it.rinfo();
- int debug_break_slot_bytes =
- debug_break_slot_count * Assembler::kDebugBreakSlotLength;
- intptr_t new_delta =
- info->pc() -
- new_code->instruction_start() -
- debug_break_slot_bytes;
- if (new_delta > delta) {
+ intptr_t new_offset = info->pc() - new_code->instruction_start() -
+ new_code_const_pool_size - debug_break_slot_bytes;
+ if (new_offset >= frame_offset) {
break;
}
- // Passed a debug break slot in the full code with debug
- // break slots.
- debug_break_slot_count++;
+ if (RelocInfo::IsDebugBreakSlot(info->rmode())) {
+ debug_break_slot_bytes += Assembler::kDebugBreakSlotLength;
+ } else {
+ ASSERT(RelocInfo::IsConstPool(info->rmode()));
+ // The size of the constant pool is encoded in the data.
+ new_code_const_pool_size += static_cast<int>(info->data());
+ }
}
- int debug_break_slot_bytes =
- debug_break_slot_count * Assembler::kDebugBreakSlotLength;
+
+ // Compute the equivalent pc in the new code.
+ byte* new_pc = new_code->instruction_start() + frame_offset +
+ debug_break_slot_bytes + new_code_const_pool_size;
+
if (FLAG_trace_deopt) {
PrintF("Replacing code %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
"with %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
@@ -1873,14 +1936,12 @@ static void RedirectActivationsToRecompiledCodeOnThread(
new_code->instruction_size(),
new_code->instruction_size(),
reinterpret_cast<intptr_t>(frame->pc()),
- reinterpret_cast<intptr_t>(new_code->instruction_start()) +
- delta + debug_break_slot_bytes);
+ reinterpret_cast<intptr_t>(new_pc));
}
// Patch the return address to return into the code with
// debug break slots.
- frame->set_pc(
- new_code->instruction_start() + delta + debug_break_slot_bytes);
+ frame->set_pc(new_pc);
}
}
@@ -1922,6 +1983,9 @@ void Debug::PrepareForBreakPoints() {
Handle<Code> lazy_compile =
Handle<Code>(isolate_->builtins()->builtin(Builtins::kLazyCompile));
+ // There will be at least one break point when we are done.
+ has_break_points_ = true;
+
// Keep the list of activated functions in a handlified list as it
// is used both in GC and non-GC code.
List<Handle<JSFunction> > active_functions(100);
@@ -1999,7 +2063,6 @@ void Debug::PrepareForBreakPoints() {
// Try to compile the full code with debug break slots. If it
// fails just keep the current code.
Handle<Code> current_code(function->shared()->code());
- ZoneScope zone_scope(isolate_, DELETE_ON_EXIT);
shared->set_code(*lazy_compile);
bool prev_force_debugger_active =
isolate_->debugger()->force_debugger_active();
@@ -2028,16 +2091,130 @@ void Debug::PrepareForBreakPoints() {
}
+Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
+ int position) {
+ // Iterate the heap looking for SharedFunctionInfo generated from the
+ // script. The inner most SharedFunctionInfo containing the source position
+ // for the requested break point is found.
+ // NOTE: This might require several heap iterations. If the SharedFunctionInfo
+ // which is found is not compiled it is compiled and the heap is iterated
+ // again as the compilation might create inner functions from the newly
+ // compiled function and the actual requested break point might be in one of
+ // these functions.
+ // NOTE: The below fix-point iteration depends on all functions that cannot be
+ // compiled lazily without a context to not be compiled at all. Compilation
+ // will be triggered at points where we do not need a context.
+ bool done = false;
+ // The current candidate for the source position:
+ int target_start_position = RelocInfo::kNoPosition;
+ Handle<JSFunction> target_function;
+ Handle<SharedFunctionInfo> target;
+ while (!done) {
+ { // Extra scope for iterator and no-allocation.
+ isolate_->heap()->EnsureHeapIsIterable();
+ AssertNoAllocation no_alloc_during_heap_iteration;
+ HeapIterator iterator;
+ for (HeapObject* obj = iterator.next();
+ obj != NULL; obj = iterator.next()) {
+ bool found_next_candidate = false;
+ Handle<JSFunction> function;
+ Handle<SharedFunctionInfo> shared;
+ if (obj->IsJSFunction()) {
+ function = Handle<JSFunction>(JSFunction::cast(obj));
+ shared = Handle<SharedFunctionInfo>(function->shared());
+ ASSERT(shared->allows_lazy_compilation() || shared->is_compiled());
+ found_next_candidate = true;
+ } else if (obj->IsSharedFunctionInfo()) {
+ shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj));
+ // Skip functions that we cannot compile lazily without a context,
+ // which is not available here, because there is no closure.
+ found_next_candidate = shared->is_compiled() ||
+ shared->allows_lazy_compilation_without_context();
+ }
+ if (!found_next_candidate) continue;
+ if (shared->script() == *script) {
+ // If the SharedFunctionInfo found has the requested script data and
+ // contains the source position it is a candidate.
+ int start_position = shared->function_token_position();
+ if (start_position == RelocInfo::kNoPosition) {
+ start_position = shared->start_position();
+ }
+ if (start_position <= position &&
+ position <= shared->end_position()) {
+ // If there is no candidate or this function is within the current
+ // candidate this is the new candidate.
+ if (target.is_null()) {
+ target_start_position = start_position;
+ target_function = function;
+ target = shared;
+ } else {
+ if (target_start_position == start_position &&
+ shared->end_position() == target->end_position()) {
+ // If a top-level function contains only one function
+ // declaration the source for the top-level and the function
+ // is the same. In that case prefer the non top-level function.
+ if (!shared->is_toplevel()) {
+ target_start_position = start_position;
+ target_function = function;
+ target = shared;
+ }
+ } else if (target_start_position <= start_position &&
+ shared->end_position() <= target->end_position()) {
+ // This containment check includes equality as a function
+ // inside a top-level function can share either start or end
+ // position with the top-level function.
+ target_start_position = start_position;
+ target_function = function;
+ target = shared;
+ }
+ }
+ }
+ }
+ } // End for loop.
+ } // End no-allocation scope.
+
+ if (target.is_null()) {
+ return isolate_->heap()->undefined_value();
+ }
+
+ // There will be at least one break point when we are done.
+ has_break_points_ = true;
+
+ // If the candidate found is compiled we are done.
+ done = target->is_compiled();
+ if (!done) {
+ // If the candidate is not compiled, compile it to reveal any inner
+ // functions which might contain the requested source position. This
+ // will compile all inner functions that cannot be compiled without a
+ // context, because Compiler::BuildFunctionInfo checks whether the
+ // debugger is active.
+ if (target_function.is_null()) {
+ SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION);
+ } else {
+ JSFunction::CompileLazy(target_function, KEEP_EXCEPTION);
+ }
+ }
+ } // End while loop.
+
+ return *target;
+}
+
+
// Ensures the debug information is present for shared.
-bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {
+bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
+ Handle<JSFunction> function) {
// Return if we already have the debug info for shared.
if (HasDebugInfo(shared)) {
ASSERT(shared->is_compiled());
return true;
}
- // Ensure shared in compiled. Return false if this failed.
- if (!SharedFunctionInfo::EnsureCompiled(shared, CLEAR_EXCEPTION)) {
+ // There will be at least one break point when we are done.
+ has_break_points_ = true;
+
+ // Ensure function is compiled. Return false if this failed.
+ if (!function.is_null() &&
+ !JSFunction::EnsureCompiled(function, CLEAR_EXCEPTION)) {
return false;
}
@@ -2049,9 +2226,6 @@ bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {
node->set_next(debug_info_list_);
debug_info_list_ = node;
- // Now there is at least one break point.
- has_break_points_ = true;
-
return true;
}
@@ -2093,9 +2267,9 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
PrepareForBreakPoints();
// Get the executing function in which the debug break occurred.
- Handle<SharedFunctionInfo> shared =
- Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
- if (!EnsureDebugInfo(shared)) {
+ Handle<JSFunction> function(JSFunction::cast(frame->function()));
+ Handle<SharedFunctionInfo> shared(function->shared());
+ if (!EnsureDebugInfo(shared, function)) {
// Return if we failed to retrieve the debug info.
return;
}
@@ -2111,7 +2285,7 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
// Find the call address in the running code. This address holds the call to
// either a DebugBreakXXX or to the debug break return entry code if the
// break point is still active after processing the break point.
- Address addr = frame->pc() - Assembler::kCallTargetAddressOffset;
+ Address addr = frame->pc() - Assembler::kPatchDebugBreakSlotReturnOffset;
// Check if the location is at JS exit or debug break slot.
bool at_js_return = false;
@@ -2185,9 +2359,9 @@ bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
PrepareForBreakPoints();
// Get the executing function in which the debug break occurred.
- Handle<SharedFunctionInfo> shared =
- Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
- if (!EnsureDebugInfo(shared)) {
+ Handle<JSFunction> function(JSFunction::cast(frame->function()));
+ Handle<SharedFunctionInfo> shared(function->shared());
+ if (!EnsureDebugInfo(shared, function)) {
// Return if we failed to retrieve the debug info.
return false;
}
@@ -2200,7 +2374,7 @@ bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
#endif
// Find the call address in the running code.
- Address addr = frame->pc() - Assembler::kCallTargetAddressOffset;
+ Address addr = frame->pc() - Assembler::kPatchDebugBreakSlotReturnOffset;
// Check if the location is at JS return.
RelocIterator it(debug_info->code());
@@ -2218,7 +2392,9 @@ bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
FrameDropMode mode,
Object** restarter_frame_function_pointer) {
- thread_local_.frame_drop_mode_ = mode;
+ if (mode != CURRENTLY_SET_MODE) {
+ thread_local_.frame_drop_mode_ = mode;
+ }
thread_local_.break_frame_id_ = new_break_frame_id;
thread_local_.restarter_frame_function_pointer_ =
restarter_frame_function_pointer;
@@ -2233,7 +2409,7 @@ const int Debug::FramePaddingLayout::kPaddingValue = kInitialSize + 1;
bool Debug::IsDebugGlobal(GlobalObject* global) {
- return IsLoaded() && global == debug_context()->global();
+ return IsLoaded() && global == debug_context()->global_object();
}
@@ -2245,12 +2421,13 @@ void Debug::ClearMirrorCache() {
// Clear the mirror cache.
Handle<String> function_name =
isolate_->factory()->LookupSymbol(CStrVector("ClearMirrorCache"));
- Handle<Object> fun(Isolate::Current()->global()->GetPropertyNoExceptionThrown(
+ Handle<Object> fun(
+ Isolate::Current()->global_object()->GetPropertyNoExceptionThrown(
*function_name));
ASSERT(fun->IsJSFunction());
bool caught_exception;
Execution::TryCall(Handle<JSFunction>::cast(fun),
- Handle<JSObject>(Debug::debug_context()->global()),
+ Handle<JSObject>(Debug::debug_context()->global_object()),
0, NULL, &caught_exception);
}
@@ -2337,6 +2514,7 @@ Debugger::Debugger(Isolate* isolate)
event_listener_data_(Handle<Object>()),
compiling_natives_(false),
is_loading_debugger_(false),
+ live_edit_enabled_(true),
never_unload_debugger_(false),
force_debugger_active_(false),
message_handler_(NULL),
@@ -2372,7 +2550,8 @@ Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
Handle<String> constructor_str =
isolate_->factory()->LookupSymbol(constructor_name);
Handle<Object> constructor(
- isolate_->global()->GetPropertyNoExceptionThrown(*constructor_str));
+ isolate_->global_object()->GetPropertyNoExceptionThrown(
+ *constructor_str));
ASSERT(constructor->IsJSFunction());
if (!constructor->IsJSFunction()) {
*caught_exception = true;
@@ -2380,7 +2559,7 @@ Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
}
Handle<Object> js_object = Execution::TryCall(
Handle<JSFunction>::cast(constructor),
- Handle<JSObject>(isolate_->debug()->debug_context()->global()),
+ Handle<JSObject>(isolate_->debug()->debug_context()->global_object()),
argc,
argv,
caught_exception);
@@ -2602,7 +2781,7 @@ void Debugger::OnAfterCompile(Handle<Script> script,
Handle<String> update_script_break_points_symbol =
isolate_->factory()->LookupAsciiSymbol("UpdateScriptBreakPoints");
Handle<Object> update_script_break_points =
- Handle<Object>(debug->debug_context()->global()->
+ Handle<Object>(debug->debug_context()->global_object()->
GetPropertyNoExceptionThrown(*update_script_break_points_symbol));
if (!update_script_break_points->IsJSFunction()) {
return;
@@ -2647,6 +2826,7 @@ void Debugger::OnScriptCollected(int id) {
HandleScope scope(isolate_);
// No more to do if not debugging.
+ if (isolate_->debug()->InDebugger()) return;
if (!IsDebuggerActive()) return;
if (!Debugger::EventActive(v8::ScriptCollected)) return;
@@ -2758,7 +2938,7 @@ void Debugger::CallJSEventCallback(v8::DebugEvent event,
event_listener_data_ };
bool caught_exception;
Execution::TryCall(fun,
- isolate_->global(),
+ isolate_->global_object(),
ARRAY_SIZE(argv),
argv,
&caught_exception);
diff --git a/deps/v8/src/debug.h b/deps/v8/src/debug.h
index 2adbd2433..150e29e30 100644
--- a/deps/v8/src/debug.h
+++ b/deps/v8/src/debug.h
@@ -233,12 +233,15 @@ class Debug {
void Iterate(ObjectVisitor* v);
Object* Break(Arguments args);
- void SetBreakPoint(Handle<SharedFunctionInfo> shared,
+ void SetBreakPoint(Handle<JSFunction> function,
Handle<Object> break_point_object,
int* source_position);
+ bool SetBreakPointForScript(Handle<Script> script,
+ Handle<Object> break_point_object,
+ int* source_position);
void ClearBreakPoint(Handle<Object> break_point_object);
void ClearAllBreakPoints();
- void FloodWithOneShot(Handle<SharedFunctionInfo> shared);
+ void FloodWithOneShot(Handle<JSFunction> function);
void FloodBoundFunctionWithOneShot(Handle<JSFunction> function);
void FloodHandlerWithOneShot();
void ChangeBreakOnException(ExceptionBreakType type, bool enable);
@@ -254,8 +257,14 @@ class Debug {
void PrepareForBreakPoints();
- // Returns whether the operation succeeded.
- bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared);
+ // This function is used in FunctionNameUsing* tests.
+ Object* FindSharedFunctionInfoInScript(Handle<Script> script, int position);
+
+ // Returns whether the operation succeeded. Compilation can only be triggered
+ // if a valid closure is passed as the second argument, otherwise the shared
+ // function needs to be compiled already.
+ bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
+ Handle<JSFunction> function);
// Returns true if the current stub call is patched to call the debugger.
static bool IsDebugBreak(Address addr);
@@ -434,7 +443,8 @@ class Debug {
// The top JS frame had been calling some C++ function. The return address
// gets patched automatically.
FRAME_DROPPED_IN_DIRECT_CALL,
- FRAME_DROPPED_IN_RETURN_CALL
+ FRAME_DROPPED_IN_RETURN_CALL,
+ CURRENTLY_SET_MODE
};
void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
@@ -783,7 +793,6 @@ class Debugger {
};
void OnAfterCompile(Handle<Script> script,
AfterCompileFlags after_compile_flags);
- void OnNewFunction(Handle<JSFunction> fun);
void OnScriptCollected(int id);
void ProcessDebugEvent(v8::DebugEvent event,
Handle<JSObject> event_data,
@@ -865,6 +874,8 @@ class Debugger {
bool compiling_natives() const { return compiling_natives_; }
void set_loading_debugger(bool v) { is_loading_debugger_ = v; }
bool is_loading_debugger() const { return is_loading_debugger_; }
+ void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
+ bool live_edit_enabled() const { return live_edit_enabled_; }
void set_force_debugger_active(bool force_debugger_active) {
force_debugger_active_ = force_debugger_active;
}
@@ -893,6 +904,7 @@ class Debugger {
Handle<Object> event_listener_data_;
bool compiling_natives_; // Are we compiling natives?
bool is_loading_debugger_; // Are we loading the debugger?
+ bool live_edit_enabled_; // Enable LiveEdit.
bool never_unload_debugger_; // Can we unload the debugger?
bool force_debugger_active_; // Activate debugger without event listeners.
v8::Debug::MessageHandler2 message_handler_;
diff --git a/deps/v8/src/deoptimizer.cc b/deps/v8/src/deoptimizer.cc
index 3debf55cd..ad893b3b4 100644
--- a/deps/v8/src/deoptimizer.cc
+++ b/deps/v8/src/deoptimizer.cc
@@ -27,6 +27,7 @@
#include "v8.h"
+#include "accessors.h"
#include "codegen.h"
#include "deoptimizer.h"
#include "disasm.h"
@@ -268,20 +269,29 @@ void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) {
void Deoptimizer::VisitAllOptimizedFunctionsForContext(
Context* context, OptimizedFunctionVisitor* visitor) {
+ Isolate* isolate = context->GetIsolate();
+ ZoneScope zone_scope(isolate->runtime_zone(), DELETE_ON_EXIT);
AssertNoAllocation no_allocation;
- ASSERT(context->IsGlobalContext());
+ ASSERT(context->IsNativeContext());
visitor->EnterContext(context);
- // Run through the list of optimized functions and deoptimize them.
+
+ // Create a snapshot of the optimized functions list. This is needed because
+ // visitors might remove more than one link from the list at once.
+ ZoneList<JSFunction*> snapshot(1, isolate->runtime_zone());
Object* element = context->OptimizedFunctionsListHead();
while (!element->IsUndefined()) {
JSFunction* element_function = JSFunction::cast(element);
- // Get the next link before deoptimizing as deoptimizing will clear the
- // next link.
+ snapshot.Add(element_function, isolate->runtime_zone());
element = element_function->next_function_link();
- visitor->VisitFunction(element_function);
}
+
+ // Run through the snapshot of optimized functions and visit them.
+ for (int i = 0; i < snapshot.length(); ++i) {
+ visitor->VisitFunction(snapshot.at(i));
+ }
+
visitor->LeaveContext(context);
}
@@ -294,10 +304,10 @@ void Deoptimizer::VisitAllOptimizedFunctionsForGlobalObject(
Object* proto = object->GetPrototype();
ASSERT(proto->IsJSGlobalObject());
VisitAllOptimizedFunctionsForContext(
- GlobalObject::cast(proto)->global_context(), visitor);
+ GlobalObject::cast(proto)->native_context(), visitor);
} else if (object->IsGlobalObject()) {
VisitAllOptimizedFunctionsForContext(
- GlobalObject::cast(object)->global_context(), visitor);
+ GlobalObject::cast(object)->native_context(), visitor);
}
}
@@ -306,12 +316,12 @@ void Deoptimizer::VisitAllOptimizedFunctions(
OptimizedFunctionVisitor* visitor) {
AssertNoAllocation no_allocation;
- // Run through the list of all global contexts and deoptimize.
- Object* context = Isolate::Current()->heap()->global_contexts_list();
+ // Run through the list of all native contexts and deoptimize.
+ Object* context = Isolate::Current()->heap()->native_contexts_list();
while (!context->IsUndefined()) {
// GC can happen when the context is not fully initialized,
// so the global field of the context can be undefined.
- Object* global = Context::cast(context)->get(Context::GLOBAL_INDEX);
+ Object* global = Context::cast(context)->get(Context::GLOBAL_OBJECT_INDEX);
if (!global->IsUndefined()) {
VisitAllOptimizedFunctionsForGlobalObject(JSObject::cast(global),
visitor);
@@ -359,6 +369,8 @@ Deoptimizer::Deoptimizer(Isolate* isolate,
output_count_(0),
jsframe_count_(0),
output_(NULL),
+ deferred_arguments_objects_values_(0),
+ deferred_arguments_objects_(0),
deferred_heap_numbers_(0) {
if (FLAG_trace_deopt && type != OSR) {
if (type == DEBUGGER) {
@@ -484,19 +496,18 @@ int Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) {
int Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
- unsigned id,
+ BailoutId id,
SharedFunctionInfo* shared) {
// TODO(kasperl): For now, we do a simple linear search for the PC
// offset associated with the given node id. This should probably be
// changed to a binary search.
int length = data->DeoptPoints();
- Smi* smi_id = Smi::FromInt(id);
for (int i = 0; i < length; i++) {
- if (data->AstId(i) == smi_id) {
+ if (data->AstId(i) == id) {
return data->PcAndState(i)->value();
}
}
- PrintF("[couldn't find pc offset for node=%u]\n", id);
+ PrintF("[couldn't find pc offset for node=%d]\n", id.ToInt());
PrintF("[method: %s]\n", *shared->DebugName()->ToCString());
// Print the source code if available.
HeapStringAllocator string_allocator;
@@ -543,7 +554,7 @@ void Deoptimizer::DoComputeOutputFrames() {
// described by the input data.
DeoptimizationInputData* input_data =
DeoptimizationInputData::cast(optimized_code_->deoptimization_data());
- unsigned node_id = input_data->AstId(bailout_id_)->value();
+ BailoutId node_id = input_data->AstId(bailout_id_);
ByteArray* translations = input_data->TranslationByteArray();
unsigned translation_index =
input_data->TranslationIndex(bailout_id_)->value();
@@ -581,7 +592,24 @@ void Deoptimizer::DoComputeOutputFrames() {
case Translation::CONSTRUCT_STUB_FRAME:
DoComputeConstructStubFrame(&iterator, i);
break;
- default:
+ case Translation::GETTER_STUB_FRAME:
+ DoComputeAccessorStubFrame(&iterator, i, false);
+ break;
+ case Translation::SETTER_STUB_FRAME:
+ DoComputeAccessorStubFrame(&iterator, i, true);
+ break;
+ case Translation::BEGIN:
+ case Translation::REGISTER:
+ case Translation::INT32_REGISTER:
+ case Translation::UINT32_REGISTER:
+ case Translation::DOUBLE_REGISTER:
+ case Translation::STACK_SLOT:
+ case Translation::INT32_STACK_SLOT:
+ case Translation::UINT32_STACK_SLOT:
+ case Translation::DOUBLE_STACK_SLOT:
+ case Translation::LITERAL:
+ case Translation::ARGUMENTS_OBJECT:
+ case Translation::DUPLICATE:
UNREACHABLE();
break;
}
@@ -595,9 +623,9 @@ void Deoptimizer::DoComputeOutputFrames() {
PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ",
reinterpret_cast<intptr_t>(function));
function->PrintName();
- PrintF(" => node=%u, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
+ PrintF(" => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
" took %0.3f ms]\n",
- node_id,
+ node_id.ToInt(),
output_[index]->GetPc(),
FullCodeGenerator::State2String(
static_cast<FullCodeGenerator::State>(
@@ -608,8 +636,21 @@ void Deoptimizer::DoComputeOutputFrames() {
}
-void Deoptimizer::MaterializeHeapNumbers() {
+void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
ASSERT_NE(DEBUGGER, bailout_type_);
+
+ // Handlify all argument object values before triggering any allocation.
+ List<Handle<Object> > values(deferred_arguments_objects_values_.length());
+ for (int i = 0; i < deferred_arguments_objects_values_.length(); ++i) {
+ values.Add(Handle<Object>(deferred_arguments_objects_values_[i]));
+ }
+
+ // Play it safe and clear all unhandlified values before we continue.
+ deferred_arguments_objects_values_.Clear();
+
+ // Materialize all heap numbers before looking at arguments because when the
+ // output frames are used to materialize arguments objects later on they need
+ // to already contain valid heap numbers.
for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
Handle<Object> num = isolate_->factory()->NewNumber(d.value());
@@ -619,9 +660,55 @@ void Deoptimizer::MaterializeHeapNumbers() {
d.value(),
d.slot_address());
}
-
Memory::Object_at(d.slot_address()) = *num;
}
+
+ // Materialize arguments objects one frame at a time.
+ for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) {
+ if (frame_index != 0) it->Advance();
+ JavaScriptFrame* frame = it->frame();
+ Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate_);
+ Handle<JSObject> arguments;
+ for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) {
+ if (frame->GetExpression(i) == isolate_->heap()->arguments_marker()) {
+ ArgumentsObjectMaterializationDescriptor descriptor =
+ deferred_arguments_objects_.RemoveLast();
+ const int length = descriptor.arguments_length();
+ if (arguments.is_null()) {
+ if (frame->has_adapted_arguments()) {
+ // Use the arguments adapter frame we just built to materialize the
+ // arguments object. FunctionGetArguments can't throw an exception,
+ // so cast away the doubt with an assert.
+ arguments = Handle<JSObject>(JSObject::cast(
+ Accessors::FunctionGetArguments(*function,
+ NULL)->ToObjectUnchecked()));
+ values.RewindBy(length);
+ } else {
+ // Construct an arguments object and copy the parameters to a newly
+ // allocated arguments object backing store.
+ arguments =
+ isolate_->factory()->NewArgumentsObject(function, length);
+ Handle<FixedArray> array =
+ isolate_->factory()->NewFixedArray(length);
+ ASSERT(array->length() == length);
+ for (int i = length - 1; i >= 0 ; --i) {
+ array->set(i, *values.RemoveLast());
+ }
+ arguments->set_elements(*array);
+ }
+ }
+ frame->SetExpression(i, *arguments);
+ ASSERT_EQ(Memory::Object_at(descriptor.slot_address()), *arguments);
+ if (FLAG_trace_deopt) {
+ PrintF("Materializing %sarguments object for %p: ",
+ frame->has_adapted_arguments() ? "(adapted) " : "",
+ reinterpret_cast<void*>(descriptor.slot_address()));
+ arguments->ShortPrint();
+ PrintF("\n");
+ }
+ }
+ }
+ }
}
@@ -700,6 +787,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
case Translation::JS_FRAME:
case Translation::ARGUMENTS_ADAPTOR_FRAME:
case Translation::CONSTRUCT_STUB_FRAME:
+ case Translation::GETTER_STUB_FRAME:
+ case Translation::SETTER_STUB_FRAME:
case Translation::DUPLICATE:
UNREACHABLE();
return;
@@ -748,6 +837,34 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
return;
}
+ case Translation::UINT32_REGISTER: {
+ int input_reg = iterator->Next();
+ uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg));
+ bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
+ if (FLAG_trace_deopt) {
+ PrintF(
+ " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR
+ " ; uint %s (%s)\n",
+ output_[frame_index]->GetTop() + output_offset,
+ output_offset,
+ value,
+ converter.NameOfCPURegister(input_reg),
+ is_smi ? "smi" : "heap number");
+ }
+ if (is_smi) {
+ intptr_t tagged_value =
+ reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
+ output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
+ } else {
+ // We save the untagged value on the side and store a GC-safe
+ // temporary placeholder in the frame.
+ AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
+ static_cast<double>(static_cast<uint32_t>(value)));
+ output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
+ }
+ return;
+ }
+
case Translation::DOUBLE_REGISTER: {
int input_reg = iterator->Next();
double value = input_->GetDoubleRegister(input_reg);
@@ -813,6 +930,36 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
return;
}
+ case Translation::UINT32_STACK_SLOT: {
+ int input_slot_index = iterator->Next();
+ unsigned input_offset =
+ input_->GetOffsetFromSlotIndex(input_slot_index);
+ uintptr_t value =
+ static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
+ bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": ",
+ output_[frame_index]->GetTop() + output_offset);
+ PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n",
+ output_offset,
+ value,
+ input_offset,
+ is_smi ? "smi" : "heap number");
+ }
+ if (is_smi) {
+ intptr_t tagged_value =
+ reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
+ output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
+ } else {
+ // We save the untagged value on the side and store a GC-safe
+ // temporary placeholder in the frame.
+ AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
+ static_cast<double>(static_cast<uint32_t>(value)));
+ output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
+ }
+ return;
+ }
+
case Translation::DOUBLE_STACK_SLOT: {
int input_slot_index = iterator->Next();
unsigned input_offset =
@@ -847,8 +994,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
}
case Translation::ARGUMENTS_OBJECT: {
- // Use the arguments marker value as a sentinel and fill in the arguments
- // object after the deoptimized frame is built.
+ int args_index = iterator->Next() + 1; // Skip receiver.
+ int args_length = iterator->Next() - 1; // Skip receiver.
if (FLAG_trace_deopt) {
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ",
output_[frame_index]->GetTop() + output_offset,
@@ -856,15 +1003,76 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
isolate_->heap()->arguments_marker()->ShortPrint();
PrintF(" ; arguments object\n");
}
+ // Use the arguments marker value as a sentinel and fill in the arguments
+ // object after the deoptimized frame is built.
intptr_t value = reinterpret_cast<intptr_t>(
isolate_->heap()->arguments_marker());
+ AddArgumentsObject(
+ output_[frame_index]->GetTop() + output_offset, args_length);
output_[frame_index]->SetFrameSlot(output_offset, value);
+ // We save the tagged argument values on the side and materialize the
+ // actual arguments object after the deoptimized frame is built.
+ for (int i = 0; i < args_length; i++) {
+ unsigned input_offset = input_->GetOffsetFromSlotIndex(args_index + i);
+ intptr_t input_value = input_->GetFrameSlot(input_offset);
+ AddArgumentsObjectValue(input_value);
+ }
return;
}
}
}
+static bool ObjectToInt32(Object* obj, int32_t* value) {
+ if (obj->IsSmi()) {
+ *value = Smi::cast(obj)->value();
+ return true;
+ }
+
+ if (obj->IsHeapNumber()) {
+ double num = HeapNumber::cast(obj)->value();
+ if (FastI2D(FastD2I(num)) != num) {
+ if (FLAG_trace_osr) {
+ PrintF("**** %g could not be converted to int32 ****\n",
+ HeapNumber::cast(obj)->value());
+ }
+ return false;
+ }
+
+ *value = FastD2I(num);
+ return true;
+ }
+
+ return false;
+}
+
+
+static bool ObjectToUint32(Object* obj, uint32_t* value) {
+ if (obj->IsSmi()) {
+ if (Smi::cast(obj)->value() < 0) return false;
+
+ *value = static_cast<uint32_t>(Smi::cast(obj)->value());
+ return true;
+ }
+
+ if (obj->IsHeapNumber()) {
+ double num = HeapNumber::cast(obj)->value();
+ if ((num < 0) || (FastUI2D(FastD2UI(num)) != num)) {
+ if (FLAG_trace_osr) {
+ PrintF("**** %g could not be converted to uint32 ****\n",
+ HeapNumber::cast(obj)->value());
+ }
+ return false;
+ }
+
+ *value = FastD2UI(num);
+ return true;
+ }
+
+ return false;
+}
+
+
bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
int* input_offset) {
disasm::NameConverter converter;
@@ -887,6 +1095,8 @@ bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
case Translation::JS_FRAME:
case Translation::ARGUMENTS_ADAPTOR_FRAME:
case Translation::CONSTRUCT_STUB_FRAME:
+ case Translation::GETTER_STUB_FRAME:
+ case Translation::SETTER_STUB_FRAME:
case Translation::DUPLICATE:
UNREACHABLE(); // Malformed input.
return false;
@@ -904,22 +1114,10 @@ bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
}
case Translation::INT32_REGISTER: {
- // Abort OSR if we don't have a number.
- if (!input_object->IsNumber()) return false;
+ int32_t int32_value = 0;
+ if (!ObjectToInt32(input_object, &int32_value)) return false;
int output_reg = iterator->Next();
- int int32_value = input_object->IsSmi()
- ? Smi::cast(input_object)->value()
- : FastD2I(input_object->Number());
- // Abort the translation if the conversion lost information.
- if (!input_object->IsSmi() &&
- FastI2D(int32_value) != input_object->Number()) {
- if (FLAG_trace_osr) {
- PrintF("**** %g could not be converted to int32 ****\n",
- input_object->Number());
- }
- return false;
- }
if (FLAG_trace_osr) {
PrintF(" %s <- %d (int32) ; [sp + %d]\n",
converter.NameOfCPURegister(output_reg),
@@ -930,6 +1128,21 @@ bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
break;
}
+ case Translation::UINT32_REGISTER: {
+ uint32_t uint32_value = 0;
+ if (!ObjectToUint32(input_object, &uint32_value)) return false;
+
+ int output_reg = iterator->Next();
+ if (FLAG_trace_osr) {
+ PrintF(" %s <- %u (uint32) ; [sp + %d]\n",
+ converter.NameOfCPURegister(output_reg),
+ uint32_value,
+ *input_offset);
+ }
+ output->SetRegister(output_reg, static_cast<int32_t>(uint32_value));
+ }
+
+
case Translation::DOUBLE_REGISTER: {
// Abort OSR if we don't have a number.
if (!input_object->IsNumber()) return false;
@@ -963,24 +1176,12 @@ bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
}
case Translation::INT32_STACK_SLOT: {
- // Abort OSR if we don't have a number.
- if (!input_object->IsNumber()) return false;
+ int32_t int32_value = 0;
+ if (!ObjectToInt32(input_object, &int32_value)) return false;
int output_index = iterator->Next();
unsigned output_offset =
output->GetOffsetFromSlotIndex(output_index);
- int int32_value = input_object->IsSmi()
- ? Smi::cast(input_object)->value()
- : DoubleToInt32(input_object->Number());
- // Abort the translation if the conversion lost information.
- if (!input_object->IsSmi() &&
- FastI2D(int32_value) != input_object->Number()) {
- if (FLAG_trace_osr) {
- PrintF("**** %g could not be converted to int32 ****\n",
- input_object->Number());
- }
- return false;
- }
if (FLAG_trace_osr) {
PrintF(" [sp + %d] <- %d (int32) ; [sp + %d]\n",
output_offset,
@@ -991,6 +1192,23 @@ bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
break;
}
+ case Translation::UINT32_STACK_SLOT: {
+ uint32_t uint32_value = 0;
+ if (!ObjectToUint32(input_object, &uint32_value)) return false;
+
+ int output_index = iterator->Next();
+ unsigned output_offset =
+ output->GetOffsetFromSlotIndex(output_index);
+ if (FLAG_trace_osr) {
+ PrintF(" [sp + %d] <- %u (uint32) ; [sp + %d]\n",
+ output_offset,
+ uint32_value,
+ *input_offset);
+ }
+ output->SetFrameSlot(output_offset, static_cast<int32_t>(uint32_value));
+ break;
+ }
+
case Translation::DOUBLE_STACK_SLOT: {
static const int kLowerOffset = 0 * kPointerSize;
static const int kUpperOffset = 1 * kPointerSize;
@@ -1140,8 +1358,19 @@ Object* Deoptimizer::ComputeLiteral(int index) const {
}
-void Deoptimizer::AddDoubleValue(intptr_t slot_address,
- double value) {
+void Deoptimizer::AddArgumentsObject(intptr_t slot_address, int argc) {
+ ArgumentsObjectMaterializationDescriptor object_desc(
+ reinterpret_cast<Address>(slot_address), argc);
+ deferred_arguments_objects_.Add(object_desc);
+}
+
+
+void Deoptimizer::AddArgumentsObjectValue(intptr_t value) {
+ deferred_arguments_objects_values_.Add(reinterpret_cast<Object*>(value));
+}
+
+
+void Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) {
HeapNumberMaterializationDescriptor value_desc(
reinterpret_cast<Address>(slot_address), value);
deferred_heap_numbers_.Add(value_desc);
@@ -1214,6 +1443,54 @@ void Deoptimizer::RemoveDeoptimizingCode(Code* code) {
}
+static Object* CutOutRelatedFunctionsList(Context* context,
+ Code* code,
+ Object* undefined) {
+ Object* result_list_head = undefined;
+ Object* head;
+ Object* current;
+ current = head = context->get(Context::OPTIMIZED_FUNCTIONS_LIST);
+ JSFunction* prev = NULL;
+ while (current != undefined) {
+ JSFunction* func = JSFunction::cast(current);
+ current = func->next_function_link();
+ if (func->code() == code) {
+ func->set_next_function_link(result_list_head);
+ result_list_head = func;
+ if (prev) {
+ prev->set_next_function_link(current);
+ } else {
+ head = current;
+ }
+ } else {
+ prev = func;
+ }
+ }
+ if (head != context->get(Context::OPTIMIZED_FUNCTIONS_LIST)) {
+ context->set(Context::OPTIMIZED_FUNCTIONS_LIST, head);
+ }
+ return result_list_head;
+}
+
+
+void Deoptimizer::ReplaceCodeForRelatedFunctions(JSFunction* function,
+ Code* code) {
+ Context* context = function->context()->native_context();
+
+ SharedFunctionInfo* shared = function->shared();
+
+ Object* undefined = Isolate::Current()->heap()->undefined_value();
+ Object* current = CutOutRelatedFunctionsList(context, code, undefined);
+
+ while (current != undefined) {
+ JSFunction* func = JSFunction::cast(current);
+ current = func->next_function_link();
+ func->set_code(shared->code());
+ func->set_next_function_link(undefined);
+ }
+}
+
+
FrameDescription::FrameDescription(uint32_t frame_size,
JSFunction* function)
: frame_size_(frame_size),
@@ -1342,6 +1619,18 @@ void Translation::BeginConstructStubFrame(int literal_id, unsigned height) {
}
+void Translation::BeginGetterStubFrame(int literal_id) {
+ buffer_->Add(GETTER_STUB_FRAME, zone());
+ buffer_->Add(literal_id, zone());
+}
+
+
+void Translation::BeginSetterStubFrame(int literal_id) {
+ buffer_->Add(SETTER_STUB_FRAME, zone());
+ buffer_->Add(literal_id, zone());
+}
+
+
void Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) {
buffer_->Add(ARGUMENTS_ADAPTOR_FRAME, zone());
buffer_->Add(literal_id, zone());
@@ -1349,9 +1638,11 @@ void Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) {
}
-void Translation::BeginJSFrame(int node_id, int literal_id, unsigned height) {
+void Translation::BeginJSFrame(BailoutId node_id,
+ int literal_id,
+ unsigned height) {
buffer_->Add(JS_FRAME, zone());
- buffer_->Add(node_id, zone());
+ buffer_->Add(node_id.ToInt(), zone());
buffer_->Add(literal_id, zone());
buffer_->Add(height, zone());
}
@@ -1369,6 +1660,12 @@ void Translation::StoreInt32Register(Register reg) {
}
+void Translation::StoreUint32Register(Register reg) {
+ buffer_->Add(UINT32_REGISTER, zone());
+ buffer_->Add(reg.code(), zone());
+}
+
+
void Translation::StoreDoubleRegister(DoubleRegister reg) {
buffer_->Add(DOUBLE_REGISTER, zone());
buffer_->Add(DoubleRegister::ToAllocationIndex(reg), zone());
@@ -1387,6 +1684,12 @@ void Translation::StoreInt32StackSlot(int index) {
}
+void Translation::StoreUint32StackSlot(int index) {
+ buffer_->Add(UINT32_STACK_SLOT, zone());
+ buffer_->Add(index, zone());
+}
+
+
void Translation::StoreDoubleStackSlot(int index) {
buffer_->Add(DOUBLE_STACK_SLOT, zone());
buffer_->Add(index, zone());
@@ -1399,8 +1702,10 @@ void Translation::StoreLiteral(int literal_id) {
}
-void Translation::StoreArgumentsObject() {
+void Translation::StoreArgumentsObject(int args_index, int args_length) {
buffer_->Add(ARGUMENTS_OBJECT, zone());
+ buffer_->Add(args_index, zone());
+ buffer_->Add(args_length, zone());
}
@@ -1411,20 +1716,24 @@ void Translation::MarkDuplicate() {
int Translation::NumberOfOperandsFor(Opcode opcode) {
switch (opcode) {
- case ARGUMENTS_OBJECT:
case DUPLICATE:
return 0;
+ case GETTER_STUB_FRAME:
+ case SETTER_STUB_FRAME:
case REGISTER:
case INT32_REGISTER:
+ case UINT32_REGISTER:
case DOUBLE_REGISTER:
case STACK_SLOT:
case INT32_STACK_SLOT:
+ case UINT32_STACK_SLOT:
case DOUBLE_STACK_SLOT:
case LITERAL:
return 1;
case BEGIN:
case ARGUMENTS_ADAPTOR_FRAME:
case CONSTRUCT_STUB_FRAME:
+ case ARGUMENTS_OBJECT:
return 2;
case JS_FRAME:
return 3;
@@ -1446,16 +1755,24 @@ const char* Translation::StringFor(Opcode opcode) {
return "ARGUMENTS_ADAPTOR_FRAME";
case CONSTRUCT_STUB_FRAME:
return "CONSTRUCT_STUB_FRAME";
+ case GETTER_STUB_FRAME:
+ return "GETTER_STUB_FRAME";
+ case SETTER_STUB_FRAME:
+ return "SETTER_STUB_FRAME";
case REGISTER:
return "REGISTER";
case INT32_REGISTER:
return "INT32_REGISTER";
+ case UINT32_REGISTER:
+ return "UINT32_REGISTER";
case DOUBLE_REGISTER:
return "DOUBLE_REGISTER";
case STACK_SLOT:
return "STACK_SLOT";
case INT32_STACK_SLOT:
return "INT32_STACK_SLOT";
+ case UINT32_STACK_SLOT:
+ return "UINT32_STACK_SLOT";
case DOUBLE_STACK_SLOT:
return "DOUBLE_STACK_SLOT";
case LITERAL:
@@ -1502,6 +1819,8 @@ SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator,
case Translation::JS_FRAME:
case Translation::ARGUMENTS_ADAPTOR_FRAME:
case Translation::CONSTRUCT_STUB_FRAME:
+ case Translation::GETTER_STUB_FRAME:
+ case Translation::SETTER_STUB_FRAME:
// Peeled off before getting here.
break;
@@ -1511,6 +1830,7 @@ SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator,
case Translation::REGISTER:
case Translation::INT32_REGISTER:
+ case Translation::UINT32_REGISTER:
case Translation::DOUBLE_REGISTER:
case Translation::DUPLICATE:
// We are at safepoint which corresponds to call. All registers are
@@ -1530,6 +1850,12 @@ SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator,
return SlotRef(slot_addr, SlotRef::INT32);
}
+ case Translation::UINT32_STACK_SLOT: {
+ int slot_index = iterator->Next();
+ Address slot_addr = SlotAddress(frame, slot_index);
+ return SlotRef(slot_addr, SlotRef::UINT32);
+ }
+
case Translation::DOUBLE_STACK_SLOT: {
int slot_index = iterator->Next();
Address slot_addr = SlotAddress(frame, slot_index);
@@ -1569,7 +1895,7 @@ Vector<SlotRef> SlotRef::ComputeSlotMappingForArguments(
int inlined_jsframe_index,
int formal_parameter_count) {
AssertNoAllocation no_gc;
- int deopt_index = AstNode::kNoNumber;
+ int deopt_index = Safepoint::kNoDeoptimizationIndex;
DeoptimizationInputData* data =
static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index);
TranslationIterator it(data->TranslationByteArray(),
diff --git a/deps/v8/src/deoptimizer.h b/deps/v8/src/deoptimizer.h
index 9e8a5491a..f67f986ba 100644
--- a/deps/v8/src/deoptimizer.h
+++ b/deps/v8/src/deoptimizer.h
@@ -57,18 +57,32 @@ class HeapNumberMaterializationDescriptor BASE_EMBEDDED {
};
+class ArgumentsObjectMaterializationDescriptor BASE_EMBEDDED {
+ public:
+ ArgumentsObjectMaterializationDescriptor(Address slot_address, int argc)
+ : slot_address_(slot_address), arguments_length_(argc) { }
+
+ Address slot_address() const { return slot_address_; }
+ int arguments_length() const { return arguments_length_; }
+
+ private:
+ Address slot_address_;
+ int arguments_length_;
+};
+
+
class OptimizedFunctionVisitor BASE_EMBEDDED {
public:
virtual ~OptimizedFunctionVisitor() {}
// Function which is called before iteration of any optimized functions
- // from given global context.
+ // from given native context.
virtual void EnterContext(Context* context) = 0;
virtual void VisitFunction(JSFunction* function) = 0;
// Function which is called after iteration of all optimized functions
- // from given global context.
+ // from given native context.
virtual void LeaveContext(Context* context) = 0;
};
@@ -152,6 +166,10 @@ class Deoptimizer : public Malloced {
// execution returns.
static void DeoptimizeFunction(JSFunction* function);
+ // Iterate over all the functions which share the same code object
+ // and make them use unoptimized version.
+ static void ReplaceCodeForRelatedFunctions(JSFunction* function, Code* code);
+
// Deoptimize all functions in the heap.
static void DeoptimizeAll();
@@ -196,7 +214,7 @@ class Deoptimizer : public Malloced {
~Deoptimizer();
- void MaterializeHeapNumbers();
+ void MaterializeHeapObjects(JavaScriptFrameIterator* it);
#ifdef ENABLE_DEBUGGER_SUPPORT
void MaterializeHeapNumbersForDebuggerInspectableFrame(
Address parameters_top,
@@ -211,7 +229,7 @@ class Deoptimizer : public Malloced {
static Address GetDeoptimizationEntry(int id, BailoutType type);
static int GetDeoptimizationId(Address addr, BailoutType type);
static int GetOutputInfo(DeoptimizationOutputData* data,
- unsigned node_id,
+ BailoutId node_id,
SharedFunctionInfo* shared);
// Code generation support.
@@ -284,6 +302,9 @@ class Deoptimizer : public Malloced {
int frame_index);
void DoComputeConstructStubFrame(TranslationIterator* iterator,
int frame_index);
+ void DoComputeAccessorStubFrame(TranslationIterator* iterator,
+ int frame_index,
+ bool is_setter_stub_frame);
void DoTranslateCommand(TranslationIterator* iterator,
int frame_index,
unsigned output_offset);
@@ -302,6 +323,8 @@ class Deoptimizer : public Malloced {
Object* ComputeLiteral(int index) const;
+ void AddArgumentsObject(intptr_t slot_address, int argc);
+ void AddArgumentsObjectValue(intptr_t value);
void AddDoubleValue(intptr_t slot_address, double value);
static MemoryChunk* CreateCode(BailoutType type);
@@ -337,6 +360,8 @@ class Deoptimizer : public Malloced {
// Array of output frame descriptions.
FrameDescription** output_;
+ List<Object*> deferred_arguments_objects_values_;
+ List<ArgumentsObjectMaterializationDescriptor> deferred_arguments_objects_;
List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_;
static const int table_entry_size_;
@@ -559,12 +584,16 @@ class Translation BASE_EMBEDDED {
BEGIN,
JS_FRAME,
CONSTRUCT_STUB_FRAME,
+ GETTER_STUB_FRAME,
+ SETTER_STUB_FRAME,
ARGUMENTS_ADAPTOR_FRAME,
REGISTER,
INT32_REGISTER,
+ UINT32_REGISTER,
DOUBLE_REGISTER,
STACK_SLOT,
INT32_STACK_SLOT,
+ UINT32_STACK_SLOT,
DOUBLE_STACK_SLOT,
LITERAL,
ARGUMENTS_OBJECT,
@@ -587,17 +616,21 @@ class Translation BASE_EMBEDDED {
int index() const { return index_; }
// Commands.
- void BeginJSFrame(int node_id, int literal_id, unsigned height);
+ void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height);
void BeginArgumentsAdaptorFrame(int literal_id, unsigned height);
void BeginConstructStubFrame(int literal_id, unsigned height);
+ void BeginGetterStubFrame(int literal_id);
+ void BeginSetterStubFrame(int literal_id);
void StoreRegister(Register reg);
void StoreInt32Register(Register reg);
+ void StoreUint32Register(Register reg);
void StoreDoubleRegister(DoubleRegister reg);
void StoreStackSlot(int index);
void StoreInt32StackSlot(int index);
+ void StoreUint32StackSlot(int index);
void StoreDoubleStackSlot(int index);
void StoreLiteral(int literal_id);
- void StoreArgumentsObject();
+ void StoreArgumentsObject(int args_index, int args_length);
void MarkDuplicate();
Zone* zone() const { return zone_; }
@@ -608,6 +641,9 @@ class Translation BASE_EMBEDDED {
static const char* StringFor(Opcode opcode);
#endif
+ // A literal id which refers to the JSFunction itself.
+ static const int kSelfLiteralId = -239;
+
private:
TranslationBuffer* buffer_;
int index_;
@@ -641,6 +677,7 @@ class SlotRef BASE_EMBEDDED {
UNKNOWN,
TAGGED,
INT32,
+ UINT32,
DOUBLE,
LITERAL
};
@@ -668,6 +705,16 @@ class SlotRef BASE_EMBEDDED {
}
}
+ case UINT32: {
+ uint32_t value = Memory::uint32_at(addr_);
+ if (value <= static_cast<uint32_t>(Smi::kMaxValue)) {
+ return Handle<Object>(Smi::FromInt(static_cast<int>(value)));
+ } else {
+ return Isolate::Current()->factory()->NewNumber(
+ static_cast<double>(value));
+ }
+ }
+
case DOUBLE: {
double value = Memory::double_at(addr_);
return Isolate::Current()->factory()->NewNumber(value);
diff --git a/deps/v8/src/disassembler.cc b/deps/v8/src/disassembler.cc
index e3b40ab93..9f8b9a820 100644
--- a/deps/v8/src/disassembler.cc
+++ b/deps/v8/src/disassembler.cc
@@ -244,8 +244,8 @@ static int DecodeIt(FILE* f,
out.AddFormatted(" %s, %s", Code::Kind2String(kind),
Code::ICState2String(ic_state));
if (ic_state == MONOMORPHIC) {
- PropertyType type = code->type();
- out.AddFormatted(", %s", Code::PropertyType2String(type));
+ Code::StubType type = code->type();
+ out.AddFormatted(", %s", Code::StubType2String(type));
}
if (kind == Code::CALL_IC || kind == Code::KEYED_CALL_IC) {
out.AddFormatted(", argc = %d", code->arguments_count());
diff --git a/deps/v8/src/elements.cc b/deps/v8/src/elements.cc
index f0e1414de..6afbcc0ee 100644
--- a/deps/v8/src/elements.cc
+++ b/deps/v8/src/elements.cc
@@ -800,7 +800,7 @@ class FastElementsAccessor
}
} else {
// Otherwise, fill the unused tail with holes.
- int old_length = FastD2I(array->length()->Number());
+ int old_length = FastD2IChecked(array->length()->Number());
for (int i = length; i < old_length; i++) {
backing_store->set_the_hole(i);
}
@@ -1268,7 +1268,30 @@ class DictionaryElementsAccessor
JSArray* array,
Object* length_object,
uint32_t length) {
- if (length == 0) {
+ Heap* heap = array->GetHeap();
+ int capacity = dict->Capacity();
+ uint32_t new_length = length;
+ uint32_t old_length = static_cast<uint32_t>(array->length()->Number());
+ if (new_length < old_length) {
+ // Find last non-deletable element in range of elements to be
+ // deleted and adjust range accordingly.
+ for (int i = 0; i < capacity; i++) {
+ Object* key = dict->KeyAt(i);
+ if (key->IsNumber()) {
+ uint32_t number = static_cast<uint32_t>(key->Number());
+ if (new_length <= number && number < old_length) {
+ PropertyDetails details = dict->DetailsAt(i);
+ if (details.IsDontDelete()) new_length = number + 1;
+ }
+ }
+ }
+ if (new_length != length) {
+ MaybeObject* maybe_object = heap->NumberFromUint32(new_length);
+ if (!maybe_object->To(&length_object)) return maybe_object;
+ }
+ }
+
+ if (new_length == 0) {
// If the length of a slow array is reset to zero, we clear
// the array and flush backing storage. This has the added
// benefit that the array returns to fast mode.
@@ -1276,45 +1299,22 @@ class DictionaryElementsAccessor
MaybeObject* maybe_obj = array->ResetElements();
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
} else {
- uint32_t new_length = length;
- uint32_t old_length = static_cast<uint32_t>(array->length()->Number());
- if (new_length < old_length) {
- // Find last non-deletable element in range of elements to be
- // deleted and adjust range accordingly.
- Heap* heap = array->GetHeap();
- int capacity = dict->Capacity();
- for (int i = 0; i < capacity; i++) {
- Object* key = dict->KeyAt(i);
- if (key->IsNumber()) {
- uint32_t number = static_cast<uint32_t>(key->Number());
- if (new_length <= number && number < old_length) {
- PropertyDetails details = dict->DetailsAt(i);
- if (details.IsDontDelete()) new_length = number + 1;
- }
- }
- }
- if (new_length != length) {
- MaybeObject* maybe_object = heap->NumberFromUint32(new_length);
- if (!maybe_object->To(&length_object)) return maybe_object;
- }
-
- // Remove elements that should be deleted.
- int removed_entries = 0;
- Object* the_hole_value = heap->the_hole_value();
- for (int i = 0; i < capacity; i++) {
- Object* key = dict->KeyAt(i);
- if (key->IsNumber()) {
- uint32_t number = static_cast<uint32_t>(key->Number());
- if (new_length <= number && number < old_length) {
- dict->SetEntry(i, the_hole_value, the_hole_value);
- removed_entries++;
- }
+ // Remove elements that should be deleted.
+ int removed_entries = 0;
+ Object* the_hole_value = heap->the_hole_value();
+ for (int i = 0; i < capacity; i++) {
+ Object* key = dict->KeyAt(i);
+ if (key->IsNumber()) {
+ uint32_t number = static_cast<uint32_t>(key->Number());
+ if (new_length <= number && number < old_length) {
+ dict->SetEntry(i, the_hole_value, the_hole_value);
+ removed_entries++;
}
}
-
- // Update the number of elements.
- dict->ElementsRemoved(removed_entries);
}
+
+ // Update the number of elements.
+ dict->ElementsRemoved(removed_entries);
}
return length_object;
}
@@ -1336,30 +1336,29 @@ class DictionaryElementsAccessor
int entry = dictionary->FindEntry(key);
if (entry != SeededNumberDictionary::kNotFound) {
Object* result = dictionary->DeleteProperty(entry, mode);
- if (result == heap->true_value()) {
- MaybeObject* maybe_elements = dictionary->Shrink(key);
- FixedArray* new_elements = NULL;
- if (!maybe_elements->To(&new_elements)) {
- return maybe_elements;
- }
- if (is_arguments) {
- FixedArray::cast(obj->elements())->set(1, new_elements);
- } else {
- obj->set_elements(new_elements);
+ if (result == heap->false_value()) {
+ if (mode == JSObject::STRICT_DELETION) {
+ // Deleting a non-configurable property in strict mode.
+ HandleScope scope(isolate);
+ Handle<Object> holder(obj);
+ Handle<Object> name = isolate->factory()->NewNumberFromUint(key);
+ Handle<Object> args[2] = { name, holder };
+ Handle<Object> error =
+ isolate->factory()->NewTypeError("strict_delete_property",
+ HandleVector(args, 2));
+ return isolate->Throw(*error);
}
+ return heap->false_value();
}
- if (mode == JSObject::STRICT_DELETION &&
- result == heap->false_value()) {
- // In strict mode, attempting to delete a non-configurable property
- // throws an exception.
- HandleScope scope(isolate);
- Handle<Object> holder(obj);
- Handle<Object> name = isolate->factory()->NewNumberFromUint(key);
- Handle<Object> args[2] = { name, holder };
- Handle<Object> error =
- isolate->factory()->NewTypeError("strict_delete_property",
- HandleVector(args, 2));
- return isolate->Throw(*error);
+ MaybeObject* maybe_elements = dictionary->Shrink(key);
+ FixedArray* new_elements = NULL;
+ if (!maybe_elements->To(&new_elements)) {
+ return maybe_elements;
+ }
+ if (is_arguments) {
+ FixedArray::cast(obj->elements())->set(1, new_elements);
+ } else {
+ obj->set_elements(new_elements);
}
}
return heap->true_value();
diff --git a/deps/v8/src/execution.cc b/deps/v8/src/execution.cc
index 40ed7de41..89091ba42 100644
--- a/deps/v8/src/execution.cc
+++ b/deps/v8/src/execution.cc
@@ -100,7 +100,7 @@ static Handle<Object> Invoke(bool is_construct,
// Make sure that the global object of the context we're about to
// make the current one is indeed a global object.
- ASSERT(function->context()->global()->IsGlobalObject());
+ ASSERT(function->context()->global_object()->IsGlobalObject());
{
// Save and restore context around invocation and block the
@@ -118,7 +118,7 @@ static Handle<Object> Invoke(bool is_construct,
CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
value->Verify();
#endif
@@ -165,10 +165,10 @@ Handle<Object> Execution::Call(Handle<Object> callable,
if (convert_receiver && !receiver->IsJSReceiver() &&
!func->shared()->native() && func->shared()->is_classic_mode()) {
if (receiver->IsUndefined() || receiver->IsNull()) {
- Object* global = func->context()->global()->global_receiver();
+ Object* global = func->context()->global_object()->global_receiver();
// Under some circumstances, 'global' can be the JSBuiltinsObject
- // In that case, don't rewrite.
- // (FWIW, the same holds for GetIsolate()->global()->global_receiver().)
+ // In that case, don't rewrite. (FWIW, the same holds for
+ // GetIsolate()->global_object()->global_receiver().)
if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global);
} else {
receiver = ToObject(receiver, pending_exception);
@@ -184,7 +184,7 @@ Handle<Object> Execution::New(Handle<JSFunction> func,
int argc,
Handle<Object> argv[],
bool* pending_exception) {
- return Invoke(true, func, Isolate::Current()->global(), argc, argv,
+ return Invoke(true, func, Isolate::Current()->global_object(), argc, argv,
pending_exception);
}
@@ -246,7 +246,7 @@ Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
if (fun->IsHeapObject() &&
HeapObject::cast(fun)->map()->has_instance_call_handler()) {
return Handle<JSFunction>(
- isolate->global_context()->call_as_function_delegate());
+ isolate->native_context()->call_as_function_delegate());
}
return factory->undefined_value();
@@ -270,7 +270,7 @@ Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object,
if (fun->IsHeapObject() &&
HeapObject::cast(fun)->map()->has_instance_call_handler()) {
return Handle<JSFunction>(
- isolate->global_context()->call_as_function_delegate());
+ isolate->native_context()->call_as_function_delegate());
}
// If the Object doesn't have an instance-call handler we should
@@ -303,7 +303,7 @@ Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
if (fun->IsHeapObject() &&
HeapObject::cast(fun)->map()->has_instance_call_handler()) {
return Handle<JSFunction>(
- isolate->global_context()->call_as_constructor_delegate());
+ isolate->native_context()->call_as_constructor_delegate());
}
return isolate->factory()->undefined_value();
@@ -331,7 +331,7 @@ Handle<Object> Execution::TryGetConstructorDelegate(
if (fun->IsHeapObject() &&
HeapObject::cast(fun)->map()->has_instance_call_handler()) {
return Handle<JSFunction>(
- isolate->global_context()->call_as_constructor_delegate());
+ isolate->native_context()->call_as_constructor_delegate());
}
// If the Object doesn't have an instance-call handler we should
@@ -446,6 +446,25 @@ void StackGuard::RequestRuntimeProfilerTick() {
}
+void StackGuard::RequestCodeReadyEvent() {
+ ASSERT(FLAG_parallel_recompilation);
+ if (ExecutionAccess::TryLock(isolate_)) {
+ thread_local_.interrupt_flags_ |= CODE_READY;
+ if (thread_local_.postpone_interrupts_nesting_ == 0) {
+ thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
+ isolate_->heap()->SetStackLimits();
+ }
+ ExecutionAccess::Unlock(isolate_);
+ }
+}
+
+
+bool StackGuard::IsCodeReadyEvent() {
+ ExecutionAccess access(isolate_);
+ return (thread_local_.interrupt_flags_ & CODE_READY) != 0;
+}
+
+
bool StackGuard::IsGCRequest() {
ExecutionAccess access(isolate_);
return (thread_local_.interrupt_flags_ & GC_REQUEST) != 0;
@@ -661,7 +680,7 @@ Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
Handle<String> flags,
bool* exc) {
Handle<JSFunction> function = Handle<JSFunction>(
- pattern->GetIsolate()->global_context()->regexp_function());
+ pattern->GetIsolate()->native_context()->regexp_function());
Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral(
function, pattern, flags, exc);
if (*exc) return Handle<JSRegExp>();
@@ -707,7 +726,7 @@ Handle<JSFunction> Execution::InstantiateFunction(
// Fast case: see if the function has already been instantiated
int serial_number = Smi::cast(data->serial_number())->value();
Object* elm =
- isolate->global_context()->function_cache()->
+ isolate->native_context()->function_cache()->
GetElementNoExceptionThrown(serial_number);
if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
// The function has not yet been instantiated in this context; do it.
@@ -832,6 +851,11 @@ Object* Execution::DebugBreakHelper() {
return isolate->heap()->undefined_value();
}
+ // Ignore debug break if debugger is not active.
+ if (!isolate->debugger()->IsDebuggerActive()) {
+ return isolate->heap()->undefined_value();
+ }
+
StackLimitCheck check(isolate);
if (check.HasOverflowed()) {
return isolate->heap()->undefined_value();
@@ -846,7 +870,7 @@ Object* Execution::DebugBreakHelper() {
if (JSFunction::cast(fun)->IsBuiltin()) {
return isolate->heap()->undefined_value();
}
- GlobalObject* global = JSFunction::cast(fun)->context()->global();
+ GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
// Don't stop in debugger functions.
if (isolate->debug()->IsDebugGlobal(global)) {
return isolate->heap()->undefined_value();
@@ -906,6 +930,17 @@ MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
stack_guard->Continue(GC_REQUEST);
}
+ if (stack_guard->IsCodeReadyEvent()) {
+ ASSERT(FLAG_parallel_recompilation);
+ if (FLAG_trace_parallel_recompilation) {
+ PrintF(" ** CODE_READY event received.\n");
+ }
+ stack_guard->Continue(CODE_READY);
+ }
+ if (!stack_guard->IsTerminateExecution()) {
+ isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
+ }
+
isolate->counters()->stack_interrupts()->Increment();
// If FLAG_count_based_interrupts, every interrupt is a profiler interrupt.
if (FLAG_count_based_interrupts ||
diff --git a/deps/v8/src/execution.h b/deps/v8/src/execution.h
index 01e4b9da4..9f5d9ff2c 100644
--- a/deps/v8/src/execution.h
+++ b/deps/v8/src/execution.h
@@ -42,7 +42,8 @@ enum InterruptFlag {
PREEMPT = 1 << 3,
TERMINATE = 1 << 4,
RUNTIME_PROFILER_TICK = 1 << 5,
- GC_REQUEST = 1 << 6
+ GC_REQUEST = 1 << 6,
+ CODE_READY = 1 << 7
};
@@ -195,6 +196,8 @@ class StackGuard {
void TerminateExecution();
bool IsRuntimeProfilerTick();
void RequestRuntimeProfilerTick();
+ bool IsCodeReadyEvent();
+ void RequestCodeReadyEvent();
#ifdef ENABLE_DEBUGGER_SUPPORT
bool IsDebugBreak();
void DebugBreak();
diff --git a/deps/v8/src/extensions/statistics-extension.cc b/deps/v8/src/extensions/statistics-extension.cc
new file mode 100644
index 000000000..7ae090c98
--- /dev/null
+++ b/deps/v8/src/extensions/statistics-extension.cc
@@ -0,0 +1,153 @@
+// Copyright 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.
+
+#include "statistics-extension.h"
+
+namespace v8 {
+namespace internal {
+
+const char* const StatisticsExtension::kSource =
+ "native function getV8Statistics();";
+
+
+v8::Handle<v8::FunctionTemplate> StatisticsExtension::GetNativeFunction(
+ v8::Handle<v8::String> str) {
+ ASSERT(strcmp(*v8::String::AsciiValue(str), "getV8Statistics") == 0);
+ return v8::FunctionTemplate::New(StatisticsExtension::GetCounters);
+}
+
+
+static void AddCounter(v8::Local<v8::Object> object,
+ StatsCounter* counter,
+ const char* name) {
+ if (counter->Enabled()) {
+ object->Set(v8::String::New(name),
+ v8::Number::New(*counter->GetInternalPointer()));
+ }
+}
+
+static void AddNumber(v8::Local<v8::Object> object,
+ intptr_t value,
+ const char* name) {
+ object->Set(v8::String::New(name),
+ v8::Number::New(static_cast<double>(value)));
+}
+
+
+v8::Handle<v8::Value> StatisticsExtension::GetCounters(
+ const v8::Arguments& args) {
+ Isolate* isolate = Isolate::Current();
+ Heap* heap = isolate->heap();
+
+ if (args.Length() > 0) { // GC if first argument evaluates to true.
+ if (args[0]->IsBoolean() && args[0]->ToBoolean()->Value()) {
+ heap->CollectAllGarbage(Heap::kNoGCFlags, "counters extension");
+ }
+ }
+
+ Counters* counters = isolate->counters();
+ v8::Local<v8::Object> result = v8::Object::New();
+
+#define ADD_COUNTER(name, caption) \
+ AddCounter(result, counters->name(), #name);
+
+ STATS_COUNTER_LIST_1(ADD_COUNTER)
+ STATS_COUNTER_LIST_2(ADD_COUNTER)
+#undef ADD_COUNTER
+#define ADD_COUNTER(name) \
+ AddCounter(result, counters->count_of_##name(), "count_of_" #name); \
+ AddCounter(result, counters->size_of_##name(), "size_of_" #name);
+
+ INSTANCE_TYPE_LIST(ADD_COUNTER)
+#undef ADD_COUNTER
+#define ADD_COUNTER(name) \
+ AddCounter(result, counters->count_of_CODE_TYPE_##name(), \
+ "count_of_CODE_TYPE_" #name); \
+ AddCounter(result, counters->size_of_CODE_TYPE_##name(), \
+ "size_of_CODE_TYPE_" #name);
+
+ CODE_KIND_LIST(ADD_COUNTER)
+#undef ADD_COUNTER
+#define ADD_COUNTER(name) \
+ AddCounter(result, counters->count_of_FIXED_ARRAY_##name(), \
+ "count_of_FIXED_ARRAY_" #name); \
+ AddCounter(result, counters->size_of_FIXED_ARRAY_##name(), \
+ "size_of_FIXED_ARRAY_" #name);
+
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADD_COUNTER)
+#undef ADD_COUNTER
+
+ AddNumber(result, isolate->memory_allocator()->Size(),
+ "total_committed_bytes");
+ AddNumber(result, heap->new_space()->Size(),
+ "new_space_live_bytes");
+ AddNumber(result, heap->new_space()->Available(),
+ "new_space_available_bytes");
+ AddNumber(result, heap->new_space()->CommittedMemory(),
+ "new_space_commited_bytes");
+ AddNumber(result, heap->old_pointer_space()->Size(),
+ "old_pointer_space_live_bytes");
+ AddNumber(result, heap->old_pointer_space()->Available(),
+ "old_pointer_space_available_bytes");
+ AddNumber(result, heap->old_pointer_space()->CommittedMemory(),
+ "old_pointer_space_commited_bytes");
+ AddNumber(result, heap->old_data_space()->Size(),
+ "old_data_space_live_bytes");
+ AddNumber(result, heap->old_data_space()->Available(),
+ "old_data_space_available_bytes");
+ AddNumber(result, heap->old_data_space()->CommittedMemory(),
+ "old_data_space_commited_bytes");
+ AddNumber(result, heap->code_space()->Size(),
+ "code_space_live_bytes");
+ AddNumber(result, heap->code_space()->Available(),
+ "code_space_available_bytes");
+ AddNumber(result, heap->code_space()->CommittedMemory(),
+ "code_space_commited_bytes");
+ AddNumber(result, heap->cell_space()->Size(),
+ "cell_space_live_bytes");
+ AddNumber(result, heap->cell_space()->Available(),
+ "cell_space_available_bytes");
+ AddNumber(result, heap->cell_space()->CommittedMemory(),
+ "cell_space_commited_bytes");
+ AddNumber(result, heap->lo_space()->Size(),
+ "lo_space_live_bytes");
+ AddNumber(result, heap->lo_space()->Available(),
+ "lo_space_available_bytes");
+ AddNumber(result, heap->lo_space()->CommittedMemory(),
+ "lo_space_commited_bytes");
+ AddNumber(result, heap->amount_of_external_allocated_memory(),
+ "amount_of_external_allocated_memory");
+ return result;
+}
+
+
+void StatisticsExtension::Register() {
+ static StatisticsExtension statistics_extension;
+ static v8::DeclareExtension declaration(&statistics_extension);
+}
+
+} } // namespace v8::internal
diff --git a/deps/v8/src/extensions/statistics-extension.h b/deps/v8/src/extensions/statistics-extension.h
new file mode 100644
index 000000000..433c4cf68
--- /dev/null
+++ b/deps/v8/src/extensions/statistics-extension.h
@@ -0,0 +1,49 @@
+// Copyright 2010 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.
+
+#ifndef V8_EXTENSIONS_STATISTICS_EXTENSION_H_
+#define V8_EXTENSIONS_STATISTICS_EXTENSION_H_
+
+#include "v8.h"
+
+namespace v8 {
+namespace internal {
+
+class StatisticsExtension : public v8::Extension {
+ public:
+ StatisticsExtension() : v8::Extension("v8/statistics", kSource) {}
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
+ v8::Handle<v8::String> name);
+ static v8::Handle<v8::Value> GetCounters(const v8::Arguments& args);
+ static void Register();
+ private:
+ static const char* const kSource;
+};
+
+} } // namespace v8::internal
+
+#endif // V8_EXTENSIONS_STATISTICS_EXTENSION_H_
diff --git a/deps/v8/src/factory.cc b/deps/v8/src/factory.cc
index 28b318a8f..a2bb9391e 100644
--- a/deps/v8/src/factory.cc
+++ b/deps/v8/src/factory.cc
@@ -112,11 +112,11 @@ Handle<ObjectHashTable> Factory::NewObjectHashTable(int at_least_space_for) {
}
-Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors) {
+Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors,
+ int slack) {
ASSERT(0 <= number_of_descriptors);
CALL_HEAP_FUNCTION(isolate(),
- DescriptorArray::Allocate(number_of_descriptors,
- DescriptorArray::MAY_BE_SHARED),
+ DescriptorArray::Allocate(number_of_descriptors, slack),
DescriptorArray);
}
@@ -285,19 +285,27 @@ Handle<String> Factory::NewExternalStringFromTwoByte(
}
-Handle<Context> Factory::NewGlobalContext() {
+Handle<Context> Factory::NewNativeContext() {
CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->AllocateGlobalContext(),
+ isolate()->heap()->AllocateNativeContext(),
Context);
}
-Handle<Context> Factory::NewModuleContext(Handle<Context> previous,
+Handle<Context> Factory::NewGlobalContext(Handle<JSFunction> function,
Handle<ScopeInfo> scope_info) {
CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->AllocateModuleContext(*previous, *scope_info),
+ isolate()->heap()->AllocateGlobalContext(*function, *scope_info),
+ Context);
+}
+
+
+Handle<Context> Factory::NewModuleContext(Handle<ScopeInfo> scope_info) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->AllocateModuleContext(*scope_info),
Context);
}
@@ -466,14 +474,15 @@ Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
}
-Handle<Map> Factory::CopyMapDropDescriptors(Handle<Map> src) {
- CALL_HEAP_FUNCTION(isolate(), src->CopyDropDescriptors(), Map);
+Handle<Map> Factory::CopyWithPreallocatedFieldDescriptors(Handle<Map> src) {
+ CALL_HEAP_FUNCTION(
+ isolate(), src->CopyWithPreallocatedFieldDescriptors(), Map);
}
Handle<Map> Factory::CopyMap(Handle<Map> src,
int extra_inobject_properties) {
- Handle<Map> copy = CopyMapDropDescriptors(src);
+ Handle<Map> copy = CopyWithPreallocatedFieldDescriptors(src);
// Check that we do not overflow the instance size when adding the
// extra inobject properties.
int instance_size_delta = extra_inobject_properties * kPointerSize;
@@ -496,10 +505,8 @@ Handle<Map> Factory::CopyMap(Handle<Map> src,
}
-Handle<Map> Factory::CopyMapDropTransitions(Handle<Map> src) {
- CALL_HEAP_FUNCTION(isolate(),
- src->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED),
- Map);
+Handle<Map> Factory::CopyMap(Handle<Map> src) {
+ CALL_HEAP_FUNCTION(isolate(), src->Copy(), Map);
}
@@ -554,18 +561,27 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
}
result->set_context(*context);
- if (!function_info->bound()) {
+
+ int index = function_info->SearchOptimizedCodeMap(context->native_context());
+ if (!function_info->bound() && index < 0) {
int number_of_literals = function_info->num_literals();
Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
if (number_of_literals > 0) {
- // Store the object, regexp and array functions in the literals
- // array prefix. These functions will be used when creating
- // object, regexp and array literals in this function.
- literals->set(JSFunction::kLiteralGlobalContextIndex,
- context->global_context());
+ // Store the native context in the literals array prefix. This
+ // context will be used when creating object, regexp and array
+ // literals in this function.
+ literals->set(JSFunction::kLiteralNativeContextIndex,
+ context->native_context());
}
result->set_literals(*literals);
}
+
+ if (index > 0) {
+ // Caching of optimized code enabled and optimized code found.
+ function_info->InstallFromOptimizedCodeMap(*result, index);
+ return result;
+ }
+
if (V8::UseCrankshaft() &&
FLAG_always_opt &&
result->is_compiled() &&
@@ -699,7 +715,7 @@ Handle<String> Factory::EmergencyNewError(const char* type,
MaybeObject* maybe_arg = args->GetElement(i);
Handle<String> arg_str(reinterpret_cast<String*>(maybe_arg));
const char* arg = *arg_str->ToCString();
- Vector<char> v2(p, space);
+ Vector<char> v2(p, static_cast<int>(space));
OS::StrNCpy(v2, arg, space);
space -= Min(space, strlen(arg));
p = &buffer[kBufferSize] - space;
@@ -879,97 +895,12 @@ Handle<Code> Factory::CopyCode(Handle<Code> code, Vector<byte> reloc_info) {
}
-MUST_USE_RESULT static inline MaybeObject* DoCopyInsert(
- DescriptorArray* array,
- String* key,
- Object* value,
- PropertyAttributes attributes) {
- CallbacksDescriptor desc(key, value, attributes);
- MaybeObject* obj = array->CopyInsert(&desc, REMOVE_TRANSITIONS);
- return obj;
-}
-
-
-// Allocate the new array.
-Handle<DescriptorArray> Factory::CopyAppendForeignDescriptor(
- Handle<DescriptorArray> array,
- Handle<String> key,
- Handle<Object> value,
- PropertyAttributes attributes) {
- CALL_HEAP_FUNCTION(isolate(),
- DoCopyInsert(*array, *key, *value, attributes),
- DescriptorArray);
-}
-
-
Handle<String> Factory::SymbolFromString(Handle<String> value) {
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->LookupSymbol(*value), String);
}
-Handle<DescriptorArray> Factory::CopyAppendCallbackDescriptors(
- Handle<DescriptorArray> array,
- Handle<Object> descriptors) {
- v8::NeanderArray callbacks(descriptors);
- int nof_callbacks = callbacks.length();
- Handle<DescriptorArray> result =
- NewDescriptorArray(array->number_of_descriptors() + nof_callbacks);
-
- // Number of descriptors added to the result so far.
- int descriptor_count = 0;
-
- // Ensure that marking will not progress and change color of objects.
- DescriptorArray::WhitenessWitness witness(*result);
-
- // Copy the descriptors from the array.
- for (int i = 0; i < array->number_of_descriptors(); i++) {
- if (!array->IsNullDescriptor(i)) {
- DescriptorArray::CopyFrom(result, descriptor_count++, array, i, witness);
- }
- }
-
- // Number of duplicates detected.
- int duplicates = 0;
-
- // Fill in new callback descriptors. Process the callbacks from
- // back to front so that the last callback with a given name takes
- // precedence over previously added callbacks with that name.
- for (int i = nof_callbacks - 1; i >= 0; i--) {
- Handle<AccessorInfo> entry =
- Handle<AccessorInfo>(AccessorInfo::cast(callbacks.get(i)));
- // Ensure the key is a symbol before writing into the instance descriptor.
- Handle<String> key =
- SymbolFromString(Handle<String>(String::cast(entry->name())));
- // Check if a descriptor with this name already exists before writing.
- if (result->LinearSearch(EXPECT_UNSORTED, *key, descriptor_count) ==
- DescriptorArray::kNotFound) {
- CallbacksDescriptor desc(*key, *entry, entry->property_attributes());
- result->Set(descriptor_count, &desc, witness);
- descriptor_count++;
- } else {
- duplicates++;
- }
- }
-
- // If duplicates were detected, allocate a result of the right size
- // and transfer the elements.
- if (duplicates > 0) {
- int number_of_descriptors = result->number_of_descriptors() - duplicates;
- Handle<DescriptorArray> new_result =
- NewDescriptorArray(number_of_descriptors);
- for (int i = 0; i < number_of_descriptors; i++) {
- DescriptorArray::CopyFrom(new_result, i, result, i, witness);
- }
- result = new_result;
- }
-
- // Sort the result before returning.
- result->Sort(witness);
- return result;
-}
-
-
Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(
@@ -978,10 +909,11 @@ Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
}
-Handle<JSModule> Factory::NewJSModule() {
+Handle<JSModule> Factory::NewJSModule(Handle<Context> context,
+ Handle<ScopeInfo> scope_info) {
CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->AllocateJSModule(), JSModule);
+ isolate()->heap()->AllocateJSModule(*context, *scope_info), JSModule);
}
@@ -1088,7 +1020,7 @@ void Factory::BecomeJSFunction(Handle<JSReceiver> object) {
}
-void Factory::SetIdentityHash(Handle<JSObject> object, Object* hash) {
+void Factory::SetIdentityHash(Handle<JSObject> object, Smi* hash) {
CALL_HEAP_FUNCTION_VOID(
isolate(),
object->SetIdentityHash(hash, ALLOW_CREATION));
@@ -1188,7 +1120,7 @@ Handle<JSFunction> Factory::NewFunctionHelper(Handle<String> name,
Handle<JSFunction> Factory::NewFunction(Handle<String> name,
Handle<Object> prototype) {
Handle<JSFunction> fun = NewFunctionHelper(name, prototype);
- fun->set_context(isolate()->context()->global_context());
+ fun->set_context(isolate()->context()->native_context());
return fun;
}
@@ -1214,7 +1146,7 @@ Handle<JSFunction> Factory::NewFunctionWithoutPrototype(
LanguageMode language_mode) {
Handle<JSFunction> fun =
NewFunctionWithoutPrototypeHelper(name, language_mode);
- fun->set_context(isolate()->context()->global_context());
+ fun->set_context(isolate()->context()->native_context());
return fun;
}
@@ -1225,8 +1157,8 @@ Handle<Object> Factory::ToObject(Handle<Object> object) {
Handle<Object> Factory::ToObject(Handle<Object> object,
- Handle<Context> global_context) {
- CALL_HEAP_FUNCTION(isolate(), object->ToObject(*global_context), Object);
+ Handle<Context> native_context) {
+ CALL_HEAP_FUNCTION(isolate(), object->ToObject(*native_context), Object);
}
@@ -1353,20 +1285,31 @@ Handle<JSFunction> Factory::CreateApiFunction(
result->shared()->DontAdaptArguments();
// Recursively copy parent templates' accessors, 'data' may be modified.
- Handle<DescriptorArray> array =
- Handle<DescriptorArray>(map->instance_descriptors());
+ int max_number_of_additional_properties = 0;
+ FunctionTemplateInfo* info = *obj;
+ while (true) {
+ Object* props = info->property_accessors();
+ if (!props->IsUndefined()) {
+ Handle<Object> props_handle(props);
+ NeanderArray props_array(props_handle);
+ max_number_of_additional_properties += props_array.length();
+ }
+ Object* parent = info->parent_template();
+ if (parent->IsUndefined()) break;
+ info = FunctionTemplateInfo::cast(parent);
+ }
+
+ Map::EnsureDescriptorSlack(map, max_number_of_additional_properties);
+
while (true) {
Handle<Object> props = Handle<Object>(obj->property_accessors());
if (!props->IsUndefined()) {
- array = CopyAppendCallbackDescriptors(array, props);
+ Map::AppendCallbackDescriptors(map, props);
}
Handle<Object> parent = Handle<Object>(obj->parent_template());
if (parent->IsUndefined()) break;
obj = Handle<FunctionTemplateInfo>::cast(parent);
}
- if (!array->IsEmpty()) {
- map->set_instance_descriptors(*array);
- }
ASSERT(result->shared()->IsApiFunction());
return result;
@@ -1403,7 +1346,7 @@ Handle<MapCache> Factory::AddToMapCache(Handle<Context> context,
Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
Handle<FixedArray> keys) {
if (context->map_cache()->IsUndefined()) {
- // Allocate the new map cache for the global context.
+ // Allocate the new map cache for the native context.
Handle<MapCache> new_cache = NewMapCache(24);
context->set_map_cache(*new_cache);
}
diff --git a/deps/v8/src/factory.h b/deps/v8/src/factory.h
index bb435456b..51065aac4 100644
--- a/deps/v8/src/factory.h
+++ b/deps/v8/src/factory.h
@@ -66,7 +66,8 @@ class Factory {
Handle<ObjectHashTable> NewObjectHashTable(int at_least_space_for);
- Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors);
+ Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors,
+ int slack = 0);
Handle<DeoptimizationInputData> NewDeoptimizationInputData(
int deopt_entry_count,
PretenureFlag pretenure);
@@ -160,12 +161,15 @@ class Factory {
const ExternalTwoByteString::Resource* resource);
// Create a global (but otherwise uninitialized) context.
- Handle<Context> NewGlobalContext();
+ Handle<Context> NewNativeContext();
- // Create a module context.
- Handle<Context> NewModuleContext(Handle<Context> previous,
+ // Create a global context.
+ Handle<Context> NewGlobalContext(Handle<JSFunction> function,
Handle<ScopeInfo> scope_info);
+ // Create a module context.
+ Handle<Context> NewModuleContext(Handle<ScopeInfo> scope_info);
+
// Create a function context.
Handle<Context> NewFunctionContext(int length, Handle<JSFunction> function);
@@ -223,13 +227,12 @@ class Factory {
Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function);
- Handle<Map> CopyMapDropDescriptors(Handle<Map> map);
+ Handle<Map> CopyWithPreallocatedFieldDescriptors(Handle<Map> map);
// Copy the map adding more inobject properties if possible without
// overflowing the instance size.
Handle<Map> CopyMap(Handle<Map> map, int extra_inobject_props);
-
- Handle<Map> CopyMapDropTransitions(Handle<Map> map);
+ Handle<Map> CopyMap(Handle<Map> map);
Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
ElementsKind elements_kind);
@@ -267,7 +270,8 @@ class Factory {
Handle<JSObject> NewJSObjectFromMap(Handle<Map> map);
// JS modules are pretenured.
- Handle<JSModule> NewJSModule();
+ Handle<JSModule> NewJSModule(Handle<Context> context,
+ Handle<ScopeInfo> scope_info);
// JS arrays are pretenured when allocated by the parser.
Handle<JSArray> NewJSArray(
@@ -298,7 +302,7 @@ class Factory {
void BecomeJSObject(Handle<JSReceiver> object);
void BecomeJSFunction(Handle<JSReceiver> object);
- void SetIdentityHash(Handle<JSObject> object, Object* hash);
+ void SetIdentityHash(Handle<JSObject> object, Smi* hash);
Handle<JSFunction> NewFunction(Handle<String> name,
Handle<Object> prototype);
@@ -332,7 +336,7 @@ class Factory {
Handle<Object> ToObject(Handle<Object> object);
Handle<Object> ToObject(Handle<Object> object,
- Handle<Context> global_context);
+ Handle<Context> native_context);
// Interface for creating error objects.
@@ -386,12 +390,6 @@ class Factory {
Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
Handle<Code> code);
- Handle<DescriptorArray> CopyAppendForeignDescriptor(
- Handle<DescriptorArray> array,
- Handle<String> key,
- Handle<Object> value,
- PropertyAttributes attributes);
-
Handle<String> NumberToString(Handle<Object> number);
Handle<String> Uint32ToString(uint32_t value);
@@ -464,7 +462,7 @@ class Factory {
Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);
#endif
- // Return a map using the map cache in the global context.
+ // Return a map using the map cache in the native context.
// The key the an ordered set of property names.
Handle<Map> ObjectLiteralMapFromCache(Handle<Context> context,
Handle<FixedArray> keys);
@@ -503,14 +501,10 @@ class Factory {
Handle<String> name,
LanguageMode language_mode);
- Handle<DescriptorArray> CopyAppendCallbackDescriptors(
- Handle<DescriptorArray> array,
- Handle<Object> descriptors);
-
// Create a new map cache.
Handle<MapCache> NewMapCache(int at_least_space_for);
- // Update the map cache in the global context with (keys, map)
+ // Update the map cache in the native context with (keys, map)
Handle<MapCache> AddToMapCache(Handle<Context> context,
Handle<FixedArray> keys,
Handle<Map> map);
diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h
index 6bb1507da..4c7c090f4 100644
--- a/deps/v8/src/flag-definitions.h
+++ b/deps/v8/src/flag-definitions.h
@@ -132,9 +132,9 @@ public:
// Flags for language modes and experimental language features.
DEFINE_bool(use_strict, false, "enforce strict mode")
-DEFINE_bool(es5_readonly, false,
+DEFINE_bool(es5_readonly, true,
"activate correct semantics for inheriting readonliness")
-DEFINE_bool(es52_globals, false,
+DEFINE_bool(es52_globals, true,
"activate new semantics for global var declarations")
DEFINE_bool(harmony_typeof, false, "enable harmony semantics for typeof")
@@ -152,7 +152,7 @@ DEFINE_implication(harmony, harmony_collections)
DEFINE_implication(harmony_modules, harmony_scoping)
// Flags for experimental implementation features.
-DEFINE_bool(packed_arrays, false, "optimizes arrays that have no holes")
+DEFINE_bool(packed_arrays, true, "optimizes arrays that have no holes")
DEFINE_bool(smi_only_arrays, true, "tracks arrays with only smi values")
DEFINE_bool(clever_optimizations,
true,
@@ -198,20 +198,37 @@ DEFINE_bool(trap_on_deopt, false, "put a break point before deoptimizing")
DEFINE_bool(deoptimize_uncommon_cases, true, "deoptimize uncommon cases")
DEFINE_bool(polymorphic_inlining, true, "polymorphic inlining")
DEFINE_bool(use_osr, true, "use on-stack replacement")
-DEFINE_bool(array_bounds_checks_elimination, false,
+DEFINE_bool(array_bounds_checks_elimination, true,
"perform array bounds checks elimination")
-DEFINE_bool(array_index_dehoisting, false,
+DEFINE_bool(array_index_dehoisting, true,
"perform array index dehoisting")
+DEFINE_bool(dead_code_elimination, true, "use dead code elimination")
+DEFINE_bool(trace_dead_code_elimination, false, "trace dead code elimination")
DEFINE_bool(trace_osr, false, "trace on-stack replacement")
DEFINE_int(stress_runs, 0, "number of stress runs")
DEFINE_bool(optimize_closures, true, "optimize closures")
+DEFINE_bool(lookup_sample_by_shared, true,
+ "when picking a function to optimize, watch for shared function "
+ "info, not JSFunction itself")
+DEFINE_bool(cache_optimized_code, true,
+ "cache optimized code for closures")
DEFINE_bool(inline_construct, true, "inline constructor calls")
DEFINE_bool(inline_arguments, true, "inline functions with arguments object")
+DEFINE_bool(inline_accessors, true, "inline JavaScript accessors")
DEFINE_int(loop_weight, 1, "loop weight for representation inference")
DEFINE_bool(optimize_for_in, true,
"optimize functions containing for-in loops")
+DEFINE_bool(opt_safe_uint32_operations, true,
+ "allow uint32 values on optimize frames if they are used only in"
+ "safe operations")
+
+DEFINE_bool(parallel_recompilation, false,
+ "optimizing hot functions asynchronously on a separate thread")
+DEFINE_bool(trace_parallel_recompilation, false, "track parallel recompilation")
+DEFINE_int(parallel_recompilation_queue_length, 2,
+ "the length of the parallel compilation queue")
// Experimental profiler changes.
DEFINE_bool(experimental_profiler, true, "enable all profiler experiments")
@@ -228,7 +245,8 @@ DEFINE_bool(interrupt_at_exit, false,
"insert an interrupt check at function exit")
DEFINE_bool(weighted_back_edges, false,
"weight back edges by jump distance for interrupt triggering")
-DEFINE_int(interrupt_budget, 5900,
+ // 0x1700 fits in the immediate field of an ARM instruction.
+DEFINE_int(interrupt_budget, 0x1700,
"execution budget before interrupt is triggered")
DEFINE_int(type_info_threshold, 15,
"percentage of ICs that must have type info to allow optimization")
@@ -268,6 +286,13 @@ DEFINE_bool(enable_vfp2, true,
"enable use of VFP2 instructions if available")
DEFINE_bool(enable_armv7, true,
"enable use of ARMv7 instructions if available (ARM only)")
+DEFINE_bool(enable_sudiv, true,
+ "enable use of SDIV and UDIV instructions if available (ARM only)")
+DEFINE_bool(enable_movw_movt, false,
+ "enable loading 32-bit constant by means of movw/movt "
+ "instruction pairs (ARM only)")
+DEFINE_bool(enable_unaligned_accesses, true,
+ "enable unaligned accesses for ARMv7 (ARM only)")
DEFINE_bool(enable_fpu, true,
"enable use of MIPS FPU instructions if available (MIPS only)")
@@ -309,8 +334,8 @@ DEFINE_int(min_preparse_length, 1024,
"minimum length for automatic enable preparsing")
DEFINE_bool(always_full_compiler, false,
"try to use the dedicated run-once backend for all code")
-DEFINE_bool(trace_bailout, false,
- "print reasons for falling back to using the classic V8 backend")
+DEFINE_int(max_opt_count, 10,
+ "maximum number of optimization attempts before giving up.")
// compilation-cache.cc
DEFINE_bool(compilation_cache, true, "enable compilation cache")
@@ -350,12 +375,17 @@ DEFINE_bool(trace_gc, false,
DEFINE_bool(trace_gc_nvp, false,
"print one detailed trace line in name=value format "
"after each garbage collection")
+DEFINE_bool(trace_gc_ignore_scavenger, false,
+ "do not print trace line after scavenger collection")
DEFINE_bool(print_cumulative_gc_stat, false,
"print cumulative GC statistics in name=value format on exit")
DEFINE_bool(trace_gc_verbose, false,
"print more details following each garbage collection")
DEFINE_bool(trace_fragmentation, false,
"report fragmentation for old pointer and data pages")
+DEFINE_bool(trace_external_memory, false,
+ "print amount of external allocated memory after each time "
+ "it is adjusted.")
DEFINE_bool(collect_maps, true,
"garbage collect maps from which no objects can be reached")
DEFINE_bool(flush_code, true,
@@ -364,13 +394,15 @@ DEFINE_bool(incremental_marking, true, "use incremental marking")
DEFINE_bool(incremental_marking_steps, true, "do incremental marking steps")
DEFINE_bool(trace_incremental_marking, false,
"trace progress of the incremental marking")
+DEFINE_bool(track_gc_object_stats, false,
+ "track object counts and memory usage")
+#ifdef VERIFY_HEAP
+DEFINE_bool(verify_heap, false, "verify heap pointers before and after GC")
+#endif
// v8.cc
DEFINE_bool(use_idle_notification, true,
"Use idle notification to reduce memory footprint.")
-
-DEFINE_bool(send_idle_notification, false,
- "Send idle notifcation between stress runs.")
// ic.cc
DEFINE_bool(use_ic, true, "use inline caching")
@@ -392,6 +424,8 @@ DEFINE_bool(never_compact, false,
"Never perform compaction on full GC - testing only")
DEFINE_bool(compact_code_space, true,
"Compact code space on full non-incremental collections")
+DEFINE_bool(incremental_code_compaction, true,
+ "Compact code space on full incremental collections")
DEFINE_bool(cleanup_code_caches_at_gc, true,
"Flush inline caches prior to mark compact collection and "
"flush code caches in maps during mark compact cycle.")
@@ -404,6 +438,7 @@ DEFINE_bool(use_verbose_printer, true, "allows verbose printing")
// parser.cc
DEFINE_bool(allow_natives_syntax, false, "allow natives syntax")
+DEFINE_bool(trace_parse, false, "trace parsing and preparsing")
// simulator-arm.cc and simulator-mips.cc
DEFINE_bool(trace_sim, false, "Trace simulator execution")
@@ -448,6 +483,10 @@ DEFINE_string(testing_serialization_file, "/tmp/serdes",
"file in which to serialize heap")
#endif
+// mksnapshot.cc
+DEFINE_string(extra_code, NULL, "A filename with extra code to be included in"
+ " the snapshot (mksnapshot only)")
+
//
// Dev shell flags
//
@@ -533,7 +572,8 @@ DEFINE_bool(gc_greedy, false, "perform GC prior to some allocations")
DEFINE_bool(gc_verbose, false, "print stuff during garbage collection")
DEFINE_bool(heap_stats, false, "report heap statistics before and after GC")
DEFINE_bool(code_stats, false, "report code statistics after GC")
-DEFINE_bool(verify_heap, false, "verify heap pointers before and after GC")
+DEFINE_bool(verify_native_context_separation, false,
+ "verify that code holds on to at most one native context after GC")
DEFINE_bool(print_handles, false, "report handles after GC")
DEFINE_bool(print_global_handles, false, "report global handles after GC")
@@ -606,6 +646,8 @@ DEFINE_bool(sliding_state_window, false,
"Update sliding state window counters.")
DEFINE_string(logfile, "v8.log", "Specify the name of the log file.")
DEFINE_bool(ll_prof, false, "Enable low-level linux profiler.")
+DEFINE_string(gc_fake_mmap, "/tmp/__v8_gc__",
+ "Specify the name of the file for fake gc mmap used in ll_prof")
//
// Disassembler only flags
diff --git a/deps/v8/src/flags.cc b/deps/v8/src/flags.cc
index 5720cbda3..bca0eff58 100644
--- a/deps/v8/src/flags.cc
+++ b/deps/v8/src/flags.cc
@@ -31,7 +31,7 @@
#include "v8.h"
#include "platform.h"
-#include "smart-array-pointer.h"
+#include "smart-pointers.h"
#include "string-stream.h"
@@ -343,6 +343,7 @@ static Flag* FindFlag(const char* name) {
int FlagList::SetFlagsFromCommandLine(int* argc,
char** argv,
bool remove_flags) {
+ int return_code = 0;
// parse arguments
for (int i = 1; i < *argc;) {
int j = i; // j > 0
@@ -368,7 +369,8 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
} else {
fprintf(stderr, "Error: unrecognized flag %s\n"
"Try --help for options\n", arg);
- return j;
+ return_code = j;
+ break;
}
}
@@ -382,7 +384,8 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
fprintf(stderr, "Error: missing value for flag %s of type %s\n"
"Try --help for options\n",
arg, Type2String(flag->type()));
- return j;
+ return_code = j;
+ break;
}
}
@@ -424,7 +427,8 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
fprintf(stderr, "Error: illegal value for flag %s of type %s\n"
"Try --help for options\n",
arg, Type2String(flag->type()));
- return j;
+ return_code = j;
+ break;
}
// remove the flag & value from the command
@@ -451,7 +455,7 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
exit(0);
}
// parsed all flags successfully
- return 0;
+ return return_code;
}
diff --git a/deps/v8/src/frames.cc b/deps/v8/src/frames.cc
index b7e028634..18dc54164 100644
--- a/deps/v8/src/frames.cc
+++ b/deps/v8/src/frames.cc
@@ -789,7 +789,7 @@ void JavaScriptFrame::PrintTop(FILE* file,
ROBUST_STRING_TRAVERSAL);
PrintF(file, " at %s:%d", *c_script_name, line);
} else {
- PrintF(file, "at <unknown>:%d", line);
+ PrintF(file, " at <unknown>:%d", line);
}
} else {
PrintF(file, " at <unknown>:<unknown>");
@@ -832,12 +832,23 @@ void FrameSummary::Print() {
}
+JSFunction* OptimizedFrame::LiteralAt(FixedArray* literal_array,
+ int literal_id) {
+ if (literal_id == Translation::kSelfLiteralId) {
+ return JSFunction::cast(function());
+ }
+
+ return JSFunction::cast(literal_array->get(literal_id));
+}
+
+
void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
ASSERT(frames->length() == 0);
ASSERT(is_optimized());
int deopt_index = Safepoint::kNoDeoptimizationIndex;
DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
+ FixedArray* literal_array = data->LiteralArray();
// BUG(3243555): Since we don't have a lazy-deopt registered at
// throw-statements, we can't use the translation at the call-site of
@@ -864,11 +875,9 @@ void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
opcode = static_cast<Translation::Opcode>(it.Next());
if (opcode == Translation::JS_FRAME) {
i--;
- int ast_id = it.Next();
- int function_id = it.Next();
+ BailoutId ast_id = BailoutId(it.Next());
+ JSFunction* function = LiteralAt(literal_array, it.Next());
it.Next(); // Skip height.
- JSFunction* function =
- JSFunction::cast(data->LiteralArray()->get(function_id));
// The translation commands are ordered and the receiver is always
// at the first position. Since we are always at a call when we need
@@ -975,6 +984,7 @@ void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) {
int deopt_index = Safepoint::kNoDeoptimizationIndex;
DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
+ FixedArray* literal_array = data->LiteralArray();
TranslationIterator it(data->TranslationByteArray(),
data->TranslationIndex(deopt_index)->value());
@@ -990,10 +1000,8 @@ void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) {
if (opcode == Translation::JS_FRAME) {
jsframe_count--;
it.Next(); // Skip ast id.
- int function_id = it.Next();
+ JSFunction* function = LiteralAt(literal_array, it.Next());
it.Next(); // Skip height.
- JSFunction* function =
- JSFunction::cast(data->LiteralArray()->get(function_id));
functions->Add(function);
} else {
// Skip over operands to advance to the next opcode.
diff --git a/deps/v8/src/frames.h b/deps/v8/src/frames.h
index 2d45932d0..30f7e1f00 100644
--- a/deps/v8/src/frames.h
+++ b/deps/v8/src/frames.h
@@ -577,6 +577,8 @@ class OptimizedFrame : public JavaScriptFrame {
inline explicit OptimizedFrame(StackFrameIterator* iterator);
private:
+ JSFunction* LiteralAt(FixedArray* literal_array, int literal_id);
+
friend class StackFrameIterator;
};
diff --git a/deps/v8/src/full-codegen.cc b/deps/v8/src/full-codegen.cc
index 4da4e531e..9592e0afa 100644
--- a/deps/v8/src/full-codegen.cc
+++ b/deps/v8/src/full-codegen.cc
@@ -36,6 +36,7 @@
#include "prettyprinter.h"
#include "scopes.h"
#include "scopeinfo.h"
+#include "snapshot.h"
#include "stub-cache.h"
namespace v8 {
@@ -303,7 +304,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
masm.positions_recorder()->StartGDBJITLineInfoRecording();
#endif
- FullCodeGenerator cgen(&masm, info, isolate->zone());
+ FullCodeGenerator cgen(&masm, info);
cgen.Generate();
if (cgen.HasStackOverflow()) {
ASSERT(!isolate->has_pending_exception());
@@ -315,7 +316,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
code->set_optimizable(info->IsOptimizable() &&
!info->function()->flags()->Contains(kDontOptimize) &&
- info->function()->scope()->AllowsLazyRecompilation());
+ info->function()->scope()->AllowsLazyCompilation());
cgen.PopulateDeoptimizationData(code);
cgen.PopulateTypeFeedbackInfo(code);
cgen.PopulateTypeFeedbackCells(code);
@@ -352,7 +353,7 @@ unsigned FullCodeGenerator::EmitStackCheckTable() {
unsigned length = stack_checks_.length();
__ dd(length);
for (unsigned i = 0; i < length; ++i) {
- __ dd(stack_checks_[i].id);
+ __ dd(stack_checks_[i].id.ToInt());
__ dd(stack_checks_[i].pc_and_state);
}
return offset;
@@ -367,7 +368,7 @@ void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
Handle<DeoptimizationOutputData> data = isolate()->factory()->
NewDeoptimizationOutputData(length, TENURED);
for (int i = 0; i < length; i++) {
- data->SetAstId(i, Smi::FromInt(bailout_entries_[i].id));
+ data->SetAstId(i, bailout_entries_[i].id);
data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state));
}
code->set_deoptimization_data(*data);
@@ -382,6 +383,20 @@ void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
}
+void FullCodeGenerator::Initialize() {
+ // The generation of debug code must match between the snapshot code and the
+ // code that is generated later. This is assumed by the debugger when it is
+ // calculating PC offsets after generating a debug version of code. Therefore
+ // we disable the production of debug code in the full compiler if we are
+ // either generating a snapshot or we booted from a snapshot.
+ generate_debug_code_ = FLAG_debug_code &&
+ !Serializer::enabled() &&
+ !Snapshot::HaveASnapshotToStartFrom();
+ masm_->set_emit_debug_code(generate_debug_code_);
+ masm_->set_predictable_code_size(true);
+}
+
+
void FullCodeGenerator::PopulateTypeFeedbackCells(Handle<Code> code) {
if (type_feedback_cells_.is_empty()) return;
int length = type_feedback_cells_.length();
@@ -389,7 +404,7 @@ void FullCodeGenerator::PopulateTypeFeedbackCells(Handle<Code> code) {
Handle<TypeFeedbackCells> cache = Handle<TypeFeedbackCells>::cast(
isolate()->factory()->NewFixedArray(array_size, TENURED));
for (int i = 0; i < length; i++) {
- cache->SetAstId(i, Smi::FromInt(type_feedback_cells_[i].ast_id));
+ cache->SetAstId(i, type_feedback_cells_[i].ast_id);
cache->SetCell(i, *type_feedback_cells_[i].cell);
}
TypeFeedbackInfo::cast(code->type_feedback_info())->set_type_feedback_cells(
@@ -420,7 +435,7 @@ void FullCodeGenerator::RecordJSReturnSite(Call* call) {
}
-void FullCodeGenerator::PrepareForBailoutForId(unsigned id, State state) {
+void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, State state) {
// There's no need to prepare this code for bailouts from already optimized
// code or code that can't be optimized.
if (!info_->HasDeoptimizationSupport()) return;
@@ -445,13 +460,13 @@ void FullCodeGenerator::PrepareForBailoutForId(unsigned id, State state) {
void FullCodeGenerator::RecordTypeFeedbackCell(
- unsigned id, Handle<JSGlobalPropertyCell> cell) {
+ TypeFeedbackId id, Handle<JSGlobalPropertyCell> cell) {
TypeFeedbackCellEntry entry = { id, cell };
type_feedback_cells_.Add(entry, zone());
}
-void FullCodeGenerator::RecordStackCheck(unsigned ast_id) {
+void FullCodeGenerator::RecordStackCheck(BailoutId ast_id) {
// The pc offset does not need to be encoded and packed together with a
// state.
ASSERT(masm_->pc_offset() > 0);
@@ -589,27 +604,20 @@ void FullCodeGenerator::VisitDeclarations(
void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
- Handle<JSModule> instance = module->interface()->Instance();
- ASSERT(!instance.is_null());
-
// Allocate a module context statically.
Block* block = module->body();
Scope* saved_scope = scope();
scope_ = block->scope();
- Handle<ScopeInfo> scope_info = scope_->GetScopeInfo();
+ Interface* interface = module->interface();
+ Handle<JSModule> instance = interface->Instance();
- // Generate code for module creation and linking.
Comment cmnt(masm_, "[ ModuleLiteral");
SetStatementPosition(block);
- if (scope_info->HasContext()) {
- // Set up module context.
- __ Push(scope_info);
- __ Push(instance);
- __ CallRuntime(Runtime::kPushModuleContext, 2);
- StoreToFrameField(
- StandardFrameConstants::kContextOffset, context_register());
- }
+ // Set up module context.
+ __ Push(instance);
+ __ CallRuntime(Runtime::kPushModuleContext, 1);
+ StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
{
Comment cmnt(masm_, "[ Declarations");
@@ -617,42 +625,21 @@ void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
}
scope_ = saved_scope;
- if (scope_info->HasContext()) {
- // Pop module context.
- LoadContextField(context_register(), Context::PREVIOUS_INDEX);
- // Update local stack frame context field.
- StoreToFrameField(
- StandardFrameConstants::kContextOffset, context_register());
- }
-
- // Populate module instance object.
- const PropertyAttributes attr =
- static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE | DONT_ENUM);
- for (Interface::Iterator it = module->interface()->iterator();
- !it.done(); it.Advance()) {
- if (it.interface()->IsModule()) {
- Handle<Object> value = it.interface()->Instance();
- ASSERT(!value.is_null());
- JSReceiver::SetProperty(instance, it.name(), value, attr, kStrictMode);
- } else {
- // TODO(rossberg): set proper getters instead of undefined...
- // instance->DefineAccessor(*it.name(), ACCESSOR_GETTER, *getter, attr);
- Handle<Object> value(isolate()->heap()->undefined_value());
- JSReceiver::SetProperty(instance, it.name(), value, attr, kStrictMode);
- }
- }
- USE(instance->PreventExtensions());
+ // Pop module context.
+ LoadContextField(context_register(), Context::PREVIOUS_INDEX);
+ // Update local stack frame context field.
+ StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
}
void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) {
- // Noting to do.
+ // Nothing to do.
// The instance object is resolved statically through the module's interface.
}
void FullCodeGenerator::VisitModulePath(ModulePath* module) {
- // Noting to do.
+ // Nothing to do.
// The instance object is resolved statically through the module's interface.
}
@@ -822,7 +809,7 @@ void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) {
Comment cmnt(masm_, is_logical_and ? "[ Logical AND" : "[ Logical OR");
Expression* left = expr->left();
Expression* right = expr->right();
- int right_id = expr->RightId();
+ BailoutId right_id = expr->RightId();
Label done;
if (context()->IsTest()) {
@@ -916,25 +903,36 @@ void FullCodeGenerator::VisitBlock(Block* stmt) {
Scope* saved_scope = scope();
// Push a block context when entering a block with block scoped variables.
if (stmt->scope() != NULL) {
- { Comment cmnt(masm_, "[ Extend block context");
- scope_ = stmt->scope();
- Handle<ScopeInfo> scope_info = scope_->GetScopeInfo();
- int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS;
- __ Push(scope_info);
- PushFunctionArgumentForContextAllocation();
- if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) {
- FastNewBlockContextStub stub(heap_slots);
- __ CallStub(&stub);
- } else {
- __ CallRuntime(Runtime::kPushBlockContext, 2);
+ scope_ = stmt->scope();
+ if (scope_->is_module_scope()) {
+ // If this block is a module body, then we have already allocated and
+ // initialized the declarations earlier. Just push the context.
+ ASSERT(!scope_->interface()->Instance().is_null());
+ __ Push(scope_->interface()->Instance());
+ __ CallRuntime(Runtime::kPushModuleContext, 1);
+ StoreToFrameField(
+ StandardFrameConstants::kContextOffset, context_register());
+ } else {
+ { Comment cmnt(masm_, "[ Extend block context");
+ Handle<ScopeInfo> scope_info = scope_->GetScopeInfo();
+ int heap_slots =
+ scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS;
+ __ Push(scope_info);
+ PushFunctionArgumentForContextAllocation();
+ if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) {
+ FastNewBlockContextStub stub(heap_slots);
+ __ CallStub(&stub);
+ } else {
+ __ CallRuntime(Runtime::kPushBlockContext, 2);
+ }
+
+ // Replace the context stored in the frame.
+ StoreToFrameField(StandardFrameConstants::kContextOffset,
+ context_register());
+ }
+ { Comment cmnt(masm_, "[ Declarations");
+ VisitDeclarations(scope_->declarations());
}
-
- // Replace the context stored in the frame.
- StoreToFrameField(StandardFrameConstants::kContextOffset,
- context_register());
- }
- { Comment cmnt(masm_, "[ Declarations");
- VisitDeclarations(scope_->declarations());
}
}
PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
diff --git a/deps/v8/src/full-codegen.h b/deps/v8/src/full-codegen.h
index 928de47b3..89b51f958 100644
--- a/deps/v8/src/full-codegen.h
+++ b/deps/v8/src/full-codegen.h
@@ -77,8 +77,7 @@ class FullCodeGenerator: public AstVisitor {
TOS_REG
};
- FullCodeGenerator(MacroAssembler* masm, CompilationInfo* info,
- Zone* zone)
+ FullCodeGenerator(MacroAssembler* masm, CompilationInfo* info)
: masm_(masm),
info_(info),
scope_(info->scope()),
@@ -87,12 +86,18 @@ class FullCodeGenerator: public AstVisitor {
globals_(NULL),
context_(NULL),
bailout_entries_(info->HasDeoptimizationSupport()
- ? info->function()->ast_node_count() : 0, zone),
- stack_checks_(2, zone), // There's always at least one.
+ ? info->function()->ast_node_count() : 0,
+ info->zone()),
+ stack_checks_(2, info->zone()), // There's always at least one.
type_feedback_cells_(info->HasDeoptimizationSupport()
- ? info->function()->ast_node_count() : 0, zone),
+ ? info->function()->ast_node_count() : 0,
+ info->zone()),
ic_total_count_(0),
- zone_(zone) { }
+ zone_(info->zone()) {
+ Initialize();
+ }
+
+ void Initialize();
static bool MakeCode(CompilationInfo* info);
@@ -112,6 +117,21 @@ class FullCodeGenerator: public AstVisitor {
Zone* zone() const { return zone_; }
+ static const int kMaxBackEdgeWeight = 127;
+
+#if V8_TARGET_ARCH_IA32
+ static const int kBackEdgeDistanceUnit = 100;
+#elif V8_TARGET_ARCH_X64
+ static const int kBackEdgeDistanceUnit = 162;
+#elif V8_TARGET_ARCH_ARM
+ static const int kBackEdgeDistanceUnit = 142;
+#elif V8_TARGET_ARCH_MIPS
+ static const int kBackEdgeDistanceUnit = 142;
+#else
+#error Unsupported target architecture.
+#endif
+
+
private:
class Breakable;
class Iteration;
@@ -397,11 +417,12 @@ class FullCodeGenerator: public AstVisitor {
// Bailout support.
void PrepareForBailout(Expression* node, State state);
- void PrepareForBailoutForId(unsigned id, State state);
+ void PrepareForBailoutForId(BailoutId id, State state);
// Cache cell support. This associates AST ids with global property cells
// that will be cleared during GC and collected by the type-feedback oracle.
- void RecordTypeFeedbackCell(unsigned id, Handle<JSGlobalPropertyCell> cell);
+ void RecordTypeFeedbackCell(TypeFeedbackId id,
+ Handle<JSGlobalPropertyCell> cell);
// Record a call's return site offset, used to rebuild the frame if the
// called function was inlined at the site.
@@ -428,7 +449,7 @@ class FullCodeGenerator: public AstVisitor {
// of code inside the loop.
void EmitStackCheck(IterationStatement* stmt, Label* back_edge_target);
// Record the OSR AST id corresponding to a stack check in the code.
- void RecordStackCheck(unsigned osr_ast_id);
+ void RecordStackCheck(BailoutId osr_ast_id);
// Emit a table of stack check ids and pcs into the code stream. Return
// the offset of the start of the table.
unsigned EmitStackCheckTable();
@@ -519,7 +540,7 @@ class FullCodeGenerator: public AstVisitor {
void CallIC(Handle<Code> code,
RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
- unsigned ast_id = kNoASTId);
+ TypeFeedbackId id = TypeFeedbackId::None());
void SetFunctionPosition(FunctionLiteral* fun);
void SetReturnPosition(FunctionLiteral* fun);
@@ -590,12 +611,12 @@ class FullCodeGenerator: public AstVisitor {
Handle<FixedArray> handler_table() { return handler_table_; }
struct BailoutEntry {
- unsigned id;
+ BailoutId id;
unsigned pc_and_state;
};
struct TypeFeedbackCellEntry {
- unsigned ast_id;
+ TypeFeedbackId ast_id;
Handle<JSGlobalPropertyCell> cell;
};
@@ -790,6 +811,7 @@ class FullCodeGenerator: public AstVisitor {
int ic_total_count_;
Handle<FixedArray> handler_table_;
Handle<JSGlobalPropertyCell> profiling_counter_;
+ bool generate_debug_code_;
Zone* zone_;
friend class NestedStatement;
diff --git a/deps/v8/src/gdb-jit.cc b/deps/v8/src/gdb-jit.cc
index d3cd44707..dde6bbdaa 100644
--- a/deps/v8/src/gdb-jit.cc
+++ b/deps/v8/src/gdb-jit.cc
@@ -31,11 +31,13 @@
#include "bootstrapper.h"
#include "compiler.h"
+#include "frames.h"
+#include "frames-inl.h"
#include "global-handles.h"
#include "messages.h"
-#include "platform.h"
#include "natives.h"
-#include "scopeinfo.h"
+#include "platform.h"
+#include "scopes.h"
namespace v8 {
namespace internal {
@@ -194,7 +196,7 @@ class DebugSectionBase : public ZoneObject {
virtual void WriteBody(Writer::Slot<THeader> header, Writer* writer) {
uintptr_t start = writer->position();
- if (WriteBody(writer)) {
+ if (WriteBodyInternal(writer)) {
uintptr_t end = writer->position();
header->offset = start;
#if defined(__MACH_O)
@@ -204,7 +206,7 @@ class DebugSectionBase : public ZoneObject {
}
}
- virtual bool WriteBody(Writer* writer) {
+ virtual bool WriteBodyInternal(Writer* writer) {
return false;
}
@@ -340,14 +342,14 @@ class ELFSection : public DebugSectionBase<ELFSectionHeader> {
virtual void WriteBody(Writer::Slot<Header> header, Writer* w) {
uintptr_t start = w->position();
- if (WriteBody(w)) {
+ if (WriteBodyInternal(w)) {
uintptr_t end = w->position();
header->offset = start;
header->size = end - start;
}
}
- virtual bool WriteBody(Writer* w) {
+ virtual bool WriteBodyInternal(Writer* w) {
return false;
}
@@ -627,9 +629,9 @@ class MachO BASE_EMBEDDED {
#if defined(__ELF)
class ELF BASE_EMBEDDED {
public:
- ELF() : sections_(6) {
- sections_.Add(new ELFSection("", ELFSection::TYPE_NULL, 0));
- sections_.Add(new StringTable(".shstrtab"));
+ ELF(Zone* zone) : sections_(6, zone) {
+ sections_.Add(new(zone) ELFSection("", ELFSection::TYPE_NULL, 0), zone);
+ sections_.Add(new(zone) StringTable(".shstrtab"), zone);
}
void Write(Writer* w) {
@@ -642,8 +644,8 @@ class ELF BASE_EMBEDDED {
return sections_[index];
}
- uint32_t AddSection(ELFSection* section) {
- sections_.Add(section);
+ uint32_t AddSection(ELFSection* section, Zone* zone) {
+ sections_.Add(section, zone);
section->set_index(sections_.length() - 1);
return sections_.length() - 1;
}
@@ -675,7 +677,7 @@ class ELF BASE_EMBEDDED {
{ 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#elif defined(V8_TARGET_ARCH_X64)
const uint8_t ident[16] =
- { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0 , 0, 0, 0, 0, 0, 0};
+ { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#else
#error Unsupported target architecture.
#endif
@@ -852,10 +854,10 @@ class ELFSymbol BASE_EMBEDDED {
class ELFSymbolTable : public ELFSection {
public:
- explicit ELFSymbolTable(const char* name)
+ ELFSymbolTable(const char* name, Zone* zone)
: ELFSection(name, TYPE_SYMTAB, sizeof(uintptr_t)),
- locals_(1),
- globals_(1) {
+ locals_(1, zone),
+ globals_(1, zone) {
}
virtual void WriteBody(Writer::Slot<Header> header, Writer* w) {
@@ -883,11 +885,11 @@ class ELFSymbolTable : public ELFSection {
strtab->DetachWriter();
}
- void Add(const ELFSymbol& symbol) {
+ void Add(const ELFSymbol& symbol, Zone* zone) {
if (symbol.binding() == ELFSymbol::BIND_LOCAL) {
- locals_.Add(symbol);
+ locals_.Add(symbol, zone);
} else {
- globals_.Add(symbol);
+ globals_.Add(symbol, zone);
}
}
@@ -1019,26 +1021,29 @@ class CodeDescription BASE_EMBEDDED {
static void CreateSymbolsTable(CodeDescription* desc,
ELF* elf,
int text_section_index) {
- ELFSymbolTable* symtab = new ELFSymbolTable(".symtab");
- StringTable* strtab = new StringTable(".strtab");
+ Zone* zone = desc->info()->zone();
+ ELFSymbolTable* symtab = new(zone) ELFSymbolTable(".symtab", zone);
+ StringTable* strtab = new(zone) StringTable(".strtab");
// Symbol table should be followed by the linked string table.
- elf->AddSection(symtab);
- elf->AddSection(strtab);
+ elf->AddSection(symtab, zone);
+ elf->AddSection(strtab, zone);
symtab->Add(ELFSymbol("V8 Code",
0,
0,
ELFSymbol::BIND_LOCAL,
ELFSymbol::TYPE_FILE,
- ELFSection::INDEX_ABSOLUTE));
+ ELFSection::INDEX_ABSOLUTE),
+ zone);
symtab->Add(ELFSymbol(desc->name(),
0,
desc->CodeSize(),
ELFSymbol::BIND_GLOBAL,
ELFSymbol::TYPE_FUNC,
- text_section_index));
+ text_section_index),
+ zone);
}
#endif // defined(__ELF)
@@ -1074,7 +1079,7 @@ class DebugInfoSection : public DebugSection {
DW_ATE_SIGNED = 0x5
};
- bool WriteBody(Writer* w) {
+ bool WriteBodyInternal(Writer* w) {
uintptr_t cu_start = w->position();
Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>();
uintptr_t start = w->position();
@@ -1094,8 +1099,7 @@ class DebugInfoSection : public DebugSection {
w->WriteString("v8value");
if (desc_->IsInfoAvailable()) {
- CompilationInfo* info = desc_->info();
- ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope());
+ Scope* scope = desc_->info()->scope();
w->WriteULEB128(2);
w->WriteString(desc_->name());
w->Write<intptr_t>(desc_->CodeStart());
@@ -1106,23 +1110,27 @@ class DebugInfoSection : public DebugSection {
w->Write<uint8_t>(DW_OP_reg5); // The frame pointer's here on ia32
#elif defined(V8_TARGET_ARCH_X64)
w->Write<uint8_t>(DW_OP_reg6); // and here on x64.
+#elif defined(V8_TARGET_ARCH_ARM)
+ UNIMPLEMENTED();
+#elif defined(V8_TARGET_ARCH_MIPS)
+ UNIMPLEMENTED();
#else
#error Unsupported target architecture.
#endif
fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start));
- int params = scope_info.number_of_parameters();
- int slots = scope_info.number_of_stack_slots();
- int context_slots = scope_info.number_of_context_slots();
+ int params = scope->num_parameters();
+ int slots = scope->num_stack_slots();
+ int context_slots = scope->ContextLocalCount();
// The real slot ID is internal_slots + context_slot_id.
int internal_slots = Context::MIN_CONTEXT_SLOTS;
- int locals = scope_info.LocalCount();
+ int locals = scope->StackLocalCount();
int current_abbreviation = 4;
for (int param = 0; param < params; ++param) {
w->WriteULEB128(current_abbreviation++);
w->WriteString(
- *scope_info.ParameterName(param)->ToCString(DISALLOW_NULLS));
+ *scope->parameter(param)->name()->ToCString(DISALLOW_NULLS));
w->Write<uint32_t>(ty_offset);
Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
uintptr_t block_start = w->position();
@@ -1148,7 +1156,7 @@ class DebugInfoSection : public DebugSection {
ASSERT(Context::CLOSURE_INDEX == 0);
ASSERT(Context::PREVIOUS_INDEX == 1);
ASSERT(Context::EXTENSION_INDEX == 2);
- ASSERT(Context::GLOBAL_INDEX == 3);
+ ASSERT(Context::GLOBAL_OBJECT_INDEX == 3);
w->WriteULEB128(current_abbreviation++);
w->WriteString(".closure");
w->WriteULEB128(current_abbreviation++);
@@ -1167,10 +1175,13 @@ class DebugInfoSection : public DebugSection {
w->WriteString(builder.Finalize());
}
+ ZoneList<Variable*> stack_locals(locals, scope->zone());
+ ZoneList<Variable*> context_locals(context_slots, scope->zone());
+ scope->CollectStackAndContextLocals(&stack_locals, &context_locals);
for (int local = 0; local < locals; ++local) {
w->WriteULEB128(current_abbreviation++);
w->WriteString(
- *scope_info.LocalName(local)->ToCString(DISALLOW_NULLS));
+ *stack_locals[local]->name()->ToCString(DISALLOW_NULLS));
w->Write<uint32_t>(ty_offset);
Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
uintptr_t block_start = w->position();
@@ -1287,7 +1298,7 @@ class DebugAbbrevSection : public DebugSection {
w->WriteULEB128(0);
}
- bool WriteBody(Writer* w) {
+ bool WriteBodyInternal(Writer* w) {
int current_abbreviation = 1;
bool extra_info = desc_->IsInfoAvailable();
ASSERT(desc_->IsLineInfoAvailable());
@@ -1306,14 +1317,13 @@ class DebugAbbrevSection : public DebugSection {
w->WriteULEB128(0);
if (extra_info) {
- CompilationInfo* info = desc_->info();
- ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope());
- int params = scope_info.number_of_parameters();
- int slots = scope_info.number_of_stack_slots();
- int context_slots = scope_info.number_of_context_slots();
+ Scope* scope = desc_->info()->scope();
+ int params = scope->num_parameters();
+ int slots = scope->num_stack_slots();
+ int context_slots = scope->ContextLocalCount();
// The real slot ID is internal_slots + context_slot_id.
int internal_slots = Context::MIN_CONTEXT_SLOTS;
- int locals = scope_info.LocalCount();
+ int locals = scope->StackLocalCount();
int total_children =
params + slots + context_slots + internal_slots + locals + 2;
@@ -1418,7 +1428,7 @@ class DebugLineSection : public DebugSection {
DW_LNE_DEFINE_FILE = 3
};
- bool WriteBody(Writer* w) {
+ bool WriteBodyInternal(Writer* w) {
// Write prologue.
Writer::Slot<uint32_t> total_length = w->CreateSlotHere<uint32_t>();
uintptr_t start = w->position();
@@ -1558,7 +1568,7 @@ class DebugLineSection : public DebugSection {
class UnwindInfoSection : public DebugSection {
public:
explicit UnwindInfoSection(CodeDescription* desc);
- virtual bool WriteBody(Writer* w);
+ virtual bool WriteBodyInternal(Writer* w);
int WriteCIE(Writer* w);
void WriteFDE(Writer* w, int);
@@ -1770,7 +1780,7 @@ void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer* w) {
}
-bool UnwindInfoSection::WriteBody(Writer* w) {
+bool UnwindInfoSection::WriteBodyInternal(Writer* w) {
uint32_t cie_position = WriteCIE(w);
WriteFDE(w, cie_position);
return true;
@@ -1780,13 +1790,14 @@ bool UnwindInfoSection::WriteBody(Writer* w) {
#endif // V8_TARGET_ARCH_X64
static void CreateDWARFSections(CodeDescription* desc, DebugObject* obj) {
+ Zone* zone = desc->info()->zone();
if (desc->IsLineInfoAvailable()) {
- obj->AddSection(new DebugInfoSection(desc));
- obj->AddSection(new DebugAbbrevSection(desc));
- obj->AddSection(new DebugLineSection(desc));
+ obj->AddSection(new(zone) DebugInfoSection(desc), zone);
+ obj->AddSection(new(zone) DebugAbbrevSection(desc), zone);
+ obj->AddSection(new(zone) DebugLineSection(desc), zone);
}
#ifdef V8_TARGET_ARCH_X64
- obj->AddSection(new UnwindInfoSection(desc));
+ obj->AddSection(new(zone) UnwindInfoSection(desc), zone);
#endif
}
@@ -1905,7 +1916,8 @@ static void UnregisterCodeEntry(JITCodeEntry* entry) {
static JITCodeEntry* CreateELFObject(CodeDescription* desc) {
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ Zone* zone = desc->info()->zone();
+ ZoneScope zone_scope(zone, DELETE_ON_EXIT);
#ifdef __MACH_O
MachO mach_o;
Writer w(&mach_o);
@@ -1918,17 +1930,19 @@ static JITCodeEntry* CreateELFObject(CodeDescription* desc) {
mach_o.Write(&w, desc->CodeStart(), desc->CodeSize());
#else
- ELF elf;
+ ELF elf(zone);
Writer w(&elf);
int text_section_index = elf.AddSection(
- new FullHeaderELFSection(".text",
- ELFSection::TYPE_NOBITS,
- kCodeAlignment,
- desc->CodeStart(),
- 0,
- desc->CodeSize(),
- ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC));
+ new(zone) FullHeaderELFSection(
+ ".text",
+ ELFSection::TYPE_NOBITS,
+ kCodeAlignment,
+ desc->CodeStart(),
+ 0,
+ desc->CodeSize(),
+ ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC),
+ zone);
CreateSymbolsTable(desc, &elf, text_section_index);
diff --git a/deps/v8/src/global-handles.cc b/deps/v8/src/global-handles.cc
index 9c0ad4517..c09ba4b47 100644
--- a/deps/v8/src/global-handles.cc
+++ b/deps/v8/src/global-handles.cc
@@ -448,6 +448,11 @@ void GlobalHandles::MarkIndependent(Object** location) {
}
+bool GlobalHandles::IsIndependent(Object** location) {
+ return Node::FromLocation(location)->is_independent();
+}
+
+
bool GlobalHandles::IsNearDeath(Object** location) {
return Node::FromLocation(location)->IsNearDeath();
}
@@ -462,6 +467,9 @@ void GlobalHandles::SetWrapperClassId(Object** location, uint16_t class_id) {
Node::FromLocation(location)->set_wrapper_class_id(class_id);
}
+uint16_t GlobalHandles::GetWrapperClassId(Object** location) {
+ return Node::FromLocation(location)->wrapper_class_id();
+}
void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
for (NodeIterator it(this); !it.done(); it.Advance()) {
diff --git a/deps/v8/src/global-handles.h b/deps/v8/src/global-handles.h
index ddf5fe29c..866317ee1 100644
--- a/deps/v8/src/global-handles.h
+++ b/deps/v8/src/global-handles.h
@@ -131,6 +131,7 @@ class GlobalHandles {
WeakReferenceCallback callback);
static void SetWrapperClassId(Object** location, uint16_t class_id);
+ static uint16_t GetWrapperClassId(Object** location);
// Returns the current number of weak handles.
int NumberOfWeakHandles() { return number_of_weak_handles_; }
@@ -154,6 +155,8 @@ class GlobalHandles {
// Clear the weakness of a global handle.
void MarkIndependent(Object** location);
+ static bool IsIndependent(Object** location);
+
// Tells whether global handle is near death.
static bool IsNearDeath(Object** location);
diff --git a/deps/v8/src/globals.h b/deps/v8/src/globals.h
index 97b033f84..babffbf65 100644
--- a/deps/v8/src/globals.h
+++ b/deps/v8/src/globals.h
@@ -136,21 +136,6 @@ namespace internal {
#endif
#endif
-// Define unaligned read for the target architectures supporting it.
-#if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_IA32)
-#define V8_TARGET_CAN_READ_UNALIGNED 1
-#elif V8_TARGET_ARCH_ARM
-// Some CPU-OS combinations allow unaligned access on ARM. We assume
-// that unaligned accesses are not allowed unless the build system
-// defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero.
-#if CAN_USE_UNALIGNED_ACCESSES
-#define V8_TARGET_CAN_READ_UNALIGNED 1
-#endif
-#elif V8_TARGET_ARCH_MIPS
-#else
-#error Target architecture is not supported by v8
-#endif
-
// Support for alternative bool type. This is only enabled if the code is
// compiled with USE_MYBOOL defined. This catches some nasty type bugs.
// For instance, 'bool b = "false";' results in b == true! This is a hidden
@@ -203,6 +188,7 @@ typedef byte* Address;
#define V8PRIxPTR V8_PTR_PREFIX "x"
#define V8PRIdPTR V8_PTR_PREFIX "d"
+#define V8PRIuPTR V8_PTR_PREFIX "u"
// Fix for Mac OS X defining uintptr_t as "unsigned long":
#if defined(__APPLE__) && defined(__MACH__)
@@ -360,6 +346,20 @@ F FUNCTION_CAST(Address addr) {
#define MUST_USE_RESULT
#endif
+
+// Define DISABLE_ASAN macros.
+#if defined(__has_feature)
+#if __has_feature(address_sanitizer)
+#define DISABLE_ASAN __attribute__((no_address_safety_analysis))
+#endif
+#endif
+
+
+#ifndef DISABLE_ASAN
+#define DISABLE_ASAN
+#endif
+
+
// -----------------------------------------------------------------------------
// Forward declarations for frequently used classes
// (sorted alphabetically)
diff --git a/deps/v8/src/handles-inl.h b/deps/v8/src/handles-inl.h
index a5c81cec5..130798647 100644
--- a/deps/v8/src/handles-inl.h
+++ b/deps/v8/src/handles-inl.h
@@ -149,25 +149,31 @@ T** HandleScope::CreateHandle(T* value, Isolate* isolate) {
#ifdef DEBUG
inline NoHandleAllocation::NoHandleAllocation() {
+ Isolate* isolate = Isolate::Current();
v8::ImplementationUtilities::HandleScopeData* current =
- Isolate::Current()->handle_scope_data();
+ isolate->handle_scope_data();
- // Shrink the current handle scope to make it impossible to do
- // handle allocations without an explicit handle scope.
- current->limit = current->next;
+ active_ = !isolate->optimizing_compiler_thread()->IsOptimizerThread();
+ if (active_) {
+ // Shrink the current handle scope to make it impossible to do
+ // handle allocations without an explicit handle scope.
+ current->limit = current->next;
- level_ = current->level;
- current->level = 0;
+ level_ = current->level;
+ current->level = 0;
+ }
}
inline NoHandleAllocation::~NoHandleAllocation() {
- // Restore state in current handle scope to re-enable handle
- // allocations.
- v8::ImplementationUtilities::HandleScopeData* data =
- Isolate::Current()->handle_scope_data();
- ASSERT_EQ(0, data->level);
- data->level = level_;
+ if (active_) {
+ // Restore state in current handle scope to re-enable handle
+ // allocations.
+ v8::ImplementationUtilities::HandleScopeData* data =
+ Isolate::Current()->handle_scope_data();
+ ASSERT_EQ(0, data->level);
+ data->level = level_;
+ }
}
#endif
diff --git a/deps/v8/src/handles.cc b/deps/v8/src/handles.cc
index def1604ac..46399d65e 100644
--- a/deps/v8/src/handles.cc
+++ b/deps/v8/src/handles.cc
@@ -165,7 +165,7 @@ void SetExpectedNofProperties(Handle<JSFunction> func, int nof) {
func->shared()->set_expected_nof_properties(nof);
if (func->has_initial_map()) {
Handle<Map> new_initial_map =
- func->GetIsolate()->factory()->CopyMapDropTransitions(
+ func->GetIsolate()->factory()->CopyMap(
Handle<Map>(func->initial_map()));
new_initial_map->set_unused_property_fields(nof);
func->set_initial_map(*new_initial_map);
@@ -561,6 +561,9 @@ v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSReceiver> receiver,
result = enum_fun(info);
}
}
+#if ENABLE_EXTRA_CHECKS
+ CHECK(result.IsEmpty() || v8::Utils::OpenHandle(*result)->IsJSObject());
+#endif
return result;
}
@@ -581,6 +584,9 @@ v8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSReceiver> receiver,
// Leaving JavaScript.
VMState state(isolate, EXTERNAL);
result = enum_fun(info);
+#if ENABLE_EXTRA_CHECKS
+ CHECK(result.IsEmpty() || v8::Utils::OpenHandle(*result)->IsJSObject());
+#endif
}
}
return result;
@@ -604,7 +610,7 @@ Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
Isolate* isolate = object->GetIsolate();
Handle<FixedArray> content = isolate->factory()->empty_fixed_array();
Handle<JSObject> arguments_boilerplate = Handle<JSObject>(
- isolate->context()->global_context()->arguments_boilerplate(),
+ isolate->context()->native_context()->arguments_boilerplate(),
isolate);
Handle<JSFunction> arguments_function = Handle<JSFunction>(
JSFunction::cast(arguments_boilerplate->map()->constructor()),
@@ -699,77 +705,134 @@ Handle<JSArray> GetKeysFor(Handle<JSReceiver> object, bool* threw) {
}
+Handle<FixedArray> ReduceFixedArrayTo(Handle<FixedArray> array, int length) {
+ ASSERT(array->length() >= length);
+ if (array->length() == length) return array;
+
+ Handle<FixedArray> new_array =
+ array->GetIsolate()->factory()->NewFixedArray(length);
+ for (int i = 0; i < length; ++i) new_array->set(i, array->get(i));
+ return new_array;
+}
+
+
Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
bool cache_result) {
- int index = 0;
Isolate* isolate = object->GetIsolate();
if (object->HasFastProperties()) {
if (object->map()->instance_descriptors()->HasEnumCache()) {
- isolate->counters()->enum_cache_hits()->Increment();
+ int own_property_count = object->map()->EnumLength();
+ // If we have an enum cache, but the enum length of the given map is set
+ // to kInvalidEnumCache, this means that the map itself has never used the
+ // present enum cache. The first step to using the cache is to set the
+ // enum length of the map by counting the number of own descriptors that
+ // are not DONT_ENUM.
+ if (own_property_count == Map::kInvalidEnumCache) {
+ own_property_count = object->map()->NumberOfDescribedProperties(
+ OWN_DESCRIPTORS, DONT_ENUM);
+
+ if (cache_result) object->map()->SetEnumLength(own_property_count);
+ }
+
DescriptorArray* desc = object->map()->instance_descriptors();
- return Handle<FixedArray>(FixedArray::cast(desc->GetEnumCache()),
- isolate);
+ Handle<FixedArray> keys(desc->GetEnumCache(), isolate);
+
+ // In case the number of properties required in the enum are actually
+ // present, we can reuse the enum cache. Otherwise, this means that the
+ // enum cache was generated for a previous (smaller) version of the
+ // Descriptor Array. In that case we regenerate the enum cache.
+ if (own_property_count <= keys->length()) {
+ isolate->counters()->enum_cache_hits()->Increment();
+ return ReduceFixedArrayTo(keys, own_property_count);
+ }
}
- isolate->counters()->enum_cache_misses()->Increment();
+
Handle<Map> map(object->map());
- int num_enum = object->NumberOfLocalProperties(DONT_ENUM);
- Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum);
- Handle<FixedArray> sort_array = isolate->factory()->NewFixedArray(num_enum);
+ if (map->instance_descriptors()->IsEmpty()) {
+ isolate->counters()->enum_cache_hits()->Increment();
+ if (cache_result) map->SetEnumLength(0);
+ return isolate->factory()->empty_fixed_array();
+ }
- Handle<FixedArray> indices;
- Handle<FixedArray> sort_array2;
+ isolate->counters()->enum_cache_misses()->Increment();
+ int num_enum = map->NumberOfDescribedProperties(ALL_DESCRIPTORS, DONT_ENUM);
- if (cache_result) {
- indices = isolate->factory()->NewFixedArray(num_enum);
- sort_array2 = isolate->factory()->NewFixedArray(num_enum);
- }
+ Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum);
+ Handle<FixedArray> indices = isolate->factory()->NewFixedArray(num_enum);
Handle<DescriptorArray> descs =
Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate);
+ int real_size = map->NumberOfOwnDescriptors();
+ int enum_size = 0;
+ int index = 0;
+
for (int i = 0; i < descs->number_of_descriptors(); i++) {
- if (descs->IsProperty(i) && !descs->GetDetails(i).IsDontEnum()) {
+ PropertyDetails details = descs->GetDetails(i);
+ if (!details.IsDontEnum()) {
+ if (i < real_size) ++enum_size;
storage->set(index, descs->GetKey(i));
- PropertyDetails details = descs->GetDetails(i);
- sort_array->set(index, Smi::FromInt(details.index()));
if (!indices.is_null()) {
if (details.type() != FIELD) {
indices = Handle<FixedArray>();
- sort_array2 = Handle<FixedArray>();
} else {
int field_index = Descriptor::IndexFromValue(descs->GetValue(i));
if (field_index >= map->inobject_properties()) {
field_index = -(field_index - map->inobject_properties() + 1);
}
indices->set(index, Smi::FromInt(field_index));
- sort_array2->set(index, Smi::FromInt(details.index()));
}
}
index++;
}
}
- storage->SortPairs(*sort_array, sort_array->length());
- if (!indices.is_null()) {
- indices->SortPairs(*sort_array2, sort_array2->length());
- }
+ ASSERT(index == storage->length());
+
+ Handle<FixedArray> bridge_storage =
+ isolate->factory()->NewFixedArray(
+ DescriptorArray::kEnumCacheBridgeLength);
+ DescriptorArray* desc = object->map()->instance_descriptors();
+ desc->SetEnumCache(*bridge_storage,
+ *storage,
+ indices.is_null() ? Object::cast(Smi::FromInt(0))
+ : Object::cast(*indices));
if (cache_result) {
- Handle<FixedArray> bridge_storage =
- isolate->factory()->NewFixedArray(
- DescriptorArray::kEnumCacheBridgeLength);
- DescriptorArray* desc = object->map()->instance_descriptors();
- desc->SetEnumCache(*bridge_storage,
- *storage,
- indices.is_null() ? Object::cast(Smi::FromInt(0))
- : Object::cast(*indices));
+ object->map()->SetEnumLength(enum_size);
}
- ASSERT(storage->length() == index);
- return storage;
+
+ return ReduceFixedArrayTo(storage, enum_size);
} else {
- int num_enum = object->NumberOfLocalProperties(DONT_ENUM);
- Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum);
- Handle<FixedArray> sort_array = isolate->factory()->NewFixedArray(num_enum);
- object->property_dictionary()->CopyEnumKeysTo(*storage, *sort_array);
+ Handle<StringDictionary> dictionary(object->property_dictionary());
+
+ int length = dictionary->NumberOfElements();
+ if (length == 0) {
+ return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
+ }
+
+ // The enumeration array is generated by allocating an array big enough to
+ // hold all properties that have been seen, whether they are are deleted or
+ // not. Subsequently all visible properties are added to the array. If some
+ // properties were not visible, the array is trimmed so it only contains
+ // visible properties. This improves over adding elements and sorting by
+ // index by having linear complexity rather than n*log(n).
+
+ // By comparing the monotonous NextEnumerationIndex to the NumberOfElements,
+ // we can predict the number of holes in the final array. If there will be
+ // more than 50% holes, regenerate the enumeration indices to reduce the
+ // number of holes to a minimum. This avoids allocating a large array if
+ // many properties were added but subsequently deleted.
+ int next_enumeration = dictionary->NextEnumerationIndex();
+ if (!object->IsGlobalObject() && next_enumeration > (length * 3) / 2) {
+ StringDictionary::DoGenerateNewEnumerationIndices(dictionary);
+ next_enumeration = dictionary->NextEnumerationIndex();
+ }
+
+ Handle<FixedArray> storage =
+ isolate->factory()->NewFixedArray(next_enumeration);
+
+ storage = Handle<FixedArray>(dictionary->CopyEnumKeysTo(*storage));
+ ASSERT(storage->length() == object->NumberOfLocalProperties(DONT_ENUM));
return storage;
}
}
@@ -958,4 +1021,47 @@ int Utf8Length(Handle<String> str) {
return len;
}
+
+DeferredHandleScope::DeferredHandleScope(Isolate* isolate)
+ : impl_(isolate->handle_scope_implementer()) {
+ ASSERT(impl_->isolate() == Isolate::Current());
+ impl_->BeginDeferredScope();
+ v8::ImplementationUtilities::HandleScopeData* data =
+ impl_->isolate()->handle_scope_data();
+ Object** new_next = impl_->GetSpareOrNewBlock();
+ Object** new_limit = &new_next[kHandleBlockSize];
+ ASSERT(data->limit == &impl_->blocks()->last()[kHandleBlockSize]);
+ impl_->blocks()->Add(new_next);
+
+#ifdef DEBUG
+ prev_level_ = data->level;
+#endif
+ data->level++;
+ prev_limit_ = data->limit;
+ prev_next_ = data->next;
+ data->next = new_next;
+ data->limit = new_limit;
+}
+
+
+DeferredHandleScope::~DeferredHandleScope() {
+ impl_->isolate()->handle_scope_data()->level--;
+ ASSERT(handles_detached_);
+ ASSERT(impl_->isolate()->handle_scope_data()->level == prev_level_);
+}
+
+
+DeferredHandles* DeferredHandleScope::Detach() {
+ DeferredHandles* deferred = impl_->Detach(prev_limit_);
+ v8::ImplementationUtilities::HandleScopeData* data =
+ impl_->isolate()->handle_scope_data();
+ data->next = prev_next_;
+ data->limit = prev_limit_;
+#ifdef DEBUG
+ handles_detached_ = true;
+#endif
+ return deferred;
+}
+
+
} } // namespace v8::internal
diff --git a/deps/v8/src/handles.h b/deps/v8/src/handles.h
index 960696b5f..a1d88c2f8 100644
--- a/deps/v8/src/handles.h
+++ b/deps/v8/src/handles.h
@@ -95,6 +95,10 @@ class Handle {
};
+class DeferredHandles;
+class HandleScopeImplementer;
+
+
// A stack-allocated class that governs a number of local handles.
// After a handle scope has been created, all local handles will be
// allocated within that handle scope until either the handle scope is
@@ -156,8 +160,37 @@ class HandleScope {
// Zaps the handles in the half-open interval [start, end).
static void ZapRange(internal::Object** start, internal::Object** end);
+ friend class v8::internal::DeferredHandles;
friend class v8::HandleScope;
+ friend class v8::internal::HandleScopeImplementer;
friend class v8::ImplementationUtilities;
+ friend class v8::internal::Isolate;
+};
+
+
+class DeferredHandles;
+
+
+class DeferredHandleScope {
+ public:
+ explicit DeferredHandleScope(Isolate* isolate);
+ // The DeferredHandles object returned stores the Handles created
+ // since the creation of this DeferredHandleScope. The Handles are
+ // alive as long as the DeferredHandles object is alive.
+ DeferredHandles* Detach();
+ ~DeferredHandleScope();
+
+ private:
+ Object** prev_limit_;
+ Object** prev_next_;
+ HandleScopeImplementer* impl_;
+
+#ifdef DEBUG
+ bool handles_detached_;
+ int prev_level_;
+#endif
+
+ friend class HandleScopeImplementer;
};
@@ -216,7 +249,7 @@ Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray>,
// if none exists.
Handle<JSValue> GetScriptWrapper(Handle<Script> script);
-// Script line number computations.
+// Script line number computations. Note that the line number is zero-based.
void InitScriptLineEnds(Handle<Script> script);
// For string calculates an array of line end positions. If the string
// does not end with a new line character, this character may optionally be
@@ -243,6 +276,7 @@ Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
KeyCollectionType type,
bool* threw);
Handle<JSArray> GetKeysFor(Handle<JSReceiver> object, bool* threw);
+Handle<FixedArray> ReduceFixedArrayTo(Handle<FixedArray> array, int length);
Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
bool cache_result);
@@ -294,6 +328,7 @@ class NoHandleAllocation BASE_EMBEDDED {
inline ~NoHandleAllocation();
private:
int level_;
+ bool active_;
#endif
};
diff --git a/deps/v8/src/hashmap.h b/deps/v8/src/hashmap.h
index 6f76e9f7f..11f6ace7d 100644
--- a/deps/v8/src/hashmap.h
+++ b/deps/v8/src/hashmap.h
@@ -59,7 +59,8 @@ class TemplateHashMapImpl {
struct Entry {
void* key;
void* value;
- uint32_t hash; // the full hash value for key
+ uint32_t hash; // The full hash value for key
+ int order; // If you never remove entries this is the insertion order.
};
// If an entry with matching key is found, Lookup()
@@ -140,6 +141,7 @@ TemplateHashMapImpl<AllocationPolicy>::Lookup(
p->key = key;
p->value = NULL;
p->hash = hash;
+ p->order = occupancy_;
occupancy_++;
// Grow the map if we reached >= 80% occupancy.
@@ -297,7 +299,9 @@ void TemplateHashMapImpl<AllocationPolicy>::Resize(AllocationPolicy allocator) {
// Rehash all current entries.
for (Entry* p = map; n > 0; p++) {
if (p->key != NULL) {
- Lookup(p->key, p->hash, true, allocator)->value = p->value;
+ Entry* entry = Lookup(p->key, p->hash, true, allocator);
+ entry->value = p->value;
+ entry->order = p->order;
n--;
}
}
diff --git a/deps/v8/src/heap-inl.h b/deps/v8/src/heap-inl.h
index 9d79db246..bace902d4 100644
--- a/deps/v8/src/heap-inl.h
+++ b/deps/v8/src/heap-inl.h
@@ -85,13 +85,16 @@ void PromotionQueue::ActivateGuardIfOnTheSamePage() {
MaybeObject* Heap::AllocateStringFromUtf8(Vector<const char> str,
PretenureFlag pretenure) {
// Check for ASCII first since this is the common case.
- if (String::IsAscii(str.start(), str.length())) {
+ const char* start = str.start();
+ int length = str.length();
+ int non_ascii_start = String::NonAsciiStart(start, length);
+ if (non_ascii_start >= length) {
// If the string is ASCII, we do not need to convert the characters
// since UTF8 is backwards compatible with ASCII.
return AllocateStringFromAscii(str, pretenure);
}
// Non-ASCII and we need to decode.
- return AllocateStringFromUtf8Slow(str, pretenure);
+ return AllocateStringFromUtf8Slow(str, non_ascii_start, pretenure);
}
@@ -267,13 +270,6 @@ MaybeObject* Heap::AllocateRawMap() {
#endif
MaybeObject* result = map_space_->AllocateRaw(Map::kSize);
if (result->IsFailure()) old_gen_exhausted_ = true;
-#ifdef DEBUG
- if (!result->IsFailure()) {
- // Maps have their own alignment.
- CHECK((reinterpret_cast<intptr_t>(result) & kMapAlignmentMask) ==
- static_cast<intptr_t>(kHeapObjectTag));
- }
-#endif
return result;
}
@@ -468,10 +464,12 @@ intptr_t Heap::AdjustAmountOfExternalAllocatedMemory(
// Avoid overflow.
if (amount > amount_of_external_allocated_memory_) {
amount_of_external_allocated_memory_ = amount;
+ } else {
+ // Give up and reset the counters in case of an overflow.
+ amount_of_external_allocated_memory_ = 0;
+ amount_of_external_allocated_memory_at_last_global_gc_ = 0;
}
- intptr_t amount_since_last_global_gc =
- amount_of_external_allocated_memory_ -
- amount_of_external_allocated_memory_at_last_global_gc_;
+ intptr_t amount_since_last_global_gc = PromotedExternalMemorySize();
if (amount_since_last_global_gc > external_allocation_limit_) {
CollectAllGarbage(kNoGCFlags, "external memory allocation limit reached");
}
@@ -479,8 +477,19 @@ intptr_t Heap::AdjustAmountOfExternalAllocatedMemory(
// Avoid underflow.
if (amount >= 0) {
amount_of_external_allocated_memory_ = amount;
+ } else {
+ // Give up and reset the counters in case of an overflow.
+ amount_of_external_allocated_memory_ = 0;
+ amount_of_external_allocated_memory_at_last_global_gc_ = 0;
}
}
+ if (FLAG_trace_external_memory) {
+ PrintPID("%8.0f ms: ", isolate()->time_millis_since_init());
+ PrintF("Adjust amount of external memory: delta=%6" V8_PTR_PREFIX "d KB, "
+ " amount=%6" V8_PTR_PREFIX "d KB, isolate=0x%08" V8PRIxPTR ".\n",
+ change_in_bytes / 1024, amount_of_external_allocated_memory_ / 1024,
+ reinterpret_cast<intptr_t>(isolate()));
+ }
ASSERT(amount_of_external_allocated_memory_ >= 0);
return amount_of_external_allocated_memory_;
}
@@ -627,9 +636,11 @@ void ExternalStringTable::AddOldString(String* string) {
void ExternalStringTable::ShrinkNewStrings(int position) {
new_space_strings_.Rewind(position);
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
Verify();
}
+#endif
}
@@ -728,28 +739,15 @@ AlwaysAllocateScope::~AlwaysAllocateScope() {
}
-LinearAllocationScope::LinearAllocationScope() {
- HEAP->linear_allocation_scope_depth_++;
-}
-
-
-LinearAllocationScope::~LinearAllocationScope() {
- HEAP->linear_allocation_scope_depth_--;
- ASSERT(HEAP->linear_allocation_scope_depth_ >= 0);
-}
-
-
-#ifdef DEBUG
void VerifyPointersVisitor::VisitPointers(Object** start, Object** end) {
for (Object** current = start; current < end; current++) {
if ((*current)->IsHeapObject()) {
HeapObject* object = HeapObject::cast(*current);
- ASSERT(HEAP->Contains(object));
- ASSERT(object->map()->IsMap());
+ CHECK(HEAP->Contains(object));
+ CHECK(object->map()->IsMap());
}
}
}
-#endif
double GCTracer::SizeOfHeapObjects() {
@@ -757,37 +755,47 @@ double GCTracer::SizeOfHeapObjects() {
}
-#ifdef DEBUG
DisallowAllocationFailure::DisallowAllocationFailure() {
+#ifdef DEBUG
old_state_ = HEAP->disallow_allocation_failure_;
HEAP->disallow_allocation_failure_ = true;
+#endif
}
DisallowAllocationFailure::~DisallowAllocationFailure() {
+#ifdef DEBUG
HEAP->disallow_allocation_failure_ = old_state_;
-}
#endif
+}
#ifdef DEBUG
AssertNoAllocation::AssertNoAllocation() {
- old_state_ = HEAP->allow_allocation(false);
+ Isolate* isolate = ISOLATE;
+ active_ = !isolate->optimizing_compiler_thread()->IsOptimizerThread();
+ if (active_) {
+ old_state_ = isolate->heap()->allow_allocation(false);
+ }
}
AssertNoAllocation::~AssertNoAllocation() {
- HEAP->allow_allocation(old_state_);
+ if (active_) HEAP->allow_allocation(old_state_);
}
DisableAssertNoAllocation::DisableAssertNoAllocation() {
- old_state_ = HEAP->allow_allocation(true);
+ Isolate* isolate = ISOLATE;
+ active_ = !isolate->optimizing_compiler_thread()->IsOptimizerThread();
+ if (active_) {
+ old_state_ = isolate->heap()->allow_allocation(true);
+ }
}
DisableAssertNoAllocation::~DisableAssertNoAllocation() {
- HEAP->allow_allocation(old_state_);
+ if (active_) HEAP->allow_allocation(old_state_);
}
#else
diff --git a/deps/v8/src/heap.cc b/deps/v8/src/heap.cc
index c37c084fa..e3fcb93a7 100644
--- a/deps/v8/src/heap.cc
+++ b/deps/v8/src/heap.cc
@@ -48,6 +48,7 @@
#include "snapshot.h"
#include "store-buffer.h"
#include "v8threads.h"
+#include "v8utils.h"
#include "vm-state-inl.h"
#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
#include "regexp-macro-assembler.h"
@@ -97,6 +98,7 @@ Heap::Heap()
linear_allocation_scope_depth_(0),
contexts_disposed_(0),
global_ic_age_(0),
+ flush_monomorphic_ics_(false),
scan_on_scavenge_pages_(0),
new_space_(this),
old_pointer_space_(NULL),
@@ -139,6 +141,7 @@ Heap::Heap()
previous_survival_rate_trend_(Heap::STABLE),
survival_rate_trend_(Heap::STABLE),
max_gc_pause_(0),
+ total_gc_time_ms_(0),
max_alive_after_gc_(0),
min_in_mutator_(kMaxInt),
alive_after_last_gc_(0),
@@ -155,7 +158,8 @@ Heap::Heap()
scavenges_since_last_idle_round_(kIdleScavengeThreshold),
promotion_queue_(this),
configured_(false),
- chunks_queued_for_free_(NULL) {
+ chunks_queued_for_free_(NULL),
+ relocation_mutex_(NULL) {
// Allow build-time customization of the max semispace size. Building
// V8 with snapshots and a non-default max semispace size is much
// easier if you can define it as part of the build environment.
@@ -173,12 +177,14 @@ Heap::Heap()
}
memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
- global_contexts_list_ = NULL;
+ native_contexts_list_ = NULL;
mark_compact_collector_.heap_ = this;
external_string_table_.heap_ = this;
// Put a dummy entry in the remembered pages so we can find the list the
// minidump even if there are no real unmapped pages.
RememberUnmappedPage(NULL, false);
+
+ ClearObjectStats(true);
}
@@ -320,48 +326,59 @@ void Heap::ReportStatisticsBeforeGC() {
void Heap::PrintShortHeapStatistics() {
if (!FLAG_trace_gc_verbose) return;
- PrintF("Memory allocator, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d\n",
- isolate_->memory_allocator()->Size(),
- isolate_->memory_allocator()->Available());
- PrintF("New space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d\n",
- Heap::new_space_.Size(),
- new_space_.Available());
- PrintF("Old pointers, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d"
- ", waste: %8" V8_PTR_PREFIX "d\n",
- old_pointer_space_->Size(),
- old_pointer_space_->Available(),
- old_pointer_space_->Waste());
- PrintF("Old data space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d"
- ", waste: %8" V8_PTR_PREFIX "d\n",
- old_data_space_->Size(),
- old_data_space_->Available(),
- old_data_space_->Waste());
- PrintF("Code space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d"
- ", waste: %8" V8_PTR_PREFIX "d\n",
- code_space_->Size(),
- code_space_->Available(),
- code_space_->Waste());
- PrintF("Map space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d"
- ", waste: %8" V8_PTR_PREFIX "d\n",
- map_space_->Size(),
- map_space_->Available(),
- map_space_->Waste());
- PrintF("Cell space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d"
- ", waste: %8" V8_PTR_PREFIX "d\n",
- cell_space_->Size(),
- cell_space_->Available(),
- cell_space_->Waste());
- PrintF("Large object space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d\n",
- lo_space_->Size(),
- lo_space_->Available());
+ PrintPID("Memory allocator, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB\n",
+ isolate_->memory_allocator()->Size() / KB,
+ isolate_->memory_allocator()->Available() / KB);
+ PrintPID("New space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ new_space_.Size() / KB,
+ new_space_.Available() / KB,
+ new_space_.CommittedMemory() / KB);
+ PrintPID("Old pointers, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ old_pointer_space_->SizeOfObjects() / KB,
+ old_pointer_space_->Available() / KB,
+ old_pointer_space_->CommittedMemory() / KB);
+ PrintPID("Old data space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ old_data_space_->SizeOfObjects() / KB,
+ old_data_space_->Available() / KB,
+ old_data_space_->CommittedMemory() / KB);
+ PrintPID("Code space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ code_space_->SizeOfObjects() / KB,
+ code_space_->Available() / KB,
+ code_space_->CommittedMemory() / KB);
+ PrintPID("Map space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ map_space_->SizeOfObjects() / KB,
+ map_space_->Available() / KB,
+ map_space_->CommittedMemory() / KB);
+ PrintPID("Cell space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ cell_space_->SizeOfObjects() / KB,
+ cell_space_->Available() / KB,
+ cell_space_->CommittedMemory() / KB);
+ PrintPID("Large object space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ lo_space_->SizeOfObjects() / KB,
+ lo_space_->Available() / KB,
+ lo_space_->CommittedMemory() / KB);
+ PrintPID("All spaces, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ this->SizeOfObjects() / KB,
+ this->Available() / KB,
+ this->CommittedMemory() / KB);
+ PrintPID("Total time spent in GC : %d ms\n", total_gc_time_ms_);
}
@@ -388,18 +405,19 @@ void Heap::GarbageCollectionPrologue() {
ClearJSFunctionResultCaches();
gc_count_++;
unflattened_strings_length_ = 0;
-#ifdef DEBUG
- ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
- allow_allocation(false);
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
Verify();
}
+#endif
+
+#ifdef DEBUG
+ ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
+ allow_allocation(false);
if (FLAG_gc_verbose) Print();
-#endif // DEBUG
-#if defined(DEBUG)
ReportStatisticsBeforeGC();
#endif // DEBUG
@@ -407,6 +425,7 @@ void Heap::GarbageCollectionPrologue() {
store_buffer()->GCPrologue();
}
+
intptr_t Heap::SizeOfObjects() {
intptr_t total = 0;
AllSpaces spaces;
@@ -416,17 +435,34 @@ intptr_t Heap::SizeOfObjects() {
return total;
}
+
+void Heap::RepairFreeListsAfterBoot() {
+ PagedSpaces spaces;
+ for (PagedSpace* space = spaces.next();
+ space != NULL;
+ space = spaces.next()) {
+ space->RepairFreeListsAfterBoot();
+ }
+}
+
+
void Heap::GarbageCollectionEpilogue() {
store_buffer()->GCEpilogue();
LiveObjectList::GCEpilogue();
-#ifdef DEBUG
- allow_allocation(true);
- ZapFromSpace();
+ // In release mode, we only zap the from space under heap verification.
+ if (Heap::ShouldZapGarbage()) {
+ ZapFromSpace();
+ }
+
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
Verify();
}
+#endif
+#ifdef DEBUG
+ allow_allocation(true);
if (FLAG_print_global_handles) isolate_->global_handles()->Print();
if (FLAG_print_handles) PrintHandles();
if (FLAG_gc_verbose) Print();
@@ -440,6 +476,56 @@ void Heap::GarbageCollectionEpilogue() {
symbol_table()->Capacity());
isolate_->counters()->number_of_symbols()->Set(
symbol_table()->NumberOfElements());
+
+ if (CommittedMemory() > 0) {
+ isolate_->counters()->external_fragmentation_total()->AddSample(
+ static_cast<int>(100 - (SizeOfObjects() * 100.0) / CommittedMemory()));
+
+ isolate_->counters()->heap_fraction_map_space()->AddSample(
+ static_cast<int>(
+ (map_space()->CommittedMemory() * 100.0) / CommittedMemory()));
+ isolate_->counters()->heap_fraction_cell_space()->AddSample(
+ static_cast<int>(
+ (cell_space()->CommittedMemory() * 100.0) / CommittedMemory()));
+
+ isolate_->counters()->heap_sample_total_committed()->AddSample(
+ static_cast<int>(CommittedMemory() / KB));
+ isolate_->counters()->heap_sample_total_used()->AddSample(
+ static_cast<int>(SizeOfObjects() / KB));
+ isolate_->counters()->heap_sample_map_space_committed()->AddSample(
+ static_cast<int>(map_space()->CommittedMemory() / KB));
+ isolate_->counters()->heap_sample_cell_space_committed()->AddSample(
+ static_cast<int>(cell_space()->CommittedMemory() / KB));
+ }
+
+#define UPDATE_COUNTERS_FOR_SPACE(space) \
+ isolate_->counters()->space##_bytes_available()->Set( \
+ static_cast<int>(space()->Available())); \
+ isolate_->counters()->space##_bytes_committed()->Set( \
+ static_cast<int>(space()->CommittedMemory())); \
+ isolate_->counters()->space##_bytes_used()->Set( \
+ static_cast<int>(space()->SizeOfObjects()));
+#define UPDATE_FRAGMENTATION_FOR_SPACE(space) \
+ if (space()->CommittedMemory() > 0) { \
+ isolate_->counters()->external_fragmentation_##space()->AddSample( \
+ static_cast<int>(100 - \
+ (space()->SizeOfObjects() * 100.0) / space()->CommittedMemory())); \
+ }
+#define UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(space) \
+ UPDATE_COUNTERS_FOR_SPACE(space) \
+ UPDATE_FRAGMENTATION_FOR_SPACE(space)
+
+ UPDATE_COUNTERS_FOR_SPACE(new_space)
+ UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_pointer_space)
+ UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_data_space)
+ UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(code_space)
+ UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(map_space)
+ UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(cell_space)
+ UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(lo_space)
+#undef UPDATE_COUNTERS_FOR_SPACE
+#undef UPDATE_FRAGMENTATION_FOR_SPACE
+#undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE
+
#if defined(DEBUG)
ReportStatisticsAfterGC();
#endif // DEBUG
@@ -547,10 +633,12 @@ bool Heap::CollectGarbage(AllocationSpace space,
PerformGarbageCollection(collector, &tracer);
rate->Stop();
+ ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped());
+
+ // This can do debug callbacks and restart incremental marking.
GarbageCollectionEpilogue();
}
- ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped());
if (incremental_marking()->IsStopped()) {
if (incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull()) {
incremental_marking()->Start();
@@ -571,7 +659,7 @@ void Heap::PerformScavenge() {
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
// Helper class for verifying the symbol table.
class SymbolTableVerifier : public ObjectVisitor {
public:
@@ -580,20 +668,18 @@ class SymbolTableVerifier : public ObjectVisitor {
for (Object** p = start; p < end; p++) {
if ((*p)->IsHeapObject()) {
// Check that the symbol is actually a symbol.
- ASSERT((*p)->IsTheHole() || (*p)->IsUndefined() || (*p)->IsSymbol());
+ CHECK((*p)->IsTheHole() || (*p)->IsUndefined() || (*p)->IsSymbol());
}
}
}
};
-#endif // DEBUG
static void VerifySymbolTable() {
-#ifdef DEBUG
SymbolTableVerifier verifier;
HEAP->symbol_table()->IterateElements(&verifier);
-#endif // DEBUG
}
+#endif // VERIFY_HEAP
static bool AbortIncrementalMarkingAndCollectGarbage(
@@ -608,67 +694,42 @@ static bool AbortIncrementalMarkingAndCollectGarbage(
void Heap::ReserveSpace(
- int new_space_size,
- int pointer_space_size,
- int data_space_size,
- int code_space_size,
- int map_space_size,
- int cell_space_size,
- int large_object_size) {
- NewSpace* new_space = Heap::new_space();
- PagedSpace* old_pointer_space = Heap::old_pointer_space();
- PagedSpace* old_data_space = Heap::old_data_space();
- PagedSpace* code_space = Heap::code_space();
- PagedSpace* map_space = Heap::map_space();
- PagedSpace* cell_space = Heap::cell_space();
- LargeObjectSpace* lo_space = Heap::lo_space();
+ int *sizes,
+ Address *locations_out) {
bool gc_performed = true;
int counter = 0;
static const int kThreshold = 20;
while (gc_performed && counter++ < kThreshold) {
gc_performed = false;
- if (!new_space->ReserveSpace(new_space_size)) {
- Heap::CollectGarbage(NEW_SPACE,
- "failed to reserve space in the new space");
- gc_performed = true;
- }
- if (!old_pointer_space->ReserveSpace(pointer_space_size)) {
- AbortIncrementalMarkingAndCollectGarbage(this, OLD_POINTER_SPACE,
- "failed to reserve space in the old pointer space");
- gc_performed = true;
- }
- if (!(old_data_space->ReserveSpace(data_space_size))) {
- AbortIncrementalMarkingAndCollectGarbage(this, OLD_DATA_SPACE,
- "failed to reserve space in the old data space");
- gc_performed = true;
- }
- if (!(code_space->ReserveSpace(code_space_size))) {
- AbortIncrementalMarkingAndCollectGarbage(this, CODE_SPACE,
- "failed to reserve space in the code space");
- gc_performed = true;
- }
- if (!(map_space->ReserveSpace(map_space_size))) {
- AbortIncrementalMarkingAndCollectGarbage(this, MAP_SPACE,
- "failed to reserve space in the map space");
- gc_performed = true;
- }
- if (!(cell_space->ReserveSpace(cell_space_size))) {
- AbortIncrementalMarkingAndCollectGarbage(this, CELL_SPACE,
- "failed to reserve space in the cell space");
- gc_performed = true;
- }
- // We add a slack-factor of 2 in order to have space for a series of
- // large-object allocations that are only just larger than the page size.
- large_object_size *= 2;
- // The ReserveSpace method on the large object space checks how much
- // we can expand the old generation. This includes expansion caused by
- // allocation in the other spaces.
- large_object_size += cell_space_size + map_space_size + code_space_size +
- data_space_size + pointer_space_size;
- if (!(lo_space->ReserveSpace(large_object_size))) {
- AbortIncrementalMarkingAndCollectGarbage(this, LO_SPACE,
- "failed to reserve space in the large object space");
- gc_performed = true;
+ ASSERT(NEW_SPACE == FIRST_PAGED_SPACE - 1);
+ for (int space = NEW_SPACE; space <= LAST_PAGED_SPACE; space++) {
+ if (sizes[space] != 0) {
+ MaybeObject* allocation;
+ if (space == NEW_SPACE) {
+ allocation = new_space()->AllocateRaw(sizes[space]);
+ } else {
+ allocation = paged_space(space)->AllocateRaw(sizes[space]);
+ }
+ FreeListNode* node;
+ if (!allocation->To<FreeListNode>(&node)) {
+ if (space == NEW_SPACE) {
+ Heap::CollectGarbage(NEW_SPACE,
+ "failed to reserve space in the new space");
+ } else {
+ AbortIncrementalMarkingAndCollectGarbage(
+ this,
+ static_cast<AllocationSpace>(space),
+ "failed to reserve space in paged space");
+ }
+ gc_performed = true;
+ break;
+ } else {
+ // Mark with a free list node, in case we have a GC before
+ // deserializing.
+ node->set_size(this, sizes[space]);
+ locations_out[space] = node->address();
+ }
+ }
}
}
@@ -696,7 +757,7 @@ void Heap::EnsureFromSpaceIsCommitted() {
void Heap::ClearJSFunctionResultCaches() {
if (isolate_->bootstrapper()->IsActive()) return;
- Object* context = global_contexts_list_;
+ Object* context = native_contexts_list_;
while (!context->IsUndefined()) {
// Get the caches for this context. GC can happen when the context
// is not fully initialized, so the caches can be undefined.
@@ -723,7 +784,7 @@ void Heap::ClearNormalizedMapCaches() {
return;
}
- Object* context = global_contexts_list_;
+ Object* context = native_contexts_list_;
while (!context->IsUndefined()) {
// GC can happen when the context is not fully initialized,
// so the cache can be undefined.
@@ -775,9 +836,12 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
PROFILE(isolate_, CodeMovingGCEvent());
}
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
VerifySymbolTable();
}
+#endif
+
if (collector == MARK_COMPACTOR && global_gc_prologue_callback_) {
ASSERT(!allocation_allowed_);
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
@@ -852,8 +916,8 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
// have to limit maximal capacity of the young generation.
new_space_high_promotion_mode_active_ = true;
if (FLAG_trace_gc) {
- PrintF("Limited new space size due to high promotion rate: %d MB\n",
- new_space_.InitialCapacity() / MB);
+ PrintPID("Limited new space size due to high promotion rate: %d MB\n",
+ new_space_.InitialCapacity() / MB);
}
} else if (new_space_high_promotion_mode_active_ &&
IsStableOrDecreasingSurvivalTrend() &&
@@ -863,8 +927,8 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
// to grow again.
new_space_high_promotion_mode_active_ = false;
if (FLAG_trace_gc) {
- PrintF("Unlimited new space size due to low promotion rate: %d MB\n",
- new_space_.MaximumCapacity() / MB);
+ PrintPID("Unlimited new space size due to low promotion rate: %d MB\n",
+ new_space_.MaximumCapacity() / MB);
}
}
@@ -904,9 +968,12 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
global_gc_epilogue_callback_();
}
+
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
VerifySymbolTable();
}
+#endif
return next_gc_likely_to_collect_more;
}
@@ -933,7 +1000,7 @@ void Heap::MarkCompact(GCTracer* tracer) {
contexts_disposed_ = 0;
- isolate_->set_context_exit_happened(false);
+ flush_monomorphic_ics_ = false;
}
@@ -943,7 +1010,8 @@ void Heap::MarkCompactPrologue() {
isolate_->keyed_lookup_cache()->Clear();
isolate_->context_slot_cache()->Clear();
isolate_->descriptor_lookup_cache()->Clear();
- StringSplitCache::Clear(string_split_cache());
+ RegExpResultsCache::Clear(string_split_cache());
+ RegExpResultsCache::Clear(regexp_multiple_cache());
isolate_->compilation_cache()->MarkCompactPrologue();
@@ -988,7 +1056,7 @@ class ScavengeVisitor: public ObjectVisitor {
};
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
// Visitor class to verify pointers in code or data space do not point into
// new space.
class VerifyNonPointerSpacePointersVisitor: public ObjectVisitor {
@@ -996,7 +1064,7 @@ class VerifyNonPointerSpacePointersVisitor: public ObjectVisitor {
void VisitPointers(Object** start, Object**end) {
for (Object** current = start; current < end; current++) {
if ((*current)->IsHeapObject()) {
- ASSERT(!HEAP->InNewSpace(HeapObject::cast(*current)));
+ CHECK(!HEAP->InNewSpace(HeapObject::cast(*current)));
}
}
}
@@ -1021,7 +1089,7 @@ static void VerifyNonPointerSpacePointers() {
object->Iterate(&v);
}
}
-#endif
+#endif // VERIFY_HEAP
void Heap::CheckNewSpaceExpansionCriteria() {
@@ -1159,7 +1227,9 @@ class ScavengeWeakObjectRetainer : public WeakObjectRetainer {
void Heap::Scavenge() {
-#ifdef DEBUG
+ RelocationLock relocation_lock(this);
+
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) VerifyNonPointerSpacePointers();
#endif
@@ -1225,18 +1295,18 @@ void Heap::Scavenge() {
// Copy objects reachable from cells by scavenging cell values directly.
HeapObjectIterator cell_iterator(cell_space_);
- for (HeapObject* cell = cell_iterator.Next();
- cell != NULL; cell = cell_iterator.Next()) {
- if (cell->IsJSGlobalPropertyCell()) {
- Address value_address =
- reinterpret_cast<Address>(cell) +
- (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag);
+ for (HeapObject* heap_object = cell_iterator.Next();
+ heap_object != NULL;
+ heap_object = cell_iterator.Next()) {
+ if (heap_object->IsJSGlobalPropertyCell()) {
+ JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(heap_object);
+ Address value_address = cell->ValueAddress();
scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
}
}
- // Scavenge object reachable from the global contexts list directly.
- scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_));
+ // Scavenge object reachable from the native contexts list directly.
+ scavenge_visitor.VisitPointer(BitCast<Object**>(&native_contexts_list_));
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
@@ -1296,9 +1366,11 @@ String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
void Heap::UpdateNewSpaceReferencesInExternalStringTable(
ExternalStringTableUpdaterCallback updater_func) {
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
external_string_table_.Verify();
}
+#endif
if (external_string_table_.new_space_strings_.is_empty()) return;
@@ -1396,7 +1468,7 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
Object* undefined = undefined_value();
Object* head = undefined;
Context* tail = NULL;
- Object* candidate = global_contexts_list_;
+ Object* candidate = native_contexts_list_;
// We don't record weak slots during marking or scavenges.
// Instead we do it once when we complete mark-compact cycle.
@@ -1469,7 +1541,7 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
}
// Update the head of the list of contexts.
- global_contexts_list_ = head;
+ native_contexts_list_ = head;
}
@@ -1595,7 +1667,7 @@ class ScavengingVisitor : public StaticVisitorBase {
table_.Register(kVisitFixedArray, &EvacuateFixedArray);
table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray);
- table_.Register(kVisitGlobalContext,
+ table_.Register(kVisitNativeContext,
&ObjectEvacuationStrategy<POINTER_OBJECT>::
template VisitSpecialized<Context::kSize>);
@@ -1681,7 +1753,7 @@ class ScavengingVisitor : public StaticVisitorBase {
RecordCopiedObject(heap, target);
HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address()));
Isolate* isolate = heap->isolate();
- if (isolate->logger()->is_logging() ||
+ if (isolate->logger()->is_logging_code_events() ||
CpuProfiler::is_profiling(isolate)) {
if (target->IsSharedFunctionInfo()) {
PROFILE(isolate, SharedFunctionInfoMoveEvent(
@@ -1989,9 +2061,8 @@ void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) {
MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type,
int instance_size) {
Object* result;
- { MaybeObject* maybe_result = AllocateRawMap();
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ MaybeObject* maybe_result = AllocateRawMap();
+ if (!maybe_result->ToObject(&result)) return maybe_result;
// Map::cast cannot be used due to uninitialized map field.
reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map());
@@ -2004,6 +2075,9 @@ MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type,
reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
reinterpret_cast<Map*>(result)->set_bit_field(0);
reinterpret_cast<Map*>(result)->set_bit_field2(0);
+ int bit_field3 = Map::EnumLengthBits::encode(Map::kInvalidEnumCache) |
+ Map::OwnsDescriptors::encode(true);
+ reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3);
return result;
}
@@ -2012,9 +2086,8 @@ MaybeObject* Heap::AllocateMap(InstanceType instance_type,
int instance_size,
ElementsKind elements_kind) {
Object* result;
- { MaybeObject* maybe_result = AllocateRawMap();
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ MaybeObject* maybe_result = AllocateRawMap();
+ if (!maybe_result->To(&result)) return maybe_result;
Map* map = reinterpret_cast<Map*>(result);
map->set_map_no_write_barrier(meta_map());
@@ -2026,20 +2099,17 @@ MaybeObject* Heap::AllocateMap(InstanceType instance_type,
map->set_instance_size(instance_size);
map->set_inobject_properties(0);
map->set_pre_allocated_property_fields(0);
- map->init_instance_descriptors();
map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
- map->init_prototype_transitions(undefined_value());
+ map->init_back_pointer(undefined_value());
map->set_unused_property_fields(0);
+ map->set_instance_descriptors(empty_descriptor_array());
map->set_bit_field(0);
map->set_bit_field2(1 << Map::kIsExtensible);
+ int bit_field3 = Map::EnumLengthBits::encode(Map::kInvalidEnumCache) |
+ Map::OwnsDescriptors::encode(true);
+ map->set_bit_field3(bit_field3);
map->set_elements_kind(elements_kind);
- // If the map object is aligned fill the padding area with Smi 0 objects.
- if (Map::kPadStart < Map::kSize) {
- memset(reinterpret_cast<byte*>(map) + Map::kPadStart - kHeapObjectTag,
- 0,
- Map::kSize - Map::kPadStart);
- }
return map;
}
@@ -2076,8 +2146,7 @@ MaybeObject* Heap::AllocateTypeFeedbackInfo() {
{ MaybeObject* maybe_info = AllocateStruct(TYPE_FEEDBACK_INFO_TYPE);
if (!maybe_info->To(&info)) return maybe_info;
}
- info->set_ic_total_count(0);
- info->set_ic_with_type_info_count(0);
+ info->initialize_storage();
info->set_type_feedback_cells(TypeFeedbackCells::cast(empty_fixed_array()),
SKIP_WRITE_BARRIER);
return info;
@@ -2165,17 +2234,17 @@ bool Heap::CreateInitialMaps() {
set_empty_descriptor_array(DescriptorArray::cast(obj));
// Fix the instance_descriptors for the existing maps.
- meta_map()->init_instance_descriptors();
meta_map()->set_code_cache(empty_fixed_array());
- meta_map()->init_prototype_transitions(undefined_value());
+ meta_map()->init_back_pointer(undefined_value());
+ meta_map()->set_instance_descriptors(empty_descriptor_array());
- fixed_array_map()->init_instance_descriptors();
fixed_array_map()->set_code_cache(empty_fixed_array());
- fixed_array_map()->init_prototype_transitions(undefined_value());
+ fixed_array_map()->init_back_pointer(undefined_value());
+ fixed_array_map()->set_instance_descriptors(empty_descriptor_array());
- oddball_map()->init_instance_descriptors();
oddball_map()->set_code_cache(empty_fixed_array());
- oddball_map()->init_prototype_transitions(undefined_value());
+ oddball_map()->init_back_pointer(undefined_value());
+ oddball_map()->set_instance_descriptors(empty_descriptor_array());
// Fix prototype object for existing maps.
meta_map()->set_prototype(null_value());
@@ -2383,9 +2452,16 @@ bool Heap::CreateInitialMaps() {
AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
}
- Map* global_context_map = Map::cast(obj);
- global_context_map->set_visitor_id(StaticVisitorBase::kVisitGlobalContext);
- set_global_context_map(global_context_map);
+ set_global_context_map(Map::cast(obj));
+
+ { MaybeObject* maybe_obj =
+ AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
+ if (!maybe_obj->ToObject(&obj)) return false;
+ }
+ Map* native_context_map = Map::cast(obj);
+ native_context_map->set_dictionary_map(true);
+ native_context_map->set_visitor_id(StaticVisitorBase::kVisitNativeContext);
+ set_native_context_map(native_context_map);
{ MaybeObject* maybe_obj = AllocateMap(SHARED_FUNCTION_INFO_TYPE,
SharedFunctionInfo::kAlignedSize);
@@ -2637,7 +2713,7 @@ bool Heap::CreateInitialObjects() {
// hash code in place. The hash code for the hidden_symbol is zero to ensure
// that it will always be at the first entry in property descriptors.
{ MaybeObject* maybe_obj =
- AllocateSymbol(CStrVector(""), 0, String::kZeroHash);
+ AllocateSymbol(CStrVector(""), 0, String::kEmptyStringHash);
if (!maybe_obj->ToObject(&obj)) return false;
}
hidden_symbol_ = String::cast(obj);
@@ -2698,12 +2774,18 @@ bool Heap::CreateInitialObjects() {
set_single_character_string_cache(FixedArray::cast(obj));
// Allocate cache for string split.
- { MaybeObject* maybe_obj =
- AllocateFixedArray(StringSplitCache::kStringSplitCacheSize, TENURED);
+ { MaybeObject* maybe_obj = AllocateFixedArray(
+ RegExpResultsCache::kRegExpResultsCacheSize, TENURED);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_string_split_cache(FixedArray::cast(obj));
+ { MaybeObject* maybe_obj = AllocateFixedArray(
+ RegExpResultsCache::kRegExpResultsCacheSize, TENURED);
+ if (!maybe_obj->ToObject(&obj)) return false;
+ }
+ set_regexp_multiple_cache(FixedArray::cast(obj));
+
// Allocate cache for external strings pointing to native source code.
{ MaybeObject* maybe_obj = AllocateFixedArray(Natives::GetBuiltinsCount());
if (!maybe_obj->ToObject(&obj)) return false;
@@ -2729,70 +2811,98 @@ bool Heap::CreateInitialObjects() {
}
-Object* StringSplitCache::Lookup(
- FixedArray* cache, String* string, String* pattern) {
- if (!string->IsSymbol() || !pattern->IsSymbol()) return Smi::FromInt(0);
- uint32_t hash = string->Hash();
- uint32_t index = ((hash & (kStringSplitCacheSize - 1)) &
+Object* RegExpResultsCache::Lookup(Heap* heap,
+ String* key_string,
+ Object* key_pattern,
+ ResultsCacheType type) {
+ FixedArray* cache;
+ if (!key_string->IsSymbol()) return Smi::FromInt(0);
+ if (type == STRING_SPLIT_SUBSTRINGS) {
+ ASSERT(key_pattern->IsString());
+ if (!key_pattern->IsSymbol()) return Smi::FromInt(0);
+ cache = heap->string_split_cache();
+ } else {
+ ASSERT(type == REGEXP_MULTIPLE_INDICES);
+ ASSERT(key_pattern->IsFixedArray());
+ cache = heap->regexp_multiple_cache();
+ }
+
+ uint32_t hash = key_string->Hash();
+ uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) &
~(kArrayEntriesPerCacheEntry - 1));
- if (cache->get(index + kStringOffset) == string &&
- cache->get(index + kPatternOffset) == pattern) {
+ if (cache->get(index + kStringOffset) == key_string &&
+ cache->get(index + kPatternOffset) == key_pattern) {
return cache->get(index + kArrayOffset);
}
- index = ((index + kArrayEntriesPerCacheEntry) & (kStringSplitCacheSize - 1));
- if (cache->get(index + kStringOffset) == string &&
- cache->get(index + kPatternOffset) == pattern) {
+ index =
+ ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1));
+ if (cache->get(index + kStringOffset) == key_string &&
+ cache->get(index + kPatternOffset) == key_pattern) {
return cache->get(index + kArrayOffset);
}
return Smi::FromInt(0);
}
-void StringSplitCache::Enter(Heap* heap,
- FixedArray* cache,
- String* string,
- String* pattern,
- FixedArray* array) {
- if (!string->IsSymbol() || !pattern->IsSymbol()) return;
- uint32_t hash = string->Hash();
- uint32_t index = ((hash & (kStringSplitCacheSize - 1)) &
+void RegExpResultsCache::Enter(Heap* heap,
+ String* key_string,
+ Object* key_pattern,
+ FixedArray* value_array,
+ ResultsCacheType type) {
+ FixedArray* cache;
+ if (!key_string->IsSymbol()) return;
+ if (type == STRING_SPLIT_SUBSTRINGS) {
+ ASSERT(key_pattern->IsString());
+ if (!key_pattern->IsSymbol()) return;
+ cache = heap->string_split_cache();
+ } else {
+ ASSERT(type == REGEXP_MULTIPLE_INDICES);
+ ASSERT(key_pattern->IsFixedArray());
+ cache = heap->regexp_multiple_cache();
+ }
+
+ uint32_t hash = key_string->Hash();
+ uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) &
~(kArrayEntriesPerCacheEntry - 1));
if (cache->get(index + kStringOffset) == Smi::FromInt(0)) {
- cache->set(index + kStringOffset, string);
- cache->set(index + kPatternOffset, pattern);
- cache->set(index + kArrayOffset, array);
+ cache->set(index + kStringOffset, key_string);
+ cache->set(index + kPatternOffset, key_pattern);
+ cache->set(index + kArrayOffset, value_array);
} else {
uint32_t index2 =
- ((index + kArrayEntriesPerCacheEntry) & (kStringSplitCacheSize - 1));
+ ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1));
if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) {
- cache->set(index2 + kStringOffset, string);
- cache->set(index2 + kPatternOffset, pattern);
- cache->set(index2 + kArrayOffset, array);
+ cache->set(index2 + kStringOffset, key_string);
+ cache->set(index2 + kPatternOffset, key_pattern);
+ cache->set(index2 + kArrayOffset, value_array);
} else {
cache->set(index2 + kStringOffset, Smi::FromInt(0));
cache->set(index2 + kPatternOffset, Smi::FromInt(0));
cache->set(index2 + kArrayOffset, Smi::FromInt(0));
- cache->set(index + kStringOffset, string);
- cache->set(index + kPatternOffset, pattern);
- cache->set(index + kArrayOffset, array);
+ cache->set(index + kStringOffset, key_string);
+ cache->set(index + kPatternOffset, key_pattern);
+ cache->set(index + kArrayOffset, value_array);
}
}
- if (array->length() < 100) { // Limit how many new symbols we want to make.
- for (int i = 0; i < array->length(); i++) {
- String* str = String::cast(array->get(i));
+ // If the array is a reasonably short list of substrings, convert it into a
+ // list of symbols.
+ if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) {
+ for (int i = 0; i < value_array->length(); i++) {
+ String* str = String::cast(value_array->get(i));
Object* symbol;
MaybeObject* maybe_symbol = heap->LookupSymbol(str);
if (maybe_symbol->ToObject(&symbol)) {
- array->set(i, symbol);
+ value_array->set(i, symbol);
}
}
}
- array->set_map_no_write_barrier(heap->fixed_cow_array_map());
+ // Convert backing store to a copy-on-write array.
+ value_array->set_map_no_write_barrier(heap->fixed_cow_array_map());
}
-void StringSplitCache::Clear(FixedArray* cache) {
- for (int i = 0; i < kStringSplitCacheSize; i++) {
+void RegExpResultsCache::Clear(FixedArray* cache) {
+ for (int i = 0; i < kRegExpResultsCacheSize; i++) {
cache->set(i, Smi::FromInt(0));
}
}
@@ -2822,7 +2932,7 @@ void Heap::AllocateFullSizeNumberStringCache() {
// The idea is to have a small number string cache in the snapshot to keep
// boot-time memory usage down. If we expand the number string cache already
// while creating the snapshot then that didn't work out.
- ASSERT(!Serializer::enabled());
+ ASSERT(!Serializer::enabled() || FLAG_extra_code != NULL);
MaybeObject* maybe_obj =
AllocateFixedArray(FullSizeNumberStringCacheLength(), TENURED);
Object* new_cache;
@@ -3010,6 +3120,7 @@ MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) {
share->set_name(name);
Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal);
share->set_code(illegal);
+ share->ClearOptimizedCodeMap();
share->set_scope_info(ScopeInfo::Empty());
Code* construct_stub =
isolate_->builtins()->builtin(Builtins::kJSConstructStubGeneric);
@@ -3280,7 +3391,7 @@ MaybeObject* Heap::AllocateSubString(String* buffer,
}
ASSERT(buffer->IsFlat());
-#if DEBUG
+#if VERIFY_HEAP
if (FLAG_verify_heap) {
buffer->StringVerify();
}
@@ -3497,17 +3608,27 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc,
MaybeObject* maybe_result;
// Large code objects and code objects which should stay at a fixed address
// are allocated in large object space.
- if (obj_size > code_space()->AreaSize() || immovable) {
+ HeapObject* result;
+ bool force_lo_space = obj_size > code_space()->AreaSize();
+ if (force_lo_space) {
maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE);
} else {
maybe_result = code_space_->AllocateRaw(obj_size);
}
+ if (!maybe_result->To<HeapObject>(&result)) return maybe_result;
- Object* result;
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ if (immovable && !force_lo_space &&
+ // Objects on the first page of each space are never moved.
+ !code_space_->FirstPage()->Contains(result->address())) {
+ // Discard the first code allocation, which was on a page where it could be
+ // moved.
+ CreateFillerObjectAt(result->address(), obj_size);
+ maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE);
+ if (!maybe_result->To<HeapObject>(&result)) return maybe_result;
+ }
// Initialize the object
- HeapObject::cast(result)->set_map_no_write_barrier(code_map());
+ result->set_map_no_write_barrier(code_map());
Code* code = Code::cast(result);
ASSERT(!isolate_->code_range()->exists() ||
isolate_->code_range()->contains(code->address()));
@@ -3534,7 +3655,7 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc,
// through the self_reference parameter.
code->CopyFrom(desc);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
code->Verify();
}
@@ -3616,7 +3737,7 @@ MaybeObject* Heap::CopyCode(Code* code, Vector<byte> reloc_info) {
isolate_->code_range()->contains(code->address()));
new_code->Relocate(new_addr - old_addr);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
code->Verify();
}
@@ -3663,30 +3784,27 @@ MaybeObject* Heap::AllocateFunctionPrototype(JSFunction* function) {
// from the function's context, since the function can be from a
// different context.
JSFunction* object_function =
- function->context()->global_context()->object_function();
+ function->context()->native_context()->object_function();
// Each function prototype gets a copy of the object function map.
// This avoid unwanted sharing of maps between prototypes of different
// constructors.
Map* new_map;
ASSERT(object_function->has_initial_map());
- { MaybeObject* maybe_map =
- object_function->initial_map()->CopyDropTransitions(
- DescriptorArray::MAY_BE_SHARED);
- if (!maybe_map->To<Map>(&new_map)) return maybe_map;
- }
+ MaybeObject* maybe_map = object_function->initial_map()->Copy();
+ if (!maybe_map->To(&new_map)) return maybe_map;
+
Object* prototype;
- { MaybeObject* maybe_prototype = AllocateJSObjectFromMap(new_map);
- if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
- }
+ MaybeObject* maybe_prototype = AllocateJSObjectFromMap(new_map);
+ if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
+
// When creating the prototype for the function we must set its
// constructor to the function.
- Object* result;
- { MaybeObject* maybe_result =
- JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes(
- constructor_symbol(), function, DONT_ENUM);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ MaybeObject* maybe_failure =
+ JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes(
+ constructor_symbol(), function, DONT_ENUM);
+ if (maybe_failure->IsFailure()) return maybe_failure;
+
return prototype;
}
@@ -3716,12 +3834,12 @@ MaybeObject* Heap::AllocateArgumentsObject(Object* callee, int length) {
!JSFunction::cast(callee)->shared()->is_classic_mode();
if (strict_mode_callee) {
boilerplate =
- isolate()->context()->global_context()->
+ isolate()->context()->native_context()->
strict_mode_arguments_boilerplate();
arguments_object_size = kArgumentsObjectSizeStrict;
} else {
boilerplate =
- isolate()->context()->global_context()->arguments_boilerplate();
+ isolate()->context()->native_context()->arguments_boilerplate();
arguments_object_size = kArgumentsObjectSize;
}
@@ -3787,21 +3905,18 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) {
// suggested by the function.
int instance_size = fun->shared()->CalculateInstanceSize();
int in_object_properties = fun->shared()->CalculateInObjectProperties();
- Object* map_obj;
- { MaybeObject* maybe_map_obj = AllocateMap(JS_OBJECT_TYPE, instance_size);
- if (!maybe_map_obj->ToObject(&map_obj)) return maybe_map_obj;
- }
+ Map* map;
+ MaybeObject* maybe_map = AllocateMap(JS_OBJECT_TYPE, instance_size);
+ if (!maybe_map->To(&map)) return maybe_map;
// Fetch or allocate prototype.
Object* prototype;
if (fun->has_instance_prototype()) {
prototype = fun->instance_prototype();
} else {
- { MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun);
- if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
- }
+ MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun);
+ if (!maybe_prototype->To(&prototype)) return maybe_prototype;
}
- Map* map = Map::cast(map_obj);
map->set_inobject_properties(in_object_properties);
map->set_unused_property_fields(in_object_properties);
map->set_prototype(prototype);
@@ -3820,22 +3935,17 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) {
fun->shared()->ForbidInlineConstructor();
} else {
DescriptorArray* descriptors;
- { MaybeObject* maybe_descriptors_obj =
- DescriptorArray::Allocate(count, DescriptorArray::MAY_BE_SHARED);
- if (!maybe_descriptors_obj->To<DescriptorArray>(&descriptors)) {
- return maybe_descriptors_obj;
- }
- }
+ MaybeObject* maybe_descriptors = DescriptorArray::Allocate(count);
+ if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
+
DescriptorArray::WhitenessWitness witness(descriptors);
for (int i = 0; i < count; i++) {
String* name = fun->shared()->GetThisPropertyAssignmentName(i);
ASSERT(name->IsSymbol());
- FieldDescriptor field(name, i, NONE);
- field.SetEnumerationIndex(i);
+ FieldDescriptor field(name, i, NONE, i + 1);
descriptors->Set(i, &field, witness);
}
- descriptors->SetNextEnumerationIndex(count);
- descriptors->SortUnchecked(witness);
+ descriptors->Sort();
// The descriptors may contain duplicates because the compiler does not
// guarantee the uniqueness of property names (it would have required
@@ -3844,7 +3954,7 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) {
if (HasDuplicates(descriptors)) {
fun->shared()->ForbidInlineConstructor();
} else {
- map->set_instance_descriptors(descriptors);
+ map->InitializeDescriptors(descriptors);
map->set_pre_allocated_property_fields(count);
map->set_unused_property_fields(in_object_properties - count);
}
@@ -3951,13 +4061,18 @@ MaybeObject* Heap::AllocateJSObject(JSFunction* constructor,
}
-MaybeObject* Heap::AllocateJSModule() {
+MaybeObject* Heap::AllocateJSModule(Context* context, ScopeInfo* scope_info) {
// Allocate a fresh map. Modules do not have a prototype.
Map* map;
MaybeObject* maybe_map = AllocateMap(JS_MODULE_TYPE, JSModule::kSize);
if (!maybe_map->To(&map)) return maybe_map;
// Allocate the object based on the map.
- return AllocateJSObjectFromMap(map, TENURED);
+ JSModule* module;
+ MaybeObject* maybe_module = AllocateJSObjectFromMap(map, TENURED);
+ if (!maybe_module->To(&module)) return maybe_module;
+ module->set_context(context);
+ module->set_scope_info(scope_info);
+ return module;
}
@@ -4071,6 +4186,7 @@ MaybeObject* Heap::AllocateJSFunctionProxy(Object* handler,
MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
ASSERT(constructor->has_initial_map());
Map* map = constructor->initial_map();
+ ASSERT(map->is_dictionary_map());
// Make sure no field properties are described in the initial map.
// This guarantees us that normalizing the properties does not
@@ -4088,13 +4204,11 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512;
// Allocate a dictionary object for backing storage.
- Object* obj;
- { MaybeObject* maybe_obj =
- StringDictionary::Allocate(
- map->NumberOfDescribedProperties() * 2 + initial_size);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- StringDictionary* dictionary = StringDictionary::cast(obj);
+ StringDictionary* dictionary;
+ MaybeObject* maybe_dictionary =
+ StringDictionary::Allocate(
+ map->NumberOfOwnDescriptors() * 2 + initial_size);
+ if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
// The global object might be created from an object template with accessors.
// Fill these accessors into the dictionary.
@@ -4102,36 +4216,32 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
for (int i = 0; i < descs->number_of_descriptors(); i++) {
PropertyDetails details = descs->GetDetails(i);
ASSERT(details.type() == CALLBACKS); // Only accessors are expected.
- PropertyDetails d =
- PropertyDetails(details.attributes(), CALLBACKS, details.index());
+ PropertyDetails d = PropertyDetails(details.attributes(),
+ CALLBACKS,
+ details.descriptor_index());
Object* value = descs->GetCallbacksObject(i);
- { MaybeObject* maybe_value = AllocateJSGlobalPropertyCell(value);
- if (!maybe_value->ToObject(&value)) return maybe_value;
- }
+ MaybeObject* maybe_value = AllocateJSGlobalPropertyCell(value);
+ if (!maybe_value->ToObject(&value)) return maybe_value;
- Object* result;
- { MaybeObject* maybe_result = dictionary->Add(descs->GetKey(i), value, d);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- dictionary = StringDictionary::cast(result);
+ MaybeObject* maybe_added = dictionary->Add(descs->GetKey(i), value, d);
+ if (!maybe_added->To(&dictionary)) return maybe_added;
}
// Allocate the global object and initialize it with the backing store.
- { MaybeObject* maybe_obj = Allocate(map, OLD_POINTER_SPACE);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- JSObject* global = JSObject::cast(obj);
+ JSObject* global;
+ MaybeObject* maybe_global = Allocate(map, OLD_POINTER_SPACE);
+ if (!maybe_global->To(&global)) return maybe_global;
+
InitializeJSObjectFromMap(global, dictionary, map);
// Create a new map for the global object.
- { MaybeObject* maybe_obj = map->CopyDropDescriptors();
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- Map* new_map = Map::cast(obj);
+ Map* new_map;
+ MaybeObject* maybe_map = map->CopyDropDescriptors();
+ if (!maybe_map->To(&new_map)) return maybe_map;
+ new_map->set_dictionary_map(true);
// Set up the global object as a normalized object.
global->set_map(new_map);
- global->map()->clear_instance_descriptors();
global->set_properties(dictionary);
// Make sure result is a global object with properties in dictionary.
@@ -4260,7 +4370,7 @@ MaybeObject* Heap::ReinitializeJSReceiver(
map->set_function_with_prototype(true);
InitializeFunction(JSFunction::cast(object), shared, the_hole_value());
JSFunction::cast(object)->set_context(
- isolate()->context()->global_context());
+ isolate()->context()->native_context());
}
// Put in filler if the new object is smaller than the old.
@@ -4301,7 +4411,8 @@ MaybeObject* Heap::ReinitializeJSGlobalProxy(JSFunction* constructor,
MaybeObject* Heap::AllocateStringFromAscii(Vector<const char> string,
PretenureFlag pretenure) {
- if (string.length() == 1) {
+ int length = string.length();
+ if (length == 1) {
return Heap::LookupSingleCharacterStringFromCode(string[0]);
}
Object* result;
@@ -4311,22 +4422,20 @@ MaybeObject* Heap::AllocateStringFromAscii(Vector<const char> string,
}
// Copy the characters into the new object.
- SeqAsciiString* string_result = SeqAsciiString::cast(result);
- for (int i = 0; i < string.length(); i++) {
- string_result->SeqAsciiStringSet(i, string[i]);
- }
+ CopyChars(SeqAsciiString::cast(result)->GetChars(), string.start(), length);
return result;
}
MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
+ int non_ascii_start,
PretenureFlag pretenure) {
- // Count the number of characters in the UTF-8 string and check if
- // it is an ASCII string.
+ // Continue counting the number of characters in the UTF-8 string, starting
+ // from the first non-ascii character or word.
+ int chars = non_ascii_start;
Access<UnicodeCache::Utf8Decoder>
decoder(isolate_->unicode_cache()->utf8_decoder());
- decoder->Reset(string.start(), string.length());
- int chars = 0;
+ decoder->Reset(string.start() + non_ascii_start, string.length() - chars);
while (decoder->has_more()) {
uint32_t r = decoder->GetNext();
if (r <= unibrow::Utf16::kMaxNonSurrogateCharCode) {
@@ -4342,16 +4451,16 @@ MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
}
// Convert and copy the characters into the new object.
- String* string_result = String::cast(result);
+ SeqTwoByteString* twobyte = SeqTwoByteString::cast(result);
decoder->Reset(string.start(), string.length());
int i = 0;
while (i < chars) {
uint32_t r = decoder->GetNext();
if (r > unibrow::Utf16::kMaxNonSurrogateCharCode) {
- string_result->Set(i++, unibrow::Utf16::LeadSurrogate(r));
- string_result->Set(i++, unibrow::Utf16::TrailSurrogate(r));
+ twobyte->SeqTwoByteStringSet(i++, unibrow::Utf16::LeadSurrogate(r));
+ twobyte->SeqTwoByteStringSet(i++, unibrow::Utf16::TrailSurrogate(r));
} else {
- string_result->Set(i++, r);
+ twobyte->SeqTwoByteStringSet(i++, r);
}
}
return result;
@@ -4361,20 +4470,18 @@ MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
MaybeObject* Heap::AllocateStringFromTwoByte(Vector<const uc16> string,
PretenureFlag pretenure) {
// Check if the string is an ASCII string.
- MaybeObject* maybe_result;
- if (String::IsAscii(string.start(), string.length())) {
- maybe_result = AllocateRawAsciiString(string.length(), pretenure);
- } else { // It's not an ASCII string.
- maybe_result = AllocateRawTwoByteString(string.length(), pretenure);
- }
Object* result;
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ int length = string.length();
+ const uc16* start = string.start();
- // Copy the characters into the new object, which may be either ASCII or
- // UTF-16.
- String* string_result = String::cast(result);
- for (int i = 0; i < string.length(); i++) {
- string_result->Set(i, string[i]);
+ if (String::IsAscii(start, length)) {
+ MaybeObject* maybe_result = AllocateRawAsciiString(length, pretenure);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ CopyChars(SeqAsciiString::cast(result)->GetChars(), start, length);
+ } else { // It's not an ASCII string.
+ MaybeObject* maybe_result = AllocateRawTwoByteString(length, pretenure);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ CopyChars(SeqTwoByteString::cast(result)->GetChars(), start, length);
}
return result;
}
@@ -4503,14 +4610,14 @@ MaybeObject* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) {
String::cast(result)->set_hash_field(String::kEmptyHashField);
ASSERT_EQ(size, HeapObject::cast(result)->Size());
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
// Initialize string's content to ensure ASCII-ness (character range 0-127)
// as required when verifying the heap.
char* dest = SeqAsciiString::cast(result)->GetChars();
memset(dest, 0x0F, length * kCharSize);
}
-#endif // DEBUG
+#endif
return result;
}
@@ -4555,10 +4662,10 @@ MaybeObject* Heap::AllocateRawTwoByteString(int length,
MaybeObject* Heap::AllocateJSArray(
ElementsKind elements_kind,
PretenureFlag pretenure) {
- Context* global_context = isolate()->context()->global_context();
- JSFunction* array_function = global_context->array_function();
+ Context* native_context = isolate()->context()->native_context();
+ JSFunction* array_function = native_context->array_function();
Map* map = array_function->initial_map();
- Object* maybe_map_array = global_context->js_array_maps();
+ Object* maybe_map_array = native_context->js_array_maps();
if (!maybe_map_array->IsUndefined()) {
Object* maybe_transitioned_map =
FixedArray::cast(maybe_map_array)->get(elements_kind);
@@ -4841,33 +4948,50 @@ MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) {
}
-MaybeObject* Heap::AllocateGlobalContext() {
+MaybeObject* Heap::AllocateNativeContext() {
Object* result;
{ MaybeObject* maybe_result =
- AllocateFixedArray(Context::GLOBAL_CONTEXT_SLOTS);
+ AllocateFixedArray(Context::NATIVE_CONTEXT_SLOTS);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Context* context = reinterpret_cast<Context*>(result);
- context->set_map_no_write_barrier(global_context_map());
+ context->set_map_no_write_barrier(native_context_map());
context->set_js_array_maps(undefined_value());
- ASSERT(context->IsGlobalContext());
+ ASSERT(context->IsNativeContext());
ASSERT(result->IsContext());
return result;
}
-MaybeObject* Heap::AllocateModuleContext(Context* previous,
+MaybeObject* Heap::AllocateGlobalContext(JSFunction* function,
ScopeInfo* scope_info) {
Object* result;
{ MaybeObject* maybe_result =
- AllocateFixedArrayWithHoles(scope_info->ContextLength(), TENURED);
+ AllocateFixedArray(scope_info->ContextLength(), TENURED);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Context* context = reinterpret_cast<Context*>(result);
- context->set_map_no_write_barrier(module_context_map());
- context->set_previous(previous);
+ context->set_map_no_write_barrier(global_context_map());
+ context->set_closure(function);
+ context->set_previous(function->context());
context->set_extension(scope_info);
- context->set_global(previous->global());
+ context->set_global_object(function->context()->global_object());
+ ASSERT(context->IsGlobalContext());
+ ASSERT(result->IsContext());
+ return context;
+}
+
+
+MaybeObject* Heap::AllocateModuleContext(ScopeInfo* scope_info) {
+ Object* result;
+ { MaybeObject* maybe_result =
+ AllocateFixedArray(scope_info->ContextLength(), TENURED);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ Context* context = reinterpret_cast<Context*>(result);
+ context->set_map_no_write_barrier(module_context_map());
+ // Context links will be set later.
+ context->set_extension(Smi::FromInt(0));
return context;
}
@@ -4882,8 +5006,8 @@ MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) {
context->set_map_no_write_barrier(function_context_map());
context->set_closure(function);
context->set_previous(function->context());
- context->set_extension(NULL);
- context->set_global(function->context()->global());
+ context->set_extension(Smi::FromInt(0));
+ context->set_global_object(function->context()->global_object());
return context;
}
@@ -4903,7 +5027,7 @@ MaybeObject* Heap::AllocateCatchContext(JSFunction* function,
context->set_closure(function);
context->set_previous(previous);
context->set_extension(name);
- context->set_global(previous->global());
+ context->set_global_object(previous->global_object());
context->set(Context::THROWN_OBJECT_INDEX, thrown_object);
return context;
}
@@ -4921,7 +5045,7 @@ MaybeObject* Heap::AllocateWithContext(JSFunction* function,
context->set_closure(function);
context->set_previous(previous);
context->set_extension(extension);
- context->set_global(previous->global());
+ context->set_global_object(previous->global_object());
return context;
}
@@ -4939,7 +5063,7 @@ MaybeObject* Heap::AllocateBlockContext(JSFunction* function,
context->set_closure(function);
context->set_previous(previous);
context->set_extension(scope_info);
- context->set_global(previous->global());
+ context->set_global_object(previous->global_object());
return context;
}
@@ -5022,7 +5146,8 @@ bool Heap::IdleNotification(int hint) {
// The size factor is in range [5..250]. The numbers here are chosen from
// experiments. If you changes them, make sure to test with
// chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.*
- intptr_t step_size = size_factor * IncrementalMarking::kAllocatedThreshold;
+ intptr_t step_size =
+ size_factor * IncrementalMarking::kAllocatedThreshold;
if (contexts_disposed_ > 0) {
if (hint >= kMaxHint) {
@@ -5282,9 +5407,9 @@ bool Heap::InSpace(Address addr, AllocationSpace space) {
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
void Heap::Verify() {
- ASSERT(HasBeenSetUp());
+ CHECK(HasBeenSetUp());
store_buffer()->Verify();
@@ -5302,38 +5427,8 @@ void Heap::Verify() {
cell_space_->Verify(&no_dirty_regions_visitor);
lo_space_->Verify();
-
- VerifyNoAccessorPairSharing();
-}
-
-
-void Heap::VerifyNoAccessorPairSharing() {
- // Verification is done in 2 phases: First we mark all AccessorPairs, checking
- // that we mark only unmarked pairs, then we clear all marks, restoring the
- // initial state. We use the Smi tag of the AccessorPair's getter as the
- // marking bit, because we can never see a Smi as the getter.
- for (int phase = 0; phase < 2; phase++) {
- HeapObjectIterator iter(map_space());
- for (HeapObject* obj = iter.Next(); obj != NULL; obj = iter.Next()) {
- if (obj->IsMap()) {
- DescriptorArray* descs = Map::cast(obj)->instance_descriptors();
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
- if (descs->GetType(i) == CALLBACKS &&
- descs->GetValue(i)->IsAccessorPair()) {
- AccessorPair* accessors = AccessorPair::cast(descs->GetValue(i));
- uintptr_t before = reinterpret_cast<intptr_t>(accessors->getter());
- uintptr_t after = (phase == 0) ?
- ((before & ~kSmiTagMask) | kSmiTag) :
- ((before & ~kHeapObjectTag) | kHeapObjectTag);
- CHECK(before != after);
- accessors->set_getter(reinterpret_cast<Object*>(after));
- }
- }
- }
- }
- }
}
-#endif // DEBUG
+#endif
MaybeObject* Heap::LookupSymbol(Vector<const char> string) {
@@ -5425,8 +5520,6 @@ bool Heap::LookupSymbolIfExists(String* string, String** symbol) {
return symbol_table()->LookupSymbolIfExists(string, symbol);
}
-
-#ifdef DEBUG
void Heap::ZapFromSpace() {
NewSpacePageIterator it(new_space_.FromSpaceStart(),
new_space_.FromSpaceEnd());
@@ -5439,7 +5532,6 @@ void Heap::ZapFromSpace() {
}
}
}
-#endif // DEBUG
void Heap::IterateAndMarkPointersToFromSpace(Address start,
@@ -5689,6 +5781,7 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
// Iterate over local handles in handle scopes.
isolate_->handle_scope_implementer()->Iterate(v);
+ isolate_->IterateDeferredHandles(v);
v->Synchronize(VisitorSynchronization::kHandleScope);
// Iterate over the builtin code objects and code stubs in the
@@ -5751,8 +5844,8 @@ bool Heap::ConfigureHeap(int max_semispace_size,
if (max_semispace_size < Page::kPageSize) {
max_semispace_size = Page::kPageSize;
if (FLAG_trace_gc) {
- PrintF("Max semispace size cannot be less than %dkbytes\n",
- Page::kPageSize >> 10);
+ PrintPID("Max semispace size cannot be less than %dkbytes\n",
+ Page::kPageSize >> 10);
}
}
max_semispace_size_ = max_semispace_size;
@@ -5767,8 +5860,8 @@ bool Heap::ConfigureHeap(int max_semispace_size,
if (max_semispace_size_ > reserved_semispace_size_) {
max_semispace_size_ = reserved_semispace_size_;
if (FLAG_trace_gc) {
- PrintF("Max semispace size cannot be more than %dkbytes\n",
- reserved_semispace_size_ >> 10);
+ PrintPID("Max semispace size cannot be more than %dkbytes\n",
+ reserved_semispace_size_ >> 10);
}
}
} else {
@@ -5793,7 +5886,7 @@ bool Heap::ConfigureHeap(int max_semispace_size,
max_semispace_size_ = RoundUpToPowerOf2(max_semispace_size_);
reserved_semispace_size_ = RoundUpToPowerOf2(reserved_semispace_size_);
initial_semispace_size_ = Min(initial_semispace_size_, max_semispace_size_);
- external_allocation_limit_ = 10 * max_semispace_size_;
+ external_allocation_limit_ = 16 * max_semispace_size_;
// The old generation is paged and needs at least one page for each space.
int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1;
@@ -6143,7 +6236,7 @@ bool Heap::SetUp(bool create_heap_objects) {
// Create initial objects
if (!CreateInitialObjects()) return false;
- global_contexts_list_ = undefined_value();
+ native_contexts_list_ = undefined_value();
}
LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
@@ -6151,6 +6244,8 @@ bool Heap::SetUp(bool create_heap_objects) {
store_buffer()->SetUp();
+ if (FLAG_parallel_recompilation) relocation_mutex_ = OS::CreateMutex();
+
return true;
}
@@ -6173,16 +6268,18 @@ void Heap::SetStackLimits() {
void Heap::TearDown() {
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
Verify();
}
#endif
+
if (FLAG_print_cumulative_gc_stat) {
PrintF("\n\n");
PrintF("gc_count=%d ", gc_count_);
PrintF("mark_sweep_count=%d ", ms_count_);
PrintF("max_gc_pause=%d ", get_max_gc_pause());
+ PrintF("total_gc_time=%d ", total_gc_time_ms_);
PrintF("min_in_mutator=%d ", get_min_in_mutator());
PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ",
get_max_alive_after_gc());
@@ -6236,6 +6333,8 @@ void Heap::TearDown() {
isolate_->memory_allocator()->TearDown();
+ delete relocation_mutex_;
+
#ifdef DEBUG
delete debug_utils_;
debug_utils_ = NULL;
@@ -6653,7 +6752,7 @@ void PathTracer::TracePathFrom(Object** root) {
ASSERT((search_target_ == kAnyGlobalObject) ||
search_target_->IsHeapObject());
found_target_in_trace_ = false;
- object_stack_.Clear();
+ Reset();
MarkVisitor mark_visitor(this);
MarkRecursively(root, &mark_visitor);
@@ -6665,8 +6764,8 @@ void PathTracer::TracePathFrom(Object** root) {
}
-static bool SafeIsGlobalContext(HeapObject* obj) {
- return obj->map() == obj->GetHeap()->raw_unchecked_global_context_map();
+static bool SafeIsNativeContext(HeapObject* obj) {
+ return obj->map() == obj->GetHeap()->raw_unchecked_native_context_map();
}
@@ -6688,7 +6787,7 @@ void PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) {
return;
}
- bool is_global_context = SafeIsGlobalContext(obj);
+ bool is_native_context = SafeIsNativeContext(obj);
// not visited yet
Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map));
@@ -6698,7 +6797,7 @@ void PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) {
obj->set_map_no_write_barrier(reinterpret_cast<Map*>(map_addr + kMarkTag));
// Scan the object body.
- if (is_global_context && (visit_mode_ == VISIT_ONLY_STRONG)) {
+ if (is_native_context && (visit_mode_ == VISIT_ONLY_STRONG)) {
// This is specialized to scan Context's properly.
Object** start = reinterpret_cast<Object**>(obj->address() +
Context::kHeaderSize);
@@ -6757,11 +6856,7 @@ void PathTracer::ProcessResults() {
for (int i = 0; i < object_stack_.length(); i++) {
if (i > 0) PrintF("\n |\n |\n V\n\n");
Object* obj = object_stack_[i];
-#ifdef OBJECT_PRINT
obj->Print();
-#else
- obj->ShortPrint();
-#endif
}
PrintF("=====================================\n");
}
@@ -6770,6 +6865,15 @@ void PathTracer::ProcessResults() {
#ifdef DEBUG
+// Triggers a depth-first traversal of reachable objects from one
+// given root object and finds a path to a specific heap object and
+// prints it.
+void Heap::TracePathToObjectFrom(Object* target, Object* root) {
+ PathTracer tracer(target, PathTracer::FIND_ALL, VISIT_ALL);
+ tracer.VisitPointer(&root);
+}
+
+
// Triggers a depth-first traversal of reachable objects from roots
// and finds a path to a specific heap object and prints it.
void Heap::TracePathToObject(Object* target) {
@@ -6857,6 +6961,7 @@ GCTracer::~GCTracer() {
// Update cumulative GC statistics if required.
if (FLAG_print_cumulative_gc_stat) {
+ heap_->total_gc_time_ms_ += time;
heap_->max_gc_pause_ = Max(heap_->max_gc_pause_, time);
heap_->max_alive_after_gc_ = Max(heap_->max_alive_after_gc_,
heap_->alive_after_last_gc_);
@@ -6864,9 +6969,13 @@ GCTracer::~GCTracer() {
heap_->min_in_mutator_ = Min(heap_->min_in_mutator_,
static_cast<int>(spent_in_mutator_));
}
+ } else if (FLAG_trace_gc_verbose) {
+ heap_->total_gc_time_ms_ += time;
}
- PrintF("%8.0f ms: ", heap_->isolate()->time_millis_since_init());
+ if (collector_ == SCAVENGER && FLAG_trace_gc_ignore_scavenger) return;
+
+ PrintPID("%8.0f ms: ", heap_->isolate()->time_millis_since_init());
if (!FLAG_trace_gc_nvp) {
int external_time = static_cast<int>(scopes_[Scope::EXTERNAL]);
@@ -6908,9 +7017,7 @@ GCTracer::~GCTracer() {
PrintF(".\n");
} else {
PrintF("pause=%d ", time);
- PrintF("mutator=%d ",
- static_cast<int>(spent_in_mutator_));
-
+ PrintF("mutator=%d ", static_cast<int>(spent_in_mutator_));
PrintF("gc=");
switch (collector_) {
case SCAVENGER:
@@ -7037,7 +7144,7 @@ void KeyedLookupCache::Clear() {
void DescriptorLookupCache::Clear() {
- for (int index = 0; index < kLength; index++) keys_[index].array = NULL;
+ for (int index = 0; index < kLength; index++) keys_[index].source = NULL;
}
@@ -7096,9 +7203,11 @@ void ExternalStringTable::CleanUp() {
old_space_strings_[last++] = old_space_strings_[i];
}
old_space_strings_.Rewind(last);
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
Verify();
}
+#endif
}
@@ -7176,4 +7285,63 @@ void Heap::RememberUnmappedPage(Address page, bool compacted) {
remembered_unmapped_pages_index_ %= kRememberedUnmappedPages;
}
+
+void Heap::ClearObjectStats(bool clear_last_time_stats) {
+ memset(object_counts_, 0, sizeof(object_counts_));
+ memset(object_sizes_, 0, sizeof(object_sizes_));
+ if (clear_last_time_stats) {
+ memset(object_counts_last_time_, 0, sizeof(object_counts_last_time_));
+ memset(object_sizes_last_time_, 0, sizeof(object_sizes_last_time_));
+ }
+}
+
+
+static LazyMutex checkpoint_object_stats_mutex = LAZY_MUTEX_INITIALIZER;
+
+
+void Heap::CheckpointObjectStats() {
+ ScopedLock lock(checkpoint_object_stats_mutex.Pointer());
+ Counters* counters = isolate()->counters();
+#define ADJUST_LAST_TIME_OBJECT_COUNT(name) \
+ counters->count_of_##name()->Increment( \
+ static_cast<int>(object_counts_[name])); \
+ counters->count_of_##name()->Decrement( \
+ static_cast<int>(object_counts_last_time_[name])); \
+ counters->size_of_##name()->Increment( \
+ static_cast<int>(object_sizes_[name])); \
+ counters->size_of_##name()->Decrement( \
+ static_cast<int>(object_sizes_last_time_[name]));
+ INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
+#undef ADJUST_LAST_TIME_OBJECT_COUNT
+ int index;
+#define ADJUST_LAST_TIME_OBJECT_COUNT(name) \
+ index = FIRST_CODE_KIND_SUB_TYPE + Code::name; \
+ counters->count_of_CODE_TYPE_##name()->Increment( \
+ static_cast<int>(object_counts_[index])); \
+ counters->count_of_CODE_TYPE_##name()->Decrement( \
+ static_cast<int>(object_counts_last_time_[index])); \
+ counters->size_of_CODE_TYPE_##name()->Increment( \
+ static_cast<int>(object_sizes_[index])); \
+ counters->size_of_CODE_TYPE_##name()->Decrement( \
+ static_cast<int>(object_sizes_last_time_[index]));
+ CODE_KIND_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
+#undef ADJUST_LAST_TIME_OBJECT_COUNT
+#define ADJUST_LAST_TIME_OBJECT_COUNT(name) \
+ index = FIRST_FIXED_ARRAY_SUB_TYPE + name; \
+ counters->count_of_FIXED_ARRAY_##name()->Increment( \
+ static_cast<int>(object_counts_[index])); \
+ counters->count_of_FIXED_ARRAY_##name()->Decrement( \
+ static_cast<int>(object_counts_last_time_[index])); \
+ counters->size_of_FIXED_ARRAY_##name()->Increment( \
+ static_cast<int>(object_sizes_[index])); \
+ counters->size_of_FIXED_ARRAY_##name()->Decrement( \
+ static_cast<int>(object_sizes_last_time_[index]));
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
+#undef ADJUST_LAST_TIME_OBJECT_COUNT
+
+ memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
+ memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
+ ClearObjectStats();
+}
+
} } // namespace v8::internal
diff --git a/deps/v8/src/heap.h b/deps/v8/src/heap.h
index f80f2a780..0ab7ae0bd 100644
--- a/deps/v8/src/heap.h
+++ b/deps/v8/src/heap.h
@@ -64,7 +64,7 @@ namespace internal {
V(Map, ascii_symbol_map, AsciiSymbolMap) \
V(Map, ascii_string_map, AsciiStringMap) \
V(Map, heap_number_map, HeapNumberMap) \
- V(Map, global_context_map, GlobalContextMap) \
+ V(Map, native_context_map, NativeContextMap) \
V(Map, fixed_array_map, FixedArrayMap) \
V(Map, code_map, CodeMap) \
V(Map, scope_info_map, ScopeInfoMap) \
@@ -87,6 +87,7 @@ namespace internal {
V(Object, instanceof_cache_answer, InstanceofCacheAnswer) \
V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \
V(FixedArray, string_split_cache, StringSplitCache) \
+ V(FixedArray, regexp_multiple_cache, RegExpMultipleCache) \
V(Object, termination_exception, TerminationException) \
V(Smi, hash_seed, HashSeed) \
V(Map, string_map, StringMap) \
@@ -130,6 +131,7 @@ namespace internal {
V(Map, with_context_map, WithContextMap) \
V(Map, block_context_map, BlockContextMap) \
V(Map, module_context_map, ModuleContextMap) \
+ V(Map, global_context_map, GlobalContextMap) \
V(Map, oddball_map, OddballMap) \
V(Map, message_object_map, JSMessageObjectMap) \
V(Map, foreign_map, ForeignMap) \
@@ -150,7 +152,9 @@ namespace internal {
V(Smi, real_stack_limit, RealStackLimit) \
V(StringDictionary, intrinsic_function_names, IntrinsicFunctionNames) \
V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset) \
- V(Smi, construct_stub_deopt_pc_offset, ConstructStubDeoptPCOffset)
+ V(Smi, construct_stub_deopt_pc_offset, ConstructStubDeoptPCOffset) \
+ V(Smi, getter_stub_deopt_pc_offset, GetterStubDeoptPCOffset) \
+ V(Smi, setter_stub_deopt_pc_offset, SetterStubDeoptPCOffset)
#define ROOT_LIST(V) \
STRONG_ROOT_LIST(V) \
@@ -172,6 +176,7 @@ namespace internal {
V(constructor_symbol, "constructor") \
V(code_symbol, ".code") \
V(result_symbol, ".result") \
+ V(dot_for_symbol, ".for.") \
V(catch_var_symbol, ".catch-var") \
V(empty_symbol, "") \
V(eval_symbol, "eval") \
@@ -504,6 +509,24 @@ class Heap {
MapSpace* map_space() { return map_space_; }
CellSpace* cell_space() { return cell_space_; }
LargeObjectSpace* lo_space() { return lo_space_; }
+ PagedSpace* paged_space(int idx) {
+ switch (idx) {
+ case OLD_POINTER_SPACE:
+ return old_pointer_space();
+ case OLD_DATA_SPACE:
+ return old_data_space();
+ case MAP_SPACE:
+ return map_space();
+ case CELL_SPACE:
+ return cell_space();
+ case CODE_SPACE:
+ return code_space();
+ case NEW_SPACE:
+ case LO_SPACE:
+ UNREACHABLE();
+ }
+ return NULL;
+ }
bool always_allocate() { return always_allocate_scope_depth_ != 0; }
Address always_allocate_scope_depth_address() {
@@ -531,7 +554,8 @@ class Heap {
MUST_USE_RESULT MaybeObject* AllocateJSObject(
JSFunction* constructor, PretenureFlag pretenure = NOT_TENURED);
- MUST_USE_RESULT MaybeObject* AllocateJSModule();
+ MUST_USE_RESULT MaybeObject* AllocateJSModule(Context* context,
+ ScopeInfo* scope_info);
// Allocate a JSArray with no elements
MUST_USE_RESULT MaybeObject* AllocateEmptyJSArray(
@@ -652,6 +676,9 @@ class Heap {
// Clear the Instanceof cache (used when a prototype changes).
inline void ClearInstanceofCache();
+ // For use during bootup.
+ void RepairFreeListsAfterBoot();
+
// Allocates and fully initializes a String. There are two String
// encodings: ASCII and two byte. One should choose between the three string
// allocation functions based on the encoding of the string buffer used to
@@ -678,6 +705,7 @@ class Heap {
PretenureFlag pretenure = NOT_TENURED);
MUST_USE_RESULT MaybeObject* AllocateStringFromUtf8Slow(
Vector<const char> str,
+ int non_ascii_start,
PretenureFlag pretenure = NOT_TENURED);
MUST_USE_RESULT MaybeObject* AllocateStringFromTwoByte(
Vector<const uc16> str,
@@ -821,13 +849,16 @@ class Heap {
MUST_USE_RESULT MaybeObject* AllocateHashTable(
int length, PretenureFlag pretenure = NOT_TENURED);
- // Allocate a global (but otherwise uninitialized) context.
- MUST_USE_RESULT MaybeObject* AllocateGlobalContext();
+ // Allocate a native (but otherwise uninitialized) context.
+ MUST_USE_RESULT MaybeObject* AllocateNativeContext();
- // Allocate a module context.
- MUST_USE_RESULT MaybeObject* AllocateModuleContext(Context* previous,
+ // Allocate a global context.
+ MUST_USE_RESULT MaybeObject* AllocateGlobalContext(JSFunction* function,
ScopeInfo* scope_info);
+ // Allocate a module context.
+ MUST_USE_RESULT MaybeObject* AllocateModuleContext(ScopeInfo* scope_info);
+
// Allocate a function context.
MUST_USE_RESULT MaybeObject* AllocateFunctionContext(int length,
JSFunction* function);
@@ -1073,7 +1104,10 @@ class Heap {
void EnsureHeapIsIterable();
// Notify the heap that a context has been disposed.
- int NotifyContextDisposed() { return ++contexts_disposed_; }
+ int NotifyContextDisposed() {
+ flush_monomorphic_ics_ = true;
+ return ++contexts_disposed_;
+ }
// Utility to invoke the scavenger. This is needed in test code to
// ensure correct callback for weak global handles.
@@ -1101,8 +1135,8 @@ class Heap {
#endif
void AddGCPrologueCallback(
- GCEpilogueCallback callback, GCType gc_type_filter);
- void RemoveGCPrologueCallback(GCEpilogueCallback callback);
+ GCPrologueCallback callback, GCType gc_type_filter);
+ void RemoveGCPrologueCallback(GCPrologueCallback callback);
void AddGCEpilogueCallback(
GCEpilogueCallback callback, GCType gc_type_filter);
@@ -1149,13 +1183,13 @@ class Heap {
// not match the empty string.
String* hidden_symbol() { return hidden_symbol_; }
- void set_global_contexts_list(Object* object) {
- global_contexts_list_ = object;
+ void set_native_contexts_list(Object* object) {
+ native_contexts_list_ = object;
}
- Object* global_contexts_list() { return global_contexts_list_; }
+ Object* native_contexts_list() { return native_contexts_list_; }
// Number of mark-sweeps.
- int ms_count() { return ms_count_; }
+ unsigned int ms_count() { return ms_count_; }
// Iterates over all roots in the heap.
void IterateRoots(ObjectVisitor* v, VisitMode mode);
@@ -1226,21 +1260,19 @@ class Heap {
return reinterpret_cast<Address*>(&roots_[kStoreBufferTopRootIndex]);
}
- // Get address of global contexts list for serialization support.
- Object** global_contexts_list_address() {
- return &global_contexts_list_;
+ // Get address of native contexts list for serialization support.
+ Object** native_contexts_list_address() {
+ return &native_contexts_list_;
}
-#ifdef DEBUG
- void Print();
- void PrintHandles();
-
+#ifdef VERIFY_HEAP
// Verify the heap is in its normal state before or after a GC.
void Verify();
+#endif
- // Verify that AccessorPairs are not shared, i.e. make sure that they have
- // exactly one pointer to them.
- void VerifyNoAccessorPairSharing();
+#ifdef DEBUG
+ void Print();
+ void PrintHandles();
void OldPointerSpaceCheckStoreBuffer();
void MapSpaceCheckStoreBuffer();
@@ -1249,10 +1281,23 @@ class Heap {
// Report heap statistics.
void ReportHeapStatistics(const char* title);
void ReportCodeStatistics(const char* title);
+#endif
+
+ // Zapping is needed for verify heap, and always done in debug builds.
+ static inline bool ShouldZapGarbage() {
+#ifdef DEBUG
+ return true;
+#else
+#ifdef VERIFY_HEAP
+ return FLAG_verify_heap;
+#else
+ return false;
+#endif
+#endif
+ }
// Fill in bogus values in from space
void ZapFromSpace();
-#endif
// Print short heap statistics.
void PrintShortHeapStatistics();
@@ -1290,6 +1335,7 @@ class Heap {
return disallow_allocation_failure_;
}
+ void TracePathToObjectFrom(Object* target, Object* root);
void TracePathToObject(Object* target);
void TracePathToGlobal();
#endif
@@ -1304,20 +1350,9 @@ class Heap {
// Commits from space if it is uncommitted.
void EnsureFromSpaceIsCommitted();
- // Support for partial snapshots. After calling this we can allocate a
- // certain number of bytes using only linear allocation (with a
- // LinearAllocationScope and an AlwaysAllocateScope) without using freelists
- // or causing a GC. It returns true of space was reserved or false if a GC is
- // needed. For paged spaces the space requested must include the space wasted
- // at the end of each page when allocating linearly.
- void ReserveSpace(
- int new_space_size,
- int pointer_space_size,
- int data_space_size,
- int code_space_size,
- int map_space_size,
- int cell_space_size,
- int large_object_size);
+ // Support for partial snapshots. After calling this we have a linear
+ // space to write objects in each space.
+ void ReserveSpace(int *sizes, Address* addresses);
//
// Support for the API.
@@ -1393,15 +1428,15 @@ class Heap {
STRONG_ROOT_LIST(ROOT_INDEX_DECLARATION)
#undef ROOT_INDEX_DECLARATION
-// Utility type maps
-#define DECLARE_STRUCT_MAP(NAME, Name, name) k##Name##MapRootIndex,
- STRUCT_LIST(DECLARE_STRUCT_MAP)
-#undef DECLARE_STRUCT_MAP
-
#define SYMBOL_INDEX_DECLARATION(name, str) k##name##RootIndex,
SYMBOL_LIST(SYMBOL_INDEX_DECLARATION)
#undef SYMBOL_DECLARATION
+ // Utility type maps
+#define DECLARE_STRUCT_MAP(NAME, Name, name) k##Name##MapRootIndex,
+ STRUCT_LIST(DECLARE_STRUCT_MAP)
+#undef DECLARE_STRUCT_MAP
+
kSymbolTableRootIndex,
kStrongRootListLength = kSymbolTableRootIndex,
kRootListLength
@@ -1484,13 +1519,6 @@ class Heap {
void ClearNormalizedMapCaches();
- // Clears the cache of ICs related to this map.
- void ClearCacheOnMap(Map* map) {
- if (FLAG_cleanup_code_caches_at_gc) {
- map->ClearCodeCache(this);
- }
- }
-
GCTracer* tracer() { return tracer_; }
// Returns the size of objects residing in non new spaces.
@@ -1588,6 +1616,16 @@ class Heap {
set_construct_stub_deopt_pc_offset(Smi::FromInt(pc_offset));
}
+ void SetGetterStubDeoptPCOffset(int pc_offset) {
+ ASSERT(getter_stub_deopt_pc_offset() == Smi::FromInt(0));
+ set_getter_stub_deopt_pc_offset(Smi::FromInt(pc_offset));
+ }
+
+ void SetSetterStubDeoptPCOffset(int pc_offset) {
+ ASSERT(setter_stub_deopt_pc_offset() == Smi::FromInt(0));
+ set_setter_stub_deopt_pc_offset(Smi::FromInt(pc_offset));
+ }
+
// For post mortem debugging.
void RememberUnmappedPage(Address page, bool compacted);
@@ -1601,6 +1639,62 @@ class Heap {
global_ic_age_ = (global_ic_age_ + 1) & SharedFunctionInfo::ICAgeBits::kMax;
}
+ bool flush_monomorphic_ics() { return flush_monomorphic_ics_; }
+
+ intptr_t amount_of_external_allocated_memory() {
+ return amount_of_external_allocated_memory_;
+ }
+
+ // ObjectStats are kept in two arrays, counts and sizes. Related stats are
+ // stored in a contiguous linear buffer. Stats groups are stored one after
+ // another.
+ enum {
+ FIRST_CODE_KIND_SUB_TYPE = LAST_TYPE + 1,
+ FIRST_FIXED_ARRAY_SUB_TYPE =
+ FIRST_CODE_KIND_SUB_TYPE + Code::LAST_CODE_KIND + 1,
+ OBJECT_STATS_COUNT =
+ FIRST_FIXED_ARRAY_SUB_TYPE + LAST_FIXED_ARRAY_SUB_TYPE + 1
+ };
+
+ void RecordObjectStats(InstanceType type, int sub_type, size_t size) {
+ ASSERT(type <= LAST_TYPE);
+ if (sub_type < 0) {
+ object_counts_[type]++;
+ object_sizes_[type] += size;
+ } else {
+ if (type == CODE_TYPE) {
+ ASSERT(sub_type <= Code::LAST_CODE_KIND);
+ object_counts_[FIRST_CODE_KIND_SUB_TYPE + sub_type]++;
+ object_sizes_[FIRST_CODE_KIND_SUB_TYPE + sub_type] += size;
+ } else if (type == FIXED_ARRAY_TYPE) {
+ ASSERT(sub_type <= LAST_FIXED_ARRAY_SUB_TYPE);
+ object_counts_[FIRST_FIXED_ARRAY_SUB_TYPE + sub_type]++;
+ object_sizes_[FIRST_FIXED_ARRAY_SUB_TYPE + sub_type] += size;
+ }
+ }
+ }
+
+ void CheckpointObjectStats();
+
+ // We don't use a ScopedLock here since we want to lock the heap
+ // only when FLAG_parallel_recompilation is true.
+ class RelocationLock {
+ public:
+ explicit RelocationLock(Heap* heap) : heap_(heap) {
+ if (FLAG_parallel_recompilation) {
+ heap_->relocation_mutex_->Lock();
+ }
+ }
+ ~RelocationLock() {
+ if (FLAG_parallel_recompilation) {
+ heap_->relocation_mutex_->Unlock();
+ }
+ }
+
+ private:
+ Heap* heap_;
+ };
+
private:
Heap();
@@ -1632,6 +1726,8 @@ class Heap {
int global_ic_age_;
+ bool flush_monomorphic_ics_;
+
int scan_on_scavenge_pages_;
#if defined(V8_TARGET_ARCH_X64)
@@ -1653,7 +1749,7 @@ class Heap {
// Returns the amount of external memory registered since last global gc.
intptr_t PromotedExternalMemorySize();
- int ms_count_; // how many mark-sweep collections happened
+ unsigned int ms_count_; // how many mark-sweep collections happened
unsigned int gc_count_; // how many gc happened
// For post mortem debugging.
@@ -1725,7 +1821,7 @@ class Heap {
// last GC.
int old_gen_exhausted_;
- Object* global_contexts_list_;
+ Object* native_contexts_list_;
StoreBufferRebuilder store_buffer_rebuilder_;
@@ -1994,14 +2090,24 @@ class Heap {
void AdvanceIdleIncrementalMarking(intptr_t step_size);
+ void ClearObjectStats(bool clear_last_time_stats = false);
static const int kInitialSymbolTableSize = 2048;
static const int kInitialEvalCacheSize = 64;
static const int kInitialNumberStringCacheSize = 256;
+ // Object counts and used memory by InstanceType
+ size_t object_counts_[OBJECT_STATS_COUNT];
+ size_t object_counts_last_time_[OBJECT_STATS_COUNT];
+ size_t object_sizes_[OBJECT_STATS_COUNT];
+ size_t object_sizes_last_time_[OBJECT_STATS_COUNT];
+
// Maximum GC pause.
int max_gc_pause_;
+ // Total time spent in GC.
+ int total_gc_time_ms_;
+
// Maximum size of objects alive after GC.
intptr_t max_alive_after_gc_;
@@ -2046,15 +2152,16 @@ class Heap {
MemoryChunk* chunks_queued_for_free_;
+ Mutex* relocation_mutex_;
+
friend class Factory;
friend class GCTracer;
friend class DisallowAllocationFailure;
friend class AlwaysAllocateScope;
- friend class LinearAllocationScope;
friend class Page;
friend class Isolate;
friend class MarkCompactCollector;
- friend class StaticMarkingVisitor;
+ friend class MarkCompactMarkingVisitor;
friend class MapCompact;
DISALLOW_COPY_AND_ASSIGN(Heap);
@@ -2094,21 +2201,29 @@ class HeapStats {
};
-class AlwaysAllocateScope {
+class DisallowAllocationFailure {
public:
- inline AlwaysAllocateScope();
- inline ~AlwaysAllocateScope();
+ inline DisallowAllocationFailure();
+ inline ~DisallowAllocationFailure();
+
+#ifdef DEBUG
+ private:
+ bool old_state_;
+#endif
};
-class LinearAllocationScope {
+class AlwaysAllocateScope {
public:
- inline LinearAllocationScope();
- inline ~LinearAllocationScope();
+ inline AlwaysAllocateScope();
+ inline ~AlwaysAllocateScope();
+
+ private:
+ // Implicitly disable artificial allocation failures.
+ DisallowAllocationFailure disallow_allocation_failure_;
};
-#ifdef DEBUG
// Visitor class to verify interior pointers in spaces that do not contain
// or care about intergenerational references. All heap object pointers have to
// point into the heap to a location that has a map pointer at its first word.
@@ -2118,7 +2233,6 @@ class VerifyPointersVisitor: public ObjectVisitor {
public:
inline void VisitPointers(Object** start, Object** end);
};
-#endif
// Space iterator for iterating over all spaces of the heap.
@@ -2277,7 +2391,7 @@ class KeyedLookupCache {
};
-// Cache for mapping (array, property name) into descriptor index.
+// Cache for mapping (map, property name) into descriptor index.
// The cache contains both positive and negative results.
// Descriptor index equals kNotFound means the property is absent.
// Cleared at startup and prior to any gc.
@@ -2285,21 +2399,21 @@ class DescriptorLookupCache {
public:
// Lookup descriptor index for (map, name).
// If absent, kAbsent is returned.
- int Lookup(DescriptorArray* array, String* name) {
+ int Lookup(Map* source, String* name) {
if (!StringShape(name).IsSymbol()) return kAbsent;
- int index = Hash(array, name);
+ int index = Hash(source, name);
Key& key = keys_[index];
- if ((key.array == array) && (key.name == name)) return results_[index];
+ if ((key.source == source) && (key.name == name)) return results_[index];
return kAbsent;
}
// Update an element in the cache.
- void Update(DescriptorArray* array, String* name, int result) {
+ void Update(Map* source, String* name, int result) {
ASSERT(result != kAbsent);
if (StringShape(name).IsSymbol()) {
- int index = Hash(array, name);
+ int index = Hash(source, name);
Key& key = keys_[index];
- key.array = array;
+ key.source = source;
key.name = name;
results_[index] = result;
}
@@ -2313,24 +2427,26 @@ class DescriptorLookupCache {
private:
DescriptorLookupCache() {
for (int i = 0; i < kLength; ++i) {
- keys_[i].array = NULL;
+ keys_[i].source = NULL;
keys_[i].name = NULL;
results_[i] = kAbsent;
}
}
- static int Hash(DescriptorArray* array, String* name) {
+ static int Hash(Object* source, String* name) {
// Uses only lower 32 bits if pointers are larger.
- uint32_t array_hash =
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(array)) >> 2;
+ uint32_t source_hash =
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(source))
+ >> kPointerSizeLog2;
uint32_t name_hash =
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)) >> 2;
- return (array_hash ^ name_hash) % kLength;
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name))
+ >> kPointerSizeLog2;
+ return (source_hash ^ name_hash) % kLength;
}
static const int kLength = 64;
struct Key {
- DescriptorArray* array;
+ Map* source;
String* name;
};
@@ -2342,18 +2458,6 @@ class DescriptorLookupCache {
};
-#ifdef DEBUG
-class DisallowAllocationFailure {
- public:
- inline DisallowAllocationFailure();
- inline ~DisallowAllocationFailure();
-
- private:
- bool old_state_;
-};
-#endif
-
-
// A helper class to document/test C++ scopes where we do not
// expect a GC. Usage:
//
@@ -2369,6 +2473,7 @@ class AssertNoAllocation {
#ifdef DEBUG
private:
bool old_state_;
+ bool active_;
#endif
};
@@ -2381,6 +2486,7 @@ class DisableAssertNoAllocation {
#ifdef DEBUG
private:
bool old_state_;
+ bool active_;
#endif
};
@@ -2500,24 +2606,31 @@ class GCTracer BASE_EMBEDDED {
};
-class StringSplitCache {
+class RegExpResultsCache {
public:
- static Object* Lookup(FixedArray* cache, String* string, String* pattern);
+ enum ResultsCacheType { REGEXP_MULTIPLE_INDICES, STRING_SPLIT_SUBSTRINGS };
+
+ // Attempt to retrieve a cached result. On failure, 0 is returned as a Smi.
+ // On success, the returned result is guaranteed to be a COW-array.
+ static Object* Lookup(Heap* heap,
+ String* key_string,
+ Object* key_pattern,
+ ResultsCacheType type);
+ // Attempt to add value_array to the cache specified by type. On success,
+ // value_array is turned into a COW-array.
static void Enter(Heap* heap,
- FixedArray* cache,
- String* string,
- String* pattern,
- FixedArray* array);
+ String* key_string,
+ Object* key_pattern,
+ FixedArray* value_array,
+ ResultsCacheType type);
static void Clear(FixedArray* cache);
- static const int kStringSplitCacheSize = 0x100;
+ static const int kRegExpResultsCacheSize = 0x100;
private:
static const int kArrayEntriesPerCacheEntry = 4;
static const int kStringOffset = 0;
static const int kPatternOffset = 1;
static const int kArrayOffset = 2;
-
- static MaybeObject* WrapFixedArrayInJSArray(Object* fixed_array);
};
diff --git a/deps/v8/src/hydrogen-instructions.cc b/deps/v8/src/hydrogen-instructions.cc
index db3c3f3f7..939b4f497 100644
--- a/deps/v8/src/hydrogen-instructions.cc
+++ b/deps/v8/src/hydrogen-instructions.cc
@@ -156,6 +156,20 @@ void Range::Union(Range* other) {
}
+void Range::CombinedMax(Range* other) {
+ upper_ = Max(upper_, other->upper_);
+ lower_ = Max(lower_, other->lower_);
+ set_can_be_minus_zero(CanBeMinusZero() || other->CanBeMinusZero());
+}
+
+
+void Range::CombinedMin(Range* other) {
+ upper_ = Min(upper_, other->upper_);
+ lower_ = Min(lower_, other->lower_);
+ set_can_be_minus_zero(CanBeMinusZero() || other->CanBeMinusZero());
+}
+
+
void Range::Sar(int32_t value) {
int32_t bits = value & 0x1F;
lower_ = lower_ >> bits;
@@ -693,7 +707,7 @@ void HCallGlobal::PrintDataTo(StringStream* stream) {
void HCallKnownGlobal::PrintDataTo(StringStream* stream) {
- stream->Add("o ", target()->shared()->DebugName());
+ stream->Add("%o ", target()->shared()->DebugName());
stream->Add("#%d", argument_count());
}
@@ -861,12 +875,14 @@ HValue* HBitwise::Canonicalize() {
int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0;
if (left()->IsConstant() &&
HConstant::cast(left())->HasInteger32Value() &&
- HConstant::cast(left())->Integer32Value() == nop_constant) {
+ HConstant::cast(left())->Integer32Value() == nop_constant &&
+ !right()->CheckFlag(kUint32)) {
return right();
}
if (right()->IsConstant() &&
HConstant::cast(right())->HasInteger32Value() &&
- HConstant::cast(right())->Integer32Value() == nop_constant) {
+ HConstant::cast(right())->Integer32Value() == nop_constant &&
+ !left()->CheckFlag(kUint32)) {
return left();
}
return this;
@@ -878,7 +894,9 @@ HValue* HBitNot::Canonicalize() {
if (value()->IsBitNot()) {
HValue* result = HBitNot::cast(value())->value();
ASSERT(result->representation().IsInteger32());
- return result;
+ if (!result->CheckFlag(kUint32)) {
+ return result;
+ }
}
return this;
}
@@ -941,7 +959,8 @@ HValue* HUnaryMathOperation::Canonicalize() {
// introduced.
if (value()->representation().IsInteger32()) return value();
-#ifdef V8_TARGET_ARCH_ARM
+#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \
+ defined(V8_TARGET_ARCH_X64)
if (value()->IsDiv() && (value()->UseCount() == 1)) {
// TODO(2038): Implement this optimization for non ARM architectures.
HDiv* hdiv = HDiv::cast(value());
@@ -1039,6 +1058,13 @@ void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) {
}
+void HLoadElements::PrintDataTo(StringStream* stream) {
+ value()->PrintNameTo(stream);
+ stream->Add(" ");
+ typecheck()->PrintNameTo(stream);
+}
+
+
void HCheckMaps::PrintDataTo(StringStream* stream) {
value()->PrintNameTo(stream);
stream->Add(" [%p", *map_set()->first());
@@ -1072,6 +1098,11 @@ void HCheckInstanceType::PrintDataTo(StringStream* stream) {
}
+void HCheckPrototypeMaps::PrintDataTo(StringStream* stream) {
+ stream->Add("[receiver_prototype=%p,holder=%p]", *prototype(), *holder());
+}
+
+
void HCallStub::PrintDataTo(StringStream* stream) {
stream->Add("%s ",
CodeStub::MajorName(major_key_, false));
@@ -1100,6 +1131,7 @@ Range* HChange::InferRange(Zone* zone) {
Range* input_range = value()->range();
if (from().IsInteger32() &&
to().IsTagged() &&
+ !value()->CheckFlag(HInstruction::kUint32) &&
input_range != NULL && input_range->IsInSmiRange()) {
set_type(HType::Smi());
}
@@ -1232,6 +1264,24 @@ Range* HMod::InferRange(Zone* zone) {
}
+Range* HMathMinMax::InferRange(Zone* zone) {
+ if (representation().IsInteger32()) {
+ Range* a = left()->range();
+ Range* b = right()->range();
+ Range* res = a->Copy(zone);
+ if (operation_ == kMathMax) {
+ res->CombinedMax(b);
+ } else {
+ ASSERT(operation_ == kMathMin);
+ res->CombinedMin(b);
+ }
+ return res;
+ } else {
+ return HValue::InferRange(zone);
+ }
+}
+
+
void HPhi::PrintTo(StringStream* stream) {
stream->Add("[");
for (int i = 0; i < OperandCount(); ++i) {
@@ -1346,7 +1396,7 @@ void HPhi::ResetInteger32Uses() {
void HSimulate::PrintDataTo(StringStream* stream) {
- stream->Add("id=%d", ast_id());
+ stream->Add("id=%d", ast_id().ToInt());
if (pop_count_ > 0) stream->Add(" pop %d", pop_count_);
if (values_.length() > 0) {
if (pop_count_ > 0) stream->Add(" /");
@@ -1375,45 +1425,82 @@ void HDeoptimize::PrintDataTo(StringStream* stream) {
void HEnterInlined::PrintDataTo(StringStream* stream) {
SmartArrayPointer<char> name = function()->debug_name()->ToCString();
- stream->Add("%s, id=%d", *name, function()->id());
+ stream->Add("%s, id=%d", *name, function()->id().ToInt());
+}
+
+
+static bool IsInteger32(double value) {
+ double roundtrip_value = static_cast<double>(static_cast<int32_t>(value));
+ return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value);
}
HConstant::HConstant(Handle<Object> handle, Representation r)
: handle_(handle),
has_int32_value_(false),
- has_double_value_(false),
- int32_value_(0),
- double_value_(0) {
+ has_double_value_(false) {
set_representation(r);
SetFlag(kUseGVN);
if (handle_->IsNumber()) {
double n = handle_->Number();
- double roundtrip_value = static_cast<double>(static_cast<int32_t>(n));
- has_int32_value_ = BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(n);
- if (has_int32_value_) int32_value_ = static_cast<int32_t>(n);
+ has_int32_value_ = IsInteger32(n);
+ int32_value_ = DoubleToInt32(n);
double_value_ = n;
has_double_value_ = true;
}
}
+HConstant::HConstant(int32_t integer_value, Representation r)
+ : has_int32_value_(true),
+ has_double_value_(true),
+ int32_value_(integer_value),
+ double_value_(FastI2D(integer_value)) {
+ set_representation(r);
+ SetFlag(kUseGVN);
+}
+
+
+HConstant::HConstant(double double_value, Representation r)
+ : has_int32_value_(IsInteger32(double_value)),
+ has_double_value_(true),
+ int32_value_(DoubleToInt32(double_value)),
+ double_value_(double_value) {
+ set_representation(r);
+ SetFlag(kUseGVN);
+}
+
+
HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
if (r.IsInteger32() && !has_int32_value_) return NULL;
if (r.IsDouble() && !has_double_value_) return NULL;
+ if (handle_.is_null()) {
+ ASSERT(has_int32_value_ || has_double_value_);
+ if (has_int32_value_) return new(zone) HConstant(int32_value_, r);
+ return new(zone) HConstant(double_value_, r);
+ }
return new(zone) HConstant(handle_, r);
}
HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const {
- if (!has_double_value_) return NULL;
- int32_t truncated = NumberToInt32(*handle_);
- return new(zone) HConstant(FACTORY->NewNumberFromInt(truncated),
- Representation::Integer32());
+ if (has_int32_value_) {
+ if (handle_.is_null()) {
+ return new(zone) HConstant(int32_value_, Representation::Integer32());
+ } else {
+ // Re-use the existing Handle if possible.
+ return new(zone) HConstant(handle_, Representation::Integer32());
+ }
+ } else if (has_double_value_) {
+ return new(zone) HConstant(DoubleToInt32(double_value_),
+ Representation::Integer32());
+ } else {
+ return NULL;
+ }
}
-bool HConstant::ToBoolean() const {
+bool HConstant::ToBoolean() {
// Converts the constant's boolean value according to
// ECMAScript section 9.2 ToBoolean conversion.
if (HasInteger32Value()) return Integer32Value() != 0;
@@ -1421,17 +1508,25 @@ bool HConstant::ToBoolean() const {
double v = DoubleValue();
return v != 0 && !isnan(v);
}
- if (handle()->IsTrue()) return true;
- if (handle()->IsFalse()) return false;
- if (handle()->IsUndefined()) return false;
- if (handle()->IsNull()) return false;
- if (handle()->IsString() &&
- String::cast(*handle())->length() == 0) return false;
+ Handle<Object> literal = handle();
+ if (literal->IsTrue()) return true;
+ if (literal->IsFalse()) return false;
+ if (literal->IsUndefined()) return false;
+ if (literal->IsNull()) return false;
+ if (literal->IsString() && String::cast(*literal)->length() == 0) {
+ return false;
+ }
return true;
}
void HConstant::PrintDataTo(StringStream* stream) {
- handle()->ShortPrint(stream);
+ if (has_int32_value_) {
+ stream->Add("%d ", int32_value_);
+ } else if (has_double_value_) {
+ stream->Add("%f ", FmtElm(double_value_));
+ } else {
+ handle()->ShortPrint(stream);
+ }
}
@@ -1638,13 +1733,10 @@ static bool PrototypeChainCanNeverResolve(
}
LookupResult lookup(isolate);
- JSObject::cast(current)->map()->LookupInDescriptors(NULL, *name, &lookup);
- if (lookup.IsFound()) {
- if (lookup.type() != MAP_TRANSITION) return false;
- } else if (!lookup.IsCacheable()) {
- return false;
- }
-
+ Map* map = JSObject::cast(current)->map();
+ map->LookupDescriptor(NULL, *name, &lookup);
+ if (lookup.IsFound()) return false;
+ if (!lookup.IsCacheable()) return false;
current = JSObject::cast(current)->GetPrototype();
}
return true;
@@ -1669,7 +1761,7 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
++i) {
Handle<Map> map = types->at(i);
LookupResult lookup(map->GetIsolate());
- map->LookupInDescriptors(NULL, *name, &lookup);
+ map->LookupDescriptor(NULL, *name, &lookup);
if (lookup.IsFound()) {
switch (lookup.type()) {
case FIELD: {
@@ -1685,20 +1777,24 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
case CONSTANT_FUNCTION:
types_.Add(types->at(i), zone);
break;
- case MAP_TRANSITION:
- if (!map->has_named_interceptor() &&
- PrototypeChainCanNeverResolve(map, name)) {
- negative_lookups.Add(types->at(i), zone);
- }
+ case CALLBACKS:
break;
- default:
+ case TRANSITION:
+ case INTERCEPTOR:
+ case NONEXISTENT:
+ case NORMAL:
+ case HANDLER:
+ UNREACHABLE();
break;
}
- } else if (lookup.IsCacheable()) {
- if (!map->has_named_interceptor() &&
- PrototypeChainCanNeverResolve(map, name)) {
- negative_lookups.Add(types->at(i), zone);
- }
+ } else if (lookup.IsCacheable() &&
+ // For dicts the lookup on the map will fail, but the object may
+ // contain the property so we cannot generate a negative lookup
+ // (which would just be a map check and return undefined).
+ !map->is_dictionary_map() &&
+ !map->has_named_interceptor() &&
+ PrototypeChainCanNeverResolve(map, name)) {
+ negative_lookups.Add(types->at(i), zone);
}
}
@@ -1757,14 +1853,15 @@ void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) {
object()->PrintNameTo(stream);
stream->Add("[");
key()->PrintNameTo(stream);
- stream->Add("]");
+ stream->Add("] ");
+ dependency()->PrintNameTo(stream);
if (RequiresHoleCheck()) {
stream->Add(" check_hole");
}
}
-bool HLoadKeyedFastElement::RequiresHoleCheck() {
+bool HLoadKeyedFastElement::RequiresHoleCheck() const {
if (IsFastPackedElementsKind(elements_kind())) {
return false;
}
@@ -1782,7 +1879,8 @@ void HLoadKeyedFastDoubleElement::PrintDataTo(StringStream* stream) {
elements()->PrintNameTo(stream);
stream->Add("[");
key()->PrintNameTo(stream);
- stream->Add("]");
+ stream->Add("] ");
+ dependency()->PrintNameTo(stream);
}
@@ -1811,6 +1909,7 @@ HValue* HLoadKeyedGeneric::Canonicalize() {
new(block()->zone()) HCheckMapValue(object(), names_cache->map());
HInstruction* index = new(block()->zone()) HLoadKeyedFastElement(
index_cache,
+ key_load->key(),
key_load->key());
map_check->InsertBefore(this);
index->InsertBefore(this);
@@ -1871,7 +1970,8 @@ void HLoadKeyedSpecializedArrayElement::PrintDataTo(
}
stream->Add("[");
key()->PrintNameTo(stream);
- stream->Add("]");
+ stream->Add("] ");
+ dependency()->PrintNameTo(stream);
}
@@ -1997,7 +2097,7 @@ void HLoadGlobalCell::PrintDataTo(StringStream* stream) {
}
-bool HLoadGlobalCell::RequiresHoleCheck() {
+bool HLoadGlobalCell::RequiresHoleCheck() const {
if (details_.IsDontDelete() && !details_.IsReadOnly()) return false;
for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
HValue* use = it.value();
@@ -2079,6 +2179,10 @@ HType HPhi::CalculateInferredType() {
HType HConstant::CalculateInferredType() {
+ if (has_int32_value_) {
+ return Smi::IsValid(int32_value_) ? HType::Smi() : HType::HeapNumber();
+ }
+ if (has_double_value_) return HType::HeapNumber();
return HType::TypeFromValue(handle_);
}
@@ -2226,6 +2330,13 @@ HValue* HDiv::EnsureAndPropagateNotMinusZero(BitVector* visited) {
}
+HValue* HMathFloorOfDiv::EnsureAndPropagateNotMinusZero(BitVector* visited) {
+ visited->Add(id());
+ SetFlag(kBailoutOnMinusZero);
+ return NULL;
+}
+
+
HValue* HMul::EnsureAndPropagateNotMinusZero(BitVector* visited) {
visited->Add(id());
if (range() == NULL || range()->CanBeMinusZero()) {
diff --git a/deps/v8/src/hydrogen-instructions.h b/deps/v8/src/hydrogen-instructions.h
index 780d57d61..9e6344cd5 100644
--- a/deps/v8/src/hydrogen-instructions.h
+++ b/deps/v8/src/hydrogen-instructions.h
@@ -53,6 +53,7 @@ class LChunkBuilder;
#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
+ V(BinaryOperation) \
V(BitwiseBinaryOperation) \
V(ControlInstruction) \
V(Instruction) \
@@ -124,7 +125,6 @@ class LChunkBuilder;
V(IsStringAndBranch) \
V(IsSmiAndBranch) \
V(IsUndetectableAndBranch) \
- V(StringCompareAndBranch) \
V(JSArrayLength) \
V(LeaveInlined) \
V(LoadContextSlot) \
@@ -140,7 +140,9 @@ class LChunkBuilder;
V(LoadNamedField) \
V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
+ V(MapEnumLength) \
V(MathFloorOfDiv) \
+ V(MathMinMax) \
V(Mod) \
V(Mul) \
V(ObjectLiteral) \
@@ -170,6 +172,7 @@ class LChunkBuilder;
V(StringAdd) \
V(StringCharCodeAt) \
V(StringCharFromCode) \
+ V(StringCompareAndBranch) \
V(StringLength) \
V(Sub) \
V(ThisFunction) \
@@ -224,6 +227,16 @@ class LChunkBuilder;
virtual Opcode opcode() const { return HValue::k##type; }
+#ifdef DEBUG
+#define ASSERT_ALLOCATION_DISABLED do { \
+ OptimizingCompilerThread* thread = \
+ ISOLATE->optimizing_compiler_thread(); \
+ ASSERT(thread->IsOptimizerThread() || !HEAP->IsAllocationAllowed()); \
+ } while (0)
+#else
+#define ASSERT_ALLOCATION_DISABLED do {} while (0)
+#endif
+
class Range: public ZoneObject {
public:
Range()
@@ -276,6 +289,8 @@ class Range: public ZoneObject {
void Intersect(Range* other);
void Union(Range* other);
+ void CombinedMax(Range* other);
+ void CombinedMin(Range* other);
void AddConstant(int32_t value);
void Sar(int32_t value);
@@ -549,7 +564,14 @@ class HValue: public ZoneObject {
kIsArguments,
kTruncatingToInt32,
kIsDead,
- kLastFlag = kIsDead
+ // Instructions that are allowed to produce full range unsigned integer
+ // values are marked with kUint32 flag. If arithmetic shift or a load from
+ // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag
+ // it will deoptimize if result does not fit into signed integer range.
+ // HGraph::ComputeSafeUint32Operations is responsible for setting this
+ // flag.
+ kUint32,
+ kLastFlag = kUint32
};
STATIC_ASSERT(kLastFlag < kBitsPerInt);
@@ -645,7 +667,7 @@ class HValue: public ZoneObject {
// Operands.
virtual int OperandCount() = 0;
- virtual HValue* OperandAt(int index) = 0;
+ virtual HValue* OperandAt(int index) const = 0;
void SetOperandAt(int index, HValue* value);
void DeleteAndReplaceWith(HValue* other);
@@ -756,6 +778,10 @@ class HValue: public ZoneObject {
UNREACHABLE();
}
+ bool IsDead() const {
+ return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
+ }
+
#ifdef DEBUG
virtual void Verify() = 0;
#endif
@@ -840,6 +866,8 @@ class HValue: public ZoneObject {
GVNFlagSet gvn_flags_;
private:
+ virtual bool IsDeletable() const { return false; }
+
DISALLOW_COPY_AND_ASSIGN(HValue);
};
@@ -857,9 +885,14 @@ class HInstruction: public HValue {
void InsertBefore(HInstruction* next);
void InsertAfter(HInstruction* previous);
+ // The position is a write-once variable.
int position() const { return position_; }
bool has_position() const { return position_ != RelocInfo::kNoPosition; }
- void set_position(int position) { position_ = position; }
+ void set_position(int position) {
+ ASSERT(!has_position());
+ ASSERT(position != RelocInfo::kNoPosition);
+ position_ = position;
+ }
bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
@@ -903,7 +936,7 @@ template<int V>
class HTemplateInstruction : public HInstruction {
public:
int OperandCount() { return V; }
- HValue* OperandAt(int i) { return inputs_[i]; }
+ HValue* OperandAt(int i) const { return inputs_[i]; }
protected:
void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
@@ -955,7 +988,7 @@ class HTemplateControlInstruction: public HControlInstruction {
void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
int OperandCount() { return V; }
- HValue* OperandAt(int i) { return inputs_[i]; }
+ HValue* OperandAt(int i) const { return inputs_[i]; }
protected:
@@ -1000,7 +1033,7 @@ class HDeoptimize: public HControlInstruction {
}
virtual int OperandCount() { return values_.length(); }
- virtual HValue* OperandAt(int index) { return values_[index]; }
+ virtual HValue* OperandAt(int index) const { return values_[index]; }
virtual void PrintDataTo(StringStream* stream);
virtual int SuccessorCount() { return 0; }
@@ -1161,7 +1194,7 @@ class HUnaryOperation: public HTemplateInstruction<1> {
return reinterpret_cast<HUnaryOperation*>(value);
}
- HValue* value() { return OperandAt(0); }
+ HValue* value() const { return OperandAt(0); }
virtual void PrintDataTo(StringStream* stream);
};
@@ -1237,8 +1270,8 @@ class HChange: public HUnaryOperation {
virtual HType CalculateInferredType();
virtual HValue* Canonicalize();
- Representation from() { return value()->representation(); }
- Representation to() { return representation(); }
+ Representation from() const { return value()->representation(); }
+ Representation to() const { return representation(); }
bool deoptimize_on_undefined() const {
return CheckFlag(kDeoptimizeOnUndefined);
}
@@ -1257,6 +1290,11 @@ class HChange: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const {
+ return !from().IsTagged() || value()->type().IsSmi();
+ }
};
@@ -1276,12 +1314,15 @@ class HClampToUint8: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
class HSimulate: public HInstruction {
public:
- HSimulate(int ast_id, int pop_count, Zone* zone)
+ HSimulate(BailoutId ast_id, int pop_count, Zone* zone)
: ast_id_(ast_id),
pop_count_(pop_count),
values_(2, zone),
@@ -1291,9 +1332,9 @@ class HSimulate: public HInstruction {
virtual void PrintDataTo(StringStream* stream);
- bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
- int ast_id() const { return ast_id_; }
- void set_ast_id(int id) {
+ bool HasAstId() const { return !ast_id_.IsNone(); }
+ BailoutId ast_id() const { return ast_id_; }
+ void set_ast_id(BailoutId id) {
ASSERT(!HasAstId());
ast_id_ = id;
}
@@ -1314,7 +1355,7 @@ class HSimulate: public HInstruction {
AddValue(kNoIndex, value);
}
virtual int OperandCount() { return values_.length(); }
- virtual HValue* OperandAt(int index) { return values_[index]; }
+ virtual HValue* OperandAt(int index) const { return values_[index]; }
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
@@ -1341,7 +1382,7 @@ class HSimulate: public HInstruction {
// use lists are correctly updated.
SetOperandAt(values_.length() - 1, value);
}
- int ast_id_;
+ BailoutId ast_id_;
int pop_count_;
ZoneList<HValue*> values_;
ZoneList<int> assigned_indexes_;
@@ -1385,20 +1426,30 @@ class HStackCheck: public HTemplateInstruction<1> {
};
+enum InliningKind {
+ NORMAL_RETURN, // Normal function/method call and return.
+ DROP_EXTRA_ON_RETURN, // Drop an extra value from the environment on return.
+ CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value.
+ GETTER_CALL_RETURN, // Returning from a getter, need to restore context.
+ SETTER_CALL_RETURN // Use the RHS of the assignment as the return value.
+};
+
+
class HEnterInlined: public HTemplateInstruction<0> {
public:
HEnterInlined(Handle<JSFunction> closure,
int arguments_count,
FunctionLiteral* function,
CallKind call_kind,
- bool is_construct,
+ InliningKind inlining_kind,
Variable* arguments_var,
ZoneList<HValue*>* arguments_values)
: closure_(closure),
arguments_count_(arguments_count),
+ arguments_pushed_(false),
function_(function),
call_kind_(call_kind),
- is_construct_(is_construct),
+ inlining_kind_(inlining_kind),
arguments_var_(arguments_var),
arguments_values_(arguments_values) {
}
@@ -1407,9 +1458,11 @@ class HEnterInlined: public HTemplateInstruction<0> {
Handle<JSFunction> closure() const { return closure_; }
int arguments_count() const { return arguments_count_; }
+ bool arguments_pushed() const { return arguments_pushed_; }
+ void set_arguments_pushed() { arguments_pushed_ = true; }
FunctionLiteral* function() const { return function_; }
CallKind call_kind() const { return call_kind_; }
- bool is_construct() const { return is_construct_; }
+ InliningKind inlining_kind() const { return inlining_kind_; }
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
@@ -1423,9 +1476,10 @@ class HEnterInlined: public HTemplateInstruction<0> {
private:
Handle<JSFunction> closure_;
int arguments_count_;
+ bool arguments_pushed_;
FunctionLiteral* function_;
CallKind call_kind_;
- bool is_construct_;
+ InliningKind inlining_kind_;
Variable* arguments_var_;
ZoneList<HValue*>* arguments_values_;
};
@@ -1433,21 +1487,13 @@ class HEnterInlined: public HTemplateInstruction<0> {
class HLeaveInlined: public HTemplateInstruction<0> {
public:
- explicit HLeaveInlined(bool arguments_pushed)
- : arguments_pushed_(arguments_pushed) { }
+ HLeaveInlined() { }
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
}
- bool arguments_pushed() {
- return arguments_pushed_;
- }
-
DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
-
- private:
- bool arguments_pushed_;
};
@@ -1469,7 +1515,7 @@ class HPushArgument: public HUnaryOperation {
class HThisFunction: public HTemplateInstruction<0> {
public:
- explicit HThisFunction(Handle<JSFunction> closure) : closure_(closure) {
+ HThisFunction() {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
}
@@ -1478,18 +1524,13 @@ class HThisFunction: public HTemplateInstruction<0> {
return Representation::None();
}
- Handle<JSFunction> closure() const { return closure_; }
-
DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
protected:
- virtual bool DataEquals(HValue* other) {
- HThisFunction* b = HThisFunction::cast(other);
- return *closure() == *b->closure();
- }
+ virtual bool DataEquals(HValue* other) { return true; }
private:
- Handle<JSFunction> closure_;
+ virtual bool IsDeletable() const { return true; }
};
@@ -1508,6 +1549,9 @@ class HContext: public HTemplateInstruction<0> {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -1526,6 +1570,9 @@ class HOuterContext: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -1571,6 +1618,9 @@ class HGlobalObject: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -1590,6 +1640,9 @@ class HGlobalReceiver: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -1875,12 +1928,16 @@ class HJSArrayLength: public HTemplateInstruction<2> {
protected:
virtual bool DataEquals(HValue* other_raw) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
class HFixedArrayBaseLength: public HUnaryOperation {
public:
explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
+ set_type(HType::Smi());
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
SetGVNFlag(kDependsOnArrayLengths);
@@ -1894,6 +1951,32 @@ class HFixedArrayBaseLength: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
+};
+
+
+class HMapEnumLength: public HUnaryOperation {
+ public:
+ explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) {
+ set_type(HType::Smi());
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ SetGVNFlag(kDependsOnMaps);
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(MapEnumLength)
+
+ protected:
+ virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -1913,6 +1996,9 @@ class HElementsKind: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -1935,6 +2021,9 @@ class HBitNot: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -2017,18 +2106,27 @@ class HUnaryMathOperation: public HTemplateInstruction<2> {
}
private:
+ virtual bool IsDeletable() const { return true; }
+
BuiltinFunctionId op_;
};
-class HLoadElements: public HUnaryOperation {
+class HLoadElements: public HTemplateInstruction<2> {
public:
- explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
+ HLoadElements(HValue* value, HValue* typecheck) {
+ SetOperandAt(0, value);
+ SetOperandAt(1, typecheck);
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
SetGVNFlag(kDependsOnElementsPointer);
}
+ HValue* value() { return OperandAt(0); }
+ HValue* typecheck() { return OperandAt(1); }
+
+ virtual void PrintDataTo(StringStream* stream);
+
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
@@ -2037,6 +2135,9 @@ class HLoadElements: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -2060,6 +2161,9 @@ class HLoadExternalArrayPointer: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -2289,8 +2393,10 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> {
return Representation::None();
}
+ virtual void PrintDataTo(StringStream* stream);
+
virtual intptr_t Hashcode() {
- ASSERT(!HEAP->IsAllocationAllowed());
+ ASSERT_ALLOCATION_DISABLED;
intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
return hash;
@@ -2357,7 +2463,7 @@ class HPhi: public HValue {
}
virtual HType CalculateInferredType();
virtual int OperandCount() { return inputs_.length(); }
- virtual HValue* OperandAt(int index) { return inputs_[index]; }
+ virtual HValue* OperandAt(int index) const { return inputs_[index]; }
HValue* GetRedundantReplacement();
void AddInput(HValue* value);
bool HasRealUses();
@@ -2453,26 +2559,51 @@ class HArgumentsObject: public HTemplateInstruction<0> {
}
DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
class HConstant: public HTemplateInstruction<0> {
public:
HConstant(Handle<Object> handle, Representation r);
+ HConstant(int32_t value, Representation r);
+ HConstant(double value, Representation r);
- Handle<Object> handle() const { return handle_; }
+ Handle<Object> handle() {
+ if (handle_.is_null()) {
+ handle_ = FACTORY->NewNumber(double_value_, TENURED);
+ }
+ ASSERT(has_int32_value_ || !handle_->IsSmi());
+ return handle_;
+ }
bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
bool ImmortalImmovable() const {
+ if (has_int32_value_) {
+ return false;
+ }
+ if (has_double_value_) {
+ if (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
+ isnan(double_value_)) {
+ return true;
+ }
+ return false;
+ }
+
+ ASSERT(!handle_.is_null());
Heap* heap = HEAP;
+ // We should have handled minus_zero_value and nan_value in the
+ // has_double_value_ clause above.
+ ASSERT(*handle_ != heap->minus_zero_value());
+ ASSERT(*handle_ != heap->nan_value());
if (*handle_ == heap->undefined_value()) return true;
if (*handle_ == heap->null_value()) return true;
if (*handle_ == heap->true_value()) return true;
if (*handle_ == heap->false_value()) return true;
if (*handle_ == heap->the_hole_value()) return true;
- if (*handle_ == heap->minus_zero_value()) return true;
- if (*handle_ == heap->nan_value()) return true;
if (*handle_ == heap->empty_string()) return true;
return false;
}
@@ -2482,18 +2613,14 @@ class HConstant: public HTemplateInstruction<0> {
}
virtual bool IsConvertibleToInteger() const {
- if (handle_->IsSmi()) return true;
- if (handle_->IsHeapNumber() &&
- (HeapNumber::cast(*handle_)->value() ==
- static_cast<double>(NumberToInt32(*handle_)))) return true;
- return false;
+ return has_int32_value_;
}
virtual bool EmitAtUses() { return !representation().IsDouble(); }
virtual HValue* Canonicalize();
virtual void PrintDataTo(StringStream* stream);
virtual HType CalculateInferredType();
- bool IsInteger() const { return handle_->IsSmi(); }
+ bool IsInteger() { return handle()->IsSmi(); }
HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
HConstant* CopyToTruncatedInt32(Zone* zone) const;
bool HasInteger32Value() const { return has_int32_value_; }
@@ -2506,24 +2633,35 @@ class HConstant: public HTemplateInstruction<0> {
ASSERT(HasDoubleValue());
return double_value_;
}
- bool HasNumberValue() const { return has_int32_value_ || has_double_value_; }
+ bool HasNumberValue() const { return has_double_value_; }
int32_t NumberValueAsInteger32() const {
ASSERT(HasNumberValue());
- if (has_int32_value_) return int32_value_;
- return DoubleToInt32(double_value_);
+ // Irrespective of whether a numeric HConstant can be safely
+ // represented as an int32, we store the (in some cases lossy)
+ // representation of the number in int32_value_.
+ return int32_value_;
}
- bool HasStringValue() const { return handle_->IsString(); }
- bool ToBoolean() const;
+ bool ToBoolean();
+
+ bool IsUint32() {
+ return HasInteger32Value() && (Integer32Value() >= 0);
+ }
virtual intptr_t Hashcode() {
- ASSERT(!HEAP->allow_allocation(false));
- intptr_t hash = reinterpret_cast<intptr_t>(*handle());
- // Prevent smis from having fewer hash values when truncated to
- // the least significant bits.
- const int kShiftSize = kSmiShiftSize + kSmiTagSize;
- STATIC_ASSERT(kShiftSize != 0);
- return hash ^ (hash >> kShiftSize);
+ ASSERT_ALLOCATION_DISABLED;
+ intptr_t hash;
+
+ if (has_int32_value_) {
+ hash = static_cast<intptr_t>(int32_value_);
+ } else if (has_double_value_) {
+ hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_));
+ } else {
+ ASSERT(!handle_.is_null());
+ hash = reinterpret_cast<intptr_t>(*handle_);
+ }
+
+ return hash;
}
#ifdef DEBUG
@@ -2537,15 +2675,34 @@ class HConstant: public HTemplateInstruction<0> {
virtual bool DataEquals(HValue* other) {
HConstant* other_constant = HConstant::cast(other);
- return handle().is_identical_to(other_constant->handle());
+ if (has_int32_value_) {
+ return other_constant->has_int32_value_ &&
+ int32_value_ == other_constant->int32_value_;
+ } else if (has_double_value_) {
+ return other_constant->has_double_value_ &&
+ BitCast<int64_t>(double_value_) ==
+ BitCast<int64_t>(other_constant->double_value_);
+ } else {
+ ASSERT(!handle_.is_null());
+ return !other_constant->handle_.is_null() &&
+ *handle_ == *other_constant->handle_;
+ }
}
private:
+ virtual bool IsDeletable() const { return true; }
+
+ // If this is a numerical constant, handle_ either points to to the
+ // HeapObject the constant originated from or is null. If the
+ // constant is non-numeric, handle_ always points to a valid
+ // constant HeapObject.
Handle<Object> handle_;
- // The following two values represent the int32 and the double value of the
- // given constant if there is a lossless conversion between the constant
- // and the specific representation.
+ // We store the HConstant in the most specific form safely possible.
+ // The two flags, has_int32_value_ and has_double_value_ tell us if
+ // int32_value_ and double_value_ hold valid, safe representations
+ // of the constant. has_int32_value_ implies has_double_value_ but
+ // not the converse.
bool has_int32_value_ : 1;
bool has_double_value_ : 1;
int32_t int32_value_;
@@ -2581,6 +2738,8 @@ class HBinaryOperation: public HTemplateInstruction<3> {
virtual bool IsCommutative() const { return false; }
virtual void PrintDataTo(StringStream* stream);
+
+ DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
};
@@ -2655,6 +2814,9 @@ class HArgumentsElements: public HTemplateInstruction<0> {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+ private:
+ virtual bool IsDeletable() const { return true; }
+
bool from_inlined_;
};
@@ -2674,6 +2836,9 @@ class HArgumentsLength: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -2706,16 +2871,42 @@ class HAccessArgumentsAt: public HTemplateInstruction<3> {
};
+enum BoundsCheckKeyMode {
+ DONT_ALLOW_SMI_KEY,
+ ALLOW_SMI_KEY
+};
+
+
class HBoundsCheck: public HTemplateInstruction<2> {
public:
- HBoundsCheck(HValue* index, HValue* length) {
+ HBoundsCheck(HValue* index, HValue* length,
+ BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY)
+ : key_mode_(key_mode) {
SetOperandAt(0, index);
SetOperandAt(1, length);
set_representation(Representation::Integer32());
SetFlag(kUseGVN);
}
- virtual Representation RequiredInputRepresentation(int index) {
+ virtual Representation RequiredInputRepresentation(int arg_index) {
+ if (key_mode_ == DONT_ALLOW_SMI_KEY ||
+ !length()->representation().IsTagged()) {
+ return Representation::Integer32();
+ }
+ // If the index is tagged and isn't constant, then allow the length
+ // to be tagged, since it is usually already tagged from loading it out of
+ // the length field of a JSArray. This allows for direct comparison without
+ // untagging.
+ if (index()->representation().IsTagged() && !index()->IsConstant()) {
+ return Representation::Tagged();
+ }
+ // Also allow the length to be tagged if the index is constant, because
+ // it can be tagged to allow direct comparison.
+ if (index()->IsConstant() &&
+ index()->representation().IsInteger32() &&
+ arg_index == 1) {
+ return Representation::Tagged();
+ }
return Representation::Integer32();
}
@@ -2728,6 +2919,7 @@ class HBoundsCheck: public HTemplateInstruction<2> {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+ BoundsCheckKeyMode key_mode_;
};
@@ -2772,6 +2964,8 @@ class HBitwiseBinaryOperation: public HBinaryOperation {
DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
private:
+ virtual bool IsDeletable() const { return true; }
+
Representation observed_input_representation_[3];
};
@@ -2782,8 +2976,11 @@ class HMathFloorOfDiv: public HBinaryOperation {
: HBinaryOperation(context, left, right) {
set_representation(Representation::Integer32());
SetFlag(kUseGVN);
+ SetFlag(kCanOverflow);
}
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
+
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Integer32();
}
@@ -2792,6 +2989,9 @@ class HMathFloorOfDiv: public HBinaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -2824,6 +3024,9 @@ class HArithmeticBinaryOperation: public HBinaryOperation {
}
return HValue::InferredRepresentation();
}
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -3109,6 +3312,9 @@ class HGetCachedArrayIndex: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -3213,7 +3419,7 @@ class HPower: public HTemplateInstruction<2> {
}
HValue* left() { return OperandAt(0); }
- HValue* right() { return OperandAt(1); }
+ HValue* right() const { return OperandAt(1); }
virtual Representation RequiredInputRepresentation(int index) {
return index == 0
@@ -3225,6 +3431,11 @@ class HPower: public HTemplateInstruction<2> {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ virtual bool IsDeletable() const {
+ return !right()->representation().IsTagged();
+ }
};
@@ -3242,6 +3453,9 @@ class HRandom: public HTemplateInstruction<1> {
}
DECLARE_CONCRETE_INSTRUCTION(Random)
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -3388,6 +3602,47 @@ class HDiv: public HArithmeticBinaryOperation {
};
+class HMathMinMax: public HArithmeticBinaryOperation {
+ public:
+ enum Operation { kMathMin, kMathMax };
+
+ HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op)
+ : HArithmeticBinaryOperation(context, left, right),
+ operation_(op) { }
+
+ virtual Representation RequiredInputRepresentation(int index) {
+ return index == 0
+ ? Representation::Tagged()
+ : representation();
+ }
+
+ virtual Representation InferredRepresentation() {
+ if (left()->representation().IsInteger32() &&
+ right()->representation().IsInteger32()) {
+ return Representation::Integer32();
+ }
+ return Representation::Double();
+ }
+
+ virtual bool IsCommutative() const { return true; }
+
+ Operation operation() { return operation_; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathMinMax)
+
+ protected:
+ virtual bool DataEquals(HValue* other) {
+ return other->IsMathMinMax() &&
+ HMathMinMax::cast(other)->operation_ == operation_;
+ }
+
+ virtual Range* InferRange(Zone* zone);
+
+ private:
+ Operation operation_;
+};
+
+
class HBitwise: public HBitwiseBinaryOperation {
public:
HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right)
@@ -3484,11 +3739,11 @@ class HSar: public HBitwiseBinaryOperation {
class HOsrEntry: public HTemplateInstruction<0> {
public:
- explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
+ explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
SetGVNFlag(kChangesOsrEntries);
}
- int ast_id() const { return ast_id_; }
+ BailoutId ast_id() const { return ast_id_; }
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
@@ -3497,7 +3752,7 @@ class HOsrEntry: public HTemplateInstruction<0> {
DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
private:
- int ast_id_;
+ BailoutId ast_id_;
};
@@ -3591,12 +3846,12 @@ class HLoadGlobalCell: public HTemplateInstruction<0> {
}
Handle<JSGlobalPropertyCell> cell() const { return cell_; }
- bool RequiresHoleCheck();
+ bool RequiresHoleCheck() const;
virtual void PrintDataTo(StringStream* stream);
virtual intptr_t Hashcode() {
- ASSERT(!HEAP->allow_allocation(false));
+ ASSERT_ALLOCATION_DISABLED;
return reinterpret_cast<intptr_t>(*cell_);
}
@@ -3613,6 +3868,8 @@ class HLoadGlobalCell: public HTemplateInstruction<0> {
}
private:
+ virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
+
Handle<JSGlobalPropertyCell> cell_;
PropertyDetails details_;
};
@@ -3773,7 +4030,7 @@ class HLoadContextSlot: public HUnaryOperation {
return mode_ == kCheckDeoptimize;
}
- bool RequiresHoleCheck() {
+ bool RequiresHoleCheck() const {
return mode_ != kNoCheck;
}
@@ -3792,6 +4049,8 @@ class HLoadContextSlot: public HUnaryOperation {
}
private:
+ virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
+
int slot_index_;
Mode mode_;
};
@@ -3884,6 +4143,8 @@ class HLoadNamedField: public HUnaryOperation {
}
private:
+ virtual bool IsDeletable() const { return true; }
+
bool is_in_object_;
int offset_;
};
@@ -3983,10 +4244,11 @@ class ArrayInstructionInterface {
};
class HLoadKeyedFastElement
- : public HTemplateInstruction<2>, public ArrayInstructionInterface {
+ : public HTemplateInstruction<3>, public ArrayInstructionInterface {
public:
HLoadKeyedFastElement(HValue* obj,
HValue* key,
+ HValue* dependency,
ElementsKind elements_kind = FAST_ELEMENTS)
: bit_field_(0) {
ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
@@ -3997,6 +4259,7 @@ class HLoadKeyedFastElement
}
SetOperandAt(0, obj);
SetOperandAt(1, key);
+ SetOperandAt(2, dependency);
set_representation(Representation::Tagged());
SetGVNFlag(kDependsOnArrayElements);
SetFlag(kUseGVN);
@@ -4004,6 +4267,7 @@ class HLoadKeyedFastElement
HValue* object() { return OperandAt(0); }
HValue* key() { return OperandAt(1); }
+ HValue* dependency() { return OperandAt(2); }
uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
void SetIndexOffset(uint32_t index_offset) {
bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
@@ -4020,14 +4284,14 @@ class HLoadKeyedFastElement
virtual Representation RequiredInputRepresentation(int index) {
// The key is supposed to be Integer32.
- return index == 0
- ? Representation::Tagged()
- : Representation::Integer32();
+ if (index == 0) return Representation::Tagged();
+ if (index == 1) return Representation::Integer32();
+ return Representation::None();
}
virtual void PrintDataTo(StringStream* stream);
- bool RequiresHoleCheck();
+ bool RequiresHoleCheck() const;
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
@@ -4041,6 +4305,8 @@ class HLoadKeyedFastElement
}
private:
+ virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
+
class ElementsKindField: public BitField<ElementsKind, 0, 4> {};
class IndexOffsetField: public BitField<uint32_t, 4, 27> {};
class IsDehoistedField: public BitField<bool, 31, 1> {};
@@ -4052,17 +4318,19 @@ enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK };
class HLoadKeyedFastDoubleElement
- : public HTemplateInstruction<2>, public ArrayInstructionInterface {
+ : public HTemplateInstruction<3>, public ArrayInstructionInterface {
public:
HLoadKeyedFastDoubleElement(
HValue* elements,
HValue* key,
+ HValue* dependency,
HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK)
: index_offset_(0),
is_dehoisted_(false),
hole_check_mode_(hole_check_mode) {
SetOperandAt(0, elements);
SetOperandAt(1, key);
+ SetOperandAt(2, dependency);
set_representation(Representation::Double());
SetGVNFlag(kDependsOnDoubleArrayElements);
SetFlag(kUseGVN);
@@ -4070,6 +4338,7 @@ class HLoadKeyedFastDoubleElement
HValue* elements() { return OperandAt(0); }
HValue* key() { return OperandAt(1); }
+ HValue* dependency() { return OperandAt(2); }
uint32_t index_offset() { return index_offset_; }
void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
HValue* GetKey() { return key(); }
@@ -4079,12 +4348,12 @@ class HLoadKeyedFastDoubleElement
virtual Representation RequiredInputRepresentation(int index) {
// The key is supposed to be Integer32.
- return index == 0
- ? Representation::Tagged()
- : Representation::Integer32();
+ if (index == 0) return Representation::Tagged();
+ if (index == 1) return Representation::Integer32();
+ return Representation::None();
}
- bool RequiresHoleCheck() {
+ bool RequiresHoleCheck() const {
return hole_check_mode_ == PERFORM_HOLE_CHECK;
}
@@ -4101,6 +4370,8 @@ class HLoadKeyedFastDoubleElement
}
private:
+ virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
+
uint32_t index_offset_;
bool is_dehoisted_;
HoleCheckMode hole_check_mode_;
@@ -4108,16 +4379,18 @@ class HLoadKeyedFastDoubleElement
class HLoadKeyedSpecializedArrayElement
- : public HTemplateInstruction<2>, public ArrayInstructionInterface {
+ : public HTemplateInstruction<3>, public ArrayInstructionInterface {
public:
HLoadKeyedSpecializedArrayElement(HValue* external_elements,
HValue* key,
+ HValue* dependency,
ElementsKind elements_kind)
: elements_kind_(elements_kind),
index_offset_(0),
is_dehoisted_(false) {
SetOperandAt(0, external_elements);
SetOperandAt(1, key);
+ SetOperandAt(2, dependency);
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
set_representation(Representation::Double());
@@ -4133,15 +4406,15 @@ class HLoadKeyedSpecializedArrayElement
virtual void PrintDataTo(StringStream* stream);
virtual Representation RequiredInputRepresentation(int index) {
- // The key is supposed to be Integer32, but the base pointer
- // for the element load is a naked pointer.
- return index == 0
- ? Representation::External()
- : Representation::Integer32();
+ // The key is supposed to be Integer32.
+ if (index == 0) return Representation::External();
+ if (index == 1) return Representation::Integer32();
+ return Representation::None();
}
HValue* external_pointer() { return OperandAt(0); }
HValue* key() { return OperandAt(1); }
+ HValue* dependency() { return OperandAt(2); }
ElementsKind elements_kind() const { return elements_kind_; }
uint32_t index_offset() { return index_offset_; }
void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
@@ -4163,6 +4436,8 @@ class HLoadKeyedSpecializedArrayElement
}
private:
+ virtual bool IsDeletable() const { return true; }
+
ElementsKind elements_kind_;
uint32_t index_offset_;
bool is_dehoisted_;
@@ -4352,6 +4627,7 @@ class HStoreKeyedFastDoubleElement
SetOperandAt(0, elements);
SetOperandAt(1, key);
SetOperandAt(2, val);
+ SetFlag(kDeoptimizeOnUndefined);
SetGVNFlag(kChangesDoubleArrayElements);
}
@@ -4485,10 +4761,6 @@ class HTransitionElementsKind: public HTemplateInstruction<1> {
transitioned_map_(transitioned_map) {
SetOperandAt(0, object);
SetFlag(kUseGVN);
- // Don't set GVN DependOn flags here. That would defeat GVN's detection of
- // congruent HTransitionElementsKind instructions. Instruction hoisting
- // handles HTransitionElementsKind instruction specially, explicitly adding
- // DependsOn flags during its dependency calculations.
SetGVNFlag(kChangesElementsKind);
if (original_map->has_fast_double_elements()) {
SetGVNFlag(kChangesElementsPointer);
@@ -4547,6 +4819,10 @@ class HStringAdd: public HBinaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
+ // private:
+ // virtual bool IsDeletable() const { return true; }
};
@@ -4581,6 +4857,10 @@ class HStringCharCodeAt: public HTemplateInstruction<3> {
virtual Range* InferRange(Zone* zone) {
return new(zone) Range(0, String::kMaxUtf16CodeUnit);
}
+
+ // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
+ // private:
+ // virtual bool IsDeletable() const { return true; }
};
@@ -4607,6 +4887,10 @@ class HStringCharFromCode: public HTemplateInstruction<2> {
virtual bool DataEquals(HValue* other) { return true; }
DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
+
+ // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
+ // private:
+ // virtual bool IsDeletable() const { return true; }
};
@@ -4635,6 +4919,9 @@ class HStringLength: public HUnaryOperation {
virtual Range* InferRange(Zone* zone) {
return new(zone) Range(0, String::kMaxLength);
}
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -4661,6 +4948,9 @@ class HAllocateObject: public HTemplateInstruction<1> {
DECLARE_CONCRETE_INSTRUCTION(AllocateObject)
private:
+ // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
+ // virtual bool IsDeletable() const { return true; }
+
Handle<JSFunction> constructor_;
};
@@ -4677,6 +4967,8 @@ class HMaterializedLiteral: public HTemplateInstruction<V> {
int depth() const { return depth_; }
private:
+ virtual bool IsDeletable() const { return true; }
+
int literal_index_;
int depth_;
};
@@ -4797,10 +5089,12 @@ class HObjectLiteral: public HMaterializedLiteral<1> {
class HRegExpLiteral: public HMaterializedLiteral<1> {
public:
HRegExpLiteral(HValue* context,
+ Handle<FixedArray> literals,
Handle<String> pattern,
Handle<String> flags,
int literal_index)
: HMaterializedLiteral<1>(literal_index, 0),
+ literals_(literals),
pattern_(pattern),
flags_(flags) {
SetOperandAt(0, context);
@@ -4808,6 +5102,7 @@ class HRegExpLiteral: public HMaterializedLiteral<1> {
}
HValue* context() { return OperandAt(0); }
+ Handle<FixedArray> literals() { return literals_; }
Handle<String> pattern() { return pattern_; }
Handle<String> flags() { return flags_; }
@@ -4819,6 +5114,7 @@ class HRegExpLiteral: public HMaterializedLiteral<1> {
DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
private:
+ Handle<FixedArray> literals_;
Handle<String> pattern_;
Handle<String> flags_;
};
@@ -4848,6 +5144,8 @@ class HFunctionLiteral: public HTemplateInstruction<1> {
bool pretenure() const { return pretenure_; }
private:
+ virtual bool IsDeletable() const { return true; }
+
Handle<SharedFunctionInfo> shared_info_;
bool pretenure_;
};
@@ -4872,6 +5170,9 @@ class HTypeof: public HTemplateInstruction<2> {
}
DECLARE_CONCRETE_INSTRUCTION(Typeof)
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -4890,6 +5191,9 @@ class HToFastProperties: public HUnaryOperation {
}
DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -4904,6 +5208,9 @@ class HValueOf: public HUnaryOperation {
}
DECLARE_CONCRETE_INSTRUCTION(ValueOf)
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
@@ -5100,6 +5407,9 @@ class HLoadFieldByIndex : public HTemplateInstruction<2> {
}
DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
+
+ private:
+ virtual bool IsDeletable() const { return true; }
};
diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc
index 2c8a0f659..374e54c97 100644
--- a/deps/v8/src/hydrogen.cc
+++ b/deps/v8/src/hydrogen.cc
@@ -133,10 +133,10 @@ HDeoptimize* HBasicBlock::CreateDeoptimize(
}
-HSimulate* HBasicBlock::CreateSimulate(int ast_id) {
+HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id) {
ASSERT(HasEnvironment());
HEnvironment* environment = last_environment();
- ASSERT(ast_id == AstNode::kNoNumber ||
+ ASSERT(ast_id.IsNone() ||
environment->closure()->shared()->VerifyBailoutId(ast_id));
int push_count = environment->push_count();
@@ -166,32 +166,31 @@ void HBasicBlock::Finish(HControlInstruction* end) {
void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) {
- bool drop_extra = state != NULL && state->drop_extra();
- bool arguments_pushed = state != NULL && state->arguments_pushed();
+ bool drop_extra = state != NULL &&
+ state->inlining_kind() == DROP_EXTRA_ON_RETURN;
if (block->IsInlineReturnTarget()) {
- AddInstruction(new(zone()) HLeaveInlined(arguments_pushed));
+ AddInstruction(new(zone()) HLeaveInlined());
last_environment_ = last_environment()->DiscardInlined(drop_extra);
}
- AddSimulate(AstNode::kNoNumber);
+ AddSimulate(BailoutId::None());
HGoto* instr = new(zone()) HGoto(block);
Finish(instr);
}
void HBasicBlock::AddLeaveInlined(HValue* return_value,
- HBasicBlock* target,
FunctionState* state) {
- bool drop_extra = state != NULL && state->drop_extra();
- bool arguments_pushed = state != NULL && state->arguments_pushed();
+ HBasicBlock* target = state->function_return();
+ bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN;
ASSERT(target->IsInlineReturnTarget());
ASSERT(return_value != NULL);
- AddInstruction(new(zone()) HLeaveInlined(arguments_pushed));
+ AddInstruction(new(zone()) HLeaveInlined());
last_environment_ = last_environment()->DiscardInlined(drop_extra);
last_environment()->Push(return_value);
- AddSimulate(AstNode::kNoNumber);
+ AddSimulate(BailoutId::None());
HGoto* instr = new(zone()) HGoto(target);
Finish(instr);
}
@@ -204,7 +203,7 @@ void HBasicBlock::SetInitialEnvironment(HEnvironment* env) {
}
-void HBasicBlock::SetJoinId(int ast_id) {
+void HBasicBlock::SetJoinId(BailoutId ast_id) {
int length = predecessors_.length();
ASSERT(length > 0);
for (int i = 0; i < length; i++) {
@@ -527,7 +526,8 @@ void HGraph::Verify(bool do_full_verify) const {
// Check that all join blocks have predecessors that end with an
// unconditional goto and agree on their environment node id.
if (block->predecessors()->length() >= 2) {
- int id = block->predecessors()->first()->last_environment()->ast_id();
+ BailoutId id =
+ block->predecessors()->first()->last_environment()->ast_id();
for (int k = 0; k < block->predecessors()->length(); k++) {
HBasicBlock* predecessor = block->predecessors()->at(k);
ASSERT(predecessor->end()->IsGoto());
@@ -568,9 +568,9 @@ void HGraph::Verify(bool do_full_verify) const {
HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer,
- Object* value) {
+ Handle<Object> value) {
if (!pointer->is_set()) {
- HConstant* constant = new(zone()) HConstant(Handle<Object>(value),
+ HConstant* constant = new(zone()) HConstant(value,
Representation::Tagged());
constant->InsertAfter(GetConstantUndefined());
pointer->set(constant);
@@ -579,34 +579,45 @@ HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer,
}
+HConstant* HGraph::GetConstantInt32(SetOncePointer<HConstant>* pointer,
+ int32_t value) {
+ if (!pointer->is_set()) {
+ HConstant* constant =
+ new(zone()) HConstant(value, Representation::Integer32());
+ constant->InsertAfter(GetConstantUndefined());
+ pointer->set(constant);
+ }
+ return pointer->get();
+}
+
+
HConstant* HGraph::GetConstant1() {
- return GetConstant(&constant_1_, Smi::FromInt(1));
+ return GetConstantInt32(&constant_1_, 1);
}
HConstant* HGraph::GetConstantMinus1() {
- return GetConstant(&constant_minus1_, Smi::FromInt(-1));
+ return GetConstantInt32(&constant_minus1_, -1);
}
HConstant* HGraph::GetConstantTrue() {
- return GetConstant(&constant_true_, isolate()->heap()->true_value());
+ return GetConstant(&constant_true_, isolate()->factory()->true_value());
}
HConstant* HGraph::GetConstantFalse() {
- return GetConstant(&constant_false_, isolate()->heap()->false_value());
+ return GetConstant(&constant_false_, isolate()->factory()->false_value());
}
HConstant* HGraph::GetConstantHole() {
- return GetConstant(&constant_hole_, isolate()->heap()->the_hole_value());
+ return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value());
}
HGraphBuilder::HGraphBuilder(CompilationInfo* info,
- TypeFeedbackOracle* oracle,
- Zone* zone)
+ TypeFeedbackOracle* oracle)
: function_state_(NULL),
initial_function_state_(this, info, oracle, NORMAL_RETURN),
ast_context_(NULL),
@@ -614,8 +625,8 @@ HGraphBuilder::HGraphBuilder(CompilationInfo* info,
graph_(NULL),
current_block_(NULL),
inlined_count_(0),
- globals_(10, zone),
- zone_(zone),
+ globals_(10, info->zone()),
+ zone_(info->zone()),
inline_bailout_(false) {
// This is not initialized in the initializer list because the
// constructor for the initial state relies on function_state_ == NULL
@@ -625,7 +636,7 @@ HGraphBuilder::HGraphBuilder(CompilationInfo* info,
HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first,
HBasicBlock* second,
- int join_id) {
+ BailoutId join_id) {
if (first == NULL) {
return second;
} else if (second == NULL) {
@@ -674,64 +685,27 @@ void HBasicBlock::FinishExit(HControlInstruction* instruction) {
}
-HGraph::HGraph(CompilationInfo* info, Zone* zone)
+HGraph::HGraph(CompilationInfo* info)
: isolate_(info->isolate()),
next_block_id_(0),
entry_block_(NULL),
- blocks_(8, zone),
- values_(16, zone),
+ blocks_(8, info->zone()),
+ values_(16, info->zone()),
phi_list_(NULL),
- zone_(zone),
- is_recursive_(false) {
+ uint32_instructions_(NULL),
+ info_(info),
+ zone_(info->zone()),
+ is_recursive_(false),
+ use_optimistic_licm_(false),
+ type_change_checksum_(0) {
start_environment_ =
- new(zone) HEnvironment(NULL, info->scope(), info->closure(), zone);
- start_environment_->set_ast_id(AstNode::kFunctionEntryId);
+ new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
+ start_environment_->set_ast_id(BailoutId::FunctionEntry());
entry_block_ = CreateBasicBlock();
entry_block_->SetInitialEnvironment(start_environment_);
}
-Handle<Code> HGraph::Compile(CompilationInfo* info, Zone* zone) {
- int values = GetMaximumValueID();
- if (values > LUnallocated::kMaxVirtualRegisters) {
- if (FLAG_trace_bailout) {
- PrintF("Not enough virtual registers for (values).\n");
- }
- return Handle<Code>::null();
- }
- LAllocator allocator(values, this);
- LChunkBuilder builder(info, this, &allocator);
- LChunk* chunk = builder.Build();
- if (chunk == NULL) return Handle<Code>::null();
-
- if (!allocator.Allocate(chunk)) {
- if (FLAG_trace_bailout) {
- PrintF("Not enough virtual registers (regalloc).\n");
- }
- return Handle<Code>::null();
- }
-
- MacroAssembler assembler(info->isolate(), NULL, 0);
- LCodeGen generator(chunk, &assembler, info, zone);
-
- chunk->MarkEmptyBlocks();
-
- if (generator.GenerateCode()) {
- if (FLAG_trace_codegen) {
- PrintF("Crankshaft Compiler - ");
- }
- CodeGenerator::MakeCodePrologue(info);
- Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
- Handle<Code> code =
- CodeGenerator::MakeCodeEpilogue(&assembler, flags, info);
- generator.FinishCode(code);
- CodeGenerator::PrintCode(code, info);
- return code;
- }
- return Handle<Code>::null();
-}
-
-
HBasicBlock* HGraph::CreateBasicBlock() {
HBasicBlock* result = new(zone()) HBasicBlock(this);
blocks_.Add(result, zone());
@@ -752,66 +726,319 @@ void HGraph::Canonicalize() {
}
}
+// Block ordering was implemented with two mutually recursive methods,
+// HGraph::Postorder and HGraph::PostorderLoopBlocks.
+// The recursion could lead to stack overflow so the algorithm has been
+// implemented iteratively.
+// At a high level the algorithm looks like this:
+//
+// Postorder(block, loop_header) : {
+// if (block has already been visited or is of another loop) return;
+// mark block as visited;
+// if (block is a loop header) {
+// VisitLoopMembers(block, loop_header);
+// VisitSuccessorsOfLoopHeader(block);
+// } else {
+// VisitSuccessors(block)
+// }
+// put block in result list;
+// }
+//
+// VisitLoopMembers(block, outer_loop_header) {
+// foreach (block b in block loop members) {
+// VisitSuccessorsOfLoopMember(b, outer_loop_header);
+// if (b is loop header) VisitLoopMembers(b);
+// }
+// }
+//
+// VisitSuccessorsOfLoopMember(block, outer_loop_header) {
+// foreach (block b in block successors) Postorder(b, outer_loop_header)
+// }
+//
+// VisitSuccessorsOfLoopHeader(block) {
+// foreach (block b in block successors) Postorder(b, block)
+// }
+//
+// VisitSuccessors(block, loop_header) {
+// foreach (block b in block successors) Postorder(b, loop_header)
+// }
+//
+// The ordering is started calling Postorder(entry, NULL).
+//
+// Each instance of PostorderProcessor represents the "stack frame" of the
+// recursion, and particularly keeps the state of the loop (iteration) of the
+// "Visit..." function it represents.
+// To recycle memory we keep all the frames in a double linked list but
+// this means that we cannot use constructors to initialize the frames.
+//
+class PostorderProcessor : public ZoneObject {
+ public:
+ // Back link (towards the stack bottom).
+ PostorderProcessor* parent() {return father_; }
+ // Forward link (towards the stack top).
+ PostorderProcessor* child() {return child_; }
+ HBasicBlock* block() { return block_; }
+ HLoopInformation* loop() { return loop_; }
+ HBasicBlock* loop_header() { return loop_header_; }
+
+ static PostorderProcessor* CreateEntryProcessor(Zone* zone,
+ HBasicBlock* block,
+ BitVector* visited) {
+ PostorderProcessor* result = new(zone) PostorderProcessor(NULL);
+ return result->SetupSuccessors(zone, block, NULL, visited);
+ }
-void HGraph::OrderBlocks() {
- HPhase phase("H_Block ordering");
- BitVector visited(blocks_.length(), zone());
+ PostorderProcessor* PerformStep(Zone* zone,
+ BitVector* visited,
+ ZoneList<HBasicBlock*>* order) {
+ PostorderProcessor* next =
+ PerformNonBacktrackingStep(zone, visited, order);
+ if (next != NULL) {
+ return next;
+ } else {
+ return Backtrack(zone, visited, order);
+ }
+ }
- ZoneList<HBasicBlock*> reverse_result(8, zone());
- HBasicBlock* start = blocks_[0];
- Postorder(start, &visited, &reverse_result, NULL);
+ private:
+ explicit PostorderProcessor(PostorderProcessor* father)
+ : father_(father), child_(NULL), successor_iterator(NULL) { }
+
+ // Each enum value states the cycle whose state is kept by this instance.
+ enum LoopKind {
+ NONE,
+ SUCCESSORS,
+ SUCCESSORS_OF_LOOP_HEADER,
+ LOOP_MEMBERS,
+ SUCCESSORS_OF_LOOP_MEMBER
+ };
+
+ // Each "Setup..." method is like a constructor for a cycle state.
+ PostorderProcessor* SetupSuccessors(Zone* zone,
+ HBasicBlock* block,
+ HBasicBlock* loop_header,
+ BitVector* visited) {
+ if (block == NULL || visited->Contains(block->block_id()) ||
+ block->parent_loop_header() != loop_header) {
+ kind_ = NONE;
+ block_ = NULL;
+ loop_ = NULL;
+ loop_header_ = NULL;
+ return this;
+ } else {
+ block_ = block;
+ loop_ = NULL;
+ visited->Add(block->block_id());
- blocks_.Rewind(0);
- int index = 0;
- for (int i = reverse_result.length() - 1; i >= 0; --i) {
- HBasicBlock* b = reverse_result[i];
- blocks_.Add(b, zone());
- b->set_block_id(index++);
+ if (block->IsLoopHeader()) {
+ kind_ = SUCCESSORS_OF_LOOP_HEADER;
+ loop_header_ = block;
+ InitializeSuccessors();
+ PostorderProcessor* result = Push(zone);
+ return result->SetupLoopMembers(zone, block, block->loop_information(),
+ loop_header);
+ } else {
+ ASSERT(block->IsFinished());
+ kind_ = SUCCESSORS;
+ loop_header_ = loop_header;
+ InitializeSuccessors();
+ return this;
+ }
+ }
}
-}
+ PostorderProcessor* SetupLoopMembers(Zone* zone,
+ HBasicBlock* block,
+ HLoopInformation* loop,
+ HBasicBlock* loop_header) {
+ kind_ = LOOP_MEMBERS;
+ block_ = block;
+ loop_ = loop;
+ loop_header_ = loop_header;
+ InitializeLoopMembers();
+ return this;
+ }
-void HGraph::PostorderLoopBlocks(HLoopInformation* loop,
- BitVector* visited,
- ZoneList<HBasicBlock*>* order,
- HBasicBlock* loop_header) {
- for (int i = 0; i < loop->blocks()->length(); ++i) {
- HBasicBlock* b = loop->blocks()->at(i);
- for (HSuccessorIterator it(b->end()); !it.Done(); it.Advance()) {
- Postorder(it.Current(), visited, order, loop_header);
+ PostorderProcessor* SetupSuccessorsOfLoopMember(
+ HBasicBlock* block,
+ HLoopInformation* loop,
+ HBasicBlock* loop_header) {
+ kind_ = SUCCESSORS_OF_LOOP_MEMBER;
+ block_ = block;
+ loop_ = loop;
+ loop_header_ = loop_header;
+ InitializeSuccessors();
+ return this;
+ }
+
+ // This method "allocates" a new stack frame.
+ PostorderProcessor* Push(Zone* zone) {
+ if (child_ == NULL) {
+ child_ = new(zone) PostorderProcessor(this);
+ }
+ return child_;
+ }
+
+ void ClosePostorder(ZoneList<HBasicBlock*>* order, Zone* zone) {
+ ASSERT(block_->end()->FirstSuccessor() == NULL ||
+ order->Contains(block_->end()->FirstSuccessor()) ||
+ block_->end()->FirstSuccessor()->IsLoopHeader());
+ ASSERT(block_->end()->SecondSuccessor() == NULL ||
+ order->Contains(block_->end()->SecondSuccessor()) ||
+ block_->end()->SecondSuccessor()->IsLoopHeader());
+ order->Add(block_, zone);
+ }
+
+ // This method is the basic block to walk up the stack.
+ PostorderProcessor* Pop(Zone* zone,
+ BitVector* visited,
+ ZoneList<HBasicBlock*>* order) {
+ switch (kind_) {
+ case SUCCESSORS:
+ case SUCCESSORS_OF_LOOP_HEADER:
+ ClosePostorder(order, zone);
+ return father_;
+ case LOOP_MEMBERS:
+ return father_;
+ case SUCCESSORS_OF_LOOP_MEMBER:
+ if (block()->IsLoopHeader() && block() != loop_->loop_header()) {
+ // In this case we need to perform a LOOP_MEMBERS cycle so we
+ // initialize it and return this instead of father.
+ return SetupLoopMembers(zone, block(),
+ block()->loop_information(), loop_header_);
+ } else {
+ return father_;
+ }
+ case NONE:
+ return father_;
}
- if (b->IsLoopHeader() && b != loop->loop_header()) {
- PostorderLoopBlocks(b->loop_information(), visited, order, loop_header);
+ UNREACHABLE();
+ return NULL;
+ }
+
+ // Walks up the stack.
+ PostorderProcessor* Backtrack(Zone* zone,
+ BitVector* visited,
+ ZoneList<HBasicBlock*>* order) {
+ PostorderProcessor* parent = Pop(zone, visited, order);
+ while (parent != NULL) {
+ PostorderProcessor* next =
+ parent->PerformNonBacktrackingStep(zone, visited, order);
+ if (next != NULL) {
+ return next;
+ } else {
+ parent = parent->Pop(zone, visited, order);
+ }
}
+ return NULL;
+ }
+
+ PostorderProcessor* PerformNonBacktrackingStep(
+ Zone* zone,
+ BitVector* visited,
+ ZoneList<HBasicBlock*>* order) {
+ HBasicBlock* next_block;
+ switch (kind_) {
+ case SUCCESSORS:
+ next_block = AdvanceSuccessors();
+ if (next_block != NULL) {
+ PostorderProcessor* result = Push(zone);
+ return result->SetupSuccessors(zone, next_block,
+ loop_header_, visited);
+ }
+ break;
+ case SUCCESSORS_OF_LOOP_HEADER:
+ next_block = AdvanceSuccessors();
+ if (next_block != NULL) {
+ PostorderProcessor* result = Push(zone);
+ return result->SetupSuccessors(zone, next_block,
+ block(), visited);
+ }
+ break;
+ case LOOP_MEMBERS:
+ next_block = AdvanceLoopMembers();
+ if (next_block != NULL) {
+ PostorderProcessor* result = Push(zone);
+ return result->SetupSuccessorsOfLoopMember(next_block,
+ loop_, loop_header_);
+ }
+ break;
+ case SUCCESSORS_OF_LOOP_MEMBER:
+ next_block = AdvanceSuccessors();
+ if (next_block != NULL) {
+ PostorderProcessor* result = Push(zone);
+ return result->SetupSuccessors(zone, next_block,
+ loop_header_, visited);
+ }
+ break;
+ case NONE:
+ return NULL;
+ }
+ return NULL;
}
-}
+ // The following two methods implement a "foreach b in successors" cycle.
+ void InitializeSuccessors() {
+ loop_index = 0;
+ loop_length = 0;
+ successor_iterator = HSuccessorIterator(block_->end());
+ }
-void HGraph::Postorder(HBasicBlock* block,
- BitVector* visited,
- ZoneList<HBasicBlock*>* order,
- HBasicBlock* loop_header) {
- if (block == NULL || visited->Contains(block->block_id())) return;
- if (block->parent_loop_header() != loop_header) return;
- visited->Add(block->block_id());
- if (block->IsLoopHeader()) {
- PostorderLoopBlocks(block->loop_information(), visited, order, loop_header);
- for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
- Postorder(it.Current(), visited, order, block);
+ HBasicBlock* AdvanceSuccessors() {
+ if (!successor_iterator.Done()) {
+ HBasicBlock* result = successor_iterator.Current();
+ successor_iterator.Advance();
+ return result;
}
- } else {
- ASSERT(block->IsFinished());
- for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
- Postorder(it.Current(), visited, order, loop_header);
+ return NULL;
+ }
+
+ // The following two methods implement a "foreach b in loop members" cycle.
+ void InitializeLoopMembers() {
+ loop_index = 0;
+ loop_length = loop_->blocks()->length();
+ }
+
+ HBasicBlock* AdvanceLoopMembers() {
+ if (loop_index < loop_length) {
+ HBasicBlock* result = loop_->blocks()->at(loop_index);
+ loop_index++;
+ return result;
+ } else {
+ return NULL;
}
}
- ASSERT(block->end()->FirstSuccessor() == NULL ||
- order->Contains(block->end()->FirstSuccessor()) ||
- block->end()->FirstSuccessor()->IsLoopHeader());
- ASSERT(block->end()->SecondSuccessor() == NULL ||
- order->Contains(block->end()->SecondSuccessor()) ||
- block->end()->SecondSuccessor()->IsLoopHeader());
- order->Add(block, zone());
+
+ LoopKind kind_;
+ PostorderProcessor* father_;
+ PostorderProcessor* child_;
+ HLoopInformation* loop_;
+ HBasicBlock* block_;
+ HBasicBlock* loop_header_;
+ int loop_index;
+ int loop_length;
+ HSuccessorIterator successor_iterator;
+};
+
+
+void HGraph::OrderBlocks() {
+ HPhase phase("H_Block ordering");
+ BitVector visited(blocks_.length(), zone());
+
+ ZoneList<HBasicBlock*> reverse_result(8, zone());
+ HBasicBlock* start = blocks_[0];
+ PostorderProcessor* postorder =
+ PostorderProcessor::CreateEntryProcessor(zone(), start, &visited);
+ while (postorder != NULL) {
+ postorder = postorder->PerformStep(zone(), &visited, &reverse_result);
+ }
+ blocks_.Rewind(0);
+ int index = 0;
+ for (int i = reverse_result.length() - 1; i >= 0; --i) {
+ HBasicBlock* b = reverse_result[i];
+ blocks_.Add(b, zone());
+ b->set_block_id(index++);
+ }
}
@@ -1487,15 +1714,15 @@ class HGlobalValueNumberer BASE_EMBEDDED {
block_side_effects_(graph->blocks()->length(), graph->zone()),
loop_side_effects_(graph->blocks()->length(), graph->zone()),
visited_on_paths_(graph->zone(), graph->blocks()->length()) {
- ASSERT(info->isolate()->heap()->allow_allocation(false));
+#ifdef DEBUG
+ ASSERT(info->isolate()->optimizing_compiler_thread()->IsOptimizerThread() ||
+ !info->isolate()->heap()->IsAllocationAllowed());
+#endif
block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(),
graph_->zone());
loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(),
graph_->zone());
}
- ~HGlobalValueNumberer() {
- ASSERT(!info_->isolate()->heap()->allow_allocation(true));
- }
// Returns true if values with side effects are removed.
bool Analyze();
@@ -1673,6 +1900,8 @@ GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
void HGlobalValueNumberer::LoopInvariantCodeMotion() {
+ TRACE_GVN_1("Using optimistic loop invariant code motion: %s\n",
+ graph_->use_optimistic_licm() ? "yes" : "no");
for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
HBasicBlock* block = graph_->blocks()->at(i);
if (block->IsLoopHeader()) {
@@ -1716,51 +1945,8 @@ void HGlobalValueNumberer::ProcessLoopBlock(
*GetGVNFlagsString(instr->gvn_flags()),
*GetGVNFlagsString(loop_kills));
bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags);
- if (instr->IsTransitionElementsKind()) {
- // It's possible to hoist transitions out of a loop as long as the
- // hoisting wouldn't move the transition past an instruction that has a
- // DependsOn flag for anything it changes.
- GVNFlagSet hoist_depends_blockers =
- HValue::ConvertChangesToDependsFlags(instr->ChangesFlags());
-
- // In addition, the transition must not be hoisted above elements kind
- // changes, or if the transition is destructive to the elements buffer,
- // changes to array pointer or array contents.
- GVNFlagSet hoist_change_blockers;
- hoist_change_blockers.Add(kChangesElementsKind);
- HTransitionElementsKind* trans = HTransitionElementsKind::cast(instr);
- if (trans->original_map()->has_fast_double_elements()) {
- hoist_change_blockers.Add(kChangesElementsPointer);
- hoist_change_blockers.Add(kChangesDoubleArrayElements);
- }
- if (trans->transitioned_map()->has_fast_double_elements()) {
- hoist_change_blockers.Add(kChangesElementsPointer);
- hoist_change_blockers.Add(kChangesArrayElements);
- }
- if (FLAG_trace_gvn) {
- GVNFlagSet hoist_blockers = hoist_depends_blockers;
- hoist_blockers.Add(hoist_change_blockers);
- GVNFlagSet first_time = *first_time_changes;
- first_time.Add(*first_time_depends);
- TRACE_GVN_4("Checking dependencies on HTransitionElementsKind "
- "%d (%s) hoist blockers: %s; "
- "first-time accumulated: %s\n",
- instr->id(),
- instr->Mnemonic(),
- *GetGVNFlagsString(hoist_blockers),
- *GetGVNFlagsString(first_time));
- }
- // It's possible to hoist transition from the current loop loop only if
- // they dominate all of the successor blocks in the same loop and there
- // are not any instructions that have Changes/DependsOn that intervene
- // between it and the beginning of the loop header.
- bool in_nested_loop = block != loop_header &&
- ((block->parent_loop_header() != loop_header) ||
- block->IsLoopHeader());
- can_hoist = !in_nested_loop &&
- block->IsLoopSuccessorDominator() &&
- !first_time_depends->ContainsAnyOf(hoist_depends_blockers) &&
- !first_time_changes->ContainsAnyOf(hoist_change_blockers);
+ if (can_hoist && !graph()->use_optimistic_licm()) {
+ can_hoist = block->IsLoopSuccessorDominator();
}
if (can_hoist) {
@@ -1803,7 +1989,7 @@ void HGlobalValueNumberer::ProcessLoopBlock(
bool HGlobalValueNumberer::AllowCodeMotion() {
- return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount;
+ return info()->shared_info()->opt_count() + 1 < FLAG_max_opt_count;
}
@@ -2331,8 +2517,8 @@ void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) {
break;
}
- // For multiplication and division, we must propagate to the left and
- // the right side.
+ // For multiplication, division, and Math.min/max(), we must propagate
+ // to the left and the right side.
if (current->IsMul()) {
HMul* mul = HMul::cast(current);
mul->EnsureAndPropagateNotMinusZero(visited);
@@ -2343,6 +2529,11 @@ void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) {
div->EnsureAndPropagateNotMinusZero(visited);
PropagateMinusZeroChecks(div->left(), visited);
PropagateMinusZeroChecks(div->right(), visited);
+ } else if (current->IsMathMinMax()) {
+ HMathMinMax* minmax = HMathMinMax::cast(current);
+ visited->Add(minmax->id());
+ PropagateMinusZeroChecks(minmax->left(), visited);
+ PropagateMinusZeroChecks(minmax->right(), visited);
}
current = current->EnsureAndPropagateNotMinusZero(visited);
@@ -2492,6 +2683,228 @@ void HGraph::MarkDeoptimizeOnUndefined() {
}
+// Discover instructions that can be marked with kUint32 flag allowing
+// them to produce full range uint32 values.
+class Uint32Analysis BASE_EMBEDDED {
+ public:
+ explicit Uint32Analysis(Zone* zone) : zone_(zone), phis_(4, zone) { }
+
+ void Analyze(HInstruction* current);
+
+ void UnmarkUnsafePhis();
+
+ private:
+ bool IsSafeUint32Use(HValue* val, HValue* use);
+ bool Uint32UsesAreSafe(HValue* uint32val);
+ bool CheckPhiOperands(HPhi* phi);
+ void UnmarkPhi(HPhi* phi, ZoneList<HPhi*>* worklist);
+
+ Zone* zone_;
+ ZoneList<HPhi*> phis_;
+};
+
+
+bool Uint32Analysis::IsSafeUint32Use(HValue* val, HValue* use) {
+ // Operations that operatate on bits are safe.
+ if (use->IsBitwise() ||
+ use->IsShl() ||
+ use->IsSar() ||
+ use->IsShr() ||
+ use->IsBitNot()) {
+ return true;
+ } else if (use->IsChange() || use->IsSimulate()) {
+ // Conversions and deoptimization have special support for unt32.
+ return true;
+ } else if (use->IsStoreKeyedSpecializedArrayElement()) {
+ // Storing a value into an external integer array is a bit level operation.
+ HStoreKeyedSpecializedArrayElement* store =
+ HStoreKeyedSpecializedArrayElement::cast(use);
+
+ if (store->value() == val) {
+ // Clamping or a conversion to double should have beed inserted.
+ ASSERT(store->elements_kind() != EXTERNAL_PIXEL_ELEMENTS);
+ ASSERT(store->elements_kind() != EXTERNAL_FLOAT_ELEMENTS);
+ ASSERT(store->elements_kind() != EXTERNAL_DOUBLE_ELEMENTS);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+// Iterate over all uses and verify that they are uint32 safe: either don't
+// distinguish between int32 and uint32 due to their bitwise nature or
+// have special support for uint32 values.
+// Encountered phis are optimisitically treated as safe uint32 uses,
+// marked with kUint32 flag and collected in the phis_ list. A separate
+// path will be performed later by UnmarkUnsafePhis to clear kUint32 from
+// phis that are not actually uint32-safe (it requries fix point iteration).
+bool Uint32Analysis::Uint32UsesAreSafe(HValue* uint32val) {
+ bool collect_phi_uses = false;
+ for (HUseIterator it(uint32val->uses()); !it.Done(); it.Advance()) {
+ HValue* use = it.value();
+
+ if (use->IsPhi()) {
+ if (!use->CheckFlag(HInstruction::kUint32)) {
+ // There is a phi use of this value from a phis that is not yet
+ // collected in phis_ array. Separate pass is required.
+ collect_phi_uses = true;
+ }
+
+ // Optimistically treat phis as uint32 safe.
+ continue;
+ }
+
+ if (!IsSafeUint32Use(uint32val, use)) {
+ return false;
+ }
+ }
+
+ if (collect_phi_uses) {
+ for (HUseIterator it(uint32val->uses()); !it.Done(); it.Advance()) {
+ HValue* use = it.value();
+
+ // There is a phi use of this value from a phis that is not yet
+ // collected in phis_ array. Separate pass is required.
+ if (use->IsPhi() && !use->CheckFlag(HInstruction::kUint32)) {
+ use->SetFlag(HInstruction::kUint32);
+ phis_.Add(HPhi::cast(use), zone_);
+ }
+ }
+ }
+
+ return true;
+}
+
+
+// Analyze instruction and mark it with kUint32 if all its uses are uint32
+// safe.
+void Uint32Analysis::Analyze(HInstruction* current) {
+ if (Uint32UsesAreSafe(current)) current->SetFlag(HInstruction::kUint32);
+}
+
+
+// Check if all operands to the given phi are marked with kUint32 flag.
+bool Uint32Analysis::CheckPhiOperands(HPhi* phi) {
+ if (!phi->CheckFlag(HInstruction::kUint32)) {
+ // This phi is not uint32 safe. No need to check operands.
+ return false;
+ }
+
+ for (int j = 0; j < phi->OperandCount(); j++) {
+ HValue* operand = phi->OperandAt(j);
+ if (!operand->CheckFlag(HInstruction::kUint32)) {
+ // Lazyly mark constants that fit into uint32 range with kUint32 flag.
+ if (operand->IsConstant() &&
+ HConstant::cast(operand)->IsUint32()) {
+ operand->SetFlag(HInstruction::kUint32);
+ continue;
+ }
+
+ // This phi is not safe, some operands are not uint32 values.
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+// Remove kUint32 flag from the phi itself and its operands. If any operand
+// was a phi marked with kUint32 place it into a worklist for
+// transitive clearing of kUint32 flag.
+void Uint32Analysis::UnmarkPhi(HPhi* phi, ZoneList<HPhi*>* worklist) {
+ phi->ClearFlag(HInstruction::kUint32);
+ for (int j = 0; j < phi->OperandCount(); j++) {
+ HValue* operand = phi->OperandAt(j);
+ if (operand->CheckFlag(HInstruction::kUint32)) {
+ operand->ClearFlag(HInstruction::kUint32);
+ if (operand->IsPhi()) {
+ worklist->Add(HPhi::cast(operand), zone_);
+ }
+ }
+ }
+}
+
+
+void Uint32Analysis::UnmarkUnsafePhis() {
+ // No phis were collected. Nothing to do.
+ if (phis_.length() == 0) return;
+
+ // Worklist used to transitively clear kUint32 from phis that
+ // are used as arguments to other phis.
+ ZoneList<HPhi*> worklist(phis_.length(), zone_);
+
+ // Phi can be used as a uint32 value if and only if
+ // all its operands are uint32 values and all its
+ // uses are uint32 safe.
+
+ // Iterate over collected phis and unmark those that
+ // are unsafe. When unmarking phi unmark its operands
+ // and add it to the worklist if it is a phi as well.
+ // Phis that are still marked as safe are shifted down
+ // so that all safe phis form a prefix of the phis_ array.
+ int phi_count = 0;
+ for (int i = 0; i < phis_.length(); i++) {
+ HPhi* phi = phis_[i];
+
+ if (CheckPhiOperands(phi) && Uint32UsesAreSafe(phi)) {
+ phis_[phi_count++] = phi;
+ } else {
+ UnmarkPhi(phi, &worklist);
+ }
+ }
+
+ // Now phis array contains only those phis that have safe
+ // non-phi uses. Start transitively clearing kUint32 flag
+ // from phi operands of discovered non-safe phies until
+ // only safe phies are left.
+ while (!worklist.is_empty()) {
+ while (!worklist.is_empty()) {
+ HPhi* phi = worklist.RemoveLast();
+ UnmarkPhi(phi, &worklist);
+ }
+
+ // Check if any operands to safe phies were unmarked
+ // turning a safe phi into unsafe. The same value
+ // can flow into several phis.
+ int new_phi_count = 0;
+ for (int i = 0; i < phi_count; i++) {
+ HPhi* phi = phis_[i];
+
+ if (CheckPhiOperands(phi)) {
+ phis_[new_phi_count++] = phi;
+ } else {
+ UnmarkPhi(phi, &worklist);
+ }
+ }
+ phi_count = new_phi_count;
+ }
+}
+
+
+void HGraph::ComputeSafeUint32Operations() {
+ if (!FLAG_opt_safe_uint32_operations || uint32_instructions_ == NULL) {
+ return;
+ }
+
+ Uint32Analysis analysis(zone());
+ for (int i = 0; i < uint32_instructions_->length(); ++i) {
+ HInstruction* current = uint32_instructions_->at(i);
+ if (current->IsLinked() && current->representation().IsInteger32()) {
+ analysis.Analyze(current);
+ }
+ }
+
+ // Some phis might have been optimistically marked with kUint32 flag.
+ // Remove this flag from those phis that are unsafe and propagate
+ // this information transitively potentially clearing kUint32 flag
+ // from some non-phi operations that are used as operands to unsafe phis.
+ analysis.UnmarkUnsafePhis();
+}
+
+
void HGraph::ComputeMinusZeroChecks() {
BitVector visited(GetMaximumValueID(), zone());
for (int i = 0; i < blocks_.length(); ++i) {
@@ -2521,12 +2934,12 @@ void HGraph::ComputeMinusZeroChecks() {
FunctionState::FunctionState(HGraphBuilder* owner,
CompilationInfo* info,
TypeFeedbackOracle* oracle,
- ReturnHandlingFlag return_handling)
+ InliningKind inlining_kind)
: owner_(owner),
compilation_info_(info),
oracle_(oracle),
call_context_(NULL),
- return_handling_(return_handling),
+ inlining_kind_(inlining_kind),
function_return_(NULL),
test_context_(NULL),
entry_(NULL),
@@ -2539,10 +2952,13 @@ FunctionState::FunctionState(HGraphBuilder* owner,
HBasicBlock* if_false = owner->graph()->CreateBasicBlock();
if_true->MarkAsInlineReturnTarget();
if_false->MarkAsInlineReturnTarget();
- Expression* cond = TestContext::cast(owner->ast_context())->condition();
+ TestContext* outer_test_context = TestContext::cast(owner->ast_context());
+ Expression* cond = outer_test_context->condition();
+ TypeFeedbackOracle* outer_oracle = outer_test_context->oracle();
// The AstContext constructor pushed on the context stack. This newed
// instance is the reason that AstContext can't be BASE_EMBEDDED.
- test_context_ = new TestContext(owner, cond, if_true, if_false);
+ test_context_ =
+ new TestContext(owner, cond, outer_oracle, if_true, if_false);
} else {
function_return_ = owner->graph()->CreateBasicBlock();
function_return()->MarkAsInlineReturnTarget();
@@ -2618,14 +3034,15 @@ void TestContext::ReturnValue(HValue* value) {
}
-void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) {
+void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
ASSERT(!instr->IsControlInstruction());
owner()->AddInstruction(instr);
if (instr->HasObservableSideEffects()) owner()->AddSimulate(ast_id);
}
-void EffectContext::ReturnControl(HControlInstruction* instr, int ast_id) {
+void EffectContext::ReturnControl(HControlInstruction* instr,
+ BailoutId ast_id) {
ASSERT(!instr->HasObservableSideEffects());
HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
@@ -2637,7 +3054,7 @@ void EffectContext::ReturnControl(HControlInstruction* instr, int ast_id) {
}
-void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) {
+void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
ASSERT(!instr->IsControlInstruction());
if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
return owner()->Bailout("bad value context for arguments object value");
@@ -2648,7 +3065,7 @@ void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) {
}
-void ValueContext::ReturnControl(HControlInstruction* instr, int ast_id) {
+void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
ASSERT(!instr->HasObservableSideEffects());
if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
return owner()->Bailout("bad value context for arguments object value");
@@ -2668,7 +3085,7 @@ void ValueContext::ReturnControl(HControlInstruction* instr, int ast_id) {
}
-void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) {
+void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
ASSERT(!instr->IsControlInstruction());
HGraphBuilder* builder = owner();
builder->AddInstruction(instr);
@@ -2683,7 +3100,7 @@ void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) {
}
-void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) {
+void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
ASSERT(!instr->HasObservableSideEffects());
HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
@@ -2707,8 +3124,8 @@ void TestContext::BuildBranch(HValue* value) {
}
HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
- unsigned test_id = condition()->test_id();
- ToBooleanStub::Types expected(builder->oracle()->ToBooleanTypes(test_id));
+ TypeFeedbackId test_id = condition()->test_id();
+ ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id));
HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected);
builder->current_block()->Finish(test);
@@ -2734,11 +3151,7 @@ void TestContext::BuildBranch(HValue* value) {
void HGraphBuilder::Bailout(const char* reason) {
- if (FLAG_trace_bailout) {
- SmartArrayPointer<char> name(
- info()->shared_info()->DebugName()->ToCString());
- PrintF("Bailout in HGraphBuilder: @\"%s\": %s\n", *name, reason);
- }
+ info()->set_bailout_reason(reason);
SetStackOverflow();
}
@@ -2766,17 +3179,14 @@ void HGraphBuilder::VisitForTypeOf(Expression* expr) {
void HGraphBuilder::VisitForControl(Expression* expr,
HBasicBlock* true_block,
HBasicBlock* false_block) {
- TestContext for_test(this, expr, true_block, false_block);
+ TestContext for_test(this, expr, oracle(), true_block, false_block);
Visit(expr);
}
-HValue* HGraphBuilder::VisitArgument(Expression* expr) {
- VisitForValue(expr);
- if (HasStackOverflow() || current_block() == NULL) return NULL;
- HValue* value = Pop();
- Push(AddInstruction(new(zone()) HPushArgument(value)));
- return value;
+void HGraphBuilder::VisitArgument(Expression* expr) {
+ CHECK_ALIVE(VisitForValue(expr));
+ Push(AddInstruction(new(zone()) HPushArgument(Pop())));
}
@@ -2795,7 +3205,7 @@ void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) {
HGraph* HGraphBuilder::CreateGraph() {
- graph_ = new(zone()) HGraph(info(), zone());
+ graph_ = new(zone()) HGraph(info());
if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info());
{
@@ -2831,7 +3241,7 @@ HGraph* HGraphBuilder::CreateGraph() {
HEnvironment* initial_env = environment()->CopyWithoutHistory();
HBasicBlock* body_entry = CreateBasicBlock(initial_env);
current_block()->Goto(body_entry);
- body_entry->SetJoinId(AstNode::kFunctionEntryId);
+ body_entry->SetJoinId(BailoutId::FunctionEntry());
set_current_block(body_entry);
// Handle implicit declaration of the function name in named function
@@ -2840,7 +3250,7 @@ HGraph* HGraphBuilder::CreateGraph() {
VisitVariableDeclaration(scope->function());
}
VisitDeclarations(scope->declarations());
- AddSimulate(AstNode::kDeclarationsId);
+ AddSimulate(BailoutId::Declarations());
HValue* context = environment()->LookupContext();
AddInstruction(
@@ -2854,50 +3264,78 @@ HGraph* HGraphBuilder::CreateGraph() {
current_block()->FinishExit(instr);
set_current_block(NULL);
}
+
+ // If the checksum of the number of type info changes is the same as the
+ // last time this function was compiled, then this recompile is likely not
+ // due to missing/inadequate type feedback, but rather too aggressive
+ // optimization. Disable optimistic LICM in that case.
+ Handle<Code> unoptimized_code(info()->shared_info()->code());
+ ASSERT(unoptimized_code->kind() == Code::FUNCTION);
+ Handle<Object> maybe_type_info(unoptimized_code->type_feedback_info());
+ Handle<TypeFeedbackInfo> type_info(
+ Handle<TypeFeedbackInfo>::cast(maybe_type_info));
+ int checksum = type_info->own_type_change_checksum();
+ int composite_checksum = graph()->update_type_change_checksum(checksum);
+ graph()->set_use_optimistic_licm(
+ !type_info->matches_inlined_type_change_checksum(composite_checksum));
+ type_info->set_inlined_type_change_checksum(composite_checksum);
}
- graph()->OrderBlocks();
- graph()->AssignDominators();
+ return graph();
+}
+
+bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
+ *bailout_reason = SmartArrayPointer<char>();
+ OrderBlocks();
+ AssignDominators();
#ifdef DEBUG
// Do a full verify after building the graph and computing dominators.
- graph()->Verify(true);
+ Verify(true);
#endif
- graph()->PropagateDeoptimizingMark();
- if (!graph()->CheckConstPhiUses()) {
- Bailout("Unsupported phi use of const variable");
- return NULL;
+ PropagateDeoptimizingMark();
+ if (!CheckConstPhiUses()) {
+ *bailout_reason = SmartArrayPointer<char>(StrDup(
+ "Unsupported phi use of const variable"));
+ return false;
}
- graph()->EliminateRedundantPhis();
- if (!graph()->CheckArgumentsPhiUses()) {
- Bailout("Unsupported phi use of arguments");
- return NULL;
+ EliminateRedundantPhis();
+ if (!CheckArgumentsPhiUses()) {
+ *bailout_reason = SmartArrayPointer<char>(StrDup(
+ "Unsupported phi use of arguments"));
+ return false;
}
- if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis();
- graph()->CollectPhis();
+ if (FLAG_eliminate_dead_phis) EliminateUnreachablePhis();
+ CollectPhis();
- if (graph()->has_osr_loop_entry()) {
- const ZoneList<HPhi*>* phis = graph()->osr_loop_entry()->phis();
+ if (has_osr_loop_entry()) {
+ const ZoneList<HPhi*>* phis = osr_loop_entry()->phis();
for (int j = 0; j < phis->length(); j++) {
HPhi* phi = phis->at(j);
- graph()->osr_values()->at(phi->merged_index())->set_incoming_value(phi);
+ osr_values()->at(phi->merged_index())->set_incoming_value(phi);
}
}
- HInferRepresentation rep(graph());
+ HInferRepresentation rep(this);
rep.Analyze();
- graph()->MarkDeoptimizeOnUndefined();
- graph()->InsertRepresentationChanges();
+ MarkDeoptimizeOnUndefined();
+ InsertRepresentationChanges();
+
+ InitializeInferredTypes();
+
+ // Must be performed before canonicalization to ensure that Canonicalize
+ // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with
+ // zero.
+ ComputeSafeUint32Operations();
- graph()->InitializeInferredTypes();
- graph()->Canonicalize();
+ Canonicalize();
// Perform common subexpression elimination and loop-invariant code motion.
if (FLAG_use_gvn) {
- HPhase phase("H_Global value numbering", graph());
- HGlobalValueNumberer gvn(graph(), info());
+ HPhase phase("H_Global value numbering", this);
+ HGlobalValueNumberer gvn(this, info());
bool removed_side_effects = gvn.Analyze();
// Trigger a second analysis pass to further eliminate duplicate values that
// could only be discovered by removing side-effect-generating instructions
@@ -2909,19 +3347,20 @@ HGraph* HGraphBuilder::CreateGraph() {
}
if (FLAG_use_range) {
- HRangeAnalysis rangeAnalysis(graph());
+ HRangeAnalysis rangeAnalysis(this);
rangeAnalysis.Analyze();
}
- graph()->ComputeMinusZeroChecks();
+ ComputeMinusZeroChecks();
// Eliminate redundant stack checks on backwards branches.
- HStackCheckEliminator sce(graph());
+ HStackCheckEliminator sce(this);
sce.Process();
- graph()->EliminateRedundantBoundsChecks();
- graph()->DehoistSimpleArrayIndexComputations();
+ EliminateRedundantBoundsChecks();
+ DehoistSimpleArrayIndexComputations();
+ if (FLAG_dead_code_elimination) DeadCodeElimination();
- return graph();
+ return true;
}
@@ -2946,6 +3385,8 @@ class BoundsCheckKey : public ZoneObject {
static BoundsCheckKey* Create(Zone* zone,
HBoundsCheck* check,
int32_t* offset) {
+ if (!check->index()->representation().IsInteger32()) return NULL;
+
HValue* index_base = NULL;
HConstant* constant = NULL;
bool is_sub = false;
@@ -3012,7 +3453,8 @@ class BoundsCheckBbData: public ZoneObject {
int32_t LowerOffset() const { return lower_offset_; }
int32_t UpperOffset() const { return upper_offset_; }
HBasicBlock* BasicBlock() const { return basic_block_; }
- HBoundsCheck* Check() const { return check_; }
+ HBoundsCheck* LowerCheck() const { return lower_check_; }
+ HBoundsCheck* UpperCheck() const { return upper_check_; }
BoundsCheckBbData* NextInBasicBlock() const { return next_in_bb_; }
BoundsCheckBbData* FatherInDominatorTree() const { return father_in_dt_; }
@@ -3020,76 +3462,85 @@ class BoundsCheckBbData: public ZoneObject {
return offset >= LowerOffset() && offset <= UpperOffset();
}
- // This method removes new_check and modifies the current check so that it
- // also "covers" what new_check covered.
- // The obvious precondition is that new_check follows Check() in the
- // same basic block, and that new_offset is not covered (otherwise we
- // could simply remove new_check).
- // As a consequence LowerOffset() or UpperOffset() change (the covered
+ bool HasSingleCheck() { return lower_check_ == upper_check_; }
+
+ // The goal of this method is to modify either upper_offset_ or
+ // lower_offset_ so that also new_offset is covered (the covered
// range grows).
//
- // In the general case the check covering the current range should be like
- // these two checks:
- // 0 <= Key()->IndexBase() + LowerOffset()
- // Key()->IndexBase() + UpperOffset() < Key()->Length()
+ // The precondition is that new_check follows UpperCheck() and
+ // LowerCheck() in the same basic block, and that new_offset is not
+ // covered (otherwise we could simply remove new_check).
//
- // We can transform the second check like this:
- // Key()->IndexBase() + LowerOffset() <
- // Key()->Length() + (LowerOffset() - UpperOffset())
- // so we can handle both checks with a single unsigned comparison.
- //
- // The bulk of this method changes Check()->index() and Check()->length()
- // replacing them with new HAdd instructions to perform the transformation
- // described above.
+ // If HasSingleCheck() is true then new_check is added as "second check"
+ // (either upper or lower; note that HasSingleCheck() becomes false).
+ // Otherwise one of the current checks is modified so that it also covers
+ // new_offset, and new_check is removed.
void CoverCheck(HBoundsCheck* new_check,
int32_t new_offset) {
ASSERT(new_check->index()->representation().IsInteger32());
+ bool keep_new_check = false;
if (new_offset > upper_offset_) {
upper_offset_ = new_offset;
+ if (HasSingleCheck()) {
+ keep_new_check = true;
+ upper_check_ = new_check;
+ } else {
+ BuildOffsetAdd(upper_check_,
+ &added_upper_index_,
+ &added_upper_offset_,
+ Key()->IndexBase(),
+ new_check->index()->representation(),
+ new_offset);
+ upper_check_->SetOperandAt(0, added_upper_index_);
+ }
} else if (new_offset < lower_offset_) {
lower_offset_ = new_offset;
+ if (HasSingleCheck()) {
+ keep_new_check = true;
+ lower_check_ = new_check;
+ } else {
+ BuildOffsetAdd(lower_check_,
+ &added_lower_index_,
+ &added_lower_offset_,
+ Key()->IndexBase(),
+ new_check->index()->representation(),
+ new_offset);
+ lower_check_->SetOperandAt(0, added_lower_index_);
+ }
} else {
ASSERT(false);
}
- BuildOffsetAdd(&added_index_,
- &added_index_offset_,
- Key()->IndexBase(),
- new_check->index()->representation(),
- lower_offset_);
- Check()->SetOperandAt(0, added_index_);
- BuildOffsetAdd(&added_length_,
- &added_length_offset_,
- Key()->Length(),
- new_check->length()->representation(),
- lower_offset_ - upper_offset_);
- Check()->SetOperandAt(1, added_length_);
-
- new_check->DeleteAndReplaceWith(NULL);
+ if (!keep_new_check) {
+ new_check->DeleteAndReplaceWith(NULL);
+ }
}
void RemoveZeroOperations() {
- RemoveZeroAdd(&added_index_, &added_index_offset_);
- RemoveZeroAdd(&added_length_, &added_length_offset_);
+ RemoveZeroAdd(&added_lower_index_, &added_lower_offset_);
+ RemoveZeroAdd(&added_upper_index_, &added_upper_offset_);
}
BoundsCheckBbData(BoundsCheckKey* key,
int32_t lower_offset,
int32_t upper_offset,
HBasicBlock* bb,
- HBoundsCheck* check,
+ HBoundsCheck* lower_check,
+ HBoundsCheck* upper_check,
BoundsCheckBbData* next_in_bb,
BoundsCheckBbData* father_in_dt)
: key_(key),
lower_offset_(lower_offset),
upper_offset_(upper_offset),
basic_block_(bb),
- check_(check),
- added_index_offset_(NULL),
- added_index_(NULL),
- added_length_offset_(NULL),
- added_length_(NULL),
+ lower_check_(lower_check),
+ upper_check_(upper_check),
+ added_lower_index_(NULL),
+ added_lower_offset_(NULL),
+ added_upper_index_(NULL),
+ added_upper_offset_(NULL),
next_in_bb_(next_in_bb),
father_in_dt_(father_in_dt) { }
@@ -3098,29 +3549,33 @@ class BoundsCheckBbData: public ZoneObject {
int32_t lower_offset_;
int32_t upper_offset_;
HBasicBlock* basic_block_;
- HBoundsCheck* check_;
- HConstant* added_index_offset_;
- HAdd* added_index_;
- HConstant* added_length_offset_;
- HAdd* added_length_;
+ HBoundsCheck* lower_check_;
+ HBoundsCheck* upper_check_;
+ HAdd* added_lower_index_;
+ HConstant* added_lower_offset_;
+ HAdd* added_upper_index_;
+ HConstant* added_upper_offset_;
BoundsCheckBbData* next_in_bb_;
BoundsCheckBbData* father_in_dt_;
- void BuildOffsetAdd(HAdd** add,
+ void BuildOffsetAdd(HBoundsCheck* check,
+ HAdd** add,
HConstant** constant,
HValue* original_value,
Representation representation,
int32_t new_offset) {
HConstant* new_constant = new(BasicBlock()->zone())
- HConstant(Handle<Object>(Smi::FromInt(new_offset)),
- Representation::Integer32());
+ HConstant(new_offset, Representation::Integer32());
if (*add == NULL) {
- new_constant->InsertBefore(Check());
- *add = new(BasicBlock()->zone()) HAdd(NULL,
+ new_constant->InsertBefore(check);
+ // Because of the bounds checks elimination algorithm, the index is always
+ // an HAdd or an HSub here, so we can safely cast to an HBinaryOperation.
+ HValue* context = HBinaryOperation::cast(check->index())->context();
+ *add = new(BasicBlock()->zone()) HAdd(context,
original_value,
new_constant);
(*add)->AssumeRepresentation(representation);
- (*add)->InsertBefore(Check());
+ (*add)->InsertBefore(check);
} else {
new_constant->InsertBefore(*add);
(*constant)->DeleteAndReplaceWith(new_constant);
@@ -3185,6 +3640,7 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb,
int32_t offset;
BoundsCheckKey* key =
BoundsCheckKey::Create(zone(), check, &offset);
+ if (key == NULL) continue;
BoundsCheckBbData** data_p = table->LookupOrInsert(key, zone());
BoundsCheckBbData* data = *data_p;
if (data == NULL) {
@@ -3193,6 +3649,7 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb,
offset,
bb,
check,
+ check,
bb_data_list,
NULL);
*data_p = bb_data_list;
@@ -3211,7 +3668,8 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb,
new_lower_offset,
new_upper_offset,
bb,
- check,
+ data->LowerCheck(),
+ data->UpperCheck(),
bb_data_list,
data);
table->Insert(key, bb_data_list, zone());
@@ -3237,7 +3695,6 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb,
void HGraph::EliminateRedundantBoundsChecks() {
HPhase phase("H_Eliminate bounds checks", this);
- AssertNoAllocation no_gc;
BoundsCheckTable checks_table(zone());
EliminateRedundantBoundsChecks(entry_block(), &checks_table);
}
@@ -3245,6 +3702,7 @@ void HGraph::EliminateRedundantBoundsChecks() {
static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) {
HValue* index = array_operation->GetKey();
+ if (!index->representation().IsInteger32()) return;
HConstant* constant;
HValue* subexpression;
@@ -3330,6 +3788,36 @@ void HGraph::DehoistSimpleArrayIndexComputations() {
}
+void HGraph::DeadCodeElimination() {
+ HPhase phase("H_Dead code elimination", this);
+ ZoneList<HInstruction*> worklist(blocks_.length(), zone());
+ for (int i = 0; i < blocks()->length(); ++i) {
+ for (HInstruction* instr = blocks()->at(i)->first();
+ instr != NULL;
+ instr = instr->next()) {
+ if (instr->IsDead()) worklist.Add(instr, zone());
+ }
+ }
+
+ while (!worklist.is_empty()) {
+ HInstruction* instr = worklist.RemoveLast();
+ if (FLAG_trace_dead_code_elimination) {
+ HeapStringAllocator allocator;
+ StringStream stream(&allocator);
+ instr->PrintNameTo(&stream);
+ stream.Add(" = ");
+ instr->PrintTo(&stream);
+ PrintF("[removing dead instruction %s]\n", *stream.ToCString());
+ }
+ instr->DeleteAndReplaceWith(NULL);
+ for (int i = 0; i < instr->OperandCount(); ++i) {
+ HValue* operand = instr->OperandAt(i);
+ if (operand->IsDead()) worklist.Add(HInstruction::cast(operand), zone());
+ }
+ }
+}
+
+
HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
ASSERT(current_block() != NULL);
current_block()->AddInstruction(instr);
@@ -3337,7 +3825,7 @@ HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
}
-void HGraphBuilder::AddSimulate(int ast_id) {
+void HGraphBuilder::AddSimulate(BailoutId ast_id) {
ASSERT(current_block() != NULL);
current_block()->AddSimulate(ast_id);
}
@@ -3581,28 +4069,29 @@ void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
+ FunctionState* state = function_state();
AstContext* context = call_context();
if (context == NULL) {
// Not an inlined return, so an actual one.
CHECK_ALIVE(VisitForValue(stmt->expression()));
HValue* result = environment()->Pop();
current_block()->FinishExit(new(zone()) HReturn(result));
- } else if (function_state()->is_construct()) {
- // Return from an inlined construct call. In a test context the return
- // value will always evaluate to true, in a value context the return value
- // needs to be a JSObject.
+ } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
+ // Return from an inlined construct call. In a test context the return value
+ // will always evaluate to true, in a value context the return value needs
+ // to be a JSObject.
if (context->IsTest()) {
TestContext* test = TestContext::cast(context);
CHECK_ALIVE(VisitForEffect(stmt->expression()));
- current_block()->Goto(test->if_true(), function_state());
+ current_block()->Goto(test->if_true(), state);
} else if (context->IsEffect()) {
CHECK_ALIVE(VisitForEffect(stmt->expression()));
- current_block()->Goto(function_return(), function_state());
+ current_block()->Goto(function_return(), state);
} else {
ASSERT(context->IsValue());
CHECK_ALIVE(VisitForValue(stmt->expression()));
HValue* return_value = Pop();
- HValue* receiver = environment()->Lookup(0);
+ HValue* receiver = environment()->arguments_environment()->Lookup(0);
HHasInstanceTypeAndBranch* typecheck =
new(zone()) HHasInstanceTypeAndBranch(return_value,
FIRST_SPEC_OBJECT_TYPE,
@@ -3612,31 +4101,36 @@ void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
typecheck->SetSuccessorAt(0, if_spec_object);
typecheck->SetSuccessorAt(1, not_spec_object);
current_block()->Finish(typecheck);
- if_spec_object->AddLeaveInlined(return_value,
- function_return(),
- function_state());
- not_spec_object->AddLeaveInlined(receiver,
- function_return(),
- function_state());
+ if_spec_object->AddLeaveInlined(return_value, state);
+ not_spec_object->AddLeaveInlined(receiver, state);
+ }
+ } else if (state->inlining_kind() == SETTER_CALL_RETURN) {
+ // Return from an inlined setter call. The returned value is never used, the
+ // value of an assignment is always the value of the RHS of the assignment.
+ CHECK_ALIVE(VisitForEffect(stmt->expression()));
+ if (context->IsTest()) {
+ HValue* rhs = environment()->arguments_environment()->Lookup(1);
+ context->ReturnValue(rhs);
+ } else if (context->IsEffect()) {
+ current_block()->Goto(function_return(), state);
+ } else {
+ ASSERT(context->IsValue());
+ HValue* rhs = environment()->arguments_environment()->Lookup(1);
+ current_block()->AddLeaveInlined(rhs, state);
}
} else {
- // Return from an inlined function, visit the subexpression in the
+ // Return from a normal inlined function. Visit the subexpression in the
// expression context of the call.
if (context->IsTest()) {
TestContext* test = TestContext::cast(context);
- VisitForControl(stmt->expression(),
- test->if_true(),
- test->if_false());
+ VisitForControl(stmt->expression(), test->if_true(), test->if_false());
} else if (context->IsEffect()) {
CHECK_ALIVE(VisitForEffect(stmt->expression()));
- current_block()->Goto(function_return(), function_state());
+ current_block()->Goto(function_return(), state);
} else {
ASSERT(context->IsValue());
CHECK_ALIVE(VisitForValue(stmt->expression()));
- HValue* return_value = Pop();
- current_block()->AddLeaveInlined(return_value,
- function_return(),
- function_state());
+ current_block()->AddLeaveInlined(Pop(), state);
}
}
set_current_block(NULL);
@@ -3711,7 +4205,7 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
}
// 2. Build all the tests, with dangling true branches
- int default_id = AstNode::kNoNumber;
+ BailoutId default_id = BailoutId::None();
for (int i = 0; i < clause_count; ++i) {
CaseClause* clause = clauses->at(i);
if (clause->is_default()) {
@@ -3764,9 +4258,7 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
HBasicBlock* last_block = current_block();
if (not_string_block != NULL) {
- int join_id = (default_id != AstNode::kNoNumber)
- ? default_id
- : stmt->ExitId();
+ BailoutId join_id = !default_id.IsNone() ? default_id : stmt->ExitId();
last_block = CreateJoin(last_block, not_string_block, join_id);
}
@@ -3856,7 +4348,7 @@ bool HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
non_osr_entry->Goto(loop_predecessor);
set_current_block(osr_entry);
- int osr_entry_id = statement->OsrEntryId();
+ BailoutId osr_entry_id = statement->OsrEntryId();
int first_expression_index = environment()->first_expression_index();
int length = environment()->length();
ZoneList<HUnknownOSRValue*>* osr_values =
@@ -4080,15 +4572,14 @@ void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
map,
DescriptorArray::kEnumCacheBridgeCacheIndex));
- HInstruction* array_length = AddInstruction(
- new(zone()) HFixedArrayBaseLength(array));
+ HInstruction* enum_length = AddInstruction(new(zone()) HMapEnumLength(map));
HInstruction* start_index = AddInstruction(new(zone()) HConstant(
Handle<Object>(Smi::FromInt(0)), Representation::Integer32()));
Push(map);
Push(array);
- Push(array_length);
+ Push(enum_length);
Push(start_index);
HInstruction* index_cache = AddInstruction(
@@ -4128,7 +4619,8 @@ void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
HValue* key = AddInstruction(
new(zone()) HLoadKeyedFastElement(
environment()->ExpressionStackAt(2), // Enum cache.
- environment()->ExpressionStackAt(0))); // Iteration index.
+ environment()->ExpressionStackAt(0), // Iteration index.
+ environment()->ExpressionStackAt(0)));
// Check if the expected map still matches that of the enumerable.
// If not just deoptimize.
@@ -4283,8 +4775,7 @@ HGraphBuilder::GlobalPropertyAccess HGraphBuilder::LookupGlobalProperty(
}
Handle<GlobalObject> global(info()->global_object());
global->Lookup(*var->name(), lookup);
- if (!lookup->IsFound() ||
- lookup->type() != NORMAL ||
+ if (!lookup->IsNormal() ||
(is_store && lookup->IsReadOnly()) ||
lookup->holder() != *global) {
return kUseGeneric;
@@ -4314,8 +4805,9 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
Variable* variable = expr->var();
switch (variable->location()) {
case Variable::UNALLOCATED: {
- if (variable->mode() == LET || variable->mode() == CONST_HARMONY) {
- return Bailout("reference to global harmony declared variable");
+ if (IsLexicalVariableMode(variable->mode())) {
+ // TODO(rossberg): should this be an ASSERT?
+ return Bailout("reference to global lexical variable");
}
// Handle known global constants like 'undefined' specially to avoid a
// load from a global cell for them.
@@ -4360,9 +4852,8 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
case Variable::LOCAL: {
HValue* value = environment()->Lookup(variable);
if (value == graph()->GetConstantHole()) {
- ASSERT(variable->mode() == CONST ||
- variable->mode() == CONST_HARMONY ||
- variable->mode() == LET);
+ ASSERT(IsDeclaredVariableMode(variable->mode()) &&
+ variable->mode() != VAR);
return Bailout("reference to uninitialized variable");
}
return ast_context()->ReturnValue(value);
@@ -4394,9 +4885,12 @@ void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
+ Handle<JSFunction> closure = function_state()->compilation_info()->closure();
+ Handle<FixedArray> literals(closure->literals());
HValue* context = environment()->LookupContext();
HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context,
+ literals,
expr->pattern(),
expr->flags(),
expr->literal_index());
@@ -4404,6 +4898,86 @@ void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
}
+static void LookupInPrototypes(Handle<Map> map,
+ Handle<String> name,
+ LookupResult* lookup) {
+ while (map->prototype()->IsJSObject()) {
+ Handle<JSObject> holder(JSObject::cast(map->prototype()));
+ if (!holder->HasFastProperties()) break;
+ map = Handle<Map>(holder->map());
+ map->LookupDescriptor(*holder, *name, lookup);
+ if (lookup->IsFound()) return;
+ }
+ lookup->NotFound();
+}
+
+
+// Tries to find a JavaScript accessor of the given name in the prototype chain
+// starting at the given map. Return true iff there is one, including the
+// corresponding AccessorPair plus its holder (which could be null when the
+// accessor is found directly in the given map).
+static bool LookupAccessorPair(Handle<Map> map,
+ Handle<String> name,
+ Handle<AccessorPair>* accessors,
+ Handle<JSObject>* holder) {
+ LookupResult lookup(map->GetIsolate());
+
+ // Check for a JavaScript accessor directly in the map.
+ map->LookupDescriptor(NULL, *name, &lookup);
+ if (lookup.IsPropertyCallbacks()) {
+ Handle<Object> callback(lookup.GetValueFromMap(*map));
+ if (!callback->IsAccessorPair()) return false;
+ *accessors = Handle<AccessorPair>::cast(callback);
+ *holder = Handle<JSObject>();
+ return true;
+ }
+
+ // Everything else, e.g. a field, can't be an accessor call.
+ if (lookup.IsFound()) return false;
+
+ // Check for a JavaScript accessor somewhere in the proto chain.
+ LookupInPrototypes(map, name, &lookup);
+ if (lookup.IsPropertyCallbacks()) {
+ Handle<Object> callback(lookup.GetValue());
+ if (!callback->IsAccessorPair()) return false;
+ *accessors = Handle<AccessorPair>::cast(callback);
+ *holder = Handle<JSObject>(lookup.holder());
+ return true;
+ }
+
+ // We haven't found a JavaScript accessor anywhere.
+ return false;
+}
+
+
+static bool LookupGetter(Handle<Map> map,
+ Handle<String> name,
+ Handle<JSFunction>* getter,
+ Handle<JSObject>* holder) {
+ Handle<AccessorPair> accessors;
+ if (LookupAccessorPair(map, name, &accessors, holder) &&
+ accessors->getter()->IsJSFunction()) {
+ *getter = Handle<JSFunction>(JSFunction::cast(accessors->getter()));
+ return true;
+ }
+ return false;
+}
+
+
+static bool LookupSetter(Handle<Map> map,
+ Handle<String> name,
+ Handle<JSFunction>* setter,
+ Handle<JSObject>* holder) {
+ Handle<AccessorPair> accessors;
+ if (LookupAccessorPair(map, name, &accessors, holder) &&
+ accessors->setter()->IsJSFunction()) {
+ *setter = Handle<JSFunction>(JSFunction::cast(accessors->setter()));
+ return true;
+ }
+ return false;
+}
+
+
// Determines whether the given array or object literal boilerplate satisfies
// all limits to be considered for fast deep-copying and computes the total
// size of all objects that are part of the graph.
@@ -4521,8 +5095,23 @@ void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
property->RecordTypeFeedback(oracle());
CHECK_ALIVE(VisitForValue(value));
HValue* value = Pop();
+ Handle<Map> map = property->GetReceiverType();
+ Handle<String> name = property->key()->AsPropertyName();
HInstruction* store;
- CHECK_ALIVE(store = BuildStoreNamed(literal, value, property));
+ if (map.is_null()) {
+ // If we don't know the monomorphic type, do a generic store.
+ CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value));
+ } else {
+#if DEBUG
+ Handle<JSFunction> setter;
+ Handle<JSObject> holder;
+ ASSERT(!LookupSetter(map, name, &setter, &holder));
+#endif
+ CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal,
+ name,
+ value,
+ map));
+ }
AddInstruction(store);
if (store->HasObservableSideEffects()) AddSimulate(key->id());
} else {
@@ -4619,7 +5208,9 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
HValue* value = Pop();
if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal");
- elements = new(zone()) HLoadElements(literal);
+ // Pass in literal as dummy depedency, since the receiver always has
+ // elements.
+ elements = new(zone()) HLoadElements(literal, literal);
AddInstruction(elements);
HValue* key = AddInstruction(
@@ -4662,10 +5253,17 @@ static bool ComputeLoadStoreField(Handle<Map> type,
Handle<String> name,
LookupResult* lookup,
bool is_store) {
- type->LookupInDescriptors(NULL, *name, lookup);
- if (!lookup->IsFound()) return false;
- if (lookup->type() == FIELD) return true;
- return is_store && (lookup->type() == MAP_TRANSITION) &&
+ // If we directly find a field, the access can be inlined.
+ type->LookupDescriptor(NULL, *name, lookup);
+ if (lookup->IsField()) return true;
+
+ // For a load, we are out of luck if there is no such field.
+ if (!is_store) return false;
+
+ // 2nd chance: A store into a non-existent field can still be inlined if we
+ // have a matching transition and some room left in the object.
+ type->LookupTransition(NULL, *name, lookup);
+ return lookup->IsTransitionToField(*type) &&
(type->unused_property_fields() > 0);
}
@@ -4673,8 +5271,8 @@ static bool ComputeLoadStoreField(Handle<Map> type,
static int ComputeLoadStoreFieldIndex(Handle<Map> type,
Handle<String> name,
LookupResult* lookup) {
- ASSERT(lookup->type() == FIELD || lookup->type() == MAP_TRANSITION);
- if (lookup->type() == FIELD) {
+ ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type));
+ if (lookup->IsField()) {
return lookup->GetLocalFieldIndexFromMap(*type);
} else {
Map* transition = lookup->GetTransitionMapFromMap(*type);
@@ -4686,20 +5284,20 @@ static int ComputeLoadStoreFieldIndex(Handle<Map> type,
HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object,
Handle<String> name,
HValue* value,
- Handle<Map> type,
+ Handle<Map> map,
LookupResult* lookup,
bool smi_and_map_check) {
ASSERT(lookup->IsFound());
if (smi_and_map_check) {
AddInstruction(new(zone()) HCheckNonSmi(object));
- AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone()));
+ AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
}
// If the property does not exist yet, we have to check that it wasn't made
// readonly or turned into a setter by some meanwhile modifications on the
// prototype chain.
- if (!lookup->IsProperty() && type->prototype()->IsJSReceiver()) {
- Object* proto = type->prototype();
+ if (!lookup->IsProperty() && map->prototype()->IsJSReceiver()) {
+ Object* proto = map->prototype();
// First check that the prototype chain isn't affected already.
LookupResult proto_result(isolate());
proto->Lookup(*name, &proto_result);
@@ -4718,24 +5316,24 @@ HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object,
}
ASSERT(proto->IsJSObject());
AddInstruction(new(zone()) HCheckPrototypeMaps(
- Handle<JSObject>(JSObject::cast(type->prototype())),
+ Handle<JSObject>(JSObject::cast(map->prototype())),
Handle<JSObject>(JSObject::cast(proto))));
}
- int index = ComputeLoadStoreFieldIndex(type, name, lookup);
+ int index = ComputeLoadStoreFieldIndex(map, name, lookup);
bool is_in_object = index < 0;
int offset = index * kPointerSize;
if (index < 0) {
// Negative property indices are in-object properties, indexed
// from the end of the fixed part of the object.
- offset += type->instance_size();
+ offset += map->instance_size();
} else {
offset += FixedArray::kHeaderSize;
}
HStoreNamedField* instr =
new(zone()) HStoreNamedField(object, name, value, is_in_object, offset);
- if (lookup->type() == MAP_TRANSITION) {
- Handle<Map> transition(lookup->GetTransitionMapFromMap(*type));
+ if (lookup->IsTransitionToField(*map)) {
+ Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
instr->set_transition(transition);
// TODO(fschneider): Record the new map type of the object in the IR to
// enable elimination of redundant checks after the transition store.
@@ -4758,44 +5356,31 @@ HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object,
}
-HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object,
+HInstruction* HGraphBuilder::BuildCallSetter(HValue* object,
HValue* value,
- ObjectLiteral::Property* prop) {
- Literal* key = prop->key()->AsLiteral();
- Handle<String> name = Handle<String>::cast(key->handle());
- ASSERT(!name.is_null());
-
- LookupResult lookup(isolate());
- Handle<Map> type = prop->GetReceiverType();
- bool is_monomorphic = prop->IsMonomorphic() &&
- ComputeLoadStoreField(type, name, &lookup, true);
-
- return is_monomorphic
- ? BuildStoreNamedField(object, name, value, type, &lookup,
- true) // Needs smi and map check.
- : BuildStoreNamedGeneric(object, name, value);
+ Handle<Map> map,
+ Handle<JSFunction> setter,
+ Handle<JSObject> holder) {
+ AddCheckConstantFunction(holder, object, map, true);
+ AddInstruction(new(zone()) HPushArgument(object));
+ AddInstruction(new(zone()) HPushArgument(value));
+ return new(zone()) HCallConstantFunction(setter, 2);
}
-HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object,
- HValue* value,
- Expression* expr) {
- Property* prop = (expr->AsProperty() != NULL)
- ? expr->AsProperty()
- : expr->AsAssignment()->target()->AsProperty();
- Literal* key = prop->key()->AsLiteral();
- Handle<String> name = Handle<String>::cast(key->handle());
- ASSERT(!name.is_null());
-
+HInstruction* HGraphBuilder::BuildStoreNamedMonomorphic(HValue* object,
+ Handle<String> name,
+ HValue* value,
+ Handle<Map> map) {
+ // Handle a store to a known field.
LookupResult lookup(isolate());
- SmallMapList* types = expr->GetReceiverTypes();
- bool is_monomorphic = expr->IsMonomorphic() &&
- ComputeLoadStoreField(types->first(), name, &lookup, true);
+ if (ComputeLoadStoreField(map, name, &lookup, true)) {
+ // true = needs smi and map check.
+ return BuildStoreNamedField(object, name, value, map, &lookup, true);
+ }
- return is_monomorphic
- ? BuildStoreNamedField(object, name, value, types->first(), &lookup,
- true) // Needs smi and map check.
- : BuildStoreNamedGeneric(object, name, value);
+ // No luck, do a generic store.
+ return BuildStoreNamedGeneric(object, name, value);
}
@@ -4835,10 +5420,11 @@ void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
// Use monomorphic load if property lookup results in the same field index
// for all maps. Requires special map check on the set of all handled maps.
+ AddInstruction(new(zone()) HCheckNonSmi(object));
HInstruction* instr;
if (count == types->length() && is_monomorphic_field) {
AddInstruction(new(zone()) HCheckMaps(object, types, zone()));
- instr = BuildLoadNamedField(object, expr, map, &lookup, false);
+ instr = BuildLoadNamedField(object, map, &lookup, false);
} else {
HValue* context = environment()->LookupContext();
instr = new(zone()) HLoadNamedFieldPolymorphic(context,
@@ -4935,36 +5521,63 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
expr->RecordTypeFeedback(oracle(), zone());
CHECK_ALIVE(VisitForValue(prop->obj()));
- HValue* value = NULL;
- HInstruction* instr = NULL;
-
if (prop->key()->IsPropertyName()) {
// Named store.
CHECK_ALIVE(VisitForValue(expr->value()));
- value = Pop();
- HValue* object = Pop();
+ HValue* value = environment()->ExpressionStackAt(0);
+ HValue* object = environment()->ExpressionStackAt(1);
Literal* key = prop->key()->AsLiteral();
Handle<String> name = Handle<String>::cast(key->handle());
ASSERT(!name.is_null());
+ HInstruction* instr = NULL;
SmallMapList* types = expr->GetReceiverTypes();
- if (expr->IsMonomorphic()) {
- CHECK_ALIVE(instr = BuildStoreNamed(object, value, expr));
+ bool monomorphic = expr->IsMonomorphic();
+ Handle<Map> map;
+ if (monomorphic) {
+ map = types->first();
+ if (map->is_dictionary_map()) monomorphic = false;
+ }
+ if (monomorphic) {
+ Handle<JSFunction> setter;
+ Handle<JSObject> holder;
+ if (LookupSetter(map, name, &setter, &holder)) {
+ AddCheckConstantFunction(holder, object, map, true);
+ if (FLAG_inline_accessors && TryInlineSetter(setter, expr, value)) {
+ return;
+ }
+ Drop(2);
+ AddInstruction(new(zone()) HPushArgument(object));
+ AddInstruction(new(zone()) HPushArgument(value));
+ instr = new(zone()) HCallConstantFunction(setter, 2);
+ } else {
+ Drop(2);
+ CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
+ name,
+ value,
+ map));
+ }
} else if (types != NULL && types->length() > 1) {
- HandlePolymorphicStoreNamedField(expr, object, value, types, name);
- return;
-
+ Drop(2);
+ return HandlePolymorphicStoreNamedField(expr, object, value, types, name);
} else {
+ Drop(2);
instr = BuildStoreNamedGeneric(object, name, value);
}
+ Push(value);
+ instr->set_position(expr->position());
+ AddInstruction(instr);
+ if (instr->HasObservableSideEffects()) AddSimulate(expr->AssignmentId());
+ return ast_context()->ReturnValue(Pop());
+
} else {
// Keyed store.
CHECK_ALIVE(VisitForValue(prop->key()));
CHECK_ALIVE(VisitForValue(expr->value()));
- value = Pop();
+ HValue* value = Pop();
HValue* key = Pop();
HValue* object = Pop();
bool has_side_effects = false;
@@ -4977,11 +5590,6 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
AddSimulate(expr->AssignmentId());
return ast_context()->ReturnValue(Pop());
}
- Push(value);
- instr->set_position(expr->position());
- AddInstruction(instr);
- if (instr->HasObservableSideEffects()) AddSimulate(expr->AssignmentId());
- return ast_context()->ReturnValue(Pop());
}
@@ -4991,7 +5599,7 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
HValue* value,
int position,
- int ast_id) {
+ BailoutId ast_id) {
LookupResult lookup(isolate());
GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
if (type == kUseCell) {
@@ -5108,18 +5716,31 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
if (prop->key()->IsPropertyName()) {
// Named property.
CHECK_ALIVE(VisitForValue(prop->obj()));
- HValue* obj = Top();
-
- HInstruction* load = NULL;
- if (prop->IsMonomorphic()) {
- Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
- Handle<Map> map = prop->GetReceiverTypes()->first();
- load = BuildLoadNamed(obj, prop, map, name);
+ HValue* object = Top();
+
+ Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
+ Handle<Map> map;
+ HInstruction* load;
+ bool monomorphic = prop->IsMonomorphic();
+ if (monomorphic) {
+ map = prop->GetReceiverTypes()->first();
+ // We can't generate code for a monomorphic dict mode load so
+ // just pretend it is not monomorphic.
+ if (map->is_dictionary_map()) monomorphic = false;
+ }
+ if (monomorphic) {
+ Handle<JSFunction> getter;
+ Handle<JSObject> holder;
+ if (LookupGetter(map, name, &getter, &holder)) {
+ load = BuildCallGetter(object, map, getter, holder);
+ } else {
+ load = BuildLoadNamedMonomorphic(object, name, prop, map);
+ }
} else {
- load = BuildLoadNamedGeneric(obj, prop);
+ load = BuildLoadNamedGeneric(object, name, prop);
}
PushAndAdd(load);
- if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId());
+ if (load->HasObservableSideEffects()) AddSimulate(prop->LoadId());
CHECK_ALIVE(VisitForValue(expr->value()));
HValue* right = Pop();
@@ -5130,7 +5751,21 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
if (instr->HasObservableSideEffects()) AddSimulate(operation->id());
HInstruction* store;
- CHECK_ALIVE(store = BuildStoreNamed(obj, instr, prop));
+ if (!monomorphic) {
+ // If we don't know the monomorphic type, do a generic store.
+ CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr));
+ } else {
+ Handle<JSFunction> setter;
+ Handle<JSObject> holder;
+ if (LookupSetter(map, name, &setter, &holder)) {
+ store = BuildCallSetter(object, instr, map, setter, holder);
+ } else {
+ CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
+ name,
+ instr,
+ map));
+ }
+ }
AddInstruction(store);
// Drop the simulated receiver and value. Return the value.
Drop(2);
@@ -5147,11 +5782,11 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
bool has_side_effects = false;
HValue* load = HandleKeyedElementAccess(
- obj, key, NULL, prop, expr->CompoundLoadId(), RelocInfo::kNoPosition,
+ obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
false, // is_store
&has_side_effects);
Push(load);
- if (has_side_effects) AddSimulate(expr->CompoundLoadId());
+ if (has_side_effects) AddSimulate(prop->LoadId());
CHECK_ALIVE(VisitForValue(expr->value()));
@@ -5331,20 +5966,19 @@ void HGraphBuilder::VisitThrow(Throw* expr) {
HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
- Property* expr,
- Handle<Map> type,
+ Handle<Map> map,
LookupResult* lookup,
bool smi_and_map_check) {
if (smi_and_map_check) {
AddInstruction(new(zone()) HCheckNonSmi(object));
- AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone()));
+ AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
}
- int index = lookup->GetLocalFieldIndexFromMap(*type);
+ int index = lookup->GetLocalFieldIndexFromMap(*map);
if (index < 0) {
// Negative property indices are in-object properties, indexed
// from the end of the fixed part of the object.
- int offset = (index * kPointerSize) + type->instance_size();
+ int offset = (index * kPointerSize) + map->instance_size();
return new(zone()) HLoadNamedField(object, true, offset);
} else {
// Non-negative property indices are in the properties array.
@@ -5354,39 +5988,50 @@ HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
}
-HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj,
+HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* object,
+ Handle<String> name,
Property* expr) {
if (expr->IsUninitialized() && !FLAG_always_opt) {
AddInstruction(new(zone()) HSoftDeoptimize);
current_block()->MarkAsDeoptimizing();
}
- ASSERT(expr->key()->IsPropertyName());
- Handle<Object> name = expr->key()->AsLiteral()->handle();
HValue* context = environment()->LookupContext();
- return new(zone()) HLoadNamedGeneric(context, obj, name);
+ return new(zone()) HLoadNamedGeneric(context, object, name);
+}
+
+
+HInstruction* HGraphBuilder::BuildCallGetter(HValue* object,
+ Handle<Map> map,
+ Handle<JSFunction> getter,
+ Handle<JSObject> holder) {
+ AddCheckConstantFunction(holder, object, map, true);
+ AddInstruction(new(zone()) HPushArgument(object));
+ return new(zone()) HCallConstantFunction(getter, 1);
}
-HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj,
- Property* expr,
- Handle<Map> map,
- Handle<String> name) {
+HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object,
+ Handle<String> name,
+ Property* expr,
+ Handle<Map> map) {
+ // Handle a load from a known field.
+ ASSERT(!map->is_dictionary_map());
LookupResult lookup(isolate());
- map->LookupInDescriptors(NULL, *name, &lookup);
- if (lookup.IsFound() && lookup.type() == FIELD) {
- return BuildLoadNamedField(obj,
- expr,
- map,
- &lookup,
- true);
- } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) {
- AddInstruction(new(zone()) HCheckNonSmi(obj));
- AddInstruction(HCheckMaps::NewWithTransitions(obj, map, zone()));
+ map->LookupDescriptor(NULL, *name, &lookup);
+ if (lookup.IsField()) {
+ return BuildLoadNamedField(object, map, &lookup, true);
+ }
+
+ // Handle a load of a constant known function.
+ if (lookup.IsConstantFunction()) {
+ AddInstruction(new(zone()) HCheckNonSmi(object));
+ AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
return new(zone()) HConstant(function, Representation::Tagged());
- } else {
- return BuildLoadNamedGeneric(obj, expr);
}
+
+ // No luck, do a generic load.
+ return BuildLoadNamedGeneric(object, name, expr);
}
@@ -5401,6 +6046,7 @@ HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
HValue* external_elements,
HValue* checked_key,
HValue* val,
+ HValue* dependency,
ElementsKind elements_kind,
bool is_store) {
if (is_store) {
@@ -5443,8 +6089,14 @@ HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
external_elements, checked_key, val, elements_kind);
} else {
ASSERT(val == NULL);
- return new(zone()) HLoadKeyedSpecializedArrayElement(
- external_elements, checked_key, elements_kind);
+ HLoadKeyedSpecializedArrayElement* load =
+ new(zone()) HLoadKeyedSpecializedArrayElement(
+ external_elements, checked_key, dependency, elements_kind);
+ if (FLAG_opt_safe_uint32_operations &&
+ elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
+ graph()->RecordUint32Instruction(load);
+ }
+ return load;
}
}
@@ -5452,6 +6104,7 @@ HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements,
HValue* checked_key,
HValue* val,
+ HValue* load_dependency,
ElementsKind elements_kind,
bool is_store) {
if (is_store) {
@@ -5480,10 +6133,11 @@ HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements,
OMIT_HOLE_CHECK :
PERFORM_HOLE_CHECK;
if (IsFastDoubleElementsKind(elements_kind)) {
- return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key, mode);
+ return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key,
+ load_dependency, mode);
} else { // Smi or Object elements.
return new(zone()) HLoadKeyedFastElement(elements, checked_key,
- elements_kind);
+ load_dependency, elements_kind);
}
}
@@ -5494,22 +6148,38 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
HValue* dependency,
Handle<Map> map,
bool is_store) {
- HInstruction* mapcheck =
- AddInstruction(new(zone()) HCheckMaps(object, map, zone(), dependency));
+ HCheckMaps* mapcheck = new(zone()) HCheckMaps(object, map,
+ zone(), dependency);
+ AddInstruction(mapcheck);
+ if (dependency) {
+ mapcheck->ClearGVNFlag(kDependsOnElementsKind);
+ }
+ return BuildUncheckedMonomorphicElementAccess(object, key, val,
+ mapcheck, map, is_store);
+}
+
+
+HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
+ HValue* object,
+ HValue* key,
+ HValue* val,
+ HCheckMaps* mapcheck,
+ Handle<Map> map,
+ bool is_store) {
// No GVNFlag is necessary for ElementsKind if there is an explicit dependency
// on a HElementsTransition instruction. The flag can also be removed if the
// map to check has FAST_HOLEY_ELEMENTS, since there can be no further
// ElementsKind transitions. Finally, the dependency can be removed for stores
// for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
// generated store code.
- if (dependency ||
- (map->elements_kind() == FAST_HOLEY_ELEMENTS) ||
+ if ((map->elements_kind() == FAST_HOLEY_ELEMENTS) ||
(map->elements_kind() == FAST_ELEMENTS && is_store)) {
mapcheck->ClearGVNFlag(kDependsOnElementsKind);
}
bool fast_smi_only_elements = map->has_fast_smi_elements();
bool fast_elements = map->has_fast_object_elements();
- HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
+ HInstruction* elements =
+ AddInstruction(new(zone()) HLoadElements(object, mapcheck));
if (is_store && (fast_elements || fast_smi_only_elements)) {
HCheckMaps* check_cow_map = new(zone()) HCheckMaps(
elements, isolate()->factory()->fixed_array_map(), zone());
@@ -5520,12 +6190,14 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
HInstruction* checked_key = NULL;
if (map->has_external_array_elements()) {
length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
- checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
+ checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length,
+ ALLOW_SMI_KEY));
HLoadExternalArrayPointer* external_elements =
new(zone()) HLoadExternalArrayPointer(elements);
AddInstruction(external_elements);
- return BuildExternalArrayElementAccess(external_elements, checked_key,
- val, map->elements_kind(), is_store);
+ return BuildExternalArrayElementAccess(
+ external_elements, checked_key, val, mapcheck,
+ map->elements_kind(), is_store);
}
ASSERT(fast_smi_only_elements ||
fast_elements ||
@@ -5536,17 +6208,71 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
} else {
length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
}
- checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
- return BuildFastElementAccess(elements, checked_key, val,
+ checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length,
+ ALLOW_SMI_KEY));
+ return BuildFastElementAccess(elements, checked_key, val, mapcheck,
map->elements_kind(), is_store);
}
+HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad(
+ HValue* object,
+ HValue* key,
+ HValue* val,
+ SmallMapList* maps) {
+ // For polymorphic loads of similar elements kinds (i.e. all tagged or all
+ // double), always use the "worst case" code without a transition. This is
+ // much faster than transitioning the elements to the worst case, trading a
+ // HTransitionElements for a HCheckMaps, and avoiding mutation of the array.
+ bool has_double_maps = false;
+ bool has_smi_or_object_maps = false;
+ bool has_js_array_access = false;
+ bool has_non_js_array_access = false;
+ Handle<Map> most_general_consolidated_map;
+ for (int i = 0; i < maps->length(); ++i) {
+ Handle<Map> map = maps->at(i);
+ // Don't allow mixing of JSArrays with JSObjects.
+ if (map->instance_type() == JS_ARRAY_TYPE) {
+ if (has_non_js_array_access) return NULL;
+ has_js_array_access = true;
+ } else if (has_js_array_access) {
+ return NULL;
+ } else {
+ has_non_js_array_access = true;
+ }
+ // Don't allow mixed, incompatible elements kinds.
+ if (map->has_fast_double_elements()) {
+ if (has_smi_or_object_maps) return NULL;
+ has_double_maps = true;
+ } else if (map->has_fast_smi_or_object_elements()) {
+ if (has_double_maps) return NULL;
+ has_smi_or_object_maps = true;
+ } else {
+ return NULL;
+ }
+ // Remember the most general elements kind, the code for its load will
+ // properly handle all of the more specific cases.
+ if ((i == 0) || IsMoreGeneralElementsKindTransition(
+ most_general_consolidated_map->elements_kind(),
+ map->elements_kind())) {
+ most_general_consolidated_map = map;
+ }
+ }
+ if (!has_double_maps && !has_smi_or_object_maps) return NULL;
+
+ HCheckMaps* check_maps = new(zone()) HCheckMaps(object, maps, zone());
+ AddInstruction(check_maps);
+ HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
+ object, key, val, check_maps, most_general_consolidated_map, false);
+ return instr;
+}
+
+
HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
HValue* key,
HValue* val,
Expression* prop,
- int ast_id,
+ BailoutId ast_id,
int position,
bool is_store,
bool* has_side_effects) {
@@ -5555,6 +6281,19 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
SmallMapList* maps = prop->GetReceiverTypes();
bool todo_external_array = false;
+ if (!is_store) {
+ HInstruction* consolidated_load =
+ TryBuildConsolidatedElementLoad(object, key, val, maps);
+ if (consolidated_load != NULL) {
+ AddInstruction(consolidated_load);
+ *has_side_effects |= consolidated_load->HasObservableSideEffects();
+ if (position != RelocInfo::kNoPosition) {
+ consolidated_load->set_position(position);
+ }
+ return consolidated_load;
+ }
+ }
+
static const int kNumElementTypes = kElementsKindCount;
bool type_todo[kNumElementTypes];
for (int i = 0; i < kNumElementTypes; ++i) {
@@ -5616,17 +6355,19 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
object, key, val, transition, untransitionable_map, is_store));
}
*has_side_effects |= instr->HasObservableSideEffects();
- instr->set_position(position);
+ if (position != RelocInfo::kNoPosition) instr->set_position(position);
return is_store ? NULL : instr;
}
- AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone()));
+ HInstruction* checkspec =
+ AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone()));
HBasicBlock* join = graph()->CreateBasicBlock();
HInstruction* elements_kind_instr =
AddInstruction(new(zone()) HElementsKind(object));
HCompareConstantEqAndBranch* elements_kind_branch = NULL;
- HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
+ HInstruction* elements =
+ AddInstruction(new(zone()) HLoadElements(object, checkspec));
HLoadExternalArrayPointer* external_elements = NULL;
HInstruction* checked_key = NULL;
@@ -5689,9 +6430,11 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
HInstruction* length;
length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck,
HType::Smi()));
- checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
+ checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length,
+ ALLOW_SMI_KEY));
access = AddInstruction(BuildFastElementAccess(
- elements, checked_key, val, elements_kind, is_store));
+ elements, checked_key, val, elements_kind_branch,
+ elements_kind, is_store));
if (!is_store) {
Push(access);
}
@@ -5704,9 +6447,11 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
set_current_block(if_fastobject);
length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
- checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
+ checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length,
+ ALLOW_SMI_KEY));
access = AddInstruction(BuildFastElementAccess(
- elements, checked_key, val, elements_kind, is_store));
+ elements, checked_key, val, elements_kind_branch,
+ elements_kind, is_store));
} else if (elements_kind == DICTIONARY_ELEMENTS) {
if (is_store) {
access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
@@ -5715,10 +6460,11 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
}
} else { // External array elements.
access = AddInstruction(BuildExternalArrayElementAccess(
- external_elements, checked_key, val, elements_kind, is_store));
+ external_elements, checked_key, val, elements_kind_branch,
+ elements_kind, is_store));
}
*has_side_effects |= access->HasObservableSideEffects();
- access->set_position(position);
+ if (position != RelocInfo::kNoPosition) access->set_position(position);
if (!is_store) {
Push(access);
}
@@ -5739,7 +6485,7 @@ HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj,
HValue* key,
HValue* val,
Expression* expr,
- int ast_id,
+ BailoutId ast_id,
int position,
bool is_store,
bool* has_side_effects) {
@@ -5765,7 +6511,7 @@ HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj,
instr = BuildLoadKeyedGeneric(obj, key);
}
}
- instr->set_position(position);
+ if (position != RelocInfo::kNoPosition) instr->set_position(position);
AddInstruction(instr);
*has_side_effects = instr->HasObservableSideEffects();
return instr;
@@ -5793,6 +6539,7 @@ void HGraphBuilder::EnsureArgumentsArePushedForAccess() {
// Push arguments when entering inlined function.
HEnterInlined* entry = function_state()->entry();
+ entry->set_arguments_pushed();
ZoneList<HValue*>* arguments_values = entry->arguments_values();
@@ -5912,15 +6659,27 @@ void HGraphBuilder::VisitProperty(Property* expr) {
Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
SmallMapList* types = expr->GetReceiverTypes();
- HValue* obj = Pop();
+ bool monomorphic = expr->IsMonomorphic();
+ Handle<Map> map;
if (expr->IsMonomorphic()) {
- instr = BuildLoadNamed(obj, expr, types->first(), name);
+ map = types->first();
+ if (map->is_dictionary_map()) monomorphic = false;
+ }
+ if (monomorphic) {
+ Handle<JSFunction> getter;
+ Handle<JSObject> holder;
+ if (LookupGetter(map, name, &getter, &holder)) {
+ AddCheckConstantFunction(holder, Top(), map, true);
+ if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return;
+ AddInstruction(new(zone()) HPushArgument(Pop()));
+ instr = new(zone()) HCallConstantFunction(getter, 1);
+ } else {
+ instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map);
+ }
} else if (types != NULL && types->length() > 1) {
- AddInstruction(new(zone()) HCheckNonSmi(obj));
- HandlePolymorphicLoadNamedField(expr, obj, types, name);
- return;
+ return HandlePolymorphicLoadNamedField(expr, Pop(), types, name);
} else {
- instr = BuildLoadNamedGeneric(obj, expr);
+ instr = BuildLoadNamedGeneric(Pop(), name, expr);
}
} else {
@@ -5950,7 +6709,7 @@ void HGraphBuilder::VisitProperty(Property* expr) {
}
-void HGraphBuilder::AddCheckConstantFunction(Call* expr,
+void HGraphBuilder::AddCheckConstantFunction(Handle<JSObject> holder,
HValue* receiver,
Handle<Map> receiver_map,
bool smi_and_map_check) {
@@ -5962,10 +6721,9 @@ void HGraphBuilder::AddCheckConstantFunction(Call* expr,
AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map,
zone()));
}
- if (!expr->holder().is_null()) {
+ if (!holder.is_null()) {
AddInstruction(new(zone()) HCheckPrototypeMaps(
- Handle<JSObject>(JSObject::cast(receiver_map->prototype())),
- expr->holder()));
+ Handle<JSObject>(JSObject::cast(receiver_map->prototype())), holder));
}
}
@@ -6048,7 +6806,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
set_current_block(if_true);
expr->ComputeTarget(map, name);
- AddCheckConstantFunction(expr, receiver, map, false);
+ AddCheckConstantFunction(expr->holder(), receiver, map, false);
if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
Handle<JSFunction> caller = info()->closure();
SmartArrayPointer<char> caller_name =
@@ -6162,11 +6920,11 @@ int HGraphBuilder::InliningAstSize(Handle<JSFunction> target) {
bool HGraphBuilder::TryInline(CallKind call_kind,
Handle<JSFunction> target,
- ZoneList<Expression*>* arguments,
- HValue* receiver,
- int ast_id,
- int return_id,
- ReturnHandlingFlag return_handling) {
+ int arguments_count,
+ HValue* implicit_return_value,
+ BailoutId ast_id,
+ BailoutId return_id,
+ InliningKind inlining_kind) {
int nodes_added = InliningAstSize(target);
if (nodes_added == kNotInlinable) return false;
@@ -6223,13 +6981,13 @@ bool HGraphBuilder::TryInline(CallKind call_kind,
}
// Parse and allocate variables.
- CompilationInfo target_info(target);
+ CompilationInfo target_info(target, zone());
if (!ParserApi::Parse(&target_info, kNoParsingFlags) ||
!Scope::Analyze(&target_info)) {
if (target_info.isolate()->has_pending_exception()) {
// Parse or scope error, never optimize this function.
SetStackOverflow();
- target_shared->DisableOptimization();
+ target_shared->DisableOptimization("parse/scope error");
}
TraceInline(target, caller, "parse failure");
return false;
@@ -6311,24 +7069,25 @@ bool HGraphBuilder::TryInline(CallKind call_kind,
// Save the pending call context and type feedback oracle. Set up new ones
// for the inlined function.
ASSERT(target_shared->has_deoptimization_support());
+ Handle<Code> unoptimized_code(target_shared->code());
TypeFeedbackOracle target_oracle(
- Handle<Code>(target_shared->code()),
- Handle<Context>(target->context()->global_context()),
+ unoptimized_code,
+ Handle<Context>(target->context()->native_context()),
isolate(),
zone());
// The function state is new-allocated because we need to delete it
// in two different places.
FunctionState* target_state = new FunctionState(
- this, &target_info, &target_oracle, return_handling);
+ this, &target_info, &target_oracle, inlining_kind);
HConstant* undefined = graph()->GetConstantUndefined();
HEnvironment* inner_env =
environment()->CopyForInlining(target,
- arguments->length(),
+ arguments_count,
function,
undefined,
call_kind,
- function_state()->is_construct());
+ function_state()->inlining_kind());
#ifdef V8_TARGET_ARCH_IA32
// IA32 only, overwrite the caller's context in the deoptimization
// environment with the correct one.
@@ -6360,10 +7119,10 @@ bool HGraphBuilder::TryInline(CallKind call_kind,
HEnterInlined* enter_inlined =
new(zone()) HEnterInlined(target,
- arguments->length(),
+ arguments_count,
function,
call_kind,
- function_state()->is_construct(),
+ function_state()->inlining_kind(),
function->scope()->arguments(),
arguments_values);
function_state()->set_entry(enter_inlined);
@@ -6383,7 +7142,7 @@ bool HGraphBuilder::TryInline(CallKind call_kind,
// Bail out if the inline function did, as we cannot residualize a call
// instead.
TraceInline(target, caller, "inline graph construction failed");
- target_shared->DisableOptimization();
+ target_shared->DisableOptimization("inlining bailed out");
inline_bailout_ = true;
delete target_state;
return true;
@@ -6392,30 +7151,51 @@ bool HGraphBuilder::TryInline(CallKind call_kind,
// Update inlined nodes count.
inlined_count_ += nodes_added;
+ ASSERT(unoptimized_code->kind() == Code::FUNCTION);
+ Handle<Object> maybe_type_info(unoptimized_code->type_feedback_info());
+ Handle<TypeFeedbackInfo> type_info(
+ Handle<TypeFeedbackInfo>::cast(maybe_type_info));
+ graph()->update_type_change_checksum(type_info->own_type_change_checksum());
+
TraceInline(target, caller, NULL);
if (current_block() != NULL) {
- // Add default return value (i.e. undefined for normals calls or the newly
- // allocated receiver for construct calls) if control can fall off the
- // body. In a test context, undefined is false and any JSObject is true.
- if (call_context()->IsValue()) {
- ASSERT(function_return() != NULL);
- HValue* return_value = function_state()->is_construct()
- ? receiver
- : undefined;
- current_block()->AddLeaveInlined(return_value,
- function_return(),
- function_state());
- } else if (call_context()->IsEffect()) {
- ASSERT(function_return() != NULL);
- current_block()->Goto(function_return(), function_state());
+ FunctionState* state = function_state();
+ if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
+ // Falling off the end of an inlined construct call. In a test context the
+ // return value will always evaluate to true, in a value context the
+ // return value is the newly allocated receiver.
+ if (call_context()->IsTest()) {
+ current_block()->Goto(inlined_test_context()->if_true(), state);
+ } else if (call_context()->IsEffect()) {
+ current_block()->Goto(function_return(), state);
+ } else {
+ ASSERT(call_context()->IsValue());
+ current_block()->AddLeaveInlined(implicit_return_value, state);
+ }
+ } else if (state->inlining_kind() == SETTER_CALL_RETURN) {
+ // Falling off the end of an inlined setter call. The returned value is
+ // never used, the value of an assignment is always the value of the RHS
+ // of the assignment.
+ if (call_context()->IsTest()) {
+ inlined_test_context()->ReturnValue(implicit_return_value);
+ } else if (call_context()->IsEffect()) {
+ current_block()->Goto(function_return(), state);
+ } else {
+ ASSERT(call_context()->IsValue());
+ current_block()->AddLeaveInlined(implicit_return_value, state);
+ }
} else {
- ASSERT(call_context()->IsTest());
- ASSERT(inlined_test_context() != NULL);
- HBasicBlock* target = function_state()->is_construct()
- ? inlined_test_context()->if_true()
- : inlined_test_context()->if_false();
- current_block()->Goto(target, function_state());
+ // Falling off the end of a normal inlined function. This basically means
+ // returning undefined.
+ if (call_context()->IsTest()) {
+ current_block()->Goto(inlined_test_context()->if_false(), state);
+ } else if (call_context()->IsEffect()) {
+ current_block()->Goto(function_return(), state);
+ } else {
+ ASSERT(call_context()->IsValue());
+ current_block()->AddLeaveInlined(undefined, state);
+ }
}
}
@@ -6463,7 +7243,7 @@ bool HGraphBuilder::TryInlineCall(Call* expr, bool drop_extra) {
return TryInline(call_kind,
expr->target(),
- expr->arguments(),
+ expr->arguments()->length(),
NULL,
expr->id(),
expr->ReturnId(),
@@ -6471,17 +7251,43 @@ bool HGraphBuilder::TryInlineCall(Call* expr, bool drop_extra) {
}
-bool HGraphBuilder::TryInlineConstruct(CallNew* expr, HValue* receiver) {
+bool HGraphBuilder::TryInlineConstruct(CallNew* expr,
+ HValue* implicit_return_value) {
return TryInline(CALL_AS_FUNCTION,
expr->target(),
- expr->arguments(),
- receiver,
+ expr->arguments()->length(),
+ implicit_return_value,
expr->id(),
expr->ReturnId(),
CONSTRUCT_CALL_RETURN);
}
+bool HGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
+ Property* prop) {
+ return TryInline(CALL_AS_METHOD,
+ getter,
+ 0,
+ NULL,
+ prop->id(),
+ prop->LoadId(),
+ GETTER_CALL_RETURN);
+}
+
+
+bool HGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
+ Assignment* assignment,
+ HValue* implicit_return_value) {
+ return TryInline(CALL_AS_METHOD,
+ setter,
+ 1,
+ implicit_return_value,
+ assignment->id(),
+ assignment->AssignmentId(),
+ SETTER_CALL_RETURN);
+}
+
+
bool HGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra) {
if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
@@ -6555,7 +7361,7 @@ bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
case kMathCos:
case kMathTan:
if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
- AddCheckConstantFunction(expr, receiver, receiver_map, true);
+ AddCheckConstantFunction(expr->holder(), receiver, receiver_map, true);
HValue* argument = Pop();
HValue* context = environment()->LookupContext();
Drop(1); // Receiver.
@@ -6568,7 +7374,7 @@ bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
break;
case kMathPow:
if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
- AddCheckConstantFunction(expr, receiver, receiver_map, true);
+ AddCheckConstantFunction(expr->holder(), receiver, receiver_map, true);
HValue* right = Pop();
HValue* left = Pop();
Pop(); // Pop receiver.
@@ -6610,7 +7416,7 @@ bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
break;
case kMathRandom:
if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
- AddCheckConstantFunction(expr, receiver, receiver_map, true);
+ AddCheckConstantFunction(expr->holder(), receiver, receiver_map, true);
Drop(1); // Receiver.
HValue* context = environment()->LookupContext();
HGlobalObject* global_object = new(zone()) HGlobalObject(context);
@@ -6623,82 +7429,15 @@ bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
case kMathMax:
case kMathMin:
if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
- AddCheckConstantFunction(expr, receiver, receiver_map, true);
+ AddCheckConstantFunction(expr->holder(), receiver, receiver_map, true);
HValue* right = Pop();
HValue* left = Pop();
- Pop(); // Pop receiver.
-
- HValue* left_operand = left;
- HValue* right_operand = right;
-
- // If we do not have two integers, we convert to double for comparison.
- if (!left->representation().IsInteger32() ||
- !right->representation().IsInteger32()) {
- if (!left->representation().IsDouble()) {
- HChange* left_convert = new(zone()) HChange(
- left,
- Representation::Double(),
- false, // Do not truncate when converting to double.
- true); // Deoptimize for undefined.
- left_convert->SetFlag(HValue::kBailoutOnMinusZero);
- left_operand = AddInstruction(left_convert);
- }
- if (!right->representation().IsDouble()) {
- HChange* right_convert = new(zone()) HChange(
- right,
- Representation::Double(),
- false, // Do not truncate when converting to double.
- true); // Deoptimize for undefined.
- right_convert->SetFlag(HValue::kBailoutOnMinusZero);
- right_operand = AddInstruction(right_convert);
- }
- }
-
- ASSERT(left_operand->representation().Equals(
- right_operand->representation()));
- ASSERT(!left_operand->representation().IsTagged());
-
- Token::Value op = (id == kMathMin) ? Token::LT : Token::GT;
-
- HCompareIDAndBranch* compare =
- new(zone()) HCompareIDAndBranch(left_operand, right_operand, op);
- compare->SetInputRepresentation(left_operand->representation());
-
- HBasicBlock* return_left = graph()->CreateBasicBlock();
- HBasicBlock* return_right = graph()->CreateBasicBlock();
-
- compare->SetSuccessorAt(0, return_left);
- compare->SetSuccessorAt(1, return_right);
- current_block()->Finish(compare);
-
- set_current_block(return_left);
- Push(left);
- set_current_block(return_right);
- // The branch above always returns the right operand if either of
- // them is NaN, but the spec requires that max/min(NaN, X) = NaN.
- // We add another branch that checks if the left operand is NaN or not.
- if (left_operand->representation().IsDouble()) {
- // If left_operand != left_operand then it is NaN.
- HCompareIDAndBranch* compare_nan = new(zone()) HCompareIDAndBranch(
- left_operand, left_operand, Token::EQ);
- compare_nan->SetInputRepresentation(left_operand->representation());
- HBasicBlock* left_is_number = graph()->CreateBasicBlock();
- HBasicBlock* left_is_nan = graph()->CreateBasicBlock();
- compare_nan->SetSuccessorAt(0, left_is_number);
- compare_nan->SetSuccessorAt(1, left_is_nan);
- current_block()->Finish(compare_nan);
- set_current_block(left_is_nan);
- Push(left);
- set_current_block(left_is_number);
- Push(right);
- return_right = CreateJoin(left_is_number, left_is_nan, expr->id());
- } else {
- Push(right);
- }
-
- HBasicBlock* join = CreateJoin(return_left, return_right, expr->id());
- set_current_block(join);
- ast_context()->ReturnValue(Pop());
+ Drop(1); // Receiver.
+ HValue* context = environment()->LookupContext();
+ HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin
+ : HMathMinMax::kMathMax;
+ HMathMinMax* result = new(zone()) HMathMinMax(context, left, right, op);
+ ast_context()->ReturnInstruction(result, expr->id());
return true;
}
break;
@@ -6739,7 +7478,7 @@ bool HGraphBuilder::TryCallApply(Call* expr) {
VisitForValue(prop->obj());
if (HasStackOverflow() || current_block() == NULL) return true;
HValue* function = Top();
- AddCheckConstantFunction(expr, function, function_map, true);
+ AddCheckConstantFunction(expr->holder(), function, function_map, true);
Drop(1);
VisitForValue(args->at(0));
@@ -6858,7 +7597,7 @@ void HGraphBuilder::VisitCall(Call* expr) {
call = PreProcessCall(
new(zone()) HCallNamed(context, name, argument_count));
} else {
- AddCheckConstantFunction(expr, receiver, receiver_map, true);
+ AddCheckConstantFunction(expr->holder(), receiver, receiver_map, true);
if (TryInlineCall(expr)) return;
call = PreProcessCall(
@@ -7059,8 +7798,8 @@ void HGraphBuilder::VisitCallNew(CallNew* expr) {
} else {
// The constructor function is both an operand to the instruction and an
// argument to the construct call.
- HValue* constructor = NULL;
- CHECK_ALIVE(constructor = VisitArgument(expr->expression()));
+ CHECK_ALIVE(VisitArgument(expr->expression()));
+ HValue* constructor = HPushArgument::cast(Top())->argument();
CHECK_ALIVE(VisitArgumentList(expr->arguments()));
HInstruction* call =
new(zone()) HCallNew(context, constructor, argument_count);
@@ -7118,7 +7857,6 @@ void HGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
int argument_count = expr->arguments()->length();
HCallRuntime* call =
new(zone()) HCallRuntime(context, name, function, argument_count);
- call->set_position(RelocInfo::kNoPosition);
Drop(argument_count);
return ast_context()->ReturnInstruction(call, expr->id());
}
@@ -7373,8 +8111,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
}
HValue* context = BuildContextChainWalk(var);
- HStoreContextSlot::Mode mode =
- (var->mode() == LET || var->mode() == CONST_HARMONY)
+ HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode())
? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck;
HStoreContextSlot* instr =
new(zone()) HStoreContextSlot(context, var->index(), mode, after);
@@ -7399,24 +8136,49 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
if (returns_original_input) Push(graph_->GetConstantUndefined());
CHECK_ALIVE(VisitForValue(prop->obj()));
- HValue* obj = Top();
-
- HInstruction* load = NULL;
- if (prop->IsMonomorphic()) {
- Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
- Handle<Map> map = prop->GetReceiverTypes()->first();
- load = BuildLoadNamed(obj, prop, map, name);
+ HValue* object = Top();
+
+ Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
+ Handle<Map> map;
+ HInstruction* load;
+ bool monomorphic = prop->IsMonomorphic();
+ if (monomorphic) {
+ map = prop->GetReceiverTypes()->first();
+ if (map->is_dictionary_map()) monomorphic = false;
+ }
+ if (monomorphic) {
+ Handle<JSFunction> getter;
+ Handle<JSObject> holder;
+ if (LookupGetter(map, name, &getter, &holder)) {
+ load = BuildCallGetter(object, map, getter, holder);
+ } else {
+ load = BuildLoadNamedMonomorphic(object, name, prop, map);
+ }
} else {
- load = BuildLoadNamedGeneric(obj, prop);
+ load = BuildLoadNamedGeneric(object, name, prop);
}
PushAndAdd(load);
- if (load->HasObservableSideEffects()) AddSimulate(expr->CountId());
+ if (load->HasObservableSideEffects()) AddSimulate(prop->LoadId());
after = BuildIncrement(returns_original_input, expr);
input = Pop();
HInstruction* store;
- CHECK_ALIVE(store = BuildStoreNamed(obj, after, prop));
+ if (!monomorphic) {
+ // If we don't know the monomorphic type, do a generic store.
+ CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after));
+ } else {
+ Handle<JSFunction> setter;
+ Handle<JSObject> holder;
+ if (LookupSetter(map, name, &setter, &holder)) {
+ store = BuildCallSetter(object, after, map, setter, holder);
+ } else {
+ CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
+ name,
+ after,
+ map));
+ }
+ }
AddInstruction(store);
// Overwrite the receiver in the bailout environment with the result
@@ -7437,11 +8199,11 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
bool has_side_effects = false;
HValue* load = HandleKeyedElementAccess(
- obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition,
+ obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
false, // is_store
&has_side_effects);
Push(load);
- if (has_side_effects) AddSimulate(expr->CountId());
+ if (has_side_effects) AddSimulate(prop->LoadId());
after = BuildIncrement(returns_original_input, expr);
input = Pop();
@@ -7526,6 +8288,18 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
break;
case Token::SHR:
instr = HShr::NewHShr(zone(), context, left, right);
+ if (FLAG_opt_safe_uint32_operations && instr->IsShr()) {
+ bool can_be_shift_by_zero = true;
+ if (right->IsConstant()) {
+ HConstant* right_const = HConstant::cast(right);
+ if (right_const->HasInteger32Value() &&
+ (right_const->Integer32Value() & 0x1f) != 0) {
+ can_be_shift_by_zero = false;
+ }
+ }
+
+ if (can_be_shift_by_zero) graph()->RecordUint32Instruction(instr);
+ }
break;
case Token::SHL:
instr = HShl::NewHShl(zone(), context, left, right);
@@ -7538,8 +8312,8 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
// for a smi operation. If one of the operands is a constant string
// do not generate code assuming it is a smi operation.
if (info.IsSmi() &&
- ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) ||
- (right->IsConstant() && HConstant::cast(right)->HasStringValue()))) {
+ ((left->IsConstant() && HConstant::cast(left)->handle()->IsString()) ||
+ (right->IsConstant() && HConstant::cast(right)->handle()->IsString()))) {
return instr;
}
Representation rep = ToRepresentation(info);
@@ -7624,7 +8398,7 @@ void HGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
// We need an extra block to maintain edge-split form.
HBasicBlock* empty_block = graph()->CreateBasicBlock();
HBasicBlock* eval_right = graph()->CreateBasicBlock();
- unsigned test_id = expr->left()->test_id();
+ TypeFeedbackId test_id = expr->left()->test_id();
ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id));
HBranch* test = is_logical_and
? new(zone()) HBranch(Top(), eval_right, empty_block, expected)
@@ -7757,7 +8531,7 @@ static bool MatchLiteralCompareTypeof(HValue* left,
if (left->IsTypeof() &&
Token::IsEqualityOp(op) &&
right->IsConstant() &&
- HConstant::cast(right)->HasStringValue()) {
+ HConstant::cast(right)->handle()->IsString()) {
*typeof_expr = HTypeof::cast(left);
*check = Handle<String>::cast(HConstant::cast(right)->handle());
return true;
@@ -7863,9 +8637,7 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
Handle<GlobalObject> global(info()->global_object());
LookupResult lookup(isolate());
global->Lookup(*name, &lookup);
- if (lookup.IsFound() &&
- lookup.type() == NORMAL &&
- lookup.GetValue()->IsJSFunction()) {
+ if (lookup.IsNormal() && lookup.GetValue()->IsJSFunction()) {
Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue()));
// If the function is in new space we assume it's more likely to
// change and thus prefer the general IC code.
@@ -7963,13 +8735,25 @@ void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
}
+HInstruction* HGraphBuilder::BuildThisFunction() {
+ // If we share optimized code between different closures, the
+ // this-function is not a constant, except inside an inlined body.
+ if (function_state()->outer() != NULL) {
+ return new(zone()) HConstant(
+ function_state()->compilation_info()->closure(),
+ Representation::Tagged());
+ } else {
+ return new(zone()) HThisFunction;
+ }
+}
+
+
void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
- HThisFunction* self = new(zone()) HThisFunction(
- function_state()->compilation_info()->closure());
- return ast_context()->ReturnInstruction(self, expr->id());
+ HInstruction* instr = BuildThisFunction();
+ return ast_context()->ReturnInstruction(instr, expr->id());
}
@@ -8196,7 +8980,7 @@ void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
ASSERT(call->arguments()->length() == 0);
if (function_state()->outer() != NULL) {
// We are generating graph for inlined function.
- HValue* value = function_state()->is_construct()
+ HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN
? graph()->GetConstantTrue()
: graph()->GetConstantFalse();
return ast_context()->ReturnValue(value);
@@ -8232,8 +9016,10 @@ void HGraphBuilder::GenerateArguments(CallRuntime* call) {
HInstruction* elements = AddInstruction(
new(zone()) HArgumentsElements(false));
HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
+ HInstruction* checked_index =
+ AddInstruction(new(zone()) HBoundsCheck(index, length));
HAccessArgumentsAt* result =
- new(zone()) HAccessArgumentsAt(elements, length, index);
+ new(zone()) HAccessArgumentsAt(elements, length, checked_index);
return ast_context()->ReturnInstruction(result, call->id());
}
@@ -8598,9 +9384,10 @@ HEnvironment::HEnvironment(HEnvironment* outer,
specials_count_(1),
local_count_(0),
outer_(outer),
+ entry_(NULL),
pop_count_(0),
push_count_(0),
- ast_id_(AstNode::kNoNumber),
+ ast_id_(BailoutId::None()),
zone_(zone) {
Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0);
}
@@ -8614,6 +9401,7 @@ HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone)
specials_count_(1),
local_count_(0),
outer_(NULL),
+ entry_(NULL),
pop_count_(0),
push_count_(0),
ast_id_(other->ast_id()),
@@ -8634,9 +9422,10 @@ HEnvironment::HEnvironment(HEnvironment* outer,
parameter_count_(arguments),
local_count_(0),
outer_(outer),
+ entry_(NULL),
pop_count_(0),
push_count_(0),
- ast_id_(AstNode::kNoNumber),
+ ast_id_(BailoutId::None()),
zone_(zone) {
}
@@ -8662,6 +9451,7 @@ void HEnvironment::Initialize(const HEnvironment* other) {
parameter_count_ = other->parameter_count_;
local_count_ = other->local_count_;
if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy.
+ entry_ = other->entry_;
pop_count_ = other->pop_count_;
push_count_ = other->push_count_;
ast_id_ = other->ast_id_;
@@ -8786,11 +9576,9 @@ HEnvironment* HEnvironment::CopyForInlining(
FunctionLiteral* function,
HConstant* undefined,
CallKind call_kind,
- bool is_construct) const {
+ InliningKind inlining_kind) const {
ASSERT(frame_type() == JS_FUNCTION);
- Zone* zone = closure()->GetIsolate()->zone();
-
// Outer environment is a copy of this one without the arguments.
int arity = function->scope()->num_parameters();
@@ -8798,11 +9586,19 @@ HEnvironment* HEnvironment::CopyForInlining(
outer->Drop(arguments + 1); // Including receiver.
outer->ClearHistory();
- if (is_construct) {
+ if (inlining_kind == CONSTRUCT_CALL_RETURN) {
// Create artificial constructor stub environment. The receiver should
// actually be the constructor function, but we pass the newly allocated
// object instead, DoComputeConstructStubFrame() relies on that.
outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments);
+ } else if (inlining_kind == GETTER_CALL_RETURN) {
+ // We need an additional StackFrame::INTERNAL frame for restoring the
+ // correct context.
+ outer = CreateStubEnvironment(outer, target, JS_GETTER, arguments);
+ } else if (inlining_kind == SETTER_CALL_RETURN) {
+ // We need an additional StackFrame::INTERNAL frame for temporarily saving
+ // the argument of the setter, see StoreStubCompiler::CompileStoreViaSetter.
+ outer = CreateStubEnvironment(outer, target, JS_SETTER, arguments);
}
if (arity != arguments) {
@@ -8811,7 +9607,7 @@ HEnvironment* HEnvironment::CopyForInlining(
}
HEnvironment* inner =
- new(zone) HEnvironment(outer, function->scope(), target, zone);
+ new(zone()) HEnvironment(outer, function->scope(), target, zone());
// Get the argument values from the original environment.
for (int i = 0; i <= arity; ++i) { // Include receiver.
HValue* push = (i <= arguments) ?
@@ -8822,7 +9618,7 @@ HEnvironment* HEnvironment::CopyForInlining(
// builtin function, pass undefined as the receiver for function
// calls (instead of the global receiver).
if ((target->shared()->native() || !function->is_classic_mode()) &&
- call_kind == CALL_AS_FUNCTION && !is_construct) {
+ call_kind == CALL_AS_FUNCTION && inlining_kind != CONSTRUCT_CALL_RETURN) {
inner->SetValueAt(0, undefined);
}
inner->SetValueAt(arity + 1, LookupContext());
@@ -8830,7 +9626,7 @@ HEnvironment* HEnvironment::CopyForInlining(
inner->SetValueAt(i, undefined);
}
- inner->set_ast_id(AstNode::kFunctionEntryId);
+ inner->set_ast_id(BailoutId::FunctionEntry());
return inner;
}
diff --git a/deps/v8/src/hydrogen.h b/deps/v8/src/hydrogen.h
index 6fa3d1b9f..a0d81497f 100644
--- a/deps/v8/src/hydrogen.h
+++ b/deps/v8/src/hydrogen.h
@@ -118,14 +118,14 @@ class HBasicBlock: public ZoneObject {
bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; }
- void SetJoinId(int ast_id);
+ void SetJoinId(BailoutId ast_id);
void Finish(HControlInstruction* last);
void FinishExit(HControlInstruction* instruction);
void Goto(HBasicBlock* block, FunctionState* state = NULL);
int PredecessorIndexOf(HBasicBlock* predecessor) const;
- void AddSimulate(int ast_id) { AddInstruction(CreateSimulate(ast_id)); }
+ void AddSimulate(BailoutId ast_id) { AddInstruction(CreateSimulate(ast_id)); }
void AssignCommonDominator(HBasicBlock* other);
void AssignLoopSuccessorDominators();
@@ -135,9 +135,7 @@ class HBasicBlock: public ZoneObject {
// Add the inlined function exit sequence, adding an HLeaveInlined
// instruction and updating the bailout environment.
- void AddLeaveInlined(HValue* return_value,
- HBasicBlock* target,
- FunctionState* state = NULL);
+ void AddLeaveInlined(HValue* return_value, FunctionState* state);
// If a target block is tagged as an inline function return, all
// predecessors should contain the inlined exit sequence:
@@ -168,7 +166,7 @@ class HBasicBlock: public ZoneObject {
void RegisterPredecessor(HBasicBlock* pred);
void AddDominatedBlock(HBasicBlock* block);
- HSimulate* CreateSimulate(int ast_id);
+ HSimulate* CreateSimulate(BailoutId ast_id);
HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses);
int block_id_;
@@ -244,10 +242,11 @@ class HLoopInformation: public ZoneObject {
class BoundsCheckTable;
class HGraph: public ZoneObject {
public:
- HGraph(CompilationInfo* info, Zone* zone);
+ explicit HGraph(CompilationInfo* info);
Isolate* isolate() { return isolate_; }
Zone* zone() const { return zone_; }
+ CompilationInfo* info() const { return info_; }
const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
@@ -259,6 +258,7 @@ class HGraph: public ZoneObject {
void InsertRepresentationChanges();
void MarkDeoptimizeOnUndefined();
void ComputeMinusZeroChecks();
+ void ComputeSafeUint32Operations();
bool ProcessArgumentsObject();
void EliminateRedundantPhis();
void EliminateUnreachablePhis();
@@ -268,6 +268,7 @@ class HGraph: public ZoneObject {
void ReplaceCheckedValues();
void EliminateRedundantBoundsChecks();
void DehoistSimpleArrayIndexComputations();
+ void DeadCodeElimination();
void PropagateDeoptimizingMark();
// Returns false if there are phi-uses of the arguments-object
@@ -280,8 +281,6 @@ class HGraph: public ZoneObject {
void CollectPhis();
- Handle<Code> Compile(CompilationInfo* info, Zone* zone);
-
void set_undefined_constant(HConstant* constant) {
undefined_constant_.set(constant);
}
@@ -312,6 +311,8 @@ class HGraph: public ZoneObject {
return NULL;
}
+ bool Optimize(SmartArrayPointer<char>* bailout_reason);
+
#ifdef DEBUG
void Verify(bool do_full_verify) const;
#endif
@@ -336,6 +337,19 @@ class HGraph: public ZoneObject {
osr_values_.set(values);
}
+ int update_type_change_checksum(int delta) {
+ type_change_checksum_ += delta;
+ return type_change_checksum_;
+ }
+
+ bool use_optimistic_licm() {
+ return use_optimistic_licm_;
+ }
+
+ void set_use_optimistic_licm(bool value) {
+ use_optimistic_licm_ = value;
+ }
+
void MarkRecursive() {
is_recursive_ = true;
}
@@ -344,17 +358,18 @@ class HGraph: public ZoneObject {
return is_recursive_;
}
+ void RecordUint32Instruction(HInstruction* instr) {
+ if (uint32_instructions_ == NULL) {
+ uint32_instructions_ = new(zone()) ZoneList<HInstruction*>(4, zone());
+ }
+ uint32_instructions_->Add(instr, zone());
+ }
+
private:
- void Postorder(HBasicBlock* block,
- BitVector* visited,
- ZoneList<HBasicBlock*>* order,
- HBasicBlock* loop_header);
- void PostorderLoopBlocks(HLoopInformation* loop,
- BitVector* visited,
- ZoneList<HBasicBlock*>* order,
- HBasicBlock* loop_header);
HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
- Object* value);
+ Handle<Object> value);
+ HConstant* GetConstantInt32(SetOncePointer<HConstant>* pointer,
+ int32_t integer_value);
void MarkAsDeoptimizingRecursively(HBasicBlock* block);
void InsertTypeConversions(HInstruction* instr);
@@ -377,6 +392,7 @@ class HGraph: public ZoneObject {
ZoneList<HBasicBlock*> blocks_;
ZoneList<HValue*> values_;
ZoneList<HPhi*>* phi_list_;
+ ZoneList<HInstruction*>* uint32_instructions_;
SetOncePointer<HConstant> undefined_constant_;
SetOncePointer<HConstant> constant_1_;
SetOncePointer<HConstant> constant_minus1_;
@@ -388,9 +404,12 @@ class HGraph: public ZoneObject {
SetOncePointer<HBasicBlock> osr_loop_entry_;
SetOncePointer<ZoneList<HUnknownOSRValue*> > osr_values_;
+ CompilationInfo* info_;
Zone* zone_;
bool is_recursive_;
+ bool use_optimistic_licm_;
+ int type_change_checksum_;
DISALLOW_COPY_AND_ASSIGN(HGraph);
};
@@ -400,7 +419,13 @@ Zone* HBasicBlock::zone() const { return graph_->zone(); }
// Type of stack frame an environment might refer to.
-enum FrameType { JS_FUNCTION, JS_CONSTRUCT, ARGUMENTS_ADAPTOR };
+enum FrameType {
+ JS_FUNCTION,
+ JS_CONSTRUCT,
+ JS_GETTER,
+ JS_SETTER,
+ ARGUMENTS_ADAPTOR
+};
class HEnvironment: public ZoneObject {
@@ -410,13 +435,6 @@ class HEnvironment: public ZoneObject {
Handle<JSFunction> closure,
Zone* zone);
- HEnvironment* DiscardInlined(bool drop_extra) {
- HEnvironment* outer = outer_;
- while (outer->frame_type() != JS_FUNCTION) outer = outer->outer_;
- if (drop_extra) outer->Drop(1);
- return outer;
- }
-
HEnvironment* arguments_environment() {
return outer()->frame_type() == ARGUMENTS_ADAPTOR ? outer() : this;
}
@@ -435,8 +453,11 @@ class HEnvironment: public ZoneObject {
int pop_count() const { return pop_count_; }
int push_count() const { return push_count_; }
- int ast_id() const { return ast_id_; }
- void set_ast_id(int id) { ast_id_ = id; }
+ BailoutId ast_id() const { return ast_id_; }
+ void set_ast_id(BailoutId id) { ast_id_ = id; }
+
+ HEnterInlined* entry() const { return entry_; }
+ void set_entry(HEnterInlined* entry) { entry_ = entry; }
int length() const { return values_.length(); }
bool is_special_index(int i) const {
@@ -514,7 +535,14 @@ class HEnvironment: public ZoneObject {
FunctionLiteral* function,
HConstant* undefined,
CallKind call_kind,
- bool is_construct) const;
+ InliningKind inlining_kind) const;
+
+ HEnvironment* DiscardInlined(bool drop_extra) {
+ HEnvironment* outer = outer_;
+ while (outer->frame_type() != JS_FUNCTION) outer = outer->outer_;
+ if (drop_extra) outer->Drop(1);
+ return outer;
+ }
void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
@@ -576,9 +604,10 @@ class HEnvironment: public ZoneObject {
int specials_count_;
int local_count_;
HEnvironment* outer_;
+ HEnterInlined* entry_;
int pop_count_;
int push_count_;
- int ast_id_;
+ BailoutId ast_id_;
Zone* zone_;
};
@@ -607,13 +636,13 @@ class AstContext {
// Add a hydrogen instruction to the instruction stream (recording an
// environment simulation if necessary) and then fill this context with
// the instruction as value.
- virtual void ReturnInstruction(HInstruction* instr, int ast_id) = 0;
+ virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id) = 0;
// Finishes the current basic block and materialize a boolean for
// value context, nothing for effect, generate a branch for test context.
// Call this function in tail position in the Visit functions for
// expressions.
- virtual void ReturnControl(HControlInstruction* instr, int ast_id) = 0;
+ virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id) = 0;
void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; }
bool is_for_typeof() { return for_typeof_; }
@@ -648,8 +677,8 @@ class EffectContext: public AstContext {
virtual ~EffectContext();
virtual void ReturnValue(HValue* value);
- virtual void ReturnInstruction(HInstruction* instr, int ast_id);
- virtual void ReturnControl(HControlInstruction* instr, int ast_id);
+ virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
+ virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
};
@@ -661,8 +690,8 @@ class ValueContext: public AstContext {
virtual ~ValueContext();
virtual void ReturnValue(HValue* value);
- virtual void ReturnInstruction(HInstruction* instr, int ast_id);
- virtual void ReturnControl(HControlInstruction* instr, int ast_id);
+ virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
+ virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; }
@@ -675,17 +704,19 @@ class TestContext: public AstContext {
public:
TestContext(HGraphBuilder* owner,
Expression* condition,
+ TypeFeedbackOracle* oracle,
HBasicBlock* if_true,
HBasicBlock* if_false)
: AstContext(owner, Expression::kTest),
condition_(condition),
+ oracle_(oracle),
if_true_(if_true),
if_false_(if_false) {
}
virtual void ReturnValue(HValue* value);
- virtual void ReturnInstruction(HInstruction* instr, int ast_id);
- virtual void ReturnControl(HControlInstruction* instr, int ast_id);
+ virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
+ virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
static TestContext* cast(AstContext* context) {
ASSERT(context->IsTest());
@@ -693,6 +724,7 @@ class TestContext: public AstContext {
}
Expression* condition() const { return condition_; }
+ TypeFeedbackOracle* oracle() const { return oracle_; }
HBasicBlock* if_true() const { return if_true_; }
HBasicBlock* if_false() const { return if_false_; }
@@ -702,31 +734,24 @@ class TestContext: public AstContext {
void BuildBranch(HValue* value);
Expression* condition_;
+ TypeFeedbackOracle* oracle_;
HBasicBlock* if_true_;
HBasicBlock* if_false_;
};
-enum ReturnHandlingFlag {
- NORMAL_RETURN,
- DROP_EXTRA_ON_RETURN,
- CONSTRUCT_CALL_RETURN
-};
-
-
class FunctionState {
public:
FunctionState(HGraphBuilder* owner,
CompilationInfo* info,
TypeFeedbackOracle* oracle,
- ReturnHandlingFlag return_handling);
+ InliningKind inlining_kind);
~FunctionState();
CompilationInfo* compilation_info() { return compilation_info_; }
TypeFeedbackOracle* oracle() { return oracle_; }
AstContext* call_context() { return call_context_; }
- bool drop_extra() { return return_handling_ == DROP_EXTRA_ON_RETURN; }
- bool is_construct() { return return_handling_ == CONSTRUCT_CALL_RETURN; }
+ InliningKind inlining_kind() const { return inlining_kind_; }
HBasicBlock* function_return() { return function_return_; }
TestContext* test_context() { return test_context_; }
void ClearInlinedTestContext() {
@@ -756,11 +781,8 @@ class FunctionState {
// inlined. NULL when not inlining.
AstContext* call_context_;
- // Indicate whether we have to perform special handling on return from
- // inlined functions.
- // - DROP_EXTRA_ON_RETURN: Drop an extra value from the environment.
- // - CONSTRUCT_CALL_RETURN: Either use allocated receiver or return value.
- ReturnHandlingFlag return_handling_;
+ // The kind of call which is currently being inlined.
+ InliningKind inlining_kind_;
// When inlining in an effect or value context, this is the return block.
// It is NULL otherwise. When inlining in a test context, there are a
@@ -838,7 +860,7 @@ class HGraphBuilder: public AstVisitor {
BreakAndContinueScope* next_;
};
- HGraphBuilder(CompilationInfo* info, TypeFeedbackOracle* oracle, Zone* zone);
+ HGraphBuilder(CompilationInfo* info, TypeFeedbackOracle* oracle);
HGraph* CreateGraph();
@@ -857,7 +879,7 @@ class HGraphBuilder: public AstVisitor {
// Adding instructions.
HInstruction* AddInstruction(HInstruction* instr);
- void AddSimulate(int ast_id);
+ void AddSimulate(BailoutId ast_id);
// Bailout environment manipulation.
void Push(HValue* value) { environment()->Push(value); }
@@ -867,7 +889,7 @@ class HGraphBuilder: public AstVisitor {
HBasicBlock* CreateJoin(HBasicBlock* first,
HBasicBlock* second,
- int join_id);
+ BailoutId join_id);
TypeFeedbackOracle* oracle() const { return function_state()->oracle(); }
@@ -875,6 +897,12 @@ class HGraphBuilder: public AstVisitor {
void VisitDeclarations(ZoneList<Declaration*>* declarations);
+ void* operator new(size_t size, Zone* zone) {
+ return zone->New(static_cast<int>(size));
+ }
+ void operator delete(void* pointer, Zone* zone) { }
+ void operator delete(void* pointer) { }
+
private:
// Type of a member function that generates inline code for a native function.
typedef void (HGraphBuilder::*InlineFunctionGenerator)(CallRuntime* call);
@@ -980,9 +1008,8 @@ class HGraphBuilder: public AstVisitor {
HBasicBlock* true_block,
HBasicBlock* false_block);
- // Visit an argument subexpression and emit a push to the outgoing
- // arguments. Returns the hydrogen value that was pushed.
- HValue* VisitArgument(Expression* expr);
+ // Visit an argument subexpression and emit a push to the outgoing arguments.
+ void VisitArgument(Expression* expr);
void VisitArgumentList(ZoneList<Expression*>* arguments);
@@ -1031,14 +1058,18 @@ class HGraphBuilder: public AstVisitor {
int InliningAstSize(Handle<JSFunction> target);
bool TryInline(CallKind call_kind,
Handle<JSFunction> target,
- ZoneList<Expression*>* arguments,
- HValue* receiver,
- int ast_id,
- int return_id,
- ReturnHandlingFlag return_handling);
+ int arguments_count,
+ HValue* implicit_return_value,
+ BailoutId ast_id,
+ BailoutId return_id,
+ InliningKind inlining_kind);
bool TryInlineCall(Call* expr, bool drop_extra = false);
- bool TryInlineConstruct(CallNew* expr, HValue* receiver);
+ bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
+ bool TryInlineGetter(Handle<JSFunction> getter, Property* prop);
+ bool TryInlineSetter(Handle<JSFunction> setter,
+ Assignment* assignment,
+ HValue* implicit_return_value);
bool TryInlineBuiltinMethodCall(Call* expr,
HValue* receiver,
Handle<Map> receiver_map,
@@ -1055,7 +1086,7 @@ class HGraphBuilder: public AstVisitor {
void HandleGlobalVariableAssignment(Variable* var,
HValue* value,
int position,
- int ast_id);
+ BailoutId ast_id);
void HandlePropertyAssignment(Assignment* expr);
void HandleCompoundAssignment(Assignment* expr);
@@ -1087,37 +1118,37 @@ class HGraphBuilder: public AstVisitor {
HValue* right);
HInstruction* BuildIncrement(bool returns_original_input,
CountOperation* expr);
- HLoadNamedField* BuildLoadNamedField(HValue* object,
- Property* expr,
- Handle<Map> type,
- LookupResult* result,
- bool smi_and_map_check);
- HInstruction* BuildLoadNamedGeneric(HValue* object, Property* expr);
- HInstruction* BuildLoadKeyedGeneric(HValue* object,
- HValue* key);
- HInstruction* BuildExternalArrayElementAccess(
- HValue* external_elements,
- HValue* checked_key,
- HValue* val,
- ElementsKind elements_kind,
- bool is_store);
HInstruction* BuildFastElementAccess(HValue* elements,
HValue* checked_key,
HValue* val,
+ HValue* dependency,
ElementsKind elements_kind,
bool is_store);
+ HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
+ HValue* key,
+ HValue* val,
+ SmallMapList* maps);
+
+ HInstruction* BuildUncheckedMonomorphicElementAccess(HValue* object,
+ HValue* key,
+ HValue* val,
+ HCheckMaps* mapcheck,
+ Handle<Map> map,
+ bool is_store);
+
HInstruction* BuildMonomorphicElementAccess(HValue* object,
HValue* key,
HValue* val,
HValue* dependency,
Handle<Map> map,
bool is_store);
+
HValue* HandlePolymorphicElementAccess(HValue* object,
HValue* key,
HValue* val,
Expression* prop,
- int ast_id,
+ BailoutId ast_id,
int position,
bool is_store,
bool* has_side_effects);
@@ -1126,37 +1157,62 @@ class HGraphBuilder: public AstVisitor {
HValue* key,
HValue* val,
Expression* expr,
- int ast_id,
+ BailoutId ast_id,
int position,
bool is_store,
bool* has_side_effects);
- HInstruction* BuildLoadNamed(HValue* object,
- Property* prop,
- Handle<Map> map,
- Handle<String> name);
- HInstruction* BuildStoreNamed(HValue* object,
- HValue* value,
- Expression* expr);
- HInstruction* BuildStoreNamed(HValue* object,
- HValue* value,
- ObjectLiteral::Property* prop);
+ HLoadNamedField* BuildLoadNamedField(HValue* object,
+ Handle<Map> map,
+ LookupResult* result,
+ bool smi_and_map_check);
+ HInstruction* BuildLoadNamedGeneric(HValue* object,
+ Handle<String> name,
+ Property* expr);
+ HInstruction* BuildCallGetter(HValue* object,
+ Handle<Map> map,
+ Handle<JSFunction> getter,
+ Handle<JSObject> holder);
+ HInstruction* BuildLoadNamedMonomorphic(HValue* object,
+ Handle<String> name,
+ Property* expr,
+ Handle<Map> map);
+ HInstruction* BuildLoadKeyedGeneric(HValue* object, HValue* key);
+ HInstruction* BuildExternalArrayElementAccess(
+ HValue* external_elements,
+ HValue* checked_key,
+ HValue* val,
+ HValue* dependency,
+ ElementsKind elements_kind,
+ bool is_store);
+
HInstruction* BuildStoreNamedField(HValue* object,
Handle<String> name,
HValue* value,
- Handle<Map> type,
+ Handle<Map> map,
LookupResult* lookup,
bool smi_and_map_check);
HInstruction* BuildStoreNamedGeneric(HValue* object,
Handle<String> name,
HValue* value);
+ HInstruction* BuildCallSetter(HValue* object,
+ HValue* value,
+ Handle<Map> map,
+ Handle<JSFunction> setter,
+ Handle<JSObject> holder);
+ HInstruction* BuildStoreNamedMonomorphic(HValue* object,
+ Handle<String> name,
+ HValue* value,
+ Handle<Map> map);
HInstruction* BuildStoreKeyedGeneric(HValue* object,
HValue* key,
HValue* value);
HValue* BuildContextChainWalk(Variable* var);
- void AddCheckConstantFunction(Call* expr,
+ HInstruction* BuildThisFunction();
+
+ void AddCheckConstantFunction(Handle<JSObject> holder,
HValue* receiver,
Handle<Map> receiver_map,
bool smi_and_map_check);
diff --git a/deps/v8/src/ia32/assembler-ia32-inl.h b/deps/v8/src/ia32/assembler-ia32-inl.h
index 3cf0d005e..7fdf50c7a 100644
--- a/deps/v8/src/ia32/assembler-ia32-inl.h
+++ b/deps/v8/src/ia32/assembler-ia32-inl.h
@@ -150,10 +150,7 @@ Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
JSGlobalPropertyCell* RelocInfo::target_cell() {
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
- Address address = Memory::Address_at(pc_);
- Object* object = HeapObject::FromAddress(
- address - JSGlobalPropertyCell::kValueOffset);
- return reinterpret_cast<JSGlobalPropertyCell*>(object);
+ return JSGlobalPropertyCell::FromValueAddress(Memory::Address_at(pc_));
}
@@ -338,9 +335,9 @@ void Assembler::emit(Handle<Object> handle) {
}
-void Assembler::emit(uint32_t x, RelocInfo::Mode rmode, unsigned id) {
- if (rmode == RelocInfo::CODE_TARGET && id != kNoASTId) {
- RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, static_cast<intptr_t>(id));
+void Assembler::emit(uint32_t x, RelocInfo::Mode rmode, TypeFeedbackId id) {
+ if (rmode == RelocInfo::CODE_TARGET && !id.IsNone()) {
+ RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, id.ToInt());
} else if (rmode != RelocInfo::NONE) {
RecordRelocInfo(rmode);
}
@@ -390,6 +387,11 @@ void Assembler::set_target_address_at(Address pc, Address target) {
}
+Address Assembler::target_address_from_return_address(Address pc) {
+ return pc - kCallTargetAddressOffset;
+}
+
+
Displacement Assembler::disp_at(Label* L) {
return Displacement(long_at(L->pos()));
}
diff --git a/deps/v8/src/ia32/assembler-ia32.cc b/deps/v8/src/ia32/assembler-ia32.cc
index a42f6324e..f291b0526 100644
--- a/deps/v8/src/ia32/assembler-ia32.cc
+++ b/deps/v8/src/ia32/assembler-ia32.cc
@@ -1373,7 +1373,7 @@ void Assembler::bind_to(Label* L, int pos) {
ASSERT(offset_to_next <= 0);
// Relative address, relative to point after address.
int disp = pos - fixup_pos - sizeof(int8_t);
- ASSERT(0 <= disp && disp <= 127);
+ CHECK(0 <= disp && disp <= 127);
set_byte_at(fixup_pos, disp);
if (offset_to_next < 0) {
L->link_to(fixup_pos + offset_to_next, Label::kNear);
@@ -1440,7 +1440,7 @@ int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
void Assembler::call(Handle<Code> code,
RelocInfo::Mode rmode,
- unsigned ast_id) {
+ TypeFeedbackId ast_id) {
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
ASSERT(RelocInfo::IsCodeTarget(rmode));
@@ -1938,6 +1938,16 @@ void Assembler::cvttsd2si(Register dst, const Operand& src) {
}
+void Assembler::cvtsd2si(Register dst, XMMRegister src) {
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
+ EnsureSpace ensure_space(this);
+ EMIT(0xF2);
+ EMIT(0x0F);
+ EMIT(0x2D);
+ emit_sse_operand(dst, src);
+}
+
+
void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
@@ -2044,6 +2054,15 @@ void Assembler::andpd(XMMRegister dst, XMMRegister src) {
}
+void Assembler::orpd(XMMRegister dst, XMMRegister src) {
+ EnsureSpace ensure_space(this);
+ EMIT(0x66);
+ EMIT(0x0F);
+ EMIT(0x56);
+ emit_sse_operand(dst, src);
+}
+
+
void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
@@ -2086,6 +2105,16 @@ void Assembler::movmskpd(Register dst, XMMRegister src) {
}
+void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
+ EnsureSpace ensure_space(this);
+ EMIT(0x66);
+ EMIT(0x0F);
+ EMIT(0x76);
+ emit_sse_operand(dst, src);
+}
+
+
void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
diff --git a/deps/v8/src/ia32/assembler-ia32.h b/deps/v8/src/ia32/assembler-ia32.h
index 4ead80b0e..b0f4651d1 100644
--- a/deps/v8/src/ia32/assembler-ia32.h
+++ b/deps/v8/src/ia32/assembler-ia32.h
@@ -587,6 +587,11 @@ class Assembler : public AssemblerBase {
// Overrides the default provided by FLAG_debug_code.
void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
+ // Avoids using instructions that vary in size in unpredictable ways between
+ // the snapshot and the running VM. This is needed by the full compiler so
+ // that it can recompile code with debug support and fix the PC.
+ void set_predictable_code_size(bool value) { predictable_code_size_ = value; }
+
// GetCode emits any pending (non-emitted) code and fills the descriptor
// desc. GetCode() is idempotent; it returns the same result if no other
// Assembler functions are invoked in between GetCode() calls.
@@ -596,6 +601,10 @@ class Assembler : public AssemblerBase {
inline static Address target_address_at(Address pc);
inline static void set_target_address_at(Address pc, Address target);
+ // Return the code target address at a call site from the return address
+ // of that call in the instruction stream.
+ inline static Address target_address_from_return_address(Address pc);
+
// This sets the branch destination (which is in the instruction on x86).
// This is for calls and branches within generated code.
inline static void deserialization_set_special_target_at(
@@ -624,6 +633,7 @@ class Assembler : public AssemblerBase {
static const int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32.
static const int kCallInstructionLength = 5;
+ static const int kPatchDebugBreakSlotReturnOffset = kPointerSize;
static const int kJSReturnSequenceLength = 6;
// The debug break slot must be able to contain a call instruction.
@@ -883,8 +893,8 @@ class Assembler : public AssemblerBase {
void call(const Operand& adr);
int CallSize(Handle<Code> code, RelocInfo::Mode mode);
void call(Handle<Code> code,
- RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
- unsigned ast_id = kNoASTId);
+ RelocInfo::Mode rmode,
+ TypeFeedbackId id = TypeFeedbackId::None());
// Jumps
// unconditional jump to L
@@ -978,6 +988,7 @@ class Assembler : public AssemblerBase {
// SSE2 instructions
void cvttss2si(Register dst, const Operand& src);
void cvttsd2si(Register dst, const Operand& src);
+ void cvtsd2si(Register dst, XMMRegister src);
void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); }
void cvtsi2sd(XMMRegister dst, const Operand& src);
@@ -993,6 +1004,7 @@ class Assembler : public AssemblerBase {
void sqrtsd(XMMRegister dst, XMMRegister src);
void andpd(XMMRegister dst, XMMRegister src);
+ void orpd(XMMRegister dst, XMMRegister src);
void ucomisd(XMMRegister dst, XMMRegister src);
void ucomisd(XMMRegister dst, const Operand& src);
@@ -1009,6 +1021,7 @@ class Assembler : public AssemblerBase {
void movmskpd(Register dst, XMMRegister src);
void cmpltsd(XMMRegister dst, XMMRegister src);
+ void pcmpeqd(XMMRegister dst, XMMRegister src);
void movaps(XMMRegister dst, XMMRegister src);
@@ -1111,6 +1124,7 @@ class Assembler : public AssemblerBase {
protected:
bool emit_debug_code() const { return emit_debug_code_; }
+ bool predictable_code_size() const { return predictable_code_size_ ; }
void movsd(XMMRegister dst, const Operand& src);
void movsd(const Operand& dst, XMMRegister src);
@@ -1136,7 +1150,7 @@ class Assembler : public AssemblerBase {
inline void emit(Handle<Object> handle);
inline void emit(uint32_t x,
RelocInfo::Mode rmode,
- unsigned ast_id = kNoASTId);
+ TypeFeedbackId id = TypeFeedbackId::None());
inline void emit(const Immediate& x);
inline void emit_w(const Immediate& x);
@@ -1186,6 +1200,7 @@ class Assembler : public AssemblerBase {
PositionsRecorder positions_recorder_;
bool emit_debug_code_;
+ bool predictable_code_size_;
friend class PositionsRecorder;
};
diff --git a/deps/v8/src/ia32/builtins-ia32.cc b/deps/v8/src/ia32/builtins-ia32.cc
index be46ff216..9bc15e909 100644
--- a/deps/v8/src/ia32/builtins-ia32.cc
+++ b/deps/v8/src/ia32/builtins-ia32.cc
@@ -74,6 +74,43 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
}
+static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
+ __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
+ __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kCodeOffset));
+ __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
+ __ jmp(eax);
+}
+
+
+void Builtins::Generate_InRecompileQueue(MacroAssembler* masm) {
+ GenerateTailCallToSharedCode(masm);
+}
+
+
+void Builtins::Generate_ParallelRecompile(MacroAssembler* masm) {
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ // Push a copy of the function onto the stack.
+ __ push(edi);
+ // Push call kind information.
+ __ push(ecx);
+
+ __ push(edi); // Function is also the parameter to the runtime call.
+ __ CallRuntime(Runtime::kParallelRecompile, 1);
+
+ // Restore call kind information.
+ __ pop(ecx);
+ // Restore receiver.
+ __ pop(edi);
+
+ // Tear down internal frame.
+ }
+
+ GenerateTailCallToSharedCode(masm);
+}
+
+
static void Generate_JSConstructStubHelper(MacroAssembler* masm,
bool is_api_function,
bool count_constructions) {
@@ -641,9 +678,9 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// receiver.
__ bind(&use_global_receiver);
const int kGlobalIndex =
- Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
__ mov(ebx, FieldOperand(esi, kGlobalIndex));
- __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalContextOffset));
+ __ mov(ebx, FieldOperand(ebx, GlobalObject::kNativeContextOffset));
__ mov(ebx, FieldOperand(ebx, kGlobalIndex));
__ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
@@ -819,9 +856,9 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Use the current global receiver object as the receiver.
__ bind(&use_global_receiver);
const int kGlobalOffset =
- Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
__ mov(ebx, FieldOperand(esi, kGlobalOffset));
- __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalContextOffset));
+ __ mov(ebx, FieldOperand(ebx, GlobalObject::kNativeContextOffset));
__ mov(ebx, FieldOperand(ebx, kGlobalOffset));
__ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc
index df04b289b..3b6987e6f 100644
--- a/deps/v8/src/ia32/code-stubs-ia32.cc
+++ b/deps/v8/src/ia32/code-stubs-ia32.cc
@@ -66,9 +66,13 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
void FastNewClosureStub::Generate(MacroAssembler* masm) {
// Create a new closure from the given function info in new
// space. Set the context to the current context in esi.
+ Counters* counters = masm->isolate()->counters();
+
Label gc;
__ AllocateInNewSpace(JSFunction::kSize, eax, ebx, ecx, &gc, TAG_OBJECT);
+ __ IncrementCounter(counters->fast_new_closure_total(), 1);
+
// Get the function info from the stack.
__ mov(edx, Operand(esp, 1 * kPointerSize));
@@ -76,12 +80,12 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) {
? Context::FUNCTION_MAP_INDEX
: Context::STRICT_MODE_FUNCTION_MAP_INDEX;
- // Compute the function map in the current global context and set that
+ // Compute the function map in the current native context and set that
// as the map of the allocated object.
- __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalContextOffset));
- __ mov(ecx, Operand(ecx, Context::SlotOffset(map_index)));
- __ mov(FieldOperand(eax, JSObject::kMapOffset), ecx);
+ __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ mov(ecx, FieldOperand(ecx, GlobalObject::kNativeContextOffset));
+ __ mov(ebx, Operand(ecx, Context::SlotOffset(map_index)));
+ __ mov(FieldOperand(eax, JSObject::kMapOffset), ebx);
// Initialize the rest of the function. We don't have to update the
// write barrier because the allocated object is in new space.
@@ -94,11 +98,20 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) {
__ mov(FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset), edx);
__ mov(FieldOperand(eax, JSFunction::kContextOffset), esi);
__ mov(FieldOperand(eax, JSFunction::kLiteralsOffset), ebx);
- __ mov(FieldOperand(eax, JSFunction::kNextFunctionLinkOffset),
- Immediate(factory->undefined_value()));
// Initialize the code pointer in the function to be the one
// found in the shared function info object.
+ // But first check if there is an optimized version for our context.
+ Label check_optimized;
+ Label install_unoptimized;
+ if (FLAG_cache_optimized_code) {
+ __ mov(ebx, FieldOperand(edx, SharedFunctionInfo::kOptimizedCodeMapOffset));
+ __ test(ebx, ebx);
+ __ j(not_zero, &check_optimized, Label::kNear);
+ }
+ __ bind(&install_unoptimized);
+ __ mov(FieldOperand(eax, JSFunction::kNextFunctionLinkOffset),
+ Immediate(factory->undefined_value()));
__ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
__ lea(edx, FieldOperand(edx, Code::kHeaderSize));
__ mov(FieldOperand(eax, JSFunction::kCodeEntryOffset), edx);
@@ -106,6 +119,68 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) {
// Return and remove the on-stack parameter.
__ ret(1 * kPointerSize);
+ __ bind(&check_optimized);
+
+ __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1);
+
+ // ecx holds native context, ebx points to fixed array of 3-element entries
+ // (native context, optimized code, literals).
+ // Map must never be empty, so check the first elements.
+ Label install_optimized;
+ // Speculatively move code object into edx.
+ __ mov(edx, FieldOperand(ebx, FixedArray::kHeaderSize + kPointerSize));
+ __ cmp(ecx, FieldOperand(ebx, FixedArray::kHeaderSize));
+ __ j(equal, &install_optimized);
+
+ // Iterate through the rest of map backwards. edx holds an index as a Smi.
+ Label loop;
+ Label restore;
+ __ mov(edx, FieldOperand(ebx, FixedArray::kLengthOffset));
+ __ bind(&loop);
+ // Do not double check first entry.
+ __ cmp(edx, Immediate(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
+ __ j(equal, &restore);
+ __ sub(edx, Immediate(Smi::FromInt(
+ SharedFunctionInfo::kEntryLength))); // Skip an entry.
+ __ cmp(ecx, CodeGenerator::FixedArrayElementOperand(ebx, edx, 0));
+ __ j(not_equal, &loop, Label::kNear);
+ // Hit: fetch the optimized code.
+ __ mov(edx, CodeGenerator::FixedArrayElementOperand(ebx, edx, 1));
+
+ __ bind(&install_optimized);
+ __ IncrementCounter(counters->fast_new_closure_install_optimized(), 1);
+
+ // TODO(fschneider): Idea: store proper code pointers in the optimized code
+ // map and either unmangle them on marking or do nothing as the whole map is
+ // discarded on major GC anyway.
+ __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
+ __ mov(FieldOperand(eax, JSFunction::kCodeEntryOffset), edx);
+
+ // Now link a function into a list of optimized functions.
+ __ mov(edx, ContextOperand(ecx, Context::OPTIMIZED_FUNCTIONS_LIST));
+
+ __ mov(FieldOperand(eax, JSFunction::kNextFunctionLinkOffset), edx);
+ // No need for write barrier as JSFunction (eax) is in the new space.
+
+ __ mov(ContextOperand(ecx, Context::OPTIMIZED_FUNCTIONS_LIST), eax);
+ // Store JSFunction (eax) into edx before issuing write barrier as
+ // it clobbers all the registers passed.
+ __ mov(edx, eax);
+ __ RecordWriteContextSlot(
+ ecx,
+ Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
+ edx,
+ ebx,
+ kDontSaveFPRegs);
+
+ // Return and remove the on-stack parameter.
+ __ ret(1 * kPointerSize);
+
+ __ bind(&restore);
+ // Restore SharedFunctionInfo into edx.
+ __ mov(edx, Operand(esp, 1 * kPointerSize));
+ __ jmp(&install_unoptimized);
+
// Create a new closure through the slower runtime call.
__ bind(&gc);
__ pop(ecx); // Temporarily remove return address.
@@ -142,8 +217,8 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
__ mov(Operand(eax, Context::SlotOffset(Context::EXTENSION_INDEX)), ebx);
// Copy the global object from the previous context.
- __ mov(ebx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_INDEX)), ebx);
+ __ mov(ebx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)), ebx);
// Initialize the rest of the slots to undefined.
__ mov(ebx, factory->undefined_value());
@@ -186,9 +261,9 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ mov(FieldOperand(eax, Context::kLengthOffset),
Immediate(Smi::FromInt(length)));
- // If this block context is nested in the global context we get a smi
+ // If this block context is nested in the native context we get a smi
// sentinel instead of a function. The block context should get the
- // canonical empty function of the global context as its closure which
+ // canonical empty function of the native context as its closure which
// we still have to look up.
Label after_sentinel;
__ JumpIfNotSmi(ecx, &after_sentinel, Label::kNear);
@@ -198,7 +273,7 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ Assert(equal, message);
}
__ mov(ecx, GlobalObjectOperand());
- __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalContextOffset));
+ __ mov(ecx, FieldOperand(ecx, GlobalObject::kNativeContextOffset));
__ mov(ecx, ContextOperand(ecx, Context::CLOSURE_INDEX));
__ bind(&after_sentinel);
@@ -208,8 +283,8 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ mov(ContextOperand(eax, Context::EXTENSION_INDEX), ebx);
// Copy the global object from the previous context.
- __ mov(ebx, ContextOperand(esi, Context::GLOBAL_INDEX));
- __ mov(ContextOperand(eax, Context::GLOBAL_INDEX), ebx);
+ __ mov(ebx, ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX));
+ __ mov(ContextOperand(eax, Context::GLOBAL_OBJECT_INDEX), ebx);
// Initialize the rest of the slots to the hole value.
if (slots_ == 1) {
@@ -1718,9 +1793,10 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
if (result_type_ <= BinaryOpIC::INT32) {
__ cvttsd2si(ecx, Operand(xmm0));
__ cvtsi2sd(xmm2, ecx);
- __ ucomisd(xmm0, xmm2);
- __ j(not_zero, &not_int32);
- __ j(carry, &not_int32);
+ __ pcmpeqd(xmm2, xmm0);
+ __ movmskpd(ecx, xmm2);
+ __ test(ecx, Immediate(1));
+ __ j(zero, &not_int32);
}
GenerateHeapResultAllocation(masm, &call_runtime);
__ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
@@ -3138,21 +3214,28 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ movsd(double_scratch2, double_result); // Load double_exponent with 1.
// Get absolute value of exponent.
- Label no_neg, while_true, no_multiply;
+ Label no_neg, while_true, while_false;
__ test(scratch, scratch);
__ j(positive, &no_neg, Label::kNear);
__ neg(scratch);
__ bind(&no_neg);
- __ bind(&while_true);
+ __ j(zero, &while_false, Label::kNear);
__ shr(scratch, 1);
- __ j(not_carry, &no_multiply, Label::kNear);
- __ mulsd(double_result, double_scratch);
- __ bind(&no_multiply);
+ // Above condition means CF==0 && ZF==0. This means that the
+ // bit that has been shifted out is 0 and the result is not 0.
+ __ j(above, &while_true, Label::kNear);
+ __ movsd(double_result, double_scratch);
+ __ j(zero, &while_false, Label::kNear);
+ __ bind(&while_true);
+ __ shr(scratch, 1);
__ mulsd(double_scratch, double_scratch);
+ __ j(above, &while_true, Label::kNear);
+ __ mulsd(double_result, double_scratch);
__ j(not_zero, &while_true);
+ __ bind(&while_false);
// scratch has the original value of the exponent - if the exponent is
// negative, return 1/result.
__ test(exponent, exponent);
@@ -3359,10 +3442,10 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
// esp[0] = mapped parameter count (tagged)
// esp[8] = parameter count (tagged)
// esp[12] = address of receiver argument
- // Get the arguments boilerplate from the current (global) context into edi.
+ // Get the arguments boilerplate from the current native context into edi.
Label has_mapped_parameters, copy;
- __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset));
+ __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset));
__ mov(ebx, Operand(esp, 0 * kPointerSize));
__ test(ebx, ebx);
__ j(not_zero, &has_mapped_parameters, Label::kNear);
@@ -3552,9 +3635,9 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Do the allocation of both objects in one go.
__ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
- // Get the arguments boilerplate from the current (global) context.
- __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset));
+ // Get the arguments boilerplate from the current native context.
+ __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset));
const int offset =
Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX);
__ mov(edi, Operand(edi, offset));
@@ -3673,7 +3756,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
__ add(edx, Immediate(2)); // edx was a smi.
// Check that the static offsets vector buffer is large enough.
- __ cmp(edx, OffsetsVector::kStaticOffsetsVectorSize);
+ __ cmp(edx, Isolate::kJSRegexpStaticOffsetsVectorSize);
__ j(above, &runtime);
// ecx: RegExp data (FixedArray)
@@ -4067,11 +4150,11 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
// Set empty properties FixedArray.
// Set elements to point to FixedArray allocated right after the JSArray.
// Interleave operations for better latency.
- __ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX));
+ __ mov(edx, ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX));
Factory* factory = masm->isolate()->factory();
__ mov(ecx, Immediate(factory->empty_fixed_array()));
__ lea(ebx, Operand(eax, JSRegExpResult::kSize));
- __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalContextOffset));
+ __ mov(edx, FieldOperand(edx, GlobalObject::kNativeContextOffset));
__ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx);
__ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx);
__ mov(edx, ContextOperand(edx, Context::REGEXP_RESULT_MAP_INDEX));
@@ -4095,15 +4178,15 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
Immediate(factory->fixed_array_map()));
// Set length.
__ mov(FieldOperand(ebx, FixedArray::kLengthOffset), ecx);
- // Fill contents of fixed-array with the-hole.
+ // Fill contents of fixed-array with undefined.
__ SmiUntag(ecx);
- __ mov(edx, Immediate(factory->the_hole_value()));
+ __ mov(edx, Immediate(factory->undefined_value()));
__ lea(ebx, FieldOperand(ebx, FixedArray::kHeaderSize));
- // Fill fixed array elements with hole.
+ // Fill fixed array elements with undefined.
// eax: JSArray.
// ecx: Number of elements to fill.
// ebx: Start of elements in FixedArray.
- // edx: the hole.
+ // edx: undefined.
Label loop;
__ test(ecx, ecx);
__ bind(&loop);
@@ -5649,7 +5732,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
__ AllocateAsciiConsString(ecx, edi, no_reg, &call_runtime);
__ bind(&allocated);
// Fill the fields of the cons string.
- if (FLAG_debug_code) __ AbortIfNotSmi(ebx);
+ __ AssertSmi(ebx);
__ mov(FieldOperand(ecx, ConsString::kLengthOffset), ebx);
__ mov(FieldOperand(ecx, ConsString::kHashFieldOffset),
Immediate(String::kEmptyHashField));
@@ -6898,8 +6981,7 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
ASSERT(!name.is(r0));
ASSERT(!name.is(r1));
- // Assert that name contains a string.
- if (FLAG_debug_code) __ AbortIfNotString(name);
+ __ AssertString(name);
__ mov(r1, FieldOperand(elements, kCapacityOffset));
__ shr(r1, kSmiTagSize); // convert smi to int
@@ -7073,6 +7155,8 @@ static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
{ REG(edx), REG(eax), REG(edi), EMIT_REMEMBERED_SET},
// StoreArrayLiteralElementStub::Generate
{ REG(ebx), REG(eax), REG(ecx), EMIT_REMEMBERED_SET},
+ // FastNewClosureStub
+ { REG(ecx), REG(edx), REG(ebx), EMIT_REMEMBERED_SET},
// Null termination.
{ REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET}
};
@@ -7121,6 +7205,11 @@ void RecordWriteStub::GenerateFixedRegStubsAheadOfTime() {
}
+bool CodeStub::CanUseFPRegisters() {
+ return CpuFeatures::IsSupported(SSE2);
+}
+
+
// Takes the input in 3 registers: address_ value_ and object_. A pointer to
// the value has just been written into the object, now this stub makes sure
// we keep the GC informed. The word in the object where the value has been
@@ -7241,6 +7330,17 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
Mode mode) {
Label object_is_black, need_incremental, need_incremental_pop_object;
+ __ mov(regs_.scratch0(), Immediate(~Page::kPageAlignmentMask));
+ __ and_(regs_.scratch0(), regs_.object());
+ __ mov(regs_.scratch1(),
+ Operand(regs_.scratch0(),
+ MemoryChunk::kWriteBarrierCounterOffset));
+ __ sub(regs_.scratch1(), Immediate(1));
+ __ mov(Operand(regs_.scratch0(),
+ MemoryChunk::kWriteBarrierCounterOffset),
+ regs_.scratch1());
+ __ j(negative, &need_incremental);
+
// Let's look at the color of the object: If it is not black we don't have
// to inform the incremental marker.
__ JumpIfBlack(regs_.object(),
@@ -7397,6 +7497,38 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
__ ret(0);
}
+
+void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
+ if (entry_hook_ != NULL) {
+ ProfileEntryHookStub stub;
+ masm->CallStub(&stub);
+ }
+}
+
+
+void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
+ // Ecx is the only volatile register we must save.
+ __ push(ecx);
+
+ // Calculate and push the original stack pointer.
+ __ lea(eax, Operand(esp, kPointerSize));
+ __ push(eax);
+
+ // Calculate and push the function address.
+ __ mov(eax, Operand(eax, 0));
+ __ sub(eax, Immediate(Assembler::kCallInstructionLength));
+ __ push(eax);
+
+ // Call the entry hook.
+ int32_t hook_location = reinterpret_cast<int32_t>(&entry_hook_);
+ __ call(Operand(hook_location, RelocInfo::NONE));
+ __ add(esp, Immediate(2 * kPointerSize));
+
+ // Restore ecx.
+ __ pop(ecx);
+ __ ret(0);
+}
+
#undef __
} } // namespace v8::internal
diff --git a/deps/v8/src/ia32/deoptimizer-ia32.cc b/deps/v8/src/ia32/deoptimizer-ia32.cc
index 326207fbc..99ad5225b 100644
--- a/deps/v8/src/ia32/deoptimizer-ia32.cc
+++ b/deps/v8/src/ia32/deoptimizer-ia32.cc
@@ -117,6 +117,10 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
if (!function->IsOptimized()) return;
+ // The optimized code is going to be patched, so we cannot use it
+ // any more. Play safe and reset the whole cache.
+ function->shared()->ClearOptimizedCodeMap();
+
Isolate* isolate = function->GetIsolate();
HandleScope scope(isolate);
AssertNoAllocation no_allocation;
@@ -194,8 +198,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
// ignore all slots that might have been recorded on it.
isolate->heap()->mark_compact_collector()->InvalidateCode(code);
- // Set the code for the function to non-optimized version.
- function->ReplaceCode(function->shared()->code());
+ ReplaceCodeForRelatedFunctions(function, code);
if (FLAG_trace_deopt) {
PrintF("[forced deoptimization: ");
@@ -284,11 +287,11 @@ void Deoptimizer::RevertStackCheckCodeAt(Code* unoptimized_code,
}
-static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) {
+static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) {
ByteArray* translations = data->TranslationByteArray();
int length = data->DeoptCount();
for (int i = 0; i < length; i++) {
- if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) {
+ if (data->AstId(i) == ast_id) {
TranslationIterator it(translations, data->TranslationIndex(i)->value());
int value = it.Next();
ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value));
@@ -310,7 +313,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
// the ast id. Confusing.
ASSERT(bailout_id_ == ast_id);
- int bailout_id = LookupBailoutId(data, ast_id);
+ int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
unsigned translation_index = data->TranslationIndex(bailout_id)->value();
ByteArray* translations = data->TranslationByteArray();
@@ -330,9 +333,9 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
unsigned node_id = iterator.Next();
USE(node_id);
ASSERT(node_id == ast_id);
- JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next()));
- USE(function);
- ASSERT(function == function_);
+ int closure_id = iterator.Next();
+ USE(closure_id);
+ ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
unsigned height = iterator.Next();
unsigned height_in_bytes = height * kPointerSize;
USE(height_in_bytes);
@@ -456,15 +459,15 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
output_[0]->SetPc(pc);
}
Code* continuation =
- function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
+ function_->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
output_[0]->SetContinuation(
reinterpret_cast<uint32_t>(continuation->entry()));
if (FLAG_trace_osr) {
PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
ok ? "finished" : "aborted",
- reinterpret_cast<intptr_t>(function));
- function->PrintName();
+ reinterpret_cast<intptr_t>(function_));
+ function_->PrintName();
PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
}
}
@@ -679,16 +682,143 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
}
+void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
+ int frame_index,
+ bool is_setter_stub_frame) {
+ JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ // The receiver (and the implicit return value, if any) are expected in
+ // registers by the LoadIC/StoreIC, so they don't belong to the output stack
+ // frame. This means that we have to use a height of 0.
+ unsigned height = 0;
+ unsigned height_in_bytes = height * kPointerSize;
+ const char* kind = is_setter_stub_frame ? "setter" : "getter";
+ if (FLAG_trace_deopt) {
+ PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes);
+ }
+
+ // We need 1 stack entry for the return address + 4 stack entries from
+ // StackFrame::INTERNAL (FP, context, frame type, code object, see
+ // MacroAssembler::EnterFrame). For a setter stub frame we need one additional
+ // entry for the implicit return value, see
+ // StoreStubCompiler::CompileStoreViaSetter.
+ unsigned fixed_frame_entries = 1 + 4 + (is_setter_stub_frame ? 1 : 0);
+ unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
+ unsigned output_frame_size = height_in_bytes + fixed_frame_size;
+
+ // Allocate and store the output frame description.
+ FrameDescription* output_frame =
+ new(output_frame_size) FrameDescription(output_frame_size, accessor);
+ output_frame->SetFrameType(StackFrame::INTERNAL);
+
+ // A frame for an accessor stub can not be the topmost or bottommost one.
+ ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
+ ASSERT(output_[frame_index] == NULL);
+ output_[frame_index] = output_frame;
+
+ // The top address of the frame is computed from the previous frame's top and
+ // this frame's size.
+ intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
+ output_frame->SetTop(top_address);
+
+ unsigned output_offset = output_frame_size;
+
+ // Read caller's PC from the previous frame.
+ output_offset -= kPointerSize;
+ intptr_t callers_pc = output_[frame_index - 1]->GetPc();
+ output_frame->SetFrameSlot(output_offset, callers_pc);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; caller's pc\n",
+ top_address + output_offset, output_offset, callers_pc);
+ }
+
+ // Read caller's FP from the previous frame, and set this frame's FP.
+ output_offset -= kPointerSize;
+ intptr_t value = output_[frame_index - 1]->GetFp();
+ output_frame->SetFrameSlot(output_offset, value);
+ intptr_t fp_value = top_address + output_offset;
+ output_frame->SetFp(fp_value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; caller's fp\n",
+ fp_value, output_offset, value);
+ }
+
+ // The context can be gotten from the previous frame.
+ output_offset -= kPointerSize;
+ value = output_[frame_index - 1]->GetContext();
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; context\n",
+ top_address + output_offset, output_offset, value);
+ }
+
+ // A marker value is used in place of the function.
+ output_offset -= kPointerSize;
+ value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; function (%s sentinel)\n",
+ top_address + output_offset, output_offset, value, kind);
+ }
+
+ // Get Code object from accessor stub.
+ output_offset -= kPointerSize;
+ Builtins::Name name = is_setter_stub_frame ?
+ Builtins::kStoreIC_Setter_ForDeopt :
+ Builtins::kLoadIC_Getter_ForDeopt;
+ Code* accessor_stub = isolate_->builtins()->builtin(name);
+ value = reinterpret_cast<intptr_t>(accessor_stub);
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; code object\n",
+ top_address + output_offset, output_offset, value);
+ }
+
+ // Skip receiver.
+ Translation::Opcode opcode =
+ static_cast<Translation::Opcode>(iterator->Next());
+ iterator->Skip(Translation::NumberOfOperandsFor(opcode));
+
+ if (is_setter_stub_frame) {
+ // The implicit return value was part of the artificial setter stub
+ // environment.
+ output_offset -= kPointerSize;
+ DoTranslateCommand(iterator, frame_index, output_offset);
+ }
+
+ ASSERT(0 == output_offset);
+
+ Smi* offset = is_setter_stub_frame ?
+ isolate_->heap()->setter_stub_deopt_pc_offset() :
+ isolate_->heap()->getter_stub_deopt_pc_offset();
+ intptr_t pc = reinterpret_cast<intptr_t>(
+ accessor_stub->instruction_start() + offset->value());
+ output_frame->SetPc(pc);
+}
+
+
void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
int frame_index) {
- int node_id = iterator->Next();
- JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ BailoutId node_id = BailoutId(iterator->Next());
+ JSFunction* function;
+ if (frame_index != 0) {
+ function = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ } else {
+ int closure_id = iterator->Next();
+ USE(closure_id);
+ ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
+ function = function_;
+ }
unsigned height = iterator->Next();
unsigned height_in_bytes = height * kPointerSize;
if (FLAG_trace_deopt) {
PrintF(" translating ");
function->PrintName();
- PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes);
+ PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
}
// The 'fixed' part of the frame consists of the incoming parameters and
diff --git a/deps/v8/src/ia32/disasm-ia32.cc b/deps/v8/src/ia32/disasm-ia32.cc
index b5ddcca19..75b46bd47 100644
--- a/deps/v8/src/ia32/disasm-ia32.cc
+++ b/deps/v8/src/ia32/disasm-ia32.cc
@@ -553,6 +553,7 @@ int DisassemblerIA32::F7Instruction(byte* data) {
case 2: mnem = "not"; break;
case 3: mnem = "neg"; break;
case 4: mnem = "mul"; break;
+ case 5: mnem = "imul"; break;
case 7: mnem = "idiv"; break;
default: UnimplementedInstruction();
}
@@ -1266,6 +1267,14 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
NameOfXMMRegister(regop),
NameOfXMMRegister(rm));
data++;
+ } else if (*data == 0x56) {
+ data++;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, &regop, &rm);
+ AppendToBuffer("orpd %s,%s",
+ NameOfXMMRegister(regop),
+ NameOfXMMRegister(rm));
+ data++;
} else if (*data == 0x57) {
data++;
int mod, regop, rm;
@@ -1296,6 +1305,14 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
NameOfXMMRegister(rm),
static_cast<int>(imm8));
data += 2;
+ } else if (*data == 0x76) {
+ data++;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, &regop, &rm);
+ AppendToBuffer("pcmpeqd %s,%s",
+ NameOfXMMRegister(regop),
+ NameOfXMMRegister(rm));
+ data++;
} else if (*data == 0x90) {
data++;
AppendToBuffer("nop"); // 2 byte nop.
@@ -1463,6 +1480,7 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
switch (b2) {
case 0x2A: mnem = "cvtsi2sd"; break;
case 0x2C: mnem = "cvttsd2si"; break;
+ case 0x2D: mnem = "cvtsd2si"; break;
case 0x51: mnem = "sqrtsd"; break;
case 0x58: mnem = "addsd"; break;
case 0x59: mnem = "mulsd"; break;
@@ -1475,7 +1493,7 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
if (b2 == 0x2A) {
AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop));
data += PrintRightOperand(data);
- } else if (b2 == 0x2C) {
+ } else if (b2 == 0x2C || b2 == 0x2D) {
AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop));
data += PrintRightXMMOperand(data);
} else if (b2 == 0xC2) {
diff --git a/deps/v8/src/ia32/full-codegen-ia32.cc b/deps/v8/src/ia32/full-codegen-ia32.cc
index 5a513fd48..406537d2d 100644
--- a/deps/v8/src/ia32/full-codegen-ia32.cc
+++ b/deps/v8/src/ia32/full-codegen-ia32.cc
@@ -123,6 +123,8 @@ void FullCodeGenerator::Generate() {
SetFunctionPosition(function());
Comment cmnt(masm_, "[ function compiled by full code generator");
+ ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+
#ifdef DEBUG
if (strlen(FLAG_stop_at) > 0 &&
info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
@@ -176,10 +178,13 @@ void FullCodeGenerator::Generate() {
// Possibly allocate a local context.
int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
if (heap_slots > 0) {
- Comment cmnt(masm_, "[ Allocate local context");
+ Comment cmnt(masm_, "[ Allocate context");
// Argument to NewContext is the function, which is still in edi.
__ push(edi);
- if (heap_slots <= FastNewContextStub::kMaximumSlots) {
+ if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+ __ Push(info->scope()->GetScopeInfo());
+ __ CallRuntime(Runtime::kNewGlobalContext, 2);
+ } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
FastNewContextStub stub(heap_slots);
__ CallStub(&stub);
} else {
@@ -227,7 +232,7 @@ void FullCodeGenerator::Generate() {
__ lea(edx,
Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset));
__ push(edx);
- __ SafePush(Immediate(Smi::FromInt(num_parameters)));
+ __ push(Immediate(Smi::FromInt(num_parameters)));
// Arguments to ArgumentsAccessStub:
// function, receiver address, parameter count.
// The stub will rewrite receiver and parameter count if the previous
@@ -257,7 +262,7 @@ void FullCodeGenerator::Generate() {
scope()->VisitIllegalRedeclaration(this);
} else {
- PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
+ PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
{ Comment cmnt(masm_, "[ Declarations");
// For named function expressions, declare the function name as a
// constant.
@@ -272,7 +277,7 @@ void FullCodeGenerator::Generate() {
}
{ Comment cmnt(masm_, "[ Stack check");
- PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
+ PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
Label ok;
ExternalReference stack_limit =
ExternalReference::address_of_stack_limit(isolate());
@@ -317,20 +322,12 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
// Self-optimization is a one-off thing: if it fails, don't try again.
reset_value = Smi::kMaxValue;
}
- if (isolate()->IsDebuggerActive()) {
- // Detect debug break requests as soon as possible.
- reset_value = 10;
- }
__ mov(ebx, Immediate(profiling_counter_));
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
Immediate(Smi::FromInt(reset_value)));
}
-static const int kMaxBackEdgeWeight = 127;
-static const int kBackEdgeDistanceDivisor = 100;
-
-
void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
Label* back_edge_target) {
Comment cmnt(masm_, "[ Stack check");
@@ -342,7 +339,7 @@ void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
ASSERT(back_edge_target->is_bound());
int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kBackEdgeDistanceDivisor));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
__ j(positive, &ok, Label::kNear);
@@ -404,7 +401,7 @@ void FullCodeGenerator::EmitReturnSequence() {
} else if (FLAG_weighted_back_edges) {
int distance = masm_->pc_offset();
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kBackEdgeDistanceDivisor));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
Label ok;
@@ -760,7 +757,7 @@ void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
// The variable in the declaration always resides in the current function
// context.
ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
- if (FLAG_debug_code) {
+ if (generate_debug_code_) {
// Check that we're not inside a with or catch context.
__ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset));
__ cmp(ebx, isolate()->factory()->with_context_map());
@@ -813,10 +810,9 @@ void FullCodeGenerator::VisitVariableDeclaration(
__ push(esi);
__ push(Immediate(variable->name()));
// VariableDeclaration nodes are always introduced in one of four modes.
- ASSERT(mode == VAR || mode == LET ||
- mode == CONST || mode == CONST_HARMONY);
- PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
- ? READ_ONLY : NONE;
+ ASSERT(IsDeclaredVariableMode(mode));
+ PropertyAttributes attr =
+ IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
__ push(Immediate(Smi::FromInt(attr)));
// Push initial value, if any.
// Note: For variables we must not push an initial value (such as
@@ -1094,19 +1090,28 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// We got a map in register eax. Get the enumeration cache from it.
+ Label no_descriptors;
__ bind(&use_cache);
+
+ __ EnumLength(edx, eax);
+ __ cmp(edx, Immediate(Smi::FromInt(0)));
+ __ j(equal, &no_descriptors);
+
__ LoadInstanceDescriptors(eax, ecx);
- __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumerationIndexOffset));
- __ mov(edx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset));
+ __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumCacheOffset));
+ __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset));
// Set up the four remaining stack slots.
__ push(eax); // Map.
- __ push(edx); // Enumeration cache.
- __ mov(eax, FieldOperand(edx, FixedArray::kLengthOffset));
- __ push(eax); // Enumeration cache length (as smi).
+ __ push(ecx); // Enumeration cache.
+ __ push(edx); // Number of valid entries for the map in the enum cache.
__ push(Immediate(Smi::FromInt(0))); // Initial index.
__ jmp(&loop);
+ __ bind(&no_descriptors);
+ __ add(esp, Immediate(kPointerSize));
+ __ jmp(&exit);
+
// We got a fixed array in register eax. Iterate through that.
Label non_proxy;
__ bind(&fixed_array);
@@ -1115,7 +1120,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
isolate()->factory()->NewJSGlobalPropertyCell(
Handle<Object>(
Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker)));
- RecordTypeFeedbackCell(stmt->PrepareId(), cell);
+ RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
__ LoadHeapObject(ebx, cell);
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
Immediate(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
@@ -1271,9 +1276,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
__ mov(temp, context);
}
__ bind(&next);
- // Terminate at global context.
+ // Terminate at native context.
__ cmp(FieldOperand(temp, HeapObject::kMapOffset),
- Immediate(isolate()->factory()->global_context_map()));
+ Immediate(isolate()->factory()->native_context_map()));
__ j(equal, &fast, Label::kNear);
// Check that extension is NULL.
__ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
@@ -1559,7 +1564,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
// marked expressions, no store code is emitted.
expr->CalculateEmitStore(zone());
- AccessorTable accessor_table(isolate()->zone());
+ AccessorTable accessor_table(zone());
for (int i = 0; i < expr->properties()->length(); i++) {
ObjectLiteral::Property* property = expr->properties()->at(i);
if (property->IsCompileTimeValue()) continue;
@@ -1585,7 +1590,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, key->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
VisitForEffect(value);
@@ -1797,11 +1802,11 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
break;
case NAMED_PROPERTY:
EmitNamedPropertyLoad(property);
- PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
+ PrepareForBailoutForId(property->LoadId(), TOS_REG);
break;
case KEYED_PROPERTY:
EmitKeyedPropertyLoad(property);
- PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
+ PrepareForBailoutForId(property->LoadId(), TOS_REG);
break;
}
}
@@ -1857,14 +1862,14 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
ASSERT(!key->handle()->IsSmi());
__ mov(ecx, Immediate(key->handle()));
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
- CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
}
@@ -1885,7 +1890,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call);
__ mov(eax, ecx);
BinaryOpStub stub(op, mode);
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear);
@@ -1970,7 +1976,8 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
__ pop(edx);
BinaryOpStub stub(op, mode);
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
context()->Plug(eax);
}
@@ -2097,7 +2104,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// in harmony mode.
if (var->IsStackAllocated() || var->IsContextSlot()) {
MemOperand location = VarOperand(var, ecx);
- if (FLAG_debug_code && op == Token::INIT_LET) {
+ if (generate_debug_code_ && op == Token::INIT_LET) {
// Check for an uninitialized let binding.
__ mov(edx, location);
__ cmp(edx, isolate()->factory()->the_hole_value());
@@ -2132,37 +2139,15 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
ASSERT(prop != NULL);
ASSERT(prop->key()->AsLiteral() != NULL);
- // If the assignment starts a block of assignments to the same object,
- // change to slow case to avoid the quadratic behavior of repeatedly
- // adding fast properties.
- if (expr->starts_initialization_block()) {
- __ push(result_register());
- __ push(Operand(esp, kPointerSize)); // Receiver is now under value.
- __ CallRuntime(Runtime::kToSlowProperties, 1);
- __ pop(result_register());
- }
-
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ mov(ecx, prop->key()->AsLiteral()->handle());
- if (expr->ends_initialization_block()) {
- __ mov(edx, Operand(esp, 0));
- } else {
- __ pop(edx);
- }
+ __ pop(edx);
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
- // If the assignment ends an initialization block, revert to fast case.
- if (expr->ends_initialization_block()) {
- __ push(eax); // Result of assignment, saved even if not needed.
- __ push(Operand(esp, kPointerSize)); // Receiver is under value.
- __ CallRuntime(Runtime::kToFastProperties, 1);
- __ pop(eax);
- __ Drop(1);
- }
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
context()->Plug(eax);
}
@@ -2174,38 +2159,14 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// esp[0] : key
// esp[kPointerSize] : receiver
- // If the assignment starts a block of assignments to the same object,
- // change to slow case to avoid the quadratic behavior of repeatedly
- // adding fast properties.
- if (expr->starts_initialization_block()) {
- __ push(result_register());
- // Receiver is now under the key and value.
- __ push(Operand(esp, 2 * kPointerSize));
- __ CallRuntime(Runtime::kToSlowProperties, 1);
- __ pop(result_register());
- }
-
__ pop(ecx); // Key.
- if (expr->ends_initialization_block()) {
- __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
- } else {
- __ pop(edx);
- }
+ __ pop(edx);
// Record source code position before IC call.
SetSourcePosition(expr->position());
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
-
- // If the assignment ends an initialization block, revert to fast case.
- if (expr->ends_initialization_block()) {
- __ pop(edx);
- __ push(eax); // Result of assignment, saved even if not needed.
- __ push(edx);
- __ CallRuntime(Runtime::kToFastProperties, 1);
- __ pop(eax);
- }
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
context()->Plug(eax);
@@ -2220,6 +2181,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
VisitForAccumulatorValue(expr->obj());
__ mov(edx, result_register());
EmitNamedPropertyLoad(expr);
+ PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(eax);
} else {
VisitForStackValue(expr->obj());
@@ -2234,7 +2196,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
void FullCodeGenerator::CallIC(Handle<Code> code,
RelocInfo::Mode rmode,
- unsigned ast_id) {
+ TypeFeedbackId ast_id) {
ic_total_count_++;
__ call(code, rmode, ast_id);
}
@@ -2258,7 +2220,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
SetSourcePosition(expr->position());
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
- CallIC(ic, mode, expr->id());
+ CallIC(ic, mode, expr->CallFeedbackId());
RecordJSReturnSite(expr);
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
@@ -2290,7 +2252,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
Handle<Code> ic =
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
__ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId());
RecordJSReturnSite(expr);
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
@@ -2310,20 +2272,18 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
// Record source position for debugger.
SetSourcePosition(expr->position());
- // Record call targets in unoptimized code, but not in the snapshot.
- if (!Serializer::enabled()) {
- flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
- Handle<Object> uninitialized =
- TypeFeedbackCells::UninitializedSentinel(isolate());
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
- RecordTypeFeedbackCell(expr->id(), cell);
- __ mov(ebx, cell);
- }
+ // Record call targets in unoptimized code.
+ flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
+ Handle<Object> uninitialized =
+ TypeFeedbackCells::UninitializedSentinel(isolate());
+ Handle<JSGlobalPropertyCell> cell =
+ isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
+ RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
+ __ mov(ebx, cell);
CallFunctionStub stub(arg_count, flags);
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub, expr->id());
+ __ CallStub(&stub, expr->CallFeedbackId());
RecordJSReturnSite(expr);
// Restore context register.
@@ -2495,24 +2455,18 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
SetSourcePosition(expr->position());
// Load function and argument count into edi and eax.
- __ SafeSet(eax, Immediate(arg_count));
+ __ Set(eax, Immediate(arg_count));
__ mov(edi, Operand(esp, arg_count * kPointerSize));
- // Record call targets in unoptimized code, but not in the snapshot.
- CallFunctionFlags flags;
- if (!Serializer::enabled()) {
- flags = RECORD_CALL_TARGET;
- Handle<Object> uninitialized =
- TypeFeedbackCells::UninitializedSentinel(isolate());
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
- RecordTypeFeedbackCell(expr->id(), cell);
- __ mov(ebx, cell);
- } else {
- flags = NO_CALL_FUNCTION_FLAGS;
- }
+ // Record call targets in unoptimized code.
+ Handle<Object> uninitialized =
+ TypeFeedbackCells::UninitializedSentinel(isolate());
+ Handle<JSGlobalPropertyCell> cell =
+ isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
+ RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
+ __ mov(ebx, cell);
- CallConstructStub stub(flags);
+ CallConstructStub stub(RECORD_CALL_TARGET);
__ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
context()->Plug(eax);
@@ -2653,7 +2607,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
- if (FLAG_debug_code) __ AbortIfSmi(eax);
+ __ AssertNotSmi(eax);
// Check whether this map has already been checked to be safe for default
// valueOf.
@@ -2669,45 +2623,51 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ j(equal, if_false);
// Look for valueOf symbol in the descriptor array, and indicate false if
- // found. The type is not checked, so if it is a transition it is a false
- // negative.
+ // found. Since we omit an enumeration index check, if it is added via a
+ // transition that shares its descriptor array, this is a false positive.
+ Label entry, loop, done;
+
+ // Skip loop if no descriptors are valid.
+ __ NumberOfOwnDescriptors(ecx, ebx);
+ __ cmp(ecx, 0);
+ __ j(equal, &done);
+
__ LoadInstanceDescriptors(ebx, ebx);
- __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
- // ebx: descriptor array
- // ecx: length of descriptor array
+ // ebx: descriptor array.
+ // ecx: valid entries in the descriptor array.
// Calculate the end of the descriptor array.
STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize == 1);
STATIC_ASSERT(kPointerSize == 4);
- __ lea(ecx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
+ __ imul(ecx, ecx, DescriptorArray::kDescriptorSize);
+ __ lea(ecx, Operand(ebx, ecx, times_2, DescriptorArray::kFirstOffset));
// Calculate location of the first key name.
- __ add(ebx,
- Immediate(FixedArray::kHeaderSize +
- DescriptorArray::kFirstIndex * kPointerSize));
+ __ add(ebx, Immediate(DescriptorArray::kFirstOffset));
// Loop through all the keys in the descriptor array. If one of these is the
// symbol valueOf the result is false.
- Label entry, loop;
__ jmp(&entry);
__ bind(&loop);
__ mov(edx, FieldOperand(ebx, 0));
__ cmp(edx, FACTORY->value_of_symbol());
__ j(equal, if_false);
- __ add(ebx, Immediate(kPointerSize));
+ __ add(ebx, Immediate(DescriptorArray::kDescriptorSize * kPointerSize));
__ bind(&entry);
__ cmp(ebx, ecx);
__ j(not_equal, &loop);
+ __ bind(&done);
+
// Reload map as register ebx was used as temporary above.
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
- // If a valueOf property is not found on the object check that it's
+ // If a valueOf property is not found on the object check that its
// prototype is the un-modified String prototype. If not result is false.
__ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
__ JumpIfSmi(ecx, if_false);
__ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
- __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ mov(edx,
- FieldOperand(edx, GlobalObject::kGlobalContextOffset));
+ FieldOperand(edx, GlobalObject::kNativeContextOffset));
__ cmp(ecx,
ContextOperand(edx,
Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
@@ -2853,7 +2813,7 @@ void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
// parameter count in eax.
VisitForAccumulatorValue(args->at(0));
__ mov(edx, eax);
- __ SafeSet(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
+ __ Set(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
__ CallStub(&stub);
context()->Plug(eax);
@@ -2865,7 +2825,7 @@ void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
Label exit;
// Get the number of formal parameters.
- __ SafeSet(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
+ __ Set(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
// Check if the calling frame is an arguments adaptor frame.
__ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
@@ -2878,7 +2838,7 @@ void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
__ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
__ bind(&exit);
- if (FLAG_debug_code) __ AbortIfNotSmi(eax);
+ __ AssertSmi(eax);
context()->Plug(eax);
}
@@ -2982,8 +2942,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) {
__ bind(&heapnumber_allocated);
__ PrepareCallCFunction(1, ebx);
- __ mov(eax, ContextOperand(context_register(), Context::GLOBAL_INDEX));
- __ mov(eax, FieldOperand(eax, GlobalObject::kGlobalContextOffset));
+ __ mov(eax, ContextOperand(context_register(), Context::GLOBAL_OBJECT_INDEX));
+ __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset));
__ mov(Operand(esp, 0), eax);
__ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
@@ -3070,19 +3030,18 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0)); // Load the object.
- Label runtime, done;
+ Label runtime, done, not_date_object;
Register object = eax;
Register result = eax;
Register scratch = ecx;
-#ifdef DEBUG
- __ AbortIfSmi(object);
+ __ JumpIfSmi(object, &not_date_object);
__ CmpObjectType(object, JS_DATE_TYPE, scratch);
- __ Assert(equal, "Trying to get date field from non-date.");
-#endif
+ __ j(not_equal, &not_date_object);
if (index->value() == 0) {
__ mov(result, FieldOperand(object, JSDate::kValueOffset));
+ __ jmp(&done);
} else {
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
@@ -3098,8 +3057,12 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
__ mov(Operand(esp, 0), object);
__ mov(Operand(esp, 1 * kPointerSize), Immediate(index));
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
- __ bind(&done);
+ __ jmp(&done);
}
+
+ __ bind(&not_date_object);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
+ __ bind(&done);
context()->Plug(result);
}
@@ -3370,10 +3333,11 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
- // Check for proxy.
- Label proxy, done;
- __ CmpObjectType(eax, JS_FUNCTION_PROXY_TYPE, ebx);
- __ j(equal, &proxy);
+ Label runtime, done;
+ // Check for non-function argument (including proxy).
+ __ JumpIfSmi(eax, &runtime);
+ __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
+ __ j(not_equal, &runtime);
// InvokeFunction requires the function in edi. Move it in there.
__ mov(edi, result_register());
@@ -3383,7 +3347,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
__ jmp(&done);
- __ bind(&proxy);
+ __ bind(&runtime);
__ push(eax);
__ CallRuntime(Runtime::kCall, args->length());
__ bind(&done);
@@ -3413,7 +3377,7 @@ void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
Handle<FixedArray> jsfunction_result_caches(
- isolate()->global_context()->jsfunction_result_caches());
+ isolate()->native_context()->jsfunction_result_caches());
if (jsfunction_result_caches->length() <= cache_id) {
__ Abort("Attempt to use undefined cache.");
__ mov(eax, isolate()->factory()->undefined_value());
@@ -3426,9 +3390,9 @@ void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
Register key = eax;
Register cache = ebx;
Register tmp = ecx;
- __ mov(cache, ContextOperand(esi, Context::GLOBAL_INDEX));
+ __ mov(cache, ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX));
__ mov(cache,
- FieldOperand(cache, GlobalObject::kGlobalContextOffset));
+ FieldOperand(cache, GlobalObject::kNativeContextOffset));
__ mov(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX));
__ mov(cache,
FieldOperand(cache, FixedArray::OffsetOfElementAt(cache_id)));
@@ -3498,9 +3462,7 @@ void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0));
- if (FLAG_debug_code) {
- __ AbortIfNotString(eax);
- }
+ __ AssertString(eax);
Label materialize_true, materialize_false;
Label* if_true = NULL;
@@ -3523,9 +3485,7 @@ void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
ASSERT(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
- if (FLAG_debug_code) {
- __ AbortIfNotString(eax);
- }
+ __ AssertString(eax);
__ mov(eax, FieldOperand(eax, String::kHashFieldOffset));
__ IndexFromHash(eax, eax);
@@ -3599,7 +3559,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
// Loop condition: while (index < length).
// Live loop registers: index, array_length, string,
// scratch, string_length, elements.
- if (FLAG_debug_code) {
+ if (generate_debug_code_) {
__ cmp(index, array_length);
__ Assert(less, "No empty arrays here in EmitFastAsciiArrayJoin");
}
@@ -3827,7 +3787,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
- CallIC(ic, mode, expr->id());
+ CallIC(ic, mode, expr->CallRuntimeFeedbackId());
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
} else {
@@ -3985,7 +3945,8 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
// accumulator register eax.
VisitForAccumulatorValue(expr->expression());
SetSourcePosition(expr->position());
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->UnaryOperationFeedbackId());
context()->Plug(eax);
}
@@ -4043,7 +4004,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == VARIABLE) {
PrepareForBailout(expr->expression(), TOS_REG);
} else {
- PrepareForBailoutForId(expr->CountId(), TOS_REG);
+ PrepareForBailoutForId(prop->LoadId(), TOS_REG);
}
// Call ToNumber only if operand is not a smi.
@@ -4106,7 +4067,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ mov(edx, eax);
__ mov(eax, Immediate(Smi::FromInt(1)));
BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4140,7 +4101,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
if (!context()->IsEffect()) {
@@ -4157,7 +4118,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
// Result is on the stack
@@ -4365,7 +4326,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CompareIC::GetUninitialized(op);
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
@@ -4447,7 +4408,7 @@ void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
Scope* declaration_scope = scope()->DeclarationScope();
if (declaration_scope->is_global_scope() ||
declaration_scope->is_module_scope()) {
- // Contexts nested in the global context have a canonical empty function
+ // Contexts nested in the native context have a canonical empty function
// as their closure, not the anonymous closure containing the global
// code. Pass a smi sentinel and let the runtime look up the empty
// function.
@@ -4489,6 +4450,7 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference has_pending_message =
ExternalReference::address_of_has_pending_message(isolate());
__ mov(edx, Operand::StaticVariable(has_pending_message));
+ __ SmiTag(edx);
__ push(edx);
ExternalReference pending_message_script =
@@ -4507,6 +4469,7 @@ void FullCodeGenerator::ExitFinallyBlock() {
__ mov(Operand::StaticVariable(pending_message_script), edx);
__ pop(edx);
+ __ SmiUntag(edx);
ExternalReference has_pending_message =
ExternalReference::address_of_has_pending_message(isolate());
__ mov(Operand::StaticVariable(has_pending_message), edx);
@@ -4554,7 +4517,6 @@ FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
return previous_;
}
-
#undef __
} } // namespace v8::internal
diff --git a/deps/v8/src/ia32/ic-ia32.cc b/deps/v8/src/ia32/ic-ia32.cc
index a091ff1aa..dae3bbd63 100644
--- a/deps/v8/src/ia32/ic-ia32.cc
+++ b/deps/v8/src/ia32/ic-ia32.cc
@@ -747,6 +747,125 @@ void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
}
+static void KeyedStoreGenerateGenericHelper(
+ MacroAssembler* masm,
+ Label* fast_object,
+ Label* fast_double,
+ Label* slow,
+ KeyedStoreCheckMap check_map,
+ KeyedStoreIncrementLength increment_length) {
+ Label transition_smi_elements;
+ Label finish_object_store, non_double_value, transition_double_elements;
+ Label fast_double_without_map_check;
+ // eax: value
+ // ecx: key (a smi)
+ // edx: receiver
+ // ebx: FixedArray receiver->elements
+ // edi: receiver map
+ // Fast case: Do the store, could either Object or double.
+ __ bind(fast_object);
+ if (check_map == kCheckMap) {
+ __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset));
+ __ cmp(edi, masm->isolate()->factory()->fixed_array_map());
+ __ j(not_equal, fast_double);
+ }
+ // Smi stores don't require further checks.
+ Label non_smi_value;
+ __ JumpIfNotSmi(eax, &non_smi_value);
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ add(FieldOperand(edx, JSArray::kLengthOffset),
+ Immediate(Smi::FromInt(1)));
+ }
+ // It's irrelevant whether array is smi-only or not when writing a smi.
+ __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
+ __ ret(0);
+
+ __ bind(&non_smi_value);
+ // Escape to elements kind transition case.
+ __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
+ __ CheckFastObjectElements(edi, &transition_smi_elements);
+
+ // Fast elements array, store the value to the elements backing store.
+ __ bind(&finish_object_store);
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ add(FieldOperand(edx, JSArray::kLengthOffset),
+ Immediate(Smi::FromInt(1)));
+ }
+ __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
+ // Update write barrier for the elements array address.
+ __ mov(edx, eax); // Preserve the value which is returned.
+ __ RecordWriteArray(
+ ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+ __ ret(0);
+
+ __ bind(fast_double);
+ if (check_map == kCheckMap) {
+ // Check for fast double array case. If this fails, call through to the
+ // runtime.
+ __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map());
+ __ j(not_equal, slow);
+ // If the value is a number, store it as a double in the FastDoubleElements
+ // array.
+ }
+ __ bind(&fast_double_without_map_check);
+ __ StoreNumberToDoubleElements(eax, ebx, ecx, edi, xmm0,
+ &transition_double_elements, false);
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ add(FieldOperand(edx, JSArray::kLengthOffset),
+ Immediate(Smi::FromInt(1)));
+ }
+ __ ret(0);
+
+ __ bind(&transition_smi_elements);
+ __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
+
+ // Transition the array appropriately depending on the value type.
+ __ CheckMap(eax,
+ masm->isolate()->factory()->heap_number_map(),
+ &non_double_value,
+ DONT_DO_SMI_CHECK);
+
+ // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS
+ // and complete the store.
+ __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
+ FAST_DOUBLE_ELEMENTS,
+ ebx,
+ edi,
+ slow);
+ ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
+ __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ __ jmp(&fast_double_without_map_check);
+
+ __ bind(&non_double_value);
+ // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
+ __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
+ FAST_ELEMENTS,
+ ebx,
+ edi,
+ slow);
+ ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
+ __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ __ jmp(&finish_object_store);
+
+ __ bind(&transition_double_elements);
+ // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
+ // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
+ // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
+ __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
+ __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
+ FAST_ELEMENTS,
+ ebx,
+ edi,
+ slow);
+ ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
+ __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ __ jmp(&finish_object_store);
+}
+
+
void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
StrictModeFlag strict_mode) {
// ----------- S t a t e -------------
@@ -755,10 +874,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
- Label slow, fast_object_with_map_check, fast_object_without_map_check;
- Label fast_double_with_map_check, fast_double_without_map_check;
- Label check_if_double_array, array, extra, transition_smi_elements;
- Label finish_object_store, non_double_value, transition_double_elements;
+ Label slow, fast_object, fast_object_grow;
+ Label fast_double, fast_double_grow;
+ Label array, extra, check_if_double_array;
// Check that the object isn't a smi.
__ JumpIfSmi(edx, &slow);
@@ -785,7 +903,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
__ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
// Check array bounds. Both the key and the length of FixedArray are smis.
__ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
- __ j(below, &fast_object_with_map_check);
+ __ j(below, &fast_object);
// Slow case: call runtime.
__ bind(&slow);
@@ -808,18 +926,12 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
__ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset));
__ cmp(edi, masm->isolate()->factory()->fixed_array_map());
__ j(not_equal, &check_if_double_array);
- // Add 1 to receiver->length, and go to common element store code for Objects.
- __ add(FieldOperand(edx, JSArray::kLengthOffset),
- Immediate(Smi::FromInt(1)));
- __ jmp(&fast_object_without_map_check);
+ __ jmp(&fast_object_grow);
__ bind(&check_if_double_array);
__ cmp(edi, masm->isolate()->factory()->fixed_double_array_map());
__ j(not_equal, &slow);
- // Add 1 to receiver->length, and go to common element store code for doubles.
- __ add(FieldOperand(edx, JSArray::kLengthOffset),
- Immediate(Smi::FromInt(1)));
- __ jmp(&fast_double_without_map_check);
+ __ jmp(&fast_double_grow);
// Array case: Get the length and the elements array from the JS
// array. Check that the array is in fast mode (and writable); if it
@@ -836,94 +948,10 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
__ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
__ j(above_equal, &extra);
- // Fast case: Do the store, could either Object or double.
- __ bind(&fast_object_with_map_check);
- // eax: value
- // ecx: key (a smi)
- // edx: receiver
- // ebx: FixedArray receiver->elements
- // edi: receiver map
- __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset));
- __ cmp(edi, masm->isolate()->factory()->fixed_array_map());
- __ j(not_equal, &fast_double_with_map_check);
- __ bind(&fast_object_without_map_check);
- // Smi stores don't require further checks.
- Label non_smi_value;
- __ JumpIfNotSmi(eax, &non_smi_value);
- // It's irrelevant whether array is smi-only or not when writing a smi.
- __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
- __ ret(0);
-
- __ bind(&non_smi_value);
- // Escape to elements kind transition case.
- __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
- __ CheckFastObjectElements(edi, &transition_smi_elements);
-
- // Fast elements array, store the value to the elements backing store.
- __ bind(&finish_object_store);
- __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
- // Update write barrier for the elements array address.
- __ mov(edx, eax); // Preserve the value which is returned.
- __ RecordWriteArray(
- ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
- __ ret(0);
-
- __ bind(&fast_double_with_map_check);
- // Check for fast double array case. If this fails, call through to the
- // runtime.
- __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map());
- __ j(not_equal, &slow);
- __ bind(&fast_double_without_map_check);
- // If the value is a number, store it as a double in the FastDoubleElements
- // array.
- __ StoreNumberToDoubleElements(eax, ebx, ecx, edx, xmm0,
- &transition_double_elements, false);
- __ ret(0);
-
- __ bind(&transition_smi_elements);
- __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
-
- // Transition the array appropriately depending on the value type.
- __ CheckMap(eax,
- masm->isolate()->factory()->heap_number_map(),
- &non_double_value,
- DONT_DO_SMI_CHECK);
-
- // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS
- // and complete the store.
- __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
- FAST_DOUBLE_ELEMENTS,
- ebx,
- edi,
- &slow);
- ElementsTransitionGenerator::GenerateSmiToDouble(masm, &slow);
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
- __ jmp(&fast_double_without_map_check);
-
- __ bind(&non_double_value);
- // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
- __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
- FAST_ELEMENTS,
- ebx,
- edi,
- &slow);
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
- __ jmp(&finish_object_store);
-
- __ bind(&transition_double_elements);
- // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
- // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
- // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
- __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
- __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
- FAST_ELEMENTS,
- ebx,
- edi,
- &slow);
- ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow);
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
- __ jmp(&finish_object_store);
+ KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
+ &slow, kCheckMap, kDontIncrementLength);
+ KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
+ &slow, kDontCheckMap, kIncrementLength);
}
@@ -943,7 +971,7 @@ void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC,
extra_state,
- NORMAL,
+ Code::NORMAL,
argc);
Isolate* isolate = masm->isolate();
isolate->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, eax);
diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.cc b/deps/v8/src/ia32/lithium-codegen-ia32.cc
index 2c6a916b0..32c66a05f 100644
--- a/deps/v8/src/ia32/lithium-codegen-ia32.cc
+++ b/deps/v8/src/ia32/lithium-codegen-ia32.cc
@@ -81,7 +81,7 @@ bool LCodeGen::GenerateCode() {
dynamic_frame_alignment_ = (chunk()->num_double_slots() > 2 &&
!chunk()->graph()->is_recursive()) ||
- info()->osr_ast_id() != AstNode::kNoNumber;
+ !info()->osr_ast_id().IsNone();
return GeneratePrologue() &&
GenerateBody() &&
@@ -99,17 +99,8 @@ void LCodeGen::FinishCode(Handle<Code> code) {
}
-void LCodeGen::Abort(const char* format, ...) {
- if (FLAG_trace_bailout) {
- SmartArrayPointer<char> name(
- info()->shared_info()->DebugName()->ToCString());
- PrintF("Aborting LCodeGen in @\"%s\": ", *name);
- va_list arguments;
- va_start(arguments, format);
- OS::VPrint(format, arguments);
- va_end(arguments);
- PrintF("\n");
- }
+void LCodeGen::Abort(const char* reason) {
+ info()->set_bailout_reason(reason);
status_ = ABORTED;
}
@@ -135,6 +126,8 @@ void LCodeGen::Comment(const char* format, ...) {
bool LCodeGen::GeneratePrologue() {
ASSERT(is_generating());
+ ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+
#ifdef DEBUG
if (strlen(FLAG_stop_at) > 0 &&
info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
@@ -360,24 +353,24 @@ XMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
int LCodeGen::ToInteger32(LConstantOperand* op) const {
- Handle<Object> value = chunk_->LookupLiteral(op);
+ HConstant* constant = chunk_->LookupConstant(op);
ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32());
- ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) ==
- value->Number());
- return static_cast<int32_t>(value->Number());
+ ASSERT(constant->HasInteger32Value());
+ return constant->Integer32Value();
}
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
- Handle<Object> literal = chunk_->LookupLiteral(op);
+ HConstant* constant = chunk_->LookupConstant(op);
ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
- return literal;
+ return constant->handle();
}
double LCodeGen::ToDouble(LConstantOperand* op) const {
- Handle<Object> value = chunk_->LookupLiteral(op);
- return value->Number();
+ HConstant* constant = chunk_->LookupConstant(op);
+ ASSERT(constant->HasDoubleValue());
+ return constant->DoubleValue();
}
@@ -411,7 +404,9 @@ Operand LCodeGen::HighOperand(LOperand* op) {
void LCodeGen::WriteTranslation(LEnvironment* environment,
- Translation* translation) {
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count) {
if (environment == NULL) return;
// The translation includes one command per value in the environment.
@@ -419,8 +414,20 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
// The output frame height does not include the parameters.
int height = translation_size - environment->parameter_count();
- WriteTranslation(environment->outer(), translation);
- int closure_id = DefineDeoptimizationLiteral(environment->closure());
+ // Function parameters are arguments to the outermost environment. The
+ // arguments index points to the first element of a sequence of tagged
+ // values on the stack that represent the arguments. This needs to be
+ // kept in sync with the LArgumentsElements implementation.
+ *arguments_index = -environment->parameter_count();
+ *arguments_count = environment->parameter_count();
+
+ WriteTranslation(environment->outer(),
+ translation,
+ arguments_index,
+ arguments_count);
+ int closure_id = *info()->closure() != *environment->closure()
+ ? DefineDeoptimizationLiteral(environment->closure())
+ : Translation::kSelfLiteralId;
switch (environment->frame_type()) {
case JS_FUNCTION:
translation->BeginJSFrame(environment->ast_id(), closure_id, height);
@@ -428,12 +435,31 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
case JS_CONSTRUCT:
translation->BeginConstructStubFrame(closure_id, translation_size);
break;
+ case JS_GETTER:
+ ASSERT(translation_size == 1);
+ ASSERT(height == 0);
+ translation->BeginGetterStubFrame(closure_id);
+ break;
+ case JS_SETTER:
+ ASSERT(translation_size == 2);
+ ASSERT(height == 0);
+ translation->BeginSetterStubFrame(closure_id);
+ break;
case ARGUMENTS_ADAPTOR:
translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
break;
- default:
- UNREACHABLE();
}
+
+ // Inlined frames which push their arguments cause the index to be
+ // bumped and another stack area to be used for materialization.
+ if (environment->entry() != NULL &&
+ environment->entry()->arguments_pushed()) {
+ *arguments_index = *arguments_index < 0
+ ? GetStackSlotCount()
+ : *arguments_index + *arguments_count;
+ *arguments_count = environment->entry()->arguments_count() + 1;
+ }
+
for (int i = 0; i < translation_size; ++i) {
LOperand* value = environment->values()->at(i);
// spilled_registers_ and spilled_double_registers_ are either
@@ -444,7 +470,10 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
translation->MarkDuplicate();
AddToTranslation(translation,
environment->spilled_registers()[value->index()],
- environment->HasTaggedValueAt(i));
+ environment->HasTaggedValueAt(i),
+ environment->HasUint32ValueAt(i),
+ *arguments_index,
+ *arguments_count);
} else if (
value->IsDoubleRegister() &&
environment->spilled_double_registers()[value->index()] != NULL) {
@@ -452,26 +481,39 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
AddToTranslation(
translation,
environment->spilled_double_registers()[value->index()],
- false);
+ false,
+ false,
+ *arguments_index,
+ *arguments_count);
}
}
- AddToTranslation(translation, value, environment->HasTaggedValueAt(i));
+ AddToTranslation(translation,
+ value,
+ environment->HasTaggedValueAt(i),
+ environment->HasUint32ValueAt(i),
+ *arguments_index,
+ *arguments_count);
}
}
void LCodeGen::AddToTranslation(Translation* translation,
LOperand* op,
- bool is_tagged) {
+ bool is_tagged,
+ bool is_uint32,
+ int arguments_index,
+ int arguments_count) {
if (op == NULL) {
// TODO(twuerthinger): Introduce marker operands to indicate that this value
// is not present and must be reconstructed from the deoptimizer. Currently
// this is only used for the arguments object.
- translation->StoreArgumentsObject();
+ translation->StoreArgumentsObject(arguments_index, arguments_count);
} else if (op->IsStackSlot()) {
if (is_tagged) {
translation->StoreStackSlot(op->index());
+ } else if (is_uint32) {
+ translation->StoreUint32StackSlot(op->index());
} else {
translation->StoreInt32StackSlot(op->index());
}
@@ -485,6 +527,8 @@ void LCodeGen::AddToTranslation(Translation* translation,
Register reg = ToRegister(op);
if (is_tagged) {
translation->StoreRegister(reg);
+ } else if (is_uint32) {
+ translation->StoreUint32Register(reg);
} else {
translation->StoreInt32Register(reg);
}
@@ -492,8 +536,8 @@ void LCodeGen::AddToTranslation(Translation* translation,
XMMRegister reg = ToDoubleRegister(op);
translation->StoreDoubleRegister(reg);
} else if (op->IsConstantOperand()) {
- Handle<Object> literal = chunk()->LookupLiteral(LConstantOperand::cast(op));
- int src_index = DefineDeoptimizationLiteral(literal);
+ HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
+ int src_index = DefineDeoptimizationLiteral(constant->handle());
translation->StoreLiteral(src_index);
} else {
UNREACHABLE();
@@ -552,9 +596,9 @@ void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
} else if (context->IsStackSlot()) {
__ mov(esi, ToOperand(context));
} else if (context->IsConstantOperand()) {
- Handle<Object> literal =
- chunk_->LookupLiteral(LConstantOperand::cast(context));
- __ LoadHeapObject(esi, Handle<Context>::cast(literal));
+ HConstant* constant =
+ chunk_->LookupConstant(LConstantOperand::cast(context));
+ __ LoadHeapObject(esi, Handle<Context>::cast(constant->handle()));
} else {
UNREACHABLE();
}
@@ -583,15 +627,16 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(
int frame_count = 0;
int jsframe_count = 0;
+ int args_index = 0;
+ int args_count = 0;
for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
++frame_count;
if (e->frame_type() == JS_FUNCTION) {
++jsframe_count;
}
}
- Translation translation(&translations_, frame_count, jsframe_count,
- zone());
- WriteTranslation(environment, &translation);
+ Translation translation(&translations_, frame_count, jsframe_count, zone());
+ WriteTranslation(environment, &translation, &args_index, &args_count);
int deoptimization_index = deoptimizations_.length();
int pc_offset = masm()->pc_offset();
environment->Register(deoptimization_index,
@@ -674,13 +719,13 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
}
data->SetLiteralArray(*literals);
- data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id()));
+ data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt()));
data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
// Populate the deoptimization entries.
for (int i = 0; i < length; i++) {
LEnvironment* env = deoptimizations_[i];
- data->SetAstId(i, Smi::FromInt(env->ast_id()));
+ data->SetAstId(i, env->ast_id());
data->SetTranslationIndex(i, Smi::FromInt(env->translation_index()));
data->SetArgumentsStackHeight(i,
Smi::FromInt(env->arguments_stack_height()));
@@ -864,7 +909,7 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
void LCodeGen::DoModI(LModI* instr) {
if (instr->hydrogen()->HasPowerOf2Divisor()) {
- Register dividend = ToRegister(instr->InputAt(0));
+ Register dividend = ToRegister(instr->left());
int32_t divisor =
HConstant::cast(instr->hydrogen()->right())->Integer32Value();
@@ -888,8 +933,8 @@ void LCodeGen::DoModI(LModI* instr) {
__ bind(&done);
} else {
Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
- Register left_reg = ToRegister(instr->InputAt(0));
- Register right_reg = ToRegister(instr->InputAt(1));
+ Register left_reg = ToRegister(instr->left());
+ Register right_reg = ToRegister(instr->right());
Register result_reg = ToRegister(instr->result());
ASSERT(left_reg.is(eax));
@@ -919,7 +964,7 @@ void LCodeGen::DoModI(LModI* instr) {
__ j(less, &remainder_eq_dividend, Label::kNear);
// Check if the divisor is a PowerOfTwo integer.
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
__ mov(scratch, right_reg);
__ sub(Operand(scratch), Immediate(1));
__ test(scratch, Operand(right_reg));
@@ -975,11 +1020,11 @@ void LCodeGen::DoModI(LModI* instr) {
void LCodeGen::DoDivI(LDivI* instr) {
- LOperand* right = instr->InputAt(1);
+ LOperand* right = instr->right();
ASSERT(ToRegister(instr->result()).is(eax));
- ASSERT(ToRegister(instr->InputAt(0)).is(eax));
- ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
- ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
+ ASSERT(ToRegister(instr->left()).is(eax));
+ ASSERT(!ToRegister(instr->right()).is(eax));
+ ASSERT(!ToRegister(instr->right()).is(edx));
Register left_reg = eax;
@@ -1020,12 +1065,115 @@ void LCodeGen::DoDivI(LDivI* instr) {
}
+void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
+ ASSERT(instr->right()->IsConstantOperand());
+
+ Register dividend = ToRegister(instr->left());
+ int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
+ Register result = ToRegister(instr->result());
+
+ switch (divisor) {
+ case 0:
+ DeoptimizeIf(no_condition, instr->environment());
+ return;
+
+ case 1:
+ __ Move(result, dividend);
+ return;
+
+ case -1:
+ __ Move(result, dividend);
+ __ neg(result);
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ DeoptimizeIf(zero, instr->environment());
+ }
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ DeoptimizeIf(overflow, instr->environment());
+ }
+ return;
+ }
+
+ uint32_t divisor_abs = abs(divisor);
+ if (IsPowerOf2(divisor_abs)) {
+ int32_t power = WhichPowerOf2(divisor_abs);
+ if (divisor < 0) {
+ // Input[dividend] is clobbered.
+ // The sequence is tedious because neg(dividend) might overflow.
+ __ mov(result, dividend);
+ __ sar(dividend, 31);
+ __ neg(result);
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ DeoptimizeIf(zero, instr->environment());
+ }
+ __ shl(dividend, 32 - power);
+ __ sar(result, power);
+ __ not_(dividend);
+ // Clear result.sign if dividend.sign is set.
+ __ and_(result, dividend);
+ } else {
+ __ Move(result, dividend);
+ __ sar(result, power);
+ }
+ } else {
+ ASSERT(ToRegister(instr->left()).is(eax));
+ ASSERT(ToRegister(instr->result()).is(edx));
+ Register scratch = ToRegister(instr->temp());
+
+ // Find b which: 2^b < divisor_abs < 2^(b+1).
+ unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
+ unsigned shift = 32 + b; // Precision +1bit (effectively).
+ double multiplier_f =
+ static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs;
+ int64_t multiplier;
+ if (multiplier_f - floor(multiplier_f) < 0.5) {
+ multiplier = static_cast<int64_t>(floor(multiplier_f));
+ } else {
+ multiplier = static_cast<int64_t>(floor(multiplier_f)) + 1;
+ }
+ // The multiplier is a uint32.
+ ASSERT(multiplier > 0 &&
+ multiplier < (static_cast<int64_t>(1) << 32));
+ __ mov(scratch, dividend);
+ if (divisor < 0 &&
+ instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ __ test(dividend, dividend);
+ DeoptimizeIf(zero, instr->environment());
+ }
+ __ mov(edx, static_cast<int32_t>(multiplier));
+ __ imul(edx);
+ if (static_cast<int32_t>(multiplier) < 0) {
+ __ add(edx, scratch);
+ }
+ Register reg_lo = eax;
+ Register reg_byte_scratch = scratch;
+ if (!reg_byte_scratch.is_byte_register()) {
+ __ xchg(reg_lo, reg_byte_scratch);
+ reg_lo = scratch;
+ reg_byte_scratch = eax;
+ }
+ if (divisor < 0) {
+ __ xor_(reg_byte_scratch, reg_byte_scratch);
+ __ cmp(reg_lo, 0x40000000);
+ __ setcc(above, reg_byte_scratch);
+ __ neg(edx);
+ __ sub(edx, reg_byte_scratch);
+ } else {
+ __ xor_(reg_byte_scratch, reg_byte_scratch);
+ __ cmp(reg_lo, 0xC0000000);
+ __ setcc(above_equal, reg_byte_scratch);
+ __ add(edx, reg_byte_scratch);
+ }
+ __ sar(edx, shift - 32);
+ }
+}
+
+
void LCodeGen::DoMulI(LMulI* instr) {
- Register left = ToRegister(instr->InputAt(0));
- LOperand* right = instr->InputAt(1);
+ Register left = ToRegister(instr->left());
+ LOperand* right = instr->right();
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- __ mov(ToRegister(instr->TempAt(0)), left);
+ __ mov(ToRegister(instr->temp()), left);
}
if (right->IsConstantOperand()) {
@@ -1086,12 +1234,15 @@ void LCodeGen::DoMulI(LMulI* instr) {
__ test(left, Operand(left));
__ j(not_zero, &done, Label::kNear);
if (right->IsConstantOperand()) {
- if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
+ if (ToInteger32(LConstantOperand::cast(right)) < 0) {
DeoptimizeIf(no_condition, instr->environment());
+ } else if (ToInteger32(LConstantOperand::cast(right)) == 0) {
+ __ cmp(ToRegister(instr->temp()), Immediate(0));
+ DeoptimizeIf(less, instr->environment());
}
} else {
// Test the non-zero operand for negative sign.
- __ or_(ToRegister(instr->TempAt(0)), ToOperand(right));
+ __ or_(ToRegister(instr->temp()), ToOperand(right));
DeoptimizeIf(sign, instr->environment());
}
__ bind(&done);
@@ -1100,8 +1251,8 @@ void LCodeGen::DoMulI(LMulI* instr) {
void LCodeGen::DoBitI(LBitI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
ASSERT(left->Equals(instr->result()));
ASSERT(left->IsRegister());
@@ -1141,8 +1292,8 @@ void LCodeGen::DoBitI(LBitI* instr) {
void LCodeGen::DoShiftI(LShiftI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
ASSERT(left->Equals(instr->result()));
ASSERT(left->IsRegister());
if (right->IsRegister()) {
@@ -1197,8 +1348,8 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
void LCodeGen::DoSubI(LSubI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
ASSERT(left->Equals(instr->result()));
if (right->IsConstantOperand()) {
@@ -1227,7 +1378,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
if (BitCast<uint64_t, double>(v) == 0) {
__ xorps(res, res);
} else {
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
uint64_t int_val = BitCast<uint64_t, double>(v);
int32_t lower = static_cast<int32_t>(int_val);
int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
@@ -1270,7 +1421,7 @@ void LCodeGen::DoConstantT(LConstantT* instr) {
void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
+ Register array = ToRegister(instr->value());
__ mov(result, FieldOperand(array, JSArray::kLengthOffset));
}
@@ -1278,14 +1429,21 @@ void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
void LCodeGen::DoFixedArrayBaseLength(
LFixedArrayBaseLength* instr) {
Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
+ Register array = ToRegister(instr->value());
__ mov(result, FieldOperand(array, FixedArrayBase::kLengthOffset));
}
+void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
+ Register result = ToRegister(instr->result());
+ Register map = ToRegister(instr->value());
+ __ EnumLength(result, map);
+}
+
+
void LCodeGen::DoElementsKind(LElementsKind* instr) {
Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
// Load map into |result|.
__ mov(result, FieldOperand(input, HeapObject::kMapOffset));
@@ -1299,9 +1457,9 @@ void LCodeGen::DoElementsKind(LElementsKind* instr) {
void LCodeGen::DoValueOf(LValueOf* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
- Register map = ToRegister(instr->TempAt(0));
+ Register map = ToRegister(instr->temp());
ASSERT(input.is(result));
Label done;
@@ -1318,19 +1476,18 @@ void LCodeGen::DoValueOf(LValueOf* instr) {
void LCodeGen::DoDateField(LDateField* instr) {
- Register object = ToRegister(instr->InputAt(0));
+ Register object = ToRegister(instr->date());
Register result = ToRegister(instr->result());
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
Smi* index = instr->index();
Label runtime, done;
ASSERT(object.is(result));
ASSERT(object.is(eax));
-#ifdef DEBUG
- __ AbortIfSmi(object);
+ __ test(object, Immediate(kSmiTagMask));
+ DeoptimizeIf(zero, instr->environment());
__ CmpObjectType(object, JS_DATE_TYPE, scratch);
- __ Assert(equal, "Trying to get date field from non-date.");
-#endif
+ DeoptimizeIf(not_equal, instr->environment());
if (index->value() == 0) {
__ mov(result, FieldOperand(object, JSDate::kValueOffset));
@@ -1355,7 +1512,7 @@ void LCodeGen::DoDateField(LDateField* instr) {
void LCodeGen::DoBitNotI(LBitNotI* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->Equals(instr->result()));
__ not_(ToRegister(input));
}
@@ -1374,8 +1531,8 @@ void LCodeGen::DoThrow(LThrow* instr) {
void LCodeGen::DoAddI(LAddI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
ASSERT(left->Equals(instr->result()));
if (right->IsConstantOperand()) {
@@ -1390,9 +1547,70 @@ void LCodeGen::DoAddI(LAddI* instr) {
}
+void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
+ ASSERT(left->Equals(instr->result()));
+ HMathMinMax::Operation operation = instr->hydrogen()->operation();
+ if (instr->hydrogen()->representation().IsInteger32()) {
+ Label return_left;
+ Condition condition = (operation == HMathMinMax::kMathMin)
+ ? less_equal
+ : greater_equal;
+ if (right->IsConstantOperand()) {
+ Operand left_op = ToOperand(left);
+ Immediate right_imm = ToInteger32Immediate(right);
+ __ cmp(left_op, right_imm);
+ __ j(condition, &return_left, Label::kNear);
+ __ mov(left_op, right_imm);
+ } else {
+ Register left_reg = ToRegister(left);
+ Operand right_op = ToOperand(right);
+ __ cmp(left_reg, right_op);
+ __ j(condition, &return_left, Label::kNear);
+ __ mov(left_reg, right_op);
+ }
+ __ bind(&return_left);
+ } else {
+ ASSERT(instr->hydrogen()->representation().IsDouble());
+ Label check_nan_left, check_zero, return_left, return_right;
+ Condition condition = (operation == HMathMinMax::kMathMin) ? below : above;
+ XMMRegister left_reg = ToDoubleRegister(left);
+ XMMRegister right_reg = ToDoubleRegister(right);
+ __ ucomisd(left_reg, right_reg);
+ __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN.
+ __ j(equal, &check_zero, Label::kNear); // left == right.
+ __ j(condition, &return_left, Label::kNear);
+ __ jmp(&return_right, Label::kNear);
+
+ __ bind(&check_zero);
+ XMMRegister xmm_scratch = xmm0;
+ __ xorps(xmm_scratch, xmm_scratch);
+ __ ucomisd(left_reg, xmm_scratch);
+ __ j(not_equal, &return_left, Label::kNear); // left == right != 0.
+ // At this point, both left and right are either 0 or -0.
+ if (operation == HMathMinMax::kMathMin) {
+ __ orpd(left_reg, right_reg);
+ } else {
+ // Since we operate on +0 and/or -0, addsd and andsd have the same effect.
+ __ addsd(left_reg, right_reg);
+ }
+ __ jmp(&return_left, Label::kNear);
+
+ __ bind(&check_nan_left);
+ __ ucomisd(left_reg, left_reg); // NaN check.
+ __ j(parity_even, &return_left, Label::kNear); // left == NaN.
+ __ bind(&return_right);
+ __ movsd(left_reg, right_reg);
+
+ __ bind(&return_left);
+ }
+}
+
+
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
- XMMRegister left = ToDoubleRegister(instr->InputAt(0));
- XMMRegister right = ToDoubleRegister(instr->InputAt(1));
+ XMMRegister left = ToDoubleRegister(instr->left());
+ XMMRegister right = ToDoubleRegister(instr->right());
XMMRegister result = ToDoubleRegister(instr->result());
// Modulo uses a fixed result register.
ASSERT(instr->op() == Token::MOD || left.is(result));
@@ -1478,17 +1696,17 @@ void LCodeGen::DoBranch(LBranch* instr) {
Representation r = instr->hydrogen()->value()->representation();
if (r.IsInteger32()) {
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
__ test(reg, Operand(reg));
EmitBranch(true_block, false_block, not_zero);
} else if (r.IsDouble()) {
- XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
+ XMMRegister reg = ToDoubleRegister(instr->value());
__ xorps(xmm0, xmm0);
__ ucomisd(reg, xmm0);
EmitBranch(true_block, false_block, not_equal);
} else {
ASSERT(r.IsTagged());
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
HType type = instr->hydrogen()->value()->type();
if (type.IsBoolean()) {
__ cmp(reg, factory()->true_value());
@@ -1536,7 +1754,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
Register map = no_reg; // Keep the compiler happy.
if (expected.NeedsMap()) {
- map = ToRegister(instr->TempAt(0));
+ map = ToRegister(instr->temp());
ASSERT(!map.is(reg));
__ mov(map, FieldOperand(reg, HeapObject::kMapOffset));
@@ -1629,8 +1847,8 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
Condition cc = TokenToCondition(instr->op(), instr->is_double());
@@ -1666,8 +1884,8 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
- Register left = ToRegister(instr->InputAt(0));
- Operand right = ToOperand(instr->InputAt(1));
+ Register left = ToRegister(instr->left());
+ Operand right = ToOperand(instr->right());
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -1677,7 +1895,7 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
- Register left = ToRegister(instr->InputAt(0));
+ Register left = ToRegister(instr->left());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1687,7 +1905,7 @@ void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
int false_block = chunk_->LookupDestination(instr->false_block_id());
// If the expression is known to be untagged or a smi, then it's definitely
@@ -1717,7 +1935,7 @@ void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
__ JumpIfSmi(reg, false_label);
// Check for undetectable objects by looking in the bit field in
// the map. The object has already been smi checked.
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
__ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
__ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
__ test(scratch, Immediate(1 << Map::kIsUndetectable));
@@ -1750,8 +1968,8 @@ Condition LCodeGen::EmitIsObject(Register input,
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1776,8 +1994,8 @@ Condition LCodeGen::EmitIsString(Register input,
void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1790,7 +2008,7 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
- Operand input = ToOperand(instr->InputAt(0));
+ Operand input = ToOperand(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1801,8 +2019,8 @@ void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register input = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1872,8 +2090,8 @@ static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register input = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1888,12 +2106,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
- if (FLAG_debug_code) {
- __ AbortIfNotString(input);
- }
+ __ AssertString(input);
__ mov(result, FieldOperand(input, String::kHashFieldOffset));
__ IndexFromHash(result, result);
@@ -1902,7 +2118,7 @@ void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
void LCodeGen::DoHasCachedArrayIndexAndBranch(
LHasCachedArrayIndexAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1979,9 +2195,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
- Register temp2 = ToRegister(instr->TempAt(1));
+ Register input = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
+ Register temp2 = ToRegister(instr->temp2());
Handle<String> class_name = instr->hydrogen()->class_name();
@@ -1998,7 +2214,7 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
int true_block = instr->true_block_id();
int false_block = instr->false_block_id();
@@ -2044,8 +2260,8 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
Label done, false_result;
- Register object = ToRegister(instr->InputAt(1));
- Register temp = ToRegister(instr->TempAt(0));
+ Register object = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
// A Smi is not an instance of anything.
__ JumpIfSmi(object, &false_result);
@@ -2054,7 +2270,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
// hole value will be patched to the last map/result pair generated by the
// instanceof stub.
Label cache_miss;
- Register map = ToRegister(instr->TempAt(0));
+ Register map = ToRegister(instr->temp());
__ mov(map, FieldOperand(object, HeapObject::kMapOffset));
__ bind(deferred->map_check()); // Label for calculating code patching.
Handle<JSGlobalPropertyCell> cache_cell =
@@ -2105,7 +2321,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
// register which is pushed last by PushSafepointRegisters as top of the
// stack is used to pass the offset to the location of the map check to
// the stub.
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0);
__ LoadHeapObject(InstanceofStub::right(), instr->function());
static const int kAdditionalDelta = 13;
@@ -2272,7 +2488,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
HType type = instr->hydrogen()->value()->type();
SmiCheck check_needed =
type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
int offset = Context::SlotOffset(instr->slot_index());
__ RecordWriteContextSlot(context,
offset,
@@ -2305,9 +2521,9 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
Handle<String> name,
LEnvironment* env) {
LookupResult lookup(isolate());
- type->LookupInDescriptors(NULL, *name, &lookup);
+ type->LookupDescriptor(NULL, *name, &lookup);
ASSERT(lookup.IsFound() || lookup.IsCacheable());
- if (lookup.IsFound() && lookup.type() == FIELD) {
+ if (lookup.IsField()) {
int index = lookup.GetLocalFieldIndexFromMap(*type);
int offset = index * kPointerSize;
if (index < 0) {
@@ -2319,7 +2535,7 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
__ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
__ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
}
- } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) {
+ } else if (lookup.IsConstantFunction()) {
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
__ LoadHeapObject(result, function);
} else {
@@ -2366,11 +2582,10 @@ static bool CompactEmit(SmallMapList* list,
Handle<Map> map = list->at(i);
// If the map has ElementsKind transitions, we will generate map checks
// for each kind in __ CompareMap(..., ALLOW_ELEMENTS_TRANSITION_MAPS).
- if (map->elements_transition_map() != NULL) return false;
+ if (map->HasElementsTransition()) return false;
LookupResult lookup(isolate);
- map->LookupInDescriptors(NULL, *name, &lookup);
- return lookup.IsFound() &&
- (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION);
+ map->LookupDescriptor(NULL, *name, &lookup);
+ return lookup.IsField() || lookup.IsConstantFunction();
}
@@ -2438,7 +2653,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
Register function = ToRegister(instr->function());
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
Register result = ToRegister(instr->result());
// Check that the function really is a function.
@@ -2480,7 +2695,7 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
void LCodeGen::DoLoadElements(LLoadElements* instr) {
Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->object());
__ mov(result, FieldOperand(input, JSObject::kElementsOffset));
if (FLAG_debug_code) {
Label done, ok, fail;
@@ -2516,7 +2731,7 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
void LCodeGen::DoLoadExternalArrayPointer(
LLoadExternalArrayPointer* instr) {
Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->object());
__ mov(result, FieldOperand(input,
ExternalArray::kExternalPointerOffset));
}
@@ -2527,12 +2742,9 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
Register length = ToRegister(instr->length());
Operand index = ToOperand(instr->index());
Register result = ToRegister(instr->result());
-
- __ sub(length, index);
- DeoptimizeIf(below_equal, instr->environment());
-
// There are two words between the frame pointer and the last argument.
// Subtracting from length accounts for one of them add one more.
+ __ sub(length, index);
__ mov(result, Operand(arguments, length, times_4, kPointerSize));
}
@@ -2544,6 +2756,7 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
__ mov(result,
BuildFastArrayOperand(instr->elements(),
instr->key(),
+ instr->hydrogen()->key()->representation(),
FAST_ELEMENTS,
FixedArray::kHeaderSize - kHeapObjectTag,
instr->additional_index()));
@@ -2570,6 +2783,7 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
sizeof(kHoleNanLower32);
Operand hole_check_operand = BuildFastArrayOperand(
instr->elements(), instr->key(),
+ instr->hydrogen()->key()->representation(),
FAST_DOUBLE_ELEMENTS,
offset,
instr->additional_index());
@@ -2580,6 +2794,7 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
Operand double_load_operand = BuildFastArrayOperand(
instr->elements(),
instr->key(),
+ instr->hydrogen()->key()->representation(),
FAST_DOUBLE_ELEMENTS,
FixedDoubleArray::kHeaderSize - kHeapObjectTag,
instr->additional_index());
@@ -2590,11 +2805,19 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
Operand LCodeGen::BuildFastArrayOperand(
LOperand* elements_pointer,
LOperand* key,
+ Representation key_representation,
ElementsKind elements_kind,
uint32_t offset,
uint32_t additional_index) {
Register elements_pointer_reg = ToRegister(elements_pointer);
int shift_size = ElementsKindToShiftSize(elements_kind);
+ // Even though the HLoad/StoreKeyedFastElement instructions force the input
+ // representation for the key to be an integer, the input gets replaced during
+ // bound check elimination with the index argument to the bounds check, which
+ // can be tagged, so that case must be handled here, too.
+ if (key_representation.IsTagged() && (shift_size >= 1)) {
+ shift_size -= kSmiTagSize;
+ }
if (key->IsConstantOperand()) {
int constant_value = ToInteger32(LConstantOperand::cast(key));
if (constant_value & 0xF0000000) {
@@ -2616,11 +2839,19 @@ Operand LCodeGen::BuildFastArrayOperand(
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) {
ElementsKind elements_kind = instr->elements_kind();
- Operand operand(BuildFastArrayOperand(instr->external_pointer(),
- instr->key(),
- elements_kind,
- 0,
- instr->additional_index()));
+ LOperand* key = instr->key();
+ if (!key->IsConstantOperand() &&
+ ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
+ elements_kind)) {
+ __ SmiUntag(ToRegister(key));
+ }
+ Operand operand(BuildFastArrayOperand(
+ instr->external_pointer(),
+ key,
+ instr->hydrogen()->key()->representation(),
+ elements_kind,
+ 0,
+ instr->additional_index()));
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
XMMRegister result(ToDoubleRegister(instr->result()));
__ movss(result, operand);
@@ -2648,11 +2879,10 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
break;
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ mov(result, operand);
- __ test(result, Operand(result));
- // TODO(danno): we could be more clever here, perhaps having a special
- // version of the stub that detects if the overflow case actually
- // happens, and generate code that returns a double rather than int.
- DeoptimizeIf(negative, instr->environment());
+ if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
+ __ test(result, Operand(result));
+ DeoptimizeIf(negative, instr->environment());
+ }
break;
case EXTERNAL_FLOAT_ELEMENTS:
case EXTERNAL_DOUBLE_ELEMENTS:
@@ -2711,7 +2941,7 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
- Operand elem = ToOperand(instr->InputAt(0));
+ Operand elem = ToOperand(instr->elements());
Register result = ToRegister(instr->result());
Label done;
@@ -2735,7 +2965,7 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
Register receiver = ToRegister(instr->receiver());
Register function = ToRegister(instr->function());
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
// If the receiver is null or undefined, we have to pass the global
// object as a receiver to normal functions. Values have to be
@@ -2748,12 +2978,12 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
__ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset),
1 << SharedFunctionInfo::kStrictModeBitWithinByte);
- __ j(not_equal, &receiver_ok, Label::kNear);
+ __ j(not_equal, &receiver_ok); // A near jump is not sufficient here!
// Do not transform the receiver to object for builtins.
__ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
1 << SharedFunctionInfo::kNativeBitWithinByte);
- __ j(not_equal, &receiver_ok, Label::kNear);
+ __ j(not_equal, &receiver_ok);
// Normal function. Replace undefined or null with global receiver.
__ cmp(receiver, factory()->null_value());
@@ -2773,7 +3003,7 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
// if it's better to use it than to explicitly fetch it from the context
// here.
__ mov(receiver, Operand(ebp, StandardFrameConstants::kContextOffset));
- __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_INDEX));
+ __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_OBJECT_INDEX));
__ mov(receiver,
FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
__ bind(&receiver_ok);
@@ -2823,7 +3053,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
void LCodeGen::DoPushArgument(LPushArgument* instr) {
- LOperand* argument = instr->InputAt(0);
+ LOperand* argument = instr->value();
EmitPushTaggedOperand(argument);
}
@@ -2835,7 +3065,7 @@ void LCodeGen::DoDrop(LDrop* instr) {
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
- __ LoadHeapObject(result, instr->hydrogen()->closure());
+ __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
}
@@ -2854,7 +3084,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(esi));
+ ASSERT(ToRegister(instr->context()).is(esi));
__ push(esi); // The context is the first argument.
__ push(Immediate(instr->hydrogen()->pairs()));
__ push(Immediate(Smi::FromInt(instr->hydrogen()->flags())));
@@ -2865,7 +3095,8 @@ void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
Register context = ToRegister(instr->context());
Register result = ToRegister(instr->result());
- __ mov(result, Operand(context, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ mov(result,
+ Operand(context, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
}
@@ -2892,17 +3123,8 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
__ LoadHeapObject(edi, function);
}
- // Change context if needed.
- bool change_context =
- (info()->closure()->context() != function->context()) ||
- scope()->contains_with() ||
- (scope()->num_heap_slots() > 0);
-
- if (change_context) {
- __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
- } else {
- __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
- }
+ // Change context.
+ __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
// Set eax to arguments count if adaption is not needed. Assumes that eax
// is available to write to at this point.
@@ -3065,8 +3287,7 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
__ cmp(output_reg, 0x80000000u);
DeoptimizeIf(equal, instr->environment());
} else {
- Label negative_sign;
- Label done;
+ Label negative_sign, done;
// Deoptimize on unordered.
__ xorps(xmm_scratch, xmm_scratch); // Zero the register.
__ ucomisd(input_reg, xmm_scratch);
@@ -3092,9 +3313,9 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
DeoptimizeIf(equal, instr->environment());
__ jmp(&done, Label::kNear);
- // Non-zero negative reaches here
+ // Non-zero negative reaches here.
__ bind(&negative_sign);
- // Truncate, then compare and compensate
+ // Truncate, then compare and compensate.
__ cvttsd2si(output_reg, Operand(input_reg));
__ cvtsi2sd(xmm_scratch, output_reg);
__ ucomisd(input_reg, xmm_scratch);
@@ -3196,11 +3417,11 @@ void LCodeGen::DoPower(LPower* instr) {
Representation exponent_type = instr->hydrogen()->right()->representation();
// Having marked this as a call, we can use any registers.
// Just make sure that the input/output registers are the expected ones.
- ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
- ToDoubleRegister(instr->InputAt(1)).is(xmm1));
- ASSERT(!instr->InputAt(1)->IsRegister() ||
- ToRegister(instr->InputAt(1)).is(eax));
- ASSERT(ToDoubleRegister(instr->InputAt(0)).is(xmm2));
+ ASSERT(!instr->right()->IsDoubleRegister() ||
+ ToDoubleRegister(instr->right()).is(xmm1));
+ ASSERT(!instr->right()->IsRegister() ||
+ ToRegister(instr->right()).is(eax));
+ ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
if (exponent_type.IsTagged()) {
@@ -3238,16 +3459,16 @@ void LCodeGen::DoRandom(LRandom* instr) {
// Having marked this instruction as a call we can use any
// registers.
ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
- ASSERT(ToRegister(instr->InputAt(0)).is(eax));
+ ASSERT(ToRegister(instr->global_object()).is(eax));
// Assert that the register size is indeed the size of each seed.
static const int kSeedSize = sizeof(uint32_t);
STATIC_ASSERT(kPointerSize == kSeedSize);
- __ mov(eax, FieldOperand(eax, GlobalObject::kGlobalContextOffset));
+ __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset));
static const int kRandomSeedOffset =
FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
__ mov(ebx, FieldOperand(eax, kRandomSeedOffset));
- // ebx: FixedArray of the global context's random seeds
+ // ebx: FixedArray of the native context's random seeds
// Load state[0].
__ mov(ecx, FieldOperand(ebx, ByteArray::kHeaderSize));
@@ -3495,8 +3716,8 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
__ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition());
} else {
- Register temp = ToRegister(instr->TempAt(0));
- Register temp_map = ToRegister(instr->TempAt(1));
+ Register temp = ToRegister(instr->temp());
+ Register temp_map = ToRegister(instr->temp_map());
__ mov(temp_map, instr->transition());
__ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map);
// Update the write barrier for the map field.
@@ -3517,7 +3738,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
if (instr->is_in_object()) {
__ mov(FieldOperand(object, offset), value);
if (instr->hydrogen()->NeedsWriteBarrier()) {
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
// Update the write barrier for the object for in-object properties.
__ RecordWriteField(object,
offset,
@@ -3528,7 +3749,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
check_needed);
}
} else {
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
__ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
__ mov(FieldOperand(temp, offset), value);
if (instr->hydrogen()->NeedsWriteBarrier()) {
@@ -3559,10 +3780,36 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
}
+void LCodeGen::DeoptIfTaggedButNotSmi(LEnvironment* environment,
+ HValue* value,
+ LOperand* operand) {
+ if (value->representation().IsTagged() && !value->type().IsSmi()) {
+ if (operand->IsRegister()) {
+ __ test(ToRegister(operand), Immediate(kSmiTagMask));
+ } else {
+ __ test(ToOperand(operand), Immediate(kSmiTagMask));
+ }
+ DeoptimizeIf(not_zero, environment);
+ }
+}
+
+
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
+ DeoptIfTaggedButNotSmi(instr->environment(),
+ instr->hydrogen()->length(),
+ instr->length());
+ DeoptIfTaggedButNotSmi(instr->environment(),
+ instr->hydrogen()->index(),
+ instr->index());
if (instr->index()->IsConstantOperand()) {
- __ cmp(ToOperand(instr->length()),
- Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
+ int constant_index =
+ ToInteger32(LConstantOperand::cast(instr->index()));
+ if (instr->hydrogen()->length()->representation().IsTagged()) {
+ __ cmp(ToOperand(instr->length()),
+ Immediate(Smi::FromInt(constant_index)));
+ } else {
+ __ cmp(ToOperand(instr->length()), Immediate(constant_index));
+ }
DeoptimizeIf(below_equal, instr->environment());
} else {
__ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
@@ -3574,11 +3821,19 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
void LCodeGen::DoStoreKeyedSpecializedArrayElement(
LStoreKeyedSpecializedArrayElement* instr) {
ElementsKind elements_kind = instr->elements_kind();
- Operand operand(BuildFastArrayOperand(instr->external_pointer(),
- instr->key(),
- elements_kind,
- 0,
- instr->additional_index()));
+ LOperand* key = instr->key();
+ if (!key->IsConstantOperand() &&
+ ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
+ elements_kind)) {
+ __ SmiUntag(ToRegister(key));
+ }
+ Operand operand(BuildFastArrayOperand(
+ instr->external_pointer(),
+ key,
+ instr->hydrogen()->key()->representation(),
+ elements_kind,
+ 0,
+ instr->additional_index()));
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
__ movss(operand, xmm0);
@@ -3625,6 +3880,7 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
Operand operand = BuildFastArrayOperand(
instr->object(),
instr->key(),
+ instr->hydrogen()->key()->representation(),
FAST_ELEMENTS,
FixedArray::kHeaderSize - kHeapObjectTag,
instr->additional_index());
@@ -3666,6 +3922,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
Operand double_store_operand = BuildFastArrayOperand(
instr->elements(),
instr->key(),
+ instr->hydrogen()->key()->representation(),
FAST_DOUBLE_ELEMENTS,
FixedDoubleArray::kHeaderSize - kHeapObjectTag,
instr->additional_index());
@@ -3688,7 +3945,7 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
Register object_reg = ToRegister(instr->object());
- Register new_map_reg = ToRegister(instr->new_map_reg());
+ Register new_map_reg = ToRegister(instr->new_map_temp());
Handle<Map> from_map = instr->original_map();
Handle<Map> to_map = instr->transitioned_map();
@@ -3708,14 +3965,14 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
__ mov(FieldOperand(object_reg, HeapObject::kMapOffset),
Immediate(map));
// Write barrier.
- ASSERT_NE(instr->temp_reg(), NULL);
+ ASSERT_NE(instr->temp(), NULL);
__ RecordWriteForMap(object_reg, to_map, new_map_reg,
- ToRegister(instr->temp_reg()),
+ ToRegister(instr->temp()),
kDontSaveFPRegs);
} else if (IsFastSmiElementsKind(from_kind) &&
IsFastDoubleElementsKind(to_kind)) {
__ mov(new_map_reg, to_map);
- Register fixed_object_reg = ToRegister(instr->temp_reg());
+ Register fixed_object_reg = ToRegister(instr->temp());
ASSERT(fixed_object_reg.is(edx));
ASSERT(new_map_reg.is(ebx));
__ mov(fixed_object_reg, object_reg);
@@ -3724,7 +3981,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
} else if (IsFastDoubleElementsKind(from_kind) &&
IsFastObjectElementsKind(to_kind)) {
__ mov(new_map_reg, to_map);
- Register fixed_object_reg = ToRegister(instr->temp_reg());
+ Register fixed_object_reg = ToRegister(instr->temp());
ASSERT(fixed_object_reg.is(edx));
ASSERT(new_map_reg.is(ebx));
__ mov(fixed_object_reg, object_reg);
@@ -3785,9 +4042,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
}
CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2,
instr, instr->context());
- if (FLAG_debug_code) {
- __ AbortIfNotSmi(eax);
- }
+ __ AssertSmi(eax);
__ SmiUntag(eax);
__ StoreToSafepointRegisterSlot(result, eax);
}
@@ -3857,7 +4112,7 @@ void LCodeGen::DoStringAdd(LStringAdd* instr) {
void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister() || input->IsStackSlot());
LOperand* output = instr->result();
ASSERT(output->IsDoubleRegister());
@@ -3865,18 +4120,31 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
}
+void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
+ LOperand* input = instr->value();
+ LOperand* output = instr->result();
+ LOperand* temp = instr->temp();
+
+ __ LoadUint32(ToDoubleRegister(output),
+ ToRegister(input),
+ ToDoubleRegister(temp));
+}
+
+
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
class DeferredNumberTagI: public LDeferredCode {
public:
DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
: LDeferredCode(codegen), instr_(instr) { }
- virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); }
+ virtual void Generate() {
+ codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32);
+ }
virtual LInstruction* instr() { return instr_; }
private:
LNumberTagI* instr_;
};
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister() && input->Equals(instr->result()));
Register reg = ToRegister(input);
@@ -3887,21 +4155,54 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
}
-void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
+void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
+ class DeferredNumberTagU: public LDeferredCode {
+ public:
+ DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
+ : LDeferredCode(codegen), instr_(instr) { }
+ virtual void Generate() {
+ codegen()->DoDeferredNumberTagI(instr_, instr_->value(), UNSIGNED_INT32);
+ }
+ virtual LInstruction* instr() { return instr_; }
+ private:
+ LNumberTagU* instr_;
+ };
+
+ LOperand* input = instr->value();
+ ASSERT(input->IsRegister() && input->Equals(instr->result()));
+ Register reg = ToRegister(input);
+
+ DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
+ __ cmp(reg, Immediate(Smi::kMaxValue));
+ __ j(above, deferred->entry());
+ __ SmiTag(reg);
+ __ bind(deferred->exit());
+}
+
+
+void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
+ LOperand* value,
+ IntegerSignedness signedness) {
Label slow;
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(value);
Register tmp = reg.is(eax) ? ecx : eax;
// Preserve the value of all registers.
PushSafepointRegistersScope scope(this);
- // There was overflow, so bits 30 and 31 of the original integer
- // disagree. Try to allocate a heap number in new space and store
- // the value in there. If that fails, call the runtime system.
Label done;
- __ SmiUntag(reg);
- __ xor_(reg, 0x80000000);
- __ cvtsi2sd(xmm0, Operand(reg));
+
+ if (signedness == SIGNED_INT32) {
+ // There was overflow, so bits 30 and 31 of the original integer
+ // disagree. Try to allocate a heap number in new space and store
+ // the value in there. If that fails, call the runtime system.
+ __ SmiUntag(reg);
+ __ xor_(reg, 0x80000000);
+ __ cvtsi2sd(xmm0, Operand(reg));
+ } else {
+ __ LoadUint32(xmm0, reg, xmm1);
+ }
+
if (FLAG_inline_new) {
__ AllocateHeapNumber(reg, tmp, no_reg, &slow);
__ jmp(&done, Label::kNear);
@@ -3944,9 +4245,9 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
LNumberTagD* instr_;
};
- XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+ XMMRegister input_reg = ToDoubleRegister(instr->value());
Register reg = ToRegister(instr->result());
- Register tmp = ToRegister(instr->TempAt(0));
+ Register tmp = ToRegister(instr->temp());
DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
if (FLAG_inline_new) {
@@ -3981,7 +4282,7 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
void LCodeGen::DoSmiTag(LSmiTag* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister() && input->Equals(instr->result()));
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
__ SmiTag(ToRegister(input));
@@ -3989,15 +4290,13 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) {
void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister() && input->Equals(instr->result()));
if (instr->needs_check()) {
__ test(ToRegister(input), Immediate(kSmiTagMask));
DeoptimizeIf(not_zero, instr->environment());
} else {
- if (FLAG_debug_code) {
- __ AbortIfNotSmi(ToRegister(input));
- }
+ __ AssertSmi(ToRegister(input));
}
__ SmiUntag(ToRegister(input));
}
@@ -4058,7 +4357,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
Label done, heap_number;
- Register input_reg = ToRegister(instr->InputAt(0));
+ Register input_reg = ToRegister(instr->value());
// Heap number map check.
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
@@ -4099,7 +4398,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
__ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
__ add(Operand(esp), Immediate(kDoubleSize));
} else {
- XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
+ XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
__ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ cvttsd2si(input_reg, Operand(xmm0));
__ cmp(input_reg, 0x80000000u);
@@ -4116,7 +4415,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
// Deoptimize if we don't have a heap number.
DeoptimizeIf(not_equal, instr->environment());
- XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
+ XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
__ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ cvttsd2si(input_reg, Operand(xmm0));
__ cvtsi2sd(xmm_temp, Operand(input_reg));
@@ -4146,7 +4445,7 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
LTaggedToI* instr_;
};
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
ASSERT(input->Equals(instr->result()));
@@ -4165,9 +4464,9 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
- LOperand* temp = instr->TempAt(0);
+ LOperand* temp = instr->temp();
ASSERT(temp == NULL || temp->IsRegister());
LOperand* result = instr->result();
ASSERT(result->IsDoubleRegister());
@@ -4189,7 +4488,7 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsDoubleRegister());
LOperand* result = instr->result();
ASSERT(result->IsRegister());
@@ -4227,7 +4526,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
__ bind(&done);
} else {
Label done;
- Register temp_reg = ToRegister(instr->TempAt(0));
+ Register temp_reg = ToRegister(instr->temp());
XMMRegister xmm_scratch = xmm0;
// If cvttsd2si succeeded, we're done. Otherwise, we attempt
@@ -4306,22 +4605,22 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
__ test(ToOperand(input), Immediate(kSmiTagMask));
DeoptimizeIf(not_zero, instr->environment());
}
void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
__ test(ToOperand(input), Immediate(kSmiTagMask));
DeoptimizeIf(zero, instr->environment());
}
void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
- Register input = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register input = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
__ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
@@ -4391,7 +4690,7 @@ void LCodeGen::DoCheckMapCommon(Register reg,
void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
@@ -4457,7 +4756,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
- Register reg = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->temp());
Handle<JSObject> holder = instr->holder();
Handle<JSObject> current_prototype = instr->prototype();
@@ -4497,7 +4796,7 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
new(zone()) DeferredAllocateObject(this, instr);
Register result = ToRegister(instr->result());
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
Handle<JSFunction> constructor = instr->hydrogen()->constructor();
Handle<Map> initial_map(constructor->initial_map());
int instance_size = initial_map->instance_size();
@@ -4530,7 +4829,7 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
__ mov(map, FieldOperand(scratch, JSFunction::kPrototypeOrInitialMapOffset));
if (FLAG_debug_code) {
- __ AbortIfSmi(map);
+ __ AssertNotSmi(map);
__ cmpb(FieldOperand(map, Map::kInstanceSizeOffset),
instance_size >> kPointerSizeLog2);
__ Assert(equal, "Unexpected instance size");
@@ -4582,7 +4881,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
- Heap* heap = isolate()->heap();
+ Handle<FixedArray> literals(instr->environment()->closure()->literals());
ElementsKind boilerplate_elements_kind =
instr->hydrogen()->boilerplate_elements_kind();
@@ -4603,12 +4902,11 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
}
// Set up the parameters to the stub/runtime call.
- __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
- __ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
+ __ PushHeapObject(literals);
__ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
// Boilerplate already exists, constant elements are never accessed.
// Pass an empty fixed array.
- __ push(Immediate(Handle<FixedArray>(heap->empty_fixed_array())));
+ __ push(Immediate(isolate()->factory()->empty_fixed_array()));
// Pick the right runtime function or stub to call.
int length = instr->hydrogen()->length();
@@ -4712,8 +5010,8 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
Handle<FixedDoubleArray>::cast(elements);
for (int i = 0; i < elements_length; i++) {
int64_t value = double_array->get_representation(i);
- int32_t value_low = value & 0xFFFFFFFF;
- int32_t value_high = value >> 32;
+ int32_t value_low = static_cast<int32_t>(value & 0xFFFFFFFF);
+ int32_t value_high = static_cast<int32_t>(value >> 32);
int total_offset =
elements_offset + FixedDoubleArray::OffsetOfElementAt(i);
__ mov(FieldOperand(result, total_offset), Immediate(value_low));
@@ -4817,7 +5115,7 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(eax));
+ ASSERT(ToRegister(instr->value()).is(eax));
__ push(eax);
CallRuntime(Runtime::kToFastProperties, 1, instr);
}
@@ -4827,15 +5125,13 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
Label materialized;
// Registers will be used as follows:
- // edi = JS function.
// ecx = literals array.
// ebx = regexp literal.
// eax = regexp literal clone.
// esi = context.
- __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
- __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset));
- int literal_offset = FixedArray::kHeaderSize +
- instr->hydrogen()->literal_index() * kPointerSize;
+ int literal_offset =
+ FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+ __ LoadHeapObject(ecx, instr->hydrogen()->literals());
__ mov(ebx, FieldOperand(ecx, literal_offset));
__ cmp(ebx, factory()->undefined_value());
__ j(not_equal, &materialized, Label::kNear);
@@ -4899,14 +5195,14 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
void LCodeGen::DoTypeof(LTypeof* instr) {
- LOperand* input = instr->InputAt(1);
+ LOperand* input = instr->value();
EmitPushTaggedOperand(input);
CallRuntime(Runtime::kTypeof, 1, instr);
}
void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* true_label = chunk_->GetAssemblyLabel(true_block);
@@ -4990,7 +5286,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -5191,11 +5487,20 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
Register map = ToRegister(instr->map());
Register result = ToRegister(instr->result());
+ Label load_cache, done;
+ __ EnumLength(result, map);
+ __ cmp(result, Immediate(Smi::FromInt(0)));
+ __ j(not_equal, &load_cache);
+ __ mov(result, isolate()->factory()->empty_fixed_array());
+ __ jmp(&done);
+
+ __ bind(&load_cache);
__ LoadInstanceDescriptors(map, result);
__ mov(result,
- FieldOperand(result, DescriptorArray::kEnumerationIndexOffset));
+ FieldOperand(result, DescriptorArray::kEnumCacheOffset));
__ mov(result,
FieldOperand(result, FixedArray::SizeFor(instr->idx())));
+ __ bind(&done);
__ test(result, result);
DeoptimizeIf(equal, instr->environment());
}
diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.h b/deps/v8/src/ia32/lithium-codegen-ia32.h
index b241aafb9..6670024db 100644
--- a/deps/v8/src/ia32/lithium-codegen-ia32.h
+++ b/deps/v8/src/ia32/lithium-codegen-ia32.h
@@ -46,26 +46,25 @@ class SafepointGenerator;
class LCodeGen BASE_EMBEDDED {
public:
- LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info,
- Zone* zone)
- : chunk_(chunk),
+ LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
+ : zone_(info->zone()),
+ chunk_(static_cast<LPlatformChunk*>(chunk)),
masm_(assembler),
info_(info),
current_block_(-1),
current_instruction_(-1),
instructions_(chunk->instructions()),
- deoptimizations_(4, zone),
- deoptimization_literals_(8, zone),
+ deoptimizations_(4, info->zone()),
+ deoptimization_literals_(8, info->zone()),
inlined_function_count_(0),
scope_(info->scope()),
status_(UNUSED),
- translations_(zone),
- deferred_(8, zone),
+ translations_(info->zone()),
+ deferred_(8, info->zone()),
dynamic_frame_alignment_(false),
osr_pc_offset_(-1),
last_lazy_deopt_pc_(0),
- safepoints_(zone),
- zone_(zone),
+ safepoints_(info->zone()),
resolver_(this),
expected_safepoint_kind_(Safepoint::kSimple) {
PopulateDeoptimizationLiteralsWithInlinedFunctions();
@@ -106,7 +105,12 @@ class LCodeGen BASE_EMBEDDED {
// Deferred code support.
void DoDeferredNumberTagD(LNumberTagD* instr);
- void DoDeferredNumberTagI(LNumberTagI* instr);
+
+ enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
+ void DoDeferredNumberTagI(LInstruction* instr,
+ LOperand* value,
+ IntegerSignedness signedness);
+
void DoDeferredTaggedToI(LTaggedToI* instr);
void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
void DoDeferredStackCheck(LStackCheck* instr);
@@ -125,7 +129,10 @@ class LCodeGen BASE_EMBEDDED {
void DoGap(LGap* instr);
// Emit frame translation commands for an environment.
- void WriteTranslation(LEnvironment* environment, Translation* translation);
+ void WriteTranslation(LEnvironment* environment,
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count);
void EnsureRelocSpaceForDeoptimization();
@@ -151,7 +158,7 @@ class LCodeGen BASE_EMBEDDED {
return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
}
- LChunk* chunk() const { return chunk_; }
+ LPlatformChunk* chunk() const { return chunk_; }
Scope* scope() const { return scope_; }
HGraph* graph() const { return chunk_->graph(); }
@@ -167,7 +174,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
int GetParameterCount() const { return scope()->num_parameters(); }
- void Abort(const char* format, ...);
+ void Abort(const char* reason);
void Comment(const char* format, ...);
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
@@ -234,7 +241,10 @@ class LCodeGen BASE_EMBEDDED {
void AddToTranslation(Translation* translation,
LOperand* op,
- bool is_tagged);
+ bool is_tagged,
+ bool is_uint32,
+ int arguments_index,
+ int arguments_count);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
@@ -247,6 +257,7 @@ class LCodeGen BASE_EMBEDDED {
double ToDouble(LConstantOperand* op) const;
Operand BuildFastArrayOperand(LOperand* elements_pointer,
LOperand* key,
+ Representation key_representation,
ElementsKind elements_kind,
uint32_t offset,
uint32_t additional_index = 0);
@@ -284,6 +295,10 @@ class LCodeGen BASE_EMBEDDED {
bool deoptimize_on_minus_zero,
LEnvironment* env);
+ void DeoptIfTaggedButNotSmi(LEnvironment* environment,
+ HValue* value,
+ LOperand* operand);
+
// Emits optimized code for typeof x == "y". Modifies input register.
// Returns the condition on which a final split to
// true and false label should be made, to optimize fallthrough.
@@ -330,7 +345,8 @@ class LCodeGen BASE_EMBEDDED {
// register, or a stack slot operand.
void EmitPushTaggedOperand(LOperand* operand);
- LChunk* const chunk_;
+ Zone* zone_;
+ LPlatformChunk* const chunk_;
MacroAssembler* const masm_;
CompilationInfo* const info_;
@@ -352,8 +368,6 @@ class LCodeGen BASE_EMBEDDED {
// itself is emitted at the end of the generated code.
SafepointTableBuilder safepoints_;
- Zone* zone_;
-
// Compiler from a set of parallel moves to a sequential list of moves.
LGapResolver resolver_;
diff --git a/deps/v8/src/ia32/lithium-ia32.cc b/deps/v8/src/ia32/lithium-ia32.cc
index 60366f744..1d12d23d2 100644
--- a/deps/v8/src/ia32/lithium-ia32.cc
+++ b/deps/v8/src/ia32/lithium-ia32.cc
@@ -196,22 +196,22 @@ void LGoto::PrintDataTo(StringStream* stream) {
void LBranch::PrintDataTo(StringStream* stream) {
stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
- InputAt(0)->PrintTo(stream);
+ left()->PrintTo(stream);
stream->Add(" %s ", Token::String(op()));
- InputAt(1)->PrintTo(stream);
+ right()->PrintTo(stream);
stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
}
void LIsNilAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(kind() == kStrictEquality ? " === " : " == ");
stream->Add(nil() == kNullValue ? "null" : "undefined");
stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
@@ -220,57 +220,57 @@ void LIsNilAndBranch::PrintDataTo(StringStream* stream) {
void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_object(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsStringAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_string(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_smi(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsUndetectableAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_undetectable(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LStringCompareAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if string_compare(");
- InputAt(1)->PrintTo(stream);
- InputAt(2)->PrintTo(stream);
+ left()->PrintTo(stream);
+ right()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if has_instance_type(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if has_cached_array_index(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if class_of_test(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(", \"%o\") then B%d else B%d",
*hydrogen()->class_name(),
true_block_id(),
@@ -280,7 +280,7 @@ void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if typeof ");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(" == \"%s\" then B%d else B%d",
*hydrogen()->type_literal()->ToCString(),
true_block_id(), false_block_id());
@@ -294,34 +294,34 @@ void LCallConstantFunction::PrintDataTo(StringStream* stream) {
void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
stream->Add("/%s ", hydrogen()->OpName());
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LMathPowHalf::PrintDataTo(StringStream* stream) {
stream->Add("/pow_half ");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LLoadContextSlot::PrintDataTo(StringStream* stream) {
- InputAt(0)->PrintTo(stream);
+ context()->PrintTo(stream);
stream->Add("[%d]", slot_index());
}
void LStoreContextSlot::PrintDataTo(StringStream* stream) {
- InputAt(0)->PrintTo(stream);
+ context()->PrintTo(stream);
stream->Add("[%d] <- ", slot_index());
- InputAt(1)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LInvokeFunction::PrintDataTo(StringStream* stream) {
stream->Add("= ");
- InputAt(0)->PrintTo(stream);
+ context()->PrintTo(stream);
stream->Add(" ");
- InputAt(1)->PrintTo(stream);
+ function()->PrintTo(stream);
stream->Add(" #%d / ", arity());
}
@@ -350,7 +350,9 @@ void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
void LCallNew::PrintDataTo(StringStream* stream) {
stream->Add("= ");
- InputAt(0)->PrintTo(stream);
+ context()->PrintTo(stream);
+ stream->Add(" ");
+ constructor()->PrintTo(stream);
stream->Add(" #%d / ", arity());
}
@@ -366,7 +368,7 @@ void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
}
-int LChunk::GetNextSpillIndex(bool is_double) {
+int LPlatformChunk::GetNextSpillIndex(bool is_double) {
// Skip a slot if for a double-width slot.
if (is_double) {
spill_slot_count_++;
@@ -377,7 +379,7 @@ int LChunk::GetNextSpillIndex(bool is_double) {
}
-LOperand* LChunk::GetNextSpillSlot(bool is_double) {
+LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) {
int index = GetNextSpillIndex(is_double);
if (is_double) {
return LDoubleStackSlot::Create(index, zone());
@@ -387,42 +389,6 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) {
}
-void LChunk::MarkEmptyBlocks() {
- HPhase phase("L_Mark empty blocks", this);
- for (int i = 0; i < graph()->blocks()->length(); ++i) {
- HBasicBlock* block = graph()->blocks()->at(i);
- int first = block->first_instruction_index();
- int last = block->last_instruction_index();
- LInstruction* first_instr = instructions()->at(first);
- LInstruction* last_instr = instructions()->at(last);
-
- LLabel* label = LLabel::cast(first_instr);
- if (last_instr->IsGoto()) {
- LGoto* goto_instr = LGoto::cast(last_instr);
- if (label->IsRedundant() &&
- !label->is_loop_header()) {
- bool can_eliminate = true;
- for (int i = first + 1; i < last && can_eliminate; ++i) {
- LInstruction* cur = instructions()->at(i);
- if (cur->IsGap()) {
- LGap* gap = LGap::cast(cur);
- if (!gap->IsRedundant()) {
- can_eliminate = false;
- }
- } else {
- can_eliminate = false;
- }
- }
-
- if (can_eliminate) {
- label->set_replacement(GetLabel(goto_instr->block_id()));
- }
- }
- }
- }
-}
-
-
void LStoreNamedField::PrintDataTo(StringStream* stream) {
object()->PrintTo(stream);
stream->Add(".");
@@ -474,84 +440,9 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) {
}
-void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
- LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
- int index = -1;
- if (instr->IsControl()) {
- instructions_.Add(gap, zone());
- index = instructions_.length();
- instructions_.Add(instr, zone());
- } else {
- index = instructions_.length();
- instructions_.Add(instr, zone());
- instructions_.Add(gap, zone());
- }
- if (instr->HasPointerMap()) {
- pointer_maps_.Add(instr->pointer_map(), zone());
- instr->pointer_map()->set_lithium_position(index);
- }
-}
-
-
-LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
- return LConstantOperand::Create(constant->id(), zone());
-}
-
-
-int LChunk::GetParameterStackSlot(int index) const {
- // The receiver is at index 0, the first parameter at index 1, so we
- // shift all parameter indexes down by the number of parameters, and
- // make sure they end up negative so they are distinguishable from
- // spill slots.
- int result = index - info()->scope()->num_parameters() - 1;
- ASSERT(result < 0);
- return result;
-}
-
-// A parameter relative to ebp in the arguments stub.
-int LChunk::ParameterAt(int index) {
- ASSERT(-1 <= index); // -1 is the receiver.
- return (1 + info()->scope()->num_parameters() - index) *
- kPointerSize;
-}
-
-
-LGap* LChunk::GetGapAt(int index) const {
- return LGap::cast(instructions_[index]);
-}
-
-
-bool LChunk::IsGapAt(int index) const {
- return instructions_[index]->IsGap();
-}
-
-
-int LChunk::NearestGapPos(int index) const {
- while (!IsGapAt(index)) index--;
- return index;
-}
-
-
-void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
- GetGapAt(index)->GetOrCreateParallelMove(
- LGap::START, zone())->AddMove(from, to, zone());
-}
-
-
-Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
- return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
-}
-
-
-Representation LChunk::LookupLiteralRepresentation(
- LConstantOperand* operand) const {
- return graph_->LookupValue(operand->index())->representation();
-}
-
-
-LChunk* LChunkBuilder::Build() {
+LPlatformChunk* LChunkBuilder::Build() {
ASSERT(is_unused());
- chunk_ = new(zone()) LChunk(info(), graph());
+ chunk_ = new(zone()) LPlatformChunk(info(), graph());
HPhase phase("L_Building chunk", chunk_);
status_ = BUILDING;
@@ -572,17 +463,8 @@ LChunk* LChunkBuilder::Build() {
}
-void LChunkBuilder::Abort(const char* format, ...) {
- if (FLAG_trace_bailout) {
- SmartArrayPointer<char> name(
- info()->shared_info()->DebugName()->ToCString());
- PrintF("Aborting LChunk building in @\"%s\": ", *name);
- va_list arguments;
- va_start(arguments, format);
- OS::VPrint(format, arguments);
- va_end(arguments);
- PrintF("\n");
- }
+void LChunkBuilder::Abort(const char* reason) {
+ info()->set_bailout_reason(reason);
status_ = ABORTED;
}
@@ -753,7 +635,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
ASSERT(hinstr->next()->IsSimulate());
HSimulate* sim = HSimulate::cast(hinstr->next());
ASSERT(instruction_pending_deoptimization_environment_ == NULL);
- ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
+ ASSERT(pending_deoptimization_ast_id_.IsNone());
instruction_pending_deoptimization_environment_ = instr;
pending_deoptimization_ast_id_ = sim->ast_id();
}
@@ -851,13 +733,16 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
// Shift operations can only deoptimize if we do a logical shift by 0 and
// the result cannot be truncated to int32.
- bool may_deopt = (op == Token::SHR && constant_value == 0);
bool does_deopt = false;
- if (may_deopt) {
- for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
- if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
- does_deopt = true;
- break;
+ if (op == Token::SHR && constant_value == 0) {
+ if (FLAG_opt_safe_uint32_operations) {
+ does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+ } else {
+ for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
+ if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
+ does_deopt = true;
+ break;
+ }
}
}
}
@@ -991,8 +876,8 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
LEnvironment* outer =
CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator);
- int ast_id = hydrogen_env->ast_id();
- ASSERT(ast_id != AstNode::kNoNumber ||
+ BailoutId ast_id = hydrogen_env->ast_id();
+ ASSERT(!ast_id.IsNone() ||
hydrogen_env->frame_type() != JS_FUNCTION);
int value_count = hydrogen_env->length();
LEnvironment* result =
@@ -1003,6 +888,7 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
argument_count_,
value_count,
outer,
+ hydrogen_env->entry(),
zone());
int argument_index = *argument_index_accumulator;
for (int i = 0; i < value_count; ++i) {
@@ -1017,7 +903,9 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
} else {
op = UseAny(value);
}
- result->AddValue(op, value->representation());
+ result->AddValue(op,
+ value->representation(),
+ value->CheckFlag(HInstruction::kUint32));
}
if (hydrogen_env->frame_type() == JS_FUNCTION) {
@@ -1347,12 +1235,57 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
}
-LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
- UNIMPLEMENTED();
+HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) {
+ // A value with an integer representation does not need to be transformed.
+ if (dividend->representation().IsInteger32()) {
+ return dividend;
+ // A change from an integer32 can be replaced by the integer32 value.
+ } else if (dividend->IsChange() &&
+ HChange::cast(dividend)->from().IsInteger32()) {
+ return HChange::cast(dividend)->value();
+ }
return NULL;
}
+HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) {
+ if (divisor->IsConstant() &&
+ HConstant::cast(divisor)->HasInteger32Value()) {
+ HConstant* constant_val = HConstant::cast(divisor);
+ return constant_val->CopyToRepresentation(Representation::Integer32(),
+ divisor->block()->zone());
+ }
+ return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
+ HValue* right = instr->right();
+ ASSERT(right->IsConstant() && HConstant::cast(right)->HasInteger32Value());
+ LOperand* divisor = chunk_->DefineConstantOperand(HConstant::cast(right));
+ int32_t divisor_si = HConstant::cast(right)->Integer32Value();
+ if (divisor_si == 0) {
+ LOperand* dividend = UseRegister(instr->left());
+ return AssignEnvironment(DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, NULL)));
+ } else if (IsPowerOf2(abs(divisor_si))) {
+ // use dividend as temp if divisor < 0 && divisor != -1
+ LOperand* dividend = divisor_si < -1 ? UseTempRegister(instr->left()) :
+ UseRegisterAtStart(instr->left());
+ LInstruction* result = DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, NULL));
+ return divisor_si < 0 ? AssignEnvironment(result) : result;
+ } else {
+ // needs edx:eax, plus a temp
+ LOperand* dividend = UseFixed(instr->left(), eax);
+ LOperand* temp = TempRegister();
+ LInstruction* result = DefineFixed(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, temp), edx);
+ return divisor_si < 0 ? AssignEnvironment(result) : result;
+ }
+}
+
+
LInstruction* LChunkBuilder::DoMod(HMod* instr) {
if (instr->representation().IsInteger32()) {
ASSERT(instr->left()->representation().IsInteger32());
@@ -1461,6 +1394,26 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
+LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
+ LOperand* left = NULL;
+ LOperand* right = NULL;
+ if (instr->representation().IsInteger32()) {
+ ASSERT(instr->left()->representation().IsInteger32());
+ ASSERT(instr->right()->representation().IsInteger32());
+ left = UseRegisterAtStart(instr->LeastConstantOperand());
+ right = UseOrConstantAtStart(instr->MostConstantOperand());
+ } else {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->left()->representation().IsDouble());
+ ASSERT(instr->right()->representation().IsDouble());
+ left = UseRegisterAtStart(instr->left());
+ right = UseRegisterAtStart(instr->right());
+ }
+ LMathMinMax* minmax = new(zone()) LMathMinMax(left, right);
+ return DefineSameAsFirst(minmax);
+}
+
+
LInstruction* LChunkBuilder::DoPower(HPower* instr) {
ASSERT(instr->representation().IsDouble());
// We call a C function for double power. It can't trigger a GC.
@@ -1637,6 +1590,12 @@ LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
}
+LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
+ LOperand* map = UseRegisterAtStart(instr->value());
+ return DefineAsRegister(new(zone()) LMapEnumLength(map));
+}
+
+
LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
LOperand* object = UseRegisterAtStart(instr->value());
return DefineAsRegister(new(zone()) LElementsKind(object));
@@ -1654,7 +1613,7 @@ LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
LOperand* date = UseFixed(instr->value(), eax);
LDateField* result =
new(zone()) LDateField(date, FixedTemp(ecx), instr->index());
- return MarkAsCall(DefineFixed(result, eax), instr);
+ return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
}
@@ -1744,14 +1703,24 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
LOperand* value = UseRegister(val);
if (val->HasRange() && val->range()->IsInSmiRange()) {
return DefineSameAsFirst(new(zone()) LSmiTag(value));
+ } else if (val->CheckFlag(HInstruction::kUint32)) {
+ LOperand* temp = FixedTemp(xmm1);
+ LNumberTagU* result = new(zone()) LNumberTagU(value, temp);
+ return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
} else {
LNumberTagI* result = new(zone()) LNumberTagI(value);
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
}
} else {
ASSERT(to.IsDouble());
- return DefineAsRegister(
- new(zone()) LInteger32ToDouble(Use(instr->value())));
+ if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+ LOperand* temp = FixedTemp(xmm1);
+ return DefineAsRegister(
+ new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
+ } else {
+ return DefineAsRegister(
+ new(zone()) LInteger32ToDouble(Use(instr->value())));
+ }
}
}
UNREACHABLE();
@@ -1810,7 +1779,7 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
Representation input_rep = value->representation();
if (input_rep.IsDouble()) {
LOperand* reg = UseRegister(value);
- return DefineAsRegister(new(zone()) LClampDToUint8(reg));
+ return DefineFixed(new(zone()) LClampDToUint8(reg), eax);
} else if (input_rep.IsInteger32()) {
LOperand* reg = UseFixed(value, eax);
return DefineFixed(new(zone()) LClampIToUint8(reg), eax);
@@ -1966,7 +1935,8 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
HLoadKeyedFastElement* instr) {
ASSERT(instr->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key);
@@ -1978,7 +1948,8 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
HLoadKeyedFastDoubleElement* instr) {
ASSERT(instr->representation().IsDouble());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* elements = UseRegisterAtStart(instr->elements());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastDoubleElement* result =
@@ -1997,11 +1968,17 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
(instr->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer());
- LOperand* key = UseRegisterOrConstant(instr->key());
+ bool clobbers_key = ExternalArrayOpRequiresTemp(
+ instr->key()->representation(), elements_kind);
+ LOperand* key = clobbers_key
+ ? UseTempRegister(instr->key())
+ : UseRegisterOrConstant(instr->key());
+
LLoadKeyedSpecializedArrayElement* result =
- new(zone()) LLoadKeyedSpecializedArrayElement(external_pointer, key);
+ new(zone()) LLoadKeyedSpecializedArrayElement(external_pointer, key);
LInstruction* load_instr = DefineAsRegister(result);
// An unsigned int array load might overflow and cause a deopt, make sure it
// has an environment.
@@ -2027,7 +2004,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
bool needs_write_barrier = instr->NeedsWriteBarrier();
ASSERT(instr->value()->representation().IsTagged());
ASSERT(instr->object()->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* obj = UseRegister(instr->object());
LOperand* val = needs_write_barrier
@@ -2044,7 +2022,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
HStoreKeyedFastDoubleElement* instr) {
ASSERT(instr->value()->representation().IsDouble());
ASSERT(instr->elements()->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* elements = UseRegisterAtStart(instr->elements());
LOperand* val = UseTempRegister(instr->value());
@@ -2065,10 +2044,10 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer());
- LOperand* key = UseRegisterOrConstant(instr->key());
LOperand* val = NULL;
if (elements_kind == EXTERNAL_BYTE_ELEMENTS ||
elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS ||
@@ -2078,7 +2057,11 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
} else {
val = UseRegister(instr->value());
}
-
+ bool clobbers_key = ExternalArrayOpRequiresTemp(
+ instr->key()->representation(), elements_kind);
+ LOperand* key = clobbers_key
+ ? UseTempRegister(instr->key())
+ : UseRegisterOrConstant(instr->key());
return new(zone()) LStoreKeyedSpecializedArrayElement(external_pointer,
key,
val);
@@ -2255,6 +2238,7 @@ LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
+ ASSERT(argument_count_ == 0);
allocator_->MarkAsOsrEntry();
current_block_->last_environment()->set_ast_id(instr->ast_id());
return AssignEnvironment(new(zone()) LOsrEntry);
@@ -2295,12 +2279,10 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
- LOperand* arguments = UseRegister(instr->arguments());
+ LOperand* args = UseRegister(instr->arguments());
LOperand* length = UseTempRegister(instr->length());
LOperand* index = Use(instr->index());
- LAccessArgumentsAt* result =
- new(zone()) LAccessArgumentsAt(arguments, length, index);
- return AssignEnvironment(DefineAsRegister(result));
+ return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
}
@@ -2348,7 +2330,7 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
// If there is an instruction pending deoptimization environment create a
// lazy bailout instruction to capture the environment.
- if (pending_deoptimization_ast_id_ != AstNode::kNoNumber) {
+ if (!pending_deoptimization_ast_id_.IsNone()) {
ASSERT(pending_deoptimization_ast_id_ == instr->ast_id());
LLazyBailout* lazy_bailout = new(zone()) LLazyBailout;
LInstruction* result = AssignEnvironment(lazy_bailout);
@@ -2357,7 +2339,7 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
instruction_pending_deoptimization_environment_->
SetDeferredLazyDeoptimizationEnvironment(result->environment());
instruction_pending_deoptimization_environment_ = NULL;
- pending_deoptimization_ast_id_ = AstNode::kNoNumber;
+ pending_deoptimization_ast_id_ = BailoutId::None();
return result;
}
@@ -2386,10 +2368,11 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
instr->function(),
undefined,
instr->call_kind(),
- instr->is_construct());
+ instr->inlining_kind());
if (instr->arguments_var() != NULL) {
inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
}
+ inner->set_entry(instr);
current_block_->UpdateEnvironment(inner);
chunk_->AddInlinedClosure(instr->closure());
return NULL;
@@ -2401,7 +2384,7 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
HEnvironment* env = current_block_->last_environment();
- if (instr->arguments_pushed()) {
+ if (env->entry()->arguments_pushed()) {
int argument_count = env->arguments_environment()->parameter_count();
pop = new(zone()) LDrop(argument_count);
argument_count_ -= argument_count;
diff --git a/deps/v8/src/ia32/lithium-ia32.h b/deps/v8/src/ia32/lithium-ia32.h
index cd2063180..4643f95f4 100644
--- a/deps/v8/src/ia32/lithium-ia32.h
+++ b/deps/v8/src/ia32/lithium-ia32.h
@@ -102,6 +102,7 @@ class LCodeGen;
V(InstanceOfKnownGlobal) \
V(InstructionGap) \
V(Integer32ToDouble) \
+ V(Uint32ToDouble) \
V(InvokeFunction) \
V(IsConstructCallAndBranch) \
V(IsNilAndBranch) \
@@ -109,7 +110,6 @@ class LCodeGen;
V(IsStringAndBranch) \
V(IsSmiAndBranch) \
V(IsUndetectableAndBranch) \
- V(StringCompareAndBranch) \
V(JSArrayLength) \
V(Label) \
V(LazyBailout) \
@@ -126,11 +126,15 @@ class LCodeGen;
V(LoadNamedField) \
V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
+ V(MapEnumLength) \
+ V(MathFloorOfDiv) \
+ V(MathMinMax) \
V(MathPowHalf) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
V(NumberTagI) \
+ V(NumberTagU) \
V(NumberUntagD) \
V(ObjectLiteral) \
V(OsrEntry) \
@@ -157,6 +161,7 @@ class LCodeGen;
V(StringAdd) \
V(StringCharCodeAt) \
V(StringCharFromCode) \
+ V(StringCompareAndBranch) \
V(StringLength) \
V(SubI) \
V(TaggedToI) \
@@ -252,11 +257,6 @@ class LInstruction: public ZoneObject {
virtual bool HasResult() const = 0;
virtual LOperand* result() = 0;
- virtual int InputCount() = 0;
- virtual LOperand* InputAt(int i) = 0;
- virtual int TempCount() = 0;
- virtual LOperand* TempAt(int i) = 0;
-
LOperand* FirstInput() { return InputAt(0); }
LOperand* Output() { return HasResult() ? result() : NULL; }
@@ -265,6 +265,15 @@ class LInstruction: public ZoneObject {
#endif
private:
+ // Iterator support.
+ friend class InputIterator;
+ virtual int InputCount() = 0;
+ virtual LOperand* InputAt(int i) = 0;
+
+ friend class TempIterator;
+ virtual int TempCount() = 0;
+ virtual LOperand* TempAt(int i) = 0;
+
LEnvironment* environment_;
SetOncePointer<LPointerMap> pointer_map_;
HValue* hydrogen_value_;
@@ -284,16 +293,18 @@ class LTemplateInstruction: public LInstruction {
void set_result(LOperand* operand) { results_[0] = operand; }
LOperand* result() { return results_[0]; }
- int InputCount() { return I; }
- LOperand* InputAt(int i) { return inputs_[i]; }
-
- int TempCount() { return T; }
- LOperand* TempAt(int i) { return temps_[i]; }
-
protected:
EmbeddedContainer<LOperand*, R> results_;
EmbeddedContainer<LOperand*, I> inputs_;
EmbeddedContainer<LOperand*, T> temps_;
+
+ private:
+ // Iterator support.
+ virtual int InputCount() { return I; }
+ virtual LOperand* InputAt(int i) { return inputs_[i]; }
+
+ virtual int TempCount() { return T; }
+ virtual LOperand* TempAt(int i) { return temps_[i]; }
};
@@ -413,11 +424,11 @@ class LCallStub: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
+ LOperand* context() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
DECLARE_HYDROGEN_ACCESSOR(CallStub)
- LOperand* context() { return inputs_[0]; }
-
TranscendentalCache::Type transcendental_type() {
return hydrogen()->transcendental_type();
}
@@ -457,10 +468,11 @@ class LWrapReceiver: public LTemplateInstruction<1, 2, 1> {
temps_[0] = temp;
}
- DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
-
LOperand* receiver() { return inputs_[0]; }
LOperand* function() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
};
@@ -476,12 +488,12 @@ class LApplyArguments: public LTemplateInstruction<1, 4, 0> {
inputs_[3] = elements;
}
- DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
-
LOperand* function() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* length() { return inputs_[2]; }
LOperand* elements() { return inputs_[3]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
};
@@ -493,12 +505,12 @@ class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> {
inputs_[2] = index;
}
- DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
-
LOperand* arguments() { return inputs_[0]; }
LOperand* length() { return inputs_[1]; }
LOperand* index() { return inputs_[2]; }
+ DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
+
virtual void PrintDataTo(StringStream* stream);
};
@@ -509,6 +521,8 @@ class LArgumentsLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = elements;
}
+ LOperand* elements() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
};
@@ -528,6 +542,10 @@ class LModI: public LTemplateInstruction<1, 2, 1> {
temps_[0] = temp;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
DECLARE_HYDROGEN_ACCESSOR(Mod)
};
@@ -541,11 +559,33 @@ class LDivI: public LTemplateInstruction<1, 2, 1> {
temps_[0] = temp;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(Div)
};
+class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> {
+ public:
+ LMathFloorOfDiv(LOperand* left,
+ LOperand* right,
+ LOperand* temp = NULL) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ temps_[0] = temp;
+ }
+
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
+ DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
class LMulI: public LTemplateInstruction<1, 2, 1> {
public:
LMulI(LOperand* left, LOperand* right, LOperand* temp) {
@@ -554,6 +594,10 @@ class LMulI: public LTemplateInstruction<1, 2, 1> {
temps_[0] = temp;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
DECLARE_HYDROGEN_ACCESSOR(Mul)
};
@@ -566,6 +610,9 @@ class LCmpIDAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
@@ -621,6 +668,9 @@ class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch,
"cmp-object-eq-and-branch")
};
@@ -632,6 +682,8 @@ class LCmpConstantEqAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = left;
}
+ LOperand* left() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpConstantEqAndBranch,
"cmp-constant-eq-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareConstantEqAndBranch)
@@ -645,6 +697,9 @@ class LIsNilAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch, "is-nil-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsNilAndBranch)
@@ -662,6 +717,9 @@ class LIsObjectAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
virtual void PrintDataTo(StringStream* stream);
@@ -675,6 +733,9 @@ class LIsStringAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
virtual void PrintDataTo(StringStream* stream);
@@ -687,6 +748,8 @@ class LIsSmiAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
@@ -701,6 +764,9 @@ class LIsUndetectableAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
"is-undetectable-and-branch")
@@ -716,6 +782,9 @@ class LStringCompareAndBranch: public LControlInstruction<3, 0> {
inputs_[2] = right;
}
+ LOperand* left() { return inputs_[1]; }
+ LOperand* right() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
"string-compare-and-branch")
DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
@@ -733,6 +802,9 @@ class LHasInstanceTypeAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
"has-instance-type-and-branch")
DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
@@ -747,6 +819,8 @@ class LGetCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
};
@@ -758,8 +832,11 @@ class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
"has-cached-array-index-and-branch")
+
virtual void PrintDataTo(StringStream* stream);
};
@@ -770,6 +847,8 @@ class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
temps_[0] = temp;
}
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
"is-construct-call-and-branch")
};
@@ -783,6 +862,10 @@ class LClassOfTestAndBranch: public LControlInstruction<1, 2> {
temps_[1] = temp2;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
"class-of-test-and-branch")
DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
@@ -814,9 +897,9 @@ class LInstanceOf: public LTemplateInstruction<1, 3, 0> {
inputs_[2] = right;
}
- DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
-
LOperand* context() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
};
@@ -828,6 +911,9 @@ class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 2, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
"instance-of-known-global")
DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
@@ -856,6 +942,7 @@ class LBoundsCheck: public LTemplateInstruction<0, 2, 0> {
LOperand* length() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
+ DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
};
@@ -866,10 +953,13 @@ class LBitI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
- Token::Value op() const { return hydrogen()->op(); }
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
DECLARE_HYDROGEN_ACCESSOR(Bitwise)
+
+ Token::Value op() const { return hydrogen()->op(); }
};
@@ -881,12 +971,14 @@ class LShiftI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
- Token::Value op() const { return op_; }
-
- bool can_deopt() const { return can_deopt_; }
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
+ Token::Value op() const { return op_; }
+ bool can_deopt() const { return can_deopt_; }
+
private:
Token::Value op_;
bool can_deopt_;
@@ -900,6 +992,9 @@ class LSubI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
DECLARE_HYDROGEN_ACCESSOR(Sub)
};
@@ -920,6 +1015,8 @@ class LConstantD: public LTemplateInstruction<1, 0, 1> {
temps_[0] = temp;
}
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
DECLARE_HYDROGEN_ACCESSOR(Constant)
@@ -938,11 +1035,14 @@ class LConstantT: public LTemplateInstruction<1, 0, 0> {
class LBranch: public LControlInstruction<1, 1> {
public:
- explicit LBranch(LOperand* value, LOperand* temp) {
+ LBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
DECLARE_HYDROGEN_ACCESSOR(Branch)
@@ -956,6 +1056,8 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMap)
@@ -977,6 +1079,8 @@ class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
};
@@ -988,18 +1092,34 @@ class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength,
"fixed-array-base-length")
DECLARE_HYDROGEN_ACCESSOR(FixedArrayBaseLength)
};
+class LMapEnumLength: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LMapEnumLength(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
+};
+
+
class LElementsKind: public LTemplateInstruction<1, 1, 0> {
public:
explicit LElementsKind(LOperand* value) {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
};
@@ -1012,6 +1132,9 @@ class LValueOf: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
DECLARE_HYDROGEN_ACCESSOR(ValueOf)
};
@@ -1025,6 +1148,9 @@ class LDateField: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* date() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
DECLARE_HYDROGEN_ACCESSOR(DateField)
@@ -1055,6 +1181,8 @@ class LBitNotI: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
};
@@ -1066,11 +1194,29 @@ class LAddI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
DECLARE_HYDROGEN_ACCESSOR(Add)
};
+class LMathMinMax: public LTemplateInstruction<1, 2, 0> {
+ public:
+ LMathMinMax(LOperand* left, LOperand* right) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ }
+
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "min-max")
+ DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
+};
+
+
class LPower: public LTemplateInstruction<1, 2, 0> {
public:
LPower(LOperand* left, LOperand* right) {
@@ -1078,6 +1224,9 @@ class LPower: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(Power, "power")
DECLARE_HYDROGEN_ACCESSOR(Power)
};
@@ -1089,6 +1238,8 @@ class LRandom: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = global_object;
}
+ LOperand* global_object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Random, "random")
DECLARE_HYDROGEN_ACCESSOR(Random)
};
@@ -1102,6 +1253,9 @@ class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
Token::Value op() const { return op_; }
virtual Opcode opcode() const { return LInstruction::kArithmeticD; }
@@ -1125,14 +1279,15 @@ class LArithmeticT: public LTemplateInstruction<1, 3, 0> {
inputs_[2] = right;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* left() { return inputs_[1]; }
+ LOperand* right() { return inputs_[2]; }
+
virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
Token::Value op() const { return op_; }
- LOperand* context() { return inputs_[0]; }
- LOperand* left() { return inputs_[1]; }
- LOperand* right() { return inputs_[2]; }
private:
Token::Value op_;
@@ -1155,10 +1310,10 @@ class LLoadNamedField: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
-
- LOperand* object() { return inputs_[0]; }
};
@@ -1169,11 +1324,11 @@ class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = object;
}
- DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
- DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
-
LOperand* context() { return inputs_[0]; }
LOperand* object() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
+ DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
};
@@ -1184,11 +1339,12 @@ class LLoadNamedGeneric: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = object;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* object() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
- LOperand* context() { return inputs_[0]; }
- LOperand* object() { return inputs_[1]; }
Handle<Object> name() const { return hydrogen()->name(); }
};
@@ -1200,10 +1356,11 @@ class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* function() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
-
- LOperand* function() { return inputs_[0]; }
};
@@ -1213,6 +1370,8 @@ class LLoadElements: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
};
@@ -1223,6 +1382,8 @@ class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
"load-external-array-pointer")
};
@@ -1235,11 +1396,12 @@ class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
+ LOperand* elements() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
- LOperand* elements() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1251,16 +1413,30 @@ class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
+ LOperand* elements() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement,
"load-keyed-fast-double-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastDoubleElement)
- LOperand* elements() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
+inline static bool ExternalArrayOpRequiresTemp(
+ Representation key_representation,
+ ElementsKind elements_kind) {
+ // Operations that require the key to be divided by two to be converted into
+ // an index cannot fold the scale operation into a load and need an extra
+ // temp register to do the work.
+ return key_representation.IsTagged() &&
+ (elements_kind == EXTERNAL_BYTE_ELEMENTS ||
+ elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS ||
+ elements_kind == EXTERNAL_PIXEL_ELEMENTS);
+}
+
+
class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
public:
LLoadKeyedSpecializedArrayElement(LOperand* external_pointer, LOperand* key) {
@@ -1268,12 +1444,13 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
+ LOperand* external_pointer() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
"load-keyed-specialized-array-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
- LOperand* external_pointer() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
ElementsKind elements_kind() const {
return hydrogen()->elements_kind();
}
@@ -1289,11 +1466,11 @@ class LLoadKeyedGeneric: public LTemplateInstruction<1, 3, 0> {
inputs_[2] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
-
LOperand* context() { return inputs_[0]; }
LOperand* object() { return inputs_[1]; }
LOperand* key() { return inputs_[2]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
};
@@ -1311,11 +1488,12 @@ class LLoadGlobalGeneric: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = global_object;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* global_object() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
- LOperand* context() { return inputs_[0]; }
- LOperand* global_object() { return inputs_[1]; }
Handle<Object> name() const { return hydrogen()->name(); }
bool for_typeof() const { return hydrogen()->for_typeof(); }
};
@@ -1327,10 +1505,10 @@ class LStoreGlobalCell: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
-
- LOperand* value() { return inputs_[0]; }
};
@@ -1344,13 +1522,14 @@ class LStoreGlobalGeneric: public LTemplateInstruction<0, 3, 0> {
inputs_[2] = value;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* global_object() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric)
- LOperand* context() { return InputAt(0); }
- LOperand* global_object() { return InputAt(1); }
Handle<Object> name() const { return hydrogen()->name(); }
- LOperand* value() { return InputAt(2); }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1361,10 +1540,11 @@ class LLoadContextSlot: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
+ LOperand* context() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
- LOperand* context() { return InputAt(0); }
int slot_index() { return hydrogen()->slot_index(); }
virtual void PrintDataTo(StringStream* stream);
@@ -1379,11 +1559,13 @@ class LStoreContextSlot: public LTemplateInstruction<0, 2, 1> {
temps_[0] = temp;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
- LOperand* context() { return InputAt(0); }
- LOperand* value() { return InputAt(1); }
int slot_index() { return hydrogen()->slot_index(); }
virtual void PrintDataTo(StringStream* stream);
@@ -1396,6 +1578,8 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
};
@@ -1432,9 +1616,9 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
- DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
+ LOperand* context() { return inputs_[0]; }
- LOperand* context() { return InputAt(0); }
+ DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
};
@@ -1444,6 +1628,8 @@ class LDeclareGlobals: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = context;
}
+ LOperand* context() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
};
@@ -1455,9 +1641,9 @@ class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
- DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
+ LOperand* context() { return inputs_[0]; }
- LOperand* context() { return InputAt(0); }
+ DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
};
@@ -1467,9 +1653,9 @@ class LGlobalReceiver: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = global_object;
}
- DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
+ LOperand* global() { return inputs_[0]; }
- LOperand* global() { return InputAt(0); }
+ DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
};
@@ -1492,12 +1678,12 @@ class LInvokeFunction: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = function;
}
- DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
- DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
-
LOperand* context() { return inputs_[0]; }
LOperand* function() { return inputs_[1]; }
+ DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
+ DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
+
virtual void PrintDataTo(StringStream* stream);
int arity() const { return hydrogen()->argument_count() - 1; }
@@ -1512,12 +1698,12 @@ class LCallKeyed: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
- DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
-
LOperand* context() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+ DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
+ DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
+
virtual void PrintDataTo(StringStream* stream);
int arity() const { return hydrogen()->argument_count() - 1; }
@@ -1530,12 +1716,13 @@ class LCallNamed: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
+ LOperand* context() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
DECLARE_HYDROGEN_ACCESSOR(CallNamed)
virtual void PrintDataTo(StringStream* stream);
- LOperand* context() { return inputs_[0]; }
Handle<String> name() const { return hydrogen()->name(); }
int arity() const { return hydrogen()->argument_count() - 1; }
};
@@ -1548,11 +1735,12 @@ class LCallFunction: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = function;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* function() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
DECLARE_HYDROGEN_ACCESSOR(CallFunction)
- LOperand* context() { return inputs_[0]; }
- LOperand* function() { return inputs_[1]; }
int arity() const { return hydrogen()->argument_count() - 1; }
};
@@ -1563,12 +1751,13 @@ class LCallGlobal: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
+ LOperand* context() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
virtual void PrintDataTo(StringStream* stream);
- LOperand* context() { return inputs_[0]; }
Handle<String> name() const {return hydrogen()->name(); }
int arity() const { return hydrogen()->argument_count() - 1; }
};
@@ -1593,13 +1782,14 @@ class LCallNew: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = constructor;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* constructor() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
DECLARE_HYDROGEN_ACCESSOR(CallNew)
virtual void PrintDataTo(StringStream* stream);
- LOperand* context() { return inputs_[0]; }
- LOperand* constructor() { return inputs_[1]; }
int arity() const { return hydrogen()->argument_count() - 1; }
};
@@ -1609,10 +1799,12 @@ class LCallRuntime: public LTemplateInstruction<1, 1, 0> {
explicit LCallRuntime(LOperand* context) {
inputs_[0] = context;
}
+
+ LOperand* context() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
- LOperand* context() { return inputs_[0]; }
const Runtime::Function* function() const { return hydrogen()->function(); }
int arity() const { return hydrogen()->argument_count(); }
};
@@ -1624,20 +1816,51 @@ class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
};
+class LUint32ToDouble: public LTemplateInstruction<1, 1, 1> {
+ public:
+ explicit LUint32ToDouble(LOperand* value, LOperand* temp) {
+ inputs_[0] = value;
+ temps_[0] = temp;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
+};
+
+
class LNumberTagI: public LTemplateInstruction<1, 1, 0> {
public:
explicit LNumberTagI(LOperand* value) {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
};
+class LNumberTagU: public LTemplateInstruction<1, 1, 1> {
+ public:
+ explicit LNumberTagU(LOperand* value, LOperand* temp) {
+ inputs_[0] = value;
+ temps_[0] = temp;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
+};
+
+
class LNumberTagD: public LTemplateInstruction<1, 1, 1> {
public:
LNumberTagD(LOperand* value, LOperand* temp) {
@@ -1645,6 +1868,9 @@ class LNumberTagD: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
};
@@ -1657,6 +1883,9 @@ class LDoubleToI: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
@@ -1672,6 +1901,9 @@ class LTaggedToI: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
@@ -1685,6 +1917,8 @@ class LSmiTag: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
};
@@ -1696,6 +1930,9 @@ class LNumberUntagD: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
DECLARE_HYDROGEN_ACCESSOR(Change);
};
@@ -1708,6 +1945,8 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
bool needs_check() const { return needs_check_; }
@@ -1729,14 +1968,16 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 2> {
temps_[1] = temp_map;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp_map() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* value() { return inputs_[1]; }
-
Handle<Object> name() const { return hydrogen()->name(); }
bool is_in_object() { return hydrogen()->is_in_object(); }
int offset() { return hydrogen()->offset(); }
@@ -1752,14 +1993,14 @@ class LStoreNamedGeneric: public LTemplateInstruction<0, 3, 0> {
inputs_[2] = value;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* object() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
virtual void PrintDataTo(StringStream* stream);
-
- LOperand* context() { return inputs_[0]; }
- LOperand* object() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
Handle<Object> name() const { return hydrogen()->name(); }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1773,15 +2014,15 @@ class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
inputs_[2] = val;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
"store-keyed-fast-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
virtual void PrintDataTo(StringStream* stream);
-
- LOperand* object() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1796,15 +2037,16 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
inputs_[2] = val;
}
+ LOperand* elements() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement,
"store-keyed-fast-double-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastDoubleElement)
virtual void PrintDataTo(StringStream* stream);
- LOperand* elements() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
@@ -1821,13 +2063,14 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
inputs_[2] = val;
}
+ LOperand* external_pointer() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
"store-keyed-specialized-array-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
- LOperand* external_pointer() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
ElementsKind elements_kind() const {
return hydrogen()->elements_kind();
}
@@ -1847,15 +2090,16 @@ class LStoreKeyedGeneric: public LTemplateInstruction<0, 4, 0> {
inputs_[3] = value;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* object() { return inputs_[1]; }
+ LOperand* key() { return inputs_[2]; }
+ LOperand* value() { return inputs_[3]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
virtual void PrintDataTo(StringStream* stream);
- LOperand* context() { return inputs_[0]; }
- LOperand* object() { return inputs_[1]; }
- LOperand* key() { return inputs_[2]; }
- LOperand* value() { return inputs_[3]; }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1864,21 +2108,22 @@ class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> {
public:
LTransitionElementsKind(LOperand* object,
LOperand* new_map_temp,
- LOperand* temp_reg) {
+ LOperand* temp) {
inputs_[0] = object;
temps_[0] = new_map_temp;
- temps_[1] = temp_reg;
+ temps_[1] = temp;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* new_map_temp() { return temps_[0]; }
+ LOperand* temp() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
"transition-elements-kind")
DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* new_map_reg() { return temps_[0]; }
- LOperand* temp_reg() { return temps_[1]; }
Handle<Map> original_map() { return hydrogen()->original_map(); }
Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); }
};
@@ -1892,12 +2137,12 @@ class LStringAdd: public LTemplateInstruction<1, 3, 0> {
inputs_[2] = right;
}
- DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
- DECLARE_HYDROGEN_ACCESSOR(StringAdd)
-
LOperand* context() { return inputs_[0]; }
LOperand* left() { return inputs_[1]; }
LOperand* right() { return inputs_[2]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
+ DECLARE_HYDROGEN_ACCESSOR(StringAdd)
};
@@ -1909,12 +2154,12 @@ class LStringCharCodeAt: public LTemplateInstruction<1, 3, 0> {
inputs_[2] = index;
}
- DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
- DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
-
LOperand* context() { return inputs_[0]; }
LOperand* string() { return inputs_[1]; }
LOperand* index() { return inputs_[2]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
+ DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
};
@@ -1925,11 +2170,11 @@ class LStringCharFromCode: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = char_code;
}
- DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
- DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
-
LOperand* context() { return inputs_[0]; }
LOperand* char_code() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
+ DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
};
@@ -1939,10 +2184,10 @@ class LStringLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = string;
}
+ LOperand* string() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
DECLARE_HYDROGEN_ACCESSOR(StringLength)
-
- LOperand* string() { return inputs_[0]; }
};
@@ -1966,6 +2211,9 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
};
@@ -1977,6 +2225,8 @@ class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
};
@@ -1988,6 +2238,8 @@ class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 1> {
temps_[0] = temp;
}
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
@@ -2002,6 +2254,8 @@ class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
};
@@ -2049,6 +2303,8 @@ class LCheckNonSmi: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
};
@@ -2060,10 +2316,11 @@ class LAllocateObject: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object")
DECLARE_HYDROGEN_ACCESSOR(AllocateObject)
-
- LOperand* context() { return inputs_[0]; }
};
@@ -2140,6 +2397,8 @@ class LToFastProperties: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
};
@@ -2152,6 +2411,9 @@ class LTypeof: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = value;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
};
@@ -2162,6 +2424,8 @@ class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
@@ -2179,11 +2443,11 @@ class LDeleteProperty: public LTemplateInstruction<1, 3, 0> {
inputs_[2] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
-
LOperand* context() { return inputs_[0]; }
LOperand* object() { return inputs_[1]; }
LOperand* key() { return inputs_[2]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
};
@@ -2303,74 +2567,19 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> {
class LChunkBuilder;
-class LChunk: public ZoneObject {
- public:
- LChunk(CompilationInfo* info, HGraph* graph)
- : spill_slot_count_(0),
- num_double_slots_(0),
- info_(info),
- graph_(graph),
- instructions_(32, graph->zone()),
- pointer_maps_(8, graph->zone()),
- inlined_closures_(1, graph->zone()) { }
-
- void AddInstruction(LInstruction* instruction, HBasicBlock* block);
- LConstantOperand* DefineConstantOperand(HConstant* constant);
- Handle<Object> LookupLiteral(LConstantOperand* operand) const;
- Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
+class LPlatformChunk: public LChunk {
+ public:
+ LPlatformChunk(CompilationInfo* info, HGraph* graph)
+ : LChunk(info, graph),
+ num_double_slots_(0) { }
int GetNextSpillIndex(bool is_double);
LOperand* GetNextSpillSlot(bool is_double);
- int ParameterAt(int index);
- int GetParameterStackSlot(int index) const;
- int spill_slot_count() const { return spill_slot_count_; }
int num_double_slots() const { return num_double_slots_; }
- CompilationInfo* info() const { return info_; }
- HGraph* graph() const { return graph_; }
- const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
- void AddGapMove(int index, LOperand* from, LOperand* to);
- LGap* GetGapAt(int index) const;
- bool IsGapAt(int index) const;
- int NearestGapPos(int index) const;
- void MarkEmptyBlocks();
- const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
- LLabel* GetLabel(int block_id) const {
- HBasicBlock* block = graph_->blocks()->at(block_id);
- int first_instruction = block->first_instruction_index();
- return LLabel::cast(instructions_[first_instruction]);
- }
- int LookupDestination(int block_id) const {
- LLabel* cur = GetLabel(block_id);
- while (cur->replacement() != NULL) {
- cur = cur->replacement();
- }
- return cur->block_id();
- }
- Label* GetAssemblyLabel(int block_id) const {
- LLabel* label = GetLabel(block_id);
- ASSERT(!label->HasReplacement());
- return label->label();
- }
-
- const ZoneList<Handle<JSFunction> >* inlined_closures() const {
- return &inlined_closures_;
- }
-
- void AddInlinedClosure(Handle<JSFunction> closure) {
- inlined_closures_.Add(closure, zone());
- }
-
- Zone* zone() const { return graph_->zone(); }
private:
- int spill_slot_count_;
int num_double_slots_;
- CompilationInfo* info_;
- HGraph* const graph_;
- ZoneList<LInstruction*> instructions_;
- ZoneList<LPointerMap*> pointer_maps_;
- ZoneList<Handle<JSFunction> > inlined_closures_;
};
@@ -2389,16 +2598,19 @@ class LChunkBuilder BASE_EMBEDDED {
allocator_(allocator),
position_(RelocInfo::kNoPosition),
instruction_pending_deoptimization_environment_(NULL),
- pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
+ pending_deoptimization_ast_id_(BailoutId::None()) { }
// Build the sequence for the graph.
- LChunk* Build();
+ LPlatformChunk* Build();
// Declare methods that deal with the individual node types.
#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
+ static HValue* SimplifiedDividendForMathFloorOfDiv(HValue* val);
+ static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
+
private:
enum Status {
UNUSED,
@@ -2407,7 +2619,7 @@ class LChunkBuilder BASE_EMBEDDED {
ABORTED
};
- LChunk* chunk() const { return chunk_; }
+ LPlatformChunk* chunk() const { return chunk_; }
CompilationInfo* info() const { return info_; }
HGraph* graph() const { return graph_; }
Zone* zone() const { return zone_; }
@@ -2417,7 +2629,7 @@ class LChunkBuilder BASE_EMBEDDED {
bool is_done() const { return status_ == DONE; }
bool is_aborted() const { return status_ == ABORTED; }
- void Abort(const char* format, ...);
+ void Abort(const char* reason);
// Methods for getting operands for Use / Define / Temp.
LUnallocated* ToUnallocated(Register reg);
@@ -2511,7 +2723,7 @@ class LChunkBuilder BASE_EMBEDDED {
LInstruction* DoArithmeticT(Token::Value op,
HArithmeticBinaryOperation* instr);
- LChunk* chunk_;
+ LPlatformChunk* chunk_;
CompilationInfo* info_;
HGraph* const graph_;
Zone* zone_;
@@ -2523,7 +2735,7 @@ class LChunkBuilder BASE_EMBEDDED {
LAllocator* allocator_;
int position_;
LInstruction* instruction_pending_deoptimization_environment_;
- int pending_deoptimization_ast_id_;
+ BailoutId pending_deoptimization_ast_id_;
DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
};
diff --git a/deps/v8/src/ia32/macro-assembler-ia32.cc b/deps/v8/src/ia32/macro-assembler-ia32.cc
index 2012a5ad9..0d0bf0377 100644
--- a/deps/v8/src/ia32/macro-assembler-ia32.cc
+++ b/deps/v8/src/ia32/macro-assembler-ia32.cc
@@ -85,7 +85,7 @@ void MacroAssembler::RememberedSetHelper(
SaveFPRegsMode save_fp,
MacroAssembler::RememberedSetFinalAction and_then) {
Label done;
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
Label ok;
JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear);
int3();
@@ -129,17 +129,22 @@ void MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg,
XMMRegister scratch_reg,
Register result_reg) {
Label done;
- ExternalReference zero_ref = ExternalReference::address_of_zero();
- movdbl(scratch_reg, Operand::StaticVariable(zero_ref));
+ Label conv_failure;
+ pxor(scratch_reg, scratch_reg);
+ cvtsd2si(result_reg, input_reg);
+ test(result_reg, Immediate(0xFFFFFF00));
+ j(zero, &done, Label::kNear);
+ cmp(result_reg, Immediate(0x80000000));
+ j(equal, &conv_failure, Label::kNear);
+ mov(result_reg, Immediate(0));
+ setcc(above, result_reg);
+ sub(result_reg, Immediate(1));
+ and_(result_reg, Immediate(255));
+ jmp(&done, Label::kNear);
+ bind(&conv_failure);
Set(result_reg, Immediate(0));
ucomisd(input_reg, scratch_reg);
j(below, &done, Label::kNear);
- ExternalReference half_ref = ExternalReference::address_of_one_half();
- movdbl(scratch_reg, Operand::StaticVariable(half_ref));
- addsd(scratch_reg, input_reg);
- cvttsd2si(result_reg, Operand(scratch_reg));
- test(result_reg, Immediate(0xFFFFFF00));
- j(zero, &done, Label::kNear);
Set(result_reg, Immediate(255));
bind(&done);
}
@@ -155,6 +160,24 @@ void MacroAssembler::ClampUint8(Register reg) {
}
+static double kUint32Bias =
+ static_cast<double>(static_cast<uint32_t>(0xFFFFFFFF)) + 1;
+
+
+void MacroAssembler::LoadUint32(XMMRegister dst,
+ Register src,
+ XMMRegister scratch) {
+ Label done;
+ cmp(src, Immediate(0));
+ movdbl(scratch,
+ Operand(reinterpret_cast<int32_t>(&kUint32Bias), RelocInfo::NONE));
+ cvtsi2sd(dst, src);
+ j(not_sign, &done, Label::kNear);
+ addsd(dst, scratch);
+ bind(&done);
+}
+
+
void MacroAssembler::RecordWriteArray(Register object,
Register value,
Register index,
@@ -259,9 +282,7 @@ void MacroAssembler::RecordWriteForMap(
ASSERT(!object.is(value));
ASSERT(!object.is(address));
ASSERT(!value.is(address));
- if (emit_debug_code()) {
- AbortIfSmi(object);
- }
+ AssertNotSmi(object);
if (!FLAG_incremental_marking) {
return;
@@ -308,16 +329,14 @@ void MacroAssembler::RecordWrite(Register object,
ASSERT(!object.is(value));
ASSERT(!object.is(address));
ASSERT(!value.is(address));
- if (emit_debug_code()) {
- AbortIfSmi(object);
- }
+ AssertNotSmi(object);
if (remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) {
return;
}
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
Label ok;
cmp(value, Operand(address, 0));
j(equal, &ok, Label::kNear);
@@ -653,36 +672,44 @@ void MacroAssembler::FCmp() {
}
-void MacroAssembler::AbortIfNotNumber(Register object) {
- Label ok;
- JumpIfSmi(object, &ok);
- cmp(FieldOperand(object, HeapObject::kMapOffset),
- isolate()->factory()->heap_number_map());
- Assert(equal, "Operand not a number");
- bind(&ok);
+void MacroAssembler::AssertNumber(Register object) {
+ if (emit_debug_code()) {
+ Label ok;
+ JumpIfSmi(object, &ok);
+ cmp(FieldOperand(object, HeapObject::kMapOffset),
+ isolate()->factory()->heap_number_map());
+ Check(equal, "Operand not a number");
+ bind(&ok);
+ }
}
-void MacroAssembler::AbortIfNotSmi(Register object) {
- test(object, Immediate(kSmiTagMask));
- Assert(equal, "Operand is not a smi");
+void MacroAssembler::AssertSmi(Register object) {
+ if (emit_debug_code()) {
+ test(object, Immediate(kSmiTagMask));
+ Check(equal, "Operand is not a smi");
+ }
}
-void MacroAssembler::AbortIfNotString(Register object) {
- test(object, Immediate(kSmiTagMask));
- Assert(not_equal, "Operand is not a string");
- push(object);
- mov(object, FieldOperand(object, HeapObject::kMapOffset));
- CmpInstanceType(object, FIRST_NONSTRING_TYPE);
- pop(object);
- Assert(below, "Operand is not a string");
+void MacroAssembler::AssertString(Register object) {
+ if (emit_debug_code()) {
+ test(object, Immediate(kSmiTagMask));
+ Check(not_equal, "Operand is a smi and not a string");
+ push(object);
+ mov(object, FieldOperand(object, HeapObject::kMapOffset));
+ CmpInstanceType(object, FIRST_NONSTRING_TYPE);
+ pop(object);
+ Check(below, "Operand is not a string");
+ }
}
-void MacroAssembler::AbortIfSmi(Register object) {
- test(object, Immediate(kSmiTagMask));
- Assert(not_equal, "Operand is a smi");
+void MacroAssembler::AssertNotSmi(Register object) {
+ if (emit_debug_code()) {
+ test(object, Immediate(kSmiTagMask));
+ Check(not_equal, "Operand is a smi");
+ }
}
@@ -982,23 +1009,24 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
cmp(scratch, Immediate(0));
Check(not_equal, "we should not have an empty lexical context");
}
- // Load the global context of the current context.
- int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ // Load the native context of the current context.
+ int offset =
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
mov(scratch, FieldOperand(scratch, offset));
- mov(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
+ mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
- // Check the context is a global context.
+ // Check the context is a native context.
if (emit_debug_code()) {
push(scratch);
- // Read the first word and compare to global_context_map.
+ // Read the first word and compare to native_context_map.
mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
- cmp(scratch, isolate()->factory()->global_context_map());
- Check(equal, "JSGlobalObject::global_context should be a global context.");
+ cmp(scratch, isolate()->factory()->native_context_map());
+ Check(equal, "JSGlobalObject::native_context should be a native context.");
pop(scratch);
}
// Check if both contexts are the same.
- cmp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
+ cmp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
j(equal, &same_contexts);
// Compare security tokens, save holder_reg on the stack so we can use it
@@ -1009,18 +1037,19 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
// Check that the security token in the calling global object is
// compatible with the security token in the receiving global
// object.
- mov(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
+ mov(holder_reg,
+ FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
- // Check the context is a global context.
+ // Check the context is a native context.
if (emit_debug_code()) {
cmp(holder_reg, isolate()->factory()->null_value());
Check(not_equal, "JSGlobalProxy::context() should not be null.");
push(holder_reg);
- // Read the first word and compare to global_context_map(),
+ // Read the first word and compare to native_context_map(),
mov(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset));
- cmp(holder_reg, isolate()->factory()->global_context_map());
- Check(equal, "JSGlobalObject::global_context should be a global context.");
+ cmp(holder_reg, isolate()->factory()->native_context_map());
+ Check(equal, "JSGlobalObject::native_context should be a native context.");
pop(holder_reg);
}
@@ -1707,7 +1736,7 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
}
-void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) {
+void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs.
call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
}
@@ -1922,16 +1951,53 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
cmp(Operand::StaticVariable(scheduled_exception_address),
Immediate(isolate()->factory()->the_hole_value()));
j(not_equal, &promote_scheduled_exception);
+
+#if ENABLE_EXTRA_CHECKS
+ // Check if the function returned a valid JavaScript value.
+ Label ok;
+ Register return_value = eax;
+ Register map = ecx;
+
+ JumpIfSmi(return_value, &ok, Label::kNear);
+ mov(map, FieldOperand(return_value, HeapObject::kMapOffset));
+
+ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
+ j(below, &ok, Label::kNear);
+
+ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
+ j(above_equal, &ok, Label::kNear);
+
+ cmp(map, isolate()->factory()->heap_number_map());
+ j(equal, &ok, Label::kNear);
+
+ cmp(return_value, isolate()->factory()->undefined_value());
+ j(equal, &ok, Label::kNear);
+
+ cmp(return_value, isolate()->factory()->true_value());
+ j(equal, &ok, Label::kNear);
+
+ cmp(return_value, isolate()->factory()->false_value());
+ j(equal, &ok, Label::kNear);
+
+ cmp(return_value, isolate()->factory()->null_value());
+ j(equal, &ok, Label::kNear);
+
+ Abort("API call returned invalid object");
+
+ bind(&ok);
+#endif
+
LeaveApiExitFrame();
ret(stack_space * kPointerSize);
- bind(&promote_scheduled_exception);
- TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
bind(&empty_handle);
// It was zero; the result is undefined.
mov(eax, isolate()->factory()->undefined_value());
jmp(&prologue);
+ bind(&promote_scheduled_exception);
+ TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
+
// HandleScope limit has changed. Delete allocated extensions.
ExternalReference delete_extensions =
ExternalReference::delete_handle_scope_extensions(isolate());
@@ -2169,7 +2235,7 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
void MacroAssembler::GetBuiltinFunction(Register target,
Builtins::JavaScript id) {
// Load the JavaScript builtin function from the builtins object.
- mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
mov(target, FieldOperand(target,
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
@@ -2218,8 +2284,8 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
Register scratch,
Label* no_map_match) {
// Load the global or builtins object from the current context.
- mov(scratch, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- mov(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
+ mov(scratch, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
// Check that the function's map is the same as the expected cached map.
mov(scratch, Operand(scratch,
@@ -2264,10 +2330,11 @@ void MacroAssembler::LoadInitialArrayMap(
void MacroAssembler::LoadGlobalFunction(int index, Register function) {
// Load the global or builtins object from the current context.
- mov(function, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- // Load the global context from the global or builtins object.
- mov(function, FieldOperand(function, GlobalObject::kGlobalContextOffset));
- // Load the function from the global context.
+ mov(function,
+ Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ // Load the native context from the global or builtins object.
+ mov(function, FieldOperand(function, GlobalObject::kNativeContextOffset));
+ // Load the function from the native context.
mov(function, Operand(function, Context::SlotOffset(index)));
}
@@ -2518,12 +2585,13 @@ void MacroAssembler::Abort(const char* msg) {
void MacroAssembler::LoadInstanceDescriptors(Register map,
Register descriptors) {
- mov(descriptors,
- FieldOperand(map, Map::kInstanceDescriptorsOrBitField3Offset));
- Label not_smi;
- JumpIfNotSmi(descriptors, &not_smi);
- mov(descriptors, isolate()->factory()->empty_descriptor_array());
- bind(&not_smi);
+ mov(descriptors, FieldOperand(map, Map::kDescriptorsOffset));
+}
+
+
+void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
+ mov(dst, FieldOperand(map, Map::kBitField3Offset));
+ DecodeField<Map::NumberOfOwnDescriptorsBits>(dst);
}
@@ -2786,7 +2854,7 @@ void MacroAssembler::EnsureNotWhite(
test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize));
j(not_zero, &done, Label::kNear);
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// Check for impossible bit pattern.
Label ok;
push(mask_scratch);
@@ -2861,7 +2929,7 @@ void MacroAssembler::EnsureNotWhite(
and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask));
add(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset),
length);
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
mov(length, Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset));
cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset));
Check(less_equal, "Live Bytes Count overflow chunk size");
@@ -2871,40 +2939,43 @@ void MacroAssembler::EnsureNotWhite(
}
+void MacroAssembler::EnumLength(Register dst, Register map) {
+ STATIC_ASSERT(Map::EnumLengthBits::kShift == 0);
+ mov(dst, FieldOperand(map, Map::kBitField3Offset));
+ and_(dst, Immediate(Smi::FromInt(Map::EnumLengthBits::kMask)));
+}
+
+
void MacroAssembler::CheckEnumCache(Label* call_runtime) {
- Label next;
+ Label next, start;
mov(ecx, eax);
- bind(&next);
-
- // Check that there are no elements. Register ecx contains the
- // current JS object we've reached through the prototype chain.
- cmp(FieldOperand(ecx, JSObject::kElementsOffset),
- isolate()->factory()->empty_fixed_array());
- j(not_equal, call_runtime);
- // Check that instance descriptors are not empty so that we can
- // check for an enum cache. Leave the map in ebx for the subsequent
- // prototype load.
+ // Check if the enum length field is properly initialized, indicating that
+ // there is an enum cache.
mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset));
- mov(edx, FieldOperand(ebx, Map::kInstanceDescriptorsOrBitField3Offset));
- JumpIfSmi(edx, call_runtime);
- // Check that there is an enum cache in the non-empty instance
- // descriptors (edx). This is the case if the next enumeration
- // index field does not contain a smi.
- mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset));
- JumpIfSmi(edx, call_runtime);
+ EnumLength(edx, ebx);
+ cmp(edx, Immediate(Smi::FromInt(Map::kInvalidEnumCache)));
+ j(equal, call_runtime);
+
+ jmp(&start);
+
+ bind(&next);
+ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset));
// For all objects but the receiver, check that the cache is empty.
- Label check_prototype;
- cmp(ecx, eax);
- j(equal, &check_prototype, Label::kNear);
- mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset));
- cmp(edx, isolate()->factory()->empty_fixed_array());
+ EnumLength(edx, ebx);
+ cmp(edx, Immediate(Smi::FromInt(0)));
+ j(not_equal, call_runtime);
+
+ bind(&start);
+
+ // Check that there are no elements. Register rcx contains the current JS
+ // object we've reached through the prototype chain.
+ mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset));
+ cmp(ecx, isolate()->factory()->empty_fixed_array());
j(not_equal, call_runtime);
- // Load the prototype from the map and loop if non-null.
- bind(&check_prototype);
mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
cmp(ecx, isolate()->factory()->null_value());
j(not_equal, &next);
diff --git a/deps/v8/src/ia32/macro-assembler-ia32.h b/deps/v8/src/ia32/macro-assembler-ia32.h
index 5c7a6d6d2..e48d0e75c 100644
--- a/deps/v8/src/ia32/macro-assembler-ia32.h
+++ b/deps/v8/src/ia32/macro-assembler-ia32.h
@@ -239,8 +239,8 @@ class MacroAssembler: public Assembler {
void LoadContext(Register dst, int context_chain_length);
// Conditionally load the cached Array transitioned map of type
- // transitioned_kind from the global context if the map in register
- // map_in_out is the cached Array map in the global context of
+ // transitioned_kind from the native context if the map in register
+ // map_in_out is the cached Array map in the native context of
// expected_kind.
void LoadTransitionedArrayMapConditional(
ElementsKind expected_kind,
@@ -467,6 +467,8 @@ class MacroAssembler: public Assembler {
j(not_carry, is_smi);
}
+ void LoadUint32(XMMRegister dst, Register src, XMMRegister scratch);
+
// Jump the register contains a smi.
inline void JumpIfSmi(Register value,
Label* smi_label,
@@ -490,20 +492,29 @@ class MacroAssembler: public Assembler {
}
void LoadInstanceDescriptors(Register map, Register descriptors);
-
+ void EnumLength(Register dst, Register map);
+ void NumberOfOwnDescriptors(Register dst, Register map);
+
+ template<typename Field>
+ void DecodeField(Register reg) {
+ static const int shift = Field::kShift;
+ static const int mask = (Field::kMask >> Field::kShift) << kSmiTagSize;
+ sar(reg, shift);
+ and_(reg, Immediate(mask));
+ }
void LoadPowerOf2(XMMRegister dst, Register scratch, int power);
- // Abort execution if argument is not a number. Used in debug code.
- void AbortIfNotNumber(Register object);
+ // Abort execution if argument is not a number, enabled via --debug-code.
+ void AssertNumber(Register object);
- // Abort execution if argument is not a smi. Used in debug code.
- void AbortIfNotSmi(Register object);
+ // Abort execution if argument is not a smi, enabled via --debug-code.
+ void AssertSmi(Register object);
- // Abort execution if argument is a smi. Used in debug code.
- void AbortIfSmi(Register object);
+ // Abort execution if argument is a smi, enabled via --debug-code.
+ void AssertNotSmi(Register object);
- // Abort execution if argument is a string. Used in debug code.
- void AbortIfNotString(Register object);
+ // Abort execution if argument is not a string, enabled via --debug-code.
+ void AssertString(Register object);
// ---------------------------------------------------------------------------
// Exception handling
@@ -688,7 +699,7 @@ class MacroAssembler: public Assembler {
// Runtime calls
// Call a code stub. Generate the code if necessary.
- void CallStub(CodeStub* stub, unsigned ast_id = kNoASTId);
+ void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None());
// Tail call a code stub (jump). Generate the code if necessary.
void TailCallStub(CodeStub* stub);
@@ -961,7 +972,7 @@ inline Operand ContextOperand(Register context, int index) {
inline Operand GlobalObjectOperand() {
- return ContextOperand(esi, Context::GLOBAL_INDEX);
+ return ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX);
}
diff --git a/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc b/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc
index 07782cc80..622dc4254 100644
--- a/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc
@@ -316,6 +316,11 @@ void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase(
// uncaptured. In either case succeed immediately.
__ j(equal, &fallthrough);
+ // Check that there are sufficient characters left in the input.
+ __ mov(eax, edi);
+ __ add(eax, ebx);
+ BranchOrBacktrack(greater, on_no_match);
+
if (mode_ == ASCII) {
Label success;
Label fail;
diff --git a/deps/v8/src/ia32/regexp-macro-assembler-ia32.h b/deps/v8/src/ia32/regexp-macro-assembler-ia32.h
index 760fadc77..7aea38586 100644
--- a/deps/v8/src/ia32/regexp-macro-assembler-ia32.h
+++ b/deps/v8/src/ia32/regexp-macro-assembler-ia32.h
@@ -34,14 +34,7 @@
namespace v8 {
namespace internal {
-#ifdef V8_INTERPRETED_REGEXP
-class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
- public:
- RegExpMacroAssemblerIA32() { }
- virtual ~RegExpMacroAssemblerIA32() { }
-};
-
-#else // V8_INTERPRETED_REGEXP
+#ifndef V8_INTERPRETED_REGEXP
class RegExpMacroAssemblerIA32: public NativeRegExpMacroAssembler {
public:
RegExpMacroAssemblerIA32(Mode mode, int registers_to_save, Zone* zone);
diff --git a/deps/v8/src/ia32/stub-cache-ia32.cc b/deps/v8/src/ia32/stub-cache-ia32.cc
index 0e4ce20bd..f5e2d0589 100644
--- a/deps/v8/src/ia32/stub-cache-ia32.cc
+++ b/deps/v8/src/ia32/stub-cache-ia32.cc
@@ -276,12 +276,12 @@ void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
Register prototype,
Label* miss) {
// Check we're still in the same context.
- __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)),
- masm->isolate()->global());
+ __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)),
+ masm->isolate()->global_object());
__ j(not_equal, miss);
// Get the global function with the given index.
Handle<JSFunction> function(
- JSFunction::cast(masm->isolate()->global_context()->get(index)));
+ JSFunction::cast(masm->isolate()->native_context()->get(index)));
// Load its initial map. The global functions all have initial maps.
__ Set(prototype, Immediate(Handle<Map>(function->initial_map())));
// Load the prototype from the initial map.
@@ -1052,6 +1052,58 @@ void StubCompiler::GenerateLoadField(Handle<JSObject> object,
}
+void StubCompiler::GenerateDictionaryLoadCallback(Register receiver,
+ Register name_reg,
+ Register scratch1,
+ Register scratch2,
+ Register scratch3,
+ Handle<AccessorInfo> callback,
+ Handle<String> name,
+ Label* miss) {
+ ASSERT(!receiver.is(scratch2));
+ ASSERT(!receiver.is(scratch3));
+ Register dictionary = scratch1;
+ bool must_preserve_dictionary_reg = receiver.is(dictionary);
+
+ // Load the properties dictionary.
+ if (must_preserve_dictionary_reg) {
+ __ push(dictionary);
+ }
+ __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset));
+
+ // Probe the dictionary.
+ Label probe_done, pop_and_miss;
+ StringDictionaryLookupStub::GeneratePositiveLookup(masm(),
+ &pop_and_miss,
+ &probe_done,
+ dictionary,
+ name_reg,
+ scratch2,
+ scratch3);
+ __ bind(&pop_and_miss);
+ if (must_preserve_dictionary_reg) {
+ __ pop(dictionary);
+ }
+ __ jmp(miss);
+ __ bind(&probe_done);
+
+ // If probing finds an entry in the dictionary, scratch2 contains the
+ // index into the dictionary. Check that the value is the callback.
+ Register index = scratch2;
+ const int kElementsStartOffset =
+ StringDictionary::kHeaderSize +
+ StringDictionary::kElementsStartIndex * kPointerSize;
+ const int kValueOffset = kElementsStartOffset + kPointerSize;
+ __ mov(scratch3,
+ Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag));
+ if (must_preserve_dictionary_reg) {
+ __ pop(dictionary);
+ }
+ __ cmp(scratch3, callback);
+ __ j(not_equal, miss);
+}
+
+
void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Handle<JSObject> holder,
Register receiver,
@@ -1059,6 +1111,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Register scratch1,
Register scratch2,
Register scratch3,
+ Register scratch4,
Handle<AccessorInfo> callback,
Handle<String> name,
Label* miss) {
@@ -1069,6 +1122,11 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Register reg = CheckPrototypes(object, receiver, holder, scratch1,
scratch2, scratch3, name, miss);
+ if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
+ GenerateDictionaryLoadCallback(
+ reg, name_reg, scratch1, scratch2, scratch3, callback, name, miss);
+ }
+
// Insert additional parameters into the stack frame above return address.
ASSERT(!scratch3.is(reg));
__ pop(scratch3); // Get return address to place it below.
@@ -1157,7 +1215,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
// later.
bool compile_followup_inline = false;
if (lookup->IsFound() && lookup->IsCacheable()) {
- if (lookup->type() == FIELD) {
+ if (lookup->IsField()) {
compile_followup_inline = true;
} else if (lookup->type() == CALLBACKS &&
lookup->GetCallbackObject()->IsAccessorInfo()) {
@@ -1242,7 +1300,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
miss);
}
- if (lookup->type() == FIELD) {
+ if (lookup->IsField()) {
// We found FIELD property in prototype chain of interceptor's holder.
// Retrieve a field from field's holder.
GenerateFastPropertyLoad(masm(), eax, holder_reg,
@@ -1415,7 +1473,7 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
GenerateMissBranch();
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -1962,7 +2020,7 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2092,7 +2150,7 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2197,7 +2255,7 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2444,7 +2502,7 @@ Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
GenerateMissBranch();
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2505,7 +2563,7 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
GenerateMissBranch();
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2536,14 +2594,17 @@ Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
Handle<Code> StoreStubCompiler::CompileStoreCallback(
- Handle<JSObject> object,
- Handle<AccessorInfo> callback,
- Handle<String> name) {
+ Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- eax : value
// -- ecx : name
@@ -2551,19 +2612,14 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -- esp[0] : return address
// -----------------------------------
Label miss;
+ // Check that the maps haven't changed, preserving the value register.
+ __ push(eax);
+ __ JumpIfSmi(edx, &miss);
+ CheckPrototypes(receiver, edx, holder, ebx, eax, edi, name, &miss);
+ __ pop(eax); // restore value
- // Check that the map of the object hasn't changed.
- __ CheckMap(edx, Handle<Map>(object->map()),
- &miss, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
-
- // Perform global security token check if needed.
- if (object->IsJSGlobalProxy()) {
- __ CheckAccessGlobalProxy(edx, ebx, &miss);
- }
-
- // Stub never generated for non-global objects that require access
- // checks.
- ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
+ // Stub never generated for non-global objects that require access checks.
+ ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
__ pop(ebx); // remove the return address
__ push(edx); // receiver
@@ -2579,42 +2635,46 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// Handle store cache miss.
__ bind(&miss);
+ __ pop(eax);
Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
-Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
- Handle<JSObject> receiver,
- Handle<JSFunction> setter,
- Handle<String> name) {
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void StoreStubCompiler::GenerateStoreViaSetter(
+ MacroAssembler* masm,
+ Handle<JSFunction> setter) {
// ----------- S t a t e -------------
// -- eax : value
// -- ecx : name
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
- Label miss;
-
- // Check that the map of the object hasn't changed.
- __ CheckMap(edx, Handle<Map>(receiver->map()), &miss, DO_SMI_CHECK,
- ALLOW_ELEMENT_TRANSITION_MAPS);
-
{
- FrameScope scope(masm(), StackFrame::INTERNAL);
+ FrameScope scope(masm, StackFrame::INTERNAL);
// Save value register, so we can restore it later.
__ push(eax);
- // Call the JavaScript getter with the receiver and the value on the stack.
- __ push(edx);
- __ push(eax);
- ParameterCount actual(1);
- __ InvokeFunction(setter, actual, CALL_FUNCTION, NullCallWrapper(),
- CALL_AS_METHOD);
+ if (!setter.is_null()) {
+ // Call the JavaScript setter with receiver and value on the stack.
+ __ push(edx);
+ __ push(eax);
+ ParameterCount actual(1);
+ __ InvokeFunction(setter, actual, CALL_FUNCTION, NullCallWrapper(),
+ CALL_AS_METHOD);
+ } else {
+ // If we generate a global code snippet for deoptimization only, remember
+ // the place to continue after deoptimization.
+ masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+ }
// We have to return the passed value, not the return value of the setter.
__ pop(eax);
@@ -2623,13 +2683,41 @@ Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
}
__ ret(0);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
+Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
+ Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<JSFunction> setter) {
+ // ----------- S t a t e -------------
+ // -- eax : value
+ // -- ecx : name
+ // -- edx : receiver
+ // -- esp[0] : return address
+ // -----------------------------------
+ Label miss;
+
+ // Check that the maps haven't changed, preserving the name register.
+ __ push(ecx);
+ __ JumpIfSmi(edx, &miss);
+ CheckPrototypes(receiver, edx, holder, ebx, ecx, edi, name, &miss);
+ __ pop(ecx);
+
+ GenerateStoreViaSetter(masm(), setter);
__ bind(&miss);
+ __ pop(ecx);
Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2675,7 +2763,7 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2723,7 +2811,7 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal(
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2762,7 +2850,9 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -2785,7 +2875,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -2820,7 +2910,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
__ jmp(miss_ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
@@ -2860,7 +2950,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NONEXISTENT, factory()->empty_string());
+ return GetCode(Code::NONEXISTENT, factory()->empty_string());
}
@@ -2880,7 +2970,7 @@ Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2896,16 +2986,53 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
// -----------------------------------
Label miss;
- GenerateLoadCallback(object, holder, edx, ecx, ebx, eax, edi, callback,
- name, &miss);
+ GenerateLoadCallback(object, holder, edx, ecx, ebx, eax, edi, no_reg,
+ callback, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
+ Handle<JSFunction> getter) {
+ // ----------- S t a t e -------------
+ // -- ecx : name
+ // -- edx : receiver
+ // -- esp[0] : return address
+ // -----------------------------------
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ if (!getter.is_null()) {
+ // Call the JavaScript getter with the receiver on the stack.
+ __ push(edx);
+ ParameterCount actual(0);
+ __ InvokeFunction(getter, actual, CALL_FUNCTION, NullCallWrapper(),
+ CALL_AS_METHOD);
+ } else {
+ // If we generate a global code snippet for deoptimization only, remember
+ // the place to continue after deoptimization.
+ masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
+ }
+
+ // Restore context register.
+ __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
+ }
+ __ ret(0);
}
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
@@ -2922,25 +3049,13 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
__ JumpIfSmi(edx, &miss);
CheckPrototypes(receiver, edx, holder, ebx, eax, edi, name, &miss);
- {
- FrameScope scope(masm(), StackFrame::INTERNAL);
-
- // Call the JavaScript getter with the receiver on the stack.
- __ push(edx);
- ParameterCount actual(0);
- __ InvokeFunction(getter, actual, CALL_FUNCTION, NullCallWrapper(),
- CALL_AS_METHOD);
-
- // Restore context register.
- __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
- }
- __ ret(0);
+ GenerateLoadViaGetter(masm(), getter);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2960,7 +3075,7 @@ Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -2986,7 +3101,7 @@ Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> receiver,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3034,7 +3149,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -3063,7 +3178,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -3086,15 +3201,15 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
__ cmp(ecx, Immediate(name));
__ j(not_equal, &miss);
- GenerateLoadCallback(receiver, holder, edx, ecx, ebx, eax, edi, callback,
- name, &miss);
+ GenerateLoadCallback(receiver, holder, edx, ecx, ebx, eax, edi, no_reg,
+ callback, name, &miss);
__ bind(&miss);
__ DecrementCounter(counters->keyed_load_callback(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3124,7 +3239,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -3155,7 +3270,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3181,7 +3296,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3207,7 +3322,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3233,7 +3348,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3253,7 +3368,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3280,7 +3395,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
diff --git a/deps/v8/src/ic-inl.h b/deps/v8/src/ic-inl.h
index 6a86921a4..49b6ef9d0 100644
--- a/deps/v8/src/ic-inl.h
+++ b/deps/v8/src/ic-inl.h
@@ -40,7 +40,7 @@ namespace internal {
Address IC::address() const {
// Get the address of the call.
- Address result = pc() - Assembler::kCallTargetAddressOffset;
+ Address result = Assembler::target_address_from_return_address(pc());
#ifdef ENABLE_DEBUGGER_SUPPORT
Debug* debug = Isolate::Current()->debug();
@@ -79,6 +79,7 @@ Code* IC::GetTargetAtAddress(Address address) {
void IC::SetTargetAtAddress(Address address, Code* target) {
ASSERT(target->is_inline_cache_stub() || target->is_compare_ic_stub());
+ Heap* heap = target->GetHeap();
Code* old_target = GetTargetAtAddress(address);
#ifdef DEBUG
// STORE_IC and KEYED_STORE_IC use Code::extra_ic_state() to mark
@@ -90,8 +91,11 @@ void IC::SetTargetAtAddress(Address address, Code* target) {
}
#endif
Assembler::set_target_address_at(address, target->instruction_start());
- target->GetHeap()->incremental_marking()->RecordCodeTargetPatch(address,
- target);
+ if (heap->gc_state() == Heap::MARK_COMPACT) {
+ heap->mark_compact_collector()->RecordCodeTargetPatch(address, target);
+ } else {
+ heap->incremental_marking()->RecordCodeTargetPatch(address, target);
+ }
PostPatching(address, target, old_target);
}
diff --git a/deps/v8/src/ic.cc b/deps/v8/src/ic.cc
index d169993e3..dd0bb10e1 100644
--- a/deps/v8/src/ic.cc
+++ b/deps/v8/src/ic.cc
@@ -158,7 +158,7 @@ Address IC::OriginalCodeAddress() const {
// Get the address of the call site in the active code. This is the
// place where the call to DebugBreakXXX is and where the IC
// normally would be.
- Address addr = pc() - Assembler::kCallTargetAddressOffset;
+ Address addr = Assembler::target_address_from_return_address(pc());
// Return the address in the original code. This is the place where
// the call which has been overwritten by the DebugBreakXXX resides
// and the place where the inline cache system should look.
@@ -320,13 +320,17 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) {
int delta = ComputeTypeInfoCountDelta(old_target->ic_state(),
target->ic_state());
// Not all Code objects have TypeFeedbackInfo.
- if (delta != 0 && host->type_feedback_info()->IsTypeFeedbackInfo()) {
+ if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) {
TypeFeedbackInfo* info =
TypeFeedbackInfo::cast(host->type_feedback_info());
- info->set_ic_with_type_info_count(
- info->ic_with_type_info_count() + delta);
+ info->change_ic_with_type_info_count(delta);
}
}
+ if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
+ TypeFeedbackInfo* info =
+ TypeFeedbackInfo::cast(host->type_feedback_info());
+ info->change_own_type_change_checksum();
+ }
if (FLAG_watch_ic_patching) {
host->set_profiler_ticks(0);
Isolate::Current()->runtime_profiler()->NotifyICChanged();
@@ -435,9 +439,7 @@ static void LookupForRead(Handle<Object> object,
// Besides normal conditions (property not found or it's not
// an interceptor), bail out if lookup is not cacheable: we won't
// be able to IC it anyway and regular lookup should work fine.
- if (!lookup->IsFound()
- || (lookup->type() != INTERCEPTOR)
- || !lookup->IsCacheable()) {
+ if (!lookup->IsInterceptor() || !lookup->IsCacheable()) {
return;
}
@@ -447,14 +449,14 @@ static void LookupForRead(Handle<Object> object,
}
holder->LocalLookupRealNamedProperty(*name, lookup);
- if (lookup->IsProperty()) {
- ASSERT(lookup->type() != INTERCEPTOR);
+ if (lookup->IsFound()) {
+ ASSERT(!lookup->IsInterceptor());
return;
}
Handle<Object> proto(holder->GetPrototype());
if (proto->IsNull()) {
- lookup->NotFound();
+ ASSERT(!lookup->IsFound());
return;
}
@@ -535,7 +537,7 @@ MaybeObject* CallICBase::LoadFunction(State state,
LookupResult lookup(isolate());
LookupForRead(object, name, &lookup);
- if (!lookup.IsProperty()) {
+ if (!lookup.IsFound()) {
// If the object does not have the requested property, check which
// exception we need to throw.
return IsContextual(object)
@@ -554,7 +556,7 @@ MaybeObject* CallICBase::LoadFunction(State state,
Object::GetProperty(object, object, &lookup, name, &attr);
RETURN_IF_EMPTY_HANDLE(isolate(), result);
- if (lookup.type() == INTERCEPTOR && attr == ABSENT) {
+ if (lookup.IsInterceptor() && attr == ABSENT) {
// If the object does not have the requested property, check which
// exception we need to throw.
return IsContextual(object)
@@ -902,7 +904,7 @@ MaybeObject* LoadIC::Load(State state,
LookupForRead(object, name, &lookup);
// If we did not find a property, check if we need to throw an exception.
- if (!lookup.IsProperty()) {
+ if (!lookup.IsFound()) {
if (IsContextual(object)) {
return ReferenceError("not_defined", name);
}
@@ -915,8 +917,7 @@ MaybeObject* LoadIC::Load(State state,
}
PropertyAttributes attr;
- if (lookup.IsFound() &&
- (lookup.type() == INTERCEPTOR || lookup.type() == HANDLER)) {
+ if (lookup.IsInterceptor() || lookup.IsHandler()) {
// Get the property.
Handle<Object> result =
Object::GetProperty(object, object, &lookup, name, &attr);
@@ -992,7 +993,6 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
if (callback->IsAccessorInfo()) {
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
if (v8::ToCData<Address>(info->getter()) == 0) return;
- if (!holder->HasFastProperties()) return;
if (!info->IsCompatibleReceiver(*receiver)) return;
code = isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, info);
@@ -1169,7 +1169,7 @@ MaybeObject* KeyedLoadIC::Load(State state,
LookupForRead(object, name, &lookup);
// If we did not find a property, check if we need to throw an exception.
- if (!lookup.IsProperty() && IsContextual(object)) {
+ if (!lookup.IsFound() && IsContextual(object)) {
return ReferenceError("not_defined", name);
}
@@ -1178,7 +1178,7 @@ MaybeObject* KeyedLoadIC::Load(State state,
}
PropertyAttributes attr;
- if (lookup.IsFound() && lookup.type() == INTERCEPTOR) {
+ if (lookup.IsInterceptor()) {
// Get the property.
Handle<Object> result =
Object::GetProperty(object, object, &lookup, name, &attr);
@@ -1269,7 +1269,6 @@ void KeyedLoadIC::UpdateCaches(LookupResult* lookup,
Handle<AccessorInfo> callback =
Handle<AccessorInfo>::cast(callback_object);
if (v8::ToCData<Address>(callback->getter()) == 0) return;
- if (!holder->HasFastProperties()) return;
if (!callback->IsCompatibleReceiver(*receiver)) return;
code = isolate()->stub_cache()->ComputeKeyedLoadCallback(
name, receiver, holder, callback);
@@ -1303,15 +1302,16 @@ void KeyedLoadIC::UpdateCaches(LookupResult* lookup,
static bool StoreICableLookup(LookupResult* lookup) {
// Bail out if we didn't find a result.
- if (!lookup->IsFound() || lookup->type() == NULL_DESCRIPTOR) return false;
+ if (!lookup->IsFound()) return false;
// Bail out if inline caching is not allowed.
if (!lookup->IsCacheable()) return false;
// If the property is read-only, we leave the IC in its current state.
- if (lookup->IsReadOnly()) return false;
-
- return true;
+ if (lookup->IsTransition()) {
+ return !lookup->GetTransitionDetails().IsReadOnly();
+ }
+ return !lookup->IsReadOnly();
}
@@ -1319,11 +1319,16 @@ static bool LookupForWrite(Handle<JSObject> receiver,
Handle<String> name,
LookupResult* lookup) {
receiver->LocalLookup(*name, lookup);
+ if (!lookup->IsFound()) {
+ receiver->map()->LookupTransition(*receiver, *name, lookup);
+ }
if (!StoreICableLookup(lookup)) {
- return false;
+ // 2nd chance: There can be accessors somewhere in the prototype chain.
+ receiver->Lookup(*name, lookup);
+ return lookup->IsPropertyCallbacks() && StoreICableLookup(lookup);
}
- if (lookup->type() == INTERCEPTOR &&
+ if (lookup->IsInterceptor() &&
receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
receiver->LocalLookupRealNamedProperty(*name, lookup);
return StoreICableLookup(lookup);
@@ -1390,12 +1395,13 @@ MaybeObject* StoreIC::Store(State state,
}
// Lookup the property locally in the receiver.
- if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
+ if (!receiver->IsJSGlobalProxy()) {
LookupResult lookup(isolate());
if (LookupForWrite(receiver, name, &lookup)) {
- // Generate a stub for this store.
- UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
+ if (FLAG_use_ic) { // Generate a stub for this store.
+ UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
+ }
} else {
// Strict mode doesn't allow setting non-existent global property
// or an assignment to a read only property.
@@ -1439,10 +1445,10 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
Handle<Object> value) {
ASSERT(!receiver->IsJSGlobalProxy());
ASSERT(StoreICableLookup(lookup));
+ ASSERT(lookup->IsFound());
+
// These are not cacheable, so we never see such LookupResults here.
- ASSERT(lookup->type() != HANDLER);
- // We get only called for properties or transitions, see StoreICableLookup.
- ASSERT(lookup->type() != NULL_DESCRIPTOR);
+ ASSERT(!lookup->IsHandler());
// If the property has a non-field type allowing map transitions
// where there is extra room in the object, we leave the IC in its
@@ -1462,14 +1468,6 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
Handle<Map>::null(),
strict_mode);
break;
- case MAP_TRANSITION: {
- if (lookup->GetAttributes() != NONE) return;
- Handle<Map> transition(lookup->GetTransitionMap());
- int index = transition->PropertyIndexFor(*name);
- code = isolate()->stub_cache()->ComputeStoreField(
- name, receiver, index, transition, strict_mode);
- break;
- }
case NORMAL:
if (receiver->IsGlobalObject()) {
// The stub generated for the global object picks the value directly
@@ -1487,20 +1485,20 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
case CALLBACKS: {
Handle<Object> callback(lookup->GetCallbackObject());
if (callback->IsAccessorInfo()) {
- ASSERT(*holder == *receiver); // LookupForWrite checks this.
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
if (v8::ToCData<Address>(info->setter()) == 0) return;
if (!holder->HasFastProperties()) return;
- ASSERT(info->IsCompatibleReceiver(*receiver));
+ if (!info->IsCompatibleReceiver(*receiver)) return;
code = isolate()->stub_cache()->ComputeStoreCallback(
- name, receiver, info, strict_mode);
+ name, receiver, holder, info, strict_mode);
} else if (callback->IsAccessorPair()) {
Handle<Object> setter(Handle<AccessorPair>::cast(callback)->setter());
if (!setter->IsJSFunction()) return;
if (holder->IsGlobalObject()) return;
if (!holder->HasFastProperties()) return;
code = isolate()->stub_cache()->ComputeStoreViaSetter(
- name, receiver, Handle<JSFunction>::cast(setter), strict_mode);
+ name, receiver, holder, Handle<JSFunction>::cast(setter),
+ strict_mode);
} else {
ASSERT(callback->IsForeign());
// No IC support for old-style native accessors.
@@ -1514,10 +1512,24 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
name, receiver, strict_mode);
break;
case CONSTANT_FUNCTION:
- case CONSTANT_TRANSITION:
return;
+ case TRANSITION: {
+ Handle<Map> transition(lookup->GetTransitionTarget());
+ int descriptor = transition->LastAdded();
+
+ DescriptorArray* target_descriptors = transition->instance_descriptors();
+ PropertyDetails details = target_descriptors->GetDetails(descriptor);
+
+ if (details.type() != FIELD || details.attributes() != NONE) return;
+
+ int field_index = target_descriptors->GetFieldIndex(descriptor);
+ code = isolate()->stub_cache()->ComputeStoreField(
+ name, receiver, field_index, transition, strict_mode);
+
+ break;
+ }
+ case NONEXISTENT:
case HANDLER:
- case NULL_DESCRIPTOR:
UNREACHABLE();
return;
}
@@ -1590,7 +1602,7 @@ Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
// Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
// via megamorphic stubs, since they don't have a map in their relocation info
// and so the stubs can't be harvested for the object needed for a map check.
- if (target()->type() != NORMAL) {
+ if (target()->type() != Code::NORMAL) {
TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type");
return generic_stub;
}
@@ -1943,10 +1955,10 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
Handle<Object> value) {
ASSERT(!receiver->IsJSGlobalProxy());
ASSERT(StoreICableLookup(lookup));
+ ASSERT(lookup->IsFound());
+
// These are not cacheable, so we never see such LookupResults here.
- ASSERT(lookup->type() != HANDLER);
- // We get only called for properties or transitions, see StoreICableLookup.
- ASSERT(lookup->type() != NULL_DESCRIPTOR);
+ ASSERT(!lookup->IsHandler());
// If the property has a non-field type allowing map transitions
// where there is extra room in the object, we leave the IC in its
@@ -1964,20 +1976,25 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
name, receiver, lookup->GetFieldIndex(),
Handle<Map>::null(), strict_mode);
break;
- case MAP_TRANSITION:
- if (lookup->GetAttributes() == NONE) {
- Handle<Map> transition(lookup->GetTransitionMap());
- int index = transition->PropertyIndexFor(*name);
+ case TRANSITION: {
+ Handle<Map> transition(lookup->GetTransitionTarget());
+ int descriptor = transition->LastAdded();
+
+ DescriptorArray* target_descriptors = transition->instance_descriptors();
+ PropertyDetails details = target_descriptors->GetDetails(descriptor);
+
+ if (details.type() == FIELD && details.attributes() == NONE) {
+ int field_index = target_descriptors->GetFieldIndex(descriptor);
code = isolate()->stub_cache()->ComputeKeyedStoreField(
- name, receiver, index, transition, strict_mode);
+ name, receiver, field_index, transition, strict_mode);
break;
}
// fall through.
+ }
case NORMAL:
case CONSTANT_FUNCTION:
case CALLBACKS:
case INTERCEPTOR:
- case CONSTANT_TRANSITION:
// Always rewrite to the generic case so that we do not
// repeatedly try to rewrite.
code = (strict_mode == kStrictMode)
@@ -1985,7 +2002,7 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
: generic_stub();
break;
case HANDLER:
- case NULL_DESCRIPTOR:
+ case NONEXISTENT:
UNREACHABLE();
return;
}
@@ -2120,7 +2137,7 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
// The length property has to be a writable callback property.
LookupResult debug_lookup(isolate);
receiver->LocalLookup(isolate->heap()->length_symbol(), &debug_lookup);
- ASSERT(debug_lookup.type() == CALLBACKS && !debug_lookup.IsReadOnly());
+ ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly());
#endif
Object* result;
@@ -2561,7 +2578,8 @@ CompareIC::State CompareIC::ComputeState(Code* target) {
Token::Value CompareIC::ComputeOperation(Code* target) {
ASSERT(target->major_key() == CodeStub::CompareIC);
- return static_cast<Token::Value>(target->compare_operation());
+ return static_cast<Token::Value>(
+ target->compare_operation() + Token::EQ);
}
@@ -2571,7 +2589,7 @@ const char* CompareIC::GetStateName(State state) {
case SMIS: return "SMIS";
case HEAP_NUMBERS: return "HEAP_NUMBERS";
case OBJECTS: return "OBJECTS";
- case KNOWN_OBJECTS: return "OBJECTS";
+ case KNOWN_OBJECTS: return "KNOWN_OBJECTS";
case SYMBOLS: return "SYMBOLS";
case STRINGS: return "STRINGS";
case GENERIC: return "GENERIC";
diff --git a/deps/v8/src/ic.h b/deps/v8/src/ic.h
index c86f316ef..8767f988a 100644
--- a/deps/v8/src/ic.h
+++ b/deps/v8/src/ic.h
@@ -631,6 +631,18 @@ class StoreIC: public IC {
};
+enum KeyedStoreCheckMap {
+ kDontCheckMap,
+ kCheckMap
+};
+
+
+enum KeyedStoreIncrementLength {
+ kDontIncrementLength,
+ kIncrementLength
+};
+
+
class KeyedStoreIC: public KeyedIC {
public:
explicit KeyedStoreIC(Isolate* isolate) : KeyedIC(isolate) {
@@ -638,7 +650,7 @@ class KeyedStoreIC: public KeyedIC {
}
MUST_USE_RESULT MaybeObject* Store(State state,
- StrictModeFlag strict_mode,
+ StrictModeFlag strict_mode,
Handle<Object> object,
Handle<Object> name,
Handle<Object> value,
diff --git a/deps/v8/src/incremental-marking-inl.h b/deps/v8/src/incremental-marking-inl.h
index 2dae6f207..bbe9a9d20 100644
--- a/deps/v8/src/incremental-marking-inl.h
+++ b/deps/v8/src/incremental-marking-inl.h
@@ -48,7 +48,9 @@ bool IncrementalMarking::BaseRecordWrite(HeapObject* obj,
// Object is either grey or white. It will be scanned if survives.
return false;
}
- return true;
+ if (!is_compacting_) return false;
+ MarkBit obj_bit = Marking::MarkBitFrom(obj);
+ return Marking::IsBlack(obj_bit);
}
@@ -107,9 +109,9 @@ void IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj,
// trace it. In this case we switch to non-incremental marking in
// order to finish off this marking phase.
if (FLAG_trace_gc) {
- PrintF("Hurrying incremental marking because of lack of progress\n");
+ PrintPID("Hurrying incremental marking because of lack of progress\n");
}
- allocation_marking_factor_ = kMaxAllocationMarkingFactor;
+ marking_speed_ = kMaxMarkingSpeed;
}
}
@@ -123,27 +125,6 @@ void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) {
}
-bool IncrementalMarking::MarkObjectAndPush(HeapObject* obj) {
- MarkBit mark_bit = Marking::MarkBitFrom(obj);
- if (!mark_bit.Get()) {
- WhiteToGreyAndPush(obj, mark_bit);
- return true;
- }
- return false;
-}
-
-
-bool IncrementalMarking::MarkObjectWithoutPush(HeapObject* obj) {
- MarkBit mark_bit = Marking::MarkBitFrom(obj);
- if (!mark_bit.Get()) {
- mark_bit.Set();
- MemoryChunk::IncrementLiveBytesFromGC(obj->address(), obj->Size());
- return true;
- }
- return false;
-}
-
-
} } // namespace v8::internal
#endif // V8_INCREMENTAL_MARKING_INL_H_
diff --git a/deps/v8/src/incremental-marking.cc b/deps/v8/src/incremental-marking.cc
index 94afffa73..e51d6c136 100644
--- a/deps/v8/src/incremental-marking.cc
+++ b/deps/v8/src/incremental-marking.cc
@@ -31,6 +31,8 @@
#include "code-stubs.h"
#include "compilation-cache.h"
+#include "objects-visiting.h"
+#include "objects-visiting-inl.h"
#include "v8conversions.h"
namespace v8 {
@@ -42,7 +44,6 @@ IncrementalMarking::IncrementalMarking(Heap* heap)
state_(STOPPED),
marking_deque_memory_(NULL),
marking_deque_memory_committed_(false),
- marker_(this, heap->mark_compact_collector()),
steps_count_(0),
steps_took_(0),
longest_step_(0.0),
@@ -51,7 +52,7 @@ IncrementalMarking::IncrementalMarking(Heap* heap)
steps_count_since_last_gc_(0),
steps_took_since_last_gc_(0),
should_hurry_(false),
- allocation_marking_factor_(0),
+ marking_speed_(0),
allocated_(0),
no_marking_scope_depth_(0) {
}
@@ -65,7 +66,7 @@ void IncrementalMarking::TearDown() {
void IncrementalMarking::RecordWriteSlow(HeapObject* obj,
Object** slot,
Object* value) {
- if (BaseRecordWrite(obj, slot, value) && is_compacting_ && slot != NULL) {
+ if (BaseRecordWrite(obj, slot, value) && slot != NULL) {
MarkBit obj_bit = Marking::MarkBitFrom(obj);
if (Marking::IsBlack(obj_bit)) {
// Object is not going to be rescanned we need to record the slot.
@@ -80,17 +81,19 @@ void IncrementalMarking::RecordWriteFromCode(HeapObject* obj,
Object* value,
Isolate* isolate) {
ASSERT(obj->IsHeapObject());
-
- // Fast cases should already be covered by RecordWriteStub.
- ASSERT(value->IsHeapObject());
- ASSERT(!value->IsHeapNumber());
- ASSERT(!value->IsString() ||
- value->IsConsString() ||
- value->IsSlicedString());
- ASSERT(Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(value))));
-
IncrementalMarking* marking = isolate->heap()->incremental_marking();
ASSERT(!marking->is_compacting_);
+
+ MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
+ int counter = chunk->write_barrier_counter();
+ if (counter < (MemoryChunk::kWriteBarrierCounterGranularity / 2)) {
+ marking->write_barriers_invoked_since_last_step_ +=
+ MemoryChunk::kWriteBarrierCounterGranularity -
+ chunk->write_barrier_counter();
+ chunk->set_write_barrier_counter(
+ MemoryChunk::kWriteBarrierCounterGranularity);
+ }
+
marking->RecordWrite(obj, NULL, value);
}
@@ -98,8 +101,20 @@ void IncrementalMarking::RecordWriteFromCode(HeapObject* obj,
void IncrementalMarking::RecordWriteForEvacuationFromCode(HeapObject* obj,
Object** slot,
Isolate* isolate) {
+ ASSERT(obj->IsHeapObject());
IncrementalMarking* marking = isolate->heap()->incremental_marking();
ASSERT(marking->is_compacting_);
+
+ MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
+ int counter = chunk->write_barrier_counter();
+ if (counter < (MemoryChunk::kWriteBarrierCounterGranularity / 2)) {
+ marking->write_barriers_invoked_since_last_step_ +=
+ MemoryChunk::kWriteBarrierCounterGranularity -
+ chunk->write_barrier_counter();
+ chunk->set_write_barrier_counter(
+ MemoryChunk::kWriteBarrierCounterGranularity);
+ }
+
marking->RecordWrite(obj, slot, *slot);
}
@@ -125,9 +140,9 @@ void IncrementalMarking::RecordCodeTargetPatch(Address pc, HeapObject* value) {
void IncrementalMarking::RecordWriteOfCodeEntrySlow(JSFunction* host,
- Object** slot,
- Code* value) {
- if (BaseRecordWrite(host, slot, value) && is_compacting_) {
+ Object** slot,
+ Code* value) {
+ if (BaseRecordWrite(host, slot, value)) {
ASSERT(slot != NULL);
heap_->mark_compact_collector()->
RecordCodeEntrySlot(reinterpret_cast<Address>(slot), value);
@@ -160,93 +175,69 @@ void IncrementalMarking::RecordWriteIntoCodeSlow(HeapObject* obj,
}
-class IncrementalMarkingMarkingVisitor : public ObjectVisitor {
+class IncrementalMarkingMarkingVisitor
+ : public StaticMarkingVisitor<IncrementalMarkingMarkingVisitor> {
public:
- IncrementalMarkingMarkingVisitor(Heap* heap,
- IncrementalMarking* incremental_marking)
- : heap_(heap),
- incremental_marking_(incremental_marking) {
- }
+ static void Initialize() {
+ StaticMarkingVisitor<IncrementalMarkingMarkingVisitor>::Initialize();
- void VisitEmbeddedPointer(RelocInfo* rinfo) {
- ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
- Object* target = rinfo->target_object();
- if (target->NonFailureIsHeapObject()) {
- heap_->mark_compact_collector()->RecordRelocSlot(rinfo, target);
- MarkObject(target);
- }
+ table_.Register(kVisitJSRegExp, &VisitJSRegExp);
}
- void VisitCodeTarget(RelocInfo* rinfo) {
- ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
- Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
- if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
- && (target->ic_age() != heap_->global_ic_age())) {
- IC::Clear(rinfo->pc());
- target = Code::GetCodeFromTargetAddress(rinfo->target_address());
- }
- heap_->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target));
- MarkObject(target);
- }
-
- void VisitDebugTarget(RelocInfo* rinfo) {
- ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
- rinfo->IsPatchedReturnSequence()) ||
- (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
- rinfo->IsPatchedDebugBreakSlotSequence()));
- Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
- heap_->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target));
- MarkObject(target);
- }
-
- void VisitCodeEntry(Address entry_address) {
- Object* target = Code::GetObjectFromEntryAddress(entry_address);
- heap_->mark_compact_collector()->
- RecordCodeEntrySlot(entry_address, Code::cast(target));
- MarkObject(target);
+ static void VisitJSWeakMap(Map* map, HeapObject* object) {
+ Heap* heap = map->GetHeap();
+ VisitPointers(heap,
+ HeapObject::RawField(object, JSWeakMap::kPropertiesOffset),
+ HeapObject::RawField(object, JSWeakMap::kSize));
}
- void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {
- if (shared->ic_age() != heap_->global_ic_age()) {
- shared->ResetForNewContext(heap_->global_ic_age());
- }
- }
+ static void BeforeVisitingSharedFunctionInfo(HeapObject* object) {}
- void VisitPointer(Object** p) {
+ INLINE(static void VisitPointer(Heap* heap, Object** p)) {
Object* obj = *p;
if (obj->NonFailureIsHeapObject()) {
- heap_->mark_compact_collector()->RecordSlot(p, p, obj);
- MarkObject(obj);
+ heap->mark_compact_collector()->RecordSlot(p, p, obj);
+ MarkObject(heap, obj);
}
}
- void VisitPointers(Object** start, Object** end) {
+ INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) {
for (Object** p = start; p < end; p++) {
Object* obj = *p;
if (obj->NonFailureIsHeapObject()) {
- heap_->mark_compact_collector()->RecordSlot(start, p, obj);
- MarkObject(obj);
+ heap->mark_compact_collector()->RecordSlot(start, p, obj);
+ MarkObject(heap, obj);
}
}
}
- private:
- // Mark object pointed to by p.
- INLINE(void MarkObject(Object* obj)) {
+ // Marks the object grey and pushes it on the marking stack.
+ INLINE(static void MarkObject(Heap* heap, Object* obj)) {
HeapObject* heap_object = HeapObject::cast(obj);
MarkBit mark_bit = Marking::MarkBitFrom(heap_object);
if (mark_bit.data_only()) {
- if (incremental_marking_->MarkBlackOrKeepGrey(mark_bit)) {
+ if (heap->incremental_marking()->MarkBlackOrKeepGrey(mark_bit)) {
MemoryChunk::IncrementLiveBytesFromGC(heap_object->address(),
heap_object->Size());
}
} else if (Marking::IsWhite(mark_bit)) {
- incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit);
+ heap->incremental_marking()->WhiteToGreyAndPush(heap_object, mark_bit);
}
}
- Heap* heap_;
- IncrementalMarking* incremental_marking_;
+ // Marks the object black without pushing it on the marking stack.
+ // Returns true if object needed marking and false otherwise.
+ INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) {
+ HeapObject* heap_object = HeapObject::cast(obj);
+ MarkBit mark_bit = Marking::MarkBitFrom(heap_object);
+ if (Marking::IsWhite(mark_bit)) {
+ mark_bit.Set();
+ MemoryChunk::IncrementLiveBytesFromGC(heap_object->address(),
+ heap_object->Size());
+ return true;
+ }
+ return false;
+ }
};
@@ -290,6 +281,11 @@ class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor {
};
+void IncrementalMarking::Initialize() {
+ IncrementalMarkingMarkingVisitor::Initialize();
+}
+
+
void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk,
bool is_marking,
bool is_compacting) {
@@ -537,8 +533,8 @@ void IncrementalMarking::StartMarking(CompactionFlag flag) {
ActivateIncrementalWriteBarrier();
-#ifdef DEBUG
// Marking bits are cleared by the sweeper.
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
heap_->mark_compact_collector()->VerifyMarkbitsAreClean();
}
@@ -623,24 +619,6 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
}
-void IncrementalMarking::VisitGlobalContext(Context* ctx, ObjectVisitor* v) {
- v->VisitPointers(
- HeapObject::RawField(
- ctx, Context::MarkCompactBodyDescriptor::kStartOffset),
- HeapObject::RawField(
- ctx, Context::MarkCompactBodyDescriptor::kEndOffset));
-
- MarkCompactCollector* collector = heap_->mark_compact_collector();
- for (int idx = Context::FIRST_WEAK_SLOT;
- idx < Context::GLOBAL_CONTEXT_SLOTS;
- ++idx) {
- Object** slot =
- HeapObject::RawField(ctx, FixedArray::OffsetOfElementAt(idx));
- collector->RecordSlot(slot, slot, *slot);
- }
-}
-
-
void IncrementalMarking::Hurry() {
if (state() == MARKING) {
double start = 0.0;
@@ -651,8 +629,7 @@ void IncrementalMarking::Hurry() {
// TODO(gc) hurry can mark objects it encounters black as mutator
// was stopped.
Map* filler_map = heap_->one_pointer_filler_map();
- Map* global_context_map = heap_->global_context_map();
- IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
+ Map* native_context_map = heap_->native_context_map();
while (!marking_deque_.IsEmpty()) {
HeapObject* obj = marking_deque_.Pop();
@@ -661,27 +638,15 @@ void IncrementalMarking::Hurry() {
Map* map = obj->map();
if (map == filler_map) {
continue;
- } else if (map == global_context_map) {
- // Global contexts have weak fields.
- VisitGlobalContext(Context::cast(obj), &marking_visitor);
- } else if (map->instance_type() == MAP_TYPE) {
- Map* map = Map::cast(obj);
- heap_->ClearCacheOnMap(map);
-
- // When map collection is enabled we have to mark through map's
- // transitions and back pointers in a special way to make these links
- // weak. Only maps for subclasses of JSReceiver can have transitions.
- STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
- if (FLAG_collect_maps &&
- map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
- marker_.MarkMapContents(map);
- } else {
- marking_visitor.VisitPointers(
- HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
- HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
- }
+ } else if (map == native_context_map) {
+ // Native contexts have weak fields.
+ IncrementalMarkingMarkingVisitor::VisitNativeContext(map, obj);
} else {
- obj->Iterate(&marking_visitor);
+ MarkBit map_mark_bit = Marking::MarkBitFrom(map);
+ if (Marking::IsWhite(map_mark_bit)) {
+ WhiteToGreyAndPush(map, map_mark_bit);
+ }
+ IncrementalMarkingMarkingVisitor::IterateBody(map, obj);
}
MarkBit mark_bit = Marking::MarkBitFrom(obj);
@@ -704,7 +669,7 @@ void IncrementalMarking::Hurry() {
PolymorphicCodeCache::kSize);
}
- Object* context = heap_->global_contexts_list();
+ Object* context = heap_->native_contexts_list();
while (!context->IsUndefined()) {
// GC can happen when the context is not fully initialized,
// so the cache can be undefined.
@@ -794,11 +759,25 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
allocated_ += allocated_bytes;
- if (allocated_ < kAllocatedThreshold) return;
+ if (allocated_ < kAllocatedThreshold &&
+ write_barriers_invoked_since_last_step_ <
+ kWriteBarriersInvokedThreshold) {
+ return;
+ }
if (state_ == MARKING && no_marking_scope_depth_ > 0) return;
- intptr_t bytes_to_process = allocated_ * allocation_marking_factor_;
+ // The marking speed is driven either by the allocation rate or by the rate
+ // at which we are having to check the color of objects in the write barrier.
+ // It is possible for a tight non-allocating loop to run a lot of write
+ // barriers before we get here and check them (marking can only take place on
+ // allocation), so to reduce the lumpiness we don't use the write barriers
+ // invoked since last step directly to determine the amount of work to do.
+ intptr_t bytes_to_process =
+ marking_speed_ * Max(allocated_, kWriteBarriersInvokedThreshold);
+ allocated_ = 0;
+ write_barriers_invoked_since_last_step_ = 0;
+
bytes_scanned_ += bytes_to_process;
double start = 0;
@@ -814,8 +793,7 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
}
} else if (state_ == MARKING) {
Map* filler_map = heap_->one_pointer_filler_map();
- Map* global_context_map = heap_->global_context_map();
- IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
+ Map* native_context_map = heap_->native_context_map();
while (!marking_deque_.IsEmpty() && bytes_to_process > 0) {
HeapObject* obj = marking_deque_.Pop();
@@ -832,46 +810,17 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
}
// TODO(gc) switch to static visitor instead of normal visitor.
- if (map == global_context_map) {
- // Global contexts have weak fields.
+ if (map == native_context_map) {
+ // Native contexts have weak fields.
Context* ctx = Context::cast(obj);
// We will mark cache black with a separate pass
// when we finish marking.
MarkObjectGreyDoNotEnqueue(ctx->normalized_map_cache());
- VisitGlobalContext(ctx, &marking_visitor);
- } else if (map->instance_type() == MAP_TYPE) {
- Map* map = Map::cast(obj);
- heap_->ClearCacheOnMap(map);
-
- // When map collection is enabled we have to mark through map's
- // transitions and back pointers in a special way to make these links
- // weak. Only maps for subclasses of JSReceiver can have transitions.
- STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
- if (FLAG_collect_maps &&
- map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
- marker_.MarkMapContents(map);
- } else {
- marking_visitor.VisitPointers(
- HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
- HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
- }
- } else if (map->instance_type() == JS_FUNCTION_TYPE) {
- marking_visitor.VisitPointers(
- HeapObject::RawField(obj, JSFunction::kPropertiesOffset),
- HeapObject::RawField(obj, JSFunction::kCodeEntryOffset));
-
- marking_visitor.VisitCodeEntry(
- obj->address() + JSFunction::kCodeEntryOffset);
-
- marking_visitor.VisitPointers(
- HeapObject::RawField(obj,
- JSFunction::kCodeEntryOffset + kPointerSize),
- HeapObject::RawField(obj,
- JSFunction::kNonWeakFieldsEndOffset));
+ IncrementalMarkingMarkingVisitor::VisitNativeContext(map, ctx);
} else {
- obj->IterateBody(map->instance_type(), size, &marking_visitor);
+ IncrementalMarkingMarkingVisitor::IterateBody(map, obj);
}
MarkBit obj_mark_bit = Marking::MarkBitFrom(obj);
@@ -883,17 +832,15 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
if (marking_deque_.IsEmpty()) MarkingComplete(action);
}
- allocated_ = 0;
-
steps_count_++;
steps_count_since_last_gc_++;
bool speed_up = false;
- if ((steps_count_ % kAllocationMarkingFactorSpeedupInterval) == 0) {
+ if ((steps_count_ % kMarkingSpeedAccellerationInterval) == 0) {
if (FLAG_trace_gc) {
- PrintF("Speed up marking after %d steps\n",
- static_cast<int>(kAllocationMarkingFactorSpeedupInterval));
+ PrintPID("Speed up marking after %d steps\n",
+ static_cast<int>(kMarkingSpeedAccellerationInterval));
}
speed_up = true;
}
@@ -902,35 +849,35 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
(old_generation_space_available_at_start_of_incremental_ < 10 * MB);
bool only_1_nth_of_space_that_was_available_still_left =
- (SpaceLeftInOldSpace() * (allocation_marking_factor_ + 1) <
+ (SpaceLeftInOldSpace() * (marking_speed_ + 1) <
old_generation_space_available_at_start_of_incremental_);
if (space_left_is_very_small ||
only_1_nth_of_space_that_was_available_still_left) {
- if (FLAG_trace_gc) PrintF("Speed up marking because of low space left\n");
+ if (FLAG_trace_gc) PrintPID("Speed up marking because of low space left\n");
speed_up = true;
}
bool size_of_old_space_multiplied_by_n_during_marking =
(heap_->PromotedTotalSize() >
- (allocation_marking_factor_ + 1) *
+ (marking_speed_ + 1) *
old_generation_space_used_at_start_of_incremental_);
if (size_of_old_space_multiplied_by_n_during_marking) {
speed_up = true;
if (FLAG_trace_gc) {
- PrintF("Speed up marking because of heap size increase\n");
+ PrintPID("Speed up marking because of heap size increase\n");
}
}
int64_t promoted_during_marking = heap_->PromotedTotalSize()
- old_generation_space_used_at_start_of_incremental_;
- intptr_t delay = allocation_marking_factor_ * MB;
+ intptr_t delay = marking_speed_ * MB;
intptr_t scavenge_slack = heap_->MaxSemiSpaceSize();
// We try to scan at at least twice the speed that we are allocating.
if (promoted_during_marking > bytes_scanned_ / 2 + scavenge_slack + delay) {
if (FLAG_trace_gc) {
- PrintF("Speed up marking because marker was not keeping up\n");
+ PrintPID("Speed up marking because marker was not keeping up\n");
}
speed_up = true;
}
@@ -938,15 +885,15 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
if (speed_up) {
if (state_ != MARKING) {
if (FLAG_trace_gc) {
- PrintF("Postponing speeding up marking until marking starts\n");
+ PrintPID("Postponing speeding up marking until marking starts\n");
}
} else {
- allocation_marking_factor_ += kAllocationMarkingFactorSpeedup;
- allocation_marking_factor_ = static_cast<int>(
- Min(kMaxAllocationMarkingFactor,
- static_cast<intptr_t>(allocation_marking_factor_ * 1.3)));
+ marking_speed_ += kMarkingSpeedAccellerationInterval;
+ marking_speed_ = static_cast<int>(
+ Min(kMaxMarkingSpeed,
+ static_cast<intptr_t>(marking_speed_ * 1.3)));
if (FLAG_trace_gc) {
- PrintF("Marking speed increased to %d\n", allocation_marking_factor_);
+ PrintPID("Marking speed increased to %d\n", marking_speed_);
}
}
}
@@ -972,8 +919,9 @@ void IncrementalMarking::ResetStepCounters() {
steps_count_since_last_gc_ = 0;
steps_took_since_last_gc_ = 0;
bytes_rescanned_ = 0;
- allocation_marking_factor_ = kInitialAllocationMarkingFactor;
+ marking_speed_ = kInitialMarkingSpeed;
bytes_scanned_ = 0;
+ write_barriers_invoked_since_last_step_ = 0;
}
diff --git a/deps/v8/src/incremental-marking.h b/deps/v8/src/incremental-marking.h
index 39e8daed6..1a86fcd44 100644
--- a/deps/v8/src/incremental-marking.h
+++ b/deps/v8/src/incremental-marking.h
@@ -53,6 +53,8 @@ class IncrementalMarking {
explicit IncrementalMarking(Heap* heap);
+ static void Initialize();
+
void TearDown();
State state() {
@@ -93,21 +95,23 @@ class IncrementalMarking {
// progress in the face of the mutator creating new work for it. We start
// of at a moderate rate of work and gradually increase the speed of the
// incremental marker until it completes.
- // Do some marking every time this much memory has been allocated.
+ // Do some marking every time this much memory has been allocated or that many
+ // heavy (color-checking) write barriers have been invoked.
static const intptr_t kAllocatedThreshold = 65536;
+ static const intptr_t kWriteBarriersInvokedThreshold = 65536;
// Start off by marking this many times more memory than has been allocated.
- static const intptr_t kInitialAllocationMarkingFactor = 1;
+ static const intptr_t kInitialMarkingSpeed = 1;
// But if we are promoting a lot of data we need to mark faster to keep up
// with the data that is entering the old space through promotion.
static const intptr_t kFastMarking = 3;
// After this many steps we increase the marking/allocating factor.
- static const intptr_t kAllocationMarkingFactorSpeedupInterval = 1024;
+ static const intptr_t kMarkingSpeedAccellerationInterval = 1024;
// This is how much we increase the marking/allocating factor by.
- static const intptr_t kAllocationMarkingFactorSpeedup = 2;
- static const intptr_t kMaxAllocationMarkingFactor = 1000;
+ static const intptr_t kMarkingSpeedAccelleration = 2;
+ static const intptr_t kMaxMarkingSpeed = 1000;
void OldSpaceStep(intptr_t allocated) {
- Step(allocated * kFastMarking / kInitialAllocationMarkingFactor,
+ Step(allocated * kFastMarking / kInitialMarkingSpeed,
GC_VIA_STACK_GUARD);
}
@@ -130,6 +134,12 @@ class IncrementalMarking {
Object** slot,
Isolate* isolate);
+ // Record a slot for compaction. Returns false for objects that are
+ // guaranteed to be rescanned or not guaranteed to survive.
+ //
+ // No slots in white objects should be recorded, as some slots are typed and
+ // cannot be interpreted correctly if the underlying object does not survive
+ // the incremental cycle (stays white).
INLINE(bool BaseRecordWrite(HeapObject* obj, Object** slot, Object* value));
INLINE(void RecordWrite(HeapObject* obj, Object** slot, Object* value));
INLINE(void RecordWriteIntoCode(HeapObject* obj,
@@ -167,16 +177,6 @@ class IncrementalMarking {
return true;
}
- // Marks the object grey and pushes it on the marking stack.
- // Returns true if object needed marking and false otherwise.
- // This is for incremental marking only.
- INLINE(bool MarkObjectAndPush(HeapObject* obj));
-
- // Marks the object black without pushing it on the marking stack.
- // Returns true if object needed marking and false otherwise.
- // This is for incremental marking only.
- INLINE(bool MarkObjectWithoutPush(HeapObject* obj));
-
inline int steps_count() {
return steps_count_;
}
@@ -213,12 +213,13 @@ class IncrementalMarking {
void NotifyOfHighPromotionRate() {
if (IsMarking()) {
- if (allocation_marking_factor_ < kFastMarking) {
+ if (marking_speed_ < kFastMarking) {
if (FLAG_trace_gc) {
- PrintF("Increasing marking speed to %d due to high promotion rate\n",
- static_cast<int>(kFastMarking));
+ PrintPID("Increasing marking speed to %d "
+ "due to high promotion rate\n",
+ static_cast<int>(kFastMarking));
}
- allocation_marking_factor_ = kFastMarking;
+ marking_speed_ = kFastMarking;
}
}
}
@@ -258,8 +259,6 @@ class IncrementalMarking {
void EnsureMarkingDequeIsCommitted();
- void VisitGlobalContext(Context* ctx, ObjectVisitor* v);
-
Heap* heap_;
State state_;
@@ -268,7 +267,6 @@ class IncrementalMarking {
VirtualMemory* marking_deque_memory_;
bool marking_deque_memory_committed_;
MarkingDeque marking_deque_;
- Marker<IncrementalMarking> marker_;
int steps_count_;
double steps_took_;
@@ -279,9 +277,10 @@ class IncrementalMarking {
double steps_took_since_last_gc_;
int64_t bytes_rescanned_;
bool should_hurry_;
- int allocation_marking_factor_;
+ int marking_speed_;
intptr_t bytes_scanned_;
intptr_t allocated_;
+ intptr_t write_barriers_invoked_since_last_step_;
int no_marking_scope_depth_;
diff --git a/deps/v8/src/interface.cc b/deps/v8/src/interface.cc
index 86bb9d0bf..336be82c6 100644
--- a/deps/v8/src/interface.cc
+++ b/deps/v8/src/interface.cc
@@ -124,8 +124,16 @@ void Interface::Unify(Interface* that, Zone* zone, bool* ok) {
*ok = true;
if (this == that) return;
- if (this->IsValue()) return that->MakeValue(ok);
- if (that->IsValue()) return this->MakeValue(ok);
+ if (this->IsValue()) {
+ that->MakeValue(ok);
+ if (*ok && this->IsConst()) that->MakeConst(ok);
+ return;
+ }
+ if (that->IsValue()) {
+ this->MakeValue(ok);
+ if (*ok && that->IsConst()) this->MakeConst(ok);
+ return;
+ }
#ifdef DEBUG
if (FLAG_print_interface_details) {
@@ -214,6 +222,8 @@ void Interface::Print(int n) {
if (IsUnknown()) {
PrintF("unknown\n");
+ } else if (IsConst()) {
+ PrintF("const\n");
} else if (IsValue()) {
PrintF("value\n");
} else if (IsModule()) {
diff --git a/deps/v8/src/interface.h b/deps/v8/src/interface.h
index 2670e7428..94ef11ba5 100644
--- a/deps/v8/src/interface.h
+++ b/deps/v8/src/interface.h
@@ -36,25 +36,41 @@ namespace internal {
// This class implements the following abstract grammar of interfaces
// (i.e. module types):
-// interface ::= UNDETERMINED | VALUE | MODULE(exports)
+// interface ::= UNDETERMINED | VALUE | CONST | MODULE(exports)
// exports ::= {name : interface, ...}
-// A frozen module type is one that is fully determined. Unification does not
-// allow adding additional exports to frozen interfaces.
-// Otherwise, unifying modules merges their exports.
+// A frozen type is one that is fully determined. Unification does not
+// allow to turn non-const values into const, or adding additional exports to
+// frozen interfaces. Otherwise, unifying modules merges their exports.
// Undetermined types are unification variables that can be unified freely.
+// There is a natural subsort lattice that reflects the increase of knowledge:
+//
+// undetermined
+// // | \\ .
+// value (frozen) module
+// // \\ / \ //
+// const fr.value fr.module
+// \\ /
+// fr.const
+//
+// where the bold lines are the only transitions allowed.
class Interface : public ZoneObject {
public:
// ---------------------------------------------------------------------------
// Factory methods.
+ static Interface* NewUnknown(Zone* zone) {
+ return new(zone) Interface(NONE);
+ }
+
static Interface* NewValue() {
static Interface value_interface(VALUE + FROZEN); // Cached.
return &value_interface;
}
- static Interface* NewUnknown(Zone* zone) {
- return new(zone) Interface(NONE);
+ static Interface* NewConst() {
+ static Interface value_interface(VALUE + CONST + FROZEN); // Cached.
+ return &value_interface;
}
static Interface* NewModule(Zone* zone) {
@@ -80,6 +96,12 @@ class Interface : public ZoneObject {
if (*ok) Chase()->flags_ |= VALUE;
}
+ // Determine this interface to be an immutable interface.
+ void MakeConst(bool* ok) {
+ *ok = !IsModule() && (IsConst() || !IsFrozen());
+ if (*ok) Chase()->flags_ |= VALUE + CONST;
+ }
+
// Determine this interface to be a module interface.
void MakeModule(bool* ok) {
*ok = !IsValue();
@@ -107,6 +129,9 @@ class Interface : public ZoneObject {
// Check whether this is a value type.
bool IsValue() { return Chase()->flags_ & VALUE; }
+ // Check whether this is a constant type.
+ bool IsConst() { return Chase()->flags_ & CONST; }
+
// Check whether this is a module type.
bool IsModule() { return Chase()->flags_ & MODULE; }
@@ -161,8 +186,9 @@ class Interface : public ZoneObject {
enum Flags { // All flags are monotonic
NONE = 0,
VALUE = 1, // This type describes a value
- MODULE = 2, // This type describes a module
- FROZEN = 4 // This type is fully determined
+ CONST = 2, // This type describes a constant
+ MODULE = 4, // This type describes a module
+ FROZEN = 8 // This type is fully determined
};
int flags_;
diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc
index 8fcb370c3..75e15a454 100644
--- a/deps/v8/src/isolate.cc
+++ b/deps/v8/src/isolate.cc
@@ -477,6 +477,14 @@ void Isolate::Iterate(ObjectVisitor* v) {
Iterate(v, current_t);
}
+void Isolate::IterateDeferredHandles(ObjectVisitor* visitor) {
+ for (DeferredHandles* deferred = deferred_handles_head_;
+ deferred != NULL;
+ deferred = deferred->next_) {
+ deferred->Iterate(visitor);
+ }
+}
+
void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) {
// The ARM simulator has a separate JS stack. We therefore register
@@ -527,6 +535,24 @@ Handle<String> Isolate::StackTraceString() {
}
+void Isolate::PushStackTraceAndDie(unsigned int magic,
+ Object* object,
+ Map* map,
+ unsigned int magic2) {
+ const int kMaxStackTraceSize = 8192;
+ Handle<String> trace = StackTraceString();
+ char buffer[kMaxStackTraceSize];
+ int length = Min(kMaxStackTraceSize - 1, trace->length());
+ String::WriteToFlat(*trace, buffer, 0, length);
+ buffer[length] = '\0';
+ OS::PrintError("Stacktrace (%x-%x) %p %p: %s\n",
+ magic, magic2,
+ static_cast<void*>(object), static_cast<void*>(map),
+ buffer);
+ OS::Abort();
+}
+
+
void Isolate::CaptureAndSetCurrentStackTraceFor(Handle<JSObject> error_object) {
if (capture_stack_trace_for_uncaught_exceptions_) {
// Capture stack trace for a detailed exception message.
@@ -781,16 +807,17 @@ static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
if (isolate->bootstrapper()->IsActive()) return YES;
if (receiver->IsJSGlobalProxy()) {
- Object* receiver_context = JSGlobalProxy::cast(receiver)->context();
+ Object* receiver_context = JSGlobalProxy::cast(receiver)->native_context();
if (!receiver_context->IsContext()) return NO;
- // Get the global context of current top context.
- // avoid using Isolate::global_context() because it uses Handle.
- Context* global_context = isolate->context()->global()->global_context();
- if (receiver_context == global_context) return YES;
+ // Get the native context of current top context.
+ // avoid using Isolate::native_context() because it uses Handle.
+ Context* native_context =
+ isolate->context()->global_object()->native_context();
+ if (receiver_context == native_context) return YES;
if (Context::cast(receiver_context)->security_token() ==
- global_context->security_token())
+ native_context->security_token())
return YES;
}
@@ -1136,12 +1163,12 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
"Extension or internal compilation error: %s in %s at line %d.\n",
*String::cast(exception)->ToCString(),
*String::cast(location->script()->name())->ToCString(),
- line_number);
+ line_number + 1);
} else {
OS::PrintError(
"Extension or internal compilation error in %s at line %d.\n",
*String::cast(location->script()->name())->ToCString(),
- line_number);
+ line_number + 1);
}
}
}
@@ -1205,7 +1232,7 @@ void Isolate::ReportPendingMessages() {
PropagatePendingExceptionToExternalTryCatch();
// If the pending exception is OutOfMemoryException set out_of_memory in
- // the global context. Note: We have to mark the global context here
+ // the native context. Note: We have to mark the native context here
// since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
// set it.
HandleScope scope;
@@ -1315,20 +1342,26 @@ bool Isolate::is_out_of_memory() {
}
+Handle<Context> Isolate::native_context() {
+ GlobalObject* global = thread_local_top()->context_->global_object();
+ return Handle<Context>(global->native_context());
+}
+
+
Handle<Context> Isolate::global_context() {
- GlobalObject* global = thread_local_top()->context_->global();
+ GlobalObject* global = thread_local_top()->context_->global_object();
return Handle<Context>(global->global_context());
}
-Handle<Context> Isolate::GetCallingGlobalContext() {
+Handle<Context> Isolate::GetCallingNativeContext() {
JavaScriptFrameIterator it;
#ifdef ENABLE_DEBUGGER_SUPPORT
if (debug_->InDebugger()) {
while (!it.done()) {
JavaScriptFrame* frame = it.frame();
Context* context = Context::cast(frame->context());
- if (context->global_context() == *debug_->debug_context()) {
+ if (context->native_context() == *debug_->debug_context()) {
it.Advance();
} else {
break;
@@ -1339,7 +1372,7 @@ Handle<Context> Isolate::GetCallingGlobalContext() {
if (it.done()) return Handle<Context>::null();
JavaScriptFrame* frame = it.frame();
Context* context = Context::cast(frame->context());
- return Handle<Context>(context->global_context());
+ return Handle<Context>(context->native_context());
}
@@ -1470,6 +1503,7 @@ Isolate::Isolate()
descriptor_lookup_cache_(NULL),
handle_scope_implementer_(NULL),
unicode_cache_(NULL),
+ runtime_zone_(this),
in_use_list_(0),
free_list_(0),
preallocated_storage_preallocated_(false),
@@ -1483,14 +1517,15 @@ Isolate::Isolate()
string_tracker_(NULL),
regexp_stack_(NULL),
date_cache_(NULL),
- context_exit_happened_(false) {
+ context_exit_happened_(false),
+ deferred_handles_head_(NULL),
+ optimizing_compiler_thread_(this) {
TRACE_ISOLATE(constructor);
memset(isolate_addresses_, 0,
sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1));
heap_.isolate_ = this;
- zone_.isolate_ = this;
stack_guard_.isolate_ = this;
// ThreadManager is initialized early to support locking an isolate
@@ -1547,6 +1582,11 @@ void Isolate::TearDown() {
thread_data_table_->RemoveAllThreads(this);
}
+ if (serialize_partial_snapshot_cache_ != NULL) {
+ delete[] serialize_partial_snapshot_cache_;
+ serialize_partial_snapshot_cache_ = NULL;
+ }
+
if (!IsDefaultIsolate()) {
delete this;
}
@@ -1560,6 +1600,8 @@ void Isolate::Deinit() {
if (state_ == INITIALIZED) {
TRACE_ISOLATE(deinit);
+ if (FLAG_parallel_recompilation) optimizing_compiler_thread_.Stop();
+
if (FLAG_hydrogen_stats) HStatistics::Instance()->Print();
// We must stop the logger before we tear down other components.
@@ -1595,6 +1637,26 @@ void Isolate::Deinit() {
}
+void Isolate::PushToPartialSnapshotCache(Object* obj) {
+ int length = serialize_partial_snapshot_cache_length();
+ int capacity = serialize_partial_snapshot_cache_capacity();
+
+ if (length >= capacity) {
+ int new_capacity = static_cast<int>((capacity + 10) * 1.2);
+ Object** new_array = new Object*[new_capacity];
+ for (int i = 0; i < length; i++) {
+ new_array[i] = serialize_partial_snapshot_cache()[i];
+ }
+ if (capacity != 0) delete[] serialize_partial_snapshot_cache();
+ set_serialize_partial_snapshot_cache(new_array);
+ set_serialize_partial_snapshot_cache_capacity(new_capacity);
+ }
+
+ serialize_partial_snapshot_cache()[length] = obj;
+ set_serialize_partial_snapshot_cache_length(length + 1);
+}
+
+
void Isolate::SetIsolateThreadLocals(Isolate* isolate,
PerIsolateThreadData* data) {
Thread::SetThreadLocal(isolate_key_, isolate);
@@ -1606,7 +1668,7 @@ Isolate::~Isolate() {
TRACE_ISOLATE(destructor);
// Has to be called while counters_ are still alive.
- zone_.DeleteKeptSegment();
+ runtime_zone_.DeleteKeptSegment();
delete[] assembler_spare_buffer_;
assembler_spare_buffer_ = NULL;
@@ -1743,10 +1805,8 @@ bool Isolate::Init(Deserializer* des) {
ASSERT(Isolate::Current() == this);
TRACE_ISOLATE(init);
-#ifdef DEBUG
// The initialization process does not handle memory exhaustion.
DisallowAllocationFailure disallow_allocation_failure;
-#endif
InitializeLoggingAndCounters();
@@ -1778,7 +1838,7 @@ bool Isolate::Init(Deserializer* des) {
global_handles_ = new GlobalHandles(this);
bootstrapper_ = new Bootstrapper();
handle_scope_implementer_ = new HandleScopeImplementer(this);
- stub_cache_ = new StubCache(this, zone());
+ stub_cache_ = new StubCache(this, runtime_zone());
regexp_stack_ = new RegExpStack();
regexp_stack_->isolate_ = this;
date_cache_ = new DateCache();
@@ -1812,6 +1872,11 @@ bool Isolate::Init(Deserializer* des) {
return false;
}
+ if (create_heap_objects) {
+ // Terminate the cache array with the sentinel so we can iterate.
+ PushToPartialSnapshotCache(heap_.undefined_value());
+ }
+
InitializeThreadLocal();
bootstrapper_->Initialize(create_heap_objects);
@@ -1838,7 +1903,7 @@ bool Isolate::Init(Deserializer* des) {
#endif
// If we are deserializing, read the state into the now-empty heap.
- if (des != NULL) {
+ if (!create_heap_objects) {
des->Deserialize();
}
stub_cache_->Initialize();
@@ -1853,7 +1918,7 @@ bool Isolate::Init(Deserializer* des) {
heap_.SetStackLimits();
// Quiet the heap NaN if needed on target platform.
- if (des != NULL) Assembler::QuietNaN(heap_.nan_value());
+ if (!create_heap_objects) Assembler::QuietNaN(heap_.nan_value());
deoptimizer_data_ = new DeoptimizerData;
runtime_profiler_ = new RuntimeProfiler(this);
@@ -1861,7 +1926,8 @@ bool Isolate::Init(Deserializer* des) {
// If we are deserializing, log non-function code objects and compiled
// functions found in the snapshot.
- if (des != NULL && (FLAG_log_code || FLAG_ll_prof)) {
+ if (create_heap_objects &&
+ (FLAG_log_code || FLAG_ll_prof || logger_->is_logging_code_events())) {
HandleScope scope;
LOG(this, LogCodeObjects());
LOG(this, LogCompiledFunctions());
@@ -1876,6 +1942,7 @@ bool Isolate::Init(Deserializer* des) {
state_ = INITIALIZED;
time_millis_at_init_ = OS::TimeCurrentMillis();
+ if (FLAG_parallel_recompilation) optimizing_compiler_thread_.Start();
return true;
}
@@ -1959,6 +2026,36 @@ void Isolate::Exit() {
}
+void Isolate::LinkDeferredHandles(DeferredHandles* deferred) {
+ deferred->next_ = deferred_handles_head_;
+ if (deferred_handles_head_ != NULL) {
+ deferred_handles_head_->previous_ = deferred;
+ }
+ deferred_handles_head_ = deferred;
+}
+
+
+void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) {
+#ifdef DEBUG
+ // In debug mode assert that the linked list is well-formed.
+ DeferredHandles* deferred_iterator = deferred;
+ while (deferred_iterator->previous_ != NULL) {
+ deferred_iterator = deferred_iterator->previous_;
+ }
+ ASSERT(deferred_handles_head_ == deferred_iterator);
+#endif
+ if (deferred_handles_head_ == deferred) {
+ deferred_handles_head_ = deferred_handles_head_->next_;
+ }
+ if (deferred->next_ != NULL) {
+ deferred->next_->previous_ = deferred->previous_;
+ }
+ if (deferred->previous_ != NULL) {
+ deferred->previous_->next_ = deferred->next_;
+ }
+}
+
+
#ifdef DEBUG
#define ISOLATE_FIELD_OFFSET(type, name, ignored) \
const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
diff --git a/deps/v8/src/isolate.h b/deps/v8/src/isolate.h
index 5ca2b87f0..b90191d0e 100644
--- a/deps/v8/src/isolate.h
+++ b/deps/v8/src/isolate.h
@@ -41,6 +41,7 @@
#include "handles.h"
#include "hashmap.h"
#include "heap.h"
+#include "optimizing-compiler-thread.h"
#include "regexp-stack.h"
#include "runtime-profiler.h"
#include "runtime.h"
@@ -307,8 +308,7 @@ class ThreadLocalTop BASE_EMBEDDED {
#define ISOLATE_INIT_ARRAY_LIST(V) \
/* SerializerDeserializer state. */ \
- V(Object*, serialize_partial_snapshot_cache, kPartialSnapshotCacheCapacity) \
- V(int, jsregexp_static_offsets_vector, kJSRegexpStaticOffsetsVectorSize) \
+ V(int32_t, jsregexp_static_offsets_vector, kJSRegexpStaticOffsetsVectorSize) \
V(int, bad_char_shift_table, kUC16AlphabetSize) \
V(int, good_suffix_shift_table, (kBMMaxShift + 1)) \
V(int, suffix_table, (kBMMaxShift + 1)) \
@@ -320,6 +320,8 @@ typedef List<HeapObject*, PreallocatedStorageAllocationPolicy> DebugObjectCache;
#define ISOLATE_INIT_LIST(V) \
/* SerializerDeserializer state. */ \
V(int, serialize_partial_snapshot_cache_length, 0) \
+ V(int, serialize_partial_snapshot_cache_capacity, 0) \
+ V(Object**, serialize_partial_snapshot_cache, NULL) \
/* Assembler state. */ \
/* A previously allocated buffer of kMinimalBufferSize bytes, or NULL. */ \
V(byte*, assembler_spare_buffer, NULL) \
@@ -327,7 +329,7 @@ typedef List<HeapObject*, PreallocatedStorageAllocationPolicy> DebugObjectCache;
V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, NULL) \
V(v8::Debug::MessageHandler, message_handler, NULL) \
/* To distinguish the function templates, so that we can find them in the */ \
- /* function cache of the global context. */ \
+ /* function cache of the native context. */ \
V(int, next_serial_number, 0) \
V(ExternalReferenceRedirectorPointer*, external_reference_redirector, NULL) \
V(bool, always_allow_natives_syntax, false) \
@@ -527,6 +529,11 @@ class Isolate {
thread_local_top_.save_context_ = save;
}
+ // Access to the map of "new Object()".
+ Map* empty_object_map() {
+ return context()->native_context()->object_function()->map();
+ }
+
// Access to current thread id.
ThreadId thread_id() { return thread_local_top_.thread_id_; }
void set_thread_id(ThreadId id) { thread_local_top_.thread_id_ = id; }
@@ -610,6 +617,9 @@ class Isolate {
(exception != heap()->termination_exception());
}
+ // Serializer.
+ void PushToPartialSnapshotCache(Object* obj);
+
// JS execution stack (see frames.h).
static Address c_entry_fp(ThreadLocalTop* thread) {
return thread->c_entry_fp_;
@@ -634,8 +644,8 @@ class Isolate {
// Returns the global object of the current context. It could be
// a builtin object, or a JS global object.
- Handle<GlobalObject> global() {
- return Handle<GlobalObject>(context()->global());
+ Handle<GlobalObject> global_object() {
+ return Handle<GlobalObject>(context()->global_object());
}
// Returns the global proxy object of the current context.
@@ -697,6 +707,10 @@ class Isolate {
void PrintStack(StringStream* accumulator);
void PrintStack();
Handle<String> StackTraceString();
+ NO_INLINE(void PushStackTraceAndDie(unsigned int magic,
+ Object* object,
+ Map* map,
+ unsigned int magic2));
Handle<JSArray> CaptureCurrentStackTrace(
int frame_limit,
StackTrace::StackTraceOptions options);
@@ -754,12 +768,13 @@ class Isolate {
void IterateThread(ThreadVisitor* v, char* t);
- // Returns the current global context.
+ // Returns the current native and global context.
+ Handle<Context> native_context();
Handle<Context> global_context();
- // Returns the global context of the calling JavaScript code. That
- // is, the global context of the top-most JavaScript frame.
- Handle<Context> GetCallingGlobalContext();
+ // Returns the native context of the calling JavaScript code. That
+ // is, the native context of the top-most JavaScript frame.
+ Handle<Context> GetCallingNativeContext();
void RegisterTryCatchHandler(v8::TryCatch* that);
void UnregisterTryCatchHandler(v8::TryCatch* that);
@@ -793,12 +808,12 @@ class Isolate {
ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR)
#undef GLOBAL_ARRAY_ACCESSOR
-#define GLOBAL_CONTEXT_FIELD_ACCESSOR(index, type, name) \
+#define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name) \
Handle<type> name() { \
- return Handle<type>(context()->global_context()->name()); \
+ return Handle<type>(context()->native_context()->name()); \
}
- GLOBAL_CONTEXT_FIELDS(GLOBAL_CONTEXT_FIELD_ACCESSOR)
-#undef GLOBAL_CONTEXT_FIELD_ACCESSOR
+ NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR)
+#undef NATIVE_CONTEXT_FIELD_ACCESSOR
Bootstrapper* bootstrapper() { return bootstrapper_; }
Counters* counters() {
@@ -850,7 +865,7 @@ class Isolate {
ASSERT(handle_scope_implementer_);
return handle_scope_implementer_;
}
- Zone* zone() { return &zone_; }
+ Zone* runtime_zone() { return &runtime_zone_; }
UnicodeCache* unicode_cache() {
return unicode_cache_;
@@ -976,9 +991,6 @@ class Isolate {
Factory* factory() { return reinterpret_cast<Factory*>(this); }
- // SerializerDeserializer state.
- static const int kPartialSnapshotCacheCapacity = 1400;
-
static const int kJSRegexpStaticOffsetsVectorSize = 128;
Address external_callback() {
@@ -1046,6 +1058,14 @@ class Isolate {
date_cache_ = date_cache;
}
+ void IterateDeferredHandles(ObjectVisitor* visitor);
+ void LinkDeferredHandles(DeferredHandles* deferred_handles);
+ void UnlinkDeferredHandles(DeferredHandles* deferred_handles);
+
+ OptimizingCompilerThread* optimizing_compiler_thread() {
+ return &optimizing_compiler_thread_;
+ }
+
private:
Isolate();
@@ -1196,7 +1216,7 @@ class Isolate {
v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
HandleScopeImplementer* handle_scope_implementer_;
UnicodeCache* unicode_cache_;
- Zone zone_;
+ Zone runtime_zone_;
PreallocatedStorage in_use_list_;
PreallocatedStorage free_list_;
bool preallocated_storage_preallocated_;
@@ -1269,8 +1289,13 @@ class Isolate {
#undef ISOLATE_FIELD_OFFSET
#endif
+ DeferredHandles* deferred_handles_head_;
+ OptimizingCompilerThread optimizing_compiler_thread_;
+
friend class ExecutionAccess;
+ friend class HandleScopeImplementer;
friend class IsolateInitializer;
+ friend class OptimizingCompilerThread;
friend class ThreadManager;
friend class Simulator;
friend class StackGuard;
@@ -1411,15 +1436,15 @@ class PostponeInterruptsScope BASE_EMBEDDED {
#define LOGGER (v8::internal::Isolate::Current()->logger())
-// Tells whether the global context is marked with out of memory.
+// Tells whether the native context is marked with out of memory.
inline bool Context::has_out_of_memory() {
- return global_context()->out_of_memory()->IsTrue();
+ return native_context()->out_of_memory()->IsTrue();
}
-// Mark the global context with out of memory.
+// Mark the native context with out of memory.
inline void Context::mark_out_of_memory() {
- global_context()->set_out_of_memory(HEAP->true_value());
+ native_context()->set_out_of_memory(HEAP->true_value());
}
diff --git a/deps/v8/src/json-parser.h b/deps/v8/src/json-parser.h
index 7265165ac..40116fa59 100644
--- a/deps/v8/src/json-parser.h
+++ b/deps/v8/src/json-parser.h
@@ -71,11 +71,11 @@ class JsonParser BASE_EMBEDDED {
inline void AdvanceSkipWhitespace() {
do {
Advance();
- } while (c0_ == '\t' || c0_ == '\r' || c0_ == '\n' || c0_ == ' ');
+ } while (c0_ == ' ' || c0_ == '\t' || c0_ == '\n' || c0_ == '\r');
}
inline void SkipWhitespace() {
- while (c0_ == '\t' || c0_ == '\r' || c0_ == '\n' || c0_ == ' ') {
+ while (c0_ == ' ' || c0_ == '\t' || c0_ == '\n' || c0_ == '\r') {
Advance();
}
}
@@ -149,6 +149,8 @@ class JsonParser BASE_EMBEDDED {
}
inline Isolate* isolate() { return isolate_; }
+ inline Factory* factory() { return factory_; }
+ inline Handle<JSFunction> object_constructor() { return object_constructor_; }
inline Zone* zone() const { return zone_; }
static const int kInitialSpecialStringLength = 1024;
@@ -160,6 +162,8 @@ class JsonParser BASE_EMBEDDED {
Handle<SeqAsciiString> seq_source_;
Isolate* isolate_;
+ Factory* factory_;
+ Handle<JSFunction> object_constructor_;
uc32 c0_;
int position_;
Zone* zone_;
@@ -169,6 +173,9 @@ template <bool seq_ascii>
Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source,
Zone* zone) {
isolate_ = source->map()->GetHeap()->isolate();
+ factory_ = isolate_->factory();
+ object_constructor_ =
+ Handle<JSFunction>(isolate()->native_context()->object_function());
zone_ = zone;
FlattenString(source);
source_ = source;
@@ -188,7 +195,7 @@ Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source,
// Parse failed. Current character is the unexpected token.
const char* message;
- Factory* factory = isolate()->factory();
+ Factory* factory = this->factory();
Handle<JSArray> array;
switch (c0_) {
@@ -237,87 +244,101 @@ Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source,
// Parse any JSON value.
template <bool seq_ascii>
Handle<Object> JsonParser<seq_ascii>::ParseJsonValue() {
- switch (c0_) {
- case '"':
- return ParseJsonString();
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return ParseJsonNumber();
- case 'f':
- if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' &&
- AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') {
- AdvanceSkipWhitespace();
- return isolate()->factory()->false_value();
- } else {
- return ReportUnexpectedCharacter();
- }
- case 't':
- if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' &&
- AdvanceGetChar() == 'e') {
- AdvanceSkipWhitespace();
- return isolate()->factory()->true_value();
- } else {
- return ReportUnexpectedCharacter();
- }
- case 'n':
- if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' &&
- AdvanceGetChar() == 'l') {
- AdvanceSkipWhitespace();
- return isolate()->factory()->null_value();
- } else {
- return ReportUnexpectedCharacter();
- }
- case '{':
- return ParseJsonObject();
- case '[':
- return ParseJsonArray();
- default:
- return ReportUnexpectedCharacter();
+ if (c0_ == '"') return ParseJsonString();
+ if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber();
+ if (c0_ == '{') return ParseJsonObject();
+ if (c0_ == '[') return ParseJsonArray();
+ if (c0_ == 'f') {
+ if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' &&
+ AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') {
+ AdvanceSkipWhitespace();
+ return factory()->false_value();
+ }
+ return ReportUnexpectedCharacter();
}
+ if (c0_ == 't') {
+ if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' &&
+ AdvanceGetChar() == 'e') {
+ AdvanceSkipWhitespace();
+ return factory()->true_value();
+ }
+ return ReportUnexpectedCharacter();
+ }
+ if (c0_ == 'n') {
+ if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' &&
+ AdvanceGetChar() == 'l') {
+ AdvanceSkipWhitespace();
+ return factory()->null_value();
+ }
+ return ReportUnexpectedCharacter();
+ }
+ return ReportUnexpectedCharacter();
}
// Parse a JSON object. Position must be right at '{'.
template <bool seq_ascii>
Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
- Handle<JSFunction> object_constructor(
- isolate()->global_context()->object_function());
+ Handle<Object> prototype;
Handle<JSObject> json_object =
- isolate()->factory()->NewJSObject(object_constructor);
+ factory()->NewJSObject(object_constructor());
ASSERT_EQ(c0_, '{');
AdvanceSkipWhitespace();
if (c0_ != '}') {
do {
if (c0_ != '"') return ReportUnexpectedCharacter();
- Handle<String> key = ParseJsonSymbol();
- if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
- AdvanceSkipWhitespace();
- Handle<Object> value = ParseJsonValue();
- if (value.is_null()) return ReportUnexpectedCharacter();
- uint32_t index;
- if (key->AsArrayIndex(&index)) {
+ int start_position = position_;
+ Advance();
+
+ uint32_t index = 0;
+ while (c0_ >= '0' && c0_ <= '9') {
+ int d = c0_ - '0';
+ if (index > 429496729U - ((d > 5) ? 1 : 0)) break;
+ index = (index * 10) + d;
+ Advance();
+ }
+
+ if (position_ != start_position + 1 && c0_ == '"') {
+ AdvanceSkipWhitespace();
+
+ if (c0_ != ':') return ReportUnexpectedCharacter();
+ AdvanceSkipWhitespace();
+ Handle<Object> value = ParseJsonValue();
+ if (value.is_null()) return ReportUnexpectedCharacter();
+
JSObject::SetOwnElement(json_object, index, value, kNonStrictMode);
- } else if (key->Equals(isolate()->heap()->Proto_symbol())) {
- SetPrototype(json_object, value);
} else {
- JSObject::SetLocalPropertyIgnoreAttributes(
- json_object, key, value, NONE);
+ position_ = start_position;
+#ifdef DEBUG
+ c0_ = '"';
+#endif
+
+ Handle<String> key = ParseJsonSymbol();
+ if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
+
+ AdvanceSkipWhitespace();
+ Handle<Object> value = ParseJsonValue();
+ if (value.is_null()) return ReportUnexpectedCharacter();
+
+ if (key->Equals(isolate()->heap()->Proto_symbol())) {
+ prototype = value;
+ } else {
+ if (JSObject::TryTransitionToField(json_object, key)) {
+ int index = json_object->LastAddedFieldIndex();
+ json_object->FastPropertyAtPut(index, *value);
+ } else {
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ json_object, key, value, NONE);
+ }
+ }
}
} while (MatchSkipWhiteSpace(','));
if (c0_ != '}') {
return ReportUnexpectedCharacter();
}
+ if (!prototype.is_null()) SetPrototype(json_object, prototype);
}
AdvanceSkipWhitespace();
return json_object;
@@ -326,7 +347,7 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
// Parse a JSON array. Position must be right at '['.
template <bool seq_ascii>
Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() {
- ZoneScope zone_scope(isolate(), DELETE_ON_EXIT);
+ ZoneScope zone_scope(zone(), DELETE_ON_EXIT);
ZoneList<Handle<Object> > elements(4, zone());
ASSERT_EQ(c0_, '[');
@@ -344,11 +365,11 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() {
AdvanceSkipWhitespace();
// Allocate a fixed array with all the elements.
Handle<FixedArray> fast_elements =
- isolate()->factory()->NewFixedArray(elements.length());
+ factory()->NewFixedArray(elements.length());
for (int i = 0, n = elements.length(); i < n; i++) {
fast_elements->set(i, *elements[i]);
}
- return isolate()->factory()->NewJSArrayWithElements(fast_elements);
+ return factory()->NewJSArrayWithElements(fast_elements);
}
@@ -415,7 +436,7 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() {
buffer.Dispose();
}
SkipWhitespace();
- return isolate()->factory()->NewNumber(number);
+ return factory()->NewNumber(number);
}
@@ -456,8 +477,7 @@ Handle<String> JsonParser<seq_ascii>::SlowScanJsonString(
int count = end - start;
int max_length = count + source_length_ - position_;
int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
- Handle<StringType> seq_str = NewRawString<StringType>(isolate()->factory(),
- length);
+ Handle<StringType> seq_str = NewRawString<StringType>(factory(), length);
// Copy prefix into seq_str.
SinkChar* dest = seq_str->GetChars();
String::WriteToFlat(*prefix, dest, start, end);
@@ -563,6 +583,56 @@ Handle<String> JsonParser<seq_ascii>::ScanJsonString() {
AdvanceSkipWhitespace();
return Handle<String>(isolate()->heap()->empty_string());
}
+
+ if (seq_ascii && is_symbol) {
+ // Fast path for existing symbols. If the the string being parsed is not
+ // a known symbol, contains backslashes or unexpectedly reaches the end of
+ // string, return with an empty handle.
+ uint32_t running_hash = isolate()->heap()->HashSeed();
+ int position = position_;
+ uc32 c0 = c0_;
+ do {
+ if (c0 == '\\') {
+ c0_ = c0;
+ int beg_pos = position_;
+ position_ = position;
+ return SlowScanJsonString<SeqAsciiString, char>(source_,
+ beg_pos,
+ position_);
+ }
+ if (c0 < 0x20) return Handle<String>::null();
+ running_hash = StringHasher::AddCharacterCore(running_hash, c0);
+ position++;
+ if (position >= source_length_) return Handle<String>::null();
+ c0 = seq_source_->SeqAsciiStringGet(position);
+ } while (c0 != '"');
+ int length = position - position_;
+ uint32_t hash = (length <= String::kMaxHashCalcLength)
+ ? StringHasher::GetHashCore(running_hash) : length;
+ Vector<const char> string_vector(
+ seq_source_->GetChars() + position_, length);
+ SymbolTable* symbol_table = isolate()->heap()->symbol_table();
+ uint32_t capacity = symbol_table->Capacity();
+ uint32_t entry = SymbolTable::FirstProbe(hash, capacity);
+ uint32_t count = 1;
+ while (true) {
+ Object* element = symbol_table->KeyAt(entry);
+ if (element == isolate()->heap()->raw_unchecked_undefined_value()) {
+ // Lookup failure.
+ break;
+ }
+ if (element != isolate()->heap()->raw_unchecked_the_hole_value() &&
+ String::cast(element)->IsAsciiEqualTo(string_vector)) {
+ // Lookup success, update the current position.
+ position_ = position;
+ // Advance past the last '"'.
+ AdvanceSkipWhitespace();
+ return Handle<String>(String::cast(element));
+ }
+ entry = SymbolTable::NextProbe(entry, count++, capacity);
+ }
+ }
+
int beg_pos = position_;
// Fast case for ASCII only without escape characters.
do {
@@ -585,11 +655,11 @@ Handle<String> JsonParser<seq_ascii>::ScanJsonString() {
int length = position_ - beg_pos;
Handle<String> result;
if (seq_ascii && is_symbol) {
- result = isolate()->factory()->LookupAsciiSymbol(seq_source_,
+ result = factory()->LookupAsciiSymbol(seq_source_,
beg_pos,
length);
} else {
- result = isolate()->factory()->NewRawAsciiString(length);
+ result = factory()->NewRawAsciiString(length);
char* dest = SeqAsciiString::cast(*result)->GetChars();
String::WriteToFlat(*source_, dest, beg_pos, position_);
}
diff --git a/deps/v8/src/json.js b/deps/v8/src/json.js
index ccef4456d..85224b0f0 100644
--- a/deps/v8/src/json.js
+++ b/deps/v8/src/json.js
@@ -247,22 +247,23 @@ function BasicSerializeObject(value, stack, builder) {
}
builder.push("{");
var first = true;
- for (var p in value) {
- if (%HasLocalProperty(value, p)) {
- if (!first) {
- builder.push(%QuoteJSONStringComma(p));
- } else {
- builder.push(%QuoteJSONString(p));
- }
- builder.push(":");
- var before = builder.length;
- BasicJSONSerialize(p, value[p], stack, builder);
- if (before == builder.length) {
- builder.pop();
- builder.pop();
- } else {
- first = false;
- }
+ var keys = %ObjectKeys(value);
+ var len = keys.length;
+ for (var i = 0; i < len; i++) {
+ var p = keys[i];
+ if (!first) {
+ builder.push(%QuoteJSONStringComma(p));
+ } else {
+ builder.push(%QuoteJSONString(p));
+ }
+ builder.push(":");
+ var before = builder.length;
+ BasicJSONSerialize(p, value[p], stack, builder);
+ if (before == builder.length) {
+ builder.pop();
+ builder.pop();
+ } else {
+ first = false;
}
}
stack.pop();
diff --git a/deps/v8/src/jsregexp.cc b/deps/v8/src/jsregexp.cc
index cd51db80a..e59170d5a 100644
--- a/deps/v8/src/jsregexp.cc
+++ b/deps/v8/src/jsregexp.cc
@@ -167,7 +167,9 @@ static bool HasFewDifferentCharacters(Handle<String> pattern) {
Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
Handle<String> pattern,
- Handle<String> flag_str) {
+ Handle<String> flag_str,
+ Zone* zone) {
+ ZoneScope zone_scope(zone, DELETE_ON_EXIT);
Isolate* isolate = re->GetIsolate();
JSRegExp::Flags flags = RegExpFlagsFromString(flag_str);
CompilationCache* compilation_cache = isolate->compilation_cache();
@@ -181,12 +183,11 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
return re;
}
pattern = FlattenGetString(pattern);
- ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
PostponeInterruptsScope postpone(isolate);
RegExpCompileData parse_result;
FlatStringReader reader(isolate, pattern);
if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
- &parse_result)) {
+ &parse_result, zone)) {
// Throw an exception if we fail to parse the pattern.
ThrowRegExpException(re,
pattern,
@@ -231,14 +232,13 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
- Handle<JSArray> last_match_info,
- Zone* zone) {
+ Handle<JSArray> last_match_info) {
switch (regexp->TypeTag()) {
case JSRegExp::ATOM:
return AtomExec(regexp, subject, index, last_match_info);
case JSRegExp::IRREGEXP: {
Handle<Object> result =
- IrregexpExec(regexp, subject, index, last_match_info, zone);
+ IrregexpExec(regexp, subject, index, last_match_info);
ASSERT(!result.is_null() ||
regexp->GetIsolate()->has_pending_exception());
return result;
@@ -278,11 +278,12 @@ static void SetAtomLastCapture(FixedArray* array,
}
-Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
- Handle<String> subject,
- int index,
- Handle<JSArray> last_match_info) {
- Isolate* isolate = re->GetIsolate();
+int RegExpImpl::AtomExecRaw(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ int index,
+ int32_t* output,
+ int output_size) {
+ Isolate* isolate = regexp->GetIsolate();
ASSERT(0 <= index);
ASSERT(index <= subject->length());
@@ -290,15 +291,16 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
if (!subject->IsFlat()) FlattenString(subject);
AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
- String* needle = String::cast(re->DataAt(JSRegExp::kAtomPatternIndex));
+ String* needle = String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex));
int needle_len = needle->length();
ASSERT(needle->IsFlat());
+ ASSERT_LT(0, needle_len);
- if (needle_len != 0) {
- if (index + needle_len > subject->length()) {
- return isolate->factory()->null_value();
- }
+ if (index + needle_len > subject->length()) {
+ return RegExpImpl::RE_FAILURE;
+ }
+ for (int i = 0; i < output_size; i += 2) {
String::FlatContent needle_content = needle->GetFlatContent();
String::FlatContent subject_content = subject->GetFlatContent();
ASSERT(needle_content.IsFlat());
@@ -323,15 +325,36 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
subject_content.ToUC16Vector(),
needle_content.ToUC16Vector(),
index)));
- if (index == -1) return isolate->factory()->null_value();
+ if (index == -1) {
+ return i / 2; // Return number of matches.
+ } else {
+ output[i] = index;
+ output[i+1] = index + needle_len;
+ index += needle_len;
+ }
}
- ASSERT(last_match_info->HasFastObjectElements());
+ return output_size / 2;
+}
- {
- NoHandleAllocation no_handles;
- FixedArray* array = FixedArray::cast(last_match_info->elements());
- SetAtomLastCapture(array, *subject, index, index + needle_len);
- }
+
+Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
+ Handle<String> subject,
+ int index,
+ Handle<JSArray> last_match_info) {
+ Isolate* isolate = re->GetIsolate();
+
+ static const int kNumRegisters = 2;
+ STATIC_ASSERT(kNumRegisters <= Isolate::kJSRegexpStaticOffsetsVectorSize);
+ int32_t* output_registers = isolate->jsregexp_static_offsets_vector();
+
+ int res = AtomExecRaw(re, subject, index, output_registers, kNumRegisters);
+
+ if (res == RegExpImpl::RE_FAILURE) return isolate->factory()->null_value();
+
+ ASSERT_EQ(res, RegExpImpl::RE_SUCCESS);
+ NoHandleAllocation no_handles;
+ FixedArray* array = FixedArray::cast(last_match_info->elements());
+ SetAtomLastCapture(array, *subject, output_registers[0], output_registers[1]);
return last_match_info;
}
@@ -345,8 +368,7 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
// If compilation fails, an exception is thrown and this function
// returns false.
bool RegExpImpl::EnsureCompiledIrregexp(
- Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii,
- Zone* zone) {
+ Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii) {
Object* compiled_code = re->DataAt(JSRegExp::code_index(is_ascii));
#ifdef V8_INTERPRETED_REGEXP
if (compiled_code->IsByteArray()) return true;
@@ -362,7 +384,7 @@ bool RegExpImpl::EnsureCompiledIrregexp(
ASSERT(compiled_code->IsSmi());
return true;
}
- return CompileIrregexp(re, sample_subject, is_ascii, zone);
+ return CompileIrregexp(re, sample_subject, is_ascii);
}
@@ -384,11 +406,10 @@ static bool CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re,
bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
Handle<String> sample_subject,
- bool is_ascii,
- Zone* zone) {
+ bool is_ascii) {
// Compile the RegExp.
Isolate* isolate = re->GetIsolate();
- ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
+ ZoneScope zone_scope(isolate->runtime_zone(), DELETE_ON_EXIT);
PostponeInterruptsScope postpone(isolate);
// If we had a compilation error the last time this is saved at the
// saved code index.
@@ -419,8 +440,10 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
if (!pattern->IsFlat()) FlattenString(pattern);
RegExpCompileData compile_data;
FlatStringReader reader(isolate, pattern);
+ Zone* zone = isolate->runtime_zone();
if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
- &compile_data)) {
+ &compile_data,
+ zone)) {
// Throw an exception if we fail to parse the pattern.
// THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once.
ThrowRegExpException(re,
@@ -502,17 +525,20 @@ void RegExpImpl::IrregexpInitialize(Handle<JSRegExp> re,
int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
- Handle<String> subject,
- Zone* zone) {
+ Handle<String> subject) {
if (!subject->IsFlat()) FlattenString(subject);
// Check the asciiness of the underlying storage.
bool is_ascii = subject->IsAsciiRepresentationUnderneath();
- if (!EnsureCompiledIrregexp(regexp, subject, is_ascii, zone)) return -1;
+ if (!EnsureCompiledIrregexp(regexp, subject, is_ascii)) return -1;
#ifdef V8_INTERPRETED_REGEXP
// Byte-code regexp needs space allocated for all its registers.
- return IrregexpNumberOfRegisters(FixedArray::cast(regexp->data()));
+ // The result captures are copied to the start of the registers array
+ // if the match succeeds. This way those registers are not clobbered
+ // when we set the last match info from last successful match.
+ return IrregexpNumberOfRegisters(FixedArray::cast(regexp->data())) +
+ (IrregexpNumberOfCaptures(FixedArray::cast(regexp->data())) + 1) * 2;
#else // V8_INTERPRETED_REGEXP
// Native regexp only needs room to output captures. Registers are handled
// internally.
@@ -521,28 +547,11 @@ int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
}
-int RegExpImpl::GlobalOffsetsVectorSize(Handle<JSRegExp> regexp,
- int registers_per_match,
- int* max_matches) {
-#ifdef V8_INTERPRETED_REGEXP
- // Global loop in interpreted regexp is not implemented. Therefore we choose
- // the size of the offsets vector so that it can only store one match.
- *max_matches = 1;
- return registers_per_match;
-#else // V8_INTERPRETED_REGEXP
- int size = Max(registers_per_match, OffsetsVector::kStaticOffsetsVectorSize);
- *max_matches = size / registers_per_match;
- return size;
-#endif // V8_INTERPRETED_REGEXP
-}
-
-
-int RegExpImpl::IrregexpExecRaw(
- Handle<JSRegExp> regexp,
- Handle<String> subject,
- int index,
- Vector<int> output,
- Zone* zone) {
+int RegExpImpl::IrregexpExecRaw(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ int index,
+ int32_t* output,
+ int output_size) {
Isolate* isolate = regexp->GetIsolate();
Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate);
@@ -554,15 +563,19 @@ int RegExpImpl::IrregexpExecRaw(
bool is_ascii = subject->IsAsciiRepresentationUnderneath();
#ifndef V8_INTERPRETED_REGEXP
- ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
+ ASSERT(output_size >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
do {
- EnsureCompiledIrregexp(regexp, subject, is_ascii, zone);
+ EnsureCompiledIrregexp(regexp, subject, is_ascii);
Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate);
+ // The stack is used to allocate registers for the compiled regexp code.
+ // This means that in case of failure, the output registers array is left
+ // untouched and contains the capture results from the previous successful
+ // match. We can use that to set the last match info lazily.
NativeRegExpMacroAssembler::Result res =
NativeRegExpMacroAssembler::Match(code,
subject,
- output.start(),
- output.length(),
+ output,
+ output_size,
index,
isolate);
if (res != NativeRegExpMacroAssembler::RETRY) {
@@ -582,29 +595,36 @@ int RegExpImpl::IrregexpExecRaw(
// the, potentially, different subject (the string can switch between
// being internal and external, and even between being ASCII and UC16,
// but the characters are always the same).
- IrregexpPrepare(regexp, subject, zone);
+ IrregexpPrepare(regexp, subject);
is_ascii = subject->IsAsciiRepresentationUnderneath();
} while (true);
UNREACHABLE();
return RE_EXCEPTION;
#else // V8_INTERPRETED_REGEXP
- ASSERT(output.length() >= IrregexpNumberOfRegisters(*irregexp));
+ ASSERT(output_size >= IrregexpNumberOfRegisters(*irregexp));
// We must have done EnsureCompiledIrregexp, so we can get the number of
// registers.
- int* register_vector = output.start();
int number_of_capture_registers =
(IrregexpNumberOfCaptures(*irregexp) + 1) * 2;
+ int32_t* raw_output = &output[number_of_capture_registers];
+ // We do not touch the actual capture result registers until we know there
+ // has been a match so that we can use those capture results to set the
+ // last match info.
for (int i = number_of_capture_registers - 1; i >= 0; i--) {
- register_vector[i] = -1;
+ raw_output[i] = -1;
}
Handle<ByteArray> byte_codes(IrregexpByteCode(*irregexp, is_ascii), isolate);
IrregexpResult result = IrregexpInterpreter::Match(isolate,
byte_codes,
subject,
- register_vector,
+ raw_output,
index);
+ if (result == RE_SUCCESS) {
+ // Copy capture results to the start of the registers array.
+ memcpy(output, raw_output, number_of_capture_registers * sizeof(int32_t));
+ }
if (result == RE_EXCEPTION) {
ASSERT(!isolate->has_pending_exception());
isolate->StackOverflow();
@@ -614,52 +634,44 @@ int RegExpImpl::IrregexpExecRaw(
}
-Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
+Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp,
Handle<String> subject,
int previous_index,
- Handle<JSArray> last_match_info,
- Zone* zone) {
- Isolate* isolate = jsregexp->GetIsolate();
- ASSERT_EQ(jsregexp->TypeTag(), JSRegExp::IRREGEXP);
+ Handle<JSArray> last_match_info) {
+ Isolate* isolate = regexp->GetIsolate();
+ ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
// Prepare space for the return values.
-#ifdef V8_INTERPRETED_REGEXP
-#ifdef DEBUG
+#if defined(V8_INTERPRETED_REGEXP) && defined(DEBUG)
if (FLAG_trace_regexp_bytecodes) {
- String* pattern = jsregexp->Pattern();
+ String* pattern = regexp->Pattern();
PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString()));
PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
}
#endif
-#endif
- int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject, zone);
+ int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
if (required_registers < 0) {
// Compiling failed with an exception.
ASSERT(isolate->has_pending_exception());
return Handle<Object>::null();
}
- OffsetsVector registers(required_registers, isolate);
+ int32_t* output_registers = NULL;
+ if (required_registers > Isolate::kJSRegexpStaticOffsetsVectorSize) {
+ output_registers = NewArray<int32_t>(required_registers);
+ }
+ SmartArrayPointer<int32_t> auto_release(output_registers);
+ if (output_registers == NULL) {
+ output_registers = isolate->jsregexp_static_offsets_vector();
+ }
- int res = RegExpImpl::IrregexpExecRaw(jsregexp, subject, previous_index,
- Vector<int>(registers.vector(),
- registers.length()),
- zone);
+ int res = RegExpImpl::IrregexpExecRaw(
+ regexp, subject, previous_index, output_registers, required_registers);
if (res == RE_SUCCESS) {
- int capture_register_count =
- (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2;
- last_match_info->EnsureSize(capture_register_count + kLastMatchOverhead);
- AssertNoAllocation no_gc;
- int* register_vector = registers.vector();
- FixedArray* array = FixedArray::cast(last_match_info->elements());
- for (int i = 0; i < capture_register_count; i += 2) {
- SetCapture(array, i, register_vector[i]);
- SetCapture(array, i + 1, register_vector[i + 1]);
- }
- SetLastCaptureCount(array, capture_register_count);
- SetLastSubject(array, *subject);
- SetLastInput(array, *subject);
- return last_match_info;
+ int capture_count =
+ IrregexpNumberOfCaptures(FixedArray::cast(regexp->data()));
+ return SetLastMatchInfo(
+ last_match_info, subject, capture_count, output_registers);
}
if (res == RE_EXCEPTION) {
ASSERT(isolate->has_pending_exception());
@@ -670,6 +682,146 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
}
+Handle<JSArray> RegExpImpl::SetLastMatchInfo(Handle<JSArray> last_match_info,
+ Handle<String> subject,
+ int capture_count,
+ int32_t* match) {
+ int capture_register_count = (capture_count + 1) * 2;
+ last_match_info->EnsureSize(capture_register_count + kLastMatchOverhead);
+ AssertNoAllocation no_gc;
+ FixedArray* array = FixedArray::cast(last_match_info->elements());
+ if (match != NULL) {
+ for (int i = 0; i < capture_register_count; i += 2) {
+ SetCapture(array, i, match[i]);
+ SetCapture(array, i + 1, match[i + 1]);
+ }
+ }
+ SetLastCaptureCount(array, capture_register_count);
+ SetLastSubject(array, *subject);
+ SetLastInput(array, *subject);
+ return last_match_info;
+}
+
+
+RegExpImpl::GlobalCache::GlobalCache(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ bool is_global,
+ Isolate* isolate)
+ : register_array_(NULL),
+ register_array_size_(0),
+ regexp_(regexp),
+ subject_(subject) {
+#ifdef V8_INTERPRETED_REGEXP
+ bool interpreted = true;
+#else
+ bool interpreted = false;
+#endif // V8_INTERPRETED_REGEXP
+
+ if (regexp_->TypeTag() == JSRegExp::ATOM) {
+ static const int kAtomRegistersPerMatch = 2;
+ registers_per_match_ = kAtomRegistersPerMatch;
+ // There is no distinction between interpreted and native for atom regexps.
+ interpreted = false;
+ } else {
+ registers_per_match_ = RegExpImpl::IrregexpPrepare(regexp_, subject_);
+ if (registers_per_match_ < 0) {
+ num_matches_ = -1; // Signal exception.
+ return;
+ }
+ }
+
+ if (is_global && !interpreted) {
+ register_array_size_ =
+ Max(registers_per_match_, Isolate::kJSRegexpStaticOffsetsVectorSize);
+ max_matches_ = register_array_size_ / registers_per_match_;
+ } else {
+ // Global loop in interpreted regexp is not implemented. We choose
+ // the size of the offsets vector so that it can only store one match.
+ register_array_size_ = registers_per_match_;
+ max_matches_ = 1;
+ }
+
+ if (register_array_size_ > Isolate::kJSRegexpStaticOffsetsVectorSize) {
+ register_array_ = NewArray<int32_t>(register_array_size_);
+ } else {
+ register_array_ = isolate->jsregexp_static_offsets_vector();
+ }
+
+ // Set state so that fetching the results the first time triggers a call
+ // to the compiled regexp.
+ current_match_index_ = max_matches_ - 1;
+ num_matches_ = max_matches_;
+ ASSERT(registers_per_match_ >= 2); // Each match has at least one capture.
+ ASSERT_GE(register_array_size_, registers_per_match_);
+ int32_t* last_match =
+ &register_array_[current_match_index_ * registers_per_match_];
+ last_match[0] = -1;
+ last_match[1] = 0;
+}
+
+
+RegExpImpl::GlobalCache::~GlobalCache() {
+ // Deallocate the register array if we allocated it in the constructor
+ // (as opposed to using the existing jsregexp_static_offsets_vector).
+ if (register_array_size_ > Isolate::kJSRegexpStaticOffsetsVectorSize) {
+ DeleteArray(register_array_);
+ }
+}
+
+
+int32_t* RegExpImpl::GlobalCache::FetchNext() {
+ current_match_index_++;
+ if (current_match_index_ >= num_matches_) {
+ // Current batch of results exhausted.
+ // Fail if last batch was not even fully filled.
+ if (num_matches_ < max_matches_) {
+ num_matches_ = 0; // Signal failed match.
+ return NULL;
+ }
+
+ int32_t* last_match =
+ &register_array_[(current_match_index_ - 1) * registers_per_match_];
+ int last_end_index = last_match[1];
+
+ if (regexp_->TypeTag() == JSRegExp::ATOM) {
+ num_matches_ = RegExpImpl::AtomExecRaw(regexp_,
+ subject_,
+ last_end_index,
+ register_array_,
+ register_array_size_);
+ } else {
+ int last_start_index = last_match[0];
+ if (last_start_index == last_end_index) last_end_index++;
+ if (last_end_index > subject_->length()) {
+ num_matches_ = 0; // Signal failed match.
+ return NULL;
+ }
+ num_matches_ = RegExpImpl::IrregexpExecRaw(regexp_,
+ subject_,
+ last_end_index,
+ register_array_,
+ register_array_size_);
+ }
+
+ if (num_matches_ <= 0) return NULL;
+ current_match_index_ = 0;
+ return register_array_;
+ } else {
+ return &register_array_[current_match_index_ * registers_per_match_];
+ }
+}
+
+
+int32_t* RegExpImpl::GlobalCache::LastSuccessfulMatch() {
+ int index = current_match_index_ * registers_per_match_;
+ if (num_matches_ == 0) {
+ // After a failed match we shift back by one result.
+ index -= registers_per_match_;
+ }
+ return &register_array_[index];
+}
+
+
// -------------------------------------------------------------------
// Implementation of the Irregexp regular expression engine.
//
@@ -5987,7 +6139,7 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
#else // V8_INTERPRETED_REGEXP
// Interpreted regexp implementation.
EmbeddedVector<byte, 1024> codes;
- RegExpMacroAssemblerIrregexp macro_assembler(codes);
+ RegExpMacroAssemblerIrregexp macro_assembler(codes, zone);
#endif // V8_INTERPRETED_REGEXP
// Inserted here, instead of in Assembler, because it depends on information
diff --git a/deps/v8/src/jsregexp.h b/deps/v8/src/jsregexp.h
index 782c5b0b2..96825cef2 100644
--- a/deps/v8/src/jsregexp.h
+++ b/deps/v8/src/jsregexp.h
@@ -71,15 +71,15 @@ class RegExpImpl {
// Returns false if compilation fails.
static Handle<Object> Compile(Handle<JSRegExp> re,
Handle<String> pattern,
- Handle<String> flags);
+ Handle<String> flags,
+ Zone* zone);
// See ECMA-262 section 15.10.6.2.
// This function calls the garbage collector if necessary.
static Handle<Object> Exec(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
- Handle<JSArray> lastMatchInfo,
- Zone* zone);
+ Handle<JSArray> lastMatchInfo);
// Prepares a JSRegExp object with Irregexp-specific data.
static void IrregexpInitialize(Handle<JSRegExp> re,
@@ -93,6 +93,14 @@ class RegExpImpl {
JSRegExp::Flags flags,
Handle<String> match_pattern);
+
+ static int AtomExecRaw(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ int index,
+ int32_t* output,
+ int output_size);
+
+
static Handle<Object> AtomExec(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
@@ -105,17 +113,10 @@ class RegExpImpl {
// This ensures that the regexp is compiled for the subject, and that
// the subject is flat.
// Returns the number of integer spaces required by IrregexpExecOnce
- // as its "registers" argument. If the regexp cannot be compiled,
+ // as its "registers" argument. If the regexp cannot be compiled,
// an exception is set as pending, and this function returns negative.
static int IrregexpPrepare(Handle<JSRegExp> regexp,
- Handle<String> subject,
- Zone* zone);
-
- // Calculate the size of offsets vector for the case of global regexp
- // and the number of matches this vector is able to store.
- static int GlobalOffsetsVectorSize(Handle<JSRegExp> regexp,
- int registers_per_match,
- int* max_matches);
+ Handle<String> subject);
// Execute a regular expression on the subject, starting from index.
// If matching succeeds, return the number of matches. This can be larger
@@ -126,18 +127,56 @@ class RegExpImpl {
static int IrregexpExecRaw(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
- Vector<int> registers,
- Zone* zone);
+ int32_t* output,
+ int output_size);
// Execute an Irregexp bytecode pattern.
// On a successful match, the result is a JSArray containing
- // captured positions. On a failure, the result is the null value.
+ // captured positions. On a failure, the result is the null value.
// Returns an empty handle in case of an exception.
static Handle<Object> IrregexpExec(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
- Handle<JSArray> lastMatchInfo,
- Zone* zone);
+ Handle<JSArray> lastMatchInfo);
+
+ // Set last match info. If match is NULL, then setting captures is omitted.
+ static Handle<JSArray> SetLastMatchInfo(Handle<JSArray> last_match_info,
+ Handle<String> subject,
+ int capture_count,
+ int32_t* match);
+
+
+ class GlobalCache {
+ public:
+ GlobalCache(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ bool is_global,
+ Isolate* isolate);
+
+ ~GlobalCache();
+
+ // Fetch the next entry in the cache for global regexp match results.
+ // This does not set the last match info. Upon failure, NULL is returned.
+ // The cause can be checked with Result(). The previous
+ // result is still in available in memory when a failure happens.
+ int32_t* FetchNext();
+
+ int32_t* LastSuccessfulMatch();
+
+ inline bool HasException() { return num_matches_ < 0; }
+
+ private:
+ int num_matches_;
+ int max_matches_;
+ int current_match_index_;
+ int registers_per_match_;
+ // Pointer to the last set of captures.
+ int32_t* register_array_;
+ int register_array_size_;
+ Handle<JSRegExp> regexp_;
+ Handle<String> subject_;
+ };
+
// Array index in the lastMatchInfo array.
static const int kLastCaptureCount = 0;
@@ -198,32 +237,10 @@ class RegExpImpl {
static const int kRegWxpCompiledLimit = 1 * MB;
private:
- static String* last_ascii_string_;
- static String* two_byte_cached_string_;
-
static bool CompileIrregexp(
- Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii,
- Zone* zone);
+ Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii);
static inline bool EnsureCompiledIrregexp(
- Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii,
- Zone* zone);
-
-
- // Set the subject cache. The previous string buffer is not deleted, so the
- // caller should ensure that it doesn't leak.
- static void SetSubjectCache(String* subject,
- char* utf8_subject,
- int uft8_length,
- int character_position,
- int utf8_position);
-
- // A one element cache of the last utf8_subject string and its length. The
- // subject JS String object is cached in the heap. We also cache a
- // translation between position and utf8 position.
- static char* utf8_subject_cache_;
- static int utf8_length_cache_;
- static int utf8_position_;
- static int character_position_;
+ Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii);
};
@@ -1627,40 +1644,6 @@ class RegExpEngine: public AllStatic {
};
-class OffsetsVector {
- public:
- inline OffsetsVector(int num_registers, Isolate* isolate)
- : offsets_vector_length_(num_registers) {
- if (offsets_vector_length_ > Isolate::kJSRegexpStaticOffsetsVectorSize) {
- vector_ = NewArray<int>(offsets_vector_length_);
- } else {
- vector_ = isolate->jsregexp_static_offsets_vector();
- }
- }
- inline ~OffsetsVector() {
- if (offsets_vector_length_ > Isolate::kJSRegexpStaticOffsetsVectorSize) {
- DeleteArray(vector_);
- vector_ = NULL;
- }
- }
- inline int* vector() { return vector_; }
- inline int length() { return offsets_vector_length_; }
-
- static const int kStaticOffsetsVectorSize =
- Isolate::kJSRegexpStaticOffsetsVectorSize;
-
- private:
- static Address static_offsets_vector_address(Isolate* isolate) {
- return reinterpret_cast<Address>(isolate->jsregexp_static_offsets_vector());
- }
-
- int* vector_;
- int offsets_vector_length_;
-
- friend class ExternalReference;
-};
-
-
} } // namespace v8::internal
#endif // V8_JSREGEXP_H_
diff --git a/deps/v8/src/lithium-allocator.cc b/deps/v8/src/lithium-allocator.cc
index bbc405ba0..91a98112b 100644
--- a/deps/v8/src/lithium-allocator.cc
+++ b/deps/v8/src/lithium-allocator.cc
@@ -1064,7 +1064,7 @@ void LAllocator::ResolvePhis(HBasicBlock* block) {
bool LAllocator::Allocate(LChunk* chunk) {
ASSERT(chunk_ == NULL);
- chunk_ = chunk;
+ chunk_ = static_cast<LPlatformChunk*>(chunk);
MeetRegisterConstraints();
if (!AllocationOk()) return false;
ResolvePhis();
diff --git a/deps/v8/src/lithium-allocator.h b/deps/v8/src/lithium-allocator.h
index d47e33595..5b0526357 100644
--- a/deps/v8/src/lithium-allocator.h
+++ b/deps/v8/src/lithium-allocator.h
@@ -48,7 +48,7 @@ class BitVector;
class StringStream;
class LArgument;
-class LChunk;
+class LPlatformChunk;
class LOperand;
class LUnallocated;
class LConstantOperand;
@@ -455,7 +455,7 @@ class LAllocator BASE_EMBEDDED {
return &fixed_double_live_ranges_;
}
- LChunk* chunk() const { return chunk_; }
+ LPlatformChunk* chunk() const { return chunk_; }
HGraph* graph() const { return graph_; }
Zone* zone() const { return zone_; }
@@ -598,7 +598,7 @@ class LAllocator BASE_EMBEDDED {
Zone* zone_;
- LChunk* chunk_;
+ LPlatformChunk* chunk_;
// During liveness analysis keep a mapping from block id to live_in sets
// for blocks already analyzed.
diff --git a/deps/v8/src/lithium.cc b/deps/v8/src/lithium.cc
index fd8b7965f..eb2198d85 100644
--- a/deps/v8/src/lithium.cc
+++ b/deps/v8/src/lithium.cc
@@ -27,6 +27,23 @@
#include "v8.h"
#include "lithium.h"
+#include "scopes.h"
+
+#if V8_TARGET_ARCH_IA32
+#include "ia32/lithium-ia32.h"
+#include "ia32/lithium-codegen-ia32.h"
+#elif V8_TARGET_ARCH_X64
+#include "x64/lithium-x64.h"
+#include "x64/lithium-codegen-x64.h"
+#elif V8_TARGET_ARCH_ARM
+#include "arm/lithium-arm.h"
+#include "arm/lithium-codegen-arm.h"
+#elif V8_TARGET_ARCH_MIPS
+#include "mips/lithium-mips.h"
+#include "mips/lithium-codegen-mips.h"
+#else
+#error "Unknown architecture."
+#endif
namespace v8 {
namespace internal {
@@ -156,7 +173,7 @@ void LParallelMove::PrintDataTo(StringStream* stream) const {
void LEnvironment::PrintTo(StringStream* stream) {
- stream->Add("[id=%d|", ast_id());
+ stream->Add("[id=%d|", ast_id().ToInt());
stream->Add("[parameters=%d|", parameter_count());
stream->Add("[arguments_stack_height=%d|", arguments_stack_height());
for (int i = 0; i < values_.length(); ++i) {
@@ -240,4 +257,183 @@ int ElementsKindToShiftSize(ElementsKind elements_kind) {
}
+LLabel* LChunk::GetLabel(int block_id) const {
+ HBasicBlock* block = graph_->blocks()->at(block_id);
+ int first_instruction = block->first_instruction_index();
+ return LLabel::cast(instructions_[first_instruction]);
+}
+
+
+int LChunk::LookupDestination(int block_id) const {
+ LLabel* cur = GetLabel(block_id);
+ while (cur->replacement() != NULL) {
+ cur = cur->replacement();
+ }
+ return cur->block_id();
+}
+
+Label* LChunk::GetAssemblyLabel(int block_id) const {
+ LLabel* label = GetLabel(block_id);
+ ASSERT(!label->HasReplacement());
+ return label->label();
+}
+
+void LChunk::MarkEmptyBlocks() {
+ HPhase phase("L_Mark empty blocks", this);
+ for (int i = 0; i < graph()->blocks()->length(); ++i) {
+ HBasicBlock* block = graph()->blocks()->at(i);
+ int first = block->first_instruction_index();
+ int last = block->last_instruction_index();
+ LInstruction* first_instr = instructions()->at(first);
+ LInstruction* last_instr = instructions()->at(last);
+
+ LLabel* label = LLabel::cast(first_instr);
+ if (last_instr->IsGoto()) {
+ LGoto* goto_instr = LGoto::cast(last_instr);
+ if (label->IsRedundant() &&
+ !label->is_loop_header()) {
+ bool can_eliminate = true;
+ for (int i = first + 1; i < last && can_eliminate; ++i) {
+ LInstruction* cur = instructions()->at(i);
+ if (cur->IsGap()) {
+ LGap* gap = LGap::cast(cur);
+ if (!gap->IsRedundant()) {
+ can_eliminate = false;
+ }
+ } else {
+ can_eliminate = false;
+ }
+ }
+
+ if (can_eliminate) {
+ label->set_replacement(GetLabel(goto_instr->block_id()));
+ }
+ }
+ }
+ }
+}
+
+
+void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
+ LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
+ int index = -1;
+ if (instr->IsControl()) {
+ instructions_.Add(gap, zone());
+ index = instructions_.length();
+ instructions_.Add(instr, zone());
+ } else {
+ index = instructions_.length();
+ instructions_.Add(instr, zone());
+ instructions_.Add(gap, zone());
+ }
+ if (instr->HasPointerMap()) {
+ pointer_maps_.Add(instr->pointer_map(), zone());
+ instr->pointer_map()->set_lithium_position(index);
+ }
+}
+
+
+LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
+ return LConstantOperand::Create(constant->id(), zone());
+}
+
+
+int LChunk::GetParameterStackSlot(int index) const {
+ // The receiver is at index 0, the first parameter at index 1, so we
+ // shift all parameter indexes down by the number of parameters, and
+ // make sure they end up negative so they are distinguishable from
+ // spill slots.
+ int result = index - info()->scope()->num_parameters() - 1;
+ ASSERT(result < 0);
+ return result;
+}
+
+
+// A parameter relative to ebp in the arguments stub.
+int LChunk::ParameterAt(int index) {
+ ASSERT(-1 <= index); // -1 is the receiver.
+ return (1 + info()->scope()->num_parameters() - index) *
+ kPointerSize;
+}
+
+
+LGap* LChunk::GetGapAt(int index) const {
+ return LGap::cast(instructions_[index]);
+}
+
+
+bool LChunk::IsGapAt(int index) const {
+ return instructions_[index]->IsGap();
+}
+
+
+int LChunk::NearestGapPos(int index) const {
+ while (!IsGapAt(index)) index--;
+ return index;
+}
+
+
+void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
+ GetGapAt(index)->GetOrCreateParallelMove(
+ LGap::START, zone())->AddMove(from, to, zone());
+}
+
+
+HConstant* LChunk::LookupConstant(LConstantOperand* operand) const {
+ return HConstant::cast(graph_->LookupValue(operand->index()));
+}
+
+
+Representation LChunk::LookupLiteralRepresentation(
+ LConstantOperand* operand) const {
+ return graph_->LookupValue(operand->index())->representation();
+}
+
+
+LChunk* LChunk::NewChunk(HGraph* graph) {
+ NoHandleAllocation no_handles;
+ AssertNoAllocation no_gc;
+
+ int values = graph->GetMaximumValueID();
+ CompilationInfo* info = graph->info();
+ if (values > LUnallocated::kMaxVirtualRegisters) {
+ info->set_bailout_reason("not enough virtual registers for values");
+ return NULL;
+ }
+ LAllocator allocator(values, graph);
+ LChunkBuilder builder(info, graph, &allocator);
+ LChunk* chunk = builder.Build();
+ if (chunk == NULL) return NULL;
+
+ if (!allocator.Allocate(chunk)) {
+ info->set_bailout_reason("not enough virtual registers (regalloc)");
+ return NULL;
+ }
+
+ return chunk;
+}
+
+
+Handle<Code> LChunk::Codegen() {
+ MacroAssembler assembler(info()->isolate(), NULL, 0);
+ LCodeGen generator(this, &assembler, info());
+
+ MarkEmptyBlocks();
+
+ if (generator.GenerateCode()) {
+ if (FLAG_trace_codegen) {
+ PrintF("Crankshaft Compiler - ");
+ }
+ CodeGenerator::MakeCodePrologue(info());
+ Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
+ Handle<Code> code =
+ CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
+ generator.FinishCode(code);
+ CodeGenerator::PrintCode(code, info());
+ return code;
+ }
+ return Handle<Code>::null();
+}
+
+
} } // namespace v8::internal
diff --git a/deps/v8/src/lithium.h b/deps/v8/src/lithium.h
index 1f42b686a..b4eb2bb2d 100644
--- a/deps/v8/src/lithium.h
+++ b/deps/v8/src/lithium.h
@@ -133,13 +133,15 @@ class LUnallocated: public LOperand {
// index in the upper bits.
static const int kPolicyWidth = 3;
static const int kLifetimeWidth = 1;
- static const int kVirtualRegisterWidth = 18;
+ static const int kVirtualRegisterWidth = 15;
static const int kPolicyShift = kKindFieldWidth;
static const int kLifetimeShift = kPolicyShift + kPolicyWidth;
static const int kVirtualRegisterShift = kLifetimeShift + kLifetimeWidth;
static const int kFixedIndexShift =
kVirtualRegisterShift + kVirtualRegisterWidth;
+ static const int kFixedIndexWidth = 32 - kFixedIndexShift;
+ STATIC_ASSERT(kFixedIndexWidth > 5);
class PolicyField : public BitField<Policy, kPolicyShift, kPolicyWidth> { };
@@ -154,8 +156,8 @@ class LUnallocated: public LOperand {
};
static const int kMaxVirtualRegisters = 1 << kVirtualRegisterWidth;
- static const int kMaxFixedIndex = 63;
- static const int kMinFixedIndex = -64;
+ static const int kMaxFixedIndex = (1 << kFixedIndexWidth) - 1;
+ static const int kMinFixedIndex = -(1 << kFixedIndexWidth);
bool HasAnyPolicy() const {
return policy() == ANY;
@@ -455,11 +457,12 @@ class LEnvironment: public ZoneObject {
public:
LEnvironment(Handle<JSFunction> closure,
FrameType frame_type,
- int ast_id,
+ BailoutId ast_id,
int parameter_count,
int argument_count,
int value_count,
LEnvironment* outer,
+ HEnterInlined* entry,
Zone* zone)
: closure_(closure),
frame_type_(frame_type),
@@ -470,10 +473,12 @@ class LEnvironment: public ZoneObject {
parameter_count_(parameter_count),
pc_offset_(-1),
values_(value_count, zone),
- is_tagged_(value_count, closure->GetHeap()->isolate()->zone()),
+ is_tagged_(value_count, zone),
+ is_uint32_(value_count, zone),
spilled_registers_(NULL),
spilled_double_registers_(NULL),
outer_(outer),
+ entry_(entry),
zone_(zone) { }
Handle<JSFunction> closure() const { return closure_; }
@@ -481,7 +486,7 @@ class LEnvironment: public ZoneObject {
int arguments_stack_height() const { return arguments_stack_height_; }
int deoptimization_index() const { return deoptimization_index_; }
int translation_index() const { return translation_index_; }
- int ast_id() const { return ast_id_; }
+ BailoutId ast_id() const { return ast_id_; }
int parameter_count() const { return parameter_count_; }
int pc_offset() const { return pc_offset_; }
LOperand** spilled_registers() const { return spilled_registers_; }
@@ -490,18 +495,30 @@ class LEnvironment: public ZoneObject {
}
const ZoneList<LOperand*>* values() const { return &values_; }
LEnvironment* outer() const { return outer_; }
+ HEnterInlined* entry() { return entry_; }
- void AddValue(LOperand* operand, Representation representation) {
+ void AddValue(LOperand* operand,
+ Representation representation,
+ bool is_uint32) {
values_.Add(operand, zone());
if (representation.IsTagged()) {
+ ASSERT(!is_uint32);
is_tagged_.Add(values_.length() - 1);
}
+
+ if (is_uint32) {
+ is_uint32_.Add(values_.length() - 1);
+ }
}
bool HasTaggedValueAt(int index) const {
return is_tagged_.Contains(index);
}
+ bool HasUint32ValueAt(int index) const {
+ return is_uint32_.Contains(index);
+ }
+
void Register(int deoptimization_index,
int translation_index,
int pc_offset) {
@@ -530,11 +547,12 @@ class LEnvironment: public ZoneObject {
int arguments_stack_height_;
int deoptimization_index_;
int translation_index_;
- int ast_id_;
+ BailoutId ast_id_;
int parameter_count_;
int pc_offset_;
ZoneList<LOperand*> values_;
BitVector is_tagged_;
+ BitVector is_uint32_;
// Allocation index indexed arrays of spill slot operands for registers
// that are also in spill slots at an OSR entry. NULL for environments
@@ -543,6 +561,7 @@ class LEnvironment: public ZoneObject {
LOperand** spilled_double_registers_;
LEnvironment* outer_;
+ HEnterInlined* entry_;
Zone* zone_;
};
@@ -622,6 +641,69 @@ class DeepIterator BASE_EMBEDDED {
};
+class LPlatformChunk;
+class LGap;
+class LLabel;
+
+// Superclass providing data and behavior common to all the
+// arch-specific LPlatformChunk classes.
+class LChunk: public ZoneObject {
+ public:
+ static LChunk* NewChunk(HGraph* graph);
+
+ void AddInstruction(LInstruction* instruction, HBasicBlock* block);
+ LConstantOperand* DefineConstantOperand(HConstant* constant);
+ HConstant* LookupConstant(LConstantOperand* operand) const;
+ Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
+
+ int ParameterAt(int index);
+ int GetParameterStackSlot(int index) const;
+ int spill_slot_count() const { return spill_slot_count_; }
+ CompilationInfo* info() const { return info_; }
+ HGraph* graph() const { return graph_; }
+ const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
+ void AddGapMove(int index, LOperand* from, LOperand* to);
+ LGap* GetGapAt(int index) const;
+ bool IsGapAt(int index) const;
+ int NearestGapPos(int index) const;
+ void MarkEmptyBlocks();
+ const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
+ LLabel* GetLabel(int block_id) const;
+ int LookupDestination(int block_id) const;
+ Label* GetAssemblyLabel(int block_id) const;
+
+ const ZoneList<Handle<JSFunction> >* inlined_closures() const {
+ return &inlined_closures_;
+ }
+
+ void AddInlinedClosure(Handle<JSFunction> closure) {
+ inlined_closures_.Add(closure, zone());
+ }
+
+ Zone* zone() const { return info_->zone(); }
+
+ Handle<Code> Codegen();
+
+ protected:
+ LChunk(CompilationInfo* info, HGraph* graph)
+ : spill_slot_count_(0),
+ info_(info),
+ graph_(graph),
+ instructions_(32, graph->zone()),
+ pointer_maps_(8, graph->zone()),
+ inlined_closures_(1, graph->zone()) { }
+
+ int spill_slot_count_;
+
+ private:
+ CompilationInfo* info_;
+ HGraph* const graph_;
+ ZoneList<LInstruction*> instructions_;
+ ZoneList<LPointerMap*> pointer_maps_;
+ ZoneList<Handle<JSFunction> > inlined_closures_;
+};
+
+
int ElementsKindToShiftSize(ElementsKind elements_kind);
diff --git a/deps/v8/src/liveedit-debugger.js b/deps/v8/src/liveedit-debugger.js
index 4463c93e2..cfcdb818c 100644
--- a/deps/v8/src/liveedit-debugger.js
+++ b/deps/v8/src/liveedit-debugger.js
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -47,6 +47,8 @@ Debug.LiveEdit = new function() {
// Forward declaration for minifier.
var FunctionStatus;
+ var NEEDS_STEP_IN_PROPERTY_NAME = "stack_update_needs_step_in";
+
// Applies the change to the script.
// The change is in form of list of chunks encoded in a single array as
// a series of triplets (pos1_start, pos1_end, pos2_end)
@@ -161,7 +163,7 @@ Debug.LiveEdit = new function() {
// Our current implementation requires client to manually issue "step in"
// command for correct stack state.
- preview_description.stack_update_needs_step_in =
+ preview_description[NEEDS_STEP_IN_PROPERTY_NAME] =
preview_description.stack_modified;
// Start with breakpoints. Convert their line/column positions and
@@ -1078,6 +1080,18 @@ Debug.LiveEdit = new function() {
return ProcessOldNode(old_code_tree);
}
+ // Restarts call frame and returns value similar to what LiveEdit returns.
+ function RestartFrame(frame_mirror) {
+ var result = frame_mirror.restart();
+ if (IS_STRING(result)) {
+ throw new Failure("Failed to restart frame: " + result);
+ }
+ var result = {};
+ result[NEEDS_STEP_IN_PROPERTY_NAME] = true;
+ return result;
+ }
+ // Function is public.
+ this.RestartFrame = RestartFrame;
// Functions are public for tests.
this.TestApi = {
diff --git a/deps/v8/src/liveedit.cc b/deps/v8/src/liveedit.cc
index e670b442b..2a3aafc1f 100644
--- a/deps/v8/src/liveedit.cc
+++ b/deps/v8/src/liveedit.cc
@@ -601,7 +601,7 @@ static void CompileScriptForTracker(Isolate* isolate, Handle<Script> script) {
PostponeInterruptsScope postpone(isolate);
// Build AST.
- CompilationInfo info(script);
+ CompilationInfoWithZone info(script);
info.MarkAsGlobal();
// Parse and don't allow skipping lazy functions.
if (ParserApi::Parse(&info, kNoParsingFlags)) {
@@ -635,6 +635,21 @@ static Handle<JSValue> WrapInJSValue(Handle<Object> object) {
}
+static Handle<SharedFunctionInfo> UnwrapSharedFunctionInfoFromJSValue(
+ Handle<JSValue> jsValue) {
+ Object* shared = jsValue->value();
+ CHECK(shared->IsSharedFunctionInfo());
+ return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(shared));
+}
+
+
+static int GetArrayLength(Handle<JSArray> array) {
+ Object* length = array->length();
+ CHECK(length->IsSmi());
+ return Smi::cast(length)->value();
+}
+
+
// Simple helper class that creates more or less typed structures over
// JSArray object. This is an adhoc method of passing structures from C++
// to JavaScript.
@@ -670,6 +685,7 @@ class JSArrayBasedStruct {
}
int GetSmiValueField(int field_position) {
Object* res = GetField(field_position);
+ CHECK(res->IsSmi());
return Smi::cast(res)->value();
}
@@ -714,14 +730,17 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
return this->GetSmiValueField(kParentIndexOffset_);
}
Handle<Code> GetFunctionCode() {
- Handle<Object> raw_result = UnwrapJSValue(Handle<JSValue>(
- JSValue::cast(this->GetField(kCodeOffset_))));
+ Object* element = this->GetField(kCodeOffset_);
+ CHECK(element->IsJSValue());
+ Handle<JSValue> value_wrapper(JSValue::cast(element));
+ Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
+ CHECK(raw_result->IsCode());
return Handle<Code>::cast(raw_result);
}
Handle<Object> GetCodeScopeInfo() {
- Handle<Object> raw_result = UnwrapJSValue(Handle<JSValue>(
- JSValue::cast(this->GetField(kCodeScopeInfoOffset_))));
- return raw_result;
+ Object* element = this->GetField(kCodeScopeInfoOffset_);
+ CHECK(element->IsJSValue());
+ return UnwrapJSValue(Handle<JSValue>(JSValue::cast(element)));
}
int GetStartPosition() {
return this->GetSmiValueField(kStartPositionOffset_);
@@ -771,9 +790,9 @@ class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> {
}
Handle<SharedFunctionInfo> GetInfo() {
Object* element = this->GetField(kSharedInfoOffset_);
+ CHECK(element->IsJSValue());
Handle<JSValue> value_wrapper(JSValue::cast(element));
- Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
- return Handle<SharedFunctionInfo>::cast(raw_result);
+ return UnwrapSharedFunctionInfoFromJSValue(value_wrapper);
}
private:
@@ -894,7 +913,6 @@ class FunctionInfoListener {
JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
Handle<String> source) {
Isolate* isolate = Isolate::Current();
- ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
FunctionInfoListener listener;
Handle<Object> original_source = Handle<Object>(script->source());
@@ -910,7 +928,7 @@ JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) {
HandleScope scope;
- int len = Smi::cast(array->length())->value();
+ int len = GetArrayLength(array);
for (int i = 0; i < len; i++) {
Handle<SharedFunctionInfo> info(
SharedFunctionInfo::cast(array->GetElementNoExceptionThrown(i)));
@@ -923,37 +941,35 @@ void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) {
}
-// Visitor that collects all references to a particular code object,
-// including "CODE_TARGET" references in other code objects.
-// It works in context of ZoneScope.
-class ReferenceCollectorVisitor : public ObjectVisitor {
+// Visitor that finds all references to a particular code object,
+// including "CODE_TARGET" references in other code objects and replaces
+// them on the fly.
+class ReplacingVisitor : public ObjectVisitor {
public:
- ReferenceCollectorVisitor(Code* original, Zone* zone)
- : original_(original),
- rvalues_(10, zone),
- reloc_infos_(10, zone),
- code_entries_(10, zone),
- zone_(zone) {
+ explicit ReplacingVisitor(Code* original, Code* substitution)
+ : original_(original), substitution_(substitution) {
}
virtual void VisitPointers(Object** start, Object** end) {
for (Object** p = start; p < end; p++) {
if (*p == original_) {
- rvalues_.Add(p, zone_);
+ *p = substitution_;
}
}
}
virtual void VisitCodeEntry(Address entry) {
if (Code::GetObjectFromEntryAddress(entry) == original_) {
- code_entries_.Add(entry, zone_);
+ Address substitution_entry = substitution_->instruction_start();
+ Memory::Address_at(entry) = substitution_entry;
}
}
virtual void VisitCodeTarget(RelocInfo* rinfo) {
if (RelocInfo::IsCodeTarget(rinfo->rmode()) &&
Code::GetCodeFromTargetAddress(rinfo->target_address()) == original_) {
- reloc_infos_.Add(*rinfo, zone_);
+ Address substitution_entry = substitution_->instruction_start();
+ rinfo->set_target_address(substitution_entry);
}
}
@@ -961,57 +977,40 @@ class ReferenceCollectorVisitor : public ObjectVisitor {
VisitCodeTarget(rinfo);
}
- // Post-visiting method that iterates over all collected references and
- // modifies them.
- void Replace(Code* substitution) {
- for (int i = 0; i < rvalues_.length(); i++) {
- *(rvalues_[i]) = substitution;
- }
- Address substitution_entry = substitution->instruction_start();
- for (int i = 0; i < reloc_infos_.length(); i++) {
- reloc_infos_[i].set_target_address(substitution_entry);
- }
- for (int i = 0; i < code_entries_.length(); i++) {
- Address entry = code_entries_[i];
- Memory::Address_at(entry) = substitution_entry;
- }
- }
-
private:
Code* original_;
- ZoneList<Object**> rvalues_;
- ZoneList<RelocInfo> reloc_infos_;
- ZoneList<Address> code_entries_;
- Zone* zone_;
+ Code* substitution_;
};
// Finds all references to original and replaces them with substitution.
-static void ReplaceCodeObject(Code* original, Code* substitution) {
- ASSERT(!HEAP->InNewSpace(substitution));
+static void ReplaceCodeObject(Handle<Code> original,
+ Handle<Code> substitution) {
+ // Perform a full GC in order to ensure that we are not in the middle of an
+ // incremental marking phase when we are replacing the code object.
+ // Since we are not in an incremental marking phase we can write pointers
+ // to code objects (that are never in new space) without worrying about
+ // write barriers.
+ HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask,
+ "liveedit.cc ReplaceCodeObject");
+
+ ASSERT(!HEAP->InNewSpace(*substitution));
- HeapIterator iterator;
AssertNoAllocation no_allocations_please;
- // A zone scope for ReferenceCollectorVisitor.
- ZoneScope scope(Isolate::Current(), DELETE_ON_EXIT);
-
- ReferenceCollectorVisitor visitor(original, Isolate::Current()->zone());
+ ReplacingVisitor visitor(*original, *substitution);
// Iterate over all roots. Stack frames may have pointer into original code,
// so temporary replace the pointers with offset numbers
// in prologue/epilogue.
- {
- HEAP->IterateStrongRoots(&visitor, VISIT_ALL);
- }
+ HEAP->IterateRoots(&visitor, VISIT_ALL);
// Now iterate over all pointers of all objects, including code_target
// implicit pointers.
+ HeapIterator iterator;
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
obj->Iterate(&visitor);
}
-
- visitor.Replace(substitution);
}
@@ -1095,8 +1094,8 @@ MaybeObject* LiveEdit::ReplaceFunctionCode(
if (IsJSFunctionCode(shared_info->code())) {
Handle<Code> code = compile_info_wrapper.GetFunctionCode();
- ReplaceCodeObject(shared_info->code(), *code);
- Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo();
+ ReplaceCodeObject(Handle<Code>(shared_info->code()), code);
+ Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo();
if (code_scope_info->IsFixedArray()) {
shared_info->set_scope_info(ScopeInfo::cast(*code_scope_info));
}
@@ -1146,7 +1145,8 @@ MaybeObject* LiveEdit::FunctionSourceUpdated(
void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper,
Handle<Object> script_handle) {
Handle<SharedFunctionInfo> shared_info =
- Handle<SharedFunctionInfo>::cast(UnwrapJSValue(function_wrapper));
+ UnwrapSharedFunctionInfoFromJSValue(function_wrapper);
+ CHECK(script_handle->IsScript() || script_handle->IsUndefined());
shared_info->set_script(*script_handle);
Isolate::Current()->compilation_cache()->Remove(shared_info);
@@ -1165,19 +1165,22 @@ void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper,
static int TranslatePosition(int original_position,
Handle<JSArray> position_change_array) {
int position_diff = 0;
- int array_len = Smi::cast(position_change_array->length())->value();
+ int array_len = GetArrayLength(position_change_array);
// TODO(635): binary search may be used here
for (int i = 0; i < array_len; i += 3) {
Object* element = position_change_array->GetElementNoExceptionThrown(i);
+ CHECK(element->IsSmi());
int chunk_start = Smi::cast(element)->value();
if (original_position < chunk_start) {
break;
}
element = position_change_array->GetElementNoExceptionThrown(i + 1);
+ CHECK(element->IsSmi());
int chunk_end = Smi::cast(element)->value();
// Position mustn't be inside a chunk.
ASSERT(original_position >= chunk_end);
element = position_change_array->GetElementNoExceptionThrown(i + 2);
+ CHECK(element->IsSmi());
int chunk_changed_end = Smi::cast(element)->value();
position_diff = chunk_changed_end - chunk_end;
}
@@ -1306,7 +1309,6 @@ static Handle<Code> PatchPositionsInCode(
MaybeObject* LiveEdit::PatchFunctionPositions(
Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array) {
-
if (!SharedInfoWrapper::IsInstance(shared_info_array)) {
return Isolate::Current()->ThrowIllegalOperation();
}
@@ -1338,7 +1340,7 @@ MaybeObject* LiveEdit::PatchFunctionPositions(
// on stack (it is safe to substitute the code object on stack, because
// we only change the structure of rinfo and leave instructions
// untouched).
- ReplaceCodeObject(info->code(), *patched_code);
+ ReplaceCodeObject(Handle<Code>(info->code()), patched_code);
}
}
@@ -1396,11 +1398,11 @@ void LiveEdit::ReplaceRefToNestedFunction(
Handle<JSValue> subst_function_wrapper) {
Handle<SharedFunctionInfo> parent_shared =
- Handle<SharedFunctionInfo>::cast(UnwrapJSValue(parent_function_wrapper));
+ UnwrapSharedFunctionInfoFromJSValue(parent_function_wrapper);
Handle<SharedFunctionInfo> orig_shared =
- Handle<SharedFunctionInfo>::cast(UnwrapJSValue(orig_function_wrapper));
+ UnwrapSharedFunctionInfoFromJSValue(orig_function_wrapper);
Handle<SharedFunctionInfo> subst_shared =
- Handle<SharedFunctionInfo>::cast(UnwrapJSValue(subst_function_wrapper));
+ UnwrapSharedFunctionInfoFromJSValue(subst_function_wrapper);
for (RelocIterator it(parent_shared->code()); !it.done(); it.next()) {
if (it.rinfo()->rmode() == RelocInfo::EMBEDDED_OBJECT) {
@@ -1423,12 +1425,13 @@ static bool CheckActivation(Handle<JSArray> shared_info_array,
Handle<JSFunction> function(
JSFunction::cast(JavaScriptFrame::cast(frame)->function()));
- int len = Smi::cast(shared_info_array->length())->value();
+ int len = GetArrayLength(shared_info_array);
for (int i = 0; i < len; i++) {
- JSValue* wrapper =
- JSValue::cast(shared_info_array->GetElementNoExceptionThrown(i));
- Handle<SharedFunctionInfo> shared(
- SharedFunctionInfo::cast(wrapper->value()));
+ Object* element = shared_info_array->GetElementNoExceptionThrown(i);
+ CHECK(element->IsJSValue());
+ Handle<JSValue> jsvalue(JSValue::cast(element));
+ Handle<SharedFunctionInfo> shared =
+ UnwrapSharedFunctionInfoFromJSValue(jsvalue);
if (function->shared() == *shared || IsInlined(*function, *shared)) {
SetElementNonStrict(result, i, Handle<Smi>(Smi::FromInt(status)));
@@ -1497,7 +1500,9 @@ static const char* DropFrames(Vector<StackFrame*> frames,
isolate->builtins()->builtin(
Builtins::kFrameDropper_LiveEdit)) {
// OK, we can drop our own code.
- *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL;
+ pre_top_frame = frames[top_frame_index - 2];
+ top_frame = frames[top_frame_index - 1];
+ *mode = Debug::CURRENTLY_SET_MODE;
frame_has_padding = false;
} else if (pre_top_frame_code ==
isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) {
@@ -1512,6 +1517,15 @@ static const char* DropFrames(Vector<StackFrame*> frames,
// Here the stub is CEntry, it's not debug-only and can't be padded.
// If anyone would complain, a proxy padded stub could be added.
frame_has_padding = false;
+ } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) {
+ // This must be adaptor that remain from the frame dropping that
+ // is still on stack. A frame dropper frame must be above it.
+ ASSERT(frames[top_frame_index - 2]->LookupCode() ==
+ isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit));
+ pre_top_frame = frames[top_frame_index - 3];
+ top_frame = frames[top_frame_index - 2];
+ *mode = Debug::CURRENTLY_SET_MODE;
+ frame_has_padding = false;
} else {
return "Unknown structure of stack above changing function";
}
@@ -1595,17 +1609,36 @@ static bool IsDropableFrame(StackFrame* frame) {
return !frame->is_exit();
}
-// Fills result array with statuses of functions. Modifies the stack
-// removing all listed function if possible and if do_drop is true.
-static const char* DropActivationsInActiveThread(
- Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop,
- Zone* zone) {
+
+// Describes a set of call frames that execute any of listed functions.
+// Finding no such frames does not mean error.
+class MultipleFunctionTarget {
+ public:
+ MultipleFunctionTarget(Handle<JSArray> shared_info_array,
+ Handle<JSArray> result)
+ : m_shared_info_array(shared_info_array),
+ m_result(result) {}
+ bool MatchActivation(StackFrame* frame,
+ LiveEdit::FunctionPatchabilityStatus status) {
+ return CheckActivation(m_shared_info_array, m_result, frame, status);
+ }
+ const char* GetNotFoundMessage() {
+ return NULL;
+ }
+ private:
+ Handle<JSArray> m_shared_info_array;
+ Handle<JSArray> m_result;
+};
+
+// Drops all call frame matched by target and all frames above them.
+template<typename TARGET>
+static const char* DropActivationsInActiveThreadImpl(
+ TARGET& target, bool do_drop, Zone* zone) {
Isolate* isolate = Isolate::Current();
Debug* debug = isolate->debug();
- ZoneScope scope(isolate, DELETE_ON_EXIT);
+ ZoneScope scope(zone, DELETE_ON_EXIT);
Vector<StackFrame*> frames = CreateStackMap(zone);
- int array_len = Smi::cast(shared_info_array->length())->value();
int top_frame_index = -1;
int frame_index = 0;
@@ -1615,8 +1648,8 @@ static const char* DropActivationsInActiveThread(
top_frame_index = frame_index;
break;
}
- if (CheckActivation(shared_info_array, result, frame,
- LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
+ if (target.MatchActivation(
+ frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
// We are still above break_frame. It is not a target frame,
// it is a problem.
return "Debugger mark-up on stack is not found";
@@ -1625,7 +1658,7 @@ static const char* DropActivationsInActiveThread(
if (top_frame_index == -1) {
// We haven't found break frame, but no function is blocking us anyway.
- return NULL;
+ return target.GetNotFoundMessage();
}
bool target_frame_found = false;
@@ -1638,8 +1671,8 @@ static const char* DropActivationsInActiveThread(
c_code_found = true;
break;
}
- if (CheckActivation(shared_info_array, result, frame,
- LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
+ if (target.MatchActivation(
+ frame, LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
target_frame_found = true;
bottom_js_frame_index = frame_index;
}
@@ -1651,8 +1684,8 @@ static const char* DropActivationsInActiveThread(
for (; frame_index < frames.length(); frame_index++) {
StackFrame* frame = frames[frame_index];
if (frame->is_java_script()) {
- if (CheckActivation(shared_info_array, result, frame,
- LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
+ if (target.MatchActivation(
+ frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
// Cannot drop frame under C frames.
return NULL;
}
@@ -1667,7 +1700,7 @@ static const char* DropActivationsInActiveThread(
if (!target_frame_found) {
// Nothing to drop.
- return NULL;
+ return target.GetNotFoundMessage();
}
Debug::FrameDropMode drop_mode = Debug::FRAMES_UNTOUCHED;
@@ -1690,6 +1723,23 @@ static const char* DropActivationsInActiveThread(
}
debug->FramesHaveBeenDropped(new_id, drop_mode,
restarter_frame_function_pointer);
+ return NULL;
+}
+
+// Fills result array with statuses of functions. Modifies the stack
+// removing all listed function if possible and if do_drop is true.
+static const char* DropActivationsInActiveThread(
+ Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop,
+ Zone* zone) {
+ MultipleFunctionTarget target(shared_info_array, result);
+
+ const char* message =
+ DropActivationsInActiveThreadImpl(target, do_drop, zone);
+ if (message) {
+ return message;
+ }
+
+ int array_len = GetArrayLength(shared_info_array);
// Replace "blocked on active" with "replaced on active" status.
for (int i = 0; i < array_len; i++) {
@@ -1731,7 +1781,7 @@ class InactiveThreadActivationsChecker : public ThreadVisitor {
Handle<JSArray> LiveEdit::CheckAndDropActivations(
Handle<JSArray> shared_info_array, bool do_drop, Zone* zone) {
- int len = Smi::cast(shared_info_array->length())->value();
+ int len = GetArrayLength(shared_info_array);
Handle<JSArray> result = FACTORY->NewJSArray(len);
@@ -1766,6 +1816,50 @@ Handle<JSArray> LiveEdit::CheckAndDropActivations(
}
+// Describes a single callframe a target. Not finding this frame
+// means an error.
+class SingleFrameTarget {
+ public:
+ explicit SingleFrameTarget(JavaScriptFrame* frame)
+ : m_frame(frame),
+ m_saved_status(LiveEdit::FUNCTION_AVAILABLE_FOR_PATCH) {}
+
+ bool MatchActivation(StackFrame* frame,
+ LiveEdit::FunctionPatchabilityStatus status) {
+ if (frame->fp() == m_frame->fp()) {
+ m_saved_status = status;
+ return true;
+ }
+ return false;
+ }
+ const char* GetNotFoundMessage() {
+ return "Failed to found requested frame";
+ }
+ LiveEdit::FunctionPatchabilityStatus saved_status() {
+ return m_saved_status;
+ }
+ private:
+ JavaScriptFrame* m_frame;
+ LiveEdit::FunctionPatchabilityStatus m_saved_status;
+};
+
+
+// Finds a drops required frame and all frames above.
+// Returns error message or NULL.
+const char* LiveEdit::RestartFrame(JavaScriptFrame* frame, Zone* zone) {
+ SingleFrameTarget target(frame);
+
+ const char* result = DropActivationsInActiveThreadImpl(target, true, zone);
+ if (result != NULL) {
+ return result;
+ }
+ if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE) {
+ return "Function is blocked under native code";
+ }
+ return NULL;
+}
+
+
LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate,
FunctionLiteral* fun)
: isolate_(isolate) {
@@ -1816,7 +1910,8 @@ LiveEditFunctionTracker::~LiveEditFunctionTracker() {
void LiveEditFunctionTracker::RecordFunctionInfo(
- Handle<SharedFunctionInfo> info, FunctionLiteral* lit) {
+ Handle<SharedFunctionInfo> info, FunctionLiteral* lit,
+ Zone* zone) {
}
diff --git a/deps/v8/src/liveedit.h b/deps/v8/src/liveedit.h
index 424c24e35..5b12854d8 100644
--- a/deps/v8/src/liveedit.h
+++ b/deps/v8/src/liveedit.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -123,6 +123,10 @@ class LiveEdit : AllStatic {
static Handle<JSArray> CheckAndDropActivations(
Handle<JSArray> shared_info_array, bool do_drop, Zone* zone);
+ // Restarts the call frame and completely drops all frames above it.
+ // Return error message or NULL.
+ static const char* RestartFrame(JavaScriptFrame* frame, Zone* zone);
+
// A copy of this is in liveedit-debugger.js.
enum FunctionPatchabilityStatus {
FUNCTION_AVAILABLE_FOR_PATCH = 1,
diff --git a/deps/v8/src/liveobjectlist.cc b/deps/v8/src/liveobjectlist.cc
index 1aabc5981..6b89cf683 100644
--- a/deps/v8/src/liveobjectlist.cc
+++ b/deps/v8/src/liveobjectlist.cc
@@ -74,7 +74,7 @@ typedef int (*RawComparer)(const void*, const void*);
v(SeqAsciiString, "unexpected: SeqAsciiString") \
v(SeqString, "unexpected: SeqString") \
v(JSFunctionResultCache, "unexpected: JSFunctionResultCache") \
- v(GlobalContext, "unexpected: GlobalContext") \
+ v(NativeContext, "unexpected: NativeContext") \
v(MapCache, "unexpected: MapCache") \
v(CodeCacheHashTable, "unexpected: CodeCacheHashTable") \
v(CompilationCacheTable, "unexpected: CompilationCacheTable") \
@@ -1951,7 +1951,7 @@ MaybeObject* LiveObjectList::GetObjRetainers(int obj_id,
// Get the constructor function for context extension and arguments array.
JSObject* arguments_boilerplate =
- isolate->context()->global_context()->arguments_boilerplate();
+ isolate->context()->native_context()->arguments_boilerplate();
JSFunction* arguments_function =
JSFunction::cast(arguments_boilerplate->map()->constructor());
diff --git a/deps/v8/src/log.cc b/deps/v8/src/log.cc
index d93a9d82b..b049ffe4e 100644
--- a/deps/v8/src/log.cc
+++ b/deps/v8/src/log.cc
@@ -145,7 +145,7 @@ class Profiler: public Thread {
//
// StackTracer implementation
//
-void StackTracer::Trace(Isolate* isolate, TickSample* sample) {
+DISABLE_ASAN void StackTracer::Trace(Isolate* isolate, TickSample* sample) {
ASSERT(isolate->IsInitialized());
// Avoid collecting traces while doing GC.
@@ -526,6 +526,7 @@ Logger::Logger()
name_buffer_(new NameBuffer),
address_to_name_map_(NULL),
is_initialized_(false),
+ code_event_handler_(NULL),
last_address_(NULL),
prev_sp_(NULL),
prev_function_(NULL),
@@ -541,6 +542,52 @@ Logger::~Logger() {
}
+void Logger::IssueCodeAddedEvent(Code* code,
+ const char* name,
+ size_t name_len) {
+ JitCodeEvent event;
+ event.type = JitCodeEvent::CODE_ADDED;
+ event.code_start = code->instruction_start();
+ event.code_len = code->instruction_size();
+ event.name.str = name;
+ event.name.len = name_len;
+
+ code_event_handler_(&event);
+}
+
+
+void Logger::IssueCodeMovedEvent(Address from, Address to) {
+ Code* from_code = Code::cast(HeapObject::FromAddress(from));
+
+ JitCodeEvent event;
+ event.type = JitCodeEvent::CODE_MOVED;
+ event.code_start = from_code->instruction_start();
+ event.code_len = from_code->instruction_size();
+
+ // Calculate the header size.
+ const size_t header_size =
+ from_code->instruction_start() - reinterpret_cast<byte*>(from_code);
+
+ // Calculate the new start address of the instructions.
+ event.new_code_start =
+ reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size;
+
+ code_event_handler_(&event);
+}
+
+
+void Logger::IssueCodeRemovedEvent(Address from) {
+ Code* from_code = Code::cast(HeapObject::FromAddress(from));
+
+ JitCodeEvent event;
+ event.type = JitCodeEvent::CODE_REMOVED;
+ event.code_start = from_code->instruction_start();
+ event.code_len = from_code->instruction_size();
+
+ code_event_handler_(&event);
+}
+
+
#define DECLARE_EVENT(ignore1, name) name,
static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)
@@ -864,13 +911,17 @@ void Logger::SetterCallbackEvent(String* name, Address entry_point) {
void Logger::CodeCreateEvent(LogEventsAndTags tag,
Code* code,
const char* comment) {
- if (!log_->IsEnabled()) return;
- if (FLAG_ll_prof || Serializer::enabled()) {
+ if (!is_logging_code_events()) return;
+ if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[tag]);
name_buffer_->AppendByte(':');
name_buffer_->AppendBytes(comment);
}
+ if (code_event_handler_ != NULL) {
+ IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
+ }
+ if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
@@ -899,13 +950,17 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
void Logger::CodeCreateEvent(LogEventsAndTags tag,
Code* code,
String* name) {
- if (!log_->IsEnabled()) return;
- if (FLAG_ll_prof || Serializer::enabled()) {
+ if (!is_logging_code_events()) return;
+ if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[tag]);
name_buffer_->AppendByte(':');
name_buffer_->AppendString(name);
}
+ if (code_event_handler_ != NULL) {
+ IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
+ }
+ if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
@@ -940,14 +995,18 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
String* name) {
- if (!log_->IsEnabled()) return;
- if (FLAG_ll_prof || Serializer::enabled()) {
+ if (!is_logging_code_events()) return;
+ if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[tag]);
name_buffer_->AppendByte(':');
name_buffer_->AppendBytes(ComputeMarker(code));
name_buffer_->AppendString(name);
}
+ if (code_event_handler_ != NULL) {
+ IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
+ }
+ if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
@@ -981,8 +1040,8 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
String* source, int line) {
- if (!log_->IsEnabled()) return;
- if (FLAG_ll_prof || Serializer::enabled()) {
+ if (!is_logging_code_events()) return;
+ if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[tag]);
name_buffer_->AppendByte(':');
@@ -993,6 +1052,10 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
name_buffer_->AppendByte(':');
name_buffer_->AppendInt(line);
}
+ if (code_event_handler_ != NULL) {
+ IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
+ }
+ if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
@@ -1022,13 +1085,17 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) {
- if (!log_->IsEnabled()) return;
- if (FLAG_ll_prof || Serializer::enabled()) {
+ if (!is_logging_code_events()) return;
+ if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[tag]);
name_buffer_->AppendByte(':');
name_buffer_->AppendInt(args_count);
}
+ if (code_event_handler_ != NULL) {
+ IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
+ }
+ if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
@@ -1055,13 +1122,17 @@ void Logger::CodeMovingGCEvent() {
void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
- if (!log_->IsEnabled()) return;
- if (FLAG_ll_prof || Serializer::enabled()) {
+ if (!is_logging_code_events()) return;
+ if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[REG_EXP_TAG]);
name_buffer_->AppendByte(':');
name_buffer_->AppendString(source);
}
+ if (code_event_handler_ != NULL) {
+ IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
+ }
+ if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
@@ -1083,6 +1154,7 @@ void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
void Logger::CodeMoveEvent(Address from, Address to) {
+ if (code_event_handler_ != NULL) IssueCodeMovedEvent(from, to);
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) LowLevelCodeMoveEvent(from, to);
if (Serializer::enabled() && address_to_name_map_ != NULL) {
@@ -1093,6 +1165,7 @@ void Logger::CodeMoveEvent(Address from, Address to) {
void Logger::CodeDeleteEvent(Address from) {
+ if (code_event_handler_ != NULL) IssueCodeRemovedEvent(from);
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) LowLevelCodeDeleteEvent(from);
if (Serializer::enabled() && address_to_name_map_ != NULL) {
@@ -1392,7 +1465,7 @@ static int EnumerateCompiledFunctions(Handle<SharedFunctionInfo>* sfis,
void Logger::LogCodeObject(Object* object) {
- if (FLAG_log_code || FLAG_ll_prof) {
+ if (FLAG_log_code || FLAG_ll_prof || is_logging_code_events()) {
Code* code_object = Code::cast(object);
LogEventsAndTags tag = Logger::STUB_TAG;
const char* description = "Unknown code from the snapshot";
@@ -1676,6 +1749,18 @@ bool Logger::SetUp() {
}
+void Logger::SetCodeEventHandler(uint32_t options,
+ JitCodeEventHandler event_handler) {
+ code_event_handler_ = event_handler;
+
+ if (code_event_handler_ != NULL && (options & kJitCodeEventEnumExisting)) {
+ HandleScope scope;
+ LogCodeObjects();
+ LogCompiledFunctions();
+ }
+}
+
+
Sampler* Logger::sampler() {
return ticker_;
}
diff --git a/deps/v8/src/log.h b/deps/v8/src/log.h
index 03c7b3b67..33f359a7f 100644
--- a/deps/v8/src/log.h
+++ b/deps/v8/src/log.h
@@ -86,6 +86,15 @@ class Ticker;
logger->Call; \
} while (false)
+#define LOG_CODE_EVENT(isolate, Call) \
+ do { \
+ v8::internal::Logger* logger = \
+ (isolate)->logger(); \
+ if (logger->is_logging_code_events()) \
+ logger->Call; \
+ } while (false)
+
+
#define LOG_EVENTS_AND_TAGS_LIST(V) \
V(CODE_CREATION_EVENT, "code-creation") \
V(CODE_MOVE_EVENT, "code-move") \
@@ -151,6 +160,10 @@ class Logger {
// Acquires resources for logging if the right flags are set.
bool SetUp();
+ // Sets the current code event handler.
+ void SetCodeEventHandler(uint32_t options,
+ JitCodeEventHandler event_handler);
+
void EnsureTickerStarted();
void EnsureTickerStopped();
@@ -274,6 +287,10 @@ class Logger {
return logging_nesting_ > 0;
}
+ bool is_logging_code_events() {
+ return is_logging() || code_event_handler_ != NULL;
+ }
+
// Pause/Resume collection of profiling data.
// When data collection is paused, CPU Tick events are discarded until
// data collection is Resumed.
@@ -312,6 +329,11 @@ class Logger {
Logger();
~Logger();
+ // Issue code notifications.
+ void IssueCodeAddedEvent(Code* code, const char* name, size_t name_len);
+ void IssueCodeMovedEvent(Address from, Address to);
+ void IssueCodeRemovedEvent(Address from);
+
// Emits the profiler's first message.
void ProfilerBeginEvent();
@@ -413,6 +435,9 @@ class Logger {
// 'true' between SetUp() and TearDown().
bool is_initialized_;
+ // The code event handler - if any.
+ JitCodeEventHandler code_event_handler_;
+
// Support for 'incremental addresses' in compressed logs:
// LogMessageBuilder::AppendAddress(Address addr)
Address last_address_;
diff --git a/deps/v8/src/mark-compact-inl.h b/deps/v8/src/mark-compact-inl.h
index 2f7e31fea..10773e720 100644
--- a/deps/v8/src/mark-compact-inl.h
+++ b/deps/v8/src/mark-compact-inl.h
@@ -52,32 +52,15 @@ void MarkCompactCollector::SetFlags(int flags) {
}
-bool MarkCompactCollector::MarkObjectAndPush(HeapObject* obj) {
- if (MarkObjectWithoutPush(obj)) {
- marking_deque_.PushBlack(obj);
- return true;
- }
- return false;
-}
-
-
void MarkCompactCollector::MarkObject(HeapObject* obj, MarkBit mark_bit) {
ASSERT(Marking::MarkBitFrom(obj) == mark_bit);
if (!mark_bit.Get()) {
mark_bit.Set();
MemoryChunk::IncrementLiveBytesFromGC(obj->address(), obj->Size());
- ProcessNewlyMarkedObject(obj);
- }
-}
-
-
-bool MarkCompactCollector::MarkObjectWithoutPush(HeapObject* obj) {
- MarkBit mark_bit = Marking::MarkBitFrom(obj);
- if (!mark_bit.Get()) {
- SetMark(obj, mark_bit);
- return true;
+ ASSERT(IsMarked(obj));
+ ASSERT(HEAP->Contains(obj));
+ marking_deque_.PushBlack(obj);
}
- return false;
}
@@ -86,9 +69,6 @@ void MarkCompactCollector::SetMark(HeapObject* obj, MarkBit mark_bit) {
ASSERT(Marking::MarkBitFrom(obj) == mark_bit);
mark_bit.Set();
MemoryChunk::IncrementLiveBytesFromGC(obj->address(), obj->Size());
- if (obj->IsMap()) {
- heap_->ClearCacheOnMap(Map::cast(obj));
- }
}
diff --git a/deps/v8/src/mark-compact.cc b/deps/v8/src/mark-compact.cc
index 6f2b55963..24730c6c0 100644
--- a/deps/v8/src/mark-compact.cc
+++ b/deps/v8/src/mark-compact.cc
@@ -64,23 +64,21 @@ MarkCompactCollector::MarkCompactCollector() : // NOLINT
abort_incremental_marking_(false),
compacting_(false),
was_marked_incrementally_(false),
- flush_monomorphic_ics_(false),
tracer_(NULL),
migration_slots_buffer_(NULL),
heap_(NULL),
code_flusher_(NULL),
- encountered_weak_maps_(NULL),
- marker_(this, this) { }
+ encountered_weak_maps_(NULL) { }
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
class VerifyMarkingVisitor: public ObjectVisitor {
public:
void VisitPointers(Object** start, Object** end) {
for (Object** current = start; current < end; current++) {
if ((*current)->IsHeapObject()) {
HeapObject* object = HeapObject::cast(*current);
- ASSERT(HEAP->mark_compact_collector()->IsMarked(object));
+ CHECK(HEAP->mark_compact_collector()->IsMarked(object));
}
}
}
@@ -97,7 +95,7 @@ static void VerifyMarking(Address bottom, Address top) {
current += kPointerSize) {
object = HeapObject::FromAddress(current);
if (MarkCompactCollector::IsMarked(object)) {
- ASSERT(current >= next_object_must_be_here_or_later);
+ CHECK(current >= next_object_must_be_here_or_later);
object->Iterate(&visitor);
next_object_must_be_here_or_later = current + object->Size();
}
@@ -110,12 +108,12 @@ static void VerifyMarking(NewSpace* space) {
NewSpacePageIterator it(space->bottom(), end);
// The bottom position is at the start of its page. Allows us to use
// page->area_start() as start of range on all pages.
- ASSERT_EQ(space->bottom(),
+ CHECK_EQ(space->bottom(),
NewSpacePage::FromAddress(space->bottom())->area_start());
while (it.has_next()) {
NewSpacePage* page = it.next();
Address limit = it.has_next() ? page->area_end() : end;
- ASSERT(limit == end || !page->Contains(end));
+ CHECK(limit == end || !page->Contains(end));
VerifyMarking(page->area_start(), limit);
}
}
@@ -175,7 +173,7 @@ static void VerifyEvacuation(Address bottom, Address top) {
current += kPointerSize) {
object = HeapObject::FromAddress(current);
if (MarkCompactCollector::IsMarked(object)) {
- ASSERT(current >= next_object_must_be_here_or_later);
+ CHECK(current >= next_object_must_be_here_or_later);
object->Iterate(&visitor);
next_object_must_be_here_or_later = current + object->Size();
}
@@ -191,7 +189,7 @@ static void VerifyEvacuation(NewSpace* space) {
NewSpacePage* page = it.next();
Address current = page->area_start();
Address limit = it.has_next() ? page->area_end() : space->top();
- ASSERT(limit == space->top() || !page->Contains(space->top()));
+ CHECK(limit == space->top() || !page->Contains(space->top()));
while (current < limit) {
HeapObject* object = HeapObject::FromAddress(current);
object->Iterate(&visitor);
@@ -223,6 +221,101 @@ static void VerifyEvacuation(Heap* heap) {
VerifyEvacuationVisitor visitor;
heap->IterateStrongRoots(&visitor, VISIT_ALL);
}
+#endif // VERIFY_HEAP
+
+
+#ifdef DEBUG
+class VerifyNativeContextSeparationVisitor: public ObjectVisitor {
+ public:
+ VerifyNativeContextSeparationVisitor() : current_native_context_(NULL) {}
+
+ void VisitPointers(Object** start, Object** end) {
+ for (Object** current = start; current < end; current++) {
+ if ((*current)->IsHeapObject()) {
+ HeapObject* object = HeapObject::cast(*current);
+ if (object->IsString()) continue;
+ switch (object->map()->instance_type()) {
+ case JS_FUNCTION_TYPE:
+ CheckContext(JSFunction::cast(object)->context());
+ break;
+ case JS_GLOBAL_PROXY_TYPE:
+ CheckContext(JSGlobalProxy::cast(object)->native_context());
+ break;
+ case JS_GLOBAL_OBJECT_TYPE:
+ case JS_BUILTINS_OBJECT_TYPE:
+ CheckContext(GlobalObject::cast(object)->native_context());
+ break;
+ case JS_ARRAY_TYPE:
+ case JS_DATE_TYPE:
+ case JS_OBJECT_TYPE:
+ case JS_REGEXP_TYPE:
+ VisitPointer(HeapObject::RawField(object, JSObject::kMapOffset));
+ break;
+ case MAP_TYPE:
+ VisitPointer(HeapObject::RawField(object, Map::kPrototypeOffset));
+ VisitPointer(HeapObject::RawField(object, Map::kConstructorOffset));
+ break;
+ case FIXED_ARRAY_TYPE:
+ if (object->IsContext()) {
+ CheckContext(object);
+ } else {
+ FixedArray* array = FixedArray::cast(object);
+ int length = array->length();
+ // Set array length to zero to prevent cycles while iterating
+ // over array bodies, this is easier than intrusive marking.
+ array->set_length(0);
+ array->IterateBody(
+ FIXED_ARRAY_TYPE, FixedArray::SizeFor(length), this);
+ array->set_length(length);
+ }
+ break;
+ case JS_GLOBAL_PROPERTY_CELL_TYPE:
+ case JS_PROXY_TYPE:
+ case JS_VALUE_TYPE:
+ case TYPE_FEEDBACK_INFO_TYPE:
+ object->Iterate(this);
+ break;
+ case ACCESSOR_INFO_TYPE:
+ case BYTE_ARRAY_TYPE:
+ case CALL_HANDLER_INFO_TYPE:
+ case CODE_TYPE:
+ case FIXED_DOUBLE_ARRAY_TYPE:
+ case HEAP_NUMBER_TYPE:
+ case INTERCEPTOR_INFO_TYPE:
+ case ODDBALL_TYPE:
+ case SCRIPT_TYPE:
+ case SHARED_FUNCTION_INFO_TYPE:
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+ }
+
+ private:
+ void CheckContext(Object* context) {
+ if (!context->IsContext()) return;
+ Context* native_context = Context::cast(context)->native_context();
+ if (current_native_context_ == NULL) {
+ current_native_context_ = native_context;
+ } else {
+ CHECK_EQ(current_native_context_, native_context);
+ }
+ }
+
+ Context* current_native_context_;
+};
+
+
+static void VerifyNativeContextSeparation(Heap* heap) {
+ HeapObjectIterator it(heap->code_space());
+
+ for (Object* object = it.Next(); object != NULL; object = it.Next()) {
+ VerifyNativeContextSeparationVisitor visitor;
+ Code::cast(object)->CodeIterateBody(&visitor);
+ }
+}
#endif
@@ -248,10 +341,17 @@ bool MarkCompactCollector::StartCompaction(CompactionMode mode) {
if (!compacting_) {
ASSERT(evacuation_candidates_.length() == 0);
+#ifdef ENABLE_GDB_JIT_INTERFACE
+ // If GDBJIT interface is active disable compaction.
+ if (FLAG_gdbjit) return false;
+#endif
+
CollectEvacuationCandidates(heap()->old_pointer_space());
CollectEvacuationCandidates(heap()->old_data_space());
- if (FLAG_compact_code_space && mode == NON_INCREMENTAL_COMPACTION) {
+ if (FLAG_compact_code_space &&
+ (mode == NON_INCREMENTAL_COMPACTION ||
+ FLAG_incremental_code_compaction)) {
CollectEvacuationCandidates(heap()->code_space());
} else if (FLAG_trace_fragmentation) {
TraceFragmentation(heap()->code_space());
@@ -286,7 +386,7 @@ void MarkCompactCollector::CollectGarbage() {
ClearWeakMaps();
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
VerifyMarking(heap_);
}
@@ -296,13 +396,19 @@ void MarkCompactCollector::CollectGarbage() {
if (!FLAG_collect_maps) ReattachInitialMaps();
+#ifdef DEBUG
+ if (FLAG_verify_native_context_separation) {
+ VerifyNativeContextSeparation(heap_);
+ }
+#endif
+
Finish();
tracer_ = NULL;
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) {
PageIterator it(space);
@@ -313,6 +419,7 @@ void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) {
}
}
+
void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) {
NewSpacePageIterator it(space->bottom(), space->top());
@@ -323,6 +430,7 @@ void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) {
}
}
+
void MarkCompactCollector::VerifyMarkbitsAreClean() {
VerifyMarkbitsAreClean(heap_->old_pointer_space());
VerifyMarkbitsAreClean(heap_->old_data_space());
@@ -334,11 +442,11 @@ void MarkCompactCollector::VerifyMarkbitsAreClean() {
LargeObjectIterator it(heap_->lo_space());
for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
MarkBit mark_bit = Marking::MarkBitFrom(obj);
- ASSERT(Marking::IsWhite(mark_bit));
- ASSERT_EQ(0, Page::FromAddress(obj->address())->LiveBytes());
+ CHECK(Marking::IsWhite(mark_bit));
+ CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes());
}
}
-#endif
+#endif // VERIFY_HEAP
static void ClearMarkbitsInPagedSpace(PagedSpace* space) {
@@ -503,7 +611,7 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
static const int kMaxMaxEvacuationCandidates = 1000;
int number_of_pages = space->CountTotalPages();
int max_evacuation_candidates =
- static_cast<int>(sqrt(static_cast<double>(number_of_pages / 2)) + 1);
+ static_cast<int>(sqrt(number_of_pages / 2.0) + 1);
if (FLAG_stress_compaction || FLAG_always_compact) {
max_evacuation_candidates = kMaxMaxEvacuationCandidates;
@@ -533,29 +641,28 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
intptr_t over_reserved = reserved - space->SizeOfObjects();
static const intptr_t kFreenessThreshold = 50;
- if (over_reserved >= 2 * space->AreaSize()) {
+ if (reduce_memory_footprint_ && over_reserved >= space->AreaSize()) {
// If reduction of memory footprint was requested, we are aggressive
// about choosing pages to free. We expect that half-empty pages
// are easier to compact so slightly bump the limit.
- if (reduce_memory_footprint_) {
- mode = REDUCE_MEMORY_FOOTPRINT;
- max_evacuation_candidates += 2;
- }
+ mode = REDUCE_MEMORY_FOOTPRINT;
+ max_evacuation_candidates += 2;
+ }
+
+ if (over_reserved > reserved / 3 && over_reserved >= 2 * space->AreaSize()) {
// If over-usage is very high (more than a third of the space), we
// try to free all mostly empty pages. We expect that almost empty
// pages are even easier to compact so bump the limit even more.
- if (over_reserved > reserved / 3) {
- mode = REDUCE_MEMORY_FOOTPRINT;
- max_evacuation_candidates *= 2;
- }
+ mode = REDUCE_MEMORY_FOOTPRINT;
+ max_evacuation_candidates *= 2;
+ }
- if (FLAG_trace_fragmentation && mode == REDUCE_MEMORY_FOOTPRINT) {
- PrintF("Estimated over reserved memory: %.1f / %.1f MB (threshold %d)\n",
- static_cast<double>(over_reserved) / MB,
- static_cast<double>(reserved) / MB,
- static_cast<int>(kFreenessThreshold));
- }
+ if (FLAG_trace_fragmentation && mode == REDUCE_MEMORY_FOOTPRINT) {
+ PrintF("Estimated over reserved memory: %.1f / %.1f MB (threshold %d)\n",
+ static_cast<double>(over_reserved) / MB,
+ static_cast<double>(reserved) / MB,
+ static_cast<int>(kFreenessThreshold));
}
intptr_t estimated_release = 0;
@@ -577,7 +684,7 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
p->ClearEvacuationCandidate();
if (FLAG_stress_compaction) {
- int counter = space->heap()->ms_count();
+ unsigned int counter = space->heap()->ms_count();
uintptr_t page_number = reinterpret_cast<uintptr_t>(p) >> kPageSizeBits;
if ((counter & 1) == (page_number & 1)) fragmentation = 1;
} else if (mode == REDUCE_MEMORY_FOOTPRINT) {
@@ -669,12 +776,6 @@ void MarkCompactCollector::AbortCompaction() {
void MarkCompactCollector::Prepare(GCTracer* tracer) {
was_marked_incrementally_ = heap()->incremental_marking()->IsMarking();
- // Monomorphic ICs are preserved when possible, but need to be flushed
- // when they might be keeping a Context alive, or when the heap is about
- // to be serialized.
- flush_monomorphic_ics_ =
- heap()->isolate()->context_exit_happened() || Serializer::enabled();
-
// Rather than passing the tracer around we stash it in a static member
// variable.
tracer_ = tracer;
@@ -686,13 +787,6 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) {
ASSERT(!FLAG_never_compact || !FLAG_always_compact);
-#ifdef ENABLE_GDB_JIT_INTERFACE
- if (FLAG_gdbjit) {
- // If GDBJIT interface is active disable compaction.
- compacting_collection_ = false;
- }
-#endif
-
// Clear marking bits if incremental marking is aborted.
if (was_marked_incrementally_ && abort_incremental_marking_) {
heap()->incremental_marking()->Abort();
@@ -714,7 +808,7 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) {
space->PrepareForMarkCompact();
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (!was_marked_incrementally_ && FLAG_verify_heap) {
VerifyMarkbitsAreClean();
}
@@ -765,133 +859,71 @@ void MarkCompactCollector::Finish() {
// and continue with marking. This process repeats until all reachable
// objects have been marked.
-class CodeFlusher {
- public:
- explicit CodeFlusher(Isolate* isolate)
- : isolate_(isolate),
- jsfunction_candidates_head_(NULL),
- shared_function_info_candidates_head_(NULL) {}
-
- void AddCandidate(SharedFunctionInfo* shared_info) {
- SetNextCandidate(shared_info, shared_function_info_candidates_head_);
- shared_function_info_candidates_head_ = shared_info;
- }
+void CodeFlusher::ProcessJSFunctionCandidates() {
+ Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
+ Object* undefined = isolate_->heap()->undefined_value();
- void AddCandidate(JSFunction* function) {
- ASSERT(function->code() == function->shared()->code());
+ JSFunction* candidate = jsfunction_candidates_head_;
+ JSFunction* next_candidate;
+ while (candidate != NULL) {
+ next_candidate = GetNextCandidate(candidate);
+ ClearNextCandidate(candidate, undefined);
- SetNextCandidate(function, jsfunction_candidates_head_);
- jsfunction_candidates_head_ = function;
- }
+ SharedFunctionInfo* shared = candidate->shared();
- void ProcessCandidates() {
- ProcessSharedFunctionInfoCandidates();
- ProcessJSFunctionCandidates();
- }
-
- private:
- void ProcessJSFunctionCandidates() {
- Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
-
- JSFunction* candidate = jsfunction_candidates_head_;
- JSFunction* next_candidate;
- while (candidate != NULL) {
- next_candidate = GetNextCandidate(candidate);
-
- SharedFunctionInfo* shared = candidate->shared();
-
- Code* code = shared->code();
- MarkBit code_mark = Marking::MarkBitFrom(code);
- if (!code_mark.Get()) {
- shared->set_code(lazy_compile);
- candidate->set_code(lazy_compile);
- } else {
- candidate->set_code(shared->code());
- }
-
- // We are in the middle of a GC cycle so the write barrier in the code
- // setter did not record the slot update and we have to do that manually.
- Address slot = candidate->address() + JSFunction::kCodeEntryOffset;
- Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot));
- isolate_->heap()->mark_compact_collector()->
- RecordCodeEntrySlot(slot, target);
-
- RecordSharedFunctionInfoCodeSlot(shared);
-
- candidate = next_candidate;
+ Code* code = shared->code();
+ MarkBit code_mark = Marking::MarkBitFrom(code);
+ if (!code_mark.Get()) {
+ shared->set_code(lazy_compile);
+ candidate->set_code(lazy_compile);
+ } else if (code == lazy_compile) {
+ candidate->set_code(lazy_compile);
}
- jsfunction_candidates_head_ = NULL;
- }
-
-
- void ProcessSharedFunctionInfoCandidates() {
- Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
-
- SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
- SharedFunctionInfo* next_candidate;
- while (candidate != NULL) {
- next_candidate = GetNextCandidate(candidate);
- SetNextCandidate(candidate, NULL);
-
- Code* code = candidate->code();
- MarkBit code_mark = Marking::MarkBitFrom(code);
- if (!code_mark.Get()) {
- candidate->set_code(lazy_compile);
- }
-
- RecordSharedFunctionInfoCodeSlot(candidate);
+ // We are in the middle of a GC cycle so the write barrier in the code
+ // setter did not record the slot update and we have to do that manually.
+ Address slot = candidate->address() + JSFunction::kCodeEntryOffset;
+ Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot));
+ isolate_->heap()->mark_compact_collector()->
+ RecordCodeEntrySlot(slot, target);
- candidate = next_candidate;
- }
+ Object** shared_code_slot =
+ HeapObject::RawField(shared, SharedFunctionInfo::kCodeOffset);
+ isolate_->heap()->mark_compact_collector()->
+ RecordSlot(shared_code_slot, shared_code_slot, *shared_code_slot);
- shared_function_info_candidates_head_ = NULL;
+ candidate = next_candidate;
}
- void RecordSharedFunctionInfoCodeSlot(SharedFunctionInfo* shared) {
- Object** slot = HeapObject::RawField(shared,
- SharedFunctionInfo::kCodeOffset);
- isolate_->heap()->mark_compact_collector()->
- RecordSlot(slot, slot, HeapObject::cast(*slot));
- }
+ jsfunction_candidates_head_ = NULL;
+}
- static JSFunction** GetNextCandidateField(JSFunction* candidate) {
- return reinterpret_cast<JSFunction**>(
- candidate->address() + JSFunction::kCodeEntryOffset);
- }
- static JSFunction* GetNextCandidate(JSFunction* candidate) {
- return *GetNextCandidateField(candidate);
- }
+void CodeFlusher::ProcessSharedFunctionInfoCandidates() {
+ Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
- static void SetNextCandidate(JSFunction* candidate,
- JSFunction* next_candidate) {
- *GetNextCandidateField(candidate) = next_candidate;
- }
+ SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
+ SharedFunctionInfo* next_candidate;
+ while (candidate != NULL) {
+ next_candidate = GetNextCandidate(candidate);
+ ClearNextCandidate(candidate);
- static SharedFunctionInfo** GetNextCandidateField(
- SharedFunctionInfo* candidate) {
Code* code = candidate->code();
- return reinterpret_cast<SharedFunctionInfo**>(
- code->address() + Code::kGCMetadataOffset);
- }
+ MarkBit code_mark = Marking::MarkBitFrom(code);
+ if (!code_mark.Get()) {
+ candidate->set_code(lazy_compile);
+ }
- static SharedFunctionInfo* GetNextCandidate(SharedFunctionInfo* candidate) {
- return reinterpret_cast<SharedFunctionInfo*>(
- candidate->code()->gc_metadata());
- }
+ Object** code_slot =
+ HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset);
+ isolate_->heap()->mark_compact_collector()->
+ RecordSlot(code_slot, code_slot, *code_slot);
- static void SetNextCandidate(SharedFunctionInfo* candidate,
- SharedFunctionInfo* next_candidate) {
- candidate->code()->set_gc_metadata(next_candidate);
+ candidate = next_candidate;
}
- Isolate* isolate_;
- JSFunction* jsfunction_candidates_head_;
- SharedFunctionInfo* shared_function_info_candidates_head_;
-
- DISALLOW_COPY_AND_ASSIGN(CodeFlusher);
-};
+ shared_function_info_candidates_head_ = NULL;
+}
MarkCompactCollector::~MarkCompactCollector() {
@@ -938,81 +970,24 @@ static inline HeapObject* ShortCircuitConsString(Object** p) {
}
-class StaticMarkingVisitor : public StaticVisitorBase {
+class MarkCompactMarkingVisitor
+ : public StaticMarkingVisitor<MarkCompactMarkingVisitor> {
public:
- static inline void IterateBody(Map* map, HeapObject* obj) {
- table_.GetVisitor(map)(map, obj);
- }
-
- static void Initialize() {
- table_.Register(kVisitShortcutCandidate,
- &FixedBodyVisitor<StaticMarkingVisitor,
- ConsString::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitConsString,
- &FixedBodyVisitor<StaticMarkingVisitor,
- ConsString::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitSlicedString,
- &FixedBodyVisitor<StaticMarkingVisitor,
- SlicedString::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitFixedArray,
- &FlexibleBodyVisitor<StaticMarkingVisitor,
- FixedArray::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitGlobalContext, &VisitGlobalContext);
+ static void ObjectStatsVisitBase(StaticVisitorBase::VisitorId id,
+ Map* map, HeapObject* obj);
- table_.Register(kVisitFixedDoubleArray, DataObjectVisitor::Visit);
+ static void ObjectStatsCountFixedArray(
+ FixedArrayBase* fixed_array,
+ FixedArraySubInstanceType fast_type,
+ FixedArraySubInstanceType dictionary_type);
- table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
- table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit);
- table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit);
- table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
-
- table_.Register(kVisitJSWeakMap, &VisitJSWeakMap);
-
- table_.Register(kVisitOddball,
- &FixedBodyVisitor<StaticMarkingVisitor,
- Oddball::BodyDescriptor,
- void>::Visit);
- table_.Register(kVisitMap,
- &FixedBodyVisitor<StaticMarkingVisitor,
- Map::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitCode, &VisitCode);
-
- table_.Register(kVisitSharedFunctionInfo,
- &VisitSharedFunctionInfoAndFlushCode);
-
- table_.Register(kVisitJSFunction,
- &VisitJSFunctionAndFlushCode);
-
- table_.Register(kVisitJSRegExp,
- &VisitRegExpAndFlushCode);
-
- table_.Register(kVisitPropertyCell,
- &FixedBodyVisitor<StaticMarkingVisitor,
- JSGlobalPropertyCell::BodyDescriptor,
- void>::Visit);
-
- table_.RegisterSpecializations<DataObjectVisitor,
- kVisitDataObject,
- kVisitDataObjectGeneric>();
-
- table_.RegisterSpecializations<JSObjectVisitor,
- kVisitJSObject,
- kVisitJSObjectGeneric>();
+ template<MarkCompactMarkingVisitor::VisitorId id>
+ class ObjectStatsTracker {
+ public:
+ static inline void Visit(Map* map, HeapObject* obj);
+ };
- table_.RegisterSpecializations<StructObjectVisitor,
- kVisitStruct,
- kVisitStructGeneric>();
- }
+ static void Initialize();
INLINE(static void VisitPointer(Heap* heap, Object** p)) {
MarkObjectByPointer(heap->mark_compact_collector(), p, p);
@@ -1031,48 +1006,21 @@ class StaticMarkingVisitor : public StaticVisitorBase {
}
}
- static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) {
- ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
- JSGlobalPropertyCell* cell =
- JSGlobalPropertyCell::cast(rinfo->target_cell());
- MarkBit mark = Marking::MarkBitFrom(cell);
- heap->mark_compact_collector()->MarkObject(cell, mark);
- }
-
- static inline void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo) {
- ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
- // TODO(mstarzinger): We do not short-circuit cons strings here, verify
- // that there can be no such embedded pointers and add assertion here.
- HeapObject* object = HeapObject::cast(rinfo->target_object());
- heap->mark_compact_collector()->RecordRelocSlot(rinfo, object);
+ // Marks the object black and pushes it on the marking stack.
+ INLINE(static void MarkObject(Heap* heap, HeapObject* object)) {
MarkBit mark = Marking::MarkBitFrom(object);
heap->mark_compact_collector()->MarkObject(object, mark);
}
- static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) {
- ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
- Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
- if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
- && (target->ic_state() == MEGAMORPHIC ||
- heap->mark_compact_collector()->flush_monomorphic_ics_ ||
- target->ic_age() != heap->global_ic_age())) {
- IC::Clear(rinfo->pc());
- target = Code::GetCodeFromTargetAddress(rinfo->target_address());
+ // Marks the object black without pushing it on the marking stack.
+ // Returns true if object needed marking and false otherwise.
+ INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) {
+ MarkBit mark_bit = Marking::MarkBitFrom(object);
+ if (!mark_bit.Get()) {
+ heap->mark_compact_collector()->SetMark(object, mark_bit);
+ return true;
}
- MarkBit code_mark = Marking::MarkBitFrom(target);
- heap->mark_compact_collector()->MarkObject(target, code_mark);
- heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
- }
-
- static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) {
- ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
- rinfo->IsPatchedReturnSequence()) ||
- (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
- rinfo->IsPatchedDebugBreakSlotSequence()));
- Code* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
- MarkBit code_mark = Marking::MarkBitFrom(target);
- heap->mark_compact_collector()->MarkObject(target, code_mark);
- heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
+ return false;
}
// Mark object pointed to by p.
@@ -1127,28 +1075,10 @@ class StaticMarkingVisitor : public StaticVisitorBase {
return true;
}
- static inline void VisitExternalReference(Address* p) { }
- static inline void VisitExternalReference(RelocInfo* rinfo) { }
- static inline void VisitRuntimeEntry(RelocInfo* rinfo) { }
-
- private:
- class DataObjectVisitor {
- public:
- template<int size>
- static void VisitSpecialized(Map* map, HeapObject* object) {
- }
-
- static void Visit(Map* map, HeapObject* object) {
- }
- };
-
- typedef FlexibleBodyVisitor<StaticMarkingVisitor,
- JSObject::BodyDescriptor,
- void> JSObjectVisitor;
-
- typedef FlexibleBodyVisitor<StaticMarkingVisitor,
- StructBodyDescriptor,
- void> StructObjectVisitor;
+ INLINE(static void BeforeVisitingSharedFunctionInfo(HeapObject* object)) {
+ SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
+ shared->BeforeVisitingPointers();
+ }
static void VisitJSWeakMap(Map* map, HeapObject* object) {
MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
@@ -1162,12 +1092,12 @@ class StaticMarkingVisitor : public StaticVisitorBase {
// Skip visiting the backing hash table containing the mappings.
int object_size = JSWeakMap::BodyDescriptor::SizeOf(map, object);
- BodyVisitorBase<StaticMarkingVisitor>::IteratePointers(
+ BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers(
map->GetHeap(),
object,
JSWeakMap::BodyDescriptor::kStartOffset,
JSWeakMap::kTableOffset);
- BodyVisitorBase<StaticMarkingVisitor>::IteratePointers(
+ BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers(
map->GetHeap(),
object,
JSWeakMap::kTableOffset + kPointerSize,
@@ -1187,136 +1117,14 @@ class StaticMarkingVisitor : public StaticVisitorBase {
ASSERT(MarkCompactCollector::IsMarked(table->map()));
}
- static void VisitCode(Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
- Code* code = reinterpret_cast<Code*>(object);
- if (FLAG_cleanup_code_caches_at_gc) {
- code->ClearTypeFeedbackCells(heap);
- }
- code->CodeIterateBody<StaticMarkingVisitor>(heap);
- }
+ private:
+ template<int id>
+ static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj);
// Code flushing support.
- // How many collections newly compiled code object will survive before being
- // flushed.
- static const int kCodeAgeThreshold = 5;
-
static const int kRegExpCodeThreshold = 5;
- inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) {
- Object* undefined = heap->undefined_value();
- return (info->script() != undefined) &&
- (reinterpret_cast<Script*>(info->script())->source() != undefined);
- }
-
-
- inline static bool IsCompiled(JSFunction* function) {
- return function->code() !=
- function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
- }
-
- inline static bool IsCompiled(SharedFunctionInfo* function) {
- return function->code() !=
- function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
- }
-
- inline static bool IsFlushable(Heap* heap, JSFunction* function) {
- SharedFunctionInfo* shared_info = function->unchecked_shared();
-
- // Code is either on stack, in compilation cache or referenced
- // by optimized version of function.
- MarkBit code_mark = Marking::MarkBitFrom(function->code());
- if (code_mark.Get()) {
- if (!Marking::MarkBitFrom(shared_info).Get()) {
- shared_info->set_code_age(0);
- }
- return false;
- }
-
- // We do not flush code for optimized functions.
- if (function->code() != shared_info->code()) {
- return false;
- }
-
- return IsFlushable(heap, shared_info);
- }
-
- inline static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info) {
- // Code is either on stack, in compilation cache or referenced
- // by optimized version of function.
- MarkBit code_mark =
- Marking::MarkBitFrom(shared_info->code());
- if (code_mark.Get()) {
- return false;
- }
-
- // The function must be compiled and have the source code available,
- // to be able to recompile it in case we need the function again.
- if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) {
- return false;
- }
-
- // We never flush code for Api functions.
- Object* function_data = shared_info->function_data();
- if (function_data->IsFunctionTemplateInfo()) {
- return false;
- }
-
- // Only flush code for functions.
- if (shared_info->code()->kind() != Code::FUNCTION) {
- return false;
- }
-
- // Function must be lazy compilable.
- if (!shared_info->allows_lazy_compilation()) {
- return false;
- }
-
- // If this is a full script wrapped in a function we do no flush the code.
- if (shared_info->is_toplevel()) {
- return false;
- }
-
- // Age this shared function info.
- if (shared_info->code_age() < kCodeAgeThreshold) {
- shared_info->set_code_age(shared_info->code_age() + 1);
- return false;
- }
-
- return true;
- }
-
-
- static bool FlushCodeForFunction(Heap* heap, JSFunction* function) {
- if (!IsFlushable(heap, function)) return false;
-
- // This function's code looks flushable. But we have to postpone the
- // decision until we see all functions that point to the same
- // SharedFunctionInfo because some of them might be optimized.
- // That would make the nonoptimized version of the code nonflushable,
- // because it is required for bailing out from optimized code.
- heap->mark_compact_collector()->code_flusher()->AddCandidate(function);
- return true;
- }
-
- static inline bool IsValidNotBuiltinContext(Object* ctx) {
- return ctx->IsContext() &&
- !Context::cast(ctx)->global()->IsJSBuiltinsObject();
- }
-
-
- static void VisitSharedFunctionInfoGeneric(Map* map, HeapObject* object) {
- SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object);
-
- if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap();
-
- FixedBodyVisitor<StaticMarkingVisitor,
- SharedFunctionInfo::BodyDescriptor,
- void>::Visit(map, object);
- }
-
-
static void UpdateRegExpCodeAgeAndFlush(Heap* heap,
JSRegExp* re,
bool is_ascii) {
@@ -1379,7 +1187,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
Heap* heap = map->GetHeap();
MarkCompactCollector* collector = heap->mark_compact_collector();
if (!collector->is_code_flushing_enabled()) {
- VisitJSRegExpFields(map, object);
+ VisitJSRegExp(map, object);
return;
}
JSRegExp* re = reinterpret_cast<JSRegExp*>(object);
@@ -1387,183 +1195,161 @@ class StaticMarkingVisitor : public StaticVisitorBase {
UpdateRegExpCodeAgeAndFlush(heap, re, true);
UpdateRegExpCodeAgeAndFlush(heap, re, false);
// Visit the fields of the RegExp, including the updated FixedArray.
- VisitJSRegExpFields(map, object);
+ VisitJSRegExp(map, object);
}
+ static VisitorDispatchTable<Callback> non_count_table_;
+};
- static void VisitSharedFunctionInfoAndFlushCode(Map* map,
- HeapObject* object) {
- Heap* heap = map->GetHeap();
- SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object);
- if (shared->ic_age() != heap->global_ic_age()) {
- shared->ResetForNewContext(heap->global_ic_age());
- }
- MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
- if (!collector->is_code_flushing_enabled()) {
- VisitSharedFunctionInfoGeneric(map, object);
- return;
+void MarkCompactMarkingVisitor::ObjectStatsCountFixedArray(
+ FixedArrayBase* fixed_array,
+ FixedArraySubInstanceType fast_type,
+ FixedArraySubInstanceType dictionary_type) {
+ Heap* heap = fixed_array->map()->GetHeap();
+ if (fixed_array->map() != heap->fixed_cow_array_map() &&
+ fixed_array->map() != heap->fixed_double_array_map() &&
+ fixed_array != heap->empty_fixed_array()) {
+ if (fixed_array->IsDictionary()) {
+ heap->RecordObjectStats(FIXED_ARRAY_TYPE,
+ dictionary_type,
+ fixed_array->Size());
+ } else {
+ heap->RecordObjectStats(FIXED_ARRAY_TYPE,
+ fast_type,
+ fixed_array->Size());
}
- VisitSharedFunctionInfoAndFlushCodeGeneric(map, object, false);
}
+}
- static void VisitSharedFunctionInfoAndFlushCodeGeneric(
- Map* map, HeapObject* object, bool known_flush_code_candidate) {
- Heap* heap = map->GetHeap();
- SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object);
-
- if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap();
-
- if (!known_flush_code_candidate) {
- known_flush_code_candidate = IsFlushable(heap, shared);
- if (known_flush_code_candidate) {
- heap->mark_compact_collector()->code_flusher()->AddCandidate(shared);
- }
- }
-
- VisitSharedFunctionInfoFields(heap, object, known_flush_code_candidate);
+void MarkCompactMarkingVisitor::ObjectStatsVisitBase(
+ MarkCompactMarkingVisitor::VisitorId id, Map* map, HeapObject* obj) {
+ Heap* heap = map->GetHeap();
+ int object_size = obj->Size();
+ heap->RecordObjectStats(map->instance_type(), -1, object_size);
+ non_count_table_.GetVisitorById(id)(map, obj);
+ if (obj->IsJSObject()) {
+ JSObject* object = JSObject::cast(obj);
+ ObjectStatsCountFixedArray(object->elements(),
+ DICTIONARY_ELEMENTS_SUB_TYPE,
+ FAST_ELEMENTS_SUB_TYPE);
+ ObjectStatsCountFixedArray(object->properties(),
+ DICTIONARY_PROPERTIES_SUB_TYPE,
+ FAST_PROPERTIES_SUB_TYPE);
}
+}
- static void VisitCodeEntry(Heap* heap, Address entry_address) {
- Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
- MarkBit mark = Marking::MarkBitFrom(code);
- heap->mark_compact_collector()->MarkObject(code, mark);
- heap->mark_compact_collector()->
- RecordCodeEntrySlot(entry_address, code);
- }
-
- static void VisitGlobalContext(Map* map, HeapObject* object) {
- FixedBodyVisitor<StaticMarkingVisitor,
- Context::MarkCompactBodyDescriptor,
- void>::Visit(map, object);
+template<MarkCompactMarkingVisitor::VisitorId id>
+void MarkCompactMarkingVisitor::ObjectStatsTracker<id>::Visit(
+ Map* map, HeapObject* obj) {
+ ObjectStatsVisitBase(id, map, obj);
+}
- MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
- for (int idx = Context::FIRST_WEAK_SLOT;
- idx < Context::GLOBAL_CONTEXT_SLOTS;
- ++idx) {
- Object** slot =
- HeapObject::RawField(object, FixedArray::OffsetOfElementAt(idx));
- collector->RecordSlot(slot, slot, *slot);
- }
- }
- static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) {
+template<>
+class MarkCompactMarkingVisitor::ObjectStatsTracker<
+ MarkCompactMarkingVisitor::kVisitMap> {
+ public:
+ static inline void Visit(Map* map, HeapObject* obj) {
Heap* heap = map->GetHeap();
- MarkCompactCollector* collector = heap->mark_compact_collector();
- if (!collector->is_code_flushing_enabled()) {
- VisitJSFunction(map, object);
- return;
- }
-
- JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object);
- // The function must have a valid context and not be a builtin.
- bool flush_code_candidate = false;
- if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) {
- flush_code_candidate = FlushCodeForFunction(heap, jsfunction);
- }
-
- if (!flush_code_candidate) {
- Code* code = jsfunction->shared()->code();
- MarkBit code_mark = Marking::MarkBitFrom(code);
- collector->MarkObject(code, code_mark);
-
- if (jsfunction->code()->kind() == Code::OPTIMIZED_FUNCTION) {
- collector->MarkInlinedFunctionsCode(jsfunction->code());
- }
- }
-
- VisitJSFunctionFields(map,
- reinterpret_cast<JSFunction*>(object),
- flush_code_candidate);
+ Map* map_obj = Map::cast(obj);
+ ASSERT(map->instance_type() == MAP_TYPE);
+ DescriptorArray* array = map_obj->instance_descriptors();
+ if (map_obj->owns_descriptors() &&
+ array != heap->empty_descriptor_array()) {
+ int fixed_array_size = array->Size();
+ heap->RecordObjectStats(FIXED_ARRAY_TYPE,
+ DESCRIPTOR_ARRAY_SUB_TYPE,
+ fixed_array_size);
+ }
+ if (map_obj->HasTransitionArray()) {
+ int fixed_array_size = map_obj->transitions()->Size();
+ heap->RecordObjectStats(FIXED_ARRAY_TYPE,
+ TRANSITION_ARRAY_SUB_TYPE,
+ fixed_array_size);
+ }
+ if (map_obj->code_cache() != heap->empty_fixed_array()) {
+ heap->RecordObjectStats(
+ FIXED_ARRAY_TYPE,
+ MAP_CODE_CACHE_SUB_TYPE,
+ FixedArray::cast(map_obj->code_cache())->Size());
+ }
+ ObjectStatsVisitBase(kVisitMap, map, obj);
}
+};
- static void VisitJSFunction(Map* map, HeapObject* object) {
- VisitJSFunctionFields(map,
- reinterpret_cast<JSFunction*>(object),
- false);
+template<>
+class MarkCompactMarkingVisitor::ObjectStatsTracker<
+ MarkCompactMarkingVisitor::kVisitCode> {
+ public:
+ static inline void Visit(Map* map, HeapObject* obj) {
+ Heap* heap = map->GetHeap();
+ int object_size = obj->Size();
+ ASSERT(map->instance_type() == CODE_TYPE);
+ heap->RecordObjectStats(CODE_TYPE, Code::cast(obj)->kind(), object_size);
+ ObjectStatsVisitBase(kVisitCode, map, obj);
}
+};
-#define SLOT_ADDR(obj, offset) \
- reinterpret_cast<Object**>((obj)->address() + offset)
-
-
- static inline void VisitJSFunctionFields(Map* map,
- JSFunction* object,
- bool flush_code_candidate) {
+template<>
+class MarkCompactMarkingVisitor::ObjectStatsTracker<
+ MarkCompactMarkingVisitor::kVisitSharedFunctionInfo> {
+ public:
+ static inline void Visit(Map* map, HeapObject* obj) {
Heap* heap = map->GetHeap();
-
- VisitPointers(heap,
- HeapObject::RawField(object, JSFunction::kPropertiesOffset),
- HeapObject::RawField(object, JSFunction::kCodeEntryOffset));
-
- if (!flush_code_candidate) {
- VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset);
- } else {
- // Don't visit code object.
-
- // Visit shared function info to avoid double checking of it's
- // flushability.
- SharedFunctionInfo* shared_info = object->unchecked_shared();
- MarkBit shared_info_mark = Marking::MarkBitFrom(shared_info);
- if (!shared_info_mark.Get()) {
- Map* shared_info_map = shared_info->map();
- MarkBit shared_info_map_mark =
- Marking::MarkBitFrom(shared_info_map);
- heap->mark_compact_collector()->SetMark(shared_info, shared_info_mark);
- heap->mark_compact_collector()->MarkObject(shared_info_map,
- shared_info_map_mark);
- VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map,
- shared_info,
- true);
- }
+ SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
+ if (sfi->scope_info() != heap->empty_fixed_array()) {
+ heap->RecordObjectStats(
+ FIXED_ARRAY_TYPE,
+ SCOPE_INFO_SUB_TYPE,
+ FixedArray::cast(sfi->scope_info())->Size());
}
-
- VisitPointers(
- heap,
- HeapObject::RawField(object,
- JSFunction::kCodeEntryOffset + kPointerSize),
- HeapObject::RawField(object,
- JSFunction::kNonWeakFieldsEndOffset));
- }
-
- static inline void VisitJSRegExpFields(Map* map,
- HeapObject* object) {
- int last_property_offset =
- JSRegExp::kSize + kPointerSize * map->inobject_properties();
- VisitPointers(map->GetHeap(),
- SLOT_ADDR(object, JSRegExp::kPropertiesOffset),
- SLOT_ADDR(object, last_property_offset));
+ ObjectStatsVisitBase(kVisitSharedFunctionInfo, map, obj);
}
+};
- static void VisitSharedFunctionInfoFields(Heap* heap,
- HeapObject* object,
- bool flush_code_candidate) {
- VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kNameOffset));
-
- if (!flush_code_candidate) {
- VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kCodeOffset));
+template<>
+class MarkCompactMarkingVisitor::ObjectStatsTracker<
+ MarkCompactMarkingVisitor::kVisitFixedArray> {
+ public:
+ static inline void Visit(Map* map, HeapObject* obj) {
+ Heap* heap = map->GetHeap();
+ FixedArray* fixed_array = FixedArray::cast(obj);
+ if (fixed_array == heap->symbol_table()) {
+ heap->RecordObjectStats(
+ FIXED_ARRAY_TYPE,
+ SYMBOL_TABLE_SUB_TYPE,
+ fixed_array->Size());
}
-
- VisitPointers(heap,
- SLOT_ADDR(object, SharedFunctionInfo::kScopeInfoOffset),
- SLOT_ADDR(object, SharedFunctionInfo::kSize));
+ ObjectStatsVisitBase(kVisitFixedArray, map, obj);
}
+};
- #undef SLOT_ADDR
- typedef void (*Callback)(Map* map, HeapObject* object);
+void MarkCompactMarkingVisitor::Initialize() {
+ StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize();
- static VisitorDispatchTable<Callback> table_;
-};
+ table_.Register(kVisitJSRegExp,
+ &VisitRegExpAndFlushCode);
+
+ if (FLAG_track_gc_object_stats) {
+ // Copy the visitor table to make call-through possible.
+ non_count_table_.CopyFrom(&table_);
+#define VISITOR_ID_COUNT_FUNCTION(id) \
+ table_.Register(kVisit##id, ObjectStatsTracker<kVisit##id>::Visit);
+ VISITOR_ID_LIST(VISITOR_ID_COUNT_FUNCTION)
+#undef VISITOR_ID_COUNT_FUNCTION
+ }
+}
-VisitorDispatchTable<StaticMarkingVisitor::Callback>
- StaticMarkingVisitor::table_;
+VisitorDispatchTable<MarkCompactMarkingVisitor::Callback>
+ MarkCompactMarkingVisitor::non_count_table_;
class MarkingVisitor : public ObjectVisitor {
@@ -1571,11 +1357,11 @@ class MarkingVisitor : public ObjectVisitor {
explicit MarkingVisitor(Heap* heap) : heap_(heap) { }
void VisitPointer(Object** p) {
- StaticMarkingVisitor::VisitPointer(heap_, p);
+ MarkCompactMarkingVisitor::VisitPointer(heap_, p);
}
void VisitPointers(Object** start, Object** end) {
- StaticMarkingVisitor::VisitPointers(heap_, start, end);
+ MarkCompactMarkingVisitor::VisitPointers(heap_, start, end);
}
private:
@@ -1622,26 +1408,6 @@ class SharedFunctionInfoMarkingVisitor : public ObjectVisitor {
};
-void MarkCompactCollector::MarkInlinedFunctionsCode(Code* code) {
- // For optimized functions we should retain both non-optimized version
- // of it's code and non-optimized version of all inlined functions.
- // This is required to support bailing out from inlined code.
- DeoptimizationInputData* data =
- DeoptimizationInputData::cast(code->deoptimization_data());
-
- FixedArray* literals = data->LiteralArray();
-
- for (int i = 0, count = data->InlinedFunctionCount()->value();
- i < count;
- i++) {
- JSFunction* inlined = JSFunction::cast(literals->get(i));
- Code* inlined_code = inlined->shared()->code();
- MarkBit inlined_code_mark = Marking::MarkBitFrom(inlined_code);
- MarkObject(inlined_code, inlined_code_mark);
- }
-}
-
-
void MarkCompactCollector::PrepareThreadForCodeFlushing(Isolate* isolate,
ThreadLocalTop* top) {
for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) {
@@ -1654,7 +1420,8 @@ void MarkCompactCollector::PrepareThreadForCodeFlushing(Isolate* isolate,
MarkBit code_mark = Marking::MarkBitFrom(code);
MarkObject(code, code_mark);
if (frame->is_optimized()) {
- MarkInlinedFunctionsCode(frame->LookupCode());
+ MarkCompactMarkingVisitor::MarkInlinedFunctionsCode(heap(),
+ frame->LookupCode());
}
}
}
@@ -1734,7 +1501,7 @@ class RootMarkingVisitor : public ObjectVisitor {
// Mark the map pointer and body, and push them on the marking stack.
MarkBit map_mark = Marking::MarkBitFrom(map);
collector_->MarkObject(map, map_mark);
- StaticMarkingVisitor::IterateBody(map, object);
+ MarkCompactMarkingVisitor::IterateBody(map, object);
// Mark all the objects reachable from the map and body. May leave
// overflowed objects in the heap.
@@ -1796,172 +1563,6 @@ class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
};
-void MarkCompactCollector::ProcessNewlyMarkedObject(HeapObject* object) {
- ASSERT(IsMarked(object));
- ASSERT(HEAP->Contains(object));
- if (object->IsMap()) {
- Map* map = Map::cast(object);
- heap_->ClearCacheOnMap(map);
-
- // When map collection is enabled we have to mark through map's transitions
- // in a special way to make transition links weak. Only maps for subclasses
- // of JSReceiver can have transitions.
- STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
- if (FLAG_collect_maps && map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
- marker_.MarkMapContents(map);
- } else {
- marking_deque_.PushBlack(map);
- }
- } else {
- marking_deque_.PushBlack(object);
- }
-}
-
-
-// Force instantiation of template instances.
-template void Marker<IncrementalMarking>::MarkMapContents(Map* map);
-template void Marker<MarkCompactCollector>::MarkMapContents(Map* map);
-
-
-template <class T>
-void Marker<T>::MarkMapContents(Map* map) {
- // Mark prototype transitions array but don't push it into marking stack.
- // This will make references from it weak. We will clean dead prototype
- // transitions in ClearNonLiveTransitions.
- Object** proto_trans_slot =
- HeapObject::RawField(map, Map::kPrototypeTransitionsOrBackPointerOffset);
- HeapObject* prototype_transitions = HeapObject::cast(*proto_trans_slot);
- if (prototype_transitions->IsFixedArray()) {
- mark_compact_collector()->RecordSlot(proto_trans_slot,
- proto_trans_slot,
- prototype_transitions);
- MarkBit mark = Marking::MarkBitFrom(prototype_transitions);
- if (!mark.Get()) {
- mark.Set();
- MemoryChunk::IncrementLiveBytesFromGC(prototype_transitions->address(),
- prototype_transitions->Size());
- }
- }
-
- // Make sure that the back pointer stored either in the map itself or inside
- // its prototype transitions array is marked. Treat pointers in the descriptor
- // array as weak and also mark that array to prevent visiting it later.
- base_marker()->MarkObjectAndPush(HeapObject::cast(map->GetBackPointer()));
-
- Object** descriptor_array_slot =
- HeapObject::RawField(map, Map::kInstanceDescriptorsOrBitField3Offset);
- Object* descriptor_array = *descriptor_array_slot;
- if (!descriptor_array->IsSmi()) {
- MarkDescriptorArray(reinterpret_cast<DescriptorArray*>(descriptor_array));
- }
-
- // Mark the Object* fields of the Map. Since the descriptor array has been
- // marked already, it is fine that one of these fields contains a pointer
- // to it. But make sure to skip back pointer and prototype transitions.
- STATIC_ASSERT(Map::kPointerFieldsEndOffset ==
- Map::kPrototypeTransitionsOrBackPointerOffset + kPointerSize);
- Object** start_slot = HeapObject::RawField(
- map, Map::kPointerFieldsBeginOffset);
- Object** end_slot = HeapObject::RawField(
- map, Map::kPrototypeTransitionsOrBackPointerOffset);
- for (Object** slot = start_slot; slot < end_slot; slot++) {
- Object* obj = *slot;
- if (!obj->NonFailureIsHeapObject()) continue;
- mark_compact_collector()->RecordSlot(start_slot, slot, obj);
- base_marker()->MarkObjectAndPush(reinterpret_cast<HeapObject*>(obj));
- }
-}
-
-
-template <class T>
-void Marker<T>::MarkDescriptorArray(DescriptorArray* descriptors) {
- // Empty descriptor array is marked as a root before any maps are marked.
- ASSERT(descriptors != descriptors->GetHeap()->empty_descriptor_array());
-
- if (!base_marker()->MarkObjectWithoutPush(descriptors)) return;
- Object** descriptor_start = descriptors->data_start();
-
- // Since the descriptor array itself is not pushed for scanning, all fields
- // that point to objects manually have to be pushed, marked, and their slots
- // recorded.
- if (descriptors->HasEnumCache()) {
- Object** enum_cache_slot = descriptors->GetEnumCacheSlot();
- Object* enum_cache = *enum_cache_slot;
- base_marker()->MarkObjectAndPush(
- reinterpret_cast<HeapObject*>(enum_cache));
- mark_compact_collector()->RecordSlot(descriptor_start,
- enum_cache_slot,
- enum_cache);
- }
-
- // TODO(verwaest) Make sure we free unused transitions.
- if (descriptors->elements_transition_map() != NULL) {
- Object** transitions_slot = descriptors->GetTransitionsSlot();
- Object* transitions = *transitions_slot;
- base_marker()->MarkObjectAndPush(
- reinterpret_cast<HeapObject*>(transitions));
- mark_compact_collector()->RecordSlot(descriptor_start,
- transitions_slot,
- transitions);
- }
-
- // If the descriptor contains a transition (value is a Map), we don't mark the
- // value as live. It might be set to the NULL_DESCRIPTOR in
- // ClearNonLiveTransitions later.
- for (int i = 0; i < descriptors->number_of_descriptors(); ++i) {
- Object** key_slot = descriptors->GetKeySlot(i);
- Object* key = *key_slot;
- if (key->IsHeapObject()) {
- base_marker()->MarkObjectAndPush(reinterpret_cast<HeapObject*>(key));
- mark_compact_collector()->RecordSlot(descriptor_start, key_slot, key);
- }
-
- Object** value_slot = descriptors->GetValueSlot(i);
- if (!(*value_slot)->IsHeapObject()) continue;
- HeapObject* value = HeapObject::cast(*value_slot);
-
- mark_compact_collector()->RecordSlot(descriptor_start,
- value_slot,
- value);
-
- PropertyDetails details(descriptors->GetDetails(i));
-
- switch (details.type()) {
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case HANDLER:
- case INTERCEPTOR:
- base_marker()->MarkObjectAndPush(value);
- break;
- case CALLBACKS:
- if (!value->IsAccessorPair()) {
- base_marker()->MarkObjectAndPush(value);
- } else if (base_marker()->MarkObjectWithoutPush(value)) {
- AccessorPair* accessors = AccessorPair::cast(value);
- MarkAccessorPairSlot(accessors, AccessorPair::kGetterOffset);
- MarkAccessorPairSlot(accessors, AccessorPair::kSetterOffset);
- }
- break;
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
- break;
- }
- }
-}
-
-
-template <class T>
-void Marker<T>::MarkAccessorPairSlot(AccessorPair* accessors, int offset) {
- Object** slot = HeapObject::RawField(accessors, offset);
- HeapObject* accessor = HeapObject::cast(*slot);
- if (accessor->IsMap()) return;
- mark_compact_collector()->RecordSlot(slot, slot, accessor);
- base_marker()->MarkObjectAndPush(accessor);
-}
-
-
// Fill the marking stack with overflowed objects returned by the given
// iterator. Stop when the marking stack is filled or the end of the space
// is reached, whichever comes first.
@@ -2198,7 +1799,7 @@ void MarkCompactCollector::EmptyMarkingDeque() {
MarkBit map_mark = Marking::MarkBitFrom(map);
MarkObject(map, map_mark);
- StaticMarkingVisitor::IterateBody(map, object);
+ MarkCompactMarkingVisitor::IterateBody(map, object);
}
// Process encountered weak maps, mark objects only reachable by those
@@ -2295,7 +1896,7 @@ void MarkCompactCollector::MarkLiveObjects() {
// non-incremental marker can deal with them as if overflow
// occured during normal marking.
// But incremental marker uses a separate marking deque
- // so we have to explicitly copy it's overflow state.
+ // so we have to explicitly copy its overflow state.
incremental_marking->Finalize();
incremental_marking_overflowed =
incremental_marking->marking_deque()->overflowed();
@@ -2337,7 +1938,7 @@ void MarkCompactCollector::MarkLiveObjects() {
ASSERT(cell->IsJSGlobalPropertyCell());
if (IsMarked(cell)) {
int offset = JSGlobalPropertyCell::kValueOffset;
- StaticMarkingVisitor::VisitPointer(
+ MarkCompactMarkingVisitor::VisitPointer(
heap(),
reinterpret_cast<Object**>(cell->address() + offset));
}
@@ -2404,17 +2005,24 @@ void MarkCompactCollector::AfterMarking() {
// Flush code from collected candidates.
if (is_code_flushing_enabled()) {
code_flusher_->ProcessCandidates();
+ // TODO(1609) Currently incremental marker does not support code flushing,
+ // we need to disable it before incremental marking steps for next cycle.
+ EnableCodeFlushing(false);
}
if (!FLAG_watch_ic_patching) {
// Clean up dead objects from the runtime profiler.
heap()->isolate()->runtime_profiler()->RemoveDeadSamples();
}
+
+ if (FLAG_track_gc_object_stats) {
+ heap()->CheckpointObjectStats();
+ }
}
void MarkCompactCollector::ProcessMapCaches() {
- Object* raw_context = heap()->global_contexts_list_;
+ Object* raw_context = heap()->native_contexts_list_;
while (raw_context != heap()->undefined_value()) {
Context* context = reinterpret_cast<Context*>(raw_context);
if (IsMarked(context)) {
@@ -2514,7 +2122,7 @@ void MarkCompactCollector::ClearNonLiveTransitions() {
void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) {
int number_of_transitions = map->NumberOfProtoTransitions();
- FixedArray* prototype_transitions = map->prototype_transitions();
+ FixedArray* prototype_transitions = map->GetPrototypeTransitions();
int new_number_of_transitions = 0;
const int header = Map::kProtoTransitionHeaderSize;
@@ -2592,7 +2200,8 @@ void MarkCompactCollector::ProcessWeakMaps() {
Object** value_slot =
HeapObject::RawField(table, FixedArray::OffsetOfElementAt(
ObjectHashTable::EntryToValueIndex(i)));
- StaticMarkingVisitor::MarkObjectByPointer(this, anchor, value_slot);
+ MarkCompactMarkingVisitor::MarkObjectByPointer(
+ this, anchor, value_slot);
}
}
weak_map_obj = weak_map->next();
@@ -2706,15 +2315,23 @@ class PointersUpdatingVisitor: public ObjectVisitor {
void VisitEmbeddedPointer(RelocInfo* rinfo) {
ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
Object* target = rinfo->target_object();
+ Object* old_target = target;
VisitPointer(&target);
- rinfo->set_target_object(target);
+ // Avoid unnecessary changes that might unnecessary flush the instruction
+ // cache.
+ if (target != old_target) {
+ rinfo->set_target_object(target);
+ }
}
void VisitCodeTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
+ Object* old_target = target;
VisitPointer(&target);
- rinfo->set_target_address(Code::cast(target)->instruction_start());
+ if (target != old_target) {
+ rinfo->set_target_address(Code::cast(target)->instruction_start());
+ }
}
void VisitDebugTarget(RelocInfo* rinfo) {
@@ -3254,6 +2871,8 @@ void MarkCompactCollector::ProcessInvalidatedCode(ObjectVisitor* visitor) {
void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
+ Heap::RelocationLock relocation_lock(heap());
+
bool code_slots_filtering_required;
{ GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE);
code_slots_filtering_required = MarkInvalidatedCode();
@@ -3392,8 +3011,8 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
}
}
- // Update pointer from the global contexts list.
- updating_visitor.VisitPointer(heap_->global_contexts_list_address());
+ // Update pointer from the native contexts list.
+ updating_visitor.VisitPointer(heap_->native_contexts_list_address());
heap_->symbol_table()->Iterate(&updating_visitor);
@@ -3416,7 +3035,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
heap_->isolate()->inner_pointer_to_code_cache()->Flush();
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
VerifyEvacuation(heap_);
}
@@ -3991,7 +3610,8 @@ void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj,
void MarkCompactCollector::Initialize() {
- StaticMarkingVisitor::Initialize();
+ MarkCompactMarkingVisitor::Initialize();
+ IncrementalMarking::Initialize();
}
@@ -4067,6 +3687,20 @@ void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) {
}
+void MarkCompactCollector::RecordCodeTargetPatch(Address pc, Code* target) {
+ ASSERT(heap()->gc_state() == Heap::MARK_COMPACT);
+ if (is_compacting()) {
+ Code* host = heap()->isolate()->inner_pointer_to_code_cache()->
+ GcSafeFindCodeForInnerPointer(pc);
+ MarkBit mark_bit = Marking::MarkBitFrom(host);
+ if (Marking::IsBlack(mark_bit)) {
+ RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host);
+ RecordRelocSlot(&rinfo, target);
+ }
+ }
+}
+
+
static inline SlotsBuffer::SlotType DecodeSlotType(
SlotsBuffer::ObjectSlot slot) {
return static_cast<SlotsBuffer::SlotType>(reinterpret_cast<intptr_t>(slot));
diff --git a/deps/v8/src/mark-compact.h b/deps/v8/src/mark-compact.h
index dbc28697f..7c648000d 100644
--- a/deps/v8/src/mark-compact.h
+++ b/deps/v8/src/mark-compact.h
@@ -304,6 +304,26 @@ class SlotsBuffer {
NUMBER_OF_SLOT_TYPES
};
+ static const char* SlotTypeToString(SlotType type) {
+ switch (type) {
+ case EMBEDDED_OBJECT_SLOT:
+ return "EMBEDDED_OBJECT_SLOT";
+ case RELOCATED_CODE_OBJECT:
+ return "RELOCATED_CODE_OBJECT";
+ case CODE_TARGET_SLOT:
+ return "CODE_TARGET_SLOT";
+ case CODE_ENTRY_SLOT:
+ return "CODE_ENTRY_SLOT";
+ case DEBUG_TARGET_SLOT:
+ return "DEBUG_TARGET_SLOT";
+ case JS_RETURN_SLOT:
+ return "JS_RETURN_SLOT";
+ case NUMBER_OF_SLOT_TYPES:
+ return "NUMBER_OF_SLOT_TYPES";
+ }
+ return "UNKNOWN SlotType";
+ }
+
void UpdateSlots(Heap* heap);
void UpdateSlotsWithFilter(Heap* heap);
@@ -383,31 +403,77 @@ class SlotsBuffer {
};
-// -------------------------------------------------------------------------
-// Marker shared between incremental and non-incremental marking
-template<class BaseMarker> class Marker {
+// CodeFlusher collects candidates for code flushing during marking and
+// processes those candidates after marking has completed in order to
+// reset those functions referencing code objects that would otherwise
+// be unreachable. Code objects can be referenced in two ways:
+// - SharedFunctionInfo references unoptimized code.
+// - JSFunction references either unoptimized or optimized code.
+// We are not allowed to flush unoptimized code for functions that got
+// optimized or inlined into optimized code, because we might bailout
+// into the unoptimized code again during deoptimization.
+class CodeFlusher {
public:
- Marker(BaseMarker* base_marker, MarkCompactCollector* mark_compact_collector)
- : base_marker_(base_marker),
- mark_compact_collector_(mark_compact_collector) {}
+ explicit CodeFlusher(Isolate* isolate)
+ : isolate_(isolate),
+ jsfunction_candidates_head_(NULL),
+ shared_function_info_candidates_head_(NULL) {}
+
+ void AddCandidate(SharedFunctionInfo* shared_info) {
+ SetNextCandidate(shared_info, shared_function_info_candidates_head_);
+ shared_function_info_candidates_head_ = shared_info;
+ }
+
+ void AddCandidate(JSFunction* function) {
+ ASSERT(function->code() == function->shared()->code());
+ ASSERT(function->next_function_link()->IsUndefined());
+ SetNextCandidate(function, jsfunction_candidates_head_);
+ jsfunction_candidates_head_ = function;
+ }
- // Mark pointers in a Map and its DescriptorArray together, possibly
- // treating transitions or back pointers weak.
- void MarkMapContents(Map* map);
- void MarkDescriptorArray(DescriptorArray* descriptors);
- void MarkAccessorPairSlot(AccessorPair* accessors, int offset);
+ void ProcessCandidates() {
+ ProcessSharedFunctionInfoCandidates();
+ ProcessJSFunctionCandidates();
+ }
private:
- BaseMarker* base_marker() {
- return base_marker_;
+ void ProcessJSFunctionCandidates();
+ void ProcessSharedFunctionInfoCandidates();
+
+ static JSFunction* GetNextCandidate(JSFunction* candidate) {
+ Object* next_candidate = candidate->next_function_link();
+ return reinterpret_cast<JSFunction*>(next_candidate);
+ }
+
+ static void SetNextCandidate(JSFunction* candidate,
+ JSFunction* next_candidate) {
+ candidate->set_next_function_link(next_candidate);
+ }
+
+ static void ClearNextCandidate(JSFunction* candidate, Object* undefined) {
+ ASSERT(undefined->IsUndefined());
+ candidate->set_next_function_link(undefined, SKIP_WRITE_BARRIER);
}
- MarkCompactCollector* mark_compact_collector() {
- return mark_compact_collector_;
+ static SharedFunctionInfo* GetNextCandidate(SharedFunctionInfo* candidate) {
+ Object* next_candidate = candidate->code()->gc_metadata();
+ return reinterpret_cast<SharedFunctionInfo*>(next_candidate);
}
- BaseMarker* base_marker_;
- MarkCompactCollector* mark_compact_collector_;
+ static void SetNextCandidate(SharedFunctionInfo* candidate,
+ SharedFunctionInfo* next_candidate) {
+ candidate->code()->set_gc_metadata(next_candidate);
+ }
+
+ static void ClearNextCandidate(SharedFunctionInfo* candidate) {
+ candidate->code()->set_gc_metadata(NULL, SKIP_WRITE_BARRIER);
+ }
+
+ Isolate* isolate_;
+ JSFunction* jsfunction_candidates_head_;
+ SharedFunctionInfo* shared_function_info_candidates_head_;
+
+ DISALLOW_COPY_AND_ASSIGN(CodeFlusher);
};
@@ -505,7 +571,7 @@ class MarkCompactCollector {
PRECISE
};
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
void VerifyMarkbitsAreClean();
static void VerifyMarkbitsAreClean(PagedSpace* space);
static void VerifyMarkbitsAreClean(NewSpace* space);
@@ -553,6 +619,7 @@ class MarkCompactCollector {
void RecordRelocSlot(RelocInfo* rinfo, Object* target);
void RecordCodeEntrySlot(Address slot, Code* target);
+ void RecordCodeTargetPatch(Address pc, Code* target);
INLINE(void RecordSlot(Object** anchor_slot, Object** slot, Object* object));
@@ -612,8 +679,6 @@ class MarkCompactCollector {
bool was_marked_incrementally_;
- bool flush_monomorphic_ics_;
-
// A pointer to the current stack-allocated GC tracer object during a full
// collection (NULL before and after).
GCTracer* tracer_;
@@ -636,15 +701,9 @@ class MarkCompactCollector {
friend class RootMarkingVisitor;
friend class MarkingVisitor;
- friend class StaticMarkingVisitor;
+ friend class MarkCompactMarkingVisitor;
friend class CodeMarkingVisitor;
friend class SharedFunctionInfoMarkingVisitor;
- friend class Marker<IncrementalMarking>;
- friend class Marker<MarkCompactCollector>;
-
- // Mark non-optimize code for functions inlined into the given optimized
- // code. This will prevent it from being flushed.
- void MarkInlinedFunctionsCode(Code* code);
// Mark code objects that are active on the stack to prevent them
// from being flushed.
@@ -658,25 +717,13 @@ class MarkCompactCollector {
void AfterMarking();
// Marks the object black and pushes it on the marking stack.
- // Returns true if object needed marking and false otherwise.
- // This is for non-incremental marking only.
- INLINE(bool MarkObjectAndPush(HeapObject* obj));
-
- // Marks the object black and pushes it on the marking stack.
// This is for non-incremental marking only.
INLINE(void MarkObject(HeapObject* obj, MarkBit mark_bit));
- // Marks the object black without pushing it on the marking stack.
- // Returns true if object needed marking and false otherwise.
- // This is for non-incremental marking only.
- INLINE(bool MarkObjectWithoutPush(HeapObject* obj));
-
// Marks the object black assuming that it is not yet marked.
// This is for non-incremental marking only.
INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit));
- void ProcessNewlyMarkedObject(HeapObject* obj);
-
// Mark the heap roots and all objects reachable from them.
void MarkRoots(RootMarkingVisitor* visitor);
@@ -779,7 +826,6 @@ class MarkCompactCollector {
MarkingDeque marking_deque_;
CodeFlusher* code_flusher_;
Object* encountered_weak_maps_;
- Marker<MarkCompactCollector> marker_;
List<Page*> evacuation_candidates_;
List<Code*> invalidated_code_;
diff --git a/deps/v8/src/messages.cc b/deps/v8/src/messages.cc
index a0793c2df..23fd4fd5d 100644
--- a/deps/v8/src/messages.cc
+++ b/deps/v8/src/messages.cc
@@ -106,11 +106,20 @@ void MessageHandler::ReportMessage(Isolate* isolate,
// We are calling into embedder's code which can throw exceptions.
// Thus we need to save current exception state, reset it to the clean one
// and ignore scheduled exceptions callbacks can throw.
+
+ // We pass the exception object into the message handler callback though.
+ Object* exception_object = isolate->heap()->undefined_value();
+ if (isolate->has_pending_exception()) {
+ isolate->pending_exception()->ToObject(&exception_object);
+ }
+ Handle<Object> exception_handle(exception_object);
+
Isolate::ExceptionScope exception_scope(isolate);
isolate->clear_pending_exception();
isolate->set_external_caught_exception(false);
v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message);
+ v8::Local<v8::Value> api_exception_obj = v8::Utils::ToLocal(exception_handle);
v8::NeanderArray global_listeners(FACTORY->message_listeners());
int global_length = global_listeners.length();
@@ -123,15 +132,13 @@ void MessageHandler::ReportMessage(Isolate* isolate,
for (int i = 0; i < global_length; i++) {
HandleScope scope;
if (global_listeners.get(i)->IsUndefined()) continue;
- v8::NeanderObject listener(JSObject::cast(global_listeners.get(i)));
- Handle<Foreign> callback_obj(Foreign::cast(listener.get(0)));
+ Handle<Foreign> callback_obj(Foreign::cast(global_listeners.get(i)));
v8::MessageCallback callback =
FUNCTION_CAST<v8::MessageCallback>(callback_obj->foreign_address());
- Handle<Object> callback_data(listener.get(1));
{
// Do not allow exceptions to propagate.
v8::TryCatch try_catch;
- callback(api_message_obj, v8::Utils::ToLocal(callback_data));
+ callback(api_message_obj, api_exception_obj);
}
if (isolate->has_scheduled_exception()) {
isolate->clear_scheduled_exception();
diff --git a/deps/v8/src/messages.js b/deps/v8/src/messages.js
index 2a00ba846..fe894b578 100644
--- a/deps/v8/src/messages.js
+++ b/deps/v8/src/messages.js
@@ -50,7 +50,12 @@ function FormatString(format, message) {
try {
str = ToDetailString(args[arg_num]);
} catch (e) {
- str = "#<error>";
+ if (%IsJSModule(args[arg_num]))
+ str = "module";
+ else if (IS_SPEC_OBJECT(args[arg_num]))
+ str = "object";
+ else
+ str = "#<error>";
}
}
}
@@ -135,7 +140,7 @@ function FormatMessage(message) {
var messagesDictionary = [
// Error
"cyclic_proto", ["Cyclic __proto__ value"],
- "code_gen_from_strings", ["Code generation from strings disallowed for this context"],
+ "code_gen_from_strings", ["%0"],
// TypeError
"unexpected_token", ["Unexpected token ", "%0"],
"unexpected_token_number", ["Unexpected number"],
@@ -197,6 +202,7 @@ function FormatMessage(message) {
"proxy_non_object_prop_names", ["Trap '", "%1", "' returned non-object ", "%0"],
"proxy_repeated_prop_name", ["Trap '", "%1", "' returned repeated property name '", "%2", "'"],
"invalid_weakmap_key", ["Invalid value used as weak map key"],
+ "not_date_object", ["this is not a Date object."],
// RangeError
"invalid_array_length", ["Invalid array length"],
"stack_overflow", ["Maximum call stack size exceeded"],
@@ -223,7 +229,7 @@ function FormatMessage(message) {
"strict_catch_variable", ["Catch variable may not be eval or arguments in strict mode"],
"too_many_arguments", ["Too many arguments in function call (only 32766 allowed)"],
"too_many_parameters", ["Too many parameters in function definition (only 32766 allowed)"],
- "too_many_variables", ["Too many variables declared (only 32767 allowed)"],
+ "too_many_variables", ["Too many variables declared (only 131071 allowed)"],
"strict_param_name", ["Parameter name eval or arguments is not allowed in strict mode"],
"strict_param_dupe", ["Strict mode function may not have duplicate parameter names"],
"strict_var_name", ["Variable name may not be eval or arguments in strict mode"],
@@ -251,6 +257,7 @@ function FormatMessage(message) {
"harmony_const_assign", ["Assignment to constant variable."],
"invalid_module_path", ["Module does not export '", "%0", "', or export is not itself a module"],
"module_type_error", ["Module '", "%0", "' used improperly"],
+ "module_export_undefined", ["Export '", "%0", "' is not defined in module"],
];
var messages = { __proto__ : null };
for (var i = 0; i < messagesDictionary.length; i += 2) {
@@ -525,8 +532,8 @@ function ScriptLineCount() {
/**
- * Returns the name of script if available, contents of sourceURL comment
- * otherwise. See
+ * If sourceURL comment is available and script starts at zero returns sourceURL
+ * comment contents. Otherwise, script name is returned. See
* http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
* for details on using //@ sourceURL comment to identify scritps that don't
* have name.
@@ -535,14 +542,15 @@ function ScriptLineCount() {
* otherwise.
*/
function ScriptNameOrSourceURL() {
- if (this.name) {
+ if (this.line_offset > 0 || this.column_offset > 0) {
return this.name;
}
// The result is cached as on long scripts it takes noticable time to search
// for the sourceURL.
- if (this.hasCachedNameOrSourceURL)
- return this.cachedNameOrSourceURL;
+ if (this.hasCachedNameOrSourceURL) {
+ return this.cachedNameOrSourceURL;
+ }
this.hasCachedNameOrSourceURL = true;
// TODO(608): the spaces in a regexp below had to be escaped as \040
@@ -760,18 +768,18 @@ function DefineOneShotAccessor(obj, name, fun) {
// Note that the accessors consistently operate on 'obj', not 'this'.
// Since the object may occur in someone else's prototype chain we
// can't rely on 'this' being the same as 'obj'.
- var hasBeenSet = false;
var value;
+ var value_factory = fun;
var getter = function() {
- if (hasBeenSet) {
+ if (value_factory == null) {
return value;
}
- hasBeenSet = true;
- value = fun(obj);
+ value = value_factory(obj);
+ value_factory = null;
return value;
};
var setter = function(v) {
- hasBeenSet = true;
+ value_factory = null;
value = v;
};
%DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM);
@@ -853,9 +861,9 @@ function CallSiteGetMethodName() {
}
var name = null;
for (var prop in this.receiver) {
- if (this.receiver.__lookupGetter__(prop) === this.fun ||
- this.receiver.__lookupSetter__(prop) === this.fun ||
- (!this.receiver.__lookupGetter__(prop) &&
+ if (%_CallFunction(this.receiver, prop, ObjectLookupGetter) === this.fun ||
+ %_CallFunction(this.receiver, prop, ObjectLookupSetter) === this.fun ||
+ (!%_CallFunction(this.receiver, prop, ObjectLookupGetter) &&
this.receiver[prop] === this.fun)) {
// If we find more than one match bail out to avoid confusion.
if (name) {
@@ -921,17 +929,25 @@ function CallSiteToString() {
var fileLocation = "";
if (this.isNative()) {
fileLocation = "native";
- } else if (this.isEval()) {
- fileName = this.getScriptNameOrSourceURL();
- if (!fileName) {
- fileLocation = this.getEvalOrigin();
- }
} else {
- fileName = this.getFileName();
- }
+ if (this.isEval()) {
+ fileName = this.getScriptNameOrSourceURL();
+ if (!fileName) {
+ fileLocation = this.getEvalOrigin();
+ fileLocation += ", "; // Expecting source position to follow.
+ }
+ } else {
+ fileName = this.getFileName();
+ }
- if (fileName) {
- fileLocation += fileName;
+ if (fileName) {
+ fileLocation += fileName;
+ } else {
+ // Source code does not originate from a file and is not native, but we
+ // can still get the source position inside the source string, e.g. in
+ // an eval string.
+ fileLocation += "<anonymous>";
+ }
var lineNumber = this.getLineNumber();
if (lineNumber != null) {
fileLocation += ":" + lineNumber;
@@ -942,9 +958,6 @@ function CallSiteToString() {
}
}
- if (!fileLocation) {
- fileLocation = "unknown source";
- }
var line = "";
var functionName = this.getFunctionName();
var addSuffix = true;
diff --git a/deps/v8/src/mips/assembler-mips-inl.h b/deps/v8/src/mips/assembler-mips-inl.h
index 2ff4710ef..3e726a754 100644
--- a/deps/v8/src/mips/assembler-mips-inl.h
+++ b/deps/v8/src/mips/assembler-mips-inl.h
@@ -156,6 +156,11 @@ void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
}
+Address Assembler::target_address_from_return_address(Address pc) {
+ return pc - kCallTargetAddressOffset;
+}
+
+
Object* RelocInfo::target_object() {
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
return reinterpret_cast<Object*>(Assembler::target_address_at(pc_));
@@ -208,10 +213,7 @@ Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
JSGlobalPropertyCell* RelocInfo::target_cell() {
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
- Address address = Memory::Address_at(pc_);
- Object* object = HeapObject::FromAddress(
- address - JSGlobalPropertyCell::kValueOffset);
- return reinterpret_cast<JSGlobalPropertyCell*>(object);
+ return JSGlobalPropertyCell::FromValueAddress(Memory::Address_at(pc_));
}
diff --git a/deps/v8/src/mips/assembler-mips.cc b/deps/v8/src/mips/assembler-mips.cc
index f347fdc57..a4563a64f 100644
--- a/deps/v8/src/mips/assembler-mips.cc
+++ b/deps/v8/src/mips/assembler-mips.cc
@@ -273,6 +273,7 @@ static const int kMinimalBufferSize = 4 * KB;
Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
: AssemblerBase(arg_isolate),
+ recorded_ast_id_(TypeFeedbackId::None()),
positions_recorder_(this),
emit_debug_code_(FLAG_debug_code) {
if (buffer == NULL) {
@@ -579,17 +580,20 @@ bool Assembler::IsNop(Instr instr, unsigned int type) {
// See Assembler::nop(type).
ASSERT(type < 32);
uint32_t opcode = GetOpcodeField(instr);
+ uint32_t function = GetFunctionField(instr);
uint32_t rt = GetRt(instr);
- uint32_t rs = GetRs(instr);
+ uint32_t rd = GetRd(instr);
uint32_t sa = GetSa(instr);
- // nop(type) == sll(zero_reg, zero_reg, type);
- // Technically all these values will be 0 but
- // this makes more sense to the reader.
+ // Traditional mips nop == sll(zero_reg, zero_reg, 0)
+ // When marking non-zero type, use sll(zero_reg, at, type)
+ // to avoid use of mips ssnop and ehb special encodings
+ // of the sll instruction.
- bool ret = (opcode == SLL &&
- rt == static_cast<uint32_t>(ToNumber(zero_reg)) &&
- rs == static_cast<uint32_t>(ToNumber(zero_reg)) &&
+ Register nop_rt_reg = (type == 0) ? zero_reg : at;
+ bool ret = (opcode == SPECIAL && function == SLL &&
+ rd == static_cast<uint32_t>(ToNumber(zero_reg)) &&
+ rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) &&
sa == type);
return ret;
@@ -2046,7 +2050,10 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
}
ASSERT(buffer_space() >= kMaxRelocSize); // Too late to grow buffer here.
if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
- RelocInfo reloc_info_with_ast_id(pc_, rmode, RecordedAstId(), NULL);
+ RelocInfo reloc_info_with_ast_id(pc_,
+ rmode,
+ RecordedAstId().ToInt(),
+ NULL);
ClearRecordedAstId();
reloc_info_writer.Write(&reloc_info_with_ast_id);
} else {
diff --git a/deps/v8/src/mips/assembler-mips.h b/deps/v8/src/mips/assembler-mips.h
index 84714e507..59c45c927 100644
--- a/deps/v8/src/mips/assembler-mips.h
+++ b/deps/v8/src/mips/assembler-mips.h
@@ -318,12 +318,15 @@ const FPURegister f31 = { 31 };
// Register aliases.
// cp is assumed to be a callee saved register.
-static const Register& kLithiumScratchReg = s3; // Scratch register.
-static const Register& kLithiumScratchReg2 = s4; // Scratch register.
-static const Register& kRootRegister = s6; // Roots array pointer.
-static const Register& cp = s7; // JavaScript context pointer.
-static const DoubleRegister& kLithiumScratchDouble = f30;
-static const FPURegister& kDoubleRegZero = f28;
+// Defined using #define instead of "static const Register&" because Clang
+// complains otherwise when a compilation unit that includes this header
+// doesn't use the variables.
+#define kRootRegister s6
+#define cp s7
+#define kLithiumScratchReg s3
+#define kLithiumScratchReg2 s4
+#define kLithiumScratchDouble f30
+#define kDoubleRegZero f28
// FPU (coprocessor 1) control registers.
// Currently only FCSR (#31) is implemented.
@@ -525,6 +528,9 @@ class Assembler : public AssemblerBase {
// Overrides the default provided by FLAG_debug_code.
void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
+ // Dummy for cross platform compatibility.
+ void set_predictable_code_size(bool value) { }
+
// GetCode emits any pending (non-emitted) code and fills the descriptor
// desc. GetCode() is idempotent; it returns the same result if no other
// Assembler functions are invoked in between GetCode() calls.
@@ -568,6 +574,10 @@ class Assembler : public AssemblerBase {
static Address target_address_at(Address pc);
static void set_target_address_at(Address pc, Address target);
+ // Return the code target address at a call site from the return address
+ // of that call in the instruction stream.
+ inline static Address target_address_from_return_address(Address pc);
+
static void JumpLabelToJumpRegister(Address pc);
static void QuietNaN(HeapObject* nan);
@@ -628,6 +638,8 @@ class Assembler : public AssemblerBase {
// register.
static const int kPcLoadDelta = 4;
+ static const int kPatchDebugBreakSlotReturnOffset = 4 * kInstrSize;
+
// Number of instructions used for the JS return sequence. The constant is
// used by the debugger to patch the JS return sequence.
static const int kJSReturnSequenceInstructions = 7;
@@ -660,10 +672,13 @@ class Assembler : public AssemblerBase {
FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
};
- // Type == 0 is the default non-marking type.
+ // Type == 0 is the default non-marking nop. For mips this is a
+ // sll(zero_reg, zero_reg, 0). We use rt_reg == at for non-zero
+ // marking, to avoid conflict with ssnop and ehb instructions.
void nop(unsigned int type = 0) {
ASSERT(type < 32);
- sll(zero_reg, zero_reg, type, true);
+ Register nop_rt_reg = (type == 0) ? zero_reg : at;
+ sll(zero_reg, nop_rt_reg, type, true);
}
@@ -909,17 +924,17 @@ class Assembler : public AssemblerBase {
// Record the AST id of the CallIC being compiled, so that it can be placed
// in the relocation information.
- void SetRecordedAstId(unsigned ast_id) {
- ASSERT(recorded_ast_id_ == kNoASTId);
+ void SetRecordedAstId(TypeFeedbackId ast_id) {
+ ASSERT(recorded_ast_id_.IsNone());
recorded_ast_id_ = ast_id;
}
- unsigned RecordedAstId() {
- ASSERT(recorded_ast_id_ != kNoASTId);
+ TypeFeedbackId RecordedAstId() {
+ ASSERT(!recorded_ast_id_.IsNone());
return recorded_ast_id_;
}
- void ClearRecordedAstId() { recorded_ast_id_ = kNoASTId; }
+ void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
// Record a comment relocation entry that can be used by a disassembler.
// Use --code-comments to enable.
@@ -1016,7 +1031,7 @@ class Assembler : public AssemblerBase {
// Relocation for a type-recording IC has the AST id added to it. This
// member variable is a way to pass the information from the call site to
// the relocation info.
- unsigned recorded_ast_id_;
+ TypeFeedbackId recorded_ast_id_;
bool emit_debug_code() const { return emit_debug_code_; }
diff --git a/deps/v8/src/mips/builtins-mips.cc b/deps/v8/src/mips/builtins-mips.cc
index 5a2074e65..0342e6505 100644
--- a/deps/v8/src/mips/builtins-mips.cc
+++ b/deps/v8/src/mips/builtins-mips.cc
@@ -79,12 +79,13 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
// Load the built-in InternalArray function from the current context.
static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
Register result) {
- // Load the global context.
+ // Load the native context.
- __ lw(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ lw(result,
- FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
- // Load the InternalArray function from the global context.
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ lw(result,
+ FieldMemOperand(result, GlobalObject::kNativeContextOffset));
+ // Load the InternalArray function from the native context.
__ lw(result,
MemOperand(result,
Context::SlotOffset(
@@ -94,12 +95,13 @@ static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
// Load the built-in Array function from the current context.
static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
- // Load the global context.
+ // Load the native context.
- __ lw(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ lw(result,
- FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
- // Load the Array function from the global context.
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ lw(result,
+ FieldMemOperand(result, GlobalObject::kNativeContextOffset));
+ // Load the Array function from the native context.
__ lw(result,
MemOperand(result,
Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
@@ -713,6 +715,43 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
}
+static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
+ __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
+ __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset));
+ __ Addu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag));
+ __ Jump(at);
+}
+
+
+void Builtins::Generate_InRecompileQueue(MacroAssembler* masm) {
+ GenerateTailCallToSharedCode(masm);
+}
+
+
+void Builtins::Generate_ParallelRecompile(MacroAssembler* masm) {
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ // Push a copy of the function onto the stack.
+ __ push(a1);
+ // Push call kind information.
+ __ push(t1);
+
+ __ push(a1); // Function is also the parameter to the runtime call.
+ __ CallRuntime(Runtime::kParallelRecompile, 1);
+
+ // Restore call kind information.
+ __ pop(t1);
+ // Restore receiver.
+ __ pop(a1);
+
+ // Tear down internal frame.
+ }
+
+ GenerateTailCallToSharedCode(masm);
+}
+
+
static void Generate_JSConstructStubHelper(MacroAssembler* masm,
bool is_api_function,
bool count_constructions) {
@@ -1393,9 +1432,9 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// receiver.
__ bind(&use_global_receiver);
const int kGlobalIndex =
- Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
__ lw(a2, FieldMemOperand(cp, kGlobalIndex));
- __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalContextOffset));
+ __ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset));
__ lw(a2, FieldMemOperand(a2, kGlobalIndex));
__ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
@@ -1586,9 +1625,9 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Use the current global receiver object as the receiver.
__ bind(&use_global_receiver);
const int kGlobalOffset =
- Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
__ lw(a0, FieldMemOperand(cp, kGlobalOffset));
- __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalContextOffset));
+ __ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset));
__ lw(a0, FieldMemOperand(a0, kGlobalOffset));
__ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
diff --git a/deps/v8/src/mips/code-stubs-mips.cc b/deps/v8/src/mips/code-stubs-mips.cc
index 22e1e3553..ca3182645 100644
--- a/deps/v8/src/mips/code-stubs-mips.cc
+++ b/deps/v8/src/mips/code-stubs-mips.cc
@@ -87,6 +87,8 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
void FastNewClosureStub::Generate(MacroAssembler* masm) {
// Create a new closure from the given function info in new
// space. Set the context to the current context in cp.
+ Counters* counters = masm->isolate()->counters();
+
Label gc;
// Pop the function info from the stack.
@@ -100,32 +102,44 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) {
&gc,
TAG_OBJECT);
+ __ IncrementCounter(counters->fast_new_closure_total(), 1, t2, t3);
+
int map_index = (language_mode_ == CLASSIC_MODE)
? Context::FUNCTION_MAP_INDEX
: Context::STRICT_MODE_FUNCTION_MAP_INDEX;
- // Compute the function map in the current global context and set that
+ // Compute the function map in the current native context and set that
// as the map of the allocated object.
- __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalContextOffset));
- __ lw(a2, MemOperand(a2, Context::SlotOffset(map_index)));
- __ sw(a2, FieldMemOperand(v0, HeapObject::kMapOffset));
+ __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset));
+ __ lw(t1, MemOperand(a2, Context::SlotOffset(map_index)));
+ __ sw(t1, FieldMemOperand(v0, HeapObject::kMapOffset));
// Initialize the rest of the function. We don't have to update the
// write barrier because the allocated object is in new space.
__ LoadRoot(a1, Heap::kEmptyFixedArrayRootIndex);
- __ LoadRoot(a2, Heap::kTheHoleValueRootIndex);
- __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
+ __ LoadRoot(t1, Heap::kTheHoleValueRootIndex);
__ sw(a1, FieldMemOperand(v0, JSObject::kPropertiesOffset));
__ sw(a1, FieldMemOperand(v0, JSObject::kElementsOffset));
- __ sw(a2, FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
+ __ sw(t1, FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
__ sw(a3, FieldMemOperand(v0, JSFunction::kSharedFunctionInfoOffset));
__ sw(cp, FieldMemOperand(v0, JSFunction::kContextOffset));
__ sw(a1, FieldMemOperand(v0, JSFunction::kLiteralsOffset));
- __ sw(t0, FieldMemOperand(v0, JSFunction::kNextFunctionLinkOffset));
// Initialize the code pointer in the function to be the one
// found in the shared function info object.
+ // But first check if there is an optimized version for our context.
+ Label check_optimized;
+ Label install_unoptimized;
+ if (FLAG_cache_optimized_code) {
+ __ lw(a1,
+ FieldMemOperand(a3, SharedFunctionInfo::kOptimizedCodeMapOffset));
+ __ And(at, a1, a1);
+ __ Branch(&check_optimized, ne, at, Operand(zero_reg));
+ }
+ __ bind(&install_unoptimized);
+ __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
+ __ sw(t0, FieldMemOperand(v0, JSFunction::kNextFunctionLinkOffset));
__ lw(a3, FieldMemOperand(a3, SharedFunctionInfo::kCodeOffset));
__ Addu(a3, a3, Operand(Code::kHeaderSize - kHeapObjectTag));
@@ -133,6 +147,72 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) {
__ sw(a3, FieldMemOperand(v0, JSFunction::kCodeEntryOffset));
__ Ret();
+ __ bind(&check_optimized);
+
+ __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1, t2, t3);
+
+ // a2 holds native context, a1 points to fixed array of 3-element entries
+ // (native context, optimized code, literals).
+ // The optimized code map must never be empty, so check the first elements.
+ Label install_optimized;
+ // Speculatively move code object into t0.
+ __ lw(t0, FieldMemOperand(a1, FixedArray::kHeaderSize + kPointerSize));
+ __ lw(t1, FieldMemOperand(a1, FixedArray::kHeaderSize));
+ __ Branch(&install_optimized, eq, a2, Operand(t1));
+
+ // Iterate through the rest of map backwards. t0 holds an index as a Smi.
+ Label loop;
+ __ lw(t0, FieldMemOperand(a1, FixedArray::kLengthOffset));
+ __ bind(&loop);
+ // Do not double check first entry.
+
+ __ Branch(&install_unoptimized, eq, t0,
+ Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
+ __ Subu(t0, t0, Operand(
+ Smi::FromInt(SharedFunctionInfo::kEntryLength))); // Skip an entry.
+ __ Addu(t1, a1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ sll(at, t0, kPointerSizeLog2 - kSmiTagSize);
+ __ Addu(t1, t1, Operand(at));
+ __ lw(t1, MemOperand(t1));
+ __ Branch(&loop, ne, a2, Operand(t1));
+ // Hit: fetch the optimized code.
+ __ Addu(t1, a1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ sll(at, t0, kPointerSizeLog2 - kSmiTagSize);
+ __ Addu(t1, t1, Operand(at));
+ __ Addu(t1, t1, Operand(kPointerSize));
+ __ lw(t0, MemOperand(t1));
+
+ __ bind(&install_optimized);
+ __ IncrementCounter(counters->fast_new_closure_install_optimized(),
+ 1, t2, t3);
+
+ // TODO(fschneider): Idea: store proper code pointers in the map and either
+ // unmangle them on marking or do nothing as the whole map is discarded on
+ // major GC anyway.
+ __ Addu(t0, t0, Operand(Code::kHeaderSize - kHeapObjectTag));
+ __ sw(t0, FieldMemOperand(v0, JSFunction::kCodeEntryOffset));
+
+ // Now link a function into a list of optimized functions.
+ __ lw(t0, ContextOperand(a2, Context::OPTIMIZED_FUNCTIONS_LIST));
+
+ __ sw(t0, FieldMemOperand(v0, JSFunction::kNextFunctionLinkOffset));
+ // No need for write barrier as JSFunction (eax) is in the new space.
+
+ __ sw(v0, ContextOperand(a2, Context::OPTIMIZED_FUNCTIONS_LIST));
+ // Store JSFunction (eax) into edx before issuing write barrier as
+ // it clobbers all the registers passed.
+ __ mov(t0, v0);
+ __ RecordWriteContextSlot(
+ a2,
+ Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
+ t0,
+ a1,
+ kRAHasNotBeenSaved,
+ kDontSaveFPRegs);
+
+ // Return result. The argument function info has been popped already.
+ __ Ret();
+
// Create a new closure through the slower runtime call.
__ bind(&gc);
__ LoadRoot(t0, Heap::kFalseValueRootIndex);
@@ -164,12 +244,12 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
__ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
// Set up the fixed slots, copy the global object from the previous context.
- __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ li(a1, Operand(Smi::FromInt(0)));
__ sw(a3, MemOperand(v0, Context::SlotOffset(Context::CLOSURE_INDEX)));
__ sw(cp, MemOperand(v0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
__ sw(a1, MemOperand(v0, Context::SlotOffset(Context::EXTENSION_INDEX)));
- __ sw(a2, MemOperand(v0, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ sw(a2, MemOperand(v0, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
// Initialize the rest of the slots to undefined.
__ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
@@ -211,9 +291,9 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ li(a2, Operand(Smi::FromInt(length)));
__ sw(a2, FieldMemOperand(v0, FixedArray::kLengthOffset));
- // If this block context is nested in the global context we get a smi
+ // If this block context is nested in the native context we get a smi
// sentinel instead of a function. The block context should get the
- // canonical empty function of the global context as its closure which
+ // canonical empty function of the native context as its closure which
// we still have to look up.
Label after_sentinel;
__ JumpIfNotSmi(a3, &after_sentinel);
@@ -222,16 +302,16 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ Assert(eq, message, a3, Operand(zero_reg));
}
__ lw(a3, GlobalObjectOperand());
- __ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalContextOffset));
+ __ lw(a3, FieldMemOperand(a3, GlobalObject::kNativeContextOffset));
__ lw(a3, ContextOperand(a3, Context::CLOSURE_INDEX));
__ bind(&after_sentinel);
// Set up the fixed slots, copy the global object from the previous context.
- __ lw(a2, ContextOperand(cp, Context::GLOBAL_INDEX));
+ __ lw(a2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
__ sw(a3, ContextOperand(v0, Context::CLOSURE_INDEX));
__ sw(cp, ContextOperand(v0, Context::PREVIOUS_INDEX));
__ sw(a1, ContextOperand(v0, Context::EXTENSION_INDEX));
- __ sw(a2, ContextOperand(v0, Context::GLOBAL_INDEX));
+ __ sw(a2, ContextOperand(v0, Context::GLOBAL_OBJECT_INDEX));
// Initialize the rest of the slots to the hole value.
__ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
@@ -575,11 +655,9 @@ void FloatingPointHelper::LoadNumber(MacroAssembler* masm,
Register scratch1,
Register scratch2,
Label* not_number) {
- if (FLAG_debug_code) {
- __ AbortIfNotRootValue(heap_number_map,
- Heap::kHeapNumberMapRootIndex,
- "HeapNumberMap register clobbered.");
- }
+ __ AssertRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
Label is_smi, done;
@@ -641,11 +719,9 @@ void FloatingPointHelper::ConvertNumberToInt32(MacroAssembler* masm,
Register scratch3,
FPURegister double_scratch,
Label* not_number) {
- if (FLAG_debug_code) {
- __ AbortIfNotRootValue(heap_number_map,
- Heap::kHeapNumberMapRootIndex,
- "HeapNumberMap register clobbered.");
- }
+ __ AssertRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
Label done;
Label not_in_int32_range;
@@ -781,11 +857,9 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
__ Branch(&done);
__ bind(&obj_is_not_smi);
- if (FLAG_debug_code) {
- __ AbortIfNotRootValue(heap_number_map,
- Heap::kHeapNumberMapRootIndex,
- "HeapNumberMap register clobbered.");
- }
+ __ AssertRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
__ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
// Load the number.
@@ -852,11 +926,9 @@ void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
__ UntagAndJumpIfSmi(dst, object, &done);
- if (FLAG_debug_code) {
- __ AbortIfNotRootValue(heap_number_map,
- Heap::kHeapNumberMapRootIndex,
- "HeapNumberMap register clobbered.");
- }
+ __ AssertRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
__ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
// Object is a heap number.
@@ -2539,9 +2611,9 @@ void BinaryOpStub::GenerateFPOperation(MacroAssembler* masm,
Register scratch3 = t0;
ASSERT(smi_operands || (not_numbers != NULL));
- if (smi_operands && FLAG_debug_code) {
- __ AbortIfNotSmi(left);
- __ AbortIfNotSmi(right);
+ if (smi_operands) {
+ __ AssertSmi(left);
+ __ AssertSmi(right);
}
Register heap_number_map = t2;
@@ -4566,14 +4638,14 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
// v0 = address of new object(s) (tagged)
// a2 = argument count (tagged)
- // Get the arguments boilerplate from the current (global) context into t0.
+ // Get the arguments boilerplate from the current native context into t0.
const int kNormalOffset =
Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
const int kAliasedOffset =
Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX);
- __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ lw(t0, FieldMemOperand(t0, GlobalObject::kGlobalContextOffset));
+ __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset));
Label skip2_ne, skip2_eq;
__ Branch(&skip2_ne, ne, a1, Operand(zero_reg));
__ lw(t0, MemOperand(t0, kNormalOffset));
@@ -4761,9 +4833,9 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
static_cast<AllocationFlags>(TAG_OBJECT |
SIZE_IN_WORDS));
- // Get the arguments boilerplate from the current (global) context.
- __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ lw(t0, FieldMemOperand(t0, GlobalObject::kGlobalContextOffset));
+ // Get the arguments boilerplate from the current native context.
+ __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset));
__ lw(t0, MemOperand(t0, Context::SlotOffset(
Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
@@ -4897,7 +4969,8 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
__ Addu(a2, a2, Operand(2)); // a2 was a smi.
// Check that the static offsets vector buffer is large enough.
- __ Branch(&runtime, hi, a2, Operand(OffsetsVector::kStaticOffsetsVectorSize));
+ __ Branch(
+ &runtime, hi, a2, Operand(Isolate::kJSRegexpStaticOffsetsVectorSize));
// a2: Number of capture registers
// regexp_data: RegExp data (FixedArray)
@@ -5296,10 +5369,10 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
// Set empty properties FixedArray.
// Set elements to point to FixedArray allocated right after the JSArray.
// Interleave operations for better latency.
- __ lw(a2, ContextOperand(cp, Context::GLOBAL_INDEX));
+ __ lw(a2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
__ Addu(a3, v0, Operand(JSRegExpResult::kSize));
__ li(t0, Operand(masm->isolate()->factory()->empty_fixed_array()));
- __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalContextOffset));
+ __ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset));
__ sw(a3, FieldMemOperand(v0, JSObject::kElementsOffset));
__ lw(a2, ContextOperand(a2, Context::REGEXP_RESULT_MAP_INDEX));
__ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset));
@@ -5324,12 +5397,12 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
// Set FixedArray length.
__ sll(t2, t1, kSmiTagSize);
__ sw(t2, FieldMemOperand(a3, FixedArray::kLengthOffset));
- // Fill contents of fixed-array with the-hole.
- __ li(a2, Operand(masm->isolate()->factory()->the_hole_value()));
+ // Fill contents of fixed-array with undefined.
+ __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
__ Addu(a3, a3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- // Fill fixed array elements with hole.
+ // Fill fixed array elements with undefined.
// v0: JSArray, tagged.
- // a2: the hole.
+ // a2: undefined.
// a3: Start of elements in FixedArray.
// t1: Number of elements to fill.
Label loop;
@@ -5408,7 +5481,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
__ Branch(&call, ne, t0, Operand(at));
// Patch the receiver on the stack with the global receiver object.
- __ lw(a3, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ lw(a3,
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset));
__ sw(a3, MemOperand(sp, argc_ * kPointerSize));
__ bind(&call);
@@ -7183,8 +7257,7 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
ASSERT(!name.is(scratch1));
ASSERT(!name.is(scratch2));
- // Assert that name contains a string.
- if (FLAG_debug_code) __ AbortIfNotString(name);
+ __ AssertString(name);
// Compute the capacity mask.
__ lw(scratch1, FieldMemOperand(elements, kCapacityOffset));
@@ -7380,6 +7453,8 @@ static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
{ REG(a2), REG(t2), REG(t5), EMIT_REMEMBERED_SET },
// StoreArrayLiteralElementStub::Generate
{ REG(t1), REG(a0), REG(t2), EMIT_REMEMBERED_SET },
+ // FastNewClosureStub::Generate
+ { REG(a2), REG(t0), REG(a1), EMIT_REMEMBERED_SET },
// Null termination.
{ REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET}
};
@@ -7428,6 +7503,11 @@ void RecordWriteStub::GenerateFixedRegStubsAheadOfTime() {
}
+bool CodeStub::CanUseFPRegisters() {
+ return CpuFeatures::IsSupported(FPU);
+}
+
+
// Takes the input in 3 registers: address_ value_ and object_. A pointer to
// the value has just been written into the object, now this stub makes sure
// we keep the GC informed. The word in the object where the value has been
@@ -7553,6 +7633,16 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
Label need_incremental;
Label need_incremental_pop_scratch;
+ __ And(regs_.scratch0(), regs_.object(), Operand(~Page::kPageAlignmentMask));
+ __ lw(regs_.scratch1(),
+ MemOperand(regs_.scratch0(),
+ MemoryChunk::kWriteBarrierCounterOffset));
+ __ Subu(regs_.scratch1(), regs_.scratch1(), Operand(1));
+ __ sw(regs_.scratch1(),
+ MemOperand(regs_.scratch0(),
+ MemoryChunk::kWriteBarrierCounterOffset));
+ __ Branch(&need_incremental, lt, regs_.scratch1(), Operand(zero_reg));
+
// Let's look at the color of the object: If it is not black we don't have
// to inform the incremental marker.
__ JumpIfBlack(regs_.object(), regs_.scratch0(), regs_.scratch1(), &on_black);
@@ -7677,13 +7767,75 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
// Array literal has ElementsKind of FAST_*_DOUBLE_ELEMENTS.
__ bind(&double_elements);
__ lw(t1, FieldMemOperand(a1, JSObject::kElementsOffset));
- __ StoreNumberToDoubleElements(a0, a3, a1, t1, t2, t3, t5, a2,
+ __ StoreNumberToDoubleElements(a0, a3, a1,
+ // Overwrites all regs after this.
+ t1, t2, t3, t5, a2,
&slow_elements);
__ Ret(USE_DELAY_SLOT);
__ mov(v0, a0);
}
+void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
+ if (entry_hook_ != NULL) {
+ ProfileEntryHookStub stub;
+ __ push(ra);
+ __ CallStub(&stub);
+ __ pop(ra);
+ }
+}
+
+
+void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
+ // The entry hook is a "push ra" instruction, followed by a call.
+ // Note: on MIPS "push" is 2 instruction
+ const int32_t kReturnAddressDistanceFromFunctionStart =
+ Assembler::kCallTargetAddressOffset + (2 * Assembler::kInstrSize);
+
+ // Save live volatile registers.
+ __ Push(ra, t1, a1);
+ const int32_t kNumSavedRegs = 3;
+
+ // Compute the function's address for the first argument.
+ __ Subu(a0, ra, Operand(kReturnAddressDistanceFromFunctionStart));
+
+ // The caller's return address is above the saved temporaries.
+ // Grab that for the second argument to the hook.
+ __ Addu(a1, sp, Operand(kNumSavedRegs * kPointerSize));
+
+ // Align the stack if necessary.
+ int frame_alignment = masm->ActivationFrameAlignment();
+ if (frame_alignment > kPointerSize) {
+ __ mov(t1, sp);
+ ASSERT(IsPowerOf2(frame_alignment));
+ __ And(sp, sp, Operand(-frame_alignment));
+ }
+
+#if defined(V8_HOST_ARCH_MIPS)
+ __ li(at, Operand(reinterpret_cast<int32_t>(&entry_hook_)));
+ __ lw(at, MemOperand(at));
+#else
+ // Under the simulator we need to indirect the entry hook through a
+ // trampoline function at a known address.
+ Address trampoline_address = reinterpret_cast<Address>(
+ reinterpret_cast<intptr_t>(EntryHookTrampoline));
+ ApiFunction dispatcher(trampoline_address);
+ __ li(at, Operand(ExternalReference(&dispatcher,
+ ExternalReference::BUILTIN_CALL,
+ masm->isolate())));
+#endif
+ __ Call(at);
+
+ // Restore the stack pointer if needed.
+ if (frame_alignment > kPointerSize) {
+ __ mov(sp, t1);
+ }
+
+ __ Pop(ra, t1, a1);
+ __ Ret();
+}
+
+
#undef __
} } // namespace v8::internal
diff --git a/deps/v8/src/mips/deoptimizer-mips.cc b/deps/v8/src/mips/deoptimizer-mips.cc
index 62f3155eb..9fd815bb4 100644
--- a/deps/v8/src/mips/deoptimizer-mips.cc
+++ b/deps/v8/src/mips/deoptimizer-mips.cc
@@ -48,6 +48,10 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
if (!function->IsOptimized()) return;
+ // The optimized code is going to be patched, so we cannot use it
+ // any more. Play safe and reset the whole cache.
+ function->shared()->ClearOptimizedCodeMap();
+
// Get the optimized code.
Code* code = function->code();
Address code_start_address = code->instruction_start();
@@ -96,8 +100,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
// ignore all slots that might have been recorded on it.
isolate->heap()->mark_compact_collector()->InvalidateCode(code);
- // Set the code for the function to non-optimized version.
- function->ReplaceCode(function->shared()->code());
+ ReplaceCodeForRelatedFunctions(function, code);
if (FLAG_trace_deopt) {
PrintF("[forced deoptimization: ");
@@ -186,11 +189,11 @@ void Deoptimizer::RevertStackCheckCodeAt(Code* unoptimized_code,
}
-static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) {
+static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) {
ByteArray* translations = data->TranslationByteArray();
int length = data->DeoptCount();
for (int i = 0; i < length; i++) {
- if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) {
+ if (data->AstId(i) == ast_id) {
TranslationIterator it(translations, data->TranslationIndex(i)->value());
int value = it.Next();
ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value));
@@ -209,7 +212,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
optimized_code_->deoptimization_data());
unsigned ast_id = data->OsrAstId()->value();
- int bailout_id = LookupBailoutId(data, ast_id);
+ int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
unsigned translation_index = data->TranslationIndex(bailout_id)->value();
ByteArray* translations = data->TranslationByteArray();
@@ -229,9 +232,9 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
unsigned node_id = iterator.Next();
USE(node_id);
ASSERT(node_id == ast_id);
- JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next()));
- USE(function);
- ASSERT(function == function_);
+ int closure_id = iterator.Next();
+ USE(closure_id);
+ ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
unsigned height = iterator.Next();
unsigned height_in_bytes = height * kPointerSize;
USE(height_in_bytes);
@@ -342,8 +345,8 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
if (FLAG_trace_osr) {
PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
ok ? "finished" : "aborted",
- reinterpret_cast<intptr_t>(function));
- function->PrintName();
+ reinterpret_cast<intptr_t>(function_));
+ function_->PrintName();
PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
}
}
@@ -567,19 +570,145 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
}
+void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
+ int frame_index,
+ bool is_setter_stub_frame) {
+ JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ // The receiver (and the implicit return value, if any) are expected in
+ // registers by the LoadIC/StoreIC, so they don't belong to the output stack
+ // frame. This means that we have to use a height of 0.
+ unsigned height = 0;
+ unsigned height_in_bytes = height * kPointerSize;
+ const char* kind = is_setter_stub_frame ? "setter" : "getter";
+ if (FLAG_trace_deopt) {
+ PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes);
+ }
+
+ // We need 5 stack entries from StackFrame::INTERNAL (ra, fp, cp, frame type,
+ // code object, see MacroAssembler::EnterFrame). For a setter stub frame we
+ // need one additional entry for the implicit return value, see
+ // StoreStubCompiler::CompileStoreViaSetter.
+ unsigned fixed_frame_entries = 5 + (is_setter_stub_frame ? 1 : 0);
+ unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
+ unsigned output_frame_size = height_in_bytes + fixed_frame_size;
+
+ // Allocate and store the output frame description.
+ FrameDescription* output_frame =
+ new(output_frame_size) FrameDescription(output_frame_size, accessor);
+ output_frame->SetFrameType(StackFrame::INTERNAL);
+
+ // A frame for an accessor stub can not be the topmost or bottommost one.
+ ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
+ ASSERT(output_[frame_index] == NULL);
+ output_[frame_index] = output_frame;
+
+ // The top address of the frame is computed from the previous frame's top and
+ // this frame's size.
+ uint32_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
+ output_frame->SetTop(top_address);
+
+ unsigned output_offset = output_frame_size;
+
+ // Read caller's PC from the previous frame.
+ output_offset -= kPointerSize;
+ intptr_t value = output_[frame_index - 1]->GetPc();
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; caller's pc\n",
+ top_address + output_offset, output_offset, value);
+ }
+
+ // Read caller's FP from the previous frame, and set this frame's FP.
+ output_offset -= kPointerSize;
+ value = output_[frame_index - 1]->GetFp();
+ output_frame->SetFrameSlot(output_offset, value);
+ intptr_t fp_value = top_address + output_offset;
+ output_frame->SetFp(fp_value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; caller's fp\n",
+ fp_value, output_offset, value);
+ }
+
+ // The context can be gotten from the previous frame.
+ output_offset -= kPointerSize;
+ value = output_[frame_index - 1]->GetContext();
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; context\n",
+ top_address + output_offset, output_offset, value);
+ }
+
+ // A marker value is used in place of the function.
+ output_offset -= kPointerSize;
+ value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; function (%s sentinel)\n",
+ top_address + output_offset, output_offset, value, kind);
+ }
+
+ // Get Code object from accessor stub.
+ output_offset -= kPointerSize;
+ Builtins::Name name = is_setter_stub_frame ?
+ Builtins::kStoreIC_Setter_ForDeopt :
+ Builtins::kLoadIC_Getter_ForDeopt;
+ Code* accessor_stub = isolate_->builtins()->builtin(name);
+ value = reinterpret_cast<intptr_t>(accessor_stub);
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; code object\n",
+ top_address + output_offset, output_offset, value);
+ }
+
+ // Skip receiver.
+ Translation::Opcode opcode =
+ static_cast<Translation::Opcode>(iterator->Next());
+ iterator->Skip(Translation::NumberOfOperandsFor(opcode));
+
+ if (is_setter_stub_frame) {
+ // The implicit return value was part of the artificial setter stub
+ // environment.
+ output_offset -= kPointerSize;
+ DoTranslateCommand(iterator, frame_index, output_offset);
+ }
+
+ ASSERT(0 == output_offset);
+
+ Smi* offset = is_setter_stub_frame ?
+ isolate_->heap()->setter_stub_deopt_pc_offset() :
+ isolate_->heap()->getter_stub_deopt_pc_offset();
+ intptr_t pc = reinterpret_cast<intptr_t>(
+ accessor_stub->instruction_start() + offset->value());
+ output_frame->SetPc(pc);
+}
+
+
// This code is very similar to ia32/arm code, but relies on register names
// (fp, sp) and how the frame is laid out.
void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
int frame_index) {
// Read the ast node id, function, and frame height for this output frame.
- int node_id = iterator->Next();
- JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ BailoutId node_id = BailoutId(iterator->Next());
+ JSFunction* function;
+ if (frame_index != 0) {
+ function = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ } else {
+ int closure_id = iterator->Next();
+ USE(closure_id);
+ ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
+ function = function_;
+ }
unsigned height = iterator->Next();
unsigned height_in_bytes = height * kPointerSize;
if (FLAG_trace_deopt) {
PrintF(" translating ");
function->PrintName();
- PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes);
+ PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
}
// The 'fixed' part of the frame consists of the incoming parameters and
diff --git a/deps/v8/src/mips/full-codegen-mips.cc b/deps/v8/src/mips/full-codegen-mips.cc
index 263656ea0..3e89fb43b 100644
--- a/deps/v8/src/mips/full-codegen-mips.cc
+++ b/deps/v8/src/mips/full-codegen-mips.cc
@@ -143,6 +143,8 @@ void FullCodeGenerator::Generate() {
SetFunctionPosition(function());
Comment cmnt(masm_, "[ function compiled by full code generator");
+ ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+
#ifdef DEBUG
if (strlen(FLAG_stop_at) > 0 &&
info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
@@ -190,10 +192,13 @@ void FullCodeGenerator::Generate() {
// Possibly allocate a local context.
int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
if (heap_slots > 0) {
- Comment cmnt(masm_, "[ Allocate local context");
- // Argument to NewContext is the function, which is in a1.
+ Comment cmnt(masm_, "[ Allocate context");
+ // Argument to NewContext is the function, which is still in a1.
__ push(a1);
- if (heap_slots <= FastNewContextStub::kMaximumSlots) {
+ if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+ __ Push(info->scope()->GetScopeInfo());
+ __ CallRuntime(Runtime::kNewGlobalContext, 2);
+ } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
FastNewContextStub stub(heap_slots);
__ CallStub(&stub);
} else {
@@ -270,7 +275,7 @@ void FullCodeGenerator::Generate() {
scope()->VisitIllegalRedeclaration(this);
} else {
- PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
+ PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
{ Comment cmnt(masm_, "[ Declarations");
// For named function expressions, declare the function name as a
// constant.
@@ -285,7 +290,7 @@ void FullCodeGenerator::Generate() {
}
{ Comment cmnt(masm_, "[ Stack check");
- PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
+ PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
Label ok;
__ LoadRoot(t0, Heap::kStackLimitRootIndex);
__ Branch(&ok, hs, sp, Operand(t0));
@@ -332,7 +337,7 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
}
if (isolate()->IsDebuggerActive()) {
// Detect debug break requests as soon as possible.
- reset_value = 10;
+ reset_value = FLAG_interrupt_budget >> 4;
}
__ li(a2, Operand(profiling_counter_));
__ li(a3, Operand(Smi::FromInt(reset_value)));
@@ -340,10 +345,6 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
}
-static const int kMaxBackEdgeWeight = 127;
-static const int kBackEdgeDistanceDivisor = 142;
-
-
void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
Label* back_edge_target) {
// The generated code is used in Deoptimizer::PatchStackCheckCodeAt so we need
@@ -360,7 +361,7 @@ void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
ASSERT(back_edge_target->is_bound());
int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kBackEdgeDistanceDivisor));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
__ slt(at, a3, zero_reg);
@@ -413,7 +414,7 @@ void FullCodeGenerator::EmitReturnSequence() {
} else if (FLAG_weighted_back_edges) {
int distance = masm_->pc_offset();
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kBackEdgeDistanceDivisor));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
Label ok;
@@ -793,7 +794,7 @@ void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
// The variable in the declaration always resides in the current function
// context.
ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
- if (FLAG_debug_code) {
+ if (generate_debug_code_) {
// Check that we're not inside a with or catch context.
__ lw(a1, FieldMemOperand(cp, HeapObject::kMapOffset));
__ LoadRoot(t0, Heap::kWithContextMapRootIndex);
@@ -848,10 +849,9 @@ void FullCodeGenerator::VisitVariableDeclaration(
Comment cmnt(masm_, "[ VariableDeclaration");
__ li(a2, Operand(variable->name()));
// Declaration nodes are always introduced in one of four modes.
- ASSERT(mode == VAR || mode == LET ||
- mode == CONST || mode == CONST_HARMONY);
- PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
- ? READ_ONLY : NONE;
+ ASSERT(IsDeclaredVariableMode(mode));
+ PropertyAttributes attr =
+ IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
__ li(a1, Operand(Smi::FromInt(attr)));
// Push initial value, if any.
// Note: For variables we must not push an initial value (such as
@@ -1141,25 +1141,32 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// modification check. Otherwise, we got a fixed array, and we have
// to do a slow check.
Label fixed_array;
- __ mov(a2, v0);
- __ lw(a1, FieldMemOperand(a2, HeapObject::kMapOffset));
+ __ lw(a2, FieldMemOperand(v0, HeapObject::kMapOffset));
__ LoadRoot(at, Heap::kMetaMapRootIndex);
- __ Branch(&fixed_array, ne, a1, Operand(at));
+ __ Branch(&fixed_array, ne, a2, Operand(at));
// We got a map in register v0. Get the enumeration cache from it.
+ Label no_descriptors;
__ bind(&use_cache);
- __ LoadInstanceDescriptors(v0, a1);
- __ lw(a1, FieldMemOperand(a1, DescriptorArray::kEnumerationIndexOffset));
- __ lw(a2, FieldMemOperand(a1, DescriptorArray::kEnumCacheBridgeCacheOffset));
+
+ __ EnumLength(a1, v0);
+ __ Branch(&no_descriptors, eq, a1, Operand(Smi::FromInt(0)));
+
+ __ LoadInstanceDescriptors(v0, a2);
+ __ lw(a2, FieldMemOperand(a2, DescriptorArray::kEnumCacheOffset));
+ __ lw(a2, FieldMemOperand(a2, DescriptorArray::kEnumCacheBridgeCacheOffset));
// Set up the four remaining stack slots.
__ push(v0); // Map.
- __ lw(a1, FieldMemOperand(a2, FixedArray::kLengthOffset));
__ li(a0, Operand(Smi::FromInt(0)));
// Push enumeration cache, enumeration cache length (as smi) and zero.
__ Push(a2, a1, a0);
__ jmp(&loop);
+ __ bind(&no_descriptors);
+ __ Drop(1);
+ __ jmp(&exit);
+
// We got a fixed array in register v0. Iterate through that.
Label non_proxy;
__ bind(&fixed_array);
@@ -1168,7 +1175,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
isolate()->factory()->NewJSGlobalPropertyCell(
Handle<Object>(
Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker)));
- RecordTypeFeedbackCell(stmt->PrepareId(), cell);
+ RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
__ LoadHeapObject(a1, cell);
__ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
__ sw(a2, FieldMemOperand(a1, JSGlobalPropertyCell::kValueOffset));
@@ -1324,9 +1331,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
__ Move(next, current);
}
__ bind(&loop);
- // Terminate at global context.
+ // Terminate at native context.
__ lw(temp, FieldMemOperand(next, HeapObject::kMapOffset));
- __ LoadRoot(t0, Heap::kGlobalContextMapRootIndex);
+ __ LoadRoot(t0, Heap::kNativeContextMapRootIndex);
__ Branch(&fast, eq, temp, Operand(t0));
// Check that extension is NULL.
__ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX));
@@ -1614,7 +1621,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
// marked expressions, no store code is emitted.
expr->CalculateEmitStore(zone());
- AccessorTable accessor_table(isolate()->zone());
+ AccessorTable accessor_table(zone());
for (int i = 0; i < expr->properties()->length(); i++) {
ObjectLiteral::Property* property = expr->properties()->at(i);
if (property->IsCompileTimeValue()) continue;
@@ -1641,7 +1648,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, key->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
VisitForEffect(value);
@@ -1852,11 +1859,11 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
break;
case NAMED_PROPERTY:
EmitNamedPropertyLoad(property);
- PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
+ PrepareForBailoutForId(property->LoadId(), TOS_REG);
break;
case KEYED_PROPERTY:
EmitKeyedPropertyLoad(property);
- PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
+ PrepareForBailoutForId(property->LoadId(), TOS_REG);
break;
}
}
@@ -1914,7 +1921,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ li(a2, Operand(key->handle()));
// Call load IC. It has arguments receiver and property name a0 and a2.
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
}
@@ -1923,7 +1930,7 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
__ mov(a0, result_register());
// Call keyed load IC. It has arguments key and receiver in a0 and a1.
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
- CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
}
@@ -1951,7 +1958,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call);
BinaryOpStub stub(op, mode);
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done);
@@ -2034,7 +2042,8 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
__ pop(a1);
BinaryOpStub stub(op, mode);
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
context()->Plug(v0);
}
@@ -2166,7 +2175,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// in harmony mode.
if (var->IsStackAllocated() || var->IsContextSlot()) {
MemOperand location = VarOperand(var, a1);
- if (FLAG_debug_code && op == Token::INIT_LET) {
+ if (generate_debug_code_ && op == Token::INIT_LET) {
// Check for an uninitialized let binding.
__ lw(a2, location);
__ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
@@ -2199,44 +2208,17 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
ASSERT(prop != NULL);
ASSERT(prop->key()->AsLiteral() != NULL);
- // If the assignment starts a block of assignments to the same object,
- // change to slow case to avoid the quadratic behavior of repeatedly
- // adding fast properties.
- if (expr->starts_initialization_block()) {
- __ push(result_register());
- __ lw(t0, MemOperand(sp, kPointerSize)); // Receiver is now under value.
- __ push(t0);
- __ CallRuntime(Runtime::kToSlowProperties, 1);
- __ pop(result_register());
- }
-
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ mov(a0, result_register()); // Load the value.
__ li(a2, Operand(prop->key()->AsLiteral()->handle()));
- // Load receiver to a1. Leave a copy in the stack if needed for turning the
- // receiver into fast case.
- if (expr->ends_initialization_block()) {
- __ lw(a1, MemOperand(sp));
- } else {
- __ pop(a1);
- }
+ __ pop(a1);
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
-
- // If the assignment ends an initialization block, revert to fast case.
- if (expr->ends_initialization_block()) {
- __ push(v0); // Result of assignment, saved even if not needed.
- // Receiver is under the result value.
- __ lw(t0, MemOperand(sp, kPointerSize));
- __ push(t0);
- __ CallRuntime(Runtime::kToFastProperties, 1);
- __ pop(v0);
- __ Drop(1);
- }
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
+
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
context()->Plug(v0);
}
@@ -2245,18 +2227,6 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
- // If the assignment starts a block of assignments to the same object,
- // change to slow case to avoid the quadratic behavior of repeatedly
- // adding fast properties.
- if (expr->starts_initialization_block()) {
- __ push(result_register());
- // Receiver is now under the key and value.
- __ lw(t0, MemOperand(sp, 2 * kPointerSize));
- __ push(t0);
- __ CallRuntime(Runtime::kToSlowProperties, 1);
- __ pop(result_register());
- }
-
// Record source code position before IC call.
SetSourcePosition(expr->position());
// Call keyed store IC.
@@ -2266,29 +2236,13 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// - a2 is the receiver.
__ mov(a0, result_register());
__ pop(a1); // Key.
- // Load receiver to a2. Leave a copy in the stack if needed for turning the
- // receiver into fast case.
- if (expr->ends_initialization_block()) {
- __ lw(a2, MemOperand(sp));
- } else {
- __ pop(a2);
- }
+ __ pop(a2);
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
-
- // If the assignment ends an initialization block, revert to fast case.
- if (expr->ends_initialization_block()) {
- __ push(v0); // Result of assignment, saved even if not needed.
- // Receiver is under the result value.
- __ lw(t0, MemOperand(sp, kPointerSize));
- __ push(t0);
- __ CallRuntime(Runtime::kToFastProperties, 1);
- __ pop(v0);
- __ Drop(1);
- }
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
+
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
context()->Plug(v0);
}
@@ -2301,6 +2255,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj());
EmitNamedPropertyLoad(expr);
+ PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(v0);
} else {
VisitForStackValue(expr->obj());
@@ -2314,9 +2269,9 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
void FullCodeGenerator::CallIC(Handle<Code> code,
RelocInfo::Mode rmode,
- unsigned ast_id) {
+ TypeFeedbackId id) {
ic_total_count_++;
- __ Call(code, rmode, ast_id);
+ __ Call(code, rmode, id);
}
@@ -2337,7 +2292,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
// Call the IC initialization code.
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
- CallIC(ic, mode, expr->id());
+ CallIC(ic, mode, expr->CallFeedbackId());
RecordJSReturnSite(expr);
// Restore context register.
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2370,7 +2325,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
Handle<Code> ic =
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
__ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key.
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId());
RecordJSReturnSite(expr);
// Restore context register.
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2390,16 +2345,14 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
// Record source position for debugger.
SetSourcePosition(expr->position());
- // Record call targets in unoptimized code, but not in the snapshot.
- if (!Serializer::enabled()) {
- flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
- Handle<Object> uninitialized =
- TypeFeedbackCells::UninitializedSentinel(isolate());
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
- RecordTypeFeedbackCell(expr->id(), cell);
- __ li(a2, Operand(cell));
- }
+ // Record call targets.
+ flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
+ Handle<Object> uninitialized =
+ TypeFeedbackCells::UninitializedSentinel(isolate());
+ Handle<JSGlobalPropertyCell> cell =
+ isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
+ RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
+ __ li(a2, Operand(cell));
CallFunctionStub stub(arg_count, flags);
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
@@ -2588,21 +2541,15 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ li(a0, Operand(arg_count));
__ lw(a1, MemOperand(sp, arg_count * kPointerSize));
- // Record call targets in unoptimized code, but not in the snapshot.
- CallFunctionFlags flags;
- if (!Serializer::enabled()) {
- flags = RECORD_CALL_TARGET;
- Handle<Object> uninitialized =
- TypeFeedbackCells::UninitializedSentinel(isolate());
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
- RecordTypeFeedbackCell(expr->id(), cell);
- __ li(a2, Operand(cell));
- } else {
- flags = NO_CALL_FUNCTION_FLAGS;
- }
+ // Record call targets in unoptimized code.
+ Handle<Object> uninitialized =
+ TypeFeedbackCells::UninitializedSentinel(isolate());
+ Handle<JSGlobalPropertyCell> cell =
+ isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
+ RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
+ __ li(a2, Operand(cell));
- CallConstructStub stub(flags);
+ CallConstructStub stub(RECORD_CALL_TARGET);
__ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
context()->Plug(v0);
@@ -2743,7 +2690,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
- if (FLAG_debug_code) __ AbortIfSmi(v0);
+ __ AssertNotSmi(v0);
__ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
__ lbu(t0, FieldMemOperand(a1, Map::kBitField2Offset));
@@ -2757,28 +2704,31 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ Branch(if_false, eq, a2, Operand(t0));
// Look for valueOf symbol in the descriptor array, and indicate false if
- // found. The type is not checked, so if it is a transition it is a false
- // negative.
+ // found. Since we omit an enumeration index check, if it is added via a
+ // transition that shares its descriptor array, this is a false positive.
+ Label entry, loop, done;
+
+ // Skip loop if no descriptors are valid.
+ __ NumberOfOwnDescriptors(a3, a1);
+ __ Branch(&done, eq, a3, Operand(zero_reg));
+
__ LoadInstanceDescriptors(a1, t0);
- __ lw(a3, FieldMemOperand(t0, FixedArray::kLengthOffset));
- // t0: descriptor array
- // a3: length of descriptor array
- // Calculate the end of the descriptor array.
+ // t0: descriptor array.
+ // a3: valid entries in the descriptor array.
STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize == 1);
STATIC_ASSERT(kPointerSize == 4);
- __ Addu(a2, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ li(at, Operand(DescriptorArray::kDescriptorSize));
+ __ Mul(a3, a3, at);
+ // Calculate location of the first key name.
+ __ Addu(t0, t0, Operand(DescriptorArray::kFirstOffset - kHeapObjectTag));
+ // Calculate the end of the descriptor array.
+ __ mov(a2, t0);
__ sll(t1, a3, kPointerSizeLog2 - kSmiTagSize);
__ Addu(a2, a2, t1);
- // Calculate location of the first key name.
- __ Addu(t0,
- t0,
- Operand(FixedArray::kHeaderSize - kHeapObjectTag +
- DescriptorArray::kFirstIndex * kPointerSize));
// Loop through all the keys in the descriptor array. If one of these is the
// symbol valueOf the result is false.
- Label entry, loop;
// The use of t2 to store the valueOf symbol asumes that it is not otherwise
// used in the loop below.
__ LoadRoot(t2, Heap::kvalue_of_symbolRootIndex);
@@ -2786,17 +2736,18 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ bind(&loop);
__ lw(a3, MemOperand(t0, 0));
__ Branch(if_false, eq, a3, Operand(t2));
- __ Addu(t0, t0, Operand(kPointerSize));
+ __ Addu(t0, t0, Operand(DescriptorArray::kDescriptorSize * kPointerSize));
__ bind(&entry);
__ Branch(&loop, ne, t0, Operand(a2));
- // If a valueOf property is not found on the object check that it's
+ __ bind(&done);
+ // If a valueOf property is not found on the object check that its
// prototype is the un-modified String prototype. If not result is false.
__ lw(a2, FieldMemOperand(a1, Map::kPrototypeOffset));
__ JumpIfSmi(a2, if_false);
__ lw(a2, FieldMemOperand(a2, HeapObject::kMapOffset));
- __ lw(a3, ContextOperand(cp, Context::GLOBAL_INDEX));
- __ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalContextOffset));
+ __ lw(a3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+ __ lw(a3, FieldMemOperand(a3, GlobalObject::kNativeContextOffset));
__ lw(a3, ContextOperand(a3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
__ Branch(if_false, ne, a2, Operand(a3));
@@ -3076,8 +3027,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) {
// ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
if (CpuFeatures::IsSupported(FPU)) {
__ PrepareCallCFunction(1, a0);
- __ lw(a0, ContextOperand(cp, Context::GLOBAL_INDEX));
- __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalContextOffset));
+ __ lw(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+ __ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset));
__ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
CpuFeatures::Scope scope(FPU);
@@ -3094,8 +3045,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) {
} else {
__ PrepareCallCFunction(2, a0);
__ mov(a0, s0);
- __ lw(a1, ContextOperand(cp, Context::GLOBAL_INDEX));
- __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalContextOffset));
+ __ lw(a1, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+ __ lw(a1, FieldMemOperand(a1, GlobalObject::kNativeContextOffset));
__ CallCFunction(
ExternalReference::fill_heap_number_with_random_function(isolate()), 2);
}
@@ -3159,21 +3110,19 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0)); // Load the object.
- Label runtime, done;
+ Label runtime, done, not_date_object;
Register object = v0;
Register result = v0;
Register scratch0 = t5;
Register scratch1 = a1;
-#ifdef DEBUG
- __ AbortIfSmi(object);
+ __ JumpIfSmi(object, &not_date_object);
__ GetObjectType(object, scratch1, scratch1);
- __ Assert(eq, "Trying to get date field from non-date.",
- scratch1, Operand(JS_DATE_TYPE));
-#endif
+ __ Branch(&not_date_object, ne, scratch1, Operand(JS_DATE_TYPE));
if (index->value() == 0) {
__ lw(result, FieldMemOperand(object, JSDate::kValueOffset));
+ __ jmp(&done);
} else {
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
@@ -3190,9 +3139,12 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
__ li(a1, Operand(index));
__ Move(a0, object);
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
- __ bind(&done);
+ __ jmp(&done);
}
+ __ bind(&not_date_object);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
+ __ bind(&done);
context()->Plug(v0);
}
@@ -3467,10 +3419,11 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
- // Check for proxy.
- Label proxy, done;
+ Label runtime, done;
+ // Check for non-function argument (including proxy).
+ __ JumpIfSmi(v0, &runtime);
__ GetObjectType(v0, a1, a1);
- __ Branch(&proxy, eq, a1, Operand(JS_FUNCTION_PROXY_TYPE));
+ __ Branch(&runtime, ne, a1, Operand(JS_FUNCTION_TYPE));
// InvokeFunction requires the function in a1. Move it in there.
__ mov(a1, result_register());
@@ -3480,7 +3433,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ jmp(&done);
- __ bind(&proxy);
+ __ bind(&runtime);
__ push(v0);
__ CallRuntime(Runtime::kCall, args->length());
__ bind(&done);
@@ -3509,7 +3462,7 @@ void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
Handle<FixedArray> jsfunction_result_caches(
- isolate()->global_context()->jsfunction_result_caches());
+ isolate()->native_context()->jsfunction_result_caches());
if (jsfunction_result_caches->length() <= cache_id) {
__ Abort("Attempt to use undefined cache.");
__ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
@@ -3521,8 +3474,8 @@ void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
Register key = v0;
Register cache = a1;
- __ lw(cache, ContextOperand(cp, Context::GLOBAL_INDEX));
- __ lw(cache, FieldMemOperand(cache, GlobalObject::kGlobalContextOffset));
+ __ lw(cache, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+ __ lw(cache, FieldMemOperand(cache, GlobalObject::kNativeContextOffset));
__ lw(cache,
ContextOperand(
cache, Context::JSFUNCTION_RESULT_CACHES_INDEX));
@@ -3618,9 +3571,7 @@ void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
ASSERT(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
- if (FLAG_debug_code) {
- __ AbortIfNotString(v0);
- }
+ __ AssertString(v0);
__ lw(v0, FieldMemOperand(v0, String::kHashFieldOffset));
__ IndexFromHash(v0, v0);
@@ -3694,7 +3645,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
// string_length: Accumulated sum of string lengths (smi).
// element: Current array element.
// elements_end: Array end.
- if (FLAG_debug_code) {
+ if (generate_debug_code_) {
__ Assert(gt, "No empty arrays here in EmitFastAsciiArrayJoin",
array_length, Operand(zero_reg));
}
@@ -3897,7 +3848,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
- CallIC(ic, mode, expr->id());
+ CallIC(ic, mode, expr->CallRuntimeFeedbackId());
// Restore context register.
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
} else {
@@ -4053,7 +4004,8 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
VisitForAccumulatorValue(expr->expression());
SetSourcePosition(expr->position());
__ mov(a0, result_register());
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->UnaryOperationFeedbackId());
context()->Plug(v0);
}
@@ -4111,7 +4063,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == VARIABLE) {
PrepareForBailout(expr->expression(), TOS_REG);
} else {
- PrepareForBailoutForId(expr->CountId(), TOS_REG);
+ PrepareForBailoutForId(prop->LoadId(), TOS_REG);
}
// Call ToNumber only if operand is not a smi.
@@ -4164,7 +4116,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
SetSourcePosition(expr->position());
BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4197,7 +4149,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
if (!context()->IsEffect()) {
@@ -4215,7 +4167,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
if (!context()->IsEffect()) {
@@ -4419,7 +4371,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CompareIC::GetUninitialized(op);
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through);
@@ -4500,7 +4452,7 @@ void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
Scope* declaration_scope = scope()->DeclarationScope();
if (declaration_scope->is_global_scope() ||
declaration_scope->is_module_scope()) {
- // Contexts nested in the global context have a canonical empty function
+ // Contexts nested in the native context have a canonical empty function
// as their closure, not the anonymous closure containing the global
// code. Pass a smi sentinel and let the runtime look up the empty
// function.
@@ -4545,6 +4497,7 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference::address_of_has_pending_message(isolate());
__ li(at, Operand(has_pending_message));
__ lw(a1, MemOperand(at));
+ __ SmiTag(a1);
__ push(a1);
ExternalReference pending_message_script =
@@ -4565,6 +4518,7 @@ void FullCodeGenerator::ExitFinallyBlock() {
__ sw(a1, MemOperand(at));
__ pop(a1);
+ __ SmiUntag(a1);
ExternalReference has_pending_message =
ExternalReference::address_of_has_pending_message(isolate());
__ li(at, Operand(has_pending_message));
diff --git a/deps/v8/src/mips/ic-mips.cc b/deps/v8/src/mips/ic-mips.cc
index 5d530d0e9..cf706815e 100644
--- a/deps/v8/src/mips/ic-mips.cc
+++ b/deps/v8/src/mips/ic-mips.cc
@@ -398,7 +398,7 @@ void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC,
extra_state,
- NORMAL,
+ Code::NORMAL,
argc);
Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, a1, a2, a3, t0, t1, t2);
@@ -1189,6 +1189,145 @@ void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
}
+static void KeyedStoreGenerateGenericHelper(
+ MacroAssembler* masm,
+ Label* fast_object,
+ Label* fast_double,
+ Label* slow,
+ KeyedStoreCheckMap check_map,
+ KeyedStoreIncrementLength increment_length,
+ Register value,
+ Register key,
+ Register receiver,
+ Register receiver_map,
+ Register elements_map,
+ Register elements) {
+ Label transition_smi_elements;
+ Label finish_object_store, non_double_value, transition_double_elements;
+ Label fast_double_without_map_check;
+
+ // Fast case: Do the store, could be either Object or double.
+ __ bind(fast_object);
+ Register scratch_value = t0;
+ Register address = t1;
+ if (check_map == kCheckMap) {
+ __ lw(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
+ __ Branch(fast_double, ne, elements_map,
+ Operand(masm->isolate()->factory()->fixed_array_map()));
+ }
+ // Smi stores don't require further checks.
+ Label non_smi_value;
+ __ JumpIfNotSmi(value, &non_smi_value);
+
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ Addu(scratch_value, key, Operand(Smi::FromInt(1)));
+ __ sw(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
+ }
+ // It's irrelevant whether array is smi-only or not when writing a smi.
+ __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize);
+ __ Addu(address, address, scratch_value);
+ __ sw(value, MemOperand(address));
+ __ Ret();
+
+ __ bind(&non_smi_value);
+ // Escape to elements kind transition case.
+ __ CheckFastObjectElements(receiver_map, scratch_value,
+ &transition_smi_elements);
+
+ // Fast elements array, store the value to the elements backing store.
+ __ bind(&finish_object_store);
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ Addu(scratch_value, key, Operand(Smi::FromInt(1)));
+ __ sw(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
+ }
+ __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize);
+ __ Addu(address, address, scratch_value);
+ __ sw(value, MemOperand(address));
+ // Update write barrier for the elements array address.
+ __ mov(scratch_value, value); // Preserve the value which is returned.
+ __ RecordWrite(elements,
+ address,
+ scratch_value,
+ kRAHasNotBeenSaved,
+ kDontSaveFPRegs,
+ EMIT_REMEMBERED_SET,
+ OMIT_SMI_CHECK);
+ __ Ret();
+
+ __ bind(fast_double);
+ if (check_map == kCheckMap) {
+ // Check for fast double array case. If this fails, call through to the
+ // runtime.
+ __ LoadRoot(at, Heap::kFixedDoubleArrayMapRootIndex);
+ __ Branch(slow, ne, elements_map, Operand(at));
+ }
+ __ bind(&fast_double_without_map_check);
+ __ StoreNumberToDoubleElements(value,
+ key,
+ receiver,
+ elements, // Overwritten.
+ a3, // Scratch regs...
+ t0,
+ t1,
+ t2,
+ &transition_double_elements);
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ Addu(scratch_value, key, Operand(Smi::FromInt(1)));
+ __ sw(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
+ }
+ __ Ret();
+
+ __ bind(&transition_smi_elements);
+ // Transition the array appropriately depending on the value type.
+ __ lw(t0, FieldMemOperand(value, HeapObject::kMapOffset));
+ __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
+ __ Branch(&non_double_value, ne, t0, Operand(at));
+
+ // Value is a double. Transition FAST_SMI_ELEMENTS ->
+ // FAST_DOUBLE_ELEMENTS and complete the store.
+ __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
+ FAST_DOUBLE_ELEMENTS,
+ receiver_map,
+ t0,
+ slow);
+ ASSERT(receiver_map.is(a3)); // Transition code expects map in a3
+ ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
+ __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+ __ jmp(&fast_double_without_map_check);
+
+ __ bind(&non_double_value);
+ // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
+ __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
+ FAST_ELEMENTS,
+ receiver_map,
+ t0,
+ slow);
+ ASSERT(receiver_map.is(a3)); // Transition code expects map in a3
+ ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
+ __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+ __ jmp(&finish_object_store);
+
+ __ bind(&transition_double_elements);
+ // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
+ // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
+ // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
+ __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
+ FAST_ELEMENTS,
+ receiver_map,
+ t0,
+ slow);
+ ASSERT(receiver_map.is(a3)); // Transition code expects map in a3
+ ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
+ __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+ __ jmp(&finish_object_store);
+}
+
+
void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
StrictModeFlag strict_mode) {
// ---------- S t a t e --------------
@@ -1197,11 +1336,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// -- a2 : receiver
// -- ra : return address
// -----------------------------------
- Label slow, array, extra, check_if_double_array;
- Label fast_object_with_map_check, fast_object_without_map_check;
- Label fast_double_with_map_check, fast_double_without_map_check;
- Label transition_smi_elements, finish_object_store, non_double_value;
- Label transition_double_elements;
+ Label slow, fast_object, fast_object_grow;
+ Label fast_double, fast_double_grow;
+ Label array, extra, check_if_double_array;
// Register usage.
Register value = a0;
@@ -1233,7 +1370,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
__ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
// Check array bounds. Both the key and the length of FixedArray are smis.
__ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ Branch(&fast_object_with_map_check, lo, key, Operand(t0));
+ __ Branch(&fast_object, lo, key, Operand(t0));
// Slow case, handle jump to runtime.
__ bind(&slow);
@@ -1258,19 +1395,11 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
__ Branch(
&check_if_double_array, ne, elements_map, Heap::kFixedArrayMapRootIndex);
- // Calculate key + 1 as smi.
- STATIC_ASSERT(kSmiTag == 0);
- __ Addu(t0, key, Operand(Smi::FromInt(1)));
- __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Branch(&fast_object_without_map_check);
+ __ jmp(&fast_object_grow);
__ bind(&check_if_double_array);
__ Branch(&slow, ne, elements_map, Heap::kFixedDoubleArrayMapRootIndex);
- // Add 1 to key, and go to common element store code for doubles.
- STATIC_ASSERT(kSmiTag == 0);
- __ Addu(t0, key, Operand(Smi::FromInt(1)));
- __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ jmp(&fast_double_without_map_check);
+ __ jmp(&fast_double_grow);
// Array case: Get the length and the elements array from the JS
// array. Check that the array is in fast mode (and writable); if it
@@ -1281,110 +1410,15 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// Check the key against the length in the array.
__ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ Branch(&extra, hs, key, Operand(t0));
- // Fall through to fast case.
- __ bind(&fast_object_with_map_check);
- Register scratch_value = t0;
- Register address = t1;
- __ lw(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
- __ Branch(&fast_double_with_map_check,
- ne,
- elements_map,
- Heap::kFixedArrayMapRootIndex);
- __ bind(&fast_object_without_map_check);
- // Smi stores don't require further checks.
- Label non_smi_value;
- __ JumpIfNotSmi(value, &non_smi_value);
- // It's irrelevant whether array is smi-only or not when writing a smi.
- __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(address, address, scratch_value);
- __ sw(value, MemOperand(address));
- __ Ret(USE_DELAY_SLOT);
- __ mov(v0, value);
-
- __ bind(&non_smi_value);
- // Escape to elements kind transition case.
- __ CheckFastObjectElements(receiver_map, scratch_value,
- &transition_smi_elements);
- // Fast elements array, store the value to the elements backing store.
- __ bind(&finish_object_store);
- __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(address, address, scratch_value);
- __ sw(value, MemOperand(address));
- // Update write barrier for the elements array address.
- __ mov(v0, value); // Preserve the value which is returned.
- __ RecordWrite(elements,
- address,
- value,
- kRAHasNotBeenSaved,
- kDontSaveFPRegs,
- EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ Ret();
-
- __ bind(&fast_double_with_map_check);
- // Check for fast double array case. If this fails, call through to the
- // runtime.
- __ Branch(&slow, ne, elements_map, Heap::kFixedDoubleArrayMapRootIndex);
- __ bind(&fast_double_without_map_check);
- __ StoreNumberToDoubleElements(value,
- key,
- receiver,
- elements,
- a3,
- t0,
- t1,
- t2,
- &transition_double_elements);
- __ Ret(USE_DELAY_SLOT);
- __ mov(v0, value);
-
- __ bind(&transition_smi_elements);
- // Transition the array appropriately depending on the value type.
- __ lw(t0, FieldMemOperand(value, HeapObject::kMapOffset));
- __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
- __ Branch(&non_double_value, ne, t0, Operand(at));
-
-
- // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS
- // and complete the store.
- __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
- FAST_DOUBLE_ELEMENTS,
- receiver_map,
- t0,
- &slow);
- ASSERT(receiver_map.is(a3)); // Transition code expects map in a3
- ElementsTransitionGenerator::GenerateSmiToDouble(masm, &slow);
- __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
- __ jmp(&fast_double_without_map_check);
-
- __ bind(&non_double_value);
- // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
- __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
- FAST_ELEMENTS,
- receiver_map,
- t0,
- &slow);
- ASSERT(receiver_map.is(a3)); // Transition code expects map in a3
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
- __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
- __ jmp(&finish_object_store);
-
- __ bind(&transition_double_elements);
- // Elements are double, but value is an Object that's not a HeapNumber. Make
- // sure that the receiver is a Array with Object elements and transition array
- // from double elements to Object elements.
- __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
- FAST_ELEMENTS,
- receiver_map,
- t0,
- &slow);
- ASSERT(receiver_map.is(a3)); // Transition code expects map in a3
- ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow);
- __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
- __ jmp(&finish_object_store);
+ KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
+ &slow, kCheckMap, kDontIncrementLength,
+ value, key, receiver, receiver_map,
+ elements_map, elements);
+ KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
+ &slow, kDontCheckMap, kIncrementLength,
+ value, key, receiver, receiver_map,
+ elements_map, elements);
}
diff --git a/deps/v8/src/mips/lithium-codegen-mips.cc b/deps/v8/src/mips/lithium-codegen-mips.cc
index 68f8a3dd7..4c2182bdb 100644
--- a/deps/v8/src/mips/lithium-codegen-mips.cc
+++ b/deps/v8/src/mips/lithium-codegen-mips.cc
@@ -89,17 +89,8 @@ void LCodeGen::FinishCode(Handle<Code> code) {
}
-void LCodeGen::Abort(const char* format, ...) {
- if (FLAG_trace_bailout) {
- SmartArrayPointer<char> name(
- info()->shared_info()->DebugName()->ToCString());
- PrintF("Aborting LCodeGen in @\"%s\": ", *name);
- va_list arguments;
- va_start(arguments, format);
- OS::VPrint(format, arguments);
- va_end(arguments);
- PrintF("\n");
- }
+void LChunkBuilder::Abort(const char* reason) {
+ info()->set_bailout_reason(reason);
status_ = ABORTED;
}
@@ -125,6 +116,8 @@ void LCodeGen::Comment(const char* format, ...) {
bool LCodeGen::GeneratePrologue() {
ASSERT(is_generating());
+ ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+
#ifdef DEBUG
if (strlen(FLAG_stop_at) > 0 &&
info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
@@ -259,7 +252,7 @@ bool LCodeGen::GenerateDeferredCode() {
bool LCodeGen::GenerateDeoptJumpTable() {
// TODO(plind): not clear that this will have advantage for MIPS.
// Skipping it for now. Raised issue #100 for this.
- Abort("Unimplemented: %s", "GenerateDeoptJumpTable");
+ Abort("Unimplemented: GenerateDeoptJumpTable");
return false;
}
@@ -292,7 +285,8 @@ Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
return ToRegister(op->index());
} else if (op->IsConstantOperand()) {
LConstantOperand* const_op = LConstantOperand::cast(op);
- Handle<Object> literal = chunk_->LookupLiteral(const_op);
+ HConstant* constant = chunk_->LookupConstant(const_op);
+ Handle<Object> literal = constant->handle();
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
ASSERT(literal->IsNumber());
@@ -330,7 +324,8 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
return ToDoubleRegister(op->index());
} else if (op->IsConstantOperand()) {
LConstantOperand* const_op = LConstantOperand::cast(op);
- Handle<Object> literal = chunk_->LookupLiteral(const_op);
+ HConstant* constant = chunk_->LookupConstant(const_op);
+ Handle<Object> literal = constant->handle();
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
ASSERT(literal->IsNumber());
@@ -354,9 +349,9 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
- Handle<Object> literal = chunk_->LookupLiteral(op);
+ HConstant* constant = chunk_->LookupConstant(op);
ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
- return literal;
+ return constant->handle();
}
@@ -366,33 +361,33 @@ bool LCodeGen::IsInteger32(LConstantOperand* op) const {
int LCodeGen::ToInteger32(LConstantOperand* op) const {
- Handle<Object> value = chunk_->LookupLiteral(op);
+ HConstant* constant = chunk_->LookupConstant(op);
ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32());
- ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) ==
- value->Number());
- return static_cast<int32_t>(value->Number());
+ ASSERT(constant->HasInteger32Value());
+ return constant->Integer32Value();
}
double LCodeGen::ToDouble(LConstantOperand* op) const {
- Handle<Object> value = chunk_->LookupLiteral(op);
- return value->Number();
+ HConstant* constant = chunk_->LookupConstant(op);
+ ASSERT(constant->HasDoubleValue());
+ return constant->DoubleValue();
}
Operand LCodeGen::ToOperand(LOperand* op) {
if (op->IsConstantOperand()) {
LConstantOperand* const_op = LConstantOperand::cast(op);
- Handle<Object> literal = chunk_->LookupLiteral(const_op);
+ HConstant* constant = chunk()->LookupConstant(const_op);
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
- ASSERT(literal->IsNumber());
- return Operand(static_cast<int32_t>(literal->Number()));
+ ASSERT(constant->HasInteger32Value());
+ return Operand(constant->Integer32Value());
} else if (r.IsDouble()) {
Abort("ToOperand Unsupported double immediate.");
}
ASSERT(r.IsTagged());
- return Operand(literal);
+ return Operand(constant->handle());
} else if (op->IsRegister()) {
return Operand(ToRegister(op));
} else if (op->IsDoubleRegister()) {
@@ -437,7 +432,9 @@ MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const {
void LCodeGen::WriteTranslation(LEnvironment* environment,
- Translation* translation) {
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count) {
if (environment == NULL) return;
// The translation includes one command per value in the environment.
@@ -445,8 +442,21 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
// The output frame height does not include the parameters.
int height = translation_size - environment->parameter_count();
- WriteTranslation(environment->outer(), translation);
- int closure_id = DefineDeoptimizationLiteral(environment->closure());
+ // Function parameters are arguments to the outermost environment. The
+ // arguments index points to the first element of a sequence of tagged
+ // values on the stack that represent the arguments. This needs to be
+ // kept in sync with the LArgumentsElements implementation.
+ *arguments_index = -environment->parameter_count();
+ *arguments_count = environment->parameter_count();
+
+ WriteTranslation(environment->outer(),
+ translation,
+ arguments_index,
+ arguments_count);
+ int closure_id = *info()->closure() != *environment->closure()
+ ? DefineDeoptimizationLiteral(environment->closure())
+ : Translation::kSelfLiteralId;
+
switch (environment->frame_type()) {
case JS_FUNCTION:
translation->BeginJSFrame(environment->ast_id(), closure_id, height);
@@ -454,12 +464,31 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
case JS_CONSTRUCT:
translation->BeginConstructStubFrame(closure_id, translation_size);
break;
+ case JS_GETTER:
+ ASSERT(translation_size == 1);
+ ASSERT(height == 0);
+ translation->BeginGetterStubFrame(closure_id);
+ break;
+ case JS_SETTER:
+ ASSERT(translation_size == 2);
+ ASSERT(height == 0);
+ translation->BeginSetterStubFrame(closure_id);
+ break;
case ARGUMENTS_ADAPTOR:
translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
break;
- default:
- UNREACHABLE();
}
+
+ // Inlined frames which push their arguments cause the index to be
+ // bumped and a new stack area to be used for materialization.
+ if (environment->entry() != NULL &&
+ environment->entry()->arguments_pushed()) {
+ *arguments_index = *arguments_index < 0
+ ? GetStackSlotCount()
+ : *arguments_index + *arguments_count;
+ *arguments_count = environment->entry()->arguments_count() + 1;
+ }
+
for (int i = 0; i < translation_size; ++i) {
LOperand* value = environment->values()->at(i);
// spilled_registers_ and spilled_double_registers_ are either
@@ -470,7 +499,10 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
translation->MarkDuplicate();
AddToTranslation(translation,
environment->spilled_registers()[value->index()],
- environment->HasTaggedValueAt(i));
+ environment->HasTaggedValueAt(i),
+ environment->HasUint32ValueAt(i),
+ *arguments_index,
+ *arguments_count);
} else if (
value->IsDoubleRegister() &&
environment->spilled_double_registers()[value->index()] != NULL) {
@@ -478,26 +510,39 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
AddToTranslation(
translation,
environment->spilled_double_registers()[value->index()],
- false);
+ false,
+ false,
+ *arguments_index,
+ *arguments_count);
}
}
- AddToTranslation(translation, value, environment->HasTaggedValueAt(i));
+ AddToTranslation(translation,
+ value,
+ environment->HasTaggedValueAt(i),
+ environment->HasUint32ValueAt(i),
+ *arguments_index,
+ *arguments_count);
}
}
void LCodeGen::AddToTranslation(Translation* translation,
LOperand* op,
- bool is_tagged) {
+ bool is_tagged,
+ bool is_uint32,
+ int arguments_index,
+ int arguments_count) {
if (op == NULL) {
// TODO(twuerthinger): Introduce marker operands to indicate that this value
// is not present and must be reconstructed from the deoptimizer. Currently
// this is only used for the arguments object.
- translation->StoreArgumentsObject();
+ translation->StoreArgumentsObject(arguments_index, arguments_count);
} else if (op->IsStackSlot()) {
if (is_tagged) {
translation->StoreStackSlot(op->index());
+ } else if (is_uint32) {
+ translation->StoreUint32StackSlot(op->index());
} else {
translation->StoreInt32StackSlot(op->index());
}
@@ -511,6 +556,8 @@ void LCodeGen::AddToTranslation(Translation* translation,
Register reg = ToRegister(op);
if (is_tagged) {
translation->StoreRegister(reg);
+ } else if (is_uint32) {
+ translation->StoreUint32Register(reg);
} else {
translation->StoreInt32Register(reg);
}
@@ -518,8 +565,8 @@ void LCodeGen::AddToTranslation(Translation* translation,
DoubleRegister reg = ToDoubleRegister(op);
translation->StoreDoubleRegister(reg);
} else if (op->IsConstantOperand()) {
- Handle<Object> literal = chunk()->LookupLiteral(LConstantOperand::cast(op));
- int src_index = DefineDeoptimizationLiteral(literal);
+ HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
+ int src_index = DefineDeoptimizationLiteral(constant->handle());
translation->StoreLiteral(src_index);
} else {
UNREACHABLE();
@@ -586,6 +633,8 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
int frame_count = 0;
int jsframe_count = 0;
+ int args_index = 0;
+ int args_count = 0;
for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
++frame_count;
if (e->frame_type() == JS_FUNCTION) {
@@ -593,7 +642,7 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
}
}
Translation translation(&translations_, frame_count, jsframe_count, zone());
- WriteTranslation(environment, &translation);
+ WriteTranslation(environment, &translation, &args_index, &args_count);
int deoptimization_index = deoptimizations_.length();
int pc_offset = masm()->pc_offset();
environment->Register(deoptimization_index,
@@ -657,13 +706,13 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
}
data->SetLiteralArray(*literals);
- data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id()));
+ data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt()));
data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
// Populate the deoptimization entries.
for (int i = 0; i < length; i++) {
LEnvironment* env = deoptimizations_[i];
- data->SetAstId(i, Smi::FromInt(env->ast_id()));
+ data->SetAstId(i, env->ast_id());
data->SetTranslationIndex(i, Smi::FromInt(env->translation_index()));
data->SetArgumentsStackHeight(i,
Smi::FromInt(env->arguments_stack_height()));
@@ -862,7 +911,7 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
void LCodeGen::DoModI(LModI* instr) {
Register scratch = scratch0();
- const Register left = ToRegister(instr->InputAt(0));
+ const Register left = ToRegister(instr->left());
const Register result = ToRegister(instr->result());
Label done;
@@ -890,7 +939,7 @@ void LCodeGen::DoModI(LModI* instr) {
__ And(result, scratch, p2constant - 1);
} else {
// div runs in the background while we check for special cases.
- Register right = EmitLoadRegister(instr->InputAt(1), scratch);
+ Register right = EmitLoadRegister(instr->right(), scratch);
__ div(left, right);
// Check for x % 0.
@@ -910,8 +959,8 @@ void LCodeGen::DoModI(LModI* instr) {
void LCodeGen::DoDivI(LDivI* instr) {
- const Register left = ToRegister(instr->InputAt(0));
- const Register right = ToRegister(instr->InputAt(1));
+ const Register left = ToRegister(instr->left());
+ const Register right = ToRegister(instr->right());
const Register result = ToRegister(instr->result());
// On MIPS div is asynchronous - it will run in the background while we
@@ -949,8 +998,8 @@ void LCodeGen::DoMulI(LMulI* instr) {
Register scratch = scratch0();
Register result = ToRegister(instr->result());
// Note that result may alias left.
- Register left = ToRegister(instr->InputAt(0));
- LOperand* right_op = instr->InputAt(1);
+ Register left = ToRegister(instr->left());
+ LOperand* right_op = instr->right();
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
bool bailout_on_minus_zero =
@@ -1020,7 +1069,7 @@ void LCodeGen::DoMulI(LMulI* instr) {
} else {
Register right = EmitLoadRegister(right_op, scratch);
if (bailout_on_minus_zero) {
- __ Or(ToRegister(instr->TempAt(0)), left, right);
+ __ Or(ToRegister(instr->temp()), left, right);
}
if (can_overflow) {
@@ -1040,7 +1089,7 @@ void LCodeGen::DoMulI(LMulI* instr) {
__ Branch(&done, ne, result, Operand(zero_reg));
DeoptimizeIf(lt,
instr->environment(),
- ToRegister(instr->TempAt(0)),
+ ToRegister(instr->temp()),
Operand(zero_reg));
__ bind(&done);
}
@@ -1049,8 +1098,8 @@ void LCodeGen::DoMulI(LMulI* instr) {
void LCodeGen::DoBitI(LBitI* instr) {
- LOperand* left_op = instr->InputAt(0);
- LOperand* right_op = instr->InputAt(1);
+ LOperand* left_op = instr->left();
+ LOperand* right_op = instr->right();
ASSERT(left_op->IsRegister());
Register left = ToRegister(left_op);
Register result = ToRegister(instr->result());
@@ -1083,8 +1132,8 @@ void LCodeGen::DoBitI(LBitI* instr) {
void LCodeGen::DoShiftI(LShiftI* instr) {
// Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so
// result may alias either of them.
- LOperand* right_op = instr->InputAt(1);
- Register left = ToRegister(instr->InputAt(0));
+ LOperand* right_op = instr->right();
+ Register left = ToRegister(instr->left());
Register result = ToRegister(instr->result());
if (right_op->IsRegister()) {
@@ -1146,8 +1195,8 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
void LCodeGen::DoSubI(LSubI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
LOperand* result = instr->result();
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
@@ -1211,21 +1260,28 @@ void LCodeGen::DoConstantT(LConstantT* instr) {
void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
+ Register array = ToRegister(instr->value());
__ lw(result, FieldMemOperand(array, JSArray::kLengthOffset));
}
void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
+ Register array = ToRegister(instr->value());
__ lw(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset));
}
+void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
+ Register result = ToRegister(instr->result());
+ Register map = ToRegister(instr->value());
+ __ EnumLength(result, map);
+}
+
+
void LCodeGen::DoElementsKind(LElementsKind* instr) {
Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
// Load map into |result|.
__ lw(result, FieldMemOperand(input, HeapObject::kMapOffset));
@@ -1238,9 +1294,9 @@ void LCodeGen::DoElementsKind(LElementsKind* instr) {
void LCodeGen::DoValueOf(LValueOf* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
- Register map = ToRegister(instr->TempAt(0));
+ Register map = ToRegister(instr->temp());
Label done;
// If the object is a smi return the object.
@@ -1257,9 +1313,9 @@ void LCodeGen::DoValueOf(LValueOf* instr) {
void LCodeGen::DoDateField(LDateField* instr) {
- Register object = ToRegister(instr->InputAt(0));
+ Register object = ToRegister(instr->date());
Register result = ToRegister(instr->result());
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
Smi* index = instr->index();
Label runtime, done;
ASSERT(object.is(a0));
@@ -1267,12 +1323,10 @@ void LCodeGen::DoDateField(LDateField* instr) {
ASSERT(!scratch.is(scratch0()));
ASSERT(!scratch.is(object));
-#ifdef DEBUG
- __ AbortIfSmi(object);
+ __ And(at, object, Operand(kSmiTagMask));
+ DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
__ GetObjectType(object, scratch, scratch);
- __ Assert(eq, "Trying to get date field from non-date.",
- scratch, Operand(JS_DATE_TYPE));
-#endif
+ DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_DATE_TYPE));
if (index->value() == 0) {
__ lw(result, FieldMemOperand(object, JSDate::kValueOffset));
@@ -1297,14 +1351,14 @@ void LCodeGen::DoDateField(LDateField* instr) {
void LCodeGen::DoBitNotI(LBitNotI* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
__ Nor(result, zero_reg, Operand(input));
}
void LCodeGen::DoThrow(LThrow* instr) {
- Register input_reg = EmitLoadRegister(instr->InputAt(0), at);
+ Register input_reg = EmitLoadRegister(instr->value(), at);
__ push(input_reg);
CallRuntime(Runtime::kThrow, 1, instr);
@@ -1315,8 +1369,8 @@ void LCodeGen::DoThrow(LThrow* instr) {
void LCodeGen::DoAddI(LAddI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
LOperand* result = instr->result();
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
@@ -1353,9 +1407,71 @@ void LCodeGen::DoAddI(LAddI* instr) {
}
+void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
+ HMathMinMax::Operation operation = instr->hydrogen()->operation();
+ Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
+ if (instr->hydrogen()->representation().IsInteger32()) {
+ Register left_reg = ToRegister(left);
+ Operand right_op = (right->IsRegister() || right->IsConstantOperand())
+ ? ToOperand(right)
+ : Operand(EmitLoadRegister(right, at));
+ Register result_reg = ToRegister(instr->result());
+ Label return_right, done;
+ if (!result_reg.is(left_reg)) {
+ __ Branch(&return_right, NegateCondition(condition), left_reg, right_op);
+ __ mov(result_reg, left_reg);
+ __ Branch(&done);
+ }
+ __ Branch(&done, condition, left_reg, right_op);
+ __ bind(&return_right);
+ __ Addu(result_reg, zero_reg, right_op);
+ __ bind(&done);
+ } else {
+ ASSERT(instr->hydrogen()->representation().IsDouble());
+ FPURegister left_reg = ToDoubleRegister(left);
+ FPURegister right_reg = ToDoubleRegister(right);
+ FPURegister result_reg = ToDoubleRegister(instr->result());
+ Label check_nan_left, check_zero, return_left, return_right, done;
+ __ BranchF(&check_zero, &check_nan_left, eq, left_reg, right_reg);
+ __ BranchF(&return_left, NULL, condition, left_reg, right_reg);
+ __ Branch(&return_right);
+
+ __ bind(&check_zero);
+ // left == right != 0.
+ __ BranchF(&return_left, NULL, ne, left_reg, kDoubleRegZero);
+ // At this point, both left and right are either 0 or -0.
+ if (operation == HMathMinMax::kMathMin) {
+ __ neg_d(left_reg, left_reg);
+ __ sub_d(result_reg, left_reg, right_reg);
+ __ neg_d(result_reg, result_reg);
+ } else {
+ __ add_d(result_reg, left_reg, right_reg);
+ }
+ __ Branch(&done);
+
+ __ bind(&check_nan_left);
+ // left == NaN.
+ __ BranchF(NULL, &return_left, eq, left_reg, left_reg);
+ __ bind(&return_right);
+ if (!right_reg.is(result_reg)) {
+ __ mov_d(result_reg, right_reg);
+ }
+ __ Branch(&done);
+
+ __ bind(&return_left);
+ if (!left_reg.is(result_reg)) {
+ __ mov_d(result_reg, left_reg);
+ }
+ __ bind(&done);
+ }
+}
+
+
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
- DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
- DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
+ DoubleRegister left = ToDoubleRegister(instr->left());
+ DoubleRegister right = ToDoubleRegister(instr->right());
DoubleRegister result = ToDoubleRegister(instr->result());
switch (instr->op()) {
case Token::ADD:
@@ -1395,8 +1511,8 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(a1));
- ASSERT(ToRegister(instr->InputAt(1)).is(a0));
+ ASSERT(ToRegister(instr->left()).is(a1));
+ ASSERT(ToRegister(instr->right()).is(a0));
ASSERT(ToRegister(instr->result()).is(v0));
BinaryOpStub stub(instr->op(), NO_OVERWRITE);
@@ -1460,15 +1576,15 @@ void LCodeGen::DoBranch(LBranch* instr) {
Representation r = instr->hydrogen()->value()->representation();
if (r.IsInteger32()) {
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
} else if (r.IsDouble()) {
- DoubleRegister reg = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister reg = ToDoubleRegister(instr->value());
// Test the double value. Zero and NaN are false.
EmitBranchF(true_block, false_block, ne, reg, kDoubleRegZero);
} else {
ASSERT(r.IsTagged());
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
HType type = instr->hydrogen()->value()->type();
if (type.IsBoolean()) {
__ LoadRoot(at, Heap::kTrueValueRootIndex);
@@ -1602,8 +1718,8 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -1654,8 +1770,8 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
- Register left = ToRegister(instr->InputAt(0));
- Register right = ToRegister(instr->InputAt(1));
+ Register left = ToRegister(instr->left());
+ Register right = ToRegister(instr->right());
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -1664,7 +1780,7 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
- Register left = ToRegister(instr->InputAt(0));
+ Register left = ToRegister(instr->left());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1676,7 +1792,7 @@ void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
Register scratch = scratch0();
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
int false_block = chunk_->LookupDestination(instr->false_block_id());
// If the expression is known to be untagged or a smi, then it's definitely
@@ -1742,8 +1858,8 @@ Condition LCodeGen::EmitIsObject(Register input,
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
- Register temp1 = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->value());
+ Register temp1 = ToRegister(instr->temp());
Register temp2 = scratch0();
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -1770,8 +1886,8 @@ Condition LCodeGen::EmitIsString(Register input,
void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
- Register temp1 = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->value());
+ Register temp1 = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1789,15 +1905,15 @@ void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
- Register input_reg = EmitLoadRegister(instr->InputAt(0), at);
+ Register input_reg = EmitLoadRegister(instr->value(), at);
__ And(at, input_reg, kSmiTagMask);
EmitBranch(true_block, false_block, eq, at, Operand(zero_reg));
}
void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register input = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1866,7 +1982,7 @@ static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
Register scratch = scratch0();
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1885,12 +2001,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
- if (FLAG_debug_code) {
- __ AbortIfNotString(input);
- }
+ __ AssertString(input);
__ lw(result, FieldMemOperand(input, String::kHashFieldOffset));
__ IndexFromHash(result, result);
@@ -1899,7 +2013,7 @@ void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
void LCodeGen::DoHasCachedArrayIndexAndBranch(
LHasCachedArrayIndexAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register scratch = scratch0();
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -1979,9 +2093,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register temp = scratch0();
- Register temp2 = ToRegister(instr->TempAt(0));
+ Register temp2 = ToRegister(instr->temp());
Handle<String> class_name = instr->hydrogen()->class_name();
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -1997,8 +2111,8 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
int true_block = instr->true_block_id();
int false_block = instr->false_block_id();
@@ -2009,8 +2123,8 @@ void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
Label true_label, done;
- ASSERT(ToRegister(instr->InputAt(0)).is(a0)); // Object is in a0.
- ASSERT(ToRegister(instr->InputAt(1)).is(a1)); // Function is in a1.
+ ASSERT(ToRegister(instr->left()).is(a0)); // Object is in a0.
+ ASSERT(ToRegister(instr->right()).is(a1)); // Function is in a1.
Register result = ToRegister(instr->result());
ASSERT(result.is(v0));
@@ -2047,8 +2161,8 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
Label done, false_result;
- Register object = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register object = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
Register result = ToRegister(instr->result());
ASSERT(object.is(a0));
@@ -2123,7 +2237,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
// Get the temp register reserved by the instruction. This needs to be t0 as
// its slot of the pushing of safepoint registers is used to communicate the
// offset to the location of the map check.
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
ASSERT(temp.is(t0));
__ LoadHeapObject(InstanceofStub::right(), instr->function());
static const int kAdditionalDelta = 7;
@@ -2218,7 +2332,7 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
// it as no longer deleted.
if (instr->hydrogen()->RequiresHoleCheck()) {
// We use a temp to check the payload.
- Register payload = ToRegister(instr->TempAt(0));
+ Register payload = ToRegister(instr->temp());
__ lw(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
DeoptimizeIf(eq, instr->environment(), payload, Operand(at));
@@ -2301,7 +2415,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
- Register object = ToRegister(instr->InputAt(0));
+ Register object = ToRegister(instr->object());
Register result = ToRegister(instr->result());
if (instr->hydrogen()->is_in_object()) {
__ lw(result, FieldMemOperand(object, instr->hydrogen()->offset()));
@@ -2318,9 +2432,9 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
Handle<String> name,
LEnvironment* env) {
LookupResult lookup(isolate());
- type->LookupInDescriptors(NULL, *name, &lookup);
+ type->LookupDescriptor(NULL, *name, &lookup);
ASSERT(lookup.IsFound() || lookup.IsCacheable());
- if (lookup.IsFound() && lookup.type() == FIELD) {
+ if (lookup.IsField()) {
int index = lookup.GetLocalFieldIndexFromMap(*type);
int offset = index * kPointerSize;
if (index < 0) {
@@ -2332,7 +2446,7 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
__ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
__ lw(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
}
- } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) {
+ } else if (lookup.IsConstantFunction()) {
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
__ LoadHeapObject(result, function);
} else {
@@ -2454,7 +2568,7 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
void LCodeGen::DoLoadElements(LLoadElements* instr) {
Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->object());
Register scratch = scratch0();
__ lw(result, FieldMemOperand(input, JSObject::kElementsOffset));
@@ -2487,7 +2601,7 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
void LCodeGen::DoLoadExternalArrayPointer(
LLoadExternalArrayPointer* instr) {
Register to_reg = ToRegister(instr->result());
- Register from_reg = ToRegister(instr->InputAt(0));
+ Register from_reg = ToRegister(instr->object());
__ lw(to_reg, FieldMemOperand(from_reg,
ExternalArray::kExternalPointerOffset));
}
@@ -2498,14 +2612,6 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
Register length = ToRegister(instr->length());
Register index = ToRegister(instr->index());
Register result = ToRegister(instr->result());
-
- // Bailout index is not a valid argument index. Use unsigned check to get
- // negative check for free.
-
- // TODO(plind): Shoud be optimized to do the sub before the DeoptimizeIf(),
- // as they do in Arm. It will save us an instruction.
- DeoptimizeIf(ls, instr->environment(), length, Operand(index));
-
// There are two words between the frame pointer and the last argument.
// Subtracting from length accounts for one of them, add one more.
__ subu(length, length, index);
@@ -2518,16 +2624,32 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
Register elements = ToRegister(instr->elements());
- Register key = EmitLoadRegister(instr->key(), scratch0());
Register result = ToRegister(instr->result());
Register scratch = scratch0();
+ Register store_base = scratch;
+ int offset = 0;
- // Load the result.
- __ sll(scratch, key, kPointerSizeLog2); // Key indexes words.
- __ addu(scratch, elements, scratch);
- uint32_t offset = FixedArray::kHeaderSize +
- (instr->additional_index() << kPointerSizeLog2);
- __ lw(result, FieldMemOperand(scratch, offset));
+ if (instr->key()->IsConstantOperand()) {
+ LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
+ offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
+ instr->additional_index());
+ store_base = elements;
+ } else {
+ Register key = EmitLoadRegister(instr->key(), scratch);
+ // Even though the HLoadKeyedFastElement instruction forces the input
+ // representation for the key to be an integer, the input gets replaced
+ // during bound check elimination with the index argument to the bounds
+ // check, which can be tagged, so that case must be handled here, too.
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
+ __ addu(scratch, elements, scratch);
+ } else {
+ __ sll(scratch, key, kPointerSizeLog2);
+ __ addu(scratch, elements, scratch);
+ }
+ offset = FixedArray::OffsetOfElementAt(instr->additional_index());
+ }
+ __ lw(result, FieldMemOperand(store_base, offset));
// Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -2550,8 +2672,9 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
DoubleRegister result = ToDoubleRegister(instr->result());
Register scratch = scratch0();
- int shift_size =
- ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+ int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+ int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
+ ? (element_size_shift - kSmiTagSize) : element_size_shift;
int constant_key = 0;
if (key_is_constant) {
constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
@@ -2564,14 +2687,15 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
if (key_is_constant) {
__ Addu(elements, elements,
- Operand(((constant_key + instr->additional_index()) << shift_size) +
+ Operand(((constant_key + instr->additional_index()) <<
+ element_size_shift) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
__ sll(scratch, key, shift_size);
__ Addu(elements, elements, Operand(scratch));
__ Addu(elements, elements,
Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
- (instr->additional_index() << shift_size)));
+ (instr->additional_index() << element_size_shift)));
}
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -2583,6 +2707,50 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
}
+MemOperand LCodeGen::PrepareKeyedOperand(Register key,
+ Register base,
+ bool key_is_constant,
+ int constant_key,
+ int element_size,
+ int shift_size,
+ int additional_index,
+ int additional_offset) {
+ if (additional_index != 0 && !key_is_constant) {
+ additional_index *= 1 << (element_size - shift_size);
+ __ Addu(scratch0(), key, Operand(additional_index));
+ }
+
+ if (key_is_constant) {
+ return MemOperand(base,
+ (constant_key << element_size) + additional_offset);
+ }
+
+ if (additional_index == 0) {
+ if (shift_size >= 0) {
+ __ sll(scratch0(), key, shift_size);
+ __ Addu(scratch0(), base, scratch0());
+ return MemOperand(scratch0());
+ } else {
+ ASSERT_EQ(-1, shift_size);
+ __ srl(scratch0(), key, 1);
+ __ Addu(scratch0(), base, scratch0());
+ return MemOperand(scratch0());
+ }
+ }
+
+ if (shift_size >= 0) {
+ __ sll(scratch0(), scratch0(), shift_size);
+ __ Addu(scratch0(), base, scratch0());
+ return MemOperand(scratch0());
+ } else {
+ ASSERT_EQ(-1, shift_size);
+ __ srl(scratch0(), scratch0(), 1);
+ __ Addu(scratch0(), base, scratch0());
+ return MemOperand(scratch0());
+ }
+}
+
+
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer());
@@ -2598,14 +2766,16 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
} else {
key = ToRegister(instr->key());
}
- int shift_size = ElementsKindToShiftSize(elements_kind);
- int additional_offset = instr->additional_index() << shift_size;
+ int element_size_shift = ElementsKindToShiftSize(elements_kind);
+ int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
+ ? (element_size_shift - kSmiTagSize) : element_size_shift;
+ int additional_offset = instr->additional_index() << element_size_shift;
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
FPURegister result = ToDoubleRegister(instr->result());
if (key_is_constant) {
- __ Addu(scratch0(), external_pointer, constant_key << shift_size);
+ __ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
} else {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), external_pointer);
@@ -2619,24 +2789,10 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
}
} else {
Register result = ToRegister(instr->result());
- Register scratch = scratch0();
- if (instr->additional_index() != 0 && !key_is_constant) {
- __ Addu(scratch, key, instr->additional_index());
- }
- MemOperand mem_operand(zero_reg);
- if (key_is_constant) {
- mem_operand =
- MemOperand(external_pointer,
- (constant_key << shift_size) + additional_offset);
- } else {
- if (instr->additional_index() == 0) {
- __ sll(scratch, key, shift_size);
- } else {
- __ sll(scratch, scratch, shift_size);
- }
- __ Addu(scratch, scratch, external_pointer);
- mem_operand = MemOperand(scratch);
- }
+ MemOperand mem_operand = PrepareKeyedOperand(
+ key, external_pointer, key_is_constant, constant_key,
+ element_size_shift, shift_size,
+ instr->additional_index(), additional_offset);
switch (elements_kind) {
case EXTERNAL_BYTE_ELEMENTS:
__ lb(result, mem_operand);
@@ -2656,11 +2812,10 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
break;
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ lw(result, mem_operand);
- // TODO(danno): we could be more clever here, perhaps having a special
- // version of the stub that detects if the overflow case actually
- // happens, and generate code that returns a double rather than int.
- DeoptimizeIf(Ugreater_equal, instr->environment(),
- result, Operand(0x80000000));
+ if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
+ DeoptimizeIf(Ugreater_equal, instr->environment(),
+ result, Operand(0x80000000));
+ }
break;
case EXTERNAL_FLOAT_ELEMENTS:
case EXTERNAL_DOUBLE_ELEMENTS:
@@ -2711,7 +2866,7 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
- Register elem = ToRegister(instr->InputAt(0));
+ Register elem = ToRegister(instr->elements());
Register result = ToRegister(instr->result());
Label done;
@@ -2829,7 +2984,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
void LCodeGen::DoPushArgument(LPushArgument* instr) {
- LOperand* argument = instr->InputAt(0);
+ LOperand* argument = instr->value();
if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
Abort("DoPushArgument not implemented for double type.");
} else {
@@ -2846,7 +3001,7 @@ void LCodeGen::DoDrop(LDrop* instr) {
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
- __ LoadHeapObject(result, instr->hydrogen()->closure());
+ __ lw(result, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
}
@@ -2875,12 +3030,12 @@ void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
Register result = ToRegister(instr->result());
- __ lw(result, ContextOperand(cp, Context::GLOBAL_INDEX));
+ __ lw(result, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
}
void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
- Register global = ToRegister(instr->global());
+ Register global = ToRegister(instr->global_object());
Register result = ToRegister(instr->result());
__ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
}
@@ -2902,14 +3057,8 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
__ LoadHeapObject(a1, function);
}
- // Change context if needed.
- bool change_context =
- (info()->closure()->context() != function->context()) ||
- scope()->contains_with() ||
- (scope()->num_heap_slots() > 0);
- if (change_context) {
- __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
- }
+ // Change context.
+ __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
// Set r0 to arguments count if adaption is not needed. Assumes that r0
// is available to write to at this point.
@@ -2947,7 +3096,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
Register scratch = scratch0();
@@ -3012,7 +3161,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
Label done;
@@ -3043,7 +3192,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
Representation r = instr->hydrogen()->value()->representation();
if (r.IsDouble()) {
- FPURegister input = ToDoubleRegister(instr->InputAt(0));
+ FPURegister input = ToDoubleRegister(instr->value());
FPURegister result = ToDoubleRegister(instr->result());
__ abs_d(result, input);
} else if (r.IsInteger32()) {
@@ -3052,7 +3201,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
// Representation is tagged.
DeferredMathAbsTaggedHeapNumber* deferred =
new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
// Smi check.
__ JumpIfNotSmi(input, deferred->entry());
// If smi, handle it directly.
@@ -3063,11 +3212,11 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
- DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister input = ToDoubleRegister(instr->value());
Register result = ToRegister(instr->result());
FPURegister single_scratch = double_scratch0().low();
Register scratch1 = scratch0();
- Register except_flag = ToRegister(instr->TempAt(0));
+ Register except_flag = ToRegister(instr->temp());
__ EmitFPUTruncate(kRoundToMinusInf,
single_scratch,
@@ -3094,7 +3243,7 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
- DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister input = ToDoubleRegister(instr->value());
Register result = ToRegister(instr->result());
Register scratch = scratch0();
Label done, check_sign_on_zero;
@@ -3171,16 +3320,16 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
- DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister input = ToDoubleRegister(instr->value());
DoubleRegister result = ToDoubleRegister(instr->result());
__ sqrt_d(result, input);
}
void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
- DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister input = ToDoubleRegister(instr->value());
DoubleRegister result = ToDoubleRegister(instr->result());
- DoubleRegister temp = ToDoubleRegister(instr->TempAt(0));
+ DoubleRegister temp = ToDoubleRegister(instr->temp());
ASSERT(!input.is(result));
@@ -3205,11 +3354,11 @@ void LCodeGen::DoPower(LPower* instr) {
Representation exponent_type = instr->hydrogen()->right()->representation();
// Having marked this as a call, we can use any registers.
// Just make sure that the input/output registers are the expected ones.
- ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
- ToDoubleRegister(instr->InputAt(1)).is(f4));
- ASSERT(!instr->InputAt(1)->IsRegister() ||
- ToRegister(instr->InputAt(1)).is(a2));
- ASSERT(ToDoubleRegister(instr->InputAt(0)).is(f2));
+ ASSERT(!instr->right()->IsDoubleRegister() ||
+ ToDoubleRegister(instr->right()).is(f4));
+ ASSERT(!instr->right()->IsRegister() ||
+ ToRegister(instr->right()).is(a2));
+ ASSERT(ToDoubleRegister(instr->left()).is(f2));
ASSERT(ToDoubleRegister(instr->result()).is(f0));
if (exponent_type.IsTagged()) {
@@ -3246,16 +3395,16 @@ void LCodeGen::DoRandom(LRandom* instr) {
// Having marked this instruction as a call we can use any
// registers.
ASSERT(ToDoubleRegister(instr->result()).is(f0));
- ASSERT(ToRegister(instr->InputAt(0)).is(a0));
+ ASSERT(ToRegister(instr->global_object()).is(a0));
static const int kSeedSize = sizeof(uint32_t);
STATIC_ASSERT(kPointerSize == kSeedSize);
- __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalContextOffset));
+ __ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset));
static const int kRandomSeedOffset =
FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
__ lw(a2, FieldMemOperand(a0, kRandomSeedOffset));
- // a2: FixedArray of the global context's random seeds
+ // a2: FixedArray of the native context's random seeds
// Load state[0].
__ lw(a1, FieldMemOperand(a2, ByteArray::kHeaderSize));
@@ -3456,7 +3605,7 @@ void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
void LCodeGen::DoCallNew(LCallNew* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(a1));
+ ASSERT(ToRegister(instr->constructor()).is(a1));
ASSERT(ToRegister(instr->result()).is(v0));
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
@@ -3482,7 +3631,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
__ li(scratch, Operand(instr->transition()));
__ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
// Update the write barrier for the map field.
__ RecordWriteField(object,
HeapObject::kMapOffset,
@@ -3544,11 +3693,47 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
}
+void LCodeGen::DeoptIfTaggedButNotSmi(LEnvironment* environment,
+ HValue* value,
+ LOperand* operand) {
+ if (value->representation().IsTagged() && !value->type().IsSmi()) {
+ if (operand->IsRegister()) {
+ __ And(at, ToRegister(operand), Operand(kSmiTagMask));
+ DeoptimizeIf(ne, environment, at, Operand(zero_reg));
+ } else {
+ __ li(at, ToOperand(operand));
+ __ And(at, at, Operand(kSmiTagMask));
+ DeoptimizeIf(ne, environment, at, Operand(zero_reg));
+ }
+ }
+}
+
+
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
- DeoptimizeIf(hs,
- instr->environment(),
- ToRegister(instr->index()),
- Operand(ToRegister(instr->length())));
+ DeoptIfTaggedButNotSmi(instr->environment(),
+ instr->hydrogen()->length(),
+ instr->length());
+ DeoptIfTaggedButNotSmi(instr->environment(),
+ instr->hydrogen()->index(),
+ instr->index());
+ if (instr->index()->IsConstantOperand()) {
+ int constant_index =
+ ToInteger32(LConstantOperand::cast(instr->index()));
+ if (instr->hydrogen()->length()->representation().IsTagged()) {
+ __ li(at, Operand(Smi::FromInt(constant_index)));
+ } else {
+ __ li(at, Operand(constant_index));
+ }
+ DeoptimizeIf(hs,
+ instr->environment(),
+ at,
+ Operand(ToRegister(instr->length())));
+ } else {
+ DeoptimizeIf(hs,
+ instr->environment(),
+ ToRegister(instr->index()),
+ Operand(ToRegister(instr->length())));
+ }
}
@@ -3557,32 +3742,38 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
Register elements = ToRegister(instr->object());
Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
Register scratch = scratch0();
+ Register store_base = scratch;
+ int offset = 0;
// Do the store.
if (instr->key()->IsConstantOperand()) {
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
- int offset =
- (ToInteger32(const_operand) + instr->additional_index()) * kPointerSize
- + FixedArray::kHeaderSize;
- __ sw(value, FieldMemOperand(elements, offset));
+ offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
+ instr->additional_index());
+ store_base = elements;
} else {
- __ sll(scratch, key, kPointerSizeLog2);
- __ addu(scratch, elements, scratch);
- if (instr->additional_index() != 0) {
- __ Addu(scratch,
- scratch,
- instr->additional_index() << kPointerSizeLog2);
+ // Even though the HLoadKeyedFastElement instruction forces the input
+ // representation for the key to be an integer, the input gets replaced
+ // during bound check elimination with the index argument to the bounds
+ // check, which can be tagged, so that case must be handled here, too.
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
+ __ addu(scratch, elements, scratch);
+ } else {
+ __ sll(scratch, key, kPointerSizeLog2);
+ __ addu(scratch, elements, scratch);
}
- __ sw(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
+ offset = FixedArray::OffsetOfElementAt(instr->additional_index());
}
+ __ sw(value, FieldMemOperand(store_base, offset));
if (instr->hydrogen()->NeedsWriteBarrier()) {
HType type = instr->hydrogen()->value()->type();
SmiCheck check_needed =
type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
// Compute address of modified element and store it into key register.
- __ Addu(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ Addu(key, store_base, Operand(offset - kHeapObjectTag));
__ RecordWrite(elements,
key,
value,
@@ -3614,9 +3805,11 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
} else {
key = ToRegister(instr->key());
}
- int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+ int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+ int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
+ ? (element_size_shift - kSmiTagSize) : element_size_shift;
if (key_is_constant) {
- __ Addu(scratch, elements, Operand((constant_key << shift_size) +
+ __ Addu(scratch, elements, Operand((constant_key << element_size_shift) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
__ sll(scratch, key, shift_size);
@@ -3637,7 +3830,8 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
}
__ bind(&not_nan);
- __ sdc1(value, MemOperand(scratch, instr->additional_index() << shift_size));
+ __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
+ element_size_shift));
}
@@ -3657,14 +3851,17 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
} else {
key = ToRegister(instr->key());
}
- int shift_size = ElementsKindToShiftSize(elements_kind);
- int additional_offset = instr->additional_index() << shift_size;
+ int element_size_shift = ElementsKindToShiftSize(elements_kind);
+ int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
+ ? (element_size_shift - kSmiTagSize) : element_size_shift;
+ int additional_offset = instr->additional_index() << element_size_shift;
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
FPURegister value(ToDoubleRegister(instr->value()));
if (key_is_constant) {
- __ Addu(scratch0(), external_pointer, constant_key << shift_size);
+ __ Addu(scratch0(), external_pointer, constant_key <<
+ element_size_shift);
} else {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), external_pointer);
@@ -3678,24 +3875,10 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
}
} else {
Register value(ToRegister(instr->value()));
- Register scratch = scratch0();
- if (instr->additional_index() != 0 && !key_is_constant) {
- __ Addu(scratch, key, instr->additional_index());
- }
- MemOperand mem_operand(zero_reg);
- if (key_is_constant) {
- mem_operand = MemOperand(external_pointer,
- ((constant_key + instr->additional_index())
- << shift_size));
- } else {
- if (instr->additional_index() == 0) {
- __ sll(scratch, key, shift_size);
- } else {
- __ sll(scratch, scratch, shift_size);
- }
- __ Addu(scratch, scratch, external_pointer);
- mem_operand = MemOperand(scratch);
- }
+ MemOperand mem_operand = PrepareKeyedOperand(
+ key, external_pointer, key_is_constant, constant_key,
+ element_size_shift, shift_size,
+ instr->additional_index(), additional_offset);
switch (elements_kind) {
case EXTERNAL_PIXEL_ELEMENTS:
case EXTERNAL_BYTE_ELEMENTS:
@@ -3740,7 +3923,7 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
Register object_reg = ToRegister(instr->object());
- Register new_map_reg = ToRegister(instr->new_map_reg());
+ Register new_map_reg = ToRegister(instr->new_map_temp());
Register scratch = scratch0();
Handle<Map> from_map = instr->original_map();
@@ -3762,7 +3945,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
scratch, kRAHasBeenSaved, kDontSaveFPRegs);
} else if (IsFastSmiElementsKind(from_kind) &&
IsFastDoubleElementsKind(to_kind)) {
- Register fixed_object_reg = ToRegister(instr->temp_reg());
+ Register fixed_object_reg = ToRegister(instr->temp());
ASSERT(fixed_object_reg.is(a2));
ASSERT(new_map_reg.is(a3));
__ mov(fixed_object_reg, object_reg);
@@ -3770,7 +3953,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
RelocInfo::CODE_TARGET, instr);
} else if (IsFastDoubleElementsKind(from_kind) &&
IsFastObjectElementsKind(to_kind)) {
- Register fixed_object_reg = ToRegister(instr->temp_reg());
+ Register fixed_object_reg = ToRegister(instr->temp());
ASSERT(fixed_object_reg.is(a2));
ASSERT(new_map_reg.is(a3));
__ mov(fixed_object_reg, object_reg);
@@ -3837,9 +4020,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
__ push(index);
}
CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
- if (FLAG_debug_code) {
- __ AbortIfNotSmi(v0);
- }
+ __ AssertSmi(v0);
__ SmiUntag(v0);
__ StoreToSafepointRegisterSlot(v0, result);
}
@@ -3895,14 +4076,14 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
void LCodeGen::DoStringLength(LStringLength* instr) {
- Register string = ToRegister(instr->InputAt(0));
+ Register string = ToRegister(instr->string());
Register result = ToRegister(instr->result());
__ lw(result, FieldMemOperand(string, String::kLengthOffset));
}
void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister() || input->IsStackSlot());
LOperand* output = instr->result();
ASSERT(output->IsDoubleRegister());
@@ -3918,18 +4099,32 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
}
+void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
+ LOperand* input = instr->value();
+ LOperand* output = instr->result();
+
+ FPURegister dbl_scratch = double_scratch0();
+ __ mtc1(ToRegister(input), dbl_scratch);
+ __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22);
+}
+
+
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
class DeferredNumberTagI: public LDeferredCode {
public:
DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
: LDeferredCode(codegen), instr_(instr) { }
- virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); }
+ virtual void Generate() {
+ codegen()->DoDeferredNumberTagI(instr_,
+ instr_->value(),
+ SIGNED_INT32);
+ }
virtual LInstruction* instr() { return instr_; }
private:
LNumberTagI* instr_;
};
- Register src = ToRegister(instr->InputAt(0));
+ Register src = ToRegister(instr->value());
Register dst = ToRegister(instr->result());
Register overflow = scratch0();
@@ -3940,25 +4135,59 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
}
-void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
+void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
+ class DeferredNumberTagU: public LDeferredCode {
+ public:
+ DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
+ : LDeferredCode(codegen), instr_(instr) { }
+ virtual void Generate() {
+ codegen()->DoDeferredNumberTagI(instr_,
+ instr_->value(),
+ UNSIGNED_INT32);
+ }
+ virtual LInstruction* instr() { return instr_; }
+ private:
+ LNumberTagU* instr_;
+ };
+
+ LOperand* input = instr->value();
+ ASSERT(input->IsRegister() && input->Equals(instr->result()));
+ Register reg = ToRegister(input);
+
+ DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
+ __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue));
+ __ SmiTag(reg, reg);
+ __ bind(deferred->exit());
+}
+
+
+void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
+ LOperand* value,
+ IntegerSignedness signedness) {
Label slow;
- Register src = ToRegister(instr->InputAt(0));
+ Register src = ToRegister(value);
Register dst = ToRegister(instr->result());
FPURegister dbl_scratch = double_scratch0();
// Preserve the value of all registers.
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
- // There was overflow, so bits 30 and 31 of the original integer
- // disagree. Try to allocate a heap number in new space and store
- // the value in there. If that fails, call the runtime system.
Label done;
- if (dst.is(src)) {
- __ SmiUntag(src, dst);
- __ Xor(src, src, Operand(0x80000000));
+ if (signedness == SIGNED_INT32) {
+ // There was overflow, so bits 30 and 31 of the original integer
+ // disagree. Try to allocate a heap number in new space and store
+ // the value in there. If that fails, call the runtime system.
+ if (dst.is(src)) {
+ __ SmiUntag(src, dst);
+ __ Xor(src, src, Operand(0x80000000));
+ }
+ __ mtc1(src, dbl_scratch);
+ __ cvt_d_w(dbl_scratch, dbl_scratch);
+ } else {
+ __ mtc1(src, dbl_scratch);
+ __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22);
}
- __ mtc1(src, dbl_scratch);
- __ cvt_d_w(dbl_scratch, dbl_scratch);
+
if (FLAG_inline_new) {
__ LoadRoot(t2, Heap::kHeapNumberMapRootIndex);
__ AllocateHeapNumber(t1, a3, t0, t2, &slow);
@@ -3995,11 +4224,11 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
LNumberTagD* instr_;
};
- DoubleRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+ DoubleRegister input_reg = ToDoubleRegister(instr->value());
Register scratch = scratch0();
Register reg = ToRegister(instr->result());
- Register temp1 = ToRegister(instr->TempAt(0));
- Register temp2 = ToRegister(instr->TempAt(1));
+ Register temp1 = ToRegister(instr->temp());
+ Register temp2 = ToRegister(instr->temp2());
DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
if (FLAG_inline_new) {
@@ -4028,13 +4257,13 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
void LCodeGen::DoSmiTag(LSmiTag* instr) {
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
- __ SmiTag(ToRegister(instr->result()), ToRegister(instr->InputAt(0)));
+ __ SmiTag(ToRegister(instr->result()), ToRegister(instr->value()));
}
void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
Register scratch = scratch0();
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
if (instr->needs_check()) {
STATIC_ASSERT(kHeapObjectTag == 1);
@@ -4099,9 +4328,9 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
- Register input_reg = ToRegister(instr->InputAt(0));
+ Register input_reg = ToRegister(instr->value());
Register scratch1 = scratch0();
- Register scratch2 = ToRegister(instr->TempAt(0));
+ Register scratch2 = ToRegister(instr->temp());
DoubleRegister double_scratch = double_scratch0();
FPURegister single_scratch = double_scratch.low();
@@ -4118,8 +4347,8 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
// of the if.
if (instr->truncating()) {
- Register scratch3 = ToRegister(instr->TempAt(1));
- DoubleRegister double_scratch2 = ToDoubleRegister(instr->TempAt(2));
+ Register scratch3 = ToRegister(instr->temp2());
+ DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp3());
ASSERT(!scratch3.is(input_reg) &&
!scratch3.is(scratch1) &&
!scratch3.is(scratch2));
@@ -4189,7 +4418,7 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
LTaggedToI* instr_;
};
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
ASSERT(input->Equals(instr->result()));
@@ -4207,7 +4436,7 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
LOperand* result = instr->result();
ASSERT(result->IsDoubleRegister());
@@ -4225,12 +4454,12 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
Register result_reg = ToRegister(instr->result());
Register scratch1 = scratch0();
- Register scratch2 = ToRegister(instr->TempAt(0));
- DoubleRegister double_input = ToDoubleRegister(instr->InputAt(0));
+ Register scratch2 = ToRegister(instr->temp());
+ DoubleRegister double_input = ToDoubleRegister(instr->value());
FPURegister single_scratch = double_scratch0().low();
if (instr->truncating()) {
- Register scratch3 = ToRegister(instr->TempAt(1));
+ Register scratch3 = ToRegister(instr->temp2());
__ EmitECMATruncate(result_reg,
double_input,
single_scratch,
@@ -4257,21 +4486,21 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
__ And(at, ToRegister(input), Operand(kSmiTagMask));
DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg));
}
void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
__ And(at, ToRegister(input), Operand(kSmiTagMask));
DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
}
void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register scratch = scratch0();
__ GetObjectType(input, scratch, scratch);
@@ -4341,7 +4570,7 @@ void LCodeGen::DoCheckMapCommon(Register reg,
void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
Register scratch = scratch0();
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
Label success;
@@ -4360,7 +4589,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
Register result_reg = ToRegister(instr->result());
- DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0));
+ DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
__ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
}
@@ -4376,7 +4605,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
Register scratch = scratch0();
Register input_reg = ToRegister(instr->unclamped());
Register result_reg = ToRegister(instr->result());
- DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0));
+ DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
Label is_smi, done, heap_number;
// Both smi and heap number cases are handled.
@@ -4408,8 +4637,8 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
- Register temp1 = ToRegister(instr->TempAt(0));
- Register temp2 = ToRegister(instr->TempAt(1));
+ Register temp1 = ToRegister(instr->temp());
+ Register temp2 = ToRegister(instr->temp2());
Handle<JSObject> holder = instr->holder();
Handle<JSObject> current_prototype = instr->prototype();
@@ -4450,8 +4679,8 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
new(zone()) DeferredAllocateObject(this, instr);
Register result = ToRegister(instr->result());
- Register scratch = ToRegister(instr->TempAt(0));
- Register scratch2 = ToRegister(instr->TempAt(1));
+ Register scratch = ToRegister(instr->temp());
+ Register scratch2 = ToRegister(instr->temp2());
Handle<JSFunction> constructor = instr->hydrogen()->constructor();
Handle<Map> initial_map(constructor->initial_map());
int instance_size = initial_map->instance_size();
@@ -4519,7 +4748,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
- Heap* heap = isolate()->heap();
+ Handle<FixedArray> literals(instr->environment()->closure()->literals());
ElementsKind boilerplate_elements_kind =
instr->hydrogen()->boilerplate_elements_kind();
@@ -4540,12 +4769,13 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
a2,
Operand(boilerplate_elements_kind));
}
- __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset));
+
+ // Set up the parameters to the stub/runtime call.
+ __ LoadHeapObject(a3, literals);
__ li(a2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
// Boilerplate already exists, constant elements are never accessed.
// Pass an empty fixed array.
- __ li(a1, Operand(Handle<FixedArray>(heap->empty_fixed_array())));
+ __ li(a1, Operand(isolate()->factory()->empty_fixed_array()));
__ Push(a3, a2, a1);
// Pick the right runtime function or stub to call.
@@ -4640,8 +4870,8 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
for (int i = 0; i < elements_length; i++) {
int64_t value = double_array->get_representation(i);
// We only support little endian mode...
- int32_t value_low = value & 0xFFFFFFFF;
- int32_t value_high = value >> 32;
+ int32_t value_low = static_cast<int32_t>(value & 0xFFFFFFFF);
+ int32_t value_high = static_cast<int32_t>(value >> 32);
int total_offset =
elements_offset + FixedDoubleArray::OffsetOfElementAt(i);
__ li(a2, Operand(value_low));
@@ -4746,7 +4976,7 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(a0));
+ ASSERT(ToRegister(instr->value()).is(a0));
ASSERT(ToRegister(instr->result()).is(v0));
__ push(a0);
CallRuntime(Runtime::kToFastProperties, 1, instr);
@@ -4756,15 +4986,13 @@ void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
Label materialized;
// Registers will be used as follows:
- // a3 = JS function.
// t3 = literals array.
// a1 = regexp literal.
// a0 = regexp literal clone.
// a2 and t0-t2 are used as temporaries.
- __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ lw(t3, FieldMemOperand(a3, JSFunction::kLiteralsOffset));
- int literal_offset = FixedArray::kHeaderSize +
- instr->hydrogen()->literal_index() * kPointerSize;
+ int literal_offset =
+ FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+ __ LoadHeapObject(t3, instr->hydrogen()->literals());
__ lw(a1, FieldMemOperand(t3, literal_offset));
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ Branch(&materialized, ne, a1, Operand(at));
@@ -4830,14 +5058,14 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
void LCodeGen::DoTypeof(LTypeof* instr) {
ASSERT(ToRegister(instr->result()).is(v0));
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
__ push(input);
CallRuntime(Runtime::kTypeof, 1, instr);
}
void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* true_label = chunk_->GetAssemblyLabel(true_block);
@@ -4964,7 +5192,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
- Register temp1 = ToRegister(instr->TempAt(0));
+ Register temp1 = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -5163,12 +5391,21 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
Register map = ToRegister(instr->map());
Register result = ToRegister(instr->result());
+ Label load_cache, done;
+ __ EnumLength(result, map);
+ __ Branch(&load_cache, ne, result, Operand(Smi::FromInt(0)));
+ __ li(result, Operand(isolate()->factory()->empty_fixed_array()));
+ __ jmp(&done);
+
+ __ bind(&load_cache);
__ LoadInstanceDescriptors(map, result);
__ lw(result,
- FieldMemOperand(result, DescriptorArray::kEnumerationIndexOffset));
+ FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
__ lw(result,
FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg));
+
+ __ bind(&done);
}
diff --git a/deps/v8/src/mips/lithium-codegen-mips.h b/deps/v8/src/mips/lithium-codegen-mips.h
index 32a696bc3..38c5255a4 100644
--- a/deps/v8/src/mips/lithium-codegen-mips.h
+++ b/deps/v8/src/mips/lithium-codegen-mips.h
@@ -43,26 +43,25 @@ class SafepointGenerator;
class LCodeGen BASE_EMBEDDED {
public:
- LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info,
- Zone* zone)
- : chunk_(chunk),
+ LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
+ : zone_(info->zone()),
+ chunk_(static_cast<LPlatformChunk*>(chunk)),
masm_(assembler),
info_(info),
current_block_(-1),
current_instruction_(-1),
instructions_(chunk->instructions()),
- deoptimizations_(4, zone),
- deopt_jump_table_(4, zone),
- deoptimization_literals_(8, zone),
+ deoptimizations_(4, info->zone()),
+ deopt_jump_table_(4, info->zone()),
+ deoptimization_literals_(8, info->zone()),
inlined_function_count_(0),
scope_(info->scope()),
status_(UNUSED),
- translations_(zone),
- deferred_(8, zone),
+ translations_(info->zone()),
+ deferred_(8, info->zone()),
osr_pc_offset_(-1),
last_lazy_deopt_pc_(0),
- safepoints_(zone),
- zone_(zone),
+ safepoints_(info->zone()),
resolver_(this),
expected_safepoint_kind_(Safepoint::kSimple) {
PopulateDeoptimizationLiteralsWithInlinedFunctions();
@@ -111,7 +110,12 @@ class LCodeGen BASE_EMBEDDED {
void FinishCode(Handle<Code> code);
void DoDeferredNumberTagD(LNumberTagD* instr);
- void DoDeferredNumberTagI(LNumberTagI* instr);
+
+ enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
+ void DoDeferredNumberTagI(LInstruction* instr,
+ LOperand* value,
+ IntegerSignedness signedness);
+
void DoDeferredTaggedToI(LTaggedToI* instr);
void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
void DoDeferredStackCheck(LStackCheck* instr);
@@ -129,8 +133,20 @@ class LCodeGen BASE_EMBEDDED {
void DoParallelMove(LParallelMove* move);
void DoGap(LGap* instr);
+ MemOperand PrepareKeyedOperand(Register key,
+ Register base,
+ bool key_is_constant,
+ int constant_key,
+ int element_size,
+ int shift_size,
+ int additional_index,
+ int additional_offset);
+
// Emit frame translation commands for an environment.
- void WriteTranslation(LEnvironment* environment, Translation* translation);
+ void WriteTranslation(LEnvironment* environment,
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count);
// Declare methods that deal with the individual node types.
#define DECLARE_DO(type) void Do##type(L##type* node);
@@ -154,7 +170,7 @@ class LCodeGen BASE_EMBEDDED {
return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
}
- LChunk* chunk() const { return chunk_; }
+ LPlatformChunk* chunk() const { return chunk_; }
Scope* scope() const { return scope_; }
HGraph* graph() const { return chunk_->graph(); }
@@ -175,7 +191,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
int GetParameterCount() const { return scope()->num_parameters(); }
- void Abort(const char* format, ...);
+ void Abort(const char* reason);
void Comment(const char* format, ...);
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
@@ -244,7 +260,10 @@ class LCodeGen BASE_EMBEDDED {
void AddToTranslation(Translation* translation,
LOperand* op,
- bool is_tagged);
+ bool is_tagged,
+ bool is_uint32,
+ int arguments_index,
+ int arguments_count);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
@@ -299,6 +318,10 @@ class LCodeGen BASE_EMBEDDED {
bool deoptimize_on_minus_zero,
LEnvironment* env);
+ void DeoptIfTaggedButNotSmi(LEnvironment* environment,
+ HValue* value,
+ LOperand* operand);
+
// Emits optimized code for typeof x == "y". Modifies input register.
// Returns the condition on which a final split to
// true and false label should be made, to optimize fallthrough.
@@ -354,7 +377,8 @@ class LCodeGen BASE_EMBEDDED {
void EnsureSpaceForLazyDeopt();
- LChunk* const chunk_;
+ Zone* zone_;
+ LPlatformChunk* const chunk_;
MacroAssembler* const masm_;
CompilationInfo* const info_;
@@ -376,8 +400,6 @@ class LCodeGen BASE_EMBEDDED {
// itself is emitted at the end of the generated code.
SafepointTableBuilder safepoints_;
- Zone* zone_;
-
// Compiler from a set of parallel moves to a sequential list of moves.
LGapResolver resolver_;
diff --git a/deps/v8/src/mips/lithium-mips.cc b/deps/v8/src/mips/lithium-mips.cc
index 842001ddf..0b6dcaea5 100644
--- a/deps/v8/src/mips/lithium-mips.cc
+++ b/deps/v8/src/mips/lithium-mips.cc
@@ -194,22 +194,22 @@ void LGoto::PrintDataTo(StringStream* stream) {
void LBranch::PrintDataTo(StringStream* stream) {
stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
- InputAt(0)->PrintTo(stream);
+ left()->PrintTo(stream);
stream->Add(" %s ", Token::String(op()));
- InputAt(1)->PrintTo(stream);
+ right()->PrintTo(stream);
stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
}
void LIsNilAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(kind() == kStrictEquality ? " === " : " == ");
stream->Add(nil() == kNullValue ? "null" : "undefined");
stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
@@ -218,57 +218,57 @@ void LIsNilAndBranch::PrintDataTo(StringStream* stream) {
void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_object(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsStringAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_string(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_smi(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsUndetectableAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_undetectable(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LStringCompareAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if string_compare(");
- InputAt(0)->PrintTo(stream);
- InputAt(1)->PrintTo(stream);
+ left()->PrintTo(stream);
+ right()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if has_instance_type(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if has_cached_array_index(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if class_of_test(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(", \"%o\") then B%d else B%d",
*hydrogen()->class_name(),
true_block_id(),
@@ -278,7 +278,7 @@ void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if typeof ");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(" == \"%s\" then B%d else B%d",
*hydrogen()->type_literal()->ToCString(),
true_block_id(), false_block_id());
@@ -292,26 +292,26 @@ void LCallConstantFunction::PrintDataTo(StringStream* stream) {
void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
stream->Add("/%s ", hydrogen()->OpName());
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LLoadContextSlot::PrintDataTo(StringStream* stream) {
- InputAt(0)->PrintTo(stream);
+ context()->PrintTo(stream);
stream->Add("[%d]", slot_index());
}
void LStoreContextSlot::PrintDataTo(StringStream* stream) {
- InputAt(0)->PrintTo(stream);
+ context()->PrintTo(stream);
stream->Add("[%d] <- ", slot_index());
- InputAt(1)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LInvokeFunction::PrintDataTo(StringStream* stream) {
stream->Add("= ");
- InputAt(0)->PrintTo(stream);
+ function()->PrintTo(stream);
stream->Add(" #%d / ", arity());
}
@@ -340,17 +340,15 @@ void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
void LCallNew::PrintDataTo(StringStream* stream) {
stream->Add("= ");
- InputAt(0)->PrintTo(stream);
+ constructor()->PrintTo(stream);
stream->Add(" #%d / ", arity());
}
void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
arguments()->PrintTo(stream);
-
stream->Add(" length ");
length()->PrintTo(stream);
-
stream->Add(" index ");
index()->PrintTo(stream);
}
@@ -407,24 +405,14 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) {
}
-LChunk::LChunk(CompilationInfo* info, HGraph* graph)
- : spill_slot_count_(0),
- info_(info),
- graph_(graph),
- instructions_(32, graph->zone()),
- pointer_maps_(8, graph->zone()),
- inlined_closures_(1, graph->zone()) {
-}
-
-
-int LChunk::GetNextSpillIndex(bool is_double) {
+int LPlatformChunk::GetNextSpillIndex(bool is_double) {
// Skip a slot if for a double-width slot.
if (is_double) spill_slot_count_++;
return spill_slot_count_++;
}
-LOperand* LChunk::GetNextSpillSlot(bool is_double) {
+LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) {
int index = GetNextSpillIndex(is_double);
if (is_double) {
return LDoubleStackSlot::Create(index, zone());
@@ -434,120 +422,9 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) {
}
-void LChunk::MarkEmptyBlocks() {
- HPhase phase("L_Mark empty blocks", this);
- for (int i = 0; i < graph()->blocks()->length(); ++i) {
- HBasicBlock* block = graph()->blocks()->at(i);
- int first = block->first_instruction_index();
- int last = block->last_instruction_index();
- LInstruction* first_instr = instructions()->at(first);
- LInstruction* last_instr = instructions()->at(last);
-
- LLabel* label = LLabel::cast(first_instr);
- if (last_instr->IsGoto()) {
- LGoto* goto_instr = LGoto::cast(last_instr);
- if (label->IsRedundant() &&
- !label->is_loop_header()) {
- bool can_eliminate = true;
- for (int i = first + 1; i < last && can_eliminate; ++i) {
- LInstruction* cur = instructions()->at(i);
- if (cur->IsGap()) {
- LGap* gap = LGap::cast(cur);
- if (!gap->IsRedundant()) {
- can_eliminate = false;
- }
- } else {
- can_eliminate = false;
- }
- }
-
- if (can_eliminate) {
- label->set_replacement(GetLabel(goto_instr->block_id()));
- }
- }
- }
- }
-}
-
-
-void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
- LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
- int index = -1;
- if (instr->IsControl()) {
- instructions_.Add(gap, zone());
- index = instructions_.length();
- instructions_.Add(instr, zone());
- } else {
- index = instructions_.length();
- instructions_.Add(instr, zone());
- instructions_.Add(gap, zone());
- }
- if (instr->HasPointerMap()) {
- pointer_maps_.Add(instr->pointer_map(), zone());
- instr->pointer_map()->set_lithium_position(index);
- }
-}
-
-
-LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
- return LConstantOperand::Create(constant->id(), zone());
-}
-
-
-int LChunk::GetParameterStackSlot(int index) const {
- // The receiver is at index 0, the first parameter at index 1, so we
- // shift all parameter indexes down by the number of parameters, and
- // make sure they end up negative so they are distinguishable from
- // spill slots.
- int result = index - info()->scope()->num_parameters() - 1;
- ASSERT(result < 0);
- return result;
-}
-
-// A parameter relative to ebp in the arguments stub.
-int LChunk::ParameterAt(int index) {
- ASSERT(-1 <= index); // -1 is the receiver.
- return (1 + info()->scope()->num_parameters() - index) *
- kPointerSize;
-}
-
-
-LGap* LChunk::GetGapAt(int index) const {
- return LGap::cast(instructions_[index]);
-}
-
-
-bool LChunk::IsGapAt(int index) const {
- return instructions_[index]->IsGap();
-}
-
-
-int LChunk::NearestGapPos(int index) const {
- while (!IsGapAt(index)) index--;
- return index;
-}
-
-
-void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
- GetGapAt(index)->GetOrCreateParallelMove(
- LGap::START, zone())->AddMove(from, to, zone());
-}
-
-
-Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
- return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
-}
-
-
-Representation LChunk::LookupLiteralRepresentation(
- LConstantOperand* operand) const {
- return graph_->LookupValue(operand->index())->representation();
-}
-
-
-LChunk* LChunkBuilder::Build() {
+LPlatformChunk* LChunkBuilder::Build() {
ASSERT(is_unused());
- chunk_ = new(zone()) LChunk(info(), graph());
+ chunk_ = new(zone()) LPlatformChunk(info(), graph());
HPhase phase("L_Building chunk", chunk_);
status_ = BUILDING;
const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
@@ -562,17 +439,8 @@ LChunk* LChunkBuilder::Build() {
}
-void LChunkBuilder::Abort(const char* format, ...) {
- if (FLAG_trace_bailout) {
- SmartArrayPointer<char> name(
- info()->shared_info()->DebugName()->ToCString());
- PrintF("Aborting LChunk building in @\"%s\": ", *name);
- va_list arguments;
- va_start(arguments, format);
- OS::VPrint(format, arguments);
- va_end(arguments);
- PrintF("\n");
- }
+void LCodeGen::Abort(const char* reason) {
+ info()->set_bailout_reason(reason);
status_ = ABORTED;
}
@@ -741,7 +609,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
ASSERT(hinstr->next()->IsSimulate());
HSimulate* sim = HSimulate::cast(hinstr->next());
ASSERT(instruction_pending_deoptimization_environment_ == NULL);
- ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
+ ASSERT(pending_deoptimization_ast_id_.IsNone());
instruction_pending_deoptimization_environment_ = instr;
pending_deoptimization_ast_id_ = sim->ast_id();
}
@@ -834,15 +702,20 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
right = UseRegisterAtStart(right_value);
}
- // Shift operations can only deoptimize if we do a logical shift
- // by 0 and the result cannot be truncated to int32.
- bool may_deopt = (op == Token::SHR && constant_value == 0);
bool does_deopt = false;
- if (may_deopt) {
- for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
- if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
- does_deopt = true;
- break;
+
+ if (FLAG_opt_safe_uint32_operations) {
+ does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+ } else {
+ // Shift operations can only deoptimize if we do a logical shift
+ // by 0 and the result cannot be truncated to int32.
+ bool may_deopt = (op == Token::SHR && constant_value == 0);
+ if (may_deopt) {
+ for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
+ if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
+ does_deopt = true;
+ break;
+ }
}
}
}
@@ -975,8 +848,8 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
LEnvironment* outer =
CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator);
- int ast_id = hydrogen_env->ast_id();
- ASSERT(ast_id != AstNode::kNoNumber ||
+ BailoutId ast_id = hydrogen_env->ast_id();
+ ASSERT(!ast_id.IsNone() ||
hydrogen_env->frame_type() != JS_FUNCTION);
int value_count = hydrogen_env->length();
LEnvironment* result = new(zone()) LEnvironment(
@@ -987,6 +860,7 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
argument_count_,
value_count,
outer,
+ hydrogen_env->entry(),
zone());
int argument_index = *argument_index_accumulator;
for (int i = 0; i < value_count; ++i) {
@@ -1001,7 +875,9 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
} else {
op = UseAny(value);
}
- result->AddValue(op, value->representation());
+ result->AddValue(op,
+ value->representation(),
+ value->CheckFlag(HInstruction::kUint32));
}
if (hydrogen_env->frame_type() == JS_FUNCTION) {
@@ -1417,6 +1293,25 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
+LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
+ LOperand* left = NULL;
+ LOperand* right = NULL;
+ if (instr->representation().IsInteger32()) {
+ ASSERT(instr->left()->representation().IsInteger32());
+ ASSERT(instr->right()->representation().IsInteger32());
+ left = UseRegisterAtStart(instr->LeastConstantOperand());
+ right = UseOrConstantAtStart(instr->MostConstantOperand());
+ } else {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->left()->representation().IsDouble());
+ ASSERT(instr->right()->representation().IsDouble());
+ left = UseRegisterAtStart(instr->left());
+ right = UseRegisterAtStart(instr->right());
+ }
+ return DefineAsRegister(new(zone()) LMathMinMax(left, right));
+}
+
+
LInstruction* LChunkBuilder::DoPower(HPower* instr) {
ASSERT(instr->representation().IsDouble());
// We call a C function for double power. It can't trigger a GC.
@@ -1582,6 +1477,12 @@ LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
}
+LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
+ LOperand* map = UseRegisterAtStart(instr->value());
+ return DefineAsRegister(new(zone()) LMapEnumLength(map));
+}
+
+
LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
LOperand* object = UseRegisterAtStart(instr->value());
return DefineAsRegister(new(zone()) LElementsKind(object));
@@ -1599,12 +1500,12 @@ LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
LOperand* object = UseFixed(instr->value(), a0);
LDateField* result =
new(zone()) LDateField(object, FixedTemp(a1), instr->index());
- return MarkAsCall(DefineFixed(result, v0), instr);
+ return MarkAsCall(DefineFixed(result, v0), instr, CAN_DEOPTIMIZE_EAGERLY);
}
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
- LOperand* value = UseRegisterAtStart(instr->index());
+ LOperand* value = UseRegisterOrConstantAtStart(instr->index());
LOperand* length = UseRegister(instr->length());
return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
}
@@ -1688,7 +1589,10 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
if (to.IsTagged()) {
HValue* val = instr->value();
LOperand* value = UseRegisterAtStart(val);
- if (val->HasRange() && val->range()->IsInSmiRange()) {
+ if (val->CheckFlag(HInstruction::kUint32)) {
+ LNumberTagU* result = new(zone()) LNumberTagU(value);
+ return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
+ } else if (val->HasRange() && val->range()->IsInSmiRange()) {
return DefineAsRegister(new(zone()) LSmiTag(value));
} else {
LNumberTagI* result = new(zone()) LNumberTagI(value);
@@ -1696,8 +1600,13 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
}
} else {
ASSERT(to.IsDouble());
- LOperand* value = Use(instr->value());
- return DefineAsRegister(new(zone()) LInteger32ToDouble(value));
+ if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+ return DefineAsRegister(
+ new(zone()) LUint32ToDouble(UseRegister(instr->value())));
+ } else {
+ return DefineAsRegister(
+ new(zone()) LInteger32ToDouble(Use(instr->value())));
+ }
}
}
UNREACHABLE();
@@ -1894,9 +1803,10 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
HLoadKeyedFastElement* instr) {
ASSERT(instr->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* obj = UseRegisterAtStart(instr->object());
- LOperand* key = UseRegisterAtStart(instr->key());
+ LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key);
if (instr->RequiresHoleCheck()) AssignEnvironment(result);
return DefineAsRegister(result);
@@ -1906,7 +1816,8 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
HLoadKeyedFastDoubleElement* instr) {
ASSERT(instr->representation().IsDouble());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* elements = UseTempRegister(instr->elements());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastDoubleElement* result =
@@ -1918,15 +1829,15 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
HLoadKeyedSpecializedArrayElement* instr) {
ElementsKind elements_kind = instr->elements_kind();
- Representation representation(instr->representation());
ASSERT(
- (representation.IsInteger32() &&
+ (instr->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
- (representation.IsDouble() &&
+ (instr->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* key = UseRegisterOrConstant(instr->key());
LLoadKeyedSpecializedArrayElement* result =
@@ -1954,7 +1865,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
bool needs_write_barrier = instr->NeedsWriteBarrier();
ASSERT(instr->value()->representation().IsTagged());
ASSERT(instr->object()->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* obj = UseTempRegister(instr->object());
LOperand* val = needs_write_barrier
@@ -1971,7 +1883,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
HStoreKeyedFastDoubleElement* instr) {
ASSERT(instr->value()->representation().IsDouble());
ASSERT(instr->elements()->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* elements = UseRegisterAtStart(instr->elements());
LOperand* val = UseTempRegister(instr->value());
@@ -1983,17 +1896,17 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
HStoreKeyedSpecializedArrayElement* instr) {
- Representation representation(instr->value()->representation());
ElementsKind elements_kind = instr->elements_kind();
ASSERT(
- (representation.IsInteger32() &&
+ (instr->value()->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
- (representation.IsDouble() &&
+ (instr->value()->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer());
bool val_is_temp_register =
@@ -2152,6 +2065,7 @@ LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
+ ASSERT(argument_count_ == 0);
allocator_->MarkAsOsrEntry();
current_block_->last_environment()->set_ast_id(instr->ast_id());
return AssignEnvironment(new(zone()) LOsrEntry);
@@ -2190,12 +2104,10 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
- LOperand* arguments = UseRegister(instr->arguments());
+ LOperand* args = UseRegister(instr->arguments());
LOperand* length = UseTempRegister(instr->length());
LOperand* index = UseRegister(instr->index());
- LAccessArgumentsAt* result =
- new(zone()) LAccessArgumentsAt(arguments, length, index);
- return AssignEnvironment(DefineAsRegister(result));
+ return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
}
@@ -2249,7 +2161,7 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
instruction_pending_deoptimization_environment_->
SetDeferredLazyDeoptimizationEnvironment(result->environment());
instruction_pending_deoptimization_environment_ = NULL;
- pending_deoptimization_ast_id_ = AstNode::kNoNumber;
+ pending_deoptimization_ast_id_ = BailoutId::None();
return result;
}
@@ -2275,10 +2187,11 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
instr->function(),
undefined,
instr->call_kind(),
- instr->is_construct());
+ instr->inlining_kind());
if (instr->arguments_var() != NULL) {
inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
}
+ inner->set_entry(instr);
current_block_->UpdateEnvironment(inner);
chunk_->AddInlinedClosure(instr->closure());
return NULL;
@@ -2290,7 +2203,7 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
HEnvironment* env = current_block_->last_environment();
- if (instr->arguments_pushed()) {
+ if (env->entry()->arguments_pushed()) {
int argument_count = env->arguments_environment()->parameter_count();
pop = new(zone()) LDrop(argument_count);
argument_count_ -= argument_count;
@@ -2321,8 +2234,7 @@ LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
LOperand* map = UseRegister(instr->map());
- return AssignEnvironment(DefineAsRegister(
- new(zone()) LForInCacheArray(map)));
+ return AssignEnvironment(DefineAsRegister(new(zone()) LForInCacheArray(map)));
}
diff --git a/deps/v8/src/mips/lithium-mips.h b/deps/v8/src/mips/lithium-mips.h
index e21c921ee..3a9aa7acc 100644
--- a/deps/v8/src/mips/lithium-mips.h
+++ b/deps/v8/src/mips/lithium-mips.h
@@ -108,6 +108,7 @@ class LCodeGen;
V(InstanceOfKnownGlobal) \
V(InstructionGap) \
V(Integer32ToDouble) \
+ V(Uint32ToDouble) \
V(InvokeFunction) \
V(IsConstructCallAndBranch) \
V(IsNilAndBranch) \
@@ -115,7 +116,6 @@ class LCodeGen;
V(IsStringAndBranch) \
V(IsSmiAndBranch) \
V(IsUndetectableAndBranch) \
- V(StringCompareAndBranch) \
V(JSArrayLength) \
V(Label) \
V(LazyBailout) \
@@ -132,10 +132,13 @@ class LCodeGen;
V(LoadNamedField) \
V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
+ V(MapEnumLength) \
+ V(MathMinMax) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
V(NumberTagI) \
+ V(NumberTagU) \
V(NumberUntagD) \
V(ObjectLiteral) \
V(OsrEntry) \
@@ -162,6 +165,7 @@ class LCodeGen;
V(StringAdd) \
V(StringCharCodeAt) \
V(StringCharFromCode) \
+ V(StringCompareAndBranch) \
V(StringLength) \
V(SubI) \
V(TaggedToI) \
@@ -255,11 +259,6 @@ class LInstruction: public ZoneObject {
virtual bool HasResult() const = 0;
virtual LOperand* result() = 0;
- virtual int InputCount() = 0;
- virtual LOperand* InputAt(int i) = 0;
- virtual int TempCount() = 0;
- virtual LOperand* TempAt(int i) = 0;
-
LOperand* FirstInput() { return InputAt(0); }
LOperand* Output() { return HasResult() ? result() : NULL; }
@@ -268,6 +267,15 @@ class LInstruction: public ZoneObject {
#endif
private:
+ // Iterator interface.
+ friend class InputIterator;
+ virtual int InputCount() = 0;
+ virtual LOperand* InputAt(int i) = 0;
+
+ friend class TempIterator;
+ virtual int TempCount() = 0;
+ virtual LOperand* TempAt(int i) = 0;
+
LEnvironment* environment_;
SetOncePointer<LPointerMap> pointer_map_;
HValue* hydrogen_value_;
@@ -288,16 +296,17 @@ class LTemplateInstruction: public LInstruction {
void set_result(LOperand* operand) { results_[0] = operand; }
LOperand* result() { return results_[0]; }
- int InputCount() { return I; }
- LOperand* InputAt(int i) { return inputs_[i]; }
-
- int TempCount() { return T; }
- LOperand* TempAt(int i) { return temps_[i]; }
-
protected:
EmbeddedContainer<LOperand*, R> results_;
EmbeddedContainer<LOperand*, I> inputs_;
EmbeddedContainer<LOperand*, T> temps_;
+
+ private:
+ virtual int InputCount() { return I; }
+ virtual LOperand* InputAt(int i) { return inputs_[i]; }
+
+ virtual int TempCount() { return T; }
+ virtual LOperand* TempAt(int i) { return temps_[i]; }
};
@@ -515,6 +524,8 @@ class LArgumentsLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = elements;
}
+ LOperand* elements() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
};
@@ -541,16 +552,22 @@ class LModI: public LTemplateInstruction<1, 2, 3> {
// Used for the standard case.
LModI(LOperand* left,
LOperand* right,
- LOperand* temp1,
+ LOperand* temp,
LOperand* temp2,
LOperand* temp3) {
inputs_[0] = left;
inputs_[1] = right;
- temps_[0] = temp1;
+ temps_[0] = temp;
temps_[1] = temp2;
temps_[2] = temp3;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+ LOperand* temp3() { return temps_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
DECLARE_HYDROGEN_ACCESSOR(Mod)
};
@@ -563,6 +580,9 @@ class LDivI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(Div)
};
@@ -576,6 +596,10 @@ class LMulI: public LTemplateInstruction<1, 2, 1> {
temps_[0] = temp;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
DECLARE_HYDROGEN_ACCESSOR(Mul)
};
@@ -588,6 +612,9 @@ class LCmpIDAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
@@ -607,6 +634,9 @@ class LUnaryMathOperation: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
@@ -622,6 +652,9 @@ class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch,
"cmp-object-eq-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch)
@@ -634,6 +667,8 @@ class LCmpConstantEqAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = left;
}
+ LOperand* left() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpConstantEqAndBranch,
"cmp-constant-eq-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareConstantEqAndBranch)
@@ -646,6 +681,8 @@ class LIsNilAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch, "is-nil-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsNilAndBranch)
@@ -663,6 +700,9 @@ class LIsObjectAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
@@ -677,6 +717,9 @@ class LIsStringAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
@@ -690,6 +733,8 @@ class LIsSmiAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
@@ -704,6 +749,9 @@ class LIsUndetectableAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
"is-undetectable-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
@@ -719,6 +767,9 @@ class LStringCompareAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
"string-compare-and-branch")
DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
@@ -735,6 +786,8 @@ class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
"has-instance-type-and-branch")
DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
@@ -749,6 +802,8 @@ class LGetCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
};
@@ -760,6 +815,8 @@ class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
"has-cached-array-index-and-branch")
DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
@@ -775,6 +832,9 @@ class LClassOfTestAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
"class-of-test-and-branch")
DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
@@ -790,6 +850,9 @@ class LCmpT: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
@@ -804,6 +867,9 @@ class LInstanceOf: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
};
@@ -815,6 +881,9 @@ class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
"instance-of-known-global")
DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
@@ -843,6 +912,7 @@ class LBoundsCheck: public LTemplateInstruction<0, 2, 0> {
LOperand* length() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
+ DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
};
@@ -853,6 +923,9 @@ class LBitI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
Token::Value op() const { return hydrogen()->op(); }
DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
@@ -869,7 +942,8 @@ class LShiftI: public LTemplateInstruction<1, 2, 0> {
}
Token::Value op() const { return op_; }
-
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
bool can_deopt() const { return can_deopt_; }
DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
@@ -887,6 +961,9 @@ class LSubI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
DECLARE_HYDROGEN_ACCESSOR(Sub)
};
@@ -925,6 +1002,8 @@ class LBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
DECLARE_HYDROGEN_ACCESSOR(Branch)
@@ -939,6 +1018,9 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMap)
@@ -960,6 +1042,8 @@ class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
};
@@ -971,18 +1055,34 @@ class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength,
"fixed-array-base-length")
DECLARE_HYDROGEN_ACCESSOR(FixedArrayBaseLength)
};
+class LMapEnumLength: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LMapEnumLength(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
+};
+
+
class LElementsKind: public LTemplateInstruction<1, 1, 0> {
public:
explicit LElementsKind(LOperand* value) {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
};
@@ -995,6 +1095,9 @@ class LValueOf: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
DECLARE_HYDROGEN_ACCESSOR(ValueOf)
};
@@ -1007,9 +1110,12 @@ class LDateField: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* date() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ Smi* index() const { return index_; }
+
DECLARE_CONCRETE_INSTRUCTION(ValueOf, "date-field")
DECLARE_HYDROGEN_ACCESSOR(ValueOf)
- Smi* index() const { return index_; }
private:
Smi* index_;
@@ -1022,6 +1128,8 @@ class LThrow: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
};
@@ -1032,6 +1140,8 @@ class LBitNotI: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
};
@@ -1043,11 +1153,29 @@ class LAddI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
DECLARE_HYDROGEN_ACCESSOR(Add)
};
+class LMathMinMax: public LTemplateInstruction<1, 2, 0> {
+ public:
+ LMathMinMax(LOperand* left, LOperand* right) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ }
+
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "min-max")
+ DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
+};
+
+
class LPower: public LTemplateInstruction<1, 2, 0> {
public:
LPower(LOperand* left, LOperand* right) {
@@ -1055,6 +1183,9 @@ class LPower: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(Power, "power")
DECLARE_HYDROGEN_ACCESSOR(Power)
};
@@ -1066,6 +1197,8 @@ class LRandom: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = global_object;
}
+ LOperand* global_object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Random, "random")
DECLARE_HYDROGEN_ACCESSOR(Random)
};
@@ -1080,6 +1213,8 @@ class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
}
Token::Value op() const { return op_; }
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
virtual Opcode opcode() const { return LInstruction::kArithmeticD; }
virtual void CompileToNative(LCodeGen* generator);
@@ -1098,12 +1233,14 @@ class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ Token::Value op() const { return op_; }
+
virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
- Token::Value op() const { return op_; }
-
private:
Token::Value op_;
};
@@ -1115,6 +1252,8 @@ class LReturn: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Return, "return")
};
@@ -1125,6 +1264,8 @@ class LLoadNamedField: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
};
@@ -1136,10 +1277,10 @@ class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
-
- LOperand* object() { return inputs_[0]; }
};
@@ -1149,10 +1290,11 @@ class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
- LOperand* object() { return inputs_[0]; }
Handle<Object> name() const { return hydrogen()->name(); }
};
@@ -1163,10 +1305,10 @@ class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = function;
}
+ LOperand* function() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
-
- LOperand* function() { return inputs_[0]; }
};
@@ -1176,6 +1318,8 @@ class LLoadElements: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
};
@@ -1186,6 +1330,8 @@ class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
"load-external-array-pointer")
};
@@ -1198,11 +1344,12 @@ class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
+ LOperand* elements() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
- LOperand* elements() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1214,12 +1361,13 @@ class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
+ LOperand* elements() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement,
"load-keyed-fast-double-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastDoubleElement)
- LOperand* elements() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1232,12 +1380,13 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
+ LOperand* external_pointer() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
"load-keyed-specialized-array-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
- LOperand* external_pointer() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
ElementsKind elements_kind() const {
return hydrogen()->elements_kind();
}
@@ -1247,15 +1396,15 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
class LLoadKeyedGeneric: public LTemplateInstruction<1, 2, 0> {
public:
- LLoadKeyedGeneric(LOperand* obj, LOperand* key) {
- inputs_[0] = obj;
+ LLoadKeyedGeneric(LOperand* object, LOperand* key) {
+ inputs_[0] = object;
inputs_[1] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
-
LOperand* object() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
};
@@ -1272,10 +1421,11 @@ class LLoadGlobalGeneric: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = global_object;
}
+ LOperand* global_object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
- LOperand* global_object() { return inputs_[0]; }
Handle<Object> name() const { return hydrogen()->name(); }
bool for_typeof() const { return hydrogen()->for_typeof(); }
};
@@ -1288,10 +1438,11 @@ class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
-
- LOperand* value() { return inputs_[0]; }
};
@@ -1303,12 +1454,13 @@ class LStoreGlobalGeneric: public LTemplateInstruction<0, 2, 0> {
inputs_[1] = value;
}
+ LOperand* global_object() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric)
- LOperand* global_object() { return InputAt(0); }
Handle<Object> name() const { return hydrogen()->name(); }
- LOperand* value() { return InputAt(1); }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1319,10 +1471,11 @@ class LLoadContextSlot: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
+ LOperand* context() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
- LOperand* context() { return InputAt(0); }
int slot_index() { return hydrogen()->slot_index(); }
virtual void PrintDataTo(StringStream* stream);
@@ -1336,11 +1489,12 @@ class LStoreContextSlot: public LTemplateInstruction<0, 2, 0> {
inputs_[1] = value;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
- LOperand* context() { return InputAt(0); }
- LOperand* value() { return InputAt(1); }
int slot_index() { return hydrogen()->slot_index(); }
virtual void PrintDataTo(StringStream* stream);
@@ -1353,6 +1507,8 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
};
@@ -1389,9 +1545,9 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
- DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
+ LOperand* context() { return inputs_[0]; }
- LOperand* context() { return InputAt(0); }
+ DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
};
@@ -1408,9 +1564,9 @@ class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
- DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
+ LOperand* context() { return inputs_[0]; }
- LOperand* context() { return InputAt(0); }
+ DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
};
@@ -1420,9 +1576,9 @@ class LGlobalReceiver: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = global_object;
}
- DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
+ LOperand* global_object() { return inputs_[0]; }
- LOperand* global() { return InputAt(0); }
+ DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
};
@@ -1444,11 +1600,11 @@ class LInvokeFunction: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = function;
}
+ LOperand* function() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
- LOperand* function() { return inputs_[0]; }
-
virtual void PrintDataTo(StringStream* stream);
int arity() const { return hydrogen()->argument_count() - 1; }
@@ -1462,6 +1618,8 @@ class LCallKeyed: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = key;
}
+ LOperand* key() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
@@ -1490,10 +1648,11 @@ class LCallFunction: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = function;
}
+ LOperand* function() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
DECLARE_HYDROGEN_ACCESSOR(CallFunction)
- LOperand* function() { return inputs_[0]; }
int arity() const { return hydrogen()->argument_count() - 1; }
};
@@ -1528,6 +1687,8 @@ class LCallNew: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = constructor;
}
+ LOperand* constructor() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
DECLARE_HYDROGEN_ACCESSOR(CallNew)
@@ -1553,28 +1714,60 @@ class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
};
+class LUint32ToDouble: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LUint32ToDouble(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
+};
+
+
class LNumberTagI: public LTemplateInstruction<1, 1, 0> {
public:
explicit LNumberTagI(LOperand* value) {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
};
+class LNumberTagU: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LNumberTagU(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
+};
+
+
class LNumberTagD: public LTemplateInstruction<1, 1, 2> {
public:
- LNumberTagD(LOperand* value, LOperand* temp1, LOperand* temp2) {
+ LNumberTagD(LOperand* value, LOperand* temp, LOperand* temp2) {
inputs_[0] = value;
- temps_[0] = temp1;
+ temps_[0] = temp;
temps_[1] = temp2;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
};
@@ -1582,12 +1775,16 @@ class LNumberTagD: public LTemplateInstruction<1, 1, 2> {
// Sometimes truncating conversion from a tagged value to an int32.
class LDoubleToI: public LTemplateInstruction<1, 1, 2> {
public:
- LDoubleToI(LOperand* value, LOperand* temp1, LOperand* temp2) {
+ LDoubleToI(LOperand* value, LOperand* temp, LOperand* temp2) {
inputs_[0] = value;
- temps_[0] = temp1;
+ temps_[0] = temp;
temps_[1] = temp2;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
@@ -1599,15 +1796,20 @@ class LDoubleToI: public LTemplateInstruction<1, 1, 2> {
class LTaggedToI: public LTemplateInstruction<1, 1, 3> {
public:
LTaggedToI(LOperand* value,
- LOperand* temp1,
+ LOperand* temp,
LOperand* temp2,
LOperand* temp3) {
inputs_[0] = value;
- temps_[0] = temp1;
+ temps_[0] = temp;
temps_[1] = temp2;
temps_[2] = temp3;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+ LOperand* temp3() { return temps_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
@@ -1621,6 +1823,8 @@ class LSmiTag: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
};
@@ -1631,6 +1835,8 @@ class LNumberUntagD: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
DECLARE_HYDROGEN_ACCESSOR(Change)
};
@@ -1643,10 +1849,11 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
- DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
-
+ LOperand* value() { return inputs_[0]; }
bool needs_check() const { return needs_check_; }
+ DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
+
private:
bool needs_check_;
};
@@ -1654,20 +1861,21 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
public:
- LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp) {
- inputs_[0] = obj;
- inputs_[1] = val;
+ LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
+ inputs_[0] = object;
+ inputs_[1] = value;
temps_[0] = temp;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* value() { return inputs_[1]; }
-
Handle<Object> name() const { return hydrogen()->name(); }
bool is_in_object() { return hydrogen()->is_in_object(); }
int offset() { return hydrogen()->offset(); }
@@ -1677,18 +1885,19 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
public:
- LStoreNamedGeneric(LOperand* obj, LOperand* val) {
- inputs_[0] = obj;
- inputs_[1] = val;
+ LStoreNamedGeneric(LOperand* object, LOperand* value) {
+ inputs_[0] = object;
+ inputs_[1] = value;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* value() { return inputs_[1]; }
Handle<Object> name() const { return hydrogen()->name(); }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1696,21 +1905,22 @@ class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
public:
- LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val) {
- inputs_[0] = obj;
+ LStoreKeyedFastElement(LOperand* object, LOperand* key, LOperand* value) {
+ inputs_[0] = object;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
"store-keyed-fast-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1719,21 +1929,22 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
public:
LStoreKeyedFastDoubleElement(LOperand* elements,
LOperand* key,
- LOperand* val) {
+ LOperand* value) {
inputs_[0] = elements;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* elements() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement,
"store-keyed-fast-double-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastDoubleElement)
virtual void PrintDataTo(StringStream* stream);
- LOperand* elements() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
@@ -1742,20 +1953,21 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> {
public:
- LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val) {
+ LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* value) {
inputs_[0] = obj;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1763,22 +1975,21 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
public:
LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
LOperand* key,
- LOperand* val) {
+ LOperand* value) {
inputs_[0] = external_pointer;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* external_pointer() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
"store-keyed-specialized-array-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
- LOperand* external_pointer() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
- ElementsKind elements_kind() const {
- return hydrogen()->elements_kind();
- }
+ ElementsKind elements_kind() const { return hydrogen()->elements_kind(); }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1787,21 +1998,22 @@ class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> {
public:
LTransitionElementsKind(LOperand* object,
LOperand* new_map_temp,
- LOperand* temp_reg) {
+ LOperand* temp) {
inputs_[0] = object;
temps_[0] = new_map_temp;
- temps_[1] = temp_reg;
+ temps_[1] = temp;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* new_map_temp() { return temps_[0]; }
+ LOperand* temp() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
"transition-elements-kind")
DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* new_map_reg() { return temps_[0]; }
- LOperand* temp_reg() { return temps_[1]; }
Handle<Map> original_map() { return hydrogen()->original_map(); }
Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); }
};
@@ -1814,11 +2026,11 @@ class LStringAdd: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
- DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
- DECLARE_HYDROGEN_ACCESSOR(StringAdd)
-
LOperand* left() { return inputs_[0]; }
LOperand* right() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
+ DECLARE_HYDROGEN_ACCESSOR(StringAdd)
};
@@ -1830,11 +2042,11 @@ class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = index;
}
- DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
- DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
-
LOperand* string() { return inputs_[0]; }
LOperand* index() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
+ DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
};
@@ -1844,10 +2056,10 @@ class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = char_code;
}
+ LOperand* char_code() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
-
- LOperand* char_code() { return inputs_[0]; }
};
@@ -1857,10 +2069,10 @@ class LStringLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = string;
}
+ LOperand* string() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
DECLARE_HYDROGEN_ACCESSOR(StringLength)
-
- LOperand* string() { return inputs_[0]; }
};
@@ -1870,7 +2082,7 @@ class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
- LOperand* value() { return InputAt(0); }
+ LOperand* value() { return inputs_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
@@ -1883,6 +2095,8 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
};
@@ -1894,6 +2108,8 @@ class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
};
@@ -1901,11 +2117,14 @@ class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 2> {
public:
- LCheckPrototypeMaps(LOperand* temp1, LOperand* temp2) {
- temps_[0] = temp1;
+ LCheckPrototypeMaps(LOperand* temp, LOperand* temp2) {
+ temps_[0] = temp;
temps_[1] = temp2;
}
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
@@ -1920,6 +2139,8 @@ class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
};
@@ -1930,18 +2151,21 @@ class LCheckNonSmi: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
};
class LClampDToUint8: public LTemplateInstruction<1, 1, 1> {
public:
- LClampDToUint8(LOperand* value, LOperand* temp) {
- inputs_[0] = value;
+ LClampDToUint8(LOperand* unclamped, LOperand* temp) {
+ inputs_[0] = unclamped;
temps_[0] = temp;
}
LOperand* unclamped() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
};
@@ -1949,8 +2173,8 @@ class LClampDToUint8: public LTemplateInstruction<1, 1, 1> {
class LClampIToUint8: public LTemplateInstruction<1, 1, 0> {
public:
- explicit LClampIToUint8(LOperand* value) {
- inputs_[0] = value;
+ explicit LClampIToUint8(LOperand* unclamped) {
+ inputs_[0] = unclamped;
}
LOperand* unclamped() { return inputs_[0]; }
@@ -1961,12 +2185,13 @@ class LClampIToUint8: public LTemplateInstruction<1, 1, 0> {
class LClampTToUint8: public LTemplateInstruction<1, 1, 1> {
public:
- LClampTToUint8(LOperand* value, LOperand* temp) {
- inputs_[0] = value;
+ LClampTToUint8(LOperand* unclamped, LOperand* temp) {
+ inputs_[0] = unclamped;
temps_[0] = temp;
}
LOperand* unclamped() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
};
@@ -1974,11 +2199,14 @@ class LClampTToUint8: public LTemplateInstruction<1, 1, 1> {
class LAllocateObject: public LTemplateInstruction<1, 0, 2> {
public:
- LAllocateObject(LOperand* temp1, LOperand* temp2) {
- temps_[0] = temp1;
+ LAllocateObject(LOperand* temp, LOperand* temp2) {
+ temps_[0] = temp;
temps_[1] = temp2;
}
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object")
DECLARE_HYDROGEN_ACCESSOR(AllocateObject)
};
@@ -2027,6 +2255,8 @@ class LToFastProperties: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
};
@@ -2038,6 +2268,8 @@ class LTypeof: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
};
@@ -2048,6 +2280,8 @@ class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
@@ -2063,6 +2297,8 @@ class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
temps_[0] = temp;
}
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
"is-construct-call-and-branch")
};
@@ -2070,15 +2306,15 @@ class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
class LDeleteProperty: public LTemplateInstruction<1, 2, 0> {
public:
- LDeleteProperty(LOperand* obj, LOperand* key) {
- inputs_[0] = obj;
+ LDeleteProperty(LOperand* object, LOperand* key) {
+ inputs_[0] = object;
inputs_[1] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
-
LOperand* object() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
};
@@ -2188,65 +2424,13 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> {
class LChunkBuilder;
-class LChunk: public ZoneObject {
+class LPlatformChunk: public LChunk {
public:
- explicit LChunk(CompilationInfo* info, HGraph* graph);
-
- void AddInstruction(LInstruction* instruction, HBasicBlock* block);
- LConstantOperand* DefineConstantOperand(HConstant* constant);
- Handle<Object> LookupLiteral(LConstantOperand* operand) const;
- Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
+ LPlatformChunk(CompilationInfo* info, HGraph* graph)
+ : LChunk(info, graph) { }
int GetNextSpillIndex(bool is_double);
LOperand* GetNextSpillSlot(bool is_double);
-
- int ParameterAt(int index);
- int GetParameterStackSlot(int index) const;
- int spill_slot_count() const { return spill_slot_count_; }
- CompilationInfo* info() const { return info_; }
- HGraph* graph() const { return graph_; }
- const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
- void AddGapMove(int index, LOperand* from, LOperand* to);
- LGap* GetGapAt(int index) const;
- bool IsGapAt(int index) const;
- int NearestGapPos(int index) const;
- void MarkEmptyBlocks();
- const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
- LLabel* GetLabel(int block_id) const {
- HBasicBlock* block = graph_->blocks()->at(block_id);
- int first_instruction = block->first_instruction_index();
- return LLabel::cast(instructions_[first_instruction]);
- }
- int LookupDestination(int block_id) const {
- LLabel* cur = GetLabel(block_id);
- while (cur->replacement() != NULL) {
- cur = cur->replacement();
- }
- return cur->block_id();
- }
- Label* GetAssemblyLabel(int block_id) const {
- LLabel* label = GetLabel(block_id);
- ASSERT(!label->HasReplacement());
- return label->label();
- }
-
- const ZoneList<Handle<JSFunction> >* inlined_closures() const {
- return &inlined_closures_;
- }
-
- void AddInlinedClosure(Handle<JSFunction> closure) {
- inlined_closures_.Add(closure, zone());
- }
-
- Zone* zone() const { return graph_->zone(); }
-
- private:
- int spill_slot_count_;
- CompilationInfo* info_;
- HGraph* const graph_;
- ZoneList<LInstruction*> instructions_;
- ZoneList<LPointerMap*> pointer_maps_;
- ZoneList<Handle<JSFunction> > inlined_closures_;
};
@@ -2265,10 +2449,10 @@ class LChunkBuilder BASE_EMBEDDED {
allocator_(allocator),
position_(RelocInfo::kNoPosition),
instruction_pending_deoptimization_environment_(NULL),
- pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
+ pending_deoptimization_ast_id_(BailoutId::None()) { }
// Build the sequence for the graph.
- LChunk* Build();
+ LPlatformChunk* Build();
// Declare methods that deal with the individual node types.
#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
@@ -2283,7 +2467,7 @@ class LChunkBuilder BASE_EMBEDDED {
ABORTED
};
- LChunk* chunk() const { return chunk_; }
+ LPlatformChunk* chunk() const { return chunk_; }
CompilationInfo* info() const { return info_; }
HGraph* graph() const { return graph_; }
Zone* zone() const { return zone_; }
@@ -2293,7 +2477,7 @@ class LChunkBuilder BASE_EMBEDDED {
bool is_done() const { return status_ == DONE; }
bool is_aborted() const { return status_ == ABORTED; }
- void Abort(const char* format, ...);
+ void Abort(const char* reason);
// Methods for getting operands for Use / Define / Temp.
LUnallocated* ToUnallocated(Register reg);
@@ -2384,7 +2568,7 @@ class LChunkBuilder BASE_EMBEDDED {
LInstruction* DoArithmeticT(Token::Value op,
HArithmeticBinaryOperation* instr);
- LChunk* chunk_;
+ LPlatformChunk* chunk_;
CompilationInfo* info_;
HGraph* const graph_;
Zone* zone_;
@@ -2396,7 +2580,7 @@ class LChunkBuilder BASE_EMBEDDED {
LAllocator* allocator_;
int position_;
LInstruction* instruction_pending_deoptimization_environment_;
- int pending_deoptimization_ast_id_;
+ BailoutId pending_deoptimization_ast_id_;
DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
};
diff --git a/deps/v8/src/mips/macro-assembler-mips.cc b/deps/v8/src/mips/macro-assembler-mips.cc
index 1a6bc216c..052387ab0 100644
--- a/deps/v8/src/mips/macro-assembler-mips.cc
+++ b/deps/v8/src/mips/macro-assembler-mips.cc
@@ -361,28 +361,29 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
scratch, Operand(zero_reg));
#endif
- // Load the global context of the current context.
- int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ // Load the native context of the current context.
+ int offset =
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
lw(scratch, FieldMemOperand(scratch, offset));
- lw(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
+ lw(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
- // Check the context is a global context.
+ // Check the context is a native context.
if (emit_debug_code()) {
// TODO(119): Avoid push(holder_reg)/pop(holder_reg).
push(holder_reg); // Temporarily save holder on the stack.
- // Read the first word and compare to the global_context_map.
+ // Read the first word and compare to the native_context_map.
lw(holder_reg, FieldMemOperand(scratch, HeapObject::kMapOffset));
- LoadRoot(at, Heap::kGlobalContextMapRootIndex);
- Check(eq, "JSGlobalObject::global_context should be a global context.",
+ LoadRoot(at, Heap::kNativeContextMapRootIndex);
+ Check(eq, "JSGlobalObject::native_context should be a native context.",
holder_reg, Operand(at));
pop(holder_reg); // Restore holder.
}
// Check if both contexts are the same.
- lw(at, FieldMemOperand(holder_reg, JSGlobalProxy::kContextOffset));
+ lw(at, FieldMemOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
Branch(&same_contexts, eq, scratch, Operand(at));
- // Check the context is a global context.
+ // Check the context is a native context.
if (emit_debug_code()) {
// TODO(119): Avoid push(holder_reg)/pop(holder_reg).
push(holder_reg); // Temporarily save holder on the stack.
@@ -392,13 +393,13 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
holder_reg, Operand(at));
lw(holder_reg, FieldMemOperand(holder_reg, HeapObject::kMapOffset));
- LoadRoot(at, Heap::kGlobalContextMapRootIndex);
- Check(eq, "JSGlobalObject::global_context should be a global context.",
+ LoadRoot(at, Heap::kNativeContextMapRootIndex);
+ Check(eq, "JSGlobalObject::native_context should be a native context.",
holder_reg, Operand(at));
// Restore at is not needed. at is reloaded below.
pop(holder_reg); // Restore holder.
// Restore at to holder's context.
- lw(at, FieldMemOperand(holder_reg, JSGlobalProxy::kContextOffset));
+ lw(at, FieldMemOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
}
// Check that the security token in the calling global object is
@@ -2559,7 +2560,7 @@ void MacroAssembler::Call(Address target,
int MacroAssembler::CallSize(Handle<Code> code,
RelocInfo::Mode rmode,
- unsigned ast_id,
+ TypeFeedbackId ast_id,
Condition cond,
Register rs,
const Operand& rt,
@@ -2571,7 +2572,7 @@ int MacroAssembler::CallSize(Handle<Code> code,
void MacroAssembler::Call(Handle<Code> code,
RelocInfo::Mode rmode,
- unsigned ast_id,
+ TypeFeedbackId ast_id,
Condition cond,
Register rs,
const Operand& rt,
@@ -2580,7 +2581,7 @@ void MacroAssembler::Call(Handle<Code> code,
Label start;
bind(&start);
ASSERT(RelocInfo::IsCodeTarget(rmode));
- if (rmode == RelocInfo::CODE_TARGET && ast_id != kNoASTId) {
+ if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) {
SetRecordedAstId(ast_id);
rmode = RelocInfo::CODE_TARGET_WITH_ID;
}
@@ -3444,7 +3445,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
destination = FloatingPointHelper::kCoreRegisters;
}
- Register untagged_value = receiver_reg;
+ Register untagged_value = elements_reg;
SmiUntag(untagged_value, value_reg);
FloatingPointHelper::ConvertIntToDouble(this,
untagged_value,
@@ -3911,7 +3912,8 @@ void MacroAssembler::CallStub(CodeStub* stub,
const Operand& r2,
BranchDelaySlot bd) {
ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
- Call(stub->GetCode(), RelocInfo::CODE_TARGET, kNoASTId, cond, r1, r2, bd);
+ Call(stub->GetCode(), RelocInfo::CODE_TARGET, TypeFeedbackId::None(),
+ cond, r1, r2, bd);
}
@@ -4281,7 +4283,7 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
void MacroAssembler::GetBuiltinFunction(Register target,
Builtins::JavaScript id) {
// Load the builtins object into target register.
- lw(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ lw(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
lw(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
// Load the JavaScript builtin function from the builtins object.
lw(target, FieldMemOperand(target,
@@ -4450,8 +4452,9 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
Register scratch,
Label* no_map_match) {
// Load the global or builtins object from the current context.
- lw(scratch, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- lw(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
+ lw(scratch,
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ lw(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
// Check that the function's map is the same as the expected cached map.
lw(scratch,
@@ -4496,11 +4499,12 @@ void MacroAssembler::LoadInitialArrayMap(
void MacroAssembler::LoadGlobalFunction(int index, Register function) {
// Load the global or builtins object from the current context.
- lw(function, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- // Load the global context from the global or builtins object.
+ lw(function,
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ // Load the native context from the global or builtins object.
lw(function, FieldMemOperand(function,
- GlobalObject::kGlobalContextOffset));
- // Load the function from the global context.
+ GlobalObject::kNativeContextOffset));
+ // Load the function from the native context.
lw(function, MemOperand(function, Context::SlotOffset(index)));
}
@@ -4794,38 +4798,46 @@ void MacroAssembler::JumpIfEitherSmi(Register reg1,
}
-void MacroAssembler::AbortIfSmi(Register object) {
- STATIC_ASSERT(kSmiTag == 0);
- andi(at, object, kSmiTagMask);
- Assert(ne, "Operand is a smi", at, Operand(zero_reg));
+void MacroAssembler::AssertNotSmi(Register object) {
+ if (emit_debug_code()) {
+ STATIC_ASSERT(kSmiTag == 0);
+ andi(at, object, kSmiTagMask);
+ Check(ne, "Operand is a smi", at, Operand(zero_reg));
+ }
}
-void MacroAssembler::AbortIfNotSmi(Register object) {
- STATIC_ASSERT(kSmiTag == 0);
- andi(at, object, kSmiTagMask);
- Assert(eq, "Operand is a smi", at, Operand(zero_reg));
+void MacroAssembler::AssertSmi(Register object) {
+ if (emit_debug_code()) {
+ STATIC_ASSERT(kSmiTag == 0);
+ andi(at, object, kSmiTagMask);
+ Check(eq, "Operand is a smi", at, Operand(zero_reg));
+ }
}
-void MacroAssembler::AbortIfNotString(Register object) {
- STATIC_ASSERT(kSmiTag == 0);
- And(t0, object, Operand(kSmiTagMask));
- Assert(ne, "Operand is not a string", t0, Operand(zero_reg));
- push(object);
- lw(object, FieldMemOperand(object, HeapObject::kMapOffset));
- lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset));
- Assert(lo, "Operand is not a string", object, Operand(FIRST_NONSTRING_TYPE));
- pop(object);
+void MacroAssembler::AssertString(Register object) {
+ if (emit_debug_code()) {
+ STATIC_ASSERT(kSmiTag == 0);
+ And(t0, object, Operand(kSmiTagMask));
+ Check(ne, "Operand is a smi and not a string", t0, Operand(zero_reg));
+ push(object);
+ lw(object, FieldMemOperand(object, HeapObject::kMapOffset));
+ lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset));
+ Check(lo, "Operand is not a string", object, Operand(FIRST_NONSTRING_TYPE));
+ pop(object);
+ }
}
-void MacroAssembler::AbortIfNotRootValue(Register src,
- Heap::RootListIndex root_value_index,
- const char* message) {
- ASSERT(!src.is(at));
- LoadRoot(at, root_value_index);
- Assert(eq, message, src, Operand(at));
+void MacroAssembler::AssertRootValue(Register src,
+ Heap::RootListIndex root_value_index,
+ const char* message) {
+ if (emit_debug_code()) {
+ ASSERT(!src.is(at));
+ LoadRoot(at, root_value_index);
+ Check(eq, message, src, Operand(at));
+ }
}
@@ -5291,54 +5303,54 @@ void MacroAssembler::EnsureNotWhite(
void MacroAssembler::LoadInstanceDescriptors(Register map,
Register descriptors) {
- lw(descriptors,
- FieldMemOperand(map, Map::kInstanceDescriptorsOrBitField3Offset));
- Label not_smi;
- JumpIfNotSmi(descriptors, &not_smi);
- LoadRoot(descriptors, Heap::kEmptyDescriptorArrayRootIndex);
- bind(&not_smi);
+ lw(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset));
+}
+
+
+void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
+ lw(dst, FieldMemOperand(map, Map::kBitField3Offset));
+ DecodeField<Map::NumberOfOwnDescriptorsBits>(dst);
+}
+
+
+void MacroAssembler::EnumLength(Register dst, Register map) {
+ STATIC_ASSERT(Map::EnumLengthBits::kShift == 0);
+ lw(dst, FieldMemOperand(map, Map::kBitField3Offset));
+ And(dst, dst, Operand(Smi::FromInt(Map::EnumLengthBits::kMask)));
}
void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
- Label next;
- // Preload a couple of values used in the loop.
Register empty_fixed_array_value = t2;
LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
- Register empty_descriptor_array_value = t3;
- LoadRoot(empty_descriptor_array_value,
- Heap::kEmptyDescriptorArrayRootIndex);
- mov(a1, a0);
- bind(&next);
+ Label next, start;
+ mov(a2, a0);
- // Check that there are no elements. Register a1 contains the
- // current JS object we've reached through the prototype chain.
- lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset));
- Branch(call_runtime, ne, a2, Operand(empty_fixed_array_value));
+ // Check if the enum length field is properly initialized, indicating that
+ // there is an enum cache.
+ lw(a1, FieldMemOperand(a2, HeapObject::kMapOffset));
- // Check that instance descriptors are not empty so that we can
- // check for an enum cache. Leave the map in a2 for the subsequent
- // prototype load.
- lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset));
- lw(a3, FieldMemOperand(a2, Map::kInstanceDescriptorsOrBitField3Offset));
- JumpIfSmi(a3, call_runtime);
+ EnumLength(a3, a1);
+ Branch(call_runtime, eq, a3, Operand(Smi::FromInt(Map::kInvalidEnumCache)));
- // Check that there is an enum cache in the non-empty instance
- // descriptors (a3). This is the case if the next enumeration
- // index field does not contain a smi.
- lw(a3, FieldMemOperand(a3, DescriptorArray::kEnumerationIndexOffset));
- JumpIfSmi(a3, call_runtime);
+ jmp(&start);
+
+ bind(&next);
+ lw(a1, FieldMemOperand(a2, HeapObject::kMapOffset));
// For all objects but the receiver, check that the cache is empty.
- Label check_prototype;
- Branch(&check_prototype, eq, a1, Operand(a0));
- lw(a3, FieldMemOperand(a3, DescriptorArray::kEnumCacheBridgeCacheOffset));
- Branch(call_runtime, ne, a3, Operand(empty_fixed_array_value));
+ EnumLength(a3, a1);
+ Branch(call_runtime, ne, a3, Operand(Smi::FromInt(0)));
+
+ bind(&start);
+
+ // Check that there are no elements. Register r2 contains the current JS
+ // object we've reached through the prototype chain.
+ lw(a2, FieldMemOperand(a2, JSObject::kElementsOffset));
+ Branch(call_runtime, ne, a2, Operand(empty_fixed_array_value));
- // Load the prototype from the map and loop if non-null.
- bind(&check_prototype);
- lw(a1, FieldMemOperand(a2, Map::kPrototypeOffset));
- Branch(&next, ne, a1, Operand(null_value));
+ lw(a2, FieldMemOperand(a1, Map::kPrototypeOffset));
+ Branch(&next, ne, a2, Operand(null_value));
}
@@ -5379,7 +5391,7 @@ void MacroAssembler::ClampDoubleToUint8(Register result_reg,
// In 0-255 range, round and truncate.
bind(&in_bounds);
- round_w_d(temp_double_reg, input_reg);
+ cvt_w_d(temp_double_reg, input_reg);
mfc1(result_reg, temp_double_reg);
bind(&done);
}
diff --git a/deps/v8/src/mips/macro-assembler-mips.h b/deps/v8/src/mips/macro-assembler-mips.h
index bb3dc01e3..b57e51486 100644
--- a/deps/v8/src/mips/macro-assembler-mips.h
+++ b/deps/v8/src/mips/macro-assembler-mips.h
@@ -108,7 +108,7 @@ inline MemOperand ContextOperand(Register context, int index) {
inline MemOperand GlobalObjectOperand() {
- return ContextOperand(cp, Context::GLOBAL_INDEX);
+ return ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX);
}
@@ -182,11 +182,11 @@ class MacroAssembler: public Assembler {
void Call(Address target, RelocInfo::Mode rmode, COND_ARGS);
static int CallSize(Handle<Code> code,
RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
- unsigned ast_id = kNoASTId,
+ TypeFeedbackId ast_id = TypeFeedbackId::None(),
COND_ARGS);
void Call(Handle<Code> code,
RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
- unsigned ast_id = kNoASTId,
+ TypeFeedbackId ast_id = TypeFeedbackId::None(),
COND_ARGS);
void Ret(COND_ARGS);
inline void Ret(BranchDelaySlot bd, Condition cond = al,
@@ -806,8 +806,8 @@ class MacroAssembler: public Assembler {
void LoadContext(Register dst, int context_chain_length);
// Conditionally load the cached Array transitioned map of type
- // transitioned_kind from the global context if the map in register
- // map_in_out is the cached Array map in the global context of
+ // transitioned_kind from the native context if the map in register
+ // map_in_out is the cached Array map in the native context of
// expected_kind.
void LoadTransitionedArrayMapConditional(
ElementsKind expected_kind,
@@ -973,6 +973,7 @@ class MacroAssembler: public Assembler {
void StoreNumberToDoubleElements(Register value_reg,
Register key_reg,
Register receiver_reg,
+ // All regs below here overwritten.
Register elements_reg,
Register scratch1,
Register scratch2,
@@ -1335,17 +1336,18 @@ class MacroAssembler: public Assembler {
// Jump if either of the registers contain a smi.
void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
- // Abort execution if argument is a smi. Used in debug code.
- void AbortIfSmi(Register object);
- void AbortIfNotSmi(Register object);
+ // Abort execution if argument is a smi, enabled via --debug-code.
+ void AssertNotSmi(Register object);
+ void AssertSmi(Register object);
- // Abort execution if argument is a string. Used in debug code.
- void AbortIfNotString(Register object);
+ // Abort execution if argument is not a string, enabled via --debug-code.
+ void AssertString(Register object);
- // Abort execution if argument is not the root value with the given index.
- void AbortIfNotRootValue(Register src,
- Heap::RootListIndex root_value_index,
- const char* message);
+ // Abort execution if argument is not the root value with the given index,
+ // enabled via --debug-code.
+ void AssertRootValue(Register src,
+ Heap::RootListIndex root_value_index,
+ const char* message);
// ---------------------------------------------------------------------------
// HeapNumber utilities.
@@ -1397,7 +1399,16 @@ class MacroAssembler: public Assembler {
void LoadInstanceDescriptors(Register map, Register descriptors);
-
+ void EnumLength(Register dst, Register map);
+ void NumberOfOwnDescriptors(Register dst, Register map);
+
+ template<typename Field>
+ void DecodeField(Register reg) {
+ static const int shift = Field::kShift;
+ static const int mask = (Field::kMask >> shift) << kSmiTagSize;
+ srl(reg, reg, shift);
+ And(reg, reg, Operand(mask));
+ }
// Activation support.
void EnterFrame(StackFrame::Type type);
diff --git a/deps/v8/src/mips/regexp-macro-assembler-mips.cc b/deps/v8/src/mips/regexp-macro-assembler-mips.cc
index 21d1ce11b..672ba0eee 100644
--- a/deps/v8/src/mips/regexp-macro-assembler-mips.cc
+++ b/deps/v8/src/mips/regexp-macro-assembler-mips.cc
@@ -1103,6 +1103,11 @@ void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
}
+bool RegExpMacroAssemblerMIPS::CanReadUnaligned() {
+ return false;
+}
+
+
// Private methods:
void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) {
diff --git a/deps/v8/src/mips/regexp-macro-assembler-mips.h b/deps/v8/src/mips/regexp-macro-assembler-mips.h
index d3fff0db2..8dd52a484 100644
--- a/deps/v8/src/mips/regexp-macro-assembler-mips.h
+++ b/deps/v8/src/mips/regexp-macro-assembler-mips.h
@@ -38,13 +38,7 @@
namespace v8 {
namespace internal {
-#ifdef V8_INTERPRETED_REGEXP
-class RegExpMacroAssemblerMIPS: public RegExpMacroAssembler {
- public:
- RegExpMacroAssemblerMIPS();
- virtual ~RegExpMacroAssemblerMIPS();
-};
-#else // V8_INTERPRETED_REGEXP
+#ifndef V8_INTERPRETED_REGEXP
class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler {
public:
RegExpMacroAssemblerMIPS(Mode mode, int registers_to_save, Zone* zone);
@@ -118,6 +112,7 @@ class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler {
virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
virtual void ClearRegisters(int reg_from, int reg_to);
virtual void WriteStackPointerToRegister(int reg);
+ virtual bool CanReadUnaligned();
// Called from RegExp if the stack-guard is triggered.
// If the code object is relocated, the return address is fixed before
diff --git a/deps/v8/src/mips/simulator-mips.cc b/deps/v8/src/mips/simulator-mips.cc
index 66d0da71f..cf87f9360 100644
--- a/deps/v8/src/mips/simulator-mips.cc
+++ b/deps/v8/src/mips/simulator-mips.cc
@@ -2068,10 +2068,15 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
// Rounding modes are not yet supported.
ASSERT((FCSR_ & 3) == 0);
// In rounding mode 0 it should behave like ROUND.
- case ROUND_W_D: // Round double to word.
+ case ROUND_W_D: // Round double to word (round half to even).
{
- double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
+ double rounded = floor(fs + 0.5);
int32_t result = static_cast<int32_t>(rounded);
+ if ((result & 1) != 0 && result - fs == 0.5) {
+ // If the number is halfway between two integers,
+ // round to the even one.
+ result--;
+ }
set_fpu_register(fd_reg, result);
if (set_fcsr_round_error(fs, rounded)) {
set_fpu_register(fd_reg, kFPUInvalidResult);
diff --git a/deps/v8/src/mips/stub-cache-mips.cc b/deps/v8/src/mips/stub-cache-mips.cc
index 967ce4a60..ba1d17722 100644
--- a/deps/v8/src/mips/stub-cache-mips.cc
+++ b/deps/v8/src/mips/stub-cache-mips.cc
@@ -270,11 +270,12 @@ void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
int index,
Register prototype) {
// Load the global or builtins object from the current context.
- __ lw(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- // Load the global context from the global or builtins object.
__ lw(prototype,
- FieldMemOperand(prototype, GlobalObject::kGlobalContextOffset));
- // Load the function from the global context.
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ // Load the native context from the global or builtins object.
+ __ lw(prototype,
+ FieldMemOperand(prototype, GlobalObject::kNativeContextOffset));
+ // Load the function from the native context.
__ lw(prototype, MemOperand(prototype, Context::SlotOffset(index)));
// Load the initial map. The global functions all have initial maps.
__ lw(prototype,
@@ -291,13 +292,14 @@ void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
Label* miss) {
Isolate* isolate = masm->isolate();
// Check we're still in the same context.
- __ lw(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ lw(prototype,
+ MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
ASSERT(!prototype.is(at));
- __ li(at, isolate->global());
+ __ li(at, isolate->global_object());
__ Branch(miss, ne, prototype, Operand(at));
// Get the global function with the given index.
Handle<JSFunction> function(
- JSFunction::cast(isolate->global_context()->get(index)));
+ JSFunction::cast(isolate->native_context()->get(index)));
// Load its initial map. The global functions all have initial maps.
__ li(prototype, Handle<Map>(function->initial_map()));
// Load the prototype from the initial map.
@@ -1234,6 +1236,44 @@ void StubCompiler::GenerateLoadConstant(Handle<JSObject> object,
}
+void StubCompiler::GenerateDictionaryLoadCallback(Register receiver,
+ Register name_reg,
+ Register scratch1,
+ Register scratch2,
+ Register scratch3,
+ Handle<AccessorInfo> callback,
+ Handle<String> name,
+ Label* miss) {
+ ASSERT(!receiver.is(scratch1));
+ ASSERT(!receiver.is(scratch2));
+ ASSERT(!receiver.is(scratch3));
+
+ // Load the properties dictionary.
+ Register dictionary = scratch1;
+ __ lw(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+
+ // Probe the dictionary.
+ Label probe_done;
+ StringDictionaryLookupStub::GeneratePositiveLookup(masm(),
+ miss,
+ &probe_done,
+ dictionary,
+ name_reg,
+ scratch2,
+ scratch3);
+ __ bind(&probe_done);
+
+ // If probing finds an entry in the dictionary, scratch3 contains the
+ // pointer into the dictionary. Check that the value is the callback.
+ Register pointer = scratch3;
+ const int kElementsStartOffset = StringDictionary::kHeaderSize +
+ StringDictionary::kElementsStartIndex * kPointerSize;
+ const int kValueOffset = kElementsStartOffset + kPointerSize;
+ __ lw(scratch2, FieldMemOperand(pointer, kValueOffset));
+ __ Branch(miss, ne, scratch2, Operand(callback));
+}
+
+
void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Handle<JSObject> holder,
Register receiver,
@@ -1241,6 +1281,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Register scratch1,
Register scratch2,
Register scratch3,
+ Register scratch4,
Handle<AccessorInfo> callback,
Handle<String> name,
Label* miss) {
@@ -1251,6 +1292,11 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Register reg = CheckPrototypes(object, receiver, holder, scratch1,
scratch2, scratch3, name, miss);
+ if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
+ GenerateDictionaryLoadCallback(
+ reg, name_reg, scratch2, scratch3, scratch4, callback, name, miss);
+ }
+
// Build AccessorInfo::args_ list on the stack and push property name below
// the exit frame to make GC aware of them and store pointers to them.
__ push(receiver);
@@ -1318,7 +1364,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
// later.
bool compile_followup_inline = false;
if (lookup->IsFound() && lookup->IsCacheable()) {
- if (lookup->type() == FIELD) {
+ if (lookup->IsField()) {
compile_followup_inline = true;
} else if (lookup->type() == CALLBACKS &&
lookup->GetCallbackObject()->IsAccessorInfo()) {
@@ -1391,7 +1437,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
miss);
}
- if (lookup->type() == FIELD) {
+ if (lookup->IsField()) {
// We found FIELD property in prototype chain of interceptor's holder.
// Retrieve a field from field's holder.
GenerateFastPropertyLoad(masm(), v0, holder_reg,
@@ -1531,7 +1577,7 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
GenerateMissBranch();
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2078,7 +2124,7 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2212,7 +2258,7 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2313,7 +2359,7 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2534,7 +2580,7 @@ Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
GenerateMissBranch();
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2593,7 +2639,7 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
GenerateMissBranch();
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2623,14 +2669,17 @@ Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
Handle<Code> StoreStubCompiler::CompileStoreCallback(
- Handle<JSObject> object,
- Handle<AccessorInfo> callback,
- Handle<String> name) {
+ Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
@@ -2638,19 +2687,13 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -- ra : return address
// -----------------------------------
Label miss;
-
- // Check that the map of the object hasn't changed.
- __ CheckMap(a1, a3, Handle<Map>(object->map()), &miss,
- DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
-
- // Perform global security token check if needed.
- if (object->IsJSGlobalProxy()) {
- __ CheckAccessGlobalProxy(a1, a3, &miss);
- }
+ // Check that the maps haven't changed.
+ __ JumpIfSmi(a1, &miss, a3);
+ CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss);
// Stub never generated for non-global objects that require access
// checks.
- ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
+ ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
__ push(a1); // Receiver.
__ li(a3, Operand(callback)); // Callback info.
@@ -2668,38 +2711,41 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
-Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
- Handle<JSObject> receiver,
- Handle<JSFunction> setter,
- Handle<String> name) {
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void StoreStubCompiler::GenerateStoreViaSetter(
+ MacroAssembler* masm,
+ Handle<JSFunction> setter) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
- Label miss;
-
- // Check that the map of the object hasn't changed.
- __ CheckMap(a1, a3, Handle<Map>(receiver->map()), &miss, DO_SMI_CHECK,
- ALLOW_ELEMENT_TRANSITION_MAPS);
-
{
- FrameScope scope(masm(), StackFrame::INTERNAL);
+ FrameScope scope(masm, StackFrame::INTERNAL);
// Save value register, so we can restore it later.
__ push(a0);
- // Call the JavaScript getter with the receiver and the value on the stack.
- __ push(a1);
- __ push(a0);
- ParameterCount actual(1);
- __ InvokeFunction(setter, actual, CALL_FUNCTION, NullCallWrapper(),
- CALL_AS_METHOD);
+ if (!setter.is_null()) {
+ // Call the JavaScript setter with receiver and value on the stack.
+ __ push(a1);
+ __ push(a0);
+ ParameterCount actual(1);
+ __ InvokeFunction(setter, actual, CALL_FUNCTION, NullCallWrapper(),
+ CALL_AS_METHOD);
+ } else {
+ // If we generate a global code snippet for deoptimization only, remember
+ // the place to continue after deoptimization.
+ masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+ }
// We have to return the passed value, not the return value of the setter.
__ pop(v0);
@@ -2708,13 +2754,38 @@ Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
__ Ret();
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
+Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
+ Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<JSFunction> setter) {
+ // ----------- S t a t e -------------
+ // -- a0 : value
+ // -- a1 : receiver
+ // -- a2 : name
+ // -- ra : return address
+ // -----------------------------------
+ Label miss;
+
+ // Check that the maps haven't changed.
+ __ JumpIfSmi(a1, &miss);
+ CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss);
+
+ GenerateStoreViaSetter(masm(), setter);
__ bind(&miss);
Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2759,7 +2830,7 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2804,7 +2875,7 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2838,7 +2909,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NONEXISTENT, factory()->empty_string());
+ return GetCode(Code::NONEXISTENT, factory()->empty_string());
}
@@ -2860,7 +2931,7 @@ Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2875,16 +2946,53 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
// -- ra : return address
// -----------------------------------
Label miss;
- GenerateLoadCallback(object, holder, a0, a2, a3, a1, t0, callback, name,
+ GenerateLoadCallback(object, holder, a0, a2, a3, a1, t0, t1, callback, name,
&miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
+ Handle<JSFunction> getter) {
+ // ----------- S t a t e -------------
+ // -- a0 : receiver
+ // -- a2 : name
+ // -- ra : return address
+ // -----------------------------------
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ if (!getter.is_null()) {
+ // Call the JavaScript getter with the receiver on the stack.
+ __ push(a0);
+ ParameterCount actual(0);
+ __ InvokeFunction(getter, actual, CALL_FUNCTION, NullCallWrapper(),
+ CALL_AS_METHOD);
+ } else {
+ // If we generate a global code snippet for deoptimization only, remember
+ // the place to continue after deoptimization.
+ masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
+ }
+
+ // Restore context register.
+ __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+ }
+ __ Ret();
}
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
@@ -2901,25 +3009,13 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
__ JumpIfSmi(a0, &miss);
CheckPrototypes(receiver, a0, holder, a3, t0, a1, name, &miss);
- {
- FrameScope scope(masm(), StackFrame::INTERNAL);
-
- // Call the JavaScript getter with the receiver on the stack.
- __ push(a0);
- ParameterCount actual(0);
- __ InvokeFunction(getter, actual, CALL_FUNCTION, NullCallWrapper(),
- CALL_AS_METHOD);
-
- // Restore context register.
- __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
- }
- __ Ret();
+ GenerateLoadViaGetter(masm(), getter);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2939,7 +3035,7 @@ Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -2962,7 +3058,7 @@ Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> object,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3003,7 +3099,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -3025,7 +3121,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -3044,12 +3140,12 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
// Check the key is the cached one.
__ Branch(&miss, ne, a0, Operand(name));
- GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, t0, callback, name,
- &miss);
+ GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, t0, t1, callback,
+ name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3073,7 +3169,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -3098,7 +3194,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3118,7 +3214,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3143,7 +3239,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3167,7 +3263,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
__ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3187,7 +3283,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3214,7 +3310,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic(
__ Jump(miss_ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
@@ -3253,7 +3349,9 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -3277,7 +3375,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3315,7 +3413,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
__ Jump(miss_ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
@@ -4650,6 +4748,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
__ StoreNumberToDoubleElements(value_reg,
key_reg,
receiver_reg,
+ // All registers after this are overwritten.
elements_reg,
scratch1,
scratch2,
diff --git a/deps/v8/src/mirror-debugger.js b/deps/v8/src/mirror-debugger.js
index c7f0dccb7..a5331a014 100644
--- a/deps/v8/src/mirror-debugger.js
+++ b/deps/v8/src/mirror-debugger.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// 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:
@@ -154,6 +154,7 @@ var FUNCTION_TYPE = 'function';
var REGEXP_TYPE = 'regexp';
var ERROR_TYPE = 'error';
var PROPERTY_TYPE = 'property';
+var INTERNAL_PROPERTY_TYPE = 'internalProperty';
var FRAME_TYPE = 'frame';
var SCRIPT_TYPE = 'script';
var CONTEXT_TYPE = 'context';
@@ -176,10 +177,8 @@ PropertyType.ConstantFunction = 2;
PropertyType.Callbacks = 3;
PropertyType.Handler = 4;
PropertyType.Interceptor = 5;
-PropertyType.MapTransition = 6;
-PropertyType.ExternalArrayTransition = 7;
-PropertyType.ConstantTransition = 8;
-PropertyType.NullDescriptor = 9;
+PropertyType.Transition = 6;
+PropertyType.Nonexistent = 7;
// Different attributes for a property.
@@ -214,6 +213,7 @@ var ScopeType = { Global: 0,
// - RegExpMirror
// - ErrorMirror
// - PropertyMirror
+// - InternalPropertyMirror
// - FrameMirror
// - ScriptMirror
@@ -360,6 +360,15 @@ Mirror.prototype.isProperty = function() {
/**
+ * Check whether the mirror reflects an internal property.
+ * @returns {boolean} True if the mirror reflects an internal property
+ */
+Mirror.prototype.isInternalProperty = function() {
+ return this instanceof InternalPropertyMirror;
+};
+
+
+/**
* Check whether the mirror reflects a stack frame.
* @returns {boolean} True if the mirror reflects a stack frame
*/
@@ -596,23 +605,6 @@ ObjectMirror.prototype.protoObject = function() {
};
-/**
- * Return the primitive value if this is object of Boolean, Number or String
- * type (but not Date). Otherwise return undefined.
- */
-ObjectMirror.prototype.primitiveValue = function() {
- if (!IS_STRING_WRAPPER(this.value_) && !IS_NUMBER_WRAPPER(this.value_) &&
- !IS_BOOLEAN_WRAPPER(this.value_)) {
- return void 0;
- }
- var primitiveValue = %_ValueOf(this.value_);
- if (IS_UNDEFINED(primitiveValue)) {
- return void 0;
- }
- return MakeMirror(primitiveValue);
-};
-
-
ObjectMirror.prototype.hasNamedInterceptor = function() {
// Get information on interceptors for this object.
var x = %GetInterceptorInfo(this.value_);
@@ -703,7 +695,7 @@ ObjectMirror.prototype.propertyNames = function(kind, limit) {
* Return the properties for this object as an array of PropertyMirror objects.
* @param {number} kind Indicate whether named, indexed or both kinds of
* properties are requested
- * @param {number} limit Limit the number of properties returend to the
+ * @param {number} limit Limit the number of properties returned to the
specified value
* @return {Array} Property mirrors for this object
*/
@@ -718,6 +710,16 @@ ObjectMirror.prototype.properties = function(kind, limit) {
};
+/**
+ * Return the internal properties for this object as an array of
+ * InternalPropertyMirror objects.
+ * @return {Array} Property mirrors for this object
+ */
+ObjectMirror.prototype.internalProperties = function() {
+ return ObjectMirror.GetInternalProperties(this.value_);
+}
+
+
ObjectMirror.prototype.property = function(name) {
var details = %DebugGetPropertyDetails(this.value_, %ToString(name));
if (details) {
@@ -792,6 +794,37 @@ ObjectMirror.prototype.toText = function() {
/**
+ * Return the internal properties of the value, such as [[PrimitiveValue]] of
+ * scalar wrapper objects and properties of the bound function.
+ * This method is done static to be accessible from Debug API with the bare
+ * values without mirrors.
+ * @return {Array} array (possibly empty) of InternalProperty instances
+ */
+ObjectMirror.GetInternalProperties = function(value) {
+ if (IS_STRING_WRAPPER(value) || IS_NUMBER_WRAPPER(value) ||
+ IS_BOOLEAN_WRAPPER(value)) {
+ var primitiveValue = %_ValueOf(value);
+ return [new InternalPropertyMirror("[[PrimitiveValue]]", primitiveValue)];
+ } else if (IS_FUNCTION(value)) {
+ var bindings = %BoundFunctionGetBindings(value);
+ var result = [];
+ if (bindings && IS_ARRAY(bindings)) {
+ result.push(new InternalPropertyMirror("[[TargetFunction]]",
+ bindings[0]));
+ result.push(new InternalPropertyMirror("[[BoundThis]]", bindings[1]));
+ var boundArgs = [];
+ for (var i = 2; i < bindings.length; i++) {
+ boundArgs.push(bindings[i]);
+ }
+ result.push(new InternalPropertyMirror("[[BoundArgs]]", boundArgs));
+ }
+ return result;
+ }
+ return [];
+}
+
+
+/**
* Mirror object for functions.
* @param {function} value The function object reflected by this mirror.
* @constructor
@@ -1270,6 +1303,33 @@ PropertyMirror.prototype.isNative = function() {
};
+/**
+ * Mirror object for internal properties. Internal property reflects properties
+ * not accessible from user code such as [[BoundThis]] in bound function.
+ * Their names are merely symbolic.
+ * @param {string} name The name of the property
+ * @param {value} property value
+ * @constructor
+ * @extends Mirror
+ */
+function InternalPropertyMirror(name, value) {
+ %_CallFunction(this, INTERNAL_PROPERTY_TYPE, Mirror);
+ this.name_ = name;
+ this.value_ = value;
+}
+inherits(InternalPropertyMirror, Mirror);
+
+
+InternalPropertyMirror.prototype.name = function() {
+ return this.name_;
+};
+
+
+InternalPropertyMirror.prototype.value = function() {
+ return MakeMirror(this.value_, false);
+};
+
+
var kFrameDetailsFrameIdIndex = 0;
var kFrameDetailsReceiverIndex = 1;
var kFrameDetailsFunctionIndex = 2;
@@ -1750,6 +1810,15 @@ FrameMirror.prototype.localsText = function() {
};
+FrameMirror.prototype.restart = function() {
+ var result = %LiveEditRestartFrame(this.break_id_, this.index_);
+ if (IS_UNDEFINED(result)) {
+ result = "Failed to find requested frame";
+ }
+ return result;
+};
+
+
FrameMirror.prototype.toText = function(opt_locals) {
var result = '';
result += '#' + (this.index() <= 9 ? '0' : '') + this.index();
@@ -2195,7 +2264,8 @@ JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
break;
case PROPERTY_TYPE:
- throw new Error('PropertyMirror cannot be serialized independeltly');
+ case INTERNAL_PROPERTY_TYPE:
+ throw new Error('PropertyMirror cannot be serialized independently');
break;
case FRAME_TYPE:
@@ -2271,7 +2341,8 @@ JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
* "prototypeObject":{"ref":<number>},
* "namedInterceptor":<boolean>,
* "indexedInterceptor":<boolean>,
- * "properties":[<properties>]}
+ * "properties":[<properties>],
+ * "internalProperties":[<internal properties>]}
*/
JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
details) {
@@ -2282,11 +2353,6 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
content.protoObject = this.serializeReference(mirror.protoObject());
content.prototypeObject = this.serializeReference(mirror.prototypeObject());
- var primitiveValue = mirror.primitiveValue();
- if (!IS_UNDEFINED(primitiveValue)) {
- content.primitiveValue = this.serializeReference(primitiveValue);
- }
-
// Add flags to indicate whether there are interceptors.
if (mirror.hasNamedInterceptor()) {
content.namedInterceptor = true;
@@ -2348,6 +2414,15 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
}
}
content.properties = p;
+
+ var internalProperties = mirror.internalProperties();
+ if (internalProperties.length > 0) {
+ var ip = [];
+ for (var i = 0; i < internalProperties.length; i++) {
+ ip.push(this.serializeInternalProperty_(internalProperties[i]));
+ }
+ content.internalProperties = ip;
+ }
};
@@ -2415,6 +2490,33 @@ JSONProtocolSerializer.prototype.serializeProperty_ = function(propertyMirror) {
};
+/**
+ * Serialize internal property information to the following JSON format for
+ * building the array of properties.
+ *
+ * {"name":"<property name>",
+ * "ref":<number>}
+ *
+ * {"name":"[[BoundThis]]","ref":117}
+ *
+ * @param {InternalPropertyMirror} propertyMirror The property to serialize.
+ * @returns {Object} Protocol object representing the property.
+ */
+JSONProtocolSerializer.prototype.serializeInternalProperty_ =
+ function(propertyMirror) {
+ var result = {};
+
+ result.name = propertyMirror.name();
+ var propertyValue = propertyMirror.value();
+ if (this.inlineRefs_() && propertyValue.isValue()) {
+ result.value = this.serializeReferenceWithDisplayData_(propertyValue);
+ } else {
+ result.ref = propertyValue.handle();
+ }
+ return result;
+};
+
+
JSONProtocolSerializer.prototype.serializeFrame_ = function(mirror, content) {
content.index = mirror.index();
content.receiver = this.serializeReference(mirror.receiver());
diff --git a/deps/v8/src/mksnapshot.cc b/deps/v8/src/mksnapshot.cc
index e426a5809..d7775517b 100644
--- a/deps/v8/src/mksnapshot.cc
+++ b/deps/v8/src/mksnapshot.cc
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include <errno.h>
+#include <stdio.h>
#ifdef COMPRESS_STARTUP_DATA_BZ2
#include <bzlib.h>
#endif
@@ -33,6 +35,7 @@
#include "v8.h"
#include "bootstrapper.h"
+#include "flags.h"
#include "natives.h"
#include "platform.h"
#include "serialize.h"
@@ -163,30 +166,37 @@ class CppByteSink : public PartialSnapshotSink {
}
void WriteSpaceUsed(
+ const char* prefix,
int new_space_used,
int pointer_space_used,
int data_space_used,
int code_space_used,
int map_space_used,
- int cell_space_used,
- int large_space_used) {
- fprintf(fp_, "const int Snapshot::new_space_used_ = %d;\n", new_space_used);
+ int cell_space_used) {
fprintf(fp_,
- "const int Snapshot::pointer_space_used_ = %d;\n",
+ "const int Snapshot::%snew_space_used_ = %d;\n",
+ prefix,
+ new_space_used);
+ fprintf(fp_,
+ "const int Snapshot::%spointer_space_used_ = %d;\n",
+ prefix,
pointer_space_used);
fprintf(fp_,
- "const int Snapshot::data_space_used_ = %d;\n",
+ "const int Snapshot::%sdata_space_used_ = %d;\n",
+ prefix,
data_space_used);
fprintf(fp_,
- "const int Snapshot::code_space_used_ = %d;\n",
+ "const int Snapshot::%scode_space_used_ = %d;\n",
+ prefix,
code_space_used);
- fprintf(fp_, "const int Snapshot::map_space_used_ = %d;\n", map_space_used);
fprintf(fp_,
- "const int Snapshot::cell_space_used_ = %d;\n",
- cell_space_used);
+ "const int Snapshot::%smap_space_used_ = %d;\n",
+ prefix,
+ map_space_used);
fprintf(fp_,
- "const int Snapshot::large_space_used_ = %d;\n",
- large_space_used);
+ "const int Snapshot::%scell_space_used_ = %d;\n",
+ prefix,
+ cell_space_used);
}
void WritePartialSnapshot() {
@@ -308,6 +318,62 @@ int main(int argc, char** argv) {
"\nException thrown while compiling natives - see above.\n\n");
exit(1);
}
+ if (i::FLAG_extra_code != NULL) {
+ context->Enter();
+ // Capture 100 frames if anything happens.
+ V8::SetCaptureStackTraceForUncaughtExceptions(true, 100);
+ HandleScope scope;
+ const char* name = i::FLAG_extra_code;
+ FILE* file = i::OS::FOpen(name, "rb");
+ if (file == NULL) {
+ fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno);
+ exit(1);
+ }
+
+ fseek(file, 0, SEEK_END);
+ int size = ftell(file);
+ rewind(file);
+
+ char* chars = new char[size + 1];
+ chars[size] = '\0';
+ for (int i = 0; i < size;) {
+ int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
+ if (read < 0) {
+ fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno);
+ exit(1);
+ }
+ i += read;
+ }
+ fclose(file);
+ Local<String> source = String::New(chars);
+ TryCatch try_catch;
+ Local<Script> script = Script::Compile(source);
+ if (try_catch.HasCaught()) {
+ fprintf(stderr, "Failure compiling '%s' (see above)\n", name);
+ exit(1);
+ }
+ script->Run();
+ if (try_catch.HasCaught()) {
+ fprintf(stderr, "Failure running '%s'\n", name);
+ Local<Message> message = try_catch.Message();
+ Local<String> message_string = message->Get();
+ Local<String> message_line = message->GetSourceLine();
+ int len = 2 + message_string->Utf8Length() + message_line->Utf8Length();
+ char* buf = new char(len);
+ message_string->WriteUtf8(buf);
+ fprintf(stderr, "%s at line %d\n", buf, message->GetLineNumber());
+ message_line->WriteUtf8(buf);
+ fprintf(stderr, "%s\n", buf);
+ int from = message->GetStartColumn();
+ int to = message->GetEndColumn();
+ int i;
+ for (i = 0; i < from; i++) fprintf(stderr, " ");
+ for ( ; i <= to; i++) fprintf(stderr, "^");
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+ context->Exit();
+ }
// Make sure all builtin scripts are cached.
{ HandleScope scope;
for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
@@ -341,12 +407,20 @@ int main(int argc, char** argv) {
sink.WritePartialSnapshot();
sink.WriteSpaceUsed(
+ "context_",
partial_ser.CurrentAllocationAddress(i::NEW_SPACE),
partial_ser.CurrentAllocationAddress(i::OLD_POINTER_SPACE),
partial_ser.CurrentAllocationAddress(i::OLD_DATA_SPACE),
partial_ser.CurrentAllocationAddress(i::CODE_SPACE),
partial_ser.CurrentAllocationAddress(i::MAP_SPACE),
- partial_ser.CurrentAllocationAddress(i::CELL_SPACE),
- partial_ser.CurrentAllocationAddress(i::LO_SPACE));
+ partial_ser.CurrentAllocationAddress(i::CELL_SPACE));
+ sink.WriteSpaceUsed(
+ "",
+ ser.CurrentAllocationAddress(i::NEW_SPACE),
+ ser.CurrentAllocationAddress(i::OLD_POINTER_SPACE),
+ ser.CurrentAllocationAddress(i::OLD_DATA_SPACE),
+ ser.CurrentAllocationAddress(i::CODE_SPACE),
+ ser.CurrentAllocationAddress(i::MAP_SPACE),
+ ser.CurrentAllocationAddress(i::CELL_SPACE));
return 0;
}
diff --git a/deps/v8/src/objects-debug.cc b/deps/v8/src/objects-debug.cc
index 5aac50319..be9659296 100644
--- a/deps/v8/src/objects-debug.cc
+++ b/deps/v8/src/objects-debug.cc
@@ -35,7 +35,7 @@
namespace v8 {
namespace internal {
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
void MaybeObject::Verify() {
Object* this_as_object;
@@ -55,18 +55,18 @@ void Object::VerifyPointer(Object* p) {
if (p->IsHeapObject()) {
HeapObject::VerifyHeapPointer(p);
} else {
- ASSERT(p->IsSmi());
+ CHECK(p->IsSmi());
}
}
void Smi::SmiVerify() {
- ASSERT(IsSmi());
+ CHECK(IsSmi());
}
void Failure::FailureVerify() {
- ASSERT(IsFailure());
+ CHECK(IsFailure());
}
@@ -207,68 +207,68 @@ void HeapObject::HeapObjectVerify() {
void HeapObject::VerifyHeapPointer(Object* p) {
- ASSERT(p->IsHeapObject());
- ASSERT(HEAP->Contains(HeapObject::cast(p)));
+ CHECK(p->IsHeapObject());
+ CHECK(HEAP->Contains(HeapObject::cast(p)));
}
void HeapNumber::HeapNumberVerify() {
- ASSERT(IsHeapNumber());
+ CHECK(IsHeapNumber());
}
void ByteArray::ByteArrayVerify() {
- ASSERT(IsByteArray());
+ CHECK(IsByteArray());
}
void FreeSpace::FreeSpaceVerify() {
- ASSERT(IsFreeSpace());
+ CHECK(IsFreeSpace());
}
void ExternalPixelArray::ExternalPixelArrayVerify() {
- ASSERT(IsExternalPixelArray());
+ CHECK(IsExternalPixelArray());
}
void ExternalByteArray::ExternalByteArrayVerify() {
- ASSERT(IsExternalByteArray());
+ CHECK(IsExternalByteArray());
}
void ExternalUnsignedByteArray::ExternalUnsignedByteArrayVerify() {
- ASSERT(IsExternalUnsignedByteArray());
+ CHECK(IsExternalUnsignedByteArray());
}
void ExternalShortArray::ExternalShortArrayVerify() {
- ASSERT(IsExternalShortArray());
+ CHECK(IsExternalShortArray());
}
void ExternalUnsignedShortArray::ExternalUnsignedShortArrayVerify() {
- ASSERT(IsExternalUnsignedShortArray());
+ CHECK(IsExternalUnsignedShortArray());
}
void ExternalIntArray::ExternalIntArrayVerify() {
- ASSERT(IsExternalIntArray());
+ CHECK(IsExternalIntArray());
}
void ExternalUnsignedIntArray::ExternalUnsignedIntArrayVerify() {
- ASSERT(IsExternalUnsignedIntArray());
+ CHECK(IsExternalUnsignedIntArray());
}
void ExternalFloatArray::ExternalFloatArrayVerify() {
- ASSERT(IsExternalFloatArray());
+ CHECK(IsExternalFloatArray());
}
void ExternalDoubleArray::ExternalDoubleArrayVerify() {
- ASSERT(IsExternalDoubleArray());
+ CHECK(IsExternalDoubleArray());
}
@@ -277,8 +277,8 @@ void JSObject::JSObjectVerify() {
VerifyHeapPointer(elements());
if (GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) {
- ASSERT(this->elements()->IsFixedArray());
- ASSERT(this->elements()->length() >= 2);
+ CHECK(this->elements()->IsFixedArray());
+ CHECK_GE(this->elements()->length(), 2);
}
if (HasFastProperties()) {
@@ -286,34 +286,41 @@ void JSObject::JSObjectVerify() {
(map()->inobject_properties() + properties()->length() -
map()->NextFreePropertyIndex()));
}
- ASSERT_EQ((map()->has_fast_smi_or_object_elements() ||
+ CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
(elements() == GetHeap()->empty_fixed_array())),
(elements()->map() == GetHeap()->fixed_array_map() ||
elements()->map() == GetHeap()->fixed_cow_array_map()));
- ASSERT(map()->has_fast_object_elements() == HasFastObjectElements());
+ CHECK(map()->has_fast_object_elements() == HasFastObjectElements());
}
void Map::MapVerify() {
- ASSERT(!HEAP->InNewSpace(this));
- ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
- ASSERT(instance_size() == kVariableSizeSentinel ||
+ CHECK(!HEAP->InNewSpace(this));
+ CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
+ CHECK(instance_size() == kVariableSizeSentinel ||
(kPointerSize <= instance_size() &&
instance_size() < HEAP->Capacity()));
VerifyHeapPointer(prototype());
VerifyHeapPointer(instance_descriptors());
+ DescriptorArray* descriptors = instance_descriptors();
+ for (int i = 0; i < NumberOfOwnDescriptors(); ++i) {
+ CHECK_EQ(i, descriptors->GetDetails(i).descriptor_index() - 1);
+ }
SLOW_ASSERT(instance_descriptors()->IsSortedNoDuplicates());
- SLOW_ASSERT(instance_descriptors()->IsConsistentWithBackPointers(this));
+ if (HasTransitionArray()) {
+ SLOW_ASSERT(transitions()->IsSortedNoDuplicates());
+ SLOW_ASSERT(transitions()->IsConsistentWithBackPointers(this));
+ }
}
void Map::SharedMapVerify() {
MapVerify();
- ASSERT(is_shared());
- ASSERT(instance_descriptors()->IsEmpty());
- ASSERT_EQ(0, pre_allocated_property_fields());
- ASSERT_EQ(0, unused_property_fields());
- ASSERT_EQ(StaticVisitorBase::GetVisitorId(instance_type(), instance_size()),
+ CHECK(is_shared());
+ CHECK(instance_descriptors()->IsEmpty());
+ CHECK_EQ(0, pre_allocated_property_fields());
+ CHECK_EQ(0, unused_property_fields());
+ CHECK_EQ(StaticVisitorBase::GetVisitorId(instance_type(), instance_size()),
visitor_id());
}
@@ -321,21 +328,21 @@ void Map::SharedMapVerify() {
void CodeCache::CodeCacheVerify() {
VerifyHeapPointer(default_cache());
VerifyHeapPointer(normal_type_cache());
- ASSERT(default_cache()->IsFixedArray());
- ASSERT(normal_type_cache()->IsUndefined()
+ CHECK(default_cache()->IsFixedArray());
+ CHECK(normal_type_cache()->IsUndefined()
|| normal_type_cache()->IsCodeCacheHashTable());
}
void PolymorphicCodeCache::PolymorphicCodeCacheVerify() {
VerifyHeapPointer(cache());
- ASSERT(cache()->IsUndefined() || cache()->IsPolymorphicCodeCacheHashTable());
+ CHECK(cache()->IsUndefined() || cache()->IsPolymorphicCodeCacheHashTable());
}
void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
- VerifyObjectField(kIcTotalCountOffset);
- VerifyObjectField(kIcWithTypeinfoCountOffset);
+ VerifyObjectField(kStorage1Offset);
+ VerifyObjectField(kStorage2Offset);
VerifyHeapPointer(type_feedback_cells());
}
@@ -361,7 +368,7 @@ void FixedDoubleArray::FixedDoubleArrayVerify() {
for (int i = 0; i < length(); i++) {
if (!is_the_hole(i)) {
double value = get_scalar(i);
- ASSERT(!isnan(value) ||
+ CHECK(!isnan(value) ||
(BitCast<uint64_t>(value) ==
BitCast<uint64_t>(canonical_not_the_hole_nan_as_double())) ||
((BitCast<uint64_t>(value) & Double::kSignMask) != 0));
@@ -371,11 +378,10 @@ void FixedDoubleArray::FixedDoubleArrayVerify() {
void JSModule::JSModuleVerify() {
- Object* v = context();
- if (v->IsHeapObject()) {
- VerifyHeapPointer(v);
- }
- CHECK(v->IsUndefined() || v->IsModuleContext());
+ VerifyObjectField(kContextOffset);
+ VerifyObjectField(kScopeInfoOffset);
+ CHECK(context()->IsUndefined() ||
+ Context::cast(context())->IsModuleContext());
}
@@ -502,6 +508,7 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() {
CHECK(IsSharedFunctionInfo());
VerifyObjectField(kNameOffset);
VerifyObjectField(kCodeOffset);
+ VerifyObjectField(kOptimizedCodeMapOffset);
VerifyObjectField(kScopeInfoOffset);
VerifyObjectField(kInstanceClassNameOffset);
VerifyObjectField(kFunctionDataOffset);
@@ -513,7 +520,7 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() {
void JSGlobalProxy::JSGlobalProxyVerify() {
CHECK(IsJSGlobalProxy());
JSObjectVerify();
- VerifyObjectField(JSGlobalProxy::kContextOffset);
+ VerifyObjectField(JSGlobalProxy::kNativeContextOffset);
// Make sure that this object has no properties, elements.
CHECK_EQ(0, properties()->length());
CHECK(HasFastObjectElements());
@@ -548,14 +555,14 @@ void Oddball::OddballVerify() {
VerifyHeapPointer(to_string());
Object* number = to_number();
if (number->IsHeapObject()) {
- ASSERT(number == HEAP->nan_value());
+ CHECK(number == HEAP->nan_value());
} else {
- ASSERT(number->IsSmi());
+ CHECK(number->IsSmi());
int value = Smi::cast(number)->value();
// Hidden oddballs have negative smis.
const int kLeastHiddenOddballNumber = -4;
- ASSERT(value <= 1);
- ASSERT(value >= kLeastHiddenOddballNumber);
+ CHECK_LE(value, 1);
+ CHECK(value >= kLeastHiddenOddballNumber);
}
}
@@ -584,8 +591,8 @@ void Code::CodeVerify() {
void JSArray::JSArrayVerify() {
JSObjectVerify();
- ASSERT(length()->IsNumber() || length()->IsUndefined());
- ASSERT(elements()->IsUndefined() ||
+ CHECK(length()->IsNumber() || length()->IsUndefined());
+ CHECK(elements()->IsUndefined() ||
elements()->IsFixedArray() ||
elements()->IsFixedDoubleArray());
}
@@ -595,7 +602,7 @@ void JSSet::JSSetVerify() {
CHECK(IsJSSet());
JSObjectVerify();
VerifyHeapPointer(table());
- ASSERT(table()->IsHashTable() || table()->IsUndefined());
+ CHECK(table()->IsHashTable() || table()->IsUndefined());
}
@@ -603,7 +610,7 @@ void JSMap::JSMapVerify() {
CHECK(IsJSMap());
JSObjectVerify();
VerifyHeapPointer(table());
- ASSERT(table()->IsHashTable() || table()->IsUndefined());
+ CHECK(table()->IsHashTable() || table()->IsUndefined());
}
@@ -611,17 +618,17 @@ void JSWeakMap::JSWeakMapVerify() {
CHECK(IsJSWeakMap());
JSObjectVerify();
VerifyHeapPointer(table());
- ASSERT(table()->IsHashTable() || table()->IsUndefined());
+ CHECK(table()->IsHashTable() || table()->IsUndefined());
}
void JSRegExp::JSRegExpVerify() {
JSObjectVerify();
- ASSERT(data()->IsUndefined() || data()->IsFixedArray());
+ CHECK(data()->IsUndefined() || data()->IsFixedArray());
switch (TypeTag()) {
case JSRegExp::ATOM: {
FixedArray* arr = FixedArray::cast(data());
- ASSERT(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
+ CHECK(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
break;
}
case JSRegExp::IRREGEXP: {
@@ -632,26 +639,26 @@ void JSRegExp::JSRegExpVerify() {
// Smi : Not compiled yet (-1) or code prepared for flushing.
// JSObject: Compilation error.
// Code/ByteArray: Compiled code.
- ASSERT(ascii_data->IsSmi() ||
+ CHECK(ascii_data->IsSmi() ||
(is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
- ASSERT(uc16_data->IsSmi() ||
+ CHECK(uc16_data->IsSmi() ||
(is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
Object* ascii_saved = arr->get(JSRegExp::kIrregexpASCIICodeSavedIndex);
- ASSERT(ascii_saved->IsSmi() || ascii_saved->IsString() ||
+ CHECK(ascii_saved->IsSmi() || ascii_saved->IsString() ||
ascii_saved->IsCode());
Object* uc16_saved = arr->get(JSRegExp::kIrregexpUC16CodeSavedIndex);
- ASSERT(uc16_saved->IsSmi() || uc16_saved->IsString() ||
+ CHECK(uc16_saved->IsSmi() || uc16_saved->IsString() ||
uc16_saved->IsCode());
- ASSERT(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
- ASSERT(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
+ CHECK(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
+ CHECK(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
break;
}
default:
- ASSERT_EQ(JSRegExp::NOT_COMPILED, TypeTag());
- ASSERT(data()->IsUndefined());
+ CHECK_EQ(JSRegExp::NOT_COMPILED, TypeTag());
+ CHECK(data()->IsUndefined());
break;
}
}
@@ -660,7 +667,7 @@ void JSRegExp::JSRegExpVerify() {
void JSProxy::JSProxyVerify() {
CHECK(IsJSProxy());
VerifyPointer(handler());
- ASSERT(hash()->IsSmi() || hash()->IsUndefined());
+ CHECK(hash()->IsSmi() || hash()->IsUndefined());
}
@@ -673,7 +680,7 @@ void JSFunctionProxy::JSFunctionProxyVerify() {
void Foreign::ForeignVerify() {
- ASSERT(IsForeign());
+ CHECK(IsForeign());
}
@@ -777,6 +784,47 @@ void Script::ScriptVerify() {
}
+void JSFunctionResultCache::JSFunctionResultCacheVerify() {
+ JSFunction::cast(get(kFactoryIndex))->Verify();
+
+ int size = Smi::cast(get(kCacheSizeIndex))->value();
+ CHECK(kEntriesIndex <= size);
+ CHECK(size <= length());
+ CHECK_EQ(0, size % kEntrySize);
+
+ int finger = Smi::cast(get(kFingerIndex))->value();
+ CHECK(kEntriesIndex <= finger);
+ CHECK((finger < size) || (finger == kEntriesIndex && finger == size));
+ CHECK_EQ(0, finger % kEntrySize);
+
+ if (FLAG_enable_slow_asserts) {
+ for (int i = kEntriesIndex; i < size; i++) {
+ CHECK(!get(i)->IsTheHole());
+ get(i)->Verify();
+ }
+ for (int i = size; i < length(); i++) {
+ CHECK(get(i)->IsTheHole());
+ get(i)->Verify();
+ }
+ }
+}
+
+
+void NormalizedMapCache::NormalizedMapCacheVerify() {
+ FixedArray::cast(this)->Verify();
+ if (FLAG_enable_slow_asserts) {
+ for (int i = 0; i < length(); i++) {
+ Object* e = get(i);
+ if (e->IsMap()) {
+ Map::cast(e)->SharedMapVerify();
+ } else {
+ CHECK(e->IsUndefined());
+ }
+ }
+ }
+}
+
+
#ifdef ENABLE_DEBUGGER_SUPPORT
void DebugInfo::DebugInfoVerify() {
CHECK(IsDebugInfo());
@@ -795,7 +843,9 @@ void BreakPointInfo::BreakPointInfoVerify() {
VerifyPointer(break_point_objects());
}
#endif // ENABLE_DEBUGGER_SUPPORT
+#endif // VERIFY_HEAP
+#ifdef DEBUG
void JSObject::IncrementSpillStatistics(SpillInformation* info) {
info->number_of_objects_++;
@@ -894,17 +944,18 @@ void JSObject::SpillInformation::Print() {
}
-bool DescriptorArray::IsSortedNoDuplicates() {
+bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
+ if (valid_entries == -1) valid_entries = number_of_descriptors();
String* current_key = NULL;
uint32_t current = 0;
for (int i = 0; i < number_of_descriptors(); i++) {
- String* key = GetKey(i);
+ String* key = GetSortedKey(i);
if (key == current_key) {
PrintDescriptors();
return false;
}
current_key = key;
- uint32_t hash = GetKey(i)->Hash();
+ uint32_t hash = GetSortedKey(i)->Hash();
if (hash < current) {
PrintDescriptors();
return false;
@@ -915,101 +966,42 @@ bool DescriptorArray::IsSortedNoDuplicates() {
}
-static bool CheckOneBackPointer(Map* current_map, Object* target) {
- return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
-}
-
-
-bool DescriptorArray::IsConsistentWithBackPointers(Map* current_map) {
- for (int i = 0; i < number_of_descriptors(); ++i) {
- switch (GetType(i)) {
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- if (!CheckOneBackPointer(current_map, GetValue(i))) {
- return false;
- }
- break;
- case CALLBACKS: {
- Object* object = GetValue(i);
- if (object->IsAccessorPair()) {
- AccessorPair* accessors = AccessorPair::cast(object);
- if (!CheckOneBackPointer(current_map, accessors->getter())) {
- return false;
- }
- if (!CheckOneBackPointer(current_map, accessors->setter())) {
- return false;
- }
- }
- break;
- }
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case HANDLER:
- case INTERCEPTOR:
- case NULL_DESCRIPTOR:
- break;
+bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
+ ASSERT(valid_entries == -1);
+ String* current_key = NULL;
+ uint32_t current = 0;
+ for (int i = 0; i < number_of_transitions(); i++) {
+ String* key = GetSortedKey(i);
+ if (key == current_key) {
+ PrintTransitions();
+ return false;
+ }
+ current_key = key;
+ uint32_t hash = GetSortedKey(i)->Hash();
+ if (hash < current) {
+ PrintTransitions();
+ return false;
}
+ current = hash;
}
return true;
}
-void JSFunctionResultCache::JSFunctionResultCacheVerify() {
- JSFunction::cast(get(kFactoryIndex))->Verify();
-
- int size = Smi::cast(get(kCacheSizeIndex))->value();
- ASSERT(kEntriesIndex <= size);
- ASSERT(size <= length());
- ASSERT_EQ(0, size % kEntrySize);
-
- int finger = Smi::cast(get(kFingerIndex))->value();
- ASSERT(kEntriesIndex <= finger);
- ASSERT((finger < size) || (finger == kEntriesIndex && finger == size));
- ASSERT_EQ(0, finger % kEntrySize);
-
- if (FLAG_enable_slow_asserts) {
- for (int i = kEntriesIndex; i < size; i++) {
- ASSERT(!get(i)->IsTheHole());
- get(i)->Verify();
- }
- for (int i = size; i < length(); i++) {
- ASSERT(get(i)->IsTheHole());
- get(i)->Verify();
- }
- }
+static bool CheckOneBackPointer(Map* current_map, Object* target) {
+ return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
}
-void NormalizedMapCache::NormalizedMapCacheVerify() {
- FixedArray::cast(this)->Verify();
- if (FLAG_enable_slow_asserts) {
- for (int i = 0; i < length(); i++) {
- Object* e = get(i);
- if (e->IsMap()) {
- Map::cast(e)->SharedMapVerify();
- } else {
- ASSERT(e->IsUndefined());
- }
- }
+bool TransitionArray::IsConsistentWithBackPointers(Map* current_map) {
+ if (HasElementsTransition() &&
+ !CheckOneBackPointer(current_map, elements_transition())) {
+ return false;
}
-}
-
-
-void Map::ZapInstanceDescriptors() {
- DescriptorArray* descriptors = instance_descriptors();
- if (descriptors == GetHeap()->empty_descriptor_array()) return;
- MemsetPointer(descriptors->data_start(),
- GetHeap()->the_hole_value(),
- descriptors->length());
-}
-
-
-void Map::ZapPrototypeTransitions() {
- FixedArray* proto_transitions = prototype_transitions();
- MemsetPointer(proto_transitions->data_start(),
- GetHeap()->the_hole_value(),
- proto_transitions->length());
+ for (int i = 0; i < number_of_transitions(); ++i) {
+ if (!CheckOneBackPointer(current_map, GetTarget(i))) return false;
+ }
+ return true;
}
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h
index 4f66af28a..d2f996bae 100644
--- a/deps/v8/src/objects-inl.h
+++ b/deps/v8/src/objects-inl.h
@@ -47,6 +47,7 @@
#include "v8memory.h"
#include "factory.h"
#include "incremental-marking.h"
+#include "transitions-inl.h"
namespace v8 {
namespace internal {
@@ -381,6 +382,9 @@ uint32_t StringShape::full_representation_tag() {
STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
Internals::kFullStringRepresentationMask);
+STATIC_CHECK(static_cast<uint32_t>(kStringEncodingMask) ==
+ Internals::kStringEncodingMask);
+
bool StringShape::IsSequentialAscii() {
return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
@@ -397,6 +401,12 @@ bool StringShape::IsExternalAscii() {
}
+STATIC_CHECK((kExternalStringTag | kAsciiStringTag) ==
+ Internals::kExternalAsciiRepresentationTag);
+
+STATIC_CHECK(v8::String::ASCII_ENCODING == kAsciiStringTag);
+
+
bool StringShape::IsExternalTwoByte() {
return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
}
@@ -405,6 +415,7 @@ bool StringShape::IsExternalTwoByte() {
STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
Internals::kExternalTwoByteRepresentationTag);
+STATIC_CHECK(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
uc32 FlatStringReader::Get(int index) {
ASSERT(0 <= index && index <= length_);
@@ -524,6 +535,11 @@ bool Object::IsDescriptorArray() {
}
+bool Object::IsTransitionArray() {
+ return IsFixedArray();
+}
+
+
bool Object::IsDeoptimizationInputData() {
// Must be a fixed array.
if (!IsFixedArray()) return false;
@@ -562,31 +578,23 @@ bool Object::IsTypeFeedbackCells() {
bool Object::IsContext() {
- if (Object::IsHeapObject()) {
- Map* map = HeapObject::cast(this)->map();
- Heap* heap = map->GetHeap();
- return (map == heap->function_context_map() ||
- map == heap->catch_context_map() ||
- map == heap->with_context_map() ||
- map == heap->global_context_map() ||
- map == heap->block_context_map() ||
- map == heap->module_context_map());
- }
- return false;
-}
-
-
-bool Object::IsGlobalContext() {
- return Object::IsHeapObject() &&
- HeapObject::cast(this)->map() ==
- HeapObject::cast(this)->GetHeap()->global_context_map();
+ if (!Object::IsHeapObject()) return false;
+ Map* map = HeapObject::cast(this)->map();
+ Heap* heap = map->GetHeap();
+ return (map == heap->function_context_map() ||
+ map == heap->catch_context_map() ||
+ map == heap->with_context_map() ||
+ map == heap->native_context_map() ||
+ map == heap->block_context_map() ||
+ map == heap->module_context_map() ||
+ map == heap->global_context_map());
}
-bool Object::IsModuleContext() {
+bool Object::IsNativeContext() {
return Object::IsHeapObject() &&
HeapObject::cast(this)->map() ==
- HeapObject::cast(this)->GetHeap()->module_context_map();
+ HeapObject::cast(this)->GetHeap()->native_context_map();
}
@@ -666,7 +674,7 @@ bool Object::IsJSFunctionResultCache() {
% JSFunctionResultCache::kEntrySize != 0) {
return false;
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
reinterpret_cast<JSFunctionResultCache*>(this)->
JSFunctionResultCacheVerify();
@@ -681,7 +689,7 @@ bool Object::IsNormalizedMapCache() {
if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
return false;
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
}
@@ -1102,13 +1110,13 @@ HeapObject* MapWord::ToForwardingAddress() {
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
void HeapObject::VerifyObjectField(int offset) {
VerifyPointer(READ_FIELD(this, offset));
}
void HeapObject::VerifySmiField(int offset) {
- ASSERT(READ_FIELD(this, offset)->IsSmi());
+ CHECK(READ_FIELD(this, offset)->IsSmi());
}
#endif
@@ -1333,8 +1341,8 @@ MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
ElementsKind from_kind = current_map->elements_kind();
if (from_kind == to_kind) return current_map;
- Context* global_context = isolate->context()->global_context();
- Object* maybe_array_maps = global_context->js_array_maps();
+ Context* native_context = isolate->context()->native_context();
+ Object* maybe_array_maps = native_context->js_array_maps();
if (maybe_array_maps->IsFixedArray()) {
FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
if (array_maps->get(from_kind) == current_map) {
@@ -1406,6 +1414,43 @@ MaybeObject* JSObject::ResetElements() {
}
+MaybeObject* JSObject::AddFastPropertyUsingMap(Map* map) {
+ ASSERT(this->map()->NumberOfOwnDescriptors() + 1 ==
+ map->NumberOfOwnDescriptors());
+ if (this->map()->unused_property_fields() == 0) {
+ int new_size = properties()->length() + map->unused_property_fields() + 1;
+ FixedArray* new_properties;
+ MaybeObject* maybe_properties = properties()->CopySize(new_size);
+ if (!maybe_properties->To(&new_properties)) return maybe_properties;
+ set_properties(new_properties);
+ }
+ set_map(map);
+ return this;
+}
+
+
+bool JSObject::TryTransitionToField(Handle<JSObject> object,
+ Handle<String> key) {
+ if (!object->map()->HasTransitionArray()) return false;
+ Handle<TransitionArray> transitions(object->map()->transitions());
+ int transition = transitions->Search(*key);
+ if (transition == TransitionArray::kNotFound) return false;
+ PropertyDetails target_details = transitions->GetTargetDetails(transition);
+ if (target_details.type() != FIELD) return false;
+ if (target_details.attributes() != NONE) return false;
+ Handle<Map> target(transitions->GetTarget(transition));
+ JSObject::AddFastPropertyUsingMap(object, target);
+ return true;
+}
+
+
+int JSObject::LastAddedFieldIndex() {
+ Map* map = this->map();
+ int last_added = map->LastAdded();
+ return map->instance_descriptors()->GetFieldIndex(last_added);
+}
+
+
ACCESSORS(Oddball, to_string, String, kToStringOffset)
ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
@@ -1602,6 +1647,7 @@ void JSObject::InitializeBody(Map* map,
bool JSObject::HasFastProperties() {
+ ASSERT(properties()->IsDictionary() == map()->is_dictionary_map());
return !properties()->IsDictionary();
}
@@ -1665,6 +1711,23 @@ bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
}
+
+void Object::VerifyApiCallResultType() {
+#if ENABLE_EXTRA_CHECKS
+ if (!(IsSmi() ||
+ IsString() ||
+ IsSpecObject() ||
+ IsHeapNumber() ||
+ IsUndefined() ||
+ IsTrue() ||
+ IsFalse() ||
+ IsNull())) {
+ FATAL("API call returned invalid object");
+ }
+#endif // ENABLE_EXTRA_CHECKS
+}
+
+
FixedArrayBase* FixedArrayBase::cast(Object* object) {
ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
return reinterpret_cast<FixedArrayBase*>(object);
@@ -1863,7 +1926,7 @@ void FixedArray::set_unchecked(Heap* heap,
void FixedArray::set_null_unchecked(Heap* heap, int index) {
ASSERT(index >= 0 && index < this->length());
- ASSERT(!HEAP->InNewSpace(heap->null_value()));
+ ASSERT(!heap->InNewSpace(heap->null_value()));
WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
}
@@ -1874,87 +1937,148 @@ Object** FixedArray::data_start() {
bool DescriptorArray::IsEmpty() {
- ASSERT(this->IsSmi() ||
- this->MayContainTransitions() ||
+ ASSERT(length() >= kFirstIndex ||
this == HEAP->empty_descriptor_array());
- return this->IsSmi() || length() < kFirstIndex;
+ return length() < kFirstIndex;
}
-bool DescriptorArray::MayContainTransitions() {
- return length() >= kTransitionsIndex;
+void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
+ WRITE_FIELD(
+ this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
}
-int DescriptorArray::bit_field3_storage() {
- Object* storage = READ_FIELD(this, kBitField3StorageOffset);
- return Smi::cast(storage)->value();
-}
+// Perform a binary search in a fixed array. Low and high are entry indices. If
+// there are three entries in this array it should be called with low=0 and
+// high=2.
+template<SearchMode search_mode, typename T>
+int BinarySearch(T* array, String* name, int low, int high, int valid_entries) {
+ uint32_t hash = name->Hash();
+ int limit = high;
+
+ ASSERT(low <= high);
-void DescriptorArray::set_bit_field3_storage(int value) {
- ASSERT(this->MayContainTransitions());
- WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
+ while (low != high) {
+ int mid = (low + high) / 2;
+ String* mid_name = array->GetSortedKey(mid);
+ uint32_t mid_hash = mid_name->Hash();
+
+ if (mid_hash >= hash) {
+ high = mid;
+ } else {
+ low = mid + 1;
+ }
+ }
+
+ for (; low <= limit; ++low) {
+ int sort_index = array->GetSortedKeyIndex(low);
+ String* entry = array->GetKey(sort_index);
+ if (entry->Hash() != hash) break;
+ if (entry->Equals(name)) {
+ if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
+ return sort_index;
+ }
+ return T::kNotFound;
+ }
+ }
+
+ return T::kNotFound;
}
-void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
- int first,
- int second) {
- Object* tmp = array->get(first);
- NoIncrementalWriteBarrierSet(array, first, array->get(second));
- NoIncrementalWriteBarrierSet(array, second, tmp);
+// Perform a linear search in this fixed array. len is the number of entry
+// indices that are valid.
+template<SearchMode search_mode, typename T>
+int LinearSearch(T* array, String* name, int len, int valid_entries) {
+ uint32_t hash = name->Hash();
+ if (search_mode == ALL_ENTRIES) {
+ for (int number = 0; number < len; number++) {
+ int sorted_index = array->GetSortedKeyIndex(number);
+ String* entry = array->GetKey(sorted_index);
+ uint32_t current_hash = entry->Hash();
+ if (current_hash > hash) break;
+ if (current_hash == hash && entry->Equals(name)) return sorted_index;
+ }
+ } else {
+ ASSERT(len >= valid_entries);
+ for (int number = 0; number < valid_entries; number++) {
+ String* entry = array->GetKey(number);
+ uint32_t current_hash = entry->Hash();
+ if (current_hash == hash && entry->Equals(name)) return number;
+ }
+ }
+ return T::kNotFound;
}
-int DescriptorArray::Search(String* name) {
- SLOW_ASSERT(IsSortedNoDuplicates());
+template<SearchMode search_mode, typename T>
+int Search(T* array, String* name, int valid_entries) {
+ if (search_mode == VALID_ENTRIES) {
+ SLOW_ASSERT(array->IsSortedNoDuplicates(valid_entries));
+ } else {
+ SLOW_ASSERT(array->IsSortedNoDuplicates());
+ }
- // Check for empty descriptor array.
- int nof = number_of_descriptors();
- if (nof == 0) return kNotFound;
+ int nof = array->number_of_entries();
+ if (nof == 0) return T::kNotFound;
// Fast case: do linear search for small arrays.
const int kMaxElementsForLinearSearch = 8;
- if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
- return LinearSearch(EXPECT_SORTED, name, nof);
+ if ((search_mode == ALL_ENTRIES &&
+ nof <= kMaxElementsForLinearSearch) ||
+ (search_mode == VALID_ENTRIES &&
+ valid_entries <= (kMaxElementsForLinearSearch * 3))) {
+ return LinearSearch<search_mode>(array, name, nof, valid_entries);
}
// Slow case: perform binary search.
- return BinarySearch(name, 0, nof - 1);
+ return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries);
+}
+
+
+int DescriptorArray::Search(String* name, int valid_descriptors) {
+ return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors);
}
-int DescriptorArray::SearchWithCache(String* name) {
- int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
+int DescriptorArray::SearchWithCache(String* name, Map* map) {
+ int number_of_own_descriptors = map->NumberOfOwnDescriptors();
+ if (number_of_own_descriptors == 0) return kNotFound;
+
+ DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
+ int number = cache->Lookup(map, name);
+
if (number == DescriptorLookupCache::kAbsent) {
- number = Search(name);
- GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
+ number = Search(name, number_of_own_descriptors);
+ cache->Update(map, name, number);
}
+
return number;
}
-Map* DescriptorArray::elements_transition_map() {
- if (!this->MayContainTransitions()) {
- return NULL;
- }
- Object* transition_map = get(kTransitionsIndex);
- if (transition_map == Smi::FromInt(0)) {
- return NULL;
- } else {
- return Map::cast(transition_map);
- }
+void Map::LookupDescriptor(JSObject* holder,
+ String* name,
+ LookupResult* result) {
+ DescriptorArray* descriptors = this->instance_descriptors();
+ int number = descriptors->SearchWithCache(name, this);
+ if (number == DescriptorArray::kNotFound) return result->NotFound();
+ result->DescriptorResult(holder, descriptors->GetDetails(number), number);
}
-void DescriptorArray::set_elements_transition_map(
- Map* transition_map, WriteBarrierMode mode) {
- ASSERT(this->length() > kTransitionsIndex);
- Heap* heap = GetHeap();
- WRITE_FIELD(this, kTransitionsOffset, transition_map);
- CONDITIONAL_WRITE_BARRIER(
- heap, this, kTransitionsOffset, transition_map, mode);
- ASSERT(DescriptorArray::cast(this));
+void Map::LookupTransition(JSObject* holder,
+ String* name,
+ LookupResult* result) {
+ if (HasTransitionArray()) {
+ TransitionArray* transition_array = transitions();
+ int number = transition_array->Search(name);
+ if (number != TransitionArray::kNotFound) {
+ return result->TransitionResult(holder, number);
+ }
+ }
+ result->NotFound();
}
@@ -1972,6 +2096,22 @@ String* DescriptorArray::GetKey(int descriptor_number) {
}
+int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
+ return GetDetails(descriptor_number).pointer();
+}
+
+
+String* DescriptorArray::GetSortedKey(int descriptor_number) {
+ return GetKey(GetSortedKeyIndex(descriptor_number));
+}
+
+
+void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
+ PropertyDetails details = GetDetails(descriptor_index);
+ set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
+}
+
+
Object** DescriptorArray::GetValueSlot(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
return HeapObject::RawField(
@@ -1986,12 +2126,6 @@ Object* DescriptorArray::GetValue(int descriptor_number) {
}
-void DescriptorArray::SetNullValueUnchecked(int descriptor_number, Heap* heap) {
- ASSERT(descriptor_number < number_of_descriptors());
- set_null_unchecked(heap, ToValueIndex(descriptor_number));
-}
-
-
PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
Object* details = get(ToDetailsIndex(descriptor_number));
@@ -1999,12 +2133,6 @@ PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
}
-void DescriptorArray::SetDetailsUnchecked(int descriptor_number, Smi* value) {
- ASSERT(descriptor_number < number_of_descriptors());
- set_unchecked(ToDetailsIndex(descriptor_number), value);
-}
-
-
PropertyType DescriptorArray::GetType(int descriptor_number) {
return GetDetails(descriptor_number).type();
}
@@ -2033,41 +2161,6 @@ AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
}
-bool DescriptorArray::IsProperty(int descriptor_number) {
- Entry entry(this, descriptor_number);
- return IsPropertyDescriptor(&entry);
-}
-
-
-bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
- switch (GetType(descriptor_number)) {
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- return true;
- case CALLBACKS: {
- Object* value = GetValue(descriptor_number);
- if (!value->IsAccessorPair()) return false;
- AccessorPair* accessors = AccessorPair::cast(value);
- return accessors->getter()->IsMap() && accessors->setter()->IsMap();
- }
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case HANDLER:
- case INTERCEPTOR:
- case NULL_DESCRIPTOR:
- return false;
- }
- UNREACHABLE(); // Keep the compiler happy.
- return false;
-}
-
-
-bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
- return GetType(descriptor_number) == NULL_DESCRIPTOR;
-}
-
-
void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
desc->Init(GetKey(descriptor_number),
GetValue(descriptor_number),
@@ -2080,6 +2173,9 @@ void DescriptorArray::Set(int descriptor_number,
const WhitenessWitness&) {
// Range check.
ASSERT(descriptor_number < number_of_descriptors());
+ ASSERT(desc->GetDetails().descriptor_index() <=
+ number_of_descriptors());
+ ASSERT(desc->GetDetails().descriptor_index() > 0);
NoIncrementalWriteBarrierSet(this,
ToKeyIndex(descriptor_number),
@@ -2093,24 +2189,73 @@ void DescriptorArray::Set(int descriptor_number,
}
-void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
- int first, int second) {
- NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
- NoIncrementalWriteBarrierSwap(this,
- ToValueIndex(first),
- ToValueIndex(second));
- NoIncrementalWriteBarrierSwap(this,
- ToDetailsIndex(first),
- ToDetailsIndex(second));
+void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
+ // Range check.
+ ASSERT(descriptor_number < number_of_descriptors());
+ ASSERT(desc->GetDetails().descriptor_index() <=
+ number_of_descriptors());
+ ASSERT(desc->GetDetails().descriptor_index() > 0);
+
+ set(ToKeyIndex(descriptor_number), desc->GetKey());
+ set(ToValueIndex(descriptor_number), desc->GetValue());
+ set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
}
-DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
+void DescriptorArray::Append(Descriptor* desc,
+ const WhitenessWitness& witness) {
+ int descriptor_number = number_of_descriptors();
+ int enumeration_index = descriptor_number + 1;
+ SetNumberOfDescriptors(descriptor_number + 1);
+ desc->SetEnumerationIndex(enumeration_index);
+ Set(descriptor_number, desc, witness);
+
+ uint32_t hash = desc->GetKey()->Hash();
+
+ int insertion;
+
+ for (insertion = descriptor_number; insertion > 0; --insertion) {
+ String* key = GetSortedKey(insertion - 1);
+ if (key->Hash() <= hash) break;
+ SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
+ }
+
+ SetSortedKey(insertion, descriptor_number);
+}
+
+
+void DescriptorArray::Append(Descriptor* desc) {
+ int descriptor_number = number_of_descriptors();
+ int enumeration_index = descriptor_number + 1;
+ SetNumberOfDescriptors(descriptor_number + 1);
+ desc->SetEnumerationIndex(enumeration_index);
+ Set(descriptor_number, desc);
+
+ uint32_t hash = desc->GetKey()->Hash();
+
+ int insertion;
+
+ for (insertion = descriptor_number; insertion > 0; --insertion) {
+ String* key = GetSortedKey(insertion - 1);
+ if (key->Hash() <= hash) break;
+ SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
+ }
+
+ SetSortedKey(insertion, descriptor_number);
+}
+
+
+void DescriptorArray::SwapSortedKeys(int first, int second) {
+ int first_key = GetSortedKeyIndex(first);
+ SetSortedKey(first, GetSortedKeyIndex(second));
+ SetSortedKey(second, first_key);
+}
+
+
+DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
: marking_(array->GetHeap()->incremental_marking()) {
marking_->EnterNoMarkingScope();
- if (array->number_of_descriptors() > 0) {
- ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
- }
+ ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
}
@@ -2409,9 +2554,10 @@ String* SlicedString::parent() {
}
-void SlicedString::set_parent(String* parent) {
+void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
ASSERT(parent->IsSeqString() || parent->IsExternalString());
WRITE_FIELD(this, kParentOffset, parent);
+ CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
}
@@ -2915,16 +3061,12 @@ bool Map::has_non_instance_prototype() {
void Map::set_function_with_prototype(bool value) {
- if (value) {
- set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
- } else {
- set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
- }
+ set_bit_field3(FunctionWithPrototype::update(bit_field3(), value));
}
bool Map::function_with_prototype() {
- return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
+ return FunctionWithPrototype::decode(bit_field3());
}
@@ -2969,15 +3111,22 @@ bool Map::attached_to_shared_function_info() {
void Map::set_is_shared(bool value) {
- if (value) {
- set_bit_field3(bit_field3() | (1 << kIsShared));
- } else {
- set_bit_field3(bit_field3() & ~(1 << kIsShared));
- }
+ set_bit_field3(IsShared::update(bit_field3(), value));
}
+
bool Map::is_shared() {
- return ((1 << kIsShared) & bit_field3()) != 0;
+ return IsShared::decode(bit_field3());
+}
+
+
+void Map::set_dictionary_map(bool value) {
+ set_bit_field3(DictionaryMap::update(bit_field3(), value));
+}
+
+
+bool Map::is_dictionary_map() {
+ return DictionaryMap::decode(bit_field3());
}
@@ -2991,6 +3140,16 @@ Code::Flags Code::flags() {
}
+void Map::set_owns_descriptors(bool is_shared) {
+ set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
+}
+
+
+bool Map::owns_descriptors() {
+ return OwnsDescriptors::decode(bit_field3());
+}
+
+
void Code::set_flags(Code::Flags flags) {
STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
// Make sure that all call stubs have an arguments count.
@@ -3025,7 +3184,7 @@ Code::ExtraICState Code::extra_ic_state() {
}
-PropertyType Code::type() {
+Code::StubType Code::type() {
return ExtractTypeFromFlags(flags());
}
@@ -3042,7 +3201,8 @@ int Code::major_key() {
kind() == BINARY_OP_IC ||
kind() == COMPARE_IC ||
kind() == TO_BOOLEAN_IC);
- return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
+ return StubMajorKeyField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
}
@@ -3053,7 +3213,9 @@ void Code::set_major_key(int major) {
kind() == COMPARE_IC ||
kind() == TO_BOOLEAN_IC);
ASSERT(0 <= major && major < 256);
- WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
+ int updated = StubMajorKeyField::update(previous, major);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
}
@@ -3155,39 +3317,50 @@ void Code::set_profiler_ticks(int ticks) {
unsigned Code::stack_slots() {
ASSERT(kind() == OPTIMIZED_FUNCTION);
- return READ_UINT32_FIELD(this, kStackSlotsOffset);
+ return StackSlotsField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
}
void Code::set_stack_slots(unsigned slots) {
+ CHECK(slots <= (1 << kStackSlotsBitCount));
ASSERT(kind() == OPTIMIZED_FUNCTION);
- WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = StackSlotsField::update(previous, slots);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
}
unsigned Code::safepoint_table_offset() {
ASSERT(kind() == OPTIMIZED_FUNCTION);
- return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
+ return SafepointTableOffsetField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
}
void Code::set_safepoint_table_offset(unsigned offset) {
+ CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
ASSERT(kind() == OPTIMIZED_FUNCTION);
ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
- WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
+ int updated = SafepointTableOffsetField::update(previous, offset);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
}
unsigned Code::stack_check_table_offset() {
ASSERT_EQ(FUNCTION, kind());
- return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
+ return StackCheckTableOffsetField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
}
void Code::set_stack_check_table_offset(unsigned offset) {
ASSERT_EQ(FUNCTION, kind());
ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
- WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
+ int updated = StackCheckTableOffsetField::update(previous, offset);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
}
@@ -3206,85 +3379,106 @@ void Code::set_check_type(CheckType value) {
byte Code::unary_op_type() {
ASSERT(is_unary_op_stub());
- return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
+ return UnaryOpTypeField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
}
void Code::set_unary_op_type(byte value) {
ASSERT(is_unary_op_stub());
- WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = UnaryOpTypeField::update(previous, value);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
}
byte Code::binary_op_type() {
ASSERT(is_binary_op_stub());
- return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
+ return BinaryOpTypeField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
}
void Code::set_binary_op_type(byte value) {
ASSERT(is_binary_op_stub());
- WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = BinaryOpTypeField::update(previous, value);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
}
byte Code::binary_op_result_type() {
ASSERT(is_binary_op_stub());
- return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
+ return BinaryOpResultTypeField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
}
void Code::set_binary_op_result_type(byte value) {
ASSERT(is_binary_op_stub());
- WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = BinaryOpResultTypeField::update(previous, value);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
}
byte Code::compare_state() {
ASSERT(is_compare_ic_stub());
- return READ_BYTE_FIELD(this, kCompareStateOffset);
+ return CompareStateField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
}
void Code::set_compare_state(byte value) {
ASSERT(is_compare_ic_stub());
- WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = CompareStateField::update(previous, value);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
}
byte Code::compare_operation() {
ASSERT(is_compare_ic_stub());
- return READ_BYTE_FIELD(this, kCompareOperationOffset);
+ return CompareOperationField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
}
void Code::set_compare_operation(byte value) {
ASSERT(is_compare_ic_stub());
- WRITE_BYTE_FIELD(this, kCompareOperationOffset, value);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = CompareOperationField::update(previous, value);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
}
byte Code::to_boolean_state() {
ASSERT(is_to_boolean_ic_stub());
- return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
+ return ToBooleanStateField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
}
void Code::set_to_boolean_state(byte value) {
ASSERT(is_to_boolean_ic_stub());
- WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = ToBooleanStateField::update(previous, value);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
}
bool Code::has_function_cache() {
ASSERT(kind() == STUB);
- return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
+ return HasFunctionCacheField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
}
void Code::set_has_function_cache(bool flag) {
ASSERT(kind() == STUB);
- WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = HasFunctionCacheField::update(previous, flag);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
}
@@ -3297,7 +3491,7 @@ bool Code::is_inline_cache_stub() {
Code::Flags Code::ComputeFlags(Kind kind,
InlineCacheState ic_state,
ExtraICState extra_ic_state,
- PropertyType type,
+ StubType type,
int argc,
InlineCacheHolderFlag holder) {
// Extra IC state is only allowed for call IC stubs or for store IC
@@ -3318,7 +3512,7 @@ Code::Flags Code::ComputeFlags(Kind kind,
Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
- PropertyType type,
+ StubType type,
ExtraICState extra_ic_state,
InlineCacheHolderFlag holder,
int argc) {
@@ -3341,7 +3535,7 @@ Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
}
-PropertyType Code::ExtractTypeFromFlags(Flags flags) {
+Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
return TypeField::decode(flags);
}
@@ -3391,160 +3585,222 @@ void Map::set_prototype(Object* value, WriteBarrierMode mode) {
}
-DescriptorArray* Map::instance_descriptors() {
- Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
- if (object->IsSmi()) {
- return GetHeap()->empty_descriptor_array();
+// If the descriptor is using the empty transition array, install a new empty
+// transition array that will have place for an element transition.
+static MaybeObject* EnsureHasTransitionArray(Map* map) {
+ TransitionArray* transitions;
+ MaybeObject* maybe_transitions;
+ if (!map->HasTransitionArray()) {
+ maybe_transitions = TransitionArray::Allocate(0);
+ if (!maybe_transitions->To(&transitions)) return maybe_transitions;
+ transitions->set_back_pointer_storage(map->GetBackPointer());
+ } else if (!map->transitions()->IsFullTransitionArray()) {
+ maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
+ if (!maybe_transitions->To(&transitions)) return maybe_transitions;
} else {
- return DescriptorArray::cast(object);
+ return map;
}
+ map->set_transitions(transitions);
+ return transitions;
}
-void Map::init_instance_descriptors() {
- WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
-}
-
-
-void Map::clear_instance_descriptors() {
- Object* object = READ_FIELD(this,
- kInstanceDescriptorsOrBitField3Offset);
- if (!object->IsSmi()) {
+void Map::InitializeDescriptors(DescriptorArray* descriptors) {
+ int len = descriptors->number_of_descriptors();
#ifdef DEBUG
- ZapInstanceDescriptors();
-#endif
- WRITE_FIELD(
- this,
- kInstanceDescriptorsOrBitField3Offset,
- Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
+ ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
+
+ bool used_indices[DescriptorArray::kMaxNumberOfDescriptors];
+ for (int i = 0; i < len; ++i) used_indices[i] = false;
+
+ // Ensure that all enumeration indexes between 1 and length occur uniquely in
+ // the descriptor array.
+ for (int i = 0; i < len; ++i) {
+ int enum_index = descriptors->GetDetails(i).descriptor_index() -
+ PropertyDetails::kInitialIndex;
+ ASSERT(0 <= enum_index && enum_index < len);
+ ASSERT(!used_indices[enum_index]);
+ used_indices[enum_index] = true;
}
+#endif
+
+ set_instance_descriptors(descriptors);
+ SetNumberOfOwnDescriptors(len);
}
-void Map::set_instance_descriptors(DescriptorArray* value,
- WriteBarrierMode mode) {
- Object* object = READ_FIELD(this,
- kInstanceDescriptorsOrBitField3Offset);
- Heap* heap = GetHeap();
- if (value == heap->empty_descriptor_array()) {
- clear_instance_descriptors();
- return;
- } else {
- if (object->IsSmi()) {
- value->set_bit_field3_storage(Smi::cast(object)->value());
- } else {
- value->set_bit_field3_storage(
- DescriptorArray::cast(object)->bit_field3_storage());
- }
- }
- ASSERT(!is_shared());
-#ifdef DEBUG
- if (value != instance_descriptors()) {
- ZapInstanceDescriptors();
- }
-#endif
- WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
- CONDITIONAL_WRITE_BARRIER(
- heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
-}
+ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
+SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
-int Map::bit_field3() {
- Object* object = READ_FIELD(this,
- kInstanceDescriptorsOrBitField3Offset);
- if (object->IsSmi()) {
- return Smi::cast(object)->value();
- } else {
- return DescriptorArray::cast(object)->bit_field3_storage();
+void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
+ Object* back_pointer = GetBackPointer();
+
+ if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
+ ZapTransitions();
}
+
+ WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer);
+ CONDITIONAL_WRITE_BARRIER(
+ heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode);
}
-void Map::set_bit_field3(int value) {
- ASSERT(Smi::IsValid(value));
- Object* object = READ_FIELD(this,
- kInstanceDescriptorsOrBitField3Offset);
- if (object->IsSmi()) {
- WRITE_FIELD(this,
- kInstanceDescriptorsOrBitField3Offset,
- Smi::FromInt(value));
- } else {
- DescriptorArray::cast(object)->set_bit_field3_storage(value);
- }
+void Map::AppendDescriptor(Descriptor* desc,
+ const DescriptorArray::WhitenessWitness& witness) {
+ DescriptorArray* descriptors = instance_descriptors();
+ int number_of_own_descriptors = NumberOfOwnDescriptors();
+ ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
+ descriptors->Append(desc, witness);
+ SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
}
Object* Map::GetBackPointer() {
- Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
- if (object->IsFixedArray()) {
- return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
+ Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
+ if (object->IsDescriptorArray()) {
+ return TransitionArray::cast(object)->back_pointer_storage();
} else {
+ ASSERT(object->IsMap() || object->IsUndefined());
return object;
}
}
+bool Map::HasElementsTransition() {
+ return HasTransitionArray() && transitions()->HasElementsTransition();
+}
+
+
+bool Map::HasTransitionArray() {
+ Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
+ return object->IsTransitionArray();
+}
+
+
Map* Map::elements_transition_map() {
- return instance_descriptors()->elements_transition_map();
+ return transitions()->elements_transition();
}
-void Map::set_elements_transition_map(Map* transitioned_map) {
- return instance_descriptors()->set_elements_transition_map(transitioned_map);
+bool Map::CanHaveMoreTransitions() {
+ if (!HasTransitionArray()) return true;
+ return FixedArray::SizeFor(transitions()->length() +
+ TransitionArray::kTransitionSize)
+ <= Page::kMaxNonCodeHeapObjectSize;
}
-void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
- Heap* heap = GetHeap();
- ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
- ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
- (value->IsMap() && GetBackPointer()->IsUndefined()));
- Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
- if (object->IsFixedArray()) {
- FixedArray::cast(object)->set(
- kProtoTransitionBackPointerOffset, value, mode);
- } else {
- WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
- CONDITIONAL_WRITE_BARRIER(
- heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
- }
+MaybeObject* Map::AddTransition(String* key,
+ Map* target,
+ SimpleTransitionFlag flag) {
+ if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
+ return TransitionArray::NewWith(flag, key, target, GetBackPointer());
}
-FixedArray* Map::prototype_transitions() {
- Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
- if (object->IsFixedArray()) {
- return FixedArray::cast(object);
- } else {
+void Map::SetTransition(int transition_index, Map* target) {
+ transitions()->SetTarget(transition_index, target);
+}
+
+
+Map* Map::GetTransition(int transition_index) {
+ return transitions()->GetTarget(transition_index);
+}
+
+
+MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
+ MaybeObject* allow_elements = EnsureHasTransitionArray(this);
+ if (allow_elements->IsFailure()) return allow_elements;
+ transitions()->set_elements_transition(transitioned_map);
+ return this;
+}
+
+
+FixedArray* Map::GetPrototypeTransitions() {
+ if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
+ if (!transitions()->HasPrototypeTransitions()) {
return GetHeap()->empty_fixed_array();
}
+ return transitions()->GetPrototypeTransitions();
}
-void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) {
- Heap* heap = GetHeap();
- ASSERT(value != heap->empty_fixed_array());
- value->set(kProtoTransitionBackPointerOffset, GetBackPointer());
+MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
+ MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
+ if (allow_prototype->IsFailure()) return allow_prototype;
#ifdef DEBUG
- if (value != prototype_transitions()) {
+ if (HasPrototypeTransitions()) {
+ ASSERT(GetPrototypeTransitions() != proto_transitions);
ZapPrototypeTransitions();
}
#endif
- WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
+ transitions()->SetPrototypeTransitions(proto_transitions);
+ return this;
+}
+
+
+bool Map::HasPrototypeTransitions() {
+ return HasTransitionArray() && transitions()->HasPrototypeTransitions();
+}
+
+
+TransitionArray* Map::transitions() {
+ ASSERT(HasTransitionArray());
+ Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
+ return TransitionArray::cast(object);
+}
+
+
+void Map::set_transitions(TransitionArray* transition_array,
+ WriteBarrierMode mode) {
+ // In release mode, only run this code if verify_heap is on.
+ if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
+ CHECK(transitions() != transition_array);
+ ZapTransitions();
+ }
+
+ WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array);
CONDITIONAL_WRITE_BARRIER(
- heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
+ GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode);
}
-void Map::init_prototype_transitions(Object* undefined) {
+void Map::init_back_pointer(Object* undefined) {
ASSERT(undefined->IsUndefined());
- WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined);
+ WRITE_FIELD(this, kTransitionsOrBackPointerOffset, undefined);
}
-HeapObject* Map::unchecked_prototype_transitions() {
- Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
- return reinterpret_cast<HeapObject*>(object);
+void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
+ ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
+ ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
+ (value->IsMap() && GetBackPointer()->IsUndefined()));
+ Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
+ if (object->IsTransitionArray()) {
+ TransitionArray::cast(object)->set_back_pointer_storage(value);
+ } else {
+ WRITE_FIELD(this, kTransitionsOrBackPointerOffset, value);
+ CONDITIONAL_WRITE_BARRIER(
+ GetHeap(), this, kTransitionsOrBackPointerOffset, value, mode);
+ }
+}
+
+
+// Can either be Smi (no transitions), normal transition array, or a transition
+// array with the header overwritten as a Smi (thus iterating).
+TransitionArray* Map::unchecked_transition_array() {
+ Object* object = *HeapObject::RawField(this,
+ Map::kTransitionsOrBackPointerOffset);
+ TransitionArray* transition_array = static_cast<TransitionArray*>(object);
+ return transition_array;
+}
+
+
+HeapObject* Map::UncheckedPrototypeTransitions() {
+ ASSERT(HasTransitionArray());
+ ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
+ return unchecked_transition_array()->UncheckedPrototypeTransitions();
}
@@ -3556,10 +3812,11 @@ ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
+ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
-ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
+ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
@@ -3648,6 +3905,8 @@ ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
#endif
ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
+ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
+ kOptimizedCodeMapOffset)
ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
@@ -3682,6 +3941,10 @@ BOOL_ACCESSORS(SharedFunctionInfo,
kAllowLazyCompilation)
BOOL_ACCESSORS(SharedFunctionInfo,
compiler_hints,
+ allows_lazy_compilation_without_context,
+ kAllowLazyCompilationWithoutContext)
+BOOL_ACCESSORS(SharedFunctionInfo,
+ compiler_hints,
uses_arguments,
kUsesArguments)
BOOL_ACCESSORS(SharedFunctionInfo,
@@ -3858,6 +4121,18 @@ BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
kDontOptimize)
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
+
+void SharedFunctionInfo::BeforeVisitingPointers() {
+ if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
+
+ // Flush optimized code map on major GC.
+ // Note: we may experiment with rebuilding it or retaining entries
+ // which should survive as we iterate through optimized functions
+ // anyway.
+ set_optimized_code_map(Smi::FromInt(0));
+}
+
ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
@@ -4025,7 +4300,7 @@ void SharedFunctionInfo::TryReenableOptimization() {
bool JSFunction::IsBuiltin() {
- return context()->global()->IsJSBuiltinsObject();
+ return context()->global_object()->IsJSBuiltinsObject();
}
@@ -4050,6 +4325,18 @@ bool JSFunction::IsMarkedForLazyRecompilation() {
}
+bool JSFunction::IsMarkedForParallelRecompilation() {
+ return code() ==
+ GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile);
+}
+
+
+bool JSFunction::IsInRecompileQueue() {
+ return code() == GetIsolate()->builtins()->builtin(
+ Builtins::kInRecompileQueue);
+}
+
+
Code* JSFunction::code() {
return Code::cast(unchecked_code());
}
@@ -4081,10 +4368,10 @@ void JSFunction::ReplaceCode(Code* code) {
// Add/remove the function from the list of optimized functions for this
// context based on the state change.
if (!was_optimized && is_optimized) {
- context()->global_context()->AddOptimizedFunction(this);
+ context()->native_context()->AddOptimizedFunction(this);
}
if (was_optimized && !is_optimized) {
- context()->global_context()->RemoveOptimizedFunction(this);
+ context()->native_context()->RemoveOptimizedFunction(this);
}
}
@@ -4127,12 +4414,12 @@ void JSFunction::set_initial_map(Map* value) {
MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
Map* initial_map) {
- Context* global_context = context()->global_context();
+ Context* native_context = context()->native_context();
Object* array_function =
- global_context->get(Context::ARRAY_FUNCTION_INDEX);
+ native_context->get(Context::ARRAY_FUNCTION_INDEX);
if (array_function->IsJSFunction() &&
this == JSFunction::cast(array_function)) {
- // Replace all of the cached initial array maps in the global context with
+ // Replace all of the cached initial array maps in the native context with
// the appropriate transitioned elements kind maps.
Heap* heap = GetHeap();
MaybeObject* maybe_maps =
@@ -4149,12 +4436,12 @@ MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
Map* new_map;
ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
MaybeObject* maybe_new_map =
- current_map->CreateNextElementsTransition(next_kind);
+ current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION);
if (!maybe_new_map->To(&new_map)) return maybe_new_map;
maps->set(next_kind, new_map);
current_map = new_map;
}
- global_context->set_js_array_maps(maps);
+ native_context->set_js_array_maps(maps);
}
set_initial_map(initial_map);
return this;
@@ -4297,6 +4584,7 @@ void Foreign::set_foreign_address(Address value) {
ACCESSORS(JSModule, context, Object, kContextOffset)
+ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
JSModule* JSModule::cast(Object* obj) {
@@ -4644,8 +4932,7 @@ StringHasher::StringHasher(int length, uint32_t seed)
raw_running_hash_(seed),
array_index_(0),
is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
- is_first_char_(true),
- is_valid_(true) {
+ is_first_char_(true) {
ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
}
@@ -4655,6 +4942,25 @@ bool StringHasher::has_trivial_hash() {
}
+uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint32_t c) {
+ running_hash += c;
+ running_hash += (running_hash << 10);
+ running_hash ^= (running_hash >> 6);
+ return running_hash;
+}
+
+
+uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
+ running_hash += (running_hash << 3);
+ running_hash ^= (running_hash >> 11);
+ running_hash += (running_hash << 15);
+ if ((running_hash & String::kHashBitMask) == 0) {
+ return kZeroHash;
+ }
+ return running_hash;
+}
+
+
void StringHasher::AddCharacter(uint32_t c) {
if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
AddSurrogatePair(c); // Not inlined.
@@ -4662,9 +4968,7 @@ void StringHasher::AddCharacter(uint32_t c) {
}
// Use the Jenkins one-at-a-time hash function to update the hash
// for the given character.
- raw_running_hash_ += c;
- raw_running_hash_ += (raw_running_hash_ << 10);
- raw_running_hash_ ^= (raw_running_hash_ >> 6);
+ raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
// Incremental array index computation.
if (is_array_index_) {
if (c < '0' || c > '9') {
@@ -4694,23 +4998,14 @@ void StringHasher::AddCharacterNoIndex(uint32_t c) {
AddSurrogatePairNoIndex(c); // Not inlined.
return;
}
- raw_running_hash_ += c;
- raw_running_hash_ += (raw_running_hash_ << 10);
- raw_running_hash_ ^= (raw_running_hash_ >> 6);
+ raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
}
uint32_t StringHasher::GetHash() {
// Get the calculated raw hash value and do some more bit ops to distribute
// the hash further. Ensure that we never return zero as the hash value.
- uint32_t result = raw_running_hash_;
- result += (result << 3);
- result ^= (result >> 11);
- result += (result << 15);
- if ((result & String::kHashBitMask) == 0) {
- result = 27;
- }
- return result;
+ return GetHashCore(raw_running_hash_);
}
@@ -4740,7 +5035,12 @@ bool String::AsArrayIndex(uint32_t* index) {
Object* JSReceiver::GetPrototype() {
- return HeapObject::cast(this)->map()->prototype();
+ return map()->prototype();
+}
+
+
+Object* JSReceiver::GetConstructor() {
+ return map()->constructor();
}
@@ -4852,7 +5152,9 @@ void Dictionary<Shape, Key>::SetEntry(int entry,
Object* key,
Object* value,
PropertyDetails details) {
- ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
+ ASSERT(!key->IsString() ||
+ details.IsDeleted() ||
+ details.dictionary_index() > 0);
int index = HashTable<Shape, Key>::EntryToIndex(entry);
AssertNoAllocation no_gc;
WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
@@ -5014,13 +5316,13 @@ MaybeObject* FixedDoubleArray::Copy() {
}
-void TypeFeedbackCells::SetAstId(int index, Smi* id) {
- set(1 + index * 2, id);
+void TypeFeedbackCells::SetAstId(int index, TypeFeedbackId id) {
+ set(1 + index * 2, Smi::FromInt(id.ToInt()));
}
-Smi* TypeFeedbackCells::AstId(int index) {
- return Smi::cast(get(1 + index * 2));
+TypeFeedbackId TypeFeedbackCells::AstId(int index) {
+ return TypeFeedbackId(Smi::cast(get(1 + index * 2))->value());
}
@@ -5049,9 +5351,84 @@ Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
}
-SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
-SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
- kIcWithTypeinfoCountOffset)
+int TypeFeedbackInfo::ic_total_count() {
+ int current = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
+ return ICTotalCountField::decode(current);
+}
+
+
+void TypeFeedbackInfo::set_ic_total_count(int count) {
+ int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
+ value = ICTotalCountField::update(value,
+ ICTotalCountField::decode(count));
+ WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
+}
+
+
+int TypeFeedbackInfo::ic_with_type_info_count() {
+ int current = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
+ return ICsWithTypeInfoCountField::decode(current);
+}
+
+
+void TypeFeedbackInfo::change_ic_with_type_info_count(int delta) {
+ int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
+ int new_count = ICsWithTypeInfoCountField::decode(value) + delta;
+ // We can get negative count here when the type-feedback info is
+ // shared between two code objects. The can only happen when
+ // the debugger made a shallow copy of code object (see Heap::CopyCode).
+ // Since we do not optimize when the debugger is active, we can skip
+ // this counter update.
+ if (new_count >= 0) {
+ new_count &= ICsWithTypeInfoCountField::kMask;
+ value = ICsWithTypeInfoCountField::update(value, new_count);
+ WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
+ }
+}
+
+
+void TypeFeedbackInfo::initialize_storage() {
+ WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(0));
+ WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(0));
+}
+
+
+void TypeFeedbackInfo::change_own_type_change_checksum() {
+ int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
+ int checksum = OwnTypeChangeChecksum::decode(value);
+ checksum = (checksum + 1) % (1 << kTypeChangeChecksumBits);
+ value = OwnTypeChangeChecksum::update(value, checksum);
+ // Ensure packed bit field is in Smi range.
+ if (value > Smi::kMaxValue) value |= Smi::kMinValue;
+ if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
+ WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
+}
+
+
+void TypeFeedbackInfo::set_inlined_type_change_checksum(int checksum) {
+ int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
+ int mask = (1 << kTypeChangeChecksumBits) - 1;
+ value = InlinedTypeChangeChecksum::update(value, checksum & mask);
+ // Ensure packed bit field is in Smi range.
+ if (value > Smi::kMaxValue) value |= Smi::kMinValue;
+ if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
+ WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
+}
+
+
+int TypeFeedbackInfo::own_type_change_checksum() {
+ int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
+ return OwnTypeChangeChecksum::decode(value);
+}
+
+
+bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) {
+ int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
+ int mask = (1 << kTypeChangeChecksumBits) - 1;
+ return InlinedTypeChangeChecksum::decode(value) == (checksum & mask);
+}
+
+
ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
kTypeFeedbackCellsOffset)
@@ -5121,14 +5498,13 @@ void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
}
-#define SLOT_ADDR(obj, offset) \
- reinterpret_cast<Object**>((obj)->address() + offset)
template<int start_offset, int end_offset, int size>
void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
HeapObject* obj,
ObjectVisitor* v) {
- v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
+ v->VisitPointers(HeapObject::RawField(obj, start_offset),
+ HeapObject::RawField(obj, end_offset));
}
@@ -5136,10 +5512,10 @@ template<int start_offset>
void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
int object_size,
ObjectVisitor* v) {
- v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
+ v->VisitPointers(HeapObject::RawField(obj, start_offset),
+ HeapObject::RawField(obj, object_size));
}
-#undef SLOT_ADDR
#undef TYPE_CHECKER
#undef CAST_ACCESSOR
diff --git a/deps/v8/src/objects-printer.cc b/deps/v8/src/objects-printer.cc
index b88616899..b1118de9c 100644
--- a/deps/v8/src/objects-printer.cc
+++ b/deps/v8/src/objects-printer.cc
@@ -254,7 +254,7 @@ void ExternalDoubleArray::ExternalDoubleArrayPrint(FILE* out) {
void JSObject::PrintProperties(FILE* out) {
if (HasFastProperties()) {
DescriptorArray* descs = map()->instance_descriptors();
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
PrintF(out, " ");
descs->GetKey(i)->StringPrint(out);
PrintF(out, ": ");
@@ -273,18 +273,12 @@ void JSObject::PrintProperties(FILE* out) {
descs->GetCallbacksObject(i)->ShortPrint(out);
PrintF(out, " (callback)\n");
break;
- case MAP_TRANSITION:
- PrintF(out, "(map transition)\n");
- break;
- case CONSTANT_TRANSITION:
- PrintF(out, "(constant transition)\n");
- break;
- case NULL_DESCRIPTOR:
- PrintF(out, "(null descriptor)\n");
- break;
case NORMAL: // only in slow mode
case HANDLER: // only in lookup results, not in descriptors
case INTERCEPTOR: // only in lookup results, not in descriptors
+ // There are no transitions in the descriptor array.
+ case TRANSITION:
+ case NONEXISTENT:
UNREACHABLE();
break;
}
@@ -410,6 +404,37 @@ void JSObject::PrintElements(FILE* out) {
}
+void JSObject::PrintTransitions(FILE* out) {
+ if (!map()->HasTransitionArray()) return;
+ TransitionArray* transitions = map()->transitions();
+ for (int i = 0; i < transitions->number_of_transitions(); i++) {
+ PrintF(out, " ");
+ transitions->GetKey(i)->StringPrint(out);
+ PrintF(out, ": ");
+ switch (transitions->GetTargetDetails(i).type()) {
+ case FIELD: {
+ PrintF(out, " (transition to field)\n");
+ break;
+ }
+ case CONSTANT_FUNCTION:
+ PrintF(out, " (transition to constant function)\n");
+ break;
+ case CALLBACKS:
+ PrintF(out, " (transition to callback)\n");
+ break;
+ // Values below are never in the target descriptor array.
+ case NORMAL:
+ case HANDLER:
+ case INTERCEPTOR:
+ case TRANSITION:
+ case NONEXISTENT:
+ UNREACHABLE();
+ break;
+ }
+ }
+}
+
+
void JSObject::JSObjectPrint(FILE* out) {
PrintF(out, "%p: [JSObject]\n", reinterpret_cast<void*>(this));
PrintF(out, " - map = %p [", reinterpret_cast<void*>(map()));
@@ -419,11 +444,9 @@ void JSObject::JSObjectPrint(FILE* out) {
PrintF(out,
"]\n - prototype = %p\n",
reinterpret_cast<void*>(GetPrototype()));
- PrintF(out,
- " - elements transition to = %p\n",
- reinterpret_cast<void*>(map()->elements_transition_map()));
PrintF(out, " {\n");
PrintProperties(out);
+ PrintTransitions(out);
PrintElements(out);
PrintF(out, " }\n");
}
@@ -434,6 +457,8 @@ void JSModule::JSModulePrint(FILE* out) {
PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map()));
PrintF(out, " - context = ");
context()->Print(out);
+ PrintF(out, " - scope_info = ");
+ scope_info()->ShortPrint(out);
PrintElementsKind(out, this->map()->elements_kind());
PrintF(out, " {\n");
PrintProperties(out);
@@ -537,8 +562,16 @@ void Map::MapPrint(FILE* out) {
if (is_access_check_needed()) {
PrintF(out, " - access_check_needed\n");
}
- PrintF(out, " - instance descriptors: ");
+ PrintF(out, " - back pointer: ");
+ GetBackPointer()->ShortPrint(out);
+ PrintF(out, "\n - instance descriptors %i #%i: ",
+ owns_descriptors(),
+ NumberOfOwnDescriptors());
instance_descriptors()->ShortPrint(out);
+ if (HasTransitionArray()) {
+ PrintF(out, "\n - transitions: ");
+ transitions()->ShortPrint(out);
+ }
PrintF(out, "\n - prototype: ");
prototype()->ShortPrint(out);
PrintF(out, "\n - constructor: ");
@@ -567,9 +600,9 @@ void PolymorphicCodeCache::PolymorphicCodeCachePrint(FILE* out) {
void TypeFeedbackInfo::TypeFeedbackInfoPrint(FILE* out) {
HeapObject::PrintHeader(out, "TypeFeedbackInfo");
- PrintF(out, "\n - ic_total_count: %d, ic_with_type_info_count: %d",
+ PrintF(out, " - ic_total_count: %d, ic_with_type_info_count: %d\n",
ic_total_count(), ic_with_type_info_count());
- PrintF(out, "\n - type_feedback_cells: ");
+ PrintF(out, " - type_feedback_cells: ");
type_feedback_cells()->FixedArrayPrint(out);
}
@@ -741,6 +774,8 @@ void JSFunction::JSFunctionPrint(FILE* out) {
shared()->name()->Print(out);
PrintF(out, "\n - context = ");
unchecked_context()->ShortPrint(out);
+ PrintF(out, "\n - literals = ");
+ literals()->ShortPrint(out);
PrintF(out, "\n - code = ");
code()->ShortPrint(out);
PrintF(out, "\n");
@@ -761,8 +796,17 @@ void SharedFunctionInfo::SharedFunctionInfoPrint(FILE* out) {
instance_class_name()->Print(out);
PrintF(out, "\n - code = ");
code()->ShortPrint(out);
- PrintF(out, "\n - source code = ");
- GetSourceCode()->ShortPrint(out);
+ if (HasSourceCode()) {
+ PrintF(out, "\n - source code = ");
+ String* source = String::cast(Script::cast(script())->source());
+ int start = start_position();
+ int length = end_position() - start;
+ SmartArrayPointer<char> source_string =
+ source->ToCString(DISALLOW_NULLS,
+ FAST_STRING_TRAVERSAL,
+ start, length, NULL);
+ PrintF(out, "%s", *source_string);
+ }
// Script files are often large, hard to read.
// PrintF(out, "\n - script =");
// script()->Print(out);
@@ -782,10 +826,10 @@ void SharedFunctionInfo::SharedFunctionInfoPrint(FILE* out) {
void JSGlobalProxy::JSGlobalProxyPrint(FILE* out) {
- PrintF(out, "global_proxy");
+ PrintF(out, "global_proxy ");
JSObjectPrint(out);
- PrintF(out, "context : ");
- context()->ShortPrint(out);
+ PrintF(out, "native context : ");
+ native_context()->ShortPrint(out);
PrintF(out, "\n");
}
@@ -793,8 +837,8 @@ void JSGlobalProxy::JSGlobalProxyPrint(FILE* out) {
void JSGlobalObject::JSGlobalObjectPrint(FILE* out) {
PrintF(out, "global ");
JSObjectPrint(out);
- PrintF(out, "global context : ");
- global_context()->ShortPrint(out);
+ PrintF(out, "native context : ");
+ native_context()->ShortPrint(out);
PrintF(out, "\n");
}
@@ -1022,6 +1066,37 @@ void DescriptorArray::PrintDescriptors(FILE* out) {
}
+void TransitionArray::PrintTransitions(FILE* out) {
+ PrintF(out, "Transition array %d\n", number_of_transitions());
+ for (int i = 0; i < number_of_transitions(); i++) {
+ PrintF(out, " %d: ", i);
+ GetKey(i)->StringPrint(out);
+ PrintF(out, ": ");
+ switch (GetTargetDetails(i).type()) {
+ case FIELD: {
+ PrintF(out, " (transition to field)\n");
+ break;
+ }
+ case CONSTANT_FUNCTION:
+ PrintF(out, " (transition to constant function)\n");
+ break;
+ case CALLBACKS:
+ PrintF(out, " (transition to callback)\n");
+ break;
+ // Values below are never in the target descriptor array.
+ case NORMAL:
+ case HANDLER:
+ case INTERCEPTOR:
+ case TRANSITION:
+ case NONEXISTENT:
+ UNREACHABLE();
+ break;
+ }
+ }
+ PrintF(out, "\n");
+}
+
+
#endif // OBJECT_PRINT
diff --git a/deps/v8/src/objects-visiting-inl.h b/deps/v8/src/objects-visiting-inl.h
index 8ba92f70c..d698a8df0 100644
--- a/deps/v8/src/objects-visiting-inl.h
+++ b/deps/v8/src/objects-visiting-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -56,7 +56,7 @@ void StaticNewSpaceVisitor<StaticVisitor>::Initialize() {
table_.Register(kVisitFixedDoubleArray, &VisitFixedDoubleArray);
- table_.Register(kVisitGlobalContext,
+ table_.Register(kVisitNativeContext,
&FixedBodyVisitor<StaticVisitor,
Context::ScavengeBodyDescriptor,
int>::Visit);
@@ -93,6 +93,516 @@ void StaticNewSpaceVisitor<StaticVisitor>::Initialize() {
}
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::Initialize() {
+ table_.Register(kVisitShortcutCandidate,
+ &FixedBodyVisitor<StaticVisitor,
+ ConsString::BodyDescriptor,
+ void>::Visit);
+
+ table_.Register(kVisitConsString,
+ &FixedBodyVisitor<StaticVisitor,
+ ConsString::BodyDescriptor,
+ void>::Visit);
+
+ table_.Register(kVisitSlicedString,
+ &FixedBodyVisitor<StaticVisitor,
+ SlicedString::BodyDescriptor,
+ void>::Visit);
+
+ table_.Register(kVisitFixedArray,
+ &FlexibleBodyVisitor<StaticVisitor,
+ FixedArray::BodyDescriptor,
+ void>::Visit);
+
+ table_.Register(kVisitFixedDoubleArray, &DataObjectVisitor::Visit);
+
+ table_.Register(kVisitNativeContext, &VisitNativeContext);
+
+ table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
+
+ table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit);
+
+ table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit);
+
+ table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
+
+ table_.Register(kVisitJSWeakMap, &StaticVisitor::VisitJSWeakMap);
+
+ table_.Register(kVisitOddball,
+ &FixedBodyVisitor<StaticVisitor,
+ Oddball::BodyDescriptor,
+ void>::Visit);
+
+ table_.Register(kVisitMap, &VisitMap);
+
+ table_.Register(kVisitCode, &VisitCode);
+
+ table_.Register(kVisitSharedFunctionInfo, &VisitSharedFunctionInfo);
+
+ table_.Register(kVisitJSFunction, &VisitJSFunction);
+
+ // Registration for kVisitJSRegExp is done by StaticVisitor.
+
+ table_.Register(kVisitPropertyCell,
+ &FixedBodyVisitor<StaticVisitor,
+ JSGlobalPropertyCell::BodyDescriptor,
+ void>::Visit);
+
+ table_.template RegisterSpecializations<DataObjectVisitor,
+ kVisitDataObject,
+ kVisitDataObjectGeneric>();
+
+ table_.template RegisterSpecializations<JSObjectVisitor,
+ kVisitJSObject,
+ kVisitJSObjectGeneric>();
+
+ table_.template RegisterSpecializations<StructObjectVisitor,
+ kVisitStruct,
+ kVisitStructGeneric>();
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitCodeEntry(
+ Heap* heap, Address entry_address) {
+ Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
+ heap->mark_compact_collector()->RecordCodeEntrySlot(entry_address, code);
+ StaticVisitor::MarkObject(heap, code);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitEmbeddedPointer(
+ Heap* heap, RelocInfo* rinfo) {
+ ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
+ ASSERT(!rinfo->target_object()->IsConsString());
+ HeapObject* object = HeapObject::cast(rinfo->target_object());
+ heap->mark_compact_collector()->RecordRelocSlot(rinfo, object);
+ StaticVisitor::MarkObject(heap, object);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitGlobalPropertyCell(
+ Heap* heap, RelocInfo* rinfo) {
+ ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
+ JSGlobalPropertyCell* cell = rinfo->target_cell();
+ StaticVisitor::MarkObject(heap, cell);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitDebugTarget(
+ Heap* heap, RelocInfo* rinfo) {
+ ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
+ rinfo->IsPatchedReturnSequence()) ||
+ (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
+ rinfo->IsPatchedDebugBreakSlotSequence()));
+ Code* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
+ heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
+ StaticVisitor::MarkObject(heap, target);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget(
+ Heap* heap, RelocInfo* rinfo) {
+ ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
+ Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
+ // Monomorphic ICs are preserved when possible, but need to be flushed
+ // when they might be keeping a Context alive, or when the heap is about
+ // to be serialized.
+ if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
+ && (target->ic_state() == MEGAMORPHIC || heap->flush_monomorphic_ics() ||
+ Serializer::enabled() || target->ic_age() != heap->global_ic_age())) {
+ IC::Clear(rinfo->pc());
+ target = Code::GetCodeFromTargetAddress(rinfo->target_address());
+ }
+ heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
+ StaticVisitor::MarkObject(heap, target);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitNativeContext(
+ Map* map, HeapObject* object) {
+ FixedBodyVisitor<StaticVisitor,
+ Context::MarkCompactBodyDescriptor,
+ void>::Visit(map, object);
+
+ MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
+ for (int idx = Context::FIRST_WEAK_SLOT;
+ idx < Context::NATIVE_CONTEXT_SLOTS;
+ ++idx) {
+ Object** slot =
+ HeapObject::RawField(object, FixedArray::OffsetOfElementAt(idx));
+ collector->RecordSlot(slot, slot, *slot);
+ }
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitMap(
+ Map* map, HeapObject* object) {
+ Heap* heap = map->GetHeap();
+ Map* map_object = Map::cast(object);
+
+ // Clears the cache of ICs related to this map.
+ if (FLAG_cleanup_code_caches_at_gc) {
+ map_object->ClearCodeCache(heap);
+ }
+
+ // When map collection is enabled we have to mark through map's
+ // transitions and back pointers in a special way to make these links
+ // weak. Only maps for subclasses of JSReceiver can have transitions.
+ STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
+ if (FLAG_collect_maps &&
+ map_object->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
+ MarkMapContents(heap, map_object);
+ } else {
+ StaticVisitor::VisitPointers(heap,
+ HeapObject::RawField(object, Map::kPointerFieldsBeginOffset),
+ HeapObject::RawField(object, Map::kPointerFieldsEndOffset));
+ }
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitCode(
+ Map* map, HeapObject* object) {
+ Heap* heap = map->GetHeap();
+ Code* code = Code::cast(object);
+ if (FLAG_cleanup_code_caches_at_gc) {
+ code->ClearTypeFeedbackCells(heap);
+ }
+ code->CodeIterateBody<StaticVisitor>(heap);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfo(
+ Map* map, HeapObject* object) {
+ Heap* heap = map->GetHeap();
+ SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
+ if (shared->ic_age() != heap->global_ic_age()) {
+ shared->ResetForNewContext(heap->global_ic_age());
+ }
+ MarkCompactCollector* collector = heap->mark_compact_collector();
+ if (collector->is_code_flushing_enabled()) {
+ if (IsFlushable(heap, shared)) {
+ // This function's code looks flushable. But we have to postpone
+ // the decision until we see all functions that point to the same
+ // SharedFunctionInfo because some of them might be optimized.
+ // That would also make the non-optimized version of the code
+ // non-flushable, because it is required for bailing out from
+ // optimized code.
+ collector->code_flusher()->AddCandidate(shared);
+ // Treat the reference to the code object weakly.
+ VisitSharedFunctionInfoWeakCode(heap, object);
+ return;
+ }
+ }
+ VisitSharedFunctionInfoStrongCode(heap, object);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitJSFunction(
+ Map* map, HeapObject* object) {
+ Heap* heap = map->GetHeap();
+ JSFunction* function = JSFunction::cast(object);
+ MarkCompactCollector* collector = heap->mark_compact_collector();
+ if (collector->is_code_flushing_enabled()) {
+ if (IsFlushable(heap, function)) {
+ // This function's code looks flushable. But we have to postpone
+ // the decision until we see all functions that point to the same
+ // SharedFunctionInfo because some of them might be optimized.
+ // That would also make the non-optimized version of the code
+ // non-flushable, because it is required for bailing out from
+ // optimized code.
+ collector->code_flusher()->AddCandidate(function);
+ // Visit shared function info immediately to avoid double checking
+ // of its flushability later. This is just an optimization because
+ // the shared function info would eventually be visited.
+ SharedFunctionInfo* shared = function->unchecked_shared();
+ if (StaticVisitor::MarkObjectWithoutPush(heap, shared)) {
+ StaticVisitor::MarkObject(heap, shared->map());
+ VisitSharedFunctionInfoWeakCode(heap, shared);
+ }
+ // Treat the reference to the code object weakly.
+ VisitJSFunctionWeakCode(heap, object);
+ return;
+ } else {
+ // Visit all unoptimized code objects to prevent flushing them.
+ StaticVisitor::MarkObject(heap, function->shared()->code());
+ if (function->code()->kind() == Code::OPTIMIZED_FUNCTION) {
+ MarkInlinedFunctionsCode(heap, function->code());
+ }
+ }
+ }
+ VisitJSFunctionStrongCode(heap, object);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(
+ Map* map, HeapObject* object) {
+ int last_property_offset =
+ JSRegExp::kSize + kPointerSize * map->inobject_properties();
+ StaticVisitor::VisitPointers(map->GetHeap(),
+ HeapObject::RawField(object, JSRegExp::kPropertiesOffset),
+ HeapObject::RawField(object, last_property_offset));
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::MarkMapContents(
+ Heap* heap, Map* map) {
+ // Make sure that the back pointer stored either in the map itself or
+ // inside its transitions array is marked. Skip recording the back
+ // pointer slot since map space is not compacted.
+ StaticVisitor::MarkObject(heap, HeapObject::cast(map->GetBackPointer()));
+
+ // Treat pointers in the transitions array as weak and also mark that
+ // array to prevent visiting it later. Skip recording the transition
+ // array slot, since it will be implicitly recorded when the pointer
+ // fields of this map are visited.
+ TransitionArray* transitions = map->unchecked_transition_array();
+ if (transitions->IsTransitionArray()) {
+ MarkTransitionArray(heap, transitions);
+ } else {
+ // Already marked by marking map->GetBackPointer() above.
+ ASSERT(transitions->IsMap() || transitions->IsUndefined());
+ }
+
+ // Mark the pointer fields of the Map. Since the transitions array has
+ // been marked already, it is fine that one of these fields contains a
+ // pointer to it.
+ StaticVisitor::VisitPointers(heap,
+ HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
+ HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::MarkTransitionArray(
+ Heap* heap, TransitionArray* transitions) {
+ if (!StaticVisitor::MarkObjectWithoutPush(heap, transitions)) return;
+
+ // Simple transitions do not have keys nor prototype transitions.
+ if (transitions->IsSimpleTransition()) return;
+
+ if (transitions->HasPrototypeTransitions()) {
+ // Mark prototype transitions array but do not push it onto marking
+ // stack, this will make references from it weak. We will clean dead
+ // prototype transitions in ClearNonLiveTransitions.
+ Object** slot = transitions->GetPrototypeTransitionsSlot();
+ HeapObject* obj = HeapObject::cast(*slot);
+ heap->mark_compact_collector()->RecordSlot(slot, slot, obj);
+ StaticVisitor::MarkObjectWithoutPush(heap, obj);
+ }
+
+ for (int i = 0; i < transitions->number_of_transitions(); ++i) {
+ StaticVisitor::VisitPointer(heap, transitions->GetKeySlot(i));
+ }
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::MarkInlinedFunctionsCode(
+ Heap* heap, Code* code) {
+ // For optimized functions we should retain both non-optimized version
+ // of its code and non-optimized version of all inlined functions.
+ // This is required to support bailing out from inlined code.
+ DeoptimizationInputData* data =
+ DeoptimizationInputData::cast(code->deoptimization_data());
+ FixedArray* literals = data->LiteralArray();
+ for (int i = 0, count = data->InlinedFunctionCount()->value();
+ i < count;
+ i++) {
+ JSFunction* inlined = JSFunction::cast(literals->get(i));
+ StaticVisitor::MarkObject(heap, inlined->shared()->code());
+ }
+}
+
+
+inline static bool IsValidNonBuiltinContext(Object* context) {
+ return context->IsContext() &&
+ !Context::cast(context)->global_object()->IsJSBuiltinsObject();
+}
+
+
+inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) {
+ Object* undefined = heap->undefined_value();
+ return (info->script() != undefined) &&
+ (reinterpret_cast<Script*>(info->script())->source() != undefined);
+}
+
+
+template<typename StaticVisitor>
+bool StaticMarkingVisitor<StaticVisitor>::IsFlushable(
+ Heap* heap, JSFunction* function) {
+ SharedFunctionInfo* shared_info = function->unchecked_shared();
+
+ // Code is either on stack, in compilation cache or referenced
+ // by optimized version of function.
+ MarkBit code_mark = Marking::MarkBitFrom(function->code());
+ if (code_mark.Get()) {
+ if (!Marking::MarkBitFrom(shared_info).Get()) {
+ shared_info->set_code_age(0);
+ }
+ return false;
+ }
+
+ // The function must have a valid context and not be a builtin.
+ if (!IsValidNonBuiltinContext(function->unchecked_context())) {
+ return false;
+ }
+
+ // We do not flush code for optimized functions.
+ if (function->code() != shared_info->code()) {
+ return false;
+ }
+
+ return IsFlushable(heap, shared_info);
+}
+
+
+template<typename StaticVisitor>
+bool StaticMarkingVisitor<StaticVisitor>::IsFlushable(
+ Heap* heap, SharedFunctionInfo* shared_info) {
+ // Code is either on stack, in compilation cache or referenced
+ // by optimized version of function.
+ MarkBit code_mark = Marking::MarkBitFrom(shared_info->code());
+ if (code_mark.Get()) {
+ return false;
+ }
+
+ // The function must be compiled and have the source code available,
+ // to be able to recompile it in case we need the function again.
+ if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) {
+ return false;
+ }
+
+ // We never flush code for API functions.
+ Object* function_data = shared_info->function_data();
+ if (function_data->IsFunctionTemplateInfo()) {
+ return false;
+ }
+
+ // Only flush code for functions.
+ if (shared_info->code()->kind() != Code::FUNCTION) {
+ return false;
+ }
+
+ // Function must be lazy compilable.
+ if (!shared_info->allows_lazy_compilation()) {
+ return false;
+ }
+
+ // If this is a full script wrapped in a function we do no flush the code.
+ if (shared_info->is_toplevel()) {
+ return false;
+ }
+
+ // TODO(mstarzinger): The following will soon be replaced by a new way of
+ // aging code, that is based on an aging stub in the function prologue.
+
+ // How many collections newly compiled code object will survive before being
+ // flushed.
+ static const int kCodeAgeThreshold = 5;
+
+ // Age this shared function info.
+ if (shared_info->code_age() < kCodeAgeThreshold) {
+ shared_info->set_code_age(shared_info->code_age() + 1);
+ return false;
+ }
+
+ return true;
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfoStrongCode(
+ Heap* heap, HeapObject* object) {
+ StaticVisitor::BeforeVisitingSharedFunctionInfo(object);
+ Object** start_slot =
+ HeapObject::RawField(object,
+ SharedFunctionInfo::BodyDescriptor::kStartOffset);
+ Object** end_slot =
+ HeapObject::RawField(object,
+ SharedFunctionInfo::BodyDescriptor::kEndOffset);
+ StaticVisitor::VisitPointers(heap, start_slot, end_slot);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfoWeakCode(
+ Heap* heap, HeapObject* object) {
+ StaticVisitor::BeforeVisitingSharedFunctionInfo(object);
+ Object** name_slot =
+ HeapObject::RawField(object, SharedFunctionInfo::kNameOffset);
+ StaticVisitor::VisitPointer(heap, name_slot);
+
+ // Skip visiting kCodeOffset as it is treated weakly here.
+ STATIC_ASSERT(SharedFunctionInfo::kNameOffset + kPointerSize ==
+ SharedFunctionInfo::kCodeOffset);
+ STATIC_ASSERT(SharedFunctionInfo::kCodeOffset + kPointerSize ==
+ SharedFunctionInfo::kOptimizedCodeMapOffset);
+
+ Object** start_slot =
+ HeapObject::RawField(object,
+ SharedFunctionInfo::kOptimizedCodeMapOffset);
+ Object** end_slot =
+ HeapObject::RawField(object,
+ SharedFunctionInfo::BodyDescriptor::kEndOffset);
+ StaticVisitor::VisitPointers(heap, start_slot, end_slot);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitJSFunctionStrongCode(
+ Heap* heap, HeapObject* object) {
+ Object** start_slot =
+ HeapObject::RawField(object, JSFunction::kPropertiesOffset);
+ Object** end_slot =
+ HeapObject::RawField(object, JSFunction::kCodeEntryOffset);
+ StaticVisitor::VisitPointers(heap, start_slot, end_slot);
+
+ VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset);
+ STATIC_ASSERT(JSFunction::kCodeEntryOffset + kPointerSize ==
+ JSFunction::kPrototypeOrInitialMapOffset);
+
+ start_slot =
+ HeapObject::RawField(object, JSFunction::kPrototypeOrInitialMapOffset);
+ end_slot =
+ HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset);
+ StaticVisitor::VisitPointers(heap, start_slot, end_slot);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitJSFunctionWeakCode(
+ Heap* heap, HeapObject* object) {
+ Object** start_slot =
+ HeapObject::RawField(object, JSFunction::kPropertiesOffset);
+ Object** end_slot =
+ HeapObject::RawField(object, JSFunction::kCodeEntryOffset);
+ StaticVisitor::VisitPointers(heap, start_slot, end_slot);
+
+ // Skip visiting kCodeEntryOffset as it is treated weakly here.
+ STATIC_ASSERT(JSFunction::kCodeEntryOffset + kPointerSize ==
+ JSFunction::kPrototypeOrInitialMapOffset);
+
+ start_slot =
+ HeapObject::RawField(object, JSFunction::kPrototypeOrInitialMapOffset);
+ end_slot =
+ HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset);
+ StaticVisitor::VisitPointers(heap, start_slot, end_slot);
+}
+
+
void Code::CodeIterateBody(ObjectVisitor* v) {
int mode_mask = RelocInfo::kCodeTargetMask |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
diff --git a/deps/v8/src/objects-visiting.h b/deps/v8/src/objects-visiting.h
index b476dfef2..26d1b121d 100644
--- a/deps/v8/src/objects-visiting.h
+++ b/deps/v8/src/objects-visiting.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -46,71 +46,70 @@ namespace internal {
// Base class for all static visitors.
class StaticVisitorBase : public AllStatic {
public:
+#define VISITOR_ID_LIST(V) \
+ V(SeqAsciiString) \
+ V(SeqTwoByteString) \
+ V(ShortcutCandidate) \
+ V(ByteArray) \
+ V(FreeSpace) \
+ V(FixedArray) \
+ V(FixedDoubleArray) \
+ V(NativeContext) \
+ V(DataObject2) \
+ V(DataObject3) \
+ V(DataObject4) \
+ V(DataObject5) \
+ V(DataObject6) \
+ V(DataObject7) \
+ V(DataObject8) \
+ V(DataObject9) \
+ V(DataObjectGeneric) \
+ V(JSObject2) \
+ V(JSObject3) \
+ V(JSObject4) \
+ V(JSObject5) \
+ V(JSObject6) \
+ V(JSObject7) \
+ V(JSObject8) \
+ V(JSObject9) \
+ V(JSObjectGeneric) \
+ V(Struct2) \
+ V(Struct3) \
+ V(Struct4) \
+ V(Struct5) \
+ V(Struct6) \
+ V(Struct7) \
+ V(Struct8) \
+ V(Struct9) \
+ V(StructGeneric) \
+ V(ConsString) \
+ V(SlicedString) \
+ V(Oddball) \
+ V(Code) \
+ V(Map) \
+ V(PropertyCell) \
+ V(SharedFunctionInfo) \
+ V(JSFunction) \
+ V(JSWeakMap) \
+ V(JSRegExp)
+
+ // For data objects, JS objects and structs along with generic visitor which
+ // can visit object of any size we provide visitors specialized by
+ // object size in words.
+ // Ids of specialized visitors are declared in a linear order (without
+ // holes) starting from the id of visitor specialized for 2 words objects
+ // (base visitor id) and ending with the id of generic visitor.
+ // Method GetVisitorIdForSize depends on this ordering to calculate visitor
+ // id of specialized visitor from given instance size, base visitor id and
+ // generic visitor's id.
enum VisitorId {
- kVisitSeqAsciiString = 0,
- kVisitSeqTwoByteString,
- kVisitShortcutCandidate,
- kVisitByteArray,
- kVisitFreeSpace,
- kVisitFixedArray,
- kVisitFixedDoubleArray,
- kVisitGlobalContext,
-
- // For data objects, JS objects and structs along with generic visitor which
- // can visit object of any size we provide visitors specialized by
- // object size in words.
- // Ids of specialized visitors are declared in a linear order (without
- // holes) starting from the id of visitor specialized for 2 words objects
- // (base visitor id) and ending with the id of generic visitor.
- // Method GetVisitorIdForSize depends on this ordering to calculate visitor
- // id of specialized visitor from given instance size, base visitor id and
- // generic visitor's id.
-
- kVisitDataObject,
- kVisitDataObject2 = kVisitDataObject,
- kVisitDataObject3,
- kVisitDataObject4,
- kVisitDataObject5,
- kVisitDataObject6,
- kVisitDataObject7,
- kVisitDataObject8,
- kVisitDataObject9,
- kVisitDataObjectGeneric,
-
- kVisitJSObject,
- kVisitJSObject2 = kVisitJSObject,
- kVisitJSObject3,
- kVisitJSObject4,
- kVisitJSObject5,
- kVisitJSObject6,
- kVisitJSObject7,
- kVisitJSObject8,
- kVisitJSObject9,
- kVisitJSObjectGeneric,
-
- kVisitStruct,
- kVisitStruct2 = kVisitStruct,
- kVisitStruct3,
- kVisitStruct4,
- kVisitStruct5,
- kVisitStruct6,
- kVisitStruct7,
- kVisitStruct8,
- kVisitStruct9,
- kVisitStructGeneric,
-
- kVisitConsString,
- kVisitSlicedString,
- kVisitOddball,
- kVisitCode,
- kVisitMap,
- kVisitPropertyCell,
- kVisitSharedFunctionInfo,
- kVisitJSFunction,
- kVisitJSWeakMap,
- kVisitJSRegExp,
-
+#define VISITOR_ID_ENUM_DECL(id) kVisit##id,
+ VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
+#undef VISITOR_ID_ENUM_DECL
kVisitorIdCount,
+ kVisitDataObject = kVisitDataObject2,
+ kVisitJSObject = kVisitJSObject2,
+ kVisitStruct = kVisitStruct2,
kMinObjectSizeInWords = 2
};
@@ -361,7 +360,98 @@ class StaticNewSpaceVisitor : public StaticVisitorBase {
template<typename StaticVisitor>
VisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback>
- StaticNewSpaceVisitor<StaticVisitor>::table_;
+ StaticNewSpaceVisitor<StaticVisitor>::table_;
+
+
+// Base class for visitors used to transitively mark the entire heap.
+// IterateBody returns nothing.
+// Certain types of objects might not be handled by this base class and
+// no visitor function is registered by the generic initialization. A
+// specialized visitor function needs to be provided by the inheriting
+// class itself for those cases.
+//
+// This class is intended to be used in the following way:
+//
+// class SomeVisitor : public StaticMarkingVisitor<SomeVisitor> {
+// ...
+// }
+//
+// This is an example of Curiously recurring template pattern.
+template<typename StaticVisitor>
+class StaticMarkingVisitor : public StaticVisitorBase {
+ public:
+ static void Initialize();
+
+ static inline void IterateBody(Map* map, HeapObject* obj) {
+ table_.GetVisitor(map)(map, obj);
+ }
+
+ static inline void VisitCodeEntry(Heap* heap, Address entry_address);
+ static inline void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo);
+ static inline void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo);
+ static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo);
+ static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo);
+ static inline void VisitExternalReference(RelocInfo* rinfo) { }
+ static inline void VisitRuntimeEntry(RelocInfo* rinfo) { }
+
+ // TODO(mstarzinger): This should be made protected once refactoring is done.
+ static inline void VisitNativeContext(Map* map, HeapObject* object);
+
+ // TODO(mstarzinger): This should be made protected once refactoring is done.
+ // Mark non-optimize code for functions inlined into the given optimized
+ // code. This will prevent it from being flushed.
+ static void MarkInlinedFunctionsCode(Heap* heap, Code* code);
+
+ protected:
+ static inline void VisitMap(Map* map, HeapObject* object);
+ static inline void VisitCode(Map* map, HeapObject* object);
+ static inline void VisitSharedFunctionInfo(Map* map, HeapObject* object);
+ static inline void VisitJSFunction(Map* map, HeapObject* object);
+ static inline void VisitJSRegExp(Map* map, HeapObject* object);
+
+ // Mark pointers in a Map and its TransitionArray together, possibly
+ // treating transitions or back pointers weak.
+ static void MarkMapContents(Heap* heap, Map* map);
+ static void MarkTransitionArray(Heap* heap, TransitionArray* transitions);
+
+ // Code flushing support.
+ static inline bool IsFlushable(Heap* heap, JSFunction* function);
+ static inline bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info);
+
+ // Helpers used by code flushing support that visit pointer fields and treat
+ // references to code objects either strongly or weakly.
+ static void VisitSharedFunctionInfoStrongCode(Heap* heap, HeapObject* object);
+ static void VisitSharedFunctionInfoWeakCode(Heap* heap, HeapObject* object);
+ static void VisitJSFunctionStrongCode(Heap* heap, HeapObject* object);
+ static void VisitJSFunctionWeakCode(Heap* heap, HeapObject* object);
+
+ class DataObjectVisitor {
+ public:
+ template<int size>
+ static inline void VisitSpecialized(Map* map, HeapObject* object) {
+ }
+
+ static inline void Visit(Map* map, HeapObject* object) {
+ }
+ };
+
+ typedef FlexibleBodyVisitor<StaticVisitor,
+ JSObject::BodyDescriptor,
+ void> JSObjectVisitor;
+
+ typedef FlexibleBodyVisitor<StaticVisitor,
+ StructBodyDescriptor,
+ void> StructObjectVisitor;
+
+ typedef void (*Callback)(Map* map, HeapObject* object);
+
+ static VisitorDispatchTable<Callback> table_;
+};
+
+
+template<typename StaticVisitor>
+VisitorDispatchTable<typename StaticMarkingVisitor<StaticVisitor>::Callback>
+ StaticMarkingVisitor<StaticVisitor>::table_;
} } // namespace v8::internal
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index 6b2f64ac2..792b6d984 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -69,13 +69,13 @@ MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
}
-MaybeObject* Object::ToObject(Context* global_context) {
+MaybeObject* Object::ToObject(Context* native_context) {
if (IsNumber()) {
- return CreateJSValue(global_context->number_function(), this);
+ return CreateJSValue(native_context->number_function(), this);
} else if (IsBoolean()) {
- return CreateJSValue(global_context->boolean_function(), this);
+ return CreateJSValue(native_context->boolean_function(), this);
} else if (IsString()) {
- return CreateJSValue(global_context->string_function(), this);
+ return CreateJSValue(native_context->string_function(), this);
}
ASSERT(IsJSObject());
return this;
@@ -87,16 +87,16 @@ MaybeObject* Object::ToObject() {
return this;
} else if (IsNumber()) {
Isolate* isolate = Isolate::Current();
- Context* global_context = isolate->context()->global_context();
- return CreateJSValue(global_context->number_function(), this);
+ Context* native_context = isolate->context()->native_context();
+ return CreateJSValue(native_context->number_function(), this);
} else if (IsBoolean()) {
Isolate* isolate = HeapObject::cast(this)->GetIsolate();
- Context* global_context = isolate->context()->global_context();
- return CreateJSValue(global_context->boolean_function(), this);
+ Context* native_context = isolate->context()->native_context();
+ return CreateJSValue(native_context->boolean_function(), this);
} else if (IsString()) {
Isolate* isolate = HeapObject::cast(this)->GetIsolate();
- Context* global_context = isolate->context()->global_context();
- return CreateJSValue(global_context->string_function(), this);
+ Context* native_context = isolate->context()->native_context();
+ return CreateJSValue(native_context->string_function(), this);
}
// Throw a type error.
@@ -134,13 +134,16 @@ void Object::Lookup(String* name, LookupResult* result) {
if (IsJSReceiver()) {
holder = this;
} else {
- Context* global_context = Isolate::Current()->context()->global_context();
+ Context* native_context = Isolate::Current()->context()->native_context();
if (IsNumber()) {
- holder = global_context->number_function()->instance_prototype();
+ holder = native_context->number_function()->instance_prototype();
} else if (IsString()) {
- holder = global_context->string_function()->instance_prototype();
+ holder = native_context->string_function()->instance_prototype();
} else if (IsBoolean()) {
- holder = global_context->boolean_function()->instance_prototype();
+ holder = native_context->boolean_function()->instance_prototype();
+ } else {
+ Isolate::Current()->PushStackTraceAndDie(
+ 0xDEAD0000, this, JSReceiver::cast(this)->map(), 0xDEAD0001);
}
}
ASSERT(holder != NULL); // Cannot handle null or undefined.
@@ -190,6 +193,7 @@ MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver,
}
Object* fun_obj = data->getter();
v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
+ if (call_fun == NULL) return isolate->heap()->undefined_value();
HandleScope scope(isolate);
JSObject* self = JSObject::cast(receiver);
Handle<String> key(name);
@@ -206,7 +210,9 @@ MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver,
if (result.IsEmpty()) {
return isolate->heap()->undefined_value();
}
- return *v8::Utils::OpenHandle(*result);
+ Object* return_value = *v8::Utils::OpenHandle(*result);
+ return_value->VerifyApiCallResultType();
+ return return_value;
}
// __defineGetter__ callback
@@ -406,16 +412,16 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
} else {
result->holder()->LocalLookupRealNamedProperty(name, &r);
}
- if (r.IsProperty()) {
- return GetPropertyAttributeWithFailedAccessCheck(receiver,
- &r,
- name,
- continue_search);
- }
- break;
+ if (!r.IsFound()) break;
+ return GetPropertyAttributeWithFailedAccessCheck(receiver,
+ &r,
+ name,
+ continue_search);
}
- default:
+ case HANDLER:
+ case TRANSITION:
+ case NONEXISTENT:
UNREACHABLE();
}
}
@@ -481,10 +487,21 @@ MaybeObject* JSObject::SetNormalizedProperty(String* name,
set_properties(StringDictionary::cast(dict));
return value;
}
- // Preserve enumeration index.
- details = PropertyDetails(details.attributes(),
- details.type(),
- property_dictionary()->DetailsAt(entry).index());
+
+ PropertyDetails original_details = property_dictionary()->DetailsAt(entry);
+ int enumeration_index;
+ // Preserve the enumeration index unless the property was deleted.
+ if (original_details.IsDeleted()) {
+ enumeration_index = property_dictionary()->NextEnumerationIndex();
+ property_dictionary()->SetNextEnumerationIndex(enumeration_index + 1);
+ } else {
+ enumeration_index = original_details.dictionary_index();
+ ASSERT(enumeration_index > 0);
+ }
+
+ details = PropertyDetails(
+ details.attributes(), details.type(), enumeration_index);
+
if (IsGlobalObject()) {
JSGlobalPropertyCell* cell =
JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry));
@@ -512,11 +529,12 @@ MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) {
// map change to invalidate any ICs that think they can load
// from the DontDelete cell without checking if it contains
// the hole value.
- Object* new_map;
- { MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
- if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
- }
- set_map(Map::cast(new_map));
+ Map* new_map;
+ MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+
+ ASSERT(new_map->is_dictionary_map());
+ set_map(new_map);
}
JSGlobalPropertyCell* cell =
JSGlobalPropertyCell::cast(dictionary->ValueAt(entry));
@@ -633,14 +651,12 @@ MaybeObject* Object::GetProperty(Object* receiver,
receiver, result->GetCallbackObject(), name);
case HANDLER:
return result->proxy()->GetPropertyWithHandler(receiver, name);
- case INTERCEPTOR: {
- JSObject* recvr = JSObject::cast(receiver);
+ case INTERCEPTOR:
return result->holder()->GetPropertyWithInterceptor(
- recvr, name, attributes);
- }
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
+ receiver, name, attributes);
+ case TRANSITION:
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
UNREACHABLE();
@@ -661,13 +677,13 @@ MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
holder = holder->GetPrototype()) {
if (!holder->IsJSObject()) {
Isolate* isolate = heap->isolate();
- Context* global_context = isolate->context()->global_context();
+ Context* native_context = isolate->context()->native_context();
if (holder->IsNumber()) {
- holder = global_context->number_function()->instance_prototype();
+ holder = native_context->number_function()->instance_prototype();
} else if (holder->IsString()) {
- holder = global_context->string_function()->instance_prototype();
+ holder = native_context->string_function()->instance_prototype();
} else if (holder->IsBoolean()) {
- holder = global_context->boolean_function()->instance_prototype();
+ holder = native_context->boolean_function()->instance_prototype();
} else if (holder->IsJSProxy()) {
return JSProxy::cast(holder)->GetElementWithHandler(receiver, index);
} else {
@@ -709,7 +725,7 @@ MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
Object* Object::GetPrototype() {
if (IsSmi()) {
Heap* heap = Isolate::Current()->heap();
- Context* context = heap->isolate()->context()->global_context();
+ Context* context = heap->isolate()->context()->native_context();
return context->number_function()->instance_prototype();
}
@@ -721,7 +737,7 @@ Object* Object::GetPrototype() {
return heap_object->map()->prototype();
}
Heap* heap = heap_object->GetHeap();
- Context* context = heap->isolate()->context()->global_context();
+ Context* context = heap->isolate()->context()->native_context();
if (heap_object->IsHeapNumber()) {
return context->number_function()->instance_prototype();
@@ -763,7 +779,6 @@ MaybeObject* Object::GetHash(CreationFlag flag) {
bool Object::SameValue(Object* other) {
if (other == this) return true;
- if (!IsHeapObject() || !other->IsHeapObject()) return false;
// The object is either a number, a string, an odd-ball,
// a real JS object, or a Harmony proxy.
@@ -1399,8 +1414,7 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
case EXTERNAL_DOUBLE_ARRAY_TYPE:
break;
case SHARED_FUNCTION_INFO_TYPE: {
- SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(this);
- shared->SharedFunctionInfoIterateBody(v);
+ SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
break;
}
@@ -1488,20 +1502,19 @@ String* JSReceiver::constructor_name() {
MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
String* name,
- Object* value) {
- int index = new_map->PropertyIndexFor(name);
+ Object* value,
+ int field_index) {
if (map()->unused_property_fields() == 0) {
- ASSERT(map()->unused_property_fields() == 0);
int new_unused = new_map->unused_property_fields();
- Object* values;
+ FixedArray* values;
{ MaybeObject* maybe_values =
properties()->CopySize(properties()->length() + new_unused + 1);
- if (!maybe_values->ToObject(&values)) return maybe_values;
+ if (!maybe_values->To(&values)) return maybe_values;
}
- set_properties(FixedArray::cast(values));
+ set_properties(values);
}
set_map(new_map);
- return FastPropertyAtPut(index, value);
+ return FastPropertyAtPut(field_index, value);
}
@@ -1526,93 +1539,63 @@ MaybeObject* JSObject::AddFastProperty(String* name,
PropertyAttributes attributes,
StoreFromKeyed store_mode) {
ASSERT(!IsJSGlobalProxy());
+ ASSERT(DescriptorArray::kNotFound ==
+ map()->instance_descriptors()->Search(
+ name, map()->NumberOfOwnDescriptors()));
// Normalize the object if the name is an actual string (not the
// hidden symbols) and is not a real identifier.
+ // Normalize the object if it will have too many fast properties.
Isolate* isolate = GetHeap()->isolate();
StringInputBuffer buffer(name);
- if (!IsIdentifier(isolate->unicode_cache(), &buffer)
- && name != isolate->heap()->hidden_symbol()) {
+ if ((!IsIdentifier(isolate->unicode_cache(), &buffer)
+ && name != isolate->heap()->hidden_symbol()) ||
+ (map()->unused_property_fields() == 0 &&
+ TooManyFastProperties(properties()->length(), store_mode))) {
Object* obj;
- { MaybeObject* maybe_obj =
- NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
+ MaybeObject* maybe_obj =
+ NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+
return AddSlowProperty(name, value, attributes);
}
- DescriptorArray* old_descriptors = map()->instance_descriptors();
// Compute the new index for new field.
int index = map()->NextFreePropertyIndex();
// Allocate new instance descriptors with (name, index) added
- FieldDescriptor new_field(name, index, attributes);
- Object* new_descriptors;
- { MaybeObject* maybe_new_descriptors =
- old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS);
- if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
- return maybe_new_descriptors;
- }
- }
-
- // Only allow map transition if the object isn't the global object and there
- // is not a transition for the name, or there's a transition for the name but
- // it's unrelated to properties.
- int descriptor_index = old_descriptors->Search(name);
-
- // Element transitions are stored in the descriptor for property "", which is
- // not a identifier and should have forced a switch to slow properties above.
- bool can_insert_transition = descriptor_index == DescriptorArray::kNotFound;
- bool allow_map_transition =
- can_insert_transition &&
- (isolate->context()->global_context()->object_function()->map() != map());
+ FieldDescriptor new_field(name, index, attributes, 0);
ASSERT(index < map()->inobject_properties() ||
(index - map()->inobject_properties()) < properties()->length() ||
map()->unused_property_fields() == 0);
- // Allocate a new map for the object.
- Object* r;
- { MaybeObject* maybe_r = map()->CopyDropDescriptors();
- if (!maybe_r->ToObject(&r)) return maybe_r;
- }
- Map* new_map = Map::cast(r);
- if (allow_map_transition) {
- // Allocate new instance descriptors for the old map with map transition.
- MapTransitionDescriptor d(name, Map::cast(new_map), attributes);
- Object* r;
- { MaybeObject* maybe_r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS);
- if (!maybe_r->ToObject(&r)) return maybe_r;
- }
- old_descriptors = DescriptorArray::cast(r);
- }
+
+ FixedArray* values = NULL;
if (map()->unused_property_fields() == 0) {
- if (TooManyFastProperties(properties()->length(), store_mode)) {
- Object* obj;
- { MaybeObject* maybe_obj =
- NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- return AddSlowProperty(name, value, attributes);
- }
// Make room for the new value
- Object* values;
- { MaybeObject* maybe_values =
- properties()->CopySize(properties()->length() + kFieldsAdded);
- if (!maybe_values->ToObject(&values)) return maybe_values;
- }
- set_properties(FixedArray::cast(values));
+ MaybeObject* maybe_values =
+ properties()->CopySize(properties()->length() + kFieldsAdded);
+ if (!maybe_values->To(&values)) return maybe_values;
+ }
+
+ // Only allow map transition if the object isn't the global object.
+ TransitionFlag flag = isolate->empty_object_map() != map()
+ ? INSERT_TRANSITION
+ : OMIT_TRANSITION;
+
+ Map* new_map;
+ MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag);
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+
+ if (map()->unused_property_fields() == 0) {
+ ASSERT(values != NULL);
+ set_properties(values);
new_map->set_unused_property_fields(kFieldsAdded - 1);
} else {
new_map->set_unused_property_fields(map()->unused_property_fields() - 1);
}
- // We have now allocated all the necessary objects.
- // All the changes can be applied at once, so they are atomic.
- if (allow_map_transition) {
- map()->set_instance_descriptors(old_descriptors);
- }
- new_map->SetBackPointer(map());
- new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
+
set_map(new_map);
return FastPropertyAtPut(index, value);
}
@@ -1623,57 +1606,26 @@ MaybeObject* JSObject::AddConstantFunctionProperty(
JSFunction* function,
PropertyAttributes attributes) {
// Allocate new instance descriptors with (name, function) added
- ConstantFunctionDescriptor d(name, function, attributes);
- Object* new_descriptors;
- { MaybeObject* maybe_new_descriptors =
- map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS);
- if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
- return maybe_new_descriptors;
- }
- }
-
- // Allocate a new map for the object.
- Object* new_map;
- { MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
- if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
- }
-
- DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors);
- Map::cast(new_map)->set_instance_descriptors(descriptors);
- Map* old_map = map();
- set_map(Map::cast(new_map));
+ ConstantFunctionDescriptor d(name, function, attributes, 0);
- // If the old map is the global object map (from new Object()),
- // then transitions are not added to it, so we are done.
Heap* heap = GetHeap();
- if (old_map == heap->isolate()->context()->global_context()->
- object_function()->map()) {
- return function;
- }
-
- // Do not add CONSTANT_TRANSITIONS to global objects
- if (IsGlobalObject()) {
- return function;
- }
+ TransitionFlag flag =
+ // Do not add transitions to the empty object map (map of "new Object()"),
+ // nor to global objects.
+ (map() == heap->isolate()->empty_object_map() || IsGlobalObject() ||
+ // Don't add transitions to special properties with non-trivial
+ // attributes.
+ // TODO(verwaest): Once we support attribute changes, these transitions
+ // should be kept as well.
+ attributes != NONE)
+ ? OMIT_TRANSITION
+ : INSERT_TRANSITION;
- // Add a CONSTANT_TRANSITION descriptor to the old map,
- // so future assignments to this property on other objects
- // of the same type will create a normal field, not a constant function.
- // Don't do this for special properties, with non-trival attributes.
- if (attributes != NONE) {
- return function;
- }
- ConstTransitionDescriptor mark(name, Map::cast(new_map));
- { MaybeObject* maybe_new_descriptors =
- old_map->instance_descriptors()->CopyInsert(&mark, KEEP_TRANSITIONS);
- if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
- // We have accomplished the main goal, so return success.
- return function;
- }
- }
- old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
- Map::cast(new_map)->SetBackPointer(old_map);
+ Map* new_map;
+ MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag);
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+ set_map(new_map);
return function;
}
@@ -1738,7 +1690,7 @@ MaybeObject* JSObject::AddProperty(String* name,
}
if (HasFastProperties()) {
// Ensure the descriptor array does not get too big.
- if (map_of_this->instance_descriptors()->number_of_descriptors() <
+ if (map_of_this->NumberOfOwnDescriptors() <
DescriptorArray::kMaxNumberOfDescriptors) {
if (value->IsJSFunction()) {
return AddConstantFunctionProperty(name,
@@ -1770,9 +1722,10 @@ MaybeObject* JSObject::SetPropertyPostInterceptor(
// Check local property, ignore interceptor.
LookupResult result(GetIsolate());
LocalLookupRealNamedProperty(name, &result);
+ if (!result.IsFound()) map()->LookupTransition(this, name, &result);
if (result.IsFound()) {
- // An existing property, a map transition or a null descriptor was
- // found. Use set property to handle all these cases.
+ // An existing property or a map transition was found. Use set property to
+ // handle all these cases.
return SetProperty(&result, name, value, attributes, strict_mode);
}
bool done = false;
@@ -1794,8 +1747,7 @@ MaybeObject* JSObject::ReplaceSlowProperty(String* name,
int new_enumeration_index = 0; // 0 means "Use the next available index."
if (old_index != -1) {
// All calls to ReplaceSlowProperty have had all transitions removed.
- ASSERT(!dictionary->ContainsTransition(old_index));
- new_enumeration_index = dictionary->DetailsAt(old_index).index();
+ new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index();
}
PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
@@ -1803,39 +1755,52 @@ MaybeObject* JSObject::ReplaceSlowProperty(String* name,
}
-MaybeObject* JSObject::ConvertDescriptorToFieldAndMapTransition(
+MaybeObject* JSObject::ConvertTransitionToMapTransition(
+ int transition_index,
String* name,
Object* new_value,
PropertyAttributes attributes) {
Map* old_map = map();
+ Map* old_target = old_map->GetTransition(transition_index);
Object* result;
- { MaybeObject* maybe_result =
- ConvertDescriptorToField(name, new_value, attributes);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- // If we get to this point we have succeeded - do not return failure
- // after this point. Later stuff is optional.
- if (!HasFastProperties()) {
- return result;
- }
- // Do not add transitions to the map of "new Object()".
- if (map() == GetIsolate()->context()->global_context()->
- object_function()->map()) {
- return result;
- }
- MapTransitionDescriptor transition(name,
- map(),
- attributes);
- Object* new_descriptors;
- { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()->
- CopyInsert(&transition, KEEP_TRANSITIONS);
- if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
- return result; // Yes, return _result_.
- }
- }
- old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
- map()->SetBackPointer(old_map);
+ MaybeObject* maybe_result =
+ ConvertDescriptorToField(name, new_value, attributes);
+ if (!maybe_result->To(&result)) return maybe_result;
+
+ if (!HasFastProperties()) return result;
+
+ // This method should only be used to convert existing transitions. Objects
+ // with the map of "new Object()" cannot have transitions in the first place.
+ Map* new_map = map();
+ ASSERT(new_map != GetIsolate()->empty_object_map());
+
+ // TODO(verwaest): From here on we lose existing map transitions, causing
+ // invalid back pointers. This will change once we can store multiple
+ // transitions with the same key.
+
+ bool owned_descriptors = old_map->owns_descriptors();
+ if (owned_descriptors ||
+ old_target->instance_descriptors() == old_map->instance_descriptors()) {
+ // Since the conversion above generated a new fast map with an additional
+ // property which can be shared as well, install this descriptor pointer
+ // along the entire chain of smaller maps.
+ Map* map;
+ DescriptorArray* new_descriptors = new_map->instance_descriptors();
+ DescriptorArray* old_descriptors = old_map->instance_descriptors();
+ for (Object* current = old_map;
+ !current->IsUndefined();
+ current = map->GetBackPointer()) {
+ map = Map::cast(current);
+ if (map->instance_descriptors() != old_descriptors) break;
+ map->SetEnumLength(Map::kInvalidEnumCache);
+ map->set_instance_descriptors(new_descriptors);
+ }
+ old_map->set_owns_descriptors(false);
+ }
+
+ old_map->SetTransition(transition_index, new_map);
+ new_map->SetBackPointer(old_map);
return result;
}
@@ -1846,57 +1811,36 @@ MaybeObject* JSObject::ConvertDescriptorToField(String* name,
if (map()->unused_property_fields() == 0 &&
TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) {
Object* obj;
- { MaybeObject* maybe_obj =
- NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
+ MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
return ReplaceSlowProperty(name, new_value, attributes);
}
int index = map()->NextFreePropertyIndex();
- FieldDescriptor new_field(name, index, attributes);
- // Make a new DescriptorArray replacing an entry with FieldDescriptor.
- Object* descriptors_unchecked;
- { MaybeObject* maybe_descriptors_unchecked = map()->instance_descriptors()->
- CopyInsert(&new_field, REMOVE_TRANSITIONS);
- if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
- return maybe_descriptors_unchecked;
- }
- }
- DescriptorArray* new_descriptors =
- DescriptorArray::cast(descriptors_unchecked);
+ FieldDescriptor new_field(name, index, attributes, 0);
// Make a new map for the object.
- Object* new_map_unchecked;
- { MaybeObject* maybe_new_map_unchecked = map()->CopyDropDescriptors();
- if (!maybe_new_map_unchecked->ToObject(&new_map_unchecked)) {
- return maybe_new_map_unchecked;
- }
- }
- Map* new_map = Map::cast(new_map_unchecked);
- new_map->set_instance_descriptors(new_descriptors);
+ Map* new_map;
+ MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field,
+ OMIT_TRANSITION);
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
// Make new properties array if necessary.
- FixedArray* new_properties = 0; // Will always be NULL or a valid pointer.
+ FixedArray* new_properties = NULL;
int new_unused_property_fields = map()->unused_property_fields() - 1;
if (map()->unused_property_fields() == 0) {
new_unused_property_fields = kFieldsAdded - 1;
- Object* new_properties_object;
- { MaybeObject* maybe_new_properties_object =
- properties()->CopySize(properties()->length() + kFieldsAdded);
- if (!maybe_new_properties_object->ToObject(&new_properties_object)) {
- return maybe_new_properties_object;
- }
- }
- new_properties = FixedArray::cast(new_properties_object);
+ MaybeObject* maybe_new_properties =
+ properties()->CopySize(properties()->length() + kFieldsAdded);
+ if (!maybe_new_properties->To(&new_properties)) return maybe_new_properties;
}
// Update pointers to commit changes.
// Object points to the new map.
new_map->set_unused_property_fields(new_unused_property_fields);
set_map(new_map);
- if (new_properties) {
- set_properties(FixedArray::cast(new_properties));
+ if (new_properties != NULL) {
+ set_properties(new_properties);
}
return FastPropertyAtPut(index, new_value);
}
@@ -1964,6 +1908,9 @@ MaybeObject* JSReceiver::SetProperty(String* name,
JSReceiver::StoreFromKeyed store_mode) {
LookupResult result(GetIsolate());
LocalLookup(name, &result);
+ if (!result.IsFound()) {
+ map()->LookupTransition(JSObject::cast(this), name, &result);
+ }
return SetProperty(&result, name, value, attributes, strict_mode, store_mode);
}
@@ -2152,9 +2099,9 @@ MaybeObject* JSObject::SetPropertyViaPrototypes(
return result.proxy()->SetPropertyViaPrototypesWithHandler(
this, name, value, attributes, strict_mode, done);
}
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
+ case TRANSITION:
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
}
@@ -2171,33 +2118,109 @@ MaybeObject* JSObject::SetPropertyViaPrototypes(
}
-void JSObject::LookupInDescriptor(String* name, LookupResult* result) {
- DescriptorArray* descriptors = map()->instance_descriptors();
- int number = descriptors->SearchWithCache(name);
- if (number != DescriptorArray::kNotFound) {
- result->DescriptorResult(this, descriptors->GetDetails(number), number);
- } else {
- result->NotFound();
+enum RightTrimMode { FROM_GC, FROM_MUTATOR };
+
+
+static void ZapEndOfFixedArray(Address new_end, int to_trim) {
+ // If we are doing a big trim in old space then we zap the space.
+ Object** zap = reinterpret_cast<Object**>(new_end);
+ zap++; // Header of filler must be at least one word so skip that.
+ for (int i = 1; i < to_trim; i++) {
+ *zap++ = Smi::FromInt(0);
}
}
-void Map::LookupInDescriptors(JSObject* holder,
- String* name,
- LookupResult* result) {
- DescriptorArray* descriptors = instance_descriptors();
- DescriptorLookupCache* cache =
- GetHeap()->isolate()->descriptor_lookup_cache();
- int number = cache->Lookup(descriptors, name);
- if (number == DescriptorLookupCache::kAbsent) {
- number = descriptors->Search(name);
- cache->Update(descriptors, name, number);
- }
- if (number != DescriptorArray::kNotFound) {
- result->DescriptorResult(holder, descriptors->GetDetails(number), number);
- } else {
- result->NotFound();
+template<RightTrimMode trim_mode>
+static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) {
+ ASSERT(elms->map() != HEAP->fixed_cow_array_map());
+ // For now this trick is only applied to fixed arrays in new and paged space.
+ ASSERT(!HEAP->lo_space()->Contains(elms));
+
+ const int len = elms->length();
+
+ ASSERT(to_trim < len);
+
+ Address new_end = elms->address() + FixedArray::SizeFor(len - to_trim);
+
+ if (trim_mode != FROM_GC || Heap::ShouldZapGarbage()) {
+ ZapEndOfFixedArray(new_end, to_trim);
+ }
+
+ int size_delta = to_trim * kPointerSize;
+
+ // Technically in new space this write might be omitted (except for
+ // debug mode which iterates through the heap), but to play safer
+ // we still do it.
+ heap->CreateFillerObjectAt(new_end, size_delta);
+
+ elms->set_length(len - to_trim);
+
+ // Maintain marking consistency for IncrementalMarking.
+ if (Marking::IsBlack(Marking::MarkBitFrom(elms))) {
+ if (trim_mode == FROM_GC) {
+ MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta);
+ } else {
+ MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta);
+ }
+ }
+}
+
+
+void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
+ Handle<DescriptorArray> descriptors(map->instance_descriptors());
+ if (slack <= descriptors->NumberOfSlackDescriptors()) return;
+ int number_of_descriptors = descriptors->number_of_descriptors();
+ Isolate* isolate = map->GetIsolate();
+ Handle<DescriptorArray> new_descriptors =
+ isolate->factory()->NewDescriptorArray(number_of_descriptors, slack);
+ DescriptorArray::WhitenessWitness witness(*new_descriptors);
+
+ for (int i = 0; i < number_of_descriptors; ++i) {
+ new_descriptors->CopyFrom(i, *descriptors, i, witness);
+ }
+
+ map->set_instance_descriptors(*new_descriptors);
+}
+
+
+void Map::AppendCallbackDescriptors(Handle<Map> map,
+ Handle<Object> descriptors) {
+ Isolate* isolate = map->GetIsolate();
+ Handle<DescriptorArray> array(map->instance_descriptors());
+ NeanderArray callbacks(descriptors);
+ int nof_callbacks = callbacks.length();
+
+ ASSERT(array->NumberOfSlackDescriptors() >= nof_callbacks);
+
+ // Ensure the keys are symbols before writing them into the instance
+ // descriptor. Since it may cause a GC, it has to be done before we
+ // temporarily put the heap in an invalid state while appending descriptors.
+ for (int i = 0; i < nof_callbacks; ++i) {
+ Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks.get(i)));
+ Handle<String> key =
+ isolate->factory()->SymbolFromString(
+ Handle<String>(String::cast(entry->name())));
+ entry->set_name(*key);
}
+
+ int nof = map->NumberOfOwnDescriptors();
+
+ // Fill in new callback descriptors. Process the callbacks from
+ // back to front so that the last callback with a given name takes
+ // precedence over previously added callbacks with that name.
+ for (int i = nof_callbacks - 1; i >= 0; i--) {
+ AccessorInfo* entry = AccessorInfo::cast(callbacks.get(i));
+ String* key = String::cast(entry->name());
+ // Check if a descriptor with this name already exists before writing.
+ if (array->Search(key, nof) == DescriptorArray::kNotFound) {
+ CallbacksDescriptor desc(key, entry, entry->property_attributes());
+ array->Append(&desc);
+ nof += 1;
+ }
+ }
+
+ map->SetNumberOfOwnDescriptors(nof);
}
@@ -2250,21 +2273,16 @@ static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
ASSERT(index <= to_index);
for (; index < to_index; ++index) {
- Map* next_map = current_map->elements_transition_map();
- if (next_map == NULL) {
- return current_map;
- }
- current_map = next_map;
+ if (!current_map->HasElementsTransition()) return current_map;
+ current_map = current_map->elements_transition_map();
}
- if (!IsFastElementsKind(to_kind)) {
+ if (!IsFastElementsKind(to_kind) && current_map->HasElementsTransition()) {
Map* next_map = current_map->elements_transition_map();
- if (next_map != NULL && next_map->elements_kind() == to_kind) {
- return next_map;
- }
- ASSERT(current_map->elements_kind() == TERMINAL_FAST_ELEMENTS_KIND);
- } else {
- ASSERT(current_map->elements_kind() == to_kind);
+ if (next_map->elements_kind() == to_kind) return next_map;
}
+ ASSERT(IsFastElementsKind(to_kind)
+ ? current_map->elements_kind() == to_kind
+ : current_map->elements_kind() == TERMINAL_FAST_ELEMENTS_KIND);
return current_map;
}
@@ -2276,29 +2294,6 @@ Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) {
}
-MaybeObject* Map::CreateNextElementsTransition(ElementsKind next_kind) {
- ASSERT(elements_transition_map() == NULL ||
- ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS ||
- IsExternalArrayElementsKind(
- elements_transition_map()->elements_kind())) &&
- (next_kind == DICTIONARY_ELEMENTS ||
- IsExternalArrayElementsKind(next_kind))));
- ASSERT(!IsFastElementsKind(next_kind) ||
- IsMoreGeneralElementsKindTransition(elements_kind(), next_kind));
- ASSERT(next_kind != elements_kind());
-
- Map* next_map;
- MaybeObject* maybe_next_map =
- this->CopyDropTransitions(DescriptorArray::CANNOT_BE_SHARED);
- if (!maybe_next_map->To(&next_map)) return maybe_next_map;
-
- next_map->set_elements_kind(next_kind);
- next_map->SetBackPointer(this);
- this->set_elements_transition_map(next_map);
- return next_map;
-}
-
-
static MaybeObject* AddMissingElementsTransitions(Map* map,
ElementsKind to_kind) {
ASSERT(IsFastElementsKind(map->elements_kind()));
@@ -2312,18 +2307,18 @@ static MaybeObject* AddMissingElementsTransitions(Map* map,
Map* current_map = map;
for (; index < to_index; ++index) {
- ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index + 1);
- MaybeObject* maybe_next_map =
- current_map->CreateNextElementsTransition(next_kind);
- if (!maybe_next_map->To(&current_map)) return maybe_next_map;
+ ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index + 1);
+ MaybeObject* maybe_next_map =
+ current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION);
+ if (!maybe_next_map->To(&current_map)) return maybe_next_map;
}
// In case we are exiting the fast elements kind system, just add the map in
// the end.
if (!IsFastElementsKind(to_kind)) {
- MaybeObject* maybe_next_map =
- current_map->CreateNextElementsTransition(to_kind);
- if (!maybe_next_map->To(&current_map)) return maybe_next_map;
+ MaybeObject* maybe_next_map =
+ current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION);
+ if (!maybe_next_map->To(&current_map)) return maybe_next_map;
}
ASSERT(current_map->elements_kind() == to_kind);
@@ -2340,22 +2335,6 @@ Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
}
-// If the map is using the empty descriptor array, install a new empty
-// descriptor array that will contain an element transition.
-// TODO(verwaest) Goes away once the descriptor array is immutable.
-static MaybeObject* EnsureMayContainTransitions(Map* map) {
- if (map->instance_descriptors()->MayContainTransitions()) return map;
- DescriptorArray* descriptor_array;
- MaybeObject* maybe_descriptor_array =
- DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
- if (!maybe_descriptor_array->To(&descriptor_array)) {
- return maybe_descriptor_array;
- }
- map->set_instance_descriptors(descriptor_array);
- return map;
-}
-
-
MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) {
Map* start_map = map();
ElementsKind from_kind = start_map->elements_kind();
@@ -2364,12 +2343,11 @@ MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) {
return start_map;
}
- Context* global_context = GetIsolate()->context()->global_context();
bool allow_store_transition =
// Only remember the map transition if the object's map is NOT equal to
// the global object_function's map and there is not an already existing
// non-matching element transition.
- (global_context->object_function()->map() != map()) &&
+ (GetIsolate()->empty_object_map() != map()) &&
!start_map->IsUndefined() && !start_map->is_shared() &&
IsFastElementsKind(from_kind);
@@ -2381,16 +2359,9 @@ MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) {
}
if (!allow_store_transition) {
- // Create a new free-floating map only if we are not allowed to store it.
- Map* new_map = NULL;
- MaybeObject* maybe_new_map =
- start_map->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- new_map->set_elements_kind(to_kind);
- return new_map;
+ return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION);
}
- EnsureMayContainTransitions(start_map);
Map* closest_map = FindClosestElementsTransition(start_map, to_kind);
if (closest_map->elements_kind() == to_kind) {
@@ -2412,47 +2383,47 @@ void JSObject::LocalLookupRealNamedProperty(String* name,
}
if (HasFastProperties()) {
- LookupInDescriptor(name, result);
- if (result->IsFound()) {
- // A property, a map transition or a null descriptor was found.
- // We return all of these result types because
- // LocalLookupRealNamedProperty is used when setting properties
- // where map transitions and null descriptors are handled.
- ASSERT(result->holder() == this && result->type() != NORMAL);
- // Disallow caching for uninitialized constants. These can only
- // occur as fields.
- if (result->IsReadOnly() && result->type() == FIELD &&
- FastPropertyAt(result->GetFieldIndex())->IsTheHole()) {
- result->DisallowCaching();
- }
- return;
+ map()->LookupDescriptor(this, name, result);
+ // A property or a map transition was found. We return all of these result
+ // types because LocalLookupRealNamedProperty is used when setting
+ // properties where map transitions are handled.
+ ASSERT(!result->IsFound() ||
+ (result->holder() == this && result->IsFastPropertyType()));
+ // Disallow caching for uninitialized constants. These can only
+ // occur as fields.
+ if (result->IsField() &&
+ result->IsReadOnly() &&
+ FastPropertyAt(result->GetFieldIndex())->IsTheHole()) {
+ result->DisallowCaching();
}
- } else {
- int entry = property_dictionary()->FindEntry(name);
- if (entry != StringDictionary::kNotFound) {
- Object* value = property_dictionary()->ValueAt(entry);
- if (IsGlobalObject()) {
- PropertyDetails d = property_dictionary()->DetailsAt(entry);
- if (d.IsDeleted()) {
- result->NotFound();
- return;
- }
- value = JSGlobalPropertyCell::cast(value)->value();
+ return;
+ }
+
+ int entry = property_dictionary()->FindEntry(name);
+ if (entry != StringDictionary::kNotFound) {
+ Object* value = property_dictionary()->ValueAt(entry);
+ if (IsGlobalObject()) {
+ PropertyDetails d = property_dictionary()->DetailsAt(entry);
+ if (d.IsDeleted()) {
+ result->NotFound();
+ return;
}
- // Make sure to disallow caching for uninitialized constants
- // found in the dictionary-mode objects.
- if (value->IsTheHole()) result->DisallowCaching();
- result->DictionaryResult(this, entry);
- return;
+ value = JSGlobalPropertyCell::cast(value)->value();
}
+ // Make sure to disallow caching for uninitialized constants
+ // found in the dictionary-mode objects.
+ if (value->IsTheHole()) result->DisallowCaching();
+ result->DictionaryResult(this, entry);
+ return;
}
+
result->NotFound();
}
void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) {
LocalLookupRealNamedProperty(name, result);
- if (result->IsProperty()) return;
+ if (result->IsFound()) return;
LookupRealNamedPropertyInPrototypes(name, result);
}
@@ -2468,8 +2439,8 @@ void JSObject::LookupRealNamedPropertyInPrototypes(String* name,
return result->HandlerResult(JSProxy::cast(pt));
}
JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
- ASSERT(!(result->IsProperty() && result->type() == INTERCEPTOR));
- if (result->IsProperty()) return;
+ ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR));
+ if (result->IsFound()) return;
}
result->NotFound();
}
@@ -2538,7 +2509,7 @@ MaybeObject* JSReceiver::SetProperty(LookupResult* result,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
JSReceiver::StoreFromKeyed store_mode) {
- if (result->IsFound() && result->type() == HANDLER) {
+ if (result->IsHandler()) {
return result->proxy()->SetPropertyWithHandler(
this, key, value, attributes, strict_mode);
} else {
@@ -2676,7 +2647,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler(
String* name_raw, DeleteMode mode) {
Isolate* isolate = GetIsolate();
HandleScope scope(isolate);
- Handle<Object> receiver(this);
+ Handle<JSProxy> receiver(this);
Handle<Object> name(name_raw);
Handle<Object> args[] = { name };
@@ -2686,8 +2657,9 @@ MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler(
Object* bool_result = result->ToBoolean();
if (mode == STRICT_DELETION && bool_result == GetHeap()->false_value()) {
+ Handle<Object> handler(receiver->handler());
Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("delete");
- Handle<Object> args[] = { Handle<Object>(handler()), trap_name };
+ Handle<Object> args[] = { handler, trap_name };
Handle<Object> error = isolate->factory()->NewTypeError(
"handler_failed", HandleVector(args, ARRAY_SIZE(args)));
isolate->Throw(*error);
@@ -2790,7 +2762,7 @@ void JSProxy::Fix() {
Object* hash;
if (maybe_hash->To<Object>(&hash) && hash->IsSmi()) {
Handle<JSObject> new_self(JSObject::cast(*self));
- isolate->factory()->SetIdentityHash(new_self, hash);
+ isolate->factory()->SetIdentityHash(new_self, Smi::cast(hash));
}
}
@@ -2822,9 +2794,17 @@ MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name,
}
+void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object,
+ Handle<Map> map) {
+ CALL_HEAP_FUNCTION_VOID(
+ object->GetIsolate(),
+ object->AddFastPropertyUsingMap(*map));
+}
+
+
MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
- String* name,
- Object* value,
+ String* name_raw,
+ Object* value_raw,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
StoreFromKeyed store_mode) {
@@ -2836,114 +2816,127 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
// Optimization for 2-byte strings often used as keys in a decompression
// dictionary. We make these short keys into symbols to avoid constantly
// reallocating them.
- if (!name->IsSymbol() && name->length() <= 2) {
+ if (!name_raw->IsSymbol() && name_raw->length() <= 2) {
Object* symbol_version;
- { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name);
+ { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name_raw);
if (maybe_symbol_version->ToObject(&symbol_version)) {
- name = String::cast(symbol_version);
+ name_raw = String::cast(symbol_version);
}
}
}
// Check access rights if needed.
if (IsAccessCheckNeeded()) {
- if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) {
+ if (!heap->isolate()->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) {
return SetPropertyWithFailedAccessCheck(
- result, name, value, true, strict_mode);
+ result, name_raw, value_raw, true, strict_mode);
}
}
if (IsJSGlobalProxy()) {
Object* proto = GetPrototype();
- if (proto->IsNull()) return value;
+ if (proto->IsNull()) return value_raw;
ASSERT(proto->IsJSGlobalObject());
return JSObject::cast(proto)->SetPropertyForResult(
- result, name, value, attributes, strict_mode, store_mode);
+ result, name_raw, value_raw, attributes, strict_mode, store_mode);
}
- if (!result->IsProperty() && !IsJSContextExtensionObject()) {
+ // From this point on everything needs to be handlified, because
+ // SetPropertyViaPrototypes might call back into JavaScript.
+ HandleScope scope(GetIsolate());
+ Handle<JSObject> self(this);
+ Handle<String> name(name_raw);
+ Handle<Object> value(value_raw);
+
+ if (!result->IsProperty() && !self->IsJSContextExtensionObject()) {
bool done = false;
- MaybeObject* result_object =
- SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done);
+ MaybeObject* result_object = self->SetPropertyViaPrototypes(
+ *name, *value, attributes, strict_mode, &done);
if (done) return result_object;
}
if (!result->IsFound()) {
// Neither properties nor transitions found.
- return AddProperty(name, value, attributes, strict_mode, store_mode);
+ return self->AddProperty(
+ *name, *value, attributes, strict_mode, store_mode);
}
- if (result->IsReadOnly() && result->IsProperty()) {
+ if (result->IsProperty() && result->IsReadOnly()) {
if (strict_mode == kStrictMode) {
- Handle<JSObject> self(this);
- Handle<String> hname(name);
- Handle<Object> args[] = { hname, self };
+ Handle<Object> args[] = { name, self };
return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError(
"strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
} else {
- return value;
+ return *value;
}
}
+
// This is a real property that is not read-only, or it is a
// transition or null descriptor and there are no setters in the prototypes.
switch (result->type()) {
case NORMAL:
- return SetNormalizedProperty(result, value);
+ return self->SetNormalizedProperty(result, *value);
case FIELD:
- return FastPropertyAtPut(result->GetFieldIndex(), value);
- case MAP_TRANSITION:
- if (attributes == result->GetAttributes()) {
- // Only use map transition if the attributes match.
- return AddFastPropertyUsingMap(result->GetTransitionMap(),
- name,
- value);
- }
- return ConvertDescriptorToField(name, value, attributes);
+ return self->FastPropertyAtPut(result->GetFieldIndex(), *value);
case CONSTANT_FUNCTION:
// Only replace the function if necessary.
- if (value == result->GetConstantFunction()) return value;
+ if (*value == result->GetConstantFunction()) return *value;
// Preserve the attributes of this existing property.
attributes = result->GetAttributes();
- return ConvertDescriptorToField(name, value, attributes);
+ return self->ConvertDescriptorToField(*name, *value, attributes);
case CALLBACKS: {
Object* callback_object = result->GetCallbackObject();
- if (callback_object->IsAccessorPair() &&
- !AccessorPair::cast(callback_object)->ContainsAccessor()) {
- return ConvertDescriptorToField(name, value, attributes);
- }
- return SetPropertyWithCallback(callback_object,
- name,
- value,
- result->holder(),
- strict_mode);
+ return self->SetPropertyWithCallback(callback_object,
+ *name,
+ *value,
+ result->holder(),
+ strict_mode);
}
case INTERCEPTOR:
- return SetPropertyWithInterceptor(name, value, attributes, strict_mode);
- case CONSTANT_TRANSITION: {
+ return self->SetPropertyWithInterceptor(*name,
+ *value,
+ attributes,
+ strict_mode);
+ case TRANSITION: {
+ Map* transition_map = result->GetTransitionTarget();
+ int descriptor = transition_map->LastAdded();
+
+ DescriptorArray* descriptors = transition_map->instance_descriptors();
+ PropertyDetails details = descriptors->GetDetails(descriptor);
+
+ if (details.type() == FIELD) {
+ if (attributes == details.attributes()) {
+ int field_index = descriptors->GetFieldIndex(descriptor);
+ return self->AddFastPropertyUsingMap(transition_map,
+ *name,
+ *value,
+ field_index);
+ }
+ return self->ConvertDescriptorToField(*name, *value, attributes);
+ } else if (details.type() == CALLBACKS) {
+ return ConvertDescriptorToField(*name, *value, attributes);
+ }
+
+ ASSERT(details.type() == CONSTANT_FUNCTION);
+
+ Object* constant_function = descriptors->GetValue(descriptor);
// If the same constant function is being added we can simply
// transition to the target map.
- Map* target_map = result->GetTransitionMap();
- DescriptorArray* target_descriptors = target_map->instance_descriptors();
- int number = target_descriptors->SearchWithCache(name);
- ASSERT(number != DescriptorArray::kNotFound);
- ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION);
- JSFunction* function =
- JSFunction::cast(target_descriptors->GetValue(number));
- if (value == function) {
- set_map(target_map);
- return value;
+ if (constant_function == *value) {
+ self->set_map(transition_map);
+ return constant_function;
}
- // Otherwise, replace with a MAP_TRANSITION to a new map with a
- // FIELD, even if the value is a constant function.
- return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
+ // Otherwise, replace with a map transition to a new map with a FIELD,
+ // even if the value is a constant function.
+ return ConvertTransitionToMapTransition(
+ result->GetTransitionIndex(), *name, *value, attributes);
}
- case NULL_DESCRIPTOR:
- return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
case HANDLER:
+ case NONEXISTENT:
UNREACHABLE();
- return value;
+ return *value;
}
UNREACHABLE(); // keep the compiler happy
- return value;
+ return *value;
}
@@ -2978,6 +2971,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
Isolate* isolate = GetIsolate();
LookupResult result(isolate);
LocalLookup(name, &result);
+ if (!result.IsFound()) map()->LookupTransition(this, name, &result);
// Check access rights if needed.
if (IsAccessCheckNeeded()) {
if (!isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
@@ -3005,22 +2999,14 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
return AddProperty(name, value, attributes, kNonStrictMode);
}
- PropertyDetails details = PropertyDetails(attributes, NORMAL);
-
// Check of IsReadOnly removed from here in clone.
switch (result.type()) {
- case NORMAL:
+ case NORMAL: {
+ PropertyDetails details = PropertyDetails(attributes, NORMAL);
return SetNormalizedProperty(name, value, details);
+ }
case FIELD:
return FastPropertyAtPut(result.GetFieldIndex(), value);
- case MAP_TRANSITION:
- if (attributes == result.GetAttributes()) {
- // Only use map transition if the attributes match.
- return AddFastPropertyUsingMap(result.GetTransitionMap(),
- name,
- value);
- }
- return ConvertDescriptorToField(name, value, attributes);
case CONSTANT_FUNCTION:
// Only replace the function if necessary.
if (value == result.GetConstantFunction()) return value;
@@ -3031,12 +3017,35 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
case INTERCEPTOR:
// Override callback in clone
return ConvertDescriptorToField(name, value, attributes);
- case CONSTANT_TRANSITION:
- // Replace with a MAP_TRANSITION to a new map with a FIELD, even
- // if the value is a function.
- case NULL_DESCRIPTOR:
- return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
+ case TRANSITION: {
+ Map* transition_map = result.GetTransitionTarget();
+ int descriptor = transition_map->LastAdded();
+
+ DescriptorArray* descriptors = transition_map->instance_descriptors();
+ PropertyDetails details = descriptors->GetDetails(descriptor);
+
+ if (details.type() == FIELD) {
+ if (attributes == details.attributes()) {
+ int field_index = descriptors->GetFieldIndex(descriptor);
+ return AddFastPropertyUsingMap(transition_map,
+ name,
+ value,
+ field_index);
+ }
+ return ConvertDescriptorToField(name, value, attributes);
+ } else if (details.type() == CALLBACKS) {
+ return ConvertDescriptorToField(name, value, attributes);
+ }
+
+ ASSERT(details.type() == CONSTANT_FUNCTION);
+
+ // Replace transition to CONSTANT FUNCTION with a map transition to a new
+ // map with a FIELD, even if the value is a function.
+ return ConvertTransitionToMapTransition(
+ result.GetTransitionIndex(), name, value, attributes);
+ }
case HANDLER:
+ case NONEXISTENT:
UNREACHABLE();
}
UNREACHABLE(); // keep the compiler happy
@@ -3051,7 +3060,7 @@ PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
// Check local property, ignore interceptor.
LookupResult result(GetIsolate());
LocalLookupRealNamedProperty(name, &result);
- if (result.IsProperty()) return result.GetAttributes();
+ if (result.IsFound()) return result.GetAttributes();
if (continue_search) {
// Continue searching via the prototype chain.
@@ -3144,7 +3153,7 @@ PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver,
receiver, result, name, continue_search);
}
}
- if (result->IsProperty()) {
+ if (result->IsFound()) {
switch (result->type()) {
case NORMAL: // fall through
case FIELD:
@@ -3158,7 +3167,8 @@ PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver,
case INTERCEPTOR:
return result->holder()->GetPropertyAttributeWithInterceptor(
JSObject::cast(receiver), name, continue_search);
- default:
+ case TRANSITION:
+ case NONEXISTENT:
UNREACHABLE();
}
}
@@ -3188,26 +3198,27 @@ MaybeObject* NormalizedMapCache::Get(JSObject* obj,
Object* result = get(index);
if (result->IsMap() &&
Map::cast(result)->EquivalentToForNormalization(fast, mode)) {
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
Map::cast(result)->SharedMapVerify();
}
+#endif
+#ifdef DEBUG
if (FLAG_enable_slow_asserts) {
// The cached map should match newly created normalized map bit-by-bit,
// except for the code cache, which can contain some ics which can be
// applied to the shared map.
Object* fresh;
- { MaybeObject* maybe_fresh =
- fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
- if (maybe_fresh->ToObject(&fresh)) {
- ASSERT(memcmp(Map::cast(fresh)->address(),
- Map::cast(result)->address(),
- Map::kCodeCacheOffset) == 0);
- int offset = Map::kCodeCacheOffset + kPointerSize;
- ASSERT(memcmp(Map::cast(fresh)->address() + offset,
- Map::cast(result)->address() + offset,
- Map::kSize - offset) == 0);
- }
+ MaybeObject* maybe_fresh =
+ fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
+ if (maybe_fresh->ToObject(&fresh)) {
+ ASSERT(memcmp(Map::cast(fresh)->address(),
+ Map::cast(result)->address(),
+ Map::kCodeCacheOffset) == 0);
+ int offset = Map::kCodeCacheOffset + kPointerSize;
+ ASSERT(memcmp(Map::cast(fresh)->address() + offset,
+ Map::cast(result)->address() + offset,
+ Map::kSize - offset) == 0);
}
}
#endif
@@ -3218,6 +3229,7 @@ MaybeObject* NormalizedMapCache::Get(JSObject* obj,
fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
+ ASSERT(Map::cast(result)->is_dictionary_map());
set(index, result);
isolate->counters()->normalized_maps()->Increment();
@@ -3281,24 +3293,25 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
Map* map_of_this = map();
// Allocate new content.
- int property_count = map_of_this->NumberOfDescribedProperties();
+ int real_size = map_of_this->NumberOfOwnDescriptors();
+ int property_count = real_size;
if (expected_additional_properties > 0) {
property_count += expected_additional_properties;
} else {
property_count += 2; // Make space for two more properties.
}
StringDictionary* dictionary;
- { MaybeObject* maybe_dictionary = StringDictionary::Allocate(property_count);
- if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
- }
+ MaybeObject* maybe_dictionary = StringDictionary::Allocate(property_count);
+ if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
DescriptorArray* descs = map_of_this->instance_descriptors();
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ for (int i = 0; i < real_size; i++) {
PropertyDetails details = descs->GetDetails(i);
switch (details.type()) {
case CONSTANT_FUNCTION: {
- PropertyDetails d =
- PropertyDetails(details.attributes(), NORMAL, details.index());
+ PropertyDetails d = PropertyDetails(details.attributes(),
+ NORMAL,
+ details.descriptor_index());
Object* value = descs->GetConstantFunction(i);
MaybeObject* maybe_dictionary =
dictionary->Add(descs->GetKey(i), value, d);
@@ -3306,8 +3319,9 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
break;
}
case FIELD: {
- PropertyDetails d =
- PropertyDetails(details.attributes(), NORMAL, details.index());
+ PropertyDetails d = PropertyDetails(details.attributes(),
+ NORMAL,
+ details.descriptor_index());
Object* value = FastPropertyAt(descs->GetFieldIndex(i));
MaybeObject* maybe_dictionary =
dictionary->Add(descs->GetKey(i), value, d);
@@ -3315,25 +3329,19 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
break;
}
case CALLBACKS: {
- if (!descs->IsProperty(i)) break;
Object* value = descs->GetCallbacksObject(i);
- if (value->IsAccessorPair()) {
- MaybeObject* maybe_copy =
- AccessorPair::cast(value)->CopyWithoutTransitions();
- if (!maybe_copy->To(&value)) return maybe_copy;
- }
+ details = details.set_pointer(0);
MaybeObject* maybe_dictionary =
dictionary->Add(descs->GetKey(i), value, details);
if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
break;
}
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
case INTERCEPTOR:
break;
case HANDLER:
case NORMAL:
+ case TRANSITION:
+ case NONEXISTENT:
UNREACHABLE();
break;
}
@@ -3342,15 +3350,14 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
Heap* current_heap = GetHeap();
// Copy the next enumeration index from instance descriptor.
- int index = map_of_this->instance_descriptors()->NextEnumerationIndex();
- dictionary->SetNextEnumerationIndex(index);
+ dictionary->SetNextEnumerationIndex(real_size + 1);
Map* new_map;
- { MaybeObject* maybe_map =
- current_heap->isolate()->context()->global_context()->
- normalized_map_cache()->Get(this, mode);
- if (!maybe_map->To(&new_map)) return maybe_map;
- }
+ MaybeObject* maybe_map =
+ current_heap->isolate()->context()->native_context()->
+ normalized_map_cache()->Get(this, mode);
+ if (!maybe_map->To(&new_map)) return maybe_map;
+ ASSERT(new_map->is_dictionary_map());
// We have now successfully allocated all the necessary objects.
// Changes can now be made with the guarantee that all of them take effect.
@@ -3366,9 +3373,7 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
-instance_size_delta);
}
-
set_map(new_map);
- new_map->clear_instance_descriptors();
set_properties(dictionary);
@@ -3515,7 +3520,7 @@ Smi* JSReceiver::GenerateIdentityHash() {
}
-MaybeObject* JSObject::SetIdentityHash(Object* hash, CreationFlag flag) {
+MaybeObject* JSObject::SetIdentityHash(Smi* hash, CreationFlag flag) {
MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_symbol(),
hash);
if (maybe->IsFailure()) return maybe;
@@ -3561,6 +3566,7 @@ MaybeObject* JSProxy::GetIdentityHash(CreationFlag flag) {
Object* JSObject::GetHiddenProperty(String* key) {
+ ASSERT(key->IsSymbol());
if (IsJSGlobalProxy()) {
// For a proxy, use the prototype as target object.
Object* proxy_parent = GetPrototype();
@@ -3570,22 +3576,31 @@ Object* JSObject::GetHiddenProperty(String* key) {
return JSObject::cast(proxy_parent)->GetHiddenProperty(key);
}
ASSERT(!IsJSGlobalProxy());
- MaybeObject* hidden_lookup = GetHiddenPropertiesDictionary(false);
- ASSERT(!hidden_lookup->IsFailure()); // No failure when passing false as arg.
- if (hidden_lookup->ToObjectUnchecked()->IsUndefined()) {
- return GetHeap()->undefined_value();
+ MaybeObject* hidden_lookup =
+ GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE);
+ Object* inline_value = hidden_lookup->ToObjectUnchecked();
+
+ if (inline_value->IsSmi()) {
+ // Handle inline-stored identity hash.
+ if (key == GetHeap()->identity_hash_symbol()) {
+ return inline_value;
+ } else {
+ return GetHeap()->undefined_value();
+ }
}
- StringDictionary* dictionary =
- StringDictionary::cast(hidden_lookup->ToObjectUnchecked());
- int entry = dictionary->FindEntry(key);
- if (entry == StringDictionary::kNotFound) return GetHeap()->undefined_value();
- return dictionary->ValueAt(entry);
+
+ if (inline_value->IsUndefined()) return GetHeap()->undefined_value();
+
+ ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value);
+ Object* entry = hashtable->Lookup(key);
+ if (entry->IsTheHole()) return GetHeap()->undefined_value();
+ return entry;
}
Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj,
- Handle<String> key,
- Handle<Object> value) {
+ Handle<String> key,
+ Handle<Object> value) {
CALL_HEAP_FUNCTION(obj->GetIsolate(),
obj->SetHiddenProperty(*key, *value),
Object);
@@ -3593,6 +3608,7 @@ Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj,
MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) {
+ ASSERT(key->IsSymbol());
if (IsJSGlobalProxy()) {
// For a proxy, use the prototype as target object.
Object* proxy_parent = GetPrototype();
@@ -3602,27 +3618,29 @@ MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) {
return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value);
}
ASSERT(!IsJSGlobalProxy());
- MaybeObject* hidden_lookup = GetHiddenPropertiesDictionary(true);
- StringDictionary* dictionary;
- if (!hidden_lookup->To<StringDictionary>(&dictionary)) return hidden_lookup;
+ MaybeObject* hidden_lookup =
+ GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE);
+ Object* inline_value = hidden_lookup->ToObjectUnchecked();
- // If it was found, check if the key is already in the dictionary.
- int entry = dictionary->FindEntry(key);
- if (entry != StringDictionary::kNotFound) {
- // If key was found, just update the value.
- dictionary->ValueAtPut(entry, value);
- return this;
+ // If there is no backing store yet, store the identity hash inline.
+ if (value->IsSmi() &&
+ key == GetHeap()->identity_hash_symbol() &&
+ (inline_value->IsUndefined() || inline_value->IsSmi())) {
+ return SetHiddenPropertiesHashTable(value);
}
- // Key was not already in the dictionary, so add the entry.
- MaybeObject* insert_result = dictionary->Add(key,
- value,
- PropertyDetails(NONE, NORMAL));
- StringDictionary* new_dict;
- if (!insert_result->To<StringDictionary>(&new_dict)) return insert_result;
- if (new_dict != dictionary) {
+
+ hidden_lookup = GetHiddenPropertiesHashTable(CREATE_NEW_IF_ABSENT);
+ ObjectHashTable* hashtable;
+ if (!hidden_lookup->To(&hashtable)) return hidden_lookup;
+
+ // If it was found, check if the key is already in the dictionary.
+ MaybeObject* insert_result = hashtable->Put(key, value);
+ ObjectHashTable* new_table;
+ if (!insert_result->To(&new_table)) return insert_result;
+ if (new_table != hashtable) {
// If adding the key expanded the dictionary (i.e., Add returned a new
// dictionary), store it back to the object.
- MaybeObject* store_result = SetHiddenPropertiesDictionary(new_dict);
+ MaybeObject* store_result = SetHiddenPropertiesHashTable(new_table);
if (store_result->IsFailure()) return store_result;
}
// Return this to mark success.
@@ -3631,6 +3649,7 @@ MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) {
void JSObject::DeleteHiddenProperty(String* key) {
+ ASSERT(key->IsSymbol());
if (IsJSGlobalProxy()) {
// For a proxy, use the prototype as target object.
Object* proxy_parent = GetPrototype();
@@ -3640,18 +3659,19 @@ void JSObject::DeleteHiddenProperty(String* key) {
JSObject::cast(proxy_parent)->DeleteHiddenProperty(key);
return;
}
- MaybeObject* hidden_lookup = GetHiddenPropertiesDictionary(false);
- ASSERT(!hidden_lookup->IsFailure()); // No failure when passing false as arg.
- if (hidden_lookup->ToObjectUnchecked()->IsUndefined()) return;
- StringDictionary* dictionary =
- StringDictionary::cast(hidden_lookup->ToObjectUnchecked());
- int entry = dictionary->FindEntry(key);
- if (entry == StringDictionary::kNotFound) {
- // Key wasn't in dictionary. Deletion is a success.
- return;
- }
- // Key was in the dictionary. Remove it.
- dictionary->DeleteProperty(entry, JSReceiver::FORCE_DELETION);
+ ASSERT(!IsJSGlobalProxy());
+ MaybeObject* hidden_lookup =
+ GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE);
+ Object* inline_value = hidden_lookup->ToObjectUnchecked();
+
+ // We never delete (inline-stored) identity hashes.
+ ASSERT(key != GetHeap()->identity_hash_symbol());
+ if (inline_value->IsUndefined() || inline_value->IsSmi()) return;
+
+ ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value);
+ MaybeObject* delete_result = hashtable->Put(key, GetHeap()->the_hole_value());
+ USE(delete_result);
+ ASSERT(!delete_result->IsFailure()); // Delete does not cause GC.
}
@@ -3662,78 +3682,99 @@ bool JSObject::HasHiddenProperties() {
}
-MaybeObject* JSObject::GetHiddenPropertiesDictionary(bool create_if_absent) {
+MaybeObject* JSObject::GetHiddenPropertiesHashTable(
+ InitializeHiddenProperties init_option) {
ASSERT(!IsJSGlobalProxy());
+ Object* inline_value;
if (HasFastProperties()) {
// If the object has fast properties, check whether the first slot
// in the descriptor array matches the hidden symbol. Since the
// hidden symbols hash code is zero (and no other string has hash
// code zero) it will always occupy the first entry if present.
DescriptorArray* descriptors = this->map()->instance_descriptors();
- if ((descriptors->number_of_descriptors() > 0) &&
- (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) {
- if (descriptors->GetType(0) == FIELD) {
- Object* hidden_store =
- this->FastPropertyAt(descriptors->GetFieldIndex(0));
- return StringDictionary::cast(hidden_store);
+ if (descriptors->number_of_descriptors() > 0) {
+ int sorted_index = descriptors->GetSortedKeyIndex(0);
+ if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_symbol() &&
+ sorted_index < map()->NumberOfOwnDescriptors()) {
+ ASSERT(descriptors->GetType(sorted_index) == FIELD);
+ inline_value =
+ this->FastPropertyAt(descriptors->GetFieldIndex(sorted_index));
} else {
- ASSERT(descriptors->GetType(0) == NULL_DESCRIPTOR ||
- descriptors->GetType(0) == MAP_TRANSITION);
+ inline_value = GetHeap()->undefined_value();
}
+ } else {
+ inline_value = GetHeap()->undefined_value();
}
} else {
PropertyAttributes attributes;
// You can't install a getter on a property indexed by the hidden symbol,
// so we can be sure that GetLocalPropertyPostInterceptor returns a real
// object.
- Object* lookup =
+ inline_value =
GetLocalPropertyPostInterceptor(this,
GetHeap()->hidden_symbol(),
&attributes)->ToObjectUnchecked();
- if (!lookup->IsUndefined()) {
- return StringDictionary::cast(lookup);
- }
}
- if (!create_if_absent) return GetHeap()->undefined_value();
- const int kInitialSize = 5;
- MaybeObject* dict_alloc = StringDictionary::Allocate(kInitialSize);
- StringDictionary* dictionary;
- if (!dict_alloc->To<StringDictionary>(&dictionary)) return dict_alloc;
+
+ if (init_option == ONLY_RETURN_INLINE_VALUE ||
+ inline_value->IsHashTable()) {
+ return inline_value;
+ }
+
+ ObjectHashTable* hashtable;
+ static const int kInitialCapacity = 4;
+ MaybeObject* maybe_obj =
+ ObjectHashTable::Allocate(kInitialCapacity,
+ ObjectHashTable::USE_CUSTOM_MINIMUM_CAPACITY);
+ if (!maybe_obj->To<ObjectHashTable>(&hashtable)) return maybe_obj;
+
+ if (inline_value->IsSmi()) {
+ // We were storing the identity hash inline and now allocated an actual
+ // dictionary. Put the identity hash into the new dictionary.
+ MaybeObject* insert_result =
+ hashtable->Put(GetHeap()->identity_hash_symbol(), inline_value);
+ ObjectHashTable* new_table;
+ if (!insert_result->To(&new_table)) return insert_result;
+ // We expect no resizing for the first insert.
+ ASSERT_EQ(hashtable, new_table);
+ }
+
MaybeObject* store_result =
SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
- dictionary,
+ hashtable,
DONT_ENUM,
kNonStrictMode,
OMIT_EXTENSIBILITY_CHECK);
if (store_result->IsFailure()) return store_result;
- return dictionary;
+ return hashtable;
}
-MaybeObject* JSObject::SetHiddenPropertiesDictionary(
- StringDictionary* dictionary) {
+MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) {
ASSERT(!IsJSGlobalProxy());
- ASSERT(HasHiddenProperties());
+ // We can store the identity hash inline iff there is no backing store
+ // for hidden properties yet.
+ ASSERT(HasHiddenProperties() != value->IsSmi());
if (HasFastProperties()) {
// If the object has fast properties, check whether the first slot
// in the descriptor array matches the hidden symbol. Since the
// hidden symbols hash code is zero (and no other string has hash
// code zero) it will always occupy the first entry if present.
DescriptorArray* descriptors = this->map()->instance_descriptors();
- if ((descriptors->number_of_descriptors() > 0) &&
- (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) {
- if (descriptors->GetType(0) == FIELD) {
- this->FastPropertyAtPut(descriptors->GetFieldIndex(0), dictionary);
+ if (descriptors->number_of_descriptors() > 0) {
+ int sorted_index = descriptors->GetSortedKeyIndex(0);
+ if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_symbol() &&
+ sorted_index < map()->NumberOfOwnDescriptors()) {
+ ASSERT(descriptors->GetType(sorted_index) == FIELD);
+ this->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index),
+ value);
return this;
- } else {
- ASSERT(descriptors->GetType(0) == NULL_DESCRIPTOR ||
- descriptors->GetType(0) == MAP_TRANSITION);
}
}
}
MaybeObject* store_result =
SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
- dictionary,
+ value,
DONT_ENUM,
kNonStrictMode,
OMIT_EXTENSIBILITY_CHECK);
@@ -3747,7 +3788,7 @@ MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
// Check local property, ignore interceptor.
LookupResult result(GetIsolate());
LocalLookupRealNamedProperty(name, &result);
- if (!result.IsProperty()) return GetHeap()->true_value();
+ if (!result.IsFound()) return GetHeap()->true_value();
// Normalize object if needed.
Object* obj;
@@ -3781,7 +3822,9 @@ MaybeObject* JSObject::DeletePropertyWithInterceptor(String* name) {
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!result.IsEmpty()) {
ASSERT(result->IsBoolean());
- return *v8::Utils::OpenHandle(*result);
+ Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
+ result_internal->VerifyApiCallResultType();
+ return *result_internal;
}
}
MaybeObject* raw_result =
@@ -3816,7 +3859,9 @@ MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) {
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!result.IsEmpty()) {
ASSERT(result->IsBoolean());
- return *v8::Utils::OpenHandle(*result);
+ Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
+ result_internal->VerifyApiCallResultType();
+ return *result_internal;
}
MaybeObject* raw_result = this_handle->GetElementsAccessor()->Delete(
*this_handle,
@@ -3844,6 +3889,21 @@ MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
return isolate->heap()->false_value();
}
+ if (IsStringObjectWithCharacterAt(index)) {
+ if (mode == STRICT_DELETION) {
+ // Deleting a non-configurable property in strict mode.
+ HandleScope scope(isolate);
+ Handle<Object> holder(this);
+ Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
+ Handle<Object> args[2] = { name, holder };
+ Handle<Object> error =
+ isolate->factory()->NewTypeError("strict_delete_property",
+ HandleVector(args, 2));
+ return isolate->Throw(*error);
+ }
+ return isolate->heap()->false_value();
+ }
+
if (IsJSGlobalProxy()) {
Object* proto = GetPrototype();
if (proto->IsNull()) return isolate->heap()->false_value();
@@ -3896,7 +3956,7 @@ MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
} else {
LookupResult result(isolate);
LocalLookup(name, &result);
- if (!result.IsProperty()) return isolate->heap()->true_value();
+ if (!result.IsFound()) return isolate->heap()->true_value();
// Ignore attributes if forcing a deletion.
if (result.IsDontDelete() && mode != FORCE_DELETION) {
if (mode == STRICT_DELETION) {
@@ -3909,7 +3969,7 @@ MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
return isolate->heap()->false_value();
}
// Check for interceptor.
- if (result.type() == INTERCEPTOR) {
+ if (result.IsInterceptor()) {
// Skip interceptor if forcing a deletion.
if (mode == FORCE_DELETION) {
return DeletePropertyPostInterceptor(name, mode);
@@ -4036,15 +4096,15 @@ bool JSObject::ReferencesObject(Object* obj) {
if (IsJSFunction()) {
// Get the constructor function for arguments array.
JSObject* arguments_boilerplate =
- heap->isolate()->context()->global_context()->
+ heap->isolate()->context()->native_context()->
arguments_boilerplate();
JSFunction* arguments_function =
JSFunction::cast(arguments_boilerplate->map()->constructor());
- // Get the context and don't check if it is the global context.
+ // Get the context and don't check if it is the native context.
JSFunction* f = JSFunction::cast(this);
Context* context = f->context();
- if (context->IsGlobalContext()) {
+ if (context->IsNativeContext()) {
return false;
}
@@ -4120,10 +4180,9 @@ MaybeObject* JSObject::PreventExtensions() {
// Do a map transition, other objects with this map may still
// be extensible.
Map* new_map;
- { MaybeObject* maybe =
- map()->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
- if (!maybe->To<Map>(&new_map)) return maybe;
- }
+ MaybeObject* maybe = map()->Copy();
+ if (!maybe->To(&new_map)) return maybe;
+
new_map->set_is_extensible(false);
set_map(new_map);
ASSERT(!map()->is_extensible());
@@ -4143,29 +4202,27 @@ bool JSReceiver::IsSimpleEnum() {
o = JSObject::cast(o)->GetPrototype()) {
if (!o->IsJSObject()) return false;
JSObject* curr = JSObject::cast(o);
- if (!curr->map()->instance_descriptors()->HasEnumCache()) return false;
+ int enum_length = curr->map()->EnumLength();
+ if (enum_length == Map::kInvalidEnumCache) return false;
ASSERT(!curr->HasNamedInterceptor());
ASSERT(!curr->HasIndexedInterceptor());
ASSERT(!curr->IsAccessCheckNeeded());
if (curr->NumberOfEnumElements() > 0) return false;
- if (curr != this) {
- FixedArray* curr_fixed_array =
- FixedArray::cast(curr->map()->instance_descriptors()->GetEnumCache());
- if (curr_fixed_array->length() > 0) return false;
- }
+ if (curr != this && enum_length != 0) return false;
}
return true;
}
-int Map::NumberOfDescribedProperties(PropertyAttributes filter) {
+int Map::NumberOfDescribedProperties(DescriptorFlag which,
+ PropertyAttributes filter) {
int result = 0;
DescriptorArray* descs = instance_descriptors();
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
- PropertyDetails details = descs->GetDetails(i);
- if (descs->IsProperty(i) && (details.attributes() & filter) == 0) {
- result++;
- }
+ int limit = which == ALL_DESCRIPTORS
+ ? descs->number_of_descriptors()
+ : NumberOfOwnDescriptors();
+ for (int i = 0; i < limit; i++) {
+ if ((descs->GetDetails(i).attributes() & filter) == 0) result++;
}
return result;
}
@@ -4173,10 +4230,9 @@ int Map::NumberOfDescribedProperties(PropertyAttributes filter) {
int Map::PropertyIndexFor(String* name) {
DescriptorArray* descs = instance_descriptors();
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
- if (name->Equals(descs->GetKey(i)) && !descs->IsNullDescriptor(i)) {
- return descs->GetFieldIndex(i);
- }
+ int limit = NumberOfOwnDescriptors();
+ for (int i = 0; i < limit; i++) {
+ if (name->Equals(descs->GetKey(i))) return descs->GetFieldIndex(i);
}
return -1;
}
@@ -4184,8 +4240,9 @@ int Map::PropertyIndexFor(String* name) {
int Map::NextFreePropertyIndex() {
int max_index = -1;
+ int number_of_own_descriptors = NumberOfOwnDescriptors();
DescriptorArray* descs = instance_descriptors();
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ for (int i = 0; i < number_of_own_descriptors; i++) {
if (descs->GetType(i) == FIELD) {
int current_index = descs->GetFieldIndex(i);
if (current_index > max_index) max_index = current_index;
@@ -4197,8 +4254,9 @@ int Map::NextFreePropertyIndex() {
AccessorDescriptor* Map::FindAccessor(String* name) {
DescriptorArray* descs = instance_descriptors();
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
- if (name->Equals(descs->GetKey(i)) && descs->GetType(i) == CALLBACKS) {
+ int number_of_own_descriptors = NumberOfOwnDescriptors();
+ for (int i = 0; i < number_of_own_descriptors; i++) {
+ if (descs->GetType(i) == CALLBACKS && name->Equals(descs->GetKey(i))) {
return descs->GetCallbacks(i);
}
}
@@ -4255,20 +4313,20 @@ void JSReceiver::Lookup(String* name, LookupResult* result) {
current != heap->null_value();
current = JSObject::cast(current)->GetPrototype()) {
JSReceiver::cast(current)->LocalLookup(name, result);
- if (result->IsProperty()) return;
+ if (result->IsFound()) return;
}
result->NotFound();
}
// Search object and its prototype chain for callback properties.
-void JSObject::LookupCallback(String* name, LookupResult* result) {
+void JSObject::LookupCallbackProperty(String* name, LookupResult* result) {
Heap* heap = GetHeap();
for (Object* current = this;
current != heap->null_value() && current->IsJSObject();
current = JSObject::cast(current)->GetPrototype()) {
JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
- if (result->IsFound() && result->type() == CALLBACKS) return;
+ if (result->IsPropertyCallbacks()) return;
}
result->NotFound();
}
@@ -4371,7 +4429,7 @@ MaybeObject* JSObject::DefineElementAccessor(uint32_t index,
MaybeObject* JSObject::CreateAccessorPairFor(String* name) {
LookupResult result(GetHeap()->isolate());
LocalLookupRealNamedProperty(name, &result);
- if (result.IsProperty() && result.type() == CALLBACKS) {
+ if (result.IsPropertyCallbacks()) {
// Note that the result can actually have IsDontDelete() == true when we
// e.g. have to fall back to the slow case while adding a setter after
// successfully reusing a map transition for a getter. Nevertheless, this is
@@ -4380,7 +4438,7 @@ MaybeObject* JSObject::CreateAccessorPairFor(String* name) {
// DefinePropertyAccessor below.
Object* obj = result.GetCallbackObject();
if (obj->IsAccessorPair()) {
- return AccessorPair::cast(obj)->CopyWithoutTransitions();
+ return AccessorPair::cast(obj)->Copy();
}
}
return GetHeap()->AllocateAccessorPair();
@@ -4414,9 +4472,9 @@ MaybeObject* JSObject::DefinePropertyAccessor(String* name,
}
AccessorPair* accessors;
- { MaybeObject* maybe_accessors = CreateAccessorPairFor(name);
- if (!maybe_accessors->To(&accessors)) return maybe_accessors;
- }
+ MaybeObject* maybe_accessors = CreateAccessorPairFor(name);
+ if (!maybe_accessors->To(&accessors)) return maybe_accessors;
+
accessors->SetComponents(getter, setter);
return SetPropertyCallback(name, accessors, attributes);
}
@@ -4433,8 +4491,8 @@ bool JSObject::CanSetCallback(String* name) {
// to be overwritten because allowing overwriting could potentially
// cause security problems.
LookupResult callback_result(GetIsolate());
- LookupCallback(name, &callback_result);
- if (callback_result.IsProperty()) {
+ LookupCallbackProperty(name, &callback_result);
+ if (callback_result.IsFound()) {
Object* obj = callback_result.GetCallbackObject();
if (obj->IsAccessorInfo() &&
AccessorInfo::cast(obj)->prohibits_overwriting()) {
@@ -4488,17 +4546,17 @@ MaybeObject* JSObject::SetPropertyCallback(String* name,
Object* structure,
PropertyAttributes attributes) {
// Normalize object to make this operation simple.
- { MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
- if (maybe_ok->IsFailure()) return maybe_ok;
- }
+ MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
+ if (maybe_ok->IsFailure()) return maybe_ok;
// For the global object allocate a new map to invalidate the global inline
// caches which have a global property cell reference directly in the code.
if (IsGlobalObject()) {
Map* new_map;
- { MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- }
+ MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+ ASSERT(new_map->is_dictionary_map());
+
set_map(new_map);
// When running crankshaft, changing the map is not enough. We
// need to deoptimize all functions that rely on this global
@@ -4508,9 +4566,8 @@ MaybeObject* JSObject::SetPropertyCallback(String* name,
// Update the dictionary with the new CALLBACKS property.
PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
- { MaybeObject* maybe_ok = SetNormalizedProperty(name, structure, details);
- if (maybe_ok->IsFailure()) return maybe_ok;
- }
+ maybe_ok = SetNormalizedProperty(name, structure, details);
+ if (maybe_ok->IsFailure()) return maybe_ok;
return GetHeap()->undefined_value();
}
@@ -4562,111 +4619,32 @@ MaybeObject* JSObject::DefineAccessor(String* name,
}
-static MaybeObject* CreateFreshAccessor(JSObject* obj,
- String* name,
- AccessorComponent component,
- Object* accessor,
- PropertyAttributes attributes) {
- // step 1: create a new getter/setter pair with only the accessor in it
- Heap* heap = obj->GetHeap();
- AccessorPair* accessors2;
- { MaybeObject* maybe_accessors2 = heap->AllocateAccessorPair();
- if (!maybe_accessors2->To(&accessors2)) return maybe_accessors2;
- }
- accessors2->set(component, accessor);
-
- // step 2: create a copy of the descriptors, incl. the new getter/setter pair
- Map* map1 = obj->map();
- CallbacksDescriptor callbacks_descr2(name, accessors2, attributes);
- DescriptorArray* descriptors2;
- { MaybeObject* maybe_descriptors2 =
- map1->instance_descriptors()->CopyInsert(&callbacks_descr2,
- REMOVE_TRANSITIONS);
- if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2;
- }
+static MaybeObject* TryAccessorTransition(JSObject* self,
+ Map* transitioned_map,
+ int target_descriptor,
+ AccessorComponent component,
+ Object* accessor,
+ PropertyAttributes attributes) {
+ DescriptorArray* descs = transitioned_map->instance_descriptors();
+ PropertyDetails details = descs->GetDetails(target_descriptor);
- // step 3: create a new map with the new descriptors
- Map* map2;
- { MaybeObject* maybe_map2 = map1->CopyDropDescriptors();
- if (!maybe_map2->To(&map2)) return maybe_map2;
- }
- map2->set_instance_descriptors(descriptors2);
+ // If the transition target was not callbacks, fall back to the slow case.
+ if (details.type() != CALLBACKS) return self->GetHeap()->null_value();
+ Object* descriptor = descs->GetCallbacksObject(target_descriptor);
+ if (!descriptor->IsAccessorPair()) return self->GetHeap()->null_value();
- // step 4: create a new getter/setter pair with a transition to the new map
- AccessorPair* accessors1;
- { MaybeObject* maybe_accessors1 = heap->AllocateAccessorPair();
- if (!maybe_accessors1->To(&accessors1)) return maybe_accessors1;
- }
- accessors1->set(component, map2);
+ Object* target_accessor = AccessorPair::cast(descriptor)->get(component);
+ PropertyAttributes target_attributes = details.attributes();
- // step 5: create a copy of the descriptors, incl. the new getter/setter pair
- // with the transition
- CallbacksDescriptor callbacks_descr1(name, accessors1, attributes);
- DescriptorArray* descriptors1;
- { MaybeObject* maybe_descriptors1 =
- map1->instance_descriptors()->CopyInsert(&callbacks_descr1,
- KEEP_TRANSITIONS);
- if (!maybe_descriptors1->To(&descriptors1)) return maybe_descriptors1;
+ // Reuse transition if adding same accessor with same attributes.
+ if (target_accessor == accessor && target_attributes == attributes) {
+ self->set_map(transitioned_map);
+ return self;
}
- // step 6: everything went well so far, so we make our changes visible
- obj->set_map(map2);
- map1->set_instance_descriptors(descriptors1);
- map2->SetBackPointer(map1);
- return obj;
-}
-
-
-static bool TransitionToSameAccessor(Object* map,
- String* name,
- AccessorComponent component,
- Object* accessor,
- PropertyAttributes attributes ) {
- DescriptorArray* descs = Map::cast(map)->instance_descriptors();
- int number = descs->SearchWithCache(name);
- ASSERT(number != DescriptorArray::kNotFound);
- Object* target_accessor =
- AccessorPair::cast(descs->GetCallbacksObject(number))->get(component);
- PropertyAttributes target_attributes = descs->GetDetails(number).attributes();
- return target_accessor == accessor && target_attributes == attributes;
-}
-
-
-static MaybeObject* NewCallbackTransition(JSObject* obj,
- String* name,
- AccessorComponent component,
- Object* accessor,
- PropertyAttributes attributes,
- AccessorPair* accessors2) {
- // step 1: copy the old getter/setter pair and set the new accessor
- AccessorPair* accessors3;
- { MaybeObject* maybe_accessors3 = accessors2->CopyWithoutTransitions();
- if (!maybe_accessors3->To(&accessors3)) return maybe_accessors3;
- }
- accessors3->set(component, accessor);
-
- // step 2: create a copy of the descriptors, incl. the new getter/setter pair
- Map* map2 = obj->map();
- CallbacksDescriptor callbacks_descr3(name, accessors3, attributes);
- DescriptorArray* descriptors3;
- { MaybeObject* maybe_descriptors3 =
- map2->instance_descriptors()->CopyInsert(&callbacks_descr3,
- REMOVE_TRANSITIONS);
- if (!maybe_descriptors3->To(&descriptors3)) return maybe_descriptors3;
- }
-
- // step 3: create a new map with the new descriptors
- Map* map3;
- { MaybeObject* maybe_map3 = map2->CopyDropDescriptors();
- if (!maybe_map3->To(&map3)) return maybe_map3;
- }
- map3->set_instance_descriptors(descriptors3);
-
- // step 4: everything went well so far, so we make our changes visible
- obj->set_map(map3);
- accessors2->set(component, map3);
- map3->SetBackPointer(map2);
- return obj;
+ // If either not the same accessor, or not the same attributes, fall back to
+ // the slow case.
+ return self->GetHeap()->null_value();
}
@@ -4678,40 +4656,75 @@ MaybeObject* JSObject::DefineFastAccessor(String* name,
LookupResult result(GetIsolate());
LocalLookup(name, &result);
- // If we have a new property, create a fresh accessor plus a transition to it.
- if (!result.IsFound()) {
- return CreateFreshAccessor(this, name, component, accessor, attributes);
- }
+ if (result.IsFound()
+ && !result.IsPropertyCallbacks()
+ && !result.IsTransition()) return GetHeap()->null_value();
+
+ // Return success if the same accessor with the same attributes already exist.
+ AccessorPair* source_accessors = NULL;
+ if (result.IsPropertyCallbacks()) {
+ Object* callback_value = result.GetCallbackObject();
+ if (callback_value->IsAccessorPair()) {
+ source_accessors = AccessorPair::cast(callback_value);
+ Object* entry = source_accessors->get(component);
+ if (entry == accessor && result.GetAttributes() == attributes) {
+ return this;
+ }
+ } else {
+ return GetHeap()->null_value();
+ }
- // If the property is not a JavaScript accessor, fall back to the slow case.
- if (result.type() != CALLBACKS) return GetHeap()->null_value();
- Object* callback_value = result.GetCallbackObject();
- if (!callback_value->IsAccessorPair()) return GetHeap()->null_value();
- AccessorPair* accessors = AccessorPair::cast(callback_value);
+ int descriptor_number = result.GetDescriptorIndex();
- // Follow a callback transition, if there is a fitting one.
- Object* entry = accessors->get(component);
- if (entry->IsMap() &&
- TransitionToSameAccessor(entry, name, component, accessor, attributes)) {
- set_map(Map::cast(entry));
- return this;
+ map()->LookupTransition(this, name, &result);
+
+ if (result.IsFound()) {
+ Map* target = result.GetTransitionTarget();
+ ASSERT(target->NumberOfOwnDescriptors() ==
+ map()->NumberOfOwnDescriptors());
+ // This works since descriptors are sorted in order of addition.
+ ASSERT(map()->instance_descriptors()->GetKey(descriptor_number) == name);
+ return TryAccessorTransition(
+ this, target, descriptor_number, component, accessor, attributes);
+ }
+ } else {
+ // If not, lookup a transition.
+ map()->LookupTransition(this, name, &result);
+
+ // If there is a transition, try to follow it.
+ if (result.IsFound()) {
+ Map* target = result.GetTransitionTarget();
+ int descriptor_number = target->LastAdded();
+ ASSERT(target->instance_descriptors()->GetKey(descriptor_number) == name);
+ return TryAccessorTransition(
+ this, target, descriptor_number, component, accessor, attributes);
+ }
}
- // When we re-add the same accessor again, there is nothing to do.
- if (entry == accessor && result.GetAttributes() == attributes) return this;
+ // If there is no transition yet, add a transition to the a new accessor pair
+ // containing the accessor.
+ AccessorPair* accessors;
+ MaybeObject* maybe_accessors;
- // Only the other accessor has been set so far, create a new transition.
- if (entry->IsTheHole()) {
- return NewCallbackTransition(this,
- name,
- component,
- accessor,
- attributes,
- accessors);
+ // Allocate a new pair if there were no source accessors. Otherwise, copy the
+ // pair and modify the accessor.
+ if (source_accessors != NULL) {
+ maybe_accessors = source_accessors->Copy();
+ } else {
+ maybe_accessors = GetHeap()->AllocateAccessorPair();
}
+ if (!maybe_accessors->To(&accessors)) return maybe_accessors;
+ accessors->set(component, accessor);
- // Nothing from the above worked, so we have to fall back to the slow case.
- return GetHeap()->null_value();
+ CallbacksDescriptor new_accessors_desc(name, accessors, attributes);
+
+ Map* new_map;
+ MaybeObject* maybe_new_map =
+ map()->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION);
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+
+ set_map(new_map);
+ return this;
}
@@ -4739,9 +4752,7 @@ MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) {
// Try to flatten before operating on the string.
name->TryFlatten();
- if (!CanSetCallback(name)) {
- return isolate->heap()->undefined_value();
- }
+ if (!CanSetCallback(name)) return isolate->heap()->undefined_value();
uint32_t index = 0;
bool is_element = name->AsArrayIndex(&index);
@@ -4777,23 +4788,22 @@ MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) {
break;
}
- { MaybeObject* maybe_ok =
- SetElementCallback(index, info, info->property_attributes());
- if (maybe_ok->IsFailure()) return maybe_ok;
- }
+ MaybeObject* maybe_ok =
+ SetElementCallback(index, info, info->property_attributes());
+ if (maybe_ok->IsFailure()) return maybe_ok;
} else {
// Lookup the name.
LookupResult result(isolate);
LocalLookup(name, &result);
// ES5 forbids turning a property into an accessor if it's not
// configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
- if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) {
+ if (result.IsFound() && (result.IsReadOnly() || result.IsDontDelete())) {
return isolate->heap()->undefined_value();
}
- { MaybeObject* maybe_ok =
- SetPropertyCallback(name, info, info->property_attributes());
- if (maybe_ok->IsFailure()) return maybe_ok;
- }
+
+ MaybeObject* maybe_ok =
+ SetPropertyCallback(name, info, info->property_attributes());
+ if (maybe_ok->IsFailure()) return maybe_ok;
}
return this;
@@ -4819,9 +4829,9 @@ Object* JSObject::LookupAccessor(String* name, AccessorComponent component) {
if (name->AsArrayIndex(&index)) {
for (Object* obj = this;
obj != heap->null_value();
- obj = JSObject::cast(obj)->GetPrototype()) {
- JSObject* js_object = JSObject::cast(obj);
- if (js_object->HasDictionaryElements()) {
+ obj = JSReceiver::cast(obj)->GetPrototype()) {
+ if (obj->IsJSObject() && JSObject::cast(obj)->HasDictionaryElements()) {
+ JSObject* js_object = JSObject::cast(obj);
SeededNumberDictionary* dictionary = js_object->element_dictionary();
int entry = dictionary->FindEntry(index);
if (entry != SeededNumberDictionary::kNotFound) {
@@ -4836,12 +4846,12 @@ Object* JSObject::LookupAccessor(String* name, AccessorComponent component) {
} else {
for (Object* obj = this;
obj != heap->null_value();
- obj = JSObject::cast(obj)->GetPrototype()) {
+ obj = JSReceiver::cast(obj)->GetPrototype()) {
LookupResult result(heap->isolate());
- JSObject::cast(obj)->LocalLookup(name, &result);
- if (result.IsProperty()) {
+ JSReceiver::cast(obj)->LocalLookup(name, &result);
+ if (result.IsFound()) {
if (result.IsReadOnly()) return heap->undefined_value();
- if (result.type() == CALLBACKS) {
+ if (result.IsPropertyCallbacks()) {
Object* obj = result.GetCallbackObject();
if (obj->IsAccessorPair()) {
return AccessorPair::cast(obj)->GetComponent(component);
@@ -4856,8 +4866,9 @@ Object* JSObject::LookupAccessor(String* name, AccessorComponent component) {
Object* JSObject::SlowReverseLookup(Object* value) {
if (HasFastProperties()) {
+ int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
DescriptorArray* descs = map()->instance_descriptors();
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ for (int i = 0; i < number_of_own_descriptors; i++) {
if (descs->GetType(i) == FIELD) {
if (FastPropertyAt(descs->GetFieldIndex(i)) == value) {
return descs->GetKey(i);
@@ -4875,46 +4886,22 @@ Object* JSObject::SlowReverseLookup(Object* value) {
}
-MaybeObject* Map::CopyDropDescriptors() {
- Heap* heap = GetHeap();
- Object* result;
- { MaybeObject* maybe_result =
- heap->AllocateMap(instance_type(), instance_size());
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- Map::cast(result)->set_prototype(prototype());
- Map::cast(result)->set_constructor(constructor());
- // Don't copy descriptors, so map transitions always remain a forest.
- // If we retained the same descriptors we would have two maps
- // pointing to the same transition which is bad because the garbage
- // collector relies on being able to reverse pointers from transitions
- // to maps. If properties need to be retained use CopyDropTransitions.
- Map::cast(result)->clear_instance_descriptors();
- // Please note instance_type and instance_size are set when allocated.
- Map::cast(result)->set_inobject_properties(inobject_properties());
- Map::cast(result)->set_unused_property_fields(unused_property_fields());
-
- // If the map has pre-allocated properties always start out with a descriptor
- // array describing these properties.
- if (pre_allocated_property_fields() > 0) {
- ASSERT(constructor()->IsJSFunction());
- JSFunction* ctor = JSFunction::cast(constructor());
- Object* descriptors;
- { MaybeObject* maybe_descriptors =
- ctor->initial_map()->instance_descriptors()->RemoveTransitions(
- DescriptorArray::MAY_BE_SHARED);
- if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors;
- }
- Map::cast(result)->set_instance_descriptors(
- DescriptorArray::cast(descriptors));
- Map::cast(result)->set_pre_allocated_property_fields(
- pre_allocated_property_fields());
- }
- Map::cast(result)->set_bit_field(bit_field());
- Map::cast(result)->set_bit_field2(bit_field2());
- Map::cast(result)->set_bit_field3(bit_field3());
- Map::cast(result)->set_is_shared(false);
- Map::cast(result)->ClearCodeCache(heap);
+MaybeObject* Map::RawCopy(int instance_size) {
+ Map* result;
+ MaybeObject* maybe_result =
+ GetHeap()->AllocateMap(instance_type(), instance_size);
+ if (!maybe_result->To(&result)) return maybe_result;
+
+ result->set_prototype(prototype());
+ result->set_constructor(constructor());
+ result->set_bit_field(bit_field());
+ result->set_bit_field2(bit_field2());
+ result->set_bit_field3(bit_field3());
+ int new_bit_field3 = bit_field3();
+ new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
+ new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
+ new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache);
+ result->set_bit_field3(new_bit_field3);
return result;
}
@@ -4926,52 +4913,351 @@ MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode,
new_instance_size -= inobject_properties() * kPointerSize;
}
- Object* result;
- { MaybeObject* maybe_result =
- GetHeap()->AllocateMap(instance_type(), new_instance_size);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ Map* result;
+ MaybeObject* maybe_result = RawCopy(new_instance_size);
+ if (!maybe_result->To(&result)) return maybe_result;
if (mode != CLEAR_INOBJECT_PROPERTIES) {
- Map::cast(result)->set_inobject_properties(inobject_properties());
+ result->set_inobject_properties(inobject_properties());
}
- Map::cast(result)->set_prototype(prototype());
- Map::cast(result)->set_constructor(constructor());
+ result->set_code_cache(code_cache());
+ result->set_is_shared(sharing == SHARED_NORMALIZED_MAP);
+ result->set_dictionary_map(true);
- Map::cast(result)->set_bit_field(bit_field());
- Map::cast(result)->set_bit_field2(bit_field2());
- Map::cast(result)->set_bit_field3(bit_field3());
- Map::cast(result)->set_code_cache(code_cache());
+#ifdef VERIFY_HEAP
+ if (FLAG_verify_heap && result->is_shared()) {
+ result->SharedMapVerify();
+ }
+#endif
+
+ return result;
+}
- Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP);
-#ifdef DEBUG
- if (FLAG_verify_heap && Map::cast(result)->is_shared()) {
- Map::cast(result)->SharedMapVerify();
+MaybeObject* Map::CopyDropDescriptors() {
+ Map* result;
+ MaybeObject* maybe_result = RawCopy(instance_size());
+ if (!maybe_result->To(&result)) return maybe_result;
+
+ // Please note instance_type and instance_size are set when allocated.
+ result->set_inobject_properties(inobject_properties());
+ result->set_unused_property_fields(unused_property_fields());
+
+ result->set_pre_allocated_property_fields(pre_allocated_property_fields());
+ result->set_is_shared(false);
+ result->ClearCodeCache(GetHeap());
+ return result;
+}
+
+
+MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors,
+ Descriptor* descriptor) {
+ // Sanity check. This path is only to be taken if the map owns its descriptor
+ // array, implying that its NumberOfOwnDescriptors equals the number of
+ // descriptors in the descriptor array.
+ ASSERT(NumberOfOwnDescriptors() ==
+ instance_descriptors()->number_of_descriptors());
+ Map* result;
+ MaybeObject* maybe_result = CopyDropDescriptors();
+ if (!maybe_result->To(&result)) return maybe_result;
+
+ String* name = descriptor->GetKey();
+
+ TransitionArray* transitions;
+ MaybeObject* maybe_transitions =
+ AddTransition(name, result, SIMPLE_TRANSITION);
+ if (!maybe_transitions->To(&transitions)) return maybe_transitions;
+
+ int old_size = descriptors->number_of_descriptors();
+
+ DescriptorArray* new_descriptors;
+
+ if (descriptors->NumberOfSlackDescriptors() > 0) {
+ new_descriptors = descriptors;
+ new_descriptors->Append(descriptor);
+ } else {
+ // Descriptor arrays grow by 50%.
+ MaybeObject* maybe_descriptors = DescriptorArray::Allocate(
+ old_size, old_size < 4 ? 1 : old_size / 2);
+ if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
+
+ DescriptorArray::WhitenessWitness witness(new_descriptors);
+
+ // Copy the descriptors, inserting a descriptor.
+ for (int i = 0; i < old_size; ++i) {
+ new_descriptors->CopyFrom(i, descriptors, i, witness);
+ }
+
+ new_descriptors->Append(descriptor, witness);
+
+ if (old_size > 0) {
+ // If the source descriptors had an enum cache we copy it. This ensures
+ // that the maps to which we push the new descriptor array back can rely
+ // on a cache always being available once it is set. If the map has more
+ // enumerated descriptors than available in the original cache, the cache
+ // will be lazily replaced by the extended cache when needed.
+ if (descriptors->HasEnumCache()) {
+ new_descriptors->CopyEnumCacheFrom(descriptors);
+ }
+
+ Map* map;
+ // Replace descriptors by new_descriptors in all maps that share it.
+ for (Object* current = GetBackPointer();
+ !current->IsUndefined();
+ current = map->GetBackPointer()) {
+ map = Map::cast(current);
+ if (map->instance_descriptors() != descriptors) break;
+ map->set_instance_descriptors(new_descriptors);
+ }
+
+ set_instance_descriptors(new_descriptors);
+ }
}
-#endif
+
+ result->SetBackPointer(this);
+ result->InitializeDescriptors(new_descriptors);
+ ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1);
+
+ set_transitions(transitions);
+ set_owns_descriptors(false);
return result;
}
-MaybeObject* Map::CopyDropTransitions(
- DescriptorArray::SharedMode shared_mode) {
- Object* new_map;
- { MaybeObject* maybe_new_map = CopyDropDescriptors();
- if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
+MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
+ String* name,
+ TransitionFlag flag,
+ int descriptor_index) {
+ ASSERT(descriptors->IsSortedNoDuplicates());
+
+ Map* result;
+ MaybeObject* maybe_result = CopyDropDescriptors();
+ if (!maybe_result->To(&result)) return maybe_result;
+
+ result->InitializeDescriptors(descriptors);
+
+ if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
+ TransitionArray* transitions;
+ SimpleTransitionFlag simple_flag =
+ (descriptor_index == descriptors->number_of_descriptors() - 1)
+ ? SIMPLE_TRANSITION
+ : FULL_TRANSITION;
+ MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
+ if (!maybe_transitions->To(&transitions)) return maybe_transitions;
+
+ set_transitions(transitions);
+ result->SetBackPointer(this);
+ }
+
+ return result;
+}
+
+
+MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
+ if (flag == INSERT_TRANSITION) {
+ ASSERT(!HasElementsTransition() ||
+ ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS ||
+ IsExternalArrayElementsKind(
+ elements_transition_map()->elements_kind())) &&
+ (kind == DICTIONARY_ELEMENTS ||
+ IsExternalArrayElementsKind(kind))));
+ ASSERT(!IsFastElementsKind(kind) ||
+ IsMoreGeneralElementsKindTransition(elements_kind(), kind));
+ ASSERT(kind != elements_kind());
+ }
+
+ bool insert_transition =
+ flag == INSERT_TRANSITION && !HasElementsTransition();
+
+ if (insert_transition && owns_descriptors()) {
+ // In case the map owned its own descriptors, share the descriptors and
+ // transfer ownership to the new map.
+ Map* new_map;
+ MaybeObject* maybe_new_map = CopyDropDescriptors();
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+
+ MaybeObject* added_elements = set_elements_transition_map(new_map);
+ if (added_elements->IsFailure()) return added_elements;
+
+ new_map->set_elements_kind(kind);
+ new_map->InitializeDescriptors(instance_descriptors());
+ new_map->SetBackPointer(this);
+ set_owns_descriptors(false);
+ return new_map;
}
- Object* descriptors;
- { MaybeObject* maybe_descriptors =
- instance_descriptors()->RemoveTransitions(shared_mode);
- if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors;
+
+ // In case the map did not own its own descriptors, a split is forced by
+ // copying the map; creating a new descriptor array cell.
+ // Create a new free-floating map only if we are not allowed to store it.
+ Map* new_map;
+ MaybeObject* maybe_new_map = Copy();
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+
+ new_map->set_elements_kind(kind);
+
+ if (insert_transition) {
+ MaybeObject* added_elements = set_elements_transition_map(new_map);
+ if (added_elements->IsFailure()) return added_elements;
+ new_map->SetBackPointer(this);
}
- cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors));
+
return new_map;
}
+MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() {
+ if (pre_allocated_property_fields() == 0) return CopyDropDescriptors();
+
+ // If the map has pre-allocated properties always start out with a descriptor
+ // array describing these properties.
+ ASSERT(constructor()->IsJSFunction());
+ JSFunction* ctor = JSFunction::cast(constructor());
+ Map* map = ctor->initial_map();
+ DescriptorArray* descriptors = map->instance_descriptors();
+
+ int number_of_own_descriptors = map->NumberOfOwnDescriptors();
+ DescriptorArray* new_descriptors;
+ MaybeObject* maybe_descriptors =
+ descriptors->CopyUpTo(number_of_own_descriptors);
+ if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
+
+ return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0);
+}
+
+
+MaybeObject* Map::Copy() {
+ DescriptorArray* descriptors = instance_descriptors();
+ DescriptorArray* new_descriptors;
+ int number_of_own_descriptors = NumberOfOwnDescriptors();
+ MaybeObject* maybe_descriptors =
+ descriptors->CopyUpTo(number_of_own_descriptors);
+ if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
+
+ return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0);
+}
+
+
+MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
+ TransitionFlag flag) {
+ DescriptorArray* descriptors = instance_descriptors();
+
+ // Ensure the key is a symbol.
+ MaybeObject* maybe_failure = descriptor->KeyToSymbol();
+ if (maybe_failure->IsFailure()) return maybe_failure;
+
+ int old_size = NumberOfOwnDescriptors();
+ int new_size = old_size + 1;
+ descriptor->SetEnumerationIndex(new_size);
+
+ if (flag == INSERT_TRANSITION &&
+ owns_descriptors() &&
+ CanHaveMoreTransitions()) {
+ return ShareDescriptor(descriptors, descriptor);
+ }
+
+ DescriptorArray* new_descriptors;
+ MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size, 1);
+ if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
+
+ DescriptorArray::WhitenessWitness witness(new_descriptors);
+
+ // Copy the descriptors, inserting a descriptor.
+ for (int i = 0; i < old_size; ++i) {
+ new_descriptors->CopyFrom(i, descriptors, i, witness);
+ }
+
+ if (old_size != descriptors->number_of_descriptors()) {
+ new_descriptors->SetNumberOfDescriptors(new_size);
+ new_descriptors->Set(old_size, descriptor, witness);
+ new_descriptors->Sort();
+ } else {
+ new_descriptors->Append(descriptor, witness);
+ }
+
+ String* key = descriptor->GetKey();
+ int insertion_index = new_descriptors->number_of_descriptors() - 1;
+
+ return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index);
+}
+
+
+MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor,
+ TransitionFlag flag) {
+ DescriptorArray* old_descriptors = instance_descriptors();
+
+ // Ensure the key is a symbol.
+ MaybeObject* maybe_result = descriptor->KeyToSymbol();
+ if (maybe_result->IsFailure()) return maybe_result;
+
+ // We replace the key if it is already present.
+ int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this);
+ if (index != DescriptorArray::kNotFound) {
+ return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag);
+ }
+ return CopyAddDescriptor(descriptor, flag);
+}
+
+
+MaybeObject* DescriptorArray::CopyUpTo(int enumeration_index) {
+ if (enumeration_index == 0) return GetHeap()->empty_descriptor_array();
+
+ int size = enumeration_index;
+
+ DescriptorArray* descriptors;
+ MaybeObject* maybe_descriptors = Allocate(size);
+ if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
+ DescriptorArray::WhitenessWitness witness(descriptors);
+
+ for (int i = 0; i < size; ++i) {
+ descriptors->CopyFrom(i, this, i, witness);
+ }
+
+ if (number_of_descriptors() != enumeration_index) descriptors->Sort();
+
+ return descriptors;
+}
+
+
+MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors,
+ Descriptor* descriptor,
+ int insertion_index,
+ TransitionFlag flag) {
+ // Ensure the key is a symbol.
+ MaybeObject* maybe_failure = descriptor->KeyToSymbol();
+ if (maybe_failure->IsFailure()) return maybe_failure;
+
+ String* key = descriptor->GetKey();
+ ASSERT(key == descriptors->GetKey(insertion_index));
+
+ int new_size = NumberOfOwnDescriptors();
+ ASSERT(0 <= insertion_index && insertion_index < new_size);
+
+ PropertyDetails details = descriptors->GetDetails(insertion_index);
+ ASSERT_LE(details.descriptor_index(), new_size);
+ descriptor->SetEnumerationIndex(details.descriptor_index());
+
+ DescriptorArray* new_descriptors;
+ MaybeObject* maybe_descriptors = DescriptorArray::Allocate(new_size);
+ if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
+ DescriptorArray::WhitenessWitness witness(new_descriptors);
+
+ for (int i = 0; i < new_size; ++i) {
+ if (i == insertion_index) {
+ new_descriptors->Set(i, descriptor, witness);
+ } else {
+ new_descriptors->CopyFrom(i, descriptors, i, witness);
+ }
+ }
+
+ // Re-sort if descriptors were removed.
+ if (new_size != descriptors->length()) new_descriptors->Sort();
+
+ return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index);
+}
+
+
void Map::UpdateCodeCache(Handle<Map> map,
Handle<String> name,
Handle<Code> code) {
@@ -4980,6 +5266,7 @@ void Map::UpdateCodeCache(Handle<Map> map,
map->UpdateCodeCache(*name, *code));
}
+
MaybeObject* Map::UpdateCodeCache(String* name, Code* code) {
ASSERT(!is_shared() || code->allowed_in_shared_map_code_cache());
@@ -5028,85 +5315,43 @@ void Map::RemoveFromCodeCache(String* name, Code* code, int index) {
// field of the contens array while it is running.
class IntrusiveMapTransitionIterator {
public:
- explicit IntrusiveMapTransitionIterator(DescriptorArray* descriptor_array)
- : descriptor_array_(descriptor_array) { }
+ explicit IntrusiveMapTransitionIterator(TransitionArray* transition_array)
+ : transition_array_(transition_array) { }
void Start() {
ASSERT(!IsIterating());
- if (descriptor_array_->MayContainTransitions())
- *DescriptorArrayHeader() = Smi::FromInt(0);
+ *TransitionArrayHeader() = Smi::FromInt(0);
}
bool IsIterating() {
- return descriptor_array_->MayContainTransitions() &&
- (*DescriptorArrayHeader())->IsSmi();
+ return (*TransitionArrayHeader())->IsSmi();
}
Map* Next() {
ASSERT(IsIterating());
- // Attention, tricky index manipulation ahead: Two consecutive indices are
- // assigned to each descriptor. Most descriptors directly advance to the
- // next descriptor by adding 2 to the index. The exceptions are the
- // CALLBACKS entries: An even index means we look at its getter, and an odd
- // index means we look at its setter.
- int raw_index = Smi::cast(*DescriptorArrayHeader())->value();
- int index = raw_index / 2;
- int number_of_descriptors = descriptor_array_->number_of_descriptors();
- while (index < number_of_descriptors) {
- PropertyDetails details(descriptor_array_->GetDetails(index));
- switch (details.type()) {
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- // We definitely have a map transition.
- *DescriptorArrayHeader() = Smi::FromInt(raw_index + 2);
- return static_cast<Map*>(descriptor_array_->GetValue(index));
- case CALLBACKS: {
- // We might have a map transition in a getter or in a setter.
- AccessorPair* accessors =
- static_cast<AccessorPair*>(descriptor_array_->GetValue(index));
- Object* accessor;
- if ((raw_index & 1) == 0) {
- accessor = accessors->setter();
- } else {
- ++index;
- accessor = accessors->getter();
- }
- ++raw_index;
- if (accessor->IsMap()) {
- *DescriptorArrayHeader() = Smi::FromInt(raw_index);
- return static_cast<Map*>(accessor);
- }
- break;
- }
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case HANDLER:
- case INTERCEPTOR:
- case NULL_DESCRIPTOR:
- // We definitely have no map transition.
- raw_index += 2;
- ++index;
- break;
- }
+ int index = Smi::cast(*TransitionArrayHeader())->value();
+ int number_of_transitions = transition_array_->number_of_transitions();
+ while (index < number_of_transitions) {
+ *TransitionArrayHeader() = Smi::FromInt(index + 1);
+ return transition_array_->GetTarget(index);
}
- if (index == descriptor_array_->number_of_descriptors()) {
- Map* elements_transition = descriptor_array_->elements_transition_map();
- if (elements_transition != NULL) {
- *DescriptorArrayHeader() = Smi::FromInt(raw_index + 2);
- return elements_transition;
- }
+
+ if (index == number_of_transitions &&
+ transition_array_->HasElementsTransition()) {
+ Map* elements_transition = transition_array_->elements_transition();
+ *TransitionArrayHeader() = Smi::FromInt(index + 1);
+ return elements_transition;
}
- *DescriptorArrayHeader() = descriptor_array_->GetHeap()->fixed_array_map();
+ *TransitionArrayHeader() = transition_array_->GetHeap()->fixed_array_map();
return NULL;
}
private:
- Object** DescriptorArrayHeader() {
- return HeapObject::RawField(descriptor_array_, DescriptorArray::kMapOffset);
+ Object** TransitionArrayHeader() {
+ return HeapObject::RawField(transition_array_, TransitionArray::kMapOffset);
}
- DescriptorArray* descriptor_array_;
+ TransitionArray* transition_array_;
};
@@ -5119,11 +5364,11 @@ class IntrusivePrototypeTransitionIterator {
void Start() {
ASSERT(!IsIterating());
- if (HasTransitions()) *Header() = Smi::FromInt(0);
+ *Header() = Smi::FromInt(0);
}
bool IsIterating() {
- return HasTransitions() && (*Header())->IsSmi();
+ return (*Header())->IsSmi();
}
Map* Next() {
@@ -5138,23 +5383,17 @@ class IntrusivePrototypeTransitionIterator {
}
private:
- bool HasTransitions() {
- return proto_trans_->map()->IsSmi() || proto_trans_->IsFixedArray();
- }
-
Object** Header() {
return HeapObject::RawField(proto_trans_, FixedArray::kMapOffset);
}
int NumberOfTransitions() {
- ASSERT(HasTransitions());
FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_);
Object* num = proto_trans->get(Map::kProtoTransitionNumberOfEntriesOffset);
return Smi::cast(num)->value();
}
Map* GetTransition(int transitionNumber) {
- ASSERT(HasTransitions());
FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_);
return Map::cast(proto_trans->get(IndexFor(transitionNumber)));
}
@@ -5204,43 +5443,43 @@ class TraversableMap : public Map {
return old_parent;
}
- // Can either be Smi (no instance descriptors), or a descriptor array with the
- // header overwritten as a Smi (thus iterating).
- DescriptorArray* MutatedInstanceDescriptors() {
- Object* object =
- *HeapObject::RawField(this, kInstanceDescriptorsOrBitField3Offset);
- if (object->IsSmi()) {
- return GetHeap()->empty_descriptor_array();
- } else {
- DescriptorArray* descriptor_array =
- static_cast<DescriptorArray*>(object);
- return descriptor_array;
- }
- }
-
// Start iterating over this map's children, possibly destroying a FixedArray
// map (see explanation above).
void ChildIteratorStart() {
- IntrusiveMapTransitionIterator(instance_descriptors()).Start();
- IntrusivePrototypeTransitionIterator(
- unchecked_prototype_transitions()).Start();
+ if (HasTransitionArray()) {
+ if (HasPrototypeTransitions()) {
+ IntrusivePrototypeTransitionIterator(GetPrototypeTransitions()).Start();
+ }
+
+ IntrusiveMapTransitionIterator(transitions()).Start();
+ }
}
// If we have an unvisited child map, return that one and advance. If we have
// none, return NULL and reset any destroyed FixedArray maps.
TraversableMap* ChildIteratorNext() {
- IntrusivePrototypeTransitionIterator
- proto_iterator(unchecked_prototype_transitions());
- if (proto_iterator.IsIterating()) {
- Map* next = proto_iterator.Next();
- if (next != NULL) return static_cast<TraversableMap*>(next);
+ TransitionArray* transition_array = unchecked_transition_array();
+ if (!transition_array->map()->IsSmi() &&
+ !transition_array->IsTransitionArray()) {
+ return NULL;
+ }
+
+ if (transition_array->HasPrototypeTransitions()) {
+ HeapObject* proto_transitions =
+ transition_array->UncheckedPrototypeTransitions();
+ IntrusivePrototypeTransitionIterator proto_iterator(proto_transitions);
+ if (proto_iterator.IsIterating()) {
+ Map* next = proto_iterator.Next();
+ if (next != NULL) return static_cast<TraversableMap*>(next);
+ }
}
- IntrusiveMapTransitionIterator
- descriptor_iterator(MutatedInstanceDescriptors());
- if (descriptor_iterator.IsIterating()) {
- Map* next = descriptor_iterator.Next();
+
+ IntrusiveMapTransitionIterator transition_iterator(transition_array);
+ if (transition_iterator.IsIterating()) {
+ Map* next = transition_iterator.Next();
if (next != NULL) return static_cast<TraversableMap*>(next);
}
+
return NULL;
}
};
@@ -5271,7 +5510,7 @@ MaybeObject* CodeCache::Update(String* name, Code* code) {
// The number of monomorphic stubs for normal load/store/call IC's can grow to
// a large number and therefore they need to go into a hash table. They are
// used to load global properties from cells.
- if (code->type() == NORMAL) {
+ if (code->type() == Code::NORMAL) {
// Make sure that a hash table is allocated for the normal load code cache.
if (normal_type_cache()->IsUndefined()) {
Object* result;
@@ -5362,7 +5601,7 @@ MaybeObject* CodeCache::UpdateNormalTypeCache(String* name, Code* code) {
Object* CodeCache::Lookup(String* name, Code::Flags flags) {
- if (Code::ExtractTypeFromFlags(flags) == NORMAL) {
+ if (Code::ExtractTypeFromFlags(flags) == Code::NORMAL) {
return LookupNormalTypeCache(name, flags);
} else {
return LookupDefaultCache(name, flags);
@@ -5400,7 +5639,7 @@ Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) {
int CodeCache::GetIndex(Object* name, Code* code) {
- if (code->type() == NORMAL) {
+ if (code->type() == Code::NORMAL) {
if (normal_type_cache()->IsUndefined()) return -1;
CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
return cache->GetIndex(String::cast(name), code->flags());
@@ -5416,7 +5655,7 @@ int CodeCache::GetIndex(Object* name, Code* code) {
void CodeCache::RemoveByIndex(Object* name, Code* code, int index) {
- if (code->type() == NORMAL) {
+ if (code->type() == Code::NORMAL) {
ASSERT(!normal_type_cache()->IsUndefined());
CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
ASSERT(cache->GetIndex(String::cast(name), code->flags()) == index);
@@ -5734,7 +5973,7 @@ MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) {
MaybeObject* maybe_result =
accessor->AddElementsToFixedArray(NULL, NULL, this, other);
FixedArray* result;
- if (!maybe_result->To<FixedArray>(&result)) return maybe_result;
+ if (!maybe_result->To(&result)) return maybe_result;
#ifdef DEBUG
if (FLAG_enable_slow_asserts) {
for (int i = 0; i < result->length(); i++) {
@@ -5790,235 +6029,80 @@ bool FixedArray::IsEqualTo(FixedArray* other) {
#endif
-MaybeObject* DescriptorArray::Allocate(int number_of_descriptors,
- SharedMode shared_mode) {
+MaybeObject* DescriptorArray::Allocate(int number_of_descriptors, int slack) {
Heap* heap = Isolate::Current()->heap();
// Do not use DescriptorArray::cast on incomplete object.
+ int size = number_of_descriptors + slack;
+ if (size == 0) return heap->empty_descriptor_array();
FixedArray* result;
- if (number_of_descriptors == 0 && shared_mode == MAY_BE_SHARED) {
- return heap->empty_descriptor_array();
- }
// Allocate the array of keys.
- { MaybeObject* maybe_array =
- heap->AllocateFixedArray(ToKeyIndex(number_of_descriptors));
- if (!maybe_array->To(&result)) return maybe_array;
- }
+ MaybeObject* maybe_array = heap->AllocateFixedArray(LengthFor(size));
+ if (!maybe_array->To(&result)) return maybe_array;
- result->set(kBitField3StorageIndex, Smi::FromInt(0));
- result->set(kEnumerationIndexIndex,
- Smi::FromInt(PropertyDetails::kInitialIndex));
- result->set(kTransitionsIndex, Smi::FromInt(0));
+ result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
+ result->set(kEnumCacheIndex, Smi::FromInt(0));
return result;
}
+void DescriptorArray::ClearEnumCache() {
+ set(kEnumCacheIndex, Smi::FromInt(0));
+}
+
+
void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
FixedArray* new_cache,
Object* new_index_cache) {
ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength);
ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray());
- if (HasEnumCache()) {
- FixedArray::cast(get(kEnumerationIndexIndex))->
- set(kEnumCacheBridgeCacheIndex, new_cache);
- FixedArray::cast(get(kEnumerationIndexIndex))->
- set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
- } else {
- if (IsEmpty()) return; // Do nothing for empty descriptor array.
- FixedArray::cast(bridge_storage)->
- set(kEnumCacheBridgeCacheIndex, new_cache);
- FixedArray::cast(bridge_storage)->
- set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
- NoWriteBarrierSet(FixedArray::cast(bridge_storage),
- kEnumCacheBridgeEnumIndex,
- get(kEnumerationIndexIndex));
- set(kEnumerationIndexIndex, bridge_storage);
- }
-}
-
-
-static bool InsertionPointFound(String* key1, String* key2) {
- return key1->Hash() > key2->Hash() || key1 == key2;
+ ASSERT(!IsEmpty());
+ ASSERT(!HasEnumCache() || new_cache->length() > GetEnumCache()->length());
+ FixedArray::cast(bridge_storage)->
+ set(kEnumCacheBridgeCacheIndex, new_cache);
+ FixedArray::cast(bridge_storage)->
+ set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
+ set(kEnumCacheIndex, bridge_storage);
}
-void DescriptorArray::CopyFrom(Handle<DescriptorArray> dst,
- int dst_index,
- Handle<DescriptorArray> src,
+void DescriptorArray::CopyFrom(int dst_index,
+ DescriptorArray* src,
int src_index,
const WhitenessWitness& witness) {
- CALL_HEAP_FUNCTION_VOID(dst->GetIsolate(),
- dst->CopyFrom(dst_index, *src, src_index, witness));
-}
-
-
-MaybeObject* DescriptorArray::CopyFrom(int dst_index,
- DescriptorArray* src,
- int src_index,
- const WhitenessWitness& witness) {
Object* value = src->GetValue(src_index);
PropertyDetails details = src->GetDetails(src_index);
- if (details.type() == CALLBACKS && value->IsAccessorPair()) {
- MaybeObject* maybe_copy =
- AccessorPair::cast(value)->CopyWithoutTransitions();
- if (!maybe_copy->To(&value)) return maybe_copy;
- }
Descriptor desc(src->GetKey(src_index), value, details);
Set(dst_index, &desc, witness);
- return this;
-}
-
-
-MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor,
- TransitionFlag transition_flag) {
- // Transitions are only kept when inserting another transition.
- // This precondition is not required by this function's implementation, but
- // is currently required by the semantics of maps, so we check it.
- // Conversely, we filter after replacing, so replacing a transition and
- // removing all other transitions is not supported.
- bool remove_transitions = transition_flag == REMOVE_TRANSITIONS;
- ASSERT(remove_transitions == !descriptor->ContainsTransition());
- ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR);
-
- // Ensure the key is a symbol.
- { MaybeObject* maybe_result = descriptor->KeyToSymbol();
- if (maybe_result->IsFailure()) return maybe_result;
- }
-
- int new_size = 0;
- for (int i = 0; i < number_of_descriptors(); i++) {
- if (IsNullDescriptor(i)) continue;
- if (remove_transitions && IsTransitionOnly(i)) continue;
- new_size++;
- }
-
- // If key is in descriptor, we replace it in-place when filtering.
- // Count a null descriptor for key as inserted, not replaced.
- int index = Search(descriptor->GetKey());
- const bool replacing = (index != kNotFound);
- bool keep_enumeration_index = false;
- if (!replacing) {
- ++new_size;
- } else if (!IsTransitionOnly(index)) {
- // We are replacing an existing descriptor. We keep the enumeration index
- // of a visible property.
- keep_enumeration_index = true;
- } else if (remove_transitions) {
- // Replaced descriptor has been counted as removed if it is a transition
- // that will be replaced. Adjust count in this case.
- ++new_size;
- }
-
- DescriptorArray* new_descriptors;
- { SharedMode mode = remove_transitions ? MAY_BE_SHARED : CANNOT_BE_SHARED;
- MaybeObject* maybe_result = Allocate(new_size, mode);
- if (!maybe_result->To(&new_descriptors)) return maybe_result;
- }
-
- DescriptorArray::WhitenessWitness witness(new_descriptors);
-
- // Set the enumeration index in the descriptors and set the enumeration index
- // in the result.
- int enumeration_index = NextEnumerationIndex();
- if (!descriptor->ContainsTransition()) {
- if (keep_enumeration_index) {
- descriptor->SetEnumerationIndex(GetDetails(index).index());
- } else {
- descriptor->SetEnumerationIndex(enumeration_index);
- ++enumeration_index;
- }
- }
- Map* old_elements_transition = elements_transition_map();
- if ((!remove_transitions) && (old_elements_transition != NULL)) {
- new_descriptors->set_elements_transition_map(old_elements_transition);
- }
- new_descriptors->SetNextEnumerationIndex(enumeration_index);
-
- // Copy the descriptors, filtering out transitions and null descriptors,
- // and inserting or replacing a descriptor.
- int to_index = 0;
- int insertion_index = -1;
- int from_index = 0;
- while (from_index < number_of_descriptors()) {
- if (insertion_index < 0 &&
- InsertionPointFound(GetKey(from_index), descriptor->GetKey())) {
- insertion_index = to_index++;
- if (replacing) from_index++;
- } else {
- if (!(IsNullDescriptor(from_index) ||
- (remove_transitions && IsTransitionOnly(from_index)))) {
- MaybeObject* copy_result =
- new_descriptors->CopyFrom(to_index++, this, from_index, witness);
- if (copy_result->IsFailure()) return copy_result;
- }
- from_index++;
- }
- }
- if (insertion_index < 0) insertion_index = to_index++;
-
- ASSERT(insertion_index < new_descriptors->number_of_descriptors());
- new_descriptors->Set(insertion_index, descriptor, witness);
-
- ASSERT(to_index == new_descriptors->number_of_descriptors());
- SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
-
- return new_descriptors;
}
-MaybeObject* DescriptorArray::RemoveTransitions(SharedMode shared_mode) {
- // Allocate the new descriptor array.
- int new_number_of_descriptors = 0;
- for (int i = 0; i < number_of_descriptors(); i++) {
- if (IsProperty(i)) new_number_of_descriptors++;
- }
- DescriptorArray* new_descriptors;
- { MaybeObject* maybe_result = Allocate(new_number_of_descriptors,
- shared_mode);
- if (!maybe_result->To(&new_descriptors)) return maybe_result;
- }
-
- // Copy the content.
- DescriptorArray::WhitenessWitness witness(new_descriptors);
- int next_descriptor = 0;
- for (int i = 0; i < number_of_descriptors(); i++) {
- if (IsProperty(i)) {
- MaybeObject* copy_result =
- new_descriptors->CopyFrom(next_descriptor++, this, i, witness);
- if (copy_result->IsFailure()) return copy_result;
- }
- }
- ASSERT(next_descriptor == new_descriptors->number_of_descriptors());
- new_descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
-
- return new_descriptors;
-}
-
// We need the whiteness witness since sort will reshuffle the entries in the
// descriptor array. If the descriptor array were to be black, the shuffling
// would move a slot that was already recorded as pointing into an evacuation
// candidate. This would result in missing updates upon evacuation.
-void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) {
+void DescriptorArray::Sort() {
// In-place heap sort.
int len = number_of_descriptors();
-
+ // Reset sorting since the descriptor array might contain invalid pointers.
+ for (int i = 0; i < len; ++i) SetSortedKey(i, i);
// Bottom-up max-heap construction.
// Index of the last node with children
const int max_parent_index = (len / 2) - 1;
for (int i = max_parent_index; i >= 0; --i) {
int parent_index = i;
- const uint32_t parent_hash = GetKey(i)->Hash();
+ const uint32_t parent_hash = GetSortedKey(i)->Hash();
while (parent_index <= max_parent_index) {
int child_index = 2 * parent_index + 1;
- uint32_t child_hash = GetKey(child_index)->Hash();
+ uint32_t child_hash = GetSortedKey(child_index)->Hash();
if (child_index + 1 < len) {
- uint32_t right_child_hash = GetKey(child_index + 1)->Hash();
+ uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
if (right_child_hash > child_hash) {
child_index++;
child_hash = right_child_hash;
}
}
if (child_hash <= parent_hash) break;
- NoIncrementalWriteBarrierSwapDescriptors(parent_index, child_index);
+ SwapSortedKeys(parent_index, child_index);
// Now element at child_index could be < its children.
parent_index = child_index; // parent_hash remains correct.
}
@@ -6027,83 +6111,38 @@ void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) {
// Extract elements and create sorted array.
for (int i = len - 1; i > 0; --i) {
// Put max element at the back of the array.
- NoIncrementalWriteBarrierSwapDescriptors(0, i);
+ SwapSortedKeys(0, i);
// Shift down the new top element.
int parent_index = 0;
- const uint32_t parent_hash = GetKey(parent_index)->Hash();
+ const uint32_t parent_hash = GetSortedKey(parent_index)->Hash();
const int max_parent_index = (i / 2) - 1;
while (parent_index <= max_parent_index) {
int child_index = parent_index * 2 + 1;
- uint32_t child_hash = GetKey(child_index)->Hash();
+ uint32_t child_hash = GetSortedKey(child_index)->Hash();
if (child_index + 1 < i) {
- uint32_t right_child_hash = GetKey(child_index + 1)->Hash();
+ uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
if (right_child_hash > child_hash) {
child_index++;
child_hash = right_child_hash;
}
}
if (child_hash <= parent_hash) break;
- NoIncrementalWriteBarrierSwapDescriptors(parent_index, child_index);
+ SwapSortedKeys(parent_index, child_index);
parent_index = child_index;
}
}
+ ASSERT(IsSortedNoDuplicates());
}
-void DescriptorArray::Sort(const WhitenessWitness& witness) {
- SortUnchecked(witness);
- SLOW_ASSERT(IsSortedNoDuplicates());
-}
-
-
-int DescriptorArray::BinarySearch(String* name, int low, int high) {
- uint32_t hash = name->Hash();
- int limit = high;
-
- ASSERT(low <= high);
-
- while (low != high) {
- int mid = (low + high) / 2;
- String* mid_name = GetKey(mid);
- uint32_t mid_hash = mid_name->Hash();
-
- if (mid_hash >= hash) {
- high = mid;
- } else {
- low = mid + 1;
- }
- }
-
- for (; low <= limit && GetKey(low)->Hash() == hash; ++low) {
- if (GetKey(low)->Equals(name) && !IsNullDescriptor(low))
- return low;
- }
-
- return kNotFound;
-}
-
-
-int DescriptorArray::LinearSearch(SearchMode mode, String* name, int len) {
- uint32_t hash = name->Hash();
- for (int number = 0; number < len; number++) {
- String* entry = GetKey(number);
- if (mode == EXPECT_SORTED && entry->Hash() > hash) break;
- if (name->Equals(entry) && !IsNullDescriptor(number)) {
- return number;
- }
- }
- return kNotFound;
-}
-
-
-MaybeObject* AccessorPair::CopyWithoutTransitions() {
+MaybeObject* AccessorPair::Copy() {
Heap* heap = GetHeap();
AccessorPair* copy;
- { MaybeObject* maybe_copy = heap->AllocateAccessorPair();
- if (!maybe_copy->To(&copy)) return maybe_copy;
- }
- copy->set_getter(getter()->IsMap() ? heap->the_hole_value() : getter());
- copy->set_setter(setter()->IsMap() ? heap->the_hole_value() : setter());
+ MaybeObject* maybe_copy = heap->AllocateAccessorPair();
+ if (!maybe_copy->To(&copy)) return maybe_copy;
+
+ copy->set_getter(getter());
+ copy->set_setter(setter());
return copy;
}
@@ -7283,7 +7322,6 @@ void StringHasher::AddSurrogatePairNoIndex(uc32 c) {
uint32_t StringHasher::GetHashField() {
- ASSERT(is_valid());
if (length_ <= String::kMaxHashCalcLength) {
if (is_array_index()) {
return MakeArrayIndexHash(array_index(), length_);
@@ -7338,81 +7376,117 @@ void String::PrintOn(FILE* file) {
}
+static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) {
+ int live_enum = map->EnumLength();
+ if (live_enum == Map::kInvalidEnumCache) {
+ live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
+ }
+ if (live_enum == 0) return descriptors->ClearEnumCache();
+
+ FixedArray* enum_cache = descriptors->GetEnumCache();
+
+ int to_trim = enum_cache->length() - live_enum;
+ if (to_trim <= 0) return;
+ RightTrimFixedArray<FROM_GC>(heap, descriptors->GetEnumCache(), to_trim);
+
+ if (!descriptors->HasEnumIndicesCache()) return;
+ FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache();
+ RightTrimFixedArray<FROM_GC>(heap, enum_indices_cache, to_trim);
+}
+
+
+static void TrimDescriptorArray(Heap* heap,
+ Map* map,
+ DescriptorArray* descriptors,
+ int number_of_own_descriptors) {
+ int number_of_descriptors = descriptors->number_of_descriptors();
+ int to_trim = number_of_descriptors - number_of_own_descriptors;
+ if (to_trim <= 0) return;
+
+ RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim);
+ descriptors->SetNumberOfDescriptors(number_of_own_descriptors);
+
+ if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors);
+ descriptors->Sort();
+}
+
+
// Clear a possible back pointer in case the transition leads to a dead map.
// Return true in case a back pointer has been cleared and false otherwise.
-static bool ClearBackPointer(Heap* heap, Object* target) {
- ASSERT(target->IsMap());
- Map* map = Map::cast(target);
- if (Marking::MarkBitFrom(map).Get()) return false;
- map->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER);
+static bool ClearBackPointer(Heap* heap, Map* target) {
+ if (Marking::MarkBitFrom(target).Get()) return false;
+ target->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER);
return true;
}
+// TODO(mstarzinger): This method should be moved into MarkCompactCollector,
+// because it cannot be called from outside the GC and we already have methods
+// depending on the transitions layout in the GC anyways.
void Map::ClearNonLiveTransitions(Heap* heap) {
- DescriptorArray* d = DescriptorArray::cast(
- *RawField(this, Map::kInstanceDescriptorsOrBitField3Offset));
- if (d->IsEmpty()) return;
- Smi* NullDescriptorDetails =
- PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi();
- for (int i = 0; i < d->number_of_descriptors(); ++i) {
- // If the pair (value, details) is a map transition, check if the target is
- // live. If not, null the descriptor. Also drop the back pointer for that
- // map transition, so that this map is not reached again by following a back
- // pointer from that non-live map.
- bool keep_entry = false;
- PropertyDetails details(d->GetDetails(i));
- switch (details.type()) {
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- keep_entry = !ClearBackPointer(heap, d->GetValue(i));
- break;
- case CALLBACKS: {
- Object* object = d->GetValue(i);
- if (object->IsAccessorPair()) {
- AccessorPair* accessors = AccessorPair::cast(object);
- Object* getter = accessors->getter();
- if (getter->IsMap()) {
- if (ClearBackPointer(heap, getter)) {
- accessors->set_getter(heap->the_hole_value());
- } else {
- keep_entry = true;
- }
- } else if (!getter->IsTheHole()) {
- keep_entry = true;
- }
- Object* setter = accessors->setter();
- if (setter->IsMap()) {
- if (ClearBackPointer(heap, setter)) {
- accessors->set_setter(heap->the_hole_value());
- } else {
- keep_entry = true;
- }
- } else if (!setter->IsTheHole()) {
- keep_entry = true;
- }
- } else {
- keep_entry = true;
- }
- break;
+ // If there are no transitions to be cleared, return.
+ // TODO(verwaest) Should be an assert, otherwise back pointers are not
+ // properly cleared.
+ if (!HasTransitionArray()) return;
+
+ TransitionArray* t = transitions();
+ MarkCompactCollector* collector = heap->mark_compact_collector();
+
+ int transition_index = 0;
+
+ DescriptorArray* descriptors = instance_descriptors();
+ bool descriptors_owner_died = false;
+
+ // Compact all live descriptors to the left.
+ for (int i = 0; i < t->number_of_transitions(); ++i) {
+ Map* target = t->GetTarget(i);
+ if (ClearBackPointer(heap, target)) {
+ if (target->instance_descriptors() == descriptors) {
+ descriptors_owner_died = true;
+ descriptors_owner_died = true;
}
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case HANDLER:
- case INTERCEPTOR:
- case NULL_DESCRIPTOR:
- keep_entry = true;
- break;
+ } else {
+ if (i != transition_index) {
+ String* key = t->GetKey(i);
+ t->SetKey(transition_index, key);
+ Object** key_slot = t->GetKeySlot(transition_index);
+ collector->RecordSlot(key_slot, key_slot, key);
+ // Target slots do not need to be recorded since maps are not compacted.
+ t->SetTarget(transition_index, t->GetTarget(i));
+ }
+ transition_index++;
+ }
+ }
+
+ if (t->HasElementsTransition() &&
+ ClearBackPointer(heap, t->elements_transition())) {
+ if (t->elements_transition()->instance_descriptors() == descriptors) {
+ descriptors_owner_died = true;
}
- // Make sure that an entry containing only dead transitions gets collected.
- // What we *really* want to do here is removing this entry completely, but
- // for technical reasons we can't do this, so we zero it out instead.
- if (!keep_entry) {
- d->SetDetailsUnchecked(i, NullDescriptorDetails);
- d->SetNullValueUnchecked(i, heap);
+ t->ClearElementsTransition();
+ } else {
+ // If there are no transitions to be cleared, return.
+ // TODO(verwaest) Should be an assert, otherwise back pointers are not
+ // properly cleared.
+ if (transition_index == t->number_of_transitions()) return;
+ }
+
+ int number_of_own_descriptors = NumberOfOwnDescriptors();
+
+ if (descriptors_owner_died) {
+ if (number_of_own_descriptors > 0) {
+ TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors);
+ ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
+ } else {
+ ASSERT(descriptors == GetHeap()->empty_descriptor_array());
}
}
+
+ int trim = t->number_of_transitions() - transition_index;
+ if (trim > 0) {
+ RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition()
+ ? trim : trim * TransitionArray::kTransitionSize);
+ }
}
@@ -7445,8 +7519,7 @@ bool Map::EquivalentToForNormalization(Map* other,
instance_type() == other->instance_type() &&
bit_field() == other->bit_field() &&
bit_field2() == other->bit_field2() &&
- (bit_field3() & ~(1<<Map::kIsShared)) ==
- (other->bit_field3() & ~(1<<Map::kIsShared));
+ function_with_prototype() == other->function_with_prototype();
}
@@ -7467,13 +7540,19 @@ void JSFunction::MarkForLazyRecompilation() {
ReplaceCode(builtins->builtin(Builtins::kLazyRecompile));
}
+void JSFunction::MarkForParallelRecompilation() {
+ ASSERT(is_compiled() && !IsOptimized());
+ ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
+ Builtins* builtins = GetIsolate()->builtins();
+ ReplaceCode(builtins->builtin(Builtins::kParallelRecompile));
-bool SharedFunctionInfo::EnsureCompiled(Handle<SharedFunctionInfo> shared,
- ClearExceptionFlag flag) {
- return shared->is_compiled() || CompileLazy(shared, flag);
+ // Unlike MarkForLazyRecompilation, after queuing a function for
+ // recompilation on the compiler thread, we actually tail-call into
+ // the full code. We reset the profiler ticks here so that the
+ // function doesn't bother the runtime profiler too much.
+ shared()->code()->set_profiler_ticks(0);
}
-
static bool CompileLazyHelper(CompilationInfo* info,
ClearExceptionFlag flag) {
// Compile the source information to a code object.
@@ -7490,11 +7569,77 @@ static bool CompileLazyHelper(CompilationInfo* info,
bool SharedFunctionInfo::CompileLazy(Handle<SharedFunctionInfo> shared,
ClearExceptionFlag flag) {
- CompilationInfo info(shared);
+ ASSERT(shared->allows_lazy_compilation_without_context());
+ CompilationInfoWithZone info(shared);
return CompileLazyHelper(&info, flag);
}
+void SharedFunctionInfo::ClearOptimizedCodeMap() {
+ set_optimized_code_map(Smi::FromInt(0));
+}
+
+
+void SharedFunctionInfo::AddToOptimizedCodeMap(
+ Handle<SharedFunctionInfo> shared,
+ Handle<Context> native_context,
+ Handle<Code> code,
+ Handle<FixedArray> literals) {
+ ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
+ ASSERT(native_context->IsNativeContext());
+ STATIC_ASSERT(kEntryLength == 3);
+ Object* value = shared->optimized_code_map();
+ Handle<FixedArray> new_code_map;
+ if (value->IsSmi()) {
+ // No optimized code map.
+ ASSERT_EQ(0, Smi::cast(value)->value());
+ // Crate 3 entries per context {context, code, literals}.
+ new_code_map = FACTORY->NewFixedArray(kEntryLength);
+ new_code_map->set(0, *native_context);
+ new_code_map->set(1, *code);
+ new_code_map->set(2, *literals);
+ } else {
+ // Copy old map and append one new entry.
+ Handle<FixedArray> old_code_map(FixedArray::cast(value));
+ ASSERT_EQ(-1, shared->SearchOptimizedCodeMap(*native_context));
+ int old_length = old_code_map->length();
+ int new_length = old_length + kEntryLength;
+ new_code_map = FACTORY->NewFixedArray(new_length);
+ old_code_map->CopyTo(0, *new_code_map, 0, old_length);
+ new_code_map->set(old_length, *native_context);
+ new_code_map->set(old_length + 1, *code);
+ new_code_map->set(old_length + 2, *literals);
+ }
+#ifdef DEBUG
+ for (int i = 0; i < new_code_map->length(); i += kEntryLength) {
+ ASSERT(new_code_map->get(i)->IsNativeContext());
+ ASSERT(new_code_map->get(i + 1)->IsCode());
+ ASSERT(Code::cast(new_code_map->get(i + 1))->kind() ==
+ Code::OPTIMIZED_FUNCTION);
+ ASSERT(new_code_map->get(i + 2)->IsFixedArray());
+ }
+#endif
+ shared->set_optimized_code_map(*new_code_map);
+}
+
+
+void SharedFunctionInfo::InstallFromOptimizedCodeMap(JSFunction* function,
+ int index) {
+ ASSERT(index > 0);
+ ASSERT(optimized_code_map()->IsFixedArray());
+ FixedArray* code_map = FixedArray::cast(optimized_code_map());
+ if (!bound()) {
+ FixedArray* cached_literals = FixedArray::cast(code_map->get(index + 1));
+ ASSERT(cached_literals != NULL);
+ function->set_literals(cached_literals);
+ }
+ Code* code = Code::cast(code_map->get(index));
+ ASSERT(code != NULL);
+ ASSERT(function->context()->native_context() == code_map->get(index - 1));
+ function->ReplaceCode(code);
+}
+
+
bool JSFunction::CompileLazy(Handle<JSFunction> function,
ClearExceptionFlag flag) {
bool result = true;
@@ -7502,7 +7647,8 @@ bool JSFunction::CompileLazy(Handle<JSFunction> function,
function->ReplaceCode(function->shared()->code());
function->shared()->set_code_age(0);
} else {
- CompilationInfo info(function);
+ ASSERT(function->shared()->allows_lazy_compilation());
+ CompilationInfoWithZone info(function);
result = CompileLazyHelper(&info, flag);
ASSERT(!result || function->is_compiled());
}
@@ -7511,14 +7657,20 @@ bool JSFunction::CompileLazy(Handle<JSFunction> function,
bool JSFunction::CompileOptimized(Handle<JSFunction> function,
- int osr_ast_id,
+ BailoutId osr_ast_id,
ClearExceptionFlag flag) {
- CompilationInfo info(function);
+ CompilationInfoWithZone info(function);
info.SetOptimizing(osr_ast_id);
return CompileLazyHelper(&info, flag);
}
+bool JSFunction::EnsureCompiled(Handle<JSFunction> function,
+ ClearExceptionFlag flag) {
+ return function->is_compiled() || CompileLazy(function, flag);
+}
+
+
bool JSFunction::IsInlineable() {
if (IsBuiltin()) return false;
SharedFunctionInfo* shared_info = shared();
@@ -7564,12 +7716,10 @@ MaybeObject* JSFunction::SetInstancePrototype(Object* value) {
// If the function has allocated the initial map
// replace it with a copy containing the new prototype.
Map* new_map;
- MaybeObject* maybe_new_map =
- initial_map()->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
+ MaybeObject* maybe_new_map = initial_map()->Copy();
if (!maybe_new_map->To(&new_map)) return maybe_new_map;
new_map->set_prototype(value);
- MaybeObject* maybe_object =
- set_initial_map_and_cache_transitions(new_map);
+ MaybeObject* maybe_object = set_initial_map_and_cache_transitions(new_map);
if (maybe_object->IsFailure()) return maybe_object;
} else {
// Put the value in the initial map field until an initial map is
@@ -7595,16 +7745,15 @@ MaybeObject* JSFunction::SetPrototype(Object* value) {
// Remove map transitions because they point to maps with a
// different prototype.
Map* new_map;
- { MaybeObject* maybe_new_map =
- map()->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- }
+ MaybeObject* maybe_new_map = map()->Copy();
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+
Heap* heap = new_map->GetHeap();
set_map(new_map);
new_map->set_constructor(value);
new_map->set_non_instance_prototype(true);
construct_prototype =
- heap->isolate()->context()->global_context()->
+ heap->isolate()->context()->native_context()->
initial_object_prototype();
} else {
map()->set_non_instance_prototype(false);
@@ -7614,30 +7763,25 @@ MaybeObject* JSFunction::SetPrototype(Object* value) {
}
-Object* JSFunction::RemovePrototype() {
- Context* global_context = context()->global_context();
+void JSFunction::RemovePrototype() {
+ Context* native_context = context()->native_context();
Map* no_prototype_map = shared()->is_classic_mode()
- ? global_context->function_without_prototype_map()
- : global_context->strict_mode_function_without_prototype_map();
+ ? native_context->function_without_prototype_map()
+ : native_context->strict_mode_function_without_prototype_map();
- if (map() == no_prototype_map) {
- // Be idempotent.
- return this;
- }
+ if (map() == no_prototype_map) return;
ASSERT(map() == (shared()->is_classic_mode()
- ? global_context->function_map()
- : global_context->strict_mode_function_map()));
+ ? native_context->function_map()
+ : native_context->strict_mode_function_map()));
set_map(no_prototype_map);
set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
- return this;
}
-Object* JSFunction::SetInstanceClassName(String* name) {
+void JSFunction::SetInstanceClassName(String* name) {
shared()->set_instance_class_name(name);
- return this;
}
@@ -7647,8 +7791,8 @@ void JSFunction::PrintName(FILE* out) {
}
-Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) {
- return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex));
+Context* JSFunction::NativeContextFromLiterals(FixedArray* literals) {
+ return Context::cast(literals->get(JSFunction::kLiteralNativeContextIndex));
}
@@ -7716,26 +7860,33 @@ bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) {
return false;
}
- // If the prototype is null inline constructors cause no problems.
- if (!prototype->IsJSObject()) {
- ASSERT(prototype->IsNull());
- return true;
- }
-
Heap* heap = GetHeap();
- // Traverse the proposed prototype chain looking for setters for properties of
- // the same names as are set by the inline constructor.
+ // Traverse the proposed prototype chain looking for properties of the
+ // same names as are set by the inline constructor.
for (Object* obj = prototype;
obj != heap->null_value();
obj = obj->GetPrototype()) {
- JSObject* js_object = JSObject::cast(obj);
+ JSReceiver* receiver = JSReceiver::cast(obj);
for (int i = 0; i < this_property_assignments_count(); i++) {
LookupResult result(heap->isolate());
String* name = GetThisPropertyAssignmentName(i);
- js_object->LocalLookupRealNamedProperty(name, &result);
- if (result.IsFound() && result.type() == CALLBACKS) {
- return false;
+ receiver->LocalLookup(name, &result);
+ if (result.IsFound()) {
+ switch (result.type()) {
+ case NORMAL:
+ case FIELD:
+ case CONSTANT_FUNCTION:
+ break;
+ case INTERCEPTOR:
+ case CALLBACKS:
+ case HANDLER:
+ return false;
+ case TRANSITION:
+ case NONEXISTENT:
+ UNREACHABLE();
+ break;
+ }
}
}
}
@@ -7880,7 +8031,7 @@ void SharedFunctionInfo::EnableDeoptimizationSupport(Code* recompiled) {
}
-void SharedFunctionInfo::DisableOptimization() {
+void SharedFunctionInfo::DisableOptimization(const char* reason) {
// Disable optimization for the shared function info and mark the
// code as non-optimizable. The marker on the shared function info
// is there because we flush non-optimized code thereby loosing the
@@ -7896,13 +8047,14 @@ void SharedFunctionInfo::DisableOptimization() {
code()->set_optimizable(false);
}
if (FLAG_trace_opt) {
- PrintF("[disabled optimization for %s]\n", *DebugName()->ToCString());
+ PrintF("[disabled optimization for %s, reason: %s]\n",
+ *DebugName()->ToCString(), reason);
}
}
-bool SharedFunctionInfo::VerifyBailoutId(int id) {
- ASSERT(id != AstNode::kNoNumber);
+bool SharedFunctionInfo::VerifyBailoutId(BailoutId id) {
+ ASSERT(!id.IsNone());
Code* unoptimized = code();
DeoptimizationOutputData* data =
DeoptimizationOutputData::cast(unoptimized->deoptimization_data());
@@ -7985,7 +8137,7 @@ void SharedFunctionInfo::ResetForNewContext(int new_ic_age) {
if (code()->kind() == Code::FUNCTION) {
code()->set_profiler_ticks(0);
if (optimization_disabled() &&
- opt_count() >= Compiler::kDefaultMaxOptCount) {
+ opt_count() >= FLAG_max_opt_count) {
// Re-enable optimizations if they were disabled due to opt_count limit.
set_optimization_disabled(false);
code()->set_optimizable(true);
@@ -8039,9 +8191,20 @@ void SharedFunctionInfo::CompleteInobjectSlackTracking() {
}
-void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) {
- v->VisitSharedFunctionInfo(this);
- SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
+int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context) {
+ ASSERT(native_context->IsNativeContext());
+ if (!FLAG_cache_optimized_code) return -1;
+ Object* value = optimized_code_map();
+ if (!value->IsSmi()) {
+ FixedArray* optimized_code_map = FixedArray::cast(value);
+ int length = optimized_code_map->length();
+ for (int i = 0; i < length; i += 3) {
+ if (optimized_code_map->get(i) == native_context) {
+ return i + 1;
+ }
+ }
+ }
+ return -1;
}
@@ -8269,7 +8432,6 @@ void Code::ClearTypeFeedbackCells(Heap* heap) {
TypeFeedbackCells* type_feedback_cells =
TypeFeedbackInfo::cast(raw_info)->type_feedback_cells();
for (int i = 0; i < type_feedback_cells->CellCount(); i++) {
- ASSERT(type_feedback_cells->AstId(i)->IsSmi());
JSGlobalPropertyCell* cell = type_feedback_cells->Cell(i);
cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap));
}
@@ -8296,7 +8458,7 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
for (int i = 0; i < deopt_count; i++) {
PrintF(out, "%6d %6d %6d %6d",
i,
- AstId(i)->value(),
+ AstId(i).ToInt(),
ArgumentsStackHeight(i)->value(),
Pc(i)->value());
@@ -8330,11 +8492,14 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
case Translation::JS_FRAME: {
int ast_id = iterator.Next();
int function_id = iterator.Next();
- JSFunction* function =
- JSFunction::cast(LiteralArray()->get(function_id));
unsigned height = iterator.Next();
PrintF(out, "{ast_id=%d, function=", ast_id);
- function->PrintName(out);
+ if (function_id != Translation::kSelfLiteralId) {
+ Object* function = LiteralArray()->get(function_id);
+ JSFunction::cast(function)->PrintName(out);
+ } else {
+ PrintF(out, "<self>");
+ }
PrintF(out, ", height=%u}", height);
break;
}
@@ -8351,6 +8516,17 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
break;
}
+ case Translation::GETTER_STUB_FRAME:
+ case Translation::SETTER_STUB_FRAME: {
+ int function_id = iterator.Next();
+ JSFunction* function =
+ JSFunction::cast(LiteralArray()->get(function_id));
+ PrintF(out, "{function=");
+ function->PrintName(out);
+ PrintF(out, "}");
+ break;
+ }
+
case Translation::DUPLICATE:
break;
@@ -8366,6 +8542,14 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
break;
}
+ case Translation::UINT32_REGISTER: {
+ int reg_code = iterator.Next();
+ PrintF(out,
+ "{input=%s (unsigned)}",
+ converter.NameOfCPURegister(reg_code));
+ break;
+ }
+
case Translation::DOUBLE_REGISTER: {
int reg_code = iterator.Next();
PrintF(out, "{input=%s}",
@@ -8385,6 +8569,12 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
break;
}
+ case Translation::UINT32_STACK_SLOT: {
+ int input_slot_index = iterator.Next();
+ PrintF(out, "{input=%d (unsigned)}", input_slot_index);
+ break;
+ }
+
case Translation::DOUBLE_STACK_SLOT: {
int input_slot_index = iterator.Next();
PrintF(out, "{input=%d}", input_slot_index);
@@ -8415,7 +8605,7 @@ void DeoptimizationOutputData::DeoptimizationOutputDataPrint(FILE* out) {
for (int i = 0; i < this->DeoptPoints(); i++) {
int pc_and_state = this->PcAndState(i)->value();
PrintF("%6d %8d %s\n",
- this->AstId(i)->value(),
+ this->AstId(i).ToInt(),
FullCodeGenerator::PcField::decode(pc_and_state),
FullCodeGenerator::State2String(
FullCodeGenerator::StateField::decode(pc_and_state)));
@@ -8461,17 +8651,15 @@ const char* Code::ICState2String(InlineCacheState state) {
}
-const char* Code::PropertyType2String(PropertyType type) {
+const char* Code::StubType2String(StubType type) {
switch (type) {
case NORMAL: return "NORMAL";
case FIELD: return "FIELD";
case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION";
case CALLBACKS: return "CALLBACKS";
- case HANDLER: return "HANDLER";
case INTERCEPTOR: return "INTERCEPTOR";
case MAP_TRANSITION: return "MAP_TRANSITION";
- case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION";
- case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR";
+ case NONEXISTENT: return "NONEXISTENT";
}
UNREACHABLE(); // keep the compiler happy
return NULL;
@@ -8509,7 +8697,7 @@ void Code::Disassemble(const char* name, FILE* out) {
PrintF(out, "ic_state = %s\n", ICState2String(ic_state()));
PrintExtraICState(out, kind(), extra_ic_state());
if (ic_state() == MONOMORPHIC) {
- PrintF(out, "type = %s\n", PropertyType2String(type()));
+ PrintF(out, "type = %s\n", StubType2String(type()));
}
if (is_call_stub() || is_keyed_call_stub()) {
PrintF(out, "argc = %d\n", arguments_count());
@@ -8565,6 +8753,8 @@ void Code::Disassemble(const char* name, FILE* out) {
PrintF(out, "\n");
}
PrintF(out, "\n");
+ // Just print if type feedback info is ever used for optimized code.
+ ASSERT(type_feedback_info()->IsUndefined());
} else if (kind() == FUNCTION) {
unsigned offset = stack_check_table_offset();
// If there is no stack check table, the "table start" will at or after
@@ -8581,6 +8771,12 @@ void Code::Disassemble(const char* name, FILE* out) {
}
PrintF(out, "\n");
}
+#ifdef OBJECT_PRINT
+ if (!type_feedback_info()->IsUndefined()) {
+ TypeFeedbackInfo::cast(type_feedback_info())->TypeFeedbackInfoPrint(out);
+ PrintF(out, "\n");
+ }
+#endif
}
PrintF("RelocInfo (size = %d)\n", relocation_size());
@@ -8740,7 +8936,7 @@ MaybeObject* JSArray::SetElementsLength(Object* len) {
Map* Map::GetPrototypeTransition(Object* prototype) {
- FixedArray* cache = prototype_transitions();
+ FixedArray* cache = GetPrototypeTransitions();
int number_of_transitions = NumberOfProtoTransitions();
const int proto_offset =
kProtoTransitionHeaderSize + kProtoTransitionPrototypeOffset;
@@ -8762,7 +8958,7 @@ MaybeObject* Map::PutPrototypeTransition(Object* prototype, Map* map) {
// Don't cache prototype transition if this map is shared.
if (is_shared() || !FLAG_cache_prototype_transitions) return this;
- FixedArray* cache = prototype_transitions();
+ FixedArray* cache = GetPrototypeTransitions();
const int step = kProtoTransitionElementsPerEntry;
const int header = kProtoTransitionHeaderSize;
@@ -8785,7 +8981,8 @@ MaybeObject* Map::PutPrototypeTransition(Object* prototype, Map* map) {
new_cache->set(i + header, cache->get(i + header));
}
cache = new_cache;
- set_prototype_transitions(cache);
+ MaybeObject* set_result = SetPrototypeTransitions(cache);
+ if (set_result->IsFailure()) return set_result;
}
int last = transitions - 1;
@@ -8798,6 +8995,22 @@ MaybeObject* Map::PutPrototypeTransition(Object* prototype, Map* map) {
}
+void Map::ZapTransitions() {
+ TransitionArray* transition_array = transitions();
+ MemsetPointer(transition_array->data_start(),
+ GetHeap()->the_hole_value(),
+ transition_array->length());
+}
+
+
+void Map::ZapPrototypeTransitions() {
+ FixedArray* proto_transitions = GetPrototypeTransitions();
+ MemsetPointer(proto_transitions->data_start(),
+ GetHeap()->the_hole_value(),
+ proto_transitions->length());
+}
+
+
MaybeObject* JSReceiver::SetPrototype(Object* value,
bool skip_hidden_prototypes) {
#ifdef DEBUG
@@ -8864,15 +9077,12 @@ MaybeObject* JSReceiver::SetPrototype(Object* value,
Map* new_map = map->GetPrototypeTransition(value);
if (new_map == NULL) {
- { MaybeObject* maybe_new_map =
- map->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- }
+ MaybeObject* maybe_new_map = map->Copy();
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- { MaybeObject* maybe_new_cache =
- map->PutPrototypeTransition(value, new_map);
- if (maybe_new_cache->IsFailure()) return maybe_new_cache;
- }
+ MaybeObject* maybe_new_cache =
+ map->PutPrototypeTransition(value, new_map);
+ if (maybe_new_cache->IsFailure()) return maybe_new_cache;
new_map->set_prototype(value);
}
@@ -9152,6 +9362,7 @@ MaybeObject* JSObject::GetElementWithCallback(Object* receiver,
Handle<AccessorInfo> data(AccessorInfo::cast(structure));
Object* fun_obj = data->getter();
v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
+ if (call_fun == NULL) return isolate->heap()->undefined_value();
HandleScope scope(isolate);
Handle<JSObject> self(JSObject::cast(receiver));
Handle<JSObject> holder_handle(JSObject::cast(holder));
@@ -9168,7 +9379,9 @@ MaybeObject* JSObject::GetElementWithCallback(Object* receiver,
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (result.IsEmpty()) return isolate->heap()->undefined_value();
- return *v8::Utils::OpenHandle(*result);
+ Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
+ result_internal->VerifyApiCallResultType();
+ return *result_internal;
}
// __defineGetter__ callback
@@ -9432,7 +9645,8 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
// is read-only (a declared const that has not been initialized). If a
// value is being defined we skip attribute checks completely.
if (set_mode == DEFINE_PROPERTY) {
- details = PropertyDetails(attributes, NORMAL, details.index());
+ details = PropertyDetails(
+ attributes, NORMAL, details.dictionary_index());
dictionary->DetailsAtPut(entry, details);
} else if (details.IsReadOnly() && !element->IsTheHole()) {
if (strict_mode == kNonStrictMode) {
@@ -9722,8 +9936,9 @@ MaybeObject* JSObject::SetElement(uint32_t index,
// Don't allow element properties to be redefined for external arrays.
if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) {
Isolate* isolate = GetHeap()->isolate();
+ Handle<Object> receiver(this);
Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
- Handle<Object> args[] = { Handle<Object>(this), number };
+ Handle<Object> args[] = { receiver, number };
Handle<Object> error = isolate->factory()->NewTypeError(
"redef_external_array_element", HandleVector(args, ARRAY_SIZE(args)));
return isolate->Throw(*error);
@@ -9985,7 +10200,11 @@ MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver,
result = getter(index, info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
- if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
+ if (!result.IsEmpty()) {
+ Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
+ result_internal->VerifyApiCallResultType();
+ return *result_internal;
+ }
}
Heap* heap = holder_handle->GetHeap();
@@ -10229,13 +10448,13 @@ InterceptorInfo* JSObject::GetIndexedInterceptor() {
MaybeObject* JSObject::GetPropertyPostInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
LookupResult result(GetIsolate());
LocalLookupRealNamedProperty(name, &result);
- if (result.IsProperty()) {
+ if (result.IsFound()) {
return GetProperty(receiver, &result, name, attributes);
}
// Continue searching via the prototype chain.
@@ -10247,13 +10466,13 @@ MaybeObject* JSObject::GetPropertyPostInterceptor(
MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
LookupResult result(GetIsolate());
LocalLookupRealNamedProperty(name, &result);
- if (result.IsProperty()) {
+ if (result.IsFound()) {
return GetProperty(receiver, &result, name, attributes);
}
return GetHeap()->undefined_value();
@@ -10261,13 +10480,13 @@ MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
MaybeObject* JSObject::GetPropertyWithInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes) {
Isolate* isolate = GetIsolate();
InterceptorInfo* interceptor = GetNamedInterceptor();
HandleScope scope(isolate);
- Handle<JSReceiver> receiver_handle(receiver);
+ Handle<Object> receiver_handle(receiver);
Handle<JSObject> holder_handle(this);
Handle<String> name_handle(name);
@@ -10287,7 +10506,9 @@ MaybeObject* JSObject::GetPropertyWithInterceptor(
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!result.IsEmpty()) {
*attributes = NONE;
- return *v8::Utils::OpenHandle(*result);
+ Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
+ result_internal->VerifyApiCallResultType();
+ return *result_internal;
}
}
@@ -10312,7 +10533,7 @@ bool JSObject::HasRealNamedProperty(String* key) {
LookupResult result(isolate);
LocalLookupRealNamedProperty(key, &result);
- return result.IsProperty() && (result.type() != INTERCEPTOR);
+ return result.IsFound() && !result.IsInterceptor();
}
@@ -10392,14 +10613,21 @@ bool JSObject::HasRealNamedCallbackProperty(String* key) {
LookupResult result(isolate);
LocalLookupRealNamedProperty(key, &result);
- return result.IsFound() && (result.type() == CALLBACKS);
+ return result.IsPropertyCallbacks();
}
int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
- return HasFastProperties() ?
- map()->NumberOfDescribedProperties(filter) :
- property_dictionary()->NumberOfElementsFilterAttributes(filter);
+ if (HasFastProperties()) {
+ Map* map = this->map();
+ if (filter == NONE) return map->NumberOfOwnDescriptors();
+ if (filter == DONT_ENUM) {
+ int result = map->EnumLength();
+ if (result != Map::kInvalidEnumCache) return result;
+ }
+ return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter);
+ }
+ return property_dictionary()->NumberOfElementsFilterAttributes(filter);
}
@@ -10522,11 +10750,12 @@ void FixedArray::SortPairs(FixedArray* numbers, uint32_t len) {
void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) {
ASSERT(storage->length() >= (NumberOfLocalProperties() - index));
if (HasFastProperties()) {
+ int real_size = map()->NumberOfOwnDescriptors();
DescriptorArray* descs = map()->instance_descriptors();
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
- if (descs->IsProperty(i)) storage->set(index++, descs->GetKey(i));
+ ASSERT(storage->length() >= index + real_size);
+ for (int i = 0; i < real_size; i++) {
+ storage->set(index + i, descs->GetKey(i));
}
- ASSERT(storage->length() >= index);
} else {
property_dictionary()->CopyKeysTo(storage,
index,
@@ -11096,8 +11325,12 @@ void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) {
template<typename Shape, typename Key>
MaybeObject* HashTable<Shape, Key>::Allocate(int at_least_space_for,
+ MinimumCapacity capacity_option,
PretenureFlag pretenure) {
- int capacity = ComputeCapacity(at_least_space_for);
+ ASSERT(!capacity_option || IS_POWER_OF_TWO(at_least_space_for));
+ int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
+ ? at_least_space_for
+ : ComputeCapacity(at_least_space_for);
if (capacity > HashTable::kMaxCapacity) {
return Failure::OutOfMemoryException();
}
@@ -11154,30 +11387,6 @@ int StringDictionary::FindEntry(String* key) {
}
-bool StringDictionary::ContainsTransition(int entry) {
- switch (DetailsAt(entry).type()) {
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- return true;
- case CALLBACKS: {
- Object* value = ValueAt(entry);
- if (!value->IsAccessorPair()) return false;
- AccessorPair* accessors = AccessorPair::cast(value);
- return accessors->getter()->IsMap() || accessors->setter()->IsMap();
- }
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case HANDLER:
- case INTERCEPTOR:
- case NULL_DESCRIPTOR:
- return false;
- }
- UNREACHABLE(); // Keep the compiler happy.
- return false;
-}
-
-
template<typename Shape, typename Key>
MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) {
ASSERT(NumberOfElements() < new_table->Capacity());
@@ -11230,7 +11439,9 @@ MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
(capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this);
Object* obj;
{ MaybeObject* maybe_obj =
- Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED);
+ Allocate(nof * 2,
+ USE_DEFAULT_MINIMUM_CAPACITY,
+ pretenure ? TENURED : NOT_TENURED);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
@@ -11259,7 +11470,9 @@ MaybeObject* HashTable<Shape, Key>::Shrink(Key key) {
!GetHeap()->InNewSpace(this);
Object* obj;
{ MaybeObject* maybe_obj =
- Allocate(at_least_room_for, pretenure ? TENURED : NOT_TENURED);
+ Allocate(at_least_room_for,
+ USE_DEFAULT_MINIMUM_CAPACITY,
+ pretenure ? TENURED : NOT_TENURED);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
@@ -11664,7 +11877,7 @@ Object* ExternalPixelArray::SetValue(uint32_t index, Object* value) {
clamped_value = 255;
} else {
// Other doubles are rounded to the nearest integer.
- clamped_value = static_cast<uint8_t>(double_value + 0.5);
+ clamped_value = static_cast<uint8_t>(lrint(double_value));
}
} else {
// Clamp undefined to zero (default). All other types have been
@@ -11868,7 +12081,7 @@ class TwoCharHashTableKey : public HashTableKey {
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
- if ((hash & String::kHashBitMask) == 0) hash = String::kZeroHash;
+ if ((hash & String::kHashBitMask) == 0) hash = StringHasher::kZeroHash;
#ifdef DEBUG
StringHasher hasher(2, seed);
hasher.AddCharacter(c1);
@@ -12004,8 +12217,23 @@ MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
}
-Object* CompilationCacheTable::Lookup(String* src) {
- StringKey key(src);
+// The key for the script compilation cache is dependent on the mode flags,
+// because they change the global language mode and thus binding behaviour.
+// If flags change at some point, we must ensure that we do not hit the cache
+// for code compiled with different settings.
+static LanguageMode CurrentGlobalLanguageMode() {
+ return FLAG_use_strict
+ ? (FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE)
+ : CLASSIC_MODE;
+}
+
+
+Object* CompilationCacheTable::Lookup(String* src, Context* context) {
+ SharedFunctionInfo* shared = context->closure()->shared();
+ StringSharedKey key(src,
+ shared,
+ CurrentGlobalLanguageMode(),
+ RelocInfo::kNoPosition);
int entry = FindEntry(&key);
if (entry == kNotFound) return GetHeap()->undefined_value();
return get(EntryToIndex(entry) + 1);
@@ -12035,17 +12263,24 @@ Object* CompilationCacheTable::LookupRegExp(String* src,
}
-MaybeObject* CompilationCacheTable::Put(String* src, Object* value) {
- StringKey key(src);
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
+MaybeObject* CompilationCacheTable::Put(String* src,
+ Context* context,
+ Object* value) {
+ SharedFunctionInfo* shared = context->closure()->shared();
+ StringSharedKey key(src,
+ shared,
+ CurrentGlobalLanguageMode(),
+ RelocInfo::kNoPosition);
+ CompilationCacheTable* cache;
+ MaybeObject* maybe_cache = EnsureCapacity(1, &key);
+ if (!maybe_cache->To(&cache)) return maybe_cache;
+
+ Object* k;
+ MaybeObject* maybe_k = key.AsObject();
+ if (!maybe_k->To(&k)) return maybe_k;
- CompilationCacheTable* cache =
- reinterpret_cast<CompilationCacheTable*>(obj);
int entry = cache->FindInsertionEntry(key.Hash());
- cache->set(EntryToIndex(entry), src);
+ cache->set(EntryToIndex(entry), k);
cache->set(EntryToIndex(entry) + 1, value);
cache->ElementAdded();
return cache;
@@ -12189,6 +12424,12 @@ MaybeObject* Dictionary<Shape, Key>::Allocate(int at_least_space_for) {
}
+void StringDictionary::DoGenerateNewEnumerationIndices(
+ Handle<StringDictionary> dictionary) {
+ CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(),
+ dictionary->GenerateNewEnumerationIndices());
+}
+
template<typename Shape, typename Key>
MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
Heap* heap = Dictionary<Shape, Key>::GetHeap();
@@ -12215,7 +12456,8 @@ MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
int pos = 0;
for (int i = 0; i < capacity; i++) {
if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) {
- enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index()));
+ int index = DetailsAt(i).dictionary_index();
+ enumeration_order->set(pos++, Smi::FromInt(index));
}
}
@@ -12314,6 +12556,8 @@ template<typename Shape, typename Key>
MaybeObject* Dictionary<Shape, Key>::Add(Key key,
Object* value,
PropertyDetails details) {
+ ASSERT(details.dictionary_index() == details.descriptor_index());
+
// Valdate key is absent.
SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound));
// Check whether the dictionary should be extended.
@@ -12341,7 +12585,9 @@ MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key,
uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash);
// Insert element at empty or deleted entry
- if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) {
+ if (!details.IsDeleted() &&
+ details.dictionary_index() == 0 &&
+ Shape::kIsEnumerable) {
// Assign an enumeration index to the property and update
// SetNextEnumerationIndex.
int index = NextEnumerationIndex();
@@ -12432,7 +12678,7 @@ MaybeObject* SeededNumberDictionary::Set(uint32_t key,
// Preserve enumeration index.
details = PropertyDetails(details.attributes(),
details.type(),
- DetailsAt(entry).index());
+ DetailsAt(entry).dictionary_index());
MaybeObject* maybe_object_key = SeededNumberDictionaryShape::AsObject(key);
Object* object_key;
if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
@@ -12503,23 +12749,45 @@ void Dictionary<Shape, Key>::CopyKeysTo(
}
-void StringDictionary::CopyEnumKeysTo(FixedArray* storage,
- FixedArray* sort_array) {
- ASSERT(storage->length() >= NumberOfEnumElements());
+FixedArray* StringDictionary::CopyEnumKeysTo(FixedArray* storage) {
+ int length = storage->length();
+ ASSERT(length >= NumberOfEnumElements());
+ Heap* heap = GetHeap();
+ Object* undefined_value = heap->undefined_value();
int capacity = Capacity();
- int index = 0;
+ int properties = 0;
+
+ // Fill in the enumeration array by assigning enumerable keys at their
+ // enumeration index. This will leave holes in the array if there are keys
+ // that are deleted or not enumerable.
for (int i = 0; i < capacity; i++) {
Object* k = KeyAt(i);
if (IsKey(k)) {
PropertyDetails details = DetailsAt(i);
if (details.IsDeleted() || details.IsDontEnum()) continue;
- storage->set(index, k);
- sort_array->set(index, Smi::FromInt(details.index()));
- index++;
+ properties++;
+ storage->set(details.dictionary_index() - 1, k);
+ if (properties == length) break;
}
}
- storage->SortPairs(sort_array, sort_array->length());
- ASSERT(storage->length() >= index);
+
+ // There are holes in the enumeration array if less properties were assigned
+ // than the length of the array. If so, crunch all the existing properties
+ // together by shifting them to the left (maintaining the enumeration order),
+ // and trimming of the right side of the array.
+ if (properties < length) {
+ if (properties == 0) return heap->empty_fixed_array();
+ properties = 0;
+ for (int i = 0; i < length; ++i) {
+ Object* value = storage->get(i);
+ if (value != undefined_value) {
+ storage->set(properties, value);
+ ++properties;
+ }
+ }
+ RightTrimFixedArray<FROM_MUTATOR>(heap, storage, length - properties);
+ }
+ return storage;
}
@@ -12569,18 +12837,12 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
JSObject* obj, int unused_property_fields) {
// Make sure we preserve dictionary representation if there are too many
// descriptors.
- if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj;
-
- // Figure out if it is necessary to generate new enumeration indices.
- int max_enumeration_index =
- NextEnumerationIndex() +
- (DescriptorArray::kMaxNumberOfDescriptors -
- NumberOfElements());
- if (!PropertyDetails::IsValidIndex(max_enumeration_index)) {
- Object* result;
- { MaybeObject* maybe_result = GenerateNewEnumerationIndices();
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ int number_of_elements = NumberOfElements();
+ if (number_of_elements > DescriptorArray::kMaxNumberOfDescriptors) return obj;
+
+ if (number_of_elements != NextEnumerationIndex()) {
+ MaybeObject* maybe_result = GenerateNewEnumerationIndices();
+ if (maybe_result->IsFailure()) return maybe_result;
}
int instance_descriptor_length = 0;
@@ -12604,19 +12866,35 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
}
}
+ int inobject_props = obj->map()->inobject_properties();
+
+ // Allocate new map.
+ Map* new_map;
+ MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors();
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+ new_map->set_dictionary_map(false);
+
+ if (instance_descriptor_length == 0) {
+ ASSERT_LE(unused_property_fields, inobject_props);
+ // Transform the object.
+ new_map->set_unused_property_fields(inobject_props);
+ obj->set_map(new_map);
+ obj->set_properties(heap->empty_fixed_array());
+ // Check that it really works.
+ ASSERT(obj->HasFastProperties());
+ return obj;
+ }
+
// Allocate the instance descriptor.
DescriptorArray* descriptors;
- { MaybeObject* maybe_descriptors =
- DescriptorArray::Allocate(instance_descriptor_length,
- DescriptorArray::MAY_BE_SHARED);
- if (!maybe_descriptors->To<DescriptorArray>(&descriptors)) {
- return maybe_descriptors;
- }
+ MaybeObject* maybe_descriptors =
+ DescriptorArray::Allocate(instance_descriptor_length);
+ if (!maybe_descriptors->To(&descriptors)) {
+ return maybe_descriptors;
}
DescriptorArray::WhitenessWitness witness(descriptors);
- int inobject_props = obj->map()->inobject_properties();
int number_of_allocated_fields =
number_of_fields + unused_property_fields - inobject_props;
if (number_of_allocated_fields < 0) {
@@ -12626,33 +12904,33 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
}
// Allocate the fixed array for the fields.
- Object* fields;
- { MaybeObject* maybe_fields =
- heap->AllocateFixedArray(number_of_allocated_fields);
- if (!maybe_fields->ToObject(&fields)) return maybe_fields;
- }
+ FixedArray* fields;
+ MaybeObject* maybe_fields =
+ heap->AllocateFixedArray(number_of_allocated_fields);
+ if (!maybe_fields->To(&fields)) return maybe_fields;
// Fill in the instance descriptor and the fields.
- int next_descriptor = 0;
int current_offset = 0;
for (int i = 0; i < capacity; i++) {
Object* k = KeyAt(i);
if (IsKey(k)) {
Object* value = ValueAt(i);
// Ensure the key is a symbol before writing into the instance descriptor.
- Object* key;
- { MaybeObject* maybe_key = heap->LookupSymbol(String::cast(k));
- if (!maybe_key->ToObject(&key)) return maybe_key;
- }
+ String* key;
+ MaybeObject* maybe_key = heap->LookupSymbol(String::cast(k));
+ if (!maybe_key->To(&key)) return maybe_key;
+
PropertyDetails details = DetailsAt(i);
+ ASSERT(details.descriptor_index() == details.dictionary_index());
+ int enumeration_index = details.descriptor_index();
PropertyType type = details.type();
if (value->IsJSFunction() && !heap->InNewSpace(value)) {
- ConstantFunctionDescriptor d(String::cast(key),
+ ConstantFunctionDescriptor d(key,
JSFunction::cast(value),
details.attributes(),
- details.index());
- descriptors->Set(next_descriptor++, &d, witness);
+ enumeration_index);
+ descriptors->Set(enumeration_index - 1, &d, witness);
} else if (type == NORMAL) {
if (current_offset < inobject_props) {
obj->InObjectPropertyAtPut(current_offset,
@@ -12660,24 +12938,19 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
UPDATE_WRITE_BARRIER);
} else {
int offset = current_offset - inobject_props;
- FixedArray::cast(fields)->set(offset, value);
+ fields->set(offset, value);
}
- FieldDescriptor d(String::cast(key),
+ FieldDescriptor d(key,
current_offset++,
details.attributes(),
- details.index());
- descriptors->Set(next_descriptor++, &d, witness);
+ enumeration_index);
+ descriptors->Set(enumeration_index - 1, &d, witness);
} else if (type == CALLBACKS) {
- if (value->IsAccessorPair()) {
- MaybeObject* maybe_copy =
- AccessorPair::cast(value)->CopyWithoutTransitions();
- if (!maybe_copy->To(&value)) return maybe_copy;
- }
- CallbacksDescriptor d(String::cast(key),
+ CallbacksDescriptor d(key,
value,
details.attributes(),
- details.index());
- descriptors->Set(next_descriptor++, &d, witness);
+ enumeration_index);
+ descriptors->Set(enumeration_index - 1, &d, witness);
} else {
UNREACHABLE();
}
@@ -12685,22 +12958,17 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
}
ASSERT(current_offset == number_of_fields);
- descriptors->Sort(witness);
- // Allocate new map.
- Object* new_map;
- { MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors();
- if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
- }
+ descriptors->Sort();
+
+ new_map->InitializeDescriptors(descriptors);
+ new_map->set_unused_property_fields(unused_property_fields);
// Transform the object.
- obj->set_map(Map::cast(new_map));
- obj->map()->set_instance_descriptors(descriptors);
- obj->map()->set_unused_property_fields(unused_property_fields);
+ obj->set_map(new_map);
- obj->set_properties(FixedArray::cast(fields));
+ obj->set_properties(fields);
ASSERT(obj->IsJSObject());
- descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
// Check that it really works.
ASSERT(obj->HasFastProperties());
@@ -12771,11 +13039,11 @@ Object* ObjectHashTable::Lookup(Object* key) {
// If the object does not have an identity hash, it was never used as a key.
{ MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
if (maybe_hash->ToObjectUnchecked()->IsUndefined()) {
- return GetHeap()->undefined_value();
+ return GetHeap()->the_hole_value();
}
}
int entry = FindEntry(key);
- if (entry == kNotFound) return GetHeap()->undefined_value();
+ if (entry == kNotFound) return GetHeap()->the_hole_value();
return get(EntryToIndex(entry) + 1);
}
@@ -12792,7 +13060,7 @@ MaybeObject* ObjectHashTable::Put(Object* key, Object* value) {
int entry = FindEntry(key);
// Check whether to perform removal operation.
- if (value->IsUndefined()) {
+ if (value->IsTheHole()) {
if (entry == kNotFound) return this;
RemoveEntry(entry);
return Shrink(key);
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index 88e3243fc..0d1a69cb9 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -33,7 +33,7 @@
#include "elements-kind.h"
#include "list.h"
#include "property-details.h"
-#include "smart-array-pointer.h"
+#include "smart-pointers.h"
#include "unicode-inl.h"
#if V8_TARGET_ARCH_ARM
#include "arm/constants-arm.h"
@@ -84,6 +84,7 @@
// - Context
// - JSFunctionResultCache
// - ScopeInfo
+// - TransitionArray
// - FixedDoubleArray
// - ExternalArray
// - ExternalPixelArray
@@ -170,17 +171,35 @@ enum CreationFlag {
};
-// Indicates whether the search function should expect a sorted or an unsorted
-// array as input.
-enum SearchMode {
- EXPECT_SORTED,
- EXPECT_UNSORTED
+// Indicates whether transitions can be added to a source map or not.
+enum TransitionFlag {
+ INSERT_TRANSITION,
+ OMIT_TRANSITION
+};
+
+
+// Indicates whether the transition is simple: the target map of the transition
+// either extends the current map with a new property, or it modifies the
+// property that was added last to the current map.
+enum SimpleTransitionFlag {
+ SIMPLE_TRANSITION,
+ FULL_TRANSITION
+};
+
+
+// Indicates whether we are only interested in the descriptors of a particular
+// map, or in all descriptors in the descriptor array.
+enum DescriptorFlag {
+ ALL_DESCRIPTORS,
+ OWN_DESCRIPTORS
};
// Instance size sentinel for objects of variable size.
const int kVariableSizeSentinel = 0;
+const int kStubMajorKeyBits = 6;
+const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
// All Maps have a field instance_type containing a InstanceType.
// It describes the type of the instances.
@@ -653,6 +672,25 @@ STATIC_CHECK(ODDBALL_TYPE == Internals::kOddballType);
STATIC_CHECK(FOREIGN_TYPE == Internals::kForeignType);
+#define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
+ V(FAST_ELEMENTS_SUB_TYPE) \
+ V(DICTIONARY_ELEMENTS_SUB_TYPE) \
+ V(FAST_PROPERTIES_SUB_TYPE) \
+ V(DICTIONARY_PROPERTIES_SUB_TYPE) \
+ V(MAP_CODE_CACHE_SUB_TYPE) \
+ V(SCOPE_INFO_SUB_TYPE) \
+ V(SYMBOL_TABLE_SUB_TYPE) \
+ V(DESCRIPTOR_ARRAY_SUB_TYPE) \
+ V(TRANSITION_ARRAY_SUB_TYPE)
+
+enum FixedArraySubInstanceType {
+#define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
+#undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
+ LAST_FIXED_ARRAY_SUB_TYPE = TRANSITION_ARRAY_SUB_TYPE
+};
+
+
enum CompareResult {
LESS = -1,
EQUAL = 0,
@@ -693,6 +731,11 @@ struct ValueInfo : public Malloced {
// A template-ized version of the IsXXX functions.
template <class C> static inline bool Is(Object* obj);
+#ifdef VERIFY_HEAP
+#define DECLARE_VERIFIER(Name) void Name##Verify();
+#else
+#define DECLARE_VERIFIER(Name)
+#endif
class MaybeObject BASE_EMBEDDED {
public:
@@ -737,7 +780,7 @@ class MaybeObject BASE_EMBEDDED {
void Print(FILE* out);
void PrintLn(FILE* out);
#endif
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
// Verifies the object.
void Verify();
#endif
@@ -780,14 +823,14 @@ class MaybeObject BASE_EMBEDDED {
V(JSModule) \
V(Map) \
V(DescriptorArray) \
+ V(TransitionArray) \
V(DeoptimizationInputData) \
V(DeoptimizationOutputData) \
V(TypeFeedbackCells) \
V(FixedArray) \
V(FixedDoubleArray) \
V(Context) \
- V(GlobalContext) \
- V(ModuleContext) \
+ V(NativeContext) \
V(ScopeInfo) \
V(JSFunction) \
V(Code) \
@@ -883,8 +926,8 @@ class Object : public MaybeObject {
Object* ToBoolean(); // ECMA-262 9.2.
// Convert to a JSObject if needed.
- // global_context is used when creating wrapper object.
- MUST_USE_RESULT MaybeObject* ToObject(Context* global_context);
+ // native_context is used when creating wrapper object.
+ MUST_USE_RESULT MaybeObject* ToObject(Context* native_context);
// Converts this to a Smi if possible.
// Failure is returned otherwise.
@@ -944,11 +987,13 @@ class Object : public MaybeObject {
// < the length of the string. Used to implement [] on strings.
inline bool IsStringObjectWithCharacterAt(uint32_t index);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
// Verify a pointer is a valid object pointer.
static void VerifyPointer(Object* p);
#endif
+ inline void VerifyApiCallResultType();
+
// Prints this object without details.
inline void ShortPrint() {
ShortPrint(stdout);
@@ -997,9 +1042,8 @@ class Smi: public Object {
}
void SmiPrint(FILE* out);
void SmiPrint(StringStream* accumulator);
-#ifdef DEBUG
- void SmiVerify();
-#endif
+
+ DECLARE_VERIFIER(Smi)
static const int kMinValue =
(static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
@@ -1070,9 +1114,8 @@ class Failure: public MaybeObject {
}
void FailurePrint(FILE* out);
void FailurePrint(StringStream* accumulator);
-#ifdef DEBUG
- void FailureVerify();
-#endif
+
+ DECLARE_VERIFIER(Failure)
private:
inline intptr_t value() const;
@@ -1203,9 +1246,8 @@ class HeapObject: public Object {
void HeapObjectPrint(FILE* out);
void PrintHeader(FILE* out, const char* id);
#endif
-
-#ifdef DEBUG
- void HeapObjectVerify();
+ DECLARE_VERIFIER(HeapObject)
+#ifdef VERIFY_HEAP
inline void VerifyObjectField(int offset);
inline void VerifySmiField(int offset);
@@ -1233,9 +1275,6 @@ class HeapObject: public Object {
};
-#define SLOT_ADDR(obj, offset) \
- reinterpret_cast<Object**>((obj)->address() + offset)
-
// This class describes a body of an object of a fixed size
// in which all pointer fields are located in the [start_offset, end_offset)
// interval.
@@ -1250,8 +1289,8 @@ class FixedBodyDescriptor {
template<typename StaticVisitor>
static inline void IterateBody(HeapObject* obj) {
- StaticVisitor::VisitPointers(SLOT_ADDR(obj, start_offset),
- SLOT_ADDR(obj, end_offset));
+ StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset),
+ HeapObject::RawField(obj, end_offset));
}
};
@@ -1270,13 +1309,11 @@ class FlexibleBodyDescriptor {
template<typename StaticVisitor>
static inline void IterateBody(HeapObject* obj, int object_size) {
- StaticVisitor::VisitPointers(SLOT_ADDR(obj, start_offset),
- SLOT_ADDR(obj, object_size));
+ StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset),
+ HeapObject::RawField(obj, object_size));
}
};
-#undef SLOT_ADDR
-
// The HeapNumber class describes heap allocated numbers that cannot be
// represented in a Smi (small integer)
@@ -1296,9 +1333,7 @@ class HeapNumber: public HeapObject {
}
void HeapNumberPrint(FILE* out);
void HeapNumberPrint(StringStream* accumulator);
-#ifdef DEBUG
- void HeapNumberVerify();
-#endif
+ DECLARE_VERIFIER(HeapNumber)
inline int get_exponent();
inline int get_sign();
@@ -1435,6 +1470,9 @@ class JSReceiver: public HeapObject {
// Return the object's prototype (might be Heap::null_value()).
inline Object* GetPrototype();
+ // Return the constructor function (may be Heap::null_value()).
+ inline Object* GetConstructor();
+
// Set the object's prototype (only JSReceiver and null are allowed).
MUST_USE_RESULT MaybeObject* SetPrototype(Object* value,
bool skip_hidden_prototypes);
@@ -1583,6 +1621,18 @@ class JSObject: public JSReceiver {
Handle<Object> value,
PropertyAttributes attributes);
+ // Try to follow an existing transition to a field with attributes NONE. The
+ // return value indicates whether the transition was successful.
+ static inline bool TryTransitionToField(Handle<JSObject> object,
+ Handle<String> key);
+
+ inline int LastAddedFieldIndex();
+
+ // Extend the receiver with a single fast property appeared first in the
+ // passed map. This also extends the property backing store if necessary.
+ static void AddFastPropertyUsingMap(Handle<JSObject> object, Handle<Map> map);
+ inline MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* map);
+
// Can cause GC.
MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
String* key,
@@ -1659,15 +1709,15 @@ class JSObject: public JSReceiver {
String* name,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes);
@@ -1707,7 +1757,7 @@ class JSObject: public JSReceiver {
static int GetIdentityHash(Handle<JSObject> obj);
MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
- MUST_USE_RESULT MaybeObject* SetIdentityHash(Object* hash, CreationFlag flag);
+ MUST_USE_RESULT MaybeObject* SetIdentityHash(Smi* hash, CreationFlag flag);
static Handle<Object> DeleteProperty(Handle<JSObject> obj,
Handle<String> name);
@@ -1870,7 +1920,7 @@ class JSObject: public JSReceiver {
void LookupRealNamedPropertyInPrototypes(String* name, LookupResult* result);
MUST_USE_RESULT MaybeObject* SetElementWithCallbackSetterInPrototypes(
uint32_t index, Object* value, bool* found, StrictModeFlag strict_mode);
- void LookupCallback(String* name, LookupResult* result);
+ void LookupCallbackProperty(String* name, LookupResult* result);
// Returns the number of properties on this object filtering out properties
// with the specified attributes (ignoring interceptors).
@@ -1898,7 +1948,8 @@ class JSObject: public JSReceiver {
// new_map.
MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* new_map,
String* name,
- Object* value);
+ Object* value,
+ int field_index);
// Add a constant function property to a fast-case object.
// This leaves a CONSTANT_TRANSITION in the old map, and
@@ -1931,19 +1982,15 @@ class JSObject: public JSReceiver {
MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
- // Converts a descriptor of any other type to a real field,
- // backed by the properties array. Descriptors of visible
- // types, such as CONSTANT_FUNCTION, keep their enumeration order.
- // Converts the descriptor on the original object's map to a
- // map transition, and the the new field is on the object's new map.
- MUST_USE_RESULT MaybeObject* ConvertDescriptorToFieldAndMapTransition(
+ // Replaces an existing transition with a transition to a map with a FIELD.
+ MUST_USE_RESULT MaybeObject* ConvertTransitionToMapTransition(
+ int transition_index,
String* name,
Object* new_value,
PropertyAttributes attributes);
- // Converts a descriptor of any other type to a real field,
- // backed by the properties array. Descriptors of visible
- // types, such as CONSTANT_FUNCTION, keep their enumeration order.
+ // Converts a descriptor of any other type to a real field, backed by the
+ // properties array.
MUST_USE_RESULT MaybeObject* ConvertDescriptorToField(
String* name,
Object* new_value,
@@ -2043,9 +2090,7 @@ class JSObject: public JSReceiver {
}
void JSObjectPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSObjectVerify();
-#endif
+ DECLARE_VERIFIER(JSObject)
#ifdef OBJECT_PRINT
inline void PrintProperties() {
PrintProperties(stdout);
@@ -2056,6 +2101,10 @@ class JSObject: public JSReceiver {
PrintElements(stdout);
}
void PrintElements(FILE* out);
+ inline void PrintTransitions() {
+ PrintTransitions(stdout);
+ }
+ void PrintTransitions(FILE* out);
#endif
void PrintElementsTransition(
@@ -2209,18 +2258,23 @@ class JSObject: public JSReceiver {
Object* getter,
Object* setter,
PropertyAttributes attributes);
- void LookupInDescriptor(String* name, LookupResult* result);
-
- // Returns the hidden properties backing store object, currently
- // a StringDictionary, stored on this object.
- // If no hidden properties object has been put on this object,
- // return undefined, unless create_if_absent is true, in which case
- // a new dictionary is created, added to this object, and returned.
- MUST_USE_RESULT MaybeObject* GetHiddenPropertiesDictionary(
- bool create_if_absent);
- // Updates the existing hidden properties dictionary.
- MUST_USE_RESULT MaybeObject* SetHiddenPropertiesDictionary(
- StringDictionary* dictionary);
+
+
+ enum InitializeHiddenProperties {
+ CREATE_NEW_IF_ABSENT,
+ ONLY_RETURN_INLINE_VALUE
+ };
+
+ // If create_if_absent is true, return the hash table backing store
+ // for hidden properties. If there is no backing store, allocate one.
+ // If create_if_absent is false, return the hash table backing store
+ // or the inline stored identity hash, whatever is found.
+ MUST_USE_RESULT MaybeObject* GetHiddenPropertiesHashTable(
+ InitializeHiddenProperties init_option);
+ // Set the hidden property backing store to either a hash table or
+ // the inline-stored identity hash.
+ MUST_USE_RESULT MaybeObject* SetHiddenPropertiesHashTable(
+ Object* value);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
};
@@ -2244,6 +2298,8 @@ class FixedArrayBase: public HeapObject {
class FixedDoubleArray;
+class IncrementalMarking;
+
// FixedArray describes fixed-sized arrays with element type Object*.
class FixedArray: public FixedArrayBase {
@@ -2316,8 +2372,8 @@ class FixedArray: public FixedArrayBase {
}
void FixedArrayPrint(FILE* out);
#endif
+ DECLARE_VERIFIER(FixedArray)
#ifdef DEBUG
- void FixedArrayVerify();
// Checks if two FixedArrays have identical contents.
bool IsEqualTo(FixedArray* other);
#endif
@@ -2403,93 +2459,99 @@ class FixedDoubleArray: public FixedArrayBase {
}
void FixedDoubleArrayPrint(FILE* out);
#endif
-
-#ifdef DEBUG
- void FixedDoubleArrayVerify();
-#endif
+ DECLARE_VERIFIER(FixedDoubleArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
};
-class IncrementalMarking;
-
-
// DescriptorArrays are fixed arrays used to hold instance descriptors.
// The format of the these objects is:
-// TODO(1399): It should be possible to make room for bit_field3 in the map
-// without overloading the instance descriptors field in the map
-// (and storing it in the DescriptorArray when the map has one).
-// [0]: storage for bit_field3 for Map owning this object (Smi)
-// [1]: point to a fixed array with (value, detail) pairs.
-// [2]: next enumeration index (Smi), or pointer to small fixed array:
-// [0]: next enumeration index (Smi)
-// [1]: pointer to fixed array with enum cache
-// [3]: first key
-// [length() - 1]: last key
-//
+// [0]: Number of descriptors
+// [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
+// [0]: pointer to fixed array with enum cache
+// [1]: either Smi(0) or pointer to fixed array with indices
+// [2]: first key
+// [2 + number of descriptors * kDescriptorSize]: start of slack
class DescriptorArray: public FixedArray {
public:
+ // WhitenessWitness is used to prove that a descriptor array is white
+ // (unmarked), so incremental write barriers can be skipped because the
+ // marking invariant cannot be broken and slots pointing into evacuation
+ // candidates will be discovered when the object is scanned. A witness is
+ // always stack-allocated right after creating an array. By allocating a
+ // witness, incremental marking is globally disabled. The witness is then
+ // passed along wherever needed to statically prove that the array is known to
+ // be white.
+ class WhitenessWitness {
+ public:
+ inline explicit WhitenessWitness(FixedArray* array);
+ inline ~WhitenessWitness();
+
+ private:
+ IncrementalMarking* marking_;
+ };
+
// Returns true for both shared empty_descriptor_array and for smis, which the
// map uses to encode additional bit fields when the descriptor array is not
// yet used.
inline bool IsEmpty();
- inline bool MayContainTransitions();
-
- DECL_ACCESSORS(elements_transition_map, Map)
// Returns the number of descriptors in the array.
int number_of_descriptors() {
ASSERT(length() >= kFirstIndex || IsEmpty());
int len = length();
- return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize;
+ return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value();
}
- int NextEnumerationIndex() {
- if (IsEmpty()) return PropertyDetails::kInitialIndex;
- Object* obj = get(kEnumerationIndexIndex);
- if (obj->IsSmi()) {
- return Smi::cast(obj)->value();
- } else {
- Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex);
- return Smi::cast(index)->value();
- }
+ int number_of_descriptors_storage() {
+ int len = length();
+ return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize;
}
- // Set next enumeration index and flush any enum cache.
- void SetNextEnumerationIndex(int value) {
- if (!IsEmpty()) {
- set(kEnumerationIndexIndex, Smi::FromInt(value));
- }
+ int NumberOfSlackDescriptors() {
+ return number_of_descriptors_storage() - number_of_descriptors();
}
+
+ inline void SetNumberOfDescriptors(int number_of_descriptors);
+ inline int number_of_entries() { return number_of_descriptors(); }
+
bool HasEnumCache() {
- return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi();
+ return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi();
}
- Object* GetEnumCache() {
- ASSERT(HasEnumCache());
- FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex));
- return bridge->get(kEnumCacheBridgeCacheIndex);
+ void CopyEnumCacheFrom(DescriptorArray* array) {
+ set(kEnumCacheIndex, array->get(kEnumCacheIndex));
}
- Object** GetEnumCacheSlot() {
+ FixedArray* GetEnumCache() {
ASSERT(HasEnumCache());
- return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
- kEnumerationIndexOffset);
+ FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
+ return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex));
}
- Object** GetTransitionsSlot() {
- ASSERT(elements_transition_map() != NULL);
+ bool HasEnumIndicesCache() {
+ if (IsEmpty()) return false;
+ Object* object = get(kEnumCacheIndex);
+ if (object->IsSmi()) return false;
+ FixedArray* bridge = FixedArray::cast(object);
+ return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi();
+ }
+
+ FixedArray* GetEnumIndicesCache() {
+ ASSERT(HasEnumIndicesCache());
+ FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
+ return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex));
+ }
+
+ Object** GetEnumCacheSlot() {
+ ASSERT(HasEnumCache());
return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
- kTransitionsOffset);
+ kEnumCacheOffset);
}
- // TODO(1399): It should be possible to make room for bit_field3 in the map
- // without overloading the instance descriptors field in the map
- // (and storing it in the DescriptorArray when the map has one).
- inline int bit_field3_storage();
- inline void set_bit_field3_storage(int value);
+ void ClearEnumCache();
// Initialize or change the enum cache,
// using the supplied storage for the small "bridge".
@@ -2502,109 +2564,53 @@ class DescriptorArray: public FixedArray {
inline Object** GetKeySlot(int descriptor_number);
inline Object* GetValue(int descriptor_number);
inline Object** GetValueSlot(int descriptor_number);
- inline void SetNullValueUnchecked(int descriptor_number, Heap* heap);
inline PropertyDetails GetDetails(int descriptor_number);
- inline void SetDetailsUnchecked(int descriptor_number, Smi* value);
inline PropertyType GetType(int descriptor_number);
inline int GetFieldIndex(int descriptor_number);
inline JSFunction* GetConstantFunction(int descriptor_number);
inline Object* GetCallbacksObject(int descriptor_number);
inline AccessorDescriptor* GetCallbacks(int descriptor_number);
- inline bool IsProperty(int descriptor_number);
- inline bool IsTransitionOnly(int descriptor_number);
- inline bool IsNullDescriptor(int descriptor_number);
-
- // WhitenessWitness is used to prove that a specific descriptor array is white
- // (unmarked), so incremental write barriers can be skipped because the
- // marking invariant cannot be broken and slots pointing into evacuation
- // candidates will be discovered when the object is scanned. A witness is
- // always stack-allocated right after creating a descriptor array. By
- // allocating a witness, incremental marking is globally disabled. The witness
- // is then passed along wherever needed to statically prove that the
- // descriptor array is known to be white.
- class WhitenessWitness {
- public:
- inline explicit WhitenessWitness(DescriptorArray* array);
- inline ~WhitenessWitness();
- private:
- IncrementalMarking* marking_;
- };
+ inline String* GetSortedKey(int descriptor_number);
+ inline int GetSortedKeyIndex(int descriptor_number);
+ inline void SetSortedKey(int pointer, int descriptor_number);
// Accessor for complete descriptor.
inline void Get(int descriptor_number, Descriptor* desc);
inline void Set(int descriptor_number,
Descriptor* desc,
const WhitenessWitness&);
+ inline void Set(int descriptor_number, Descriptor* desc);
- // Transfer a complete descriptor from the src descriptor array to the dst
- // one, dropping map transitions in CALLBACKS.
- static void CopyFrom(Handle<DescriptorArray> dst,
- int dst_index,
- Handle<DescriptorArray> src,
- int src_index,
- const WhitenessWitness& witness);
+ // Append automatically sets the enumeration index. This should only be used
+ // to add descriptors in bulk at the end, followed by sorting the descriptor
+ // array.
+ inline void Append(Descriptor* desc, const WhitenessWitness&);
+ inline void Append(Descriptor* desc);
// Transfer a complete descriptor from the src descriptor array to this
- // descriptor array, dropping map transitions in CALLBACKS.
- MUST_USE_RESULT MaybeObject* CopyFrom(int dst_index,
- DescriptorArray* src,
- int src_index,
- const WhitenessWitness&);
-
- // Copy the descriptor array, insert a new descriptor and optionally
- // remove map transitions. If the descriptor is already present, it is
- // replaced. If a replaced descriptor is a real property (not a transition
- // or null), its enumeration index is kept as is.
- // If adding a real property, map transitions must be removed. If adding
- // a transition, they must not be removed. All null descriptors are removed.
- MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor,
- TransitionFlag transition_flag);
-
- // Indicates whether the search function should expect a sorted or an unsorted
- // descriptor array as input.
- enum SharedMode {
- MAY_BE_SHARED,
- CANNOT_BE_SHARED
- };
+ // descriptor array.
+ void CopyFrom(int dst_index,
+ DescriptorArray* src,
+ int src_index,
+ const WhitenessWitness&);
- // Return a copy of the array with all transitions and null descriptors
- // removed. Return a Failure object in case of an allocation failure.
- MUST_USE_RESULT MaybeObject* RemoveTransitions(SharedMode shared_mode);
-
- // Sort the instance descriptors by the hash codes of their keys.
- // Does not check for duplicates.
- void SortUnchecked(const WhitenessWitness&);
+ MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index);
// Sort the instance descriptors by the hash codes of their keys.
- // Checks the result for duplicates.
- void Sort(const WhitenessWitness&);
+ void Sort();
// Search the instance descriptors for given name.
- INLINE(int Search(String* name));
+ INLINE(int Search(String* name, int number_of_own_descriptors));
// As the above, but uses DescriptorLookupCache and updates it when
// necessary.
- INLINE(int SearchWithCache(String* name));
-
- // Tells whether the name is present int the array.
- bool Contains(String* name) { return kNotFound != Search(name); }
-
- // Perform a binary search in the instance descriptors represented
- // by this fixed array. low and high are descriptor indices. If there
- // are three instance descriptors in this array it should be called
- // with low=0 and high=2.
- int BinarySearch(String* name, int low, int high);
-
- // Perform a linear search in the instance descriptors represented
- // by this fixed array. len is the number of descriptor indices that are
- // valid.
- int LinearSearch(SearchMode mode, String* name, int len);
+ INLINE(int SearchWithCache(String* name, Map* map));
// Allocates a DescriptorArray, but returns the singleton
// empty descriptor array object if number_of_descriptors is 0.
MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors,
- SharedMode shared_mode);
+ int slack = 0);
// Casting.
static inline DescriptorArray* cast(Object* obj);
@@ -2612,28 +2618,22 @@ class DescriptorArray: public FixedArray {
// Constant for denoting key was not found.
static const int kNotFound = -1;
- static const int kBitField3StorageIndex = 0;
- static const int kEnumerationIndexIndex = 1;
- static const int kTransitionsIndex = 2;
- static const int kFirstIndex = 3;
+ static const int kDescriptorLengthIndex = 0;
+ static const int kEnumCacheIndex = 1;
+ static const int kFirstIndex = 2;
// The length of the "bridge" to the enum cache.
- static const int kEnumCacheBridgeLength = 3;
- static const int kEnumCacheBridgeEnumIndex = 0;
- static const int kEnumCacheBridgeCacheIndex = 1;
- static const int kEnumCacheBridgeIndicesCacheIndex = 2;
+ static const int kEnumCacheBridgeLength = 2;
+ static const int kEnumCacheBridgeCacheIndex = 0;
+ static const int kEnumCacheBridgeIndicesCacheIndex = 1;
// Layout description.
- static const int kBitField3StorageOffset = FixedArray::kHeaderSize;
- static const int kEnumerationIndexOffset =
- kBitField3StorageOffset + kPointerSize;
- static const int kTransitionsOffset = kEnumerationIndexOffset + kPointerSize;
- static const int kFirstOffset = kTransitionsOffset + kPointerSize;
+ static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
+ static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
+ static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
// Layout description for the bridge array.
- static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize;
- static const int kEnumCacheBridgeCacheOffset =
- kEnumCacheBridgeEnumOffset + kPointerSize;
+ static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
// Layout of descriptor.
static const int kDescriptorKey = 0;
@@ -2651,7 +2651,7 @@ class DescriptorArray: public FixedArray {
#ifdef DEBUG
// Is the descriptor array sorted and without duplicates?
- bool IsSortedNoDuplicates();
+ bool IsSortedNoDuplicates(int valid_descriptors = -1);
// Is the descriptor array consistent with the back pointers in targets?
bool IsConsistentWithBackPointers(Map* current_map);
@@ -2664,6 +2664,12 @@ class DescriptorArray: public FixedArray {
// fit in a page).
static const int kMaxNumberOfDescriptors = 1024 + 512;
+ // Returns the fixed array length required to hold number_of_descriptors
+ // descriptors.
+ static int LengthFor(int number_of_descriptors) {
+ return ToKeyIndex(number_of_descriptors);
+ }
+
private:
// An entry in a DescriptorArray, represented as an (array, index) pair.
class Entry {
@@ -2698,18 +2704,23 @@ class DescriptorArray: public FixedArray {
kDescriptorValue;
}
- // Swap operation on FixedArray without using write barriers.
- static inline void NoIncrementalWriteBarrierSwap(
- FixedArray* array, int first, int second);
-
- // Swap descriptor first and second.
- inline void NoIncrementalWriteBarrierSwapDescriptors(
- int first, int second);
+ // Swap first and second descriptor.
+ inline void SwapSortedKeys(int first, int second);
DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
};
+enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
+
+template<SearchMode search_mode, typename T>
+inline int LinearSearch(T* array, String* name, int len, int valid_entries);
+
+
+template<SearchMode search_mode, typename T>
+inline int Search(T* array, String* name, int valid_entries = 0);
+
+
// HashTable is a subclass of FixedArray that implements a hash table
// that uses open addressing and quadratic probing.
//
@@ -2762,6 +2773,11 @@ class BaseShape {
template<typename Shape, typename Key>
class HashTable: public FixedArray {
public:
+ enum MinimumCapacity {
+ USE_DEFAULT_MINIMUM_CAPACITY,
+ USE_CUSTOM_MINIMUM_CAPACITY
+ };
+
// Wrapper methods
inline uint32_t Hash(Key key) {
if (Shape::UsesSeed) {
@@ -2814,6 +2830,7 @@ class HashTable: public FixedArray {
// Returns a new HashTable object. Might return Failure.
MUST_USE_RESULT static MaybeObject* Allocate(
int at_least_space_for,
+ MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
PretenureFlag pretenure = NOT_TENURED);
// Computes the required capacity for a table holding the given
@@ -2903,11 +2920,12 @@ class HashTable: public FixedArray {
return (hash + GetProbeOffset(number)) & (size - 1);
}
- static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
+ inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
return hash & (size - 1);
}
- static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size) {
+ inline static uint32_t NextProbe(
+ uint32_t last, uint32_t number, uint32_t size) {
return (last + number) & (size - 1);
}
@@ -2994,6 +3012,8 @@ class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> {
private:
MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s);
+ template <bool seq_ascii> friend class JsonParser;
+
DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable);
};
@@ -3091,6 +3111,7 @@ class Dictionary: public HashTable<Shape, Key> {
// Accessors for next enumeration index.
void SetNextEnumerationIndex(int index) {
+ ASSERT(index != 0);
this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
}
@@ -3164,7 +3185,9 @@ class StringDictionary: public Dictionary<StringDictionaryShape, String*> {
}
// Copies enumerable keys to preallocated fixed array.
- void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array);
+ FixedArray* CopyEnumKeysTo(FixedArray* storage);
+ static void DoGenerateNewEnumerationIndices(
+ Handle<StringDictionary> dictionary);
// For transforming properties of a JSObject.
MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor(
@@ -3174,8 +3197,6 @@ class StringDictionary: public Dictionary<StringDictionaryShape, String*> {
// Find entry for key, otherwise return kNotFound. Optimized version of
// HashTable::FindEntry.
int FindEntry(String* key);
-
- bool ContainsTransition(int entry);
};
@@ -3321,12 +3342,12 @@ class ObjectHashTable: public HashTable<ObjectHashTableShape<2>, Object*> {
return reinterpret_cast<ObjectHashTable*>(obj);
}
- // Looks up the value associated with the given key. The undefined value is
+ // Looks up the value associated with the given key. The hole value is
// returned in case the key is not present.
Object* Lookup(Object* key);
// Adds (or overwrites) the value associated with the given key. Mapping a
- // key to the undefined value causes removal of the whole entry.
+ // key to the hole value causes removal of the whole entry.
MUST_USE_RESULT MaybeObject* Put(Object* key, Object* value);
private:
@@ -3374,9 +3395,7 @@ class JSFunctionResultCache: public FixedArray {
// Casting
static inline JSFunctionResultCache* cast(Object* obj);
-#ifdef DEBUG
- void JSFunctionResultCacheVerify();
-#endif
+ DECLARE_VERIFIER(JSFunctionResultCache)
};
@@ -3523,7 +3542,7 @@ class ScopeInfo : public FixedArray {
FOR_EACH_NUMERIC_FIELD(DECL_INDEX)
#undef DECL_INDEX
#undef FOR_EACH_NUMERIC_FIELD
- kVariablePartIndex
+ kVariablePartIndex
};
// The layout of the variable part of a ScopeInfo is as follows:
@@ -3596,9 +3615,7 @@ class NormalizedMapCache: public FixedArray {
// Casting
static inline NormalizedMapCache* cast(Object* obj);
-#ifdef DEBUG
- void NormalizedMapCacheVerify();
-#endif
+ DECLARE_VERIFIER(NormalizedMapCache)
};
@@ -3647,9 +3664,7 @@ class ByteArray: public FixedArrayBase {
}
void ByteArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ByteArrayVerify();
-#endif
+ DECLARE_VERIFIER(ByteArray)
// Layout description.
static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
@@ -3683,9 +3698,7 @@ class FreeSpace: public HeapObject {
}
void FreeSpacePrint(FILE* out);
#endif
-#ifdef DEBUG
- void FreeSpaceVerify();
-#endif
+ DECLARE_VERIFIER(FreeSpace)
// Layout description.
// Size is smi tagged when it is stored.
@@ -3765,9 +3778,7 @@ class ExternalPixelArray: public ExternalArray {
}
void ExternalPixelArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalPixelArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalPixelArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalPixelArray);
@@ -3794,9 +3805,7 @@ class ExternalByteArray: public ExternalArray {
}
void ExternalByteArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalByteArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalByteArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalByteArray);
@@ -3823,9 +3832,7 @@ class ExternalUnsignedByteArray: public ExternalArray {
}
void ExternalUnsignedByteArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalUnsignedByteArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalUnsignedByteArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedByteArray);
@@ -3852,9 +3859,7 @@ class ExternalShortArray: public ExternalArray {
}
void ExternalShortArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalShortArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalShortArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalShortArray);
@@ -3881,9 +3886,7 @@ class ExternalUnsignedShortArray: public ExternalArray {
}
void ExternalUnsignedShortArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalUnsignedShortArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalUnsignedShortArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedShortArray);
@@ -3910,9 +3913,7 @@ class ExternalIntArray: public ExternalArray {
}
void ExternalIntArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalIntArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalIntArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalIntArray);
@@ -3939,9 +3940,7 @@ class ExternalUnsignedIntArray: public ExternalArray {
}
void ExternalUnsignedIntArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalUnsignedIntArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalUnsignedIntArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedIntArray);
@@ -3968,9 +3967,7 @@ class ExternalFloatArray: public ExternalArray {
}
void ExternalFloatArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalFloatArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalFloatArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloatArray);
@@ -3997,9 +3994,7 @@ class ExternalDoubleArray: public ExternalArray {
}
void ExternalDoubleArrayPrint(FILE* out);
#endif // OBJECT_PRINT
-#ifdef DEBUG
- void ExternalDoubleArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalDoubleArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalDoubleArray);
@@ -4024,7 +4019,7 @@ class DeoptimizationInputData: public FixedArray {
static const int kFirstDeoptEntryIndex = 5;
// Offsets of deopt entry elements relative to the start of the entry.
- static const int kAstIdOffset = 0;
+ static const int kAstIdRawOffset = 0;
static const int kTranslationIndexOffset = 1;
static const int kArgumentsStackHeightOffset = 2;
static const int kPcOffset = 3;
@@ -4056,13 +4051,21 @@ class DeoptimizationInputData: public FixedArray {
set(IndexForEntry(i) + k##name##Offset, value); \
}
- DEFINE_ENTRY_ACCESSORS(AstId, Smi)
+ DEFINE_ENTRY_ACCESSORS(AstIdRaw, Smi)
DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi)
DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
DEFINE_ENTRY_ACCESSORS(Pc, Smi)
#undef DEFINE_ENTRY_ACCESSORS
+ BailoutId AstId(int i) {
+ return BailoutId(AstIdRaw(i)->value());
+ }
+
+ void SetAstId(int i, BailoutId value) {
+ SetAstIdRaw(i, Smi::FromInt(value.ToInt()));
+ }
+
int DeoptCount() {
return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
}
@@ -4097,8 +4100,15 @@ class DeoptimizationInputData: public FixedArray {
class DeoptimizationOutputData: public FixedArray {
public:
int DeoptPoints() { return length() / 2; }
- Smi* AstId(int index) { return Smi::cast(get(index * 2)); }
- void SetAstId(int index, Smi* id) { set(index * 2, id); }
+
+ BailoutId AstId(int index) {
+ return BailoutId(Smi::cast(get(index * 2))->value());
+ }
+
+ void SetAstId(int index, BailoutId id) {
+ set(index * 2, Smi::FromInt(id.ToInt()));
+ }
+
Smi* PcAndState(int index) { return Smi::cast(get(1 + index * 2)); }
void SetPcAndState(int index, Smi* offset) { set(1 + index * 2, offset); }
@@ -4133,8 +4143,8 @@ class TypeFeedbackCells: public FixedArray {
static int LengthOfFixedArray(int cell_count) { return cell_count * 2; }
// Accessors for AST ids associated with cache values.
- inline Smi* AstId(int index);
- inline void SetAstId(int index, Smi* id);
+ inline TypeFeedbackId AstId(int index);
+ inline void SetAstId(int index, TypeFeedbackId id);
// Accessors for global property cells holding the cache values.
inline JSGlobalPropertyCell* Cell(int index);
@@ -4174,30 +4184,49 @@ class Code: public HeapObject {
FLAGS_MAX_VALUE = kMaxInt
};
+#define CODE_KIND_LIST(V) \
+ V(FUNCTION) \
+ V(OPTIMIZED_FUNCTION) \
+ V(STUB) \
+ V(BUILTIN) \
+ V(LOAD_IC) \
+ V(KEYED_LOAD_IC) \
+ V(CALL_IC) \
+ V(KEYED_CALL_IC) \
+ V(STORE_IC) \
+ V(KEYED_STORE_IC) \
+ V(UNARY_OP_IC) \
+ V(BINARY_OP_IC) \
+ V(COMPARE_IC) \
+ V(TO_BOOLEAN_IC)
+
enum Kind {
- FUNCTION,
- OPTIMIZED_FUNCTION,
- STUB,
- BUILTIN,
- LOAD_IC,
- KEYED_LOAD_IC,
- CALL_IC,
- KEYED_CALL_IC,
- STORE_IC,
- KEYED_STORE_IC,
- UNARY_OP_IC,
- BINARY_OP_IC,
- COMPARE_IC,
- TO_BOOLEAN_IC,
- // No more than 16 kinds. The value currently encoded in four bits in
- // Flags.
+#define DEFINE_CODE_KIND_ENUM(name) name,
+ CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
+#undef DEFINE_CODE_KIND_ENUM
// Pseudo-kinds.
+ LAST_CODE_KIND = TO_BOOLEAN_IC,
REGEXP = BUILTIN,
FIRST_IC_KIND = LOAD_IC,
LAST_IC_KIND = TO_BOOLEAN_IC
};
+ // No more than 16 kinds. The value is currently encoded in four bits in
+ // Flags.
+ STATIC_ASSERT(LAST_CODE_KIND < 16);
+
+ // Types of stubs.
+ enum StubType {
+ NORMAL,
+ FIELD,
+ CONSTANT_FUNCTION,
+ CALLBACKS,
+ INTERCEPTOR,
+ MAP_TRANSITION,
+ NONEXISTENT
+ };
+
enum {
NUMBER_OF_KINDS = LAST_IC_KIND + 1
};
@@ -4210,7 +4239,7 @@ class Code: public HeapObject {
// Printing
static const char* Kind2String(Kind kind);
static const char* ICState2String(InlineCacheState state);
- static const char* PropertyType2String(PropertyType type);
+ static const char* StubType2String(StubType type);
static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra);
inline void Disassemble(const char* name) {
Disassemble(name, stdout);
@@ -4260,7 +4289,7 @@ class Code: public HeapObject {
inline Kind kind();
inline InlineCacheState ic_state(); // Only valid for IC stubs.
inline ExtraICState extra_ic_state(); // Only valid for IC stubs.
- inline PropertyType type(); // Only valid for monomorphic IC stubs.
+ inline StubType type(); // Only valid for monomorphic IC stubs.
inline int arguments_count(); // Only valid for call IC stubs.
// Testers for IC stub kinds.
@@ -4403,19 +4432,19 @@ class Code: public HeapObject {
Kind kind,
InlineCacheState ic_state = UNINITIALIZED,
ExtraICState extra_ic_state = kNoExtraICState,
- PropertyType type = NORMAL,
+ StubType type = NORMAL,
int argc = -1,
InlineCacheHolderFlag holder = OWN_MAP);
static inline Flags ComputeMonomorphicFlags(
Kind kind,
- PropertyType type,
+ StubType type,
ExtraICState extra_ic_state = kNoExtraICState,
InlineCacheHolderFlag holder = OWN_MAP,
int argc = -1);
static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
- static inline PropertyType ExtractTypeFromFlags(Flags flags);
+ static inline StubType ExtractTypeFromFlags(Flags flags);
static inline Kind ExtractKindFromFlags(Flags flags);
static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
@@ -4488,9 +4517,8 @@ class Code: public HeapObject {
}
void CodePrint(FILE* out);
#endif
-#ifdef DEBUG
- void CodeVerify();
-#endif
+ DECLARE_VERIFIER(Code)
+
void ClearInlineCaches();
void ClearTypeFeedbackCells(Heap* heap);
@@ -4510,28 +4538,20 @@ class Code: public HeapObject {
static const int kICAgeOffset =
kGCMetadataOffset + kPointerSize;
static const int kFlagsOffset = kICAgeOffset + kIntSize;
- static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize;
- static const int kKindSpecificFlagsSize = 2 * kIntSize;
+ static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
+ static const int kKindSpecificFlags2Offset =
+ kKindSpecificFlags1Offset + kIntSize;
- static const int kHeaderPaddingStart = kKindSpecificFlagsOffset +
- kKindSpecificFlagsSize;
+ static const int kHeaderPaddingStart = kKindSpecificFlags2Offset + kIntSize;
// Add padding to align the instruction start following right after
// the Code object header.
static const int kHeaderSize =
(kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
- // Byte offsets within kKindSpecificFlagsOffset.
- static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset;
- static const int kOptimizableOffset = kKindSpecificFlagsOffset;
- static const int kStackSlotsOffset = kKindSpecificFlagsOffset;
- static const int kCheckTypeOffset = kKindSpecificFlagsOffset;
-
- static const int kUnaryOpTypeOffset = kStubMajorKeyOffset + 1;
- static const int kBinaryOpTypeOffset = kStubMajorKeyOffset + 1;
- static const int kCompareStateOffset = kStubMajorKeyOffset + 1;
- static const int kToBooleanTypeOffset = kStubMajorKeyOffset + 1;
- static const int kHasFunctionCacheOffset = kStubMajorKeyOffset + 1;
+ // Byte offsets within kKindSpecificFlags1Offset.
+ static const int kOptimizableOffset = kKindSpecificFlags1Offset;
+ static const int kCheckTypeOffset = kKindSpecificFlags1Offset;
static const int kFullCodeFlags = kOptimizableOffset + 1;
class FullCodeFlagsHasDeoptimizationSupportField:
@@ -4539,26 +4559,90 @@ class Code: public HeapObject {
class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {};
- static const int kBinaryOpReturnTypeOffset = kBinaryOpTypeOffset + 1;
-
- static const int kCompareOperationOffset = kCompareStateOffset + 1;
-
static const int kAllowOSRAtLoopNestingLevelOffset = kFullCodeFlags + 1;
static const int kProfilerTicksOffset = kAllowOSRAtLoopNestingLevelOffset + 1;
- static const int kSafepointTableOffsetOffset = kStackSlotsOffset + kIntSize;
- static const int kStackCheckTableOffsetOffset = kStackSlotsOffset + kIntSize;
-
// Flags layout. BitField<type, shift, size>.
class ICStateField: public BitField<InlineCacheState, 0, 3> {};
- class TypeField: public BitField<PropertyType, 3, 4> {};
- class CacheHolderField: public BitField<InlineCacheHolderFlag, 7, 1> {};
- class KindField: public BitField<Kind, 8, 4> {};
- class ExtraICStateField: public BitField<ExtraICState, 12, 2> {};
- class IsPregeneratedField: public BitField<bool, 14, 1> {};
+ class TypeField: public BitField<StubType, 3, 3> {};
+ class CacheHolderField: public BitField<InlineCacheHolderFlag, 6, 1> {};
+ class KindField: public BitField<Kind, 7, 4> {};
+ class ExtraICStateField: public BitField<ExtraICState, 11, 2> {};
+ class IsPregeneratedField: public BitField<bool, 13, 1> {};
+
+ // KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION)
+ static const int kStackSlotsFirstBit = 0;
+ static const int kStackSlotsBitCount = 24;
+ static const int kUnaryOpTypeFirstBit =
+ kStackSlotsFirstBit + kStackSlotsBitCount;
+ static const int kUnaryOpTypeBitCount = 3;
+ static const int kBinaryOpTypeFirstBit =
+ kStackSlotsFirstBit + kStackSlotsBitCount;
+ static const int kBinaryOpTypeBitCount = 3;
+ static const int kBinaryOpResultTypeFirstBit =
+ kBinaryOpTypeFirstBit + kBinaryOpTypeBitCount;
+ static const int kBinaryOpResultTypeBitCount = 3;
+ static const int kCompareStateFirstBit =
+ kStackSlotsFirstBit + kStackSlotsBitCount;
+ static const int kCompareStateBitCount = 3;
+ static const int kCompareOperationFirstBit =
+ kCompareStateFirstBit + kCompareStateBitCount;
+ static const int kCompareOperationBitCount = 4;
+ static const int kToBooleanStateFirstBit =
+ kStackSlotsFirstBit + kStackSlotsBitCount;
+ static const int kToBooleanStateBitCount = 8;
+ static const int kHasFunctionCacheFirstBit =
+ kStackSlotsFirstBit + kStackSlotsBitCount;
+ static const int kHasFunctionCacheBitCount = 1;
+
+ STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
+ STATIC_ASSERT(kUnaryOpTypeFirstBit + kUnaryOpTypeBitCount <= 32);
+ STATIC_ASSERT(kBinaryOpTypeFirstBit + kBinaryOpTypeBitCount <= 32);
+ STATIC_ASSERT(kBinaryOpResultTypeFirstBit +
+ kBinaryOpResultTypeBitCount <= 32);
+ STATIC_ASSERT(kCompareStateFirstBit + kCompareStateBitCount <= 32);
+ STATIC_ASSERT(kCompareOperationFirstBit + kCompareOperationBitCount <= 32);
+ STATIC_ASSERT(kToBooleanStateFirstBit + kToBooleanStateBitCount <= 32);
+ STATIC_ASSERT(kHasFunctionCacheFirstBit + kHasFunctionCacheBitCount <= 32);
+
+ class StackSlotsField: public BitField<int,
+ kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
+ class UnaryOpTypeField: public BitField<int,
+ kUnaryOpTypeFirstBit, kUnaryOpTypeBitCount> {}; // NOLINT
+ class BinaryOpTypeField: public BitField<int,
+ kBinaryOpTypeFirstBit, kBinaryOpTypeBitCount> {}; // NOLINT
+ class BinaryOpResultTypeField: public BitField<int,
+ kBinaryOpResultTypeFirstBit, kBinaryOpResultTypeBitCount> {}; // NOLINT
+ class CompareStateField: public BitField<int,
+ kCompareStateFirstBit, kCompareStateBitCount> {}; // NOLINT
+ class CompareOperationField: public BitField<int,
+ kCompareOperationFirstBit, kCompareOperationBitCount> {}; // NOLINT
+ class ToBooleanStateField: public BitField<int,
+ kToBooleanStateFirstBit, kToBooleanStateBitCount> {}; // NOLINT
+ class HasFunctionCacheField: public BitField<bool,
+ kHasFunctionCacheFirstBit, kHasFunctionCacheBitCount> {}; // NOLINT
+
+ // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
+ static const int kStubMajorKeyFirstBit = 0;
+ static const int kSafepointTableOffsetFirstBit =
+ kStubMajorKeyFirstBit + kStubMajorKeyBits;
+ static const int kSafepointTableOffsetBitCount = 26;
+
+ STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32);
+ STATIC_ASSERT(kSafepointTableOffsetFirstBit +
+ kSafepointTableOffsetBitCount <= 32);
+
+ class SafepointTableOffsetField: public BitField<int,
+ kSafepointTableOffsetFirstBit,
+ kSafepointTableOffsetBitCount> {}; // NOLINT
+ class StubMajorKeyField: public BitField<int,
+ kStubMajorKeyFirstBit, kStubMajorKeyBits> {}; // NOLINT
+
+ // KindSpecificFlags2 layout (FUNCTION)
+ class StackCheckTableOffsetField: public BitField<int, 0, 31> {};
// Signed field cannot be encoded using the BitField class.
- static const int kArgumentsCountShift = 15;
+ static const int kArgumentsCountShift = 14;
static const int kArgumentsCountMask = ~((1 << kArgumentsCountShift) - 1);
// This constant should be encodable in an ARM instruction.
@@ -4608,12 +4692,16 @@ class Map: public HeapObject {
inline void set_bit_field2(byte value);
// Bit field 3.
- // TODO(1399): It should be possible to make room for bit_field3 in the map
- // without overloading the instance descriptors field (and storing it in the
- // DescriptorArray when the map has one).
inline int bit_field3();
inline void set_bit_field3(int value);
+ class EnumLengthBits: public BitField<int, 0, 11> {};
+ class NumberOfOwnDescriptorsBits: public BitField<int, 11, 11> {};
+ class IsShared: public BitField<bool, 22, 1> {};
+ class FunctionWithPrototype: public BitField<bool, 23, 1> {};
+ class DictionaryMap: public BitField<bool, 24, 1> {};
+ class OwnsDescriptors: public BitField<bool, 25, 1> {};
+
// Tells whether the object in the prototype property will be used
// for instances created from this function. If the prototype
// property is set to a value that is not a JSObject, the prototype
@@ -4733,8 +4821,19 @@ class Map: public HeapObject {
static bool IsValidElementsTransition(ElementsKind from_kind,
ElementsKind to_kind);
+ inline bool HasTransitionArray();
+ inline bool HasElementsTransition();
inline Map* elements_transition_map();
- inline void set_elements_transition_map(Map* transitioned_map);
+ MUST_USE_RESULT inline MaybeObject* set_elements_transition_map(
+ Map* transitioned_map);
+ inline void SetTransition(int transition_index, Map* target);
+ inline Map* GetTransition(int transition_index);
+ MUST_USE_RESULT inline MaybeObject* AddTransition(String* key,
+ Map* target,
+ SimpleTransitionFlag flag);
+ DECL_ACCESSORS(transitions, TransitionArray)
+ inline void ClearTransitions(Heap* heap,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// Tells whether the map is attached to SharedFunctionInfo
// (for inobject slack tracking).
@@ -4748,6 +4847,13 @@ class Map: public HeapObject {
inline void set_is_shared(bool value);
inline bool is_shared();
+ // Tells whether the map is used for JSObjects in dictionary mode (ie
+ // normalized objects, ie objects for which HasFastProperties returns false).
+ // A map can never be used for both dictionary mode and fast mode JSObjects.
+ // False by default and for HeapObjects that are not JSObjects.
+ inline void set_dictionary_map(bool value);
+ inline bool is_dictionary_map();
+
// Tells whether the instance needs security checks when accessing its
// properties.
inline void set_is_access_check_needed(bool access_check_needed);
@@ -4761,16 +4867,9 @@ class Map: public HeapObject {
inline JSFunction* unchecked_constructor();
- // Should only be called by the code that initializes map to set initial valid
- // value of the instance descriptor member.
- inline void init_instance_descriptors();
-
// [instance descriptors]: describes the object.
DECL_ACCESSORS(instance_descriptors, DescriptorArray)
-
- // Sets the instance descriptor array for the map to be an empty descriptor
- // array.
- inline void clear_instance_descriptors();
+ inline void InitializeDescriptors(DescriptorArray* descriptors);
// [stub cache]: contains stubs compiled for this map.
DECL_ACCESSORS(code_cache, Object)
@@ -4782,6 +4881,7 @@ class Map: public HeapObject {
inline Object* GetBackPointer();
inline void SetBackPointer(Object* value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+ inline void init_back_pointer(Object* undefined);
// [prototype transitions]: cache of prototype transitions.
// Prototype transition is a transition that happens
@@ -4791,27 +4891,29 @@ class Map: public HeapObject {
// 1: back pointer that overlaps with prototype transitions field.
// 2 + 2 * i: prototype
// 3 + 2 * i: target map
- DECL_ACCESSORS(prototype_transitions, FixedArray)
+ inline FixedArray* GetPrototypeTransitions();
+ MUST_USE_RESULT inline MaybeObject* SetPrototypeTransitions(
+ FixedArray* prototype_transitions);
+ inline bool HasPrototypeTransitions();
- inline void init_prototype_transitions(Object* undefined);
- inline HeapObject* unchecked_prototype_transitions();
+ inline HeapObject* UncheckedPrototypeTransitions();
+ inline TransitionArray* unchecked_transition_array();
- static const int kProtoTransitionHeaderSize = 2;
+ static const int kProtoTransitionHeaderSize = 1;
static const int kProtoTransitionNumberOfEntriesOffset = 0;
- static const int kProtoTransitionBackPointerOffset = 1;
static const int kProtoTransitionElementsPerEntry = 2;
static const int kProtoTransitionPrototypeOffset = 0;
static const int kProtoTransitionMapOffset = 1;
inline int NumberOfProtoTransitions() {
- FixedArray* cache = prototype_transitions();
+ FixedArray* cache = GetPrototypeTransitions();
if (cache->length() == 0) return 0;
return
Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value();
}
inline void SetNumberOfProtoTransitions(int value) {
- FixedArray* cache = prototype_transitions();
+ FixedArray* cache = GetPrototypeTransitions();
ASSERT(cache->length() != 0);
cache->set_unchecked(kProtoTransitionNumberOfEntriesOffset,
Smi::FromInt(value));
@@ -4820,19 +4922,84 @@ class Map: public HeapObject {
// Lookup in the map's instance descriptors and fill out the result
// with the given holder if the name is found. The holder may be
// NULL when this function is used from the compiler.
- void LookupInDescriptors(JSObject* holder,
- String* name,
- LookupResult* result);
+ inline void LookupDescriptor(JSObject* holder,
+ String* name,
+ LookupResult* result);
+
+ inline void LookupTransition(JSObject* holder,
+ String* name,
+ LookupResult* result);
+
+ // The size of transition arrays are limited so they do not end up in large
+ // object space. Otherwise ClearNonLiveTransitions would leak memory while
+ // applying in-place right trimming.
+ inline bool CanHaveMoreTransitions();
+
+ int LastAdded() {
+ int number_of_own_descriptors = NumberOfOwnDescriptors();
+ ASSERT(number_of_own_descriptors > 0);
+ return number_of_own_descriptors - 1;
+ }
+
+ int NumberOfOwnDescriptors() {
+ return NumberOfOwnDescriptorsBits::decode(bit_field3());
+ }
+
+ void SetNumberOfOwnDescriptors(int number) {
+ ASSERT(number <= instance_descriptors()->number_of_descriptors());
+ set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number));
+ }
+ inline JSGlobalPropertyCell* RetrieveDescriptorsPointer();
+
+ int EnumLength() {
+ return EnumLengthBits::decode(bit_field3());
+ }
+
+ void SetEnumLength(int length) {
+ if (length != kInvalidEnumCache) {
+ ASSERT(length >= 0);
+ ASSERT(length == 0 || instance_descriptors()->HasEnumCache());
+ ASSERT(length <= NumberOfOwnDescriptors());
+ }
+ set_bit_field3(EnumLengthBits::update(bit_field3(), length));
+ }
+
+
+ inline bool owns_descriptors();
+ inline void set_owns_descriptors(bool is_shared);
+
+ MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
+ MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors();
MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
+ MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors(
+ DescriptorArray* descriptors,
+ String* name,
+ TransitionFlag flag,
+ int descriptor_index);
+ MUST_USE_RESULT MaybeObject* ShareDescriptor(DescriptorArray* descriptors,
+ Descriptor* descriptor);
+ MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor,
+ TransitionFlag flag);
+ MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor,
+ TransitionFlag flag);
+ MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(
+ DescriptorArray* descriptors,
+ Descriptor* descriptor,
+ int index,
+ TransitionFlag flag);
+ MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind,
+ TransitionFlag flag);
MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode,
NormalizedMapSharingMode sharing);
+ inline void AppendDescriptor(Descriptor* desc,
+ const DescriptorArray::WhitenessWitness&);
+
// Returns a copy of the map, with all transitions dropped from the
// instance descriptors.
- MUST_USE_RESULT MaybeObject* CopyDropTransitions(
- DescriptorArray::SharedMode shared_mode);
+ MUST_USE_RESULT MaybeObject* Copy();
// Returns the property index for name (only valid for FAST MODE).
int PropertyIndexFor(String* name);
@@ -4842,7 +5009,8 @@ class Map: public HeapObject {
// Returns the number of properties described in instance_descriptors
// filtering out properties with the specified attributes.
- int NumberOfDescribedProperties(PropertyAttributes filter = NONE);
+ int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
+ PropertyAttributes filter = NONE);
// Casting.
static inline Map* cast(Object* obj);
@@ -4861,6 +5029,13 @@ class Map: public HeapObject {
Handle<Code> code);
MUST_USE_RESULT MaybeObject* UpdateCodeCache(String* name, Code* code);
+ // Extend the descriptor array of the map with the list of descriptors.
+ // In case of duplicates, the latest descriptor is used.
+ static void AppendCallbackDescriptors(Handle<Map> map,
+ Handle<Object> descriptors);
+
+ static void EnsureDescriptorSlack(Handle<Map> map, int slack);
+
// Returns the found code or undefined if absent.
Object* FindInCodeCache(String* name, Code::Flags flags);
@@ -4891,24 +5066,20 @@ class Map: public HeapObject {
// allowed.
Map* LookupElementsTransitionMap(ElementsKind elements_kind);
- // Adds a new transitions for changing the elements kind to |elements_kind|.
- MUST_USE_RESULT MaybeObject* CreateNextElementsTransition(
- ElementsKind elements_kind);
-
// Returns the transitioned map for this map with the most generic
// elements_kind that's found in |candidates|, or null handle if no match is
// found at all.
Handle<Map> FindTransitionedMap(MapHandleList* candidates);
Map* FindTransitionedMap(MapList* candidates);
- // Zaps the contents of backing data structures in debug mode. Note that the
+ // Zaps the contents of backing data structures. Note that the
// heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
// holding weak references when incremental marking is used, because it also
// iterates over objects that are otherwise unreachable.
-#ifdef DEBUG
- void ZapInstanceDescriptors();
+ // In general we only want to call these functions in release mode when
+ // heap verification is turned on.
void ZapPrototypeTransitions();
-#endif
+ void ZapTransitions();
// Dispatched behavior.
#ifdef OBJECT_PRINT
@@ -4917,8 +5088,9 @@ class Map: public HeapObject {
}
void MapPrint(FILE* out);
#endif
-#ifdef DEBUG
- void MapVerify();
+ DECLARE_VERIFIER(Map)
+
+#ifdef VERIFY_HEAP
void SharedMapVerify();
#endif
@@ -4945,35 +5117,31 @@ class Map: public HeapObject {
static const int kMaxPreAllocatedPropertyFields = 255;
+ // Constant for denoting that the enum cache is not yet initialized.
+ static const int kInvalidEnumCache = EnumLengthBits::kMax;
+
// Layout description.
static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize;
static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
- // Storage for instance descriptors is overloaded to also contain additional
- // map flags when unused (bit_field3). When the map has instance descriptors,
- // the flags are transferred to the instance descriptor array and accessed
- // through an extra indirection.
- // TODO(1399): It should be possible to make room for bit_field3 in the map
- // without overloading the instance descriptors field, but the map is
- // currently perfectly aligned to 32 bytes and extending it at all would
- // double its size. After the increment GC work lands, this size restriction
- // could be loosened and bit_field3 moved directly back in the map.
- static const int kInstanceDescriptorsOrBitField3Offset =
+ // Storage for the transition array is overloaded to directly contain a back
+ // pointer if unused. When the map has transitions, the back pointer is
+ // transferred to the transition array and accessed through an extra
+ // indirection.
+ static const int kTransitionsOrBackPointerOffset =
kConstructorOffset + kPointerSize;
+ static const int kDescriptorsOffset =
+ kTransitionsOrBackPointerOffset + kPointerSize;
static const int kCodeCacheOffset =
- kInstanceDescriptorsOrBitField3Offset + kPointerSize;
- static const int kPrototypeTransitionsOrBackPointerOffset =
- kCodeCacheOffset + kPointerSize;
- static const int kPadStart =
- kPrototypeTransitionsOrBackPointerOffset + kPointerSize;
- static const int kSize = MAP_POINTER_ALIGN(kPadStart);
+ kDescriptorsOffset + kPointerSize;
+ static const int kBitField3Offset = kCodeCacheOffset + kPointerSize;
+ static const int kSize = kBitField3Offset + kPointerSize;
// Layout of pointer fields. Heap iteration code relies on them
// being continuously allocated.
static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
- static const int kPointerFieldsEndOffset =
- kPrototypeTransitionsOrBackPointerOffset + kPointerSize;
+ static const int kPointerFieldsEndOffset = kBitField3Offset + kPointerSize;
// Byte offsets within kInstanceSizesOffset.
static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
@@ -5028,10 +5196,6 @@ class Map: public HeapObject {
static_cast<int8_t>((FAST_HOLEY_SMI_ELEMENTS + 1) <<
Map::kElementsKindShift) - 1;
- // Bit positions for bit field 3
- static const int kIsShared = 0;
- static const int kFunctionWithPrototype = 1;
-
typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
kPointerFieldsEndOffset,
kSize> BodyDescriptor;
@@ -5130,9 +5294,7 @@ class Script: public Struct {
}
void ScriptPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ScriptVerify();
-#endif
+ DECLARE_VERIFIER(Script)
static const int kSourceOffset = HeapObject::kHeaderSize;
static const int kNameOffset = kSourceOffset + kPointerSize;
@@ -5217,6 +5379,29 @@ class SharedFunctionInfo: public HeapObject {
// [code]: Function code.
DECL_ACCESSORS(code, Code)
+ // [optimized_code_map]: Map from native context to optimized code
+ // and a shared literals array or Smi 0 if none.
+ DECL_ACCESSORS(optimized_code_map, Object)
+
+ // Returns index i of the entry with the specified context. At position
+ // i - 1 is the context, position i the code, and i + 1 the literals array.
+ // Returns -1 when no matching entry is found.
+ int SearchOptimizedCodeMap(Context* native_context);
+
+ // Installs optimized code from the code map on the given closure. The
+ // index has to be consistent with a search result as defined above.
+ void InstallFromOptimizedCodeMap(JSFunction* function, int index);
+
+ // Clear optimized code map.
+ void ClearOptimizedCodeMap();
+
+ // Add a new entry to the optimized code map.
+ static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
+ Handle<Context> native_context,
+ Handle<Code> code,
+ Handle<FixedArray> literals);
+ static const int kEntryLength = 3;
+
// [scope_info]: Scope info.
DECL_ACCESSORS(scope_info, ScopeInfo)
@@ -5324,6 +5509,10 @@ class SharedFunctionInfo: public HeapObject {
// IsInobjectSlackTrackingInProgress is false after this call.
void CompleteInobjectSlackTracking();
+ // Invoked before pointers in SharedFunctionInfo are being marked.
+ // Also clears the optimized code map.
+ inline void BeforeVisitingPointers();
+
// Clears the initial_map before the GC marking phase to ensure the reference
// is weak. IsInobjectSlackTrackingInProgress is false after this call.
void DetachInitialMap();
@@ -5436,6 +5625,12 @@ class SharedFunctionInfo: public HeapObject {
// when doing GC if we expect that the function will no longer be used.
DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
+ // Indicates if this function can be lazy compiled without a context.
+ // This is used to determine if we can force compilation without reaching
+ // the function through program execution but through other means (e.g. heap
+ // iteration by the debugger).
+ DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation_without_context)
+
// Indicates how many full GCs this function has survived with assigned
// code object. Used to determine when it is relatively safe to flush
// this code object and replace it with lazy compilation stub.
@@ -5500,6 +5695,9 @@ class SharedFunctionInfo: public HeapObject {
// Indicates that the function cannot be inlined.
DECL_BOOLEAN_ACCESSORS(dont_inline)
+ // Indicates that code for this function cannot be cached.
+ DECL_BOOLEAN_ACCESSORS(dont_cache)
+
// Indicates whether or not the code in the shared function support
// deoptimization.
inline bool has_deoptimization_support();
@@ -5509,12 +5707,12 @@ class SharedFunctionInfo: public HeapObject {
// Disable (further) attempted optimization of all functions sharing this
// shared function info.
- void DisableOptimization();
+ void DisableOptimization(const char* reason);
// Lookup the bailout ID and ASSERT that it exists in the non-optimized
// code, returns whether it asserted (i.e., always true if assertions are
// disabled).
- bool VerifyBailoutId(int id);
+ bool VerifyBailoutId(BailoutId id);
// Check whether a inlined constructor can be generated with the given
// prototype.
@@ -5576,21 +5774,16 @@ class SharedFunctionInfo: public HeapObject {
}
void SharedFunctionInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void SharedFunctionInfoVerify();
-#endif
+ DECLARE_VERIFIER(SharedFunctionInfo)
void ResetForNewContext(int new_ic_age);
- // Helpers to compile the shared code. Returns true on success, false on
- // failure (e.g., stack overflow during compilation).
- static bool EnsureCompiled(Handle<SharedFunctionInfo> shared,
- ClearExceptionFlag flag);
+ // Helper to compile the shared code. Returns true on success, false on
+ // failure (e.g., stack overflow during compilation). This is only used by
+ // the debugger, it is not possible to compile without a context otherwise.
static bool CompileLazy(Handle<SharedFunctionInfo> shared,
ClearExceptionFlag flag);
- void SharedFunctionInfoIterateBody(ObjectVisitor* v);
-
// Casting.
static inline SharedFunctionInfo* cast(Object* obj);
@@ -5601,7 +5794,8 @@ class SharedFunctionInfo: public HeapObject {
// Pointer fields.
static const int kNameOffset = HeapObject::kHeaderSize;
static const int kCodeOffset = kNameOffset + kPointerSize;
- static const int kScopeInfoOffset = kCodeOffset + kPointerSize;
+ static const int kOptimizedCodeMapOffset = kCodeOffset + kPointerSize;
+ static const int kScopeInfoOffset = kOptimizedCodeMapOffset + kPointerSize;
static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize;
static const int kInstanceClassNameOffset =
kConstructStubOffset + kPointerSize;
@@ -5719,6 +5913,7 @@ class SharedFunctionInfo: public HeapObject {
enum CompilerHints {
kHasOnlySimpleThisPropertyAssignments,
kAllowLazyCompilation,
+ kAllowLazyCompilationWithoutContext,
kLiveObjectsMayExist,
kCodeAgeShift,
kOptimizationDisabled = kCodeAgeShift + kCodeAgeSize,
@@ -5733,6 +5928,7 @@ class SharedFunctionInfo: public HeapObject {
kIsFunction,
kDontOptimize,
kDontInline,
+ kDontCache,
kCompilerHintsCount // Pseudo entry
};
@@ -5799,6 +5995,9 @@ class JSModule: public JSObject {
// [context]: the context holding the module's locals, or undefined if none.
DECL_ACCESSORS(context, Object)
+ // [scope_info]: Scope info.
+ DECL_ACCESSORS(scope_info, ScopeInfo)
+
// Casting.
static inline JSModule* cast(Object* obj);
@@ -5809,13 +6008,12 @@ class JSModule: public JSObject {
}
void JSModulePrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSModuleVerify();
-#endif
+ DECLARE_VERIFIER(JSModule)
// Layout description.
static const int kContextOffset = JSObject::kHeaderSize;
- static const int kSize = kContextOffset + kPointerSize;
+ static const int kScopeInfoOffset = kContextOffset + kPointerSize;
+ static const int kSize = kScopeInfoOffset + kPointerSize;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSModule);
@@ -5864,18 +6062,26 @@ class JSFunction: public JSObject {
// Mark this function for lazy recompilation. The function will be
// recompiled the next time it is executed.
void MarkForLazyRecompilation();
+ void MarkForParallelRecompilation();
// Helpers to compile this function. Returns true on success, false on
// failure (e.g., stack overflow during compilation).
+ static bool EnsureCompiled(Handle<JSFunction> function,
+ ClearExceptionFlag flag);
static bool CompileLazy(Handle<JSFunction> function,
ClearExceptionFlag flag);
static bool CompileOptimized(Handle<JSFunction> function,
- int osr_ast_id,
+ BailoutId osr_ast_id,
ClearExceptionFlag flag);
// Tells whether or not the function is already marked for lazy
// recompilation.
inline bool IsMarkedForLazyRecompilation();
+ inline bool IsMarkedForParallelRecompilation();
+
+ // Tells whether or not the function is on the parallel
+ // recompilation queue.
+ inline bool IsInRecompileQueue();
// Check whether or not this function is inlineable.
bool IsInlineable();
@@ -5922,7 +6128,7 @@ class JSFunction: public JSObject {
// After prototype is removed, it will not be created when accessed, and
// [[Construct]] from this function will not be allowed.
- Object* RemovePrototype();
+ void RemovePrototype();
inline bool should_have_prototype();
// Accessor for this function's initial map's [[class]]
@@ -5934,7 +6140,7 @@ class JSFunction: public JSObject {
// Instances created afterwards will have a map whose [[class]] is
// set to 'value', but there is no guarantees on instances created
// before.
- Object* SetInstanceClassName(String* name);
+ void SetInstanceClassName(String* name);
// Returns if this function has been compiled to native code yet.
inline bool is_compiled();
@@ -5963,15 +6169,13 @@ class JSFunction: public JSObject {
}
void JSFunctionPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSFunctionVerify();
-#endif
+ DECLARE_VERIFIER(JSFunction)
// Returns the number of allocated literals.
inline int NumberOfLiterals();
- // Retrieve the global context from a function's literal array.
- static Context* GlobalContextFromLiterals(FixedArray* literals);
+ // Retrieve the native context from a function's literal array.
+ static Context* NativeContextFromLiterals(FixedArray* literals);
// Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
// kSize) is weak and has special handling during garbage collection.
@@ -5988,7 +6192,7 @@ class JSFunction: public JSObject {
// Layout of the literals array.
static const int kLiteralsPrefixSize = 1;
- static const int kLiteralGlobalContextIndex = 0;
+ static const int kLiteralNativeContextIndex = 0;
// Layout of the bound-function binding array.
static const int kBoundFunctionIndex = 0;
@@ -6010,9 +6214,9 @@ class JSFunction: public JSObject {
class JSGlobalProxy : public JSObject {
public:
- // [context]: the owner global context of this global proxy object.
+ // [native_context]: the owner native context of this global proxy object.
// It is null value if this object is not used by any context.
- DECL_ACCESSORS(context, Object)
+ DECL_ACCESSORS(native_context, Object)
// Casting.
static inline JSGlobalProxy* cast(Object* obj);
@@ -6024,13 +6228,11 @@ class JSGlobalProxy : public JSObject {
}
void JSGlobalProxyPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSGlobalProxyVerify();
-#endif
+ DECLARE_VERIFIER(JSGlobalProxy)
// Layout description.
- static const int kContextOffset = JSObject::kHeaderSize;
- static const int kSize = kContextOffset + kPointerSize;
+ static const int kNativeContextOffset = JSObject::kHeaderSize;
+ static const int kSize = kNativeContextOffset + kPointerSize;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
@@ -6047,7 +6249,10 @@ class GlobalObject: public JSObject {
// [builtins]: the object holding the runtime routines written in JS.
DECL_ACCESSORS(builtins, JSBuiltinsObject)
- // [global context]: the global context corresponding to this global object.
+ // [native context]: the natives corresponding to this global object.
+ DECL_ACCESSORS(native_context, Context)
+
+ // [global context]: the most recent (i.e. innermost) global context.
DECL_ACCESSORS(global_context, Context)
// [global receiver]: the global receiver object of the context
@@ -6078,7 +6283,8 @@ class GlobalObject: public JSObject {
// Layout description.
static const int kBuiltinsOffset = JSObject::kHeaderSize;
- static const int kGlobalContextOffset = kBuiltinsOffset + kPointerSize;
+ static const int kNativeContextOffset = kBuiltinsOffset + kPointerSize;
+ static const int kGlobalContextOffset = kNativeContextOffset + kPointerSize;
static const int kGlobalReceiverOffset = kGlobalContextOffset + kPointerSize;
static const int kHeaderSize = kGlobalReceiverOffset + kPointerSize;
@@ -6100,9 +6306,7 @@ class JSGlobalObject: public GlobalObject {
}
void JSGlobalObjectPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSGlobalObjectVerify();
-#endif
+ DECLARE_VERIFIER(JSGlobalObject)
// Layout description.
static const int kSize = GlobalObject::kHeaderSize;
@@ -6134,9 +6338,7 @@ class JSBuiltinsObject: public GlobalObject {
}
void JSBuiltinsObjectPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSBuiltinsObjectVerify();
-#endif
+ DECLARE_VERIFIER(JSBuiltinsObject)
// Layout description. The size of the builtins object includes
// room for two pointers per runtime routine written in javascript
@@ -6177,9 +6379,7 @@ class JSValue: public JSObject {
}
void JSValuePrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSValueVerify();
-#endif
+ DECLARE_VERIFIER(JSValue)
// Layout description.
static const int kValueOffset = JSObject::kHeaderSize;
@@ -6233,9 +6433,8 @@ class JSDate: public JSObject {
}
void JSDatePrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSDateVerify();
-#endif
+ DECLARE_VERIFIER(JSDate)
+
// The order is important. It must be kept in sync with date macros
// in macros.py.
enum FieldIndex {
@@ -6331,9 +6530,7 @@ class JSMessageObject: public JSObject {
}
void JSMessageObjectPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSMessageObjectVerify();
-#endif
+ DECLARE_VERIFIER(JSMessageObject)
// Layout description.
static const int kTypeOffset = JSObject::kHeaderSize;
@@ -6422,9 +6619,7 @@ class JSRegExp: public JSObject {
static inline JSRegExp* cast(Object* obj);
// Dispatched behavior.
-#ifdef DEBUG
- void JSRegExpVerify();
-#endif
+ DECLARE_VERIFIER(JSRegExp)
static const int kDataOffset = JSObject::kHeaderSize;
static const int kSize = kDataOffset + kPointerSize;
@@ -6524,13 +6719,15 @@ class CompilationCacheTable: public HashTable<CompilationCacheShape,
HashTableKey*> {
public:
// Find cached value for a string key, otherwise return null.
- Object* Lookup(String* src);
+ Object* Lookup(String* src, Context* context);
Object* LookupEval(String* src,
Context* context,
LanguageMode language_mode,
int scope_position);
Object* LookupRegExp(String* source, JSRegExp::Flags flags);
- MUST_USE_RESULT MaybeObject* Put(String* src, Object* value);
+ MUST_USE_RESULT MaybeObject* Put(String* src,
+ Context* context,
+ Object* value);
MUST_USE_RESULT MaybeObject* PutEval(String* src,
Context* context,
SharedFunctionInfo* value,
@@ -6578,9 +6775,7 @@ class CodeCache: public Struct {
}
void CodeCachePrint(FILE* out);
#endif
-#ifdef DEBUG
- void CodeCacheVerify();
-#endif
+ DECLARE_VERIFIER(CodeCache)
static const int kDefaultCacheOffset = HeapObject::kHeaderSize;
static const int kNormalTypeCacheOffset =
@@ -6669,9 +6864,7 @@ class PolymorphicCodeCache: public Struct {
}
void PolymorphicCodeCachePrint(FILE* out);
#endif
-#ifdef DEBUG
- void PolymorphicCodeCacheVerify();
-#endif
+ DECLARE_VERIFIER(PolymorphicCodeCache)
static const int kCacheOffset = HeapObject::kHeaderSize;
static const int kSize = kCacheOffset + kPointerSize;
@@ -6704,7 +6897,15 @@ class TypeFeedbackInfo: public Struct {
inline void set_ic_total_count(int count);
inline int ic_with_type_info_count();
- inline void set_ic_with_type_info_count(int count);
+ inline void change_ic_with_type_info_count(int count);
+
+ inline void initialize_storage();
+
+ inline void change_own_type_change_checksum();
+ inline int own_type_change_checksum();
+
+ inline void set_inlined_type_change_checksum(int checksum);
+ inline bool matches_inlined_type_change_checksum(int checksum);
DECL_ACCESSORS(type_feedback_cells, TypeFeedbackCells)
@@ -6716,18 +6917,27 @@ class TypeFeedbackInfo: public Struct {
}
void TypeFeedbackInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void TypeFeedbackInfoVerify();
-#endif
+ DECLARE_VERIFIER(TypeFeedbackInfo)
- static const int kIcTotalCountOffset = HeapObject::kHeaderSize;
- static const int kIcWithTypeinfoCountOffset =
- kIcTotalCountOffset + kPointerSize;
- static const int kTypeFeedbackCellsOffset =
- kIcWithTypeinfoCountOffset + kPointerSize;
+ static const int kStorage1Offset = HeapObject::kHeaderSize;
+ static const int kStorage2Offset = kStorage1Offset + kPointerSize;
+ static const int kTypeFeedbackCellsOffset = kStorage2Offset + kPointerSize;
static const int kSize = kTypeFeedbackCellsOffset + kPointerSize;
private:
+ static const int kTypeChangeChecksumBits = 7;
+
+ class ICTotalCountField: public BitField<int, 0,
+ kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
+ class OwnTypeChangeChecksum: public BitField<int,
+ kSmiValueSize - kTypeChangeChecksumBits,
+ kTypeChangeChecksumBits> {}; // NOLINT
+ class ICsWithTypeInfoCountField: public BitField<int, 0,
+ kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
+ class InlinedTypeChangeChecksum: public BitField<int,
+ kSmiValueSize - kTypeChangeChecksumBits,
+ kTypeChangeChecksumBits> {}; // NOLINT
+
DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
};
@@ -6753,9 +6963,7 @@ class AliasedArgumentsEntry: public Struct {
}
void AliasedArgumentsEntryPrint(FILE* out);
#endif
-#ifdef DEBUG
- void AliasedArgumentsEntryVerify();
-#endif
+ DECLARE_VERIFIER(AliasedArgumentsEntry)
static const int kAliasedContextSlot = HeapObject::kHeaderSize;
static const int kSize = kAliasedContextSlot + kPointerSize;
@@ -6798,10 +7006,6 @@ class StringHasher {
// index.
bool is_array_index() { return is_array_index_; }
- bool is_valid() { return is_valid_; }
-
- void invalidate() { is_valid_ = false; }
-
// Calculated hash value for a string consisting of 1 to
// String::kMaxArrayIndexSize digits with no leading zeros (except "0").
// value is represented decimal value.
@@ -6820,13 +7024,33 @@ class StringHasher {
inline uint32_t GetHash();
+ // Reusable parts of the hashing algorithm.
+ INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint32_t c));
+ INLINE(static uint32_t GetHashCore(uint32_t running_hash));
+
int length_;
uint32_t raw_running_hash_;
uint32_t array_index_;
bool is_array_index_;
bool is_first_char_;
- bool is_valid_;
friend class TwoCharHashTableKey;
+
+ template <bool seq_ascii> friend class JsonParser;
+};
+
+
+class IncrementalAsciiStringHasher {
+ public:
+ explicit inline IncrementalAsciiStringHasher(uint32_t seed, char first_char);
+ inline void AddCharacter(uc32 c);
+ inline uint32_t GetHash();
+
+ private:
+ int length_;
+ uint32_t raw_running_hash_;
+ uint32_t array_index_;
+ bool is_array_index_;
+ char first_char_;
};
@@ -7086,9 +7310,8 @@ class String: public HeapObject {
char* ToAsciiArray();
#endif
-#ifdef DEBUG
- void StringVerify();
-#endif
+ DECLARE_VERIFIER(String)
+
inline bool IsFlat();
// Layout description.
@@ -7157,7 +7380,7 @@ class String: public HeapObject {
kIsNotArrayIndexMask | kHashNotComputedMask;
// Value of hash field containing computed hash equal to zero.
- static const int kZeroHash = kIsNotArrayIndexMask;
+ static const int kEmptyStringHash = kIsNotArrayIndexMask;
// Maximal string length.
static const int kMaxLength = (1 << (32 - 2)) - 1;
@@ -7192,32 +7415,47 @@ class String: public HeapObject {
int from,
int to);
- static inline bool IsAscii(const char* chars, int length) {
+ // The return value may point to the first aligned word containing the
+ // first non-ascii character, rather than directly to the non-ascii character.
+ // If the return value is >= the passed length, the entire string was ASCII.
+ static inline int NonAsciiStart(const char* chars, int length) {
+ const char* start = chars;
const char* limit = chars + length;
#ifdef V8_HOST_CAN_READ_UNALIGNED
ASSERT(kMaxAsciiCharCode == 0x7F);
const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
- while (chars <= limit - sizeof(uintptr_t)) {
+ while (chars + sizeof(uintptr_t) <= limit) {
if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
- return false;
+ return static_cast<int>(chars - start);
}
chars += sizeof(uintptr_t);
}
#endif
while (chars < limit) {
- if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) return false;
+ if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) {
+ return static_cast<int>(chars - start);
+ }
++chars;
}
- return true;
+ return static_cast<int>(chars - start);
}
- static inline bool IsAscii(const uc16* chars, int length) {
+ static inline bool IsAscii(const char* chars, int length) {
+ return NonAsciiStart(chars, length) >= length;
+ }
+
+ static inline int NonAsciiStart(const uc16* chars, int length) {
const uc16* limit = chars + length;
+ const uc16* start = chars;
while (chars < limit) {
- if (*chars > kMaxAsciiCharCodeU) return false;
+ if (*chars > kMaxAsciiCharCodeU) return static_cast<int>(chars - start);
++chars;
}
- return true;
+ return static_cast<int>(chars - start);
+ }
+
+ static inline bool IsAscii(const uc16* chars, int length) {
+ return NonAsciiStart(chars, length) >= length;
}
protected:
@@ -7325,9 +7563,7 @@ class SeqAsciiString: public SeqString {
unsigned* offset,
unsigned chars);
-#ifdef DEBUG
- void SeqAsciiStringVerify();
-#endif
+ DECLARE_VERIFIER(SeqAsciiString)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SeqAsciiString);
@@ -7432,9 +7668,7 @@ class ConsString: public String {
typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
BodyDescriptor;
-#ifdef DEBUG
- void ConsStringVerify();
-#endif
+ DECLARE_VERIFIER(ConsString)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
@@ -7456,7 +7690,8 @@ class ConsString: public String {
class SlicedString: public String {
public:
inline String* parent();
- inline void set_parent(String* parent);
+ inline void set_parent(String* parent,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline int offset();
inline void set_offset(int offset);
@@ -7485,9 +7720,7 @@ class SlicedString: public String {
kOffsetOffset + kPointerSize, kSize>
BodyDescriptor;
-#ifdef DEBUG
- void SlicedStringVerify();
-#endif
+ DECLARE_VERIFIER(SlicedString)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
@@ -7714,9 +7947,7 @@ class Oddball: public HeapObject {
static inline Oddball* cast(Object* obj);
// Dispatched behavior.
-#ifdef DEBUG
- void OddballVerify();
-#endif
+ DECLARE_VERIFIER(Oddball)
// Initialize the fields.
MUST_USE_RESULT MaybeObject* Initialize(const char* to_string,
@@ -7759,9 +7990,16 @@ class JSGlobalPropertyCell: public HeapObject {
// Casting.
static inline JSGlobalPropertyCell* cast(Object* obj);
-#ifdef DEBUG
- void JSGlobalPropertyCellVerify();
-#endif
+ static inline JSGlobalPropertyCell* FromValueAddress(Address value) {
+ return cast(FromAddress(value - kValueOffset));
+ }
+
+ inline Address ValueAddress() {
+ return address() + kValueOffset;
+ }
+
+ DECLARE_VERIFIER(JSGlobalPropertyCell)
+
#ifdef OBJECT_PRINT
inline void JSGlobalPropertyCellPrint() {
JSGlobalPropertyCellPrint(stdout);
@@ -7864,9 +8102,7 @@ class JSProxy: public JSReceiver {
}
void JSProxyPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSProxyVerify();
-#endif
+ DECLARE_VERIFIER(JSProxy)
// Layout description. We add padding so that a proxy has the same
// size as a virgin JSObject. This is essential for becoming a JSObject
@@ -7907,9 +8143,7 @@ class JSFunctionProxy: public JSProxy {
}
void JSFunctionProxyPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSFunctionProxyVerify();
-#endif
+ DECLARE_VERIFIER(JSFunctionProxy)
// Layout description.
static const int kCallTrapOffset = JSProxy::kPaddingOffset;
@@ -7944,9 +8178,7 @@ class JSSet: public JSObject {
}
void JSSetPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSSetVerify();
-#endif
+ DECLARE_VERIFIER(JSSet)
static const int kTableOffset = JSObject::kHeaderSize;
static const int kSize = kTableOffset + kPointerSize;
@@ -7971,9 +8203,7 @@ class JSMap: public JSObject {
}
void JSMapPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSMapVerify();
-#endif
+ DECLARE_VERIFIER(JSMap)
static const int kTableOffset = JSObject::kHeaderSize;
static const int kSize = kTableOffset + kPointerSize;
@@ -8001,9 +8231,7 @@ class JSWeakMap: public JSObject {
}
void JSWeakMapPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSWeakMapVerify();
-#endif
+ DECLARE_VERIFIER(JSWeakMap)
static const int kTableOffset = JSObject::kHeaderSize;
static const int kNextOffset = kTableOffset + kPointerSize;
@@ -8038,9 +8266,7 @@ class Foreign: public HeapObject {
}
void ForeignPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ForeignVerify();
-#endif
+ DECLARE_VERIFIER(Foreign)
// Layout description.
@@ -8097,9 +8323,7 @@ class JSArray: public JSObject {
}
void JSArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSArrayVerify();
-#endif
+ DECLARE_VERIFIER(JSArray)
// Number of element slots to pre-allocate for an empty array.
static const int kPreallocatedArrayElements = 4;
@@ -8178,9 +8402,7 @@ class AccessorInfo: public Struct {
}
void AccessorInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void AccessorInfoVerify();
-#endif
+ DECLARE_VERIFIER(AccessorInfo)
static const int kGetterOffset = HeapObject::kHeaderSize;
static const int kSetterOffset = kGetterOffset + kPointerSize;
@@ -8214,7 +8436,7 @@ class AccessorPair: public Struct {
static inline AccessorPair* cast(Object* obj);
- MUST_USE_RESULT MaybeObject* CopyWithoutTransitions();
+ MUST_USE_RESULT MaybeObject* Copy();
Object* get(AccessorComponent component) {
return component == ACCESSOR_GETTER ? getter() : setter();
@@ -8244,9 +8466,7 @@ class AccessorPair: public Struct {
#ifdef OBJECT_PRINT
void AccessorPairPrint(FILE* out = stdout);
#endif
-#ifdef DEBUG
- void AccessorPairVerify();
-#endif
+ DECLARE_VERIFIER(AccessorPair)
static const int kGetterOffset = HeapObject::kHeaderSize;
static const int kSetterOffset = kGetterOffset + kPointerSize;
@@ -8280,9 +8500,7 @@ class AccessCheckInfo: public Struct {
}
void AccessCheckInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void AccessCheckInfoVerify();
-#endif
+ DECLARE_VERIFIER(AccessCheckInfo)
static const int kNamedCallbackOffset = HeapObject::kHeaderSize;
static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize;
@@ -8311,9 +8529,7 @@ class InterceptorInfo: public Struct {
}
void InterceptorInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void InterceptorInfoVerify();
-#endif
+ DECLARE_VERIFIER(InterceptorInfo)
static const int kGetterOffset = HeapObject::kHeaderSize;
static const int kSetterOffset = kGetterOffset + kPointerSize;
@@ -8341,9 +8557,7 @@ class CallHandlerInfo: public Struct {
}
void CallHandlerInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void CallHandlerInfoVerify();
-#endif
+ DECLARE_VERIFIER(CallHandlerInfo)
static const int kCallbackOffset = HeapObject::kHeaderSize;
static const int kDataOffset = kCallbackOffset + kPointerSize;
@@ -8359,9 +8573,7 @@ class TemplateInfo: public Struct {
DECL_ACCESSORS(tag, Object)
DECL_ACCESSORS(property_list, Object)
-#ifdef DEBUG
- void TemplateInfoVerify();
-#endif
+ DECLARE_VERIFIER(TemplateInfo)
static const int kTagOffset = HeapObject::kHeaderSize;
static const int kPropertyListOffset = kTagOffset + kPointerSize;
@@ -8404,9 +8616,7 @@ class FunctionTemplateInfo: public TemplateInfo {
}
void FunctionTemplateInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void FunctionTemplateInfoVerify();
-#endif
+ DECLARE_VERIFIER(FunctionTemplateInfo)
static const int kSerialNumberOffset = TemplateInfo::kHeaderSize;
static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize;
@@ -8453,9 +8663,7 @@ class ObjectTemplateInfo: public TemplateInfo {
}
void ObjectTemplateInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ObjectTemplateInfoVerify();
-#endif
+ DECLARE_VERIFIER(ObjectTemplateInfo)
static const int kConstructorOffset = TemplateInfo::kHeaderSize;
static const int kInternalFieldCountOffset =
@@ -8477,9 +8685,7 @@ class SignatureInfo: public Struct {
}
void SignatureInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void SignatureInfoVerify();
-#endif
+ DECLARE_VERIFIER(SignatureInfo)
static const int kReceiverOffset = Struct::kHeaderSize;
static const int kArgsOffset = kReceiverOffset + kPointerSize;
@@ -8502,9 +8708,7 @@ class TypeSwitchInfo: public Struct {
}
void TypeSwitchInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void TypeSwitchInfoVerify();
-#endif
+ DECLARE_VERIFIER(TypeSwitchInfo)
static const int kTypesOffset = Struct::kHeaderSize;
static const int kSize = kTypesOffset + kPointerSize;
@@ -8554,9 +8758,7 @@ class DebugInfo: public Struct {
}
void DebugInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void DebugInfoVerify();
-#endif
+ DECLARE_VERIFIER(DebugInfo)
static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
@@ -8612,9 +8814,7 @@ class BreakPointInfo: public Struct {
}
void BreakPointInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void BreakPointInfoVerify();
-#endif
+ DECLARE_VERIFIER(BreakPointInfo)
static const int kCodePositionIndex = Struct::kHeaderSize;
static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize;
@@ -8632,6 +8832,7 @@ class BreakPointInfo: public Struct {
#undef DECL_BOOLEAN_ACCESSORS
#undef DECL_ACCESSORS
+#undef DECLARE_VERIFIER
#define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \
V(kSymbolTable, "symbol_table", "(Symbols)") \
@@ -8702,8 +8903,6 @@ class ObjectVisitor BASE_EMBEDDED {
// Visit pointer embedded into a code object.
virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
- virtual void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {}
-
// Visits a contiguous arrays of external references (references to the C++
// heap) in the half-open range [start, end). Any or all of the values
// may be modified on return.
diff --git a/deps/v8/src/optimizing-compiler-thread.cc b/deps/v8/src/optimizing-compiler-thread.cc
new file mode 100644
index 000000000..06018dd1a
--- /dev/null
+++ b/deps/v8/src/optimizing-compiler-thread.cc
@@ -0,0 +1,127 @@
+// Copyright 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.
+
+#include "optimizing-compiler-thread.h"
+
+#include "v8.h"
+
+#include "hydrogen.h"
+#include "isolate.h"
+#include "v8threads.h"
+
+namespace v8 {
+namespace internal {
+
+
+void OptimizingCompilerThread::Run() {
+#ifdef DEBUG
+ thread_id_ = ThreadId::Current().ToInteger();
+#endif
+ Isolate::SetIsolateThreadLocals(isolate_, NULL);
+
+ int64_t epoch = 0;
+ if (FLAG_trace_parallel_recompilation) epoch = OS::Ticks();
+
+ while (true) {
+ input_queue_semaphore_->Wait();
+ if (Acquire_Load(&stop_thread_)) {
+ stop_semaphore_->Signal();
+ if (FLAG_trace_parallel_recompilation) {
+ time_spent_total_ = OS::Ticks() - epoch;
+ }
+ return;
+ }
+
+ int64_t compiling_start = 0;
+ if (FLAG_trace_parallel_recompilation) compiling_start = OS::Ticks();
+
+ Heap::RelocationLock relocation_lock(isolate_->heap());
+ OptimizingCompiler* optimizing_compiler = NULL;
+ input_queue_.Dequeue(&optimizing_compiler);
+ Barrier_AtomicIncrement(&queue_length_, static_cast<Atomic32>(-1));
+
+ ASSERT(!optimizing_compiler->info()->closure()->IsOptimized());
+
+ OptimizingCompiler::Status status = optimizing_compiler->OptimizeGraph();
+ ASSERT(status != OptimizingCompiler::FAILED);
+ // Prevent an unused-variable error in release mode.
+ USE(status);
+
+ output_queue_.Enqueue(optimizing_compiler);
+ isolate_->stack_guard()->RequestCodeReadyEvent();
+
+ if (FLAG_trace_parallel_recompilation) {
+ time_spent_compiling_ += OS::Ticks() - compiling_start;
+ }
+ }
+}
+
+
+void OptimizingCompilerThread::Stop() {
+ Release_Store(&stop_thread_, static_cast<AtomicWord>(true));
+ input_queue_semaphore_->Signal();
+ stop_semaphore_->Wait();
+
+ if (FLAG_trace_parallel_recompilation) {
+ double compile_time = static_cast<double>(time_spent_compiling_);
+ double total_time = static_cast<double>(time_spent_total_);
+ double percentage = (compile_time * 100) / total_time;
+ PrintF(" ** Compiler thread did %.2f%% useful work\n", percentage);
+ }
+}
+
+
+void OptimizingCompilerThread::InstallOptimizedFunctions() {
+ HandleScope handle_scope(isolate_);
+ int functions_installed = 0;
+ while (!output_queue_.IsEmpty()) {
+ OptimizingCompiler* compiler = NULL;
+ output_queue_.Dequeue(&compiler);
+ Compiler::InstallOptimizedCode(compiler);
+ functions_installed++;
+ }
+ if (FLAG_trace_parallel_recompilation && functions_installed != 0) {
+ PrintF(" ** Installed %d function(s).\n", functions_installed);
+ }
+}
+
+
+void OptimizingCompilerThread::QueueForOptimization(
+ OptimizingCompiler* optimizing_compiler) {
+ input_queue_.Enqueue(optimizing_compiler);
+ input_queue_semaphore_->Signal();
+}
+
+#ifdef DEBUG
+bool OptimizingCompilerThread::IsOptimizerThread() {
+ if (!FLAG_parallel_recompilation) return false;
+ return ThreadId::Current().ToInteger() == thread_id_;
+}
+#endif
+
+
+} } // namespace v8::internal
diff --git a/deps/v8/src/optimizing-compiler-thread.h b/deps/v8/src/optimizing-compiler-thread.h
new file mode 100644
index 000000000..d5627266d
--- /dev/null
+++ b/deps/v8/src/optimizing-compiler-thread.h
@@ -0,0 +1,101 @@
+// Copyright 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.
+
+#ifndef V8_OPTIMIZING_COMPILER_THREAD_H_
+#define V8_OPTIMIZING_COMPILER_THREAD_H_
+
+#include "atomicops.h"
+#include "platform.h"
+#include "flags.h"
+#include "unbound-queue.h"
+
+namespace v8 {
+namespace internal {
+
+class HGraphBuilder;
+class OptimizingCompiler;
+
+class OptimizingCompilerThread : public Thread {
+ public:
+ explicit OptimizingCompilerThread(Isolate *isolate) :
+ Thread("OptimizingCompilerThread"),
+ isolate_(isolate),
+ stop_semaphore_(OS::CreateSemaphore(0)),
+ input_queue_semaphore_(OS::CreateSemaphore(0)),
+ time_spent_compiling_(0),
+ time_spent_total_(0) {
+ NoBarrier_Store(&stop_thread_, static_cast<AtomicWord>(false));
+ NoBarrier_Store(&queue_length_, static_cast<AtomicWord>(0));
+ }
+
+ void Run();
+ void Stop();
+ void QueueForOptimization(OptimizingCompiler* optimizing_compiler);
+ void InstallOptimizedFunctions();
+
+ inline bool IsQueueAvailable() {
+ // We don't need a barrier since we have a data dependency right
+ // after.
+ Atomic32 current_length = NoBarrier_Load(&queue_length_);
+
+ // This can be queried only from the execution thread.
+ ASSERT(!IsOptimizerThread());
+ // Since only the execution thread increments queue_length_ and
+ // only one thread can run inside an Isolate at one time, a direct
+ // doesn't introduce a race -- queue_length_ may decreased in
+ // meantime, but not increased.
+ return (current_length < FLAG_parallel_recompilation_queue_length);
+ }
+
+#ifdef DEBUG
+ bool IsOptimizerThread();
+#endif
+
+ ~OptimizingCompilerThread() {
+ delete input_queue_semaphore_;
+ delete stop_semaphore_;
+ }
+
+ private:
+ Isolate* isolate_;
+ Semaphore* stop_semaphore_;
+ Semaphore* input_queue_semaphore_;
+ UnboundQueue<OptimizingCompiler*> input_queue_;
+ UnboundQueue<OptimizingCompiler*> output_queue_;
+ volatile AtomicWord stop_thread_;
+ volatile Atomic32 queue_length_;
+ int64_t time_spent_compiling_;
+ int64_t time_spent_total_;
+
+#ifdef DEBUG
+ int thread_id_;
+#endif
+};
+
+} } // namespace v8::internal
+
+#endif // V8_OPTIMIZING_COMPILER_THREAD_H_
diff --git a/deps/v8/src/parser.cc b/deps/v8/src/parser.cc
index 7c51b694c..129bd9546 100644
--- a/deps/v8/src/parser.cc
+++ b/deps/v8/src/parser.cc
@@ -493,10 +493,10 @@ Parser::FunctionState::FunctionState(Parser* parser,
outer_function_state_(parser->current_function_state_),
outer_scope_(parser->top_scope_),
saved_ast_node_id_(isolate->ast_node_id()),
- factory_(isolate) {
+ factory_(isolate, parser->zone()) {
parser->top_scope_ = scope;
parser->current_function_state_ = this;
- isolate->set_ast_node_id(AstNode::kDeclarationsId + 1);
+ isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt());
}
@@ -532,14 +532,13 @@ Parser::FunctionState::~FunctionState() {
// ----------------------------------------------------------------------------
// Implementation of Parser
-Parser::Parser(Handle<Script> script,
+Parser::Parser(CompilationInfo* info,
int parser_flags,
v8::Extension* extension,
- ScriptDataImpl* pre_data,
- Zone* zone)
- : isolate_(script->GetIsolate()),
- symbol_cache_(pre_data ? pre_data->symbol_count() : 0, zone),
- script_(script),
+ ScriptDataImpl* pre_data)
+ : isolate_(info->isolate()),
+ symbol_cache_(pre_data ? pre_data->symbol_count() : 0, info->zone()),
+ script_(info->script()),
scanner_(isolate_->unicode_cache()),
reusable_preparser_(NULL),
top_scope_(NULL),
@@ -553,7 +552,9 @@ Parser::Parser(Handle<Script> script,
allow_modules_((parser_flags & kAllowModules) != 0),
stack_overflow_(false),
parenthesized_function_(false),
- zone_(zone) {
+ zone_(info->zone()),
+ info_(info) {
+ ASSERT(!script_.is_null());
isolate_->set_ast_node_id(0);
if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) {
scanner().SetHarmonyScoping(true);
@@ -564,16 +565,17 @@ Parser::Parser(Handle<Script> script,
}
-FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) {
- ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
-
+FunctionLiteral* Parser::ParseProgram() {
+ ZoneScope zone_scope(zone(), DONT_DELETE_ON_EXIT);
HistogramTimerScope timer(isolate()->counters()->parse());
Handle<String> source(String::cast(script_->source()));
isolate()->counters()->total_parse_size()->Increment(source->length());
+ int64_t start = FLAG_trace_parse ? OS::Ticks() : 0;
fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
// Initialize parser state.
source->TryFlatten();
+ FunctionLiteral* result;
if (source->IsExternalTwoByteString()) {
// Notice that the stream is destroyed at the end of the branch block.
// The last line of the blocks can't be moved outside, even though they're
@@ -581,12 +583,27 @@ FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) {
ExternalTwoByteStringUtf16CharacterStream stream(
Handle<ExternalTwoByteString>::cast(source), 0, source->length());
scanner_.Initialize(&stream);
- return DoParseProgram(info, source, &zone_scope);
+ result = DoParseProgram(info(), source, &zone_scope);
} else {
GenericStringUtf16CharacterStream stream(source, 0, source->length());
scanner_.Initialize(&stream);
- return DoParseProgram(info, source, &zone_scope);
+ result = DoParseProgram(info(), source, &zone_scope);
}
+
+ if (FLAG_trace_parse && result != NULL) {
+ double ms = static_cast<double>(OS::Ticks() - start) / 1000;
+ if (info()->is_eval()) {
+ PrintF("[parsing eval");
+ } else if (info()->script()->name()->IsString()) {
+ String* name = String::cast(info()->script()->name());
+ SmartArrayPointer<char> name_chars = name->ToCString();
+ PrintF("[parsing script: %s", *name_chars);
+ } else {
+ PrintF("[parsing script");
+ }
+ PrintF(" - took %0.3f ms]\n", ms);
+ }
+ return result;
}
@@ -598,32 +615,34 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
if (pre_data_ != NULL) pre_data_->Initialize();
// Compute the parsing mode.
- mode_ = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
- if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
+ Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
+ if (allow_natives_syntax_ || extension_ != NULL) mode = PARSE_EAGERLY;
+ ParsingModeScope parsing_mode(this, mode);
Handle<String> no_name = isolate()->factory()->empty_symbol();
FunctionLiteral* result = NULL;
{ Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
info->SetGlobalScope(scope);
+ if (!info->context().is_null()) {
+ scope = Scope::DeserializeScopeChain(*info->context(), scope, zone());
+ }
if (info->is_eval()) {
- Handle<SharedFunctionInfo> shared = info->shared_info();
- if (!info->is_global() && (shared.is_null() || shared->is_function())) {
- scope = Scope::DeserializeScopeChain(*info->calling_context(), scope,
- zone());
- }
if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) {
scope = NewScope(scope, EVAL_SCOPE);
}
+ } else if (info->is_global()) {
+ scope = NewScope(scope, GLOBAL_SCOPE);
}
scope->set_start_position(0);
scope->set_end_position(source->length());
- FunctionState function_state(this, scope, isolate());
+
+ FunctionState function_state(this, scope, isolate()); // Enters 'scope'.
top_scope_->SetLanguageMode(info->language_mode());
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
bool ok = true;
int beg_loc = scanner().location().beg_pos;
- ParseSourceElements(body, Token::EOS, info->is_eval(), &ok);
+ ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok);
if (ok && !top_scope_->is_classic_mode()) {
CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
}
@@ -645,7 +664,8 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
0,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::ANONYMOUS_EXPRESSION,
- FunctionLiteral::kGlobalOrEval);
+ FunctionLiteral::kGlobalOrEval,
+ FunctionLiteral::kNotParenthesized);
result->set_ast_properties(factory()->visitor()->ast_properties());
} else if (stack_overflow_) {
isolate()->StackOverflow();
@@ -662,36 +682,42 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
}
-FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
- ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
+FunctionLiteral* Parser::ParseLazy() {
+ ZoneScope zone_scope(zone(), DONT_DELETE_ON_EXIT);
HistogramTimerScope timer(isolate()->counters()->parse_lazy());
Handle<String> source(String::cast(script_->source()));
isolate()->counters()->total_parse_size()->Increment(source->length());
+ int64_t start = FLAG_trace_parse ? OS::Ticks() : 0;
+ Handle<SharedFunctionInfo> shared_info = info()->shared_info();
- Handle<SharedFunctionInfo> shared_info = info->shared_info();
// Initialize parser state.
source->TryFlatten();
+ FunctionLiteral* result;
if (source->IsExternalTwoByteString()) {
ExternalTwoByteStringUtf16CharacterStream stream(
Handle<ExternalTwoByteString>::cast(source),
shared_info->start_position(),
shared_info->end_position());
- FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
- return result;
+ result = ParseLazy(&stream, &zone_scope);
} else {
GenericStringUtf16CharacterStream stream(source,
shared_info->start_position(),
shared_info->end_position());
- FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
- return result;
+ result = ParseLazy(&stream, &zone_scope);
}
+
+ if (FLAG_trace_parse && result != NULL) {
+ double ms = static_cast<double>(OS::Ticks() - start) / 1000;
+ SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
+ PrintF("[parsing function: %s - took %0.3f ms]\n", *name_chars, ms);
+ }
+ return result;
}
-FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
- Utf16CharacterStream* source,
+FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source,
ZoneScope* zone_scope) {
- Handle<SharedFunctionInfo> shared_info = info->shared_info();
+ Handle<SharedFunctionInfo> shared_info = info()->shared_info();
scanner_.Initialize(source);
ASSERT(top_scope_ == NULL);
ASSERT(target_stack_ == NULL);
@@ -700,7 +726,7 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
fni_->PushEnclosingName(name);
- mode_ = PARSE_EAGERLY;
+ ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
// Place holder for the result.
FunctionLiteral* result = NULL;
@@ -708,16 +734,16 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
{
// Parse the function literal.
Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
- info->SetGlobalScope(scope);
- if (!info->closure().is_null()) {
- scope = Scope::DeserializeScopeChain(info->closure()->context(), scope,
+ info()->SetGlobalScope(scope);
+ if (!info()->closure().is_null()) {
+ scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
zone());
}
FunctionState function_state(this, scope, isolate());
- ASSERT(scope->language_mode() != STRICT_MODE || !info->is_classic_mode());
+ ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode());
ASSERT(scope->language_mode() != EXTENDED_MODE ||
- info->is_extended_mode());
- ASSERT(info->language_mode() == shared_info->language_mode());
+ info()->is_extended_mode());
+ ASSERT(info()->language_mode() == shared_info->language_mode());
scope->SetLanguageMode(shared_info->language_mode());
FunctionLiteral::Type type = shared_info->is_expression()
? (shared_info->is_anonymous()
@@ -806,145 +832,10 @@ void Parser::ReportMessageAt(Scanner::Location source_location,
}
-// Base class containing common code for the different finder classes used by
-// the parser.
-class ParserFinder {
- protected:
- ParserFinder() {}
- static Assignment* AsAssignment(Statement* stat) {
- if (stat == NULL) return NULL;
- ExpressionStatement* exp_stat = stat->AsExpressionStatement();
- if (exp_stat == NULL) return NULL;
- return exp_stat->expression()->AsAssignment();
- }
-};
-
-
-// An InitializationBlockFinder finds and marks sequences of statements of the
-// form expr.a = ...; expr.b = ...; etc.
-class InitializationBlockFinder : public ParserFinder {
- public:
- // We find and mark the initialization blocks in top level
- // non-looping code only. This is because the optimization prevents
- // reuse of the map transitions, so it should be used only for code
- // that will only be run once.
- InitializationBlockFinder(Scope* top_scope, Target* target)
- : enabled_(top_scope->DeclarationScope()->is_global_scope() &&
- !IsLoopTarget(target)),
- first_in_block_(NULL),
- last_in_block_(NULL),
- block_size_(0) {}
-
- ~InitializationBlockFinder() {
- if (!enabled_) return;
- if (InBlock()) EndBlock();
- }
-
- void Update(Statement* stat) {
- if (!enabled_) return;
- Assignment* assignment = AsAssignment(stat);
- if (InBlock()) {
- if (BlockContinues(assignment)) {
- UpdateBlock(assignment);
- } else {
- EndBlock();
- }
- }
- if (!InBlock() && (assignment != NULL) &&
- (assignment->op() == Token::ASSIGN)) {
- StartBlock(assignment);
- }
- }
-
- private:
- // The minimum number of contiguous assignment that will
- // be treated as an initialization block. Benchmarks show that
- // the overhead exceeds the savings below this limit.
- static const int kMinInitializationBlock = 3;
-
- static bool IsLoopTarget(Target* target) {
- while (target != NULL) {
- if (target->node()->AsIterationStatement() != NULL) return true;
- target = target->previous();
- }
- return false;
- }
-
- // Returns true if the expressions appear to denote the same object.
- // In the context of initialization blocks, we only consider expressions
- // of the form 'expr.x' or expr["x"].
- static bool SameObject(Expression* e1, Expression* e2) {
- VariableProxy* v1 = e1->AsVariableProxy();
- VariableProxy* v2 = e2->AsVariableProxy();
- if (v1 != NULL && v2 != NULL) {
- return v1->name()->Equals(*v2->name());
- }
- Property* p1 = e1->AsProperty();
- Property* p2 = e2->AsProperty();
- if ((p1 == NULL) || (p2 == NULL)) return false;
- Literal* key1 = p1->key()->AsLiteral();
- Literal* key2 = p2->key()->AsLiteral();
- if ((key1 == NULL) || (key2 == NULL)) return false;
- if (!key1->handle()->IsString() || !key2->handle()->IsString()) {
- return false;
- }
- String* name1 = String::cast(*key1->handle());
- String* name2 = String::cast(*key2->handle());
- if (!name1->Equals(name2)) return false;
- return SameObject(p1->obj(), p2->obj());
- }
-
- // Returns true if the expressions appear to denote different properties
- // of the same object.
- static bool PropertyOfSameObject(Expression* e1, Expression* e2) {
- Property* p1 = e1->AsProperty();
- Property* p2 = e2->AsProperty();
- if ((p1 == NULL) || (p2 == NULL)) return false;
- return SameObject(p1->obj(), p2->obj());
- }
-
- bool BlockContinues(Assignment* assignment) {
- if ((assignment == NULL) || (first_in_block_ == NULL)) return false;
- if (assignment->op() != Token::ASSIGN) return false;
- return PropertyOfSameObject(first_in_block_->target(),
- assignment->target());
- }
-
- void StartBlock(Assignment* assignment) {
- first_in_block_ = assignment;
- last_in_block_ = assignment;
- block_size_ = 1;
- }
-
- void UpdateBlock(Assignment* assignment) {
- last_in_block_ = assignment;
- ++block_size_;
- }
-
- void EndBlock() {
- if (block_size_ >= kMinInitializationBlock) {
- first_in_block_->mark_block_start();
- last_in_block_->mark_block_end();
- }
- last_in_block_ = first_in_block_ = NULL;
- block_size_ = 0;
- }
-
- bool InBlock() { return first_in_block_ != NULL; }
-
- const bool enabled_;
- Assignment* first_in_block_;
- Assignment* last_in_block_;
- int block_size_;
-
- DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder);
-};
-
-
// A ThisNamedPropertyAssignmentFinder finds and marks statements of the form
// this.x = ...;, where x is a named property. It also determines whether a
// function contains only assignments of this type.
-class ThisNamedPropertyAssignmentFinder : public ParserFinder {
+class ThisNamedPropertyAssignmentFinder {
public:
ThisNamedPropertyAssignmentFinder(Isolate* isolate, Zone* zone)
: isolate_(isolate),
@@ -955,6 +846,13 @@ class ThisNamedPropertyAssignmentFinder : public ParserFinder {
zone_(zone) {
}
+ static Assignment* AsAssignment(Statement* stat) {
+ if (stat == NULL) return NULL;
+ ExpressionStatement* exp_stat = stat->AsExpressionStatement();
+ if (exp_stat == NULL) return NULL;
+ return exp_stat->expression()->AsAssignment();
+ }
+
void Update(Scope* scope, Statement* stat) {
// Bail out if function already has property assignment that are
// not simple this property assignments.
@@ -1109,6 +1007,7 @@ class ThisNamedPropertyAssignmentFinder : public ParserFinder {
void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
int end_token,
bool is_eval,
+ bool is_global,
bool* ok) {
// SourceElements ::
// (ModuleElement)* <end_token>
@@ -1120,7 +1019,6 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
TargetScope scope(&this->target_stack_);
ASSERT(processor != NULL);
- InitializationBlockFinder block_finder(top_scope_, target_stack_);
ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate(),
zone());
bool directive_prologue = true; // Parsing directive prologue.
@@ -1131,7 +1029,12 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
}
Scanner::Location token_loc = scanner().peek_location();
- Statement* stat = ParseModuleElement(NULL, CHECK_OK);
+ Statement* stat;
+ if (is_global && !is_eval) {
+ stat = ParseModuleElement(NULL, CHECK_OK);
+ } else {
+ stat = ParseBlockElement(NULL, CHECK_OK);
+ }
if (stat == NULL || stat->IsEmpty()) {
directive_prologue = false; // End of directive prologue.
continue;
@@ -1175,7 +1078,6 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
}
}
- block_finder.Update(stat);
// Find and mark all assignments to named properties in this (this.x =)
if (top_scope_->is_function_scope()) {
this_property_assignment_finder.Update(top_scope_, stat);
@@ -1246,12 +1148,10 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels,
}
-Block* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
+Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
// ModuleDeclaration:
// 'module' Identifier Module
- // Create new block with one expected declaration.
- Block* block = factory()->NewBlock(NULL, 1, true, zone());
Handle<String> name = ParseIdentifier(CHECK_OK);
#ifdef DEBUG
@@ -1275,10 +1175,11 @@ Block* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
}
#endif
- // TODO(rossberg): Add initialization statement to block.
-
if (names) names->Add(name, zone());
- return block;
+ if (module->body() == NULL)
+ return factory()->NewEmptyStatement();
+ else
+ return module->body();
}
@@ -1314,7 +1215,7 @@ Module* Parser::ParseModuleLiteral(bool* ok) {
// '{' ModuleElement '}'
// Construct block expecting 16 statements.
- Block* body = factory()->NewBlock(NULL, 16, false, zone());
+ Block* body = factory()->NewBlock(NULL, 16, false);
#ifdef DEBUG
if (FLAG_print_interface_details) PrintF("# Literal ");
#endif
@@ -1329,13 +1230,11 @@ Module* Parser::ParseModuleLiteral(bool* ok) {
TargetCollector collector(zone());
Target target(&this->target_stack_, &collector);
Target target_body(&this->target_stack_, body);
- InitializationBlockFinder block_finder(top_scope_, target_stack_);
while (peek() != Token::RBRACE) {
Statement* stat = ParseModuleElement(NULL, CHECK_OK);
if (stat && !stat->IsEmpty()) {
body->AddStatement(stat, zone());
- block_finder.Update(stat);
}
}
}
@@ -1344,16 +1243,23 @@ Module* Parser::ParseModuleLiteral(bool* ok) {
scope->set_end_position(scanner().location().end_pos);
body->set_scope(scope);
- // Instance objects have to be created ahead of time (before code generation
- // linking them) because of potentially cyclic references between them.
- // We create them here, to avoid another pass over the AST.
+ // Check that all exports are bound.
Interface* interface = scope->interface();
+ for (Interface::Iterator it = interface->iterator();
+ !it.done(); it.Advance()) {
+ if (scope->LocalLookup(it.name()) == NULL) {
+ Handle<String> name(it.name());
+ ReportMessage("module_export_undefined",
+ Vector<Handle<String> >(&name, 1));
+ *ok = false;
+ return NULL;
+ }
+ }
+
interface->MakeModule(ok);
- ASSERT(ok);
- interface->MakeSingleton(Isolate::Current()->factory()->NewJSModule(), ok);
- ASSERT(ok);
+ ASSERT(*ok);
interface->Freeze(ok);
- ASSERT(ok);
+ ASSERT(*ok);
return factory()->NewModuleLiteral(body, interface);
}
@@ -1402,8 +1308,8 @@ Module* Parser::ParseModuleVariable(bool* ok) {
PrintF("# Module variable %s ", name->ToAsciiArray());
#endif
VariableProxy* proxy = top_scope_->NewUnresolved(
- factory(), name, scanner().location().beg_pos,
- Interface::NewModule(zone()));
+ factory(), name, Interface::NewModule(zone()),
+ scanner().location().beg_pos);
return factory()->NewModuleVariable(proxy);
}
@@ -1424,10 +1330,12 @@ Module* Parser::ParseModuleUrl(bool* ok) {
Module* result = factory()->NewModuleUrl(symbol);
Interface* interface = result->interface();
- interface->MakeSingleton(Isolate::Current()->factory()->NewJSModule(), ok);
- ASSERT(ok);
interface->Freeze(ok);
- ASSERT(ok);
+ ASSERT(*ok);
+ // Create dummy scope to avoid errors as long as the feature isn't finished.
+ Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
+ interface->Unify(scope->interface(), zone(), ok);
+ ASSERT(*ok);
return result;
}
@@ -1468,7 +1376,7 @@ Block* Parser::ParseImportDeclaration(bool* ok) {
// Generate a separate declaration for each identifier.
// TODO(ES6): once we implement destructuring, make that one declaration.
- Block* block = factory()->NewBlock(NULL, 1, true, zone());
+ Block* block = factory()->NewBlock(NULL, 1, true);
for (int i = 0; i < names.length(); ++i) {
#ifdef DEBUG
if (FLAG_print_interface_details)
@@ -1491,7 +1399,6 @@ Block* Parser::ParseImportDeclaration(bool* ok) {
Declaration* declaration =
factory()->NewImportDeclaration(proxy, module, top_scope_);
Declare(declaration, true, CHECK_OK);
- // TODO(rossberg): Add initialization statement to block.
}
return block;
@@ -1683,7 +1590,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
// one must take great care not to treat it as a
// fall-through. It is much easier just to wrap the entire
// try-statement in a statement block and put the labels there
- Block* result = factory()->NewBlock(labels, 1, false, zone());
+ Block* result = factory()->NewBlock(labels, 1, false);
Target target(&this->target_stack_, result);
TryStatement* statement = ParseTryStatement(CHECK_OK);
if (statement) {
@@ -1732,7 +1639,7 @@ VariableProxy* Parser::NewUnresolved(
// Let/const variables in harmony mode are always added to the immediately
// enclosing scope.
return DeclarationScope(mode)->NewUnresolved(
- factory(), name, scanner().location().beg_pos, interface);
+ factory(), name, interface, scanner().location().beg_pos);
}
@@ -1743,7 +1650,7 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
Scope* declaration_scope = DeclarationScope(mode);
Variable* var = NULL;
- // If a function scope exists, then we can statically declare this
+ // If a suitable scope exists, then we can statically declare this
// variable and also set its mode. In any case, a Declaration node
// will be added to the scope so that the declaration can be added
// to the corresponding activation frame at runtime if necessary.
@@ -1751,56 +1658,58 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
// to the calling function context.
// Similarly, strict mode eval scope does not leak variable declarations to
// the caller's scope so we declare all locals, too.
- // Also for block scoped let/const bindings the variable can be
- // statically declared.
if (declaration_scope->is_function_scope() ||
declaration_scope->is_strict_or_extended_eval_scope() ||
declaration_scope->is_block_scope() ||
declaration_scope->is_module_scope() ||
- declaration->AsModuleDeclaration() != NULL) {
- // Declare the variable in the function scope.
- var = declaration_scope->LocalLookup(name);
+ declaration_scope->is_global_scope()) {
+ // Declare the variable in the declaration scope.
+ // For the global scope, we have to check for collisions with earlier
+ // (i.e., enclosing) global scopes, to maintain the illusion of a single
+ // global scope.
+ var = declaration_scope->is_global_scope()
+ ? declaration_scope->Lookup(name)
+ : declaration_scope->LocalLookup(name);
if (var == NULL) {
// Declare the name.
var = declaration_scope->DeclareLocal(
name, mode, declaration->initialization(), proxy->interface());
- } else {
+ } else if ((mode != VAR || var->mode() != VAR) &&
+ (!declaration_scope->is_global_scope() ||
+ IsLexicalVariableMode(mode) ||
+ IsLexicalVariableMode(var->mode()))) {
// The name was declared in this scope before; check for conflicting
// re-declarations. We have a conflict if either of the declarations is
- // not a var. There is similar code in runtime.cc in the Declare
+ // not a var (in the global scope, we also have to ignore legacy const for
+ // compatibility). There is similar code in runtime.cc in the Declare
// functions. The function CheckNonConflictingScope checks for conflicting
// var and let bindings from different scopes whereas this is a check for
// conflicting declarations within the same scope. This check also covers
+ // the special case
//
// function () { let x; { var x; } }
//
// because the var declaration is hoisted to the function scope where 'x'
// is already bound.
- if ((mode != VAR) || (var->mode() != VAR)) {
- // We only have vars, consts and lets in declarations.
- ASSERT(var->mode() == VAR ||
- var->mode() == CONST ||
- var->mode() == CONST_HARMONY ||
- var->mode() == LET);
- if (is_extended_mode()) {
- // In harmony mode we treat re-declarations as early errors. See
- // ES5 16 for a definition of early errors.
- SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
- const char* elms[2] = { "Variable", *c_string };
- Vector<const char*> args(elms, 2);
- ReportMessage("redeclaration", args);
- *ok = false;
- return;
- }
- const char* type = (var->mode() == VAR)
- ? "var" : var->is_const_mode() ? "const" : "let";
- Handle<String> type_string =
- isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
- Expression* expression =
- NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
- type_string, name);
- declaration_scope->SetIllegalRedeclaration(expression);
+ ASSERT(IsDeclaredVariableMode(var->mode()));
+ if (is_extended_mode()) {
+ // In harmony mode we treat re-declarations as early errors. See
+ // ES5 16 for a definition of early errors.
+ SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
+ const char* elms[2] = { "Variable", *c_string };
+ Vector<const char*> args(elms, 2);
+ ReportMessage("redeclaration", args);
+ *ok = false;
+ return;
}
+ const char* type =
+ (var->mode() == VAR) ? "var" : var->is_const_mode() ? "const" : "let";
+ Handle<String> type_string =
+ isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
+ Expression* expression =
+ NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
+ type_string, name);
+ declaration_scope->SetIllegalRedeclaration(expression);
}
}
@@ -1822,8 +1731,7 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
// Runtime::DeclareContextSlot() calls.
declaration_scope->AddDeclaration(declaration);
- if ((mode == CONST || mode == CONST_HARMONY) &&
- declaration_scope->is_global_scope()) {
+ if (mode == CONST && declaration_scope->is_global_scope()) {
// For global const variables we bind the proxy to a variable.
ASSERT(resolve); // should be set by all callers
Variable::Kind kind = Variable::NORMAL;
@@ -1948,7 +1856,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
// TODO(1240846): It's weird that native function declarations are
// introduced dynamically when we meet their declarations, whereas
// other functions are set up when entering the surrounding scope.
- VariableProxy* proxy = NewUnresolved(name, VAR);
+ VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, VAR, top_scope_);
Declare(declaration, true, CHECK_OK);
@@ -1974,10 +1882,13 @@ Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
FunctionLiteral::DECLARATION,
CHECK_OK);
// Even if we're not at the top-level of the global or a function
- // scope, we treat is as such and introduce the function with it's
+ // scope, we treat it as such and introduce the function with its
// initial value upon entering the corresponding scope.
- VariableMode mode = is_extended_mode() ? LET : VAR;
- VariableProxy* proxy = NewUnresolved(name, mode);
+ // In extended mode, a function behaves as a lexical binding, except in the
+ // global scope.
+ VariableMode mode =
+ is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR;
+ VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
Declaration* declaration =
factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_);
Declare(declaration, true, CHECK_OK);
@@ -1996,15 +1907,13 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
// (ECMA-262, 3rd, 12.2)
//
// Construct block expecting 16 statements.
- Block* result = factory()->NewBlock(labels, 16, false, zone());
+ Block* result = factory()->NewBlock(labels, 16, false);
Target target(&this->target_stack_, result);
Expect(Token::LBRACE, CHECK_OK);
- InitializationBlockFinder block_finder(top_scope_, target_stack_);
while (peek() != Token::RBRACE) {
Statement* stat = ParseStatement(NULL, CHECK_OK);
if (stat && !stat->IsEmpty()) {
result->AddStatement(stat, zone());
- block_finder.Update(stat);
}
}
Expect(Token::RBRACE, CHECK_OK);
@@ -2019,7 +1928,7 @@ Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
// '{' BlockElement* '}'
// Construct block expecting 16 statements.
- Block* body = factory()->NewBlock(labels, 16, false, zone());
+ Block* body = factory()->NewBlock(labels, 16, false);
Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE);
// Parse the statements and collect escaping labels.
@@ -2029,13 +1938,11 @@ Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
TargetCollector collector(zone());
Target target(&this->target_stack_, &collector);
Target target_body(&this->target_stack_, body);
- InitializationBlockFinder block_finder(top_scope_, target_stack_);
while (peek() != Token::RBRACE) {
Statement* stat = ParseBlockElement(NULL, CHECK_OK);
if (stat && !stat->IsEmpty()) {
body->AddStatement(stat, zone());
- block_finder.Update(stat);
}
}
}
@@ -2176,7 +2083,7 @@ Block* Parser::ParseVariableDeclarations(
// is inside an initializer block, it is ignored.
//
// Create new block with one expected declaration.
- Block* block = factory()->NewBlock(NULL, 1, true, zone());
+ Block* block = factory()->NewBlock(NULL, 1, true);
int nvars = 0; // the number of variables declared
Handle<String> name;
do {
@@ -2209,7 +2116,9 @@ Block* Parser::ParseVariableDeclarations(
// For let/const declarations in harmony mode, we can also immediately
// pre-resolve the proxy because it resides in the same scope as the
// declaration.
- VariableProxy* proxy = NewUnresolved(name, mode);
+ Interface* interface =
+ is_const ? Interface::NewConst() : Interface::NewValue();
+ VariableProxy* proxy = NewUnresolved(name, mode, interface);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, mode, top_scope_);
Declare(declaration, mode != VAR, CHECK_OK);
@@ -2297,7 +2206,8 @@ Block* Parser::ParseVariableDeclarations(
// declaration statement has been executed. This is important in
// browsers where the global object (window) has lots of
// properties defined in prototype objects.
- if (initialization_scope->is_global_scope()) {
+ if (initialization_scope->is_global_scope() &&
+ !IsLexicalVariableMode(mode)) {
// Compute the arguments for the runtime call.
ZoneList<Expression*>* arguments =
new(zone()) ZoneList<Expression*>(3, zone());
@@ -2370,7 +2280,7 @@ Block* Parser::ParseVariableDeclarations(
// if they are inside a 'with' statement - they may change a 'with' object
// property).
VariableProxy* proxy =
- initialization_scope->NewUnresolved(factory(), name);
+ initialization_scope->NewUnresolved(factory(), name, interface);
Assignment* assignment =
factory()->NewAssignment(init_op, proxy, value, position);
block->AddStatement(factory()->NewExpressionStatement(assignment),
@@ -2787,7 +2697,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
TryCatchStatement* statement = factory()->NewTryCatchStatement(
index, try_block, catch_scope, catch_variable, catch_block);
statement->set_escaping_targets(try_collector.targets());
- try_block = factory()->NewBlock(NULL, 1, false, zone());
+ try_block = factory()->NewBlock(NULL, 1, false);
try_block->AddStatement(statement, zone());
catch_block = NULL; // Clear to indicate it's been handled.
}
@@ -2878,12 +2788,14 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
for_scope->set_start_position(scanner().location().beg_pos);
if (peek() != Token::SEMICOLON) {
if (peek() == Token::VAR || peek() == Token::CONST) {
+ bool is_const = peek() == Token::CONST;
Handle<String> name;
Block* variable_statement =
ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK);
if (peek() == Token::IN && !name.is_null()) {
- VariableProxy* each = top_scope_->NewUnresolved(factory(), name);
+ Interface* interface =
+ is_const ? Interface::NewConst() : Interface::NewValue();
ForInStatement* loop = factory()->NewForInStatement(labels);
Target target(&this->target_stack_, loop);
@@ -2891,9 +2803,11 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
Expression* enumerable = ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
+ VariableProxy* each =
+ top_scope_->NewUnresolved(factory(), name, interface);
Statement* body = ParseStatement(NULL, CHECK_OK);
loop->Initialize(each, enumerable, body);
- Block* result = factory()->NewBlock(NULL, 2, false, zone());
+ Block* result = factory()->NewBlock(NULL, 2, false);
result->AddStatement(variable_statement, zone());
result->AddStatement(loop, zone());
top_scope_ = saved_scope;
@@ -2928,18 +2842,26 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
// TODO(keuchel): Move the temporary variable to the block scope, after
// implementing stack allocated block scoped variables.
- Variable* temp = top_scope_->DeclarationScope()->NewTemporary(name);
+ Factory* heap_factory = isolate()->factory();
+ Handle<String> tempstr =
+ heap_factory->NewConsString(heap_factory->dot_for_symbol(), name);
+ Handle<String> tempname = heap_factory->LookupSymbol(tempstr);
+ Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname);
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
- VariableProxy* each = top_scope_->NewUnresolved(factory(), name);
ForInStatement* loop = factory()->NewForInStatement(labels);
Target target(&this->target_stack_, loop);
+ // The expression does not see the loop variable.
Expect(Token::IN, CHECK_OK);
+ top_scope_ = saved_scope;
Expression* enumerable = ParseExpression(true, CHECK_OK);
+ top_scope_ = for_scope;
Expect(Token::RPAREN, CHECK_OK);
+ VariableProxy* each =
+ top_scope_->NewUnresolved(factory(), name, Interface::NewValue());
Statement* body = ParseStatement(NULL, CHECK_OK);
- Block* body_block = factory()->NewBlock(NULL, 3, false, zone());
+ Block* body_block = factory()->NewBlock(NULL, 3, false);
Assignment* assignment = factory()->NewAssignment(
Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
Statement* assignment_statement =
@@ -3028,7 +2950,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
// for (; c; n) b
// }
ASSERT(init != NULL);
- Block* result = factory()->NewBlock(NULL, 2, false, zone());
+ Block* result = factory()->NewBlock(NULL, 2, false);
result->AddStatement(init, zone());
result->AddStatement(loop, zone());
result->set_scope(for_scope);
@@ -3412,6 +3334,12 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
// should not point to the closing brace otherwise it will intersect
// with positions recorded for function literal and confuse debugger.
pos = scanner().peek_location().beg_pos;
+ // Also the trailing parenthesis are a hint that the function will
+ // be called immediately. If we happen to have parsed a preceding
+ // function literal eagerly, we can also compile it eagerly.
+ if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
+ result->AsFunctionLiteral()->set_parenthesized();
+ }
}
ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
@@ -3665,7 +3593,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
#endif
Interface* interface = Interface::NewUnknown(zone());
result = top_scope_->NewUnresolved(
- factory(), name, scanner().location().beg_pos, interface);
+ factory(), name, interface, scanner().location().beg_pos);
break;
}
@@ -4356,6 +4284,7 @@ class SingletonLogger : public ParserRecorder {
int end,
const char* message,
const char* argument_opt) {
+ if (has_error_) return;
has_error_ = true;
start_ = start;
end_ = end;
@@ -4450,6 +4379,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
Handle<FixedArray> this_property_assignments;
FunctionLiteral::ParameterFlag duplicate_parameters =
FunctionLiteral::kNoDuplicateParameters;
+ FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
+ ? FunctionLiteral::kIsParenthesized
+ : FunctionLiteral::kNotParenthesized;
AstProperties ast_properties;
// Parse function body.
{ FunctionState function_state(this, scope, isolate());
@@ -4510,7 +4442,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST;
fvar = new(zone()) Variable(top_scope_,
function_name, fvar_mode, true /* is valid LHS */,
- Variable::NORMAL, kCreatedInitialized);
+ Variable::NORMAL, kCreatedInitialized, Interface::NewConst());
VariableProxy* proxy = factory()->NewVariableProxy(fvar);
VariableDeclaration* fvar_declaration =
factory()->NewVariableDeclaration(proxy, fvar_mode, top_scope_);
@@ -4521,7 +4453,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
// The heuristics are:
// - It must not have been prohibited by the caller to Parse (some callers
// need a full AST).
- // - The outer scope must be trivial (only global variables in scope).
+ // - The outer scope must allow lazy compilation of inner functions.
// - The function mustn't be a function expression with an open parenthesis
// before; we consider that a hint that the function will be called
// immediately, and it would be a waste of time to make it lazily
@@ -4529,8 +4461,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
// These are all things we can know at this point, without looking at the
// function itself.
bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
- top_scope_->outer_scope()->is_global_scope() &&
- top_scope_->HasTrivialOuterContext() &&
+ top_scope_->AllowsLazyCompilation() &&
!parenthesized_function_);
parenthesized_function_ = false; // The bit was set for this function only.
@@ -4599,19 +4530,20 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
}
if (!is_lazily_compiled) {
+ ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
body = new(zone()) ZoneList<Statement*>(8, zone());
if (fvar != NULL) {
- VariableProxy* fproxy =
- top_scope_->NewUnresolved(factory(), function_name);
+ VariableProxy* fproxy = top_scope_->NewUnresolved(
+ factory(), function_name, Interface::NewConst());
fproxy->BindTo(fvar);
body->Add(factory()->NewExpressionStatement(
factory()->NewAssignment(fvar_init_op,
fproxy,
factory()->NewThisFunction(),
RelocInfo::kNoPosition)),
- zone());
+ zone());
}
- ParseSourceElements(body, Token::RBRACE, false, CHECK_OK);
+ ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
@@ -4689,7 +4621,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
num_parameters,
duplicate_parameters,
type,
- FunctionLiteral::kIsFunction);
+ FunctionLiteral::kIsFunction,
+ parenthesized);
function_literal->set_function_token_position(function_token_position);
function_literal->set_ast_properties(&ast_properties);
@@ -4761,6 +4694,13 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
return NULL;
}
+ // Check that the function is defined if it's an inline runtime call.
+ if (function == NULL && name->Get(0) == '_') {
+ ReportMessage("not_defined", Vector<Handle<String> >(&name, 1));
+ *ok = false;
+ return NULL;
+ }
+
// We have a valid intrinsics call or a call to a builtin.
return factory()->NewCallRuntime(name, function, args);
}
@@ -5069,8 +5009,10 @@ Expression* Parser::NewThrowError(Handle<String> constructor,
RegExpParser::RegExpParser(FlatStringReader* in,
Handle<String>* error,
- bool multiline)
+ bool multiline,
+ Zone* zone)
: isolate_(Isolate::Current()),
+ zone_(zone),
error_(error),
captures_(NULL),
in_(in),
@@ -5101,7 +5043,7 @@ void RegExpParser::Advance() {
StackLimitCheck check(isolate());
if (check.HasOverflowed()) {
ReportError(CStrVector(Isolate::kStackOverflowMessage));
- } else if (isolate()->zone()->excess_allocation()) {
+ } else if (zone()->excess_allocation()) {
ReportError(CStrVector("Regular expression too large"));
} else {
current_ = in()->Get(next_pos_);
@@ -5964,31 +5906,6 @@ static ScriptDataImpl* DoPreParse(Utf16CharacterStream* source,
}
-// Preparse, but only collect data that is immediately useful,
-// even if the preparser data is only used once.
-ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source,
- v8::Extension* extension,
- int flags) {
- bool allow_lazy = FLAG_lazy && (extension == NULL);
- if (!allow_lazy) {
- // Partial preparsing is only about lazily compiled functions.
- // If we don't allow lazy compilation, the log data will be empty.
- return NULL;
- }
- flags |= kAllowLazy;
- PartialParserRecorder recorder;
- int source_length = source->length();
- if (source->IsExternalTwoByteString()) {
- ExternalTwoByteStringUtf16CharacterStream stream(
- Handle<ExternalTwoByteString>::cast(source), 0, source_length);
- return DoPreParse(&stream, flags, &recorder);
- } else {
- GenericStringUtf16CharacterStream stream(source, 0, source_length);
- return DoPreParse(&stream, flags, &recorder);
- }
-}
-
-
ScriptDataImpl* ParserApi::PreParse(Utf16CharacterStream* source,
v8::Extension* extension,
int flags) {
@@ -6003,9 +5920,10 @@ ScriptDataImpl* ParserApi::PreParse(Utf16CharacterStream* source,
bool RegExpParser::ParseRegExp(FlatStringReader* input,
bool multiline,
- RegExpCompileData* result) {
+ RegExpCompileData* result,
+ Zone* zone) {
ASSERT(result != NULL);
- RegExpParser parser(input, &result->error, multiline);
+ RegExpParser parser(input, &result->error, multiline, zone);
RegExpTree* tree = parser.ParsePattern();
if (parser.failed()) {
ASSERT(tree == NULL);
@@ -6026,7 +5944,6 @@ bool RegExpParser::ParseRegExp(FlatStringReader* input,
bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) {
ASSERT(info->function() == NULL);
FunctionLiteral* result = NULL;
- Handle<Script> script = info->script();
ASSERT((parsing_flags & kLanguageModeMask) == CLASSIC_MODE);
if (!info->is_native() && FLAG_harmony_scoping) {
// Harmony scoping is requested.
@@ -6041,16 +5958,15 @@ bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) {
}
if (info->is_lazy()) {
ASSERT(!info->is_eval());
- Parser parser(script, parsing_flags, NULL, NULL, info->isolate()->zone());
+ Parser parser(info, parsing_flags, NULL, NULL);
if (info->shared_info()->is_function()) {
- result = parser.ParseLazy(info);
+ result = parser.ParseLazy();
} else {
- result = parser.ParseProgram(info);
+ result = parser.ParseProgram();
}
} else {
ScriptDataImpl* pre_data = info->pre_parse_data();
- Parser parser(script, parsing_flags, info->extension(), pre_data,
- info->isolate()->zone());
+ Parser parser(info, parsing_flags, info->extension(), pre_data);
if (pre_data != NULL && pre_data->has_error()) {
Scanner::Location loc = pre_data->MessageLocation();
const char* message = pre_data->BuildMessage();
@@ -6063,7 +5979,7 @@ bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) {
DeleteArray(args.start());
ASSERT(info->isolate()->has_pending_exception());
} else {
- result = parser.ParseProgram(info);
+ result = parser.ParseProgram();
}
}
info->SetFunction(result);
diff --git a/deps/v8/src/parser.h b/deps/v8/src/parser.h
index 773d59a5e..93fd1b8aa 100644
--- a/deps/v8/src/parser.h
+++ b/deps/v8/src/parser.h
@@ -175,12 +175,6 @@ class ParserApi {
static ScriptDataImpl* PreParse(Utf16CharacterStream* source,
v8::Extension* extension,
int flags);
-
- // Preparser that only does preprocessing that makes sense if only used
- // immediately after.
- static ScriptDataImpl* PartialPreParse(Handle<String> source,
- v8::Extension* extension,
- int flags);
};
// ----------------------------------------------------------------------------
@@ -306,11 +300,13 @@ class RegExpParser {
public:
RegExpParser(FlatStringReader* in,
Handle<String>* error,
- bool multiline_mode);
+ bool multiline_mode,
+ Zone* zone);
static bool ParseRegExp(FlatStringReader* input,
bool multiline,
- RegExpCompileData* result);
+ RegExpCompileData* result,
+ Zone* zone);
RegExpTree* ParsePattern();
RegExpTree* ParseDisjunction();
@@ -398,7 +394,7 @@ class RegExpParser {
};
Isolate* isolate() { return isolate_; }
- Zone* zone() const { return isolate_->zone(); }
+ Zone* zone() const { return zone_; }
uc32 current() { return current_; }
bool has_more() { return has_more_; }
@@ -408,6 +404,7 @@ class RegExpParser {
void ScanForCaptures();
Isolate* isolate_;
+ Zone* zone_;
Handle<String>* error_;
ZoneList<RegExpCapture*>* captures_;
FlatStringReader* in_;
@@ -431,19 +428,18 @@ class SingletonLogger;
class Parser {
public:
- Parser(Handle<Script> script,
+ Parser(CompilationInfo* info,
int parsing_flags, // Combination of ParsingFlags
v8::Extension* extension,
- ScriptDataImpl* pre_data,
- Zone* zone);
+ ScriptDataImpl* pre_data);
virtual ~Parser() {
delete reusable_preparser_;
reusable_preparser_ = NULL;
}
// Returns NULL if parsing failed.
- FunctionLiteral* ParseProgram(CompilationInfo* info);
- FunctionLiteral* ParseLazy(CompilationInfo* info);
+ FunctionLiteral* ParseProgram();
+ FunctionLiteral* ParseLazy();
void ReportMessageAt(Scanner::Location loc,
const char* message,
@@ -458,7 +454,7 @@ class Parser {
// construct a hashable id, so if more than 2^17 are allowed, this
// should be checked.
static const int kMaxNumFunctionParameters = 32766;
- static const int kMaxNumFunctionLocals = 32767;
+ static const int kMaxNumFunctionLocals = 131071; // 2^17-1
enum Mode {
PARSE_LAZILY,
@@ -540,15 +536,28 @@ class Parser {
AstNodeFactory<AstConstructionVisitor> factory_;
};
+ class ParsingModeScope BASE_EMBEDDED {
+ public:
+ ParsingModeScope(Parser* parser, Mode mode)
+ : parser_(parser),
+ old_mode_(parser->mode()) {
+ parser_->mode_ = mode;
+ }
+ ~ParsingModeScope() {
+ parser_->mode_ = old_mode_;
+ }
+ private:
+ Parser* parser_;
+ Mode old_mode_;
+ };
-
- FunctionLiteral* ParseLazy(CompilationInfo* info,
- Utf16CharacterStream* source,
+ FunctionLiteral* ParseLazy(Utf16CharacterStream* source,
ZoneScope* zone_scope);
Isolate* isolate() { return isolate_; }
Zone* zone() const { return zone_; }
+ CompilationInfo* info() const { return info_; }
// Called by ParseProgram after setting up the scanner.
FunctionLiteral* DoParseProgram(CompilationInfo* info,
@@ -570,7 +579,7 @@ class Parser {
return top_scope_->is_extended_mode();
}
Scope* DeclarationScope(VariableMode mode) {
- return (mode == LET || mode == CONST_HARMONY)
+ return IsLexicalVariableMode(mode)
? top_scope_ : top_scope_->DeclarationScope();
}
@@ -581,10 +590,10 @@ class Parser {
// which is set to false if parsing failed; it is unchanged otherwise.
// By making the 'exception handling' explicit, we are forced to check
// for failure at the call sites.
- void* ParseSourceElements(ZoneList<Statement*>* processor,
- int end_token, bool is_eval, bool* ok);
+ void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
+ bool is_eval, bool is_global, bool* ok);
Statement* ParseModuleElement(ZoneStringList* labels, bool* ok);
- Block* ParseModuleDeclaration(ZoneStringList* names, bool* ok);
+ Statement* ParseModuleDeclaration(ZoneStringList* names, bool* ok);
Module* ParseModule(bool* ok);
Module* ParseModuleLiteral(bool* ok);
Module* ParseModulePath(bool* ok);
@@ -769,7 +778,7 @@ class Parser {
// Parser support
VariableProxy* NewUnresolved(Handle<String> name,
VariableMode mode,
- Interface* interface = Interface::NewValue());
+ Interface* interface);
void Declare(Declaration* declaration, bool resolve, bool* ok);
bool TargetStackContainsLabel(Handle<String> label);
@@ -837,6 +846,7 @@ class Parser {
bool parenthesized_function_;
Zone* zone_;
+ CompilationInfo* info_;
friend class BlockState;
friend class FunctionState;
};
diff --git a/deps/v8/src/platform-linux.cc b/deps/v8/src/platform-linux.cc
index ed9eb7908..beb2ccee2 100644
--- a/deps/v8/src/platform-linux.cc
+++ b/deps/v8/src/platform-linux.cc
@@ -53,6 +53,13 @@
#include <errno.h>
#include <stdarg.h>
+// GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'.
+// Old versions of the C library <signal.h> didn't define the type.
+#if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T) && \
+ defined(__arm__) && !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT)
+#include <asm/sigcontext.h>
+#endif
+
#undef MAP_TYPE
#include "v8.h"
@@ -141,6 +148,9 @@ bool OS::ArmCpuHasFeature(CpuFeature feature) {
case ARMv7:
search_string = "ARMv7";
break;
+ case SUDIV:
+ search_string = "idiva";
+ break;
default:
UNREACHABLE();
}
@@ -164,48 +174,61 @@ bool OS::ArmCpuHasFeature(CpuFeature feature) {
}
-// Simple helper function to detect whether the C code is compiled with
-// option -mfloat-abi=hard. The register d0 is loaded with 1.0 and the register
-// pair r0, r1 is loaded with 0.0. If -mfloat-abi=hard is pased to GCC then
-// calling this will return 1.0 and otherwise 0.0.
-static void ArmUsingHardFloatHelper() {
- asm("mov r0, #0":::"r0");
-#if defined(__VFP_FP__) && !defined(__SOFTFP__)
- // Load 0x3ff00000 into r1 using instructions available in both ARM
- // and Thumb mode.
- asm("mov r1, #3":::"r1");
- asm("mov r2, #255":::"r2");
- asm("lsl r1, r1, #8":::"r1");
- asm("orr r1, r1, r2":::"r1");
- asm("lsl r1, r1, #20":::"r1");
- // For vmov d0, r0, r1 use ARM mode.
-#ifdef __thumb__
- asm volatile(
- "@ Enter ARM Mode \n\t"
- " adr r3, 1f \n\t"
- " bx r3 \n\t"
- " .ALIGN 4 \n\t"
- " .ARM \n"
- "1: vmov d0, r0, r1 \n\t"
- "@ Enter THUMB Mode\n\t"
- " adr r3, 2f+1 \n\t"
- " bx r3 \n\t"
- " .THUMB \n"
- "2: \n\t":::"r3");
-#else
- asm("vmov d0, r0, r1");
-#endif // __thumb__
-#endif // defined(__VFP_FP__) && !defined(__SOFTFP__)
- asm("mov r1, #0":::"r1");
+CpuImplementer OS::GetCpuImplementer() {
+ static bool use_cached_value = false;
+ static CpuImplementer cached_value = UNKNOWN_IMPLEMENTER;
+ if (use_cached_value) {
+ return cached_value;
+ }
+ if (CPUInfoContainsString("CPU implementer\t: 0x41")) {
+ cached_value = ARM_IMPLEMENTER;
+ } else if (CPUInfoContainsString("CPU implementer\t: 0x51")) {
+ cached_value = QUALCOMM_IMPLEMENTER;
+ } else {
+ cached_value = UNKNOWN_IMPLEMENTER;
+ }
+ use_cached_value = true;
+ return cached_value;
}
bool OS::ArmUsingHardFloat() {
- // Cast helper function from returning void to returning double.
- typedef double (*F)();
- F f = FUNCTION_CAST<F>(FUNCTION_ADDR(ArmUsingHardFloatHelper));
- return f() == 1.0;
+ // 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.
+
+#define GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+#if GCC_VERSION >= 40600
+#if defined(__ARM_PCS_VFP)
+ return true;
+#else
+ return false;
+#endif
+
+#elif GCC_VERSION < 40500
+ return false;
+
+#else
+#if defined(__ARM_PCS_VFP)
+ return true;
+#elif defined(__ARM_PCS) || defined(__SOFTFP) || !defined(__VFP_FP__)
+ return false;
+#else
+#error "Your version of GCC does not report the FP ABI compiled for." \
+ "Please report it on this issue" \
+ "http://code.google.com/p/v8/issues/detail?id=2140"
+
+#endif
+#endif
+#undef GCC_VERSION
}
+
#endif // def __arm__
@@ -510,9 +533,6 @@ void OS::LogSharedLibraryAddresses() {
}
-static const char kGCFakeMmap[] = "/tmp/__v8_gc__";
-
-
void OS::SignalCodeMovingGC() {
// Support for ll_prof.py.
//
@@ -523,7 +543,7 @@ void OS::SignalCodeMovingGC() {
// by the kernel and allows us to synchronize V8 code log and the
// kernel log.
int size = sysconf(_SC_PAGESIZE);
- FILE* f = fopen(kGCFakeMmap, "w+");
+ FILE* f = fopen(FLAG_gc_fake_mmap, "w+");
void* addr = mmap(OS::GetRandomMmapAddr(),
size,
PROT_READ | PROT_EXEC,
@@ -912,32 +932,30 @@ Semaphore* OS::CreateSemaphore(int count) {
}
-#if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__))
-// Android runs a fairly new Linux kernel, so signal info is there,
-// but the C library doesn't have the structs defined.
+#if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T)
+
+// Not all versions of Android's C library provide ucontext_t.
+// Detect this and provide custom but compatible definitions. Note that these
+// follow the GLibc naming convention to access register values from
+// mcontext_t.
+//
+// See http://code.google.com/p/android/issues/detail?id=34784
+
+#if defined(__arm__)
-struct sigcontext {
- uint32_t trap_no;
- uint32_t error_code;
- uint32_t oldmask;
- uint32_t gregs[16];
- uint32_t arm_cpsr;
- uint32_t fault_address;
-};
-typedef uint32_t __sigset_t;
typedef struct sigcontext mcontext_t;
+
typedef struct ucontext {
uint32_t uc_flags;
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- __sigset_t uc_sigmask;
+ // Other fields are not used by V8, don't define them here.
} ucontext_t;
-enum ArmRegisters {R15 = 15, R13 = 13, R11 = 11};
-#elif !defined(__GLIBC__) && defined(__mips__)
+#elif defined(__mips__)
// MIPS version of sigcontext, for Android bionic.
-struct sigcontext {
+typedef struct {
uint32_t regmask;
uint32_t status;
uint64_t pc;
@@ -956,44 +974,44 @@ struct sigcontext {
uint32_t lo2;
uint32_t hi3;
uint32_t lo3;
-};
-typedef uint32_t __sigset_t;
-typedef struct sigcontext mcontext_t;
+} mcontext_t;
+
typedef struct ucontext {
uint32_t uc_flags;
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- __sigset_t uc_sigmask;
+ // Other fields are not used by V8, don't define them here.
} ucontext_t;
-#elif !defined(__GLIBC__) && defined(__i386__)
+#elif defined(__i386__)
// x86 version for Android.
-struct sigcontext {
+typedef struct {
uint32_t gregs[19];
void* fpregs;
uint32_t oldmask;
uint32_t cr2;
-};
+} mcontext_t;
-typedef uint32_t __sigset_t;
-typedef struct sigcontext mcontext_t;
+typedef uint32_t kernel_sigset_t[2]; // x86 kernel uses 64-bit signal masks
typedef struct ucontext {
uint32_t uc_flags;
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- __sigset_t uc_sigmask;
+ // Other fields are not used by V8, don't define them here.
} ucontext_t;
enum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 };
#endif
+#endif // __ANDROID__ && !defined(__BIONIC_HAVE_UCONTEXT_T)
static int GetThreadID() {
- // Glibc doesn't provide a wrapper for gettid(2).
-#if defined(ANDROID)
- return syscall(__NR_gettid);
+#if defined(__ANDROID__)
+ // Android's C library provides gettid(2).
+ return gettid();
#else
+ // Glibc doesn't provide a wrapper for gettid(2).
return syscall(SYS_gettid);
#endif
}
@@ -1032,8 +1050,10 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
#elif V8_HOST_ARCH_ARM
-// An undefined macro evaluates to 0, so this applies to Android's Bionic also.
-#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
+#if defined(__GLIBC__) && !defined(__UCLIBC__) && \
+ (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
+ // Old GLibc ARM versions used a gregs[] array to access the register
+ // values from mcontext_t.
sample->pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
sample->sp = reinterpret_cast<Address>(mcontext.gregs[R13]);
sample->fp = reinterpret_cast<Address>(mcontext.gregs[R11]);
@@ -1041,7 +1061,8 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
sample->pc = reinterpret_cast<Address>(mcontext.arm_pc);
sample->sp = reinterpret_cast<Address>(mcontext.arm_sp);
sample->fp = reinterpret_cast<Address>(mcontext.arm_fp);
-#endif // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
+#endif // defined(__GLIBC__) && !defined(__UCLIBC__) &&
+ // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
#elif V8_HOST_ARCH_MIPS
sample->pc = reinterpret_cast<Address>(mcontext.pc);
sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]);
diff --git a/deps/v8/src/platform-nullos.cc b/deps/v8/src/platform-nullos.cc
index 679ef8e89..7aaa7b204 100644
--- a/deps/v8/src/platform-nullos.cc
+++ b/deps/v8/src/platform-nullos.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -215,6 +215,11 @@ double OS::nan_value() {
}
+CpuImplementer OS::GetCpuImplementer() {
+ UNIMPLEMENTED();
+}
+
+
bool OS::ArmCpuHasFeature(CpuFeature feature) {
UNIMPLEMENTED();
}
diff --git a/deps/v8/src/platform-openbsd.cc b/deps/v8/src/platform-openbsd.cc
index ba33a8444..408d4dc0f 100644
--- a/deps/v8/src/platform-openbsd.cc
+++ b/deps/v8/src/platform-openbsd.cc
@@ -323,9 +323,6 @@ void OS::LogSharedLibraryAddresses() {
}
-static const char kGCFakeMmap[] = "/tmp/__v8_gc__";
-
-
void OS::SignalCodeMovingGC() {
// Support for ll_prof.py.
//
@@ -336,7 +333,7 @@ void OS::SignalCodeMovingGC() {
// by the kernel and allows us to synchronize V8 code log and the
// kernel log.
int size = sysconf(_SC_PAGESIZE);
- FILE* f = fopen(kGCFakeMmap, "w+");
+ FILE* f = fopen(FLAG_gc_fake_mmap, "w+");
void* addr = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_PRIVATE,
fileno(f), 0);
ASSERT(addr != MAP_FAILED);
diff --git a/deps/v8/src/platform-posix.cc b/deps/v8/src/platform-posix.cc
index 7ac114b45..2b8001516 100644
--- a/deps/v8/src/platform-posix.cc
+++ b/deps/v8/src/platform-posix.cc
@@ -162,6 +162,11 @@ double OS::nan_value() {
}
+int OS::GetCurrentProcessId() {
+ return static_cast<int>(getpid());
+}
+
+
// ----------------------------------------------------------------------------
// POSIX date/time support.
//
diff --git a/deps/v8/src/platform-solaris.cc b/deps/v8/src/platform-solaris.cc
index 07718fe50..4248ea214 100644
--- a/deps/v8/src/platform-solaris.cc
+++ b/deps/v8/src/platform-solaris.cc
@@ -125,8 +125,12 @@ const char* OS::LocalTimezone(double time) {
double OS::LocalTimeOffset() {
- tzset();
- return -static_cast<double>(timezone * msPerSecond);
+ // On Solaris, struct tm does not contain a tm_gmtoff field.
+ time_t utc = time(NULL);
+ ASSERT(utc != -1);
+ struct tm* loc = localtime(&utc);
+ ASSERT(loc != NULL);
+ return static_cast<double>((mktime(loc) - utc) * msPerSecond);
}
diff --git a/deps/v8/src/platform-win32.cc b/deps/v8/src/platform-win32.cc
index 2473949de..49463be8e 100644
--- a/deps/v8/src/platform-win32.cc
+++ b/deps/v8/src/platform-win32.cc
@@ -627,6 +627,11 @@ int OS::GetLastError() {
}
+int OS::GetCurrentProcessId() {
+ return static_cast<int>(::GetCurrentProcessId());
+}
+
+
// ----------------------------------------------------------------------------
// Win32 console output.
//
diff --git a/deps/v8/src/platform.h b/deps/v8/src/platform.h
index a2ddf7a62..de896acad 100644
--- a/deps/v8/src/platform.h
+++ b/deps/v8/src/platform.h
@@ -71,6 +71,24 @@ int signbit(double x);
int strncasecmp(const char* s1, const char* s2, int n);
+inline int lrint(double flt) {
+ int intgr;
+#if defined(V8_TARGET_ARCH_IA32)
+ __asm {
+ fld flt
+ fistp intgr
+ };
+#else
+ intgr = static_cast<int>(flt + 0.5);
+ if ((intgr & 1) != 0 && intgr - flt == 0.5) {
+ // If the number is halfway between two integers, round to the even one.
+ intgr--;
+ }
+#endif
+ return intgr;
+}
+
+
#endif // _MSC_VER
// Random is missing on both Visual Studio and MinGW.
@@ -89,7 +107,11 @@ namespace internal {
// Use AtomicWord for a machine-sized pointer. It is assumed that
// reads and writes of naturally aligned values of this type are atomic.
+#if defined(__OpenBSD__) && defined(__i386__)
+typedef Atomic32 AtomicWord;
+#else
typedef intptr_t AtomicWord;
+#endif
class Semaphore;
class Mutex;
@@ -286,6 +308,9 @@ class OS {
// Returns the double constant NAN
static double nan_value();
+ // Support runtime detection of Cpu implementer
+ static CpuImplementer GetCpuImplementer();
+
// Support runtime detection of VFP3 on ARM CPUs.
static bool ArmCpuHasFeature(CpuFeature feature);
@@ -317,6 +342,8 @@ class OS {
static const int kMinComplexMemCopy = 256;
#endif // V8_TARGET_ARCH_IA32
+ static int GetCurrentProcessId();
+
private:
static const int msPerSecond = 1000;
diff --git a/deps/v8/src/preparser.cc b/deps/v8/src/preparser.cc
index 0c17eecd6..21da4f80d 100644
--- a/deps/v8/src/preparser.cc
+++ b/deps/v8/src/preparser.cc
@@ -602,14 +602,17 @@ PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
if (token == i::Token::CASE) {
Expect(i::Token::CASE, CHECK_OK);
ParseExpression(true, CHECK_OK);
- Expect(i::Token::COLON, CHECK_OK);
- } else if (token == i::Token::DEFAULT) {
- Expect(i::Token::DEFAULT, CHECK_OK);
- Expect(i::Token::COLON, CHECK_OK);
} else {
- ParseStatement(CHECK_OK);
+ Expect(i::Token::DEFAULT, CHECK_OK);
}
+ Expect(i::Token::COLON, CHECK_OK);
token = peek();
+ while (token != i::Token::CASE &&
+ token != i::Token::DEFAULT &&
+ token != i::Token::RBRACE) {
+ ParseStatement(CHECK_OK);
+ token = peek();
+ }
}
Expect(i::Token::RBRACE, ok);
return Statement::Default();
diff --git a/deps/v8/src/profile-generator-inl.h b/deps/v8/src/profile-generator-inl.h
index 6c64350e8..02e146f14 100644
--- a/deps/v8/src/profile-generator-inl.h
+++ b/deps/v8/src/profile-generator-inl.h
@@ -84,6 +84,7 @@ CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
return gc_entry_;
case JS:
case COMPILER:
+ case PARALLEL_COMPILER_PROLOGUE:
// DOM events handlers are reported as OTHER / EXTERNAL entries.
// To avoid confusing people, let's put all these entries into
// one bucket.
diff --git a/deps/v8/src/profile-generator.cc b/deps/v8/src/profile-generator.cc
index a3143bea5..b853f33cb 100644
--- a/deps/v8/src/profile-generator.cc
+++ b/deps/v8/src/profile-generator.cc
@@ -1711,8 +1711,8 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) {
name->IsString()
? collection_->names()->GetName(String::cast(name))
: "");
- } else if (object->IsGlobalContext()) {
- return AddEntry(object, HeapEntry::kHidden, "system / GlobalContext");
+ } else if (object->IsNativeContext()) {
+ return AddEntry(object, HeapEntry::kHidden, "system / NativeContext");
} else if (object->IsContext()) {
return AddEntry(object, HeapEntry::kHidden, "system / Context");
} else if (object->IsFixedArray() ||
@@ -1946,8 +1946,8 @@ void V8HeapExplorer::ExtractJSObjectReferences(
"builtins", global_obj->builtins(),
GlobalObject::kBuiltinsOffset);
SetInternalReference(global_obj, entry,
- "global_context", global_obj->global_context(),
- GlobalObject::kGlobalContextOffset);
+ "native_context", global_obj->native_context(),
+ GlobalObject::kNativeContextOffset);
SetInternalReference(global_obj, entry,
"global_receiver", global_obj->global_receiver(),
GlobalObject::kGlobalReceiverOffset);
@@ -1982,17 +1982,17 @@ void V8HeapExplorer::ExtractContextReferences(int entry, Context* context) {
EXTRACT_CONTEXT_FIELD(CLOSURE_INDEX, JSFunction, closure);
EXTRACT_CONTEXT_FIELD(PREVIOUS_INDEX, Context, previous);
EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension);
- EXTRACT_CONTEXT_FIELD(GLOBAL_INDEX, GlobalObject, global);
- if (context->IsGlobalContext()) {
+ EXTRACT_CONTEXT_FIELD(GLOBAL_OBJECT_INDEX, GlobalObject, global);
+ if (context->IsNativeContext()) {
TagObject(context->jsfunction_result_caches(),
"(context func. result caches)");
TagObject(context->normalized_map_cache(), "(context norm. map cache)");
TagObject(context->runtime_context(), "(runtime context)");
TagObject(context->data(), "(context data)");
- GLOBAL_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD);
+ NATIVE_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD);
#undef EXTRACT_CONTEXT_FIELD
for (int i = Context::FIRST_WEAK_SLOT;
- i < Context::GLOBAL_CONTEXT_SLOTS;
+ i < Context::NATIVE_CONTEXT_SLOTS;
++i) {
SetWeakReference(context, entry, i, context->get(i),
FixedArray::OffsetOfElementAt(i));
@@ -2007,22 +2007,34 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
SetInternalReference(map, entry,
"constructor", map->constructor(),
Map::kConstructorOffset);
- if (!map->instance_descriptors()->IsEmpty()) {
- TagObject(map->instance_descriptors(), "(map descriptors)");
+ if (map->HasTransitionArray()) {
+ TransitionArray* transitions = map->transitions();
+
+ Object* back_pointer = transitions->back_pointer_storage();
+ TagObject(transitions->back_pointer_storage(), "(back pointer)");
+ SetInternalReference(transitions, entry,
+ "backpointer", back_pointer,
+ TransitionArray::kBackPointerStorageOffset);
+ IndexedReferencesExtractor transitions_refs(this, transitions, entry);
+ transitions->Iterate(&transitions_refs);
+
+ TagObject(transitions, "(transition array)");
SetInternalReference(map, entry,
- "descriptors", map->instance_descriptors(),
- Map::kInstanceDescriptorsOrBitField3Offset);
- }
- if (map->unchecked_prototype_transitions()->IsFixedArray()) {
- TagObject(map->prototype_transitions(), "(prototype transitions)");
- SetInternalReference(map, entry,
- "prototype_transitions", map->prototype_transitions(),
- Map::kPrototypeTransitionsOrBackPointerOffset);
+ "transitions", transitions,
+ Map::kTransitionsOrBackPointerOffset);
} else {
+ Object* back_pointer = map->GetBackPointer();
+ TagObject(back_pointer, "(back pointer)");
SetInternalReference(map, entry,
- "back_pointer", map->GetBackPointer(),
- Map::kPrototypeTransitionsOrBackPointerOffset);
+ "backpointer", back_pointer,
+ Map::kTransitionsOrBackPointerOffset);
}
+ DescriptorArray* descriptors = map->instance_descriptors();
+ TagObject(descriptors, "(map descriptors)");
+ SetInternalReference(map, entry,
+ "descriptors", descriptors,
+ Map::kDescriptorsOffset);
+
SetInternalReference(map, entry,
"code_cache", map->code_cache(),
Map::kCodeCacheOffset);
@@ -2178,20 +2190,37 @@ void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) {
void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
if (js_obj->HasFastProperties()) {
DescriptorArray* descs = js_obj->map()->instance_descriptors();
+ int real_size = js_obj->map()->NumberOfOwnDescriptors();
for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ if (descs->GetDetails(i).descriptor_index() > real_size) continue;
switch (descs->GetType(i)) {
case FIELD: {
int index = descs->GetFieldIndex(i);
+
+ String* k = descs->GetKey(i);
if (index < js_obj->map()->inobject_properties()) {
- SetPropertyReference(
- js_obj, entry,
- descs->GetKey(i), js_obj->InObjectPropertyAt(index),
- NULL,
- js_obj->GetInObjectPropertyOffset(index));
+ Object* value = js_obj->InObjectPropertyAt(index);
+ if (k != heap_->hidden_symbol()) {
+ SetPropertyReference(
+ js_obj, entry,
+ k, value,
+ NULL,
+ js_obj->GetInObjectPropertyOffset(index));
+ } else {
+ TagObject(value, "(hidden properties)");
+ SetInternalReference(
+ js_obj, entry,
+ "hidden_properties", value,
+ js_obj->GetInObjectPropertyOffset(index));
+ }
} else {
- SetPropertyReference(
- js_obj, entry,
- descs->GetKey(i), js_obj->FastPropertyAt(index));
+ Object* value = js_obj->FastPropertyAt(index);
+ if (k != heap_->hidden_symbol()) {
+ SetPropertyReference(js_obj, entry, k, value);
+ } else {
+ TagObject(value, "(hidden properties)");
+ SetInternalReference(js_obj, entry, "hidden_properties", value);
+ }
}
break;
}
@@ -2218,9 +2247,10 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
case NORMAL: // only in slow mode
case HANDLER: // only in lookup results, not in descriptors
case INTERCEPTOR: // only in lookup results, not in descriptors
- case MAP_TRANSITION: // we do not care about transitions here...
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR: // ... and not about "holes"
+ break;
+ case TRANSITION:
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
}
@@ -2235,7 +2265,7 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
Object* value = target->IsJSGlobalPropertyCell()
? JSGlobalPropertyCell::cast(target)->value()
: target;
- if (String::cast(k)->length() > 0) {
+ if (k != heap_->hidden_symbol()) {
SetPropertyReference(js_obj, entry, String::cast(k), value);
} else {
TagObject(value, "(hidden properties)");
@@ -2294,11 +2324,12 @@ String* V8HeapExplorer::GetConstructorName(JSObject* object) {
Object* constructor_prop = NULL;
LookupResult result(heap->isolate());
object->LocalLookupRealNamedProperty(heap->constructor_symbol(), &result);
- if (result.IsProperty()) {
- constructor_prop = result.GetLazyValue();
- }
+ if (!result.IsFound()) return object->constructor_name();
+
+ constructor_prop = result.GetLazyValue();
if (constructor_prop->IsJSFunction()) {
- Object* maybe_name = JSFunction::cast(constructor_prop)->shared()->name();
+ Object* maybe_name =
+ JSFunction::cast(constructor_prop)->shared()->name();
if (maybe_name->IsString()) {
String* name = String::cast(maybe_name);
if (name->length() > 0) return name;
@@ -2560,20 +2591,6 @@ void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
}
-void V8HeapExplorer::SetPropertyShortcutReference(HeapObject* parent_obj,
- int parent_entry,
- String* reference_name,
- Object* child_obj) {
- HeapEntry* child_entry = GetEntry(child_obj);
- if (child_entry != NULL) {
- filler_->SetNamedReference(HeapGraphEdge::kShortcut,
- parent_entry,
- collection_->names()->GetName(reference_name),
- child_entry);
- }
-}
-
-
void V8HeapExplorer::SetRootGcRootsReference() {
filler_->SetIndexedAutoIndexReference(
HeapGraphEdge::kElement,
@@ -2654,7 +2671,7 @@ class GlobalObjectsEnumerator : public ObjectVisitor {
public:
virtual void VisitPointers(Object** start, Object** end) {
for (Object** p = start; p < end; p++) {
- if ((*p)->IsGlobalContext()) {
+ if ((*p)->IsNativeContext()) {
Context* context = Context::cast(*p);
JSObject* proxy = context->global_proxy();
if (proxy->IsJSGlobalProxy()) {
@@ -3078,26 +3095,26 @@ bool HeapSnapshotGenerator::GenerateSnapshot() {
Heap::kMakeHeapIterableMask,
"HeapSnapshotGenerator::GenerateSnapshot");
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
Heap* debug_heap = Isolate::Current()->heap();
- ASSERT(!debug_heap->old_data_space()->was_swept_conservatively());
- ASSERT(!debug_heap->old_pointer_space()->was_swept_conservatively());
- ASSERT(!debug_heap->code_space()->was_swept_conservatively());
- ASSERT(!debug_heap->cell_space()->was_swept_conservatively());
- ASSERT(!debug_heap->map_space()->was_swept_conservatively());
+ CHECK(!debug_heap->old_data_space()->was_swept_conservatively());
+ CHECK(!debug_heap->old_pointer_space()->was_swept_conservatively());
+ CHECK(!debug_heap->code_space()->was_swept_conservatively());
+ CHECK(!debug_heap->cell_space()->was_swept_conservatively());
+ CHECK(!debug_heap->map_space()->was_swept_conservatively());
#endif
// The following code uses heap iterators, so we want the heap to be
// stable. It should follow TagGlobalObjects as that can allocate.
AssertNoAllocation no_alloc;
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
debug_heap->Verify();
#endif
SetProgressTotal(1); // 1 pass.
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
debug_heap->Verify();
#endif
@@ -3345,9 +3362,9 @@ static int utoa(unsigned value, const Vector<char>& buffer, int buffer_pos) {
void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge,
bool first_edge) {
- // The buffer needs space for 3 unsigned ints, 3 commas and \0
+ // The buffer needs space for 3 unsigned ints, 3 commas, \n and \0
static const int kBufferSize =
- MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned * 3 + 3 + 1; // NOLINT
+ MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned * 3 + 3 + 2; // NOLINT
EmbeddedVector<char, kBufferSize> buffer;
int edge_name_or_index = edge->type() == HeapGraphEdge::kElement
|| edge->type() == HeapGraphEdge::kHidden
@@ -3362,6 +3379,7 @@ void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge,
buffer_pos = utoa(edge_name_or_index, buffer, buffer_pos);
buffer[buffer_pos++] = ',';
buffer_pos = utoa(entry_index(edge->to()), buffer, buffer_pos);
+ buffer[buffer_pos++] = '\n';
buffer[buffer_pos++] = '\0';
writer_->AddString(buffer.start());
}
diff --git a/deps/v8/src/profile-generator.h b/deps/v8/src/profile-generator.h
index d56d87470..04f4a1c71 100644
--- a/deps/v8/src/profile-generator.h
+++ b/deps/v8/src/profile-generator.h
@@ -925,10 +925,6 @@ class V8HeapExplorer : public HeapEntriesAllocator {
Object* child,
const char* name_format_string = NULL,
int field_offset = -1);
- void SetPropertyShortcutReference(HeapObject* parent_obj,
- int parent,
- String* reference_name,
- Object* child);
void SetUserGlobalReference(Object* user_global);
void SetRootGcRootsReference();
void SetGcRootsReference(VisitorSynchronization::SyncTag tag);
diff --git a/deps/v8/src/property-details.h b/deps/v8/src/property-details.h
index a623fe9b1..64e320514 100644
--- a/deps/v8/src/property-details.h
+++ b/deps/v8/src/property-details.h
@@ -55,20 +55,18 @@ class Smi;
// Must fit in the BitField PropertyDetails::TypeField.
// A copy of this is in mirror-debugger.js.
enum PropertyType {
- NORMAL = 0, // only in slow mode
- FIELD = 1, // only in fast mode
- CONSTANT_FUNCTION = 2, // only in fast mode
+ // Only in slow mode.
+ NORMAL = 0,
+ // Only in fast mode.
+ FIELD = 1,
+ CONSTANT_FUNCTION = 2,
CALLBACKS = 3,
- HANDLER = 4, // only in lookup results, not in descriptors
- INTERCEPTOR = 5, // only in lookup results, not in descriptors
- // All properties before MAP_TRANSITION are real.
- MAP_TRANSITION = 6, // only in fast mode
- CONSTANT_TRANSITION = 7, // only in fast mode
- NULL_DESCRIPTOR = 8, // only in fast mode
- // There are no IC stubs for NULL_DESCRIPTORS. Therefore,
- // NULL_DESCRIPTOR can be used as the type flag for IC stubs for
- // nonexistent properties.
- NONEXISTENT = NULL_DESCRIPTOR
+ // Only in lookup results, not in descriptors.
+ HANDLER = 4,
+ INTERCEPTOR = 5,
+ TRANSITION = 6,
+ // Only used as a marker in LookupResult.
+ NONEXISTENT = 7
};
@@ -79,50 +77,64 @@ class PropertyDetails BASE_EMBEDDED {
PropertyDetails(PropertyAttributes attributes,
PropertyType type,
int index = 0) {
- ASSERT(TypeField::is_valid(type));
- ASSERT(AttributesField::is_valid(attributes));
- ASSERT(StorageField::is_valid(index));
-
value_ = TypeField::encode(type)
| AttributesField::encode(attributes)
- | StorageField::encode(index);
+ | DictionaryStorageField::encode(index);
ASSERT(type == this->type());
ASSERT(attributes == this->attributes());
- ASSERT(index == this->index());
+ ASSERT(index == this->dictionary_index());
}
+ int pointer() { return DescriptorPointer::decode(value_); }
+
+ PropertyDetails set_pointer(int i) { return PropertyDetails(value_, i); }
+
// Conversion for storing details as Object*.
explicit inline PropertyDetails(Smi* smi);
inline Smi* AsSmi();
PropertyType type() { return TypeField::decode(value_); }
- PropertyAttributes attributes() { return AttributesField::decode(value_); }
+ PropertyAttributes attributes() const {
+ return AttributesField::decode(value_);
+ }
- int index() { return StorageField::decode(value_); }
+ int dictionary_index() {
+ return DictionaryStorageField::decode(value_);
+ }
+
+ int descriptor_index() {
+ return DescriptorStorageField::decode(value_);
+ }
inline PropertyDetails AsDeleted();
static bool IsValidIndex(int index) {
- return StorageField::is_valid(index);
+ return DictionaryStorageField::is_valid(index);
}
- bool IsReadOnly() { return (attributes() & READ_ONLY) != 0; }
- bool IsDontDelete() { return (attributes() & DONT_DELETE) != 0; }
- bool IsDontEnum() { return (attributes() & DONT_ENUM) != 0; }
- bool IsDeleted() { return DeletedField::decode(value_) != 0;}
+ bool IsReadOnly() const { return (attributes() & READ_ONLY) != 0; }
+ bool IsDontDelete() const { return (attributes() & DONT_DELETE) != 0; }
+ bool IsDontEnum() const { return (attributes() & DONT_ENUM) != 0; }
+ bool IsDeleted() const { return DeletedField::decode(value_) != 0;}
// Bit fields in value_ (type, shift, size). Must be public so the
// constants can be embedded in generated code.
- class TypeField: public BitField<PropertyType, 0, 4> {};
- class AttributesField: public BitField<PropertyAttributes, 4, 3> {};
- class DeletedField: public BitField<uint32_t, 7, 1> {};
- class StorageField: public BitField<uint32_t, 8, 32-8> {};
+ class TypeField: public BitField<PropertyType, 0, 3> {};
+ class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
+ class DeletedField: public BitField<uint32_t, 6, 1> {};
+ class DictionaryStorageField: public BitField<uint32_t, 7, 24> {};
+ class DescriptorStorageField: public BitField<uint32_t, 7, 11> {};
+ class DescriptorPointer: public BitField<uint32_t, 18, 11> {};
static const int kInitialIndex = 1;
private:
+ PropertyDetails(int value, int pointer) {
+ value_ = DescriptorPointer::update(value, pointer);
+ }
+
uint32_t value_;
};
diff --git a/deps/v8/src/property.cc b/deps/v8/src/property.cc
index 8c69541be..05342eea9 100644
--- a/deps/v8/src/property.cc
+++ b/deps/v8/src/property.cc
@@ -55,12 +55,6 @@ void LookupResult::Print(FILE* out) {
PrintF(out, " -type = normal\n");
PrintF(out, " -entry = %d", GetDictionaryEntry());
break;
- case MAP_TRANSITION:
- PrintF(out, " -type = map transition\n");
- PrintF(out, " -map:\n");
- GetTransitionMap()->Print(out);
- PrintF(out, "\n");
- break;
case CONSTANT_FUNCTION:
PrintF(out, " -type = constant function\n");
PrintF(out, " -function:\n");
@@ -83,14 +77,31 @@ void LookupResult::Print(FILE* out) {
case INTERCEPTOR:
PrintF(out, " -type = lookup interceptor\n");
break;
- case CONSTANT_TRANSITION:
- PrintF(out, " -type = constant property transition\n");
- PrintF(out, " -map:\n");
- GetTransitionMap()->Print(out);
- PrintF(out, "\n");
- break;
- case NULL_DESCRIPTOR:
- PrintF(out, " =type = null descriptor\n");
+ case TRANSITION:
+ switch (GetTransitionDetails().type()) {
+ case FIELD:
+ PrintF(out, " -type = map transition\n");
+ PrintF(out, " -map:\n");
+ GetTransitionMap()->Print(out);
+ PrintF(out, "\n");
+ return;
+ case CONSTANT_FUNCTION:
+ PrintF(out, " -type = constant property transition\n");
+ PrintF(out, " -map:\n");
+ GetTransitionMap()->Print(out);
+ PrintF(out, "\n");
+ return;
+ case CALLBACKS:
+ PrintF(out, " -type = callbacks transition\n");
+ PrintF(out, " -callback object:\n");
+ GetCallbackObject()->Print(out);
+ return;
+ default:
+ UNREACHABLE();
+ return;
+ }
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
}
@@ -101,34 +112,11 @@ void Descriptor::Print(FILE* out) {
GetKey()->ShortPrint(out);
PrintF(out, " @ ");
GetValue()->ShortPrint(out);
- PrintF(out, " %d\n", GetDetails().index());
+ PrintF(out, " %d\n", GetDetails().descriptor_index());
}
#endif
-bool Descriptor::ContainsTransition() {
- switch (details_.type()) {
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- return true;
- case CALLBACKS: {
- if (!value_->IsAccessorPair()) return false;
- AccessorPair* accessors = AccessorPair::cast(value_);
- return accessors->getter()->IsMap() || accessors->setter()->IsMap();
- }
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case HANDLER:
- case INTERCEPTOR:
- case NULL_DESCRIPTOR:
- return false;
- }
- UNREACHABLE(); // Keep the compiler happy.
- return false;
-}
-
-
} } // namespace v8::internal
diff --git a/deps/v8/src/property.h b/deps/v8/src/property.h
index aa851f1c8..9eb4194b4 100644
--- a/deps/v8/src/property.h
+++ b/deps/v8/src/property.h
@@ -29,6 +29,7 @@
#define V8_PROPERTY_H_
#include "allocation.h"
+#include "transitions.h"
namespace v8 {
namespace internal {
@@ -64,11 +65,10 @@ class Descriptor BASE_EMBEDDED {
#endif
void SetEnumerationIndex(int index) {
- ASSERT(PropertyDetails::IsValidIndex(index));
details_ = PropertyDetails(details_.attributes(), details_.type(), index);
}
- bool ContainsTransition();
+ void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
private:
String* key_;
@@ -93,7 +93,7 @@ class Descriptor BASE_EMBEDDED {
Object* value,
PropertyAttributes attributes,
PropertyType type,
- int index = 0)
+ int index)
: key_(key),
value_(value),
details_(attributes, type, index) { }
@@ -101,27 +101,6 @@ class Descriptor BASE_EMBEDDED {
friend class DescriptorArray;
};
-// A pointer from a map to the new map that is created by adding
-// a named property. These are key to the speed and functioning of V8.
-// The two maps should always have the same prototype, since
-// MapSpace::CreateBackPointers depends on this.
-class MapTransitionDescriptor: public Descriptor {
- public:
- MapTransitionDescriptor(String* key, Map* map, PropertyAttributes attributes)
- : Descriptor(key, map, attributes, MAP_TRANSITION) { }
-};
-
-// Marks a field name in a map so that adding the field is guaranteed
-// to create a FIELD descriptor in the new map. Used after adding
-// a constant function the first time, creating a CONSTANT_FUNCTION
-// descriptor in the new map. This avoids creating multiple maps with
-// the same CONSTANT_FUNCTION field.
-class ConstTransitionDescriptor: public Descriptor {
- public:
- explicit ConstTransitionDescriptor(String* key, Map* map)
- : Descriptor(key, map, NONE, CONSTANT_TRANSITION) { }
-};
-
class FieldDescriptor: public Descriptor {
public:
@@ -138,7 +117,7 @@ class ConstantFunctionDescriptor: public Descriptor {
ConstantFunctionDescriptor(String* key,
JSFunction* function,
PropertyAttributes attributes,
- int index = 0)
+ int index)
: Descriptor(key, function, attributes, CONSTANT_FUNCTION, index) {}
};
@@ -153,34 +132,6 @@ class CallbacksDescriptor: public Descriptor {
};
-template <class T>
-bool IsPropertyDescriptor(T* desc) {
- switch (desc->type()) {
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case HANDLER:
- case INTERCEPTOR:
- return true;
- case CALLBACKS: {
- Object* callback_object = desc->GetCallbackObject();
- // Non-JavaScript (i.e. native) accessors are always a property, otherwise
- // either the getter or the setter must be an accessor. Put another way:
- // If we only see map transitions and holes in a pair, this is not a
- // property.
- return (!callback_object->IsAccessorPair() ||
- AccessorPair::cast(callback_object)->ContainsAccessor());
- }
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
- return false;
- }
- UNREACHABLE(); // keep the compiler happy
- return false;
-}
-
-
class LookupResult BASE_EMBEDDED {
public:
explicit LookupResult(Isolate* isolate)
@@ -189,7 +140,7 @@ class LookupResult BASE_EMBEDDED {
lookup_type_(NOT_FOUND),
holder_(NULL),
cacheable_(true),
- details_(NONE, NORMAL) {
+ details_(NONE, NONEXISTENT) {
isolate->SetTopLookupResult(this);
}
@@ -205,6 +156,13 @@ class LookupResult BASE_EMBEDDED {
number_ = number;
}
+ void TransitionResult(JSObject* holder, int number) {
+ lookup_type_ = TRANSITION_TYPE;
+ details_ = PropertyDetails(NONE, TRANSITION);
+ holder_ = holder;
+ number_ = number;
+ }
+
void ConstantResult(JSObject* holder) {
lookup_type_ = CONSTANT_TYPE;
holder_ = holder;
@@ -237,6 +195,7 @@ class LookupResult BASE_EMBEDDED {
void NotFound() {
lookup_type_ = NOT_FOUND;
+ details_ = PropertyDetails(NONE, NONEXISTENT);
holder_ = NULL;
}
@@ -256,24 +215,61 @@ class LookupResult BASE_EMBEDDED {
}
PropertyAttributes GetAttributes() {
+ ASSERT(!IsTransition());
ASSERT(IsFound());
+ ASSERT(details_.type() != NONEXISTENT);
return details_.attributes();
}
PropertyDetails GetPropertyDetails() {
+ ASSERT(!IsTransition());
return details_;
}
- bool IsReadOnly() { return details_.IsReadOnly(); }
+ bool IsFastPropertyType() {
+ ASSERT(IsFound());
+ return IsTransition() || type() != NORMAL;
+ }
+
+ // Property callbacks does not include transitions to callbacks.
+ bool IsPropertyCallbacks() {
+ ASSERT(!(details_.type() == CALLBACKS && !IsFound()));
+ return details_.type() == CALLBACKS;
+ }
+
+ bool IsReadOnly() {
+ ASSERT(IsFound());
+ ASSERT(!IsTransition());
+ ASSERT(details_.type() != NONEXISTENT);
+ return details_.IsReadOnly();
+ }
+
+ bool IsField() {
+ ASSERT(!(details_.type() == FIELD && !IsFound()));
+ return details_.type() == FIELD;
+ }
+
+ bool IsNormal() {
+ ASSERT(!(details_.type() == NORMAL && !IsFound()));
+ return details_.type() == NORMAL;
+ }
+
+ bool IsConstantFunction() {
+ ASSERT(!(details_.type() == CONSTANT_FUNCTION && !IsFound()));
+ return details_.type() == CONSTANT_FUNCTION;
+ }
+
bool IsDontDelete() { return details_.IsDontDelete(); }
bool IsDontEnum() { return details_.IsDontEnum(); }
bool IsDeleted() { return details_.IsDeleted(); }
bool IsFound() { return lookup_type_ != NOT_FOUND; }
+ bool IsTransition() { return lookup_type_ == TRANSITION_TYPE; }
bool IsHandler() { return lookup_type_ == HANDLER_TYPE; }
+ bool IsInterceptor() { return lookup_type_ == INTERCEPTOR_TYPE; }
// Is the result is a property excluding transitions and the null descriptor?
bool IsProperty() {
- return IsFound() && IsPropertyDescriptor(this);
+ return IsFound() && !IsTransition();
}
bool IsCacheable() { return cacheable_; }
@@ -298,31 +294,55 @@ class LookupResult BASE_EMBEDDED {
}
}
+ Map* GetTransitionTarget() {
+ ASSERT(IsTransition());
+ TransitionArray* transitions = holder()->map()->transitions();
+ return transitions->GetTarget(number_);
+ }
+
+ PropertyDetails GetTransitionDetails(Map* map) {
+ ASSERT(IsTransition());
+ TransitionArray* transitions = map->transitions();
+ return transitions->GetTargetDetails(number_);
+ }
+
+ PropertyDetails GetTransitionDetails() {
+ return GetTransitionDetails(holder()->map());
+ }
+
+ bool IsTransitionToField(Map* map) {
+ return IsTransition() && GetTransitionDetails(map).type() == FIELD;
+ }
Map* GetTransitionMap() {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- ASSERT(type() == MAP_TRANSITION ||
- type() == CONSTANT_TRANSITION);
+ ASSERT(IsTransition());
return Map::cast(GetValue());
}
Map* GetTransitionMapFromMap(Map* map) {
+ ASSERT(IsTransition());
+ return map->transitions()->GetTarget(number_);
+ }
+
+ int GetTransitionIndex() {
+ ASSERT(IsTransition());
+ return number_;
+ }
+
+ int GetDescriptorIndex() {
ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- ASSERT(type() == MAP_TRANSITION);
- return Map::cast(map->instance_descriptors()->GetValue(number_));
+ return number_;
}
int GetFieldIndex() {
ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- ASSERT(type() == FIELD);
+ ASSERT(IsField());
return Descriptor::IndexFromValue(GetValue());
}
int GetLocalFieldIndexFromMap(Map* map) {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- ASSERT(type() == FIELD);
- return Descriptor::IndexFromValue(
- map->instance_descriptors()->GetValue(number_)) -
+ ASSERT(IsField());
+ return Descriptor::IndexFromValue(GetValueFromMap(map)) -
map->inobject_properties();
}
@@ -337,16 +357,15 @@ class LookupResult BASE_EMBEDDED {
}
JSFunction* GetConstantFunctionFromMap(Map* map) {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
ASSERT(type() == CONSTANT_FUNCTION);
- return JSFunction::cast(map->instance_descriptors()->GetValue(number_));
+ return JSFunction::cast(GetValueFromMap(map));
}
Object* GetCallbackObject() {
if (lookup_type_ == CONSTANT_TYPE) {
- // For now we only have the __proto__ as constant type.
return HEAP->prototype_accessors();
}
+ ASSERT(!IsTransition());
return GetValue();
}
@@ -356,14 +375,19 @@ class LookupResult BASE_EMBEDDED {
Object* GetValue() {
if (lookup_type_ == DESCRIPTOR_TYPE) {
- DescriptorArray* descriptors = holder()->map()->instance_descriptors();
- return descriptors->GetValue(number_);
+ return GetValueFromMap(holder()->map());
}
// In the dictionary case, the data is held in the value field.
ASSERT(lookup_type_ == DICTIONARY_TYPE);
return holder()->GetNormalizedProperty(this);
}
+ Object* GetValueFromMap(Map* map) const {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(number_ < map->NumberOfOwnDescriptors());
+ return map->instance_descriptors()->GetValue(number_);
+ }
+
void Iterate(ObjectVisitor* visitor);
private:
@@ -374,6 +398,7 @@ class LookupResult BASE_EMBEDDED {
enum {
NOT_FOUND,
DESCRIPTOR_TYPE,
+ TRANSITION_TYPE,
DICTIONARY_TYPE,
HANDLER_TYPE,
INTERCEPTOR_TYPE,
diff --git a/deps/v8/src/regexp-macro-assembler-irregexp.cc b/deps/v8/src/regexp-macro-assembler-irregexp.cc
index d2cd22e9a..16766cab0 100644
--- a/deps/v8/src/regexp-macro-assembler-irregexp.cc
+++ b/deps/v8/src/regexp-macro-assembler-irregexp.cc
@@ -38,8 +38,10 @@ namespace internal {
#ifdef V8_INTERPRETED_REGEXP
-RegExpMacroAssemblerIrregexp::RegExpMacroAssemblerIrregexp(Vector<byte> buffer)
- : buffer_(buffer),
+RegExpMacroAssemblerIrregexp::RegExpMacroAssemblerIrregexp(Vector<byte> buffer,
+ Zone* zone)
+ : RegExpMacroAssembler(zone),
+ buffer_(buffer),
pc_(0),
own_buffer_(false),
advance_current_end_(kInvalidPC) {
diff --git a/deps/v8/src/regexp-macro-assembler-irregexp.h b/deps/v8/src/regexp-macro-assembler-irregexp.h
index 7232342dc..4bc29809b 100644
--- a/deps/v8/src/regexp-macro-assembler-irregexp.h
+++ b/deps/v8/src/regexp-macro-assembler-irregexp.h
@@ -48,7 +48,7 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler {
// for code generation and assumes its size to be buffer_size. If the buffer
// is too small, a fatal error occurs. No deallocation of the buffer is done
// upon destruction of the assembler.
- explicit RegExpMacroAssemblerIrregexp(Vector<byte>);
+ RegExpMacroAssemblerIrregexp(Vector<byte>, Zone* zone);
virtual ~RegExpMacroAssemblerIrregexp();
// The byte-code interpreter checks on each push anyway.
virtual int stack_limit_slack() { return 1; }
diff --git a/deps/v8/src/regexp-macro-assembler.cc b/deps/v8/src/regexp-macro-assembler.cc
index a4719b53f..82ba34d5c 100644
--- a/deps/v8/src/regexp-macro-assembler.cc
+++ b/deps/v8/src/regexp-macro-assembler.cc
@@ -67,11 +67,7 @@ NativeRegExpMacroAssembler::~NativeRegExpMacroAssembler() {
bool NativeRegExpMacroAssembler::CanReadUnaligned() {
-#ifdef V8_TARGET_CAN_READ_UNALIGNED
- return !slow_safe();
-#else
- return false;
-#endif
+ return FLAG_enable_unaligned_accesses && !slow_safe();
}
const byte* NativeRegExpMacroAssembler::StringCharacterPosition(
diff --git a/deps/v8/src/regexp.js b/deps/v8/src/regexp.js
index 38090397a..a3675f033 100644
--- a/deps/v8/src/regexp.js
+++ b/deps/v8/src/regexp.js
@@ -140,18 +140,15 @@ function BuildResultFromMatchInfo(lastMatchInfo, s) {
var j = REGEXP_FIRST_CAPTURE + 2;
for (var i = 1; i < numResults; i++) {
start = lastMatchInfo[j++];
- end = lastMatchInfo[j++];
- if (end != -1) {
+ if (start != -1) {
+ end = lastMatchInfo[j];
if (start + 1 == end) {
result[i] = %_StringCharAt(s, start);
} else {
result[i] = %_SubString(s, start, end);
}
- } else {
- // Make sure the element is present. Avoid reading the undefined
- // property from the global object since this may change.
- result[i] = void 0;
}
+ j++;
}
return result;
}
diff --git a/deps/v8/src/rewriter.cc b/deps/v8/src/rewriter.cc
index 3fcd603ff..6541546cb 100644
--- a/deps/v8/src/rewriter.cc
+++ b/deps/v8/src/rewriter.cc
@@ -38,12 +38,12 @@ namespace internal {
class Processor: public AstVisitor {
public:
- explicit Processor(Variable* result)
+ Processor(Variable* result, Zone* zone)
: result_(result),
result_assigned_(false),
is_set_(false),
in_try_(false),
- factory_(isolate()) { }
+ factory_(isolate(), zone) { }
virtual ~Processor() { }
@@ -230,8 +230,8 @@ EXPRESSION_NODE_LIST(DEF_VISIT)
#undef DEF_VISIT
-// Assumes code has been parsed and scopes have been analyzed. Mutates the
-// AST, so the AST should not continue to be used in the case of failure.
+// Assumes code has been parsed. Mutates the AST, so the AST should not
+// continue to be used in the case of failure.
bool Rewriter::Rewrite(CompilationInfo* info) {
FunctionLiteral* function = info->function();
ASSERT(function != NULL);
@@ -243,7 +243,7 @@ bool Rewriter::Rewrite(CompilationInfo* info) {
if (!body->is_empty()) {
Variable* result = scope->NewTemporary(
info->isolate()->factory()->result_symbol());
- Processor processor(result);
+ Processor processor(result, info->zone());
processor.Process(body);
if (processor.HasStackOverflow()) return false;
@@ -257,12 +257,12 @@ bool Rewriter::Rewrite(CompilationInfo* info) {
// coincides with the end of the with scope which is the position of '1'.
int position = function->end_position();
VariableProxy* result_proxy = processor.factory()->NewVariableProxy(
- result->name(), false, position);
+ result->name(), false, Interface::NewValue(), position);
result_proxy->BindTo(result);
Statement* result_statement =
processor.factory()->NewReturnStatement(result_proxy);
result_statement->set_statement_pos(position);
- body->Add(result_statement, info->isolate()->zone());
+ body->Add(result_statement, info->zone());
}
}
diff --git a/deps/v8/src/runtime-profiler.cc b/deps/v8/src/runtime-profiler.cc
index 003b882f3..23f41fa7d 100644
--- a/deps/v8/src/runtime-profiler.cc
+++ b/deps/v8/src/runtime-profiler.cc
@@ -34,6 +34,7 @@
#include "compilation-cache.h"
#include "deoptimizer.h"
#include "execution.h"
+#include "full-codegen.h"
#include "global-handles.h"
#include "isolate-inl.h"
#include "mark-compact.h"
@@ -81,7 +82,8 @@ STATIC_ASSERT(kTicksWhenNotEnoughTypeInfo < 256);
// Maximum size in bytes of generated code for a function to be optimized
// the very first time it is seen on the stack.
-static const int kMaxSizeEarlyOpt = 500;
+static const int kMaxSizeEarlyOpt =
+ 5 * FullCodeGenerator::kBackEdgeDistanceUnit;
Atomic32 RuntimeProfiler::state_ = 0;
@@ -151,15 +153,20 @@ void RuntimeProfiler::Optimize(JSFunction* function, const char* reason) {
PrintF("]\n");
}
- // The next call to the function will trigger optimization.
- function->MarkForLazyRecompilation();
+ if (FLAG_parallel_recompilation) {
+ function->MarkForParallelRecompilation();
+ } else {
+ // The next call to the function will trigger optimization.
+ function->MarkForLazyRecompilation();
+ }
}
void RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function) {
// See AlwaysFullCompiler (in compiler.cc) comment on why we need
// Debug::has_break_points().
- ASSERT(function->IsMarkedForLazyRecompilation());
+ ASSERT(function->IsMarkedForLazyRecompilation() ||
+ function->IsMarkedForParallelRecompilation());
if (!FLAG_use_osr ||
isolate_->DebuggerHasBreakPoints() ||
function->IsBuiltin()) {
@@ -218,7 +225,10 @@ int RuntimeProfiler::LookupSample(JSFunction* function) {
for (int i = 0; i < kSamplerWindowSize; i++) {
Object* sample = sampler_window_[i];
if (sample != NULL) {
- if (function == sample) {
+ bool fits = FLAG_lookup_sample_by_shared
+ ? (function->shared() == JSFunction::cast(sample)->shared())
+ : (function == JSFunction::cast(sample));
+ if (fits) {
weight += sampler_window_weight_[i];
}
}
@@ -275,7 +285,8 @@ void RuntimeProfiler::OptimizeNow() {
if (shared_code->kind() != Code::FUNCTION) continue;
- if (function->IsMarkedForLazyRecompilation()) {
+ if (function->IsMarkedForLazyRecompilation() ||
+ function->IsMarkedForParallelRecompilation()) {
int nesting = shared_code->allow_osr_at_loop_nesting_level();
if (nesting == 0) AttemptOnStackReplacement(function);
int new_nesting = Min(nesting + 1, Code::kMaxLoopNestingMarker);
@@ -293,7 +304,7 @@ void RuntimeProfiler::OptimizeNow() {
// Do not record non-optimizable functions.
if (shared->optimization_disabled()) {
- if (shared->deopt_count() >= Compiler::kDefaultMaxOptCount) {
+ if (shared->deopt_count() >= FLAG_max_opt_count) {
// If optimization was disabled due to many deoptimizations,
// then check if the function is hot and try to reenable optimization.
int ticks = shared_code->profiler_ticks();
@@ -308,8 +319,6 @@ void RuntimeProfiler::OptimizeNow() {
}
if (!function->IsOptimizable()) continue;
-
-
if (FLAG_watch_ic_patching) {
int ticks = shared_code->profiler_ticks();
@@ -332,7 +341,7 @@ void RuntimeProfiler::OptimizeNow() {
}
}
} else if (!any_ic_changed_ &&
- shared_code->instruction_size() < kMaxSizeEarlyOpt) {
+ shared_code->instruction_size() < kMaxSizeEarlyOpt) {
// If no IC was patched since the last tick and this function is very
// small, optimistically optimize it now.
Optimize(function, "small function");
diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc
index de3a55e5d..19d9a3f0b 100644
--- a/deps/v8/src/runtime.cc
+++ b/deps/v8/src/runtime.cc
@@ -54,7 +54,7 @@
#include "runtime-profiler.h"
#include "runtime.h"
#include "scopeinfo.h"
-#include "smart-array-pointer.h"
+#include "smart-pointers.h"
#include "string-search.h"
#include "stub-cache.h"
#include "v8threads.h"
@@ -303,7 +303,7 @@ static Handle<Map> ComputeObjectLiteralMap(
}
}
// If we only have symbols and array indices among keys then we can
- // use the map cache in the global context.
+ // use the map cache in the native context.
const int kMaxKeys = 10;
if ((number_of_symbol_keys == number_of_properties) &&
(number_of_symbol_keys < kMaxKeys)) {
@@ -342,14 +342,14 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
Handle<FixedArray> constant_properties,
bool should_have_fast_elements,
bool has_function_literal) {
- // Get the global context from the literals array. This is the
+ // Get the native context from the literals array. This is the
// context in which the function was created and we use the object
// function from this context to create the object literal. We do
- // not use the object function from the current global context
+ // not use the object function from the current native context
// because this might be the object function from another context
// which we should not have access to.
Handle<Context> context =
- Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals));
+ Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
// In case we have function literals, we want the object to be in
// slow properties mode for now. We don't go in the map cache because
@@ -464,7 +464,7 @@ Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
Handle<FixedArray> elements) {
// Create the JSArray.
Handle<JSFunction> constructor(
- JSFunction::GlobalContextFromLiterals(*literals)->array_function());
+ JSFunction::NativeContextFromLiterals(*literals)->array_function());
Handle<JSArray> object =
Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor));
@@ -474,8 +474,8 @@ Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
FixedArrayBase::cast(elements->get(1)));
ASSERT(IsFastElementsKind(constant_elements_kind));
- Context* global_context = isolate->context()->global_context();
- Object* maybe_maps_array = global_context->js_array_maps();
+ Context* native_context = isolate->context()->native_context();
+ Object* maybe_maps_array = native_context->js_array_maps();
ASSERT(!maybe_maps_array->IsUndefined());
Object* maybe_map = FixedArray::cast(maybe_maps_array)->get(
constant_elements_kind);
@@ -635,6 +635,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
// Check if boilerplate exists. If not, create it first.
Handle<Object> boilerplate(literals->get(literals_index), isolate);
if (*boilerplate == isolate->heap()->undefined_value()) {
+ ASSERT(*elements != isolate->heap()->empty_fixed_array());
boilerplate =
Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
if (boilerplate.is_null()) return Failure::Exception();
@@ -672,7 +673,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
ASSERT(args.length() == 2);
- Object* handler = args[0];
+ CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
Object* prototype = args[1];
Object* used_prototype =
prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
@@ -682,9 +683,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSFunctionProxy) {
ASSERT(args.length() == 4);
- Object* handler = args[0];
+ CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
Object* call_trap = args[1];
- Object* construct_trap = args[2];
+ RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
+ CONVERT_ARG_CHECKED(JSFunction, construct_trap, 2);
Object* prototype = args[3];
Object* used_prototype =
prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
@@ -754,7 +756,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) {
Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
table = ObjectHashSetAdd(table, key);
holder->set_table(*table);
- return isolate->heap()->undefined_symbol();
+ return isolate->heap()->undefined_value();
}
@@ -776,7 +778,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
table = ObjectHashSetRemove(table, key);
holder->set_table(*table);
- return isolate->heap()->undefined_symbol();
+ return isolate->heap()->undefined_value();
}
@@ -794,8 +796,35 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGet) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
- Handle<Object> key(args[1]);
- return ObjectHashTable::cast(holder->table())->Lookup(*key);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MapHas) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ return isolate->heap()->ToBoolean(!lookup->IsTheHole());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ Handle<ObjectHashTable> new_table =
+ PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value());
+ holder->set_table(*new_table);
+ return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
@@ -803,12 +832,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
- Handle<Object> key(args[1]);
- Handle<Object> value(args[2]);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
holder->set_table(*new_table);
- return *value;
+ return isolate->heap()->undefined_value();
}
@@ -825,11 +854,38 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
- NoHandleAllocation ha;
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapHas) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ return isolate->heap()->ToBoolean(!lookup->IsTheHole());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapDelete) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
- return ObjectHashTable::cast(weakmap->table())->Lookup(*key);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ Handle<ObjectHashTable> new_table =
+ PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value());
+ weakmap->set_table(*new_table);
+ return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
@@ -842,7 +898,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapSet) {
Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
weakmap->set_table(*new_table);
- return *value;
+ return isolate->heap()->undefined_value();
}
@@ -898,13 +954,13 @@ static void GetOwnPropertyImplementation(JSObject* obj,
LookupResult* result) {
obj->LocalLookupRealNamedProperty(name, result);
- if (!result->IsProperty()) {
- Object* proto = obj->GetPrototype();
- if (proto->IsJSObject() &&
- JSObject::cast(proto)->map()->is_hidden_prototype())
- GetOwnPropertyImplementation(JSObject::cast(proto),
- name, result);
- }
+ if (result->IsFound()) return;
+
+ Object* proto = obj->GetPrototype();
+ if (proto->IsJSObject() &&
+ JSObject::cast(proto)->map()->is_hidden_prototype())
+ GetOwnPropertyImplementation(JSObject::cast(proto),
+ name, result);
}
@@ -1115,7 +1171,7 @@ static MaybeObject* GetOwnProperty(Isolate* isolate,
elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum()));
elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete()));
- bool is_js_accessor = (result.type() == CALLBACKS) &&
+ bool is_js_accessor = result.IsPropertyCallbacks() &&
(result.GetCallbackObject()->IsAccessorPair());
if (is_js_accessor) {
@@ -1190,7 +1246,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpCompile) {
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
- Handle<Object> result = RegExpImpl::Compile(re, pattern, flags);
+ Handle<Object> result =
+ RegExpImpl::Compile(re, pattern, flags, isolate->runtime_zone());
if (result.is_null()) return Failure::Exception();
return *result;
}
@@ -1237,14 +1294,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
bool needs_access_checks = old_map->is_access_check_needed();
if (needs_access_checks) {
// Copy map so it won't interfere constructor's initial map.
- Object* new_map;
- { MaybeObject* maybe_new_map =
- old_map->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
- if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
- }
+ Map* new_map;
+ MaybeObject* maybe_new_map = old_map->Copy();
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- Map::cast(new_map)->set_is_access_check_needed(false);
- object->set_map(Map::cast(new_map));
+ new_map->set_is_access_check_needed(false);
+ object->set_map(new_map);
}
return isolate->heap()->ToBoolean(needs_access_checks);
}
@@ -1256,14 +1311,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_EnableAccessChecks) {
Map* old_map = object->map();
if (!old_map->is_access_check_needed()) {
// Copy map so it won't interfere constructor's initial map.
- Object* new_map;
- { MaybeObject* maybe_new_map =
- old_map->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
- if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
- }
+ Map* new_map;
+ MaybeObject* maybe_new_map = old_map->Copy();
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- Map::cast(new_map)->set_is_access_check_needed(true);
- object->set_map(Map::cast(new_map));
+ new_map->set_is_access_check_needed(true);
+ object->set_map(new_map);
}
return isolate->heap()->undefined_value();
}
@@ -1286,7 +1339,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
ASSERT(args.length() == 3);
HandleScope scope(isolate);
Handle<GlobalObject> global = Handle<GlobalObject>(
- isolate->context()->global());
+ isolate->context()->global_object());
Handle<Context> context = args.at<Context>(0);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
@@ -1311,16 +1364,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
if (is_var || is_const) {
// Lookup the property in the global object, and don't set the
// value of the variable if the property is already there.
- // Do the lookup locally only, see ES5 errata.
+ // Do the lookup locally only, see ES5 erratum.
LookupResult lookup(isolate);
- if (FLAG_es52_globals)
- global->LocalLookup(*name, &lookup);
- else
+ if (FLAG_es52_globals) {
+ Object* obj = *global;
+ do {
+ JSObject::cast(obj)->LocalLookup(*name, &lookup);
+ if (lookup.IsFound()) break;
+ obj = obj->GetPrototype();
+ } while (obj->IsJSObject() &&
+ JSObject::cast(obj)->map()->is_hidden_prototype());
+ } else {
global->Lookup(*name, &lookup);
- if (lookup.IsProperty()) {
+ }
+ if (lookup.IsFound()) {
// We found an existing property. Unless it was an interceptor
// that claims the property is absent, skip this declaration.
- if (lookup.type() != INTERCEPTOR) continue;
+ if (!lookup.IsInterceptor()) continue;
PropertyAttributes attributes = global->GetPropertyAttribute(*name);
if (attributes != ABSENT) continue;
// Fall-through and introduce the absent property by using
@@ -1353,12 +1413,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags);
- if (!lookup.IsProperty() || is_function || is_module) {
+ if (!lookup.IsFound() || is_function || is_module) {
// If the local property exists, check that we can reconfigure it
// as required for function declarations.
- if (lookup.IsProperty() && lookup.IsDontDelete()) {
+ if (lookup.IsFound() && lookup.IsDontDelete()) {
if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
- lookup.type() == CALLBACKS) {
+ lookup.IsPropertyCallbacks()) {
return ThrowRedeclarationError(
isolate, is_function ? "function" : "module", name);
}
@@ -1387,7 +1447,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- // Declarations are always made in a function or global context. In the
+ // Declarations are always made in a function or native context. In the
// case of eval code, the context passed is the context of the caller,
// which may be some nested context and not the declaration context.
RUNTIME_ASSERT(args[0]->IsContext());
@@ -1426,7 +1486,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
}
} else {
// Slow case: The property is in the context extension object of a
- // function context or the global object of a global context.
+ // function context or the global object of a native context.
Handle<JSObject> object = Handle<JSObject>::cast(holder);
RETURN_IF_EMPTY_HANDLE(
isolate,
@@ -1467,7 +1527,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
!object->IsJSContextExtensionObject()) {
LookupResult lookup(isolate);
object->Lookup(*name, &lookup);
- if (lookup.IsFound() && (lookup.type() == CALLBACKS)) {
+ if (lookup.IsPropertyCallbacks()) {
return ThrowRedeclarationError(isolate, "const", name);
}
}
@@ -1497,7 +1557,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
bool assign = args.length() == 3;
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
- GlobalObject* global = isolate->context()->global();
+ GlobalObject* global = isolate->context()->global_object();
RUNTIME_ASSERT(args[1]->IsSmi());
CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
@@ -1520,7 +1580,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
JSObject::cast(object)->map()->is_hidden_prototype()) {
JSObject* raw_holder = JSObject::cast(object);
raw_holder->LocalLookup(*name, &lookup);
- if (lookup.IsFound() && lookup.type() == INTERCEPTOR) {
+ if (lookup.IsInterceptor()) {
HandleScope handle_scope(isolate);
Handle<JSObject> holder(raw_holder);
PropertyAttributes intercepted = holder->GetPropertyAttribute(*name);
@@ -1540,7 +1600,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
}
// Reload global in case the loop above performed a GC.
- global = isolate->context()->global();
+ global = isolate->context()->global_object();
if (assign) {
return global->SetProperty(*name, args[2], attributes, strict_mode_flag);
}
@@ -1557,7 +1617,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
Handle<Object> value = args.at<Object>(1);
// Get the current global object from top.
- GlobalObject* global = isolate->context()->global();
+ GlobalObject* global = isolate->context()->global_object();
// According to ECMA-262, section 12.2, page 62, the property must
// not be deletable. Since it's a const, it must be READ_ONLY too.
@@ -1571,7 +1631,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
// We use SetLocalPropertyIgnoreAttributes instead
LookupResult lookup(isolate);
global->LocalLookup(*name, &lookup);
- if (!lookup.IsProperty()) {
+ if (!lookup.IsFound()) {
return global->SetLocalPropertyIgnoreAttributes(*name,
*value,
attributes);
@@ -1581,7 +1641,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
// Restore global object from context (in case of GC) and continue
// with setting the value.
HandleScope handle_scope(isolate);
- Handle<GlobalObject> global(isolate->context()->global());
+ Handle<GlobalObject> global(isolate->context()->global_object());
// BUG 1213575: Handle the case where we have to set a read-only
// property through an interceptor and only do it if it's
@@ -1598,14 +1658,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
// constant. For now, we determine this by checking if the
// current value is the hole.
// Strict mode handling not needed (const is disallowed in strict mode).
- PropertyType type = lookup.type();
- if (type == FIELD) {
+ if (lookup.IsField()) {
FixedArray* properties = global->properties();
int index = lookup.GetFieldIndex();
if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
properties->set(index, *value);
}
- } else if (type == NORMAL) {
+ } else if (lookup.IsNormal()) {
if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
!lookup.IsReadOnly()) {
global->SetNormalizedProperty(&lookup, *value);
@@ -1613,7 +1672,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
} else {
// Ignore re-initialization of constants that have already been
// assigned a function value.
- ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION);
+ ASSERT(lookup.IsReadOnly() && lookup.IsConstantFunction());
}
// Use the set value as the result of the operation.
@@ -1628,7 +1687,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
Handle<Object> value(args[0], isolate);
ASSERT(!value->IsTheHole());
- // Initializations are always done in a function or global context.
+ // Initializations are always done in a function or native context.
RUNTIME_ASSERT(args[1]->IsContext());
Handle<Context> context(Context::cast(args[1])->declaration_context());
@@ -1656,7 +1715,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
// global object.
if (attributes == ABSENT) {
Handle<JSObject> global = Handle<JSObject>(
- isolate->context()->global());
+ isolate->context()->global_object());
// Strict mode not needed (const disallowed in strict mode).
RETURN_IF_EMPTY_HANDLE(
isolate,
@@ -1689,14 +1748,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
ASSERT(lookup.IsFound()); // the property was declared
ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
- PropertyType type = lookup.type();
- if (type == FIELD) {
+ if (lookup.IsField()) {
FixedArray* properties = object->properties();
int index = lookup.GetFieldIndex();
if (properties->get(index)->IsTheHole()) {
properties->set(index, *value);
}
- } else if (type == NORMAL) {
+ } else if (lookup.IsNormal()) {
if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
object->SetNormalizedProperty(&lookup, *value);
}
@@ -1750,8 +1808,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
Handle<Object> result = RegExpImpl::Exec(regexp,
subject,
index,
- last_match_info,
- isolate->zone());
+ last_match_info);
if (result.is_null()) return Failure::Exception();
return *result;
}
@@ -1779,7 +1836,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
AssertNoAllocation no_gc;
HandleScope scope(isolate);
reinterpret_cast<HeapObject*>(new_object)->
- set_map(isolate->global_context()->regexp_result_map());
+ set_map(isolate->native_context()->regexp_result_map());
}
JSArray* array = JSArray::cast(new_object);
array->set_properties(isolate->heap()->empty_fixed_array());
@@ -1931,9 +1988,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
// Returns undefined for strict or native functions, or
// the associated global receiver for "normal" functions.
- Context* global_context =
- function->context()->global()->global_context();
- return global_context->global()->global_receiver();
+ Context* native_context =
+ function->context()->global_object()->native_context();
+ return native_context->global_object()->global_receiver();
}
@@ -1948,11 +2005,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MaterializeRegExpLiteral) {
// Get the RegExp function from the context in the literals array.
// This is the RegExp function from the context in which the
// function was created. We do not use the RegExp function from the
- // current global context because this might be the RegExp function
+ // current native context because this might be the RegExp function
// from another context which we should not have access to.
Handle<JSFunction> constructor =
Handle<JSFunction>(
- JSFunction::GlobalContextFromLiterals(*literals)->regexp_function());
+ JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
// Compute the regular expression literal.
bool has_pending_exception;
Handle<Object> regexp =
@@ -2010,8 +2067,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
- Object* obj = f->RemovePrototype();
- if (obj->IsFailure()) return obj;
+ f->RemovePrototype();
return isolate->heap()->undefined_value();
}
@@ -2104,40 +2160,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
RUNTIME_ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, function, 0);
- MaybeObject* maybe_name =
- isolate->heap()->AllocateStringFromAscii(CStrVector("prototype"));
- String* name;
- if (!maybe_name->To(&name)) return maybe_name;
+ String* name = isolate->heap()->prototype_symbol();
if (function->HasFastProperties()) {
// Construct a new field descriptor with updated attributes.
DescriptorArray* instance_desc = function->map()->instance_descriptors();
- int index = instance_desc->Search(name);
+
+ int index = instance_desc->SearchWithCache(name, function->map());
ASSERT(index != DescriptorArray::kNotFound);
PropertyDetails details = instance_desc->GetDetails(index);
+
CallbacksDescriptor new_desc(name,
instance_desc->GetValue(index),
static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
- details.index());
- // Construct a new field descriptors array containing the new descriptor.
- Object* descriptors_unchecked;
- { MaybeObject* maybe_descriptors_unchecked =
- instance_desc->CopyInsert(&new_desc, REMOVE_TRANSITIONS);
- if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
- return maybe_descriptors_unchecked;
- }
- }
- DescriptorArray* new_descriptors =
- DescriptorArray::cast(descriptors_unchecked);
+ details.descriptor_index());
+
// Create a new map featuring the new field descriptors array.
- Object* map_unchecked;
- { MaybeObject* maybe_map_unchecked = function->map()->CopyDropDescriptors();
- if (!maybe_map_unchecked->ToObject(&map_unchecked)) {
- return maybe_map_unchecked;
- }
- }
- Map* new_map = Map::cast(map_unchecked);
- new_map->set_instance_descriptors(new_descriptors);
+ Map* new_map;
+ MaybeObject* maybe_map =
+ function->map()->CopyReplaceDescriptor(
+ instance_desc, &new_desc, index, OMIT_TRANSITION);
+ if (!maybe_map->To(&new_map)) return maybe_map;
+
function->set_map(new_map);
} else { // Dictionary properties.
// Directly manipulate the property details.
@@ -2147,7 +2191,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
PropertyDetails new_details(
static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
details.type(),
- details.index());
+ details.dictionary_index());
function->property_dictionary()->DetailsAtPut(entry, new_details);
}
return function;
@@ -2185,8 +2229,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
Handle<SharedFunctionInfo> target_shared(target->shared());
Handle<SharedFunctionInfo> source_shared(source->shared());
- if (!source->is_compiled() &&
- !JSFunction::CompileLazy(source, KEEP_EXCEPTION)) {
+ if (!JSFunction::EnsureCompiled(source, KEEP_EXCEPTION)) {
return Failure::Exception();
}
@@ -2211,6 +2254,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
// Set the code of the target function.
target->ReplaceCode(source_shared->code());
+ ASSERT(target->next_function_link()->IsUndefined());
// Make sure we get a fresh copy of the literal vector to avoid cross
// context contamination.
@@ -2219,14 +2263,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
Handle<FixedArray> literals =
isolate->factory()->NewFixedArray(number_of_literals, TENURED);
if (number_of_literals > 0) {
- literals->set(JSFunction::kLiteralGlobalContextIndex,
- context->global_context());
+ literals->set(JSFunction::kLiteralNativeContextIndex,
+ context->native_context());
}
target->set_context(*context);
target->set_literals(*literals);
- target->set_next_function_link(isolate->heap()->undefined_value());
- if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) {
+ if (isolate->logger()->is_logging_code_events() ||
+ CpuProfiler::is_profiling(isolate)) {
isolate->logger()->LogExistingFunction(
source_shared, Handle<Code>(source_shared->code()));
}
@@ -2263,19 +2307,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCharCodeAt) {
ASSERT(args.length() == 2);
CONVERT_ARG_CHECKED(String, subject, 0);
- Object* index = args[1];
- RUNTIME_ASSERT(index->IsNumber());
-
- uint32_t i = 0;
- if (index->IsSmi()) {
- int value = Smi::cast(index)->value();
- if (value < 0) return isolate->heap()->nan_value();
- i = value;
- } else {
- ASSERT(index->IsHeapNumber());
- double value = HeapNumber::cast(index)->value();
- i = static_cast<uint32_t>(DoubleToInteger(value));
- }
+ CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
// Flatten the string. If someone wants to get a char at an index
// in a cons string, it is likely that more indices will be
@@ -2369,18 +2401,13 @@ class FixedArrayBuilder {
return array_->length();
}
- Handle<JSArray> ToJSArray() {
- Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_);
- result_array->set_length(Smi::FromInt(length_));
- return result_array;
- }
-
Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
FACTORY->SetContent(target_array, array_);
target_array->set_length(Smi::FromInt(length_));
return target_array;
}
+
private:
Handle<FixedArray> array_;
int length_;
@@ -2499,10 +2526,6 @@ class ReplacementStringBuilder {
character_count_ += by;
}
- Handle<JSArray> GetParts() {
- return array_builder_.ToJSArray();
- }
-
private:
Handle<SeqAsciiString> NewRawAsciiString(int length) {
return heap_->isolate()->factory()->NewRawAsciiString(length);
@@ -2531,28 +2554,24 @@ class ReplacementStringBuilder {
class CompiledReplacement {
public:
explicit CompiledReplacement(Zone* zone)
- : parts_(1, zone), replacement_substrings_(0, zone),
- simple_hint_(false),
- zone_(zone) {}
+ : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
- void Compile(Handle<String> replacement,
+ // Return whether the replacement is simple.
+ bool Compile(Handle<String> replacement,
int capture_count,
int subject_length);
+ // Use Apply only if Compile returned false.
void Apply(ReplacementStringBuilder* builder,
int match_from,
int match_to,
- Handle<JSArray> last_match_info);
+ int32_t* match);
// Number of distinct parts of the replacement pattern.
int parts() {
return parts_.length();
}
- bool simple_hint() {
- return simple_hint_;
- }
-
Zone* zone() const { return zone_; }
private:
@@ -2613,11 +2632,11 @@ class CompiledReplacement {
};
template<typename Char>
- static bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
- Vector<Char> characters,
- int capture_count,
- int subject_length,
- Zone* zone) {
+ bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
+ Vector<Char> characters,
+ int capture_count,
+ int subject_length,
+ Zone* zone) {
int length = characters.length();
int last = 0;
for (int i = 0; i < length; i++) {
@@ -2711,7 +2730,7 @@ class CompiledReplacement {
}
if (length > last) {
if (last == 0) {
- parts->Add(ReplacementPart::ReplacementString(), zone);
+ // Replacement is simple. Do not use Apply to do the replacement.
return true;
} else {
parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
@@ -2722,33 +2741,35 @@ class CompiledReplacement {
ZoneList<ReplacementPart> parts_;
ZoneList<Handle<String> > replacement_substrings_;
- bool simple_hint_;
Zone* zone_;
};
-void CompiledReplacement::Compile(Handle<String> replacement,
+bool CompiledReplacement::Compile(Handle<String> replacement,
int capture_count,
int subject_length) {
{
AssertNoAllocation no_alloc;
String::FlatContent content = replacement->GetFlatContent();
ASSERT(content.IsFlat());
+ bool simple = false;
if (content.IsAscii()) {
- simple_hint_ = ParseReplacementPattern(&parts_,
- content.ToAsciiVector(),
- capture_count,
- subject_length,
- zone());
+ simple = ParseReplacementPattern(&parts_,
+ content.ToAsciiVector(),
+ capture_count,
+ subject_length,
+ zone());
} else {
ASSERT(content.IsTwoByte());
- simple_hint_ = ParseReplacementPattern(&parts_,
- content.ToUC16Vector(),
- capture_count,
- subject_length,
- zone());
+ simple = ParseReplacementPattern(&parts_,
+ content.ToUC16Vector(),
+ capture_count,
+ subject_length,
+ zone());
}
+ if (simple) return true;
}
+
Isolate* isolate = replacement->GetIsolate();
// Find substrings of replacement string and create them as String objects.
int substring_index = 0;
@@ -2768,13 +2789,15 @@ void CompiledReplacement::Compile(Handle<String> replacement,
substring_index++;
}
}
+ return false;
}
void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
int match_from,
int match_to,
- Handle<JSArray> last_match_info) {
+ int32_t* match) {
+ ASSERT_LT(0, parts_.length());
for (int i = 0, n = parts_.length(); i < n; i++) {
ReplacementPart part = parts_[i];
switch (part.tag) {
@@ -2790,9 +2813,8 @@ void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
}
case SUBJECT_CAPTURE: {
int capture = part.data;
- FixedArray* match_info = FixedArray::cast(last_match_info->elements());
- int from = RegExpImpl::GetCapture(match_info, capture * 2);
- int to = RegExpImpl::GetCapture(match_info, capture * 2 + 1);
+ int from = match[capture * 2];
+ int to = match[capture * 2 + 1];
if (from >= 0 && to > from) {
builder->AddSubjectSlice(from, to);
}
@@ -2914,85 +2936,19 @@ void FindStringIndicesDispatch(Isolate* isolate,
}
-// Two smis before and after the match, for very long strings.
-const int kMaxBuilderEntriesPerRegExpMatch = 5;
-
-
-static void SetLastMatchInfoNoCaptures(Handle<String> subject,
- Handle<JSArray> last_match_info,
- int match_start,
- int match_end) {
- // Fill last_match_info with a single capture.
- last_match_info->EnsureSize(2 + RegExpImpl::kLastMatchOverhead);
- AssertNoAllocation no_gc;
- FixedArray* elements = FixedArray::cast(last_match_info->elements());
- RegExpImpl::SetLastCaptureCount(elements, 2);
- RegExpImpl::SetLastInput(elements, *subject);
- RegExpImpl::SetLastSubject(elements, *subject);
- RegExpImpl::SetCapture(elements, 0, match_start);
- RegExpImpl::SetCapture(elements, 1, match_end);
-}
-
-
-template <typename SubjectChar, typename PatternChar>
-static bool SearchStringMultiple(Isolate* isolate,
- Vector<const SubjectChar> subject,
- Vector<const PatternChar> pattern,
- String* pattern_string,
- FixedArrayBuilder* builder,
- int* match_pos) {
- int pos = *match_pos;
- int subject_length = subject.length();
- int pattern_length = pattern.length();
- int max_search_start = subject_length - pattern_length;
- StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
- while (pos <= max_search_start) {
- if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
- *match_pos = pos;
- return false;
- }
- // Position of end of previous match.
- int match_end = pos + pattern_length;
- int new_pos = search.Search(subject, match_end);
- if (new_pos >= 0) {
- // A match.
- if (new_pos > match_end) {
- ReplacementStringBuilder::AddSubjectSlice(builder,
- match_end,
- new_pos);
- }
- pos = new_pos;
- builder->Add(pattern_string);
- } else {
- break;
- }
- }
-
- if (pos < max_search_start) {
- ReplacementStringBuilder::AddSubjectSlice(builder,
- pos + pattern_length,
- subject_length);
- }
- *match_pos = pos;
- return true;
-}
-
-
-
-
template<typename ResultSeqString>
MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString(
Isolate* isolate,
Handle<String> subject,
Handle<JSRegExp> pattern_regexp,
Handle<String> replacement,
- Handle<JSArray> last_match_info,
- Zone* zone) {
+ Handle<JSArray> last_match_info) {
ASSERT(subject->IsFlat());
ASSERT(replacement->IsFlat());
- ZoneScope zone_space(isolate, DELETE_ON_EXIT);
- ZoneList<int> indices(8, isolate->zone());
+ Zone* zone = isolate->runtime_zone();
+ ZoneScope zone_space(zone, DELETE_ON_EXIT);
+ ZoneList<int> indices(8, zone);
ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
String* pattern =
String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
@@ -3000,8 +2956,8 @@ MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString(
int pattern_len = pattern->length();
int replacement_len = replacement->length();
- FindStringIndicesDispatch(isolate, *subject, pattern, &indices, 0xffffffff,
- zone);
+ FindStringIndicesDispatch(
+ isolate, *subject, pattern, &indices, 0xffffffff, zone);
int matches = indices.length();
if (matches == 0) return *subject;
@@ -3056,10 +3012,9 @@ MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString(
subject_len);
}
- SetLastMatchInfoNoCaptures(subject,
- last_match_info,
- indices.at(matches - 1),
- indices.at(matches - 1) + pattern_len);
+ int32_t match_indices[] = { indices.at(matches - 1),
+ indices.at(matches - 1) + pattern_len };
+ RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
return *result;
}
@@ -3067,138 +3022,101 @@ MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString(
MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString(
Isolate* isolate,
- String* subject,
- JSRegExp* regexp,
- String* replacement,
- JSArray* last_match_info,
- Zone* zone) {
+ Handle<String> subject,
+ Handle<JSRegExp> regexp,
+ Handle<String> replacement,
+ Handle<JSArray> last_match_info) {
ASSERT(subject->IsFlat());
ASSERT(replacement->IsFlat());
- HandleScope handles(isolate);
-
- int length = subject->length();
- Handle<String> subject_handle(subject);
- Handle<JSRegExp> regexp_handle(regexp);
- Handle<String> replacement_handle(replacement);
- Handle<JSArray> last_match_info_handle(last_match_info);
- Handle<Object> match = RegExpImpl::Exec(regexp_handle,
- subject_handle,
- 0,
- last_match_info_handle,
- isolate->zone());
- if (match.is_null()) {
- return Failure::Exception();
- }
- if (match->IsNull()) {
- return *subject_handle;
- }
-
- int capture_count = regexp_handle->CaptureCount();
+ bool is_global = regexp->GetFlags().is_global();
+ int capture_count = regexp->CaptureCount();
+ int subject_length = subject->length();
// CompiledReplacement uses zone allocation.
- ZoneScope zonescope(isolate, DELETE_ON_EXIT);
- CompiledReplacement compiled_replacement(isolate->zone());
- compiled_replacement.Compile(replacement_handle,
- capture_count,
- length);
-
- bool is_global = regexp_handle->GetFlags().is_global();
+ Zone* zone = isolate->runtime_zone();
+ ZoneScope zonescope(zone, DELETE_ON_EXIT);
+ CompiledReplacement compiled_replacement(zone);
+ bool simple_replace = compiled_replacement.Compile(replacement,
+ capture_count,
+ subject_length);
// Shortcut for simple non-regexp global replacements
if (is_global &&
- regexp_handle->TypeTag() == JSRegExp::ATOM &&
- compiled_replacement.simple_hint()) {
- if (subject_handle->HasOnlyAsciiChars() &&
- replacement_handle->HasOnlyAsciiChars()) {
+ regexp->TypeTag() == JSRegExp::ATOM &&
+ simple_replace) {
+ if (subject->HasOnlyAsciiChars() && replacement->HasOnlyAsciiChars()) {
return StringReplaceAtomRegExpWithString<SeqAsciiString>(
- isolate,
- subject_handle,
- regexp_handle,
- replacement_handle,
- last_match_info_handle,
- zone);
+ isolate, subject, regexp, replacement, last_match_info);
} else {
return StringReplaceAtomRegExpWithString<SeqTwoByteString>(
- isolate,
- subject_handle,
- regexp_handle,
- replacement_handle,
- last_match_info_handle,
- zone);
+ isolate, subject, regexp, replacement, last_match_info);
}
}
+ RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate);
+ if (global_cache.HasException()) return Failure::Exception();
+
+ int32_t* current_match = global_cache.FetchNext();
+ if (current_match == NULL) {
+ if (global_cache.HasException()) return Failure::Exception();
+ return *subject;
+ }
+
// Guessing the number of parts that the final result string is built
// from. Global regexps can match any number of times, so we guess
// conservatively.
int expected_parts =
(compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1;
ReplacementStringBuilder builder(isolate->heap(),
- subject_handle,
+ subject,
expected_parts);
- // Index of end of last match.
- int prev = 0;
-
// Number of parts added by compiled replacement plus preceeding
// string and possibly suffix after last match. It is possible for
// all components to use two elements when encoded as two smis.
const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
- bool matched = true;
+
+ int prev = 0;
+
do {
- ASSERT(last_match_info_handle->HasFastObjectElements());
- // Increase the capacity of the builder before entering local handle-scope,
- // so its internal buffer can safely allocate a new handle if it grows.
builder.EnsureCapacity(parts_added_per_loop);
- HandleScope loop_scope(isolate);
- int start, end;
- {
- AssertNoAllocation match_info_array_is_not_in_a_handle;
- FixedArray* match_info_array =
- FixedArray::cast(last_match_info_handle->elements());
-
- ASSERT_EQ(capture_count * 2 + 2,
- RegExpImpl::GetLastCaptureCount(match_info_array));
- start = RegExpImpl::GetCapture(match_info_array, 0);
- end = RegExpImpl::GetCapture(match_info_array, 1);
- }
+ int start = current_match[0];
+ int end = current_match[1];
if (prev < start) {
builder.AddSubjectSlice(prev, start);
}
- compiled_replacement.Apply(&builder,
- start,
- end,
- last_match_info_handle);
+
+ if (simple_replace) {
+ builder.AddString(replacement);
+ } else {
+ compiled_replacement.Apply(&builder,
+ start,
+ end,
+ current_match);
+ }
prev = end;
// Only continue checking for global regexps.
if (!is_global) break;
- // Continue from where the match ended, unless it was an empty match.
- int next = end;
- if (start == end) {
- next = end + 1;
- if (next > length) break;
- }
+ current_match = global_cache.FetchNext();
+ } while (current_match != NULL);
- match = RegExpImpl::Exec(regexp_handle,
- subject_handle,
- next,
- last_match_info_handle,
- isolate->zone());
- if (match.is_null()) {
- return Failure::Exception();
- }
- matched = !match->IsNull();
- } while (matched);
+ if (global_cache.HasException()) return Failure::Exception();
- if (prev < length) {
- builder.AddSubjectSlice(prev, length);
+ if (prev < subject_length) {
+ builder.EnsureCapacity(2);
+ builder.AddSubjectSlice(prev, subject_length);
}
+ RegExpImpl::SetLastMatchInfo(last_match_info,
+ subject,
+ capture_count,
+ global_cache.LastSuccessfulMatch());
+
return *(builder.ToString());
}
@@ -3206,70 +3124,51 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString(
template <typename ResultSeqString>
MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString(
Isolate* isolate,
- String* subject,
- JSRegExp* regexp,
- JSArray* last_match_info,
- Zone* zone) {
+ Handle<String> subject,
+ Handle<JSRegExp> regexp,
+ Handle<JSArray> last_match_info) {
ASSERT(subject->IsFlat());
- HandleScope handles(isolate);
-
- Handle<String> subject_handle(subject);
- Handle<JSRegExp> regexp_handle(regexp);
- Handle<JSArray> last_match_info_handle(last_match_info);
+ bool is_global = regexp->GetFlags().is_global();
// Shortcut for simple non-regexp global replacements
- if (regexp_handle->GetFlags().is_global() &&
- regexp_handle->TypeTag() == JSRegExp::ATOM) {
- Handle<String> empty_string_handle(HEAP->empty_string());
- if (subject_handle->HasOnlyAsciiChars()) {
+ if (is_global &&
+ regexp->TypeTag() == JSRegExp::ATOM) {
+ Handle<String> empty_string(HEAP->empty_string());
+ if (subject->HasOnlyAsciiChars()) {
return StringReplaceAtomRegExpWithString<SeqAsciiString>(
isolate,
- subject_handle,
- regexp_handle,
- empty_string_handle,
- last_match_info_handle,
- zone);
+ subject,
+ regexp,
+ empty_string,
+ last_match_info);
} else {
return StringReplaceAtomRegExpWithString<SeqTwoByteString>(
isolate,
- subject_handle,
- regexp_handle,
- empty_string_handle,
- last_match_info_handle,
- zone);
+ subject,
+ regexp,
+ empty_string,
+ last_match_info);
}
}
- Handle<Object> match = RegExpImpl::Exec(regexp_handle,
- subject_handle,
- 0,
- last_match_info_handle,
- isolate->zone());
- if (match.is_null()) return Failure::Exception();
- if (match->IsNull()) return *subject_handle;
+ RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate);
+ if (global_cache.HasException()) return Failure::Exception();
- ASSERT(last_match_info_handle->HasFastObjectElements());
-
- int start, end;
- {
- AssertNoAllocation match_info_array_is_not_in_a_handle;
- FixedArray* match_info_array =
- FixedArray::cast(last_match_info_handle->elements());
-
- start = RegExpImpl::GetCapture(match_info_array, 0);
- end = RegExpImpl::GetCapture(match_info_array, 1);
+ int32_t* current_match = global_cache.FetchNext();
+ if (current_match == NULL) {
+ if (global_cache.HasException()) return Failure::Exception();
+ return *subject;
}
- bool global = regexp_handle->GetFlags().is_global();
+ int start = current_match[0];
+ int end = current_match[1];
+ int capture_count = regexp->CaptureCount();
+ int subject_length = subject->length();
- if (start == end && !global) return *subject_handle;
+ int new_length = subject_length - (end - start);
+ if (new_length == 0) return isolate->heap()->empty_string();
- int length = subject_handle->length();
- int new_length = length - (end - start);
- if (new_length == 0) {
- return isolate->heap()->empty_string();
- }
Handle<ResultSeqString> answer;
if (ResultSeqString::kHasAsciiEncoding) {
answer = Handle<ResultSeqString>::cast(
@@ -3279,74 +3178,55 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString(
isolate->factory()->NewRawTwoByteString(new_length));
}
- // If the regexp isn't global, only match once.
- if (!global) {
- if (start > 0) {
- String::WriteToFlat(*subject_handle,
- answer->GetChars(),
- 0,
- start);
- }
- if (end < length) {
- String::WriteToFlat(*subject_handle,
- answer->GetChars() + start,
- end,
- length);
+ if (!is_global) {
+ RegExpImpl::SetLastMatchInfo(
+ last_match_info, subject, capture_count, current_match);
+ if (start == end) {
+ return *subject;
+ } else {
+ if (start > 0) {
+ String::WriteToFlat(*subject, answer->GetChars(), 0, start);
+ }
+ if (end < subject_length) {
+ String::WriteToFlat(
+ *subject, answer->GetChars() + start, end, subject_length);
+ }
+ return *answer;
}
- return *answer;
}
- int prev = 0; // Index of end of last match.
- int next = 0; // Start of next search (prev unless last match was empty).
+ int prev = 0;
int position = 0;
do {
+ start = current_match[0];
+ end = current_match[1];
if (prev < start) {
// Add substring subject[prev;start] to answer string.
- String::WriteToFlat(*subject_handle,
- answer->GetChars() + position,
- prev,
- start);
+ String::WriteToFlat(
+ *subject, answer->GetChars() + position, prev, start);
position += start - prev;
}
prev = end;
- next = end;
- // Continue from where the match ended, unless it was an empty match.
- if (start == end) {
- next++;
- if (next > length) break;
- }
- match = RegExpImpl::Exec(regexp_handle,
- subject_handle,
- next,
- last_match_info_handle,
- isolate->zone());
- if (match.is_null()) return Failure::Exception();
- if (match->IsNull()) break;
-
- ASSERT(last_match_info_handle->HasFastObjectElements());
- HandleScope loop_scope(isolate);
- {
- AssertNoAllocation match_info_array_is_not_in_a_handle;
- FixedArray* match_info_array =
- FixedArray::cast(last_match_info_handle->elements());
- start = RegExpImpl::GetCapture(match_info_array, 0);
- end = RegExpImpl::GetCapture(match_info_array, 1);
- }
- } while (true);
- if (prev < length) {
+ current_match = global_cache.FetchNext();
+ } while (current_match != NULL);
+
+ if (global_cache.HasException()) return Failure::Exception();
+
+ RegExpImpl::SetLastMatchInfo(last_match_info,
+ subject,
+ capture_count,
+ global_cache.LastSuccessfulMatch());
+
+ if (prev < subject_length) {
// Add substring subject[prev;length] to answer string.
- String::WriteToFlat(*subject_handle,
- answer->GetChars() + position,
- prev,
- length);
- position += length - prev;
+ String::WriteToFlat(
+ *subject, answer->GetChars() + position, prev, subject_length);
+ position += subject_length - prev;
}
- if (position == 0) {
- return isolate->heap()->empty_string();
- }
+ if (position == 0) return isolate->heap()->empty_string();
// Shorten string and fill
int string_size = ResultSeqString::SizeFor(position);
@@ -3369,59 +3249,40 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString(
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) {
ASSERT(args.length() == 4);
- CONVERT_ARG_CHECKED(String, subject, 0);
- if (!subject->IsFlat()) {
- Object* flat_subject;
- { MaybeObject* maybe_flat_subject = subject->TryFlatten();
- if (!maybe_flat_subject->ToObject(&flat_subject)) {
- return maybe_flat_subject;
- }
- }
- subject = String::cast(flat_subject);
- }
+ HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(String, replacement, 2);
- if (!replacement->IsFlat()) {
- Object* flat_replacement;
- { MaybeObject* maybe_flat_replacement = replacement->TryFlatten();
- if (!maybe_flat_replacement->ToObject(&flat_replacement)) {
- return maybe_flat_replacement;
- }
- }
- replacement = String::cast(flat_replacement);
- }
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
- CONVERT_ARG_CHECKED(JSRegExp, regexp, 1);
- CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
+ if (!subject->IsFlat()) subject = FlattenGetString(subject);
+
+ if (!replacement->IsFlat()) replacement = FlattenGetString(replacement);
ASSERT(last_match_info->HasFastObjectElements());
- Zone* zone = isolate->zone();
if (replacement->length() == 0) {
if (subject->HasOnlyAsciiChars()) {
return StringReplaceRegExpWithEmptyString<SeqAsciiString>(
- isolate, subject, regexp, last_match_info, zone);
+ isolate, subject, regexp, last_match_info);
} else {
return StringReplaceRegExpWithEmptyString<SeqTwoByteString>(
- isolate, subject, regexp, last_match_info, zone);
+ isolate, subject, regexp, last_match_info);
}
}
- return StringReplaceRegExpWithString(isolate,
- subject,
- regexp,
- replacement,
- last_match_info,
- zone);
+ return StringReplaceRegExpWithString(
+ isolate, subject, regexp, replacement, last_match_info);
}
-Handle<String> Runtime::StringReplaceOneCharWithString(Isolate* isolate,
- Handle<String> subject,
- Handle<String> search,
- Handle<String> replace,
- bool* found,
- int recursion_limit) {
+Handle<String> StringReplaceOneCharWithString(Isolate* isolate,
+ Handle<String> subject,
+ Handle<String> search,
+ Handle<String> replace,
+ bool* found,
+ int recursion_limit) {
if (recursion_limit == 0) return Handle<String>::null();
if (subject->IsConsString()) {
ConsString* cons = ConsString::cast(*subject);
@@ -3449,7 +3310,7 @@ Handle<String> Runtime::StringReplaceOneCharWithString(Isolate* isolate,
return subject;
} else {
- int index = StringMatch(isolate, subject, search, 0);
+ int index = Runtime::StringMatch(isolate, subject, search, 0);
if (index == -1) return subject;
*found = true;
Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
@@ -3472,20 +3333,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceOneCharWithString) {
// retry with a flattened subject string.
const int kRecursionLimit = 0x1000;
bool found = false;
- Handle<String> result =
- Runtime::StringReplaceOneCharWithString(isolate,
- subject,
- search,
- replace,
- &found,
- kRecursionLimit);
+ Handle<String> result = StringReplaceOneCharWithString(isolate,
+ subject,
+ search,
+ replace,
+ &found,
+ kRecursionLimit);
if (!result.is_null()) return *result;
- return *Runtime::StringReplaceOneCharWithString(isolate,
- FlattenGetString(subject),
- search,
- replace,
- &found,
- kRecursionLimit);
+ return *StringReplaceOneCharWithString(isolate,
+ FlattenGetString(subject),
+ search,
+ replace,
+ &found,
+ kRecursionLimit);
}
@@ -3716,8 +3576,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) {
} else {
CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
- start = FastD2I(from_number);
- end = FastD2I(to_number);
+ start = FastD2IChecked(from_number);
+ end = FastD2IChecked(to_number);
}
RUNTIME_ASSERT(end >= start);
RUNTIME_ASSERT(start >= 0);
@@ -3735,48 +3595,45 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
HandleScope handles;
- Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info,
- isolate->zone());
+ RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
+ if (global_cache.HasException()) return Failure::Exception();
- if (match.is_null()) {
- return Failure::Exception();
+ int capture_count = regexp->CaptureCount();
+
+ Zone* zone = isolate->runtime_zone();
+ ZoneScope zone_space(zone, DELETE_ON_EXIT);
+ ZoneList<int> offsets(8, zone);
+
+ while (true) {
+ int32_t* match = global_cache.FetchNext();
+ if (match == NULL) break;
+ offsets.Add(match[0], zone); // start
+ offsets.Add(match[1], zone); // end
}
- if (match->IsNull()) {
+
+ if (global_cache.HasException()) return Failure::Exception();
+
+ if (offsets.length() == 0) {
+ // Not a single match.
return isolate->heap()->null_value();
}
- int length = subject->length();
- Zone* zone = isolate->zone();
- ZoneScope zone_space(isolate, DELETE_ON_EXIT);
- ZoneList<int> offsets(8, zone);
- int start;
- int end;
- do {
- {
- AssertNoAllocation no_alloc;
- FixedArray* elements = FixedArray::cast(regexp_info->elements());
- start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value();
- end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value();
- }
- offsets.Add(start, zone);
- offsets.Add(end, zone);
- if (start == end) if (++end > length) break;
- match = RegExpImpl::Exec(regexp, subject, end, regexp_info,
- isolate->zone());
- if (match.is_null()) {
- return Failure::Exception();
- }
- } while (!match->IsNull());
+ RegExpImpl::SetLastMatchInfo(regexp_info,
+ subject,
+ capture_count,
+ global_cache.LastSuccessfulMatch());
+
int matches = offsets.length() / 2;
Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
- Handle<String> substring = isolate->factory()->
- NewSubString(subject, offsets.at(0), offsets.at(1));
+ Handle<String> substring =
+ isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
elements->set(0, *substring);
- for (int i = 1; i < matches ; i++) {
+ for (int i = 1; i < matches; i++) {
+ HandleScope temp_scope(isolate);
int from = offsets.at(i * 2);
int to = offsets.at(i * 2 + 1);
- Handle<String> substring = isolate->factory()->
- NewProperSubString(subject, from, to);
+ Handle<String> substring =
+ isolate->factory()->NewProperSubString(subject, from, to);
elements->set(i, *substring);
}
Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
@@ -3785,298 +3642,154 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
}
-static bool SearchStringMultiple(Isolate* isolate,
- Handle<String> subject,
- Handle<String> pattern,
- Handle<JSArray> last_match_info,
- FixedArrayBuilder* builder) {
- ASSERT(subject->IsFlat());
- ASSERT(pattern->IsFlat());
-
- // Treating as if a previous match was before first character.
- int match_pos = -pattern->length();
-
- for (;;) { // Break when search complete.
- builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
- AssertNoAllocation no_gc;
- String::FlatContent subject_content = subject->GetFlatContent();
- String::FlatContent pattern_content = pattern->GetFlatContent();
- if (subject_content.IsAscii()) {
- Vector<const char> subject_vector = subject_content.ToAsciiVector();
- if (pattern_content.IsAscii()) {
- if (SearchStringMultiple(isolate,
- subject_vector,
- pattern_content.ToAsciiVector(),
- *pattern,
- builder,
- &match_pos)) break;
- } else {
- if (SearchStringMultiple(isolate,
- subject_vector,
- pattern_content.ToUC16Vector(),
- *pattern,
- builder,
- &match_pos)) break;
- }
- } else {
- Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
- if (pattern_content.IsAscii()) {
- if (SearchStringMultiple(isolate,
- subject_vector,
- pattern_content.ToAsciiVector(),
- *pattern,
- builder,
- &match_pos)) break;
- } else {
- if (SearchStringMultiple(isolate,
- subject_vector,
- pattern_content.ToUC16Vector(),
- *pattern,
- builder,
- &match_pos)) break;
- }
- }
- }
-
- if (match_pos >= 0) {
- SetLastMatchInfoNoCaptures(subject,
- last_match_info,
- match_pos,
- match_pos + pattern->length());
- return true;
- }
- return false; // No matches at all.
-}
-
-
-static int SearchRegExpNoCaptureMultiple(
+// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
+// separate last match info. See comment on that function.
+template<bool has_capture>
+static MaybeObject* SearchRegExpMultiple(
Isolate* isolate,
Handle<String> subject,
Handle<JSRegExp> regexp,
Handle<JSArray> last_match_array,
- FixedArrayBuilder* builder) {
+ Handle<JSArray> result_array) {
ASSERT(subject->IsFlat());
- ASSERT(regexp->CaptureCount() == 0);
- int match_start = -1;
- int match_end = 0;
- int pos = 0;
- int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject,
- isolate->zone());
- if (registers_per_match < 0) return RegExpImpl::RE_EXCEPTION;
-
- int max_matches;
- int num_registers = RegExpImpl::GlobalOffsetsVectorSize(regexp,
- registers_per_match,
- &max_matches);
- OffsetsVector registers(num_registers, isolate);
- Vector<int32_t> register_vector(registers.vector(), registers.length());
- int subject_length = subject->length();
- bool first = true;
- for (;;) { // Break on failure, return on exception.
- int num_matches = RegExpImpl::IrregexpExecRaw(regexp,
- subject,
- pos,
- register_vector,
- isolate->zone());
- if (num_matches > 0) {
- for (int match_index = 0; match_index < num_matches; match_index++) {
- int32_t* current_match = &register_vector[match_index * 2];
- match_start = current_match[0];
- builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
- if (match_end < match_start) {
- ReplacementStringBuilder::AddSubjectSlice(builder,
- match_end,
- match_start);
- }
- match_end = current_match[1];
- HandleScope loop_scope(isolate);
- if (!first) {
- builder->Add(*isolate->factory()->NewProperSubString(subject,
- match_start,
- match_end));
- } else {
- builder->Add(*isolate->factory()->NewSubString(subject,
- match_start,
- match_end));
- first = false;
- }
- }
+ ASSERT_NE(has_capture, regexp->CaptureCount() == 0);
- // If we did not get the maximum number of matches, we can stop here
- // since there are no matches left.
- if (num_matches < max_matches) break;
+ int capture_count = regexp->CaptureCount();
+ int subject_length = subject->length();
- if (match_start != match_end) {
- pos = match_end;
- } else {
- pos = match_end + 1;
- if (pos > subject_length) break;
- }
- } else if (num_matches == 0) {
- break;
- } else {
- ASSERT_EQ(num_matches, RegExpImpl::RE_EXCEPTION);
- return RegExpImpl::RE_EXCEPTION;
- }
- }
+ static const int kMinLengthToCache = 0x1000;
- if (match_start >= 0) {
- if (match_end < subject_length) {
- ReplacementStringBuilder::AddSubjectSlice(builder,
- match_end,
- subject_length);
+ if (subject_length > kMinLengthToCache) {
+ Handle<Object> cached_answer(RegExpResultsCache::Lookup(
+ isolate->heap(),
+ *subject,
+ regexp->data(),
+ RegExpResultsCache::REGEXP_MULTIPLE_INDICES));
+ if (*cached_answer != Smi::FromInt(0)) {
+ Handle<FixedArray> cached_fixed_array =
+ Handle<FixedArray>(FixedArray::cast(*cached_answer));
+ // The cache FixedArray is a COW-array and can therefore be reused.
+ isolate->factory()->SetContent(result_array, cached_fixed_array);
+ // The actual length of the result array is stored in the last element of
+ // the backing store (the backing FixedArray may have a larger capacity).
+ Object* cached_fixed_array_last_element =
+ cached_fixed_array->get(cached_fixed_array->length() - 1);
+ Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
+ result_array->set_length(js_array_length);
+ RegExpImpl::SetLastMatchInfo(
+ last_match_array, subject, capture_count, NULL);
+ return *result_array;
}
- SetLastMatchInfoNoCaptures(subject,
- last_match_array,
- match_start,
- match_end);
- return RegExpImpl::RE_SUCCESS;
- } else {
- return RegExpImpl::RE_FAILURE; // No matches at all.
}
-}
-
-// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
-// separate last match info. See comment on that function.
-static int SearchRegExpMultiple(
- Isolate* isolate,
- Handle<String> subject,
- Handle<JSRegExp> regexp,
- Handle<JSArray> last_match_array,
- FixedArrayBuilder* builder) {
+ RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
+ if (global_cache.HasException()) return Failure::Exception();
- ASSERT(subject->IsFlat());
- int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject,
- isolate->zone());
- if (registers_per_match < 0) return RegExpImpl::RE_EXCEPTION;
-
- int max_matches;
- int num_registers = RegExpImpl::GlobalOffsetsVectorSize(regexp,
- registers_per_match,
- &max_matches);
- OffsetsVector registers(num_registers, isolate);
- Vector<int32_t> register_vector(registers.vector(), registers.length());
-
- int num_matches = RegExpImpl::IrregexpExecRaw(regexp,
- subject,
- 0,
- register_vector,
- isolate->zone());
+ Handle<FixedArray> result_elements;
+ if (result_array->HasFastObjectElements()) {
+ result_elements =
+ Handle<FixedArray>(FixedArray::cast(result_array->elements()));
+ }
+ if (result_elements.is_null() || result_elements->length() < 16) {
+ result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
+ }
- int capture_count = regexp->CaptureCount();
- int subject_length = subject->length();
+ FixedArrayBuilder builder(result_elements);
// Position to search from.
- int pos = 0;
- // End of previous match. Differs from pos if match was empty.
+ int match_start = -1;
int match_end = 0;
bool first = true;
- if (num_matches > 0) {
- do {
- int match_start = 0;
- for (int match_index = 0; match_index < num_matches; match_index++) {
- int32_t* current_match =
- &register_vector[match_index * registers_per_match];
- match_start = current_match[0];
- builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
- if (match_end < match_start) {
- ReplacementStringBuilder::AddSubjectSlice(builder,
- match_end,
- match_start);
- }
- match_end = current_match[1];
-
- {
- // Avoid accumulating new handles inside loop.
- HandleScope temp_scope(isolate);
- // Arguments array to replace function is match, captures, index and
- // subject, i.e., 3 + capture count in total.
- Handle<FixedArray> elements =
- isolate->factory()->NewFixedArray(3 + capture_count);
- Handle<String> match;
- if (!first) {
- match = isolate->factory()->NewProperSubString(subject,
- match_start,
- match_end);
- } else {
- match = isolate->factory()->NewSubString(subject,
- match_start,
- match_end);
- }
- elements->set(0, *match);
- for (int i = 1; i <= capture_count; i++) {
- int start = current_match[i * 2];
- if (start >= 0) {
- int end = current_match[i * 2 + 1];
- ASSERT(start <= end);
- Handle<String> substring;
- if (!first) {
- substring =
- isolate->factory()->NewProperSubString(subject, start, end);
- } else {
- substring =
- isolate->factory()->NewSubString(subject, start, end);
- }
- elements->set(i, *substring);
- } else {
- ASSERT(current_match[i * 2 + 1] < 0);
- elements->set(i, isolate->heap()->undefined_value());
- }
- }
- elements->set(capture_count + 1, Smi::FromInt(match_start));
- elements->set(capture_count + 2, *subject);
- builder->Add(*isolate->factory()->NewJSArrayWithElements(elements));
- }
+ // Two smis before and after the match, for very long strings.
+ static const int kMaxBuilderEntriesPerRegExpMatch = 5;
+
+ while (true) {
+ int32_t* current_match = global_cache.FetchNext();
+ if (current_match == NULL) break;
+ match_start = current_match[0];
+ builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
+ if (match_end < match_start) {
+ ReplacementStringBuilder::AddSubjectSlice(&builder,
+ match_end,
+ match_start);
+ }
+ match_end = current_match[1];
+ {
+ // Avoid accumulating new handles inside loop.
+ HandleScope temp_scope(isolate);
+ Handle<String> match;
+ if (!first) {
+ match = isolate->factory()->NewProperSubString(subject,
+ match_start,
+ match_end);
+ } else {
+ match = isolate->factory()->NewSubString(subject,
+ match_start,
+ match_end);
first = false;
}
- // If we did not get the maximum number of matches, we can stop here
- // since there are no matches left.
- if (num_matches < max_matches) break;
-
- if (match_end > match_start) {
- pos = match_end;
- } else {
- pos = match_end + 1;
- if (pos > subject_length) {
- break;
+ if (has_capture) {
+ // Arguments array to replace function is match, captures, index and
+ // subject, i.e., 3 + capture count in total.
+ Handle<FixedArray> elements =
+ isolate->factory()->NewFixedArray(3 + capture_count);
+
+ elements->set(0, *match);
+ for (int i = 1; i <= capture_count; i++) {
+ int start = current_match[i * 2];
+ if (start >= 0) {
+ int end = current_match[i * 2 + 1];
+ ASSERT(start <= end);
+ Handle<String> substring =
+ isolate->factory()->NewSubString(subject, start, end);
+ elements->set(i, *substring);
+ } else {
+ ASSERT(current_match[i * 2 + 1] < 0);
+ elements->set(i, isolate->heap()->undefined_value());
+ }
}
+ elements->set(capture_count + 1, Smi::FromInt(match_start));
+ elements->set(capture_count + 2, *subject);
+ builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
+ } else {
+ builder.Add(*match);
}
+ }
+ }
- num_matches = RegExpImpl::IrregexpExecRaw(regexp,
- subject,
- pos,
- register_vector,
- isolate->zone());
- } while (num_matches > 0);
-
- if (num_matches != RegExpImpl::RE_EXCEPTION) {
- // Finished matching, with at least one match.
- if (match_end < subject_length) {
- ReplacementStringBuilder::AddSubjectSlice(builder,
- match_end,
- subject_length);
- }
+ if (global_cache.HasException()) return Failure::Exception();
- int last_match_capture_count = (capture_count + 1) * 2;
- int last_match_array_size =
- last_match_capture_count + RegExpImpl::kLastMatchOverhead;
- last_match_array->EnsureSize(last_match_array_size);
- AssertNoAllocation no_gc;
- FixedArray* elements = FixedArray::cast(last_match_array->elements());
- // We have to set this even though the rest of the last match array is
- // ignored.
- RegExpImpl::SetLastCaptureCount(elements, last_match_capture_count);
- // These are also read without consulting the override.
- RegExpImpl::SetLastSubject(elements, *subject);
- RegExpImpl::SetLastInput(elements, *subject);
- return RegExpImpl::RE_SUCCESS;
+ if (match_start >= 0) {
+ // Finished matching, with at least one match.
+ if (match_end < subject_length) {
+ ReplacementStringBuilder::AddSubjectSlice(&builder,
+ match_end,
+ subject_length);
}
+
+ RegExpImpl::SetLastMatchInfo(
+ last_match_array, subject, capture_count, NULL);
+
+ if (subject_length > kMinLengthToCache) {
+ // Store the length of the result array into the last element of the
+ // backing FixedArray.
+ builder.EnsureCapacity(1);
+ Handle<FixedArray> fixed_array = builder.array();
+ fixed_array->set(fixed_array->length() - 1,
+ Smi::FromInt(builder.length()));
+ // Cache the result and turn the FixedArray into a COW array.
+ RegExpResultsCache::Enter(isolate->heap(),
+ *subject,
+ regexp->data(),
+ *fixed_array,
+ RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
+ }
+ return *builder.ToJSArray(result_array);
+ } else {
+ return isolate->heap()->null_value(); // No matches at all.
}
- // No matches at all, return failure or exception result directly.
- return num_matches;
}
@@ -4095,47 +3808,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
ASSERT(last_match_info->HasFastObjectElements());
ASSERT(regexp->GetFlags().is_global());
- Handle<FixedArray> result_elements;
- if (result_array->HasFastObjectElements()) {
- result_elements =
- Handle<FixedArray>(FixedArray::cast(result_array->elements()));
- }
- if (result_elements.is_null() || result_elements->length() < 16) {
- result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
- }
- FixedArrayBuilder builder(result_elements);
-
- if (regexp->TypeTag() == JSRegExp::ATOM) {
- Handle<String> pattern(
- String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex)));
- ASSERT(pattern->IsFlat());
- if (SearchStringMultiple(isolate, subject, pattern,
- last_match_info, &builder)) {
- return *builder.ToJSArray(result_array);
- }
- return isolate->heap()->null_value();
- }
-
- ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
- int result;
if (regexp->CaptureCount() == 0) {
- result = SearchRegExpNoCaptureMultiple(isolate,
- subject,
- regexp,
- last_match_info,
- &builder);
+ return SearchRegExpMultiple<false>(
+ isolate, subject, regexp, last_match_info, result_array);
} else {
- result = SearchRegExpMultiple(isolate,
- subject,
- regexp,
- last_match_info,
- &builder);
+ return SearchRegExpMultiple<true>(
+ isolate, subject, regexp, last_match_info, result_array);
}
- if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array);
- if (result == RegExpImpl::RE_FAILURE) return isolate->heap()->null_value();
- ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
- return Failure::Exception();
}
@@ -4190,7 +3870,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
return *isolate->factory()->infinity_symbol();
}
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
- int f = FastD2I(f_number);
+ int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= 0);
char* str = DoubleToFixedCString(value, f);
MaybeObject* res =
@@ -4215,7 +3895,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
return *isolate->factory()->infinity_symbol();
}
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
- int f = FastD2I(f_number);
+ int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= -1 && f <= 20);
char* str = DoubleToExponentialCString(value, f);
MaybeObject* res =
@@ -4240,7 +3920,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
return *isolate->factory()->infinity_symbol();
}
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
- int f = FastD2I(f_number);
+ int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= 1 && f <= 21);
char* str = DoubleToPrecisionCString(value, f);
MaybeObject* res =
@@ -4376,7 +4056,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
// appropriate.
LookupResult result(isolate);
receiver->LocalLookup(key, &result);
- if (result.IsFound() && result.type() == FIELD) {
+ if (result.IsField()) {
int offset = result.GetFieldIndex();
keyed_lookup_cache->Update(receiver_map, key, offset);
return receiver->FastPropertyAt(offset);
@@ -4488,7 +4168,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
js_object->LocalLookupRealNamedProperty(*name, &result);
// Special case for callback properties.
- if (result.IsFound() && result.type() == CALLBACKS) {
+ if (result.IsPropertyCallbacks()) {
Object* callback = result.GetCallbackObject();
// To be compatible with Safari we do not change the value on API objects
// in Object.defineProperty(). Firefox disagrees here, and actually changes
@@ -4515,8 +4195,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
// map. The current version of SetObjectProperty does not handle attributes
// correctly in the case where a property is a field and is reset with
// new attributes.
- if (result.IsProperty() &&
- (attr != result.GetAttributes() || result.type() == CALLBACKS)) {
+ if (result.IsFound() &&
+ (attr != result.GetAttributes() || result.IsPropertyCallbacks())) {
// New attributes - normalize to avoid writing to instance descriptor
if (js_object->IsJSGlobalProxy()) {
// Since the result is a property, the prototype will exist so
@@ -4864,14 +4544,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) {
#ifdef ENABLE_DEBUGGER_SUPPORT
Debug* debug = isolate->debug();
if (!debug->IsStepping()) return isolate->heap()->undefined_value();
- CONVERT_ARG_CHECKED(Object, callback, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
HandleScope scope(isolate);
- Handle<SharedFunctionInfo> shared_info(JSFunction::cast(callback)->shared());
// When leaving the callback, step out has been activated, but not performed
// if we do not leave the builtin. To be able to step into the callback
// again, we need to clear the step out at this point.
debug->ClearStepOut();
- debug->FloodWithOneShot(shared_info);
+ debug->FloodWithOneShot(callback);
#endif // ENABLE_DEBUGGER_SUPPORT
return isolate->heap()->undefined_value();
}
@@ -5353,15 +5032,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ToSlowProperties) {
- ASSERT(args.length() == 1);
- Object* obj = args[0];
- return (obj->IsJSObject() && !obj->IsJSGlobalProxy())
- ? JSObject::cast(obj)->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0)
- : obj;
-}
-
-
RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
@@ -6453,11 +6123,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
RUNTIME_ASSERT(pattern_length > 0);
if (limit == 0xffffffffu) {
- Handle<Object> cached_answer(StringSplitCache::Lookup(
- isolate->heap()->string_split_cache(),
+ Handle<Object> cached_answer(RegExpResultsCache::Lookup(
+ isolate->heap(),
*subject,
- *pattern));
+ *pattern,
+ RegExpResultsCache::STRING_SPLIT_SUBSTRINGS));
if (*cached_answer != Smi::FromInt(0)) {
+ // The cache FixedArray is a COW-array and can therefore be reused.
Handle<JSArray> result =
isolate->factory()->NewJSArrayWithElements(
Handle<FixedArray>::cast(cached_answer));
@@ -6473,8 +6145,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
static const int kMaxInitialListCapacity = 16;
- Zone* zone = isolate->zone();
- ZoneScope scope(isolate, DELETE_ON_EXIT);
+ Zone* zone = isolate->runtime_zone();
+ ZoneScope scope(zone, DELETE_ON_EXIT);
// Find (up to limit) indices of separator and end-of-string in subject
int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
@@ -6517,11 +6189,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
if (limit == 0xffffffffu) {
if (result->HasFastObjectElements()) {
- StringSplitCache::Enter(isolate->heap(),
- isolate->heap()->string_split_cache(),
- *subject,
- *pattern,
- *elements);
+ RegExpResultsCache::Enter(isolate->heap(),
+ *subject,
+ *pattern,
+ *elements,
+ RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
}
}
@@ -7787,8 +7459,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
isolate->heap()->non_strict_arguments_elements_map());
Handle<Map> old_map(result->map());
- Handle<Map> new_map =
- isolate->factory()->CopyMapDropTransitions(old_map);
+ Handle<Map> new_map = isolate->factory()->CopyMap(old_map);
new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
result->set_map(*new_map);
@@ -8145,17 +7816,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
// instead of a new JSFunction object. This way, errors are
// reported the same way whether or not 'Function' is called
// using 'new'.
- return isolate->context()->global();
+ return isolate->context()->global_object();
}
}
// The function should be compiled for the optimization hints to be
- // available. We cannot use EnsureCompiled because that forces a
- // compilation through the shared function info which makes it
- // impossible for us to optimize.
- if (!function->is_compiled()) {
- JSFunction::CompileLazy(function, CLEAR_EXCEPTION);
- }
+ // available.
+ JSFunction::EnsureCompiled(function, CLEAR_EXCEPTION);
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
if (!function->has_initial_map() &&
@@ -8233,7 +7900,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
// If the function is not optimizable or debugger is active continue using the
// code from the full compiler.
- if (!function->shared()->code()->optimizable() ||
+ if (!FLAG_crankshaft ||
+ !function->shared()->code()->optimizable() ||
isolate->DebuggerHasBreakPoints()) {
if (FLAG_trace_opt) {
PrintF("[failed to optimize ");
@@ -8247,7 +7915,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
}
function->shared()->code()->set_profiler_ticks(0);
if (JSFunction::CompileOptimized(function,
- AstNode::kNoNumber,
+ BailoutId::None(),
CLEAR_EXCEPTION)) {
return function->code();
}
@@ -8261,6 +7929,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ParallelRecompile) {
+ HandleScope handle_scope(isolate);
+ ASSERT(FLAG_parallel_recompilation);
+ Compiler::RecompileParallel(args.at<JSFunction>(0));
+ return *isolate->factory()->undefined_value();
+}
+
+
class ActivationsFinder : public ThreadVisitor {
public:
explicit ActivationsFinder(JSFunction* function)
@@ -8286,35 +7962,6 @@ class ActivationsFinder : public ThreadVisitor {
};
-static void MaterializeArgumentsObjectInFrame(Isolate* isolate,
- JavaScriptFrame* frame) {
- Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
- Handle<Object> arguments;
- for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) {
- if (frame->GetExpression(i) == isolate->heap()->arguments_marker()) {
- if (arguments.is_null()) {
- // FunctionGetArguments can't throw an exception, so cast away the
- // doubt with an assert.
- arguments = Handle<Object>(
- Accessors::FunctionGetArguments(*function,
- NULL)->ToObjectUnchecked());
- ASSERT(*arguments != isolate->heap()->null_value());
- ASSERT(*arguments != isolate->heap()->undefined_value());
- }
- frame->SetExpression(i, *arguments);
- if (FLAG_trace_deopt) {
- PrintF("Materializing arguments object for frame %p - %p: %p ",
- reinterpret_cast<void*>(frame->sp()),
- reinterpret_cast<void*>(frame->fp()),
- reinterpret_cast<void*>(*arguments));
- arguments->ShortPrint();
- PrintF("\n");
- }
- }
- }
-}
-
-
RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -8323,25 +7970,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
ASSERT(isolate->heap()->IsAllocationAllowed());
- int jsframes = deoptimizer->jsframe_count();
+ JavaScriptFrameIterator it(isolate);
- deoptimizer->MaterializeHeapNumbers();
+ // Make sure to materialize objects before causing any allocation.
+ deoptimizer->MaterializeHeapObjects(&it);
delete deoptimizer;
- JavaScriptFrameIterator it(isolate);
- for (int i = 0; i < jsframes - 1; i++) {
- MaterializeArgumentsObjectInFrame(isolate, it.frame());
- it.Advance();
- }
-
JavaScriptFrame* frame = it.frame();
RUNTIME_ASSERT(frame->function()->IsJSFunction());
Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
- MaterializeArgumentsObjectInFrame(isolate, frame);
-
- if (type == Deoptimizer::EAGER) {
- RUNTIME_ASSERT(function->IsOptimized());
- }
+ RUNTIME_ASSERT(type != Deoptimizer::EAGER || function->IsOptimized());
// Avoid doing too much work when running with --always-opt and keep
// the optimized code around.
@@ -8349,11 +7987,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
return isolate->heap()->undefined_value();
}
- // Find other optimized activations of the function.
+ // Find other optimized activations of the function or functions that
+ // share the same optimized code.
bool has_other_activations = false;
while (!it.done()) {
JavaScriptFrame* frame = it.frame();
- if (frame->is_optimized() && frame->function() == *function) {
+ JSFunction* other_function = JSFunction::cast(frame->function());
+ if (frame->is_optimized() && other_function->code() == function->code()) {
has_other_activations = true;
break;
}
@@ -8376,6 +8016,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
} else {
Deoptimizer::DeoptimizeFunction(*function);
}
+ // Flush optimized code cache for this function.
+ function->shared()->ClearOptimizedCodeMap();
+
return isolate->heap()->undefined_value();
}
@@ -8452,6 +8095,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
return Smi::FromInt(4); // 4 == "never".
}
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+ if (FLAG_parallel_recompilation) {
+ if (function->IsMarkedForLazyRecompilation()) {
+ return Smi::FromInt(5);
+ }
+ }
if (FLAG_always_opt) {
// We may have always opt, but that is more best-effort than a real
// promise, so we still say "no" if it is not optimized.
@@ -8498,7 +8146,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
}
}
- int ast_id = AstNode::kNoNumber;
+ BailoutId ast_id = BailoutId::None();
if (succeeded) {
// The top JS function is this one, the PC is somewhere in the
// unoptimized code.
@@ -8519,14 +8167,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
// Table entries are (AST id, pc offset) pairs.
uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize);
if (pc_offset == target_pc_offset) {
- ast_id = static_cast<int>(Memory::uint32_at(table_cursor));
+ ast_id = BailoutId(static_cast<int>(Memory::uint32_at(table_cursor)));
break;
}
table_cursor += 2 * kIntSize;
}
- ASSERT(ast_id != AstNode::kNoNumber);
+ ASSERT(!ast_id.IsNone());
if (FLAG_trace_osr) {
- PrintF("[replacing on-stack at AST id %d in ", ast_id);
+ PrintF("[replacing on-stack at AST id %d in ", ast_id.ToInt());
function->PrintName();
PrintF("]\n");
}
@@ -8543,7 +8191,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
PrintF("[on-stack replacement offset %d in optimized code]\n",
data->OsrPcOffset()->value());
}
- ASSERT(data->OsrAstId()->value() == ast_id);
+ ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
} else {
// We may never generate the desired OSR entry if we emit an
// early deoptimize.
@@ -8582,7 +8230,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
// frame to an optimized one.
if (succeeded) {
ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
- return Smi::FromInt(ast_id);
+ return Smi::FromInt(ast_id.ToInt());
} else {
if (function->IsMarkedForLazyRecompilation()) {
function->ReplaceCode(function->shared()->code());
@@ -8691,19 +8339,38 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NewGlobalContext) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 2);
+
+ CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_CHECKED(ScopeInfo, scope_info, 1);
+ Context* result;
+ MaybeObject* maybe_result =
+ isolate->heap()->AllocateGlobalContext(function, scope_info);
+ if (!maybe_result->To(&result)) return maybe_result;
+
+ ASSERT(function->context() == isolate->context());
+ ASSERT(function->context()->global_object() == result->global_object());
+ isolate->set_context(result);
+ result->global_object()->set_global_context(result);
+
+ return result; // non-failure
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, function, 0);
int length = function->shared()->scope_info()->ContextLength();
- Object* result;
- { MaybeObject* maybe_result =
- isolate->heap()->AllocateFunctionContext(length, function);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ Context* result;
+ MaybeObject* maybe_result =
+ isolate->heap()->AllocateFunctionContext(length, function);
+ if (!maybe_result->To(&result)) return maybe_result;
- isolate->set_context(Context::cast(result));
+ isolate->set_context(result);
return result; // non-failure
}
@@ -8736,8 +8403,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
if (args[1]->IsSmi()) {
// A smi sentinel indicates a context nested inside global code rather
// than some function. There is a canonical empty function that can be
- // gotten from the global context.
- function = isolate->context()->global_context()->closure();
+ // gotten from the native context.
+ function = isolate->context()->native_context()->closure();
} else {
function = JSFunction::cast(args[1]);
}
@@ -8762,8 +8429,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
if (args[2]->IsSmi()) {
// A smi sentinel indicates a context nested inside global code rather
// than some function. There is a canonical empty function that can be
- // gotten from the global context.
- function = isolate->context()->global_context()->closure();
+ // gotten from the native context.
+ function = isolate->context()->native_context()->closure();
} else {
function = JSFunction::cast(args[2]);
}
@@ -8787,8 +8454,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
if (args[1]->IsSmi()) {
// A smi sentinel indicates a context nested inside global code rather
// than some function. There is a canonical empty function that can be
- // gotten from the global context.
- function = isolate->context()->global_context()->closure();
+ // gotten from the native context.
+ function = isolate->context()->native_context()->closure();
} else {
function = JSFunction::cast(args[1]);
}
@@ -8803,19 +8470,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSModule) {
+ ASSERT(args.length() == 1);
+ Object* obj = args[0];
+ return isolate->heap()->ToBoolean(obj->IsJSModule());
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_PushModuleContext) {
NoHandleAllocation ha;
- ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(ScopeInfo, scope_info, 0);
- CONVERT_ARG_HANDLE_CHECKED(JSModule, instance, 1);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSModule, instance, 0);
- Context* context;
- MaybeObject* maybe_context =
- isolate->heap()->AllocateModuleContext(isolate->context(),
- scope_info);
- if (!maybe_context->To(&context)) return maybe_context;
- // Also initialize the context slot of the instance object.
- instance->set_context(context);
+ Context* context = Context::cast(instance->context());
+ Context* previous = isolate->context();
+ ASSERT(context->IsModuleContext());
+ // Initialize the context links.
+ context->set_previous(previous);
+ context->set_closure(previous->closure());
+ context->set_global_object(previous->global_object());
isolate->set_context(context);
return context;
@@ -8901,7 +8574,7 @@ static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
Context* top = isolate->context();
// Get the context extension function.
JSFunction* context_extension_function =
- top->global_context()->context_extension_function();
+ top->native_context()->context_extension_function();
// If the holder isn't a context extension object, we just return it
// as the receiver. This allows arguments objects to be used as
// receivers, but only if they are put in the context scope chain
@@ -9080,7 +8753,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
}
// In non-strict mode, the property is added to the global object.
attributes = NONE;
- object = Handle<JSObject>(isolate->context()->global());
+ object = Handle<JSObject>(isolate->context()->global_object());
}
// Set the property if it's not read only or doesn't yet exist.
@@ -9134,6 +8807,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowReferenceError) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowNotDateError) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 0);
+ return isolate->Throw(*isolate->factory()->NewTypeError(
+ "not_date_object", HandleVector<Object>(NULL, 0)));
+}
+
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_StackGuard) {
ASSERT(args.length() == 0);
@@ -9323,7 +9005,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
ASSERT_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
- Zone* zone = isolate->zone();
+ Zone* zone = isolate->runtime_zone();
source = Handle<String>(source->TryFlattenGetString());
// Optimized fast case where we only have ASCII characters.
Handle<Object> result;
@@ -9363,18 +9045,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
ASSERT_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
- // Extract global context.
- Handle<Context> context(isolate->context()->global_context());
+ // Extract native context.
+ Handle<Context> context(isolate->context()->native_context());
- // Check if global context allows code generation from
+ // Check if native context allows code generation from
// strings. Throw an exception if it doesn't.
if (context->allow_code_gen_from_strings()->IsFalse() &&
!CodeGenerationFromStringsAllowed(isolate, context)) {
- return isolate->Throw(*isolate->factory()->NewError(
- "code_gen_from_strings", HandleVector<Object>(NULL, 0)));
+ Handle<Object> error_message =
+ context->ErrorMessageForCodeGenerationFromStrings();
+ return isolate->Throw(*isolate->factory()->NewEvalError(
+ "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
}
- // Compile source string in the global context.
+ // Compile source string in the native context.
Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
source, context, true, CLASSIC_MODE, RelocInfo::kNoPosition);
if (shared.is_null()) return Failure::Exception();
@@ -9392,14 +9076,16 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
LanguageMode language_mode,
int scope_position) {
Handle<Context> context = Handle<Context>(isolate->context());
- Handle<Context> global_context = Handle<Context>(context->global_context());
+ Handle<Context> native_context = Handle<Context>(context->native_context());
- // Check if global context allows code generation from
+ // Check if native context allows code generation from
// strings. Throw an exception if it doesn't.
- if (global_context->allow_code_gen_from_strings()->IsFalse() &&
- !CodeGenerationFromStringsAllowed(isolate, global_context)) {
- isolate->Throw(*isolate->factory()->NewError(
- "code_gen_from_strings", HandleVector<Object>(NULL, 0)));
+ if (native_context->allow_code_gen_from_strings()->IsFalse() &&
+ !CodeGenerationFromStringsAllowed(isolate, native_context)) {
+ Handle<Object> error_message =
+ native_context->ErrorMessageForCodeGenerationFromStrings();
+ isolate->Throw(*isolate->factory()->NewEvalError(
+ "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
return MakePair(Failure::Exception(), NULL);
}
@@ -9408,7 +9094,7 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
source,
Handle<Context>(isolate->context()),
- context->IsGlobalContext(),
+ context->IsNativeContext(),
language_mode,
scope_position);
if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
@@ -9430,7 +9116,7 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
// (And even if it is, but the first argument isn't a string, just let
// execution default to an indirect call to eval, which will also return
// the first argument without doing anything).
- if (*callee != isolate->global_context()->global_eval_fun() ||
+ if (*callee != isolate->native_context()->global_eval_fun() ||
!args[1]->IsString()) {
return MakePair(*callee, isolate->heap()->the_hole_value());
}
@@ -10203,11 +9889,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
CONVERT_ARG_CHECKED(String, name, 1);
CONVERT_SMI_ARG_CHECKED(flag, 2);
AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
- return obj->LookupAccessor(name, component);
+ if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
+ return JSObject::cast(receiver)->LookupAccessor(name, component);
}
@@ -10298,11 +9985,10 @@ static MaybeObject* DebugLookupResultValue(Heap* heap,
}
}
case INTERCEPTOR:
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
+ case TRANSITION:
return heap->undefined_value();
case HANDLER:
+ case NONEXISTENT:
UNREACHABLE();
return heap->undefined_value();
}
@@ -10335,7 +10021,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
// entered (if the debugger is entered). The reason for switching context here
// is that for some property lookups (accessors and interceptors) callbacks
// into the embedding application can occour, and the embedding application
- // could have the assumption that its own global context is the current
+ // could have the assumption that its own native context is the current
// context and not some internal debugger context.
SaveContext save(isolate);
if (isolate->debug()->InDebugger()) {
@@ -10374,13 +10060,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
for (int i = 0; i < length; i++) {
LookupResult result(isolate);
jsproto->LocalLookup(*name, &result);
- if (result.IsProperty()) {
+ if (result.IsFound()) {
// LookupResult is not GC safe as it holds raw object pointers.
// GC can happen later in this code so put the required fields into
// local variables using handles when required for later use.
- PropertyType result_type = result.type();
Handle<Object> result_callback_obj;
- if (result_type == CALLBACKS) {
+ if (result.IsPropertyCallbacks()) {
result_callback_obj = Handle<Object>(result.GetCallbackObject(),
isolate);
}
@@ -10398,7 +10083,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
// If the callback object is a fixed array then it contains JavaScript
// getter and/or setter.
- bool hasJavaScriptAccessors = result_type == CALLBACKS &&
+ bool hasJavaScriptAccessors = result.IsPropertyCallbacks() &&
result_callback_obj->IsAccessorPair();
Handle<FixedArray> details =
isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
@@ -10432,7 +10117,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) {
LookupResult result(isolate);
obj->Lookup(*name, &result);
- if (result.IsProperty()) {
+ if (result.IsFound()) {
return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL);
}
return isolate->heap()->undefined_value();
@@ -10462,7 +10147,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyAttributesFromDetails) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyIndexFromDetails) {
ASSERT(args.length() == 1);
CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
- return Smi::FromInt(details.index());
+ // TODO(verwaest): Depends on the type of details.
+ return Smi::FromInt(details.dictionary_index());
}
@@ -10881,12 +10567,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
// value object is not converted into a wrapped JS objects. To
// hide this optimization from the debugger, we wrap the receiver
// by creating correct wrapper object based on the calling frame's
- // global context.
+ // native context.
it.Advance();
- Handle<Context> calling_frames_global_context(
- Context::cast(Context::cast(it.frame()->context())->global_context()));
+ Handle<Context> calling_frames_native_context(
+ Context::cast(Context::cast(it.frame()->context())->native_context()));
receiver =
- isolate->factory()->ToObject(receiver, calling_frames_global_context);
+ isolate->factory()->ToObject(receiver, calling_frames_native_context);
}
details->set(kFrameDetailsReceiverIndex, *receiver);
@@ -10978,7 +10664,7 @@ static Handle<JSObject> MaterializeLocalScopeWithFrameInspector(
// These will be variables introduced by eval.
if (function_context->closure() == *function) {
if (function_context->has_extension() &&
- !function_context->IsGlobalContext()) {
+ !function_context->IsNativeContext()) {
Handle<JSObject> ext(JSObject::cast(function_context->extension()));
bool threw = false;
Handle<FixedArray> keys =
@@ -11152,7 +10838,8 @@ class ScopeIterator {
inlined_jsframe_index_(inlined_jsframe_index),
function_(JSFunction::cast(frame->function())),
context_(Context::cast(frame->context())),
- nested_scope_chain_(4) {
+ nested_scope_chain_(4),
+ failed_(false) {
// Catch the case when the debugger stops in an internal function.
Handle<SharedFunctionInfo> shared_info(function_->shared());
@@ -11165,7 +10852,7 @@ class ScopeIterator {
}
// Get the debug info (create it if it does not exist).
- if (!isolate->debug()->EnsureDebugInfo(shared_info)) {
+ if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
// Return if ensuring debug info failed.
return;
}
@@ -11190,7 +10877,6 @@ class ScopeIterator {
if (scope_info->Type() != EVAL_SCOPE) nested_scope_chain_.Add(scope_info);
} else {
// Reparse the code and analyze the scopes.
- ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
Handle<Script> script(Script::cast(shared_info->script()));
Scope* scope = NULL;
@@ -11198,36 +10884,25 @@ class ScopeIterator {
Handle<ScopeInfo> scope_info(shared_info->scope_info());
if (scope_info->Type() != FUNCTION_SCOPE) {
// Global or eval code.
- CompilationInfo info(script);
+ CompilationInfoWithZone info(script);
if (scope_info->Type() == GLOBAL_SCOPE) {
info.MarkAsGlobal();
} else {
ASSERT(scope_info->Type() == EVAL_SCOPE);
info.MarkAsEval();
- info.SetCallingContext(Handle<Context>(function_->context()));
+ info.SetContext(Handle<Context>(function_->context()));
}
if (ParserApi::Parse(&info, kNoParsingFlags) && Scope::Analyze(&info)) {
scope = info.function()->scope();
}
+ RetrieveScopeChain(scope, shared_info);
} else {
// Function code
- CompilationInfo info(shared_info);
+ CompilationInfoWithZone info(shared_info);
if (ParserApi::Parse(&info, kNoParsingFlags) && Scope::Analyze(&info)) {
scope = info.function()->scope();
}
- }
-
- // Retrieve the scope chain for the current position.
- if (scope != NULL) {
- int source_position = shared_info->code()->SourcePosition(frame_->pc());
- scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
- } else {
- // A failed reparse indicates that the preparser has diverged from the
- // parser or that the preparse data given to the initial parse has been
- // faulty. We fail in debug mode but in release mode we only provide the
- // information we get from the context chain but nothing about
- // completely stack allocated scopes or stack allocated locals.
- UNREACHABLE();
+ RetrieveScopeChain(scope, shared_info);
}
}
}
@@ -11238,21 +10913,28 @@ class ScopeIterator {
frame_(NULL),
inlined_jsframe_index_(0),
function_(function),
- context_(function->context()) {
+ context_(function->context()),
+ failed_(false) {
if (function->IsBuiltin()) {
context_ = Handle<Context>();
}
}
// More scopes?
- bool Done() { return context_.is_null(); }
+ bool Done() {
+ ASSERT(!failed_);
+ return context_.is_null();
+ }
+
+ bool Failed() { return failed_; }
// Move to the next scope.
void Next() {
+ ASSERT(!failed_);
ScopeType scope_type = Type();
if (scope_type == ScopeTypeGlobal) {
// The global scope is always the last in the chain.
- ASSERT(context_->IsGlobalContext());
+ ASSERT(context_->IsNativeContext());
context_ = Handle<Context>();
return;
}
@@ -11269,6 +10951,7 @@ class ScopeIterator {
// Return the type of the current scope.
ScopeType Type() {
+ ASSERT(!failed_);
if (!nested_scope_chain_.is_empty()) {
Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
switch (scope_info->Type()) {
@@ -11280,7 +10963,7 @@ class ScopeIterator {
ASSERT(context_->IsModuleContext());
return ScopeTypeModule;
case GLOBAL_SCOPE:
- ASSERT(context_->IsGlobalContext());
+ ASSERT(context_->IsNativeContext());
return ScopeTypeGlobal;
case WITH_SCOPE:
ASSERT(context_->IsWithContext());
@@ -11296,8 +10979,8 @@ class ScopeIterator {
UNREACHABLE();
}
}
- if (context_->IsGlobalContext()) {
- ASSERT(context_->global()->IsGlobalObject());
+ if (context_->IsNativeContext()) {
+ ASSERT(context_->global_object()->IsGlobalObject());
return ScopeTypeGlobal;
}
if (context_->IsFunctionContext()) {
@@ -11318,9 +11001,10 @@ class ScopeIterator {
// Return the JavaScript object with the content of the current scope.
Handle<JSObject> ScopeObject() {
+ ASSERT(!failed_);
switch (Type()) {
case ScopeIterator::ScopeTypeGlobal:
- return Handle<JSObject>(CurrentContext()->global());
+ return Handle<JSObject>(CurrentContext()->global_object());
case ScopeIterator::ScopeTypeLocal:
// Materialize the content of the local scope into a JSObject.
ASSERT(nested_scope_chain_.length() == 1);
@@ -11343,6 +11027,7 @@ class ScopeIterator {
}
Handle<ScopeInfo> CurrentScopeInfo() {
+ ASSERT(!failed_);
if (!nested_scope_chain_.is_empty()) {
return nested_scope_chain_.last();
} else if (context_->IsBlockContext()) {
@@ -11356,6 +11041,7 @@ class ScopeIterator {
// Return the context for this scope. For the local context there might not
// be an actual context.
Handle<Context> CurrentContext() {
+ ASSERT(!failed_);
if (Type() == ScopeTypeGlobal ||
nested_scope_chain_.is_empty()) {
return context_;
@@ -11369,6 +11055,7 @@ class ScopeIterator {
#ifdef DEBUG
// Debug print of the content of the current scope.
void DebugPrint() {
+ ASSERT(!failed_);
switch (Type()) {
case ScopeIterator::ScopeTypeGlobal:
PrintF("Global:\n");
@@ -11426,6 +11113,24 @@ class ScopeIterator {
Handle<JSFunction> function_;
Handle<Context> context_;
List<Handle<ScopeInfo> > nested_scope_chain_;
+ bool failed_;
+
+ void RetrieveScopeChain(Scope* scope,
+ Handle<SharedFunctionInfo> shared_info) {
+ if (scope != NULL) {
+ int source_position = shared_info->code()->SourcePosition(frame_->pc());
+ scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
+ } else {
+ // A failed reparse indicates that the preparser has diverged from the
+ // parser or that the preparse data given to the initial parse has been
+ // faulty. We fail in debug mode but in release mode we only provide the
+ // information we get from the context chain but nothing about
+ // completely stack allocated scopes or stack allocated locals.
+ // Or it could be due to stack overflow.
+ ASSERT(isolate_->has_pending_exception());
+ failed_ = true;
+ }
+ }
DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
};
@@ -11688,110 +11393,26 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetBreakLocations) {
}
-// Set a break point in a function
+// Set a break point in a function.
// args[0]: function
// args[1]: number: break source position (within the function source)
// args[2]: number: break point object
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
- Handle<SharedFunctionInfo> shared(fun->shared());
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= 0);
Handle<Object> break_point_object_arg = args.at<Object>(2);
// Set break point.
- isolate->debug()->SetBreakPoint(shared, break_point_object_arg,
+ isolate->debug()->SetBreakPoint(function, break_point_object_arg,
&source_position);
return Smi::FromInt(source_position);
}
-Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate,
- Handle<Script> script,
- int position) {
- // Iterate the heap looking for SharedFunctionInfo generated from the
- // script. The inner most SharedFunctionInfo containing the source position
- // for the requested break point is found.
- // NOTE: This might require several heap iterations. If the SharedFunctionInfo
- // which is found is not compiled it is compiled and the heap is iterated
- // again as the compilation might create inner functions from the newly
- // compiled function and the actual requested break point might be in one of
- // these functions.
- bool done = false;
- // The current candidate for the source position:
- int target_start_position = RelocInfo::kNoPosition;
- Handle<SharedFunctionInfo> target;
- while (!done) {
- { // Extra scope for iterator and no-allocation.
- isolate->heap()->EnsureHeapIsIterable();
- AssertNoAllocation no_alloc_during_heap_iteration;
- HeapIterator iterator;
- for (HeapObject* obj = iterator.next();
- obj != NULL; obj = iterator.next()) {
- if (obj->IsSharedFunctionInfo()) {
- Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj));
- if (shared->script() == *script) {
- // If the SharedFunctionInfo found has the requested script data and
- // contains the source position it is a candidate.
- int start_position = shared->function_token_position();
- if (start_position == RelocInfo::kNoPosition) {
- start_position = shared->start_position();
- }
- if (start_position <= position &&
- position <= shared->end_position()) {
- // If there is no candidate or this function is within the current
- // candidate this is the new candidate.
- if (target.is_null()) {
- target_start_position = start_position;
- target = shared;
- } else {
- if (target_start_position == start_position &&
- shared->end_position() == target->end_position()) {
- // If a top-level function contain only one function
- // declartion the source for the top-level and the
- // function is the same. In that case prefer the non
- // top-level function.
- if (!shared->is_toplevel()) {
- target_start_position = start_position;
- target = shared;
- }
- } else if (target_start_position <= start_position &&
- shared->end_position() <= target->end_position()) {
- // This containment check includes equality as a function
- // inside a top-level function can share either start or end
- // position with the top-level function.
- target_start_position = start_position;
- target = shared;
- }
- }
- }
- }
- }
- } // End for loop.
- } // End No allocation scope.
-
- if (target.is_null()) {
- return isolate->heap()->undefined_value();
- }
-
- // If the candidate found is compiled we are done. NOTE: when lazy
- // compilation of inner functions is introduced some additional checking
- // needs to be done here to compile inner functions.
- done = target->is_compiled();
- if (!done) {
- // If the candidate is not compiled compile it to reveal any inner
- // functions which might contain the requested source position.
- SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION);
- }
- } // End while loop.
-
- return *target;
-}
-
-
// Changes the state of a break point in a script and returns source position
// where break point was set. NOTE: Regarding performance see the NOTE for
// GetScriptFromScriptData.
@@ -11810,23 +11431,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {
RUNTIME_ASSERT(wrapper->value()->IsScript());
Handle<Script> script(Script::cast(wrapper->value()));
- Object* result = Runtime::FindSharedFunctionInfoInScript(
- isolate, script, source_position);
- if (!result->IsUndefined()) {
- Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result));
- // Find position within function. The script position might be before the
- // source position of the first function.
- int position;
- if (shared->start_position() > source_position) {
- position = 0;
- } else {
- position = source_position - shared->start_position();
- }
- isolate->debug()->SetBreakPoint(shared, break_point_object_arg, &position);
- position += shared->start_position();
- return Smi::FromInt(position);
+ // Set break point.
+ if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
+ &source_position)) {
+ return isolate->heap()->undefined_value();
}
- return isolate->heap()->undefined_value();
+
+ return Smi::FromInt(source_position);
}
@@ -11942,6 +11553,8 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
List<Handle<Context> > context_chain;
ScopeIterator it(isolate, frame, inlined_jsframe_index);
+ if (it.Failed()) return Handle<Context>::null();
+
for (; it.Type() != ScopeIterator::ScopeTypeGlobal &&
it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) {
ASSERT(!it.Done());
@@ -11970,9 +11583,7 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
// Materialize the contents of the block scope into a JSObject.
Handle<JSObject> block_scope_object =
MaterializeBlockScope(isolate, current);
- if (block_scope_object.is_null()) {
- return Handle<Context>::null();
- }
+ CHECK(!block_scope_object.is_null());
// Allocate a new function context for the debug evaluation and set the
// extension object.
Handle<Context> new_context =
@@ -12116,7 +11727,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
Handle<Context> context =
isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS,
go_between);
- context->set_extension(*local_scope);
+
+ // Use the materialized local scope in a with context.
+ context =
+ isolate->factory()->NewWithContext(go_between, context, local_scope);
+
// Copy any with contexts present and chain them in front of this context.
Handle<Context> frame_context(Context::cast(frame->context()));
Handle<Context> function_context;
@@ -12129,6 +11744,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
context,
frame,
inlined_jsframe_index);
+ if (context.is_null()) {
+ ASSERT(isolate->has_pending_exception());
+ MaybeObject* exception = isolate->pending_exception();
+ isolate->clear_pending_exception();
+ return exception;
+ }
if (additional_context->IsJSObject()) {
Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
@@ -12151,7 +11772,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
Handle<SharedFunctionInfo> shared =
Compiler::CompileEval(function_source,
context,
- context->IsGlobalContext(),
+ context->IsNativeContext(),
CLASSIC_MODE,
RelocInfo::kNoPosition);
if (shared.is_null()) return Failure::Exception();
@@ -12172,6 +11793,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
scope_info,
function_context);
+ // Check if eval is blocked in the context and temporarily allow it
+ // for debugger.
+ Handle<Context> native_context = Handle<Context>(context->native_context());
+ bool eval_disabled =
+ native_context->allow_code_gen_from_strings()->IsFalse();
+ if (eval_disabled) {
+ native_context->set_allow_code_gen_from_strings(
+ isolate->heap()->true_value());
+ }
// Invoke the evaluation function and return the result.
Handle<Object> argv[] = { arguments, source };
Handle<Object> result =
@@ -12180,6 +11810,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
ARRAY_SIZE(argv),
argv,
&has_pending_exception);
+ if (eval_disabled) {
+ native_context->set_allow_code_gen_from_strings(
+ isolate->heap()->false_value());
+ }
if (has_pending_exception) return Failure::Exception();
// Skip the global proxy as it has no properties and always delegates to the
@@ -12222,9 +11856,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
isolate->set_context(*top->context());
}
- // Get the global context now set to the top context from before the
+ // Get the native context now set to the top context from before the
// debugger was invoked.
- Handle<Context> context = isolate->global_context();
+ Handle<Context> context = isolate->native_context();
bool is_global = true;
@@ -12255,7 +11889,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
// Invoke the result of the compilation to get the evaluation function.
bool has_pending_exception;
- Handle<Object> receiver = isolate->global();
+ Handle<Object> receiver = isolate->global_object();
Handle<Object> result =
Execution::Call(compiled_function, receiver, 0, NULL,
&has_pending_exception);
@@ -12389,7 +12023,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
// Get the constructor function for context extension and arguments array.
JSObject* arguments_boilerplate =
- isolate->context()->global_context()->arguments_boilerplate();
+ isolate->context()->native_context()->arguments_boilerplate();
JSFunction* arguments_function =
JSFunction::cast(arguments_boilerplate->map()->constructor());
@@ -12418,7 +12052,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
// Return result as JS array.
Object* result;
MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
- isolate->context()->global_context()->array_function());
+ isolate->context()->native_context()->array_function());
if (!maybe_result->ToObject(&result)) return maybe_result;
return JSArray::cast(result)->SetContent(instances);
}
@@ -12499,7 +12133,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
// Return result as JS array.
Object* result;
{ MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
- isolate->context()->global_context()->array_function());
+ isolate->context()->native_context()->array_function());
if (!maybe_result->ToObject(&result)) return maybe_result;
}
return JSArray::cast(result)->SetContent(instances);
@@ -12524,7 +12158,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugSetScriptSource) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
- Handle<String> source(String::cast(args[1]));
+ CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
RUNTIME_ASSERT(script_wrapper->value()->IsScript());
Handle<Script> script(Script::cast(script_wrapper->value()));
@@ -12550,7 +12184,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) {
ASSERT(args.length() == 1);
// Get the function and make sure it is compiled.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
- if (!JSFunction::CompileLazy(func, KEEP_EXCEPTION)) {
+ if (!JSFunction::EnsureCompiled(func, KEEP_EXCEPTION)) {
return Failure::Exception();
}
func->code()->PrintLn();
@@ -12565,7 +12199,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) {
ASSERT(args.length() == 1);
// Get the function and make sure it is compiled.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
- if (!JSFunction::CompileLazy(func, KEEP_EXCEPTION)) {
+ if (!JSFunction::EnsureCompiled(func, KEEP_EXCEPTION)) {
return Failure::Exception();
}
func->shared()->construct_stub()->PrintLn();
@@ -12613,11 +12247,12 @@ static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
// in OpaqueReferences.
RUNTIME_FUNCTION(MaybeObject*,
Runtime_LiveEditFindSharedFunctionInfosForScript) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 1);
HandleScope scope(isolate);
CONVERT_ARG_CHECKED(JSValue, script_value, 0);
-
+ RUNTIME_ASSERT(script_value->value()->IsScript());
Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
const int kBufferSize = 32;
@@ -12659,10 +12294,13 @@ RUNTIME_FUNCTION(MaybeObject*,
// each function with all its descendant is always stored in a continues range
// with the function itself going first. The root function is a script function.
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditGatherCompileInfo) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
HandleScope scope(isolate);
CONVERT_ARG_CHECKED(JSValue, script, 0);
CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
+
+ RUNTIME_ASSERT(script->value()->IsScript());
Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source);
@@ -12678,6 +12316,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditGatherCompileInfo) {
// If old_script_name is provided (i.e. is a String), also creates a copy of
// the script with its original source and sends notification to debugger.
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceScript) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 3);
HandleScope scope(isolate);
CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
@@ -12701,6 +12340,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceScript) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSourceUpdated) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 1);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
@@ -12710,6 +12350,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSourceUpdated) {
// Replaces code of SharedFunctionInfo with a new one.
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceFunctionCode) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
@@ -12720,6 +12361,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceFunctionCode) {
// Connects SharedFunctionInfo to another script.
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSetScript) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
HandleScope scope(isolate);
Handle<Object> function_object(args[0], isolate);
@@ -12746,6 +12388,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSetScript) {
// In a code of a parent function replaces original function as embedded object
// with a substitution one.
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceRefToNestedFunction) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 3);
HandleScope scope(isolate);
@@ -12766,6 +12409,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceRefToNestedFunction) {
// (change_begin, change_end, change_end_new_position).
// Each group describes a change in text; groups are sorted by change_begin.
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditPatchFunctionPositions) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
@@ -12780,19 +12424,21 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditPatchFunctionPositions) {
// Returns array of the same length with corresponding results of
// LiveEdit::FunctionPatchabilityStatus type.
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
return *LiveEdit::CheckAndDropActivations(shared_array, do_drop,
- isolate->zone());
+ isolate->runtime_zone());
}
// Compares 2 strings line-by-line, then token-wise and returns diff in form
// of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
// of diff chunks.
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
@@ -12802,9 +12448,50 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) {
}
+// Restarts a call frame and completely drops all frames above.
+// Returns true if successful. Otherwise returns undefined or an error message.
+RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditRestartFrame) {
+ CHECK(isolate->debugger()->live_edit_enabled());
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+
+ // Check arguments.
+ Object* check;
+ { MaybeObject* maybe_check = Runtime_CheckExecutionState(
+ RUNTIME_ARGUMENTS(isolate, args));
+ if (!maybe_check->ToObject(&check)) return maybe_check;
+ }
+ CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
+ Heap* heap = isolate->heap();
+
+ // Find the relevant frame with the requested index.
+ StackFrame::Id id = isolate->debug()->break_frame_id();
+ if (id == StackFrame::NO_ID) {
+ // If there are no JavaScript stack frames return undefined.
+ return heap->undefined_value();
+ }
+
+ int count = 0;
+ JavaScriptFrameIterator it(isolate, id);
+ for (; !it.done(); it.Advance()) {
+ if (index < count + it.frame()->GetInlineCount()) break;
+ count += it.frame()->GetInlineCount();
+ }
+ if (it.done()) return heap->undefined_value();
+
+ const char* error_message =
+ LiveEdit::RestartFrame(it.frame(), isolate->runtime_zone());
+ if (error_message) {
+ return *(isolate->factory()->LookupAsciiSymbol(error_message));
+ }
+ return heap->true_value();
+}
+
+
// A testing entry. Returns statement position which is the closest to
// source_position.
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionCodePositionFromSource) {
+ CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
@@ -12851,11 +12538,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ExecuteInDebugContext) {
bool pending_exception;
{
if (without_debugger) {
- result = Execution::Call(function, isolate->global(), 0, NULL,
+ result = Execution::Call(function, isolate->global_object(), 0, NULL,
&pending_exception);
} else {
EnterDebugger enter_debugger;
- result = Execution::Call(function, isolate->global(), 0, NULL,
+ result = Execution::Call(function, isolate->global_object(), 0, NULL,
&pending_exception);
}
}
@@ -13334,7 +13021,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
Handle<JSFunction> factory(JSFunction::cast(
cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
// TODO(antonm): consider passing a receiver when constructing a cache.
- Handle<Object> receiver(isolate->global_context()->global());
+ Handle<Object> receiver(isolate->native_context()->global_object());
// This handle is nor shared, nor used later, so it's safe.
Handle<Object> argv[] = { key_handle };
bool pending_exception;
@@ -13346,7 +13033,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
if (pending_exception) return Failure::Exception();
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
cache_handle->JSFunctionResultCacheVerify();
}
@@ -13377,7 +13064,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
cache_handle->set(index + 1, *value);
cache_handle->set_finger_index(index);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
cache_handle->JSFunctionResultCacheVerify();
}
diff --git a/deps/v8/src/runtime.h b/deps/v8/src/runtime.h
index f5a4f5020..c9939d06c 100644
--- a/deps/v8/src/runtime.h
+++ b/deps/v8/src/runtime.h
@@ -62,7 +62,6 @@ namespace internal {
F(GetIndexedInterceptorElementNames, 1, 1) \
F(GetArgumentsProperty, 1, 1) \
F(ToFastProperties, 1, 1) \
- F(ToSlowProperties, 1, 1) \
F(FinishArrayPrototypeSetup, 1, 1) \
F(SpecialArrayFunctions, 1, 1) \
F(GetDefaultReceiver, 1, 1) \
@@ -86,6 +85,7 @@ namespace internal {
F(NewStrictArgumentsFast, 3, 1) \
F(LazyCompile, 1, 1) \
F(LazyRecompile, 1, 1) \
+ F(ParallelRecompile, 1, 1) \
F(NotifyDeoptimized, 1, 1) \
F(NotifyOSR, 0, 1) \
F(DeoptimizeFunction, 1, 1) \
@@ -283,6 +283,9 @@ namespace internal {
F(CreateArrayLiteral, 3, 1) \
F(CreateArrayLiteralShallow, 3, 1) \
\
+ /* Harmony modules */ \
+ F(IsJSModule, 1, 1) \
+ \
/* Harmony proxies */ \
F(CreateJSProxy, 2, 1) \
F(CreateJSFunctionProxy, 4, 1) \
@@ -302,11 +305,15 @@ namespace internal {
/* Harmony maps */ \
F(MapInitialize, 1, 1) \
F(MapGet, 2, 1) \
+ F(MapHas, 2, 1) \
+ F(MapDelete, 2, 1) \
F(MapSet, 3, 1) \
\
/* Harmony weakmaps */ \
F(WeakMapInitialize, 1, 1) \
F(WeakMapGet, 2, 1) \
+ F(WeakMapHas, 2, 1) \
+ F(WeakMapDelete, 2, 1) \
F(WeakMapSet, 3, 1) \
\
/* Statements */ \
@@ -317,16 +324,18 @@ namespace internal {
F(Throw, 1, 1) \
F(ReThrow, 1, 1) \
F(ThrowReferenceError, 1, 1) \
+ F(ThrowNotDateError, 0, 1) \
F(StackGuard, 0, 1) \
F(Interrupt, 0, 1) \
F(PromoteScheduledException, 0, 1) \
\
/* Contexts */ \
+ F(NewGlobalContext, 2, 1) \
F(NewFunctionContext, 1, 1) \
F(PushWithContext, 2, 1) \
F(PushCatchContext, 3, 1) \
F(PushBlockContext, 2, 1) \
- F(PushModuleContext, 2, 1) \
+ F(PushModuleContext, 1, 1) \
F(DeleteContextSlot, 2, 1) \
F(LoadContextSlot, 2, 2) \
F(LoadContextSlotNoReferenceError, 2, 2) \
@@ -442,6 +451,7 @@ namespace internal {
F(LiveEditPatchFunctionPositions, 2, 1) \
F(LiveEditCheckAndDropActivations, 2, 1) \
F(LiveEditCompareStrings, 2, 1) \
+ F(LiveEditRestartFrame, 2, 1) \
F(GetFunctionCodePositionFromSource, 2, 1) \
F(ExecuteInDebugContext, 2, 1) \
\
@@ -637,13 +647,6 @@ class Runtime : public AllStatic {
// Get the intrinsic function with the given FunctionId.
static const Function* FunctionForId(FunctionId id);
- static Handle<String> StringReplaceOneCharWithString(Isolate* isolate,
- Handle<String> subject,
- Handle<String> search,
- Handle<String> replace,
- bool* found,
- int recursion_limit);
-
// General-purpose helper functions for runtime system.
static int StringMatch(Isolate* isolate,
Handle<String> sub,
@@ -686,11 +689,6 @@ class Runtime : public AllStatic {
Handle<Object> object,
Handle<Object> key);
- // This function is used in FunctionNameUsing* tests.
- static Object* FindSharedFunctionInfoInScript(Isolate* isolate,
- Handle<Script> script,
- int position);
-
// Helper functions used stubs.
static void PerformGC(Object* result);
diff --git a/deps/v8/src/scanner.cc b/deps/v8/src/scanner.cc
index f24af2ed2..bd2db5818 100755
--- a/deps/v8/src/scanner.cc
+++ b/deps/v8/src/scanner.cc
@@ -1077,6 +1077,7 @@ bool Scanner::ScanRegExpFlags() {
if (!ScanLiteralUnicodeEscape()) {
break;
}
+ Advance();
}
}
literal.Complete();
diff --git a/deps/v8/src/scopeinfo.cc b/deps/v8/src/scopeinfo.cc
index 25f02f632..02b432398 100644
--- a/deps/v8/src/scopeinfo.cc
+++ b/deps/v8/src/scopeinfo.cc
@@ -193,7 +193,8 @@ int ScopeInfo::ContextLength() {
bool has_context = context_locals > 0 ||
function_name_context_slot ||
Type() == WITH_SCOPE ||
- (Type() == FUNCTION_SCOPE && CallsEval());
+ (Type() == FUNCTION_SCOPE && CallsEval()) ||
+ Type() == MODULE_SCOPE;
if (has_context) {
return Context::MIN_CONTEXT_SLOTS + context_locals +
(function_name_context_slot ? 1 : 0);
@@ -222,11 +223,7 @@ bool ScopeInfo::HasHeapAllocatedLocals() {
bool ScopeInfo::HasContext() {
- if (length() > 0) {
- return ContextLength() > 0;
- } else {
- return false;
- }
+ return ContextLength() > 0;
}
diff --git a/deps/v8/src/scopes.cc b/deps/v8/src/scopes.cc
index ad6692e57..c9612577a 100644
--- a/deps/v8/src/scopes.cc
+++ b/deps/v8/src/scopes.cc
@@ -29,6 +29,7 @@
#include "scopes.h"
+#include "accessors.h"
#include "bootstrapper.h"
#include "compiler.h"
#include "messages.h"
@@ -117,10 +118,8 @@ Scope::Scope(Scope* outer_scope, ScopeType type, Zone* zone)
already_resolved_(false),
zone_(zone) {
SetDefaults(type, outer_scope, Handle<ScopeInfo>::null());
- // At some point we might want to provide outer scopes to
- // eval scopes (by walking the stack and reading the scope info).
- // In that case, the ASSERT below needs to be adjusted.
- ASSERT_EQ(type == GLOBAL_SCOPE, outer_scope == NULL);
+ // The outermost scope must be a global scope.
+ ASSERT(type == GLOBAL_SCOPE || outer_scope != NULL);
ASSERT(!HasIllegalRedeclaration());
}
@@ -214,7 +213,7 @@ Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope,
Scope* current_scope = NULL;
Scope* innermost_scope = NULL;
bool contains_with = false;
- while (!context->IsGlobalContext()) {
+ while (!context->IsNativeContext()) {
if (context->IsWithContext()) {
Scope* with_scope = new(zone) Scope(current_scope,
WITH_SCOPE,
@@ -226,6 +225,18 @@ Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope,
for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
s->scope_inside_with_ = true;
}
+ } else if (context->IsGlobalContext()) {
+ ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
+ current_scope = new(zone) Scope(current_scope,
+ GLOBAL_SCOPE,
+ Handle<ScopeInfo>(scope_info),
+ zone);
+ } else if (context->IsModuleContext()) {
+ ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info());
+ current_scope = new(zone) Scope(current_scope,
+ MODULE_SCOPE,
+ Handle<ScopeInfo>(scope_info),
+ zone);
} else if (context->IsFunctionContext()) {
ScopeInfo* scope_info = context->closure()->shared()->scope_info();
current_scope = new(zone) Scope(current_scope,
@@ -274,7 +285,8 @@ bool Scope::Analyze(CompilationInfo* info) {
// Allocate the variables.
{
- AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate());
+ AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate(),
+ info->zone());
if (!top->AllocateVariables(info, &ast_node_factory)) return false;
}
@@ -473,17 +485,14 @@ Variable* Scope::DeclareLocal(Handle<String> name,
// This function handles VAR and CONST modes. DYNAMIC variables are
// introduces during variable allocation, INTERNAL variables are allocated
// explicitly, and TEMPORARY variables are allocated via NewTemporary().
- ASSERT(mode == VAR ||
- mode == CONST ||
- mode == CONST_HARMONY ||
- mode == LET);
+ ASSERT(IsDeclaredVariableMode(mode));
++num_var_or_const_;
return variables_.Declare(
this, name, mode, true, Variable::NORMAL, init_flag, interface);
}
-Variable* Scope::DeclareGlobal(Handle<String> name) {
+Variable* Scope::DeclareDynamicGlobal(Handle<String> name) {
ASSERT(is_global_scope());
return variables_.Declare(this,
name,
@@ -586,6 +595,21 @@ VariableProxy* Scope::CheckAssignmentToConst() {
}
+class VarAndOrder {
+ public:
+ VarAndOrder(Variable* var, int order) : var_(var), order_(order) { }
+ Variable* var() const { return var_; }
+ int order() const { return order_; }
+ static int Compare(const VarAndOrder* a, const VarAndOrder* b) {
+ return a->order_ - b->order_;
+ }
+
+ private:
+ Variable* var_;
+ int order_;
+};
+
+
void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
ZoneList<Variable*>* context_locals) {
ASSERT(stack_locals != NULL);
@@ -600,17 +624,25 @@ void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
}
}
+ ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
+
// Collect declared local variables.
for (VariableMap::Entry* p = variables_.Start();
p != NULL;
p = variables_.Next(p)) {
Variable* var = reinterpret_cast<Variable*>(p->value);
if (var->is_used()) {
- if (var->IsStackLocal()) {
- stack_locals->Add(var, zone());
- } else if (var->IsContextSlot()) {
- context_locals->Add(var, zone());
- }
+ vars.Add(VarAndOrder(var, p->order), zone());
+ }
+ }
+ vars.Sort(VarAndOrder::Compare);
+ int var_count = vars.length();
+ for (int i = 0; i < var_count; i++) {
+ Variable* var = vars[i].var();
+ if (var->IsStackLocal()) {
+ stack_locals->Add(var, zone());
+ } else if (var->IsContextSlot()) {
+ context_locals->Add(var, zone());
}
}
}
@@ -633,12 +665,13 @@ bool Scope::AllocateVariables(CompilationInfo* info,
// 3) Allocate variables.
AllocateVariablesRecursively();
- return true;
-}
-
+ // 4) Allocate and link module instance objects.
+ if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) {
+ AllocateModules(info);
+ LinkModules(info);
+ }
-bool Scope::AllowsLazyCompilation() const {
- return !force_eager_compilation_ && HasTrivialOuterContext();
+ return true;
}
@@ -666,23 +699,36 @@ bool Scope::HasTrivialOuterContext() const {
}
-bool Scope::AllowsLazyRecompilation() const {
- return !force_eager_compilation_ &&
- !TrivialDeclarationScopesBeforeWithScope();
-}
-
-
-bool Scope::TrivialDeclarationScopesBeforeWithScope() const {
+bool Scope::HasLazyCompilableOuterContext() const {
Scope* outer = outer_scope_;
- if (outer == NULL) return false;
+ if (outer == NULL) return true;
+ // There are several reasons that prevent lazy compilation:
+ // - This scope is inside a with scope and all declaration scopes between
+ // them have empty contexts. Such declaration scopes become invisible
+ // during scope info deserialization.
+ // - This scope is inside a strict eval scope with variables that are
+ // potentially context allocated in an artificial function scope that
+ // is not deserialized correctly.
outer = outer->DeclarationScope();
- while (outer != NULL) {
- if (outer->is_with_scope()) return true;
- if (outer->is_declaration_scope() && outer->num_heap_slots() > 0)
- return false;
- outer = outer->outer_scope_;
+ bool found_non_trivial_declarations = false;
+ for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) {
+ if (scope->is_eval_scope()) return false;
+ if (scope->is_with_scope() && !found_non_trivial_declarations) return false;
+ if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) {
+ found_non_trivial_declarations = true;
+ }
}
- return false;
+ return true;
+}
+
+
+bool Scope::AllowsLazyCompilation() const {
+ return !force_eager_compilation_ && HasLazyCompilableOuterContext();
+}
+
+
+bool Scope::AllowsLazyCompilationWithoutContext() const {
+ return !force_eager_compilation_ && HasTrivialOuterContext();
}
@@ -990,7 +1036,7 @@ bool Scope::ResolveVariable(CompilationInfo* info,
// gave up on it (e.g. by encountering a local with the same in the outer
// scope which was not promoted to a context, this can happen if we use
// debugger to evaluate arbitrary expressions at a break point).
- if (var->is_global()) {
+ if (var->IsGlobalObjectProperty()) {
var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
} else if (var->is_dynamic()) {
var = NonLocal(proxy->name(), DYNAMIC);
@@ -1002,8 +1048,8 @@ bool Scope::ResolveVariable(CompilationInfo* info,
break;
case UNBOUND:
- // No binding has been found. Declare a variable in global scope.
- var = info->global_scope()->DeclareGlobal(proxy->name());
+ // No binding has been found. Declare a variable on the global object.
+ var = info->global_scope()->DeclareDynamicGlobal(proxy->name());
break;
case UNBOUND_EVAL_SHADOWED:
@@ -1110,11 +1156,13 @@ bool Scope::MustAllocate(Variable* var) {
inner_scope_calls_eval_ ||
scope_contains_with_ ||
is_catch_scope() ||
- is_block_scope())) {
+ is_block_scope() ||
+ is_module_scope() ||
+ is_global_scope())) {
var->set_is_used(true);
}
// Global variables do not need to be allocated.
- return !var->is_global() && var->is_used();
+ return !var->IsGlobalObjectProperty() && var->is_used();
}
@@ -1128,11 +1176,11 @@ bool Scope::MustAllocateInContext(Variable* var) {
// catch-bound variables are always allocated in a context.
if (var->mode() == TEMPORARY) return false;
if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
+ if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true;
return var->has_forced_context_allocation() ||
scope_calls_eval_ ||
inner_scope_calls_eval_ ||
- scope_contains_with_ ||
- var->is_global();
+ scope_contains_with_;
}
@@ -1233,11 +1281,19 @@ void Scope::AllocateNonParameterLocals() {
AllocateNonParameterLocal(temps_[i]);
}
+ ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
+
for (VariableMap::Entry* p = variables_.Start();
p != NULL;
p = variables_.Next(p)) {
Variable* var = reinterpret_cast<Variable*>(p->value);
- AllocateNonParameterLocal(var);
+ vars.Add(VarAndOrder(var, p->order), zone());
+ }
+
+ vars.Sort(VarAndOrder::Compare);
+ int var_count = vars.length();
+ for (int i = 0; i < var_count; i++) {
+ AllocateNonParameterLocal(vars[i].var());
}
// For now, function_ must be allocated at the very end. If it gets
@@ -1298,4 +1354,77 @@ int Scope::ContextLocalCount() const {
(function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
}
+
+void Scope::AllocateModules(CompilationInfo* info) {
+ ASSERT(is_global_scope() || is_module_scope());
+
+ if (is_module_scope()) {
+ ASSERT(interface_->IsFrozen());
+ ASSERT(scope_info_.is_null());
+
+ // TODO(rossberg): This has to be the initial compilation of this code.
+ // We currently do not allow recompiling any module definitions.
+ Handle<ScopeInfo> scope_info = GetScopeInfo();
+ Factory* factory = info->isolate()->factory();
+ Handle<Context> context = factory->NewModuleContext(scope_info);
+ Handle<JSModule> instance = factory->NewJSModule(context, scope_info);
+ context->set_module(*instance);
+
+ bool ok;
+ interface_->MakeSingleton(instance, &ok);
+ ASSERT(ok);
+ }
+
+ // Allocate nested modules.
+ for (int i = 0; i < inner_scopes_.length(); i++) {
+ Scope* inner_scope = inner_scopes_.at(i);
+ if (inner_scope->is_module_scope()) {
+ inner_scope->AllocateModules(info);
+ }
+ }
+}
+
+
+void Scope::LinkModules(CompilationInfo* info) {
+ ASSERT(is_global_scope() || is_module_scope());
+
+ if (is_module_scope()) {
+ Handle<JSModule> instance = interface_->Instance();
+
+ // Populate the module instance object.
+ const PropertyAttributes ro_attr =
+ static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE | DONT_ENUM);
+ const PropertyAttributes rw_attr =
+ static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM);
+ for (Interface::Iterator it = interface_->iterator();
+ !it.done(); it.Advance()) {
+ if (it.interface()->IsModule()) {
+ Handle<Object> value = it.interface()->Instance();
+ ASSERT(!value.is_null());
+ JSReceiver::SetProperty(
+ instance, it.name(), value, ro_attr, kStrictMode);
+ } else {
+ Variable* var = LocalLookup(it.name());
+ ASSERT(var != NULL && var->IsContextSlot());
+ PropertyAttributes attr = var->is_const_mode() ? ro_attr : rw_attr;
+ Handle<AccessorInfo> info =
+ Accessors::MakeModuleExport(it.name(), var->index(), attr);
+ Handle<Object> result = SetAccessor(instance, info);
+ ASSERT(!(result.is_null() || result->IsUndefined()));
+ USE(result);
+ }
+ }
+ USE(JSObject::PreventExtensions(instance));
+ }
+
+ // Link nested modules.
+ for (int i = 0; i < inner_scopes_.length(); i++) {
+ Scope* inner_scope = inner_scopes_.at(i);
+ if (inner_scope->is_module_scope()) {
+ inner_scope->LinkModules(info);
+ }
+ }
+}
+
+
} } // namespace v8::internal
diff --git a/deps/v8/src/scopes.h b/deps/v8/src/scopes.h
index decd74d23..b9d151cba 100644
--- a/deps/v8/src/scopes.h
+++ b/deps/v8/src/scopes.h
@@ -160,20 +160,20 @@ class Scope: public ZoneObject {
// global scope. The variable was introduced (possibly from an inner
// scope) by a reference to an unresolved variable with no intervening
// with statements or eval calls.
- Variable* DeclareGlobal(Handle<String> name);
+ Variable* DeclareDynamicGlobal(Handle<String> name);
// Create a new unresolved variable.
template<class Visitor>
VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory,
Handle<String> name,
- int position = RelocInfo::kNoPosition,
- Interface* interface = Interface::NewValue()) {
+ Interface* interface = Interface::NewValue(),
+ int position = RelocInfo::kNoPosition) {
// Note that we must not share the unresolved variables with
// the same name because they may be removed selectively via
// RemoveUnresolved().
ASSERT(!already_resolved());
VariableProxy* proxy =
- factory->NewVariableProxy(name, false, position, interface);
+ factory->NewVariableProxy(name, false, interface, position);
unresolved_.Add(proxy, zone_);
return proxy;
}
@@ -189,7 +189,7 @@ class Scope: public ZoneObject {
// Creates a new temporary variable in this scope. The name is only used
// for printing and cannot be used to find the variable. In particular,
// the only way to get hold of the temporary is by keeping the Variable*
- // around.
+ // around. The name should not clash with a legitimate variable names.
Variable* NewTemporary(Handle<String> name);
// Adds the specific declaration node to the list of declarations in
@@ -280,7 +280,8 @@ class Scope: public ZoneObject {
bool is_block_scope() const { return type_ == BLOCK_SCOPE; }
bool is_with_scope() const { return type_ == WITH_SCOPE; }
bool is_declaration_scope() const {
- return is_eval_scope() || is_function_scope() || is_global_scope();
+ return is_eval_scope() || is_function_scope() ||
+ is_module_scope() || is_global_scope();
}
bool is_classic_mode() const {
return language_mode() == CLASSIC_MODE;
@@ -374,16 +375,14 @@ class Scope: public ZoneObject {
// Determine if we can use lazy compilation for this scope.
bool AllowsLazyCompilation() const;
- // True if we can lazily recompile functions with this scope.
- bool AllowsLazyRecompilation() const;
+ // Determine if we can use lazy compilation for this scope without a context.
+ bool AllowsLazyCompilationWithoutContext() const;
- // True if the outer context of this scope is always the global context.
+ // True if the outer context of this scope is always the native context.
bool HasTrivialOuterContext() const;
- // True if this scope is inside a with scope and all declaration scopes
- // between them have empty contexts. Such declaration scopes become
- // invisible during scope info deserialization.
- bool TrivialDeclarationScopesBeforeWithScope() const;
+ // True if the outer context allows lazy compilation of this scope.
+ bool HasLazyCompilableOuterContext() const;
// The number of contexts between this and scope; zero if this == scope.
int ContextChainLength(Scope* scope);
@@ -592,6 +591,13 @@ class Scope: public ZoneObject {
bool AllocateVariables(CompilationInfo* info,
AstNodeFactory<AstNullVisitor>* factory);
+ // Instance objects have to be created ahead of time (before code generation)
+ // because of potentially cyclic references between them.
+ // Linking also has to be a separate stage, since populating one object may
+ // potentially require (forward) references to others.
+ void AllocateModules(CompilationInfo* info);
+ void LinkModules(CompilationInfo* info);
+
private:
// Construct a scope based on the scope info.
Scope(Scope* inner_scope, ScopeType type, Handle<ScopeInfo> scope_info,
diff --git a/deps/v8/src/serialize.cc b/deps/v8/src/serialize.cc
index cf8e5e18e..2ea09f89c 100644
--- a/deps/v8/src/serialize.cc
+++ b/deps/v8/src/serialize.cc
@@ -37,6 +37,7 @@
#include "platform.h"
#include "runtime.h"
#include "serialize.h"
+#include "snapshot.h"
#include "stub-cache.h"
#include "v8threads.h"
@@ -510,6 +511,18 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
UNCLASSIFIED,
47,
"date_cache_stamp");
+ Add(ExternalReference::address_of_pending_message_obj(isolate).address(),
+ UNCLASSIFIED,
+ 48,
+ "address_of_pending_message_obj");
+ Add(ExternalReference::address_of_has_pending_message(isolate).address(),
+ UNCLASSIFIED,
+ 49,
+ "address_of_has_pending_message");
+ Add(ExternalReference::address_of_pending_message_script(isolate).address(),
+ UNCLASSIFIED,
+ 50,
+ "pending_message_script");
}
@@ -586,104 +599,27 @@ Deserializer::Deserializer(SnapshotByteSource* source)
: isolate_(NULL),
source_(source),
external_reference_decoder_(NULL) {
-}
-
-
-// This routine both allocates a new object, and also keeps
-// track of where objects have been allocated so that we can
-// fix back references when deserializing.
-Address Deserializer::Allocate(int space_index, Space* space, int size) {
- Address address;
- if (!SpaceIsLarge(space_index)) {
- ASSERT(!SpaceIsPaged(space_index) ||
- size <= Page::kPageSize - Page::kObjectStartOffset);
- MaybeObject* maybe_new_allocation;
- if (space_index == NEW_SPACE) {
- maybe_new_allocation =
- reinterpret_cast<NewSpace*>(space)->AllocateRaw(size);
- } else {
- maybe_new_allocation =
- reinterpret_cast<PagedSpace*>(space)->AllocateRaw(size);
- }
- ASSERT(!maybe_new_allocation->IsFailure());
- Object* new_allocation = maybe_new_allocation->ToObjectUnchecked();
- HeapObject* new_object = HeapObject::cast(new_allocation);
- address = new_object->address();
- high_water_[space_index] = address + size;
- } else {
- ASSERT(SpaceIsLarge(space_index));
- LargeObjectSpace* lo_space = reinterpret_cast<LargeObjectSpace*>(space);
- Object* new_allocation;
- if (space_index == kLargeData || space_index == kLargeFixedArray) {
- new_allocation =
- lo_space->AllocateRaw(size, NOT_EXECUTABLE)->ToObjectUnchecked();
- } else {
- ASSERT_EQ(kLargeCode, space_index);
- new_allocation =
- lo_space->AllocateRaw(size, EXECUTABLE)->ToObjectUnchecked();
- }
- HeapObject* new_object = HeapObject::cast(new_allocation);
- // Record all large objects in the same space.
- address = new_object->address();
- pages_[LO_SPACE].Add(address);
+ for (int i = 0; i < LAST_SPACE + 1; i++) {
+ reservations_[i] = kUninitializedReservation;
}
- last_object_address_ = address;
- return address;
-}
-
-
-// This returns the address of an object that has been described in the
-// snapshot as being offset bytes back in a particular space.
-HeapObject* Deserializer::GetAddressFromEnd(int space) {
- int offset = source_->GetInt();
- ASSERT(!SpaceIsLarge(space));
- offset <<= kObjectAlignmentBits;
- return HeapObject::FromAddress(high_water_[space] - offset);
-}
-
-
-// This returns the address of an object that has been described in the
-// snapshot as being offset bytes into a particular space.
-HeapObject* Deserializer::GetAddressFromStart(int space) {
- int offset = source_->GetInt();
- if (SpaceIsLarge(space)) {
- // Large spaces have one object per 'page'.
- return HeapObject::FromAddress(pages_[LO_SPACE][offset]);
- }
- offset <<= kObjectAlignmentBits;
- if (space == NEW_SPACE) {
- // New space has only one space - numbered 0.
- return HeapObject::FromAddress(pages_[space][0] + offset);
- }
- ASSERT(SpaceIsPaged(space));
- int page_of_pointee = offset >> kPageSizeBits;
- Address object_address = pages_[space][page_of_pointee] +
- (offset & Page::kPageAlignmentMask);
- return HeapObject::FromAddress(object_address);
}
void Deserializer::Deserialize() {
isolate_ = Isolate::Current();
ASSERT(isolate_ != NULL);
- // Don't GC while deserializing - just expand the heap.
- AlwaysAllocateScope always_allocate;
- // Don't use the free lists while deserializing.
- LinearAllocationScope allocate_linearly;
+ isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]);
// No active threads.
ASSERT_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse());
// No active handles.
ASSERT(isolate_->handle_scope_implementer()->blocks()->is_empty());
- // Make sure the entire partial snapshot cache is traversed, filling it with
- // valid object pointers.
- isolate_->set_serialize_partial_snapshot_cache_length(
- Isolate::kPartialSnapshotCacheCapacity);
ASSERT_EQ(NULL, external_reference_decoder_);
external_reference_decoder_ = new ExternalReferenceDecoder();
isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG);
+ isolate_->heap()->RepairFreeListsAfterBoot();
isolate_->heap()->IterateWeakRoots(this, VISIT_ALL);
- isolate_->heap()->set_global_contexts_list(
+ isolate_->heap()->set_native_contexts_list(
isolate_->heap()->undefined_value());
// Update data pointers to the external strings containing natives sources.
@@ -693,19 +629,33 @@ void Deserializer::Deserialize() {
ExternalAsciiString::cast(source)->update_data_cache();
}
}
+
+ // Issue code events for newly deserialized code objects.
+ LOG_CODE_EVENT(isolate_, LogCodeObjects());
+ LOG_CODE_EVENT(isolate_, LogCompiledFunctions());
}
void Deserializer::DeserializePartial(Object** root) {
isolate_ = Isolate::Current();
- // Don't GC while deserializing - just expand the heap.
- AlwaysAllocateScope always_allocate;
- // Don't use the free lists while deserializing.
- LinearAllocationScope allocate_linearly;
+ for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) {
+ ASSERT(reservations_[i] != kUninitializedReservation);
+ }
+ isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]);
if (external_reference_decoder_ == NULL) {
external_reference_decoder_ = new ExternalReferenceDecoder();
}
+
+ // Keep track of the code space start and end pointers in case new
+ // code objects were unserialized
+ OldSpace* code_space = isolate_->heap()->code_space();
+ Address start_address = code_space->top();
VisitPointer(root);
+
+ // There's no code deserialized here. If this assert fires
+ // then that's changed and logging should be added to notify
+ // the profiler et al of the new code.
+ CHECK_EQ(start_address, code_space->top());
}
@@ -733,10 +683,9 @@ void Deserializer::VisitPointers(Object** start, Object** end) {
// written very late, which means the FreeSpace map is not set up by the
// time we need to use it to mark the space at the end of a page free.
void Deserializer::ReadObject(int space_number,
- Space* space,
Object** write_back) {
int size = source_->GetInt() << kObjectAlignmentBits;
- Address address = Allocate(space_number, space, size);
+ Address address = Allocate(space_number, size);
*write_back = HeapObject::FromAddress(address);
Object** current = reinterpret_cast<Object**>(address);
Object** limit = current + (size >> kPointerSizeLog2);
@@ -745,44 +694,19 @@ void Deserializer::ReadObject(int space_number,
}
ReadChunk(current, limit, space_number, address);
#ifdef DEBUG
- bool is_codespace = (space == HEAP->code_space()) ||
- ((space == HEAP->lo_space()) && (space_number == kLargeCode));
+ bool is_codespace = (space_number == CODE_SPACE);
ASSERT(HeapObject::FromAddress(address)->IsCode() == is_codespace);
#endif
}
-
-// This macro is always used with a constant argument so it should all fold
-// away to almost nothing in the generated code. It might be nicer to do this
-// with the ternary operator but there are type issues with that.
-#define ASSIGN_DEST_SPACE(space_number) \
- Space* dest_space; \
- if (space_number == NEW_SPACE) { \
- dest_space = isolate->heap()->new_space(); \
- } else if (space_number == OLD_POINTER_SPACE) { \
- dest_space = isolate->heap()->old_pointer_space(); \
- } else if (space_number == OLD_DATA_SPACE) { \
- dest_space = isolate->heap()->old_data_space(); \
- } else if (space_number == CODE_SPACE) { \
- dest_space = isolate->heap()->code_space(); \
- } else if (space_number == MAP_SPACE) { \
- dest_space = isolate->heap()->map_space(); \
- } else if (space_number == CELL_SPACE) { \
- dest_space = isolate->heap()->cell_space(); \
- } else { \
- ASSERT(space_number >= LO_SPACE); \
- dest_space = isolate->heap()->lo_space(); \
- }
-
-
-static const int kUnknownOffsetFromStart = -1;
-
-
void Deserializer::ReadChunk(Object** current,
Object** limit,
int source_space,
Address current_object_address) {
Isolate* const isolate = isolate_;
+ // Write barrier support costs around 1% in startup time. In fact there
+ // are no new space objects in current boot snapshots, so it's not needed,
+ // but that may change.
bool write_barrier_needed = (current_object_address != NULL &&
source_space != NEW_SPACE &&
source_space != CELL_SPACE &&
@@ -798,21 +722,19 @@ void Deserializer::ReadChunk(Object** current,
ASSERT((within & ~kWhereToPointMask) == 0); \
ASSERT((space_number & ~kSpaceMask) == 0);
-#define CASE_BODY(where, how, within, space_number_if_any, offset_from_start) \
+#define CASE_BODY(where, how, within, space_number_if_any) \
{ \
bool emit_write_barrier = false; \
bool current_was_incremented = false; \
int space_number = space_number_if_any == kAnyOldSpace ? \
(data & kSpaceMask) : space_number_if_any; \
if (where == kNewObject && how == kPlain && within == kStartOfObject) {\
- ASSIGN_DEST_SPACE(space_number) \
- ReadObject(space_number, dest_space, current); \
+ ReadObject(space_number, current); \
emit_write_barrier = (space_number == NEW_SPACE); \
} else { \
Object* new_object = NULL; /* May not be a real Object pointer. */ \
if (where == kNewObject) { \
- ASSIGN_DEST_SPACE(space_number) \
- ReadObject(space_number, dest_space, &new_object); \
+ ReadObject(space_number, &new_object); \
} else if (where == kRootArray) { \
int root_id = source_->GetInt(); \
new_object = isolate->heap()->roots_array_start()[root_id]; \
@@ -823,6 +745,9 @@ void Deserializer::ReadChunk(Object** current,
[cache_index]; \
emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
} else if (where == kExternalReference) { \
+ int skip = source_->GetInt(); \
+ current = reinterpret_cast<Object**>(reinterpret_cast<Address>( \
+ current) + skip); \
int reference_id = source_->GetInt(); \
Address address = external_reference_decoder_-> \
Decode(reference_id); \
@@ -831,21 +756,26 @@ void Deserializer::ReadChunk(Object** current,
emit_write_barrier = (space_number == NEW_SPACE); \
new_object = GetAddressFromEnd(data & kSpaceMask); \
} else { \
- ASSERT(where == kFromStart); \
- if (offset_from_start == kUnknownOffsetFromStart) { \
- emit_write_barrier = (space_number == NEW_SPACE); \
- new_object = GetAddressFromStart(data & kSpaceMask); \
+ ASSERT(where == kBackrefWithSkip); \
+ int skip = source_->GetInt(); \
+ current = reinterpret_cast<Object**>( \
+ reinterpret_cast<Address>(current) + skip); \
+ emit_write_barrier = (space_number == NEW_SPACE); \
+ new_object = GetAddressFromEnd(data & kSpaceMask); \
+ } \
+ if (within == kInnerPointer) { \
+ if (space_number != CODE_SPACE || new_object->IsCode()) { \
+ Code* new_code_object = reinterpret_cast<Code*>(new_object); \
+ new_object = reinterpret_cast<Object*>( \
+ new_code_object->instruction_start()); \
} else { \
- Address object_address = pages_[space_number][0] + \
- (offset_from_start << kObjectAlignmentBits); \
- new_object = HeapObject::FromAddress(object_address); \
+ ASSERT(space_number == CODE_SPACE); \
+ JSGlobalPropertyCell* cell = \
+ JSGlobalPropertyCell::cast(new_object); \
+ new_object = reinterpret_cast<Object*>( \
+ cell->ValueAddress()); \
} \
} \
- if (within == kFirstInstruction) { \
- Code* new_code_object = reinterpret_cast<Code*>(new_object); \
- new_object = reinterpret_cast<Object*>( \
- new_code_object->instruction_start()); \
- } \
if (how == kFromCode) { \
Address location_of_branch_data = \
reinterpret_cast<Address>(current); \
@@ -871,47 +801,18 @@ void Deserializer::ReadChunk(Object** current,
break; \
} \
-// This generates a case and a body for each space. The large object spaces are
-// very rare in snapshots so they are grouped in one body.
-#define ONE_PER_SPACE(where, how, within) \
- CASE_STATEMENT(where, how, within, NEW_SPACE) \
- CASE_BODY(where, how, within, NEW_SPACE, kUnknownOffsetFromStart) \
- CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \
- CASE_BODY(where, how, within, OLD_DATA_SPACE, kUnknownOffsetFromStart) \
- CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \
- CASE_BODY(where, how, within, OLD_POINTER_SPACE, kUnknownOffsetFromStart) \
- CASE_STATEMENT(where, how, within, CODE_SPACE) \
- CASE_BODY(where, how, within, CODE_SPACE, kUnknownOffsetFromStart) \
- CASE_STATEMENT(where, how, within, CELL_SPACE) \
- CASE_BODY(where, how, within, CELL_SPACE, kUnknownOffsetFromStart) \
- CASE_STATEMENT(where, how, within, MAP_SPACE) \
- CASE_BODY(where, how, within, MAP_SPACE, kUnknownOffsetFromStart) \
- CASE_STATEMENT(where, how, within, kLargeData) \
- CASE_STATEMENT(where, how, within, kLargeCode) \
- CASE_STATEMENT(where, how, within, kLargeFixedArray) \
- CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart)
-
// This generates a case and a body for the new space (which has to do extra
// write barrier handling) and handles the other spaces with 8 fall-through
// cases and one body.
#define ALL_SPACES(where, how, within) \
CASE_STATEMENT(where, how, within, NEW_SPACE) \
- CASE_BODY(where, how, within, NEW_SPACE, kUnknownOffsetFromStart) \
+ CASE_BODY(where, how, within, NEW_SPACE) \
CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \
CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \
CASE_STATEMENT(where, how, within, CODE_SPACE) \
CASE_STATEMENT(where, how, within, CELL_SPACE) \
CASE_STATEMENT(where, how, within, MAP_SPACE) \
- CASE_STATEMENT(where, how, within, kLargeData) \
- CASE_STATEMENT(where, how, within, kLargeCode) \
- CASE_STATEMENT(where, how, within, kLargeFixedArray) \
- CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart)
-
-#define ONE_PER_CODE_SPACE(where, how, within) \
- CASE_STATEMENT(where, how, within, CODE_SPACE) \
- CASE_BODY(where, how, within, CODE_SPACE, kUnknownOffsetFromStart) \
- CASE_STATEMENT(where, how, within, kLargeCode) \
- CASE_BODY(where, how, within, kLargeCode, kUnknownOffsetFromStart)
+ CASE_BODY(where, how, within, kAnyOldSpace)
#define FOUR_CASES(byte_code) \
case byte_code: \
@@ -925,14 +826,48 @@ void Deserializer::ReadChunk(Object** current,
FOUR_CASES(byte_code + 8) \
FOUR_CASES(byte_code + 12)
+#define COMMON_RAW_LENGTHS(f) \
+ f(1) \
+ f(2) \
+ f(3) \
+ f(4) \
+ f(5) \
+ f(6) \
+ f(7) \
+ f(8) \
+ f(9) \
+ f(10) \
+ f(11) \
+ f(12) \
+ f(13) \
+ f(14) \
+ f(15) \
+ f(16) \
+ f(17) \
+ f(18) \
+ f(19) \
+ f(20) \
+ f(21) \
+ f(22) \
+ f(23) \
+ f(24) \
+ f(25) \
+ f(26) \
+ f(27) \
+ f(28) \
+ f(29) \
+ f(30) \
+ f(31)
+
// We generate 15 cases and bodies that process special tags that combine
// the raw data tag and the length into one byte.
-#define RAW_CASE(index, size) \
- case kRawData + index: { \
- byte* raw_data_out = reinterpret_cast<byte*>(current); \
- source_->CopyRaw(raw_data_out, size); \
- current = reinterpret_cast<Object**>(raw_data_out + size); \
- break; \
+#define RAW_CASE(index) \
+ case kRawData + index: { \
+ byte* raw_data_out = reinterpret_cast<byte*>(current); \
+ source_->CopyRaw(raw_data_out, index * kPointerSize); \
+ current = \
+ reinterpret_cast<Object**>(raw_data_out + index * kPointerSize); \
+ break; \
}
COMMON_RAW_LENGTHS(RAW_CASE)
#undef RAW_CASE
@@ -943,12 +878,11 @@ void Deserializer::ReadChunk(Object** current,
int size = source_->GetInt();
byte* raw_data_out = reinterpret_cast<byte*>(current);
source_->CopyRaw(raw_data_out, size);
- current = reinterpret_cast<Object**>(raw_data_out + size);
break;
}
- SIXTEEN_CASES(kRootArrayLowConstants)
- SIXTEEN_CASES(kRootArrayHighConstants) {
+ SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance)
+ SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) {
int root_id = RootArrayConstantFromByteCode(data);
Object* object = isolate->heap()->roots_array_start()[root_id];
ASSERT(!isolate->heap()->InNewSpace(object));
@@ -956,6 +890,18 @@ void Deserializer::ReadChunk(Object** current,
break;
}
+ SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance)
+ SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) {
+ int root_id = RootArrayConstantFromByteCode(data);
+ int skip = source_->GetInt();
+ current = reinterpret_cast<Object**>(
+ reinterpret_cast<intptr_t>(current) + skip);
+ Object* object = isolate->heap()->roots_array_start()[root_id];
+ ASSERT(!isolate->heap()->InNewSpace(object));
+ *current++ = object;
+ break;
+ }
+
case kRepeat: {
int repeats = source_->GetInt();
Object* object = current[-1];
@@ -967,10 +913,11 @@ void Deserializer::ReadChunk(Object** current,
STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
Heap::kOldSpaceRoots);
- STATIC_ASSERT(kMaxRepeats == 12);
- FOUR_CASES(kConstantRepeat)
- FOUR_CASES(kConstantRepeat + 4)
- FOUR_CASES(kConstantRepeat + 8) {
+ STATIC_ASSERT(kMaxRepeats == 13);
+ case kConstantRepeat:
+ FOUR_CASES(kConstantRepeat + 1)
+ FOUR_CASES(kConstantRepeat + 5)
+ FOUR_CASES(kConstantRepeat + 9) {
int repeats = RepeatsForCode(data);
Object* object = current[-1];
ASSERT(!isolate->heap()->InNewSpace(object));
@@ -981,98 +928,80 @@ void Deserializer::ReadChunk(Object** current,
// Deserialize a new object and write a pointer to it to the current
// object.
- ONE_PER_SPACE(kNewObject, kPlain, kStartOfObject)
- // Support for direct instruction pointers in functions
- ONE_PER_CODE_SPACE(kNewObject, kPlain, kFirstInstruction)
+ ALL_SPACES(kNewObject, kPlain, kStartOfObject)
+ // Support for direct instruction pointers in functions. It's an inner
+ // pointer because it points at the entry point, not at the start of the
+ // code object.
+ CASE_STATEMENT(kNewObject, kPlain, kInnerPointer, CODE_SPACE)
+ CASE_BODY(kNewObject, kPlain, kInnerPointer, CODE_SPACE)
// Deserialize a new code object and write a pointer to its first
// instruction to the current code object.
- ONE_PER_SPACE(kNewObject, kFromCode, kFirstInstruction)
+ ALL_SPACES(kNewObject, kFromCode, kInnerPointer)
// Find a recently deserialized object using its offset from the current
// allocation point and write a pointer to it to the current object.
ALL_SPACES(kBackref, kPlain, kStartOfObject)
+ ALL_SPACES(kBackrefWithSkip, kPlain, kStartOfObject)
#if V8_TARGET_ARCH_MIPS
// Deserialize a new object from pointer found in code and write
// a pointer to it to the current object. Required only for MIPS, and
// omitted on the other architectures because it is fully unrolled and
// would cause bloat.
- ONE_PER_SPACE(kNewObject, kFromCode, kStartOfObject)
+ ALL_SPACES(kNewObject, kFromCode, kStartOfObject)
// Find a recently deserialized code object using its offset from the
// current allocation point and write a pointer to it to the current
// object. Required only for MIPS.
ALL_SPACES(kBackref, kFromCode, kStartOfObject)
- // Find an already deserialized code object using its offset from
- // the start and write a pointer to it to the current object.
- // Required only for MIPS.
- ALL_SPACES(kFromStart, kFromCode, kStartOfObject)
+ ALL_SPACES(kBackrefWithSkip, kFromCode, kStartOfObject)
#endif
// Find a recently deserialized code object using its offset from the
// current allocation point and write a pointer to its first instruction
// to the current code object or the instruction pointer in a function
// object.
- ALL_SPACES(kBackref, kFromCode, kFirstInstruction)
- ALL_SPACES(kBackref, kPlain, kFirstInstruction)
- // Find an already deserialized object using its offset from the start
- // and write a pointer to it to the current object.
- ALL_SPACES(kFromStart, kPlain, kStartOfObject)
- ALL_SPACES(kFromStart, kPlain, kFirstInstruction)
- // Find an already deserialized code object using its offset from the
- // start and write a pointer to its first instruction to the current code
- // object.
- ALL_SPACES(kFromStart, kFromCode, kFirstInstruction)
+ ALL_SPACES(kBackref, kFromCode, kInnerPointer)
+ ALL_SPACES(kBackrefWithSkip, kFromCode, kInnerPointer)
+ ALL_SPACES(kBackref, kPlain, kInnerPointer)
+ ALL_SPACES(kBackrefWithSkip, kPlain, kInnerPointer)
// Find an object in the roots array and write a pointer to it to the
// current object.
CASE_STATEMENT(kRootArray, kPlain, kStartOfObject, 0)
- CASE_BODY(kRootArray, kPlain, kStartOfObject, 0, kUnknownOffsetFromStart)
+ CASE_BODY(kRootArray, kPlain, kStartOfObject, 0)
// Find an object in the partial snapshots cache and write a pointer to it
// to the current object.
CASE_STATEMENT(kPartialSnapshotCache, kPlain, kStartOfObject, 0)
CASE_BODY(kPartialSnapshotCache,
kPlain,
kStartOfObject,
- 0,
- kUnknownOffsetFromStart)
+ 0)
// Find an code entry in the partial snapshots cache and
// write a pointer to it to the current object.
- CASE_STATEMENT(kPartialSnapshotCache, kPlain, kFirstInstruction, 0)
+ CASE_STATEMENT(kPartialSnapshotCache, kPlain, kInnerPointer, 0)
CASE_BODY(kPartialSnapshotCache,
kPlain,
- kFirstInstruction,
- 0,
- kUnknownOffsetFromStart)
+ kInnerPointer,
+ 0)
// Find an external reference and write a pointer to it to the current
// object.
CASE_STATEMENT(kExternalReference, kPlain, kStartOfObject, 0)
CASE_BODY(kExternalReference,
kPlain,
kStartOfObject,
- 0,
- kUnknownOffsetFromStart)
+ 0)
// Find an external reference and write a pointer to it in the current
// code object.
CASE_STATEMENT(kExternalReference, kFromCode, kStartOfObject, 0)
CASE_BODY(kExternalReference,
kFromCode,
kStartOfObject,
- 0,
- kUnknownOffsetFromStart)
+ 0)
#undef CASE_STATEMENT
#undef CASE_BODY
-#undef ONE_PER_SPACE
#undef ALL_SPACES
-#undef ASSIGN_DEST_SPACE
-
- case kNewPage: {
- int space = source_->Get();
- pages_[space].Add(last_object_address_);
- if (space == CODE_SPACE) {
- CPU::FlushICache(last_object_address_, Page::kPageSize);
- }
- break;
- }
case kSkip: {
- current++;
+ int size = source_->GetInt();
+ current = reinterpret_cast<Object**>(
+ reinterpret_cast<intptr_t>(current) + size);
break;
}
@@ -1097,18 +1026,20 @@ void Deserializer::ReadChunk(Object** current,
UNREACHABLE();
}
}
- ASSERT_EQ(current, limit);
+ ASSERT_EQ(limit, current);
}
void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) {
- const int max_shift = ((kPointerSize * kBitsPerByte) / 7) * 7;
- for (int shift = max_shift; shift > 0; shift -= 7) {
- if (integer >= static_cast<uintptr_t>(1u) << shift) {
- Put((static_cast<int>((integer >> shift)) & 0x7f) | 0x80, "IntPart");
- }
- }
- PutSection(static_cast<int>(integer & 0x7f), "IntLastPart");
+ ASSERT(integer < 1 << 22);
+ integer <<= 2;
+ int bytes = 1;
+ if (integer > 0xff) bytes = 2;
+ if (integer > 0xffff) bytes = 3;
+ integer |= bytes;
+ Put(static_cast<int>(integer & 0xff), "IntPart1");
+ if (bytes > 1) Put(static_cast<int>((integer >> 8) & 0xff), "IntPart2");
+ if (bytes > 2) Put(static_cast<int>((integer >> 16) & 0xff), "IntPart3");
}
@@ -1116,7 +1047,6 @@ Serializer::Serializer(SnapshotByteSink* sink)
: sink_(sink),
current_root_index_(0),
external_reference_encoder_(new ExternalReferenceEncoder),
- large_object_total_(0),
root_index_wave_front_(0) {
isolate_ = Isolate::Current();
// The serializer is meant to be used only to generate initial heap images
@@ -1149,22 +1079,7 @@ void StartupSerializer::SerializeStrongReferences() {
void PartialSerializer::Serialize(Object** object) {
this->VisitPointer(object);
- Isolate* isolate = Isolate::Current();
-
- // After we have done the partial serialization the partial snapshot cache
- // will contain some references needed to decode the partial snapshot. We
- // fill it up with undefineds so it has a predictable length so the
- // deserialization code doesn't need to know the length.
- for (int index = isolate->serialize_partial_snapshot_cache_length();
- index < Isolate::kPartialSnapshotCacheCapacity;
- index++) {
- isolate->serialize_partial_snapshot_cache()[index] =
- isolate->heap()->undefined_value();
- startup_serializer_->VisitPointer(
- &isolate->serialize_partial_snapshot_cache()[index]);
- }
- isolate->set_serialize_partial_snapshot_cache_length(
- Isolate::kPartialSnapshotCacheCapacity);
+ Pad();
}
@@ -1179,14 +1094,14 @@ void Serializer::VisitPointers(Object** start, Object** end) {
if (reinterpret_cast<Address>(current) ==
isolate->heap()->store_buffer()->TopAddress()) {
sink_->Put(kSkip, "Skip");
+ sink_->PutInt(kPointerSize, "SkipOneWord");
} else if ((*current)->IsSmi()) {
- sink_->Put(kRawData, "RawData");
- sink_->PutInt(kPointerSize, "length");
+ sink_->Put(kRawData + 1, "Smi");
for (int i = 0; i < kPointerSize; i++) {
sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
}
} else {
- SerializeObject(*current, kPlain, kStartOfObject);
+ SerializeObject(*current, kPlain, kStartOfObject, 0);
}
}
}
@@ -1194,26 +1109,29 @@ void Serializer::VisitPointers(Object** start, Object** end) {
// This ensures that the partial snapshot cache keeps things alive during GC and
// tracks their movement. When it is called during serialization of the startup
-// snapshot the partial snapshot is empty, so nothing happens. When the partial
-// (context) snapshot is created, this array is populated with the pointers that
-// the partial snapshot will need. As that happens we emit serialized objects to
-// the startup snapshot that correspond to the elements of this cache array. On
-// deserialization we therefore need to visit the cache array. This fills it up
-// with pointers to deserialized objects.
+// snapshot nothing happens. When the partial (context) snapshot is created,
+// this array is populated with the pointers that the partial snapshot will
+// need. As that happens we emit serialized objects to the startup snapshot
+// that correspond to the elements of this cache array. On deserialization we
+// therefore need to visit the cache array. This fills it up with pointers to
+// deserialized objects.
void SerializerDeserializer::Iterate(ObjectVisitor* visitor) {
+ if (Serializer::enabled()) return;
Isolate* isolate = Isolate::Current();
- visitor->VisitPointers(
- isolate->serialize_partial_snapshot_cache(),
- &isolate->serialize_partial_snapshot_cache()[
- isolate->serialize_partial_snapshot_cache_length()]);
-}
-
-
-// When deserializing we need to set the size of the snapshot cache. This means
-// the root iteration code (above) will iterate over array elements, writing the
-// references to deserialized objects in them.
-void SerializerDeserializer::SetSnapshotCacheSize(int size) {
- Isolate::Current()->set_serialize_partial_snapshot_cache_length(size);
+ for (int i = 0; ; i++) {
+ if (isolate->serialize_partial_snapshot_cache_length() <= i) {
+ // Extend the array ready to get a value from the visitor when
+ // deserializing.
+ isolate->PushToPartialSnapshotCache(Smi::FromInt(0));
+ }
+ Object** cache = isolate->serialize_partial_snapshot_cache();
+ visitor->VisitPointers(&cache[i], &cache[i + 1]);
+ // Sentinel is the undefined object, which is a root so it will not normally
+ // be found in the cache.
+ if (cache[i] == isolate->heap()->undefined_value()) {
+ break;
+ }
+ }
}
@@ -1231,14 +1149,11 @@ int PartialSerializer::PartialSnapshotCacheIndex(HeapObject* heap_object) {
// then visit the pointer so that it becomes part of the startup snapshot
// and we can refer to it from the partial snapshot.
int length = isolate->serialize_partial_snapshot_cache_length();
- CHECK(length < Isolate::kPartialSnapshotCacheCapacity);
- isolate->serialize_partial_snapshot_cache()[length] = heap_object;
- startup_serializer_->VisitPointer(
- &isolate->serialize_partial_snapshot_cache()[length]);
+ isolate->PushToPartialSnapshotCache(heap_object);
+ startup_serializer_->VisitPointer(reinterpret_cast<Object**>(&heap_object));
// We don't recurse from the startup snapshot generator into the partial
// snapshot generator.
- ASSERT(length == isolate->serialize_partial_snapshot_cache_length());
- isolate->set_serialize_partial_snapshot_cache_length(length + 1);
+ ASSERT(length == isolate->serialize_partial_snapshot_cache_length() - 1);
return length;
}
@@ -1273,58 +1188,50 @@ void Serializer::SerializeReferenceToPreviousObject(
int space,
int address,
HowToCode how_to_code,
- WhereToPoint where_to_point) {
+ WhereToPoint where_to_point,
+ int skip) {
int offset = CurrentAllocationAddress(space) - address;
- bool from_start = true;
- if (SpaceIsPaged(space)) {
- // For paged space it is simple to encode back from current allocation if
- // the object is on the same page as the current allocation pointer.
- if ((CurrentAllocationAddress(space) >> kPageSizeBits) ==
- (address >> kPageSizeBits)) {
- from_start = false;
- address = offset;
- }
- } else if (space == NEW_SPACE) {
- // For new space it is always simple to encode back from current allocation.
- if (offset < address) {
- from_start = false;
- address = offset;
- }
- }
- // If we are actually dealing with real offsets (and not a numbering of
- // all objects) then we should shift out the bits that are always 0.
- if (!SpaceIsLarge(space)) address >>= kObjectAlignmentBits;
- if (from_start) {
- sink_->Put(kFromStart + how_to_code + where_to_point + space, "RefSer");
- sink_->PutInt(address, "address");
- } else {
+ // Shift out the bits that are always 0.
+ offset >>= kObjectAlignmentBits;
+ if (skip == 0) {
sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer");
- sink_->PutInt(address, "address");
+ } else {
+ sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space,
+ "BackRefSerWithSkip");
+ sink_->PutInt(skip, "BackRefSkipDistance");
}
+ sink_->PutInt(offset, "offset");
}
void StartupSerializer::SerializeObject(
Object* o,
HowToCode how_to_code,
- WhereToPoint where_to_point) {
+ WhereToPoint where_to_point,
+ int skip) {
CHECK(o->IsHeapObject());
HeapObject* heap_object = HeapObject::cast(o);
int root_index;
if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) {
- PutRoot(root_index, heap_object, how_to_code, where_to_point);
+ PutRoot(root_index, heap_object, how_to_code, where_to_point, skip);
return;
}
if (address_mapper_.IsMapped(heap_object)) {
- int space = SpaceOfAlreadySerializedObject(heap_object);
+ int space = SpaceOfObject(heap_object);
int address = address_mapper_.MappedTo(heap_object);
SerializeReferenceToPreviousObject(space,
address,
how_to_code,
- where_to_point);
+ where_to_point,
+ skip);
} else {
+ if (skip != 0) {
+ sink_->Put(kSkip, "FlushPendingSkip");
+ sink_->PutInt(skip, "SkipDistance");
+ }
+
// Object has not yet been serialized. Serialize it here.
ObjectSerializer object_serializer(this,
heap_object,
@@ -1337,32 +1244,41 @@ void StartupSerializer::SerializeObject(
void StartupSerializer::SerializeWeakReferences() {
- for (int i = Isolate::Current()->serialize_partial_snapshot_cache_length();
- i < Isolate::kPartialSnapshotCacheCapacity;
- i++) {
- sink_->Put(kRootArray + kPlain + kStartOfObject, "RootSerialization");
- sink_->PutInt(Heap::kUndefinedValueRootIndex, "root_index");
- }
+ // This phase comes right after the partial serialization (of the snapshot).
+ // After we have done the partial serialization the partial snapshot cache
+ // will contain some references needed to decode the partial snapshot. We
+ // add one entry with 'undefined' which is the sentinel that the deserializer
+ // uses to know it is done deserializing the array.
+ Isolate* isolate = Isolate::Current();
+ Object* undefined = isolate->heap()->undefined_value();
+ VisitPointer(&undefined);
HEAP->IterateWeakRoots(this, VISIT_ALL);
+ Pad();
}
void Serializer::PutRoot(int root_index,
HeapObject* object,
SerializerDeserializer::HowToCode how_to_code,
- SerializerDeserializer::WhereToPoint where_to_point) {
+ SerializerDeserializer::WhereToPoint where_to_point,
+ int skip) {
if (how_to_code == kPlain &&
where_to_point == kStartOfObject &&
root_index < kRootArrayNumberOfConstantEncodings &&
!HEAP->InNewSpace(object)) {
- if (root_index < kRootArrayNumberOfLowConstantEncodings) {
- sink_->Put(kRootArrayLowConstants + root_index, "RootLoConstant");
+ if (skip == 0) {
+ sink_->Put(kRootArrayConstants + kNoSkipDistance + root_index,
+ "RootConstant");
} else {
- sink_->Put(kRootArrayHighConstants + root_index -
- kRootArrayNumberOfLowConstantEncodings,
- "RootHiConstant");
+ sink_->Put(kRootArrayConstants + kHasSkipDistance + root_index,
+ "RootConstant");
+ sink_->PutInt(skip, "SkipInPutRoot");
}
} else {
+ if (skip != 0) {
+ sink_->Put(kSkip, "SkipFromPutRoot");
+ sink_->PutInt(skip, "SkipFromPutRootDistance");
+ }
sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
sink_->PutInt(root_index, "root_index");
}
@@ -1372,7 +1288,8 @@ void Serializer::PutRoot(int root_index,
void PartialSerializer::SerializeObject(
Object* o,
HowToCode how_to_code,
- WhereToPoint where_to_point) {
+ WhereToPoint where_to_point,
+ int skip) {
CHECK(o->IsHeapObject());
HeapObject* heap_object = HeapObject::cast(o);
@@ -1385,11 +1302,16 @@ void PartialSerializer::SerializeObject(
int root_index;
if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) {
- PutRoot(root_index, heap_object, how_to_code, where_to_point);
+ PutRoot(root_index, heap_object, how_to_code, where_to_point, skip);
return;
}
if (ShouldBeInThePartialSnapshotCache(heap_object)) {
+ if (skip != 0) {
+ sink_->Put(kSkip, "SkipFromSerializeObject");
+ sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
+ }
+
int cache_index = PartialSnapshotCacheIndex(heap_object);
sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point,
"PartialSnapshotCache");
@@ -1406,13 +1328,18 @@ void PartialSerializer::SerializeObject(
ASSERT(!heap_object->IsSymbol());
if (address_mapper_.IsMapped(heap_object)) {
- int space = SpaceOfAlreadySerializedObject(heap_object);
+ int space = SpaceOfObject(heap_object);
int address = address_mapper_.MappedTo(heap_object);
SerializeReferenceToPreviousObject(space,
address,
how_to_code,
- where_to_point);
+ where_to_point,
+ skip);
} else {
+ if (skip != 0) {
+ sink_->Put(kSkip, "SkipFromSerializeObject");
+ sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
+ }
// Object has not yet been serialized. Serialize it here.
ObjectSerializer serializer(this,
heap_object,
@@ -1436,16 +1363,11 @@ void Serializer::ObjectSerializer::Serialize() {
SnapshotPositionEvent(object_->address(), sink_->Position()));
// Mark this object as already serialized.
- bool start_new_page;
- int offset = serializer_->Allocate(space, size, &start_new_page);
+ int offset = serializer_->Allocate(space, size);
serializer_->address_mapper()->AddMapping(object_, offset);
- if (start_new_page) {
- sink_->Put(kNewPage, "NewPage");
- sink_->PutSection(space, "NewPageSpace");
- }
// Serialize the map (first word of the object).
- serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject);
+ serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0);
// Serialize the rest of the object.
CHECK_EQ(0, bytes_processed_so_far_);
@@ -1486,7 +1408,8 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start,
sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats");
}
} else {
- serializer_->SerializeObject(current_contents, kPlain, kStartOfObject);
+ serializer_->SerializeObject(
+ current_contents, kPlain, kStartOfObject, 0);
bytes_processed_so_far_ += kPointerSize;
current++;
}
@@ -1498,9 +1421,10 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start,
void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) {
Object** current = rinfo->target_object_address();
- OutputRawData(rinfo->target_address_address());
+ int skip = OutputRawData(rinfo->target_address_address(),
+ kCanReturnSkipInsteadOfSkipping);
HowToCode representation = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
- serializer_->SerializeObject(*current, representation, kStartOfObject);
+ serializer_->SerializeObject(*current, representation, kStartOfObject, skip);
bytes_processed_so_far_ += rinfo->target_address_size();
}
@@ -1508,10 +1432,12 @@ void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) {
void Serializer::ObjectSerializer::VisitExternalReferences(Address* start,
Address* end) {
Address references_start = reinterpret_cast<Address>(start);
- OutputRawData(references_start);
+ int skip = OutputRawData(references_start, kCanReturnSkipInsteadOfSkipping);
for (Address* current = start; current < end; current++) {
sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef");
+ sink_->PutInt(skip, "SkipB4ExternalRef");
+ skip = 0;
int reference_id = serializer_->EncodeExternalReference(*current);
sink_->PutInt(reference_id, "reference id");
}
@@ -1521,12 +1447,13 @@ void Serializer::ObjectSerializer::VisitExternalReferences(Address* start,
void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) {
Address references_start = rinfo->target_address_address();
- OutputRawData(references_start);
+ int skip = OutputRawData(references_start, kCanReturnSkipInsteadOfSkipping);
Address* current = rinfo->target_reference_address();
int representation = rinfo->IsCodedSpecially() ?
kFromCode + kStartOfObject : kPlain + kStartOfObject;
sink_->Put(kExternalReference + representation, "ExternalRef");
+ sink_->PutInt(skip, "SkipB4ExternalRef");
int reference_id = serializer_->EncodeExternalReference(*current);
sink_->PutInt(reference_id, "reference id");
bytes_processed_so_far_ += rinfo->target_address_size();
@@ -1535,7 +1462,7 @@ void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) {
void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
Address target_start = rinfo->target_address_address();
- OutputRawData(target_start);
+ int skip = OutputRawData(target_start, kCanReturnSkipInsteadOfSkipping);
Address target = rinfo->target_address();
uint32_t encoding = serializer_->EncodeExternalReference(target);
CHECK(target == NULL ? encoding == 0 : encoding != 0);
@@ -1547,6 +1474,7 @@ void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
representation = kStartOfObject + kPlain;
}
sink_->Put(kExternalReference + representation, "ExternalReference");
+ sink_->PutInt(skip, "SkipB4ExternalRef");
sink_->PutInt(encoding, "reference id");
bytes_processed_so_far_ += rinfo->target_address_size();
}
@@ -1555,25 +1483,27 @@ void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
CHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
Address target_start = rinfo->target_address_address();
- OutputRawData(target_start);
+ int skip = OutputRawData(target_start, kCanReturnSkipInsteadOfSkipping);
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
- serializer_->SerializeObject(target, kFromCode, kFirstInstruction);
+ serializer_->SerializeObject(target, kFromCode, kInnerPointer, skip);
bytes_processed_so_far_ += rinfo->target_address_size();
}
void Serializer::ObjectSerializer::VisitCodeEntry(Address entry_address) {
Code* target = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
- OutputRawData(entry_address);
- serializer_->SerializeObject(target, kPlain, kFirstInstruction);
+ int skip = OutputRawData(entry_address, kCanReturnSkipInsteadOfSkipping);
+ serializer_->SerializeObject(target, kPlain, kInnerPointer, skip);
bytes_processed_so_far_ += kPointerSize;
}
void Serializer::ObjectSerializer::VisitGlobalPropertyCell(RelocInfo* rinfo) {
- // We shouldn't have any global property cell references in code
- // objects in the snapshot.
- UNREACHABLE();
+ ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
+ JSGlobalPropertyCell* cell =
+ JSGlobalPropertyCell::cast(rinfo->target_cell());
+ int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping);
+ serializer_->SerializeObject(cell, kPlain, kInnerPointer, skip);
}
@@ -1601,59 +1531,58 @@ void Serializer::ObjectSerializer::VisitExternalAsciiString(
}
-void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
+int Serializer::ObjectSerializer::OutputRawData(
+ Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) {
Address object_start = object_->address();
+ Address base = object_start + bytes_processed_so_far_;
int up_to_offset = static_cast<int>(up_to - object_start);
- int skipped = up_to_offset - bytes_processed_so_far_;
+ int to_skip = up_to_offset - bytes_processed_so_far_;
+ int bytes_to_output = to_skip;
+ bytes_processed_so_far_ += to_skip;
// This assert will fail if the reloc info gives us the target_address_address
// locations in a non-ascending order. Luckily that doesn't happen.
- ASSERT(skipped >= 0);
- if (skipped != 0) {
- Address base = object_start + bytes_processed_so_far_;
-#define RAW_CASE(index, length) \
- if (skipped == length) { \
+ ASSERT(to_skip >= 0);
+ bool outputting_code = false;
+ if (to_skip != 0 && code_object_ && !code_has_been_output_) {
+ // Output the code all at once and fix later.
+ bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_;
+ outputting_code = true;
+ code_has_been_output_ = true;
+ }
+ if (bytes_to_output != 0 &&
+ (!code_object_ || outputting_code)) {
+#define RAW_CASE(index) \
+ if (!outputting_code && bytes_to_output == index * kPointerSize && \
+ index * kPointerSize == to_skip) { \
sink_->PutSection(kRawData + index, "RawDataFixed"); \
+ to_skip = 0; /* This insn already skips. */ \
} else /* NOLINT */
COMMON_RAW_LENGTHS(RAW_CASE)
#undef RAW_CASE
{ /* NOLINT */
+ // We always end up here if we are outputting the code of a code object.
sink_->Put(kRawData, "RawData");
- sink_->PutInt(skipped, "length");
+ sink_->PutInt(bytes_to_output, "length");
}
- for (int i = 0; i < skipped; i++) {
+ for (int i = 0; i < bytes_to_output; i++) {
unsigned int data = base[i];
sink_->PutSection(data, "Byte");
}
- bytes_processed_so_far_ += skipped;
}
-}
-
-
-int Serializer::SpaceOfObject(HeapObject* object) {
- for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) {
- AllocationSpace s = static_cast<AllocationSpace>(i);
- if (HEAP->InSpace(object, s)) {
- if (i == LO_SPACE) {
- if (object->IsCode()) {
- return kLargeCode;
- } else if (object->IsFixedArray()) {
- return kLargeFixedArray;
- } else {
- return kLargeData;
- }
- }
- return i;
- }
+ if (to_skip != 0 && return_skip == kIgnoringReturn) {
+ sink_->Put(kSkip, "Skip");
+ sink_->PutInt(to_skip, "SkipDistance");
+ to_skip = 0;
}
- UNREACHABLE();
- return 0;
+ return to_skip;
}
-int Serializer::SpaceOfAlreadySerializedObject(HeapObject* object) {
+int Serializer::SpaceOfObject(HeapObject* object) {
for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) {
AllocationSpace s = static_cast<AllocationSpace>(i);
if (HEAP->InSpace(object, s)) {
+ ASSERT(i < kNumberOfSpaces);
return i;
}
}
@@ -1662,34 +1591,8 @@ int Serializer::SpaceOfAlreadySerializedObject(HeapObject* object) {
}
-int Serializer::Allocate(int space, int size, bool* new_page) {
+int Serializer::Allocate(int space, int size) {
CHECK(space >= 0 && space < kNumberOfSpaces);
- if (SpaceIsLarge(space)) {
- // In large object space we merely number the objects instead of trying to
- // determine some sort of address.
- *new_page = true;
- large_object_total_ += size;
- return fullness_[LO_SPACE]++;
- }
- *new_page = false;
- if (fullness_[space] == 0) {
- *new_page = true;
- }
- if (SpaceIsPaged(space)) {
- // Paged spaces are a little special. We encode their addresses as if the
- // pages were all contiguous and each page were filled up in the range
- // 0 - Page::kObjectAreaSize. In practice the pages may not be contiguous
- // and allocation does not start at offset 0 in the page, but this scheme
- // means the deserializer can get the page number quickly by shifting the
- // serialized address.
- CHECK(IsPowerOf2(Page::kPageSize));
- int used_in_this_page = (fullness_[space] & (Page::kPageSize - 1));
- CHECK(size <= SpaceAreaSize(space));
- if (used_in_this_page + size > SpaceAreaSize(space)) {
- *new_page = true;
- fullness_[space] = RoundUp(fullness_[space], Page::kPageSize);
- }
- }
int allocation_address = fullness_[space];
fullness_[space] = allocation_address + size;
return allocation_address;
@@ -1705,4 +1608,21 @@ int Serializer::SpaceAreaSize(int space) {
}
+void Serializer::Pad() {
+ // The non-branching GetInt will read up to 3 bytes too far, so we need
+ // to pad the snapshot to make sure we don't read over the end.
+ for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) {
+ sink_->Put(kNop, "Padding");
+ }
+}
+
+
+bool SnapshotByteSource::AtEOF() {
+ if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false;
+ for (int x = position_; x < length_; x++) {
+ if (data_[x] != SerializerDeserializer::nop()) return false;
+ }
+ return true;
+}
+
} } // namespace v8::internal
diff --git a/deps/v8/src/serialize.h b/deps/v8/src/serialize.h
index f50e23eac..204179285 100644
--- a/deps/v8/src/serialize.h
+++ b/deps/v8/src/serialize.h
@@ -170,13 +170,27 @@ class SnapshotByteSource {
return data_[position_++];
}
+ int32_t GetUnalignedInt() {
+#if defined(V8_HOST_CAN_READ_UNALIGNED) && __BYTE_ORDER == __LITTLE_ENDIAN
+ int32_t answer;
+ ASSERT(position_ + sizeof(answer) <= length_ + 0u);
+ answer = *reinterpret_cast<const int32_t*>(data_ + position_);
+#else
+ int32_t answer = data_[position_];
+ answer |= data_[position_ + 1] << 8;
+ answer |= data_[position_ + 2] << 16;
+ answer |= data_[position_ + 3] << 24;
+#endif
+ return answer;
+ }
+
+ void Advance(int by) { position_ += by; }
+
inline void CopyRaw(byte* to, int number_of_bytes);
inline int GetInt();
- bool AtEOF() {
- return position_ == length_;
- }
+ bool AtEOF();
int position() { return position_; }
@@ -187,48 +201,31 @@ class SnapshotByteSource {
};
-#define COMMON_RAW_LENGTHS(f) \
- f(1, 1) \
- f(2, 2) \
- f(3, 3) \
- f(4, 4) \
- f(5, 5) \
- f(6, 6) \
- f(7, 7) \
- f(8, 8) \
- f(9, 12) \
- f(10, 16) \
- f(11, 20) \
- f(12, 24) \
- f(13, 28) \
- f(14, 32) \
- f(15, 36)
-
// The Serializer/Deserializer class is a common superclass for Serializer and
// Deserializer which is used to store common constants and methods used by
// both.
class SerializerDeserializer: public ObjectVisitor {
public:
static void Iterate(ObjectVisitor* visitor);
- static void SetSnapshotCacheSize(int size);
+
+ static int nop() { return kNop; }
protected:
// Where the pointed-to object can be found:
enum Where {
kNewObject = 0, // Object is next in snapshot.
- // 1-8 One per space.
+ // 1-6 One per space.
kRootArray = 0x9, // Object is found in root array.
kPartialSnapshotCache = 0xa, // Object is in the cache.
kExternalReference = 0xb, // Pointer to an external reference.
- kSkip = 0xc, // Skip a pointer sized cell.
- // 0xd-0xf Free.
- kBackref = 0x10, // Object is described relative to end.
- // 0x11-0x18 One per space.
- // 0x19-0x1f Free.
- kFromStart = 0x20, // Object is described relative to start.
- // 0x21-0x28 One per space.
- // 0x29-0x2f Free.
- // 0x30-0x3f Used by misc. tags below.
+ kSkip = 0xc, // Skip n bytes.
+ kNop = 0xd, // Does nothing, used to pad.
+ // 0xe-0xf Free.
+ kBackref = 0x10, // Object is described relative to end.
+ // 0x11-0x16 One per space.
+ kBackrefWithSkip = 0x18, // Object is described relative to end.
+ // 0x19-0x1e One per space.
+ // 0x20-0x3f Used by misc. tags below.
kPointedToMask = 0x3f
};
@@ -240,17 +237,27 @@ class SerializerDeserializer: public ObjectVisitor {
kHowToCodeMask = 0x40
};
+ // For kRootArrayConstants
+ enum WithSkip {
+ kNoSkipDistance = 0,
+ kHasSkipDistance = 0x40,
+ kWithSkipMask = 0x40
+ };
+
// Where to point within the object.
enum WhereToPoint {
kStartOfObject = 0,
- kFirstInstruction = 0x80,
+ kInnerPointer = 0x80, // First insn in code object or payload of cell.
kWhereToPointMask = 0x80
};
// Misc.
- // Raw data to be copied from the snapshot.
- static const int kRawData = 0x30;
- // Some common raw lengths: 0x31-0x3f
+ // Raw data to be copied from the snapshot. This byte code does not advance
+ // the current pointer, which is used for code objects, where we write the
+ // entire code in one memcpy, then fix up stuff with kSkip and other byte
+ // codes that overwrite data.
+ static const int kRawData = 0x20;
+ // Some common raw lengths: 0x21-0x3f. These autoadvance the current pointer.
// A tag emitted at strategic points in the snapshot to delineate sections.
// If the deserializer does not find these at the expected moments then it
// is an indication that the snapshot and the VM do not fit together.
@@ -260,64 +267,44 @@ class SerializerDeserializer: public ObjectVisitor {
// Used for the source code of the natives, which is in the executable, but
// is referred to from external strings in the snapshot.
static const int kNativesStringResource = 0x71;
- static const int kNewPage = 0x72;
- static const int kRepeat = 0x73;
- static const int kConstantRepeat = 0x74;
- // 0x74-0x7f Repeat last word (subtract 0x73 to get the count).
- static const int kMaxRepeats = 0x7f - 0x73;
+ static const int kRepeat = 0x72;
+ static const int kConstantRepeat = 0x73;
+ // 0x73-0x7f Repeat last word (subtract 0x72 to get the count).
+ static const int kMaxRepeats = 0x7f - 0x72;
static int CodeForRepeats(int repeats) {
ASSERT(repeats >= 1 && repeats <= kMaxRepeats);
- return 0x73 + repeats;
+ return 0x72 + repeats;
}
static int RepeatsForCode(int byte_code) {
ASSERT(byte_code >= kConstantRepeat && byte_code <= 0x7f);
- return byte_code - 0x73;
+ return byte_code - 0x72;
}
- static const int kRootArrayLowConstants = 0xb0;
- // 0xb0-0xbf Things from the first 16 elements of the root array.
- static const int kRootArrayHighConstants = 0xf0;
- // 0xf0-0xff Things from the next 16 elements of the root array.
+ static const int kRootArrayConstants = 0xa0;
+ // 0xa0-0xbf Things from the first 32 elements of the root array.
static const int kRootArrayNumberOfConstantEncodings = 0x20;
- static const int kRootArrayNumberOfLowConstantEncodings = 0x10;
static int RootArrayConstantFromByteCode(int byte_code) {
- int constant = (byte_code & 0xf) | ((byte_code & 0x40) >> 2);
- ASSERT(constant >= 0 && constant < kRootArrayNumberOfConstantEncodings);
- return constant;
+ return byte_code & 0x1f;
}
-
- static const int kLargeData = LAST_SPACE;
- static const int kLargeCode = kLargeData + 1;
- static const int kLargeFixedArray = kLargeCode + 1;
- static const int kNumberOfSpaces = kLargeFixedArray + 1;
+ static const int kNumberOfSpaces = LO_SPACE;
static const int kAnyOldSpace = -1;
// A bitmask for getting the space out of an instruction.
- static const int kSpaceMask = 15;
-
- static inline bool SpaceIsLarge(int space) { return space >= kLargeData; }
- static inline bool SpaceIsPaged(int space) {
- return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE;
- }
+ static const int kSpaceMask = 7;
};
int SnapshotByteSource::GetInt() {
- // A little unwind to catch the really small ints.
- int snapshot_byte = Get();
- if ((snapshot_byte & 0x80) == 0) {
- return snapshot_byte;
- }
- int accumulator = (snapshot_byte & 0x7f) << 7;
- while (true) {
- snapshot_byte = Get();
- if ((snapshot_byte & 0x80) == 0) {
- return accumulator | snapshot_byte;
- }
- accumulator = (accumulator | (snapshot_byte & 0x7f)) << 7;
- }
- UNREACHABLE();
- return accumulator;
+ // This way of variable-length encoding integers does not suffer from branch
+ // mispredictions.
+ uint32_t answer = GetUnalignedInt();
+ int bytes = answer & 3;
+ Advance(bytes);
+ uint32_t mask = 0xffffffffu;
+ mask >>= 32 - (bytes << 3);
+ answer &= mask;
+ answer >>= 2;
+ return answer;
}
@@ -341,6 +328,12 @@ class Deserializer: public SerializerDeserializer {
// Deserialize a single object and the objects reachable from it.
void DeserializePartial(Object** root);
+ void set_reservation(int space_number, int reservation) {
+ ASSERT(space_number >= 0);
+ ASSERT(space_number <= LAST_SPACE);
+ reservations_[space_number] = reservation;
+ }
+
private:
virtual void VisitPointers(Object** start, Object** end);
@@ -359,28 +352,36 @@ class Deserializer: public SerializerDeserializer {
// the heap.
void ReadChunk(
Object** start, Object** end, int space, Address object_address);
- HeapObject* GetAddressFromStart(int space);
- inline HeapObject* GetAddressFromEnd(int space);
- Address Allocate(int space_number, Space* space, int size);
- void ReadObject(int space_number, Space* space, Object** write_back);
+ void ReadObject(int space_number, Object** write_back);
+
+ // This routine both allocates a new object, and also keeps
+ // track of where objects have been allocated so that we can
+ // fix back references when deserializing.
+ Address Allocate(int space_index, int size) {
+ Address address = high_water_[space_index];
+ high_water_[space_index] = address + size;
+ return address;
+ }
+
+ // This returns the address of an object that has been described in the
+ // snapshot as being offset bytes back in a particular space.
+ HeapObject* GetAddressFromEnd(int space) {
+ int offset = source_->GetInt();
+ offset <<= kObjectAlignmentBits;
+ return HeapObject::FromAddress(high_water_[space] - offset);
+ }
+
// Cached current isolate.
Isolate* isolate_;
- // Keep track of the pages in the paged spaces.
- // (In large object space we are keeping track of individual objects
- // rather than pages.) In new space we just need the address of the
- // first object and the others will flow from that.
- List<Address> pages_[SerializerDeserializer::kNumberOfSpaces];
-
SnapshotByteSource* source_;
// This is the address of the next object that will be allocated in each
// space. It is used to calculate the addresses of back-references.
Address high_water_[LAST_SPACE + 1];
- // This is the address of the most recent object that was allocated. It
- // is used to set the location of the new page when we encounter a
- // START_NEW_PAGE_SERIALIZATION tag.
- Address last_object_address_;
+
+ int reservations_[LAST_SPACE + 1];
+ static const intptr_t kUninitializedReservation = -1;
ExternalReferenceDecoder* external_reference_decoder_;
@@ -462,7 +463,7 @@ class Serializer : public SerializerDeserializer {
// You can call this after serialization to find out how much space was used
// in each space.
int CurrentAllocationAddress(int space) {
- if (SpaceIsLarge(space)) return large_object_total_;
+ ASSERT(space < kNumberOfSpaces);
return fullness_[space];
}
@@ -479,8 +480,11 @@ class Serializer : public SerializerDeserializer {
static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
static bool enabled() { return serialization_enabled_; }
SerializationAddressMapper* address_mapper() { return &address_mapper_; }
- void PutRoot(
- int index, HeapObject* object, HowToCode how, WhereToPoint where);
+ void PutRoot(int index,
+ HeapObject* object,
+ HowToCode how,
+ WhereToPoint where,
+ int skip);
protected:
static const int kInvalidRootIndex = -1;
@@ -504,7 +508,9 @@ class Serializer : public SerializerDeserializer {
object_(HeapObject::cast(o)),
sink_(sink),
reference_representation_(how_to_code + where_to_point),
- bytes_processed_so_far_(0) { }
+ bytes_processed_so_far_(0),
+ code_object_(o->IsCode()),
+ code_has_been_output_(false) { }
void Serialize();
void VisitPointers(Object** start, Object** end);
void VisitEmbeddedPointer(RelocInfo* target);
@@ -524,34 +530,36 @@ class Serializer : public SerializerDeserializer {
}
private:
- void OutputRawData(Address up_to);
+ enum ReturnSkip { kCanReturnSkipInsteadOfSkipping, kIgnoringReturn };
+ // This function outputs or skips the raw data between the last pointer and
+ // up to the current position. It optionally can just return the number of
+ // bytes to skip instead of performing a skip instruction, in case the skip
+ // can be merged into the next instruction.
+ int OutputRawData(Address up_to, ReturnSkip return_skip = kIgnoringReturn);
Serializer* serializer_;
HeapObject* object_;
SnapshotByteSink* sink_;
int reference_representation_;
int bytes_processed_so_far_;
+ bool code_object_;
+ bool code_has_been_output_;
};
virtual void SerializeObject(Object* o,
HowToCode how_to_code,
- WhereToPoint where_to_point) = 0;
+ WhereToPoint where_to_point,
+ int skip) = 0;
void SerializeReferenceToPreviousObject(
int space,
int address,
HowToCode how_to_code,
- WhereToPoint where_to_point);
+ WhereToPoint where_to_point,
+ int skip);
void InitializeAllocators();
- // This will return the space for an object. If the object is in large
- // object space it may return kLargeCode or kLargeFixedArray in order
- // to indicate to the deserializer what kind of large object allocation
- // to make.
+ // This will return the space for an object.
static int SpaceOfObject(HeapObject* object);
- // This just returns the space of the object. It will return LO_SPACE
- // for all large objects since you can't check the type of the object
- // once the map has been used for the serialization address.
- static int SpaceOfAlreadySerializedObject(HeapObject* object);
- int Allocate(int space, int size, bool* new_page_started);
+ int Allocate(int space, int size);
int EncodeExternalReference(Address addr) {
return external_reference_encoder_->Encode(addr);
}
@@ -560,9 +568,7 @@ class Serializer : public SerializerDeserializer {
Isolate* isolate_;
// Keep track of the fullness of each space in order to generate
- // relative addresses for back references. Large objects are
- // just numbered sequentially since relative addresses make no
- // sense in large object space.
+ // relative addresses for back references.
int fullness_[LAST_SPACE + 1];
SnapshotByteSink* sink_;
int current_root_index_;
@@ -570,9 +576,9 @@ class Serializer : public SerializerDeserializer {
static bool serialization_enabled_;
// Did we already make use of the fact that serialization was not enabled?
static bool too_late_to_enable_now_;
- int large_object_total_;
SerializationAddressMapper address_mapper_;
intptr_t root_index_wave_front_;
+ void Pad();
friend class ObjectSerializer;
friend class Deserializer;
@@ -595,7 +601,8 @@ class PartialSerializer : public Serializer {
virtual void Serialize(Object** o);
virtual void SerializeObject(Object* o,
HowToCode how_to_code,
- WhereToPoint where_to_point);
+ WhereToPoint where_to_point,
+ int skip);
protected:
virtual int PartialSnapshotCacheIndex(HeapObject* o);
@@ -633,11 +640,13 @@ class StartupSerializer : public Serializer {
virtual void SerializeStrongReferences();
virtual void SerializeObject(Object* o,
HowToCode how_to_code,
- WhereToPoint where_to_point);
+ WhereToPoint where_to_point,
+ int skip);
void SerializeWeakReferences();
void Serialize() {
SerializeStrongReferences();
SerializeWeakReferences();
+ Pad();
}
private:
diff --git a/deps/v8/src/smart-array-pointer.h b/deps/v8/src/smart-array-pointer.h
deleted file mode 100644
index 00721c1a0..000000000
--- a/deps/v8/src/smart-array-pointer.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef V8_SMART_ARRAY_POINTER_H_
-#define V8_SMART_ARRAY_POINTER_H_
-
-namespace v8 {
-namespace internal {
-
-
-// A 'scoped array pointer' that calls DeleteArray on its pointer when the
-// destructor is called.
-template<typename T>
-class SmartArrayPointer {
- public:
- // Default constructor. Constructs an empty scoped pointer.
- inline SmartArrayPointer() : p_(NULL) {}
-
- // Constructs a scoped pointer from a plain one.
- explicit inline SmartArrayPointer(T* ptr) : p_(ptr) {}
-
- // Copy constructor removes the pointer from the original to avoid double
- // freeing.
- inline SmartArrayPointer(const SmartArrayPointer<T>& rhs) : p_(rhs.p_) {
- const_cast<SmartArrayPointer<T>&>(rhs).p_ = NULL;
- }
-
- // When the destructor of the scoped pointer is executed the plain pointer
- // is deleted using DeleteArray. This implies that you must allocate with
- // NewArray.
- inline ~SmartArrayPointer() { if (p_) DeleteArray(p_); }
-
- inline T* operator->() const { return p_; }
-
- // You can get the underlying pointer out with the * operator.
- inline T* operator*() { return p_; }
-
- // You can use [n] to index as if it was a plain pointer
- inline T& operator[](size_t i) {
- return p_[i];
- }
-
- // We don't have implicit conversion to a T* since that hinders migration:
- // You would not be able to change a method from returning a T* to
- // returning an SmartArrayPointer<T> and then get errors wherever it is used.
-
-
- // If you want to take out the plain pointer and don't want it automatically
- // deleted then call Detach(). Afterwards, the smart pointer is empty
- // (NULL).
- inline T* Detach() {
- T* temp = p_;
- p_ = NULL;
- return temp;
- }
-
- // Assignment requires an empty (NULL) SmartArrayPointer as the receiver. Like
- // the copy constructor it removes the pointer in the original to avoid
- // double freeing.
- inline SmartArrayPointer& operator=(const SmartArrayPointer<T>& rhs) {
- ASSERT(is_empty());
- T* tmp = rhs.p_; // swap to handle self-assignment
- const_cast<SmartArrayPointer<T>&>(rhs).p_ = NULL;
- p_ = tmp;
- return *this;
- }
-
- inline bool is_empty() { return p_ == NULL; }
-
- private:
- T* p_;
-};
-
-} } // namespace v8::internal
-
-#endif // V8_SMART_ARRAY_POINTER_H_
diff --git a/deps/v8/src/smart-pointers.h b/deps/v8/src/smart-pointers.h
new file mode 100644
index 000000000..345c4d47f
--- /dev/null
+++ b/deps/v8/src/smart-pointers.h
@@ -0,0 +1,139 @@
+// Copyright 2011 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.
+
+#ifndef V8_SMART_POINTERS_H_
+#define V8_SMART_POINTERS_H_
+
+namespace v8 {
+namespace internal {
+
+
+template<typename Deallocator, typename T>
+class SmartPointerBase {
+ public:
+ // Default constructor. Constructs an empty scoped pointer.
+ inline SmartPointerBase() : p_(NULL) {}
+
+ // Constructs a scoped pointer from a plain one.
+ explicit inline SmartPointerBase(T* ptr) : p_(ptr) {}
+
+ // Copy constructor removes the pointer from the original to avoid double
+ // freeing.
+ inline SmartPointerBase(const SmartPointerBase<Deallocator, T>& rhs)
+ : p_(rhs.p_) {
+ const_cast<SmartPointerBase<Deallocator, T>&>(rhs).p_ = NULL;
+ }
+
+ // When the destructor of the scoped pointer is executed the plain pointer
+ // is deleted using DeleteArray. This implies that you must allocate with
+ // NewArray.
+ inline ~SmartPointerBase() { if (p_) Deallocator::Delete(p_); }
+
+ inline T* operator->() const { return p_; }
+
+ // You can get the underlying pointer out with the * operator.
+ inline T* operator*() { return p_; }
+
+ // You can use [n] to index as if it was a plain pointer
+ inline T& operator[](size_t i) {
+ return p_[i];
+ }
+
+ // We don't have implicit conversion to a T* since that hinders migration:
+ // You would not be able to change a method from returning a T* to
+ // returning an SmartArrayPointer<T> and then get errors wherever it is used.
+
+
+ // If you want to take out the plain pointer and don't want it automatically
+ // deleted then call Detach(). Afterwards, the smart pointer is empty
+ // (NULL).
+ inline T* Detach() {
+ T* temp = p_;
+ p_ = NULL;
+ return temp;
+ }
+
+ // Assignment requires an empty (NULL) SmartArrayPointer as the receiver. Like
+ // the copy constructor it removes the pointer in the original to avoid
+ // double freeing.
+ inline SmartPointerBase<Deallocator, T>& operator=(
+ const SmartPointerBase<Deallocator, T>& rhs) {
+ ASSERT(is_empty());
+ T* tmp = rhs.p_; // swap to handle self-assignment
+ const_cast<SmartPointerBase<Deallocator, T>&>(rhs).p_ = NULL;
+ p_ = tmp;
+ return *this;
+ }
+
+ inline bool is_empty() { return p_ == NULL; }
+
+ private:
+ T* p_;
+};
+
+// A 'scoped array pointer' that calls DeleteArray on its pointer when the
+// destructor is called.
+
+template<typename T>
+struct ArrayDeallocator {
+ static void Delete(T* array) {
+ DeleteArray(array);
+ }
+};
+
+
+template<typename T>
+class SmartArrayPointer: public SmartPointerBase<ArrayDeallocator<T>, T> {
+ public:
+ inline SmartArrayPointer() { }
+ explicit inline SmartArrayPointer(T* ptr)
+ : SmartPointerBase<ArrayDeallocator<T>, T>(ptr) { }
+ inline SmartArrayPointer(const SmartArrayPointer<T>& rhs)
+ : SmartPointerBase<ArrayDeallocator<T>, T>(rhs) { }
+};
+
+
+template<typename T>
+struct ObjectDeallocator {
+ static void Delete(T* array) {
+ Malloced::Delete(array);
+ }
+};
+
+template<typename T>
+class SmartPointer: public SmartPointerBase<ObjectDeallocator<T>, T> {
+ public:
+ inline SmartPointer() { }
+ explicit inline SmartPointer(T* ptr)
+ : SmartPointerBase<ObjectDeallocator<T>, T>(ptr) { }
+ inline SmartPointer(const SmartPointer<T>& rhs)
+ : SmartPointerBase<ObjectDeallocator<T>, T>(rhs) { }
+};
+
+} } // namespace v8::internal
+
+#endif // V8_SMART_POINTERS_H_
diff --git a/deps/v8/src/snapshot-common.cc b/deps/v8/src/snapshot-common.cc
index ef89a5ef7..a8806f053 100644
--- a/deps/v8/src/snapshot-common.cc
+++ b/deps/v8/src/snapshot-common.cc
@@ -37,10 +37,47 @@
namespace v8 {
namespace internal {
-bool Snapshot::Deserialize(const byte* content, int len) {
- SnapshotByteSource source(content, len);
- Deserializer deserializer(&source);
- return V8::Initialize(&deserializer);
+
+static void ReserveSpaceForSnapshot(Deserializer* deserializer,
+ const char* file_name) {
+ int file_name_length = StrLength(file_name) + 10;
+ Vector<char> name = Vector<char>::New(file_name_length + 1);
+ OS::SNPrintF(name, "%s.size", file_name);
+ FILE* fp = OS::FOpen(name.start(), "r");
+ CHECK_NE(NULL, fp);
+ int new_size, pointer_size, data_size, code_size, map_size, cell_size;
+#ifdef _MSC_VER
+ // Avoid warning about unsafe fscanf from MSVC.
+ // Please note that this is only fine if %c and %s are not being used.
+#define fscanf fscanf_s
+#endif
+ CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
+ CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
+ CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
+ CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
+ CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
+ CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
+#ifdef _MSC_VER
+#undef fscanf
+#endif
+ fclose(fp);
+ deserializer->set_reservation(NEW_SPACE, new_size);
+ deserializer->set_reservation(OLD_POINTER_SPACE, pointer_size);
+ deserializer->set_reservation(OLD_DATA_SPACE, data_size);
+ deserializer->set_reservation(CODE_SPACE, code_size);
+ deserializer->set_reservation(MAP_SPACE, map_size);
+ deserializer->set_reservation(CELL_SPACE, cell_size);
+ name.Dispose();
+}
+
+
+void Snapshot::ReserveSpaceForLinkedInSnapshot(Deserializer* deserializer) {
+ deserializer->set_reservation(NEW_SPACE, new_space_used_);
+ deserializer->set_reservation(OLD_POINTER_SPACE, pointer_space_used_);
+ deserializer->set_reservation(OLD_DATA_SPACE, data_space_used_);
+ deserializer->set_reservation(CODE_SPACE, code_space_used_);
+ deserializer->set_reservation(MAP_SPACE, map_space_used_);
+ deserializer->set_reservation(CELL_SPACE, cell_space_used_);
}
@@ -49,32 +86,44 @@ bool Snapshot::Initialize(const char* snapshot_file) {
int len;
byte* str = ReadBytes(snapshot_file, &len);
if (!str) return false;
- Deserialize(str, len);
+ bool success;
+ {
+ SnapshotByteSource source(str, len);
+ Deserializer deserializer(&source);
+ ReserveSpaceForSnapshot(&deserializer, snapshot_file);
+ success = V8::Initialize(&deserializer);
+ }
DeleteArray(str);
- return true;
+ return success;
} else if (size_ > 0) {
- Deserialize(raw_data_, raw_size_);
- return true;
+ SnapshotByteSource source(raw_data_, raw_size_);
+ Deserializer deserializer(&source);
+ ReserveSpaceForLinkedInSnapshot(&deserializer);
+ return V8::Initialize(&deserializer);
}
return false;
}
+bool Snapshot::HaveASnapshotToStartFrom() {
+ return size_ != 0;
+}
+
+
Handle<Context> Snapshot::NewContextFromSnapshot() {
if (context_size_ == 0) {
return Handle<Context>();
}
- HEAP->ReserveSpace(new_space_used_,
- pointer_space_used_,
- data_space_used_,
- code_space_used_,
- map_space_used_,
- cell_space_used_,
- large_space_used_);
SnapshotByteSource source(context_raw_data_,
context_raw_size_);
Deserializer deserializer(&source);
Object* root;
+ deserializer.set_reservation(NEW_SPACE, context_new_space_used_);
+ deserializer.set_reservation(OLD_POINTER_SPACE, context_pointer_space_used_);
+ deserializer.set_reservation(OLD_DATA_SPACE, context_data_space_used_);
+ deserializer.set_reservation(CODE_SPACE, context_code_space_used_);
+ deserializer.set_reservation(MAP_SPACE, context_map_space_used_);
+ deserializer.set_reservation(CELL_SPACE, context_cell_space_used_);
deserializer.DeserializePartial(&root);
CHECK(root->IsContext());
return Handle<Context>(Context::cast(root));
diff --git a/deps/v8/src/snapshot-empty.cc b/deps/v8/src/snapshot-empty.cc
index 0b35720cc..70e7ab815 100644
--- a/deps/v8/src/snapshot-empty.cc
+++ b/deps/v8/src/snapshot-empty.cc
@@ -49,6 +49,12 @@ const int Snapshot::data_space_used_ = 0;
const int Snapshot::code_space_used_ = 0;
const int Snapshot::map_space_used_ = 0;
const int Snapshot::cell_space_used_ = 0;
-const int Snapshot::large_space_used_ = 0;
+
+const int Snapshot::context_new_space_used_ = 0;
+const int Snapshot::context_pointer_space_used_ = 0;
+const int Snapshot::context_data_space_used_ = 0;
+const int Snapshot::context_code_space_used_ = 0;
+const int Snapshot::context_map_space_used_ = 0;
+const int Snapshot::context_cell_space_used_ = 0;
} } // namespace v8::internal
diff --git a/deps/v8/src/snapshot.h b/deps/v8/src/snapshot.h
index 4f01a2d62..c4ae45eee 100644
--- a/deps/v8/src/snapshot.h
+++ b/deps/v8/src/snapshot.h
@@ -40,6 +40,8 @@ class Snapshot {
// could be found.
static bool Initialize(const char* snapshot_file = NULL);
+ static bool HaveASnapshotToStartFrom();
+
// Create a new context using the internal partial snapshot.
static Handle<Context> NewContextFromSnapshot();
@@ -75,13 +77,18 @@ class Snapshot {
static const int code_space_used_;
static const int map_space_used_;
static const int cell_space_used_;
- static const int large_space_used_;
+ static const int context_new_space_used_;
+ static const int context_pointer_space_used_;
+ static const int context_data_space_used_;
+ static const int context_code_space_used_;
+ static const int context_map_space_used_;
+ static const int context_cell_space_used_;
static const int size_;
static const int raw_size_;
static const int context_size_;
static const int context_raw_size_;
- static bool Deserialize(const byte* content, int len);
+ static void ReserveSpaceForLinkedInSnapshot(Deserializer* deserializer);
DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot);
};
diff --git a/deps/v8/src/spaces-inl.h b/deps/v8/src/spaces-inl.h
index ed78fc7a1..c64772775 100644
--- a/deps/v8/src/spaces-inl.h
+++ b/deps/v8/src/spaces-inl.h
@@ -269,6 +269,10 @@ MaybeObject* PagedSpace::AllocateRaw(int size_in_bytes) {
return object;
}
+ ASSERT(!heap()->linear_allocation() ||
+ (anchor_.next_chunk() == &anchor_ &&
+ anchor_.prev_chunk() == &anchor_));
+
object = free_list_.Allocate(size_in_bytes);
if (object != NULL) {
if (identity() == CODE_SPACE) {
diff --git a/deps/v8/src/spaces.cc b/deps/v8/src/spaces.cc
index a0c8f2cba..cc841806b 100644
--- a/deps/v8/src/spaces.cc
+++ b/deps/v8/src/spaces.cc
@@ -447,6 +447,7 @@ MemoryChunk* MemoryChunk::Initialize(Heap* heap,
chunk->InitializeReservedMemory();
chunk->slots_buffer_ = NULL;
chunk->skip_list_ = NULL;
+ chunk->write_barrier_counter_ = kWriteBarrierCounterGranularity;
chunk->ResetLiveBytes();
Bitmap::Clear(chunk);
chunk->initialize_scan_on_scavenge(false);
@@ -496,6 +497,7 @@ MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size,
VirtualMemory reservation;
Address area_start = NULL;
Address area_end = NULL;
+
if (executable == EXECUTABLE) {
chunk_size = RoundUp(CodePageAreaStartOffset() + body_size,
OS::CommitPageSize()) + CodePageGuardSize();
@@ -528,10 +530,11 @@ MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size,
size_executable_ += reservation.size();
}
-#ifdef DEBUG
- ZapBlock(base, CodePageGuardStartOffset());
- ZapBlock(base + CodePageAreaStartOffset(), body_size);
-#endif
+ if (Heap::ShouldZapGarbage()) {
+ ZapBlock(base, CodePageGuardStartOffset());
+ ZapBlock(base + CodePageAreaStartOffset(), body_size);
+ }
+
area_start = base + CodePageAreaStartOffset();
area_end = area_start + body_size;
} else {
@@ -543,9 +546,9 @@ MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size,
if (base == NULL) return NULL;
-#ifdef DEBUG
- ZapBlock(base, chunk_size);
-#endif
+ if (Heap::ShouldZapGarbage()) {
+ ZapBlock(base, chunk_size);
+ }
area_start = base + Page::kObjectStartOffset;
area_end = base + chunk_size;
@@ -621,9 +624,11 @@ bool MemoryAllocator::CommitBlock(Address start,
size_t size,
Executability executable) {
if (!VirtualMemory::CommitRegion(start, size, executable)) return false;
-#ifdef DEBUG
- ZapBlock(start, size);
-#endif
+
+ if (Heap::ShouldZapGarbage()) {
+ ZapBlock(start, size);
+ }
+
isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size));
return true;
}
@@ -881,10 +886,10 @@ intptr_t PagedSpace::SizeOfFirstPage() {
size = 192 * KB;
break;
case MAP_SPACE:
- size = 128 * KB;
+ size = 16 * kPointerSize * KB;
break;
case CELL_SPACE:
- size = 96 * KB;
+ size = 16 * kPointerSize * KB;
break;
case CODE_SPACE:
if (kPointerSize == 8) {
@@ -984,8 +989,7 @@ void PagedSpace::ReleaseAllUnusedPages() {
void PagedSpace::Print() { }
#endif
-
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
void PagedSpace::Verify(ObjectVisitor* visitor) {
// We can only iterate over the pages if they were swept precisely.
if (was_swept_conservatively_) return;
@@ -995,23 +999,23 @@ void PagedSpace::Verify(ObjectVisitor* visitor) {
PageIterator page_iterator(this);
while (page_iterator.has_next()) {
Page* page = page_iterator.next();
- ASSERT(page->owner() == this);
+ CHECK(page->owner() == this);
if (page == Page::FromAllocationTop(allocation_info_.top)) {
allocation_pointer_found_in_space = true;
}
- ASSERT(page->WasSweptPrecisely());
+ CHECK(page->WasSweptPrecisely());
HeapObjectIterator it(page, NULL);
Address end_of_previous_object = page->area_start();
Address top = page->area_end();
int black_size = 0;
for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
- ASSERT(end_of_previous_object <= object->address());
+ CHECK(end_of_previous_object <= object->address());
// The first word should be a map, and we expect all map pointers to
// be in map space.
Map* map = object->map();
- ASSERT(map->IsMap());
- ASSERT(heap()->map_space()->Contains(map));
+ CHECK(map->IsMap());
+ CHECK(heap()->map_space()->Contains(map));
// Perform space-specific object verification.
VerifyObject(object);
@@ -1026,15 +1030,14 @@ void PagedSpace::Verify(ObjectVisitor* visitor) {
black_size += size;
}
- ASSERT(object->address() + size <= top);
+ CHECK(object->address() + size <= top);
end_of_previous_object = object->address() + size;
}
- ASSERT_LE(black_size, page->LiveBytes());
+ CHECK_LE(black_size, page->LiveBytes());
}
- ASSERT(allocation_pointer_found_in_space);
+ CHECK(allocation_pointer_found_in_space);
}
-#endif
-
+#endif // VERIFY_HEAP
// -----------------------------------------------------------------------------
// NewSpace implementation
@@ -1258,7 +1261,7 @@ MaybeObject* NewSpace::SlowAllocateRaw(int size_in_bytes) {
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
// We do not use the SemiSpaceIterator because verification doesn't assume
// that it works (it depends on the invariants we are checking).
void NewSpace::Verify() {
@@ -1307,8 +1310,8 @@ void NewSpace::Verify() {
}
// Check semi-spaces.
- ASSERT_EQ(from_space_.id(), kFromSpace);
- ASSERT_EQ(to_space_.id(), kToSpace);
+ CHECK_EQ(from_space_.id(), kFromSpace);
+ CHECK_EQ(to_space_.id(), kToSpace);
from_space_.Verify();
to_space_.Verify();
}
@@ -1524,8 +1527,9 @@ void SemiSpace::set_age_mark(Address mark) {
#ifdef DEBUG
void SemiSpace::Print() { }
+#endif
-
+#ifdef VERIFY_HEAP
void SemiSpace::Verify() {
bool is_from_space = (id_ == kFromSpace);
NewSpacePage* page = anchor_.next_page();
@@ -1555,8 +1559,9 @@ void SemiSpace::Verify() {
page = page->next_page();
}
}
+#endif
-
+#ifdef DEBUG
void SemiSpace::AssertValidRange(Address start, Address end) {
// Addresses belong to same semi-space
NewSpacePage* page = NewSpacePage::FromLimit(start);
@@ -2027,15 +2032,16 @@ HeapObject* FreeList::Allocate(int size_in_bytes) {
// if it is big enough.
owner_->Free(owner_->top(), old_linear_size);
+ owner_->heap()->incremental_marking()->OldSpaceStep(
+ size_in_bytes - old_linear_size);
+
#ifdef DEBUG
for (int i = 0; i < size_in_bytes / kPointerSize; i++) {
- reinterpret_cast<Object**>(new_node->address())[i] = Smi::FromInt(0);
+ reinterpret_cast<Object**>(new_node->address())[i] =
+ Smi::FromInt(kCodeZapValue);
}
#endif
- owner_->heap()->incremental_marking()->OldSpaceStep(
- size_in_bytes - old_linear_size);
-
// The old-space-step might have finished sweeping and restarted marking.
// Verify that it did not turn the page of the new node into an evacuation
// candidate.
@@ -2257,11 +2263,40 @@ bool PagedSpace::ReserveSpace(int size_in_bytes) {
Free(top(), old_linear_size);
SetTop(new_area->address(), new_area->address() + size_in_bytes);
- Allocate(size_in_bytes);
return true;
}
+static void RepairFreeList(Heap* heap, FreeListNode* n) {
+ while (n != NULL) {
+ Map** map_location = reinterpret_cast<Map**>(n->address());
+ if (*map_location == NULL) {
+ *map_location = heap->free_space_map();
+ } else {
+ ASSERT(*map_location == heap->free_space_map());
+ }
+ n = n->next();
+ }
+}
+
+
+void FreeList::RepairLists(Heap* heap) {
+ RepairFreeList(heap, small_list_);
+ RepairFreeList(heap, medium_list_);
+ RepairFreeList(heap, large_list_);
+ RepairFreeList(heap, huge_list_);
+}
+
+
+// After we have booted, we have created a map which represents free space
+// on the heap. If there was already a free list then the elements on it
+// were created with the wrong FreeSpaceMap (normally NULL), so we need to
+// fix them.
+void PagedSpace::RepairFreeListsAfterBoot() {
+ free_list_.RepairLists(heap());
+}
+
+
// You have to call this last, since the implementation from PagedSpace
// doesn't know that memory was 'promised' to large object space.
bool LargeObjectSpace::ReserveSpace(int bytes) {
@@ -2520,25 +2555,27 @@ void FixedSpace::PrepareForMarkCompact() {
// -----------------------------------------------------------------------------
// MapSpace implementation
+// TODO(mvstanton): this is weird...the compiler can't make a vtable unless
+// there is at least one non-inlined virtual function. I would prefer to hide
+// the VerifyObject definition behind VERIFY_HEAP.
-#ifdef DEBUG
void MapSpace::VerifyObject(HeapObject* object) {
// The object should be a map or a free-list node.
- ASSERT(object->IsMap() || object->IsFreeSpace());
+ CHECK(object->IsMap() || object->IsFreeSpace());
}
-#endif
// -----------------------------------------------------------------------------
// GlobalPropertyCellSpace implementation
+// TODO(mvstanton): this is weird...the compiler can't make a vtable unless
+// there is at least one non-inlined virtual function. I would prefer to hide
+// the VerifyObject definition behind VERIFY_HEAP.
-#ifdef DEBUG
void CellSpace::VerifyObject(HeapObject* object) {
// The object should be a global object property cell or a free-list node.
- ASSERT(object->IsJSGlobalPropertyCell() ||
+ CHECK(object->IsJSGlobalPropertyCell() ||
object->map() == heap()->two_pointer_filler_map());
}
-#endif
// -----------------------------------------------------------------------------
@@ -2648,12 +2685,13 @@ MaybeObject* LargeObjectSpace::AllocateRaw(int object_size,
HeapObject* object = page->GetObject();
-#ifdef DEBUG
- // Make the object consistent so the heap can be vefified in OldSpaceStep.
- reinterpret_cast<Object**>(object->address())[0] =
- heap()->fixed_array_map();
- reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0);
-#endif
+ if (Heap::ShouldZapGarbage()) {
+ // Make the object consistent so the heap can be verified in OldSpaceStep.
+ // We only need to do this in debug builds or if verify_heap is on.
+ reinterpret_cast<Object**>(object->address())[0] =
+ heap()->fixed_array_map();
+ reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0);
+ }
heap()->incremental_marking()->OldSpaceStep(object_size);
return object;
@@ -2752,7 +2790,7 @@ bool LargeObjectSpace::Contains(HeapObject* object) {
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
// We do not assume that the large object iterator works, because it depends
// on the invariants we are checking during verification.
void LargeObjectSpace::Verify() {
@@ -2763,18 +2801,18 @@ void LargeObjectSpace::Verify() {
// object area start.
HeapObject* object = chunk->GetObject();
Page* page = Page::FromAddress(object->address());
- ASSERT(object->address() == page->area_start());
+ CHECK(object->address() == page->area_start());
// The first word should be a map, and we expect all map pointers to be
// in map space.
Map* map = object->map();
- ASSERT(map->IsMap());
- ASSERT(heap()->map_space()->Contains(map));
+ CHECK(map->IsMap());
+ CHECK(heap()->map_space()->Contains(map));
// We have only code, sequential strings, external strings
// (sequential strings that have been morphed into external
// strings), fixed arrays, and byte arrays in large object space.
- ASSERT(object->IsCode() || object->IsSeqString() ||
+ CHECK(object->IsCode() || object->IsSeqString() ||
object->IsExternalString() || object->IsFixedArray() ||
object->IsFixedDoubleArray() || object->IsByteArray());
@@ -2793,15 +2831,17 @@ void LargeObjectSpace::Verify() {
Object* element = array->get(j);
if (element->IsHeapObject()) {
HeapObject* element_object = HeapObject::cast(element);
- ASSERT(heap()->Contains(element_object));
- ASSERT(element_object->map()->IsMap());
+ CHECK(heap()->Contains(element_object));
+ CHECK(element_object->map()->IsMap());
}
}
}
}
}
+#endif
+#ifdef DEBUG
void LargeObjectSpace::Print() {
LargeObjectIterator it(this);
for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
diff --git a/deps/v8/src/spaces.h b/deps/v8/src/spaces.h
index b0ecc5d00..95c63d6b6 100644
--- a/deps/v8/src/spaces.h
+++ b/deps/v8/src/spaces.h
@@ -100,9 +100,6 @@ class Isolate;
#define ASSERT_OBJECT_ALIGNED(address) \
ASSERT((OffsetFrom(address) & kObjectAlignmentMask) == 0)
-#define ASSERT_MAP_ALIGNED(address) \
- ASSERT((OffsetFrom(address) & kMapAlignmentMask) == 0)
-
#define ASSERT_OBJECT_SIZE(size) \
ASSERT((0 < size) && (size <= Page::kMaxNonCodeHeapObjectSize))
@@ -284,7 +281,9 @@ class Bitmap {
bool IsClean() {
for (int i = 0; i < CellsCount(); i++) {
- if (cells()[i] != 0) return false;
+ if (cells()[i] != 0) {
+ return false;
+ }
}
return true;
}
@@ -373,6 +372,11 @@ class MemoryChunk {
return addr >= area_start() && addr <= area_end();
}
+ // Every n write barrier invocations we go to runtime even though
+ // we could have handled it in generated code. This lets us check
+ // whether we have hit the limit and should do some more marking.
+ static const int kWriteBarrierCounterGranularity = 500;
+
enum MemoryChunkFlags {
IS_EXECUTABLE,
ABOUT_TO_BE_FREED,
@@ -468,6 +472,15 @@ class MemoryChunk {
return live_byte_count_;
}
+ int write_barrier_counter() {
+ return static_cast<int>(write_barrier_counter_);
+ }
+
+ void set_write_barrier_counter(int counter) {
+ write_barrier_counter_ = counter;
+ }
+
+
static void IncrementLiveBytesFromGC(Address address, int by) {
MemoryChunk::FromAddress(address)->IncrementLiveBytes(by);
}
@@ -488,11 +501,13 @@ class MemoryChunk {
static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize;
- static const size_t kHeaderSize =
+ static const size_t kWriteBarrierCounterOffset =
kSlotsBufferOffset + kPointerSize + kPointerSize;
+ static const size_t kHeaderSize = kWriteBarrierCounterOffset + kPointerSize;
+
static const int kBodyOffset =
- CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize));
+ CODE_POINTER_ALIGN(kHeaderSize + Bitmap::kSize);
// The start offset of the object area in a page. Aligned to both maps and
// code alignment to be suitable for both. Also aligned to 32 words because
@@ -625,6 +640,7 @@ class MemoryChunk {
int live_byte_count_;
SlotsBuffer* slots_buffer_;
SkipList* skip_list_;
+ intptr_t write_barrier_counter_;
static MemoryChunk* Initialize(Heap* heap,
Address base,
@@ -790,14 +806,6 @@ class Space : public Malloced {
virtual void Print() = 0;
#endif
- // After calling this we can allocate a certain number of bytes using only
- // linear allocation (with a LinearAllocationScope and an AlwaysAllocateScope)
- // without using freelists or causing a GC. This is used by partial
- // snapshots. It returns true of space was reserved or false if a GC is
- // needed. For paged spaces the space requested must include the space wasted
- // at the end of each when allocating linearly.
- virtual bool ReserveSpace(int bytes) = 0;
-
private:
Heap* heap_;
AllocationSpace id_;
@@ -1318,6 +1326,11 @@ class FreeListNode: public HeapObject {
inline void Zap();
+ static inline FreeListNode* cast(MaybeObject* maybe) {
+ ASSERT(!maybe->IsFailure());
+ return reinterpret_cast<FreeListNode*>(maybe);
+ }
+
private:
static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize);
@@ -1380,6 +1393,9 @@ class FreeList BASE_EMBEDDED {
bool IsVeryLong();
#endif
+ // Used after booting the VM.
+ void RepairLists(Heap* heap);
+
struct SizeStats {
intptr_t Total() {
return small_size_ + medium_size_ + large_size_ + huge_size_;
@@ -1460,6 +1476,10 @@ class PagedSpace : public Space {
// linear in the number of objects in the page. It may be slow.
MUST_USE_RESULT MaybeObject* FindObject(Address addr);
+ // During boot the free_space_map is created, and afterwards we may need
+ // to write it into the free list nodes that were already created.
+ virtual void RepairFreeListsAfterBoot();
+
// Prepares for a mark-compact GC.
virtual void PrepareForMarkCompact();
@@ -1551,19 +1571,21 @@ class PagedSpace : public Space {
// The dummy page that anchors the linked list of pages.
Page* anchor() { return &anchor_; }
-#ifdef DEBUG
- // Print meta info and objects in this space.
- virtual void Print();
-
+#ifdef VERIFY_HEAP
// Verify integrity of this space.
virtual void Verify(ObjectVisitor* visitor);
- // Reports statistics for the space
- void ReportStatistics();
-
// Overridden by subclasses to verify space-specific object
// properties (e.g., only maps or free-list nodes are in map space).
virtual void VerifyObject(HeapObject* obj) {}
+#endif
+
+#ifdef DEBUG
+ // Print meta info and objects in this space.
+ virtual void Print();
+
+ // Reports statistics for the space
+ void ReportStatistics();
// Report code object related statistics
void CollectCodeStatistics();
@@ -1911,9 +1933,12 @@ class SemiSpace : public Space {
NewSpacePage* first_page() { return anchor_.next_page(); }
NewSpacePage* current_page() { return current_page_; }
+#ifdef VERIFY_HEAP
+ virtual void Verify();
+#endif
+
#ifdef DEBUG
virtual void Print();
- virtual void Verify();
// Validate a range of of addresses in a SemiSpace.
// The "from" address must be on a page prior to the "to" address,
// in the linked page order, or it must be earlier on the same page.
@@ -2238,9 +2263,12 @@ class NewSpace : public Space {
template <typename StringType>
inline void ShrinkStringAtAllocationBoundary(String* string, int len);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
// Verify the active semispace.
virtual void Verify();
+#endif
+
+#ifdef DEBUG
// Print the active semispace.
virtual void Print() { to_space_.Print(); }
#endif
@@ -2410,9 +2438,7 @@ class MapSpace : public FixedSpace {
}
protected:
-#ifdef DEBUG
virtual void VerifyObject(HeapObject* obj);
-#endif
private:
static const int kMapsPerPage = Page::kNonCodeObjectAreaSize / Map::kSize;
@@ -2448,9 +2474,7 @@ class CellSpace : public FixedSpace {
}
protected:
-#ifdef DEBUG
virtual void VerifyObject(HeapObject* obj);
-#endif
public:
TRACK_MEMORY("CellSpace")
@@ -2496,6 +2520,10 @@ class LargeObjectSpace : public Space {
return objects_size_;
}
+ intptr_t CommittedMemory() {
+ return Size();
+ }
+
int PageCount() {
return page_count_;
}
@@ -2525,8 +2553,11 @@ class LargeObjectSpace : public Space {
LargePage* first_page() { return first_page_; }
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
virtual void Verify();
+#endif
+
+#ifdef DEBUG
virtual void Print();
void ReportStatistics();
void CollectCodeStatistics();
diff --git a/deps/v8/src/store-buffer.cc b/deps/v8/src/store-buffer.cc
index 385215573..66488ae50 100644
--- a/deps/v8/src/store-buffer.cc
+++ b/deps/v8/src/store-buffer.cc
@@ -372,7 +372,7 @@ void StoreBuffer::GCPrologue() {
}
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
static void DummyScavengePointer(HeapObject** p, HeapObject* o) {
// Do nothing.
}
@@ -415,7 +415,7 @@ void StoreBuffer::VerifyPointers(LargeObjectSpace* space) {
void StoreBuffer::Verify() {
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
VerifyPointers(heap_->old_pointer_space(),
&StoreBuffer::FindPointersToNewSpaceInRegion);
VerifyPointers(heap_->map_space(),
@@ -427,9 +427,11 @@ void StoreBuffer::Verify() {
void StoreBuffer::GCEpilogue() {
during_gc_ = false;
+#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
Verify();
}
+#endif
}
diff --git a/deps/v8/src/store-buffer.h b/deps/v8/src/store-buffer.h
index 951a9ca2b..0ade8cee1 100644
--- a/deps/v8/src/store-buffer.h
+++ b/deps/v8/src/store-buffer.h
@@ -195,7 +195,7 @@ class StoreBuffer {
void IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
void VerifyPointers(PagedSpace* space, RegionCallback region_callback);
void VerifyPointers(LargeObjectSpace* space);
#endif
diff --git a/deps/v8/src/string-stream.cc b/deps/v8/src/string-stream.cc
index 270fe5a40..30519b561 100644
--- a/deps/v8/src/string-stream.cc
+++ b/deps/v8/src/string-stream.cc
@@ -348,9 +348,12 @@ void StringStream::PrintUsingMap(JSObject* js_object) {
Add("<Invalid map>\n");
return;
}
+ int real_size = map->NumberOfOwnDescriptors();
DescriptorArray* descs = map->instance_descriptors();
for (int i = 0; i < descs->number_of_descriptors(); i++) {
- if (descs->GetType(i) == FIELD) {
+ PropertyDetails details = descs->GetDetails(i);
+ if (details.descriptor_index() > real_size) continue;
+ if (details.type() == FIELD) {
Object* key = descs->GetKey(i);
if (key->IsString() || key->IsNumber()) {
int len = 3;
@@ -469,7 +472,7 @@ void StringStream::PrintSecurityTokenIfChanged(Object* f) {
Add("(Function context is outside heap)\n");
return;
}
- Object* token = context->global_context()->security_token();
+ Object* token = context->native_context()->security_token();
if (token != isolate->string_stream_current_security_token()) {
Add("Security context: %o\n", token);
isolate->set_string_stream_current_security_token(token);
diff --git a/deps/v8/src/stub-cache.cc b/deps/v8/src/stub-cache.cc
index 27948919d..411914719 100644
--- a/deps/v8/src/stub-cache.cc
+++ b/deps/v8/src/stub-cache.cc
@@ -44,7 +44,7 @@ namespace internal {
StubCache::StubCache(Isolate* isolate, Zone* zone)
- : isolate_(isolate), zone_(zone) {
+ : isolate_(isolate) {
ASSERT(isolate == Isolate::Current());
}
@@ -119,7 +119,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
// Compile the stub that is either shared for all names or
// name specific if there are global objects involved.
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT);
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NONEXISTENT);
Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -138,7 +138,7 @@ Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
Handle<JSObject> holder,
int field_index) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD);
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::FIELD);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -158,7 +158,8 @@ Handle<Code> StubCache::ComputeLoadCallback(Handle<String> name,
Handle<AccessorInfo> callback) {
ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -177,7 +178,8 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name,
Handle<JSObject> holder,
Handle<JSFunction> getter) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -197,7 +199,7 @@ Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
Handle<JSFunction> value) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION);
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CONSTANT_FUNCTION);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -215,7 +217,8 @@ Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::INTERCEPTOR);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -240,7 +243,8 @@ Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
Handle<JSGlobalPropertyCell> cell,
bool is_dont_delete) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -259,7 +263,8 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
Handle<JSObject> holder,
int field_index) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::FIELD);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -278,8 +283,8 @@ Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
Handle<JSObject> holder,
Handle<JSFunction> value) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION);
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC,
+ Code::CONSTANT_FUNCTION);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -298,7 +303,7 @@ Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name,
Handle<JSObject> holder) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR);
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -318,7 +323,7 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
Handle<AccessorInfo> callback) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -335,7 +340,7 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
Handle<Code> StubCache::ComputeKeyedLoadArrayLength(Handle<String> name,
Handle<JSArray> receiver) {
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -351,7 +356,7 @@ Handle<Code> StubCache::ComputeKeyedLoadArrayLength(Handle<String> name,
Handle<Code> StubCache::ComputeKeyedLoadStringLength(Handle<String> name,
Handle<String> receiver) {
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
Handle<Map> map(receiver->map());
Handle<Object> probe(map->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -369,7 +374,7 @@ Handle<Code> StubCache::ComputeKeyedLoadFunctionPrototype(
Handle<String> name,
Handle<JSFunction> receiver) {
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -387,7 +392,8 @@ Handle<Code> StubCache::ComputeStoreField(Handle<String> name,
int field_index,
Handle<Map> transition,
StrictModeFlag strict_mode) {
- PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION;
+ Code::StubType type =
+ (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::STORE_IC, type, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
@@ -415,7 +421,7 @@ Handle<Code> StubCache::ComputeKeyedLoadOrStoreElement(
Code::ComputeMonomorphicFlags(
stub_kind == KeyedIC::LOAD ? Code::KEYED_LOAD_IC
: Code::KEYED_STORE_IC,
- NORMAL,
+ Code::NORMAL,
extra_state);
Handle<String> name;
switch (stub_kind) {
@@ -483,7 +489,7 @@ Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name,
Handle<JSGlobalPropertyCell> cell,
StrictModeFlag strict_mode) {
Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::STORE_IC, NORMAL, strict_mode);
+ Code::STORE_IC, Code::NORMAL, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -498,16 +504,18 @@ Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name,
Handle<Code> StubCache::ComputeStoreCallback(Handle<String> name,
Handle<JSObject> receiver,
+ Handle<JSObject> holder,
Handle<AccessorInfo> callback,
StrictModeFlag strict_mode) {
ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::STORE_IC, CALLBACKS, strict_mode);
+ Code::STORE_IC, Code::CALLBACKS, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
StoreStubCompiler compiler(isolate_, strict_mode);
- Handle<Code> code = compiler.CompileStoreCallback(receiver, callback, name);
+ Handle<Code> code =
+ compiler.CompileStoreCallback(name, receiver, holder, callback);
PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
JSObject::UpdateMapCodeCache(receiver, name, code);
@@ -517,15 +525,17 @@ Handle<Code> StubCache::ComputeStoreCallback(Handle<String> name,
Handle<Code> StubCache::ComputeStoreViaSetter(Handle<String> name,
Handle<JSObject> receiver,
+ Handle<JSObject> holder,
Handle<JSFunction> setter,
StrictModeFlag strict_mode) {
Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::STORE_IC, CALLBACKS, strict_mode);
+ Code::STORE_IC, Code::CALLBACKS, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
StoreStubCompiler compiler(isolate_, strict_mode);
- Handle<Code> code = compiler.CompileStoreViaSetter(receiver, setter, name);
+ Handle<Code> code =
+ compiler.CompileStoreViaSetter(name, receiver, holder, setter);
PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
JSObject::UpdateMapCodeCache(receiver, name, code);
@@ -537,7 +547,7 @@ Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name,
Handle<JSObject> receiver,
StrictModeFlag strict_mode) {
Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::STORE_IC, INTERCEPTOR, strict_mode);
+ Code::STORE_IC, Code::INTERCEPTOR, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -554,7 +564,8 @@ Handle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name,
int field_index,
Handle<Map> transition,
StrictModeFlag strict_mode) {
- PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION;
+ Code::StubType type =
+ (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::KEYED_STORE_IC, type, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
@@ -597,7 +608,7 @@ Handle<Code> StubCache::ComputeCallConstant(int argc,
}
Code::Flags flags =
- Code::ComputeMonomorphicFlags(kind, CONSTANT_FUNCTION, extra_state,
+ Code::ComputeMonomorphicFlags(kind, Code::CONSTANT_FUNCTION, extra_state,
cache_holder, argc);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -635,7 +646,7 @@ Handle<Code> StubCache::ComputeCallField(int argc,
}
Code::Flags flags =
- Code::ComputeMonomorphicFlags(kind, FIELD, extra_state,
+ Code::ComputeMonomorphicFlags(kind, Code::FIELD, extra_state,
cache_holder, argc);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -672,7 +683,7 @@ Handle<Code> StubCache::ComputeCallInterceptor(int argc,
}
Code::Flags flags =
- Code::ComputeMonomorphicFlags(kind, INTERCEPTOR, extra_state,
+ Code::ComputeMonomorphicFlags(kind, Code::INTERCEPTOR, extra_state,
cache_holder, argc);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -702,7 +713,7 @@ Handle<Code> StubCache::ComputeCallGlobal(int argc,
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Code::Flags flags =
- Code::ComputeMonomorphicFlags(kind, NORMAL, extra_state,
+ Code::ComputeMonomorphicFlags(kind, Code::NORMAL, extra_state,
cache_holder, argc);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -735,7 +746,7 @@ Code* StubCache::FindCallInitialize(int argc,
CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
Code::Flags flags =
- Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
+ Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc);
// Use raw_unchecked... so we don't get assert failures during GC.
UnseededNumberDictionary* dictionary =
@@ -756,7 +767,7 @@ Handle<Code> StubCache::ComputeCallInitialize(int argc,
CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
Code::Flags flags =
- Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
+ Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -785,7 +796,7 @@ Handle<Code> StubCache::ComputeCallPreMonomorphic(
Code::Kind kind,
Code::ExtraICState extra_state) {
Code::Flags flags =
- Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, NORMAL, argc);
+ Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -802,7 +813,7 @@ Handle<Code> StubCache::ComputeCallNormal(int argc,
Code::Kind kind,
Code::ExtraICState extra_state) {
Code::Flags flags =
- Code::ComputeFlags(kind, MONOMORPHIC, extra_state, NORMAL, argc);
+ Code::ComputeFlags(kind, MONOMORPHIC, extra_state, Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -819,7 +830,7 @@ Handle<Code> StubCache::ComputeCallArguments(int argc, Code::Kind kind) {
ASSERT(kind == Code::KEYED_CALL_IC);
Code::Flags flags =
Code::ComputeFlags(kind, MEGAMORPHIC, Code::kNoExtraICState,
- NORMAL, argc);
+ Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -838,7 +849,7 @@ Handle<Code> StubCache::ComputeCallMegamorphic(
Code::ExtraICState extra_state) {
Code::Flags flags =
Code::ComputeFlags(kind, MEGAMORPHIC, extra_state,
- NORMAL, argc);
+ Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -858,7 +869,7 @@ Handle<Code> StubCache::ComputeCallMiss(int argc,
// and monomorphic stubs are not mixed up together in the stub cache.
Code::Flags flags =
Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state,
- NORMAL, argc, OWN_MAP);
+ Code::NORMAL, argc, OWN_MAP);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -878,7 +889,7 @@ Handle<Code> StubCache::ComputeCallDebugBreak(int argc,
// the actual call ic to carry out the work.
Code::Flags flags =
Code::ComputeFlags(kind, DEBUG_BREAK, Code::kNoExtraICState,
- NORMAL, argc);
+ Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -897,7 +908,7 @@ Handle<Code> StubCache::ComputeCallDebugPrepareStepIn(int argc,
// the actual call ic to carry out the work.
Code::Flags flags =
Code::ComputeFlags(kind, DEBUG_PREPARE_STEP_IN, Code::kNoExtraICState,
- NORMAL, argc);
+ Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -927,7 +938,8 @@ void StubCache::Clear() {
void StubCache::CollectMatchingMaps(SmallMapList* types,
String* name,
Code::Flags flags,
- Handle<Context> global_context) {
+ Handle<Context> native_context,
+ Zone* zone) {
for (int i = 0; i < kPrimaryTableSize; i++) {
if (primary_[i].key == name) {
Map* map = primary_[i].value->FindFirstMap();
@@ -937,8 +949,8 @@ void StubCache::CollectMatchingMaps(SmallMapList* types,
int offset = PrimaryOffset(name, flags, map);
if (entry(primary_, offset) == &primary_[i] &&
- !TypeFeedbackOracle::CanRetainOtherContext(map, *global_context)) {
- types->Add(Handle<Map>(map), zone());
+ !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
+ types->Add(Handle<Map>(map), zone);
}
}
}
@@ -961,8 +973,8 @@ void StubCache::CollectMatchingMaps(SmallMapList* types,
// Lookup in secondary table and add matches.
int offset = SecondaryOffset(name, flags, primary_offset);
if (entry(secondary_, offset) == &secondary_[i] &&
- !TypeFeedbackOracle::CanRetainOtherContext(map, *global_context)) {
- types->Add(Handle<Map>(map), zone());
+ !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
+ types->Add(Handle<Map>(map), zone);
}
}
}
@@ -993,7 +1005,9 @@ RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) {
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (result.IsEmpty()) return HEAP->undefined_value();
- return *v8::Utils::OpenHandle(*result);
+ Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
+ result_internal->VerifyApiCallResultType();
+ return *result_internal;
}
@@ -1058,6 +1072,8 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!r.IsEmpty()) {
+ Handle<Object> result = v8::Utils::OpenHandle(*r);
+ result->VerifyApiCallResultType();
return *v8::Utils::OpenHandle(*r);
}
}
@@ -1114,7 +1130,9 @@ static MaybeObject* LoadWithInterceptor(Arguments* args,
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!r.IsEmpty()) {
*attrs = NONE;
- return *v8::Utils::OpenHandle(*r);
+ Handle<Object> result = v8::Utils::OpenHandle(*r);
+ result->VerifyApiCallResultType();
+ return *result;
}
}
@@ -1351,16 +1369,14 @@ void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
Handle<String> name,
LookupResult* lookup) {
holder->LocalLookupRealNamedProperty(*name, lookup);
- if (lookup->IsProperty()) return;
-
- lookup->NotFound();
+ if (lookup->IsFound()) return;
if (holder->GetPrototype()->IsNull()) return;
-
holder->GetPrototype()->Lookup(*name, lookup);
}
-Handle<Code> LoadStubCompiler::GetCode(PropertyType type, Handle<String> name) {
+Handle<Code> LoadStubCompiler::GetCode(Code::StubType type,
+ Handle<String> name) {
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type);
Handle<Code> code = GetCodeWithFlags(flags, name);
PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
@@ -1369,7 +1385,7 @@ Handle<Code> LoadStubCompiler::GetCode(PropertyType type, Handle<String> name) {
}
-Handle<Code> KeyedLoadStubCompiler::GetCode(PropertyType type,
+Handle<Code> KeyedLoadStubCompiler::GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state) {
Code::Flags flags = Code::ComputeFlags(
@@ -1381,7 +1397,7 @@ Handle<Code> KeyedLoadStubCompiler::GetCode(PropertyType type,
}
-Handle<Code> StoreStubCompiler::GetCode(PropertyType type,
+Handle<Code> StoreStubCompiler::GetCode(Code::StubType type,
Handle<String> name) {
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_);
@@ -1392,7 +1408,7 @@ Handle<Code> StoreStubCompiler::GetCode(PropertyType type,
}
-Handle<Code> KeyedStoreStubCompiler::GetCode(PropertyType type,
+Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state) {
Code::ExtraICState extra_state =
@@ -1470,7 +1486,8 @@ Handle<Code> CallStubCompiler::CompileCustomCall(
}
-Handle<Code> CallStubCompiler::GetCode(PropertyType type, Handle<String> name) {
+Handle<Code> CallStubCompiler::GetCode(Code::StubType type,
+ Handle<String> name) {
int argc = arguments_.immediate();
Code::Flags flags = Code::ComputeMonomorphicFlags(kind_,
type,
@@ -1486,7 +1503,7 @@ Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) {
if (function->shared()->name()->IsString()) {
function_name = Handle<String>(String::cast(function->shared()->name()));
}
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(Code::CONSTANT_FUNCTION, function_name);
}
diff --git a/deps/v8/src/stub-cache.h b/deps/v8/src/stub-cache.h
index cd0414319..005c537ab 100644
--- a/deps/v8/src/stub-cache.h
+++ b/deps/v8/src/stub-cache.h
@@ -159,11 +159,13 @@ class StubCache {
Handle<Code> ComputeStoreCallback(Handle<String> name,
Handle<JSObject> receiver,
+ Handle<JSObject> holder,
Handle<AccessorInfo> callback,
StrictModeFlag strict_mode);
Handle<Code> ComputeStoreViaSetter(Handle<String> name,
Handle<JSObject> receiver,
+ Handle<JSObject> holder,
Handle<JSFunction> setter,
StrictModeFlag strict_mode);
@@ -260,7 +262,8 @@ class StubCache {
void CollectMatchingMaps(SmallMapList* types,
String* name,
Code::Flags flags,
- Handle<Context> global_context);
+ Handle<Context> native_context,
+ Zone* zone);
// Generate code for probing the stub cache table.
// Arguments extra, extra2 and extra3 may be used to pass additional scratch
@@ -310,7 +313,6 @@ class StubCache {
Isolate* isolate() { return isolate_; }
Heap* heap() { return isolate()->heap(); }
Factory* factory() { return isolate()->factory(); }
- Zone* zone() const { return zone_; }
private:
StubCache(Isolate* isolate, Zone* zone);
@@ -386,7 +388,6 @@ class StubCache {
Entry primary_[kPrimaryTableSize];
Entry secondary_[kSecondaryTableSize];
Isolate* isolate_;
- Zone* zone_;
friend class Isolate;
friend class SCTableReference;
@@ -550,10 +551,20 @@ class StubCompiler BASE_EMBEDDED {
Register scratch1,
Register scratch2,
Register scratch3,
+ Register scratch4,
Handle<AccessorInfo> callback,
Handle<String> name,
Label* miss);
+ void GenerateDictionaryLoadCallback(Register receiver,
+ Register name_reg,
+ Register scratch1,
+ Register scratch2,
+ Register scratch3,
+ Handle<AccessorInfo> callback,
+ Handle<String> name,
+ Label* miss);
+
void GenerateLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Register receiver,
@@ -608,6 +619,9 @@ class LoadStubCompiler: public StubCompiler {
Handle<JSObject> holder,
Handle<AccessorInfo> callback);
+ static void GenerateLoadViaGetter(MacroAssembler* masm,
+ Handle<JSFunction> getter);
+
Handle<Code> CompileLoadViaGetter(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
@@ -629,7 +643,7 @@ class LoadStubCompiler: public StubCompiler {
bool is_dont_delete);
private:
- Handle<Code> GetCode(PropertyType type, Handle<String> name);
+ Handle<Code> GetCode(Code::StubType type, Handle<String> name);
};
@@ -677,7 +691,7 @@ class KeyedLoadStubCompiler: public StubCompiler {
static void GenerateLoadDictionaryElement(MacroAssembler* masm);
private:
- Handle<Code> GetCode(PropertyType type,
+ Handle<Code> GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state = MONOMORPHIC);
};
@@ -694,13 +708,18 @@ class StoreStubCompiler: public StubCompiler {
Handle<Map> transition,
Handle<String> name);
- Handle<Code> CompileStoreCallback(Handle<JSObject> object,
- Handle<AccessorInfo> callback,
- Handle<String> name);
+ Handle<Code> CompileStoreCallback(Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<AccessorInfo> callback);
- Handle<Code> CompileStoreViaSetter(Handle<JSObject> receiver,
- Handle<JSFunction> setter,
- Handle<String> name);
+ static void GenerateStoreViaSetter(MacroAssembler* masm,
+ Handle<JSFunction> setter);
+
+ Handle<Code> CompileStoreViaSetter(Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<JSFunction> setter);
Handle<Code> CompileStoreInterceptor(Handle<JSObject> object,
Handle<String> name);
@@ -710,7 +729,7 @@ class StoreStubCompiler: public StubCompiler {
Handle<String> name);
private:
- Handle<Code> GetCode(PropertyType type, Handle<String> name);
+ Handle<Code> GetCode(Code::StubType type, Handle<String> name);
StrictModeFlag strict_mode_;
};
@@ -751,7 +770,7 @@ class KeyedStoreStubCompiler: public StubCompiler {
static void GenerateStoreDictionaryElement(MacroAssembler* masm);
private:
- Handle<Code> GetCode(PropertyType type,
+ Handle<Code> GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state = MONOMORPHIC);
@@ -831,7 +850,7 @@ class CallStubCompiler: public StubCompiler {
Handle<JSFunction> function,
Handle<String> name);
- Handle<Code> GetCode(PropertyType type, Handle<String> name);
+ Handle<Code> GetCode(Code::StubType type, Handle<String> name);
Handle<Code> GetCode(Handle<JSFunction> function);
const ParameterCount& arguments() { return arguments_; }
diff --git a/deps/v8/src/transitions-inl.h b/deps/v8/src/transitions-inl.h
new file mode 100644
index 000000000..cfaa99d73
--- /dev/null
+++ b/deps/v8/src/transitions-inl.h
@@ -0,0 +1,220 @@
+// Copyright 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.
+
+#ifndef V8_TRANSITIONS_INL_H_
+#define V8_TRANSITIONS_INL_H_
+
+#include "objects-inl.h"
+#include "transitions.h"
+
+namespace v8 {
+namespace internal {
+
+
+#define FIELD_ADDR(p, offset) \
+ (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
+
+#define WRITE_FIELD(p, offset, value) \
+ (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
+
+#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
+ if (mode == UPDATE_WRITE_BARRIER) { \
+ heap->incremental_marking()->RecordWrite( \
+ object, HeapObject::RawField(object, offset), value); \
+ if (heap->InNewSpace(value)) { \
+ heap->RecordWrite(object->address(), offset); \
+ } \
+ }
+
+
+TransitionArray* TransitionArray::cast(Object* object) {
+ ASSERT(object->IsTransitionArray());
+ return reinterpret_cast<TransitionArray*>(object);
+}
+
+
+Map* TransitionArray::elements_transition() {
+ Object* transition_map = get(kElementsTransitionIndex);
+ return Map::cast(transition_map);
+}
+
+
+void TransitionArray::ClearElementsTransition() {
+ WRITE_FIELD(this, kElementsTransitionOffset, Smi::FromInt(0));
+}
+
+
+bool TransitionArray::HasElementsTransition() {
+ return IsFullTransitionArray() &&
+ get(kElementsTransitionIndex) != Smi::FromInt(0);
+}
+
+
+void TransitionArray::set_elements_transition(Map* transition_map,
+ WriteBarrierMode mode) {
+ ASSERT(IsFullTransitionArray());
+ Heap* heap = GetHeap();
+ WRITE_FIELD(this, kElementsTransitionOffset, transition_map);
+ CONDITIONAL_WRITE_BARRIER(
+ heap, this, kElementsTransitionOffset, transition_map, mode);
+}
+
+
+Object* TransitionArray::back_pointer_storage() {
+ return get(kBackPointerStorageIndex);
+}
+
+
+void TransitionArray::set_back_pointer_storage(Object* back_pointer,
+ WriteBarrierMode mode) {
+ Heap* heap = GetHeap();
+ WRITE_FIELD(this, kBackPointerStorageOffset, back_pointer);
+ CONDITIONAL_WRITE_BARRIER(
+ heap, this, kBackPointerStorageOffset, back_pointer, mode);
+}
+
+
+bool TransitionArray::HasPrototypeTransitions() {
+ return IsFullTransitionArray() &&
+ get(kPrototypeTransitionsIndex) != Smi::FromInt(0);
+}
+
+
+FixedArray* TransitionArray::GetPrototypeTransitions() {
+ ASSERT(IsFullTransitionArray());
+ Object* prototype_transitions = get(kPrototypeTransitionsIndex);
+ return FixedArray::cast(prototype_transitions);
+}
+
+
+HeapObject* TransitionArray::UncheckedPrototypeTransitions() {
+ ASSERT(HasPrototypeTransitions());
+ return reinterpret_cast<HeapObject*>(get(kPrototypeTransitionsIndex));
+}
+
+
+void TransitionArray::SetPrototypeTransitions(FixedArray* transitions,
+ WriteBarrierMode mode) {
+ ASSERT(IsFullTransitionArray());
+ ASSERT(transitions->IsFixedArray());
+ Heap* heap = GetHeap();
+ WRITE_FIELD(this, kPrototypeTransitionsOffset, transitions);
+ CONDITIONAL_WRITE_BARRIER(
+ heap, this, kPrototypeTransitionsOffset, transitions, mode);
+}
+
+
+Object** TransitionArray::GetPrototypeTransitionsSlot() {
+ return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
+ kPrototypeTransitionsOffset);
+}
+
+
+Object** TransitionArray::GetKeySlot(int transition_number) {
+ ASSERT(!IsSimpleTransition());
+ ASSERT(transition_number < number_of_transitions());
+ return HeapObject::RawField(
+ reinterpret_cast<HeapObject*>(this),
+ OffsetOfElementAt(ToKeyIndex(transition_number)));
+}
+
+
+String* TransitionArray::GetKey(int transition_number) {
+ if (IsSimpleTransition()) {
+ Map* target = GetTarget(kSimpleTransitionIndex);
+ int descriptor = target->LastAdded();
+ String* key = target->instance_descriptors()->GetKey(descriptor);
+ return key;
+ }
+ ASSERT(transition_number < number_of_transitions());
+ return String::cast(get(ToKeyIndex(transition_number)));
+}
+
+
+void TransitionArray::SetKey(int transition_number, String* key) {
+ ASSERT(!IsSimpleTransition());
+ ASSERT(transition_number < number_of_transitions());
+ set(ToKeyIndex(transition_number), key);
+}
+
+
+Map* TransitionArray::GetTarget(int transition_number) {
+ if (IsSimpleTransition()) {
+ ASSERT(transition_number == kSimpleTransitionIndex);
+ return Map::cast(get(kSimpleTransitionTarget));
+ }
+ ASSERT(transition_number < number_of_transitions());
+ return Map::cast(get(ToTargetIndex(transition_number)));
+}
+
+
+void TransitionArray::SetTarget(int transition_number, Map* value) {
+ if (IsSimpleTransition()) {
+ ASSERT(transition_number == kSimpleTransitionIndex);
+ return set(kSimpleTransitionTarget, value);
+ }
+ ASSERT(transition_number < number_of_transitions());
+ set(ToTargetIndex(transition_number), value);
+}
+
+
+PropertyDetails TransitionArray::GetTargetDetails(int transition_number) {
+ Map* map = GetTarget(transition_number);
+ DescriptorArray* descriptors = map->instance_descriptors();
+ int descriptor = map->LastAdded();
+ return descriptors->GetDetails(descriptor);
+}
+
+
+int TransitionArray::Search(String* name) {
+ if (IsSimpleTransition()) {
+ String* key = GetKey(kSimpleTransitionIndex);
+ if (key->Equals(name)) return kSimpleTransitionIndex;
+ return kNotFound;
+ }
+ return internal::Search<ALL_ENTRIES>(this, name);
+}
+
+
+void TransitionArray::NoIncrementalWriteBarrierSet(int transition_number,
+ String* key,
+ Map* target) {
+ FixedArray::NoIncrementalWriteBarrierSet(
+ this, ToKeyIndex(transition_number), key);
+ FixedArray::NoIncrementalWriteBarrierSet(
+ this, ToTargetIndex(transition_number), target);
+}
+
+
+#undef FIELD_ADDR
+#undef WRITE_FIELD
+#undef CONDITIONAL_WRITE_BARRIER
+
+
+} } // namespace v8::internal
+
+#endif // V8_TRANSITIONS_INL_H_
diff --git a/deps/v8/src/transitions.cc b/deps/v8/src/transitions.cc
new file mode 100644
index 000000000..56b6caf3d
--- /dev/null
+++ b/deps/v8/src/transitions.cc
@@ -0,0 +1,160 @@
+// Copyright 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.
+
+#include "v8.h"
+
+#include "objects.h"
+#include "transitions-inl.h"
+#include "utils.h"
+
+namespace v8 {
+namespace internal {
+
+
+static MaybeObject* AllocateRaw(int length) {
+ Heap* heap = Isolate::Current()->heap();
+
+ // Use FixedArray to not use TransitionArray::cast on incomplete object.
+ FixedArray* array;
+ MaybeObject* maybe_array = heap->AllocateFixedArray(length);
+ if (!maybe_array->To(&array)) return maybe_array;
+ return array;
+}
+
+
+MaybeObject* TransitionArray::Allocate(int number_of_transitions) {
+ FixedArray* array;
+ MaybeObject* maybe_array = AllocateRaw(ToKeyIndex(number_of_transitions));
+ if (!maybe_array->To(&array)) return maybe_array;
+ array->set(kElementsTransitionIndex, Smi::FromInt(0));
+ array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
+ return array;
+}
+
+
+void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
+ int origin_transition,
+ int target_transition) {
+ NoIncrementalWriteBarrierSet(target_transition,
+ origin->GetKey(origin_transition),
+ origin->GetTarget(origin_transition));
+}
+
+
+static bool InsertionPointFound(String* key1, String* key2) {
+ return key1->Hash() > key2->Hash();
+}
+
+
+MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag,
+ String* key,
+ Map* target,
+ Object* back_pointer) {
+ TransitionArray* result;
+ MaybeObject* maybe_result;
+
+ if (flag == SIMPLE_TRANSITION) {
+ maybe_result = AllocateRaw(kSimpleTransitionSize);
+ if (!maybe_result->To(&result)) return maybe_result;
+ result->set(kSimpleTransitionTarget, target);
+ } else {
+ maybe_result = Allocate(1);
+ if (!maybe_result->To(&result)) return maybe_result;
+ result->NoIncrementalWriteBarrierSet(0, key, target);
+ }
+ result->set_back_pointer_storage(back_pointer);
+ return result;
+}
+
+
+MaybeObject* TransitionArray::ExtendToFullTransitionArray() {
+ ASSERT(!IsFullTransitionArray());
+ int nof = number_of_transitions();
+ TransitionArray* result;
+ MaybeObject* maybe_result = Allocate(nof);
+ if (!maybe_result->To(&result)) return maybe_result;
+
+ if (nof == 1) {
+ result->NoIncrementalWriteBarrierCopyFrom(this, kSimpleTransitionIndex, 0);
+ }
+
+ result->set_back_pointer_storage(back_pointer_storage());
+ return result;
+}
+
+
+MaybeObject* TransitionArray::CopyInsert(String* name, Map* target) {
+ TransitionArray* result;
+
+ int number_of_transitions = this->number_of_transitions();
+ int new_size = number_of_transitions;
+
+ int insertion_index = this->Search(name);
+ if (insertion_index == kNotFound) ++new_size;
+
+ MaybeObject* maybe_array;
+ maybe_array = TransitionArray::Allocate(new_size);
+ if (!maybe_array->To(&result)) return maybe_array;
+
+ if (HasElementsTransition()) {
+ result->set_elements_transition(elements_transition());
+ }
+
+ if (HasPrototypeTransitions()) {
+ result->SetPrototypeTransitions(GetPrototypeTransitions());
+ }
+
+ if (insertion_index != kNotFound) {
+ for (int i = 0; i < number_of_transitions; ++i) {
+ if (i != insertion_index) {
+ result->NoIncrementalWriteBarrierCopyFrom(this, i, i);
+ }
+ }
+ result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
+ return result;
+ }
+
+ insertion_index = 0;
+ for (; insertion_index < number_of_transitions; ++insertion_index) {
+ if (InsertionPointFound(GetKey(insertion_index), name)) break;
+ result->NoIncrementalWriteBarrierCopyFrom(
+ this, insertion_index, insertion_index);
+ }
+
+ result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
+
+ for (; insertion_index < number_of_transitions; ++insertion_index) {
+ result->NoIncrementalWriteBarrierCopyFrom(
+ this, insertion_index, insertion_index + 1);
+ }
+
+ result->set_back_pointer_storage(back_pointer_storage());
+ return result;
+}
+
+
+} } // namespace v8::internal
diff --git a/deps/v8/src/transitions.h b/deps/v8/src/transitions.h
new file mode 100644
index 000000000..0a660261c
--- /dev/null
+++ b/deps/v8/src/transitions.h
@@ -0,0 +1,207 @@
+// Copyright 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.
+
+#ifndef V8_TRANSITIONS_H_
+#define V8_TRANSITIONS_H_
+
+#include "elements-kind.h"
+#include "heap.h"
+#include "isolate.h"
+#include "objects.h"
+#include "v8checks.h"
+
+namespace v8 {
+namespace internal {
+
+
+// TransitionArrays are fixed arrays used to hold map transitions for property,
+// constant, and element changes. They can either be simple transition arrays
+// that store a single property transition, or a full transition array that has
+// space for elements transitions, prototype transitions and multiple property
+// transitons. The details related to property transitions are accessed in the
+// descriptor array of the target map. In the case of a simple transition, the
+// key is also read from the descriptor array of the target map.
+//
+// The simple format of the these objects is:
+// [0] Undefined or back pointer map
+// [1] Single transition
+//
+// The full format is:
+// [0] Undefined or back pointer map
+// [1] Smi(0) or elements transition map
+// [2] Smi(0) or fixed array of prototype transitions
+// [3] First transition
+// [length() - kTransitionSize] Last transition
+class TransitionArray: public FixedArray {
+ public:
+ // Accessors for fetching instance transition at transition number.
+ inline String* GetKey(int transition_number);
+ inline void SetKey(int transition_number, String* value);
+ inline Object** GetKeySlot(int transition_number);
+ int GetSortedKeyIndex(int transition_number) { return transition_number; }
+
+ String* GetSortedKey(int transition_number) {
+ return GetKey(transition_number);
+ }
+
+ inline Map* GetTarget(int transition_number);
+ inline void SetTarget(int transition_number, Map* target);
+
+ inline PropertyDetails GetTargetDetails(int transition_number);
+
+ inline Map* elements_transition();
+ inline void set_elements_transition(
+ Map* target,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+ inline bool HasElementsTransition();
+ inline void ClearElementsTransition();
+
+ inline Object* back_pointer_storage();
+ inline void set_back_pointer_storage(
+ Object* back_pointer,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+
+ inline FixedArray* GetPrototypeTransitions();
+ inline void SetPrototypeTransitions(
+ FixedArray* prototype_transitions,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+ inline Object** GetPrototypeTransitionsSlot();
+ inline bool HasPrototypeTransitions();
+ inline HeapObject* UncheckedPrototypeTransitions();
+
+ // Returns the number of transitions in the array.
+ int number_of_transitions() {
+ if (IsSimpleTransition()) return 1;
+ int len = length();
+ return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kTransitionSize;
+ }
+
+ inline int number_of_entries() { return number_of_transitions(); }
+
+ // Allocate a new transition array with a single entry.
+ static MUST_USE_RESULT MaybeObject* NewWith(
+ SimpleTransitionFlag flag,
+ String* key,
+ Map* target,
+ Object* back_pointer);
+
+ MUST_USE_RESULT MaybeObject* ExtendToFullTransitionArray();
+
+ // Copy the transition array, inserting a new transition.
+ // TODO(verwaest): This should not cause an existing transition to be
+ // overwritten.
+ MUST_USE_RESULT MaybeObject* CopyInsert(String* name, Map* target);
+
+ // Copy a single transition from the origin array.
+ inline void NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
+ int origin_transition,
+ int target_transition);
+
+ // Search a transition for a given property name.
+ inline int Search(String* name);
+
+ // Allocates a TransitionArray.
+ MUST_USE_RESULT static MaybeObject* Allocate(int number_of_transitions);
+
+ bool IsSimpleTransition() { return length() == kSimpleTransitionSize; }
+ bool IsFullTransitionArray() { return length() >= kFirstIndex; }
+
+ // Casting.
+ static inline TransitionArray* cast(Object* obj);
+
+ // Constant for denoting key was not found.
+ static const int kNotFound = -1;
+
+ static const int kBackPointerStorageIndex = 0;
+
+ // Layout for full transition arrays.
+ static const int kElementsTransitionIndex = 1;
+ static const int kPrototypeTransitionsIndex = 2;
+ static const int kFirstIndex = 3;
+
+ // Layout for simple transition arrays.
+ static const int kSimpleTransitionTarget = 1;
+ static const int kSimpleTransitionSize = 2;
+ static const int kSimpleTransitionIndex = 0;
+ STATIC_ASSERT(kSimpleTransitionIndex != kNotFound);
+
+ static const int kBackPointerStorageOffset = FixedArray::kHeaderSize;
+
+ // Layout for the full transition array header.
+ static const int kElementsTransitionOffset = kBackPointerStorageOffset +
+ kPointerSize;
+ static const int kPrototypeTransitionsOffset = kElementsTransitionOffset +
+ kPointerSize;
+
+ // Layout of map transition entries in full transition arrays.
+ static const int kTransitionKey = 0;
+ static const int kTransitionTarget = 1;
+ static const int kTransitionSize = 2;
+
+#ifdef OBJECT_PRINT
+ // Print all the transitions.
+ inline void PrintTransitions() {
+ PrintTransitions(stdout);
+ }
+ void PrintTransitions(FILE* out);
+#endif
+
+#ifdef DEBUG
+ bool IsSortedNoDuplicates(int valid_entries = -1);
+ bool IsConsistentWithBackPointers(Map* current_map);
+ bool IsEqualTo(TransitionArray* other);
+#endif
+
+ // The maximum number of transitions we want in a transition array (should
+ // fit in a page).
+ static const int kMaxNumberOfTransitions = 1024 + 512;
+
+ private:
+ // Conversion from transition number to array indices.
+ static int ToKeyIndex(int transition_number) {
+ return kFirstIndex +
+ (transition_number * kTransitionSize) +
+ kTransitionKey;
+ }
+
+ static int ToTargetIndex(int transition_number) {
+ return kFirstIndex +
+ (transition_number * kTransitionSize) +
+ kTransitionTarget;
+ }
+
+ inline void NoIncrementalWriteBarrierSet(int transition_number,
+ String* key,
+ Map* target);
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray);
+};
+
+
+} } // namespace v8::internal
+
+#endif // V8_TRANSITIONS_H_
diff --git a/deps/v8/src/type-info.cc b/deps/v8/src/type-info.cc
index f5e910674..bc6a46b4b 100644
--- a/deps/v8/src/type-info.cc
+++ b/deps/v8/src/type-info.cc
@@ -60,10 +60,10 @@ TypeInfo TypeInfo::TypeFromValue(Handle<Object> value) {
TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
- Handle<Context> global_context,
+ Handle<Context> native_context,
Isolate* isolate,
Zone* zone) {
- global_context_ = global_context;
+ native_context_ = native_context;
isolate_ = isolate;
zone_ = zone;
BuildDictionary(code);
@@ -71,8 +71,13 @@ TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
}
-Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) {
- int entry = dictionary_->FindEntry(ast_id);
+static uint32_t IdToKey(TypeFeedbackId ast_id) {
+ return static_cast<uint32_t>(ast_id.ToInt());
+}
+
+
+Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) {
+ int entry = dictionary_->FindEntry(IdToKey(ast_id));
return entry != UnseededNumberDictionary::kNotFound
? Handle<Object>(dictionary_->ValueAt(entry))
: Handle<Object>::cast(isolate_->factory()->undefined_value());
@@ -80,7 +85,7 @@ Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) {
bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) {
- Handle<Object> map_or_code = GetInfo(expr->id());
+ Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
if (map_or_code->IsMap()) return false;
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
@@ -91,22 +96,23 @@ bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) {
bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) {
- Handle<Object> map_or_code = GetInfo(expr->id());
+ Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
if (map_or_code->IsMap()) return true;
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
- return code->is_keyed_load_stub() &&
+ bool preliminary_checks = code->is_keyed_load_stub() &&
code->ic_state() == MONOMORPHIC &&
- Code::ExtractTypeFromFlags(code->flags()) == NORMAL &&
- code->FindFirstMap() != NULL &&
- !CanRetainOtherContext(code->FindFirstMap(), *global_context_);
+ Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL;
+ if (!preliminary_checks) return false;
+ Map* map = code->FindFirstMap();
+ return map != NULL && !CanRetainOtherContext(map, *native_context_);
}
return false;
}
bool TypeFeedbackOracle::LoadIsMegamorphicWithTypeInfo(Property* expr) {
- Handle<Object> map_or_code = GetInfo(expr->id());
+ Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
Builtins* builtins = isolate_->builtins();
@@ -118,27 +124,29 @@ bool TypeFeedbackOracle::LoadIsMegamorphicWithTypeInfo(Property* expr) {
}
-bool TypeFeedbackOracle::StoreIsMonomorphicNormal(Expression* expr) {
- Handle<Object> map_or_code = GetInfo(expr->id());
+bool TypeFeedbackOracle::StoreIsMonomorphicNormal(TypeFeedbackId ast_id) {
+ Handle<Object> map_or_code = GetInfo(ast_id);
if (map_or_code->IsMap()) return true;
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
bool allow_growth =
Code::GetKeyedAccessGrowMode(code->extra_ic_state()) ==
ALLOW_JSARRAY_GROWTH;
- return code->is_keyed_store_stub() &&
+ bool preliminary_checks =
+ code->is_keyed_store_stub() &&
!allow_growth &&
code->ic_state() == MONOMORPHIC &&
- Code::ExtractTypeFromFlags(code->flags()) == NORMAL &&
- code->FindFirstMap() != NULL &&
- !CanRetainOtherContext(code->FindFirstMap(), *global_context_);
+ Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL;
+ if (!preliminary_checks) return false;
+ Map* map = code->FindFirstMap();
+ return map != NULL && !CanRetainOtherContext(map, *native_context_);
}
return false;
}
-bool TypeFeedbackOracle::StoreIsMegamorphicWithTypeInfo(Expression* expr) {
- Handle<Object> map_or_code = GetInfo(expr->id());
+bool TypeFeedbackOracle::StoreIsMegamorphicWithTypeInfo(TypeFeedbackId ast_id) {
+ Handle<Object> map_or_code = GetInfo(ast_id);
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
Builtins* builtins = isolate_->builtins();
@@ -156,26 +164,26 @@ bool TypeFeedbackOracle::StoreIsMegamorphicWithTypeInfo(Expression* expr) {
bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) {
- Handle<Object> value = GetInfo(expr->id());
+ Handle<Object> value = GetInfo(expr->CallFeedbackId());
return value->IsMap() || value->IsSmi() || value->IsJSFunction();
}
bool TypeFeedbackOracle::CallNewIsMonomorphic(CallNew* expr) {
- Handle<Object> value = GetInfo(expr->id());
+ Handle<Object> value = GetInfo(expr->CallNewFeedbackId());
return value->IsJSFunction();
}
bool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic(
ObjectLiteral::Property* prop) {
- Handle<Object> map_or_code = GetInfo(prop->key()->id());
+ Handle<Object> map_or_code = GetInfo(prop->key()->LiteralFeedbackId());
return map_or_code->IsMap();
}
bool TypeFeedbackOracle::IsForInFastCase(ForInStatement* stmt) {
- Handle<Object> value = GetInfo(stmt->PrepareId());
+ Handle<Object> value = GetInfo(stmt->ForInFeedbackId());
return value->IsSmi() &&
Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker;
}
@@ -183,12 +191,12 @@ bool TypeFeedbackOracle::IsForInFastCase(ForInStatement* stmt) {
Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
ASSERT(LoadIsMonomorphicNormal(expr));
- Handle<Object> map_or_code = GetInfo(expr->id());
+ Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
Map* first_map = code->FindFirstMap();
ASSERT(first_map != NULL);
- return CanRetainOtherContext(first_map, *global_context_)
+ return CanRetainOtherContext(first_map, *native_context_)
? Handle<Map>::null()
: Handle<Map>(first_map);
}
@@ -196,14 +204,15 @@ Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
}
-Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) {
- ASSERT(StoreIsMonomorphicNormal(expr));
- Handle<Object> map_or_code = GetInfo(expr->id());
+Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(
+ TypeFeedbackId ast_id) {
+ ASSERT(StoreIsMonomorphicNormal(ast_id));
+ Handle<Object> map_or_code = GetInfo(ast_id);
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
Map* first_map = code->FindFirstMap();
ASSERT(first_map != NULL);
- return CanRetainOtherContext(first_map, *global_context_)
+ return CanRetainOtherContext(first_map, *native_context_)
? Handle<Map>::null()
: Handle<Map>(first_map);
}
@@ -214,16 +223,18 @@ Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) {
void TypeFeedbackOracle::LoadReceiverTypes(Property* expr,
Handle<String> name,
SmallMapList* types) {
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
- CollectReceiverTypes(expr->id(), name, flags, types);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL);
+ CollectReceiverTypes(expr->PropertyFeedbackId(), name, flags, types);
}
void TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr,
Handle<String> name,
SmallMapList* types) {
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL);
- CollectReceiverTypes(expr->id(), name, flags, types);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::STORE_IC, Code::NORMAL);
+ CollectReceiverTypes(expr->AssignmentFeedbackId(), name, flags, types);
}
@@ -239,16 +250,16 @@ void TypeFeedbackOracle::CallReceiverTypes(Call* expr,
CallIC::Contextual::encode(call_kind == CALL_AS_FUNCTION);
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC,
- NORMAL,
+ Code::NORMAL,
extra_ic_state,
OWN_MAP,
arity);
- CollectReceiverTypes(expr->id(), name, flags, types);
+ CollectReceiverTypes(expr->CallFeedbackId(), name, flags, types);
}
CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) {
- Handle<Object> value = GetInfo(expr->id());
+ Handle<Object> value = GetInfo(expr->CallFeedbackId());
if (!value->IsSmi()) return RECEIVER_MAP_CHECK;
CheckType check = static_cast<CheckType>(Smi::cast(*value)->value());
ASSERT(check != RECEIVER_MAP_CHECK);
@@ -264,13 +275,13 @@ Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck(
UNREACHABLE();
break;
case STRING_CHECK:
- function = global_context_->string_function();
+ function = native_context_->string_function();
break;
case NUMBER_CHECK:
- function = global_context_->number_function();
+ function = native_context_->number_function();
break;
case BOOLEAN_CHECK:
- function = global_context_->boolean_function();
+ function = native_context_->boolean_function();
break;
}
ASSERT(function != NULL);
@@ -279,30 +290,30 @@ Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck(
Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(Call* expr) {
- return Handle<JSFunction>::cast(GetInfo(expr->id()));
+ return Handle<JSFunction>::cast(GetInfo(expr->CallFeedbackId()));
}
Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) {
- return Handle<JSFunction>::cast(GetInfo(expr->id()));
+ return Handle<JSFunction>::cast(GetInfo(expr->CallNewFeedbackId()));
}
Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(
ObjectLiteral::Property* prop) {
ASSERT(ObjectLiteralStoreIsMonomorphic(prop));
- return Handle<Map>::cast(GetInfo(prop->key()->id()));
+ return Handle<Map>::cast(GetInfo(prop->key()->LiteralFeedbackId()));
}
bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) {
- return *GetInfo(expr->id()) ==
+ return *GetInfo(expr->PropertyFeedbackId()) ==
isolate_->builtins()->builtin(id);
}
TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) {
- Handle<Object> object = GetInfo(expr->id());
+ Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
TypeInfo unknown = TypeInfo::Unknown();
if (!object->IsCode()) return unknown;
Handle<Code> code = Handle<Code>::cast(object);
@@ -332,7 +343,7 @@ TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) {
bool TypeFeedbackOracle::IsSymbolCompare(CompareOperation* expr) {
- Handle<Object> object = GetInfo(expr->id());
+ Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
if (!object->IsCode()) return false;
Handle<Code> code = Handle<Code>::cast(object);
if (!code->is_compare_ic_stub()) return false;
@@ -342,7 +353,7 @@ bool TypeFeedbackOracle::IsSymbolCompare(CompareOperation* expr) {
Handle<Map> TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) {
- Handle<Object> object = GetInfo(expr->id());
+ Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
if (!object->IsCode()) return Handle<Map>::null();
Handle<Code> code = Handle<Code>::cast(object);
if (!code->is_compare_ic_stub()) return Handle<Map>::null();
@@ -352,14 +363,14 @@ Handle<Map> TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) {
}
Map* first_map = code->FindFirstMap();
ASSERT(first_map != NULL);
- return CanRetainOtherContext(first_map, *global_context_)
+ return CanRetainOtherContext(first_map, *native_context_)
? Handle<Map>::null()
: Handle<Map>(first_map);
}
TypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) {
- Handle<Object> object = GetInfo(expr->id());
+ Handle<Object> object = GetInfo(expr->UnaryOperationFeedbackId());
TypeInfo unknown = TypeInfo::Unknown();
if (!object->IsCode()) return unknown;
Handle<Code> code = Handle<Code>::cast(object);
@@ -378,7 +389,7 @@ TypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) {
TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) {
- Handle<Object> object = GetInfo(expr->id());
+ Handle<Object> object = GetInfo(expr->BinaryOperationFeedbackId());
TypeInfo unknown = TypeInfo::Unknown();
if (!object->IsCode()) return unknown;
Handle<Code> code = Handle<Code>::cast(object);
@@ -462,7 +473,7 @@ TypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) {
TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
- Handle<Object> object = GetInfo(expr->CountId());
+ Handle<Object> object = GetInfo(expr->CountBinOpFeedbackId());
TypeInfo unknown = TypeInfo::Unknown();
if (!object->IsCode()) return unknown;
Handle<Code> code = Handle<Code>::cast(object);
@@ -490,7 +501,7 @@ TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
}
-void TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
+void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
Handle<String> name,
Code::Flags flags,
SmallMapList* types) {
@@ -511,26 +522,27 @@ void TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
isolate_->stub_cache()->CollectMatchingMaps(types,
*name,
flags,
- global_context_);
+ native_context_,
+ zone());
}
}
-// Check if a map originates from a given global context. We use this
+// Check if a map originates from a given native context. We use this
// information to filter out maps from different context to avoid
// retaining objects from different tabs in Chrome via optimized code.
bool TypeFeedbackOracle::CanRetainOtherContext(Map* map,
- Context* global_context) {
+ Context* native_context) {
Object* constructor = NULL;
while (!map->prototype()->IsNull()) {
constructor = map->constructor();
if (!constructor->IsNull()) {
// If the constructor is not null or a JSFunction, we have to
- // conservatively assume that it may retain a global context.
+ // conservatively assume that it may retain a native context.
if (!constructor->IsJSFunction()) return true;
// Check if the constructor directly references a foreign context.
if (CanRetainOtherContext(JSFunction::cast(constructor),
- global_context)) {
+ native_context)) {
return true;
}
}
@@ -539,14 +551,14 @@ bool TypeFeedbackOracle::CanRetainOtherContext(Map* map,
constructor = map->constructor();
if (constructor->IsNull()) return false;
JSFunction* function = JSFunction::cast(constructor);
- return CanRetainOtherContext(function, global_context);
+ return CanRetainOtherContext(function, native_context);
}
bool TypeFeedbackOracle::CanRetainOtherContext(JSFunction* function,
- Context* global_context) {
- return function->context()->global() != global_context->global()
- && function->context()->global() != global_context->builtins();
+ Context* native_context) {
+ return function->context()->global_object() != native_context->global_object()
+ && function->context()->global_object() != native_context->builtins();
}
@@ -559,7 +571,7 @@ static void AddMapIfMissing(Handle<Map> map, SmallMapList* list,
}
-void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id,
+void TypeFeedbackOracle::CollectKeyedReceiverTypes(TypeFeedbackId ast_id,
SmallMapList* types) {
Handle<Object> object = GetInfo(ast_id);
if (!object->IsCode()) return;
@@ -573,7 +585,7 @@ void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id,
Object* object = info->target_object();
if (object->IsMap()) {
Map* map = Map::cast(object);
- if (!CanRetainOtherContext(map, *global_context_)) {
+ if (!CanRetainOtherContext(map, *native_context_)) {
AddMapIfMissing(Handle<Map>(map), types, zone());
}
}
@@ -582,7 +594,7 @@ void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id,
}
-byte TypeFeedbackOracle::ToBooleanTypes(unsigned ast_id) {
+byte TypeFeedbackOracle::ToBooleanTypes(TypeFeedbackId ast_id) {
Handle<Object> object = GetInfo(ast_id);
return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0;
}
@@ -643,7 +655,8 @@ void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
for (int i = 0; i < infos->length(); i++) {
RelocInfo reloc_entry = (*infos)[i];
Address target_address = reloc_entry.target_address();
- unsigned ast_id = static_cast<unsigned>((*infos)[i].data());
+ TypeFeedbackId ast_id =
+ TypeFeedbackId(static_cast<unsigned>((*infos)[i].data()));
Code* target = Code::GetCodeFromTargetAddress(target_address);
switch (target->kind()) {
case Code::LOAD_IC:
@@ -659,7 +672,7 @@ void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
if (map == NULL) {
SetInfo(ast_id, static_cast<Object*>(target));
} else if (!CanRetainOtherContext(Map::cast(map),
- *global_context_)) {
+ *native_context_)) {
SetInfo(ast_id, map);
}
}
@@ -696,21 +709,22 @@ void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> code) {
Handle<TypeFeedbackCells> cache(
TypeFeedbackInfo::cast(raw_info)->type_feedback_cells());
for (int i = 0; i < cache->CellCount(); i++) {
- unsigned ast_id = cache->AstId(i)->value();
+ TypeFeedbackId ast_id = cache->AstId(i);
Object* value = cache->Cell(i)->value();
if (value->IsSmi() ||
(value->IsJSFunction() &&
!CanRetainOtherContext(JSFunction::cast(value),
- *global_context_))) {
+ *native_context_))) {
SetInfo(ast_id, value);
}
}
}
-void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) {
- ASSERT(dictionary_->FindEntry(ast_id) == UnseededNumberDictionary::kNotFound);
- MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target);
+void TypeFeedbackOracle::SetInfo(TypeFeedbackId ast_id, Object* target) {
+ ASSERT(dictionary_->FindEntry(IdToKey(ast_id)) ==
+ UnseededNumberDictionary::kNotFound);
+ MaybeObject* maybe_result = dictionary_->AtNumberPut(IdToKey(ast_id), target);
USE(maybe_result);
#ifdef DEBUG
Object* result = NULL;
diff --git a/deps/v8/src/type-info.h b/deps/v8/src/type-info.h
index 74910cd1a..00d88c2af 100644
--- a/deps/v8/src/type-info.h
+++ b/deps/v8/src/type-info.h
@@ -232,18 +232,18 @@ class UnaryOperation;
class ForInStatement;
-class TypeFeedbackOracle BASE_EMBEDDED {
+class TypeFeedbackOracle: public ZoneObject {
public:
TypeFeedbackOracle(Handle<Code> code,
- Handle<Context> global_context,
+ Handle<Context> native_context,
Isolate* isolate,
Zone* zone);
bool LoadIsMonomorphicNormal(Property* expr);
bool LoadIsUninitialized(Property* expr);
bool LoadIsMegamorphicWithTypeInfo(Property* expr);
- bool StoreIsMonomorphicNormal(Expression* expr);
- bool StoreIsMegamorphicWithTypeInfo(Expression* expr);
+ bool StoreIsMonomorphicNormal(TypeFeedbackId ast_id);
+ bool StoreIsMegamorphicWithTypeInfo(TypeFeedbackId ast_id);
bool CallIsMonomorphic(Call* expr);
bool CallNewIsMonomorphic(CallNew* expr);
bool ObjectLiteralStoreIsMonomorphic(ObjectLiteral::Property* prop);
@@ -251,7 +251,7 @@ class TypeFeedbackOracle BASE_EMBEDDED {
bool IsForInFastCase(ForInStatement* expr);
Handle<Map> LoadMonomorphicReceiverType(Property* expr);
- Handle<Map> StoreMonomorphicReceiverType(Expression* expr);
+ Handle<Map> StoreMonomorphicReceiverType(TypeFeedbackId ast_id);
void LoadReceiverTypes(Property* expr,
Handle<String> name,
@@ -263,12 +263,12 @@ class TypeFeedbackOracle BASE_EMBEDDED {
Handle<String> name,
CallKind call_kind,
SmallMapList* types);
- void CollectKeyedReceiverTypes(unsigned ast_id,
+ void CollectKeyedReceiverTypes(TypeFeedbackId ast_id,
SmallMapList* types);
- static bool CanRetainOtherContext(Map* map, Context* global_context);
+ static bool CanRetainOtherContext(Map* map, Context* native_context);
static bool CanRetainOtherContext(JSFunction* function,
- Context* global_context);
+ Context* native_context);
CheckType GetCallCheckType(Call* expr);
Handle<JSObject> GetPrototypeForPrimitiveCheck(CheckType check);
@@ -283,7 +283,7 @@ class TypeFeedbackOracle BASE_EMBEDDED {
// TODO(1571) We can't use ToBooleanStub::Types as the return value because
// of various cylces in our headers. Death to tons of implementations in
// headers!! :-P
- byte ToBooleanTypes(unsigned ast_id);
+ byte ToBooleanTypes(TypeFeedbackId ast_id);
// Get type information for arithmetic operations and compares.
TypeInfo UnaryType(UnaryOperation* expr);
@@ -297,12 +297,12 @@ class TypeFeedbackOracle BASE_EMBEDDED {
Zone* zone() const { return zone_; }
private:
- void CollectReceiverTypes(unsigned ast_id,
+ void CollectReceiverTypes(TypeFeedbackId ast_id,
Handle<String> name,
Code::Flags flags,
SmallMapList* types);
- void SetInfo(unsigned ast_id, Object* target);
+ void SetInfo(TypeFeedbackId ast_id, Object* target);
void BuildDictionary(Handle<Code> code);
void GetRelocInfos(Handle<Code> code, ZoneList<RelocInfo>* infos);
@@ -315,9 +315,9 @@ class TypeFeedbackOracle BASE_EMBEDDED {
// Returns an element from the backing store. Returns undefined if
// there is no information.
- Handle<Object> GetInfo(unsigned ast_id);
+ Handle<Object> GetInfo(TypeFeedbackId ast_id);
- Handle<Context> global_context_;
+ Handle<Context> native_context_;
Isolate* isolate_;
Handle<UnseededNumberDictionary> dictionary_;
Zone* zone_;
diff --git a/deps/v8/src/unicode-inl.h b/deps/v8/src/unicode-inl.h
index 9c0ebf9e1..ec9c69f8d 100644
--- a/deps/v8/src/unicode-inl.h
+++ b/deps/v8/src/unicode-inl.h
@@ -29,6 +29,7 @@
#define V8_UNICODE_INL_H_
#include "unicode.h"
+#include "checks.h"
namespace unibrow {
@@ -144,6 +145,7 @@ uchar CharacterStream::GetNext() {
} else {
remaining_--;
}
+ ASSERT(BoundsCheck(cursor_));
return result;
}
diff --git a/deps/v8/src/unicode.h b/deps/v8/src/unicode.h
index 94ab1b4c1..91b16c9f3 100644
--- a/deps/v8/src/unicode.h
+++ b/deps/v8/src/unicode.h
@@ -201,6 +201,7 @@ class CharacterStream {
protected:
virtual void FillBuffer() = 0;
+ virtual bool BoundsCheck(unsigned offset) = 0;
// The number of characters left in the current buffer
unsigned remaining_;
// The current offset within the buffer
@@ -228,6 +229,9 @@ class InputBuffer : public CharacterStream {
InputBuffer() { }
explicit InputBuffer(Input input) { Reset(input); }
virtual void FillBuffer();
+ virtual bool BoundsCheck(unsigned offset) {
+ return (buffer_ != util_buffer_) || (offset < kSize);
+ }
// A custom offset that can be used by the string implementation to
// mark progress within the encoded string.
diff --git a/deps/v8/src/utils.h b/deps/v8/src/utils.h
index f116c14db..e03f96f6e 100644
--- a/deps/v8/src/utils.h
+++ b/deps/v8/src/utils.h
@@ -248,6 +248,7 @@ class BitField {
// bitfield without compiler warnings we have to compute 2^32 without
// using a shift count of 32.
static const uint32_t kMask = ((1U << shift) << size) - (1U << shift);
+ static const uint32_t kShift = shift;
// Value for the field with all bits set.
static const T kMax = static_cast<T>((1U << size) - 1);
@@ -861,7 +862,11 @@ class EmbeddedContainer {
public:
EmbeddedContainer() : elems_() { }
- int length() { return NumElements; }
+ int length() const { return NumElements; }
+ const ElementType& operator[](int i) const {
+ ASSERT(i < length());
+ return elems_[i];
+ }
ElementType& operator[](int i) {
ASSERT(i < length());
return elems_[i];
@@ -875,7 +880,12 @@ class EmbeddedContainer {
template<typename ElementType>
class EmbeddedContainer<ElementType, 0> {
public:
- int length() { return 0; }
+ int length() const { return 0; }
+ const ElementType& operator[](int i) const {
+ UNREACHABLE();
+ static ElementType t = 0;
+ return t;
+ }
ElementType& operator[](int i) {
UNREACHABLE();
static ElementType t = 0;
@@ -973,13 +983,59 @@ class EnumSet {
T Mask(E element) const {
// The strange typing in ASSERT is necessary to avoid stupid warnings, see:
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43680
- ASSERT(element < static_cast<int>(sizeof(T) * CHAR_BIT));
+ ASSERT(static_cast<int>(element) < static_cast<int>(sizeof(T) * CHAR_BIT));
return 1 << element;
}
T bits_;
};
+
+class TypeFeedbackId {
+ public:
+ explicit TypeFeedbackId(int id) : id_(id) { }
+ int ToInt() const { return id_; }
+
+ static TypeFeedbackId None() { return TypeFeedbackId(kNoneId); }
+ bool IsNone() const { return id_ == kNoneId; }
+
+ private:
+ static const int kNoneId = -1;
+
+ int id_;
+};
+
+
+class BailoutId {
+ public:
+ explicit BailoutId(int id) : id_(id) { }
+ int ToInt() const { return id_; }
+
+ static BailoutId None() { return BailoutId(kNoneId); }
+ static BailoutId FunctionEntry() { return BailoutId(kFunctionEntryId); }
+ static BailoutId Declarations() { return BailoutId(kDeclarationsId); }
+ static BailoutId FirstUsable() { return BailoutId(kFirstUsableId); }
+
+ bool IsNone() const { return id_ == kNoneId; }
+ bool operator==(const BailoutId& other) const { return id_ == other.id_; }
+
+ private:
+ static const int kNoneId = -1;
+
+ // Using 0 could disguise errors.
+ static const int kFunctionEntryId = 2;
+
+ // This AST id identifies the point after the declarations have been visited.
+ // We need it to capture the environment effects of declarations that emit
+ // code (function declarations).
+ static const int kDeclarationsId = 3;
+
+ // Ever FunctionState starts with this id.
+ static const int kFirstUsableId = 4;
+
+ int id_;
+};
+
} } // namespace v8::internal
#endif // V8_UTILS_H_
diff --git a/deps/v8/src/v8-counters.cc b/deps/v8/src/v8-counters.cc
index c6aa9cb7f..3f83dffca 100644
--- a/deps/v8/src/v8-counters.cc
+++ b/deps/v8/src/v8-counters.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -34,11 +34,23 @@ namespace internal {
Counters::Counters() {
#define HT(name, caption) \
- HistogramTimer name = { #caption, NULL, false, 0, 0 }; \
+ HistogramTimer name = { {#caption, 0, 10000, 50, NULL, false}, 0, 0 }; \
name##_ = name;
HISTOGRAM_TIMER_LIST(HT)
#undef HT
+#define HP(name, caption) \
+ Histogram name = { #caption, 0, 101, 100, NULL, false }; \
+ name##_ = name;
+ HISTOGRAM_PERCENTAGE_LIST(HP)
+#undef HP
+
+#define HM(name, caption) \
+ Histogram name = { #caption, 1000, 500000, 50, NULL, false }; \
+ name##_ = name;
+ HISTOGRAM_MEMORY_LIST(HM)
+#undef HM
+
#define SC(name, caption) \
StatsCounter name = { "c:" #caption, NULL, false };\
name##_ = name;
@@ -47,6 +59,34 @@ Counters::Counters() {
STATS_COUNTER_LIST_2(SC)
#undef SC
+#define SC(name) \
+ StatsCounter count_of_##name = { "c:" "V8.CountOf_" #name, NULL, false };\
+ count_of_##name##_ = count_of_##name; \
+ StatsCounter size_of_##name = { "c:" "V8.SizeOf_" #name, NULL, false };\
+ size_of_##name##_ = size_of_##name;
+ INSTANCE_TYPE_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter count_of_CODE_TYPE_##name = { \
+ "c:" "V8.CountOf_CODE_TYPE-" #name, NULL, false }; \
+ count_of_CODE_TYPE_##name##_ = count_of_CODE_TYPE_##name; \
+ StatsCounter size_of_CODE_TYPE_##name = { \
+ "c:" "V8.SizeOf_CODE_TYPE-" #name, NULL, false }; \
+ size_of_CODE_TYPE_##name##_ = size_of_CODE_TYPE_##name;
+ CODE_KIND_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter count_of_FIXED_ARRAY_##name = { \
+ "c:" "V8.CountOf_FIXED_ARRAY-" #name, NULL, false }; \
+ count_of_FIXED_ARRAY_##name##_ = count_of_FIXED_ARRAY_##name; \
+ StatsCounter size_of_FIXED_ARRAY_##name = { \
+ "c:" "V8.SizeOf_FIXED_ARRAY-" #name, NULL, false }; \
+ size_of_FIXED_ARRAY_##name##_ = size_of_FIXED_ARRAY_##name;
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
+#undef SC
+
StatsCounter state_counters[] = {
#define COUNTER_NAME(name) \
{ "c:V8.State" #name, NULL, false },
@@ -59,4 +99,18 @@ Counters::Counters() {
}
}
+void Counters::ResetHistograms() {
+#define HT(name, caption) name##_.Reset();
+ HISTOGRAM_TIMER_LIST(HT)
+#undef HT
+
+#define HP(name, caption) name##_.Reset();
+ HISTOGRAM_PERCENTAGE_LIST(HP)
+#undef HP
+
+#define HM(name, caption) name##_.Reset();
+ HISTOGRAM_MEMORY_LIST(HM)
+#undef HM
+}
+
} } // namespace v8::internal
diff --git a/deps/v8/src/v8-counters.h b/deps/v8/src/v8-counters.h
index 6db9c77ed..fad345481 100644
--- a/deps/v8/src/v8-counters.h
+++ b/deps/v8/src/v8-counters.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -30,6 +30,7 @@
#include "allocation.h"
#include "counters.h"
+#include "objects.h"
#include "v8globals.h"
namespace v8 {
@@ -50,6 +51,36 @@ namespace internal {
HT(compile_lazy, V8.CompileLazy)
+#define HISTOGRAM_PERCENTAGE_LIST(HP) \
+ HP(external_fragmentation_total, \
+ V8.MemoryExternalFragmentationTotal) \
+ HP(external_fragmentation_old_pointer_space, \
+ V8.MemoryExternalFragmentationOldPointerSpace) \
+ HP(external_fragmentation_old_data_space, \
+ V8.MemoryExternalFragmentationOldDataSpace) \
+ HP(external_fragmentation_code_space, \
+ V8.MemoryExternalFragmentationCodeSpace) \
+ HP(external_fragmentation_map_space, \
+ V8.MemoryExternalFragmentationMapSpace) \
+ HP(external_fragmentation_cell_space, \
+ V8.MemoryExternalFragmentationCellSpace) \
+ HP(external_fragmentation_lo_space, \
+ V8.MemoryExternalFragmentationLoSpace) \
+ HP(heap_fraction_map_space, \
+ V8.MemoryHeapFractionMapSpace) \
+ HP(heap_fraction_cell_space, \
+ V8.MemoryHeapFractionCellSpace) \
+
+
+#define HISTOGRAM_MEMORY_LIST(HM) \
+ HM(heap_sample_total_committed, V8.MemoryHeapSampleTotalCommitted) \
+ HM(heap_sample_total_used, V8.MemoryHeapSampleTotalUsed) \
+ HM(heap_sample_map_space_committed, \
+ V8.MemoryHeapSampleMapSpaceCommitted) \
+ HM(heap_sample_cell_space_committed, \
+ V8.MemoryHeapSampleCellSpaceCommitted)
+
+
// WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC
// Intellisense to crash. It was broken into two macros (each of length 40
// lines) rather than one macro (of length about 80 lines) to work around
@@ -210,6 +241,9 @@ namespace internal {
SC(compute_entry_frame, V8.ComputeEntryFrame) \
SC(generic_binary_stub_calls, V8.GenericBinaryStubCalls) \
SC(generic_binary_stub_calls_regs, V8.GenericBinaryStubCallsRegs) \
+ SC(fast_new_closure_total, V8.FastNewClosureTotal) \
+ SC(fast_new_closure_try_optimized, V8.FastNewClosureTryOptimized) \
+ SC(fast_new_closure_install_optimized, V8.FastNewClosureInstallOptimized) \
SC(string_add_runtime, V8.StringAddRuntime) \
SC(string_add_native, V8.StringAddNative) \
SC(string_add_runtime_ext_to_ascii, V8.StringAddRuntimeExtToAscii) \
@@ -240,14 +274,33 @@ namespace internal {
SC(transcendental_cache_miss, V8.TranscendentalCacheMiss) \
SC(stack_interrupts, V8.StackInterrupts) \
SC(runtime_profiler_ticks, V8.RuntimeProfilerTicks) \
- SC(other_ticks, V8.OtherTicks) \
- SC(js_opt_ticks, V8.JsOptTicks) \
- SC(js_non_opt_ticks, V8.JsNonoptTicks) \
- SC(js_other_ticks, V8.JsOtherTicks) \
SC(smi_checks_removed, V8.SmiChecksRemoved) \
SC(map_checks_removed, V8.MapChecksRemoved) \
SC(quote_json_char_count, V8.QuoteJsonCharacterCount) \
- SC(quote_json_char_recount, V8.QuoteJsonCharacterReCount)
+ SC(quote_json_char_recount, V8.QuoteJsonCharacterReCount) \
+ SC(new_space_bytes_available, V8.MemoryNewSpaceBytesAvailable) \
+ SC(new_space_bytes_committed, V8.MemoryNewSpaceBytesCommitted) \
+ SC(new_space_bytes_used, V8.MemoryNewSpaceBytesUsed) \
+ SC(old_pointer_space_bytes_available, \
+ V8.MemoryOldPointerSpaceBytesAvailable) \
+ SC(old_pointer_space_bytes_committed, \
+ V8.MemoryOldPointerSpaceBytesCommitted) \
+ SC(old_pointer_space_bytes_used, V8.MemoryOldPointerSpaceBytesUsed) \
+ SC(old_data_space_bytes_available, V8.MemoryOldDataSpaceBytesAvailable) \
+ SC(old_data_space_bytes_committed, V8.MemoryOldDataSpaceBytesCommitted) \
+ SC(old_data_space_bytes_used, V8.MemoryOldDataSpaceBytesUsed) \
+ SC(code_space_bytes_available, V8.MemoryCodeSpaceBytesAvailable) \
+ SC(code_space_bytes_committed, V8.MemoryCodeSpaceBytesCommitted) \
+ SC(code_space_bytes_used, V8.MemoryCodeSpaceBytesUsed) \
+ SC(map_space_bytes_available, V8.MemoryMapSpaceBytesAvailable) \
+ SC(map_space_bytes_committed, V8.MemoryMapSpaceBytesCommitted) \
+ SC(map_space_bytes_used, V8.MemoryMapSpaceBytesUsed) \
+ SC(cell_space_bytes_available, V8.MemoryCellSpaceBytesAvailable) \
+ SC(cell_space_bytes_committed, V8.MemoryCellSpaceBytesCommitted) \
+ SC(cell_space_bytes_used, V8.MemoryCellSpaceBytesUsed) \
+ SC(lo_space_bytes_available, V8.MemoryLoSpaceBytesAvailable) \
+ SC(lo_space_bytes_committed, V8.MemoryLoSpaceBytesCommitted) \
+ SC(lo_space_bytes_used, V8.MemoryLoSpaceBytesUsed)
// This file contains all the v8 counters that are in use.
@@ -258,20 +311,69 @@ class Counters {
HISTOGRAM_TIMER_LIST(HT)
#undef HT
+#define HP(name, caption) \
+ Histogram* name() { return &name##_; }
+ HISTOGRAM_PERCENTAGE_LIST(HP)
+#undef HP
+
+#define HM(name, caption) \
+ Histogram* name() { return &name##_; }
+ HISTOGRAM_MEMORY_LIST(HM)
+#undef HM
+
#define SC(name, caption) \
StatsCounter* name() { return &name##_; }
STATS_COUNTER_LIST_1(SC)
STATS_COUNTER_LIST_2(SC)
#undef SC
+#define SC(name) \
+ StatsCounter* count_of_##name() { return &count_of_##name##_; } \
+ StatsCounter* size_of_##name() { return &size_of_##name##_; }
+ INSTANCE_TYPE_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter* count_of_CODE_TYPE_##name() \
+ { return &count_of_CODE_TYPE_##name##_; } \
+ StatsCounter* size_of_CODE_TYPE_##name() \
+ { return &size_of_CODE_TYPE_##name##_; }
+ CODE_KIND_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter* count_of_FIXED_ARRAY_##name() \
+ { return &count_of_FIXED_ARRAY_##name##_; } \
+ StatsCounter* size_of_FIXED_ARRAY_##name() \
+ { return &size_of_FIXED_ARRAY_##name##_; }
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
+#undef SC
+
enum Id {
#define RATE_ID(name, caption) k_##name,
HISTOGRAM_TIMER_LIST(RATE_ID)
#undef RATE_ID
+#define PERCENTAGE_ID(name, caption) k_##name,
+ HISTOGRAM_PERCENTAGE_LIST(PERCENTAGE_ID)
+#undef PERCENTAGE_ID
+#define MEMORY_ID(name, caption) k_##name,
+ HISTOGRAM_MEMORY_LIST(MEMORY_ID)
+#undef MEMORY_ID
#define COUNTER_ID(name, caption) k_##name,
STATS_COUNTER_LIST_1(COUNTER_ID)
STATS_COUNTER_LIST_2(COUNTER_ID)
#undef COUNTER_ID
+#define COUNTER_ID(name) kCountOf##name, kSizeOf##name,
+ INSTANCE_TYPE_LIST(COUNTER_ID)
+#undef COUNTER_ID
+#define COUNTER_ID(name) kCountOfCODE_TYPE_##name, \
+ kSizeOfCODE_TYPE_##name,
+ CODE_KIND_LIST(COUNTER_ID)
+#undef COUNTER_ID
+#define COUNTER_ID(name) kCountOfFIXED_ARRAY__##name, \
+ kSizeOfFIXED_ARRAY__##name,
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COUNTER_ID)
+#undef COUNTER_ID
#define COUNTER_ID(name) k_##name,
STATE_TAG_LIST(COUNTER_ID)
#undef COUNTER_ID
@@ -282,18 +384,48 @@ class Counters {
return &state_counters_[state];
}
+ void ResetHistograms();
+
private:
#define HT(name, caption) \
HistogramTimer name##_;
HISTOGRAM_TIMER_LIST(HT)
#undef HT
+#define HP(name, caption) \
+ Histogram name##_;
+ HISTOGRAM_PERCENTAGE_LIST(HP)
+#undef HP
+
+#define HM(name, caption) \
+ Histogram name##_;
+ HISTOGRAM_MEMORY_LIST(HM)
+#undef HM
+
#define SC(name, caption) \
StatsCounter name##_;
STATS_COUNTER_LIST_1(SC)
STATS_COUNTER_LIST_2(SC)
#undef SC
+#define SC(name) \
+ StatsCounter size_of_##name##_; \
+ StatsCounter count_of_##name##_;
+ INSTANCE_TYPE_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter size_of_CODE_TYPE_##name##_; \
+ StatsCounter count_of_CODE_TYPE_##name##_;
+ CODE_KIND_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter size_of_FIXED_ARRAY_##name##_; \
+ StatsCounter count_of_FIXED_ARRAY_##name##_;
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
+#undef SC
+
enum {
#define COUNTER_ID(name) __##name,
STATE_TAG_LIST(COUNTER_ID)
diff --git a/deps/v8/src/v8.cc b/deps/v8/src/v8.cc
index 2910a0700..2407037b3 100644
--- a/deps/v8/src/v8.cc
+++ b/deps/v8/src/v8.cc
@@ -106,13 +106,16 @@ void V8::TearDown() {
if (!has_been_set_up_ || has_been_disposed_) return;
+ // The isolate has to be torn down before clearing the LOperand
+ // caches so that the optimizing compiler thread (if running)
+ // doesn't see an inconsistent view of the lithium instructions.
+ isolate->TearDown();
+ delete isolate;
+
ElementsAccessor::TearDown();
LOperand::TearDownCaches();
RegisteredExtension::UnregisterAll();
- isolate->TearDown();
- delete isolate;
-
is_running_ = false;
has_been_disposed_ = true;
@@ -166,7 +169,7 @@ void V8::SetReturnAddressLocationResolver(
// Used by JavaScript APIs
uint32_t V8::Random(Context* context) {
- ASSERT(context->IsGlobalContext());
+ ASSERT(context->IsNativeContext());
ByteArray* seed = context->random_seed();
return random_base(reinterpret_cast<uint32_t*>(seed->GetDataStartAddress()));
}
diff --git a/deps/v8/src/v8globals.h b/deps/v8/src/v8globals.h
index 4dec1830d..95390adcf 100644
--- a/deps/v8/src/v8globals.h
+++ b/deps/v8/src/v8globals.h
@@ -52,15 +52,6 @@ const intptr_t kPointerAlignmentMask = kPointerAlignment - 1;
const intptr_t kDoubleAlignment = 8;
const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1;
-// Desired alignment for maps.
-#if V8_HOST_ARCH_64_BIT
-const intptr_t kMapAlignmentBits = kObjectAlignmentBits;
-#else
-const intptr_t kMapAlignmentBits = kObjectAlignmentBits + 3;
-#endif
-const intptr_t kMapAlignment = (1 << kMapAlignmentBits);
-const intptr_t kMapAlignmentMask = kMapAlignment - 1;
-
// Desired alignment for generated code is 32 bytes (to improve cache line
// utilization).
const int kCodeAlignmentBits = 5;
@@ -94,6 +85,7 @@ const uint32_t kDebugZapValue = 0xbadbaddb;
const uint32_t kFreeListZapValue = 0xfeed1eaf;
#endif
+const int kCodeZapValue = 0xbadc0de;
// Number of bits to represent the page size for paged spaces. The value of 20
// gives 1Mb bytes per page.
@@ -126,6 +118,7 @@ class Debugger;
class DebugInfo;
class Descriptor;
class DescriptorArray;
+class TransitionArray;
class ExternalReference;
class FixedArray;
class FunctionTemplateInfo;
@@ -311,14 +304,6 @@ typedef void (*StoreBufferCallback)(Heap* heap,
StoreBufferEvent event);
-// Whether to remove map transitions and constant transitions from a
-// DescriptorArray.
-enum TransitionFlag {
- REMOVE_TRANSITIONS,
- KEEP_TRANSITIONS
-};
-
-
// Union used for fast testing of specific double values.
union DoubleRepresentation {
double value;
@@ -366,11 +351,12 @@ struct AccessorDescriptor {
// VMState object leaves a state by popping the current state from the
// stack.
-#define STATE_TAG_LIST(V) \
- V(JS) \
- V(GC) \
- V(COMPILER) \
- V(OTHER) \
+#define STATE_TAG_LIST(V) \
+ V(JS) \
+ V(GC) \
+ V(COMPILER) \
+ V(PARALLEL_COMPILER_PROLOGUE) \
+ V(OTHER) \
V(EXTERNAL)
enum StateTag {
@@ -401,10 +387,6 @@ enum StateTag {
#define POINTER_SIZE_ALIGN(value) \
(((value) + kPointerAlignmentMask) & ~kPointerAlignmentMask)
-// MAP_POINTER_ALIGN returns the value aligned as a map pointer.
-#define MAP_POINTER_ALIGN(value) \
- (((value) + kMapAlignmentMask) & ~kMapAlignmentMask)
-
// CODE_POINTER_ALIGN returns the value aligned as a generated code segment.
#define CODE_POINTER_ALIGN(value) \
(((value) + kCodeAlignmentMask) & ~kCodeAlignmentMask)
@@ -430,6 +412,13 @@ enum StateTag {
#endif
+enum CpuImplementer {
+ UNKNOWN_IMPLEMENTER,
+ ARM_IMPLEMENTER,
+ QUALCOMM_IMPLEMENTER
+};
+
+
// Feature flags bit positions. They are mostly based on the CPUID spec.
// (We assign CPUID itself to one of the currently reserved bits --
// feel free to change this if needed.)
@@ -443,6 +432,9 @@ enum CpuFeature { SSE4_1 = 32 + 19, // x86
VFP3 = 1, // ARM
ARMv7 = 2, // ARM
VFP2 = 3, // ARM
+ SUDIV = 4, // ARM
+ UNALIGNED_ACCESSES = 5, // ARM
+ MOVW_MOVT_IMMEDIATE_LOADS = 6, // ARM
SAHF = 0, // x86
FPU = 1}; // MIPS
@@ -484,16 +476,17 @@ const uint64_t kLastNonNaNInt64 =
(static_cast<uint64_t>(kNaNOrInfinityLowerBoundUpper32) << 32);
+// The order of this enum has to be kept in sync with the predicates below.
enum VariableMode {
// User declared variables:
VAR, // declared via 'var', and 'function' declarations
CONST, // declared via 'const' declarations
- CONST_HARMONY, // declared via 'const' declarations in harmony mode
-
LET, // declared via 'let' declarations
+ CONST_HARMONY, // declared via 'const' declarations in harmony mode
+
// Variables introduced by the compiler:
DYNAMIC, // always require dynamic lookup (we don't know
// the declaration)
@@ -515,6 +508,26 @@ enum VariableMode {
};
+inline bool IsDynamicVariableMode(VariableMode mode) {
+ return mode >= DYNAMIC && mode <= DYNAMIC_LOCAL;
+}
+
+
+inline bool IsDeclaredVariableMode(VariableMode mode) {
+ return mode >= VAR && mode <= CONST_HARMONY;
+}
+
+
+inline bool IsLexicalVariableMode(VariableMode mode) {
+ return mode >= LET && mode <= CONST_HARMONY;
+}
+
+
+inline bool IsImmutableVariableMode(VariableMode mode) {
+ return mode == CONST || mode == CONST_HARMONY;
+}
+
+
// ES6 Draft Rev3 10.2 specifies declarative environment records with mutable
// and immutable bindings that can be in two states: initialized and
// uninitialized. In ES5 only immutable bindings have these two states. When
diff --git a/deps/v8/src/v8threads.cc b/deps/v8/src/v8threads.cc
index fd8d53640..32ea5e197 100644
--- a/deps/v8/src/v8threads.cc
+++ b/deps/v8/src/v8threads.cc
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -238,12 +238,18 @@ static int ArchiveSpacePerThread() {
ThreadState::ThreadState(ThreadManager* thread_manager)
: id_(ThreadId::Invalid()),
terminate_on_restore_(false),
+ data_(NULL),
next_(this),
previous_(this),
thread_manager_(thread_manager) {
}
+ThreadState::~ThreadState() {
+ DeleteArray<char>(data_);
+}
+
+
void ThreadState::AllocateSpace() {
data_ = NewArray<char>(ArchiveSpacePerThread());
}
@@ -306,8 +312,19 @@ ThreadManager::ThreadManager()
ThreadManager::~ThreadManager() {
delete mutex_;
- delete free_anchor_;
- delete in_use_anchor_;
+ DeleteThreadStateList(free_anchor_);
+ DeleteThreadStateList(in_use_anchor_);
+}
+
+
+void ThreadManager::DeleteThreadStateList(ThreadState* anchor) {
+ // The list starts and ends with the anchor.
+ for (ThreadState* current = anchor->next_; current != anchor;) {
+ ThreadState* next = current->next_;
+ delete current;
+ current = next;
+ }
+ delete anchor;
}
diff --git a/deps/v8/src/v8threads.h b/deps/v8/src/v8threads.h
index a2aee4e33..8dce8602f 100644
--- a/deps/v8/src/v8threads.h
+++ b/deps/v8/src/v8threads.h
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -57,6 +57,7 @@ class ThreadState {
private:
explicit ThreadState(ThreadManager* thread_manager);
+ ~ThreadState();
void AllocateSpace();
@@ -114,6 +115,8 @@ class ThreadManager {
ThreadManager();
~ThreadManager();
+ void DeleteThreadStateList(ThreadState* anchor);
+
void EagerlyArchiveThread();
Mutex* mutex_;
diff --git a/deps/v8/src/v8utils.cc b/deps/v8/src/v8utils.cc
index 042a60f0b..627169e70 100644
--- a/deps/v8/src/v8utils.cc
+++ b/deps/v8/src/v8utils.cc
@@ -53,6 +53,15 @@ void PrintF(FILE* out, const char* format, ...) {
}
+void PrintPID(const char* format, ...) {
+ OS::Print("[%d] ", OS::GetCurrentProcessId());
+ va_list arguments;
+ va_start(arguments, format);
+ OS::VPrint(format, arguments);
+ va_end(arguments);
+}
+
+
void Flush(FILE* out) {
fflush(out);
}
diff --git a/deps/v8/src/v8utils.h b/deps/v8/src/v8utils.h
index bb587e173..111abdf8b 100644
--- a/deps/v8/src/v8utils.h
+++ b/deps/v8/src/v8utils.h
@@ -57,6 +57,9 @@ namespace internal {
void PRINTF_CHECKING PrintF(const char* format, ...);
void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...);
+// Prepends the current process ID to the output.
+void PRINTF_CHECKING PrintPID(const char* format, ...);
+
// Our version of fflush.
void Flush(FILE* out);
@@ -206,6 +209,8 @@ INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars));
template <typename sourcechar, typename sinkchar>
void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
+ ASSERT(chars >= 0);
+ if (chars == 0) return;
sinkchar* limit = dest + chars;
#ifdef V8_HOST_CAN_READ_UNALIGNED
if (sizeof(*dest) == sizeof(*src)) {
diff --git a/deps/v8/src/variables.cc b/deps/v8/src/variables.cc
index 32ad5bc5d..0416f3a39 100644
--- a/deps/v8/src/variables.cc
+++ b/deps/v8/src/variables.cc
@@ -41,7 +41,7 @@ const char* Variable::Mode2String(VariableMode mode) {
switch (mode) {
case VAR: return "VAR";
case CONST: return "CONST";
- case CONST_HARMONY: return "CONST";
+ case CONST_HARMONY: return "CONST_HARMONY";
case LET: return "LET";
case DYNAMIC: return "DYNAMIC";
case DYNAMIC_GLOBAL: return "DYNAMIC_GLOBAL";
@@ -81,10 +81,11 @@ Variable::Variable(Scope* scope,
}
-bool Variable::is_global() const {
+bool Variable::IsGlobalObjectProperty() const {
// Temporaries are never global, they must always be allocated in the
// activation frame.
- return mode_ != TEMPORARY && scope_ != NULL && scope_->is_global_scope();
+ return mode_ != TEMPORARY && !IsLexicalVariableMode(mode_)
+ && scope_ != NULL && scope_->is_global_scope();
}
diff --git a/deps/v8/src/variables.h b/deps/v8/src/variables.h
index f49b6e127..ba26b8047 100644
--- a/deps/v8/src/variables.h
+++ b/deps/v8/src/variables.h
@@ -55,7 +55,7 @@ class Variable: public ZoneObject {
UNALLOCATED,
// A slot in the parameter section on the stack. index() is the
- // parameter index, counting left-to-right. The reciever is index -1;
+ // parameter index, counting left-to-right. The receiver is index -1;
// the first parameter is index 0.
PARAMETER,
@@ -118,21 +118,14 @@ class Variable: public ZoneObject {
bool IsStackAllocated() const { return IsParameter() || IsStackLocal(); }
bool IsContextSlot() const { return location_ == CONTEXT; }
bool IsLookupSlot() const { return location_ == LOOKUP; }
+ bool IsGlobalObjectProperty() const;
- bool is_dynamic() const {
- return (mode_ == DYNAMIC ||
- mode_ == DYNAMIC_GLOBAL ||
- mode_ == DYNAMIC_LOCAL);
- }
- bool is_const_mode() const {
- return (mode_ == CONST ||
- mode_ == CONST_HARMONY);
- }
+ bool is_dynamic() const { return IsDynamicVariableMode(mode_); }
+ bool is_const_mode() const { return IsImmutableVariableMode(mode_); }
bool binding_needs_init() const {
return initialization_flag_ == kNeedsInitialization;
}
- bool is_global() const;
bool is_this() const { return kind_ == THIS; }
bool is_arguments() const { return kind_ == ARGUMENTS; }
diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc
index 48dd5ef3d..213259f5f 100644
--- a/deps/v8/src/version.cc
+++ b/deps/v8/src/version.cc
@@ -33,9 +33,9 @@
// NOTE these macros are used by the SCons build script so their names
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 3
-#define MINOR_VERSION 11
-#define BUILD_NUMBER 10
-#define PATCH_LEVEL 25
+#define MINOR_VERSION 14
+#define BUILD_NUMBER 5
+#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/deps/v8/src/vm-state-inl.h b/deps/v8/src/vm-state-inl.h
index c647e56c9..384940dfa 100644
--- a/deps/v8/src/vm-state-inl.h
+++ b/deps/v8/src/vm-state-inl.h
@@ -47,6 +47,8 @@ inline const char* StateToString(StateTag state) {
return "GC";
case COMPILER:
return "COMPILER";
+ case PARALLEL_COMPILER_PROLOGUE:
+ return "PARALLEL_COMPILER_PROLOGUE";
case OTHER:
return "OTHER";
case EXTERNAL:
diff --git a/deps/v8/src/x64/assembler-x64-inl.h b/deps/v8/src/x64/assembler-x64-inl.h
index a9cc2ef28..d022340c1 100644
--- a/deps/v8/src/x64/assembler-x64-inl.h
+++ b/deps/v8/src/x64/assembler-x64-inl.h
@@ -65,10 +65,10 @@ void Assembler::emitw(uint16_t x) {
void Assembler::emit_code_target(Handle<Code> target,
RelocInfo::Mode rmode,
- unsigned ast_id) {
+ TypeFeedbackId ast_id) {
ASSERT(RelocInfo::IsCodeTarget(rmode));
- if (rmode == RelocInfo::CODE_TARGET && ast_id != kNoASTId) {
- RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, ast_id);
+ if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) {
+ RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, ast_id.ToInt());
} else {
RecordRelocInfo(rmode);
}
@@ -195,6 +195,12 @@ void Assembler::set_target_address_at(Address pc, Address target) {
CPU::FlushICache(pc, sizeof(int32_t));
}
+
+Address Assembler::target_address_from_return_address(Address pc) {
+ return pc - kCallTargetAddressOffset;
+}
+
+
Handle<Object> Assembler::code_target_object_handle_at(Address pc) {
return code_targets_[Memory::int32_at(pc)];
}
@@ -309,10 +315,7 @@ Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
JSGlobalPropertyCell* RelocInfo::target_cell() {
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
- Address address = Memory::Address_at(pc_);
- Object* object = HeapObject::FromAddress(
- address - JSGlobalPropertyCell::kValueOffset);
- return reinterpret_cast<JSGlobalPropertyCell*>(object);
+ return JSGlobalPropertyCell::FromValueAddress(Memory::Address_at(pc_));
}
diff --git a/deps/v8/src/x64/assembler-x64.cc b/deps/v8/src/x64/assembler-x64.cc
index 2f0c542bc..862a73557 100644
--- a/deps/v8/src/x64/assembler-x64.cc
+++ b/deps/v8/src/x64/assembler-x64.cc
@@ -75,6 +75,7 @@ void CpuFeatures::Probe() {
// Save old rsp, since we are going to modify the stack.
__ push(rbp);
__ pushfq();
+ __ push(rdi);
__ push(rcx);
__ push(rbx);
__ movq(rbp, rsp);
@@ -128,6 +129,7 @@ void CpuFeatures::Probe() {
__ movq(rsp, rbp);
__ pop(rbx);
__ pop(rcx);
+ __ pop(rdi);
__ popfq();
__ pop(rbp);
__ ret(0);
@@ -348,7 +350,8 @@ Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
: AssemblerBase(arg_isolate),
code_targets_(100),
positions_recorder_(this),
- emit_debug_code_(FLAG_debug_code) {
+ emit_debug_code_(FLAG_debug_code),
+ predictable_code_size_(false) {
if (buffer == NULL) {
// Do our own buffer management.
if (buffer_size <= kMinimalBufferSize) {
@@ -467,7 +470,7 @@ void Assembler::bind_to(Label* L, int pos) {
static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
ASSERT(offset_to_next <= 0);
int disp = pos - (fixup_pos + sizeof(int8_t));
- ASSERT(is_int8(disp));
+ CHECK(is_int8(disp));
set_byte_at(fixup_pos, disp);
if (offset_to_next < 0) {
L->link_to(fixup_pos + offset_to_next, Label::kNear);
@@ -875,7 +878,7 @@ void Assembler::call(Label* L) {
void Assembler::call(Handle<Code> target,
RelocInfo::Mode rmode,
- unsigned ast_id) {
+ TypeFeedbackId ast_id) {
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
// 1110 1000 #32-bit disp.
@@ -1232,7 +1235,16 @@ void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
const int long_size = 6;
int offs = L->pos() - pc_offset();
ASSERT(offs <= 0);
- if (is_int8(offs - short_size)) {
+ // Determine whether we can use 1-byte offsets for backwards branches,
+ // which have a max range of 128 bytes.
+
+ // We also need to check the predictable_code_size_ flag here, because
+ // on x64, when the full code generator recompiles code for debugging, some
+ // places need to be padded out to a certain size. The debugger is keeping
+ // track of how often it did this so that it can adjust return addresses on
+ // the stack, but if the size of jump instructions can also change, that's
+ // not enough and the calculated offsets would be incorrect.
+ if (is_int8(offs - short_size) && !predictable_code_size_) {
// 0111 tttn #8-bit disp.
emit(0x70 | cc);
emit((offs - short_size) & 0xFF);
@@ -1289,7 +1301,7 @@ void Assembler::jmp(Label* L, Label::Distance distance) {
if (L->is_bound()) {
int offs = L->pos() - pc_offset() - 1;
ASSERT(offs <= 0);
- if (is_int8(offs - short_size)) {
+ if (is_int8(offs - short_size) && !predictable_code_size_) {
// 1110 1011 #8-bit disp.
emit(0xEB);
emit((offs - short_size) & 0xFF);
diff --git a/deps/v8/src/x64/assembler-x64.h b/deps/v8/src/x64/assembler-x64.h
index 9f5f85029..e8b0be9ba 100644
--- a/deps/v8/src/x64/assembler-x64.h
+++ b/deps/v8/src/x64/assembler-x64.h
@@ -455,6 +455,7 @@ class CpuFeatures : public AllStatic {
ASSERT(initialized_);
if (f == SSE2 && !FLAG_enable_sse2) return false;
if (f == SSE3 && !FLAG_enable_sse3) return false;
+ if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
if (f == CMOV && !FLAG_enable_cmov) return false;
if (f == RDTSC && !FLAG_enable_rdtsc) return false;
if (f == SAHF && !FLAG_enable_sahf) return false;
@@ -560,6 +561,11 @@ class Assembler : public AssemblerBase {
// Overrides the default provided by FLAG_debug_code.
void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
+ // Avoids using instructions that vary in size in unpredictable ways between
+ // the snapshot and the running VM. This is needed by the full compiler so
+ // that it can recompile code with debug support and fix the PC.
+ void set_predictable_code_size(bool value) { predictable_code_size_ = value; }
+
// GetCode emits any pending (non-emitted) code and fills the descriptor
// desc. GetCode() is idempotent; it returns the same result if no other
// Assembler functions are invoked in between GetCode() calls.
@@ -575,6 +581,10 @@ class Assembler : public AssemblerBase {
static inline Address target_address_at(Address pc);
static inline void set_target_address_at(Address pc, Address target);
+ // Return the code target address at a call site from the return address
+ // of that call in the instruction stream.
+ static inline Address target_address_from_return_address(Address pc);
+
// This sets the branch destination (which is in the instruction on x64).
// This is for calls and branches within generated code.
inline static void deserialization_set_special_target_at(
@@ -614,6 +624,7 @@ class Assembler : public AssemblerBase {
static const int kCallInstructionLength = 13;
static const int kJSReturnSequenceLength = 13;
static const int kShortCallInstructionLength = 5;
+ static const int kPatchDebugBreakSlotReturnOffset = 4;
// The debug break slot must be able to contain a call instruction.
static const int kDebugBreakSlotLength = kCallInstructionLength;
@@ -1201,7 +1212,7 @@ class Assembler : public AssemblerBase {
void call(Label* L);
void call(Handle<Code> target,
RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
- unsigned ast_id = kNoASTId);
+ TypeFeedbackId ast_id = TypeFeedbackId::None());
// Calls directly to the given address using a relative offset.
// Should only ever be used in Code objects for calls within the
@@ -1432,6 +1443,7 @@ class Assembler : public AssemblerBase {
protected:
bool emit_debug_code() const { return emit_debug_code_; }
+ bool predictable_code_size() const { return predictable_code_size_; }
private:
byte* addr_at(int pos) { return buffer_ + pos; }
@@ -1451,7 +1463,7 @@ class Assembler : public AssemblerBase {
inline void emitw(uint16_t x);
inline void emit_code_target(Handle<Code> target,
RelocInfo::Mode rmode,
- unsigned ast_id = kNoASTId);
+ TypeFeedbackId ast_id = TypeFeedbackId::None());
void emit(Immediate x) { emitl(x.value_); }
// Emits a REX prefix that encodes a 64-bit operand size and
@@ -1636,6 +1648,7 @@ class Assembler : public AssemblerBase {
PositionsRecorder positions_recorder_;
bool emit_debug_code_;
+ bool predictable_code_size_;
friend class PositionsRecorder;
};
diff --git a/deps/v8/src/x64/builtins-x64.cc b/deps/v8/src/x64/builtins-x64.cc
index 0af0a4347..9e4153a86 100644
--- a/deps/v8/src/x64/builtins-x64.cc
+++ b/deps/v8/src/x64/builtins-x64.cc
@@ -73,6 +73,45 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
}
+static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
+ __ movq(kScratchRegister,
+ FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
+ __ movq(kScratchRegister,
+ FieldOperand(kScratchRegister, SharedFunctionInfo::kCodeOffset));
+ __ lea(kScratchRegister, FieldOperand(kScratchRegister, Code::kHeaderSize));
+ __ jmp(kScratchRegister);
+}
+
+
+void Builtins::Generate_InRecompileQueue(MacroAssembler* masm) {
+ GenerateTailCallToSharedCode(masm);
+}
+
+
+void Builtins::Generate_ParallelRecompile(MacroAssembler* masm) {
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ // Push a copy of the function onto the stack.
+ __ push(rdi);
+ // Push call kind information.
+ __ push(rcx);
+
+ __ push(rdi); // Function is also the parameter to the runtime call.
+ __ CallRuntime(Runtime::kParallelRecompile, 1);
+
+ // Restore call kind information.
+ __ pop(rcx);
+ // Restore receiver.
+ __ pop(rdi);
+
+ // Tear down internal frame.
+ }
+
+ GenerateTailCallToSharedCode(masm);
+}
+
+
static void Generate_JSConstructStubHelper(MacroAssembler* masm,
bool is_api_function,
bool count_constructions) {
@@ -711,9 +750,9 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// receiver.
__ bind(&use_global_receiver);
const int kGlobalIndex =
- Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
__ movq(rbx, FieldOperand(rsi, kGlobalIndex));
- __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalContextOffset));
+ __ movq(rbx, FieldOperand(rbx, GlobalObject::kNativeContextOffset));
__ movq(rbx, FieldOperand(rbx, kGlobalIndex));
__ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
@@ -896,9 +935,9 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Use the current global receiver object as the receiver.
__ bind(&use_global_receiver);
const int kGlobalOffset =
- Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
__ movq(rbx, FieldOperand(rsi, kGlobalOffset));
- __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalContextOffset));
+ __ movq(rbx, FieldOperand(rbx, GlobalObject::kNativeContextOffset));
__ movq(rbx, FieldOperand(rbx, kGlobalOffset));
__ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc
index 17b5ce93b..675d404b9 100644
--- a/deps/v8/src/x64/code-stubs-x64.cc
+++ b/deps/v8/src/x64/code-stubs-x64.cc
@@ -62,9 +62,13 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
void FastNewClosureStub::Generate(MacroAssembler* masm) {
// Create a new closure from the given function info in new
// space. Set the context to the current context in rsi.
+ Counters* counters = masm->isolate()->counters();
+
Label gc;
__ AllocateInNewSpace(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT);
+ __ IncrementCounter(counters->fast_new_closure_total(), 1);
+
// Get the function info from the stack.
__ movq(rdx, Operand(rsp, 1 * kPointerSize));
@@ -72,36 +76,113 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) {
? Context::FUNCTION_MAP_INDEX
: Context::STRICT_MODE_FUNCTION_MAP_INDEX;
- // Compute the function map in the current global context and set that
+ // Compute the function map in the current native context and set that
// as the map of the allocated object.
- __ movq(rcx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalContextOffset));
- __ movq(rcx, Operand(rcx, Context::SlotOffset(map_index)));
- __ movq(FieldOperand(rax, JSObject::kMapOffset), rcx);
+ __ movq(rcx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ movq(rcx, FieldOperand(rcx, GlobalObject::kNativeContextOffset));
+ __ movq(rbx, Operand(rcx, Context::SlotOffset(map_index)));
+ __ movq(FieldOperand(rax, JSObject::kMapOffset), rbx);
// Initialize the rest of the function. We don't have to update the
// write barrier because the allocated object is in new space.
__ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex);
- __ LoadRoot(rcx, Heap::kTheHoleValueRootIndex);
+ __ LoadRoot(r8, Heap::kTheHoleValueRootIndex);
__ LoadRoot(rdi, Heap::kUndefinedValueRootIndex);
__ movq(FieldOperand(rax, JSObject::kPropertiesOffset), rbx);
__ movq(FieldOperand(rax, JSObject::kElementsOffset), rbx);
- __ movq(FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset), rcx);
+ __ movq(FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset), r8);
__ movq(FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset), rdx);
__ movq(FieldOperand(rax, JSFunction::kContextOffset), rsi);
__ movq(FieldOperand(rax, JSFunction::kLiteralsOffset), rbx);
- __ movq(FieldOperand(rax, JSFunction::kNextFunctionLinkOffset), rdi);
// Initialize the code pointer in the function to be the one
// found in the shared function info object.
+ // But first check if there is an optimized version for our context.
+ Label check_optimized;
+ Label install_unoptimized;
+ if (FLAG_cache_optimized_code) {
+ __ movq(rbx,
+ FieldOperand(rdx, SharedFunctionInfo::kOptimizedCodeMapOffset));
+ __ testq(rbx, rbx);
+ __ j(not_zero, &check_optimized, Label::kNear);
+ }
+ __ bind(&install_unoptimized);
+ __ movq(FieldOperand(rax, JSFunction::kNextFunctionLinkOffset),
+ rdi); // Initialize with undefined.
__ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
__ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
__ movq(FieldOperand(rax, JSFunction::kCodeEntryOffset), rdx);
+ // Return and remove the on-stack parameter.
+ __ ret(1 * kPointerSize);
+
+ __ bind(&check_optimized);
+
+ __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1);
+
+ // rcx holds native context, ebx points to fixed array of 3-element entries
+ // (native context, optimized code, literals).
+ // The optimized code map must never be empty, so check the first elements.
+ Label install_optimized;
+ // Speculatively move code object into edx.
+ __ movq(rdx, FieldOperand(rbx, FixedArray::kHeaderSize + kPointerSize));
+ __ cmpq(rcx, FieldOperand(rbx, FixedArray::kHeaderSize));
+ __ j(equal, &install_optimized);
+
+ // Iterate through the rest of map backwards. rdx holds an index.
+ Label loop;
+ Label restore;
+ __ movq(rdx, FieldOperand(rbx, FixedArray::kLengthOffset));
+ __ SmiToInteger32(rdx, rdx);
+ __ bind(&loop);
+ // Do not double check first entry.
+ __ cmpq(rdx, Immediate(SharedFunctionInfo::kEntryLength));
+ __ j(equal, &restore);
+ __ subq(rdx, Immediate(SharedFunctionInfo::kEntryLength)); // Skip an entry.
+ __ cmpq(rcx, FieldOperand(rbx,
+ rdx,
+ times_pointer_size,
+ FixedArray::kHeaderSize));
+ __ j(not_equal, &loop, Label::kNear);
+ // Hit: fetch the optimized code.
+ __ movq(rdx, FieldOperand(rbx,
+ rdx,
+ times_pointer_size,
+ FixedArray::kHeaderSize + 1 * kPointerSize));
+
+ __ bind(&install_optimized);
+ __ IncrementCounter(counters->fast_new_closure_install_optimized(), 1);
+
+ // TODO(fschneider): Idea: store proper code pointers in the map and either
+ // unmangle them on marking or do nothing as the whole map is discarded on
+ // major GC anyway.
+ __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
+ __ movq(FieldOperand(rax, JSFunction::kCodeEntryOffset), rdx);
+
+ // Now link a function into a list of optimized functions.
+ __ movq(rdx, ContextOperand(rcx, Context::OPTIMIZED_FUNCTIONS_LIST));
+
+ __ movq(FieldOperand(rax, JSFunction::kNextFunctionLinkOffset), rdx);
+ // No need for write barrier as JSFunction (rax) is in the new space.
+
+ __ movq(ContextOperand(rcx, Context::OPTIMIZED_FUNCTIONS_LIST), rax);
+ // Store JSFunction (rax) into rdx before issuing write barrier as
+ // it clobbers all the registers passed.
+ __ movq(rdx, rax);
+ __ RecordWriteContextSlot(
+ rcx,
+ Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
+ rdx,
+ rbx,
+ kDontSaveFPRegs);
// Return and remove the on-stack parameter.
__ ret(1 * kPointerSize);
+ __ bind(&restore);
+ __ movq(rdx, Operand(rsp, 1 * kPointerSize));
+ __ jmp(&install_unoptimized);
+
// Create a new closure through the slower runtime call.
__ bind(&gc);
__ pop(rcx); // Temporarily remove return address.
@@ -136,8 +217,8 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
__ movq(Operand(rax, Context::SlotOffset(Context::EXTENSION_INDEX)), rbx);
// Copy the global object from the previous context.
- __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ movq(Operand(rax, Context::SlotOffset(Context::GLOBAL_INDEX)), rbx);
+ __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ movq(Operand(rax, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)), rbx);
// Initialize the rest of the slots to undefined.
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
@@ -178,9 +259,9 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister);
__ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length));
- // If this block context is nested in the global context we get a smi
+ // If this block context is nested in the native context we get a smi
// sentinel instead of a function. The block context should get the
- // canonical empty function of the global context as its closure which
+ // canonical empty function of the native context as its closure which
// we still have to look up.
Label after_sentinel;
__ JumpIfNotSmi(rcx, &after_sentinel, Label::kNear);
@@ -190,7 +271,7 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ Assert(equal, message);
}
__ movq(rcx, GlobalObjectOperand());
- __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalContextOffset));
+ __ movq(rcx, FieldOperand(rcx, GlobalObject::kNativeContextOffset));
__ movq(rcx, ContextOperand(rcx, Context::CLOSURE_INDEX));
__ bind(&after_sentinel);
@@ -200,8 +281,8 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ movq(ContextOperand(rax, Context::EXTENSION_INDEX), rbx);
// Copy the global object from the previous context.
- __ movq(rbx, ContextOperand(rsi, Context::GLOBAL_INDEX));
- __ movq(ContextOperand(rax, Context::GLOBAL_INDEX), rbx);
+ __ movq(rbx, ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX));
+ __ movq(ContextOperand(rax, Context::GLOBAL_OBJECT_INDEX), rbx);
// Initialize the rest of the slots to the hole value.
__ LoadRoot(rbx, Heap::kTheHoleValueRootIndex);
@@ -1216,11 +1297,9 @@ void BinaryOpStub::GenerateFloatingPointCode(MacroAssembler* masm,
&allocation_failed,
TAG_OBJECT);
// Set the map.
- if (FLAG_debug_code) {
- __ AbortIfNotRootValue(heap_number_map,
- Heap::kHeapNumberMapRootIndex,
- "HeapNumberMap register clobbered.");
- }
+ __ AssertRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
__ movq(FieldOperand(rax, HeapObject::kMapOffset),
heap_number_map);
__ cvtqsi2sd(xmm0, rbx);
@@ -1968,10 +2047,7 @@ void FloatingPointHelper::NumbersToSmis(MacroAssembler* masm,
__ JumpIfSmi(second, (on_success != NULL) ? on_success : &done);
__ bind(&first_smi);
- if (FLAG_debug_code) {
- // Second should be non-smi if we get here.
- __ AbortIfSmi(second);
- }
+ __ AssertNotSmi(second);
__ cmpq(FieldOperand(second, HeapObject::kMapOffset), heap_number_map);
__ j(not_equal, on_not_smis);
// Convert second to smi, if possible.
@@ -2181,21 +2257,28 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ movsd(double_scratch2, double_result); // Load double_exponent with 1.
// Get absolute value of exponent.
- Label no_neg, while_true, no_multiply;
+ Label no_neg, while_true, while_false;
__ testl(scratch, scratch);
__ j(positive, &no_neg, Label::kNear);
__ negl(scratch);
__ bind(&no_neg);
- __ bind(&while_true);
+ __ j(zero, &while_false, Label::kNear);
__ shrl(scratch, Immediate(1));
- __ j(not_carry, &no_multiply, Label::kNear);
- __ mulsd(double_result, double_scratch);
- __ bind(&no_multiply);
+ // Above condition means CF==0 && ZF==0. This means that the
+ // bit that has been shifted out is 0 and the result is not 0.
+ __ j(above, &while_true, Label::kNear);
+ __ movsd(double_result, double_scratch);
+ __ j(zero, &while_false, Label::kNear);
+ __ bind(&while_true);
+ __ shrl(scratch, Immediate(1));
__ mulsd(double_scratch, double_scratch);
+ __ j(above, &while_true, Label::kNear);
+ __ mulsd(double_result, double_scratch);
__ j(not_zero, &while_true);
+ __ bind(&while_false);
// If the exponent is negative, return 1/result.
__ testl(exponent, exponent);
__ j(greater, &done);
@@ -2375,10 +2458,10 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
// rax = address of new object(s) (tagged)
// rcx = argument count (untagged)
- // Get the arguments boilerplate from the current (global) context into rdi.
+ // Get the arguments boilerplate from the current native context into rdi.
Label has_mapped_parameters, copy;
- __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset));
+ __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ movq(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
__ testq(rbx, rbx);
__ j(not_zero, &has_mapped_parameters, Label::kNear);
@@ -2591,9 +2674,9 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Do the allocation of both objects in one go.
__ AllocateInNewSpace(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
- // Get the arguments boilerplate from the current (global) context.
- __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset));
+ // Get the arguments boilerplate from the current native context.
+ __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ movq(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
const int offset =
Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX);
__ movq(rdi, Operand(rdi, offset));
@@ -2710,7 +2793,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Calculate number of capture registers (number_of_captures + 1) * 2.
__ leal(rdx, Operand(rdx, rdx, times_1, 2));
// Check that the static offsets vector buffer is large enough.
- __ cmpl(rdx, Immediate(OffsetsVector::kStaticOffsetsVectorSize));
+ __ cmpl(rdx, Immediate(Isolate::kJSRegexpStaticOffsetsVectorSize));
__ j(above, &runtime);
// rax: RegExp data (FixedArray)
@@ -3122,8 +3205,8 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
// r8: Number of array elements as smi.
// Set JSArray map to global.regexp_result_map().
- __ movq(rdx, ContextOperand(rsi, Context::GLOBAL_INDEX));
- __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalContextOffset));
+ __ movq(rdx, ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX));
+ __ movq(rdx, FieldOperand(rdx, GlobalObject::kNativeContextOffset));
__ movq(rdx, ContextOperand(rdx, Context::REGEXP_RESULT_MAP_INDEX));
__ movq(FieldOperand(rax, HeapObject::kMapOffset), rdx);
@@ -3154,14 +3237,14 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
// Set length.
__ Integer32ToSmi(rdx, rbx);
__ movq(FieldOperand(rcx, FixedArray::kLengthOffset), rdx);
- // Fill contents of fixed-array with the-hole.
- __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
+ // Fill contents of fixed-array with undefined.
+ __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex);
__ lea(rcx, FieldOperand(rcx, FixedArray::kHeaderSize));
- // Fill fixed array elements with hole.
+ // Fill fixed array elements with undefined.
// rax: JSArray.
// rbx: Number of elements in array that remains to be filled, as int32.
// rcx: Start of elements in FixedArray.
- // rdx: the hole.
+ // rdx: undefined.
Label loop;
__ testl(rbx, rbx);
__ bind(&loop);
@@ -5841,8 +5924,7 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
ASSERT(!name.is(r0));
ASSERT(!name.is(r1));
- // Assert that name contains a string.
- if (FLAG_debug_code) __ AbortIfNotString(name);
+ __ AssertString(name);
__ SmiToInteger32(r0, FieldOperand(elements, kCapacityOffset));
__ decl(r0);
@@ -6010,6 +6092,8 @@ struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
{ REG(r11), REG(rax), REG(r15), EMIT_REMEMBERED_SET},
// StoreArrayLiteralElementStub::Generate
{ REG(rbx), REG(rax), REG(rcx), EMIT_REMEMBERED_SET},
+ // FastNewClosureStub::Generate
+ { REG(rcx), REG(rdx), REG(rbx), EMIT_REMEMBERED_SET},
// Null termination.
{ REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET}
};
@@ -6054,6 +6138,11 @@ void RecordWriteStub::GenerateFixedRegStubsAheadOfTime() {
}
+bool CodeStub::CanUseFPRegisters() {
+ return true; // Always have SSE2 on x64.
+}
+
+
// Takes the input in 3 registers: address_ value_ and object_. A pointer to
// the value has just been written into the object, now this stub makes sure
// we keep the GC informed. The word in the object where the value has been
@@ -6186,6 +6275,17 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
Label need_incremental;
Label need_incremental_pop_object;
+ __ movq(regs_.scratch0(), Immediate(~Page::kPageAlignmentMask));
+ __ and_(regs_.scratch0(), regs_.object());
+ __ movq(regs_.scratch1(),
+ Operand(regs_.scratch0(),
+ MemoryChunk::kWriteBarrierCounterOffset));
+ __ subq(regs_.scratch1(), Immediate(1));
+ __ movq(Operand(regs_.scratch0(),
+ MemoryChunk::kWriteBarrierCounterOffset),
+ regs_.scratch1());
+ __ j(negative, &need_incremental);
+
// Let's look at the color of the object: If it is not black we don't have
// to inform the incremental marker.
__ JumpIfBlack(regs_.object(),
@@ -6333,6 +6433,74 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
__ ret(0);
}
+
+void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
+ if (entry_hook_ != NULL) {
+ ProfileEntryHookStub stub;
+ masm->CallStub(&stub);
+ }
+}
+
+
+void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
+ // Save volatile registers.
+ // Live registers at this point are the same as at the start of any
+ // JS function:
+ // o rdi: the JS function object being called (i.e. ourselves)
+ // o rsi: our context
+ // o rbp: our caller's frame pointer
+ // o rsp: stack pointer (pointing to return address)
+ // o rcx: rcx is zero for method calls and non-zero for function calls.
+#ifdef _WIN64
+ const int kNumSavedRegisters = 1;
+
+ __ push(rcx);
+#else
+ const int kNumSavedRegisters = 3;
+
+ __ push(rcx);
+ __ push(rdi);
+ __ push(rsi);
+#endif
+
+ // Calculate the original stack pointer and store it in the second arg.
+#ifdef _WIN64
+ __ lea(rdx, Operand(rsp, kNumSavedRegisters * kPointerSize));
+#else
+ __ lea(rsi, Operand(rsp, kNumSavedRegisters * kPointerSize));
+#endif
+
+ // Calculate the function address to the first arg.
+#ifdef _WIN64
+ __ movq(rcx, Operand(rdx, 0));
+ __ subq(rcx, Immediate(Assembler::kShortCallInstructionLength));
+#else
+ __ movq(rdi, Operand(rsi, 0));
+ __ subq(rdi, Immediate(Assembler::kShortCallInstructionLength));
+#endif
+
+ // Call the entry hook function.
+ __ movq(rax, &entry_hook_, RelocInfo::NONE);
+ __ movq(rax, Operand(rax, 0));
+
+ AllowExternalCallThatCantCauseGC scope(masm);
+
+ const int kArgumentCount = 2;
+ __ PrepareCallCFunction(kArgumentCount);
+ __ CallCFunction(rax, kArgumentCount);
+
+ // Restore volatile regs.
+#ifdef _WIN64
+ __ pop(rcx);
+#else
+ __ pop(rsi);
+ __ pop(rdi);
+ __ pop(rcx);
+#endif
+
+ __ Ret();
+}
+
#undef __
} } // namespace v8::internal
diff --git a/deps/v8/src/x64/deoptimizer-x64.cc b/deps/v8/src/x64/deoptimizer-x64.cc
index f3046b9ce..a3fe8f9cf 100644
--- a/deps/v8/src/x64/deoptimizer-x64.cc
+++ b/deps/v8/src/x64/deoptimizer-x64.cc
@@ -52,6 +52,10 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
if (!function->IsOptimized()) return;
+ // The optimized code is going to be patched, so we cannot use it
+ // any more. Play safe and reset the whole cache.
+ function->shared()->ClearOptimizedCodeMap();
+
// Get the optimized code.
Code* code = function->code();
@@ -100,8 +104,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
// ignore all slots that might have been recorded on it.
isolate->heap()->mark_compact_collector()->InvalidateCode(code);
- // Set the code for the function to non-optimized version.
- function->ReplaceCode(function->shared()->code());
+ ReplaceCodeForRelatedFunctions(function, code);
if (FLAG_trace_deopt) {
PrintF("[forced deoptimization: ");
@@ -188,11 +191,11 @@ void Deoptimizer::RevertStackCheckCodeAt(Code* unoptimized_code,
}
-static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) {
+static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) {
ByteArray* translations = data->TranslationByteArray();
int length = data->DeoptCount();
for (int i = 0; i < length; i++) {
- if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) {
+ if (data->AstId(i) == ast_id) {
TranslationIterator it(translations, data->TranslationIndex(i)->value());
int value = it.Next();
ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value));
@@ -214,7 +217,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
// the ast id. Confusing.
ASSERT(bailout_id_ == ast_id);
- int bailout_id = LookupBailoutId(data, ast_id);
+ int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
unsigned translation_index = data->TranslationIndex(bailout_id)->value();
ByteArray* translations = data->TranslationByteArray();
@@ -234,9 +237,9 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
unsigned node_id = iterator.Next();
USE(node_id);
ASSERT(node_id == ast_id);
- JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next()));
- USE(function);
- ASSERT(function == function_);
+ int closure_id = iterator.Next();
+ USE(closure_id);
+ ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
unsigned height = iterator.Next();
unsigned height_in_bytes = height * kPointerSize;
USE(height_in_bytes);
@@ -341,15 +344,15 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
output_[0]->SetPc(pc);
}
Code* continuation =
- function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
+ function_->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
output_[0]->SetContinuation(
reinterpret_cast<intptr_t>(continuation->entry()));
if (FLAG_trace_osr) {
PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
ok ? "finished" : "aborted",
- reinterpret_cast<intptr_t>(function));
- function->PrintName();
+ reinterpret_cast<intptr_t>(function_));
+ function_->PrintName();
PrintF(" => pc=0x%0" V8PRIxPTR "]\n", output_[0]->GetPc());
}
}
@@ -576,16 +579,143 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
}
+void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
+ int frame_index,
+ bool is_setter_stub_frame) {
+ JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ // The receiver (and the implicit return value, if any) are expected in
+ // registers by the LoadIC/StoreIC, so they don't belong to the output stack
+ // frame. This means that we have to use a height of 0.
+ unsigned height = 0;
+ unsigned height_in_bytes = height * kPointerSize;
+ const char* kind = is_setter_stub_frame ? "setter" : "getter";
+ if (FLAG_trace_deopt) {
+ PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes);
+ }
+
+ // We need 1 stack entry for the return address + 4 stack entries from
+ // StackFrame::INTERNAL (FP, context, frame type, code object, see
+ // MacroAssembler::EnterFrame). For a setter stub frame we need one additional
+ // entry for the implicit return value, see
+ // StoreStubCompiler::CompileStoreViaSetter.
+ unsigned fixed_frame_entries = 1 + 4 + (is_setter_stub_frame ? 1 : 0);
+ unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
+ unsigned output_frame_size = height_in_bytes + fixed_frame_size;
+
+ // Allocate and store the output frame description.
+ FrameDescription* output_frame =
+ new(output_frame_size) FrameDescription(output_frame_size, accessor);
+ output_frame->SetFrameType(StackFrame::INTERNAL);
+
+ // A frame for an accessor stub can not be the topmost or bottommost one.
+ ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
+ ASSERT(output_[frame_index] == NULL);
+ output_[frame_index] = output_frame;
+
+ // The top address of the frame is computed from the previous frame's top and
+ // this frame's size.
+ intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
+ output_frame->SetTop(top_address);
+
+ unsigned output_offset = output_frame_size;
+
+ // Read caller's PC from the previous frame.
+ output_offset -= kPointerSize;
+ intptr_t callers_pc = output_[frame_index - 1]->GetPc();
+ output_frame->SetFrameSlot(output_offset, callers_pc);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; caller's pc\n",
+ top_address + output_offset, output_offset, callers_pc);
+ }
+
+ // Read caller's FP from the previous frame, and set this frame's FP.
+ output_offset -= kPointerSize;
+ intptr_t value = output_[frame_index - 1]->GetFp();
+ output_frame->SetFrameSlot(output_offset, value);
+ intptr_t fp_value = top_address + output_offset;
+ output_frame->SetFp(fp_value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; caller's fp\n",
+ fp_value, output_offset, value);
+ }
+
+ // The context can be gotten from the previous frame.
+ output_offset -= kPointerSize;
+ value = output_[frame_index - 1]->GetContext();
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; context\n",
+ top_address + output_offset, output_offset, value);
+ }
+
+ // A marker value is used in place of the function.
+ output_offset -= kPointerSize;
+ value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; function (%s sentinel)\n",
+ top_address + output_offset, output_offset, value, kind);
+ }
+
+ // Get Code object from accessor stub.
+ output_offset -= kPointerSize;
+ Builtins::Name name = is_setter_stub_frame ?
+ Builtins::kStoreIC_Setter_ForDeopt :
+ Builtins::kLoadIC_Getter_ForDeopt;
+ Code* accessor_stub = isolate_->builtins()->builtin(name);
+ value = reinterpret_cast<intptr_t>(accessor_stub);
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+ " ; code object\n",
+ top_address + output_offset, output_offset, value);
+ }
+
+ // Skip receiver.
+ Translation::Opcode opcode =
+ static_cast<Translation::Opcode>(iterator->Next());
+ iterator->Skip(Translation::NumberOfOperandsFor(opcode));
+
+ if (is_setter_stub_frame) {
+ // The implicit return value was part of the artificial setter stub
+ // environment.
+ output_offset -= kPointerSize;
+ DoTranslateCommand(iterator, frame_index, output_offset);
+ }
+
+ ASSERT(0 == output_offset);
+
+ Smi* offset = is_setter_stub_frame ?
+ isolate_->heap()->setter_stub_deopt_pc_offset() :
+ isolate_->heap()->getter_stub_deopt_pc_offset();
+ intptr_t pc = reinterpret_cast<intptr_t>(
+ accessor_stub->instruction_start() + offset->value());
+ output_frame->SetPc(pc);
+}
+
+
void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
int frame_index) {
- int node_id = iterator->Next();
- JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ BailoutId node_id = BailoutId(iterator->Next());
+ JSFunction* function;
+ if (frame_index != 0) {
+ function = JSFunction::cast(ComputeLiteral(iterator->Next()));
+ } else {
+ int closure_id = iterator->Next();
+ USE(closure_id);
+ ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
+ function = function_;
+ }
unsigned height = iterator->Next();
unsigned height_in_bytes = height * kPointerSize;
if (FLAG_trace_deopt) {
PrintF(" translating ");
function->PrintName();
- PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes);
+ PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
}
// The 'fixed' part of the frame consists of the incoming parameters and
diff --git a/deps/v8/src/x64/disasm-x64.cc b/deps/v8/src/x64/disasm-x64.cc
index 073815358..c8606c40b 100644
--- a/deps/v8/src/x64/disasm-x64.cc
+++ b/deps/v8/src/x64/disasm-x64.cc
@@ -703,6 +703,9 @@ int DisassemblerX64::F6F7Instruction(byte* data) {
case 4:
mnem = "mul";
break;
+ case 5:
+ mnem = "imul";
+ break;
case 7:
mnem = "idiv";
break;
diff --git a/deps/v8/src/x64/full-codegen-x64.cc b/deps/v8/src/x64/full-codegen-x64.cc
index a3e42eb50..475fb9de3 100644
--- a/deps/v8/src/x64/full-codegen-x64.cc
+++ b/deps/v8/src/x64/full-codegen-x64.cc
@@ -123,6 +123,8 @@ void FullCodeGenerator::Generate() {
SetFunctionPosition(function());
Comment cmnt(masm_, "[ function compiled by full code generator");
+ ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+
#ifdef DEBUG
if (strlen(FLAG_stop_at) > 0 &&
info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
@@ -172,10 +174,13 @@ void FullCodeGenerator::Generate() {
// Possibly allocate a local context.
int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
if (heap_slots > 0) {
- Comment cmnt(masm_, "[ Allocate local context");
+ Comment cmnt(masm_, "[ Allocate context");
// Argument to NewContext is the function, which is still in rdi.
__ push(rdi);
- if (heap_slots <= FastNewContextStub::kMaximumSlots) {
+ if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+ __ Push(info->scope()->GetScopeInfo());
+ __ CallRuntime(Runtime::kNewGlobalContext, 2);
+ } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
FastNewContextStub stub(heap_slots);
__ CallStub(&stub);
} else {
@@ -252,7 +257,7 @@ void FullCodeGenerator::Generate() {
scope()->VisitIllegalRedeclaration(this);
} else {
- PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
+ PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
{ Comment cmnt(masm_, "[ Declarations");
// For named function expressions, declare the function name as a
// constant.
@@ -267,7 +272,7 @@ void FullCodeGenerator::Generate() {
}
{ Comment cmnt(masm_, "[ Stack check");
- PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
+ PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
Label ok;
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);
__ j(above_equal, &ok, Label::kNear);
@@ -310,10 +315,6 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
// Self-optimization is a one-off thing; if it fails, don't try again.
reset_value = Smi::kMaxValue;
}
- if (isolate()->IsDebuggerActive()) {
- // Detect debug break requests as soon as possible.
- reset_value = 10;
- }
__ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT);
__ movq(kScratchRegister,
reinterpret_cast<uint64_t>(Smi::FromInt(reset_value)),
@@ -323,10 +324,6 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
}
-static const int kMaxBackEdgeWeight = 127;
-static const int kBackEdgeDistanceDivisor = 162;
-
-
void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
Label* back_edge_target) {
Comment cmnt(masm_, "[ Stack check");
@@ -338,7 +335,7 @@ void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
ASSERT(back_edge_target->is_bound());
int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kBackEdgeDistanceDivisor));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
__ j(positive, &ok, Label::kNear);
@@ -394,7 +391,7 @@ void FullCodeGenerator::EmitReturnSequence() {
} else if (FLAG_weighted_back_edges) {
int distance = masm_->pc_offset();
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance = kBackEdgeDistanceDivisor));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
Label ok;
@@ -508,12 +505,20 @@ void FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const {
void FullCodeGenerator::AccumulatorValueContext::Plug(
Handle<Object> lit) const {
- __ Move(result_register(), lit);
+ if (lit->IsSmi()) {
+ __ SafeMove(result_register(), Smi::cast(*lit));
+ } else {
+ __ Move(result_register(), lit);
+ }
}
void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
- __ Push(lit);
+ if (lit->IsSmi()) {
+ __ SafePush(Smi::cast(*lit));
+ } else {
+ __ Push(lit);
+ }
}
@@ -757,7 +762,7 @@ void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
// The variable in the declaration always resides in the current function
// context.
ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
- if (FLAG_debug_code) {
+ if (generate_debug_code_) {
// Check that we're not inside a with or catch context.
__ movq(rbx, FieldOperand(rsi, HeapObject::kMapOffset));
__ CompareRoot(rbx, Heap::kWithContextMapRootIndex);
@@ -811,10 +816,9 @@ void FullCodeGenerator::VisitVariableDeclaration(
__ push(rsi);
__ Push(variable->name());
// Declaration nodes are always introduced in one of four modes.
- ASSERT(mode == VAR || mode == LET ||
- mode == CONST || mode == CONST_HARMONY);
+ ASSERT(IsDeclaredVariableMode(mode));
PropertyAttributes attr =
- (mode == CONST || mode == CONST_HARMONY) ? READ_ONLY : NONE;
+ IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
__ Push(Smi::FromInt(attr));
// Push initial value, if any.
// Note: For variables we must not push an initial value (such as
@@ -1100,22 +1104,32 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Label fixed_array;
__ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
Heap::kMetaMapRootIndex);
- __ j(not_equal, &fixed_array, Label::kNear);
+ __ j(not_equal, &fixed_array);
// We got a map in register rax. Get the enumeration cache from it.
__ bind(&use_cache);
+
+ Label no_descriptors;
+
+ __ EnumLength(rdx, rax);
+ __ Cmp(rdx, Smi::FromInt(0));
+ __ j(equal, &no_descriptors);
+
__ LoadInstanceDescriptors(rax, rcx);
- __ movq(rcx, FieldOperand(rcx, DescriptorArray::kEnumerationIndexOffset));
- __ movq(rdx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset));
+ __ movq(rcx, FieldOperand(rcx, DescriptorArray::kEnumCacheOffset));
+ __ movq(rcx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset));
// Set up the four remaining stack slots.
__ push(rax); // Map.
- __ push(rdx); // Enumeration cache.
- __ movq(rax, FieldOperand(rdx, FixedArray::kLengthOffset));
- __ push(rax); // Enumeration cache length (as smi).
+ __ push(rcx); // Enumeration cache.
+ __ push(rdx); // Number of valid entries for the map in the enum cache.
__ Push(Smi::FromInt(0)); // Initial index.
__ jmp(&loop);
+ __ bind(&no_descriptors);
+ __ addq(rsp, Immediate(kPointerSize));
+ __ jmp(&exit);
+
// We got a fixed array in register rax. Iterate through that.
Label non_proxy;
__ bind(&fixed_array);
@@ -1124,7 +1138,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
isolate()->factory()->NewJSGlobalPropertyCell(
Handle<Object>(
Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker)));
- RecordTypeFeedbackCell(stmt->PrepareId(), cell);
+ RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
__ LoadHeapObject(rbx, cell);
__ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker));
@@ -1283,9 +1297,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
__ movq(temp, context);
}
// Load map for comparison into register, outside loop.
- __ LoadRoot(kScratchRegister, Heap::kGlobalContextMapRootIndex);
+ __ LoadRoot(kScratchRegister, Heap::kNativeContextMapRootIndex);
__ bind(&next);
- // Terminate at global context.
+ // Terminate at native context.
__ cmpq(kScratchRegister, FieldOperand(temp, HeapObject::kMapOffset));
__ j(equal, &fast, Label::kNear);
// Check that extension is NULL.
@@ -1570,7 +1584,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
// marked expressions, no store code is emitted.
expr->CalculateEmitStore(zone());
- AccessorTable accessor_table(isolate()->zone());
+ AccessorTable accessor_table(zone());
for (int i = 0; i < expr->properties()->length(); i++) {
ObjectLiteral::Property* property = expr->properties()->at(i);
if (property->IsCompileTimeValue()) continue;
@@ -1596,7 +1610,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, key->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
VisitForEffect(value);
@@ -1807,11 +1821,11 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
break;
case NAMED_PROPERTY:
EmitNamedPropertyLoad(property);
- PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
+ PrepareForBailoutForId(property->LoadId(), TOS_REG);
break;
case KEYED_PROPERTY:
EmitKeyedPropertyLoad(property);
- PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
+ PrepareForBailoutForId(property->LoadId(), TOS_REG);
break;
}
}
@@ -1866,14 +1880,14 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
Literal* key = prop->key()->AsLiteral();
__ Move(rcx, key->handle());
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
- CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
}
@@ -1895,7 +1909,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call);
__ movq(rax, rcx);
BinaryOpStub stub(op, mode);
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear);
@@ -1944,7 +1959,8 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
__ pop(rdx);
BinaryOpStub stub(op, mode);
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
context()->Plug(rax);
}
@@ -2070,7 +2086,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// in harmony mode.
if (var->IsStackAllocated() || var->IsContextSlot()) {
MemOperand location = VarOperand(var, rcx);
- if (FLAG_debug_code && op == Token::INIT_LET) {
+ if (generate_debug_code_ && op == Token::INIT_LET) {
// Check for an uninitialized let binding.
__ movq(rdx, location);
__ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
@@ -2102,37 +2118,15 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
ASSERT(prop != NULL);
ASSERT(prop->key()->AsLiteral() != NULL);
- // If the assignment starts a block of assignments to the same object,
- // change to slow case to avoid the quadratic behavior of repeatedly
- // adding fast properties.
- if (expr->starts_initialization_block()) {
- __ push(result_register());
- __ push(Operand(rsp, kPointerSize)); // Receiver is now under value.
- __ CallRuntime(Runtime::kToSlowProperties, 1);
- __ pop(result_register());
- }
-
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ Move(rcx, prop->key()->AsLiteral()->handle());
- if (expr->ends_initialization_block()) {
- __ movq(rdx, Operand(rsp, 0));
- } else {
- __ pop(rdx);
- }
+ __ pop(rdx);
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
- // If the assignment ends an initialization block, revert to fast case.
- if (expr->ends_initialization_block()) {
- __ push(rax); // Result of assignment, saved even if not needed.
- __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
- __ CallRuntime(Runtime::kToFastProperties, 1);
- __ pop(rax);
- __ Drop(1);
- }
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
context()->Plug(rax);
}
@@ -2141,38 +2135,14 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
- // If the assignment starts a block of assignments to the same object,
- // change to slow case to avoid the quadratic behavior of repeatedly
- // adding fast properties.
- if (expr->starts_initialization_block()) {
- __ push(result_register());
- // Receiver is now under the key and value.
- __ push(Operand(rsp, 2 * kPointerSize));
- __ CallRuntime(Runtime::kToSlowProperties, 1);
- __ pop(result_register());
- }
-
__ pop(rcx);
- if (expr->ends_initialization_block()) {
- __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later.
- } else {
- __ pop(rdx);
- }
+ __ pop(rdx);
// Record source code position before IC call.
SetSourcePosition(expr->position());
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
-
- // If the assignment ends an initialization block, revert to fast case.
- if (expr->ends_initialization_block()) {
- __ pop(rdx);
- __ push(rax); // Result of assignment, saved even if not needed.
- __ push(rdx);
- __ CallRuntime(Runtime::kToFastProperties, 1);
- __ pop(rax);
- }
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
context()->Plug(rax);
@@ -2186,6 +2156,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj());
EmitNamedPropertyLoad(expr);
+ PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(rax);
} else {
VisitForStackValue(expr->obj());
@@ -2199,7 +2170,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
void FullCodeGenerator::CallIC(Handle<Code> code,
RelocInfo::Mode rmode,
- unsigned ast_id) {
+ TypeFeedbackId ast_id) {
ic_total_count_++;
__ call(code, rmode, ast_id);
}
@@ -2222,7 +2193,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
// Call the IC initialization code.
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
- CallIC(ic, mode, expr->id());
+ CallIC(ic, mode, expr->CallFeedbackId());
RecordJSReturnSite(expr);
// Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2255,7 +2226,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
Handle<Code> ic =
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
__ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key.
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId());
RecordJSReturnSite(expr);
// Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2275,20 +2246,18 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
// Record source position for debugger.
SetSourcePosition(expr->position());
- // Record call targets in unoptimized code, but not in the snapshot.
- if (!Serializer::enabled()) {
- flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
- Handle<Object> uninitialized =
- TypeFeedbackCells::UninitializedSentinel(isolate());
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
- RecordTypeFeedbackCell(expr->id(), cell);
- __ Move(rbx, cell);
- }
+ // Record call targets in unoptimized code.
+ flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
+ Handle<Object> uninitialized =
+ TypeFeedbackCells::UninitializedSentinel(isolate());
+ Handle<JSGlobalPropertyCell> cell =
+ isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
+ RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
+ __ Move(rbx, cell);
CallFunctionStub stub(arg_count, flags);
__ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub, expr->id());
+ __ CallStub(&stub, expr->CallFeedbackId());
RecordJSReturnSite(expr);
// Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2463,20 +2432,14 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ movq(rdi, Operand(rsp, arg_count * kPointerSize));
// Record call targets in unoptimized code, but not in the snapshot.
- CallFunctionFlags flags;
- if (!Serializer::enabled()) {
- flags = RECORD_CALL_TARGET;
- Handle<Object> uninitialized =
- TypeFeedbackCells::UninitializedSentinel(isolate());
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
- RecordTypeFeedbackCell(expr->id(), cell);
- __ Move(rbx, cell);
- } else {
- flags = NO_CALL_FUNCTION_FLAGS;
- }
+ Handle<Object> uninitialized =
+ TypeFeedbackCells::UninitializedSentinel(isolate());
+ Handle<JSGlobalPropertyCell> cell =
+ isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
+ RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
+ __ Move(rbx, cell);
- CallConstructStub stub(flags);
+ CallConstructStub stub(RECORD_CALL_TARGET);
__ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
context()->Plug(rax);
@@ -2617,7 +2580,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
- if (FLAG_debug_code) __ AbortIfSmi(rax);
+ __ AssertNotSmi(rax);
// Check whether this map has already been checked to be safe for default
// valueOf.
@@ -2633,45 +2596,50 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ j(equal, if_false);
// Look for valueOf symbol in the descriptor array, and indicate false if
- // found. The type is not checked, so if it is a transition it is a false
- // negative.
+ // found. Since we omit an enumeration index check, if it is added via a
+ // transition that shares its descriptor array, this is a false positive.
+ Label entry, loop, done;
+
+ // Skip loop if no descriptors are valid.
+ __ NumberOfOwnDescriptors(rcx, rbx);
+ __ cmpq(rcx, Immediate(0));
+ __ j(equal, &done);
+
__ LoadInstanceDescriptors(rbx, rbx);
- __ movq(rcx, FieldOperand(rbx, FixedArray::kLengthOffset));
- // rbx: descriptor array
- // rcx: length of descriptor array
+ // rbx: descriptor array.
+ // rcx: valid entries in the descriptor array.
// Calculate the end of the descriptor array.
+ __ imul(rcx, rcx, Immediate(DescriptorArray::kDescriptorSize));
SmiIndex index = masm_->SmiToIndex(rdx, rcx, kPointerSizeLog2);
__ lea(rcx,
Operand(
- rbx, index.reg, index.scale, FixedArray::kHeaderSize));
+ rbx, index.reg, index.scale, DescriptorArray::kFirstOffset));
// Calculate location of the first key name.
- __ addq(rbx,
- Immediate(FixedArray::kHeaderSize +
- DescriptorArray::kFirstIndex * kPointerSize));
+ __ addq(rbx, Immediate(DescriptorArray::kFirstOffset));
// Loop through all the keys in the descriptor array. If one of these is the
// symbol valueOf the result is false.
- Label entry, loop;
__ jmp(&entry);
__ bind(&loop);
__ movq(rdx, FieldOperand(rbx, 0));
__ Cmp(rdx, FACTORY->value_of_symbol());
__ j(equal, if_false);
- __ addq(rbx, Immediate(kPointerSize));
+ __ addq(rbx, Immediate(DescriptorArray::kDescriptorSize * kPointerSize));
__ bind(&entry);
__ cmpq(rbx, rcx);
__ j(not_equal, &loop);
+ __ bind(&done);
// Reload map as register rbx was used as temporary above.
__ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
- // If a valueOf property is not found on the object check that it's
+ // If a valueOf property is not found on the object check that its
// prototype is the un-modified String prototype. If not result is false.
__ movq(rcx, FieldOperand(rbx, Map::kPrototypeOffset));
__ testq(rcx, Immediate(kSmiTagMask));
__ j(zero, if_false);
__ movq(rcx, FieldOperand(rcx, HeapObject::kMapOffset));
- __ movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalContextOffset));
+ __ movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ movq(rdx, FieldOperand(rdx, GlobalObject::kNativeContextOffset));
__ cmpq(rcx,
ContextOperand(rdx, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
__ j(not_equal, if_false);
@@ -2841,7 +2809,7 @@ void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
__ movq(rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
__ bind(&exit);
- if (FLAG_debug_code) __ AbortIfNotSmi(rax);
+ __ AssertSmi(rax);
context()->Plug(rax);
}
@@ -2948,12 +2916,14 @@ void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) {
// The fresh HeapNumber is in rbx, which is callee-save on both x64 ABIs.
__ PrepareCallCFunction(1);
#ifdef _WIN64
- __ movq(rcx, ContextOperand(context_register(), Context::GLOBAL_INDEX));
- __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalContextOffset));
+ __ movq(rcx,
+ ContextOperand(context_register(), Context::GLOBAL_OBJECT_INDEX));
+ __ movq(rcx, FieldOperand(rcx, GlobalObject::kNativeContextOffset));
#else
- __ movq(rdi, ContextOperand(context_register(), Context::GLOBAL_INDEX));
- __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset));
+ __ movq(rdi,
+ ContextOperand(context_register(), Context::GLOBAL_OBJECT_INDEX));
+ __ movq(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
#endif
__ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
@@ -3027,19 +2997,18 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0)); // Load the object.
- Label runtime, done;
+ Label runtime, done, not_date_object;
Register object = rax;
Register result = rax;
Register scratch = rcx;
-#ifdef DEBUG
- __ AbortIfSmi(object);
+ __ JumpIfSmi(object, &not_date_object);
__ CmpObjectType(object, JS_DATE_TYPE, scratch);
- __ Assert(equal, "Trying to get date field from non-date.");
-#endif
+ __ j(not_equal, &not_date_object);
if (index->value() == 0) {
__ movq(result, FieldOperand(object, JSDate::kValueOffset));
+ __ jmp(&done);
} else {
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
@@ -3061,8 +3030,12 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
#endif
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
- __ bind(&done);
+ __ jmp(&done);
}
+
+ __ bind(&not_date_object);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
+ __ bind(&done);
context()->Plug(rax);
}
@@ -3327,10 +3300,11 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
- // Check for proxy.
- Label proxy, done;
- __ CmpObjectType(rax, JS_FUNCTION_PROXY_TYPE, rbx);
- __ j(equal, &proxy);
+ Label runtime, done;
+ // Check for non-function argument (including proxy).
+ __ JumpIfSmi(rax, &runtime);
+ __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
+ __ j(not_equal, &runtime);
// InvokeFunction requires the function in rdi. Move it in there.
__ movq(rdi, result_register());
@@ -3340,7 +3314,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
__ jmp(&done);
- __ bind(&proxy);
+ __ bind(&runtime);
__ push(rax);
__ CallRuntime(Runtime::kCall, args->length());
__ bind(&done);
@@ -3369,7 +3343,7 @@ void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
Handle<FixedArray> jsfunction_result_caches(
- isolate()->global_context()->jsfunction_result_caches());
+ isolate()->native_context()->jsfunction_result_caches());
if (jsfunction_result_caches->length() <= cache_id) {
__ Abort("Attempt to use undefined cache.");
__ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
@@ -3382,9 +3356,9 @@ void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
Register key = rax;
Register cache = rbx;
Register tmp = rcx;
- __ movq(cache, ContextOperand(rsi, Context::GLOBAL_INDEX));
+ __ movq(cache, ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX));
__ movq(cache,
- FieldOperand(cache, GlobalObject::kGlobalContextOffset));
+ FieldOperand(cache, GlobalObject::kNativeContextOffset));
__ movq(cache,
ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX));
__ movq(cache,
@@ -3485,9 +3459,7 @@ void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
ASSERT(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
- if (FLAG_debug_code) {
- __ AbortIfNotString(rax);
- }
+ __ AssertString(rax);
__ movl(rax, FieldOperand(rax, String::kHashFieldOffset));
ASSERT(String::kHashShift >= kSmiTagSize);
@@ -3565,7 +3537,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
// Loop condition: while (index < array_length).
// Live loop registers: index(int32), array_length(int32), string(String*),
// scratch, string_length(int32), elements(FixedArray*).
- if (FLAG_debug_code) {
+ if (generate_debug_code_) {
__ cmpq(index, array_length);
__ Assert(below, "No empty arrays here in EmitFastAsciiArrayJoin");
}
@@ -3811,7 +3783,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
- CallIC(ic, mode, expr->id());
+ CallIC(ic, mode, expr->CallRuntimeFeedbackId());
// Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
} else {
@@ -3969,7 +3941,8 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
// accumulator register rax.
VisitForAccumulatorValue(expr->expression());
SetSourcePosition(expr->position());
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET,
+ expr->UnaryOperationFeedbackId());
context()->Plug(rax);
}
@@ -4025,7 +3998,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == VARIABLE) {
PrepareForBailout(expr->expression(), TOS_REG);
} else {
- PrepareForBailoutForId(expr->CountId(), TOS_REG);
+ PrepareForBailoutForId(prop->LoadId(), TOS_REG);
}
// Call ToNumber only if operand is not a smi.
@@ -4090,7 +4063,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ movq(rdx, rax);
__ Move(rax, Smi::FromInt(1));
}
- CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4124,7 +4097,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
if (!context()->IsEffect()) {
@@ -4141,7 +4114,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
if (!context()->IsEffect()) {
@@ -4348,7 +4321,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CompareIC::GetUninitialized(op);
- CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
@@ -4430,7 +4403,7 @@ void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
Scope* declaration_scope = scope()->DeclarationScope();
if (declaration_scope->is_global_scope() ||
declaration_scope->is_module_scope()) {
- // Contexts nested in the global context have a canonical empty function
+ // Contexts nested in the native context have a canonical empty function
// as their closure, not the anonymous closure containing the global
// code. Pass a smi sentinel and let the runtime look up the empty
// function.
@@ -4473,6 +4446,7 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference has_pending_message =
ExternalReference::address_of_has_pending_message(isolate());
__ Load(rdx, has_pending_message);
+ __ Integer32ToSmi(rdx, rdx);
__ push(rdx);
ExternalReference pending_message_script =
@@ -4492,6 +4466,7 @@ void FullCodeGenerator::ExitFinallyBlock() {
__ Store(pending_message_script, rdx);
__ pop(rdx);
+ __ SmiToInteger32(rdx, rdx);
ExternalReference has_pending_message =
ExternalReference::address_of_has_pending_message(isolate());
__ Store(has_pending_message, rdx);
diff --git a/deps/v8/src/x64/ic-x64.cc b/deps/v8/src/x64/ic-x64.cc
index 82fdb3cec..efa07a80b 100644
--- a/deps/v8/src/x64/ic-x64.cc
+++ b/deps/v8/src/x64/ic-x64.cc
@@ -135,7 +135,7 @@ static void GenerateDictionaryLoad(MacroAssembler* masm,
r0,
r1);
- // If probing finds an entry in the dictionary, r0 contains the
+ // If probing finds an entry in the dictionary, r1 contains the
// index into the dictionary. Check that the value is a normal
// property.
__ bind(&done);
@@ -178,10 +178,9 @@ static void GenerateDictionaryStore(MacroAssembler* masm,
//
// value - holds the value to store and is unchanged.
//
- // scratch0 - used for index into the property dictionary and is clobbered.
+ // scratch0 - used during the positive dictionary lookup and is clobbered.
//
- // scratch1 - used to hold the capacity of the property dictionary and is
- // clobbered.
+ // scratch1 - used for index into the property dictionary and is clobbered.
Label done;
// Probe the dictionary.
@@ -624,6 +623,123 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
}
+static void KeyedStoreGenerateGenericHelper(
+ MacroAssembler* masm,
+ Label* fast_object,
+ Label* fast_double,
+ Label* slow,
+ KeyedStoreCheckMap check_map,
+ KeyedStoreIncrementLength increment_length) {
+ Label transition_smi_elements;
+ Label finish_object_store, non_double_value, transition_double_elements;
+ Label fast_double_without_map_check;
+ // Fast case: Do the store, could be either Object or double.
+ __ bind(fast_object);
+ // rax: value
+ // rbx: receiver's elements array (a FixedArray)
+ // rcx: index
+ // rdx: receiver (a JSArray)
+ // r9: map of receiver
+ if (check_map == kCheckMap) {
+ __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
+ __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
+ __ j(not_equal, fast_double);
+ }
+ // Smi stores don't require further checks.
+ Label non_smi_value;
+ __ JumpIfNotSmi(rax, &non_smi_value);
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ leal(rdi, Operand(rcx, 1));
+ __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
+ }
+ // It's irrelevant whether array is smi-only or not when writing a smi.
+ __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
+ rax);
+ __ ret(0);
+
+ __ bind(&non_smi_value);
+ // Writing a non-smi, check whether array allows non-smi elements.
+ // r9: receiver's map
+ __ CheckFastObjectElements(r9, &transition_smi_elements);
+
+ __ bind(&finish_object_store);
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ leal(rdi, Operand(rcx, 1));
+ __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
+ }
+ __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
+ rax);
+ __ movq(rdx, rax); // Preserve the value which is returned.
+ __ RecordWriteArray(
+ rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+ __ ret(0);
+
+ __ bind(fast_double);
+ if (check_map == kCheckMap) {
+ // Check for fast double array case. If this fails, call through to the
+ // runtime.
+ // rdi: elements array's map
+ __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
+ __ j(not_equal, slow);
+ }
+ __ bind(&fast_double_without_map_check);
+ __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0,
+ &transition_double_elements);
+ if (increment_length == kIncrementLength) {
+ // Add 1 to receiver->length.
+ __ leal(rdi, Operand(rcx, 1));
+ __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
+ }
+ __ ret(0);
+
+ __ bind(&transition_smi_elements);
+ __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
+
+ // Transition the array appropriately depending on the value type.
+ __ movq(r9, FieldOperand(rax, HeapObject::kMapOffset));
+ __ CompareRoot(r9, Heap::kHeapNumberMapRootIndex);
+ __ j(not_equal, &non_double_value);
+
+ // Value is a double. Transition FAST_SMI_ELEMENTS ->
+ // FAST_DOUBLE_ELEMENTS and complete the store.
+ __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
+ FAST_DOUBLE_ELEMENTS,
+ rbx,
+ rdi,
+ slow);
+ ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
+ __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ jmp(&fast_double_without_map_check);
+
+ __ bind(&non_double_value);
+ // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
+ __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
+ FAST_ELEMENTS,
+ rbx,
+ rdi,
+ slow);
+ ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
+ __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ jmp(&finish_object_store);
+
+ __ bind(&transition_double_elements);
+ // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
+ // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
+ // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
+ __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
+ __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
+ FAST_ELEMENTS,
+ rbx,
+ rdi,
+ slow);
+ ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
+ __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ jmp(&finish_object_store);
+}
+
+
void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
StrictModeFlag strict_mode) {
// ----------- S t a t e -------------
@@ -632,11 +748,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
- Label slow, slow_with_tagged_index, fast, array, extra, check_extra_double;
- Label fast_object_with_map_check, fast_object_without_map_check;
- Label fast_double_with_map_check, fast_double_without_map_check;
- Label transition_smi_elements, finish_object_store, non_double_value;
- Label transition_double_elements;
+ Label slow, slow_with_tagged_index, fast_object, fast_object_grow;
+ Label fast_double, fast_double_grow;
+ Label array, extra, check_if_double_array;
// Check that the object isn't a smi.
__ JumpIfSmi(rdx, &slow_with_tagged_index);
@@ -667,7 +781,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// rax: value
// rbx: FixedArray
// rcx: index
- __ j(above, &fast_object_with_map_check);
+ __ j(above, &fast_object);
// Slow case: call runtime.
__ bind(&slow);
@@ -691,18 +805,14 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// Increment index to get new length.
__ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
__ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
- __ j(not_equal, &check_extra_double);
- __ leal(rdi, Operand(rcx, 1));
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
- __ jmp(&fast_object_without_map_check);
+ __ j(not_equal, &check_if_double_array);
+ __ jmp(&fast_object_grow);
- __ bind(&check_extra_double);
+ __ bind(&check_if_double_array);
// rdi: elements array's map
__ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
__ j(not_equal, &slow);
- __ leal(rdi, Operand(rcx, 1));
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
- __ jmp(&fast_double_without_map_check);
+ __ jmp(&fast_double_grow);
// Array case: Get the length and the elements array from the JS
// array. Check that the array is in fast mode (and writable); if it
@@ -718,92 +828,10 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
__ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx);
__ j(below_equal, &extra);
- // Fast case: Do the store.
- __ bind(&fast_object_with_map_check);
- // rax: value
- // rbx: receiver's elements array (a FixedArray)
- // rcx: index
- // rdx: receiver (a JSArray)
- __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
- __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
- __ j(not_equal, &fast_double_with_map_check);
- __ bind(&fast_object_without_map_check);
- // Smi stores don't require further checks.
- Label non_smi_value;
- __ JumpIfNotSmi(rax, &non_smi_value);
- // It's irrelevant whether array is smi-only or not when writing a smi.
- __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
- rax);
- __ ret(0);
-
- __ bind(&non_smi_value);
- // Writing a non-smi, check whether array allows non-smi elements.
- // r9: receiver's map
- __ CheckFastObjectElements(r9, &transition_smi_elements);
- __ bind(&finish_object_store);
- __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
- rax);
- __ movq(rdx, rax); // Preserve the value which is returned.
- __ RecordWriteArray(
- rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
- __ ret(0);
-
- __ bind(&fast_double_with_map_check);
- // Check for fast double array case. If this fails, call through to the
- // runtime.
- // rdi: elements array's map
- __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
- __ j(not_equal, &slow);
- __ bind(&fast_double_without_map_check);
- // If the value is a number, store it as a double in the FastDoubleElements
- // array.
- __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0,
- &transition_double_elements);
- __ ret(0);
-
- __ bind(&transition_smi_elements);
- __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
-
- // Transition the array appropriately depending on the value type.
- __ movq(r9, FieldOperand(rax, HeapObject::kMapOffset));
- __ CompareRoot(r9, Heap::kHeapNumberMapRootIndex);
- __ j(not_equal, &non_double_value);
-
- // Value is a double. Transition FAST_SMI_ELEMENTS ->
- // FAST_DOUBLE_ELEMENTS and complete the store.
- __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
- FAST_DOUBLE_ELEMENTS,
- rbx,
- rdi,
- &slow);
- ElementsTransitionGenerator::GenerateSmiToDouble(masm, &slow);
- __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
- __ jmp(&fast_double_without_map_check);
-
- __ bind(&non_double_value);
- // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
- __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
- FAST_ELEMENTS,
- rbx,
- rdi,
- &slow);
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
- __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
- __ jmp(&finish_object_store);
-
- __ bind(&transition_double_elements);
- // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
- // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
- // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
- __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
- __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
- FAST_ELEMENTS,
- rbx,
- rdi,
- &slow);
- ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow);
- __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
- __ jmp(&finish_object_store);
+ KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
+ &slow, kCheckMap, kDontIncrementLength);
+ KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
+ &slow, kDontCheckMap, kIncrementLength);
}
@@ -823,7 +851,7 @@ void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC,
extra_state,
- NORMAL,
+ Code::NORMAL,
argc);
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
rax);
diff --git a/deps/v8/src/x64/lithium-codegen-x64.cc b/deps/v8/src/x64/lithium-codegen-x64.cc
index 7dc38a142..b461e6290 100644
--- a/deps/v8/src/x64/lithium-codegen-x64.cc
+++ b/deps/v8/src/x64/lithium-codegen-x64.cc
@@ -92,17 +92,8 @@ void LCodeGen::FinishCode(Handle<Code> code) {
}
-void LCodeGen::Abort(const char* format, ...) {
- if (FLAG_trace_bailout) {
- SmartArrayPointer<char> name(
- info()->shared_info()->DebugName()->ToCString());
- PrintF("Aborting LCodeGen in @\"%s\": ", *name);
- va_list arguments;
- va_start(arguments, format);
- OS::VPrint(format, arguments);
- va_end(arguments);
- PrintF("\n");
- }
+void LChunkBuilder::Abort(const char* reason) {
+ info()->set_bailout_reason(reason);
status_ = ABORTED;
}
@@ -128,6 +119,8 @@ void LCodeGen::Comment(const char* format, ...) {
bool LCodeGen::GeneratePrologue() {
ASSERT(is_generating());
+ ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+
#ifdef DEBUG
if (strlen(FLAG_stop_at) > 0 &&
info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
@@ -320,24 +313,24 @@ bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const {
int LCodeGen::ToInteger32(LConstantOperand* op) const {
- Handle<Object> value = chunk_->LookupLiteral(op);
+ HConstant* constant = chunk_->LookupConstant(op);
ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32());
- ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) ==
- value->Number());
- return static_cast<int32_t>(value->Number());
+ ASSERT(constant->HasInteger32Value());
+ return constant->Integer32Value();
}
double LCodeGen::ToDouble(LConstantOperand* op) const {
- Handle<Object> value = chunk_->LookupLiteral(op);
- return value->Number();
+ HConstant* constant = chunk_->LookupConstant(op);
+ ASSERT(constant->HasDoubleValue());
+ return constant->DoubleValue();
}
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
- Handle<Object> literal = chunk_->LookupLiteral(op);
+ HConstant* constant = chunk_->LookupConstant(op);
ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
- return literal;
+ return constant->handle();
}
@@ -358,7 +351,9 @@ Operand LCodeGen::ToOperand(LOperand* op) const {
void LCodeGen::WriteTranslation(LEnvironment* environment,
- Translation* translation) {
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count) {
if (environment == NULL) return;
// The translation includes one command per value in the environment.
@@ -366,8 +361,21 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
// The output frame height does not include the parameters.
int height = translation_size - environment->parameter_count();
- WriteTranslation(environment->outer(), translation);
- int closure_id = DefineDeoptimizationLiteral(environment->closure());
+ // Function parameters are arguments to the outermost environment. The
+ // arguments index points to the first element of a sequence of tagged
+ // values on the stack that represent the arguments. This needs to be
+ // kept in sync with the LArgumentsElements implementation.
+ *arguments_index = -environment->parameter_count();
+ *arguments_count = environment->parameter_count();
+
+ WriteTranslation(environment->outer(),
+ translation,
+ arguments_index,
+ arguments_count);
+ int closure_id = *info()->closure() != *environment->closure()
+ ? DefineDeoptimizationLiteral(environment->closure())
+ : Translation::kSelfLiteralId;
+
switch (environment->frame_type()) {
case JS_FUNCTION:
translation->BeginJSFrame(environment->ast_id(), closure_id, height);
@@ -375,12 +383,31 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
case JS_CONSTRUCT:
translation->BeginConstructStubFrame(closure_id, translation_size);
break;
+ case JS_GETTER:
+ ASSERT(translation_size == 1);
+ ASSERT(height == 0);
+ translation->BeginGetterStubFrame(closure_id);
+ break;
+ case JS_SETTER:
+ ASSERT(translation_size == 2);
+ ASSERT(height == 0);
+ translation->BeginSetterStubFrame(closure_id);
+ break;
case ARGUMENTS_ADAPTOR:
translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
break;
- default:
- UNREACHABLE();
}
+
+ // Inlined frames which push their arguments cause the index to be
+ // bumped and a new stack area to be used for materialization.
+ if (environment->entry() != NULL &&
+ environment->entry()->arguments_pushed()) {
+ *arguments_index = *arguments_index < 0
+ ? GetStackSlotCount()
+ : *arguments_index + *arguments_count;
+ *arguments_count = environment->entry()->arguments_count() + 1;
+ }
+
for (int i = 0; i < translation_size; ++i) {
LOperand* value = environment->values()->at(i);
// spilled_registers_ and spilled_double_registers_ are either
@@ -391,7 +418,10 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
translation->MarkDuplicate();
AddToTranslation(translation,
environment->spilled_registers()[value->index()],
- environment->HasTaggedValueAt(i));
+ environment->HasTaggedValueAt(i),
+ environment->HasUint32ValueAt(i),
+ *arguments_index,
+ *arguments_count);
} else if (
value->IsDoubleRegister() &&
environment->spilled_double_registers()[value->index()] != NULL) {
@@ -399,26 +429,39 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
AddToTranslation(
translation,
environment->spilled_double_registers()[value->index()],
- false);
+ false,
+ false,
+ *arguments_index,
+ *arguments_count);
}
}
- AddToTranslation(translation, value, environment->HasTaggedValueAt(i));
+ AddToTranslation(translation,
+ value,
+ environment->HasTaggedValueAt(i),
+ environment->HasUint32ValueAt(i),
+ *arguments_index,
+ *arguments_count);
}
}
void LCodeGen::AddToTranslation(Translation* translation,
LOperand* op,
- bool is_tagged) {
+ bool is_tagged,
+ bool is_uint32,
+ int arguments_index,
+ int arguments_count) {
if (op == NULL) {
// TODO(twuerthinger): Introduce marker operands to indicate that this value
// is not present and must be reconstructed from the deoptimizer. Currently
// this is only used for the arguments object.
- translation->StoreArgumentsObject();
+ translation->StoreArgumentsObject(arguments_index, arguments_count);
} else if (op->IsStackSlot()) {
if (is_tagged) {
translation->StoreStackSlot(op->index());
+ } else if (is_uint32) {
+ translation->StoreUint32StackSlot(op->index());
} else {
translation->StoreInt32StackSlot(op->index());
}
@@ -432,6 +475,8 @@ void LCodeGen::AddToTranslation(Translation* translation,
Register reg = ToRegister(op);
if (is_tagged) {
translation->StoreRegister(reg);
+ } else if (is_uint32) {
+ translation->StoreUint32Register(reg);
} else {
translation->StoreInt32Register(reg);
}
@@ -439,8 +484,8 @@ void LCodeGen::AddToTranslation(Translation* translation,
XMMRegister reg = ToDoubleRegister(op);
translation->StoreDoubleRegister(reg);
} else if (op->IsConstantOperand()) {
- Handle<Object> literal = chunk()->LookupLiteral(LConstantOperand::cast(op));
- int src_index = DefineDeoptimizationLiteral(literal);
+ HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
+ int src_index = DefineDeoptimizationLiteral(constant->handle());
translation->StoreLiteral(src_index);
} else {
UNREACHABLE();
@@ -517,15 +562,16 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
int frame_count = 0;
int jsframe_count = 0;
+ int args_index = 0;
+ int args_count = 0;
for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
++frame_count;
if (e->frame_type() == JS_FUNCTION) {
++jsframe_count;
}
}
- Translation translation(&translations_, frame_count, jsframe_count,
- environment->zone());
- WriteTranslation(environment, &translation);
+ Translation translation(&translations_, frame_count, jsframe_count, zone());
+ WriteTranslation(environment, &translation, &args_index, &args_count);
int deoptimization_index = deoptimizations_.length();
int pc_offset = masm()->pc_offset();
environment->Register(deoptimization_index,
@@ -577,13 +623,13 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
}
data->SetLiteralArray(*literals);
- data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id()));
+ data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt()));
data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
// Populate the deoptimization entries.
for (int i = 0; i < length; i++) {
LEnvironment* env = deoptimizations_[i];
- data->SetAstId(i, Smi::FromInt(env->ast_id()));
+ data->SetAstId(i, env->ast_id());
data->SetTranslationIndex(i, Smi::FromInt(env->translation_index()));
data->SetArgumentsStackHeight(i,
Smi::FromInt(env->arguments_stack_height()));
@@ -772,7 +818,7 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
void LCodeGen::DoModI(LModI* instr) {
if (instr->hydrogen()->HasPowerOf2Divisor()) {
- Register dividend = ToRegister(instr->InputAt(0));
+ Register dividend = ToRegister(instr->left());
int32_t divisor =
HConstant::cast(instr->hydrogen()->right())->Integer32Value();
@@ -796,8 +842,8 @@ void LCodeGen::DoModI(LModI* instr) {
__ bind(&done);
} else {
Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
- Register left_reg = ToRegister(instr->InputAt(0));
- Register right_reg = ToRegister(instr->InputAt(1));
+ Register left_reg = ToRegister(instr->left());
+ Register right_reg = ToRegister(instr->right());
Register result_reg = ToRegister(instr->result());
ASSERT(left_reg.is(rax));
@@ -827,7 +873,7 @@ void LCodeGen::DoModI(LModI* instr) {
__ j(less, &remainder_eq_dividend, Label::kNear);
// Check if the divisor is a PowerOfTwo integer.
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
__ movl(scratch, right_reg);
__ subl(scratch, Immediate(1));
__ testl(scratch, right_reg);
@@ -883,12 +929,95 @@ void LCodeGen::DoModI(LModI* instr) {
}
+void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
+ ASSERT(instr->right()->IsConstantOperand());
+
+ const Register dividend = ToRegister(instr->left());
+ int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
+ const Register result = ToRegister(instr->result());
+
+ switch (divisor) {
+ case 0:
+ DeoptimizeIf(no_condition, instr->environment());
+ return;
+
+ case 1:
+ if (!result.is(dividend)) {
+ __ movl(result, dividend);
+ }
+ return;
+
+ case -1:
+ if (!result.is(dividend)) {
+ __ movl(result, dividend);
+ }
+ __ negl(result);
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ DeoptimizeIf(zero, instr->environment());
+ }
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ DeoptimizeIf(overflow, instr->environment());
+ }
+ return;
+ }
+
+ uint32_t divisor_abs = abs(divisor);
+ if (IsPowerOf2(divisor_abs)) {
+ int32_t power = WhichPowerOf2(divisor_abs);
+ if (divisor < 0) {
+ __ movsxlq(result, dividend);
+ __ neg(result);
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ DeoptimizeIf(zero, instr->environment());
+ }
+ __ sar(result, Immediate(power));
+ } else {
+ if (!result.is(dividend)) {
+ __ movl(result, dividend);
+ }
+ __ sarl(result, Immediate(power));
+ }
+ } else {
+ Register reg1 = ToRegister(instr->temp());
+ Register reg2 = ToRegister(instr->result());
+
+ // Find b which: 2^b < divisor_abs < 2^(b+1).
+ unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
+ unsigned shift = 32 + b; // Precision +1bit (effectively).
+ double multiplier_f =
+ static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs;
+ int64_t multiplier;
+ if (multiplier_f - floor(multiplier_f) < 0.5) {
+ multiplier = static_cast<int64_t>(floor(multiplier_f));
+ } else {
+ multiplier = static_cast<int64_t>(floor(multiplier_f)) + 1;
+ }
+ // The multiplier is a uint32.
+ ASSERT(multiplier > 0 &&
+ multiplier < (static_cast<int64_t>(1) << 32));
+ // The multiply is int64, so sign-extend to r64.
+ __ movsxlq(reg1, dividend);
+ if (divisor < 0 &&
+ instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ __ neg(reg1);
+ DeoptimizeIf(zero, instr->environment());
+ }
+ __ movq(reg2, multiplier, RelocInfo::NONE);
+ // Result just fit in r64, because it's int32 * uint32.
+ __ imul(reg2, reg1);
+
+ __ addq(reg2, Immediate(1 << 30));
+ __ sar(reg2, Immediate(shift));
+ }
+}
+
+
void LCodeGen::DoDivI(LDivI* instr) {
- LOperand* right = instr->InputAt(1);
+ LOperand* right = instr->right();
ASSERT(ToRegister(instr->result()).is(rax));
- ASSERT(ToRegister(instr->InputAt(0)).is(rax));
- ASSERT(!ToRegister(instr->InputAt(1)).is(rax));
- ASSERT(!ToRegister(instr->InputAt(1)).is(rdx));
+ ASSERT(ToRegister(instr->left()).is(rax));
+ ASSERT(!ToRegister(instr->right()).is(rax));
+ ASSERT(!ToRegister(instr->right()).is(rdx));
Register left_reg = rax;
@@ -930,8 +1059,8 @@ void LCodeGen::DoDivI(LDivI* instr) {
void LCodeGen::DoMulI(LMulI* instr) {
- Register left = ToRegister(instr->InputAt(0));
- LOperand* right = instr->InputAt(1);
+ Register left = ToRegister(instr->left());
+ LOperand* right = instr->right();
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ movl(kScratchRegister, left);
@@ -996,8 +1125,11 @@ void LCodeGen::DoMulI(LMulI* instr) {
__ testl(left, left);
__ j(not_zero, &done, Label::kNear);
if (right->IsConstantOperand()) {
- if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
+ if (ToInteger32(LConstantOperand::cast(right)) < 0) {
DeoptimizeIf(no_condition, instr->environment());
+ } else if (ToInteger32(LConstantOperand::cast(right)) == 0) {
+ __ cmpl(kScratchRegister, Immediate(0));
+ DeoptimizeIf(less, instr->environment());
}
} else if (right->IsStackSlot()) {
__ orl(kScratchRegister, ToOperand(right));
@@ -1013,8 +1145,8 @@ void LCodeGen::DoMulI(LMulI* instr) {
void LCodeGen::DoBitI(LBitI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
ASSERT(left->Equals(instr->result()));
ASSERT(left->IsRegister());
@@ -1070,8 +1202,8 @@ void LCodeGen::DoBitI(LBitI* instr) {
void LCodeGen::DoShiftI(LShiftI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
ASSERT(left->Equals(instr->result()));
ASSERT(left->IsRegister());
if (right->IsRegister()) {
@@ -1126,8 +1258,8 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
void LCodeGen::DoSubI(LSubI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
ASSERT(left->Equals(instr->result()));
if (right->IsConstantOperand()) {
@@ -1161,7 +1293,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
if (int_val == 0) {
__ xorps(res, res);
} else {
- Register tmp = ToRegister(instr->TempAt(0));
+ Register tmp = ToRegister(instr->temp());
__ Set(tmp, int_val);
__ movq(res, tmp);
}
@@ -1181,21 +1313,28 @@ void LCodeGen::DoConstantT(LConstantT* instr) {
void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
+ Register array = ToRegister(instr->value());
__ movq(result, FieldOperand(array, JSArray::kLengthOffset));
}
void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
+ Register array = ToRegister(instr->value());
__ movq(result, FieldOperand(array, FixedArrayBase::kLengthOffset));
}
+void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
+ Register result = ToRegister(instr->result());
+ Register map = ToRegister(instr->value());
+ __ EnumLength(result, map);
+}
+
+
void LCodeGen::DoElementsKind(LElementsKind* instr) {
Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
// Load map into |result|.
__ movq(result, FieldOperand(input, HeapObject::kMapOffset));
@@ -1208,7 +1347,7 @@ void LCodeGen::DoElementsKind(LElementsKind* instr) {
void LCodeGen::DoValueOf(LValueOf* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
ASSERT(input.is(result));
Label done;
@@ -1225,18 +1364,17 @@ void LCodeGen::DoValueOf(LValueOf* instr) {
void LCodeGen::DoDateField(LDateField* instr) {
- Register object = ToRegister(instr->InputAt(0));
+ Register object = ToRegister(instr->date());
Register result = ToRegister(instr->result());
Smi* index = instr->index();
- Label runtime, done;
+ Label runtime, done, not_date_object;
ASSERT(object.is(result));
ASSERT(object.is(rax));
-#ifdef DEBUG
- __ AbortIfSmi(object);
+ Condition cc = masm()->CheckSmi(object);
+ DeoptimizeIf(cc, instr->environment());
__ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister);
- __ Assert(equal, "Trying to get date field from non-date.");
-#endif
+ DeoptimizeIf(not_equal, instr->environment());
if (index->value() == 0) {
__ movq(result, FieldOperand(object, JSDate::kValueOffset));
@@ -1268,14 +1406,14 @@ void LCodeGen::DoDateField(LDateField* instr) {
void LCodeGen::DoBitNotI(LBitNotI* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->Equals(instr->result()));
__ not_(ToRegister(input));
}
void LCodeGen::DoThrow(LThrow* instr) {
- __ push(ToRegister(instr->InputAt(0)));
+ __ push(ToRegister(instr->value()));
CallRuntime(Runtime::kThrow, 1, instr);
if (FLAG_debug_code) {
@@ -1286,8 +1424,8 @@ void LCodeGen::DoThrow(LThrow* instr) {
void LCodeGen::DoAddI(LAddI* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
ASSERT(left->Equals(instr->result()));
if (right->IsConstantOperand()) {
@@ -1305,9 +1443,75 @@ void LCodeGen::DoAddI(LAddI* instr) {
}
+void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
+ ASSERT(left->Equals(instr->result()));
+ HMathMinMax::Operation operation = instr->hydrogen()->operation();
+ if (instr->hydrogen()->representation().IsInteger32()) {
+ Label return_left;
+ Condition condition = (operation == HMathMinMax::kMathMin)
+ ? less_equal
+ : greater_equal;
+ Register left_reg = ToRegister(left);
+ if (right->IsConstantOperand()) {
+ Immediate right_imm =
+ Immediate(ToInteger32(LConstantOperand::cast(right)));
+ __ cmpq(left_reg, right_imm);
+ __ j(condition, &return_left, Label::kNear);
+ __ movq(left_reg, right_imm);
+ } else if (right->IsRegister()) {
+ Register right_reg = ToRegister(right);
+ __ cmpq(left_reg, right_reg);
+ __ j(condition, &return_left, Label::kNear);
+ __ movq(left_reg, right_reg);
+ } else {
+ Operand right_op = ToOperand(right);
+ __ cmpq(left_reg, right_op);
+ __ j(condition, &return_left, Label::kNear);
+ __ movq(left_reg, right_op);
+ }
+ __ bind(&return_left);
+ } else {
+ ASSERT(instr->hydrogen()->representation().IsDouble());
+ Label check_nan_left, check_zero, return_left, return_right;
+ Condition condition = (operation == HMathMinMax::kMathMin) ? below : above;
+ XMMRegister left_reg = ToDoubleRegister(left);
+ XMMRegister right_reg = ToDoubleRegister(right);
+ __ ucomisd(left_reg, right_reg);
+ __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN.
+ __ j(equal, &check_zero, Label::kNear); // left == right.
+ __ j(condition, &return_left, Label::kNear);
+ __ jmp(&return_right, Label::kNear);
+
+ __ bind(&check_zero);
+ XMMRegister xmm_scratch = xmm0;
+ __ xorps(xmm_scratch, xmm_scratch);
+ __ ucomisd(left_reg, xmm_scratch);
+ __ j(not_equal, &return_left, Label::kNear); // left == right != 0.
+ // At this point, both left and right are either 0 or -0.
+ if (operation == HMathMinMax::kMathMin) {
+ __ orpd(left_reg, right_reg);
+ } else {
+ // Since we operate on +0 and/or -0, addsd and andsd have the same effect.
+ __ addsd(left_reg, right_reg);
+ }
+ __ jmp(&return_left, Label::kNear);
+
+ __ bind(&check_nan_left);
+ __ ucomisd(left_reg, left_reg); // NaN check.
+ __ j(parity_even, &return_left, Label::kNear);
+ __ bind(&return_right);
+ __ movsd(left_reg, right_reg);
+
+ __ bind(&return_left);
+ }
+}
+
+
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
- XMMRegister left = ToDoubleRegister(instr->InputAt(0));
- XMMRegister right = ToDoubleRegister(instr->InputAt(1));
+ XMMRegister left = ToDoubleRegister(instr->left());
+ XMMRegister right = ToDoubleRegister(instr->right());
XMMRegister result = ToDoubleRegister(instr->result());
// All operations except MOD are computed in-place.
ASSERT(instr->op() == Token::MOD || left.is(result));
@@ -1341,8 +1545,8 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(rdx));
- ASSERT(ToRegister(instr->InputAt(1)).is(rax));
+ ASSERT(ToRegister(instr->left()).is(rdx));
+ ASSERT(ToRegister(instr->right()).is(rax));
ASSERT(ToRegister(instr->result()).is(rax));
BinaryOpStub stub(instr->op(), NO_OVERWRITE);
@@ -1386,17 +1590,17 @@ void LCodeGen::DoBranch(LBranch* instr) {
Representation r = instr->hydrogen()->value()->representation();
if (r.IsInteger32()) {
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
__ testl(reg, reg);
EmitBranch(true_block, false_block, not_zero);
} else if (r.IsDouble()) {
- XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
+ XMMRegister reg = ToDoubleRegister(instr->value());
__ xorps(xmm0, xmm0);
__ ucomisd(reg, xmm0);
EmitBranch(true_block, false_block, not_equal);
} else {
ASSERT(r.IsTagged());
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
HType type = instr->hydrogen()->value()->type();
if (type.IsBoolean()) {
__ CompareRoot(reg, Heap::kTrueValueRootIndex);
@@ -1533,8 +1737,8 @@ inline Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
- LOperand* left = instr->InputAt(0);
- LOperand* right = instr->InputAt(1);
+ LOperand* left = instr->left();
+ LOperand* right = instr->right();
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
Condition cc = TokenToCondition(instr->op(), instr->is_double());
@@ -1581,8 +1785,8 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
- Register left = ToRegister(instr->InputAt(0));
- Register right = ToRegister(instr->InputAt(1));
+ Register left = ToRegister(instr->left());
+ Register right = ToRegister(instr->right());
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -1592,7 +1796,7 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
- Register left = ToRegister(instr->InputAt(0));
+ Register left = ToRegister(instr->left());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1602,7 +1806,7 @@ void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
int false_block = chunk_->LookupDestination(instr->false_block_id());
// If the expression is known to be untagged or a smi, then it's definitely
@@ -1632,7 +1836,7 @@ void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
__ JumpIfSmi(reg, false_label);
// Check for undetectable objects by looking in the bit field in
// the map. The object has already been smi checked.
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
__ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset));
__ testb(FieldOperand(scratch, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable));
@@ -1667,7 +1871,7 @@ Condition LCodeGen::EmitIsObject(Register input,
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1691,8 +1895,8 @@ Condition LCodeGen::EmitIsString(Register input,
void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1709,11 +1913,11 @@ void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
int false_block = chunk_->LookupDestination(instr->false_block_id());
Condition is_smi;
- if (instr->InputAt(0)->IsRegister()) {
- Register input = ToRegister(instr->InputAt(0));
+ if (instr->value()->IsRegister()) {
+ Register input = ToRegister(instr->value());
is_smi = masm()->CheckSmi(input);
} else {
- Operand input = ToOperand(instr->InputAt(0));
+ Operand input = ToOperand(instr->value());
is_smi = masm()->CheckSmi(input);
}
EmitBranch(true_block, false_block, is_smi);
@@ -1721,8 +1925,8 @@ void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
+ Register input = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1771,7 +1975,7 @@ static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1786,12 +1990,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
Register result = ToRegister(instr->result());
- if (FLAG_debug_code) {
- __ AbortIfNotString(input);
- }
+ __ AssertString(input);
__ movl(result, FieldOperand(input, String::kHashFieldOffset));
ASSERT(String::kHashShift >= kSmiTagSize);
@@ -1801,7 +2003,7 @@ void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
void LCodeGen::DoHasCachedArrayIndexAndBranch(
LHasCachedArrayIndexAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1881,9 +2083,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
- Register temp = ToRegister(instr->TempAt(0));
- Register temp2 = ToRegister(instr->TempAt(1));
+ Register input = ToRegister(instr->value());
+ Register temp = ToRegister(instr->temp());
+ Register temp2 = ToRegister(instr->temp2());
Handle<String> class_name = instr->hydrogen()->class_name();
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -1899,7 +2101,7 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
- Register reg = ToRegister(instr->InputAt(0));
+ Register reg = ToRegister(instr->value());
int true_block = instr->true_block_id();
int false_block = instr->false_block_id();
@@ -1910,8 +2112,8 @@ void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
InstanceofStub stub(InstanceofStub::kNoFlags);
- __ push(ToRegister(instr->InputAt(0)));
- __ push(ToRegister(instr->InputAt(1)));
+ __ push(ToRegister(instr->left()));
+ __ push(ToRegister(instr->right()));
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
Label true_value, done;
__ testq(rax, rax);
@@ -1945,7 +2147,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
Label done, false_result;
- Register object = ToRegister(instr->InputAt(0));
+ Register object = ToRegister(instr->value());
// A Smi is not an instance of anything.
__ JumpIfSmi(object, &false_result);
@@ -1955,7 +2157,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
// instanceof stub.
Label cache_miss;
// Use a temp register to avoid memory operands with variable lengths.
- Register map = ToRegister(instr->TempAt(0));
+ Register map = ToRegister(instr->temp());
__ movq(map, FieldOperand(object, HeapObject::kMapOffset));
__ bind(deferred->map_check()); // Label for calculating code patching.
Handle<JSGlobalPropertyCell> cache_cell =
@@ -1998,7 +2200,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck);
InstanceofStub stub(flags);
- __ push(ToRegister(instr->InputAt(0)));
+ __ push(ToRegister(instr->value()));
__ PushHeapObject(instr->function());
static const int kAdditionalDelta = 10;
@@ -2098,7 +2300,7 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
// it as no longer deleted. We deoptimize in that case.
if (instr->hydrogen()->RequiresHoleCheck()) {
// We have a temp because CompareRoot might clobber kScratchRegister.
- Register cell = ToRegister(instr->TempAt(0));
+ Register cell = ToRegister(instr->temp());
ASSERT(!value.is(cell));
__ movq(cell, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
__ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex);
@@ -2166,7 +2368,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
SmiCheck check_needed =
type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
int offset = Context::SlotOffset(instr->slot_index());
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
__ RecordWriteContextSlot(context,
offset,
value,
@@ -2181,7 +2383,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
- Register object = ToRegister(instr->InputAt(0));
+ Register object = ToRegister(instr->object());
Register result = ToRegister(instr->result());
if (instr->hydrogen()->is_in_object()) {
__ movq(result, FieldOperand(object, instr->hydrogen()->offset()));
@@ -2198,9 +2400,9 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
Handle<String> name,
LEnvironment* env) {
LookupResult lookup(isolate());
- type->LookupInDescriptors(NULL, *name, &lookup);
+ type->LookupDescriptor(NULL, *name, &lookup);
ASSERT(lookup.IsFound() || lookup.IsCacheable());
- if (lookup.IsFound() && lookup.type() == FIELD) {
+ if (lookup.IsField()) {
int index = lookup.GetLocalFieldIndexFromMap(*type);
int offset = index * kPointerSize;
if (index < 0) {
@@ -2212,7 +2414,7 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
__ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
__ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
}
- } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) {
+ } else if (lookup.IsConstantFunction()) {
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
__ LoadHeapObject(result, function);
} else {
@@ -2242,11 +2444,10 @@ static bool CompactEmit(SmallMapList* list,
Handle<Map> map = list->at(i);
// If the map has ElementsKind transitions, we will generate map checks
// for each kind in __ CompareMap(..., ALLOW_ELEMENTS_TRANSITION_MAPS).
- if (map->elements_transition_map() != NULL) return false;
+ if (map->HasElementsTransition()) return false;
LookupResult lookup(isolate);
- map->LookupInDescriptors(NULL, *name, &lookup);
- return lookup.IsFound() &&
- (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION);
+ map->LookupDescriptor(NULL, *name, &lookup);
+ return lookup.IsField() || lookup.IsConstantFunction();
}
@@ -2354,7 +2555,7 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
void LCodeGen::DoLoadElements(LLoadElements* instr) {
Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->object());
__ movq(result, FieldOperand(input, JSObject::kElementsOffset));
if (FLAG_debug_code) {
Label done, ok, fail;
@@ -2390,7 +2591,7 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
void LCodeGen::DoLoadExternalArrayPointer(
LLoadExternalArrayPointer* instr) {
Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->object());
__ movq(result, FieldOperand(input,
ExternalPixelArray::kExternalPointerOffset));
}
@@ -2400,34 +2601,39 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
Register arguments = ToRegister(instr->arguments());
Register length = ToRegister(instr->length());
Register result = ToRegister(instr->result());
-
+ // There are two words between the frame pointer and the last argument.
+ // Subtracting from length accounts for one of them add one more.
if (instr->index()->IsRegister()) {
__ subl(length, ToRegister(instr->index()));
} else {
__ subl(length, ToOperand(instr->index()));
}
- DeoptimizeIf(below_equal, instr->environment());
-
- // There are two words between the frame pointer and the last argument.
- // Subtracting from length accounts for one of them add one more.
__ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
}
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
Register result = ToRegister(instr->result());
-
- if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
- // Sign extend key because it could be a 32 bit negative value
- // and the dehoisted address computation happens in 64 bits.
- Register key_reg = ToRegister(instr->key());
- __ movsxlq(key_reg, key_reg);
+ LOperand* key = instr->key();
+ if (!key->IsConstantOperand()) {
+ Register key_reg = ToRegister(key);
+ // Even though the HLoad/StoreKeyedFastElement instructions force the input
+ // representation for the key to be an integer, the input gets replaced
+ // during bound check elimination with the index argument to the bounds
+ // check, which can be tagged, so that case must be handled here, too.
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
+ // Sign extend key because it could be a 32 bit negative value
+ // and the dehoisted address computation happens in 64 bits
+ __ movsxlq(key_reg, key_reg);
+ }
}
// Load the result.
__ movq(result,
BuildFastArrayOperand(instr->elements(),
- instr->key(),
+ key,
FAST_ELEMENTS,
FixedArray::kHeaderSize - kHeapObjectTag,
instr->additional_index()));
@@ -2448,12 +2654,20 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
void LCodeGen::DoLoadKeyedFastDoubleElement(
LLoadKeyedFastDoubleElement* instr) {
XMMRegister result(ToDoubleRegister(instr->result()));
-
- if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
- // Sign extend key because it could be a 32 bit negative value
- // and the dehoisted address computation happens in 64 bits
- Register key_reg = ToRegister(instr->key());
- __ movsxlq(key_reg, key_reg);
+ LOperand* key = instr->key();
+ if (!key->IsConstantOperand()) {
+ Register key_reg = ToRegister(key);
+ // Even though the HLoad/StoreKeyedFastElement instructions force the input
+ // representation for the key to be an integer, the input gets replaced
+ // during bound check elimination with the index argument to the bounds
+ // check, which can be tagged, so that case must be handled here, too.
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
+ // Sign extend key because it could be a 32 bit negative value
+ // and the dehoisted address computation happens in 64 bits
+ __ movsxlq(key_reg, key_reg);
+ }
}
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -2461,7 +2675,7 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
sizeof(kHoleNanLower32);
Operand hole_check_operand = BuildFastArrayOperand(
instr->elements(),
- instr->key(),
+ key,
FAST_DOUBLE_ELEMENTS,
offset,
instr->additional_index());
@@ -2471,7 +2685,7 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
Operand double_load_operand = BuildFastArrayOperand(
instr->elements(),
- instr->key(),
+ key,
FAST_DOUBLE_ELEMENTS,
FixedDoubleArray::kHeaderSize - kHeapObjectTag,
instr->additional_index());
@@ -2508,17 +2722,27 @@ Operand LCodeGen::BuildFastArrayOperand(
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) {
ElementsKind elements_kind = instr->elements_kind();
- Operand operand(BuildFastArrayOperand(instr->external_pointer(),
- instr->key(),
- elements_kind,
- 0,
- instr->additional_index()));
- if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
- // Sign extend key because it could be a 32 bit negative value
- // and the dehoisted address computation happens in 64 bits
- Register key_reg = ToRegister(instr->key());
- __ movsxlq(key_reg, key_reg);
+ LOperand* key = instr->key();
+ if (!key->IsConstantOperand()) {
+ Register key_reg = ToRegister(key);
+ // Even though the HLoad/StoreKeyedFastElement instructions force the input
+ // representation for the key to be an integer, the input gets replaced
+ // during bound check elimination with the index argument to the bounds
+ // check, which can be tagged, so that case must be handled here, too.
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
+ // Sign extend key because it could be a 32 bit negative value
+ // and the dehoisted address computation happens in 64 bits
+ __ movsxlq(key_reg, key_reg);
+ }
}
+ Operand operand(BuildFastArrayOperand(
+ instr->external_pointer(),
+ key,
+ elements_kind,
+ 0,
+ instr->additional_index()));
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
XMMRegister result(ToDoubleRegister(instr->result()));
@@ -2547,11 +2771,10 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
break;
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ movl(result, operand);
- __ testl(result, result);
- // TODO(danno): we could be more clever here, perhaps having a special
- // version of the stub that detects if the overflow case actually
- // happens, and generate code that returns a double rather than int.
- DeoptimizeIf(negative, instr->environment());
+ if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
+ __ testl(result, result);
+ DeoptimizeIf(negative, instr->environment());
+ }
break;
case EXTERNAL_FLOAT_ELEMENTS:
case EXTERNAL_DOUBLE_ELEMENTS:
@@ -2613,10 +2836,10 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
Label done;
// If no arguments adaptor frame the number of arguments is fixed.
- if (instr->InputAt(0)->IsRegister()) {
- __ cmpq(rbp, ToRegister(instr->InputAt(0)));
+ if (instr->elements()->IsRegister()) {
+ __ cmpq(rbp, ToRegister(instr->elements()));
} else {
- __ cmpq(rbp, ToOperand(instr->InputAt(0)));
+ __ cmpq(rbp, ToOperand(instr->elements()));
}
__ movl(result, Immediate(scope()->num_parameters()));
__ j(equal, &done, Label::kNear);
@@ -2673,7 +2896,7 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
// TODO(kmillikin): We have a hydrogen value for the global object. See
// if it's better to use it than to explicitly fetch it from the context
// here.
- __ movq(receiver, ContextOperand(rsi, Context::GLOBAL_INDEX));
+ __ movq(receiver, ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX));
__ movq(receiver,
FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
__ bind(&receiver_ok);
@@ -2724,7 +2947,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
void LCodeGen::DoPushArgument(LPushArgument* instr) {
- LOperand* argument = instr->InputAt(0);
+ LOperand* argument = instr->value();
EmitPushTaggedOperand(argument);
}
@@ -2736,7 +2959,7 @@ void LCodeGen::DoDrop(LDrop* instr) {
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
- __ LoadHeapObject(result, instr->hydrogen()->closure());
+ __ movq(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
}
@@ -2791,14 +3014,8 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
__ LoadHeapObject(rdi, function);
}
- // Change context if needed.
- bool change_context =
- (info()->closure()->context() != function->context()) ||
- scope()->contains_with() ||
- (scope()->num_heap_slots() > 0);
- if (change_context) {
- __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
- }
+ // Change context.
+ __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
// Set rax to arguments count if adaption is not needed. Assumes that rax
// is available to write to at this point.
@@ -2840,7 +3057,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
- Register input_reg = ToRegister(instr->InputAt(0));
+ Register input_reg = ToRegister(instr->value());
__ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
DeoptimizeIf(not_equal, instr->environment());
@@ -2892,7 +3109,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
- Register input_reg = ToRegister(instr->InputAt(0));
+ Register input_reg = ToRegister(instr->value());
__ testl(input_reg, input_reg);
Label is_positive;
__ j(not_sign, &is_positive);
@@ -2917,12 +3134,12 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
LUnaryMathOperation* instr_;
};
- ASSERT(instr->InputAt(0)->Equals(instr->result()));
+ ASSERT(instr->value()->Equals(instr->result()));
Representation r = instr->hydrogen()->value()->representation();
if (r.IsDouble()) {
XMMRegister scratch = xmm0;
- XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+ XMMRegister input_reg = ToDoubleRegister(instr->value());
__ xorps(scratch, scratch);
__ subsd(scratch, input_reg);
__ andpd(input_reg, scratch);
@@ -2931,7 +3148,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
} else { // Tagged case.
DeferredMathAbsTaggedHeapNumber* deferred =
new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
- Register input_reg = ToRegister(instr->InputAt(0));
+ Register input_reg = ToRegister(instr->value());
// Smi check.
__ JumpIfNotSmi(input_reg, deferred->entry());
__ SmiToInteger32(input_reg, input_reg);
@@ -2945,8 +3162,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
XMMRegister xmm_scratch = xmm0;
Register output_reg = ToRegister(instr->result());
- XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
- Label done;
+ XMMRegister input_reg = ToDoubleRegister(instr->value());
if (CpuFeatures::IsSupported(SSE4_1)) {
CpuFeatures::Scope scope(SSE4_1);
@@ -2961,10 +3177,13 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
__ cmpl(output_reg, Immediate(0x80000000));
DeoptimizeIf(equal, instr->environment());
} else {
+ Label negative_sign, done;
// Deoptimize on negative inputs.
__ xorps(xmm_scratch, xmm_scratch); // Zero the register.
__ ucomisd(input_reg, xmm_scratch);
- DeoptimizeIf(below, instr->environment());
+ DeoptimizeIf(parity_even, instr->environment());
+ __ j(below, &negative_sign, Label::kNear);
+
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Check for negative zero.
Label positive_sign;
@@ -2979,19 +3198,30 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
// Use truncating instruction (OK because input is positive).
__ cvttsd2si(output_reg, input_reg);
-
// Overflow is signalled with minint.
__ cmpl(output_reg, Immediate(0x80000000));
DeoptimizeIf(equal, instr->environment());
+ __ jmp(&done, Label::kNear);
+
+ // Non-zero negative reaches here.
+ __ bind(&negative_sign);
+ // Truncate, then compare and compensate.
+ __ cvttsd2si(output_reg, input_reg);
+ __ cvtlsi2sd(xmm_scratch, output_reg);
+ __ ucomisd(input_reg, xmm_scratch);
+ __ j(equal, &done, Label::kNear);
+ __ subl(output_reg, Immediate(1));
+ DeoptimizeIf(overflow, instr->environment());
+
+ __ bind(&done);
}
- __ bind(&done);
}
void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
const XMMRegister xmm_scratch = xmm0;
Register output_reg = ToRegister(instr->result());
- XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+ XMMRegister input_reg = ToDoubleRegister(instr->value());
Label done;
// xmm_scratch = 0.5
@@ -3036,7 +3266,7 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
- XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+ XMMRegister input_reg = ToDoubleRegister(instr->value());
ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
__ sqrtsd(input_reg, input_reg);
}
@@ -3044,7 +3274,7 @@ void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
XMMRegister xmm_scratch = xmm0;
- XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+ XMMRegister input_reg = ToDoubleRegister(instr->value());
ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
// Note that according to ECMA-262 15.8.2.13:
@@ -3085,11 +3315,11 @@ void LCodeGen::DoPower(LPower* instr) {
#else
Register exponent = rdi;
#endif
- ASSERT(!instr->InputAt(1)->IsRegister() ||
- ToRegister(instr->InputAt(1)).is(exponent));
- ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
- ToDoubleRegister(instr->InputAt(1)).is(xmm1));
- ASSERT(ToDoubleRegister(instr->InputAt(0)).is(xmm2));
+ ASSERT(!instr->right()->IsRegister() ||
+ ToRegister(instr->right()).is(exponent));
+ ASSERT(!instr->right()->IsDoubleRegister() ||
+ ToDoubleRegister(instr->right()).is(xmm1));
+ ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
if (exponent_type.IsTagged()) {
@@ -3131,10 +3361,10 @@ void LCodeGen::DoRandom(LRandom* instr) {
// Choose the right register for the first argument depending on
// calling convention.
#ifdef _WIN64
- ASSERT(ToRegister(instr->InputAt(0)).is(rcx));
+ ASSERT(ToRegister(instr->global_object()).is(rcx));
Register global_object = rcx;
#else
- ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
+ ASSERT(ToRegister(instr->global_object()).is(rdi));
Register global_object = rdi;
#endif
@@ -3142,11 +3372,11 @@ void LCodeGen::DoRandom(LRandom* instr) {
STATIC_ASSERT(kPointerSize == 2 * kSeedSize);
__ movq(global_object,
- FieldOperand(global_object, GlobalObject::kGlobalContextOffset));
+ FieldOperand(global_object, GlobalObject::kNativeContextOffset));
static const int kRandomSeedOffset =
FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
__ movq(rbx, FieldOperand(global_object, kRandomSeedOffset));
- // rbx: FixedArray of the global context's random seeds
+ // rbx: FixedArray of the native context's random seeds
// Load state[0].
__ movl(rax, FieldOperand(rbx, ByteArray::kHeaderSize));
@@ -3349,7 +3579,7 @@ void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
void LCodeGen::DoCallNew(LCallNew* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
+ ASSERT(ToRegister(instr->constructor()).is(rdi));
ASSERT(ToRegister(instr->result()).is(rax));
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
@@ -3373,7 +3603,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
__ Move(FieldOperand(object, HeapObject::kMapOffset),
instr->transition());
} else {
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
__ Move(kScratchRegister, instr->transition());
__ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister);
// Update the write barrier for the map field.
@@ -3394,7 +3624,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
if (instr->is_in_object()) {
__ movq(FieldOperand(object, offset), value);
if (instr->hydrogen()->NeedsWriteBarrier()) {
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
// Update the write barrier for the object for in-object properties.
__ RecordWriteField(object,
offset,
@@ -3405,7 +3635,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
check_needed);
}
} else {
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
__ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset));
__ movq(FieldOperand(temp, offset), value);
if (instr->hydrogen()->NeedsWriteBarrier()) {
@@ -3438,18 +3668,27 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
void LCodeGen::DoStoreKeyedSpecializedArrayElement(
LStoreKeyedSpecializedArrayElement* instr) {
ElementsKind elements_kind = instr->elements_kind();
- Operand operand(BuildFastArrayOperand(instr->external_pointer(),
- instr->key(),
- elements_kind,
- 0,
- instr->additional_index()));
-
- if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
- // Sign extend key because it could be a 32 bit negative value
- // and the dehoisted address computation happens in 64 bits
- Register key_reg = ToRegister(instr->key());
- __ movsxlq(key_reg, key_reg);
+ LOperand* key = instr->key();
+ if (!key->IsConstantOperand()) {
+ Register key_reg = ToRegister(key);
+ // Even though the HLoad/StoreKeyedFastElement instructions force the input
+ // representation for the key to be an integer, the input gets replaced
+ // during bound check elimination with the index argument to the bounds
+ // check, which can be tagged, so that case must be handled here, too.
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
+ // Sign extend key because it could be a 32 bit negative value
+ // and the dehoisted address computation happens in 64 bits
+ __ movsxlq(key_reg, key_reg);
+ }
}
+ Operand operand(BuildFastArrayOperand(
+ instr->external_pointer(),
+ key,
+ elements_kind,
+ 0,
+ instr->additional_index()));
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
XMMRegister value(ToDoubleRegister(instr->value()));
@@ -3490,28 +3729,60 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
}
+void LCodeGen::DeoptIfTaggedButNotSmi(LEnvironment* environment,
+ HValue* value,
+ LOperand* operand) {
+ if (value->representation().IsTagged() && !value->type().IsSmi()) {
+ Condition cc;
+ if (operand->IsRegister()) {
+ cc = masm()->CheckSmi(ToRegister(operand));
+ } else {
+ cc = masm()->CheckSmi(ToOperand(operand));
+ }
+ DeoptimizeIf(NegateCondition(cc), environment);
+ }
+}
+
+
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
+ DeoptIfTaggedButNotSmi(instr->environment(),
+ instr->hydrogen()->length(),
+ instr->length());
+ DeoptIfTaggedButNotSmi(instr->environment(),
+ instr->hydrogen()->index(),
+ instr->index());
if (instr->length()->IsRegister()) {
Register reg = ToRegister(instr->length());
- if (FLAG_debug_code) {
- __ AbortIfNotZeroExtended(reg);
+ if (!instr->hydrogen()->length()->representation().IsTagged()) {
+ __ AssertZeroExtended(reg);
}
if (instr->index()->IsConstantOperand()) {
- __ cmpq(reg,
- Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
+ int constant_index =
+ ToInteger32(LConstantOperand::cast(instr->index()));
+ if (instr->hydrogen()->length()->representation().IsTagged()) {
+ __ Cmp(reg, Smi::FromInt(constant_index));
+ } else {
+ __ cmpq(reg, Immediate(constant_index));
+ }
} else {
Register reg2 = ToRegister(instr->index());
- if (FLAG_debug_code) {
- __ AbortIfNotZeroExtended(reg2);
+ if (!instr->hydrogen()->index()->representation().IsTagged()) {
+ __ AssertZeroExtended(reg2);
}
__ cmpq(reg, reg2);
}
} else {
+ Operand length = ToOperand(instr->length());
if (instr->index()->IsConstantOperand()) {
- __ cmpq(ToOperand(instr->length()),
- Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
+ int constant_index =
+ ToInteger32(LConstantOperand::cast(instr->index()));
+ if (instr->hydrogen()->length()->representation().IsTagged()) {
+ __ Cmp(length, Smi::FromInt(constant_index));
+ } else {
+ __ cmpq(length, Immediate(constant_index));
+ }
} else {
- __ cmpq(ToOperand(instr->length()), ToRegister(instr->index()));
+ __ cmpq(length, ToRegister(instr->index()));
}
}
DeoptimizeIf(below_equal, instr->environment());
@@ -3521,37 +3792,46 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
Register value = ToRegister(instr->value());
Register elements = ToRegister(instr->object());
- Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
+ LOperand* key = instr->key();
+ if (!key->IsConstantOperand()) {
+ Register key_reg = ToRegister(key);
+ // Even though the HLoad/StoreKeyedFastElement instructions force the input
+ // representation for the key to be an integer, the input gets replaced
+ // during bound check elimination with the index argument to the bounds
+ // check, which can be tagged, so that case must be handled here, too.
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
+ // Sign extend key because it could be a 32 bit negative value
+ // and the dehoisted address computation happens in 64 bits
+ __ movsxlq(key_reg, key_reg);
+ }
+ }
Operand operand =
BuildFastArrayOperand(instr->object(),
- instr->key(),
+ key,
FAST_ELEMENTS,
FixedArray::kHeaderSize - kHeapObjectTag,
instr->additional_index());
- if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
- // Sign extend key because it could be a 32 bit negative value
- // and the dehoisted address computation happens in 64 bits
- Register key_reg = ToRegister(instr->key());
- __ movsxlq(key_reg, key_reg);
- }
-
- __ movq(operand, value);
-
if (instr->hydrogen()->NeedsWriteBarrier()) {
ASSERT(!instr->key()->IsConstantOperand());
HType type = instr->hydrogen()->value()->type();
SmiCheck check_needed =
type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
// Compute address of modified element and store it into key register.
- __ lea(key, operand);
+ Register key_reg(ToRegister(key));
+ __ lea(key_reg, operand);
+ __ movq(Operand(key_reg, 0), value);
__ RecordWrite(elements,
- key,
+ key_reg,
value,
kSaveFPRegs,
EMIT_REMEMBERED_SET,
check_needed);
+ } else {
+ __ movq(operand, value);
}
}
@@ -3559,6 +3839,21 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
void LCodeGen::DoStoreKeyedFastDoubleElement(
LStoreKeyedFastDoubleElement* instr) {
XMMRegister value = ToDoubleRegister(instr->value());
+ LOperand* key = instr->key();
+ if (!key->IsConstantOperand()) {
+ Register key_reg = ToRegister(key);
+ // Even though the HLoad/StoreKeyedFastElement instructions force the input
+ // representation for the key to be an integer, the input gets replaced
+ // during bound check elimination with the index argument to the bounds
+ // check, which can be tagged, so that case must be handled here, too.
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
+ // Sign extend key because it could be a 32 bit negative value
+ // and the dehoisted address computation happens in 64 bits
+ __ movsxlq(key_reg, key_reg);
+ }
+ }
if (instr->NeedsCanonicalization()) {
Label have_value;
@@ -3575,18 +3870,11 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
Operand double_store_operand = BuildFastArrayOperand(
instr->elements(),
- instr->key(),
+ key,
FAST_DOUBLE_ELEMENTS,
FixedDoubleArray::kHeaderSize - kHeapObjectTag,
instr->additional_index());
- if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
- // Sign extend key because it could be a 32 bit negative value
- // and the dehoisted address computation happens in 64 bits
- Register key_reg = ToRegister(instr->key());
- __ movsxlq(key_reg, key_reg);
- }
-
__ movsd(double_store_operand, value);
}
@@ -3604,7 +3892,7 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
Register object_reg = ToRegister(instr->object());
- Register new_map_reg = ToRegister(instr->new_map_reg());
+ Register new_map_reg = ToRegister(instr->new_map_temp());
Handle<Map> from_map = instr->original_map();
Handle<Map> to_map = instr->transitioned_map();
@@ -3618,12 +3906,12 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
__ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg);
// Write barrier.
- ASSERT_NE(instr->temp_reg(), NULL);
+ ASSERT_NE(instr->temp(), NULL);
__ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
- ToRegister(instr->temp_reg()), kDontSaveFPRegs);
+ ToRegister(instr->temp()), kDontSaveFPRegs);
} else if (IsFastSmiElementsKind(from_kind) &&
IsFastDoubleElementsKind(to_kind)) {
- Register fixed_object_reg = ToRegister(instr->temp_reg());
+ Register fixed_object_reg = ToRegister(instr->temp());
ASSERT(fixed_object_reg.is(rdx));
ASSERT(new_map_reg.is(rbx));
__ movq(fixed_object_reg, object_reg);
@@ -3631,7 +3919,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
RelocInfo::CODE_TARGET, instr);
} else if (IsFastDoubleElementsKind(from_kind) &&
IsFastObjectElementsKind(to_kind)) {
- Register fixed_object_reg = ToRegister(instr->temp_reg());
+ Register fixed_object_reg = ToRegister(instr->temp());
ASSERT(fixed_object_reg.is(rdx));
ASSERT(new_map_reg.is(rbx));
__ movq(fixed_object_reg, object_reg);
@@ -3698,9 +3986,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
__ push(index);
}
CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
- if (FLAG_debug_code) {
- __ AbortIfNotSmi(rax);
- }
+ __ AssertSmi(rax);
__ SmiToInteger32(rax, rax);
__ StoreToSafepointRegisterSlot(result, rax);
}
@@ -3762,7 +4048,7 @@ void LCodeGen::DoStringLength(LStringLength* instr) {
void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister() || input->IsStackSlot());
LOperand* output = instr->result();
ASSERT(output->IsDoubleRegister());
@@ -3774,8 +4060,19 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
}
+void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
+ LOperand* input = instr->value();
+ LOperand* output = instr->result();
+ LOperand* temp = instr->temp();
+
+ __ LoadUint32(ToDoubleRegister(output),
+ ToRegister(input),
+ ToDoubleRegister(temp));
+}
+
+
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister() && input->Equals(instr->result()));
Register reg = ToRegister(input);
@@ -3783,6 +4080,69 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
}
+void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
+ class DeferredNumberTagU: public LDeferredCode {
+ public:
+ DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
+ : LDeferredCode(codegen), instr_(instr) { }
+ virtual void Generate() {
+ codegen()->DoDeferredNumberTagU(instr_);
+ }
+ virtual LInstruction* instr() { return instr_; }
+ private:
+ LNumberTagU* instr_;
+ };
+
+ LOperand* input = instr->value();
+ ASSERT(input->IsRegister() && input->Equals(instr->result()));
+ Register reg = ToRegister(input);
+
+ DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
+ __ cmpl(reg, Immediate(Smi::kMaxValue));
+ __ j(above, deferred->entry());
+ __ Integer32ToSmi(reg, reg);
+ __ bind(deferred->exit());
+}
+
+
+void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) {
+ Label slow;
+ Register reg = ToRegister(instr->value());
+ Register tmp = reg.is(rax) ? rcx : rax;
+
+ // Preserve the value of all registers.
+ PushSafepointRegistersScope scope(this);
+
+ Label done;
+ // Load value into xmm1 which will be preserved across potential call to
+ // runtime (MacroAssembler::EnterExitFrameEpilogue preserves only allocatable
+ // XMM registers on x64).
+ __ LoadUint32(xmm1, reg, xmm0);
+
+ if (FLAG_inline_new) {
+ __ AllocateHeapNumber(reg, tmp, &slow);
+ __ jmp(&done, Label::kNear);
+ }
+
+ // Slow case: Call the runtime system to do the number allocation.
+ __ bind(&slow);
+
+ // Put a valid pointer value in the stack slot where the result
+ // register is stored, as this register is in the pointer map, but contains an
+ // integer value.
+ __ StoreToSafepointRegisterSlot(reg, Immediate(0));
+
+ CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
+ if (!reg.is(rax)) __ movq(reg, rax);
+
+ // Done. Put the value in xmm1 into the value of the allocated heap
+ // number.
+ __ bind(&done);
+ __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm1);
+ __ StoreToSafepointRegisterSlot(reg, reg);
+}
+
+
void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
class DeferredNumberTagD: public LDeferredCode {
public:
@@ -3794,9 +4154,9 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
LNumberTagD* instr_;
};
- XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+ XMMRegister input_reg = ToDoubleRegister(instr->value());
Register reg = ToRegister(instr->result());
- Register tmp = ToRegister(instr->TempAt(0));
+ Register tmp = ToRegister(instr->temp());
DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
if (FLAG_inline_new) {
@@ -3827,23 +4187,21 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
void LCodeGen::DoSmiTag(LSmiTag* instr) {
- ASSERT(instr->InputAt(0)->Equals(instr->result()));
- Register input = ToRegister(instr->InputAt(0));
+ ASSERT(instr->value()->Equals(instr->result()));
+ Register input = ToRegister(instr->value());
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
__ Integer32ToSmi(input, input);
}
void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
- ASSERT(instr->InputAt(0)->Equals(instr->result()));
- Register input = ToRegister(instr->InputAt(0));
+ ASSERT(instr->value()->Equals(instr->result()));
+ Register input = ToRegister(instr->value());
if (instr->needs_check()) {
Condition is_smi = __ CheckSmi(input);
DeoptimizeIf(NegateCondition(is_smi), instr->environment());
} else {
- if (FLAG_debug_code) {
- __ AbortIfNotSmi(input);
- }
+ __ AssertSmi(input);
}
__ SmiToInteger32(input, input);
}
@@ -3901,7 +4259,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
Label done, heap_number;
- Register input_reg = ToRegister(instr->InputAt(0));
+ Register input_reg = ToRegister(instr->value());
// Heap number map check.
__ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
@@ -3927,7 +4285,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
// Deoptimize if we don't have a heap number.
DeoptimizeIf(not_equal, instr->environment());
- XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
+ XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
__ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ cvttsd2si(input_reg, xmm0);
__ cvtlsi2sd(xmm_temp, input_reg);
@@ -3957,7 +4315,7 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
LTaggedToI* instr_;
};
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
ASSERT(input->Equals(instr->result()));
@@ -3970,7 +4328,7 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
LOperand* result = instr->result();
ASSERT(result->IsDoubleRegister());
@@ -3986,7 +4344,7 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsDoubleRegister());
LOperand* result = instr->result();
ASSERT(result->IsRegister());
@@ -4026,21 +4384,21 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
Condition cc = masm()->CheckSmi(ToRegister(input));
DeoptimizeIf(NegateCondition(cc), instr->environment());
}
void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
Condition cc = masm()->CheckSmi(ToRegister(input));
DeoptimizeIf(cc, instr->environment());
}
void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
__ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset));
@@ -4112,7 +4470,7 @@ void LCodeGen::DoCheckMapCommon(Register reg,
void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
@@ -4132,8 +4490,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
Register result_reg = ToRegister(instr->result());
- Register temp_reg = ToRegister(instr->TempAt(0));
- __ ClampDoubleToUint8(value_reg, xmm0, result_reg, temp_reg);
+ __ ClampDoubleToUint8(value_reg, xmm0, result_reg);
}
@@ -4147,8 +4504,7 @@ void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
ASSERT(instr->unclamped()->Equals(instr->result()));
Register input_reg = ToRegister(instr->unclamped());
- Register temp_reg = ToRegister(instr->TempAt(0));
- XMMRegister temp_xmm_reg = ToDoubleRegister(instr->TempAt(1));
+ XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp_xmm());
Label is_smi, done, heap_number;
__ JumpIfSmi(input_reg, &is_smi);
@@ -4168,7 +4524,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
// Heap number
__ bind(&heap_number);
__ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
- __ ClampDoubleToUint8(xmm0, temp_xmm_reg, input_reg, temp_reg);
+ __ ClampDoubleToUint8(xmm0, temp_xmm_reg, input_reg);
__ jmp(&done, Label::kNear);
// smi
@@ -4181,7 +4537,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
- Register reg = ToRegister(instr->TempAt(0));
+ Register reg = ToRegister(instr->temp());
Handle<JSObject> holder = instr->holder();
Handle<JSObject> current_prototype = instr->prototype();
@@ -4220,7 +4576,7 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
new(zone()) DeferredAllocateObject(this, instr);
Register result = ToRegister(instr->result());
- Register scratch = ToRegister(instr->TempAt(0));
+ Register scratch = ToRegister(instr->temp());
Handle<JSFunction> constructor = instr->hydrogen()->constructor();
Handle<Map> initial_map(constructor->initial_map());
int instance_size = initial_map->instance_size();
@@ -4253,7 +4609,7 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
__ movq(map, FieldOperand(scratch, JSFunction::kPrototypeOrInitialMapOffset));
if (FLAG_debug_code) {
- __ AbortIfSmi(map);
+ __ AssertNotSmi(map);
__ cmpb(FieldOperand(map, Map::kInstanceSizeOffset),
Immediate(instance_size >> kPointerSizeLog2));
__ Assert(equal, "Unexpected instance size");
@@ -4303,7 +4659,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
- Heap* heap = isolate()->heap();
+ Handle<FixedArray> literals(instr->environment()->closure()->literals());
ElementsKind boilerplate_elements_kind =
instr->hydrogen()->boilerplate_elements_kind();
@@ -4324,12 +4680,11 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
}
// Set up the parameters to the stub/runtime call.
- __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
- __ push(FieldOperand(rax, JSFunction::kLiteralsOffset));
+ __ PushHeapObject(literals);
__ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
// Boilerplate already exists, constant elements are never accessed.
// Pass an empty fixed array.
- __ Push(Handle<FixedArray>(heap->empty_fixed_array()));
+ __ Push(isolate()->factory()->empty_fixed_array());
// Pick the right runtime function or stub to call.
int length = instr->hydrogen()->length();
@@ -4523,7 +4878,7 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
- ASSERT(ToRegister(instr->InputAt(0)).is(rax));
+ ASSERT(ToRegister(instr->value()).is(rax));
__ push(rax);
CallRuntime(Runtime::kToFastProperties, 1, instr);
}
@@ -4532,14 +4887,12 @@ void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
Label materialized;
// Registers will be used as follows:
- // rdi = JS function.
// rcx = literals array.
// rbx = regexp literal.
// rax = regexp literal clone.
- __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
- __ movq(rcx, FieldOperand(rdi, JSFunction::kLiteralsOffset));
- int literal_offset = FixedArray::kHeaderSize +
- instr->hydrogen()->literal_index() * kPointerSize;
+ int literal_offset =
+ FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+ __ LoadHeapObject(rcx, instr->hydrogen()->literals());
__ movq(rbx, FieldOperand(rcx, literal_offset));
__ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
__ j(not_equal, &materialized, Label::kNear);
@@ -4602,7 +4955,7 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
void LCodeGen::DoTypeof(LTypeof* instr) {
- LOperand* input = instr->InputAt(0);
+ LOperand* input = instr->value();
EmitPushTaggedOperand(input);
CallRuntime(Runtime::kTypeof, 1, instr);
}
@@ -4626,7 +4979,7 @@ void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
- Register input = ToRegister(instr->InputAt(0));
+ Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* true_label = chunk_->GetAssemblyLabel(true_block);
@@ -4712,7 +5065,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
- Register temp = ToRegister(instr->TempAt(0));
+ Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -4908,11 +5261,19 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
Register map = ToRegister(instr->map());
Register result = ToRegister(instr->result());
+ Label load_cache, done;
+ __ EnumLength(result, map);
+ __ Cmp(result, Smi::FromInt(0));
+ __ j(not_equal, &load_cache);
+ __ LoadRoot(result, Heap::kEmptyFixedArrayRootIndex);
+ __ jmp(&done);
+ __ bind(&load_cache);
__ LoadInstanceDescriptors(map, result);
__ movq(result,
- FieldOperand(result, DescriptorArray::kEnumerationIndexOffset));
+ FieldOperand(result, DescriptorArray::kEnumCacheOffset));
__ movq(result,
FieldOperand(result, FixedArray::SizeFor(instr->idx())));
+ __ bind(&done);
Condition cc = masm()->CheckSmi(result);
DeoptimizeIf(cc, instr->environment());
}
diff --git a/deps/v8/src/x64/lithium-codegen-x64.h b/deps/v8/src/x64/lithium-codegen-x64.h
index 99e7ec824..65b398016 100644
--- a/deps/v8/src/x64/lithium-codegen-x64.h
+++ b/deps/v8/src/x64/lithium-codegen-x64.h
@@ -45,26 +45,25 @@ class SafepointGenerator;
class LCodeGen BASE_EMBEDDED {
public:
- LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info,
- Zone* zone)
- : chunk_(chunk),
+ LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
+ : zone_(info->zone()),
+ chunk_(static_cast<LPlatformChunk*>(chunk)),
masm_(assembler),
info_(info),
current_block_(-1),
current_instruction_(-1),
instructions_(chunk->instructions()),
- deoptimizations_(4, zone),
- jump_table_(4, zone),
- deoptimization_literals_(8, zone),
+ deoptimizations_(4, info->zone()),
+ jump_table_(4, info->zone()),
+ deoptimization_literals_(8, info->zone()),
inlined_function_count_(0),
scope_(info->scope()),
status_(UNUSED),
- translations_(zone),
- deferred_(8, zone),
+ translations_(info->zone()),
+ deferred_(8, info->zone()),
osr_pc_offset_(-1),
last_lazy_deopt_pc_(0),
- safepoints_(zone),
- zone_(zone),
+ safepoints_(info->zone()),
resolver_(this),
expected_safepoint_kind_(Safepoint::kSimple) {
PopulateDeoptimizationLiteralsWithInlinedFunctions();
@@ -99,6 +98,7 @@ class LCodeGen BASE_EMBEDDED {
// Deferred code support.
void DoDeferredNumberTagD(LNumberTagD* instr);
+ void DoDeferredNumberTagU(LNumberTagU* instr);
void DoDeferredTaggedToI(LTaggedToI* instr);
void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
void DoDeferredStackCheck(LStackCheck* instr);
@@ -117,7 +117,10 @@ class LCodeGen BASE_EMBEDDED {
void DoGap(LGap* instr);
// Emit frame translation commands for an environment.
- void WriteTranslation(LEnvironment* environment, Translation* translation);
+ void WriteTranslation(LEnvironment* environment,
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count);
// Declare methods that deal with the individual node types.
#define DECLARE_DO(type) void Do##type(L##type* node);
@@ -141,7 +144,7 @@ class LCodeGen BASE_EMBEDDED {
return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
}
- LChunk* chunk() const { return chunk_; }
+ LPlatformChunk* chunk() const { return chunk_; }
Scope* scope() const { return scope_; }
HGraph* graph() const { return chunk_->graph(); }
@@ -157,7 +160,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
int GetParameterCount() const { return scope()->num_parameters(); }
- void Abort(const char* format, ...);
+ void Abort(const char* reason);
void Comment(const char* format, ...);
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
@@ -224,7 +227,10 @@ class LCodeGen BASE_EMBEDDED {
void AddToTranslation(Translation* translation,
LOperand* op,
- bool is_tagged);
+ bool is_tagged,
+ bool is_uint32,
+ int arguments_index,
+ int arguments_count);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
@@ -272,6 +278,11 @@ class LCodeGen BASE_EMBEDDED {
bool deoptimize_on_minus_zero,
LEnvironment* env);
+
+ void DeoptIfTaggedButNotSmi(LEnvironment* environment,
+ HValue* value,
+ LOperand* operand);
+
// Emits optimized code for typeof x == "y". Modifies input register.
// Returns the condition on which a final split to
// true and false label should be made, to optimize fallthrough.
@@ -325,7 +336,8 @@ class LCodeGen BASE_EMBEDDED {
void EnsureSpaceForLazyDeopt(int space_needed);
- LChunk* const chunk_;
+ Zone* zone_;
+ LPlatformChunk* const chunk_;
MacroAssembler* const masm_;
CompilationInfo* const info_;
@@ -347,8 +359,6 @@ class LCodeGen BASE_EMBEDDED {
// itself is emitted at the end of the generated code.
SafepointTableBuilder safepoints_;
- Zone* zone_;
-
// Compiler from a set of parallel moves to a sequential list of moves.
LGapResolver resolver_;
diff --git a/deps/v8/src/x64/lithium-x64.cc b/deps/v8/src/x64/lithium-x64.cc
index d06a6a406..43fb8b9ba 100644
--- a/deps/v8/src/x64/lithium-x64.cc
+++ b/deps/v8/src/x64/lithium-x64.cc
@@ -196,22 +196,22 @@ void LGoto::PrintDataTo(StringStream* stream) {
void LBranch::PrintDataTo(StringStream* stream) {
stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
- InputAt(0)->PrintTo(stream);
+ left()->PrintTo(stream);
stream->Add(" %s ", Token::String(op()));
- InputAt(1)->PrintTo(stream);
+ right()->PrintTo(stream);
stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
}
void LIsNilAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(kind() == kStrictEquality ? " === " : " == ");
stream->Add(nil() == kNullValue ? "null" : "undefined");
stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
@@ -220,57 +220,57 @@ void LIsNilAndBranch::PrintDataTo(StringStream* stream) {
void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_object(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsStringAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_string(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_smi(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsUndetectableAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_undetectable(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LStringCompareAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if string_compare(");
- InputAt(0)->PrintTo(stream);
- InputAt(1)->PrintTo(stream);
+ left()->PrintTo(stream);
+ right()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if has_instance_type(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if has_cached_array_index(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if class_of_test(");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(", \"%o\") then B%d else B%d",
*hydrogen()->class_name(),
true_block_id(),
@@ -280,7 +280,7 @@ void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if typeof ");
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
stream->Add(" == \"%s\" then B%d else B%d",
*hydrogen()->type_literal()->ToCString(),
true_block_id(), false_block_id());
@@ -294,26 +294,26 @@ void LCallConstantFunction::PrintDataTo(StringStream* stream) {
void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
stream->Add("/%s ", hydrogen()->OpName());
- InputAt(0)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LLoadContextSlot::PrintDataTo(StringStream* stream) {
- InputAt(0)->PrintTo(stream);
+ context()->PrintTo(stream);
stream->Add("[%d]", slot_index());
}
void LStoreContextSlot::PrintDataTo(StringStream* stream) {
- InputAt(0)->PrintTo(stream);
+ context()->PrintTo(stream);
stream->Add("[%d] <- ", slot_index());
- InputAt(1)->PrintTo(stream);
+ value()->PrintTo(stream);
}
void LInvokeFunction::PrintDataTo(StringStream* stream) {
stream->Add("= ");
- InputAt(0)->PrintTo(stream);
+ function()->PrintTo(stream);
stream->Add(" #%d / ", arity());
}
@@ -342,7 +342,7 @@ void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
void LCallNew::PrintDataTo(StringStream* stream) {
stream->Add("= ");
- InputAt(0)->PrintTo(stream);
+ constructor()->PrintTo(stream);
stream->Add(" #%d / ", arity());
}
@@ -358,12 +358,12 @@ void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
}
-int LChunk::GetNextSpillIndex(bool is_double) {
+int LPlatformChunk::GetNextSpillIndex(bool is_double) {
return spill_slot_count_++;
}
-LOperand* LChunk::GetNextSpillSlot(bool is_double) {
+LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) {
// All stack slots are Double stack slots on x64.
// Alternatively, at some point, start using half-size
// stack slots for int32 values.
@@ -376,42 +376,6 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) {
}
-void LChunk::MarkEmptyBlocks() {
- HPhase phase("L_Mark empty blocks", this);
- for (int i = 0; i < graph()->blocks()->length(); ++i) {
- HBasicBlock* block = graph()->blocks()->at(i);
- int first = block->first_instruction_index();
- int last = block->last_instruction_index();
- LInstruction* first_instr = instructions()->at(first);
- LInstruction* last_instr = instructions()->at(last);
-
- LLabel* label = LLabel::cast(first_instr);
- if (last_instr->IsGoto()) {
- LGoto* goto_instr = LGoto::cast(last_instr);
- if (label->IsRedundant() &&
- !label->is_loop_header()) {
- bool can_eliminate = true;
- for (int i = first + 1; i < last && can_eliminate; ++i) {
- LInstruction* cur = instructions()->at(i);
- if (cur->IsGap()) {
- LGap* gap = LGap::cast(cur);
- if (!gap->IsRedundant()) {
- can_eliminate = false;
- }
- } else {
- can_eliminate = false;
- }
- }
-
- if (can_eliminate) {
- label->set_replacement(GetLabel(goto_instr->block_id()));
- }
- }
- }
- }
-}
-
-
void LStoreNamedField::PrintDataTo(StringStream* stream) {
object()->PrintTo(stream);
stream->Add(".");
@@ -463,84 +427,9 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) {
}
-void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
- LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
- int index = -1;
- if (instr->IsControl()) {
- instructions_.Add(gap, zone());
- index = instructions_.length();
- instructions_.Add(instr, zone());
- } else {
- index = instructions_.length();
- instructions_.Add(instr, zone());
- instructions_.Add(gap, zone());
- }
- if (instr->HasPointerMap()) {
- pointer_maps_.Add(instr->pointer_map(), zone());
- instr->pointer_map()->set_lithium_position(index);
- }
-}
-
-
-LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
- return LConstantOperand::Create(constant->id(), zone());
-}
-
-
-int LChunk::GetParameterStackSlot(int index) const {
- // The receiver is at index 0, the first parameter at index 1, so we
- // shift all parameter indexes down by the number of parameters, and
- // make sure they end up negative so they are distinguishable from
- // spill slots.
- int result = index - info()->scope()->num_parameters() - 1;
- ASSERT(result < 0);
- return result;
-}
-
-// A parameter relative to ebp in the arguments stub.
-int LChunk::ParameterAt(int index) {
- ASSERT(-1 <= index); // -1 is the receiver.
- return (1 + info()->scope()->num_parameters() - index) *
- kPointerSize;
-}
-
-
-LGap* LChunk::GetGapAt(int index) const {
- return LGap::cast(instructions_[index]);
-}
-
-
-bool LChunk::IsGapAt(int index) const {
- return instructions_[index]->IsGap();
-}
-
-
-int LChunk::NearestGapPos(int index) const {
- while (!IsGapAt(index)) index--;
- return index;
-}
-
-
-void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
- GetGapAt(index)->GetOrCreateParallelMove(
- LGap::START, zone())->AddMove(from, to, zone());
-}
-
-
-Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
- return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
-}
-
-
-Representation LChunk::LookupLiteralRepresentation(
- LConstantOperand* operand) const {
- return graph_->LookupValue(operand->index())->representation();
-}
-
-
-LChunk* LChunkBuilder::Build() {
+LPlatformChunk* LChunkBuilder::Build() {
ASSERT(is_unused());
- chunk_ = new(zone()) LChunk(info(), graph());
+ chunk_ = new(zone()) LPlatformChunk(info(), graph());
HPhase phase("L_Building chunk", chunk_);
status_ = BUILDING;
const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
@@ -555,17 +444,8 @@ LChunk* LChunkBuilder::Build() {
}
-void LChunkBuilder::Abort(const char* format, ...) {
- if (FLAG_trace_bailout) {
- SmartArrayPointer<char> name(
- info()->shared_info()->DebugName()->ToCString());
- PrintF("Aborting LChunk building in @\"%s\": ", *name);
- va_list arguments;
- va_start(arguments, format);
- OS::VPrint(format, arguments);
- va_end(arguments);
- PrintF("\n");
- }
+void LCodeGen::Abort(const char* reason) {
+ info()->set_bailout_reason(reason);
status_ = ABORTED;
}
@@ -736,7 +616,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
ASSERT(hinstr->next()->IsSimulate());
HSimulate* sim = HSimulate::cast(hinstr->next());
ASSERT(instruction_pending_deoptimization_environment_ == NULL);
- ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
+ ASSERT(pending_deoptimization_ast_id_.IsNone());
instruction_pending_deoptimization_environment_ = instr;
pending_deoptimization_ast_id_ = sim->ast_id();
}
@@ -831,13 +711,16 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
// Shift operations can only deoptimize if we do a logical shift by 0 and
// the result cannot be truncated to int32.
- bool may_deopt = (op == Token::SHR && constant_value == 0);
bool does_deopt = false;
- if (may_deopt) {
- for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
- if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
- does_deopt = true;
- break;
+ if (op == Token::SHR && constant_value == 0) {
+ if (FLAG_opt_safe_uint32_operations) {
+ does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+ } else {
+ for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
+ if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
+ does_deopt = true;
+ break;
+ }
}
}
}
@@ -970,8 +853,8 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
LEnvironment* outer =
CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator);
- int ast_id = hydrogen_env->ast_id();
- ASSERT(ast_id != AstNode::kNoNumber ||
+ BailoutId ast_id = hydrogen_env->ast_id();
+ ASSERT(!ast_id.IsNone() ||
hydrogen_env->frame_type() != JS_FUNCTION);
int value_count = hydrogen_env->length();
LEnvironment* result = new(zone()) LEnvironment(
@@ -982,6 +865,7 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
argument_count_,
value_count,
outer,
+ hydrogen_env->entry(),
zone());
int argument_index = *argument_index_accumulator;
for (int i = 0; i < value_count; ++i) {
@@ -996,7 +880,9 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
} else {
op = UseAny(value);
}
- result->AddValue(op, value->representation());
+ result->AddValue(op,
+ value->representation(),
+ value->CheckFlag(HInstruction::kUint32));
}
if (hydrogen_env->frame_type() == JS_FUNCTION) {
@@ -1287,12 +1173,55 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
}
-LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
- UNIMPLEMENTED();
+HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) {
+ // A value with an integer representation does not need to be transformed.
+ if (dividend->representation().IsInteger32()) {
+ return dividend;
+ // A change from an integer32 can be replaced by the integer32 value.
+ } else if (dividend->IsChange() &&
+ HChange::cast(dividend)->from().IsInteger32()) {
+ return HChange::cast(dividend)->value();
+ }
return NULL;
}
+HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) {
+ if (divisor->IsConstant() &&
+ HConstant::cast(divisor)->HasInteger32Value()) {
+ HConstant* constant_val = HConstant::cast(divisor);
+ return constant_val->CopyToRepresentation(Representation::Integer32(),
+ divisor->block()->zone());
+ }
+ return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
+ HValue* right = instr->right();
+ ASSERT(right->IsConstant() && HConstant::cast(right)->HasInteger32Value());
+ LOperand* divisor = chunk_->DefineConstantOperand(HConstant::cast(right));
+ int32_t divisor_si = HConstant::cast(right)->Integer32Value();
+ if (divisor_si == 0) {
+ LOperand* dividend = UseRegister(instr->left());
+ return AssignEnvironment(DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, NULL)));
+ } else if (IsPowerOf2(abs(divisor_si))) {
+ LOperand* dividend = UseRegisterAtStart(instr->left());
+ LInstruction* result = DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, NULL));
+ return divisor_si < 0 ? AssignEnvironment(result) : result;
+ } else {
+ // use two r64
+ LOperand* dividend = UseRegisterAtStart(instr->left());
+ LOperand* temp = TempRegister();
+ LInstruction* result = DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, temp));
+ return divisor_si < 0 ? AssignEnvironment(result) : result;
+ }
+}
+
+
LInstruction* LChunkBuilder::DoMod(HMod* instr) {
if (instr->representation().IsInteger32()) {
ASSERT(instr->left()->representation().IsInteger32());
@@ -1398,6 +1327,26 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
+LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
+ LOperand* left = NULL;
+ LOperand* right = NULL;
+ if (instr->representation().IsInteger32()) {
+ ASSERT(instr->left()->representation().IsInteger32());
+ ASSERT(instr->right()->representation().IsInteger32());
+ left = UseRegisterAtStart(instr->LeastConstantOperand());
+ right = UseOrConstantAtStart(instr->MostConstantOperand());
+ } else {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->left()->representation().IsDouble());
+ ASSERT(instr->right()->representation().IsDouble());
+ left = UseRegisterAtStart(instr->left());
+ right = UseRegisterAtStart(instr->right());
+ }
+ LMathMinMax* minmax = new(zone()) LMathMinMax(left, right);
+ return DefineSameAsFirst(minmax);
+}
+
+
LInstruction* LChunkBuilder::DoPower(HPower* instr) {
ASSERT(instr->representation().IsDouble());
// We call a C function for double power. It can't trigger a GC.
@@ -1580,6 +1529,12 @@ LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
}
+LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
+ LOperand* map = UseRegisterAtStart(instr->value());
+ return DefineAsRegister(new(zone()) LMapEnumLength(map));
+}
+
+
LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
LOperand* object = UseRegisterAtStart(instr->value());
return DefineAsRegister(new(zone()) LElementsKind(object));
@@ -1596,7 +1551,7 @@ LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
LOperand* object = UseFixed(instr->value(), rax);
LDateField* result = new(zone()) LDateField(object, instr->index());
- return MarkAsCall(DefineFixed(result, rax), instr);
+ return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY);
}
@@ -1671,16 +1626,26 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
if (to.IsTagged()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val);
- if (val->HasRange() && val->range()->IsInSmiRange()) {
+ if (val->CheckFlag(HInstruction::kUint32)) {
+ LOperand* temp = FixedTemp(xmm1);
+ LNumberTagU* result = new(zone()) LNumberTagU(value, temp);
+ return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
+ } else if (val->HasRange() && val->range()->IsInSmiRange()) {
return DefineSameAsFirst(new(zone()) LSmiTag(value));
} else {
LNumberTagI* result = new(zone()) LNumberTagI(value);
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
}
} else {
- ASSERT(to.IsDouble());
- LOperand* value = Use(instr->value());
- return DefineAsRegister(new(zone()) LInteger32ToDouble(value));
+ if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+ LOperand* temp = FixedTemp(xmm1);
+ return DefineAsRegister(
+ new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
+ } else {
+ ASSERT(to.IsDouble());
+ LOperand* value = Use(instr->value());
+ return DefineAsRegister(new(zone()) LInteger32ToDouble(value));
+ }
}
}
UNREACHABLE();
@@ -1732,8 +1697,7 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
Representation input_rep = value->representation();
LOperand* reg = UseRegister(value);
if (input_rep.IsDouble()) {
- return DefineAsRegister(new(zone()) LClampDToUint8(reg,
- TempRegister()));
+ return DefineAsRegister(new(zone()) LClampDToUint8(reg));
} else if (input_rep.IsInteger32()) {
return DefineSameAsFirst(new(zone()) LClampIToUint8(reg));
} else {
@@ -1741,7 +1705,6 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
// Register allocator doesn't (yet) support allocation of double
// temps. Reserve xmm1 explicitly.
LClampTToUint8* result = new(zone()) LClampTToUint8(reg,
- TempRegister(),
FixedTemp(xmm1));
return AssignEnvironment(DefineSameAsFirst(result));
}
@@ -1883,10 +1846,15 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
HLoadKeyedFastElement* instr) {
ASSERT(instr->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* obj = UseRegisterAtStart(instr->object());
- LOperand* key = UseRegisterOrConstantAtStart(instr->key());
- LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key);
+ bool clobbers_key = instr->key()->representation().IsTagged();
+ LOperand* key = clobbers_key
+ ? UseTempRegister(instr->key())
+ : UseRegisterOrConstantAtStart(instr->key());
+ LLoadKeyedFastElement* result =
+ new(zone()) LLoadKeyedFastElement(obj, key);
if (instr->RequiresHoleCheck()) AssignEnvironment(result);
return DefineAsRegister(result);
}
@@ -1895,9 +1863,13 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
HLoadKeyedFastDoubleElement* instr) {
ASSERT(instr->representation().IsDouble());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* elements = UseRegisterAtStart(instr->elements());
- LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+ bool clobbers_key = instr->key()->representation().IsTagged();
+ LOperand* key = clobbers_key
+ ? UseTempRegister(instr->key())
+ : UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastDoubleElement* result =
new(zone()) LLoadKeyedFastDoubleElement(elements, key);
return AssignEnvironment(DefineAsRegister(result));
@@ -1914,9 +1886,13 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
(instr->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer());
- LOperand* key = UseRegisterOrConstant(instr->key());
+ bool clobbers_key = instr->key()->representation().IsTagged();
+ LOperand* key = clobbers_key
+ ? UseTempRegister(instr->key())
+ : UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedSpecializedArrayElement* result =
new(zone()) LLoadKeyedSpecializedArrayElement(external_pointer, key);
LInstruction* load_instr = DefineAsRegister(result);
@@ -1941,13 +1917,16 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
bool needs_write_barrier = instr->NeedsWriteBarrier();
ASSERT(instr->value()->representation().IsTagged());
ASSERT(instr->object()->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* obj = UseTempRegister(instr->object());
LOperand* val = needs_write_barrier
? UseTempRegister(instr->value())
: UseRegisterAtStart(instr->value());
- LOperand* key = needs_write_barrier
+ bool clobbers_key = needs_write_barrier ||
+ instr->key()->representation().IsTagged();
+ LOperand* key = clobbers_key
? UseTempRegister(instr->key())
: UseRegisterOrConstantAtStart(instr->key());
return new(zone()) LStoreKeyedFastElement(obj, key, val);
@@ -1958,12 +1937,15 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
HStoreKeyedFastDoubleElement* instr) {
ASSERT(instr->value()->representation().IsDouble());
ASSERT(instr->elements()->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* elements = UseRegisterAtStart(instr->elements());
LOperand* val = UseTempRegister(instr->value());
- LOperand* key = UseRegisterOrConstantAtStart(instr->key());
-
+ bool clobbers_key = instr->key()->representation().IsTagged();
+ LOperand* key = clobbers_key
+ ? UseTempRegister(instr->key())
+ : UseRegisterOrConstantAtStart(instr->key());
return new(zone()) LStoreKeyedFastDoubleElement(elements, key, val);
}
@@ -1979,7 +1961,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32() ||
+ instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer());
bool val_is_temp_register =
@@ -1988,11 +1971,12 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
LOperand* val = val_is_temp_register
? UseTempRegister(instr->value())
: UseRegister(instr->value());
- LOperand* key = UseRegisterOrConstant(instr->key());
-
+ bool clobbers_key = instr->key()->representation().IsTagged();
+ LOperand* key = clobbers_key
+ ? UseTempRegister(instr->key())
+ : UseRegisterOrConstantAtStart(instr->key());
return new(zone()) LStoreKeyedSpecializedArrayElement(external_pointer,
- key,
- val);
+ key, val);
}
@@ -2142,6 +2126,7 @@ LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
+ ASSERT(argument_count_ == 0);
allocator_->MarkAsOsrEntry();
current_block_->last_environment()->set_ast_id(instr->ast_id());
return AssignEnvironment(new(zone()) LOsrEntry);
@@ -2180,12 +2165,10 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
- LOperand* arguments = UseRegister(instr->arguments());
+ LOperand* args = UseRegister(instr->arguments());
LOperand* length = UseTempRegister(instr->length());
LOperand* index = Use(instr->index());
- LAccessArgumentsAt* result =
- new(zone()) LAccessArgumentsAt(arguments, length, index);
- return AssignEnvironment(DefineAsRegister(result));
+ return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
}
@@ -2239,7 +2222,7 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
instruction_pending_deoptimization_environment_->
SetDeferredLazyDeoptimizationEnvironment(result->environment());
instruction_pending_deoptimization_environment_ = NULL;
- pending_deoptimization_ast_id_ = AstNode::kNoNumber;
+ pending_deoptimization_ast_id_ = BailoutId::None();
return result;
}
@@ -2265,10 +2248,11 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
instr->function(),
undefined,
instr->call_kind(),
- instr->is_construct());
+ instr->inlining_kind());
if (instr->arguments_var() != NULL) {
inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
}
+ inner->set_entry(instr);
current_block_->UpdateEnvironment(inner);
chunk_->AddInlinedClosure(instr->closure());
return NULL;
@@ -2280,7 +2264,7 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
HEnvironment* env = current_block_->last_environment();
- if (instr->arguments_pushed()) {
+ if (env->entry()->arguments_pushed()) {
int argument_count = env->arguments_environment()->parameter_count();
pop = new(zone()) LDrop(argument_count);
argument_count_ -= argument_count;
diff --git a/deps/v8/src/x64/lithium-x64.h b/deps/v8/src/x64/lithium-x64.h
index d038dda06..6cf4af661 100644
--- a/deps/v8/src/x64/lithium-x64.h
+++ b/deps/v8/src/x64/lithium-x64.h
@@ -96,6 +96,7 @@ class LCodeGen;
V(ElementsKind) \
V(FastLiteral) \
V(FixedArrayBaseLength) \
+ V(MapEnumLength) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
@@ -108,6 +109,7 @@ class LCodeGen;
V(InstanceOfKnownGlobal) \
V(InstructionGap) \
V(Integer32ToDouble) \
+ V(Uint32ToDouble) \
V(InvokeFunction) \
V(IsConstructCallAndBranch) \
V(IsNilAndBranch) \
@@ -115,7 +117,6 @@ class LCodeGen;
V(IsStringAndBranch) \
V(IsSmiAndBranch) \
V(IsUndetectableAndBranch) \
- V(StringCompareAndBranch) \
V(JSArrayLength) \
V(Label) \
V(LazyBailout) \
@@ -132,10 +133,13 @@ class LCodeGen;
V(LoadNamedField) \
V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
+ V(MathFloorOfDiv) \
+ V(MathMinMax) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
V(NumberTagI) \
+ V(NumberTagU) \
V(NumberUntagD) \
V(ObjectLiteral) \
V(OsrEntry) \
@@ -162,6 +166,7 @@ class LCodeGen;
V(StringAdd) \
V(StringCharCodeAt) \
V(StringCharFromCode) \
+ V(StringCompareAndBranch) \
V(StringLength) \
V(SubI) \
V(TaggedToI) \
@@ -257,11 +262,6 @@ class LInstruction: public ZoneObject {
virtual bool HasResult() const = 0;
virtual LOperand* result() = 0;
- virtual int InputCount() = 0;
- virtual LOperand* InputAt(int i) = 0;
- virtual int TempCount() = 0;
- virtual LOperand* TempAt(int i) = 0;
-
LOperand* FirstInput() { return InputAt(0); }
LOperand* Output() { return HasResult() ? result() : NULL; }
@@ -270,6 +270,15 @@ class LInstruction: public ZoneObject {
#endif
private:
+ // Iterator support.
+ friend class InputIterator;
+ virtual int InputCount() = 0;
+ virtual LOperand* InputAt(int i) = 0;
+
+ friend class TempIterator;
+ virtual int TempCount() = 0;
+ virtual LOperand* TempAt(int i) = 0;
+
LEnvironment* environment_;
SetOncePointer<LPointerMap> pointer_map_;
HValue* hydrogen_value_;
@@ -289,16 +298,18 @@ class LTemplateInstruction: public LInstruction {
void set_result(LOperand* operand) { results_[0] = operand; }
LOperand* result() { return results_[0]; }
- int InputCount() { return I; }
- LOperand* InputAt(int i) { return inputs_[i]; }
-
- int TempCount() { return T; }
- LOperand* TempAt(int i) { return temps_[i]; }
-
protected:
EmbeddedContainer<LOperand*, R> results_;
EmbeddedContainer<LOperand*, I> inputs_;
EmbeddedContainer<LOperand*, T> temps_;
+
+ private:
+ // Iterator support.
+ virtual int InputCount() { return I; }
+ virtual LOperand* InputAt(int i) { return inputs_[i]; }
+
+ virtual int TempCount() { return T; }
+ virtual LOperand* TempAt(int i) { return temps_[i]; }
};
@@ -465,10 +476,10 @@ class LWrapReceiver: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = function;
}
- DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
-
LOperand* receiver() { return inputs_[0]; }
LOperand* function() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
};
@@ -484,12 +495,12 @@ class LApplyArguments: public LTemplateInstruction<1, 4, 0> {
inputs_[3] = elements;
}
- DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
-
LOperand* function() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* length() { return inputs_[2]; }
LOperand* elements() { return inputs_[3]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
};
@@ -501,12 +512,12 @@ class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> {
inputs_[2] = index;
}
- DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
-
LOperand* arguments() { return inputs_[0]; }
LOperand* length() { return inputs_[1]; }
LOperand* index() { return inputs_[2]; }
+ DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
+
virtual void PrintDataTo(StringStream* stream);
};
@@ -517,6 +528,8 @@ class LArgumentsLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = elements;
}
+ LOperand* elements() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
};
@@ -536,6 +549,10 @@ class LModI: public LTemplateInstruction<1, 2, 1> {
temps_[0] = temp;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
DECLARE_HYDROGEN_ACCESSOR(Mod)
};
@@ -549,11 +566,34 @@ class LDivI: public LTemplateInstruction<1, 2, 1> {
temps_[0] = temp;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(Div)
};
+class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> {
+ public:
+ LMathFloorOfDiv(LOperand* left,
+ LOperand* right,
+ LOperand* temp = NULL) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ temps_[0] = temp;
+ }
+
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
+ DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
class LMulI: public LTemplateInstruction<1, 2, 0> {
public:
LMulI(LOperand* left, LOperand* right) {
@@ -561,6 +601,9 @@ class LMulI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
DECLARE_HYDROGEN_ACCESSOR(Mul)
};
@@ -573,6 +616,9 @@ class LCmpIDAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
@@ -591,6 +637,8 @@ class LUnaryMathOperation: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
@@ -606,6 +654,9 @@ class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch,
"cmp-object-eq-and-branch")
};
@@ -617,6 +668,8 @@ class LCmpConstantEqAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = left;
}
+ LOperand* left() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpConstantEqAndBranch,
"cmp-constant-eq-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareConstantEqAndBranch)
@@ -630,6 +683,9 @@ class LIsNilAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch, "is-nil-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsNilAndBranch)
@@ -646,6 +702,8 @@ class LIsObjectAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
@@ -660,6 +718,9 @@ class LIsStringAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
@@ -673,6 +734,8 @@ class LIsSmiAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
@@ -687,6 +750,9 @@ class LIsUndetectableAndBranch: public LControlInstruction<1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
"is-undetectable-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
@@ -702,6 +768,9 @@ class LStringCompareAndBranch: public LControlInstruction<2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
"string-compare-and-branch")
DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
@@ -718,6 +787,8 @@ class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
"has-instance-type-and-branch")
DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
@@ -732,6 +803,8 @@ class LGetCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
};
@@ -743,6 +816,8 @@ class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
"has-cached-array-index-and-branch")
DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
@@ -759,6 +834,10 @@ class LClassOfTestAndBranch: public LControlInstruction<1, 2> {
temps_[1] = temp2;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
"class-of-test-and-branch")
DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
@@ -774,6 +853,9 @@ class LCmpT: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
@@ -802,6 +884,9 @@ class LInstanceOf: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
};
@@ -813,6 +898,9 @@ class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
"instance-of-known-global")
DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
@@ -841,6 +929,7 @@ class LBoundsCheck: public LTemplateInstruction<0, 2, 0> {
LOperand* length() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
+ DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
};
@@ -851,6 +940,9 @@ class LBitI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
Token::Value op() const { return hydrogen()->op(); }
DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
@@ -867,7 +959,8 @@ class LShiftI: public LTemplateInstruction<1, 2, 0> {
}
Token::Value op() const { return op_; }
-
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
bool can_deopt() const { return can_deopt_; }
DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
@@ -885,6 +978,9 @@ class LSubI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
DECLARE_HYDROGEN_ACCESSOR(Sub)
};
@@ -904,6 +1000,9 @@ class LConstantD: public LTemplateInstruction<1, 0, 1> {
explicit LConstantD(LOperand* temp) {
temps_[0] = temp;
}
+
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
DECLARE_HYDROGEN_ACCESSOR(Constant)
@@ -926,6 +1025,8 @@ class LBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
DECLARE_HYDROGEN_ACCESSOR(Branch)
@@ -939,6 +1040,8 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMap)
@@ -960,6 +1063,8 @@ class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
};
@@ -971,18 +1076,34 @@ class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength,
"fixed-array-base-length")
DECLARE_HYDROGEN_ACCESSOR(FixedArrayBaseLength)
};
+class LMapEnumLength: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LMapEnumLength(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
+};
+
+
class LElementsKind: public LTemplateInstruction<1, 1, 0> {
public:
explicit LElementsKind(LOperand* value) {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
};
@@ -994,6 +1115,8 @@ class LValueOf: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
DECLARE_HYDROGEN_ACCESSOR(ValueOf)
};
@@ -1005,11 +1128,12 @@ class LDateField: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = date;
}
+ LOperand* date() { return inputs_[0]; }
+ Smi* index() const { return index_; }
+
DECLARE_CONCRETE_INSTRUCTION(ValueOf, "date-field")
DECLARE_HYDROGEN_ACCESSOR(ValueOf)
- Smi* index() const { return index_; }
-
private:
Smi* index_;
};
@@ -1021,6 +1145,8 @@ class LThrow: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
};
@@ -1031,6 +1157,8 @@ class LBitNotI: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
};
@@ -1042,11 +1170,29 @@ class LAddI: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
DECLARE_HYDROGEN_ACCESSOR(Add)
};
+class LMathMinMax: public LTemplateInstruction<1, 2, 0> {
+ public:
+ LMathMinMax(LOperand* left, LOperand* right) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ }
+
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "min-max")
+ DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
+};
+
+
class LPower: public LTemplateInstruction<1, 2, 0> {
public:
LPower(LOperand* left, LOperand* right) {
@@ -1054,6 +1200,9 @@ class LPower: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(Power, "power")
DECLARE_HYDROGEN_ACCESSOR(Power)
};
@@ -1065,6 +1214,8 @@ class LRandom: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = global_object;
}
+ LOperand* global_object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Random, "random")
DECLARE_HYDROGEN_ACCESSOR(Random)
};
@@ -1079,6 +1230,8 @@ class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
}
Token::Value op() const { return op_; }
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
virtual Opcode opcode() const { return LInstruction::kArithmeticD; }
virtual void CompileToNative(LCodeGen* generator);
@@ -1097,12 +1250,14 @@ class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
+ Token::Value op() const { return op_; }
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
- Token::Value op() const { return op_; }
-
private:
Token::Value op_;
};
@@ -1114,6 +1269,8 @@ class LReturn: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Return, "return")
};
@@ -1124,6 +1281,8 @@ class LLoadNamedField: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
};
@@ -1175,6 +1334,8 @@ class LLoadElements: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
};
@@ -1185,6 +1346,8 @@ class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = object;
}
+ LOperand* object() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
"load-external-array-pointer")
};
@@ -1286,10 +1449,11 @@ class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
-
- LOperand* value() { return inputs_[0]; }
};
@@ -1301,12 +1465,13 @@ class LStoreGlobalGeneric: public LTemplateInstruction<0, 2, 0> {
inputs_[1] = value;
}
+ LOperand* global_object() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric)
- LOperand* global_object() { return InputAt(0); }
Handle<Object> name() const { return hydrogen()->name(); }
- LOperand* value() { return InputAt(1); }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1317,10 +1482,11 @@ class LLoadContextSlot: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
+ LOperand* context() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
- LOperand* context() { return InputAt(0); }
int slot_index() { return hydrogen()->slot_index(); }
virtual void PrintDataTo(StringStream* stream);
@@ -1335,11 +1501,13 @@ class LStoreContextSlot: public LTemplateInstruction<0, 2, 1> {
temps_[0] = temp;
}
+ LOperand* context() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
- LOperand* context() { return InputAt(0); }
- LOperand* value() { return InputAt(1); }
int slot_index() { return hydrogen()->slot_index(); }
virtual void PrintDataTo(StringStream* stream);
@@ -1352,6 +1520,8 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
};
@@ -1388,9 +1558,9 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = context;
}
- DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
+ LOperand* context() { return inputs_[0]; }
- LOperand* context() { return InputAt(0); }
+ DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
};
@@ -1413,9 +1583,9 @@ class LGlobalReceiver: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = global_object;
}
- DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
+ LOperand* global() { return inputs_[0]; }
- LOperand* global() { return InputAt(0); }
+ DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
};
@@ -1437,11 +1607,11 @@ class LInvokeFunction: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = function;
}
+ LOperand* function() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
- LOperand* function() { return inputs_[0]; }
-
virtual void PrintDataTo(StringStream* stream);
int arity() const { return hydrogen()->argument_count() - 1; }
@@ -1522,6 +1692,8 @@ class LCallNew: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = constructor;
}
+ LOperand* constructor() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
DECLARE_HYDROGEN_ACCESSOR(CallNew)
@@ -1547,20 +1719,52 @@ class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
};
+class LUint32ToDouble: public LTemplateInstruction<1, 1, 1> {
+ public:
+ explicit LUint32ToDouble(LOperand* value, LOperand* temp) {
+ inputs_[0] = value;
+ temps_[0] = temp;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
+};
+
+
class LNumberTagI: public LTemplateInstruction<1, 1, 0> {
public:
explicit LNumberTagI(LOperand* value) {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
};
+class LNumberTagU: public LTemplateInstruction<1, 1, 1> {
+ public:
+ explicit LNumberTagU(LOperand* value, LOperand* temp) {
+ inputs_[0] = value;
+ temps_[0] = temp;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
+};
+
+
class LNumberTagD: public LTemplateInstruction<1, 1, 1> {
public:
explicit LNumberTagD(LOperand* value, LOperand* temp) {
@@ -1568,6 +1772,9 @@ class LNumberTagD: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
};
@@ -1579,6 +1786,8 @@ class LDoubleToI: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
@@ -1594,6 +1803,9 @@ class LTaggedToI: public LTemplateInstruction<1, 1, 1> {
temps_[0] = temp;
}
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
@@ -1607,6 +1819,8 @@ class LSmiTag: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
};
@@ -1617,6 +1831,8 @@ class LNumberUntagD: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
DECLARE_HYDROGEN_ACCESSOR(Change);
};
@@ -1629,10 +1845,11 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
- DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
-
+ LOperand* value() { return inputs_[0]; }
bool needs_check() const { return needs_check_; }
+ DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
+
private:
bool needs_check_;
};
@@ -1646,14 +1863,15 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
temps_[0] = temp;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* value() { return inputs_[1]; }
-
Handle<Object> name() const { return hydrogen()->name(); }
bool is_in_object() { return hydrogen()->is_in_object(); }
int offset() { return hydrogen()->offset(); }
@@ -1668,13 +1886,14 @@ class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
inputs_[1] = value;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* value() { return inputs_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* value() { return inputs_[1]; }
Handle<Object> name() const { return hydrogen()->name(); }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1682,21 +1901,22 @@ class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
public:
- LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val) {
- inputs_[0] = obj;
+ LStoreKeyedFastElement(LOperand* object, LOperand* key, LOperand* value) {
+ inputs_[0] = object;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
"store-keyed-fast-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1705,22 +1925,22 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
public:
LStoreKeyedFastDoubleElement(LOperand* elements,
LOperand* key,
- LOperand* val) {
+ LOperand* value) {
inputs_[0] = elements;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* elements() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement,
"store-keyed-fast-double-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastDoubleElement)
virtual void PrintDataTo(StringStream* stream);
- LOperand* elements() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
-
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1730,22 +1950,21 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
public:
LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
LOperand* key,
- LOperand* val) {
+ LOperand* value) {
inputs_[0] = external_pointer;
inputs_[1] = key;
- inputs_[2] = val;
+ inputs_[2] = value;
}
+ LOperand* external_pointer() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
"store-keyed-specialized-array-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
- LOperand* external_pointer() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
- ElementsKind elements_kind() const {
- return hydrogen()->elements_kind();
- }
+ ElementsKind elements_kind() const { return hydrogen()->elements_kind(); }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1758,14 +1977,15 @@ class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> {
inputs_[2] = value;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* key() { return inputs_[1]; }
+ LOperand* value() { return inputs_[2]; }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
};
@@ -1774,21 +1994,22 @@ class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> {
public:
LTransitionElementsKind(LOperand* object,
LOperand* new_map_temp,
- LOperand* temp_reg) {
+ LOperand* temp) {
inputs_[0] = object;
temps_[0] = new_map_temp;
- temps_[1] = temp_reg;
+ temps_[1] = temp;
}
+ LOperand* object() { return inputs_[0]; }
+ LOperand* new_map_temp() { return temps_[0]; }
+ LOperand* temp() { return temps_[1]; }
+
DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
"transition-elements-kind")
DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
virtual void PrintDataTo(StringStream* stream);
- LOperand* object() { return inputs_[0]; }
- LOperand* new_map_reg() { return temps_[0]; }
- LOperand* temp_reg() { return temps_[1]; }
Handle<Map> original_map() { return hydrogen()->original_map(); }
Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); }
};
@@ -1801,11 +2022,11 @@ class LStringAdd: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
- DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
- DECLARE_HYDROGEN_ACCESSOR(StringAdd)
-
LOperand* left() { return inputs_[0]; }
LOperand* right() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
+ DECLARE_HYDROGEN_ACCESSOR(StringAdd)
};
@@ -1816,11 +2037,11 @@ class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = index;
}
- DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
- DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
-
LOperand* string() { return inputs_[0]; }
LOperand* index() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
+ DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
};
@@ -1830,10 +2051,10 @@ class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = char_code;
}
+ LOperand* char_code() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
-
- LOperand* char_code() { return inputs_[0]; }
};
@@ -1843,10 +2064,10 @@ class LStringLength: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = string;
}
+ LOperand* string() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
DECLARE_HYDROGEN_ACCESSOR(StringLength)
-
- LOperand* string() { return inputs_[0]; }
};
@@ -1856,7 +2077,7 @@ class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
- LOperand* value() { return InputAt(0); }
+ LOperand* value() { return inputs_[0]; }
DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
@@ -1869,6 +2090,8 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
};
@@ -1880,6 +2103,8 @@ class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
};
@@ -1891,6 +2116,8 @@ class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 1> {
temps_[0] = temp;
}
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
@@ -1905,15 +2132,16 @@ class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
};
-class LClampDToUint8: public LTemplateInstruction<1, 1, 1> {
+class LClampDToUint8: public LTemplateInstruction<1, 1, 0> {
public:
- LClampDToUint8(LOperand* value, LOperand* temp) {
- inputs_[0] = value;
- temps_[0] = temp;
+ explicit LClampDToUint8(LOperand* unclamped) {
+ inputs_[0] = unclamped;
}
LOperand* unclamped() { return inputs_[0]; }
@@ -1924,8 +2152,8 @@ class LClampDToUint8: public LTemplateInstruction<1, 1, 1> {
class LClampIToUint8: public LTemplateInstruction<1, 1, 0> {
public:
- explicit LClampIToUint8(LOperand* value) {
- inputs_[0] = value;
+ explicit LClampIToUint8(LOperand* unclamped) {
+ inputs_[0] = unclamped;
}
LOperand* unclamped() { return inputs_[0]; }
@@ -1934,17 +2162,16 @@ class LClampIToUint8: public LTemplateInstruction<1, 1, 0> {
};
-class LClampTToUint8: public LTemplateInstruction<1, 1, 2> {
+class LClampTToUint8: public LTemplateInstruction<1, 1, 1> {
public:
- LClampTToUint8(LOperand* value,
- LOperand* temp,
- LOperand* temp2) {
- inputs_[0] = value;
- temps_[0] = temp;
- temps_[1] = temp2;
+ LClampTToUint8(LOperand* unclamped,
+ LOperand* temp_xmm) {
+ inputs_[0] = unclamped;
+ temps_[0] = temp_xmm;
}
LOperand* unclamped() { return inputs_[0]; }
+ LOperand* temp_xmm() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
};
@@ -1956,6 +2183,8 @@ class LCheckNonSmi: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
};
@@ -1966,6 +2195,8 @@ class LAllocateObject: public LTemplateInstruction<1, 0, 1> {
temps_[0] = temp;
}
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object")
DECLARE_HYDROGEN_ACCESSOR(AllocateObject)
};
@@ -2014,6 +2245,8 @@ class LToFastProperties: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
};
@@ -2025,6 +2258,8 @@ class LTypeof: public LTemplateInstruction<1, 1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
};
@@ -2035,6 +2270,8 @@ class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
inputs_[0] = value;
}
+ LOperand* value() { return inputs_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
@@ -2050,6 +2287,8 @@ class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
temps_[0] = temp;
}
+ LOperand* temp() { return temps_[0]; }
+
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
"is-construct-call-and-branch")
DECLARE_HYDROGEN_ACCESSOR(IsConstructCallAndBranch)
@@ -2063,10 +2302,10 @@ class LDeleteProperty: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
-
LOperand* object() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
};
@@ -2162,71 +2401,13 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> {
class LChunkBuilder;
-class LChunk: public ZoneObject {
+class LPlatformChunk: public LChunk {
public:
- LChunk(CompilationInfo* info, HGraph* graph)
- : spill_slot_count_(0),
- info_(info),
- graph_(graph),
- instructions_(32, graph->zone()),
- pointer_maps_(8, graph->zone()),
- inlined_closures_(1, graph->zone()) { }
-
- void AddInstruction(LInstruction* instruction, HBasicBlock* block);
- LConstantOperand* DefineConstantOperand(HConstant* constant);
- Handle<Object> LookupLiteral(LConstantOperand* operand) const;
- Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
+ LPlatformChunk(CompilationInfo* info, HGraph* graph)
+ : LChunk(info, graph) { }
int GetNextSpillIndex(bool is_double);
LOperand* GetNextSpillSlot(bool is_double);
-
- int ParameterAt(int index);
- int GetParameterStackSlot(int index) const;
- int spill_slot_count() const { return spill_slot_count_; }
- CompilationInfo* info() const { return info_; }
- HGraph* graph() const { return graph_; }
- const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
- void AddGapMove(int index, LOperand* from, LOperand* to);
- LGap* GetGapAt(int index) const;
- bool IsGapAt(int index) const;
- int NearestGapPos(int index) const;
- void MarkEmptyBlocks();
- const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
- LLabel* GetLabel(int block_id) const {
- HBasicBlock* block = graph_->blocks()->at(block_id);
- int first_instruction = block->first_instruction_index();
- return LLabel::cast(instructions_[first_instruction]);
- }
- int LookupDestination(int block_id) const {
- LLabel* cur = GetLabel(block_id);
- while (cur->replacement() != NULL) {
- cur = cur->replacement();
- }
- return cur->block_id();
- }
- Label* GetAssemblyLabel(int block_id) const {
- LLabel* label = GetLabel(block_id);
- ASSERT(!label->HasReplacement());
- return label->label();
- }
-
- const ZoneList<Handle<JSFunction> >* inlined_closures() const {
- return &inlined_closures_;
- }
-
- void AddInlinedClosure(Handle<JSFunction> closure) {
- inlined_closures_.Add(closure, zone());
- }
-
- Zone* zone() const { return graph_->zone(); }
-
- private:
- int spill_slot_count_;
- CompilationInfo* info_;
- HGraph* const graph_;
- ZoneList<LInstruction*> instructions_;
- ZoneList<LPointerMap*> pointer_maps_;
- ZoneList<Handle<JSFunction> > inlined_closures_;
};
@@ -2245,16 +2426,19 @@ class LChunkBuilder BASE_EMBEDDED {
allocator_(allocator),
position_(RelocInfo::kNoPosition),
instruction_pending_deoptimization_environment_(NULL),
- pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
+ pending_deoptimization_ast_id_(BailoutId::None()) { }
// Build the sequence for the graph.
- LChunk* Build();
+ LPlatformChunk* Build();
// Declare methods that deal with the individual node types.
#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
+ static HValue* SimplifiedDividendForMathFloorOfDiv(HValue* val);
+ static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
+
private:
enum Status {
UNUSED,
@@ -2263,7 +2447,7 @@ class LChunkBuilder BASE_EMBEDDED {
ABORTED
};
- LChunk* chunk() const { return chunk_; }
+ LPlatformChunk* chunk() const { return chunk_; }
CompilationInfo* info() const { return info_; }
HGraph* graph() const { return graph_; }
Zone* zone() const { return zone_; }
@@ -2273,7 +2457,7 @@ class LChunkBuilder BASE_EMBEDDED {
bool is_done() const { return status_ == DONE; }
bool is_aborted() const { return status_ == ABORTED; }
- void Abort(const char* format, ...);
+ void Abort(const char* reason);
// Methods for getting operands for Use / Define / Temp.
LUnallocated* ToUnallocated(Register reg);
@@ -2367,7 +2551,7 @@ class LChunkBuilder BASE_EMBEDDED {
LInstruction* DoArithmeticT(Token::Value op,
HArithmeticBinaryOperation* instr);
- LChunk* chunk_;
+ LPlatformChunk* chunk_;
CompilationInfo* info_;
HGraph* const graph_;
Zone* zone_;
@@ -2379,7 +2563,7 @@ class LChunkBuilder BASE_EMBEDDED {
LAllocator* allocator_;
int position_;
LInstruction* instruction_pending_deoptimization_environment_;
- int pending_deoptimization_ast_id_;
+ BailoutId pending_deoptimization_ast_id_;
DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
};
diff --git a/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc
index 7d5d6d3d0..77506741a 100644
--- a/deps/v8/src/x64/macro-assembler-x64.cc
+++ b/deps/v8/src/x64/macro-assembler-x64.cc
@@ -53,9 +53,17 @@ MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size)
}
-static intptr_t RootRegisterDelta(ExternalReference other, Isolate* isolate) {
+static const int kInvalidRootRegisterDelta = -1;
+
+
+intptr_t MacroAssembler::RootRegisterDelta(ExternalReference other) {
+ if (predictable_code_size() &&
+ (other.address() < reinterpret_cast<Address>(isolate()) ||
+ other.address() >= reinterpret_cast<Address>(isolate() + 1))) {
+ return kInvalidRootRegisterDelta;
+ }
Address roots_register_value = kRootRegisterBias +
- reinterpret_cast<Address>(isolate->heap()->roots_array_start());
+ reinterpret_cast<Address>(isolate()->heap()->roots_array_start());
intptr_t delta = other.address() - roots_register_value;
return delta;
}
@@ -64,8 +72,8 @@ static intptr_t RootRegisterDelta(ExternalReference other, Isolate* isolate) {
Operand MacroAssembler::ExternalOperand(ExternalReference target,
Register scratch) {
if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(target, isolate());
- if (is_int32(delta)) {
+ intptr_t delta = RootRegisterDelta(target);
+ if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
Serializer::TooLateToEnableNow();
return Operand(kRootRegister, static_cast<int32_t>(delta));
}
@@ -77,8 +85,8 @@ Operand MacroAssembler::ExternalOperand(ExternalReference target,
void MacroAssembler::Load(Register destination, ExternalReference source) {
if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(source, isolate());
- if (is_int32(delta)) {
+ intptr_t delta = RootRegisterDelta(source);
+ if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
Serializer::TooLateToEnableNow();
movq(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
return;
@@ -96,8 +104,8 @@ void MacroAssembler::Load(Register destination, ExternalReference source) {
void MacroAssembler::Store(ExternalReference destination, Register source) {
if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(destination, isolate());
- if (is_int32(delta)) {
+ intptr_t delta = RootRegisterDelta(destination);
+ if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
Serializer::TooLateToEnableNow();
movq(Operand(kRootRegister, static_cast<int32_t>(delta)), source);
return;
@@ -116,8 +124,8 @@ void MacroAssembler::Store(ExternalReference destination, Register source) {
void MacroAssembler::LoadAddress(Register destination,
ExternalReference source) {
if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(source, isolate());
- if (is_int32(delta)) {
+ intptr_t delta = RootRegisterDelta(source);
+ if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
Serializer::TooLateToEnableNow();
lea(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
return;
@@ -133,8 +141,8 @@ int MacroAssembler::LoadAddressSize(ExternalReference source) {
// This calculation depends on the internals of LoadAddress.
// It's correctness is ensured by the asserts in the Call
// instruction below.
- intptr_t delta = RootRegisterDelta(source, isolate());
- if (is_int32(delta)) {
+ intptr_t delta = RootRegisterDelta(source);
+ if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
Serializer::TooLateToEnableNow();
// Operand is lea(scratch, Operand(kRootRegister, delta));
// Opcodes : REX.W 8D ModRM Disp8/Disp32 - 4 or 7.
@@ -216,7 +224,7 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
Register scratch,
SaveFPRegsMode save_fp,
RememberedSetFinalAction and_then) {
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
Label ok;
JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear);
int3();
@@ -388,16 +396,14 @@ void MacroAssembler::RecordWrite(Register object,
ASSERT(!object.is(value));
ASSERT(!object.is(address));
ASSERT(!value.is(address));
- if (emit_debug_code()) {
- AbortIfSmi(object);
- }
+ AssertNotSmi(object);
if (remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) {
return;
}
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
Label ok;
cmpq(value, Operand(address, 0));
j(equal, &ok, Label::kNear);
@@ -538,7 +544,7 @@ void MacroAssembler::Abort(const char* msg) {
}
-void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) {
+void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs
Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
}
@@ -743,17 +749,52 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
Cmp(Operand(rsi, 0), factory->the_hole_value());
j(not_equal, &promote_scheduled_exception);
+#if ENABLE_EXTRA_CHECKS
+ // Check if the function returned a valid JavaScript value.
+ Label ok;
+ Register return_value = rax;
+ Register map = rcx;
+
+ JumpIfSmi(return_value, &ok, Label::kNear);
+ movq(map, FieldOperand(return_value, HeapObject::kMapOffset));
+
+ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
+ j(below, &ok, Label::kNear);
+
+ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
+ j(above_equal, &ok, Label::kNear);
+
+ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
+ j(equal, &ok, Label::kNear);
+
+ CompareRoot(return_value, Heap::kUndefinedValueRootIndex);
+ j(equal, &ok, Label::kNear);
+
+ CompareRoot(return_value, Heap::kTrueValueRootIndex);
+ j(equal, &ok, Label::kNear);
+
+ CompareRoot(return_value, Heap::kFalseValueRootIndex);
+ j(equal, &ok, Label::kNear);
+
+ CompareRoot(return_value, Heap::kNullValueRootIndex);
+ j(equal, &ok, Label::kNear);
+
+ Abort("API call returned invalid object");
+
+ bind(&ok);
+#endif
+
LeaveApiExitFrame();
ret(stack_space * kPointerSize);
- bind(&promote_scheduled_exception);
- TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
-
bind(&empty_result);
// It was zero; the result is undefined.
- Move(rax, factory->undefined_value());
+ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
jmp(&prologue);
+ bind(&promote_scheduled_exception);
+ TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
+
// HandleScope limit has changed. Delete allocated extensions.
bind(&delete_allocated_handles);
movq(Operand(base_reg, kLimitOffset), prev_limit_reg);
@@ -798,7 +839,7 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
void MacroAssembler::GetBuiltinFunction(Register target,
Builtins::JavaScript id) {
// Load the builtins object into target register.
- movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
movq(target, FieldOperand(target,
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
@@ -892,6 +933,38 @@ void MacroAssembler::Set(const Operand& dst, int64_t x) {
}
}
+
+bool MacroAssembler::IsUnsafeInt(const int x) {
+ static const int kMaxBits = 17;
+ return !is_intn(x, kMaxBits);
+}
+
+
+void MacroAssembler::SafeMove(Register dst, Smi* src) {
+ ASSERT(!dst.is(kScratchRegister));
+ ASSERT(kSmiValueSize == 32); // JIT cookie can be converted to Smi.
+ if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
+ Move(dst, Smi::FromInt(src->value() ^ jit_cookie()));
+ Move(kScratchRegister, Smi::FromInt(jit_cookie()));
+ xor_(dst, kScratchRegister);
+ } else {
+ Move(dst, src);
+ }
+}
+
+
+void MacroAssembler::SafePush(Smi* src) {
+ ASSERT(kSmiValueSize == 32); // JIT cookie can be converted to Smi.
+ if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
+ Push(Smi::FromInt(src->value() ^ jit_cookie()));
+ Move(kScratchRegister, Smi::FromInt(jit_cookie()));
+ xor_(Operand(rsp, 0), kScratchRegister);
+ } else {
+ Push(src);
+ }
+}
+
+
// ----------------------------------------------------------------------------
// Smi tagging, untagging and tag detection.
@@ -1040,18 +1113,14 @@ void MacroAssembler::SmiTest(Register src) {
void MacroAssembler::SmiCompare(Register smi1, Register smi2) {
- if (emit_debug_code()) {
- AbortIfNotSmi(smi1);
- AbortIfNotSmi(smi2);
- }
+ AssertSmi(smi1);
+ AssertSmi(smi2);
cmpq(smi1, smi2);
}
void MacroAssembler::SmiCompare(Register dst, Smi* src) {
- if (emit_debug_code()) {
- AbortIfNotSmi(dst);
- }
+ AssertSmi(dst);
Cmp(dst, src);
}
@@ -1068,27 +1137,21 @@ void MacroAssembler::Cmp(Register dst, Smi* src) {
void MacroAssembler::SmiCompare(Register dst, const Operand& src) {
- if (emit_debug_code()) {
- AbortIfNotSmi(dst);
- AbortIfNotSmi(src);
- }
+ AssertSmi(dst);
+ AssertSmi(src);
cmpq(dst, src);
}
void MacroAssembler::SmiCompare(const Operand& dst, Register src) {
- if (emit_debug_code()) {
- AbortIfNotSmi(dst);
- AbortIfNotSmi(src);
- }
+ AssertSmi(dst);
+ AssertSmi(src);
cmpq(dst, src);
}
void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) {
- if (emit_debug_code()) {
- AbortIfNotSmi(dst);
- }
+ AssertSmi(dst);
cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value()));
}
@@ -2377,7 +2440,7 @@ void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) {
void MacroAssembler::Call(Handle<Code> code_object,
RelocInfo::Mode rmode,
- unsigned ast_id) {
+ TypeFeedbackId ast_id) {
#ifdef DEBUG
int end_position = pc_offset() + CallSize(code_object);
#endif
@@ -2460,6 +2523,12 @@ MacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = {
};
+void MacroAssembler::StoreToSafepointRegisterSlot(Register dst,
+ const Immediate& imm) {
+ movq(SafepointRegisterSlot(dst), imm);
+}
+
+
void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) {
movq(SafepointRegisterSlot(dst), src);
}
@@ -2799,33 +2868,66 @@ void MacroAssembler::ClampUint8(Register reg) {
void MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg,
XMMRegister temp_xmm_reg,
- Register result_reg,
- Register temp_reg) {
+ Register result_reg) {
Label done;
- Set(result_reg, 0);
+ Label conv_failure;
xorps(temp_xmm_reg, temp_xmm_reg);
- ucomisd(input_reg, temp_xmm_reg);
- j(below, &done, Label::kNear);
- uint64_t one_half = BitCast<uint64_t, double>(0.5);
- Set(temp_reg, one_half);
- movq(temp_xmm_reg, temp_reg);
- addsd(temp_xmm_reg, input_reg);
- cvttsd2si(result_reg, temp_xmm_reg);
+ cvtsd2si(result_reg, input_reg);
testl(result_reg, Immediate(0xFFFFFF00));
j(zero, &done, Label::kNear);
+ cmpl(result_reg, Immediate(0x80000000));
+ j(equal, &conv_failure, Label::kNear);
+ movl(result_reg, Immediate(0));
+ setcc(above, result_reg);
+ subl(result_reg, Immediate(1));
+ andl(result_reg, Immediate(255));
+ jmp(&done, Label::kNear);
+ bind(&conv_failure);
+ Set(result_reg, 0);
+ ucomisd(input_reg, temp_xmm_reg);
+ j(below, &done, Label::kNear);
Set(result_reg, 255);
bind(&done);
}
+static double kUint32Bias =
+ static_cast<double>(static_cast<uint32_t>(0xFFFFFFFF)) + 1;
+
+
+void MacroAssembler::LoadUint32(XMMRegister dst,
+ Register src,
+ XMMRegister scratch) {
+ Label done;
+ cmpl(src, Immediate(0));
+ movq(kScratchRegister,
+ reinterpret_cast<int64_t>(&kUint32Bias),
+ RelocInfo::NONE);
+ movsd(scratch, Operand(kScratchRegister, 0));
+ cvtlsi2sd(dst, src);
+ j(not_sign, &done, Label::kNear);
+ addsd(dst, scratch);
+ bind(&done);
+}
+
+
void MacroAssembler::LoadInstanceDescriptors(Register map,
Register descriptors) {
- movq(descriptors, FieldOperand(map,
- Map::kInstanceDescriptorsOrBitField3Offset));
- Label not_smi;
- JumpIfNotSmi(descriptors, &not_smi, Label::kNear);
- Move(descriptors, isolate()->factory()->empty_descriptor_array());
- bind(&not_smi);
+ movq(descriptors, FieldOperand(map, Map::kDescriptorsOffset));
+}
+
+
+void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
+ movq(dst, FieldOperand(map, Map::kBitField3Offset));
+ DecodeField<Map::NumberOfOwnDescriptorsBits>(dst);
+}
+
+
+void MacroAssembler::EnumLength(Register dst, Register map) {
+ STATIC_ASSERT(Map::EnumLengthBits::kShift == 0);
+ movq(dst, FieldOperand(map, Map::kBitField3Offset));
+ Move(kScratchRegister, Smi::FromInt(Map::EnumLengthBits::kMask));
+ and_(dst, kScratchRegister);
}
@@ -2844,61 +2946,75 @@ void MacroAssembler::DispatchMap(Register obj,
}
-void MacroAssembler::AbortIfNotNumber(Register object) {
- Label ok;
- Condition is_smi = CheckSmi(object);
- j(is_smi, &ok, Label::kNear);
- Cmp(FieldOperand(object, HeapObject::kMapOffset),
- isolate()->factory()->heap_number_map());
- Assert(equal, "Operand not a number");
- bind(&ok);
+void MacroAssembler::AssertNumber(Register object) {
+ if (emit_debug_code()) {
+ Label ok;
+ Condition is_smi = CheckSmi(object);
+ j(is_smi, &ok, Label::kNear);
+ Cmp(FieldOperand(object, HeapObject::kMapOffset),
+ isolate()->factory()->heap_number_map());
+ Check(equal, "Operand is not a number");
+ bind(&ok);
+ }
}
-void MacroAssembler::AbortIfSmi(Register object) {
- Condition is_smi = CheckSmi(object);
- Assert(NegateCondition(is_smi), "Operand is a smi");
+void MacroAssembler::AssertNotSmi(Register object) {
+ if (emit_debug_code()) {
+ Condition is_smi = CheckSmi(object);
+ Check(NegateCondition(is_smi), "Operand is a smi");
+ }
}
-void MacroAssembler::AbortIfNotSmi(Register object) {
- Condition is_smi = CheckSmi(object);
- Assert(is_smi, "Operand is not a smi");
+void MacroAssembler::AssertSmi(Register object) {
+ if (emit_debug_code()) {
+ Condition is_smi = CheckSmi(object);
+ Check(is_smi, "Operand is not a smi");
+ }
}
-void MacroAssembler::AbortIfNotSmi(const Operand& object) {
- Condition is_smi = CheckSmi(object);
- Assert(is_smi, "Operand is not a smi");
+void MacroAssembler::AssertSmi(const Operand& object) {
+ if (emit_debug_code()) {
+ Condition is_smi = CheckSmi(object);
+ Check(is_smi, "Operand is not a smi");
+ }
}
-void MacroAssembler::AbortIfNotZeroExtended(Register int32_register) {
- ASSERT(!int32_register.is(kScratchRegister));
- movq(kScratchRegister, 0x100000000l, RelocInfo::NONE);
- cmpq(kScratchRegister, int32_register);
- Assert(above_equal, "32 bit value in register is not zero-extended");
+void MacroAssembler::AssertZeroExtended(Register int32_register) {
+ if (emit_debug_code()) {
+ ASSERT(!int32_register.is(kScratchRegister));
+ movq(kScratchRegister, 0x100000000l, RelocInfo::NONE);
+ cmpq(kScratchRegister, int32_register);
+ Check(above_equal, "32 bit value in register is not zero-extended");
+ }
}
-void MacroAssembler::AbortIfNotString(Register object) {
- testb(object, Immediate(kSmiTagMask));
- Assert(not_equal, "Operand is not a string");
- push(object);
- movq(object, FieldOperand(object, HeapObject::kMapOffset));
- CmpInstanceType(object, FIRST_NONSTRING_TYPE);
- pop(object);
- Assert(below, "Operand is not a string");
+void MacroAssembler::AssertString(Register object) {
+ if (emit_debug_code()) {
+ testb(object, Immediate(kSmiTagMask));
+ Check(not_equal, "Operand is a smi and not a string");
+ push(object);
+ movq(object, FieldOperand(object, HeapObject::kMapOffset));
+ CmpInstanceType(object, FIRST_NONSTRING_TYPE);
+ pop(object);
+ Check(below, "Operand is not a string");
+ }
}
-void MacroAssembler::AbortIfNotRootValue(Register src,
- Heap::RootListIndex root_value_index,
- const char* message) {
- ASSERT(!src.is(kScratchRegister));
- LoadRoot(kScratchRegister, root_value_index);
- cmpq(src, kScratchRegister);
- Check(equal, message);
+void MacroAssembler::AssertRootValue(Register src,
+ Heap::RootListIndex root_value_index,
+ const char* message) {
+ if (emit_debug_code()) {
+ ASSERT(!src.is(kScratchRegister));
+ LoadRoot(kScratchRegister, root_value_index);
+ cmpq(src, kScratchRegister);
+ Check(equal, message);
+ }
}
@@ -3395,20 +3511,21 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
cmpq(scratch, Immediate(0));
Check(not_equal, "we should not have an empty lexical context");
}
- // Load the global context of the current context.
- int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+ // Load the native context of the current context.
+ int offset =
+ Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
movq(scratch, FieldOperand(scratch, offset));
- movq(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
+ movq(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
- // Check the context is a global context.
+ // Check the context is a native context.
if (emit_debug_code()) {
Cmp(FieldOperand(scratch, HeapObject::kMapOffset),
- isolate()->factory()->global_context_map());
- Check(equal, "JSGlobalObject::global_context should be a global context.");
+ isolate()->factory()->native_context_map());
+ Check(equal, "JSGlobalObject::native_context should be a native context.");
}
// Check if both contexts are the same.
- cmpq(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
+ cmpq(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
j(equal, &same_contexts);
// Compare security tokens.
@@ -3416,23 +3533,24 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
// compatible with the security token in the receiving global
// object.
- // Check the context is a global context.
+ // Check the context is a native context.
if (emit_debug_code()) {
// Preserve original value of holder_reg.
push(holder_reg);
- movq(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
+ movq(holder_reg,
+ FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
CompareRoot(holder_reg, Heap::kNullValueRootIndex);
Check(not_equal, "JSGlobalProxy::context() should not be null.");
- // Read the first word and compare to global_context_map(),
+ // Read the first word and compare to native_context_map(),
movq(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset));
- CompareRoot(holder_reg, Heap::kGlobalContextMapRootIndex);
- Check(equal, "JSGlobalObject::global_context should be a global context.");
+ CompareRoot(holder_reg, Heap::kNativeContextMapRootIndex);
+ Check(equal, "JSGlobalObject::native_context should be a native context.");
pop(holder_reg);
}
movq(kScratchRegister,
- FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
+ FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
int token_offset =
Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize;
movq(scratch, FieldOperand(scratch, token_offset));
@@ -3954,7 +4072,7 @@ void MacroAssembler::CopyBytes(Register destination,
int min_length,
Register scratch) {
ASSERT(min_length >= 0);
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
cmpl(length, Immediate(min_length));
Assert(greater_equal, "Invalid min_length");
}
@@ -4052,8 +4170,9 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
Register scratch,
Label* no_map_match) {
// Load the global or builtins object from the current context.
- movq(scratch, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- movq(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
+ movq(scratch,
+ Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ movq(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
// Check that the function's map is the same as the expected cached map.
movq(scratch, Operand(scratch,
@@ -4103,10 +4222,11 @@ static const int kRegisterPassedArguments = 6;
void MacroAssembler::LoadGlobalFunction(int index, Register function) {
// Load the global or builtins object from the current context.
- movq(function, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- // Load the global context from the global or builtins object.
- movq(function, FieldOperand(function, GlobalObject::kGlobalContextOffset));
- // Load the function from the global context.
+ movq(function,
+ Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ // Load the native context from the global or builtins object.
+ movq(function, FieldOperand(function, GlobalObject::kNativeContextOffset));
+ // Load the function from the native context.
movq(function, Operand(function, Context::SlotOffset(index)));
}
@@ -4331,7 +4451,7 @@ void MacroAssembler::EnsureNotWhite(
testq(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch);
j(not_zero, &done, Label::kNear);
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// Check for impossible bit pattern.
Label ok;
push(mask_scratch);
@@ -4406,44 +4526,38 @@ void MacroAssembler::EnsureNotWhite(
void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
- Label next;
+ Label next, start;
Register empty_fixed_array_value = r8;
LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
- Register empty_descriptor_array_value = r9;
- LoadRoot(empty_descriptor_array_value,
- Heap::kEmptyDescriptorArrayRootIndex);
movq(rcx, rax);
- bind(&next);
-
- // Check that there are no elements. Register rcx contains the
- // current JS object we've reached through the prototype chain.
- cmpq(empty_fixed_array_value,
- FieldOperand(rcx, JSObject::kElementsOffset));
- j(not_equal, call_runtime);
- // Check that instance descriptors are not empty so that we can
- // check for an enum cache. Leave the map in rbx for the subsequent
- // prototype load.
+ // Check if the enum length field is properly initialized, indicating that
+ // there is an enum cache.
movq(rbx, FieldOperand(rcx, HeapObject::kMapOffset));
- movq(rdx, FieldOperand(rbx, Map::kInstanceDescriptorsOrBitField3Offset));
- JumpIfSmi(rdx, call_runtime);
- // Check that there is an enum cache in the non-empty instance
- // descriptors (rdx). This is the case if the next enumeration
- // index field does not contain a smi.
- movq(rdx, FieldOperand(rdx, DescriptorArray::kEnumerationIndexOffset));
- JumpIfSmi(rdx, call_runtime);
+ EnumLength(rdx, rbx);
+ Cmp(rdx, Smi::FromInt(Map::kInvalidEnumCache));
+ j(equal, call_runtime);
+
+ jmp(&start);
+
+ bind(&next);
+
+ movq(rbx, FieldOperand(rcx, HeapObject::kMapOffset));
// For all objects but the receiver, check that the cache is empty.
- Label check_prototype;
- cmpq(rcx, rax);
- j(equal, &check_prototype, Label::kNear);
- movq(rdx, FieldOperand(rdx, DescriptorArray::kEnumCacheBridgeCacheOffset));
- cmpq(rdx, empty_fixed_array_value);
+ EnumLength(rdx, rbx);
+ Cmp(rdx, Smi::FromInt(0));
+ j(not_equal, call_runtime);
+
+ bind(&start);
+
+ // Check that there are no elements. Register rcx contains the current JS
+ // object we've reached through the prototype chain.
+ cmpq(empty_fixed_array_value,
+ FieldOperand(rcx, JSObject::kElementsOffset));
j(not_equal, call_runtime);
- // Load the prototype from the map and loop if non-null.
- bind(&check_prototype);
movq(rcx, FieldOperand(rbx, Map::kPrototypeOffset));
cmpq(rcx, null_value);
j(not_equal, &next);
diff --git a/deps/v8/src/x64/macro-assembler-x64.h b/deps/v8/src/x64/macro-assembler-x64.h
index 1c1cd95e9..cc057ac54 100644
--- a/deps/v8/src/x64/macro-assembler-x64.h
+++ b/deps/v8/src/x64/macro-assembler-x64.h
@@ -317,6 +317,7 @@ class MacroAssembler: public Assembler {
void PopSafepointRegisters() { Popad(); }
// Store the value in register src in the safepoint register stack
// slot for register dst.
+ void StoreToSafepointRegisterSlot(Register dst, const Immediate& imm);
void StoreToSafepointRegisterSlot(Register dst, Register src);
void LoadFromSafepointRegisterSlot(Register dst, Register src);
@@ -774,6 +775,11 @@ class MacroAssembler: public Assembler {
// Move if the registers are not identical.
void Move(Register target, Register source);
+ // Support for constant splitting.
+ bool IsUnsafeInt(const int x);
+ void SafeMove(Register dst, Smi* src);
+ void SafePush(Smi* src);
+
// Bit-field support.
void TestBit(const Operand& dst, int bit_index);
@@ -817,7 +823,7 @@ class MacroAssembler: public Assembler {
void Call(ExternalReference ext);
void Call(Handle<Code> code_object,
RelocInfo::Mode rmode,
- unsigned ast_id = kNoASTId);
+ TypeFeedbackId ast_id = TypeFeedbackId::None());
// The size of the code generated for different call instructions.
int CallSize(Address destination, RelocInfo::Mode rmode) {
@@ -936,32 +942,45 @@ class MacroAssembler: public Assembler {
void ClampDoubleToUint8(XMMRegister input_reg,
XMMRegister temp_xmm_reg,
- Register result_reg,
- Register temp_reg);
+ Register result_reg);
+
+ void LoadUint32(XMMRegister dst, Register src, XMMRegister scratch);
void LoadInstanceDescriptors(Register map, Register descriptors);
+ void EnumLength(Register dst, Register map);
+ void NumberOfOwnDescriptors(Register dst, Register map);
+
+ template<typename Field>
+ void DecodeField(Register reg) {
+ static const int shift = Field::kShift + kSmiShift;
+ static const int mask = Field::kMask >> Field::kShift;
+ shr(reg, Immediate(shift));
+ and_(reg, Immediate(mask));
+ shl(reg, Immediate(kSmiShift));
+ }
- // Abort execution if argument is not a number. Used in debug code.
- void AbortIfNotNumber(Register object);
+ // Abort execution if argument is not a number, enabled via --debug-code.
+ void AssertNumber(Register object);
- // Abort execution if argument is a smi. Used in debug code.
- void AbortIfSmi(Register object);
+ // Abort execution if argument is a smi, enabled via --debug-code.
+ void AssertNotSmi(Register object);
- // Abort execution if argument is not a smi. Used in debug code.
- void AbortIfNotSmi(Register object);
- void AbortIfNotSmi(const Operand& object);
+ // Abort execution if argument is not a smi, enabled via --debug-code.
+ void AssertSmi(Register object);
+ void AssertSmi(const Operand& object);
// Abort execution if a 64 bit register containing a 32 bit payload does not
- // have zeros in the top 32 bits.
- void AbortIfNotZeroExtended(Register reg);
+ // have zeros in the top 32 bits, enabled via --debug-code.
+ void AssertZeroExtended(Register reg);
- // Abort execution if argument is a string. Used in debug code.
- void AbortIfNotString(Register object);
+ // Abort execution if argument is not a string, enabled via --debug-code.
+ void AssertString(Register object);
- // Abort execution if argument is not the root value with the given index.
- void AbortIfNotRootValue(Register src,
- Heap::RootListIndex root_value_index,
- const char* message);
+ // Abort execution if argument is not the root value with the given index,
+ // enabled via --debug-code.
+ void AssertRootValue(Register src,
+ Heap::RootListIndex root_value_index,
+ const char* message);
// ---------------------------------------------------------------------------
// Exception handling
@@ -1128,8 +1147,8 @@ class MacroAssembler: public Assembler {
void LoadContext(Register dst, int context_chain_length);
// Conditionally load the cached Array transitioned map of type
- // transitioned_kind from the global context if the map in register
- // map_in_out is the cached Array map in the global context of
+ // transitioned_kind from the native context if the map in register
+ // map_in_out is the cached Array map in the native context of
// expected_kind.
void LoadTransitionedArrayMapConditional(
ElementsKind expected_kind,
@@ -1155,7 +1174,7 @@ class MacroAssembler: public Assembler {
// Runtime calls
// Call a code stub.
- void CallStub(CodeStub* stub, unsigned ast_id = kNoASTId);
+ void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None());
// Tail call a code stub (jump).
void TailCallStub(CodeStub* stub);
@@ -1323,6 +1342,8 @@ class MacroAssembler: public Assembler {
// modified. It may be the "smi 1 constant" register.
Register GetSmiConstant(Smi* value);
+ intptr_t RootRegisterDelta(ExternalReference other);
+
// Moves the smi value to the destination register.
void LoadSmiConstant(Register dst, Smi* value);
@@ -1442,7 +1463,7 @@ inline Operand ContextOperand(Register context, int index) {
inline Operand GlobalObjectOperand() {
- return ContextOperand(rsi, Context::GLOBAL_INDEX);
+ return ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX);
}
diff --git a/deps/v8/src/x64/regexp-macro-assembler-x64.cc b/deps/v8/src/x64/regexp-macro-assembler-x64.cc
index a72a0a0d1..86f7bfe6c 100644
--- a/deps/v8/src/x64/regexp-macro-assembler-x64.cc
+++ b/deps/v8/src/x64/regexp-macro-assembler-x64.cc
@@ -353,6 +353,14 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
// In either case succeed immediately.
__ j(equal, &fallthrough);
+ // -----------------------
+ // rdx - Start of capture
+ // rbx - length of capture
+ // Check that there are sufficient characters left in the input.
+ __ movl(rax, rdi);
+ __ addl(rax, rbx);
+ BranchOrBacktrack(greater, on_no_match);
+
if (mode_ == ASCII) {
Label loop_increment;
if (on_no_match == NULL) {
diff --git a/deps/v8/src/x64/stub-cache-x64.cc b/deps/v8/src/x64/stub-cache-x64.cc
index a6acd9791..cd71086ee 100644
--- a/deps/v8/src/x64/stub-cache-x64.cc
+++ b/deps/v8/src/x64/stub-cache-x64.cc
@@ -228,15 +228,15 @@ void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
Register prototype) {
// Load the global or builtins object from the current context.
__ movq(prototype,
- Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- // Load the global context from the global or builtins object.
+ Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ // Load the native context from the global or builtins object.
__ movq(prototype,
- FieldOperand(prototype, GlobalObject::kGlobalContextOffset));
- // Load the function from the global context.
+ FieldOperand(prototype, GlobalObject::kNativeContextOffset));
+ // Load the function from the native context.
__ movq(prototype, Operand(prototype, Context::SlotOffset(index)));
// Load the initial map. The global functions all have initial maps.
__ movq(prototype,
- FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset));
+ FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset));
// Load the prototype from the initial map.
__ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
}
@@ -249,13 +249,13 @@ void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
Label* miss) {
Isolate* isolate = masm->isolate();
// Check we're still in the same context.
- __ Move(prototype, isolate->global());
- __ cmpq(Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)),
+ __ Move(prototype, isolate->global_object());
+ __ cmpq(Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)),
prototype);
__ j(not_equal, miss);
// Get the global function with the given index.
Handle<JSFunction> function(
- JSFunction::cast(isolate->global_context()->get(index)));
+ JSFunction::cast(isolate->native_context()->get(index)));
// Load its initial map. The global functions all have initial maps.
__ Move(prototype, Handle<Map>(function->initial_map()));
// Load the prototype from the initial map.
@@ -1029,6 +1029,49 @@ void StubCompiler::GenerateLoadField(Handle<JSObject> object,
}
+void StubCompiler::GenerateDictionaryLoadCallback(Register receiver,
+ Register name_reg,
+ Register scratch1,
+ Register scratch2,
+ Register scratch3,
+ Handle<AccessorInfo> callback,
+ Handle<String> name,
+ Label* miss) {
+ ASSERT(!receiver.is(scratch1));
+ ASSERT(!receiver.is(scratch2));
+ ASSERT(!receiver.is(scratch3));
+
+ // Load the properties dictionary.
+ Register dictionary = scratch1;
+ __ movq(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset));
+
+ // Probe the dictionary.
+ Label probe_done;
+ StringDictionaryLookupStub::GeneratePositiveLookup(masm(),
+ miss,
+ &probe_done,
+ dictionary,
+ name_reg,
+ scratch2,
+ scratch3);
+ __ bind(&probe_done);
+
+ // If probing finds an entry in the dictionary, scratch3 contains the
+ // index into the dictionary. Check that the value is the callback.
+ Register index = scratch3;
+ const int kElementsStartOffset =
+ StringDictionary::kHeaderSize +
+ StringDictionary::kElementsStartIndex * kPointerSize;
+ const int kValueOffset = kElementsStartOffset + kPointerSize;
+ __ movq(scratch2,
+ Operand(dictionary, index, times_pointer_size,
+ kValueOffset - kHeapObjectTag));
+ __ movq(scratch3, callback, RelocInfo::EMBEDDED_OBJECT);
+ __ cmpq(scratch2, scratch3);
+ __ j(not_equal, miss);
+}
+
+
void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Handle<JSObject> holder,
Register receiver,
@@ -1036,6 +1079,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Register scratch1,
Register scratch2,
Register scratch3,
+ Register scratch4,
Handle<AccessorInfo> callback,
Handle<String> name,
Label* miss) {
@@ -1046,6 +1090,11 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
Register reg = CheckPrototypes(object, receiver, holder, scratch1,
scratch2, scratch3, name, miss);
+ if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
+ GenerateDictionaryLoadCallback(
+ reg, name_reg, scratch2, scratch3, scratch4, callback, name, miss);
+ }
+
// Insert additional parameters into the stack frame above return address.
ASSERT(!scratch2.is(reg));
__ pop(scratch2); // Get return address to place it below.
@@ -1143,7 +1192,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
// later.
bool compile_followup_inline = false;
if (lookup->IsFound() && lookup->IsCacheable()) {
- if (lookup->type() == FIELD) {
+ if (lookup->IsField()) {
compile_followup_inline = true;
} else if (lookup->type() == CALLBACKS &&
lookup->GetCallbackObject()->IsAccessorInfo()) {
@@ -1221,7 +1270,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
miss);
}
- if (lookup->type() == FIELD) {
+ if (lookup->IsField()) {
// We found FIELD property in prototype chain of interceptor's holder.
// Retrieve a field from field's holder.
GenerateFastPropertyLoad(masm(), rax, holder_reg,
@@ -1391,7 +1440,7 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
GenerateMissBranch();
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -1915,7 +1964,7 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2030,7 +2079,7 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall(
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2279,7 +2328,7 @@ Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
GenerateMissBranch();
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2342,7 +2391,7 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
GenerateMissBranch();
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2373,14 +2422,17 @@ Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
Handle<Code> StoreStubCompiler::CompileStoreCallback(
- Handle<JSObject> object,
- Handle<AccessorInfo> callback,
- Handle<String> name) {
+ Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- rax : value
// -- rcx : name
@@ -2388,19 +2440,12 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -- rsp[0] : return address
// -----------------------------------
Label miss;
+ // Check that the maps haven't changed.
+ __ JumpIfSmi(rdx, &miss);
+ CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss);
- // Check that the map of the object hasn't changed.
- __ CheckMap(rdx, Handle<Map>(object->map()), &miss,
- DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
-
- // Perform global security token check if needed.
- if (object->IsJSGlobalProxy()) {
- __ CheckAccessGlobalProxy(rdx, rbx, &miss);
- }
-
- // Stub never generated for non-global objects that require access
- // checks.
- ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
+ // Stub never generated for non-global objects that require access checks.
+ ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
__ pop(rbx); // remove the return address
__ push(rdx); // receiver
@@ -2420,38 +2465,41 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
-Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
- Handle<JSObject> receiver,
- Handle<JSFunction> setter,
- Handle<String> name) {
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void StoreStubCompiler::GenerateStoreViaSetter(
+ MacroAssembler* masm,
+ Handle<JSFunction> setter) {
// ----------- S t a t e -------------
// -- rax : value
// -- rcx : name
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
- Label miss;
-
- // Check that the map of the object hasn't changed.
- __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, DO_SMI_CHECK,
- ALLOW_ELEMENT_TRANSITION_MAPS);
-
{
- FrameScope scope(masm(), StackFrame::INTERNAL);
+ FrameScope scope(masm, StackFrame::INTERNAL);
// Save value register, so we can restore it later.
__ push(rax);
- // Call the JavaScript getter with the receiver and the value on the stack.
- __ push(rdx);
- __ push(rax);
- ParameterCount actual(1);
- __ InvokeFunction(setter, actual, CALL_FUNCTION, NullCallWrapper(),
- CALL_AS_METHOD);
+ if (!setter.is_null()) {
+ // Call the JavaScript setter with receiver and value on the stack.
+ __ push(rdx);
+ __ push(rax);
+ ParameterCount actual(1);
+ __ InvokeFunction(setter, actual, CALL_FUNCTION, NullCallWrapper(),
+ CALL_AS_METHOD);
+ } else {
+ // If we generate a global code snippet for deoptimization only, remember
+ // the place to continue after deoptimization.
+ masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+ }
// We have to return the passed value, not the return value of the setter.
__ pop(rax);
@@ -2460,13 +2508,38 @@ Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
}
__ ret(0);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
+Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
+ Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<JSFunction> setter) {
+ // ----------- S t a t e -------------
+ // -- rax : value
+ // -- rcx : name
+ // -- rdx : receiver
+ // -- rsp[0] : return address
+ // -----------------------------------
+ Label miss;
+
+ // Check that the maps haven't changed.
+ __ JumpIfSmi(rdx, &miss);
+ CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss);
+
+ GenerateStoreViaSetter(masm(), setter);
__ bind(&miss);
Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2512,7 +2585,7 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2560,7 +2633,7 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal(
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2599,7 +2672,9 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -2623,7 +2698,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -2661,7 +2736,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
@@ -2699,7 +2774,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NONEXISTENT, factory()->empty_string());
+ return GetCode(Code::NONEXISTENT, factory()->empty_string());
}
@@ -2719,7 +2794,7 @@ Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2734,16 +2809,53 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
// -- rsp[0] : return address
// -----------------------------------
Label miss;
- GenerateLoadCallback(object, holder, rax, rcx, rdx, rbx, rdi, callback,
+ GenerateLoadCallback(object, holder, rax, rcx, rdx, rbx, rdi, r8, callback,
name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
+ Handle<JSFunction> getter) {
+ // ----------- S t a t e -------------
+ // -- rax : receiver
+ // -- rcx : name
+ // -- rsp[0] : return address
+ // -----------------------------------
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ if (!getter.is_null()) {
+ // Call the JavaScript getter with the receiver on the stack.
+ __ push(rax);
+ ParameterCount actual(0);
+ __ InvokeFunction(getter, actual, CALL_FUNCTION, NullCallWrapper(),
+ CALL_AS_METHOD);
+ } else {
+ // If we generate a global code snippet for deoptimization only, remember
+ // the place to continue after deoptimization.
+ masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
+ }
+
+ // Restore context register.
+ __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
+ }
+ __ ret(0);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
@@ -2760,25 +2872,13 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
__ JumpIfSmi(rax, &miss);
CheckPrototypes(receiver, rax, holder, rbx, rdx, rdi, name, &miss);
- {
- FrameScope scope(masm(), StackFrame::INTERNAL);
-
- // Call the JavaScript getter with the receiver on the stack.
- __ push(rax);
- ParameterCount actual(0);
- __ InvokeFunction(getter, actual, CALL_FUNCTION, NullCallWrapper(),
- CALL_AS_METHOD);
-
- // Restore context register.
- __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
- }
- __ ret(0);
+ GenerateLoadViaGetter(masm(), getter),
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2798,7 +2898,7 @@ Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -2822,7 +2922,7 @@ Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> receiver,
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2866,7 +2966,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2895,7 +2995,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2917,14 +3017,14 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
__ Cmp(rax, name);
__ j(not_equal, &miss);
- GenerateLoadCallback(receiver, holder, rdx, rax, rbx, rcx, rdi, callback,
+ GenerateLoadCallback(receiver, holder, rdx, rax, rbx, rcx, rdi, r8, callback,
name, &miss);
__ bind(&miss);
__ DecrementCounter(counters->keyed_load_callback(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2954,7 +3054,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -2984,7 +3084,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3010,7 +3110,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3036,7 +3136,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3062,7 +3162,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3082,7 +3182,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3110,7 +3210,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
diff --git a/deps/v8/src/zone-inl.h b/deps/v8/src/zone-inl.h
index d75e297af..e312b2089 100644
--- a/deps/v8/src/zone-inl.h
+++ b/deps/v8/src/zone-inl.h
@@ -40,7 +40,7 @@ namespace internal {
inline void* Zone::New(int size) {
- ASSERT(ZoneScope::nesting() > 0);
+ ASSERT(scope_nesting_ > 0);
// Round up the requested size to fit the alignment.
size = RoundUp(size, kAlignment);
@@ -100,7 +100,7 @@ void* ZoneObject::operator new(size_t size, Zone* zone) {
inline void* ZoneAllocationPolicy::New(size_t size) {
ASSERT(zone_);
- return zone_->New(size);
+ return zone_->New(static_cast<int>(size));
}
@@ -110,19 +110,14 @@ void* ZoneList<T>::operator new(size_t size, Zone* zone) {
}
-ZoneScope::ZoneScope(Isolate* isolate, ZoneScopeMode mode)
- : isolate_(isolate), mode_(mode) {
- isolate_->zone()->scope_nesting_++;
+ZoneScope::ZoneScope(Zone* zone, ZoneScopeMode mode)
+ : zone_(zone), mode_(mode) {
+ zone_->scope_nesting_++;
}
bool ZoneScope::ShouldDeleteOnExit() {
- return isolate_->zone()->scope_nesting_ == 1 && mode_ == DELETE_ON_EXIT;
-}
-
-
-int ZoneScope::nesting() {
- return Isolate::Current()->zone()->scope_nesting_;
+ return zone_->scope_nesting_ == 1 && mode_ == DELETE_ON_EXIT;
}
diff --git a/deps/v8/src/zone.cc b/deps/v8/src/zone.cc
index d5d05ab95..51b8113a0 100644
--- a/deps/v8/src/zone.cc
+++ b/deps/v8/src/zone.cc
@@ -67,20 +67,20 @@ class Segment {
};
-Zone::Zone()
+Zone::Zone(Isolate* isolate)
: zone_excess_limit_(256 * MB),
segment_bytes_allocated_(0),
position_(0),
limit_(0),
scope_nesting_(0),
- segment_head_(NULL) {
+ segment_head_(NULL),
+ isolate_(isolate) {
}
unsigned Zone::allocation_size_ = 0;
ZoneScope::~ZoneScope() {
- ASSERT_EQ(Isolate::Current(), isolate_);
- if (ShouldDeleteOnExit()) isolate_->zone()->DeleteAll();
- isolate_->zone()->scope_nesting_--;
+ if (ShouldDeleteOnExit()) zone_->DeleteAll();
+ zone_->scope_nesting_--;
}
diff --git a/deps/v8/src/zone.h b/deps/v8/src/zone.h
index 1bc4984aa..01e887e77 100644
--- a/deps/v8/src/zone.h
+++ b/deps/v8/src/zone.h
@@ -64,6 +64,8 @@ class Isolate;
class Zone {
public:
+ explicit Zone(Isolate* isolate);
+ ~Zone() { DeleteKeptSegment(); }
// Allocate 'size' bytes of memory in the Zone; expands the Zone by
// allocating new segments of memory on demand using malloc().
inline void* New(int size);
@@ -114,9 +116,6 @@ class Zone {
// the zone.
int segment_bytes_allocated_;
- // Each isolate gets its own zone.
- Zone();
-
// Expand the Zone to hold at least 'size' more bytes and allocate
// the bytes. Returns the address of the newly allocated chunk of
// memory in the Zone. Should only be called if there isn't enough
@@ -235,7 +234,7 @@ class ZoneList: public List<T, ZoneAllocationPolicy> {
// outer-most scope.
class ZoneScope BASE_EMBEDDED {
public:
- INLINE(ZoneScope(Isolate* isolate, ZoneScopeMode mode));
+ INLINE(ZoneScope(Zone* zone, ZoneScopeMode mode));
virtual ~ZoneScope();
@@ -250,7 +249,7 @@ class ZoneScope BASE_EMBEDDED {
inline static int nesting();
private:
- Isolate* isolate_;
+ Zone* zone_;
ZoneScopeMode mode_;
};
diff --git a/deps/v8/test/benchmarks/testcfg.py b/deps/v8/test/benchmarks/testcfg.py
index ab9d40fec..5bbad7ac1 100644
--- a/deps/v8/test/benchmarks/testcfg.py
+++ b/deps/v8/test/benchmarks/testcfg.py
@@ -30,6 +30,11 @@ import test
import os
from os.path import join, split
+def GetSuite(name, root):
+ # Not implemented.
+ return None
+
+
def IsNumber(string):
try:
float(string)
diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp
index a242fe3c8..66d848c5c 100644
--- a/deps/v8/test/cctest/cctest.gyp
+++ b/deps/v8/test/cctest/cctest.gyp
@@ -118,7 +118,7 @@
'test-disasm-arm.cc'
],
}],
- ['v8_target_arch=="mips"', {
+ ['v8_target_arch=="mipsel"', {
'sources': [
'test-assembler-mips.cc',
'test-disasm-mips.cc',
diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h
index 0b9356221..f3961a4ad 100644
--- a/deps/v8/test/cctest/cctest.h
+++ b/deps/v8/test/cctest/cctest.h
@@ -214,4 +214,23 @@ static inline v8::Local<v8::Value> CompileRun(const char* source) {
}
+// Helper function that compiles and runs the source with given origin.
+static inline v8::Local<v8::Value> CompileRunWithOrigin(const char* source,
+ const char* origin_url,
+ int line_number,
+ int column_number) {
+ v8::ScriptOrigin origin(v8::String::New(origin_url),
+ v8::Integer::New(line_number),
+ v8::Integer::New(column_number));
+ return v8::Script::Compile(v8::String::New(source), &origin)->Run();
+}
+
+
+// Pick a slightly different port to allow tests to be run in parallel.
+static inline int FlagDependentPortOffset() {
+ return ::v8::internal::FLAG_crankshaft == false ? 100 :
+ ::v8::internal::FLAG_always_opt ? 200 : 0;
+}
+
+
#endif // ifndef CCTEST_H_
diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status
index fc111ab94..ab59e3356 100644
--- a/deps/v8/test/cctest/cctest.status
+++ b/deps/v8/test/cctest/cctest.status
@@ -44,6 +44,9 @@ test-heap-profiler/HeapSnapshotsDiff: PASS || FAIL
test-serialize/TestThatAlwaysFails: FAIL
test-serialize/DependentTestThatAlwaysFails: FAIL
+# This test always fails. It tests that LiveEdit causes abort when turned off.
+test-debug/LiveEditDisabled: FAIL
+
# TODO(gc): Temporarily disabled in the GC branch.
test-log/EquivalenceOfLoggingAndTraversal: PASS || FAIL
@@ -65,14 +68,22 @@ test-api/OutOfMemoryNested: SKIP
# BUG(355): Test crashes on ARM.
test-log/ProfLazyMode: SKIP
-# BUG(945): Socket connect fails on ARM
-test-debug/DebuggerAgent: SKIP
-test-debug/DebuggerAgentProtocolOverflowHeader: SKIP
-test-sockets/Socket: SKIP
-
# BUG(1075): Unresolved crashes.
test-serialize/Deserialize: SKIP
test-serialize/DeserializeFromSecondSerializationAndRunScript2: SKIP
test-serialize/DeserializeAndRunScript2: SKIP
test-serialize/DeserializeFromSecondSerialization: SKIP
+##############################################################################
+[ $arch == android_arm || $arch == android_ia32 ]
+
+# Tests crash as there is no /tmp directory in Android.
+test-log/LogAccessorCallbacks: SKIP
+test-log/LogCallbacks: SKIP
+test-log/ProfLazyMode: SKIP
+
+# platform-tls.h does not contain an ANDROID-related header.
+test-platform-tls/FastTLS: SKIP
+
+# This test times out.
+test-threads/ThreadJoinSelf: SKIP
diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc
index a8e504fd4..7ba2583da 100644
--- a/deps/v8/test/cctest/test-alloc.cc
+++ b/deps/v8/test/cctest/test-alloc.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -151,12 +151,21 @@ TEST(StressJS) {
Handle<Map> map(function->initial_map());
Handle<DescriptorArray> instance_descriptors(map->instance_descriptors());
Handle<Foreign> foreign = FACTORY->NewForeign(&kDescriptor);
- instance_descriptors = FACTORY->CopyAppendForeignDescriptor(
- instance_descriptors,
- FACTORY->NewStringFromAscii(Vector<const char>("get", 3)),
- foreign,
- static_cast<PropertyAttributes>(0));
- map->set_instance_descriptors(*instance_descriptors);
+ Handle<String> name =
+ FACTORY->NewStringFromAscii(Vector<const char>("get", 3));
+ ASSERT(instance_descriptors->IsEmpty());
+
+ Handle<DescriptorArray> new_descriptors = FACTORY->NewDescriptorArray(0, 1);
+
+ v8::internal::DescriptorArray::WhitenessWitness witness(*new_descriptors);
+ map->set_instance_descriptors(*new_descriptors);
+
+ CallbacksDescriptor d(*name,
+ *foreign,
+ static_cast<PropertyAttributes>(0),
+ v8::internal::PropertyDetails::kInitialIndex);
+ map->AppendDescriptor(&d, witness);
+
// Add the Foo constructor the global object.
env->Global()->Set(v8::String::New("Foo"), v8::Utils::ToLocal(function));
// Call the accessor through JavaScript.
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index e24782085..3be068009 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -38,6 +38,7 @@
#include "isolate.h"
#include "compilation-cache.h"
#include "execution.h"
+#include "objects.h"
#include "snapshot.h"
#include "platform.h"
#include "utils.h"
@@ -403,6 +404,10 @@ THREADED_TEST(ScriptUsingStringResource) {
CHECK(source->IsExternal());
CHECK_EQ(resource,
static_cast<TestResource*>(source->GetExternalStringResource()));
+ String::Encoding encoding = String::UNKNOWN_ENCODING;
+ CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource),
+ source->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::TWO_BYTE_ENCODING, encoding);
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(0, dispose_count);
}
@@ -418,9 +423,16 @@ THREADED_TEST(ScriptUsingAsciiStringResource) {
{
v8::HandleScope scope;
LocalContext env;
- Local<String> source =
- String::NewExternal(new TestAsciiResource(i::StrDup(c_source),
- &dispose_count));
+ TestAsciiResource* resource = new TestAsciiResource(i::StrDup(c_source),
+ &dispose_count);
+ Local<String> source = String::NewExternal(resource);
+ CHECK(source->IsExternalAscii());
+ CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource),
+ source->GetExternalAsciiStringResource());
+ String::Encoding encoding = String::UNKNOWN_ENCODING;
+ CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource),
+ source->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::ASCII_ENCODING, encoding);
Local<Script> script = Script::Compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
@@ -444,6 +456,11 @@ THREADED_TEST(ScriptMakingExternalString) {
// Trigger GCs so that the newly allocated string moves to old gen.
HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CHECK_EQ(source->IsExternal(), false);
+ CHECK_EQ(source->IsExternalAscii(), false);
+ String::Encoding encoding = String::UNKNOWN_ENCODING;
+ CHECK_EQ(NULL, source->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::ASCII_ENCODING, encoding);
bool success = source->MakeExternal(new TestResource(two_byte_source,
&dispose_count));
CHECK(success);
@@ -952,22 +969,33 @@ THREADED_TEST(FindInstanceInPrototypeChain) {
THREADED_TEST(TinyInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
int32_t value = 239;
Local<v8::Integer> value_obj = v8::Integer::New(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::New(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(BigSmiInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
int32_t value = i::Smi::kMaxValue;
// We cannot add one to a Smi::kMaxValue without wrapping.
if (i::kSmiValueSize < 32) {
CHECK(i::Smi::IsValid(value));
CHECK(!i::Smi::IsValid(value + 1));
+
Local<v8::Integer> value_obj = v8::Integer::New(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::New(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
}
@@ -975,6 +1003,8 @@ THREADED_TEST(BigSmiInteger) {
THREADED_TEST(BigInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
// We cannot add one to a Smi::kMaxValue without wrapping.
if (i::kSmiValueSize < 32) {
// The casts allow this to compile, even if Smi::kMaxValue is 2^31-1.
@@ -983,8 +1013,12 @@ THREADED_TEST(BigInteger) {
static_cast<int32_t>(static_cast<uint32_t>(i::Smi::kMaxValue) + 1);
CHECK(value > i::Smi::kMaxValue);
CHECK(!i::Smi::IsValid(value));
+
Local<v8::Integer> value_obj = v8::Integer::New(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::New(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
}
@@ -992,42 +1026,66 @@ THREADED_TEST(BigInteger) {
THREADED_TEST(TinyUnsignedInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
uint32_t value = 239;
+
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(BigUnsignedSmiInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
uint32_t value = static_cast<uint32_t>(i::Smi::kMaxValue);
CHECK(i::Smi::IsValid(value));
CHECK(!i::Smi::IsValid(value + 1));
+
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(BigUnsignedInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
uint32_t value = static_cast<uint32_t>(i::Smi::kMaxValue) + 1;
CHECK(value > static_cast<uint32_t>(i::Smi::kMaxValue));
CHECK(!i::Smi::IsValid(value));
+
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(OutOfSignedRangeUnsignedInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
uint32_t INT32_MAX_AS_UINT = (1U << 31) - 1;
uint32_t value = INT32_MAX_AS_UINT + 1;
CHECK(value > INT32_MAX_AS_UINT); // No overflow.
+
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
@@ -2085,6 +2143,10 @@ THREADED_TEST(HiddenProperties) {
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+ CHECK(obj->SetHiddenValue(key, Handle<Value>()));
+ CHECK(obj->GetHiddenValue(key).IsEmpty());
+
+ CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002)));
CHECK(obj->DeleteHiddenValue(key));
CHECK(obj->GetHiddenValue(key).IsEmpty());
}
@@ -2393,20 +2455,19 @@ THREADED_TEST(ScriptException) {
bool message_received;
-static void check_message(v8::Handle<v8::Message> message,
- v8::Handle<Value> data) {
- CHECK_EQ(5.76, data->NumberValue());
+static void check_message_0(v8::Handle<v8::Message> message,
+ v8::Handle<Value> data) {
CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
CHECK_EQ(7.56, message->GetScriptData()->NumberValue());
message_received = true;
}
-THREADED_TEST(MessageHandlerData) {
+THREADED_TEST(MessageHandler0) {
message_received = false;
v8::HandleScope scope;
CHECK(!message_received);
- v8::V8::AddMessageListener(check_message, v8_num(5.76));
+ v8::V8::AddMessageListener(check_message_0);
LocalContext context;
v8::ScriptOrigin origin =
v8::ScriptOrigin(v8_str("6.75"));
@@ -2416,7 +2477,56 @@ THREADED_TEST(MessageHandlerData) {
script->Run();
CHECK(message_received);
// clear out the message listener
- v8::V8::RemoveMessageListeners(check_message);
+ v8::V8::RemoveMessageListeners(check_message_0);
+}
+
+
+static void check_message_1(v8::Handle<v8::Message> message,
+ v8::Handle<Value> data) {
+ CHECK(data->IsNumber());
+ CHECK_EQ(1337, data->Int32Value());
+ message_received = true;
+}
+
+
+TEST(MessageHandler1) {
+ message_received = false;
+ v8::HandleScope scope;
+ CHECK(!message_received);
+ v8::V8::AddMessageListener(check_message_1);
+ LocalContext context;
+ CompileRun("throw 1337;");
+ CHECK(message_received);
+ // clear out the message listener
+ v8::V8::RemoveMessageListeners(check_message_1);
+}
+
+
+static void check_message_2(v8::Handle<v8::Message> message,
+ v8::Handle<Value> data) {
+ LocalContext context;
+ CHECK(data->IsObject());
+ v8::Local<v8::Value> hidden_property =
+ v8::Object::Cast(*data)->GetHiddenValue(v8_str("hidden key"));
+ CHECK(v8_str("hidden value")->Equals(hidden_property));
+ message_received = true;
+}
+
+
+TEST(MessageHandler2) {
+ message_received = false;
+ v8::HandleScope scope;
+ CHECK(!message_received);
+ v8::V8::AddMessageListener(check_message_2);
+ LocalContext context;
+ v8::Local<v8::Value> error = v8::Exception::Error(v8_str("custom error"));
+ v8::Object::Cast(*error)->SetHiddenValue(v8_str("hidden key"),
+ v8_str("hidden value"));
+ context->Global()->Set(v8_str("error"), error);
+ CompileRun("throw error;");
+ CHECK(message_received);
+ // clear out the message listener
+ v8::V8::RemoveMessageListeners(check_message_2);
}
@@ -2702,7 +2812,7 @@ TEST(HugeConsStringOutOfMemory) {
static const int K = 1024;
v8::ResourceConstraints constraints;
constraints.set_max_young_space_size(256 * K);
- constraints.set_max_old_space_size(2 * K * K);
+ constraints.set_max_old_space_size(3 * K * K);
v8::SetResourceConstraints(&constraints);
// Execute a script that causes out of memory.
@@ -3057,7 +3167,33 @@ TEST(APIThrowMessageOverwrittenToString) {
"Number.prototype.toString = function() { return 'Whoops'; };"
"ReferenceError.prototype.toString = Object.prototype.toString;");
CompileRun("asdf;");
- v8::V8::RemoveMessageListeners(check_message);
+ v8::V8::RemoveMessageListeners(check_reference_error_message);
+}
+
+
+static void check_custom_error_message(
+ v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ const char* uncaught_error = "Uncaught MyError toString";
+ CHECK(message->Get()->Equals(v8_str(uncaught_error)));
+}
+
+
+TEST(CustomErrorToString) {
+ v8::HandleScope scope;
+ v8::V8::AddMessageListener(check_custom_error_message);
+ LocalContext context;
+ CompileRun(
+ "function MyError(name, message) { "
+ " this.name = name; "
+ " this.message = message; "
+ "} "
+ "MyError.prototype = Object.create(Error.prototype); "
+ "MyError.prototype.toString = function() { "
+ " return 'MyError toString'; "
+ "}; "
+ "throw new MyError('my name', 'my message'); ");
+ v8::V8::RemoveMessageListeners(check_custom_error_message);
}
@@ -3078,7 +3214,7 @@ TEST(APIThrowMessage) {
LocalContext context(0, templ);
CompileRun("ThrowFromC();");
CHECK(message_received);
- v8::V8::RemoveMessageListeners(check_message);
+ v8::V8::RemoveMessageListeners(receive_message);
}
@@ -3096,7 +3232,7 @@ TEST(APIThrowMessageAndVerboseTryCatch) {
CHECK(try_catch.HasCaught());
CHECK(result.IsEmpty());
CHECK(message_received);
- v8::V8::RemoveMessageListeners(check_message);
+ v8::V8::RemoveMessageListeners(receive_message);
}
@@ -3715,6 +3851,36 @@ THREADED_TEST(SimplePropertyWrite) {
}
+THREADED_TEST(SetterOnly) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetAccessor(v8_str("x"), NULL, SetXValue, v8_str("donut"));
+ LocalContext context;
+ context->Global()->Set(v8_str("obj"), templ->NewInstance());
+ Local<Script> script = Script::Compile(v8_str("obj.x = 4; obj.x"));
+ for (int i = 0; i < 10; i++) {
+ CHECK(xValue.IsEmpty());
+ script->Run();
+ CHECK_EQ(v8_num(4), xValue);
+ xValue.Dispose();
+ xValue = v8::Persistent<Value>();
+ }
+}
+
+
+THREADED_TEST(NoAccessors) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetAccessor(v8_str("x"), NULL, NULL, v8_str("donut"));
+ LocalContext context;
+ context->Global()->Set(v8_str("obj"), templ->NewInstance());
+ Local<Script> script = Script::Compile(v8_str("obj.x = 4; obj.x"));
+ for (int i = 0; i < 10; i++) {
+ script->Run();
+ }
+}
+
+
static v8::Handle<Value> XPropertyGetter(Local<String> property,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
@@ -4610,6 +4776,18 @@ THREADED_TEST(SimpleExtensions) {
}
+THREADED_TEST(NullExtensions) {
+ v8::HandleScope handle_scope;
+ v8::RegisterExtension(new Extension("nulltest", NULL));
+ const char* extension_names[] = { "nulltest" };
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Handle<Context> context = Context::New(&extensions);
+ Context::Scope lock(context);
+ v8::Handle<Value> result = Script::Compile(v8_str("1+3"))->Run();
+ CHECK_EQ(result, v8::Integer::New(4));
+}
+
+
static const char* kEmbeddedExtensionSource =
"function Ret54321(){return 54321;}~~@@$"
"$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS.";
@@ -5019,7 +5197,6 @@ TEST(RegexpOutOfMemory) {
static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
- CHECK_EQ(v8::Undefined(), data);
CHECK(message->GetScriptResourceName()->IsUndefined());
CHECK_EQ(v8::Undefined(), message->GetScriptResourceName());
message->GetLineNumber();
@@ -5140,7 +5317,9 @@ THREADED_TEST(IndependentWeakHandle) {
bool object_a_disposed = false;
object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag);
+ CHECK(!object_a.IsIndependent());
object_a.MarkIndependent();
+ CHECK(object_a.IsIndependent());
HEAP->PerformScavenge();
CHECK(object_a_disposed);
}
@@ -5223,7 +5402,7 @@ THREADED_TEST(IndependentHandleRevival) {
object.MarkIndependent();
HEAP->PerformScavenge();
CHECK(revived);
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
{
v8::HandleScope handle_scope;
v8::Local<String> y_str = v8_str("y");
@@ -5548,6 +5727,7 @@ THREADED_TEST(StringWrite) {
v8::Handle<String> str = v8_str("abcde");
// abc<Icelandic eth><Unicode snowman>.
v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203");
+ v8::Handle<String> str3 = v8::String::New("abc\0def", 7);
const int kStride = 4; // Must match stride in for loops in JS below.
CompileRun(
"var left = '';"
@@ -5758,6 +5938,28 @@ THREADED_TEST(StringWrite) {
CHECK_NE(0, strcmp(utf8buf, "abc\303\260\342\230\203"));
utf8buf[8] = '\0';
CHECK_EQ(0, strcmp(utf8buf, "abc\303\260\342\230\203"));
+
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ utf8buf[5] = 'X';
+ len = str->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen,
+ String::NO_NULL_TERMINATION);
+ CHECK_EQ(5, len);
+ CHECK_EQ('X', utf8buf[5]); // Test that the sixth character is untouched.
+ CHECK_EQ(5, charlen);
+ utf8buf[5] = '\0';
+ CHECK_EQ(0, strcmp(utf8buf, "abcde"));
+
+ memset(buf, 0x1, sizeof(buf));
+ len = str3->WriteAscii(buf);
+ CHECK_EQ(7, len);
+ CHECK_EQ(0, strcmp("abc def", buf));
+
+ memset(buf, 0x1, sizeof(buf));
+ len = str3->WriteAscii(buf, 0, -1, String::PRESERVE_ASCII_NULL);
+ CHECK_EQ(7, len);
+ CHECK_EQ(0, strcmp("abc", buf));
+ CHECK_EQ(0, buf[3]);
+ CHECK_EQ(0, strcmp("def", buf + 4));
}
@@ -9375,7 +9577,8 @@ static void GenerateSomeGarbage() {
v8::Handle<v8::Value> DirectApiCallback(const v8::Arguments& args) {
static int count = 0;
if (count++ % 3 == 0) {
- HEAP-> CollectAllGarbage(true); // This should move the stub
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+ // This should move the stub
GenerateSomeGarbage(); // This should ensure the old stub memory is flushed
}
return v8::Handle<v8::Value>();
@@ -9430,7 +9633,7 @@ THREADED_TEST(CallICFastApi_DirectCall_Throw) {
v8::Handle<v8::Value> DirectGetterCallback(Local<String> name,
const v8::AccessorInfo& info) {
if (++p_getter_count % 3 == 0) {
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
GenerateSomeGarbage();
}
return v8::Handle<v8::Value>();
@@ -10727,18 +10930,21 @@ TEST(DontLeakGlobalObjects) {
{ v8::HandleScope scope;
LocalContext context;
}
+ v8::V8::ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope;
LocalContext context;
v8_compile("Date")->Run();
}
+ v8::V8::ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope;
LocalContext context;
v8_compile("/aaa/")->Run();
}
+ v8::V8::ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope;
@@ -10747,6 +10953,7 @@ TEST(DontLeakGlobalObjects) {
LocalContext context(&extensions);
v8_compile("gc();")->Run();
}
+ v8::V8::ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
}
}
@@ -10877,6 +11084,307 @@ THREADED_TEST(NestedHandleScopeAndContexts) {
}
+static i::Handle<i::JSFunction>* foo_ptr = NULL;
+static int foo_count = 0;
+static i::Handle<i::JSFunction>* bar_ptr = NULL;
+static int bar_count = 0;
+
+
+static void entry_hook(uintptr_t function,
+ uintptr_t return_addr_location) {
+ i::Code* code = i::Code::GetCodeFromTargetAddress(
+ reinterpret_cast<i::Address>(function));
+ CHECK(code != NULL);
+
+ if (bar_ptr != NULL && code == (*bar_ptr)->code())
+ ++bar_count;
+
+ if (foo_ptr != NULL && code == (*foo_ptr)->code())
+ ++foo_count;
+
+ // TODO(siggi): Verify return_addr_location.
+ // This can be done by capturing JitCodeEvents, but requires an ordered
+ // collection.
+}
+
+
+static void RunLoopInNewEnv() {
+ bar_ptr = NULL;
+ foo_ptr = NULL;
+
+ v8::HandleScope outer;
+ v8::Persistent<Context> env = Context::New();
+ env->Enter();
+
+ const char* script =
+ "function bar() {"
+ " var sum = 0;"
+ " for (i = 0; i < 100; ++i)"
+ " sum = foo(i);"
+ " return sum;"
+ "}"
+ "function foo(i) { return i * i; }";
+ CompileRun(script);
+ i::Handle<i::JSFunction> bar =
+ i::Handle<i::JSFunction>::cast(
+ v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar"))));
+ ASSERT(*bar);
+
+ i::Handle<i::JSFunction> foo =
+ i::Handle<i::JSFunction>::cast(
+ v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo"))));
+ ASSERT(*foo);
+
+ bar_ptr = &bar;
+ foo_ptr = &foo;
+
+ v8::Handle<v8::Value> value = CompileRun("bar();");
+ CHECK(value->IsNumber());
+ CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value());
+
+ // Test the optimized codegen path.
+ value = CompileRun("%OptimizeFunctionOnNextCall(foo);"
+ "bar();");
+ CHECK(value->IsNumber());
+ CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value());
+
+ env->Exit();
+}
+
+
+TEST(SetFunctionEntryHook) {
+ i::FLAG_allow_natives_syntax = true;
+
+ // Test setting and resetting the entry hook.
+ // Nulling it should always succeed.
+ CHECK(v8::V8::SetFunctionEntryHook(NULL));
+
+ CHECK(v8::V8::SetFunctionEntryHook(entry_hook));
+ // Setting a hook while one's active should fail.
+ CHECK_EQ(false, v8::V8::SetFunctionEntryHook(entry_hook));
+
+ CHECK(v8::V8::SetFunctionEntryHook(NULL));
+
+ // Reset the entry count to zero and set the entry hook.
+ bar_count = 0;
+ foo_count = 0;
+ CHECK(v8::V8::SetFunctionEntryHook(entry_hook));
+ RunLoopInNewEnv();
+
+ CHECK_EQ(2, bar_count);
+ CHECK_EQ(200, foo_count);
+
+ // Clear the entry hook and count.
+ bar_count = 0;
+ foo_count = 0;
+ v8::V8::SetFunctionEntryHook(NULL);
+
+ // Clear the compilation cache to make sure we don't reuse the
+ // functions from the previous invocation.
+ v8::internal::Isolate::Current()->compilation_cache()->Clear();
+
+ // Verify that entry hooking is now disabled.
+ RunLoopInNewEnv();
+ CHECK_EQ(0u, bar_count);
+ CHECK_EQ(0u, foo_count);
+}
+
+
+static i::HashMap* code_map = NULL;
+static int saw_bar = 0;
+static int move_events = 0;
+
+
+static bool FunctionNameIs(const char* expected,
+ const v8::JitCodeEvent* event) {
+ // Log lines for functions are of the general form:
+ // "LazyCompile:<type><function_name>", where the type is one of
+ // "*", "~" or "".
+ static const char kPreamble[] = "LazyCompile:";
+ static size_t kPreambleLen = sizeof(kPreamble) - 1;
+
+ if (event->name.len < sizeof(kPreamble) - 1 ||
+ strncmp(kPreamble, event->name.str, kPreambleLen) != 0) {
+ return false;
+ }
+
+ const char* tail = event->name.str + kPreambleLen;
+ size_t tail_len = event->name.len - kPreambleLen;
+ size_t expected_len = strlen(expected);
+ if (tail_len == expected_len + 1) {
+ if (*tail == '*' || *tail == '~') {
+ --tail_len;
+ ++tail;
+ } else {
+ return false;
+ }
+ }
+
+ if (tail_len != expected_len)
+ return false;
+
+ return strncmp(tail, expected, expected_len) == 0;
+}
+
+
+static void event_handler(const v8::JitCodeEvent* event) {
+ CHECK(event != NULL);
+ CHECK(code_map != NULL);
+
+ switch (event->type) {
+ case v8::JitCodeEvent::CODE_ADDED: {
+ CHECK(event->code_start != NULL);
+ CHECK_NE(0, static_cast<int>(event->code_len));
+ CHECK(event->name.str != NULL);
+ i::HashMap::Entry* entry =
+ code_map->Lookup(event->code_start,
+ i::ComputePointerHash(event->code_start),
+ true);
+ entry->value = reinterpret_cast<void*>(event->code_len);
+
+ if (FunctionNameIs("bar", event)) {
+ ++saw_bar;
+ }
+ }
+ break;
+
+ case v8::JitCodeEvent::CODE_MOVED: {
+ uint32_t hash = i::ComputePointerHash(event->code_start);
+ // We would like to never see code move that we haven't seen before,
+ // but the code creation event does not happen until the line endings
+ // have been calculated (this is so that we can report the line in the
+ // script at which the function source is found, see
+ // Compiler::RecordFunctionCompilation) and the line endings
+ // calculations can cause a GC, which can move the newly created code
+ // before its existence can be logged.
+ i::HashMap::Entry* entry =
+ code_map->Lookup(event->code_start, hash, false);
+ if (entry != NULL) {
+ ++move_events;
+
+ CHECK_EQ(reinterpret_cast<void*>(event->code_len), entry->value);
+ code_map->Remove(event->code_start, hash);
+
+ entry = code_map->Lookup(event->new_code_start,
+ i::ComputePointerHash(event->new_code_start),
+ true);
+ CHECK(entry != NULL);
+ entry->value = reinterpret_cast<void*>(event->code_len);
+ }
+ }
+ break;
+
+ case v8::JitCodeEvent::CODE_REMOVED:
+ // Object/code removal events are currently not dispatched from the GC.
+ CHECK(false);
+ break;
+ default:
+ // Impossible event.
+ CHECK(false);
+ break;
+ }
+}
+
+
+// Implemented in the test-alloc.cc test suite.
+void SimulateFullSpace(i::PagedSpace* space);
+
+
+static bool MatchPointers(void* key1, void* key2) {
+ return key1 == key2;
+}
+
+
+TEST(SetJitCodeEventHandler) {
+ const char* script =
+ "function bar() {"
+ " var sum = 0;"
+ " for (i = 0; i < 100; ++i)"
+ " sum = foo(i);"
+ " return sum;"
+ "}"
+ "function foo(i) { return i * i; };"
+ "bar();";
+
+ // Run this test in a new isolate to make sure we don't
+ // have remnants of state from other code.
+ v8::Isolate* isolate = v8::Isolate::New();
+ isolate->Enter();
+
+ {
+ i::HashMap code(MatchPointers);
+ code_map = &code;
+
+ saw_bar = 0;
+ move_events = 0;
+
+ i::FLAG_stress_compaction = true;
+ V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, event_handler);
+
+ v8::HandleScope scope;
+ // Generate new code objects sparsely distributed across several
+ // different fragmented code-space pages.
+ const int kIterations = 10;
+ for (int i = 0; i < kIterations; ++i) {
+ LocalContext env;
+
+ v8::Handle<v8::Script> compiled_script;
+ {
+ i::AlwaysAllocateScope always_allocate;
+ SimulateFullSpace(HEAP->code_space());
+ compiled_script = v8_compile(script);
+ }
+ compiled_script->Run();
+
+ // Clear the compilation cache to get more wastage.
+ ISOLATE->compilation_cache()->Clear();
+ }
+
+ // Force code movement.
+ HEAP->CollectAllAvailableGarbage("TestSetJitCodeEventHandler");
+
+ CHECK_LE(kIterations, saw_bar);
+ CHECK_NE(0, move_events);
+
+ code_map = NULL;
+ V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
+ }
+
+ isolate->Exit();
+ isolate->Dispose();
+
+ // Do this in a new isolate.
+ isolate = v8::Isolate::New();
+ isolate->Enter();
+
+ // Verify that we get callbacks for existing code objects when we
+ // request enumeration of existing code.
+ {
+ v8::HandleScope scope;
+ LocalContext env;
+ CompileRun(script);
+
+ // Now get code through initial iteration.
+ i::HashMap code(MatchPointers);
+ code_map = &code;
+
+ V8::SetJitCodeEventHandler(v8::kJitCodeEventEnumExisting, event_handler);
+ V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
+
+ code_map = NULL;
+
+ // We expect that we got some events. Note that if we could get code removal
+ // notifications, we could compare two collections, one created by listening
+ // from the time of creation of an isolate, and the other by subscribing
+ // with EnumExisting.
+ CHECK_NE(0, code.occupancy());
+ }
+
+ isolate->Exit();
+ isolate->Dispose();
+}
+
+
static int64_t cast(intptr_t x) { return static_cast<int64_t>(x); }
@@ -12046,7 +12554,7 @@ class RegExpStringModificationTest {
// Inject the input as a global variable.
i::Handle<i::String> input_name =
FACTORY->NewStringFromAscii(i::Vector<const char>("input", 5));
- i::Isolate::Current()->global_context()->global()->SetProperty(
+ i::Isolate::Current()->native_context()->global_object()->SetProperty(
*input_name,
*input_,
NONE,
@@ -13625,6 +14133,41 @@ THREADED_TEST(ExternalArrayInfo) {
}
+void ExternalArrayLimitTestHelper(v8::ExternalArrayType array_type, int size) {
+ v8::Handle<v8::Object> obj = v8::Object::New();
+ v8::V8::SetFatalErrorHandler(StoringErrorCallback);
+ last_location = last_message = NULL;
+ obj->SetIndexedPropertiesToExternalArrayData(NULL, array_type, size);
+ CHECK(!obj->HasIndexedPropertiesInExternalArrayData());
+ CHECK_NE(NULL, last_location);
+ CHECK_NE(NULL, last_message);
+}
+
+
+TEST(ExternalArrayLimits) {
+ v8::HandleScope scope;
+ LocalContext context;
+ ExternalArrayLimitTestHelper(v8::kExternalByteArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalByteArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedByteArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedByteArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalShortArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalShortArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedShortArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedShortArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalIntArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalIntArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedIntArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedIntArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalFloatArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalFloatArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalDoubleArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalDoubleArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalPixelArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalPixelArray, 0xffffffff);
+}
+
+
THREADED_TEST(ScriptContextDependence) {
v8::HandleScope scope;
LocalContext c1;
@@ -14003,6 +14546,89 @@ TEST(SourceURLInStackTrace) {
}
+v8::Handle<Value> AnalyzeStackOfInlineScriptWithSourceURL(
+ const v8::Arguments& args) {
+ v8::HandleScope scope;
+ v8::Handle<v8::StackTrace> stackTrace =
+ v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
+ CHECK_EQ(4, stackTrace->GetFrameCount());
+ v8::Handle<v8::String> url = v8_str("url");
+ for (int i = 0; i < 3; i++) {
+ v8::Handle<v8::String> name =
+ stackTrace->GetFrame(i)->GetScriptNameOrSourceURL();
+ CHECK(!name.IsEmpty());
+ CHECK_EQ(url, name);
+ }
+ return v8::Undefined();
+}
+
+
+TEST(InlineScriptWithSourceURLInStackTrace) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->Set(v8_str("AnalyzeStackOfInlineScriptWithSourceURL"),
+ v8::FunctionTemplate::New(
+ AnalyzeStackOfInlineScriptWithSourceURL));
+ LocalContext context(0, templ);
+
+ const char *source =
+ "function outer() {\n"
+ "function bar() {\n"
+ " AnalyzeStackOfInlineScriptWithSourceURL();\n"
+ "}\n"
+ "function foo() {\n"
+ "\n"
+ " bar();\n"
+ "}\n"
+ "foo();\n"
+ "}\n"
+ "outer()\n"
+ "//@ sourceURL=source_url";
+ CHECK(CompileRunWithOrigin(source, "url", 0, 1)->IsUndefined());
+}
+
+
+v8::Handle<Value> AnalyzeStackOfDynamicScriptWithSourceURL(
+ const v8::Arguments& args) {
+ v8::HandleScope scope;
+ v8::Handle<v8::StackTrace> stackTrace =
+ v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
+ CHECK_EQ(4, stackTrace->GetFrameCount());
+ v8::Handle<v8::String> url = v8_str("source_url");
+ for (int i = 0; i < 3; i++) {
+ v8::Handle<v8::String> name =
+ stackTrace->GetFrame(i)->GetScriptNameOrSourceURL();
+ CHECK(!name.IsEmpty());
+ CHECK_EQ(url, name);
+ }
+ return v8::Undefined();
+}
+
+
+TEST(DynamicWithSourceURLInStackTrace) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->Set(v8_str("AnalyzeStackOfDynamicScriptWithSourceURL"),
+ v8::FunctionTemplate::New(
+ AnalyzeStackOfDynamicScriptWithSourceURL));
+ LocalContext context(0, templ);
+
+ const char *source =
+ "function outer() {\n"
+ "function bar() {\n"
+ " AnalyzeStackOfDynamicScriptWithSourceURL();\n"
+ "}\n"
+ "function foo() {\n"
+ "\n"
+ " bar();\n"
+ "}\n"
+ "foo();\n"
+ "}\n"
+ "outer()\n"
+ "//@ sourceURL=source_url";
+ CHECK(CompileRunWithOrigin(source, "url", 0, 0)->IsUndefined());
+}
+
static void CreateGarbageInOldSpace() {
v8::HandleScope scope;
i::AlwaysAllocateScope always_allocate;
@@ -14423,6 +15049,7 @@ TEST(Regress528) {
context->Exit();
}
context.Dispose();
+ v8::V8::ContextDisposedNotification();
for (gc_count = 1; gc_count < 10; gc_count++) {
other_context->Enter();
CompileRun(source_simple);
@@ -14445,6 +15072,7 @@ TEST(Regress528) {
context->Exit();
}
context.Dispose();
+ v8::V8::ContextDisposedNotification();
for (gc_count = 1; gc_count < 10; gc_count++) {
other_context->Enter();
CompileRun(source_eval);
@@ -14472,6 +15100,7 @@ TEST(Regress528) {
context->Exit();
}
context.Dispose();
+ v8::V8::ContextDisposedNotification();
for (gc_count = 1; gc_count < 10; gc_count++) {
other_context->Enter();
CompileRun(source_exception);
@@ -14483,6 +15112,7 @@ TEST(Regress528) {
CHECK_EQ(1, GetGlobalObjectsCount());
other_context.Dispose();
+ v8::V8::ContextDisposedNotification();
}
@@ -15637,6 +16267,45 @@ TEST(DontDeleteCellLoadICAPI) {
}
+class Visitor42 : public v8::PersistentHandleVisitor {
+ public:
+ explicit Visitor42(v8::Persistent<v8::Object> object)
+ : counter_(0), object_(object) { }
+
+ virtual void VisitPersistentHandle(Persistent<Value> value,
+ uint16_t class_id) {
+ if (class_id == 42) {
+ CHECK(value->IsObject());
+ v8::Persistent<v8::Object> visited =
+ v8::Persistent<v8::Object>::Cast(value);
+ CHECK_EQ(42, visited.WrapperClassId());
+ CHECK_EQ(object_, visited);
+ ++counter_;
+ }
+ }
+
+ int counter_;
+ v8::Persistent<v8::Object> object_;
+};
+
+
+TEST(PersistentHandleVisitor) {
+ v8::HandleScope scope;
+ LocalContext context;
+ v8::Persistent<v8::Object> object =
+ v8::Persistent<v8::Object>::New(v8::Object::New());
+ CHECK_EQ(0, object.WrapperClassId());
+ object.SetWrapperClassId(42);
+ CHECK_EQ(42, object.WrapperClassId());
+
+ Visitor42 visitor(object);
+ v8::V8::VisitHandlesWithClassIds(&visitor);
+ CHECK_EQ(1, visitor.counter_);
+
+ object.Dispose();
+}
+
+
TEST(RegExp) {
v8::HandleScope scope;
LocalContext context;
@@ -16072,6 +16741,24 @@ THREADED_TEST(AllowCodeGenFromStrings) {
}
+TEST(SetErrorMessageForCodeGenFromStrings) {
+ v8::HandleScope scope;
+ LocalContext context;
+ TryCatch try_catch;
+
+ Handle<String> message = v8_str("Message") ;
+ Handle<String> expected_message = v8_str("Uncaught EvalError: Message");
+ V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationDisallowed);
+ context->AllowCodeGenerationFromStrings(false);
+ context->SetErrorMessageForCodeGenerationFromStrings(message);
+ Handle<Value> result = CompileRun("eval('42')");
+ CHECK(result.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ Handle<String> actual_message = try_catch.Message()->Get();
+ CHECK(expected_message->Equals(actual_message));
+}
+
+
static v8::Handle<Value> NonObjectThis(const v8::Arguments& args) {
return v8::Undefined();
}
@@ -16125,7 +16812,8 @@ THREADED_TEST(Regress1516) {
CHECK_LE(1, elements);
}
- i::Isolate::Current()->heap()->CollectAllGarbage(true);
+ i::Isolate::Current()->heap()->CollectAllGarbage(
+ i::Heap::kAbortIncrementalMarkingMask);
{ i::Object* raw_map_cache = i::Isolate::Current()->context()->map_cache();
if (raw_map_cache != i::Isolate::Current()->heap()->undefined_value()) {
i::MapCache* map_cache = i::MapCache::cast(raw_map_cache);
@@ -16977,50 +17665,44 @@ THREADED_TEST(Regress142088) {
SetterWhichSetsYOnThisTo23);
context->Global()->Set(v8_str("obj"), templ->NewInstance());
- // Turn monomorphic on slow object with native accessor, then just
- // delete the property and fail.
CompileRun("function load(x) { return x.foo; }"
- "function store(x) { x.foo = void 0; }"
- "function keyed_load(x, key) { return x[key]; }"
- // Second version of function has a different source (add void 0)
- // so that it does not share code with the first version. This
- // ensures that the ICs are monomorphic.
- "function load2(x) { void 0; return x.foo; }"
- "function store2(x) { void 0; x.foo = void 0; }"
- "function keyed_load2(x, key) { void 0; return x[key]; }"
-
- "obj.__proto__ = null;"
- "var subobj = {};"
- "subobj.__proto__ = obj;"
+ "var o = Object.create(obj);"
"%OptimizeObjectForAddingMultipleProperties(obj, 1);"
+ "load(o); load(o); load(o); load(o);");
+}
- // Make the ICs monomorphic.
- "load(obj); load(obj);"
- "load2(subobj); load2(subobj);"
- "store(obj);"
- "store2(subobj);"
- "keyed_load(obj, 'foo'); keyed_load(obj, 'foo');"
- "keyed_load2(subobj, 'foo'); keyed_load2(subobj, 'foo');"
- // Delete the accessor. It better not be called any more now.
- "delete obj.foo;"
- "obj.y = void 0;"
- "subobj.y = void 0;"
+THREADED_TEST(Regress137496) {
+ i::FLAG_expose_gc = true;
+ v8::HandleScope scope;
+ LocalContext context;
- "var load_result = load(obj);"
- "var load_result2 = load2(subobj);"
- "var keyed_load_result = keyed_load(obj, 'foo');"
- "var keyed_load_result2 = keyed_load2(subobj, 'foo');"
- "store(obj);"
- "store2(subobj);"
- "var y_from_obj = obj.y;"
- "var y_from_subobj = subobj.y;");
- CHECK(context->Global()->Get(v8_str("load_result"))->IsUndefined());
- CHECK(context->Global()->Get(v8_str("load_result2"))->IsUndefined());
- CHECK(context->Global()->Get(v8_str("keyed_load_result"))->IsUndefined());
- CHECK(context->Global()->Get(v8_str("keyed_load_result2"))->IsUndefined());
- CHECK(context->Global()->Get(v8_str("y_from_obj"))->IsUndefined());
- CHECK(context->Global()->Get(v8_str("y_from_subobj"))->IsUndefined());
+ // Compile a try-finally clause where the finally block causes a GC
+ // while there still is a message pending for external reporting.
+ TryCatch try_catch;
+ try_catch.SetVerbose(true);
+ CompileRun("try { throw new Error(); } finally { gc(); }");
+ CHECK(try_catch.HasCaught());
+}
+
+
+THREADED_TEST(Regress149912) {
+ v8::HandleScope scope;
+ LocalContext context;
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter);
+ context->Global()->Set(v8_str("Bug"), templ->GetFunction());
+ CompileRun("Number.prototype.__proto__ = new Bug; var x = 0; x.foo();");
+}
+
+
+THREADED_TEST(Regress157124) {
+ v8::HandleScope scope;
+ LocalContext context;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ Local<Object> obj = templ->NewInstance();
+ obj->GetIdentityHash();
+ obj->DeleteHiddenValue(v8_str("Bug"));
}
diff --git a/deps/v8/test/cctest/test-ast.cc b/deps/v8/test/cctest/test-ast.cc
index 80c7fdff7..c72f87ec3 100644
--- a/deps/v8/test/cctest/test-ast.cc
+++ b/deps/v8/test/cctest/test-ast.cc
@@ -39,8 +39,10 @@ TEST(List) {
List<AstNode*>* list = new List<AstNode*>(0);
CHECK_EQ(0, list->length());
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
- AstNodeFactory<AstNullVisitor> factory(Isolate::Current());
+ Isolate* isolate = Isolate::Current();
+ Zone* zone = isolate->runtime_zone();
+ ZoneScope zone_scope(zone, DELETE_ON_EXIT);
+ AstNodeFactory<AstNullVisitor> factory(isolate, zone);
AstNode* node = factory.NewEmptyStatement();
list->Add(node);
CHECK_EQ(1, list->length());
diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc
index 9ca0b0a17..7700a980d 100644
--- a/deps/v8/test/cctest/test-compiler.cc
+++ b/deps/v8/test/cctest/test-compiler.cc
@@ -68,15 +68,9 @@ v8::Handle<v8::Value> PrintExtension::Print(const v8::Arguments& args) {
for (int i = 0; i < args.Length(); i++) {
if (i != 0) printf(" ");
v8::HandleScope scope;
- v8::Handle<v8::Value> arg = args[i];
- v8::Handle<v8::String> string_obj = arg->ToString();
- if (string_obj.IsEmpty()) return string_obj;
- int length = string_obj->Length();
- uint16_t* string = NewArray<uint16_t>(length + 1);
- string_obj->Write(string);
- for (int j = 0; j < length; j++)
- printf("%lc", static_cast<wchar_t>(string[j]));
- DeleteArray(string);
+ v8::String::Utf8Value str(args[i]);
+ if (*str == NULL) return v8::Undefined();
+ printf("%s", *str);
}
printf("\n");
return v8::Undefined();
@@ -101,14 +95,14 @@ static void InitializeVM() {
static MaybeObject* GetGlobalProperty(const char* name) {
Handle<String> symbol = FACTORY->LookupAsciiSymbol(name);
- return Isolate::Current()->context()->global()->GetProperty(*symbol);
+ return Isolate::Current()->context()->global_object()->GetProperty(*symbol);
}
static void SetGlobalProperty(const char* name, Object* value) {
Handle<Object> object(value);
Handle<String> symbol = FACTORY->LookupAsciiSymbol(name);
- Handle<JSObject> global(Isolate::Current()->context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global_object());
SetProperty(global, symbol, object, NONE, kNonStrictMode);
}
@@ -120,12 +114,13 @@ static Handle<JSFunction> Compile(const char* source) {
Handle<String>(),
0,
0,
+ Handle<Context>(Isolate::Current()->native_context()),
NULL,
NULL,
Handle<String>::null(),
NOT_NATIVES_CODE);
return FACTORY->NewFunctionFromSharedFunctionInfo(shared_function,
- Isolate::Current()->global_context());
+ Isolate::Current()->native_context());
}
@@ -138,7 +133,7 @@ static double Inc(int x) {
if (fun.is_null()) return -1;
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global_object());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
@@ -159,7 +154,7 @@ static double Add(int x, int y) {
SetGlobalProperty("x", Smi::FromInt(x));
SetGlobalProperty("y", Smi::FromInt(y));
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global_object());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
@@ -179,7 +174,7 @@ static double Abs(int x) {
SetGlobalProperty("x", Smi::FromInt(x));
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global_object());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
@@ -200,7 +195,7 @@ static double Sum(int n) {
SetGlobalProperty("n", Smi::FromInt(n));
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global_object());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
@@ -221,7 +216,7 @@ TEST(Print) {
Handle<JSFunction> fun = Compile(source);
if (fun.is_null()) return;
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global_object());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
}
@@ -254,7 +249,7 @@ TEST(Stuff) {
Handle<JSFunction> fun = Compile(source);
CHECK(!fun.is_null());
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global_object());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
CHECK_EQ(511.0, GetGlobalProperty("r")->ToObjectChecked()->Number());
@@ -269,7 +264,7 @@ TEST(UncaughtThrow) {
Handle<JSFunction> fun = Compile(source);
CHECK(!fun.is_null());
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global_object());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(has_pending_exception);
CHECK_EQ(42.0, Isolate::Current()->pending_exception()->
@@ -294,12 +289,12 @@ TEST(C2JSFrames) {
// Run the generated code to populate the global object with 'foo'.
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global_object());
Execution::Call(fun0, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
Object* foo_symbol = FACTORY->LookupAsciiSymbol("foo")->ToObjectChecked();
- MaybeObject* fun1_object = Isolate::Current()->context()->global()->
+ MaybeObject* fun1_object = Isolate::Current()->context()->global_object()->
GetProperty(String::cast(foo_symbol));
Handle<Object> fun1(fun1_object->ToObjectChecked());
CHECK(fun1->IsJSFunction());
@@ -352,6 +347,38 @@ TEST(GetScriptLineNumber) {
}
+// Test that optimized code for different closures is actually shared
+// immediately by the FastNewClosureStub when run in the same context.
+TEST(OptimizedCodeSharing) {
+ // Skip test if --cache-optimized-code is not activated by default because
+ // FastNewClosureStub that is baked into the snapshot is incorrect.
+ if (!FLAG_cache_optimized_code) return;
+ FLAG_allow_natives_syntax = true;
+ InitializeVM();
+ v8::HandleScope scope;
+ for (int i = 0; i < 10; i++) {
+ LocalContext env;
+ env->Global()->Set(v8::String::New("x"), v8::Integer::New(i));
+ CompileRun("function MakeClosure() {"
+ " return function() { return x; };"
+ "}"
+ "var closure0 = MakeClosure();"
+ "%DebugPrint(closure0());"
+ "%OptimizeFunctionOnNextCall(closure0);"
+ "%DebugPrint(closure0());"
+ "var closure1 = MakeClosure();"
+ "var closure2 = MakeClosure();");
+ Handle<JSFunction> fun1 = v8::Utils::OpenHandle(
+ *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1"))));
+ Handle<JSFunction> fun2 = v8::Utils::OpenHandle(
+ *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2"))));
+ CHECK(fun1->IsOptimized() || !fun1->IsOptimizable());
+ CHECK(fun2->IsOptimized() || !fun2->IsOptimizable());
+ CHECK_EQ(fun1->code(), fun2->code());
+ }
+}
+
+
#ifdef ENABLE_DISASSEMBLER
static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
const char* property_name) {
@@ -374,15 +401,16 @@ static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) {
Address end = pc + decode_size;
v8::internal::EmbeddedVector<char, 128> decode_buffer;
+ v8::internal::EmbeddedVector<char, 128> smi_hex_buffer;
+ Smi* smi = Smi::FromInt(12345678);
+ OS::SNPrintF(smi_hex_buffer, "0x%lx", reinterpret_cast<intptr_t>(smi));
while (pc < end) {
int num_const = d.ConstantPoolSizeAt(pc);
if (num_const >= 0) {
pc += (num_const + 1) * kPointerSize;
} else {
pc += d.InstructionDecode(decode_buffer, pc);
- CHECK(strstr(decode_buffer.start(), "mov eax,0x178c29c") == NULL);
- CHECK(strstr(decode_buffer.start(), "push 0x178c29c") == NULL);
- CHECK(strstr(decode_buffer.start(), "0x178c29c") == NULL);
+ CHECK(strstr(decode_buffer.start(), smi_hex_buffer.start()) == NULL);
}
}
}
diff --git a/deps/v8/test/cctest/test-dataflow.cc b/deps/v8/test/cctest/test-dataflow.cc
index 005d440d1..ae3327965 100644
--- a/deps/v8/test/cctest/test-dataflow.cc
+++ b/deps/v8/test/cctest/test-dataflow.cc
@@ -36,8 +36,8 @@ using namespace v8::internal;
TEST(BitVector) {
v8::internal::V8::Initialize(NULL);
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
- Zone* zone = Isolate::Current()->zone();
+ Zone* zone = Isolate::Current()->runtime_zone();
+ ZoneScope zone_scope(zone, DELETE_ON_EXIT);
{
BitVector v(15, zone);
v.Add(1);
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 166b76291..f2253e3a9 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -197,10 +197,9 @@ static bool HasDebugInfo(v8::Handle<v8::Function> fun) {
// number.
static int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) {
static int break_point = 0;
- Handle<v8::internal::SharedFunctionInfo> shared(fun->shared());
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
debug->SetBreakPoint(
- shared,
+ fun,
Handle<Object>(v8::internal::Smi::FromInt(++break_point)),
&position);
return break_point;
@@ -515,7 +514,7 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
// there
ClearBreakPoint(bp);
CHECK(!debug->HasDebugInfo(shared));
- CHECK(debug->EnsureDebugInfo(shared));
+ CHECK(debug->EnsureDebugInfo(shared, fun));
TestBreakLocationIterator it2(Debug::GetDebugInfo(shared));
it2.FindBreakLocationFromPosition(position);
actual_mode = it2.it()->rinfo()->rmode();
@@ -2382,7 +2381,7 @@ TEST(DebuggerStatementBreakpoint) {
}
-// Thest that the evaluation of expressions when a break point is hit generates
+// Test that the evaluation of expressions when a break point is hit generates
// the correct results.
TEST(DebugEvaluate) {
v8::HandleScope scope;
@@ -2498,6 +2497,98 @@ TEST(DebugEvaluate) {
CheckDebuggerUnloaded();
}
+
+int debugEventCount = 0;
+static void CheckDebugEvent(const v8::Debug::EventDetails& eventDetails) {
+ if (eventDetails.GetEvent() == v8::Break) ++debugEventCount;
+}
+
+// Test that the conditional breakpoints work event if code generation from
+// strings is prohibited in the debugee context.
+TEST(ConditionalBreakpointWithCodeGenerationDisallowed) {
+ v8::HandleScope scope;
+ DebugLocalContext env;
+ env.ExposeDebug();
+
+ v8::Debug::SetDebugEventListener2(CheckDebugEvent);
+
+ v8::Local<v8::Function> foo = CompileFunction(&env,
+ "function foo(x) {\n"
+ " var s = 'String value2';\n"
+ " return s + x;\n"
+ "}",
+ "foo");
+
+ // Set conditional breakpoint with condition 'true'.
+ CompileRun("debug.Debug.setBreakPoint(foo, 2, 0, 'true')");
+
+ debugEventCount = 0;
+ env->AllowCodeGenerationFromStrings(false);
+ foo->Call(env->Global(), 0, NULL);
+ CHECK_EQ(1, debugEventCount);
+
+ v8::Debug::SetDebugEventListener2(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
+bool checkedDebugEvals = true;
+v8::Handle<v8::Function> checkGlobalEvalFunction;
+v8::Handle<v8::Function> checkFrameEvalFunction;
+static void CheckDebugEval(const v8::Debug::EventDetails& eventDetails) {
+ if (eventDetails.GetEvent() == v8::Break) {
+ ++debugEventCount;
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Value> args[] = { eventDetails.GetExecutionState() };
+ CHECK(checkGlobalEvalFunction->Call(
+ eventDetails.GetEventContext()->Global(), 1, args)->IsTrue());
+ CHECK(checkFrameEvalFunction->Call(
+ eventDetails.GetEventContext()->Global(), 1, args)->IsTrue());
+ }
+}
+
+// Test that the evaluation of expressions when a break point is hit generates
+// the correct results in case code generation from strings is disallowed in the
+// debugee context.
+TEST(DebugEvaluateWithCodeGenerationDisallowed) {
+ v8::HandleScope scope;
+ DebugLocalContext env;
+ env.ExposeDebug();
+
+ v8::Debug::SetDebugEventListener2(CheckDebugEval);
+
+ v8::Local<v8::Function> foo = CompileFunction(&env,
+ "var global = 'Global';\n"
+ "function foo(x) {\n"
+ " var local = 'Local';\n"
+ " debugger;\n"
+ " return local + x;\n"
+ "}",
+ "foo");
+ checkGlobalEvalFunction = CompileFunction(&env,
+ "function checkGlobalEval(exec_state) {\n"
+ " return exec_state.evaluateGlobal('global').value() === 'Global';\n"
+ "}",
+ "checkGlobalEval");
+
+ checkFrameEvalFunction = CompileFunction(&env,
+ "function checkFrameEval(exec_state) {\n"
+ " return exec_state.frame(0).evaluate('local').value() === 'Local';\n"
+ "}",
+ "checkFrameEval");
+ debugEventCount = 0;
+ env->AllowCodeGenerationFromStrings(false);
+ foo->Call(env->Global(), 0, NULL);
+ CHECK_EQ(1, debugEventCount);
+
+ checkGlobalEvalFunction.Clear();
+ checkFrameEvalFunction.Clear();
+ v8::Debug::SetDebugEventListener2(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
// Copies a C string to a 16-bit string. Does not check for buffer overflow.
// Does not use the V8 engine to convert strings, so it can be used
// in any thread. Returns the length of the string.
@@ -4027,15 +4118,12 @@ TEST(StepWithException) {
TEST(DebugBreak) {
+#ifdef VERIFY_HEAP
+ i::FLAG_verify_heap = true;
+#endif
v8::HandleScope scope;
DebugLocalContext env;
- // This test should be run with option --verify-heap. As --verify-heap is
- // only available in debug mode only check for it in that case.
-#ifdef DEBUG
- CHECK(v8::internal::FLAG_verify_heap);
-#endif
-
// Register a debug event listener which sets the break flag and counts.
v8::Debug::SetDebugEventListener(DebugEventBreak);
@@ -4274,9 +4362,9 @@ TEST(InterceptorPropertyMirror) {
"named_values[%d] instanceof debug.PropertyMirror", i);
CHECK(CompileRun(buffer.start())->BooleanValue());
- // 5 is PropertyType.Interceptor
OS::SNPrintF(buffer, "named_values[%d].propertyType()", i);
- CHECK_EQ(5, CompileRun(buffer.start())->Int32Value());
+ CHECK_EQ(v8::internal::INTERCEPTOR,
+ CompileRun(buffer.start())->Int32Value());
OS::SNPrintF(buffer, "named_values[%d].isNative()", i);
CHECK(CompileRun(buffer.start())->BooleanValue());
@@ -5834,9 +5922,9 @@ TEST(DebuggerAgent) {
i::Debugger* debugger = i::Isolate::Current()->debugger();
// Make sure these ports is not used by other tests to allow tests to run in
// parallel.
- const int kPort1 = 5858;
- const int kPort2 = 5857;
- const int kPort3 = 5856;
+ const int kPort1 = 5858 + FlagDependentPortOffset();
+ const int kPort2 = 5857 + FlagDependentPortOffset();
+ const int kPort3 = 5856 + FlagDependentPortOffset();
// Make a string with the port2 number.
const int kPortBufferLen = 6;
@@ -5935,7 +6023,7 @@ void DebuggerAgentProtocolServerThread::Run() {
TEST(DebuggerAgentProtocolOverflowHeader) {
// Make sure this port is not used by other tests to allow tests to run in
// parallel.
- const int kPort = 5860;
+ const int kPort = 5860 + FlagDependentPortOffset();
static const char* kLocalhost = "localhost";
// Make a string with the port number.
@@ -7393,4 +7481,51 @@ TEST(Regress131642) {
v8::Debug::SetDebugEventListener(NULL);
}
+
+// Import from test-heap.cc
+int CountNativeContexts();
+
+
+static void NopListener(v8::DebugEvent event,
+ v8::Handle<v8::Object> exec_state,
+ v8::Handle<v8::Object> event_data,
+ v8::Handle<v8::Value> data) {
+}
+
+
+TEST(DebuggerCreatesContextIffActive) {
+ v8::HandleScope scope;
+ DebugLocalContext env;
+ CHECK_EQ(1, CountNativeContexts());
+
+ v8::Debug::SetDebugEventListener(NULL);
+ CompileRun("debugger;");
+ CHECK_EQ(1, CountNativeContexts());
+
+ v8::Debug::SetDebugEventListener(NopListener);
+ CompileRun("debugger;");
+ CHECK_EQ(2, CountNativeContexts());
+
+ v8::Debug::SetDebugEventListener(NULL);
+}
+
+
+TEST(LiveEditEnabled) {
+ v8::internal::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope;
+ LocalContext context;
+ v8::Debug::SetLiveEditEnabled(true);
+ CompileRun("%LiveEditCompareStrings('', '')");
+}
+
+
+TEST(LiveEditDisabled) {
+ v8::internal::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope;
+ LocalContext context;
+ v8::Debug::SetLiveEditEnabled(false);
+ CompileRun("%LiveEditCompareStrings('', '')");
+}
+
+
#endif // ENABLE_DEBUGGER_SUPPORT
diff --git a/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc
index e6bdc9f50..6fc601213 100644
--- a/deps/v8/test/cctest/test-decls.cc
+++ b/deps/v8/test/cctest/test-decls.cc
@@ -37,7 +37,8 @@ using namespace v8;
enum Expectations {
EXPECT_RESULT,
- EXPECT_EXCEPTION
+ EXPECT_EXCEPTION,
+ EXPECT_ERROR
};
@@ -72,6 +73,10 @@ class DeclarationContext {
void InitializeIfNeeded();
+ // Perform optional initialization steps on the context after it has
+ // been created. Defaults to none but may be overwritten.
+ virtual void PostInitializeContext(Handle<Context> context) {}
+
// Get the holder for the interceptor. Default to the instance template
// but may be overwritten.
virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
@@ -91,7 +96,6 @@ class DeclarationContext {
private:
bool is_initialized_;
Persistent<Context> context_;
- Local<String> property_;
int get_count_;
int set_count_;
@@ -120,6 +124,7 @@ void DeclarationContext::InitializeIfNeeded() {
context_ = Context::New(0, function->InstanceTemplate(), Local<Value>());
context_->Enter();
is_initialized_ = true;
+ PostInitializeContext(context_);
}
@@ -134,7 +139,13 @@ void DeclarationContext::Check(const char* source,
HandleScope scope;
TryCatch catcher;
catcher.SetVerbose(true);
- Local<Value> result = Script::Compile(String::New(source))->Run();
+ Local<Script> script = Script::Compile(String::New(source));
+ if (expectations == EXPECT_ERROR) {
+ CHECK(script.IsEmpty());
+ return;
+ }
+ CHECK(!script.IsEmpty());
+ Local<Value> result = script->Run();
CHECK_EQ(get, get_count());
CHECK_EQ(set, set_count());
CHECK_EQ(query, query_count());
@@ -536,9 +547,9 @@ TEST(ExistsInPrototype) {
{ ExistsInPrototypeContext context;
context.Check("var x; x",
- 0, // get
0,
- 0, // declaration
+ 0,
+ 0,
EXPECT_RESULT, Undefined());
}
@@ -546,7 +557,7 @@ TEST(ExistsInPrototype) {
context.Check("var x = 0; x",
0,
0,
- 0, // declaration
+ 0,
EXPECT_RESULT, Number::New(0));
}
@@ -554,7 +565,7 @@ TEST(ExistsInPrototype) {
context.Check("const x; x",
0,
0,
- 0, // declaration
+ 0,
EXPECT_RESULT, Undefined());
}
@@ -562,7 +573,7 @@ TEST(ExistsInPrototype) {
context.Check("const x = 0; x",
0,
0,
- 0, // declaration
+ 0,
EXPECT_RESULT, Number::New(0));
}
}
@@ -591,7 +602,305 @@ TEST(AbsentInPrototype) {
context.Check("if (false) { var x = 0; }; x",
0,
0,
- 0, // declaration
+ 0,
EXPECT_RESULT, Undefined());
}
}
+
+
+
+class ExistsInHiddenPrototypeContext: public DeclarationContext {
+ public:
+ ExistsInHiddenPrototypeContext() {
+ hidden_proto_ = FunctionTemplate::New();
+ hidden_proto_->SetHiddenPrototype(true);
+ }
+
+ protected:
+ virtual v8::Handle<Integer> Query(Local<String> key) {
+ // Let it seem that the property exists in the hidden prototype object.
+ return Integer::New(v8::None);
+ }
+
+ // Install the hidden prototype after the global object has been created.
+ virtual void PostInitializeContext(Handle<Context> context) {
+ Local<Object> global_object = context->Global();
+ Local<Object> hidden_proto = hidden_proto_->GetFunction()->NewInstance();
+ context->DetachGlobal();
+ context->Global()->SetPrototype(hidden_proto);
+ context->ReattachGlobal(global_object);
+ }
+
+ // Use the hidden prototype as the holder for the interceptors.
+ virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
+ return hidden_proto_->InstanceTemplate();
+ }
+
+ private:
+ Local<FunctionTemplate> hidden_proto_;
+};
+
+
+TEST(ExistsInHiddenPrototype) {
+ i::FLAG_es52_globals = true;
+ HandleScope scope;
+
+ { ExistsInHiddenPrototypeContext context;
+ context.Check("var x; x",
+ 1, // access
+ 0,
+ 2, // declaration + initialization
+ EXPECT_EXCEPTION); // x is not defined!
+ }
+
+ { ExistsInHiddenPrototypeContext context;
+ context.Check("var x = 0; x",
+ 1, // access
+ 1, // initialization
+ 2, // declaration + initialization
+ EXPECT_RESULT, Number::New(0));
+ }
+
+ { ExistsInHiddenPrototypeContext context;
+ context.Check("function x() { }; x",
+ 0,
+ 0,
+ 0,
+ EXPECT_RESULT);
+ }
+
+ // TODO(mstarzinger): The semantics of global const is vague.
+ { ExistsInHiddenPrototypeContext context;
+ context.Check("const x; x",
+ 0,
+ 0,
+ 1, // (re-)declaration
+ EXPECT_RESULT, Undefined());
+ }
+
+ // TODO(mstarzinger): The semantics of global const is vague.
+ { ExistsInHiddenPrototypeContext context;
+ context.Check("const x = 0; x",
+ 0,
+ 0,
+ 1, // (re-)declaration
+ EXPECT_RESULT, Number::New(0));
+ }
+}
+
+
+
+class SimpleContext {
+ public:
+ SimpleContext() {
+ context_ = Context::New(0);
+ context_->Enter();
+ }
+
+ virtual ~SimpleContext() {
+ context_->Exit();
+ context_.Dispose();
+ }
+
+ void Check(const char* source,
+ Expectations expectations,
+ v8::Handle<Value> value = Local<Value>()) {
+ HandleScope scope;
+ TryCatch catcher;
+ catcher.SetVerbose(true);
+ Local<Script> script = Script::Compile(String::New(source));
+ if (expectations == EXPECT_ERROR) {
+ CHECK(script.IsEmpty());
+ return;
+ }
+ CHECK(!script.IsEmpty());
+ Local<Value> result = script->Run();
+ if (expectations == EXPECT_RESULT) {
+ CHECK(!catcher.HasCaught());
+ if (!value.IsEmpty()) {
+ CHECK_EQ(value, result);
+ }
+ } else {
+ CHECK(expectations == EXPECT_EXCEPTION);
+ CHECK(catcher.HasCaught());
+ if (!value.IsEmpty()) {
+ CHECK_EQ(value, catcher.Exception());
+ }
+ }
+ }
+
+ private:
+ Persistent<Context> context_;
+};
+
+
+TEST(MultiScriptConflicts) {
+ HandleScope scope;
+
+ { SimpleContext context;
+ context.Check("var x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("var x = 2; x",
+ EXPECT_RESULT, Number::New(2));
+ context.Check("const x = 3; x",
+ EXPECT_RESULT, Number::New(3));
+ context.Check("const x = 4; x",
+ EXPECT_RESULT, Number::New(4));
+ context.Check("x = 5; x",
+ EXPECT_RESULT, Number::New(5));
+ context.Check("var x = 6; x",
+ EXPECT_RESULT, Number::New(6));
+ context.Check("this.x",
+ EXPECT_RESULT, Number::New(6));
+ context.Check("function x() { return 7 }; x()",
+ EXPECT_RESULT, Number::New(7));
+ }
+
+ { SimpleContext context;
+ context.Check("const x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("var x = 2; x", // assignment ignored
+ EXPECT_RESULT, Number::New(1));
+ context.Check("const x = 3; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("x = 4; x", // assignment ignored
+ EXPECT_RESULT, Number::New(1));
+ context.Check("var x = 5; x", // assignment ignored
+ EXPECT_RESULT, Number::New(1));
+ context.Check("this.x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("function x() { return 7 }; x",
+ EXPECT_EXCEPTION);
+ }
+
+ i::FLAG_use_strict = true;
+ i::FLAG_harmony_scoping = true;
+
+ { SimpleContext context;
+ context.Check("var x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("this.x",
+ EXPECT_RESULT, Number::New(1));
+ }
+
+ { SimpleContext context;
+ context.Check("function x() { return 4 }; x()",
+ EXPECT_RESULT, Number::New(4));
+ context.Check("x()",
+ EXPECT_RESULT, Number::New(4));
+ context.Check("this.x()",
+ EXPECT_RESULT, Number::New(4));
+ }
+
+ { SimpleContext context;
+ context.Check("let x = 2; x",
+ EXPECT_RESULT, Number::New(2));
+ context.Check("x",
+ EXPECT_RESULT, Number::New(2));
+ // TODO(rossberg): The current ES6 draft spec does not reflect lexical
+ // bindings on the global object. However, this will probably change, in
+ // which case we reactivate the following test.
+ // context.Check("this.x",
+ // EXPECT_RESULT, Number::New(2));
+ }
+
+ { SimpleContext context;
+ context.Check("const x = 3; x",
+ EXPECT_RESULT, Number::New(3));
+ context.Check("x",
+ EXPECT_RESULT, Number::New(3));
+ // TODO(rossberg): The current ES6 draft spec does not reflect lexical
+ // bindings on the global object. However, this will probably change, in
+ // which case we reactivate the following test.
+ // context.Check("this.x",
+ // EXPECT_RESULT, Number::New(3));
+ }
+
+ // TODO(rossberg): All of the below should actually be errors in Harmony.
+
+ { SimpleContext context;
+ context.Check("var x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("let x = 2; x",
+ EXPECT_RESULT, Number::New(2));
+ }
+
+ { SimpleContext context;
+ context.Check("var x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("const x = 2; x",
+ EXPECT_RESULT, Number::New(2));
+ }
+
+ { SimpleContext context;
+ context.Check("function x() { return 1 }; x()",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("let x = 2; x",
+ EXPECT_RESULT, Number::New(2));
+ }
+
+ { SimpleContext context;
+ context.Check("function x() { return 1 }; x()",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("const x = 2; x",
+ EXPECT_RESULT, Number::New(2));
+ }
+
+ { SimpleContext context;
+ context.Check("let x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("var x = 2; x",
+ EXPECT_ERROR);
+ }
+
+ { SimpleContext context;
+ context.Check("let x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("let x = 2; x",
+ EXPECT_ERROR);
+ }
+
+ { SimpleContext context;
+ context.Check("let x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("const x = 2; x",
+ EXPECT_ERROR);
+ }
+
+ { SimpleContext context;
+ context.Check("let x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("function x() { return 2 }; x()",
+ EXPECT_ERROR);
+ }
+
+ { SimpleContext context;
+ context.Check("const x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("var x = 2; x",
+ EXPECT_ERROR);
+ }
+
+ { SimpleContext context;
+ context.Check("const x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("let x = 2; x",
+ EXPECT_ERROR);
+ }
+
+ { SimpleContext context;
+ context.Check("const x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("const x = 2; x",
+ EXPECT_ERROR);
+ }
+
+ { SimpleContext context;
+ context.Check("const x = 1; x",
+ EXPECT_RESULT, Number::New(1));
+ context.Check("function x() { return 2 }; x()",
+ EXPECT_ERROR);
+ }
+}
diff --git a/deps/v8/test/cctest/test-dictionary.cc b/deps/v8/test/cctest/test-dictionary.cc
index 793e228a9..00e38333f 100644
--- a/deps/v8/test/cctest/test-dictionary.cc
+++ b/deps/v8/test/cctest/test-dictionary.cc
@@ -48,24 +48,24 @@ TEST(ObjectHashTable) {
table = PutIntoObjectHashTable(table, a, b);
CHECK_EQ(table->NumberOfElements(), 1);
CHECK_EQ(table->Lookup(*a), *b);
- CHECK_EQ(table->Lookup(*b), HEAP->undefined_value());
+ CHECK_EQ(table->Lookup(*b), HEAP->the_hole_value());
// Keys still have to be valid after objects were moved.
HEAP->CollectGarbage(NEW_SPACE);
CHECK_EQ(table->NumberOfElements(), 1);
CHECK_EQ(table->Lookup(*a), *b);
- CHECK_EQ(table->Lookup(*b), HEAP->undefined_value());
+ CHECK_EQ(table->Lookup(*b), HEAP->the_hole_value());
// Keys that are overwritten should not change number of elements.
table = PutIntoObjectHashTable(table, a, FACTORY->NewJSArray(13));
CHECK_EQ(table->NumberOfElements(), 1);
CHECK_NE(table->Lookup(*a), *b);
- // Keys mapped to undefined should be removed permanently.
- table = PutIntoObjectHashTable(table, a, FACTORY->undefined_value());
+ // Keys mapped to the hole should be removed permanently.
+ table = PutIntoObjectHashTable(table, a, FACTORY->the_hole_value());
CHECK_EQ(table->NumberOfElements(), 0);
CHECK_EQ(table->NumberOfDeletedElements(), 1);
- CHECK_EQ(table->Lookup(*a), HEAP->undefined_value());
+ CHECK_EQ(table->Lookup(*a), HEAP->the_hole_value());
// Keys should map back to their respective values and also should get
// an identity hash code generated.
@@ -85,7 +85,7 @@ TEST(ObjectHashTable) {
Handle<JSObject> key = FACTORY->NewJSArray(7);
CHECK(key->GetIdentityHash(ALLOW_CREATION)->ToObjectChecked()->IsSmi());
CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound);
- CHECK_EQ(table->Lookup(*key), HEAP->undefined_value());
+ CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value());
CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi());
}
@@ -93,7 +93,7 @@ TEST(ObjectHashTable) {
// should not get an identity hash code generated.
for (int i = 0; i < 100; i++) {
Handle<JSObject> key = FACTORY->NewJSArray(7);
- CHECK_EQ(table->Lookup(*key), HEAP->undefined_value());
+ CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value());
CHECK_EQ(key->GetIdentityHash(OMIT_CREATION), HEAP->undefined_value());
}
}
@@ -105,6 +105,12 @@ TEST(ObjectHashSetCausesGC) {
LocalContext context;
Handle<ObjectHashSet> table = FACTORY->NewObjectHashSet(1);
Handle<JSObject> key = FACTORY->NewJSArray(0);
+ v8::Handle<v8::Object> key_obj = v8::Utils::ToLocal(key);
+
+ // Force allocation of hash table backing store for hidden properties.
+ key_obj->SetHiddenValue(v8_str("key 1"), v8_str("val 1"));
+ key_obj->SetHiddenValue(v8_str("key 2"), v8_str("val 2"));
+ key_obj->SetHiddenValue(v8_str("key 3"), v8_str("val 3"));
// Simulate a full heap so that generating an identity hash code
// in subsequent calls will request GC.
@@ -128,13 +134,19 @@ TEST(ObjectHashTableCausesGC) {
LocalContext context;
Handle<ObjectHashTable> table = FACTORY->NewObjectHashTable(1);
Handle<JSObject> key = FACTORY->NewJSArray(0);
+ v8::Handle<v8::Object> key_obj = v8::Utils::ToLocal(key);
+
+ // Force allocation of hash table backing store for hidden properties.
+ key_obj->SetHiddenValue(v8_str("key 1"), v8_str("val 1"));
+ key_obj->SetHiddenValue(v8_str("key 2"), v8_str("val 2"));
+ key_obj->SetHiddenValue(v8_str("key 3"), v8_str("val 3"));
// Simulate a full heap so that generating an identity hash code
// in subsequent calls will request GC.
FLAG_gc_interval = 0;
// Calling Lookup() should not cause GC ever.
- CHECK(table->Lookup(*key)->IsUndefined());
+ CHECK(table->Lookup(*key)->IsTheHole());
// Calling Put() should request GC by returning a failure.
CHECK(table->Put(*key, *key)->IsRetryAfterGC());
diff --git a/deps/v8/test/cctest/test-flags.cc b/deps/v8/test/cctest/test-flags.cc
index 32f1264f7..9cb12c478 100644
--- a/deps/v8/test/cctest/test-flags.cc
+++ b/deps/v8/test/cctest/test-flags.cc
@@ -159,7 +159,7 @@ TEST(Flags6) {
CHECK_EQ(3, FlagList::SetFlagsFromCommandLine(&argc,
const_cast<char **>(argv),
true));
- CHECK_EQ(4, argc);
+ CHECK_EQ(2, argc);
}
@@ -232,3 +232,16 @@ TEST(FlagsJSArguments4) {
CHECK_EQ(0, FLAG_js_arguments.argc());
}
+
+TEST(FlagsRemoveIncomplete) {
+ // Test that processed command line arguments are removed, even
+ // if the list of arguments ends unexpectedly.
+ SetFlagsToDefault();
+ int argc = 3;
+ const char* argv[] = { "", "--crankshaft", "--expose-debug-as" };
+ CHECK_EQ(2, FlagList::SetFlagsFromCommandLine(&argc,
+ const_cast<char **>(argv),
+ true));
+ CHECK_NE(NULL, argv[1]);
+ CHECK_EQ(argc, 2);
+}
diff --git a/deps/v8/test/cctest/test-func-name-inference.cc b/deps/v8/test/cctest/test-func-name-inference.cc
index 762cc9f0f..cda6aa005 100644
--- a/deps/v8/test/cctest/test-func-name-inference.cc
+++ b/deps/v8/test/cctest/test-func-name-inference.cc
@@ -28,6 +28,7 @@
#include "v8.h"
#include "api.h"
+#include "debug.h"
#include "runtime.h"
#include "cctest.h"
@@ -87,10 +88,10 @@ static void CheckFunctionName(v8::Handle<v8::Script> script,
#ifdef ENABLE_DEBUGGER_SUPPORT
// Obtain SharedFunctionInfo for the function.
+ Isolate::Current()->debug()->PrepareForBreakPoints();
Object* shared_func_info_ptr =
- Runtime::FindSharedFunctionInfoInScript(Isolate::Current(),
- i_script,
- func_pos);
+ Isolate::Current()->debug()->FindSharedFunctionInfoInScript(i_script,
+ func_pos);
CHECK(shared_func_info_ptr != HEAP->undefined_value());
Handle<SharedFunctionInfo> shared_func_info(
SharedFunctionInfo::cast(shared_func_info_ptr));
@@ -398,7 +399,9 @@ TEST(AssignmentAndCall) {
// The inferred name is empty, because this is an assignment of a result.
CheckFunctionName(script, "return 1", "");
// See MultipleAssignments test.
- CheckFunctionName(script, "return 2", "Enclosing.Bar");
+ // TODO(2276): Lazy compiling the enclosing outer closure would yield
+ // in "Enclosing.Bar" being the inferred name here.
+ CheckFunctionName(script, "return 2", "Bar");
}
diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc
index 9d2755ddc..52359711d 100644
--- a/deps/v8/test/cctest/test-heap-profiler.cc
+++ b/deps/v8/test/cctest/test-heap-profiler.cc
@@ -714,9 +714,9 @@ TEST(HeapSnapshotObjectsStats) {
LocalContext env;
v8::HeapProfiler::StartHeapObjectsTracking();
- // We have to call GC 5 times. In other case the garbage will be
+ // We have to call GC 6 times. In other case the garbage will be
// the reason of flakiness.
- for (int i = 0; i < 5; ++i) {
+ for (int i = 0; i < 6; ++i) {
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -1449,6 +1449,36 @@ TEST(FastCaseGetter) {
CHECK_NE(NULL, setterFunction);
}
+TEST(HiddenPropertiesFastCase) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CompileRun(
+ "function C(x) { this.a = this; this.b = x; }\n"
+ "c = new C(2012);\n");
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8_str("HiddenPropertiesFastCase1"));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ const v8::HeapGraphNode* c =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "c");
+ CHECK_NE(NULL, c);
+ const v8::HeapGraphNode* hidden_props =
+ GetProperty(c, v8::HeapGraphEdge::kInternal, "hidden_properties");
+ CHECK_EQ(NULL, hidden_props);
+
+ v8::Handle<v8::Value> cHandle = env->Global()->Get(v8::String::New("c"));
+ CHECK(!cHandle.IsEmpty() && cHandle->IsObject());
+ cHandle->ToObject()->SetHiddenValue(v8_str("key"), v8_str("val"));
+
+ snapshot = v8::HeapProfiler::TakeSnapshot(
+ v8_str("HiddenPropertiesFastCase2"));
+ global = GetGlobalObject(snapshot);
+ c = GetProperty(global, v8::HeapGraphEdge::kProperty, "c");
+ CHECK_NE(NULL, c);
+ hidden_props = GetProperty(c, v8::HeapGraphEdge::kInternal,
+ "hidden_properties");
+ CHECK_NE(NULL, hidden_props);
+}
bool HasWeakEdge(const v8::HeapGraphNode* node) {
for (int i = 0; i < node->GetChildrenCount(); ++i) {
@@ -1491,7 +1521,7 @@ TEST(WeakGlobalHandle) {
}
-TEST(WeakGlobalContextRefs) {
+TEST(WeakNativeContextRefs) {
v8::HandleScope scope;
LocalContext env;
@@ -1503,10 +1533,10 @@ TEST(WeakGlobalContextRefs) {
const v8::HeapGraphNode* global_handles = GetNode(
gc_roots, v8::HeapGraphNode::kObject, "(Global handles)");
CHECK_NE(NULL, global_handles);
- const v8::HeapGraphNode* global_context = GetNode(
- global_handles, v8::HeapGraphNode::kHidden, "system / GlobalContext");
- CHECK_NE(NULL, global_context);
- CHECK(HasWeakEdge(global_context));
+ const v8::HeapGraphNode* native_context = GetNode(
+ global_handles, v8::HeapGraphNode::kHidden, "system / NativeContext");
+ CHECK_NE(NULL, native_context);
+ CHECK(HasWeakEdge(native_context));
}
@@ -1529,6 +1559,7 @@ TEST(SfiAndJsFunctionWeakRefs) {
}
+#ifdef ENABLE_DEBUGGER_SUPPORT
TEST(NoDebugObjectInSnapshot) {
v8::HandleScope scope;
LocalContext env;
@@ -1551,6 +1582,7 @@ TEST(NoDebugObjectInSnapshot) {
}
CHECK_EQ(1, globals_count);
}
+#endif // ENABLE_DEBUGGER_SUPPORT
TEST(PersistentHandleCount) {
@@ -1626,3 +1658,26 @@ TEST(NoRefsToNonEssentialEntries) {
GetProperty(global_object, v8::HeapGraphEdge::kInternal, "elements");
CHECK_EQ(NULL, elements);
}
+
+
+TEST(MapHasDescriptorsAndTransitions) {
+ v8::HandleScope scope;
+ LocalContext env;
+ CompileRun("obj = { a: 10 };\n");
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8_str("snapshot"));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ const v8::HeapGraphNode* global_object =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "obj");
+ CHECK_NE(NULL, global_object);
+
+ const v8::HeapGraphNode* map =
+ GetProperty(global_object, v8::HeapGraphEdge::kInternal, "map");
+ CHECK_NE(NULL, map);
+ const v8::HeapGraphNode* own_descriptors = GetProperty(
+ map, v8::HeapGraphEdge::kInternal, "descriptors");
+ CHECK_NE(NULL, own_descriptors);
+ const v8::HeapGraphNode* own_transitions = GetProperty(
+ map, v8::HeapGraphEdge::kInternal, "transitions");
+ CHECK_EQ(NULL, own_transitions);
+}
diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc
index f8f20ab3c..6927c43b9 100644
--- a/deps/v8/test/cctest/test-heap.cc
+++ b/deps/v8/test/cctest/test-heap.cc
@@ -4,10 +4,12 @@
#include "v8.h"
+#include "compilation-cache.h"
#include "execution.h"
#include "factory.h"
#include "macro-assembler.h"
#include "global-handles.h"
+#include "stub-cache.h"
#include "cctest.h"
using namespace v8::internal;
@@ -157,7 +159,8 @@ TEST(HeapObjects) {
String* object_symbol = String::cast(HEAP->Object_symbol());
CHECK(
- Isolate::Current()->context()->global()->HasLocalProperty(object_symbol));
+ Isolate::Current()->context()->global_object()->HasLocalProperty(
+ object_symbol));
// Check ToString for oddballs
CheckOddball(HEAP->true_value(), "true");
@@ -213,7 +216,7 @@ TEST(GarbageCollection) {
Handle<Map> initial_map =
FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
function->set_initial_map(*initial_map);
- Isolate::Current()->context()->global()->SetProperty(
+ Isolate::Current()->context()->global_object()->SetProperty(
*name, *function, NONE, kNonStrictMode)->ToObjectChecked();
// Allocate an object. Unrooted after leaving the scope.
Handle<JSObject> obj = FACTORY->NewJSObject(function);
@@ -229,9 +232,10 @@ TEST(GarbageCollection) {
HEAP->CollectGarbage(NEW_SPACE);
// Function should be alive.
- CHECK(Isolate::Current()->context()->global()->HasLocalProperty(*name));
+ CHECK(Isolate::Current()->context()->global_object()->
+ HasLocalProperty(*name));
// Check function is retained.
- Object* func_value = Isolate::Current()->context()->global()->
+ Object* func_value = Isolate::Current()->context()->global_object()->
GetProperty(*name)->ToObjectChecked();
CHECK(func_value->IsJSFunction());
Handle<JSFunction> function(JSFunction::cast(func_value));
@@ -240,7 +244,7 @@ TEST(GarbageCollection) {
HandleScope inner_scope;
// Allocate another object, make it reachable from global.
Handle<JSObject> obj = FACTORY->NewJSObject(function);
- Isolate::Current()->context()->global()->SetProperty(
+ Isolate::Current()->context()->global_object()->SetProperty(
*obj_name, *obj, NONE, kNonStrictMode)->ToObjectChecked();
obj->SetProperty(
*prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
@@ -249,10 +253,11 @@ TEST(GarbageCollection) {
// After gc, it should survive.
HEAP->CollectGarbage(NEW_SPACE);
- CHECK(Isolate::Current()->context()->global()->HasLocalProperty(*obj_name));
- CHECK(Isolate::Current()->context()->global()->
+ CHECK(Isolate::Current()->context()->global_object()->
+ HasLocalProperty(*obj_name));
+ CHECK(Isolate::Current()->context()->global_object()->
GetProperty(*obj_name)->ToObjectChecked()->IsJSObject());
- Object* obj = Isolate::Current()->context()->global()->
+ Object* obj = Isolate::Current()->context()->global_object()->
GetProperty(*obj_name)->ToObjectChecked();
JSObject* js_obj = JSObject::cast(obj);
CHECK_EQ(Smi::FromInt(23), js_obj->GetProperty(*prop_name));
@@ -415,6 +420,7 @@ TEST(WeakGlobalHandlesMark) {
global_handles->Destroy(h1.location());
}
+
TEST(DeleteWeakGlobalHandle) {
InitializeVM();
GlobalHandles* global_handles = Isolate::Current()->global_handles();
@@ -445,6 +451,7 @@ TEST(DeleteWeakGlobalHandle) {
CHECK(WeakPointerCleared);
}
+
static const char* not_so_random_string_table[] = {
"abstract",
"boolean",
@@ -561,7 +568,7 @@ TEST(ObjectProperties) {
v8::HandleScope sc;
String* object_symbol = String::cast(HEAP->Object_symbol());
- Object* raw_object = Isolate::Current()->context()->global()->
+ Object* raw_object = Isolate::Current()->context()->global_object()->
GetProperty(object_symbol)->ToObjectChecked();
JSFunction* object_function = JSFunction::cast(raw_object);
Handle<JSFunction> constructor(object_function);
@@ -658,7 +665,7 @@ TEST(JSArray) {
v8::HandleScope sc;
Handle<String> name = FACTORY->LookupAsciiSymbol("Array");
- Object* raw_object = Isolate::Current()->context()->global()->
+ Object* raw_object = Isolate::Current()->context()->global_object()->
GetProperty(*name)->ToObjectChecked();
Handle<JSFunction> function = Handle<JSFunction>(
JSFunction::cast(raw_object));
@@ -705,7 +712,7 @@ TEST(JSObjectCopy) {
v8::HandleScope sc;
String* object_symbol = String::cast(HEAP->Object_symbol());
- Object* raw_object = Isolate::Current()->context()->global()->
+ Object* raw_object = Isolate::Current()->context()->global_object()->
GetProperty(object_symbol)->ToObjectChecked();
JSFunction* object_function = JSFunction::cast(raw_object);
Handle<JSFunction> constructor(object_function);
@@ -874,7 +881,7 @@ TEST(Regression39128) {
// Step 1: prepare a map for the object. We add 1 inobject property to it.
Handle<JSFunction> object_ctor(
- Isolate::Current()->global_context()->object_function());
+ Isolate::Current()->native_context()->object_function());
CHECK(object_ctor->has_initial_map());
Handle<Map> object_map(object_ctor->initial_map());
// Create a map with single inobject property.
@@ -954,7 +961,7 @@ TEST(TestCodeFlushing) {
}
// Check function is compiled.
- Object* func_value = Isolate::Current()->context()->global()->
+ Object* func_value = Isolate::Current()->context()->global_object()->
GetProperty(*foo_name)->ToObjectChecked();
CHECK(func_value->IsJSFunction());
Handle<JSFunction> function(JSFunction::cast(func_value));
@@ -983,10 +990,10 @@ TEST(TestCodeFlushing) {
}
-// Count the number of global contexts in the weak list of global contexts.
-static int CountGlobalContexts() {
+// Count the number of native contexts in the weak list of native contexts.
+int CountNativeContexts() {
int count = 0;
- Object* object = HEAP->global_contexts_list();
+ Object* object = HEAP->native_contexts_list();
while (!object->IsUndefined()) {
count++;
object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK);
@@ -996,7 +1003,7 @@ static int CountGlobalContexts() {
// Count the number of user functions in the weak list of optimized
-// functions attached to a global context.
+// functions attached to a native context.
static int CountOptimizedUserFunctions(v8::Handle<v8::Context> context) {
int count = 0;
Handle<Context> icontext = v8::Utils::OpenHandle(*context);
@@ -1017,7 +1024,7 @@ TEST(TestInternalWeakLists) {
v8::HandleScope scope;
v8::Persistent<v8::Context> ctx[kNumTestContexts];
- CHECK_EQ(0, CountGlobalContexts());
+ CHECK_EQ(0, CountNativeContexts());
// Create a number of global contests which gets linked together.
for (int i = 0; i < kNumTestContexts; i++) {
@@ -1025,7 +1032,7 @@ TEST(TestInternalWeakLists) {
bool opt = (FLAG_always_opt && i::V8::UseCrankshaft());
- CHECK_EQ(i + 1, CountGlobalContexts());
+ CHECK_EQ(i + 1, CountNativeContexts());
ctx[i]->Enter();
@@ -1060,6 +1067,7 @@ TEST(TestInternalWeakLists) {
}
// Mark compact handles the weak references.
+ ISOLATE->compilation_cache()->Clear();
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
@@ -1085,7 +1093,7 @@ TEST(TestInternalWeakLists) {
// Force compilation cache cleanup.
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
- // Dispose the global contexts one by one.
+ // Dispose the native contexts one by one.
for (int i = 0; i < kNumTestContexts; i++) {
ctx[i].Dispose();
ctx[i].Clear();
@@ -1093,23 +1101,23 @@ TEST(TestInternalWeakLists) {
// Scavenge treats these references as strong.
for (int j = 0; j < 10; j++) {
HEAP->PerformScavenge();
- CHECK_EQ(kNumTestContexts - i, CountGlobalContexts());
+ CHECK_EQ(kNumTestContexts - i, CountNativeContexts());
}
// Mark compact handles the weak references.
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
- CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts());
+ CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts());
}
- CHECK_EQ(0, CountGlobalContexts());
+ CHECK_EQ(0, CountNativeContexts());
}
-// Count the number of global contexts in the weak list of global contexts
+// Count the number of native contexts in the weak list of native contexts
// causing a GC after the specified number of elements.
-static int CountGlobalContextsWithGC(int n) {
+static int CountNativeContextsWithGC(int n) {
int count = 0;
- Handle<Object> object(HEAP->global_contexts_list());
+ Handle<Object> object(HEAP->native_contexts_list());
while (!object->IsUndefined()) {
count++;
if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags);
@@ -1121,7 +1129,7 @@ static int CountGlobalContextsWithGC(int n) {
// Count the number of user functions in the weak list of optimized
-// functions attached to a global context causing a GC after the
+// functions attached to a native context causing a GC after the
// specified number of elements.
static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context,
int n) {
@@ -1147,14 +1155,14 @@ TEST(TestInternalWeakListsTraverseWithGC) {
v8::HandleScope scope;
v8::Persistent<v8::Context> ctx[kNumTestContexts];
- CHECK_EQ(0, CountGlobalContexts());
+ CHECK_EQ(0, CountNativeContexts());
// Create an number of contexts and check the length of the weak list both
// with and without GCs while iterating the list.
for (int i = 0; i < kNumTestContexts; i++) {
ctx[i] = v8::Context::New();
- CHECK_EQ(i + 1, CountGlobalContexts());
- CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1));
+ CHECK_EQ(i + 1, CountNativeContexts());
+ CHECK_EQ(i + 1, CountNativeContextsWithGC(i / 2 + 1));
}
bool opt = (FLAG_always_opt && i::V8::UseCrankshaft());
@@ -1198,6 +1206,7 @@ TEST(TestSizeOfObjects) {
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
CHECK(HEAP->old_pointer_space()->IsSweepingComplete());
int initial_size = static_cast<int>(HEAP->SizeOfObjects());
@@ -1238,7 +1247,9 @@ TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
for (HeapObject* obj = iterator.next();
obj != NULL;
obj = iterator.next()) {
- size_of_objects_2 += obj->Size();
+ if (!obj->IsFreeSpace()) {
+ size_of_objects_2 += obj->Size();
+ }
}
// Delta must be within 5% of the larger result.
// TODO(gc): Tighten this up by distinguishing between byte
@@ -1279,7 +1290,8 @@ TEST(GrowAndShrinkNewSpace) {
InitializeVM();
NewSpace* new_space = HEAP->new_space();
- if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) {
+ if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize() ||
+ HEAP->MaxSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) {
// The max size cannot exceed the reserved size, since semispaces must be
// always within the reserved space. We can't test new space growing and
// shrinking if the reserved size is the same as the minimum (initial) size.
@@ -1327,7 +1339,8 @@ TEST(GrowAndShrinkNewSpace) {
TEST(CollectingAllAvailableGarbageShrinksNewSpace) {
InitializeVM();
- if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) {
+ if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize() ||
+ HEAP->MaxSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) {
// The max size cannot exceed the reserved size, since semispaces must be
// always within the reserved space. We can't test new space growing and
// shrinking if the reserved size is the same as the minimum (initial) size.
@@ -1360,7 +1373,7 @@ static int NumberOfGlobalObjects() {
// Test that we don't embed maps from foreign contexts into
// optimized code.
-TEST(LeakGlobalContextViaMap) {
+TEST(LeakNativeContextViaMap) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope outer_scope;
v8::Persistent<v8::Context> ctx1 = v8::Context::New();
@@ -1386,6 +1399,7 @@ TEST(LeakGlobalContextViaMap) {
ctx2->Exit();
ctx1->Exit();
ctx1.Dispose();
+ v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
@@ -1397,7 +1411,7 @@ TEST(LeakGlobalContextViaMap) {
// Test that we don't embed functions from foreign contexts into
// optimized code.
-TEST(LeakGlobalContextViaFunction) {
+TEST(LeakNativeContextViaFunction) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope outer_scope;
v8::Persistent<v8::Context> ctx1 = v8::Context::New();
@@ -1423,6 +1437,7 @@ TEST(LeakGlobalContextViaFunction) {
ctx2->Exit();
ctx1->Exit();
ctx1.Dispose();
+ v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
@@ -1432,7 +1447,7 @@ TEST(LeakGlobalContextViaFunction) {
}
-TEST(LeakGlobalContextViaMapKeyed) {
+TEST(LeakNativeContextViaMapKeyed) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope outer_scope;
v8::Persistent<v8::Context> ctx1 = v8::Context::New();
@@ -1458,6 +1473,7 @@ TEST(LeakGlobalContextViaMapKeyed) {
ctx2->Exit();
ctx1->Exit();
ctx1.Dispose();
+ v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
@@ -1467,7 +1483,7 @@ TEST(LeakGlobalContextViaMapKeyed) {
}
-TEST(LeakGlobalContextViaMapProto) {
+TEST(LeakNativeContextViaMapProto) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope outer_scope;
v8::Persistent<v8::Context> ctx1 = v8::Context::New();
@@ -1497,6 +1513,7 @@ TEST(LeakGlobalContextViaMapProto) {
ctx2->Exit();
ctx1->Exit();
ctx1.Dispose();
+ v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
@@ -1508,9 +1525,10 @@ TEST(LeakGlobalContextViaMapProto) {
TEST(InstanceOfStubWriteBarrier) {
i::FLAG_allow_natives_syntax = true;
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
i::FLAG_verify_heap = true;
#endif
+
InitializeVM();
if (!i::V8::UseCrankshaft()) return;
v8::HandleScope outer_scope;
@@ -1586,7 +1604,7 @@ TEST(PrototypeTransitionClearing) {
CHECK_EQ(transitions, baseObject->map()->NumberOfProtoTransitions());
// Verify that prototype transitions array was compacted.
- FixedArray* trans = baseObject->map()->prototype_transitions();
+ FixedArray* trans = baseObject->map()->GetPrototypeTransitions();
for (int i = 0; i < transitions; i++) {
int j = Map::kProtoTransitionHeaderSize +
i * Map::kProtoTransitionElementsPerEntry;
@@ -1607,7 +1625,8 @@ TEST(PrototypeTransitionClearing) {
// clearing correctly records slots in prototype transition array.
i::FLAG_always_compact = true;
Handle<Map> map(baseObject->map());
- CHECK(!space->LastPage()->Contains(map->prototype_transitions()->address()));
+ CHECK(!space->LastPage()->Contains(
+ map->GetPrototypeTransitions()->address()));
CHECK(space->LastPage()->Contains(prototype->address()));
baseObject->SetPrototype(*prototype, false)->ToObjectChecked();
CHECK(map->GetPrototypeTransition(*prototype)->IsMap());
@@ -1618,9 +1637,10 @@ TEST(PrototypeTransitionClearing) {
TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
i::FLAG_allow_natives_syntax = true;
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
i::FLAG_verify_heap = true;
#endif
+
InitializeVM();
if (!i::V8::UseCrankshaft()) return;
v8::HandleScope outer_scope;
@@ -1673,9 +1693,10 @@ TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) {
i::FLAG_allow_natives_syntax = true;
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
i::FLAG_verify_heap = true;
#endif
+
InitializeVM();
if (!i::V8::UseCrankshaft()) return;
v8::HandleScope outer_scope;
@@ -1742,14 +1763,20 @@ TEST(OptimizedAllocationAlwaysInNewSpace) {
static int CountMapTransitions(Map* map) {
- int result = 0;
- DescriptorArray* descs = map->instance_descriptors();
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
- if (descs->IsTransitionOnly(i)) {
- result++;
- }
+ return map->transitions()->number_of_transitions();
+}
+
+
+// Go through all incremental marking steps in one swoop.
+static void SimulateIncrementalMarking() {
+ IncrementalMarking* marking = HEAP->incremental_marking();
+ CHECK(marking->IsStopped());
+ marking->Start();
+ CHECK(marking->IsMarking());
+ while (!marking->IsComplete()) {
+ marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
}
- return result;
+ CHECK(marking->IsComplete());
}
@@ -1760,14 +1787,18 @@ TEST(Regress1465) {
i::FLAG_trace_incremental_marking = true;
InitializeVM();
v8::HandleScope scope;
+ static const int transitions_count = 256;
- #define TRANSITION_COUNT 256
- for (int i = 0; i < TRANSITION_COUNT; i++) {
- EmbeddedVector<char, 64> buffer;
- OS::SNPrintF(buffer, "var o = new Object; o.prop%d = %d;", i, i);
- CompileRun(buffer.start());
+ {
+ AlwaysAllocateScope always_allocate;
+ for (int i = 0; i < transitions_count; i++) {
+ EmbeddedVector<char, 64> buffer;
+ OS::SNPrintF(buffer, "var o = new Object; o.prop%d = %d;", i, i);
+ CompileRun(buffer.start());
+ }
+ CompileRun("var root = new Object;");
}
- CompileRun("var root = new Object;");
+
Handle<JSObject> root =
v8::Utils::OpenHandle(
*v8::Handle<v8::Object>::Cast(
@@ -1776,19 +1807,10 @@ TEST(Regress1465) {
// Count number of live transitions before marking.
int transitions_before = CountMapTransitions(root->map());
CompileRun("%DebugPrint(root);");
- CHECK_EQ(TRANSITION_COUNT, transitions_before);
+ CHECK_EQ(transitions_count, transitions_before);
- // Go through all incremental marking steps in one swoop.
- IncrementalMarking* marking = HEAP->incremental_marking();
- CHECK(marking->IsStopped());
- marking->Start();
- CHECK(marking->IsMarking());
- while (!marking->IsComplete()) {
- marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
- }
- CHECK(marking->IsComplete());
+ SimulateIncrementalMarking();
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
- CHECK(marking->IsStopped());
// Count number of live transitions after marking. Note that one transition
// is left, because 'o' still holds an instance of one transition target.
@@ -1810,15 +1832,7 @@ TEST(Regress2143a) {
"root.foo = 0;"
"root = new Object;");
- // Go through all incremental marking steps in one swoop.
- IncrementalMarking* marking = HEAP->incremental_marking();
- CHECK(marking->IsStopped());
- marking->Start();
- CHECK(marking->IsMarking());
- while (!marking->IsComplete()) {
- marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
- }
- CHECK(marking->IsComplete());
+ SimulateIncrementalMarking();
// Compile a StoreIC that performs the prepared map transition. This
// will restart incremental marking and should make sure the root is
@@ -1834,7 +1848,6 @@ TEST(Regress2143a) {
// Explicitly request GC to perform final marking step and sweeping.
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
- CHECK(marking->IsStopped());
Handle<JSObject> root =
v8::Utils::OpenHandle(
@@ -1860,15 +1873,7 @@ TEST(Regress2143b) {
"root.foo = 0;"
"root = new Object;");
- // Go through all incremental marking steps in one swoop.
- IncrementalMarking* marking = HEAP->incremental_marking();
- CHECK(marking->IsStopped());
- marking->Start();
- CHECK(marking->IsMarking());
- while (!marking->IsComplete()) {
- marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
- }
- CHECK(marking->IsComplete());
+ SimulateIncrementalMarking();
// Compile an optimized LStoreNamedField that performs the prepared
// map transition. This will restart incremental marking and should
@@ -1887,7 +1892,6 @@ TEST(Regress2143b) {
// Explicitly request GC to perform final marking step and sweeping.
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
- CHECK(marking->IsStopped());
Handle<JSObject> root =
v8::Utils::OpenHandle(
@@ -1906,6 +1910,9 @@ void SimulateFullSpace(PagedSpace* space);
TEST(ReleaseOverReservedPages) {
i::FLAG_trace_gc = true;
+ // The optimizer can allocate stuff, messing up the test.
+ i::FLAG_crankshaft = false;
+ i::FLAG_always_opt = false;
InitializeVM();
v8::HandleScope scope;
static const int number_of_test_pages = 20;
@@ -1932,8 +1939,375 @@ TEST(ReleaseOverReservedPages) {
HEAP->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 2");
CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages() * 2);
- // Triggering a last-resort GC should cause all pages to be released
- // to the OS so that other processes can seize the memory.
+ // Triggering a last-resort GC should cause all pages to be released to the
+ // OS so that other processes can seize the memory. If we get a failure here
+ // where there are 2 pages left instead of 1, then we should increase the
+ // size of the first page a little in SizeOfFirstPage in spaces.cc. The
+ // first page should be small in order to reduce memory used when the VM
+ // boots, but if the 20 small arrays don't fit on the first page then that's
+ // an indication that it is too small.
HEAP->CollectAllAvailableGarbage("triggered really hard");
CHECK_EQ(1, old_pointer_space->CountTotalPages());
}
+
+
+TEST(Regress2237) {
+ InitializeVM();
+ v8::HandleScope scope;
+ Handle<String> slice(HEAP->empty_string());
+
+ {
+ // Generate a parent that lives in new-space.
+ v8::HandleScope inner_scope;
+ const char* c = "This text is long enough to trigger sliced strings.";
+ Handle<String> s = FACTORY->NewStringFromAscii(CStrVector(c));
+ CHECK(s->IsSeqAsciiString());
+ CHECK(HEAP->InNewSpace(*s));
+
+ // Generate a sliced string that is based on the above parent and
+ // lives in old-space.
+ FillUpNewSpace(HEAP->new_space());
+ AlwaysAllocateScope always_allocate;
+ Handle<String> t;
+ // TODO(mstarzinger): Unfortunately FillUpNewSpace() still leaves
+ // some slack, so we need to allocate a few sliced strings.
+ for (int i = 0; i < 16; i++) {
+ t = FACTORY->NewProperSubString(s, 5, 35);
+ }
+ CHECK(t->IsSlicedString());
+ CHECK(!HEAP->InNewSpace(*t));
+ *slice.location() = *t.location();
+ }
+
+ CHECK(SlicedString::cast(*slice)->parent()->IsSeqAsciiString());
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ CHECK(SlicedString::cast(*slice)->parent()->IsSeqAsciiString());
+}
+
+
+#ifdef OBJECT_PRINT
+TEST(PrintSharedFunctionInfo) {
+ InitializeVM();
+ v8::HandleScope scope;
+ const char* source = "f = function() { return 987654321; }\n"
+ "g = function() { return 123456789; }\n";
+ CompileRun(source);
+ Handle<JSFunction> g =
+ v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(
+ v8::Context::GetCurrent()->Global()->Get(v8_str("g"))));
+
+ AssertNoAllocation no_alloc;
+ g->shared()->PrintLn();
+}
+#endif // OBJECT_PRINT
+
+
+TEST(Regress2211) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ v8::Handle<v8::String> value = v8_str("val string");
+ Smi* hash = Smi::FromInt(321);
+ Heap* heap = Isolate::Current()->heap();
+
+ for (int i = 0; i < 2; i++) {
+ // Store identity hash first and common hidden property second.
+ v8::Handle<v8::Object> obj = v8::Object::New();
+ Handle<JSObject> internal_obj = v8::Utils::OpenHandle(*obj);
+ CHECK(internal_obj->HasFastProperties());
+
+ // In the first iteration, set hidden value first and identity hash second.
+ // In the second iteration, reverse the order.
+ if (i == 0) obj->SetHiddenValue(v8_str("key string"), value);
+ MaybeObject* maybe_obj = internal_obj->SetIdentityHash(hash,
+ ALLOW_CREATION);
+ CHECK(!maybe_obj->IsFailure());
+ if (i == 1) obj->SetHiddenValue(v8_str("key string"), value);
+
+ // Check values.
+ CHECK_EQ(hash,
+ internal_obj->GetHiddenProperty(heap->identity_hash_symbol()));
+ CHECK(value->Equals(obj->GetHiddenValue(v8_str("key string"))));
+
+ // Check size.
+ DescriptorArray* descriptors = internal_obj->map()->instance_descriptors();
+ ObjectHashTable* hashtable = ObjectHashTable::cast(
+ internal_obj->FastPropertyAt(descriptors->GetFieldIndex(0)));
+ // HashTable header (5) and 4 initial entries (8).
+ CHECK_LE(hashtable->SizeFor(hashtable->length()), 13 * kPointerSize);
+ }
+}
+
+
+TEST(IncrementalMarkingClearsTypeFeedbackCells) {
+ if (i::FLAG_always_opt) return;
+ InitializeVM();
+ v8::HandleScope scope;
+ v8::Local<v8::Value> fun1, fun2;
+
+ {
+ LocalContext env;
+ CompileRun("function fun() {};");
+ fun1 = env->Global()->Get(v8_str("fun"));
+ }
+
+ {
+ LocalContext env;
+ CompileRun("function fun() {};");
+ fun2 = env->Global()->Get(v8_str("fun"));
+ }
+
+ // Prepare function f that contains type feedback for closures
+ // originating from two different native contexts.
+ v8::Context::GetCurrent()->Global()->Set(v8_str("fun1"), fun1);
+ v8::Context::GetCurrent()->Global()->Set(v8_str("fun2"), fun2);
+ CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);");
+ Handle<JSFunction> f =
+ v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(
+ v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+ Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast(
+ f->shared()->code()->type_feedback_info())->type_feedback_cells());
+
+ CHECK_EQ(2, cells->CellCount());
+ CHECK(cells->Cell(0)->value()->IsJSFunction());
+ CHECK(cells->Cell(1)->value()->IsJSFunction());
+
+ SimulateIncrementalMarking();
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+
+ CHECK_EQ(2, cells->CellCount());
+ CHECK(cells->Cell(0)->value()->IsTheHole());
+ CHECK(cells->Cell(1)->value()->IsTheHole());
+}
+
+
+static Code* FindFirstIC(Code* code, Code::Kind kind) {
+ int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
+ RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) |
+ RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) |
+ RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT);
+ for (RelocIterator it(code, mask); !it.done(); it.next()) {
+ RelocInfo* info = it.rinfo();
+ Code* target = Code::GetCodeFromTargetAddress(info->target_address());
+ if (target->is_inline_cache_stub() && target->kind() == kind) {
+ return target;
+ }
+ }
+ return NULL;
+}
+
+
+TEST(IncrementalMarkingPreservesMonomorhpicIC) {
+ if (i::FLAG_always_opt) return;
+ InitializeVM();
+ v8::HandleScope scope;
+
+ // Prepare function f that contains a monomorphic IC for object
+ // originating from the same native context.
+ CompileRun("function fun() { this.x = 1; }; var obj = new fun();"
+ "function f(o) { return o.x; } f(obj); f(obj);");
+ Handle<JSFunction> f =
+ v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(
+ v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+
+ Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
+ CHECK(ic_before->ic_state() == MONOMORPHIC);
+
+ SimulateIncrementalMarking();
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+
+ Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
+ CHECK(ic_after->ic_state() == MONOMORPHIC);
+}
+
+
+TEST(IncrementalMarkingClearsMonomorhpicIC) {
+ if (i::FLAG_always_opt) return;
+ InitializeVM();
+ v8::HandleScope scope;
+ v8::Local<v8::Value> obj1;
+
+ {
+ LocalContext env;
+ CompileRun("function fun() { this.x = 1; }; var obj = new fun();");
+ obj1 = env->Global()->Get(v8_str("obj"));
+ }
+
+ // Prepare function f that contains a monomorphic IC for object
+ // originating from a different native context.
+ v8::Context::GetCurrent()->Global()->Set(v8_str("obj1"), obj1);
+ CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);");
+ Handle<JSFunction> f =
+ v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(
+ v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+
+ Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
+ CHECK(ic_before->ic_state() == MONOMORPHIC);
+
+ // Fire context dispose notification.
+ v8::V8::ContextDisposedNotification();
+ SimulateIncrementalMarking();
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+
+ Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
+ CHECK(ic_after->ic_state() == UNINITIALIZED);
+}
+
+
+TEST(IncrementalMarkingClearsPolymorhpicIC) {
+ if (i::FLAG_always_opt) return;
+ InitializeVM();
+ v8::HandleScope scope;
+ v8::Local<v8::Value> obj1, obj2;
+
+ {
+ LocalContext env;
+ CompileRun("function fun() { this.x = 1; }; var obj = new fun();");
+ obj1 = env->Global()->Get(v8_str("obj"));
+ }
+
+ {
+ LocalContext env;
+ CompileRun("function fun() { this.x = 2; }; var obj = new fun();");
+ obj2 = env->Global()->Get(v8_str("obj"));
+ }
+
+ // Prepare function f that contains a polymorphic IC for objects
+ // originating from two different native contexts.
+ v8::Context::GetCurrent()->Global()->Set(v8_str("obj1"), obj1);
+ v8::Context::GetCurrent()->Global()->Set(v8_str("obj2"), obj2);
+ CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);");
+ Handle<JSFunction> f =
+ v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(
+ v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+
+ Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
+ CHECK(ic_before->ic_state() == MEGAMORPHIC);
+
+ // Fire context dispose notification.
+ v8::V8::ContextDisposedNotification();
+ SimulateIncrementalMarking();
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+
+ Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
+ CHECK(ic_after->ic_state() == UNINITIALIZED);
+}
+
+
+class SourceResource: public v8::String::ExternalAsciiStringResource {
+ public:
+ explicit SourceResource(const char* data)
+ : data_(data), length_(strlen(data)) { }
+
+ virtual void Dispose() {
+ i::DeleteArray(data_);
+ data_ = NULL;
+ }
+
+ const char* data() const { return data_; }
+
+ size_t length() const { return length_; }
+
+ bool IsDisposed() { return data_ == NULL; }
+
+ private:
+ const char* data_;
+ size_t length_;
+};
+
+
+TEST(ReleaseStackTraceData) {
+ // Test that the data retained by the Error.stack accessor is released
+ // after the first time the accessor is fired. We use external string
+ // to check whether the data is being released since the external string
+ // resource's callback is fired when the external string is GC'ed.
+ InitializeVM();
+ v8::HandleScope scope;
+ static const char* source = "var error = 1; "
+ "try { "
+ " throw new Error(); "
+ "} catch (e) { "
+ " error = e; "
+ "} ";
+ SourceResource* resource = new SourceResource(i::StrDup(source));
+ {
+ v8::HandleScope scope;
+ v8::Handle<v8::String> source_string = v8::String::NewExternal(resource);
+ v8::Script::Compile(source_string)->Run();
+ CHECK(!resource->IsDisposed());
+ }
+ HEAP->CollectAllAvailableGarbage();
+ // External source is being retained by the stack trace.
+ CHECK(!resource->IsDisposed());
+
+ CompileRun("error.stack; error.stack;");
+ HEAP->CollectAllAvailableGarbage();
+ // External source has been released.
+ CHECK(resource->IsDisposed());
+
+ delete resource;
+}
+
+
+TEST(Regression144230) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ // First make sure that the uninitialized CallIC stub is on a single page
+ // that will later be selected as an evacuation candidate.
+ {
+ v8::HandleScope inner_scope;
+ AlwaysAllocateScope always_allocate;
+ SimulateFullSpace(HEAP->code_space());
+ ISOLATE->stub_cache()->ComputeCallInitialize(9, RelocInfo::CODE_TARGET);
+ }
+
+ // Second compile a CallIC and execute it once so that it gets patched to
+ // the pre-monomorphic stub. These code objects are on yet another page.
+ {
+ v8::HandleScope inner_scope;
+ AlwaysAllocateScope always_allocate;
+ SimulateFullSpace(HEAP->code_space());
+ CompileRun("var o = { f:function(a,b,c,d,e,f,g,h,i) {}};"
+ "function call() { o.f(1,2,3,4,5,6,7,8,9); };"
+ "call();");
+ }
+
+ // Third we fill up the last page of the code space so that it does not get
+ // chosen as an evacuation candidate.
+ {
+ v8::HandleScope inner_scope;
+ AlwaysAllocateScope always_allocate;
+ CompileRun("for (var i = 0; i < 2000; i++) {"
+ " eval('function f' + i + '() { return ' + i +'; };' +"
+ " 'f' + i + '();');"
+ "}");
+ }
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+
+ // Fourth is the tricky part. Make sure the code containing the CallIC is
+ // visited first without clearing the IC. The shared function info is then
+ // visited later, causing the CallIC to be cleared.
+ Handle<String> name = FACTORY->LookupAsciiSymbol("call");
+ Handle<GlobalObject> global(ISOLATE->context()->global_object());
+ MaybeObject* maybe_call = global->GetProperty(*name);
+ JSFunction* call = JSFunction::cast(maybe_call->ToObjectChecked());
+ USE(global->SetProperty(*name, Smi::FromInt(0), NONE, kNonStrictMode));
+ ISOLATE->compilation_cache()->Clear();
+ call->shared()->set_ic_age(HEAP->global_ic_age() + 1);
+ Handle<Object> call_code(call->code());
+ Handle<Object> call_function(call);
+
+ // Now we are ready to mess up the heap.
+ HEAP->CollectAllGarbage(Heap::kReduceMemoryFootprintMask);
+
+ // Either heap verification caught the problem already or we go kaboom once
+ // the CallIC is executed the next time.
+ USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode));
+ CompileRun("call();");
+}
diff --git a/deps/v8/test/cctest/test-liveedit.cc b/deps/v8/test/cctest/test-liveedit.cc
index 013de026f..2c89a387d 100644
--- a/deps/v8/test/cctest/test-liveedit.cc
+++ b/deps/v8/test/cctest/test-liveedit.cc
@@ -81,8 +81,8 @@ class ListDiffOutputWriter : public Comparator::Output {
(*next_chunk_pointer_) = NULL;
}
void AddChunk(int pos1, int pos2, int len1, int len2) {
- current_chunk_ =
- new(Isolate::Current()->zone()) DiffChunkStruct(pos1, pos2, len1, len2);
+ current_chunk_ = new(Isolate::Current()->runtime_zone()) DiffChunkStruct(
+ pos1, pos2, len1, len2);
(*next_chunk_pointer_) = current_chunk_;
next_chunk_pointer_ = &current_chunk_->next;
}
@@ -96,7 +96,7 @@ void CompareStringsOneWay(const char* s1, const char* s2,
int expected_diff_parameter = -1) {
StringCompareInput input(s1, s2);
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
DiffChunkStruct* first_chunk;
ListDiffOutputWriter writer(&first_chunk);
diff --git a/deps/v8/test/cctest/test-mark-compact.cc b/deps/v8/test/cctest/test-mark-compact.cc
index 27123704b..c0ab763a2 100644
--- a/deps/v8/test/cctest/test-mark-compact.cc
+++ b/deps/v8/test/cctest/test-mark-compact.cc
@@ -194,7 +194,7 @@ TEST(MarkCompactCollector) {
Map::cast(HEAP->AllocateMap(JS_OBJECT_TYPE,
JSObject::kHeaderSize)->ToObjectChecked());
function->set_initial_map(initial_map);
- Isolate::Current()->context()->global()->SetProperty(
+ Isolate::Current()->context()->global_object()->SetProperty(
func_name, function, NONE, kNonStrictMode)->ToObjectChecked();
JSObject* obj = JSObject::cast(
@@ -203,8 +203,9 @@ TEST(MarkCompactCollector) {
func_name =
String::cast(HEAP->LookupAsciiSymbol("theFunction")->ToObjectChecked());
- CHECK(Isolate::Current()->context()->global()->HasLocalProperty(func_name));
- Object* func_value = Isolate::Current()->context()->global()->
+ CHECK(Isolate::Current()->context()->global_object()->
+ HasLocalProperty(func_name));
+ Object* func_value = Isolate::Current()->context()->global_object()->
GetProperty(func_name)->ToObjectChecked();
CHECK(func_value->IsJSFunction());
function = JSFunction::cast(func_value);
@@ -212,7 +213,7 @@ TEST(MarkCompactCollector) {
obj = JSObject::cast(HEAP->AllocateJSObject(function)->ToObjectChecked());
String* obj_name =
String::cast(HEAP->LookupAsciiSymbol("theObject")->ToObjectChecked());
- Isolate::Current()->context()->global()->SetProperty(
+ Isolate::Current()->context()->global_object()->SetProperty(
obj_name, obj, NONE, kNonStrictMode)->ToObjectChecked();
String* prop_name =
String::cast(HEAP->LookupAsciiSymbol("theSlot")->ToObjectChecked());
@@ -225,10 +226,11 @@ TEST(MarkCompactCollector) {
obj_name =
String::cast(HEAP->LookupAsciiSymbol("theObject")->ToObjectChecked());
- CHECK(Isolate::Current()->context()->global()->HasLocalProperty(obj_name));
- CHECK(Isolate::Current()->context()->global()->
+ CHECK(Isolate::Current()->context()->global_object()->
+ HasLocalProperty(obj_name));
+ CHECK(Isolate::Current()->context()->global_object()->
GetProperty(obj_name)->ToObjectChecked()->IsJSObject());
- obj = JSObject::cast(Isolate::Current()->context()->global()->
+ obj = JSObject::cast(Isolate::Current()->context()->global_object()->
GetProperty(obj_name)->ToObjectChecked());
prop_name =
String::cast(HEAP->LookupAsciiSymbol("theSlot")->ToObjectChecked());
@@ -526,7 +528,10 @@ static intptr_t MemoryInUse() {
TEST(BootUpMemoryUse) {
intptr_t initial_memory = MemoryInUse();
- FLAG_crankshaft = false; // Avoid flakiness.
+ // Avoid flakiness.
+ FLAG_crankshaft = false;
+ FLAG_parallel_recompilation = false;
+
// Only Linux has the proc filesystem and only if it is mapped. If it's not
// there we just skip the test.
if (initial_memory >= 0) {
@@ -540,9 +545,9 @@ TEST(BootUpMemoryUse) {
}
} else {
if (v8::internal::Snapshot::IsEnabled()) {
- CHECK_LE(delta, 2600 * 1024); // 2484.
+ CHECK_LE(delta, 2500 * 1024); // 2400.
} else {
- CHECK_LE(delta, 2950 * 1024); // 2844
+ CHECK_LE(delta, 2860 * 1024); // 2760.
}
}
}
diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc
index b9123f01f..717c66519 100755
--- a/deps/v8/test/cctest/test-parsing.cc
+++ b/deps/v8/test/cctest/test-parsing.cc
@@ -354,7 +354,8 @@ TEST(Regress928) {
v8::HandleScope handles;
i::Handle<i::String> source(
FACTORY->NewStringFromAscii(i::CStrVector(program)));
- i::ScriptDataImpl* data = i::ParserApi::PartialPreParse(source, NULL, false);
+ i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
+ i::ScriptDataImpl* data = i::ParserApi::PreParse(&stream, NULL, false);
CHECK(!data->HasError());
data->Initialize();
@@ -1016,12 +1017,11 @@ TEST(ScopePositions) {
FACTORY->NewStringFromUtf8(i::CStrVector(program.start())));
CHECK_EQ(source->length(), kProgramSize);
i::Handle<i::Script> script = FACTORY->NewScript(source);
- i::Parser parser(script, i::kAllowLazy | i::EXTENDED_MODE, NULL, NULL,
- i::Isolate::Current()->zone());
- i::CompilationInfo info(script);
+ i::CompilationInfoWithZone info(script);
+ i::Parser parser(&info, i::kAllowLazy | i::EXTENDED_MODE, NULL, NULL);
info.MarkAsGlobal();
info.SetLanguageMode(source_data[i].language_mode);
- i::FunctionLiteral* function = parser.ParseProgram(&info);
+ i::FunctionLiteral* function = parser.ParseProgram();
CHECK(function != NULL);
// Check scope types and positions.
@@ -1061,10 +1061,10 @@ void TestParserSync(i::Handle<i::String> source, int flags) {
i::Handle<i::Script> script = FACTORY->NewScript(source);
bool save_harmony_scoping = i::FLAG_harmony_scoping;
i::FLAG_harmony_scoping = harmony_scoping;
- i::Parser parser(script, flags, NULL, NULL, i::Isolate::Current()->zone());
- i::CompilationInfo info(script);
+ i::CompilationInfoWithZone info(script);
+ i::Parser parser(&info, flags, NULL, NULL);
info.MarkAsGlobal();
- i::FunctionLiteral* function = parser.ParseProgram(&info);
+ i::FunctionLiteral* function = parser.ParseProgram();
i::FLAG_harmony_scoping = save_harmony_scoping;
i::String* type_string = NULL;
@@ -1148,6 +1148,7 @@ TEST(ParserSync) {
{ "with ({})", "" },
{ "switch (12) { case 12: ", "}" },
{ "switch (12) { default: ", "}" },
+ { "switch (12) { ", "case 12: }" },
{ "label2: ", "" },
{ NULL, NULL }
};
@@ -1237,3 +1238,26 @@ TEST(ParserSync) {
}
}
}
+
+
+TEST(PreparserStrictOctal) {
+ // Test that syntax error caused by octal literal is reported correctly as
+ // such (issue 2220).
+ v8::internal::FLAG_min_preparse_length = 1; // Force preparsing.
+ v8::V8::Initialize();
+ v8::HandleScope scope;
+ v8::Context::Scope context_scope(v8::Context::New());
+ v8::TryCatch try_catch;
+ const char* script =
+ "\"use strict\"; \n"
+ "a = function() { \n"
+ " b = function() { \n"
+ " 01; \n"
+ " }; \n"
+ "}; \n";
+ v8::Script::Compile(v8::String::New(script));
+ CHECK(try_catch.HasCaught());
+ v8::String::Utf8Value exception(try_catch.Exception());
+ CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.",
+ *exception);
+}
diff --git a/deps/v8/test/cctest/test-platform-linux.cc b/deps/v8/test/cctest/test-platform-linux.cc
index 2a8d49785..47b99f084 100644
--- a/deps/v8/test/cctest/test-platform-linux.cc
+++ b/deps/v8/test/cctest/test-platform-linux.cc
@@ -79,3 +79,9 @@ TEST(VirtualMemory) {
CHECK(vm->Uncommit(block_addr, block_size));
delete vm;
}
+
+
+TEST(GetCurrentProcessId) {
+ OS::SetUp();
+ CHECK_EQ(static_cast<int>(getpid()), OS::GetCurrentProcessId());
+}
diff --git a/deps/v8/test/cctest/test-platform-win32.cc b/deps/v8/test/cctest/test-platform-win32.cc
index 36b30aace..668ccdb0e 100644
--- a/deps/v8/test/cctest/test-platform-win32.cc
+++ b/deps/v8/test/cctest/test-platform-win32.cc
@@ -25,3 +25,10 @@ TEST(VirtualMemory) {
CHECK(vm->Uncommit(block_addr, block_size));
delete vm;
}
+
+
+TEST(GetCurrentProcessId) {
+ OS::SetUp();
+ CHECK_EQ(static_cast<int>(::GetCurrentProcessId()),
+ OS::GetCurrentProcessId());
+}
diff --git a/deps/v8/test/cctest/test-random.cc b/deps/v8/test/cctest/test-random.cc
index a1f49318f..86d6d8c14 100644
--- a/deps/v8/test/cctest/test-random.cc
+++ b/deps/v8/test/cctest/test-random.cc
@@ -52,7 +52,7 @@ void TestSeeds(Handle<JSFunction> fun,
uint32_t state0,
uint32_t state1) {
bool has_pending_exception;
- Handle<JSObject> global(context->global());
+ Handle<JSObject> global(context->global_object());
Handle<ByteArray> seeds(context->random_seed());
SetSeeds(seeds, state0, state1);
@@ -77,7 +77,7 @@ TEST(CrankshaftRandom) {
env->Enter();
Handle<Context> context(Isolate::Current()->context());
- Handle<JSObject> global(context->global());
+ Handle<JSObject> global(context->global_object());
Handle<ByteArray> seeds(context->random_seed());
bool has_pending_exception;
@@ -85,7 +85,7 @@ TEST(CrankshaftRandom) {
Object* symbol = FACTORY->LookupAsciiSymbol("f")->ToObjectChecked();
MaybeObject* fun_object =
- context->global()->GetProperty(String::cast(symbol));
+ context->global_object()->GetProperty(String::cast(symbol));
Handle<JSFunction> fun(JSFunction::cast(fun_object->ToObjectChecked()));
// Optimize function.
diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc
index 325c68606..e433b925e 100644
--- a/deps/v8/test/cctest/test-regexp.cc
+++ b/deps/v8/test/cctest/test-regexp.cc
@@ -72,24 +72,26 @@ using namespace v8::internal;
static bool CheckParse(const char* input) {
V8::Initialize(NULL);
v8::HandleScope scope;
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
FlatStringReader reader(Isolate::Current(), CStrVector(input));
RegExpCompileData result;
- return v8::internal::RegExpParser::ParseRegExp(&reader, false, &result);
+ return v8::internal::RegExpParser::ParseRegExp(
+ &reader, false, &result, Isolate::Current()->runtime_zone());
}
static SmartArrayPointer<const char> Parse(const char* input) {
V8::Initialize(NULL);
v8::HandleScope scope;
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
FlatStringReader reader(Isolate::Current(), CStrVector(input));
RegExpCompileData result;
- CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
+ CHECK(v8::internal::RegExpParser::ParseRegExp(
+ &reader, false, &result, Isolate::Current()->runtime_zone()));
CHECK(result.tree != NULL);
CHECK(result.error.is_null());
SmartArrayPointer<const char> output =
- result.tree->ToString(Isolate::Current()->zone());
+ result.tree->ToString(Isolate::Current()->runtime_zone());
return output;
}
@@ -97,10 +99,11 @@ static bool CheckSimple(const char* input) {
V8::Initialize(NULL);
v8::HandleScope scope;
unibrow::Utf8InputBuffer<> buffer(input, StrLength(input));
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
FlatStringReader reader(Isolate::Current(), CStrVector(input));
RegExpCompileData result;
- CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
+ CHECK(v8::internal::RegExpParser::ParseRegExp(
+ &reader, false, &result, Isolate::Current()->runtime_zone()));
CHECK(result.tree != NULL);
CHECK(result.error.is_null());
return result.simple;
@@ -115,10 +118,11 @@ static MinMaxPair CheckMinMaxMatch(const char* input) {
V8::Initialize(NULL);
v8::HandleScope scope;
unibrow::Utf8InputBuffer<> buffer(input, StrLength(input));
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
FlatStringReader reader(Isolate::Current(), CStrVector(input));
RegExpCompileData result;
- CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
+ CHECK(v8::internal::RegExpParser::ParseRegExp(
+ &reader, false, &result, Isolate::Current()->runtime_zone()));
CHECK(result.tree != NULL);
CHECK(result.error.is_null());
int min_match = result.tree->min_match();
@@ -263,6 +267,7 @@ TEST(Parser) {
CHECK_PARSE_EQ("\\u003z", "'u003z'");
CHECK_PARSE_EQ("foo[z]*", "(: 'foo' (# 0 - g [z]))");
+ CHECK_SIMPLE("", false);
CHECK_SIMPLE("a", true);
CHECK_SIMPLE("a|b", false);
CHECK_SIMPLE("a\\n", false);
@@ -386,10 +391,11 @@ static void ExpectError(const char* input,
const char* expected) {
V8::Initialize(NULL);
v8::HandleScope scope;
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
FlatStringReader reader(Isolate::Current(), CStrVector(input));
RegExpCompileData result;
- CHECK(!v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
+ CHECK(!v8::internal::RegExpParser::ParseRegExp(
+ &reader, false, &result, Isolate::Current()->runtime_zone()));
CHECK(result.tree == NULL);
CHECK(!result.error.is_null());
SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS);
@@ -469,8 +475,8 @@ static bool NotWord(uc16 c) {
static void TestCharacterClassEscapes(uc16 c, bool (pred)(uc16 c)) {
- ZoneScope scope(Isolate::Current(), DELETE_ON_EXIT);
- Zone* zone = Isolate::Current()->zone();
+ ZoneScope scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
+ Zone* zone = Isolate::Current()->runtime_zone();
ZoneList<CharacterRange>* ranges =
new(zone) ZoneList<CharacterRange>(2, zone);
CharacterRange::AddClassEscape(c, ranges, zone);
@@ -503,7 +509,8 @@ static RegExpNode* Compile(const char* input, bool multiline, bool is_ascii) {
FlatStringReader reader(isolate, CStrVector(input));
RegExpCompileData compile_data;
if (!v8::internal::RegExpParser::ParseRegExp(&reader, multiline,
- &compile_data))
+ &compile_data,
+ isolate->runtime_zone()))
return NULL;
Handle<String> pattern = isolate->factory()->
NewStringFromUtf8(CStrVector(input));
@@ -516,7 +523,7 @@ static RegExpNode* Compile(const char* input, bool multiline, bool is_ascii) {
pattern,
sample_subject,
is_ascii,
- isolate->zone());
+ isolate->runtime_zone());
return compile_data.node;
}
@@ -526,7 +533,7 @@ static void Execute(const char* input,
bool is_ascii,
bool dot_output = false) {
v8::HandleScope scope;
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
RegExpNode* node = Compile(input, multiline, is_ascii);
USE(node);
#ifdef DEBUG
@@ -566,8 +573,8 @@ static unsigned PseudoRandom(int i, int j) {
TEST(SplayTreeSimple) {
v8::internal::V8::Initialize(NULL);
static const unsigned kLimit = 1000;
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
- ZoneSplayTree<TestConfig> tree(Isolate::Current()->zone());
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
+ ZoneSplayTree<TestConfig> tree(Isolate::Current()->runtime_zone());
bool seen[kLimit];
for (unsigned i = 0; i < kLimit; i++) seen[i] = false;
#define CHECK_MAPS_EQUAL() do { \
@@ -634,13 +641,13 @@ TEST(DispatchTableConstruction) {
}
}
// Enter test data into dispatch table.
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
- DispatchTable table(Isolate::Current()->zone());
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
+ DispatchTable table(Isolate::Current()->runtime_zone());
for (int i = 0; i < kRangeCount; i++) {
uc16* range = ranges[i];
for (int j = 0; j < 2 * kRangeSize; j += 2)
table.AddRange(CharacterRange(range[j], range[j + 1]), i,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
}
// Check that the table looks as we would expect
for (int p = 0; p < kLimit; p++) {
@@ -702,7 +709,8 @@ typedef RegExpMacroAssemblerMIPS ArchRegExpMacroAssembler;
class ContextInitializer {
public:
ContextInitializer()
- : env_(), scope_(), zone_(Isolate::Current(), DELETE_ON_EXIT) {
+ : env_(), scope_(), zone_(Isolate::Current()->runtime_zone(),
+ DELETE_ON_EXIT) {
env_ = v8::Context::New();
env_->Enter();
}
@@ -741,7 +749,7 @@ TEST(MacroAssemblerNativeSuccess) {
Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
m.Succeed();
@@ -777,7 +785,7 @@ TEST(MacroAssemblerNativeSimple) {
Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
uc16 foo_chars[3] = {'f', 'o', 'o'};
Vector<const uc16> foo(foo_chars, 3);
@@ -835,7 +843,7 @@ TEST(MacroAssemblerNativeSimpleUC16) {
Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
uc16 foo_chars[3] = {'f', 'o', 'o'};
Vector<const uc16> foo(foo_chars, 3);
@@ -898,7 +906,7 @@ TEST(MacroAssemblerNativeBacktrack) {
Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
Label fail;
Label backtrack;
@@ -937,7 +945,7 @@ TEST(MacroAssemblerNativeBackReferenceASCII) {
Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
m.WriteCurrentPositionToRegister(0, 0);
m.AdvanceCurrentPosition(2);
@@ -985,7 +993,7 @@ TEST(MacroAssemblerNativeBackReferenceUC16) {
Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
m.WriteCurrentPositionToRegister(0, 0);
m.AdvanceCurrentPosition(2);
@@ -1036,7 +1044,7 @@ TEST(MacroAssemblernativeAtStart) {
Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
Label not_at_start, newline, fail;
m.CheckNotAtStart(&not_at_start);
@@ -1094,7 +1102,7 @@ TEST(MacroAssemblerNativeBackRefNoCase) {
Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
Label fail, succ;
@@ -1152,7 +1160,7 @@ TEST(MacroAssemblerNativeRegisters) {
Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 6,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
uc16 foo_chars[3] = {'f', 'o', 'o'};
Vector<const uc16> foo(foo_chars, 3);
@@ -1255,7 +1263,7 @@ TEST(MacroAssemblerStackOverflow) {
Factory* factory = isolate->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
Label loop;
m.Bind(&loop);
@@ -1294,7 +1302,7 @@ TEST(MacroAssemblerNativeLotsOfRegisters) {
Factory* factory = isolate->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 2,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
// At least 2048, to ensure the allocated space for registers
// span one full page.
@@ -1341,7 +1349,8 @@ TEST(MacroAssemblerNativeLotsOfRegisters) {
TEST(MacroAssembler) {
V8::Initialize(NULL);
byte codes[1024];
- RegExpMacroAssemblerIrregexp m(Vector<byte>(codes, 1024));
+ RegExpMacroAssemblerIrregexp m(Vector<byte>(codes, 1024),
+ Isolate::Current()->runtime_zone());
// ^f(o)o.
Label fail, fail2, start;
uc16 foo_chars[3];
@@ -1411,8 +1420,8 @@ TEST(AddInverseToTable) {
static const int kLimit = 1000;
static const int kRangeCount = 16;
for (int t = 0; t < 10; t++) {
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
- Zone* zone = Isolate::Current()->zone();
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
+ Zone* zone = Isolate::Current()->runtime_zone();
ZoneList<CharacterRange>* ranges =
new(zone)
ZoneList<CharacterRange>(kRangeCount, zone);
@@ -1423,7 +1432,8 @@ TEST(AddInverseToTable) {
ranges->Add(CharacterRange(from, to), zone);
}
DispatchTable table(zone);
- DispatchTableConstructor cons(&table, false, Isolate::Current()->zone());
+ DispatchTableConstructor cons(&table, false,
+ Isolate::Current()->runtime_zone());
cons.set_choice_index(0);
cons.AddInverse(ranges);
for (int i = 0; i < kLimit; i++) {
@@ -1434,13 +1444,14 @@ TEST(AddInverseToTable) {
CHECK_EQ(is_on, set->Get(0) == false);
}
}
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
- Zone* zone = Isolate::Current()->zone();
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
+ Zone* zone = Isolate::Current()->runtime_zone();
ZoneList<CharacterRange>* ranges =
new(zone) ZoneList<CharacterRange>(1, zone);
ranges->Add(CharacterRange(0xFFF0, 0xFFFE), zone);
DispatchTable table(zone);
- DispatchTableConstructor cons(&table, false, Isolate::Current()->zone());
+ DispatchTableConstructor cons(&table, false,
+ Isolate::Current()->runtime_zone());
cons.set_choice_index(0);
cons.AddInverse(ranges);
CHECK(!table.Get(0xFFFE)->Get(0));
@@ -1548,8 +1559,8 @@ TEST(UncanonicalizeEquivalence) {
static void TestRangeCaseIndependence(CharacterRange input,
Vector<CharacterRange> expected) {
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
- Zone* zone = Isolate::Current()->zone();
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
+ Zone* zone = Isolate::Current()->runtime_zone();
int count = expected.length();
ZoneList<CharacterRange>* list =
new(zone) ZoneList<CharacterRange>(count, zone);
@@ -1614,8 +1625,8 @@ static bool InClass(uc16 c, ZoneList<CharacterRange>* ranges) {
TEST(CharClassDifference) {
v8::internal::V8::Initialize(NULL);
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
- Zone* zone = Isolate::Current()->zone();
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
+ Zone* zone = Isolate::Current()->runtime_zone();
ZoneList<CharacterRange>* base =
new(zone) ZoneList<CharacterRange>(1, zone);
base->Add(CharacterRange::Everything(), zone);
@@ -1623,7 +1634,7 @@ TEST(CharClassDifference) {
ZoneList<CharacterRange>* included = NULL;
ZoneList<CharacterRange>* excluded = NULL;
CharacterRange::Split(base, overlay, &included, &excluded,
- Isolate::Current()->zone());
+ Isolate::Current()->runtime_zone());
for (int i = 0; i < (1 << 16); i++) {
bool in_base = InClass(i, base);
if (in_base) {
@@ -1644,8 +1655,8 @@ TEST(CharClassDifference) {
TEST(CanonicalizeCharacterSets) {
v8::internal::V8::Initialize(NULL);
- ZoneScope scope(Isolate::Current(), DELETE_ON_EXIT);
- Zone* zone = Isolate::Current()->zone();
+ ZoneScope scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
+ Zone* zone = Isolate::Current()->runtime_zone();
ZoneList<CharacterRange>* list =
new(zone) ZoneList<CharacterRange>(4, zone);
CharacterSet set(list);
@@ -1707,10 +1718,10 @@ TEST(CanonicalizeCharacterSets) {
TEST(CharacterRangeMerge) {
v8::internal::V8::Initialize(NULL);
- ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
- ZoneList<CharacterRange> l1(4, Isolate::Current()->zone());
- ZoneList<CharacterRange> l2(4, Isolate::Current()->zone());
- Zone* zone = Isolate::Current()->zone();
+ ZoneScope zone_scope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
+ ZoneList<CharacterRange> l1(4, Isolate::Current()->runtime_zone());
+ ZoneList<CharacterRange> l2(4, Isolate::Current()->runtime_zone());
+ Zone* zone = Isolate::Current()->runtime_zone();
// Create all combinations of intersections of ranges, both singletons and
// longer.
@@ -1788,9 +1799,9 @@ TEST(CharacterRangeMerge) {
ASSERT(CharacterRange::IsCanonical(&l1));
ASSERT(CharacterRange::IsCanonical(&l2));
- ZoneList<CharacterRange> first_only(4, Isolate::Current()->zone());
- ZoneList<CharacterRange> second_only(4, Isolate::Current()->zone());
- ZoneList<CharacterRange> both(4, Isolate::Current()->zone());
+ ZoneList<CharacterRange> first_only(4, Isolate::Current()->runtime_zone());
+ ZoneList<CharacterRange> second_only(4, Isolate::Current()->runtime_zone());
+ ZoneList<CharacterRange> both(4, Isolate::Current()->runtime_zone());
}
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index e426e7bd2..827918249 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -196,8 +196,7 @@ class FileByteSink : public SnapshotByteSink {
int data_space_used,
int code_space_used,
int map_space_used,
- int cell_space_used,
- int large_space_used);
+ int cell_space_used);
private:
FILE* fp_;
@@ -211,8 +210,7 @@ void FileByteSink::WriteSpaceUsed(
int data_space_used,
int code_space_used,
int map_space_used,
- int cell_space_used,
- int large_space_used) {
+ int cell_space_used) {
int file_name_length = StrLength(file_name_) + 10;
Vector<char> name = Vector<char>::New(file_name_length + 1);
OS::SNPrintF(name, "%s.size", file_name_);
@@ -224,7 +222,6 @@ void FileByteSink::WriteSpaceUsed(
fprintf(fp, "code %d\n", code_space_used);
fprintf(fp, "map %d\n", map_space_used);
fprintf(fp, "cell %d\n", cell_space_used);
- fprintf(fp, "large %d\n", large_space_used);
fclose(fp);
}
@@ -233,6 +230,15 @@ static bool WriteToFile(const char* snapshot_file) {
FileByteSink file(snapshot_file);
StartupSerializer ser(&file);
ser.Serialize();
+
+ file.WriteSpaceUsed(
+ ser.CurrentAllocationAddress(NEW_SPACE),
+ ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
+ ser.CurrentAllocationAddress(OLD_DATA_SPACE),
+ ser.CurrentAllocationAddress(CODE_SPACE),
+ ser.CurrentAllocationAddress(MAP_SPACE),
+ ser.CurrentAllocationAddress(CELL_SPACE));
+
return true;
}
@@ -250,18 +256,22 @@ static void Serialize() {
// Test that the whole heap can be serialized.
TEST(Serialize) {
- Serializer::Enable();
- v8::V8::Initialize();
- Serialize();
+ if (!Snapshot::HaveASnapshotToStartFrom()) {
+ Serializer::Enable();
+ v8::V8::Initialize();
+ Serialize();
+ }
}
// Test that heap serialization is non-destructive.
TEST(SerializeTwice) {
- Serializer::Enable();
- v8::V8::Initialize();
- Serialize();
- Serialize();
+ if (!Snapshot::HaveASnapshotToStartFrom()) {
+ Serializer::Enable();
+ v8::V8::Initialize();
+ Serialize();
+ Serialize();
+ }
}
@@ -275,11 +285,11 @@ static void Deserialize() {
static void SanityCheck() {
v8::HandleScope scope;
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
HEAP->Verify();
#endif
- CHECK(Isolate::Current()->global()->IsJSObject());
- CHECK(Isolate::Current()->global_context()->IsContext());
+ CHECK(Isolate::Current()->global_object()->IsJSObject());
+ CHECK(Isolate::Current()->native_context()->IsContext());
CHECK(HEAP->symbol_table()->IsSymbolTable());
CHECK(!FACTORY->LookupAsciiSymbol("Empty")->IsFailure());
}
@@ -289,7 +299,7 @@ DEPENDENT_TEST(Deserialize, Serialize) {
// The serialize-deserialize tests only work if the VM is built without
// serialization. That doesn't matter. We don't need to be able to
// serialize a snapshot in a VM that is booted from a snapshot.
- if (!Snapshot::IsEnabled()) {
+ if (!Snapshot::HaveASnapshotToStartFrom()) {
v8::HandleScope scope;
Deserialize();
@@ -302,7 +312,7 @@ DEPENDENT_TEST(Deserialize, Serialize) {
DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
- if (!Snapshot::IsEnabled()) {
+ if (!Snapshot::HaveASnapshotToStartFrom()) {
v8::HandleScope scope;
Deserialize();
@@ -315,7 +325,7 @@ DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
- if (!Snapshot::IsEnabled()) {
+ if (!Snapshot::HaveASnapshotToStartFrom()) {
v8::HandleScope scope;
Deserialize();
@@ -332,7 +342,7 @@ DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
SerializeTwice) {
- if (!Snapshot::IsEnabled()) {
+ if (!Snapshot::HaveASnapshotToStartFrom()) {
v8::HandleScope scope;
Deserialize();
@@ -348,63 +358,74 @@ DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
TEST(PartialSerialization) {
- Serializer::Enable();
- v8::V8::Initialize();
+ if (!Snapshot::HaveASnapshotToStartFrom()) {
+ Serializer::Enable();
+ v8::V8::Initialize();
- v8::Persistent<v8::Context> env = v8::Context::New();
- ASSERT(!env.IsEmpty());
- env->Enter();
- // Make sure all builtin scripts are cached.
- { HandleScope scope;
- for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
- Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
+ v8::Persistent<v8::Context> env = v8::Context::New();
+ ASSERT(!env.IsEmpty());
+ env->Enter();
+ // Make sure all builtin scripts are cached.
+ { HandleScope scope;
+ for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
+ Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
+ }
}
- }
- HEAP->CollectAllGarbage(Heap::kNoGCFlags);
- HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
- Object* raw_foo;
- {
- v8::HandleScope handle_scope;
- v8::Local<v8::String> foo = v8::String::New("foo");
- ASSERT(!foo.IsEmpty());
- raw_foo = *(v8::Utils::OpenHandle(*foo));
- }
-
- int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
- Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
+ Object* raw_foo;
+ {
+ v8::HandleScope handle_scope;
+ v8::Local<v8::String> foo = v8::String::New("foo");
+ ASSERT(!foo.IsEmpty());
+ raw_foo = *(v8::Utils::OpenHandle(*foo));
+ }
- env->Exit();
- env.Dispose();
+ int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
+ Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
+ OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
- FileByteSink startup_sink(startup_name.start());
- startup_name.Dispose();
- StartupSerializer startup_serializer(&startup_sink);
- startup_serializer.SerializeStrongReferences();
-
- FileByteSink partial_sink(FLAG_testing_serialization_file);
- PartialSerializer p_ser(&startup_serializer, &partial_sink);
- p_ser.Serialize(&raw_foo);
- startup_serializer.SerializeWeakReferences();
- partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE),
- p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
- p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
- p_ser.CurrentAllocationAddress(CODE_SPACE),
- p_ser.CurrentAllocationAddress(MAP_SPACE),
- p_ser.CurrentAllocationAddress(CELL_SPACE),
- p_ser.CurrentAllocationAddress(LO_SPACE));
+ env->Exit();
+ env.Dispose();
+
+ FileByteSink startup_sink(startup_name.start());
+ StartupSerializer startup_serializer(&startup_sink);
+ startup_serializer.SerializeStrongReferences();
+
+ FileByteSink partial_sink(FLAG_testing_serialization_file);
+ PartialSerializer p_ser(&startup_serializer, &partial_sink);
+ p_ser.Serialize(&raw_foo);
+ startup_serializer.SerializeWeakReferences();
+
+ partial_sink.WriteSpaceUsed(
+ p_ser.CurrentAllocationAddress(NEW_SPACE),
+ p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
+ p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
+ p_ser.CurrentAllocationAddress(CODE_SPACE),
+ p_ser.CurrentAllocationAddress(MAP_SPACE),
+ p_ser.CurrentAllocationAddress(CELL_SPACE));
+
+ startup_sink.WriteSpaceUsed(
+ startup_serializer.CurrentAllocationAddress(NEW_SPACE),
+ startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE),
+ startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE),
+ startup_serializer.CurrentAllocationAddress(CODE_SPACE),
+ startup_serializer.CurrentAllocationAddress(MAP_SPACE),
+ startup_serializer.CurrentAllocationAddress(CELL_SPACE));
+ startup_name.Dispose();
+ }
}
-static void ReserveSpaceForPartialSnapshot(const char* file_name) {
+static void ReserveSpaceForSnapshot(Deserializer* deserializer,
+ const char* file_name) {
int file_name_length = StrLength(file_name) + 10;
Vector<char> name = Vector<char>::New(file_name_length + 1);
OS::SNPrintF(name, "%s.size", file_name);
FILE* fp = OS::FOpen(name.start(), "r");
name.Dispose();
int new_size, pointer_size, data_size, code_size, map_size, cell_size;
- int large_size;
#ifdef _MSC_VER
// Avoid warning about unsafe fscanf from MSVC.
// Please note that this is only fine if %c and %s are not being used.
@@ -416,18 +437,16 @@ static void ReserveSpaceForPartialSnapshot(const char* file_name) {
CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
- CHECK_EQ(1, fscanf(fp, "large %d\n", &large_size));
#ifdef _MSC_VER
#undef fscanf
#endif
fclose(fp);
- HEAP->ReserveSpace(new_size,
- pointer_size,
- data_size,
- code_size,
- map_size,
- cell_size,
- large_size);
+ deserializer->set_reservation(NEW_SPACE, new_size);
+ deserializer->set_reservation(OLD_POINTER_SPACE, pointer_size);
+ deserializer->set_reservation(OLD_DATA_SPACE, data_size);
+ deserializer->set_reservation(CODE_SPACE, code_size);
+ deserializer->set_reservation(MAP_SPACE, map_size);
+ deserializer->set_reservation(CELL_SPACE, cell_size);
}
@@ -441,7 +460,6 @@ DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
startup_name.Dispose();
const char* file_name = FLAG_testing_serialization_file;
- ReserveSpaceForPartialSnapshot(file_name);
int snapshot_size = 0;
byte* snapshot = ReadBytes(file_name, &snapshot_size);
@@ -450,18 +468,19 @@ DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
{
SnapshotByteSource source(snapshot, snapshot_size);
Deserializer deserializer(&source);
+ ReserveSpaceForSnapshot(&deserializer, file_name);
deserializer.DeserializePartial(&root);
CHECK(root->IsString());
}
v8::HandleScope handle_scope;
Handle<Object> root_handle(root);
- ReserveSpaceForPartialSnapshot(file_name);
Object* root2;
{
SnapshotByteSource source(snapshot, snapshot_size);
Deserializer deserializer(&source);
+ ReserveSpaceForSnapshot(&deserializer, file_name);
deserializer.DeserializePartial(&root2);
CHECK(root2->IsString());
CHECK(*root_handle == root2);
@@ -471,53 +490,64 @@ DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
TEST(ContextSerialization) {
- Serializer::Enable();
- v8::V8::Initialize();
+ if (!Snapshot::HaveASnapshotToStartFrom()) {
+ Serializer::Enable();
+ v8::V8::Initialize();
- v8::Persistent<v8::Context> env = v8::Context::New();
- ASSERT(!env.IsEmpty());
- env->Enter();
- // Make sure all builtin scripts are cached.
- { HandleScope scope;
- for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
- Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
+ v8::Persistent<v8::Context> env = v8::Context::New();
+ ASSERT(!env.IsEmpty());
+ env->Enter();
+ // Make sure all builtin scripts are cached.
+ { HandleScope scope;
+ for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
+ Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
+ }
}
- }
- // If we don't do this then we end up with a stray root pointing at the
- // context even after we have disposed of env.
- HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ // If we don't do this then we end up with a stray root pointing at the
+ // context even after we have disposed of env.
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+
+ int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
+ Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
+ OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
- int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
- Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
+ env->Exit();
- env->Exit();
+ Object* raw_context = *(v8::Utils::OpenHandle(*env));
- Object* raw_context = *(v8::Utils::OpenHandle(*env));
+ env.Dispose();
- env.Dispose();
+ FileByteSink startup_sink(startup_name.start());
+ StartupSerializer startup_serializer(&startup_sink);
+ startup_serializer.SerializeStrongReferences();
+
+ FileByteSink partial_sink(FLAG_testing_serialization_file);
+ PartialSerializer p_ser(&startup_serializer, &partial_sink);
+ p_ser.Serialize(&raw_context);
+ startup_serializer.SerializeWeakReferences();
+
+ partial_sink.WriteSpaceUsed(
+ p_ser.CurrentAllocationAddress(NEW_SPACE),
+ p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
+ p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
+ p_ser.CurrentAllocationAddress(CODE_SPACE),
+ p_ser.CurrentAllocationAddress(MAP_SPACE),
+ p_ser.CurrentAllocationAddress(CELL_SPACE));
- FileByteSink startup_sink(startup_name.start());
- startup_name.Dispose();
- StartupSerializer startup_serializer(&startup_sink);
- startup_serializer.SerializeStrongReferences();
-
- FileByteSink partial_sink(FLAG_testing_serialization_file);
- PartialSerializer p_ser(&startup_serializer, &partial_sink);
- p_ser.Serialize(&raw_context);
- startup_serializer.SerializeWeakReferences();
- partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE),
- p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
- p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
- p_ser.CurrentAllocationAddress(CODE_SPACE),
- p_ser.CurrentAllocationAddress(MAP_SPACE),
- p_ser.CurrentAllocationAddress(CELL_SPACE),
- p_ser.CurrentAllocationAddress(LO_SPACE));
+ startup_sink.WriteSpaceUsed(
+ startup_serializer.CurrentAllocationAddress(NEW_SPACE),
+ startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE),
+ startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE),
+ startup_serializer.CurrentAllocationAddress(CODE_SPACE),
+ startup_serializer.CurrentAllocationAddress(MAP_SPACE),
+ startup_serializer.CurrentAllocationAddress(CELL_SPACE));
+ startup_name.Dispose();
+ }
}
DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
- if (!Snapshot::IsEnabled()) {
+ if (!Snapshot::HaveASnapshotToStartFrom()) {
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
@@ -526,7 +556,6 @@ DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
startup_name.Dispose();
const char* file_name = FLAG_testing_serialization_file;
- ReserveSpaceForPartialSnapshot(file_name);
int snapshot_size = 0;
byte* snapshot = ReadBytes(file_name, &snapshot_size);
@@ -535,18 +564,19 @@ DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
{
SnapshotByteSource source(snapshot, snapshot_size);
Deserializer deserializer(&source);
+ ReserveSpaceForSnapshot(&deserializer, file_name);
deserializer.DeserializePartial(&root);
CHECK(root->IsContext());
}
v8::HandleScope handle_scope;
Handle<Object> root_handle(root);
- ReserveSpaceForPartialSnapshot(file_name);
Object* root2;
{
SnapshotByteSource source(snapshot, snapshot_size);
Deserializer deserializer(&source);
+ ReserveSpaceForSnapshot(&deserializer, file_name);
deserializer.DeserializePartial(&root2);
CHECK(root2->IsContext());
CHECK(*root_handle != root2);
@@ -555,119 +585,6 @@ DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
}
-TEST(LinearAllocation) {
- v8::V8::Initialize();
- int new_space_max = 512 * KB;
- int paged_space_max = Page::kMaxNonCodeHeapObjectSize;
- int code_space_max = HEAP->code_space()->AreaSize();
-
- for (int size = 1000; size < 5 * MB; size += size >> 1) {
- size &= ~8; // Round.
- int new_space_size = (size < new_space_max) ? size : new_space_max;
- int paged_space_size = (size < paged_space_max) ? size : paged_space_max;
- HEAP->ReserveSpace(
- new_space_size,
- paged_space_size, // Old pointer space.
- paged_space_size, // Old data space.
- HEAP->code_space()->RoundSizeDownToObjectAlignment(code_space_max),
- HEAP->map_space()->RoundSizeDownToObjectAlignment(paged_space_size),
- HEAP->cell_space()->RoundSizeDownToObjectAlignment(paged_space_size),
- size); // Large object space.
- LinearAllocationScope linear_allocation_scope;
- const int kSmallFixedArrayLength = 4;
- const int kSmallFixedArraySize =
- FixedArray::kHeaderSize + kSmallFixedArrayLength * kPointerSize;
- const int kSmallStringLength = 16;
- const int kSmallStringSize =
- (SeqAsciiString::kHeaderSize + kSmallStringLength +
- kObjectAlignmentMask) & ~kObjectAlignmentMask;
- const int kMapSize = Map::kSize;
-
- Object* new_last = NULL;
- for (int i = 0;
- i + kSmallFixedArraySize <= new_space_size;
- i += kSmallFixedArraySize) {
- Object* obj =
- HEAP->AllocateFixedArray(kSmallFixedArrayLength)->ToObjectChecked();
- if (new_last != NULL) {
- CHECK(reinterpret_cast<char*>(obj) ==
- reinterpret_cast<char*>(new_last) + kSmallFixedArraySize);
- }
- new_last = obj;
- }
-
- Object* pointer_last = NULL;
- for (int i = 0;
- i + kSmallFixedArraySize <= paged_space_size;
- i += kSmallFixedArraySize) {
- Object* obj = HEAP->AllocateFixedArray(kSmallFixedArrayLength,
- TENURED)->ToObjectChecked();
- int old_page_fullness = i % Page::kPageSize;
- int page_fullness = (i + kSmallFixedArraySize) % Page::kPageSize;
- if (page_fullness < old_page_fullness ||
- page_fullness > HEAP->old_pointer_space()->AreaSize()) {
- i = RoundUp(i, Page::kPageSize);
- pointer_last = NULL;
- }
- if (pointer_last != NULL) {
- CHECK(reinterpret_cast<char*>(obj) ==
- reinterpret_cast<char*>(pointer_last) + kSmallFixedArraySize);
- }
- pointer_last = obj;
- }
-
- Object* data_last = NULL;
- for (int i = 0;
- i + kSmallStringSize <= paged_space_size;
- i += kSmallStringSize) {
- Object* obj = HEAP->AllocateRawAsciiString(kSmallStringLength,
- TENURED)->ToObjectChecked();
- int old_page_fullness = i % Page::kPageSize;
- int page_fullness = (i + kSmallStringSize) % Page::kPageSize;
- if (page_fullness < old_page_fullness ||
- page_fullness > HEAP->old_data_space()->AreaSize()) {
- i = RoundUp(i, Page::kPageSize);
- data_last = NULL;
- }
- if (data_last != NULL) {
- CHECK(reinterpret_cast<char*>(obj) ==
- reinterpret_cast<char*>(data_last) + kSmallStringSize);
- }
- data_last = obj;
- }
-
- Object* map_last = NULL;
- for (int i = 0; i + kMapSize <= paged_space_size; i += kMapSize) {
- Object* obj = HEAP->AllocateMap(JS_OBJECT_TYPE,
- 42 * kPointerSize)->ToObjectChecked();
- int old_page_fullness = i % Page::kPageSize;
- int page_fullness = (i + kMapSize) % Page::kPageSize;
- if (page_fullness < old_page_fullness ||
- page_fullness > HEAP->map_space()->AreaSize()) {
- i = RoundUp(i, Page::kPageSize);
- map_last = NULL;
- }
- if (map_last != NULL) {
- CHECK(reinterpret_cast<char*>(obj) ==
- reinterpret_cast<char*>(map_last) + kMapSize);
- }
- map_last = obj;
- }
-
- if (size > Page::kMaxNonCodeHeapObjectSize) {
- // Support for reserving space in large object space is not there yet,
- // but using an always-allocate scope is fine for now.
- AlwaysAllocateScope always;
- int large_object_array_length =
- (size - FixedArray::kHeaderSize) / kPointerSize;
- Object* obj = HEAP->AllocateFixedArray(large_object_array_length,
- TENURED)->ToObjectChecked();
- CHECK(!obj->IsFailure());
- }
- }
-}
-
-
TEST(TestThatAlwaysSucceeds) {
}
diff --git a/deps/v8/test/cctest/test-sockets.cc b/deps/v8/test/cctest/test-sockets.cc
index ad7354002..2f7941c6e 100644
--- a/deps/v8/test/cctest/test-sockets.cc
+++ b/deps/v8/test/cctest/test-sockets.cc
@@ -124,7 +124,7 @@ static void SendAndReceive(int port, char *data, int len) {
TEST(Socket) {
// Make sure this port is not used by other tests to allow tests to run in
// parallel.
- static const int kPort = 5859;
+ static const int kPort = 5859 + FlagDependentPortOffset();
bool ok;
diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc
index 7cddff330..5a9ccbb57 100644
--- a/deps/v8/test/cctest/test-strings.cc
+++ b/deps/v8/test/cctest/test-strings.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Check that we can traverse very deep stacks of ConsStrings using
// StringInputBuffer. Check that Get(int) works on very deep stacks
@@ -11,6 +11,7 @@
#include "api.h"
#include "factory.h"
+#include "objects.h"
#include "cctest.h"
#include "zone-inl.h"
@@ -82,7 +83,7 @@ static void InitializeBuildingBlocks(
Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]) {
// A list of pointers that we don't have any interest in cleaning up.
// If they are reachable from a root then leak detection won't complain.
- Zone* zone = Isolate::Current()->zone();
+ Zone* zone = Isolate::Current()->runtime_zone();
for (int i = 0; i < NUMBER_OF_BUILDING_BLOCKS; i++) {
int len = gen() % 16;
if (len > 14) {
@@ -234,7 +235,7 @@ TEST(Traverse) {
InitializeVM();
v8::HandleScope scope;
Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS];
- ZoneScope zone(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zone(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
InitializeBuildingBlocks(building_blocks);
Handle<String> flat = ConstructBalanced(building_blocks);
FlattenString(flat);
@@ -349,11 +350,11 @@ TEST(Utf8Conversion) {
TEST(ExternalShortStringAdd) {
- ZoneScope zonescope(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zonescope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
InitializeVM();
v8::HandleScope handle_scope;
- Zone* zone = Isolate::Current()->zone();
+ Zone* zone = Isolate::Current()->runtime_zone();
// Make sure we cover all always-flat lengths and at least one above.
static const int kMaxLength = 20;
@@ -440,7 +441,7 @@ TEST(CachedHashOverflow) {
// We incorrectly allowed strings to be tagged as array indices even if their
// values didn't fit in the hash field.
// See http://code.google.com/p/v8/issues/detail?id=728
- ZoneScope zone(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zone(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT);
InitializeVM();
v8::HandleScope handle_scope;
@@ -691,3 +692,26 @@ TEST(RegExpOverflow) {
CHECK(result.IsEmpty());
CHECK(context->HasOutOfMemoryException());
}
+
+
+TEST(StringReplaceAtomTwoByteResult) {
+ InitializeVM();
+ HandleScope scope;
+ LocalContext context;
+ v8::Local<v8::Value> result = CompileRun(
+ "var subject = 'ascii~only~string~'; "
+ "var replace = '\x80'; "
+ "subject.replace(/~/g, replace); ");
+ CHECK(result->IsString());
+ Handle<String> string = v8::Utils::OpenHandle(v8::String::Cast(*result));
+ CHECK(string->IsSeqTwoByteString());
+
+ v8::Local<v8::String> expected = v8_str("ascii\x80only\x80string\x80");
+ CHECK(expected->Equals(result));
+}
+
+
+TEST(IsAscii) {
+ CHECK(String::IsAscii(static_cast<char*>(NULL), 0));
+ CHECK(String::IsAscii(static_cast<uc16*>(NULL), 0));
+}
diff --git a/deps/v8/test/cctest/test-utils.cc b/deps/v8/test/cctest/test-utils.cc
index df8ff72e4..c83acb909 100644
--- a/deps/v8/test/cctest/test-utils.cc
+++ b/deps/v8/test/cctest/test-utils.cc
@@ -55,6 +55,22 @@ TEST(Utils1) {
CHECK_EQ(-2, -8 >> 2);
CHECK_EQ(-2, static_cast<int8_t>(-8) >> 2);
CHECK_EQ(-2, static_cast<int>(static_cast<intptr_t>(-8) >> 2));
+
+ CHECK_EQ(-1000000, FastD2IChecked(-1000000.0));
+ CHECK_EQ(-1, FastD2IChecked(-1.0));
+ CHECK_EQ(0, FastD2IChecked(0.0));
+ CHECK_EQ(1, FastD2IChecked(1.0));
+ CHECK_EQ(1000000, FastD2IChecked(1000000.0));
+
+ CHECK_EQ(-1000000, FastD2IChecked(-1000000.123));
+ CHECK_EQ(-1, FastD2IChecked(-1.234));
+ CHECK_EQ(0, FastD2IChecked(0.345));
+ CHECK_EQ(1, FastD2IChecked(1.234));
+ CHECK_EQ(1000000, FastD2IChecked(1000000.123));
+
+ CHECK_EQ(INT_MAX, FastD2IChecked(1.0e100));
+ CHECK_EQ(INT_MIN, FastD2IChecked(-1.0e100));
+ CHECK_EQ(INT_MIN, FastD2IChecked(OS::nan_value()));
}
diff --git a/deps/v8/test/cctest/test-weakmaps.cc b/deps/v8/test/cctest/test-weakmaps.cc
index 7bba7b648..7c98c573c 100644
--- a/deps/v8/test/cctest/test-weakmaps.cc
+++ b/deps/v8/test/cctest/test-weakmaps.cc
@@ -193,9 +193,10 @@ TEST(Regress2060a) {
// other strong paths are correctly recorded in the slots buffer.
TEST(Regress2060b) {
FLAG_always_compact = true;
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
FLAG_verify_heap = true;
#endif
+
LocalContext context;
v8::HandleScope scope;
Handle<JSFunction> function =
diff --git a/deps/v8/test/cctest/testcfg.py b/deps/v8/test/cctest/testcfg.py
index f1387e8a4..69a5db204 100644
--- a/deps/v8/test/cctest/testcfg.py
+++ b/deps/v8/test/cctest/testcfg.py
@@ -25,11 +25,70 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import test
import os
-from os.path import join, dirname, exists
-import platform
-import utils
+import shutil
+
+from testrunner.local import commands
+from testrunner.local import testsuite
+from testrunner.local import utils
+from testrunner.objects import testcase
+
+
+class CcTestSuite(testsuite.TestSuite):
+
+ def __init__(self, name, root):
+ super(CcTestSuite, self).__init__(name, root)
+ self.serdes_dir = os.path.normpath(
+ os.path.join(root, "..", "..", "out", ".serdes"))
+ if os.path.exists(self.serdes_dir):
+ shutil.rmtree(self.serdes_dir, True)
+ os.makedirs(self.serdes_dir)
+
+ def ListTests(self, context):
+ if utils.IsWindows():
+ shell += '.exe'
+ shell = os.path.abspath(os.path.join(context.shell_dir, self.shell()))
+ output = commands.Execute([context.command_prefix,
+ shell,
+ '--list',
+ context.extra_flags])
+ if output.exit_code != 0:
+ print output.stdout
+ print output.stderr
+ return []
+ tests = []
+ for test_desc in output.stdout.strip().split():
+ raw_test, dependency = test_desc.split('<')
+ if dependency != '':
+ dependency = raw_test.split('/')[0] + '/' + dependency
+ else:
+ dependency = None
+ test = testcase.TestCase(self, raw_test, dependency=dependency)
+ tests.append(test)
+ tests.sort()
+ return tests
+
+ def GetFlagsForTestCase(self, testcase, context):
+ testname = testcase.path.split(os.path.sep)[-1]
+ serialization_file = os.path.join(self.serdes_dir, "serdes_" + testname)
+ serialization_file += ''.join(testcase.flags).replace('-', '_')
+ return (testcase.flags + [testcase.path] + context.mode_flags +
+ ["--testing_serialization_file=" + serialization_file])
+
+ def shell(self):
+ return "cctest"
+
+
+def GetSuite(name, root):
+ return CcTestSuite(name, root)
+
+
+# Deprecated definitions below.
+# TODO(jkummerow): Remove when SCons is no longer supported.
+
+
+from os.path import exists, join, normpath
+import test
class CcTestCase(test.TestCase):
@@ -93,7 +152,8 @@ class CcTestConfiguration(test.TestConfiguration):
if utils.IsWindows():
executable += '.exe'
executable = join(self.context.buildspace, executable)
- output = test.Execute([executable, '--list'], self.context)
+ full_command = self.context.processor([executable, '--list'])
+ output = test.Execute(full_command, self.context)
if output.exit_code != 0:
print output.stdout
print output.stderr
diff --git a/deps/v8/test/es5conform/testcfg.py b/deps/v8/test/es5conform/testcfg.py
index b6a17d9b6..7de990d38 100644
--- a/deps/v8/test/es5conform/testcfg.py
+++ b/deps/v8/test/es5conform/testcfg.py
@@ -31,6 +31,11 @@ import os
from os.path import join, exists
+def GetSuite(name, root):
+ # Not implemented.
+ return None
+
+
HARNESS_FILES = ['sth.js']
diff --git a/deps/v8/test/message/testcfg.py b/deps/v8/test/message/testcfg.py
index af467e699..1b788d561 100644
--- a/deps/v8/test/message/testcfg.py
+++ b/deps/v8/test/message/testcfg.py
@@ -25,13 +25,93 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import test
+import itertools
import os
-from os.path import join, dirname, exists, basename, isdir
import re
+from testrunner.local import testsuite
+from testrunner.local import utils
+from testrunner.objects import testcase
+
+
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
+
+class MessageTestSuite(testsuite.TestSuite):
+ def __init__(self, name, root):
+ super(MessageTestSuite, self).__init__(name, root)
+
+ def ListTests(self, context):
+ tests = []
+ for dirname, dirs, files in os.walk(self.root):
+ for dotted in [x for x in dirs if x.startswith('.')]:
+ dirs.remove(dotted)
+ dirs.sort()
+ files.sort()
+ for filename in files:
+ if filename.endswith(".js"):
+ testname = join(dirname[len(self.root) + 1:], filename[:-3])
+ test = testcase.TestCase(self, testname)
+ tests.append(test)
+ return tests
+
+ def GetFlagsForTestCase(self, testcase, context):
+ source = self.GetSourceForTest(testcase)
+ result = []
+ flags_match = re.findall(FLAGS_PATTERN, source)
+ for match in flags_match:
+ result += match.strip().split()
+ result += context.mode_flags
+ result.append(os.path.join(self.root, testcase.path + ".js"))
+ return testcase.flags + result
+
+ def GetSourceForTest(self, testcase):
+ filename = os.path.join(self.root, testcase.path + self.suffix())
+ with open(filename) as f:
+ return f.read()
+
+ def _IgnoreLine(self, string):
+ """Ignore empty lines, valgrind output and Android output."""
+ if not string: return True
+ return (string.startswith("==") or string.startswith("**") or
+ string.startswith("ANDROID"))
+
+ def IsFailureOutput(self, output, testpath):
+ expected_path = os.path.join(self.root, testpath + ".out")
+ expected_lines = []
+ # Can't use utils.ReadLinesFrom() here because it strips whitespace.
+ with open(expected_path) as f:
+ for line in f:
+ if line.startswith("#") or not line.strip(): continue
+ expected_lines.append(line)
+ raw_lines = output.stdout.splitlines()
+ actual_lines = [ s for s in raw_lines if not self._IgnoreLine(s) ]
+ env = { "basename": os.path.basename(testpath + ".js") }
+ if len(expected_lines) != len(actual_lines):
+ return True
+ for (expected, actual) in itertools.izip(expected_lines, actual_lines):
+ pattern = re.escape(expected.rstrip() % env)
+ pattern = pattern.replace("\\*", ".*")
+ pattern = "^%s$" % pattern
+ if not re.match(pattern, actual):
+ return True
+ return False
+
+ def StripOutputForTransmit(self, testcase):
+ pass
+
+
+def GetSuite(name, root):
+ return MessageTestSuite(name, root)
+
+
+# Deprecated definitions below.
+# TODO(jkummerow): Remove when SCons is no longer supported.
+
+
+import test
+from os.path import join, exists, basename, isdir
+
class MessageTestCase(test.TestCase):
def __init__(self, path, file, expected, mode, context, config):
@@ -41,9 +121,10 @@ class MessageTestCase(test.TestCase):
self.config = config
def IgnoreLine(self, str):
- """Ignore empty lines and valgrind output."""
+ """Ignore empty lines, valgrind output and Android output."""
if not str: return True
- else: return str.startswith('==') or str.startswith('**')
+ return (str.startswith('==') or str.startswith('**') or
+ str.startswith('ANDROID'))
def IsFailureOutput(self, output):
f = file(self.expected)
@@ -62,7 +143,7 @@ class MessageTestCase(test.TestCase):
pattern = '^%s$' % pattern
patterns.append(pattern)
# Compare actual output with the expected
- raw_lines = output.stdout.split('\n')
+ raw_lines = output.stdout.splitlines()
outlines = [ s for s in raw_lines if not self.IgnoreLine(s) ]
if len(outlines) != len(patterns):
return True
@@ -80,9 +161,9 @@ class MessageTestCase(test.TestCase):
def GetCommand(self):
result = self.config.context.GetVmCommand(self, self.mode)
source = open(self.file).read()
- flags_match = FLAGS_PATTERN.search(source)
- if flags_match:
- result += flags_match.group(1).strip().split()
+ flags_match = re.findall(FLAGS_PATTERN, source)
+ for match in flags_match:
+ result += match.strip().split()
result.append(self.file)
return result
diff --git a/deps/v8/test/message/try-catch-finally-no-message.out b/deps/v8/test/message/try-catch-finally-no-message.out
index d85fc7d02..f59f5c6a6 100644
--- a/deps/v8/test/message/try-catch-finally-no-message.out
+++ b/deps/v8/test/message/try-catch-finally-no-message.out
@@ -1,26 +1,26 @@
-// Copyright 2008 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.
+# Copyright 2008 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.
diff --git a/deps/v8/test/mjsunit/accessor-map-sharing.js b/deps/v8/test/mjsunit/accessor-map-sharing.js
index ab45afab0..3afce37d9 100644
--- a/deps/v8/test/mjsunit/accessor-map-sharing.js
+++ b/deps/v8/test/mjsunit/accessor-map-sharing.js
@@ -35,7 +35,7 @@ function getter() { return 111; }
function setter(x) { print(222); }
function anotherGetter() { return 333; }
function anotherSetter(x) { print(444); }
-var obj1, obj2;
+var obj1, obj2, obj3, obj4;
// Two objects with the same getter.
obj1 = {};
@@ -174,3 +174,19 @@ assertEquals(getter, gop(obj1, "papa").get);
assertEquals(setter, gop(obj1, "papa").set);
assertTrue(gop(obj1, "papa").configurable);
assertFalse(gop(obj1, "papa").enumerable);
+
+// Two objects with the same getter on the prototype chain.
+obj1 = {};
+dp(obj1, "quebec", { get: getter });
+obj2 = Object.create(obj1);
+obj3 = Object.create(obj2);
+obj4 = Object.create(obj2);
+assertTrue(%HaveSameMap(obj3, obj4));
+
+// Two objects with the same setter on the prototype chain.
+obj1 = {};
+dp(obj1, "romeo", { set: setter });
+obj2 = Object.create(obj1);
+obj3 = Object.create(obj2);
+obj4 = Object.create(obj2);
+assertTrue(%HaveSameMap(obj3, obj4));
diff --git a/deps/v8/test/mjsunit/array-bounds-check-removal.js b/deps/v8/test/mjsunit/array-bounds-check-removal.js
index 81064aa23..df7988bda 100644
--- a/deps/v8/test/mjsunit/array-bounds-check-removal.js
+++ b/deps/v8/test/mjsunit/array-bounds-check-removal.js
@@ -29,6 +29,29 @@
var a = new Int32Array(1024);
+// Test that we do not assert if the accessed index has not an int32 rep.
+var v = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+function test_do_not_assert_on_non_int32(vector, base) {
+ var r = 0;
+ var a1 = base + 1;
+ var a2 = base + 2;
+ var a3 = base + 3;
+ var a4 = base + 4;
+ if (a1 == 2) {
+ r += vector[a1];
+ r += vector[a4];
+ r += vector[a2];
+ r += vector[a3];
+ }
+ return r;
+}
+test_do_not_assert_on_non_int32(v,1);
+test_do_not_assert_on_non_int32(v,1);
+test_do_not_assert_on_non_int32(v,"a");
+test_do_not_assert_on_non_int32(v,"a");
+%OptimizeFunctionOnNextCall(test_do_not_assert_on_non_int32);
+test_do_not_assert_on_non_int32(v,0);
+
function test_base(base,cond) {
a[base + 1] = 1;
a[base + 4] = 2;
@@ -123,7 +146,7 @@ check_test_minus(7,false);
// ALWAYS: 3
// NEVER: 4
-if (false) {
+// Test that we still deopt on failed bound checks
test_base(5,true);
test_base(6,true);
test_base(5,false);
@@ -139,7 +162,21 @@ test_base(6,false);
%OptimizeFunctionOnNextCall(test_base);
test_base(2048,true);
assertTrue(%GetOptimizationStatus(test_base) != 1);
+
+// Specific test on negative offsets
+var short_a = new Array(100);
+for (var i = 0; i < short_a.length; i++) short_a[i] = 0;
+function short_test(a, i) {
+ a[i + 9] = 0;
+ a[i - 10] = 0;
}
+short_test(short_a, 50);
+short_test(short_a, 50);
+%OptimizeFunctionOnNextCall(short_test);
+short_a.length = 10;
+short_test(a, 0);
+assertTrue(%GetOptimizationStatus(short_test) != 1);
+
gc();
diff --git a/deps/v8/test/mjsunit/array-iteration.js b/deps/v8/test/mjsunit/array-iteration.js
index 0ee2e6e9a..033bb5443 100644
--- a/deps/v8/test/mjsunit/array-iteration.js
+++ b/deps/v8/test/mjsunit/array-iteration.js
@@ -40,7 +40,7 @@
// Simple use.
var a = [0,1];
assertArrayEquals([0], a.filter(function(n) { return n == 0; }));
- assertArrayEquals(a, a);
+ assertArrayEquals([0,1], a);
// Use specified object as this object when calling the function.
var o = { value: 42 }
diff --git a/deps/v8/test/mjsunit/array-literal-transitions.js b/deps/v8/test/mjsunit/array-literal-transitions.js
index a96719d44..d4c0c305f 100644
--- a/deps/v8/test/mjsunit/array-literal-transitions.js
+++ b/deps/v8/test/mjsunit/array-literal-transitions.js
@@ -26,6 +26,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --noparallel-recompilation
+
// Test element kind of objects.
// Since --smi-only-arrays affects builtins, its default setting at compile
// time sticks if built with snapshot. If --smi-only-arrays is deactivated
diff --git a/deps/v8/test/mjsunit/assert-opt-and-deopt.js b/deps/v8/test/mjsunit/assert-opt-and-deopt.js
index 51cb99adc..c79d92349 100644
--- a/deps/v8/test/mjsunit/assert-opt-and-deopt.js
+++ b/deps/v8/test/mjsunit/assert-opt-and-deopt.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --noparallel-recompilation
/**
* This class shows how to use %GetOptimizationCount() and
diff --git a/deps/v8/test/mjsunit/bugs/bug-2337.js b/deps/v8/test/mjsunit/bugs/bug-2337.js
new file mode 100644
index 000000000..ebf7621c4
--- /dev/null
+++ b/deps/v8/test/mjsunit/bugs/bug-2337.js
@@ -0,0 +1,53 @@
+// Copyright 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.
+
+// Flags: --expose-debug-as debug --expose-gc
+
+// If one callback causes a GC then the other callbacks don't take place.
+
+var f = eval("(function f() { return 42; })");
+var f2 = eval("(function f2() { return 43; })");
+
+Debug = debug.Debug;
+
+var called = 0;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.ScriptCollected) {
+ if (called != 2) {
+ called++;
+ gc();
+ }
+ }
+};
+
+Debug.scripts();
+Debug.setListener(listener);
+f = void 0;
+f2 = void 0;
+gc();
+assertTrue(called == 2);
diff --git a/deps/v8/test/mjsunit/compiler/alloc-object-huge.js b/deps/v8/test/mjsunit/compiler/alloc-object-huge.js
index 0b202f758..b0a981d6c 100644
--- a/deps/v8/test/mjsunit/compiler/alloc-object-huge.js
+++ b/deps/v8/test/mjsunit/compiler/alloc-object-huge.js
@@ -25,7 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --inline-construct --max-inlined-source-size=999999 --max-inlined-nodes=999999 --max-inlined-nodes-cumulative=999999
+// Flags: --allow-natives-syntax --inline-construct
+// Flags: --max-inlined-source-size=999999 --max-inlined-nodes=999999
+// Flags: --max-inlined-nodes-cumulative=999999
// Test that huge constructors (more than 256 this assignments) are
// handled correctly.
diff --git a/deps/v8/test/mjsunit/compiler/inline-accessors.js b/deps/v8/test/mjsunit/compiler/inline-accessors.js
new file mode 100644
index 000000000..a4cf7ae8c
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/inline-accessors.js
@@ -0,0 +1,368 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax --inline-accessors --max-opt-count=100
+
+var accessorCallCount, setterArgument, setterValue, obj, forceDeopt;
+
+// -----------------------------------------------------------------------------
+// Helpers for testing inlining of getters.
+
+function TestInlinedGetter(context, obj, expected) {
+ forceDeopt = { deopt: 0 };
+ accessorCallCount = 0;
+
+ assertEquals(expected, context(obj));
+ assertEquals(1, accessorCallCount);
+
+ assertEquals(expected, context(obj));
+ assertEquals(2, accessorCallCount);
+
+ %OptimizeFunctionOnNextCall(context);
+ assertEquals(expected, context(obj));
+ assertEquals(3, accessorCallCount);
+
+ forceDeopt = { /* empty*/ };
+ assertEquals(expected, context(obj));
+ assertEquals(4, accessorCallCount);
+}
+
+
+function value_context_for_getter(obj) {
+ return obj.getterProperty;
+}
+
+function test_context_for_getter(obj) {
+ if (obj.getterProperty) {
+ return 111;
+ } else {
+ return 222;
+ }
+}
+
+function effect_context_for_getter(obj) {
+ obj.getterProperty;
+ return 5678;
+}
+
+function TryGetter(context, getter, obj, expected, expectException) {
+ try {
+ TestInlinedGetter(context, obj, expected);
+ assertFalse(expectException);
+ } catch (exception) {
+ assertTrue(expectException);
+ assertEquals(7, exception.stack.split('\n').length);
+ }
+ %DeoptimizeFunction(context);
+ %ClearFunctionTypeFeedback(context);
+ %ClearFunctionTypeFeedback(getter);
+}
+
+function TestGetterInAllContexts(getter, obj, expected, expectException) {
+ TryGetter(value_context_for_getter, getter, obj, expected, expectException);
+ TryGetter(test_context_for_getter, getter, obj, expected ? 111 : 222,
+ expectException);
+ TryGetter(effect_context_for_getter, getter, obj, 5678, expectException);
+}
+
+// -----------------------------------------------------------------------------
+// Test getter returning something 'true'ish in all contexts.
+
+function getter1() {
+ assertSame(obj, this);
+ accessorCallCount++;
+ forceDeopt.deopt;
+ return 1234;
+}
+
+function ConstrG1() { }
+obj = Object.defineProperty(new ConstrG1(), "getterProperty", { get: getter1 });
+TestGetterInAllContexts(getter1, obj, 1234, false);
+obj = Object.create(obj);
+TestGetterInAllContexts(getter1, obj, 1234, false);
+
+// -----------------------------------------------------------------------------
+// Test getter returning false in all contexts.
+
+function getter2() {
+ assertSame(obj, this);
+ accessorCallCount++;
+ forceDeopt.deopt;
+ return false;
+}
+
+function ConstrG2() { }
+obj = Object.defineProperty(new ConstrG2(), "getterProperty", { get: getter2 });
+TestGetterInAllContexts(getter2, obj, false, false);
+obj = Object.create(obj);
+TestGetterInAllContexts(getter2, obj, false, false);
+
+// -----------------------------------------------------------------------------
+// Test getter without a return in all contexts.
+
+function getter3() {
+ assertSame(obj, this);
+ accessorCallCount++;
+ forceDeopt.deopt;
+}
+
+function ConstrG3() { }
+obj = Object.defineProperty(new ConstrG3(), "getterProperty", { get: getter3 });
+TestGetterInAllContexts(getter3, obj, undefined, false);
+obj = Object.create(obj);
+TestGetterInAllContexts(getter3, obj, undefined, false);
+
+// -----------------------------------------------------------------------------
+// Test getter with too many arguments without a return in all contexts.
+
+function getter4(a) {
+ assertSame(obj, this);
+ assertEquals(undefined, a);
+ accessorCallCount++;
+ forceDeopt.deopt;
+}
+
+function ConstrG4() { }
+obj = Object.defineProperty(new ConstrG4(), "getterProperty", { get: getter4 });
+TestGetterInAllContexts(getter4, obj, undefined, false);
+obj = Object.create(obj);
+TestGetterInAllContexts(getter4, obj, undefined, false);
+
+// -----------------------------------------------------------------------------
+// Test getter with too many arguments with a return in all contexts.
+
+function getter5(a) {
+ assertSame(obj, this);
+ assertEquals(undefined, a);
+ accessorCallCount++;
+ forceDeopt.deopt;
+ return 9876;
+}
+
+function ConstrG5() { }
+obj = Object.defineProperty(new ConstrG5(), "getterProperty", { get: getter5 });
+TestGetterInAllContexts(getter5, obj, 9876, false);
+obj = Object.create(obj);
+TestGetterInAllContexts(getter5, obj, 9876, false);
+
+// -----------------------------------------------------------------------------
+// Test getter which throws from optimized code.
+
+function getter6() {
+ assertSame(obj, this);
+ accessorCallCount++;
+ forceDeopt.deopt;
+ if (accessorCallCount == 4) { 123 in null; }
+ return 13579;
+}
+
+function ConstrG6() { }
+obj = Object.defineProperty(new ConstrG6(), "getterProperty", { get: getter6 });
+TestGetterInAllContexts(getter6, obj, 13579, true);
+obj = Object.create(obj);
+TestGetterInAllContexts(getter6, obj, 13579, true);
+
+// -----------------------------------------------------------------------------
+// Helpers for testing inlining of setters.
+
+function TestInlinedSetter(context, obj, value, expected) {
+ forceDeopt = { deopt: 0 };
+ accessorCallCount = 0;
+ setterArgument = value;
+
+ assertEquals(expected, context(obj, value));
+ assertEquals(value, setterValue);
+ assertEquals(1, accessorCallCount);
+
+ assertEquals(expected, context(obj, value));
+ assertEquals(value, setterValue);
+ assertEquals(2, accessorCallCount);
+
+ %OptimizeFunctionOnNextCall(context);
+ assertEquals(expected, context(obj, value));
+ assertEquals(value, setterValue);
+ assertEquals(3, accessorCallCount);
+
+ forceDeopt = { /* empty*/ };
+ assertEquals(expected, context(obj, value));
+ assertEquals(value, setterValue);
+ assertEquals(4, accessorCallCount);
+}
+
+function value_context_for_setter(obj, value) {
+ return obj.setterProperty = value;
+}
+
+function test_context_for_setter(obj, value) {
+ if (obj.setterProperty = value) {
+ return 333;
+ } else {
+ return 444;
+ }
+}
+
+function effect_context_for_setter(obj, value) {
+ obj.setterProperty = value;
+ return 666;
+}
+
+function TrySetter(context, setter, obj, expectException, value, expected) {
+ try {
+ TestInlinedSetter(context, obj, value, expected);
+ assertFalse(expectException);
+ } catch (exception) {
+ assertTrue(expectException);
+ assertEquals(7, exception.stack.split('\n').length);
+ }
+ %DeoptimizeFunction(context);
+ %ClearFunctionTypeFeedback(context);
+ %ClearFunctionTypeFeedback(setter);
+}
+
+function TestSetterInAllContexts(setter, obj, expectException) {
+ TrySetter(value_context_for_setter, setter, obj, expectException, 111, 111);
+ TrySetter(test_context_for_setter, setter, obj, expectException, true, 333);
+ TrySetter(test_context_for_setter, setter, obj, expectException, false, 444);
+ TrySetter(effect_context_for_setter, setter, obj, expectException, 555, 666);
+}
+
+// -----------------------------------------------------------------------------
+// Test setter without a return in all contexts.
+
+function setter1(value) {
+ assertSame(obj, this);
+ accessorCallCount++;
+ forceDeopt.deopt;
+ setterValue = value;
+}
+
+function ConstrS1() { }
+obj = Object.defineProperty(new ConstrS1(), "setterProperty", { set: setter1 });
+TestSetterInAllContexts(setter1, obj, false);
+obj = Object.create(obj);
+TestSetterInAllContexts(setter1, obj, false);
+
+// -----------------------------------------------------------------------------
+// Test setter returning something different than the RHS in all contexts.
+
+function setter2(value) {
+ assertSame(obj, this);
+ accessorCallCount++;
+ forceDeopt.deopt;
+ setterValue = value;
+ return 1000000;
+}
+
+function ConstrS2() { }
+obj = Object.defineProperty(new ConstrS2(), "setterProperty", { set: setter2 });
+TestSetterInAllContexts(setter2, obj, false);
+obj = Object.create(obj);
+TestSetterInAllContexts(setter2, obj, false);
+
+// -----------------------------------------------------------------------------
+// Test setter with too few arguments without a return in all contexts.
+
+function setter3() {
+ assertSame(obj, this);
+ accessorCallCount++;
+ forceDeopt.deopt;
+ setterValue = setterArgument;
+}
+
+function ConstrS3() { }
+obj = Object.defineProperty(new ConstrS3(), "setterProperty", { set: setter3 });
+TestSetterInAllContexts(setter3, obj, false);
+obj = Object.create(obj);
+TestSetterInAllContexts(setter3, obj, false);
+
+// -----------------------------------------------------------------------------
+// Test setter with too few arguments with a return in all contexts.
+
+function setter4() {
+ assertSame(obj, this);
+ accessorCallCount++;
+ forceDeopt.deopt;
+ setterValue = setterArgument;
+ return 2000000;
+}
+
+function ConstrS4() { }
+obj = Object.defineProperty(new ConstrS4(), "setterProperty", { set: setter4 });
+TestSetterInAllContexts(setter4, obj, false);
+obj = Object.create(obj);
+TestSetterInAllContexts(setter4, obj, false);
+
+// -----------------------------------------------------------------------------
+// Test setter with too many arguments without a return in all contexts.
+
+function setter5(value, foo) {
+ assertSame(obj, this);
+ assertEquals(undefined, foo);
+ accessorCallCount++;
+ forceDeopt.deopt;
+ setterValue = value;
+}
+
+function ConstrS5() { }
+obj = Object.defineProperty(new ConstrS5(), "setterProperty", { set: setter5 });
+TestSetterInAllContexts(setter5, obj, false);
+obj = Object.create(obj);
+TestSetterInAllContexts(setter5, obj, false);
+
+// -----------------------------------------------------------------------------
+// Test setter with too many arguments with a return in all contexts.
+
+function setter6(value, foo) {
+ assertSame(obj, this);
+ assertEquals(undefined, foo);
+ accessorCallCount++;
+ forceDeopt.deopt;
+ setterValue = value;
+ return 3000000;
+}
+
+function ConstrS6() { }
+obj = Object.defineProperty(new ConstrS6(), "setterProperty", { set: setter6 });
+TestSetterInAllContexts(setter6, obj, false);
+obj = Object.create(obj);
+TestSetterInAllContexts(setter6, obj, false);
+
+// -----------------------------------------------------------------------------
+// Test setter which throws from optimized code.
+
+function setter7(value) {
+ accessorCallCount++;
+ forceDeopt.deopt;
+ if (accessorCallCount == 4) { 123 in null; }
+ setterValue = value;
+}
+
+function ConstrS7() { }
+obj = Object.defineProperty(new ConstrS7(), "setterProperty", { set: setter7 });
+TestSetterInAllContexts(setter7, obj, true);
+obj = Object.create(obj);
+TestSetterInAllContexts(setter7, obj, true);
diff --git a/deps/v8/test/mjsunit/compiler/inline-arguments.js b/deps/v8/test/mjsunit/compiler/inline-arguments.js
index f8a247608..df1bd2214 100644
--- a/deps/v8/test/mjsunit/compiler/inline-arguments.js
+++ b/deps/v8/test/mjsunit/compiler/inline-arguments.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --max-opt-count=100
function A() {
}
@@ -157,6 +157,7 @@ function test_toarr(toarr) {
test_toarr(toarr1);
test_toarr(toarr2);
+
// Test that arguments access from inlined function uses correct values.
(function () {
function inner(x, y) {
@@ -174,9 +175,94 @@ test_toarr(toarr2);
return inner(x, y);
}
+ %OptimizeFunctionOnNextCall(outer);
+ %OptimizeFunctionOnNextCall(inner);
+ assertEquals(2, outer(1, 2));
+})();
+
+
+(function () {
+ function inner(x, y) {
+ "use strict";
+ x = 10;
+ y = 20;
+ for (var i = 0; i < 1; i++) {
+ for (var j = 1; j <= arguments.length; j++) {
+ return arguments[arguments.length - j];
+ }
+ }
+ }
+
+ function outer(x, y) {
+ return inner(x, y);
+ }
+
assertEquals(2, outer(1, 2));
assertEquals(2, outer(1, 2));
assertEquals(2, outer(1, 2));
%OptimizeFunctionOnNextCall(outer);
assertEquals(2, outer(1, 2));
})();
+
+
+// Test inlining and deoptimization of functions accessing and modifying
+// the arguments object in strict mode with mismatched arguments count.
+(function () {
+ "use strict";
+ function test(outerCount, middleCount, innerCount) {
+ var forceDeopt = { deopt:false };
+ function inner(x,y) {
+ x = 0; y = 0;
+ forceDeopt.deopt;
+ assertSame(innerCount, arguments.length);
+ for (var i = 0; i < arguments.length; i++) {
+ assertSame(30 + i, arguments[i]);
+ }
+ }
+
+ function middle(x,y) {
+ x = 0; y = 0;
+ if (innerCount == 1) inner(30);
+ if (innerCount == 2) inner(30, 31);
+ if (innerCount == 3) inner(30, 31, 32);
+ assertSame(middleCount, arguments.length);
+ for (var i = 0; i < arguments.length; i++) {
+ assertSame(20 + i, arguments[i]);
+ }
+ }
+
+ function outer(x,y) {
+ x = 0; y = 0;
+ if (middleCount == 1) middle(20);
+ if (middleCount == 2) middle(20, 21);
+ if (middleCount == 3) middle(20, 21, 22);
+ assertSame(outerCount, arguments.length);
+ for (var i = 0; i < arguments.length; i++) {
+ assertSame(10 + i, arguments[i]);
+ }
+ }
+
+ for (var step = 0; step < 4; step++) {
+ if (outerCount == 1) outer(10);
+ if (outerCount == 2) outer(10, 11);
+ if (outerCount == 3) outer(10, 11, 12);
+ if (step == 1) %OptimizeFunctionOnNextCall(outer);
+ if (step == 2) delete forceDeopt.deopt;
+ }
+
+ %DeoptimizeFunction(outer);
+ %DeoptimizeFunction(middle);
+ %DeoptimizeFunction(inner);
+ %ClearFunctionTypeFeedback(outer);
+ %ClearFunctionTypeFeedback(middle);
+ %ClearFunctionTypeFeedback(inner);
+ }
+
+ for (var a = 1; a <= 3; a++) {
+ for (var b = 1; b <= 3; b++) {
+ for (var c = 1; c <= 3; c++) {
+ test(a,b,c);
+ }
+ }
+ }
+})();
diff --git a/deps/v8/test/mjsunit/compiler/inline-construct.js b/deps/v8/test/mjsunit/compiler/inline-construct.js
index 7a3f1e44b..fa784cfc9 100644
--- a/deps/v8/test/mjsunit/compiler/inline-construct.js
+++ b/deps/v8/test/mjsunit/compiler/inline-construct.js
@@ -29,63 +29,72 @@
// Test inlining of constructor calls.
-function TestInlinedConstructor(closure) {
+function TestInlinedConstructor(constructor, closure) {
var result;
var counter = { value:0 };
- result = closure(11, 12, counter);
- assertEquals(23, result);
+ var noDeopt = { deopt:0 };
+ var forceDeopt = { /*empty*/ };
+
+ result = closure(constructor, 11, noDeopt, counter);
+ assertEquals(11, result);
assertEquals(1, counter.value);
- result = closure(23, 19, counter);
- assertEquals(42, result);
+
+ result = closure(constructor, 23, noDeopt, counter);
+ assertEquals(23, result);
assertEquals(2, counter.value);
+
%OptimizeFunctionOnNextCall(closure);
- result = closure(1, 42, counter)
- assertEquals(43, result);
+ result = closure(constructor, 42, noDeopt, counter);
+ assertEquals(42, result);
assertEquals(3, counter.value);
- result = closure("foo", "bar", counter)
- assertEquals("foobar", result)
+
+ result = closure(constructor, 127, forceDeopt, counter);
+ assertEquals(127, result)
assertEquals(4, counter.value);
+
+ %DeoptimizeFunction(closure);
+ %ClearFunctionTypeFeedback(closure);
+ %ClearFunctionTypeFeedback(constructor);
}
-function TestInAllContexts(constructor) {
- function value_context(a, b, counter) {
- var obj = new constructor(a, b, counter);
- return obj.x;
- }
- function test_context(a, b, counter) {
- if (!new constructor(a, b, counter)) {
- assertUnreachable("should not happen");
- }
- return a + b;
- }
- function effect_context(a, b, counter) {
- new constructor(a, b, counter);
- return a + b;
+function value_context(constructor, val, deopt, counter) {
+ var obj = new constructor(val, deopt, counter);
+ return obj.x;
+}
+
+function test_context(constructor, val, deopt, counter) {
+ if (!new constructor(val, deopt, counter)) {
+ assertUnreachable("should not happen");
}
- TestInlinedConstructor(value_context);
- TestInlinedConstructor(test_context);
- TestInlinedConstructor(effect_context);
- %DeoptimizeFunction(value_context);
- %DeoptimizeFunction(test_context);
- %DeoptimizeFunction(effect_context);
- %ClearFunctionTypeFeedback(value_context);
- %ClearFunctionTypeFeedback(test_context);
- %ClearFunctionTypeFeedback(effect_context);
+ return val;
+}
+
+function effect_context(constructor, val, deopt, counter) {
+ new constructor(val, deopt, counter);
+ return val;
+}
+
+function TestInAllContexts(constructor) {
+ TestInlinedConstructor(constructor, value_context);
+ TestInlinedConstructor(constructor, test_context);
+ TestInlinedConstructor(constructor, effect_context);
}
// Test constructor returning nothing in all contexts.
-function c1(a, b, counter) {
- this.x = a + b;
+function c1(val, deopt, counter) {
+ deopt.deopt;
+ this.x = val;
counter.value++;
}
TestInAllContexts(c1);
// Test constructor returning an object in all contexts.
-function c2(a, b, counter) {
- var obj = new Object();
- obj.x = a + b;
+function c2(val, deopt, counter) {
+ var obj = {};
+ deopt.deopt;
+ obj.x = val;
counter.value++;
return obj;
}
@@ -93,8 +102,9 @@ TestInAllContexts(c2);
// Test constructor returning a primitive value in all contexts.
-function c3(a, b, counter) {
- this.x = a + b;
+function c3(val, deopt, counter) {
+ deopt.deopt;
+ this.x = val;
counter.value++;
return "not an object";
}
@@ -133,9 +143,10 @@ assertEquals("foo1", f_too_few("foo"))
// Test constructor that cannot be inlined.
-function c_unsupported_syntax(a, b, counter) {
+function c_unsupported_syntax(val, deopt, counter) {
try {
- this.x = a + b;
+ deopt.deopt;
+ this.x = val;
counter.value++;
} catch(e) {
throw new Error();
@@ -146,9 +157,10 @@ TestInAllContexts(c_unsupported_syntax);
// Regression test: Inlined constructors called as functions do not get their
// implicit receiver object set to undefined, even in strict mode.
-function c_strict(a, b, counter) {
+function c_strict(val, deopt, counter) {
"use strict";
- this.x = a + b;
+ deopt.deopt;
+ this.x = val;
counter.value++;
}
TestInAllContexts(c_strict);
diff --git a/deps/v8/test/mjsunit/compiler/inline-literals.js b/deps/v8/test/mjsunit/compiler/inline-literals.js
index f78abe82d..142258691 100644
--- a/deps/v8/test/mjsunit/compiler/inline-literals.js
+++ b/deps/v8/test/mjsunit/compiler/inline-literals.js
@@ -29,6 +29,26 @@
// Test that we can inline functions containing materialized literals.
+function a2(b, c) {
+ return [b, c, b + c];
+}
+
+function a1(a, b, c) {
+ return [a, a2(b, c)];
+}
+
+function TestArrayLiteral(a, b, c) {
+ var expected = [a, [b, c, b + c]];
+ var result = a1(a, b, c);
+ assertEquals(expected, result, "TestArrayLiteral");
+}
+
+TestArrayLiteral(1, 2, 3);
+TestArrayLiteral(1, 2, 3);
+%OptimizeFunctionOnNextCall(TestArrayLiteral);
+TestArrayLiteral(1, 2, 3);
+TestArrayLiteral('a', 'b', 'c');
+
function o2(b, c) {
return { 'b':b, 'c':c, 'y':b + c };
}
@@ -48,3 +68,22 @@ TestObjectLiteral(1, 2, 3);
%OptimizeFunctionOnNextCall(TestObjectLiteral);
TestObjectLiteral(1, 2, 3);
TestObjectLiteral('a', 'b', 'c');
+
+function r2(s, x, y) {
+ return s.replace(/a/, x + y);
+}
+
+function r1(s, x, y) {
+ return r2(s, x, y).replace(/b/, y + x);
+}
+
+function TestRegExpLiteral(s, x, y, expected) {
+ var result = r1(s, x, y);
+ assertEquals(expected, result, "TestRegExpLiteral");
+}
+
+TestRegExpLiteral("a-", "reg", "exp", "regexp-");
+TestRegExpLiteral("-b", "reg", "exp", "-expreg");
+%OptimizeFunctionOnNextCall(TestRegExpLiteral);
+TestRegExpLiteral("ab", "reg", "exp", "regexpexpreg");
+TestRegExpLiteral("ab", 12345, 54321, "6666666666");
diff --git a/deps/v8/test/mjsunit/compiler/optimized-closures.js b/deps/v8/test/mjsunit/compiler/optimized-closures.js
new file mode 100644
index 000000000..eaf75f8d0
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/optimized-closures.js
@@ -0,0 +1,57 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+// Test optimized closures.
+
+var a = new Array(100);
+
+function f() {
+ var x=0;
+ for (var i=0; i<100; i++) {
+ var g = function goo(y) {
+ function h() {
+ if (goo.arguments[0] == 23) return -42;
+ return 42;
+ }
+ return x + y + h(y);
+ }
+ g(0);
+ %OptimizeFunctionOnNextCall(g);
+ a[i] = g(i);
+ }
+}
+
+f();
+assertEquals(42, a[0]);
+assertEquals(49, a[7]);
+assertEquals(-19, a[23]);
+
+
+
+
diff --git a/deps/v8/test/mjsunit/compiler/regress-gvn.js b/deps/v8/test/mjsunit/compiler/regress-gvn.js
index 358daf711..01b1aa9a6 100644
--- a/deps/v8/test/mjsunit/compiler/regress-gvn.js
+++ b/deps/v8/test/mjsunit/compiler/regress-gvn.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --noalways-opt
+// Flags: --noalways-opt --allow-natives-syntax
//
// Regression test for global value numbering.
@@ -39,10 +39,11 @@ function test(a) {
var a = new Array();
-var n = 100000000;
+var n = 100;
var result = 0;
for (var i = 0; i < n; ++i) {
+ if (i == 10) %OptimizeFunctionOnNextCall(test);
a[0] = 0;
result += test(a);
}
diff --git a/deps/v8/test/mjsunit/compiler/regress-or.js b/deps/v8/test/mjsunit/compiler/regress-or.js
index 89f78025f..939f2c3ff 100644
--- a/deps/v8/test/mjsunit/compiler/regress-or.js
+++ b/deps/v8/test/mjsunit/compiler/regress-or.js
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
// Test deoptimization inside short-circuited expressions.
function f1(x) {
var c = "fail";
@@ -36,7 +38,8 @@ function f1(x) {
function g1() { try { return 1; } finally {} }
-for (var i=0; i<10000000; i++) f1(42);
+for (var i = 0; i < 5; i++) f1(42);
+%OptimizeFunctionOnNextCall(f1);
assertEquals(-1, f1(0));
assertEquals(-43, f1(42));
@@ -52,6 +55,7 @@ function f2(x) {
function g2() { try { return 0; } finally {} }
-for (var i=0; i<10000000; i++) f2(42);
+for (var i = 0; i < 5; i++) f2(42);
+%OptimizeFunctionOnNextCall(f2);
assertEquals(-1, f2(""));
diff --git a/deps/v8/test/mjsunit/compiler/uint32.js b/deps/v8/test/mjsunit/compiler/uint32.js
new file mode 100644
index 000000000..abed28583
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/uint32.js
@@ -0,0 +1,173 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+// Test uint32 handing in optimized frames.
+
+var K1 = 0x7fffffff;
+var K2 = 0xffffffff;
+
+var uint32_array = new Uint32Array(2);
+uint32_array[0] = K1;
+uint32_array[1] = K2;
+
+function ChangeI2T(arr, i) {
+ return uint32_array[i];
+}
+
+assertEquals(K1, ChangeI2T(uint32_array, 0));
+assertEquals(K2, ChangeI2T(uint32_array, 1));
+%OptimizeFunctionOnNextCall(ChangeI2T);
+assertEquals(K1, ChangeI2T(uint32_array, 0));
+// Loop to force inline allocation failure and a call into runtime.
+for (var i = 0; i < 80000; i++) {
+ assertEquals(K2, ChangeI2T(uint32_array, 1));
+}
+
+function SideEffect() {
+ with ({}) { } // not inlinable
+}
+
+function Deopt(obj, arr, i) {
+ var x = arr[i];
+ SideEffect(); // x will be used by HSimulate.
+ obj.x;
+ return x;
+}
+
+assertEquals(K1, Deopt({x: 0}, uint32_array, 0));
+assertEquals(K2, Deopt({x: 0}, uint32_array, 1));
+%OptimizeFunctionOnNextCall(Deopt);
+assertEquals(K2, Deopt({}, uint32_array, 1));
+
+function ChangeI2D(arr) {
+ // This addition will have a double type feedback so ChangeI2D will
+ // be generated for its operands.
+ return arr[0] + arr[1];
+}
+
+assertEquals(K1 + K2, ChangeI2D(uint32_array));
+assertEquals(K1 + K2, ChangeI2D(uint32_array));
+%OptimizeFunctionOnNextCall(ChangeI2D);
+assertEquals(K1 + K2, ChangeI2D(uint32_array));
+
+function ShrShr(val) {
+ return (val >>> 0) >>> 1;
+}
+
+assertEquals(K1, ShrShr(K2 | 0));
+assertEquals(K1, ShrShr(K2 | 0));
+%OptimizeFunctionOnNextCall(ShrShr);
+assertEquals(K1, ShrShr(K2 | 0));
+
+function SarShr(val) {
+ return val >> (-2 >>> 0);
+}
+
+var K3 = 0x80000000;
+assertEquals(-2, SarShr(K3 | 0));
+assertEquals(-2, SarShr(K3 | 0));
+%OptimizeFunctionOnNextCall(SarShr);
+assertEquals(-2, SarShr(K3 | 0));
+
+function Uint32Phi(a, b, c) {
+ var i = a ? (b >>> 0) : (c >>> 0);
+ return (i | 0);
+}
+
+var K4 = 0x80000001;
+assertEquals(K3 | 0, Uint32Phi(true, K3, K4));
+assertEquals(K4 | 0, Uint32Phi(false, K3, K4));
+assertEquals(K3 | 0, Uint32Phi(true, K3, K4));
+assertEquals(K4 | 0, Uint32Phi(false, K3, K4));
+%OptimizeFunctionOnNextCall(Uint32Phi);
+assertEquals(K3 | 0, Uint32Phi(true, K3, K4));
+assertEquals(K4 | 0, Uint32Phi(false, K3, K4));
+
+function NonUint32Phi(a, b, c) {
+ var i = a ? (b >>> 0) : c;
+ return (i | 0);
+}
+
+assertEquals(K3 | 0, NonUint32Phi(true, K3, K4));
+assertEquals(K4 | 0, NonUint32Phi(false, K3, K4));
+assertEquals(K3 | 0, NonUint32Phi(true, K3, K4));
+assertEquals(K4 | 0, NonUint32Phi(false, K3, K4));
+%OptimizeFunctionOnNextCall(NonUint32Phi);
+assertEquals(K3 | 0, NonUint32Phi(true, K3, K4));
+assertEquals(K4 | 0, NonUint32Phi(false, K3, K4));
+
+function PhiOfPhi(x) {
+ var a = (x >>> 0);
+ for (var i = 0; i < 2; i++) {
+ for (var j = 0; j < 2; j++) {
+ a = (a >>> 0);
+ }
+ }
+ return (a | 0);
+}
+
+assertEquals(1, PhiOfPhi(1));
+assertEquals(1, PhiOfPhi(1));
+%OptimizeFunctionOnNextCall(PhiOfPhi);
+assertEquals(K3 | 0, PhiOfPhi(K3));
+
+function PhiOfPhiUnsafe(x) {
+ var a = x >>> 0;
+ for (var i = 0; i < 2; i++) {
+ for (var j = 0; j < 2; j++) {
+ a = (a >>> 0);
+ }
+ }
+ return a + a;
+}
+
+assertEquals(2, PhiOfPhiUnsafe(1));
+assertEquals(2, PhiOfPhiUnsafe(1));
+%OptimizeFunctionOnNextCall(PhiOfPhiUnsafe);
+assertEquals(2 * K3, PhiOfPhiUnsafe(K3));
+
+var old_array = new Array(1000);
+
+for (var i = 0; i < old_array.length; i++) old_array[i] = null;
+
+// Force promotion.
+gc();
+gc();
+
+function FillOldArrayWithHeapNumbers(N) {
+ for (var i = 0; i < N; i++) {
+ old_array[i] = uint32_array[1];
+ }
+}
+
+FillOldArrayWithHeapNumbers(1);
+FillOldArrayWithHeapNumbers(1);
+%OptimizeFunctionOnNextCall(FillOldArrayWithHeapNumbers);
+FillOldArrayWithHeapNumbers(old_array.length);
+gc();
diff --git a/deps/v8/test/mjsunit/count-based-osr.js b/deps/v8/test/mjsunit/count-based-osr.js
index 125c4e26d..fbff91e4a 100644
--- a/deps/v8/test/mjsunit/count-based-osr.js
+++ b/deps/v8/test/mjsunit/count-based-osr.js
@@ -25,7 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --count-based-interrupts --interrupt-budget=10 --weighted-back-edges --allow-natives-syntax
+// Flags: --count-based-interrupts --interrupt-budget=10 --weighted-back-edges
+// Flags: --allow-natives-syntax --noparallel-recompilation
// Test that OSR works properly when using count-based interrupting/profiling.
diff --git a/deps/v8/test/mjsunit/d8-os.js b/deps/v8/test/mjsunit/d8-os.js
index 239938cd1..f6b98396e 100644
--- a/deps/v8/test/mjsunit/d8-os.js
+++ b/deps/v8/test/mjsunit/d8-os.js
@@ -129,13 +129,13 @@ if (this.os && os.system) {
have_echo = false;
}
if (have_sleep) {
- assertThrows("os.system('sleep', ['2000'], 200);", "sleep 1");
+ assertThrows("os.system('sleep', ['2000'], 20);", "sleep 1");
// Check we time out with total time.
- assertThrows("os.system('sleep', ['2000'], -1, 200);", "sleep 2");
+ assertThrows("os.system('sleep', ['2000'], -1, 20);", "sleep 2");
// Check that -1 means no timeout.
- os.system('sleep', ['1'], -1, -1);
+ os.system('sleep', ['0.1'], -1, -1);
}
diff --git a/deps/v8/test/mjsunit/date.js b/deps/v8/test/mjsunit/date.js
index 3e153aba7..5aaa3bb94 100644
--- a/deps/v8/test/mjsunit/date.js
+++ b/deps/v8/test/mjsunit/date.js
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
// Test date construction from other dates.
var date0 = new Date(1111);
var date1 = new Date(date0);
@@ -319,3 +321,23 @@ for (var i = 0; i < 24; i++) {
assertEquals(70674603500 - ms, Date.parse(string), string);
}
}
+
+assertThrows('Date.prototype.setTime.call("", 1);', TypeError);
+assertThrows('Date.prototype.setYear.call("", 1);', TypeError);
+assertThrows('Date.prototype.setHours.call("", 1, 2, 3, 4);', TypeError);
+assertThrows('Date.prototype.getDate.call("");', TypeError);
+assertThrows('Date.prototype.getUTCDate.call("");', TypeError);
+
+var date = new Date();
+date.getTime();
+date.getTime();
+%OptimizeFunctionOnNextCall(Date.prototype.getTime);
+assertThrows(function() { Date.prototype.getTime.call(""); }, TypeError);
+assertTrue(%GetOptimizationStatus(Date.prototype.getTime) != 1);
+
+date.getYear();
+date.getYear();
+%OptimizeFunctionOnNextCall(Date.prototype.getYear);
+assertThrows(function() { Date.prototype.getYear.call(""); }, TypeError);
+opt_status = %GetOptimizationStatus(Date.prototype.getYear);
+assertTrue(%GetOptimizationStatus(Date.prototype.getTime) != 1); \ No newline at end of file
diff --git a/deps/v8/test/mjsunit/debug-break-inline.js b/deps/v8/test/mjsunit/debug-break-inline.js
index 4418fa8d1..464cb7363 100644
--- a/deps/v8/test/mjsunit/debug-break-inline.js
+++ b/deps/v8/test/mjsunit/debug-break-inline.js
@@ -26,6 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --allow-natives-syntax
+// Flags: --noparallel-recompilation
// This test tests that deoptimization due to debug breaks works for
// inlined functions where the full-code is generated before the
diff --git a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js
index efbb2cc8c..8d91b973c 100644
--- a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js
+++ b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js
@@ -25,7 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-debug-as debug --expose-gc --allow-natives-syntax --inline-construct
+// Flags: --expose-debug-as debug --expose-gc --allow-natives-syntax
+// Flags: --inline-construct
+
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
@@ -43,13 +45,17 @@ var input = [
];
var expected = [
- { locals: {a0: 1.01, b0: 2.02}, args: { names: ["i", "x0", "y0"], values: [0, 3.03, 4.04] } },
- { locals: {a1: 3.03, b1: 4.04}, args: { names: ["i", "x1", "y1"], values: [1, 5.05, 6.06] } },
- { locals: {a2: 5.05, b2: 6.06}, args: { names: ["i"], values: [2] } },
- { locals: {a3: 7.07, b3: 8.08}, args: { names: ["i", "x3", "y3", "z3"],
- values: [3, 9.09, 10.10, undefined] }
- },
- { locals: {a4: 9.09, b4: 10.10}, args: { names: ["i", "x4", "y4"], values: [4, 11.11, 12.12] } }
+ { locals: {a0: 1.01, b0: 2.02},
+ args: { names: ["i", "x0", "y0"], values: [0, 3.03, 4.04] } },
+ { locals: {a1: 3.03, b1: 4.04},
+ args: { names: ["i", "x1", "y1"], values: [1, 5.05, 6.06] } },
+ { locals: {a2: 5.05, b2: 6.06},
+ args: { names: ["i"], values: [2] } },
+ { locals: {a3: 7.07, b3: 8.08},
+ args: { names: ["i", "x3", "y3", "z3"],
+ values: [3, 9.09, 10.10, undefined] } },
+ { locals: {a4: 9.09, b4: 10.10},
+ args: { names: ["i", "x4", "y4"], values: [4, 11.11, 12.12] } }
];
function arraySum(arr) {
@@ -78,7 +84,8 @@ function listener(event, exec_state, event_data, data) {
// All frames except the bottom one have expected arguments.
for (var j = 0; j < expected_args.names.length; j++) {
assertEquals(expected_args.names[j], frame.argumentName(j));
- assertEquals(expected_args.values[j], frame.argumentValue(j).value());
+ assertEquals(expected_args.values[j],
+ frame.argumentValue(j).value());
}
// All frames except the bottom one have two scopes.
@@ -87,13 +94,15 @@ function listener(event, exec_state, event_data, data) {
assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
Object.keys(expected_locals).forEach(function (name) {
- assertEquals(expected_locals[name], frame.scope(0).scopeObject().value()[name]);
+ assertEquals(expected_locals[name],
+ frame.scope(0).scopeObject().value()[name]);
});
for (var j = 0; j < expected_args.names.length; j++) {
var arg_name = expected_args.names[j];
var arg_value = expected_args.values[j];
- assertEquals(arg_value, frame.scope(0).scopeObject().value()[arg_name]);
+ assertEquals(arg_value,
+ frame.scope(0).scopeObject().value()[arg_name]);
}
// Evaluate in the inlined frame.
@@ -114,7 +123,8 @@ function listener(event, exec_state, event_data, data) {
map(function (k) { return expected_locals[k]; }));
assertEquals(expected_locals_sum + expected_args_sum,
- frame.evaluate(Object.keys(expected_locals).join('+') + ' + ' +
+ frame.evaluate(Object.keys(expected_locals).join('+') +
+ ' + ' +
expected_args.names.join('+')).value());
var arguments_sum = expected_args.names.map(function(_, idx) {
diff --git a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js
index 9c56a12be..f66291288 100644
--- a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js
+++ b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js
@@ -25,7 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-debug-as debug --expose-gc --allow-natives-syntax --inline-construct
+// Flags: --expose-debug-as debug --expose-gc --allow-natives-syntax
+// Flags: --inline-construct
+
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
@@ -35,11 +37,16 @@ var exception = false;
var testingConstructCall = false;
var expected = [
- { locals: {a0: 1, b0: 2}, args: { names: ["i", "x0", "y0"], values: [0, 3, 4] } },
- { locals: {a1: 3, b1: 4}, args: { names: ["i", "x1", "y1"], values: [1, 5, 6] } },
- { locals: {a2: 5, b2: 6}, args: { names: ["i"], values: [2] } },
- { locals: {a3: 7, b3: 8}, args: { names: ["i", "x3", "y3", "z3"], values: [3, 9, 10, undefined] } },
- { locals: {a4: 9, b4: 10}, args: { names: ["i", "x4", "y4"], values: [4, 11, 12] } }
+ { locals: {a0: 1, b0: 2},
+ args: { names: ["i", "x0", "y0"], values: [0, 3, 4] } },
+ { locals: {a1: 3, b1: 4},
+ args: { names: ["i", "x1", "y1"], values: [1, 5, 6] } },
+ { locals: {a2: 5, b2: 6},
+ args: { names: ["i"], values: [2] } },
+ { locals: {a3: 7, b3: 8},
+ args: { names: ["i", "x3", "y3", "z3"], values: [3, 9, 10, undefined] } },
+ { locals: {a4: 9, b4: 10},
+ args: { names: ["i", "x4", "y4"], values: [4, 11, 12] } }
];
function arraySum(arr) {
@@ -68,7 +75,8 @@ function listener(event, exec_state, event_data, data) {
// All frames except the bottom one have expected arguments.
for (var j = 0; j < expected_args.names.length; j++) {
assertEquals(expected_args.names[j], frame.argumentName(j));
- assertEquals(expected_args.values[j], frame.argumentValue(j).value());
+ assertEquals(expected_args.values[j],
+ frame.argumentValue(j).value());
}
// All frames except the bottom one have two scopes.
@@ -77,13 +85,15 @@ function listener(event, exec_state, event_data, data) {
assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
Object.keys(expected_locals).forEach(function (name) {
- assertEquals(expected_locals[name], frame.scope(0).scopeObject().value()[name]);
+ assertEquals(expected_locals[name],
+ frame.scope(0).scopeObject().value()[name]);
});
for (var j = 0; j < expected_args.names.length; j++) {
var arg_name = expected_args.names[j];
var arg_value = expected_args.values[j];
- assertEquals(arg_value, frame.scope(0).scopeObject().value()[arg_name]);
+ assertEquals(arg_value,
+ frame.scope(0).scopeObject().value()[arg_name]);
}
// Evaluate in the inlined frame.
@@ -104,7 +114,8 @@ function listener(event, exec_state, event_data, data) {
map(function (k) { return expected_locals[k]; }));
assertEquals(expected_locals_sum + expected_args_sum,
- frame.evaluate(Object.keys(expected_locals).join('+') + ' + ' +
+ frame.evaluate(Object.keys(expected_locals).join('+') +
+ ' + ' +
expected_args.names.join('+')).value());
var arguments_sum = expected_args.names.map(function(_, idx) {
diff --git a/deps/v8/test/mjsunit/debug-liveedit-double-call.js b/deps/v8/test/mjsunit/debug-liveedit-double-call.js
new file mode 100644
index 000000000..1df806ab7
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-liveedit-double-call.js
@@ -0,0 +1,142 @@
+// Copyright 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.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+
+Debug = debug.Debug
+
+
+function TestCase(test_scenario, expected_output) {
+ // Global variable, accessed from eval'd script.
+ test_output = "";
+
+ var script_text_generator = (function() {
+ var variables = { a: 1, b: 1, c: 1, d: 1, e: 1, f: 1 };
+
+ return {
+ get: function() {
+ return "(function() {\n " +
+ " function A() {\n " +
+ " test_output += 'a' + " + variables.a + ";\n " +
+ " test_output += '=';\n " +
+ " debugger;\n " +
+ " return 'Capybara';\n " +
+ " }\n " +
+ " function B(p1, p2) {\n " +
+ " test_output += 'b' + " + variables.b + ";\n " +
+ " return A();\n " +
+ " }\n " +
+ " function C() {\n " +
+ " test_output += 'c' + " + variables.c + ";\n " +
+ " // Function call with argument adaptor is intentional.\n " +
+ " return B();\n " +
+ " }\n " +
+ " function D() {\n " +
+ " test_output += 'd' + " + variables.d + ";\n " +
+ " // Function call with argument adaptor is intentional.\n " +
+ " return C(1, 2);\n " +
+ " }\n " +
+ " function E() {\n " +
+ " test_output += 'e' + " + variables.e + ";\n " +
+ " return D();\n " +
+ " }\n " +
+ " function F() {\n " +
+ " test_output += 'f' + " + variables.f + ";\n " +
+ " return E();\n " +
+ " }\n " +
+ " return F();\n " +
+ "})\n";
+ },
+ change: function(var_name) {
+ variables[var_name]++;
+ }
+ };
+ })();
+
+ var test_fun = eval(script_text_generator.get());
+
+ var script = Debug.findScript(test_fun);
+
+ var scenario_pos = 0;
+
+ function DebuggerStatementHandler() {
+ while (true) {
+ assertTrue(scenario_pos < test_scenario.length);
+ var change_var = test_scenario[scenario_pos++];
+ if (change_var == '=') {
+ // Continue.
+ return;
+ }
+ script_text_generator.change(change_var);
+ try {
+ Debug.LiveEdit.SetScriptSource(script, script_text_generator.get(),
+ false, []);
+ } catch (e) {
+ print("LiveEdit exception: " + e);
+ throw e;
+ }
+ }
+ }
+
+ var saved_exception = null;
+
+ function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ try {
+ DebuggerStatementHandler();
+ } catch (e) {
+ saved_exception = e;
+ }
+ } else {
+ print("Other: " + event);
+ }
+ }
+
+ Debug.setListener(listener);
+ assertEquals("Capybara", test_fun());
+ Debug.setListener(null);
+
+ if (saved_exception) {
+ print("Exception: " + saved_exception);
+ assertUnreachable();
+ }
+
+ print(test_output);
+
+ assertEquals(expected_output, test_output);
+}
+
+TestCase(['='], "f1e1d1c1b1a1=");
+
+TestCase(['c', '=', '='], "f1e1d1c1b1a1=c2b1a1=");
+
+TestCase(['b', 'c', 'd', 'e', '=', '='], "f1e1d1c1b1a1=e2d2c2b2a1=");
+
+TestCase(['b', 'c', '=', 'b', 'c', 'd', 'e', '=', '='], "f1e1d1c1b1a1=c2b2a1=e2d2c3b3a1=");
+
+TestCase(['e', 'f', '=', '='], "f1e1d1c1b1a1=f2e2d1c1b1a1=");
diff --git a/deps/v8/test/mjsunit/debug-liveedit-restart-frame.js b/deps/v8/test/mjsunit/debug-liveedit-restart-frame.js
new file mode 100644
index 000000000..d978a9709
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-liveedit-restart-frame.js
@@ -0,0 +1,153 @@
+// Copyright 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.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+
+Debug = debug.Debug
+
+function FindCallFrame(exec_state, frame_code) {
+ var number = Number(frame_code);
+ if (number >= 0) {
+ return exec_state.frame(number);
+ } else {
+ for (var i = 0; i < exec_state.frameCount(); i++) {
+ var frame = exec_state.frame(i);
+ var func_mirror = frame.func();
+ if (frame_code == func_mirror.name()) {
+ return frame;
+ }
+ }
+ }
+ throw new Error("Failed to find function name " + function_name);
+}
+
+function TestCase(test_scenario, expected_output) {
+ // Global variable, accessed from eval'd script.
+ test_output = "";
+
+ function TestCode() {
+ function A() {
+ // Extra stack variable. To make function not slim.
+ // Restarter doesn't work on slim function when stopped on 'debugger'
+ // statement. (There is no padding for 'debugger' statement).
+ var o = {};
+ test_output += 'A';
+ test_output += '=';
+ debugger;
+ return 'Capybara';
+ }
+ function B(p1, p2) {
+ test_output += 'B';
+ return A();
+ }
+ function C() {
+ test_output += 'C';
+ // Function call with argument adaptor is intentional.
+ return B();
+ }
+ function D() {
+ test_output += 'D';
+ // Function call with argument adaptor is intentional.
+ return C(1, 2);
+ }
+ function E() {
+ test_output += 'E';
+ return D();
+ }
+ function F() {
+ test_output += 'F';
+ return E();
+ }
+ return F();
+ }
+
+ var scenario_pos = 0;
+
+ function DebuggerStatementHandler(exec_state) {
+ while (true) {
+ assertTrue(scenario_pos < test_scenario.length);
+ var change_code = test_scenario[scenario_pos++];
+ if (change_code == '=') {
+ // Continue.
+ return;
+ }
+ var frame = FindCallFrame(exec_state, change_code);
+ // Throws if fails.
+ Debug.LiveEdit.RestartFrame(frame);
+ }
+ }
+
+ var saved_exception = null;
+
+ function listener(event, exec_state, event_data, data) {
+ if (saved_exception != null) {
+ return;
+ }
+ if (event == Debug.DebugEvent.Break) {
+ try {
+ DebuggerStatementHandler(exec_state);
+ } catch (e) {
+ saved_exception = e;
+ }
+ } else {
+ print("Other: " + event);
+ }
+ }
+
+ Debug.setListener(listener);
+ assertEquals("Capybara", TestCode());
+ Debug.setListener(null);
+
+ if (saved_exception) {
+ print("Exception: " + saved_exception);
+ print("Stack: " + saved_exception.stack);
+ assertUnreachable();
+ }
+
+ print(test_output);
+
+ assertEquals(expected_output, test_output);
+}
+
+TestCase('0==', "FEDCBA=A=");
+TestCase('1==', "FEDCBA=BA=");
+TestCase('2==', "FEDCBA=CBA=");
+TestCase('3==', "FEDCBA=DCBA=");
+TestCase('4==', "FEDCBA=EDCBA=");
+TestCase('5==', "FEDCBA=FEDCBA=");
+
+TestCase('=', "FEDCBA=");
+
+TestCase('C==', "FEDCBA=CBA=");
+
+TestCase('B=C=A=D==', "FEDCBA=BA=CBA=A=DCBA=");
+
+// Successive restarts don't work now and require additional fix.
+//TestCase('BCDE==', "FEDCBA=EDCBA=");
+//TestCase('BC=BCDE==', "FEDCBA=CBA=EDCBA=");
+//TestCase('EF==', "FEDCBA=FEDCBA=");
diff --git a/deps/v8/test/mjsunit/debug-multiple-breakpoints.js b/deps/v8/test/mjsunit/debug-multiple-breakpoints.js
index 104741011..d8b1d943f 100644
--- a/deps/v8/test/mjsunit/debug-multiple-breakpoints.js
+++ b/deps/v8/test/mjsunit/debug-multiple-breakpoints.js
@@ -89,7 +89,7 @@ g();
assertEquals(3, break_point_hit_count);
// Finally test with many break points.
-test_count = 100;
+test_count = 10;
bps = new Array(test_count);
break_point_hit_count = 0;
for (var i = 0; i < test_count; i++) {
diff --git a/deps/v8/test/mjsunit/debug-script-breakpoints-closure.js b/deps/v8/test/mjsunit/debug-script-breakpoints-closure.js
new file mode 100644
index 000000000..7c89718f0
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-script-breakpoints-closure.js
@@ -0,0 +1,67 @@
+// Copyright 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.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+// Simple debug event handler which just counts the number of break points hit.
+var break_point_hit_count = 0;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ break_point_hit_count++;
+ }
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function makeClosure() {
+ var x;
+ return function() {
+ return x; // Breakpoint line ( #47 )
+ };
+}
+
+// Create closure before break point is set.
+var closure = makeClosure();
+
+// The debugger triggers re-compilation.
+assertEquals(0, Debug.scriptBreakPoints().length);
+var scr = Debug.findScript(makeClosure);
+var sbp = Debug.setScriptBreakPointById(scr.id, 47);
+assertEquals(1, Debug.scriptBreakPoints().length);
+
+// Ensure the closure actually triggers a break point hit.
+closure();
+assertEquals(1, break_point_hit_count);
+
+// Remove script break point.
+assertEquals(1, Debug.scriptBreakPoints().length);
+Debug.clearBreakPoint(sbp);
+assertEquals(0, Debug.scriptBreakPoints().length);
diff --git a/deps/v8/test/mjsunit/debug-script-breakpoints-nested.js b/deps/v8/test/mjsunit/debug-script-breakpoints-nested.js
new file mode 100644
index 000000000..ce25c1781
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-script-breakpoints-nested.js
@@ -0,0 +1,82 @@
+// Copyright 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.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+// Simple debug event handler which just counts the number of break points hit.
+var break_point_hit_count = 0;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ break_point_hit_count++;
+ }
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+eval(
+ "var inner;\n" +
+ "function outer() {\n" + // Non-trivial outer closure.
+ " var x = 5;\n" +
+ " function a() {\n" +
+ " var foo = 0, y = 7;\n" +
+ " function b() {\n" +
+ " var bar = 0, baz = 0, z = 11;\n" +
+ " function c() {\n" +
+ " return x + y + z;\n" + // Breakpoint line ( #8 )
+ " }\n" +
+ " inner = c;\n" +
+ " return c();\n" +
+ " }\n" +
+ " return b();\n" +
+ " }\n" +
+ " return a();\n" +
+ "}"
+);
+
+var script = Debug.findScript(outer);
+
+// The debugger triggers compilation of inner closures.
+assertEquals(0, Debug.scriptBreakPoints().length);
+var sbp = Debug.setScriptBreakPointById(script.id, 8);
+assertEquals(1, Debug.scriptBreakPoints().length);
+
+// The compiled outer closure should behave correctly.
+assertEquals(23, outer());
+assertEquals(1, break_point_hit_count);
+
+// The compiled inner closure should behave correctly.
+assertEquals(23, inner());
+assertEquals(2, break_point_hit_count);
+
+// Remove script break point.
+assertEquals(1, Debug.scriptBreakPoints().length);
+Debug.clearBreakPoint(sbp);
+assertEquals(0, Debug.scriptBreakPoints().length);
diff --git a/deps/v8/test/mjsunit/debug-script.js b/deps/v8/test/mjsunit/debug-script.js
index 9767888f7..b9dbc075e 100644
--- a/deps/v8/test/mjsunit/debug-script.js
+++ b/deps/v8/test/mjsunit/debug-script.js
@@ -25,9 +25,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-debug-as debug --expose-gc
+// Flags: --expose-debug-as debug --expose-gc --noparallel-recompilation
+// Flags: --send-idle-notification
+
// Get the Debug object exposed from the debug context global object.
-Debug = debug.Debug
+Debug = debug.Debug;
Date();
RegExp();
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part1.js b/deps/v8/test/mjsunit/debug-stepout-scope-part1.js
new file mode 100644
index 000000000..f2f9d9141
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part1.js
@@ -0,0 +1,190 @@
+// Copyright 2011 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.
+
+// Flags: --expose-debug-as debug --expose-natives-as=builtins
+
+// Check that the ScopeIterator can properly recreate the scope at
+// every point when stepping through functions.
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ // Access scope details.
+ var scope_count = exec_state.frame().scopeCount();
+ for (var i = 0; i < scope_count; i++) {
+ var scope = exec_state.frame().scope(i);
+ // assertTrue(scope.isScope());
+ scope.scopeType();
+ scope.scopeObject();
+ }
+
+ // Do steps until we reach the global scope again.
+ if (true) {
+ exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
+ }
+ }
+}
+
+Debug.setListener(listener);
+
+
+function test1() {
+ debugger;
+ with ({x:1}) {
+ x = 2;
+ }
+}
+test1();
+
+
+function test2() {
+ if (true) {
+ with ({}) {
+ debugger;
+ }
+ } else {
+ with ({}) {
+ return 10;
+ }
+ }
+}
+test2();
+
+
+function test3() {
+ if (true) {
+ debugger;
+ } else {
+ with ({}) {
+ return 10;
+ }
+ }
+}
+test3();
+
+
+function test4() {
+ debugger;
+ with ({x:1}) x = 1
+}
+test4();
+
+
+function test5() {
+ debugger;
+ var dummy = 1;
+ with ({}) {
+ with ({}) {
+ dummy = 2;
+ }
+ }
+ dummy = 3;
+}
+test5();
+
+
+function test6() {
+ debugger;
+ try {
+ throw 'stuff';
+ } catch (e) {
+ e = 1;
+ }
+}
+test6();
+
+
+function test7() {
+ debugger;
+ function foo() {}
+}
+test7();
+
+
+function test8() {
+ debugger;
+ (function foo() {})();
+}
+test8();
+
+
+function test10() {
+ debugger;
+ with ({}) {
+ return 10;
+ }
+}
+test10();
+
+
+function test11() {
+ debugger;
+ try {
+ throw 'stuff';
+ } catch (e) {
+ return 10;
+ }
+}
+test11();
+
+
+var prefixes = [
+ "debugger; ",
+ "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ];
+
+
+// Return from function constructed with Function constructor.
+var anon = 12;
+for (var i = 0; i < prefixes.length; ++i) {
+ var pre = prefixes[i];
+ Function(pre + "return 42")();
+ Function(pre + "return 42 ")();
+ Function(pre + "return 42;")();
+ Function(pre + "return 42; ")();
+ Function(pre + "return anon")();
+ Function(pre + "return anon ")();
+ Function(pre + "return anon;")();
+ Function(pre + "return anon; ")();
+}
+
+
+try {
+ with({}) {
+ debugger;
+ eval("{}$%:^");
+ }
+} catch(e) {
+ nop();
+}
+
+
+function nop() {}
+
+
+// With block as the last(!) statement in global code.
+with ({}) { debugger; } \ No newline at end of file
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part2.js b/deps/v8/test/mjsunit/debug-stepout-scope-part2.js
new file mode 100644
index 000000000..121c7b74d
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part2.js
@@ -0,0 +1,83 @@
+// Copyright 2011 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.
+
+// Flags: --expose-debug-as debug --expose-natives-as=builtins
+
+// Check that the ScopeIterator can properly recreate the scope at
+// every point when stepping through functions.
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ // Access scope details.
+ var scope_count = exec_state.frame().scopeCount();
+ for (var i = 0; i < scope_count; i++) {
+ var scope = exec_state.frame().scope(i);
+ // assertTrue(scope.isScope());
+ scope.scopeType();
+ scope.scopeObject();
+ }
+
+ // Do steps until we reach the global scope again.
+ if (true) {
+ exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
+ }
+ }
+}
+
+Debug.setListener(listener);
+
+var q = 42;
+var prefixes = [ "debugger; ",
+ "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ];
+var bodies = [ "1",
+ "1 ",
+ "1;",
+ "1; ",
+ "q",
+ "q ",
+ "q;",
+ "q; ",
+ "try { throw 'stuff' } catch (e) { e = 1; }",
+ "try { throw 'stuff' } catch (e) { e = 1; } ",
+ "try { throw 'stuff' } catch (e) { e = 1; };",
+ "try { throw 'stuff' } catch (e) { e = 1; }; " ];
+
+
+function test9() {
+ debugger;
+ for (var i = 0; i < prefixes.length; ++i) {
+ var pre = prefixes[i];
+ for (var j = 0; j < bodies.length; ++j) {
+ var body = bodies[j];
+ eval(pre + body);
+ eval("'use strict'; " + pre + body);
+ }
+ }
+}
+test9();
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part3.js b/deps/v8/test/mjsunit/debug-stepout-scope-part3.js
new file mode 100644
index 000000000..16b085e54
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part3.js
@@ -0,0 +1,80 @@
+// Copyright 2011 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.
+
+// Flags: --expose-debug-as debug --expose-natives-as=builtins
+
+// Check that the ScopeIterator can properly recreate the scope at
+// every point when stepping through functions.
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ // Access scope details.
+ var scope_count = exec_state.frame().scopeCount();
+ for (var i = 0; i < scope_count; i++) {
+ var scope = exec_state.frame().scope(i);
+ // assertTrue(scope.isScope());
+ scope.scopeType();
+ scope.scopeObject();
+ }
+
+ // Do steps until we reach the global scope again.
+ if (true) {
+ exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
+ }
+ }
+}
+
+Debug.setListener(listener);
+
+var q = 42;
+var prefixes = [
+ "debugger; ",
+ "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ];
+var with_bodies = [ "with ({}) {}",
+ "with ({x:1}) x",
+ "with ({x:1}) x = 1",
+ "with ({x:1}) x ",
+ "with ({x:1}) x = 1 ",
+ "with ({x:1}) x;",
+ "with ({x:1}) x = 1;",
+ "with ({x:1}) x; ",
+ "with ({x:1}) x = 1; " ];
+
+
+function test9() {
+ debugger;
+ for (var i = 0; i < prefixes.length; ++i) {
+ var pre = prefixes[i];
+ for (var j = 0; j < with_bodies.length; ++j) {
+ var body = with_bodies[j];
+ eval(pre + body);
+ }
+ }
+}
+test9();
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part4.js b/deps/v8/test/mjsunit/debug-stepout-scope-part4.js
new file mode 100644
index 000000000..48f43477d
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part4.js
@@ -0,0 +1,80 @@
+// Copyright 2011 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.
+
+// Flags: --expose-debug-as debug --expose-natives-as=builtins
+
+// Check that the ScopeIterator can properly recreate the scope at
+// every point when stepping through functions.
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ // Access scope details.
+ var scope_count = exec_state.frame().scopeCount();
+ for (var i = 0; i < scope_count; i++) {
+ var scope = exec_state.frame().scope(i);
+ // assertTrue(scope.isScope());
+ scope.scopeType();
+ scope.scopeObject();
+ }
+
+ // Do steps until we reach the global scope again.
+ if (true) {
+ exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
+ }
+ }
+}
+
+Debug.setListener(listener);
+
+var q = 42;
+var prefixes = [
+ "debugger; ",
+ "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ];
+var bodies = [ "1",
+ "1 ",
+ "1;",
+ "1; ",
+ "q",
+ "q ",
+ "q;",
+ "q; ",
+ "try { throw 'stuff' } catch (e) { e = 1; }",
+ "try { throw 'stuff' } catch (e) { e = 1; } ",
+ "try { throw 'stuff' } catch (e) { e = 1; };",
+ "try { throw 'stuff' } catch (e) { e = 1; }; " ];
+
+
+// Test global eval and function constructor.
+for (var i = 0; i < prefixes.length; ++i) {
+ var pre = prefixes[i];
+ for (var j = 0; j < bodies.length; ++j) {
+ var body = bodies[j];
+ eval(pre + body);
+ }
+}
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part5.js b/deps/v8/test/mjsunit/debug-stepout-scope-part5.js
new file mode 100644
index 000000000..f060ec388
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part5.js
@@ -0,0 +1,77 @@
+// Copyright 2011 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.
+
+// Flags: --expose-debug-as debug --expose-natives-as=builtins
+
+// Check that the ScopeIterator can properly recreate the scope at
+// every point when stepping through functions.
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ // Access scope details.
+ var scope_count = exec_state.frame().scopeCount();
+ for (var i = 0; i < scope_count; i++) {
+ var scope = exec_state.frame().scope(i);
+ // assertTrue(scope.isScope());
+ scope.scopeType();
+ scope.scopeObject();
+ }
+
+ // Do steps until we reach the global scope again.
+ if (true) {
+ exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
+ }
+ }
+}
+
+Debug.setListener(listener);
+
+var q = 42;
+var prefixes = [ "debugger; ",
+ "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ];
+var with_bodies = [ "with ({}) {}",
+ "with ({x:1}) x",
+ "with ({x:1}) x = 1",
+ "with ({x:1}) x ",
+ "with ({x:1}) x = 1 ",
+ "with ({x:1}) x;",
+ "with ({x:1}) x = 1;",
+ "with ({x:1}) x; ",
+ "with ({x:1}) x = 1; " ];
+
+
+// Test global eval and function constructor.
+for (var i = 0; i < prefixes.length; ++i) {
+ var pre = prefixes[i];
+ for (var j = 0; j < with_bodies.length; ++j) {
+ var body = with_bodies[j];
+ eval(pre + body);
+ Function(pre + body)();
+ }
+}
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part6.js b/deps/v8/test/mjsunit/debug-stepout-scope-part6.js
new file mode 100644
index 000000000..f7c8df0bc
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part6.js
@@ -0,0 +1,79 @@
+// Copyright 2011 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.
+
+// Flags: --expose-debug-as debug --expose-natives-as=builtins
+
+// Check that the ScopeIterator can properly recreate the scope at
+// every point when stepping through functions.
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ // Access scope details.
+ var scope_count = exec_state.frame().scopeCount();
+ for (var i = 0; i < scope_count; i++) {
+ var scope = exec_state.frame().scope(i);
+ // assertTrue(scope.isScope());
+ scope.scopeType();
+ scope.scopeObject();
+ }
+
+ // Do steps until we reach the global scope again.
+ if (true) {
+ exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
+ }
+ }
+}
+
+Debug.setListener(listener);
+
+var q = 42;
+var prefixes = [ "debugger; ",
+ "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ];
+var bodies = [ "1",
+ "1 ",
+ "1;",
+ "1; ",
+ "q",
+ "q ",
+ "q;",
+ "q; ",
+ "try { throw 'stuff' } catch (e) { e = 1; }",
+ "try { throw 'stuff' } catch (e) { e = 1; } ",
+ "try { throw 'stuff' } catch (e) { e = 1; };",
+ "try { throw 'stuff' } catch (e) { e = 1; }; " ];
+
+
+// Test global eval and function constructor.
+for (var i = 0; i < prefixes.length; ++i) {
+ var pre = prefixes[i];
+ for (var j = 0; j < bodies.length; ++j) {
+ var body = bodies[j];
+ eval("'use strict'; " + pre + body);
+ }
+}
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part7.js b/deps/v8/test/mjsunit/debug-stepout-scope-part7.js
new file mode 100644
index 000000000..4f0c06684
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part7.js
@@ -0,0 +1,79 @@
+// Copyright 2011 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.
+
+// Flags: --expose-debug-as debug --expose-natives-as=builtins
+
+// Check that the ScopeIterator can properly recreate the scope at
+// every point when stepping through functions.
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ // Access scope details.
+ var scope_count = exec_state.frame().scopeCount();
+ for (var i = 0; i < scope_count; i++) {
+ var scope = exec_state.frame().scope(i);
+ // assertTrue(scope.isScope());
+ scope.scopeType();
+ scope.scopeObject();
+ }
+
+ // Do steps until we reach the global scope again.
+ if (true) {
+ exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
+ }
+ }
+}
+
+Debug.setListener(listener);
+
+var q = 42;
+var prefixes = [ "debugger; ",
+ "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ];
+var bodies = [ "1",
+ "1 ",
+ "1;",
+ "1; ",
+ "q",
+ "q ",
+ "q;",
+ "q; ",
+ "try { throw 'stuff' } catch (e) { e = 1; }",
+ "try { throw 'stuff' } catch (e) { e = 1; } ",
+ "try { throw 'stuff' } catch (e) { e = 1; };",
+ "try { throw 'stuff' } catch (e) { e = 1; }; " ];
+
+
+// Test global eval and function constructor.
+for (var i = 0; i < prefixes.length; ++i) {
+ var pre = prefixes[i];
+ for (var j = 0; j < bodies.length; ++j) {
+ var body = bodies[j];
+ Function(pre + body)();
+ }
+}
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part8.js b/deps/v8/test/mjsunit/debug-stepout-scope-part8.js
new file mode 100644
index 000000000..f91fab5e4
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part8.js
@@ -0,0 +1,234 @@
+// Copyright 2011 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.
+
+// Flags: --expose-debug-as debug --expose-natives-as=builtins
+
+// Check that the ScopeIterator can properly recreate the scope at
+// every point when stepping through functions.
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ // Access scope details.
+ var scope_count = exec_state.frame().scopeCount();
+ for (var i = 0; i < scope_count; i++) {
+ var scope = exec_state.frame().scope(i);
+ // assertTrue(scope.isScope());
+ scope.scopeType();
+ scope.scopeObject();
+ }
+
+ // Do steps until we reach the global scope again.
+ if (true) {
+ exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
+ }
+ }
+}
+
+Debug.setListener(listener);
+
+
+function nop() {}
+
+
+function stress() {
+ debugger;
+
+ L: with ({x:12}) {
+ break L;
+ }
+
+
+ with ({x: 'outer'}) {
+ label: {
+ with ({x: 'inner'}) {
+ break label;
+ }
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ label: {
+ with ({x: 'inner'}) {
+ break label;
+ }
+ }
+ nop();
+ }
+
+
+ with ({x: 'outer'}) {
+ label: {
+ with ({x: 'middle'}) {
+ with ({x: 'inner'}) {
+ break label;
+ }
+ }
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ label: {
+ with ({x: 'middle'}) {
+ with ({x: 'inner'}) {
+ break label;
+ }
+ }
+ }
+ nop();
+ }
+
+
+ with ({x: 'outer'}) {
+ for (var i = 0; i < 3; ++i) {
+ with ({x: 'inner' + i}) {
+ continue;
+ }
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ label: for (var i = 0; i < 3; ++i) {
+ with ({x: 'middle' + i}) {
+ for (var j = 0; j < 3; ++j) {
+ with ({x: 'inner' + j}) {
+ continue label;
+ }
+ }
+ }
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } catch (e) {
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } catch (e) {
+ nop();
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ try {
+ with ({x: 'middle'}) {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ }
+ } catch (e) {
+ }
+ }
+
+
+ try {
+ with ({x: 'outer'}) {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } finally {
+ }
+ }
+ } catch (e) {
+ }
+
+
+ try {
+ with ({x: 'outer'}) {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } finally {
+ nop();
+ }
+ }
+ } catch (e) {
+ }
+
+
+ function stress1() {
+ with ({x:12}) {
+ return x;
+ }
+ }
+ stress1();
+
+
+ function stress2() {
+ with ({x: 'outer'}) {
+ with ({x: 'inner'}) {
+ return x;
+ }
+ }
+ }
+ stress2();
+
+ function stress3() {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } catch (e) {
+ return e;
+ }
+ }
+ stress3();
+
+
+ function stress4() {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } catch (e) {
+ with ({x: 'inner'}) {
+ return e;
+ }
+ }
+ }
+ stress4();
+
+}
+stress();
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope.js b/deps/v8/test/mjsunit/debug-stepout-scope.js
deleted file mode 100644
index 9c040da93..000000000
--- a/deps/v8/test/mjsunit/debug-stepout-scope.js
+++ /dev/null
@@ -1,423 +0,0 @@
-// Copyright 2011 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.
-
-// Flags: --expose-debug-as debug --expose-natives-as=builtins
-
-// Check that the ScopeIterator can properly recreate the scope at
-// every point when stepping through functions.
-
-var Debug = debug.Debug;
-
-function listener(event, exec_state, event_data, data) {
- if (event == Debug.DebugEvent.Break) {
- // Access scope details.
- var scope_count = exec_state.frame().scopeCount();
- for (var i = 0; i < scope_count; i++) {
- var scope = exec_state.frame().scope(i);
- // assertTrue(scope.isScope());
- scope.scopeType();
- scope.scopeObject();
- }
-
- // Do steps until we reach the global scope again.
- if (true) {
- exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
- }
- }
-}
-
-Debug.setListener(listener);
-
-
-function test1() {
- debugger;
- with ({x:1}) {
- x = 2;
- }
-}
-test1();
-
-
-function test2() {
- if (true) {
- with ({}) {
- debugger;
- }
- } else {
- with ({}) {
- return 10;
- }
- }
-}
-test2();
-
-
-function test3() {
- if (true) {
- debugger;
- } else {
- with ({}) {
- return 10;
- }
- }
-}
-test3();
-
-
-function test4() {
- debugger;
- with ({x:1}) x = 1
-}
-test4();
-
-
-function test5() {
- debugger;
- var dummy = 1;
- with ({}) {
- with ({}) {
- dummy = 2;
- }
- }
- dummy = 3;
-}
-test5();
-
-
-function test6() {
- debugger;
- try {
- throw 'stuff';
- } catch (e) {
- e = 1;
- }
-}
-test6();
-
-
-function test7() {
- debugger;
- function foo() {}
-}
-test7();
-
-
-function test8() {
- debugger;
- (function foo() {})();
-}
-test8();
-
-
-var q = 42;
-var prefixes = [ "debugger; ",
- "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ];
-var bodies = [ "1",
- "1 ",
- "1;",
- "1; ",
- "q",
- "q ",
- "q;",
- "q; ",
- "try { throw 'stuff' } catch (e) { e = 1; }",
- "try { throw 'stuff' } catch (e) { e = 1; } ",
- "try { throw 'stuff' } catch (e) { e = 1; };",
- "try { throw 'stuff' } catch (e) { e = 1; }; " ];
-var with_bodies = [ "with ({}) {}",
- "with ({x:1}) x",
- "with ({x:1}) x = 1",
- "with ({x:1}) x ",
- "with ({x:1}) x = 1 ",
- "with ({x:1}) x;",
- "with ({x:1}) x = 1;",
- "with ({x:1}) x; ",
- "with ({x:1}) x = 1; " ];
-
-
-function test9() {
- debugger;
- for (var i = 0; i < prefixes.length; ++i) {
- var pre = prefixes[i];
- for (var j = 0; j < bodies.length; ++j) {
- var body = bodies[j];
- eval(pre + body);
- eval("'use strict'; " + pre + body);
- }
- for (var j = 0; j < with_bodies.length; ++j) {
- var body = with_bodies[j];
- eval(pre + body);
- }
- }
-}
-test9();
-
-
-function test10() {
- debugger;
- with ({}) {
- return 10;
- }
-}
-test10();
-
-
-function test11() {
- debugger;
- try {
- throw 'stuff';
- } catch (e) {
- return 10;
- }
-}
-test11();
-
-
-// Test global eval and function constructor.
-for (var i = 0; i < prefixes.length; ++i) {
- var pre = prefixes[i];
- for (var j = 0; j < bodies.length; ++j) {
- var body = bodies[j];
- eval(pre + body);
- eval("'use strict'; " + pre + body);
- Function(pre + body)();
- }
- for (var j = 0; j < with_bodies.length; ++j) {
- var body = with_bodies[j];
- eval(pre + body);
- Function(pre + body)();
- }
-}
-
-
-try {
- with({}) {
- debugger;
- eval("{}$%:^");
- }
-} catch(e) {
- nop();
-}
-
-// Return from function constructed with Function constructor.
-var anon = 12;
-for (var i = 0; i < prefixes.length; ++i) {
- var pre = prefixes[i];
- Function(pre + "return 42")();
- Function(pre + "return 42 ")();
- Function(pre + "return 42;")();
- Function(pre + "return 42; ")();
- Function(pre + "return anon")();
- Function(pre + "return anon ")();
- Function(pre + "return anon;")();
- Function(pre + "return anon; ")();
-}
-
-
-function nop() {}
-
-
-function stress() {
- debugger;
-
- L: with ({x:12}) {
- break L;
- }
-
-
- with ({x: 'outer'}) {
- label: {
- with ({x: 'inner'}) {
- break label;
- }
- }
- }
-
-
- with ({x: 'outer'}) {
- label: {
- with ({x: 'inner'}) {
- break label;
- }
- }
- nop();
- }
-
-
- with ({x: 'outer'}) {
- label: {
- with ({x: 'middle'}) {
- with ({x: 'inner'}) {
- break label;
- }
- }
- }
- }
-
-
- with ({x: 'outer'}) {
- label: {
- with ({x: 'middle'}) {
- with ({x: 'inner'}) {
- break label;
- }
- }
- }
- nop();
- }
-
-
- with ({x: 'outer'}) {
- for (var i = 0; i < 3; ++i) {
- with ({x: 'inner' + i}) {
- continue;
- }
- }
- }
-
-
- with ({x: 'outer'}) {
- label: for (var i = 0; i < 3; ++i) {
- with ({x: 'middle' + i}) {
- for (var j = 0; j < 3; ++j) {
- with ({x: 'inner' + j}) {
- continue label;
- }
- }
- }
- }
- }
-
-
- with ({x: 'outer'}) {
- try {
- with ({x: 'inner'}) {
- throw 0;
- }
- } catch (e) {
- }
- }
-
-
- with ({x: 'outer'}) {
- try {
- with ({x: 'inner'}) {
- throw 0;
- }
- } catch (e) {
- nop();
- }
- }
-
-
- with ({x: 'outer'}) {
- try {
- with ({x: 'middle'}) {
- with ({x: 'inner'}) {
- throw 0;
- }
- }
- } catch (e) {
- }
- }
-
-
- try {
- with ({x: 'outer'}) {
- try {
- with ({x: 'inner'}) {
- throw 0;
- }
- } finally {
- }
- }
- } catch (e) {
- }
-
-
- try {
- with ({x: 'outer'}) {
- try {
- with ({x: 'inner'}) {
- throw 0;
- }
- } finally {
- nop();
- }
- }
- } catch (e) {
- }
-
-
- function stress1() {
- with ({x:12}) {
- return x;
- }
- }
- stress1();
-
-
- function stress2() {
- with ({x: 'outer'}) {
- with ({x: 'inner'}) {
- return x;
- }
- }
- }
- stress2();
-
- function stress3() {
- try {
- with ({x: 'inner'}) {
- throw 0;
- }
- } catch (e) {
- return e;
- }
- }
- stress3();
-
-
- function stress4() {
- try {
- with ({x: 'inner'}) {
- throw 0;
- }
- } catch (e) {
- with ({x: 'inner'}) {
- return e;
- }
- }
- }
- stress4();
-
-}
-stress();
-
-
-// With block as the last(!) statement in global code.
-with ({}) { debugger; } \ No newline at end of file
diff --git a/deps/v8/test/mjsunit/delete-non-configurable.js b/deps/v8/test/mjsunit/delete-non-configurable.js
new file mode 100644
index 000000000..8991f43f5
--- /dev/null
+++ b/deps/v8/test/mjsunit/delete-non-configurable.js
@@ -0,0 +1,74 @@
+// Copyright 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.
+
+// Delete elements of a String object.
+var TIPLI = "tipli"
+var so = new String(TIPLI);
+var length = so.length;
+
+for (var i = 0; i < length; i++) {
+ assertFalse(delete so[i]);
+ assertThrows("'use strict'; delete so[i];", TypeError);
+ assertFalse(delete so[i.toString()]);
+ assertThrows("'use strict'; delete so[i.toString()];", TypeError);
+}
+
+assertEquals(length, so.length);
+assertEquals(new String(TIPLI), so);
+
+// Delete elements of an Array.
+var arr = new Array(length);
+
+for (var i = 0; i < length; i++) {
+ arr[i] = i;
+ Object.defineProperty(arr, i, { configurable: false });
+}
+
+for (var i = 0; i < length; i++) {
+ assertFalse(delete arr[i]);
+ assertThrows("'use strict'; delete arr[i];", TypeError);
+ assertFalse(delete arr[i.toString()]);
+ assertThrows("'use strict'; delete arr[i.toString()];", TypeError);
+ assertEquals(i, arr[i]);
+}
+
+assertEquals(length, arr.length);
+assertTrue(delete arr[length]);
+
+// Delete an element of an Object.
+var INDEX = 28;
+var obj = new Object();
+
+obj[INDEX] = TIPLI;
+Object.defineProperty(obj, INDEX, { configurable: false });
+
+assertFalse(delete obj[INDEX]);
+assertThrows("'use strict'; delete obj[INDEX];", TypeError);
+assertFalse(delete obj[INDEX.toString()]);
+assertThrows("'use strict'; delete obj[INDEX.toString()];", TypeError);
+assertEquals(TIPLI, obj[INDEX]);
+assertTrue(delete arr[INDEX+1]);
diff --git a/deps/v8/test/mjsunit/deopt-minus-zero.js b/deps/v8/test/mjsunit/deopt-minus-zero.js
new file mode 100644
index 000000000..ee0983127
--- /dev/null
+++ b/deps/v8/test/mjsunit/deopt-minus-zero.js
@@ -0,0 +1,56 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+/**
+ * The possible optimization states of a function. Must be in sync with the
+ * return values of Runtime_GetOptimizationStatus() in runtime.cc!
+ */
+var OptimizationState = {
+ YES: 1,
+ NO: 2,
+ ALWAYS: 3,
+ NEVER: 4
+};
+
+function mul (a, b) {
+ return a * b;
+}
+
+mul(-1, -1);
+mul(0x80000001|0, -1);
+mul(0x80000001|0, -1);
+%OptimizeFunctionOnNextCall(mul);
+mul(0, -1);
+%OptimizeFunctionOnNextCall(mul);
+mul(0, -1);
+
+var raw_optimized = %GetOptimizationStatus(mul);
+assertFalse(raw_optimized == OptimizationState.NO);
+gc();
+
diff --git a/deps/v8/test/mjsunit/elements-kind.js b/deps/v8/test/mjsunit/elements-kind.js
index 508a6b3ce..b74a21243 100644
--- a/deps/v8/test/mjsunit/elements-kind.js
+++ b/deps/v8/test/mjsunit/elements-kind.js
@@ -143,7 +143,7 @@ assertKind(elements_kind.external_int, new Int32Array(0xF));
assertKind(elements_kind.external_unsigned_int, new Uint32Array(23));
assertKind(elements_kind.external_float, new Float32Array(7));
assertKind(elements_kind.external_double, new Float64Array(0));
-assertKind(elements_kind.external_pixel, new PixelArray(512));
+assertKind(elements_kind.external_pixel, new Uint8ClampedArray(512));
// Crankshaft support for smi-only array elements.
function monomorphic(array) {
diff --git a/deps/v8/test/mjsunit/elements-transition-hoisting.js b/deps/v8/test/mjsunit/elements-transition-hoisting.js
index 9ffb67ecf..017e7ec51 100644
--- a/deps/v8/test/mjsunit/elements-transition-hoisting.js
+++ b/deps/v8/test/mjsunit/elements-transition-hoisting.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --allow-natives-syntax --smi-only-arrays --noparallel-recompilation
// Ensure that ElementsKind transitions in various situations are hoisted (or
// not hoisted) correctly, don't change the semantics programs and don't trigger
@@ -39,11 +39,6 @@ if (support_smi_only_arrays) {
print("Tests do NOT include smi-only arrays.");
}
-// Force existing ICs from previous stress runs to be flushed, otherwise the
-// assumptions in this test about when deoptimizations get triggered are not
-// valid.
-gc();
-
if (support_smi_only_arrays) {
// Make sure that a simple elements array transitions inside a loop before
// stores to an array gets hoisted in a way that doesn't generate a deopt in
@@ -65,6 +60,7 @@ if (support_smi_only_arrays) {
testDoubleConversion4(new Array(5));
testDoubleConversion4(new Array(5));
assertTrue(2 != %GetOptimizationStatus(testDoubleConversion4));
+ %ClearFunctionTypeFeedback(testDoubleConversion4);
// Make sure that non-element related map checks that are not preceded by
// transitions in a loop still get hoisted in a way that doesn't generate a
@@ -90,6 +86,7 @@ if (support_smi_only_arrays) {
testExactMapHoisting(new Array(5));
testExactMapHoisting(new Array(5));
assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting));
+ %ClearFunctionTypeFeedback(testExactMapHoisting);
// Make sure that non-element related map checks do NOT get hoisted if they
// depend on an elements transition before them and it's not possible to hoist
@@ -121,6 +118,7 @@ if (support_smi_only_arrays) {
testExactMapHoisting2(new Array(5));
// Temporarily disabled - see bug 2176.
// assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting2));
+ %ClearFunctionTypeFeedback(testExactMapHoisting2);
// Make sure that non-element related map checks do get hoisted if they use
// the transitioned map for the check and all transitions that they depend
@@ -149,6 +147,7 @@ if (support_smi_only_arrays) {
testExactMapHoisting3(new Array(5));
testExactMapHoisting3(new Array(5));
assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting3));
+ %ClearFunctionTypeFeedback(testExactMapHoisting3);
function testDominatingTransitionHoisting1(a) {
var object = new Object();
@@ -162,6 +161,7 @@ if (support_smi_only_arrays) {
} while (--count > 3);
}
+ /*
testDominatingTransitionHoisting1(new Array(5));
testDominatingTransitionHoisting1(new Array(5)); // Call twice to make sure
// that second store is a
@@ -170,7 +170,12 @@ if (support_smi_only_arrays) {
%OptimizeFunctionOnNextCall(testDominatingTransitionHoisting1);
testDominatingTransitionHoisting1(new Array(5));
testDominatingTransitionHoisting1(new Array(5));
+ // TODO(verwaest) With current changes the elements transition gets hoisted
+ // above the access, causing a deopt. We should update the type of access
+ // rather than forbid hoisting the transition.
assertTrue(2 != %GetOptimizationStatus(testDominatingTransitionHoisting1));
+ %ClearFunctionTypeFeedback(testDominatingTransitionHoisting1);
+ */
function testHoistingWithSideEffect(a) {
var object = new Object();
@@ -190,6 +195,7 @@ if (support_smi_only_arrays) {
testHoistingWithSideEffect(new Array(5));
testHoistingWithSideEffect(new Array(5));
assertTrue(2 != %GetOptimizationStatus(testHoistingWithSideEffect));
+ %ClearFunctionTypeFeedback(testHoistingWithSideEffect);
function testStraightLineDupeElinination(a,b,c,d,e,f) {
var count = 3;
@@ -225,7 +231,8 @@ if (support_smi_only_arrays) {
testStraightLineDupeElinination(new Array(5),0,0,0,.5,0);
testStraightLineDupeElinination(new Array(5),0,0,0,0,.5);
%OptimizeFunctionOnNextCall(testStraightLineDupeElinination);
- testStraightLineDupeElinination(new Array(5));
- testStraightLineDupeElinination(new Array(5));
+ testStraightLineDupeElinination(new Array(5),0,0,0,0,0);
+ testStraightLineDupeElinination(new Array(5),0,0,0,0,0);
assertTrue(2 != %GetOptimizationStatus(testStraightLineDupeElinination));
+ %ClearFunctionTypeFeedback(testStraightLineDupeElinination);
}
diff --git a/deps/v8/test/mjsunit/eval-stack-trace.js b/deps/v8/test/mjsunit/eval-stack-trace.js
new file mode 100644
index 000000000..723d522c7
--- /dev/null
+++ b/deps/v8/test/mjsunit/eval-stack-trace.js
@@ -0,0 +1,203 @@
+// Copyright 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.
+
+// Return the stack frames of an Error object.
+Error.prototype.getFrames = function() {
+ Error.prepareStackTrace = function(error, frames) {
+ return frames;
+ }
+ var frames = this.stack;
+ Error.prepareStackTrace = undefined;
+ return frames;
+}
+
+String.prototype.contains = function(pattern) {
+ return this.indexOf(pattern) > -1;
+}
+
+// Check for every frame that a certain method returns the
+// expected value for every frame.
+Array.prototype.verifyEquals = function(frames, func_name) {
+ this.forEach(
+ function(element, index) {
+ var frame = frames[index];
+ if (element === null) return;
+ assertEquals(element, (frame[func_name])());
+ }
+ );
+}
+
+// Check for every frame that a certain method has a return value
+// that contains the expected pattern for every frame.
+Array.prototype.verifyContains = function(frames, func_name) {
+ this.forEach(
+ function(element, index) {
+ var frame = frames[index];
+ if (element === null) return;
+ assertTrue((frame[func_name])().contains(element));
+ }
+ );
+}
+
+// Check for every frame that a certain method returns undefined
+// when expected.
+Array.prototype.verifyUndefined = function(frames, func_name) {
+ this.forEach(
+ function(element, index) {
+ var frame = frames[index];
+ if (element === null) return;
+ assertEquals(element, (frame[func_name])() === undefined);
+ }
+ );
+}
+
+
+// Simple eval.
+var code1 = "function f() { \n" +
+ " throw new Error(3); \n" + // Line 2
+ "} \n" +
+ "f(); \n"; // Line 4
+
+function g() {
+ eval(code1);
+}
+
+try {
+ g();
+} catch (e) {
+ // We expect something like
+ // f (eval at g (eval-stack.js:87:8), <anonymous>:2:9)
+ // eval (eval at g (eval-stack.js:87:8), <anonymous>:4:1)
+ // g (eval-stack.js:87:3)
+ // eval-stack.js:94:3
+ var frames = e.getFrames();
+ assertEquals(4, frames.length);
+ ["f", "eval", "g"]
+ .verifyEquals(frames, "getFunctionName");
+ [2, 4]
+ .verifyEquals(frames, "getLineNumber");
+ ["<anonymous>:2:", "<anonymous>:4:"]
+ .verifyContains(frames, "toString");
+ [true, true, false, false]
+ .verifyUndefined(frames, "getFileName");
+ ["eval at g", "eval at g"]
+ .verifyContains(frames, "getEvalOrigin");
+}
+
+
+// Nested eval.
+var code2 = "function h() { \n" +
+ " // Empty \n" +
+ " eval(code1); \n" + // Line 3
+ "} \n" +
+ "h(); \n"; // Line 5
+
+try {
+ eval(code2);
+} catch (e) {
+ // We expect something like
+ // f (eval at h (eval at <anonymous> (eval-stack.js:116:8)),
+ // <anonymous>:2:9)
+ // eval (eval at h (eval at <anonymous> (eval-stack.js:116:8)),
+ // <anonymous>:4:1)
+ // h (eval at <anonymous> (eval-stack.js:116:8), <anonymous>:3:3)
+ // eval (eval at <anonymous> (eval-stack.js:116:8), <anonymous>:5:1)
+ // eval-stack.js:116:3
+ var frames = e.getFrames();
+ assertEquals(5, frames.length);
+ ["f", "eval", "h", "eval"]
+ .verifyEquals(frames, "getFunctionName");
+ [2, 4, 3, 5]
+ .verifyEquals(frames, "getLineNumber");
+ ["<anonymous>:2:", "<anonymous>:4:", "<anonymous>:3:", "<anonymous>:5:"]
+ .verifyContains(frames, "toString");
+ [true, true, true, true, false]
+ .verifyUndefined(frames, "getFileName");
+ ["eval at h (eval at <anonymous> (",
+ "eval at h (eval at <anonymous> (",
+ "eval at <anonymous> (",
+ "eval at <anonymous> ("]
+ .verifyContains(frames, "getEvalOrigin");
+}
+
+
+// Nested eval calling through non-eval defined function.
+var code3 = "function h() { \n" +
+ " // Empty \n" +
+ " g(); \n" + // Line 3
+ "} \n" +
+ "h(); \n"; // Line 5
+
+try {
+ eval(code3);
+} catch (e) {
+ // We expect something like
+ // f (eval at g (test.js:83:8), <anonymous>:2:9)
+ // eval (eval at g (test.js:83:8), <anonymous>:4:1)
+ // g (test.js:83:3)
+ // h (eval at <anonymous> (test.js:149:8), <anonymous>:3:3)
+ // eval (eval at <anonymous> (test.js:149:8), <anonymous>:5:1)
+ // test.js:149:3
+ var frames = e.getFrames();
+ assertEquals(6, frames.length);
+ ["f", "eval", "g", "h", "eval"]
+ .verifyEquals(frames, "getFunctionName");
+ [2, 4, null, 3, 5]
+ .verifyEquals(frames, "getLineNumber");
+ ["<anonymous>:2:", "<anonymous>:4:", null, "<anonymous>:3:", "<anonymous>:5:"]
+ .verifyContains(frames, "toString");
+ [true, true, false, true, true, false]
+ .verifyUndefined(frames, "getFileName");
+ ["eval at g (",
+ "eval at g (",
+ null,
+ "eval at <anonymous> (",
+ "eval at <anonymous> ("]
+ .verifyContains(frames, "getEvalOrigin");
+}
+
+
+// Calling function defined in eval.
+eval("function f() { \n" +
+ " throw new Error(3); \n" +
+ "} \n");
+
+try {
+ f();
+} catch (e) {
+ // We expect something like
+ // f (eval at <anonymous> (test.js:182:40), <anonymous>:2:9)
+ // test.js:186:3
+ var frames = e.getFrames();
+ assertEquals(2, frames.length);
+ ["f"].verifyEquals(frames, "getFunctionName");
+ [2].verifyEquals(frames, "getLineNumber");
+ ["<anonymous>:2:"].verifyContains(frames, "toString");
+ [true, false].verifyUndefined(frames, "getFileName");
+ ["eval at <anonymous> ("].verifyContains(frames, "getEvalOrigin");
+}
+
diff --git a/deps/v8/test/mjsunit/external-array.js b/deps/v8/test/mjsunit/external-array.js
index d02922006..85a8cc584 100644
--- a/deps/v8/test/mjsunit/external-array.js
+++ b/deps/v8/test/mjsunit/external-array.js
@@ -27,6 +27,12 @@
// Flags: --allow-natives-syntax --expose-gc
+// Helper
+function assertInstance(o, f) {
+ assertSame(o.constructor, f);
+ assertInstanceof(o, f);
+}
+
// This is a regression test for overlapping key and value registers.
function f(a) {
a[0] = 0;
@@ -51,49 +57,58 @@ assertThrows(abfunc1);
// Test derivation from an ArrayBuffer
var ab = new ArrayBuffer(12);
+assertInstance(ab, ArrayBuffer);
var derived_uint8 = new Uint8Array(ab);
+assertInstance(derived_uint8, Uint8Array);
assertSame(ab, derived_uint8.buffer);
assertEquals(12, derived_uint8.length);
assertEquals(12, derived_uint8.byteLength);
assertEquals(0, derived_uint8.byteOffset);
assertEquals(1, derived_uint8.BYTES_PER_ELEMENT);
var derived_uint8_2 = new Uint8Array(ab,7);
+assertInstance(derived_uint8_2, Uint8Array);
assertSame(ab, derived_uint8_2.buffer);
assertEquals(5, derived_uint8_2.length);
assertEquals(5, derived_uint8_2.byteLength);
assertEquals(7, derived_uint8_2.byteOffset);
assertEquals(1, derived_uint8_2.BYTES_PER_ELEMENT);
var derived_int16 = new Int16Array(ab);
+assertInstance(derived_int16, Int16Array);
assertSame(ab, derived_int16.buffer);
assertEquals(6, derived_int16.length);
assertEquals(12, derived_int16.byteLength);
assertEquals(0, derived_int16.byteOffset);
assertEquals(2, derived_int16.BYTES_PER_ELEMENT);
var derived_int16_2 = new Int16Array(ab,6);
+assertInstance(derived_int16_2, Int16Array);
assertSame(ab, derived_int16_2.buffer);
assertEquals(3, derived_int16_2.length);
assertEquals(6, derived_int16_2.byteLength);
assertEquals(6, derived_int16_2.byteOffset);
assertEquals(2, derived_int16_2.BYTES_PER_ELEMENT);
var derived_uint32 = new Uint32Array(ab);
+assertInstance(derived_uint32, Uint32Array);
assertSame(ab, derived_uint32.buffer);
assertEquals(3, derived_uint32.length);
assertEquals(12, derived_uint32.byteLength);
assertEquals(0, derived_uint32.byteOffset);
assertEquals(4, derived_uint32.BYTES_PER_ELEMENT);
var derived_uint32_2 = new Uint32Array(ab,4);
+assertInstance(derived_uint32_2, Uint32Array);
assertSame(ab, derived_uint32_2.buffer);
assertEquals(2, derived_uint32_2.length);
assertEquals(8, derived_uint32_2.byteLength);
assertEquals(4, derived_uint32_2.byteOffset);
assertEquals(4, derived_uint32_2.BYTES_PER_ELEMENT);
var derived_uint32_3 = new Uint32Array(ab,4,1);
+assertInstance(derived_uint32_3, Uint32Array);
assertSame(ab, derived_uint32_3.buffer);
assertEquals(1, derived_uint32_3.length);
assertEquals(4, derived_uint32_3.byteLength);
assertEquals(4, derived_uint32_3.byteOffset);
assertEquals(4, derived_uint32_3.BYTES_PER_ELEMENT);
var derived_float64 = new Float64Array(ab,0,1);
+assertInstance(derived_float64, Float64Array);
assertSame(ab, derived_float64.buffer);
assertEquals(1, derived_float64.length);
assertEquals(8, derived_float64.byteLength);
@@ -144,6 +159,7 @@ a = new Float64Array(7);
assertSame(a.buffer, (new Uint16Array(a.buffer)).buffer);
assertSame(a.buffer, (new Float32Array(a.buffer,4)).buffer);
assertSame(a.buffer, (new Int8Array(a.buffer,3,51)).buffer);
+assertInstance(a.buffer, ArrayBuffer);
// Test the correct behavior of the |BYTES_PER_ELEMENT| property (which is
// "constant", but not read-only).
@@ -198,7 +214,7 @@ assertEquals(4, array_with_length_from_non_number.length);
// Test loads and stores.
types = [Array, Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array,
- Uint32Array, PixelArray, Float32Array, Float64Array];
+ Uint32Array, Uint8ClampedArray, Float32Array, Float64Array];
test_result_nan = [NaN, 0, 0, 0, 0, 0, 0, 0, NaN, NaN];
test_result_low_int = [-1, -1, 255, -1, 65535, -1, 0xFFFFFFFF, 0, -1, -1];
@@ -412,22 +428,289 @@ assertTrue(isNaN(float64_array[0]));
// Check handling of 0-sized buffers and arrays.
-
ab = new ArrayBuffer(0);
+assertInstance(ab, ArrayBuffer);
assertEquals(0, ab.byteLength);
a = new Int8Array(ab);
+assertInstance(a, Int8Array);
assertEquals(0, a.byteLength);
assertEquals(0, a.length);
a[0] = 1;
-assertEquals(undefined, a[0])
+assertEquals(undefined, a[0]);
ab = new ArrayBuffer(16);
+assertInstance(ab, ArrayBuffer);
a = new Float32Array(ab,4,0);
+assertInstance(a, Float32Array);
assertEquals(0, a.byteLength);
assertEquals(0, a.length);
a[0] = 1;
-assertEquals(undefined, a[0])
+assertEquals(undefined, a[0]);
a = new Uint16Array(0);
+assertInstance(a, Uint16Array);
assertEquals(0, a.byteLength);
assertEquals(0, a.length);
a[0] = 1;
-assertEquals(undefined, a[0])
+assertEquals(undefined, a[0]);
+
+
+// Check construction from arrays.
+a = new Uint32Array([]);
+assertInstance(a, Uint32Array);
+assertEquals(0, a.length);
+assertEquals(0, a.byteLength);
+assertEquals(0, a.buffer.byteLength);
+assertEquals(4, a.BYTES_PER_ELEMENT);
+assertInstance(a.buffer, ArrayBuffer);
+a = new Uint16Array([1,2,3]);
+assertInstance(a, Uint16Array);
+assertEquals(3, a.length);
+assertEquals(6, a.byteLength);
+assertEquals(6, a.buffer.byteLength);
+assertEquals(2, a.BYTES_PER_ELEMENT);
+assertEquals(1, a[0]);
+assertEquals(3, a[2]);
+assertInstance(a.buffer, ArrayBuffer);
+a = new Uint32Array(a);
+assertInstance(a, Uint32Array);
+assertEquals(3, a.length);
+assertEquals(12, a.byteLength);
+assertEquals(12, a.buffer.byteLength);
+assertEquals(4, a.BYTES_PER_ELEMENT);
+assertEquals(1, a[0]);
+assertEquals(3, a[2]);
+assertInstance(a.buffer, ArrayBuffer);
+
+// Check subarrays.
+a = new Uint16Array([1,2,3,4,5,6]);
+aa = a.subarray(3);
+assertInstance(aa, Uint16Array);
+assertEquals(3, aa.length);
+assertEquals(6, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(3,5);
+assertInstance(aa, Uint16Array);
+assertEquals(2, aa.length);
+assertEquals(4, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(4,8);
+assertInstance(aa, Uint16Array);
+assertEquals(2, aa.length);
+assertEquals(4, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(9);
+assertInstance(aa, Uint16Array);
+assertEquals(0, aa.length);
+assertEquals(0, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(-4);
+assertInstance(aa, Uint16Array);
+assertEquals(4, aa.length);
+assertEquals(8, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(-3,-1);
+assertInstance(aa, Uint16Array);
+assertEquals(2, aa.length);
+assertEquals(4, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(3,2);
+assertInstance(aa, Uint16Array);
+assertEquals(0, aa.length);
+assertEquals(0, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(-3,-4);
+assertInstance(aa, Uint16Array);
+assertEquals(0, aa.length);
+assertEquals(0, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(0,-8);
+assertInstance(aa, Uint16Array);
+assertEquals(0, aa.length);
+assertEquals(0, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+
+assertThrows(function(){ a.subarray.call({}, 0) });
+assertThrows(function(){ a.subarray.call([], 0) });
+assertThrows(function(){ a.subarray.call(a) });
+
+
+// Call constructors directly as functions, and through .call and .apply
+
+b = ArrayBuffer(100)
+a = Int8Array(b, 5, 77)
+assertInstance(b, ArrayBuffer)
+assertInstance(a, Int8Array)
+assertSame(b, a.buffer)
+assertEquals(5, a.byteOffset)
+assertEquals(77, a.byteLength)
+b = ArrayBuffer.call(null, 10)
+a = Uint16Array.call(null, b, 2, 4)
+assertInstance(b, ArrayBuffer)
+assertInstance(a, Uint16Array)
+assertSame(b, a.buffer)
+assertEquals(2, a.byteOffset)
+assertEquals(8, a.byteLength)
+b = ArrayBuffer.apply(null, [1000])
+a = Float32Array.apply(null, [b, 128, 1])
+assertInstance(b, ArrayBuffer)
+assertInstance(a, Float32Array)
+assertSame(b, a.buffer)
+assertEquals(128, a.byteOffset)
+assertEquals(4, a.byteLength)
+
+
+// Test array.set in different combinations.
+
+function assertArrayPrefix(expected, array) {
+ for (var i = 0; i < expected.length; ++i) {
+ assertEquals(expected[i], array[i]);
+ }
+}
+
+var a11 = new Int16Array([1, 2, 3, 4, 0, -1])
+var a12 = new Uint16Array(15)
+a12.set(a11, 3)
+assertArrayPrefix([0, 0, 0, 1, 2, 3, 4, 0, 0xffff, 0, 0], a12)
+assertThrows(function(){ a11.set(a12) })
+
+var a21 = [1, undefined, 10, NaN, 0, -1, {valueOf: function() {return 3}}]
+var a22 = new Int32Array(12)
+a22.set(a21, 2)
+assertArrayPrefix([0, 0, 1, 0, 10, 0, 0, -1, 3, 0], a22)
+
+var a31 = new Float32Array([2, 4, 6, 8, 11, NaN, 1/0, -3])
+var a32 = a31.subarray(2, 6)
+a31.set(a32, 4)
+assertArrayPrefix([2, 4, 6, 8, 6, 8, 11, NaN], a31)
+assertArrayPrefix([6, 8, 6, 8], a32)
+
+var a4 = new Uint8ClampedArray([3,2,5,6])
+a4.set(a4)
+assertArrayPrefix([3, 2, 5, 6], a4)
+
+// Cases with overlapping backing store but different element sizes.
+var b = new ArrayBuffer(4)
+var a5 = new Int16Array(b)
+var a50 = new Int8Array(b)
+var a51 = new Int8Array(b, 0, 2)
+var a52 = new Int8Array(b, 1, 2)
+var a53 = new Int8Array(b, 2, 2)
+
+a5.set([0x5050, 0x0a0a])
+assertArrayPrefix([0x50, 0x50, 0x0a, 0x0a], a50)
+assertArrayPrefix([0x50, 0x50], a51)
+assertArrayPrefix([0x50, 0x0a], a52)
+assertArrayPrefix([0x0a, 0x0a], a53)
+
+a50.set([0x50, 0x50, 0x0a, 0x0a])
+a51.set(a5)
+assertArrayPrefix([0x50, 0x0a, 0x0a, 0x0a], a50)
+
+a50.set([0x50, 0x50, 0x0a, 0x0a])
+a52.set(a5)
+assertArrayPrefix([0x50, 0x50, 0x0a, 0x0a], a50)
+
+a50.set([0x50, 0x50, 0x0a, 0x0a])
+a53.set(a5)
+assertArrayPrefix([0x50, 0x50, 0x50, 0x0a], a50)
+
+a50.set([0x50, 0x51, 0x0a, 0x0b])
+a5.set(a51)
+assertArrayPrefix([0x0050, 0x0051], a5)
+
+a50.set([0x50, 0x51, 0x0a, 0x0b])
+a5.set(a52)
+assertArrayPrefix([0x0051, 0x000a], a5)
+
+a50.set([0x50, 0x51, 0x0a, 0x0b])
+a5.set(a53)
+assertArrayPrefix([0x000a, 0x000b], a5)
+
+// Mixed types of same size.
+var a61 = new Float32Array([1.2, 12.3])
+var a62 = new Int32Array(2)
+a62.set(a61)
+assertArrayPrefix([1, 12], a62)
+a61.set(a62)
+assertArrayPrefix([1, 12], a61)
+
+// Invalid source
+assertThrows(function() { a.set(0) })
+assertThrows(function() { a.set({}) })
+
+
+// Test arraybuffer.slice
+
+var a0 = new Int8Array([1, 2, 3, 4, 5, 6])
+var b0 = a0.buffer
+
+var b1 = b0.slice(0)
+assertEquals(b0.byteLength, b1.byteLength)
+assertArrayPrefix([1, 2, 3, 4, 5, 6], Int8Array(b1))
+
+var b2 = b0.slice(3)
+assertEquals(b0.byteLength - 3, b2.byteLength)
+assertArrayPrefix([4, 5, 6], Int8Array(b2))
+
+var b3 = b0.slice(2, 4)
+assertEquals(2, b3.byteLength)
+assertArrayPrefix([3, 4], Int8Array(b3))
+
+function goo(a, i) {
+ return a[i];
+}
+
+function boo(a, i, v) {
+ return a[i] = v;
+}
+
+function do_tagged_index_external_array_test(constructor) {
+ var t_array = new constructor([1, 2, 3, 4, 5, 6]);
+ assertEquals(1, goo(t_array, 0));
+ assertEquals(1, goo(t_array, 0));
+ boo(t_array, 0, 13);
+ assertEquals(13, goo(t_array, 0));
+ %OptimizeFunctionOnNextCall(goo);
+ %OptimizeFunctionOnNextCall(boo);
+ boo(t_array, 0, 15);
+ assertEquals(15, goo(t_array, 0));
+ %ClearFunctionTypeFeedback(goo);
+ %ClearFunctionTypeFeedback(boo);
+}
+
+do_tagged_index_external_array_test(Int8Array);
+do_tagged_index_external_array_test(Uint8Array);
+do_tagged_index_external_array_test(Int16Array);
+do_tagged_index_external_array_test(Uint16Array);
+do_tagged_index_external_array_test(Int32Array);
+do_tagged_index_external_array_test(Uint32Array);
+do_tagged_index_external_array_test(Float32Array);
+do_tagged_index_external_array_test(Float64Array);
+
+var built_in_array = new Array(1, 2, 3, 4, 5, 6);
+assertEquals(1, goo(built_in_array, 0));
+assertEquals(1, goo(built_in_array, 0));
+%OptimizeFunctionOnNextCall(goo);
+%OptimizeFunctionOnNextCall(boo);
+boo(built_in_array, 0, 11);
+assertEquals(11, goo(built_in_array, 0));
+%ClearFunctionTypeFeedback(goo);
+%ClearFunctionTypeFeedback(boo);
+
+built_in_array = new Array(1.5, 2, 3, 4, 5, 6);
+assertEquals(1.5, goo(built_in_array, 0));
+assertEquals(1.5, goo(built_in_array, 0));
+%OptimizeFunctionOnNextCall(goo);
+%OptimizeFunctionOnNextCall(boo);
+boo(built_in_array, 0, 2.5);
+assertEquals(2.5, goo(built_in_array, 0));
+%ClearFunctionTypeFeedback(goo);
+%ClearFunctionTypeFeedback(boo);
diff --git a/deps/v8/test/mjsunit/fuzz-natives-part1.js b/deps/v8/test/mjsunit/fuzz-natives-part1.js
new file mode 100644
index 000000000..6941d806c
--- /dev/null
+++ b/deps/v8/test/mjsunit/fuzz-natives-part1.js
@@ -0,0 +1,222 @@
+// Copyright 2011 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.
+
+// Flags: --allow-natives-syntax
+
+var RUN_WITH_ALL_ARGUMENT_ENTRIES = false;
+var kOnManyArgumentsRemove = 5;
+
+function makeArguments() {
+ var result = [ ];
+ result.push(17);
+ result.push(-31);
+ result.push(new Array(100));
+ result.push(new Array(100003));
+ result.push(Number.MIN_VALUE);
+ result.push("whoops");
+ result.push("x");
+ result.push({"x": 1, "y": 2});
+ var slowCaseObj = {"a": 3, "b": 4, "c": 5};
+ delete slowCaseObj.c;
+ result.push(slowCaseObj);
+ result.push(function () { return 8; });
+ return result;
+}
+
+var kArgObjects = makeArguments().length;
+
+function makeFunction(name, argc) {
+ var args = [];
+ for (var i = 0; i < argc; i++)
+ args.push("x" + i);
+ var argsStr = args.join(", ");
+ return new Function(args.join(", "), "return %" + name + "(" + argsStr + ");");
+}
+
+function testArgumentCount(name, argc) {
+ for (var i = 0; i < 10; i++) {
+ var func = null;
+ try {
+ func = makeFunction(name, i);
+ } catch (e) {
+ if (e != "SyntaxError: Illegal access") throw e;
+ }
+ if (func === null && i == argc) {
+ throw "unexpected exception";
+ }
+ var args = [ ];
+ for (var j = 0; j < i; j++)
+ args.push(0);
+ try {
+ func.apply(void 0, args);
+ } catch (e) {
+ // we don't care what happens as long as we don't crash
+ }
+ }
+}
+
+function testArgumentTypes(name, argc) {
+ var type = 0;
+ var hasMore = true;
+ var func = makeFunction(name, argc);
+ while (hasMore) {
+ var argPool = makeArguments();
+ // When we have 5 or more arguments we lower the amount of tests cases
+ // by randomly removing kOnManyArgumentsRemove entries
+ var numArguments = RUN_WITH_ALL_ARGUMENT_ENTRIES ?
+ kArgObjects : kArgObjects-kOnManyArgumentsRemove;
+ if (argc >= 5 && !RUN_WITH_ALL_ARGUMENT_ENTRIES) {
+ for (var i = 0; i < kOnManyArgumentsRemove; i++) {
+ var rand = Math.floor(Math.random() * (kArgObjects - i));
+ argPool.splice(rand,1);
+ }
+ }
+ var current = type;
+ var hasMore = false;
+ var argList = [ ];
+ for (var i = 0; i < argc; i++) {
+ var index = current % numArguments;
+ current = (current / numArguments) << 0;
+ if (index != (numArguments - 1))
+ hasMore = true;
+ argList.push(argPool[index]);
+ }
+ try {
+ func.apply(void 0, argList);
+ } catch (e) {
+ // we don't care what happens as long as we don't crash
+ }
+ type++;
+ }
+}
+
+var knownProblems = {
+ "Abort": true,
+
+ // Avoid calling the concat operation, because weird lengths
+ // may lead to out-of-memory. Ditto for StringBuilderJoin.
+ "StringBuilderConcat": true,
+ "StringBuilderJoin": true,
+
+ // These functions use pseudo-stack-pointers and are not robust
+ // to unexpected integer values.
+ "DebugEvaluate": true,
+
+ // These functions do nontrivial error checking in recursive calls,
+ // which means that we have to propagate errors back.
+ "SetFunctionBreakPoint": true,
+ "SetScriptBreakPoint": true,
+ "PrepareStep": true,
+
+ // Too slow.
+ "DebugReferencedBy": true,
+
+ // Calling disable/enable access checks may interfere with the
+ // the rest of the tests.
+ "DisableAccessChecks": true,
+ "EnableAccessChecks": true,
+
+ // These functions should not be callable as runtime functions.
+ "NewFunctionContext": true,
+ "NewArgumentsFast": true,
+ "NewStrictArgumentsFast": true,
+ "PushWithContext": true,
+ "PushCatchContext": true,
+ "PushBlockContext": true,
+ "LazyCompile": true,
+ "LazyRecompile": true,
+ "ParallelRecompile": true,
+ "NotifyDeoptimized": true,
+ "NotifyOSR": true,
+ "CreateObjectLiteralBoilerplate": true,
+ "CloneLiteralBoilerplate": true,
+ "CloneShallowLiteralBoilerplate": true,
+ "CreateArrayLiteralBoilerplate": true,
+ "IS_VAR": true,
+ "ResolvePossiblyDirectEval": true,
+ "Log": true,
+ "DeclareGlobals": true,
+
+ "PromoteScheduledException": true,
+ "DeleteHandleScopeExtensions": true,
+
+ // Vararg with minimum number > 0.
+ "Call": true,
+
+ // Requires integer arguments to be non-negative.
+ "Apply": true,
+
+ // That can only be invoked on Array.prototype.
+ "FinishArrayPrototypeSetup": true,
+
+ "_SwapElements": true,
+
+ // Performance critical functions which cannot afford type checks.
+ "_IsNativeOrStrictMode": true,
+ "_CallFunction": true,
+
+ // Tries to allocate based on argument, and (correctly) throws
+ // out-of-memory if the request is too large. In practice, the
+ // size will be the number of captures of a RegExp.
+ "RegExpConstructResult": true,
+ "_RegExpConstructResult": true,
+
+ // This functions perform some checks compile time (they require one of their
+ // arguments to be a compile time smi).
+ "_DateField": true,
+ "_GetFromCache": true,
+
+ // This function expects its first argument to be a non-smi.
+ "_IsStringWrapperSafeForDefaultValueOf" : true,
+
+ // Only applicable to strings.
+ "_HasCachedArrayIndex": true,
+ "_GetCachedArrayIndex": true
+};
+
+var currentlyUncallable = {
+ // We need to find a way to test this without breaking the system.
+ "SystemBreak": true
+};
+
+function testNatives() {
+ var allNatives = %ListNatives();
+ var start = 0;
+ var stop = (allNatives.length >> 2);
+ for (var i = start; i < stop; i++) {
+ var nativeInfo = allNatives[i];
+ var name = nativeInfo[0];
+ if (name in knownProblems || name in currentlyUncallable)
+ continue;
+ print(name);
+ var argc = nativeInfo[1];
+ testArgumentCount(name, argc);
+ testArgumentTypes(name, argc);
+ }
+}
+
+testNatives();
diff --git a/deps/v8/test/mjsunit/fuzz-natives-part2.js b/deps/v8/test/mjsunit/fuzz-natives-part2.js
new file mode 100644
index 000000000..ea8a2cfe1
--- /dev/null
+++ b/deps/v8/test/mjsunit/fuzz-natives-part2.js
@@ -0,0 +1,222 @@
+// Copyright 2011 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.
+
+// Flags: --allow-natives-syntax
+
+var RUN_WITH_ALL_ARGUMENT_ENTRIES = false;
+var kOnManyArgumentsRemove = 5;
+
+function makeArguments() {
+ var result = [ ];
+ result.push(17);
+ result.push(-31);
+ result.push(new Array(100));
+ result.push(new Array(100003));
+ result.push(Number.MIN_VALUE);
+ result.push("whoops");
+ result.push("x");
+ result.push({"x": 1, "y": 2});
+ var slowCaseObj = {"a": 3, "b": 4, "c": 5};
+ delete slowCaseObj.c;
+ result.push(slowCaseObj);
+ result.push(function () { return 8; });
+ return result;
+}
+
+var kArgObjects = makeArguments().length;
+
+function makeFunction(name, argc) {
+ var args = [];
+ for (var i = 0; i < argc; i++)
+ args.push("x" + i);
+ var argsStr = args.join(", ");
+ return new Function(args.join(", "), "return %" + name + "(" + argsStr + ");");
+}
+
+function testArgumentCount(name, argc) {
+ for (var i = 0; i < 10; i++) {
+ var func = null;
+ try {
+ func = makeFunction(name, i);
+ } catch (e) {
+ if (e != "SyntaxError: Illegal access") throw e;
+ }
+ if (func === null && i == argc) {
+ throw "unexpected exception";
+ }
+ var args = [ ];
+ for (var j = 0; j < i; j++)
+ args.push(0);
+ try {
+ func.apply(void 0, args);
+ } catch (e) {
+ // we don't care what happens as long as we don't crash
+ }
+ }
+}
+
+function testArgumentTypes(name, argc) {
+ var type = 0;
+ var hasMore = true;
+ var func = makeFunction(name, argc);
+ while (hasMore) {
+ var argPool = makeArguments();
+ // When we have 5 or more arguments we lower the amount of tests cases
+ // by randomly removing kOnManyArgumentsRemove entries
+ var numArguments = RUN_WITH_ALL_ARGUMENT_ENTRIES ?
+ kArgObjects : kArgObjects-kOnManyArgumentsRemove;
+ if (argc >= 5 && !RUN_WITH_ALL_ARGUMENT_ENTRIES) {
+ for (var i = 0; i < kOnManyArgumentsRemove; i++) {
+ var rand = Math.floor(Math.random() * (kArgObjects - i));
+ argPool.splice(rand,1);
+ }
+ }
+ var current = type;
+ var hasMore = false;
+ var argList = [ ];
+ for (var i = 0; i < argc; i++) {
+ var index = current % numArguments;
+ current = (current / numArguments) << 0;
+ if (index != (numArguments - 1))
+ hasMore = true;
+ argList.push(argPool[index]);
+ }
+ try {
+ func.apply(void 0, argList);
+ } catch (e) {
+ // we don't care what happens as long as we don't crash
+ }
+ type++;
+ }
+}
+
+var knownProblems = {
+ "Abort": true,
+
+ // Avoid calling the concat operation, because weird lengths
+ // may lead to out-of-memory. Ditto for StringBuilderJoin.
+ "StringBuilderConcat": true,
+ "StringBuilderJoin": true,
+
+ // These functions use pseudo-stack-pointers and are not robust
+ // to unexpected integer values.
+ "DebugEvaluate": true,
+
+ // These functions do nontrivial error checking in recursive calls,
+ // which means that we have to propagate errors back.
+ "SetFunctionBreakPoint": true,
+ "SetScriptBreakPoint": true,
+ "PrepareStep": true,
+
+ // Too slow.
+ "DebugReferencedBy": true,
+
+ // Calling disable/enable access checks may interfere with the
+ // the rest of the tests.
+ "DisableAccessChecks": true,
+ "EnableAccessChecks": true,
+
+ // These functions should not be callable as runtime functions.
+ "NewFunctionContext": true,
+ "NewArgumentsFast": true,
+ "NewStrictArgumentsFast": true,
+ "PushWithContext": true,
+ "PushCatchContext": true,
+ "PushBlockContext": true,
+ "LazyCompile": true,
+ "LazyRecompile": true,
+ "ParallelRecompile": true,
+ "NotifyDeoptimized": true,
+ "NotifyOSR": true,
+ "CreateObjectLiteralBoilerplate": true,
+ "CloneLiteralBoilerplate": true,
+ "CloneShallowLiteralBoilerplate": true,
+ "CreateArrayLiteralBoilerplate": true,
+ "IS_VAR": true,
+ "ResolvePossiblyDirectEval": true,
+ "Log": true,
+ "DeclareGlobals": true,
+
+ "PromoteScheduledException": true,
+ "DeleteHandleScopeExtensions": true,
+
+ // Vararg with minimum number > 0.
+ "Call": true,
+
+ // Requires integer arguments to be non-negative.
+ "Apply": true,
+
+ // That can only be invoked on Array.prototype.
+ "FinishArrayPrototypeSetup": true,
+
+ "_SwapElements": true,
+
+ // Performance critical functions which cannot afford type checks.
+ "_IsNativeOrStrictMode": true,
+ "_CallFunction": true,
+
+ // Tries to allocate based on argument, and (correctly) throws
+ // out-of-memory if the request is too large. In practice, the
+ // size will be the number of captures of a RegExp.
+ "RegExpConstructResult": true,
+ "_RegExpConstructResult": true,
+
+ // This functions perform some checks compile time (they require one of their
+ // arguments to be a compile time smi).
+ "_DateField": true,
+ "_GetFromCache": true,
+
+ // This function expects its first argument to be a non-smi.
+ "_IsStringWrapperSafeForDefaultValueOf" : true,
+
+ // Only applicable to strings.
+ "_HasCachedArrayIndex": true,
+ "_GetCachedArrayIndex": true
+};
+
+var currentlyUncallable = {
+ // We need to find a way to test this without breaking the system.
+ "SystemBreak": true
+};
+
+function testNatives() {
+ var allNatives = %ListNatives();
+ var start = allNatives.length >> 2;
+ var stop = (allNatives.length >> 2)*2;
+ for (var i = start; i < stop; i++) {
+ var nativeInfo = allNatives[i];
+ var name = nativeInfo[0];
+ if (name in knownProblems || name in currentlyUncallable)
+ continue;
+ print(name);
+ var argc = nativeInfo[1];
+ testArgumentCount(name, argc);
+ testArgumentTypes(name, argc);
+ }
+}
+
+testNatives();
diff --git a/deps/v8/test/mjsunit/fuzz-natives-part3.js b/deps/v8/test/mjsunit/fuzz-natives-part3.js
new file mode 100644
index 000000000..ecfdf9737
--- /dev/null
+++ b/deps/v8/test/mjsunit/fuzz-natives-part3.js
@@ -0,0 +1,222 @@
+// Copyright 2011 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.
+
+// Flags: --allow-natives-syntax
+
+var RUN_WITH_ALL_ARGUMENT_ENTRIES = false;
+var kOnManyArgumentsRemove = 5;
+
+function makeArguments() {
+ var result = [ ];
+ result.push(17);
+ result.push(-31);
+ result.push(new Array(100));
+ result.push(new Array(100003));
+ result.push(Number.MIN_VALUE);
+ result.push("whoops");
+ result.push("x");
+ result.push({"x": 1, "y": 2});
+ var slowCaseObj = {"a": 3, "b": 4, "c": 5};
+ delete slowCaseObj.c;
+ result.push(slowCaseObj);
+ result.push(function () { return 8; });
+ return result;
+}
+
+var kArgObjects = makeArguments().length;
+
+function makeFunction(name, argc) {
+ var args = [];
+ for (var i = 0; i < argc; i++)
+ args.push("x" + i);
+ var argsStr = args.join(", ");
+ return new Function(args.join(", "), "return %" + name + "(" + argsStr + ");");
+}
+
+function testArgumentCount(name, argc) {
+ for (var i = 0; i < 10; i++) {
+ var func = null;
+ try {
+ func = makeFunction(name, i);
+ } catch (e) {
+ if (e != "SyntaxError: Illegal access") throw e;
+ }
+ if (func === null && i == argc) {
+ throw "unexpected exception";
+ }
+ var args = [ ];
+ for (var j = 0; j < i; j++)
+ args.push(0);
+ try {
+ func.apply(void 0, args);
+ } catch (e) {
+ // we don't care what happens as long as we don't crash
+ }
+ }
+}
+
+function testArgumentTypes(name, argc) {
+ var type = 0;
+ var hasMore = true;
+ var func = makeFunction(name, argc);
+ while (hasMore) {
+ var argPool = makeArguments();
+ // When we have 5 or more arguments we lower the amount of tests cases
+ // by randomly removing kOnManyArgumentsRemove entries
+ var numArguments = RUN_WITH_ALL_ARGUMENT_ENTRIES ?
+ kArgObjects : kArgObjects-kOnManyArgumentsRemove;
+ if (argc >= 5 && !RUN_WITH_ALL_ARGUMENT_ENTRIES) {
+ for (var i = 0; i < kOnManyArgumentsRemove; i++) {
+ var rand = Math.floor(Math.random() * (kArgObjects - i));
+ argPool.splice(rand,1);
+ }
+ }
+ var current = type;
+ var hasMore = false;
+ var argList = [ ];
+ for (var i = 0; i < argc; i++) {
+ var index = current % numArguments;
+ current = (current / numArguments) << 0;
+ if (index != (numArguments - 1))
+ hasMore = true;
+ argList.push(argPool[index]);
+ }
+ try {
+ func.apply(void 0, argList);
+ } catch (e) {
+ // we don't care what happens as long as we don't crash
+ }
+ type++;
+ }
+}
+
+var knownProblems = {
+ "Abort": true,
+
+ // Avoid calling the concat operation, because weird lengths
+ // may lead to out-of-memory. Ditto for StringBuilderJoin.
+ "StringBuilderConcat": true,
+ "StringBuilderJoin": true,
+
+ // These functions use pseudo-stack-pointers and are not robust
+ // to unexpected integer values.
+ "DebugEvaluate": true,
+
+ // These functions do nontrivial error checking in recursive calls,
+ // which means that we have to propagate errors back.
+ "SetFunctionBreakPoint": true,
+ "SetScriptBreakPoint": true,
+ "PrepareStep": true,
+
+ // Too slow.
+ "DebugReferencedBy": true,
+
+ // Calling disable/enable access checks may interfere with the
+ // the rest of the tests.
+ "DisableAccessChecks": true,
+ "EnableAccessChecks": true,
+
+ // These functions should not be callable as runtime functions.
+ "NewFunctionContext": true,
+ "NewArgumentsFast": true,
+ "NewStrictArgumentsFast": true,
+ "PushWithContext": true,
+ "PushCatchContext": true,
+ "PushBlockContext": true,
+ "LazyCompile": true,
+ "LazyRecompile": true,
+ "ParallelRecompile": true,
+ "NotifyDeoptimized": true,
+ "NotifyOSR": true,
+ "CreateObjectLiteralBoilerplate": true,
+ "CloneLiteralBoilerplate": true,
+ "CloneShallowLiteralBoilerplate": true,
+ "CreateArrayLiteralBoilerplate": true,
+ "IS_VAR": true,
+ "ResolvePossiblyDirectEval": true,
+ "Log": true,
+ "DeclareGlobals": true,
+
+ "PromoteScheduledException": true,
+ "DeleteHandleScopeExtensions": true,
+
+ // Vararg with minimum number > 0.
+ "Call": true,
+
+ // Requires integer arguments to be non-negative.
+ "Apply": true,
+
+ // That can only be invoked on Array.prototype.
+ "FinishArrayPrototypeSetup": true,
+
+ "_SwapElements": true,
+
+ // Performance critical functions which cannot afford type checks.
+ "_IsNativeOrStrictMode": true,
+ "_CallFunction": true,
+
+ // Tries to allocate based on argument, and (correctly) throws
+ // out-of-memory if the request is too large. In practice, the
+ // size will be the number of captures of a RegExp.
+ "RegExpConstructResult": true,
+ "_RegExpConstructResult": true,
+
+ // This functions perform some checks compile time (they require one of their
+ // arguments to be a compile time smi).
+ "_DateField": true,
+ "_GetFromCache": true,
+
+ // This function expects its first argument to be a non-smi.
+ "_IsStringWrapperSafeForDefaultValueOf" : true,
+
+ // Only applicable to strings.
+ "_HasCachedArrayIndex": true,
+ "_GetCachedArrayIndex": true
+};
+
+var currentlyUncallable = {
+ // We need to find a way to test this without breaking the system.
+ "SystemBreak": true
+};
+
+function testNatives() {
+ var allNatives = %ListNatives();
+ var start = (allNatives.length >> 2)*2;
+ var stop = (allNatives.length >> 2)*3;
+ for (var i = start; i < stop; i++) {
+ var nativeInfo = allNatives[i];
+ var name = nativeInfo[0];
+ if (name in knownProblems || name in currentlyUncallable)
+ continue;
+ print(name);
+ var argc = nativeInfo[1];
+ testArgumentCount(name, argc);
+ testArgumentTypes(name, argc);
+ }
+}
+
+testNatives();
diff --git a/deps/v8/test/mjsunit/fuzz-natives-part4.js b/deps/v8/test/mjsunit/fuzz-natives-part4.js
new file mode 100644
index 000000000..da045963f
--- /dev/null
+++ b/deps/v8/test/mjsunit/fuzz-natives-part4.js
@@ -0,0 +1,222 @@
+// Copyright 2011 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.
+
+// Flags: --allow-natives-syntax
+
+var RUN_WITH_ALL_ARGUMENT_ENTRIES = false;
+var kOnManyArgumentsRemove = 5;
+
+function makeArguments() {
+ var result = [ ];
+ result.push(17);
+ result.push(-31);
+ result.push(new Array(100));
+ result.push(new Array(100003));
+ result.push(Number.MIN_VALUE);
+ result.push("whoops");
+ result.push("x");
+ result.push({"x": 1, "y": 2});
+ var slowCaseObj = {"a": 3, "b": 4, "c": 5};
+ delete slowCaseObj.c;
+ result.push(slowCaseObj);
+ result.push(function () { return 8; });
+ return result;
+}
+
+var kArgObjects = makeArguments().length;
+
+function makeFunction(name, argc) {
+ var args = [];
+ for (var i = 0; i < argc; i++)
+ args.push("x" + i);
+ var argsStr = args.join(", ");
+ return new Function(args.join(", "), "return %" + name + "(" + argsStr + ");");
+}
+
+function testArgumentCount(name, argc) {
+ for (var i = 0; i < 10; i++) {
+ var func = null;
+ try {
+ func = makeFunction(name, i);
+ } catch (e) {
+ if (e != "SyntaxError: Illegal access") throw e;
+ }
+ if (func === null && i == argc) {
+ throw "unexpected exception";
+ }
+ var args = [ ];
+ for (var j = 0; j < i; j++)
+ args.push(0);
+ try {
+ func.apply(void 0, args);
+ } catch (e) {
+ // we don't care what happens as long as we don't crash
+ }
+ }
+}
+
+function testArgumentTypes(name, argc) {
+ var type = 0;
+ var hasMore = true;
+ var func = makeFunction(name, argc);
+ while (hasMore) {
+ var argPool = makeArguments();
+ // When we have 5 or more arguments we lower the amount of tests cases
+ // by randomly removing kOnManyArgumentsRemove entries
+ var numArguments = RUN_WITH_ALL_ARGUMENT_ENTRIES ?
+ kArgObjects : kArgObjects-kOnManyArgumentsRemove;
+ if (argc >= 5 && !RUN_WITH_ALL_ARGUMENT_ENTRIES) {
+ for (var i = 0; i < kOnManyArgumentsRemove; i++) {
+ var rand = Math.floor(Math.random() * (kArgObjects - i));
+ argPool.splice(rand,1);
+ }
+ }
+ var current = type;
+ var hasMore = false;
+ var argList = [ ];
+ for (var i = 0; i < argc; i++) {
+ var index = current % numArguments;
+ current = (current / numArguments) << 0;
+ if (index != (numArguments - 1))
+ hasMore = true;
+ argList.push(argPool[index]);
+ }
+ try {
+ func.apply(void 0, argList);
+ } catch (e) {
+ // we don't care what happens as long as we don't crash
+ }
+ type++;
+ }
+}
+
+var knownProblems = {
+ "Abort": true,
+
+ // Avoid calling the concat operation, because weird lengths
+ // may lead to out-of-memory. Ditto for StringBuilderJoin.
+ "StringBuilderConcat": true,
+ "StringBuilderJoin": true,
+
+ // These functions use pseudo-stack-pointers and are not robust
+ // to unexpected integer values.
+ "DebugEvaluate": true,
+
+ // These functions do nontrivial error checking in recursive calls,
+ // which means that we have to propagate errors back.
+ "SetFunctionBreakPoint": true,
+ "SetScriptBreakPoint": true,
+ "PrepareStep": true,
+
+ // Too slow.
+ "DebugReferencedBy": true,
+
+ // Calling disable/enable access checks may interfere with the
+ // the rest of the tests.
+ "DisableAccessChecks": true,
+ "EnableAccessChecks": true,
+
+ // These functions should not be callable as runtime functions.
+ "NewFunctionContext": true,
+ "NewArgumentsFast": true,
+ "NewStrictArgumentsFast": true,
+ "PushWithContext": true,
+ "PushCatchContext": true,
+ "PushBlockContext": true,
+ "LazyCompile": true,
+ "LazyRecompile": true,
+ "ParallelRecompile": true,
+ "NotifyDeoptimized": true,
+ "NotifyOSR": true,
+ "CreateObjectLiteralBoilerplate": true,
+ "CloneLiteralBoilerplate": true,
+ "CloneShallowLiteralBoilerplate": true,
+ "CreateArrayLiteralBoilerplate": true,
+ "IS_VAR": true,
+ "ResolvePossiblyDirectEval": true,
+ "Log": true,
+ "DeclareGlobals": true,
+
+ "PromoteScheduledException": true,
+ "DeleteHandleScopeExtensions": true,
+
+ // Vararg with minimum number > 0.
+ "Call": true,
+
+ // Requires integer arguments to be non-negative.
+ "Apply": true,
+
+ // That can only be invoked on Array.prototype.
+ "FinishArrayPrototypeSetup": true,
+
+ "_SwapElements": true,
+
+ // Performance critical functions which cannot afford type checks.
+ "_IsNativeOrStrictMode": true,
+ "_CallFunction": true,
+
+ // Tries to allocate based on argument, and (correctly) throws
+ // out-of-memory if the request is too large. In practice, the
+ // size will be the number of captures of a RegExp.
+ "RegExpConstructResult": true,
+ "_RegExpConstructResult": true,
+
+ // This functions perform some checks compile time (they require one of their
+ // arguments to be a compile time smi).
+ "_DateField": true,
+ "_GetFromCache": true,
+
+ // This function expects its first argument to be a non-smi.
+ "_IsStringWrapperSafeForDefaultValueOf" : true,
+
+ // Only applicable to strings.
+ "_HasCachedArrayIndex": true,
+ "_GetCachedArrayIndex": true
+};
+
+var currentlyUncallable = {
+ // We need to find a way to test this without breaking the system.
+ "SystemBreak": true
+};
+
+function testNatives() {
+ var allNatives = %ListNatives();
+ var start = (allNatives.length >> 2)*3;
+ var stop = allNatives.length;
+ for (var i = start; i < stop; i++) {
+ var nativeInfo = allNatives[i];
+ var name = nativeInfo[0];
+ if (name in knownProblems || name in currentlyUncallable)
+ continue;
+ print(name);
+ var argc = nativeInfo[1];
+ testArgumentCount(name, argc);
+ testArgumentTypes(name, argc);
+ }
+}
+
+testNatives();
diff --git a/deps/v8/test/mjsunit/fuzz-natives.js b/deps/v8/test/mjsunit/fuzz-natives.js
deleted file mode 100644
index 2965e7457..000000000
--- a/deps/v8/test/mjsunit/fuzz-natives.js
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2011 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.
-
-// Flags: --allow-natives-syntax
-
-var RUN_WITH_ALL_ARGUMENT_ENTRIES = false;
-var kOnManyArgumentsRemove = 5;
-
-function makeArguments() {
- var result = [ ];
- result.push(17);
- result.push(-31);
- result.push(new Array(100));
- result.push(new Array(100003));
- result.push(Number.MIN_VALUE);
- result.push("whoops");
- result.push("x");
- result.push({"x": 1, "y": 2});
- var slowCaseObj = {"a": 3, "b": 4, "c": 5};
- delete slowCaseObj.c;
- result.push(slowCaseObj);
- result.push(function () { return 8; });
- return result;
-}
-
-var kArgObjects = makeArguments().length;
-
-function makeFunction(name, argc) {
- var args = [];
- for (var i = 0; i < argc; i++)
- args.push("x" + i);
- var argsStr = args.join(", ");
- return new Function(args.join(", "), "return %" + name + "(" + argsStr + ");");
-}
-
-function testArgumentCount(name, argc) {
- for (var i = 0; i < 10; i++) {
- var func = null;
- try {
- func = makeFunction(name, i);
- } catch (e) {
- if (e != "SyntaxError: Illegal access") throw e;
- }
- if (func === null && i == argc) {
- throw "unexpected exception";
- }
- var args = [ ];
- for (var j = 0; j < i; j++)
- args.push(0);
- try {
- func.apply(void 0, args);
- } catch (e) {
- // we don't care what happens as long as we don't crash
- }
- }
-}
-
-function testArgumentTypes(name, argc) {
- var type = 0;
- var hasMore = true;
- var func = makeFunction(name, argc);
- while (hasMore) {
- var argPool = makeArguments();
- // When we have 5 or more arguments we lower the amount of tests cases
- // by randomly removing kOnManyArgumentsRemove entries
- var numArguments = RUN_WITH_ALL_ARGUMENT_ENTRIES ?
- kArgObjects : kArgObjects-kOnManyArgumentsRemove;
- if (argc >= 5 && !RUN_WITH_ALL_ARGUMENT_ENTRIES) {
- for (var i = 0; i < kOnManyArgumentsRemove; i++) {
- var rand = Math.floor(Math.random() * (kArgObjects - i));
- argPool.splice(rand,1);
- }
- }
- var current = type;
- var hasMore = false;
- var argList = [ ];
- for (var i = 0; i < argc; i++) {
- var index = current % numArguments;
- current = (current / numArguments) << 0;
- if (index != (numArguments - 1))
- hasMore = true;
- argList.push(argPool[index]);
- }
- try {
- func.apply(void 0, argList);
- } catch (e) {
- // we don't care what happens as long as we don't crash
- }
- type++;
- }
-}
-
-var knownProblems = {
- "Abort": true,
-
- // Avoid calling the concat operation, because weird lengths
- // may lead to out-of-memory. Ditto for StringBuilderJoin.
- "StringBuilderConcat": true,
- "StringBuilderJoin": true,
-
- // These functions use pseudo-stack-pointers and are not robust
- // to unexpected integer values.
- "DebugEvaluate": true,
-
- // These functions do nontrivial error checking in recursive calls,
- // which means that we have to propagate errors back.
- "SetFunctionBreakPoint": true,
- "SetScriptBreakPoint": true,
- "PrepareStep": true,
-
- // Too slow.
- "DebugReferencedBy": true,
-
- // Calling disable/enable access checks may interfere with the
- // the rest of the tests.
- "DisableAccessChecks": true,
- "EnableAccessChecks": true,
-
- // These functions should not be callable as runtime functions.
- "NewFunctionContext": true,
- "NewArgumentsFast": true,
- "NewStrictArgumentsFast": true,
- "PushWithContext": true,
- "PushCatchContext": true,
- "PushBlockContext": true,
- "LazyCompile": true,
- "LazyRecompile": true,
- "NotifyDeoptimized": true,
- "NotifyOSR": true,
- "CreateObjectLiteralBoilerplate": true,
- "CloneLiteralBoilerplate": true,
- "CloneShallowLiteralBoilerplate": true,
- "CreateArrayLiteralBoilerplate": true,
- "IS_VAR": true,
- "ResolvePossiblyDirectEval": true,
- "Log": true,
- "DeclareGlobals": true,
-
- "PromoteScheduledException": true,
- "DeleteHandleScopeExtensions": true,
-
- // Vararg with minimum number > 0.
- "Call": true,
-
- // Requires integer arguments to be non-negative.
- "Apply": true,
-
- // That can only be invoked on Array.prototype.
- "FinishArrayPrototypeSetup": true,
-
- "_SwapElements": true,
-
- // Performance critical functions which cannot afford type checks.
- "_IsNativeOrStrictMode": true,
- "_CallFunction": true,
-
- // Tries to allocate based on argument, and (correctly) throws
- // out-of-memory if the request is too large. In practice, the
- // size will be the number of captures of a RegExp.
- "RegExpConstructResult": true,
- "_RegExpConstructResult": true,
-
- // This functions perform some checks compile time (they require one of their
- // arguments to be a compile time smi).
- "_DateField": true,
- "_GetFromCache": true,
-
- // This function expects its first argument to be a non-smi.
- "_IsStringWrapperSafeForDefaultValueOf" : true,
-
- // Only applicable to strings.
- "_HasCachedArrayIndex": true,
- "_GetCachedArrayIndex": true
-};
-
-var currentlyUncallable = {
- // We need to find a way to test this without breaking the system.
- "SystemBreak": true
-};
-
-function testNatives() {
- var allNatives = %ListNatives();
- for (var i = 0; i < allNatives.length; i++) {
- var nativeInfo = allNatives[i];
- var name = nativeInfo[0];
- if (name in knownProblems || name in currentlyUncallable)
- continue;
- print(name);
- var argc = nativeInfo[1];
- testArgumentCount(name, argc);
- testArgumentTypes(name, argc);
- }
-}
-
-testNatives();
diff --git a/deps/v8/test/mjsunit/greedy.js b/deps/v8/test/mjsunit/greedy.js
index d357f0cad..8c49e41b9 100644
--- a/deps/v8/test/mjsunit/greedy.js
+++ b/deps/v8/test/mjsunit/greedy.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --gc-greedy
+// Flags: --gc-greedy --noverify-heap
function IterativeFib(n) {
var f0 = 0, f1 = 1;
diff --git a/deps/v8/test/mjsunit/harmony/block-conflicts.js b/deps/v8/test/mjsunit/harmony/block-conflicts.js
index 8388504bc..3aa9d2222 100644
--- a/deps/v8/test/mjsunit/harmony/block-conflicts.js
+++ b/deps/v8/test/mjsunit/harmony/block-conflicts.js
@@ -35,7 +35,8 @@
function CheckException(e) {
var string = e.toString();
assertTrue(string.indexOf("has already been declared") >= 0 ||
- string.indexOf("redeclaration") >= 0); return 'Conflict';
+ string.indexOf("redeclaration") >= 0);
+ return 'Conflict';
}
diff --git a/deps/v8/test/mjsunit/harmony/block-let-crankshaft.js b/deps/v8/test/mjsunit/harmony/block-let-crankshaft.js
index 1db1792ea..d01e5c08a 100644
--- a/deps/v8/test/mjsunit/harmony/block-let-crankshaft.js
+++ b/deps/v8/test/mjsunit/harmony/block-let-crankshaft.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-scoping --allow-natives-syntax
+// Flags: --harmony-scoping --allow-natives-syntax --noparallel-recompilation
// TODO(ES6): properly activate extended mode
"use strict";
diff --git a/deps/v8/test/mjsunit/harmony/collections.js b/deps/v8/test/mjsunit/harmony/collections.js
index 412e6f14c..f3db7ea2b 100644
--- a/deps/v8/test/mjsunit/harmony/collections.js
+++ b/deps/v8/test/mjsunit/harmony/collections.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -65,9 +65,11 @@ TestInvalidCalls(new WeakMap);
// Test expected behavior for Sets
function TestSet(set, key) {
assertFalse(set.has(key));
- set.add(key);
+ assertSame(undefined, set.add(key));
assertTrue(set.has(key));
- set.delete(key);
+ assertTrue(set.delete(key));
+ assertFalse(set.has(key));
+ assertFalse(set.delete(key));
assertFalse(set.has(key));
}
function TestSetBehavior(set) {
@@ -87,7 +89,7 @@ TestSetBehavior(new Set);
// Test expected mapping behavior for Maps and WeakMaps
function TestMapping(map, key, value) {
- map.set(key, value);
+ assertSame(undefined, map.set(key, value));
assertSame(value, map.get(key));
}
function TestMapBehavior1(m) {
@@ -117,12 +119,12 @@ TestMapBehavior2(new Map);
// Test expected querying behavior of Maps and WeakMaps
function TestQuery(m) {
var key = new Object;
- TestMapping(m, key, 'to-be-present');
- assertTrue(m.has(key));
- assertFalse(m.has(new Object));
- TestMapping(m, key, undefined);
- assertFalse(m.has(key));
- assertFalse(m.has(new Object));
+ var values = [ 'x', 0, +Infinity, -Infinity, true, false, null, undefined ];
+ for (var i = 0; i < values.length; i++) {
+ TestMapping(m, key, values[i]);
+ assertTrue(m.has(key));
+ assertFalse(m.has(new Object));
+ }
}
TestQuery(new Map);
TestQuery(new WeakMap);
diff --git a/deps/v8/test/mjsunit/harmony/debug-blockscopes.js b/deps/v8/test/mjsunit/harmony/debug-blockscopes.js
index 10aac2dbd..ca2ab9e5a 100644
--- a/deps/v8/test/mjsunit/harmony/debug-blockscopes.js
+++ b/deps/v8/test/mjsunit/harmony/debug-blockscopes.js
@@ -376,7 +376,7 @@ listener_delegate = function(exec_state) {
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:'y'}, 0, exec_state);
// The function scope contains a temporary iteration variable.
- CheckScopeContent({x:'y'}, 1, exec_state);
+ CheckScopeContent({'.for.x':'y'}, 1, exec_state);
};
for_loop_1();
EndTest();
@@ -401,7 +401,7 @@ listener_delegate = function(exec_state) {
CheckScopeContent({x:3}, 0, exec_state);
CheckScopeContent({x:'y'}, 1, exec_state);
// The function scope contains a temporary iteration variable.
- CheckScopeContent({x:'y'}, 2, exec_state);
+ CheckScopeContent({'.for.x':'y'}, 2, exec_state);
};
for_loop_2();
EndTest();
diff --git a/deps/v8/test/mjsunit/harmony/module-linking.js b/deps/v8/test/mjsunit/harmony/module-linking.js
index 13ca6f782..a4b272f46 100644
--- a/deps/v8/test/mjsunit/harmony/module-linking.js
+++ b/deps/v8/test/mjsunit/harmony/module-linking.js
@@ -27,10 +27,188 @@
// Flags: --harmony-modules --harmony-scoping
-// Test basic module linking.
+// Test basic module linking and initialization.
"use strict";
+module R {
+ // At this point, only functions and modules are initialized.
+ assertEquals(undefined, v)
+ assertEquals(undefined, vv)
+ assertEquals(undefined, R.v)
+ assertEquals(undefined, M.v)
+ assertEquals(undefined, MM.v)
+ assertEquals(undefined, F.v)
+ assertEquals(undefined, G.v)
+ assertThrows(function() { l }, ReferenceError)
+ assertThrows(function() { ll }, ReferenceError)
+ assertThrows(function() { R.l }, ReferenceError)
+ assertThrows(function() { M.l }, ReferenceError)
+ assertThrows(function() { MM.l }, ReferenceError)
+ assertThrows(function() { F.l }, ReferenceError)
+ assertThrows(function() { G.l }, ReferenceError)
+ assertThrows(function() { c }, ReferenceError)
+ assertThrows(function() { cc }, ReferenceError)
+ assertThrows(function() { R.c }, ReferenceError)
+ assertThrows(function() { M.c }, ReferenceError)
+ assertThrows(function() { MM.c }, ReferenceError)
+ assertThrows(function() { F.c }, ReferenceError)
+ assertThrows(function() { G.c }, ReferenceError)
+ assertEquals(4, f())
+ assertEquals(24, ff())
+ assertEquals(4, R.f())
+ assertEquals(14, M.f())
+ assertEquals(34, MM.f())
+ assertEquals(44, F.f())
+ assertEquals(14, G.f())
+
+ // All properties should already exist on the instance objects, though.
+ assertTrue("v" in R)
+ assertTrue("v" in RR)
+ assertTrue("v" in M)
+ assertTrue("v" in MM)
+ assertTrue("v" in F)
+ assertTrue("v" in G)
+ assertTrue("l" in R)
+ assertTrue("l" in RR)
+ assertTrue("l" in M)
+ assertTrue("l" in MM)
+ assertTrue("l" in F)
+ assertTrue("l" in G)
+ assertTrue("c" in R)
+ assertTrue("c" in RR)
+ assertTrue("c" in M)
+ assertTrue("c" in MM)
+ assertTrue("c" in F)
+ assertTrue("c" in G)
+ assertTrue("f" in R)
+ assertTrue("f" in RR)
+ assertTrue("f" in M)
+ assertTrue("f" in MM)
+ assertTrue("f" in F)
+ assertTrue("f" in G)
+ assertTrue("M" in R)
+ assertTrue("M" in RR)
+ assertTrue("RR" in R)
+ assertTrue("RR" in RR)
+
+ // And aliases should be identical.
+ assertSame(R, RR)
+ assertSame(R, R.RR)
+ assertSame(M, R.M)
+ assertSame(M, G)
+
+ // We can only assign to var.
+ assertEquals(-1, v = -1)
+ assertEquals(-2, R.v = -2)
+ assertEquals(-2, v)
+ assertEquals(-2, R.v)
+
+ assertThrows(function() { l = -1 }, ReferenceError)
+ assertThrows(function() { R.l = -2 }, ReferenceError)
+ assertThrows(function() { l }, ReferenceError)
+ assertThrows(function() { R.l }, ReferenceError)
+
+ assertThrows(function() { eval("c = -1") }, SyntaxError)
+ assertThrows(function() { R.c = -2 }, TypeError)
+
+ // Initialize first bunch or variables.
+ export var v = 1
+ export let l = 2
+ export const c = 3
+ export function f() { return 4 }
+
+ assertEquals(1, v)
+ assertEquals(1, R.v)
+ assertEquals(2, l)
+ assertEquals(2, R.l)
+ assertEquals(3, c)
+ assertEquals(3, R.c)
+
+ assertEquals(-3, v = -3)
+ assertEquals(-4, R.v = -4)
+ assertEquals(-3, l = -3)
+ assertEquals(-4, R.l = -4)
+ assertThrows(function() { eval("c = -3") }, SyntaxError)
+ assertThrows(function() { R.c = -4 }, TypeError)
+
+ assertEquals(-4, v)
+ assertEquals(-4, R.v)
+ assertEquals(-4, l)
+ assertEquals(-4, R.l)
+ assertEquals(3, c)
+ assertEquals(3, R.c)
+
+ // Initialize nested module.
+ export module M {
+ export var v = 11
+ export let l = 12
+ export const c = 13
+ export function f() { return 14 }
+ }
+
+ assertEquals(11, M.v)
+ assertEquals(11, G.v)
+ assertEquals(12, M.l)
+ assertEquals(12, G.l)
+ assertEquals(13, M.c)
+ assertEquals(13, G.c)
+
+ // Initialize non-exported variables.
+ var vv = 21
+ let ll = 22
+ const cc = 23
+ function ff() { return 24 }
+
+ assertEquals(21, vv)
+ assertEquals(22, ll)
+ assertEquals(23, cc)
+
+ // Initialize non-exported module.
+ module MM {
+ export var v = 31
+ export let l = 32
+ export const c = 33
+ export function f() { return 34 }
+ }
+
+ assertEquals(31, MM.v)
+ assertEquals(32, MM.l)
+ assertEquals(33, MM.c)
+
+ // Recursive self reference.
+ export module RR = R
+}
+
+// Initialize sibling module that was forward-used.
+module F {
+ assertEquals(undefined, v)
+ assertEquals(undefined, F.v)
+ assertThrows(function() { l }, ReferenceError)
+ assertThrows(function() { F.l }, ReferenceError)
+ assertThrows(function() { c }, ReferenceError)
+ assertThrows(function() { F.c }, ReferenceError)
+
+ export var v = 41
+ export let l = 42
+ export const c = 43
+ export function f() { return 44 }
+
+ assertEquals(41, v)
+ assertEquals(41, F.v)
+ assertEquals(42, l)
+ assertEquals(42, F.l)
+ assertEquals(43, c)
+ assertEquals(43, F.c)
+}
+
+// Define recursive module alias.
+module G = R.M
+
+
+
+// Second test with side effects and more module nesting.
+
let log = "";
export let x = (log += "1");
@@ -117,5 +295,4 @@ assertSame(M2, M1.A2);
assertSame(M1, M1.A2.A1);
assertSame(M2, M2.A1.A2);
-// TODO(rossberg): inner declarations are not executed yet.
-// assertEquals("1234567890", log);
+assertEquals("1234567890", log);
diff --git a/deps/v8/test/mjsunit/harmony/module-parsing.js b/deps/v8/test/mjsunit/harmony/module-parsing.js
index cdd0a2e00..8a9103d13 100644
--- a/deps/v8/test/mjsunit/harmony/module-parsing.js
+++ b/deps/v8/test/mjsunit/harmony/module-parsing.js
@@ -116,6 +116,11 @@ x
,
y
+var
+x
+,
+y
+
export
var
v1 = 1
@@ -157,3 +162,29 @@ try {} catch (module) {}
module
v = 20
+
+
+
+// Check that module declarations are rejected in eval or local scope.
+
+module M { export let x; }
+
+assertThrows("export x;", SyntaxError); // It's using eval, so should throw.
+assertThrows("export let x;", SyntaxError);
+assertThrows("import x from M;", SyntaxError);
+assertThrows("module M {};", SyntaxError);
+
+assertThrows("{ export x; }", SyntaxError);
+assertThrows("{ export let x; }", SyntaxError);
+assertThrows("{ import x from M; }", SyntaxError);
+assertThrows("{ module M {}; }", SyntaxError);
+
+assertThrows("function f() { export x; }", SyntaxError);
+assertThrows("function f() { export let x; }", SyntaxError);
+assertThrows("function f() { import x from M; }", SyntaxError);
+assertThrows("function f() { module M {}; }", SyntaxError);
+
+assertThrows("function f() { { export x; } }", SyntaxError);
+assertThrows("function f() { { export let x; } }", SyntaxError);
+assertThrows("function f() { { import x from M; } }", SyntaxError);
+assertThrows("function f() { { module M {}; } }", SyntaxError);
diff --git a/deps/v8/test/mjsunit/harmony/module-recompile.js b/deps/v8/test/mjsunit/harmony/module-recompile.js
new file mode 100644
index 000000000..23f5bfc4d
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/module-recompile.js
@@ -0,0 +1,87 @@
+// Copyright 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.
+
+// Flags: --harmony-modules
+
+// Test that potential recompilation of the global scope does not screw up.
+
+"use strict";
+
+var N = 1e5; // Number of loop iterations that trigger optimization.
+
+module A {
+ export var x = 1
+ export function f() { return x }
+}
+var f = A.f
+
+assertEquals(1, A.x)
+assertEquals(1, A.f())
+assertEquals(1, f())
+
+A.x = 2
+
+assertEquals(2, A.x)
+assertEquals(2, A.f())
+assertEquals(2, f())
+
+for (var i = 0; i < N; i++) {
+ if (i > N) print("impossible");
+}
+
+assertEquals(2, A.x)
+assertEquals(2, A.f())
+assertEquals(2, f())
+
+
+// Same test with loop inside a module.
+
+module B {
+ module A {
+ export var x = 1
+ export function f() { return x }
+ }
+ var f = A.f
+
+ assertEquals(1, A.x)
+ assertEquals(1, A.f())
+ assertEquals(1, f())
+
+ A.x = 2
+
+ assertEquals(2, A.x)
+ assertEquals(2, A.f())
+ assertEquals(2, f())
+
+ for (var i = 0; i < N; i++) {
+ if (i > N) print("impossible");
+ }
+
+ assertEquals(2, A.x)
+ assertEquals(2, A.f())
+ assertEquals(2, f())
+}
diff --git a/deps/v8/test/mjsunit/harmony/module-resolution.js b/deps/v8/test/mjsunit/harmony/module-resolution.js
index a1b991749..1a95347d1 100644
--- a/deps/v8/test/mjsunit/harmony/module-resolution.js
+++ b/deps/v8/test/mjsunit/harmony/module-resolution.js
@@ -33,6 +33,7 @@
print("begin.")
+
export let x = print("0")
export module B = A.B
@@ -44,15 +45,25 @@ export module A {
module BB = B
export BB, x
let x = print("2")
- let y = print("3")
+ var y = print("3")
let Ax = A.x
+ try { A.y } catch (e) {} // throws
+ let Az = A.z // undefined
+ let Az2 = z // undefined
+ A.g() // hoisted
+ g() // hoisted
let ABx = A.B.x
- let Ay = A.y
+ let ABy = A.B.y
+ let Bx = B.x
+ let By = B.y
let BBx = BB.x
+ let BBy = BB.y
let Af = A.f
function f(x,y) { return x }
}
export let y = print("4")
+ export var z = print("4.1")
+ export function g() {}
let Ax = A.x
let Bx = B.x
let ABx = A.B.x
@@ -92,6 +103,8 @@ export module E {
let Bx = B.x
// TODO(rossberg): Handle import *.
// import A.*
+ module B = A.B
+ let y = A.y
}
export module M1 {
diff --git a/deps/v8/test/mjsunit/json.js b/deps/v8/test/mjsunit/json.js
index bead376f8..54fa1854f 100644
--- a/deps/v8/test/mjsunit/json.js
+++ b/deps/v8/test/mjsunit/json.js
@@ -428,5 +428,5 @@ var o = JSON.parse('{"__proto__":5}');
assertEquals(Object.prototype, o.__proto__); // __proto__ isn't changed.
assertEquals(0, Object.keys(o).length); // __proto__ isn't added as enumerable.
-
-
+var json = '{"stuff before slash\\\\stuff after slash":"whatever"}';
+assertEquals(json, JSON.stringify(JSON.parse(json)));
diff --git a/deps/v8/test/mjsunit/limit-locals.js b/deps/v8/test/mjsunit/limit-locals.js
index ad9ec4368..a166f3061 100644
--- a/deps/v8/test/mjsunit/limit-locals.js
+++ b/deps/v8/test/mjsunit/limit-locals.js
@@ -25,7 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Test that there is a limit of 32767 locals.
+// Test that there is a limit of 131071 locals.
+
+// Flags: --stack-size=1200
function function_with_n_locals(n) {
test_prefix = "prefix ";
@@ -40,7 +42,6 @@ function function_with_n_locals(n) {
assertEquals("prefix 0 suffix", function_with_n_locals(0));
assertEquals("prefix 16000 suffix", function_with_n_locals(16000));
-assertEquals("prefix 32767 suffix", function_with_n_locals(32767));
+assertEquals("prefix 131071 suffix", function_with_n_locals(131071));
-assertThrows("function_with_n_locals(32768)");
-assertThrows("function_with_n_locals(100000)");
+assertThrows("function_with_n_locals(131072)");
diff --git a/deps/v8/test/mjsunit/math-floor-negative.js b/deps/v8/test/mjsunit/math-floor-negative.js
new file mode 100644
index 000000000..4cabff577
--- /dev/null
+++ b/deps/v8/test/mjsunit/math-floor-negative.js
@@ -0,0 +1,59 @@
+// Copyright 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.
+
+// Flags: --noenable_sse4_1 --allow-natives-syntax
+
+function test1() {
+ // Trigger overflow when converting/truncating double to integer.
+ // Divide by 10 to avoid overflow when smi-tagging at the end.
+ return Math.floor(-100000000000.5) / 10;
+}
+
+function test2() {
+ // Trigger no overflow.
+ return Math.floor(-100.2);
+}
+
+function test3() {
+ // Trigger overflow when compensating by subtracting after compare.
+ // Divide by 10 to avoid overflow when smi-tagging at the end.
+ return Math.floor(-2147483648.1) / 10;
+}
+
+test1();
+test1();
+%OptimizeFunctionOnNextCall(test1);
+test2();
+test2();
+%OptimizeFunctionOnNextCall(test2);
+test3();
+test3();
+%OptimizeFunctionOnNextCall(test3);
+
+assertEquals(-10000000000.1, test1());
+assertEquals(-101, test2());
+assertEquals(-214748364.9, test3());
diff --git a/deps/v8/test/mjsunit/math-floor-of-div-minus-zero.js b/deps/v8/test/mjsunit/math-floor-of-div-minus-zero.js
new file mode 100644
index 000000000..274349084
--- /dev/null
+++ b/deps/v8/test/mjsunit/math-floor-of-div-minus-zero.js
@@ -0,0 +1,40 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax --nouse_inlining --noparallel-recompilation
+
+// Test for negative zero that doesn't need bail out
+
+function test_div_no_deopt_minus_zero() {
+ var zero_in_array = [0];
+ assertTrue(0 === (Math.floor((zero_in_array[0] | 0) / -1) | 0));
+}
+
+test_div_no_deopt_minus_zero();
+%OptimizeFunctionOnNextCall(test_div_no_deopt_minus_zero);
+test_div_no_deopt_minus_zero();
+assertTrue(2 != %GetOptimizationStatus(test_div_no_deopt_minus_zero));
diff --git a/deps/v8/test/mjsunit/math-floor-part1.js b/deps/v8/test/mjsunit/math-floor-part1.js
new file mode 100644
index 000000000..313f27236
--- /dev/null
+++ b/deps/v8/test/mjsunit/math-floor-part1.js
@@ -0,0 +1,88 @@
+// Copyright 2011 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.
+
+// Flags: --max-new-space-size=256 --allow-natives-syntax
+
+var test_id = 0;
+
+function testFloor(expect, input) {
+ var test = new Function('n',
+ '"' + (test_id++) + '";return Math.floor(n)');
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ %OptimizeFunctionOnNextCall(test);
+ assertEquals(expect, test(input));
+}
+
+function zero() {
+ var x = 0.5;
+ return (function() { return x - 0.5; })();
+}
+
+function test() {
+ // Ensure that a negative zero coming from Math.floor is properly handled
+ // by other operations.
+ function ifloor(x) {
+ return 1 / Math.floor(x);
+ }
+ assertEquals(-Infinity, ifloor(-0));
+ assertEquals(-Infinity, ifloor(-0));
+ assertEquals(-Infinity, ifloor(-0));
+ %OptimizeFunctionOnNextCall(ifloor);
+ assertEquals(-Infinity, ifloor(-0));
+
+ testFloor(0, 0.1);
+ testFloor(0, 0.49999999999999994);
+ testFloor(0, 0.5);
+ testFloor(0, 0.7);
+ testFloor(-1, -0.1);
+ testFloor(-1, -0.49999999999999994);
+ testFloor(-1, -0.5);
+ testFloor(-1, -0.7);
+ testFloor(1, 1);
+ testFloor(1, 1.1);
+ testFloor(1, 1.5);
+ testFloor(1, 1.7);
+ testFloor(-1, -1);
+ testFloor(-2, -1.1);
+ testFloor(-2, -1.5);
+ testFloor(-2, -1.7);
+
+ testFloor(0, Number.MIN_VALUE);
+ testFloor(-1, -Number.MIN_VALUE);
+ testFloor(Number.MAX_VALUE, Number.MAX_VALUE);
+ testFloor(-Number.MAX_VALUE, -Number.MAX_VALUE);
+ testFloor(Infinity, Infinity);
+ testFloor(-Infinity, -Infinity);
+}
+
+
+// Test in a loop to cover the custom IC and GC-related issues.
+for (var i = 0; i < 100; i++) {
+ test();
+}
diff --git a/deps/v8/test/mjsunit/math-floor-part2.js b/deps/v8/test/mjsunit/math-floor-part2.js
new file mode 100644
index 000000000..b6d51b2bd
--- /dev/null
+++ b/deps/v8/test/mjsunit/math-floor-part2.js
@@ -0,0 +1,76 @@
+// Copyright 2011 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.
+
+// Flags: --max-new-space-size=256 --allow-natives-syntax
+
+var test_id = 0;
+
+function testFloor(expect, input) {
+ var test = new Function('n',
+ '"' + (test_id++) + '";return Math.floor(n)');
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ %OptimizeFunctionOnNextCall(test);
+ assertEquals(expect, test(input));
+}
+
+function zero() {
+ var x = 0.5;
+ return (function() { return x - 0.5; })();
+}
+
+function test() {
+ // 2^30 is a smi boundary.
+ var two_30 = 1 << 30;
+
+ testFloor(two_30, two_30);
+ testFloor(two_30, two_30 + 0.1);
+ testFloor(two_30, two_30 + 0.5);
+ testFloor(two_30, two_30 + 0.7);
+
+ testFloor(two_30 - 1, two_30 - 1);
+ testFloor(two_30 - 1, two_30 - 1 + 0.1);
+ testFloor(two_30 - 1, two_30 - 1 + 0.5);
+ testFloor(two_30 - 1, two_30 - 1 + 0.7);
+
+ testFloor(-two_30, -two_30);
+ testFloor(-two_30, -two_30 + 0.1);
+ testFloor(-two_30, -two_30 + 0.5);
+ testFloor(-two_30, -two_30 + 0.7);
+
+ testFloor(-two_30 + 1, -two_30 + 1);
+ testFloor(-two_30 + 1, -two_30 + 1 + 0.1);
+ testFloor(-two_30 + 1, -two_30 + 1 + 0.5);
+ testFloor(-two_30 + 1, -two_30 + 1 + 0.7);
+}
+
+
+// Test in a loop to cover the custom IC and GC-related issues.
+for (var i = 0; i < 100; i++) {
+ test();
+}
diff --git a/deps/v8/test/mjsunit/math-floor-part3.js b/deps/v8/test/mjsunit/math-floor-part3.js
new file mode 100644
index 000000000..db2592343
--- /dev/null
+++ b/deps/v8/test/mjsunit/math-floor-part3.js
@@ -0,0 +1,78 @@
+// Copyright 2011 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.
+
+// Flags: --max-new-space-size=256 --allow-natives-syntax
+
+var test_id = 0;
+
+function testFloor(expect, input) {
+ var test = new Function('n',
+ '"' + (test_id++) + '";return Math.floor(n)');
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ %OptimizeFunctionOnNextCall(test);
+ assertEquals(expect, test(input));
+}
+
+function zero() {
+ var x = 0.5;
+ return (function() { return x - 0.5; })();
+}
+
+function test() {
+ // 2^52 is a precision boundary.
+ var two_52 = (1 << 30) * (1 << 22);
+
+ testFloor(two_52, two_52);
+ testFloor(two_52, two_52 + 0.1);
+ assertEquals(two_52, two_52 + 0.5);
+ testFloor(two_52, two_52 + 0.5);
+ assertEquals(two_52 + 1, two_52 + 0.7);
+ testFloor(two_52 + 1, two_52 + 0.7);
+
+ testFloor(two_52 - 1, two_52 - 1);
+ testFloor(two_52 - 1, two_52 - 1 + 0.1);
+ testFloor(two_52 - 1, two_52 - 1 + 0.5);
+ testFloor(two_52 - 1, two_52 - 1 + 0.7);
+
+ testFloor(-two_52, -two_52);
+ testFloor(-two_52, -two_52 + 0.1);
+ testFloor(-two_52, -two_52 + 0.5);
+ testFloor(-two_52, -two_52 + 0.7);
+
+ testFloor(-two_52 + 1, -two_52 + 1);
+ testFloor(-two_52 + 1, -two_52 + 1 + 0.1);
+ testFloor(-two_52 + 1, -two_52 + 1 + 0.5);
+ testFloor(-two_52 + 1, -two_52 + 1 + 0.7);
+}
+
+
+// Test in a loop to cover the custom IC and GC-related issues.
+for (var i = 0; i < 100; i++) {
+ test();
+}
diff --git a/deps/v8/test/mjsunit/math-floor-part4.js b/deps/v8/test/mjsunit/math-floor-part4.js
new file mode 100644
index 000000000..c63362308
--- /dev/null
+++ b/deps/v8/test/mjsunit/math-floor-part4.js
@@ -0,0 +1,76 @@
+// Copyright 2011 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.
+
+// Flags: --max-new-space-size=256 --allow-natives-syntax
+
+var test_id = 0;
+
+function testFloor(expect, input) {
+ var test = new Function('n',
+ '"' + (test_id++) + '";return Math.floor(n)');
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ %OptimizeFunctionOnNextCall(test);
+ assertEquals(expect, test(input));
+}
+
+function zero() {
+ var x = 0.5;
+ return (function() { return x - 0.5; })();
+}
+
+function test() {
+ testFloor(0, 0);
+ testFloor(0, zero());
+ testFloor(-0, -0);
+ testFloor(Infinity, Infinity);
+ testFloor(-Infinity, -Infinity);
+ testFloor(NaN, NaN);
+}
+
+
+// Test in a loop to cover the custom IC and GC-related issues.
+for (var i = 0; i < 100; i++) {
+ test();
+}
+
+
+// Regression test for a bug where a negative zero coming from Math.floor
+// was not properly handled by other operations.
+function floorsum(i, n) {
+ var ret = Math.floor(n);
+ while (--i > 0) {
+ ret += Math.floor(n);
+ }
+ return ret;
+}
+assertEquals(-0, floorsum(1, -0));
+%OptimizeFunctionOnNextCall(floorsum);
+// The optimized function will deopt. Run it with enough iterations to try
+// to optimize via OSR (triggering the bug).
+assertEquals(-0, floorsum(100000, -0));
diff --git a/deps/v8/test/mjsunit/math-floor.js b/deps/v8/test/mjsunit/math-floor.js
deleted file mode 100644
index f211ce2e5..000000000
--- a/deps/v8/test/mjsunit/math-floor.js
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2011 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.
-
-// Flags: --max-new-space-size=256 --allow-natives-syntax
-
-var test_id = 0;
-
-function testFloor(expect, input) {
- var test = new Function('n',
- '"' + (test_id++) + '";return Math.floor(n)');
- assertEquals(expect, test(input));
- assertEquals(expect, test(input));
- assertEquals(expect, test(input));
- %OptimizeFunctionOnNextCall(test);
- assertEquals(expect, test(input));
-}
-
-function zero() {
- var x = 0.5;
- return (function() { return x - 0.5; })();
-}
-
-function test() {
- testFloor(0, 0);
- testFloor(0, zero());
- testFloor(-0, -0);
- testFloor(Infinity, Infinity);
- testFloor(-Infinity, -Infinity);
- testFloor(NaN, NaN);
-
- // Ensure that a negative zero coming from Math.floor is properly handled
- // by other operations.
- function ifloor(x) {
- return 1 / Math.floor(x);
- }
- assertEquals(-Infinity, ifloor(-0));
- assertEquals(-Infinity, ifloor(-0));
- assertEquals(-Infinity, ifloor(-0));
- %OptimizeFunctionOnNextCall(ifloor);
- assertEquals(-Infinity, ifloor(-0));
-
- testFloor(0, 0.1);
- testFloor(0, 0.49999999999999994);
- testFloor(0, 0.5);
- testFloor(0, 0.7);
- testFloor(-1, -0.1);
- testFloor(-1, -0.49999999999999994);
- testFloor(-1, -0.5);
- testFloor(-1, -0.7);
- testFloor(1, 1);
- testFloor(1, 1.1);
- testFloor(1, 1.5);
- testFloor(1, 1.7);
- testFloor(-1, -1);
- testFloor(-2, -1.1);
- testFloor(-2, -1.5);
- testFloor(-2, -1.7);
-
- testFloor(0, Number.MIN_VALUE);
- testFloor(-1, -Number.MIN_VALUE);
- testFloor(Number.MAX_VALUE, Number.MAX_VALUE);
- testFloor(-Number.MAX_VALUE, -Number.MAX_VALUE);
- testFloor(Infinity, Infinity);
- testFloor(-Infinity, -Infinity);
-
- // 2^30 is a smi boundary.
- var two_30 = 1 << 30;
-
- testFloor(two_30, two_30);
- testFloor(two_30, two_30 + 0.1);
- testFloor(two_30, two_30 + 0.5);
- testFloor(two_30, two_30 + 0.7);
-
- testFloor(two_30 - 1, two_30 - 1);
- testFloor(two_30 - 1, two_30 - 1 + 0.1);
- testFloor(two_30 - 1, two_30 - 1 + 0.5);
- testFloor(two_30 - 1, two_30 - 1 + 0.7);
-
- testFloor(-two_30, -two_30);
- testFloor(-two_30, -two_30 + 0.1);
- testFloor(-two_30, -two_30 + 0.5);
- testFloor(-two_30, -two_30 + 0.7);
-
- testFloor(-two_30 + 1, -two_30 + 1);
- testFloor(-two_30 + 1, -two_30 + 1 + 0.1);
- testFloor(-two_30 + 1, -two_30 + 1 + 0.5);
- testFloor(-two_30 + 1, -two_30 + 1 + 0.7);
-
- // 2^52 is a precision boundary.
- var two_52 = (1 << 30) * (1 << 22);
-
- testFloor(two_52, two_52);
- testFloor(two_52, two_52 + 0.1);
- assertEquals(two_52, two_52 + 0.5);
- testFloor(two_52, two_52 + 0.5);
- assertEquals(two_52 + 1, two_52 + 0.7);
- testFloor(two_52 + 1, two_52 + 0.7);
-
- testFloor(two_52 - 1, two_52 - 1);
- testFloor(two_52 - 1, two_52 - 1 + 0.1);
- testFloor(two_52 - 1, two_52 - 1 + 0.5);
- testFloor(two_52 - 1, two_52 - 1 + 0.7);
-
- testFloor(-two_52, -two_52);
- testFloor(-two_52, -two_52 + 0.1);
- testFloor(-two_52, -two_52 + 0.5);
- testFloor(-two_52, -two_52 + 0.7);
-
- testFloor(-two_52 + 1, -two_52 + 1);
- testFloor(-two_52 + 1, -two_52 + 1 + 0.1);
- testFloor(-two_52 + 1, -two_52 + 1 + 0.5);
- testFloor(-two_52 + 1, -two_52 + 1 + 0.7);
-}
-
-
-// Test in a loop to cover the custom IC and GC-related issues.
-for (var i = 0; i < 500; i++) {
- test();
-}
-
-
-// Regression test for a bug where a negative zero coming from Math.floor
-// was not properly handled by other operations.
-function floorsum(i, n) {
- var ret = Math.floor(n);
- while (--i > 0) {
- ret += Math.floor(n);
- }
- return ret;
-}
-assertEquals(-0, floorsum(1, -0));
-%OptimizeFunctionOnNextCall(floorsum);
-// The optimized function will deopt. Run it with enough iterations to try
-// to optimize via OSR (triggering the bug).
-assertEquals(-0, floorsum(100000, -0));
diff --git a/deps/v8/test/mjsunit/mirror-object.js b/deps/v8/test/mjsunit/mirror-object.js
index d4d228cf0..8bf8a2d4f 100644
--- a/deps/v8/test/mjsunit/mirror-object.js
+++ b/deps/v8/test/mjsunit/mirror-object.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -49,19 +49,19 @@ function testObjectMirror(obj, cls_name, ctor_name, hasSpecialProperties) {
JSON.stringify(serializer.serializeReferencedObjects()));
// Check the mirror hierachy.
- assertTrue(mirror instanceof debug.Mirror, 'Unexpected mirror hierachy');
- assertTrue(mirror instanceof debug.ValueMirror, 'Unexpected mirror hierachy');
- assertTrue(mirror instanceof debug.ObjectMirror, 'Unexpected mirror hierachy');
+ assertTrue(mirror instanceof debug.Mirror, 'Unexpected mirror hierarchy');
+ assertTrue(mirror instanceof debug.ValueMirror, 'Unexpected mirror hierarchy');
+ assertTrue(mirror instanceof debug.ObjectMirror, 'Unexpected mirror hierarchy');
// Check the mirror properties.
assertTrue(mirror.isObject(), 'Unexpected mirror');
assertEquals('object', mirror.type(), 'Unexpected mirror type');
assertFalse(mirror.isPrimitive(), 'Unexpected primitive mirror');
assertEquals(cls_name, mirror.className(), 'Unexpected mirror class name');
- assertTrue(mirror.constructorFunction() instanceof debug.ObjectMirror, 'Unexpected mirror hierachy');
+ assertTrue(mirror.constructorFunction() instanceof debug.ObjectMirror, 'Unexpected mirror hierarchy');
assertEquals(ctor_name, mirror.constructorFunction().name(), 'Unexpected constructor function name');
- assertTrue(mirror.protoObject() instanceof debug.Mirror, 'Unexpected mirror hierachy');
- assertTrue(mirror.prototypeObject() instanceof debug.Mirror, 'Unexpected mirror hierachy');
+ assertTrue(mirror.protoObject() instanceof debug.Mirror, 'Unexpected mirror hierarchy');
+ assertTrue(mirror.prototypeObject() instanceof debug.Mirror, 'Unexpected mirror hierarchy');
assertFalse(mirror.hasNamedInterceptor(), 'No named interceptor expected');
assertFalse(mirror.hasIndexedInterceptor(), 'No indexed interceptor expected');
@@ -69,12 +69,19 @@ function testObjectMirror(obj, cls_name, ctor_name, hasSpecialProperties) {
var properties = mirror.properties();
assertEquals(names.length, properties.length);
for (var i = 0; i < properties.length; i++) {
- assertTrue(properties[i] instanceof debug.Mirror, 'Unexpected mirror hierachy');
- assertTrue(properties[i] instanceof debug.PropertyMirror, 'Unexpected mirror hierachy');
+ assertTrue(properties[i] instanceof debug.Mirror, 'Unexpected mirror hierarchy');
+ assertTrue(properties[i] instanceof debug.PropertyMirror, 'Unexpected mirror hierarchy');
assertEquals('property', properties[i].type(), 'Unexpected mirror type');
assertEquals(names[i], properties[i].name(), 'Unexpected property name');
}
+ var internalProperties = mirror.internalProperties();
+ for (var i = 0; i < internalProperties.length; i++) {
+ assertTrue(internalProperties[i] instanceof debug.Mirror, 'Unexpected mirror hierarchy');
+ assertTrue(internalProperties[i] instanceof debug.InternalPropertyMirror, 'Unexpected mirror hierarchy');
+ assertEquals('internalProperty', internalProperties[i].type(), 'Unexpected mirror type');
+ }
+
for (var p in obj) {
var property_mirror = mirror.property(p);
assertTrue(property_mirror instanceof debug.PropertyMirror);
@@ -172,6 +179,7 @@ testObjectMirror(this, 'global', '', true); // Global object has special proper
testObjectMirror(this.__proto__, 'Object', '');
testObjectMirror([], 'Array', 'Array');
testObjectMirror([1,2], 'Array', 'Array');
+testObjectMirror(Object(17), 'Number', 'Number');
// Test circular references.
o = {};
@@ -230,3 +238,29 @@ assertTrue(mirror.property('length').isNative());
assertEquals('a', mirror.property(0).value().value());
assertEquals('b', mirror.property(1).value().value());
assertEquals('c', mirror.property(2).value().value());
+
+// Test value wrapper internal properties.
+mirror = debug.MakeMirror(Object("Capybara"));
+var ip = mirror.internalProperties();
+assertEquals(1, ip.length);
+assertEquals("[[PrimitiveValue]]", ip[0].name());
+assertEquals("string", ip[0].value().type());
+assertEquals("Capybara", ip[0].value().value());
+
+// Test bound function internal properties.
+mirror = debug.MakeMirror(Number.bind(Array, 2));
+ip = mirror.internalProperties();
+assertEquals(3, ip.length);
+var property_map = {};
+for (var i = 0; i < ip.length; i++) {
+ property_map[ip[i].name()] = ip[i];
+}
+assertTrue("[[BoundThis]]" in property_map);
+assertEquals("function", property_map["[[BoundThis]]"].value().type());
+assertEquals(Array, property_map["[[BoundThis]]"].value().value());
+assertTrue("[[TargetFunction]]" in property_map);
+assertEquals("function", property_map["[[TargetFunction]]"].value().type());
+assertEquals(Number, property_map["[[TargetFunction]]"].value().value());
+assertTrue("[[BoundArgs]]" in property_map);
+assertEquals("object", property_map["[[BoundArgs]]"].value().type());
+assertEquals(1, property_map["[[BoundArgs]]"].value().value().length);
diff --git a/deps/v8/test/mjsunit/mjsunit.js b/deps/v8/test/mjsunit/mjsunit.js
index 65fb301b4..25d7c0043 100644
--- a/deps/v8/test/mjsunit/mjsunit.js
+++ b/deps/v8/test/mjsunit/mjsunit.js
@@ -321,7 +321,7 @@ var assertUnreachable;
assertInstanceof = function assertInstanceof(obj, type) {
if (!(obj instanceof type)) {
var actualTypeName = null;
- var actualConstructor = Object.prototypeOf(obj).constructor;
+ var actualConstructor = Object.getPrototypeOf(obj).constructor;
if (typeof actualConstructor == "function") {
actualTypeName = actualConstructor.name || String(actualConstructor);
}
diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status
index e311ffbcb..037093bf7 100644
--- a/deps/v8/test/mjsunit/mjsunit.status
+++ b/deps/v8/test/mjsunit/mjsunit.status
@@ -34,9 +34,6 @@ bugs/*: FAIL
# Fails.
regress/regress-1119: FAIL
-# Issue 2177: Debugger on ARM broken due to variable literal pool size.
-debug-liveedit-breakpoints: PASS, SKIP if ($arch == arm)
-
# Issue 1719: Slow to collect arrays over several contexts.
regress/regress-524: SKIP
# When that bug is fixed, revert the expectation to:
@@ -50,40 +47,33 @@ compiler/regress-funcaller: PASS, SKIP if $mode == debug
regress/regress-create-exception: PASS, SKIP if $mode == debug
##############################################################################
-# This one uses a built-in that's only present in debug mode. It takes
+# These use a built-in that's only present in debug mode. They take
# too long to run in debug mode on ARM and MIPS.
-fuzz-natives: PASS, SKIP if ($mode == release || $arch == arm || $arch == mips)
+fuzz-natives-part*: PASS, SKIP if ($mode == release || $arch == arm || $arch == android_arm || $arch == mipsel)
-big-object-literal: PASS, SKIP if ($arch == arm)
+big-object-literal: PASS, SKIP if ($arch == arm || $arch == android_arm)
# Issue 488: this test sometimes times out.
array-constructor: PASS || TIMEOUT
# Very slow on ARM and MIPS, contains no architecture dependent code.
-unicode-case-overoptimization: PASS, TIMEOUT if ($arch == arm || $arch == mips)
-
-# Stack manipulations in LiveEdit are buggy - see bug 915
-debug-liveedit-check-stack: SKIP
-debug-liveedit-patch-positions-replace: SKIP
-debug-liveedit-stack-padding: SKIP
-
-# Test Crankshaft compilation time. Expected to take too long in debug mode.
-regress/regress-1969: PASS, SKIP if $mode == debug
+unicode-case-overoptimization: PASS, TIMEOUT if ($arch == arm || $arch == android_arm || $arch == mipsel)
##############################################################################
-[ $isolates ]
-
# This test sets the umask on a per-process basis and hence cannot be
# used in multi-threaded runs.
-d8-os: SKIP
+# On android there is no /tmp directory.
+d8-os: PASS, SKIP if ($isolates || $arch == android_arm || $arch == android_ia32)
+tools/tickprocessor: PASS, SKIP if ($arch == android_arm || $arch == android_ia32)
##############################################################################
-[ $arch == arm ]
+[ $arch == arm || $arch == android_arm ]
# Slow tests which times out in debug mode.
try: PASS, SKIP if $mode == debug
debug-scripts-request: PASS, SKIP if $mode == debug
array-constructor: PASS, SKIP if $mode == debug
+regress/regress-1122: PASS, SKIP if ($mode == debug && $arch == android_arm)
# Flaky test that can hit compilation-time stack overflow in debug mode.
unicode-test: PASS, (PASS || FAIL) if $mode == debug
@@ -93,8 +83,8 @@ compiler/regress-stacktrace-methods: PASS, PASS || TIMEOUT if $mode == release
array-splice: PASS || TIMEOUT
# Long running test.
-mirror-object: PASS || TIMEOUT
string-indexof-2: PASS || TIMEOUT
+mirror-object: PASS || TIMEOUT
# BUG(3251035): Timeouts in long looping crankshaft optimization
# tests. Skipping because having them timeout takes too long on the
@@ -111,11 +101,9 @@ compiler/property-calls: SKIP
compiler/recursive-deopt: SKIP
compiler/regress-4: SKIP
compiler/regress-funcaller: SKIP
-compiler/regress-gvn: SKIP
compiler/regress-rep-change: SKIP
compiler/regress-arguments: SKIP
compiler/regress-funarguments: SKIP
-compiler/regress-or: SKIP
compiler/regress-3249650: SKIP
compiler/simple-deopt: SKIP
regress/regress-490: SKIP
@@ -129,8 +117,17 @@ regress/regress-3247124: SKIP
# should be platform-independent.
regress/regress-1132: SKIP
+# Stack manipulations in LiveEdit is not implemented for this arch.
+debug-liveedit-check-stack: SKIP
+debug-liveedit-stack-padding: SKIP
+debug-liveedit-restart-frame: SKIP
+debug-liveedit-double-call: SKIP
+
+# Currently always deopt on minus zero
+math-floor-of-div-minus-zero: SKIP
+
##############################################################################
-[ $arch == mips ]
+[ $arch == mipsel ]
# Slow tests which times out in debug mode.
try: PASS, SKIP if $mode == debug
@@ -160,11 +157,9 @@ compiler/property-calls: SKIP
compiler/recursive-deopt: SKIP
compiler/regress-4: SKIP
compiler/regress-funcaller: SKIP
-compiler/regress-gvn: SKIP
compiler/regress-rep-change: SKIP
compiler/regress-arguments: SKIP
compiler/regress-funarguments: SKIP
-compiler/regress-or: SKIP
compiler/regress-3249650: SKIP
compiler/simple-deopt: SKIP
regress/regress-490: SKIP
@@ -177,3 +172,10 @@ regress/regress-3247124: SKIP
# the test requires too much time to run. However, the problem test covers
# should be platform-independent.
regress/regress-1132: SKIP
+
+# Stack manipulations in LiveEdit is not implemented for this arch.
+debug-liveedit-check-stack: SKIP
+debug-liveedit-stack-padding: SKIP
+debug-liveedit-restart-frame: SKIP
+debug-liveedit-double-call: SKIP
+
diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part1.js b/deps/v8/test/mjsunit/mul-exhaustive-part1.js
new file mode 100644
index 000000000..7902cc2e6
--- /dev/null
+++ b/deps/v8/test/mjsunit/mul-exhaustive-part1.js
@@ -0,0 +1,491 @@
+// Copyright 2008 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.
+
+var x;
+
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
+}
+
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 0;
+f(0, 0);
+x = 1;
+f(0, 0);
+f(1, 1);
+x = 2;
+f(0, 0);
+f(2, 1);
+f(4, 2);
+x = 3;
+f(0, 0);
+f(3, 1);
+f(6, 2);
+f(9, 3);
+x = 4;
+f(0, 0);
+f(4, 1);
+f(8, 2);
+f(12, 3);
+f(16, 4);
+x = 5;
+f(0, 0);
+f(5, 1);
+f(10, 2);
+f(15, 3);
+f(20, 4);
+f(25, 5);
+x = 7;
+f(0, 0);
+f(7, 1);
+f(14, 2);
+f(21, 3);
+f(28, 4);
+f(35, 5);
+f(49, 7);
+x = 8;
+f(0, 0);
+f(8, 1);
+f(16, 2);
+f(24, 3);
+f(32, 4);
+f(40, 5);
+f(56, 7);
+f(64, 8);
+x = 9;
+f(0, 0);
+f(9, 1);
+f(18, 2);
+f(27, 3);
+f(36, 4);
+f(45, 5);
+f(63, 7);
+f(72, 8);
+f(81, 9);
+x = 15;
+f(0, 0);
+f(15, 1);
+f(30, 2);
+f(45, 3);
+f(60, 4);
+f(75, 5);
+f(105, 7);
+f(120, 8);
+f(135, 9);
+f(225, 15);
+x = 16;
+f(0, 0);
+f(16, 1);
+f(32, 2);
+f(48, 3);
+f(64, 4);
+f(80, 5);
+f(112, 7);
+f(128, 8);
+f(144, 9);
+f(240, 15);
+f(256, 16);
+x = 17;
+f(0, 0);
+f(17, 1);
+f(34, 2);
+f(51, 3);
+f(68, 4);
+f(85, 5);
+f(119, 7);
+f(136, 8);
+f(153, 9);
+f(255, 15);
+f(272, 16);
+f(289, 17);
+x = 31;
+f(0, 0);
+f(31, 1);
+f(62, 2);
+f(93, 3);
+f(124, 4);
+f(155, 5);
+f(217, 7);
+f(248, 8);
+f(279, 9);
+f(465, 15);
+f(496, 16);
+f(527, 17);
+f(961, 31);
+x = 32;
+f(0, 0);
+f(32, 1);
+f(64, 2);
+f(96, 3);
+f(128, 4);
+f(160, 5);
+f(224, 7);
+f(256, 8);
+f(288, 9);
+f(480, 15);
+f(512, 16);
+f(544, 17);
+f(992, 31);
+f(1024, 32);
+x = 33;
+f(0, 0);
+f(33, 1);
+f(66, 2);
+f(99, 3);
+f(132, 4);
+f(165, 5);
+f(231, 7);
+f(264, 8);
+f(297, 9);
+f(495, 15);
+f(528, 16);
+f(561, 17);
+f(1023, 31);
+f(1056, 32);
+f(1089, 33);
+x = 63;
+f(0, 0);
+f(63, 1);
+f(126, 2);
+f(189, 3);
+f(252, 4);
+f(315, 5);
+f(441, 7);
+f(504, 8);
+f(567, 9);
+f(945, 15);
+f(1008, 16);
+f(1071, 17);
+f(1953, 31);
+f(2016, 32);
+f(2079, 33);
+f(3969, 63);
+x = 64;
+f(0, 0);
+f(64, 1);
+f(128, 2);
+f(192, 3);
+f(256, 4);
+f(320, 5);
+f(448, 7);
+f(512, 8);
+f(576, 9);
+f(960, 15);
+f(1024, 16);
+f(1088, 17);
+f(1984, 31);
+f(2048, 32);
+f(2112, 33);
+f(4032, 63);
+f(4096, 64);
+x = 65;
+f(0, 0);
+f(65, 1);
+f(130, 2);
+f(195, 3);
+f(260, 4);
+f(325, 5);
+f(455, 7);
+f(520, 8);
+f(585, 9);
+f(975, 15);
+f(1040, 16);
+f(1105, 17);
+f(2015, 31);
+f(2080, 32);
+f(2145, 33);
+f(4095, 63);
+f(4160, 64);
+f(4225, 65);
+x = 127;
+f(0, 0);
+f(127, 1);
+f(254, 2);
+f(381, 3);
+f(508, 4);
+f(635, 5);
+f(889, 7);
+f(1016, 8);
+f(1143, 9);
+f(1905, 15);
+f(2032, 16);
+f(2159, 17);
+f(3937, 31);
+f(4064, 32);
+f(4191, 33);
+f(8001, 63);
+f(8128, 64);
+f(8255, 65);
+f(16129, 127);
+x = 128;
+f(0, 0);
+f(128, 1);
+f(256, 2);
+f(384, 3);
+f(512, 4);
+f(640, 5);
+f(896, 7);
+f(1024, 8);
+f(1152, 9);
+f(1920, 15);
+f(2048, 16);
+f(2176, 17);
+f(3968, 31);
+f(4096, 32);
+f(4224, 33);
+f(8064, 63);
+f(8192, 64);
+f(8320, 65);
+f(16256, 127);
+f(16384, 128);
+x = 129;
+f(0, 0);
+f(129, 1);
+f(258, 2);
+f(387, 3);
+f(516, 4);
+f(645, 5);
+f(903, 7);
+f(1032, 8);
+f(1161, 9);
+f(1935, 15);
+f(2064, 16);
+f(2193, 17);
+f(3999, 31);
+f(4128, 32);
+f(4257, 33);
+f(8127, 63);
+f(8256, 64);
+f(8385, 65);
+f(16383, 127);
+f(16512, 128);
+f(16641, 129);
+x = 255;
+f(0, 0);
+f(255, 1);
+f(510, 2);
+f(765, 3);
+f(1020, 4);
+f(1275, 5);
+f(1785, 7);
+f(2040, 8);
+f(2295, 9);
+f(3825, 15);
+f(4080, 16);
+f(4335, 17);
+f(7905, 31);
+f(8160, 32);
+f(8415, 33);
+f(16065, 63);
+f(16320, 64);
+f(16575, 65);
+f(32385, 127);
+f(32640, 128);
+f(32895, 129);
+f(65025, 255);
+x = 256;
+f(0, 0);
+f(256, 1);
+f(512, 2);
+f(768, 3);
+f(1024, 4);
+f(1280, 5);
+f(1792, 7);
+f(2048, 8);
+f(2304, 9);
+f(3840, 15);
+f(4096, 16);
+f(4352, 17);
+f(7936, 31);
+f(8192, 32);
+f(8448, 33);
+f(16128, 63);
+f(16384, 64);
+f(16640, 65);
+f(32512, 127);
+f(32768, 128);
+f(33024, 129);
+f(65280, 255);
+f(65536, 256);
+x = 257;
+f(0, 0);
+f(257, 1);
+f(514, 2);
+f(771, 3);
+f(1028, 4);
+f(1285, 5);
+f(1799, 7);
+f(2056, 8);
+f(2313, 9);
+f(3855, 15);
+f(4112, 16);
+f(4369, 17);
+f(7967, 31);
+f(8224, 32);
+f(8481, 33);
+f(16191, 63);
+f(16448, 64);
+f(16705, 65);
+f(32639, 127);
+f(32896, 128);
+f(33153, 129);
+f(65535, 255);
+f(65792, 256);
+f(66049, 257);
+x = 511;
+f(0, 0);
+f(511, 1);
+f(1022, 2);
+f(1533, 3);
+f(2044, 4);
+f(2555, 5);
+f(3577, 7);
+f(4088, 8);
+f(4599, 9);
+f(7665, 15);
+f(8176, 16);
+f(8687, 17);
+f(15841, 31);
+f(16352, 32);
+f(16863, 33);
+f(32193, 63);
+f(32704, 64);
+f(33215, 65);
+f(64897, 127);
+f(65408, 128);
+f(65919, 129);
+f(130305, 255);
+f(130816, 256);
+f(131327, 257);
+f(261121, 511);
+x = 512;
+f(0, 0);
+f(512, 1);
+f(1024, 2);
+f(1536, 3);
+f(2048, 4);
+f(2560, 5);
+f(3584, 7);
+f(4096, 8);
+f(4608, 9);
+f(7680, 15);
+f(8192, 16);
+f(8704, 17);
+f(15872, 31);
+f(16384, 32);
+f(16896, 33);
+f(32256, 63);
+f(32768, 64);
+f(33280, 65);
+f(65024, 127);
+f(65536, 128);
+f(66048, 129);
+f(130560, 255);
+f(131072, 256);
+f(131584, 257);
+f(261632, 511);
+f(262144, 512);
+x = 513;
+f(0, 0);
+f(513, 1);
+f(1026, 2);
+f(1539, 3);
+f(2052, 4);
+f(2565, 5);
+f(3591, 7);
+f(4104, 8);
+f(4617, 9);
+f(7695, 15);
+f(8208, 16);
+f(8721, 17);
+f(15903, 31);
+f(16416, 32);
+f(16929, 33);
+f(32319, 63);
+f(32832, 64);
+f(33345, 65);
+f(65151, 127);
+f(65664, 128);
+f(66177, 129);
+f(130815, 255);
+f(131328, 256);
+f(131841, 257);
+f(262143, 511);
+f(262656, 512);
+f(263169, 513);
+x = 1023;
+f(0, 0);
+f(1023, 1);
+f(2046, 2);
+f(3069, 3);
+f(4092, 4);
+f(5115, 5);
+f(7161, 7);
+f(8184, 8);
+f(9207, 9);
+f(15345, 15);
+f(16368, 16);
+f(17391, 17);
+f(31713, 31);
+f(32736, 32);
+f(33759, 33);
+f(64449, 63);
+f(65472, 64);
+f(66495, 65);
+f(129921, 127);
+f(130944, 128);
+f(131967, 129);
+f(260865, 255);
+f(261888, 256);
+f(262911, 257);
+f(522753, 511);
+f(523776, 512);
+f(524799, 513);
+f(1046529, 1023);
diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part10.js b/deps/v8/test/mjsunit/mul-exhaustive-part10.js
new file mode 100644
index 000000000..166ec5217
--- /dev/null
+++ b/deps/v8/test/mjsunit/mul-exhaustive-part10.js
@@ -0,0 +1,470 @@
+// Copyright 2008 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.
+
+var x;
+
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
+}
+
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 4294967296;
+f(0, 0);
+f(4294967296, 1);
+f(8589934592, 2);
+f(12884901888, 3);
+f(17179869184, 4);
+f(21474836480, 5);
+f(30064771072, 7);
+f(34359738368, 8);
+f(38654705664, 9);
+f(64424509440, 15);
+f(68719476736, 16);
+f(73014444032, 17);
+f(133143986176, 31);
+f(137438953472, 32);
+f(141733920768, 33);
+f(270582939648, 63);
+f(274877906944, 64);
+f(279172874240, 65);
+f(545460846592, 127);
+f(549755813888, 128);
+f(554050781184, 129);
+f(1095216660480, 255);
+f(1099511627776, 256);
+f(1103806595072, 257);
+f(2194728288256, 511);
+f(2199023255552, 512);
+f(2203318222848, 513);
+f(4393751543808, 1023);
+f(4398046511104, 1024);
+f(4402341478400, 1025);
+f(8791798054912, 2047);
+f(8796093022208, 2048);
+f(8800387989504, 2049);
+f(17587891077120, 4095);
+f(17592186044416, 4096);
+f(17596481011712, 4097);
+f(35180077121536, 8191);
+f(35184372088832, 8192);
+f(35188667056128, 8193);
+f(70364449210368, 16383);
+f(70368744177664, 16384);
+f(70373039144960, 16385);
+f(140733193388032, 32767);
+f(140737488355328, 32768);
+f(140741783322624, 32769);
+f(281470681743360, 65535);
+f(281474976710656, 65536);
+f(281479271677952, 65537);
+f(562945658454016, 131071);
+f(562949953421312, 131072);
+f(562954248388608, 131073);
+f(1125895611875328, 262143);
+f(1125899906842624, 262144);
+f(1125904201809920, 262145);
+x = 4294967297;
+f(0, 0);
+f(4294967297, 1);
+f(8589934594, 2);
+f(12884901891, 3);
+f(17179869188, 4);
+f(21474836485, 5);
+f(30064771079, 7);
+f(34359738376, 8);
+f(38654705673, 9);
+f(64424509455, 15);
+f(68719476752, 16);
+f(73014444049, 17);
+f(133143986207, 31);
+f(137438953504, 32);
+f(141733920801, 33);
+f(270582939711, 63);
+f(274877907008, 64);
+f(279172874305, 65);
+f(545460846719, 127);
+f(549755814016, 128);
+f(554050781313, 129);
+f(1095216660735, 255);
+f(1099511628032, 256);
+f(1103806595329, 257);
+f(2194728288767, 511);
+f(2199023256064, 512);
+f(2203318223361, 513);
+f(4393751544831, 1023);
+f(4398046512128, 1024);
+f(4402341479425, 1025);
+f(8791798056959, 2047);
+f(8796093024256, 2048);
+f(8800387991553, 2049);
+f(17587891081215, 4095);
+f(17592186048512, 4096);
+f(17596481015809, 4097);
+f(35180077129727, 8191);
+f(35184372097024, 8192);
+f(35188667064321, 8193);
+f(70364449226751, 16383);
+f(70368744194048, 16384);
+f(70373039161345, 16385);
+f(140733193420799, 32767);
+f(140737488388096, 32768);
+f(140741783355393, 32769);
+f(281470681808895, 65535);
+f(281474976776192, 65536);
+f(281479271743489, 65537);
+f(562945658585087, 131071);
+f(562949953552384, 131072);
+f(562954248519681, 131073);
+f(1125895612137471, 262143);
+f(1125899907104768, 262144);
+f(1125904202072065, 262145);
+x = 8589934591;
+f(0, 0);
+f(8589934591, 1);
+f(17179869182, 2);
+f(25769803773, 3);
+f(34359738364, 4);
+f(42949672955, 5);
+f(60129542137, 7);
+f(68719476728, 8);
+f(77309411319, 9);
+f(128849018865, 15);
+f(137438953456, 16);
+f(146028888047, 17);
+f(266287972321, 31);
+f(274877906912, 32);
+f(283467841503, 33);
+f(541165879233, 63);
+f(549755813824, 64);
+f(558345748415, 65);
+f(1090921693057, 127);
+f(1099511627648, 128);
+f(1108101562239, 129);
+f(2190433320705, 255);
+f(2199023255296, 256);
+f(2207613189887, 257);
+f(4389456576001, 511);
+f(4398046510592, 512);
+f(4406636445183, 513);
+f(8787503086593, 1023);
+f(8796093021184, 1024);
+f(8804682955775, 1025);
+f(17583596107777, 2047);
+f(17592186042368, 2048);
+f(17600775976959, 2049);
+f(35175782150145, 4095);
+f(35184372084736, 4096);
+f(35192962019327, 4097);
+f(70360154234881, 8191);
+f(70368744169472, 8192);
+f(70377334104063, 8193);
+f(140728898404353, 16383);
+f(140737488338944, 16384);
+f(140746078273535, 16385);
+f(281466386743297, 32767);
+f(281474976677888, 32768);
+f(281483566612479, 32769);
+f(562941363421185, 65535);
+f(562949953355776, 65536);
+f(562958543290367, 65537);
+f(1125891316776961, 131071);
+f(1125899906711552, 131072);
+f(1125908496646143, 131073);
+x = 8589934592;
+f(0, 0);
+f(8589934592, 1);
+f(17179869184, 2);
+f(25769803776, 3);
+f(34359738368, 4);
+f(42949672960, 5);
+f(60129542144, 7);
+f(68719476736, 8);
+f(77309411328, 9);
+f(128849018880, 15);
+f(137438953472, 16);
+f(146028888064, 17);
+f(266287972352, 31);
+f(274877906944, 32);
+f(283467841536, 33);
+f(541165879296, 63);
+f(549755813888, 64);
+f(558345748480, 65);
+f(1090921693184, 127);
+f(1099511627776, 128);
+f(1108101562368, 129);
+f(2190433320960, 255);
+f(2199023255552, 256);
+f(2207613190144, 257);
+f(4389456576512, 511);
+f(4398046511104, 512);
+f(4406636445696, 513);
+f(8787503087616, 1023);
+f(8796093022208, 1024);
+f(8804682956800, 1025);
+f(17583596109824, 2047);
+f(17592186044416, 2048);
+f(17600775979008, 2049);
+f(35175782154240, 4095);
+f(35184372088832, 4096);
+f(35192962023424, 4097);
+f(70360154243072, 8191);
+f(70368744177664, 8192);
+f(70377334112256, 8193);
+f(140728898420736, 16383);
+f(140737488355328, 16384);
+f(140746078289920, 16385);
+f(281466386776064, 32767);
+f(281474976710656, 32768);
+f(281483566645248, 32769);
+f(562941363486720, 65535);
+f(562949953421312, 65536);
+f(562958543355904, 65537);
+f(1125891316908032, 131071);
+f(1125899906842624, 131072);
+f(1125908496777216, 131073);
+x = 8589934593;
+f(0, 0);
+f(8589934593, 1);
+f(17179869186, 2);
+f(25769803779, 3);
+f(34359738372, 4);
+f(42949672965, 5);
+f(60129542151, 7);
+f(68719476744, 8);
+f(77309411337, 9);
+f(128849018895, 15);
+f(137438953488, 16);
+f(146028888081, 17);
+f(266287972383, 31);
+f(274877906976, 32);
+f(283467841569, 33);
+f(541165879359, 63);
+f(549755813952, 64);
+f(558345748545, 65);
+f(1090921693311, 127);
+f(1099511627904, 128);
+f(1108101562497, 129);
+f(2190433321215, 255);
+f(2199023255808, 256);
+f(2207613190401, 257);
+f(4389456577023, 511);
+f(4398046511616, 512);
+f(4406636446209, 513);
+f(8787503088639, 1023);
+f(8796093023232, 1024);
+f(8804682957825, 1025);
+f(17583596111871, 2047);
+f(17592186046464, 2048);
+f(17600775981057, 2049);
+f(35175782158335, 4095);
+f(35184372092928, 4096);
+f(35192962027521, 4097);
+f(70360154251263, 8191);
+f(70368744185856, 8192);
+f(70377334120449, 8193);
+f(140728898437119, 16383);
+f(140737488371712, 16384);
+f(140746078306305, 16385);
+f(281466386808831, 32767);
+f(281474976743424, 32768);
+f(281483566678017, 32769);
+f(562941363552255, 65535);
+f(562949953486848, 65536);
+f(562958543421441, 65537);
+f(1125891317039103, 131071);
+f(1125899906973696, 131072);
+f(1125908496908289, 131073);
+x = 17179869183;
+f(0, 0);
+f(17179869183, 1);
+f(34359738366, 2);
+f(51539607549, 3);
+f(68719476732, 4);
+f(85899345915, 5);
+f(120259084281, 7);
+f(137438953464, 8);
+f(154618822647, 9);
+f(257698037745, 15);
+f(274877906928, 16);
+f(292057776111, 17);
+f(532575944673, 31);
+f(549755813856, 32);
+f(566935683039, 33);
+f(1082331758529, 63);
+f(1099511627712, 64);
+f(1116691496895, 65);
+f(2181843386241, 127);
+f(2199023255424, 128);
+f(2216203124607, 129);
+f(4380866641665, 255);
+f(4398046510848, 256);
+f(4415226380031, 257);
+f(8778913152513, 511);
+f(8796093021696, 512);
+f(8813272890879, 513);
+f(17575006174209, 1023);
+f(17592186043392, 1024);
+f(17609365912575, 1025);
+f(35167192217601, 2047);
+f(35184372086784, 2048);
+f(35201551955967, 2049);
+f(70351564304385, 4095);
+f(70368744173568, 4096);
+f(70385924042751, 4097);
+f(140720308477953, 8191);
+f(140737488347136, 8192);
+f(140754668216319, 8193);
+f(281457796825089, 16383);
+f(281474976694272, 16384);
+f(281492156563455, 16385);
+f(562932773519361, 32767);
+f(562949953388544, 32768);
+f(562967133257727, 32769);
+f(1125882726907905, 65535);
+f(1125899906777088, 65536);
+f(1125917086646271, 65537);
+x = 17179869184;
+f(0, 0);
+f(17179869184, 1);
+f(34359738368, 2);
+f(51539607552, 3);
+f(68719476736, 4);
+f(85899345920, 5);
+f(120259084288, 7);
+f(137438953472, 8);
+f(154618822656, 9);
+f(257698037760, 15);
+f(274877906944, 16);
+f(292057776128, 17);
+f(532575944704, 31);
+f(549755813888, 32);
+f(566935683072, 33);
+f(1082331758592, 63);
+f(1099511627776, 64);
+f(1116691496960, 65);
+f(2181843386368, 127);
+f(2199023255552, 128);
+f(2216203124736, 129);
+f(4380866641920, 255);
+f(4398046511104, 256);
+f(4415226380288, 257);
+f(8778913153024, 511);
+f(8796093022208, 512);
+f(8813272891392, 513);
+f(17575006175232, 1023);
+f(17592186044416, 1024);
+f(17609365913600, 1025);
+f(35167192219648, 2047);
+f(35184372088832, 2048);
+f(35201551958016, 2049);
+f(70351564308480, 4095);
+f(70368744177664, 4096);
+f(70385924046848, 4097);
+f(140720308486144, 8191);
+f(140737488355328, 8192);
+f(140754668224512, 8193);
+f(281457796841472, 16383);
+f(281474976710656, 16384);
+f(281492156579840, 16385);
+f(562932773552128, 32767);
+f(562949953421312, 32768);
+f(562967133290496, 32769);
+f(1125882726973440, 65535);
+f(1125899906842624, 65536);
+f(1125917086711808, 65537);
+x = 17179869185;
+f(0, 0);
+f(17179869185, 1);
+f(34359738370, 2);
+f(51539607555, 3);
+f(68719476740, 4);
+f(85899345925, 5);
+f(120259084295, 7);
+f(137438953480, 8);
+f(154618822665, 9);
+f(257698037775, 15);
+f(274877906960, 16);
+f(292057776145, 17);
+f(532575944735, 31);
+f(549755813920, 32);
+f(566935683105, 33);
+f(1082331758655, 63);
+f(1099511627840, 64);
+f(1116691497025, 65);
+f(2181843386495, 127);
+f(2199023255680, 128);
+f(2216203124865, 129);
+f(4380866642175, 255);
+f(4398046511360, 256);
+f(4415226380545, 257);
+f(8778913153535, 511);
+f(8796093022720, 512);
+f(8813272891905, 513);
+f(17575006176255, 1023);
+f(17592186045440, 1024);
+f(17609365914625, 1025);
+f(35167192221695, 2047);
+f(35184372090880, 2048);
+f(35201551960065, 2049);
+f(70351564312575, 4095);
+f(70368744181760, 4096);
+f(70385924050945, 4097);
+f(140720308494335, 8191);
+f(140737488363520, 8192);
+f(140754668232705, 8193);
+f(281457796857855, 16383);
+f(281474976727040, 16384);
+f(281492156596225, 16385);
+f(562932773584895, 32767);
+f(562949953454080, 32768);
+f(562967133323265, 32769);
+f(1125882727038975, 65535);
+f(1125899906908160, 65536);
+f(1125917086777345, 65537);
diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part2.js b/deps/v8/test/mjsunit/mul-exhaustive-part2.js
new file mode 100644
index 000000000..4c4a12384
--- /dev/null
+++ b/deps/v8/test/mjsunit/mul-exhaustive-part2.js
@@ -0,0 +1,525 @@
+// Copyright 2008 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.
+
+var x;
+
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
+}
+
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 1024;
+f(0, 0);
+f(1024, 1);
+f(2048, 2);
+f(3072, 3);
+f(4096, 4);
+f(5120, 5);
+f(7168, 7);
+f(8192, 8);
+f(9216, 9);
+f(15360, 15);
+f(16384, 16);
+f(17408, 17);
+f(31744, 31);
+f(32768, 32);
+f(33792, 33);
+f(64512, 63);
+f(65536, 64);
+f(66560, 65);
+f(130048, 127);
+f(131072, 128);
+f(132096, 129);
+f(261120, 255);
+f(262144, 256);
+f(263168, 257);
+f(523264, 511);
+f(524288, 512);
+f(525312, 513);
+f(1047552, 1023);
+f(1048576, 1024);
+x = 1025;
+f(0, 0);
+f(1025, 1);
+f(2050, 2);
+f(3075, 3);
+f(4100, 4);
+f(5125, 5);
+f(7175, 7);
+f(8200, 8);
+f(9225, 9);
+f(15375, 15);
+f(16400, 16);
+f(17425, 17);
+f(31775, 31);
+f(32800, 32);
+f(33825, 33);
+f(64575, 63);
+f(65600, 64);
+f(66625, 65);
+f(130175, 127);
+f(131200, 128);
+f(132225, 129);
+f(261375, 255);
+f(262400, 256);
+f(263425, 257);
+f(523775, 511);
+f(524800, 512);
+f(525825, 513);
+f(1048575, 1023);
+f(1049600, 1024);
+f(1050625, 1025);
+x = 2047;
+f(0, 0);
+f(2047, 1);
+f(4094, 2);
+f(6141, 3);
+f(8188, 4);
+f(10235, 5);
+f(14329, 7);
+f(16376, 8);
+f(18423, 9);
+f(30705, 15);
+f(32752, 16);
+f(34799, 17);
+f(63457, 31);
+f(65504, 32);
+f(67551, 33);
+f(128961, 63);
+f(131008, 64);
+f(133055, 65);
+f(259969, 127);
+f(262016, 128);
+f(264063, 129);
+f(521985, 255);
+f(524032, 256);
+f(526079, 257);
+f(1046017, 511);
+f(1048064, 512);
+f(1050111, 513);
+f(2094081, 1023);
+f(2096128, 1024);
+f(2098175, 1025);
+f(4190209, 2047);
+x = 2048;
+f(0, 0);
+f(2048, 1);
+f(4096, 2);
+f(6144, 3);
+f(8192, 4);
+f(10240, 5);
+f(14336, 7);
+f(16384, 8);
+f(18432, 9);
+f(30720, 15);
+f(32768, 16);
+f(34816, 17);
+f(63488, 31);
+f(65536, 32);
+f(67584, 33);
+f(129024, 63);
+f(131072, 64);
+f(133120, 65);
+f(260096, 127);
+f(262144, 128);
+f(264192, 129);
+f(522240, 255);
+f(524288, 256);
+f(526336, 257);
+f(1046528, 511);
+f(1048576, 512);
+f(1050624, 513);
+f(2095104, 1023);
+f(2097152, 1024);
+f(2099200, 1025);
+f(4192256, 2047);
+f(4194304, 2048);
+x = 2049;
+f(0, 0);
+f(2049, 1);
+f(4098, 2);
+f(6147, 3);
+f(8196, 4);
+f(10245, 5);
+f(14343, 7);
+f(16392, 8);
+f(18441, 9);
+f(30735, 15);
+f(32784, 16);
+f(34833, 17);
+f(63519, 31);
+f(65568, 32);
+f(67617, 33);
+f(129087, 63);
+f(131136, 64);
+f(133185, 65);
+f(260223, 127);
+f(262272, 128);
+f(264321, 129);
+f(522495, 255);
+f(524544, 256);
+f(526593, 257);
+f(1047039, 511);
+f(1049088, 512);
+f(1051137, 513);
+f(2096127, 1023);
+f(2098176, 1024);
+f(2100225, 1025);
+f(4194303, 2047);
+f(4196352, 2048);
+f(4198401, 2049);
+x = 4095;
+f(0, 0);
+f(4095, 1);
+f(8190, 2);
+f(12285, 3);
+f(16380, 4);
+f(20475, 5);
+f(28665, 7);
+f(32760, 8);
+f(36855, 9);
+f(61425, 15);
+f(65520, 16);
+f(69615, 17);
+f(126945, 31);
+f(131040, 32);
+f(135135, 33);
+f(257985, 63);
+f(262080, 64);
+f(266175, 65);
+f(520065, 127);
+f(524160, 128);
+f(528255, 129);
+f(1044225, 255);
+f(1048320, 256);
+f(1052415, 257);
+f(2092545, 511);
+f(2096640, 512);
+f(2100735, 513);
+f(4189185, 1023);
+f(4193280, 1024);
+f(4197375, 1025);
+f(8382465, 2047);
+f(8386560, 2048);
+f(8390655, 2049);
+f(16769025, 4095);
+x = 4096;
+f(0, 0);
+f(4096, 1);
+f(8192, 2);
+f(12288, 3);
+f(16384, 4);
+f(20480, 5);
+f(28672, 7);
+f(32768, 8);
+f(36864, 9);
+f(61440, 15);
+f(65536, 16);
+f(69632, 17);
+f(126976, 31);
+f(131072, 32);
+f(135168, 33);
+f(258048, 63);
+f(262144, 64);
+f(266240, 65);
+f(520192, 127);
+f(524288, 128);
+f(528384, 129);
+f(1044480, 255);
+f(1048576, 256);
+f(1052672, 257);
+f(2093056, 511);
+f(2097152, 512);
+f(2101248, 513);
+f(4190208, 1023);
+f(4194304, 1024);
+f(4198400, 1025);
+f(8384512, 2047);
+f(8388608, 2048);
+f(8392704, 2049);
+f(16773120, 4095);
+f(16777216, 4096);
+x = 4097;
+f(0, 0);
+f(4097, 1);
+f(8194, 2);
+f(12291, 3);
+f(16388, 4);
+f(20485, 5);
+f(28679, 7);
+f(32776, 8);
+f(36873, 9);
+f(61455, 15);
+f(65552, 16);
+f(69649, 17);
+f(127007, 31);
+f(131104, 32);
+f(135201, 33);
+f(258111, 63);
+f(262208, 64);
+f(266305, 65);
+f(520319, 127);
+f(524416, 128);
+f(528513, 129);
+f(1044735, 255);
+f(1048832, 256);
+f(1052929, 257);
+f(2093567, 511);
+f(2097664, 512);
+f(2101761, 513);
+f(4191231, 1023);
+f(4195328, 1024);
+f(4199425, 1025);
+f(8386559, 2047);
+f(8390656, 2048);
+f(8394753, 2049);
+f(16777215, 4095);
+f(16781312, 4096);
+f(16785409, 4097);
+x = 8191;
+f(0, 0);
+f(8191, 1);
+f(16382, 2);
+f(24573, 3);
+f(32764, 4);
+f(40955, 5);
+f(57337, 7);
+f(65528, 8);
+f(73719, 9);
+f(122865, 15);
+f(131056, 16);
+f(139247, 17);
+f(253921, 31);
+f(262112, 32);
+f(270303, 33);
+f(516033, 63);
+f(524224, 64);
+f(532415, 65);
+f(1040257, 127);
+f(1048448, 128);
+f(1056639, 129);
+f(2088705, 255);
+f(2096896, 256);
+f(2105087, 257);
+f(4185601, 511);
+f(4193792, 512);
+f(4201983, 513);
+f(8379393, 1023);
+f(8387584, 1024);
+f(8395775, 1025);
+f(16766977, 2047);
+f(16775168, 2048);
+f(16783359, 2049);
+f(33542145, 4095);
+f(33550336, 4096);
+f(33558527, 4097);
+f(67092481, 8191);
+x = 8192;
+f(0, 0);
+f(8192, 1);
+f(16384, 2);
+f(24576, 3);
+f(32768, 4);
+f(40960, 5);
+f(57344, 7);
+f(65536, 8);
+f(73728, 9);
+f(122880, 15);
+f(131072, 16);
+f(139264, 17);
+f(253952, 31);
+f(262144, 32);
+f(270336, 33);
+f(516096, 63);
+f(524288, 64);
+f(532480, 65);
+f(1040384, 127);
+f(1048576, 128);
+f(1056768, 129);
+f(2088960, 255);
+f(2097152, 256);
+f(2105344, 257);
+f(4186112, 511);
+f(4194304, 512);
+f(4202496, 513);
+f(8380416, 1023);
+f(8388608, 1024);
+f(8396800, 1025);
+f(16769024, 2047);
+f(16777216, 2048);
+f(16785408, 2049);
+f(33546240, 4095);
+f(33554432, 4096);
+f(33562624, 4097);
+f(67100672, 8191);
+f(67108864, 8192);
+x = 8193;
+f(0, 0);
+f(8193, 1);
+f(16386, 2);
+f(24579, 3);
+f(32772, 4);
+f(40965, 5);
+f(57351, 7);
+f(65544, 8);
+f(73737, 9);
+f(122895, 15);
+f(131088, 16);
+f(139281, 17);
+f(253983, 31);
+f(262176, 32);
+f(270369, 33);
+f(516159, 63);
+f(524352, 64);
+f(532545, 65);
+f(1040511, 127);
+f(1048704, 128);
+f(1056897, 129);
+f(2089215, 255);
+f(2097408, 256);
+f(2105601, 257);
+f(4186623, 511);
+f(4194816, 512);
+f(4203009, 513);
+f(8381439, 1023);
+f(8389632, 1024);
+f(8397825, 1025);
+f(16771071, 2047);
+f(16779264, 2048);
+f(16787457, 2049);
+f(33550335, 4095);
+f(33558528, 4096);
+f(33566721, 4097);
+f(67108863, 8191);
+f(67117056, 8192);
+f(67125249, 8193);
+x = 16383;
+f(0, 0);
+f(16383, 1);
+f(32766, 2);
+f(49149, 3);
+f(65532, 4);
+f(81915, 5);
+f(114681, 7);
+f(131064, 8);
+f(147447, 9);
+f(245745, 15);
+f(262128, 16);
+f(278511, 17);
+f(507873, 31);
+f(524256, 32);
+f(540639, 33);
+f(1032129, 63);
+f(1048512, 64);
+f(1064895, 65);
+f(2080641, 127);
+f(2097024, 128);
+f(2113407, 129);
+f(4177665, 255);
+f(4194048, 256);
+f(4210431, 257);
+f(8371713, 511);
+f(8388096, 512);
+f(8404479, 513);
+f(16759809, 1023);
+f(16776192, 1024);
+f(16792575, 1025);
+f(33536001, 2047);
+f(33552384, 2048);
+f(33568767, 2049);
+f(67088385, 4095);
+f(67104768, 4096);
+f(67121151, 4097);
+f(134193153, 8191);
+f(134209536, 8192);
+f(134225919, 8193);
+f(268402689, 16383);
+x = 16384;
+f(0, 0);
+f(16384, 1);
+f(32768, 2);
+f(49152, 3);
+f(65536, 4);
+f(81920, 5);
+f(114688, 7);
+f(131072, 8);
+f(147456, 9);
+f(245760, 15);
+f(262144, 16);
+f(278528, 17);
+f(507904, 31);
+f(524288, 32);
+f(540672, 33);
+f(1032192, 63);
+f(1048576, 64);
+f(1064960, 65);
+f(2080768, 127);
+f(2097152, 128);
+f(2113536, 129);
+f(4177920, 255);
+f(4194304, 256);
+f(4210688, 257);
+f(8372224, 511);
+f(8388608, 512);
+f(8404992, 513);
+f(16760832, 1023);
+f(16777216, 1024);
+f(16793600, 1025);
+f(33538048, 2047);
+f(33554432, 2048);
+f(33570816, 2049);
+f(67092480, 4095);
+f(67108864, 4096);
+f(67125248, 4097);
+f(134201344, 8191);
+f(134217728, 8192);
+f(134234112, 8193);
+f(268419072, 16383);
+f(268435456, 16384);
diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part3.js b/deps/v8/test/mjsunit/mul-exhaustive-part3.js
new file mode 100644
index 000000000..06e41a1d4
--- /dev/null
+++ b/deps/v8/test/mjsunit/mul-exhaustive-part3.js
@@ -0,0 +1,532 @@
+// Copyright 2008 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.
+
+var x;
+
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
+}
+
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 16385;
+f(0, 0);
+f(16385, 1);
+f(32770, 2);
+f(49155, 3);
+f(65540, 4);
+f(81925, 5);
+f(114695, 7);
+f(131080, 8);
+f(147465, 9);
+f(245775, 15);
+f(262160, 16);
+f(278545, 17);
+f(507935, 31);
+f(524320, 32);
+f(540705, 33);
+f(1032255, 63);
+f(1048640, 64);
+f(1065025, 65);
+f(2080895, 127);
+f(2097280, 128);
+f(2113665, 129);
+f(4178175, 255);
+f(4194560, 256);
+f(4210945, 257);
+f(8372735, 511);
+f(8389120, 512);
+f(8405505, 513);
+f(16761855, 1023);
+f(16778240, 1024);
+f(16794625, 1025);
+f(33540095, 2047);
+f(33556480, 2048);
+f(33572865, 2049);
+f(67096575, 4095);
+f(67112960, 4096);
+f(67129345, 4097);
+f(134209535, 8191);
+f(134225920, 8192);
+f(134242305, 8193);
+f(268435455, 16383);
+f(268451840, 16384);
+f(268468225, 16385);
+x = 32767;
+f(0, 0);
+f(32767, 1);
+f(65534, 2);
+f(98301, 3);
+f(131068, 4);
+f(163835, 5);
+f(229369, 7);
+f(262136, 8);
+f(294903, 9);
+f(491505, 15);
+f(524272, 16);
+f(557039, 17);
+f(1015777, 31);
+f(1048544, 32);
+f(1081311, 33);
+f(2064321, 63);
+f(2097088, 64);
+f(2129855, 65);
+f(4161409, 127);
+f(4194176, 128);
+f(4226943, 129);
+f(8355585, 255);
+f(8388352, 256);
+f(8421119, 257);
+f(16743937, 511);
+f(16776704, 512);
+f(16809471, 513);
+f(33520641, 1023);
+f(33553408, 1024);
+f(33586175, 1025);
+f(67074049, 2047);
+f(67106816, 2048);
+f(67139583, 2049);
+f(134180865, 4095);
+f(134213632, 4096);
+f(134246399, 4097);
+f(268394497, 8191);
+f(268427264, 8192);
+f(268460031, 8193);
+f(536821761, 16383);
+f(536854528, 16384);
+f(536887295, 16385);
+f(1073676289, 32767);
+x = 32768;
+f(0, 0);
+f(32768, 1);
+f(65536, 2);
+f(98304, 3);
+f(131072, 4);
+f(163840, 5);
+f(229376, 7);
+f(262144, 8);
+f(294912, 9);
+f(491520, 15);
+f(524288, 16);
+f(557056, 17);
+f(1015808, 31);
+f(1048576, 32);
+f(1081344, 33);
+f(2064384, 63);
+f(2097152, 64);
+f(2129920, 65);
+f(4161536, 127);
+f(4194304, 128);
+f(4227072, 129);
+f(8355840, 255);
+f(8388608, 256);
+f(8421376, 257);
+f(16744448, 511);
+f(16777216, 512);
+f(16809984, 513);
+f(33521664, 1023);
+f(33554432, 1024);
+f(33587200, 1025);
+f(67076096, 2047);
+f(67108864, 2048);
+f(67141632, 2049);
+f(134184960, 4095);
+f(134217728, 4096);
+f(134250496, 4097);
+f(268402688, 8191);
+f(268435456, 8192);
+f(268468224, 8193);
+f(536838144, 16383);
+f(536870912, 16384);
+f(536903680, 16385);
+f(1073709056, 32767);
+f(1073741824, 32768);
+x = 32769;
+f(0, 0);
+f(32769, 1);
+f(65538, 2);
+f(98307, 3);
+f(131076, 4);
+f(163845, 5);
+f(229383, 7);
+f(262152, 8);
+f(294921, 9);
+f(491535, 15);
+f(524304, 16);
+f(557073, 17);
+f(1015839, 31);
+f(1048608, 32);
+f(1081377, 33);
+f(2064447, 63);
+f(2097216, 64);
+f(2129985, 65);
+f(4161663, 127);
+f(4194432, 128);
+f(4227201, 129);
+f(8356095, 255);
+f(8388864, 256);
+f(8421633, 257);
+f(16744959, 511);
+f(16777728, 512);
+f(16810497, 513);
+f(33522687, 1023);
+f(33555456, 1024);
+f(33588225, 1025);
+f(67078143, 2047);
+f(67110912, 2048);
+f(67143681, 2049);
+f(134189055, 4095);
+f(134221824, 4096);
+f(134254593, 4097);
+f(268410879, 8191);
+f(268443648, 8192);
+f(268476417, 8193);
+f(536854527, 16383);
+f(536887296, 16384);
+f(536920065, 16385);
+f(1073741823, 32767);
+f(1073774592, 32768);
+f(1073807361, 32769);
+x = 65535;
+f(0, 0);
+f(65535, 1);
+f(131070, 2);
+f(196605, 3);
+f(262140, 4);
+f(327675, 5);
+f(458745, 7);
+f(524280, 8);
+f(589815, 9);
+f(983025, 15);
+f(1048560, 16);
+f(1114095, 17);
+f(2031585, 31);
+f(2097120, 32);
+f(2162655, 33);
+f(4128705, 63);
+f(4194240, 64);
+f(4259775, 65);
+f(8322945, 127);
+f(8388480, 128);
+f(8454015, 129);
+f(16711425, 255);
+f(16776960, 256);
+f(16842495, 257);
+f(33488385, 511);
+f(33553920, 512);
+f(33619455, 513);
+f(67042305, 1023);
+f(67107840, 1024);
+f(67173375, 1025);
+f(134150145, 2047);
+f(134215680, 2048);
+f(134281215, 2049);
+f(268365825, 4095);
+f(268431360, 4096);
+f(268496895, 4097);
+f(536797185, 8191);
+f(536862720, 8192);
+f(536928255, 8193);
+f(1073659905, 16383);
+f(1073725440, 16384);
+f(1073790975, 16385);
+f(2147385345, 32767);
+f(2147450880, 32768);
+f(2147516415, 32769);
+f(4294836225, 65535);
+x = 65536;
+f(0, 0);
+f(65536, 1);
+f(131072, 2);
+f(196608, 3);
+f(262144, 4);
+f(327680, 5);
+f(458752, 7);
+f(524288, 8);
+f(589824, 9);
+f(983040, 15);
+f(1048576, 16);
+f(1114112, 17);
+f(2031616, 31);
+f(2097152, 32);
+f(2162688, 33);
+f(4128768, 63);
+f(4194304, 64);
+f(4259840, 65);
+f(8323072, 127);
+f(8388608, 128);
+f(8454144, 129);
+f(16711680, 255);
+f(16777216, 256);
+f(16842752, 257);
+f(33488896, 511);
+f(33554432, 512);
+f(33619968, 513);
+f(67043328, 1023);
+f(67108864, 1024);
+f(67174400, 1025);
+f(134152192, 2047);
+f(134217728, 2048);
+f(134283264, 2049);
+f(268369920, 4095);
+f(268435456, 4096);
+f(268500992, 4097);
+f(536805376, 8191);
+f(536870912, 8192);
+f(536936448, 8193);
+f(1073676288, 16383);
+f(1073741824, 16384);
+f(1073807360, 16385);
+f(2147418112, 32767);
+f(2147483648, 32768);
+f(2147549184, 32769);
+f(4294901760, 65535);
+f(4294967296, 65536);
+x = 65537;
+f(0, 0);
+f(65537, 1);
+f(131074, 2);
+f(196611, 3);
+f(262148, 4);
+f(327685, 5);
+f(458759, 7);
+f(524296, 8);
+f(589833, 9);
+f(983055, 15);
+f(1048592, 16);
+f(1114129, 17);
+f(2031647, 31);
+f(2097184, 32);
+f(2162721, 33);
+f(4128831, 63);
+f(4194368, 64);
+f(4259905, 65);
+f(8323199, 127);
+f(8388736, 128);
+f(8454273, 129);
+f(16711935, 255);
+f(16777472, 256);
+f(16843009, 257);
+f(33489407, 511);
+f(33554944, 512);
+f(33620481, 513);
+f(67044351, 1023);
+f(67109888, 1024);
+f(67175425, 1025);
+f(134154239, 2047);
+f(134219776, 2048);
+f(134285313, 2049);
+f(268374015, 4095);
+f(268439552, 4096);
+f(268505089, 4097);
+f(536813567, 8191);
+f(536879104, 8192);
+f(536944641, 8193);
+f(1073692671, 16383);
+f(1073758208, 16384);
+f(1073823745, 16385);
+f(2147450879, 32767);
+f(2147516416, 32768);
+f(2147581953, 32769);
+f(4294967295, 65535);
+f(4295032832, 65536);
+f(4295098369, 65537);
+x = 131071;
+f(0, 0);
+f(131071, 1);
+f(262142, 2);
+f(393213, 3);
+f(524284, 4);
+f(655355, 5);
+f(917497, 7);
+f(1048568, 8);
+f(1179639, 9);
+f(1966065, 15);
+f(2097136, 16);
+f(2228207, 17);
+f(4063201, 31);
+f(4194272, 32);
+f(4325343, 33);
+f(8257473, 63);
+f(8388544, 64);
+f(8519615, 65);
+f(16646017, 127);
+f(16777088, 128);
+f(16908159, 129);
+f(33423105, 255);
+f(33554176, 256);
+f(33685247, 257);
+f(66977281, 511);
+f(67108352, 512);
+f(67239423, 513);
+f(134085633, 1023);
+f(134216704, 1024);
+f(134347775, 1025);
+f(268302337, 2047);
+f(268433408, 2048);
+f(268564479, 2049);
+f(536735745, 4095);
+f(536866816, 4096);
+f(536997887, 4097);
+f(1073602561, 8191);
+f(1073733632, 8192);
+f(1073864703, 8193);
+f(2147336193, 16383);
+f(2147467264, 16384);
+f(2147598335, 16385);
+f(4294803457, 32767);
+f(4294934528, 32768);
+f(4295065599, 32769);
+f(8589737985, 65535);
+f(8589869056, 65536);
+f(8590000127, 65537);
+f(17179607041, 131071);
+x = 131072;
+f(0, 0);
+f(131072, 1);
+f(262144, 2);
+f(393216, 3);
+f(524288, 4);
+f(655360, 5);
+f(917504, 7);
+f(1048576, 8);
+f(1179648, 9);
+f(1966080, 15);
+f(2097152, 16);
+f(2228224, 17);
+f(4063232, 31);
+f(4194304, 32);
+f(4325376, 33);
+f(8257536, 63);
+f(8388608, 64);
+f(8519680, 65);
+f(16646144, 127);
+f(16777216, 128);
+f(16908288, 129);
+f(33423360, 255);
+f(33554432, 256);
+f(33685504, 257);
+f(66977792, 511);
+f(67108864, 512);
+f(67239936, 513);
+f(134086656, 1023);
+f(134217728, 1024);
+f(134348800, 1025);
+f(268304384, 2047);
+f(268435456, 2048);
+f(268566528, 2049);
+f(536739840, 4095);
+f(536870912, 4096);
+f(537001984, 4097);
+f(1073610752, 8191);
+f(1073741824, 8192);
+f(1073872896, 8193);
+f(2147352576, 16383);
+f(2147483648, 16384);
+f(2147614720, 16385);
+f(4294836224, 32767);
+f(4294967296, 32768);
+f(4295098368, 32769);
+f(8589803520, 65535);
+f(8589934592, 65536);
+f(8590065664, 65537);
+f(17179738112, 131071);
+f(17179869184, 131072);
+x = 131073;
+f(0, 0);
+f(131073, 1);
+f(262146, 2);
+f(393219, 3);
+f(524292, 4);
+f(655365, 5);
+f(917511, 7);
+f(1048584, 8);
+f(1179657, 9);
+f(1966095, 15);
+f(2097168, 16);
+f(2228241, 17);
+f(4063263, 31);
+f(4194336, 32);
+f(4325409, 33);
+f(8257599, 63);
+f(8388672, 64);
+f(8519745, 65);
+f(16646271, 127);
+f(16777344, 128);
+f(16908417, 129);
+f(33423615, 255);
+f(33554688, 256);
+f(33685761, 257);
+f(66978303, 511);
+f(67109376, 512);
+f(67240449, 513);
+f(134087679, 1023);
+f(134218752, 1024);
+f(134349825, 1025);
+f(268306431, 2047);
+f(268437504, 2048);
+f(268568577, 2049);
+f(536743935, 4095);
+f(536875008, 4096);
+f(537006081, 4097);
+f(1073618943, 8191);
+f(1073750016, 8192);
+f(1073881089, 8193);
+f(2147368959, 16383);
+f(2147500032, 16384);
+f(2147631105, 16385);
+f(4294868991, 32767);
+f(4295000064, 32768);
+f(4295131137, 32769);
+f(8589869055, 65535);
+f(8590000128, 65536);
+f(8590131201, 65537);
+f(17179869183, 131071);
+f(17180000256, 131072);
+f(17180131329, 131073);
diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part4.js b/deps/v8/test/mjsunit/mul-exhaustive-part4.js
new file mode 100644
index 000000000..de9f9835b
--- /dev/null
+++ b/deps/v8/test/mjsunit/mul-exhaustive-part4.js
@@ -0,0 +1,509 @@
+// Copyright 2008 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.
+
+var x;
+
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
+}
+
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 262143;
+f(0, 0);
+f(262143, 1);
+f(524286, 2);
+f(786429, 3);
+f(1048572, 4);
+f(1310715, 5);
+f(1835001, 7);
+f(2097144, 8);
+f(2359287, 9);
+f(3932145, 15);
+f(4194288, 16);
+f(4456431, 17);
+f(8126433, 31);
+f(8388576, 32);
+f(8650719, 33);
+f(16515009, 63);
+f(16777152, 64);
+f(17039295, 65);
+f(33292161, 127);
+f(33554304, 128);
+f(33816447, 129);
+f(66846465, 255);
+f(67108608, 256);
+f(67370751, 257);
+f(133955073, 511);
+f(134217216, 512);
+f(134479359, 513);
+f(268172289, 1023);
+f(268434432, 1024);
+f(268696575, 1025);
+f(536606721, 2047);
+f(536868864, 2048);
+f(537131007, 2049);
+f(1073475585, 4095);
+f(1073737728, 4096);
+f(1073999871, 4097);
+f(2147213313, 8191);
+f(2147475456, 8192);
+f(2147737599, 8193);
+f(4294688769, 16383);
+f(4294950912, 16384);
+f(4295213055, 16385);
+f(8589639681, 32767);
+f(8589901824, 32768);
+f(8590163967, 32769);
+f(17179541505, 65535);
+f(17179803648, 65536);
+f(17180065791, 65537);
+f(34359345153, 131071);
+f(34359607296, 131072);
+f(34359869439, 131073);
+f(68718952449, 262143);
+x = 262144;
+f(0, 0);
+f(262144, 1);
+f(524288, 2);
+f(786432, 3);
+f(1048576, 4);
+f(1310720, 5);
+f(1835008, 7);
+f(2097152, 8);
+f(2359296, 9);
+f(3932160, 15);
+f(4194304, 16);
+f(4456448, 17);
+f(8126464, 31);
+f(8388608, 32);
+f(8650752, 33);
+f(16515072, 63);
+f(16777216, 64);
+f(17039360, 65);
+f(33292288, 127);
+f(33554432, 128);
+f(33816576, 129);
+f(66846720, 255);
+f(67108864, 256);
+f(67371008, 257);
+f(133955584, 511);
+f(134217728, 512);
+f(134479872, 513);
+f(268173312, 1023);
+f(268435456, 1024);
+f(268697600, 1025);
+f(536608768, 2047);
+f(536870912, 2048);
+f(537133056, 2049);
+f(1073479680, 4095);
+f(1073741824, 4096);
+f(1074003968, 4097);
+f(2147221504, 8191);
+f(2147483648, 8192);
+f(2147745792, 8193);
+f(4294705152, 16383);
+f(4294967296, 16384);
+f(4295229440, 16385);
+f(8589672448, 32767);
+f(8589934592, 32768);
+f(8590196736, 32769);
+f(17179607040, 65535);
+f(17179869184, 65536);
+f(17180131328, 65537);
+f(34359476224, 131071);
+f(34359738368, 131072);
+f(34360000512, 131073);
+f(68719214592, 262143);
+f(68719476736, 262144);
+x = 262145;
+f(0, 0);
+f(262145, 1);
+f(524290, 2);
+f(786435, 3);
+f(1048580, 4);
+f(1310725, 5);
+f(1835015, 7);
+f(2097160, 8);
+f(2359305, 9);
+f(3932175, 15);
+f(4194320, 16);
+f(4456465, 17);
+f(8126495, 31);
+f(8388640, 32);
+f(8650785, 33);
+f(16515135, 63);
+f(16777280, 64);
+f(17039425, 65);
+f(33292415, 127);
+f(33554560, 128);
+f(33816705, 129);
+f(66846975, 255);
+f(67109120, 256);
+f(67371265, 257);
+f(133956095, 511);
+f(134218240, 512);
+f(134480385, 513);
+f(268174335, 1023);
+f(268436480, 1024);
+f(268698625, 1025);
+f(536610815, 2047);
+f(536872960, 2048);
+f(537135105, 2049);
+f(1073483775, 4095);
+f(1073745920, 4096);
+f(1074008065, 4097);
+f(2147229695, 8191);
+f(2147491840, 8192);
+f(2147753985, 8193);
+f(4294721535, 16383);
+f(4294983680, 16384);
+f(4295245825, 16385);
+f(8589705215, 32767);
+f(8589967360, 32768);
+f(8590229505, 32769);
+f(17179672575, 65535);
+f(17179934720, 65536);
+f(17180196865, 65537);
+f(34359607295, 131071);
+f(34359869440, 131072);
+f(34360131585, 131073);
+f(68719476735, 262143);
+f(68719738880, 262144);
+f(68720001025, 262145);
+x = 524287;
+f(0, 0);
+f(524287, 1);
+f(1048574, 2);
+f(1572861, 3);
+f(2097148, 4);
+f(2621435, 5);
+f(3670009, 7);
+f(4194296, 8);
+f(4718583, 9);
+f(7864305, 15);
+f(8388592, 16);
+f(8912879, 17);
+f(16252897, 31);
+f(16777184, 32);
+f(17301471, 33);
+f(33030081, 63);
+f(33554368, 64);
+f(34078655, 65);
+f(66584449, 127);
+f(67108736, 128);
+f(67633023, 129);
+f(133693185, 255);
+f(134217472, 256);
+f(134741759, 257);
+f(267910657, 511);
+f(268434944, 512);
+f(268959231, 513);
+f(536345601, 1023);
+f(536869888, 1024);
+f(537394175, 1025);
+f(1073215489, 2047);
+f(1073739776, 2048);
+f(1074264063, 2049);
+f(2146955265, 4095);
+f(2147479552, 4096);
+f(2148003839, 4097);
+f(4294434817, 8191);
+f(4294959104, 8192);
+f(4295483391, 8193);
+f(8589393921, 16383);
+f(8589918208, 16384);
+f(8590442495, 16385);
+f(17179312129, 32767);
+f(17179836416, 32768);
+f(17180360703, 32769);
+f(34359148545, 65535);
+f(34359672832, 65536);
+f(34360197119, 65537);
+f(68718821377, 131071);
+f(68719345664, 131072);
+f(68719869951, 131073);
+f(137438167041, 262143);
+f(137438691328, 262144);
+f(137439215615, 262145);
+f(274876858369, 524287);
+x = 524288;
+f(0, 0);
+f(524288, 1);
+f(1048576, 2);
+f(1572864, 3);
+f(2097152, 4);
+f(2621440, 5);
+f(3670016, 7);
+f(4194304, 8);
+f(4718592, 9);
+f(7864320, 15);
+f(8388608, 16);
+f(8912896, 17);
+f(16252928, 31);
+f(16777216, 32);
+f(17301504, 33);
+f(33030144, 63);
+f(33554432, 64);
+f(34078720, 65);
+f(66584576, 127);
+f(67108864, 128);
+f(67633152, 129);
+f(133693440, 255);
+f(134217728, 256);
+f(134742016, 257);
+f(267911168, 511);
+f(268435456, 512);
+f(268959744, 513);
+f(536346624, 1023);
+f(536870912, 1024);
+f(537395200, 1025);
+f(1073217536, 2047);
+f(1073741824, 2048);
+f(1074266112, 2049);
+f(2146959360, 4095);
+f(2147483648, 4096);
+f(2148007936, 4097);
+f(4294443008, 8191);
+f(4294967296, 8192);
+f(4295491584, 8193);
+f(8589410304, 16383);
+f(8589934592, 16384);
+f(8590458880, 16385);
+f(17179344896, 32767);
+f(17179869184, 32768);
+f(17180393472, 32769);
+f(34359214080, 65535);
+f(34359738368, 65536);
+f(34360262656, 65537);
+f(68718952448, 131071);
+f(68719476736, 131072);
+f(68720001024, 131073);
+f(137438429184, 262143);
+f(137438953472, 262144);
+f(137439477760, 262145);
+f(274877382656, 524287);
+f(274877906944, 524288);
+x = 524289;
+f(0, 0);
+f(524289, 1);
+f(1048578, 2);
+f(1572867, 3);
+f(2097156, 4);
+f(2621445, 5);
+f(3670023, 7);
+f(4194312, 8);
+f(4718601, 9);
+f(7864335, 15);
+f(8388624, 16);
+f(8912913, 17);
+f(16252959, 31);
+f(16777248, 32);
+f(17301537, 33);
+f(33030207, 63);
+f(33554496, 64);
+f(34078785, 65);
+f(66584703, 127);
+f(67108992, 128);
+f(67633281, 129);
+f(133693695, 255);
+f(134217984, 256);
+f(134742273, 257);
+f(267911679, 511);
+f(268435968, 512);
+f(268960257, 513);
+f(536347647, 1023);
+f(536871936, 1024);
+f(537396225, 1025);
+f(1073219583, 2047);
+f(1073743872, 2048);
+f(1074268161, 2049);
+f(2146963455, 4095);
+f(2147487744, 4096);
+f(2148012033, 4097);
+f(4294451199, 8191);
+f(4294975488, 8192);
+f(4295499777, 8193);
+f(8589426687, 16383);
+f(8589950976, 16384);
+f(8590475265, 16385);
+f(17179377663, 32767);
+f(17179901952, 32768);
+f(17180426241, 32769);
+f(34359279615, 65535);
+f(34359803904, 65536);
+f(34360328193, 65537);
+f(68719083519, 131071);
+f(68719607808, 131072);
+f(68720132097, 131073);
+f(137438691327, 262143);
+f(137439215616, 262144);
+f(137439739905, 262145);
+f(274877906943, 524287);
+f(274878431232, 524288);
+f(274878955521, 524289);
+x = 1048575;
+f(0, 0);
+f(1048575, 1);
+f(2097150, 2);
+f(3145725, 3);
+f(4194300, 4);
+f(5242875, 5);
+f(7340025, 7);
+f(8388600, 8);
+f(9437175, 9);
+f(15728625, 15);
+f(16777200, 16);
+f(17825775, 17);
+f(32505825, 31);
+f(33554400, 32);
+f(34602975, 33);
+f(66060225, 63);
+f(67108800, 64);
+f(68157375, 65);
+f(133169025, 127);
+f(134217600, 128);
+f(135266175, 129);
+f(267386625, 255);
+f(268435200, 256);
+f(269483775, 257);
+f(535821825, 511);
+f(536870400, 512);
+f(537918975, 513);
+f(1072692225, 1023);
+f(1073740800, 1024);
+f(1074789375, 1025);
+f(2146433025, 2047);
+f(2147481600, 2048);
+f(2148530175, 2049);
+f(4293914625, 4095);
+f(4294963200, 4096);
+f(4296011775, 4097);
+f(8588877825, 8191);
+f(8589926400, 8192);
+f(8590974975, 8193);
+f(17178804225, 16383);
+f(17179852800, 16384);
+f(17180901375, 16385);
+f(34358657025, 32767);
+f(34359705600, 32768);
+f(34360754175, 32769);
+f(68718362625, 65535);
+f(68719411200, 65536);
+f(68720459775, 65537);
+f(137437773825, 131071);
+f(137438822400, 131072);
+f(137439870975, 131073);
+f(274876596225, 262143);
+f(274877644800, 262144);
+f(274878693375, 262145);
+f(549754241025, 524287);
+f(549755289600, 524288);
+f(549756338175, 524289);
+f(1099509530625, 1048575);
+x = 1048576;
+f(0, 0);
+f(1048576, 1);
+f(2097152, 2);
+f(3145728, 3);
+f(4194304, 4);
+f(5242880, 5);
+f(7340032, 7);
+f(8388608, 8);
+f(9437184, 9);
+f(15728640, 15);
+f(16777216, 16);
+f(17825792, 17);
+f(32505856, 31);
+f(33554432, 32);
+f(34603008, 33);
+f(66060288, 63);
+f(67108864, 64);
+f(68157440, 65);
+f(133169152, 127);
+f(134217728, 128);
+f(135266304, 129);
+f(267386880, 255);
+f(268435456, 256);
+f(269484032, 257);
+f(535822336, 511);
+f(536870912, 512);
+f(537919488, 513);
+f(1072693248, 1023);
+f(1073741824, 1024);
+f(1074790400, 1025);
+f(2146435072, 2047);
+f(2147483648, 2048);
+f(2148532224, 2049);
+f(4293918720, 4095);
+f(4294967296, 4096);
+f(4296015872, 4097);
+f(8588886016, 8191);
+f(8589934592, 8192);
+f(8590983168, 8193);
+f(17178820608, 16383);
+f(17179869184, 16384);
+f(17180917760, 16385);
+f(34358689792, 32767);
+f(34359738368, 32768);
+f(34360786944, 32769);
+f(68718428160, 65535);
+f(68719476736, 65536);
+f(68720525312, 65537);
+f(137437904896, 131071);
+f(137438953472, 131072);
+f(137440002048, 131073);
+f(274876858368, 262143);
+f(274877906944, 262144);
+f(274878955520, 262145);
+f(549754765312, 524287);
+f(549755813888, 524288);
+f(549756862464, 524289);
+f(1099510579200, 1048575);
+f(1099511627776, 1048576);
diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part5.js b/deps/v8/test/mjsunit/mul-exhaustive-part5.js
new file mode 100644
index 000000000..e92998575
--- /dev/null
+++ b/deps/v8/test/mjsunit/mul-exhaustive-part5.js
@@ -0,0 +1,505 @@
+// Copyright 2008 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.
+
+var x;
+
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
+}
+
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 1048577;
+f(0, 0);
+f(1048577, 1);
+f(2097154, 2);
+f(3145731, 3);
+f(4194308, 4);
+f(5242885, 5);
+f(7340039, 7);
+f(8388616, 8);
+f(9437193, 9);
+f(15728655, 15);
+f(16777232, 16);
+f(17825809, 17);
+f(32505887, 31);
+f(33554464, 32);
+f(34603041, 33);
+f(66060351, 63);
+f(67108928, 64);
+f(68157505, 65);
+f(133169279, 127);
+f(134217856, 128);
+f(135266433, 129);
+f(267387135, 255);
+f(268435712, 256);
+f(269484289, 257);
+f(535822847, 511);
+f(536871424, 512);
+f(537920001, 513);
+f(1072694271, 1023);
+f(1073742848, 1024);
+f(1074791425, 1025);
+f(2146437119, 2047);
+f(2147485696, 2048);
+f(2148534273, 2049);
+f(4293922815, 4095);
+f(4294971392, 4096);
+f(4296019969, 4097);
+f(8588894207, 8191);
+f(8589942784, 8192);
+f(8590991361, 8193);
+f(17178836991, 16383);
+f(17179885568, 16384);
+f(17180934145, 16385);
+f(34358722559, 32767);
+f(34359771136, 32768);
+f(34360819713, 32769);
+f(68718493695, 65535);
+f(68719542272, 65536);
+f(68720590849, 65537);
+f(137438035967, 131071);
+f(137439084544, 131072);
+f(137440133121, 131073);
+f(274877120511, 262143);
+f(274878169088, 262144);
+f(274879217665, 262145);
+f(549755289599, 524287);
+f(549756338176, 524288);
+f(549757386753, 524289);
+f(1099511627775, 1048575);
+f(1099512676352, 1048576);
+f(1099513724929, 1048577);
+x = 2097151;
+f(0, 0);
+f(2097151, 1);
+f(4194302, 2);
+f(6291453, 3);
+f(8388604, 4);
+f(10485755, 5);
+f(14680057, 7);
+f(16777208, 8);
+f(18874359, 9);
+f(31457265, 15);
+f(33554416, 16);
+f(35651567, 17);
+f(65011681, 31);
+f(67108832, 32);
+f(69205983, 33);
+f(132120513, 63);
+f(134217664, 64);
+f(136314815, 65);
+f(266338177, 127);
+f(268435328, 128);
+f(270532479, 129);
+f(534773505, 255);
+f(536870656, 256);
+f(538967807, 257);
+f(1071644161, 511);
+f(1073741312, 512);
+f(1075838463, 513);
+f(2145385473, 1023);
+f(2147482624, 1024);
+f(2149579775, 1025);
+f(4292868097, 2047);
+f(4294965248, 2048);
+f(4297062399, 2049);
+f(8587833345, 4095);
+f(8589930496, 4096);
+f(8592027647, 4097);
+f(17177763841, 8191);
+f(17179860992, 8192);
+f(17181958143, 8193);
+f(34357624833, 16383);
+f(34359721984, 16384);
+f(34361819135, 16385);
+f(68717346817, 32767);
+f(68719443968, 32768);
+f(68721541119, 32769);
+f(137436790785, 65535);
+f(137438887936, 65536);
+f(137440985087, 65537);
+f(274875678721, 131071);
+f(274877775872, 131072);
+f(274879873023, 131073);
+f(549753454593, 262143);
+f(549755551744, 262144);
+f(549757648895, 262145);
+f(1099509006337, 524287);
+f(1099511103488, 524288);
+f(1099513200639, 524289);
+f(2199020109825, 1048575);
+f(2199022206976, 1048576);
+f(2199024304127, 1048577);
+f(4398042316801, 2097151);
+x = 2097152;
+f(0, 0);
+f(2097152, 1);
+f(4194304, 2);
+f(6291456, 3);
+f(8388608, 4);
+f(10485760, 5);
+f(14680064, 7);
+f(16777216, 8);
+f(18874368, 9);
+f(31457280, 15);
+f(33554432, 16);
+f(35651584, 17);
+f(65011712, 31);
+f(67108864, 32);
+f(69206016, 33);
+f(132120576, 63);
+f(134217728, 64);
+f(136314880, 65);
+f(266338304, 127);
+f(268435456, 128);
+f(270532608, 129);
+f(534773760, 255);
+f(536870912, 256);
+f(538968064, 257);
+f(1071644672, 511);
+f(1073741824, 512);
+f(1075838976, 513);
+f(2145386496, 1023);
+f(2147483648, 1024);
+f(2149580800, 1025);
+f(4292870144, 2047);
+f(4294967296, 2048);
+f(4297064448, 2049);
+f(8587837440, 4095);
+f(8589934592, 4096);
+f(8592031744, 4097);
+f(17177772032, 8191);
+f(17179869184, 8192);
+f(17181966336, 8193);
+f(34357641216, 16383);
+f(34359738368, 16384);
+f(34361835520, 16385);
+f(68717379584, 32767);
+f(68719476736, 32768);
+f(68721573888, 32769);
+f(137436856320, 65535);
+f(137438953472, 65536);
+f(137441050624, 65537);
+f(274875809792, 131071);
+f(274877906944, 131072);
+f(274880004096, 131073);
+f(549753716736, 262143);
+f(549755813888, 262144);
+f(549757911040, 262145);
+f(1099509530624, 524287);
+f(1099511627776, 524288);
+f(1099513724928, 524289);
+f(2199021158400, 1048575);
+f(2199023255552, 1048576);
+f(2199025352704, 1048577);
+f(4398044413952, 2097151);
+f(4398046511104, 2097152);
+x = 2097153;
+f(0, 0);
+f(2097153, 1);
+f(4194306, 2);
+f(6291459, 3);
+f(8388612, 4);
+f(10485765, 5);
+f(14680071, 7);
+f(16777224, 8);
+f(18874377, 9);
+f(31457295, 15);
+f(33554448, 16);
+f(35651601, 17);
+f(65011743, 31);
+f(67108896, 32);
+f(69206049, 33);
+f(132120639, 63);
+f(134217792, 64);
+f(136314945, 65);
+f(266338431, 127);
+f(268435584, 128);
+f(270532737, 129);
+f(534774015, 255);
+f(536871168, 256);
+f(538968321, 257);
+f(1071645183, 511);
+f(1073742336, 512);
+f(1075839489, 513);
+f(2145387519, 1023);
+f(2147484672, 1024);
+f(2149581825, 1025);
+f(4292872191, 2047);
+f(4294969344, 2048);
+f(4297066497, 2049);
+f(8587841535, 4095);
+f(8589938688, 4096);
+f(8592035841, 4097);
+f(17177780223, 8191);
+f(17179877376, 8192);
+f(17181974529, 8193);
+f(34357657599, 16383);
+f(34359754752, 16384);
+f(34361851905, 16385);
+f(68717412351, 32767);
+f(68719509504, 32768);
+f(68721606657, 32769);
+f(137436921855, 65535);
+f(137439019008, 65536);
+f(137441116161, 65537);
+f(274875940863, 131071);
+f(274878038016, 131072);
+f(274880135169, 131073);
+f(549753978879, 262143);
+f(549756076032, 262144);
+f(549758173185, 262145);
+f(1099510054911, 524287);
+f(1099512152064, 524288);
+f(1099514249217, 524289);
+f(2199022206975, 1048575);
+f(2199024304128, 1048576);
+f(2199026401281, 1048577);
+f(4398046511103, 2097151);
+f(4398048608256, 2097152);
+f(4398050705409, 2097153);
+x = 4194303;
+f(0, 0);
+f(4194303, 1);
+f(8388606, 2);
+f(12582909, 3);
+f(16777212, 4);
+f(20971515, 5);
+f(29360121, 7);
+f(33554424, 8);
+f(37748727, 9);
+f(62914545, 15);
+f(67108848, 16);
+f(71303151, 17);
+f(130023393, 31);
+f(134217696, 32);
+f(138411999, 33);
+f(264241089, 63);
+f(268435392, 64);
+f(272629695, 65);
+f(532676481, 127);
+f(536870784, 128);
+f(541065087, 129);
+f(1069547265, 255);
+f(1073741568, 256);
+f(1077935871, 257);
+f(2143288833, 511);
+f(2147483136, 512);
+f(2151677439, 513);
+f(4290771969, 1023);
+f(4294966272, 1024);
+f(4299160575, 1025);
+f(8585738241, 2047);
+f(8589932544, 2048);
+f(8594126847, 2049);
+f(17175670785, 4095);
+f(17179865088, 4096);
+f(17184059391, 4097);
+f(34355535873, 8191);
+f(34359730176, 8192);
+f(34363924479, 8193);
+f(68715266049, 16383);
+f(68719460352, 16384);
+f(68723654655, 16385);
+f(137434726401, 32767);
+f(137438920704, 32768);
+f(137443115007, 32769);
+f(274873647105, 65535);
+f(274877841408, 65536);
+f(274882035711, 65537);
+f(549751488513, 131071);
+f(549755682816, 131072);
+f(549759877119, 131073);
+f(1099507171329, 262143);
+f(1099511365632, 262144);
+f(1099515559935, 262145);
+f(2199018536961, 524287);
+f(2199022731264, 524288);
+f(2199026925567, 524289);
+f(4398041268225, 1048575);
+f(4398045462528, 1048576);
+f(4398049656831, 1048577);
+f(8796086730753, 2097151);
+f(8796090925056, 2097152);
+f(8796095119359, 2097153);
+f(17592177655809, 4194303);
+x = 4194304;
+f(0, 0);
+f(4194304, 1);
+f(8388608, 2);
+f(12582912, 3);
+f(16777216, 4);
+f(20971520, 5);
+f(29360128, 7);
+f(33554432, 8);
+f(37748736, 9);
+f(62914560, 15);
+f(67108864, 16);
+f(71303168, 17);
+f(130023424, 31);
+f(134217728, 32);
+f(138412032, 33);
+f(264241152, 63);
+f(268435456, 64);
+f(272629760, 65);
+f(532676608, 127);
+f(536870912, 128);
+f(541065216, 129);
+f(1069547520, 255);
+f(1073741824, 256);
+f(1077936128, 257);
+f(2143289344, 511);
+f(2147483648, 512);
+f(2151677952, 513);
+f(4290772992, 1023);
+f(4294967296, 1024);
+f(4299161600, 1025);
+f(8585740288, 2047);
+f(8589934592, 2048);
+f(8594128896, 2049);
+f(17175674880, 4095);
+f(17179869184, 4096);
+f(17184063488, 4097);
+f(34355544064, 8191);
+f(34359738368, 8192);
+f(34363932672, 8193);
+f(68715282432, 16383);
+f(68719476736, 16384);
+f(68723671040, 16385);
+f(137434759168, 32767);
+f(137438953472, 32768);
+f(137443147776, 32769);
+f(274873712640, 65535);
+f(274877906944, 65536);
+f(274882101248, 65537);
+f(549751619584, 131071);
+f(549755813888, 131072);
+f(549760008192, 131073);
+f(1099507433472, 262143);
+f(1099511627776, 262144);
+f(1099515822080, 262145);
+f(2199019061248, 524287);
+f(2199023255552, 524288);
+f(2199027449856, 524289);
+f(4398042316800, 1048575);
+f(4398046511104, 1048576);
+f(4398050705408, 1048577);
+f(8796088827904, 2097151);
+f(8796093022208, 2097152);
+f(8796097216512, 2097153);
+f(17592181850112, 4194303);
+f(17592186044416, 4194304);
+x = 4194305;
+f(0, 0);
+f(4194305, 1);
+f(8388610, 2);
+f(12582915, 3);
+f(16777220, 4);
+f(20971525, 5);
+f(29360135, 7);
+f(33554440, 8);
+f(37748745, 9);
+f(62914575, 15);
+f(67108880, 16);
+f(71303185, 17);
+f(130023455, 31);
+f(134217760, 32);
+f(138412065, 33);
+f(264241215, 63);
+f(268435520, 64);
+f(272629825, 65);
+f(532676735, 127);
+f(536871040, 128);
+f(541065345, 129);
+f(1069547775, 255);
+f(1073742080, 256);
+f(1077936385, 257);
+f(2143289855, 511);
+f(2147484160, 512);
+f(2151678465, 513);
+f(4290774015, 1023);
+f(4294968320, 1024);
+f(4299162625, 1025);
+f(8585742335, 2047);
+f(8589936640, 2048);
+f(8594130945, 2049);
+f(17175678975, 4095);
+f(17179873280, 4096);
+f(17184067585, 4097);
+f(34355552255, 8191);
+f(34359746560, 8192);
+f(34363940865, 8193);
+f(68715298815, 16383);
+f(68719493120, 16384);
+f(68723687425, 16385);
+f(137434791935, 32767);
+f(137438986240, 32768);
+f(137443180545, 32769);
+f(274873778175, 65535);
+f(274877972480, 65536);
+f(274882166785, 65537);
+f(549751750655, 131071);
+f(549755944960, 131072);
+f(549760139265, 131073);
+f(1099507695615, 262143);
+f(1099511889920, 262144);
+f(1099516084225, 262145);
+f(2199019585535, 524287);
+f(2199023779840, 524288);
+f(2199027974145, 524289);
+f(4398043365375, 1048575);
+f(4398047559680, 1048576);
+f(4398051753985, 1048577);
+f(8796090925055, 2097151);
+f(8796095119360, 2097152);
+f(8796099313665, 2097153);
+f(17592186044415, 4194303);
+f(17592190238720, 4194304);
+f(17592194433025, 4194305);
diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part6.js b/deps/v8/test/mjsunit/mul-exhaustive-part6.js
new file mode 100644
index 000000000..91cb798a7
--- /dev/null
+++ b/deps/v8/test/mjsunit/mul-exhaustive-part6.js
@@ -0,0 +1,554 @@
+// Copyright 2008 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.
+
+var x;
+
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
+}
+
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 8388607;
+f(0, 0);
+f(8388607, 1);
+f(16777214, 2);
+f(25165821, 3);
+f(33554428, 4);
+f(41943035, 5);
+f(58720249, 7);
+f(67108856, 8);
+f(75497463, 9);
+f(125829105, 15);
+f(134217712, 16);
+f(142606319, 17);
+f(260046817, 31);
+f(268435424, 32);
+f(276824031, 33);
+f(528482241, 63);
+f(536870848, 64);
+f(545259455, 65);
+f(1065353089, 127);
+f(1073741696, 128);
+f(1082130303, 129);
+f(2139094785, 255);
+f(2147483392, 256);
+f(2155871999, 257);
+f(4286578177, 511);
+f(4294966784, 512);
+f(4303355391, 513);
+f(8581544961, 1023);
+f(8589933568, 1024);
+f(8598322175, 1025);
+f(17171478529, 2047);
+f(17179867136, 2048);
+f(17188255743, 2049);
+f(34351345665, 4095);
+f(34359734272, 4096);
+f(34368122879, 4097);
+f(68711079937, 8191);
+f(68719468544, 8192);
+f(68727857151, 8193);
+f(137430548481, 16383);
+f(137438937088, 16384);
+f(137447325695, 16385);
+f(274869485569, 32767);
+f(274877874176, 32768);
+f(274886262783, 32769);
+f(549747359745, 65535);
+f(549755748352, 65536);
+f(549764136959, 65537);
+f(1099503108097, 131071);
+f(1099511496704, 131072);
+f(1099519885311, 131073);
+f(2199014604801, 262143);
+f(2199022993408, 262144);
+f(2199031382015, 262145);
+f(4398037598209, 524287);
+f(4398045986816, 524288);
+f(4398054375423, 524289);
+f(8796083585025, 1048575);
+f(8796091973632, 1048576);
+f(8796100362239, 1048577);
+f(17592175558657, 2097151);
+f(17592183947264, 2097152);
+f(17592192335871, 2097153);
+f(35184359505921, 4194303);
+f(35184367894528, 4194304);
+f(35184376283135, 4194305);
+f(70368727400449, 8388607);
+x = 8388608;
+f(0, 0);
+f(8388608, 1);
+f(16777216, 2);
+f(25165824, 3);
+f(33554432, 4);
+f(41943040, 5);
+f(58720256, 7);
+f(67108864, 8);
+f(75497472, 9);
+f(125829120, 15);
+f(134217728, 16);
+f(142606336, 17);
+f(260046848, 31);
+f(268435456, 32);
+f(276824064, 33);
+f(528482304, 63);
+f(536870912, 64);
+f(545259520, 65);
+f(1065353216, 127);
+f(1073741824, 128);
+f(1082130432, 129);
+f(2139095040, 255);
+f(2147483648, 256);
+f(2155872256, 257);
+f(4286578688, 511);
+f(4294967296, 512);
+f(4303355904, 513);
+f(8581545984, 1023);
+f(8589934592, 1024);
+f(8598323200, 1025);
+f(17171480576, 2047);
+f(17179869184, 2048);
+f(17188257792, 2049);
+f(34351349760, 4095);
+f(34359738368, 4096);
+f(34368126976, 4097);
+f(68711088128, 8191);
+f(68719476736, 8192);
+f(68727865344, 8193);
+f(137430564864, 16383);
+f(137438953472, 16384);
+f(137447342080, 16385);
+f(274869518336, 32767);
+f(274877906944, 32768);
+f(274886295552, 32769);
+f(549747425280, 65535);
+f(549755813888, 65536);
+f(549764202496, 65537);
+f(1099503239168, 131071);
+f(1099511627776, 131072);
+f(1099520016384, 131073);
+f(2199014866944, 262143);
+f(2199023255552, 262144);
+f(2199031644160, 262145);
+f(4398038122496, 524287);
+f(4398046511104, 524288);
+f(4398054899712, 524289);
+f(8796084633600, 1048575);
+f(8796093022208, 1048576);
+f(8796101410816, 1048577);
+f(17592177655808, 2097151);
+f(17592186044416, 2097152);
+f(17592194433024, 2097153);
+f(35184363700224, 4194303);
+f(35184372088832, 4194304);
+f(35184380477440, 4194305);
+f(70368735789056, 8388607);
+f(70368744177664, 8388608);
+x = 8388609;
+f(0, 0);
+f(8388609, 1);
+f(16777218, 2);
+f(25165827, 3);
+f(33554436, 4);
+f(41943045, 5);
+f(58720263, 7);
+f(67108872, 8);
+f(75497481, 9);
+f(125829135, 15);
+f(134217744, 16);
+f(142606353, 17);
+f(260046879, 31);
+f(268435488, 32);
+f(276824097, 33);
+f(528482367, 63);
+f(536870976, 64);
+f(545259585, 65);
+f(1065353343, 127);
+f(1073741952, 128);
+f(1082130561, 129);
+f(2139095295, 255);
+f(2147483904, 256);
+f(2155872513, 257);
+f(4286579199, 511);
+f(4294967808, 512);
+f(4303356417, 513);
+f(8581547007, 1023);
+f(8589935616, 1024);
+f(8598324225, 1025);
+f(17171482623, 2047);
+f(17179871232, 2048);
+f(17188259841, 2049);
+f(34351353855, 4095);
+f(34359742464, 4096);
+f(34368131073, 4097);
+f(68711096319, 8191);
+f(68719484928, 8192);
+f(68727873537, 8193);
+f(137430581247, 16383);
+f(137438969856, 16384);
+f(137447358465, 16385);
+f(274869551103, 32767);
+f(274877939712, 32768);
+f(274886328321, 32769);
+f(549747490815, 65535);
+f(549755879424, 65536);
+f(549764268033, 65537);
+f(1099503370239, 131071);
+f(1099511758848, 131072);
+f(1099520147457, 131073);
+f(2199015129087, 262143);
+f(2199023517696, 262144);
+f(2199031906305, 262145);
+f(4398038646783, 524287);
+f(4398047035392, 524288);
+f(4398055424001, 524289);
+f(8796085682175, 1048575);
+f(8796094070784, 1048576);
+f(8796102459393, 1048577);
+f(17592179752959, 2097151);
+f(17592188141568, 2097152);
+f(17592196530177, 2097153);
+f(35184367894527, 4194303);
+f(35184376283136, 4194304);
+f(35184384671745, 4194305);
+f(70368744177663, 8388607);
+f(70368752566272, 8388608);
+f(70368760954881, 8388609);
+x = 16777215;
+f(0, 0);
+f(16777215, 1);
+f(33554430, 2);
+f(50331645, 3);
+f(67108860, 4);
+f(83886075, 5);
+f(117440505, 7);
+f(134217720, 8);
+f(150994935, 9);
+f(251658225, 15);
+f(268435440, 16);
+f(285212655, 17);
+f(520093665, 31);
+f(536870880, 32);
+f(553648095, 33);
+f(1056964545, 63);
+f(1073741760, 64);
+f(1090518975, 65);
+f(2130706305, 127);
+f(2147483520, 128);
+f(2164260735, 129);
+f(4278189825, 255);
+f(4294967040, 256);
+f(4311744255, 257);
+f(8573156865, 511);
+f(8589934080, 512);
+f(8606711295, 513);
+f(17163090945, 1023);
+f(17179868160, 1024);
+f(17196645375, 1025);
+f(34342959105, 2047);
+f(34359736320, 2048);
+f(34376513535, 2049);
+f(68702695425, 4095);
+f(68719472640, 4096);
+f(68736249855, 4097);
+f(137422168065, 8191);
+f(137438945280, 8192);
+f(137455722495, 8193);
+f(274861113345, 16383);
+f(274877890560, 16384);
+f(274894667775, 16385);
+f(549739003905, 32767);
+f(549755781120, 32768);
+f(549772558335, 32769);
+f(1099494785025, 65535);
+f(1099511562240, 65536);
+f(1099528339455, 65537);
+f(2199006347265, 131071);
+f(2199023124480, 131072);
+f(2199039901695, 131073);
+f(4398029471745, 262143);
+f(4398046248960, 262144);
+f(4398063026175, 262145);
+f(8796075720705, 524287);
+f(8796092497920, 524288);
+f(8796109275135, 524289);
+f(17592168218625, 1048575);
+f(17592184995840, 1048576);
+f(17592201773055, 1048577);
+f(35184353214465, 2097151);
+f(35184369991680, 2097152);
+f(35184386768895, 2097153);
+f(70368723206145, 4194303);
+f(70368739983360, 4194304);
+f(70368756760575, 4194305);
+f(140737463189505, 8388607);
+f(140737479966720, 8388608);
+f(140737496743935, 8388609);
+f(281474943156225, 16777215);
+x = 16777216;
+f(0, 0);
+f(16777216, 1);
+f(33554432, 2);
+f(50331648, 3);
+f(67108864, 4);
+f(83886080, 5);
+f(117440512, 7);
+f(134217728, 8);
+f(150994944, 9);
+f(251658240, 15);
+f(268435456, 16);
+f(285212672, 17);
+f(520093696, 31);
+f(536870912, 32);
+f(553648128, 33);
+f(1056964608, 63);
+f(1073741824, 64);
+f(1090519040, 65);
+f(2130706432, 127);
+f(2147483648, 128);
+f(2164260864, 129);
+f(4278190080, 255);
+f(4294967296, 256);
+f(4311744512, 257);
+f(8573157376, 511);
+f(8589934592, 512);
+f(8606711808, 513);
+f(17163091968, 1023);
+f(17179869184, 1024);
+f(17196646400, 1025);
+f(34342961152, 2047);
+f(34359738368, 2048);
+f(34376515584, 2049);
+f(68702699520, 4095);
+f(68719476736, 4096);
+f(68736253952, 4097);
+f(137422176256, 8191);
+f(137438953472, 8192);
+f(137455730688, 8193);
+f(274861129728, 16383);
+f(274877906944, 16384);
+f(274894684160, 16385);
+f(549739036672, 32767);
+f(549755813888, 32768);
+f(549772591104, 32769);
+f(1099494850560, 65535);
+f(1099511627776, 65536);
+f(1099528404992, 65537);
+f(2199006478336, 131071);
+f(2199023255552, 131072);
+f(2199040032768, 131073);
+f(4398029733888, 262143);
+f(4398046511104, 262144);
+f(4398063288320, 262145);
+f(8796076244992, 524287);
+f(8796093022208, 524288);
+f(8796109799424, 524289);
+f(17592169267200, 1048575);
+f(17592186044416, 1048576);
+f(17592202821632, 1048577);
+f(35184355311616, 2097151);
+f(35184372088832, 2097152);
+f(35184388866048, 2097153);
+f(70368727400448, 4194303);
+f(70368744177664, 4194304);
+f(70368760954880, 4194305);
+f(140737471578112, 8388607);
+f(140737488355328, 8388608);
+f(140737505132544, 8388609);
+f(281474959933440, 16777215);
+f(281474976710656, 16777216);
+x = 16777217;
+f(0, 0);
+f(16777217, 1);
+f(33554434, 2);
+f(50331651, 3);
+f(67108868, 4);
+f(83886085, 5);
+f(117440519, 7);
+f(134217736, 8);
+f(150994953, 9);
+f(251658255, 15);
+f(268435472, 16);
+f(285212689, 17);
+f(520093727, 31);
+f(536870944, 32);
+f(553648161, 33);
+f(1056964671, 63);
+f(1073741888, 64);
+f(1090519105, 65);
+f(2130706559, 127);
+f(2147483776, 128);
+f(2164260993, 129);
+f(4278190335, 255);
+f(4294967552, 256);
+f(4311744769, 257);
+f(8573157887, 511);
+f(8589935104, 512);
+f(8606712321, 513);
+f(17163092991, 1023);
+f(17179870208, 1024);
+f(17196647425, 1025);
+f(34342963199, 2047);
+f(34359740416, 2048);
+f(34376517633, 2049);
+f(68702703615, 4095);
+f(68719480832, 4096);
+f(68736258049, 4097);
+f(137422184447, 8191);
+f(137438961664, 8192);
+f(137455738881, 8193);
+f(274861146111, 16383);
+f(274877923328, 16384);
+f(274894700545, 16385);
+f(549739069439, 32767);
+f(549755846656, 32768);
+f(549772623873, 32769);
+f(1099494916095, 65535);
+f(1099511693312, 65536);
+f(1099528470529, 65537);
+f(2199006609407, 131071);
+f(2199023386624, 131072);
+f(2199040163841, 131073);
+f(4398029996031, 262143);
+f(4398046773248, 262144);
+f(4398063550465, 262145);
+f(8796076769279, 524287);
+f(8796093546496, 524288);
+f(8796110323713, 524289);
+f(17592170315775, 1048575);
+f(17592187092992, 1048576);
+f(17592203870209, 1048577);
+f(35184357408767, 2097151);
+f(35184374185984, 2097152);
+f(35184390963201, 2097153);
+f(70368731594751, 4194303);
+f(70368748371968, 4194304);
+f(70368765149185, 4194305);
+f(140737479966719, 8388607);
+f(140737496743936, 8388608);
+f(140737513521153, 8388609);
+f(281474976710655, 16777215);
+f(281474993487872, 16777216);
+f(281475010265089, 16777217);
+x = 33554431;
+f(0, 0);
+f(33554431, 1);
+f(67108862, 2);
+f(100663293, 3);
+f(134217724, 4);
+f(167772155, 5);
+f(234881017, 7);
+f(268435448, 8);
+f(301989879, 9);
+f(503316465, 15);
+f(536870896, 16);
+f(570425327, 17);
+f(1040187361, 31);
+f(1073741792, 32);
+f(1107296223, 33);
+f(2113929153, 63);
+f(2147483584, 64);
+f(2181038015, 65);
+f(4261412737, 127);
+f(4294967168, 128);
+f(4328521599, 129);
+f(8556379905, 255);
+f(8589934336, 256);
+f(8623488767, 257);
+f(17146314241, 511);
+f(17179868672, 512);
+f(17213423103, 513);
+f(34326182913, 1023);
+f(34359737344, 1024);
+f(34393291775, 1025);
+f(68685920257, 2047);
+f(68719474688, 2048);
+f(68753029119, 2049);
+f(137405394945, 4095);
+f(137438949376, 4096);
+f(137472503807, 4097);
+f(274844344321, 8191);
+f(274877898752, 8192);
+f(274911453183, 8193);
+f(549722243073, 16383);
+f(549755797504, 16384);
+f(549789351935, 16385);
+f(1099478040577, 32767);
+f(1099511595008, 32768);
+f(1099545149439, 32769);
+f(2198989635585, 65535);
+f(2199023190016, 65536);
+f(2199056744447, 65537);
+f(4398012825601, 131071);
+f(4398046380032, 131072);
+f(4398079934463, 131073);
+f(8796059205633, 262143);
+f(8796092760064, 262144);
+f(8796126314495, 262145);
+f(17592151965697, 524287);
+f(17592185520128, 524288);
+f(17592219074559, 524289);
+f(35184337485825, 1048575);
+f(35184371040256, 1048576);
+f(35184404594687, 1048577);
+f(70368708526081, 2097151);
+f(70368742080512, 2097152);
+f(70368775634943, 2097153);
+f(140737450606593, 4194303);
+f(140737484161024, 4194304);
+f(140737517715455, 4194305);
+f(281474934767617, 8388607);
+f(281474968322048, 8388608);
+f(281475001876479, 8388609);
+f(562949903089665, 16777215);
+f(562949936644096, 16777216);
+f(562949970198527, 16777217);
+f(1125899839733761, 33554431); \ No newline at end of file
diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part7.js b/deps/v8/test/mjsunit/mul-exhaustive-part7.js
new file mode 100644
index 000000000..d517225e7
--- /dev/null
+++ b/deps/v8/test/mjsunit/mul-exhaustive-part7.js
@@ -0,0 +1,497 @@
+// Copyright 2008 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.
+
+var x;
+
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
+}
+
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 33554432;
+f(0, 0);
+f(33554432, 1);
+f(67108864, 2);
+f(100663296, 3);
+f(134217728, 4);
+f(167772160, 5);
+f(234881024, 7);
+f(268435456, 8);
+f(301989888, 9);
+f(503316480, 15);
+f(536870912, 16);
+f(570425344, 17);
+f(1040187392, 31);
+f(1073741824, 32);
+f(1107296256, 33);
+f(2113929216, 63);
+f(2147483648, 64);
+f(2181038080, 65);
+f(4261412864, 127);
+f(4294967296, 128);
+f(4328521728, 129);
+f(8556380160, 255);
+f(8589934592, 256);
+f(8623489024, 257);
+f(17146314752, 511);
+f(17179869184, 512);
+f(17213423616, 513);
+f(34326183936, 1023);
+f(34359738368, 1024);
+f(34393292800, 1025);
+f(68685922304, 2047);
+f(68719476736, 2048);
+f(68753031168, 2049);
+f(137405399040, 4095);
+f(137438953472, 4096);
+f(137472507904, 4097);
+f(274844352512, 8191);
+f(274877906944, 8192);
+f(274911461376, 8193);
+f(549722259456, 16383);
+f(549755813888, 16384);
+f(549789368320, 16385);
+f(1099478073344, 32767);
+f(1099511627776, 32768);
+f(1099545182208, 32769);
+f(2198989701120, 65535);
+f(2199023255552, 65536);
+f(2199056809984, 65537);
+f(4398012956672, 131071);
+f(4398046511104, 131072);
+f(4398080065536, 131073);
+f(8796059467776, 262143);
+f(8796093022208, 262144);
+f(8796126576640, 262145);
+f(17592152489984, 524287);
+f(17592186044416, 524288);
+f(17592219598848, 524289);
+f(35184338534400, 1048575);
+f(35184372088832, 1048576);
+f(35184405643264, 1048577);
+f(70368710623232, 2097151);
+f(70368744177664, 2097152);
+f(70368777732096, 2097153);
+f(140737454800896, 4194303);
+f(140737488355328, 4194304);
+f(140737521909760, 4194305);
+f(281474943156224, 8388607);
+f(281474976710656, 8388608);
+f(281475010265088, 8388609);
+f(562949919866880, 16777215);
+f(562949953421312, 16777216);
+f(562949986975744, 16777217);
+f(1125899873288192, 33554431);
+f(1125899906842624, 33554432);
+x = 33554433;
+f(0, 0);
+f(33554433, 1);
+f(67108866, 2);
+f(100663299, 3);
+f(134217732, 4);
+f(167772165, 5);
+f(234881031, 7);
+f(268435464, 8);
+f(301989897, 9);
+f(503316495, 15);
+f(536870928, 16);
+f(570425361, 17);
+f(1040187423, 31);
+f(1073741856, 32);
+f(1107296289, 33);
+f(2113929279, 63);
+f(2147483712, 64);
+f(2181038145, 65);
+f(4261412991, 127);
+f(4294967424, 128);
+f(4328521857, 129);
+f(8556380415, 255);
+f(8589934848, 256);
+f(8623489281, 257);
+f(17146315263, 511);
+f(17179869696, 512);
+f(17213424129, 513);
+f(34326184959, 1023);
+f(34359739392, 1024);
+f(34393293825, 1025);
+f(68685924351, 2047);
+f(68719478784, 2048);
+f(68753033217, 2049);
+f(137405403135, 4095);
+f(137438957568, 4096);
+f(137472512001, 4097);
+f(274844360703, 8191);
+f(274877915136, 8192);
+f(274911469569, 8193);
+f(549722275839, 16383);
+f(549755830272, 16384);
+f(549789384705, 16385);
+f(1099478106111, 32767);
+f(1099511660544, 32768);
+f(1099545214977, 32769);
+f(2198989766655, 65535);
+f(2199023321088, 65536);
+f(2199056875521, 65537);
+f(4398013087743, 131071);
+f(4398046642176, 131072);
+f(4398080196609, 131073);
+f(8796059729919, 262143);
+f(8796093284352, 262144);
+f(8796126838785, 262145);
+f(17592153014271, 524287);
+f(17592186568704, 524288);
+f(17592220123137, 524289);
+f(35184339582975, 1048575);
+f(35184373137408, 1048576);
+f(35184406691841, 1048577);
+f(70368712720383, 2097151);
+f(70368746274816, 2097152);
+f(70368779829249, 2097153);
+f(140737458995199, 4194303);
+f(140737492549632, 4194304);
+f(140737526104065, 4194305);
+f(281474951544831, 8388607);
+f(281474985099264, 8388608);
+f(281475018653697, 8388609);
+f(562949936644095, 16777215);
+f(562949970198528, 16777216);
+f(562950003752961, 16777217);
+f(1125899906842623, 33554431);
+f(1125899940397056, 33554432);
+f(1125899973951489, 33554433);
+x = 67108863;
+f(0, 0);
+f(67108863, 1);
+f(134217726, 2);
+f(201326589, 3);
+f(268435452, 4);
+f(335544315, 5);
+f(469762041, 7);
+f(536870904, 8);
+f(603979767, 9);
+f(1006632945, 15);
+f(1073741808, 16);
+f(1140850671, 17);
+f(2080374753, 31);
+f(2147483616, 32);
+f(2214592479, 33);
+f(4227858369, 63);
+f(4294967232, 64);
+f(4362076095, 65);
+f(8522825601, 127);
+f(8589934464, 128);
+f(8657043327, 129);
+f(17112760065, 255);
+f(17179868928, 256);
+f(17246977791, 257);
+f(34292628993, 511);
+f(34359737856, 512);
+f(34426846719, 513);
+f(68652366849, 1023);
+f(68719475712, 1024);
+f(68786584575, 1025);
+f(137371842561, 2047);
+f(137438951424, 2048);
+f(137506060287, 2049);
+f(274810793985, 4095);
+f(274877902848, 4096);
+f(274945011711, 4097);
+f(549688696833, 8191);
+f(549755805696, 8192);
+f(549822914559, 8193);
+f(1099444502529, 16383);
+f(1099511611392, 16384);
+f(1099578720255, 16385);
+f(2198956113921, 32767);
+f(2199023222784, 32768);
+f(2199090331647, 32769);
+f(4397979336705, 65535);
+f(4398046445568, 65536);
+f(4398113554431, 65537);
+f(8796025782273, 131071);
+f(8796092891136, 131072);
+f(8796159999999, 131073);
+f(17592118673409, 262143);
+f(17592185782272, 262144);
+f(17592252891135, 262145);
+f(35184304455681, 524287);
+f(35184371564544, 524288);
+f(35184438673407, 524289);
+f(70368676020225, 1048575);
+f(70368743129088, 1048576);
+f(70368810237951, 1048577);
+f(140737419149313, 2097151);
+f(140737486258176, 2097152);
+f(140737553367039, 2097153);
+f(281474905407489, 4194303);
+f(281474972516352, 4194304);
+f(281475039625215, 4194305);
+f(562949877923841, 8388607);
+f(562949945032704, 8388608);
+f(562950012141567, 8388609);
+f(1125899822956545, 16777215);
+f(1125899890065408, 16777216);
+f(1125899957174271, 16777217);
+x = 67108864;
+f(0, 0);
+f(67108864, 1);
+f(134217728, 2);
+f(201326592, 3);
+f(268435456, 4);
+f(335544320, 5);
+f(469762048, 7);
+f(536870912, 8);
+f(603979776, 9);
+f(1006632960, 15);
+f(1073741824, 16);
+f(1140850688, 17);
+f(2080374784, 31);
+f(2147483648, 32);
+f(2214592512, 33);
+f(4227858432, 63);
+f(4294967296, 64);
+f(4362076160, 65);
+f(8522825728, 127);
+f(8589934592, 128);
+f(8657043456, 129);
+f(17112760320, 255);
+f(17179869184, 256);
+f(17246978048, 257);
+f(34292629504, 511);
+f(34359738368, 512);
+f(34426847232, 513);
+f(68652367872, 1023);
+f(68719476736, 1024);
+f(68786585600, 1025);
+f(137371844608, 2047);
+f(137438953472, 2048);
+f(137506062336, 2049);
+f(274810798080, 4095);
+f(274877906944, 4096);
+f(274945015808, 4097);
+f(549688705024, 8191);
+f(549755813888, 8192);
+f(549822922752, 8193);
+f(1099444518912, 16383);
+f(1099511627776, 16384);
+f(1099578736640, 16385);
+f(2198956146688, 32767);
+f(2199023255552, 32768);
+f(2199090364416, 32769);
+f(4397979402240, 65535);
+f(4398046511104, 65536);
+f(4398113619968, 65537);
+f(8796025913344, 131071);
+f(8796093022208, 131072);
+f(8796160131072, 131073);
+f(17592118935552, 262143);
+f(17592186044416, 262144);
+f(17592253153280, 262145);
+f(35184304979968, 524287);
+f(35184372088832, 524288);
+f(35184439197696, 524289);
+f(70368677068800, 1048575);
+f(70368744177664, 1048576);
+f(70368811286528, 1048577);
+f(140737421246464, 2097151);
+f(140737488355328, 2097152);
+f(140737555464192, 2097153);
+f(281474909601792, 4194303);
+f(281474976710656, 4194304);
+f(281475043819520, 4194305);
+f(562949886312448, 8388607);
+f(562949953421312, 8388608);
+f(562950020530176, 8388609);
+f(1125899839733760, 16777215);
+f(1125899906842624, 16777216);
+f(1125899973951488, 16777217);
+x = 67108865;
+f(0, 0);
+f(67108865, 1);
+f(134217730, 2);
+f(201326595, 3);
+f(268435460, 4);
+f(335544325, 5);
+f(469762055, 7);
+f(536870920, 8);
+f(603979785, 9);
+f(1006632975, 15);
+f(1073741840, 16);
+f(1140850705, 17);
+f(2080374815, 31);
+f(2147483680, 32);
+f(2214592545, 33);
+f(4227858495, 63);
+f(4294967360, 64);
+f(4362076225, 65);
+f(8522825855, 127);
+f(8589934720, 128);
+f(8657043585, 129);
+f(17112760575, 255);
+f(17179869440, 256);
+f(17246978305, 257);
+f(34292630015, 511);
+f(34359738880, 512);
+f(34426847745, 513);
+f(68652368895, 1023);
+f(68719477760, 1024);
+f(68786586625, 1025);
+f(137371846655, 2047);
+f(137438955520, 2048);
+f(137506064385, 2049);
+f(274810802175, 4095);
+f(274877911040, 4096);
+f(274945019905, 4097);
+f(549688713215, 8191);
+f(549755822080, 8192);
+f(549822930945, 8193);
+f(1099444535295, 16383);
+f(1099511644160, 16384);
+f(1099578753025, 16385);
+f(2198956179455, 32767);
+f(2199023288320, 32768);
+f(2199090397185, 32769);
+f(4397979467775, 65535);
+f(4398046576640, 65536);
+f(4398113685505, 65537);
+f(8796026044415, 131071);
+f(8796093153280, 131072);
+f(8796160262145, 131073);
+f(17592119197695, 262143);
+f(17592186306560, 262144);
+f(17592253415425, 262145);
+f(35184305504255, 524287);
+f(35184372613120, 524288);
+f(35184439721985, 524289);
+f(70368678117375, 1048575);
+f(70368745226240, 1048576);
+f(70368812335105, 1048577);
+f(140737423343615, 2097151);
+f(140737490452480, 2097152);
+f(140737557561345, 2097153);
+f(281474913796095, 4194303);
+f(281474980904960, 4194304);
+f(281475048013825, 4194305);
+f(562949894701055, 8388607);
+f(562949961809920, 8388608);
+f(562950028918785, 8388609);
+f(1125899856510975, 16777215);
+f(1125899923619840, 16777216);
+f(1125899990728705, 16777217);
+x = 134217727;
+f(0, 0);
+f(134217727, 1);
+f(268435454, 2);
+f(402653181, 3);
+f(536870908, 4);
+f(671088635, 5);
+f(939524089, 7);
+f(1073741816, 8);
+f(1207959543, 9);
+f(2013265905, 15);
+f(2147483632, 16);
+f(2281701359, 17);
+f(4160749537, 31);
+f(4294967264, 32);
+f(4429184991, 33);
+f(8455716801, 63);
+f(8589934528, 64);
+f(8724152255, 65);
+f(17045651329, 127);
+f(17179869056, 128);
+f(17314086783, 129);
+f(34225520385, 255);
+f(34359738112, 256);
+f(34493955839, 257);
+f(68585258497, 511);
+f(68719476224, 512);
+f(68853693951, 513);
+f(137304734721, 1023);
+f(137438952448, 1024);
+f(137573170175, 1025);
+f(274743687169, 2047);
+f(274877904896, 2048);
+f(275012122623, 2049);
+f(549621592065, 4095);
+f(549755809792, 4096);
+f(549890027519, 4097);
+f(1099377401857, 8191);
+f(1099511619584, 8192);
+f(1099645837311, 8193);
+f(2198889021441, 16383);
+f(2199023239168, 16384);
+f(2199157456895, 16385);
+f(4397912260609, 32767);
+f(4398046478336, 32768);
+f(4398180696063, 32769);
+f(8795958738945, 65535);
+f(8796092956672, 65536);
+f(8796227174399, 65537);
+f(17592051695617, 131071);
+f(17592185913344, 131072);
+f(17592320131071, 131073);
+f(35184237608961, 262143);
+f(35184371826688, 262144);
+f(35184506044415, 262145);
+f(70368609435649, 524287);
+f(70368743653376, 524288);
+f(70368877871103, 524289);
+f(140737353089025, 1048575);
+f(140737487306752, 1048576);
+f(140737621524479, 1048577);
+f(281474840395777, 2097151);
+f(281474974613504, 2097152);
+f(281475108831231, 2097153);
+f(562949815009281, 4194303);
+f(562949949227008, 4194304);
+f(562950083444735, 4194305);
+f(1125899764236289, 8388607);
+f(1125899898454016, 8388608);
+f(1125900032671743, 8388609);
diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part8.js b/deps/v8/test/mjsunit/mul-exhaustive-part8.js
new file mode 100644
index 000000000..7e5f2851c
--- /dev/null
+++ b/deps/v8/test/mjsunit/mul-exhaustive-part8.js
@@ -0,0 +1,526 @@
+// Copyright 2008 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.
+
+var x;
+
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
+}
+
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 134217728;
+f(0, 0);
+f(134217728, 1);
+f(268435456, 2);
+f(402653184, 3);
+f(536870912, 4);
+f(671088640, 5);
+f(939524096, 7);
+f(1073741824, 8);
+f(1207959552, 9);
+f(2013265920, 15);
+f(2147483648, 16);
+f(2281701376, 17);
+f(4160749568, 31);
+f(4294967296, 32);
+f(4429185024, 33);
+f(8455716864, 63);
+f(8589934592, 64);
+f(8724152320, 65);
+f(17045651456, 127);
+f(17179869184, 128);
+f(17314086912, 129);
+f(34225520640, 255);
+f(34359738368, 256);
+f(34493956096, 257);
+f(68585259008, 511);
+f(68719476736, 512);
+f(68853694464, 513);
+f(137304735744, 1023);
+f(137438953472, 1024);
+f(137573171200, 1025);
+f(274743689216, 2047);
+f(274877906944, 2048);
+f(275012124672, 2049);
+f(549621596160, 4095);
+f(549755813888, 4096);
+f(549890031616, 4097);
+f(1099377410048, 8191);
+f(1099511627776, 8192);
+f(1099645845504, 8193);
+f(2198889037824, 16383);
+f(2199023255552, 16384);
+f(2199157473280, 16385);
+f(4397912293376, 32767);
+f(4398046511104, 32768);
+f(4398180728832, 32769);
+f(8795958804480, 65535);
+f(8796093022208, 65536);
+f(8796227239936, 65537);
+f(17592051826688, 131071);
+f(17592186044416, 131072);
+f(17592320262144, 131073);
+f(35184237871104, 262143);
+f(35184372088832, 262144);
+f(35184506306560, 262145);
+f(70368609959936, 524287);
+f(70368744177664, 524288);
+f(70368878395392, 524289);
+f(140737354137600, 1048575);
+f(140737488355328, 1048576);
+f(140737622573056, 1048577);
+f(281474842492928, 2097151);
+f(281474976710656, 2097152);
+f(281475110928384, 2097153);
+f(562949819203584, 4194303);
+f(562949953421312, 4194304);
+f(562950087639040, 4194305);
+f(1125899772624896, 8388607);
+f(1125899906842624, 8388608);
+f(1125900041060352, 8388609);
+x = 134217729;
+f(0, 0);
+f(134217729, 1);
+f(268435458, 2);
+f(402653187, 3);
+f(536870916, 4);
+f(671088645, 5);
+f(939524103, 7);
+f(1073741832, 8);
+f(1207959561, 9);
+f(2013265935, 15);
+f(2147483664, 16);
+f(2281701393, 17);
+f(4160749599, 31);
+f(4294967328, 32);
+f(4429185057, 33);
+f(8455716927, 63);
+f(8589934656, 64);
+f(8724152385, 65);
+f(17045651583, 127);
+f(17179869312, 128);
+f(17314087041, 129);
+f(34225520895, 255);
+f(34359738624, 256);
+f(34493956353, 257);
+f(68585259519, 511);
+f(68719477248, 512);
+f(68853694977, 513);
+f(137304736767, 1023);
+f(137438954496, 1024);
+f(137573172225, 1025);
+f(274743691263, 2047);
+f(274877908992, 2048);
+f(275012126721, 2049);
+f(549621600255, 4095);
+f(549755817984, 4096);
+f(549890035713, 4097);
+f(1099377418239, 8191);
+f(1099511635968, 8192);
+f(1099645853697, 8193);
+f(2198889054207, 16383);
+f(2199023271936, 16384);
+f(2199157489665, 16385);
+f(4397912326143, 32767);
+f(4398046543872, 32768);
+f(4398180761601, 32769);
+f(8795958870015, 65535);
+f(8796093087744, 65536);
+f(8796227305473, 65537);
+f(17592051957759, 131071);
+f(17592186175488, 131072);
+f(17592320393217, 131073);
+f(35184238133247, 262143);
+f(35184372350976, 262144);
+f(35184506568705, 262145);
+f(70368610484223, 524287);
+f(70368744701952, 524288);
+f(70368878919681, 524289);
+f(140737355186175, 1048575);
+f(140737489403904, 1048576);
+f(140737623621633, 1048577);
+f(281474844590079, 2097151);
+f(281474978807808, 2097152);
+f(281475113025537, 2097153);
+f(562949823397887, 4194303);
+f(562949957615616, 4194304);
+f(562950091833345, 4194305);
+f(1125899781013503, 8388607);
+f(1125899915231232, 8388608);
+f(1125900049448961, 8388609);
+x = 268435455;
+f(0, 0);
+f(268435455, 1);
+f(536870910, 2);
+f(805306365, 3);
+f(1073741820, 4);
+f(1342177275, 5);
+f(1879048185, 7);
+f(2147483640, 8);
+f(2415919095, 9);
+f(4026531825, 15);
+f(4294967280, 16);
+f(4563402735, 17);
+f(8321499105, 31);
+f(8589934560, 32);
+f(8858370015, 33);
+f(16911433665, 63);
+f(17179869120, 64);
+f(17448304575, 65);
+f(34091302785, 127);
+f(34359738240, 128);
+f(34628173695, 129);
+f(68451041025, 255);
+f(68719476480, 256);
+f(68987911935, 257);
+f(137170517505, 511);
+f(137438952960, 512);
+f(137707388415, 513);
+f(274609470465, 1023);
+f(274877905920, 1024);
+f(275146341375, 1025);
+f(549487376385, 2047);
+f(549755811840, 2048);
+f(550024247295, 2049);
+f(1099243188225, 4095);
+f(1099511623680, 4096);
+f(1099780059135, 4097);
+f(2198754811905, 8191);
+f(2199023247360, 8192);
+f(2199291682815, 8193);
+f(4397778059265, 16383);
+f(4398046494720, 16384);
+f(4398314930175, 16385);
+f(8795824553985, 32767);
+f(8796092989440, 32768);
+f(8796361424895, 32769);
+f(17591917543425, 65535);
+f(17592185978880, 65536);
+f(17592454414335, 65537);
+f(35184103522305, 131071);
+f(35184371957760, 131072);
+f(35184640393215, 131073);
+f(70368475480065, 262143);
+f(70368743915520, 262144);
+f(70369012350975, 262145);
+f(140737219395585, 524287);
+f(140737487831040, 524288);
+f(140737756266495, 524289);
+f(281474707226625, 1048575);
+f(281474975662080, 1048576);
+f(281475244097535, 1048577);
+f(562949682888705, 2097151);
+f(562949951324160, 2097152);
+f(562950219759615, 2097153);
+f(1125899634212865, 4194303);
+f(1125899902648320, 4194304);
+f(1125900171083775, 4194305);
+x = 268435456;
+f(0, 0);
+f(268435456, 1);
+f(536870912, 2);
+f(805306368, 3);
+f(1073741824, 4);
+f(1342177280, 5);
+f(1879048192, 7);
+f(2147483648, 8);
+f(2415919104, 9);
+f(4026531840, 15);
+f(4294967296, 16);
+f(4563402752, 17);
+f(8321499136, 31);
+f(8589934592, 32);
+f(8858370048, 33);
+f(16911433728, 63);
+f(17179869184, 64);
+f(17448304640, 65);
+f(34091302912, 127);
+f(34359738368, 128);
+f(34628173824, 129);
+f(68451041280, 255);
+f(68719476736, 256);
+f(68987912192, 257);
+f(137170518016, 511);
+f(137438953472, 512);
+f(137707388928, 513);
+f(274609471488, 1023);
+f(274877906944, 1024);
+f(275146342400, 1025);
+f(549487378432, 2047);
+f(549755813888, 2048);
+f(550024249344, 2049);
+f(1099243192320, 4095);
+f(1099511627776, 4096);
+f(1099780063232, 4097);
+f(2198754820096, 8191);
+f(2199023255552, 8192);
+f(2199291691008, 8193);
+f(4397778075648, 16383);
+f(4398046511104, 16384);
+f(4398314946560, 16385);
+f(8795824586752, 32767);
+f(8796093022208, 32768);
+f(8796361457664, 32769);
+f(17591917608960, 65535);
+f(17592186044416, 65536);
+f(17592454479872, 65537);
+f(35184103653376, 131071);
+f(35184372088832, 131072);
+f(35184640524288, 131073);
+f(70368475742208, 262143);
+f(70368744177664, 262144);
+f(70369012613120, 262145);
+f(140737219919872, 524287);
+f(140737488355328, 524288);
+f(140737756790784, 524289);
+f(281474708275200, 1048575);
+f(281474976710656, 1048576);
+f(281475245146112, 1048577);
+f(562949684985856, 2097151);
+f(562949953421312, 2097152);
+f(562950221856768, 2097153);
+f(1125899638407168, 4194303);
+f(1125899906842624, 4194304);
+f(1125900175278080, 4194305);
+x = 268435457;
+f(0, 0);
+f(268435457, 1);
+f(536870914, 2);
+f(805306371, 3);
+f(1073741828, 4);
+f(1342177285, 5);
+f(1879048199, 7);
+f(2147483656, 8);
+f(2415919113, 9);
+f(4026531855, 15);
+f(4294967312, 16);
+f(4563402769, 17);
+f(8321499167, 31);
+f(8589934624, 32);
+f(8858370081, 33);
+f(16911433791, 63);
+f(17179869248, 64);
+f(17448304705, 65);
+f(34091303039, 127);
+f(34359738496, 128);
+f(34628173953, 129);
+f(68451041535, 255);
+f(68719476992, 256);
+f(68987912449, 257);
+f(137170518527, 511);
+f(137438953984, 512);
+f(137707389441, 513);
+f(274609472511, 1023);
+f(274877907968, 1024);
+f(275146343425, 1025);
+f(549487380479, 2047);
+f(549755815936, 2048);
+f(550024251393, 2049);
+f(1099243196415, 4095);
+f(1099511631872, 4096);
+f(1099780067329, 4097);
+f(2198754828287, 8191);
+f(2199023263744, 8192);
+f(2199291699201, 8193);
+f(4397778092031, 16383);
+f(4398046527488, 16384);
+f(4398314962945, 16385);
+f(8795824619519, 32767);
+f(8796093054976, 32768);
+f(8796361490433, 32769);
+f(17591917674495, 65535);
+f(17592186109952, 65536);
+f(17592454545409, 65537);
+f(35184103784447, 131071);
+f(35184372219904, 131072);
+f(35184640655361, 131073);
+f(70368476004351, 262143);
+f(70368744439808, 262144);
+f(70369012875265, 262145);
+f(140737220444159, 524287);
+f(140737488879616, 524288);
+f(140737757315073, 524289);
+f(281474709323775, 1048575);
+f(281474977759232, 1048576);
+f(281475246194689, 1048577);
+f(562949687083007, 2097151);
+f(562949955518464, 2097152);
+f(562950223953921, 2097153);
+f(1125899642601471, 4194303);
+f(1125899911036928, 4194304);
+f(1125900179472385, 4194305);
+x = 536870911;
+f(0, 0);
+f(536870911, 1);
+f(1073741822, 2);
+f(1610612733, 3);
+f(2147483644, 4);
+f(2684354555, 5);
+f(3758096377, 7);
+f(4294967288, 8);
+f(4831838199, 9);
+f(8053063665, 15);
+f(8589934576, 16);
+f(9126805487, 17);
+f(16642998241, 31);
+f(17179869152, 32);
+f(17716740063, 33);
+f(33822867393, 63);
+f(34359738304, 64);
+f(34896609215, 65);
+f(68182605697, 127);
+f(68719476608, 128);
+f(69256347519, 129);
+f(136902082305, 255);
+f(137438953216, 256);
+f(137975824127, 257);
+f(274341035521, 511);
+f(274877906432, 512);
+f(275414777343, 513);
+f(549218941953, 1023);
+f(549755812864, 1024);
+f(550292683775, 1025);
+f(1098974754817, 2047);
+f(1099511625728, 2048);
+f(1100048496639, 2049);
+f(2198486380545, 4095);
+f(2199023251456, 4096);
+f(2199560122367, 4097);
+f(4397509632001, 8191);
+f(4398046502912, 8192);
+f(4398583373823, 8193);
+f(8795556134913, 16383);
+f(8796093005824, 16384);
+f(8796629876735, 16385);
+f(17591649140737, 32767);
+f(17592186011648, 32768);
+f(17592722882559, 32769);
+f(35183835152385, 65535);
+f(35184372023296, 65536);
+f(35184908894207, 65537);
+f(70368207175681, 131071);
+f(70368744046592, 131072);
+f(70369280917503, 131073);
+f(140736951222273, 262143);
+f(140737488093184, 262144);
+f(140738024964095, 262145);
+f(281474439315457, 524287);
+f(281474976186368, 524288);
+f(281475513057279, 524289);
+f(562949415501825, 1048575);
+f(562949952372736, 1048576);
+f(562950489243647, 1048577);
+f(1125899367874561, 2097151);
+f(1125899904745472, 2097152);
+f(1125900441616383, 2097153);
+x = 536870912;
+f(0, 0);
+f(536870912, 1);
+f(1073741824, 2);
+f(1610612736, 3);
+f(2147483648, 4);
+f(2684354560, 5);
+f(3758096384, 7);
+f(4294967296, 8);
+f(4831838208, 9);
+f(8053063680, 15);
+f(8589934592, 16);
+f(9126805504, 17);
+f(16642998272, 31);
+f(17179869184, 32);
+f(17716740096, 33);
+f(33822867456, 63);
+f(34359738368, 64);
+f(34896609280, 65);
+f(68182605824, 127);
+f(68719476736, 128);
+f(69256347648, 129);
+f(136902082560, 255);
+f(137438953472, 256);
+f(137975824384, 257);
+f(274341036032, 511);
+f(274877906944, 512);
+f(275414777856, 513);
+f(549218942976, 1023);
+f(549755813888, 1024);
+f(550292684800, 1025);
+f(1098974756864, 2047);
+f(1099511627776, 2048);
+f(1100048498688, 2049);
+f(2198486384640, 4095);
+f(2199023255552, 4096);
+f(2199560126464, 4097);
+f(4397509640192, 8191);
+f(4398046511104, 8192);
+f(4398583382016, 8193);
+f(8795556151296, 16383);
+f(8796093022208, 16384);
+f(8796629893120, 16385);
+f(17591649173504, 32767);
+f(17592186044416, 32768);
+f(17592722915328, 32769);
+f(35183835217920, 65535);
+f(35184372088832, 65536);
+f(35184908959744, 65537);
+f(70368207306752, 131071);
+f(70368744177664, 131072);
+f(70369281048576, 131073);
+f(140736951484416, 262143);
+f(140737488355328, 262144);
+f(140738025226240, 262145);
+f(281474439839744, 524287);
+f(281474976710656, 524288);
+f(281475513581568, 524289);
+f(562949416550400, 1048575);
+f(562949953421312, 1048576);
+f(562950490292224, 1048577);
+f(1125899369971712, 2097151);
+f(1125899906842624, 2097152);
+f(1125900443713536, 2097153);
diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part9.js b/deps/v8/test/mjsunit/mul-exhaustive-part9.js
new file mode 100644
index 000000000..f329a5a14
--- /dev/null
+++ b/deps/v8/test/mjsunit/mul-exhaustive-part9.js
@@ -0,0 +1,533 @@
+// Copyright 2008 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.
+
+var x;
+
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
+}
+
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 536870913;
+f(0, 0);
+f(536870913, 1);
+f(1073741826, 2);
+f(1610612739, 3);
+f(2147483652, 4);
+f(2684354565, 5);
+f(3758096391, 7);
+f(4294967304, 8);
+f(4831838217, 9);
+f(8053063695, 15);
+f(8589934608, 16);
+f(9126805521, 17);
+f(16642998303, 31);
+f(17179869216, 32);
+f(17716740129, 33);
+f(33822867519, 63);
+f(34359738432, 64);
+f(34896609345, 65);
+f(68182605951, 127);
+f(68719476864, 128);
+f(69256347777, 129);
+f(136902082815, 255);
+f(137438953728, 256);
+f(137975824641, 257);
+f(274341036543, 511);
+f(274877907456, 512);
+f(275414778369, 513);
+f(549218943999, 1023);
+f(549755814912, 1024);
+f(550292685825, 1025);
+f(1098974758911, 2047);
+f(1099511629824, 2048);
+f(1100048500737, 2049);
+f(2198486388735, 4095);
+f(2199023259648, 4096);
+f(2199560130561, 4097);
+f(4397509648383, 8191);
+f(4398046519296, 8192);
+f(4398583390209, 8193);
+f(8795556167679, 16383);
+f(8796093038592, 16384);
+f(8796629909505, 16385);
+f(17591649206271, 32767);
+f(17592186077184, 32768);
+f(17592722948097, 32769);
+f(35183835283455, 65535);
+f(35184372154368, 65536);
+f(35184909025281, 65537);
+f(70368207437823, 131071);
+f(70368744308736, 131072);
+f(70369281179649, 131073);
+f(140736951746559, 262143);
+f(140737488617472, 262144);
+f(140738025488385, 262145);
+f(281474440364031, 524287);
+f(281474977234944, 524288);
+f(281475514105857, 524289);
+f(562949417598975, 1048575);
+f(562949954469888, 1048576);
+f(562950491340801, 1048577);
+f(1125899372068863, 2097151);
+f(1125899908939776, 2097152);
+f(1125900445810689, 2097153);
+x = 1073741823;
+f(0, 0);
+f(1073741823, 1);
+f(2147483646, 2);
+f(3221225469, 3);
+f(4294967292, 4);
+f(5368709115, 5);
+f(7516192761, 7);
+f(8589934584, 8);
+f(9663676407, 9);
+f(16106127345, 15);
+f(17179869168, 16);
+f(18253610991, 17);
+f(33285996513, 31);
+f(34359738336, 32);
+f(35433480159, 33);
+f(67645734849, 63);
+f(68719476672, 64);
+f(69793218495, 65);
+f(136365211521, 127);
+f(137438953344, 128);
+f(138512695167, 129);
+f(273804164865, 255);
+f(274877906688, 256);
+f(275951648511, 257);
+f(548682071553, 511);
+f(549755813376, 512);
+f(550829555199, 513);
+f(1098437884929, 1023);
+f(1099511626752, 1024);
+f(1100585368575, 1025);
+f(2197949511681, 2047);
+f(2199023253504, 2048);
+f(2200096995327, 2049);
+f(4396972765185, 4095);
+f(4398046507008, 4096);
+f(4399120248831, 4097);
+f(8795019272193, 8191);
+f(8796093014016, 8192);
+f(8797166755839, 8193);
+f(17591112286209, 16383);
+f(17592186028032, 16384);
+f(17593259769855, 16385);
+f(35183298314241, 32767);
+f(35184372056064, 32768);
+f(35185445797887, 32769);
+f(70367670370305, 65535);
+f(70368744112128, 65536);
+f(70369817853951, 65537);
+f(140736414482433, 131071);
+f(140737488224256, 131072);
+f(140738561966079, 131073);
+f(281473902706689, 262143);
+f(281474976448512, 262144);
+f(281476050190335, 262145);
+f(562948879155201, 524287);
+f(562949952897024, 524288);
+f(562951026638847, 524289);
+f(1125898832052225, 1048575);
+f(1125899905794048, 1048576);
+f(1125900979535871, 1048577);
+x = 1073741824;
+f(0, 0);
+f(1073741824, 1);
+f(2147483648, 2);
+f(3221225472, 3);
+f(4294967296, 4);
+f(5368709120, 5);
+f(7516192768, 7);
+f(8589934592, 8);
+f(9663676416, 9);
+f(16106127360, 15);
+f(17179869184, 16);
+f(18253611008, 17);
+f(33285996544, 31);
+f(34359738368, 32);
+f(35433480192, 33);
+f(67645734912, 63);
+f(68719476736, 64);
+f(69793218560, 65);
+f(136365211648, 127);
+f(137438953472, 128);
+f(138512695296, 129);
+f(273804165120, 255);
+f(274877906944, 256);
+f(275951648768, 257);
+f(548682072064, 511);
+f(549755813888, 512);
+f(550829555712, 513);
+f(1098437885952, 1023);
+f(1099511627776, 1024);
+f(1100585369600, 1025);
+f(2197949513728, 2047);
+f(2199023255552, 2048);
+f(2200096997376, 2049);
+f(4396972769280, 4095);
+f(4398046511104, 4096);
+f(4399120252928, 4097);
+f(8795019280384, 8191);
+f(8796093022208, 8192);
+f(8797166764032, 8193);
+f(17591112302592, 16383);
+f(17592186044416, 16384);
+f(17593259786240, 16385);
+f(35183298347008, 32767);
+f(35184372088832, 32768);
+f(35185445830656, 32769);
+f(70367670435840, 65535);
+f(70368744177664, 65536);
+f(70369817919488, 65537);
+f(140736414613504, 131071);
+f(140737488355328, 131072);
+f(140738562097152, 131073);
+f(281473902968832, 262143);
+f(281474976710656, 262144);
+f(281476050452480, 262145);
+f(562948879679488, 524287);
+f(562949953421312, 524288);
+f(562951027163136, 524289);
+f(1125898833100800, 1048575);
+f(1125899906842624, 1048576);
+f(1125900980584448, 1048577);
+x = 1073741825;
+f(0, 0);
+f(1073741825, 1);
+f(2147483650, 2);
+f(3221225475, 3);
+f(4294967300, 4);
+f(5368709125, 5);
+f(7516192775, 7);
+f(8589934600, 8);
+f(9663676425, 9);
+f(16106127375, 15);
+f(17179869200, 16);
+f(18253611025, 17);
+f(33285996575, 31);
+f(34359738400, 32);
+f(35433480225, 33);
+f(67645734975, 63);
+f(68719476800, 64);
+f(69793218625, 65);
+f(136365211775, 127);
+f(137438953600, 128);
+f(138512695425, 129);
+f(273804165375, 255);
+f(274877907200, 256);
+f(275951649025, 257);
+f(548682072575, 511);
+f(549755814400, 512);
+f(550829556225, 513);
+f(1098437886975, 1023);
+f(1099511628800, 1024);
+f(1100585370625, 1025);
+f(2197949515775, 2047);
+f(2199023257600, 2048);
+f(2200096999425, 2049);
+f(4396972773375, 4095);
+f(4398046515200, 4096);
+f(4399120257025, 4097);
+f(8795019288575, 8191);
+f(8796093030400, 8192);
+f(8797166772225, 8193);
+f(17591112318975, 16383);
+f(17592186060800, 16384);
+f(17593259802625, 16385);
+f(35183298379775, 32767);
+f(35184372121600, 32768);
+f(35185445863425, 32769);
+f(70367670501375, 65535);
+f(70368744243200, 65536);
+f(70369817985025, 65537);
+f(140736414744575, 131071);
+f(140737488486400, 131072);
+f(140738562228225, 131073);
+f(281473903230975, 262143);
+f(281474976972800, 262144);
+f(281476050714625, 262145);
+f(562948880203775, 524287);
+f(562949953945600, 524288);
+f(562951027687425, 524289);
+f(1125898834149375, 1048575);
+f(1125899907891200, 1048576);
+f(1125900981633025, 1048577);
+x = 2147483647;
+f(0, 0);
+f(2147483647, 1);
+f(4294967294, 2);
+f(6442450941, 3);
+f(8589934588, 4);
+f(10737418235, 5);
+f(15032385529, 7);
+f(17179869176, 8);
+f(19327352823, 9);
+f(32212254705, 15);
+f(34359738352, 16);
+f(36507221999, 17);
+f(66571993057, 31);
+f(68719476704, 32);
+f(70866960351, 33);
+f(135291469761, 63);
+f(137438953408, 64);
+f(139586437055, 65);
+f(272730423169, 127);
+f(274877906816, 128);
+f(277025390463, 129);
+f(547608329985, 255);
+f(549755813632, 256);
+f(551903297279, 257);
+f(1097364143617, 511);
+f(1099511627264, 512);
+f(1101659110911, 513);
+f(2196875770881, 1023);
+f(2199023254528, 1024);
+f(2201170738175, 1025);
+f(4395899025409, 2047);
+f(4398046509056, 2048);
+f(4400193992703, 2049);
+f(8793945534465, 4095);
+f(8796093018112, 4096);
+f(8798240501759, 4097);
+f(17590038552577, 8191);
+f(17592186036224, 8192);
+f(17594333519871, 8193);
+f(35182224588801, 16383);
+f(35184372072448, 16384);
+f(35186519556095, 16385);
+f(70366596661249, 32767);
+f(70368744144896, 32768);
+f(70370891628543, 32769);
+f(140735340806145, 65535);
+f(140737488289792, 65536);
+f(140739635773439, 65537);
+f(281472829095937, 131071);
+f(281474976579584, 131072);
+f(281477124063231, 131073);
+f(562947805675521, 262143);
+f(562949953159168, 262144);
+f(562952100642815, 262145);
+f(1125897758834689, 524287);
+f(1125899906318336, 524288);
+f(1125902053801983, 524289);
+x = 2147483648;
+f(0, 0);
+f(2147483648, 1);
+f(4294967296, 2);
+f(6442450944, 3);
+f(8589934592, 4);
+f(10737418240, 5);
+f(15032385536, 7);
+f(17179869184, 8);
+f(19327352832, 9);
+f(32212254720, 15);
+f(34359738368, 16);
+f(36507222016, 17);
+f(66571993088, 31);
+f(68719476736, 32);
+f(70866960384, 33);
+f(135291469824, 63);
+f(137438953472, 64);
+f(139586437120, 65);
+f(272730423296, 127);
+f(274877906944, 128);
+f(277025390592, 129);
+f(547608330240, 255);
+f(549755813888, 256);
+f(551903297536, 257);
+f(1097364144128, 511);
+f(1099511627776, 512);
+f(1101659111424, 513);
+f(2196875771904, 1023);
+f(2199023255552, 1024);
+f(2201170739200, 1025);
+f(4395899027456, 2047);
+f(4398046511104, 2048);
+f(4400193994752, 2049);
+f(8793945538560, 4095);
+f(8796093022208, 4096);
+f(8798240505856, 4097);
+f(17590038560768, 8191);
+f(17592186044416, 8192);
+f(17594333528064, 8193);
+f(35182224605184, 16383);
+f(35184372088832, 16384);
+f(35186519572480, 16385);
+f(70366596694016, 32767);
+f(70368744177664, 32768);
+f(70370891661312, 32769);
+f(140735340871680, 65535);
+f(140737488355328, 65536);
+f(140739635838976, 65537);
+f(281472829227008, 131071);
+f(281474976710656, 131072);
+f(281477124194304, 131073);
+f(562947805937664, 262143);
+f(562949953421312, 262144);
+f(562952100904960, 262145);
+f(1125897759358976, 524287);
+f(1125899906842624, 524288);
+f(1125902054326272, 524289);
+x = 2147483649;
+f(0, 0);
+f(2147483649, 1);
+f(4294967298, 2);
+f(6442450947, 3);
+f(8589934596, 4);
+f(10737418245, 5);
+f(15032385543, 7);
+f(17179869192, 8);
+f(19327352841, 9);
+f(32212254735, 15);
+f(34359738384, 16);
+f(36507222033, 17);
+f(66571993119, 31);
+f(68719476768, 32);
+f(70866960417, 33);
+f(135291469887, 63);
+f(137438953536, 64);
+f(139586437185, 65);
+f(272730423423, 127);
+f(274877907072, 128);
+f(277025390721, 129);
+f(547608330495, 255);
+f(549755814144, 256);
+f(551903297793, 257);
+f(1097364144639, 511);
+f(1099511628288, 512);
+f(1101659111937, 513);
+f(2196875772927, 1023);
+f(2199023256576, 1024);
+f(2201170740225, 1025);
+f(4395899029503, 2047);
+f(4398046513152, 2048);
+f(4400193996801, 2049);
+f(8793945542655, 4095);
+f(8796093026304, 4096);
+f(8798240509953, 4097);
+f(17590038568959, 8191);
+f(17592186052608, 8192);
+f(17594333536257, 8193);
+f(35182224621567, 16383);
+f(35184372105216, 16384);
+f(35186519588865, 16385);
+f(70366596726783, 32767);
+f(70368744210432, 32768);
+f(70370891694081, 32769);
+f(140735340937215, 65535);
+f(140737488420864, 65536);
+f(140739635904513, 65537);
+f(281472829358079, 131071);
+f(281474976841728, 131072);
+f(281477124325377, 131073);
+f(562947806199807, 262143);
+f(562949953683456, 262144);
+f(562952101167105, 262145);
+f(1125897759883263, 524287);
+f(1125899907366912, 524288);
+f(1125902054850561, 524289);
+x = 4294967295;
+f(0, 0);
+f(4294967295, 1);
+f(8589934590, 2);
+f(12884901885, 3);
+f(17179869180, 4);
+f(21474836475, 5);
+f(30064771065, 7);
+f(34359738360, 8);
+f(38654705655, 9);
+f(64424509425, 15);
+f(68719476720, 16);
+f(73014444015, 17);
+f(133143986145, 31);
+f(137438953440, 32);
+f(141733920735, 33);
+f(270582939585, 63);
+f(274877906880, 64);
+f(279172874175, 65);
+f(545460846465, 127);
+f(549755813760, 128);
+f(554050781055, 129);
+f(1095216660225, 255);
+f(1099511627520, 256);
+f(1103806594815, 257);
+f(2194728287745, 511);
+f(2199023255040, 512);
+f(2203318222335, 513);
+f(4393751542785, 1023);
+f(4398046510080, 1024);
+f(4402341477375, 1025);
+f(8791798052865, 2047);
+f(8796093020160, 2048);
+f(8800387987455, 2049);
+f(17587891073025, 4095);
+f(17592186040320, 4096);
+f(17596481007615, 4097);
+f(35180077113345, 8191);
+f(35184372080640, 8192);
+f(35188667047935, 8193);
+f(70364449193985, 16383);
+f(70368744161280, 16384);
+f(70373039128575, 16385);
+f(140733193355265, 32767);
+f(140737488322560, 32768);
+f(140741783289855, 32769);
+f(281470681677825, 65535);
+f(281474976645120, 65536);
+f(281479271612415, 65537);
+f(562945658322945, 131071);
+f(562949953290240, 131072);
+f(562954248257535, 131073);
+f(1125895611613185, 262143);
+f(1125899906580480, 262144);
+f(1125904201547775, 262145);
diff --git a/deps/v8/test/mjsunit/mul-exhaustive.js b/deps/v8/test/mjsunit/mul-exhaustive.js
deleted file mode 100644
index 12689db32..000000000
--- a/deps/v8/test/mjsunit/mul-exhaustive.js
+++ /dev/null
@@ -1,4629 +0,0 @@
-// Copyright 2008 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.
-
-var x;
-
-// Converts a number to string respecting -0.
-function stringify(n) {
- if ((1 / n) === -Infinity) return "-0";
- return String(n);
-}
-
-function f(expected, y) {
- function testEval(string, x, y) {
- var mulFunction = Function("x, y", "return " + string);
- return mulFunction(x, y);
- }
- function mulTest(expected, x, y) {
- assertEquals(expected, x * y);
- assertEquals(expected, testEval(stringify(x) + " * y", x, y));
- assertEquals(expected, testEval("x * " + stringify(y), x, y));
- assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
- }
- mulTest(expected, x, y);
- mulTest(-expected, -x, y);
- mulTest(-expected, x, -y);
- mulTest(expected, -x, -y);
- if (x === y) return; // Symmetric cases not necessary.
- mulTest(expected, y, x);
- mulTest(-expected, -y, x);
- mulTest(-expected, y, -x);
- mulTest(expected, -y, -x);
-}
-
-x = 0;
-f(0, 0);
-x = 1;
-f(0, 0);
-f(1, 1);
-x = 2;
-f(0, 0);
-f(2, 1);
-f(4, 2);
-x = 3;
-f(0, 0);
-f(3, 1);
-f(6, 2);
-f(9, 3);
-x = 4;
-f(0, 0);
-f(4, 1);
-f(8, 2);
-f(12, 3);
-f(16, 4);
-x = 5;
-f(0, 0);
-f(5, 1);
-f(10, 2);
-f(15, 3);
-f(20, 4);
-f(25, 5);
-x = 7;
-f(0, 0);
-f(7, 1);
-f(14, 2);
-f(21, 3);
-f(28, 4);
-f(35, 5);
-f(49, 7);
-x = 8;
-f(0, 0);
-f(8, 1);
-f(16, 2);
-f(24, 3);
-f(32, 4);
-f(40, 5);
-f(56, 7);
-f(64, 8);
-x = 9;
-f(0, 0);
-f(9, 1);
-f(18, 2);
-f(27, 3);
-f(36, 4);
-f(45, 5);
-f(63, 7);
-f(72, 8);
-f(81, 9);
-x = 15;
-f(0, 0);
-f(15, 1);
-f(30, 2);
-f(45, 3);
-f(60, 4);
-f(75, 5);
-f(105, 7);
-f(120, 8);
-f(135, 9);
-f(225, 15);
-x = 16;
-f(0, 0);
-f(16, 1);
-f(32, 2);
-f(48, 3);
-f(64, 4);
-f(80, 5);
-f(112, 7);
-f(128, 8);
-f(144, 9);
-f(240, 15);
-f(256, 16);
-x = 17;
-f(0, 0);
-f(17, 1);
-f(34, 2);
-f(51, 3);
-f(68, 4);
-f(85, 5);
-f(119, 7);
-f(136, 8);
-f(153, 9);
-f(255, 15);
-f(272, 16);
-f(289, 17);
-x = 31;
-f(0, 0);
-f(31, 1);
-f(62, 2);
-f(93, 3);
-f(124, 4);
-f(155, 5);
-f(217, 7);
-f(248, 8);
-f(279, 9);
-f(465, 15);
-f(496, 16);
-f(527, 17);
-f(961, 31);
-x = 32;
-f(0, 0);
-f(32, 1);
-f(64, 2);
-f(96, 3);
-f(128, 4);
-f(160, 5);
-f(224, 7);
-f(256, 8);
-f(288, 9);
-f(480, 15);
-f(512, 16);
-f(544, 17);
-f(992, 31);
-f(1024, 32);
-x = 33;
-f(0, 0);
-f(33, 1);
-f(66, 2);
-f(99, 3);
-f(132, 4);
-f(165, 5);
-f(231, 7);
-f(264, 8);
-f(297, 9);
-f(495, 15);
-f(528, 16);
-f(561, 17);
-f(1023, 31);
-f(1056, 32);
-f(1089, 33);
-x = 63;
-f(0, 0);
-f(63, 1);
-f(126, 2);
-f(189, 3);
-f(252, 4);
-f(315, 5);
-f(441, 7);
-f(504, 8);
-f(567, 9);
-f(945, 15);
-f(1008, 16);
-f(1071, 17);
-f(1953, 31);
-f(2016, 32);
-f(2079, 33);
-f(3969, 63);
-x = 64;
-f(0, 0);
-f(64, 1);
-f(128, 2);
-f(192, 3);
-f(256, 4);
-f(320, 5);
-f(448, 7);
-f(512, 8);
-f(576, 9);
-f(960, 15);
-f(1024, 16);
-f(1088, 17);
-f(1984, 31);
-f(2048, 32);
-f(2112, 33);
-f(4032, 63);
-f(4096, 64);
-x = 65;
-f(0, 0);
-f(65, 1);
-f(130, 2);
-f(195, 3);
-f(260, 4);
-f(325, 5);
-f(455, 7);
-f(520, 8);
-f(585, 9);
-f(975, 15);
-f(1040, 16);
-f(1105, 17);
-f(2015, 31);
-f(2080, 32);
-f(2145, 33);
-f(4095, 63);
-f(4160, 64);
-f(4225, 65);
-x = 127;
-f(0, 0);
-f(127, 1);
-f(254, 2);
-f(381, 3);
-f(508, 4);
-f(635, 5);
-f(889, 7);
-f(1016, 8);
-f(1143, 9);
-f(1905, 15);
-f(2032, 16);
-f(2159, 17);
-f(3937, 31);
-f(4064, 32);
-f(4191, 33);
-f(8001, 63);
-f(8128, 64);
-f(8255, 65);
-f(16129, 127);
-x = 128;
-f(0, 0);
-f(128, 1);
-f(256, 2);
-f(384, 3);
-f(512, 4);
-f(640, 5);
-f(896, 7);
-f(1024, 8);
-f(1152, 9);
-f(1920, 15);
-f(2048, 16);
-f(2176, 17);
-f(3968, 31);
-f(4096, 32);
-f(4224, 33);
-f(8064, 63);
-f(8192, 64);
-f(8320, 65);
-f(16256, 127);
-f(16384, 128);
-x = 129;
-f(0, 0);
-f(129, 1);
-f(258, 2);
-f(387, 3);
-f(516, 4);
-f(645, 5);
-f(903, 7);
-f(1032, 8);
-f(1161, 9);
-f(1935, 15);
-f(2064, 16);
-f(2193, 17);
-f(3999, 31);
-f(4128, 32);
-f(4257, 33);
-f(8127, 63);
-f(8256, 64);
-f(8385, 65);
-f(16383, 127);
-f(16512, 128);
-f(16641, 129);
-x = 255;
-f(0, 0);
-f(255, 1);
-f(510, 2);
-f(765, 3);
-f(1020, 4);
-f(1275, 5);
-f(1785, 7);
-f(2040, 8);
-f(2295, 9);
-f(3825, 15);
-f(4080, 16);
-f(4335, 17);
-f(7905, 31);
-f(8160, 32);
-f(8415, 33);
-f(16065, 63);
-f(16320, 64);
-f(16575, 65);
-f(32385, 127);
-f(32640, 128);
-f(32895, 129);
-f(65025, 255);
-x = 256;
-f(0, 0);
-f(256, 1);
-f(512, 2);
-f(768, 3);
-f(1024, 4);
-f(1280, 5);
-f(1792, 7);
-f(2048, 8);
-f(2304, 9);
-f(3840, 15);
-f(4096, 16);
-f(4352, 17);
-f(7936, 31);
-f(8192, 32);
-f(8448, 33);
-f(16128, 63);
-f(16384, 64);
-f(16640, 65);
-f(32512, 127);
-f(32768, 128);
-f(33024, 129);
-f(65280, 255);
-f(65536, 256);
-x = 257;
-f(0, 0);
-f(257, 1);
-f(514, 2);
-f(771, 3);
-f(1028, 4);
-f(1285, 5);
-f(1799, 7);
-f(2056, 8);
-f(2313, 9);
-f(3855, 15);
-f(4112, 16);
-f(4369, 17);
-f(7967, 31);
-f(8224, 32);
-f(8481, 33);
-f(16191, 63);
-f(16448, 64);
-f(16705, 65);
-f(32639, 127);
-f(32896, 128);
-f(33153, 129);
-f(65535, 255);
-f(65792, 256);
-f(66049, 257);
-x = 511;
-f(0, 0);
-f(511, 1);
-f(1022, 2);
-f(1533, 3);
-f(2044, 4);
-f(2555, 5);
-f(3577, 7);
-f(4088, 8);
-f(4599, 9);
-f(7665, 15);
-f(8176, 16);
-f(8687, 17);
-f(15841, 31);
-f(16352, 32);
-f(16863, 33);
-f(32193, 63);
-f(32704, 64);
-f(33215, 65);
-f(64897, 127);
-f(65408, 128);
-f(65919, 129);
-f(130305, 255);
-f(130816, 256);
-f(131327, 257);
-f(261121, 511);
-x = 512;
-f(0, 0);
-f(512, 1);
-f(1024, 2);
-f(1536, 3);
-f(2048, 4);
-f(2560, 5);
-f(3584, 7);
-f(4096, 8);
-f(4608, 9);
-f(7680, 15);
-f(8192, 16);
-f(8704, 17);
-f(15872, 31);
-f(16384, 32);
-f(16896, 33);
-f(32256, 63);
-f(32768, 64);
-f(33280, 65);
-f(65024, 127);
-f(65536, 128);
-f(66048, 129);
-f(130560, 255);
-f(131072, 256);
-f(131584, 257);
-f(261632, 511);
-f(262144, 512);
-x = 513;
-f(0, 0);
-f(513, 1);
-f(1026, 2);
-f(1539, 3);
-f(2052, 4);
-f(2565, 5);
-f(3591, 7);
-f(4104, 8);
-f(4617, 9);
-f(7695, 15);
-f(8208, 16);
-f(8721, 17);
-f(15903, 31);
-f(16416, 32);
-f(16929, 33);
-f(32319, 63);
-f(32832, 64);
-f(33345, 65);
-f(65151, 127);
-f(65664, 128);
-f(66177, 129);
-f(130815, 255);
-f(131328, 256);
-f(131841, 257);
-f(262143, 511);
-f(262656, 512);
-f(263169, 513);
-x = 1023;
-f(0, 0);
-f(1023, 1);
-f(2046, 2);
-f(3069, 3);
-f(4092, 4);
-f(5115, 5);
-f(7161, 7);
-f(8184, 8);
-f(9207, 9);
-f(15345, 15);
-f(16368, 16);
-f(17391, 17);
-f(31713, 31);
-f(32736, 32);
-f(33759, 33);
-f(64449, 63);
-f(65472, 64);
-f(66495, 65);
-f(129921, 127);
-f(130944, 128);
-f(131967, 129);
-f(260865, 255);
-f(261888, 256);
-f(262911, 257);
-f(522753, 511);
-f(523776, 512);
-f(524799, 513);
-f(1046529, 1023);
-x = 1024;
-f(0, 0);
-f(1024, 1);
-f(2048, 2);
-f(3072, 3);
-f(4096, 4);
-f(5120, 5);
-f(7168, 7);
-f(8192, 8);
-f(9216, 9);
-f(15360, 15);
-f(16384, 16);
-f(17408, 17);
-f(31744, 31);
-f(32768, 32);
-f(33792, 33);
-f(64512, 63);
-f(65536, 64);
-f(66560, 65);
-f(130048, 127);
-f(131072, 128);
-f(132096, 129);
-f(261120, 255);
-f(262144, 256);
-f(263168, 257);
-f(523264, 511);
-f(524288, 512);
-f(525312, 513);
-f(1047552, 1023);
-f(1048576, 1024);
-x = 1025;
-f(0, 0);
-f(1025, 1);
-f(2050, 2);
-f(3075, 3);
-f(4100, 4);
-f(5125, 5);
-f(7175, 7);
-f(8200, 8);
-f(9225, 9);
-f(15375, 15);
-f(16400, 16);
-f(17425, 17);
-f(31775, 31);
-f(32800, 32);
-f(33825, 33);
-f(64575, 63);
-f(65600, 64);
-f(66625, 65);
-f(130175, 127);
-f(131200, 128);
-f(132225, 129);
-f(261375, 255);
-f(262400, 256);
-f(263425, 257);
-f(523775, 511);
-f(524800, 512);
-f(525825, 513);
-f(1048575, 1023);
-f(1049600, 1024);
-f(1050625, 1025);
-x = 2047;
-f(0, 0);
-f(2047, 1);
-f(4094, 2);
-f(6141, 3);
-f(8188, 4);
-f(10235, 5);
-f(14329, 7);
-f(16376, 8);
-f(18423, 9);
-f(30705, 15);
-f(32752, 16);
-f(34799, 17);
-f(63457, 31);
-f(65504, 32);
-f(67551, 33);
-f(128961, 63);
-f(131008, 64);
-f(133055, 65);
-f(259969, 127);
-f(262016, 128);
-f(264063, 129);
-f(521985, 255);
-f(524032, 256);
-f(526079, 257);
-f(1046017, 511);
-f(1048064, 512);
-f(1050111, 513);
-f(2094081, 1023);
-f(2096128, 1024);
-f(2098175, 1025);
-f(4190209, 2047);
-x = 2048;
-f(0, 0);
-f(2048, 1);
-f(4096, 2);
-f(6144, 3);
-f(8192, 4);
-f(10240, 5);
-f(14336, 7);
-f(16384, 8);
-f(18432, 9);
-f(30720, 15);
-f(32768, 16);
-f(34816, 17);
-f(63488, 31);
-f(65536, 32);
-f(67584, 33);
-f(129024, 63);
-f(131072, 64);
-f(133120, 65);
-f(260096, 127);
-f(262144, 128);
-f(264192, 129);
-f(522240, 255);
-f(524288, 256);
-f(526336, 257);
-f(1046528, 511);
-f(1048576, 512);
-f(1050624, 513);
-f(2095104, 1023);
-f(2097152, 1024);
-f(2099200, 1025);
-f(4192256, 2047);
-f(4194304, 2048);
-x = 2049;
-f(0, 0);
-f(2049, 1);
-f(4098, 2);
-f(6147, 3);
-f(8196, 4);
-f(10245, 5);
-f(14343, 7);
-f(16392, 8);
-f(18441, 9);
-f(30735, 15);
-f(32784, 16);
-f(34833, 17);
-f(63519, 31);
-f(65568, 32);
-f(67617, 33);
-f(129087, 63);
-f(131136, 64);
-f(133185, 65);
-f(260223, 127);
-f(262272, 128);
-f(264321, 129);
-f(522495, 255);
-f(524544, 256);
-f(526593, 257);
-f(1047039, 511);
-f(1049088, 512);
-f(1051137, 513);
-f(2096127, 1023);
-f(2098176, 1024);
-f(2100225, 1025);
-f(4194303, 2047);
-f(4196352, 2048);
-f(4198401, 2049);
-x = 4095;
-f(0, 0);
-f(4095, 1);
-f(8190, 2);
-f(12285, 3);
-f(16380, 4);
-f(20475, 5);
-f(28665, 7);
-f(32760, 8);
-f(36855, 9);
-f(61425, 15);
-f(65520, 16);
-f(69615, 17);
-f(126945, 31);
-f(131040, 32);
-f(135135, 33);
-f(257985, 63);
-f(262080, 64);
-f(266175, 65);
-f(520065, 127);
-f(524160, 128);
-f(528255, 129);
-f(1044225, 255);
-f(1048320, 256);
-f(1052415, 257);
-f(2092545, 511);
-f(2096640, 512);
-f(2100735, 513);
-f(4189185, 1023);
-f(4193280, 1024);
-f(4197375, 1025);
-f(8382465, 2047);
-f(8386560, 2048);
-f(8390655, 2049);
-f(16769025, 4095);
-x = 4096;
-f(0, 0);
-f(4096, 1);
-f(8192, 2);
-f(12288, 3);
-f(16384, 4);
-f(20480, 5);
-f(28672, 7);
-f(32768, 8);
-f(36864, 9);
-f(61440, 15);
-f(65536, 16);
-f(69632, 17);
-f(126976, 31);
-f(131072, 32);
-f(135168, 33);
-f(258048, 63);
-f(262144, 64);
-f(266240, 65);
-f(520192, 127);
-f(524288, 128);
-f(528384, 129);
-f(1044480, 255);
-f(1048576, 256);
-f(1052672, 257);
-f(2093056, 511);
-f(2097152, 512);
-f(2101248, 513);
-f(4190208, 1023);
-f(4194304, 1024);
-f(4198400, 1025);
-f(8384512, 2047);
-f(8388608, 2048);
-f(8392704, 2049);
-f(16773120, 4095);
-f(16777216, 4096);
-x = 4097;
-f(0, 0);
-f(4097, 1);
-f(8194, 2);
-f(12291, 3);
-f(16388, 4);
-f(20485, 5);
-f(28679, 7);
-f(32776, 8);
-f(36873, 9);
-f(61455, 15);
-f(65552, 16);
-f(69649, 17);
-f(127007, 31);
-f(131104, 32);
-f(135201, 33);
-f(258111, 63);
-f(262208, 64);
-f(266305, 65);
-f(520319, 127);
-f(524416, 128);
-f(528513, 129);
-f(1044735, 255);
-f(1048832, 256);
-f(1052929, 257);
-f(2093567, 511);
-f(2097664, 512);
-f(2101761, 513);
-f(4191231, 1023);
-f(4195328, 1024);
-f(4199425, 1025);
-f(8386559, 2047);
-f(8390656, 2048);
-f(8394753, 2049);
-f(16777215, 4095);
-f(16781312, 4096);
-f(16785409, 4097);
-x = 8191;
-f(0, 0);
-f(8191, 1);
-f(16382, 2);
-f(24573, 3);
-f(32764, 4);
-f(40955, 5);
-f(57337, 7);
-f(65528, 8);
-f(73719, 9);
-f(122865, 15);
-f(131056, 16);
-f(139247, 17);
-f(253921, 31);
-f(262112, 32);
-f(270303, 33);
-f(516033, 63);
-f(524224, 64);
-f(532415, 65);
-f(1040257, 127);
-f(1048448, 128);
-f(1056639, 129);
-f(2088705, 255);
-f(2096896, 256);
-f(2105087, 257);
-f(4185601, 511);
-f(4193792, 512);
-f(4201983, 513);
-f(8379393, 1023);
-f(8387584, 1024);
-f(8395775, 1025);
-f(16766977, 2047);
-f(16775168, 2048);
-f(16783359, 2049);
-f(33542145, 4095);
-f(33550336, 4096);
-f(33558527, 4097);
-f(67092481, 8191);
-x = 8192;
-f(0, 0);
-f(8192, 1);
-f(16384, 2);
-f(24576, 3);
-f(32768, 4);
-f(40960, 5);
-f(57344, 7);
-f(65536, 8);
-f(73728, 9);
-f(122880, 15);
-f(131072, 16);
-f(139264, 17);
-f(253952, 31);
-f(262144, 32);
-f(270336, 33);
-f(516096, 63);
-f(524288, 64);
-f(532480, 65);
-f(1040384, 127);
-f(1048576, 128);
-f(1056768, 129);
-f(2088960, 255);
-f(2097152, 256);
-f(2105344, 257);
-f(4186112, 511);
-f(4194304, 512);
-f(4202496, 513);
-f(8380416, 1023);
-f(8388608, 1024);
-f(8396800, 1025);
-f(16769024, 2047);
-f(16777216, 2048);
-f(16785408, 2049);
-f(33546240, 4095);
-f(33554432, 4096);
-f(33562624, 4097);
-f(67100672, 8191);
-f(67108864, 8192);
-x = 8193;
-f(0, 0);
-f(8193, 1);
-f(16386, 2);
-f(24579, 3);
-f(32772, 4);
-f(40965, 5);
-f(57351, 7);
-f(65544, 8);
-f(73737, 9);
-f(122895, 15);
-f(131088, 16);
-f(139281, 17);
-f(253983, 31);
-f(262176, 32);
-f(270369, 33);
-f(516159, 63);
-f(524352, 64);
-f(532545, 65);
-f(1040511, 127);
-f(1048704, 128);
-f(1056897, 129);
-f(2089215, 255);
-f(2097408, 256);
-f(2105601, 257);
-f(4186623, 511);
-f(4194816, 512);
-f(4203009, 513);
-f(8381439, 1023);
-f(8389632, 1024);
-f(8397825, 1025);
-f(16771071, 2047);
-f(16779264, 2048);
-f(16787457, 2049);
-f(33550335, 4095);
-f(33558528, 4096);
-f(33566721, 4097);
-f(67108863, 8191);
-f(67117056, 8192);
-f(67125249, 8193);
-x = 16383;
-f(0, 0);
-f(16383, 1);
-f(32766, 2);
-f(49149, 3);
-f(65532, 4);
-f(81915, 5);
-f(114681, 7);
-f(131064, 8);
-f(147447, 9);
-f(245745, 15);
-f(262128, 16);
-f(278511, 17);
-f(507873, 31);
-f(524256, 32);
-f(540639, 33);
-f(1032129, 63);
-f(1048512, 64);
-f(1064895, 65);
-f(2080641, 127);
-f(2097024, 128);
-f(2113407, 129);
-f(4177665, 255);
-f(4194048, 256);
-f(4210431, 257);
-f(8371713, 511);
-f(8388096, 512);
-f(8404479, 513);
-f(16759809, 1023);
-f(16776192, 1024);
-f(16792575, 1025);
-f(33536001, 2047);
-f(33552384, 2048);
-f(33568767, 2049);
-f(67088385, 4095);
-f(67104768, 4096);
-f(67121151, 4097);
-f(134193153, 8191);
-f(134209536, 8192);
-f(134225919, 8193);
-f(268402689, 16383);
-x = 16384;
-f(0, 0);
-f(16384, 1);
-f(32768, 2);
-f(49152, 3);
-f(65536, 4);
-f(81920, 5);
-f(114688, 7);
-f(131072, 8);
-f(147456, 9);
-f(245760, 15);
-f(262144, 16);
-f(278528, 17);
-f(507904, 31);
-f(524288, 32);
-f(540672, 33);
-f(1032192, 63);
-f(1048576, 64);
-f(1064960, 65);
-f(2080768, 127);
-f(2097152, 128);
-f(2113536, 129);
-f(4177920, 255);
-f(4194304, 256);
-f(4210688, 257);
-f(8372224, 511);
-f(8388608, 512);
-f(8404992, 513);
-f(16760832, 1023);
-f(16777216, 1024);
-f(16793600, 1025);
-f(33538048, 2047);
-f(33554432, 2048);
-f(33570816, 2049);
-f(67092480, 4095);
-f(67108864, 4096);
-f(67125248, 4097);
-f(134201344, 8191);
-f(134217728, 8192);
-f(134234112, 8193);
-f(268419072, 16383);
-f(268435456, 16384);
-x = 16385;
-f(0, 0);
-f(16385, 1);
-f(32770, 2);
-f(49155, 3);
-f(65540, 4);
-f(81925, 5);
-f(114695, 7);
-f(131080, 8);
-f(147465, 9);
-f(245775, 15);
-f(262160, 16);
-f(278545, 17);
-f(507935, 31);
-f(524320, 32);
-f(540705, 33);
-f(1032255, 63);
-f(1048640, 64);
-f(1065025, 65);
-f(2080895, 127);
-f(2097280, 128);
-f(2113665, 129);
-f(4178175, 255);
-f(4194560, 256);
-f(4210945, 257);
-f(8372735, 511);
-f(8389120, 512);
-f(8405505, 513);
-f(16761855, 1023);
-f(16778240, 1024);
-f(16794625, 1025);
-f(33540095, 2047);
-f(33556480, 2048);
-f(33572865, 2049);
-f(67096575, 4095);
-f(67112960, 4096);
-f(67129345, 4097);
-f(134209535, 8191);
-f(134225920, 8192);
-f(134242305, 8193);
-f(268435455, 16383);
-f(268451840, 16384);
-f(268468225, 16385);
-x = 32767;
-f(0, 0);
-f(32767, 1);
-f(65534, 2);
-f(98301, 3);
-f(131068, 4);
-f(163835, 5);
-f(229369, 7);
-f(262136, 8);
-f(294903, 9);
-f(491505, 15);
-f(524272, 16);
-f(557039, 17);
-f(1015777, 31);
-f(1048544, 32);
-f(1081311, 33);
-f(2064321, 63);
-f(2097088, 64);
-f(2129855, 65);
-f(4161409, 127);
-f(4194176, 128);
-f(4226943, 129);
-f(8355585, 255);
-f(8388352, 256);
-f(8421119, 257);
-f(16743937, 511);
-f(16776704, 512);
-f(16809471, 513);
-f(33520641, 1023);
-f(33553408, 1024);
-f(33586175, 1025);
-f(67074049, 2047);
-f(67106816, 2048);
-f(67139583, 2049);
-f(134180865, 4095);
-f(134213632, 4096);
-f(134246399, 4097);
-f(268394497, 8191);
-f(268427264, 8192);
-f(268460031, 8193);
-f(536821761, 16383);
-f(536854528, 16384);
-f(536887295, 16385);
-f(1073676289, 32767);
-x = 32768;
-f(0, 0);
-f(32768, 1);
-f(65536, 2);
-f(98304, 3);
-f(131072, 4);
-f(163840, 5);
-f(229376, 7);
-f(262144, 8);
-f(294912, 9);
-f(491520, 15);
-f(524288, 16);
-f(557056, 17);
-f(1015808, 31);
-f(1048576, 32);
-f(1081344, 33);
-f(2064384, 63);
-f(2097152, 64);
-f(2129920, 65);
-f(4161536, 127);
-f(4194304, 128);
-f(4227072, 129);
-f(8355840, 255);
-f(8388608, 256);
-f(8421376, 257);
-f(16744448, 511);
-f(16777216, 512);
-f(16809984, 513);
-f(33521664, 1023);
-f(33554432, 1024);
-f(33587200, 1025);
-f(67076096, 2047);
-f(67108864, 2048);
-f(67141632, 2049);
-f(134184960, 4095);
-f(134217728, 4096);
-f(134250496, 4097);
-f(268402688, 8191);
-f(268435456, 8192);
-f(268468224, 8193);
-f(536838144, 16383);
-f(536870912, 16384);
-f(536903680, 16385);
-f(1073709056, 32767);
-f(1073741824, 32768);
-x = 32769;
-f(0, 0);
-f(32769, 1);
-f(65538, 2);
-f(98307, 3);
-f(131076, 4);
-f(163845, 5);
-f(229383, 7);
-f(262152, 8);
-f(294921, 9);
-f(491535, 15);
-f(524304, 16);
-f(557073, 17);
-f(1015839, 31);
-f(1048608, 32);
-f(1081377, 33);
-f(2064447, 63);
-f(2097216, 64);
-f(2129985, 65);
-f(4161663, 127);
-f(4194432, 128);
-f(4227201, 129);
-f(8356095, 255);
-f(8388864, 256);
-f(8421633, 257);
-f(16744959, 511);
-f(16777728, 512);
-f(16810497, 513);
-f(33522687, 1023);
-f(33555456, 1024);
-f(33588225, 1025);
-f(67078143, 2047);
-f(67110912, 2048);
-f(67143681, 2049);
-f(134189055, 4095);
-f(134221824, 4096);
-f(134254593, 4097);
-f(268410879, 8191);
-f(268443648, 8192);
-f(268476417, 8193);
-f(536854527, 16383);
-f(536887296, 16384);
-f(536920065, 16385);
-f(1073741823, 32767);
-f(1073774592, 32768);
-f(1073807361, 32769);
-x = 65535;
-f(0, 0);
-f(65535, 1);
-f(131070, 2);
-f(196605, 3);
-f(262140, 4);
-f(327675, 5);
-f(458745, 7);
-f(524280, 8);
-f(589815, 9);
-f(983025, 15);
-f(1048560, 16);
-f(1114095, 17);
-f(2031585, 31);
-f(2097120, 32);
-f(2162655, 33);
-f(4128705, 63);
-f(4194240, 64);
-f(4259775, 65);
-f(8322945, 127);
-f(8388480, 128);
-f(8454015, 129);
-f(16711425, 255);
-f(16776960, 256);
-f(16842495, 257);
-f(33488385, 511);
-f(33553920, 512);
-f(33619455, 513);
-f(67042305, 1023);
-f(67107840, 1024);
-f(67173375, 1025);
-f(134150145, 2047);
-f(134215680, 2048);
-f(134281215, 2049);
-f(268365825, 4095);
-f(268431360, 4096);
-f(268496895, 4097);
-f(536797185, 8191);
-f(536862720, 8192);
-f(536928255, 8193);
-f(1073659905, 16383);
-f(1073725440, 16384);
-f(1073790975, 16385);
-f(2147385345, 32767);
-f(2147450880, 32768);
-f(2147516415, 32769);
-f(4294836225, 65535);
-x = 65536;
-f(0, 0);
-f(65536, 1);
-f(131072, 2);
-f(196608, 3);
-f(262144, 4);
-f(327680, 5);
-f(458752, 7);
-f(524288, 8);
-f(589824, 9);
-f(983040, 15);
-f(1048576, 16);
-f(1114112, 17);
-f(2031616, 31);
-f(2097152, 32);
-f(2162688, 33);
-f(4128768, 63);
-f(4194304, 64);
-f(4259840, 65);
-f(8323072, 127);
-f(8388608, 128);
-f(8454144, 129);
-f(16711680, 255);
-f(16777216, 256);
-f(16842752, 257);
-f(33488896, 511);
-f(33554432, 512);
-f(33619968, 513);
-f(67043328, 1023);
-f(67108864, 1024);
-f(67174400, 1025);
-f(134152192, 2047);
-f(134217728, 2048);
-f(134283264, 2049);
-f(268369920, 4095);
-f(268435456, 4096);
-f(268500992, 4097);
-f(536805376, 8191);
-f(536870912, 8192);
-f(536936448, 8193);
-f(1073676288, 16383);
-f(1073741824, 16384);
-f(1073807360, 16385);
-f(2147418112, 32767);
-f(2147483648, 32768);
-f(2147549184, 32769);
-f(4294901760, 65535);
-f(4294967296, 65536);
-x = 65537;
-f(0, 0);
-f(65537, 1);
-f(131074, 2);
-f(196611, 3);
-f(262148, 4);
-f(327685, 5);
-f(458759, 7);
-f(524296, 8);
-f(589833, 9);
-f(983055, 15);
-f(1048592, 16);
-f(1114129, 17);
-f(2031647, 31);
-f(2097184, 32);
-f(2162721, 33);
-f(4128831, 63);
-f(4194368, 64);
-f(4259905, 65);
-f(8323199, 127);
-f(8388736, 128);
-f(8454273, 129);
-f(16711935, 255);
-f(16777472, 256);
-f(16843009, 257);
-f(33489407, 511);
-f(33554944, 512);
-f(33620481, 513);
-f(67044351, 1023);
-f(67109888, 1024);
-f(67175425, 1025);
-f(134154239, 2047);
-f(134219776, 2048);
-f(134285313, 2049);
-f(268374015, 4095);
-f(268439552, 4096);
-f(268505089, 4097);
-f(536813567, 8191);
-f(536879104, 8192);
-f(536944641, 8193);
-f(1073692671, 16383);
-f(1073758208, 16384);
-f(1073823745, 16385);
-f(2147450879, 32767);
-f(2147516416, 32768);
-f(2147581953, 32769);
-f(4294967295, 65535);
-f(4295032832, 65536);
-f(4295098369, 65537);
-x = 131071;
-f(0, 0);
-f(131071, 1);
-f(262142, 2);
-f(393213, 3);
-f(524284, 4);
-f(655355, 5);
-f(917497, 7);
-f(1048568, 8);
-f(1179639, 9);
-f(1966065, 15);
-f(2097136, 16);
-f(2228207, 17);
-f(4063201, 31);
-f(4194272, 32);
-f(4325343, 33);
-f(8257473, 63);
-f(8388544, 64);
-f(8519615, 65);
-f(16646017, 127);
-f(16777088, 128);
-f(16908159, 129);
-f(33423105, 255);
-f(33554176, 256);
-f(33685247, 257);
-f(66977281, 511);
-f(67108352, 512);
-f(67239423, 513);
-f(134085633, 1023);
-f(134216704, 1024);
-f(134347775, 1025);
-f(268302337, 2047);
-f(268433408, 2048);
-f(268564479, 2049);
-f(536735745, 4095);
-f(536866816, 4096);
-f(536997887, 4097);
-f(1073602561, 8191);
-f(1073733632, 8192);
-f(1073864703, 8193);
-f(2147336193, 16383);
-f(2147467264, 16384);
-f(2147598335, 16385);
-f(4294803457, 32767);
-f(4294934528, 32768);
-f(4295065599, 32769);
-f(8589737985, 65535);
-f(8589869056, 65536);
-f(8590000127, 65537);
-f(17179607041, 131071);
-x = 131072;
-f(0, 0);
-f(131072, 1);
-f(262144, 2);
-f(393216, 3);
-f(524288, 4);
-f(655360, 5);
-f(917504, 7);
-f(1048576, 8);
-f(1179648, 9);
-f(1966080, 15);
-f(2097152, 16);
-f(2228224, 17);
-f(4063232, 31);
-f(4194304, 32);
-f(4325376, 33);
-f(8257536, 63);
-f(8388608, 64);
-f(8519680, 65);
-f(16646144, 127);
-f(16777216, 128);
-f(16908288, 129);
-f(33423360, 255);
-f(33554432, 256);
-f(33685504, 257);
-f(66977792, 511);
-f(67108864, 512);
-f(67239936, 513);
-f(134086656, 1023);
-f(134217728, 1024);
-f(134348800, 1025);
-f(268304384, 2047);
-f(268435456, 2048);
-f(268566528, 2049);
-f(536739840, 4095);
-f(536870912, 4096);
-f(537001984, 4097);
-f(1073610752, 8191);
-f(1073741824, 8192);
-f(1073872896, 8193);
-f(2147352576, 16383);
-f(2147483648, 16384);
-f(2147614720, 16385);
-f(4294836224, 32767);
-f(4294967296, 32768);
-f(4295098368, 32769);
-f(8589803520, 65535);
-f(8589934592, 65536);
-f(8590065664, 65537);
-f(17179738112, 131071);
-f(17179869184, 131072);
-x = 131073;
-f(0, 0);
-f(131073, 1);
-f(262146, 2);
-f(393219, 3);
-f(524292, 4);
-f(655365, 5);
-f(917511, 7);
-f(1048584, 8);
-f(1179657, 9);
-f(1966095, 15);
-f(2097168, 16);
-f(2228241, 17);
-f(4063263, 31);
-f(4194336, 32);
-f(4325409, 33);
-f(8257599, 63);
-f(8388672, 64);
-f(8519745, 65);
-f(16646271, 127);
-f(16777344, 128);
-f(16908417, 129);
-f(33423615, 255);
-f(33554688, 256);
-f(33685761, 257);
-f(66978303, 511);
-f(67109376, 512);
-f(67240449, 513);
-f(134087679, 1023);
-f(134218752, 1024);
-f(134349825, 1025);
-f(268306431, 2047);
-f(268437504, 2048);
-f(268568577, 2049);
-f(536743935, 4095);
-f(536875008, 4096);
-f(537006081, 4097);
-f(1073618943, 8191);
-f(1073750016, 8192);
-f(1073881089, 8193);
-f(2147368959, 16383);
-f(2147500032, 16384);
-f(2147631105, 16385);
-f(4294868991, 32767);
-f(4295000064, 32768);
-f(4295131137, 32769);
-f(8589869055, 65535);
-f(8590000128, 65536);
-f(8590131201, 65537);
-f(17179869183, 131071);
-f(17180000256, 131072);
-f(17180131329, 131073);
-x = 262143;
-f(0, 0);
-f(262143, 1);
-f(524286, 2);
-f(786429, 3);
-f(1048572, 4);
-f(1310715, 5);
-f(1835001, 7);
-f(2097144, 8);
-f(2359287, 9);
-f(3932145, 15);
-f(4194288, 16);
-f(4456431, 17);
-f(8126433, 31);
-f(8388576, 32);
-f(8650719, 33);
-f(16515009, 63);
-f(16777152, 64);
-f(17039295, 65);
-f(33292161, 127);
-f(33554304, 128);
-f(33816447, 129);
-f(66846465, 255);
-f(67108608, 256);
-f(67370751, 257);
-f(133955073, 511);
-f(134217216, 512);
-f(134479359, 513);
-f(268172289, 1023);
-f(268434432, 1024);
-f(268696575, 1025);
-f(536606721, 2047);
-f(536868864, 2048);
-f(537131007, 2049);
-f(1073475585, 4095);
-f(1073737728, 4096);
-f(1073999871, 4097);
-f(2147213313, 8191);
-f(2147475456, 8192);
-f(2147737599, 8193);
-f(4294688769, 16383);
-f(4294950912, 16384);
-f(4295213055, 16385);
-f(8589639681, 32767);
-f(8589901824, 32768);
-f(8590163967, 32769);
-f(17179541505, 65535);
-f(17179803648, 65536);
-f(17180065791, 65537);
-f(34359345153, 131071);
-f(34359607296, 131072);
-f(34359869439, 131073);
-f(68718952449, 262143);
-x = 262144;
-f(0, 0);
-f(262144, 1);
-f(524288, 2);
-f(786432, 3);
-f(1048576, 4);
-f(1310720, 5);
-f(1835008, 7);
-f(2097152, 8);
-f(2359296, 9);
-f(3932160, 15);
-f(4194304, 16);
-f(4456448, 17);
-f(8126464, 31);
-f(8388608, 32);
-f(8650752, 33);
-f(16515072, 63);
-f(16777216, 64);
-f(17039360, 65);
-f(33292288, 127);
-f(33554432, 128);
-f(33816576, 129);
-f(66846720, 255);
-f(67108864, 256);
-f(67371008, 257);
-f(133955584, 511);
-f(134217728, 512);
-f(134479872, 513);
-f(268173312, 1023);
-f(268435456, 1024);
-f(268697600, 1025);
-f(536608768, 2047);
-f(536870912, 2048);
-f(537133056, 2049);
-f(1073479680, 4095);
-f(1073741824, 4096);
-f(1074003968, 4097);
-f(2147221504, 8191);
-f(2147483648, 8192);
-f(2147745792, 8193);
-f(4294705152, 16383);
-f(4294967296, 16384);
-f(4295229440, 16385);
-f(8589672448, 32767);
-f(8589934592, 32768);
-f(8590196736, 32769);
-f(17179607040, 65535);
-f(17179869184, 65536);
-f(17180131328, 65537);
-f(34359476224, 131071);
-f(34359738368, 131072);
-f(34360000512, 131073);
-f(68719214592, 262143);
-f(68719476736, 262144);
-x = 262145;
-f(0, 0);
-f(262145, 1);
-f(524290, 2);
-f(786435, 3);
-f(1048580, 4);
-f(1310725, 5);
-f(1835015, 7);
-f(2097160, 8);
-f(2359305, 9);
-f(3932175, 15);
-f(4194320, 16);
-f(4456465, 17);
-f(8126495, 31);
-f(8388640, 32);
-f(8650785, 33);
-f(16515135, 63);
-f(16777280, 64);
-f(17039425, 65);
-f(33292415, 127);
-f(33554560, 128);
-f(33816705, 129);
-f(66846975, 255);
-f(67109120, 256);
-f(67371265, 257);
-f(133956095, 511);
-f(134218240, 512);
-f(134480385, 513);
-f(268174335, 1023);
-f(268436480, 1024);
-f(268698625, 1025);
-f(536610815, 2047);
-f(536872960, 2048);
-f(537135105, 2049);
-f(1073483775, 4095);
-f(1073745920, 4096);
-f(1074008065, 4097);
-f(2147229695, 8191);
-f(2147491840, 8192);
-f(2147753985, 8193);
-f(4294721535, 16383);
-f(4294983680, 16384);
-f(4295245825, 16385);
-f(8589705215, 32767);
-f(8589967360, 32768);
-f(8590229505, 32769);
-f(17179672575, 65535);
-f(17179934720, 65536);
-f(17180196865, 65537);
-f(34359607295, 131071);
-f(34359869440, 131072);
-f(34360131585, 131073);
-f(68719476735, 262143);
-f(68719738880, 262144);
-f(68720001025, 262145);
-x = 524287;
-f(0, 0);
-f(524287, 1);
-f(1048574, 2);
-f(1572861, 3);
-f(2097148, 4);
-f(2621435, 5);
-f(3670009, 7);
-f(4194296, 8);
-f(4718583, 9);
-f(7864305, 15);
-f(8388592, 16);
-f(8912879, 17);
-f(16252897, 31);
-f(16777184, 32);
-f(17301471, 33);
-f(33030081, 63);
-f(33554368, 64);
-f(34078655, 65);
-f(66584449, 127);
-f(67108736, 128);
-f(67633023, 129);
-f(133693185, 255);
-f(134217472, 256);
-f(134741759, 257);
-f(267910657, 511);
-f(268434944, 512);
-f(268959231, 513);
-f(536345601, 1023);
-f(536869888, 1024);
-f(537394175, 1025);
-f(1073215489, 2047);
-f(1073739776, 2048);
-f(1074264063, 2049);
-f(2146955265, 4095);
-f(2147479552, 4096);
-f(2148003839, 4097);
-f(4294434817, 8191);
-f(4294959104, 8192);
-f(4295483391, 8193);
-f(8589393921, 16383);
-f(8589918208, 16384);
-f(8590442495, 16385);
-f(17179312129, 32767);
-f(17179836416, 32768);
-f(17180360703, 32769);
-f(34359148545, 65535);
-f(34359672832, 65536);
-f(34360197119, 65537);
-f(68718821377, 131071);
-f(68719345664, 131072);
-f(68719869951, 131073);
-f(137438167041, 262143);
-f(137438691328, 262144);
-f(137439215615, 262145);
-f(274876858369, 524287);
-x = 524288;
-f(0, 0);
-f(524288, 1);
-f(1048576, 2);
-f(1572864, 3);
-f(2097152, 4);
-f(2621440, 5);
-f(3670016, 7);
-f(4194304, 8);
-f(4718592, 9);
-f(7864320, 15);
-f(8388608, 16);
-f(8912896, 17);
-f(16252928, 31);
-f(16777216, 32);
-f(17301504, 33);
-f(33030144, 63);
-f(33554432, 64);
-f(34078720, 65);
-f(66584576, 127);
-f(67108864, 128);
-f(67633152, 129);
-f(133693440, 255);
-f(134217728, 256);
-f(134742016, 257);
-f(267911168, 511);
-f(268435456, 512);
-f(268959744, 513);
-f(536346624, 1023);
-f(536870912, 1024);
-f(537395200, 1025);
-f(1073217536, 2047);
-f(1073741824, 2048);
-f(1074266112, 2049);
-f(2146959360, 4095);
-f(2147483648, 4096);
-f(2148007936, 4097);
-f(4294443008, 8191);
-f(4294967296, 8192);
-f(4295491584, 8193);
-f(8589410304, 16383);
-f(8589934592, 16384);
-f(8590458880, 16385);
-f(17179344896, 32767);
-f(17179869184, 32768);
-f(17180393472, 32769);
-f(34359214080, 65535);
-f(34359738368, 65536);
-f(34360262656, 65537);
-f(68718952448, 131071);
-f(68719476736, 131072);
-f(68720001024, 131073);
-f(137438429184, 262143);
-f(137438953472, 262144);
-f(137439477760, 262145);
-f(274877382656, 524287);
-f(274877906944, 524288);
-x = 524289;
-f(0, 0);
-f(524289, 1);
-f(1048578, 2);
-f(1572867, 3);
-f(2097156, 4);
-f(2621445, 5);
-f(3670023, 7);
-f(4194312, 8);
-f(4718601, 9);
-f(7864335, 15);
-f(8388624, 16);
-f(8912913, 17);
-f(16252959, 31);
-f(16777248, 32);
-f(17301537, 33);
-f(33030207, 63);
-f(33554496, 64);
-f(34078785, 65);
-f(66584703, 127);
-f(67108992, 128);
-f(67633281, 129);
-f(133693695, 255);
-f(134217984, 256);
-f(134742273, 257);
-f(267911679, 511);
-f(268435968, 512);
-f(268960257, 513);
-f(536347647, 1023);
-f(536871936, 1024);
-f(537396225, 1025);
-f(1073219583, 2047);
-f(1073743872, 2048);
-f(1074268161, 2049);
-f(2146963455, 4095);
-f(2147487744, 4096);
-f(2148012033, 4097);
-f(4294451199, 8191);
-f(4294975488, 8192);
-f(4295499777, 8193);
-f(8589426687, 16383);
-f(8589950976, 16384);
-f(8590475265, 16385);
-f(17179377663, 32767);
-f(17179901952, 32768);
-f(17180426241, 32769);
-f(34359279615, 65535);
-f(34359803904, 65536);
-f(34360328193, 65537);
-f(68719083519, 131071);
-f(68719607808, 131072);
-f(68720132097, 131073);
-f(137438691327, 262143);
-f(137439215616, 262144);
-f(137439739905, 262145);
-f(274877906943, 524287);
-f(274878431232, 524288);
-f(274878955521, 524289);
-x = 1048575;
-f(0, 0);
-f(1048575, 1);
-f(2097150, 2);
-f(3145725, 3);
-f(4194300, 4);
-f(5242875, 5);
-f(7340025, 7);
-f(8388600, 8);
-f(9437175, 9);
-f(15728625, 15);
-f(16777200, 16);
-f(17825775, 17);
-f(32505825, 31);
-f(33554400, 32);
-f(34602975, 33);
-f(66060225, 63);
-f(67108800, 64);
-f(68157375, 65);
-f(133169025, 127);
-f(134217600, 128);
-f(135266175, 129);
-f(267386625, 255);
-f(268435200, 256);
-f(269483775, 257);
-f(535821825, 511);
-f(536870400, 512);
-f(537918975, 513);
-f(1072692225, 1023);
-f(1073740800, 1024);
-f(1074789375, 1025);
-f(2146433025, 2047);
-f(2147481600, 2048);
-f(2148530175, 2049);
-f(4293914625, 4095);
-f(4294963200, 4096);
-f(4296011775, 4097);
-f(8588877825, 8191);
-f(8589926400, 8192);
-f(8590974975, 8193);
-f(17178804225, 16383);
-f(17179852800, 16384);
-f(17180901375, 16385);
-f(34358657025, 32767);
-f(34359705600, 32768);
-f(34360754175, 32769);
-f(68718362625, 65535);
-f(68719411200, 65536);
-f(68720459775, 65537);
-f(137437773825, 131071);
-f(137438822400, 131072);
-f(137439870975, 131073);
-f(274876596225, 262143);
-f(274877644800, 262144);
-f(274878693375, 262145);
-f(549754241025, 524287);
-f(549755289600, 524288);
-f(549756338175, 524289);
-f(1099509530625, 1048575);
-x = 1048576;
-f(0, 0);
-f(1048576, 1);
-f(2097152, 2);
-f(3145728, 3);
-f(4194304, 4);
-f(5242880, 5);
-f(7340032, 7);
-f(8388608, 8);
-f(9437184, 9);
-f(15728640, 15);
-f(16777216, 16);
-f(17825792, 17);
-f(32505856, 31);
-f(33554432, 32);
-f(34603008, 33);
-f(66060288, 63);
-f(67108864, 64);
-f(68157440, 65);
-f(133169152, 127);
-f(134217728, 128);
-f(135266304, 129);
-f(267386880, 255);
-f(268435456, 256);
-f(269484032, 257);
-f(535822336, 511);
-f(536870912, 512);
-f(537919488, 513);
-f(1072693248, 1023);
-f(1073741824, 1024);
-f(1074790400, 1025);
-f(2146435072, 2047);
-f(2147483648, 2048);
-f(2148532224, 2049);
-f(4293918720, 4095);
-f(4294967296, 4096);
-f(4296015872, 4097);
-f(8588886016, 8191);
-f(8589934592, 8192);
-f(8590983168, 8193);
-f(17178820608, 16383);
-f(17179869184, 16384);
-f(17180917760, 16385);
-f(34358689792, 32767);
-f(34359738368, 32768);
-f(34360786944, 32769);
-f(68718428160, 65535);
-f(68719476736, 65536);
-f(68720525312, 65537);
-f(137437904896, 131071);
-f(137438953472, 131072);
-f(137440002048, 131073);
-f(274876858368, 262143);
-f(274877906944, 262144);
-f(274878955520, 262145);
-f(549754765312, 524287);
-f(549755813888, 524288);
-f(549756862464, 524289);
-f(1099510579200, 1048575);
-f(1099511627776, 1048576);
-x = 1048577;
-f(0, 0);
-f(1048577, 1);
-f(2097154, 2);
-f(3145731, 3);
-f(4194308, 4);
-f(5242885, 5);
-f(7340039, 7);
-f(8388616, 8);
-f(9437193, 9);
-f(15728655, 15);
-f(16777232, 16);
-f(17825809, 17);
-f(32505887, 31);
-f(33554464, 32);
-f(34603041, 33);
-f(66060351, 63);
-f(67108928, 64);
-f(68157505, 65);
-f(133169279, 127);
-f(134217856, 128);
-f(135266433, 129);
-f(267387135, 255);
-f(268435712, 256);
-f(269484289, 257);
-f(535822847, 511);
-f(536871424, 512);
-f(537920001, 513);
-f(1072694271, 1023);
-f(1073742848, 1024);
-f(1074791425, 1025);
-f(2146437119, 2047);
-f(2147485696, 2048);
-f(2148534273, 2049);
-f(4293922815, 4095);
-f(4294971392, 4096);
-f(4296019969, 4097);
-f(8588894207, 8191);
-f(8589942784, 8192);
-f(8590991361, 8193);
-f(17178836991, 16383);
-f(17179885568, 16384);
-f(17180934145, 16385);
-f(34358722559, 32767);
-f(34359771136, 32768);
-f(34360819713, 32769);
-f(68718493695, 65535);
-f(68719542272, 65536);
-f(68720590849, 65537);
-f(137438035967, 131071);
-f(137439084544, 131072);
-f(137440133121, 131073);
-f(274877120511, 262143);
-f(274878169088, 262144);
-f(274879217665, 262145);
-f(549755289599, 524287);
-f(549756338176, 524288);
-f(549757386753, 524289);
-f(1099511627775, 1048575);
-f(1099512676352, 1048576);
-f(1099513724929, 1048577);
-x = 2097151;
-f(0, 0);
-f(2097151, 1);
-f(4194302, 2);
-f(6291453, 3);
-f(8388604, 4);
-f(10485755, 5);
-f(14680057, 7);
-f(16777208, 8);
-f(18874359, 9);
-f(31457265, 15);
-f(33554416, 16);
-f(35651567, 17);
-f(65011681, 31);
-f(67108832, 32);
-f(69205983, 33);
-f(132120513, 63);
-f(134217664, 64);
-f(136314815, 65);
-f(266338177, 127);
-f(268435328, 128);
-f(270532479, 129);
-f(534773505, 255);
-f(536870656, 256);
-f(538967807, 257);
-f(1071644161, 511);
-f(1073741312, 512);
-f(1075838463, 513);
-f(2145385473, 1023);
-f(2147482624, 1024);
-f(2149579775, 1025);
-f(4292868097, 2047);
-f(4294965248, 2048);
-f(4297062399, 2049);
-f(8587833345, 4095);
-f(8589930496, 4096);
-f(8592027647, 4097);
-f(17177763841, 8191);
-f(17179860992, 8192);
-f(17181958143, 8193);
-f(34357624833, 16383);
-f(34359721984, 16384);
-f(34361819135, 16385);
-f(68717346817, 32767);
-f(68719443968, 32768);
-f(68721541119, 32769);
-f(137436790785, 65535);
-f(137438887936, 65536);
-f(137440985087, 65537);
-f(274875678721, 131071);
-f(274877775872, 131072);
-f(274879873023, 131073);
-f(549753454593, 262143);
-f(549755551744, 262144);
-f(549757648895, 262145);
-f(1099509006337, 524287);
-f(1099511103488, 524288);
-f(1099513200639, 524289);
-f(2199020109825, 1048575);
-f(2199022206976, 1048576);
-f(2199024304127, 1048577);
-f(4398042316801, 2097151);
-x = 2097152;
-f(0, 0);
-f(2097152, 1);
-f(4194304, 2);
-f(6291456, 3);
-f(8388608, 4);
-f(10485760, 5);
-f(14680064, 7);
-f(16777216, 8);
-f(18874368, 9);
-f(31457280, 15);
-f(33554432, 16);
-f(35651584, 17);
-f(65011712, 31);
-f(67108864, 32);
-f(69206016, 33);
-f(132120576, 63);
-f(134217728, 64);
-f(136314880, 65);
-f(266338304, 127);
-f(268435456, 128);
-f(270532608, 129);
-f(534773760, 255);
-f(536870912, 256);
-f(538968064, 257);
-f(1071644672, 511);
-f(1073741824, 512);
-f(1075838976, 513);
-f(2145386496, 1023);
-f(2147483648, 1024);
-f(2149580800, 1025);
-f(4292870144, 2047);
-f(4294967296, 2048);
-f(4297064448, 2049);
-f(8587837440, 4095);
-f(8589934592, 4096);
-f(8592031744, 4097);
-f(17177772032, 8191);
-f(17179869184, 8192);
-f(17181966336, 8193);
-f(34357641216, 16383);
-f(34359738368, 16384);
-f(34361835520, 16385);
-f(68717379584, 32767);
-f(68719476736, 32768);
-f(68721573888, 32769);
-f(137436856320, 65535);
-f(137438953472, 65536);
-f(137441050624, 65537);
-f(274875809792, 131071);
-f(274877906944, 131072);
-f(274880004096, 131073);
-f(549753716736, 262143);
-f(549755813888, 262144);
-f(549757911040, 262145);
-f(1099509530624, 524287);
-f(1099511627776, 524288);
-f(1099513724928, 524289);
-f(2199021158400, 1048575);
-f(2199023255552, 1048576);
-f(2199025352704, 1048577);
-f(4398044413952, 2097151);
-f(4398046511104, 2097152);
-x = 2097153;
-f(0, 0);
-f(2097153, 1);
-f(4194306, 2);
-f(6291459, 3);
-f(8388612, 4);
-f(10485765, 5);
-f(14680071, 7);
-f(16777224, 8);
-f(18874377, 9);
-f(31457295, 15);
-f(33554448, 16);
-f(35651601, 17);
-f(65011743, 31);
-f(67108896, 32);
-f(69206049, 33);
-f(132120639, 63);
-f(134217792, 64);
-f(136314945, 65);
-f(266338431, 127);
-f(268435584, 128);
-f(270532737, 129);
-f(534774015, 255);
-f(536871168, 256);
-f(538968321, 257);
-f(1071645183, 511);
-f(1073742336, 512);
-f(1075839489, 513);
-f(2145387519, 1023);
-f(2147484672, 1024);
-f(2149581825, 1025);
-f(4292872191, 2047);
-f(4294969344, 2048);
-f(4297066497, 2049);
-f(8587841535, 4095);
-f(8589938688, 4096);
-f(8592035841, 4097);
-f(17177780223, 8191);
-f(17179877376, 8192);
-f(17181974529, 8193);
-f(34357657599, 16383);
-f(34359754752, 16384);
-f(34361851905, 16385);
-f(68717412351, 32767);
-f(68719509504, 32768);
-f(68721606657, 32769);
-f(137436921855, 65535);
-f(137439019008, 65536);
-f(137441116161, 65537);
-f(274875940863, 131071);
-f(274878038016, 131072);
-f(274880135169, 131073);
-f(549753978879, 262143);
-f(549756076032, 262144);
-f(549758173185, 262145);
-f(1099510054911, 524287);
-f(1099512152064, 524288);
-f(1099514249217, 524289);
-f(2199022206975, 1048575);
-f(2199024304128, 1048576);
-f(2199026401281, 1048577);
-f(4398046511103, 2097151);
-f(4398048608256, 2097152);
-f(4398050705409, 2097153);
-x = 4194303;
-f(0, 0);
-f(4194303, 1);
-f(8388606, 2);
-f(12582909, 3);
-f(16777212, 4);
-f(20971515, 5);
-f(29360121, 7);
-f(33554424, 8);
-f(37748727, 9);
-f(62914545, 15);
-f(67108848, 16);
-f(71303151, 17);
-f(130023393, 31);
-f(134217696, 32);
-f(138411999, 33);
-f(264241089, 63);
-f(268435392, 64);
-f(272629695, 65);
-f(532676481, 127);
-f(536870784, 128);
-f(541065087, 129);
-f(1069547265, 255);
-f(1073741568, 256);
-f(1077935871, 257);
-f(2143288833, 511);
-f(2147483136, 512);
-f(2151677439, 513);
-f(4290771969, 1023);
-f(4294966272, 1024);
-f(4299160575, 1025);
-f(8585738241, 2047);
-f(8589932544, 2048);
-f(8594126847, 2049);
-f(17175670785, 4095);
-f(17179865088, 4096);
-f(17184059391, 4097);
-f(34355535873, 8191);
-f(34359730176, 8192);
-f(34363924479, 8193);
-f(68715266049, 16383);
-f(68719460352, 16384);
-f(68723654655, 16385);
-f(137434726401, 32767);
-f(137438920704, 32768);
-f(137443115007, 32769);
-f(274873647105, 65535);
-f(274877841408, 65536);
-f(274882035711, 65537);
-f(549751488513, 131071);
-f(549755682816, 131072);
-f(549759877119, 131073);
-f(1099507171329, 262143);
-f(1099511365632, 262144);
-f(1099515559935, 262145);
-f(2199018536961, 524287);
-f(2199022731264, 524288);
-f(2199026925567, 524289);
-f(4398041268225, 1048575);
-f(4398045462528, 1048576);
-f(4398049656831, 1048577);
-f(8796086730753, 2097151);
-f(8796090925056, 2097152);
-f(8796095119359, 2097153);
-f(17592177655809, 4194303);
-x = 4194304;
-f(0, 0);
-f(4194304, 1);
-f(8388608, 2);
-f(12582912, 3);
-f(16777216, 4);
-f(20971520, 5);
-f(29360128, 7);
-f(33554432, 8);
-f(37748736, 9);
-f(62914560, 15);
-f(67108864, 16);
-f(71303168, 17);
-f(130023424, 31);
-f(134217728, 32);
-f(138412032, 33);
-f(264241152, 63);
-f(268435456, 64);
-f(272629760, 65);
-f(532676608, 127);
-f(536870912, 128);
-f(541065216, 129);
-f(1069547520, 255);
-f(1073741824, 256);
-f(1077936128, 257);
-f(2143289344, 511);
-f(2147483648, 512);
-f(2151677952, 513);
-f(4290772992, 1023);
-f(4294967296, 1024);
-f(4299161600, 1025);
-f(8585740288, 2047);
-f(8589934592, 2048);
-f(8594128896, 2049);
-f(17175674880, 4095);
-f(17179869184, 4096);
-f(17184063488, 4097);
-f(34355544064, 8191);
-f(34359738368, 8192);
-f(34363932672, 8193);
-f(68715282432, 16383);
-f(68719476736, 16384);
-f(68723671040, 16385);
-f(137434759168, 32767);
-f(137438953472, 32768);
-f(137443147776, 32769);
-f(274873712640, 65535);
-f(274877906944, 65536);
-f(274882101248, 65537);
-f(549751619584, 131071);
-f(549755813888, 131072);
-f(549760008192, 131073);
-f(1099507433472, 262143);
-f(1099511627776, 262144);
-f(1099515822080, 262145);
-f(2199019061248, 524287);
-f(2199023255552, 524288);
-f(2199027449856, 524289);
-f(4398042316800, 1048575);
-f(4398046511104, 1048576);
-f(4398050705408, 1048577);
-f(8796088827904, 2097151);
-f(8796093022208, 2097152);
-f(8796097216512, 2097153);
-f(17592181850112, 4194303);
-f(17592186044416, 4194304);
-x = 4194305;
-f(0, 0);
-f(4194305, 1);
-f(8388610, 2);
-f(12582915, 3);
-f(16777220, 4);
-f(20971525, 5);
-f(29360135, 7);
-f(33554440, 8);
-f(37748745, 9);
-f(62914575, 15);
-f(67108880, 16);
-f(71303185, 17);
-f(130023455, 31);
-f(134217760, 32);
-f(138412065, 33);
-f(264241215, 63);
-f(268435520, 64);
-f(272629825, 65);
-f(532676735, 127);
-f(536871040, 128);
-f(541065345, 129);
-f(1069547775, 255);
-f(1073742080, 256);
-f(1077936385, 257);
-f(2143289855, 511);
-f(2147484160, 512);
-f(2151678465, 513);
-f(4290774015, 1023);
-f(4294968320, 1024);
-f(4299162625, 1025);
-f(8585742335, 2047);
-f(8589936640, 2048);
-f(8594130945, 2049);
-f(17175678975, 4095);
-f(17179873280, 4096);
-f(17184067585, 4097);
-f(34355552255, 8191);
-f(34359746560, 8192);
-f(34363940865, 8193);
-f(68715298815, 16383);
-f(68719493120, 16384);
-f(68723687425, 16385);
-f(137434791935, 32767);
-f(137438986240, 32768);
-f(137443180545, 32769);
-f(274873778175, 65535);
-f(274877972480, 65536);
-f(274882166785, 65537);
-f(549751750655, 131071);
-f(549755944960, 131072);
-f(549760139265, 131073);
-f(1099507695615, 262143);
-f(1099511889920, 262144);
-f(1099516084225, 262145);
-f(2199019585535, 524287);
-f(2199023779840, 524288);
-f(2199027974145, 524289);
-f(4398043365375, 1048575);
-f(4398047559680, 1048576);
-f(4398051753985, 1048577);
-f(8796090925055, 2097151);
-f(8796095119360, 2097152);
-f(8796099313665, 2097153);
-f(17592186044415, 4194303);
-f(17592190238720, 4194304);
-f(17592194433025, 4194305);
-x = 8388607;
-f(0, 0);
-f(8388607, 1);
-f(16777214, 2);
-f(25165821, 3);
-f(33554428, 4);
-f(41943035, 5);
-f(58720249, 7);
-f(67108856, 8);
-f(75497463, 9);
-f(125829105, 15);
-f(134217712, 16);
-f(142606319, 17);
-f(260046817, 31);
-f(268435424, 32);
-f(276824031, 33);
-f(528482241, 63);
-f(536870848, 64);
-f(545259455, 65);
-f(1065353089, 127);
-f(1073741696, 128);
-f(1082130303, 129);
-f(2139094785, 255);
-f(2147483392, 256);
-f(2155871999, 257);
-f(4286578177, 511);
-f(4294966784, 512);
-f(4303355391, 513);
-f(8581544961, 1023);
-f(8589933568, 1024);
-f(8598322175, 1025);
-f(17171478529, 2047);
-f(17179867136, 2048);
-f(17188255743, 2049);
-f(34351345665, 4095);
-f(34359734272, 4096);
-f(34368122879, 4097);
-f(68711079937, 8191);
-f(68719468544, 8192);
-f(68727857151, 8193);
-f(137430548481, 16383);
-f(137438937088, 16384);
-f(137447325695, 16385);
-f(274869485569, 32767);
-f(274877874176, 32768);
-f(274886262783, 32769);
-f(549747359745, 65535);
-f(549755748352, 65536);
-f(549764136959, 65537);
-f(1099503108097, 131071);
-f(1099511496704, 131072);
-f(1099519885311, 131073);
-f(2199014604801, 262143);
-f(2199022993408, 262144);
-f(2199031382015, 262145);
-f(4398037598209, 524287);
-f(4398045986816, 524288);
-f(4398054375423, 524289);
-f(8796083585025, 1048575);
-f(8796091973632, 1048576);
-f(8796100362239, 1048577);
-f(17592175558657, 2097151);
-f(17592183947264, 2097152);
-f(17592192335871, 2097153);
-f(35184359505921, 4194303);
-f(35184367894528, 4194304);
-f(35184376283135, 4194305);
-f(70368727400449, 8388607);
-x = 8388608;
-f(0, 0);
-f(8388608, 1);
-f(16777216, 2);
-f(25165824, 3);
-f(33554432, 4);
-f(41943040, 5);
-f(58720256, 7);
-f(67108864, 8);
-f(75497472, 9);
-f(125829120, 15);
-f(134217728, 16);
-f(142606336, 17);
-f(260046848, 31);
-f(268435456, 32);
-f(276824064, 33);
-f(528482304, 63);
-f(536870912, 64);
-f(545259520, 65);
-f(1065353216, 127);
-f(1073741824, 128);
-f(1082130432, 129);
-f(2139095040, 255);
-f(2147483648, 256);
-f(2155872256, 257);
-f(4286578688, 511);
-f(4294967296, 512);
-f(4303355904, 513);
-f(8581545984, 1023);
-f(8589934592, 1024);
-f(8598323200, 1025);
-f(17171480576, 2047);
-f(17179869184, 2048);
-f(17188257792, 2049);
-f(34351349760, 4095);
-f(34359738368, 4096);
-f(34368126976, 4097);
-f(68711088128, 8191);
-f(68719476736, 8192);
-f(68727865344, 8193);
-f(137430564864, 16383);
-f(137438953472, 16384);
-f(137447342080, 16385);
-f(274869518336, 32767);
-f(274877906944, 32768);
-f(274886295552, 32769);
-f(549747425280, 65535);
-f(549755813888, 65536);
-f(549764202496, 65537);
-f(1099503239168, 131071);
-f(1099511627776, 131072);
-f(1099520016384, 131073);
-f(2199014866944, 262143);
-f(2199023255552, 262144);
-f(2199031644160, 262145);
-f(4398038122496, 524287);
-f(4398046511104, 524288);
-f(4398054899712, 524289);
-f(8796084633600, 1048575);
-f(8796093022208, 1048576);
-f(8796101410816, 1048577);
-f(17592177655808, 2097151);
-f(17592186044416, 2097152);
-f(17592194433024, 2097153);
-f(35184363700224, 4194303);
-f(35184372088832, 4194304);
-f(35184380477440, 4194305);
-f(70368735789056, 8388607);
-f(70368744177664, 8388608);
-x = 8388609;
-f(0, 0);
-f(8388609, 1);
-f(16777218, 2);
-f(25165827, 3);
-f(33554436, 4);
-f(41943045, 5);
-f(58720263, 7);
-f(67108872, 8);
-f(75497481, 9);
-f(125829135, 15);
-f(134217744, 16);
-f(142606353, 17);
-f(260046879, 31);
-f(268435488, 32);
-f(276824097, 33);
-f(528482367, 63);
-f(536870976, 64);
-f(545259585, 65);
-f(1065353343, 127);
-f(1073741952, 128);
-f(1082130561, 129);
-f(2139095295, 255);
-f(2147483904, 256);
-f(2155872513, 257);
-f(4286579199, 511);
-f(4294967808, 512);
-f(4303356417, 513);
-f(8581547007, 1023);
-f(8589935616, 1024);
-f(8598324225, 1025);
-f(17171482623, 2047);
-f(17179871232, 2048);
-f(17188259841, 2049);
-f(34351353855, 4095);
-f(34359742464, 4096);
-f(34368131073, 4097);
-f(68711096319, 8191);
-f(68719484928, 8192);
-f(68727873537, 8193);
-f(137430581247, 16383);
-f(137438969856, 16384);
-f(137447358465, 16385);
-f(274869551103, 32767);
-f(274877939712, 32768);
-f(274886328321, 32769);
-f(549747490815, 65535);
-f(549755879424, 65536);
-f(549764268033, 65537);
-f(1099503370239, 131071);
-f(1099511758848, 131072);
-f(1099520147457, 131073);
-f(2199015129087, 262143);
-f(2199023517696, 262144);
-f(2199031906305, 262145);
-f(4398038646783, 524287);
-f(4398047035392, 524288);
-f(4398055424001, 524289);
-f(8796085682175, 1048575);
-f(8796094070784, 1048576);
-f(8796102459393, 1048577);
-f(17592179752959, 2097151);
-f(17592188141568, 2097152);
-f(17592196530177, 2097153);
-f(35184367894527, 4194303);
-f(35184376283136, 4194304);
-f(35184384671745, 4194305);
-f(70368744177663, 8388607);
-f(70368752566272, 8388608);
-f(70368760954881, 8388609);
-x = 16777215;
-f(0, 0);
-f(16777215, 1);
-f(33554430, 2);
-f(50331645, 3);
-f(67108860, 4);
-f(83886075, 5);
-f(117440505, 7);
-f(134217720, 8);
-f(150994935, 9);
-f(251658225, 15);
-f(268435440, 16);
-f(285212655, 17);
-f(520093665, 31);
-f(536870880, 32);
-f(553648095, 33);
-f(1056964545, 63);
-f(1073741760, 64);
-f(1090518975, 65);
-f(2130706305, 127);
-f(2147483520, 128);
-f(2164260735, 129);
-f(4278189825, 255);
-f(4294967040, 256);
-f(4311744255, 257);
-f(8573156865, 511);
-f(8589934080, 512);
-f(8606711295, 513);
-f(17163090945, 1023);
-f(17179868160, 1024);
-f(17196645375, 1025);
-f(34342959105, 2047);
-f(34359736320, 2048);
-f(34376513535, 2049);
-f(68702695425, 4095);
-f(68719472640, 4096);
-f(68736249855, 4097);
-f(137422168065, 8191);
-f(137438945280, 8192);
-f(137455722495, 8193);
-f(274861113345, 16383);
-f(274877890560, 16384);
-f(274894667775, 16385);
-f(549739003905, 32767);
-f(549755781120, 32768);
-f(549772558335, 32769);
-f(1099494785025, 65535);
-f(1099511562240, 65536);
-f(1099528339455, 65537);
-f(2199006347265, 131071);
-f(2199023124480, 131072);
-f(2199039901695, 131073);
-f(4398029471745, 262143);
-f(4398046248960, 262144);
-f(4398063026175, 262145);
-f(8796075720705, 524287);
-f(8796092497920, 524288);
-f(8796109275135, 524289);
-f(17592168218625, 1048575);
-f(17592184995840, 1048576);
-f(17592201773055, 1048577);
-f(35184353214465, 2097151);
-f(35184369991680, 2097152);
-f(35184386768895, 2097153);
-f(70368723206145, 4194303);
-f(70368739983360, 4194304);
-f(70368756760575, 4194305);
-f(140737463189505, 8388607);
-f(140737479966720, 8388608);
-f(140737496743935, 8388609);
-f(281474943156225, 16777215);
-x = 16777216;
-f(0, 0);
-f(16777216, 1);
-f(33554432, 2);
-f(50331648, 3);
-f(67108864, 4);
-f(83886080, 5);
-f(117440512, 7);
-f(134217728, 8);
-f(150994944, 9);
-f(251658240, 15);
-f(268435456, 16);
-f(285212672, 17);
-f(520093696, 31);
-f(536870912, 32);
-f(553648128, 33);
-f(1056964608, 63);
-f(1073741824, 64);
-f(1090519040, 65);
-f(2130706432, 127);
-f(2147483648, 128);
-f(2164260864, 129);
-f(4278190080, 255);
-f(4294967296, 256);
-f(4311744512, 257);
-f(8573157376, 511);
-f(8589934592, 512);
-f(8606711808, 513);
-f(17163091968, 1023);
-f(17179869184, 1024);
-f(17196646400, 1025);
-f(34342961152, 2047);
-f(34359738368, 2048);
-f(34376515584, 2049);
-f(68702699520, 4095);
-f(68719476736, 4096);
-f(68736253952, 4097);
-f(137422176256, 8191);
-f(137438953472, 8192);
-f(137455730688, 8193);
-f(274861129728, 16383);
-f(274877906944, 16384);
-f(274894684160, 16385);
-f(549739036672, 32767);
-f(549755813888, 32768);
-f(549772591104, 32769);
-f(1099494850560, 65535);
-f(1099511627776, 65536);
-f(1099528404992, 65537);
-f(2199006478336, 131071);
-f(2199023255552, 131072);
-f(2199040032768, 131073);
-f(4398029733888, 262143);
-f(4398046511104, 262144);
-f(4398063288320, 262145);
-f(8796076244992, 524287);
-f(8796093022208, 524288);
-f(8796109799424, 524289);
-f(17592169267200, 1048575);
-f(17592186044416, 1048576);
-f(17592202821632, 1048577);
-f(35184355311616, 2097151);
-f(35184372088832, 2097152);
-f(35184388866048, 2097153);
-f(70368727400448, 4194303);
-f(70368744177664, 4194304);
-f(70368760954880, 4194305);
-f(140737471578112, 8388607);
-f(140737488355328, 8388608);
-f(140737505132544, 8388609);
-f(281474959933440, 16777215);
-f(281474976710656, 16777216);
-x = 16777217;
-f(0, 0);
-f(16777217, 1);
-f(33554434, 2);
-f(50331651, 3);
-f(67108868, 4);
-f(83886085, 5);
-f(117440519, 7);
-f(134217736, 8);
-f(150994953, 9);
-f(251658255, 15);
-f(268435472, 16);
-f(285212689, 17);
-f(520093727, 31);
-f(536870944, 32);
-f(553648161, 33);
-f(1056964671, 63);
-f(1073741888, 64);
-f(1090519105, 65);
-f(2130706559, 127);
-f(2147483776, 128);
-f(2164260993, 129);
-f(4278190335, 255);
-f(4294967552, 256);
-f(4311744769, 257);
-f(8573157887, 511);
-f(8589935104, 512);
-f(8606712321, 513);
-f(17163092991, 1023);
-f(17179870208, 1024);
-f(17196647425, 1025);
-f(34342963199, 2047);
-f(34359740416, 2048);
-f(34376517633, 2049);
-f(68702703615, 4095);
-f(68719480832, 4096);
-f(68736258049, 4097);
-f(137422184447, 8191);
-f(137438961664, 8192);
-f(137455738881, 8193);
-f(274861146111, 16383);
-f(274877923328, 16384);
-f(274894700545, 16385);
-f(549739069439, 32767);
-f(549755846656, 32768);
-f(549772623873, 32769);
-f(1099494916095, 65535);
-f(1099511693312, 65536);
-f(1099528470529, 65537);
-f(2199006609407, 131071);
-f(2199023386624, 131072);
-f(2199040163841, 131073);
-f(4398029996031, 262143);
-f(4398046773248, 262144);
-f(4398063550465, 262145);
-f(8796076769279, 524287);
-f(8796093546496, 524288);
-f(8796110323713, 524289);
-f(17592170315775, 1048575);
-f(17592187092992, 1048576);
-f(17592203870209, 1048577);
-f(35184357408767, 2097151);
-f(35184374185984, 2097152);
-f(35184390963201, 2097153);
-f(70368731594751, 4194303);
-f(70368748371968, 4194304);
-f(70368765149185, 4194305);
-f(140737479966719, 8388607);
-f(140737496743936, 8388608);
-f(140737513521153, 8388609);
-f(281474976710655, 16777215);
-f(281474993487872, 16777216);
-f(281475010265089, 16777217);
-x = 33554431;
-f(0, 0);
-f(33554431, 1);
-f(67108862, 2);
-f(100663293, 3);
-f(134217724, 4);
-f(167772155, 5);
-f(234881017, 7);
-f(268435448, 8);
-f(301989879, 9);
-f(503316465, 15);
-f(536870896, 16);
-f(570425327, 17);
-f(1040187361, 31);
-f(1073741792, 32);
-f(1107296223, 33);
-f(2113929153, 63);
-f(2147483584, 64);
-f(2181038015, 65);
-f(4261412737, 127);
-f(4294967168, 128);
-f(4328521599, 129);
-f(8556379905, 255);
-f(8589934336, 256);
-f(8623488767, 257);
-f(17146314241, 511);
-f(17179868672, 512);
-f(17213423103, 513);
-f(34326182913, 1023);
-f(34359737344, 1024);
-f(34393291775, 1025);
-f(68685920257, 2047);
-f(68719474688, 2048);
-f(68753029119, 2049);
-f(137405394945, 4095);
-f(137438949376, 4096);
-f(137472503807, 4097);
-f(274844344321, 8191);
-f(274877898752, 8192);
-f(274911453183, 8193);
-f(549722243073, 16383);
-f(549755797504, 16384);
-f(549789351935, 16385);
-f(1099478040577, 32767);
-f(1099511595008, 32768);
-f(1099545149439, 32769);
-f(2198989635585, 65535);
-f(2199023190016, 65536);
-f(2199056744447, 65537);
-f(4398012825601, 131071);
-f(4398046380032, 131072);
-f(4398079934463, 131073);
-f(8796059205633, 262143);
-f(8796092760064, 262144);
-f(8796126314495, 262145);
-f(17592151965697, 524287);
-f(17592185520128, 524288);
-f(17592219074559, 524289);
-f(35184337485825, 1048575);
-f(35184371040256, 1048576);
-f(35184404594687, 1048577);
-f(70368708526081, 2097151);
-f(70368742080512, 2097152);
-f(70368775634943, 2097153);
-f(140737450606593, 4194303);
-f(140737484161024, 4194304);
-f(140737517715455, 4194305);
-f(281474934767617, 8388607);
-f(281474968322048, 8388608);
-f(281475001876479, 8388609);
-f(562949903089665, 16777215);
-f(562949936644096, 16777216);
-f(562949970198527, 16777217);
-f(1125899839733761, 33554431);
-x = 33554432;
-f(0, 0);
-f(33554432, 1);
-f(67108864, 2);
-f(100663296, 3);
-f(134217728, 4);
-f(167772160, 5);
-f(234881024, 7);
-f(268435456, 8);
-f(301989888, 9);
-f(503316480, 15);
-f(536870912, 16);
-f(570425344, 17);
-f(1040187392, 31);
-f(1073741824, 32);
-f(1107296256, 33);
-f(2113929216, 63);
-f(2147483648, 64);
-f(2181038080, 65);
-f(4261412864, 127);
-f(4294967296, 128);
-f(4328521728, 129);
-f(8556380160, 255);
-f(8589934592, 256);
-f(8623489024, 257);
-f(17146314752, 511);
-f(17179869184, 512);
-f(17213423616, 513);
-f(34326183936, 1023);
-f(34359738368, 1024);
-f(34393292800, 1025);
-f(68685922304, 2047);
-f(68719476736, 2048);
-f(68753031168, 2049);
-f(137405399040, 4095);
-f(137438953472, 4096);
-f(137472507904, 4097);
-f(274844352512, 8191);
-f(274877906944, 8192);
-f(274911461376, 8193);
-f(549722259456, 16383);
-f(549755813888, 16384);
-f(549789368320, 16385);
-f(1099478073344, 32767);
-f(1099511627776, 32768);
-f(1099545182208, 32769);
-f(2198989701120, 65535);
-f(2199023255552, 65536);
-f(2199056809984, 65537);
-f(4398012956672, 131071);
-f(4398046511104, 131072);
-f(4398080065536, 131073);
-f(8796059467776, 262143);
-f(8796093022208, 262144);
-f(8796126576640, 262145);
-f(17592152489984, 524287);
-f(17592186044416, 524288);
-f(17592219598848, 524289);
-f(35184338534400, 1048575);
-f(35184372088832, 1048576);
-f(35184405643264, 1048577);
-f(70368710623232, 2097151);
-f(70368744177664, 2097152);
-f(70368777732096, 2097153);
-f(140737454800896, 4194303);
-f(140737488355328, 4194304);
-f(140737521909760, 4194305);
-f(281474943156224, 8388607);
-f(281474976710656, 8388608);
-f(281475010265088, 8388609);
-f(562949919866880, 16777215);
-f(562949953421312, 16777216);
-f(562949986975744, 16777217);
-f(1125899873288192, 33554431);
-f(1125899906842624, 33554432);
-x = 33554433;
-f(0, 0);
-f(33554433, 1);
-f(67108866, 2);
-f(100663299, 3);
-f(134217732, 4);
-f(167772165, 5);
-f(234881031, 7);
-f(268435464, 8);
-f(301989897, 9);
-f(503316495, 15);
-f(536870928, 16);
-f(570425361, 17);
-f(1040187423, 31);
-f(1073741856, 32);
-f(1107296289, 33);
-f(2113929279, 63);
-f(2147483712, 64);
-f(2181038145, 65);
-f(4261412991, 127);
-f(4294967424, 128);
-f(4328521857, 129);
-f(8556380415, 255);
-f(8589934848, 256);
-f(8623489281, 257);
-f(17146315263, 511);
-f(17179869696, 512);
-f(17213424129, 513);
-f(34326184959, 1023);
-f(34359739392, 1024);
-f(34393293825, 1025);
-f(68685924351, 2047);
-f(68719478784, 2048);
-f(68753033217, 2049);
-f(137405403135, 4095);
-f(137438957568, 4096);
-f(137472512001, 4097);
-f(274844360703, 8191);
-f(274877915136, 8192);
-f(274911469569, 8193);
-f(549722275839, 16383);
-f(549755830272, 16384);
-f(549789384705, 16385);
-f(1099478106111, 32767);
-f(1099511660544, 32768);
-f(1099545214977, 32769);
-f(2198989766655, 65535);
-f(2199023321088, 65536);
-f(2199056875521, 65537);
-f(4398013087743, 131071);
-f(4398046642176, 131072);
-f(4398080196609, 131073);
-f(8796059729919, 262143);
-f(8796093284352, 262144);
-f(8796126838785, 262145);
-f(17592153014271, 524287);
-f(17592186568704, 524288);
-f(17592220123137, 524289);
-f(35184339582975, 1048575);
-f(35184373137408, 1048576);
-f(35184406691841, 1048577);
-f(70368712720383, 2097151);
-f(70368746274816, 2097152);
-f(70368779829249, 2097153);
-f(140737458995199, 4194303);
-f(140737492549632, 4194304);
-f(140737526104065, 4194305);
-f(281474951544831, 8388607);
-f(281474985099264, 8388608);
-f(281475018653697, 8388609);
-f(562949936644095, 16777215);
-f(562949970198528, 16777216);
-f(562950003752961, 16777217);
-f(1125899906842623, 33554431);
-f(1125899940397056, 33554432);
-f(1125899973951489, 33554433);
-x = 67108863;
-f(0, 0);
-f(67108863, 1);
-f(134217726, 2);
-f(201326589, 3);
-f(268435452, 4);
-f(335544315, 5);
-f(469762041, 7);
-f(536870904, 8);
-f(603979767, 9);
-f(1006632945, 15);
-f(1073741808, 16);
-f(1140850671, 17);
-f(2080374753, 31);
-f(2147483616, 32);
-f(2214592479, 33);
-f(4227858369, 63);
-f(4294967232, 64);
-f(4362076095, 65);
-f(8522825601, 127);
-f(8589934464, 128);
-f(8657043327, 129);
-f(17112760065, 255);
-f(17179868928, 256);
-f(17246977791, 257);
-f(34292628993, 511);
-f(34359737856, 512);
-f(34426846719, 513);
-f(68652366849, 1023);
-f(68719475712, 1024);
-f(68786584575, 1025);
-f(137371842561, 2047);
-f(137438951424, 2048);
-f(137506060287, 2049);
-f(274810793985, 4095);
-f(274877902848, 4096);
-f(274945011711, 4097);
-f(549688696833, 8191);
-f(549755805696, 8192);
-f(549822914559, 8193);
-f(1099444502529, 16383);
-f(1099511611392, 16384);
-f(1099578720255, 16385);
-f(2198956113921, 32767);
-f(2199023222784, 32768);
-f(2199090331647, 32769);
-f(4397979336705, 65535);
-f(4398046445568, 65536);
-f(4398113554431, 65537);
-f(8796025782273, 131071);
-f(8796092891136, 131072);
-f(8796159999999, 131073);
-f(17592118673409, 262143);
-f(17592185782272, 262144);
-f(17592252891135, 262145);
-f(35184304455681, 524287);
-f(35184371564544, 524288);
-f(35184438673407, 524289);
-f(70368676020225, 1048575);
-f(70368743129088, 1048576);
-f(70368810237951, 1048577);
-f(140737419149313, 2097151);
-f(140737486258176, 2097152);
-f(140737553367039, 2097153);
-f(281474905407489, 4194303);
-f(281474972516352, 4194304);
-f(281475039625215, 4194305);
-f(562949877923841, 8388607);
-f(562949945032704, 8388608);
-f(562950012141567, 8388609);
-f(1125899822956545, 16777215);
-f(1125899890065408, 16777216);
-f(1125899957174271, 16777217);
-x = 67108864;
-f(0, 0);
-f(67108864, 1);
-f(134217728, 2);
-f(201326592, 3);
-f(268435456, 4);
-f(335544320, 5);
-f(469762048, 7);
-f(536870912, 8);
-f(603979776, 9);
-f(1006632960, 15);
-f(1073741824, 16);
-f(1140850688, 17);
-f(2080374784, 31);
-f(2147483648, 32);
-f(2214592512, 33);
-f(4227858432, 63);
-f(4294967296, 64);
-f(4362076160, 65);
-f(8522825728, 127);
-f(8589934592, 128);
-f(8657043456, 129);
-f(17112760320, 255);
-f(17179869184, 256);
-f(17246978048, 257);
-f(34292629504, 511);
-f(34359738368, 512);
-f(34426847232, 513);
-f(68652367872, 1023);
-f(68719476736, 1024);
-f(68786585600, 1025);
-f(137371844608, 2047);
-f(137438953472, 2048);
-f(137506062336, 2049);
-f(274810798080, 4095);
-f(274877906944, 4096);
-f(274945015808, 4097);
-f(549688705024, 8191);
-f(549755813888, 8192);
-f(549822922752, 8193);
-f(1099444518912, 16383);
-f(1099511627776, 16384);
-f(1099578736640, 16385);
-f(2198956146688, 32767);
-f(2199023255552, 32768);
-f(2199090364416, 32769);
-f(4397979402240, 65535);
-f(4398046511104, 65536);
-f(4398113619968, 65537);
-f(8796025913344, 131071);
-f(8796093022208, 131072);
-f(8796160131072, 131073);
-f(17592118935552, 262143);
-f(17592186044416, 262144);
-f(17592253153280, 262145);
-f(35184304979968, 524287);
-f(35184372088832, 524288);
-f(35184439197696, 524289);
-f(70368677068800, 1048575);
-f(70368744177664, 1048576);
-f(70368811286528, 1048577);
-f(140737421246464, 2097151);
-f(140737488355328, 2097152);
-f(140737555464192, 2097153);
-f(281474909601792, 4194303);
-f(281474976710656, 4194304);
-f(281475043819520, 4194305);
-f(562949886312448, 8388607);
-f(562949953421312, 8388608);
-f(562950020530176, 8388609);
-f(1125899839733760, 16777215);
-f(1125899906842624, 16777216);
-f(1125899973951488, 16777217);
-x = 67108865;
-f(0, 0);
-f(67108865, 1);
-f(134217730, 2);
-f(201326595, 3);
-f(268435460, 4);
-f(335544325, 5);
-f(469762055, 7);
-f(536870920, 8);
-f(603979785, 9);
-f(1006632975, 15);
-f(1073741840, 16);
-f(1140850705, 17);
-f(2080374815, 31);
-f(2147483680, 32);
-f(2214592545, 33);
-f(4227858495, 63);
-f(4294967360, 64);
-f(4362076225, 65);
-f(8522825855, 127);
-f(8589934720, 128);
-f(8657043585, 129);
-f(17112760575, 255);
-f(17179869440, 256);
-f(17246978305, 257);
-f(34292630015, 511);
-f(34359738880, 512);
-f(34426847745, 513);
-f(68652368895, 1023);
-f(68719477760, 1024);
-f(68786586625, 1025);
-f(137371846655, 2047);
-f(137438955520, 2048);
-f(137506064385, 2049);
-f(274810802175, 4095);
-f(274877911040, 4096);
-f(274945019905, 4097);
-f(549688713215, 8191);
-f(549755822080, 8192);
-f(549822930945, 8193);
-f(1099444535295, 16383);
-f(1099511644160, 16384);
-f(1099578753025, 16385);
-f(2198956179455, 32767);
-f(2199023288320, 32768);
-f(2199090397185, 32769);
-f(4397979467775, 65535);
-f(4398046576640, 65536);
-f(4398113685505, 65537);
-f(8796026044415, 131071);
-f(8796093153280, 131072);
-f(8796160262145, 131073);
-f(17592119197695, 262143);
-f(17592186306560, 262144);
-f(17592253415425, 262145);
-f(35184305504255, 524287);
-f(35184372613120, 524288);
-f(35184439721985, 524289);
-f(70368678117375, 1048575);
-f(70368745226240, 1048576);
-f(70368812335105, 1048577);
-f(140737423343615, 2097151);
-f(140737490452480, 2097152);
-f(140737557561345, 2097153);
-f(281474913796095, 4194303);
-f(281474980904960, 4194304);
-f(281475048013825, 4194305);
-f(562949894701055, 8388607);
-f(562949961809920, 8388608);
-f(562950028918785, 8388609);
-f(1125899856510975, 16777215);
-f(1125899923619840, 16777216);
-f(1125899990728705, 16777217);
-x = 134217727;
-f(0, 0);
-f(134217727, 1);
-f(268435454, 2);
-f(402653181, 3);
-f(536870908, 4);
-f(671088635, 5);
-f(939524089, 7);
-f(1073741816, 8);
-f(1207959543, 9);
-f(2013265905, 15);
-f(2147483632, 16);
-f(2281701359, 17);
-f(4160749537, 31);
-f(4294967264, 32);
-f(4429184991, 33);
-f(8455716801, 63);
-f(8589934528, 64);
-f(8724152255, 65);
-f(17045651329, 127);
-f(17179869056, 128);
-f(17314086783, 129);
-f(34225520385, 255);
-f(34359738112, 256);
-f(34493955839, 257);
-f(68585258497, 511);
-f(68719476224, 512);
-f(68853693951, 513);
-f(137304734721, 1023);
-f(137438952448, 1024);
-f(137573170175, 1025);
-f(274743687169, 2047);
-f(274877904896, 2048);
-f(275012122623, 2049);
-f(549621592065, 4095);
-f(549755809792, 4096);
-f(549890027519, 4097);
-f(1099377401857, 8191);
-f(1099511619584, 8192);
-f(1099645837311, 8193);
-f(2198889021441, 16383);
-f(2199023239168, 16384);
-f(2199157456895, 16385);
-f(4397912260609, 32767);
-f(4398046478336, 32768);
-f(4398180696063, 32769);
-f(8795958738945, 65535);
-f(8796092956672, 65536);
-f(8796227174399, 65537);
-f(17592051695617, 131071);
-f(17592185913344, 131072);
-f(17592320131071, 131073);
-f(35184237608961, 262143);
-f(35184371826688, 262144);
-f(35184506044415, 262145);
-f(70368609435649, 524287);
-f(70368743653376, 524288);
-f(70368877871103, 524289);
-f(140737353089025, 1048575);
-f(140737487306752, 1048576);
-f(140737621524479, 1048577);
-f(281474840395777, 2097151);
-f(281474974613504, 2097152);
-f(281475108831231, 2097153);
-f(562949815009281, 4194303);
-f(562949949227008, 4194304);
-f(562950083444735, 4194305);
-f(1125899764236289, 8388607);
-f(1125899898454016, 8388608);
-f(1125900032671743, 8388609);
-x = 134217728;
-f(0, 0);
-f(134217728, 1);
-f(268435456, 2);
-f(402653184, 3);
-f(536870912, 4);
-f(671088640, 5);
-f(939524096, 7);
-f(1073741824, 8);
-f(1207959552, 9);
-f(2013265920, 15);
-f(2147483648, 16);
-f(2281701376, 17);
-f(4160749568, 31);
-f(4294967296, 32);
-f(4429185024, 33);
-f(8455716864, 63);
-f(8589934592, 64);
-f(8724152320, 65);
-f(17045651456, 127);
-f(17179869184, 128);
-f(17314086912, 129);
-f(34225520640, 255);
-f(34359738368, 256);
-f(34493956096, 257);
-f(68585259008, 511);
-f(68719476736, 512);
-f(68853694464, 513);
-f(137304735744, 1023);
-f(137438953472, 1024);
-f(137573171200, 1025);
-f(274743689216, 2047);
-f(274877906944, 2048);
-f(275012124672, 2049);
-f(549621596160, 4095);
-f(549755813888, 4096);
-f(549890031616, 4097);
-f(1099377410048, 8191);
-f(1099511627776, 8192);
-f(1099645845504, 8193);
-f(2198889037824, 16383);
-f(2199023255552, 16384);
-f(2199157473280, 16385);
-f(4397912293376, 32767);
-f(4398046511104, 32768);
-f(4398180728832, 32769);
-f(8795958804480, 65535);
-f(8796093022208, 65536);
-f(8796227239936, 65537);
-f(17592051826688, 131071);
-f(17592186044416, 131072);
-f(17592320262144, 131073);
-f(35184237871104, 262143);
-f(35184372088832, 262144);
-f(35184506306560, 262145);
-f(70368609959936, 524287);
-f(70368744177664, 524288);
-f(70368878395392, 524289);
-f(140737354137600, 1048575);
-f(140737488355328, 1048576);
-f(140737622573056, 1048577);
-f(281474842492928, 2097151);
-f(281474976710656, 2097152);
-f(281475110928384, 2097153);
-f(562949819203584, 4194303);
-f(562949953421312, 4194304);
-f(562950087639040, 4194305);
-f(1125899772624896, 8388607);
-f(1125899906842624, 8388608);
-f(1125900041060352, 8388609);
-x = 134217729;
-f(0, 0);
-f(134217729, 1);
-f(268435458, 2);
-f(402653187, 3);
-f(536870916, 4);
-f(671088645, 5);
-f(939524103, 7);
-f(1073741832, 8);
-f(1207959561, 9);
-f(2013265935, 15);
-f(2147483664, 16);
-f(2281701393, 17);
-f(4160749599, 31);
-f(4294967328, 32);
-f(4429185057, 33);
-f(8455716927, 63);
-f(8589934656, 64);
-f(8724152385, 65);
-f(17045651583, 127);
-f(17179869312, 128);
-f(17314087041, 129);
-f(34225520895, 255);
-f(34359738624, 256);
-f(34493956353, 257);
-f(68585259519, 511);
-f(68719477248, 512);
-f(68853694977, 513);
-f(137304736767, 1023);
-f(137438954496, 1024);
-f(137573172225, 1025);
-f(274743691263, 2047);
-f(274877908992, 2048);
-f(275012126721, 2049);
-f(549621600255, 4095);
-f(549755817984, 4096);
-f(549890035713, 4097);
-f(1099377418239, 8191);
-f(1099511635968, 8192);
-f(1099645853697, 8193);
-f(2198889054207, 16383);
-f(2199023271936, 16384);
-f(2199157489665, 16385);
-f(4397912326143, 32767);
-f(4398046543872, 32768);
-f(4398180761601, 32769);
-f(8795958870015, 65535);
-f(8796093087744, 65536);
-f(8796227305473, 65537);
-f(17592051957759, 131071);
-f(17592186175488, 131072);
-f(17592320393217, 131073);
-f(35184238133247, 262143);
-f(35184372350976, 262144);
-f(35184506568705, 262145);
-f(70368610484223, 524287);
-f(70368744701952, 524288);
-f(70368878919681, 524289);
-f(140737355186175, 1048575);
-f(140737489403904, 1048576);
-f(140737623621633, 1048577);
-f(281474844590079, 2097151);
-f(281474978807808, 2097152);
-f(281475113025537, 2097153);
-f(562949823397887, 4194303);
-f(562949957615616, 4194304);
-f(562950091833345, 4194305);
-f(1125899781013503, 8388607);
-f(1125899915231232, 8388608);
-f(1125900049448961, 8388609);
-x = 268435455;
-f(0, 0);
-f(268435455, 1);
-f(536870910, 2);
-f(805306365, 3);
-f(1073741820, 4);
-f(1342177275, 5);
-f(1879048185, 7);
-f(2147483640, 8);
-f(2415919095, 9);
-f(4026531825, 15);
-f(4294967280, 16);
-f(4563402735, 17);
-f(8321499105, 31);
-f(8589934560, 32);
-f(8858370015, 33);
-f(16911433665, 63);
-f(17179869120, 64);
-f(17448304575, 65);
-f(34091302785, 127);
-f(34359738240, 128);
-f(34628173695, 129);
-f(68451041025, 255);
-f(68719476480, 256);
-f(68987911935, 257);
-f(137170517505, 511);
-f(137438952960, 512);
-f(137707388415, 513);
-f(274609470465, 1023);
-f(274877905920, 1024);
-f(275146341375, 1025);
-f(549487376385, 2047);
-f(549755811840, 2048);
-f(550024247295, 2049);
-f(1099243188225, 4095);
-f(1099511623680, 4096);
-f(1099780059135, 4097);
-f(2198754811905, 8191);
-f(2199023247360, 8192);
-f(2199291682815, 8193);
-f(4397778059265, 16383);
-f(4398046494720, 16384);
-f(4398314930175, 16385);
-f(8795824553985, 32767);
-f(8796092989440, 32768);
-f(8796361424895, 32769);
-f(17591917543425, 65535);
-f(17592185978880, 65536);
-f(17592454414335, 65537);
-f(35184103522305, 131071);
-f(35184371957760, 131072);
-f(35184640393215, 131073);
-f(70368475480065, 262143);
-f(70368743915520, 262144);
-f(70369012350975, 262145);
-f(140737219395585, 524287);
-f(140737487831040, 524288);
-f(140737756266495, 524289);
-f(281474707226625, 1048575);
-f(281474975662080, 1048576);
-f(281475244097535, 1048577);
-f(562949682888705, 2097151);
-f(562949951324160, 2097152);
-f(562950219759615, 2097153);
-f(1125899634212865, 4194303);
-f(1125899902648320, 4194304);
-f(1125900171083775, 4194305);
-x = 268435456;
-f(0, 0);
-f(268435456, 1);
-f(536870912, 2);
-f(805306368, 3);
-f(1073741824, 4);
-f(1342177280, 5);
-f(1879048192, 7);
-f(2147483648, 8);
-f(2415919104, 9);
-f(4026531840, 15);
-f(4294967296, 16);
-f(4563402752, 17);
-f(8321499136, 31);
-f(8589934592, 32);
-f(8858370048, 33);
-f(16911433728, 63);
-f(17179869184, 64);
-f(17448304640, 65);
-f(34091302912, 127);
-f(34359738368, 128);
-f(34628173824, 129);
-f(68451041280, 255);
-f(68719476736, 256);
-f(68987912192, 257);
-f(137170518016, 511);
-f(137438953472, 512);
-f(137707388928, 513);
-f(274609471488, 1023);
-f(274877906944, 1024);
-f(275146342400, 1025);
-f(549487378432, 2047);
-f(549755813888, 2048);
-f(550024249344, 2049);
-f(1099243192320, 4095);
-f(1099511627776, 4096);
-f(1099780063232, 4097);
-f(2198754820096, 8191);
-f(2199023255552, 8192);
-f(2199291691008, 8193);
-f(4397778075648, 16383);
-f(4398046511104, 16384);
-f(4398314946560, 16385);
-f(8795824586752, 32767);
-f(8796093022208, 32768);
-f(8796361457664, 32769);
-f(17591917608960, 65535);
-f(17592186044416, 65536);
-f(17592454479872, 65537);
-f(35184103653376, 131071);
-f(35184372088832, 131072);
-f(35184640524288, 131073);
-f(70368475742208, 262143);
-f(70368744177664, 262144);
-f(70369012613120, 262145);
-f(140737219919872, 524287);
-f(140737488355328, 524288);
-f(140737756790784, 524289);
-f(281474708275200, 1048575);
-f(281474976710656, 1048576);
-f(281475245146112, 1048577);
-f(562949684985856, 2097151);
-f(562949953421312, 2097152);
-f(562950221856768, 2097153);
-f(1125899638407168, 4194303);
-f(1125899906842624, 4194304);
-f(1125900175278080, 4194305);
-x = 268435457;
-f(0, 0);
-f(268435457, 1);
-f(536870914, 2);
-f(805306371, 3);
-f(1073741828, 4);
-f(1342177285, 5);
-f(1879048199, 7);
-f(2147483656, 8);
-f(2415919113, 9);
-f(4026531855, 15);
-f(4294967312, 16);
-f(4563402769, 17);
-f(8321499167, 31);
-f(8589934624, 32);
-f(8858370081, 33);
-f(16911433791, 63);
-f(17179869248, 64);
-f(17448304705, 65);
-f(34091303039, 127);
-f(34359738496, 128);
-f(34628173953, 129);
-f(68451041535, 255);
-f(68719476992, 256);
-f(68987912449, 257);
-f(137170518527, 511);
-f(137438953984, 512);
-f(137707389441, 513);
-f(274609472511, 1023);
-f(274877907968, 1024);
-f(275146343425, 1025);
-f(549487380479, 2047);
-f(549755815936, 2048);
-f(550024251393, 2049);
-f(1099243196415, 4095);
-f(1099511631872, 4096);
-f(1099780067329, 4097);
-f(2198754828287, 8191);
-f(2199023263744, 8192);
-f(2199291699201, 8193);
-f(4397778092031, 16383);
-f(4398046527488, 16384);
-f(4398314962945, 16385);
-f(8795824619519, 32767);
-f(8796093054976, 32768);
-f(8796361490433, 32769);
-f(17591917674495, 65535);
-f(17592186109952, 65536);
-f(17592454545409, 65537);
-f(35184103784447, 131071);
-f(35184372219904, 131072);
-f(35184640655361, 131073);
-f(70368476004351, 262143);
-f(70368744439808, 262144);
-f(70369012875265, 262145);
-f(140737220444159, 524287);
-f(140737488879616, 524288);
-f(140737757315073, 524289);
-f(281474709323775, 1048575);
-f(281474977759232, 1048576);
-f(281475246194689, 1048577);
-f(562949687083007, 2097151);
-f(562949955518464, 2097152);
-f(562950223953921, 2097153);
-f(1125899642601471, 4194303);
-f(1125899911036928, 4194304);
-f(1125900179472385, 4194305);
-x = 536870911;
-f(0, 0);
-f(536870911, 1);
-f(1073741822, 2);
-f(1610612733, 3);
-f(2147483644, 4);
-f(2684354555, 5);
-f(3758096377, 7);
-f(4294967288, 8);
-f(4831838199, 9);
-f(8053063665, 15);
-f(8589934576, 16);
-f(9126805487, 17);
-f(16642998241, 31);
-f(17179869152, 32);
-f(17716740063, 33);
-f(33822867393, 63);
-f(34359738304, 64);
-f(34896609215, 65);
-f(68182605697, 127);
-f(68719476608, 128);
-f(69256347519, 129);
-f(136902082305, 255);
-f(137438953216, 256);
-f(137975824127, 257);
-f(274341035521, 511);
-f(274877906432, 512);
-f(275414777343, 513);
-f(549218941953, 1023);
-f(549755812864, 1024);
-f(550292683775, 1025);
-f(1098974754817, 2047);
-f(1099511625728, 2048);
-f(1100048496639, 2049);
-f(2198486380545, 4095);
-f(2199023251456, 4096);
-f(2199560122367, 4097);
-f(4397509632001, 8191);
-f(4398046502912, 8192);
-f(4398583373823, 8193);
-f(8795556134913, 16383);
-f(8796093005824, 16384);
-f(8796629876735, 16385);
-f(17591649140737, 32767);
-f(17592186011648, 32768);
-f(17592722882559, 32769);
-f(35183835152385, 65535);
-f(35184372023296, 65536);
-f(35184908894207, 65537);
-f(70368207175681, 131071);
-f(70368744046592, 131072);
-f(70369280917503, 131073);
-f(140736951222273, 262143);
-f(140737488093184, 262144);
-f(140738024964095, 262145);
-f(281474439315457, 524287);
-f(281474976186368, 524288);
-f(281475513057279, 524289);
-f(562949415501825, 1048575);
-f(562949952372736, 1048576);
-f(562950489243647, 1048577);
-f(1125899367874561, 2097151);
-f(1125899904745472, 2097152);
-f(1125900441616383, 2097153);
-x = 536870912;
-f(0, 0);
-f(536870912, 1);
-f(1073741824, 2);
-f(1610612736, 3);
-f(2147483648, 4);
-f(2684354560, 5);
-f(3758096384, 7);
-f(4294967296, 8);
-f(4831838208, 9);
-f(8053063680, 15);
-f(8589934592, 16);
-f(9126805504, 17);
-f(16642998272, 31);
-f(17179869184, 32);
-f(17716740096, 33);
-f(33822867456, 63);
-f(34359738368, 64);
-f(34896609280, 65);
-f(68182605824, 127);
-f(68719476736, 128);
-f(69256347648, 129);
-f(136902082560, 255);
-f(137438953472, 256);
-f(137975824384, 257);
-f(274341036032, 511);
-f(274877906944, 512);
-f(275414777856, 513);
-f(549218942976, 1023);
-f(549755813888, 1024);
-f(550292684800, 1025);
-f(1098974756864, 2047);
-f(1099511627776, 2048);
-f(1100048498688, 2049);
-f(2198486384640, 4095);
-f(2199023255552, 4096);
-f(2199560126464, 4097);
-f(4397509640192, 8191);
-f(4398046511104, 8192);
-f(4398583382016, 8193);
-f(8795556151296, 16383);
-f(8796093022208, 16384);
-f(8796629893120, 16385);
-f(17591649173504, 32767);
-f(17592186044416, 32768);
-f(17592722915328, 32769);
-f(35183835217920, 65535);
-f(35184372088832, 65536);
-f(35184908959744, 65537);
-f(70368207306752, 131071);
-f(70368744177664, 131072);
-f(70369281048576, 131073);
-f(140736951484416, 262143);
-f(140737488355328, 262144);
-f(140738025226240, 262145);
-f(281474439839744, 524287);
-f(281474976710656, 524288);
-f(281475513581568, 524289);
-f(562949416550400, 1048575);
-f(562949953421312, 1048576);
-f(562950490292224, 1048577);
-f(1125899369971712, 2097151);
-f(1125899906842624, 2097152);
-f(1125900443713536, 2097153);
-x = 536870913;
-f(0, 0);
-f(536870913, 1);
-f(1073741826, 2);
-f(1610612739, 3);
-f(2147483652, 4);
-f(2684354565, 5);
-f(3758096391, 7);
-f(4294967304, 8);
-f(4831838217, 9);
-f(8053063695, 15);
-f(8589934608, 16);
-f(9126805521, 17);
-f(16642998303, 31);
-f(17179869216, 32);
-f(17716740129, 33);
-f(33822867519, 63);
-f(34359738432, 64);
-f(34896609345, 65);
-f(68182605951, 127);
-f(68719476864, 128);
-f(69256347777, 129);
-f(136902082815, 255);
-f(137438953728, 256);
-f(137975824641, 257);
-f(274341036543, 511);
-f(274877907456, 512);
-f(275414778369, 513);
-f(549218943999, 1023);
-f(549755814912, 1024);
-f(550292685825, 1025);
-f(1098974758911, 2047);
-f(1099511629824, 2048);
-f(1100048500737, 2049);
-f(2198486388735, 4095);
-f(2199023259648, 4096);
-f(2199560130561, 4097);
-f(4397509648383, 8191);
-f(4398046519296, 8192);
-f(4398583390209, 8193);
-f(8795556167679, 16383);
-f(8796093038592, 16384);
-f(8796629909505, 16385);
-f(17591649206271, 32767);
-f(17592186077184, 32768);
-f(17592722948097, 32769);
-f(35183835283455, 65535);
-f(35184372154368, 65536);
-f(35184909025281, 65537);
-f(70368207437823, 131071);
-f(70368744308736, 131072);
-f(70369281179649, 131073);
-f(140736951746559, 262143);
-f(140737488617472, 262144);
-f(140738025488385, 262145);
-f(281474440364031, 524287);
-f(281474977234944, 524288);
-f(281475514105857, 524289);
-f(562949417598975, 1048575);
-f(562949954469888, 1048576);
-f(562950491340801, 1048577);
-f(1125899372068863, 2097151);
-f(1125899908939776, 2097152);
-f(1125900445810689, 2097153);
-x = 1073741823;
-f(0, 0);
-f(1073741823, 1);
-f(2147483646, 2);
-f(3221225469, 3);
-f(4294967292, 4);
-f(5368709115, 5);
-f(7516192761, 7);
-f(8589934584, 8);
-f(9663676407, 9);
-f(16106127345, 15);
-f(17179869168, 16);
-f(18253610991, 17);
-f(33285996513, 31);
-f(34359738336, 32);
-f(35433480159, 33);
-f(67645734849, 63);
-f(68719476672, 64);
-f(69793218495, 65);
-f(136365211521, 127);
-f(137438953344, 128);
-f(138512695167, 129);
-f(273804164865, 255);
-f(274877906688, 256);
-f(275951648511, 257);
-f(548682071553, 511);
-f(549755813376, 512);
-f(550829555199, 513);
-f(1098437884929, 1023);
-f(1099511626752, 1024);
-f(1100585368575, 1025);
-f(2197949511681, 2047);
-f(2199023253504, 2048);
-f(2200096995327, 2049);
-f(4396972765185, 4095);
-f(4398046507008, 4096);
-f(4399120248831, 4097);
-f(8795019272193, 8191);
-f(8796093014016, 8192);
-f(8797166755839, 8193);
-f(17591112286209, 16383);
-f(17592186028032, 16384);
-f(17593259769855, 16385);
-f(35183298314241, 32767);
-f(35184372056064, 32768);
-f(35185445797887, 32769);
-f(70367670370305, 65535);
-f(70368744112128, 65536);
-f(70369817853951, 65537);
-f(140736414482433, 131071);
-f(140737488224256, 131072);
-f(140738561966079, 131073);
-f(281473902706689, 262143);
-f(281474976448512, 262144);
-f(281476050190335, 262145);
-f(562948879155201, 524287);
-f(562949952897024, 524288);
-f(562951026638847, 524289);
-f(1125898832052225, 1048575);
-f(1125899905794048, 1048576);
-f(1125900979535871, 1048577);
-x = 1073741824;
-f(0, 0);
-f(1073741824, 1);
-f(2147483648, 2);
-f(3221225472, 3);
-f(4294967296, 4);
-f(5368709120, 5);
-f(7516192768, 7);
-f(8589934592, 8);
-f(9663676416, 9);
-f(16106127360, 15);
-f(17179869184, 16);
-f(18253611008, 17);
-f(33285996544, 31);
-f(34359738368, 32);
-f(35433480192, 33);
-f(67645734912, 63);
-f(68719476736, 64);
-f(69793218560, 65);
-f(136365211648, 127);
-f(137438953472, 128);
-f(138512695296, 129);
-f(273804165120, 255);
-f(274877906944, 256);
-f(275951648768, 257);
-f(548682072064, 511);
-f(549755813888, 512);
-f(550829555712, 513);
-f(1098437885952, 1023);
-f(1099511627776, 1024);
-f(1100585369600, 1025);
-f(2197949513728, 2047);
-f(2199023255552, 2048);
-f(2200096997376, 2049);
-f(4396972769280, 4095);
-f(4398046511104, 4096);
-f(4399120252928, 4097);
-f(8795019280384, 8191);
-f(8796093022208, 8192);
-f(8797166764032, 8193);
-f(17591112302592, 16383);
-f(17592186044416, 16384);
-f(17593259786240, 16385);
-f(35183298347008, 32767);
-f(35184372088832, 32768);
-f(35185445830656, 32769);
-f(70367670435840, 65535);
-f(70368744177664, 65536);
-f(70369817919488, 65537);
-f(140736414613504, 131071);
-f(140737488355328, 131072);
-f(140738562097152, 131073);
-f(281473902968832, 262143);
-f(281474976710656, 262144);
-f(281476050452480, 262145);
-f(562948879679488, 524287);
-f(562949953421312, 524288);
-f(562951027163136, 524289);
-f(1125898833100800, 1048575);
-f(1125899906842624, 1048576);
-f(1125900980584448, 1048577);
-x = 1073741825;
-f(0, 0);
-f(1073741825, 1);
-f(2147483650, 2);
-f(3221225475, 3);
-f(4294967300, 4);
-f(5368709125, 5);
-f(7516192775, 7);
-f(8589934600, 8);
-f(9663676425, 9);
-f(16106127375, 15);
-f(17179869200, 16);
-f(18253611025, 17);
-f(33285996575, 31);
-f(34359738400, 32);
-f(35433480225, 33);
-f(67645734975, 63);
-f(68719476800, 64);
-f(69793218625, 65);
-f(136365211775, 127);
-f(137438953600, 128);
-f(138512695425, 129);
-f(273804165375, 255);
-f(274877907200, 256);
-f(275951649025, 257);
-f(548682072575, 511);
-f(549755814400, 512);
-f(550829556225, 513);
-f(1098437886975, 1023);
-f(1099511628800, 1024);
-f(1100585370625, 1025);
-f(2197949515775, 2047);
-f(2199023257600, 2048);
-f(2200096999425, 2049);
-f(4396972773375, 4095);
-f(4398046515200, 4096);
-f(4399120257025, 4097);
-f(8795019288575, 8191);
-f(8796093030400, 8192);
-f(8797166772225, 8193);
-f(17591112318975, 16383);
-f(17592186060800, 16384);
-f(17593259802625, 16385);
-f(35183298379775, 32767);
-f(35184372121600, 32768);
-f(35185445863425, 32769);
-f(70367670501375, 65535);
-f(70368744243200, 65536);
-f(70369817985025, 65537);
-f(140736414744575, 131071);
-f(140737488486400, 131072);
-f(140738562228225, 131073);
-f(281473903230975, 262143);
-f(281474976972800, 262144);
-f(281476050714625, 262145);
-f(562948880203775, 524287);
-f(562949953945600, 524288);
-f(562951027687425, 524289);
-f(1125898834149375, 1048575);
-f(1125899907891200, 1048576);
-f(1125900981633025, 1048577);
-x = 2147483647;
-f(0, 0);
-f(2147483647, 1);
-f(4294967294, 2);
-f(6442450941, 3);
-f(8589934588, 4);
-f(10737418235, 5);
-f(15032385529, 7);
-f(17179869176, 8);
-f(19327352823, 9);
-f(32212254705, 15);
-f(34359738352, 16);
-f(36507221999, 17);
-f(66571993057, 31);
-f(68719476704, 32);
-f(70866960351, 33);
-f(135291469761, 63);
-f(137438953408, 64);
-f(139586437055, 65);
-f(272730423169, 127);
-f(274877906816, 128);
-f(277025390463, 129);
-f(547608329985, 255);
-f(549755813632, 256);
-f(551903297279, 257);
-f(1097364143617, 511);
-f(1099511627264, 512);
-f(1101659110911, 513);
-f(2196875770881, 1023);
-f(2199023254528, 1024);
-f(2201170738175, 1025);
-f(4395899025409, 2047);
-f(4398046509056, 2048);
-f(4400193992703, 2049);
-f(8793945534465, 4095);
-f(8796093018112, 4096);
-f(8798240501759, 4097);
-f(17590038552577, 8191);
-f(17592186036224, 8192);
-f(17594333519871, 8193);
-f(35182224588801, 16383);
-f(35184372072448, 16384);
-f(35186519556095, 16385);
-f(70366596661249, 32767);
-f(70368744144896, 32768);
-f(70370891628543, 32769);
-f(140735340806145, 65535);
-f(140737488289792, 65536);
-f(140739635773439, 65537);
-f(281472829095937, 131071);
-f(281474976579584, 131072);
-f(281477124063231, 131073);
-f(562947805675521, 262143);
-f(562949953159168, 262144);
-f(562952100642815, 262145);
-f(1125897758834689, 524287);
-f(1125899906318336, 524288);
-f(1125902053801983, 524289);
-x = 2147483648;
-f(0, 0);
-f(2147483648, 1);
-f(4294967296, 2);
-f(6442450944, 3);
-f(8589934592, 4);
-f(10737418240, 5);
-f(15032385536, 7);
-f(17179869184, 8);
-f(19327352832, 9);
-f(32212254720, 15);
-f(34359738368, 16);
-f(36507222016, 17);
-f(66571993088, 31);
-f(68719476736, 32);
-f(70866960384, 33);
-f(135291469824, 63);
-f(137438953472, 64);
-f(139586437120, 65);
-f(272730423296, 127);
-f(274877906944, 128);
-f(277025390592, 129);
-f(547608330240, 255);
-f(549755813888, 256);
-f(551903297536, 257);
-f(1097364144128, 511);
-f(1099511627776, 512);
-f(1101659111424, 513);
-f(2196875771904, 1023);
-f(2199023255552, 1024);
-f(2201170739200, 1025);
-f(4395899027456, 2047);
-f(4398046511104, 2048);
-f(4400193994752, 2049);
-f(8793945538560, 4095);
-f(8796093022208, 4096);
-f(8798240505856, 4097);
-f(17590038560768, 8191);
-f(17592186044416, 8192);
-f(17594333528064, 8193);
-f(35182224605184, 16383);
-f(35184372088832, 16384);
-f(35186519572480, 16385);
-f(70366596694016, 32767);
-f(70368744177664, 32768);
-f(70370891661312, 32769);
-f(140735340871680, 65535);
-f(140737488355328, 65536);
-f(140739635838976, 65537);
-f(281472829227008, 131071);
-f(281474976710656, 131072);
-f(281477124194304, 131073);
-f(562947805937664, 262143);
-f(562949953421312, 262144);
-f(562952100904960, 262145);
-f(1125897759358976, 524287);
-f(1125899906842624, 524288);
-f(1125902054326272, 524289);
-x = 2147483649;
-f(0, 0);
-f(2147483649, 1);
-f(4294967298, 2);
-f(6442450947, 3);
-f(8589934596, 4);
-f(10737418245, 5);
-f(15032385543, 7);
-f(17179869192, 8);
-f(19327352841, 9);
-f(32212254735, 15);
-f(34359738384, 16);
-f(36507222033, 17);
-f(66571993119, 31);
-f(68719476768, 32);
-f(70866960417, 33);
-f(135291469887, 63);
-f(137438953536, 64);
-f(139586437185, 65);
-f(272730423423, 127);
-f(274877907072, 128);
-f(277025390721, 129);
-f(547608330495, 255);
-f(549755814144, 256);
-f(551903297793, 257);
-f(1097364144639, 511);
-f(1099511628288, 512);
-f(1101659111937, 513);
-f(2196875772927, 1023);
-f(2199023256576, 1024);
-f(2201170740225, 1025);
-f(4395899029503, 2047);
-f(4398046513152, 2048);
-f(4400193996801, 2049);
-f(8793945542655, 4095);
-f(8796093026304, 4096);
-f(8798240509953, 4097);
-f(17590038568959, 8191);
-f(17592186052608, 8192);
-f(17594333536257, 8193);
-f(35182224621567, 16383);
-f(35184372105216, 16384);
-f(35186519588865, 16385);
-f(70366596726783, 32767);
-f(70368744210432, 32768);
-f(70370891694081, 32769);
-f(140735340937215, 65535);
-f(140737488420864, 65536);
-f(140739635904513, 65537);
-f(281472829358079, 131071);
-f(281474976841728, 131072);
-f(281477124325377, 131073);
-f(562947806199807, 262143);
-f(562949953683456, 262144);
-f(562952101167105, 262145);
-f(1125897759883263, 524287);
-f(1125899907366912, 524288);
-f(1125902054850561, 524289);
-x = 4294967295;
-f(0, 0);
-f(4294967295, 1);
-f(8589934590, 2);
-f(12884901885, 3);
-f(17179869180, 4);
-f(21474836475, 5);
-f(30064771065, 7);
-f(34359738360, 8);
-f(38654705655, 9);
-f(64424509425, 15);
-f(68719476720, 16);
-f(73014444015, 17);
-f(133143986145, 31);
-f(137438953440, 32);
-f(141733920735, 33);
-f(270582939585, 63);
-f(274877906880, 64);
-f(279172874175, 65);
-f(545460846465, 127);
-f(549755813760, 128);
-f(554050781055, 129);
-f(1095216660225, 255);
-f(1099511627520, 256);
-f(1103806594815, 257);
-f(2194728287745, 511);
-f(2199023255040, 512);
-f(2203318222335, 513);
-f(4393751542785, 1023);
-f(4398046510080, 1024);
-f(4402341477375, 1025);
-f(8791798052865, 2047);
-f(8796093020160, 2048);
-f(8800387987455, 2049);
-f(17587891073025, 4095);
-f(17592186040320, 4096);
-f(17596481007615, 4097);
-f(35180077113345, 8191);
-f(35184372080640, 8192);
-f(35188667047935, 8193);
-f(70364449193985, 16383);
-f(70368744161280, 16384);
-f(70373039128575, 16385);
-f(140733193355265, 32767);
-f(140737488322560, 32768);
-f(140741783289855, 32769);
-f(281470681677825, 65535);
-f(281474976645120, 65536);
-f(281479271612415, 65537);
-f(562945658322945, 131071);
-f(562949953290240, 131072);
-f(562954248257535, 131073);
-f(1125895611613185, 262143);
-f(1125899906580480, 262144);
-f(1125904201547775, 262145);
-x = 4294967296;
-f(0, 0);
-f(4294967296, 1);
-f(8589934592, 2);
-f(12884901888, 3);
-f(17179869184, 4);
-f(21474836480, 5);
-f(30064771072, 7);
-f(34359738368, 8);
-f(38654705664, 9);
-f(64424509440, 15);
-f(68719476736, 16);
-f(73014444032, 17);
-f(133143986176, 31);
-f(137438953472, 32);
-f(141733920768, 33);
-f(270582939648, 63);
-f(274877906944, 64);
-f(279172874240, 65);
-f(545460846592, 127);
-f(549755813888, 128);
-f(554050781184, 129);
-f(1095216660480, 255);
-f(1099511627776, 256);
-f(1103806595072, 257);
-f(2194728288256, 511);
-f(2199023255552, 512);
-f(2203318222848, 513);
-f(4393751543808, 1023);
-f(4398046511104, 1024);
-f(4402341478400, 1025);
-f(8791798054912, 2047);
-f(8796093022208, 2048);
-f(8800387989504, 2049);
-f(17587891077120, 4095);
-f(17592186044416, 4096);
-f(17596481011712, 4097);
-f(35180077121536, 8191);
-f(35184372088832, 8192);
-f(35188667056128, 8193);
-f(70364449210368, 16383);
-f(70368744177664, 16384);
-f(70373039144960, 16385);
-f(140733193388032, 32767);
-f(140737488355328, 32768);
-f(140741783322624, 32769);
-f(281470681743360, 65535);
-f(281474976710656, 65536);
-f(281479271677952, 65537);
-f(562945658454016, 131071);
-f(562949953421312, 131072);
-f(562954248388608, 131073);
-f(1125895611875328, 262143);
-f(1125899906842624, 262144);
-f(1125904201809920, 262145);
-x = 4294967297;
-f(0, 0);
-f(4294967297, 1);
-f(8589934594, 2);
-f(12884901891, 3);
-f(17179869188, 4);
-f(21474836485, 5);
-f(30064771079, 7);
-f(34359738376, 8);
-f(38654705673, 9);
-f(64424509455, 15);
-f(68719476752, 16);
-f(73014444049, 17);
-f(133143986207, 31);
-f(137438953504, 32);
-f(141733920801, 33);
-f(270582939711, 63);
-f(274877907008, 64);
-f(279172874305, 65);
-f(545460846719, 127);
-f(549755814016, 128);
-f(554050781313, 129);
-f(1095216660735, 255);
-f(1099511628032, 256);
-f(1103806595329, 257);
-f(2194728288767, 511);
-f(2199023256064, 512);
-f(2203318223361, 513);
-f(4393751544831, 1023);
-f(4398046512128, 1024);
-f(4402341479425, 1025);
-f(8791798056959, 2047);
-f(8796093024256, 2048);
-f(8800387991553, 2049);
-f(17587891081215, 4095);
-f(17592186048512, 4096);
-f(17596481015809, 4097);
-f(35180077129727, 8191);
-f(35184372097024, 8192);
-f(35188667064321, 8193);
-f(70364449226751, 16383);
-f(70368744194048, 16384);
-f(70373039161345, 16385);
-f(140733193420799, 32767);
-f(140737488388096, 32768);
-f(140741783355393, 32769);
-f(281470681808895, 65535);
-f(281474976776192, 65536);
-f(281479271743489, 65537);
-f(562945658585087, 131071);
-f(562949953552384, 131072);
-f(562954248519681, 131073);
-f(1125895612137471, 262143);
-f(1125899907104768, 262144);
-f(1125904202072065, 262145);
-x = 8589934591;
-f(0, 0);
-f(8589934591, 1);
-f(17179869182, 2);
-f(25769803773, 3);
-f(34359738364, 4);
-f(42949672955, 5);
-f(60129542137, 7);
-f(68719476728, 8);
-f(77309411319, 9);
-f(128849018865, 15);
-f(137438953456, 16);
-f(146028888047, 17);
-f(266287972321, 31);
-f(274877906912, 32);
-f(283467841503, 33);
-f(541165879233, 63);
-f(549755813824, 64);
-f(558345748415, 65);
-f(1090921693057, 127);
-f(1099511627648, 128);
-f(1108101562239, 129);
-f(2190433320705, 255);
-f(2199023255296, 256);
-f(2207613189887, 257);
-f(4389456576001, 511);
-f(4398046510592, 512);
-f(4406636445183, 513);
-f(8787503086593, 1023);
-f(8796093021184, 1024);
-f(8804682955775, 1025);
-f(17583596107777, 2047);
-f(17592186042368, 2048);
-f(17600775976959, 2049);
-f(35175782150145, 4095);
-f(35184372084736, 4096);
-f(35192962019327, 4097);
-f(70360154234881, 8191);
-f(70368744169472, 8192);
-f(70377334104063, 8193);
-f(140728898404353, 16383);
-f(140737488338944, 16384);
-f(140746078273535, 16385);
-f(281466386743297, 32767);
-f(281474976677888, 32768);
-f(281483566612479, 32769);
-f(562941363421185, 65535);
-f(562949953355776, 65536);
-f(562958543290367, 65537);
-f(1125891316776961, 131071);
-f(1125899906711552, 131072);
-f(1125908496646143, 131073);
-x = 8589934592;
-f(0, 0);
-f(8589934592, 1);
-f(17179869184, 2);
-f(25769803776, 3);
-f(34359738368, 4);
-f(42949672960, 5);
-f(60129542144, 7);
-f(68719476736, 8);
-f(77309411328, 9);
-f(128849018880, 15);
-f(137438953472, 16);
-f(146028888064, 17);
-f(266287972352, 31);
-f(274877906944, 32);
-f(283467841536, 33);
-f(541165879296, 63);
-f(549755813888, 64);
-f(558345748480, 65);
-f(1090921693184, 127);
-f(1099511627776, 128);
-f(1108101562368, 129);
-f(2190433320960, 255);
-f(2199023255552, 256);
-f(2207613190144, 257);
-f(4389456576512, 511);
-f(4398046511104, 512);
-f(4406636445696, 513);
-f(8787503087616, 1023);
-f(8796093022208, 1024);
-f(8804682956800, 1025);
-f(17583596109824, 2047);
-f(17592186044416, 2048);
-f(17600775979008, 2049);
-f(35175782154240, 4095);
-f(35184372088832, 4096);
-f(35192962023424, 4097);
-f(70360154243072, 8191);
-f(70368744177664, 8192);
-f(70377334112256, 8193);
-f(140728898420736, 16383);
-f(140737488355328, 16384);
-f(140746078289920, 16385);
-f(281466386776064, 32767);
-f(281474976710656, 32768);
-f(281483566645248, 32769);
-f(562941363486720, 65535);
-f(562949953421312, 65536);
-f(562958543355904, 65537);
-f(1125891316908032, 131071);
-f(1125899906842624, 131072);
-f(1125908496777216, 131073);
-x = 8589934593;
-f(0, 0);
-f(8589934593, 1);
-f(17179869186, 2);
-f(25769803779, 3);
-f(34359738372, 4);
-f(42949672965, 5);
-f(60129542151, 7);
-f(68719476744, 8);
-f(77309411337, 9);
-f(128849018895, 15);
-f(137438953488, 16);
-f(146028888081, 17);
-f(266287972383, 31);
-f(274877906976, 32);
-f(283467841569, 33);
-f(541165879359, 63);
-f(549755813952, 64);
-f(558345748545, 65);
-f(1090921693311, 127);
-f(1099511627904, 128);
-f(1108101562497, 129);
-f(2190433321215, 255);
-f(2199023255808, 256);
-f(2207613190401, 257);
-f(4389456577023, 511);
-f(4398046511616, 512);
-f(4406636446209, 513);
-f(8787503088639, 1023);
-f(8796093023232, 1024);
-f(8804682957825, 1025);
-f(17583596111871, 2047);
-f(17592186046464, 2048);
-f(17600775981057, 2049);
-f(35175782158335, 4095);
-f(35184372092928, 4096);
-f(35192962027521, 4097);
-f(70360154251263, 8191);
-f(70368744185856, 8192);
-f(70377334120449, 8193);
-f(140728898437119, 16383);
-f(140737488371712, 16384);
-f(140746078306305, 16385);
-f(281466386808831, 32767);
-f(281474976743424, 32768);
-f(281483566678017, 32769);
-f(562941363552255, 65535);
-f(562949953486848, 65536);
-f(562958543421441, 65537);
-f(1125891317039103, 131071);
-f(1125899906973696, 131072);
-f(1125908496908289, 131073);
-x = 17179869183;
-f(0, 0);
-f(17179869183, 1);
-f(34359738366, 2);
-f(51539607549, 3);
-f(68719476732, 4);
-f(85899345915, 5);
-f(120259084281, 7);
-f(137438953464, 8);
-f(154618822647, 9);
-f(257698037745, 15);
-f(274877906928, 16);
-f(292057776111, 17);
-f(532575944673, 31);
-f(549755813856, 32);
-f(566935683039, 33);
-f(1082331758529, 63);
-f(1099511627712, 64);
-f(1116691496895, 65);
-f(2181843386241, 127);
-f(2199023255424, 128);
-f(2216203124607, 129);
-f(4380866641665, 255);
-f(4398046510848, 256);
-f(4415226380031, 257);
-f(8778913152513, 511);
-f(8796093021696, 512);
-f(8813272890879, 513);
-f(17575006174209, 1023);
-f(17592186043392, 1024);
-f(17609365912575, 1025);
-f(35167192217601, 2047);
-f(35184372086784, 2048);
-f(35201551955967, 2049);
-f(70351564304385, 4095);
-f(70368744173568, 4096);
-f(70385924042751, 4097);
-f(140720308477953, 8191);
-f(140737488347136, 8192);
-f(140754668216319, 8193);
-f(281457796825089, 16383);
-f(281474976694272, 16384);
-f(281492156563455, 16385);
-f(562932773519361, 32767);
-f(562949953388544, 32768);
-f(562967133257727, 32769);
-f(1125882726907905, 65535);
-f(1125899906777088, 65536);
-f(1125917086646271, 65537);
-x = 17179869184;
-f(0, 0);
-f(17179869184, 1);
-f(34359738368, 2);
-f(51539607552, 3);
-f(68719476736, 4);
-f(85899345920, 5);
-f(120259084288, 7);
-f(137438953472, 8);
-f(154618822656, 9);
-f(257698037760, 15);
-f(274877906944, 16);
-f(292057776128, 17);
-f(532575944704, 31);
-f(549755813888, 32);
-f(566935683072, 33);
-f(1082331758592, 63);
-f(1099511627776, 64);
-f(1116691496960, 65);
-f(2181843386368, 127);
-f(2199023255552, 128);
-f(2216203124736, 129);
-f(4380866641920, 255);
-f(4398046511104, 256);
-f(4415226380288, 257);
-f(8778913153024, 511);
-f(8796093022208, 512);
-f(8813272891392, 513);
-f(17575006175232, 1023);
-f(17592186044416, 1024);
-f(17609365913600, 1025);
-f(35167192219648, 2047);
-f(35184372088832, 2048);
-f(35201551958016, 2049);
-f(70351564308480, 4095);
-f(70368744177664, 4096);
-f(70385924046848, 4097);
-f(140720308486144, 8191);
-f(140737488355328, 8192);
-f(140754668224512, 8193);
-f(281457796841472, 16383);
-f(281474976710656, 16384);
-f(281492156579840, 16385);
-f(562932773552128, 32767);
-f(562949953421312, 32768);
-f(562967133290496, 32769);
-f(1125882726973440, 65535);
-f(1125899906842624, 65536);
-f(1125917086711808, 65537);
-x = 17179869185;
-f(0, 0);
-f(17179869185, 1);
-f(34359738370, 2);
-f(51539607555, 3);
-f(68719476740, 4);
-f(85899345925, 5);
-f(120259084295, 7);
-f(137438953480, 8);
-f(154618822665, 9);
-f(257698037775, 15);
-f(274877906960, 16);
-f(292057776145, 17);
-f(532575944735, 31);
-f(549755813920, 32);
-f(566935683105, 33);
-f(1082331758655, 63);
-f(1099511627840, 64);
-f(1116691497025, 65);
-f(2181843386495, 127);
-f(2199023255680, 128);
-f(2216203124865, 129);
-f(4380866642175, 255);
-f(4398046511360, 256);
-f(4415226380545, 257);
-f(8778913153535, 511);
-f(8796093022720, 512);
-f(8813272891905, 513);
-f(17575006176255, 1023);
-f(17592186045440, 1024);
-f(17609365914625, 1025);
-f(35167192221695, 2047);
-f(35184372090880, 2048);
-f(35201551960065, 2049);
-f(70351564312575, 4095);
-f(70368744181760, 4096);
-f(70385924050945, 4097);
-f(140720308494335, 8191);
-f(140737488363520, 8192);
-f(140754668232705, 8193);
-f(281457796857855, 16383);
-f(281474976727040, 16384);
-f(281492156596225, 16385);
-f(562932773584895, 32767);
-f(562949953454080, 32768);
-f(562967133323265, 32769);
-f(1125882727038975, 65535);
-f(1125899906908160, 65536);
-f(1125917086777345, 65537);
diff --git a/deps/v8/test/mjsunit/numops-fuzz-part1.js b/deps/v8/test/mjsunit/numops-fuzz-part1.js
new file mode 100644
index 000000000..8e98ae632
--- /dev/null
+++ b/deps/v8/test/mjsunit/numops-fuzz-part1.js
@@ -0,0 +1,1172 @@
+// Copyright 2011 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.
+
+function f() {
+ var x = 0;
+ var tmp = 0;
+ assertEquals(0, x /= (tmp = 798469700.4090232, tmp));
+ assertEquals(0, x *= (2714102322.365509));
+ assertEquals(0, x *= x);
+ assertEquals(139516372, x -= (tmp = -139516372, tmp));
+ assertEquals(1, x /= (x%(2620399703.344006)));
+ assertEquals(0, x >>>= x);
+ assertEquals(-2772151192.8633175, x -= (tmp = 2772151192.8633175, tmp));
+ assertEquals(-2786298206.8633175, x -= (14147014));
+ assertEquals(1509750523, x |= ((1073767916)-(tmp = 919311632.2789925, tmp)));
+ assertEquals(2262404051.926751, x += ((752653528.9267509)%x));
+ assertEquals(-270926893, x |= (tmp = 1837232194, tmp));
+ assertEquals(0.17730273401688765, x /= ((tmp = -2657202795, tmp)-(((((x|(tmp = -1187733892.282897, tmp))-x)<<(556523578))-x)+(-57905508.42881298))));
+ assertEquals(122483.56550261026, x *= ((((tmp = 2570017060.15193, tmp)%((-1862621126.9968336)>>x))>>(x>>(tmp = 2388674677, tmp)))>>>(-2919657526.470434)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x <<= (tmp = 2705124845.0455265, tmp));
+ assertEquals(0, x &= (-135286835.07069612));
+ assertEquals(-0, x *= ((tmp = -165810479.10020828, tmp)|x));
+ assertEquals(248741888, x += ((735976871.1308595)<<(-2608055185.0700903)));
+ assertEquals(139526144, x &= (tmp = -1454301068, tmp));
+ assertEquals(-0.047221345672746884, x /= (tmp = -2954726130.994727, tmp));
+ assertEquals(0, x <<= (x>>x));
+ assertEquals(0, x >>>= ((x+(912111201.488966))-(tmp = 1405800042.6070075, tmp)));
+ assertEquals(-1663642733, x |= (((-1663642733.5700119)<<(x^x))<<x));
+ assertEquals(-914358272, x <<= ((((-308411676)-(-618261840.9113789))%(-68488626.58621716))-x));
+ assertEquals(-1996488704, x &= (-1358622641.5848842));
+ assertEquals(-345978263, x += (1650510441));
+ assertEquals(3, x >>>= (-1106714178.701668));
+ assertEquals(1, x %= (((x>>(x>>(tmp = -3052773846.817114, tmp)))*(tmp = 1659218887.379526, tmp))&x));
+ assertEquals(-943225672, x += (-943225673));
+ assertEquals(-0.41714300120060854, x /= (tmp = 2261156652, tmp));
+ assertEquals(0, x >>>= ((3107060934.8863482)<<(tmp = 1902730887, tmp)));
+ assertEquals(0, x &= x);
+ assertEquals(1476628, x |= ((tmp = -2782899841.390033, tmp)>>>(2097653770)));
+ assertEquals(0.0008887648921591833, x /= ((tmp = 1661438264.5253348, tmp)%((tmp = 2555939813, tmp)*(-877024323.6515315))));
+ assertEquals(0, x <<= (tmp = -2366551345, tmp));
+ assertEquals(0, x &= (tmp = 1742843591, tmp));
+ assertEquals(0, x -= x);
+ assertEquals(4239, x += ((-3183564176.232031)>>>(349622674.1255014)));
+ assertEquals(-67560, x -= ((2352742295)>>>x));
+ assertEquals(-67560, x &= x);
+ assertEquals(-0.00003219917807302283, x /= (2098190203.699741));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>= ((((tmp = -869086522.8358297, tmp)/(187820779))-(tmp = -2000970995.1931965, tmp))|(1853528755.6064696)));
+ assertEquals(0, x >>= (-3040509919));
+ assertEquals(0, x %= (((tmp = -2386688049.194946, tmp)<<(tmp = -669711391, tmp))|x));
+ assertEquals(0, x %= (tmp = -298431511.4839926, tmp));
+ assertEquals(0, x /= (2830845091.2793818));
+ assertEquals(0, x /= ((((-2529926178)|x)^((tmp = 2139313707.0894063, tmp)%((-1825768525.0541775)-(-952600362.7758243))))+x));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x -= x);
+ assertEquals(NaN, x /= (tmp = -432944480, tmp));
+ assertEquals(0, x <<= (((((x^((-1777523727)+(2194962794)))>>>(((((-590335134.8224905)%(x*(2198198974)))|(tmp = -2068556796, tmp))/(1060765637))*(-147051676)))/((tmp = -477350113.92686677, tmp)<<((x/(2018712621.0397925))^((tmp = 491163813.3921983, tmp)+(((x|((((x%(1990073256.812654))%((-2024388518.9599915)>>((tmp = 223182187, tmp)*(-722241065))))>>>(tmp = 2517147885.305745, tmp))%(1189996239.11222)))&x)%(-306932860))))))&((tmp = 1117802724.485684, tmp)+((-1391614045)-x)))%((((x>>((2958453447)*x))^(((410825859)|(((tmp = -1119269292.5495896, tmp)>>>(((((((x%(tmp = 648541746.6059314, tmp))*((-2304508480)<<((((x^(1408199888.1454597))|((251623937)|x))/((-382389946.9984102)|(tmp = -2082681143.5893767, tmp)))-(((tmp = 631243472, tmp)>>>(1407556544))/(((x>>>x)>>>(tmp = -6329025.47865057, tmp))>>>(tmp = 948664752.543093, tmp))))))/((((-183248880)>>x)&x)&x))>>x)&(((-978737284.8492057)%(tmp = 2983300011.737006, tmp))&(tmp = 2641937234.2954116, tmp)))<<x)>>(2795416632.9722223)))%((((tmp = -50926632, tmp)/x)&(((tmp = -2510786916, tmp)/x)/(-699755674)))|((((tmp = 1411792593, tmp)>>(924286570.2637128))>>((1609997725)>>(2735658951.0762663)))*(tmp = 726205435, tmp)))))<<(tmp = -2135055357.3156831, tmp)))/(tmp = 1408695065, tmp))^(tmp = -1343267739.8562133, tmp))));
+ assertEquals(0, x %= (-437232116));
+ assertEquals(-2463314518.2747326, x -= (2463314518.2747326));
+ assertEquals(109, x >>= (2401429560));
+ assertEquals(-2687641732.0253763, x += (-2687641841.0253763));
+ assertEquals(-2336375490019484000, x *= (tmp = 869303174.6678596, tmp));
+ assertEquals(5.458650430363785e+36, x *= x);
+ assertEquals(0, x |= ((((-1676972008.797291)*x)*((tmp = 2606991807, tmp)-x))<<x));
+ assertEquals(0, x &= ((-3053393759.3496876)+(-1431008367)));
+ assertEquals(-856728369, x |= (x-(((((764337872)/x)<<((x|(((tmp = 1409368192.1268077, tmp)+(tmp = -848083676, tmp))|(-2797102463.7915916)))^x))/x)^(tmp = 856728369.0589117, tmp))));
+ assertEquals(-0, x %= x);
+ assertEquals(1116550103, x ^= (-3178417193));
+ assertEquals(1116550103, x %= (tmp = -1482481942, tmp));
+ assertEquals(133, x >>>= x);
+ assertEquals(-1.381429241671034e-7, x /= ((tmp = -962771116.8101778, tmp)^x));
+ assertEquals(-1092268961, x |= ((tmp = 3202672531, tmp)-((x-(tmp = 845529357, tmp))>>(tmp = -868680593, tmp))));
+ assertEquals(-1092268961, x %= (tmp = 2670840415.304719, tmp));
+ assertEquals(-122794480, x %= (tmp = 969474481, tmp));
+ assertEquals(-297606521542193600, x *= (2423614820));
+ assertEquals(72460064, x >>>= (tmp = -1230798655, tmp));
+ assertEquals(-203714325373689600, x *= (-2811401400));
+ assertEquals(2154914048, x >>>= (((2241377026.001436)/x)+x));
+ assertEquals(1177864081, x ^= (tmp = -968513903, tmp));
+ assertEquals(35947664, x &= (-2086226758.2704995));
+ assertEquals(20795732539020670, x += (x*(578500247)));
+ assertEquals(-892004992, x >>= x);
+ assertEquals(-7023661.354330708, x /= ((((((1740714214)%((tmp = -459699286, tmp)+(tmp = -1700187400, tmp)))>>(tmp = -3170295237, tmp))+(tmp = -497509780, tmp))+((1971976144.6197853)+(661992813.6077721)))>>>(-1683802728)));
+ assertEquals(-1634205696, x <<= x);
+ assertEquals(-7, x >>= (-3187653764.930914));
+ assertEquals(-5.095345981491203, x -= ((tmp = 748315289, tmp)/(tmp = -392887780, tmp)));
+ assertEquals(1486531570, x &= (1486531570.9300508));
+ assertEquals(5670, x >>= (((tmp = -2486758205.26425, tmp)*(732510414))|x));
+ assertEquals(5670, x >>= (((-1811879946.2553763)%(1797475764))/(((tmp = -2159923884, tmp)|x)+(tmp = -1774410807, tmp))));
+ assertEquals(38, x %= (x>>>x));
+ assertEquals(-151134215, x ^= (((tmp = -2593085609.5622163, tmp)+((tmp = -814992345.7516887, tmp)-(534809571)))|(tmp = -232678571, tmp)));
+ assertEquals(-234881024, x <<= x);
+ assertEquals(-234881024, x <<= (x>>>x));
+ assertEquals(55169095435288580, x *= x);
+ assertEquals(0, x >>= (tmp = 1176612256, tmp));
+ assertEquals(0, x <<= (1321866341.2486475));
+ assertEquals(0, x %= (x-(-602577995)));
+ assertEquals(0, x >>>= (((((tmp = -125628635.79970193, tmp)^(tmp = 1294209955.229382, tmp))&(((tmp = -2353256654.0725203, tmp)|((-1136743028.9425385)|((((950703429.1110399)-(x>>>x))/((((x%(-252705869.21126103))/((tmp = 886957620, tmp)<<(x%((tmp = -1952249741, tmp)*(tmp = -1998149844, tmp)))))|(tmp = 1933366713, tmp))|((tmp = -2957141565, tmp)>>>(tmp = 1408598804, tmp))))+(((((((-2455002047.4910946)%(tmp = -528017836, tmp))&((-2693432769)/(tmp = 2484427670.9045153, tmp)))%(-356969659))-((((((tmp = 3104828644.0753174, tmp)%(x>>>(tmp = 820832137.8175925, tmp)))*((tmp = 763080553.9260503, tmp)+(3173597855)))<<(((-510785437)^x)<<(x|(((x*(x%((tmp = -1391951515, tmp)/x)))-x)|(x-((-522681793.93221474)/((2514619703.2162743)*(2936688324))))))))|x)>>>(-2093210042)))&(763129279.3651779))&x))))-x))%(((-1331164821)&(tmp = 1342684586, tmp))<<(x<<(tmp = 2675008614.588005, tmp))))>>((2625292569.8984914)+(-3185992401))));
+ assertEquals(0, x *= (tmp = 671817215.1147974, tmp));
+ assertEquals(-1608821121, x ^= ((tmp = 2686146175.04077, tmp)>>>x));
+ assertEquals(-0, x %= x);
+ assertEquals(-0, x /= ((tmp = 286794551.0720866, tmp)|(x%x)));
+ assertEquals(0, x <<= (x|(tmp = 1095503996.2285218, tmp)));
+ assertEquals(443296752, x ^= (443296752));
+ assertEquals(110824188, x >>= ((184708570)>>(x&x)));
+ assertEquals(0.7908194935161674, x /= ((((167151154.63381648)&((tmp = -1434120690, tmp)-(tmp = 2346173080, tmp)))/(56656051.87305987))^(140138414)));
+ assertEquals(-0.9027245492678485, x *= ((tmp = 1724366578, tmp)/(((2979477411)<<(((897038568)>>(tmp = 348960298, tmp))%(281056223.2037884)))^((((-1383133388)-(((-1379748375)-((x>>(x&(tmp = 2456582046, tmp)))>>>(-2923911755.565961)))&x))<<(-2825791731))^(tmp = -1979992970, tmp)))));
+ assertEquals(0, x &= (2482304279));
+ assertEquals(-0, x *= (-2284213673));
+ assertEquals(0, x <<= ((2874381218.015819)|x));
+ assertEquals(0, x *= (x>>>(tmp = 2172786480, tmp)));
+ assertEquals(0, x &= (-1638727867.2978938));
+ assertEquals(0, x %= ((tmp = -2213947368.285817, tmp)>>x));
+ assertEquals(0, x >>>= (tmp = -531324706, tmp));
+ assertEquals(0, x %= (tmp = -2338792486, tmp));
+ assertEquals(0, x <<= (((tmp = 351012164, tmp)<<(x|((tmp = -3023836638.5337825, tmp)^(-2678806692))))|x));
+ assertEquals(0, x %= (x-(tmp = -3220231305.45039, tmp)));
+ assertEquals(0, x <<= (-2132833261));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x %= ((2544970469)+(((-2633093458.5911965)&(644108176))-(x>>>(tmp = -949043718, tmp)))));
+ assertEquals(-2750531265, x += (-2750531265));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x *= ((tmp = 1299005700, tmp)-x));
+ assertEquals(0, x >>= x);
+ assertEquals(-1785515304, x -= (((((-806054462.5563161)/x)>>>x)+(1785515304))|((tmp = 2937069788.9396844, tmp)/x)));
+ assertEquals(-3810117159.173689, x -= (2024601855.1736891));
+ assertEquals(-6.276064139320051, x /= (607087033.3053156));
+ assertEquals(134217727, x >>>= (((x%(tmp = 924293127, tmp))^x)|((x>>>(x&((((tmp = -413386639, tmp)/(x>>(tmp = 599075308.8479941, tmp)))^(tmp = -1076703198, tmp))*((tmp = -2239117284, tmp)>>(655036983)))))-x)));
+ assertEquals(134217727, x %= (tmp = 2452642261.038778, tmp));
+ assertEquals(-569504740360507, x *= ((tmp = -1086243941, tmp)>>(tmp = 1850668904.4885683, tmp)));
+ assertEquals(113378806, x >>>= (tmp = -2558233435, tmp));
+ assertEquals(979264375, x -= (((x>>(1950008052))%((2917183569.0209)*(tmp = 1184250640.446752, tmp)))|((((tmp = -691875212, tmp)-(-2872881803))>>(tmp = 44162204.97461021, tmp))^(tmp = 865885647, tmp))));
+ assertEquals(-1127813632, x <<= ((((tmp = -2210499281, tmp)>>>x)-(tmp = 2359697240, tmp))-x));
+ assertEquals(-1707799657, x ^= (653518231.3995534));
+ assertEquals(2916579668449318000, x *= x);
+ assertEquals(2916579669254640600, x += (x&(tmp = 2986558026.399422, tmp)));
+ assertEquals(870995175, x ^= (2598813927.8991632));
+ assertEquals(870995175, x %= (-2857038782));
+ assertEquals(1869503575895591000, x *= (x|(x|(((tmp = 2478650307.4118147, tmp)*((tmp = 2576240847.476932, tmp)>>>x))<<x))));
+ assertEquals(-134947790, x |= ((tmp = 1150911808, tmp)*((2847735464)/(-2603172652.929262))));
+ assertEquals(-137053182, x -= ((tmp = 2155921819.0929346, tmp)>>>(x-(((-1960937402)-(-1907735074.2875962))%((1827808310)^(tmp = -2788307127, tmp))))));
+ assertEquals(-134824702, x |= (((2912578752.2395406)^(x%(((-2585660111.0638976)<<(((((tmp = 747742706, tmp)%(-1630261205))&((((x|(x|(-2619903144.278758)))|((2785710568.8651934)>>((-968301967.5982246)<<(x&x))))>>((x>>>((x>>>(tmp = -1402085797.0310762, tmp))*((tmp = -323729645.2250068, tmp)<<(tmp = 2234667799, tmp))))>>>(-167003745)))>>((924665972.4681011)<<x)))>>>x)<<((((x+x)+x)-(((tmp = 2399203431.0526247, tmp)-(-2872533271))-(((tmp = 914778794.2087344, tmp)-(tmp = 806353942.9502392, tmp))|(((tmp = 262924334.99231672, tmp)&x)|(tmp = -460248836.5602243, tmp)))))/x)))%((-1681000689)/(tmp = -2805054623.654228, tmp)))))*(tmp = 957346233.9619625, tmp)));
+ assertEquals(-3274838, x %= ((((tmp = 3155450543.3524327, tmp)>>>x)<<(tmp = 2103079652.3410985, tmp))>>x));
+ assertEquals(-3274838, x |= ((((tmp = 2148004645.639173, tmp)>>>(tmp = -1285119223, tmp))<<(((((-711596054)>>>(tmp = -2779776371.3473206, tmp))^(((((tmp = -1338880329.383915, tmp)<<((-1245247254.477341)>>x))*(tmp = -2649052844.20065, tmp))>>((1734345880.4600453)%(x/(2723093117.118899))))*(1252918475.3285656)))<<(2911356885))^x))<<(-1019761103)));
+ assertEquals(1703281954, x &= (((tmp = 1036570471.7412028, tmp)+((tmp = 3043119517, tmp)%(2374310816.8346715)))%(tmp = -2979155076, tmp)));
+ assertEquals(1741588391, x |= ((tmp = 1230009575.6003838, tmp)>>>(-1247515003.8152597)));
+ assertEquals(72869474.64782429, x %= (tmp = 1668718916.3521757, tmp));
+ assertEquals(770936242.104203, x += (698066767.4563787));
+ assertEquals(-0.2820604726420833, x /= (tmp = -2733230342, tmp));
+ assertEquals(403480578, x |= ((969730374)&(tmp = 1577889835, tmp)));
+ assertEquals(-1669557233, x ^= ((-1616812135)+(tmp = -456209292, tmp)));
+ assertEquals(-1630427, x >>= ((2327783031.1175823)/(226947662.4579488)));
+ assertEquals(131022, x >>>= ((tmp = -1325018897.2482083, tmp)>>(x&((((((-1588579772.9240348)<<(tmp = -1775580288.356329, tmp))<<(tmp = -1021528325.2075481, tmp))>>((tmp = 2373033451.079956, tmp)*(tmp = 810304612, tmp)))-((tmp = -639152097, tmp)<<(tmp = 513879484, tmp)))&(2593958513)))));
+ assertEquals(1, x >>= ((3033200222)-x));
+ assertEquals(-561146816.4851823, x += (tmp = -561146817.4851823, tmp));
+ assertEquals(-4.347990105831158, x /= ((((-1270435902)*x)%((tmp = 637328492.7386824, tmp)-(x>>(-749100689))))%(x+x)));
+ assertEquals(-1, x >>= x);
+ assertEquals(1, x *= x);
+ assertEquals(111316849706694460, x += ((966274056)*(x|(115202150))));
+ assertEquals(-1001883840, x >>= x);
+ assertEquals(-1001883840, x &= x);
+ assertEquals(-3006880758, x += ((((-2275110637.4054556)/((x+(tmp = -1390035090.4324536, tmp))>>(-5910593)))&(tmp = 378982420, tmp))|(tmp = 2289970378.568629, tmp)));
+ assertEquals(314474, x >>>= (x>>((tmp = -228007336.31281257, tmp)%(tmp = 1127648013, tmp))));
+ assertEquals(-17694827, x ^= ((tmp = 2095133598.1849852, tmp)|(-1978322311)));
+ assertEquals(1, x /= x);
+ assertEquals(1, x %= (-2323617209.7531185));
+ assertEquals(0, x >>>= (x*(tmp = -1574455400.489434, tmp)));
+ assertEquals(0, x >>= (3131854684));
+ assertEquals(2853609824, x += ((-231012098)-(tmp = -3084621922, tmp)));
+ assertEquals(8143089027629311000, x *= x);
+ assertEquals(313052685, x ^= (tmp = 2962303501, tmp));
+ assertEquals(4776, x >>= (tmp = 2271457232, tmp));
+ assertEquals(0.000002812258572702285, x /= (tmp = 1698279115, tmp));
+ assertEquals(0, x >>>= (tmp = 1698465782.0927145, tmp));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x |= ((x<<((-1824760240.3040407)<<(2798263764.39145)))&(tmp = 1795988253.0493627, tmp)));
+ assertEquals(1782206945, x ^= (-2512760351.7881565));
+ assertEquals(7610569113843172000, x *= (((tmp = -44415823.92972565, tmp)&(tmp = 1402483498.9421625, tmp))+(tmp = 2909778666, tmp)));
+ assertEquals(15221138227873292000, x += (x-(tmp = -186948658.394145, tmp)));
+ assertEquals(0, x -= x);
+ assertEquals(-2238823252, x -= ((tmp = 2238823252, tmp)+x));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>= (2976069570));
+ assertEquals(0, x >>= ((tmp = -2358157433, tmp)/x));
+ assertEquals(-949967713, x ^= (tmp = -949967713, tmp));
+ assertEquals(-1, x >>= x);
+ assertEquals(-1522291702.1977966, x *= (1522291702.1977966));
+ assertEquals(-1522291702, x >>= ((((2290279800)|x)|(1793154434.6798015))&((-1161390929.0766077)>>>x)));
+ assertEquals(83894274, x &= (tmp = 1571058486, tmp));
+ assertEquals(43186847.90522933, x += ((tmp = -1131332988.0947707, tmp)%x));
+ assertEquals(0, x >>= (tmp = -1968312707.269359, tmp));
+ assertEquals(0, x &= (2507747643.26175));
+ assertEquals(0, x %= (tmp = 3190525303.366887, tmp));
+ assertEquals(-1968984602, x ^= (((x/(x|(-1607062026.5338054)))<<(tmp = 2207669861.8770065, tmp))+(tmp = 2325982694.956348, tmp)));
+ assertEquals(554, x >>>= (((tmp = -2302283871.993821, tmp)>>>(-3151835112))|(((((x%(-1534374264))/((731246012)<<(((883830997.1194847)<<(((-1337895080.1937215)/(tmp = 3166402571.8157315, tmp))^(tmp = -1563897595.5799441, tmp)))>>(tmp = -556816951.0537591, tmp))))>>(-2682203577))<<(x/((1654294674.865079)+x)))/((x^(-2189474695.4259806))/(-475915245.7363057)))));
+ assertEquals(1372586111, x ^= (1372586581));
+ assertEquals(1166831229, x -= ((-834168138)&(762573579)));
+ assertEquals(2333662456, x -= ((x>>x)-x));
+ assertEquals(-1961304840, x &= x);
+ assertEquals(-2130143128, x &= (2982852718.0711775));
+ assertEquals(1073741824, x <<= (-1446978661.6426942));
+ assertEquals(2097152, x >>>= ((-1424728215)-(((127872198)%(tmp = -2596923298, tmp))&x)));
+ assertEquals(2097152, x >>>= x);
+ assertEquals(0, x &= (x/(tmp = -518419194.42994523, tmp)));
+ assertEquals(0, x >>= ((x/(-1865078245))%(tmp = 2959239210, tmp)));
+ assertEquals(-0, x *= ((x|(-1721307400))|(-3206147171.9491577)));
+ assertEquals(0, x >>>= ((-694741143)&(tmp = -2196513947.699142, tmp)));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x &= ((tmp = 2037824385.8836646, tmp)+((tmp = 1203034986.4647732, tmp)/(x>>>(((-1374881234)/(899771270.3237157))+((-2296524362.8020077)|(-1529870870)))))));
+ assertEquals(0, x >>= (tmp = 2770637816, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(-1861843456, x |= ((632402668)*((x|(tmp = -1032952662.8269436, tmp))|(tmp = 2671272511, tmp))));
+ assertEquals(-1861843456, x >>= (((x>>>x)+x)<<(-1600908842)));
+ assertEquals(-58182608, x >>= (x-(tmp = -2496617861, tmp)));
+ assertEquals(-3636413, x >>= (tmp = -400700028, tmp));
+ assertEquals(-7272826, x += x);
+ assertEquals(-1, x >>= ((tmp = -3184897005.3614545, tmp)-((-1799843014)|(tmp = 2832132915, tmp))));
+ assertEquals(-121800925.94209385, x *= (121800925.94209385));
+ assertEquals(-30450232, x >>= (-979274206.6261561));
+ assertEquals(-30450232, x >>= (tmp = -1028204832.5078967, tmp));
+ assertEquals(-30450232, x |= x);
+ assertEquals(965888871, x ^= (((((-2157753481.3375635)*((tmp = -1810667184.8165767, tmp)&((tmp = 2503908344.422232, tmp)|x)))>>(x>>(1601560785)))<<x)^(tmp = 943867311.6380403, tmp)));
+ assertEquals(7546006, x >>>= x);
+ assertEquals(7546006, x <<= ((tmp = 1388931761.780241, tmp)*(x-(tmp = -1245147647.0070577, tmp))));
+ assertEquals(12985628, x += (x&(-1520746354)));
+ assertEquals(12985628, x &= x);
+ assertEquals(12985628, x %= (tmp = 308641965, tmp));
+ assertEquals(685733278, x |= ((tmp = -1275653544, tmp)-((tmp = -1956798010.3773859, tmp)%(tmp = 2086889575.643448, tmp))));
+ assertEquals(679679376, x &= (2860752368));
+ assertEquals(1770773904, x |= (x<<(3200659207)));
+ assertEquals(1224886544, x &= (-585733767.6876519));
+ assertEquals(1224886544, x %= ((tmp = -114218494, tmp)-x));
+ assertEquals(1208109328, x &= (tmp = 1854361593, tmp));
+ assertEquals(18434, x >>>= x);
+ assertEquals(-349394636955256100, x *= (x*(-1028198742)));
+ assertEquals(-519536600.7713163, x %= (-1054085356.9120367));
+ assertEquals(-1610612736, x ^= ((tmp = -3126078854, tmp)&x));
+ assertEquals(-2637321565906333700, x *= (1637464740.5658746));
+ assertEquals(-2637321568051070500, x -= ((tmp = -1006718806, tmp)<<(3005848133.106345)));
+ assertEquals(368168695, x ^= (x^(tmp = 368168695.6881037, tmp)));
+ assertEquals(43, x >>>= x);
+ assertEquals(-2081297089, x |= ((167169305.77248895)+(-2248466405.3199244)));
+ assertEquals(-2474622167, x -= (tmp = 393325078, tmp));
+ assertEquals(-135109701, x %= (-1169756233));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x >>= (((((tmp = -164768854, tmp)/(tmp = -1774989993.1909926, tmp))+x)-((-921438912)>>(tmp = -191772028.69249105, tmp)))-(tmp = 558728578.22033, tmp)));
+ assertEquals(0, x %= (tmp = 2188003745, tmp));
+ assertEquals(0, x <<= (((tmp = -999335540, tmp)>>((((325101977)/(tmp = -3036991542, tmp))<<(tmp = -213302488, tmp))+x))|(tmp = -1054204587, tmp)));
+ assertEquals(0, x &= ((2844053429.4720345)>>>x));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x -= (-1481729275.9118822));
+ assertEquals(NaN, x *= (tmp = 1098314618.2397528, tmp));
+ assertEquals(-1073741824, x ^= ((tmp = 1718545772, tmp)<<(((tmp = -81058910, tmp)-(2831123087.424368))+(tmp = 576710057.2361784, tmp))));
+ assertEquals(-2921155898.4793186, x -= (1847414074.4793184));
+ assertEquals(-1295646720, x <<= (2178621744));
+ assertEquals(-0.8906779709597907, x /= ((tmp = -2840292585.6837263, tmp)<<(x&((tmp = 892527695.6172305, tmp)>>>x))));
+ assertEquals(0, x <<= (((tmp = 3149667213.298993, tmp)>>(tmp = 1679370761.7226725, tmp))^(115417747.21537328)));
+ assertEquals(0, x |= x);
+ assertEquals(0, x %= ((-1112849427)>>(-1245508870.7514496)));
+ assertEquals(0, x &= x);
+ assertEquals(0, x |= x);
+ assertEquals(0, x >>>= ((3144100694.930459)>>>(tmp = 2408610503, tmp)));
+ assertEquals(0, x <<= ((tmp = 2671709754.0318713, tmp)%x));
+ assertEquals(0, x >>>= (x|((tmp = -3048578701, tmp)-(674147224))));
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x &= ((tmp = -2084883715, tmp)|(((((-3008427069)+(875536047.4283574))>>>x)%(tmp = -450003426.1091652, tmp))%(((-2956878433.269356)|(x/((((x%((((((x<<(((tmp = -1581063482.510351, tmp)^x)-(tmp = 1364458217, tmp)))^((tmp = 1661446342, tmp)+(1307091014)))/(342270750.9901335))>>>(x&((1760980812.898993)&((tmp = 2878165745.6401143, tmp)/(((tmp = -981178013, tmp)/(-2338761668.29912))>>(-958462630))))))*((1807522840)^((tmp = 1885835034, tmp)^(-2538647938))))*(1673607540.0854697)))%x)>>x)<<x)))<<(853348877.2407281)))));
+ assertEquals(0, x >>>= x);
+ assertEquals(-1162790279, x -= (1162790279));
+ assertEquals(-1162790279, x >>= (((-490178658)*x)/((((((tmp = -1883861998.6699312, tmp)/(tmp = -2369967345.240594, tmp))+(3142759868.266447))&(508784917.8158537))&x)>>(-2129532322))));
+ assertEquals(-1360849740.9829152, x -= (x+(1360849740.9829152)));
+ assertEquals(1928392181, x ^= (-602670783));
+ assertEquals(19478708.898989897, x /= (((-2617861994)>>(tmp = 797256920, tmp))%(-1784987906)));
+ assertEquals(-8648903.575540157, x *= (((tmp = 673979276, tmp)/(-1517908716))%(x/x)));
+ assertEquals(-8648903.575540157, x %= ((((643195610.4221292)>>>(tmp = 2342669302, tmp))>>>(tmp = -1682965878, tmp))^((tmp = -208158937.63443017, tmp)>>((907286989)&(x<<(448634893))))));
+ assertEquals(1399288769, x ^= (tmp = -1407486728, tmp));
+ assertEquals(0, x &= (((1999255838.815517)/(tmp = 564646001, tmp))/(-3075888101.3274765)));
+ assertEquals(0, x ^= ((-78451711.59404826)%x));
+ assertEquals(-1351557131, x |= (2943410165));
+ assertEquals(1715626371, x -= (-3067183502));
+ assertEquals(71434240, x &= ((-1800066426)<<(((((x<<(-324796375))+x)<<(tmp = 2696824955.735132, tmp))^x)%(tmp = 444916469, tmp))));
+ assertEquals(71434240, x >>>= (((x&((x%x)|x))+(tmp = 2226992348.3050146, tmp))<<(-305526260)));
+ assertEquals(0, x -= (x%(tmp = 582790928.5832802, tmp)));
+ assertEquals(0, x *= ((x%(1865155340))>>>((x<<(2600488191))^(-308995123))));
+ assertEquals(0, x >>= (x&(-3120043868.8531103)));
+ assertEquals(0, x |= x);
+ assertEquals(-0, x *= (tmp = -172569944, tmp));
+ assertEquals(0, x <<= (-1664372874));
+ assertEquals(1377713344.6784928, x += (tmp = 1377713344.6784928, tmp));
+ assertEquals(1377713344, x |= x);
+ assertEquals(-232833282, x |= (tmp = 2685870654, tmp));
+ assertEquals(84639, x -= (((((2778531079.998492)%(2029165314))>>>(tmp = -468881172.3729558, tmp))^x)|((x>>>((((x%(3044318992.943596))&(1996754328.2214756))^(1985227172.7485228))%(tmp = -1984848676.1347625, tmp)))|((tmp = 2637662639, tmp)<<x))));
+ assertEquals(0, x ^= x);
+ assertEquals(1237720303, x -= (-1237720303));
+ assertEquals(2, x >>= (-2148785379.428976));
+ assertEquals(2, x &= (tmp = -3087007874, tmp));
+ assertEquals(0, x %= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x += x);
+ assertEquals(0, x &= (2055693082));
+ assertEquals(-1349456492, x += (x^(-1349456492.315998)));
+ assertEquals(671088640, x <<= (x>>(-2030805724.5472062)));
+ assertEquals(-417654580004782100, x *= (tmp = -622353822, tmp));
+ assertEquals(1538160360, x |= (195983080.56698656));
+ assertEquals(733, x >>>= (tmp = 661085269, tmp));
+ assertEquals(657, x &= (-1611460943.993404));
+ assertEquals(431649, x *= x);
+ assertEquals(863298, x += x);
+ assertEquals(0, x &= ((1899423003)/((472439729)>>((tmp = 2903738952, tmp)+(tmp = 2164601630.3456993, tmp)))));
+ assertEquals(0, x &= (x>>>(tmp = 1939167951.2828958, tmp)));
+ assertEquals(1557813284, x |= (x-(-1557813284)));
+ assertEquals(72876068, x &= (662438974.2372154));
+ assertEquals(0.6695448637501589, x /= (tmp = 108844189.45702457, tmp));
+ assertEquals(0, x -= x);
+ assertEquals(2944889412, x += (2944889412));
+ assertEquals(3787980288, x -= ((((tmp = -2003814373.2301111, tmp)<<x)>>>(tmp = -3088357284.4405823, tmp))-(843090884)));
+ assertEquals(1, x >>>= (729274079));
+ assertEquals(1, x %= (-148002187.33869123));
+ assertEquals(3073988415.673201, x *= (tmp = 3073988415.673201, tmp));
+ assertEquals(4839166225.673201, x += (tmp = 1765177810, tmp));
+ assertEquals(4529373898.673201, x += (-309792327));
+ assertEquals(3097903.090496063, x %= (-150875866.51942348));
+ assertEquals(1270874112, x <<= ((((((tmp = -960966763.1418135, tmp)>>((((-3208596981.613482)>>>(tmp = 746403937.6913509, tmp))>>>(-2190042854.066803))/(2449323432)))*(-1272232665.791577))<<(-99306767.7209444))^((-1942103828)/((1570981655)/(tmp = 2381666337, tmp))))+(tmp = -1946759395.1558368, tmp)));
+ assertEquals(1273845956, x |= (tmp = -3197282108.6120167, tmp));
+ assertEquals(159230744, x >>= (((tmp = -1036031403.8108604, tmp)>>>(((3084964493)>>((x*x)^x))+(((2980108409.352001)^x)-(tmp = -2501685423.513927, tmp))))&(326263839)));
+ assertEquals(-370091747145550100, x *= (tmp = -2324248055.674161, tmp));
+ assertEquals(143384219.54999557, x /= (tmp = -2581119096, tmp));
+ assertEquals(1843396287, x |= (tmp = 1842718767, tmp));
+ assertEquals(2.4895593465813803, x /= (740450831));
+ assertEquals(2.4895593465813803, x %= ((((((((-3175333618)>>>((tmp = -1403880166, tmp)<<(tmp = -134875360, tmp)))>>>(2721317334.998084))<<(x&(tmp = 2924634208.1484184, tmp)))*((((x>>(tmp = -200319931.15328693, tmp))-(tmp = -495128933, tmp))+((-788052518.6610589)*((((tmp = 107902557, tmp)&(1221562660))%(x<<(((3155498059)*(((tmp = -1354381139.4897022, tmp)^(tmp = 3084557138.332852, tmp))*((((tmp = 1855251464.8464525, tmp)/((-1857403525.2008865)>>x))|x)-(-2061968455.0023944))))*(1917481864.84619))))^(x-(-508176709.52712965)))))+((((x%(-1942063404))+(x%(tmp = 855152281.180481, tmp)))|(-522863804))>>x)))>>>((tmp = -2515550553, tmp)&(((((-801095375)-(tmp = -2298729336.9792976, tmp))^x)/(tmp = 2370468053, tmp))>>(x|(tmp = -900008879, tmp)))))>>>(((tmp = -810295719.9509168, tmp)*((tmp = -1306212963.6226444, tmp)/(((tmp = 3175881540.9514832, tmp)|(-1439142297.819246))+((tmp = -134415617, tmp)|((-245801870)+x)))))>>(tmp = 1889815478, tmp)))-(((tmp = 597031177, tmp)%(858071823.7655672))+((tmp = 2320838665.8243756, tmp)|((938555608)<<(2351739219.6461897))))));
+ assertEquals(6.197905740150709, x *= x);
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>= (-1639664165.9076233));
+ assertEquals(0, x >>= (-3135317748.801177));
+ assertEquals(0, x &= (3185479232.5325994));
+ assertEquals(-0, x *= ((-119759439.19668174)/(tmp = 2123964608, tmp)));
+ assertEquals(0, x /= (-1183061929.2827876));
+ assertEquals(0, x <<= (-1981831198));
+ assertEquals(0, x >>= ((((x<<(((((((-2133752838)&((tmp = -3045157736.9331336, tmp)>>>(x%x)))>>x)%(tmp = 3082217039, tmp))&(tmp = 270770770.97558427, tmp))|((-2212037556)^((((((2089224421)|(tmp = 360979560, tmp))<<x)%((tmp = -1679487690.6940534, tmp)+((173021423)|((tmp = 560900612, tmp)+((244376267.58977115)^x)))))<<(tmp = 2534513699, tmp))^x)))>>>(2915907189.4873834)))+(x*x))%(1637581117))%(tmp = 2363861105.3786244, tmp)));
+ assertEquals(0, x &= ((-2765495757.873004)&(1727406493)));
+ assertEquals(NaN, x -= (((((-1419667515.2616255)|x)-(150530256.48022234))%((((x|x)<<x)>>>(x^x))+x))-((-1216384577.3749187)*(495244398))));
+ assertEquals(NaN, x += (x^((tmp = 2472035493, tmp)+x)));
+ assertEquals(NaN, x %= ((tmp = -1753037412.885754, tmp)|((tmp = 2507058310, tmp)<<(1475945705))));
+ assertEquals(-1008981005, x |= ((tmp = -1140889842.6099494, tmp)-(tmp = -131908837, tmp)));
+ assertEquals(999230327.5872104, x -= (tmp = -2008211332.5872104, tmp));
+ assertEquals(975810, x >>= (((-1211913874)*x)>>>((-2842129009)>>(x&(tmp = -1410865834, tmp)))));
+ assertEquals(7623, x >>= ((tmp = -1051327071, tmp)-(((tmp = -237716102.8005445, tmp)|((2938903833.416546)&x))|(((-1831064579)^x)/((tmp = 2999232092, tmp)-(981996301.2875179))))));
+ assertEquals(0, x -= x);
+ assertEquals(0, x %= (x|(tmp = -666201160.5810485, tmp)));
+ assertEquals(-1347124100, x |= (-1347124100));
+ assertEquals(-0, x %= (x&x));
+ assertEquals(-661607963, x ^= (tmp = -661607963.3794863, tmp));
+ assertEquals(3465, x >>>= (-828119020.8056595));
+ assertEquals(-268431991, x -= (((tmp = -1386256352, tmp)^((tmp = 743629575, tmp)%((x*((tmp = -1719517658, tmp)>>(2019516558)))<<((2637317661)|x))))<<(tmp = -51637065, tmp)));
+ assertEquals(1578876380, x += ((tmp = 1847308371, tmp)&(((((((tmp = 1487934776.1893163, tmp)%(tmp = 1423264469.3137975, tmp))|(((2653260792.5668964)/(-2417905016.043802))>>>(2097411118.4501896)))^x)^(((tmp = -71334226, tmp)|x)>>>(tmp = -2771758874.7696714, tmp)))^((tmp = -1464849031.3240793, tmp)%(tmp = 2349739690.6430283, tmp)))/x)));
+ assertEquals(3269293934, x += (1690417554));
+ assertEquals(4025392608.031957, x -= (((tmp = 268501120.7225704, tmp)<<(tmp = 2841620654.8903794, tmp))+((tmp = 1606704462.8455591, tmp)/((-2601879963)/(tmp = 2966620168.989736, tmp)))));
+ assertEquals(7, x >>>= (x^(-1913800035)));
+ assertEquals(1.4326776816275493e-8, x /= ((((tmp = -2703417892, tmp)/x)^((-2693772270.396241)>>>((x-(tmp = 615999818.5666655, tmp))>>((((2308121439.3702726)<<((-1794701502)>>(x+(tmp = -2253406035.972883, tmp))))<<((tmp = -197103799.0624652, tmp)|(629975898)))>>>x))))>>>((tmp = 2833656803, tmp)^(x^(tmp = -1580436025, tmp)))));
+ assertEquals(0, x >>>= (tmp = 1525372830.2126007, tmp));
+ assertEquals(0, x %= ((2354010949.24469)>>>(x<<x)));
+ assertEquals(0, x ^= (((1112335059.6922574)*(tmp = -1874363935, tmp))&(((((2154894295.8360596)<<x)&(tmp = -270736315.13505507, tmp))&x)>>>(-2205692260.552064))));
+ assertEquals(0, x >>>= (x<<((1488533932)*(tmp = 1707754286, tmp))));
+ assertEquals(0, x >>= (((tmp = 1232547376.463387, tmp)%((x>>(711691823.1608362))>>>x))>>(((895039781.7478573)*(((((-334946524)&x)*(tmp = -1214529640, tmp))^(tmp = -1586820245, tmp))*(1062595445)))+x)));
+ assertEquals(0, x *= (1863299863.2631998));
+ assertEquals(0, x /= (tmp = 1858428705.1330547, tmp));
+ assertEquals(0, x &= x);
+ assertEquals(611788028, x += (x^(611788028.1510412)));
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>= ((tmp = -1617320707.1784317, tmp)-((-2139400380)-(-1402777976))));
+ assertEquals(0, x >>= (415866827.34665));
+ assertEquals(-1990811897, x -= (tmp = 1990811897, tmp));
+ assertEquals(-1990811895, x += ((x>>>(tmp = -2175453282.769696, tmp))&(tmp = -1459450498.7327478, tmp)));
+ assertEquals(-2377017935.149517, x += (-386206040.1495173));
+ assertEquals(1946129845, x |= (tmp = -2890956796.936539, tmp));
+ assertEquals(0, x %= x);
+ assertEquals(0, x <<= (1616188263));
+ assertEquals(-1081213596, x ^= (tmp = 3213753700, tmp));
+ assertEquals(3213753700, x >>>= (tmp = -3211181312, tmp));
+ assertEquals(-1081213596, x &= x);
+ assertEquals(-1081213583, x ^= (((tmp = 1599988273.4926577, tmp)>>((((-1061394954.6331315)^x)+((-1835761078)*x))+(x%(tmp = -696221869, tmp))))/((tmp = -1156966790.3436491, tmp)^x)));
+ assertEquals(0, x ^= x);
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x += (-1257400530.9263027));
+ assertEquals(NaN, x /= (753062089));
+ assertEquals(NaN, x *= ((tmp = 305418865.57012296, tmp)^(((-2797769706)+((((tmp = -33288276.988654375, tmp)%(tmp = 1242979846, tmp))|(-316574800))-((tmp = -1766083579.4203427, tmp)*(((x*(tmp = -2400342309.2349987, tmp))>>(tmp = 2632061795, tmp))^(tmp = -1001440809, tmp)))))^((((x-(tmp = -1469542637.6925495, tmp))-x)-(3184196890))%(((((((633226688)*((tmp = -2692547856, tmp)>>(((tmp = -1244311756, tmp)>>>x)+((1746013631.405202)>>>(941829464.1962085)))))%(x-x))+(995681795))-(tmp = -3047070551.3642616, tmp))/(1968259705))-((-2853237880)^(tmp = -2746628223.4540343, tmp)))))));
+ assertEquals(0, x >>= x);
+ assertEquals(0.5713172378854926, x += (((x+(((x+x)/(tmp = 2642822318, tmp))*(-2590095885.4280834)))|(tmp = -1769210836, tmp))/(tmp = -3096722308.8665104, tmp)));
+ assertEquals(-0.000002311097780334994, x /= ((2269858877.9010344)>>(-2992512915.984787)));
+ assertEquals(-0.000002311097780334994, x %= (-1139222821));
+ assertEquals(-0.000004622195560669988, x += x);
+ assertEquals(1, x /= x);
+ assertEquals(1, x >>>= (((3002169429.6061807)/(-3068577366))>>>((tmp = -1844537620, tmp)%((((tmp = 2087505119, tmp)>>>x)+x)&(2179989542)))));
+ assertEquals(-534213071, x *= (-534213071));
+ assertEquals(-534213077.3716287, x -= (((tmp = -2390432951.154034, tmp)^x)/(-290501980)));
+ assertEquals(1836305, x >>>= (x&x));
+ assertEquals(1836305, x %= ((x|((3070123855)^(49986396)))+((-1863644960.4202995)>>>((tmp = 1886126804.6019692, tmp)^x))));
+ assertEquals(28692, x >>>= ((2561362139.491764)>>(((((tmp = -1347469854.7413375, tmp)/(((x|(x+x))^((x^(tmp = -2737413775.4595394, tmp))^x))<<(((tmp = 225344844.07128417, tmp)&x)&(tmp = 145794498, tmp))))*x)<<(1424529187))/((-2924344715)/(tmp = -2125770148, tmp)))));
+ assertEquals(-2089419535.2717648, x += (-2089448227.2717648));
+ assertEquals(18957929, x ^= (tmp = 2186590872, tmp));
+ assertEquals(-708972800, x -= (727930729));
+ assertEquals(-4198593, x |= (799483455.1885371));
+ assertEquals(-1, x >>= (-2330654693.6413193));
+ assertEquals(-1, x |= (((tmp = -116877155, tmp)>>>((((tmp = -1677422314.1333556, tmp)/(tmp = -3108738499.0798397, tmp))%((x&(x/x))%((tmp = -695607185.1561592, tmp)-(tmp = 2302449181.622259, tmp))))^(((-1482743646.5604773)^((897705064)>>>x))-(tmp = -2933836669, tmp))))%(((tmp = -2991584625, tmp)|(((x>>x)+(-1101066835))-x))>>(-33192973.819939613))));
+ assertEquals(-1, x &= x);
+ assertEquals(-524288, x <<= (-1177513101.3087924));
+ assertEquals(1978770334.9189441, x += (tmp = 1979294622.9189441, tmp));
+ assertEquals(901783582, x &= ((-368584615)^(((((-478030699.2647903)<<x)<<x)+(tmp = 708725752, tmp))^((tmp = -3081556856, tmp)/(tmp = 1149958711.0676727, tmp)))));
+ assertEquals(-1480333211.8654308, x += (tmp = -2382116793.865431, tmp));
+ assertEquals(956930239.6783283, x *= ((tmp = 956930239.6783283, tmp)/x));
+ assertEquals(1277610.4668602513, x /= ((tmp = 1571029828, tmp)>>(tmp = 2417481141, tmp)));
+ assertEquals(-1077333228, x ^= (tmp = 3218755006, tmp));
+ assertEquals(-50218, x |= (tmp = -1044436526.6435988, tmp));
+ assertEquals(-1, x >>= (-154655245.18921852));
+ assertEquals(0.00006276207290978003, x *= (((tmp = 2234286992.9800305, tmp)>>(tmp = 2132564046.0696363, tmp))/((((tmp = -2565534644.3428087, tmp)>>>(tmp = 2622809851.043325, tmp))>>>((tmp = 311277386, tmp)&x))-(tmp = -2003980974, tmp))));
+ assertEquals(0, x %= x);
+ assertEquals(1282114076, x += ((((422838227)>>>((tmp = 1024613366.1899053, tmp)-((368275340)<<(((tmp = -3066121318, tmp)+(-2319101378))&x))))^(x>>(tmp = 1920136319.803412, tmp)))^(1282264803.3968434)));
+ assertEquals(-277097604, x |= (-283585688.9123297));
+ assertEquals(553816692, x &= (x&(tmp = 554082036.676608, tmp)));
+ assertEquals(658505728, x <<= x);
+ assertEquals(658505728, x &= (x%(2846071230)));
+ assertEquals(39, x >>= (334728536.5172192));
+ assertEquals(0, x -= x);
+ assertEquals(0, x += x);
+ assertEquals(0, x &= (tmp = -335285336, tmp));
+ assertEquals(0, x <<= (tmp = 1255594828.3430014, tmp));
+ assertEquals(0, x %= (-630772751.1248167));
+ assertEquals(NaN, x /= ((((x&(tmp = -1576090612, tmp))%x)>>>x)*((-1038073094.2787619)>>>x)));
+ assertEquals(NaN, x += x);
+ assertEquals(NaN, x -= (((tmp = -2663887803, tmp)&((x+(-1402421046))/x))/(-2675654483)));
+ assertEquals(NaN, x %= (x&(tmp = 672002093, tmp)));
+ assertEquals(0, x |= x);
+ assertEquals(-2698925754, x += (tmp = -2698925754, tmp));
+ assertEquals(-2057748993, x += ((tmp = -2263466497, tmp)^x));
+ assertEquals(1, x /= x);
+ assertEquals(-2769559719.4045835, x -= (2769559720.4045835));
+ assertEquals(-1.3964174646069973, x /= (tmp = 1983332198, tmp));
+ assertEquals(-2140716624.3964174, x += (tmp = -2140716623, tmp));
+ assertEquals(0, x <<= ((2589073007)-(-816764911.8571186)));
+ assertEquals(-2837097288.161354, x -= (tmp = 2837097288.161354, tmp));
+ assertEquals(-1445059927.161354, x += (tmp = 1392037361, tmp));
+ assertEquals(155197984, x &= (tmp = -2694712730.924674, tmp));
+ assertEquals(155197984, x |= (x>>>(tmp = 69118015.20305443, tmp)));
+ assertEquals(155197984, x >>>= (((x^(-1353660241))*x)<<(((((x%(tmp = -1905584634, tmp))>>>(tmp = -860171244.5963638, tmp))&(-1084415001.7039547))+(x-(((tmp = 298064661, tmp)>>x)>>((tmp = 378629912.383446, tmp)-(x%x)))))+(((3212580683)/(((((x^x)>>(tmp = -1502887218, tmp))<<x)%(-142779025))|(((tmp = 1361745708, tmp)*(((((tmp = 1797072528.0673332, tmp)+x)%(tmp = 167297609, tmp))%(-287345856.1791787))^(((((((x*(tmp = -640510459.1514752, tmp))<<(x^(tmp = 1387982082.5646644, tmp)))>>(tmp = 2473373497.467914, tmp))^((234025940)*x))+(tmp = 520098202.9546956, tmp))*(x*(tmp = -362929250.1775775, tmp)))^(-2379972900))))*(tmp = -1385817972, tmp))))+(-1788631834)))));
+ assertEquals(0, x >>= ((tmp = -18671049, tmp)/((tmp = 651261550.6716013, tmp)>>(-58105114.70740628))));
+ assertEquals(0, x *= ((((x>>(tmp = 2256492150.737681, tmp))<<(x<<(((-2738910707)&x)<<(1892428322))))*(tmp = 1547934638, tmp))>>((((319464033.7888391)|(((((tmp = 2705641070, tmp)<<((tmp = 1566904759.36666, tmp)*((-682175559.7540412)&(-691692016.3021002))))%(tmp = 1118101737, tmp))|(902774462))<<x))^((tmp = -388997180, tmp)<<(x<<((((((-88462733)+(x>>>x))%x)*(tmp = -20297481.556210756, tmp))>>>(1927423855.1719701))-((2047811185.6278129)-(tmp = 2952219346.72126, tmp))))))|(-1685518403.7513878))));
+ assertEquals(0, x /= (tmp = 1858074757.563318, tmp));
+ assertEquals(-1351623058, x ^= (-1351623058.4756806));
+ assertEquals(1, x /= x);
+ assertEquals(0, x ^= x);
+ assertEquals(0, x -= (x&(997878144.9798675)));
+ assertEquals(-0, x /= (-2769731277));
+ assertEquals(0, x >>>= ((-2598508325)>>(-1355571351)));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x -= (x&(tmp = 1672810223, tmp)));
+ assertEquals(-924449908.1999881, x -= (924449908.1999881));
+ assertEquals(-0, x %= x);
+ assertEquals(-0, x /= (tmp = 2007131382.059545, tmp));
+ assertEquals(-0, x += x);
+ assertEquals(225132064, x += ((((tmp = -2422670578.1260514, tmp)|x)+x)^(1660142894.7066057)));
+ assertEquals(Infinity, x /= (x-x));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x <<= x);
+ assertEquals(-2455424946.732606, x -= (2455424946.732606));
+ assertEquals(1208029258, x &= ((tmp = 1823728509, tmp)+x));
+ assertEquals(1.3682499724725645, x /= ((((tmp = 1267938464.3854322, tmp)%((tmp = 2510853574, tmp)+(((2979355693.866435)-(tmp = 1989726095.7746763, tmp))<<x)))%((-1382092141.1627176)+(((-901799353)+((-2936414080.8254457)>>>(2515004943.0865674)))-(2532799222.353197))))<<(tmp = -2168058960.2694826, tmp)));
+ assertEquals(0.13799826710735907, x %= ((-1090423235)/(tmp = 2659024727, tmp)));
+ assertEquals(0, x >>= (1688542889.082693));
+ assertEquals(0, x <<= x);
+ assertEquals(NaN, x %= ((((tmp = 1461037539, tmp)<<((x<<(tmp = 2101282906.5302017, tmp))>>(-2792197742)))%(((x%x)^(((tmp = 1399565526, tmp)^(tmp = 643902, tmp))-((tmp = -1449543738, tmp)|x)))/x))*(x<<(471967867))));
+ assertEquals(0, x &= ((tmp = -2121748100.6824129, tmp)>>(tmp = -2817271480.6497793, tmp)));
+ assertEquals(0, x &= (3169130964.6291866));
+ assertEquals(-0, x /= (-2303316806));
+ assertEquals(0, x <<= (tmp = 120185946.51617038, tmp));
+ assertEquals(449448375, x ^= ((((tmp = -836410266.014014, tmp)/x)&((x>>>(tmp = -2602671283, tmp))+x))+(tmp = 449448375, tmp)));
+ assertEquals(202003841790140640, x *= x);
+ assertEquals(202003840800829020, x += (((tmp = -1339865843, tmp)+(tmp = 350554234.15375435, tmp))<<((((((tmp = -1798499687.8208885, tmp)>>(((x-(x^x))|((tmp = 463627396.23932934, tmp)/(2714928060)))&(tmp = 3048222568.1103754, tmp)))&(-3127578553))<<(tmp = -2569797028.8299003, tmp))&x)<<((tmp = 2104393646, tmp)/((tmp = 2314471015.742891, tmp)<<((2704090554.1746845)>>(((tmp = 1935999696, tmp)*(((1348554815)>>>x)>>>(146665093.82445252)))%x)))))));
+ assertEquals(202003841764125400, x -= (tmp = -963296372.2846234, tmp));
+ assertEquals(-413485056, x <<= (tmp = -2474480506.6054573, tmp));
+ assertEquals(-3171894580.186845, x += ((tmp = -1261111102, tmp)+(tmp = -1497298422.1868448, tmp)));
+ assertEquals(17136, x >>= (tmp = 3055058160, tmp));
+ assertEquals(17136, x %= (tmp = 1706784063.3577294, tmp));
+ assertEquals(17136, x >>= ((tmp = 2161213808, tmp)*x));
+ assertEquals(-17136, x /= ((((tmp = -1492618154, tmp)>>x)|(1381949066))>>(tmp = 2014457960, tmp)));
+ assertEquals(-34272, x += x);
+ assertEquals(-1498690902, x += (-1498656630));
+ assertEquals(-1168674482, x ^= (486325220));
+ assertEquals(-1168674482, x <<= ((x^x)*x));
+ assertEquals(794521557347068000, x *= (-679848469));
+ assertEquals(1.3330392590424505e+26, x *= (tmp = 167778866, tmp));
+ assertEquals(0, x <<= (tmp = -2501540637.3664584, tmp));
+ assertEquals(0, x >>>= (x-(x*(-890638026.1825848))));
+ assertEquals(0, x %= ((-285010538.2813468)&(1314684460.7634423)));
+ assertEquals(0, x -= x);
+ assertEquals(0, x *= x);
+ assertEquals(NaN, x %= (x*(x<<x)));
+ assertEquals(NaN, x %= (x<<(((tmp = -1763171810.601149, tmp)&(-138151449.18303752))^(x|x))));
+ assertEquals(0, x |= (x>>x));
+ assertEquals(0, x &= (tmp = 1107152048, tmp));
+ assertEquals(0, x >>= (1489117056.8200984));
+ assertEquals(518749976, x ^= (518749976.20107937));
+ assertEquals(356718654, x += (tmp = -162031322, tmp));
+ assertEquals(356718654, x %= (((x>>>((tmp = -373747439.09634733, tmp)*(tmp = 563665566, tmp)))*(tmp = 2853322586.588251, tmp))*((1303537213)%(-2995314284))));
+ assertEquals(5573728, x >>= (tmp = -2095997978, tmp));
+ assertEquals(5573728, x <<= x);
+ assertEquals(5573728, x >>= (((((tmp = 1745399178.334154, tmp)<<(tmp = 2647999783.8219824, tmp))^(tmp = 1571286759, tmp))%x)/(2166250345.181711)));
+ assertEquals(10886, x >>>= ((682837289)+(x*x)));
+ assertEquals(170, x >>>= x);
+ assertEquals(169.95167497151652, x -= (((tmp = 527356024.19706845, tmp)+((tmp = 1263164619.2954736, tmp)|(tmp = 2942471886, tmp)))/((3017909419.131321)+(tmp = 2137746252.8006272, tmp))));
+ assertEquals(-1915170061, x ^= (tmp = -1915170214, tmp));
+ assertEquals(206045792, x &= (((tmp = 887031922, tmp)>>>x)-((-1861922770)|(9633541))));
+ assertEquals(-1940321674, x |= (tmp = -2012149162.1817405, tmp));
+ assertEquals(-1940321674, x &= x);
+ assertEquals(1128412272.160699, x += (tmp = 3068733946.160699, tmp));
+ assertEquals(0.47486363523180236, x /= (tmp = 2376286976.807289, tmp));
+ assertEquals(-1.4931079540252477e-10, x /= (tmp = -3180370407.5892467, tmp));
+ assertEquals(0, x |= (((1220765170.5933602)*(884017786))*((x%(tmp = -2538196897.226384, tmp))<<(x^x))));
+ assertEquals(-525529894, x += (tmp = -525529894, tmp));
+ assertEquals(1621426184, x &= ((3046517714)*(((((-162481040.8033898)+(x/((x&(1489724492))/((x|(tmp = 943542303, tmp))>>>((-1840491388.1365871)<<(2338177232))))))+(((-2268887573.2430763)>>>(((tmp = 2919141667, tmp)+((tmp = 1326295559.692003, tmp)<<(-2256653815)))>>>(((((tmp = 1602731976.7514615, tmp)*(856036244.3730336))^x)>>>((((2846316421.252943)&(915324162))%(tmp = 1144577211.0221815, tmp))%x))*(x*x))))%(tmp = -2641416560, tmp)))*(x+(x>>>x)))>>x)));
+ assertEquals(1621426184, x %= (tmp = 1898223948, tmp));
+ assertEquals(-3.383396676504762, x /= ((tmp = 2211088034.5234556, tmp)^x));
+ assertEquals(7120923705.122882, x *= (((((tmp = 2632382342.914504, tmp)/(-615440284.1762738))&(2162453853.6658797))<<(-849038082.5298986))|(tmp = -2104667110.5603983, tmp)));
+ assertEquals(-1469010887, x &= x);
+ assertEquals(850767635866964700, x *= (tmp = -579143179.5338116, tmp));
+ assertEquals(0, x %= x);
+ assertEquals(-571457, x |= ((2849326490.8464212)|(tmp = 1450592063, tmp)));
+ assertEquals(-571457, x &= x);
+ assertEquals(-0.00018638416434019244, x /= (3066016912.021368));
+ assertEquals(0, x <<= (2058262829));
+ assertEquals(NaN, x %= ((x|((x%x)>>>x))%((tmp = -2970314895.6974382, tmp)+x)));
+ assertEquals(NaN, x *= (-698693934.9483855));
+ assertEquals(NaN, x += (-100150720.64391875));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x -= (-530301478));
+ assertEquals(NaN, x /= (1507673244));
+ assertEquals(0, x <<= (x%(tmp = 2977838420.857235, tmp)));
+ assertEquals(0, x <<= (tmp = 3200877763, tmp));
+ assertEquals(0, x <<= (tmp = -2592127060, tmp));
+ assertEquals(NaN, x -= (((((((1930632619)*(3018666359))<<((tmp = 2676511886, tmp)&(-2786714482.25468)))%x)-(-633193192))<<((tmp = 403293598, tmp)*(-2765170226)))%x));
+ assertEquals(530062092, x |= (tmp = 530062092, tmp));
+ assertEquals(129409, x >>>= x);
+ assertEquals(-152430382316341.78, x *= (-1177896300.229055));
+ assertEquals(-304860764632683.56, x += x);
+ assertEquals(0, x ^= x);
+ assertEquals(0, x %= (tmp = -63071565.367660046, tmp));
+ assertEquals(0, x &= ((((tmp = -1007464338, tmp)<<(x<<((x^(tmp = -726826835, tmp))|x)))>>>x)*(((tmp = 469293335.9161849, tmp)<<(((((tmp = 1035077379, tmp)*(tmp = -555174353.7567515, tmp))&(3109222796.8286266))-(((((x-(tmp = 1128900353.6650414, tmp))|(tmp = 3119921303, tmp))&((-1353827690)&(x%((-924615958)&x))))>>>x)+(tmp = 1167787910, tmp)))+x))%((605363594)>>(1784370958.269381)))));
+ assertEquals(0, x %= (2953812835.9781704));
+ assertEquals(0, x -= x);
+ assertEquals(0, x <<= x);
+ assertEquals(-901209266, x += (-901209266));
+ assertEquals(-901209266, x &= x);
+ assertEquals(404, x >>>= (-3195686249));
+ assertEquals(824237108, x ^= (824237472));
+ assertEquals(497790936.1853996, x /= ((tmp = 1253776028, tmp)/(757207285)));
+ assertEquals(497790936, x >>>= ((tmp = -2212598336, tmp)<<(x^(1335355792.9363852))));
+ assertEquals(0, x %= x);
+ assertEquals(-2659887352.6415873, x += (tmp = -2659887352.6415873, tmp));
+ assertEquals(1635079945, x |= ((x&(1234659380))>>((((tmp = 2694276886.979136, tmp)|x)^((tmp = 132795582, tmp)<<((-1089828902)>>>x)))<<((((tmp = -2098728613.0310376, tmp)<<(x/(tmp = -2253865599, tmp)))*((x+(x>>>((48633053.82579231)-(385301592))))*(tmp = -1847454853.333535, tmp)))/((-540428068.8583717)+x)))));
+ assertEquals(1, x /= x);
+ assertEquals(33554432, x <<= ((((2803140769)<<x)|(tmp = -1965793804, tmp))>>>(tmp = -2273336965.575082, tmp)));
+ assertEquals(67108864, x += x);
+ assertEquals(9007199254740992, x *= (x+((x>>x)%(2674760854))));
+ assertEquals(55369784, x %= (x|(-170725544.20038843)));
+ assertEquals(55369784, x %= (-1186186787));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x <<= x);
+ assertEquals(NaN, x /= ((-2968110098)-((x/(x|(((((x|((x&((-130329882)>>>(((-135670650)|(x<<(tmp = 1280371822, tmp)))^x)))-(-1183024707.2230911)))&(-1072829280))>>>(-340696948.41492534))>>>(tmp = 436308526.4938295, tmp))<<(((tmp = 3113787500, tmp)*((2038309320)>>>(-1818917055)))&((2808000707)/(774731251))))))%x)));
+ assertEquals(0, x |= (x*(tmp = -843074864, tmp)));
+ assertEquals(0, x &= (tmp = -752261173.8090212, tmp));
+ assertEquals(0, x >>>= (tmp = 1532349931.7517128, tmp));
+ assertEquals(0, x <<= ((tmp = -8628768, tmp)-((((tmp = 225928543, tmp)%(x>>>(x+x)))^((tmp = -2051536806.5249376, tmp)-x))-((tmp = -2274310376.9964137, tmp)%(tmp = 2251342739, tmp)))));
+ assertEquals(0, x >>= (1011388449));
+ assertEquals(0, x += x);
+ assertEquals(0, x >>>= x);
+ assertEquals(-0, x *= ((-1781234179.8663826)>>(((1514201119.9761915)>>(((((1174857164.90042)^(tmp = 1124973934, tmp))^x)+((-1059246013.8834443)<<(2997611138.4876065)))%(((798188010)*(-1428293122))>>>(tmp = -3087267036.8035297, tmp))))<<x)));
+ assertEquals(1752554372, x ^= (tmp = -2542412924, tmp));
+ assertEquals(1752554372, x %= (tmp = 3037553410.2298307, tmp));
+ assertEquals(1859383977, x -= (x^(2446603103)));
+ assertEquals(1183048193, x &= ((tmp = -962336957, tmp)/(x/x)));
+ assertEquals(67738157, x %= ((((tmp = -1813911745.5223546, tmp)+x)<<(x-(((-1980179168)^x)|x)))|(1913769561.1308007)));
+ assertEquals(67698724, x &= ((1801574998.3142045)*((tmp = -2057492249, tmp)/((1713854494.72282)>>x))));
+ assertEquals(0, x -= x);
+ assertEquals(-25232836, x -= ((tmp = 25232836, tmp)|x));
+ assertEquals(-49, x >>= (x+((tmp = 2201204630.2897243, tmp)|(-1929326509))));
+ assertEquals(-1605632, x <<= x);
+ assertEquals(-165965313, x += (tmp = -164359681, tmp));
+ assertEquals(9.220413724941365e-10, x /= (((((tmp = 2579760013.0808706, tmp)*(tmp = -2535370639.9805303, tmp))>>((tmp = 2138199747.0301933, tmp)-(tmp = -2698019325.0972376, tmp)))*(tmp = -425284716, tmp))/((-1951538149.6611228)/(x^(2632919130)))));
+ assertEquals(0, x &= x);
+ assertEquals(0, x &= ((-645189137)/(tmp = 800952748, tmp)));
+ assertEquals(0, x &= (tmp = -1773606925, tmp));
+ assertEquals(0, x += x);
+ assertEquals(0, x >>>= (tmp = 211399355.0741787, tmp));
+ assertEquals(0, x <<= ((-1317040231.5737965)/((((((tmp = 838897586.0147077, tmp)|((-1902447594)|(tmp = 404942728.83034873, tmp)))^(2462760692.2907705))%((((((x%(tmp = -2888980287, tmp))<<(-368505224.49609876))-((x>>>(532513369))&(((((((tmp = -1298067543, tmp)^(tmp = -3130435881.100909, tmp))>>x)/(tmp = -3041161992, tmp))>>(x|(-431685991.95776653)))^((tmp = 1031777777, tmp)^((-105610810)>>>((-631433779)>>(tmp = -2577780871.167671, tmp)))))%(tmp = -3170517650.088039, tmp))))-(((tmp = 2175146237.968785, tmp)-((384631158.50508535)>>((893912279.4646157)|(tmp = -1478803924.5338967, tmp))))%(x/(-1089156420))))<<(tmp = -2024709456, tmp))>>x))*(tmp = -1423824994.6993582, tmp))%(tmp = 1739143409, tmp))));
+ assertEquals(-1799353648, x |= ((-1799353648.3589036)>>>((((x&(-923571640.1012449))%x)+((tmp = 971885508, tmp)>>((tmp = -2207464428.2123804, tmp)+(-3108177894.0459776))))-(-2048954486.7014258))));
+ assertEquals(-3666808032.2958965, x -= (tmp = 1867454384.2958965, tmp));
+ assertEquals(-260069478915415100, x *= (tmp = 70925305.23136711, tmp));
+ assertEquals(1142096768, x &= (tmp = 1866401706.9144325, tmp));
+ assertEquals(1, x >>>= (tmp = 2701377150.5717473, tmp));
+ assertEquals(1865946805, x |= (tmp = -2429020492, tmp));
+ assertEquals(1424222287, x ^= ((((tmp = 433781338, tmp)>>(x>>>((-2914418422.4829016)/(tmp = 1600920669, tmp))))|(tmp = 588320482.9566053, tmp))>>>((((((x+(tmp = -2556387365.5071325, tmp))+(tmp = -2381889946.1830974, tmp))/(3154278191))>>>(-1069701268.8022757))>>(((tmp = 182049089.28866422, tmp)>>x)>>>(tmp = -447146173, tmp)))/(x-(2103883357.0929923)))));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x -= (x%(3036884806)));
+ assertEquals(0, x >>>= (tmp = -652793480.3870945, tmp));
+ assertEquals(0, x += x);
+ assertEquals(304031003, x ^= ((tmp = -900156495, tmp)^(-666397014.0711515)));
+ assertEquals(1, x /= x);
+ assertEquals(-1974501681, x |= (x^(-1974501681.4628205)));
+ assertEquals(-1.3089278317616264, x /= (((-1723703186.962839)>>>x)|((2061022161.6239533)<<x)));
+ assertEquals(-1, x |= (tmp = -1987006457, tmp));
+ assertEquals(-0.14285714285714285, x /= ((((((x|(-1767793799.7595732))-(-1391656680))<<x)|(x>>(tmp = -2301588485.2811003, tmp)))>>>(((tmp = 1812723993, tmp)>>>((x^(((tmp = -3154100157.951021, tmp)%((tmp = -1254955564.4553523, tmp)-(((x>>>(((-1762886343)*x)*x))*(x^(x*(-750918563.4387553))))*x)))|((x>>x)>>(x<<((((-1766797454.5634143)^(tmp = -2251474340, tmp))-(-787637516.5276759))<<((1390653368)^(-1937605249.245374)))))))|(((tmp = 1156611894, tmp)<<x)<<(x>>((((x+(tmp = 2170166060.881797, tmp))&(x>>>(tmp = -1749295923.1498983, tmp)))>>(((-1014973878)|x)&(1302866805.684057)))*(tmp = 560439074.4002491, tmp))))))|(-2758270803.4510045)))&x));
+ assertEquals(0, x |= x);
+ assertEquals(0, x += ((x>>((x+(tmp = -2776680860.870219, tmp))-(((688502468)<<(((tmp = 475364260.57888806, tmp)<<x)+(329071671)))/(-1097134948))))*(tmp = -1281834214.3416953, tmp)));
+ assertEquals(0, x *= ((((1159762330)<<(tmp = -1892429200, tmp))%x)<<x));
+ assertEquals(0, x >>>= (-770595225));
+ assertEquals(NaN, x += (((x>>x)/(tmp = 281621135, tmp))/x));
+ assertEquals(0, x >>= (1363890241));
+ assertEquals(1639023942.9945002, x += (1639023942.9945002));
+ assertEquals(-2568590958567747000, x *= (-1567146697));
+ assertEquals(1793554700, x ^= (tmp = 3215813388.405799, tmp));
+ assertEquals(437879, x >>= x);
+ assertEquals(1339485943, x |= (1339220210));
+ assertEquals(1, x /= x);
+ assertEquals(512, x <<= (2509226729.1477118));
+ assertEquals(512, x <<= ((x>>(1326274040.7181284))<<(tmp = -760670199, tmp)));
+ assertEquals(1, x /= (x<<(x^x)));
+ assertEquals(0, x >>>= (((((1382512625.8298302)&(x>>>x))*(tmp = -815316595, tmp))>>>x)-(-95538051)));
+ assertEquals(-544344229.3548596, x -= (tmp = 544344229.3548596, tmp));
+ assertEquals(-1088688458.7097192, x += x);
+ assertEquals(-1022850479579041900, x *= (939525418.3104812));
+ assertEquals(2069622661, x |= (-2632744187.7721186));
+ assertEquals(-1353480538017756400, x -= ((tmp = 1308085980, tmp)*((x>>>(-629663391.5165792))&(tmp = 3182319856.674114, tmp))));
+ assertEquals(1.3702811563654176e+27, x *= ((((3061414617.6321163)/(tmp = 2628865442, tmp))+(-1549548261))+(x&((tmp = 809684398, tmp)|(x^(tmp = 801765002, tmp))))));
+ assertEquals(0, x >>>= ((-2988504159)&((tmp = -260444190.02252054, tmp)^(2178729442.260293))));
+ assertEquals(-1518607002, x -= (tmp = 1518607002, tmp));
+ assertEquals(724566016, x <<= (tmp = 1042915731.7055794, tmp));
+ assertEquals(707584, x >>>= (-208959862.93305588));
+ assertEquals(0, x >>>= (((tmp = 877181764, tmp)>>(-970697753.3318911))%x));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x += x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x /= (x^((x/(-2903618412.4936123))+(tmp = 1169288899, tmp))));
+ assertEquals(0, x >>>= x);
+ assertEquals(-1302645245, x ^= ((1855892732.3544865)+(tmp = 1136429319.5633948, tmp)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x &= (-1384534597.409375));
+ assertEquals(-0, x /= (tmp = -680466419.8289509, tmp));
+ assertEquals(-0, x *= (318728599.95017374));
+ assertEquals(NaN, x %= (x>>(2019695267)));
+ assertEquals(0, x >>= (tmp = 1280789995, tmp));
+ assertEquals(0, x *= (tmp = 2336951458, tmp));
+ assertEquals(0, x >>= ((2981466013.758637)%(731947033)));
+ assertEquals(0, x -= x);
+ assertEquals(0, x ^= x);
+ assertEquals(0, x /= ((((3068070149.1452317)>>x)%(((1448965452)*((tmp = -2961594129, tmp)+(1829082104.0681171)))>>(-2331499703)))>>>(tmp = -3206314941.2626476, tmp)));
+ assertEquals(0, x >>= (x%(1869217101.9823673)));
+ assertEquals(0, x <<= (x+x));
+ assertEquals(0, x >>>= ((1202130282)>>>x));
+ assertEquals(0, x += x);
+ assertEquals(2603245248.6273212, x += (tmp = 2603245248.6273212, tmp));
+ assertEquals(-1691864471, x ^= (x>>>(2504513614.117516)));
+ assertEquals(136835305, x -= ((-1618979896)&(-746953306)));
+ assertEquals(-2568499564.1261334, x += (tmp = -2705334869.1261334, tmp));
+ assertEquals(1038075700, x ^= (1530399136));
+ assertEquals(2076151400, x += x);
+ assertEquals(-524018410.1751909, x -= ((2398973627.175191)-(-201196183)));
+ assertEquals(0.327110599608614, x /= ((3181340288.602796)&x));
+ assertEquals(0.327110599608614, x %= (tmp = -2284484060, tmp));
+ assertEquals(0, x |= x);
+ assertEquals(403217947.5779772, x += (tmp = 403217947.5779772, tmp));
+ assertEquals(403217947, x |= x);
+ assertEquals(-Infinity, x *= ((58693583.845808744)+(((tmp = -1527787016, tmp)*x)/((((2532689893.3191843)/(tmp = 2781746479.850424, tmp))|(((((460850355.9211761)/((((tmp = 626683450, tmp)<<((tmp = 1349974710, tmp)-((tmp = -1349602292, tmp)/(-2199808871.1229663))))>>((x/(-3092436372.3078623))&(tmp = -1190631012.0323825, tmp)))^((-2907082828.4552956)-(tmp = 1858683340.1157017, tmp))))^(-1513755598.5398848))%x)/x))&(1147739260.136806)))));
+ assertEquals(0, x &= (tmp = -3047356844.109563, tmp));
+ assertEquals(637934616, x -= (tmp = -637934616, tmp));
+ assertEquals(-1553350083, x ^= (-2056266203.094929));
+ assertEquals(-0.13467351026547192, x %= ((tmp = 824736251, tmp)/(2544186314)));
+ assertEquals(1, x /= x);
+ assertEquals(1, x |= x);
+ assertEquals(0, x >>>= (2166609431.9515543));
+ assertEquals(0, x <<= (x|(tmp = 121899222.14603412, tmp)));
+ assertEquals(0, x *= (1300447849.6595674));
+ assertEquals(0, x %= (tmp = -2360500865.3944597, tmp));
+ assertEquals(0, x %= (tmp = -1693401247, tmp));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x /= (471265307));
+ assertEquals(257349748, x ^= (257349748.689448));
+ assertEquals(257349748, x &= x);
+ assertEquals(981, x >>>= (tmp = -1959001422, tmp));
+ assertEquals(0, x >>= ((-79932778.18114972)/x));
+ assertEquals(0, x <<= (((-2599621472)^(tmp = 662071103, tmp))%(tmp = -2675822640.7641535, tmp)));
+ assertEquals(0, x &= (tmp = 2582354953.878623, tmp));
+ assertEquals(0, x /= ((-953254484)/((-2571632163.376176)-(tmp = -342034471, tmp))));
+ assertEquals(0, x <<= ((x-(tmp = -3013057672, tmp))&(tmp = -3204761036, tmp)));
+ assertEquals(0, x ^= ((x&((515934453)>>>x))/x));
+ assertEquals(1, x |= ((-1914707646.2075093)>>>(tmp = -1918045025, tmp)));
+ assertEquals(-2002844120.8792589, x += (tmp = -2002844121.8792589, tmp));
+ assertEquals(573030794, x >>>= (tmp = 1707788162, tmp));
+ assertEquals(1.917619109627369, x /= ((1909436830.484202)%((123114323)<<(tmp = -1288988388.6444468, tmp))));
+ assertEquals(-1400358045, x |= (-1400358046));
+ assertEquals(-2043022529.4273133, x += (tmp = -642664484.4273133, tmp));
+ assertEquals(-81408068.86728716, x %= (tmp = -980807230.2800131, tmp));
+ assertEquals(0.1436896445024992, x /= (((tmp = 3201789924.913518, tmp)%(tmp = -962242528.6008646, tmp))^((tmp = -338830119.55884504, tmp)*(tmp = -916120166, tmp))));
+ assertEquals(0.1436896445024992, x %= (tmp = 2598469263, tmp));
+ assertEquals(0, x *= (x-x));
+ assertEquals(-1409286144, x += (((-111514798.64745283)|(2372059654))<<(tmp = 175644313, tmp)));
+ assertEquals(-2393905467.0073113, x += (-984619323.0073113));
+ assertEquals(-835111172.0073113, x %= (x^(-765900532.5585573)));
+ assertEquals(-835111172.0073113, x %= (tmp = -946478116, tmp));
+ assertEquals(-100, x >>= ((-1020515908)>>(((x&((x^(169474253.53811646))>>(-221739002)))+x)*((201939882.92880356)/(tmp = -50402570, tmp)))));
+ assertEquals(2131506964, x &= (tmp = -2163460268, tmp));
+ assertEquals(1074275840, x &= ((-1561930379.8719592)*(tmp = -2871750052.876917, tmp)));
+ assertEquals(-954232605.5377102, x -= (tmp = 2028508445.5377102, tmp));
+ assertEquals(-29, x >>= (-279577351.87217045));
+ assertEquals(-232, x <<= x);
+ assertEquals(-70, x |= (215185578));
+ assertEquals(-1, x >>= (x>>(-1691303095)));
+ assertEquals(1, x /= x);
+ assertEquals(3149465364.2236686, x *= (3149465364.2236686));
+ assertEquals(3304787832.3790073, x += (tmp = 155322468.15533853, tmp));
+ assertEquals(100068712.23500109, x %= (tmp = 3204719120.1440063, tmp));
+ assertEquals(91628864, x &= (tmp = 629090241, tmp));
+ assertEquals(-113202292046379710, x *= (-1235443583));
+ assertEquals(122, x >>>= (tmp = 3196555256, tmp));
+ assertEquals(122, x >>>= (((2226535734)-x)^(2248399036.393125)));
+ assertEquals(6.904199169070746e-8, x /= (tmp = 1767040564.9149356, tmp));
+ assertEquals(-212687449.99999994, x += ((((2244322375)*(((2515994102)^x)>>x))<<(x-(-832407685.3251972)))^(2266670502)));
+ assertEquals(366515938514778750, x *= (tmp = -1723260768.3940866, tmp));
+ assertEquals(366515938514778750, x += ((-1643386193.9159095)/(tmp = 425161225.95316494, tmp)));
+ assertEquals(654872716.4123061, x /= ((-1377382984)-(tmp = -1937058061.811642, tmp)));
+ assertEquals(654872716, x &= x);
+ assertEquals(-86260926.17813063, x -= (tmp = 741133642.1781306, tmp));
+ assertEquals(1052176592, x >>>= x);
+ assertEquals(2020882856, x ^= (-3107796616));
+ assertEquals(0, x <<= ((606939871.9812952)|(tmp = -3127138319.1557302, tmp)));
+ assertEquals(NaN, x -= ((x%((1120711400.2242608)%x))*(tmp = -930171286.7999947, tmp)));
+ assertEquals(NaN, x %= (3215044180));
+ assertEquals(NaN, x %= (tmp = 2882893804.20102, tmp));
+ assertEquals(NaN, x %= ((217170359.5778643)^x));
+ assertEquals(0, x &= ((-1095125960.9903677)>>(x^(-2227981276))));
+ assertEquals(-748549860, x += (-748549860));
+ assertEquals(1816208256, x <<= (-610872411.3826082));
+ assertEquals(201400576, x &= (((tmp = 1910394603.4836266, tmp)<<x)^x));
+ assertEquals(0, x %= x);
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x <<= (((((2670901339.6696005)%(2180020861))*((2134469504)/(2237096063.0680027)))*((tmp = 1203829756, tmp)>>((765467065)+(x|(2673651811.9494815)))))<<((-1463378514)|(((x/(tmp = -1075050081, tmp))-((-879974865)+x))>>>(tmp = 2172883926, tmp)))));
+ assertEquals(433013198, x ^= (433013198.2833413));
+ assertEquals(0, x >>= ((((-2404431196)%(x%(tmp = 1443152875.8809233, tmp)))&(x|((1414364997.0517852)/((tmp = -435854369, tmp)+(tmp = 2737625141, tmp)))))|(((tmp = 2241746562.2197237, tmp)^(tmp = -1606928010.1992552, tmp))|((tmp = -3083227418.686173, tmp)>>(tmp = -2717460410, tmp)))));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x *= ((tmp = 2302521322, tmp)>>>(((((((tmp = 344089066.9725498, tmp)%(tmp = 1765830559, tmp))-x)|x)^(((-2450263325)/(tmp = 371928405.17475057, tmp))>>>(1330100413.7731652)))^(((173024329)%(tmp = -2927276187, tmp))+(x>>>(-1042229940.308507))))|(((((tmp = 379074096, tmp)+((142762508)-((-2773070834.526266)-(x&((tmp = 57957493, tmp)<<(2189553500))))))+((36991093)+(tmp = 339487168.58069587, tmp)))*(-1257565451))&(tmp = 645233114, tmp)))));
+ assertEquals(-2644503151.1185284, x += (-2644503151.1185284));
+ assertEquals(-5289006302.237057, x += x);
+ assertEquals(-4008773824.2370567, x -= (tmp = -1280232478, tmp));
+ assertEquals(1975449413, x |= ((tmp = 1957832005.4285066, tmp)>>((1681236712.9715524)&(-675823978))));
+ assertEquals(-146472960, x <<= (-648510672.5644083));
+ assertEquals(-3, x |= (((((x>>>(tmp = 2271744104, tmp))+(tmp = -210058133.30147195, tmp))+(tmp = -2827493425, tmp))/(tmp = 765962538, tmp))%(tmp = 1048631551, tmp)));
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>= (1070524782.5154183));
+ assertEquals(0, x <<= (462502504));
+ assertEquals(0, x %= (540589670.0730014));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x /= ((-1268640098)%x));
+ assertEquals(NaN, x %= (1741157613.744652));
+ assertEquals(NaN, x += x);
+ assertEquals(NaN, x %= ((x|(tmp = 1992323492.7000637, tmp))*x));
+ assertEquals(NaN, x /= ((tmp = -2271503368.0341196, tmp)>>((tmp = 1224449194, tmp)>>>(tmp = 2976803997, tmp))));
+ assertEquals(NaN, x += (tmp = -1078313742.1633894, tmp));
+ assertEquals(NaN, x += (-787923311));
+ assertEquals(NaN, x %= x);
+ assertEquals(-1299878219, x ^= (2995089077));
+ assertEquals(536887953, x &= ((625660571.2651105)&(x^(((tmp = 950150725.2319129, tmp)+(-2122154205.466675))/(tmp = 1754964696.974752, tmp)))));
+ assertEquals(4096, x >>>= x);
+ assertEquals(1, x /= x);
+ assertEquals(-82508517, x ^= (((-930231800)%(tmp = -423861640.4356506, tmp))+x));
+ assertEquals(-82508517, x &= (x&x));
+ assertEquals(-479519, x %= ((tmp = 1861364600.595756, tmp)|x));
+ assertEquals(479518, x ^= (((x>>(-1539139751.6860313))>>(tmp = -456165734, tmp))|(-2786433531)));
+ assertEquals(959036, x += x);
+ assertEquals(29, x >>>= ((tmp = -1049329009.7632706, tmp)^(((((((1117739997)/(((-841179741.4939663)*(-1211599672))>>>((-413696355)%(tmp = -1753423217.2170188, tmp))))<<(tmp = 1599076219.09274, tmp))>>>(-1382960317))^(((x^(tmp = 515115394, tmp))>>>(tmp = -388476217, tmp))>>>(x/x)))^x)<<(136327532.213817))));
+ assertEquals(24, x &= (2388755418));
+ assertEquals(0, x >>>= (tmp = -405535917, tmp));
+ assertEquals(0, x &= (tmp = -1427139674, tmp));
+ assertEquals(NaN, x /= (x^((1530470340)%x)));
+ assertEquals(0, x |= ((x>>(-1429690909.8472774))*((((tmp = 2033516515, tmp)/(1314782862))>>>x)>>(tmp = 1737186497.6441216, tmp))));
+ assertEquals(0, x -= x);
+ assertEquals(0, x %= (3115422786));
+ assertEquals(-0, x *= (x+(tmp = -2558930842.267017, tmp)));
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x &= (2695531252.254449));
+ assertEquals(-613178182, x ^= (-613178182));
+ assertEquals(54, x >>>= (x%(((tmp = 2277868389, tmp)^((((tmp = -1143932265.3616111, tmp)^((x&((x-((-2100384445.7850044)|(tmp = 908075129.3456883, tmp)))*x))+(((tmp = 1031013284.0275401, tmp)*((((tmp = -233393205, tmp)>>>(tmp = -111859419, tmp))*(-1199307178))|(tmp = -1998399599, tmp)))>>>((((-731759641.9036775)>>>(tmp = 2147849691, tmp))>>>(tmp = -2121899736, tmp))>>>(x>>>x)))))>>((1900348757.360562)^(tmp = 2726336203.6149445, tmp)))>>>((x*((tmp = -2697628471.0234947, tmp)%((x^(tmp = -2751379613.9474974, tmp))*x)))+(x>>(tmp = 42868998.384643435, tmp)))))+(598988941))));
+ assertEquals(34, x &= ((tmp = 2736218794.4991407, tmp)%(2169273288.1339874)));
+ assertEquals(2.086197133417468, x /= ((tmp = 2176358852.297597, tmp)%x));
+ assertEquals(2, x <<= (((tmp = -1767330075, tmp)|(-3107230779.8512735))&x));
+ assertEquals(4194304, x <<= (tmp = 1061841749.105744, tmp));
+ assertEquals(48609515, x ^= (44415211.320786595));
+ assertEquals(48609515, x %= (1308576139));
+ assertEquals(23735, x >>>= ((-324667786)-x));
+ assertEquals(23735, x <<= ((-1270911229)<<(((((tmp = -882992909.2692418, tmp)+(tmp = 394833767.947718, tmp))-x)<<(702856751))/x)));
+ assertEquals(-31080872939240, x *= (tmp = -1309495384, tmp));
+ assertEquals(-14625.31935626114, x /= ((668084131)+(1457057357)));
+ assertEquals(-14625.31935626114, x %= (266351304.6585492));
+ assertEquals(-12577, x |= (-945583977.619837));
+ assertEquals(-4097, x |= ((tmp = -2621808583.2322493, tmp)-(tmp = -2219802863.9072213, tmp)));
+ assertEquals(-1004843865, x &= ((-1004839768)+((tmp = 2094772311, tmp)/(-1340720370.275643))));
+ assertEquals(-31401371, x >>= ((2035921047)>>>((tmp = -1756995278, tmp)>>>(-537713689))));
+ assertEquals(1791746374.016472, x -= ((tmp = -1823147745, tmp)-(x/(tmp = -1906333520, tmp))));
+ assertEquals(3.7289343120517406, x /= (tmp = 480498240, tmp));
+ assertEquals(7.457868624103481, x += x);
+ assertEquals(234881024, x <<= (-781128807.2532628));
+ assertEquals(67108864, x &= (tmp = -2060391332, tmp));
+ assertEquals(-605958718, x -= (673067582));
+ assertEquals(-605958718, x <<= ((x%x)&((tmp = 1350579401.0801518, tmp)|x)));
+ assertEquals(-109268090.4715271, x %= (tmp = -496690627.5284729, tmp));
+ assertEquals(-109268090, x <<= (((-2004197436.8023896)%((x|((tmp = 271117765.61283946, tmp)-((1595775845.0754795)*(555248692.2512416))))/x))<<x));
+ assertEquals(-652725370, x &= (-543590449));
+ assertEquals(0.321858133298825, x /= (tmp = -2027990914.2267523, tmp));
+ assertEquals(1959498446, x ^= (1959498446));
+ assertEquals(1959498446, x &= (x%(tmp = 3155552362.973523, tmp)));
+ assertEquals(14949, x >>>= ((tmp = 586618136, tmp)>>>(tmp = 699144121.9458897, tmp)));
+ assertEquals(-28611391568319.285, x *= (tmp = -1913933478.3811147, tmp));
+ assertEquals(1680557633, x &= (((tmp = 2606436319.199714, tmp)<<(1575299025.6917372))|((-1092689109)/(735420388))));
+ assertEquals(1680361024, x &= ((tmp = 1860756552.2186172, tmp)|(-360434860.1699109)));
+ assertEquals(820488, x >>>= (1788658731));
+ assertEquals(820488, x >>= (-1555444352));
+ assertEquals(2104296413, x ^= (2103543509));
+ assertEquals(16843328, x &= ((x<<((-2920883149)/(1299091676)))-(((((tmp = 3199460211, tmp)+(-237287821.61504316))&(tmp = -1524515028.3596857, tmp))-(tmp = -700644414.6785603, tmp))+(-180715428.86124516))));
+ assertEquals(1326969834, x |= (tmp = -2968063574.793867, tmp));
+ assertEquals(0, x %= (x>>>(tmp = 1350490461.0012388, tmp)));
+ assertEquals(0, x &= ((-2620439260.902854)+x));
+ assertEquals(-1775533561, x |= ((-1775533561)|(((x>>>((861896808.2264911)>>>(970216466.6532537)))%x)%(tmp = 2007357223.8893046, tmp))));
+ assertEquals(-1775533561, x &= x);
+ assertEquals(-23058877.415584415, x /= ((tmp = -3002439857, tmp)>>((((x-(tmp = 1583620685.137125, tmp))|x)%(-2568798248.6863875))^x)));
+ assertEquals(-577.4155844151974, x %= (((-1440361053.047877)+((tmp = 821546785.0910633, tmp)-(((tmp = 1023830881.1444875, tmp)/(-754884477))+(tmp = 651938896.6258571, tmp))))>>(tmp = 346467413.8959185, tmp)));
+ assertEquals(-1, x >>= (tmp = 2993867511, tmp));
+ assertEquals(-1, x |= (tmp = 823150253.4916545, tmp));
+ assertEquals(-0, x %= x);
+ assertEquals(-0, x /= ((tmp = 997969036, tmp)&((((tmp = 928480121, tmp)>>(((-2610875857.086055)>>>(tmp = -2251704283, tmp))|x))+(10781750))>>x)));
+ assertEquals(0, x >>>= ((tmp = -1872319523, tmp)>>>(-278173884)));
+ assertEquals(0, x |= (x/(x*x)));
+ assertEquals(0, x %= ((77912826.10575807)^(tmp = 2770214585.3019757, tmp)));
+ assertEquals(0, x &= (tmp = 722275824, tmp));
+ assertEquals(-1417226266, x |= (tmp = 2877741030.1195555, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x %= (tmp = -1740126105, tmp));
+ assertEquals(910709964, x |= (tmp = 910709964, tmp));
+ assertEquals(-1744830464, x <<= (tmp = -2445932551.1762686, tmp));
+ assertEquals(318767104, x >>>= (tmp = -2465332061.628887, tmp));
+ assertEquals(301989888, x &= (-2771167302.022801));
+ assertEquals(301989888, x |= x);
+ assertEquals(37748736, x >>= (tmp = -835820125, tmp));
+ assertEquals(1474977371, x ^= (tmp = -2857738661.6610327, tmp));
+ assertEquals(470467500, x += (-1004509871));
+ assertEquals(0.30466562575942585, x /= (((tmp = 1515955042, tmp)<<(x+((1607647367)-(tmp = 1427642709.697169, tmp))))^x));
+ assertEquals(1.0348231148499734e-10, x /= (tmp = 2944132397, tmp));
+ assertEquals(0, x >>= (x>>>(tmp = -2847037519.569043, tmp)));
+ assertEquals(NaN, x /= x);
+ assertEquals(0, x >>>= (-1817784819.9058492));
+ assertEquals(0, x >>= x);
+ assertEquals(-0, x *= ((tmp = -1387748473, tmp)|(x+(352432111))));
+ assertEquals(-0, x *= (((-2591789329)/(tmp = -2144460203, tmp))>>(tmp = -568837912.5033123, tmp)));
+ assertEquals(0, x <<= (-2963600437.305708));
+ assertEquals(0, x &= ((588720662)>>>x));
+ assertEquals(1561910729, x += (1561910729));
+ assertEquals(0, x ^= x);
+ assertEquals(-0, x *= (-2722445702));
+ assertEquals(0, x &= (tmp = -2738643199.732308, tmp));
+ assertEquals(0, x /= (((1859901899.227291)>>>((tmp = -1067365693, tmp)+((-1975435278)|x)))|((1844023313.3719304)&(tmp = -624215417.0227654, tmp))));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x %= (-2852766277));
+ assertEquals(0, x <<= (-1482859558));
+ assertEquals(0, x >>= x);
+ assertEquals(-1196775786, x += (tmp = -1196775786, tmp));
+ assertEquals(-68176201, x |= ((tmp = 2336517643, tmp)+x));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x >>= (2969141362.868086));
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x >>= ((x-((((tmp = -905994835, tmp)|(tmp = 2850569869.33876, tmp))<<((-2405056608.27147)>>(tmp = 1280271785, tmp)))&(-1942926558)))*(tmp = 707499803.177796, tmp)));
+ assertEquals(0, x &= ((-697565829.8780258)+((2978584888.549406)%x)));
+ assertEquals(0, x >>= (748642824.4181392));
+ assertEquals(0, x += x);
+ assertEquals(0, x >>>= (-1701028721));
+ assertEquals(92042539, x -= ((-92042539)|(x*(x%(-293705541.00228095)))));
+ assertEquals(0, x %= x);
+ assertEquals(0, x >>= x);
+ assertEquals(0, x %= (-2278672472.458228));
+ assertEquals(0, x %= (((-2374117528.0359464)/((tmp = -2809986062, tmp)|(tmp = 895734980, tmp)))&(tmp = 1564711307.41494, tmp)));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x += x);
+ assertEquals(-0, x /= ((tmp = -2749286790.3666043, tmp)<<(x^(-2966741582.324482))));
+ assertEquals(0, x *= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(-1882562314, x ^= (2412404982.782115));
+ assertEquals(-806620, x %= (((tmp = 1527219936.5232096, tmp)*(-1139841417))>>>(tmp = 201632907.3236668, tmp)));
+ assertEquals(-1613240, x += x);
+ assertEquals(-1664766177387640, x *= (1031939561));
+ assertEquals(-9.478083550117849e+23, x *= (tmp = 569334221.1571662, tmp));
+ assertEquals(-8.462574598319509e+21, x /= ((x-(tmp = -2985531211.114498, tmp))>>(tmp = 174615992.91117632, tmp)));
+ assertEquals(1638924288, x <<= (((((x>>((-1823401733.4788911)+((tmp = 1362371590, tmp)>>>x)))^(tmp = -56634380, tmp))/(tmp = 2387980757.1540084, tmp))%((((tmp = -3175469977, tmp)^(tmp = -1816794042, tmp))+(232726694))*(tmp = 822706176, tmp)))/(tmp = 1466729893.836311, tmp)));
+ assertEquals(2686072821796307000, x *= x);
+ assertEquals(-1007977445.9812208, x /= (-2664814408.800125));
+ assertEquals(-1007977445, x &= x);
+ assertEquals(322314656346249100, x *= (tmp = -319763758.54942775, tmp));
+ assertEquals(197436885.26815608, x /= (tmp = 1632494637, tmp));
+ assertEquals(-67191339, x |= ((-399580815.1746769)/((1335558363)/(tmp = 224694526, tmp))));
+ assertEquals(1229588737, x &= (tmp = 1296763683.5732255, tmp));
+ assertEquals(1229588737, x -= ((((1171546503)|((tmp = -2701891308, tmp)%(-2155432197.022206)))/(-306122816.85682726))>>x));
+ assertEquals(4162606632, x -= (tmp = -2933017895, tmp));
+ assertEquals(1.6487311395551163, x /= (2524733434.1748486));
+ assertEquals(-1929308648.9913044, x += (-1929308650.6400356));
+ assertEquals(-3858617297.982609, x += x);
+ assertEquals(788529152, x <<= (x^(1401824663)));
+ assertEquals(6160384, x >>>= ((((((x>>>x)>>((((x*(tmp = -1958877151, tmp))>>>(1310891043))-(tmp = 564909413.9962088, tmp))%(-175978438)))%x)|((tmp = -1193552419.7837512, tmp)*(tmp = 1508330424.9068346, tmp)))|(1428324616.3303494))-((1828673751)/(tmp = 1281364779, tmp))));
+ assertEquals(6160384, x |= x);
+ assertEquals(1, x /= x);
+ assertEquals(1, x &= (tmp = -855689741, tmp));
+ assertEquals(0, x >>>= x);
+ assertEquals(-1088569655.3528988, x -= (tmp = 1088569655.3528988, tmp));
+ assertEquals(-1088569655, x >>= ((tmp = 2429646226.626727, tmp)<<((-1539293782.4487276)>>(x^((tmp = 1140855945.537702, tmp)+x)))));
+ assertEquals(-311, x %= ((x/x)<<x));
+ assertEquals(1.2007722007722008, x /= (x|(tmp = 448796341.87655175, tmp)));
+ assertEquals(3, x |= (x+x));
+ assertEquals(-9.32416092168023e-10, x /= (-3217447688));
+ assertEquals(0, x >>= (615837464.0921166));
+ assertEquals(0, x >>>= (tmp = -2993750670.683118, tmp));
+ assertEquals(0, x >>>= (x%x));
+ assertEquals(1610612736, x ^= ((-1322905256.6770213)<<(-2567950598)));
+ assertEquals(1693676493, x ^= (83063757.63660407));
+ assertEquals(-758030371, x ^= (tmp = -1239274480, tmp));
+ assertEquals(-758030371, x %= (tmp = 1961339006, tmp));
+ assertEquals(-1509754528, x ^= (tmp = 1960027837, tmp));
+ assertEquals(-1509754528, x <<= x);
+ assertEquals(-1509754528, x -= (((tmp = -50690205.33559728, tmp)/((tmp = -1364565380, tmp)<<(tmp = 2585052504, tmp)))<<(tmp = -2356889596, tmp)));
+ assertEquals(1, x >>>= (-3204164321));
+ assertEquals(1, x *= x);
+ assertEquals(1114370230.591965, x *= ((tmp = 1114370229.591965, tmp)+x));
+ assertEquals(-4.886305275432552, x /= ((-228059887.33344483)%(2841553631.3685856)));
+ assertEquals(2.358309397373389e-9, x /= (((x*(tmp = 203428818.08174622, tmp))&(x-(((510438355)*x)+x)))+x));
+ assertEquals(0, x >>>= ((tmp = 1444810010, tmp)&(tmp = -3135701995.2235208, tmp)));
+ assertEquals(0, x /= (1865982928.6819582));
+ assertEquals(0, x *= x);
+ assertEquals(2078726016.3772051, x -= (tmp = -2078726016.3772051, tmp));
+ assertEquals(1580337898, x ^= ((tmp = -2714629398.447015, tmp)^x));
+ assertEquals(1268363034, x -= ((x+((tmp = 1144068248.3834887, tmp)&(-954104940.155973)))<<(tmp = 1270573731.7828264, tmp)));
+ assertEquals(1744830464, x <<= (((1444869551.7830744)>>>((((x+(tmp = -904688528, tmp))<<x)-((tmp = 121151912.85873199, tmp)/(tmp = -2414150217.66479, tmp)))|(((-472906698)|(3215236833.8417764))+(907737193.9056952))))-((x&(-732223723))|(-221800427.7392578))));
+ assertEquals(717338523283226600, x *= (x^(tmp = -2407450097.0604715, tmp)));
+ assertEquals(402653184, x >>= ((-3191405201.168252)*((tmp = -1941299639.695196, tmp)|(((x>>(((3215741220)>>>x)/(x+x)))^(((tmp = -2144862025.9842231, tmp)|((tmp = -1966913385, tmp)&x))%x))*((tmp = -1124749626.6112225, tmp)/(tmp = 837842574, tmp))))));
+ assertEquals(402653184, x &= ((x|x)>>x));
+ assertEquals(134217728, x &= ((2720231644.3849487)*x));
+ assertEquals(134217726.75839183, x -= ((2438054684.738043)/(((((-984359711)*(x|((tmp = 177559682, tmp)^x)))/(-1253443505))/((2727868438.416792)*(x+((x<<(((tmp = 3023774345, tmp)&(-705699616.0846889))/x))<<x))))^(1963626488.548761))));
+ assertEquals(1, x /= x);
+ assertEquals(245781494, x += ((tmp = 2551445099, tmp)^(2528486814)));
+ assertEquals(-1474427807, x ^= (-1497868393.342241));
+ assertEquals(-1057271682, x += ((((((x>>x)%(-1556081693))|(x/(((1166243186.6325684)-(((tmp = 2870118257.1019487, tmp)/(x+(-69909960)))^(2270610694.671496)))/((1463187204.5849519)-x))))-x)-(x<<(-3077313003)))%x));
+ assertEquals(-1065725846, x &= ((tmp = -1808223767, tmp)|(-481628214.3871765)));
+ assertEquals(-1065725846, x ^= (x&(((tmp = -1785170598, tmp)-(tmp = -2525350446.346484, tmp))/((((((-1783948056)^(tmp = 3027265884.41588, tmp))|((((tmp = 2195362566.2237773, tmp)<<(-2919444619))<<((tmp = -2507253075.2897573, tmp)^(x^((tmp = 1067516137, tmp)+((667737752)^(x*(tmp = -1187604212.7293758, tmp)))))))%(-617406719.5140038)))*(tmp = 511060465.6632478, tmp))*((tmp = 2580189800.752836, tmp)|((((tmp = 2357895660, tmp)%((-814381220)*(x-((x>>>(((x<<x)<<(tmp = 1919573020, tmp))-x))>>>((-2756011312.136148)>>(tmp = -1603458856, tmp))))))/((tmp = -1609199312, tmp)&(-3127643445)))%x)))<<(-2261731798)))));
+ assertEquals(1.6020307924030301, x /= (tmp = -665234308.2628405, tmp));
+ assertEquals(-1120020556.697667, x *= (tmp = -699125486.2321637, tmp));
+ assertEquals(-215875188, x -= (((((tmp = -1307845034, tmp)>>>((((-2820720421)^x)-(((x<<x)|(tmp = -3042092997.57406, tmp))+(((-1294857544)+((tmp = -668029108.1487186, tmp)>>(x<<x)))^(912144065.5274727))))^(389671596.2983854)))|(-2774264897.146559))%(x-((tmp = 1378085269, tmp)^x)))+((-1659377450.5247462)&(((1613063452.834885)>>>((-344896580.0694165)>>>((-13450558)+x)))^x))));
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>>= (2355750790));
+ assertEquals(1969435421.4409347, x += (1969435421.4409347));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>>= (((x*((-1022802960.6953495)<<(tmp = -2848428731.8339424, tmp)))^(-1630921485))%(1532937011)));
+ assertEquals(0, x <<= ((x+((x^(x^(tmp = 2017651860, tmp)))&(((x<<(((tmp = -1913317290.8189478, tmp)|(x-((((x%((tmp = -3035245210, tmp)+(-2270863807)))>>>((-2351852712)*(x^(-2422943296.0239563))))&((((-1578312517)%x)*x)*(-65592270.28452802)))>>>(tmp = 1104329727.2094703, tmp))))-(tmp = -1431159990.3340137, tmp)))&x)|((tmp = -2589292678.801344, tmp)&(x+((((tmp = -2557773457.456996, tmp)>>(451910805.309445))-x)>>(((tmp = -1937832765.7654495, tmp)^x)%x)))))))%x));
+ assertEquals(0, x %= (tmp = -626944459, tmp));
+ assertEquals(-732310021, x |= (tmp = -732310021, tmp));
+ assertEquals(-732310021, x |= x);
+ assertEquals(671352839, x ^= (x-((-3087309090.7153115)|x)));
+ assertEquals(134479872, x &= (tmp = 2357183984, tmp));
+ assertEquals(18084835973136384, x *= x);
+ assertEquals(0, x <<= ((1040482277)-(tmp = -357113781.82650447, tmp)));
+ assertEquals(74957, x |= ((((tmp = -70789345.7489841, tmp)%(tmp = 1415750131, tmp))&x)|((307027314)>>(2284275468))));
+ assertEquals(9, x >>>= x);
+ assertEquals(0, x &= (x&((x*((x*(x%x))%(x>>x)))/x)));
+ assertEquals(-1872875060, x |= (2422092236.6850452));
+ assertEquals(9, x >>>= (-382763684));
+ assertEquals(4608, x <<= x);
+ assertEquals(40.480234260614935, x /= (((((((tmp = 814638767.5666755, tmp)&((tmp = 2081507162, tmp)^(x>>>(1460148331.2229118))))&(tmp = 1187669197.7318723, tmp))<<(412000677.93339765))^((tmp = 556111951, tmp)>>(tmp = -2232569601.292395, tmp)))&(-3006386864))/x));
+ assertEquals(32, x &= (-3053435209.383913));
+ assertEquals(418357217, x ^= (418357185));
+ assertEquals(204275, x >>= ((-1188650337.9010527)^((51494580)%(-2544545273))));
+ assertEquals(982392804, x += (((x+(((tmp = -982596937.9757051, tmp)+x)%(-2298479347)))^((((tmp = 1610297674.0732534, tmp)>>>x)*(((x>>(-2746780903.08599))&(-2376190704.247188))^(((20545353)/(tmp = 1468302977, tmp))-(x<<x))))>>(((-1434332028.0447056)/((tmp = 1983686888, tmp)&((tmp = 2324500847, tmp)%(394330230.6163173))))%(((-1129687479.2158055)+((-3127595161)*((-3066570223)&((tmp = 3192134577.4963055, tmp)/(-2697915283.3233275)))))+(-1112243977.5306559)))))|(x&(-2622725228))));
+ assertEquals(-2735750653096133600, x *= (-2784782870.9218984));
+ assertEquals(-1876329472, x |= ((((((2752866171)<<(-1681590319))/x)>>((tmp = 1451415208, tmp)>>>(1126858636.6634417)))+(((tmp = 2165569430.4844217, tmp)/x)^(((tmp = -1675421843.4364457, tmp)-(-2187743422.2866993))|x)))*x));
+ assertEquals(3520612287495799000, x *= x);
+ assertEquals(-200278016, x |= ((((-2379590931)%((((-1558827450.833285)&x)>>(-665140792))-((tmp = -445783631.05567217, tmp)+(tmp = 93938389.53113222, tmp))))/(3103476273.734701))^x));
+ assertEquals(-9178285062592.75, x *= ((2042671875.7211144)%(((tmp = 589269308.0452716, tmp)/x)<<(-130695915.9934752))));
+ assertEquals(60048960, x |= (x<<x));
+ assertEquals(60048960, x <<= ((((((tmp = -2793966650, tmp)/(-2882180652))&(((x<<((tmp = -384468710, tmp)+(2236162820.9930468)))>>>((((969371919)>>((tmp = -3153268403.2565875, tmp)-((((573811084)/x)^(tmp = -968372697.4844134, tmp))>>>(((-3096129189)>>x)/(tmp = 830228804.6249363, tmp)))))<<(((1243972633.3592157)|x)&((-1687610429)&(tmp = -1945063977.458529, tmp))))<<(((tmp = -217456781.37068868, tmp)-(400259171.68077815))^x)))>>>x))%(((2728450651.300167)/(((-2713666705.089135)%(tmp = 740472459, tmp))^x))|x))^x)*(-2463032364)));
+ assertEquals(60048960, x %= (tmp = -442107222.9513445, tmp));
+ assertEquals(-1573781504, x <<= (960581227));
+ assertEquals(1297, x >>>= (tmp = -1692919563, tmp));
+ assertEquals(1297, x &= x);
+ assertEquals(-3113308397155.233, x *= (tmp = -2400391979.3024154, tmp));
+ assertEquals(-3115513013486.233, x -= (2204616331));
+ assertEquals(-3113809649082.233, x -= (-1703364404));
+ assertEquals(0, x >>>= (((-1181206665)-(550946816.586771))|(tmp = -2346300456, tmp)));
+ assertEquals(0, x %= (tmp = 1649529739.2785435, tmp));
+ assertEquals(0, x ^= ((tmp = -2452761827.2870226, tmp)%(((1090281070.5550141)/(tmp = 992149154.6500508, tmp))*(x<<((((((x>>>x)|((tmp = -2410892363, tmp)%(tmp = 2585150431.0231533, tmp)))/x)*(tmp = 1541294271, tmp))+x)&((97566561.77126992)&((((-640933510.1287451)&(((((x>>>((-1821077041)<<((tmp = -1138504062.093695, tmp)-(tmp = -181292160, tmp))))%x)-(x>>((x&(((tmp = 1067551355, tmp)/(x|(1004837864.8550552)))&(x-(-103229639.25084043))))&((tmp = 2064184671.210937, tmp)+((((tmp = -2245728052, tmp)|(1538407002.8365717))+(x<<((x>>((76549490)/(tmp = 628901902.6084052, tmp)))<<((x<<x)^(-1907669184)))))+(-1409123688))))))>>>((((-1911547456.933543)-((-512313175)+((tmp = -2620903017, tmp)^(tmp = 2148757592.244808, tmp))))<<((-1740876865)>>>x))+((tmp = 691314720.9488736, tmp)<<(614057604.4104803))))|(x^((tmp = -3040687.291528702, tmp)/(x^(((x+(-2899641915))^((tmp = -1220211746, tmp)/x))%x))))))^(tmp = 119850608, tmp))%(2091975696))))))));
+ assertEquals(291273239, x -= (tmp = -291273239, tmp));
+ assertEquals(2206394018, x += (1915120779));
+ assertEquals(235641480, x <<= (x&(x&(-1810963865.1415658))));
+ assertEquals(28764, x >>= ((tmp = -1927011875, tmp)^((tmp = -1986461808, tmp)|((-868139264.8399222)*((421956566)%(3068424525))))));
+ assertEquals(-99780626900900, x *= ((tmp = -1512869526.3223472, tmp)+(tmp = -1956071751, tmp)));
+ assertEquals(51218520, x &= (((-2353401311)>>>x)-(2216842509)));
+ assertEquals(51218520, x >>>= ((tmp = -1534539302.6990812, tmp)<<x));
+ assertEquals(-2147483648, x <<= (-292608644));
+ assertEquals(-2147483648, x |= ((((((x<<((-2981292735)-x))>>((tmp = 2540545320.96558, tmp)&(tmp = -2343790880, tmp)))>>>((((((x^((-172697043.94487858)/((2627260337)>>(2879112814.1247935))))&(tmp = 3000943191, tmp))<<(tmp = 1094830905, tmp))-x)>>>x)>>((((tmp = 3095796200, tmp)^(x|(tmp = 1460377694, tmp)))<<(x^(tmp = -357546193, tmp)))/((2729539495)>>x))))%(tmp = 268894171.74961245, tmp))|(x>>(tmp = 2735650924, tmp)))/(-2197885357.09768)));
+ assertEquals(-2147483648, x |= x);
+ assertEquals(-1967162776824578000, x *= (tmp = 916031551, tmp));
+ assertEquals(-2147483648, x &= x);
+ assertEquals(-457743917756973060, x *= (tmp = 213153622, tmp));
+ assertEquals(0, x >>>= ((((tmp = 2930076928.480559, tmp)+(x^x))<<(tmp = -1349755597.1280541, tmp))|(x+(2865632849))));
+ assertEquals(0, x <<= ((x>>x)-(x>>(-2629977861))));
+ assertEquals(0, x <<= x);
+ assertEquals(NaN, x /= x);
+ assertEquals(0, x |= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(749327478, x |= ((tmp = 749327478, tmp)^(x>>(tmp = 881107862, tmp))));
+ assertEquals(1897869364, x += (1148541886));
+ assertEquals(463347, x >>>= (tmp = -726431220, tmp));
+ assertEquals(-395990542, x += (-396453889));
+ assertEquals(-2824792585.1675367, x -= (2428802043.1675367));
+ assertEquals(-2147483648, x <<= (tmp = -1420072385.9175675, tmp));
+ assertEquals(8388608, x >>>= (-2211390680.488455));
+ assertEquals(8388608, x >>= (((x/(x|(((x^(((tmp = -2175960170.8055067, tmp)|((tmp = -1964957385.9669886, tmp)/(tmp = -475033330, tmp)))&((x|((tmp = 1386597019.2014387, tmp)>>((tmp = -2406589229.8801174, tmp)+x)))<<(tmp = -844032843.8415492, tmp))))>>(x^x))|x)))-((x&((tmp = 1858138856, tmp)*(-3156357504)))%x))<<(((2046448340)+x)/(-2645926916))));
+ assertEquals(8359470765396279, x *= ((tmp = 871437183.7888144, tmp)-(-125089387.17460155)));
+ assertEquals(0, x ^= x);
+ assertEquals(-303039014, x += ((tmp = -2475713214, tmp)|(-372871718.2343409)));
+ assertEquals(2655126577, x -= (-2958165591));
+ assertEquals(1830332793, x ^= (tmp = -212161208, tmp));
+ assertEquals(1830332793, x ^= (((2352454407.0126333)<<((((tmp = 3083552367, tmp)/x)-(-1243111279))-((tmp = -1669093976, tmp)%(((-757485455)-(tmp = -116051602, tmp))<<x))))>>(((((-2235071915.9536905)>>(tmp = -1284656185, tmp))-x)>>((-1807028069.7202528)>>>((x%((tmp = -3070857953.311804, tmp)+((tmp = 2759633693.441942, tmp)%((169489938)*(-1582267384)))))<<(x^((tmp = -787578860, tmp)<<x)))))>>((x/(x|(409464362)))-(tmp = -64033017, tmp)))));
+ assertEquals(397605933.90319204, x %= (tmp = 716363429.548404, tmp));
+ assertEquals(186400, x &= (((x%(-1745754586))>>>x)<<(x&(x&((-2163627752)-((1784050895)+(((-2864781121.899456)>>>x)&x)))))));
+ assertEquals(186400, x %= (tmp = -423209729, tmp));
+ assertEquals(186400, x <<= ((x<<(x+(1232575114.4447284)))*x));
+ assertEquals(1386299, x ^= ((tmp = -1074209615, tmp)>>>(x>>>((tmp = -1456741008.2654872, tmp)>>((1724761067)>>(-2016103779.9084842))))));
+ assertEquals(347302967.20758367, x -= (-345916668.20758367));
+ assertEquals(1.9325619389304094, x /= (179711170.03359854));
+ assertEquals(-3703324711.628227, x *= (tmp = -1916277371, tmp));
+ assertEquals(-920980517031624800, x *= (tmp = 248690187.53332615, tmp));
+ assertEquals(0, x &= (((tmp = -2753945953.082594, tmp)*x)-(172907186)));
+ assertEquals(-0, x /= (((((-2744323543.187253)>>((tmp = 2663112845, tmp)>>(((-121791600)+(x^x))*(2758944252.4214177))))|x)/(tmp = -2746716631.6805267, tmp))-x));
+ assertEquals(0, x ^= ((tmp = 983113117, tmp)&((2638307333)+((((tmp = 3076361304.56189, tmp)<<(-2663410588.5895214))%((-1109962112)-(tmp = -2381021732, tmp)))%((tmp = 410559095, tmp)&x)))));
+ assertEquals(0, x <<= (tmp = 1510895336.5111506, tmp));
+ assertEquals(0, x <<= (tmp = -1688348296.2730422, tmp));
+ assertEquals(2269471424, x -= (-2269471424));
+ assertEquals(-2022580224, x ^= (x%((tmp = 160999480.21415842, tmp)&x)));
+ assertEquals(-2077171712, x &= (tmp = 3032415014.3817654, tmp));
+ assertEquals(270727, x >>>= (2973489165.1553965));
+ assertEquals(270727, x |= x);
+ assertEquals(-1895894537, x |= ((tmp = -1895903118.129186, tmp)|x));
+ assertEquals(-1895894537, x -= ((((((((3143124509)>>>(-2866190144.8724117))*((x>>((961021882)*(tmp = 2363055833.8634424, tmp)))/((2032785518)+((2713643671.3420825)>>((-447782997.0173557)*((tmp = 1174918125.3178625, tmp)*((((tmp = -541539365.548115, tmp)%(-359633101))|(1765169562.2880063))+(tmp = -2512371966.374508, tmp))))))))/x)>>(x*((((-847238927.6399388)&(857288850))%(-2427015402))^((2221426567)%(x+x)))))>>>x)<<((tmp = 2009453564.2808268, tmp)>>((2924411494)<<(x>>(tmp = -1240031020.8711805, tmp)))))%(tmp = 3118159353, tmp)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x %= (-30151583));
+ assertEquals(-1035186736, x ^= ((tmp = -517593368, tmp)<<(tmp = 3216155585, tmp)));
+ assertEquals(49740, x >>>= x);
+ assertEquals(49740, x %= (640223506));
+ assertEquals(388, x >>>= ((x>>(tmp = 3161620923.50496, tmp))+(2605183207)));
+ assertEquals(776, x += x);
+ assertEquals(-97905, x ^= ((((((tmp = 145447047.8783008, tmp)^(((x>>>(tmp = 3014858214.2409887, tmp))>>>(629911626.132971))>>(((x+((369309637.229408)-x))<<(-2661038814.9204755))*(x+(x%(3025191323.4780884))))))+x)*(-482550691))|(-632782135))/x));
+ assertEquals(-97905, x %= ((((-492914681)-((-2508632959.269368)&(tmp = 1209318291, tmp)))>>(-723512989.459533))>>>(((-528429623.985692)&(x^(tmp = -925044503, tmp)))-(-1696531234))));
+ assertEquals(9585389025, x *= x);
+ assertEquals(-715425728, x <<= ((583763091)<<(-1223615295)));
+ assertEquals(-520093696, x <<= ((tmp = -1891357699.671592, tmp)*(((tmp = 3206095739.5163193, tmp)+(-2908596651.798733))>>>((tmp = -2820415686, tmp)>>(x|((((tmp = -566367675.6250327, tmp)*(-959117054))>>((((-187457085.89686918)*x)*(tmp = -2394776877.5373516, tmp))>>>x))|(((tmp = 80478970.46290505, tmp)<<(tmp = 2173570349.493097, tmp))-(x/((-2896765964)-((x/((tmp = 198741535.7034216, tmp)%(436741457)))%(tmp = 2936044280.0587225, tmp)))))))))));
+ assertEquals(-2520.5909527086624, x /= ((211290893.06029093)>>(663265322)));
+ assertEquals(-2520.5909527086624, x %= (x^((1057915688)<<(tmp = 1914820571.1142511, tmp))));
+ assertEquals(1, x >>>= (((894963408.7746166)+(tmp = -2888351666, tmp))|x));
+ assertEquals(-1989841636629996300, x += ((1424670316.224575)*((-2144149843.0876865)|((((421479301.0983993)|((3082651798)^(tmp = -271906497, tmp)))>>x)+((tmp = -178372083, tmp)%x)))));
+ assertEquals(17935384255.088326, x /= (((((((tmp = 1168194849.2361898, tmp)>>>(-107316520.53815603))>>>(x^(((x%((x>>>(((-2456622387)/x)&((2124689803)|(((-1130151701)^(2796315158))>>x))))-((-884686033.5491502)>>>((-2371185318.5358763)&x))))+(tmp = 558422989, tmp))|((tmp = -420359120.0596726, tmp)/((-1820568437.0587764)&(2298602280.266465))))))>>(x-((tmp = -1164568978, tmp)^x)))^x)-x)+x));
+ assertEquals(134233150, x &= ((x>>(((tmp = 98498118.13041973, tmp)-(804574397))/(tmp = -1564490985.7904541, tmp)))+x));
+ assertEquals(4, x >>= (449610809));
+ assertEquals(1912543790, x |= (1912543790));
+ assertEquals(2487274263, x += (tmp = 574730473, tmp));
+ assertEquals(-2140759118, x ^= (tmp = 338055333.9701035, tmp));
+ assertEquals(311607367, x += (2452366485));
+ assertEquals(9509, x >>= (372113647.84365284));
+ assertEquals(-2001075684.1562128, x += (-2001085193.1562128));
+ assertEquals(-638703280, x ^= (((tmp = 1096152237, tmp)&x)|((2707404245.0966487)-(((tmp = 1550233654.9691348, tmp)+(tmp = 2008619647, tmp))&((tmp = -2653266325, tmp)+(tmp = -280936332, tmp))))));
+ assertEquals(-101811850, x |= (-2250090202));
+ assertEquals(-13, x >>= ((-561312810.0218933)|(tmp = 79838949.86521482, tmp)));
+ assertEquals(-13, x >>= ((tmp = -936543584, tmp)/(1180727664.1746705)));
+ assertEquals(-1547, x *= (((tmp = 1005197689, tmp)>>>x)>>>(tmp = 34607588, tmp)));
+ assertEquals(2393209, x *= x);
+ assertEquals(2393209, x |= x);
+ assertEquals(0, x >>= (-2691279235.1215696));
+ assertEquals(0, x *= (((896175510.4920144)*((((tmp = 1770236555.7788959, tmp)%(537168585.7310632))/x)&(tmp = 1094337576, tmp)))&(((x-x)-x)>>x)));
+ assertEquals(-1922620126, x ^= (-1922620126));
+ assertEquals(3.43481396325761, x /= (tmp = -559745053.6088333, tmp));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x >>>= (tmp = 2106956255.6602135, tmp));
+ assertEquals(-1339003770, x ^= ((tmp = 2955963526.960022, tmp)+x));
+ assertEquals(-0, x *= ((((tmp = 368669994, tmp)>>>(x*x))<<(tmp = 2355889375, tmp))&(tmp = -2267550563.9174895, tmp)));
+ assertEquals(0, x >>= (753848520.8946902));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x %= ((tmp = -2872753234.2257266, tmp)|x));
+ assertEquals(NaN, x %= (x>>>(tmp = 890474186.0898918, tmp)));
+ assertEquals(NaN, x %= ((tmp = 1341133992.284471, tmp)&(tmp = -2979219283.794898, tmp)));
+ assertEquals(NaN, x += (-2865467651.1743298));
+ assertEquals(NaN, x += ((-1424445677)%(x^(tmp = 1150366884, tmp))));
+ assertEquals(0, x &= (x+((tmp = 1499426534, tmp)+x)));
+ assertEquals(0, x |= (((((tmp = -2413914642, tmp)<<((x>>>x)^(1218748804)))+((((-1085643932.2642736)-(-1199134221.533854))>>(tmp = 2148778719, tmp))-((tmp = 1589158782.0040946, tmp)/(tmp = -2485474016.1575155, tmp))))>>>(x>>x))/(2230919719)));
+ assertEquals(0, x %= ((tmp = -2576387170.517563, tmp)>>>((tmp = -2362334915.919525, tmp)>>>(((3096453582)-(700067891.4834484))^(2396394772.9253683)))));
+ assertEquals(-1798103432, x ^= (((((tmp = 2396144191, tmp)*(x>>>(1512158325)))&(((-1256228298.5444434)&(((-2963136043.434966)&((tmp = 2472984854, tmp)+(tmp = -454900927, tmp)))%(tmp = 484255852.65332687, tmp)))>>((x%x)-x)))&(tmp = 929723984, tmp))^(tmp = -1798103432.5838807, tmp)));
+ assertEquals(-2137913344, x &= ((((x|(-2970116473))&(((x/x)/((tmp = 2853070005, tmp)>>>x))%(((tmp = -3123344846, tmp)/((2224296621.6742916)-(tmp = -2246403296.455411, tmp)))+((x&(((x^(x*(2829687641)))+x)&(tmp = 988992521, tmp)))^x))))<<((((-820608336)^(tmp = 2851897085, tmp))>>(tmp = -402427624, tmp))>>>x))-(((x*(((-2287402266.4821453)%(tmp = -520664172.1831205, tmp))^(x/(1875488837))))<<(tmp = 402393637, tmp))&(tmp = 1576638746.3047547, tmp))));
+ assertEquals(-2827557853031924000, x *= (tmp = 1322578326.6507945, tmp));
+ assertEquals(6.424459501778244e+27, x *= (tmp = -2272087729.3065624, tmp));
+ assertEquals(-1586887483, x |= (-1586887483));
+ assertEquals(-567868980691736100, x *= (tmp = 357850816, tmp));
+ assertEquals(1489101591, x ^= (x%(x|(421921075))));
+ assertEquals(-801213804822328000, x *= (x|(-672326904.6888077)));
+ assertEquals(612257233.6612054, x /= (((tmp = -350127617, tmp)>>>(-1140467595.9752212))<<((x^x)+(-3117914887))));
+ assertEquals(19097.231243331422, x /= ((x^(tmp = -570012517, tmp))>>>x));
+ assertEquals(0, x >>= ((x%(((-2347648358)%((x-(tmp = -456496327, tmp))|(x^(-1977407615.4582832))))<<(x/(tmp = -2021394626.214082, tmp))))%(tmp = -949323000.2442119, tmp)));
+ assertEquals(0, x <<= x);
+ assertEquals(NaN, x %= (x^(x>>(((tmp = 597147546.7701412, tmp)&(((((-972400689.6267757)|(tmp = -2390675341.6367044, tmp))|(tmp = 1890069123.9831812, tmp))<<(((1606974563)-(tmp = -2211617255.8450356, tmp))&((((x+((2433096953)&(-2527357746.681596)))*(tmp = -313956807.55609417, tmp))|((tmp = -2146031047.968496, tmp)/(tmp = 2851650714.68952, tmp)))>>(((tmp = 2630692376.6265225, tmp)-(tmp = -3162222598, tmp))>>((tmp = 1915552466, tmp)*(x>>>(-2413248225.7536864)))))))&(x%((((1218471556)|x)+(tmp = -849693122.6355379, tmp))+x))))>>>(x/((tmp = 689889363, tmp)/x))))));
+ assertEquals(0, x >>>= (45649573.23297));
+ assertEquals(0, x >>>= (tmp = 1084439432.771266, tmp));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x *= (tmp = 1642750077, tmp));
+ assertEquals(0, x >>>= (tmp = -1944001182.0778434, tmp));
+ assertEquals(1682573000, x |= (tmp = -2612394296.2858696, tmp));
+ assertEquals(3041823595, x -= (((tmp = 720576773, tmp)|(x^(-1068335724.2253149)))>>(x*(-2501017061))));
+ assertEquals(6083647190, x += x);
+ assertEquals(-6536258988089986000, x *= ((tmp = 632312939.6147232, tmp)|((-1621821634)+(((tmp = -2281369913.562131, tmp)&((tmp = -381226774, tmp)|x))&(664399051)))));
+ assertEquals(4.272268155938712e+37, x *= x);
+ assertEquals(733271152, x %= (-1345127171));
+ assertEquals(847089925, x ^= (tmp = 432620917.57699084, tmp));
+ assertEquals(1337073824, x <<= x);
+ assertEquals(-25810602, x ^= (tmp = 2982414838, tmp));
+ assertEquals(-25282209, x |= ((tmp = -2927596922, tmp)>>>(-2404046645.01413)));
+ assertEquals(639190091919681, x *= x);
+ assertEquals(173568320, x &= ((((tmp = -718515534.4119437, tmp)&(tmp = 2989263401, tmp))<<x)|((tmp = 537073030.5331153, tmp)-(tmp = 883595389.314624, tmp))));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>>= (tmp = -1844717424.917882, tmp));
+ assertEquals(0, x >>= (tmp = -462881544.2225325, tmp));
+ assertEquals(0, x >>= x);
+ assertEquals(-1868450038, x ^= (2426517258.6111603));
+ assertEquals(1, x /= x);
+ assertEquals(1175936039.4202638, x += (tmp = 1175936038.4202638, tmp));
+ assertEquals(-127916015, x ^= ((x/(1841969600.3012052))-(tmp = 1099467723, tmp)));
+ assertEquals(395713785658171900, x *= (-3093543726));
+ assertEquals(395713787128560900, x += (((((-717204758)*(tmp = -588182129.6898501, tmp))-x)+(tmp = 20638023, tmp))^x));
+ assertEquals(-962609355, x |= ((x^(-3118556619.912983))<<((tmp = 876126864, tmp)&x)));
+ assertEquals(-962609355, x %= (tmp = -2079049990, tmp));
+}
+f();
diff --git a/deps/v8/test/mjsunit/numops-fuzz-part2.js b/deps/v8/test/mjsunit/numops-fuzz-part2.js
new file mode 100644
index 000000000..51260a449
--- /dev/null
+++ b/deps/v8/test/mjsunit/numops-fuzz-part2.js
@@ -0,0 +1,1178 @@
+// Copyright 2011 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.
+
+function f() {
+ var x = -962609355;
+ var tmp = 0;
+ assertEquals(-114583755, x -= (((-2806715240)&(((1961136061.0329285)>>>((2087162059)*x))+((tmp = -1890084022.7631018, tmp)%(tmp = 2137514142.358262, tmp))))+(x<<(tmp = 2991240918, tmp))));
+ assertEquals(-425721856, x <<= x);
+ assertEquals(3778560, x >>>= ((x|(3198503572))>>(1158434541.1099558)));
+ assertEquals(3778560, x %= (tmp = -2592585378.9592104, tmp));
+ assertEquals(624640, x &= (tmp = 2261638192.9864054, tmp));
+ assertEquals(1249280, x += x);
+ assertEquals(1048576, x &= ((tmp = -2144301819.9892588, tmp)^((x-x)<<x)));
+ assertEquals(2097152, x <<= (x/x));
+ assertEquals(5069061551149729, x *= (tmp = 2417116904.8069615, tmp));
+ assertEquals(1.4836296666029616e+25, x += ((tmp = 2926833006.7121572, tmp)*x));
+ assertEquals(-256, x >>= ((-469330345.3589895)%((x^(((2554170843.4978285)/(2495676674.815263))>>>x))*(-918892963))));
+ assertEquals(-134217728, x <<= (x|(((((1687450853.1321645)+(tmp = 2369533014.5803776, tmp))+(tmp = -2613779445, tmp))+(tmp = -2488826226.3733397, tmp))>>(tmp = -220646936.41245174, tmp))));
+ assertEquals(704164545131708400, x *= ((-2632786741)+(-2613647956)));
+ assertEquals(9216, x >>>= (-1925405359.657349));
+ assertEquals(4491403261551.008, x *= (tmp = 487348444.1787118, tmp));
+ assertEquals(4490606381829.008, x -= (tmp = 796879722, tmp));
+ assertEquals(-60294056, x >>= x);
+ assertEquals(-3193966580.494005, x += (tmp = -3133672524.494005, tmp));
+ assertEquals(550500358, x >>>= ((tmp = -2779637628.390116, tmp)-((tmp = 29230786.984039664, tmp)%(tmp = -310649504.7704866, tmp))));
+ assertEquals(68812544, x >>= (-1347584797));
+ assertEquals(1.2120221595741834e-11, x /= ((2791020260)*((((1964870148.6358237)^x)|(-3082869417))-((x^x)&((1234292117.8790703)<<(-1792461937.2469518))))));
+ assertEquals(1.2120221595741834e-11, x %= (x-(2780439348)));
+ assertEquals(-1421552183, x |= (tmp = -1421552183.5930738, tmp));
+ assertEquals(-1420954119, x |= ((((-2547788562.5735893)<<x)%(435385623))>>(x|x)));
+ assertEquals(1, x /= x);
+ assertEquals(1, x >>= (x>>>(((2975715011.501709)-(tmp = -1473273552.981069, tmp))/(1654883913.042487))));
+ assertEquals(-65382, x ^= ((x/((tmp = -2780026200, tmp)<<x))^(((-2683084424)<<x)>>(-1716245874))));
+ assertEquals(1530921106, x &= (1530940914));
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>= x);
+ assertEquals(0, x /= (tmp = 773741434.1972584, tmp));
+ assertEquals(0, x |= x);
+ assertEquals(0, x <<= (-67977514.99888301));
+ assertEquals(0, x %= (2496550482.524729));
+ assertEquals(-0, x /= (tmp = -515040417, tmp));
+ assertEquals(0, x <<= (-1673460935.2858837));
+ assertEquals(-2638209488, x += (-2638209488));
+ assertEquals(-2400951839498683400, x *= (910068685));
+ assertEquals(1600582036, x ^= (((-1247602308.4812562)>>(((-2393714444.179732)>>>x)%(-778140635.7165127)))+(-1933914727.2268424)));
+ assertEquals(0, x *= ((x-x)>>(-1270234575)));
+ assertEquals(0, x >>>= (tmp = 3193676327.493656, tmp));
+ assertEquals(0, x ^= (x>>>(1148676785.389884)));
+ assertEquals(0, x >>= (tmp = -2269181763.8663893, tmp));
+ assertEquals(0, x >>= (3149450221));
+ assertEquals(0, x >>= (1069630750));
+ assertEquals(-625009654, x ^= ((-2143499112)%(-759244728.6214335)));
+ assertEquals(3583943, x >>>= (-2942645558.1204453));
+ assertEquals(1791971, x >>= (x/x));
+ assertEquals(223996, x >>= x);
+ assertEquals(6999, x >>= (tmp = -1051883611.9443719, tmp));
+ assertEquals(1459617792, x <<= (-1572314984));
+ assertEquals(2622356453.269262, x -= (tmp = -1162738661.2692618, tmp));
+ assertEquals(5103676461.269262, x += (2481320008));
+ assertEquals(823989684.2692623, x %= (x^(((((1048362966)*((tmp = -2423040747.6233954, tmp)>>>x))*((tmp = 2330818588.4081, tmp)>>(tmp = 103312020.98346841, tmp)))+(tmp = 2264492857.144133, tmp))>>>((tmp = 2523442834, tmp)<<x))));
+ assertEquals(0, x >>>= (tmp = -2018700898.531027, tmp));
+ assertEquals(NaN, x /= x);
+ assertEquals(0, x <<= (tmp = -2489442223, tmp));
+ assertEquals(0, x >>= ((3045836220)>>>x));
+ assertEquals(-1156905149, x ^= (3138062147));
+ assertEquals(-0, x %= x);
+ assertEquals(-3118433907.512866, x -= ((tmp = 1338611238, tmp)-(-1779822669.5128663)));
+ assertEquals(100679693, x &= (1040565279));
+ assertEquals(10136400582574248, x *= x);
+ assertEquals(0, x %= x);
+ assertEquals(2400318405, x += (2400318405));
+ assertEquals(1.0036190808578471, x /= (((tmp = -2313492253.9889445, tmp)|(x-((tmp = -205459123, tmp)>>x)))+x));
+ assertEquals(0, x >>>= (tmp = 882343227.1675215, tmp));
+ assertEquals(0, x &= ((tmp = 2307828832.2706165, tmp)^((((((1404388047)<<((807879382)-(-2862921873)))-x)*(tmp = -1897734732, tmp))>>(tmp = 1981888881.2306776, tmp))%x)));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x *= (((x*x)*((((2764801384.171454)%(x>>>x))&(384818815))+(x>>(tmp = -1481683516, tmp))))&x));
+ assertEquals(0, x >>= (tmp = -2202536436, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x &= (tmp = 15161124, tmp));
+ assertEquals(-1586110900, x ^= (-1586110900));
+ assertEquals(-1586127952, x -= ((tmp = 560737212, tmp)%((1349529668)>>>(tmp = -1956656528, tmp))));
+ assertEquals(-1174945870, x -= ((1178456190)|x));
+ assertEquals(1335167624.3422346, x -= (tmp = -2510113494.3422346, tmp));
+ assertEquals(1329952126.3422346, x -= (x>>x));
+ assertEquals(1, x >>= x);
+ assertEquals(3, x |= (x<<x));
+ assertEquals(3, x -= (x-x));
+ assertEquals(-1938525669, x |= (tmp = 2356441625.5128202, tmp));
+ assertEquals(-1938525669, x ^= ((tmp = -197149141.3622346, tmp)/(2833823156)));
+ assertEquals(-2.6292393147661324, x /= (737295254.2254335));
+ assertEquals(2925975987.370761, x -= (-2925975990));
+ assertEquals(2925975987.370761, x %= (tmp = 3041184582.8197603, tmp));
+ assertEquals(-1908068660, x ^= ((tmp = -1380575181, tmp)-(2375164084.8366547)));
+ assertEquals(-477017165, x >>= (tmp = 2420877826.353099, tmp));
+ assertEquals(-477017165, x %= ((tmp = -2919204062.3683634, tmp)-(tmp = -2263328990, tmp)));
+ assertEquals(-2105539936, x &= ((tmp = -1630795440, tmp)-(x&((933423833)>>(-475069901)))));
+ assertEquals(-4979480720, x -= (tmp = 2873940784, tmp));
+ assertEquals(-4190953472, x -= (x&(tmp = -645918862.9001305, tmp)));
+ assertEquals(17564091004468855000, x *= x);
+ assertEquals(-857277134, x |= (tmp = 2363948338, tmp));
+ assertEquals(1015632515, x -= (-1872909649));
+ assertEquals(-1150380043, x ^= (tmp = -2014853770, tmp));
+ assertEquals(1607729152, x <<= ((2194449589)+(x|(tmp = -1470075256.4605722, tmp))));
+ assertEquals(1608356496, x |= ((((x|(670426524))<<((-2415862218)>>(tmp = 1572561529.9213061, tmp)))^((-1989566800.3681061)|x))&(2170270618.3401785)));
+ assertEquals(-1836056576, x <<= (tmp = 2906301296.540217, tmp));
+ assertEquals(-2952415961567723500, x *= (tmp = 1608020145, tmp));
+ assertEquals(1435500544, x <<= x);
+ assertEquals(700928, x >>>= (tmp = 2924829771.1804566, tmp));
+ assertEquals(0, x <<= ((x^(2410009094))|(((-164334714.18698573)%(x*x))|(tmp = 2182431441.2575436, tmp))));
+ assertEquals(-143321285, x ^= (tmp = -143321285, tmp));
+ assertEquals(-2, x >>= x);
+ assertEquals(-1, x >>= (x&(1109737404)));
+ assertEquals(1, x >>>= x);
+ assertEquals(0, x ^= x);
+ assertEquals(-2463707358.165766, x += (-2463707358.165766));
+ assertEquals(1831259938, x >>= (((((x-(tmp = 1359448920.5452857, tmp))%(tmp = -104541523, tmp))/((3133289055.9780197)*x))>>x)%x));
+ assertEquals(1858895646, x ^= ((tmp = 131424376, tmp)>>(tmp = -396761023, tmp)));
+ assertEquals(1, x >>= x);
+ assertEquals(-1888369021, x |= ((tmp = -2038869285.046599, tmp)^((tmp = -1318286592.4250565, tmp)-(tmp = 2825123496, tmp))));
+ assertEquals(1036458508, x <<= ((tmp = 2722401450, tmp)/((tmp = 1090712291, tmp)>>((tmp = -2155694696.9755683, tmp)*(tmp = 1661107340, tmp)))));
+ assertEquals(1, x /= (x%((tmp = -1716050484, tmp)+(tmp = -1683833551.797319, tmp))));
+ assertEquals(0, x >>= (tmp = -2899315628, tmp));
+ assertEquals(0, x |= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x <<= x);
+ assertEquals(1546062911, x |= (1546062911));
+ assertEquals(1546195271, x += ((tmp = -3210667091, tmp)>>(tmp = 1323121165, tmp)));
+ assertEquals(3092390542, x += x);
+ assertEquals(-1199626354, x |= (406783756));
+ assertEquals(-3650317194584908300, x *= (tmp = 3042878461.625484, tmp));
+ assertEquals(-7.650495675092354e+27, x *= (2095844078));
+ assertEquals(0, x >>= (tmp = 342617880.3384919, tmp));
+ assertEquals(22, x ^= (((tmp = 381409558.9104688, tmp)>>((2823172888.974557)>>x))>>x));
+ assertEquals(736383550, x += (736383528));
+ assertEquals(0, x %= x);
+ assertEquals(0, x += x);
+ assertEquals(-1553157831, x -= (1553157831));
+ assertEquals(1838556960, x <<= (3158944357.262641));
+ assertEquals(5503285699.188747, x *= ((tmp = 2437440276, tmp)/(814308583.8128904)));
+ assertEquals(5824889900.188747, x -= (((tmp = 1171445694, tmp)-(tmp = -1584666956, tmp))^(tmp = 1217545373, tmp)));
+ assertEquals(747032, x >>>= (-89332085));
+ assertEquals(747032, x |= (x^(x^(x>>>x))));
+ assertEquals(747032, x >>>= ((-1558482440)*((tmp = -2413907480, tmp)+(3003996862.384156))));
+ assertEquals(7.747761349084291e+23, x += ((tmp = 518064022.64624584, tmp)*((tmp = 2001951702, tmp)*x)));
+ assertEquals(0, x <<= (2769324707.5640426));
+ assertEquals(NaN, x %= (((((((-2458056470.7717686)&x)>>(tmp = -361831232.42602444, tmp))*(2611108609.6727047))>>>x)/(-1713747021.8431413))*(-1143281532)));
+ assertEquals(NaN, x %= ((x^((-613836813)*(tmp = -3180432597.0601435, tmp)))%x));
+ assertEquals(NaN, x /= ((-1607092857)^x));
+ assertEquals(0, x &= (-1190719534));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x += (x>>(642177579.1580218)));
+ assertEquals(-3129552333, x += (-3129552333));
+ assertEquals(1165414963, x &= x);
+ assertEquals(2222, x >>= (((tmp = 2606317568, tmp)|x)+(tmp = 1844107136, tmp)));
+ assertEquals(NaN, x %= ((x^x)<<(x/(((tmp = -1362148700, tmp)&((tmp = 76371048, tmp)<<x))>>>((x^(-2605741153))>>(((tmp = -2131608159.7634726, tmp)|(((2827792229.8004875)|(((-848439251)+(-2576768890.123433))|((tmp = -2617711776, tmp)-((-199980264)&((tmp = -46967951.76266599, tmp)/(-733253537))))))*(tmp = 1820087608, tmp)))>>>(tmp = -3118359396.4298744, tmp)))))));
+ assertEquals(NaN, x /= ((2144871731)*x));
+ assertEquals(NaN, x *= x);
+ assertEquals(NaN, x %= (tmp = 234811462.08692443, tmp));
+ assertEquals(0, x >>>= ((1121416685)|(x^(((tmp = -2905413334, tmp)<<(tmp = -3091554324.030834, tmp))<<x))));
+ assertEquals(-55938048, x |= ((tmp = -55938048, tmp)+(x*(tmp = -1518809027.2695136, tmp))));
+ assertEquals(-3.3234995678333864e-10, x /= (x*(tmp = -3008876576, tmp)));
+ assertEquals(0, x <<= (x/((((((-2168824234.2418427)>>(((tmp = 1976810951, tmp)%x)<<(x*(x>>(x%(3146266192))))))%(tmp = 1756971968.122397, tmp))>>>(-2859440157.8352804))/(-1001406.1919288635))>>>(-1358031926))));
+ assertEquals(-0, x *= (tmp = -1756000533, tmp));
+ assertEquals(-0, x %= (2522761446.869926));
+ assertEquals(0, x >>>= (((1087690535)>>>(2741387979))^x));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>= (-819422694.2188396));
+ assertEquals(0, x ^= x);
+ assertEquals(NaN, x /= x);
+ assertEquals(0, x &= (tmp = 86627723, tmp));
+ assertEquals(0, x += x);
+ assertEquals(0, x %= (tmp = -2317915475, tmp));
+ assertEquals(Infinity, x += (((-3072799584)^(-2487458319))/(((tmp = -3050692353, tmp)&x)>>(-777977292.8500206))));
+ assertEquals(Infinity, x += x);
+ assertEquals(Infinity, x -= (tmp = 484428269, tmp));
+ assertEquals(Infinity, x *= x);
+ assertEquals(Infinity, x /= (2059586218.2278104));
+ assertEquals(Infinity, x *= (tmp = 415918523.8350445, tmp));
+ assertEquals(-1800869091, x |= (((-1800869091)>>>(x>>>(tmp = -2832575051, tmp)))>>>x));
+ assertEquals(6196126991451132000, x *= ((-1467292383.8458765)+(-1973339154.7911158)));
+ assertEquals(6196126992684649000, x += (1233517421));
+ assertEquals(1, x /= x);
+ assertEquals(-7153809722216516000, x -= (((-2984550787.146106)<<(tmp = 743743974, tmp))*((3155151275)/((-1771412568.8965073)%x))));
+ assertEquals(-7153809721471491000, x -= (-745024056));
+ assertEquals(5.117699353102001e+37, x *= x);
+ assertEquals(0, x >>= x);
+ assertEquals(-0, x *= ((-2651785447.666973)<<(-1124902998)));
+ assertEquals(-0, x /= (2119202944));
+ assertEquals(1042673805.5205957, x -= ((x<<x)-(tmp = 1042673805.5205957, tmp)));
+ assertEquals(62, x >>>= (tmp = 2769597912.977452, tmp));
+ assertEquals(34, x &= ((tmp = -61541150, tmp)%(x^(-943160469))));
+ assertEquals(34, x ^= ((-2625482224.4605474)<<(-2277806338.3461556)));
+ assertEquals(536870912, x <<= ((-2373927426.4757633)^x));
+ assertEquals(536870912, x &= x);
+ assertEquals(512, x >>>= ((-1626769708.310139)<<((tmp = 641796314, tmp)/(721629637.3215691))));
+ assertEquals(0, x <<= (-113973033));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x += (-1602711788.2390788));
+ assertEquals(NaN, x *= (x%x));
+ assertEquals(0, x &= (x<<(x|(x>>((x>>>(x%((1182960050)^(((-220896609)-((((tmp = 1518275435.360103, tmp)/(tmp = -88234820, tmp))^x)/x))>>(3169930777.548236)))))-(tmp = -2912668817.662395, tmp))))));
+ assertEquals(0, x *= ((2323969408.7524366)/(((tmp = -3089229853, tmp)>>>((((tmp = -1012580544.5631487, tmp)>>(1138049418.9023373))>>x)&x))*(tmp = 626912001, tmp))));
+ assertEquals(0, x >>>= x);
+ assertEquals(NaN, x /= (x%(-868024322)));
+ assertEquals(NaN, x /= (tmp = -1749532322, tmp));
+ assertEquals(1861918711, x |= (-2433048585.853014));
+ assertEquals(1861918711, x >>= (((102451747)>>>((((241651917.47259736)/((((((((1759022236)^(tmp = -2592022722, tmp))+((-1748044969)>>>(704597925)))/(-1639604842))%((1349846853.7345295)<<(-729695861)))/(x>>((tmp = -2654474404.7365866, tmp)>>x)))>>>(((-480356478)|(x%((tmp = -1668269244.6979945, tmp)+(tmp = -2441424458.565183, tmp))))^((1634981212.7598324)>>>(tmp = 122455570.22000062, tmp))))<<x))*((tmp = -1058636137.5037816, tmp)+((2794083757.138838)&((x/(50081370))&x))))/x))/((tmp = -243106636, tmp)<<((x*((tmp = -648475219.5971704, tmp)>>((tmp = -1568913034, tmp)-((tmp = 911458615, tmp)|x))))>>>(tmp = 2714767933.920696, tmp)))));
+ assertEquals(0, x ^= x);
+ assertEquals(-2080484602, x |= (((1544771831.4758213)|x)^(-538113039)));
+ assertEquals(696451072, x <<= (tmp = -1587032689, tmp));
+ assertEquals(-162595645, x += (tmp = -859046717, tmp));
+ assertEquals(516546456, x >>>= x);
+ assertEquals(623083588, x += ((-1371850352)^(tmp = -1469933252, tmp)));
+ assertEquals(92342412, x %= (tmp = -132685294, tmp));
+ assertEquals(500272110, x |= ((tmp = 1616032506, tmp)%((tmp = 1589569590.4269853, tmp)|(-972791738.1829333))));
+ assertEquals(3247086, x %= (((tmp = 1372216208, tmp)|(-638950076.3387425))&((-2619249161.849716)&(73957896))));
+ assertEquals(0, x >>>= (tmp = -1482343462.6911879, tmp));
+ assertEquals(1265125662, x ^= (tmp = -3029841634, tmp));
+ assertEquals(4941897, x >>>= (-2039728632));
+ assertEquals(206857, x &= (tmp = 226962365.45571184, tmp));
+ assertEquals(1.0925018562586405e+24, x += ((tmp = 2687424146, tmp)*(((-1998020319)%x)*(-2080331363))));
+ assertEquals(-1.755270751212437e+32, x *= (-160665242));
+ assertEquals(0, x <<= (3152796521.6427975));
+ assertEquals(0, x ^= ((((((tmp = -855001595, tmp)<<(2007525777))-(x-(x-x)))/(3036585090.9701214))&(1827983388))*((tmp = -915604789.0515733, tmp)&(((((tmp = -806628722.7820358, tmp)%x)/(tmp = -2773117447, tmp))|x)<<(((tmp = -2902300974.7300634, tmp)|x)/(-1608133440))))));
+ assertEquals(0, x |= ((((((119024954)*(((x^(tmp = 2939514414, tmp))|x)^(x-(tmp = -1597415597.6795669, tmp))))+(((tmp = -182277816.14547157, tmp)<<(((-2983451324.3908825)^(tmp = 1572568307, tmp))+(-1165604960.8619013)))/(x>>((tmp = -2127699399, tmp)>>((x^(((((tmp = -1968667383, tmp)^(tmp = 3120052415.9964113, tmp))|(((x|(((x^((tmp = 2831505153, tmp)<<((-3150506831.547093)+((x%(tmp = 383761651, tmp))%(2856803457)))))+(((tmp = -2426953997, tmp)^(tmp = -2667954801.1010714, tmp))*(tmp = -2707801631, tmp)))&(tmp = 2082935238.794707, tmp)))^((tmp = 697573323.5349133, tmp)-x))%(tmp = 661936357, tmp)))/(-1717944600.261446))>>>((2423776015.0968056)^((-1410322010)|((x<<(tmp = 2935993226, tmp))/(tmp = -1533896392, tmp))))))*(tmp = -596675330, tmp))))))>>>(((2944268153)^(x&(144579050.93126357)))/(-2123810677.2619643)))>>>(1473040195.9009588))*x));
+ assertEquals(0, x /= (2877666495));
+ assertEquals(2174852514, x -= (tmp = -2174852514, tmp));
+ assertEquals(543713128, x >>>= x);
+ assertEquals(2978128878.939105, x += (tmp = 2434415750.939105, tmp));
+ assertEquals(3529591145844655600, x *= (tmp = 1185170719.3753138, tmp));
+ assertEquals(659, x >>>= ((((((x<<(((((-425423078)/(((tmp = 160617689.20550323, tmp)&(-1524740325.5003028))%(tmp = -1869426475, tmp)))<<(((x^(-487449247))>>>(tmp = -1962893666.7754712, tmp))%x))*x)>>((tmp = 623413085, tmp)&(x+(((((-2200726309.083274)-(x-x))+x)&(-1304849509))|((((tmp = -431896184, tmp)>>>(x>>(-1932126133)))<<((1078543321.2196498)*(-10761352)))>>(tmp = -2681391737.5003796, tmp)))))))/x)-(tmp = -1768629117, tmp))/(((((tmp = -2320718566.0664535, tmp)%x)+(-2831503351.995921))>>>(-2695416841.3578796))*(943979723)))<<x)|((652520546.7651662)>>(1045534827.6806792))));
+ assertEquals(531, x &= (tmp = -293707149, tmp));
+ assertEquals(0, x >>= (tmp = -678056747.5701449, tmp));
+ assertEquals(1184651529.8021393, x += (tmp = 1184651529.8021393, tmp));
+ assertEquals(1721719611, x |= (tmp = 1645413178, tmp));
+ assertEquals(-406880257, x |= (tmp = 2268544460, tmp));
+ assertEquals(-4194304, x <<= (tmp = -109701322.43455839, tmp));
+ assertEquals(17592186044416, x *= x);
+ assertEquals(0, x ^= (x&x));
+ assertEquals(0, x <<= (tmp = 1715401127, tmp));
+ assertEquals(-1793087394, x |= (tmp = -1793087394.730585, tmp));
+ assertEquals(-2, x >>= x);
+ assertEquals(263607360.10747814, x += (tmp = 263607362.10747814, tmp));
+ assertEquals(1073214955, x |= (893759979.3631718));
+ assertEquals(703953930, x -= ((2738450011)%(x^(tmp = 679402836, tmp))));
+ assertEquals(1, x >>= (tmp = 2262515165.6670284, tmp));
+ assertEquals(0, x >>= (((tmp = 747896494, tmp)^((tmp = -1005070319, tmp)+x))|x));
+ assertEquals(0, x >>= ((953612771)>>>(tmp = 3066170923.3875694, tmp)));
+ assertEquals(-314941454, x -= (x+(((314941454)%(((tmp = 2200222912.9440064, tmp)>>>(2534128736.805429))>>>(x|((747716234)%(((tmp = -252254528, tmp)%(-1553513480.1875453))&x)))))<<x)));
+ assertEquals(-535686958, x &= (-522809126));
+ assertEquals(0.5480312086215239, x /= (tmp = -977475278, tmp));
+ assertEquals(-1199953459.6090598, x *= ((-2189571393)+((3186862741.37774)>>(tmp = -2193090564.5026345, tmp))));
+ assertEquals(-1199953459.6090598, x %= ((tmp = 2986532440, tmp)*(2685122845)));
+ assertEquals(-1199953459.6090598, x %= (1951182743.7399902));
+ assertEquals(51262285383887820, x *= (-42720228));
+ assertEquals(-424776752, x |= x);
+ assertEquals(166221344210236600, x *= (tmp = -391314598.6158786, tmp));
+ assertEquals(-1883425600, x >>= (((tmp = -1020679296, tmp)^((-1416867718)+(-1412351617)))<<(-2743753169)));
+ assertEquals(0, x &= (x/(-2250026610)));
+ assertEquals(-1111956501, x ^= (tmp = 3183010795, tmp));
+ assertEquals(2012059503, x ^= (tmp = -900369276, tmp));
+ assertEquals(15719214, x >>>= (tmp = -3196277049, tmp));
+ assertEquals(15719214, x |= x);
+ assertEquals(100779035, x -= ((-1245802025)^(-2964289852)));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x &= (((x<<((2361941389.708063)%x))>>((328256762.09842086)>>>((((tmp = 3094192285, tmp)-(((x>>(tmp = -2920437464, tmp))<<(tmp = -2693021467, tmp))-(x>>>((2410065554)%(x%(tmp = 2487056196.689908, tmp))))))-(tmp = -866314146, tmp))^((1754098471)-((((((-2450740191)-(tmp = 1977885539.6785035, tmp))*((tmp = -1205431332, tmp)>>>x))>>(-870601854))>>(tmp = -301859264, tmp))|((tmp = -2308971516.8301244, tmp)/x))))))&((2307007357)-((tmp = -1518812934, tmp)+(2562270162)))));
+ assertEquals(0, x <<= x);
+ assertEquals(-1802124619, x |= (-1802124619));
+ assertEquals(-1802124619, x %= ((1617132364.306333)+((1678465962.079633)|((516698570)%(((569813606)*(-1800804098.6270027))%((tmp = 1976706935, tmp)-((tmp = -1830228989.5488424, tmp)>>(((x^((tmp = 1015246068.3791624, tmp)>>x))^((-2171682812.246772)-(tmp = -398330350, tmp)))&x))))))));
+ assertEquals(904564673.6237984, x -= (tmp = -2706689292.6237984, tmp));
+ assertEquals(818237248768128900, x *= x);
+ assertEquals(254842325.2585001, x %= (1550087667.9657679));
+ assertEquals(-1163919360, x <<= x);
+ assertEquals(-3.4644526843674166, x /= ((-446801454)+(x>>>(tmp = -2025151870, tmp))));
+ assertEquals(0, x &= ((((((((-1739617728)&(x&(((tmp = -2946470036.552597, tmp)/x)*x)))^(-1130501404))>>>x)/((1870230831)>>>(840301398)))%x)/x)/(-2927537567)));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x >>>= (x&(x&x)));
+ assertEquals(0, x &= ((-579614044)-(-756012505.4048488)));
+ assertEquals(-2970367642, x -= (tmp = 2970367642, tmp));
+ assertEquals(-415129376, x ^= (tmp = 2847041926.060355, tmp));
+ assertEquals(-1505681312, x &= (tmp = -1225184902.9215767, tmp));
+ assertEquals(-3174471329.5807734, x += (-1668790017.5807734));
+ assertEquals(-Infinity, x /= (x>>x));
+ assertEquals(NaN, x -= x);
+ assertEquals(0, x ^= (x^(((-1407936301.5682082)<<((x^(((tmp = 3213446217.307076, tmp)|x)|((tmp = 3219810777.3171635, tmp)/(tmp = 1561807400, tmp))))>>>((tmp = 2449910203.0949173, tmp)|((((1954662538.7453175)>>(tmp = -1711636239.9916713, tmp))>>>(tmp = 406219731.214718, tmp))<<(((-907908634.4609842)^((((((tmp = 2408712345, tmp)*(tmp = 1740346634.5154347, tmp))>>(tmp = 715783991, tmp))^(tmp = -655628853.2821262, tmp))%(tmp = 2819143280.434571, tmp))/(-1240412852)))*x)))))/x)));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x >>>= (((-3198075268.8543105)>>(((((x+((tmp = -133461401.50823164, tmp)-((x&(((((tmp = 2617977319, tmp)>>((tmp = -2704719576.8734636, tmp)|((tmp = -977362542.2423751, tmp)<<(x<<(tmp = 3054487697.1441813, tmp)))))>>>((-1635655471)%x))/(-2079513672))%(tmp = 1993563806, tmp)))<<(tmp = -1310524200.6106496, tmp))))%((((-2558804500.7722936)+(tmp = -1641265491, tmp))<<((tmp = -1309608349, tmp)>>>x))/((tmp = -2306644272, tmp)<<x)))*(-2009396162.3063657))+(267343314.3720045))-(-2212612983.661479)))|x));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x *= x);
+ assertEquals(-824822309, x |= (-824822309));
+ assertEquals(-807944741, x |= (((-598067403)*((x&(tmp = 2897778389, tmp))>>>(-1322468310.3699632)))|x));
+ assertEquals(90004223.44097246, x /= (((tmp = -481122620, tmp)&x)%((tmp = 1109368524, tmp)/(((-3150568522.633032)<<(tmp = 2923396776, tmp))^(x-((x/x)&(x/(-287976185.1049104))))))));
+ assertEquals(0.4521931751193329, x /= (tmp = 199039323, tmp));
+ assertEquals(1.8110466604491368e-10, x /= (2496860986.492693));
+ assertEquals(0, x |= x);
+ assertEquals(-1225944576, x += ((tmp = -807700791.631221, tmp)<<((-700782615.4781106)-((((-2954619897)>>>x)<<((tmp = 997657844, tmp)>>>(1227994596)))/((-1234591654.8495834)*((tmp = -191189053.70693636, tmp)+(tmp = -3027659304, tmp)))))));
+ assertEquals(-1225811383, x |= (-1866233271));
+ assertEquals(3069155913, x >>>= (((x/(-99524153.40911508))%(x>>>((((tmp = 2985975640, tmp)/(tmp = 2781516546.2494454, tmp))&(((2234114508)|(((x/(tmp = -1224195047, tmp))<<x)^(x>>>((537884375.5698513)+x))))^((tmp = -2144817497.5089426, tmp)|(-498079183.8178189))))>>>((x+x)&(-3086080103.6460695)))))<<(((tmp = 2151157136, tmp)*x)/(((x/x)>>>(-1149734628.4364533))-((3025445835.654089)+(tmp = 530902725.91127443, tmp))))));
+ assertEquals(-1733702568, x ^= (tmp = 776361489.423534, tmp));
+ assertEquals(8981504, x &= ((tmp = 2902581847, tmp)*(x-(-2697760560))));
+ assertEquals(1153166.8526612986, x -= ((x/(tmp = -1375025594.5027463, tmp))+((3043576689.1538706)%(x+x))));
+ assertEquals(3389855, x |= (x+x));
+ assertEquals(-488458393.17759943, x += (-491848248.17759943));
+ assertEquals(40982867145206920, x *= ((3132857155)|(tmp = -218356553, tmp)));
+ assertEquals(688, x >>= (((((tmp = 403321821, tmp)+((tmp = 2536984658, tmp)%((tmp = 2759309029.8753624, tmp)|(((tmp = 1994203554.7417293, tmp)^((704660500.434877)*(tmp = 1536292958.2691746, tmp)))+(-164139788)))))/((1205950994.1255205)+x))^((((tmp = 975272146.0133443, tmp)-(150107797))/(-1764309514))^((x>>>(x^(x^x)))+(203250124))))>>>(tmp = 1864959239.512323, tmp)));
+ assertEquals(10, x >>= ((tmp = 1631996431.9620514, tmp)>>x));
+ assertEquals(10, x %= (tmp = 2678904916, tmp));
+ assertEquals(335544320, x <<= (tmp = -2759037415.6811256, tmp));
+ assertEquals(-153389967, x |= ((tmp = -2411636565, tmp)+(tmp = -2305156154, tmp)));
+ assertEquals(-1171, x >>= x);
+ assertEquals(813080576, x &= (((tmp = -65428547, tmp)&(tmp = 3163266999, tmp))<<x));
+ assertEquals(4346532303, x += ((tmp = -761515569.0707853, tmp)>>>(((tmp = 143240971.0661509, tmp)<<x)*(x^((tmp = -271697192.8471005, tmp)&x)))));
+ assertEquals(-863299035, x ^= ((((2663001827.1492147)>>>((x/(((tmp = 482665912, tmp)-(x>>(tmp = 354425840.784659, tmp)))>>((-2012932893)>>>x)))/((tmp = -1354385830.6042836, tmp)>>>(-2149023857))))^((tmp = 585746520, tmp)+(tmp = 756104608, tmp)))^(517529841.184085)));
+ assertEquals(-997654012, x &= (((tmp = -404836025.15326166, tmp)+((tmp = 3035650114.0402126, tmp)<<((-1308209196)>>(tmp = 693748480, tmp))))<<(((465774671.4458921)<<x)/(1971108057))));
+ assertEquals(-320581507110848260, x *= ((x-(tmp = -2266777911.7123194, tmp))^(tmp = -2810021113.304348, tmp)));
+ assertEquals(-320581508271196300, x += ((-1195215841.5355926)|(x-((2715907107.4276557)+(((-843426980)>>(x&(x%(tmp = -1139279208.34768, tmp))))^x)))));
+ assertEquals(368031616, x &= x);
+ assertEquals(368031616, x %= (tmp = 1211767328, tmp));
+ assertEquals(-67505614939510744, x *= (tmp = -183423412.56766033, tmp));
+ assertEquals(959424552, x >>= ((tmp = -171120122.5083747, tmp)/x));
+ assertEquals(30949179.096774194, x /= (((x-((((x&(tmp = -180770090, tmp))<<(((tmp = -2061363045.419958, tmp)*((655711531)^((1205768703)-(tmp = 2468523718.8679857, tmp))))+(-2746704581)))+((-853685888)*(tmp = -2299124234, tmp)))|(tmp = 2429502966, tmp)))|(((-985794986.0232368)>>>(2890862426))%x))>>(tmp = 1005542138.8415397, tmp)));
+ assertEquals(30949179, x |= x);
+ assertEquals(30949179, x %= (810126097.6814196));
+ assertEquals(120895, x >>= (tmp = 3065886056.1873975, tmp));
+ assertEquals(1934320, x <<= (1478650660.7445493));
+ assertEquals(0, x >>= (1069658046.2191329));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x %= (x*x));
+ assertEquals(NaN, x *= ((((2148513916)+(tmp = -210070225.85489202, tmp))>>(975470028))+((-3060642402)>>x)));
+ assertEquals(NaN, x *= (2888778384));
+ assertEquals(NaN, x -= (294531300.16350067));
+ assertEquals(-465620423, x ^= (tmp = -465620423.5891335, tmp));
+ assertEquals(1613303808, x &= (-2530649850.1952305));
+ assertEquals(2045458658, x |= (tmp = 432158946.5708574, tmp));
+ assertEquals(0, x >>>= (2277328255.770018));
+ assertEquals(0, x &= (-64904722.41319156));
+ assertEquals(0, x >>= x);
+ assertEquals(3109394857.361766, x += (3109394857.361766));
+ assertEquals(1519021650, x ^= ((tmp = -2632472653, tmp)|(tmp = 2161964921.8225584, tmp)));
+ assertEquals(370854, x >>>= ((1486892931.4564312)-((tmp = 3017755741.9547133, tmp)>>>x)));
+ assertEquals(1333145110.39802, x -= ((-1051580495.39802)-(tmp = 281193761, tmp)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x |= x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(799202788.1455135, x -= (tmp = -799202788.1455135, tmp));
+ assertEquals(1539080192, x <<= (x%(((((x-x)|(((((x%(959993901))+(tmp = -2647575570.092733, tmp))/(tmp = -2040600976.5104427, tmp))*(x*(tmp = 2785252760, tmp)))>>(-377867259)))/((x&(1549738240.013423))>>>(tmp = -1502185618, tmp)))*x)%(1159283801.0002391))));
+ assertEquals(0, x >>= (-268660225));
+ assertEquals(-0, x /= (-2795206270.635887));
+ assertEquals(0, x >>>= (1869556260.2489955));
+ assertEquals(64202212, x ^= ((((tmp = -942983515.5386059, tmp)*(((1057759788)-x)*(tmp = 2038041858, tmp)))>>x)+(tmp = 64202212, tmp)));
+ assertEquals(2021126977, x -= ((tmp = -2009912898, tmp)^((2240062309)%x)));
+ assertEquals(4332348265459724000, x *= (tmp = 2143530968, tmp));
+ assertEquals(1472, x >>>= ((283380755)<<x));
+ assertEquals(-1672370407872, x *= (tmp = -1136121201, tmp));
+ assertEquals(338573318, x ^= (tmp = 2329579078.4832354, tmp));
+ assertEquals(2377388772.1662374, x -= (tmp = -2038815454.1662374, tmp));
+ assertEquals(-1.264761712403516, x /= ((((tmp = -2106209534, tmp)>>((((((tmp = 626190172, tmp)/x)>>>(-824270996.8545206))/((1258369810.9498723)-(tmp = -2947556209, tmp)))^((((366784589.24711144)|(1462064104.828938))-(1571045395.777879))<<(444685689.60103726)))>>(tmp = -2757110357.410516, tmp)))/(x>>>((tmp = 829226010, tmp)>>>(629512715))))|x));
+ assertEquals(-2905481691.264762, x -= (2905481690));
+ assertEquals(-1710543566.1481905, x -= (-1194938125.1165714));
+ assertEquals(-3421087132.296381, x += x);
+ assertEquals(-884178944, x <<= ((-1820881235)|x));
+ assertEquals(-884178944, x &= (x%(tmp = -2298828530, tmp)));
+ assertEquals(1516503040, x <<= ((tmp = -3039882653, tmp)+((tmp = 1956034508, tmp)<<(x>>(tmp = 280388051, tmp)))));
+ assertEquals(3033006080, x += x);
+ assertEquals(846431222.321887, x %= (x+(-1939718651.1609435)));
+ assertEquals(-846431224, x ^= ((-1742116766.54132)/x));
+ assertEquals(1157918728, x &= (tmp = 1966568030, tmp));
+ assertEquals(1157918728, x >>>= ((((((tmp = -2392096728.184257, tmp)*(x&(-3051259597.301086)))>>>(((tmp = 1712991918.071982, tmp)*(tmp = -714525951, tmp))-((-1784801647)>>((-1270567991)%(((214272558)/(((-3110194570)|(tmp = 2558910020, tmp))&(-1266294955.717899)))*((2654922400.609189)>>>(tmp = 370485018, tmp)))))))*(((tmp = -2621203138.1838865, tmp)%(858913517))*((tmp = -1564229442.2596471, tmp)>>((tmp = 1898557618, tmp)|(-1282356275)))))*(tmp = -1253508468, tmp))+((-361964404.75944185)|x)));
+ assertEquals(961668975, x += (-196249753));
+ assertEquals(1, x >>= (tmp = 890453053, tmp));
+ assertEquals(1, x >>= (((((tmp = 871309275, tmp)/(x>>>((tmp = 2033022083, tmp)&(tmp = -1393761939, tmp))))%((437488665.104565)^(tmp = 2808776860.4572067, tmp)))-((tmp = -359283111.49483967, tmp)<<((tmp = 2985855945, tmp)%(tmp = -596479825.9114966, tmp))))/(-1965528507)));
+ assertEquals(0, x >>= ((tmp = -1753776989, tmp)%(tmp = 322622654, tmp)));
+ assertEquals(84411424, x ^= (((x|(x|(tmp = -1617122265, tmp)))&(tmp = -313813263, tmp))&(1472888112.0258927)));
+ assertEquals(67633184, x &= ((1556833131.0776267)<<(x<<(1501219716.5575724))));
+ assertEquals(68002293, x |= (((tmp = 188984203.0350548, tmp)>>>(tmp = 1356052777, tmp))%(x*(tmp = -2944960865, tmp))));
+ assertEquals(67108864, x &= (((1046644783.9042064)<<x)+((-2796345632)>>>(((-1913290350.3687286)<<(((((tmp = -2223692353, tmp)>>x)&(x<<(x>>((((tmp = -976850020, tmp)%(tmp = 1379692507, tmp))>>>(1120103052.2077985))>>(tmp = 5592070.612784743, tmp)))))<<(x+((tmp = -3154037212.9764376, tmp)%(((x-(-1961060483.6965141))+(((1920670676)-(2852444470.7530622))/(((1445954602)>>((1353665887)>>(tmp = 111411560.64111042, tmp)))<<x)))+x))))<<((-1773130852.6651905)^((1216129132)>>(1511187313.2680469)))))|((tmp = -1107142147, tmp)|(tmp = -768165441.4956136, tmp))))));
+ assertEquals(0, x -= x);
+ assertEquals(0, x %= (tmp = -1655707538.0778136, tmp));
+ assertEquals(-184120712930843900, x += (x+((tmp = -3174410166, tmp)+((tmp = -301807453, tmp)*(tmp = 610060182.1666535, tmp)))));
+ assertEquals(-54598560, x >>= (-1365351357));
+ assertEquals(-6763.94449950446, x /= (((-1953016847)<<((673287269.7002038)%(-558739761)))>>>(tmp = 1607754129, tmp)));
+ assertEquals(-1, x >>= x);
+ assertEquals(1, x >>>= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x >>= ((-384747983)+((((tmp = -949058352.381772, tmp)>>>(-1920744986))-(-882729639))^((x^((tmp = 2351364046, tmp)<<(((tmp = -3110165747, tmp)^(-1266489735))-((tmp = -371614326, tmp)>>((tmp = -2064968414, tmp)&(-2075036504.617934))))))&(((-2616501739)&(tmp = 2591437335.4029164, tmp))>>x)))));
+ assertEquals(0, x >>>= ((tmp = 2946468282, tmp)&((-2741453019)>>x)));
+ assertEquals(0, x -= ((x%(-134700915))&(-1955768279)));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x /= (x^(((((((tmp = 3185669685.772061, tmp)>>(tmp = -1973500738, tmp))-(tmp = -87401348.93002152, tmp))>>(tmp = -2813508730, tmp))&(tmp = -778957225, tmp))<<(x-(x&((-2821756608)+(((((tmp = 2475456548, tmp)/(tmp = 997998362, tmp))<<((tmp = -83043634, tmp)|x))%(636120329))%(tmp = -1910213427.7556462, tmp))))))%x)));
+ assertEquals(0, x &= x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x >>>= (x%x));
+ assertEquals(0, x %= (745221113));
+ assertEquals(0, x >>>= ((1467615554.7672596)|x));
+ assertEquals(0, x /= (tmp = 735317995, tmp));
+ assertEquals(-1513001460, x |= (2781965836));
+ assertEquals(-1513001460, x |= (x%(1970577124.3780568)));
+ assertEquals(-0, x %= x);
+ assertEquals(1864972269, x ^= (-2429995027.840316));
+ assertEquals(1226843341, x &= (tmp = -639621923.5135081, tmp));
+ assertEquals(1226843339.3171186, x += ((1297620268.272113)/(-771070549)));
+ assertEquals(76677708, x >>>= (1009134980));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x ^= x);
+ assertEquals(NaN, x /= x);
+ assertEquals(716040787, x |= ((1851586229)-(1135545441.3502865)));
+ assertEquals(1385693184, x <<= x);
+ assertEquals(1321, x >>= (x^((tmp = -1576632297.0860603, tmp)>>>(405218605))));
+ assertEquals(-1319012931, x |= (-1319014243));
+ assertEquals(-1319012931, x >>= ((((1689898279.3580785)<<((((x^(x>>>((((tmp = 2635260332, tmp)*(tmp = 2053357650, tmp))*x)*(2856480122.339903))))>>x)&(-2382703000.077593))%(1183918594)))*(tmp = -1670081449, tmp))<<x));
+ assertEquals(-528327581.7646315, x %= (tmp = -790685349.2353685, tmp));
+ assertEquals(2073431790, x ^= (tmp = 2601800333, tmp));
+ assertEquals(-6514722684180, x -= (((tmp = 824141806.0668694, tmp)>>>(((-1865885282.8723454)&(x&(x|((900188006.3757659)>>>(x&x)))))+(2227126244.0526423)))*x));
+ assertEquals(1450593, x >>>= ((2157053647)>>(x+(-2934071355.418474))));
+ assertEquals(576782336, x <<= ((1054640368.827202)&((tmp = -3182236876.434615, tmp)>>(tmp = 2129856634.0328193, tmp))));
+ assertEquals(2950754326, x -= (tmp = -2373971990, tmp));
+ assertEquals(738197504, x <<= (1188157369.5988827));
+ assertEquals(0, x <<= (x+((tmp = -839533141, tmp)&((((((tmp = -1148768474.7306862, tmp)|(172650299))+(tmp = -2739838654, tmp))/(3132557129))%x)>>>(tmp = -1229961746.2466633, tmp)))));
+ assertEquals(0, x %= (tmp = -2974207636, tmp));
+ assertEquals(0, x %= ((2323482163)>>>x));
+ assertEquals(0, x &= (((x/(x+(x>>((tmp = 55935149, tmp)%x))))|((3109182235)>>>(tmp = 1217127738.8831062, tmp)))+((((tmp = -385114910, tmp)*((((((tmp = -2535158574.634239, tmp)&(x+x))<<(-2821692922.43476))&(-776804130.9457026))>>((-1374832535)^(tmp = 2175402162.701251, tmp)))%(-1646995095)))-(x*(tmp = -921556123, tmp)))^(79224621))));
+ assertEquals(128935435, x |= ((tmp = 2279459038, tmp)%(tmp = -537630900.5271742, tmp)));
+ assertEquals(128935435, x /= ((((((x<<(2750024311))-((-1332480769.4784315)&(1418160003)))&(1551783357))<<(((((-2870460218.55027)|((-1958752193.7746758)&(2551525625)))>>>((((tmp = -1698256471, tmp)^(((((((((tmp = -830799466, tmp)+x)-(-111590590))+(tmp = -1105568112.3921182, tmp))/((tmp = -3058577907, tmp)|(((-1944923240.2965696)%(-2884545285))<<(tmp = -1993196044.1645615, tmp))))^(x>>(tmp = -2961488181.3795304, tmp)))&x)*x)|(((tmp = 97259132.88922262, tmp)<<((1601451019.343733)&x))*(x|x))))+((((x>>x)<<x)+(-868409202.2512136))/(((tmp = -2893170791, tmp)-((x|(-853641616))%(((tmp = 549313922, tmp)&(-768036601.6759064))%(tmp = -543862220.9338839, tmp))))-((tmp = 1639851636, tmp)+((2164412959)/(-273028039.941242))))))>>>((((-2382311775.753495)^(-2062191030.2406163))>>>(tmp = -1054563031, tmp))/(-862111938.7009578))))%x)+(-3103170117.625942)))%((tmp = -1144062234, tmp)>>x))>>>(tmp = 1216332814.00042, tmp)));
+ assertEquals(41.631074722901715, x /= (x&(-2542806180.962227)));
+ assertEquals(41.631074722901715, x %= (-14003386.556780577));
+ assertEquals(8, x &= (x&((-2231622948)%(tmp = 488279963.9445952, tmp))));
+ assertEquals(9.002961614252625e-9, x /= ((53802728.56204891)<<(((867697152.3709695)-(538719895.5707034))&(-631307825.4491808))));
+ assertEquals(0, x >>= x);
+ assertEquals(-0, x *= (tmp = -785674989, tmp));
+ assertEquals(-0, x += x);
+ assertEquals(0, x /= (-250703244));
+ assertEquals(0, x <<= ((tmp = -661062581.5511999, tmp)|x));
+ assertEquals(0, x &= (-1299482308));
+ assertEquals(0, x &= ((-399690060)>>>(2448074202.385213)));
+ assertEquals(0, x &= (2574341201));
+ assertEquals(0, x <<= ((x|(((tmp = 2458873162.645012, tmp)+(tmp = -1999705422.8188977, tmp))<<((x^(tmp = -392530472, tmp))>>>x)))&(((tmp = 2463000826.7781224, tmp)|(tmp = 3020656037, tmp))-x)));
+ assertEquals(1397603760, x += ((tmp = -1359413071, tmp)-(tmp = -2757016831, tmp)));
+ assertEquals(513823851, x -= (883779909));
+ assertEquals(-1765712747, x ^= (2288060670.6797976));
+ assertEquals(3117741504918286000, x *= x);
+ assertEquals(3117741506284045300, x += (1365759456));
+ assertEquals(6035555595.597267, x /= (tmp = 516562470, tmp));
+ assertEquals(104203275, x &= (tmp = 376835755.32434213, tmp));
+ assertEquals(10858322520725624, x *= x);
+ assertEquals(59458951, x >>>= (153765028));
+ assertEquals(49370856, x += ((tmp = -1291276092, tmp)>>x));
+ assertEquals(0, x %= x);
+ assertEquals(0, x += x);
+ assertEquals(-1494589645, x -= (1494589645));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x <<= (x&((2730708043.467806)<<x)));
+ assertEquals(0, x /= ((tmp = -1483912394.153527, tmp)>>>((tmp = 1800568769, tmp)^((((((tmp = 1351568510, tmp)>>(tmp = -1337992543.2562337, tmp))>>>(tmp = 2602239360.40513, tmp))*x)%x)+(-2095840128.0700707)))));
+ assertEquals(-0, x /= ((2363946613)^(tmp = -2227868069, tmp)));
+ assertEquals(0, x &= ((((2634933507)<<(2798775374.140882))>>>x)>>>(((tmp = 1135200853.6396222, tmp)-(tmp = -1529829490.7007523, tmp))-(((((((((x^((x|(2135742668.591568))-(924230444.8390535)))%(tmp = -2459525610.51898, tmp))+(x&((tmp = 1177231743.809653, tmp)/(tmp = 1743270357.2735395, tmp))))|(((tmp = -1894305017, tmp)^((tmp = 1791704240, tmp)&x))%(-1569751461)))>>>(tmp = -2078321944, tmp))|x)*(((x*(tmp = -163239354, tmp))<<((tmp = 2859087562.694203, tmp)&(-657988325.9410558)))^(2508013840)))-((-243572350)+(x%((-1095206140)+((tmp = 3213566608.942816, tmp)*((2256442613)%((tmp = 1723751298, tmp)^(x-((-1145710681.2693722)|x)))))))))+(1556870627)))));
+ assertEquals(130883024.97423434, x -= (-130883024.97423434));
+ assertEquals(0.046720352789736276, x /= (tmp = 2801413456, tmp));
+ assertEquals(1806558189, x |= (tmp = 1806558189.157823, tmp));
+ assertEquals(72.40475060062144, x /= (x%((1932591076.531628)>>(1982030182))));
+ assertEquals(-1077558321.5975945, x += (tmp = -1077558394.002345, tmp));
+ assertEquals(98187, x >>>= x);
+ assertEquals(97792, x &= (tmp = -1032487404, tmp));
+ assertEquals(709197609, x |= (x^(709179177)));
+ assertEquals(11081212, x >>>= (tmp = 1412940006.169063, tmp));
+ assertEquals(11081212, x &= x);
+ assertEquals(-1920311203, x -= ((tmp = 1931392415, tmp)<<((x%(tmp = -2873576383, tmp))%x)));
+ assertEquals(-1920311203, x |= (x&(-993884718.2172024)));
+ assertEquals(-4, x >>= (1409411613.0051966));
+ assertEquals(-7947632484, x *= ((-2856731734)^((-1181032235.9132767)-((tmp = 780101930, tmp)+((tmp = -1732707132.6253016, tmp)^x)))));
+ assertEquals(-2016362769, x ^= (tmp = 2711125619.2455907, tmp));
+ assertEquals(-61535, x >>= x);
+ assertEquals(-124771649, x ^= (tmp = 124726558, tmp));
+ assertEquals(-1, x >>= x);
+ assertEquals(-0, x %= (x*x));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x /= (2444628112));
+ assertEquals(0, x <<= ((-38968517.72504854)<<x));
+ assertEquals(-1504619917, x |= (tmp = 2790347379, tmp));
+ assertEquals(-1504619917, x &= x);
+ assertEquals(2790347379, x >>>= ((1825218368)<<(-1843582593.2843356)));
+ assertEquals(7786038495492170000, x *= x);
+ assertEquals(-11011696, x |= (((tmp = 2931644407.4936504, tmp)-(3077095016.001658))%(tmp = -1731851949, tmp)));
+ assertEquals(-107866, x %= ((-697845074.1661191)>>(772708134)));
+ assertEquals(356779149, x ^= (-356884949.503757));
+ assertEquals(0, x %= x);
+ assertEquals(0, x *= ((tmp = 1542291783, tmp)^x));
+ assertEquals(0, x += ((tmp = 1105314644.002441, tmp)&x));
+ assertEquals(-1005882993, x ^= (-1005882993.0899806));
+ assertEquals(-1301065066, x += (tmp = -295182073, tmp));
+ assertEquals(-1454702592, x <<= ((-2440858737.390277)&(-1363565201.7888322)));
+ assertEquals(-201539012492525570, x *= ((((tmp = -1416268089, tmp)|x)-(tmp = 1669129769, tmp))&(x<<((x/(-2614041678.7423654))%x))));
+ assertEquals(-2.1995276811535986e+25, x *= (x/(-1846667987.154371)));
+ assertEquals(0, x |= ((x*(((x>>>((tmp = 1044173034, tmp)>>>((x<<((tmp = -2906412863, tmp)%((tmp = -437401503, tmp)<<(((((x|(2167319070))<<((tmp = 2766179640.1840167, tmp)&(-2372076054)))*(tmp = -241617431.06416297, tmp))*((((((tmp = 2570465382.5574293, tmp)>>>(x/((-2851324509.354545)%x)))>>(((x+((tmp = -614687945, tmp)^x))^((((tmp = 1653437743, tmp)>>x)/(tmp = 3072995069, tmp))>>x))*(((((-290508242)>>((tmp = 2969511554, tmp)<<(tmp = 158176292.95642304, tmp)))<<(32376015))+(tmp = 2391895870.4562025, tmp))*x)))&((((x/(tmp = 365292078.53605413, tmp))>>x)/(1167322811.0008812))|(((tmp = 2487970377.365221, tmp)^x)<<((tmp = 2342607988.711308, tmp)/(((2276081555.340126)-(((tmp = -2571071930, tmp)>>(tmp = -248468735.76550984, tmp))>>>(tmp = -2862254985.608489, tmp)))^(-1312017395))))))<<x)&(2762717852.949236)))+((((-2492896493)&x)<<(-2756272781.4642315))/x)))))*(2405395452))))>>((-1433975206)/((tmp = -2064757738.6740267, tmp)<<((((tmp = -1563531255, tmp)-(-589277532.2110934))<<x)^(2249328237.0923448)))))-x))-(-225624231)));
+ assertEquals(0, x *= (tmp = 1657982666.2188392, tmp));
+ assertEquals(86443387, x |= (tmp = 86443387.25165462, tmp));
+ assertEquals(86443387, x %= (-1341731981.702294));
+ assertEquals(172886774, x <<= ((-1799840391)&(1011948481.310498)));
+ assertEquals(-1115684864, x <<= x);
+ assertEquals(-2098253702059525600, x *= (1880686715.1865616));
+ assertEquals(-2098253700213206300, x -= (tmp = -1846319435.0583687, tmp));
+ assertEquals(570692096, x &= (((tmp = -1572055366.64332, tmp)%(tmp = 1720120910, tmp))%((x-(912386952.5959761))*(tmp = -1146251719.4027123, tmp))));
+ assertEquals(603979776, x <<= ((-329752233.8144052)&(tmp = -368636559, tmp)));
+ assertEquals(603979776, x <<= x);
+ assertEquals(364791569817010200, x *= x);
+ assertEquals(0, x &= ((2074587775.983799)/(tmp = 438856632.76449287, tmp)));
+ assertEquals(0, x &= (((1509671758)*(tmp = -935801537.7325008, tmp))>>>(((tmp = -1752877566, tmp)<<x)%(tmp = -517163766, tmp))));
+ assertEquals(-2031730599, x ^= ((2264285273)&(tmp = -1762662949.014101, tmp)));
+ assertEquals(-843578945, x %= (-1188151654));
+ assertEquals(-2147483648, x <<= x);
+ assertEquals(-2147483648, x >>= (tmp = -3165079200.229641, tmp));
+ assertEquals(-44086313.1323726, x %= ((x%(-254466243.48728585))-((x>>(-457411829.1063688))-((-2606923436.9333453)/x))));
+ assertEquals(-44086313, x |= x);
+ assertEquals(1037812, x >>>= ((tmp = 342497258.9786743, tmp)+(1652928385.8150895)));
+ assertEquals(-2371695599678100, x *= (tmp = -2285284425, tmp));
+ assertEquals(-2371697387004653, x += (tmp = -1787326553.0542095, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x >>= ((x^(tmp = 544039787, tmp))>>>x));
+ assertEquals(0, x &= ((x%(((((((tmp = -424572417.1088555, tmp)|(-2381863189))/(tmp = -2007482475.1809125, tmp))&(((((tmp = 311016073, tmp)>>(tmp = -1548839845, tmp))+((-2557740399.7947464)<<(2399113209)))&x)>>>x))%(-297180308.7721617))-(tmp = 860906293, tmp))^x))%(-2740622304)));
+ assertEquals(4971841192462909000, x += ((tmp = -2723203837.572612, tmp)+((((-2909100706)+(-951999374))|(-3116735764))*(3087123539.422669))));
+ assertEquals(-460, x >>= (1081807537.557404));
+ assertEquals(2354165127.3906384, x += (tmp = 2354165587.3906384, tmp));
+ assertEquals(357.8680960002211, x /= ((((x<<(((x&x)+(1113841407))|((x/(tmp = 384533564, tmp))>>>(-605853882))))%x)&((tmp = 2050375842, tmp)>>>x))>>(((2745147573)^x)<<(x-(900043292)))));
+ assertEquals(0, x *= (x>>>(-295974954.5058532)));
+ assertEquals(0, x *= ((-2448592125.815531)*(tmp = -94957474.8986013, tmp)));
+ assertEquals(0, x &= ((x>>x)^(tmp = -1335129180, tmp)));
+ assertEquals(395092065, x |= ((3081659156)^(tmp = -1608334475, tmp)));
+ assertEquals(395092065, x &= x);
+ assertEquals(-413337639, x += (x^(tmp = -664996071.3641524, tmp)));
+ assertEquals(-1604423637896759800, x *= (x>>>(tmp = 1242912352.955432, tmp)));
+ assertEquals(0, x &= ((((((tmp = 651293313, tmp)|(((2541604468.635497)>>>(tmp = 758815817.7145422, tmp))>>>((-1948795647)/x)))&x)/((tmp = -3161497100, tmp)+(782910972.3648237)))>>>x)%(834206255.5560443)));
+ assertEquals(0, x >>>= (tmp = 125945571, tmp));
+ assertEquals(NaN, x -= (x%x));
+ assertEquals(NaN, x %= (tmp = 282259853, tmp));
+ assertEquals(NaN, x += (tmp = -2081332383, tmp));
+ assertEquals(0, x >>>= (((x>>(-2298589097.7522116))|((((x>>>(x-(tmp = 755218194, tmp)))|x)%x)-(tmp = 2206031927, tmp)))>>>((((x&(x-x))^(tmp = 2836686653, tmp))*((x<<(tmp = -1624140906.4099245, tmp))>>>((2942895486)|((x>>>x)>>>(-1586571476)))))|((781668993)+(-1857786909)))));
+ assertEquals(0, x &= (tmp = -708084218.9248881, tmp));
+ assertEquals(0, x %= (1645913394.5625715));
+ assertEquals(0, x <<= ((x^((tmp = 1185413900, tmp)*((-2441179733.997965)*(tmp = 2554099020.066989, tmp))))%((1704286567.29923)/x)));
+ assertEquals(0, x += x);
+ assertEquals(0, x *= x);
+ assertEquals(0, x |= (x>>>(139138112.141927)));
+ assertEquals(0, x >>>= (tmp = 2142326564, tmp));
+ assertEquals(0, x |= x);
+ assertEquals(-0, x /= ((((x+(2817799428))|x)%((1050079768)-(x>>>((1452893834.8981247)|((((tmp = -1737187310.889149, tmp)/(tmp = -362842139, tmp))%(1234225406))%(((x|x)*((-1055695643.739629)-((x-x)*(945954197.676585))))-(tmp = 786185315.346615, tmp)))))))<<(-173891691)));
+ assertEquals(0, x &= (-2842855092.319309));
+ assertEquals(0, x &= ((-3188403836.570895)/x));
+ assertEquals(0, x *= (x+x));
+ assertEquals(NaN, x /= (x>>>(((tmp = 391037497.68871593, tmp)/((192754032)*(1382659402.5745282)))/((((-2187364928)>>>x)>>(tmp = 2563448665.7594023, tmp))^(tmp = 1500866009.7632217, tmp)))));
+ assertEquals(NaN, x /= ((tmp = -935036555.2500343, tmp)-(x/(((x&(x^(tmp = -3001352832.5034075, tmp)))^x)/((1122547613)>>x)))));
+ assertEquals(0, x >>= (tmp = -2951766379.0809536, tmp));
+ assertEquals(-632945188, x ^= (-632945188.7188203));
+ assertEquals(-632945188, x %= ((((((tmp = -3181527314.82724, tmp)&(2280175415))>>(x^(x|x)))^(tmp = -524233678.52970886, tmp))*x)|((tmp = 1782882786, tmp)>>>(tmp = -592607219, tmp))));
+ assertEquals(404189184, x <<= ((tmp = -2761472127, tmp)^(36616299.88780403)));
+ assertEquals(872651572, x ^= (tmp = 739568436.6252247, tmp));
+ assertEquals(13, x >>>= ((tmp = -1033843418.865577, tmp)%(x%(1247263629.0445533))));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x >>= (3189175317));
+ assertEquals(0, x &= (((2391973519.6142406)^((-2950058736.191456)|(x*x)))>>(tmp = 343822384.294345, tmp)));
+ assertEquals(0, x >>>= (tmp = -2306246544, tmp));
+ assertEquals(-1572339598, x ^= ((tmp = 2991380083.337327, tmp)&(tmp = -1361507970, tmp)));
+ assertEquals(649, x >>>= ((1961407923.4950056)>>(x-(-872821523.7513013))));
+ assertEquals(649, x ^= (((x&(tmp = -702931788, tmp))^(((x>>x)|(((tmp = 2710759269, tmp)/(x>>(x*((((((tmp = -2428445134.9555864, tmp)+(-1859938743))%(x<<x))*((236868604)+((tmp = -3066688385, tmp)/(787503572.8839133))))/(tmp = 3215629315, tmp))>>(-1315823020)))))%(1461368627.1293125)))>>>(tmp = -2921804417.5735087, tmp)))/(x>>>(((tmp = 2175260691.824617, tmp)/((-582958935.7628009)-((((((x>>x)|(2590503723.4810824))^(tmp = -1994324549, tmp))-(-684683327))/(tmp = -3133419531, tmp))|(tmp = -328974092.05095506, tmp))))>>(-447624639.4518213)))));
+ assertEquals(649, x %= ((((1854382717)|(((x+(tmp = 2568081234, tmp))-x)+((tmp = 1043086140, tmp)<<((tmp = 2979118595.0496006, tmp)+((x&(2669577199.852803))/(-2567808445.101112))))))<<((((tmp = -1471092047, tmp)&((-3099138855.21041)-((tmp = -798574377.526715, tmp)&((2255586141)<<(-1069867774)))))>>>(((x*(tmp = -2810255707.781517, tmp))/x)*(2706435744.054121)))^(394262253)))^((844325548.0612085)/(tmp = 1434691648, tmp))));
+ assertEquals(823215943.1924392, x += (tmp = 823215294.1924392, tmp));
+ assertEquals(536872706, x &= ((-334612686)%((1303605874)|x)));
+ assertEquals(-30666374.413486242, x += ((tmp = -567539080.4134862, tmp)%(tmp = -1655555936.3195171, tmp)));
+ assertEquals(-56438727096752984, x *= (tmp = 1840410814, tmp));
+ assertEquals(-33200107.984488487, x %= (((tmp = 3007206509, tmp)-(3079337725.6659536))%(1819565202.5011497)));
+ assertEquals(-1214493182, x ^= (-3060193769));
+ assertEquals(-1214493179.1335113, x -= ((-3218099496.595745)/(1122662554)));
+ assertEquals(-1214493179, x >>= ((-375364195)<<(((tmp = 619439637.8754326, tmp)>>(-1830023279.9486575))&(tmp = -1106180387.2448823, tmp))));
+ assertEquals(-303623295, x >>= (-2109241374.3349872));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x |= x);
+ assertEquals(1917126206, x -= (-1917126206));
+ assertEquals(2659779928, x -= (tmp = -742653722, tmp));
+ assertEquals(-1635187368, x >>= ((tmp = -674385169, tmp)*((9848362.783326745)|(x*(55220544.00989556)))));
+ assertEquals(-1981113695, x ^= ((tmp = 392404985, tmp)>>(((x<<((2006207061)<<(tmp = 2558988218, tmp)))*((((tmp = 1789304307.1153054, tmp)/(2538061546))<<(tmp = 556026116, tmp))&((tmp = 1076457999.6424632, tmp)*(tmp = -1822378633.2489474, tmp))))%(((((-1117046924)&((-69013651)%(x&(((-2320327696)/(x&x))-(tmp = 2458222544, tmp)))))>>((-3092360983.0037227)/(-3171415636)))*(((tmp = 2520431213, tmp)<<(1066492762.6149663))+((tmp = 1272200889, tmp)^((1687693123.2295754)+x))))-(-1096823395)))));
+ assertEquals(-990556848, x >>= x);
+ assertEquals(981202869119695100, x *= x);
+ assertEquals(981202869119695100, x -= (x/x));
+ assertEquals(0, x ^= (x>>x));
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x ^= x);
+ assertEquals(0, x *= ((((2980512718)>>>x)<<((x^(-1111233869))>>((2531466092.6036797)>>>(((tmp = -1791229364, tmp)*(-2210950307.206208))%((tmp = -806645443, tmp)<<((((((((tmp = 112334634.26187229, tmp)%(x|((((2154021796.1166573)+x)&((-1047293079.9686966)^(tmp = -1894127139, tmp)))+(tmp = 1910946653.2314827, tmp))))^(293142672.5016146))-x)<<(-1593533039.8718698))+x)>>(x<<(((46359706.50393462)&(tmp = 272146661, tmp))|(tmp = 2117690168, tmp))))%(tmp = -1784737092.4924843, tmp)))))))-(1465796246)));
+ assertEquals(0, x &= x);
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x &= (x+(-1612418456)));
+ assertEquals(0, x &= ((tmp = -843964311, tmp)/x));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x *= x);
+ assertEquals(NaN, x += (x>>>(54020240)));
+ assertEquals(489206868, x |= (489206868));
+ assertEquals(489206868, x &= x);
+ assertEquals(489206848, x &= ((tmp = -1699133906.2361684, tmp)>>(tmp = 2658633814, tmp)));
+ assertEquals(489206848, x |= x);
+ assertEquals(1910559006, x -= (tmp = -1421352158, tmp));
+ assertEquals(1, x >>= x);
+ assertEquals(0, x -= x);
+ assertEquals(0, x %= (x^(tmp = 2745376003.2927403, tmp)));
+ assertEquals(0, x %= (((tmp = 3199743302.1063356, tmp)^((-1905944176)&(x>>>(187247029.5209098))))<<((x*((-1394648387)*(1252234289)))-(3140049815))));
+ assertEquals(0, x <<= (-2567872355));
+ assertEquals(0, x %= (tmp = 1057707555.8604916, tmp));
+ assertEquals(0, x %= ((tmp = -1877857405.0228279, tmp)>>>(((tmp = 423831184, tmp)*((tmp = -2106757468.324615, tmp)%(tmp = -1197717524.6540637, tmp)))>>(tmp = -93746263.46774769, tmp))));
+ assertEquals(0, x |= x);
+ assertEquals(-0, x *= ((tmp = 1317609776.6323466, tmp)*(tmp = -26959885.89325118, tmp)));
+ assertEquals(0, x >>= (-1288116122.0091262));
+ assertEquals(0, x &= ((370818172.92511404)%((tmp = -528319853.54781747, tmp)*(x/((tmp = -2839758076, tmp)^(x+(((-1258213460.041857)<<(tmp = 302017800.72064054, tmp))|((((tmp = -624254210, tmp)^((-338165065.97507)|((623392964)-x)))>>>x)%(tmp = 2767629843.0643625, tmp)))))))));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x |= ((-2001549164.1988192)*x));
+ assertEquals(0, x -= x);
+ assertEquals(0, x *= (((((165836842.14390492)*(tmp = -3220002961, tmp))|(-2840620221.747431))%((x/(tmp = 3153915610, tmp))>>>(tmp = 2018941558, tmp)))>>>x));
+ assertEquals(-0, x *= (-231994402.93764925));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x %= (tmp = 2702385056.1149964, tmp));
+ assertEquals(0, x <<= (tmp = 378459323, tmp));
+ assertEquals(0, x >>>= ((x&(x&(((-1014963013)<<(x&((tmp = -3110294840, tmp)|(x+(x<<(1129643420))))))+(1093795819.1853619))))+((((tmp = -2295103369.697398, tmp)&(((370501313.43019223)>>>(2465439579))/x))-x)>>x)));
+ assertEquals(0, x /= ((tmp = 1779625847, tmp)+(tmp = -662459654.6908865, tmp)));
+ assertEquals(0, x -= x);
+ assertEquals(0, x %= ((tmp = 2723291421, tmp)|(277246502.4027958)));
+ assertEquals(0, x ^= (((-2936270162)>>>((((tmp = -2019015609.1648235, tmp)|(47218153))*(-823685284))+x))&(x<<(x*(x|(((tmp = -941955398, tmp)^(tmp = -2365238993.5300865, tmp))-(778674685)))))));
+ assertEquals(0, x >>>= x);
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x &= (-175235975.8858137));
+ assertEquals(-2684493800.1062117, x += (tmp = -2684493800.1062117, tmp));
+ assertEquals(-1290806265.6063132, x -= (-1393687534.4998984));
+ assertEquals(-1290806265, x >>= (((x>>(tmp = -1710112056.4935386, tmp))*(586227650.2860553))<<(tmp = -2918251533.6052856, tmp)));
+ assertEquals(23470008, x >>>= x);
+ assertEquals(1668734969, x |= ((-295560682.9663689)^(x|((((tmp = -1183847364, tmp)&(3135327694))+(1679127747.1406744))-((-1895825528)%((tmp = -3180115006, tmp)+((tmp = 2373812187, tmp)|x)))))));
+ assertEquals(1744306169, x |= (1188503928.5009093));
+ assertEquals(1744306169, x %= (tmp = -2723982401.4997177, tmp));
+ assertEquals(3488612338, x += x);
+ assertEquals(3488612337, x += (((x/(-325849204))>>x)|(-1820624550.9149108)));
+ assertEquals(-1511119305, x ^= (tmp = 1778506182.2952862, tmp));
+ assertEquals(-12211415, x %= (x^(tmp = -54943035, tmp)));
+ assertEquals(-12211415, x %= ((-1267051884)%(-643566443.0122576)));
+ assertEquals(-30.84976063258681, x /= (((1052047194)>>>x)&(1495698235.5117269)));
+ assertEquals(-61.69952126517362, x += x);
+ assertEquals(-244, x <<= (x^(x+(tmp = -2822258210.076373, tmp))));
+ assertEquals(-6652, x &= ((tmp = 2593685093, tmp)>>((((2047688852.4609032)<<((x*(-611076291))*x))^(-2665364024.817528))>>>(165267874))));
+ assertEquals(0, x -= x);
+ assertEquals(0, x /= (2454186758));
+ assertEquals(0, x &= (tmp = -2226895206, tmp));
+ assertEquals(0, x += x);
+ assertEquals(-21390701, x += ((-1369004846.0816503)>>(tmp = -2661552634.039692, tmp)));
+ assertEquals(-0.012568536912921919, x /= (1701924507.856429));
+ assertEquals(7.09517966608176e-11, x /= (tmp = -177141911.8955555, tmp));
+ assertEquals(0, x >>= (tmp = 231535697, tmp));
+ assertEquals(1383687797, x ^= (tmp = -2911279499.568808, tmp));
+ assertEquals(1383687797, x %= (tmp = -2258636646.5294995, tmp));
+ assertEquals(1319, x >>= ((tmp = -2549411892.8426056, tmp)/(((((1532476676)^(153720871.82640445))+x)/(((2988190456.3206205)&(tmp = -2920873674, tmp))-(((((tmp = -1044518167.0581458, tmp)>>x)-((((tmp = -194701879.13505793, tmp)&(498352051))&((tmp = -2167339635.6529818, tmp)^(((x>>(tmp = 700159851, tmp))*(tmp = 2874921158, tmp))/x)))-((2856128689)|((-1876321441)>>>(2110732915)))))^((((tmp = -193379494.18825436, tmp)/(-3055182489.533142))<<x)+((tmp = -2286109605, tmp)>>(tmp = 698475484.3987849, tmp))))^(3182231653.500364))))|(((tmp = -194670835, tmp)>>>((786780139)%(((2114171416.2305853)^(1703145352.8143656))/x)))>>>((tmp = -3029462067, tmp)>>((67647572.02624655)&(x*(-2394283060))))))));
+ assertEquals(13903855, x |= ((tmp = -2515306586, tmp)>>>x));
+ assertEquals(54311, x >>>= ((-2413722658)-((tmp = -2159787584, tmp)^(tmp = 949937622.9744623, tmp))));
+ assertEquals(108622, x += x);
+ assertEquals(1250717187, x ^= ((tmp = 842692148, tmp)+(((2649331689.694273)<<x)-(tmp = -2992181273, tmp))));
+ assertEquals(4536777, x %= (tmp = 73304730, tmp));
+ assertEquals(0, x -= x);
+ assertEquals(-580081499, x ^= ((tmp = -580081499.0170684, tmp)^(x%(tmp = -1542730817.88261, tmp))));
+ assertEquals(-1382738784, x <<= x);
+ assertEquals(-1382738784, x <<= x);
+ assertEquals(2912228512, x >>>= (x*(x>>>x)));
+ assertEquals(-1076374105, x |= (2589443367));
+ assertEquals(-0.2818750938197037, x /= (((tmp = -1559525732.9603848, tmp)|(-477068917.5483327))>>>((-688616257)*((((tmp = -1192490153.1226473, tmp)*(-502280624.0265591))<<(-442688727.4881985))%(x+(((((tmp = -2948836853.831935, tmp)-(tmp = -2850398330.910424, tmp))>>>(x>>>(-1947835558)))^x)+(x*x)))))));
+ assertEquals(2032826546, x |= (tmp = 2032826546.819327, tmp));
+ assertEquals(3408404827.14316, x += (tmp = 1375578281.1431599, tmp));
+ assertEquals(258183922.14315987, x %= (tmp = 350024545, tmp));
+ assertEquals(479694848, x <<= (tmp = -481187157, tmp));
+ assertEquals(-2147483648, x <<= (((tmp = -2956588045.472398, tmp)>>>(((tmp = -1838455399.1775856, tmp)&(((((tmp = -637547, tmp)/x)&(x^((-44876328.1767962)+(((-2059598286)-(1071496688))%(tmp = -1492254402, tmp)))))-(x%x))*(x|x)))>>(1226250760)))<<x));
+ assertEquals(-2288163338.9020815, x -= (140679690.9020816));
+ assertEquals(4954833118513997000, x *= (-2165419327.4906025));
+ assertEquals(1578331238, x ^= (-2410854298.2270393));
+ assertEquals(-810627292, x += (-2388958530));
+ assertEquals(-810627292, x ^= ((1495296640.4087524)/(tmp = 1561790291, tmp)));
+ assertEquals(657116606535253200, x *= x);
+ assertEquals(0.675840332689047, x %= (((-1816548473)^(((tmp = -151918689.19451094, tmp)|(1819911186.535233))/((((((1514297447)+(tmp = 856485190.9684253, tmp))&(((1809369464.4363992)<<(493538496))*x))+((x*(x>>(x&(tmp = 222293461, tmp))))>>>(((784519621)|x)^((-580766922)>>(tmp = -947264116, tmp)))))>>>((((2794210354.22964)>>>(((2896952532.0183973)*((x+(tmp = -1813175940, tmp))<<(tmp = -1302618293, tmp)))&x))>>(x-(((x|((1456466890.1952953)*x))^(-169979758.19158387))-(x-x))))>>x))&(tmp = 2671604078.3026733, tmp))))/(-1701675745)));
+ assertEquals(0.675840332689047, x %= ((tmp = 2421871143, tmp)^x));
+ assertEquals(NaN, x %= ((((tmp = 1175526323.433271, tmp)+(tmp = 2813009575.952405, tmp))%((tmp = -3112133516.3303423, tmp)&x))&((((((-424329392)^(tmp = 1430146361, tmp))+x)-(1533557337.268306))%((tmp = -3117619446, tmp)-(-3127129232)))>>>x)));
+ assertEquals(NaN, x += x);
+ assertEquals(0, x >>>= ((1710641057.7325037)%(104961723.56541145)));
+ assertEquals(0, x <<= (tmp = -970072906, tmp));
+ assertEquals(0, x *= (87768668));
+ assertEquals(-1464968122, x ^= (tmp = -1464968122, tmp));
+ assertEquals(-1467983895, x ^= ((tmp = -1204896021, tmp)>>>(((91792661)&(x>>>(((-2364345606)>>>x)*x)))+x)));
+ assertEquals(2.991581508270506, x /= (-490704963.5591147));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x >>= ((tmp = 639854873, tmp)%(tmp = 743486160.3597239, tmp)));
+ assertEquals(0, x <<= (tmp = 1045577245.3403939, tmp));
+ assertEquals(0, x >>= ((tmp = -1932462290, tmp)|(tmp = 1629217987, tmp)));
+ assertEquals(517617438, x ^= ((tmp = 2737789043, tmp)%(tmp = -2220171604.135681, tmp)));
+ assertEquals(126371, x >>>= ((tmp = 205210223.69909227, tmp)-(tmp = 598118404, tmp)));
+ assertEquals(918548455, x |= ((918228734.8363427)+(x+x)));
+ assertEquals(918548455, x |= ((tmp = 599828198, tmp)>>((tmp = -851081330, tmp)|(tmp = -1152596996.8443217, tmp))));
+ assertEquals(918548443.7739062, x -= ((tmp = 1497642976.2260938, tmp)%(x>>(tmp = -548469702.5849569, tmp))));
+ assertEquals(0.7739062309265137, x %= (x&x));
+ assertEquals(2317939163.8239403, x *= (tmp = 2995116296, tmp));
+ assertEquals(1014415360, x <<= (-279972114));
+ assertEquals(0, x &= ((296810932)/(x*(tmp = -2750499950, tmp))));
+ assertEquals(0, x *= (x%((126285451.05086231)>>>(x*(tmp = -2789790532, tmp)))));
+ assertEquals(0, x >>>= ((975695102.5771483)%(x-((-1011726540)-((tmp = 2223194882, tmp)/x)))));
+ assertEquals(-1747794584, x |= (-1747794584.3839395));
+ assertEquals(-543544679, x %= (tmp = -1204249905, tmp));
+ assertEquals(-543544679, x %= (-881024001));
+ assertEquals(1, x /= x);
+ assertEquals(-1879376393, x |= ((tmp = 161643764, tmp)|(tmp = 2281346499.9084272, tmp)));
+ assertEquals(1.321124264431369, x /= (-1422558379.7061746));
+ assertEquals(1, x >>>= (x&(tmp = -963118950.4710281, tmp)));
+ assertEquals(3, x ^= ((x+x)/x));
+ assertEquals(1, x /= x);
+ assertEquals(1, x &= (2090796073));
+ assertEquals(-1284301873, x ^= (((-11041168.146357536)+(tmp = -1273260707.8134556, tmp))+x));
+ assertEquals(292559045, x &= (x&((-2401110739)^((tmp = 630802904, tmp)^(((1012634447.0346229)+x)%((tmp = -1240091095, tmp)%(x/(-1483936527))))))));
+ assertEquals(0, x %= x);
+ assertEquals(0, x /= (tmp = 613145428.3653506, tmp));
+ assertEquals(0, x /= ((x-(tmp = 3116638456, tmp))*(-973300716)));
+ assertEquals(0, x %= (tmp = -1794741286.0464535, tmp));
+ assertEquals(0, x &= x);
+ assertEquals(0, x >>= (-551370105.0746605));
+ assertEquals(-1471996874, x ^= ((2822970422.2331414)-x));
+ assertEquals(-277914313, x |= (tmp = -818980601.2544096, tmp));
+ assertEquals(-34, x >>= x);
+ assertEquals(305422768, x -= (-305422802));
+ assertEquals(-2406146240, x += (tmp = -2711569008, tmp));
+ assertEquals(1073745408, x &= (tmp = -3046625618, tmp));
+ assertEquals(1073745408, x <<= ((-1234108306.7646303)<<((-233519302)|x)));
+ assertEquals(1073745408, x %= (tmp = 1898831268, tmp));
+ assertEquals(1073745408, x <<= (((tmp = 3089406038, tmp)/x)&(-2960027680)));
+ assertEquals(65536, x >>>= (2858188366));
+ assertEquals(128, x >>>= ((-2640257239.857275)%((tmp = -3185405235.3177376, tmp)*x)));
+ assertEquals(128, x >>>= x);
+ assertEquals(128, x -= (x&(x-(tmp = -247588018, tmp))));
+ assertEquals(81616906825.07776, x *= (tmp = 637632084.57092, tmp));
+ assertEquals(78860097686.07776, x -= (((1507215684)^((709254783)+(((x<<x)*((-2890828152.667641)%(2537817529.2041526)))^x)))+(3114024487)));
+ assertEquals(-2920545695.721283, x += (((tmp = -2555437435, tmp)>>>x)-((2920546109.72129)+x)));
+ assertEquals(-2879412281.721283, x += ((-1662428756)>>>(tmp = -1928491386.6926208, tmp)));
+ assertEquals(67403845, x &= (tmp = 2921644117, tmp));
+ assertEquals(16850961, x >>>= (((-1039328365)>>>(tmp = -768615112, tmp))<<((1037261855)*(tmp = -2906902831.4797926, tmp))));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x *= ((-2729056530)/((-1776175111)%(1493002300.4604707))));
+ assertEquals(0, x *= (tmp = 370696035.22912216, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x |= ((((((tmp = -1541196993, tmp)^x)/(854730380.1799632))/(2879117705.492209))+((((-2892068577)^(-2460614446.1044483))>>>((743413943)<<(-1285280084.4220598)))/(tmp = -1719994579.5141463, tmp)))%(((((tmp = 2522797851.088227, tmp)<<(tmp = 2257160597.1538725, tmp))/(-680406007))&((x>>>(tmp = -260350730, tmp))^(tmp = 1920522110.852598, tmp)))>>(-697620442))));
+ assertEquals(0, x &= x);
+ assertEquals(-591399642.958673, x += (x-(tmp = 591399642.958673, tmp)));
+ assertEquals(27, x >>>= (tmp = -726721317.2109983, tmp));
+ assertEquals(-2043736843, x -= (2043736870));
+ assertEquals(-3991674, x >>= (tmp = 1098126089, tmp));
+ assertEquals(-997919, x >>= ((x%(((x*(((-1497329257.1781685)%(2334511329.2690516))/(-3072526140.6635056)))+(-1843998852))-(tmp = 240300314.34070587, tmp)))+(714080860.6032693)));
+ assertEquals(-0, x %= x);
+ assertEquals(NaN, x /= x);
+ assertEquals(0, x >>= (tmp = 538348328.5363884, tmp));
+ assertEquals(0, x *= (800317515));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>= (984205514));
+ assertEquals(857282491, x += (tmp = 857282491, tmp));
+ assertEquals(587792897, x &= (tmp = 2951307845.164059, tmp));
+ assertEquals(595301269, x |= (tmp = 24285588.90314555, tmp));
+ assertEquals(1190602538, x += x);
+ assertEquals(0, x -= x);
+ assertEquals(-442423060, x |= ((x^((x-(tmp = 2342497475.637024, tmp))%(-1900074414.7678084)))|((tmp = 1932380130, tmp)%(x%(2291727569.817062)))));
+ assertEquals(-442423060, x %= (((tmp = 703479475.545413, tmp)>>(x-x))<<(2435723056.753845)));
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>= x);
+ assertEquals(-1265317851, x |= (tmp = -1265317851, tmp));
+ assertEquals(-2, x >>= (-2015895906.8256726));
+ assertEquals(-0, x %= x);
+ assertEquals(-0, x %= (((1219237746)+(284683029))*(((tmp = 2288119628, tmp)|(-404658161.2563329))*(-265228691.74142504))));
+ assertEquals(1039509109, x -= (-1039509109));
+ assertEquals(2079018218, x += x);
+ assertEquals(-1979.9362673719077, x /= ((3219723500)>>x));
+ assertEquals(-62, x >>= ((x/(326466691))*(tmp = -607654070, tmp)));
+ assertEquals(-45, x |= (tmp = -2954888429.549882, tmp));
+ assertEquals(-1180929712, x &= (3114037588.570232));
+ assertEquals(815550480, x &= (-2302684143.3378315));
+ assertEquals(815550480, x %= (-2177479570));
+ assertEquals(815550480, x %= (tmp = 2895822167, tmp));
+ assertEquals(815550480, x %= (-1247621230.5438688));
+ assertEquals(283929811, x -= ((tmp = 251831053.17096448, tmp)|((tmp = 1140463506.004994, tmp)+(tmp = -743224673.546309, tmp))));
+ assertEquals(1825767424, x <<= (((tmp = 1732353599, tmp)^(tmp = 658726044, tmp))>>>((-2827889370.932477)%(tmp = 1950139204.3291233, tmp))));
+ assertEquals(1828450414, x |= (tmp = 1618538606, tmp));
+ assertEquals(0, x <<= (-2411670689.045702));
+ assertEquals(0, x <<= (-27744888.428537607));
+ assertEquals(-0, x /= (tmp = -1597552450, tmp));
+ assertEquals(0, x >>>= (((2165722776.7220936)>>>(tmp = 1233069931, tmp))>>>(-1120420811)));
+ assertEquals(-0, x *= ((tmp = -1505252656, tmp)>>((((3035637099.6156535)&((467761577.7669761)>>(-361034537)))^(tmp = -2347994840.6541123, tmp))*(tmp = -2191739821, tmp))));
+ assertEquals(0, x &= (795727404.0738752));
+ assertEquals(-0, x *= (tmp = -3125944685.3991394, tmp));
+ assertEquals(-0, x *= (x&x));
+ assertEquals(0, x >>= ((tmp = -2045709233, tmp)^x));
+ assertEquals(NaN, x /= (x>>(x/(3102894071))));
+ assertEquals(NaN, x += ((tmp = 2149079756.8941655, tmp)-(tmp = 810121645.305179, tmp)));
+ assertEquals(0, x >>>= (-859842989));
+ assertEquals(0, x >>>= (tmp = 2530531143.9369526, tmp));
+ assertEquals(0, x >>= (((-932981419.6254237)|(tmp = 1591591715, tmp))>>>(x+((3149795006)>>>(tmp = 613352154, tmp)))));
+ assertEquals(-4294967295, x -= ((((-2289331668)%(-282648480.0078714))>>(-1373720705.5142756))>>>((tmp = 15511563.517014384, tmp)/(360279080))));
+ assertEquals(1, x &= x);
+ assertEquals(0, x >>= (x^(-2791872557.5190563)));
+ assertEquals(0, x &= ((tmp = 336466956.7847167, tmp)>>((1235728252.053619)|(x<<((1828176636.13488)%x)))));
+ assertEquals(-0, x *= (-364042830.8894656));
+ assertEquals(0, x >>>= x);
+ assertEquals(-1675298680, x |= ((2323049541.321387)+(296619075)));
+ assertEquals(-0, x %= x);
+ assertEquals(-1583048579.4420977, x += (-1583048579.4420977));
+ assertEquals(0, x -= x);
+ assertEquals(-2, x ^= ((603171992.0545617)/(((-271888695.718297)%(tmp = -400159585, tmp))^((((tmp = 1536123971, tmp)-(tmp = -2310418666.6243773, tmp))|((tmp = 2242779597.1219435, tmp)<<(tmp = 1758127684.4745512, tmp)))/x))));
+ assertEquals(-2, x &= (x&x));
+ assertEquals(0, x &= ((tmp = -1098806007.4049063, tmp)/(((2862384059.3229523)/((((tmp = -92960842, tmp)-(x>>(tmp = 1244068344.2269042, tmp)))&x)*(tmp = -1919148313, tmp)))<<(-2486665929))));
+ assertEquals(0, x &= x);
+ assertEquals(-1441272634.582818, x -= (1441272634.582818));
+ assertEquals(-3, x >>= (tmp = 3186393693.7727594, tmp));
+ assertEquals(-1206855850, x ^= (((tmp = 607979495.303539, tmp)-(tmp = -2480131951, tmp))^(x*((tmp = 1324153477, tmp)/((1248126288)+(x|(1917331780.0741704)))))));
+ assertEquals(-1206855853, x ^= (x>>>(653288765.1749961)));
+ assertEquals(-1206857725, x &= (3149461539.6019173));
+ assertEquals(3088109571, x >>>= (x*(x<<(tmp = 1543540084, tmp))));
+ assertEquals(536903680, x &= (tmp = 644851760, tmp));
+ assertEquals(536903674.312194, x += (((-3183290076)-((tmp = 40738191.12097299, tmp)-x))/((x>>>(3151371851.9408646))^(tmp = 472698205.22445416, tmp))));
+ assertEquals(2127424750.0506563, x -= (tmp = -1590521075.7384624, tmp));
+ assertEquals(2127424750.0506563, x %= (tmp = 3027273433.361373, tmp));
+ assertEquals(0, x >>= (x>>(1445204441.702043)));
+ assertEquals(NaN, x %= (x<<x));
+ assertEquals(0, x ^= ((tmp = -2903841152.136344, tmp)-(x%(2938662860))));
+ assertEquals(0, x <<= (x<<x));
+ assertEquals(0, x >>>= (tmp = -979481631.33442, tmp));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x &= (((x%((((((tmp = 1657446354.6820035, tmp)>>(-1916527001.2992697))/x)>>(tmp = 1450467955, tmp))&(277676820))+(x/(-945587805))))/((tmp = -690095354, tmp)^x))+(tmp = -2651195021, tmp)));
+ assertEquals(0, x <<= (752343428.2934296));
+ assertEquals(0, x /= (tmp = 3022310299, tmp));
+ assertEquals(0, x >>= (x%((388245402)>>>x)));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x %= ((tmp = 1205123529.8649468, tmp)>>>(-2848300932)));
+ assertEquals(0, x >>= ((x>>>x)<<(tmp = 487841938, tmp)));
+ assertEquals(0, x *= (((273436000.9463471)|(tmp = 141134074.27978027, tmp))^(tmp = 1220326800.7885802, tmp)));
+ assertEquals(1525600768, x |= (((x^(-2674777396))-(tmp = 1966360716.3434916, tmp))<<(794782595.9340223)));
+ assertEquals(761927595, x %= (tmp = -763673173, tmp));
+ assertEquals(1.1353588586934338, x /= ((x&((-1897159300.4789193)*(-348338328.0939896)))&(978680905.6470605)));
+ assertEquals(8.631173314966319e-10, x /= (1315416592));
+ assertEquals(0, x >>= ((tmp = -2581239435, tmp)-((-628818404.1122074)<<x)));
+ assertEquals(0, x -= x);
+ assertEquals(0, x *= (2925158236));
+ assertEquals(0, x /= (x+(tmp = 1405531594.0181243, tmp)));
+ assertEquals(0, x *= (2712022631.230831));
+ assertEquals(0, x >>= (tmp = 80518779.81608999, tmp));
+ assertEquals(1953477932.8046472, x += (tmp = 1953477932.8046472, tmp));
+ assertEquals(1953477932, x >>= (tmp = 3025539936, tmp));
+ assertEquals(1953477932, x -= ((-2675119685.8812313)>>(x/(-1808264410.9754841))));
+ assertEquals(1292620430, x += ((-660857502)%((((tmp = -698782819, tmp)%(tmp = 2847304199, tmp))<<(-2423443217.1315413))+x)));
+ assertEquals(78895, x >>>= x);
+ assertEquals(2, x >>= x);
+ assertEquals(2, x <<= (tmp = 1313641888.8301702, tmp));
+ assertEquals(1857416935.2532766, x += (tmp = 1857416933.2532766, tmp));
+ assertEquals(-1677721600, x <<= (tmp = -2482476902, tmp));
+ assertEquals(309226853.62854385, x -= (tmp = -1986948453.6285439, tmp));
+ assertEquals(33965156, x &= (2409088742));
+ assertEquals(Infinity, x /= (x-(x<<((x/(tmp = -3106546671.536726, tmp))/((tmp = 2695710176, tmp)-((((-2102442864)&(857636911.7079853))/x)%(-65640292)))))));
+ assertEquals(1270005091, x |= (tmp = 1270005091.0081215, tmp));
+ assertEquals(1270005091, x %= (tmp = -1833876598.2761571, tmp));
+ assertEquals(158750636, x >>>= x);
+ assertEquals(-1000809106.0879555, x -= (tmp = 1159559742.0879555, tmp));
+ assertEquals(72400936, x &= ((2448271389.3097963)%(tmp = 1517733861, tmp)));
+ assertEquals(282816, x >>= x);
+ assertEquals(282816, x %= (tmp = 3192677386, tmp));
+ assertEquals(0.00021521351827207216, x /= (1314118194.2040696));
+ assertEquals(Infinity, x /= (((tmp = 2822091386.1977024, tmp)&x)%(tmp = -3155658210, tmp)));
+ assertEquals(NaN, x %= (-359319199));
+ assertEquals(0, x >>>= (((tmp = -2651558483, tmp)-(x<<(tmp = 2537675226.941645, tmp)))<<(tmp = 667468049.0240343, tmp)));
+ assertEquals(-0, x *= (tmp = -2827980482.12998, tmp));
+ assertEquals(-0, x %= (((tmp = -689972329.3533998, tmp)>>>x)|(tmp = -7488144, tmp)));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x |= x);
+ assertEquals(-2410373675.2262926, x -= (2410373675.2262926));
+ assertEquals(1840423, x >>= ((-1081642113)^x));
+ assertEquals(-4829451429403412, x *= (-2624098606.35485));
+ assertEquals(-94552231, x %= (tmp = -97015883, tmp));
+ assertEquals(-94433287, x ^= (((tmp = -2297735280, tmp)&(((tmp = 2261074987.7072973, tmp)%((((2565078998)^(-2573247878))|x)|(((tmp = -2120919004.7239416, tmp)>>(tmp = -579224101, tmp))>>>(1905808441))))*(x|(3149383322))))>>(542664972)));
+ assertEquals(0, x ^= (x<<(tmp = -3112569312, tmp)));
+ assertEquals(0, x <<= (-2141934818.7052917));
+ assertEquals(0, x >>= (tmp = -2539525922, tmp));
+ assertEquals(-434467613, x ^= (tmp = -434467613, tmp));
+ assertEquals(-274792709, x |= (1233452601.462551));
+ assertEquals(-274726917, x |= (-2130333750));
+ assertEquals(-272629761, x |= (-1516071602.5622227));
+ assertEquals(-272629761, x |= ((tmp = 3012131694, tmp)&((tmp = -2595342375.8674774, tmp)-((tmp = -2710765792, tmp)>>>((x-(tmp = 2397845540, tmp))+(2496667307))))));
+ assertEquals(-4194305, x |= (1343705633.165825));
+ assertEquals(4190207, x >>>= ((tmp = 276587830, tmp)*((tmp = -1517753936, tmp)>>x)));
+ assertEquals(0, x >>= (x|((2247486919)-((-1664642412.4710495)*((((tmp = -358185292.17083216, tmp)-(tmp = -1472193444, tmp))*(tmp = 2699733752, tmp))&((x|(x<<(1137610148.1318119)))>>(((375089690.8764564)*x)&(tmp = 859788933.9560187, tmp))))))));
+ assertEquals(0, x %= (3080673960));
+ assertEquals(0, x >>>= (1328846190.1963305));
+ assertEquals(1249447579, x |= (-3045519717.580775));
+ assertEquals(-0.8743931060971377, x /= (-1428931187));
+ assertEquals(1, x |= ((tmp = -1756877535.7557893, tmp)/((-142900015.93200803)<<(1414557031.347334))));
+ assertEquals(759627265, x ^= (759627264.0514802));
+ assertEquals(741823, x >>= (1106391210));
+ assertEquals(610451, x &= ((x>>>((919849416)+((tmp = -427708986, tmp)^((x%x)|(tmp = -2853100288.932063, tmp)))))*x));
+ assertEquals(372650423401, x *= x);
+ assertEquals(410404493, x >>>= ((((-1425086765)>>>x)>>((2813118707.914771)>>(-424850240)))^x));
+ assertEquals(120511585729013, x *= ((tmp = -1889454669, tmp)>>>x));
+ assertEquals(120513295294304.22, x -= (tmp = -1709565291.2115698, tmp));
+ assertEquals(6164, x >>>= ((2244715719.397763)^(tmp = -741235818.6903033, tmp)));
+ assertEquals(937572790.468221, x -= (tmp = -937566626.468221, tmp));
+ assertEquals(937572790, x |= ((2129102867.156146)*(x%x)));
+ assertEquals(32, x &= ((2700124055.3712993)>>>((1977241506)>>>(-2915605511))));
+ assertEquals(32, x %= (tmp = -2513825862, tmp));
+ assertEquals(0, x <<= (-1379604802));
+ assertEquals(0, x >>>= (tmp = -1033248759, tmp));
+ assertEquals(-1151517050, x ^= (3143450246));
+ assertEquals(-180577, x |= ((738373819.4081701)^(-357134176)));
+ assertEquals(-0, x %= x);
+ assertEquals(-2086887759, x |= (tmp = 2208079537, tmp));
+ assertEquals(-2, x >>= (1460216478.7305799));
+ assertEquals(-2, x %= ((-1979700249.0593133)^(-3156454032.4790583)));
+ assertEquals(-256, x <<= ((1810316926)>>>(tmp = 414362256, tmp)));
+ assertEquals(-1, x >>= (((((((-1616428585.595561)*((tmp = 2574896242.9045777, tmp)|(86659152.37838173)))>>(((tmp = 2476869361, tmp)&((x+((tmp = -2445847462.1974697, tmp)>>(tmp = -1960643509.5255682, tmp)))+(x|(((((2231574372.778028)|(tmp = 1824767560, tmp))>>>((1108035230.2692142)|(tmp = 2354035815, tmp)))/((tmp = -2602922032, tmp)>>(-925080304.7681987)))-x))))-(x>>x)))>>>((tmp = 751425805.8402164, tmp)|(tmp = 1165240270.3437088, tmp)))-x)*(2870745939))-(x>>>((tmp = 2986532631.405425, tmp)>>>(((tmp = 2547448699, tmp)+(((((x<<(((((-2756908638.4197435)>>>(3134770084))-(-1147872642.3756688))%(x*(tmp = -282198341.6600039, tmp)))+(-770969864.2055655)))+((-2725270341)^x))/(-3093925722))>>(x&x))>>((tmp = -2705768192, tmp)>>>(((tmp = 577253091.6042917, tmp)/(((x&(((((x+x)>>>(-1000588972))/(x&(717414336)))^(tmp = 428782104.21504414, tmp))>>>(1084724288.953223)))%(tmp = -2130932217.4562194, tmp))&x))-(-286367389)))))+((x>>(tmp = 2001277117, tmp))>>((tmp = 1028512592, tmp)^((tmp = 2055148650, tmp)+((tmp = 1490798399, tmp)/(tmp = -2077566434.2678986, tmp))))))))));
+ assertEquals(-1, x |= (tmp = 1542129482, tmp));
+ assertEquals(-671816743, x &= (tmp = -671816743.9111726, tmp));
+ assertEquals(-1840333080, x -= (1168516337));
+ assertEquals(-1755382023, x |= ((((tmp = 2625163636.0142937, tmp)>>>((tmp = 1534304735, tmp)^x))-(tmp = -1959666777.9995313, tmp))%x));
+ assertEquals(-1750421896, x += (x>>>(tmp = -1364828055.1003118, tmp)));
+ assertEquals(-72864007, x %= (tmp = 239651127, tmp));
+ assertEquals(-72863956, x -= (((tmp = -1103261657.626319, tmp)*((tmp = 2789506613, tmp)+((tmp = 2294239314, tmp)>>>(2588428607.5454817))))>>x));
+ assertEquals(-170337477, x -= (tmp = 97473521, tmp));
+ assertEquals(-170337477, x |= (((tmp = 246292300.58998203, tmp)/(((tmp = -2664407492, tmp)|((-2416228818)^(tmp = 909802077, tmp)))%(tmp = 532643021.68109465, tmp)))/(tmp = 1015597843.8295637, tmp)));
+ assertEquals(1, x >>>= (((tmp = -2247554641.7422867, tmp)/(1186555294))%(tmp = -785511772.3124621, tmp)));
+ assertEquals(1188939891.668705, x -= (tmp = -1188939890.668705, tmp));
+ assertEquals(1188939891, x &= x);
+ assertEquals(1188413555, x &= (((tmp = -372965330.5709038, tmp)%(((tmp = 3108909487, tmp)|(x^(-1056955571.9951684)))^(-1549217484.009048)))/(x>>>(1403428437.9368362))));
+ assertEquals(-0.7343692094664643, x /= (-1618278026.4758227));
+ assertEquals(0, x -= x);
+ assertEquals(0, x &= (-2701762139.7500515));
+ assertEquals(0, x >>>= (((-1692761485.2299166)^x)+(tmp = -1221349575.938864, tmp)));
+ assertEquals(0, x <<= ((2148160230)<<x));
+ assertEquals(0, x <<= (((x<<(-740907931.38363))&(tmp = -930960051.6095045, tmp))>>(x/((tmp = -1921545150.1239789, tmp)/(-3015379806)))));
+ assertEquals(0, x <<= x);
+ assertEquals(NaN, x /= (x|x));
+ assertEquals(0, x >>= (tmp = -2265988773, tmp));
+ assertEquals(-0, x *= (((x<<(-928153614))<<(-989694208))^(2544757713.481016)));
+ assertEquals(0, x >>= ((tmp = 578009959.5299993, tmp)>>x));
+ assertEquals(0, x /= ((((tmp = 412689800.0431709, tmp)&(1630886276))*(tmp = 2028783080.7296097, tmp))/x));
+ assertEquals(0, x |= ((((x*(-2197198786))>>((2719887264.761987)<<(tmp = 2253246512, tmp)))-(tmp = -150703768.07045603, tmp))/(((-3160098146)%(((((1486098047.843547)>>(((tmp = -593773744.1144242, tmp)&(x<<(2651087978)))|((-680492758.930413)>>(tmp = 88363052.13662052, tmp))))<<x)<<(tmp = 2232672341, tmp))/((x<<x)&(((((348589117.64135563)<<(-1010050456.3097556))^(x/(tmp = -2282328795, tmp)))-(tmp = 1653716293, tmp))-((3157124731)/((tmp = 3007369535.341745, tmp)%(tmp = -2246556917, tmp)))))))+x)));
+ assertEquals(0, x >>= ((1935211663.5568764)>>(x-(tmp = 2116580032, tmp))));
+ assertEquals(-1725272693, x ^= (tmp = -1725272693, tmp));
+ assertEquals(313683, x >>>= (-1782632531.2877684));
+ assertEquals(0.009772287443565642, x /= (tmp = 32099240, tmp));
+ assertEquals(-647945916.9902277, x += (-647945917));
+ assertEquals(3647021380, x >>>= ((((((((2470411371.688199)<<x)>>x)-(x>>>((tmp = 1750747780, tmp)/x)))-x)<<(tmp = -2666186351.695101, tmp))^(((tmp = 2749205312.6666174, tmp)%x)&(2069802830.360536)))<<(tmp = 6051917.9244532585, tmp)));
+ assertEquals(-647939220, x |= ((x>>>((tmp = -2980404582.794245, tmp)>>>(-996846982)))^x));
+ assertEquals(-572178450, x |= ((-800571300.3277931)+(tmp = 2084365671, tmp)));
+ assertEquals(1172311208, x &= (x&((tmp = -1207487657.8953774, tmp)^x)));
+ assertEquals(12176516458994, x += ((((tmp = -1534997221, tmp)%(412142731))*((tmp = 2958726303, tmp)>>(1489169839)))+(((-574726407.2051775)>>>(((1772885017)<<(947804536.9958035))>>(-2406844737)))>>x)));
+ assertEquals(-1480065024, x <<= x);
+ assertEquals(-1736999042.227129, x += (tmp = -256934018.22712898, tmp));
+ assertEquals(-1338699394, x ^= ((((((x%(((tmp = -2551168455.222048, tmp)|(3213507293.930222))/((-1559278033)>>((tmp = 3107774495.3698573, tmp)-(2456375180.8660913)))))*((x*(tmp = 1088820004.8562922, tmp))+((tmp = 1850986704.9836102, tmp)%(tmp = -1226590364, tmp))))*(1786192008))&(((2193303940.310299)%(tmp = 1041726867.0602217, tmp))|((2210722848)/((-1293401295.6714435)&((tmp = 3052430315, tmp)|x)))))>>>(tmp = -2028014470.1524236, tmp))+(((1695818039.0383925)<<((1669068145)*(-2746592133.899276)))<<(tmp = 519092169, tmp))));
+ assertEquals(-334674849, x >>= (1170377794));
+ assertEquals(-10214, x >>= ((tmp = 1074704264.3712895, tmp)>>>((tmp = -1200860192, tmp)^((tmp = 539325023.4101218, tmp)*((tmp = -588989295, tmp)|x)))));
+ assertEquals(1384169472, x &= (1384171140));
+ assertEquals(1384169472, x >>>= ((tmp = -2161405973.830981, tmp)*(tmp = 2054628644, tmp)));
+ assertEquals(1610140972, x |= (527961388));
+ assertEquals(1073273198, x += ((tmp = -259650225.71344328, tmp)&(tmp = -344359694, tmp)));
+ assertEquals(65507, x >>= ((x<<((tmp = 2925070713.5245204, tmp)%(x+((tmp = -1229447799, tmp)/(((x/(x|(((-2337139694)|((((((2996268529.7965417)&x)%(((tmp = -1088587413, tmp)>>(-1384104418.90339))>>((tmp = -1643984822.3946526, tmp)+x)))%(((1118125268.4540217)-((((-1975051668.6652594)-(-704573232))+((tmp = 1674952373, tmp)/(tmp = 1321895696.0062659, tmp)))*(tmp = 1820002533.2021284, tmp)))>>>(tmp = -583960746.9993203, tmp)))|((tmp = -2577675508.550925, tmp)&x))/(tmp = 1459790066, tmp)))/(((((1051712301.7804044)&(tmp = -2726396354, tmp))^(tmp = 263937254.18934345, tmp))+(((x^x)*(((tmp = -2289491571, tmp)+x)%(-2239181148)))&x))>>(tmp = -1743418186.3030887, tmp)))))/(tmp = 1475718622, tmp))<<x)))))|(x&((((tmp = -2934707420, tmp)<<x)/x)^(1022527598.7386684)))));
+ assertEquals(2047, x >>= (x-(tmp = 2300626270, tmp)));
+ assertEquals(8384512, x <<= (tmp = -1917680820, tmp));
+ assertEquals(0, x <<= (2393691134));
+ assertEquals(0, x >>= x);
+ assertEquals(649995936.5853252, x -= (tmp = -649995936.5853252, tmp));
+ assertEquals(649995936, x &= x);
+ assertEquals(-0.33672017582945424, x /= (tmp = -1930374188, tmp));
+ assertEquals(-0.33672017582945424, x += (x&((1208055031)^(-2761287670.968586))));
+ assertEquals(0, x |= x);
+ assertEquals(0, x <<= ((-2038368978)/x));
+ assertEquals(0, x >>= (x&((tmp = 2481378057.738218, tmp)&(x+(1172701643)))));
+ assertEquals(0, x <<= ((x*(((((((tmp = 70690601.3046323, tmp)&(((((((((((x+(x+(x^(3118107461))))<<(264682213.41888392))&(tmp = -709415381.8623683, tmp))%(((((-1840054964)>>>(tmp = -405893120.89603686, tmp))|((-625507229)^(3128979265)))>>(x>>((tmp = -2480442390, tmp)*((x>>(tmp = -421414980.88330936, tmp))>>>((tmp = 1850868592, tmp)&(-2948543832.879225))))))|((2986545185)&((tmp = -1947550706, tmp)%(((tmp = 2590238422.1414256, tmp)/(((tmp = -361038812, tmp)>>x)|(((tmp = 1798444068, tmp)|((x&((tmp = -3104542069, tmp)-x))*((tmp = -1158658918, tmp)+((tmp = 2777031040.5552707, tmp)<<(-2816019335.9008327)))))<<x)))/(((2287795988.231702)/x)/(((-2588712925)>>>(2521189250))*((tmp = -2533527920, tmp)+(tmp = 1762281307.2162101, tmp)))))))))/x)/(tmp = 1047121955.5357032, tmp))|(((-121292251)<<(x^(x-(tmp = 1420006180, tmp))))%((-2278606219)>>>(((tmp = -1412487726, tmp)&(((((tmp = 253596554.16016424, tmp)/(tmp = 2083376247.0079951, tmp))^(x^((1549116789.8449988)>>>((((-1844170084)^(tmp = 1886066422, tmp))&x)<<(34918329)))))^(tmp = -440805555.3369155, tmp))-x))%(-1936512969)))))+(2911511178.4035435))|(1012059391))|(x>>>(tmp = -2551794626.158037, tmp)))+((2926596072.210515)/(tmp = -280299595.0450909, tmp))))&((tmp = 1501086971, tmp)^(tmp = 2114076983, tmp)))-((-1679390574.1466925)-(941349044)))-((x>>x)>>((-2600539474.2033434)+(tmp = 2567056503.9079475, tmp))))*(tmp = 1285896052, tmp))%(((tmp = 1191465410.7595167, tmp)>>((tmp = -2857472754, tmp)%x))>>>(((tmp = 1960819627.6552541, tmp)&(-2651207221.127376))*((((-687312743)+((x>>x)<<x))|((((((1549588195)*((tmp = 2733091019, tmp)^((527322540)<<(x>>x))))%(tmp = -2063962943, tmp))*x)*(734060600))&(-3049417708)))+(((((1084267726)+((x|x)^((tmp = -1917070472.4858549, tmp)%((690016078.9375831)*x))))%((((((tmp = -2091172769, tmp)%(2532365378))>>>(-871354260))/(tmp = 254167019.07825458, tmp))&(1330216175.9871218))>>(tmp = 1931099207, tmp)))^(-1116448185.2618852))>>((961660080.8135855)/x)))))))>>>(-1486048007.7053368)));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x %= (tmp = -1202200444.6506357, tmp));
+ assertEquals(-0, x *= (-527500796.4145117));
+ assertEquals(0, x >>= (tmp = -2082822707, tmp));
+ assertEquals(0, x *= ((-1882398459.290778)>>>x));
+ assertEquals(0, x &= (x/(tmp = -1569332286.392817, tmp)));
+ assertEquals(-390169607, x |= (-390169607.11600184));
+ assertEquals(-780339214, x += x);
+ assertEquals(-780339214, x %= (2765959073));
+ assertEquals(-5954, x >>= (tmp = -1900007055, tmp));
+ assertEquals(743563420, x &= ((((-1520146483.5367205)|(-2075330284.3762321))-(tmp = -2263151872, tmp))%(-1264641939.957402)));
+ assertEquals(1487126840, x += (x>>>(((x+((tmp = -1263274491, tmp)>>>x))&(470419048.0490037))%(tmp = -2642587112, tmp))));
+ assertEquals(Infinity, x /= (x^x));
+ assertEquals(0, x ^= ((tmp = -1436368543, tmp)+(x/(tmp = -1125415374.3297129, tmp))));
+ assertEquals(0, x += x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x &= (tmp = 3101147204.2905564, tmp));
+ assertEquals(0, x &= (tmp = 2914487586.606511, tmp));
+ assertEquals(0, x += x);
+ assertEquals(0, x -= (((-1738542908.6138556)&(((x+x)-(tmp = -2801153969, tmp))%(tmp = -1206684064.1477358, tmp)))>>((-2575546469.271897)|(tmp = -2573119106, tmp))));
+ assertEquals(-1468808707, x ^= (tmp = -1468808707, tmp));
+ assertEquals(1357349882, x <<= (tmp = -2808501087.7003627, tmp));
+ assertEquals(-572025862, x |= ((((tmp = -2415486246.573399, tmp)/((tmp = -707895732.4593301, tmp)&x))%((-1960091005.0425267)*(972618070.9166157)))-(1649962343)));
+ assertEquals(327213586796843100, x *= (x%(1337884626)));
+ assertEquals(42991616, x &= (-2905576654.1280055));
+ assertEquals(-26049289585042860, x *= (-605915571.6557121));
+ assertEquals(597809748, x >>= ((362850791.077795)/(tmp = 1222777657.4401796, tmp)));
+ assertEquals(597809748, x |= x);
+ assertEquals(770065246, x -= ((-711227660)|(tmp = -508554506, tmp)));
+ assertEquals(593000483097040500, x *= x);
+ assertEquals(0, x %= x);
+ assertEquals(0, x <<= (317862995.456813));
+ assertEquals(0, x >>= ((tmp = 2518385735, tmp)+((-2973864605.267604)/(-930953312.718833))));
+ assertEquals(1227822411, x ^= (x^(1227822411.8553264)));
+ assertEquals(1090520320, x &= (x+((((-2100097959)>>(x/(tmp = -2002285068, tmp)))/(-364207954.9242482))-((tmp = 2771293106.7927113, tmp)-(tmp = -847237774, tmp)))));
+ assertEquals(1090520320, x >>= (((((2439492849)<<((-2932672756.2578926)*((743648426.7224461)+((2942284935)<<((x/(((tmp = 886289462.6565771, tmp)+(-459458622.7475352))>>(tmp = -785521448.4979162, tmp)))|(tmp = -11630282.877367258, tmp))))))-(tmp = -647511106.9602091, tmp))^x)&x));
+ assertEquals(115944291.48829031, x %= (243644007.12792742));
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>>= ((tmp = -819782567, tmp)%(tmp = 2774793208.1994505, tmp)));
+ assertEquals(0, x >>= (tmp = 721096000.2409859, tmp));
+ assertEquals(0, x &= ((x%x)%x));
+ assertEquals(-0, x *= ((-1670466344)<<x));
+ assertEquals(0, x >>= (-677240844.904707));
+ assertEquals(NaN, x %= (((((-1575993236.6126876)/(-2846264078.9581823))^((((-2220459664)-(((-1809496020)>>>(tmp = -3015964803.4566207, tmp))&x))/(tmp = -3081895596.0486784, tmp))>>>(x&x)))%(x^(-1338943139)))^(x-((((2074140963.2841332)^(tmp = 1878485274, tmp))%(((x/(-2568856967.6491556))^x)<<((x+x)^((((2139002721)|(x<<(-1356174045.840464)))>>x)-(tmp = 2305062176, tmp)))))>>>(((((x<<(tmp = -1663280319.078543, tmp))-((1498355849.4158854)-((-1321681257)>>>(tmp = -1321415088.6152222, tmp))))^(-2266278142.1584673))+(858538943))&((((x-((x|(((tmp = -1576599651, tmp)+((tmp = 1595319586, tmp)&(-2736785205.9203863)))>>((x+((-1856237826)+x))<<(tmp = -1590561854.3540869, tmp))))^(((-41283672.55606127)&(tmp = 2971132248, tmp))+x)))/(-849371349.1667476))%(x*((-1705070934.6892798)>>>x)))<<((2418200640)*x)))))));
+ assertEquals(0, x >>>= (tmp = 664214199.5283061, tmp));
+ assertEquals(0, x <<= ((-2827299151)<<(1815817649)));
+ assertEquals(1405772596, x |= (tmp = 1405772596, tmp));
+ assertEquals(-1483422104, x <<= (-2791499935.6822596));
+ assertEquals(-45271, x >>= (1740128943.4254808));
+ assertEquals(-45271, x <<= ((2072269957)-((tmp = -2553664811.4472017, tmp)*(tmp = -2502730352, tmp))));
+ assertEquals(1192951471.6745887, x -= (-1192996742.6745887));
+ assertEquals(-353370112, x <<= (tmp = -1410280844, tmp));
+ assertEquals(0, x ^= (x%((2754092728)*(-1017564599.1094015))));
+ assertEquals(-2662096003.2397957, x -= (tmp = 2662096003.2397957, tmp));
+ assertEquals(-2587094028.50764, x -= (tmp = -75001974.7321558, tmp));
+ assertEquals(6693055512339889000, x *= x);
+ assertEquals(897526784, x %= (x-((tmp = 897526813, tmp)%(-1525574090))));
+ assertEquals(7011928, x >>= ((-440899641.344357)%x));
+ assertEquals(8382047686388683, x += (x*(1195398423.8538609)));
+ assertEquals(16764095372777366, x += x);
+ assertEquals(16764096859576696, x -= (tmp = -1486799329.7207344, tmp));
+ assertEquals(16764099774187724, x += (2914611029));
+ assertEquals(16764102926624664, x -= (-3152436939.724612));
+ assertEquals(-538220648, x |= x);
+ assertEquals(269110324, x /= (((-2114698894.6014318)/(tmp = 767687453, tmp))>>(623601568.1558858)));
+ assertEquals(256, x >>= x);
+ assertEquals(-293446891, x += (x+(-293447403)));
+ assertEquals(119, x >>>= ((1759400753)>>(2481263470.4489403)));
+ assertEquals(14, x >>= (762849027.89693));
+ assertEquals(16, x += (x&(x>>(1104537666.1510491))));
+ assertEquals(-12499808227.980995, x *= (tmp = -781238014.2488122, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(1, x &= x);
+ assertEquals(0, x >>>= ((tmp = 1513381008, tmp)|(tmp = 1593208075.7259543, tmp)));
+ assertEquals(0, x &= (-788154636.2843091));
+ assertEquals(-0, x /= (tmp = -2124830879, tmp));
+ assertEquals(0, x &= (934237436));
+ assertEquals(0, x |= x);
+ assertEquals(-79370942.97651315, x += (-79370942.97651315));
+ assertEquals(-79370942.97651315, x %= ((tmp = -2683255523, tmp)<<(tmp = 2323123280.287587, tmp)));
+ assertEquals(-79370942, x |= x);
+ assertEquals(0.05861647801688159, x /= (-1354072177.061561));
+ assertEquals(0, x <<= (((((((tmp = 1989257036, tmp)&(tmp = 1565496213.6578887, tmp))&x)&(tmp = -2798643735.905287, tmp))&(2354854813.43784))%(tmp = 1118124748, tmp))<<((tmp = 2453617740, tmp)*(((tmp = 1762604500.492329, tmp)<<(-2865619363))%(((2474193854.640994)|((tmp = 1425847419.6256948, tmp)|(((-1271669386)%((x|((tmp = -2059795445.3607287, tmp)+x))*(x*x)))>>>(tmp = -2997360849.0750895, tmp))))/(tmp = 2326894252, tmp))))));
+ assertEquals(0, x >>>= ((-671325215)/((-727408755.8793397)>>(tmp = 315457854, tmp))));
+ assertEquals(0, x >>= (x&x));
+ assertEquals(0, x <<= ((x/x)>>>(((((x&x)-((x*(((tmp = -2689062497.0087833, tmp)^x)/((-1465906334.9701924)<<(tmp = -349000262, tmp))))*x))%(1630399442.5429945))*x)+((tmp = 605234630, tmp)%(tmp = 2325750892.5065155, tmp)))));
+ assertEquals(0, x |= (x%((x>>(((((tmp = 1622100459, tmp)<<x)&((((((tmp = 2411490075, tmp)<<x)|x)>>((x<<x)-(-2133780459)))/x)&(x+x)))%(x/((((tmp = 580125125.5035453, tmp)>>>(-470336002.1246581))|((tmp = 871348531, tmp)*x))>>(2866448831.23781))))-((2352334552)-(-562797641.6467373))))-(x^(tmp = -681731388, tmp)))));
+ assertEquals(0, x <<= (tmp = -1358347010.3729038, tmp));
+ assertEquals(-260967814, x |= ((tmp = -260967814.45976686, tmp)%(tmp = 1126020255.1772437, tmp)));
+ assertEquals(NaN, x %= ((((tmp = 3176388281, tmp)<<(tmp = 611228283.2600244, tmp))>>>((tmp = 3068009824, tmp)+(tmp = 2482705111, tmp)))>>>((tmp = -750778285.2580311, tmp)>>>x)));
+ assertEquals(0, x <<= (x>>>x));
+ assertEquals(0, x /= (1238919162));
+ assertEquals(0, x >>= (x^x));
+ assertEquals(0, x &= (-2137844801));
+ assertEquals(0, x >>>= (x^(x*(-1774217252))));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x |= x);
+ assertEquals(0, x &= (x<<(tmp = 2791377560, tmp)));
+ assertEquals(-1330674638.8117397, x += (tmp = -1330674638.8117397, tmp));
+ assertEquals(353, x >>>= (-212202857.4320326));
+ assertEquals(353, x ^= ((((x+(tmp = 1448262278, tmp))-(-3141272537))>>(tmp = 1116596587.7832575, tmp))>>>((x-(((tmp = 303953098, tmp)>>>((tmp = 691514425, tmp)/((176223098)*(((2876180016)%(-1805235275.892374))|x))))<<(((tmp = 528736141.838547, tmp)^(2556817082))*(2898381286.2846575))))|((-1445518239)&(tmp = 389789481.9604758, tmp)))));
+ assertEquals(0, x >>>= (-227376461.14343977));
+ assertEquals(0, x <<= (tmp = -2575967504, tmp));
+ assertEquals(0, x <<= (x^((-2668391896)>>((x+(tmp = 598697235.9205595, tmp))+((((-2105306785)|((-1174912319.794015)>>>(x-((148979923)%((((tmp = -2459140558.4436393, tmp)|(1265905916.494016))^(tmp = 1213922357.2230597, tmp))|(1028030636))))))%x)+(((tmp = 1393280827.0135512, tmp)^((tmp = 1210906638, tmp)+(-1572777641.1396031)))<<x))))));
+ assertEquals(0, x *= (tmp = 2134187165, tmp));
+ assertEquals(-1084549964, x -= (tmp = 1084549964, tmp));
+ assertEquals(-2045706240, x &= ((tmp = -1250758905.7889671, tmp)*(x+(((x<<(x/(tmp = -738983664.845448, tmp)))>>>x)&(tmp = 2197525295, tmp)))));
+ assertEquals(-2045706240, x ^= (((522049712.14743733)>>(tmp = -2695628092, tmp))>>>(tmp = -2603972068, tmp)));
+ assertEquals(2249261056, x >>>= x);
+ assertEquals(-33291, x |= ((((1891467762)<<(184547486.213719))-((458875403.50689447)^(((x&(x*x))|x)%(-3127945140))))|(-100765232)));
+ assertEquals(-33291, x %= (1460486884.1367688));
+ assertEquals(-1, x >>= (tmp = -2667341441, tmp));
+ assertEquals(-3.6289151568259606e-10, x /= (tmp = 2755644474.4072013, tmp));
+ assertEquals(-3.6289151568259606e-10, x %= (tmp = 1186700893.0751028, tmp));
+ assertEquals(0, x <<= (tmp = -1199872107.9612694, tmp));
+ assertEquals(371216449, x ^= ((tmp = 371324611.1357789, tmp)&(x-(x|((tmp = -518410357, tmp)>>((tmp = 687379733, tmp)/x))))));
+ assertEquals(0.3561383159088311, x /= (((((x%(((((-2293101242)%((((495316779)/x)-((-3198854939.8857965)>>>((tmp = -288916023, tmp)-(x^(tmp = -2504080119.431858, tmp)))))^(-1201674989)))-((2965433901)*(405932927)))/((1974547923)|(tmp = 534069372, tmp)))-(x-((x+(-1258297330))%x))))<<(((-2648166176.4947824)^(-3043930615))&(1550481610)))<<(tmp = -3118264986.743822, tmp))<<x)|x));
+ assertEquals(-46272499.15029934, x -= (tmp = 46272499.50643766, tmp));
+ assertEquals(-6, x >>= ((tmp = -731454087.0621192, tmp)>>>x));
+ assertEquals(-2.7207928474520667e-9, x /= (((x<<(x|((tmp = -1650731700.9540024, tmp)/(tmp = -677823292, tmp))))^((((((1972576122.928667)>>x)%(2952412902.115453))<<((-2888879343)+(tmp = -425663504, tmp)))>>>(((((tmp = 1089969932, tmp)>>>(x|((-2088509661)/(1131470551))))>>>x)+x)|(tmp = 955695979.7982506, tmp)))|(((((tmp = 826954002.6188571, tmp)^(2016485728))|((x/(((x<<(tmp = 2493217141, tmp))/(-2259979800.997408))-(tmp = -427592173.41389966, tmp)))%(((-471172918)/x)>>>((383234436.16425097)&(tmp = 1664411146.5308032, tmp)))))*(tmp = 1863669754.7545495, tmp))*(x>>(2062197604)))))>>>((x-(2624545856))*(tmp = 1025803102, tmp))));
+ assertEquals(0, x >>= ((tmp = 1068702028, tmp)*(296106770)));
+ assertEquals(0, x ^= (x/x));
+ assertEquals(85359536, x ^= (((x|(((tmp = 740629227, tmp)<<(-1107397366))%((tmp = 2315368172, tmp)>>(((-2269513683)|(-2698795048))+(-396757976)))))*(929482738.803125))^(((-1415213955.4198723)-(tmp = -2885808324, tmp))>>>((tmp = -472842353.85736656, tmp)&(tmp = 1684231312.4497018, tmp)))));
+ assertEquals(2075131904, x <<= x);
+ assertEquals(123, x >>>= (x>>>(tmp = 754093009, tmp)));
+ assertEquals(0, x >>= ((-2690948145)/((1988638799)+x)));
+ assertEquals(0, x >>>= (tmp = -798849903.2467625, tmp));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x *= (2431863540.4609756));
+ assertEquals(484934656, x |= ((-2322193663)*(tmp = -2754666771, tmp)));
+ assertEquals(-82505091404694530, x *= (tmp = -170136513, tmp));
+ assertEquals(-82505090515370620, x += ((-148762237)&(tmp = 889417717, tmp)));
+ assertEquals(-908221124, x %= (tmp = -2346393300, tmp));
+ assertEquals(-1242515799, x ^= (2083328917));
+ assertEquals(-1126056310271520600, x *= ((((tmp = -3065605442, tmp)<<(-3012703413))|x)^(-2081329316.4781387)));
+ assertEquals(-1126056309941068000, x += ((((tmp = 1886925157, tmp)&((tmp = -163003119.31722307, tmp)/((tmp = 2094816076, tmp)>>((tmp = -706947027, tmp)^x))))^((1819889650.5261197)<<(-1641091933)))>>x));
+ assertEquals(-1864360191, x |= (((x/x)|x)|x));
+ assertEquals(-1864360191, x &= x);
+ assertEquals(-3728720382, x += x);
+ assertEquals(1042663165, x ^= (535165183.4230335));
+ assertEquals(2644530017.8833704, x += (1601866852.8833704));
+ assertEquals(-574949401, x |= ((tmp = 943193254.5210983, tmp)^((x%(tmp = -2645213497, tmp))*(-1904818769))));
+ assertEquals(1763223578, x ^= ((x^(tmp = -2244359016, tmp))^(tmp = 320955522, tmp)));
+ assertEquals(-1.9640961474334235, x /= (tmp = -897727731.0502782, tmp));
+ assertEquals(1, x >>>= (x-(-3183031393.8967886)));
+ assertEquals(1, x &= (tmp = 1732572051.4196641, tmp));
+ assertEquals(1, x >>= (-1642797568));
+ assertEquals(-2339115203.3140306, x += (-2339115204.3140306));
+ assertEquals(1955852093, x ^= (((((-1469402389)/(-2648643333.1454573))>>>x)<<(x/x))>>x));
+ assertEquals(-965322519, x ^= (3001399252));
+ assertEquals(-2139727840, x &= (tmp = 2298411812.964484, tmp));
+ assertEquals(2103328, x &= (tmp = -2488723009, tmp));
+ assertEquals(1799011007, x |= (tmp = -2498057537.226923, tmp));
+ assertEquals(1799011007, x |= ((-308193085)>>>x));
+ assertEquals(1799011007, x |= x);
+ assertEquals(818879107, x ^= (1542823996.423564));
+ assertEquals(-2601416919234843600, x *= ((-2357923057.076759)-x));
+ assertEquals(-2601416920481796600, x -= (x|(tmp = -3048039765, tmp)));
+ assertEquals(-33690112, x <<= x);
+ assertEquals(1039491072, x &= (tmp = 1039491474.3389125, tmp));
+ assertEquals(126891, x >>= (-3079837011.6151257));
+ assertEquals(-163191923097543, x *= (((tmp = -2847221258.4048786, tmp)*(x-(tmp = 1527622853.5925639, tmp)))^x));
+ assertEquals(753616551, x ^= (-946895202));
+ assertEquals(-347691264, x <<= (tmp = -433184408.33790135, tmp));
+ assertEquals(0, x <<= (x|(tmp = -1911731462.6835637, tmp)));
+ assertEquals(-0, x *= (tmp = -2616154415.1662617, tmp));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x -= x);
+ assertEquals(0, x *= (2272504250.501526));
+ assertEquals(0, x ^= x);
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x >>>= (2475346113));
+ assertEquals(NaN, x /= (((x+(-2646140897))&(((tmp = 1039073714.142481, tmp)-x)*x))|(x*(((-1277822905.773948)>>(tmp = 2035512354.2400663, tmp))*(77938193.80013895)))));
+ assertEquals(0, x ^= (x<<(tmp = 2491934268, tmp)));
+ assertEquals(0, x &= (tmp = 569878335.4607931, tmp));
+ assertEquals(-88575883, x ^= ((453890820.8012209)-((1569189876)%((-1280613677.7083852)^(-1902514249.29567)))));
+ assertEquals(-88575883, x %= (tmp = 257947563.19206762, tmp));
+ assertEquals(-88575881.7863678, x -= ((tmp = 1257547359.029678, tmp)/(x^(tmp = 948265672.821815, tmp))));
+ assertEquals(-169, x >>= (tmp = -2530523309.6703596, tmp));
+ assertEquals(-1, x >>= x);
+ assertEquals(-1, x |= x);
+ assertEquals(131071, x >>>= (-673590289));
+}
+f();
diff --git a/deps/v8/test/mjsunit/numops-fuzz-part3.js b/deps/v8/test/mjsunit/numops-fuzz-part3.js
new file mode 100644
index 000000000..7813f9182
--- /dev/null
+++ b/deps/v8/test/mjsunit/numops-fuzz-part3.js
@@ -0,0 +1,1178 @@
+// Copyright 2011 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.
+
+function f() {
+ var x = 131071;
+ var tmp = 0;
+ assertEquals(1117196836, x -= (-1117065765));
+ assertEquals(3092236000.7125187, x -= (-1975039164.7125185));
+ assertEquals(1, x /= x);
+ assertEquals(-1599945863, x ^= (tmp = 2695021432.453696, tmp));
+ assertEquals(940543782, x ^= (tmp = 2561494111, tmp));
+ assertEquals(891400321673221800, x *= (tmp = 947749949.2662871, tmp));
+ assertEquals(-1509927296, x >>= ((tmp = 1113290009, tmp)-x));
+ assertEquals(-23, x >>= (tmp = 3216989626.7370152, tmp));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x <<= (431687857.15246475));
+ assertEquals(-0, x /= (tmp = -1924652745.081665, tmp));
+ assertEquals(0, x <<= (1312950547.2179976));
+ assertEquals(0, x %= ((tmp = 2110842937.8580878, tmp)|(x<<x)));
+ assertEquals(0, x >>>= ((((-386879000)-((tmp = -2334036143.9396124, tmp)/((tmp = 965101904.2841234, tmp)<<(((3029227182.8426695)<<((tmp = -464466927, tmp)>>((((((tmp = 849594477.4111787, tmp)^(x&((513950657.6663146)%(x>>>x))))-((2898589263)|x))+(tmp = 2842171258.621288, tmp))>>>(tmp = -3158746843, tmp))<<(tmp = -2891369879, tmp))))-(x-(x&(tmp = -1707413686.2706504, tmp)))))))-(-2860419051))*(-1708418923)));
+ assertEquals(-328055783, x += ((((2857010474.8010874)|((tmp = -1415997622.320347, tmp)-(-1706423374)))%(tmp = 824357977.1339042, tmp))^(x>>(x|x))));
+ assertEquals(-168539902503779140, x *= ((tmp = -1057687018, tmp)<<((1408752963)-(2030056734))));
+ assertEquals(-Infinity, x /= ((x-(2232683614.320658))*(((tmp = 195551174, tmp)*((((739595970)>>>(tmp = -2218890946.8788786, tmp))>>>(((tmp = -240716255.22407627, tmp)&(((((1598029916.3478878)|((tmp = -881749732, tmp)+(x>>x)))^(4443059))<<(((tmp = 2453020763, tmp)+((x>>>(tmp = -1904203813, tmp))&(-355424604.49235344)))<<(tmp = 2814696070, tmp)))%((tmp = -250266444, tmp)>>>(((((2710614972)&(((tmp = 910572052.6994087, tmp)^(tmp = -1028443184.3220406, tmp))/((-2718010521)^(tmp = 676361106, tmp))))|x)^(-1326539884))>>(-1573782639.7129154)))))/(tmp = 1923172768, tmp)))>>>(tmp = -2858780232.4886074, tmp)))/((((((-2060319376.353397)%x)>>(tmp = -3122570085.9065285, tmp))/(tmp = -1499018723.8064275, tmp))*((-655257391)<<x))>>x))));
+ assertEquals(NaN, x += ((3059633304)%((((tmp = 2538190083, tmp)*((tmp = -2386800763.356364, tmp)/x))&(1341370996))%(-2929765076.078223))));
+ assertEquals(NaN, x %= ((x&(347774821))>>>(462318570.2578629)));
+ assertEquals(NaN, x *= ((2829810152.071517)*(tmp = 768565684.6892327, tmp)));
+ assertEquals(NaN, x -= x);
+ assertEquals(0, x >>>= (x&(tmp = 1786182552, tmp)));
+ assertEquals(973967377, x ^= ((tmp = 2115869489.836838, tmp)&(994956497)));
+ assertEquals(985246427.4230617, x += (11279050.423061728));
+ assertEquals(985246427, x &= x);
+ assertEquals(0, x >>= ((tmp = 1090502660.1867907, tmp)>>((-1599370623.5747645)-(tmp = -1321550958, tmp))));
+ assertEquals(0, x %= (tmp = -2386531950.018572, tmp));
+ assertEquals(0, x >>>= x);
+ assertEquals(NaN, x /= x);
+ assertEquals(0, x >>>= (tmp = -1535987507.682257, tmp));
+ assertEquals(-0, x /= (-2570639987));
+ assertEquals(-542895632, x |= (tmp = -542895632, tmp));
+ assertEquals(-33930977, x >>= (tmp = -861198108.1147206, tmp));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x ^= (x*(-608154714.1872904)));
+ assertEquals(-140011520, x |= ((tmp = 377418995, tmp)<<((1989575902)>>(tmp = -2558458031.066773, tmp))));
+ assertEquals(-140026048, x -= ((((tmp = 1465272774.7540011, tmp)<<((2164701398)<<(tmp = -818119264, tmp)))>>((tmp = -1490486001, tmp)>>(664410099.6412607)))>>(x>>>(((tmp = -2438272073.2205153, tmp)%(tmp = 2142162105.4572072, tmp))-(tmp = 2259040711.6543813, tmp)))));
+ assertEquals(39214588236996610, x *= (x<<(-401696127.06632423)));
+ assertEquals(1, x /= x);
+ assertEquals(0, x %= x);
+ assertEquals(0, x *= ((tmp = -1709874807.176726, tmp)&(-2786424611)));
+ assertEquals(-1320474063.3408537, x += (tmp = -1320474063.3408537, tmp));
+ assertEquals(88, x >>>= (tmp = -3179247911.7094674, tmp));
+ assertEquals(1606348131, x += ((tmp = 1555621121.5726175, tmp)|(-3026277110.9493155)));
+ assertEquals(200793516, x >>>= x);
+ assertEquals(-2952688672.1074514, x -= (tmp = 3153482188.1074514, tmp));
+ assertEquals(1342278624, x >>>= ((x>>>((tmp = 1264475713, tmp)-(-913041544)))>>>((tmp = 2008379930, tmp)%(tmp = 3105129336, tmp))));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x /= (tmp = 788363717, tmp));
+ assertEquals(430466213, x -= (tmp = -430466213, tmp));
+ assertEquals(164757385222499550, x *= (tmp = 382741735, tmp));
+ assertEquals(164757385222499550, x %= (((tmp = 1974063648, tmp)%((806015603)>>>x))*((tmp = 2836795324, tmp)<<(tmp = -1785878767, tmp))));
+ assertEquals(-190957725.86956096, x /= (x^((-2939333300.066044)-(x|(-2085991826)))));
+ assertEquals(-190957725.86956096, x %= (tmp = -948386352, tmp));
+ assertEquals(0.6457336106922105, x /= (-295722141));
+ assertEquals(0, x |= ((415991250)&((x>>(tmp = -3188277823, tmp))<<(511898664.1008285))));
+ assertEquals(0, x &= ((793238922)|x));
+ assertEquals(-1576701979, x ^= (2718265317));
+ assertEquals(-49271937, x >>= x);
+ assertEquals(-49271937, x |= x);
+ assertEquals(-49271937, x &= x);
+ assertEquals(775316382, x -= (-824588319));
+ assertEquals(912498176, x <<= (tmp = -2223542776.836312, tmp));
+ assertEquals(0, x -= (x&((tmp = 1999412385.1074471, tmp)/(-1628205254))));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>= (-768730139.7749677));
+ assertEquals(-1861304245, x |= (((5128483)^(((tmp = -1768372004, tmp)/(x^(tmp = 1310002444.757094, tmp)))*((tmp = 188242683.09898067, tmp)^(tmp = -2263757432, tmp))))^((tmp = 2223246327, tmp)*((tmp = -2360528979, tmp)-((tmp = 2442334308, tmp)>>(458302081))))));
+ assertEquals(1, x /= x);
+ assertEquals(2, x += x);
+ assertEquals(1, x /= x);
+ assertEquals(0, x ^= x);
+ assertEquals(-0, x *= (-1852374359.3930533));
+ assertEquals(0, x <<= (tmp = 1223645195.148961, tmp));
+ assertEquals(1789655087, x |= ((-2505312209.770559)>>x));
+ assertEquals(-65568768, x <<= x);
+ assertEquals(4229398528, x >>>= x);
+ assertEquals(-8408187, x |= (-3029781627));
+ assertEquals(-8408187, x |= (((2322165037)-((tmp = -1424506897.362995, tmp)%x))&x));
+ assertEquals(-7884926, x += (x>>>(x|(2738095820))));
+ assertEquals(-7884926, x %= (576507013));
+ assertEquals(751801768, x ^= (tmp = -750241238, tmp));
+ assertEquals(-1986010067668600800, x *= (tmp = -2641667195, tmp));
+ assertEquals(1921196240, x ^= (x%(-1954178308)));
+ assertEquals(847388880, x ^= ((tmp = 1632856124, tmp)&((tmp = -1536309755, tmp)<<(tmp = -3158362800, tmp))));
+ assertEquals(-469662000.6651099, x += (tmp = -1317050880.6651099, tmp));
+ assertEquals(-812358332, x ^= ((-2832480471)>>>(2016495937)));
+ assertEquals(21, x ^= (((tmp = 1815603134.2513008, tmp)/((tmp = 147415927, tmp)%(-1059701742)))+x));
+ assertEquals(-2844409139.792712, x += (tmp = -2844409160.792712, tmp));
+ assertEquals(177070, x >>>= x);
+ assertEquals(0, x %= x);
+ assertEquals(0, x >>= x);
+ assertEquals(1459126376, x ^= (tmp = -2835840920, tmp));
+ assertEquals(1459126376, x %= (-1462864282));
+ assertEquals(0, x >>>= (tmp = 2922724319, tmp));
+ assertEquals(338995506, x ^= (338995506.6411549));
+ assertEquals(336896258, x &= (2635904967));
+ assertEquals(336634112, x -= (x&(tmp = 1659656287, tmp)));
+ assertEquals(NaN, x %= (x-x));
+ assertEquals(NaN, x /= (tmp = -674606200, tmp));
+ assertEquals(NaN, x %= ((x|(2788108542))/(x+(tmp = 600941473, tmp))));
+ assertEquals(0, x >>>= ((-1858251597.3970242)>>>x));
+ assertEquals(1951294747, x |= (tmp = 1951294747, tmp));
+ assertEquals(1951294747, x &= x);
+ assertEquals(-153190625, x |= (-1500095737));
+ assertEquals(23467367587890624, x *= x);
+ assertEquals(346531290.1813514, x /= (((((-513617734.11148167)|x)/((tmp = -2042982150.1170752, tmp)%((x%((x%x)>>>(((-1369980151)&(((922678983)%(x&(tmp = -855337708, tmp)))-((tmp = -2717183760, tmp)>>>((1939904985.4701347)%(((tmp = -2473316858, tmp)&((tmp = -599556221.9046664, tmp)>>((tmp = -6352213, tmp)/x)))&x)))))%x)))/((tmp = -1842773812.8648412, tmp)>>>(((x>>>(tmp = 499774063, tmp))<<(((tmp = -1353532660.5755146, tmp)*(-3070956509))>>(((-905883994.0188017)>>(tmp = -16637173, tmp))<<((tmp = 471668537, tmp)*((tmp = -232036004.26637793, tmp)/x)))))&(tmp = 85227224, tmp))))))>>>(x|(-2528471983)))-((tmp = 1531574803, tmp)+((x>>>x)-(2889291290.158888)))));
+ assertEquals(-94.42225749399837, x /= (((tmp = 2381634642.1432824, tmp)>>(tmp = -2637618935, tmp))|(2307200473)));
+ assertEquals(-47, x >>= (1524333345.141235));
+ assertEquals(-2.8699253616435082e-8, x /= (1637673252));
+ assertEquals(0, x |= x);
+ assertEquals(1083427040, x += ((-2012055268)<<(tmp = -2192382589.6911573, tmp)));
+ assertEquals(1083427040, x %= (x*x));
+ assertEquals(2694039776, x += ((((-1740065704.9004602)<<(-736392934))%(2781638048.424092))>>>(x&x)));
+ assertEquals(-1600927520, x |= ((tmp = 2904430054.869525, tmp)*(((1054051883.4751332)*x)*((-939020743)-(tmp = 1636935481.1834455, tmp)))));
+ assertEquals(-1600927520, x -= (x%x));
+ assertEquals(3037584978216498700, x *= (tmp = -1897390694, tmp));
+ assertEquals(372598954.1823988, x %= (tmp = 1553763703.5082102, tmp));
+ assertEquals(-1476395008, x <<= ((x>>((tmp = 282496335.49494267, tmp)^((-1948623419.6947453)|((((((tmp = -1203306995, tmp)-(-5554612.355098486))>>>(1867254951.4836824))>>x)|(-695777865))/((-59122652.19377303)<<(-609999229.7448442))))))>>(x/(tmp = -1207010654.9993455, tmp))));
+ assertEquals(-2.2540185787941605, x /= (((tmp = 1364159859.9199843, tmp)*x)>>x));
+ assertEquals(-2, x |= x);
+ assertEquals(2241824008, x *= ((3174055292.962967)>>(((-2379151623.602476)>>(tmp = -1423760236, tmp))>>(tmp = -522536019.2225733, tmp))));
+ assertEquals(-2138158385, x ^= ((x>>((((1316131966.9180691)-((x*x)>>x))>>>x)>>((-2712430284)|(((((x<<(-616185937.6090865))-(((x-(tmp = 2957048661, tmp))<<(tmp = 617564839.888214, tmp))/(x%((tmp = -447175647.9393475, tmp)<<(2203298493.460617)))))-((x&((x<<(914944265))^(((-1294901094)*((tmp = 2512344795, tmp)+((((tmp = -1227572518, tmp)%(1831277766.4920158))*((x|x)^(tmp = 2515415182.6718826, tmp)))*x)))-(961485129))))>>>(tmp = 2079018304, tmp)))>>(tmp = 734028202, tmp))^(554858721.6149715)))))-((tmp = 1312985279.5114603, tmp)^(tmp = 2450817476.179955, tmp))));
+ assertEquals(2.759030298237921, x /= (x|(tmp = -775901745.3688724, tmp)));
+ assertEquals(8, x <<= x);
+ assertEquals(NaN, x %= (((x&((1792031228.831834)>>(-1174912501)))%(((-2351757750)+(tmp = -2610099430, tmp))*(-2811655968)))*(x&(tmp = -1881632878, tmp))));
+ assertEquals(0, x &= ((x*(616116645.7508612))^(2789436828.536846)));
+ assertEquals(0, x *= x);
+ assertEquals(35097452, x ^= ((tmp = 1023684579, tmp)%(((x|((tmp = -757953041, tmp)+(772988909)))+(tmp = -2934577578, tmp))>>>((tmp = -1973224283, tmp)>>>((x*(2244818063.270375))|(x-(-716709285)))))));
+ assertEquals(0.015207441433418992, x /= (2307913014.4056892));
+ assertEquals(-5865042.942076175, x -= (5865042.957283616));
+ assertEquals(-67719.94207617454, x %= (((1464126615.2493973)+(398302030.0108756))>>>x));
+ assertEquals(4294899577, x >>>= (x<<x));
+ assertEquals(-1, x >>= (tmp = 607447902, tmp));
+ assertEquals(-1, x >>= (3081219749.9119744));
+ assertEquals(6.53694303504065e-10, x /= (tmp = -1529767040.4034374, tmp));
+ assertEquals(6.53694303504065e-10, x %= ((tmp = 899070650.7190754, tmp)&(tmp = -1101166301, tmp)));
+ assertEquals(6.53694303504065e-10, x %= (tmp = -2207346460, tmp));
+ assertEquals(NaN, x %= (((x&x)>>x)%(((-10980184)+x)&(tmp = -1473044870.4729445, tmp))));
+ assertEquals(NaN, x -= x);
+ assertEquals(-1755985426, x ^= (tmp = 2538981870, tmp));
+ assertEquals(-13842, x %= ((((-2258237411.3816605)+(-1325704332.0531585))<<((tmp = -877665450.1877053, tmp)>>(((((2420989037)+(2084279990.6278818))*(-327869571.9348242))+x)^x)))>>>x));
+ assertEquals(1, x /= x);
+ assertEquals(1, x >>= ((2241312290)^(2859250114)));
+ assertEquals(0, x >>= x);
+ assertEquals(-1615631756, x |= (-1615631756.1469975));
+ assertEquals(-1615631756, x |= x);
+ assertEquals(-627245056, x <<= ((x*(tmp = -1308330685.5971081, tmp))|(tmp = 1479586158, tmp)));
+ assertEquals(-627245056, x |= x);
+ assertEquals(1786953888, x ^= (-1340096352.1839824));
+ assertEquals(1668014353, x -= (tmp = 118939535, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(-645681, x ^= ((-1322356629)>>(tmp = 1829870283, tmp)));
+ assertEquals(-1322354688, x <<= (-794779253));
+ assertEquals(-4310084378.672725, x += (-2987729690.6727247));
+ assertEquals(-8620168757.34545, x += x);
+ assertEquals(-8720421, x |= (tmp = -748107877.6417065, tmp));
+ assertEquals(-1508858270, x ^= (1500137913));
+ assertEquals(-0.825735756765112, x /= (1827289490.1767085));
+ assertEquals(1253449509.1742642, x += (((tmp = 1253449509.9576545, tmp)-(((tmp = 2860243975, tmp)+(367947569.85976696))>>(((((530960315)>>>((((x%(tmp = -2203199228, tmp))<<(x*(((tmp = -117302283, tmp)/(x-((2579576936)%(-1225024012))))&(tmp = -2857767500.1967726, tmp))))/((x/((tmp = -166066119, tmp)<<x))|x))>>>x))|(((2771852372)>>(((tmp = -3103692094.1463976, tmp)-(tmp = 2867208546.069278, tmp))>>>(702718610.1963737)))|(tmp = 2680447361, tmp)))>>x)>>(-2006613979.051014))))^((-1665626277.9339101)/(x<<(tmp = 342268763, tmp)))));
+ assertEquals(1693336701.1742642, x += (tmp = 439887192, tmp));
+ assertEquals(0.8479581831275719, x /= ((1171383583)+(((x&x)>>>(51482548.618915915))-(tmp = -825572595.1031849, tmp))));
+ assertEquals(28, x |= ((tmp = -2355932919.6737213, tmp)>>(tmp = -2395605638, tmp)));
+ assertEquals(0, x %= x);
+ assertEquals(0, x -= x);
+ assertEquals(0, x <<= (x^((tmp = 2793423893.484949, tmp)*(1585074754.3250475))));
+ assertEquals(0, x >>= (x/(x-((957719861.9175875)&(1288527195)))));
+ assertEquals(0, x >>>= ((-1429196921.4432657)/x));
+ assertEquals(-852424225.734199, x -= (tmp = 852424225.734199, tmp));
+ assertEquals(-46674433, x |= ((tmp = -2335242963, tmp)*((2135206646.2614377)>>(tmp = 505649511.8292929, tmp))));
+ assertEquals(2944662357, x += (tmp = 2991336790, tmp));
+ assertEquals(1404, x >>>= (849155189.1503456));
+ assertEquals(-846755170, x ^= (tmp = -846753822.4471285, tmp));
+ assertEquals(52615, x >>>= ((-517068110)+x));
+ assertEquals(1475021859.9916897, x += (tmp = 1474969244.9916897, tmp));
+ assertEquals(0, x %= x);
+ assertEquals(0, x %= ((539583595.8244679)*(tmp = 1469751690.9193692, tmp)));
+ assertEquals(0, x &= (807524227.2057163));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x -= (x^((tmp = -362481588, tmp)%(2611296227))));
+ assertEquals(NaN, x *= x);
+ assertEquals(0, x >>= ((-2519875630.999908)<<x));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x += (((tmp = 2485209575, tmp)>>(tmp = 2326979823, tmp))%(x-(((-1296334640.7476478)&x)<<x))));
+ assertEquals(0, x >>= (((tmp = 1370704131, tmp)^((((tmp = 793217372.7587746, tmp)>>(((-1455696484.109328)|(((((-2186284424.5379324)<<(tmp = 3052914152.254852, tmp))-(x>>(tmp = 3121403408, tmp)))+((778194280)-(((((tmp = 2398957652, tmp)-(x+(((-2592019996.937958)>>((tmp = 1648537981, tmp)>>x))<<(-677436594))))<<(39366669.09012544))|((tmp = 3133808408.9582872, tmp)-(-2987527245.010673)))*x)))|((tmp = -2178662629, tmp)<<x)))^(((tmp = 909652440.3570575, tmp)%(-2572839902.6852217))%(-1879408081))))*(tmp = -2910988598, tmp))&(((x^x)>>(2822040993))|((x*x)^(((1072489842.6785052)|(x-(((464054192.7390214)^x)<<(tmp = -2754448095, tmp))))*((tmp = -1544182396, tmp)/(tmp = -3198554481, tmp)))))))^(tmp = 1946162396.9841106, tmp)));
+ assertEquals(371272192, x |= (((x^((x-(x/x))&(tmp = 2370429394, tmp)))-(tmp = -403692829, tmp))*(tmp = 2808636109, tmp)));
+ assertEquals(929786482, x |= ((729966239.8987448)^(x-((tmp = 120127779, tmp)^((tmp = -3088531385, tmp)>>>((x+((tmp = 2364833601, tmp)>>>(((599149090.6666714)>>(tmp = 2838821032, tmp))%(tmp = -662846011, tmp))))-(tmp = 1168491221.1813436, tmp)))))));
+ assertEquals(-681121542, x += ((-1610909505.998718)^((tmp = -957338882, tmp)>>>(tmp = 1935594133.6531684, tmp))));
+ assertEquals(-2147483648, x <<= ((tmp = 15161708, tmp)|(2453975670)));
+ assertEquals(-2147483648, x >>= x);
+ assertEquals(0, x <<= (2080486058));
+ assertEquals(0, x &= (((x&(tmp = -767821326, tmp))/((tmp = 1877040536, tmp)>>>(tmp = 2378603217.75597, tmp)))*(-1601799835)));
+ assertEquals(0, x %= (-1820240383));
+ assertEquals(1621233920, x ^= ((tmp = 820230232, tmp)*(1727283900)));
+ assertEquals(1621233920, x |= (x>>>x));
+ assertEquals(1621233931, x += ((tmp = 794966194.9011587, tmp)>>(tmp = -597737830.5450518, tmp)));
+ assertEquals(1621276543, x |= (((x^((2354444886)+(tmp = 685142845.4708651, tmp)))-(tmp = 790204976.9120214, tmp))>>>((((tmp = -2792921939, tmp)/(((((tmp = -80705524, tmp)<<x)-(((((((tmp = 1951577216.379527, tmp)>>>x)%((-529882150)>>>(tmp = -1682409624, tmp)))<<((-42043756.29025769)-(-1803729173.6855814)))/(2937202170.118023))*(tmp = -1998098798.5722106, tmp))*(tmp = -2996229463.904228, tmp)))&x)>>>(-301330643)))/(-2858859382.0050273))-(tmp = 1571854256.0740635, tmp))));
+ assertEquals(810638271, x >>>= (x/(1553632833)));
+ assertEquals(810638271, x <<= (tmp = -1467397440, tmp));
+ assertEquals(-2147483648, x <<= x);
+ assertEquals(871068871, x ^= (tmp = 3018552519, tmp));
+ assertEquals(-1073743881, x |= ((tmp = 2294122324.020989, tmp)|(tmp = -1799706842.4493146, tmp)));
+ assertEquals(-77816868, x += (((-2225296403)&x)>>(tmp = -2667103424.445239, tmp)));
+ assertEquals(-1215889, x >>= (tmp = 1876107590.8391647, tmp));
+ assertEquals(-2431778, x += x);
+ assertEquals(4292535518, x >>>= (((x>>(-1825580683))/x)%x));
+ assertEquals(4292802560, x -= (x|(1492864090)));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>= x);
+ assertEquals(0, x %= (tmp = 2173121205, tmp));
+ assertEquals(0, x *= (x>>x));
+ assertEquals(1565261471, x |= ((1565261471.323931)>>>x));
+ assertEquals(0, x -= x);
+ assertEquals(-86980804, x |= (-86980804));
+ assertEquals(-698956484, x -= (((((2754713793.1746016)*(((((-1514587465.0698888)>>(tmp = -1307050817, tmp))/(tmp = 2368054667.438519, tmp))*(-1908125943.5714772))<<(x>>>(-357164827.4932244))))+(1257487617))<<(2954979945))&(612330472)));
+ assertEquals(-1073741824, x <<= x);
+ assertEquals(54497747, x ^= (-1019244077.098908));
+ assertEquals(54501375, x |= (((tmp = 1944912427, tmp)>>>x)%x));
+ assertEquals(0, x -= x);
+ assertEquals(0, x -= x);
+ assertEquals(-0, x *= (-1748215388));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x >>>= (((tmp = 988769112, tmp)%(tmp = -3133658477, tmp))<<x));
+ assertEquals(0, x %= (1685221089.2950323));
+ assertEquals(0, x >>>= (x+((793467168)-(tmp = 135877882, tmp))));
+ assertEquals(0, x %= ((tmp = -2406801984, tmp)%(tmp = -987618172, tmp)));
+ assertEquals(0, x *= ((-2943444887.953456)|(tmp = -2327469738.4544783, tmp)));
+ assertEquals(0, x >>= x);
+ assertEquals(-145484729.70167828, x += (tmp = -145484729.70167828, tmp));
+ assertEquals(1140855872, x &= (x^(tmp = 3151437967.965556, tmp)));
+ assertEquals(1486808408, x += (tmp = 345952536, tmp));
+ assertEquals(107846582.36594129, x %= (-1378961825.6340587));
+ assertEquals(-642031616, x <<= (x+x));
+ assertEquals(151747770.95108718, x *= (x/(tmp = 2716379907, tmp)));
+ assertEquals(192723456, x <<= (tmp = -1731167384, tmp));
+ assertEquals(2151208003, x -= ((-2151208003)+x));
+ assertEquals(1, x /= x);
+ assertEquals(1, x |= x);
+ assertEquals(1996766603, x |= (1996766602));
+ assertEquals(895606123, x ^= (tmp = 1113972960.966081, tmp));
+ assertEquals(-1500036886, x ^= (tmp = 2482412929, tmp));
+ assertEquals(-1542644247, x ^= (x>>>((tmp = 51449105, tmp)>>>(((-2057313176)*x)/(-1768119916)))));
+ assertEquals(-1496074063273093600, x *= ((tmp = 786152274, tmp)^(387292498)));
+ assertEquals(-794329073, x %= (((tmp = -2314637675.617696, tmp)*((((x*(411053423.29070306))-(2889448433.4240828))/((-970630131)/(tmp = -2886607600.7423067, tmp)))<<(tmp = 1263617112.9362245, tmp)))|(2816980223.8209996)));
+ assertEquals(2468008436047106600, x *= (tmp = -3107035257.725115, tmp));
+ assertEquals(3040956928, x >>>= ((tmp = 1514372119.1787262, tmp)*(3169809008)));
+ assertEquals(-19, x >>= (tmp = -266966022.10604453, tmp));
+ assertEquals(-1.6505580654964654e-8, x /= ((-3143841480)>>(x-x)));
+ assertEquals(-2.2420284729165577e-7, x *= (x*((((703414102.2523813)%(tmp = 2989948152, tmp))-((-1583401827.2949386)^((tmp = -1916731338, tmp)%((331500653.3566053)|(((tmp = 29865940, tmp)+((tmp = -2294889418.6764183, tmp)<<(tmp = -1558629267.255229, tmp)))>>>(x*(x+x)))))))|((988977957)&(-2986790281)))));
+ assertEquals(0, x ^= (x/(tmp = 781117823.345541, tmp)));
+ assertEquals(NaN, x *= (((x^((((tmp = -2969290335, tmp)+(((((tmp = -175387021, tmp)&(tmp = -1080807973, tmp))<<(tmp = -2395571076.6876855, tmp))|((tmp = -1775289899.4106793, tmp)^x))|(-2963463918)))*(tmp = -1761443911, tmp))^(tmp = 847135725, tmp)))<<((146689636)<<x))%x));
+ assertEquals(0, x ^= x);
+ assertEquals(1720182184, x -= (((tmp = 3184020508, tmp)|((-489485703)+(tmp = -2644503573, tmp)))&(tmp = 2575055579.6375213, tmp)));
+ assertEquals(1720182184, x >>= (x<<(-45408034)));
+ assertEquals(5.759243187540471e+27, x *= (((x&(1456298805))+(x<<(106573181)))*((566861317.2877743)+(2262937360.3733215))));
+ assertEquals(5.759243187540471e+27, x -= (tmp = -1365873935, tmp));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x >>= (1960073319.3465362));
+ assertEquals(0, x <<= x);
+ assertEquals(560463904, x += ((tmp = 1844076589.9286406, tmp)&((((((-691675777.5800121)|(-745631201))|x)+(tmp = 1504458593.2843904, tmp))-x)<<x)));
+ assertEquals(-513210271, x -= (x|(1052702623.7761713)));
+ assertEquals(3781757025, x >>>= ((-1346666404.362477)*(tmp = 2798191459, tmp)));
+ assertEquals(1080100929, x &= (1122097879.882534));
+ assertEquals(1276833905.8093092, x *= ((1276833905.8093092)/x));
+ assertEquals(1276833905.8093092, x %= (1796226525.7152414));
+ assertEquals(1276833905, x <<= (((tmp = -491205007.83412814, tmp)*(tmp = 1496201476.496839, tmp))>>(x+((tmp = -854043282.114594, tmp)-((x|(tmp = -807842056, tmp))*x)))));
+ assertEquals(1276833905, x %= (((-1870099318)>>>(((tmp = -2689717222, tmp)/(248095232))/(tmp = 1036728800.5566598, tmp)))&(((((857866837)>>(tmp = 3034825801.740485, tmp))|(-1676371984))>>>(x<<x))%((-3035366571.0221004)*(1578324367.8819473)))));
+ assertEquals(1, x /= x);
+ assertEquals(2819223656.189109, x += (2819223655.189109));
+ assertEquals(-1475743640, x >>= (((tmp = 2586723314.38089, tmp)/(x&(tmp = -697978283.9961061, tmp)))<<(x%((-1167534676)>>(x^((tmp = -284763535, tmp)*((x%x)&((((tmp = 2916973220.726839, tmp)%x)/(tmp = -1338421209.0621986, tmp))|((tmp = -834710536.803335, tmp)%x)))))))));
+ assertEquals(-3267683406, x -= (tmp = 1791939766, tmp));
+ assertEquals(-2090420900700614100, x *= (639725653));
+ assertEquals(-1540353536, x %= ((-1800269105)<<((((x&(((tmp = 1135087416.3945065, tmp)^(613708290))>>x))>>(tmp = -1234604858.7683473, tmp))^(2404822882.7666225))>>>((tmp = -287205516, tmp)-((1648853730.1462333)^((x+(x%((tmp = 359176339, tmp)%((2856479172)<<(tmp = -1995209313, tmp)))))^(((tmp = 2857919171.839304, tmp)>>>(tmp = 2779498870, tmp))>>x)))))));
+ assertEquals(-2093767030, x ^= (654554250.498078));
+ assertEquals(1, x >>>= ((tmp = -166296226.12181997, tmp)^(x/x)));
+ assertEquals(-1487427474, x -= ((x<<x)|(1487427475.4063978)));
+ assertEquals(-1487427470.562726, x += ((-1226399959.8267038)/((tmp = 2172365551, tmp)<<x)));
+ assertEquals(-3457859227618939400, x *= (tmp = 2324724597.3686075, tmp));
+ assertEquals(396221312, x >>= (-1354035390));
+ assertEquals(0, x %= x);
+ assertEquals(0, x &= (tmp = 2733387603, tmp));
+ assertEquals(1485905453, x |= ((((tmp = -1321532329.304437, tmp)&((((tmp = 1817382709.4180388, tmp)%(((tmp = 2089156555.7749293, tmp)-(-1555460267))|(tmp = 717392475.9986715, tmp)))%(tmp = 1976713214, tmp))^x))>>>x)+(tmp = -2812404197.002721, tmp)));
+ assertEquals(1485905453, x |= x);
+ assertEquals(-997658264, x <<= (-1409757949.6038744));
+ assertEquals(-997657290, x -= ((-2041106361)>>(tmp = -2014750507, tmp)));
+ assertEquals(-2138512124, x &= (tmp = 2565597060, tmp));
+ assertEquals(8422400, x &= ((-2819342693.5172367)*(tmp = 1441722560, tmp)));
+ assertEquals(111816531.81703067, x -= (-103394131.81703067));
+ assertEquals(59606682.673836395, x *= ((tmp = -1451690098, tmp)/(x-(2835050651.717734))));
+ assertEquals(-119213365.34767279, x *= (x|((-2656365050)/((-66180492)+(tmp = 284225706.32323086, tmp)))));
+ assertEquals(-232839, x >>= (1694344809.435083));
+ assertEquals(-1, x >>= x);
+ assertEquals(1, x *= x);
+ assertEquals(1, x |= x);
+ assertEquals(0, x >>= (tmp = 397239268, tmp));
+ assertEquals(-1525784563, x -= (tmp = 1525784563, tmp));
+ assertEquals(-153.62740888512675, x /= (((tmp = -2040622579.5354173, tmp)*(tmp = -1149025861.549324, tmp))%(((tmp = 2981701364.0073133, tmp)*(tmp = 2993366361, tmp))|(x|(tmp = 1800299979, tmp)))));
+ assertEquals(-1671795135, x &= (-1671795135.6173766));
+ assertEquals(-4253, x |= ((((x*((1533721762.8796673)<<((tmp = 1026164775.0081646, tmp)<<x)))<<(((x-((((x>>((((((tmp = -481536070.7067797, tmp)&(tmp = 1663121016, tmp))>>>(-2974733313.5449667))+(tmp = -493019653, tmp))>>x)&(tmp = 879307404.8600142, tmp)))>>>x)%(x-(tmp = -1806412445.788453, tmp)))%x))<<(x<<(x+x)))+x))>>((tmp = -332473688.28477216, tmp)<<((tmp = 1701065928, tmp)+(((((tmp = -2407330783, tmp)+x)-((tmp = 584100783, tmp)%(tmp = -3077106506, tmp)))^x)>>x))))<<x));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x >>>= (1578470476.6074834));
+ assertEquals(0, x >>>= (974609751));
+ assertEquals(-120, x += (x-((tmp = -245718438.0842378, tmp)>>>(tmp = -1870354951, tmp))));
+ assertEquals(-6.134465505515781e-8, x /= (1956160645));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x *= (tmp = -399718472.70049024, tmp));
+ assertEquals(-1803198769.8413258, x += (-1803198769.8413258));
+ assertEquals(988624943, x ^= ((((tmp = 320776739.5608537, tmp)*(((tmp = -983452570.3150327, tmp)^x)&(tmp = -3181597938, tmp)))-(tmp = -1367913740.9036021, tmp))/(((tmp = -535854933.2943456, tmp)-(717666905.8122432))>>>(((((x^(tmp = 380453258.60062766, tmp))^(tmp = -1242333929, tmp))/((tmp = 1072416261, tmp)+(((2090466933)*(x*(tmp = -386283072, tmp)))|((tmp = 789259942, tmp)<<(tmp = -1475723636.1901488, tmp)))))>>>x)%((x>>(tmp = -1243048658.3818703, tmp))|((((((tmp = -619553509, tmp)|x)/(878117279.285609))|((x<<(x>>>(tmp = -749568437.7390883, tmp)))*x))/(tmp = 1674804407, tmp))-(x*(tmp = 1528620873, tmp))))))));
+ assertEquals(988625135, x |= (x>>>(tmp = 2402222006, tmp)));
+ assertEquals(988625135, x %= (-2691094165.990094));
+ assertEquals(0, x %= x);
+ assertEquals(-0, x *= (tmp = -1409904262, tmp));
+ assertEquals(-0, x /= ((1176483512.8626208)<<x));
+ assertEquals(0, x &= ((((1677892713.6240005)^(tmp = 2575724881, tmp))^(tmp = -2935655281.208194, tmp))*(216675668)));
+ assertEquals(0, x >>= (tmp = -1296960457, tmp));
+ assertEquals(0, x |= x);
+ assertEquals(NaN, x /= x);
+ assertEquals(0, x <<= (x>>(-3127984289.9112387)));
+ assertEquals(0, x %= ((tmp = 190018725.45957255, tmp)<<((x>>>x)/x)));
+ assertEquals(0, x /= (1185681972));
+ assertEquals(0, x &= ((tmp = -1285574617, tmp)>>x));
+ assertEquals(0, x >>>= ((tmp = 2498246277.2054763, tmp)+(((tmp = 924534435, tmp)&x)>>(tmp = 1379755429, tmp))));
+ assertEquals(0, x -= x);
+ assertEquals(0, x /= (3093439341));
+ assertEquals(0, x *= (x>>>x));
+ assertEquals(0, x &= (tmp = 551328367, tmp));
+ assertEquals(-0, x /= (-3153411714.834353));
+ assertEquals(1217585288, x ^= (tmp = -3077382008.637764, tmp));
+ assertEquals(-639702017, x |= ((tmp = -640922633, tmp)%(tmp = -879654762, tmp)));
+ assertEquals(-1645297680, x <<= (tmp = 1418982820.8182912, tmp));
+ assertEquals(-1.4059558868398736, x /= (1170234212.4674253));
+ assertEquals(-2650856935.66554, x *= (1885448157));
+ assertEquals(1326259953.26931, x *= (((x>>(x|(-496195134.78045774)))+((2029515886)%(tmp = 1148955580, tmp)))/(tmp = -1760016519, tmp)));
+ assertEquals(0, x &= (((((-273334205)+(tmp = 797224093.682485, tmp))/x)>>>((((tmp = -887577414, tmp)/x)+x)%(tmp = 720417467, tmp)))^(((x-(tmp = -309071035, tmp))>>(-3123114729.33889))/x)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x %= ((tmp = -2243857462, tmp)/((((((2642220700.6673346)&x)*(tmp = 1454878837, tmp))|((-25825087.30002737)%(851535616.3479034)))<<(tmp = -697581582, tmp))%(tmp = 2248990486, tmp))));
+ assertEquals(0, x >>= (((x|(((tmp = -220437911, tmp)&((((255690498)*(((2993252642)>>>(tmp = 300426048.0338713, tmp))>>x))&((-364232989)+(x<<(-1824069275))))%(x+(tmp = 2696406059.026349, tmp))))+((tmp = 2911683270, tmp)/(tmp = 2718991915, tmp))))*(x/(((tmp = -982851060.0744538, tmp)^((-2903383954)<<((-85365803.80553412)^x)))%(1489258330.5730634))))>>>x));
+ assertEquals(0.7805921633088815, x += (((-1886920875)/(-2417294156.5304217))%(tmp = -1176793645.8923106, tmp)));
+ assertEquals(0, x <<= x);
+ assertEquals(-2215008905, x -= (2215008905));
+ assertEquals(1931542900, x &= (-215923724.72133207));
+ assertEquals(907191462, x ^= (-3133954606.357727));
+ assertEquals(453595731, x >>>= (((tmp = 2726241550, tmp)/(tmp = -332682163, tmp))*((((tmp = 2500467531, tmp)>>>(((x<<(tmp = -1847200310.4863105, tmp))/x)^x))+x)<<(191688342.22953415))));
+ assertEquals(-0.21671182880645923, x /= ((((-1169180683.1316955)%x)>>>(1650525418))^((2198033206.797462)&((-6913973.910871983)%(1758398541.8440342)))));
+ assertEquals(-375102237.1603561, x += (tmp = -375102236.9436443, tmp));
+ assertEquals(1, x &= (((84374105.89811504)|((tmp = -2480295008.926951, tmp)>>((605043461)>>(tmp = -2495122811, tmp))))>>(-2129266088)));
+ assertEquals(1, x |= x);
+ assertEquals(0.0000024171579540208214, x /= (((-2600416098)>>(-2076954196))^x));
+ assertEquals(0.0000024171579540208214, x %= (tmp = -2632420148.815531, tmp));
+ assertEquals(1809220936.0126908, x -= (-1809220936.0126884));
+ assertEquals(1682452118.2686126, x += (((2358977542)<<(x/(tmp = -2862107929, tmp)))+(x+(x%((-3101674407)/(((x*((x>>(tmp = 630458691.3736696, tmp))>>>(tmp = -852137742, tmp)))/x)-((-1875892391.1022017)&(tmp = -1027359748.9533749, tmp))))))));
+ assertEquals(1682452118, x <<= (((tmp = -80832958.07816291, tmp)>>x)%(x-((x^(x<<(tmp = -156565345, tmp)))|((tmp = -1208807363.727137, tmp)/(tmp = 2614737513.304538, tmp))))));
+ assertEquals(6572078, x >>= (-1573364824));
+ assertEquals(13144156, x += x);
+ assertEquals(1731678184, x ^= ((tmp = 593370804.9985657, tmp)|(-3124896848.53273)));
+ assertEquals(845545, x >>>= (tmp = -605637621.2299933, tmp));
+ assertEquals(-1383361088, x ^= (tmp = -1383632087, tmp));
+ assertEquals(-82545896480031520, x += ((x+(1023183845.7316296))*((((tmp = 576673669, tmp)>>(((-584800080.1625061)/(2388147521.9174623))+((((x>>>(-905032341.5830328))^(tmp = -2170356357, tmp))-x)+((136459319)+(-1799824119.689473)))))|x)&(tmp = -2688743506.0257063, tmp))));
+ assertEquals(-895206176, x |= x);
+ assertEquals(-0, x %= x);
+ assertEquals(1791306023, x ^= ((tmp = -3219480856, tmp)+(tmp = 715819582.0181161, tmp)));
+ assertEquals(1791306023, x &= x);
+ assertEquals(2725167636753240600, x *= (1521330025));
+ assertEquals(-281190679, x |= (tmp = -1422045975.798171, tmp));
+ assertEquals(-281190679, x += (x%x));
+ assertEquals(-2342097426.906673, x -= (tmp = 2060906747.906673, tmp));
+ assertEquals(-4651462701.906673, x -= (2309365275));
+ assertEquals(1878, x >>>= (2544974549.345834));
+ assertEquals(1964, x += (x&((1067649861)>>(182139255.7513579))));
+ assertEquals(2209, x += (x>>(tmp = -1775039165, tmp)));
+ assertEquals(0, x -= x);
+ assertEquals(-0, x /= (tmp = -1634697185, tmp));
+ assertEquals(NaN, x /= x);
+ assertEquals(0, x >>>= ((tmp = 3075747652, tmp)&(tmp = 819236484, tmp)));
+ assertEquals(0, x /= ((1276203810.476657)%(-2434960500.784484)));
+ assertEquals(0, x >>>= (tmp = -503633649, tmp));
+ assertEquals(-982731931, x |= (-982731931));
+ assertEquals(-1965463862, x += x);
+ assertEquals(-0.221469672913716, x %= ((tmp = -1742292120, tmp)/x));
+ assertEquals(-0.221469672913716, x %= (-2021391941.1839576));
+ assertEquals(0, x <<= (((((tmp = -2802447851, tmp)>>((2534456072.6518855)&x))%(tmp = 2841162496.610816, tmp))<<((89341820)/(2565367990.0552235)))>>(tmp = 2700250984.4830647, tmp)));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x >>= ((tmp = -636189745, tmp)>>>(x/(((tmp = 2634252476, tmp)%(2026595795))>>(tmp = -2048078394.743723, tmp)))));
+ assertEquals(NaN, x %= ((x%((((x%((tmp = -2583207106, tmp)&x))|(190357769))<<(tmp = 595856931.2599536, tmp))%x))*((-2433186614.6715775)<<((2856869562.1088696)^(tmp = 1112328003, tmp)))));
+ assertEquals(1621713910, x |= (tmp = 1621713910.0282416, tmp));
+ assertEquals(3243427820, x += x);
+ assertEquals(0, x *= (x&(x-x)));
+ assertEquals(0, x >>>= (((2871235439)<<((x+((tmp = -1319445828.9659343, tmp)+(tmp = 1595655077.959171, tmp)))>>(tmp = -86333903, tmp)))-(x/(2907174373.268768))));
+ assertEquals(0, x >>= (-1091774077.2173789));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x *= (tmp = 1976023677.7015994, tmp));
+ assertEquals(NaN, x -= (-3013707698));
+ assertEquals(NaN, x += ((x+(((tmp = -3119865782.9691515, tmp)<<(1327383504.0158405))^(((-143382411.7239611)>>>((-2157016781)+(((-335815848)/x)<<(tmp = 1953515427, tmp))))&(-2715729178))))/(413738158.2334299)));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x += (-845480493));
+ assertEquals(-789816013, x |= (tmp = -789816013.129916, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x <<= (3032573320));
+ assertEquals(47630, x ^= ((1086705488)%((x^(tmp = -1610832418, tmp))>>>(tmp = 1136352558, tmp))));
+ assertEquals(47630, x >>= (tmp = 1035320352.4269229, tmp));
+ assertEquals(47630, x >>= ((((x^x)<<(x*((((x&((-1657468419)*((tmp = -674435523, tmp)&((tmp = 2992300334, tmp)|x))))*((tmp = -489509378.31950426, tmp)*(tmp = 2276316053, tmp)))>>>x)<<x)))%(tmp = -1209988989, tmp))/(tmp = -2080515253.3541622, tmp)));
+ assertEquals(3192518951.8129544, x += (3192471321.8129544));
+ assertEquals(648116457.8129544, x %= (-2544402494));
+ assertEquals(0, x -= x);
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x /= x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x >>= x);
+ assertEquals(0, x *= (tmp = 30051865, tmp));
+ assertEquals(0, x ^= ((x&(((x&x)>>>(((((((x+(2319551861.0414495))>>>(tmp = -3099624461, tmp))^((((tmp = 1574312763, tmp)|x)>>>((-2723797246)&(tmp = -1993956152, tmp)))|(-1830179045)))|(((((((-2545698704.3662167)>>>x)-(((-79478653)|x)%(x+(x>>((tmp = 2386405508.2180576, tmp)/x)))))>>((((-1947911815.2808042)*((x+(368522081.2884482))-(tmp = 2452991210, tmp)))>>(343556643.1123545))>>((((tmp = 1869261547.537739, tmp)>>(3193214755))|x)&(x*(2027025120)))))<<((-1149196187)>>>(814378291.8374172)))+((((((((-160721403)/(2079201480.2186408))+((x|((((tmp = -299595483.16805863, tmp)>>>((x|((x+x)/(-2359032023.9366207)))<<(tmp = -3095108545, tmp)))>>((tmp = -1547963617.9087071, tmp)*(x>>x)))&((tmp = -1568186648.7499216, tmp)+(((2646528453)^(-2004832723.0506048))>>>(tmp = -3188715603.921877, tmp)))))+(tmp = 1578824724, tmp)))^x)^x)/(tmp = -985331362, tmp))|(tmp = 445135036, tmp))<<(tmp = -73386074.43413758, tmp)))+(((-1674995105.9837937)-(tmp = 1392915573, tmp))>>x)))%(tmp = 1215953864, tmp))&((tmp = -439264643.5238693, tmp)>>>x))+(((tmp = 2311895902, tmp)|(1604405793.6399229))&(tmp = -565192829, tmp))))-x))>>(-2455985321)));
+ assertEquals(0, x %= ((1177798817)>>(tmp = 2081394163.5420477, tmp)));
+ assertEquals(0, x >>>= ((x^(tmp = -41947528.33954811, tmp))>>(x>>>((tmp = 1367644771, tmp)+x))));
+ assertEquals(0, x %= ((x+((tmp = 163275724, tmp)<<((tmp = -514460883.3040788, tmp)+x)))|(tmp = -287112073.2482593, tmp)));
+ assertEquals(0, x &= (3067975906));
+ assertEquals(201342051, x |= (tmp = 201342051, tmp));
+ assertEquals(0, x %= (((((-2580351108.8990865)<<(tmp = 2675329316, tmp))&((1338398946)%((-1548041558)+((x>>(-1568233868.7366815))|((x>>((tmp = -1064582207, tmp)/(-1062237014)))>>(tmp = 854123209, tmp))))))<<(((989032887)*(1842748656))%(tmp = -1566983130, tmp)))-x));
+ assertEquals(-0, x /= (tmp = -828519512.617768, tmp));
+ assertEquals(0, x &= ((((1449608518)+(-1829731972))*(1828894311))*(((tmp = -1121326205.614264, tmp)^(-2057547855))<<(tmp = -2758835896, tmp))));
+ assertEquals(NaN, x %= ((tmp = -2138671333, tmp)%x));
+ assertEquals(0, x &= x);
+ assertEquals(665568613.0328879, x += (665568613.0328879));
+ assertEquals(317, x >>= (2627267349.735873));
+ assertEquals(0, x -= x);
+ assertEquals(0, x &= (((tmp = 3030611035, tmp)*(((tmp = 476143340.933007, tmp)>>(x-(2238302130.2331467)))|(x|x)))%(tmp = 320526262, tmp)));
+ assertEquals(0, x <<= (tmp = 729401206, tmp));
+ assertEquals(0, x >>>= (1721412276));
+ assertEquals(217629949.3530736, x += ((tmp = 217629949.3530736, tmp)%((-931931100.601475)%(x^(tmp = -2149340123.548764, tmp)))));
+ assertEquals(217629949.3530736, x %= (tmp = 2275384959.4243402, tmp));
+ assertEquals(0, x >>>= (1112677437.5524077));
+ assertEquals(0, x *= (500256656.7476063));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x -= x);
+ assertEquals(0, x -= x);
+ assertEquals(0, x &= (-1076968794));
+ assertEquals(0, x /= (tmp = 1774420931.0082943, tmp));
+ assertEquals(0, x |= x);
+ assertEquals(0, x >>= x);
+ assertEquals(0, x %= (-2978890122.943079));
+ assertEquals(-0, x /= (tmp = -2954608787, tmp));
+ assertEquals(-800048201, x ^= ((tmp = -800048201.7227018, tmp)>>>((-2016227566.1480863)/(tmp = -2263395521, tmp))));
+ assertEquals(3333, x >>>= (-2038839052));
+ assertEquals(487957736.625432, x += (487954403.625432));
+ assertEquals(-1650983426, x |= (2643918270));
+ assertEquals(-1861867448, x &= (tmp = -251254199.12813115, tmp));
+ assertEquals(-7.934314690172143e-18, x %= ((((x^(-703896560.6519544))>>(tmp = -1853262409, tmp))/(tmp = -1168012152.177894, tmp))/(tmp = 837616075.1097361, tmp)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x &= (tmp = -2328150260.5399947, tmp));
+ assertEquals(-1954860020, x |= (tmp = 2340107276, tmp));
+ assertEquals(-1954860020, x >>= ((tmp = 159177341, tmp)*(x&(-705832619))));
+ assertEquals(-1954895727, x -= (x>>>((-1443742544.7183702)^((((tmp = 869581714.0137681, tmp)+x)^((x%(tmp = -1036566362.5189383, tmp))^(x%x)))>>x))));
+ assertEquals(1.0241361338078498, x /= (tmp = -1908824093.2692068, tmp));
+ assertEquals(16777216, x <<= (x*(((-1925197281)^(tmp = -1392300089.4750946, tmp))|x)));
+ assertEquals(-225882765524992, x *= (tmp = -13463662, tmp));
+ assertEquals(-1845493760, x |= x);
+ assertEquals(-1845493760, x %= (tmp = 3181618519.786825, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(NaN, x /= (x>>>x));
+ assertEquals(NaN, x %= (((((tmp = -521176477, tmp)>>(((tmp = 370693623, tmp)/(((tmp = -1181033022.4136918, tmp)>>(x|(x*(2601660441))))+(tmp = -1696992780, tmp)))|(x|(-1197454193.198036))))>>>(((2512453418.3855605)+((((((tmp = 799501914, tmp)&(((1788580469.7069902)*(((((1476778529.5109258)<<(tmp = -1873387738.3541565, tmp))-((tmp = -521988584.7945764, tmp)*(-1598785351.3914914)))&(-1899161721.8061454))&((x/x)*(690506460))))>>>((tmp = 2255896398.840741, tmp)>>((tmp = -1331486014.6180065, tmp)+(-1159698058.534132)))))*((1112115365.2633948)&((x>>((x>>(-784426389.4693215))&(-492064338.97227573)))>>x)))^((x-((tmp = 2986028023, tmp)>>(tmp = 2347380320.00517, tmp)))*(tmp = -1463851121, tmp)))*(tmp = -1059437133, tmp))%(x-(tmp = 1238739493.7636225, tmp))))^(2029235174)))*(-1923899530))>>>x));
+ assertEquals(0, x >>>= (2848792983.510682));
+ assertEquals(0, x >>= (((tmp = 3042817032.705198, tmp)>>>x)&((((tmp = -829389221, tmp)-((2669682285.8576303)+(tmp = 1812236814.3082042, tmp)))^x)%((tmp = -2401726554, tmp)^((tmp = 2464685683, tmp)|(-2685039620.224061))))));
+ assertEquals(2069649722, x |= (2069649722.311271));
+ assertEquals(NaN, x %= (((((-68757739.39282179)&(-1382816369))/(3122326124))<<(x-(-507995800.3369653)))<<(((-1962768567.343907)+((tmp = 1357057125, tmp)/x))^(tmp = 1997617124, tmp))));
+ assertEquals(NaN, x += x);
+ assertEquals(0, x >>= (26895919));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x %= (tmp = 1092448030, tmp));
+ assertEquals(0, x <<= (tmp = -477672441.46258235, tmp));
+ assertEquals(0, x /= (2113701907));
+ assertEquals(0, x >>>= x);
+ assertEquals(NaN, x /= x);
+ assertEquals(1341078673, x |= (-2953888623));
+ assertEquals(1341078673, x &= x);
+ assertEquals(0, x %= x);
+ assertEquals(414817852.151006, x -= (-414817852.151006));
+ assertEquals(1006632960, x <<= ((((((126465614.8316778)+(x-(2511803375)))+(tmp = 1620717148.352402, tmp))*x)/(tmp = -3013745105.5275207, tmp))-((tmp = -418034061.6865432, tmp)/(-300492911))));
+ assertEquals(1055624813, x |= (tmp = 921407085, tmp));
+ assertEquals(-3, x |= ((((tmp = 1382397819.7507677, tmp)+(tmp = -111851147.7289567, tmp))+x)/((tmp = 247980405.7238742, tmp)^(tmp = -592156399.8577058, tmp))));
+ assertEquals(35161, x &= (((((((-2973570544.725141)*(tmp = -1244715638, tmp))+x)<<(x/((x>>>(-2143371615.073137))/(226072236))))%((x-(tmp = 1971392936, tmp))^(tmp = 2653103658, tmp)))%((tmp = 2828319571.7066674, tmp)>>((1528970502)^((tmp = -55869558, tmp)%x))))>>(889380585.6738582)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x *= (2749718750));
+ assertEquals(0, x >>>= ((((-1633495402.6252813)*(tmp = 2943656739.1108646, tmp))+(tmp = 977432165, tmp))&((tmp = -2338132019, tmp)*(408176349.8061733))));
+ assertEquals(-1778794752, x -= (((tmp = -1391412154.5199084, tmp)-((-3172342474)|x))&(1854366052)));
+ assertEquals(-1778794752, x %= (tmp = 2024807296.6901965, tmp));
+ assertEquals(-1114410.466337204, x %= ((tmp = -240344444.24487805, tmp)%(-47661164)));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x >>= (x>>x));
+ assertEquals(0, x *= x);
+ assertEquals(0, x /= ((-3134902611)|(tmp = -3131158951, tmp)));
+ assertEquals(-0, x /= (((tmp = 1430247610.634234, tmp)&x)+((tmp = -2047191110.8623483, tmp)-((((x%((((x/(tmp = -2599234213, tmp))|(tmp = 2650380060, tmp))|x)+x))>>>x)&(-1961373866))<<x))));
+ assertEquals(-718394682, x -= ((x|(tmp = 1764417670.8577194, tmp))%(1046022988)));
+ assertEquals(3576572614, x >>>= (((tmp = 2480472883.078992, tmp)<<x)>>((2035208402.8039393)&(tmp = 492980449, tmp))));
+ assertEquals(434034142, x %= (x&((x>>>(311110449.48751545))|(-243530647))));
+ assertEquals(524703439.3065736, x += (((tmp = 1392771723.3065736, tmp)%(x&x))%(tmp = -2199704930, tmp)));
+ assertEquals(373686272, x &= (x<<((tmp = 2103372351.9456532, tmp)%(tmp = -1367109519, tmp))));
+ assertEquals(373686272, x >>= x);
+ assertEquals(-0.12245430020241108, x /= (tmp = -3051638622.5907507, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(1, x %= (3095983855));
+ assertEquals(-1454736871, x ^= (x*(tmp = -1454736872, tmp)));
+ assertEquals(-1454736866, x ^= (((724989405.7338341)|(tmp = -2834298786.384371, tmp))>>>(tmp = -2029602148.1758833, tmp)));
+ assertEquals(-1454736866, x &= x);
+ assertEquals(-197394432, x <<= (tmp = -1562128975, tmp));
+ assertEquals(251658240, x <<= (tmp = 2126510950, tmp));
+ assertEquals(3295700610.703306, x -= (tmp = -3044042370.703306, tmp));
+ assertEquals(-51152917, x |= ((949179883.1784958)|(((tmp = -2046168220, tmp)>>(x/x))/(((835064313)*(tmp = 2197600689, tmp))^(((tmp = 2717104216, tmp)&x)<<(-1402661995.3845913))))));
+ assertEquals(-1549204421, x ^= ((((tmp = -481013711, tmp)>>>((tmp = 119589341.80209589, tmp)%(-995489985.2905662)))-(635717011))^(x+(x*x))));
+ assertEquals(-1078356672.3999934, x += (470847748.6000067));
+ assertEquals(1484987268.4638166, x += (tmp = 2563343940.86381, tmp));
+ assertEquals(277020804, x &= (tmp = 2532819117, tmp));
+ assertEquals(-2097118208, x <<= (x>>>x));
+ assertEquals(-2147483648, x <<= (tmp = 761285045, tmp));
+ assertEquals(2147483648, x >>>= x);
+ assertEquals(-935909870282997800, x *= ((-2583300643)|x));
+ assertEquals(-370753566.54721737, x %= (-1084543510.4524941));
+ assertEquals(-177, x >>= (-946264747.6588805));
+ assertEquals(-416077682, x ^= (tmp = 416077761, tmp));
+ assertEquals(NaN, x %= ((((tmp = 779607408, tmp)*(((tmp = -3007128117, tmp)*(851442866.6153773))+x))&(1283388806))/(-876363553)));
+ assertEquals(NaN, x %= (x/(tmp = -1668413939.652408, tmp)));
+ assertEquals(-1726405921, x ^= (tmp = -1726405921, tmp));
+ assertEquals(-1, x >>= ((3031008213.807012)>>x));
+ assertEquals(4294967295, x >>>= ((x>>>x)&(tmp = 2788082290, tmp)));
+ assertEquals(8544111670008449000, x *= (tmp = 1989331020.0417833, tmp));
+ assertEquals(268435456, x <<= (tmp = 3121736017.2098465, tmp));
+ assertEquals(-2.1011176170964474e+26, x -= (((tmp = 1392503299, tmp)*(tmp = 1446108825.1572113, tmp))*(x^(tmp = 372776014.213725, tmp))));
+ assertEquals(0, x |= x);
+ assertEquals(0, x >>= ((-112413907.70074797)*(-702798603)));
+ assertEquals(1829518838, x |= (tmp = -2465448458, tmp));
+ assertEquals(57172463, x >>= ((tmp = 2979642955.241792, tmp)%(tmp = -2464398693.291434, tmp)));
+ assertEquals(114344926, x += x);
+ assertEquals(113279134, x &= (2397742238.6877637));
+ assertEquals(54, x >>= (1908522709.6377516));
+ assertEquals(-2.966982919573829e-7, x /= (tmp = -182003070, tmp));
+ assertEquals(0, x <<= (-1078417156));
+ assertEquals(-147831390, x ^= (((-147831390)>>>x)+x));
+ assertEquals(0, x -= x);
+ assertEquals(-242221450.44696307, x -= (tmp = 242221450.44696307, tmp));
+ assertEquals(-484442900, x <<= (((tmp = -2033947265.088614, tmp)&x)/(x^(tmp = -2893953848, tmp))));
+ assertEquals(-3227648, x <<= (x<<((tmp = -193993010, tmp)*((983187830)|(3146465242.2783365)))));
+ assertEquals(-6455296, x += x);
+ assertEquals(-1771542585, x -= (x^(tmp = -1767335879, tmp)));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x >>>= ((((tmp = -1612864670.4532743, tmp)*(tmp = 786265765.210487, tmp))*((((tmp = -893735877.3250401, tmp)*((x^(tmp = -2804782464.233885, tmp))<<x))&(x-x))^x))<<x));
+ assertEquals(0, x -= (x>>>(-1648118674.380736)));
+ assertEquals(0, x >>= ((tmp = -2706058813.0028524, tmp)>>(2745047169)));
+ assertEquals(0, x += x);
+ assertEquals(0, x %= (-898267735.137356));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x >>= ((265527509)/((tmp = 2190845136.7048635, tmp)+((x>>x)>>>((x%(x-x))&((((-2080184609.8989801)&((-327231633)>>>((tmp = 864849136, tmp)%(((-524363239)*(((((tmp = 2245852565.3713694, tmp)&(1918365.8978698254))>>>(tmp = -2463081769, tmp))-(((2438244059.471446)|((((-135303645.38470244)*(-861663832.2253196))%(tmp = 1273185196.0261836, tmp))|((2261539338.832875)%((320267076.2363237)+x))))>>(tmp = -2731398821, tmp)))/(tmp = -1947938611, tmp)))^x))))>>(tmp = 833666235, tmp))|x))))));
+ assertEquals(-1116704570, x ^= (-1116704570));
+ assertEquals(1379561710, x ^= (tmp = -280362968.19654894, tmp));
+ assertEquals(-1673822208, x <<= x);
+ assertEquals(-1673822208, x |= (x<<(tmp = 1389479193.9038138, tmp)));
+ assertEquals(2559712, x >>>= (-2703763734.0354066));
+ assertEquals(2593499, x ^= (x>>>((tmp = 148668150.03291285, tmp)^(tmp = -1580360304, tmp))));
+ assertEquals(2070393855, x |= (tmp = -2227002907, tmp));
+ assertEquals(304197770, x &= (tmp = 2453257354, tmp));
+ assertEquals(304197770, x <<= ((-669331453.8814087)-(x^(x^(tmp = 33804899.98928583, tmp)))));
+ assertEquals(297068, x >>= x);
+ assertEquals(Infinity, x /= (x-x));
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x ^= x);
+ assertEquals(0, x %= ((tmp = 1723087085, tmp)%(2859382131.304421)));
+ assertEquals(0, x %= (((tmp = 2935439763, tmp)<<(-3163992768.637094))%(tmp = 67176733, tmp)));
+ assertEquals(0, x &= (tmp = 2480771277, tmp));
+ assertEquals(0, x >>>= (x+(tmp = -3168690063, tmp)));
+ assertEquals(0, x *= ((tmp = -1915275449.1806245, tmp)>>>((tmp = -1644482094.1822858, tmp)/(tmp = -432927173, tmp))));
+ assertEquals(0, x += (((2766509428.071809)/(x/((942453848.5423365)/(((tmp = -1284574492, tmp)&((tmp = 760186450.7301528, tmp)-(2464974117.358138)))/((x/(x|(672536969)))*(x>>(-1272232579)))))))>>(x*(-3175565978))));
+ assertEquals(-1277710521, x -= (1277710521));
+ assertEquals(-1277710521, x >>= (((tmp = -2349135858, tmp)-x)-x));
+ assertEquals(-1277710521, x >>= ((tmp = 2135645051, tmp)*(tmp = -2468555366, tmp)));
+ assertEquals(-155971, x >>= (-1294859507));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x >>>= (((861078292.6597499)|(-268063679))-(((((-221864206.9494424)-(-3186868203.2201176))&(tmp = 1287132927, tmp))<<(((tmp = 1964887915, tmp)<<((25908382)^(tmp = -688293519.875164, tmp)))*(2075946055)))&(x-((x>>x)&(1395338223.7954774))))));
+ assertEquals(788002218, x -= (-788002218));
+ assertEquals(716399906, x &= (-1145868506));
+ assertEquals(145776674, x &= (-1661931477.360386));
+ assertEquals(145776674, x |= x);
+ assertEquals(-0.05255700469257692, x /= (tmp = -2773686873, tmp));
+ assertEquals(-660918434, x |= (-660918434.2915542));
+ assertEquals(1223537346, x ^= (tmp = -1871274596, tmp));
+ assertEquals(305884336, x >>= (x&x));
+ assertEquals(-1.1123775647978218e-8, x *= ((tmp = -793393031.4229445, tmp)/((tmp = -503919284, tmp)*(((((tmp = 429810625, tmp)>>>x)-((2091544148.870375)<<(((((x^x)%x)|x)/(-260773261))<<((tmp = -1323834653, tmp)&x))))*((-1231800099.3724015)+x))*((x+((-559726167)^x))>>>((-549148877)<<((((tmp = 1196115201, tmp)/((tmp = -2654658968.390111, tmp)%(tmp = -1044419580, tmp)))*(((((x>>>(733571228))+(2919762692.511447))/(-2718451983.570547))^x)+((2891533060.1804514)^((tmp = -2514488663, tmp)&x))))<<(tmp = -2526139641.6733007, tmp))))))));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x *= x);
+ assertEquals(0, x |= x);
+ assertEquals(3076984066.336236, x -= ((tmp = -3076984066.336236, tmp)+((tmp = -446575828.5155368, tmp)&x)));
+ assertEquals(1, x /= x);
+ assertEquals(1513281647.839972, x *= (1513281647.839972));
+ assertEquals(1251138155, x ^= ((tmp = 2124481052, tmp)&(2431937351.4392214)));
+ assertEquals(1, x /= x);
+ assertEquals(0, x &= (tmp = 627050040, tmp));
+ assertEquals(497153016, x ^= (497153016));
+ assertEquals(-1112801283, x |= (tmp = 2752196557, tmp));
+ assertEquals(0.5735447276296568, x /= ((((tmp = -500878794, tmp)%(tmp = -2559962372.2930336, tmp))%(2661010102))+(tmp = -1439338297, tmp)));
+ assertEquals(1.0244795995097235e-9, x /= (559840067));
+ assertEquals(0.43468811912309857, x *= (424301391));
+ assertEquals(-1972757928, x ^= (tmp = -1972757928.9227014, tmp));
+ assertEquals(-606757265, x ^= (tmp = -2923461577.264596, tmp));
+ assertEquals(-37, x >>= (((-2736561559.7474318)%(tmp = -27668972.662741184, tmp))*(2774711606)));
+ assertEquals(-1923785671, x += ((-1923785597)+x));
+ assertEquals(-3877639176, x += (tmp = -1953853505, tmp));
+ assertEquals(-4688259242, x -= ((810620066.4394455)>>(((-1474285107.459875)>>x)/(((((-570672326.4007359)>>(tmp = -3086802075, tmp))%x)>>>(((tmp = 286938819.28193486, tmp)>>>((1712478502)>>(tmp = 3045149117.796816, tmp)))<<(tmp = 750463263.292952, tmp)))&(tmp = 2055350255.5669963, tmp)))));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x <<= (1037856162.5105649));
+ assertEquals(0, x *= x);
+ assertEquals(0, x &= (997845077.4917375));
+ assertEquals(0, x *= x);
+ assertEquals(0, x *= x);
+ assertEquals(0, x <<= (((x<<x)&(57691805))>>(786927663)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x += x);
+ assertEquals(0, x &= (-2131910624.1429484));
+ assertEquals(0, x >>>= (-43787814));
+ assertEquals(-2415062021, x += (tmp = -2415062021, tmp));
+ assertEquals(-4830124042, x += x);
+ assertEquals(-186683401, x |= (tmp = 1960135383, tmp));
+ assertEquals(NaN, x *= ((tmp = -1674740173.9864025, tmp)%(((((((-432895485.7261934)-x)^x)>>>(((-1627743078.3383338)>>(179992151))<<((tmp = 911484278.0555259, tmp)|(((tmp = -3042492703, tmp)>>(((-663866035.302746)>>(((x-((440661929.50030375)>>>(tmp = 263692082, tmp)))*x)+x))/((1546004407)^(((tmp = 2023662889.1594632, tmp)*(tmp = -2456602312, tmp))+(tmp = 755602286.1810379, tmp)))))%((tmp = -336449961, tmp)|(tmp = 206780145, tmp))))))/(1068005219.1508512))<<(tmp = -474008862.6864624, tmp))/(((((((1518711056.5437899)>>>(tmp = 287418286.63085747, tmp))<<(tmp = 2823048707, tmp))^(((x<<(x^(-1600970311)))&(x>>(((tmp = 157300110.7636031, tmp)*(tmp = -3047000529, tmp))&(1743024951.3535223))))>>x))-(tmp = -2895435807, tmp))*((tmp = -314120704, tmp)&(tmp = 1759205369, tmp)))>>(tmp = 1833555960.046526, tmp)))));
+ assertEquals(NaN, x -= (tmp = 694955369, tmp));
+ assertEquals(NaN, x *= (x%x));
+ assertEquals(0, x |= x);
+ assertEquals(0, x ^= x);
+ assertEquals(0, x &= x);
+ assertEquals(NaN, x /= (x+x));
+ assertEquals(NaN, x %= ((tmp = -1595988845, tmp)*((1754043345)>>>(-601631332))));
+ assertEquals(0, x >>>= (tmp = 862768754.5445609, tmp));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x *= (tmp = -1774545519, tmp));
+ assertEquals(0, x >>>= (tmp = -2492937784, tmp));
+ assertEquals(0, x %= ((((x<<(-1657262788.2028513))&((x^(tmp = -671811451, tmp))<<(-2984124996)))^(1455422699.7504625))-((-340550620)>>x)));
+ assertEquals(918278025, x ^= ((tmp = -918278027, tmp)^((tmp = 2889422870, tmp)/(tmp = -657306935.7725658, tmp))));
+ assertEquals(918278025, x %= (2603186571.0582614));
+ assertEquals(107034679.32509923, x %= (tmp = -811243345.6749008, tmp));
+ assertEquals(53517339, x >>= (x%((((x*((tmp = -983766424, tmp)^(-1881545357.8686862)))|(tmp = -1429937087, tmp))>>((x<<x)>>((((tmp = -2347470476, tmp)&x)+((x&x)<<(396061331.6476157)))*(tmp = -3136296453.209073, tmp))))>>>(((tmp = 908427836, tmp)|(tmp = 207737064, tmp))|(((1253036041)-(tmp = 2705074182, tmp))+(-431215157.82083917))))));
+ assertEquals(53477378, x &= ((((-1128036654.165636)*x)+x)>>(x>>(3080099059))));
+ assertEquals(0, x >>= (-590692293));
+ assertEquals(0, x %= (-2395850570.9700127));
+ assertEquals(0, x *= ((tmp = 1377485272, tmp)&(1129370608)));
+ assertEquals(0, x += (x>>>(x%(((((tmp = -1746827236, tmp)+((tmp = -326913490, tmp)&((-58256967)&x)))*(tmp = -1176487022.001651, tmp))>>>(-2089147643))-x))));
+ assertEquals(0, x <<= (tmp = 1073298160.2914447, tmp));
+ assertEquals(-837811832, x ^= (-837811832));
+ assertEquals(102760448, x <<= (tmp = 2833582450.4544373, tmp));
+ assertEquals(0, x &= (((((((tmp = 2595641175, tmp)*x)+(tmp = -2049260172.1025927, tmp))%((2986747823)>>(tmp = -2120598518, tmp)))&((tmp = -2742408622, tmp)&x))>>x)*((1043474247.9601482)&(tmp = 1686365779.9885998, tmp))));
+ assertEquals(0, x >>= ((tmp = 1717862848, tmp)-(tmp = 1077024446.4160957, tmp)));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x /= (-1669429787.975099));
+ assertEquals(NaN, x -= (-2299895633.4807186));
+ assertEquals(138173970, x ^= (138173970.56627905));
+ assertEquals(-2084183776, x <<= (3073345316));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x >>= (-3080556066.068573));
+ assertEquals(0, x &= ((tmp = -2587514820, tmp)*(x-((x^(1995672257))*(1125326747.2339358)))));
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x >>= (tmp = 2139186585, tmp));
+ assertEquals(-1904096640, x |= ((-602301360.1919911)*(-1270444810)));
+ assertEquals(1073741824, x <<= (tmp = -1069467849, tmp));
+ assertEquals(1073741824, x ^= (x-x));
+ assertEquals(536870912, x >>>= (-1579466367.160293));
+ assertEquals(512, x >>= (972402804.3890183));
+ assertEquals(512, x &= (tmp = 2664796831, tmp));
+ assertEquals(16777216, x <<= (-2738292561));
+ assertEquals(0, x >>>= ((((1397663615.3889246)|(1117420260.6730964))-(-1173734560))<<((tmp = 1007006104.0172879, tmp)<<((tmp = -623002097, tmp)%(tmp = -35829654.379403114, tmp)))));
+ assertEquals(1200191544, x ^= (tmp = -3094775752, tmp));
+ assertEquals(71, x >>>= x);
+ assertEquals(71, x |= x);
+ assertEquals(1394763772, x += (1394763701));
+ assertEquals(-1.492717171027427, x /= ((x&(tmp = 1243787435, tmp))-(2043911970.26752)));
+ assertEquals(-1.1002448961224718e-8, x /= ((((835185744)*(((tmp = 2165818437, tmp)^(tmp = 2567417009.1166553, tmp))/x))/x)/(((63485842.39971793)^(2668248282.597389))/x)));
+ assertEquals(0, x <<= (tmp = 1598238578.637568, tmp));
+ assertEquals(0, x |= (x&((tmp = -1812945547.5373957, tmp)>>>x)));
+ assertEquals(0, x >>>= (x+(-1969679729.7299538)));
+ assertEquals(1582033662, x += (tmp = 1582033662, tmp));
+ assertEquals(1, x >>>= x);
+ assertEquals(-550748739, x += ((tmp = -550748740, tmp)/(x&((2537822642.235506)^((-2167656297)%(tmp = 1161201210, tmp))))));
+ assertEquals(-268921, x >>= (tmp = 1916069547.7381654, tmp));
+ assertEquals(-0.00021776939364231114, x /= (tmp = 1234888868, tmp));
+ assertEquals(0, x <<= (-1036375023));
+ assertEquals(0, x &= ((((x/(2398886792.27443))&(x|((-1813057854.1797302)-x)))&(x/(((tmp = 3091133731.4967556, tmp)|(3013139691.823039))<<x)))>>>(2542784636.963599)));
+ assertEquals(0, x += ((x*x)/(tmp = 347079383, tmp)));
+ assertEquals(788347904, x |= ((1462257124.6374629)*((3180592147.4065146)-(x&(1922244678)))));
+ assertEquals(2130672735, x |= (tmp = -2846986145, tmp));
+ assertEquals(-1331327970, x ^= ((656251304)-(tmp = 1489152359, tmp)));
+ assertEquals(-0.14377179742889856, x %= (((2889747597.813753)-(1730428996))/(((tmp = -1378710998, tmp)&x)|x)));
+ assertEquals(-1754612583.143772, x += ((-1754725729)^((-2285838408)>>>(1434074349))));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x &= (tmp = -1031961332, tmp));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x /= (3059476325));
+ assertEquals(NaN, x *= ((x*((((tmp = 13529540.462185979, tmp)&x)^((x<<(-1312696238.1628869))&(-2029766712.3852897)))>>x))/x));
+ assertEquals(1657339940, x ^= ((tmp = -488956817.1491232, tmp)&(tmp = -2352413900.1983714, tmp)));
+ assertEquals(-530683621952432200, x *= (tmp = -320202035.2882054, tmp));
+ assertEquals(229226258, x ^= ((tmp = -1263410990.026416, tmp)+(((-808046349)&(tmp = -1294442506, tmp))&((tmp = 1147437219, tmp)<<((tmp = -820299900, tmp)-(tmp = -1947748943.3443851, tmp))))));
+ assertEquals(7163320, x >>= (-2631307131));
+ assertEquals(-68, x |= (((-1271721343)>>x)%x));
+ assertEquals(-39956523818.38862, x *= (587595938.505715));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>>= ((x^(x+x))<<(tmp = 265212367, tmp)));
+ assertEquals(0, x |= (((x>>((tmp = 2294761023, tmp)/(x>>(2125624288))))&((-2125650113)|(tmp = 1014409884, tmp)))%(tmp = -527324757, tmp)));
+ assertEquals(0, x >>= ((tmp = 2267075595, tmp)*(-1681569641.8304193)));
+ assertEquals(0, x >>>= x);
+ assertEquals(0.5738410949707031, x -= ((tmp = -1846572645.573841, tmp)%((((((x^(((-156613905.64173532)/x)<<x))+((x|((2405109060)>>>x))^x))/(570585894.8542807))+(x&(-2544708558)))^((((tmp = -2539082152.490635, tmp)+((((-657138283)/(2204743293))-((tmp = -1422552246.565012, tmp)+x))<<(x-x)))>>(x/(x>>>(tmp = -3027022305.484394, tmp))))<<x))&((-2066650303.3258202)/(tmp = -1666842593.0050385, tmp)))));
+ assertEquals(0, x >>>= ((((tmp = 2473451837.613817, tmp)>>((2526373359.1434193)>>(x<<x)))+((tmp = -579162065, tmp)+((tmp = -3115798169.551487, tmp)-(tmp = 933004398.9618305, tmp))))&(tmp = 131167062, tmp)));
+ assertEquals(-2067675316, x ^= (-2067675316.6300585));
+ assertEquals(543772, x >>>= x);
+ assertEquals(-1073741824, x <<= x);
+ assertEquals(3221225472, x >>>= ((x*(1478586441.081221))&(tmp = -3050416829.2279186, tmp)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x *= x);
+ assertEquals(-1017771903.0298333, x -= (1017771903.0298333));
+ assertEquals(0.6404112721149928, x /= ((tmp = -144667370, tmp)^(-2849599562)));
+ assertEquals(-2410517638773644000, x -= (((tmp = 1759631550, tmp)*x)*((((tmp = -2949481475, tmp)>>>x)*x)|(tmp = -2977983804, tmp))));
+ assertEquals(-0, x %= (x+((((tmp = -1307866327.7569134, tmp)<<((x&((tmp = -2380043169.8405933, tmp)|x))>>(472992789.7639668)))|(((((x<<(tmp = -1416427232.7298179, tmp))%(-1404989679.409946))*((x/(tmp = -992416608, tmp))/(tmp = 524646495, tmp)))-(tmp = 734405570, tmp))>>x))/(1079256317.7325506))));
+ assertEquals(0, x <<= (tmp = 2459834668, tmp));
+ assertEquals(-0, x /= (tmp = -1892164840.5719755, tmp));
+ assertEquals(0, x >>= (x|(((1299844244)>>>(((tmp = -2422924469.9824634, tmp)|x)-((((1914590293.2194016)+(-3033885853.8243046))-((tmp = -1720088308, tmp)%x))<<(tmp = 2210817619, tmp))))<<x)));
+ assertEquals(0, x <<= (((tmp = 3192483902.841396, tmp)>>>(((x^(2944537154))|(tmp = -1334426566, tmp))*(((((((-2705218389)&x)+(1987320749))+(tmp = -111851605, tmp))|(2894234323))-(265580345))&x)))%(((tmp = 1431928204.6987057, tmp)&(tmp = 914901046, tmp))&(x>>>x))));
+ assertEquals(0, x >>>= (tmp = 1941940941, tmp));
+ assertEquals(0, x %= (3089014384));
+ assertEquals(0, x += ((tmp = 2948646615, tmp)*x));
+ assertEquals(-0, x /= (tmp = -1480146895, tmp));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x %= (-2995257724.158043));
+ assertEquals(NaN, x %= (tmp = 2714835455, tmp));
+ assertEquals(NaN, x /= (tmp = -311440765.98078775, tmp));
+ assertEquals(NaN, x -= (-1600234513.697098));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x <<= (-1499045929));
+ assertEquals(-0, x *= (-2491783113));
+ assertEquals(0, x ^= (x%((x>>(((1234398704.3681123)>>>x)%(x+x)))>>(402257223.4673699))));
+ assertEquals(-643225204, x ^= (((-55960194.698637486)+((((721411198)-(((tmp = 1308676208.7953796, tmp)%(2242904895))-x))>>((((tmp = 332791012, tmp)&((tmp = -2094787948, tmp)/((x/(2427791092))^(2444944499.6414557))))%(((x+(1253986263.5049214))+(((((3135584075.248715)+((tmp = -2569819028.5414333, tmp)%(440908176.1619092)))>>>(x<<((3061615025)-x)))%x)%(x+((2369612016)*((((tmp = 1173615806, tmp)*(-1910894327))&(2428053015.077821))*(-55668334.70082307))))))<<(tmp = -2129259989.0307562, tmp)))+(1579400360)))%((-3053590451.8996153)>>x)))+(x>>(x%(x^((-1772493876)^x))))));
+ assertEquals(413738663060841600, x *= x);
+ assertEquals(1581062538.4501781, x %= ((tmp = -1298397672.0300272, tmp)-((2237197923)+(tmp = -1385478459, tmp))));
+ assertEquals(755644566.8709538, x %= (tmp = -825417971.5792243, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>>= ((89330582)%(-1012731642.4855506)));
+ assertEquals(0, x >>>= x);
+ assertEquals(NaN, x %= ((x>>>((x/(tmp = -1848848941.2352903, tmp))>>>(tmp = -71862893, tmp)))&(-2385996598.2015553)));
+ assertEquals(NaN, x += (-2292484503.318904));
+ assertEquals(NaN, x *= (2961064461));
+ assertEquals(NaN, x += (x<<((2076798243.6442)/((tmp = -81541044.75366282, tmp)^((3041366498.551101)+((2126874365)/(tmp = -177610359, tmp)))))));
+ assertEquals(NaN, x %= ((x/((x/x)+x))>>>x));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x += (1171761980.678));
+ assertEquals(NaN, x += ((2355675823)<<(-390497521)));
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x &= (tmp = -658428225.56619, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x <<= (1643310725.5713737));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x <<= (-397005335.3712895));
+ assertEquals(0, x >>>= (tmp = -2804713458.166788, tmp));
+ assertEquals(0, x <<= (((((((tmp = 1879988501, tmp)%(1528081313.9360204))+(1376936736))*((((x>>>((1736268617.339198)>>>(-2598735297.4277673)))<<((((((((-2742982036)/(231867353.4549594))-(875335564))<<x)|((2241386341.742653)<<((-22024910.828409433)&(x<<x))))*(-756987803.5693252))+x)^(tmp = 1084498737, tmp)))<<(1920373881.8464394))&(2370827451.82652)))&(x^(tmp = -891503574, tmp)))<<x)>>>((-1519588625.2332087)^(483024636.2600144))));
+ assertEquals(52193878.40997505, x -= ((tmp = -341753803.40997505, tmp)%(tmp = -96519975, tmp)));
+ assertEquals(-1665844168.938803, x -= (1718038047.348778));
+ assertEquals(3.6962232549405003e-19, x /= (((((-809583468.5507183)>>>((tmp = 286797763, tmp)%((1579183142.7321532)/(1853824036.001172))))<<x)>>(((x|x)^((tmp = -2641304815, tmp)<<(x<<x)))>>(((((268338128.8300134)&(-1778318362.8509881))*(751081373.346478))<<(((525066612)>>(-1139761212))*(2949167563.299916)))<<x)))+((tmp = 664905121, tmp)*((-2208280205)*(3069462420)))));
+ assertEquals(4710721795.110161, x += (((217604832)+((1307891481.781326)-x))+(tmp = 3185225481.328835, tmp)));
+ assertEquals(0, x %= x);
+ assertEquals(0, x -= (((x>>>(x/(tmp = 46977522.46204984, tmp)))>>(-2466993199.615269))&(tmp = 14524430.287991166, tmp)));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x /= (tmp = 578120637, tmp));
+ assertEquals(-17267104, x -= (((tmp = 1515285919.495792, tmp)+(((tmp = -1364790286.7057304, tmp)+((954599071)>>((897770243.1509961)*x)))^x))>>>(566027942.1732262)));
+ assertEquals(-17267104, x &= x);
+ assertEquals(189138241, x ^= ((tmp = 1565742675.9503145, tmp)-((tmp = 1737806643, tmp)|((x*(tmp = -1382435297.5955122, tmp))*(-2820516692.153056)))));
+ assertEquals(189138241, x %= (x*(tmp = -1670678493, tmp)));
+ assertEquals(1693, x %= ((-2328713314)>>>(1623637325)));
+ assertEquals(1693, x %= ((-1019394014)*(x|x)));
+ assertEquals(3386, x += x);
+ assertEquals(9268970871604, x *= (2737439714));
+ assertEquals(-4720.120483643183, x /= (tmp = -1963714889, tmp));
+ assertEquals(-1, x >>= ((x^(((-2404688047.455056)|((1439590234.6203847)<<(tmp = -2496557617, tmp)))/((x<<((tmp = 1865549512.282249, tmp)/(((360384191.55661833)>>(tmp = -1225297117.344188, tmp))>>>(2703264010.4122753))))*(1521960888.0071676))))%(tmp = 2834001448.0508294, tmp)));
+ assertEquals(63, x >>>= (x&(-3079339174.6490154)));
+ assertEquals(0, x >>>= (1039770956.6196513));
+ assertEquals(0, x >>>= (-1074820214));
+ assertEquals(0, x >>>= (x/x));
+ assertEquals(0, x >>= ((tmp = -449117604.2811785, tmp)&x));
+ assertEquals(-0, x /= (tmp = -118266935.1241343, tmp));
+ assertEquals(2226140134, x += (tmp = 2226140134, tmp));
+ assertEquals(2068827161, x ^= ((tmp = -1950744808.846384, tmp)>>((2258661151)^((tmp = -1118176421.8650177, tmp)<<(2828634014)))));
+ assertEquals(123, x >>>= (-1779624840.0515127));
+ assertEquals(0, x >>>= (x|((tmp = -239082904, tmp)<<(tmp = 1404827607, tmp))));
+ assertEquals(0, x >>>= x);
+ assertEquals(1793109749, x ^= (tmp = -2501857547.710491, tmp));
+ assertEquals(855, x >>>= x);
+ assertEquals(0, x >>>= (-847289833));
+ assertEquals(0, x %= (-2271241045));
+ assertEquals(169648072, x ^= (((tmp = 169648072.66759944, tmp)^x)|x));
+ assertEquals(176025927479164930, x *= ((tmp = 1111997198.8803885, tmp)<<(tmp = 2913623691, tmp)));
+ assertEquals(176025926613281700, x += ((tmp = -865883245, tmp)<<(x+(-2624661650))));
+ assertEquals(3406506912, x >>>= ((x|(tmp = 2436016535, tmp))*(((tmp = -1222337225, tmp)<<((1765930268)&x))*(tmp = 1600702938, tmp))));
+ assertEquals(1.694694170868292, x %= (x/(-1597121830.794548)));
+ assertEquals(0, x >>= (tmp = -2443203089, tmp));
+ assertEquals(0, x >>>= (1323174858.2229874));
+ assertEquals(0, x &= ((tmp = 846556929.2764134, tmp)|(((1483000635.0020065)|(-3151225553))|(tmp = -229028309, tmp))));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x >>= ((((((-2677334787)>>>x)>>((tmp = 496077992, tmp)&((((x<<(x*(tmp = 1095163344.2352686, tmp)))+(-952017952))%((x<<((x*x)/(tmp = 2983152477, tmp)))^((tmp = -939521852.1514642, tmp)^(tmp = 143967625.83755958, tmp))))*((tmp = 551827709.8366535, tmp)>>>x))))^((-1552681253.69869)-(-1874069995)))>>>(x>>(x%(tmp = -2554673215, tmp))))|(tmp = -190693051.77664518, tmp)));
+ assertEquals(0, x /= (tmp = 427402761.37668264, tmp));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x |= (x>>>(((((-543326164.0673618)>>>(-2344090136.707964))>>>((((-563350246.6026886)/x)/(1525481037.3332934))&(tmp = -2917983401.88958, tmp)))^(-1094667845.1208413))^x)));
+ assertEquals(0, x &= (1080322749.897747));
+ assertEquals(0, x %= (tmp = -1572157280, tmp));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x %= ((377280936)|x));
+ assertEquals(708335912, x -= (tmp = -708335912, tmp));
+ assertEquals(2766937, x >>>= x);
+ assertEquals(547342779, x += (tmp = 544575842, tmp));
+ assertEquals(546273751, x -= ((x>>>(472833385.9560914))|((tmp = -1164832103.9970903, tmp)/(3147856452.1699758))));
+ assertEquals(546273751, x &= x);
+ assertEquals(0, x ^= x);
+ assertEquals(0, x >>>= (tmp = -3181805175, tmp));
+ assertEquals(-375546685, x |= (-375546685.08261824));
+ assertEquals(1089992785780217200, x *= (tmp = -2902416209, tmp));
+ assertEquals(0, x %= x);
+ assertEquals(-1854981526, x -= ((x-x)-(-1854981526)));
+ assertEquals(-3709963052, x += x);
+ assertEquals(-316772482, x %= (tmp = -1696595285, tmp));
+ assertEquals(-316772482, x |= x);
+ assertEquals(1, x /= x);
+ assertEquals(0, x -= x);
+ assertEquals(-1418375842, x ^= (-1418375842));
+ assertEquals(-2, x >>= x);
+ assertEquals(-4, x += x);
+ assertEquals(-8388608, x &= (x<<(-350555339.30086184)));
+ assertEquals(-16777216, x += x);
+ assertEquals(-0, x %= x);
+ assertEquals(1083355129, x += (tmp = 1083355129, tmp));
+ assertEquals(0, x &= (((tmp = 389729053, tmp)-(tmp = 2944192190.0939536, tmp))/(x-(2081712461.2657034))));
+ assertEquals(0, x += x);
+ assertEquals(-3, x += ((3147270119.5831738)>>((2455837253.1801558)%((-2100649096)>>(((290236808.01408327)|(x&((2661741230.3235292)|((tmp = 1686874589.4690177, tmp)<<x))))*(x+(tmp = 2327674670, tmp)))))));
+ assertEquals(-3, x %= ((x>>(((-2962686431)%x)>>((((2438370783)-(tmp = 2667305770.4839745, tmp))>>>x)>>>x)))<<((x&(tmp = 1428498616, tmp))|((tmp = 2621728539.102742, tmp)/(-204559901)))));
+ assertEquals(2, x ^= (x|((((tmp = 1751230118.6865973, tmp)/(-867465831.207304))>>((-808143600.0912395)+(-2882191493.0506454)))^x)));
+ assertEquals(2, x %= (-2015954220.2250996));
+ assertEquals(0, x >>>= (tmp = 401373999, tmp));
+ assertEquals(0, x >>= (2371830723));
+ assertEquals(0, x >>>= ((((tmp = 2765919396, tmp)-x)-(530310269.7131671))|(tmp = -615761207.9006102, tmp)));
+ assertEquals(-145389011, x ^= (tmp = -145389011, tmp));
+ assertEquals(-145389011, x |= x);
+ assertEquals(1632929832, x &= (-2518898392));
+ assertEquals(4190540017.751949, x += (tmp = 2557610185.751949, tmp));
+ assertEquals(4980024282.153588, x += ((1841304364.1177452)%(tmp = 1051820099.7161053, tmp)));
+ assertEquals(0, x >>>= (((((1379314342.4233718)>>((-2782805860)^((x%(tmp = 1328845288, tmp))>>>(tmp = 901403219.858733, tmp))))+(x/((tmp = -3078904299, tmp)/x)))/x)|(x|(1399702815))));
+ assertEquals(-1820494882, x ^= (tmp = -1820494882.407127, tmp));
+ assertEquals(-305870376, x %= (tmp = -757312253, tmp));
+ assertEquals(-577530443, x += (x|(tmp = -1958083619.6653333, tmp)));
+ assertEquals(333541412591776260, x *= x);
+ assertEquals(-949341696, x >>= ((((1550069663)<<((x>>>(tmp = 2406565178.902887, tmp))>>>((1844746612.632984)/((tmp = 2233757197, tmp)*((-1524891464.1028347)>>(tmp = 2498623474.5616803, tmp))))))&x)<<(x&(tmp = -370379833.3884752, tmp))));
+ assertEquals(-277202090, x |= ((-762200848.8405354)-(tmp = 1749136282, tmp)));
+ assertEquals(0.13704539927239265, x /= (tmp = -2022702633.373563, tmp));
+ assertEquals(0, x -= x);
+ assertEquals(0, x %= ((132951580.19304836)-((427623236.27544415)-(1212242858))));
+ assertEquals(0, x &= ((449148576)&(-1609588210.249217)));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x -= x);
+ assertEquals(-0, x /= (tmp = -1640777090.9694843, tmp));
+ assertEquals(0, x &= (((tmp = -1923412153, tmp)>>>((x>>(tmp = 3027958119.0651507, tmp))+(60243350)))>>(tmp = -2610106062, tmp)));
+ assertEquals(0, x ^= (((-186998676)/(tmp = 2697937056, tmp))-x));
+ assertEquals(-1147950080, x |= ((2425449461)*(tmp = -2525854833, tmp)));
+ assertEquals(457688198, x ^= (2698274950.660941));
+ assertEquals(8724, x %= ((1174351031)>>>((371599047.36048746)+(3025292010))));
+ assertEquals(0, x <<= (tmp = -710011617, tmp));
+ assertEquals(0, x >>>= (1693410026));
+ assertEquals(1443005362, x ^= ((tmp = -2851961934, tmp)+((((x%x)-(tmp = 547622400, tmp))<<(((tmp = 722396486.5553623, tmp)|x)>>>((((tmp = -542268973.5080287, tmp)<<(tmp = 1347854903.771954, tmp))>>>(tmp = -889664427.7115686, tmp))&((tmp = 1549560114, tmp)*(tmp = 964918035, tmp)))))&(-2422502602.920377))));
+ assertEquals(3986573462, x -= (-2543568100));
+ assertEquals(7973146924, x += x);
+ assertEquals(-1, x >>= (-75987297));
+ assertEquals(-12, x += ((2940824338.64834)>>(tmp = 3061467355, tmp)));
+ assertEquals(-3.8229398525977614e-8, x /= (313894554));
+ assertEquals(-2.890709270374084e-17, x /= (tmp = 1322491989, tmp));
+ assertEquals(0, x |= (x-x));
+ assertEquals(0, x >>>= (tmp = -1205300664, tmp));
+ assertEquals(-0, x /= (((2869505187.6914144)>>(tmp = 1541407065, tmp))/(((-571132581)>>>(x>>x))/((x^(170373762.8793683))>>>((((tmp = -363073421.05897164, tmp)|(((tmp = -1591421637, tmp)>>(1095719702.8838692))&(636687681.9145031)))^x)^(x|x))))));
+ assertEquals(-1487828433, x ^= (-1487828433.3462324));
+ assertEquals(-0, x %= x);
+ assertEquals(1716342498, x -= ((tmp = 2578624798, tmp)^x));
+ assertEquals(1636, x >>= ((264194540)>>>(-801900756)));
+ assertEquals(0, x >>>= ((tmp = 2502688876, tmp)+((x<<(x|((-628272226.0338528)|((x<<(-2083074091))>>>(tmp = 1692123246.8418589, tmp)))))>>(1594759826.990993))));
+ assertEquals(0, x <<= (tmp = -904399643, tmp));
+ assertEquals(NaN, x /= ((x^(x-x))%((tmp = 1744962024.4882128, tmp)%x)));
+ assertEquals(NaN, x /= (-1013142883.1845908));
+ assertEquals(NaN, x /= ((tmp = 793633198, tmp)^(-2993598490.8659954)));
+ assertEquals(0, x &= (x>>((tmp = 1200937851, tmp)<<(((tmp = -2807378465, tmp)&(tmp = -143778237, tmp))|(tmp = -1200772223, tmp)))));
+ assertEquals(0, x <<= x);
+ assertEquals(88144, x |= (((((tmp = 3002723937.8560686, tmp)*(tmp = -3171720774.2612267, tmp))%(((tmp = -2586705978.7271833, tmp)%((x+(-1553704278))&(2405085526.501994)))>>((-240842053)>>>(((((tmp = -1886367228.4794896, tmp)>>>x)^(tmp = 2604098316, tmp))^(tmp = 1362808529, tmp))<<((tmp = -1062263918, tmp)|((-172718753)%(tmp = -1910172365.4882073, tmp)))))))^((1444153362)>>((x&((-1205465523.2604182)^(tmp = -2062463383, tmp)))>>(tmp = 956712476, tmp))))>>((((-1004215312)^((((-1707378612.5424936)^(tmp = 2372161553, tmp))/((tmp = 1802586581, tmp)*((2082257.1896460056)&((tmp = -1270773477, tmp)^(tmp = 942517360.3447798, tmp)))))+x))%((((666494127)^(x^x))>>>(tmp = -2592829775, tmp))+((-1601528223)+((x+(tmp = -2417034771.7409983, tmp))>>>((tmp = -730673817, tmp)*x)))))>>x)));
+ assertEquals(-2603179111.7557006, x -= ((2603267255.755627)+(x/(1200979191.2823262))));
+ assertEquals(1691788185, x >>= (tmp = 3088840032, tmp));
+ assertEquals(-168382533, x |= (tmp = -780750941.4590135, tmp));
+ assertEquals(-168382533, x >>= (60741120.48285198));
+ assertEquals(-134287365, x |= (x*(tmp = 834637940.7151251, tmp)));
+ assertEquals(-1481917089, x -= (tmp = 1347629724, tmp));
+ assertEquals(1, x >>>= x);
+ assertEquals(262144, x <<= (2680216914));
+ assertEquals(1075132032, x ^= (x-((tmp = 3220359552.3398685, tmp)^(((-434474746.6039338)|((((((((tmp = 1945689314.9683735, tmp)>>(1300022273))>>>(333705550))&x)%(588357521))-(x+(x^(((tmp = -134560382, tmp)+x)-((((994246147.7195556)-(-1506599689.7383268))%(x<<x))>>((1256426985.5269494)+(tmp = 1860295952.8232574, tmp)))))))^(((tmp = 917333220.2226384, tmp)>>x)>>>(tmp = 865898066, tmp)))%((x|(x%((tmp = -2660580370, tmp)&(tmp = 2966426022, tmp))))*x)))/(((tmp = 682585452, tmp)&(-3219368609))+((tmp = -1330253964, tmp)+((x&(2857161427))/x)))))));
+ assertEquals(274944, x &= ((2606953028.1319966)-(-1707165702)));
+ assertEquals(266752, x &= ((x<<((x+(x+(x^(-1570175484))))^x))^(x+(x<<(tmp = 90330700.84649956, tmp)))));
+ assertEquals(266752, x &= ((((x*(tmp = 2033225408, tmp))-(x-((tmp = 1507658653, tmp)/(-3016036094))))>>>((1497480588)>>(2784070758)))|(tmp = -3025904401.93921, tmp)));
+ assertEquals(-1680442631, x |= ((x/(445284843))|((tmp = 2614520057.2723284, tmp)<<x)));
+ assertEquals(40851947, x >>>= (tmp = -1577031386.938616, tmp));
+ assertEquals(2493, x >>= ((3044630989.3662357)-(-2670572992.8580284)));
+ assertEquals(-0.0000017317105653562252, x /= (-1439617017.9207587));
+ assertEquals(0, x &= (2359806567));
+ assertEquals(623768541, x ^= (623768541));
+ assertEquals(1028567149.0716183, x += (((tmp = 1307794561, tmp)%(x>>x))-(-404798608.0716183)));
+ assertEquals(-1.2971762489811298, x /= (tmp = -792927830.6471529, tmp));
+ assertEquals(-1.2971762489811298, x %= ((-2426421701.2490773)/(-689566815.3393874)));
+ assertEquals(-2147483648, x <<= x);
+ assertEquals(-2147483648, x &= (tmp = -869991477, tmp));
+ assertEquals(-268435456, x >>= (1383186659));
+ assertEquals(0, x -= x);
+ assertEquals(-2009742037, x |= (-2009742037.5389993));
+ assertEquals(-1386630820, x ^= (627864695));
+ assertEquals(-1033479103975173600, x *= (tmp = 745316697.9046186, tmp));
+ assertEquals(-1628048487, x |= (2662654361));
+ assertEquals(325551, x >>>= (340874477));
+ assertEquals(-1235730537, x ^= (tmp = 3059533880.0725217, tmp));
+ assertEquals(-1235730537, x %= (2247137328));
+ assertEquals(-220200960, x <<= ((x>>x)-x));
+ assertEquals(0, x <<= ((tmp = 337220439.90653336, tmp)|(tmp = 2901619168.375105, tmp)));
+ assertEquals(0, x >>>= ((-2114406183)/x));
+ assertEquals(0, x %= ((1425828626.3896675)/x));
+ assertEquals(0, x >>>= ((3213757494)>>>(2595550834.3436537)));
+ assertEquals(0, x <<= x);
+ assertEquals(-0, x /= ((1544519069.5634403)/((tmp = -1332146306, tmp)&(-762835430.0022461))));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x >>= (x|((((x*((-786272700)+x))<<x)+((tmp = -1868484904, tmp)-(tmp = -1692200376, tmp)))+(-1010450257.6674457))));
+ assertEquals(0, x -= x);
+ assertEquals(0, x ^= (x>>>(706010741)));
+ assertEquals(-964928697, x |= (-964928697));
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>= ((((tmp = 1778003555.3780043, tmp)>>(x%((tmp = -766158535, tmp)^((-2681449292.8257303)%((x-(x|(tmp = 1966478387.2443752, tmp)))^(((tmp = -1848398085, tmp)&x)>>>(tmp = -2860470842, tmp)))))))%(tmp = 2315077030, tmp))^x));
+ assertEquals(0, x ^= x);
+ assertEquals(-288007757, x ^= ((tmp = 183607156.1803962, tmp)-(tmp = 471614914, tmp)));
+ assertEquals(-270573581, x |= (tmp = -849475741.9424644, tmp));
+ assertEquals(-2129929, x |= (((((1942852445)&(tmp = 1280372312, tmp))*(x*(tmp = -1601900291, tmp)))^((509080002.81080174)-(tmp = 2699498226.9164257, tmp)))>>(((-335361221)>>(tmp = 843134832, tmp))%(-35532542))));
+ assertEquals(-232622355, x ^= ((-3060885134.5375547)-(((tmp = 1965966723, tmp)-((tmp = 1248630129.6970558, tmp)<<(tmp = 1859637857.5027392, tmp)))*x)));
+ assertEquals(-52149658093200070, x *= (224181627.31264615));
+ assertEquals(-697122968, x ^= (x-(x+(tmp = 2747211186.407712, tmp))));
+ assertEquals(-2146269688, x &= ((tmp = -1466710519, tmp)^(x/(1419998975))));
+ assertEquals(-536567422, x >>= (((((tmp = -1760701688.999274, tmp)>>(-1821976334))/(((tmp = -1660849531, tmp)>>>x)-((x+((tmp = -2489545009.4327965, tmp)>>>((tmp = -267360771.39148235, tmp)^x)))*(((-1453528661)%x)>>>(((243967010.3118453)/((((((2977476024)>>>((-1630798246)<<x))&(591563895.2506002))*(((2668543723.9720144)>>>x)|(1600638279)))^x)>>(x<<(tmp = -152589389, tmp))))>>>(x|(2821305924.9225664)))))))+(618968002.8307843))%(tmp = -1005408074.368274, tmp)));
+ assertEquals(40962, x &= (114403906));
+ assertEquals(19741977727890, x *= ((-2367133915.963945)>>>(-3119344126)));
+ assertEquals(1313341440, x <<= x);
+ assertEquals(626, x >>>= ((((-333992843)%(tmp = -2742280618.6046286, tmp))>>>x)|x));
+ assertEquals(0, x <<= (2598188575));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x ^= (x%((2507288229.3233204)&(tmp = -1714553169.9276752, tmp))));
+ assertEquals(0, x /= ((633436914.3859445)>>>(tmp = 1579804050.6442273, tmp)));
+ assertEquals(0, x *= ((tmp = 1172218326, tmp)<<((tmp = -2491306095.8456626, tmp)*(((tmp = 1305371897.9753594, tmp)>>((x^(((3077992060)*x)<<(492815553.904796)))>>((652151523)|x)))%x))));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x %= (1118131711));
+ assertEquals(0, x &= ((tmp = 2734673884, tmp)|(x-((tmp = 2694578672.8975897, tmp)*(((x>>(2350811280.974167))*(1052548515))&(x^(x*(tmp = -1336287059.0982835, tmp))))))));
+ assertEquals(-2632782867.1256156, x += ((tmp = -2743992725.1256156, tmp)+(tmp = 111209858, tmp)));
+ assertEquals(-0, x %= x);
+ assertEquals(0, x >>>= (((tmp = -2050519887, tmp)^(106865302.74529803))>>(1642851915.2909596)));
+ assertEquals(-171964826, x |= (tmp = -171964826.6087358, tmp));
+ assertEquals(-2.113405951193522, x /= (tmp = 81368572.80206144, tmp));
+ assertEquals(3, x >>>= x);
+ assertEquals(0, x %= x);
+ assertEquals(-1717345907.837667, x += (-1717345907.837667));
+ assertEquals(-100964883, x |= (tmp = -109574931.80629134, tmp));
+ assertEquals(-33849857, x |= (-974111718.2433801));
+ assertEquals(1, x >>>= (tmp = -2556222849.005595, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>>= (-1796630999.4739401));
+ assertEquals(0, x >>>= x);
+ assertEquals(2031695758, x += (((x/(((tmp = -2364918403, tmp)%(x^((tmp = 277767803.6375599, tmp)>>((((tmp = 540036080, tmp)/(x|(2665298931)))/(x|((x>>(-2035456216.6165116))<<(2143184420.5651584))))^x))))&(tmp = 927798419.8784283, tmp)))-(-2031695758))>>>x));
+ assertEquals(2031695758, x |= x);
+ assertEquals(2031695758, x <<= (((x>>(x%x))|(tmp = -1164531232.7384055, tmp))*x));
+ assertEquals(124004, x >>>= x);
+ assertEquals(529846352, x += ((529722348)%((2417645298.865121)|(x>>(x>>>(x+x))))));
+ assertEquals(60067920, x &= (((tmp = -3166008541.8486233, tmp)-x)|(x%x)));
+ assertEquals(1415594240755200, x *= ((-2786707452.873729)>>(((tmp = -2369315809, tmp)*((1559868465)|(1011218835.1735028)))>>>x)));
+ assertEquals(1415595182259140, x += (941503939.9023957));
+ assertEquals(0, x <<= ((tmp = 2887184784.265529, tmp)/(-2575891671.0881453)));
+ assertEquals(0, x &= ((tmp = -1546339583, tmp)>>>(tmp = -587433830, tmp)));
+ assertEquals(0, x *= (((tmp = 1356991166.5990682, tmp)%(tmp = -284401292, tmp))*(1869973719.9757812)));
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x ^= (((tmp = 92575404.43720293, tmp)>>>(263475358.17717505))%x));
+ assertEquals(0, x <<= (((561514358)*(tmp = -439584969, tmp))%((((-3005411368.7172136)+x)|(-2230472917))&x)));
+ assertEquals(0, x >>= ((x>>>x)-((x-(1630649280.510933))+x)));
+ assertEquals(0, x >>= (tmp = -1772403084.7012017, tmp));
+ assertEquals(0, x *= x);
+ assertEquals(0, x += x);
+ assertEquals(0, x &= x);
+ assertEquals(0, x >>= (tmp = 1622680387, tmp));
+ assertEquals(1033887633558225200, x -= ((-510616337)*(tmp = 2024783695, tmp)));
+ assertEquals(-2.8073538539158063e+27, x *= (tmp = -2715337492, tmp));
+ assertEquals(-2.8073538539158063e+27, x -= ((tmp = -1664804757, tmp)&((tmp = -226616419, tmp)>>>(1006711498))));
+ assertEquals(1894539615, x |= (tmp = -2400427681.1831083, tmp));
+ assertEquals(7400545, x >>= (774629608.4463601));
+ assertEquals(456756268, x += (449355723));
+ assertEquals(285771784, x &= (-1316427366));
+ assertEquals(17, x >>= ((tmp = -220509931.20787525, tmp)*(((tmp = 2518859292, tmp)+(-1477543005.1586645))>>(tmp = 3172820250.687789, tmp))));
+ assertEquals(85924262443, x *= (x*((tmp = -2856669745.965829, tmp)&(((tmp = 401420695, tmp)^(tmp = 2355371132, tmp))|(tmp = 590645330.021911, tmp)))));
+ assertEquals(1703875715, x ^= ((-2576394029.7843904)-x));
+ assertEquals(1703875715, x %= (tmp = 2234144310, tmp));
+ assertEquals(271405807, x ^= (1973569132));
+ assertEquals(1060178, x >>>= (tmp = -84823096, tmp));
+ assertEquals(8, x >>>= (tmp = 2246120561.905554, tmp));
+ assertEquals(-2846791089, x += (-2846791097));
+ assertEquals(104933962, x &= (x-(-2969030955.99584)));
+ assertEquals(489215611.96215343, x -= (-384281649.96215343));
+ assertEquals(489215611, x |= x);
+ assertEquals(1186191360, x <<= ((tmp = 774407142.993727, tmp)%x));
+ assertEquals(1186191360, x %= (1555004022));
+ assertEquals(-1697134080, x ^= (tmp = -597421568, tmp));
+ assertEquals(-1102053376, x <<= ((-927370769.4059179)^((tmp = 1093490918, tmp)>>(((-2522227493.3821955)%x)+(-2657319903)))));
+ assertEquals(1086450058, x ^= (-23991926.187098265));
+ assertEquals(1086450058, x |= x);
+ assertEquals(-1.6554590588410778, x /= (x|(x<<(x+x))));
+ assertEquals(67108863, x >>>= ((-926530233)+x));
+ assertEquals(494553310, x ^= (tmp = 512079649, tmp));
+ assertEquals(207751168, x &= (2892146720.6261826));
+ assertEquals(207751168, x &= x);
+ assertEquals(207751168, x |= x);
+ assertEquals(6340, x >>>= (((((x<<(x-((-2819638321)*((x<<x)+x))))>>x)+(tmp = 2016170261, tmp))+(tmp = 2755496043.772017, tmp))+(-841368625.1402085)));
+ assertEquals(6340, x ^= ((x/(tmp = -192734784, tmp))>>>(((-140306239)&x)-x)));
+ assertEquals(1, x /= x);
+ assertEquals(0, x >>= x);
+ assertEquals(26786600, x ^= (tmp = 26786600, tmp));
+ assertEquals(-0.014657576899542954, x /= ((-1454855938.0338)+(-372635753.3681567)));
+ assertEquals(0, x &= ((tmp = 2480635933, tmp)&(-2986584704.9165974)));
+ assertEquals(-2108639122, x += ((tmp = 2108639123.8683565, tmp)^((-881296055)/(((x<<(2026200582))|(tmp = -862495245.138771, tmp))-(-1111596494.892467)))));
+ assertEquals(1893466112, x <<= (tmp = 607974481, tmp));
+ assertEquals(1893466112, x |= x);
+ assertEquals(1133122783.997418, x += ((tmp = -760343332, tmp)-((x-(tmp = -878561823.4218843, tmp))/(tmp = -693454632.596637, tmp))));
+ assertEquals(8, x >>>= (tmp = 700339003.3919828, tmp));
+ assertEquals(4.605305035175536e-9, x /= (1737127060.8343256));
+ assertEquals(4.605305035175536e-9, x -= ((x%(897221779))>>>x));
+ assertEquals(-1864423625.5704088, x += (tmp = -1864423625.5704088, tmp));
+ assertEquals(1132240092, x <<= (1304417186.1193643));
+ assertEquals(-2088985380, x ^= (x<<x));
+ assertEquals(-4, x >>= ((tmp = 1959823884.0935726, tmp)%(-1679792398.569136)));
+ assertEquals(-268435456, x <<= ((tmp = 2586838136, tmp)|((tmp = -481716750.718518, tmp)>>>((1485826674.882607)/(tmp = -2826294011, tmp)))));
+ assertEquals(-32768, x >>= (2060648973));
+ assertEquals(1, x /= x);
+ assertEquals(-2838976297, x -= (tmp = 2838976298, tmp));
+ assertEquals(-1382985298, x <<= ((tmp = -2104305023, tmp)&x));
+ assertEquals(10, x >>>= (x+x));
+ assertEquals(10, x -= (x>>>(361588901.70779836)));
+ assertEquals(854603510, x -= (-854603500));
+ assertEquals(-557842432, x <<= (tmp = 1212985813.6094751, tmp));
+ assertEquals(-459390188241943040, x *= (tmp = 823512450.6304014, tmp));
+ assertEquals(-232800033621957060, x /= ((((((686635689)/(tmp = 2013252543, tmp))*(tmp = -1591617746.8678951, tmp))|(((tmp = -1777454093.5611362, tmp)>>>((tmp = 2680809394, tmp)^(((x>>((((((tmp = -265022244, tmp)%((tmp = -3075004537, tmp)>>(((((1427784269.5686688)^((tmp = -1095171528.911587, tmp)^(-942424985.7979553)))>>(-1279441481.1987405))*((2493620394)>>(-2769016043)))/(x&((tmp = 2059033657, tmp)%(((tmp = 1948606940.1488457, tmp)-(tmp = -2645984114.13219, tmp))^x))))))^x)^x)%(x%((((tmp = 3209433446.4551353, tmp)%(tmp = 1364430104.0424738, tmp))/(tmp = -2103044578.349498, tmp))+(tmp = -2613222750, tmp))))*(2099218034)))&(((tmp = -378500985.49700975, tmp)>>(((x+x)|(x%(((-1841907486)<<(-1220613546.194021))<<(tmp = -1260884176, tmp))))^(tmp = 1858784116, tmp)))>>>((x%x)%((x>>>(tmp = -2540799113.7667685, tmp))|x))))/((((tmp = 642072894.6455215, tmp)-(-324951103.6679399))*(tmp = 1424524615, tmp))+((x<<(tmp = -904578863.5945344, tmp))*(tmp = 49233475.435349464, tmp))))))<<(tmp = 1680210257, tmp)))+((tmp = -1516431503, tmp)>>>(-1105406695.3068116)))/(-275019361.6764543)));
+ assertEquals(192359387.42913792, x /= (-1210234846));
+ assertEquals(192359387.42913792, x %= (-2920206625.0154076));
+ assertEquals(192359387.42913803, x -= (((((((tmp = -1263203016.3258834, tmp)-(2432034005.6011124))&x)<<(1479434294))>>((tmp = -1695856315.523002, tmp)>>>(tmp = 557391345, tmp)))/(tmp = -1280240246.2501266, tmp))%((tmp = -2196489823.034029, tmp)>>(((x&((912221637.1101809)+((tmp = -3003677979.652423, tmp)>>(tmp = -716129460.1668484, tmp))))-((x+(x-(-2780610859)))>>>(-2445608016)))<<((x*(x+(x+(((-2124412727.9007604)%(tmp = -593539041.5539455, tmp))&(tmp = 2404054468.768749, tmp)))))%(x>>(tmp = -2913066344.404591, tmp)))))));
+ assertEquals(11740, x >>= (688848398.7228824));
+ assertEquals(11740, x >>= ((1545765912)*(307650529.9764147)));
+ assertEquals(23480, x += x);
+ assertEquals(0, x >>>= ((tmp = 1313078391, tmp)|x));
+ assertEquals(1726251264, x -= ((1939413887)<<(1004888744.2840619)));
+ assertEquals(765324793.5278986, x %= (960926470.4721014));
+ assertEquals(747387, x >>= ((2483010044)-(tmp = -413698190, tmp)));
+ assertEquals(1, x /= x);
+ assertEquals(3016811624, x *= (3016811624));
+ assertEquals(17408, x &= (((tmp = -991624868, tmp)<<(((63107932)/(tmp = 2659939199, tmp))|(tmp = -1968768911.3575773, tmp)))>>(((-2876822038.9910746)|(tmp = 2550230179.243425, tmp))<<((x*(x<<((x<<((tmp = -1627718523.616604, tmp)|((2154120561.254636)-(x%(x<<(1484563622.1791654))))))<<((((x^(tmp = 3016524169, tmp))<<(((x+(tmp = 1887816698.2455955, tmp))+x)-x))-(-3023329069))-x))))+x))));
+ assertEquals(0, x <<= (((1247441062.177967)/(-1717276234))+x));
+ assertEquals(0, x |= ((x%((-1648299429.4520087)>>(-137511052)))>>(tmp = 221301016.4926411, tmp)));
+ assertEquals(0, x /= ((-2598501544.913707)>>>(-2177037696)));
+ assertEquals(NaN, x %= (x>>x));
+ assertEquals(0, x &= (tmp = 1852419158, tmp));
+ assertEquals(-829029120, x |= (((2122339180)*((((((tmp = 768748914, tmp)<<((1008490427)&((1937367899.957056)-(((635094486)>>(((tmp = -795046025, tmp)*(2665104134.4455256))^(tmp = 706594584.2462804, tmp)))/(504397522)))))/(-556057788))>>((x/(tmp = -2732280594, tmp))-x))+(-1989667473))+(tmp = 2766802447.789895, tmp)))<<(((tmp = -2969169096, tmp)-x)+(tmp = 2093593159.0942125, tmp))));
+ assertEquals(0.6451933462602606, x /= ((-1284931292)<<(x<<(tmp = 1294716764, tmp))));
+ assertEquals(1515416866.520901, x *= (2348779440));
+ assertEquals(-1620606242886682600, x *= ((-993898625.5357854)&(((tmp = -571100481, tmp)/x)*((2428590177.311031)%(tmp = -2671379453, tmp)))));
+ assertEquals(-1137472828, x %= (tmp = -1195183004, tmp));
+ assertEquals(-3096634005473250000, x *= (tmp = 2722380640, tmp));
+ assertEquals(-3096634003996758500, x -= (-1476491033.833419));
+ assertEquals(-3096634000805538000, x += (3191220521.978341));
+ assertEquals(-3096634000805468000, x += ((((tmp = -3024976741, tmp)&(952616360))|((x*(-1547952311))+(x*x)))>>>(tmp = 981373323, tmp)));
+ assertEquals(-3096633998655594000, x += (2149873927));
+ assertEquals(-118812224101.54297, x %= (((2641881276.9898443)*(((502159480)^x)<<x))%((tmp = -2840045365.547772, tmp)*(((((-2297661528)>>>(x>>(-229103883.94961858)))&(((-1285047374.6746495)<<((-360045084)>>>((x-(tmp = -956123411.1260898, tmp))%x)))>>((tmp = -2375660287.5213504, tmp)+((((tmp = -2753478891, tmp)>>>(((tmp = 101438098, tmp)>>(((tmp = -2736502951, tmp)<<((tmp = -3084561882.368902, tmp)&(tmp = 1491700884, tmp)))|x))&(tmp = 1627412882.6404104, tmp)))>>>(tmp = 1039002116.6784904, tmp))<<((tmp = -2840130800, tmp)-(tmp = -740035567, tmp))))))&(tmp = -416316142, tmp))>>x))));
+ assertEquals(86, x >>>= (tmp = -293489896.5572462, tmp));
+ assertEquals(172, x += (x%((((-2635082487.364155)|((-2361650420.634912)&(-2147095650.7451198)))<<((tmp = 2258905145.9231243, tmp)%((((tmp = -1365987098.5130103, tmp)*(((((((932437391)/x)/(289270413.0780891))%(x-x))+((((2194986374.917528)>>(((((tmp = -1553805025, tmp)|x)^(((x>>(-564400586.0780811))^(tmp = 1738428582.0238137, tmp))>>(tmp = 1717774140, tmp)))&(tmp = -2789427438, tmp))%(((tmp = -1386118057, tmp)*(-2333221237.7915535))*(x>>>(((((41346648.46438944)&x)%(-478973697.6792319))|(tmp = 2108106738, tmp))/x)))))-(tmp = -133437701.64136505, tmp))>>>x))+(tmp = -1567210003, tmp))*(x+((x&x)-(2942851671)))))>>>(tmp = -446377136, tmp))*((((((tmp = 1597203255, tmp)>>>(619157171))|(-2766246629.005985))>>((tmp = 3130227370, tmp)%x))*(tmp = 2072227901.6101904, tmp))|((tmp = 1369019520, tmp)^(759659487))))))>>>x)));
+ assertEquals(1996475731, x ^= ((1456327892.2281098)|(1728022827)));
+ assertEquals(0, x %= x);
+ assertEquals(0, x &= (1323847974));
+ assertEquals(3076829073.8848357, x += (3076829073.8848357));
+ assertEquals(9569842648396755000, x *= (3110293883.2782717));
+ assertEquals(9569842646260304000, x -= (2136450372.9038036));
+ assertEquals(9.158188827418242e+37, x *= x);
+ assertEquals(0, x <<= ((x&(tmp = -2241179286, tmp))+((tmp = 2553144081, tmp)&((tmp = -1914709694, tmp)^(tmp = -1469651409.0651562, tmp)))));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x /= (2177840666.276347));
+ assertEquals(0, x %= (-690827104));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x ^= x);
+ assertEquals(-0, x /= (tmp = -803415280, tmp));
+ assertEquals(-2355576914.316743, x += (-2355576914.316743));
+ assertEquals(-833671722514674000, x *= ((3053388806.692315)-(tmp = 2699474775.081724, tmp)));
+ assertEquals(1, x /= x);
+ assertEquals(1898147684, x += ((tmp = 1898147683, tmp)|(x<<x)));
+ assertEquals(2.192324660388075, x %= ((tmp = 2630187518, tmp)/((2868794982.790862)|(490860748))));
+ assertEquals(0, x >>>= ((2751021779)/(-952522559)));
+ assertEquals(321040461, x ^= ((321040461.153594)-x));
+ assertEquals(-2.3814602031636922, x /= ((tmp = -170472190, tmp)|x));
+ assertEquals(-1, x >>= (2200125174.177402));
+ assertEquals(-2964432647.9379396, x += (-2964432646.9379396));
+ assertEquals(-370116502.93793964, x %= (tmp = -518863229, tmp));
+ assertEquals(777927355.2283959, x -= (-1148043858.1663356));
+ assertEquals(0, x *= ((tmp = 1134913539, tmp)&(((x>>>((tmp = -989822787, tmp)>>>x))%x)&(tmp = 1078636160.7313156, tmp))));
+ assertEquals(-1089245637, x ^= (3205721659.3548856));
+ assertEquals(-1192493056, x <<= (-1173291054));
+ assertEquals(78013832, x += ((tmp = 2462999944, tmp)+x));
+ assertEquals(0, x %= x);
+ assertEquals(0, x >>>= (1794908927.7409873));
+ assertEquals(1708338504, x += ((-2586628792.3484306)<<x));
+ assertEquals(12, x >>= (-545794789.3827574));
+ assertEquals(0, x &= ((2753207225)<<(((-1776581207.557251)+((tmp = -2414140402, tmp)*x))+(x<<(x|(tmp = 772358560.3022032, tmp))))));
+ assertEquals(0, x <<= ((tmp = -2755724712.152605, tmp)/((x>>(-732875466))&x)));
+ assertEquals(NaN, x *= (((tmp = 2617815318.1134562, tmp)/x)%(x|((((((-851659337.194871)<<(tmp = 2072294700, tmp))%((x+(2193880878.5566335))^((tmp = 3005338026, tmp)-(2947963290))))/x)/(x+(2091745239.4210382)))-(x>>x)))));
+ assertEquals(NaN, x /= (tmp = -427684595.0278094, tmp));
+ assertEquals(NaN, x /= (tmp = -263945678, tmp));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x -= (((x>>((x&x)-(tmp = -673697315, tmp)))>>(((1575095242.2330558)/(x-(-1816886266)))%(-1580195729)))>>>x));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x >>= (-2815518206));
+ assertEquals(0, x -= (x/(1795634670.692437)));
+ assertEquals(-2753579891, x += (tmp = -2753579891, tmp));
+ assertEquals(2.7773776150171776, x /= (tmp = -991431585, tmp));
+ assertEquals(5.554755230034355, x += x);
+ assertEquals(3.362161997528237e-9, x /= (1652137890.4758453));
+ assertEquals(3.362161997528237e-9, x %= (tmp = -10848734.527020693, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(-2978012493, x -= (x+(2978012493)));
+ assertEquals(-5.158905851797543, x /= (((x+((tmp = -2548840164, tmp)>>x))<<(x^((tmp = -533281232.7294345, tmp)&x)))&(tmp = -1502692171, tmp)));
+ assertEquals(-5.158905851797543, x %= (-3009435255.5612025));
+ assertEquals(-20971520, x <<= ((tmp = -2728812464, tmp)%(2619809573.672677)));
+ assertEquals(-1900019712, x &= (2398099552));
+ assertEquals(-1991377, x %= ((tmp = 1562364373.7334614, tmp)>>>(((x-(-946283217))<<(-2044590694))^(((tmp = 1681238509, tmp)>>(-2801649769))-x))));
+ assertEquals(1, x /= x);
+ assertEquals(1, x %= (x/(x-x)));
+ assertEquals(1.3525631913093335e-9, x /= (739336991));
+ assertEquals(0, x &= ((x&(x|(-1530424204)))<<((((tmp = -295143065.9115021, tmp)>>x)+x)<<x)));
+ assertEquals(0, x <<= (-1311017801));
+ assertEquals(-0, x /= (-667133339.1918633));
+ assertEquals(1038307283, x += (1038307283));
+ assertEquals(506985, x >>>= ((tmp = 1550624472.9157984, tmp)^x));
+ assertEquals(506985, x >>>= ((254646626)<<(tmp = 1572845412.744642, tmp)));
+ assertEquals(32447040, x <<= (tmp = -2427326042, tmp));
+ assertEquals(0, x -= (x<<((x|x)>>>x)));
+ assertEquals(0, x &= x);
+ assertEquals(0, x &= ((-484420357)|((tmp = 807540590.6132902, tmp)/(x/x))));
+}
+f();
diff --git a/deps/v8/test/mjsunit/numops-fuzz-part4.js b/deps/v8/test/mjsunit/numops-fuzz-part4.js
new file mode 100644
index 000000000..c4ea614b3
--- /dev/null
+++ b/deps/v8/test/mjsunit/numops-fuzz-part4.js
@@ -0,0 +1,1177 @@
+// Copyright 2011 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.
+
+function f() {
+ var x = 0;
+ var tmp = 0;
+ assertEquals(-890607324, x ^= ((tmp = -890607324, tmp)>>((((-2876826295)>>x)<<((tmp = 2351495148.117994, tmp)>>(tmp = 1368611893.274765, tmp)))*(tmp = 1531795251, tmp))));
+ assertEquals(-729075363, x += (x+(tmp = 1052139285, tmp)));
+ assertEquals(531550884933581760, x *= x);
+ assertEquals(1980836332, x ^= ((-746269795.2320724)-((2400458512)>>((1290672548)>>>((((1536843439.5629003)&(3185059975.158061))*(tmp = -1339249276.2667086, tmp))&x)))));
+ assertEquals(941373096, x %= ((x+(-451098412))^(tmp = 1725497732, tmp)));
+ assertEquals(-1766019323, x += (tmp = -2707392419, tmp));
+ assertEquals(2528947973, x >>>= (x^(-896237435.3809054)));
+ assertEquals(-263192576, x <<= (-866361580));
+ assertEquals(-2008, x >>= (-2608071791));
+ assertEquals(-88, x %= (((-1076807218.4792447)&((tmp = 601044863, tmp)>>((tmp = 1228976729, tmp)+((((-2711426325)*x)|x)|(x%(-2700007330.3266068))))))&(tmp = 3147972836.778858, tmp)));
+ assertEquals(1762886843, x ^= (tmp = 2532080403, tmp));
+ assertEquals(1762886843, x %= ((((((tmp = -2059247788, tmp)>>x)/x)+(x<<x))^x)>>>(-1969283040.3683646)));
+ assertEquals(4812334726.587896, x += (tmp = 3049447883.587897, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(1, x *= x);
+ assertEquals(-2150507334, x -= ((tmp = 1578221999, tmp)+(tmp = 572285336, tmp)));
+ assertEquals(-4546475858941548500, x *= ((tmp = -931533139.5546813, tmp)^(tmp = 3061503275, tmp)));
+ assertEquals(-269064192, x |= ((207217276.91936445)<<(tmp = -957353678.4997551, tmp)));
+ assertEquals(1, x /= x);
+ assertEquals(1, x <<= (((1463856021.8616743)%(x*(tmp = -2286419102, tmp)))/(-2852887593)));
+ assertEquals(2223868564.8383617, x *= (tmp = 2223868564.8383617, tmp));
+ assertEquals(918797189.9033995, x -= ((1305071374.9349623)%(x+(2211992629))));
+ assertEquals(-2212004787.4668465, x -= (tmp = 3130801977.370246, tmp));
+ assertEquals(31783, x >>= (2951958960));
+ assertEquals(31783, x ^= ((((tmp = -2441511566, tmp)&((tmp = 91427553.90168321, tmp)+((tmp = 3001737720.327718, tmp)%x)))>>>(-2263859841))>>>((2109161329)>>(tmp = -2816295136.7443414, tmp))));
+ assertEquals(4068224, x <<= (x%((tmp = -682576250.4464607, tmp)*(x/(((x-x)>>>(x&((((x<<(x<<x))>>>((((2243036981.528562)/(((-1839328916.9411087)>>(-1907748022.162144))<<(x+x)))+((tmp = 2362574171, tmp)<<(tmp = 1987834539, tmp)))|(-444329240)))|(399451601.1717081))>>x)))&(968363335.6089249))))));
+ assertEquals(0.0030991932898194294, x /= ((tmp = 1067316540.5529796, tmp)^(-2388640366)));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x >>>= (tmp = -393433349.1636851, tmp));
+ assertEquals(0, x *= (((x^(((1806955787.471396)<<x)^((517668047.55566347)>>>(x%(x<<(tmp = -276586733.4844558, tmp))))))%(1661242196.1472542))|x));
+ assertEquals(0, x |= (x>>x));
+ assertEquals(-155236210, x |= (tmp = -155236210.19366312, tmp));
+ assertEquals(-606392, x >>= ((tmp = -1533446042.97781, tmp)^x));
+ assertEquals(-1, x >>= (936126810));
+ assertEquals(2325115611, x -= (-2325115612));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>= (tmp = -354826623, tmp));
+ assertEquals(-0, x *= (-1232528947.7321298));
+ assertEquals(0, x |= x);
+ assertEquals(0, x <<= (((tmp = 187758893.4254812, tmp)&(x-(tmp = 648201576, tmp)))&(385106597)));
+ assertEquals(0, x >>= (tmp = 2554891961, tmp));
+ assertEquals(-1311492611.2970417, x += (-1311492611.2970417));
+ assertEquals(-688179220.3221785, x += (623313390.9748632));
+ assertEquals(1416835528, x &= (tmp = 1953739224, tmp));
+ assertEquals(-11.04719252755072, x /= (-128252995));
+ assertEquals(-6.287413042114223e-9, x /= (tmp = 1757033052.1558928, tmp));
+ assertEquals(-4231171, x |= (((((2022730885.7773404)*((-2495777565.221855)|(tmp = 274627292, tmp)))<<(-3072596920.4902725))>>>((-2215057529)+(-1134713759.4247034)))^((tmp = -1888181788, tmp)/(572025985.2748461))));
+ assertEquals(-4194305, x |= ((tmp = 167328318.038759, tmp)>>>(153800904.34551537)));
+ assertEquals(-1316525687, x -= (1312331382));
+ assertEquals(1448723245.7863903, x += (2765248932.7863903));
+ assertEquals(1.7219707102205526, x /= (tmp = 841317008, tmp));
+ assertEquals(1872027792.5217001, x *= (x|(tmp = 1087142645.6665378, tmp)));
+ assertEquals(3504488055973669400, x *= x);
+ assertEquals(-1075254784, x |= x);
+ assertEquals(-5, x >>= (((844461331.8957539)-((x&x)<<((tmp = 1443904777, tmp)+(tmp = 736164505.3670597, tmp))))-(((tmp = 1348422110, tmp)>>((tmp = -2878252514, tmp)/(-1175443113)))|((-2138724317)%(2057081133)))));
+ assertEquals(-3.038875804165675e-9, x /= (1645345292.8698258));
+ assertEquals(1.25204541454491e-18, x /= (-2427129055.274914));
+ assertEquals(-1.7151576137235622e-9, x *= (-1369884505.6247284));
+ assertEquals(1590804618, x ^= (1590804618.4910607));
+ assertEquals(5061318665300252000, x *= (x+x));
+ assertEquals(5061318665300252000, x %= ((tmp = 1102144242, tmp)*x));
+ assertEquals(-7, x >>= (2772167516.624264));
+ assertEquals(16383, x >>>= (-2979259214.5855684));
+ assertEquals(47108415435, x *= ((2944456517.839616)>>>(1041288554.5330646)));
+ assertEquals(61, x >>>= (x^(((-1305163705)<<((948566605)-x))-x)));
+ assertEquals(0, x %= x);
+ assertEquals(0, x ^= (((tmp = 1918861879.3521824, tmp)/((x%(tmp = 945292773.7188392, tmp))%(x|x)))>>x));
+ assertEquals(-0, x *= ((((x|((2810775287)|(tmp = 1265530406, tmp)))^((tmp = 3198912504.175658, tmp)-(((tmp = 1422607729.281712, tmp)<<(tmp = 2969836271.8682737, tmp))&x)))<<((tmp = 844656612, tmp)*(((((tmp = -828311659, tmp)%(((-2083870654)>>>(x^(((((933133782)-(tmp = 1033670745, tmp))-(629026895.4391923))%((-605095673.8097742)*((((-227510375.38460112)*x)+x)&(((((tmp = 472873752.68609154, tmp)^(tmp = 2815407038.712165, tmp))+((x>>>((tmp = -1331030665.3510115, tmp)>>>(2281234581)))-(x>>>x)))&(tmp = -2160840573.325921, tmp))&x))))<<(tmp = 1411888595, tmp))))|(((tmp = -915703839.0444739, tmp)/((x+(418836101.8158506))%(-1112605325.4404268)))&((-3098311830.6721926)-x))))-((49446671.477988124)*(-2522433127)))+((tmp = 443068797, tmp)>>(tmp = 418030554.97275746, tmp)))*((tmp = 38931296.738208175, tmp)+(1842742215.3282685)))))-((tmp = 1325672181.205841, tmp)^(tmp = 669284428, tmp))));
+ assertEquals(-0, x *= (tmp = 93843030, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x ^= x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x >>>= (x%((((((tmp = -107458601, tmp)>>(x*((x|((tmp = 2117286494, tmp)>>((x^(tmp = 114214295.42048478, tmp))>>>(tmp = 1032826615, tmp))))&((x*x)&(-225386977.67686415)))))^((-780566702.5911419)+(-1113319771)))|(((x^x)<<(1288064444))>>(-2292704291.619477)))>>(365125945))-((tmp = -1986270727.235776, tmp)/x))));
+ assertEquals(-0, x *= (((-18925517.67125845)|((((-1975220517)+(tmp = -1250070128.296064, tmp))+(1085931410.5895243))<<(((x|(((x*(tmp = 160207581.50536323, tmp))|(tmp = 1798744469.7958293, tmp))-x))>>>(((x+((x%x)&((((x^x)<<((tmp = 2538012074.623554, tmp)^x))*x)&x)))/(x+(tmp = -2563837407, tmp)))/(tmp = 2189564730, tmp)))/(((-1703793330.5770798)<<((176432492)|x))<<(1347017755.345185)))))<<(((tmp = -577100582.7258489, tmp)&x)/(-31246973))));
+ assertEquals(0, x >>>= x);
+ assertEquals(NaN, x %= ((x*(tmp = 1167625971, tmp))&(((tmp = -770445060, tmp)>>((339248786)^((2058689781.2387645)-((-2381162024)*(660448066)))))&x)));
+ assertEquals(NaN, x += ((3088519732.515986)-(-267270786.06493092)));
+ assertEquals(0, x &= (tmp = 2748768426.3393354, tmp));
+ assertEquals(-1109969306, x ^= ((-1109969306)>>>x));
+ assertEquals(-1109969306, x %= (tmp = 1150376563.581773, tmp));
+ assertEquals(-2058145178, x &= (-2057586057));
+ assertEquals(-850185626, x |= ((x^(tmp = 1223093422, tmp))&((-589909669)<<(2299786170))));
+ assertEquals(1489215443, x += (2339401069));
+ assertEquals(-23592960, x <<= x);
+ assertEquals(2063937322, x ^= (-2053296342.2317986));
+ assertEquals(12922122, x %= (x^((-2259987830)>>(x*(((tmp = -799867804.7716949, tmp)&(tmp = -1068744142, tmp))*(((((1091932754.8596292)-((tmp = -1778727010, tmp)>>(((tmp = 1207737073.2689717, tmp)-(x-(tmp = -1191958946, tmp)))+(-631801383.7488799))))-(-618332177))>>>(-156558558))>>>(3032101547.6262517)))))));
+ assertEquals(12922122, x &= x);
+ assertEquals(Infinity, x /= (x%x));
+ assertEquals(0, x &= (x*(-227800722.62070823)));
+ assertEquals(-865648691, x ^= (-865648691));
+ assertEquals(1, x /= (x%(tmp = 1524739353.8907173, tmp)));
+ assertEquals(16, x <<= (x<<(2335214658.789205)));
+ assertEquals(0, x &= ((tmp = 570332368.1239192, tmp)^(-2278439501)));
+ assertEquals(1881145344, x -= (((-569715735.8853142)+(2093355159))<<(tmp = 2788920949, tmp)));
+ assertEquals(0, x ^= x);
+ assertEquals(NaN, x -= ((tmp = -1427789954, tmp)%((((((411038329.49866784)-x)-(x<<((-1330832247)+x)))/x)^((x*(845763550.2134092))>>(tmp = 1427987604.5938706, tmp)))>>>(1857667535))));
+ assertEquals(NaN, x /= (-313793473));
+ assertEquals(0, x >>>= (x/x));
+ assertEquals(1869358566, x -= (-1869358566));
+ assertEquals(-1901664519209545200, x += ((tmp = 944729941.3936644, tmp)*(-2012918653)));
+ assertEquals(-1901664519209545200, x += ((tmp = 1348246793, tmp)/(x&x)));
+ assertEquals(-1576791552, x &= (tmp = 2719250966.739456, tmp));
+ assertEquals(-305087899, x ^= (-2955630491.030272));
+ assertEquals(0, x ^= (x%(1575252839.559443)));
+ assertEquals(4184604407, x += ((((tmp = -244720076.17657042, tmp)|(2819320515))^((((tmp = 1222623743.9184055, tmp)*(-95662379.577173))/(x/(x+(((x-(tmp = -3024718107.6310973, tmp))^(-1494390781))&(tmp = 2284054218.8323536, tmp)))))>>>(tmp = 2090069761, tmp)))>>>(x%x)));
+ assertEquals(3148907440, x -= (((tmp = -332379100.7695112, tmp)-(-1145399547))^(((((((tmp = 3133792677.785844, tmp)+x)<<(2306999139.5799255))>>((tmp = -2051266106, tmp)*(((((x+(((-728654312.8954825)>>(x>>>(((x%x)&(-1587152364))|(((((-2114138294)&x)&(1547554688))^x)-(-1856094268)))))*(((-1135018784)&((x+(tmp = -1444020289, tmp))|x))+x)))>>x)&x)/(2449005489))<<((131073798.64314616)%(x>>>((-2592101383.2205048)^(tmp = -757096673.0381112, tmp)))))))^(2766467316.8307915))-(-2465892914.515834))-((((tmp = 234064056, tmp)^((x>>>(1622627548.7944543))+(-1750474146)))|(-1959662039.4687617))^((-1222880974)&(-2794536175.906498))))));
+ assertEquals(-1157627488, x &= (-1156639323));
+ assertEquals(-1342170624, x <<= ((x/((((1829945345.0613894)/(x*((tmp = 1278865203.0854595, tmp)/(((tmp = -2298274086.519347, tmp)+(tmp = -545203761, tmp))-(tmp = 2712195820, tmp)))))>>>((tmp = 240870798.9384452, tmp)-(tmp = -3188865300.4768195, tmp)))>>>(x%((648799266)>>>(tmp = 24460403.864815235, tmp)))))|((tmp = 232533924, tmp)|x)));
+ assertEquals(-2684341248, x += x);
+ assertEquals(1073755136, x &= (((-662718514.9245079)>>(tmp = -1915462105, tmp))+(tmp = 1478850441.8689613, tmp)));
+ assertEquals(-1073755136, x /= (x|((tmp = -1767915185, tmp)|((325827419.1430224)|(((-1343423676)|(tmp = -1929549501, tmp))|(-866933068.9585254))))));
+ assertEquals(-1073755136, x %= ((tmp = 547342356, tmp)-((tmp = 2213249646.7047653, tmp)-((((((-2463314705)^(tmp = -993331620, tmp))^(((x%x)>>(tmp = 1798026491.3658786, tmp))-(((1024072781)/(tmp = -2407354455, tmp))%(1973295010))))<<(-1966787233))^x)|(-1787730004)))));
+ assertEquals(-1073754452, x |= (tmp = 3099823788.077907, tmp));
+ assertEquals(-1540683096, x &= (-1540674632.7013893));
+ assertEquals(-1540683052, x ^= ((tmp = -126183090, tmp)>>>((-622437575.5788481)|((((tmp = -2947914022, tmp)%(((tmp = 2512586745, tmp)>>x)>>>((27238232.23677671)/(tmp = 3203958551, tmp))))/(tmp = 2906005721.402535, tmp))^((((tmp = 1763897860.737334, tmp)^(1445562340.2485332))/x)+(-2393501217.716533))))));
+ assertEquals(-1258599433, x |= (tmp = 351291767.59661686, tmp));
+ assertEquals(-1241560065, x |= (626346046.5083935));
+ assertEquals(-1241560065, x ^= ((2263372092)/((tmp = -2868907862, tmp)>>>x)));
+ assertEquals(-893685228, x -= (tmp = -347874837, tmp));
+ assertEquals(3401282068, x >>>= (x*x));
+ assertEquals(0, x %= x);
+ assertEquals(0, x >>>= x);
+ assertEquals(-2079237393, x ^= (tmp = 2215729903, tmp));
+ assertEquals(NaN, x %= ((((tmp = 3203450436, tmp)/(2867575150.6528325))&(1864945829))&((x&((((tmp = -1927086741.3438427, tmp)|x)|(-1783290909.3240588))*((-1074778499.0697656)*(x-((tmp = -848983542.8456669, tmp)^(tmp = -1324673961, tmp))))))>>(tmp = -2144580304.245896, tmp))));
+ assertEquals(-43334009, x |= (x^(-43334009.72683525)));
+ assertEquals(-43334009, x &= x);
+ assertEquals(-43334009, x %= (tmp = 1252450645.060542, tmp));
+ assertEquals(-43334009, x |= (((((((tmp = 968062202, tmp)/(x|(tmp = 2766801984, tmp)))*((2173353793.938968)>>(((tmp = -2459317247, tmp)<<(tmp = -2333601397, tmp))>>>((tmp = -578254251.8969193, tmp)*(tmp = 839964110.7893236, tmp)))))&(((1675305119)&(tmp = -929153707, tmp))*((x*x)*x)))/x)|(x/(tmp = 384740559.43867135, tmp)))%(1657362591)));
+ assertEquals(0, x -= x);
+ assertEquals(0, x %= (-1334758781.1087842));
+ assertEquals(0, x -= x);
+ assertEquals(-54, x += ((tmp = -1787151355.470972, tmp)>>((tmp = 237028977, tmp)>>(((2829473542)<<(x>>>(((((((x-(-1950724753))*(((x>>>(2807353513.6283565))<<((-583810779.1155353)>>(x*x)))>>(-1068513265)))^(x^(-696263908.5131407)))%(((tmp = -1325619399, tmp)<<((tmp = -1030194450, tmp)-x))^x))+((-2852768585.3718724)>>(tmp = -3160022361, tmp)))%(x&x))>>(tmp = 2667222702.5454206, tmp))))+((804998368.8915854)<<x)))));
+ assertEquals(-54, x %= (-1601267268.4306633));
+ assertEquals(1, x >>>= (tmp = -543199585.579128, tmp));
+ assertEquals(4.732914708226396e-10, x /= (tmp = 2112862922, tmp));
+ assertEquals(-4266932650, x -= ((((x^((((tmp = 2784618443, tmp)^(tmp = -2271260297.9010153, tmp))|((((tmp = -599752639.7516592, tmp)*(2751967680.3680997))^(tmp = -1478450055.578217, tmp))*x))-x))&((tmp = -520061982, tmp)-((tmp = 1400176711.9637299, tmp)^(((2100417541)|(x+(tmp = -674592897.0420957, tmp)))>>x))))^(tmp = -365650686.7947228, tmp))>>>((-2943521813)&(((tmp = -1888789582, tmp)>>(tmp = 700459655.488978, tmp))+(tmp = -1725725703.655931, tmp)))));
+ assertEquals(224277168, x <<= (tmp = 2885115011.8229475, tmp));
+ assertEquals(224277168, x %= (tmp = -2655345206.442777, tmp));
+ assertEquals(850395136, x <<= (x-(((((-769868538.1729524)/((tmp = -298603579, tmp)%(x^x)))+((2691475692)|(((x>>>(628995710.4745524))^(x<<(((tmp = -1046054749, tmp)|(919868171))-x)))^((-1377678789.8170452)&((3065147797)%(tmp = 2638804433, tmp))))))^(tmp = -2036295169, tmp))&(((tmp = -157844758.08476114, tmp)*(tmp = -2819601496, tmp))&((((tmp = 78921441, tmp)<<(653551762.5197772))/(1801316098))*(-1479268961.8276927))))));
+ assertEquals(1645565728, x ^= (tmp = 1353013024, tmp));
+ assertEquals(1645565728, x >>>= x);
+ assertEquals(3020513544, x += (1374947816));
+ assertEquals(0, x %= x);
+ assertEquals(0, x %= ((((((tmp = -304228072.4115715, tmp)>>>((-90523260.45975709)-(tmp = -3013349171.084838, tmp)))%((-1640997281)*((tmp = -1600634553, tmp)%((tmp = 557387864, tmp)<<((888796080.766409)|(x^((((x%(((((tmp = 1164377954.1041703, tmp)*x)|(2742407432.192806))&((tmp = 1707928950, tmp)<<(1279554132.4481683)))+(tmp = -2108725405.7752397, tmp)))%(tmp = -465060827, tmp))^((tmp = 2422773793, tmp)+x))^((((((((tmp = -1755376249, tmp)^((-267446806)^x))/(((tmp = -1808578662.4939392, tmp)+((tmp = -1997100217, tmp)+x))+(((tmp = -2469853122.411479, tmp)/x)>>(tmp = 660624616.7956645, tmp))))%((x<<((((((tmp = -1701946558, tmp)-(tmp = 133302235, tmp))>>>x)/(738231394))<<(-1060468151.4959564))&(((((-1877380837.4678264)|(tmp = 2366186363, tmp))%x)>>>(-2382914822.1745577))>>((-1874291848.9775913)<<(tmp = 2522973186, tmp)))))<<(-2672141993)))|(tmp = 732379966, tmp))%x)^x)^x))))))))%(tmp = 2385998902.7287374, tmp))*x)+(tmp = -2195749866.017106, tmp)));
+ assertEquals(401488, x ^= (((-320896627)>>>(tmp = 2812780333.9572906, tmp))&(tmp = -2088849328, tmp)));
+ assertEquals(-1661116571.0046256, x += (tmp = -1661518059.0046256, tmp));
+ assertEquals(-1616122720, x <<= x);
+ assertEquals(-1616122720, x >>= x);
+ assertEquals(-390439413, x %= (tmp = -1225683307, tmp));
+ assertEquals(-84189205, x |= ((x|(2054757858))^(((x<<(((x|x)|(((x>>>((-2938303938.1397676)<<((2993545056)^((tmp = -643895708.5427527, tmp)/((1371449825.5345795)-(1896270238.695752))))))-(tmp = 1061837650, tmp))+(x+(tmp = 3072396681, tmp))))>>(x-((((tmp = -1877865355.1550744, tmp)&x)%(-2766344937))>>>(2055121782)))))-((x<<x)|(tmp = -2742351880.1974454, tmp)))<<((-2600270279.219802)>>(-1625612979)))));
+ assertEquals(-168378410, x += x);
+ assertEquals(-168378410, x &= x);
+ assertEquals(-1534983792, x &= (-1501412943));
+ assertEquals(-1821543761, x ^= (938439487));
+ assertEquals(-1821543761, x &= (x^(((tmp = -4237854, tmp)>>x)/x)));
+ assertEquals(2358, x >>>= (2954252724.620632));
+ assertEquals(4716, x <<= ((-75522382.8757689)/((tmp = 1074334479, tmp)|((tmp = -720387522, tmp)>>(x>>>(-3085295162.6877327))))));
+ assertEquals(-1313079316, x |= (2981887904.020387));
+ assertEquals(-1957790646, x -= (644711330));
+ assertEquals(17831, x >>>= ((tmp = -2550108342, tmp)-(((tmp = 454671414.0146706, tmp)+(-661129693.9333956))>>(x>>>(((tmp = 1752959432.3473055, tmp)*(-2619510342.1812334))%(tmp = -456773274.2411971, tmp))))));
+ assertEquals(689287937.6879716, x -= ((tmp = -397126863.6879716, tmp)-(((x>>x)^(x/(-1387467129.6278908)))|((x>>((tmp = -2361114214.8413954, tmp)<<(tmp = -805670024.4717407, tmp)))<<(-2724018098)))));
+ assertEquals(1378575875.3759432, x += x);
+ assertEquals(84112428460187.8, x *= (((((2681425112.3513584)%(tmp = -1757945333, tmp))|x)>>(-1793353713.0003397))%x));
+ assertEquals(-3221, x >>= (-1976874128));
+ assertEquals(-3221, x %= (((tmp = 2318583056.834932, tmp)|((tmp = -1016115125, tmp)+((-472566636.32567954)+x)))|(tmp = 3135899138.065598, tmp)));
+ assertEquals(-6596608, x <<= x);
+ assertEquals(-1249902592, x <<= (((tmp = -2025951709.5051148, tmp)/((-465639441)<<(-2273423897.9682302)))*((tmp = -2408892408.0294642, tmp)-(tmp = 1017739741, tmp))));
+ assertEquals(73802092170444800, x *= (tmp = -59046275, tmp));
+ assertEquals(-1619001344, x <<= x);
+ assertEquals(0, x <<= (tmp = 1610670303, tmp));
+ assertEquals(-0, x *= ((((x+(tmp = 2039867675, tmp))|(tmp = 399355061, tmp))<<(1552355369.313559))^x));
+ assertEquals(0, x *= x);
+ assertEquals(0, x >>>= (((2875576018.0610805)>>x)%(tmp = -2600467554, tmp)));
+ assertEquals(2290405226.139538, x -= (-2290405226.139538));
+ assertEquals(0, x %= x);
+ assertEquals(0, x ^= (((tmp = 2542309844.485515, tmp)-x)%((-2950029429.0027323)/(tmp = 2943628481, tmp))));
+ assertEquals(0, x += x);
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>>= (tmp = 2337330038, tmp));
+ assertEquals(0, x += (x/(((292272669.0808271)&(tmp = 2923699026.224247, tmp))^(tmp = 367745855, tmp))));
+ assertEquals(0, x &= x);
+ assertEquals(0, x %= ((tmp = 1565155613.3644123, tmp)<<(-308403859.5844681)));
+ assertEquals(-1845345399.3731332, x += (tmp = -1845345399.3731332, tmp));
+ assertEquals(5158590659731951000, x *= (-2795460763.8680177));
+ assertEquals(-364664, x >>= (1837745292.5701954));
+ assertEquals(1, x /= x);
+ assertEquals(-860616114.8182092, x += ((tmp = 2076961323.1817908, tmp)+(-2937577439)));
+ assertEquals(-860616115, x ^= ((x*(tmp = 2841422442.583121, tmp))>>>((tmp = 1929082917.9039137, tmp)>>(-2602087246.7521305))));
+ assertEquals(-38387843, x |= (3114677624));
+ assertEquals(2927507837, x += (tmp = 2965895680, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(-1792887531, x *= (-1792887531));
+ assertEquals(-0, x %= ((x^x)+x));
+ assertEquals(-0, x %= (tmp = 2800752702.562547, tmp));
+ assertEquals(1384510548, x ^= (tmp = 1384510548, tmp));
+ assertEquals(42251, x >>= (1645421551.363844));
+ assertEquals(0, x >>>= (17537561));
+ assertEquals(-2076742862, x ^= (tmp = 2218224434, tmp));
+ assertEquals(-2.790313825067623, x /= (744268563.3934636));
+ assertEquals(5313538, x &= (((((tmp = -2406579239.0691676, tmp)+((-1470174628)+(((tmp = -783981599, tmp)<<(tmp = -1789801141.272646, tmp))^(((((((tmp = -844643189.5616491, tmp)&(tmp = -252337862, tmp))&(x|x))%((-3159642145.7728815)+(tmp = 2149920003.9525595, tmp)))&(x>>(1737589807.9431858)))-((((((((1610161800)<<(497024994))>>x)<<x)/x)>>>x)&x)-(757420763.2141517)))-(tmp = -3061016994.9596977, tmp)))))/(tmp = 1810041920.4089384, tmp))&(tmp = 5887654.786785364, tmp))&((tmp = 1626414403.2432103, tmp)+(x%x))));
+ assertEquals(-2147483648, x <<= (tmp = 1304102366.8011155, tmp));
+ assertEquals(-208418816, x %= (((((-2850404799)*(x+(3158771063.226051)))*(-2017465205))/(x>>x))>>(x%(tmp = 2760203322, tmp))));
+ assertEquals(-2189223477, x -= (1980804661));
+ assertEquals(-859239912, x ^= (tmp = 2974421971.3544703, tmp));
+ assertEquals(-1599850415, x ^= (tmp = -2475871671.140151, tmp));
+ assertEquals(-1600636847, x += ((((tmp = -1311002944, tmp)<<((tmp = -1137871342, tmp)<<(tmp = 115719116, tmp)))/(413107255.6242596))<<(x>>((((-1908022173)&(((-1519897333)^((x>>(x*(tmp = -2886087774.426503, tmp)))*(tmp = 530910975, tmp)))+(-2579617265.889692)))+((2518127437.127563)>>>((tmp = 481642471.56441486, tmp)>>>(792447239))))^(x<<(248857393.6819017))))));
+ assertEquals(-191, x >>= (-1591265193));
+ assertEquals(-192.27421813247196, x += ((tmp = 2627329028.207775, tmp)/(tmp = -2061914644.9523563, tmp)));
+ assertEquals(1230613220, x ^= (tmp = 3064354212.307105, tmp));
+ assertEquals(1230613220, x &= x);
+ assertEquals(1230613220, x %= (1833479205.1064768));
+ assertEquals(1230613220, x >>>= ((((1559450742.1425748)|((2151905260.956583)*(1213275165)))%(514723483.12764716))>>>x));
+ assertEquals(1230613493, x |= ((((3004939197.578903)*(tmp = -576274956, tmp))+((tmp = 1037832416.2243971, tmp)^x))>>>(tmp = 2273969109.7735467, tmp)));
+ assertEquals(2461226986, x += x);
+ assertEquals(-27981, x >>= ((692831755.8048055)^((tmp = -1593598757, tmp)%(x-((((-1470536513.882593)|((tmp = -2716394020.466401, tmp)|(tmp = 2399097686, tmp)))&x)%x)))));
+ assertEquals(-1.4660454948034359e+23, x *= (((x>>>((((((tmp = -3056016696, tmp)<<(-2882888332))*(2041143608.321916))&(((tmp = -634710040, tmp)|(tmp = -2559412457, tmp))>>(1916553549.7552106)))%((-2150969350.3643866)*x))<<((x*(tmp = 2657960438.247278, tmp))|x)))%((tmp = 526041379, tmp)*(tmp = 2514771352.4509397, tmp)))*(1219908294.8107886)));
+ assertEquals(-1.4660454948034359e+23, x -= ((1709004428)>>(((x|(-422745730.626189))%x)>>x)));
+ assertEquals(-2247766068, x %= (-3105435508));
+ assertEquals(-386845856.0649812, x -= (-1860920211.9350188));
+ assertEquals(-386846803.0649812, x -= ((((-3214465921)|((tmp = -1326329034, tmp)+(((tmp = -1203188938.9833462, tmp)%((((((-1318276502)+(x+x))^((x<<x)%(x>>>x)))+(tmp = -439689881, tmp))+((-1455448168.695214)^(x-((-388589993)>>((((940252202)^(-2218777278))|x)/(tmp = -1007511556, tmp))))))&(-140407706.28176737)))-(x/((888903270.7746506)-((tmp = -2885938478.632409, tmp)<<(((((tmp = -1750518830.270917, tmp)>>(((((((tmp = 868557365.7908674, tmp)/(tmp = -2805687195.5172157, tmp))*x)|((((((-1342484550)-((tmp = 1089284576, tmp)^(tmp = 120651272, tmp)))<<(tmp = 2230578669.4642825, tmp))-(x*x))%(x^(((tmp = -3177941534, tmp)+(x>>(-1595660968)))/(-1738933247))))>>>(tmp = 2860175623, tmp)))-(((2392690115.8475947)>>>(tmp = -1754609670.2068992, tmp))>>>(tmp = 2615573062, tmp)))-(tmp = 2590387730, tmp))^((x+((((x-(tmp = -2823664112.4548965, tmp))*(200070977))>>>(((x|((((tmp = 1361398, tmp)>>((tmp = 1649209268, tmp)%x))+x)+(x>>>(tmp = -2379989262.1245675, tmp))))|(x^((tmp = -647953298.7526417, tmp)-x)))&(tmp = -1881232501.1945808, tmp)))>>>x))%(x^(tmp = -1737853471.005935, tmp)))))>>>(427363558))>>>((tmp = -3076726422.0846386, tmp)^(-1518782569.1853383)))/x)))))))|x)>>>(1854299126)));
+ assertEquals(-386846803.0649812, x -= (x%x));
+ assertEquals(238532, x >>>= (-448890706.10774803));
+ assertEquals(232, x >>>= (-791593878));
+ assertEquals(232, x <<= (((x^((x-x)&(tmp = 1219114201, tmp)))/(tmp = -427332955, tmp))%(tmp = 1076283154, tmp)));
+ assertEquals(210, x ^= (x>>>((2975097430)>>>x)));
+ assertEquals(1, x /= x);
+ assertEquals(2317899531, x *= (2317899531));
+ assertEquals(1131786, x >>>= x);
+ assertEquals(2301667519.6379366, x += ((tmp = 193109669.63793683, tmp)+(tmp = 2107426064, tmp)));
+ assertEquals(3842614963.6379366, x += (((-1676516834)>>>(tmp = -1817478916.5658965, tmp))^(((tmp = 1122659711, tmp)>>>(tmp = -2190796437, tmp))|(tmp = -2754023244, tmp))));
+ assertEquals(-452352333, x &= x);
+ assertEquals(-863, x >>= x);
+ assertEquals(-3.777863669459606e-7, x /= (2284359827.424491));
+ assertEquals(-3.777863669459606e-7, x %= ((tmp = -2509759238, tmp)>>>x));
+ assertEquals(0, x <<= (-814314066.6614306));
+ assertEquals(0, x %= (tmp = 190720260, tmp));
+ assertEquals(2301702913, x += (2301702913));
+ assertEquals(-249158048, x >>= (tmp = -2392013853.302008, tmp));
+ assertEquals(-249158048, x >>= x);
+ assertEquals(-498316096, x += x);
+ assertEquals(-498316096, x %= (tmp = 2981330372.914731, tmp));
+ assertEquals(106616.2199211318, x *= (((((tmp = 1020104482.2766557, tmp)^((tmp = -416114189.96786, tmp)>>>(1844055704)))|(tmp = 1665418123, tmp))>>(1826111980.6564898))/(-2446724367)));
+ assertEquals(106616, x |= x);
+ assertEquals(1094927345, x -= (((-1229759420)|(741260479.7854375))-x));
+ assertEquals(8353, x >>= x);
+ assertEquals(0, x >>>= (tmp = -327942828, tmp));
+ assertEquals(-953397616.8888416, x += (tmp = -953397616.8888416, tmp));
+ assertEquals(-1906641240.7776833, x += (x+((-3033450184.9106326)>>>(tmp = 2090901325.5617187, tmp))));
+ assertEquals(-1906641240.7776833, x %= (tmp = 2584965124.3953505, tmp));
+ assertEquals(-1098907671, x |= (tmp = -1272590495, tmp));
+ assertEquals(-1.8305258600334393, x /= (600323489));
+ assertEquals(-1, x &= x);
+ assertEquals(-1, x |= ((x+x)-x));
+ assertEquals(1, x *= x);
+ assertEquals(867473898, x ^= (tmp = 867473899.0274491, tmp));
+ assertEquals(6, x >>>= (tmp = 1174763611.341228, tmp));
+ assertEquals(0, x >>= ((689882795)^(2250084531)));
+ assertEquals(0, x /= (tmp = 2545625607, tmp));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x += x);
+ assertEquals(0, x -= (x*(-1098372339.5157008)));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x -= (tmp = -1797344676.375759, tmp));
+ assertEquals(1121476698, x |= (tmp = 1121476698, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(1, x &= (-191233693));
+ assertEquals(330137888.92595553, x += (330137887.92595553));
+ assertEquals(-1792236714, x ^= (tmp = 2256609910, tmp));
+ assertEquals(269000724, x &= (316405813.62093115));
+ assertEquals(256, x >>= x);
+ assertEquals(256, x %= ((2556320341.54669)|(1066176021.2344948)));
+ assertEquals(256, x |= x);
+ assertEquals(131072, x <<= ((-1650561175.8467631)|x));
+ assertEquals(-286761951, x -= ((tmp = 287024095, tmp)-((-2293511421)&(x|x))));
+ assertEquals(-1561852927, x &= (3002663949.0989227));
+ assertEquals(-460778761, x %= (tmp = -550537083, tmp));
+ assertEquals(-3023749308.0492287, x += (tmp = -2562970547.0492287, tmp));
+ assertEquals(-481313332.04922867, x %= ((x|((tmp = -855929299, tmp)%((2181641323)%(x|(220607471.33018696)))))&x));
+ assertEquals(17510668, x &= (tmp = 363557663, tmp));
+ assertEquals(12552, x &= (3020225307));
+ assertEquals(1814655896, x |= ((x<<(((-1475967464)*(-3122830185))*x))+(x^(-2480340864.2661023))));
+ assertEquals(-3209124403525266400, x -= ((1146847590)*(tmp = 2798213497, tmp)));
+ assertEquals(-6418248807050533000, x += x);
+ assertEquals(1.1856589432073933e+28, x *= (-1847324681.313275));
+ assertEquals(-1238853292, x ^= (-1238853292));
+ assertEquals(-77428331, x >>= (x&((((2043976651.8514216)>>>x)^(x>>>(((tmp = -1785122464.9720652, tmp)%x)<<(1570073474.271266))))*x)));
+ assertEquals(2011, x >>>= x);
+ assertEquals(2011, x &= x);
+ assertEquals(0, x >>= (-2682377538));
+ assertEquals(-1.1367252770299785, x -= (((tmp = 2704334195.566802, tmp)/(2379056972))%((((-1764065164)*((((468315142.8822602)>>((x%(((tmp = 2537190513.506641, tmp)+((x&(x|((tmp = -947458639, tmp)^(2653736677.417406))))*((x<<((1243371170.1759553)>>>(((tmp = 1572208816, tmp)<<((tmp = 963855806.1090456, tmp)>>>x))%((-3078281718.7743487)*x))))^(-1154518374))))^(-2839738226.6314087)))^((-2865141241.190915)*(-2400659423.8207664))))>>((tmp = 32940590, tmp)/(tmp = 2917024064.570817, tmp)))+(((27601850)/(tmp = 3168834986, tmp))>>x)))+(tmp = 2528181032.600125, tmp))/(3162473952))));
+ assertEquals(-1697395408.7948515, x -= (1697395407.6581264));
+ assertEquals(1536992607912062500, x *= (tmp = -905500627.5781817, tmp));
+ assertEquals(102759872, x >>= (tmp = -707887133.4484048, tmp));
+ assertEquals(102759872, x %= (tmp = -1764067619.7913327, tmp));
+ assertEquals(12543, x >>>= (-144142995.1469829));
+ assertEquals(-2059555229.2592103, x += ((-2059555229.2592103)-x));
+ assertEquals(-537022593, x |= (tmp = -2770761410.407701, tmp));
+ assertEquals(23777505, x ^= (-560496738.6854918));
+ assertEquals(-64329014115772310, x *= ((tmp = -2729234369.198843, tmp)+x));
+ assertEquals(189083830, x ^= (tmp = 933619934, tmp));
+ assertEquals(189083830, x %= ((tmp = -2918083254, tmp)-(x|(x^(-2481479224.0329475)))));
+ assertEquals(378167660, x += x);
+ assertEquals(-0.45833387791900504, x /= ((tmp = 2727991875.241294, tmp)<<(tmp = 2570034571.9084663, tmp)));
+ assertEquals(0, x <<= x);
+ assertEquals(-0, x /= (tmp = -67528553.30662966, tmp));
+ assertEquals(0, x <<= (938440044.3983492));
+ assertEquals(-945479171, x ^= (tmp = -945479171, tmp));
+ assertEquals(-225632619284361200, x *= (238643670.00884593));
+ assertEquals(-0, x %= x);
+ assertEquals(-585826304, x ^= ((-1256265560)<<(tmp = 1144713549, tmp)));
+ assertEquals(-671583855, x ^= (183333265.1468178));
+ assertEquals(-484311040, x <<= x);
+ assertEquals(-3969762.62295082, x /= ((((tmp = -1164308668.931008, tmp)-x)%x)>>>(((397816647)>>(-1605343671.4070785))<<x)));
+ assertEquals(758097879, x ^= ((tmp = -2871307491, tmp)^(-2043176492.646442)));
+ assertEquals(0, x *= ((x>>(tmp = 1983292927, tmp))&(tmp = -860505131.4484091, tmp)));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x &= x);
+ assertEquals(0, x %= ((3132981707)-(-2832016477)));
+ assertEquals(0, x >>= (x<<((1830195133.0342631)>>>(tmp = -1003969250, tmp))));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x += (tmp = 273271019.87603223, tmp));
+ assertEquals(NaN, x += (625749326.1155348));
+ assertEquals(0, x >>= (tmp = -531039433.3702333, tmp));
+ assertEquals(0, x -= (((tmp = 2029464099, tmp)-(x-(tmp = -329058111.411458, tmp)))*(x<<x)));
+ assertEquals(-0, x *= ((-1112957170.5613296)|((tmp = 847344494, tmp)>>>(tmp = 2735119927, tmp))));
+ assertEquals(-0, x /= (tmp = 544636506, tmp));
+ assertEquals(0, x >>>= (x^(545093699)));
+ assertEquals(0, x %= (((tmp = -2208409647.5052004, tmp)+(3083455385.374988))+(((-482178732.7077277)*x)>>>((2661060565)*(-2125201239)))));
+ assertEquals(0, x >>>= (-212334007.34016395));
+ assertEquals(0.7004300865203454, x -= ((2032883941)/(-2902336693.0154715)));
+ assertEquals(0, x <<= (x<<((265868133.50175047)>>>(1162631094))));
+ assertEquals(604920272.4394834, x -= (-604920272.4394834));
+ assertEquals(604920272, x &= x);
+ assertEquals(0, x <<= (((-1961880051.1127694)%(tmp = 1715021796, tmp))|((tmp = 2474759639.4587016, tmp)|(243416152.55635))));
+ assertEquals(-46419074, x |= (((tmp = -518945938.5238774, tmp)%((x+(tmp = 242636408, tmp))+(-1974062910)))|(1546269242.0259726)));
+ assertEquals(-46419074, x += ((-629802130)*((tmp = -658144149, tmp)%((-905005358.5370393)>>>x))));
+ assertEquals(-46419074, x |= (x%(-1103652494)));
+ assertEquals(7892881050983985, x *= (-170035297.36469936));
+ assertEquals(1105701997.4273424, x %= ((((-490612260.0023911)>>>(tmp = 1803426906, tmp))^(x%(2725270344.2568116)))-(1010563167.8934317)));
+ assertEquals(1088619532, x &= (-2232199650));
+ assertEquals(1073807364, x &= (-888024506.5008001));
+ assertEquals(1153062254980628500, x *= x);
+ assertEquals(1153062255703627000, x -= (tmp = -722998613.897227, tmp));
+ assertEquals(-1141418584, x |= (3017232552.4814596));
+ assertEquals(-373464140, x ^= (-2914372068));
+ assertEquals(994050048, x <<= x);
+ assertEquals(0, x ^= x);
+ assertEquals(0, x &= (tmp = -3166402389, tmp));
+ assertEquals(0, x &= ((-1760842506.337213)|(tmp = 2538748127.795164, tmp)));
+ assertEquals(-0, x /= (-2635127769.808626));
+ assertEquals(0, x &= ((((tmp = 1414701581, tmp)^(((2425608769)/((x<<x)^(x-x)))^((tmp = -2641946468.737288, tmp)|(tmp = -313564549.1754241, tmp))))*(tmp = -2126027460, tmp))|(-2255015479)));
+ assertEquals(225482894, x ^= (225482894.8767246));
+ assertEquals(0, x ^= x);
+ assertEquals(306216231, x += (tmp = 306216231, tmp));
+ assertEquals(306216231, x -= ((-465875275.19848967)&((-806775661.4260025)/((((-184966089.49763203)>>>((x>>x)+((tmp = -1951107532, tmp)|x)))%x)*((2704859526.4047284)%((x*x)>>x))))));
+ assertEquals(30754, x &= (1706162402.033193));
+ assertEquals(30454.010307602264, x -= (((590456519)>>>(tmp = 2713582726.8181214, tmp))/x));
+ assertEquals(8419062, x |= ((2848886788)<<(tmp = 2993383029.402275, tmp)));
+ assertEquals(16, x >>= (tmp = -1651287021, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(-1407643485, x ^= (-1407643486));
+ assertEquals(2, x >>>= (-1126004674));
+ assertEquals(470812081, x ^= ((-2411718964)>>>x));
+ assertEquals(550443688.6407901, x += (tmp = 79631607.6407901, tmp));
+ assertEquals(3669092443.64079, x -= (-3118648755));
+ assertEquals(-625874853, x <<= (((tmp = -1640437346, tmp)/(((x*x)>>>x)<<x))/x));
+ assertEquals(-1431439050363516700, x *= (2287101077));
+ assertEquals(-1921660672, x |= ((((((((-1912249689.9978154)&(-1676922742.5343294))*(2625527768))<<((820676465)^(((x+(tmp = -852743692, tmp))&((x-((((1361714551)/(311531668))>>>(tmp = -1330495518.8175917, tmp))<<(((tmp = 1369938417.8760853, tmp)*(-1217947853.8942266))<<(-2048029668))))-(-513455284)))>>>(tmp = 1980267333.6201067, tmp))))<<(((1503464217.2901971)>>(tmp = 2258265389, tmp))>>>(1868451148)))&(x-(x^(tmp = -1565209787, tmp))))*x)<<(tmp = -2426550685, tmp)));
+ assertEquals(-1921660672, x %= (((tmp = 523950472.3315773, tmp)+(((2971865706)^x)-x))&(-1773969177)));
+ assertEquals(420176973.1169958, x += (2341837645.116996));
+ assertEquals(420176973, x >>>= (((tmp = -2485489141, tmp)<<((tmp = -2520928568.360244, tmp)+x))&(543950045.0932506)));
+ assertEquals(50, x ^= (x|((tmp = 2001660699.5898843, tmp)>>>(tmp = 1209151128, tmp))));
+ assertEquals(138212770720.96973, x *= (2764255414.4193945));
+ assertEquals(-28683, x |= (((-535647551)|x)>>((((2065261509)>>(-354214733))*x)+(-3218217378.2592907))));
+ assertEquals(1627048838, x ^= (tmp = -1627044749, tmp));
+ assertEquals(-839408795, x ^= (2903337187.480303));
+ assertEquals(-1000652427, x += (tmp = -161243632, tmp));
+ assertEquals(740237908.4196916, x += ((tmp = 1587000348, tmp)+(tmp = 153889987.41969144, tmp)));
+ assertEquals(Infinity, x /= (((((-615607376.1012697)&(57343184.023578644))+((-1967741575)|(-3082318496)))<<(((tmp = -958212971.99792, tmp)>>(tmp = 2962656321.3519197, tmp))-(x|(x*(969365195)))))<<(tmp = -1739470562.344624, tmp)));
+ assertEquals(-Infinity, x /= ((tmp = -1736849852, tmp)%x));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x %= (tmp = -226505646, tmp));
+ assertEquals(1982856549, x -= (((x+(-1982856549))%(-2274946222))>>(x%(((tmp = -1289577208.9097936, tmp)>>x)^(778147661)))));
+ assertEquals(1648018703, x ^= ((3085618856)+((tmp = 1546283467, tmp)&(((x|((-2376306530)*(((((((tmp = -2807616416, tmp)%(((((tmp = 347097983.1491085, tmp)<<x)|(((((1135380667)/(x>>>(tmp = 1679395106, tmp)))^((1277761947)<<((tmp = -1614841203.5244312, tmp)>>x)))%((tmp = 1552249234.2065845, tmp)>>>x))>>>(tmp = -1677859287, tmp)))>>>(2605907565))/(tmp = 2291657422.221277, tmp)))%(((tmp = 425501732.6666014, tmp)>>>(1327403879.455553))+x))>>((tmp = -3075752653.2474413, tmp)&(x-(tmp = -71834630, tmp))))|((((2532199449.6500597)*(-842197612.4577162))%x)>>x))*(((1220047194.5100307)<<((tmp = 1642962251, tmp)<<((-662340)>>>((tmp = -1672316631.3251066, tmp)<<((tmp = 1762690952.542441, tmp)-(x/(1904755683.3277364)))))))>>x))|(((((tmp = 1625817700.7052522, tmp)%(tmp = -2990984460, tmp))|(2395645662))-((2619930607.550086)>>x))^(tmp = 130618712, tmp)))))&((-3142462204.4628367)/(1078126534.8819227)))%(((tmp = -256343715.2267704, tmp)+x)^(tmp = 2009243755, tmp))))));
+ assertEquals(1937698223, x |= (((tmp = 866354374.7435778, tmp)+(tmp = 2751925259.3264275, tmp))%(-2252220455)));
+ assertEquals(0, x -= x);
+ assertEquals(-823946290.6515498, x -= (tmp = 823946290.6515498, tmp));
+ assertEquals(706970324, x ^= (-457174758));
+ assertEquals(32916, x &= (25740724));
+ assertEquals(0, x >>>= ((-1658933418.6445677)|(tmp = -846929510.4794133, tmp)));
+ assertEquals(0, x ^= ((-834208600)/((-1256752740)&(tmp = 1973248337.8973258, tmp))));
+ assertEquals(-1639195806, x += (-1639195806));
+ assertEquals(-1559416478, x ^= ((tmp = 1349893449.0193534, tmp)*(tmp = 2044785568.1713037, tmp)));
+ assertEquals(0, x &= ((x>>(tmp = 1720833612, tmp))/((x+(-1305879952.5854573))^x)));
+ assertEquals(-0, x *= (tmp = -1713182743, tmp));
+ assertEquals(0, x >>= x);
+ assertEquals(NaN, x /= (((x%((x>>>(((-1515761763.5499895)^(-3076528507.626539))<<(tmp = 1293944457.8983147, tmp)))<<(tmp = 276867491.8483894, tmp)))>>(tmp = -2831726496.6887417, tmp))%((((tmp = 1780632637.3666987, tmp)^x)%((208921173.18897665)>>(tmp = 633138136, tmp)))+x)));
+ assertEquals(0, x >>= (tmp = -2755513767.0561147, tmp));
+ assertEquals(0, x |= x);
+ assertEquals(840992300.0324914, x -= ((-840992300.0324914)+x));
+ assertEquals(840992300, x &= x);
+ assertEquals(-1094140277, x ^= (2364029095));
+ assertEquals(-Infinity, x /= ((((((1257084956)<<(2009241695))>>(x+x))*x)>>>x)>>>(205318919.85870552)));
+ assertEquals(-Infinity, x -= (((x>>>(tmp = 3037168809.20163, tmp))&x)*(x&(((806151109)*x)-(tmp = -1741679480.58333, tmp)))));
+ assertEquals(400659949, x ^= (tmp = 400659949, tmp));
+ assertEquals(5, x >>= (tmp = 1175519290, tmp));
+ assertEquals(5, x |= x);
+ assertEquals(0, x >>= x);
+ assertEquals(0, x >>= ((1317772443)&(x<<x)));
+ assertEquals(-1123981819, x ^= (tmp = 3170985477, tmp));
+ assertEquals(1123864651, x ^= ((x%(((x&x)&(-2606227299.7590737))<<((tmp = -2018123078.1859496, tmp)*x)))|(x+(((((1935939774.8139446)/((-1303958190)/(2802816697.32639)))<<((2880056582)*x))+x)+x))));
+ assertEquals(1543368927, x |= (-2795691884));
+ assertEquals(NaN, x /= (x%((tmp = -1129915114, tmp)<<x)));
+ assertEquals(NaN, x += (tmp = -3045743135, tmp));
+ assertEquals(NaN, x -= (tmp = -2849555731.8207827, tmp));
+ assertEquals(NaN, x /= (((((2127485827)>>>((((tmp = 363239924, tmp)>>x)|((((tmp = -1419142286.0523334, tmp)-(x<<x))^(tmp = -1990365089.8283136, tmp))*((tmp = 2780242444.0739098, tmp)>>>(((-2336511023.342298)&x)/(tmp = 2296926221.402897, tmp)))))>>((tmp = 1378982475.6839466, tmp)>>(tmp = -816522530, tmp))))&(x^(tmp = -1668642255.0586753, tmp)))%(((tmp = 921249300.1500335, tmp)^x)*(tmp = -2228816905, tmp)))>>x));
+ assertEquals(-1460685191, x |= (tmp = 2834282105, tmp));
+ assertEquals(-1463439264, x &= (tmp = 2881860064.146755, tmp));
+ assertEquals(20.98100714963762, x /= (((3017150580.7875347)^((250499372.5339837)<<(tmp = -42767556.30788112, tmp)))|(x%(-2829281526))));
+ assertEquals(1, x /= x);
+ assertEquals(2, x += x);
+ assertEquals(8, x <<= x);
+ assertEquals(0, x >>>= ((730174750)>>>x));
+ assertEquals(0, x ^= x);
+ assertEquals(-1459637373, x ^= (2835329923.456409));
+ assertEquals(-1233115861, x ^= (511678120));
+ assertEquals(95682857, x >>>= ((tmp = 1534570885, tmp)|(tmp = -414425499.3786578, tmp)));
+ assertEquals(70254633, x &= (-1502067585));
+ assertEquals(51384749748909710, x *= (tmp = 731407276, tmp));
+ assertEquals(9390482.873469353, x %= (tmp = -592576964.7982686, tmp));
+ assertEquals(4695241, x >>>= (tmp = -1879898431.5395758, tmp));
+ assertEquals(-3129811912538149000, x += (((-727481809)^((3106908604)%x))*((((tmp = -1218123690, tmp)^(x>>((-942923806)^x)))/(x+x))>>>(-1508881888.969373))));
+ assertEquals(1596870236, x ^= (-1135673764.9721224));
+ assertEquals(0, x ^= x);
+ assertEquals(2133782410, x |= (((-2202469371)>>((tmp = 1327588406.183342, tmp)/(tmp = 253581265.7246865, tmp)))-((tmp = 2226575446.838795, tmp)^x)));
+ assertEquals(-81895217.83608055, x -= (tmp = 2215677627.8360806, tmp));
+ assertEquals(812089344, x <<= ((tmp = 882824005, tmp)/(((x>>((((((((tmp = 1211145185, tmp)/((-137817273)-(((tmp = 2165480503.1144185, tmp)-(-1840859887.1288517))*((155886014.8393339)>>((-1984526598)<<(tmp = 1331249058.3246582, tmp))))))>>(x*x))%(2830324652))%(933701061))|(1346496215))^(tmp = -988800810, tmp))+x))>>>x)<<(-2372088384))));
+ assertEquals(812089344, x <<= x);
+ assertEquals(8472, x %= ((((x|(((x%(tmp = 2772099481.664402, tmp))+(2894690616))-x))&(x&(((-715790638.6454093)>>(tmp = -1447931029, tmp))-(tmp = 1761027889, tmp))))^x)%(((tmp = 830969811, tmp)|x)|((-1102267929)-(3193018687)))));
+ assertEquals(-0.0000028559857417864914, x /= (-2966401364));
+ assertEquals(0, x >>= x);
+ assertEquals(-701800392, x += (tmp = -701800392, tmp));
+ assertEquals(2034756873, x -= (tmp = -2736557265, tmp));
+ assertEquals(-0.9475075048394501, x /= (((((82879340.27231383)+((tmp = -2876678920.653639, tmp)*(-2801097850)))<<x)>>>((x<<(((((x|x)&(tmp = -1572694766, tmp))>>(x+(x/((x-(((tmp = 1435301275, tmp)|(tmp = 983577854.212041, tmp))>>(tmp = 632633852.1644179, tmp)))+x))))>>>x)|(-850932021)))>>x))<<(-821983991)));
+ assertEquals(0, x >>= (x>>(2424003553.0883207)));
+ assertEquals(2599386349, x -= (-2599386349));
+ assertEquals(-68157441, x |= (((tmp = -1170343454.9327996, tmp)+((((tmp = 448468098, tmp)|(x>>(x>>(((x>>(((x/(x&(x<<x)))<<(2436876051.2588806))^(3010167261)))%((tmp = 2577616315.7538686, tmp)>>>(-2953152591.015912)))%((tmp = -1304628613, tmp)/(x&((x|((-2000952119)%((691146914)/((tmp = 1480966978.7766845, tmp)<<((tmp = 2644449477.392441, tmp)|(-2143869305.871568))))))+(tmp = -315254308, tmp))))))))&(-2060205555))|((-604140518.8186448)^(x*x))))%(x*((tmp = 1383244000.2807684, tmp)/(3195793656)))));
+ assertEquals(-68157441, x |= x);
+ assertEquals(-1, x >>= x);
+ assertEquals(-2147483648, x <<= x);
+ assertEquals(-1.5257198286933313, x /= (tmp = 1407521622, tmp));
+ assertEquals(1149084989.47428, x += (((tmp = 1149084991.9004865, tmp)&x)^((((((2797053000)/(x^x))*(-2829253694))>>>((tmp = -610924351, tmp)>>x))>>>(tmp = -675681012, tmp))<<(2812852729))));
+ assertEquals(0, x %= x);
+ assertEquals(0, x <<= ((tmp = -584069073, tmp)*(-2953140326)));
+ assertEquals(0, x <<= (tmp = -481515023.6404002, tmp));
+ assertEquals(-1441535370, x ^= (2853431926));
+ assertEquals(2853431926, x >>>= (((((((tmp = 2215663525.9620194, tmp)%((-1102832735.9274108)/x))>>x)&(3220898702.76322))&(((2077584946)*((x>>x)<<((tmp = 1845701049, tmp)-x)))/(tmp = 1947184202.5737212, tmp)))|(((tmp = 2976351488, tmp)^(-42517339))%((2648230244.410125)^(1520051731.31089))))/(1761635964)));
+ assertEquals(43539, x >>>= (tmp = 1361671184.7432632, tmp));
+ assertEquals(21769, x >>= ((tmp = -804932298.9572575, tmp)>>((((tmp = 1749006993.253409, tmp)+(276536978))^x)|(2698166994))));
+ assertEquals(1103025563, x |= (tmp = 1103007891, tmp));
+ assertEquals(1327594607, x += (tmp = 224569044, tmp));
+ assertEquals(1327594607, x |= x);
+ assertEquals(-478674944, x <<= (((672378508)&x)^(((-2070209708.6470091)|x)|(x>>>x))));
+ assertEquals(-478674943, x ^= ((-1832457698.6345716)>>>((tmp = -3077714019, tmp)/(1809383028))));
+ assertEquals(229129701056053250, x *= x);
+ assertEquals(1, x /= x);
+ assertEquals(2, x <<= (-1522529727));
+ assertEquals(2, x &= x);
+ assertEquals(-2016989182, x |= ((((tmp = -1267845511, tmp)*(1225350332))+((tmp = -1397690831.5717893, tmp)>>>(tmp = -2575382994, tmp)))+x));
+ assertEquals(-241, x >>= (tmp = 931869591, tmp));
+ assertEquals(-1048087547, x &= (tmp = -1048087403.1163051, tmp));
+ assertEquals(-4004486369.844599, x += (tmp = -2956398822.844599, tmp));
+ assertEquals(-4004486368.844599, x -= (((2701878498)>>x)|(x|(-1079354967))));
+ assertEquals(1, x >>= (tmp = -1583689092, tmp));
+ assertEquals(1, x *= (x>>(x%x)));
+ assertEquals(0, x %= x);
+ assertEquals(-0, x *= (-120818969));
+ assertEquals(0, x >>= ((tmp = 1794099660, tmp)/(((x&(((-321906091)^(tmp = -3009885933.8449526, tmp))&((tmp = -140917780, tmp)|(2037803173.4075825))))&x)&(tmp = -745357154, tmp))));
+ assertEquals(0, x <<= (563984257.3493614));
+ assertEquals(NaN, x %= ((((x>>(tmp = -2190891392.320677, tmp))-x)<<(462714956))<<((tmp = -84413570, tmp)|((x|(-2787022855))-((tmp = 2028532622, tmp)|(tmp = 1103757073.9178817, tmp))))));
+ assertEquals(NaN, x *= ((2137674085.3142445)|((tmp = -1054749859.2353804, tmp)%x)));
+ assertEquals(NaN, x /= (x>>>(((((tmp = 597103360.9069608, tmp)>>>(-2850217714.1866236))-((tmp = 1125150527, tmp)*x))%(tmp = -982662312, tmp))|((x/(((968656808.6069037)*(((128484784.15362918)>>x)^x))&((((x/((((tmp = 748775979, tmp)*((x-(((tmp = 709571811.9883962, tmp)%(-2083567026))%(x/(tmp = -680467505, tmp))))/((tmp = -167543858, tmp)/(tmp = -3113588783, tmp))))/x)<<(-2605415230)))>>>(tmp = 3133054172, tmp))%(tmp = -1904650393, tmp))*((x|(-1193709562))*(tmp = -1731312795.718104, tmp)))))/((tmp = -672386301, tmp)/(tmp = 808898833.4163612, tmp))))));
+ assertEquals(-9, x |= (((((tmp = 150377964.57195818, tmp)/(tmp = 2161910879.0514045, tmp))-(-2381625849))>>(-2715928517))/(((452113643)^(-2502232011))/((-3076471740)^(((tmp = 1664851172, tmp)*(((-1460011714)>>>x)<<((-2870606437)%x)))*((tmp = -2836565755.609597, tmp)-((x/(tmp = -871461415, tmp))-(2278867564))))))));
+ assertEquals(-1, x >>= x);
+ assertEquals(-1, x |= ((-1319927272)>>>(-2866709980)));
+ assertEquals(-1, x >>= ((2345179803.155703)&(-978025218.2243443)));
+ assertEquals(1, x /= x);
+ assertEquals(-260730973, x |= (tmp = -260730973, tmp));
+ assertEquals(1174405120, x <<= (2681054073));
+ assertEquals(1174405120, x &= x);
+ assertEquals(1073741824, x &= (tmp = 2017166572.7622075, tmp));
+ assertEquals(1073741824, x |= x);
+ assertEquals(168806102, x %= ((((tmp = -2939969193.950067, tmp)|((-2325174027.614815)/(-2329212715)))*(x/(((((-2927776738)/(x|x))+(x%(tmp = -3007347037.698492, tmp)))<<(-1898633380))>>(tmp = 204338085.45241892, tmp))))^x));
+ assertEquals(168806102, x %= ((-832849739.5197744)&(tmp = -141908598, tmp)));
+ assertEquals(-401033205.05225074, x -= (tmp = 569839307.0522507, tmp));
+ assertEquals(-401033205, x &= x);
+ assertEquals(-401130402, x ^= ((x*(tmp = 311418759.22436893, tmp))>>x));
+ assertEquals(793533469, x ^= (-950312893.5201888));
+ assertEquals(756, x >>>= (-1096189516));
+ assertEquals(711, x += ((tmp = -753105189, tmp)>>(599823192.5381484)));
+ assertEquals(0, x >>>= ((tmp = -2859668634.4641137, tmp)+(-1160392986.1521513)));
+ assertEquals(2427599726.176195, x -= (-2427599726.176195));
+ assertEquals(1942312465.2523103, x -= (485287260.92388475));
+ assertEquals(0, x >>>= ((tmp = -1740656456, tmp)/(tmp = 1339746799.9335847, tmp)));
+ assertEquals(0, x <<= ((-7017077.38786912)*((-699490904.4551768)^x)));
+ assertEquals(0, x <<= (tmp = 715662384, tmp));
+ assertEquals(0, x *= (x>>>(2149735450.0758677)));
+ assertEquals(NaN, x /= x);
+ assertEquals(0, x >>= ((397078885)*((851639692.8982519)-x)));
+ assertEquals(0, x &= (-2526654445));
+ assertEquals(0, x %= (-1204924598));
+ assertEquals(251639720, x ^= (x|(tmp = 251639720, tmp)));
+ assertEquals(695433573, x ^= (663539405));
+ assertEquals(-1038050104, x -= (1733483677));
+ assertEquals(0, x ^= x);
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x &= (392107269));
+ assertEquals(0, x %= (-3084908458.241551));
+ assertEquals(0, x ^= x);
+ assertEquals(-2121660509, x ^= (tmp = -2121660509.7861986, tmp));
+ assertEquals(2285041855588855800, x *= (x|(3209046634)));
+ assertEquals(54915072, x >>>= (x%(((((x%((((tmp = -1429433339.5078833, tmp)|(tmp = 2906845137, tmp))^(3207260333))&(-848438650)))-(-2721099735))&(141851917.19978714))+x)/x)));
+ assertEquals(54915072, x &= x);
+ assertEquals(54915072, x %= (x+(1855489160)));
+ assertEquals(70078753, x ^= ((((((-1648661736)+(x%((-1421237596)+(tmp = 2053180992.3857927, tmp))))+(tmp = 38606889, tmp))<<((-241334284)%((x>>(215316122))*(tmp = 396488307, tmp))))+((tmp = -2900704565, tmp)^x))^(((1103481003.1111188)^x)-(tmp = 1304113534, tmp))));
+ assertEquals(1149501440, x <<= ((x>>(tmp = 3203172843, tmp))*(tmp = -192535531, tmp)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x >>= ((tmp = 2751499787, tmp)&((tmp = 2217654798, tmp)*(tmp = -2798728014, tmp))));
+ assertEquals(NaN, x /= ((((-2019592425)>>>((((-1571930240.741224)>>>((-183952981)/((((1990518443.672842)>>(((((2051371284)%(685322833.6793983))>>>(2662885938))<<(-1212029669.6675105))|((-2790877875)<<(1546643473))))<<x)-(tmp = 804296674.4579233, tmp))))-(tmp = -417759051.68770766, tmp))/((-621859758)>>>x)))&x)<<(tmp = -48558935.55320549, tmp)));
+ assertEquals(0, x <<= (x&x));
+ assertEquals(0, x *= (x%(tmp = 301196068, tmp)));
+ assertEquals(398290944, x |= (((tmp = 1904146839, tmp)+(1521017178))*(-3174245888.562067)));
+ assertEquals(1256401076, x ^= (1566464180));
+ assertEquals(149620758, x %= ((tmp = 532626355, tmp)^(tmp = -382971203, tmp)));
+ assertEquals(149620791, x |= (x>>x));
+ assertEquals(-0.07034576194938641, x /= ((tmp = -1977313182.7573922, tmp)-x));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x &= x);
+ assertEquals(0, x /= ((2182424851.139966)%(((-2768516150)+x)>>>x)));
+ assertEquals(0, x %= (-504299638.53962016));
+ assertEquals(-0, x *= (-2915134629.6909094));
+ assertEquals(0, x <<= ((tmp = 952692723.402582, tmp)%(2146335996.785011)));
+ assertEquals(230457472, x |= ((tmp = -574776101.8681948, tmp)*(683185125)));
+ assertEquals(933795934, x ^= (tmp = 974395614, tmp));
+ assertEquals(933801974, x ^= (x>>>((-148683729)*(((tmp = 2912596991.415531, tmp)^(-2883672328))/x))));
+ assertEquals(222, x >>= (-3060224682));
+ assertEquals(27, x >>>= (1429156099.1338701));
+ assertEquals(754519106, x ^= (tmp = 754519129.7281355, tmp));
+ assertEquals(188629776, x >>>= ((x>>>((1247267193)<<(tmp = -936228622, tmp)))%((tmp = 978604324.8236886, tmp)*((tmp = -3018953108, tmp)^(((tmp = 259650195, tmp)>>>(tmp = 2762928902.7901163, tmp))*(x>>((tmp = 787444263.5542864, tmp)/(x>>>(((-2039193776)<<(tmp = -1408159169, tmp))-(1238893783))))))))));
+ assertEquals(188629775.33987066, x += ((tmp = 1040520414, tmp)/((-1576237184)|((tmp = -970083705, tmp)&(((tmp = -312062761.12228274, tmp)|(1171754278.2968853))<<(-2069846597.7723892))))));
+ assertEquals(1473670, x >>>= ((tmp = 202409672, tmp)^x));
+ assertEquals(2171703268900, x *= (x>>(((tmp = 840468550, tmp)&(-3208057101.2136793))/x)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x ^= (x&((tmp = 2569871408.2405066, tmp)|((tmp = -3149374622, tmp)<<(x-(x|((tmp = -821239139.1626894, tmp)>>>x)))))));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x %= (tmp = 1926106354, tmp));
+ assertEquals(0, x >>= ((x/(-2848416))/(tmp = 2484293767, tmp)));
+ assertEquals(0, x <<= ((tmp = -2484137114, tmp)>>>(tmp = -887083772.8318355, tmp)));
+ assertEquals(0, x >>= (tmp = -2651389432, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(1041871201, x += ((tmp = 1041871201.9272791, tmp)|(x<<(-1136959830))));
+ assertEquals(651390879501530900, x *= ((tmp = 1250424964.0346212, tmp)>>x));
+ assertEquals(1965815296.245636, x %= ((2650603245.655831)+((-1610821947.8640454)>>>(((878987151.6917406)*((((784630543)%(((1448720244)>>(((tmp = 3036767847, tmp)+((tmp = 1012548422, tmp)<<(1957000200)))-x))/(x>>x)))<<((tmp = 914710268, tmp)*(((x^(1559603121))<<(tmp = 3181816736, tmp))|((-1964115655)+x))))-(-1055603890)))&(946797797.0616649)))));
+ assertEquals(1965815296.245636, x %= (tmp = -2601038357.593118, tmp));
+ assertEquals(-769384440.872302, x += (-2735199737.117938));
+ assertEquals(-769384440.872302, x %= (2193123162));
+ assertEquals(1, x /= x);
+ assertEquals(1, x -= (((x>>>(-1968465925))*((tmp = 563037904, tmp)>>((tmp = 3009534415.769578, tmp)>>((-2567240601.7038674)<<(tmp = -1258402723.4150183, tmp)))))%(3112239470.276867)));
+ assertEquals(1, x |= x);
+ assertEquals(1505461527, x ^= (tmp = 1505461526.5858076, tmp));
+ assertEquals(406553877, x &= (tmp = 2558242293, tmp));
+ assertEquals(406553877, x |= x);
+ assertEquals(-574902339, x |= ((-709809495)%(tmp = -2880884811.410611, tmp)));
+ assertEquals(-20281777.349363208, x %= (22184822.46602547));
+ assertEquals(1, x /= x);
+ assertEquals(-4360732, x ^= ((x|(tmp = 3178620274, tmp))>>(((2686286888)&(((-1107223053.8716578)/(((-2955575332.3675404)+(-2770518721))|(-2705016953.640522)))-x))^((1473641110.4633303)*((((-1466496401)<<x)+x)%(1805868749.082736))))));
+ assertEquals(-1158545408, x <<= ((((x/((-2710098221.691819)-(-2421462965.788145)))/(((((x>>>(tmp = 1994541591.1032422, tmp))+(tmp = -1276676679.9747126, tmp))&((tmp = 1764029634.2493339, tmp)+((x|(tmp = -3050446156, tmp))-((tmp = -9441859, tmp)/(((-2072420232)&x)*(-1003199889))))))+(tmp = -2443230628, tmp))*x))*((x&((((x|(747566933))*(((2039741506)>>>((tmp = -2456000554, tmp)>>>(-1566360933.7788877)))^((tmp = 960600745, tmp)/x)))&(x^(((-2649310348.777452)^((2224282875)-(tmp = -2129141087.3182096, tmp)))<<((x<<x)+((-1307892509.3874407)-(x|(tmp = -2831643528.9720087, tmp)))))))/(((tmp = -35502946, tmp)<<((tmp = 1091279222, tmp)>>(((-2686069468.8930416)-x)+(tmp = 367442353.2904701, tmp))))%(1218262628))))/x))^(-919079153.7857773)));
+ assertEquals(747, x >>>= (1229157974));
+ assertEquals(747, x |= x);
+ assertEquals(NaN, x %= (((3086718766.4715977)*((7912648.497568846)*((-2713828337.1659327)*(-176492425.4011252))))<<(tmp = -1074475173, tmp)));
+ assertEquals(0, x >>>= ((((444923201)<<x)>>>(-883391420.2142565))*((((617245412)<<x)>>>x)*(-913086143.2793813))));
+ assertEquals(1941802406, x ^= (tmp = -2353164890, tmp));
+ assertEquals(14, x >>>= (-1600311077.4571416));
+ assertEquals(-18229482703.7246, x += (((x+(-993157139.7880647))%x)*(1862419512.1781366)));
+ assertEquals(-14.531388114858734, x /= ((tmp = -1649072797.951641, tmp)<<x));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x >>= ((x/x)^x));
+ assertEquals(2, x ^= ((-1597416259)/(-738770020)));
+ assertEquals(0, x >>= (tmp = -387850072.74833393, tmp));
+ assertEquals(0, x >>>= ((2491085477.186817)>>(x*(((tmp = -1592498533, tmp)+(tmp = 2086841852, tmp))&(-3174019330.8288536)))));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x >>>= (tmp = -3045348659.45243, tmp));
+ assertEquals(-1208573479, x |= ((3086393817)-x));
+ assertEquals(1460649854142163500, x *= x);
+ assertEquals(1588199424, x <<= (-1902076952));
+ assertEquals(1586102272, x &= (tmp = 2139876091.9142454, tmp));
+ assertEquals(-460908552.5528109, x -= (tmp = 2047010824.552811, tmp));
+ assertEquals(-460908552.5528109, x %= (tmp = 507904117.09368753, tmp));
+ assertEquals(-460908552.5528109, x %= (2749577642.527038));
+ assertEquals(234012, x >>>= (-340465746.91275));
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x %= (tmp = -2601875531, tmp));
+ assertEquals(0, x %= (x|(tmp = 650979981.1158671, tmp)));
+ assertEquals(0, x %= (tmp = -2286020987, tmp));
+ assertEquals(0, x |= x);
+ assertEquals(0, x &= (x|((tmp = 2568101411, tmp)-(-1438002403))));
+ assertEquals(0, x >>>= (1399248574));
+ assertEquals(0, x %= (-1906670287.2043698));
+ assertEquals(0, x >>= (1019286379.6962404));
+ assertEquals(0, x |= (x/(tmp = -82583591.62643051, tmp)));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x *= (x^(1874776436)));
+ assertEquals(NaN, x -= ((-1238826797)-(-2971588236.7228813)));
+ assertEquals(0, x <<= (2064632559));
+ assertEquals(-0.5967273958864694, x += (((tmp = 1502995019, tmp)>>x)/(-2518729707)));
+ assertEquals(0, x >>>= x);
+ assertEquals(-0, x /= (-1923030890));
+ assertEquals(NaN, x %= x);
+ assertEquals(0, x >>= (tmp = 1081732779.9449487, tmp));
+ assertEquals(-820183066, x |= ((tmp = -3169007292.4721155, tmp)|(-1912588318)));
+ assertEquals(0, x -= x);
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x /= (tmp = 287181840, tmp));
+ assertEquals(0, x &= (x/((tmp = -1139766051, tmp)<<(x&(tmp = 2779004578, tmp)))));
+ assertEquals(0, x >>= (((tmp = -1816938028, tmp)+(-224851993.3139863))*(-2933829524)));
+ assertEquals(0, x |= ((((tmp = 305077929.1808746, tmp)&((x-(((((tmp = 2122810346.7475111, tmp)<<(717271979))*(tmp = 256854043.72633624, tmp))%((x+(tmp = -318657223.9992106, tmp))*((1993144830)<<(2594890698.603228))))^((((tmp = 257370667, tmp)>>>((((x^(3160746820))>>>(2049640466.8116226))>>>(2543930504.7117066))^(x-x)))^(x%(964838975)))^x)))%(x*x)))>>>x)*(tmp = -46861540, tmp)));
+ assertEquals(747575633, x ^= ((-2406502427)-(-3154078060.3794584)));
+ assertEquals(0, x *= (x%x));
+ assertEquals(0, x <<= (1313773705.3087234));
+ assertEquals(0, x >>>= ((x+x)>>>(3068164056)));
+ assertEquals(-0, x *= (tmp = -1771797797, tmp));
+ assertEquals(1784146970, x ^= (tmp = 1784146970, tmp));
+ assertEquals(1784146970, x >>>= (tmp = -2219972320.7195597, tmp));
+ assertEquals(1744830464, x <<= ((((-2769476584)-(((1798431604)>>(tmp = 1337687914.799577, tmp))>>>((-2802941943.15014)>>x)))>>>(tmp = 646033678, tmp))-x));
+ assertEquals(3044433348102455300, x *= x);
+ assertEquals(0, x >>= ((tmp = 1592076570.1900845, tmp)-((645774223.6317859)>>x)));
+ assertEquals(0, x >>= (x>>>(-3045822290.1536255)));
+ assertEquals(-0, x *= (tmp = -2450298800.986624, tmp));
+ assertEquals(0, x >>= (tmp = 1379605393, tmp));
+ assertEquals(0, x &= (((x-((((tmp = 837939461.6683749, tmp)+((((-813261853.3247359)|(x&(((-2565113940)*(tmp = -2725085381.240134, tmp))|x)))%(-1457259320))-(x+((tmp = -273947066, tmp)%((1164825698.879649)>>(1653138880.3434052))))))>>>(2823967606.411492))>>>((((((((1189235604.9646997)/(tmp = -2875620103.4002438, tmp))-(tmp = -801261493, tmp))<<(((1832556579.5095325)<<x)|((tmp = -2740330665, tmp)>>(tmp = -2352814025, tmp))))-(tmp = -1445043552.99499, tmp))&(x<<(((((445325471)*(1293047043.1808558))>>>(((1901837408.5910044)-(tmp = -2349093446.5313253, tmp))>>>(tmp = 1000847053.1861948, tmp)))*(x>>>(1771853406.6567078)))>>x)))>>>x)>>>(x^((tmp = 2813422715, tmp)-(x+(-342599947)))))))&(x>>>x))*x));
+ assertEquals(NaN, x %= ((tmp = -3027713526, tmp)-((((x%(((((x/((2711155710)^(((((x>>>x)%((1098599291.155015)^(((((tmp = 1855724377.8987885, tmp)/(x|x))*((-1963179786)*((x-((-1634717702)%x))<<x)))>>(2008859507))>>((tmp = 2635024299.7983694, tmp)^(tmp = -602049246, tmp)))))*(x>>x))&(tmp = -1925103609, tmp))*((tmp = 2106913531.2828505, tmp)%((tmp = -200970069, tmp)*(-2809001910.951446))))))%x)*((1990098169)>>((x<<(2303347904.2601404))%x)))|(2767962065.9846206))+(201589933.301661)))>>(((tmp = 1921071149.5140274, tmp)>>(1054558799.1731887))|x))*(x/((((-2833879637.345674)>>>(tmp = 2849099601, tmp))%x)+(x%(x%(((tmp = 1983018049, tmp)^(tmp = -2659637454, tmp))>>((-1335497229.6945198)-(x+(((((tmp = 1136612609.848967, tmp)%(2471741030.01762))<<(x|(((tmp = 1644081190.1972675, tmp)&(-1422527338))^(2379264356.265957))))/(tmp = 2979299484.1884174, tmp))/x)))))))))*((tmp = 1858298882, tmp)^((tmp = -547417134.9651439, tmp)*x)))));
+ assertEquals(-7664, x |= ((2286000258.825538)>>(1716389170)));
+ assertEquals(-1, x >>= x);
+ assertEquals(-1231640486.3023372, x += ((tmp = 1231640485.3023372, tmp)*x));
+ assertEquals(-2463280972.6046743, x += x);
+ assertEquals(1746, x >>>= x);
+ assertEquals(1746, x >>>= (((tmp = -562546488.0669937, tmp)*((-2475357745.8508205)&((x%(821425388.8633704))%((((-2315481592.687686)&(((tmp = 3130530521.7453523, tmp)+x)-x))^(-973033390.1773088))/x))))<<x));
+ assertEquals(1746, x %= (-1544973951.076033));
+ assertEquals(27936, x <<= (-525441532.33816123));
+ assertEquals(27936, x %= (x*((tmp = 344991423.5336287, tmp)+(-2267207281))));
+ assertEquals(27, x >>>= (tmp = 1249792906, tmp));
+ assertEquals(0, x >>>= (tmp = -1068989615, tmp));
+ assertEquals(0, x >>>= (tmp = 347969658.92579734, tmp));
+ assertEquals(-2656611892, x -= (2656611892));
+ assertEquals(1944539596, x |= (((tmp = 3000889963, tmp)-x)<<((tmp = 2917390580.5323124, tmp)^(-996041439))));
+ assertEquals(1944539596, x |= x);
+ assertEquals(-739740167.0752468, x -= ((1712009965.0752468)+(x>>((tmp = -740611560.99014, tmp)>>>((tmp = -1033267419.6253037, tmp)&(862184116.3583733))))));
+ assertEquals(-1479480334.1504936, x += x);
+ assertEquals(-4294967296.150494, x -= (x>>>((1219235492.3661718)&(3138970355.0665245))));
+ assertEquals(0, x >>= (x*x));
+ assertEquals(-0, x *= ((-2202530054.6558375)-(-676578695)));
+ assertEquals(-0, x %= (1336025846));
+ assertEquals(0, x &= x);
+ assertEquals(0, x /= (1759366510));
+ assertEquals(630007622, x |= (630007622));
+ assertEquals(-0.22460286863455903, x /= (tmp = -2804984753, tmp));
+ assertEquals(1102410276.775397, x -= (-1102410277));
+ assertEquals(1102410276.775397, x %= ((((-2569525203)&x)*(x|(-1932675298)))/((-2376634450)>>>(x>>>(tmp = 936937604.9491489, tmp)))));
+ assertEquals(33642, x >>= (3028252527));
+ assertEquals(2181106522.688034, x -= (-2181072880.688034));
+ assertEquals(-2113861630, x &= (2523921542));
+ assertEquals(-2147483646, x &= (-1996601566.9370148));
+ assertEquals(-2147483648, x &= (tmp = -665669175.1968856, tmp));
+ assertEquals(-2858673260.1367273, x -= (tmp = 711189612.1367272, tmp));
+ assertEquals(350657, x >>= (tmp = -170243892.25474262, tmp));
+ assertEquals(-0.0001405571562140975, x /= (-2494764474.7868776));
+ assertEquals(0, x ^= x);
+ assertEquals(NaN, x /= ((x&(-2041236879))*((tmp = -2182530229, tmp)^((1274197078)*x))));
+ assertEquals(0, x |= (x&(x-(1794950303))));
+ assertEquals(1222105379, x |= (tmp = 1222105379, tmp));
+ assertEquals(729884484, x ^= (tmp = 1666645607.6907792, tmp));
+ assertEquals(729884484, x %= (tmp = -2896922082, tmp));
+ assertEquals(8768, x &= ((tmp = 358940932, tmp)>>>(3159687631.3308897)));
+ assertEquals(1892384495, x |= (-2402591569));
+ assertEquals(1892470533, x += ((((x^(-2266612043))>>>(tmp = -531009952, tmp))<<(x>>>((-1365315963.5698428)>>>((x+((-3168207800.184341)-(tmp = 1776222157.609917, tmp)))+(-1588857469.3596382)))))>>>x));
+ assertEquals(143587205, x += (tmp = -1748883328, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x >>= (tmp = 2334880462.3195543, tmp));
+ assertEquals(0, x &= ((tmp = 1819359625.4396145, tmp)|(tmp = -1323513565, tmp)));
+ assertEquals(-1102259874, x ^= (3192707422));
+ assertEquals(2567457772588852700, x *= (-2329267202));
+ assertEquals(-16783687, x |= ((-2212476227.060922)^(378973700.78452563)));
+ assertEquals(4278183609, x >>>= ((((((((tmp = 1766363150.197206, tmp)*(-2774552871))%x)>>>((3071429820)&((((((tmp = 351068445.27642524, tmp)<<(tmp = 2646575765, tmp))^(806452682))<<((x>>>(-2217968415.505327))<<(1564726716)))|x)-(tmp = -3110814468.9023848, tmp))))+x)^x)>>>(tmp = -617705282.0788529, tmp))>>>x));
+ assertEquals(4314933530, x -= ((1032195469.789219)|(tmp = -448053861.9531791, tmp)));
+ assertEquals(9709850, x %= (((tmp = -3056286252.5853324, tmp)*x)&x));
+ assertEquals(9709850, x %= (tmp = -2596800940, tmp));
+ assertEquals(2655489828.9461126, x -= (tmp = -2645779978.9461126, tmp));
+ assertEquals(369266212, x &= (((335712316.24874604)|(tmp = 33648215, tmp))-((x/(2639848695))<<((-499681175)<<(-2490554556)))));
+ assertEquals(-2147483648, x <<= (-834465507));
+ assertEquals(1073741824, x >>>= (((tmp = 3018385473.1824775, tmp)>>(x*(-2574502558.216812)))|(((tmp = -1742844828, tmp)*(1698724455))&x)));
+ assertEquals(-270818218, x += (-1344560042));
+ assertEquals(360710144, x <<= x);
+ assertEquals(0, x <<= (tmp = 612718075, tmp));
+ assertEquals(0, x <<= x);
+ assertEquals(-0, x /= (tmp = -1922423684, tmp));
+ assertEquals(-0, x *= ((((tmp = 741806213.3264687, tmp)%(-711184803.2022421))+((tmp = -3209040938, tmp)&(525355849.044886)))&(x<<(tmp = -698610297, tmp))));
+ assertEquals(0, x <<= (-482471790));
+ assertEquals(0, x &= ((-921538707)/(tmp = -482498765.988616, tmp)));
+ assertEquals(0, x ^= (x^x));
+ assertEquals(-351721702, x ^= (-351721702.8850286));
+ assertEquals(726242219625599900, x -= ((2064820612)*x));
+ assertEquals(1452484439251199700, x += x);
+ assertEquals(2.52318299412847e-15, x %= ((((x<<((2508143285)+x))>>(-2493225905.011774))%(1867009511.0792103))/((((x<<(2542171236))>>((x|x)&(tmp = -384528563, tmp)))+((-1168755343)*(1731980691.6745195)))+(tmp = -1608066022.71164, tmp))));
+ assertEquals(79905008, x += ((((-2702081714.590131)&(x+(tmp = -1254725471.2121565, tmp)))*(3088309981))%(((tmp = 1476844981.1453142, tmp)|((((tmp = -1243556934.7291331, tmp)%x)^(-1302096154))+((660489180)/(tmp = -681535480.8642154, tmp))))^(tmp = -8410710, tmp))));
+ assertEquals(1215822204, x ^= ((-3008054900)>>>(tmp = -1990206464.460693, tmp)));
+ assertEquals(-394790532, x |= ((((-1334779133.2038574)+(tmp = -1407958866.832946, tmp))<<(1699208315))-(((x^(x%x))<<(3216443))>>(x+((((2576716374.3081336)|((tmp = 2316167191.348064, tmp)&((51086351.20208645)&((x|(tmp = -357261999, tmp))^(x/x)))))*(-45901631.10155654))*(((-439588079)>>>((-2358959768.7634916)|(1613636894.9373643)))+(((-908627176)<<x)%(x%((-1669567978)>>>((x>>(1289400876))+(tmp = 2726174270, tmp)))))))))));
+ assertEquals(-0.17717467607696327, x /= (2228255982.974148));
+ assertEquals(-1905616474, x ^= (tmp = 2389350822.851587, tmp));
+ assertEquals(-0, x %= x);
+ assertEquals(2818124981.508915, x -= (-2818124981.508915));
+ assertEquals(-1476842315, x |= x);
+ assertEquals(73408564, x &= (-3147390604.3453345));
+ assertEquals(70, x >>>= x);
+ assertEquals(1, x >>= x);
+ assertEquals(3086527319.899181, x *= (3086527319.899181));
+ assertEquals(-145, x >>= x);
+ assertEquals(-145, x %= (tmp = -2500421077.3982406, tmp));
+ assertEquals(-1, x >>= (tmp = -2970678326.712191, tmp));
+ assertEquals(-1, x %= ((tmp = -535932632.4668834, tmp)+(((-1226598339.347982)<<((tmp = 616949449, tmp)/(tmp = 2779464046, tmp)))/(214578501.67984307))));
+ assertEquals(1, x *= x);
+ assertEquals(1, x >>= ((tmp = 11080208, tmp)<<(460763913)));
+ assertEquals(-1.8406600706723492e-19, x /= ((tmp = -2334126306.1720915, tmp)*(tmp = 2327566272.5901165, tmp)));
+ assertEquals(856681434186007200, x -= ((tmp = -2286974992.8133907, tmp)*(374591518)));
+ assertEquals(3126084224, x >>>= x);
+ assertEquals(-1160460669, x |= (tmp = 181716099, tmp));
+ assertEquals(873988096, x <<= (tmp = 406702419, tmp));
+ assertEquals(0, x <<= ((tmp = 802107965.4672925, tmp)-((tmp = 1644174603, tmp)>>((tmp = 604679952, tmp)+(tmp = -515450096.51425123, tmp)))));
+ assertEquals(NaN, x %= ((x>>(tmp = 2245570378, tmp))*(tmp = 1547616585, tmp)));
+ assertEquals(NaN, x /= ((tmp = -776657947.0382309, tmp)&(tmp = 163929332.28270507, tmp)));
+ assertEquals(NaN, x *= (tmp = 243725679.78916526, tmp));
+ assertEquals(NaN, x /= (x>>x));
+ assertEquals(0, x <<= ((tmp = -1293291295.5735884, tmp)%(((((63309078)>>>x)&(x&(-2835108260.025297)))+x)>>>(-1317213424))));
+ assertEquals(0, x *= ((((tmp = -1140319441.0068483, tmp)*(tmp = 2102496185, tmp))&(-2326380427))<<(tmp = -2765904696, tmp)));
+ assertEquals(0, x /= (tmp = 2709618593, tmp));
+ assertEquals(0, x >>= (-1753085095.7670164));
+ assertEquals(1766381484, x |= (-2528585812));
+ assertEquals(1766381484, x %= (2735943476.6363373));
+ assertEquals(1766381484, x %= (x*(tmp = 2701354268, tmp)));
+ assertEquals(-2147483648, x <<= (-323840707.4949653));
+ assertEquals(4611686018427388000, x *= (x<<x));
+ assertEquals(0, x <<= (3066735113));
+ assertEquals(0, x ^= ((((x*x)^(tmp = -2182795086.39927, tmp))<<(x^(tmp = 1661144992.4371827, tmp)))<<((((-2885512572.176741)*(tmp = 609919485, tmp))|(tmp = 929399391.0790694, tmp))>>>((((((((((399048996)>>((-107976581.61751771)>>>x))|(((-1502100015)<<(tmp = -1108852531.9494338, tmp))&(x/(tmp = -3198795871.7239237, tmp))))+((-2627653357)>>x))>>>x)*(1066736757.2718519))%(tmp = 1326732482.201604, tmp))/(tmp = 2513496019.814191, tmp))>>>((1694891519)>>>(-2860217254.378931)))<<(tmp = 31345503, tmp)))));
+ assertEquals(0, x ^= (x/((-2556481161)>>>(x/(x%(x&(1302923615.7148068)))))));
+ assertEquals(NaN, x /= x);
+ assertEquals(NaN, x += (tmp = 846522031, tmp));
+ assertEquals(0, x >>= (x+(-1420249556.419045)));
+ assertEquals(0, x ^= (((x%(-1807673170))&x)-x));
+ assertEquals(-3484.311990686845, x -= ((((((-510347602.0068991)>>>x)<<((tmp = 1647999950, tmp)&(((305407727)>>((1781066601.791009)&x))<<((tmp = -998795238, tmp)%(((x/x)+x)<<(((2586995491.434947)<<x)-((((tmp = 545715607.9395425, tmp)*x)>>>x)>>>(((((2332534960.4595165)^(-3159493972.3695474))<<(tmp = 867030294, tmp))|(2950723135.753855))^(((3150916666)<<x)>>((tmp = 414988690, tmp)|((tmp = -1879594606, tmp)/(tmp = 1485647336.933429, tmp))))))))))))>>(tmp = -2676293177, tmp))%(617312699.1995015))/((((tmp = -1742121185, tmp)^((((x&x)<<(tmp = 698266916, tmp))/(-1860886248))+((-213304430)%((((((-2508973021.1333447)+(tmp = 2678876318.4903, tmp))&(tmp = -43584540, tmp))-x)^(-2251323850.4611115))-x))))>>>(tmp = 2555971284, tmp))%((((tmp = 16925106, tmp)^x)&x)|((x/((x|(tmp = -2787677257.125139, tmp))<<(-853699567)))+(tmp = -1721553520, tmp))))));
+ assertEquals(-447873933.26863855, x += (-447870448.9566479));
+ assertEquals(200591060101520900, x *= x);
+ assertEquals(200591062202483420, x -= (-2100962536));
+ assertEquals(-5.261023346568228e+24, x *= ((tmp = -419641692.6377077, tmp)>>(tmp = -224703100, tmp)));
+ assertEquals(1269498660, x |= (195756836));
+ assertEquals(1269498660, x |= x);
+ assertEquals(1269498660, x |= x);
+ assertEquals(-37.75978948486164, x /= (((tmp = -595793780, tmp)+((tmp = 2384365752, tmp)>>>(1597707155)))|((968887032)^(tmp = 2417905313.4337964, tmp))));
+ assertEquals(-37.75978948486164, x %= (tmp = -1846958365.291661, tmp));
+ assertEquals(1102319266.6421175, x += (1102319304.401907));
+ assertEquals(-1664202255175155200, x -= ((x^(tmp = 407408729, tmp))*x));
+ assertEquals(-752874653, x ^= (tmp = 314673507, tmp));
+ assertEquals(-72474761, x |= (tmp = -2538726025.8884344, tmp));
+ assertEquals(-72474761, x |= x);
+ assertEquals(-122849418, x += ((tmp = -2332080457, tmp)|(((((30496388.145492196)*(((-1654329438.451212)|(-2205923896))&(x>>(tmp = -1179784444.957002, tmp))))&(tmp = 319312118, tmp))*(651650825))|(((-2305190283)|x)>>>(-428229803)))));
+ assertEquals(994, x >>>= x);
+ assertEquals(614292, x *= (((((2565736877)/((tmp = 649009094, tmp)>>>(((x>>>(2208471260))>>(x>>>x))%x)))&(tmp = 357846438, tmp))<<(tmp = -2175355851, tmp))%x));
+ assertEquals(1792008118, x |= (tmp = 1791924774.5121183, tmp));
+ assertEquals(1246238208, x &= (tmp = 1264064009.9569638, tmp));
+ assertEquals(-88877082, x ^= (2969289190.285704));
+ assertEquals(0.044923746573582474, x /= ((tmp = -3057438043, tmp)^(-1009304907)));
+ assertEquals(0, x <<= ((-828383918)-((((x>>(734512101))*(tmp = -3108890379, tmp))-(x|((tmp = 3081370585.3127823, tmp)^((-271087194)-(x/(tmp = -2777995324.4073873, tmp))))))%x)));
+ assertEquals(1604111507.3365753, x -= (-1604111507.3365753));
+ assertEquals(-1721314970, x ^= (tmp = -956686859, tmp));
+ assertEquals(-102247425, x |= (tmp = -2535095555, tmp));
+ assertEquals(-102247425, x %= (-955423877));
+ assertEquals(1053144489850425, x *= (((tmp = 1583243590.9550207, tmp)&(1356978114.8592746))|(tmp = -10299961.622774363, tmp)));
+ assertEquals(-0.0043728190668037336, x /= ((-1196259252.435701)*(((-689529982)|(tmp = -1698518652.4373918, tmp))<<x)));
+ assertEquals(-2, x ^= (((x+(tmp = 2961627388, tmp))>>(tmp = 231666110.84104693, tmp))|x));
+ assertEquals(-1, x >>= (tmp = -83214419.92958307, tmp));
+ assertEquals(-1, x %= (-1303878209.6288595));
+ assertEquals(2944850457.5213213, x -= (tmp = -2944850458.5213213, tmp));
+ assertEquals(-1.6607884436053055, x /= (-1773164107));
+ assertEquals(-0.6607884436053055, x %= ((x>>(1240245489.8629928))%(tmp = -3044136221, tmp)));
+ assertEquals(-0, x *= ((x*x)>>>((1069542313.7656753)+x)));
+ assertEquals(0, x >>>= (tmp = -202931587.00212693, tmp));
+ assertEquals(-0, x *= (-375274420));
+ assertEquals(0, x |= ((x/(((tmp = -876417141, tmp)*(x>>>x))&(-2406962078)))<<x));
+ assertEquals(0, x &= ((tmp = -650283599.0780096, tmp)*(tmp = 513255913.34108484, tmp)));
+ assertEquals(3027255453.458466, x += (3027255453.458466));
+ assertEquals(-12568623413253943000, x *= (((x-(198689694.92141533))|x)-x));
+ assertEquals(-12568623410285185000, x -= (tmp = -2968758030.3694654, tmp));
+ assertEquals(-2008903680, x &= (3111621747.7679076));
+ assertEquals(-110045263.26583672, x += (tmp = 1898858416.7341633, tmp));
+ assertEquals(15964, x >>>= (1141042034));
+ assertEquals(31928, x += x);
+ assertEquals(0, x ^= x);
+ assertEquals(-1159866377, x |= (-1159866377));
+ assertEquals(0, x ^= x);
+ assertEquals(3072699529.4306993, x -= (tmp = -3072699529.4306993, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(-1471195029, x |= (2823772267.429641));
+ assertEquals(-4152937108, x += (-2681742079));
+ assertEquals(142030188, x |= x);
+ assertEquals(270, x >>= (tmp = 1013826483, tmp));
+ assertEquals(0, x >>>= (529670686));
+ assertEquals(-2912300367, x -= (2912300367));
+ assertEquals(2213791134963007500, x *= (x<<((((-3214746140)>>(tmp = -588929463, tmp))+((tmp = -3084290306, tmp)>>x))>>x)));
+ assertEquals(2213791133466809900, x -= (tmp = 1496197641, tmp));
+ assertEquals(69834416, x >>>= (x|(((2755815509.6323137)^(x%(((x*((((tmp = 375453453, tmp)<<(x*x))>>(tmp = -973199642, tmp))*x))>>((tmp = -356288629, tmp)>>(tmp = 2879464644, tmp)))<<((((1353647167.9291127)>>>(x/x))<<((2919449101)/(2954998123.5529594)))^x))))&((-2317273650)>>>(tmp = 34560010.71060455, tmp)))));
+ assertEquals(69834416, x >>>= (x^(-2117657680.8646245)));
+ assertEquals(2217318064, x -= ((tmp = 2035883891, tmp)<<(tmp = -1884739265, tmp)));
+ assertEquals(-1272875686, x ^= (tmp = 805889002.7165648, tmp));
+ assertEquals(-1272875686, x >>= (x&(((1750455903)*x)>>((722098015)%((tmp = 1605335626, tmp)>>(tmp = -565369634, tmp))))));
+ assertEquals(-1274351316, x -= (x>>>((tmp = 2382002632, tmp)-((tmp = -2355012843, tmp)+(1465018311.6735773)))));
+ assertEquals(-2982908522.4418216, x -= ((tmp = 1635549038.4418216, tmp)+(((1952167017.720186)&((tmp = -2284822073.1002254, tmp)>>(-1403893917)))%(tmp = 655347757, tmp))));
+ assertEquals(312, x >>>= x);
+ assertEquals(1248, x <<= (2376583906));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x *= ((((tmp = 1914053541.881434, tmp)>>>(tmp = 1583032186, tmp))>>>(-2511688231))%(tmp = -2647173031, tmp)));
+ assertEquals(0, x >>>= (tmp = -2320612994.2421227, tmp));
+ assertEquals(0, x %= (((x+(tmp = -720216298.5403998, tmp))<<(414712685))>>(tmp = 480416588, tmp)));
+ assertEquals(0, x >>= ((((3039442014.271272)<<x)%(-2402430612.9724464))&((-2141451461.3664773)%((x>>(1361764256))/((tmp = -1723952801.9320493, tmp)%(477351810.2485285))))));
+ assertEquals(-0, x /= (tmp = -1627035877, tmp));
+ assertEquals(0, x >>>= (tmp = 1745193212, tmp));
+ assertEquals(0, x >>>= (2309131575));
+ assertEquals(NaN, x %= (((x*(tmp = -1730907131.6124666, tmp))%((((1481750041)|(x>>((((x>>>(tmp = 3128156522.5936565, tmp))/(tmp = -1277222645.9880452, tmp))^(tmp = -2327254789, tmp))+x)))>>>(-1161176960))>>>(tmp = 3135906272.5466847, tmp)))*(((((-2230902834.464362)^(1822893689.8183987))+(((tmp = 1597326356, tmp)/(x&((tmp = -3044163063.587389, tmp)>>(tmp = 2844997555, tmp))))%(x^x)))>>((x|x)/x))^(2634614167.2529745))));
+ assertEquals(0, x &= (3081901595));
+ assertEquals(0, x &= (-2453019214.8914948));
+ assertEquals(0, x &= x);
+ assertEquals(0, x >>>= (-596810618.3666217));
+ assertEquals(0, x >>= (((908276623)|x)/x));
+ assertEquals(0, x ^= x);
+ assertEquals(958890056, x |= (tmp = 958890056.474458, tmp));
+ assertEquals(1325436928, x <<= (tmp = -2474326583, tmp));
+ assertEquals(711588532333838300, x *= ((-148161646.68183947)<<(tmp = -1149179108.8049204, tmp)));
+ assertEquals(0, x ^= (((2862565506)%x)/(tmp = -2865813112, tmp)));
+ assertEquals(-2064806628, x += (((tmp = -2677361175.7317276, tmp)/((817159440)>>>(tmp = 1895467706, tmp)))^(x|(tmp = -2309094859, tmp))));
+ assertEquals(-69806982479424, x *= ((x&(tmp = 2857559765.1909904, tmp))&(-3166908966.754988)));
+ assertEquals(-430255744, x %= ((((((-2968574724.119535)<<x)<<((tmp = 1603913671, tmp)%((-1495838556.661653)^(tmp = 1778219751, tmp))))*(-400364265))<<((((1607866371.235576)-(1961740136))|(1259754297))&(tmp = -1018024797.1352971, tmp)))^x));
+ assertEquals(6.828637393208647e-7, x /= (x*(tmp = 1464421, tmp)));
+ assertEquals(0, x &= x);
+ assertEquals(-0, x *= (((tmp = -2510016276, tmp)-(2088209546))<<((tmp = -1609442851.3789036, tmp)+(tmp = 1919930212, tmp))));
+ assertEquals(-0, x %= (tmp = 1965117998, tmp));
+ assertEquals(-290294792.53186846, x += ((tmp = -2361555894.5318685, tmp)%(2071261102)));
+ assertEquals(-70873, x >>= (tmp = 2206814124, tmp));
+ assertEquals(-141746, x += x);
+ assertEquals(-141733.9831459089, x -= (((tmp = -806523527, tmp)>>>(tmp = 1897214891, tmp))/x));
+ assertEquals(-141733.9831459089, x %= ((tmp = 1996295696, tmp)<<(tmp = 3124244672, tmp)));
+ assertEquals(141733.9831459089, x /= (x>>(2688555704.561076)));
+ assertEquals(3196954517.3075542, x -= (tmp = -3196812783.3244085, tmp));
+ assertEquals(-19929155, x |= (((x|x)+x)^((tmp = 391754876, tmp)-(((((((tmp = -3051902902.5100636, tmp)*(x/(1546924993)))|(tmp = 1494375949, tmp))/((((-795378522)/(tmp = 509984856, tmp))>>>(tmp = -106173186, tmp))+x))|x)|(1916921307))>>>x))));
+ assertEquals(1279271449, x &= ((tmp = 1289446971, tmp)&(tmp = 1836102619, tmp)));
+ assertEquals(17876992, x <<= (-207633461));
+ assertEquals(0, x >>= (tmp = -903885218.9406946, tmp));
+ assertEquals(0, x >>>= x);
+ assertEquals(-2999, x -= (((754533336.2183633)%(tmp = 557970276.0537136, tmp))>>(tmp = -1171045520, tmp)));
+ assertEquals(-0.000003020470363504361, x /= (tmp = 992891715.2229724, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(0.45768595820301217, x %= ((tmp = 673779031, tmp)/(tmp = -1242414872.3263657, tmp)));
+ assertEquals(-980843052.1872087, x += (tmp = -980843052.6448946, tmp));
+ assertEquals(-Infinity, x /= ((((tmp = 317747175.8024508, tmp)&(x&(((tmp = 1632953053, tmp)>>x)/x)))%x)/(3145184986)));
+ assertEquals(0, x &= (x<<x));
+ assertEquals(0, x ^= (x-((2969023660.5619783)/x)));
+ assertEquals(0, x *= x);
+ assertEquals(NaN, x %= (x/(((x-x)/((tmp = -1622970458.3812745, tmp)-(1626134522)))&((((((tmp = 1384729039.4149384, tmp)^(x%(tmp = -2736365959, tmp)))+((-1465172172)%x))>>(tmp = -1839184810.2603343, tmp))^(((tmp = 1756918419, tmp)>>>(x+(x%(tmp = -2011122996.9794662, tmp))))<<(-3026600748.902623)))*((tmp = -2040286580, tmp)>>(-2899217430.655154))))));
+ assertEquals(0, x >>>= (tmp = 2100066003.3046467, tmp));
+ assertEquals(1362012169, x ^= (tmp = 1362012169, tmp));
+ assertEquals(1476312683, x |= ((457898409)>>>(-3079768830.723079)));
+ assertEquals(1441711, x >>>= (905040778.7770994));
+ assertEquals(2078530607521, x *= x);
+ assertEquals(-208193103, x |= ((tmp = -241750000, tmp)^x));
+ assertEquals(745036378, x ^= (((tmp = -1737151062.4726632, tmp)<<x)|(tmp = -1900321813, tmp)));
+ assertEquals(1744830464, x <<= x);
+ assertEquals(212992, x >>>= ((1210741037)-(x-(x>>>((x^(-1273817997.0036907))+((2401915056.5471)%(x<<(tmp = 1696738364.277438, tmp))))))));
+ assertEquals(0.0001604311565639742, x /= (1327622418));
+ assertEquals(0, x <<= (tmp = 166631979.34529006, tmp));
+ assertEquals(0, x *= ((((tmp = 657814984, tmp)/(((-831055031)>>>(1531978379.1768064))|((tmp = 2470027754.302619, tmp)^(-223467597))))/(tmp = 1678697269.468965, tmp))&(tmp = -1756260071.4360774, tmp)));
+ assertEquals(-2049375053, x ^= (tmp = -2049375053, tmp));
+ assertEquals(-1879109889, x |= (tmp = -1963586818.0436726, tmp));
+ assertEquals(718239919, x ^= (tmp = -1523550640.1925273, tmp));
+ assertEquals(-1361085185, x |= (-1939964707));
+ assertEquals(2, x >>>= (1864136030.7395325));
+ assertEquals(0.794648722849246, x %= ((-668830999)*(((-2227700170.7193384)%(x^(x>>>x)))/(tmp = 399149892, tmp))));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x *= x);
+ assertEquals(0, x &= ((tmp = -2389008496.5948563, tmp)|((((tmp = -2635919193.905919, tmp)*((-64464127)<<(2136112830.1317358)))>>((184057979)*(-1204959085.8362718)))>>>(-442946870.3341484))));
+ assertEquals(-243793920, x -= ((tmp = 3002998032, tmp)<<((537875759)<<x)));
+ assertEquals(0, x -= x);
+ assertEquals(0, x *= ((((66852616.82442963)/((((x^x)&(2975318321.223734))+(((tmp = -1388210811.1249495, tmp)^((((-680567297.7620237)%(x-(tmp = -672906716.4672911, tmp)))-x)*(tmp = -1452125821.0132627, tmp)))*(((2770387154.5427895)%x)%x)))-x))<<((-1481832432.924325)>>(tmp = 3109693867, tmp)))>>>(x/(((((((tmp = 928294418, tmp)^(((-1018314535)/(tmp = -3167523001, tmp))%((((((tmp = -1639338126, tmp)-(tmp = -2613558829, tmp))&x)/x)%(tmp = 513624872, tmp))/((-520660667)&x))))*(2620452414))^((tmp = 2337189239.5949326, tmp)*(3200887846.7954993)))>>>((tmp = 1173330667, tmp)^x))<<x)>>(((tmp = -2475534594.982338, tmp)*x)|x)))));
+ assertEquals(0, x /= (2520915286));
+ assertEquals(0, x &= x);
+ assertEquals(0, x >>= (-1908119327));
+ assertEquals(0, x >>>= (tmp = 549007635, tmp));
+ assertEquals(0, x >>= (-994747873.8117285));
+ assertEquals(0, x <<= ((((x>>>((-3084793026.846681)%((1107295502)&(tmp = -296613957.8133817, tmp))))&((19637717.166736007)/(x+x)))+x)/(-2479724242)));
+ assertEquals(-695401420, x += (-695401420));
+ assertEquals(-695401394, x += (x>>>(tmp = 2340097307.6556053, tmp)));
+ assertEquals(-555745552, x -= (x|(-483851950.68644)));
+ assertEquals(-17825792, x <<= x);
+ assertEquals(-17825792, x >>= x);
+ assertEquals(-17, x %= ((tmp = 1799361095, tmp)|((x>>(((-1201252592)<<((((543273288)+(-2859945716.606924))*x)<<((-3030193601)<<(3081129914.9217644))))|((1471431587.981769)>>(-246180750))))|(((tmp = -2689251055.1605787, tmp)>>x)&(((2131333169)^x)-((tmp = -951555489, tmp)/x))))));
+ assertEquals(-8912896, x <<= (1146444211));
+ assertEquals(2854567584, x += (tmp = 2863480480, tmp));
+ assertEquals(426232502.24151134, x %= (1214167540.8792443));
+ assertEquals(1806802048, x ^= (-2368317898));
+ assertEquals(432537600, x <<= (tmp = 2831272652.589364, tmp));
+ assertEquals(432537600, x %= (((1713810619.3880467)-x)&((-2853023009.553296)&(tmp = -3158798098.3355417, tmp))));
+ assertEquals(-509804066, x += (tmp = -942341666, tmp));
+ assertEquals(-509804066, x %= (-732349220));
+ assertEquals(259900185710132350, x *= x);
+ assertEquals(711598501.7021885, x %= ((tmp = 2020395586.2280731, tmp)-(tmp = 3031459563.1386633, tmp)));
+ assertEquals(711598503.0618857, x += ((tmp = 967558548.4141241, tmp)/x));
+ assertEquals(711598503, x &= x);
+ assertEquals(711598503, x ^= (((((1609355669.1963444)+((((tmp = -2660082403.258437, tmp)+(tmp = -235367868, tmp))&(x/x))*((-2595932186.69466)|((tmp = -3039202860, tmp)<<x))))>>>(-951354869))-((tmp = -691482949.6335375, tmp)/(tmp = -1735502400, tmp)))/(tmp = 798440377, tmp)));
+ assertEquals(558262613882868500, x *= (784519095.4299527));
+ assertEquals(558262611968479000, x -= ((((tmp = 1039039153.4026555, tmp)/(-3138845051.6240187))*(tmp = 633557994, tmp))&(1981507217)));
+ assertEquals(1170427648, x |= ((x>>((((-1086327124)%((tmp = -1818798806.368613, tmp)^(tmp = 2183576654.9959817, tmp)))>>x)&((((((tmp = 1315985464.0330539, tmp)&(2774283689.333836))%x)*((2722693772.8994813)&(tmp = -2720671984.945404, tmp)))^(tmp = -76808019, tmp))<<((tmp = 685037799.2336662, tmp)^((tmp = 1057250849, tmp)&(tmp = 1469205111.2989025, tmp))))))+(x*(((tmp = 448288818.47173154, tmp)-(-2527606231))-((8387088.402292728)>>x)))));
+ assertEquals(558, x >>>= (tmp = 2732701109, tmp));
+ assertEquals(558, x &= x);
+ assertEquals(-0.00015855057024653912, x /= ((x+(((tmp = -1963815633, tmp)-(x>>x))-((x|x)>>x)))/x));
+ assertEquals(1.3458861596445712e-13, x /= (-1178038492.4116466));
+ assertEquals(0, x <<= (-104550232));
+ assertEquals(0, x >>>= (x>>(tmp = -255275244.12613606, tmp)));
+ assertEquals(0, x >>= x);
+ assertEquals(375, x |= ((1576819294.6991196)>>>(-2570246122)));
+ assertEquals(96000, x <<= ((2252913843.0150948)>>>(-49239716)));
+ assertEquals(6144000, x <<= ((((tmp = -2478967279, tmp)&((x%((tmp = -1705332610.8018858, tmp)+(x+(tmp = 590766349, tmp))))<<(tmp = 1759375933, tmp)))+(-2024465658.849834))&(1564539207.3650014)));
+ assertEquals(-1149239296, x <<= (1862803657.7241006));
+ assertEquals(-9, x >>= (((tmp = 463306384.05696774, tmp)^x)|((x>>((((-2098070856.799663)<<((-2054870274.9012866)<<(((-2582579691)/(829257170.0266814))<<(((((tmp = -1753535573.7074275, tmp)<<((x>>(-197886116))%((2487188445)%(tmp = 2465391564.873364, tmp))))&(((tmp = -500069832, tmp)&(tmp = 3016637032, tmp))&((tmp = 2525942628, tmp)|((((-920996215)|x)^((((tmp = -687548533.419106, tmp)&(1423222636.058937))<<((tmp = -1096532228, tmp)>>((((tmp = -3124481449.2740726, tmp)^(tmp = 2724328271.808975, tmp))>>x)*x)))+(-1661789589.5808442)))+(((x*(tmp = -1224371664.9549093, tmp))^((tmp = 3202970043, tmp)^x))/(tmp = 131494054.58501709, tmp))))))|(((tmp = -1654136720, tmp)<<x)>>((1652979932.362416)-(tmp = -863732721, tmp))))^(-113307998)))))^(-90820449.91417909))*((tmp = 641519890, tmp)-((((x<<(tmp = 2349936514.071881, tmp))*(2324420443.587892))^x)%(x<<((tmp = -1838473742, tmp)/(((-3154172718.4274178)-x)+x)))))))|(x>>>((tmp = 2096024376.4308293, tmp)<<x)))));
+ assertEquals(81, x *= x);
+ assertEquals(81, x &= x);
+ assertEquals(81, x %= (tmp = 2223962994, tmp));
+ assertEquals(81, x ^= ((x/(((-1606183420.099584)|(-1242175583))&(((x|((tmp = 828718431.3311573, tmp)/(x>>x)))+(((-2207542725.4531174)^(x*x))*(tmp = 551575809.955105, tmp)))/x)))&((x>>x)&x)));
+ assertEquals(81, x %= (tmp = 279598358.6976975, tmp));
+ assertEquals(101.72338484518858, x -= (((tmp = 2452584495.44003, tmp)%((-1181192721)+(((x>>(((x&x)^x)+((x>>>((x+(-2472793823.57181))/(((2854104951)>>(-1208718359.6554642))>>>(1089411895.694705))))/(x|(-2821482890.1780205)))))^(-1786654551))/(-29404242.70557475))))/(((-4352531)<<((-1227287545)<<x))%(-2558589438))));
+ assertEquals(101.72338484518858, x %= (-943645643));
+ assertEquals(0, x -= x);
+ assertEquals(0, x >>>= (-2440404084));
+ assertEquals(0, x >>= (tmp = 1029680958.405923, tmp));
+ assertEquals(0, x >>>= (1213820208.7204895));
+ assertEquals(-0, x /= (tmp = -103093683, tmp));
+ assertEquals(0, x >>>= (-2098144813));
+ assertEquals(-0, x /= (((-3087283334)+(((tmp = -3129028112.6859293, tmp)%(tmp = 2413829931.1605015, tmp))-(2578195237.8071446)))|x));
+ assertEquals(-15, x |= ((((-178926550.92823577)>>>(-965071271))^((tmp = -484633724.7237625, tmp)-(tmp = 473098919.1486404, tmp)))>>((-2264998310.203265)%(tmp = -499034672, tmp))));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x >>= (((-3207915976.698118)<<(tmp = 2347058630, tmp))|(tmp = -2396250098.559627, tmp)));
+ assertEquals(NaN, x %= x);
+ assertEquals(NaN, x *= (621843222));
+ assertEquals(0, x >>= (((-2409032228.7238913)*x)-(tmp = -887793239, tmp)));
+ assertEquals(NaN, x /= x);
+ assertEquals(1193017666, x ^= (tmp = 1193017666, tmp));
+ assertEquals(3.5844761899682753, x /= (tmp = 332829011.206393, tmp));
+ assertEquals(-888572929, x |= (((tmp = 1032409228, tmp)+(tmp = -1920982163.7853453, tmp))+x));
+ assertEquals(-1817051951333455600, x *= (((-1506265102)^(tmp = -775881816, tmp))-(tmp = -32116372.59181881, tmp)));
+ assertEquals(-1638479616, x |= x);
+ assertEquals(-114489, x %= (((tmp = -247137297.37866855, tmp)>>>((((((-322805409)-x)^x)>>((((((((x>>>(tmp = -900610424.7148039, tmp))/(-1155208489.6240904))|((-2874045803)|(tmp = 3050499811, tmp)))+(x/((tmp = -613902712, tmp)^((-982142626.2892077)*((((tmp = -3201753245.6026397, tmp)|((1739238762.0423079)^x))/(243217629.47237313))^((tmp = -11944405.987132788, tmp)/(tmp = 2054031985.633406, tmp)))))))*(tmp = 2696108952.450961, tmp))*x)>>>(tmp = 3058430643.0660386, tmp))>>(x<<x)))>>(-984468302.7450335))%((tmp = 1302320585.246251, tmp)>>>x)))%(tmp = -2436842285.8208156, tmp)));
+ assertEquals(2047, x >>>= (2380161237));
+ assertEquals(0, x >>= x);
+ assertEquals(0, x &= (tmp = 980821012.975836, tmp));
+ assertEquals(-1090535537, x -= ((-3064511503.1214876)&((tmp = -2598316939.163751, tmp)<<((tmp = -969452391.8925576, tmp)*x))));
+ assertEquals(-2181071074, x += x);
+ assertEquals(1, x >>>= ((2902525386.449062)>>x));
+ assertEquals(1, x += (x&(tmp = -2643758684.6636515, tmp)));
+ assertEquals(1, x %= ((tmp = -2646526891.7004848, tmp)/x));
+ assertEquals(448735695.7888887, x -= (tmp = -448735694.7888887, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(1, x >>= ((-480385726)<<(2641021142)));
+ assertEquals(1, x %= (375099107.9200462));
+ assertEquals(1, x >>= (((x&((tmp = -2402469116.9903326, tmp)%(tmp = -2862459555.860298, tmp)))*(tmp = -2834162871.0586414, tmp))%(((x>>>(tmp = 721589907.5073895, tmp))*(x^x))%(((tmp = 2844611489.231776, tmp)^((983556913)&(906035409.6693488)))^(x>>>(1239322375))))));
+ assertEquals(268435456, x <<= (tmp = 178807644.80966163, tmp));
+ assertEquals(44, x %= ((tmp = 2527026779.081539, tmp)>>>(2736129559)));
+ assertEquals(88, x += x);
+ assertEquals(0, x >>>= x);
+ assertEquals(0, x -= x);
+ assertEquals(-1523121602, x |= (2771845694));
+ assertEquals(-2, x >>= x);
+ assertEquals(-4, x += x);
+ assertEquals(-256, x <<= (((2522793132.8616533)>>(tmp = 77232772.94058788, tmp))+(3118669244.49152)));
+ assertEquals(4294967040, x >>>= x);
+ assertEquals(-256, x &= x);
+ assertEquals(1278370155.835435, x -= (-1278370411.835435));
+ assertEquals(-3.488228054921667, x /= (tmp = -366481243.6881058, tmp));
+ assertEquals(1.162742684973889, x /= ((x|(((((2404819175.562809)*(tmp = -2524589506, tmp))&(tmp = -675727145, tmp))>>>(x*x))&((-413250006)<<(tmp = 2408322715, tmp))))|((2940367603)>>>x)));
+ assertEquals(0, x >>>= ((2513665793)-(tmp = 1249857454.3367786, tmp)));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x ^= x);
+ assertEquals(1989998348.6336238, x -= (-1989998348.6336238));
+ assertEquals(903237918.986834, x %= (1086760429.6467898));
+ assertEquals(-4.4185765232981975, x /= (-204418304));
+ assertEquals(1471621914, x ^= (tmp = -1471621914.1771696, tmp));
+ assertEquals(1471621914, x |= ((((((x<<(tmp = -2676407394.536844, tmp))%(((343324258)+(x/(x>>(((-221193011)>>>x)|x))))>>(((-2737713893)^((tmp = -49214797.00735545, tmp)+((-2818106123.172874)/(tmp = -2361786565.3028684, tmp))))<<(1859353297.6355076))))*(tmp = -751970685, tmp))|((tmp = 2502717391.425871, tmp)/(tmp = -2647169430, tmp)))*((tmp = -1647567294, tmp)&(((tmp = 1819557651, tmp)/x)>>((((-3073469753)/x)-(((tmp = -1973810496.6407511, tmp)&((x-(x+(tmp = -2986851659, tmp)))>>>(tmp = -2226975699, tmp)))|(418770782.142766)))<<x))))*(((((tmp = 125466732, tmp)/((((1453655756.398259)|(((874792086.7064595)-(194880772.91499102))>>>x))%(x<<(tmp = -1445557137, tmp)))<<x))>>>(tmp = -1953751906, tmp))/((tmp = -2140573172.2979035, tmp)*((-108581964)^x)))|(-481484013.0393069))));
+ assertEquals(1454179065, x += ((tmp = 947147038.2829313, tmp)|(tmp = -154822975.3629098, tmp)));
+ assertEquals(1, x /= x);
+ assertEquals(1, x %= ((((((tmp = -2262250297.991866, tmp)-(tmp = 481953960, tmp))/(1629215187.6020458))|(2515244216))>>>((tmp = -3040594752.2184515, tmp)-(tmp = -1116041279, tmp)))^(((-182133502)-(1065160192.6609197))+(((((-1850040207)^(tmp = -1570328610, tmp))^(tmp = 20542725.09256518, tmp))*x)|(2386866629)))));
+ assertEquals(1, x &= (2889186303));
+ assertEquals(0, x >>= (((-1323093107.050538)>>(x%x))-(((((((-1736522840)+(tmp = -2623890690.8318863, tmp))*(959395040.5565329))*(233734920))<<((x+(x%((tmp = -2370717284.4370327, tmp)%(tmp = 2109311949, tmp))))-(tmp = -1005532894, tmp)))|(861703605))>>>((2399820772)/x))));
+ assertEquals(0, x >>= x);
+ assertEquals(57233408, x |= ((tmp = 2655923764.4179816, tmp)*(-1353634624.3025436)));
+ assertEquals(997939728, x |= (980552208.9005274));
+ assertEquals(1859642592476610800, x *= (1863481872));
+ assertEquals(-977190656, x <<= x);
+ assertEquals(4.378357529141239e+26, x *= ((((x/(((tmp = 2429520991, tmp)/(x/(tmp = 784592802, tmp)))-(tmp = -2704781982, tmp)))*(tmp = -2161015768.2322354, tmp))&((((-3164868762)>>(tmp = 2390893153.32907, tmp))^x)>>(-2422626718.322538)))*(tmp = 278291869, tmp)));
+ assertEquals(4.378357529141239e+26, x -= (1710777896.992369));
+ assertEquals(0, x &= (((((tmp = -2532956158.400033, tmp)|((2195255831.279001)|(1051047432)))|(-1628591858))|(tmp = -2042607521.947963, tmp))>>((-1471225208)/(((-133621318)>>(1980416325.7358408))*((1741069593.1036062)-(x|(2133911581.991011)))))));
+ assertEquals(-0, x /= (-656083507));
+ assertEquals(NaN, x += ((tmp = -1071410982.2789869, tmp)%x));
+ assertEquals(NaN, x *= (tmp = -1513535145.3146675, tmp));
+ assertEquals(0, x >>= ((2831245247.5267224)>>(x<<((x+(((3068824580.7922907)|(1708295544.275714))*((tmp = -1662930228.1170444, tmp)-(((tmp = 1979994889, tmp)<<(tmp = -1826911988, tmp))&((x/(x<<(1909384611.043981)))+(1958052414.7139997))))))<<(tmp = 2481909816.56558, tmp)))));
+ assertEquals(0, x *= (((tmp = -2979739958.1614842, tmp)&x)+x));
+ assertEquals(-0, x *= ((-332769864.50313234)^x));
+ assertEquals(0, x >>= ((((689018886.1436445)+(tmp = -2819546038.620694, tmp))|(((tmp = -1459669934.9066005, tmp)|x)/x))<<(((tmp = 2640360389, tmp)/((x%((-1947492547.9056122)%((1487212416.2083092)-(-1751984129))))^x))%(tmp = 2666842881, tmp))));
+ assertEquals(-1801321460, x |= (tmp = 2493645836, tmp));
+ assertEquals(-1801321460, x %= (2400405136));
+ assertEquals(-2905399858195810300, x *= (tmp = 1612926911, tmp));
+ assertEquals(-2905399858195810300, x -= (x>>(tmp = 1603910263.9593458, tmp)));
+ assertEquals(-238798848, x &= ((tmp = -2638646212.767516, tmp)/(((tmp = 1755616291.436998, tmp)>>>(tmp = 1083349775, tmp))-(x%(((tmp = 1728859105.53634, tmp)^(1931522619.0403612))/(tmp = 712460587.0025489, tmp))))));
+ assertEquals(-2363873607.2302856, x += (-2125074759.230286));
+ assertEquals(1712665, x &= (((117229515)>>>(((1707090894.1915488)>>>((-1696008695)>>(((-1045367326.7522249)<<(tmp = -209334716, tmp))-x)))|(-1707909786.080653)))%(1260761349.172689)));
+ assertEquals(1073741824, x <<= (tmp = -289437762.34742975, tmp));
+ assertEquals(1073741824, x &= (tmp = 2079141140, tmp));
+ assertEquals(0, x <<= ((x^(-3139646716.1615124))-(((-362323071.74237394)|(tmp = 2989896849, tmp))*(tmp = -218217991, tmp))));
+ assertEquals(0, x &= (tmp = -1476835288.425903, tmp));
+ assertEquals(0, x >>>= (tmp = 61945262.70868635, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(-2735263498.7189775, x -= (2735263498.7189775));
+ assertEquals(-1182289920, x <<= (x+x));
+ assertEquals(-1182289580, x ^= ((2858446263.2258)>>>(2387398039.6273785)));
+ assertEquals(696693056, x &= ((2178665823)*(-51848583)));
+ assertEquals(1652555776, x <<= (((tmp = 2943916975, tmp)-((-1544273901)>>(-1671503106.2896929)))|x));
+ assertEquals(6455296, x >>>= (tmp = 1492638248.675439, tmp));
+ assertEquals(2097152, x &= (((x|x)*(2873891571.7000637))^((2165264807)+(tmp = 451721563, tmp))));
+ assertEquals(2097152, x %= (tmp = 1089484582.1455994, tmp));
+ assertEquals(2097152, x <<= x);
+ assertEquals(2097152, x &= ((tmp = 119096343.4032247, tmp)^((-1947874541)*x)));
+ assertEquals(0, x &= (tmp = 2363070677, tmp));
+ assertEquals(0, x &= ((tmp = -1897325383, tmp)>>>((2368480527)>>>((tmp = 1837528979, tmp)*(-1838904077)))));
+ assertEquals(-1898659416, x ^= (-1898659416.1125412));
+ assertEquals(-725506048, x <<= x);
+ assertEquals(1392943104, x <<= (295287938.9104482));
+ assertEquals(-63620329, x ^= ((tmp = -3175925826.5573816, tmp)-(tmp = 2474613927, tmp)));
+ assertEquals(-1135111726, x -= ((tmp = -1133259081, tmp)^(((tmp = -742228219, tmp)>>((-7801909.587711811)%((tmp = -642758873, tmp)+(tmp = 2893927824.6036444, tmp))))^((tmp = -2145465178.9142997, tmp)+x))));
+ assertEquals(0, x ^= x);
+ assertEquals(660714589, x |= (660714589));
+ assertEquals(660714676, x ^= ((-376720042.8047826)>>>(2196220344)));
+ assertEquals(660714676, x |= ((((((((x<<(-1140465568))-(tmp = -1648489774.1573918, tmp))%(((tmp = -2955505390.573639, tmp)*x)<<((((tmp = -1769375963, tmp)*(tmp = -440619797, tmp))&((tmp = 1904284066, tmp)%(-2420852665.0629807)))+(-324601009.2063596))))>>(tmp = 2317210783.9757776, tmp))^((tmp = 750057067.4541628, tmp)^(tmp = -1391814244.7286487, tmp)))>>((344544658.6054913)%((tmp = -1508630423.218488, tmp)&(tmp = 1918909238.2974637, tmp))))>>((-647746783.685822)&(tmp = 2444858958.3595476, tmp)))&x));
+ assertEquals(-962337195, x ^= (tmp = -507358495.30825853, tmp));
+ assertEquals(-182008925.58535767, x %= (tmp = -195082067.35366058, tmp));
+ assertEquals(502070, x >>>= (tmp = 1459732237.1447744, tmp));
+ assertEquals(-2391009930.7235765, x -= (tmp = 2391512000.7235765, tmp));
+ assertEquals(1568669696, x <<= x);
+ assertEquals(0, x <<= (tmp = -571056688.2717848, tmp));
+ assertEquals(1770376226, x ^= (tmp = 1770376226.0584736, tmp));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x &= ((((x<<x)>>>x)|x)|(((tmp = -2141573723, tmp)^x)|(64299956))));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x &= x);
+ assertEquals(0, x <<= (1106060336.7362857));
+ assertEquals(-0, x /= (x|(tmp = 2760823963, tmp)));
+ assertEquals(0, x <<= ((-2436225757)|(-1800598694.4062433)));
+ assertEquals(0, x >>>= ((-728332508.9870625)<<x));
+ assertEquals(-173377680, x ^= ((tmp = -173377680, tmp)%(tmp = -2843994892, tmp)));
+ assertEquals(-173377680, x |= ((((-819217898)&(tmp = -1321650255, tmp))&(x+((x^x)<<((1700753064)>>((((((-1038799327)>>((782275464)^x))-(tmp = -2113814317.8539028, tmp))>>(2143804838))&x)-((2970418921)/(-3073015285.6587048)))))))&((-1759593079.4077306)%((1699128805)-((tmp = -467193967, tmp)&(((2225788267.3466334)*(((2687946762.5504274)+x)>>>x))<<(-1853556066.880512)))))));
+ assertEquals(-0.5520657226957338, x /= ((tmp = -755493878, tmp)&(tmp = 918108389, tmp)));
+ assertEquals(0.30477656217556287, x *= x);
+ assertEquals(0, x &= ((tmp = -2746007517, tmp)<<(2749629340)));
+ assertEquals(0, x ^= ((x%(tmp = 1683077876, tmp))%(-162706778)));
+ assertEquals(0, x *= (tmp = 10203423, tmp));
+ assertEquals(119043212.1461842, x += (tmp = 119043212.1461842, tmp));
+ assertEquals(587202560, x <<= (tmp = 658697910.7051642, tmp));
+ assertEquals(-138689730, x |= (x-(tmp = 1296317634.5661907, tmp)));
+ assertEquals(-138663011, x -= ((-1751010109.5506423)>>(152829872)));
+ assertEquals(-138663011, x %= (-1266200468));
+ assertEquals(-138663011, x &= (x|((tmp = -571277275.622529, tmp)<<x)));
+ assertEquals(-138663011, x >>= ((971259905.1265712)*(tmp = 2203764981, tmp)));
+ assertEquals(-138663011, x %= (-904715829));
+ assertEquals(-138663011, x |= ((tmp = -2823047885.283391, tmp)>>>(((tmp = 533217000, tmp)|(650754598.7836078))|(-1475565890))));
+ assertEquals(-1610612736, x <<= x);
+ assertEquals(-1610612736, x &= x);
+ assertEquals(163840, x >>>= (-188885010));
+ assertEquals(-1224224814, x |= (tmp = 3070742482, tmp));
+ assertEquals(1498726395213334500, x *= x);
+ assertEquals(1723591210, x |= ((tmp = 615164458, tmp)|x));
+ assertEquals(1721910480, x ^= (x>>>x));
+ assertEquals(4505284605.764313, x -= (tmp = -2783374125.7643127, tmp));
+ assertEquals(-9504912393868483000, x *= (((tmp = 2896651872, tmp)<<(-2896385692.9017262))&(((((tmp = -2081179810.20238, tmp)|(tmp = -2484863999, tmp))>>((tmp = 1560885110.2665749, tmp)/(((tmp = 934324123.4289343, tmp)<<((tmp = -1591614157.0496385, tmp)+x))/(((x%(((tmp = 1672629986.8055913, tmp)%x)>>(tmp = 2116315086.2559657, tmp)))/(((-2687682697.5806303)>>x)/(-2034391222.5029132)))%(x-((((((tmp = 2598594967, tmp)/(((((((2950032233)%x)/x)^(tmp = -2126753451.3732262, tmp))<<(tmp = -3019113473, tmp))+(tmp = -2021220129.2320697, tmp))%((((-587645875.4666483)>>(((((x+x)+x)&(tmp = 533801785, tmp))|x)-((tmp = -2224808495.678903, tmp)/(1501942300))))>>>(-2558947646))>>((2798508249.020792)>>>x))))>>>((1060584557)/((((((((x&x)|(1426725365))>>>(tmp = 1500508838, tmp))>>(-1328705938))*((tmp = -2288009425.598777, tmp)>>>(((2586897285.9759064)%((-1605651559.2122297)>>>(tmp = 1936736684.4887302, tmp)))+((tmp = 2316261040, tmp)^(570340750.353874)))))&(x^((tmp = -2266524143, tmp)-(tmp = 2358520476, tmp))))+(tmp = 1449254900.9222453, tmp))%((-100598196)%((tmp = -2985318242.153491, tmp)>>((620722274.4565848)>>(871118975)))))))<<x)*(tmp = -1287065606.4143271, tmp))>>>(1038059916.2438471)))))))+((x/(-276990308.1264961))&(tmp = 2471016351.2195315, tmp)))|(((((tmp = -1288792769.3210807, tmp)+((tmp = -641817194, tmp)*(x<<(((-1933817364)>>(((tmp = 2084673536, tmp)|x)&x))&(tmp = -2752464480, tmp)))))%((796026752)*x))+(((tmp = -3083359669, tmp)|x)-((715303522)|(tmp = 181297266, tmp))))*(-1691520182.3207517)))));
+ assertEquals(0, x <<= (-2322389800));
+ assertEquals(0, x *= (tmp = 3188682235, tmp));
+ assertEquals(0, x |= (x>>>((tmp = -2729325231.8288336, tmp)^((-393497076.96012783)*(x/(tmp = -2198942459.9466457, tmp))))));
+ assertEquals(0, x ^= x);
+ assertEquals(0, x %= (2835024997.4447937));
+ assertEquals(0, x <<= x);
+ assertEquals(0, x >>= (tmp = 1109824126, tmp));
+ assertEquals(0, x <<= (3013043386));
+ assertEquals(206825782.74659085, x -= (-206825782.74659085));
+ assertEquals(-645346761227699500, x *= (-3120243292));
+ assertEquals(6825462, x >>= ((tmp = 1457908135, tmp)<<x));
+ assertEquals(-612366097.9189918, x -= (619191559.9189918));
+ assertEquals(-612306090.9189918, x -= ((2328676543.893506)>>x));
+ assertEquals(0, x ^= (x>>(((x>>>(1856200611.2269292))&(tmp = 2003217473, tmp))%((((((-107135673)+(((3062079356.170611)<<(tmp = -676928983, tmp))>>((tmp = -1487074941.2638814, tmp)|((-1601614031)/(1317006144.5025365)))))+x)*(((1163301641)>>>(448796567))/((x%((tmp = 72293197.34410787, tmp)+(-2304112723)))/((455610361)%(-2799431520)))))>>>(-217305041.09432888))<<(x-(tmp = -2168353649, tmp))))));
+ assertEquals(0, x >>= x);
+ assertEquals(-Infinity, x -= (((-1651597599.8950624)+(1780404320))/x));
+ assertEquals(0, x <<= (tmp = 2246420272.4321294, tmp));
+ assertEquals(0, x *= ((2793605382)-(tmp = -272299011, tmp)));
+ assertEquals(0, x *= x);
+ assertEquals(0, x <<= x);
+ assertEquals(0, x >>= (tmp = 2556413090, tmp));
+ assertEquals(0, x >>= ((tmp = -1784710085, tmp)%x));
+ assertEquals(0, x %= (tmp = -1929880813, tmp));
+ assertEquals(0, x *= (2586983368));
+ assertEquals(0, x &= x);
+ assertEquals(0, x <<= (-2144588807));
+ assertEquals(0, x ^= ((x<<(((((((-596537598)+((x-(((((((tmp = -3179604796, tmp)/((tmp = 1156725365.3543215, tmp)>>>(tmp = -2762144319, tmp)))%(x<<x))&((tmp = 1750241928.1271567, tmp)&(x/((tmp = 1781306819, tmp)|x))))+((((2893068644)/((tmp = -576164593.9720252, tmp)<<((2724671.48995471)&(tmp = -573132475, tmp))))%(tmp = -1355625108, tmp))&(tmp = -302869512.5880568, tmp)))+x)<<x))>>((tmp = -2569172808, tmp)/x)))^x)-(tmp = -1174006275.2213159, tmp))&x)&(((((((-2303274799)>>(tmp = -814839320, tmp))/(tmp = 183887306.09810615, tmp))>>(((tmp = 1054106394.3704875, tmp)|x)>>>x))-(x-(tmp = 1313696830, tmp)))-((tmp = 2373274399.0742035, tmp)|((((tmp = -3163779539.4902935, tmp)*(tmp = -3056125181.726942, tmp))&(((x^(x^(x/((tmp = -576441696.6015451, tmp)<<(tmp = -26223719.920306206, tmp)))))>>(tmp = -2332835940, tmp))|((-146303509.41093707)&(tmp = -2676964025, tmp))))/((((x*(tmp = 1059918020, tmp))|((((2341797349)|(tmp = -744763805.1381104, tmp))<<x)+((2991320875.552578)^(2920702604.701831))))^(-1721756138))^(((tmp = -2794367554, tmp)>>((-2671235923.2097874)<<(x&((((tmp = -621472314.0859051, tmp)-(((x*x)+x)>>>((tmp = 1834038956, tmp)+x)))*x)^(tmp = -2090567586.321468, tmp)))))<<(321395210))))))>>>(tmp = -1207661719, tmp)))+(-2877264053.3805156)))/(x%(tmp = -2226991657.709366, tmp))));
+ assertEquals(0, x *= (tmp = 986904991.061398, tmp));
+ assertEquals(0, x -= (x%(650819306.6671969)));
+ assertEquals(0, x >>>= (905893666.2871252));
+ assertEquals(0, x += (((tmp = 2501942710.4804144, tmp)&x)/((tmp = -851080399.1751502, tmp)-(-1168623992))));
+ assertEquals(-0, x *= (tmp = -2014577821.4554045, tmp));
+ assertEquals(0, x &= (tmp = 1995246018, tmp));
+ assertEquals(0, x %= (1724355237.7031958));
+ assertEquals(-954696411, x += (((-2825222201)+(((1662353496.1795506)>>>(x-x))|(tmp = 225015046, tmp)))^(x&x)));
+ assertEquals(-2158427339993389800, x *= (2260852052.1539803));
+ assertEquals(19559, x >>>= (-862409169.4978967));
+ assertEquals(-0.000012241163878671237, x /= (x^(tmp = 2697144215.160239, tmp)));
+ assertEquals(0, x -= x);
+ assertEquals(1448177644, x |= (tmp = 1448177644.624848, tmp));
+ assertEquals(1448177644, x %= (((-1497553637.4976408)+(402228446))<<x));
+ assertEquals(2304640553, x -= (-856462909));
+ assertEquals(152436736, x &= ((766686903)*(((tmp = 660964683.1744609, tmp)|((((tmp = 297369746, tmp)-(x+((tmp = -2677127146, tmp)/x)))>>(((((((x%(x<<x))-(((((529254728)|((x|(-1407086127.6088922))&(tmp = -1968465008.5000398, tmp)))/(x%x))&((((-2761805265.92574)-x)*(x^(tmp = 110730179, tmp)))%((177220657.06030762)*(((2532585190.671373)/x)+(-1465143151)))))<<((tmp = -3008848338, tmp)<<(-2475597073))))|((-192996756.38619018)|((((1445996780)|(x>>>((((tmp = -2482370545.791443, tmp)*(tmp = -270543594, tmp))^x)*((1346780586)/(tmp = -625613363.885356, tmp)))))-(x<<(x/(-562307527))))&(-125701272))))*((x&x)%(tmp = 752963070, tmp)))>>>(tmp = 17419750.79086232, tmp))*x)^(x^((-157821212.04674292)-(tmp = 503849221.598824, tmp)))))-(tmp = 1479418449, tmp)))>>>((((((-78138548.2193842)<<(((2319032860.806689)-(tmp = -1564963892.5137577, tmp))>>>(-73673322.28957987)))<<((1797573493.3467085)*x))>>(tmp = 759994997, tmp))>>>(-1066441220))&(((((((tmp = 1972048857, tmp)*(((x&((-1347017320.0747669)>>>x))*(-2332716925.705054))%(-376976019.24362826)))>>>((tmp = -466479974, tmp)+x))&(-2282789473.3675604))|(((((((((269205423.7510414)-(tmp = 21919626.105656862, tmp))*((x-(tmp = -378670528, tmp))>>(tmp = -1045706598, tmp)))>>(tmp = -3062647341.234485, tmp))>>>x)|(tmp = -285399599.9386575, tmp))%(tmp = 2731214562, tmp))|((((tmp = 837093165.3438574, tmp)|(tmp = -2956931321, tmp))+((1871874558.3292787)<<((x|((tmp = -3169147427, tmp)%(((x^x)%(1479885041))%((1769991217)%(tmp = -1899472458, tmp)))))*(tmp = -837098563.71806, tmp))))>>(tmp = -1866722748, tmp)))-(2037734340.8345597)))>>((tmp = -1262019180.5332131, tmp)+(x*(1274173993.9800131))))*(tmp = 2336989321.855402, tmp))))));
+ assertEquals(4, x >>= (tmp = -2577728327, tmp));
+ assertEquals(16, x *= (x<<((2622323372.580596)*(tmp = -1947643367, tmp))));
+ assertEquals(33554432, x <<= (tmp = -2938370507, tmp));
+ assertEquals(-2399497018.987414, x -= (tmp = 2433051450.987414, tmp));
+ assertEquals(1, x /= x);
+ assertEquals(2, x <<= x);
+ assertEquals(0, x >>= (x&x));
+ assertEquals(0, x <<= x);
+}
+f();
diff --git a/deps/v8/test/mjsunit/numops-fuzz.js b/deps/v8/test/mjsunit/numops-fuzz.js
deleted file mode 100644
index bd7e4fa23..000000000
--- a/deps/v8/test/mjsunit/numops-fuzz.js
+++ /dev/null
@@ -1,4609 +0,0 @@
-// Copyright 2011 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.
-
-function f() {
- var x = 0;
- var tmp = 0;
- assertEquals(0, x /= (tmp = 798469700.4090232, tmp));
- assertEquals(0, x *= (2714102322.365509));
- assertEquals(0, x *= x);
- assertEquals(139516372, x -= (tmp = -139516372, tmp));
- assertEquals(1, x /= (x%(2620399703.344006)));
- assertEquals(0, x >>>= x);
- assertEquals(-2772151192.8633175, x -= (tmp = 2772151192.8633175, tmp));
- assertEquals(-2786298206.8633175, x -= (14147014));
- assertEquals(1509750523, x |= ((1073767916)-(tmp = 919311632.2789925, tmp)));
- assertEquals(2262404051.926751, x += ((752653528.9267509)%x));
- assertEquals(-270926893, x |= (tmp = 1837232194, tmp));
- assertEquals(0.17730273401688765, x /= ((tmp = -2657202795, tmp)-(((((x|(tmp = -1187733892.282897, tmp))-x)<<(556523578))-x)+(-57905508.42881298))));
- assertEquals(122483.56550261026, x *= ((((tmp = 2570017060.15193, tmp)%((-1862621126.9968336)>>x))>>(x>>(tmp = 2388674677, tmp)))>>>(-2919657526.470434)));
- assertEquals(0, x ^= x);
- assertEquals(0, x <<= (tmp = 2705124845.0455265, tmp));
- assertEquals(0, x &= (-135286835.07069612));
- assertEquals(-0, x *= ((tmp = -165810479.10020828, tmp)|x));
- assertEquals(248741888, x += ((735976871.1308595)<<(-2608055185.0700903)));
- assertEquals(139526144, x &= (tmp = -1454301068, tmp));
- assertEquals(-0.047221345672746884, x /= (tmp = -2954726130.994727, tmp));
- assertEquals(0, x <<= (x>>x));
- assertEquals(0, x >>>= ((x+(912111201.488966))-(tmp = 1405800042.6070075, tmp)));
- assertEquals(-1663642733, x |= (((-1663642733.5700119)<<(x^x))<<x));
- assertEquals(-914358272, x <<= ((((-308411676)-(-618261840.9113789))%(-68488626.58621716))-x));
- assertEquals(-1996488704, x &= (-1358622641.5848842));
- assertEquals(-345978263, x += (1650510441));
- assertEquals(3, x >>>= (-1106714178.701668));
- assertEquals(1, x %= (((x>>(x>>(tmp = -3052773846.817114, tmp)))*(tmp = 1659218887.379526, tmp))&x));
- assertEquals(-943225672, x += (-943225673));
- assertEquals(-0.41714300120060854, x /= (tmp = 2261156652, tmp));
- assertEquals(0, x >>>= ((3107060934.8863482)<<(tmp = 1902730887, tmp)));
- assertEquals(0, x &= x);
- assertEquals(1476628, x |= ((tmp = -2782899841.390033, tmp)>>>(2097653770)));
- assertEquals(0.0008887648921591833, x /= ((tmp = 1661438264.5253348, tmp)%((tmp = 2555939813, tmp)*(-877024323.6515315))));
- assertEquals(0, x <<= (tmp = -2366551345, tmp));
- assertEquals(0, x &= (tmp = 1742843591, tmp));
- assertEquals(0, x -= x);
- assertEquals(4239, x += ((-3183564176.232031)>>>(349622674.1255014)));
- assertEquals(-67560, x -= ((2352742295)>>>x));
- assertEquals(-67560, x &= x);
- assertEquals(-0.00003219917807302283, x /= (2098190203.699741));
- assertEquals(0, x -= x);
- assertEquals(0, x >>= ((((tmp = -869086522.8358297, tmp)/(187820779))-(tmp = -2000970995.1931965, tmp))|(1853528755.6064696)));
- assertEquals(0, x >>= (-3040509919));
- assertEquals(0, x %= (((tmp = -2386688049.194946, tmp)<<(tmp = -669711391, tmp))|x));
- assertEquals(0, x %= (tmp = -298431511.4839926, tmp));
- assertEquals(0, x /= (2830845091.2793818));
- assertEquals(0, x /= ((((-2529926178)|x)^((tmp = 2139313707.0894063, tmp)%((-1825768525.0541775)-(-952600362.7758243))))+x));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x -= x);
- assertEquals(NaN, x /= (tmp = -432944480, tmp));
- assertEquals(0, x <<= (((((x^((-1777523727)+(2194962794)))>>>(((((-590335134.8224905)%(x*(2198198974)))|(tmp = -2068556796, tmp))/(1060765637))*(-147051676)))/((tmp = -477350113.92686677, tmp)<<((x/(2018712621.0397925))^((tmp = 491163813.3921983, tmp)+(((x|((((x%(1990073256.812654))%((-2024388518.9599915)>>((tmp = 223182187, tmp)*(-722241065))))>>>(tmp = 2517147885.305745, tmp))%(1189996239.11222)))&x)%(-306932860))))))&((tmp = 1117802724.485684, tmp)+((-1391614045)-x)))%((((x>>((2958453447)*x))^(((410825859)|(((tmp = -1119269292.5495896, tmp)>>>(((((((x%(tmp = 648541746.6059314, tmp))*((-2304508480)<<((((x^(1408199888.1454597))|((251623937)|x))/((-382389946.9984102)|(tmp = -2082681143.5893767, tmp)))-(((tmp = 631243472, tmp)>>>(1407556544))/(((x>>>x)>>>(tmp = -6329025.47865057, tmp))>>>(tmp = 948664752.543093, tmp))))))/((((-183248880)>>x)&x)&x))>>x)&(((-978737284.8492057)%(tmp = 2983300011.737006, tmp))&(tmp = 2641937234.2954116, tmp)))<<x)>>(2795416632.9722223)))%((((tmp = -50926632, tmp)/x)&(((tmp = -2510786916, tmp)/x)/(-699755674)))|((((tmp = 1411792593, tmp)>>(924286570.2637128))>>((1609997725)>>(2735658951.0762663)))*(tmp = 726205435, tmp)))))<<(tmp = -2135055357.3156831, tmp)))/(tmp = 1408695065, tmp))^(tmp = -1343267739.8562133, tmp))));
- assertEquals(0, x %= (-437232116));
- assertEquals(-2463314518.2747326, x -= (2463314518.2747326));
- assertEquals(109, x >>= (2401429560));
- assertEquals(-2687641732.0253763, x += (-2687641841.0253763));
- assertEquals(-2336375490019484000, x *= (tmp = 869303174.6678596, tmp));
- assertEquals(5.458650430363785e+36, x *= x);
- assertEquals(0, x |= ((((-1676972008.797291)*x)*((tmp = 2606991807, tmp)-x))<<x));
- assertEquals(0, x &= ((-3053393759.3496876)+(-1431008367)));
- assertEquals(-856728369, x |= (x-(((((764337872)/x)<<((x|(((tmp = 1409368192.1268077, tmp)+(tmp = -848083676, tmp))|(-2797102463.7915916)))^x))/x)^(tmp = 856728369.0589117, tmp))));
- assertEquals(-0, x %= x);
- assertEquals(1116550103, x ^= (-3178417193));
- assertEquals(1116550103, x %= (tmp = -1482481942, tmp));
- assertEquals(133, x >>>= x);
- assertEquals(-1.381429241671034e-7, x /= ((tmp = -962771116.8101778, tmp)^x));
- assertEquals(-1092268961, x |= ((tmp = 3202672531, tmp)-((x-(tmp = 845529357, tmp))>>(tmp = -868680593, tmp))));
- assertEquals(-1092268961, x %= (tmp = 2670840415.304719, tmp));
- assertEquals(-122794480, x %= (tmp = 969474481, tmp));
- assertEquals(-297606521542193600, x *= (2423614820));
- assertEquals(72460064, x >>>= (tmp = -1230798655, tmp));
- assertEquals(-203714325373689600, x *= (-2811401400));
- assertEquals(2154914048, x >>>= (((2241377026.001436)/x)+x));
- assertEquals(1177864081, x ^= (tmp = -968513903, tmp));
- assertEquals(35947664, x &= (-2086226758.2704995));
- assertEquals(20795732539020670, x += (x*(578500247)));
- assertEquals(-892004992, x >>= x);
- assertEquals(-7023661.354330708, x /= ((((((1740714214)%((tmp = -459699286, tmp)+(tmp = -1700187400, tmp)))>>(tmp = -3170295237, tmp))+(tmp = -497509780, tmp))+((1971976144.6197853)+(661992813.6077721)))>>>(-1683802728)));
- assertEquals(-1634205696, x <<= x);
- assertEquals(-7, x >>= (-3187653764.930914));
- assertEquals(-5.095345981491203, x -= ((tmp = 748315289, tmp)/(tmp = -392887780, tmp)));
- assertEquals(1486531570, x &= (1486531570.9300508));
- assertEquals(5670, x >>= (((tmp = -2486758205.26425, tmp)*(732510414))|x));
- assertEquals(5670, x >>= (((-1811879946.2553763)%(1797475764))/(((tmp = -2159923884, tmp)|x)+(tmp = -1774410807, tmp))));
- assertEquals(38, x %= (x>>>x));
- assertEquals(-151134215, x ^= (((tmp = -2593085609.5622163, tmp)+((tmp = -814992345.7516887, tmp)-(534809571)))|(tmp = -232678571, tmp)));
- assertEquals(-234881024, x <<= x);
- assertEquals(-234881024, x <<= (x>>>x));
- assertEquals(55169095435288580, x *= x);
- assertEquals(0, x >>= (tmp = 1176612256, tmp));
- assertEquals(0, x <<= (1321866341.2486475));
- assertEquals(0, x %= (x-(-602577995)));
- assertEquals(0, x >>>= (((((tmp = -125628635.79970193, tmp)^(tmp = 1294209955.229382, tmp))&(((tmp = -2353256654.0725203, tmp)|((-1136743028.9425385)|((((950703429.1110399)-(x>>>x))/((((x%(-252705869.21126103))/((tmp = 886957620, tmp)<<(x%((tmp = -1952249741, tmp)*(tmp = -1998149844, tmp)))))|(tmp = 1933366713, tmp))|((tmp = -2957141565, tmp)>>>(tmp = 1408598804, tmp))))+(((((((-2455002047.4910946)%(tmp = -528017836, tmp))&((-2693432769)/(tmp = 2484427670.9045153, tmp)))%(-356969659))-((((((tmp = 3104828644.0753174, tmp)%(x>>>(tmp = 820832137.8175925, tmp)))*((tmp = 763080553.9260503, tmp)+(3173597855)))<<(((-510785437)^x)<<(x|(((x*(x%((tmp = -1391951515, tmp)/x)))-x)|(x-((-522681793.93221474)/((2514619703.2162743)*(2936688324))))))))|x)>>>(-2093210042)))&(763129279.3651779))&x))))-x))%(((-1331164821)&(tmp = 1342684586, tmp))<<(x<<(tmp = 2675008614.588005, tmp))))>>((2625292569.8984914)+(-3185992401))));
- assertEquals(0, x *= (tmp = 671817215.1147974, tmp));
- assertEquals(-1608821121, x ^= ((tmp = 2686146175.04077, tmp)>>>x));
- assertEquals(-0, x %= x);
- assertEquals(-0, x /= ((tmp = 286794551.0720866, tmp)|(x%x)));
- assertEquals(0, x <<= (x|(tmp = 1095503996.2285218, tmp)));
- assertEquals(443296752, x ^= (443296752));
- assertEquals(110824188, x >>= ((184708570)>>(x&x)));
- assertEquals(0.7908194935161674, x /= ((((167151154.63381648)&((tmp = -1434120690, tmp)-(tmp = 2346173080, tmp)))/(56656051.87305987))^(140138414)));
- assertEquals(-0.9027245492678485, x *= ((tmp = 1724366578, tmp)/(((2979477411)<<(((897038568)>>(tmp = 348960298, tmp))%(281056223.2037884)))^((((-1383133388)-(((-1379748375)-((x>>(x&(tmp = 2456582046, tmp)))>>>(-2923911755.565961)))&x))<<(-2825791731))^(tmp = -1979992970, tmp)))));
- assertEquals(0, x &= (2482304279));
- assertEquals(-0, x *= (-2284213673));
- assertEquals(0, x <<= ((2874381218.015819)|x));
- assertEquals(0, x *= (x>>>(tmp = 2172786480, tmp)));
- assertEquals(0, x &= (-1638727867.2978938));
- assertEquals(0, x %= ((tmp = -2213947368.285817, tmp)>>x));
- assertEquals(0, x >>>= (tmp = -531324706, tmp));
- assertEquals(0, x %= (tmp = -2338792486, tmp));
- assertEquals(0, x <<= (((tmp = 351012164, tmp)<<(x|((tmp = -3023836638.5337825, tmp)^(-2678806692))))|x));
- assertEquals(0, x %= (x-(tmp = -3220231305.45039, tmp)));
- assertEquals(0, x <<= (-2132833261));
- assertEquals(0, x >>>= x);
- assertEquals(0, x %= ((2544970469)+(((-2633093458.5911965)&(644108176))-(x>>>(tmp = -949043718, tmp)))));
- assertEquals(-2750531265, x += (-2750531265));
- assertEquals(0, x >>= x);
- assertEquals(0, x *= ((tmp = 1299005700, tmp)-x));
- assertEquals(0, x >>= x);
- assertEquals(-1785515304, x -= (((((-806054462.5563161)/x)>>>x)+(1785515304))|((tmp = 2937069788.9396844, tmp)/x)));
- assertEquals(-3810117159.173689, x -= (2024601855.1736891));
- assertEquals(-6.276064139320051, x /= (607087033.3053156));
- assertEquals(134217727, x >>>= (((x%(tmp = 924293127, tmp))^x)|((x>>>(x&((((tmp = -413386639, tmp)/(x>>(tmp = 599075308.8479941, tmp)))^(tmp = -1076703198, tmp))*((tmp = -2239117284, tmp)>>(655036983)))))-x)));
- assertEquals(134217727, x %= (tmp = 2452642261.038778, tmp));
- assertEquals(-569504740360507, x *= ((tmp = -1086243941, tmp)>>(tmp = 1850668904.4885683, tmp)));
- assertEquals(113378806, x >>>= (tmp = -2558233435, tmp));
- assertEquals(979264375, x -= (((x>>(1950008052))%((2917183569.0209)*(tmp = 1184250640.446752, tmp)))|((((tmp = -691875212, tmp)-(-2872881803))>>(tmp = 44162204.97461021, tmp))^(tmp = 865885647, tmp))));
- assertEquals(-1127813632, x <<= ((((tmp = -2210499281, tmp)>>>x)-(tmp = 2359697240, tmp))-x));
- assertEquals(-1707799657, x ^= (653518231.3995534));
- assertEquals(2916579668449318000, x *= x);
- assertEquals(2916579669254640600, x += (x&(tmp = 2986558026.399422, tmp)));
- assertEquals(870995175, x ^= (2598813927.8991632));
- assertEquals(870995175, x %= (-2857038782));
- assertEquals(1869503575895591000, x *= (x|(x|(((tmp = 2478650307.4118147, tmp)*((tmp = 2576240847.476932, tmp)>>>x))<<x))));
- assertEquals(-134947790, x |= ((tmp = 1150911808, tmp)*((2847735464)/(-2603172652.929262))));
- assertEquals(-137053182, x -= ((tmp = 2155921819.0929346, tmp)>>>(x-(((-1960937402)-(-1907735074.2875962))%((1827808310)^(tmp = -2788307127, tmp))))));
- assertEquals(-134824702, x |= (((2912578752.2395406)^(x%(((-2585660111.0638976)<<(((((tmp = 747742706, tmp)%(-1630261205))&((((x|(x|(-2619903144.278758)))|((2785710568.8651934)>>((-968301967.5982246)<<(x&x))))>>((x>>>((x>>>(tmp = -1402085797.0310762, tmp))*((tmp = -323729645.2250068, tmp)<<(tmp = 2234667799, tmp))))>>>(-167003745)))>>((924665972.4681011)<<x)))>>>x)<<((((x+x)+x)-(((tmp = 2399203431.0526247, tmp)-(-2872533271))-(((tmp = 914778794.2087344, tmp)-(tmp = 806353942.9502392, tmp))|(((tmp = 262924334.99231672, tmp)&x)|(tmp = -460248836.5602243, tmp)))))/x)))%((-1681000689)/(tmp = -2805054623.654228, tmp)))))*(tmp = 957346233.9619625, tmp)));
- assertEquals(-3274838, x %= ((((tmp = 3155450543.3524327, tmp)>>>x)<<(tmp = 2103079652.3410985, tmp))>>x));
- assertEquals(-3274838, x |= ((((tmp = 2148004645.639173, tmp)>>>(tmp = -1285119223, tmp))<<(((((-711596054)>>>(tmp = -2779776371.3473206, tmp))^(((((tmp = -1338880329.383915, tmp)<<((-1245247254.477341)>>x))*(tmp = -2649052844.20065, tmp))>>((1734345880.4600453)%(x/(2723093117.118899))))*(1252918475.3285656)))<<(2911356885))^x))<<(-1019761103)));
- assertEquals(1703281954, x &= (((tmp = 1036570471.7412028, tmp)+((tmp = 3043119517, tmp)%(2374310816.8346715)))%(tmp = -2979155076, tmp)));
- assertEquals(1741588391, x |= ((tmp = 1230009575.6003838, tmp)>>>(-1247515003.8152597)));
- assertEquals(72869474.64782429, x %= (tmp = 1668718916.3521757, tmp));
- assertEquals(770936242.104203, x += (698066767.4563787));
- assertEquals(-0.2820604726420833, x /= (tmp = -2733230342, tmp));
- assertEquals(403480578, x |= ((969730374)&(tmp = 1577889835, tmp)));
- assertEquals(-1669557233, x ^= ((-1616812135)+(tmp = -456209292, tmp)));
- assertEquals(-1630427, x >>= ((2327783031.1175823)/(226947662.4579488)));
- assertEquals(131022, x >>>= ((tmp = -1325018897.2482083, tmp)>>(x&((((((-1588579772.9240348)<<(tmp = -1775580288.356329, tmp))<<(tmp = -1021528325.2075481, tmp))>>((tmp = 2373033451.079956, tmp)*(tmp = 810304612, tmp)))-((tmp = -639152097, tmp)<<(tmp = 513879484, tmp)))&(2593958513)))));
- assertEquals(1, x >>= ((3033200222)-x));
- assertEquals(-561146816.4851823, x += (tmp = -561146817.4851823, tmp));
- assertEquals(-4.347990105831158, x /= ((((-1270435902)*x)%((tmp = 637328492.7386824, tmp)-(x>>(-749100689))))%(x+x)));
- assertEquals(-1, x >>= x);
- assertEquals(1, x *= x);
- assertEquals(111316849706694460, x += ((966274056)*(x|(115202150))));
- assertEquals(-1001883840, x >>= x);
- assertEquals(-1001883840, x &= x);
- assertEquals(-3006880758, x += ((((-2275110637.4054556)/((x+(tmp = -1390035090.4324536, tmp))>>(-5910593)))&(tmp = 378982420, tmp))|(tmp = 2289970378.568629, tmp)));
- assertEquals(314474, x >>>= (x>>((tmp = -228007336.31281257, tmp)%(tmp = 1127648013, tmp))));
- assertEquals(-17694827, x ^= ((tmp = 2095133598.1849852, tmp)|(-1978322311)));
- assertEquals(1, x /= x);
- assertEquals(1, x %= (-2323617209.7531185));
- assertEquals(0, x >>>= (x*(tmp = -1574455400.489434, tmp)));
- assertEquals(0, x >>= (3131854684));
- assertEquals(2853609824, x += ((-231012098)-(tmp = -3084621922, tmp)));
- assertEquals(8143089027629311000, x *= x);
- assertEquals(313052685, x ^= (tmp = 2962303501, tmp));
- assertEquals(4776, x >>= (tmp = 2271457232, tmp));
- assertEquals(0.000002812258572702285, x /= (tmp = 1698279115, tmp));
- assertEquals(0, x >>>= (tmp = 1698465782.0927145, tmp));
- assertEquals(0, x <<= x);
- assertEquals(0, x |= ((x<<((-1824760240.3040407)<<(2798263764.39145)))&(tmp = 1795988253.0493627, tmp)));
- assertEquals(1782206945, x ^= (-2512760351.7881565));
- assertEquals(7610569113843172000, x *= (((tmp = -44415823.92972565, tmp)&(tmp = 1402483498.9421625, tmp))+(tmp = 2909778666, tmp)));
- assertEquals(15221138227873292000, x += (x-(tmp = -186948658.394145, tmp)));
- assertEquals(0, x -= x);
- assertEquals(-2238823252, x -= ((tmp = 2238823252, tmp)+x));
- assertEquals(0, x -= x);
- assertEquals(0, x >>= (2976069570));
- assertEquals(0, x >>= ((tmp = -2358157433, tmp)/x));
- assertEquals(-949967713, x ^= (tmp = -949967713, tmp));
- assertEquals(-1, x >>= x);
- assertEquals(-1522291702.1977966, x *= (1522291702.1977966));
- assertEquals(-1522291702, x >>= ((((2290279800)|x)|(1793154434.6798015))&((-1161390929.0766077)>>>x)));
- assertEquals(83894274, x &= (tmp = 1571058486, tmp));
- assertEquals(43186847.90522933, x += ((tmp = -1131332988.0947707, tmp)%x));
- assertEquals(0, x >>= (tmp = -1968312707.269359, tmp));
- assertEquals(0, x &= (2507747643.26175));
- assertEquals(0, x %= (tmp = 3190525303.366887, tmp));
- assertEquals(-1968984602, x ^= (((x/(x|(-1607062026.5338054)))<<(tmp = 2207669861.8770065, tmp))+(tmp = 2325982694.956348, tmp)));
- assertEquals(554, x >>>= (((tmp = -2302283871.993821, tmp)>>>(-3151835112))|(((((x%(-1534374264))/((731246012)<<(((883830997.1194847)<<(((-1337895080.1937215)/(tmp = 3166402571.8157315, tmp))^(tmp = -1563897595.5799441, tmp)))>>(tmp = -556816951.0537591, tmp))))>>(-2682203577))<<(x/((1654294674.865079)+x)))/((x^(-2189474695.4259806))/(-475915245.7363057)))));
- assertEquals(1372586111, x ^= (1372586581));
- assertEquals(1166831229, x -= ((-834168138)&(762573579)));
- assertEquals(2333662456, x -= ((x>>x)-x));
- assertEquals(-1961304840, x &= x);
- assertEquals(-2130143128, x &= (2982852718.0711775));
- assertEquals(1073741824, x <<= (-1446978661.6426942));
- assertEquals(2097152, x >>>= ((-1424728215)-(((127872198)%(tmp = -2596923298, tmp))&x)));
- assertEquals(2097152, x >>>= x);
- assertEquals(0, x &= (x/(tmp = -518419194.42994523, tmp)));
- assertEquals(0, x >>= ((x/(-1865078245))%(tmp = 2959239210, tmp)));
- assertEquals(-0, x *= ((x|(-1721307400))|(-3206147171.9491577)));
- assertEquals(0, x >>>= ((-694741143)&(tmp = -2196513947.699142, tmp)));
- assertEquals(0, x <<= x);
- assertEquals(0, x &= ((tmp = 2037824385.8836646, tmp)+((tmp = 1203034986.4647732, tmp)/(x>>>(((-1374881234)/(899771270.3237157))+((-2296524362.8020077)|(-1529870870)))))));
- assertEquals(0, x >>= (tmp = 2770637816, tmp));
- assertEquals(0, x ^= x);
- assertEquals(-1861843456, x |= ((632402668)*((x|(tmp = -1032952662.8269436, tmp))|(tmp = 2671272511, tmp))));
- assertEquals(-1861843456, x >>= (((x>>>x)+x)<<(-1600908842)));
- assertEquals(-58182608, x >>= (x-(tmp = -2496617861, tmp)));
- assertEquals(-3636413, x >>= (tmp = -400700028, tmp));
- assertEquals(-7272826, x += x);
- assertEquals(-1, x >>= ((tmp = -3184897005.3614545, tmp)-((-1799843014)|(tmp = 2832132915, tmp))));
- assertEquals(-121800925.94209385, x *= (121800925.94209385));
- assertEquals(-30450232, x >>= (-979274206.6261561));
- assertEquals(-30450232, x >>= (tmp = -1028204832.5078967, tmp));
- assertEquals(-30450232, x |= x);
- assertEquals(965888871, x ^= (((((-2157753481.3375635)*((tmp = -1810667184.8165767, tmp)&((tmp = 2503908344.422232, tmp)|x)))>>(x>>(1601560785)))<<x)^(tmp = 943867311.6380403, tmp)));
- assertEquals(7546006, x >>>= x);
- assertEquals(7546006, x <<= ((tmp = 1388931761.780241, tmp)*(x-(tmp = -1245147647.0070577, tmp))));
- assertEquals(12985628, x += (x&(-1520746354)));
- assertEquals(12985628, x &= x);
- assertEquals(12985628, x %= (tmp = 308641965, tmp));
- assertEquals(685733278, x |= ((tmp = -1275653544, tmp)-((tmp = -1956798010.3773859, tmp)%(tmp = 2086889575.643448, tmp))));
- assertEquals(679679376, x &= (2860752368));
- assertEquals(1770773904, x |= (x<<(3200659207)));
- assertEquals(1224886544, x &= (-585733767.6876519));
- assertEquals(1224886544, x %= ((tmp = -114218494, tmp)-x));
- assertEquals(1208109328, x &= (tmp = 1854361593, tmp));
- assertEquals(18434, x >>>= x);
- assertEquals(-349394636955256100, x *= (x*(-1028198742)));
- assertEquals(-519536600.7713163, x %= (-1054085356.9120367));
- assertEquals(-1610612736, x ^= ((tmp = -3126078854, tmp)&x));
- assertEquals(-2637321565906333700, x *= (1637464740.5658746));
- assertEquals(-2637321568051070500, x -= ((tmp = -1006718806, tmp)<<(3005848133.106345)));
- assertEquals(368168695, x ^= (x^(tmp = 368168695.6881037, tmp)));
- assertEquals(43, x >>>= x);
- assertEquals(-2081297089, x |= ((167169305.77248895)+(-2248466405.3199244)));
- assertEquals(-2474622167, x -= (tmp = 393325078, tmp));
- assertEquals(-135109701, x %= (-1169756233));
- assertEquals(0, x ^= x);
- assertEquals(0, x >>= (((((tmp = -164768854, tmp)/(tmp = -1774989993.1909926, tmp))+x)-((-921438912)>>(tmp = -191772028.69249105, tmp)))-(tmp = 558728578.22033, tmp)));
- assertEquals(0, x %= (tmp = 2188003745, tmp));
- assertEquals(0, x <<= (((tmp = -999335540, tmp)>>((((325101977)/(tmp = -3036991542, tmp))<<(tmp = -213302488, tmp))+x))|(tmp = -1054204587, tmp)));
- assertEquals(0, x &= ((2844053429.4720345)>>>x));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x -= (-1481729275.9118822));
- assertEquals(NaN, x *= (tmp = 1098314618.2397528, tmp));
- assertEquals(-1073741824, x ^= ((tmp = 1718545772, tmp)<<(((tmp = -81058910, tmp)-(2831123087.424368))+(tmp = 576710057.2361784, tmp))));
- assertEquals(-2921155898.4793186, x -= (1847414074.4793184));
- assertEquals(-1295646720, x <<= (2178621744));
- assertEquals(-0.8906779709597907, x /= ((tmp = -2840292585.6837263, tmp)<<(x&((tmp = 892527695.6172305, tmp)>>>x))));
- assertEquals(0, x <<= (((tmp = 3149667213.298993, tmp)>>(tmp = 1679370761.7226725, tmp))^(115417747.21537328)));
- assertEquals(0, x |= x);
- assertEquals(0, x %= ((-1112849427)>>(-1245508870.7514496)));
- assertEquals(0, x &= x);
- assertEquals(0, x |= x);
- assertEquals(0, x >>>= ((3144100694.930459)>>>(tmp = 2408610503, tmp)));
- assertEquals(0, x <<= ((tmp = 2671709754.0318713, tmp)%x));
- assertEquals(0, x >>>= (x|((tmp = -3048578701, tmp)-(674147224))));
- assertEquals(NaN, x %= x);
- assertEquals(0, x &= ((tmp = -2084883715, tmp)|(((((-3008427069)+(875536047.4283574))>>>x)%(tmp = -450003426.1091652, tmp))%(((-2956878433.269356)|(x/((((x%((((((x<<(((tmp = -1581063482.510351, tmp)^x)-(tmp = 1364458217, tmp)))^((tmp = 1661446342, tmp)+(1307091014)))/(342270750.9901335))>>>(x&((1760980812.898993)&((tmp = 2878165745.6401143, tmp)/(((tmp = -981178013, tmp)/(-2338761668.29912))>>(-958462630))))))*((1807522840)^((tmp = 1885835034, tmp)^(-2538647938))))*(1673607540.0854697)))%x)>>x)<<x)))<<(853348877.2407281)))));
- assertEquals(0, x >>>= x);
- assertEquals(-1162790279, x -= (1162790279));
- assertEquals(-1162790279, x >>= (((-490178658)*x)/((((((tmp = -1883861998.6699312, tmp)/(tmp = -2369967345.240594, tmp))+(3142759868.266447))&(508784917.8158537))&x)>>(-2129532322))));
- assertEquals(-1360849740.9829152, x -= (x+(1360849740.9829152)));
- assertEquals(1928392181, x ^= (-602670783));
- assertEquals(19478708.898989897, x /= (((-2617861994)>>(tmp = 797256920, tmp))%(-1784987906)));
- assertEquals(-8648903.575540157, x *= (((tmp = 673979276, tmp)/(-1517908716))%(x/x)));
- assertEquals(-8648903.575540157, x %= ((((643195610.4221292)>>>(tmp = 2342669302, tmp))>>>(tmp = -1682965878, tmp))^((tmp = -208158937.63443017, tmp)>>((907286989)&(x<<(448634893))))));
- assertEquals(1399288769, x ^= (tmp = -1407486728, tmp));
- assertEquals(0, x &= (((1999255838.815517)/(tmp = 564646001, tmp))/(-3075888101.3274765)));
- assertEquals(0, x ^= ((-78451711.59404826)%x));
- assertEquals(-1351557131, x |= (2943410165));
- assertEquals(1715626371, x -= (-3067183502));
- assertEquals(71434240, x &= ((-1800066426)<<(((((x<<(-324796375))+x)<<(tmp = 2696824955.735132, tmp))^x)%(tmp = 444916469, tmp))));
- assertEquals(71434240, x >>>= (((x&((x%x)|x))+(tmp = 2226992348.3050146, tmp))<<(-305526260)));
- assertEquals(0, x -= (x%(tmp = 582790928.5832802, tmp)));
- assertEquals(0, x *= ((x%(1865155340))>>>((x<<(2600488191))^(-308995123))));
- assertEquals(0, x >>= (x&(-3120043868.8531103)));
- assertEquals(0, x |= x);
- assertEquals(-0, x *= (tmp = -172569944, tmp));
- assertEquals(0, x <<= (-1664372874));
- assertEquals(1377713344.6784928, x += (tmp = 1377713344.6784928, tmp));
- assertEquals(1377713344, x |= x);
- assertEquals(-232833282, x |= (tmp = 2685870654, tmp));
- assertEquals(84639, x -= (((((2778531079.998492)%(2029165314))>>>(tmp = -468881172.3729558, tmp))^x)|((x>>>((((x%(3044318992.943596))&(1996754328.2214756))^(1985227172.7485228))%(tmp = -1984848676.1347625, tmp)))|((tmp = 2637662639, tmp)<<x))));
- assertEquals(0, x ^= x);
- assertEquals(1237720303, x -= (-1237720303));
- assertEquals(2, x >>= (-2148785379.428976));
- assertEquals(2, x &= (tmp = -3087007874, tmp));
- assertEquals(0, x %= x);
- assertEquals(0, x >>>= x);
- assertEquals(0, x >>>= x);
- assertEquals(0, x += x);
- assertEquals(0, x &= (2055693082));
- assertEquals(-1349456492, x += (x^(-1349456492.315998)));
- assertEquals(671088640, x <<= (x>>(-2030805724.5472062)));
- assertEquals(-417654580004782100, x *= (tmp = -622353822, tmp));
- assertEquals(1538160360, x |= (195983080.56698656));
- assertEquals(733, x >>>= (tmp = 661085269, tmp));
- assertEquals(657, x &= (-1611460943.993404));
- assertEquals(431649, x *= x);
- assertEquals(863298, x += x);
- assertEquals(0, x &= ((1899423003)/((472439729)>>((tmp = 2903738952, tmp)+(tmp = 2164601630.3456993, tmp)))));
- assertEquals(0, x &= (x>>>(tmp = 1939167951.2828958, tmp)));
- assertEquals(1557813284, x |= (x-(-1557813284)));
- assertEquals(72876068, x &= (662438974.2372154));
- assertEquals(0.6695448637501589, x /= (tmp = 108844189.45702457, tmp));
- assertEquals(0, x -= x);
- assertEquals(2944889412, x += (2944889412));
- assertEquals(3787980288, x -= ((((tmp = -2003814373.2301111, tmp)<<x)>>>(tmp = -3088357284.4405823, tmp))-(843090884)));
- assertEquals(1, x >>>= (729274079));
- assertEquals(1, x %= (-148002187.33869123));
- assertEquals(3073988415.673201, x *= (tmp = 3073988415.673201, tmp));
- assertEquals(4839166225.673201, x += (tmp = 1765177810, tmp));
- assertEquals(4529373898.673201, x += (-309792327));
- assertEquals(3097903.090496063, x %= (-150875866.51942348));
- assertEquals(1270874112, x <<= ((((((tmp = -960966763.1418135, tmp)>>((((-3208596981.613482)>>>(tmp = 746403937.6913509, tmp))>>>(-2190042854.066803))/(2449323432)))*(-1272232665.791577))<<(-99306767.7209444))^((-1942103828)/((1570981655)/(tmp = 2381666337, tmp))))+(tmp = -1946759395.1558368, tmp)));
- assertEquals(1273845956, x |= (tmp = -3197282108.6120167, tmp));
- assertEquals(159230744, x >>= (((tmp = -1036031403.8108604, tmp)>>>(((3084964493)>>((x*x)^x))+(((2980108409.352001)^x)-(tmp = -2501685423.513927, tmp))))&(326263839)));
- assertEquals(-370091747145550100, x *= (tmp = -2324248055.674161, tmp));
- assertEquals(143384219.54999557, x /= (tmp = -2581119096, tmp));
- assertEquals(1843396287, x |= (tmp = 1842718767, tmp));
- assertEquals(2.4895593465813803, x /= (740450831));
- assertEquals(2.4895593465813803, x %= ((((((((-3175333618)>>>((tmp = -1403880166, tmp)<<(tmp = -134875360, tmp)))>>>(2721317334.998084))<<(x&(tmp = 2924634208.1484184, tmp)))*((((x>>(tmp = -200319931.15328693, tmp))-(tmp = -495128933, tmp))+((-788052518.6610589)*((((tmp = 107902557, tmp)&(1221562660))%(x<<(((3155498059)*(((tmp = -1354381139.4897022, tmp)^(tmp = 3084557138.332852, tmp))*((((tmp = 1855251464.8464525, tmp)/((-1857403525.2008865)>>x))|x)-(-2061968455.0023944))))*(1917481864.84619))))^(x-(-508176709.52712965)))))+((((x%(-1942063404))+(x%(tmp = 855152281.180481, tmp)))|(-522863804))>>x)))>>>((tmp = -2515550553, tmp)&(((((-801095375)-(tmp = -2298729336.9792976, tmp))^x)/(tmp = 2370468053, tmp))>>(x|(tmp = -900008879, tmp)))))>>>(((tmp = -810295719.9509168, tmp)*((tmp = -1306212963.6226444, tmp)/(((tmp = 3175881540.9514832, tmp)|(-1439142297.819246))+((tmp = -134415617, tmp)|((-245801870)+x)))))>>(tmp = 1889815478, tmp)))-(((tmp = 597031177, tmp)%(858071823.7655672))+((tmp = 2320838665.8243756, tmp)|((938555608)<<(2351739219.6461897))))));
- assertEquals(6.197905740150709, x *= x);
- assertEquals(1, x /= x);
- assertEquals(0, x >>= (-1639664165.9076233));
- assertEquals(0, x >>= (-3135317748.801177));
- assertEquals(0, x &= (3185479232.5325994));
- assertEquals(-0, x *= ((-119759439.19668174)/(tmp = 2123964608, tmp)));
- assertEquals(0, x /= (-1183061929.2827876));
- assertEquals(0, x <<= (-1981831198));
- assertEquals(0, x >>= ((((x<<(((((((-2133752838)&((tmp = -3045157736.9331336, tmp)>>>(x%x)))>>x)%(tmp = 3082217039, tmp))&(tmp = 270770770.97558427, tmp))|((-2212037556)^((((((2089224421)|(tmp = 360979560, tmp))<<x)%((tmp = -1679487690.6940534, tmp)+((173021423)|((tmp = 560900612, tmp)+((244376267.58977115)^x)))))<<(tmp = 2534513699, tmp))^x)))>>>(2915907189.4873834)))+(x*x))%(1637581117))%(tmp = 2363861105.3786244, tmp)));
- assertEquals(0, x &= ((-2765495757.873004)&(1727406493)));
- assertEquals(NaN, x -= (((((-1419667515.2616255)|x)-(150530256.48022234))%((((x|x)<<x)>>>(x^x))+x))-((-1216384577.3749187)*(495244398))));
- assertEquals(NaN, x += (x^((tmp = 2472035493, tmp)+x)));
- assertEquals(NaN, x %= ((tmp = -1753037412.885754, tmp)|((tmp = 2507058310, tmp)<<(1475945705))));
- assertEquals(-1008981005, x |= ((tmp = -1140889842.6099494, tmp)-(tmp = -131908837, tmp)));
- assertEquals(999230327.5872104, x -= (tmp = -2008211332.5872104, tmp));
- assertEquals(975810, x >>= (((-1211913874)*x)>>>((-2842129009)>>(x&(tmp = -1410865834, tmp)))));
- assertEquals(7623, x >>= ((tmp = -1051327071, tmp)-(((tmp = -237716102.8005445, tmp)|((2938903833.416546)&x))|(((-1831064579)^x)/((tmp = 2999232092, tmp)-(981996301.2875179))))));
- assertEquals(0, x -= x);
- assertEquals(0, x %= (x|(tmp = -666201160.5810485, tmp)));
- assertEquals(-1347124100, x |= (-1347124100));
- assertEquals(-0, x %= (x&x));
- assertEquals(-661607963, x ^= (tmp = -661607963.3794863, tmp));
- assertEquals(3465, x >>>= (-828119020.8056595));
- assertEquals(-268431991, x -= (((tmp = -1386256352, tmp)^((tmp = 743629575, tmp)%((x*((tmp = -1719517658, tmp)>>(2019516558)))<<((2637317661)|x))))<<(tmp = -51637065, tmp)));
- assertEquals(1578876380, x += ((tmp = 1847308371, tmp)&(((((((tmp = 1487934776.1893163, tmp)%(tmp = 1423264469.3137975, tmp))|(((2653260792.5668964)/(-2417905016.043802))>>>(2097411118.4501896)))^x)^(((tmp = -71334226, tmp)|x)>>>(tmp = -2771758874.7696714, tmp)))^((tmp = -1464849031.3240793, tmp)%(tmp = 2349739690.6430283, tmp)))/x)));
- assertEquals(3269293934, x += (1690417554));
- assertEquals(4025392608.031957, x -= (((tmp = 268501120.7225704, tmp)<<(tmp = 2841620654.8903794, tmp))+((tmp = 1606704462.8455591, tmp)/((-2601879963)/(tmp = 2966620168.989736, tmp)))));
- assertEquals(7, x >>>= (x^(-1913800035)));
- assertEquals(1.4326776816275493e-8, x /= ((((tmp = -2703417892, tmp)/x)^((-2693772270.396241)>>>((x-(tmp = 615999818.5666655, tmp))>>((((2308121439.3702726)<<((-1794701502)>>(x+(tmp = -2253406035.972883, tmp))))<<((tmp = -197103799.0624652, tmp)|(629975898)))>>>x))))>>>((tmp = 2833656803, tmp)^(x^(tmp = -1580436025, tmp)))));
- assertEquals(0, x >>>= (tmp = 1525372830.2126007, tmp));
- assertEquals(0, x %= ((2354010949.24469)>>>(x<<x)));
- assertEquals(0, x ^= (((1112335059.6922574)*(tmp = -1874363935, tmp))&(((((2154894295.8360596)<<x)&(tmp = -270736315.13505507, tmp))&x)>>>(-2205692260.552064))));
- assertEquals(0, x >>>= (x<<((1488533932)*(tmp = 1707754286, tmp))));
- assertEquals(0, x >>= (((tmp = 1232547376.463387, tmp)%((x>>(711691823.1608362))>>>x))>>(((895039781.7478573)*(((((-334946524)&x)*(tmp = -1214529640, tmp))^(tmp = -1586820245, tmp))*(1062595445)))+x)));
- assertEquals(0, x *= (1863299863.2631998));
- assertEquals(0, x /= (tmp = 1858428705.1330547, tmp));
- assertEquals(0, x &= x);
- assertEquals(611788028, x += (x^(611788028.1510412)));
- assertEquals(1, x /= x);
- assertEquals(0, x >>= ((tmp = -1617320707.1784317, tmp)-((-2139400380)-(-1402777976))));
- assertEquals(0, x >>= (415866827.34665));
- assertEquals(-1990811897, x -= (tmp = 1990811897, tmp));
- assertEquals(-1990811895, x += ((x>>>(tmp = -2175453282.769696, tmp))&(tmp = -1459450498.7327478, tmp)));
- assertEquals(-2377017935.149517, x += (-386206040.1495173));
- assertEquals(1946129845, x |= (tmp = -2890956796.936539, tmp));
- assertEquals(0, x %= x);
- assertEquals(0, x <<= (1616188263));
- assertEquals(-1081213596, x ^= (tmp = 3213753700, tmp));
- assertEquals(3213753700, x >>>= (tmp = -3211181312, tmp));
- assertEquals(-1081213596, x &= x);
- assertEquals(-1081213583, x ^= (((tmp = 1599988273.4926577, tmp)>>((((-1061394954.6331315)^x)+((-1835761078)*x))+(x%(tmp = -696221869, tmp))))/((tmp = -1156966790.3436491, tmp)^x)));
- assertEquals(0, x ^= x);
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x += (-1257400530.9263027));
- assertEquals(NaN, x /= (753062089));
- assertEquals(NaN, x *= ((tmp = 305418865.57012296, tmp)^(((-2797769706)+((((tmp = -33288276.988654375, tmp)%(tmp = 1242979846, tmp))|(-316574800))-((tmp = -1766083579.4203427, tmp)*(((x*(tmp = -2400342309.2349987, tmp))>>(tmp = 2632061795, tmp))^(tmp = -1001440809, tmp)))))^((((x-(tmp = -1469542637.6925495, tmp))-x)-(3184196890))%(((((((633226688)*((tmp = -2692547856, tmp)>>(((tmp = -1244311756, tmp)>>>x)+((1746013631.405202)>>>(941829464.1962085)))))%(x-x))+(995681795))-(tmp = -3047070551.3642616, tmp))/(1968259705))-((-2853237880)^(tmp = -2746628223.4540343, tmp)))))));
- assertEquals(0, x >>= x);
- assertEquals(0.5713172378854926, x += (((x+(((x+x)/(tmp = 2642822318, tmp))*(-2590095885.4280834)))|(tmp = -1769210836, tmp))/(tmp = -3096722308.8665104, tmp)));
- assertEquals(-0.000002311097780334994, x /= ((2269858877.9010344)>>(-2992512915.984787)));
- assertEquals(-0.000002311097780334994, x %= (-1139222821));
- assertEquals(-0.000004622195560669988, x += x);
- assertEquals(1, x /= x);
- assertEquals(1, x >>>= (((3002169429.6061807)/(-3068577366))>>>((tmp = -1844537620, tmp)%((((tmp = 2087505119, tmp)>>>x)+x)&(2179989542)))));
- assertEquals(-534213071, x *= (-534213071));
- assertEquals(-534213077.3716287, x -= (((tmp = -2390432951.154034, tmp)^x)/(-290501980)));
- assertEquals(1836305, x >>>= (x&x));
- assertEquals(1836305, x %= ((x|((3070123855)^(49986396)))+((-1863644960.4202995)>>>((tmp = 1886126804.6019692, tmp)^x))));
- assertEquals(28692, x >>>= ((2561362139.491764)>>(((((tmp = -1347469854.7413375, tmp)/(((x|(x+x))^((x^(tmp = -2737413775.4595394, tmp))^x))<<(((tmp = 225344844.07128417, tmp)&x)&(tmp = 145794498, tmp))))*x)<<(1424529187))/((-2924344715)/(tmp = -2125770148, tmp)))));
- assertEquals(-2089419535.2717648, x += (-2089448227.2717648));
- assertEquals(18957929, x ^= (tmp = 2186590872, tmp));
- assertEquals(-708972800, x -= (727930729));
- assertEquals(-4198593, x |= (799483455.1885371));
- assertEquals(-1, x >>= (-2330654693.6413193));
- assertEquals(-1, x |= (((tmp = -116877155, tmp)>>>((((tmp = -1677422314.1333556, tmp)/(tmp = -3108738499.0798397, tmp))%((x&(x/x))%((tmp = -695607185.1561592, tmp)-(tmp = 2302449181.622259, tmp))))^(((-1482743646.5604773)^((897705064)>>>x))-(tmp = -2933836669, tmp))))%(((tmp = -2991584625, tmp)|(((x>>x)+(-1101066835))-x))>>(-33192973.819939613))));
- assertEquals(-1, x &= x);
- assertEquals(-524288, x <<= (-1177513101.3087924));
- assertEquals(1978770334.9189441, x += (tmp = 1979294622.9189441, tmp));
- assertEquals(901783582, x &= ((-368584615)^(((((-478030699.2647903)<<x)<<x)+(tmp = 708725752, tmp))^((tmp = -3081556856, tmp)/(tmp = 1149958711.0676727, tmp)))));
- assertEquals(-1480333211.8654308, x += (tmp = -2382116793.865431, tmp));
- assertEquals(956930239.6783283, x *= ((tmp = 956930239.6783283, tmp)/x));
- assertEquals(1277610.4668602513, x /= ((tmp = 1571029828, tmp)>>(tmp = 2417481141, tmp)));
- assertEquals(-1077333228, x ^= (tmp = 3218755006, tmp));
- assertEquals(-50218, x |= (tmp = -1044436526.6435988, tmp));
- assertEquals(-1, x >>= (-154655245.18921852));
- assertEquals(0.00006276207290978003, x *= (((tmp = 2234286992.9800305, tmp)>>(tmp = 2132564046.0696363, tmp))/((((tmp = -2565534644.3428087, tmp)>>>(tmp = 2622809851.043325, tmp))>>>((tmp = 311277386, tmp)&x))-(tmp = -2003980974, tmp))));
- assertEquals(0, x %= x);
- assertEquals(1282114076, x += ((((422838227)>>>((tmp = 1024613366.1899053, tmp)-((368275340)<<(((tmp = -3066121318, tmp)+(-2319101378))&x))))^(x>>(tmp = 1920136319.803412, tmp)))^(1282264803.3968434)));
- assertEquals(-277097604, x |= (-283585688.9123297));
- assertEquals(553816692, x &= (x&(tmp = 554082036.676608, tmp)));
- assertEquals(658505728, x <<= x);
- assertEquals(658505728, x &= (x%(2846071230)));
- assertEquals(39, x >>= (334728536.5172192));
- assertEquals(0, x -= x);
- assertEquals(0, x += x);
- assertEquals(0, x &= (tmp = -335285336, tmp));
- assertEquals(0, x <<= (tmp = 1255594828.3430014, tmp));
- assertEquals(0, x %= (-630772751.1248167));
- assertEquals(NaN, x /= ((((x&(tmp = -1576090612, tmp))%x)>>>x)*((-1038073094.2787619)>>>x)));
- assertEquals(NaN, x += x);
- assertEquals(NaN, x -= (((tmp = -2663887803, tmp)&((x+(-1402421046))/x))/(-2675654483)));
- assertEquals(NaN, x %= (x&(tmp = 672002093, tmp)));
- assertEquals(0, x |= x);
- assertEquals(-2698925754, x += (tmp = -2698925754, tmp));
- assertEquals(-2057748993, x += ((tmp = -2263466497, tmp)^x));
- assertEquals(1, x /= x);
- assertEquals(-2769559719.4045835, x -= (2769559720.4045835));
- assertEquals(-1.3964174646069973, x /= (tmp = 1983332198, tmp));
- assertEquals(-2140716624.3964174, x += (tmp = -2140716623, tmp));
- assertEquals(0, x <<= ((2589073007)-(-816764911.8571186)));
- assertEquals(-2837097288.161354, x -= (tmp = 2837097288.161354, tmp));
- assertEquals(-1445059927.161354, x += (tmp = 1392037361, tmp));
- assertEquals(155197984, x &= (tmp = -2694712730.924674, tmp));
- assertEquals(155197984, x |= (x>>>(tmp = 69118015.20305443, tmp)));
- assertEquals(155197984, x >>>= (((x^(-1353660241))*x)<<(((((x%(tmp = -1905584634, tmp))>>>(tmp = -860171244.5963638, tmp))&(-1084415001.7039547))+(x-(((tmp = 298064661, tmp)>>x)>>((tmp = 378629912.383446, tmp)-(x%x)))))+(((3212580683)/(((((x^x)>>(tmp = -1502887218, tmp))<<x)%(-142779025))|(((tmp = 1361745708, tmp)*(((((tmp = 1797072528.0673332, tmp)+x)%(tmp = 167297609, tmp))%(-287345856.1791787))^(((((((x*(tmp = -640510459.1514752, tmp))<<(x^(tmp = 1387982082.5646644, tmp)))>>(tmp = 2473373497.467914, tmp))^((234025940)*x))+(tmp = 520098202.9546956, tmp))*(x*(tmp = -362929250.1775775, tmp)))^(-2379972900))))*(tmp = -1385817972, tmp))))+(-1788631834)))));
- assertEquals(0, x >>= ((tmp = -18671049, tmp)/((tmp = 651261550.6716013, tmp)>>(-58105114.70740628))));
- assertEquals(0, x *= ((((x>>(tmp = 2256492150.737681, tmp))<<(x<<(((-2738910707)&x)<<(1892428322))))*(tmp = 1547934638, tmp))>>((((319464033.7888391)|(((((tmp = 2705641070, tmp)<<((tmp = 1566904759.36666, tmp)*((-682175559.7540412)&(-691692016.3021002))))%(tmp = 1118101737, tmp))|(902774462))<<x))^((tmp = -388997180, tmp)<<(x<<((((((-88462733)+(x>>>x))%x)*(tmp = -20297481.556210756, tmp))>>>(1927423855.1719701))-((2047811185.6278129)-(tmp = 2952219346.72126, tmp))))))|(-1685518403.7513878))));
- assertEquals(0, x /= (tmp = 1858074757.563318, tmp));
- assertEquals(-1351623058, x ^= (-1351623058.4756806));
- assertEquals(1, x /= x);
- assertEquals(0, x ^= x);
- assertEquals(0, x -= (x&(997878144.9798675)));
- assertEquals(-0, x /= (-2769731277));
- assertEquals(0, x >>>= ((-2598508325)>>(-1355571351)));
- assertEquals(0, x >>>= x);
- assertEquals(0, x -= (x&(tmp = 1672810223, tmp)));
- assertEquals(-924449908.1999881, x -= (924449908.1999881));
- assertEquals(-0, x %= x);
- assertEquals(-0, x /= (tmp = 2007131382.059545, tmp));
- assertEquals(-0, x += x);
- assertEquals(225132064, x += ((((tmp = -2422670578.1260514, tmp)|x)+x)^(1660142894.7066057)));
- assertEquals(Infinity, x /= (x-x));
- assertEquals(0, x ^= x);
- assertEquals(0, x <<= x);
- assertEquals(-2455424946.732606, x -= (2455424946.732606));
- assertEquals(1208029258, x &= ((tmp = 1823728509, tmp)+x));
- assertEquals(1.3682499724725645, x /= ((((tmp = 1267938464.3854322, tmp)%((tmp = 2510853574, tmp)+(((2979355693.866435)-(tmp = 1989726095.7746763, tmp))<<x)))%((-1382092141.1627176)+(((-901799353)+((-2936414080.8254457)>>>(2515004943.0865674)))-(2532799222.353197))))<<(tmp = -2168058960.2694826, tmp)));
- assertEquals(0.13799826710735907, x %= ((-1090423235)/(tmp = 2659024727, tmp)));
- assertEquals(0, x >>= (1688542889.082693));
- assertEquals(0, x <<= x);
- assertEquals(NaN, x %= ((((tmp = 1461037539, tmp)<<((x<<(tmp = 2101282906.5302017, tmp))>>(-2792197742)))%(((x%x)^(((tmp = 1399565526, tmp)^(tmp = 643902, tmp))-((tmp = -1449543738, tmp)|x)))/x))*(x<<(471967867))));
- assertEquals(0, x &= ((tmp = -2121748100.6824129, tmp)>>(tmp = -2817271480.6497793, tmp)));
- assertEquals(0, x &= (3169130964.6291866));
- assertEquals(-0, x /= (-2303316806));
- assertEquals(0, x <<= (tmp = 120185946.51617038, tmp));
- assertEquals(449448375, x ^= ((((tmp = -836410266.014014, tmp)/x)&((x>>>(tmp = -2602671283, tmp))+x))+(tmp = 449448375, tmp)));
- assertEquals(202003841790140640, x *= x);
- assertEquals(202003840800829020, x += (((tmp = -1339865843, tmp)+(tmp = 350554234.15375435, tmp))<<((((((tmp = -1798499687.8208885, tmp)>>(((x-(x^x))|((tmp = 463627396.23932934, tmp)/(2714928060)))&(tmp = 3048222568.1103754, tmp)))&(-3127578553))<<(tmp = -2569797028.8299003, tmp))&x)<<((tmp = 2104393646, tmp)/((tmp = 2314471015.742891, tmp)<<((2704090554.1746845)>>(((tmp = 1935999696, tmp)*(((1348554815)>>>x)>>>(146665093.82445252)))%x)))))));
- assertEquals(202003841764125400, x -= (tmp = -963296372.2846234, tmp));
- assertEquals(-413485056, x <<= (tmp = -2474480506.6054573, tmp));
- assertEquals(-3171894580.186845, x += ((tmp = -1261111102, tmp)+(tmp = -1497298422.1868448, tmp)));
- assertEquals(17136, x >>= (tmp = 3055058160, tmp));
- assertEquals(17136, x %= (tmp = 1706784063.3577294, tmp));
- assertEquals(17136, x >>= ((tmp = 2161213808, tmp)*x));
- assertEquals(-17136, x /= ((((tmp = -1492618154, tmp)>>x)|(1381949066))>>(tmp = 2014457960, tmp)));
- assertEquals(-34272, x += x);
- assertEquals(-1498690902, x += (-1498656630));
- assertEquals(-1168674482, x ^= (486325220));
- assertEquals(-1168674482, x <<= ((x^x)*x));
- assertEquals(794521557347068000, x *= (-679848469));
- assertEquals(1.3330392590424505e+26, x *= (tmp = 167778866, tmp));
- assertEquals(0, x <<= (tmp = -2501540637.3664584, tmp));
- assertEquals(0, x >>>= (x-(x*(-890638026.1825848))));
- assertEquals(0, x %= ((-285010538.2813468)&(1314684460.7634423)));
- assertEquals(0, x -= x);
- assertEquals(0, x *= x);
- assertEquals(NaN, x %= (x*(x<<x)));
- assertEquals(NaN, x %= (x<<(((tmp = -1763171810.601149, tmp)&(-138151449.18303752))^(x|x))));
- assertEquals(0, x |= (x>>x));
- assertEquals(0, x &= (tmp = 1107152048, tmp));
- assertEquals(0, x >>= (1489117056.8200984));
- assertEquals(518749976, x ^= (518749976.20107937));
- assertEquals(356718654, x += (tmp = -162031322, tmp));
- assertEquals(356718654, x %= (((x>>>((tmp = -373747439.09634733, tmp)*(tmp = 563665566, tmp)))*(tmp = 2853322586.588251, tmp))*((1303537213)%(-2995314284))));
- assertEquals(5573728, x >>= (tmp = -2095997978, tmp));
- assertEquals(5573728, x <<= x);
- assertEquals(5573728, x >>= (((((tmp = 1745399178.334154, tmp)<<(tmp = 2647999783.8219824, tmp))^(tmp = 1571286759, tmp))%x)/(2166250345.181711)));
- assertEquals(10886, x >>>= ((682837289)+(x*x)));
- assertEquals(170, x >>>= x);
- assertEquals(169.95167497151652, x -= (((tmp = 527356024.19706845, tmp)+((tmp = 1263164619.2954736, tmp)|(tmp = 2942471886, tmp)))/((3017909419.131321)+(tmp = 2137746252.8006272, tmp))));
- assertEquals(-1915170061, x ^= (tmp = -1915170214, tmp));
- assertEquals(206045792, x &= (((tmp = 887031922, tmp)>>>x)-((-1861922770)|(9633541))));
- assertEquals(-1940321674, x |= (tmp = -2012149162.1817405, tmp));
- assertEquals(-1940321674, x &= x);
- assertEquals(1128412272.160699, x += (tmp = 3068733946.160699, tmp));
- assertEquals(0.47486363523180236, x /= (tmp = 2376286976.807289, tmp));
- assertEquals(-1.4931079540252477e-10, x /= (tmp = -3180370407.5892467, tmp));
- assertEquals(0, x |= (((1220765170.5933602)*(884017786))*((x%(tmp = -2538196897.226384, tmp))<<(x^x))));
- assertEquals(-525529894, x += (tmp = -525529894, tmp));
- assertEquals(1621426184, x &= ((3046517714)*(((((-162481040.8033898)+(x/((x&(1489724492))/((x|(tmp = 943542303, tmp))>>>((-1840491388.1365871)<<(2338177232))))))+(((-2268887573.2430763)>>>(((tmp = 2919141667, tmp)+((tmp = 1326295559.692003, tmp)<<(-2256653815)))>>>(((((tmp = 1602731976.7514615, tmp)*(856036244.3730336))^x)>>>((((2846316421.252943)&(915324162))%(tmp = 1144577211.0221815, tmp))%x))*(x*x))))%(tmp = -2641416560, tmp)))*(x+(x>>>x)))>>x)));
- assertEquals(1621426184, x %= (tmp = 1898223948, tmp));
- assertEquals(-3.383396676504762, x /= ((tmp = 2211088034.5234556, tmp)^x));
- assertEquals(7120923705.122882, x *= (((((tmp = 2632382342.914504, tmp)/(-615440284.1762738))&(2162453853.6658797))<<(-849038082.5298986))|(tmp = -2104667110.5603983, tmp)));
- assertEquals(-1469010887, x &= x);
- assertEquals(850767635866964700, x *= (tmp = -579143179.5338116, tmp));
- assertEquals(0, x %= x);
- assertEquals(-571457, x |= ((2849326490.8464212)|(tmp = 1450592063, tmp)));
- assertEquals(-571457, x &= x);
- assertEquals(-0.00018638416434019244, x /= (3066016912.021368));
- assertEquals(0, x <<= (2058262829));
- assertEquals(NaN, x %= ((x|((x%x)>>>x))%((tmp = -2970314895.6974382, tmp)+x)));
- assertEquals(NaN, x *= (-698693934.9483855));
- assertEquals(NaN, x += (-100150720.64391875));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x -= (-530301478));
- assertEquals(NaN, x /= (1507673244));
- assertEquals(0, x <<= (x%(tmp = 2977838420.857235, tmp)));
- assertEquals(0, x <<= (tmp = 3200877763, tmp));
- assertEquals(0, x <<= (tmp = -2592127060, tmp));
- assertEquals(NaN, x -= (((((((1930632619)*(3018666359))<<((tmp = 2676511886, tmp)&(-2786714482.25468)))%x)-(-633193192))<<((tmp = 403293598, tmp)*(-2765170226)))%x));
- assertEquals(530062092, x |= (tmp = 530062092, tmp));
- assertEquals(129409, x >>>= x);
- assertEquals(-152430382316341.78, x *= (-1177896300.229055));
- assertEquals(-304860764632683.56, x += x);
- assertEquals(0, x ^= x);
- assertEquals(0, x %= (tmp = -63071565.367660046, tmp));
- assertEquals(0, x &= ((((tmp = -1007464338, tmp)<<(x<<((x^(tmp = -726826835, tmp))|x)))>>>x)*(((tmp = 469293335.9161849, tmp)<<(((((tmp = 1035077379, tmp)*(tmp = -555174353.7567515, tmp))&(3109222796.8286266))-(((((x-(tmp = 1128900353.6650414, tmp))|(tmp = 3119921303, tmp))&((-1353827690)&(x%((-924615958)&x))))>>>x)+(tmp = 1167787910, tmp)))+x))%((605363594)>>(1784370958.269381)))));
- assertEquals(0, x %= (2953812835.9781704));
- assertEquals(0, x -= x);
- assertEquals(0, x <<= x);
- assertEquals(-901209266, x += (-901209266));
- assertEquals(-901209266, x &= x);
- assertEquals(404, x >>>= (-3195686249));
- assertEquals(824237108, x ^= (824237472));
- assertEquals(497790936.1853996, x /= ((tmp = 1253776028, tmp)/(757207285)));
- assertEquals(497790936, x >>>= ((tmp = -2212598336, tmp)<<(x^(1335355792.9363852))));
- assertEquals(0, x %= x);
- assertEquals(-2659887352.6415873, x += (tmp = -2659887352.6415873, tmp));
- assertEquals(1635079945, x |= ((x&(1234659380))>>((((tmp = 2694276886.979136, tmp)|x)^((tmp = 132795582, tmp)<<((-1089828902)>>>x)))<<((((tmp = -2098728613.0310376, tmp)<<(x/(tmp = -2253865599, tmp)))*((x+(x>>>((48633053.82579231)-(385301592))))*(tmp = -1847454853.333535, tmp)))/((-540428068.8583717)+x)))));
- assertEquals(1, x /= x);
- assertEquals(33554432, x <<= ((((2803140769)<<x)|(tmp = -1965793804, tmp))>>>(tmp = -2273336965.575082, tmp)));
- assertEquals(67108864, x += x);
- assertEquals(9007199254740992, x *= (x+((x>>x)%(2674760854))));
- assertEquals(55369784, x %= (x|(-170725544.20038843)));
- assertEquals(55369784, x %= (-1186186787));
- assertEquals(0, x ^= x);
- assertEquals(0, x <<= x);
- assertEquals(NaN, x /= ((-2968110098)-((x/(x|(((((x|((x&((-130329882)>>>(((-135670650)|(x<<(tmp = 1280371822, tmp)))^x)))-(-1183024707.2230911)))&(-1072829280))>>>(-340696948.41492534))>>>(tmp = 436308526.4938295, tmp))<<(((tmp = 3113787500, tmp)*((2038309320)>>>(-1818917055)))&((2808000707)/(774731251))))))%x)));
- assertEquals(0, x |= (x*(tmp = -843074864, tmp)));
- assertEquals(0, x &= (tmp = -752261173.8090212, tmp));
- assertEquals(0, x >>>= (tmp = 1532349931.7517128, tmp));
- assertEquals(0, x <<= ((tmp = -8628768, tmp)-((((tmp = 225928543, tmp)%(x>>>(x+x)))^((tmp = -2051536806.5249376, tmp)-x))-((tmp = -2274310376.9964137, tmp)%(tmp = 2251342739, tmp)))));
- assertEquals(0, x >>= (1011388449));
- assertEquals(0, x += x);
- assertEquals(0, x >>>= x);
- assertEquals(-0, x *= ((-1781234179.8663826)>>(((1514201119.9761915)>>(((((1174857164.90042)^(tmp = 1124973934, tmp))^x)+((-1059246013.8834443)<<(2997611138.4876065)))%(((798188010)*(-1428293122))>>>(tmp = -3087267036.8035297, tmp))))<<x)));
- assertEquals(1752554372, x ^= (tmp = -2542412924, tmp));
- assertEquals(1752554372, x %= (tmp = 3037553410.2298307, tmp));
- assertEquals(1859383977, x -= (x^(2446603103)));
- assertEquals(1183048193, x &= ((tmp = -962336957, tmp)/(x/x)));
- assertEquals(67738157, x %= ((((tmp = -1813911745.5223546, tmp)+x)<<(x-(((-1980179168)^x)|x)))|(1913769561.1308007)));
- assertEquals(67698724, x &= ((1801574998.3142045)*((tmp = -2057492249, tmp)/((1713854494.72282)>>x))));
- assertEquals(0, x -= x);
- assertEquals(-25232836, x -= ((tmp = 25232836, tmp)|x));
- assertEquals(-49, x >>= (x+((tmp = 2201204630.2897243, tmp)|(-1929326509))));
- assertEquals(-1605632, x <<= x);
- assertEquals(-165965313, x += (tmp = -164359681, tmp));
- assertEquals(9.220413724941365e-10, x /= (((((tmp = 2579760013.0808706, tmp)*(tmp = -2535370639.9805303, tmp))>>((tmp = 2138199747.0301933, tmp)-(tmp = -2698019325.0972376, tmp)))*(tmp = -425284716, tmp))/((-1951538149.6611228)/(x^(2632919130)))));
- assertEquals(0, x &= x);
- assertEquals(0, x &= ((-645189137)/(tmp = 800952748, tmp)));
- assertEquals(0, x &= (tmp = -1773606925, tmp));
- assertEquals(0, x += x);
- assertEquals(0, x >>>= (tmp = 211399355.0741787, tmp));
- assertEquals(0, x <<= ((-1317040231.5737965)/((((((tmp = 838897586.0147077, tmp)|((-1902447594)|(tmp = 404942728.83034873, tmp)))^(2462760692.2907705))%((((((x%(tmp = -2888980287, tmp))<<(-368505224.49609876))-((x>>>(532513369))&(((((((tmp = -1298067543, tmp)^(tmp = -3130435881.100909, tmp))>>x)/(tmp = -3041161992, tmp))>>(x|(-431685991.95776653)))^((tmp = 1031777777, tmp)^((-105610810)>>>((-631433779)>>(tmp = -2577780871.167671, tmp)))))%(tmp = -3170517650.088039, tmp))))-(((tmp = 2175146237.968785, tmp)-((384631158.50508535)>>((893912279.4646157)|(tmp = -1478803924.5338967, tmp))))%(x/(-1089156420))))<<(tmp = -2024709456, tmp))>>x))*(tmp = -1423824994.6993582, tmp))%(tmp = 1739143409, tmp))));
- assertEquals(-1799353648, x |= ((-1799353648.3589036)>>>((((x&(-923571640.1012449))%x)+((tmp = 971885508, tmp)>>((tmp = -2207464428.2123804, tmp)+(-3108177894.0459776))))-(-2048954486.7014258))));
- assertEquals(-3666808032.2958965, x -= (tmp = 1867454384.2958965, tmp));
- assertEquals(-260069478915415100, x *= (tmp = 70925305.23136711, tmp));
- assertEquals(1142096768, x &= (tmp = 1866401706.9144325, tmp));
- assertEquals(1, x >>>= (tmp = 2701377150.5717473, tmp));
- assertEquals(1865946805, x |= (tmp = -2429020492, tmp));
- assertEquals(1424222287, x ^= ((((tmp = 433781338, tmp)>>(x>>>((-2914418422.4829016)/(tmp = 1600920669, tmp))))|(tmp = 588320482.9566053, tmp))>>>((((((x+(tmp = -2556387365.5071325, tmp))+(tmp = -2381889946.1830974, tmp))/(3154278191))>>>(-1069701268.8022757))>>(((tmp = 182049089.28866422, tmp)>>x)>>>(tmp = -447146173, tmp)))/(x-(2103883357.0929923)))));
- assertEquals(0, x ^= x);
- assertEquals(0, x -= (x%(3036884806)));
- assertEquals(0, x >>>= (tmp = -652793480.3870945, tmp));
- assertEquals(0, x += x);
- assertEquals(304031003, x ^= ((tmp = -900156495, tmp)^(-666397014.0711515)));
- assertEquals(1, x /= x);
- assertEquals(-1974501681, x |= (x^(-1974501681.4628205)));
- assertEquals(-1.3089278317616264, x /= (((-1723703186.962839)>>>x)|((2061022161.6239533)<<x)));
- assertEquals(-1, x |= (tmp = -1987006457, tmp));
- assertEquals(-0.14285714285714285, x /= ((((((x|(-1767793799.7595732))-(-1391656680))<<x)|(x>>(tmp = -2301588485.2811003, tmp)))>>>(((tmp = 1812723993, tmp)>>>((x^(((tmp = -3154100157.951021, tmp)%((tmp = -1254955564.4553523, tmp)-(((x>>>(((-1762886343)*x)*x))*(x^(x*(-750918563.4387553))))*x)))|((x>>x)>>(x<<((((-1766797454.5634143)^(tmp = -2251474340, tmp))-(-787637516.5276759))<<((1390653368)^(-1937605249.245374)))))))|(((tmp = 1156611894, tmp)<<x)<<(x>>((((x+(tmp = 2170166060.881797, tmp))&(x>>>(tmp = -1749295923.1498983, tmp)))>>(((-1014973878)|x)&(1302866805.684057)))*(tmp = 560439074.4002491, tmp))))))|(-2758270803.4510045)))&x));
- assertEquals(0, x |= x);
- assertEquals(0, x += ((x>>((x+(tmp = -2776680860.870219, tmp))-(((688502468)<<(((tmp = 475364260.57888806, tmp)<<x)+(329071671)))/(-1097134948))))*(tmp = -1281834214.3416953, tmp)));
- assertEquals(0, x *= ((((1159762330)<<(tmp = -1892429200, tmp))%x)<<x));
- assertEquals(0, x >>>= (-770595225));
- assertEquals(NaN, x += (((x>>x)/(tmp = 281621135, tmp))/x));
- assertEquals(0, x >>= (1363890241));
- assertEquals(1639023942.9945002, x += (1639023942.9945002));
- assertEquals(-2568590958567747000, x *= (-1567146697));
- assertEquals(1793554700, x ^= (tmp = 3215813388.405799, tmp));
- assertEquals(437879, x >>= x);
- assertEquals(1339485943, x |= (1339220210));
- assertEquals(1, x /= x);
- assertEquals(512, x <<= (2509226729.1477118));
- assertEquals(512, x <<= ((x>>(1326274040.7181284))<<(tmp = -760670199, tmp)));
- assertEquals(1, x /= (x<<(x^x)));
- assertEquals(0, x >>>= (((((1382512625.8298302)&(x>>>x))*(tmp = -815316595, tmp))>>>x)-(-95538051)));
- assertEquals(-544344229.3548596, x -= (tmp = 544344229.3548596, tmp));
- assertEquals(-1088688458.7097192, x += x);
- assertEquals(-1022850479579041900, x *= (939525418.3104812));
- assertEquals(2069622661, x |= (-2632744187.7721186));
- assertEquals(-1353480538017756400, x -= ((tmp = 1308085980, tmp)*((x>>>(-629663391.5165792))&(tmp = 3182319856.674114, tmp))));
- assertEquals(1.3702811563654176e+27, x *= ((((3061414617.6321163)/(tmp = 2628865442, tmp))+(-1549548261))+(x&((tmp = 809684398, tmp)|(x^(tmp = 801765002, tmp))))));
- assertEquals(0, x >>>= ((-2988504159)&((tmp = -260444190.02252054, tmp)^(2178729442.260293))));
- assertEquals(-1518607002, x -= (tmp = 1518607002, tmp));
- assertEquals(724566016, x <<= (tmp = 1042915731.7055794, tmp));
- assertEquals(707584, x >>>= (-208959862.93305588));
- assertEquals(0, x >>>= (((tmp = 877181764, tmp)>>(-970697753.3318911))%x));
- assertEquals(0, x ^= x);
- assertEquals(0, x += x);
- assertEquals(0, x <<= x);
- assertEquals(0, x /= (x^((x/(-2903618412.4936123))+(tmp = 1169288899, tmp))));
- assertEquals(0, x >>>= x);
- assertEquals(-1302645245, x ^= ((1855892732.3544865)+(tmp = 1136429319.5633948, tmp)));
- assertEquals(0, x ^= x);
- assertEquals(0, x &= (-1384534597.409375));
- assertEquals(-0, x /= (tmp = -680466419.8289509, tmp));
- assertEquals(-0, x *= (318728599.95017374));
- assertEquals(NaN, x %= (x>>(2019695267)));
- assertEquals(0, x >>= (tmp = 1280789995, tmp));
- assertEquals(0, x *= (tmp = 2336951458, tmp));
- assertEquals(0, x >>= ((2981466013.758637)%(731947033)));
- assertEquals(0, x -= x);
- assertEquals(0, x ^= x);
- assertEquals(0, x /= ((((3068070149.1452317)>>x)%(((1448965452)*((tmp = -2961594129, tmp)+(1829082104.0681171)))>>(-2331499703)))>>>(tmp = -3206314941.2626476, tmp)));
- assertEquals(0, x >>= (x%(1869217101.9823673)));
- assertEquals(0, x <<= (x+x));
- assertEquals(0, x >>>= ((1202130282)>>>x));
- assertEquals(0, x += x);
- assertEquals(2603245248.6273212, x += (tmp = 2603245248.6273212, tmp));
- assertEquals(-1691864471, x ^= (x>>>(2504513614.117516)));
- assertEquals(136835305, x -= ((-1618979896)&(-746953306)));
- assertEquals(-2568499564.1261334, x += (tmp = -2705334869.1261334, tmp));
- assertEquals(1038075700, x ^= (1530399136));
- assertEquals(2076151400, x += x);
- assertEquals(-524018410.1751909, x -= ((2398973627.175191)-(-201196183)));
- assertEquals(0.327110599608614, x /= ((3181340288.602796)&x));
- assertEquals(0.327110599608614, x %= (tmp = -2284484060, tmp));
- assertEquals(0, x |= x);
- assertEquals(403217947.5779772, x += (tmp = 403217947.5779772, tmp));
- assertEquals(403217947, x |= x);
- assertEquals(-Infinity, x *= ((58693583.845808744)+(((tmp = -1527787016, tmp)*x)/((((2532689893.3191843)/(tmp = 2781746479.850424, tmp))|(((((460850355.9211761)/((((tmp = 626683450, tmp)<<((tmp = 1349974710, tmp)-((tmp = -1349602292, tmp)/(-2199808871.1229663))))>>((x/(-3092436372.3078623))&(tmp = -1190631012.0323825, tmp)))^((-2907082828.4552956)-(tmp = 1858683340.1157017, tmp))))^(-1513755598.5398848))%x)/x))&(1147739260.136806)))));
- assertEquals(0, x &= (tmp = -3047356844.109563, tmp));
- assertEquals(637934616, x -= (tmp = -637934616, tmp));
- assertEquals(-1553350083, x ^= (-2056266203.094929));
- assertEquals(-0.13467351026547192, x %= ((tmp = 824736251, tmp)/(2544186314)));
- assertEquals(1, x /= x);
- assertEquals(1, x |= x);
- assertEquals(0, x >>>= (2166609431.9515543));
- assertEquals(0, x <<= (x|(tmp = 121899222.14603412, tmp)));
- assertEquals(0, x *= (1300447849.6595674));
- assertEquals(0, x %= (tmp = -2360500865.3944597, tmp));
- assertEquals(0, x %= (tmp = -1693401247, tmp));
- assertEquals(0, x >>= x);
- assertEquals(0, x /= (471265307));
- assertEquals(257349748, x ^= (257349748.689448));
- assertEquals(257349748, x &= x);
- assertEquals(981, x >>>= (tmp = -1959001422, tmp));
- assertEquals(0, x >>= ((-79932778.18114972)/x));
- assertEquals(0, x <<= (((-2599621472)^(tmp = 662071103, tmp))%(tmp = -2675822640.7641535, tmp)));
- assertEquals(0, x &= (tmp = 2582354953.878623, tmp));
- assertEquals(0, x /= ((-953254484)/((-2571632163.376176)-(tmp = -342034471, tmp))));
- assertEquals(0, x <<= ((x-(tmp = -3013057672, tmp))&(tmp = -3204761036, tmp)));
- assertEquals(0, x ^= ((x&((515934453)>>>x))/x));
- assertEquals(1, x |= ((-1914707646.2075093)>>>(tmp = -1918045025, tmp)));
- assertEquals(-2002844120.8792589, x += (tmp = -2002844121.8792589, tmp));
- assertEquals(573030794, x >>>= (tmp = 1707788162, tmp));
- assertEquals(1.917619109627369, x /= ((1909436830.484202)%((123114323)<<(tmp = -1288988388.6444468, tmp))));
- assertEquals(-1400358045, x |= (-1400358046));
- assertEquals(-2043022529.4273133, x += (tmp = -642664484.4273133, tmp));
- assertEquals(-81408068.86728716, x %= (tmp = -980807230.2800131, tmp));
- assertEquals(0.1436896445024992, x /= (((tmp = 3201789924.913518, tmp)%(tmp = -962242528.6008646, tmp))^((tmp = -338830119.55884504, tmp)*(tmp = -916120166, tmp))));
- assertEquals(0.1436896445024992, x %= (tmp = 2598469263, tmp));
- assertEquals(0, x *= (x-x));
- assertEquals(-1409286144, x += (((-111514798.64745283)|(2372059654))<<(tmp = 175644313, tmp)));
- assertEquals(-2393905467.0073113, x += (-984619323.0073113));
- assertEquals(-835111172.0073113, x %= (x^(-765900532.5585573)));
- assertEquals(-835111172.0073113, x %= (tmp = -946478116, tmp));
- assertEquals(-100, x >>= ((-1020515908)>>(((x&((x^(169474253.53811646))>>(-221739002)))+x)*((201939882.92880356)/(tmp = -50402570, tmp)))));
- assertEquals(2131506964, x &= (tmp = -2163460268, tmp));
- assertEquals(1074275840, x &= ((-1561930379.8719592)*(tmp = -2871750052.876917, tmp)));
- assertEquals(-954232605.5377102, x -= (tmp = 2028508445.5377102, tmp));
- assertEquals(-29, x >>= (-279577351.87217045));
- assertEquals(-232, x <<= x);
- assertEquals(-70, x |= (215185578));
- assertEquals(-1, x >>= (x>>(-1691303095)));
- assertEquals(1, x /= x);
- assertEquals(3149465364.2236686, x *= (3149465364.2236686));
- assertEquals(3304787832.3790073, x += (tmp = 155322468.15533853, tmp));
- assertEquals(100068712.23500109, x %= (tmp = 3204719120.1440063, tmp));
- assertEquals(91628864, x &= (tmp = 629090241, tmp));
- assertEquals(-113202292046379710, x *= (-1235443583));
- assertEquals(122, x >>>= (tmp = 3196555256, tmp));
- assertEquals(122, x >>>= (((2226535734)-x)^(2248399036.393125)));
- assertEquals(6.904199169070746e-8, x /= (tmp = 1767040564.9149356, tmp));
- assertEquals(-212687449.99999994, x += ((((2244322375)*(((2515994102)^x)>>x))<<(x-(-832407685.3251972)))^(2266670502)));
- assertEquals(366515938514778750, x *= (tmp = -1723260768.3940866, tmp));
- assertEquals(366515938514778750, x += ((-1643386193.9159095)/(tmp = 425161225.95316494, tmp)));
- assertEquals(654872716.4123061, x /= ((-1377382984)-(tmp = -1937058061.811642, tmp)));
- assertEquals(654872716, x &= x);
- assertEquals(-86260926.17813063, x -= (tmp = 741133642.1781306, tmp));
- assertEquals(1052176592, x >>>= x);
- assertEquals(2020882856, x ^= (-3107796616));
- assertEquals(0, x <<= ((606939871.9812952)|(tmp = -3127138319.1557302, tmp)));
- assertEquals(NaN, x -= ((x%((1120711400.2242608)%x))*(tmp = -930171286.7999947, tmp)));
- assertEquals(NaN, x %= (3215044180));
- assertEquals(NaN, x %= (tmp = 2882893804.20102, tmp));
- assertEquals(NaN, x %= ((217170359.5778643)^x));
- assertEquals(0, x &= ((-1095125960.9903677)>>(x^(-2227981276))));
- assertEquals(-748549860, x += (-748549860));
- assertEquals(1816208256, x <<= (-610872411.3826082));
- assertEquals(201400576, x &= (((tmp = 1910394603.4836266, tmp)<<x)^x));
- assertEquals(0, x %= x);
- assertEquals(NaN, x %= x);
- assertEquals(0, x <<= (((((2670901339.6696005)%(2180020861))*((2134469504)/(2237096063.0680027)))*((tmp = 1203829756, tmp)>>((765467065)+(x|(2673651811.9494815)))))<<((-1463378514)|(((x/(tmp = -1075050081, tmp))-((-879974865)+x))>>>(tmp = 2172883926, tmp)))));
- assertEquals(433013198, x ^= (433013198.2833413));
- assertEquals(0, x >>= ((((-2404431196)%(x%(tmp = 1443152875.8809233, tmp)))&(x|((1414364997.0517852)/((tmp = -435854369, tmp)+(tmp = 2737625141, tmp)))))|(((tmp = 2241746562.2197237, tmp)^(tmp = -1606928010.1992552, tmp))|((tmp = -3083227418.686173, tmp)>>(tmp = -2717460410, tmp)))));
- assertEquals(0, x >>= x);
- assertEquals(0, x *= ((tmp = 2302521322, tmp)>>>(((((((tmp = 344089066.9725498, tmp)%(tmp = 1765830559, tmp))-x)|x)^(((-2450263325)/(tmp = 371928405.17475057, tmp))>>>(1330100413.7731652)))^(((173024329)%(tmp = -2927276187, tmp))+(x>>>(-1042229940.308507))))|(((((tmp = 379074096, tmp)+((142762508)-((-2773070834.526266)-(x&((tmp = 57957493, tmp)<<(2189553500))))))+((36991093)+(tmp = 339487168.58069587, tmp)))*(-1257565451))&(tmp = 645233114, tmp)))));
- assertEquals(-2644503151.1185284, x += (-2644503151.1185284));
- assertEquals(-5289006302.237057, x += x);
- assertEquals(-4008773824.2370567, x -= (tmp = -1280232478, tmp));
- assertEquals(1975449413, x |= ((tmp = 1957832005.4285066, tmp)>>((1681236712.9715524)&(-675823978))));
- assertEquals(-146472960, x <<= (-648510672.5644083));
- assertEquals(-3, x |= (((((x>>>(tmp = 2271744104, tmp))+(tmp = -210058133.30147195, tmp))+(tmp = -2827493425, tmp))/(tmp = 765962538, tmp))%(tmp = 1048631551, tmp)));
- assertEquals(1, x /= x);
- assertEquals(0, x >>= (1070524782.5154183));
- assertEquals(0, x <<= (462502504));
- assertEquals(0, x %= (540589670.0730014));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x /= ((-1268640098)%x));
- assertEquals(NaN, x %= (1741157613.744652));
- assertEquals(NaN, x += x);
- assertEquals(NaN, x %= ((x|(tmp = 1992323492.7000637, tmp))*x));
- assertEquals(NaN, x /= ((tmp = -2271503368.0341196, tmp)>>((tmp = 1224449194, tmp)>>>(tmp = 2976803997, tmp))));
- assertEquals(NaN, x += (tmp = -1078313742.1633894, tmp));
- assertEquals(NaN, x += (-787923311));
- assertEquals(NaN, x %= x);
- assertEquals(-1299878219, x ^= (2995089077));
- assertEquals(536887953, x &= ((625660571.2651105)&(x^(((tmp = 950150725.2319129, tmp)+(-2122154205.466675))/(tmp = 1754964696.974752, tmp)))));
- assertEquals(4096, x >>>= x);
- assertEquals(1, x /= x);
- assertEquals(-82508517, x ^= (((-930231800)%(tmp = -423861640.4356506, tmp))+x));
- assertEquals(-82508517, x &= (x&x));
- assertEquals(-479519, x %= ((tmp = 1861364600.595756, tmp)|x));
- assertEquals(479518, x ^= (((x>>(-1539139751.6860313))>>(tmp = -456165734, tmp))|(-2786433531)));
- assertEquals(959036, x += x);
- assertEquals(29, x >>>= ((tmp = -1049329009.7632706, tmp)^(((((((1117739997)/(((-841179741.4939663)*(-1211599672))>>>((-413696355)%(tmp = -1753423217.2170188, tmp))))<<(tmp = 1599076219.09274, tmp))>>>(-1382960317))^(((x^(tmp = 515115394, tmp))>>>(tmp = -388476217, tmp))>>>(x/x)))^x)<<(136327532.213817))));
- assertEquals(24, x &= (2388755418));
- assertEquals(0, x >>>= (tmp = -405535917, tmp));
- assertEquals(0, x &= (tmp = -1427139674, tmp));
- assertEquals(NaN, x /= (x^((1530470340)%x)));
- assertEquals(0, x |= ((x>>(-1429690909.8472774))*((((tmp = 2033516515, tmp)/(1314782862))>>>x)>>(tmp = 1737186497.6441216, tmp))));
- assertEquals(0, x -= x);
- assertEquals(0, x %= (3115422786));
- assertEquals(-0, x *= (x+(tmp = -2558930842.267017, tmp)));
- assertEquals(NaN, x %= x);
- assertEquals(0, x &= (2695531252.254449));
- assertEquals(-613178182, x ^= (-613178182));
- assertEquals(54, x >>>= (x%(((tmp = 2277868389, tmp)^((((tmp = -1143932265.3616111, tmp)^((x&((x-((-2100384445.7850044)|(tmp = 908075129.3456883, tmp)))*x))+(((tmp = 1031013284.0275401, tmp)*((((tmp = -233393205, tmp)>>>(tmp = -111859419, tmp))*(-1199307178))|(tmp = -1998399599, tmp)))>>>((((-731759641.9036775)>>>(tmp = 2147849691, tmp))>>>(tmp = -2121899736, tmp))>>>(x>>>x)))))>>((1900348757.360562)^(tmp = 2726336203.6149445, tmp)))>>>((x*((tmp = -2697628471.0234947, tmp)%((x^(tmp = -2751379613.9474974, tmp))*x)))+(x>>(tmp = 42868998.384643435, tmp)))))+(598988941))));
- assertEquals(34, x &= ((tmp = 2736218794.4991407, tmp)%(2169273288.1339874)));
- assertEquals(2.086197133417468, x /= ((tmp = 2176358852.297597, tmp)%x));
- assertEquals(2, x <<= (((tmp = -1767330075, tmp)|(-3107230779.8512735))&x));
- assertEquals(4194304, x <<= (tmp = 1061841749.105744, tmp));
- assertEquals(48609515, x ^= (44415211.320786595));
- assertEquals(48609515, x %= (1308576139));
- assertEquals(23735, x >>>= ((-324667786)-x));
- assertEquals(23735, x <<= ((-1270911229)<<(((((tmp = -882992909.2692418, tmp)+(tmp = 394833767.947718, tmp))-x)<<(702856751))/x)));
- assertEquals(-31080872939240, x *= (tmp = -1309495384, tmp));
- assertEquals(-14625.31935626114, x /= ((668084131)+(1457057357)));
- assertEquals(-14625.31935626114, x %= (266351304.6585492));
- assertEquals(-12577, x |= (-945583977.619837));
- assertEquals(-4097, x |= ((tmp = -2621808583.2322493, tmp)-(tmp = -2219802863.9072213, tmp)));
- assertEquals(-1004843865, x &= ((-1004839768)+((tmp = 2094772311, tmp)/(-1340720370.275643))));
- assertEquals(-31401371, x >>= ((2035921047)>>>((tmp = -1756995278, tmp)>>>(-537713689))));
- assertEquals(1791746374.016472, x -= ((tmp = -1823147745, tmp)-(x/(tmp = -1906333520, tmp))));
- assertEquals(3.7289343120517406, x /= (tmp = 480498240, tmp));
- assertEquals(7.457868624103481, x += x);
- assertEquals(234881024, x <<= (-781128807.2532628));
- assertEquals(67108864, x &= (tmp = -2060391332, tmp));
- assertEquals(-605958718, x -= (673067582));
- assertEquals(-605958718, x <<= ((x%x)&((tmp = 1350579401.0801518, tmp)|x)));
- assertEquals(-109268090.4715271, x %= (tmp = -496690627.5284729, tmp));
- assertEquals(-109268090, x <<= (((-2004197436.8023896)%((x|((tmp = 271117765.61283946, tmp)-((1595775845.0754795)*(555248692.2512416))))/x))<<x));
- assertEquals(-652725370, x &= (-543590449));
- assertEquals(0.321858133298825, x /= (tmp = -2027990914.2267523, tmp));
- assertEquals(1959498446, x ^= (1959498446));
- assertEquals(1959498446, x &= (x%(tmp = 3155552362.973523, tmp)));
- assertEquals(14949, x >>>= ((tmp = 586618136, tmp)>>>(tmp = 699144121.9458897, tmp)));
- assertEquals(-28611391568319.285, x *= (tmp = -1913933478.3811147, tmp));
- assertEquals(1680557633, x &= (((tmp = 2606436319.199714, tmp)<<(1575299025.6917372))|((-1092689109)/(735420388))));
- assertEquals(1680361024, x &= ((tmp = 1860756552.2186172, tmp)|(-360434860.1699109)));
- assertEquals(820488, x >>>= (1788658731));
- assertEquals(820488, x >>= (-1555444352));
- assertEquals(2104296413, x ^= (2103543509));
- assertEquals(16843328, x &= ((x<<((-2920883149)/(1299091676)))-(((((tmp = 3199460211, tmp)+(-237287821.61504316))&(tmp = -1524515028.3596857, tmp))-(tmp = -700644414.6785603, tmp))+(-180715428.86124516))));
- assertEquals(1326969834, x |= (tmp = -2968063574.793867, tmp));
- assertEquals(0, x %= (x>>>(tmp = 1350490461.0012388, tmp)));
- assertEquals(0, x &= ((-2620439260.902854)+x));
- assertEquals(-1775533561, x |= ((-1775533561)|(((x>>>((861896808.2264911)>>>(970216466.6532537)))%x)%(tmp = 2007357223.8893046, tmp))));
- assertEquals(-1775533561, x &= x);
- assertEquals(-23058877.415584415, x /= ((tmp = -3002439857, tmp)>>((((x-(tmp = 1583620685.137125, tmp))|x)%(-2568798248.6863875))^x)));
- assertEquals(-577.4155844151974, x %= (((-1440361053.047877)+((tmp = 821546785.0910633, tmp)-(((tmp = 1023830881.1444875, tmp)/(-754884477))+(tmp = 651938896.6258571, tmp))))>>(tmp = 346467413.8959185, tmp)));
- assertEquals(-1, x >>= (tmp = 2993867511, tmp));
- assertEquals(-1, x |= (tmp = 823150253.4916545, tmp));
- assertEquals(-0, x %= x);
- assertEquals(-0, x /= ((tmp = 997969036, tmp)&((((tmp = 928480121, tmp)>>(((-2610875857.086055)>>>(tmp = -2251704283, tmp))|x))+(10781750))>>x)));
- assertEquals(0, x >>>= ((tmp = -1872319523, tmp)>>>(-278173884)));
- assertEquals(0, x |= (x/(x*x)));
- assertEquals(0, x %= ((77912826.10575807)^(tmp = 2770214585.3019757, tmp)));
- assertEquals(0, x &= (tmp = 722275824, tmp));
- assertEquals(-1417226266, x |= (tmp = 2877741030.1195555, tmp));
- assertEquals(0, x ^= x);
- assertEquals(0, x %= (tmp = -1740126105, tmp));
- assertEquals(910709964, x |= (tmp = 910709964, tmp));
- assertEquals(-1744830464, x <<= (tmp = -2445932551.1762686, tmp));
- assertEquals(318767104, x >>>= (tmp = -2465332061.628887, tmp));
- assertEquals(301989888, x &= (-2771167302.022801));
- assertEquals(301989888, x |= x);
- assertEquals(37748736, x >>= (tmp = -835820125, tmp));
- assertEquals(1474977371, x ^= (tmp = -2857738661.6610327, tmp));
- assertEquals(470467500, x += (-1004509871));
- assertEquals(0.30466562575942585, x /= (((tmp = 1515955042, tmp)<<(x+((1607647367)-(tmp = 1427642709.697169, tmp))))^x));
- assertEquals(1.0348231148499734e-10, x /= (tmp = 2944132397, tmp));
- assertEquals(0, x >>= (x>>>(tmp = -2847037519.569043, tmp)));
- assertEquals(NaN, x /= x);
- assertEquals(0, x >>>= (-1817784819.9058492));
- assertEquals(0, x >>= x);
- assertEquals(-0, x *= ((tmp = -1387748473, tmp)|(x+(352432111))));
- assertEquals(-0, x *= (((-2591789329)/(tmp = -2144460203, tmp))>>(tmp = -568837912.5033123, tmp)));
- assertEquals(0, x <<= (-2963600437.305708));
- assertEquals(0, x &= ((588720662)>>>x));
- assertEquals(1561910729, x += (1561910729));
- assertEquals(0, x ^= x);
- assertEquals(-0, x *= (-2722445702));
- assertEquals(0, x &= (tmp = -2738643199.732308, tmp));
- assertEquals(0, x /= (((1859901899.227291)>>>((tmp = -1067365693, tmp)+((-1975435278)|x)))|((1844023313.3719304)&(tmp = -624215417.0227654, tmp))));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x %= (-2852766277));
- assertEquals(0, x <<= (-1482859558));
- assertEquals(0, x >>= x);
- assertEquals(-1196775786, x += (tmp = -1196775786, tmp));
- assertEquals(-68176201, x |= ((tmp = 2336517643, tmp)+x));
- assertEquals(0, x ^= x);
- assertEquals(0, x <<= x);
- assertEquals(0, x >>= (2969141362.868086));
- assertEquals(NaN, x %= x);
- assertEquals(0, x >>= ((x-((((tmp = -905994835, tmp)|(tmp = 2850569869.33876, tmp))<<((-2405056608.27147)>>(tmp = 1280271785, tmp)))&(-1942926558)))*(tmp = 707499803.177796, tmp)));
- assertEquals(0, x &= ((-697565829.8780258)+((2978584888.549406)%x)));
- assertEquals(0, x >>= (748642824.4181392));
- assertEquals(0, x += x);
- assertEquals(0, x >>>= (-1701028721));
- assertEquals(92042539, x -= ((-92042539)|(x*(x%(-293705541.00228095)))));
- assertEquals(0, x %= x);
- assertEquals(0, x >>= x);
- assertEquals(0, x %= (-2278672472.458228));
- assertEquals(0, x %= (((-2374117528.0359464)/((tmp = -2809986062, tmp)|(tmp = 895734980, tmp)))&(tmp = 1564711307.41494, tmp)));
- assertEquals(0, x >>>= x);
- assertEquals(0, x += x);
- assertEquals(-0, x /= ((tmp = -2749286790.3666043, tmp)<<(x^(-2966741582.324482))));
- assertEquals(0, x *= x);
- assertEquals(0, x >>>= x);
- assertEquals(-1882562314, x ^= (2412404982.782115));
- assertEquals(-806620, x %= (((tmp = 1527219936.5232096, tmp)*(-1139841417))>>>(tmp = 201632907.3236668, tmp)));
- assertEquals(-1613240, x += x);
- assertEquals(-1664766177387640, x *= (1031939561));
- assertEquals(-9.478083550117849e+23, x *= (tmp = 569334221.1571662, tmp));
- assertEquals(-8.462574598319509e+21, x /= ((x-(tmp = -2985531211.114498, tmp))>>(tmp = 174615992.91117632, tmp)));
- assertEquals(1638924288, x <<= (((((x>>((-1823401733.4788911)+((tmp = 1362371590, tmp)>>>x)))^(tmp = -56634380, tmp))/(tmp = 2387980757.1540084, tmp))%((((tmp = -3175469977, tmp)^(tmp = -1816794042, tmp))+(232726694))*(tmp = 822706176, tmp)))/(tmp = 1466729893.836311, tmp)));
- assertEquals(2686072821796307000, x *= x);
- assertEquals(-1007977445.9812208, x /= (-2664814408.800125));
- assertEquals(-1007977445, x &= x);
- assertEquals(322314656346249100, x *= (tmp = -319763758.54942775, tmp));
- assertEquals(197436885.26815608, x /= (tmp = 1632494637, tmp));
- assertEquals(-67191339, x |= ((-399580815.1746769)/((1335558363)/(tmp = 224694526, tmp))));
- assertEquals(1229588737, x &= (tmp = 1296763683.5732255, tmp));
- assertEquals(1229588737, x -= ((((1171546503)|((tmp = -2701891308, tmp)%(-2155432197.022206)))/(-306122816.85682726))>>x));
- assertEquals(4162606632, x -= (tmp = -2933017895, tmp));
- assertEquals(1.6487311395551163, x /= (2524733434.1748486));
- assertEquals(-1929308648.9913044, x += (-1929308650.6400356));
- assertEquals(-3858617297.982609, x += x);
- assertEquals(788529152, x <<= (x^(1401824663)));
- assertEquals(6160384, x >>>= ((((((x>>>x)>>((((x*(tmp = -1958877151, tmp))>>>(1310891043))-(tmp = 564909413.9962088, tmp))%(-175978438)))%x)|((tmp = -1193552419.7837512, tmp)*(tmp = 1508330424.9068346, tmp)))|(1428324616.3303494))-((1828673751)/(tmp = 1281364779, tmp))));
- assertEquals(6160384, x |= x);
- assertEquals(1, x /= x);
- assertEquals(1, x &= (tmp = -855689741, tmp));
- assertEquals(0, x >>>= x);
- assertEquals(-1088569655.3528988, x -= (tmp = 1088569655.3528988, tmp));
- assertEquals(-1088569655, x >>= ((tmp = 2429646226.626727, tmp)<<((-1539293782.4487276)>>(x^((tmp = 1140855945.537702, tmp)+x)))));
- assertEquals(-311, x %= ((x/x)<<x));
- assertEquals(1.2007722007722008, x /= (x|(tmp = 448796341.87655175, tmp)));
- assertEquals(3, x |= (x+x));
- assertEquals(-9.32416092168023e-10, x /= (-3217447688));
- assertEquals(0, x >>= (615837464.0921166));
- assertEquals(0, x >>>= (tmp = -2993750670.683118, tmp));
- assertEquals(0, x >>>= (x%x));
- assertEquals(1610612736, x ^= ((-1322905256.6770213)<<(-2567950598)));
- assertEquals(1693676493, x ^= (83063757.63660407));
- assertEquals(-758030371, x ^= (tmp = -1239274480, tmp));
- assertEquals(-758030371, x %= (tmp = 1961339006, tmp));
- assertEquals(-1509754528, x ^= (tmp = 1960027837, tmp));
- assertEquals(-1509754528, x <<= x);
- assertEquals(-1509754528, x -= (((tmp = -50690205.33559728, tmp)/((tmp = -1364565380, tmp)<<(tmp = 2585052504, tmp)))<<(tmp = -2356889596, tmp)));
- assertEquals(1, x >>>= (-3204164321));
- assertEquals(1, x *= x);
- assertEquals(1114370230.591965, x *= ((tmp = 1114370229.591965, tmp)+x));
- assertEquals(-4.886305275432552, x /= ((-228059887.33344483)%(2841553631.3685856)));
- assertEquals(2.358309397373389e-9, x /= (((x*(tmp = 203428818.08174622, tmp))&(x-(((510438355)*x)+x)))+x));
- assertEquals(0, x >>>= ((tmp = 1444810010, tmp)&(tmp = -3135701995.2235208, tmp)));
- assertEquals(0, x /= (1865982928.6819582));
- assertEquals(0, x *= x);
- assertEquals(2078726016.3772051, x -= (tmp = -2078726016.3772051, tmp));
- assertEquals(1580337898, x ^= ((tmp = -2714629398.447015, tmp)^x));
- assertEquals(1268363034, x -= ((x+((tmp = 1144068248.3834887, tmp)&(-954104940.155973)))<<(tmp = 1270573731.7828264, tmp)));
- assertEquals(1744830464, x <<= (((1444869551.7830744)>>>((((x+(tmp = -904688528, tmp))<<x)-((tmp = 121151912.85873199, tmp)/(tmp = -2414150217.66479, tmp)))|(((-472906698)|(3215236833.8417764))+(907737193.9056952))))-((x&(-732223723))|(-221800427.7392578))));
- assertEquals(717338523283226600, x *= (x^(tmp = -2407450097.0604715, tmp)));
- assertEquals(402653184, x >>= ((-3191405201.168252)*((tmp = -1941299639.695196, tmp)|(((x>>(((3215741220)>>>x)/(x+x)))^(((tmp = -2144862025.9842231, tmp)|((tmp = -1966913385, tmp)&x))%x))*((tmp = -1124749626.6112225, tmp)/(tmp = 837842574, tmp))))));
- assertEquals(402653184, x &= ((x|x)>>x));
- assertEquals(134217728, x &= ((2720231644.3849487)*x));
- assertEquals(134217726.75839183, x -= ((2438054684.738043)/(((((-984359711)*(x|((tmp = 177559682, tmp)^x)))/(-1253443505))/((2727868438.416792)*(x+((x<<(((tmp = 3023774345, tmp)&(-705699616.0846889))/x))<<x))))^(1963626488.548761))));
- assertEquals(1, x /= x);
- assertEquals(245781494, x += ((tmp = 2551445099, tmp)^(2528486814)));
- assertEquals(-1474427807, x ^= (-1497868393.342241));
- assertEquals(-1057271682, x += ((((((x>>x)%(-1556081693))|(x/(((1166243186.6325684)-(((tmp = 2870118257.1019487, tmp)/(x+(-69909960)))^(2270610694.671496)))/((1463187204.5849519)-x))))-x)-(x<<(-3077313003)))%x));
- assertEquals(-1065725846, x &= ((tmp = -1808223767, tmp)|(-481628214.3871765)));
- assertEquals(-1065725846, x ^= (x&(((tmp = -1785170598, tmp)-(tmp = -2525350446.346484, tmp))/((((((-1783948056)^(tmp = 3027265884.41588, tmp))|((((tmp = 2195362566.2237773, tmp)<<(-2919444619))<<((tmp = -2507253075.2897573, tmp)^(x^((tmp = 1067516137, tmp)+((667737752)^(x*(tmp = -1187604212.7293758, tmp)))))))%(-617406719.5140038)))*(tmp = 511060465.6632478, tmp))*((tmp = 2580189800.752836, tmp)|((((tmp = 2357895660, tmp)%((-814381220)*(x-((x>>>(((x<<x)<<(tmp = 1919573020, tmp))-x))>>>((-2756011312.136148)>>(tmp = -1603458856, tmp))))))/((tmp = -1609199312, tmp)&(-3127643445)))%x)))<<(-2261731798)))));
- assertEquals(1.6020307924030301, x /= (tmp = -665234308.2628405, tmp));
- assertEquals(-1120020556.697667, x *= (tmp = -699125486.2321637, tmp));
- assertEquals(-215875188, x -= (((((tmp = -1307845034, tmp)>>>((((-2820720421)^x)-(((x<<x)|(tmp = -3042092997.57406, tmp))+(((-1294857544)+((tmp = -668029108.1487186, tmp)>>(x<<x)))^(912144065.5274727))))^(389671596.2983854)))|(-2774264897.146559))%(x-((tmp = 1378085269, tmp)^x)))+((-1659377450.5247462)&(((1613063452.834885)>>>((-344896580.0694165)>>>((-13450558)+x)))^x))));
- assertEquals(1, x /= x);
- assertEquals(0, x >>>= (2355750790));
- assertEquals(1969435421.4409347, x += (1969435421.4409347));
- assertEquals(0, x -= x);
- assertEquals(0, x >>>= (((x*((-1022802960.6953495)<<(tmp = -2848428731.8339424, tmp)))^(-1630921485))%(1532937011)));
- assertEquals(0, x <<= ((x+((x^(x^(tmp = 2017651860, tmp)))&(((x<<(((tmp = -1913317290.8189478, tmp)|(x-((((x%((tmp = -3035245210, tmp)+(-2270863807)))>>>((-2351852712)*(x^(-2422943296.0239563))))&((((-1578312517)%x)*x)*(-65592270.28452802)))>>>(tmp = 1104329727.2094703, tmp))))-(tmp = -1431159990.3340137, tmp)))&x)|((tmp = -2589292678.801344, tmp)&(x+((((tmp = -2557773457.456996, tmp)>>(451910805.309445))-x)>>(((tmp = -1937832765.7654495, tmp)^x)%x)))))))%x));
- assertEquals(0, x %= (tmp = -626944459, tmp));
- assertEquals(-732310021, x |= (tmp = -732310021, tmp));
- assertEquals(-732310021, x |= x);
- assertEquals(671352839, x ^= (x-((-3087309090.7153115)|x)));
- assertEquals(134479872, x &= (tmp = 2357183984, tmp));
- assertEquals(18084835973136384, x *= x);
- assertEquals(0, x <<= ((1040482277)-(tmp = -357113781.82650447, tmp)));
- assertEquals(74957, x |= ((((tmp = -70789345.7489841, tmp)%(tmp = 1415750131, tmp))&x)|((307027314)>>(2284275468))));
- assertEquals(9, x >>>= x);
- assertEquals(0, x &= (x&((x*((x*(x%x))%(x>>x)))/x)));
- assertEquals(-1872875060, x |= (2422092236.6850452));
- assertEquals(9, x >>>= (-382763684));
- assertEquals(4608, x <<= x);
- assertEquals(40.480234260614935, x /= (((((((tmp = 814638767.5666755, tmp)&((tmp = 2081507162, tmp)^(x>>>(1460148331.2229118))))&(tmp = 1187669197.7318723, tmp))<<(412000677.93339765))^((tmp = 556111951, tmp)>>(tmp = -2232569601.292395, tmp)))&(-3006386864))/x));
- assertEquals(32, x &= (-3053435209.383913));
- assertEquals(418357217, x ^= (418357185));
- assertEquals(204275, x >>= ((-1188650337.9010527)^((51494580)%(-2544545273))));
- assertEquals(982392804, x += (((x+(((tmp = -982596937.9757051, tmp)+x)%(-2298479347)))^((((tmp = 1610297674.0732534, tmp)>>>x)*(((x>>(-2746780903.08599))&(-2376190704.247188))^(((20545353)/(tmp = 1468302977, tmp))-(x<<x))))>>(((-1434332028.0447056)/((tmp = 1983686888, tmp)&((tmp = 2324500847, tmp)%(394330230.6163173))))%(((-1129687479.2158055)+((-3127595161)*((-3066570223)&((tmp = 3192134577.4963055, tmp)/(-2697915283.3233275)))))+(-1112243977.5306559)))))|(x&(-2622725228))));
- assertEquals(-2735750653096133600, x *= (-2784782870.9218984));
- assertEquals(-1876329472, x |= ((((((2752866171)<<(-1681590319))/x)>>((tmp = 1451415208, tmp)>>>(1126858636.6634417)))+(((tmp = 2165569430.4844217, tmp)/x)^(((tmp = -1675421843.4364457, tmp)-(-2187743422.2866993))|x)))*x));
- assertEquals(3520612287495799000, x *= x);
- assertEquals(-200278016, x |= ((((-2379590931)%((((-1558827450.833285)&x)>>(-665140792))-((tmp = -445783631.05567217, tmp)+(tmp = 93938389.53113222, tmp))))/(3103476273.734701))^x));
- assertEquals(-9178285062592.75, x *= ((2042671875.7211144)%(((tmp = 589269308.0452716, tmp)/x)<<(-130695915.9934752))));
- assertEquals(60048960, x |= (x<<x));
- assertEquals(60048960, x <<= ((((((tmp = -2793966650, tmp)/(-2882180652))&(((x<<((tmp = -384468710, tmp)+(2236162820.9930468)))>>>((((969371919)>>((tmp = -3153268403.2565875, tmp)-((((573811084)/x)^(tmp = -968372697.4844134, tmp))>>>(((-3096129189)>>x)/(tmp = 830228804.6249363, tmp)))))<<(((1243972633.3592157)|x)&((-1687610429)&(tmp = -1945063977.458529, tmp))))<<(((tmp = -217456781.37068868, tmp)-(400259171.68077815))^x)))>>>x))%(((2728450651.300167)/(((-2713666705.089135)%(tmp = 740472459, tmp))^x))|x))^x)*(-2463032364)));
- assertEquals(60048960, x %= (tmp = -442107222.9513445, tmp));
- assertEquals(-1573781504, x <<= (960581227));
- assertEquals(1297, x >>>= (tmp = -1692919563, tmp));
- assertEquals(1297, x &= x);
- assertEquals(-3113308397155.233, x *= (tmp = -2400391979.3024154, tmp));
- assertEquals(-3115513013486.233, x -= (2204616331));
- assertEquals(-3113809649082.233, x -= (-1703364404));
- assertEquals(0, x >>>= (((-1181206665)-(550946816.586771))|(tmp = -2346300456, tmp)));
- assertEquals(0, x %= (tmp = 1649529739.2785435, tmp));
- assertEquals(0, x ^= ((tmp = -2452761827.2870226, tmp)%(((1090281070.5550141)/(tmp = 992149154.6500508, tmp))*(x<<((((((x>>>x)|((tmp = -2410892363, tmp)%(tmp = 2585150431.0231533, tmp)))/x)*(tmp = 1541294271, tmp))+x)&((97566561.77126992)&((((-640933510.1287451)&(((((x>>>((-1821077041)<<((tmp = -1138504062.093695, tmp)-(tmp = -181292160, tmp))))%x)-(x>>((x&(((tmp = 1067551355, tmp)/(x|(1004837864.8550552)))&(x-(-103229639.25084043))))&((tmp = 2064184671.210937, tmp)+((((tmp = -2245728052, tmp)|(1538407002.8365717))+(x<<((x>>((76549490)/(tmp = 628901902.6084052, tmp)))<<((x<<x)^(-1907669184)))))+(-1409123688))))))>>>((((-1911547456.933543)-((-512313175)+((tmp = -2620903017, tmp)^(tmp = 2148757592.244808, tmp))))<<((-1740876865)>>>x))+((tmp = 691314720.9488736, tmp)<<(614057604.4104803))))|(x^((tmp = -3040687.291528702, tmp)/(x^(((x+(-2899641915))^((tmp = -1220211746, tmp)/x))%x))))))^(tmp = 119850608, tmp))%(2091975696))))))));
- assertEquals(291273239, x -= (tmp = -291273239, tmp));
- assertEquals(2206394018, x += (1915120779));
- assertEquals(235641480, x <<= (x&(x&(-1810963865.1415658))));
- assertEquals(28764, x >>= ((tmp = -1927011875, tmp)^((tmp = -1986461808, tmp)|((-868139264.8399222)*((421956566)%(3068424525))))));
- assertEquals(-99780626900900, x *= ((tmp = -1512869526.3223472, tmp)+(tmp = -1956071751, tmp)));
- assertEquals(51218520, x &= (((-2353401311)>>>x)-(2216842509)));
- assertEquals(51218520, x >>>= ((tmp = -1534539302.6990812, tmp)<<x));
- assertEquals(-2147483648, x <<= (-292608644));
- assertEquals(-2147483648, x |= ((((((x<<((-2981292735)-x))>>((tmp = 2540545320.96558, tmp)&(tmp = -2343790880, tmp)))>>>((((((x^((-172697043.94487858)/((2627260337)>>(2879112814.1247935))))&(tmp = 3000943191, tmp))<<(tmp = 1094830905, tmp))-x)>>>x)>>((((tmp = 3095796200, tmp)^(x|(tmp = 1460377694, tmp)))<<(x^(tmp = -357546193, tmp)))/((2729539495)>>x))))%(tmp = 268894171.74961245, tmp))|(x>>(tmp = 2735650924, tmp)))/(-2197885357.09768)));
- assertEquals(-2147483648, x |= x);
- assertEquals(-1967162776824578000, x *= (tmp = 916031551, tmp));
- assertEquals(-2147483648, x &= x);
- assertEquals(-457743917756973060, x *= (tmp = 213153622, tmp));
- assertEquals(0, x >>>= ((((tmp = 2930076928.480559, tmp)+(x^x))<<(tmp = -1349755597.1280541, tmp))|(x+(2865632849))));
- assertEquals(0, x <<= ((x>>x)-(x>>(-2629977861))));
- assertEquals(0, x <<= x);
- assertEquals(NaN, x /= x);
- assertEquals(0, x |= x);
- assertEquals(0, x >>>= x);
- assertEquals(749327478, x |= ((tmp = 749327478, tmp)^(x>>(tmp = 881107862, tmp))));
- assertEquals(1897869364, x += (1148541886));
- assertEquals(463347, x >>>= (tmp = -726431220, tmp));
- assertEquals(-395990542, x += (-396453889));
- assertEquals(-2824792585.1675367, x -= (2428802043.1675367));
- assertEquals(-2147483648, x <<= (tmp = -1420072385.9175675, tmp));
- assertEquals(8388608, x >>>= (-2211390680.488455));
- assertEquals(8388608, x >>= (((x/(x|(((x^(((tmp = -2175960170.8055067, tmp)|((tmp = -1964957385.9669886, tmp)/(tmp = -475033330, tmp)))&((x|((tmp = 1386597019.2014387, tmp)>>((tmp = -2406589229.8801174, tmp)+x)))<<(tmp = -844032843.8415492, tmp))))>>(x^x))|x)))-((x&((tmp = 1858138856, tmp)*(-3156357504)))%x))<<(((2046448340)+x)/(-2645926916))));
- assertEquals(8359470765396279, x *= ((tmp = 871437183.7888144, tmp)-(-125089387.17460155)));
- assertEquals(0, x ^= x);
- assertEquals(-303039014, x += ((tmp = -2475713214, tmp)|(-372871718.2343409)));
- assertEquals(2655126577, x -= (-2958165591));
- assertEquals(1830332793, x ^= (tmp = -212161208, tmp));
- assertEquals(1830332793, x ^= (((2352454407.0126333)<<((((tmp = 3083552367, tmp)/x)-(-1243111279))-((tmp = -1669093976, tmp)%(((-757485455)-(tmp = -116051602, tmp))<<x))))>>(((((-2235071915.9536905)>>(tmp = -1284656185, tmp))-x)>>((-1807028069.7202528)>>>((x%((tmp = -3070857953.311804, tmp)+((tmp = 2759633693.441942, tmp)%((169489938)*(-1582267384)))))<<(x^((tmp = -787578860, tmp)<<x)))))>>((x/(x|(409464362)))-(tmp = -64033017, tmp)))));
- assertEquals(397605933.90319204, x %= (tmp = 716363429.548404, tmp));
- assertEquals(186400, x &= (((x%(-1745754586))>>>x)<<(x&(x&((-2163627752)-((1784050895)+(((-2864781121.899456)>>>x)&x)))))));
- assertEquals(186400, x %= (tmp = -423209729, tmp));
- assertEquals(186400, x <<= ((x<<(x+(1232575114.4447284)))*x));
- assertEquals(1386299, x ^= ((tmp = -1074209615, tmp)>>>(x>>>((tmp = -1456741008.2654872, tmp)>>((1724761067)>>(-2016103779.9084842))))));
- assertEquals(347302967.20758367, x -= (-345916668.20758367));
- assertEquals(1.9325619389304094, x /= (179711170.03359854));
- assertEquals(-3703324711.628227, x *= (tmp = -1916277371, tmp));
- assertEquals(-920980517031624800, x *= (tmp = 248690187.53332615, tmp));
- assertEquals(0, x &= (((tmp = -2753945953.082594, tmp)*x)-(172907186)));
- assertEquals(-0, x /= (((((-2744323543.187253)>>((tmp = 2663112845, tmp)>>(((-121791600)+(x^x))*(2758944252.4214177))))|x)/(tmp = -2746716631.6805267, tmp))-x));
- assertEquals(0, x ^= ((tmp = 983113117, tmp)&((2638307333)+((((tmp = 3076361304.56189, tmp)<<(-2663410588.5895214))%((-1109962112)-(tmp = -2381021732, tmp)))%((tmp = 410559095, tmp)&x)))));
- assertEquals(0, x <<= (tmp = 1510895336.5111506, tmp));
- assertEquals(0, x <<= (tmp = -1688348296.2730422, tmp));
- assertEquals(2269471424, x -= (-2269471424));
- assertEquals(-2022580224, x ^= (x%((tmp = 160999480.21415842, tmp)&x)));
- assertEquals(-2077171712, x &= (tmp = 3032415014.3817654, tmp));
- assertEquals(270727, x >>>= (2973489165.1553965));
- assertEquals(270727, x |= x);
- assertEquals(-1895894537, x |= ((tmp = -1895903118.129186, tmp)|x));
- assertEquals(-1895894537, x -= ((((((((3143124509)>>>(-2866190144.8724117))*((x>>((961021882)*(tmp = 2363055833.8634424, tmp)))/((2032785518)+((2713643671.3420825)>>((-447782997.0173557)*((tmp = 1174918125.3178625, tmp)*((((tmp = -541539365.548115, tmp)%(-359633101))|(1765169562.2880063))+(tmp = -2512371966.374508, tmp))))))))/x)>>(x*((((-847238927.6399388)&(857288850))%(-2427015402))^((2221426567)%(x+x)))))>>>x)<<((tmp = 2009453564.2808268, tmp)>>((2924411494)<<(x>>(tmp = -1240031020.8711805, tmp)))))%(tmp = 3118159353, tmp)));
- assertEquals(0, x ^= x);
- assertEquals(0, x %= (-30151583));
- assertEquals(-1035186736, x ^= ((tmp = -517593368, tmp)<<(tmp = 3216155585, tmp)));
- assertEquals(49740, x >>>= x);
- assertEquals(49740, x %= (640223506));
- assertEquals(388, x >>>= ((x>>(tmp = 3161620923.50496, tmp))+(2605183207)));
- assertEquals(776, x += x);
- assertEquals(-97905, x ^= ((((((tmp = 145447047.8783008, tmp)^(((x>>>(tmp = 3014858214.2409887, tmp))>>>(629911626.132971))>>(((x+((369309637.229408)-x))<<(-2661038814.9204755))*(x+(x%(3025191323.4780884))))))+x)*(-482550691))|(-632782135))/x));
- assertEquals(-97905, x %= ((((-492914681)-((-2508632959.269368)&(tmp = 1209318291, tmp)))>>(-723512989.459533))>>>(((-528429623.985692)&(x^(tmp = -925044503, tmp)))-(-1696531234))));
- assertEquals(9585389025, x *= x);
- assertEquals(-715425728, x <<= ((583763091)<<(-1223615295)));
- assertEquals(-520093696, x <<= ((tmp = -1891357699.671592, tmp)*(((tmp = 3206095739.5163193, tmp)+(-2908596651.798733))>>>((tmp = -2820415686, tmp)>>(x|((((tmp = -566367675.6250327, tmp)*(-959117054))>>((((-187457085.89686918)*x)*(tmp = -2394776877.5373516, tmp))>>>x))|(((tmp = 80478970.46290505, tmp)<<(tmp = 2173570349.493097, tmp))-(x/((-2896765964)-((x/((tmp = 198741535.7034216, tmp)%(436741457)))%(tmp = 2936044280.0587225, tmp)))))))))));
- assertEquals(-2520.5909527086624, x /= ((211290893.06029093)>>(663265322)));
- assertEquals(-2520.5909527086624, x %= (x^((1057915688)<<(tmp = 1914820571.1142511, tmp))));
- assertEquals(1, x >>>= (((894963408.7746166)+(tmp = -2888351666, tmp))|x));
- assertEquals(-1989841636629996300, x += ((1424670316.224575)*((-2144149843.0876865)|((((421479301.0983993)|((3082651798)^(tmp = -271906497, tmp)))>>x)+((tmp = -178372083, tmp)%x)))));
- assertEquals(17935384255.088326, x /= (((((((tmp = 1168194849.2361898, tmp)>>>(-107316520.53815603))>>>(x^(((x%((x>>>(((-2456622387)/x)&((2124689803)|(((-1130151701)^(2796315158))>>x))))-((-884686033.5491502)>>>((-2371185318.5358763)&x))))+(tmp = 558422989, tmp))|((tmp = -420359120.0596726, tmp)/((-1820568437.0587764)&(2298602280.266465))))))>>(x-((tmp = -1164568978, tmp)^x)))^x)-x)+x));
- assertEquals(134233150, x &= ((x>>(((tmp = 98498118.13041973, tmp)-(804574397))/(tmp = -1564490985.7904541, tmp)))+x));
- assertEquals(4, x >>= (449610809));
- assertEquals(1912543790, x |= (1912543790));
- assertEquals(2487274263, x += (tmp = 574730473, tmp));
- assertEquals(-2140759118, x ^= (tmp = 338055333.9701035, tmp));
- assertEquals(311607367, x += (2452366485));
- assertEquals(9509, x >>= (372113647.84365284));
- assertEquals(-2001075684.1562128, x += (-2001085193.1562128));
- assertEquals(-638703280, x ^= (((tmp = 1096152237, tmp)&x)|((2707404245.0966487)-(((tmp = 1550233654.9691348, tmp)+(tmp = 2008619647, tmp))&((tmp = -2653266325, tmp)+(tmp = -280936332, tmp))))));
- assertEquals(-101811850, x |= (-2250090202));
- assertEquals(-13, x >>= ((-561312810.0218933)|(tmp = 79838949.86521482, tmp)));
- assertEquals(-13, x >>= ((tmp = -936543584, tmp)/(1180727664.1746705)));
- assertEquals(-1547, x *= (((tmp = 1005197689, tmp)>>>x)>>>(tmp = 34607588, tmp)));
- assertEquals(2393209, x *= x);
- assertEquals(2393209, x |= x);
- assertEquals(0, x >>= (-2691279235.1215696));
- assertEquals(0, x *= (((896175510.4920144)*((((tmp = 1770236555.7788959, tmp)%(537168585.7310632))/x)&(tmp = 1094337576, tmp)))&(((x-x)-x)>>x)));
- assertEquals(-1922620126, x ^= (-1922620126));
- assertEquals(3.43481396325761, x /= (tmp = -559745053.6088333, tmp));
- assertEquals(0, x >>= x);
- assertEquals(0, x >>>= (tmp = 2106956255.6602135, tmp));
- assertEquals(-1339003770, x ^= ((tmp = 2955963526.960022, tmp)+x));
- assertEquals(-0, x *= ((((tmp = 368669994, tmp)>>>(x*x))<<(tmp = 2355889375, tmp))&(tmp = -2267550563.9174895, tmp)));
- assertEquals(0, x >>= (753848520.8946902));
- assertEquals(0, x >>>= x);
- assertEquals(0, x %= ((tmp = -2872753234.2257266, tmp)|x));
- assertEquals(NaN, x %= (x>>>(tmp = 890474186.0898918, tmp)));
- assertEquals(NaN, x %= ((tmp = 1341133992.284471, tmp)&(tmp = -2979219283.794898, tmp)));
- assertEquals(NaN, x += (-2865467651.1743298));
- assertEquals(NaN, x += ((-1424445677)%(x^(tmp = 1150366884, tmp))));
- assertEquals(0, x &= (x+((tmp = 1499426534, tmp)+x)));
- assertEquals(0, x |= (((((tmp = -2413914642, tmp)<<((x>>>x)^(1218748804)))+((((-1085643932.2642736)-(-1199134221.533854))>>(tmp = 2148778719, tmp))-((tmp = 1589158782.0040946, tmp)/(tmp = -2485474016.1575155, tmp))))>>>(x>>x))/(2230919719)));
- assertEquals(0, x %= ((tmp = -2576387170.517563, tmp)>>>((tmp = -2362334915.919525, tmp)>>>(((3096453582)-(700067891.4834484))^(2396394772.9253683)))));
- assertEquals(-1798103432, x ^= (((((tmp = 2396144191, tmp)*(x>>>(1512158325)))&(((-1256228298.5444434)&(((-2963136043.434966)&((tmp = 2472984854, tmp)+(tmp = -454900927, tmp)))%(tmp = 484255852.65332687, tmp)))>>((x%x)-x)))&(tmp = 929723984, tmp))^(tmp = -1798103432.5838807, tmp)));
- assertEquals(-2137913344, x &= ((((x|(-2970116473))&(((x/x)/((tmp = 2853070005, tmp)>>>x))%(((tmp = -3123344846, tmp)/((2224296621.6742916)-(tmp = -2246403296.455411, tmp)))+((x&(((x^(x*(2829687641)))+x)&(tmp = 988992521, tmp)))^x))))<<((((-820608336)^(tmp = 2851897085, tmp))>>(tmp = -402427624, tmp))>>>x))-(((x*(((-2287402266.4821453)%(tmp = -520664172.1831205, tmp))^(x/(1875488837))))<<(tmp = 402393637, tmp))&(tmp = 1576638746.3047547, tmp))));
- assertEquals(-2827557853031924000, x *= (tmp = 1322578326.6507945, tmp));
- assertEquals(6.424459501778244e+27, x *= (tmp = -2272087729.3065624, tmp));
- assertEquals(-1586887483, x |= (-1586887483));
- assertEquals(-567868980691736100, x *= (tmp = 357850816, tmp));
- assertEquals(1489101591, x ^= (x%(x|(421921075))));
- assertEquals(-801213804822328000, x *= (x|(-672326904.6888077)));
- assertEquals(612257233.6612054, x /= (((tmp = -350127617, tmp)>>>(-1140467595.9752212))<<((x^x)+(-3117914887))));
- assertEquals(19097.231243331422, x /= ((x^(tmp = -570012517, tmp))>>>x));
- assertEquals(0, x >>= ((x%(((-2347648358)%((x-(tmp = -456496327, tmp))|(x^(-1977407615.4582832))))<<(x/(tmp = -2021394626.214082, tmp))))%(tmp = -949323000.2442119, tmp)));
- assertEquals(0, x <<= x);
- assertEquals(NaN, x %= (x^(x>>(((tmp = 597147546.7701412, tmp)&(((((-972400689.6267757)|(tmp = -2390675341.6367044, tmp))|(tmp = 1890069123.9831812, tmp))<<(((1606974563)-(tmp = -2211617255.8450356, tmp))&((((x+((2433096953)&(-2527357746.681596)))*(tmp = -313956807.55609417, tmp))|((tmp = -2146031047.968496, tmp)/(tmp = 2851650714.68952, tmp)))>>(((tmp = 2630692376.6265225, tmp)-(tmp = -3162222598, tmp))>>((tmp = 1915552466, tmp)*(x>>>(-2413248225.7536864)))))))&(x%((((1218471556)|x)+(tmp = -849693122.6355379, tmp))+x))))>>>(x/((tmp = 689889363, tmp)/x))))));
- assertEquals(0, x >>>= (45649573.23297));
- assertEquals(0, x >>>= (tmp = 1084439432.771266, tmp));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x *= (tmp = 1642750077, tmp));
- assertEquals(0, x >>>= (tmp = -1944001182.0778434, tmp));
- assertEquals(1682573000, x |= (tmp = -2612394296.2858696, tmp));
- assertEquals(3041823595, x -= (((tmp = 720576773, tmp)|(x^(-1068335724.2253149)))>>(x*(-2501017061))));
- assertEquals(6083647190, x += x);
- assertEquals(-6536258988089986000, x *= ((tmp = 632312939.6147232, tmp)|((-1621821634)+(((tmp = -2281369913.562131, tmp)&((tmp = -381226774, tmp)|x))&(664399051)))));
- assertEquals(4.272268155938712e+37, x *= x);
- assertEquals(733271152, x %= (-1345127171));
- assertEquals(847089925, x ^= (tmp = 432620917.57699084, tmp));
- assertEquals(1337073824, x <<= x);
- assertEquals(-25810602, x ^= (tmp = 2982414838, tmp));
- assertEquals(-25282209, x |= ((tmp = -2927596922, tmp)>>>(-2404046645.01413)));
- assertEquals(639190091919681, x *= x);
- assertEquals(173568320, x &= ((((tmp = -718515534.4119437, tmp)&(tmp = 2989263401, tmp))<<x)|((tmp = 537073030.5331153, tmp)-(tmp = 883595389.314624, tmp))));
- assertEquals(0, x -= x);
- assertEquals(0, x >>>= (tmp = -1844717424.917882, tmp));
- assertEquals(0, x >>= (tmp = -462881544.2225325, tmp));
- assertEquals(0, x >>= x);
- assertEquals(-1868450038, x ^= (2426517258.6111603));
- assertEquals(1, x /= x);
- assertEquals(1175936039.4202638, x += (tmp = 1175936038.4202638, tmp));
- assertEquals(-127916015, x ^= ((x/(1841969600.3012052))-(tmp = 1099467723, tmp)));
- assertEquals(395713785658171900, x *= (-3093543726));
- assertEquals(395713787128560900, x += (((((-717204758)*(tmp = -588182129.6898501, tmp))-x)+(tmp = 20638023, tmp))^x));
- assertEquals(-962609355, x |= ((x^(-3118556619.912983))<<((tmp = 876126864, tmp)&x)));
- assertEquals(-962609355, x %= (tmp = -2079049990, tmp));
- assertEquals(-114583755, x -= (((-2806715240)&(((1961136061.0329285)>>>((2087162059)*x))+((tmp = -1890084022.7631018, tmp)%(tmp = 2137514142.358262, tmp))))+(x<<(tmp = 2991240918, tmp))));
- assertEquals(-425721856, x <<= x);
- assertEquals(3778560, x >>>= ((x|(3198503572))>>(1158434541.1099558)));
- assertEquals(3778560, x %= (tmp = -2592585378.9592104, tmp));
- assertEquals(624640, x &= (tmp = 2261638192.9864054, tmp));
- assertEquals(1249280, x += x);
- assertEquals(1048576, x &= ((tmp = -2144301819.9892588, tmp)^((x-x)<<x)));
- assertEquals(2097152, x <<= (x/x));
- assertEquals(5069061551149729, x *= (tmp = 2417116904.8069615, tmp));
- assertEquals(1.4836296666029616e+25, x += ((tmp = 2926833006.7121572, tmp)*x));
- assertEquals(-256, x >>= ((-469330345.3589895)%((x^(((2554170843.4978285)/(2495676674.815263))>>>x))*(-918892963))));
- assertEquals(-134217728, x <<= (x|(((((1687450853.1321645)+(tmp = 2369533014.5803776, tmp))+(tmp = -2613779445, tmp))+(tmp = -2488826226.3733397, tmp))>>(tmp = -220646936.41245174, tmp))));
- assertEquals(704164545131708400, x *= ((-2632786741)+(-2613647956)));
- assertEquals(9216, x >>>= (-1925405359.657349));
- assertEquals(4491403261551.008, x *= (tmp = 487348444.1787118, tmp));
- assertEquals(4490606381829.008, x -= (tmp = 796879722, tmp));
- assertEquals(-60294056, x >>= x);
- assertEquals(-3193966580.494005, x += (tmp = -3133672524.494005, tmp));
- assertEquals(550500358, x >>>= ((tmp = -2779637628.390116, tmp)-((tmp = 29230786.984039664, tmp)%(tmp = -310649504.7704866, tmp))));
- assertEquals(68812544, x >>= (-1347584797));
- assertEquals(1.2120221595741834e-11, x /= ((2791020260)*((((1964870148.6358237)^x)|(-3082869417))-((x^x)&((1234292117.8790703)<<(-1792461937.2469518))))));
- assertEquals(1.2120221595741834e-11, x %= (x-(2780439348)));
- assertEquals(-1421552183, x |= (tmp = -1421552183.5930738, tmp));
- assertEquals(-1420954119, x |= ((((-2547788562.5735893)<<x)%(435385623))>>(x|x)));
- assertEquals(1, x /= x);
- assertEquals(1, x >>= (x>>>(((2975715011.501709)-(tmp = -1473273552.981069, tmp))/(1654883913.042487))));
- assertEquals(-65382, x ^= ((x/((tmp = -2780026200, tmp)<<x))^(((-2683084424)<<x)>>(-1716245874))));
- assertEquals(1530921106, x &= (1530940914));
- assertEquals(1, x /= x);
- assertEquals(0, x >>= x);
- assertEquals(0, x /= (tmp = 773741434.1972584, tmp));
- assertEquals(0, x |= x);
- assertEquals(0, x <<= (-67977514.99888301));
- assertEquals(0, x %= (2496550482.524729));
- assertEquals(-0, x /= (tmp = -515040417, tmp));
- assertEquals(0, x <<= (-1673460935.2858837));
- assertEquals(-2638209488, x += (-2638209488));
- assertEquals(-2400951839498683400, x *= (910068685));
- assertEquals(1600582036, x ^= (((-1247602308.4812562)>>(((-2393714444.179732)>>>x)%(-778140635.7165127)))+(-1933914727.2268424)));
- assertEquals(0, x *= ((x-x)>>(-1270234575)));
- assertEquals(0, x >>>= (tmp = 3193676327.493656, tmp));
- assertEquals(0, x ^= (x>>>(1148676785.389884)));
- assertEquals(0, x >>= (tmp = -2269181763.8663893, tmp));
- assertEquals(0, x >>= (3149450221));
- assertEquals(0, x >>= (1069630750));
- assertEquals(-625009654, x ^= ((-2143499112)%(-759244728.6214335)));
- assertEquals(3583943, x >>>= (-2942645558.1204453));
- assertEquals(1791971, x >>= (x/x));
- assertEquals(223996, x >>= x);
- assertEquals(6999, x >>= (tmp = -1051883611.9443719, tmp));
- assertEquals(1459617792, x <<= (-1572314984));
- assertEquals(2622356453.269262, x -= (tmp = -1162738661.2692618, tmp));
- assertEquals(5103676461.269262, x += (2481320008));
- assertEquals(823989684.2692623, x %= (x^(((((1048362966)*((tmp = -2423040747.6233954, tmp)>>>x))*((tmp = 2330818588.4081, tmp)>>(tmp = 103312020.98346841, tmp)))+(tmp = 2264492857.144133, tmp))>>>((tmp = 2523442834, tmp)<<x))));
- assertEquals(0, x >>>= (tmp = -2018700898.531027, tmp));
- assertEquals(NaN, x /= x);
- assertEquals(0, x <<= (tmp = -2489442223, tmp));
- assertEquals(0, x >>= ((3045836220)>>>x));
- assertEquals(-1156905149, x ^= (3138062147));
- assertEquals(-0, x %= x);
- assertEquals(-3118433907.512866, x -= ((tmp = 1338611238, tmp)-(-1779822669.5128663)));
- assertEquals(100679693, x &= (1040565279));
- assertEquals(10136400582574248, x *= x);
- assertEquals(0, x %= x);
- assertEquals(2400318405, x += (2400318405));
- assertEquals(1.0036190808578471, x /= (((tmp = -2313492253.9889445, tmp)|(x-((tmp = -205459123, tmp)>>x)))+x));
- assertEquals(0, x >>>= (tmp = 882343227.1675215, tmp));
- assertEquals(0, x &= ((tmp = 2307828832.2706165, tmp)^((((((1404388047)<<((807879382)-(-2862921873)))-x)*(tmp = -1897734732, tmp))>>(tmp = 1981888881.2306776, tmp))%x)));
- assertEquals(0, x <<= x);
- assertEquals(0, x *= (((x*x)*((((2764801384.171454)%(x>>>x))&(384818815))+(x>>(tmp = -1481683516, tmp))))&x));
- assertEquals(0, x >>= (tmp = -2202536436, tmp));
- assertEquals(0, x ^= x);
- assertEquals(0, x &= (tmp = 15161124, tmp));
- assertEquals(-1586110900, x ^= (-1586110900));
- assertEquals(-1586127952, x -= ((tmp = 560737212, tmp)%((1349529668)>>>(tmp = -1956656528, tmp))));
- assertEquals(-1174945870, x -= ((1178456190)|x));
- assertEquals(1335167624.3422346, x -= (tmp = -2510113494.3422346, tmp));
- assertEquals(1329952126.3422346, x -= (x>>x));
- assertEquals(1, x >>= x);
- assertEquals(3, x |= (x<<x));
- assertEquals(3, x -= (x-x));
- assertEquals(-1938525669, x |= (tmp = 2356441625.5128202, tmp));
- assertEquals(-1938525669, x ^= ((tmp = -197149141.3622346, tmp)/(2833823156)));
- assertEquals(-2.6292393147661324, x /= (737295254.2254335));
- assertEquals(2925975987.370761, x -= (-2925975990));
- assertEquals(2925975987.370761, x %= (tmp = 3041184582.8197603, tmp));
- assertEquals(-1908068660, x ^= ((tmp = -1380575181, tmp)-(2375164084.8366547)));
- assertEquals(-477017165, x >>= (tmp = 2420877826.353099, tmp));
- assertEquals(-477017165, x %= ((tmp = -2919204062.3683634, tmp)-(tmp = -2263328990, tmp)));
- assertEquals(-2105539936, x &= ((tmp = -1630795440, tmp)-(x&((933423833)>>(-475069901)))));
- assertEquals(-4979480720, x -= (tmp = 2873940784, tmp));
- assertEquals(-4190953472, x -= (x&(tmp = -645918862.9001305, tmp)));
- assertEquals(17564091004468855000, x *= x);
- assertEquals(-857277134, x |= (tmp = 2363948338, tmp));
- assertEquals(1015632515, x -= (-1872909649));
- assertEquals(-1150380043, x ^= (tmp = -2014853770, tmp));
- assertEquals(1607729152, x <<= ((2194449589)+(x|(tmp = -1470075256.4605722, tmp))));
- assertEquals(1608356496, x |= ((((x|(670426524))<<((-2415862218)>>(tmp = 1572561529.9213061, tmp)))^((-1989566800.3681061)|x))&(2170270618.3401785)));
- assertEquals(-1836056576, x <<= (tmp = 2906301296.540217, tmp));
- assertEquals(-2952415961567723500, x *= (tmp = 1608020145, tmp));
- assertEquals(1435500544, x <<= x);
- assertEquals(700928, x >>>= (tmp = 2924829771.1804566, tmp));
- assertEquals(0, x <<= ((x^(2410009094))|(((-164334714.18698573)%(x*x))|(tmp = 2182431441.2575436, tmp))));
- assertEquals(-143321285, x ^= (tmp = -143321285, tmp));
- assertEquals(-2, x >>= x);
- assertEquals(-1, x >>= (x&(1109737404)));
- assertEquals(1, x >>>= x);
- assertEquals(0, x ^= x);
- assertEquals(-2463707358.165766, x += (-2463707358.165766));
- assertEquals(1831259938, x >>= (((((x-(tmp = 1359448920.5452857, tmp))%(tmp = -104541523, tmp))/((3133289055.9780197)*x))>>x)%x));
- assertEquals(1858895646, x ^= ((tmp = 131424376, tmp)>>(tmp = -396761023, tmp)));
- assertEquals(1, x >>= x);
- assertEquals(-1888369021, x |= ((tmp = -2038869285.046599, tmp)^((tmp = -1318286592.4250565, tmp)-(tmp = 2825123496, tmp))));
- assertEquals(1036458508, x <<= ((tmp = 2722401450, tmp)/((tmp = 1090712291, tmp)>>((tmp = -2155694696.9755683, tmp)*(tmp = 1661107340, tmp)))));
- assertEquals(1, x /= (x%((tmp = -1716050484, tmp)+(tmp = -1683833551.797319, tmp))));
- assertEquals(0, x >>= (tmp = -2899315628, tmp));
- assertEquals(0, x |= x);
- assertEquals(0, x >>>= x);
- assertEquals(0, x <<= x);
- assertEquals(1546062911, x |= (1546062911));
- assertEquals(1546195271, x += ((tmp = -3210667091, tmp)>>(tmp = 1323121165, tmp)));
- assertEquals(3092390542, x += x);
- assertEquals(-1199626354, x |= (406783756));
- assertEquals(-3650317194584908300, x *= (tmp = 3042878461.625484, tmp));
- assertEquals(-7.650495675092354e+27, x *= (2095844078));
- assertEquals(0, x >>= (tmp = 342617880.3384919, tmp));
- assertEquals(22, x ^= (((tmp = 381409558.9104688, tmp)>>((2823172888.974557)>>x))>>x));
- assertEquals(736383550, x += (736383528));
- assertEquals(0, x %= x);
- assertEquals(0, x += x);
- assertEquals(-1553157831, x -= (1553157831));
- assertEquals(1838556960, x <<= (3158944357.262641));
- assertEquals(5503285699.188747, x *= ((tmp = 2437440276, tmp)/(814308583.8128904)));
- assertEquals(5824889900.188747, x -= (((tmp = 1171445694, tmp)-(tmp = -1584666956, tmp))^(tmp = 1217545373, tmp)));
- assertEquals(747032, x >>>= (-89332085));
- assertEquals(747032, x |= (x^(x^(x>>>x))));
- assertEquals(747032, x >>>= ((-1558482440)*((tmp = -2413907480, tmp)+(3003996862.384156))));
- assertEquals(7.747761349084291e+23, x += ((tmp = 518064022.64624584, tmp)*((tmp = 2001951702, tmp)*x)));
- assertEquals(0, x <<= (2769324707.5640426));
- assertEquals(NaN, x %= (((((((-2458056470.7717686)&x)>>(tmp = -361831232.42602444, tmp))*(2611108609.6727047))>>>x)/(-1713747021.8431413))*(-1143281532)));
- assertEquals(NaN, x %= ((x^((-613836813)*(tmp = -3180432597.0601435, tmp)))%x));
- assertEquals(NaN, x /= ((-1607092857)^x));
- assertEquals(0, x &= (-1190719534));
- assertEquals(0, x >>>= x);
- assertEquals(0, x += (x>>(642177579.1580218)));
- assertEquals(-3129552333, x += (-3129552333));
- assertEquals(1165414963, x &= x);
- assertEquals(2222, x >>= (((tmp = 2606317568, tmp)|x)+(tmp = 1844107136, tmp)));
- assertEquals(NaN, x %= ((x^x)<<(x/(((tmp = -1362148700, tmp)&((tmp = 76371048, tmp)<<x))>>>((x^(-2605741153))>>(((tmp = -2131608159.7634726, tmp)|(((2827792229.8004875)|(((-848439251)+(-2576768890.123433))|((tmp = -2617711776, tmp)-((-199980264)&((tmp = -46967951.76266599, tmp)/(-733253537))))))*(tmp = 1820087608, tmp)))>>>(tmp = -3118359396.4298744, tmp)))))));
- assertEquals(NaN, x /= ((2144871731)*x));
- assertEquals(NaN, x *= x);
- assertEquals(NaN, x %= (tmp = 234811462.08692443, tmp));
- assertEquals(0, x >>>= ((1121416685)|(x^(((tmp = -2905413334, tmp)<<(tmp = -3091554324.030834, tmp))<<x))));
- assertEquals(-55938048, x |= ((tmp = -55938048, tmp)+(x*(tmp = -1518809027.2695136, tmp))));
- assertEquals(-3.3234995678333864e-10, x /= (x*(tmp = -3008876576, tmp)));
- assertEquals(0, x <<= (x/((((((-2168824234.2418427)>>(((tmp = 1976810951, tmp)%x)<<(x*(x>>(x%(3146266192))))))%(tmp = 1756971968.122397, tmp))>>>(-2859440157.8352804))/(-1001406.1919288635))>>>(-1358031926))));
- assertEquals(-0, x *= (tmp = -1756000533, tmp));
- assertEquals(-0, x %= (2522761446.869926));
- assertEquals(0, x >>>= (((1087690535)>>>(2741387979))^x));
- assertEquals(0, x -= x);
- assertEquals(0, x >>= (-819422694.2188396));
- assertEquals(0, x ^= x);
- assertEquals(NaN, x /= x);
- assertEquals(0, x &= (tmp = 86627723, tmp));
- assertEquals(0, x += x);
- assertEquals(0, x %= (tmp = -2317915475, tmp));
- assertEquals(Infinity, x += (((-3072799584)^(-2487458319))/(((tmp = -3050692353, tmp)&x)>>(-777977292.8500206))));
- assertEquals(Infinity, x += x);
- assertEquals(Infinity, x -= (tmp = 484428269, tmp));
- assertEquals(Infinity, x *= x);
- assertEquals(Infinity, x /= (2059586218.2278104));
- assertEquals(Infinity, x *= (tmp = 415918523.8350445, tmp));
- assertEquals(-1800869091, x |= (((-1800869091)>>>(x>>>(tmp = -2832575051, tmp)))>>>x));
- assertEquals(6196126991451132000, x *= ((-1467292383.8458765)+(-1973339154.7911158)));
- assertEquals(6196126992684649000, x += (1233517421));
- assertEquals(1, x /= x);
- assertEquals(-7153809722216516000, x -= (((-2984550787.146106)<<(tmp = 743743974, tmp))*((3155151275)/((-1771412568.8965073)%x))));
- assertEquals(-7153809721471491000, x -= (-745024056));
- assertEquals(5.117699353102001e+37, x *= x);
- assertEquals(0, x >>= x);
- assertEquals(-0, x *= ((-2651785447.666973)<<(-1124902998)));
- assertEquals(-0, x /= (2119202944));
- assertEquals(1042673805.5205957, x -= ((x<<x)-(tmp = 1042673805.5205957, tmp)));
- assertEquals(62, x >>>= (tmp = 2769597912.977452, tmp));
- assertEquals(34, x &= ((tmp = -61541150, tmp)%(x^(-943160469))));
- assertEquals(34, x ^= ((-2625482224.4605474)<<(-2277806338.3461556)));
- assertEquals(536870912, x <<= ((-2373927426.4757633)^x));
- assertEquals(536870912, x &= x);
- assertEquals(512, x >>>= ((-1626769708.310139)<<((tmp = 641796314, tmp)/(721629637.3215691))));
- assertEquals(0, x <<= (-113973033));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x += (-1602711788.2390788));
- assertEquals(NaN, x *= (x%x));
- assertEquals(0, x &= (x<<(x|(x>>((x>>>(x%((1182960050)^(((-220896609)-((((tmp = 1518275435.360103, tmp)/(tmp = -88234820, tmp))^x)/x))>>(3169930777.548236)))))-(tmp = -2912668817.662395, tmp))))));
- assertEquals(0, x *= ((2323969408.7524366)/(((tmp = -3089229853, tmp)>>>((((tmp = -1012580544.5631487, tmp)>>(1138049418.9023373))>>x)&x))*(tmp = 626912001, tmp))));
- assertEquals(0, x >>>= x);
- assertEquals(NaN, x /= (x%(-868024322)));
- assertEquals(NaN, x /= (tmp = -1749532322, tmp));
- assertEquals(1861918711, x |= (-2433048585.853014));
- assertEquals(1861918711, x >>= (((102451747)>>>((((241651917.47259736)/((((((((1759022236)^(tmp = -2592022722, tmp))+((-1748044969)>>>(704597925)))/(-1639604842))%((1349846853.7345295)<<(-729695861)))/(x>>((tmp = -2654474404.7365866, tmp)>>x)))>>>(((-480356478)|(x%((tmp = -1668269244.6979945, tmp)+(tmp = -2441424458.565183, tmp))))^((1634981212.7598324)>>>(tmp = 122455570.22000062, tmp))))<<x))*((tmp = -1058636137.5037816, tmp)+((2794083757.138838)&((x/(50081370))&x))))/x))/((tmp = -243106636, tmp)<<((x*((tmp = -648475219.5971704, tmp)>>((tmp = -1568913034, tmp)-((tmp = 911458615, tmp)|x))))>>>(tmp = 2714767933.920696, tmp)))));
- assertEquals(0, x ^= x);
- assertEquals(-2080484602, x |= (((1544771831.4758213)|x)^(-538113039)));
- assertEquals(696451072, x <<= (tmp = -1587032689, tmp));
- assertEquals(-162595645, x += (tmp = -859046717, tmp));
- assertEquals(516546456, x >>>= x);
- assertEquals(623083588, x += ((-1371850352)^(tmp = -1469933252, tmp)));
- assertEquals(92342412, x %= (tmp = -132685294, tmp));
- assertEquals(500272110, x |= ((tmp = 1616032506, tmp)%((tmp = 1589569590.4269853, tmp)|(-972791738.1829333))));
- assertEquals(3247086, x %= (((tmp = 1372216208, tmp)|(-638950076.3387425))&((-2619249161.849716)&(73957896))));
- assertEquals(0, x >>>= (tmp = -1482343462.6911879, tmp));
- assertEquals(1265125662, x ^= (tmp = -3029841634, tmp));
- assertEquals(4941897, x >>>= (-2039728632));
- assertEquals(206857, x &= (tmp = 226962365.45571184, tmp));
- assertEquals(1.0925018562586405e+24, x += ((tmp = 2687424146, tmp)*(((-1998020319)%x)*(-2080331363))));
- assertEquals(-1.755270751212437e+32, x *= (-160665242));
- assertEquals(0, x <<= (3152796521.6427975));
- assertEquals(0, x ^= ((((((tmp = -855001595, tmp)<<(2007525777))-(x-(x-x)))/(3036585090.9701214))&(1827983388))*((tmp = -915604789.0515733, tmp)&(((((tmp = -806628722.7820358, tmp)%x)/(tmp = -2773117447, tmp))|x)<<(((tmp = -2902300974.7300634, tmp)|x)/(-1608133440))))));
- assertEquals(0, x |= ((((((119024954)*(((x^(tmp = 2939514414, tmp))|x)^(x-(tmp = -1597415597.6795669, tmp))))+(((tmp = -182277816.14547157, tmp)<<(((-2983451324.3908825)^(tmp = 1572568307, tmp))+(-1165604960.8619013)))/(x>>((tmp = -2127699399, tmp)>>((x^(((((tmp = -1968667383, tmp)^(tmp = 3120052415.9964113, tmp))|(((x|(((x^((tmp = 2831505153, tmp)<<((-3150506831.547093)+((x%(tmp = 383761651, tmp))%(2856803457)))))+(((tmp = -2426953997, tmp)^(tmp = -2667954801.1010714, tmp))*(tmp = -2707801631, tmp)))&(tmp = 2082935238.794707, tmp)))^((tmp = 697573323.5349133, tmp)-x))%(tmp = 661936357, tmp)))/(-1717944600.261446))>>>((2423776015.0968056)^((-1410322010)|((x<<(tmp = 2935993226, tmp))/(tmp = -1533896392, tmp))))))*(tmp = -596675330, tmp))))))>>>(((2944268153)^(x&(144579050.93126357)))/(-2123810677.2619643)))>>>(1473040195.9009588))*x));
- assertEquals(0, x /= (2877666495));
- assertEquals(2174852514, x -= (tmp = -2174852514, tmp));
- assertEquals(543713128, x >>>= x);
- assertEquals(2978128878.939105, x += (tmp = 2434415750.939105, tmp));
- assertEquals(3529591145844655600, x *= (tmp = 1185170719.3753138, tmp));
- assertEquals(659, x >>>= ((((((x<<(((((-425423078)/(((tmp = 160617689.20550323, tmp)&(-1524740325.5003028))%(tmp = -1869426475, tmp)))<<(((x^(-487449247))>>>(tmp = -1962893666.7754712, tmp))%x))*x)>>((tmp = 623413085, tmp)&(x+(((((-2200726309.083274)-(x-x))+x)&(-1304849509))|((((tmp = -431896184, tmp)>>>(x>>(-1932126133)))<<((1078543321.2196498)*(-10761352)))>>(tmp = -2681391737.5003796, tmp)))))))/x)-(tmp = -1768629117, tmp))/(((((tmp = -2320718566.0664535, tmp)%x)+(-2831503351.995921))>>>(-2695416841.3578796))*(943979723)))<<x)|((652520546.7651662)>>(1045534827.6806792))));
- assertEquals(531, x &= (tmp = -293707149, tmp));
- assertEquals(0, x >>= (tmp = -678056747.5701449, tmp));
- assertEquals(1184651529.8021393, x += (tmp = 1184651529.8021393, tmp));
- assertEquals(1721719611, x |= (tmp = 1645413178, tmp));
- assertEquals(-406880257, x |= (tmp = 2268544460, tmp));
- assertEquals(-4194304, x <<= (tmp = -109701322.43455839, tmp));
- assertEquals(17592186044416, x *= x);
- assertEquals(0, x ^= (x&x));
- assertEquals(0, x <<= (tmp = 1715401127, tmp));
- assertEquals(-1793087394, x |= (tmp = -1793087394.730585, tmp));
- assertEquals(-2, x >>= x);
- assertEquals(263607360.10747814, x += (tmp = 263607362.10747814, tmp));
- assertEquals(1073214955, x |= (893759979.3631718));
- assertEquals(703953930, x -= ((2738450011)%(x^(tmp = 679402836, tmp))));
- assertEquals(1, x >>= (tmp = 2262515165.6670284, tmp));
- assertEquals(0, x >>= (((tmp = 747896494, tmp)^((tmp = -1005070319, tmp)+x))|x));
- assertEquals(0, x >>= ((953612771)>>>(tmp = 3066170923.3875694, tmp)));
- assertEquals(-314941454, x -= (x+(((314941454)%(((tmp = 2200222912.9440064, tmp)>>>(2534128736.805429))>>>(x|((747716234)%(((tmp = -252254528, tmp)%(-1553513480.1875453))&x)))))<<x)));
- assertEquals(-535686958, x &= (-522809126));
- assertEquals(0.5480312086215239, x /= (tmp = -977475278, tmp));
- assertEquals(-1199953459.6090598, x *= ((-2189571393)+((3186862741.37774)>>(tmp = -2193090564.5026345, tmp))));
- assertEquals(-1199953459.6090598, x %= ((tmp = 2986532440, tmp)*(2685122845)));
- assertEquals(-1199953459.6090598, x %= (1951182743.7399902));
- assertEquals(51262285383887820, x *= (-42720228));
- assertEquals(-424776752, x |= x);
- assertEquals(166221344210236600, x *= (tmp = -391314598.6158786, tmp));
- assertEquals(-1883425600, x >>= (((tmp = -1020679296, tmp)^((-1416867718)+(-1412351617)))<<(-2743753169)));
- assertEquals(0, x &= (x/(-2250026610)));
- assertEquals(-1111956501, x ^= (tmp = 3183010795, tmp));
- assertEquals(2012059503, x ^= (tmp = -900369276, tmp));
- assertEquals(15719214, x >>>= (tmp = -3196277049, tmp));
- assertEquals(15719214, x |= x);
- assertEquals(100779035, x -= ((-1245802025)^(-2964289852)));
- assertEquals(0, x >>= x);
- assertEquals(0, x &= (((x<<((2361941389.708063)%x))>>((328256762.09842086)>>>((((tmp = 3094192285, tmp)-(((x>>(tmp = -2920437464, tmp))<<(tmp = -2693021467, tmp))-(x>>>((2410065554)%(x%(tmp = 2487056196.689908, tmp))))))-(tmp = -866314146, tmp))^((1754098471)-((((((-2450740191)-(tmp = 1977885539.6785035, tmp))*((tmp = -1205431332, tmp)>>>x))>>(-870601854))>>(tmp = -301859264, tmp))|((tmp = -2308971516.8301244, tmp)/x))))))&((2307007357)-((tmp = -1518812934, tmp)+(2562270162)))));
- assertEquals(0, x <<= x);
- assertEquals(-1802124619, x |= (-1802124619));
- assertEquals(-1802124619, x %= ((1617132364.306333)+((1678465962.079633)|((516698570)%(((569813606)*(-1800804098.6270027))%((tmp = 1976706935, tmp)-((tmp = -1830228989.5488424, tmp)>>(((x^((tmp = 1015246068.3791624, tmp)>>x))^((-2171682812.246772)-(tmp = -398330350, tmp)))&x))))))));
- assertEquals(904564673.6237984, x -= (tmp = -2706689292.6237984, tmp));
- assertEquals(818237248768128900, x *= x);
- assertEquals(254842325.2585001, x %= (1550087667.9657679));
- assertEquals(-1163919360, x <<= x);
- assertEquals(-3.4644526843674166, x /= ((-446801454)+(x>>>(tmp = -2025151870, tmp))));
- assertEquals(0, x &= ((((((((-1739617728)&(x&(((tmp = -2946470036.552597, tmp)/x)*x)))^(-1130501404))>>>x)/((1870230831)>>>(840301398)))%x)/x)/(-2927537567)));
- assertEquals(0, x >>= x);
- assertEquals(0, x >>>= (x&(x&x)));
- assertEquals(0, x &= ((-579614044)-(-756012505.4048488)));
- assertEquals(-2970367642, x -= (tmp = 2970367642, tmp));
- assertEquals(-415129376, x ^= (tmp = 2847041926.060355, tmp));
- assertEquals(-1505681312, x &= (tmp = -1225184902.9215767, tmp));
- assertEquals(-3174471329.5807734, x += (-1668790017.5807734));
- assertEquals(-Infinity, x /= (x>>x));
- assertEquals(NaN, x -= x);
- assertEquals(0, x ^= (x^(((-1407936301.5682082)<<((x^(((tmp = 3213446217.307076, tmp)|x)|((tmp = 3219810777.3171635, tmp)/(tmp = 1561807400, tmp))))>>>((tmp = 2449910203.0949173, tmp)|((((1954662538.7453175)>>(tmp = -1711636239.9916713, tmp))>>>(tmp = 406219731.214718, tmp))<<(((-907908634.4609842)^((((((tmp = 2408712345, tmp)*(tmp = 1740346634.5154347, tmp))>>(tmp = 715783991, tmp))^(tmp = -655628853.2821262, tmp))%(tmp = 2819143280.434571, tmp))/(-1240412852)))*x)))))/x)));
- assertEquals(0, x >>>= x);
- assertEquals(0, x <<= x);
- assertEquals(0, x >>>= (((-3198075268.8543105)>>(((((x+((tmp = -133461401.50823164, tmp)-((x&(((((tmp = 2617977319, tmp)>>((tmp = -2704719576.8734636, tmp)|((tmp = -977362542.2423751, tmp)<<(x<<(tmp = 3054487697.1441813, tmp)))))>>>((-1635655471)%x))/(-2079513672))%(tmp = 1993563806, tmp)))<<(tmp = -1310524200.6106496, tmp))))%((((-2558804500.7722936)+(tmp = -1641265491, tmp))<<((tmp = -1309608349, tmp)>>>x))/((tmp = -2306644272, tmp)<<x)))*(-2009396162.3063657))+(267343314.3720045))-(-2212612983.661479)))|x));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x *= x);
- assertEquals(-824822309, x |= (-824822309));
- assertEquals(-807944741, x |= (((-598067403)*((x&(tmp = 2897778389, tmp))>>>(-1322468310.3699632)))|x));
- assertEquals(90004223.44097246, x /= (((tmp = -481122620, tmp)&x)%((tmp = 1109368524, tmp)/(((-3150568522.633032)<<(tmp = 2923396776, tmp))^(x-((x/x)&(x/(-287976185.1049104))))))));
- assertEquals(0.4521931751193329, x /= (tmp = 199039323, tmp));
- assertEquals(1.8110466604491368e-10, x /= (2496860986.492693));
- assertEquals(0, x |= x);
- assertEquals(-1225944576, x += ((tmp = -807700791.631221, tmp)<<((-700782615.4781106)-((((-2954619897)>>>x)<<((tmp = 997657844, tmp)>>>(1227994596)))/((-1234591654.8495834)*((tmp = -191189053.70693636, tmp)+(tmp = -3027659304, tmp)))))));
- assertEquals(-1225811383, x |= (-1866233271));
- assertEquals(3069155913, x >>>= (((x/(-99524153.40911508))%(x>>>((((tmp = 2985975640, tmp)/(tmp = 2781516546.2494454, tmp))&(((2234114508)|(((x/(tmp = -1224195047, tmp))<<x)^(x>>>((537884375.5698513)+x))))^((tmp = -2144817497.5089426, tmp)|(-498079183.8178189))))>>>((x+x)&(-3086080103.6460695)))))<<(((tmp = 2151157136, tmp)*x)/(((x/x)>>>(-1149734628.4364533))-((3025445835.654089)+(tmp = 530902725.91127443, tmp))))));
- assertEquals(-1733702568, x ^= (tmp = 776361489.423534, tmp));
- assertEquals(8981504, x &= ((tmp = 2902581847, tmp)*(x-(-2697760560))));
- assertEquals(1153166.8526612986, x -= ((x/(tmp = -1375025594.5027463, tmp))+((3043576689.1538706)%(x+x))));
- assertEquals(3389855, x |= (x+x));
- assertEquals(-488458393.17759943, x += (-491848248.17759943));
- assertEquals(40982867145206920, x *= ((3132857155)|(tmp = -218356553, tmp)));
- assertEquals(688, x >>= (((((tmp = 403321821, tmp)+((tmp = 2536984658, tmp)%((tmp = 2759309029.8753624, tmp)|(((tmp = 1994203554.7417293, tmp)^((704660500.434877)*(tmp = 1536292958.2691746, tmp)))+(-164139788)))))/((1205950994.1255205)+x))^((((tmp = 975272146.0133443, tmp)-(150107797))/(-1764309514))^((x>>>(x^(x^x)))+(203250124))))>>>(tmp = 1864959239.512323, tmp)));
- assertEquals(10, x >>= ((tmp = 1631996431.9620514, tmp)>>x));
- assertEquals(10, x %= (tmp = 2678904916, tmp));
- assertEquals(335544320, x <<= (tmp = -2759037415.6811256, tmp));
- assertEquals(-153389967, x |= ((tmp = -2411636565, tmp)+(tmp = -2305156154, tmp)));
- assertEquals(-1171, x >>= x);
- assertEquals(813080576, x &= (((tmp = -65428547, tmp)&(tmp = 3163266999, tmp))<<x));
- assertEquals(4346532303, x += ((tmp = -761515569.0707853, tmp)>>>(((tmp = 143240971.0661509, tmp)<<x)*(x^((tmp = -271697192.8471005, tmp)&x)))));
- assertEquals(-863299035, x ^= ((((2663001827.1492147)>>>((x/(((tmp = 482665912, tmp)-(x>>(tmp = 354425840.784659, tmp)))>>((-2012932893)>>>x)))/((tmp = -1354385830.6042836, tmp)>>>(-2149023857))))^((tmp = 585746520, tmp)+(tmp = 756104608, tmp)))^(517529841.184085)));
- assertEquals(-997654012, x &= (((tmp = -404836025.15326166, tmp)+((tmp = 3035650114.0402126, tmp)<<((-1308209196)>>(tmp = 693748480, tmp))))<<(((465774671.4458921)<<x)/(1971108057))));
- assertEquals(-320581507110848260, x *= ((x-(tmp = -2266777911.7123194, tmp))^(tmp = -2810021113.304348, tmp)));
- assertEquals(-320581508271196300, x += ((-1195215841.5355926)|(x-((2715907107.4276557)+(((-843426980)>>(x&(x%(tmp = -1139279208.34768, tmp))))^x)))));
- assertEquals(368031616, x &= x);
- assertEquals(368031616, x %= (tmp = 1211767328, tmp));
- assertEquals(-67505614939510744, x *= (tmp = -183423412.56766033, tmp));
- assertEquals(959424552, x >>= ((tmp = -171120122.5083747, tmp)/x));
- assertEquals(30949179.096774194, x /= (((x-((((x&(tmp = -180770090, tmp))<<(((tmp = -2061363045.419958, tmp)*((655711531)^((1205768703)-(tmp = 2468523718.8679857, tmp))))+(-2746704581)))+((-853685888)*(tmp = -2299124234, tmp)))|(tmp = 2429502966, tmp)))|(((-985794986.0232368)>>>(2890862426))%x))>>(tmp = 1005542138.8415397, tmp)));
- assertEquals(30949179, x |= x);
- assertEquals(30949179, x %= (810126097.6814196));
- assertEquals(120895, x >>= (tmp = 3065886056.1873975, tmp));
- assertEquals(1934320, x <<= (1478650660.7445493));
- assertEquals(0, x >>= (1069658046.2191329));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x %= (x*x));
- assertEquals(NaN, x *= ((((2148513916)+(tmp = -210070225.85489202, tmp))>>(975470028))+((-3060642402)>>x)));
- assertEquals(NaN, x *= (2888778384));
- assertEquals(NaN, x -= (294531300.16350067));
- assertEquals(-465620423, x ^= (tmp = -465620423.5891335, tmp));
- assertEquals(1613303808, x &= (-2530649850.1952305));
- assertEquals(2045458658, x |= (tmp = 432158946.5708574, tmp));
- assertEquals(0, x >>>= (2277328255.770018));
- assertEquals(0, x &= (-64904722.41319156));
- assertEquals(0, x >>= x);
- assertEquals(3109394857.361766, x += (3109394857.361766));
- assertEquals(1519021650, x ^= ((tmp = -2632472653, tmp)|(tmp = 2161964921.8225584, tmp)));
- assertEquals(370854, x >>>= ((1486892931.4564312)-((tmp = 3017755741.9547133, tmp)>>>x)));
- assertEquals(1333145110.39802, x -= ((-1051580495.39802)-(tmp = 281193761, tmp)));
- assertEquals(0, x ^= x);
- assertEquals(0, x |= x);
- assertEquals(0, x <<= x);
- assertEquals(0, x >>>= x);
- assertEquals(799202788.1455135, x -= (tmp = -799202788.1455135, tmp));
- assertEquals(1539080192, x <<= (x%(((((x-x)|(((((x%(959993901))+(tmp = -2647575570.092733, tmp))/(tmp = -2040600976.5104427, tmp))*(x*(tmp = 2785252760, tmp)))>>(-377867259)))/((x&(1549738240.013423))>>>(tmp = -1502185618, tmp)))*x)%(1159283801.0002391))));
- assertEquals(0, x >>= (-268660225));
- assertEquals(-0, x /= (-2795206270.635887));
- assertEquals(0, x >>>= (1869556260.2489955));
- assertEquals(64202212, x ^= ((((tmp = -942983515.5386059, tmp)*(((1057759788)-x)*(tmp = 2038041858, tmp)))>>x)+(tmp = 64202212, tmp)));
- assertEquals(2021126977, x -= ((tmp = -2009912898, tmp)^((2240062309)%x)));
- assertEquals(4332348265459724000, x *= (tmp = 2143530968, tmp));
- assertEquals(1472, x >>>= ((283380755)<<x));
- assertEquals(-1672370407872, x *= (tmp = -1136121201, tmp));
- assertEquals(338573318, x ^= (tmp = 2329579078.4832354, tmp));
- assertEquals(2377388772.1662374, x -= (tmp = -2038815454.1662374, tmp));
- assertEquals(-1.264761712403516, x /= ((((tmp = -2106209534, tmp)>>((((((tmp = 626190172, tmp)/x)>>>(-824270996.8545206))/((1258369810.9498723)-(tmp = -2947556209, tmp)))^((((366784589.24711144)|(1462064104.828938))-(1571045395.777879))<<(444685689.60103726)))>>(tmp = -2757110357.410516, tmp)))/(x>>>((tmp = 829226010, tmp)>>>(629512715))))|x));
- assertEquals(-2905481691.264762, x -= (2905481690));
- assertEquals(-1710543566.1481905, x -= (-1194938125.1165714));
- assertEquals(-3421087132.296381, x += x);
- assertEquals(-884178944, x <<= ((-1820881235)|x));
- assertEquals(-884178944, x &= (x%(tmp = -2298828530, tmp)));
- assertEquals(1516503040, x <<= ((tmp = -3039882653, tmp)+((tmp = 1956034508, tmp)<<(x>>(tmp = 280388051, tmp)))));
- assertEquals(3033006080, x += x);
- assertEquals(846431222.321887, x %= (x+(-1939718651.1609435)));
- assertEquals(-846431224, x ^= ((-1742116766.54132)/x));
- assertEquals(1157918728, x &= (tmp = 1966568030, tmp));
- assertEquals(1157918728, x >>>= ((((((tmp = -2392096728.184257, tmp)*(x&(-3051259597.301086)))>>>(((tmp = 1712991918.071982, tmp)*(tmp = -714525951, tmp))-((-1784801647)>>((-1270567991)%(((214272558)/(((-3110194570)|(tmp = 2558910020, tmp))&(-1266294955.717899)))*((2654922400.609189)>>>(tmp = 370485018, tmp)))))))*(((tmp = -2621203138.1838865, tmp)%(858913517))*((tmp = -1564229442.2596471, tmp)>>((tmp = 1898557618, tmp)|(-1282356275)))))*(tmp = -1253508468, tmp))+((-361964404.75944185)|x)));
- assertEquals(961668975, x += (-196249753));
- assertEquals(1, x >>= (tmp = 890453053, tmp));
- assertEquals(1, x >>= (((((tmp = 871309275, tmp)/(x>>>((tmp = 2033022083, tmp)&(tmp = -1393761939, tmp))))%((437488665.104565)^(tmp = 2808776860.4572067, tmp)))-((tmp = -359283111.49483967, tmp)<<((tmp = 2985855945, tmp)%(tmp = -596479825.9114966, tmp))))/(-1965528507)));
- assertEquals(0, x >>= ((tmp = -1753776989, tmp)%(tmp = 322622654, tmp)));
- assertEquals(84411424, x ^= (((x|(x|(tmp = -1617122265, tmp)))&(tmp = -313813263, tmp))&(1472888112.0258927)));
- assertEquals(67633184, x &= ((1556833131.0776267)<<(x<<(1501219716.5575724))));
- assertEquals(68002293, x |= (((tmp = 188984203.0350548, tmp)>>>(tmp = 1356052777, tmp))%(x*(tmp = -2944960865, tmp))));
- assertEquals(67108864, x &= (((1046644783.9042064)<<x)+((-2796345632)>>>(((-1913290350.3687286)<<(((((tmp = -2223692353, tmp)>>x)&(x<<(x>>((((tmp = -976850020, tmp)%(tmp = 1379692507, tmp))>>>(1120103052.2077985))>>(tmp = 5592070.612784743, tmp)))))<<(x+((tmp = -3154037212.9764376, tmp)%(((x-(-1961060483.6965141))+(((1920670676)-(2852444470.7530622))/(((1445954602)>>((1353665887)>>(tmp = 111411560.64111042, tmp)))<<x)))+x))))<<((-1773130852.6651905)^((1216129132)>>(1511187313.2680469)))))|((tmp = -1107142147, tmp)|(tmp = -768165441.4956136, tmp))))));
- assertEquals(0, x -= x);
- assertEquals(0, x %= (tmp = -1655707538.0778136, tmp));
- assertEquals(-184120712930843900, x += (x+((tmp = -3174410166, tmp)+((tmp = -301807453, tmp)*(tmp = 610060182.1666535, tmp)))));
- assertEquals(-54598560, x >>= (-1365351357));
- assertEquals(-6763.94449950446, x /= (((-1953016847)<<((673287269.7002038)%(-558739761)))>>>(tmp = 1607754129, tmp)));
- assertEquals(-1, x >>= x);
- assertEquals(1, x >>>= x);
- assertEquals(0, x >>>= x);
- assertEquals(0, x >>= ((-384747983)+((((tmp = -949058352.381772, tmp)>>>(-1920744986))-(-882729639))^((x^((tmp = 2351364046, tmp)<<(((tmp = -3110165747, tmp)^(-1266489735))-((tmp = -371614326, tmp)>>((tmp = -2064968414, tmp)&(-2075036504.617934))))))&(((-2616501739)&(tmp = 2591437335.4029164, tmp))>>x)))));
- assertEquals(0, x >>>= ((tmp = 2946468282, tmp)&((-2741453019)>>x)));
- assertEquals(0, x -= ((x%(-134700915))&(-1955768279)));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x /= (x^(((((((tmp = 3185669685.772061, tmp)>>(tmp = -1973500738, tmp))-(tmp = -87401348.93002152, tmp))>>(tmp = -2813508730, tmp))&(tmp = -778957225, tmp))<<(x-(x&((-2821756608)+(((((tmp = 2475456548, tmp)/(tmp = 997998362, tmp))<<((tmp = -83043634, tmp)|x))%(636120329))%(tmp = -1910213427.7556462, tmp))))))%x)));
- assertEquals(0, x &= x);
- assertEquals(0, x <<= x);
- assertEquals(0, x >>>= (x%x));
- assertEquals(0, x %= (745221113));
- assertEquals(0, x >>>= ((1467615554.7672596)|x));
- assertEquals(0, x /= (tmp = 735317995, tmp));
- assertEquals(-1513001460, x |= (2781965836));
- assertEquals(-1513001460, x |= (x%(1970577124.3780568)));
- assertEquals(-0, x %= x);
- assertEquals(1864972269, x ^= (-2429995027.840316));
- assertEquals(1226843341, x &= (tmp = -639621923.5135081, tmp));
- assertEquals(1226843339.3171186, x += ((1297620268.272113)/(-771070549)));
- assertEquals(76677708, x >>>= (1009134980));
- assertEquals(0, x ^= x);
- assertEquals(0, x ^= x);
- assertEquals(NaN, x /= x);
- assertEquals(716040787, x |= ((1851586229)-(1135545441.3502865)));
- assertEquals(1385693184, x <<= x);
- assertEquals(1321, x >>= (x^((tmp = -1576632297.0860603, tmp)>>>(405218605))));
- assertEquals(-1319012931, x |= (-1319014243));
- assertEquals(-1319012931, x >>= ((((1689898279.3580785)<<((((x^(x>>>((((tmp = 2635260332, tmp)*(tmp = 2053357650, tmp))*x)*(2856480122.339903))))>>x)&(-2382703000.077593))%(1183918594)))*(tmp = -1670081449, tmp))<<x));
- assertEquals(-528327581.7646315, x %= (tmp = -790685349.2353685, tmp));
- assertEquals(2073431790, x ^= (tmp = 2601800333, tmp));
- assertEquals(-6514722684180, x -= (((tmp = 824141806.0668694, tmp)>>>(((-1865885282.8723454)&(x&(x|((900188006.3757659)>>>(x&x)))))+(2227126244.0526423)))*x));
- assertEquals(1450593, x >>>= ((2157053647)>>(x+(-2934071355.418474))));
- assertEquals(576782336, x <<= ((1054640368.827202)&((tmp = -3182236876.434615, tmp)>>(tmp = 2129856634.0328193, tmp))));
- assertEquals(2950754326, x -= (tmp = -2373971990, tmp));
- assertEquals(738197504, x <<= (1188157369.5988827));
- assertEquals(0, x <<= (x+((tmp = -839533141, tmp)&((((((tmp = -1148768474.7306862, tmp)|(172650299))+(tmp = -2739838654, tmp))/(3132557129))%x)>>>(tmp = -1229961746.2466633, tmp)))));
- assertEquals(0, x %= (tmp = -2974207636, tmp));
- assertEquals(0, x %= ((2323482163)>>>x));
- assertEquals(0, x &= (((x/(x+(x>>((tmp = 55935149, tmp)%x))))|((3109182235)>>>(tmp = 1217127738.8831062, tmp)))+((((tmp = -385114910, tmp)*((((((tmp = -2535158574.634239, tmp)&(x+x))<<(-2821692922.43476))&(-776804130.9457026))>>((-1374832535)^(tmp = 2175402162.701251, tmp)))%(-1646995095)))-(x*(tmp = -921556123, tmp)))^(79224621))));
- assertEquals(128935435, x |= ((tmp = 2279459038, tmp)%(tmp = -537630900.5271742, tmp)));
- assertEquals(128935435, x /= ((((((x<<(2750024311))-((-1332480769.4784315)&(1418160003)))&(1551783357))<<(((((-2870460218.55027)|((-1958752193.7746758)&(2551525625)))>>>((((tmp = -1698256471, tmp)^(((((((((tmp = -830799466, tmp)+x)-(-111590590))+(tmp = -1105568112.3921182, tmp))/((tmp = -3058577907, tmp)|(((-1944923240.2965696)%(-2884545285))<<(tmp = -1993196044.1645615, tmp))))^(x>>(tmp = -2961488181.3795304, tmp)))&x)*x)|(((tmp = 97259132.88922262, tmp)<<((1601451019.343733)&x))*(x|x))))+((((x>>x)<<x)+(-868409202.2512136))/(((tmp = -2893170791, tmp)-((x|(-853641616))%(((tmp = 549313922, tmp)&(-768036601.6759064))%(tmp = -543862220.9338839, tmp))))-((tmp = 1639851636, tmp)+((2164412959)/(-273028039.941242))))))>>>((((-2382311775.753495)^(-2062191030.2406163))>>>(tmp = -1054563031, tmp))/(-862111938.7009578))))%x)+(-3103170117.625942)))%((tmp = -1144062234, tmp)>>x))>>>(tmp = 1216332814.00042, tmp)));
- assertEquals(41.631074722901715, x /= (x&(-2542806180.962227)));
- assertEquals(41.631074722901715, x %= (-14003386.556780577));
- assertEquals(8, x &= (x&((-2231622948)%(tmp = 488279963.9445952, tmp))));
- assertEquals(9.002961614252625e-9, x /= ((53802728.56204891)<<(((867697152.3709695)-(538719895.5707034))&(-631307825.4491808))));
- assertEquals(0, x >>= x);
- assertEquals(-0, x *= (tmp = -785674989, tmp));
- assertEquals(-0, x += x);
- assertEquals(0, x /= (-250703244));
- assertEquals(0, x <<= ((tmp = -661062581.5511999, tmp)|x));
- assertEquals(0, x &= (-1299482308));
- assertEquals(0, x &= ((-399690060)>>>(2448074202.385213)));
- assertEquals(0, x &= (2574341201));
- assertEquals(0, x <<= ((x|(((tmp = 2458873162.645012, tmp)+(tmp = -1999705422.8188977, tmp))<<((x^(tmp = -392530472, tmp))>>>x)))&(((tmp = 2463000826.7781224, tmp)|(tmp = 3020656037, tmp))-x)));
- assertEquals(1397603760, x += ((tmp = -1359413071, tmp)-(tmp = -2757016831, tmp)));
- assertEquals(513823851, x -= (883779909));
- assertEquals(-1765712747, x ^= (2288060670.6797976));
- assertEquals(3117741504918286000, x *= x);
- assertEquals(3117741506284045300, x += (1365759456));
- assertEquals(6035555595.597267, x /= (tmp = 516562470, tmp));
- assertEquals(104203275, x &= (tmp = 376835755.32434213, tmp));
- assertEquals(10858322520725624, x *= x);
- assertEquals(59458951, x >>>= (153765028));
- assertEquals(49370856, x += ((tmp = -1291276092, tmp)>>x));
- assertEquals(0, x %= x);
- assertEquals(0, x += x);
- assertEquals(-1494589645, x -= (1494589645));
- assertEquals(-0, x %= x);
- assertEquals(0, x <<= (x&((2730708043.467806)<<x)));
- assertEquals(0, x /= ((tmp = -1483912394.153527, tmp)>>>((tmp = 1800568769, tmp)^((((((tmp = 1351568510, tmp)>>(tmp = -1337992543.2562337, tmp))>>>(tmp = 2602239360.40513, tmp))*x)%x)+(-2095840128.0700707)))));
- assertEquals(-0, x /= ((2363946613)^(tmp = -2227868069, tmp)));
- assertEquals(0, x &= ((((2634933507)<<(2798775374.140882))>>>x)>>>(((tmp = 1135200853.6396222, tmp)-(tmp = -1529829490.7007523, tmp))-(((((((((x^((x|(2135742668.591568))-(924230444.8390535)))%(tmp = -2459525610.51898, tmp))+(x&((tmp = 1177231743.809653, tmp)/(tmp = 1743270357.2735395, tmp))))|(((tmp = -1894305017, tmp)^((tmp = 1791704240, tmp)&x))%(-1569751461)))>>>(tmp = -2078321944, tmp))|x)*(((x*(tmp = -163239354, tmp))<<((tmp = 2859087562.694203, tmp)&(-657988325.9410558)))^(2508013840)))-((-243572350)+(x%((-1095206140)+((tmp = 3213566608.942816, tmp)*((2256442613)%((tmp = 1723751298, tmp)^(x-((-1145710681.2693722)|x)))))))))+(1556870627)))));
- assertEquals(130883024.97423434, x -= (-130883024.97423434));
- assertEquals(0.046720352789736276, x /= (tmp = 2801413456, tmp));
- assertEquals(1806558189, x |= (tmp = 1806558189.157823, tmp));
- assertEquals(72.40475060062144, x /= (x%((1932591076.531628)>>(1982030182))));
- assertEquals(-1077558321.5975945, x += (tmp = -1077558394.002345, tmp));
- assertEquals(98187, x >>>= x);
- assertEquals(97792, x &= (tmp = -1032487404, tmp));
- assertEquals(709197609, x |= (x^(709179177)));
- assertEquals(11081212, x >>>= (tmp = 1412940006.169063, tmp));
- assertEquals(11081212, x &= x);
- assertEquals(-1920311203, x -= ((tmp = 1931392415, tmp)<<((x%(tmp = -2873576383, tmp))%x)));
- assertEquals(-1920311203, x |= (x&(-993884718.2172024)));
- assertEquals(-4, x >>= (1409411613.0051966));
- assertEquals(-7947632484, x *= ((-2856731734)^((-1181032235.9132767)-((tmp = 780101930, tmp)+((tmp = -1732707132.6253016, tmp)^x)))));
- assertEquals(-2016362769, x ^= (tmp = 2711125619.2455907, tmp));
- assertEquals(-61535, x >>= x);
- assertEquals(-124771649, x ^= (tmp = 124726558, tmp));
- assertEquals(-1, x >>= x);
- assertEquals(-0, x %= (x*x));
- assertEquals(0, x <<= x);
- assertEquals(0, x /= (2444628112));
- assertEquals(0, x <<= ((-38968517.72504854)<<x));
- assertEquals(-1504619917, x |= (tmp = 2790347379, tmp));
- assertEquals(-1504619917, x &= x);
- assertEquals(2790347379, x >>>= ((1825218368)<<(-1843582593.2843356)));
- assertEquals(7786038495492170000, x *= x);
- assertEquals(-11011696, x |= (((tmp = 2931644407.4936504, tmp)-(3077095016.001658))%(tmp = -1731851949, tmp)));
- assertEquals(-107866, x %= ((-697845074.1661191)>>(772708134)));
- assertEquals(356779149, x ^= (-356884949.503757));
- assertEquals(0, x %= x);
- assertEquals(0, x *= ((tmp = 1542291783, tmp)^x));
- assertEquals(0, x += ((tmp = 1105314644.002441, tmp)&x));
- assertEquals(-1005882993, x ^= (-1005882993.0899806));
- assertEquals(-1301065066, x += (tmp = -295182073, tmp));
- assertEquals(-1454702592, x <<= ((-2440858737.390277)&(-1363565201.7888322)));
- assertEquals(-201539012492525570, x *= ((((tmp = -1416268089, tmp)|x)-(tmp = 1669129769, tmp))&(x<<((x/(-2614041678.7423654))%x))));
- assertEquals(-2.1995276811535986e+25, x *= (x/(-1846667987.154371)));
- assertEquals(0, x |= ((x*(((x>>>((tmp = 1044173034, tmp)>>>((x<<((tmp = -2906412863, tmp)%((tmp = -437401503, tmp)<<(((((x|(2167319070))<<((tmp = 2766179640.1840167, tmp)&(-2372076054)))*(tmp = -241617431.06416297, tmp))*((((((tmp = 2570465382.5574293, tmp)>>>(x/((-2851324509.354545)%x)))>>(((x+((tmp = -614687945, tmp)^x))^((((tmp = 1653437743, tmp)>>x)/(tmp = 3072995069, tmp))>>x))*(((((-290508242)>>((tmp = 2969511554, tmp)<<(tmp = 158176292.95642304, tmp)))<<(32376015))+(tmp = 2391895870.4562025, tmp))*x)))&((((x/(tmp = 365292078.53605413, tmp))>>x)/(1167322811.0008812))|(((tmp = 2487970377.365221, tmp)^x)<<((tmp = 2342607988.711308, tmp)/(((2276081555.340126)-(((tmp = -2571071930, tmp)>>(tmp = -248468735.76550984, tmp))>>>(tmp = -2862254985.608489, tmp)))^(-1312017395))))))<<x)&(2762717852.949236)))+((((-2492896493)&x)<<(-2756272781.4642315))/x)))))*(2405395452))))>>((-1433975206)/((tmp = -2064757738.6740267, tmp)<<((((tmp = -1563531255, tmp)-(-589277532.2110934))<<x)^(2249328237.0923448)))))-x))-(-225624231)));
- assertEquals(0, x *= (tmp = 1657982666.2188392, tmp));
- assertEquals(86443387, x |= (tmp = 86443387.25165462, tmp));
- assertEquals(86443387, x %= (-1341731981.702294));
- assertEquals(172886774, x <<= ((-1799840391)&(1011948481.310498)));
- assertEquals(-1115684864, x <<= x);
- assertEquals(-2098253702059525600, x *= (1880686715.1865616));
- assertEquals(-2098253700213206300, x -= (tmp = -1846319435.0583687, tmp));
- assertEquals(570692096, x &= (((tmp = -1572055366.64332, tmp)%(tmp = 1720120910, tmp))%((x-(912386952.5959761))*(tmp = -1146251719.4027123, tmp))));
- assertEquals(603979776, x <<= ((-329752233.8144052)&(tmp = -368636559, tmp)));
- assertEquals(603979776, x <<= x);
- assertEquals(364791569817010200, x *= x);
- assertEquals(0, x &= ((2074587775.983799)/(tmp = 438856632.76449287, tmp)));
- assertEquals(0, x &= (((1509671758)*(tmp = -935801537.7325008, tmp))>>>(((tmp = -1752877566, tmp)<<x)%(tmp = -517163766, tmp))));
- assertEquals(-2031730599, x ^= ((2264285273)&(tmp = -1762662949.014101, tmp)));
- assertEquals(-843578945, x %= (-1188151654));
- assertEquals(-2147483648, x <<= x);
- assertEquals(-2147483648, x >>= (tmp = -3165079200.229641, tmp));
- assertEquals(-44086313.1323726, x %= ((x%(-254466243.48728585))-((x>>(-457411829.1063688))-((-2606923436.9333453)/x))));
- assertEquals(-44086313, x |= x);
- assertEquals(1037812, x >>>= ((tmp = 342497258.9786743, tmp)+(1652928385.8150895)));
- assertEquals(-2371695599678100, x *= (tmp = -2285284425, tmp));
- assertEquals(-2371697387004653, x += (tmp = -1787326553.0542095, tmp));
- assertEquals(0, x ^= x);
- assertEquals(0, x >>= ((x^(tmp = 544039787, tmp))>>>x));
- assertEquals(0, x &= ((x%(((((((tmp = -424572417.1088555, tmp)|(-2381863189))/(tmp = -2007482475.1809125, tmp))&(((((tmp = 311016073, tmp)>>(tmp = -1548839845, tmp))+((-2557740399.7947464)<<(2399113209)))&x)>>>x))%(-297180308.7721617))-(tmp = 860906293, tmp))^x))%(-2740622304)));
- assertEquals(4971841192462909000, x += ((tmp = -2723203837.572612, tmp)+((((-2909100706)+(-951999374))|(-3116735764))*(3087123539.422669))));
- assertEquals(-460, x >>= (1081807537.557404));
- assertEquals(2354165127.3906384, x += (tmp = 2354165587.3906384, tmp));
- assertEquals(357.8680960002211, x /= ((((x<<(((x&x)+(1113841407))|((x/(tmp = 384533564, tmp))>>>(-605853882))))%x)&((tmp = 2050375842, tmp)>>>x))>>(((2745147573)^x)<<(x-(900043292)))));
- assertEquals(0, x *= (x>>>(-295974954.5058532)));
- assertEquals(0, x *= ((-2448592125.815531)*(tmp = -94957474.8986013, tmp)));
- assertEquals(0, x &= ((x>>x)^(tmp = -1335129180, tmp)));
- assertEquals(395092065, x |= ((3081659156)^(tmp = -1608334475, tmp)));
- assertEquals(395092065, x &= x);
- assertEquals(-413337639, x += (x^(tmp = -664996071.3641524, tmp)));
- assertEquals(-1604423637896759800, x *= (x>>>(tmp = 1242912352.955432, tmp)));
- assertEquals(0, x &= ((((((tmp = 651293313, tmp)|(((2541604468.635497)>>>(tmp = 758815817.7145422, tmp))>>>((-1948795647)/x)))&x)/((tmp = -3161497100, tmp)+(782910972.3648237)))>>>x)%(834206255.5560443)));
- assertEquals(0, x >>>= (tmp = 125945571, tmp));
- assertEquals(NaN, x -= (x%x));
- assertEquals(NaN, x %= (tmp = 282259853, tmp));
- assertEquals(NaN, x += (tmp = -2081332383, tmp));
- assertEquals(0, x >>>= (((x>>(-2298589097.7522116))|((((x>>>(x-(tmp = 755218194, tmp)))|x)%x)-(tmp = 2206031927, tmp)))>>>((((x&(x-x))^(tmp = 2836686653, tmp))*((x<<(tmp = -1624140906.4099245, tmp))>>>((2942895486)|((x>>>x)>>>(-1586571476)))))|((781668993)+(-1857786909)))));
- assertEquals(0, x &= (tmp = -708084218.9248881, tmp));
- assertEquals(0, x %= (1645913394.5625715));
- assertEquals(0, x <<= ((x^((tmp = 1185413900, tmp)*((-2441179733.997965)*(tmp = 2554099020.066989, tmp))))%((1704286567.29923)/x)));
- assertEquals(0, x += x);
- assertEquals(0, x *= x);
- assertEquals(0, x |= (x>>>(139138112.141927)));
- assertEquals(0, x >>>= (tmp = 2142326564, tmp));
- assertEquals(0, x |= x);
- assertEquals(-0, x /= ((((x+(2817799428))|x)%((1050079768)-(x>>>((1452893834.8981247)|((((tmp = -1737187310.889149, tmp)/(tmp = -362842139, tmp))%(1234225406))%(((x|x)*((-1055695643.739629)-((x-x)*(945954197.676585))))-(tmp = 786185315.346615, tmp)))))))<<(-173891691)));
- assertEquals(0, x &= (-2842855092.319309));
- assertEquals(0, x &= ((-3188403836.570895)/x));
- assertEquals(0, x *= (x+x));
- assertEquals(NaN, x /= (x>>>(((tmp = 391037497.68871593, tmp)/((192754032)*(1382659402.5745282)))/((((-2187364928)>>>x)>>(tmp = 2563448665.7594023, tmp))^(tmp = 1500866009.7632217, tmp)))));
- assertEquals(NaN, x /= ((tmp = -935036555.2500343, tmp)-(x/(((x&(x^(tmp = -3001352832.5034075, tmp)))^x)/((1122547613)>>x)))));
- assertEquals(0, x >>= (tmp = -2951766379.0809536, tmp));
- assertEquals(-632945188, x ^= (-632945188.7188203));
- assertEquals(-632945188, x %= ((((((tmp = -3181527314.82724, tmp)&(2280175415))>>(x^(x|x)))^(tmp = -524233678.52970886, tmp))*x)|((tmp = 1782882786, tmp)>>>(tmp = -592607219, tmp))));
- assertEquals(404189184, x <<= ((tmp = -2761472127, tmp)^(36616299.88780403)));
- assertEquals(872651572, x ^= (tmp = 739568436.6252247, tmp));
- assertEquals(13, x >>>= ((tmp = -1033843418.865577, tmp)%(x%(1247263629.0445533))));
- assertEquals(0, x >>>= x);
- assertEquals(0, x >>= (3189175317));
- assertEquals(0, x &= (((2391973519.6142406)^((-2950058736.191456)|(x*x)))>>(tmp = 343822384.294345, tmp)));
- assertEquals(0, x >>>= (tmp = -2306246544, tmp));
- assertEquals(-1572339598, x ^= ((tmp = 2991380083.337327, tmp)&(tmp = -1361507970, tmp)));
- assertEquals(649, x >>>= ((1961407923.4950056)>>(x-(-872821523.7513013))));
- assertEquals(649, x ^= (((x&(tmp = -702931788, tmp))^(((x>>x)|(((tmp = 2710759269, tmp)/(x>>(x*((((((tmp = -2428445134.9555864, tmp)+(-1859938743))%(x<<x))*((236868604)+((tmp = -3066688385, tmp)/(787503572.8839133))))/(tmp = 3215629315, tmp))>>(-1315823020)))))%(1461368627.1293125)))>>>(tmp = -2921804417.5735087, tmp)))/(x>>>(((tmp = 2175260691.824617, tmp)/((-582958935.7628009)-((((((x>>x)|(2590503723.4810824))^(tmp = -1994324549, tmp))-(-684683327))/(tmp = -3133419531, tmp))|(tmp = -328974092.05095506, tmp))))>>(-447624639.4518213)))));
- assertEquals(649, x %= ((((1854382717)|(((x+(tmp = 2568081234, tmp))-x)+((tmp = 1043086140, tmp)<<((tmp = 2979118595.0496006, tmp)+((x&(2669577199.852803))/(-2567808445.101112))))))<<((((tmp = -1471092047, tmp)&((-3099138855.21041)-((tmp = -798574377.526715, tmp)&((2255586141)<<(-1069867774)))))>>>(((x*(tmp = -2810255707.781517, tmp))/x)*(2706435744.054121)))^(394262253)))^((844325548.0612085)/(tmp = 1434691648, tmp))));
- assertEquals(823215943.1924392, x += (tmp = 823215294.1924392, tmp));
- assertEquals(536872706, x &= ((-334612686)%((1303605874)|x)));
- assertEquals(-30666374.413486242, x += ((tmp = -567539080.4134862, tmp)%(tmp = -1655555936.3195171, tmp)));
- assertEquals(-56438727096752984, x *= (tmp = 1840410814, tmp));
- assertEquals(-33200107.984488487, x %= (((tmp = 3007206509, tmp)-(3079337725.6659536))%(1819565202.5011497)));
- assertEquals(-1214493182, x ^= (-3060193769));
- assertEquals(-1214493179.1335113, x -= ((-3218099496.595745)/(1122662554)));
- assertEquals(-1214493179, x >>= ((-375364195)<<(((tmp = 619439637.8754326, tmp)>>(-1830023279.9486575))&(tmp = -1106180387.2448823, tmp))));
- assertEquals(-303623295, x >>= (-2109241374.3349872));
- assertEquals(-0, x %= x);
- assertEquals(0, x |= x);
- assertEquals(1917126206, x -= (-1917126206));
- assertEquals(2659779928, x -= (tmp = -742653722, tmp));
- assertEquals(-1635187368, x >>= ((tmp = -674385169, tmp)*((9848362.783326745)|(x*(55220544.00989556)))));
- assertEquals(-1981113695, x ^= ((tmp = 392404985, tmp)>>(((x<<((2006207061)<<(tmp = 2558988218, tmp)))*((((tmp = 1789304307.1153054, tmp)/(2538061546))<<(tmp = 556026116, tmp))&((tmp = 1076457999.6424632, tmp)*(tmp = -1822378633.2489474, tmp))))%(((((-1117046924)&((-69013651)%(x&(((-2320327696)/(x&x))-(tmp = 2458222544, tmp)))))>>((-3092360983.0037227)/(-3171415636)))*(((tmp = 2520431213, tmp)<<(1066492762.6149663))+((tmp = 1272200889, tmp)^((1687693123.2295754)+x))))-(-1096823395)))));
- assertEquals(-990556848, x >>= x);
- assertEquals(981202869119695100, x *= x);
- assertEquals(981202869119695100, x -= (x/x));
- assertEquals(0, x ^= (x>>x));
- assertEquals(NaN, x %= x);
- assertEquals(0, x ^= x);
- assertEquals(0, x *= ((((2980512718)>>>x)<<((x^(-1111233869))>>((2531466092.6036797)>>>(((tmp = -1791229364, tmp)*(-2210950307.206208))%((tmp = -806645443, tmp)<<((((((((tmp = 112334634.26187229, tmp)%(x|((((2154021796.1166573)+x)&((-1047293079.9686966)^(tmp = -1894127139, tmp)))+(tmp = 1910946653.2314827, tmp))))^(293142672.5016146))-x)<<(-1593533039.8718698))+x)>>(x<<(((46359706.50393462)&(tmp = 272146661, tmp))|(tmp = 2117690168, tmp))))%(tmp = -1784737092.4924843, tmp)))))))-(1465796246)));
- assertEquals(0, x &= x);
- assertEquals(NaN, x %= x);
- assertEquals(0, x &= (x+(-1612418456)));
- assertEquals(0, x &= ((tmp = -843964311, tmp)/x));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x *= x);
- assertEquals(NaN, x += (x>>>(54020240)));
- assertEquals(489206868, x |= (489206868));
- assertEquals(489206868, x &= x);
- assertEquals(489206848, x &= ((tmp = -1699133906.2361684, tmp)>>(tmp = 2658633814, tmp)));
- assertEquals(489206848, x |= x);
- assertEquals(1910559006, x -= (tmp = -1421352158, tmp));
- assertEquals(1, x >>= x);
- assertEquals(0, x -= x);
- assertEquals(0, x %= (x^(tmp = 2745376003.2927403, tmp)));
- assertEquals(0, x %= (((tmp = 3199743302.1063356, tmp)^((-1905944176)&(x>>>(187247029.5209098))))<<((x*((-1394648387)*(1252234289)))-(3140049815))));
- assertEquals(0, x <<= (-2567872355));
- assertEquals(0, x %= (tmp = 1057707555.8604916, tmp));
- assertEquals(0, x %= ((tmp = -1877857405.0228279, tmp)>>>(((tmp = 423831184, tmp)*((tmp = -2106757468.324615, tmp)%(tmp = -1197717524.6540637, tmp)))>>(tmp = -93746263.46774769, tmp))));
- assertEquals(0, x |= x);
- assertEquals(-0, x *= ((tmp = 1317609776.6323466, tmp)*(tmp = -26959885.89325118, tmp)));
- assertEquals(0, x >>= (-1288116122.0091262));
- assertEquals(0, x &= ((370818172.92511404)%((tmp = -528319853.54781747, tmp)*(x/((tmp = -2839758076, tmp)^(x+(((-1258213460.041857)<<(tmp = 302017800.72064054, tmp))|((((tmp = -624254210, tmp)^((-338165065.97507)|((623392964)-x)))>>>x)%(tmp = 2767629843.0643625, tmp)))))))));
- assertEquals(0, x >>>= x);
- assertEquals(0, x >>>= x);
- assertEquals(0, x |= ((-2001549164.1988192)*x));
- assertEquals(0, x -= x);
- assertEquals(0, x *= (((((165836842.14390492)*(tmp = -3220002961, tmp))|(-2840620221.747431))%((x/(tmp = 3153915610, tmp))>>>(tmp = 2018941558, tmp)))>>>x));
- assertEquals(-0, x *= (-231994402.93764925));
- assertEquals(0, x <<= x);
- assertEquals(0, x %= (tmp = 2702385056.1149964, tmp));
- assertEquals(0, x <<= (tmp = 378459323, tmp));
- assertEquals(0, x >>>= ((x&(x&(((-1014963013)<<(x&((tmp = -3110294840, tmp)|(x+(x<<(1129643420))))))+(1093795819.1853619))))+((((tmp = -2295103369.697398, tmp)&(((370501313.43019223)>>>(2465439579))/x))-x)>>x)));
- assertEquals(0, x /= ((tmp = 1779625847, tmp)+(tmp = -662459654.6908865, tmp)));
- assertEquals(0, x -= x);
- assertEquals(0, x %= ((tmp = 2723291421, tmp)|(277246502.4027958)));
- assertEquals(0, x ^= (((-2936270162)>>>((((tmp = -2019015609.1648235, tmp)|(47218153))*(-823685284))+x))&(x<<(x*(x|(((tmp = -941955398, tmp)^(tmp = -2365238993.5300865, tmp))-(778674685)))))));
- assertEquals(0, x >>>= x);
- assertEquals(NaN, x %= x);
- assertEquals(0, x &= (-175235975.8858137));
- assertEquals(-2684493800.1062117, x += (tmp = -2684493800.1062117, tmp));
- assertEquals(-1290806265.6063132, x -= (-1393687534.4998984));
- assertEquals(-1290806265, x >>= (((x>>(tmp = -1710112056.4935386, tmp))*(586227650.2860553))<<(tmp = -2918251533.6052856, tmp)));
- assertEquals(23470008, x >>>= x);
- assertEquals(1668734969, x |= ((-295560682.9663689)^(x|((((tmp = -1183847364, tmp)&(3135327694))+(1679127747.1406744))-((-1895825528)%((tmp = -3180115006, tmp)+((tmp = 2373812187, tmp)|x)))))));
- assertEquals(1744306169, x |= (1188503928.5009093));
- assertEquals(1744306169, x %= (tmp = -2723982401.4997177, tmp));
- assertEquals(3488612338, x += x);
- assertEquals(3488612337, x += (((x/(-325849204))>>x)|(-1820624550.9149108)));
- assertEquals(-1511119305, x ^= (tmp = 1778506182.2952862, tmp));
- assertEquals(-12211415, x %= (x^(tmp = -54943035, tmp)));
- assertEquals(-12211415, x %= ((-1267051884)%(-643566443.0122576)));
- assertEquals(-30.84976063258681, x /= (((1052047194)>>>x)&(1495698235.5117269)));
- assertEquals(-61.69952126517362, x += x);
- assertEquals(-244, x <<= (x^(x+(tmp = -2822258210.076373, tmp))));
- assertEquals(-6652, x &= ((tmp = 2593685093, tmp)>>((((2047688852.4609032)<<((x*(-611076291))*x))^(-2665364024.817528))>>>(165267874))));
- assertEquals(0, x -= x);
- assertEquals(0, x /= (2454186758));
- assertEquals(0, x &= (tmp = -2226895206, tmp));
- assertEquals(0, x += x);
- assertEquals(-21390701, x += ((-1369004846.0816503)>>(tmp = -2661552634.039692, tmp)));
- assertEquals(-0.012568536912921919, x /= (1701924507.856429));
- assertEquals(7.09517966608176e-11, x /= (tmp = -177141911.8955555, tmp));
- assertEquals(0, x >>= (tmp = 231535697, tmp));
- assertEquals(1383687797, x ^= (tmp = -2911279499.568808, tmp));
- assertEquals(1383687797, x %= (tmp = -2258636646.5294995, tmp));
- assertEquals(1319, x >>= ((tmp = -2549411892.8426056, tmp)/(((((1532476676)^(153720871.82640445))+x)/(((2988190456.3206205)&(tmp = -2920873674, tmp))-(((((tmp = -1044518167.0581458, tmp)>>x)-((((tmp = -194701879.13505793, tmp)&(498352051))&((tmp = -2167339635.6529818, tmp)^(((x>>(tmp = 700159851, tmp))*(tmp = 2874921158, tmp))/x)))-((2856128689)|((-1876321441)>>>(2110732915)))))^((((tmp = -193379494.18825436, tmp)/(-3055182489.533142))<<x)+((tmp = -2286109605, tmp)>>(tmp = 698475484.3987849, tmp))))^(3182231653.500364))))|(((tmp = -194670835, tmp)>>>((786780139)%(((2114171416.2305853)^(1703145352.8143656))/x)))>>>((tmp = -3029462067, tmp)>>((67647572.02624655)&(x*(-2394283060))))))));
- assertEquals(13903855, x |= ((tmp = -2515306586, tmp)>>>x));
- assertEquals(54311, x >>>= ((-2413722658)-((tmp = -2159787584, tmp)^(tmp = 949937622.9744623, tmp))));
- assertEquals(108622, x += x);
- assertEquals(1250717187, x ^= ((tmp = 842692148, tmp)+(((2649331689.694273)<<x)-(tmp = -2992181273, tmp))));
- assertEquals(4536777, x %= (tmp = 73304730, tmp));
- assertEquals(0, x -= x);
- assertEquals(-580081499, x ^= ((tmp = -580081499.0170684, tmp)^(x%(tmp = -1542730817.88261, tmp))));
- assertEquals(-1382738784, x <<= x);
- assertEquals(-1382738784, x <<= x);
- assertEquals(2912228512, x >>>= (x*(x>>>x)));
- assertEquals(-1076374105, x |= (2589443367));
- assertEquals(-0.2818750938197037, x /= (((tmp = -1559525732.9603848, tmp)|(-477068917.5483327))>>>((-688616257)*((((tmp = -1192490153.1226473, tmp)*(-502280624.0265591))<<(-442688727.4881985))%(x+(((((tmp = -2948836853.831935, tmp)-(tmp = -2850398330.910424, tmp))>>>(x>>>(-1947835558)))^x)+(x*x)))))));
- assertEquals(2032826546, x |= (tmp = 2032826546.819327, tmp));
- assertEquals(3408404827.14316, x += (tmp = 1375578281.1431599, tmp));
- assertEquals(258183922.14315987, x %= (tmp = 350024545, tmp));
- assertEquals(479694848, x <<= (tmp = -481187157, tmp));
- assertEquals(-2147483648, x <<= (((tmp = -2956588045.472398, tmp)>>>(((tmp = -1838455399.1775856, tmp)&(((((tmp = -637547, tmp)/x)&(x^((-44876328.1767962)+(((-2059598286)-(1071496688))%(tmp = -1492254402, tmp)))))-(x%x))*(x|x)))>>(1226250760)))<<x));
- assertEquals(-2288163338.9020815, x -= (140679690.9020816));
- assertEquals(4954833118513997000, x *= (-2165419327.4906025));
- assertEquals(1578331238, x ^= (-2410854298.2270393));
- assertEquals(-810627292, x += (-2388958530));
- assertEquals(-810627292, x ^= ((1495296640.4087524)/(tmp = 1561790291, tmp)));
- assertEquals(657116606535253200, x *= x);
- assertEquals(0.675840332689047, x %= (((-1816548473)^(((tmp = -151918689.19451094, tmp)|(1819911186.535233))/((((((1514297447)+(tmp = 856485190.9684253, tmp))&(((1809369464.4363992)<<(493538496))*x))+((x*(x>>(x&(tmp = 222293461, tmp))))>>>(((784519621)|x)^((-580766922)>>(tmp = -947264116, tmp)))))>>>((((2794210354.22964)>>>(((2896952532.0183973)*((x+(tmp = -1813175940, tmp))<<(tmp = -1302618293, tmp)))&x))>>(x-(((x|((1456466890.1952953)*x))^(-169979758.19158387))-(x-x))))>>x))&(tmp = 2671604078.3026733, tmp))))/(-1701675745)));
- assertEquals(0.675840332689047, x %= ((tmp = 2421871143, tmp)^x));
- assertEquals(NaN, x %= ((((tmp = 1175526323.433271, tmp)+(tmp = 2813009575.952405, tmp))%((tmp = -3112133516.3303423, tmp)&x))&((((((-424329392)^(tmp = 1430146361, tmp))+x)-(1533557337.268306))%((tmp = -3117619446, tmp)-(-3127129232)))>>>x)));
- assertEquals(NaN, x += x);
- assertEquals(0, x >>>= ((1710641057.7325037)%(104961723.56541145)));
- assertEquals(0, x <<= (tmp = -970072906, tmp));
- assertEquals(0, x *= (87768668));
- assertEquals(-1464968122, x ^= (tmp = -1464968122, tmp));
- assertEquals(-1467983895, x ^= ((tmp = -1204896021, tmp)>>>(((91792661)&(x>>>(((-2364345606)>>>x)*x)))+x)));
- assertEquals(2.991581508270506, x /= (-490704963.5591147));
- assertEquals(0, x >>>= x);
- assertEquals(0, x >>= ((tmp = 639854873, tmp)%(tmp = 743486160.3597239, tmp)));
- assertEquals(0, x <<= (tmp = 1045577245.3403939, tmp));
- assertEquals(0, x >>= ((tmp = -1932462290, tmp)|(tmp = 1629217987, tmp)));
- assertEquals(517617438, x ^= ((tmp = 2737789043, tmp)%(tmp = -2220171604.135681, tmp)));
- assertEquals(126371, x >>>= ((tmp = 205210223.69909227, tmp)-(tmp = 598118404, tmp)));
- assertEquals(918548455, x |= ((918228734.8363427)+(x+x)));
- assertEquals(918548455, x |= ((tmp = 599828198, tmp)>>((tmp = -851081330, tmp)|(tmp = -1152596996.8443217, tmp))));
- assertEquals(918548443.7739062, x -= ((tmp = 1497642976.2260938, tmp)%(x>>(tmp = -548469702.5849569, tmp))));
- assertEquals(0.7739062309265137, x %= (x&x));
- assertEquals(2317939163.8239403, x *= (tmp = 2995116296, tmp));
- assertEquals(1014415360, x <<= (-279972114));
- assertEquals(0, x &= ((296810932)/(x*(tmp = -2750499950, tmp))));
- assertEquals(0, x *= (x%((126285451.05086231)>>>(x*(tmp = -2789790532, tmp)))));
- assertEquals(0, x >>>= ((975695102.5771483)%(x-((-1011726540)-((tmp = 2223194882, tmp)/x)))));
- assertEquals(-1747794584, x |= (-1747794584.3839395));
- assertEquals(-543544679, x %= (tmp = -1204249905, tmp));
- assertEquals(-543544679, x %= (-881024001));
- assertEquals(1, x /= x);
- assertEquals(-1879376393, x |= ((tmp = 161643764, tmp)|(tmp = 2281346499.9084272, tmp)));
- assertEquals(1.321124264431369, x /= (-1422558379.7061746));
- assertEquals(1, x >>>= (x&(tmp = -963118950.4710281, tmp)));
- assertEquals(3, x ^= ((x+x)/x));
- assertEquals(1, x /= x);
- assertEquals(1, x &= (2090796073));
- assertEquals(-1284301873, x ^= (((-11041168.146357536)+(tmp = -1273260707.8134556, tmp))+x));
- assertEquals(292559045, x &= (x&((-2401110739)^((tmp = 630802904, tmp)^(((1012634447.0346229)+x)%((tmp = -1240091095, tmp)%(x/(-1483936527))))))));
- assertEquals(0, x %= x);
- assertEquals(0, x /= (tmp = 613145428.3653506, tmp));
- assertEquals(0, x /= ((x-(tmp = 3116638456, tmp))*(-973300716)));
- assertEquals(0, x %= (tmp = -1794741286.0464535, tmp));
- assertEquals(0, x &= x);
- assertEquals(0, x >>= (-551370105.0746605));
- assertEquals(-1471996874, x ^= ((2822970422.2331414)-x));
- assertEquals(-277914313, x |= (tmp = -818980601.2544096, tmp));
- assertEquals(-34, x >>= x);
- assertEquals(305422768, x -= (-305422802));
- assertEquals(-2406146240, x += (tmp = -2711569008, tmp));
- assertEquals(1073745408, x &= (tmp = -3046625618, tmp));
- assertEquals(1073745408, x <<= ((-1234108306.7646303)<<((-233519302)|x)));
- assertEquals(1073745408, x %= (tmp = 1898831268, tmp));
- assertEquals(1073745408, x <<= (((tmp = 3089406038, tmp)/x)&(-2960027680)));
- assertEquals(65536, x >>>= (2858188366));
- assertEquals(128, x >>>= ((-2640257239.857275)%((tmp = -3185405235.3177376, tmp)*x)));
- assertEquals(128, x >>>= x);
- assertEquals(128, x -= (x&(x-(tmp = -247588018, tmp))));
- assertEquals(81616906825.07776, x *= (tmp = 637632084.57092, tmp));
- assertEquals(78860097686.07776, x -= (((1507215684)^((709254783)+(((x<<x)*((-2890828152.667641)%(2537817529.2041526)))^x)))+(3114024487)));
- assertEquals(-2920545695.721283, x += (((tmp = -2555437435, tmp)>>>x)-((2920546109.72129)+x)));
- assertEquals(-2879412281.721283, x += ((-1662428756)>>>(tmp = -1928491386.6926208, tmp)));
- assertEquals(67403845, x &= (tmp = 2921644117, tmp));
- assertEquals(16850961, x >>>= (((-1039328365)>>>(tmp = -768615112, tmp))<<((1037261855)*(tmp = -2906902831.4797926, tmp))));
- assertEquals(0, x ^= x);
- assertEquals(0, x *= ((-2729056530)/((-1776175111)%(1493002300.4604707))));
- assertEquals(0, x *= (tmp = 370696035.22912216, tmp));
- assertEquals(0, x ^= x);
- assertEquals(0, x |= ((((((tmp = -1541196993, tmp)^x)/(854730380.1799632))/(2879117705.492209))+((((-2892068577)^(-2460614446.1044483))>>>((743413943)<<(-1285280084.4220598)))/(tmp = -1719994579.5141463, tmp)))%(((((tmp = 2522797851.088227, tmp)<<(tmp = 2257160597.1538725, tmp))/(-680406007))&((x>>>(tmp = -260350730, tmp))^(tmp = 1920522110.852598, tmp)))>>(-697620442))));
- assertEquals(0, x &= x);
- assertEquals(-591399642.958673, x += (x-(tmp = 591399642.958673, tmp)));
- assertEquals(27, x >>>= (tmp = -726721317.2109983, tmp));
- assertEquals(-2043736843, x -= (2043736870));
- assertEquals(-3991674, x >>= (tmp = 1098126089, tmp));
- assertEquals(-997919, x >>= ((x%(((x*(((-1497329257.1781685)%(2334511329.2690516))/(-3072526140.6635056)))+(-1843998852))-(tmp = 240300314.34070587, tmp)))+(714080860.6032693)));
- assertEquals(-0, x %= x);
- assertEquals(NaN, x /= x);
- assertEquals(0, x >>= (tmp = 538348328.5363884, tmp));
- assertEquals(0, x *= (800317515));
- assertEquals(0, x -= x);
- assertEquals(0, x >>= (984205514));
- assertEquals(857282491, x += (tmp = 857282491, tmp));
- assertEquals(587792897, x &= (tmp = 2951307845.164059, tmp));
- assertEquals(595301269, x |= (tmp = 24285588.90314555, tmp));
- assertEquals(1190602538, x += x);
- assertEquals(0, x -= x);
- assertEquals(-442423060, x |= ((x^((x-(tmp = 2342497475.637024, tmp))%(-1900074414.7678084)))|((tmp = 1932380130, tmp)%(x%(2291727569.817062)))));
- assertEquals(-442423060, x %= (((tmp = 703479475.545413, tmp)>>(x-x))<<(2435723056.753845)));
- assertEquals(1, x /= x);
- assertEquals(0, x >>= x);
- assertEquals(-1265317851, x |= (tmp = -1265317851, tmp));
- assertEquals(-2, x >>= (-2015895906.8256726));
- assertEquals(-0, x %= x);
- assertEquals(-0, x %= (((1219237746)+(284683029))*(((tmp = 2288119628, tmp)|(-404658161.2563329))*(-265228691.74142504))));
- assertEquals(1039509109, x -= (-1039509109));
- assertEquals(2079018218, x += x);
- assertEquals(-1979.9362673719077, x /= ((3219723500)>>x));
- assertEquals(-62, x >>= ((x/(326466691))*(tmp = -607654070, tmp)));
- assertEquals(-45, x |= (tmp = -2954888429.549882, tmp));
- assertEquals(-1180929712, x &= (3114037588.570232));
- assertEquals(815550480, x &= (-2302684143.3378315));
- assertEquals(815550480, x %= (-2177479570));
- assertEquals(815550480, x %= (tmp = 2895822167, tmp));
- assertEquals(815550480, x %= (-1247621230.5438688));
- assertEquals(283929811, x -= ((tmp = 251831053.17096448, tmp)|((tmp = 1140463506.004994, tmp)+(tmp = -743224673.546309, tmp))));
- assertEquals(1825767424, x <<= (((tmp = 1732353599, tmp)^(tmp = 658726044, tmp))>>>((-2827889370.932477)%(tmp = 1950139204.3291233, tmp))));
- assertEquals(1828450414, x |= (tmp = 1618538606, tmp));
- assertEquals(0, x <<= (-2411670689.045702));
- assertEquals(0, x <<= (-27744888.428537607));
- assertEquals(-0, x /= (tmp = -1597552450, tmp));
- assertEquals(0, x >>>= (((2165722776.7220936)>>>(tmp = 1233069931, tmp))>>>(-1120420811)));
- assertEquals(-0, x *= ((tmp = -1505252656, tmp)>>((((3035637099.6156535)&((467761577.7669761)>>(-361034537)))^(tmp = -2347994840.6541123, tmp))*(tmp = -2191739821, tmp))));
- assertEquals(0, x &= (795727404.0738752));
- assertEquals(-0, x *= (tmp = -3125944685.3991394, tmp));
- assertEquals(-0, x *= (x&x));
- assertEquals(0, x >>= ((tmp = -2045709233, tmp)^x));
- assertEquals(NaN, x /= (x>>(x/(3102894071))));
- assertEquals(NaN, x += ((tmp = 2149079756.8941655, tmp)-(tmp = 810121645.305179, tmp)));
- assertEquals(0, x >>>= (-859842989));
- assertEquals(0, x >>>= (tmp = 2530531143.9369526, tmp));
- assertEquals(0, x >>= (((-932981419.6254237)|(tmp = 1591591715, tmp))>>>(x+((3149795006)>>>(tmp = 613352154, tmp)))));
- assertEquals(-4294967295, x -= ((((-2289331668)%(-282648480.0078714))>>(-1373720705.5142756))>>>((tmp = 15511563.517014384, tmp)/(360279080))));
- assertEquals(1, x &= x);
- assertEquals(0, x >>= (x^(-2791872557.5190563)));
- assertEquals(0, x &= ((tmp = 336466956.7847167, tmp)>>((1235728252.053619)|(x<<((1828176636.13488)%x)))));
- assertEquals(-0, x *= (-364042830.8894656));
- assertEquals(0, x >>>= x);
- assertEquals(-1675298680, x |= ((2323049541.321387)+(296619075)));
- assertEquals(-0, x %= x);
- assertEquals(-1583048579.4420977, x += (-1583048579.4420977));
- assertEquals(0, x -= x);
- assertEquals(-2, x ^= ((603171992.0545617)/(((-271888695.718297)%(tmp = -400159585, tmp))^((((tmp = 1536123971, tmp)-(tmp = -2310418666.6243773, tmp))|((tmp = 2242779597.1219435, tmp)<<(tmp = 1758127684.4745512, tmp)))/x))));
- assertEquals(-2, x &= (x&x));
- assertEquals(0, x &= ((tmp = -1098806007.4049063, tmp)/(((2862384059.3229523)/((((tmp = -92960842, tmp)-(x>>(tmp = 1244068344.2269042, tmp)))&x)*(tmp = -1919148313, tmp)))<<(-2486665929))));
- assertEquals(0, x &= x);
- assertEquals(-1441272634.582818, x -= (1441272634.582818));
- assertEquals(-3, x >>= (tmp = 3186393693.7727594, tmp));
- assertEquals(-1206855850, x ^= (((tmp = 607979495.303539, tmp)-(tmp = -2480131951, tmp))^(x*((tmp = 1324153477, tmp)/((1248126288)+(x|(1917331780.0741704)))))));
- assertEquals(-1206855853, x ^= (x>>>(653288765.1749961)));
- assertEquals(-1206857725, x &= (3149461539.6019173));
- assertEquals(3088109571, x >>>= (x*(x<<(tmp = 1543540084, tmp))));
- assertEquals(536903680, x &= (tmp = 644851760, tmp));
- assertEquals(536903674.312194, x += (((-3183290076)-((tmp = 40738191.12097299, tmp)-x))/((x>>>(3151371851.9408646))^(tmp = 472698205.22445416, tmp))));
- assertEquals(2127424750.0506563, x -= (tmp = -1590521075.7384624, tmp));
- assertEquals(2127424750.0506563, x %= (tmp = 3027273433.361373, tmp));
- assertEquals(0, x >>= (x>>(1445204441.702043)));
- assertEquals(NaN, x %= (x<<x));
- assertEquals(0, x ^= ((tmp = -2903841152.136344, tmp)-(x%(2938662860))));
- assertEquals(0, x <<= (x<<x));
- assertEquals(0, x >>>= (tmp = -979481631.33442, tmp));
- assertEquals(0, x >>= x);
- assertEquals(0, x &= (((x%((((((tmp = 1657446354.6820035, tmp)>>(-1916527001.2992697))/x)>>(tmp = 1450467955, tmp))&(277676820))+(x/(-945587805))))/((tmp = -690095354, tmp)^x))+(tmp = -2651195021, tmp)));
- assertEquals(0, x <<= (752343428.2934296));
- assertEquals(0, x /= (tmp = 3022310299, tmp));
- assertEquals(0, x >>= (x%((388245402)>>>x)));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x %= ((tmp = 1205123529.8649468, tmp)>>>(-2848300932)));
- assertEquals(0, x >>= ((x>>>x)<<(tmp = 487841938, tmp)));
- assertEquals(0, x *= (((273436000.9463471)|(tmp = 141134074.27978027, tmp))^(tmp = 1220326800.7885802, tmp)));
- assertEquals(1525600768, x |= (((x^(-2674777396))-(tmp = 1966360716.3434916, tmp))<<(794782595.9340223)));
- assertEquals(761927595, x %= (tmp = -763673173, tmp));
- assertEquals(1.1353588586934338, x /= ((x&((-1897159300.4789193)*(-348338328.0939896)))&(978680905.6470605)));
- assertEquals(8.631173314966319e-10, x /= (1315416592));
- assertEquals(0, x >>= ((tmp = -2581239435, tmp)-((-628818404.1122074)<<x)));
- assertEquals(0, x -= x);
- assertEquals(0, x *= (2925158236));
- assertEquals(0, x /= (x+(tmp = 1405531594.0181243, tmp)));
- assertEquals(0, x *= (2712022631.230831));
- assertEquals(0, x >>= (tmp = 80518779.81608999, tmp));
- assertEquals(1953477932.8046472, x += (tmp = 1953477932.8046472, tmp));
- assertEquals(1953477932, x >>= (tmp = 3025539936, tmp));
- assertEquals(1953477932, x -= ((-2675119685.8812313)>>(x/(-1808264410.9754841))));
- assertEquals(1292620430, x += ((-660857502)%((((tmp = -698782819, tmp)%(tmp = 2847304199, tmp))<<(-2423443217.1315413))+x)));
- assertEquals(78895, x >>>= x);
- assertEquals(2, x >>= x);
- assertEquals(2, x <<= (tmp = 1313641888.8301702, tmp));
- assertEquals(1857416935.2532766, x += (tmp = 1857416933.2532766, tmp));
- assertEquals(-1677721600, x <<= (tmp = -2482476902, tmp));
- assertEquals(309226853.62854385, x -= (tmp = -1986948453.6285439, tmp));
- assertEquals(33965156, x &= (2409088742));
- assertEquals(Infinity, x /= (x-(x<<((x/(tmp = -3106546671.536726, tmp))/((tmp = 2695710176, tmp)-((((-2102442864)&(857636911.7079853))/x)%(-65640292)))))));
- assertEquals(1270005091, x |= (tmp = 1270005091.0081215, tmp));
- assertEquals(1270005091, x %= (tmp = -1833876598.2761571, tmp));
- assertEquals(158750636, x >>>= x);
- assertEquals(-1000809106.0879555, x -= (tmp = 1159559742.0879555, tmp));
- assertEquals(72400936, x &= ((2448271389.3097963)%(tmp = 1517733861, tmp)));
- assertEquals(282816, x >>= x);
- assertEquals(282816, x %= (tmp = 3192677386, tmp));
- assertEquals(0.00021521351827207216, x /= (1314118194.2040696));
- assertEquals(Infinity, x /= (((tmp = 2822091386.1977024, tmp)&x)%(tmp = -3155658210, tmp)));
- assertEquals(NaN, x %= (-359319199));
- assertEquals(0, x >>>= (((tmp = -2651558483, tmp)-(x<<(tmp = 2537675226.941645, tmp)))<<(tmp = 667468049.0240343, tmp)));
- assertEquals(-0, x *= (tmp = -2827980482.12998, tmp));
- assertEquals(-0, x %= (((tmp = -689972329.3533998, tmp)>>>x)|(tmp = -7488144, tmp)));
- assertEquals(0, x >>>= x);
- assertEquals(0, x |= x);
- assertEquals(-2410373675.2262926, x -= (2410373675.2262926));
- assertEquals(1840423, x >>= ((-1081642113)^x));
- assertEquals(-4829451429403412, x *= (-2624098606.35485));
- assertEquals(-94552231, x %= (tmp = -97015883, tmp));
- assertEquals(-94433287, x ^= (((tmp = -2297735280, tmp)&(((tmp = 2261074987.7072973, tmp)%((((2565078998)^(-2573247878))|x)|(((tmp = -2120919004.7239416, tmp)>>(tmp = -579224101, tmp))>>>(1905808441))))*(x|(3149383322))))>>(542664972)));
- assertEquals(0, x ^= (x<<(tmp = -3112569312, tmp)));
- assertEquals(0, x <<= (-2141934818.7052917));
- assertEquals(0, x >>= (tmp = -2539525922, tmp));
- assertEquals(-434467613, x ^= (tmp = -434467613, tmp));
- assertEquals(-274792709, x |= (1233452601.462551));
- assertEquals(-274726917, x |= (-2130333750));
- assertEquals(-272629761, x |= (-1516071602.5622227));
- assertEquals(-272629761, x |= ((tmp = 3012131694, tmp)&((tmp = -2595342375.8674774, tmp)-((tmp = -2710765792, tmp)>>>((x-(tmp = 2397845540, tmp))+(2496667307))))));
- assertEquals(-4194305, x |= (1343705633.165825));
- assertEquals(4190207, x >>>= ((tmp = 276587830, tmp)*((tmp = -1517753936, tmp)>>x)));
- assertEquals(0, x >>= (x|((2247486919)-((-1664642412.4710495)*((((tmp = -358185292.17083216, tmp)-(tmp = -1472193444, tmp))*(tmp = 2699733752, tmp))&((x|(x<<(1137610148.1318119)))>>(((375089690.8764564)*x)&(tmp = 859788933.9560187, tmp))))))));
- assertEquals(0, x %= (3080673960));
- assertEquals(0, x >>>= (1328846190.1963305));
- assertEquals(1249447579, x |= (-3045519717.580775));
- assertEquals(-0.8743931060971377, x /= (-1428931187));
- assertEquals(1, x |= ((tmp = -1756877535.7557893, tmp)/((-142900015.93200803)<<(1414557031.347334))));
- assertEquals(759627265, x ^= (759627264.0514802));
- assertEquals(741823, x >>= (1106391210));
- assertEquals(610451, x &= ((x>>>((919849416)+((tmp = -427708986, tmp)^((x%x)|(tmp = -2853100288.932063, tmp)))))*x));
- assertEquals(372650423401, x *= x);
- assertEquals(410404493, x >>>= ((((-1425086765)>>>x)>>((2813118707.914771)>>(-424850240)))^x));
- assertEquals(120511585729013, x *= ((tmp = -1889454669, tmp)>>>x));
- assertEquals(120513295294304.22, x -= (tmp = -1709565291.2115698, tmp));
- assertEquals(6164, x >>>= ((2244715719.397763)^(tmp = -741235818.6903033, tmp)));
- assertEquals(937572790.468221, x -= (tmp = -937566626.468221, tmp));
- assertEquals(937572790, x |= ((2129102867.156146)*(x%x)));
- assertEquals(32, x &= ((2700124055.3712993)>>>((1977241506)>>>(-2915605511))));
- assertEquals(32, x %= (tmp = -2513825862, tmp));
- assertEquals(0, x <<= (-1379604802));
- assertEquals(0, x >>>= (tmp = -1033248759, tmp));
- assertEquals(-1151517050, x ^= (3143450246));
- assertEquals(-180577, x |= ((738373819.4081701)^(-357134176)));
- assertEquals(-0, x %= x);
- assertEquals(-2086887759, x |= (tmp = 2208079537, tmp));
- assertEquals(-2, x >>= (1460216478.7305799));
- assertEquals(-2, x %= ((-1979700249.0593133)^(-3156454032.4790583)));
- assertEquals(-256, x <<= ((1810316926)>>>(tmp = 414362256, tmp)));
- assertEquals(-1, x >>= (((((((-1616428585.595561)*((tmp = 2574896242.9045777, tmp)|(86659152.37838173)))>>(((tmp = 2476869361, tmp)&((x+((tmp = -2445847462.1974697, tmp)>>(tmp = -1960643509.5255682, tmp)))+(x|(((((2231574372.778028)|(tmp = 1824767560, tmp))>>>((1108035230.2692142)|(tmp = 2354035815, tmp)))/((tmp = -2602922032, tmp)>>(-925080304.7681987)))-x))))-(x>>x)))>>>((tmp = 751425805.8402164, tmp)|(tmp = 1165240270.3437088, tmp)))-x)*(2870745939))-(x>>>((tmp = 2986532631.405425, tmp)>>>(((tmp = 2547448699, tmp)+(((((x<<(((((-2756908638.4197435)>>>(3134770084))-(-1147872642.3756688))%(x*(tmp = -282198341.6600039, tmp)))+(-770969864.2055655)))+((-2725270341)^x))/(-3093925722))>>(x&x))>>((tmp = -2705768192, tmp)>>>(((tmp = 577253091.6042917, tmp)/(((x&(((((x+x)>>>(-1000588972))/(x&(717414336)))^(tmp = 428782104.21504414, tmp))>>>(1084724288.953223)))%(tmp = -2130932217.4562194, tmp))&x))-(-286367389)))))+((x>>(tmp = 2001277117, tmp))>>((tmp = 1028512592, tmp)^((tmp = 2055148650, tmp)+((tmp = 1490798399, tmp)/(tmp = -2077566434.2678986, tmp))))))))));
- assertEquals(-1, x |= (tmp = 1542129482, tmp));
- assertEquals(-671816743, x &= (tmp = -671816743.9111726, tmp));
- assertEquals(-1840333080, x -= (1168516337));
- assertEquals(-1755382023, x |= ((((tmp = 2625163636.0142937, tmp)>>>((tmp = 1534304735, tmp)^x))-(tmp = -1959666777.9995313, tmp))%x));
- assertEquals(-1750421896, x += (x>>>(tmp = -1364828055.1003118, tmp)));
- assertEquals(-72864007, x %= (tmp = 239651127, tmp));
- assertEquals(-72863956, x -= (((tmp = -1103261657.626319, tmp)*((tmp = 2789506613, tmp)+((tmp = 2294239314, tmp)>>>(2588428607.5454817))))>>x));
- assertEquals(-170337477, x -= (tmp = 97473521, tmp));
- assertEquals(-170337477, x |= (((tmp = 246292300.58998203, tmp)/(((tmp = -2664407492, tmp)|((-2416228818)^(tmp = 909802077, tmp)))%(tmp = 532643021.68109465, tmp)))/(tmp = 1015597843.8295637, tmp)));
- assertEquals(1, x >>>= (((tmp = -2247554641.7422867, tmp)/(1186555294))%(tmp = -785511772.3124621, tmp)));
- assertEquals(1188939891.668705, x -= (tmp = -1188939890.668705, tmp));
- assertEquals(1188939891, x &= x);
- assertEquals(1188413555, x &= (((tmp = -372965330.5709038, tmp)%(((tmp = 3108909487, tmp)|(x^(-1056955571.9951684)))^(-1549217484.009048)))/(x>>>(1403428437.9368362))));
- assertEquals(-0.7343692094664643, x /= (-1618278026.4758227));
- assertEquals(0, x -= x);
- assertEquals(0, x &= (-2701762139.7500515));
- assertEquals(0, x >>>= (((-1692761485.2299166)^x)+(tmp = -1221349575.938864, tmp)));
- assertEquals(0, x <<= ((2148160230)<<x));
- assertEquals(0, x <<= (((x<<(-740907931.38363))&(tmp = -930960051.6095045, tmp))>>(x/((tmp = -1921545150.1239789, tmp)/(-3015379806)))));
- assertEquals(0, x <<= x);
- assertEquals(NaN, x /= (x|x));
- assertEquals(0, x >>= (tmp = -2265988773, tmp));
- assertEquals(-0, x *= (((x<<(-928153614))<<(-989694208))^(2544757713.481016)));
- assertEquals(0, x >>= ((tmp = 578009959.5299993, tmp)>>x));
- assertEquals(0, x /= ((((tmp = 412689800.0431709, tmp)&(1630886276))*(tmp = 2028783080.7296097, tmp))/x));
- assertEquals(0, x |= ((((x*(-2197198786))>>((2719887264.761987)<<(tmp = 2253246512, tmp)))-(tmp = -150703768.07045603, tmp))/(((-3160098146)%(((((1486098047.843547)>>(((tmp = -593773744.1144242, tmp)&(x<<(2651087978)))|((-680492758.930413)>>(tmp = 88363052.13662052, tmp))))<<x)<<(tmp = 2232672341, tmp))/((x<<x)&(((((348589117.64135563)<<(-1010050456.3097556))^(x/(tmp = -2282328795, tmp)))-(tmp = 1653716293, tmp))-((3157124731)/((tmp = 3007369535.341745, tmp)%(tmp = -2246556917, tmp)))))))+x)));
- assertEquals(0, x >>= ((1935211663.5568764)>>(x-(tmp = 2116580032, tmp))));
- assertEquals(-1725272693, x ^= (tmp = -1725272693, tmp));
- assertEquals(313683, x >>>= (-1782632531.2877684));
- assertEquals(0.009772287443565642, x /= (tmp = 32099240, tmp));
- assertEquals(-647945916.9902277, x += (-647945917));
- assertEquals(3647021380, x >>>= ((((((((2470411371.688199)<<x)>>x)-(x>>>((tmp = 1750747780, tmp)/x)))-x)<<(tmp = -2666186351.695101, tmp))^(((tmp = 2749205312.6666174, tmp)%x)&(2069802830.360536)))<<(tmp = 6051917.9244532585, tmp)));
- assertEquals(-647939220, x |= ((x>>>((tmp = -2980404582.794245, tmp)>>>(-996846982)))^x));
- assertEquals(-572178450, x |= ((-800571300.3277931)+(tmp = 2084365671, tmp)));
- assertEquals(1172311208, x &= (x&((tmp = -1207487657.8953774, tmp)^x)));
- assertEquals(12176516458994, x += ((((tmp = -1534997221, tmp)%(412142731))*((tmp = 2958726303, tmp)>>(1489169839)))+(((-574726407.2051775)>>>(((1772885017)<<(947804536.9958035))>>(-2406844737)))>>x)));
- assertEquals(-1480065024, x <<= x);
- assertEquals(-1736999042.227129, x += (tmp = -256934018.22712898, tmp));
- assertEquals(-1338699394, x ^= ((((((x%(((tmp = -2551168455.222048, tmp)|(3213507293.930222))/((-1559278033)>>((tmp = 3107774495.3698573, tmp)-(2456375180.8660913)))))*((x*(tmp = 1088820004.8562922, tmp))+((tmp = 1850986704.9836102, tmp)%(tmp = -1226590364, tmp))))*(1786192008))&(((2193303940.310299)%(tmp = 1041726867.0602217, tmp))|((2210722848)/((-1293401295.6714435)&((tmp = 3052430315, tmp)|x)))))>>>(tmp = -2028014470.1524236, tmp))+(((1695818039.0383925)<<((1669068145)*(-2746592133.899276)))<<(tmp = 519092169, tmp))));
- assertEquals(-334674849, x >>= (1170377794));
- assertEquals(-10214, x >>= ((tmp = 1074704264.3712895, tmp)>>>((tmp = -1200860192, tmp)^((tmp = 539325023.4101218, tmp)*((tmp = -588989295, tmp)|x)))));
- assertEquals(1384169472, x &= (1384171140));
- assertEquals(1384169472, x >>>= ((tmp = -2161405973.830981, tmp)*(tmp = 2054628644, tmp)));
- assertEquals(1610140972, x |= (527961388));
- assertEquals(1073273198, x += ((tmp = -259650225.71344328, tmp)&(tmp = -344359694, tmp)));
- assertEquals(65507, x >>= ((x<<((tmp = 2925070713.5245204, tmp)%(x+((tmp = -1229447799, tmp)/(((x/(x|(((-2337139694)|((((((2996268529.7965417)&x)%(((tmp = -1088587413, tmp)>>(-1384104418.90339))>>((tmp = -1643984822.3946526, tmp)+x)))%(((1118125268.4540217)-((((-1975051668.6652594)-(-704573232))+((tmp = 1674952373, tmp)/(tmp = 1321895696.0062659, tmp)))*(tmp = 1820002533.2021284, tmp)))>>>(tmp = -583960746.9993203, tmp)))|((tmp = -2577675508.550925, tmp)&x))/(tmp = 1459790066, tmp)))/(((((1051712301.7804044)&(tmp = -2726396354, tmp))^(tmp = 263937254.18934345, tmp))+(((x^x)*(((tmp = -2289491571, tmp)+x)%(-2239181148)))&x))>>(tmp = -1743418186.3030887, tmp)))))/(tmp = 1475718622, tmp))<<x)))))|(x&((((tmp = -2934707420, tmp)<<x)/x)^(1022527598.7386684)))));
- assertEquals(2047, x >>= (x-(tmp = 2300626270, tmp)));
- assertEquals(8384512, x <<= (tmp = -1917680820, tmp));
- assertEquals(0, x <<= (2393691134));
- assertEquals(0, x >>= x);
- assertEquals(649995936.5853252, x -= (tmp = -649995936.5853252, tmp));
- assertEquals(649995936, x &= x);
- assertEquals(-0.33672017582945424, x /= (tmp = -1930374188, tmp));
- assertEquals(-0.33672017582945424, x += (x&((1208055031)^(-2761287670.968586))));
- assertEquals(0, x |= x);
- assertEquals(0, x <<= ((-2038368978)/x));
- assertEquals(0, x >>= (x&((tmp = 2481378057.738218, tmp)&(x+(1172701643)))));
- assertEquals(0, x <<= ((x*(((((((tmp = 70690601.3046323, tmp)&(((((((((((x+(x+(x^(3118107461))))<<(264682213.41888392))&(tmp = -709415381.8623683, tmp))%(((((-1840054964)>>>(tmp = -405893120.89603686, tmp))|((-625507229)^(3128979265)))>>(x>>((tmp = -2480442390, tmp)*((x>>(tmp = -421414980.88330936, tmp))>>>((tmp = 1850868592, tmp)&(-2948543832.879225))))))|((2986545185)&((tmp = -1947550706, tmp)%(((tmp = 2590238422.1414256, tmp)/(((tmp = -361038812, tmp)>>x)|(((tmp = 1798444068, tmp)|((x&((tmp = -3104542069, tmp)-x))*((tmp = -1158658918, tmp)+((tmp = 2777031040.5552707, tmp)<<(-2816019335.9008327)))))<<x)))/(((2287795988.231702)/x)/(((-2588712925)>>>(2521189250))*((tmp = -2533527920, tmp)+(tmp = 1762281307.2162101, tmp)))))))))/x)/(tmp = 1047121955.5357032, tmp))|(((-121292251)<<(x^(x-(tmp = 1420006180, tmp))))%((-2278606219)>>>(((tmp = -1412487726, tmp)&(((((tmp = 253596554.16016424, tmp)/(tmp = 2083376247.0079951, tmp))^(x^((1549116789.8449988)>>>((((-1844170084)^(tmp = 1886066422, tmp))&x)<<(34918329)))))^(tmp = -440805555.3369155, tmp))-x))%(-1936512969)))))+(2911511178.4035435))|(1012059391))|(x>>>(tmp = -2551794626.158037, tmp)))+((2926596072.210515)/(tmp = -280299595.0450909, tmp))))&((tmp = 1501086971, tmp)^(tmp = 2114076983, tmp)))-((-1679390574.1466925)-(941349044)))-((x>>x)>>((-2600539474.2033434)+(tmp = 2567056503.9079475, tmp))))*(tmp = 1285896052, tmp))%(((tmp = 1191465410.7595167, tmp)>>((tmp = -2857472754, tmp)%x))>>>(((tmp = 1960819627.6552541, tmp)&(-2651207221.127376))*((((-687312743)+((x>>x)<<x))|((((((1549588195)*((tmp = 2733091019, tmp)^((527322540)<<(x>>x))))%(tmp = -2063962943, tmp))*x)*(734060600))&(-3049417708)))+(((((1084267726)+((x|x)^((tmp = -1917070472.4858549, tmp)%((690016078.9375831)*x))))%((((((tmp = -2091172769, tmp)%(2532365378))>>>(-871354260))/(tmp = 254167019.07825458, tmp))&(1330216175.9871218))>>(tmp = 1931099207, tmp)))^(-1116448185.2618852))>>((961660080.8135855)/x)))))))>>>(-1486048007.7053368)));
- assertEquals(0, x >>= x);
- assertEquals(0, x %= (tmp = -1202200444.6506357, tmp));
- assertEquals(-0, x *= (-527500796.4145117));
- assertEquals(0, x >>= (tmp = -2082822707, tmp));
- assertEquals(0, x *= ((-1882398459.290778)>>>x));
- assertEquals(0, x &= (x/(tmp = -1569332286.392817, tmp)));
- assertEquals(-390169607, x |= (-390169607.11600184));
- assertEquals(-780339214, x += x);
- assertEquals(-780339214, x %= (2765959073));
- assertEquals(-5954, x >>= (tmp = -1900007055, tmp));
- assertEquals(743563420, x &= ((((-1520146483.5367205)|(-2075330284.3762321))-(tmp = -2263151872, tmp))%(-1264641939.957402)));
- assertEquals(1487126840, x += (x>>>(((x+((tmp = -1263274491, tmp)>>>x))&(470419048.0490037))%(tmp = -2642587112, tmp))));
- assertEquals(Infinity, x /= (x^x));
- assertEquals(0, x ^= ((tmp = -1436368543, tmp)+(x/(tmp = -1125415374.3297129, tmp))));
- assertEquals(0, x += x);
- assertEquals(0, x <<= x);
- assertEquals(0, x &= (tmp = 3101147204.2905564, tmp));
- assertEquals(0, x &= (tmp = 2914487586.606511, tmp));
- assertEquals(0, x += x);
- assertEquals(0, x -= (((-1738542908.6138556)&(((x+x)-(tmp = -2801153969, tmp))%(tmp = -1206684064.1477358, tmp)))>>((-2575546469.271897)|(tmp = -2573119106, tmp))));
- assertEquals(-1468808707, x ^= (tmp = -1468808707, tmp));
- assertEquals(1357349882, x <<= (tmp = -2808501087.7003627, tmp));
- assertEquals(-572025862, x |= ((((tmp = -2415486246.573399, tmp)/((tmp = -707895732.4593301, tmp)&x))%((-1960091005.0425267)*(972618070.9166157)))-(1649962343)));
- assertEquals(327213586796843100, x *= (x%(1337884626)));
- assertEquals(42991616, x &= (-2905576654.1280055));
- assertEquals(-26049289585042860, x *= (-605915571.6557121));
- assertEquals(597809748, x >>= ((362850791.077795)/(tmp = 1222777657.4401796, tmp)));
- assertEquals(597809748, x |= x);
- assertEquals(770065246, x -= ((-711227660)|(tmp = -508554506, tmp)));
- assertEquals(593000483097040500, x *= x);
- assertEquals(0, x %= x);
- assertEquals(0, x <<= (317862995.456813));
- assertEquals(0, x >>= ((tmp = 2518385735, tmp)+((-2973864605.267604)/(-930953312.718833))));
- assertEquals(1227822411, x ^= (x^(1227822411.8553264)));
- assertEquals(1090520320, x &= (x+((((-2100097959)>>(x/(tmp = -2002285068, tmp)))/(-364207954.9242482))-((tmp = 2771293106.7927113, tmp)-(tmp = -847237774, tmp)))));
- assertEquals(1090520320, x >>= (((((2439492849)<<((-2932672756.2578926)*((743648426.7224461)+((2942284935)<<((x/(((tmp = 886289462.6565771, tmp)+(-459458622.7475352))>>(tmp = -785521448.4979162, tmp)))|(tmp = -11630282.877367258, tmp))))))-(tmp = -647511106.9602091, tmp))^x)&x));
- assertEquals(115944291.48829031, x %= (243644007.12792742));
- assertEquals(1, x /= x);
- assertEquals(0, x >>>= ((tmp = -819782567, tmp)%(tmp = 2774793208.1994505, tmp)));
- assertEquals(0, x >>= (tmp = 721096000.2409859, tmp));
- assertEquals(0, x &= ((x%x)%x));
- assertEquals(-0, x *= ((-1670466344)<<x));
- assertEquals(0, x >>= (-677240844.904707));
- assertEquals(NaN, x %= (((((-1575993236.6126876)/(-2846264078.9581823))^((((-2220459664)-(((-1809496020)>>>(tmp = -3015964803.4566207, tmp))&x))/(tmp = -3081895596.0486784, tmp))>>>(x&x)))%(x^(-1338943139)))^(x-((((2074140963.2841332)^(tmp = 1878485274, tmp))%(((x/(-2568856967.6491556))^x)<<((x+x)^((((2139002721)|(x<<(-1356174045.840464)))>>x)-(tmp = 2305062176, tmp)))))>>>(((((x<<(tmp = -1663280319.078543, tmp))-((1498355849.4158854)-((-1321681257)>>>(tmp = -1321415088.6152222, tmp))))^(-2266278142.1584673))+(858538943))&((((x-((x|(((tmp = -1576599651, tmp)+((tmp = 1595319586, tmp)&(-2736785205.9203863)))>>((x+((-1856237826)+x))<<(tmp = -1590561854.3540869, tmp))))^(((-41283672.55606127)&(tmp = 2971132248, tmp))+x)))/(-849371349.1667476))%(x*((-1705070934.6892798)>>>x)))<<((2418200640)*x)))))));
- assertEquals(0, x >>>= (tmp = 664214199.5283061, tmp));
- assertEquals(0, x <<= ((-2827299151)<<(1815817649)));
- assertEquals(1405772596, x |= (tmp = 1405772596, tmp));
- assertEquals(-1483422104, x <<= (-2791499935.6822596));
- assertEquals(-45271, x >>= (1740128943.4254808));
- assertEquals(-45271, x <<= ((2072269957)-((tmp = -2553664811.4472017, tmp)*(tmp = -2502730352, tmp))));
- assertEquals(1192951471.6745887, x -= (-1192996742.6745887));
- assertEquals(-353370112, x <<= (tmp = -1410280844, tmp));
- assertEquals(0, x ^= (x%((2754092728)*(-1017564599.1094015))));
- assertEquals(-2662096003.2397957, x -= (tmp = 2662096003.2397957, tmp));
- assertEquals(-2587094028.50764, x -= (tmp = -75001974.7321558, tmp));
- assertEquals(6693055512339889000, x *= x);
- assertEquals(897526784, x %= (x-((tmp = 897526813, tmp)%(-1525574090))));
- assertEquals(7011928, x >>= ((-440899641.344357)%x));
- assertEquals(8382047686388683, x += (x*(1195398423.8538609)));
- assertEquals(16764095372777366, x += x);
- assertEquals(16764096859576696, x -= (tmp = -1486799329.7207344, tmp));
- assertEquals(16764099774187724, x += (2914611029));
- assertEquals(16764102926624664, x -= (-3152436939.724612));
- assertEquals(-538220648, x |= x);
- assertEquals(269110324, x /= (((-2114698894.6014318)/(tmp = 767687453, tmp))>>(623601568.1558858)));
- assertEquals(256, x >>= x);
- assertEquals(-293446891, x += (x+(-293447403)));
- assertEquals(119, x >>>= ((1759400753)>>(2481263470.4489403)));
- assertEquals(14, x >>= (762849027.89693));
- assertEquals(16, x += (x&(x>>(1104537666.1510491))));
- assertEquals(-12499808227.980995, x *= (tmp = -781238014.2488122, tmp));
- assertEquals(1, x /= x);
- assertEquals(1, x &= x);
- assertEquals(0, x >>>= ((tmp = 1513381008, tmp)|(tmp = 1593208075.7259543, tmp)));
- assertEquals(0, x &= (-788154636.2843091));
- assertEquals(-0, x /= (tmp = -2124830879, tmp));
- assertEquals(0, x &= (934237436));
- assertEquals(0, x |= x);
- assertEquals(-79370942.97651315, x += (-79370942.97651315));
- assertEquals(-79370942.97651315, x %= ((tmp = -2683255523, tmp)<<(tmp = 2323123280.287587, tmp)));
- assertEquals(-79370942, x |= x);
- assertEquals(0.05861647801688159, x /= (-1354072177.061561));
- assertEquals(0, x <<= (((((((tmp = 1989257036, tmp)&(tmp = 1565496213.6578887, tmp))&x)&(tmp = -2798643735.905287, tmp))&(2354854813.43784))%(tmp = 1118124748, tmp))<<((tmp = 2453617740, tmp)*(((tmp = 1762604500.492329, tmp)<<(-2865619363))%(((2474193854.640994)|((tmp = 1425847419.6256948, tmp)|(((-1271669386)%((x|((tmp = -2059795445.3607287, tmp)+x))*(x*x)))>>>(tmp = -2997360849.0750895, tmp))))/(tmp = 2326894252, tmp))))));
- assertEquals(0, x >>>= ((-671325215)/((-727408755.8793397)>>(tmp = 315457854, tmp))));
- assertEquals(0, x >>= (x&x));
- assertEquals(0, x <<= ((x/x)>>>(((((x&x)-((x*(((tmp = -2689062497.0087833, tmp)^x)/((-1465906334.9701924)<<(tmp = -349000262, tmp))))*x))%(1630399442.5429945))*x)+((tmp = 605234630, tmp)%(tmp = 2325750892.5065155, tmp)))));
- assertEquals(0, x |= (x%((x>>(((((tmp = 1622100459, tmp)<<x)&((((((tmp = 2411490075, tmp)<<x)|x)>>((x<<x)-(-2133780459)))/x)&(x+x)))%(x/((((tmp = 580125125.5035453, tmp)>>>(-470336002.1246581))|((tmp = 871348531, tmp)*x))>>(2866448831.23781))))-((2352334552)-(-562797641.6467373))))-(x^(tmp = -681731388, tmp)))));
- assertEquals(0, x <<= (tmp = -1358347010.3729038, tmp));
- assertEquals(-260967814, x |= ((tmp = -260967814.45976686, tmp)%(tmp = 1126020255.1772437, tmp)));
- assertEquals(NaN, x %= ((((tmp = 3176388281, tmp)<<(tmp = 611228283.2600244, tmp))>>>((tmp = 3068009824, tmp)+(tmp = 2482705111, tmp)))>>>((tmp = -750778285.2580311, tmp)>>>x)));
- assertEquals(0, x <<= (x>>>x));
- assertEquals(0, x /= (1238919162));
- assertEquals(0, x >>= (x^x));
- assertEquals(0, x &= (-2137844801));
- assertEquals(0, x >>>= (x^(x*(-1774217252))));
- assertEquals(0, x >>= x);
- assertEquals(0, x |= x);
- assertEquals(0, x &= (x<<(tmp = 2791377560, tmp)));
- assertEquals(-1330674638.8117397, x += (tmp = -1330674638.8117397, tmp));
- assertEquals(353, x >>>= (-212202857.4320326));
- assertEquals(353, x ^= ((((x+(tmp = 1448262278, tmp))-(-3141272537))>>(tmp = 1116596587.7832575, tmp))>>>((x-(((tmp = 303953098, tmp)>>>((tmp = 691514425, tmp)/((176223098)*(((2876180016)%(-1805235275.892374))|x))))<<(((tmp = 528736141.838547, tmp)^(2556817082))*(2898381286.2846575))))|((-1445518239)&(tmp = 389789481.9604758, tmp)))));
- assertEquals(0, x >>>= (-227376461.14343977));
- assertEquals(0, x <<= (tmp = -2575967504, tmp));
- assertEquals(0, x <<= (x^((-2668391896)>>((x+(tmp = 598697235.9205595, tmp))+((((-2105306785)|((-1174912319.794015)>>>(x-((148979923)%((((tmp = -2459140558.4436393, tmp)|(1265905916.494016))^(tmp = 1213922357.2230597, tmp))|(1028030636))))))%x)+(((tmp = 1393280827.0135512, tmp)^((tmp = 1210906638, tmp)+(-1572777641.1396031)))<<x))))));
- assertEquals(0, x *= (tmp = 2134187165, tmp));
- assertEquals(-1084549964, x -= (tmp = 1084549964, tmp));
- assertEquals(-2045706240, x &= ((tmp = -1250758905.7889671, tmp)*(x+(((x<<(x/(tmp = -738983664.845448, tmp)))>>>x)&(tmp = 2197525295, tmp)))));
- assertEquals(-2045706240, x ^= (((522049712.14743733)>>(tmp = -2695628092, tmp))>>>(tmp = -2603972068, tmp)));
- assertEquals(2249261056, x >>>= x);
- assertEquals(-33291, x |= ((((1891467762)<<(184547486.213719))-((458875403.50689447)^(((x&(x*x))|x)%(-3127945140))))|(-100765232)));
- assertEquals(-33291, x %= (1460486884.1367688));
- assertEquals(-1, x >>= (tmp = -2667341441, tmp));
- assertEquals(-3.6289151568259606e-10, x /= (tmp = 2755644474.4072013, tmp));
- assertEquals(-3.6289151568259606e-10, x %= (tmp = 1186700893.0751028, tmp));
- assertEquals(0, x <<= (tmp = -1199872107.9612694, tmp));
- assertEquals(371216449, x ^= ((tmp = 371324611.1357789, tmp)&(x-(x|((tmp = -518410357, tmp)>>((tmp = 687379733, tmp)/x))))));
- assertEquals(0.3561383159088311, x /= (((((x%(((((-2293101242)%((((495316779)/x)-((-3198854939.8857965)>>>((tmp = -288916023, tmp)-(x^(tmp = -2504080119.431858, tmp)))))^(-1201674989)))-((2965433901)*(405932927)))/((1974547923)|(tmp = 534069372, tmp)))-(x-((x+(-1258297330))%x))))<<(((-2648166176.4947824)^(-3043930615))&(1550481610)))<<(tmp = -3118264986.743822, tmp))<<x)|x));
- assertEquals(-46272499.15029934, x -= (tmp = 46272499.50643766, tmp));
- assertEquals(-6, x >>= ((tmp = -731454087.0621192, tmp)>>>x));
- assertEquals(-2.7207928474520667e-9, x /= (((x<<(x|((tmp = -1650731700.9540024, tmp)/(tmp = -677823292, tmp))))^((((((1972576122.928667)>>x)%(2952412902.115453))<<((-2888879343)+(tmp = -425663504, tmp)))>>>(((((tmp = 1089969932, tmp)>>>(x|((-2088509661)/(1131470551))))>>>x)+x)|(tmp = 955695979.7982506, tmp)))|(((((tmp = 826954002.6188571, tmp)^(2016485728))|((x/(((x<<(tmp = 2493217141, tmp))/(-2259979800.997408))-(tmp = -427592173.41389966, tmp)))%(((-471172918)/x)>>>((383234436.16425097)&(tmp = 1664411146.5308032, tmp)))))*(tmp = 1863669754.7545495, tmp))*(x>>(2062197604)))))>>>((x-(2624545856))*(tmp = 1025803102, tmp))));
- assertEquals(0, x >>= ((tmp = 1068702028, tmp)*(296106770)));
- assertEquals(0, x ^= (x/x));
- assertEquals(85359536, x ^= (((x|(((tmp = 740629227, tmp)<<(-1107397366))%((tmp = 2315368172, tmp)>>(((-2269513683)|(-2698795048))+(-396757976)))))*(929482738.803125))^(((-1415213955.4198723)-(tmp = -2885808324, tmp))>>>((tmp = -472842353.85736656, tmp)&(tmp = 1684231312.4497018, tmp)))));
- assertEquals(2075131904, x <<= x);
- assertEquals(123, x >>>= (x>>>(tmp = 754093009, tmp)));
- assertEquals(0, x >>= ((-2690948145)/((1988638799)+x)));
- assertEquals(0, x >>>= (tmp = -798849903.2467625, tmp));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x *= (2431863540.4609756));
- assertEquals(484934656, x |= ((-2322193663)*(tmp = -2754666771, tmp)));
- assertEquals(-82505091404694530, x *= (tmp = -170136513, tmp));
- assertEquals(-82505090515370620, x += ((-148762237)&(tmp = 889417717, tmp)));
- assertEquals(-908221124, x %= (tmp = -2346393300, tmp));
- assertEquals(-1242515799, x ^= (2083328917));
- assertEquals(-1126056310271520600, x *= ((((tmp = -3065605442, tmp)<<(-3012703413))|x)^(-2081329316.4781387)));
- assertEquals(-1126056309941068000, x += ((((tmp = 1886925157, tmp)&((tmp = -163003119.31722307, tmp)/((tmp = 2094816076, tmp)>>((tmp = -706947027, tmp)^x))))^((1819889650.5261197)<<(-1641091933)))>>x));
- assertEquals(-1864360191, x |= (((x/x)|x)|x));
- assertEquals(-1864360191, x &= x);
- assertEquals(-3728720382, x += x);
- assertEquals(1042663165, x ^= (535165183.4230335));
- assertEquals(2644530017.8833704, x += (1601866852.8833704));
- assertEquals(-574949401, x |= ((tmp = 943193254.5210983, tmp)^((x%(tmp = -2645213497, tmp))*(-1904818769))));
- assertEquals(1763223578, x ^= ((x^(tmp = -2244359016, tmp))^(tmp = 320955522, tmp)));
- assertEquals(-1.9640961474334235, x /= (tmp = -897727731.0502782, tmp));
- assertEquals(1, x >>>= (x-(-3183031393.8967886)));
- assertEquals(1, x &= (tmp = 1732572051.4196641, tmp));
- assertEquals(1, x >>= (-1642797568));
- assertEquals(-2339115203.3140306, x += (-2339115204.3140306));
- assertEquals(1955852093, x ^= (((((-1469402389)/(-2648643333.1454573))>>>x)<<(x/x))>>x));
- assertEquals(-965322519, x ^= (3001399252));
- assertEquals(-2139727840, x &= (tmp = 2298411812.964484, tmp));
- assertEquals(2103328, x &= (tmp = -2488723009, tmp));
- assertEquals(1799011007, x |= (tmp = -2498057537.226923, tmp));
- assertEquals(1799011007, x |= ((-308193085)>>>x));
- assertEquals(1799011007, x |= x);
- assertEquals(818879107, x ^= (1542823996.423564));
- assertEquals(-2601416919234843600, x *= ((-2357923057.076759)-x));
- assertEquals(-2601416920481796600, x -= (x|(tmp = -3048039765, tmp)));
- assertEquals(-33690112, x <<= x);
- assertEquals(1039491072, x &= (tmp = 1039491474.3389125, tmp));
- assertEquals(126891, x >>= (-3079837011.6151257));
- assertEquals(-163191923097543, x *= (((tmp = -2847221258.4048786, tmp)*(x-(tmp = 1527622853.5925639, tmp)))^x));
- assertEquals(753616551, x ^= (-946895202));
- assertEquals(-347691264, x <<= (tmp = -433184408.33790135, tmp));
- assertEquals(0, x <<= (x|(tmp = -1911731462.6835637, tmp)));
- assertEquals(-0, x *= (tmp = -2616154415.1662617, tmp));
- assertEquals(0, x >>= x);
- assertEquals(0, x -= x);
- assertEquals(0, x *= (2272504250.501526));
- assertEquals(0, x ^= x);
- assertEquals(NaN, x %= x);
- assertEquals(0, x >>>= (2475346113));
- assertEquals(NaN, x /= (((x+(-2646140897))&(((tmp = 1039073714.142481, tmp)-x)*x))|(x*(((-1277822905.773948)>>(tmp = 2035512354.2400663, tmp))*(77938193.80013895)))));
- assertEquals(0, x ^= (x<<(tmp = 2491934268, tmp)));
- assertEquals(0, x &= (tmp = 569878335.4607931, tmp));
- assertEquals(-88575883, x ^= ((453890820.8012209)-((1569189876)%((-1280613677.7083852)^(-1902514249.29567)))));
- assertEquals(-88575883, x %= (tmp = 257947563.19206762, tmp));
- assertEquals(-88575881.7863678, x -= ((tmp = 1257547359.029678, tmp)/(x^(tmp = 948265672.821815, tmp))));
- assertEquals(-169, x >>= (tmp = -2530523309.6703596, tmp));
- assertEquals(-1, x >>= x);
- assertEquals(-1, x |= x);
- assertEquals(131071, x >>>= (-673590289));
- assertEquals(1117196836, x -= (-1117065765));
- assertEquals(3092236000.7125187, x -= (-1975039164.7125185));
- assertEquals(1, x /= x);
- assertEquals(-1599945863, x ^= (tmp = 2695021432.453696, tmp));
- assertEquals(940543782, x ^= (tmp = 2561494111, tmp));
- assertEquals(891400321673221800, x *= (tmp = 947749949.2662871, tmp));
- assertEquals(-1509927296, x >>= ((tmp = 1113290009, tmp)-x));
- assertEquals(-23, x >>= (tmp = 3216989626.7370152, tmp));
- assertEquals(-0, x %= x);
- assertEquals(0, x <<= (431687857.15246475));
- assertEquals(-0, x /= (tmp = -1924652745.081665, tmp));
- assertEquals(0, x <<= (1312950547.2179976));
- assertEquals(0, x %= ((tmp = 2110842937.8580878, tmp)|(x<<x)));
- assertEquals(0, x >>>= ((((-386879000)-((tmp = -2334036143.9396124, tmp)/((tmp = 965101904.2841234, tmp)<<(((3029227182.8426695)<<((tmp = -464466927, tmp)>>((((((tmp = 849594477.4111787, tmp)^(x&((513950657.6663146)%(x>>>x))))-((2898589263)|x))+(tmp = 2842171258.621288, tmp))>>>(tmp = -3158746843, tmp))<<(tmp = -2891369879, tmp))))-(x-(x&(tmp = -1707413686.2706504, tmp)))))))-(-2860419051))*(-1708418923)));
- assertEquals(-328055783, x += ((((2857010474.8010874)|((tmp = -1415997622.320347, tmp)-(-1706423374)))%(tmp = 824357977.1339042, tmp))^(x>>(x|x))));
- assertEquals(-168539902503779140, x *= ((tmp = -1057687018, tmp)<<((1408752963)-(2030056734))));
- assertEquals(-Infinity, x /= ((x-(2232683614.320658))*(((tmp = 195551174, tmp)*((((739595970)>>>(tmp = -2218890946.8788786, tmp))>>>(((tmp = -240716255.22407627, tmp)&(((((1598029916.3478878)|((tmp = -881749732, tmp)+(x>>x)))^(4443059))<<(((tmp = 2453020763, tmp)+((x>>>(tmp = -1904203813, tmp))&(-355424604.49235344)))<<(tmp = 2814696070, tmp)))%((tmp = -250266444, tmp)>>>(((((2710614972)&(((tmp = 910572052.6994087, tmp)^(tmp = -1028443184.3220406, tmp))/((-2718010521)^(tmp = 676361106, tmp))))|x)^(-1326539884))>>(-1573782639.7129154)))))/(tmp = 1923172768, tmp)))>>>(tmp = -2858780232.4886074, tmp)))/((((((-2060319376.353397)%x)>>(tmp = -3122570085.9065285, tmp))/(tmp = -1499018723.8064275, tmp))*((-655257391)<<x))>>x))));
- assertEquals(NaN, x += ((3059633304)%((((tmp = 2538190083, tmp)*((tmp = -2386800763.356364, tmp)/x))&(1341370996))%(-2929765076.078223))));
- assertEquals(NaN, x %= ((x&(347774821))>>>(462318570.2578629)));
- assertEquals(NaN, x *= ((2829810152.071517)*(tmp = 768565684.6892327, tmp)));
- assertEquals(NaN, x -= x);
- assertEquals(0, x >>>= (x&(tmp = 1786182552, tmp)));
- assertEquals(973967377, x ^= ((tmp = 2115869489.836838, tmp)&(994956497)));
- assertEquals(985246427.4230617, x += (11279050.423061728));
- assertEquals(985246427, x &= x);
- assertEquals(0, x >>= ((tmp = 1090502660.1867907, tmp)>>((-1599370623.5747645)-(tmp = -1321550958, tmp))));
- assertEquals(0, x %= (tmp = -2386531950.018572, tmp));
- assertEquals(0, x >>>= x);
- assertEquals(NaN, x /= x);
- assertEquals(0, x >>>= (tmp = -1535987507.682257, tmp));
- assertEquals(-0, x /= (-2570639987));
- assertEquals(-542895632, x |= (tmp = -542895632, tmp));
- assertEquals(-33930977, x >>= (tmp = -861198108.1147206, tmp));
- assertEquals(-0, x %= x);
- assertEquals(0, x ^= (x*(-608154714.1872904)));
- assertEquals(-140011520, x |= ((tmp = 377418995, tmp)<<((1989575902)>>(tmp = -2558458031.066773, tmp))));
- assertEquals(-140026048, x -= ((((tmp = 1465272774.7540011, tmp)<<((2164701398)<<(tmp = -818119264, tmp)))>>((tmp = -1490486001, tmp)>>(664410099.6412607)))>>(x>>>(((tmp = -2438272073.2205153, tmp)%(tmp = 2142162105.4572072, tmp))-(tmp = 2259040711.6543813, tmp)))));
- assertEquals(39214588236996610, x *= (x<<(-401696127.06632423)));
- assertEquals(1, x /= x);
- assertEquals(0, x %= x);
- assertEquals(0, x *= ((tmp = -1709874807.176726, tmp)&(-2786424611)));
- assertEquals(-1320474063.3408537, x += (tmp = -1320474063.3408537, tmp));
- assertEquals(88, x >>>= (tmp = -3179247911.7094674, tmp));
- assertEquals(1606348131, x += ((tmp = 1555621121.5726175, tmp)|(-3026277110.9493155)));
- assertEquals(200793516, x >>>= x);
- assertEquals(-2952688672.1074514, x -= (tmp = 3153482188.1074514, tmp));
- assertEquals(1342278624, x >>>= ((x>>>((tmp = 1264475713, tmp)-(-913041544)))>>>((tmp = 2008379930, tmp)%(tmp = 3105129336, tmp))));
- assertEquals(0, x ^= x);
- assertEquals(0, x /= (tmp = 788363717, tmp));
- assertEquals(430466213, x -= (tmp = -430466213, tmp));
- assertEquals(164757385222499550, x *= (tmp = 382741735, tmp));
- assertEquals(164757385222499550, x %= (((tmp = 1974063648, tmp)%((806015603)>>>x))*((tmp = 2836795324, tmp)<<(tmp = -1785878767, tmp))));
- assertEquals(-190957725.86956096, x /= (x^((-2939333300.066044)-(x|(-2085991826)))));
- assertEquals(-190957725.86956096, x %= (tmp = -948386352, tmp));
- assertEquals(0.6457336106922105, x /= (-295722141));
- assertEquals(0, x |= ((415991250)&((x>>(tmp = -3188277823, tmp))<<(511898664.1008285))));
- assertEquals(0, x &= ((793238922)|x));
- assertEquals(-1576701979, x ^= (2718265317));
- assertEquals(-49271937, x >>= x);
- assertEquals(-49271937, x |= x);
- assertEquals(-49271937, x &= x);
- assertEquals(775316382, x -= (-824588319));
- assertEquals(912498176, x <<= (tmp = -2223542776.836312, tmp));
- assertEquals(0, x -= (x&((tmp = 1999412385.1074471, tmp)/(-1628205254))));
- assertEquals(0, x -= x);
- assertEquals(0, x >>= (-768730139.7749677));
- assertEquals(-1861304245, x |= (((5128483)^(((tmp = -1768372004, tmp)/(x^(tmp = 1310002444.757094, tmp)))*((tmp = 188242683.09898067, tmp)^(tmp = -2263757432, tmp))))^((tmp = 2223246327, tmp)*((tmp = -2360528979, tmp)-((tmp = 2442334308, tmp)>>(458302081))))));
- assertEquals(1, x /= x);
- assertEquals(2, x += x);
- assertEquals(1, x /= x);
- assertEquals(0, x ^= x);
- assertEquals(-0, x *= (-1852374359.3930533));
- assertEquals(0, x <<= (tmp = 1223645195.148961, tmp));
- assertEquals(1789655087, x |= ((-2505312209.770559)>>x));
- assertEquals(-65568768, x <<= x);
- assertEquals(4229398528, x >>>= x);
- assertEquals(-8408187, x |= (-3029781627));
- assertEquals(-8408187, x |= (((2322165037)-((tmp = -1424506897.362995, tmp)%x))&x));
- assertEquals(-7884926, x += (x>>>(x|(2738095820))));
- assertEquals(-7884926, x %= (576507013));
- assertEquals(751801768, x ^= (tmp = -750241238, tmp));
- assertEquals(-1986010067668600800, x *= (tmp = -2641667195, tmp));
- assertEquals(1921196240, x ^= (x%(-1954178308)));
- assertEquals(847388880, x ^= ((tmp = 1632856124, tmp)&((tmp = -1536309755, tmp)<<(tmp = -3158362800, tmp))));
- assertEquals(-469662000.6651099, x += (tmp = -1317050880.6651099, tmp));
- assertEquals(-812358332, x ^= ((-2832480471)>>>(2016495937)));
- assertEquals(21, x ^= (((tmp = 1815603134.2513008, tmp)/((tmp = 147415927, tmp)%(-1059701742)))+x));
- assertEquals(-2844409139.792712, x += (tmp = -2844409160.792712, tmp));
- assertEquals(177070, x >>>= x);
- assertEquals(0, x %= x);
- assertEquals(0, x >>= x);
- assertEquals(1459126376, x ^= (tmp = -2835840920, tmp));
- assertEquals(1459126376, x %= (-1462864282));
- assertEquals(0, x >>>= (tmp = 2922724319, tmp));
- assertEquals(338995506, x ^= (338995506.6411549));
- assertEquals(336896258, x &= (2635904967));
- assertEquals(336634112, x -= (x&(tmp = 1659656287, tmp)));
- assertEquals(NaN, x %= (x-x));
- assertEquals(NaN, x /= (tmp = -674606200, tmp));
- assertEquals(NaN, x %= ((x|(2788108542))/(x+(tmp = 600941473, tmp))));
- assertEquals(0, x >>>= ((-1858251597.3970242)>>>x));
- assertEquals(1951294747, x |= (tmp = 1951294747, tmp));
- assertEquals(1951294747, x &= x);
- assertEquals(-153190625, x |= (-1500095737));
- assertEquals(23467367587890624, x *= x);
- assertEquals(346531290.1813514, x /= (((((-513617734.11148167)|x)/((tmp = -2042982150.1170752, tmp)%((x%((x%x)>>>(((-1369980151)&(((922678983)%(x&(tmp = -855337708, tmp)))-((tmp = -2717183760, tmp)>>>((1939904985.4701347)%(((tmp = -2473316858, tmp)&((tmp = -599556221.9046664, tmp)>>((tmp = -6352213, tmp)/x)))&x)))))%x)))/((tmp = -1842773812.8648412, tmp)>>>(((x>>>(tmp = 499774063, tmp))<<(((tmp = -1353532660.5755146, tmp)*(-3070956509))>>(((-905883994.0188017)>>(tmp = -16637173, tmp))<<((tmp = 471668537, tmp)*((tmp = -232036004.26637793, tmp)/x)))))&(tmp = 85227224, tmp))))))>>>(x|(-2528471983)))-((tmp = 1531574803, tmp)+((x>>>x)-(2889291290.158888)))));
- assertEquals(-94.42225749399837, x /= (((tmp = 2381634642.1432824, tmp)>>(tmp = -2637618935, tmp))|(2307200473)));
- assertEquals(-47, x >>= (1524333345.141235));
- assertEquals(-2.8699253616435082e-8, x /= (1637673252));
- assertEquals(0, x |= x);
- assertEquals(1083427040, x += ((-2012055268)<<(tmp = -2192382589.6911573, tmp)));
- assertEquals(1083427040, x %= (x*x));
- assertEquals(2694039776, x += ((((-1740065704.9004602)<<(-736392934))%(2781638048.424092))>>>(x&x)));
- assertEquals(-1600927520, x |= ((tmp = 2904430054.869525, tmp)*(((1054051883.4751332)*x)*((-939020743)-(tmp = 1636935481.1834455, tmp)))));
- assertEquals(-1600927520, x -= (x%x));
- assertEquals(3037584978216498700, x *= (tmp = -1897390694, tmp));
- assertEquals(372598954.1823988, x %= (tmp = 1553763703.5082102, tmp));
- assertEquals(-1476395008, x <<= ((x>>((tmp = 282496335.49494267, tmp)^((-1948623419.6947453)|((((((tmp = -1203306995, tmp)-(-5554612.355098486))>>>(1867254951.4836824))>>x)|(-695777865))/((-59122652.19377303)<<(-609999229.7448442))))))>>(x/(tmp = -1207010654.9993455, tmp))));
- assertEquals(-2.2540185787941605, x /= (((tmp = 1364159859.9199843, tmp)*x)>>x));
- assertEquals(-2, x |= x);
- assertEquals(2241824008, x *= ((3174055292.962967)>>(((-2379151623.602476)>>(tmp = -1423760236, tmp))>>(tmp = -522536019.2225733, tmp))));
- assertEquals(-2138158385, x ^= ((x>>((((1316131966.9180691)-((x*x)>>x))>>>x)>>((-2712430284)|(((((x<<(-616185937.6090865))-(((x-(tmp = 2957048661, tmp))<<(tmp = 617564839.888214, tmp))/(x%((tmp = -447175647.9393475, tmp)<<(2203298493.460617)))))-((x&((x<<(914944265))^(((-1294901094)*((tmp = 2512344795, tmp)+((((tmp = -1227572518, tmp)%(1831277766.4920158))*((x|x)^(tmp = 2515415182.6718826, tmp)))*x)))-(961485129))))>>>(tmp = 2079018304, tmp)))>>(tmp = 734028202, tmp))^(554858721.6149715)))))-((tmp = 1312985279.5114603, tmp)^(tmp = 2450817476.179955, tmp))));
- assertEquals(2.759030298237921, x /= (x|(tmp = -775901745.3688724, tmp)));
- assertEquals(8, x <<= x);
- assertEquals(NaN, x %= (((x&((1792031228.831834)>>(-1174912501)))%(((-2351757750)+(tmp = -2610099430, tmp))*(-2811655968)))*(x&(tmp = -1881632878, tmp))));
- assertEquals(0, x &= ((x*(616116645.7508612))^(2789436828.536846)));
- assertEquals(0, x *= x);
- assertEquals(35097452, x ^= ((tmp = 1023684579, tmp)%(((x|((tmp = -757953041, tmp)+(772988909)))+(tmp = -2934577578, tmp))>>>((tmp = -1973224283, tmp)>>>((x*(2244818063.270375))|(x-(-716709285)))))));
- assertEquals(0.015207441433418992, x /= (2307913014.4056892));
- assertEquals(-5865042.942076175, x -= (5865042.957283616));
- assertEquals(-67719.94207617454, x %= (((1464126615.2493973)+(398302030.0108756))>>>x));
- assertEquals(4294899577, x >>>= (x<<x));
- assertEquals(-1, x >>= (tmp = 607447902, tmp));
- assertEquals(-1, x >>= (3081219749.9119744));
- assertEquals(6.53694303504065e-10, x /= (tmp = -1529767040.4034374, tmp));
- assertEquals(6.53694303504065e-10, x %= ((tmp = 899070650.7190754, tmp)&(tmp = -1101166301, tmp)));
- assertEquals(6.53694303504065e-10, x %= (tmp = -2207346460, tmp));
- assertEquals(NaN, x %= (((x&x)>>x)%(((-10980184)+x)&(tmp = -1473044870.4729445, tmp))));
- assertEquals(NaN, x -= x);
- assertEquals(-1755985426, x ^= (tmp = 2538981870, tmp));
- assertEquals(-13842, x %= ((((-2258237411.3816605)+(-1325704332.0531585))<<((tmp = -877665450.1877053, tmp)>>(((((2420989037)+(2084279990.6278818))*(-327869571.9348242))+x)^x)))>>>x));
- assertEquals(1, x /= x);
- assertEquals(1, x >>= ((2241312290)^(2859250114)));
- assertEquals(0, x >>= x);
- assertEquals(-1615631756, x |= (-1615631756.1469975));
- assertEquals(-1615631756, x |= x);
- assertEquals(-627245056, x <<= ((x*(tmp = -1308330685.5971081, tmp))|(tmp = 1479586158, tmp)));
- assertEquals(-627245056, x |= x);
- assertEquals(1786953888, x ^= (-1340096352.1839824));
- assertEquals(1668014353, x -= (tmp = 118939535, tmp));
- assertEquals(1, x /= x);
- assertEquals(-645681, x ^= ((-1322356629)>>(tmp = 1829870283, tmp)));
- assertEquals(-1322354688, x <<= (-794779253));
- assertEquals(-4310084378.672725, x += (-2987729690.6727247));
- assertEquals(-8620168757.34545, x += x);
- assertEquals(-8720421, x |= (tmp = -748107877.6417065, tmp));
- assertEquals(-1508858270, x ^= (1500137913));
- assertEquals(-0.825735756765112, x /= (1827289490.1767085));
- assertEquals(1253449509.1742642, x += (((tmp = 1253449509.9576545, tmp)-(((tmp = 2860243975, tmp)+(367947569.85976696))>>(((((530960315)>>>((((x%(tmp = -2203199228, tmp))<<(x*(((tmp = -117302283, tmp)/(x-((2579576936)%(-1225024012))))&(tmp = -2857767500.1967726, tmp))))/((x/((tmp = -166066119, tmp)<<x))|x))>>>x))|(((2771852372)>>(((tmp = -3103692094.1463976, tmp)-(tmp = 2867208546.069278, tmp))>>>(702718610.1963737)))|(tmp = 2680447361, tmp)))>>x)>>(-2006613979.051014))))^((-1665626277.9339101)/(x<<(tmp = 342268763, tmp)))));
- assertEquals(1693336701.1742642, x += (tmp = 439887192, tmp));
- assertEquals(0.8479581831275719, x /= ((1171383583)+(((x&x)>>>(51482548.618915915))-(tmp = -825572595.1031849, tmp))));
- assertEquals(28, x |= ((tmp = -2355932919.6737213, tmp)>>(tmp = -2395605638, tmp)));
- assertEquals(0, x %= x);
- assertEquals(0, x -= x);
- assertEquals(0, x <<= (x^((tmp = 2793423893.484949, tmp)*(1585074754.3250475))));
- assertEquals(0, x >>= (x/(x-((957719861.9175875)&(1288527195)))));
- assertEquals(0, x >>>= ((-1429196921.4432657)/x));
- assertEquals(-852424225.734199, x -= (tmp = 852424225.734199, tmp));
- assertEquals(-46674433, x |= ((tmp = -2335242963, tmp)*((2135206646.2614377)>>(tmp = 505649511.8292929, tmp))));
- assertEquals(2944662357, x += (tmp = 2991336790, tmp));
- assertEquals(1404, x >>>= (849155189.1503456));
- assertEquals(-846755170, x ^= (tmp = -846753822.4471285, tmp));
- assertEquals(52615, x >>>= ((-517068110)+x));
- assertEquals(1475021859.9916897, x += (tmp = 1474969244.9916897, tmp));
- assertEquals(0, x %= x);
- assertEquals(0, x %= ((539583595.8244679)*(tmp = 1469751690.9193692, tmp)));
- assertEquals(0, x &= (807524227.2057163));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x -= (x^((tmp = -362481588, tmp)%(2611296227))));
- assertEquals(NaN, x *= x);
- assertEquals(0, x >>= ((-2519875630.999908)<<x));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x += (((tmp = 2485209575, tmp)>>(tmp = 2326979823, tmp))%(x-(((-1296334640.7476478)&x)<<x))));
- assertEquals(0, x >>= (((tmp = 1370704131, tmp)^((((tmp = 793217372.7587746, tmp)>>(((-1455696484.109328)|(((((-2186284424.5379324)<<(tmp = 3052914152.254852, tmp))-(x>>(tmp = 3121403408, tmp)))+((778194280)-(((((tmp = 2398957652, tmp)-(x+(((-2592019996.937958)>>((tmp = 1648537981, tmp)>>x))<<(-677436594))))<<(39366669.09012544))|((tmp = 3133808408.9582872, tmp)-(-2987527245.010673)))*x)))|((tmp = -2178662629, tmp)<<x)))^(((tmp = 909652440.3570575, tmp)%(-2572839902.6852217))%(-1879408081))))*(tmp = -2910988598, tmp))&(((x^x)>>(2822040993))|((x*x)^(((1072489842.6785052)|(x-(((464054192.7390214)^x)<<(tmp = -2754448095, tmp))))*((tmp = -1544182396, tmp)/(tmp = -3198554481, tmp)))))))^(tmp = 1946162396.9841106, tmp)));
- assertEquals(371272192, x |= (((x^((x-(x/x))&(tmp = 2370429394, tmp)))-(tmp = -403692829, tmp))*(tmp = 2808636109, tmp)));
- assertEquals(929786482, x |= ((729966239.8987448)^(x-((tmp = 120127779, tmp)^((tmp = -3088531385, tmp)>>>((x+((tmp = 2364833601, tmp)>>>(((599149090.6666714)>>(tmp = 2838821032, tmp))%(tmp = -662846011, tmp))))-(tmp = 1168491221.1813436, tmp)))))));
- assertEquals(-681121542, x += ((-1610909505.998718)^((tmp = -957338882, tmp)>>>(tmp = 1935594133.6531684, tmp))));
- assertEquals(-2147483648, x <<= ((tmp = 15161708, tmp)|(2453975670)));
- assertEquals(-2147483648, x >>= x);
- assertEquals(0, x <<= (2080486058));
- assertEquals(0, x &= (((x&(tmp = -767821326, tmp))/((tmp = 1877040536, tmp)>>>(tmp = 2378603217.75597, tmp)))*(-1601799835)));
- assertEquals(0, x %= (-1820240383));
- assertEquals(1621233920, x ^= ((tmp = 820230232, tmp)*(1727283900)));
- assertEquals(1621233920, x |= (x>>>x));
- assertEquals(1621233931, x += ((tmp = 794966194.9011587, tmp)>>(tmp = -597737830.5450518, tmp)));
- assertEquals(1621276543, x |= (((x^((2354444886)+(tmp = 685142845.4708651, tmp)))-(tmp = 790204976.9120214, tmp))>>>((((tmp = -2792921939, tmp)/(((((tmp = -80705524, tmp)<<x)-(((((((tmp = 1951577216.379527, tmp)>>>x)%((-529882150)>>>(tmp = -1682409624, tmp)))<<((-42043756.29025769)-(-1803729173.6855814)))/(2937202170.118023))*(tmp = -1998098798.5722106, tmp))*(tmp = -2996229463.904228, tmp)))&x)>>>(-301330643)))/(-2858859382.0050273))-(tmp = 1571854256.0740635, tmp))));
- assertEquals(810638271, x >>>= (x/(1553632833)));
- assertEquals(810638271, x <<= (tmp = -1467397440, tmp));
- assertEquals(-2147483648, x <<= x);
- assertEquals(871068871, x ^= (tmp = 3018552519, tmp));
- assertEquals(-1073743881, x |= ((tmp = 2294122324.020989, tmp)|(tmp = -1799706842.4493146, tmp)));
- assertEquals(-77816868, x += (((-2225296403)&x)>>(tmp = -2667103424.445239, tmp)));
- assertEquals(-1215889, x >>= (tmp = 1876107590.8391647, tmp));
- assertEquals(-2431778, x += x);
- assertEquals(4292535518, x >>>= (((x>>(-1825580683))/x)%x));
- assertEquals(4292802560, x -= (x|(1492864090)));
- assertEquals(0, x -= x);
- assertEquals(0, x >>= x);
- assertEquals(0, x %= (tmp = 2173121205, tmp));
- assertEquals(0, x *= (x>>x));
- assertEquals(1565261471, x |= ((1565261471.323931)>>>x));
- assertEquals(0, x -= x);
- assertEquals(-86980804, x |= (-86980804));
- assertEquals(-698956484, x -= (((((2754713793.1746016)*(((((-1514587465.0698888)>>(tmp = -1307050817, tmp))/(tmp = 2368054667.438519, tmp))*(-1908125943.5714772))<<(x>>>(-357164827.4932244))))+(1257487617))<<(2954979945))&(612330472)));
- assertEquals(-1073741824, x <<= x);
- assertEquals(54497747, x ^= (-1019244077.098908));
- assertEquals(54501375, x |= (((tmp = 1944912427, tmp)>>>x)%x));
- assertEquals(0, x -= x);
- assertEquals(0, x -= x);
- assertEquals(-0, x *= (-1748215388));
- assertEquals(0, x >>= x);
- assertEquals(0, x >>>= (((tmp = 988769112, tmp)%(tmp = -3133658477, tmp))<<x));
- assertEquals(0, x %= (1685221089.2950323));
- assertEquals(0, x >>>= (x+((793467168)-(tmp = 135877882, tmp))));
- assertEquals(0, x %= ((tmp = -2406801984, tmp)%(tmp = -987618172, tmp)));
- assertEquals(0, x *= ((-2943444887.953456)|(tmp = -2327469738.4544783, tmp)));
- assertEquals(0, x >>= x);
- assertEquals(-145484729.70167828, x += (tmp = -145484729.70167828, tmp));
- assertEquals(1140855872, x &= (x^(tmp = 3151437967.965556, tmp)));
- assertEquals(1486808408, x += (tmp = 345952536, tmp));
- assertEquals(107846582.36594129, x %= (-1378961825.6340587));
- assertEquals(-642031616, x <<= (x+x));
- assertEquals(151747770.95108718, x *= (x/(tmp = 2716379907, tmp)));
- assertEquals(192723456, x <<= (tmp = -1731167384, tmp));
- assertEquals(2151208003, x -= ((-2151208003)+x));
- assertEquals(1, x /= x);
- assertEquals(1, x |= x);
- assertEquals(1996766603, x |= (1996766602));
- assertEquals(895606123, x ^= (tmp = 1113972960.966081, tmp));
- assertEquals(-1500036886, x ^= (tmp = 2482412929, tmp));
- assertEquals(-1542644247, x ^= (x>>>((tmp = 51449105, tmp)>>>(((-2057313176)*x)/(-1768119916)))));
- assertEquals(-1496074063273093600, x *= ((tmp = 786152274, tmp)^(387292498)));
- assertEquals(-794329073, x %= (((tmp = -2314637675.617696, tmp)*((((x*(411053423.29070306))-(2889448433.4240828))/((-970630131)/(tmp = -2886607600.7423067, tmp)))<<(tmp = 1263617112.9362245, tmp)))|(2816980223.8209996)));
- assertEquals(2468008436047106600, x *= (tmp = -3107035257.725115, tmp));
- assertEquals(3040956928, x >>>= ((tmp = 1514372119.1787262, tmp)*(3169809008)));
- assertEquals(-19, x >>= (tmp = -266966022.10604453, tmp));
- assertEquals(-1.6505580654964654e-8, x /= ((-3143841480)>>(x-x)));
- assertEquals(-2.2420284729165577e-7, x *= (x*((((703414102.2523813)%(tmp = 2989948152, tmp))-((-1583401827.2949386)^((tmp = -1916731338, tmp)%((331500653.3566053)|(((tmp = 29865940, tmp)+((tmp = -2294889418.6764183, tmp)<<(tmp = -1558629267.255229, tmp)))>>>(x*(x+x)))))))|((988977957)&(-2986790281)))));
- assertEquals(0, x ^= (x/(tmp = 781117823.345541, tmp)));
- assertEquals(NaN, x *= (((x^((((tmp = -2969290335, tmp)+(((((tmp = -175387021, tmp)&(tmp = -1080807973, tmp))<<(tmp = -2395571076.6876855, tmp))|((tmp = -1775289899.4106793, tmp)^x))|(-2963463918)))*(tmp = -1761443911, tmp))^(tmp = 847135725, tmp)))<<((146689636)<<x))%x));
- assertEquals(0, x ^= x);
- assertEquals(1720182184, x -= (((tmp = 3184020508, tmp)|((-489485703)+(tmp = -2644503573, tmp)))&(tmp = 2575055579.6375213, tmp)));
- assertEquals(1720182184, x >>= (x<<(-45408034)));
- assertEquals(5.759243187540471e+27, x *= (((x&(1456298805))+(x<<(106573181)))*((566861317.2877743)+(2262937360.3733215))));
- assertEquals(5.759243187540471e+27, x -= (tmp = -1365873935, tmp));
- assertEquals(0, x <<= x);
- assertEquals(0, x >>= (1960073319.3465362));
- assertEquals(0, x <<= x);
- assertEquals(560463904, x += ((tmp = 1844076589.9286406, tmp)&((((((-691675777.5800121)|(-745631201))|x)+(tmp = 1504458593.2843904, tmp))-x)<<x)));
- assertEquals(-513210271, x -= (x|(1052702623.7761713)));
- assertEquals(3781757025, x >>>= ((-1346666404.362477)*(tmp = 2798191459, tmp)));
- assertEquals(1080100929, x &= (1122097879.882534));
- assertEquals(1276833905.8093092, x *= ((1276833905.8093092)/x));
- assertEquals(1276833905.8093092, x %= (1796226525.7152414));
- assertEquals(1276833905, x <<= (((tmp = -491205007.83412814, tmp)*(tmp = 1496201476.496839, tmp))>>(x+((tmp = -854043282.114594, tmp)-((x|(tmp = -807842056, tmp))*x)))));
- assertEquals(1276833905, x %= (((-1870099318)>>>(((tmp = -2689717222, tmp)/(248095232))/(tmp = 1036728800.5566598, tmp)))&(((((857866837)>>(tmp = 3034825801.740485, tmp))|(-1676371984))>>>(x<<x))%((-3035366571.0221004)*(1578324367.8819473)))));
- assertEquals(1, x /= x);
- assertEquals(2819223656.189109, x += (2819223655.189109));
- assertEquals(-1475743640, x >>= (((tmp = 2586723314.38089, tmp)/(x&(tmp = -697978283.9961061, tmp)))<<(x%((-1167534676)>>(x^((tmp = -284763535, tmp)*((x%x)&((((tmp = 2916973220.726839, tmp)%x)/(tmp = -1338421209.0621986, tmp))|((tmp = -834710536.803335, tmp)%x)))))))));
- assertEquals(-3267683406, x -= (tmp = 1791939766, tmp));
- assertEquals(-2090420900700614100, x *= (639725653));
- assertEquals(-1540353536, x %= ((-1800269105)<<((((x&(((tmp = 1135087416.3945065, tmp)^(613708290))>>x))>>(tmp = -1234604858.7683473, tmp))^(2404822882.7666225))>>>((tmp = -287205516, tmp)-((1648853730.1462333)^((x+(x%((tmp = 359176339, tmp)%((2856479172)<<(tmp = -1995209313, tmp)))))^(((tmp = 2857919171.839304, tmp)>>>(tmp = 2779498870, tmp))>>x)))))));
- assertEquals(-2093767030, x ^= (654554250.498078));
- assertEquals(1, x >>>= ((tmp = -166296226.12181997, tmp)^(x/x)));
- assertEquals(-1487427474, x -= ((x<<x)|(1487427475.4063978)));
- assertEquals(-1487427470.562726, x += ((-1226399959.8267038)/((tmp = 2172365551, tmp)<<x)));
- assertEquals(-3457859227618939400, x *= (tmp = 2324724597.3686075, tmp));
- assertEquals(396221312, x >>= (-1354035390));
- assertEquals(0, x %= x);
- assertEquals(0, x &= (tmp = 2733387603, tmp));
- assertEquals(1485905453, x |= ((((tmp = -1321532329.304437, tmp)&((((tmp = 1817382709.4180388, tmp)%(((tmp = 2089156555.7749293, tmp)-(-1555460267))|(tmp = 717392475.9986715, tmp)))%(tmp = 1976713214, tmp))^x))>>>x)+(tmp = -2812404197.002721, tmp)));
- assertEquals(1485905453, x |= x);
- assertEquals(-997658264, x <<= (-1409757949.6038744));
- assertEquals(-997657290, x -= ((-2041106361)>>(tmp = -2014750507, tmp)));
- assertEquals(-2138512124, x &= (tmp = 2565597060, tmp));
- assertEquals(8422400, x &= ((-2819342693.5172367)*(tmp = 1441722560, tmp)));
- assertEquals(111816531.81703067, x -= (-103394131.81703067));
- assertEquals(59606682.673836395, x *= ((tmp = -1451690098, tmp)/(x-(2835050651.717734))));
- assertEquals(-119213365.34767279, x *= (x|((-2656365050)/((-66180492)+(tmp = 284225706.32323086, tmp)))));
- assertEquals(-232839, x >>= (1694344809.435083));
- assertEquals(-1, x >>= x);
- assertEquals(1, x *= x);
- assertEquals(1, x |= x);
- assertEquals(0, x >>= (tmp = 397239268, tmp));
- assertEquals(-1525784563, x -= (tmp = 1525784563, tmp));
- assertEquals(-153.62740888512675, x /= (((tmp = -2040622579.5354173, tmp)*(tmp = -1149025861.549324, tmp))%(((tmp = 2981701364.0073133, tmp)*(tmp = 2993366361, tmp))|(x|(tmp = 1800299979, tmp)))));
- assertEquals(-1671795135, x &= (-1671795135.6173766));
- assertEquals(-4253, x |= ((((x*((1533721762.8796673)<<((tmp = 1026164775.0081646, tmp)<<x)))<<(((x-((((x>>((((((tmp = -481536070.7067797, tmp)&(tmp = 1663121016, tmp))>>>(-2974733313.5449667))+(tmp = -493019653, tmp))>>x)&(tmp = 879307404.8600142, tmp)))>>>x)%(x-(tmp = -1806412445.788453, tmp)))%x))<<(x<<(x+x)))+x))>>((tmp = -332473688.28477216, tmp)<<((tmp = 1701065928, tmp)+(((((tmp = -2407330783, tmp)+x)-((tmp = 584100783, tmp)%(tmp = -3077106506, tmp)))^x)>>x))))<<x));
- assertEquals(-0, x %= x);
- assertEquals(0, x >>>= x);
- assertEquals(0, x >>>= (1578470476.6074834));
- assertEquals(0, x >>>= (974609751));
- assertEquals(-120, x += (x-((tmp = -245718438.0842378, tmp)>>>(tmp = -1870354951, tmp))));
- assertEquals(-6.134465505515781e-8, x /= (1956160645));
- assertEquals(-0, x %= x);
- assertEquals(0, x *= (tmp = -399718472.70049024, tmp));
- assertEquals(-1803198769.8413258, x += (-1803198769.8413258));
- assertEquals(988624943, x ^= ((((tmp = 320776739.5608537, tmp)*(((tmp = -983452570.3150327, tmp)^x)&(tmp = -3181597938, tmp)))-(tmp = -1367913740.9036021, tmp))/(((tmp = -535854933.2943456, tmp)-(717666905.8122432))>>>(((((x^(tmp = 380453258.60062766, tmp))^(tmp = -1242333929, tmp))/((tmp = 1072416261, tmp)+(((2090466933)*(x*(tmp = -386283072, tmp)))|((tmp = 789259942, tmp)<<(tmp = -1475723636.1901488, tmp)))))>>>x)%((x>>(tmp = -1243048658.3818703, tmp))|((((((tmp = -619553509, tmp)|x)/(878117279.285609))|((x<<(x>>>(tmp = -749568437.7390883, tmp)))*x))/(tmp = 1674804407, tmp))-(x*(tmp = 1528620873, tmp))))))));
- assertEquals(988625135, x |= (x>>>(tmp = 2402222006, tmp)));
- assertEquals(988625135, x %= (-2691094165.990094));
- assertEquals(0, x %= x);
- assertEquals(-0, x *= (tmp = -1409904262, tmp));
- assertEquals(-0, x /= ((1176483512.8626208)<<x));
- assertEquals(0, x &= ((((1677892713.6240005)^(tmp = 2575724881, tmp))^(tmp = -2935655281.208194, tmp))*(216675668)));
- assertEquals(0, x >>= (tmp = -1296960457, tmp));
- assertEquals(0, x |= x);
- assertEquals(NaN, x /= x);
- assertEquals(0, x <<= (x>>(-3127984289.9112387)));
- assertEquals(0, x %= ((tmp = 190018725.45957255, tmp)<<((x>>>x)/x)));
- assertEquals(0, x /= (1185681972));
- assertEquals(0, x &= ((tmp = -1285574617, tmp)>>x));
- assertEquals(0, x >>>= ((tmp = 2498246277.2054763, tmp)+(((tmp = 924534435, tmp)&x)>>(tmp = 1379755429, tmp))));
- assertEquals(0, x -= x);
- assertEquals(0, x /= (3093439341));
- assertEquals(0, x *= (x>>>x));
- assertEquals(0, x &= (tmp = 551328367, tmp));
- assertEquals(-0, x /= (-3153411714.834353));
- assertEquals(1217585288, x ^= (tmp = -3077382008.637764, tmp));
- assertEquals(-639702017, x |= ((tmp = -640922633, tmp)%(tmp = -879654762, tmp)));
- assertEquals(-1645297680, x <<= (tmp = 1418982820.8182912, tmp));
- assertEquals(-1.4059558868398736, x /= (1170234212.4674253));
- assertEquals(-2650856935.66554, x *= (1885448157));
- assertEquals(1326259953.26931, x *= (((x>>(x|(-496195134.78045774)))+((2029515886)%(tmp = 1148955580, tmp)))/(tmp = -1760016519, tmp)));
- assertEquals(0, x &= (((((-273334205)+(tmp = 797224093.682485, tmp))/x)>>>((((tmp = -887577414, tmp)/x)+x)%(tmp = 720417467, tmp)))^(((x-(tmp = -309071035, tmp))>>(-3123114729.33889))/x)));
- assertEquals(0, x ^= x);
- assertEquals(0, x %= ((tmp = -2243857462, tmp)/((((((2642220700.6673346)&x)*(tmp = 1454878837, tmp))|((-25825087.30002737)%(851535616.3479034)))<<(tmp = -697581582, tmp))%(tmp = 2248990486, tmp))));
- assertEquals(0, x >>= (((x|(((tmp = -220437911, tmp)&((((255690498)*(((2993252642)>>>(tmp = 300426048.0338713, tmp))>>x))&((-364232989)+(x<<(-1824069275))))%(x+(tmp = 2696406059.026349, tmp))))+((tmp = 2911683270, tmp)/(tmp = 2718991915, tmp))))*(x/(((tmp = -982851060.0744538, tmp)^((-2903383954)<<((-85365803.80553412)^x)))%(1489258330.5730634))))>>>x));
- assertEquals(0.7805921633088815, x += (((-1886920875)/(-2417294156.5304217))%(tmp = -1176793645.8923106, tmp)));
- assertEquals(0, x <<= x);
- assertEquals(-2215008905, x -= (2215008905));
- assertEquals(1931542900, x &= (-215923724.72133207));
- assertEquals(907191462, x ^= (-3133954606.357727));
- assertEquals(453595731, x >>>= (((tmp = 2726241550, tmp)/(tmp = -332682163, tmp))*((((tmp = 2500467531, tmp)>>>(((x<<(tmp = -1847200310.4863105, tmp))/x)^x))+x)<<(191688342.22953415))));
- assertEquals(-0.21671182880645923, x /= ((((-1169180683.1316955)%x)>>>(1650525418))^((2198033206.797462)&((-6913973.910871983)%(1758398541.8440342)))));
- assertEquals(-375102237.1603561, x += (tmp = -375102236.9436443, tmp));
- assertEquals(1, x &= (((84374105.89811504)|((tmp = -2480295008.926951, tmp)>>((605043461)>>(tmp = -2495122811, tmp))))>>(-2129266088)));
- assertEquals(1, x |= x);
- assertEquals(0.0000024171579540208214, x /= (((-2600416098)>>(-2076954196))^x));
- assertEquals(0.0000024171579540208214, x %= (tmp = -2632420148.815531, tmp));
- assertEquals(1809220936.0126908, x -= (-1809220936.0126884));
- assertEquals(1682452118.2686126, x += (((2358977542)<<(x/(tmp = -2862107929, tmp)))+(x+(x%((-3101674407)/(((x*((x>>(tmp = 630458691.3736696, tmp))>>>(tmp = -852137742, tmp)))/x)-((-1875892391.1022017)&(tmp = -1027359748.9533749, tmp))))))));
- assertEquals(1682452118, x <<= (((tmp = -80832958.07816291, tmp)>>x)%(x-((x^(x<<(tmp = -156565345, tmp)))|((tmp = -1208807363.727137, tmp)/(tmp = 2614737513.304538, tmp))))));
- assertEquals(6572078, x >>= (-1573364824));
- assertEquals(13144156, x += x);
- assertEquals(1731678184, x ^= ((tmp = 593370804.9985657, tmp)|(-3124896848.53273)));
- assertEquals(845545, x >>>= (tmp = -605637621.2299933, tmp));
- assertEquals(-1383361088, x ^= (tmp = -1383632087, tmp));
- assertEquals(-82545896480031520, x += ((x+(1023183845.7316296))*((((tmp = 576673669, tmp)>>(((-584800080.1625061)/(2388147521.9174623))+((((x>>>(-905032341.5830328))^(tmp = -2170356357, tmp))-x)+((136459319)+(-1799824119.689473)))))|x)&(tmp = -2688743506.0257063, tmp))));
- assertEquals(-895206176, x |= x);
- assertEquals(-0, x %= x);
- assertEquals(1791306023, x ^= ((tmp = -3219480856, tmp)+(tmp = 715819582.0181161, tmp)));
- assertEquals(1791306023, x &= x);
- assertEquals(2725167636753240600, x *= (1521330025));
- assertEquals(-281190679, x |= (tmp = -1422045975.798171, tmp));
- assertEquals(-281190679, x += (x%x));
- assertEquals(-2342097426.906673, x -= (tmp = 2060906747.906673, tmp));
- assertEquals(-4651462701.906673, x -= (2309365275));
- assertEquals(1878, x >>>= (2544974549.345834));
- assertEquals(1964, x += (x&((1067649861)>>(182139255.7513579))));
- assertEquals(2209, x += (x>>(tmp = -1775039165, tmp)));
- assertEquals(0, x -= x);
- assertEquals(-0, x /= (tmp = -1634697185, tmp));
- assertEquals(NaN, x /= x);
- assertEquals(0, x >>>= ((tmp = 3075747652, tmp)&(tmp = 819236484, tmp)));
- assertEquals(0, x /= ((1276203810.476657)%(-2434960500.784484)));
- assertEquals(0, x >>>= (tmp = -503633649, tmp));
- assertEquals(-982731931, x |= (-982731931));
- assertEquals(-1965463862, x += x);
- assertEquals(-0.221469672913716, x %= ((tmp = -1742292120, tmp)/x));
- assertEquals(-0.221469672913716, x %= (-2021391941.1839576));
- assertEquals(0, x <<= (((((tmp = -2802447851, tmp)>>((2534456072.6518855)&x))%(tmp = 2841162496.610816, tmp))<<((89341820)/(2565367990.0552235)))>>(tmp = 2700250984.4830647, tmp)));
- assertEquals(0, x >>= x);
- assertEquals(0, x >>= ((tmp = -636189745, tmp)>>>(x/(((tmp = 2634252476, tmp)%(2026595795))>>(tmp = -2048078394.743723, tmp)))));
- assertEquals(NaN, x %= ((x%((((x%((tmp = -2583207106, tmp)&x))|(190357769))<<(tmp = 595856931.2599536, tmp))%x))*((-2433186614.6715775)<<((2856869562.1088696)^(tmp = 1112328003, tmp)))));
- assertEquals(1621713910, x |= (tmp = 1621713910.0282416, tmp));
- assertEquals(3243427820, x += x);
- assertEquals(0, x *= (x&(x-x)));
- assertEquals(0, x >>>= (((2871235439)<<((x+((tmp = -1319445828.9659343, tmp)+(tmp = 1595655077.959171, tmp)))>>(tmp = -86333903, tmp)))-(x/(2907174373.268768))));
- assertEquals(0, x >>= (-1091774077.2173789));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x *= (tmp = 1976023677.7015994, tmp));
- assertEquals(NaN, x -= (-3013707698));
- assertEquals(NaN, x += ((x+(((tmp = -3119865782.9691515, tmp)<<(1327383504.0158405))^(((-143382411.7239611)>>>((-2157016781)+(((-335815848)/x)<<(tmp = 1953515427, tmp))))&(-2715729178))))/(413738158.2334299)));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x += (-845480493));
- assertEquals(-789816013, x |= (tmp = -789816013.129916, tmp));
- assertEquals(0, x ^= x);
- assertEquals(0, x <<= (3032573320));
- assertEquals(47630, x ^= ((1086705488)%((x^(tmp = -1610832418, tmp))>>>(tmp = 1136352558, tmp))));
- assertEquals(47630, x >>= (tmp = 1035320352.4269229, tmp));
- assertEquals(47630, x >>= ((((x^x)<<(x*((((x&((-1657468419)*((tmp = -674435523, tmp)&((tmp = 2992300334, tmp)|x))))*((tmp = -489509378.31950426, tmp)*(tmp = 2276316053, tmp)))>>>x)<<x)))%(tmp = -1209988989, tmp))/(tmp = -2080515253.3541622, tmp)));
- assertEquals(3192518951.8129544, x += (3192471321.8129544));
- assertEquals(648116457.8129544, x %= (-2544402494));
- assertEquals(0, x -= x);
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x /= x);
- assertEquals(0, x <<= x);
- assertEquals(0, x >>= x);
- assertEquals(0, x *= (tmp = 30051865, tmp));
- assertEquals(0, x ^= ((x&(((x&x)>>>(((((((x+(2319551861.0414495))>>>(tmp = -3099624461, tmp))^((((tmp = 1574312763, tmp)|x)>>>((-2723797246)&(tmp = -1993956152, tmp)))|(-1830179045)))|(((((((-2545698704.3662167)>>>x)-(((-79478653)|x)%(x+(x>>((tmp = 2386405508.2180576, tmp)/x)))))>>((((-1947911815.2808042)*((x+(368522081.2884482))-(tmp = 2452991210, tmp)))>>(343556643.1123545))>>((((tmp = 1869261547.537739, tmp)>>(3193214755))|x)&(x*(2027025120)))))<<((-1149196187)>>>(814378291.8374172)))+((((((((-160721403)/(2079201480.2186408))+((x|((((tmp = -299595483.16805863, tmp)>>>((x|((x+x)/(-2359032023.9366207)))<<(tmp = -3095108545, tmp)))>>((tmp = -1547963617.9087071, tmp)*(x>>x)))&((tmp = -1568186648.7499216, tmp)+(((2646528453)^(-2004832723.0506048))>>>(tmp = -3188715603.921877, tmp)))))+(tmp = 1578824724, tmp)))^x)^x)/(tmp = -985331362, tmp))|(tmp = 445135036, tmp))<<(tmp = -73386074.43413758, tmp)))+(((-1674995105.9837937)-(tmp = 1392915573, tmp))>>x)))%(tmp = 1215953864, tmp))&((tmp = -439264643.5238693, tmp)>>>x))+(((tmp = 2311895902, tmp)|(1604405793.6399229))&(tmp = -565192829, tmp))))-x))>>(-2455985321)));
- assertEquals(0, x %= ((1177798817)>>(tmp = 2081394163.5420477, tmp)));
- assertEquals(0, x >>>= ((x^(tmp = -41947528.33954811, tmp))>>(x>>>((tmp = 1367644771, tmp)+x))));
- assertEquals(0, x %= ((x+((tmp = 163275724, tmp)<<((tmp = -514460883.3040788, tmp)+x)))|(tmp = -287112073.2482593, tmp)));
- assertEquals(0, x &= (3067975906));
- assertEquals(201342051, x |= (tmp = 201342051, tmp));
- assertEquals(0, x %= (((((-2580351108.8990865)<<(tmp = 2675329316, tmp))&((1338398946)%((-1548041558)+((x>>(-1568233868.7366815))|((x>>((tmp = -1064582207, tmp)/(-1062237014)))>>(tmp = 854123209, tmp))))))<<(((989032887)*(1842748656))%(tmp = -1566983130, tmp)))-x));
- assertEquals(-0, x /= (tmp = -828519512.617768, tmp));
- assertEquals(0, x &= ((((1449608518)+(-1829731972))*(1828894311))*(((tmp = -1121326205.614264, tmp)^(-2057547855))<<(tmp = -2758835896, tmp))));
- assertEquals(NaN, x %= ((tmp = -2138671333, tmp)%x));
- assertEquals(0, x &= x);
- assertEquals(665568613.0328879, x += (665568613.0328879));
- assertEquals(317, x >>= (2627267349.735873));
- assertEquals(0, x -= x);
- assertEquals(0, x &= (((tmp = 3030611035, tmp)*(((tmp = 476143340.933007, tmp)>>(x-(2238302130.2331467)))|(x|x)))%(tmp = 320526262, tmp)));
- assertEquals(0, x <<= (tmp = 729401206, tmp));
- assertEquals(0, x >>>= (1721412276));
- assertEquals(217629949.3530736, x += ((tmp = 217629949.3530736, tmp)%((-931931100.601475)%(x^(tmp = -2149340123.548764, tmp)))));
- assertEquals(217629949.3530736, x %= (tmp = 2275384959.4243402, tmp));
- assertEquals(0, x >>>= (1112677437.5524077));
- assertEquals(0, x *= (500256656.7476063));
- assertEquals(0, x >>>= x);
- assertEquals(0, x -= x);
- assertEquals(0, x -= x);
- assertEquals(0, x &= (-1076968794));
- assertEquals(0, x /= (tmp = 1774420931.0082943, tmp));
- assertEquals(0, x |= x);
- assertEquals(0, x >>= x);
- assertEquals(0, x %= (-2978890122.943079));
- assertEquals(-0, x /= (tmp = -2954608787, tmp));
- assertEquals(-800048201, x ^= ((tmp = -800048201.7227018, tmp)>>>((-2016227566.1480863)/(tmp = -2263395521, tmp))));
- assertEquals(3333, x >>>= (-2038839052));
- assertEquals(487957736.625432, x += (487954403.625432));
- assertEquals(-1650983426, x |= (2643918270));
- assertEquals(-1861867448, x &= (tmp = -251254199.12813115, tmp));
- assertEquals(-7.934314690172143e-18, x %= ((((x^(-703896560.6519544))>>(tmp = -1853262409, tmp))/(tmp = -1168012152.177894, tmp))/(tmp = 837616075.1097361, tmp)));
- assertEquals(0, x ^= x);
- assertEquals(0, x &= (tmp = -2328150260.5399947, tmp));
- assertEquals(-1954860020, x |= (tmp = 2340107276, tmp));
- assertEquals(-1954860020, x >>= ((tmp = 159177341, tmp)*(x&(-705832619))));
- assertEquals(-1954895727, x -= (x>>>((-1443742544.7183702)^((((tmp = 869581714.0137681, tmp)+x)^((x%(tmp = -1036566362.5189383, tmp))^(x%x)))>>x))));
- assertEquals(1.0241361338078498, x /= (tmp = -1908824093.2692068, tmp));
- assertEquals(16777216, x <<= (x*(((-1925197281)^(tmp = -1392300089.4750946, tmp))|x)));
- assertEquals(-225882765524992, x *= (tmp = -13463662, tmp));
- assertEquals(-1845493760, x |= x);
- assertEquals(-1845493760, x %= (tmp = 3181618519.786825, tmp));
- assertEquals(0, x ^= x);
- assertEquals(0, x <<= x);
- assertEquals(0, x >>>= x);
- assertEquals(NaN, x /= (x>>>x));
- assertEquals(NaN, x %= (((((tmp = -521176477, tmp)>>(((tmp = 370693623, tmp)/(((tmp = -1181033022.4136918, tmp)>>(x|(x*(2601660441))))+(tmp = -1696992780, tmp)))|(x|(-1197454193.198036))))>>>(((2512453418.3855605)+((((((tmp = 799501914, tmp)&(((1788580469.7069902)*(((((1476778529.5109258)<<(tmp = -1873387738.3541565, tmp))-((tmp = -521988584.7945764, tmp)*(-1598785351.3914914)))&(-1899161721.8061454))&((x/x)*(690506460))))>>>((tmp = 2255896398.840741, tmp)>>((tmp = -1331486014.6180065, tmp)+(-1159698058.534132)))))*((1112115365.2633948)&((x>>((x>>(-784426389.4693215))&(-492064338.97227573)))>>x)))^((x-((tmp = 2986028023, tmp)>>(tmp = 2347380320.00517, tmp)))*(tmp = -1463851121, tmp)))*(tmp = -1059437133, tmp))%(x-(tmp = 1238739493.7636225, tmp))))^(2029235174)))*(-1923899530))>>>x));
- assertEquals(0, x >>>= (2848792983.510682));
- assertEquals(0, x >>= (((tmp = 3042817032.705198, tmp)>>>x)&((((tmp = -829389221, tmp)-((2669682285.8576303)+(tmp = 1812236814.3082042, tmp)))^x)%((tmp = -2401726554, tmp)^((tmp = 2464685683, tmp)|(-2685039620.224061))))));
- assertEquals(2069649722, x |= (2069649722.311271));
- assertEquals(NaN, x %= (((((-68757739.39282179)&(-1382816369))/(3122326124))<<(x-(-507995800.3369653)))<<(((-1962768567.343907)+((tmp = 1357057125, tmp)/x))^(tmp = 1997617124, tmp))));
- assertEquals(NaN, x += x);
- assertEquals(0, x >>= (26895919));
- assertEquals(0, x >>>= x);
- assertEquals(0, x %= (tmp = 1092448030, tmp));
- assertEquals(0, x <<= (tmp = -477672441.46258235, tmp));
- assertEquals(0, x /= (2113701907));
- assertEquals(0, x >>>= x);
- assertEquals(NaN, x /= x);
- assertEquals(1341078673, x |= (-2953888623));
- assertEquals(1341078673, x &= x);
- assertEquals(0, x %= x);
- assertEquals(414817852.151006, x -= (-414817852.151006));
- assertEquals(1006632960, x <<= ((((((126465614.8316778)+(x-(2511803375)))+(tmp = 1620717148.352402, tmp))*x)/(tmp = -3013745105.5275207, tmp))-((tmp = -418034061.6865432, tmp)/(-300492911))));
- assertEquals(1055624813, x |= (tmp = 921407085, tmp));
- assertEquals(-3, x |= ((((tmp = 1382397819.7507677, tmp)+(tmp = -111851147.7289567, tmp))+x)/((tmp = 247980405.7238742, tmp)^(tmp = -592156399.8577058, tmp))));
- assertEquals(35161, x &= (((((((-2973570544.725141)*(tmp = -1244715638, tmp))+x)<<(x/((x>>>(-2143371615.073137))/(226072236))))%((x-(tmp = 1971392936, tmp))^(tmp = 2653103658, tmp)))%((tmp = 2828319571.7066674, tmp)>>((1528970502)^((tmp = -55869558, tmp)%x))))>>(889380585.6738582)));
- assertEquals(0, x ^= x);
- assertEquals(0, x *= (2749718750));
- assertEquals(0, x >>>= ((((-1633495402.6252813)*(tmp = 2943656739.1108646, tmp))+(tmp = 977432165, tmp))&((tmp = -2338132019, tmp)*(408176349.8061733))));
- assertEquals(-1778794752, x -= (((tmp = -1391412154.5199084, tmp)-((-3172342474)|x))&(1854366052)));
- assertEquals(-1778794752, x %= (tmp = 2024807296.6901965, tmp));
- assertEquals(-1114410.466337204, x %= ((tmp = -240344444.24487805, tmp)%(-47661164)));
- assertEquals(-0, x %= x);
- assertEquals(0, x >>= (x>>x));
- assertEquals(0, x *= x);
- assertEquals(0, x /= ((-3134902611)|(tmp = -3131158951, tmp)));
- assertEquals(-0, x /= (((tmp = 1430247610.634234, tmp)&x)+((tmp = -2047191110.8623483, tmp)-((((x%((((x/(tmp = -2599234213, tmp))|(tmp = 2650380060, tmp))|x)+x))>>>x)&(-1961373866))<<x))));
- assertEquals(-718394682, x -= ((x|(tmp = 1764417670.8577194, tmp))%(1046022988)));
- assertEquals(3576572614, x >>>= (((tmp = 2480472883.078992, tmp)<<x)>>((2035208402.8039393)&(tmp = 492980449, tmp))));
- assertEquals(434034142, x %= (x&((x>>>(311110449.48751545))|(-243530647))));
- assertEquals(524703439.3065736, x += (((tmp = 1392771723.3065736, tmp)%(x&x))%(tmp = -2199704930, tmp)));
- assertEquals(373686272, x &= (x<<((tmp = 2103372351.9456532, tmp)%(tmp = -1367109519, tmp))));
- assertEquals(373686272, x >>= x);
- assertEquals(-0.12245430020241108, x /= (tmp = -3051638622.5907507, tmp));
- assertEquals(1, x /= x);
- assertEquals(1, x %= (3095983855));
- assertEquals(-1454736871, x ^= (x*(tmp = -1454736872, tmp)));
- assertEquals(-1454736866, x ^= (((724989405.7338341)|(tmp = -2834298786.384371, tmp))>>>(tmp = -2029602148.1758833, tmp)));
- assertEquals(-1454736866, x &= x);
- assertEquals(-197394432, x <<= (tmp = -1562128975, tmp));
- assertEquals(251658240, x <<= (tmp = 2126510950, tmp));
- assertEquals(3295700610.703306, x -= (tmp = -3044042370.703306, tmp));
- assertEquals(-51152917, x |= ((949179883.1784958)|(((tmp = -2046168220, tmp)>>(x/x))/(((835064313)*(tmp = 2197600689, tmp))^(((tmp = 2717104216, tmp)&x)<<(-1402661995.3845913))))));
- assertEquals(-1549204421, x ^= ((((tmp = -481013711, tmp)>>>((tmp = 119589341.80209589, tmp)%(-995489985.2905662)))-(635717011))^(x+(x*x))));
- assertEquals(-1078356672.3999934, x += (470847748.6000067));
- assertEquals(1484987268.4638166, x += (tmp = 2563343940.86381, tmp));
- assertEquals(277020804, x &= (tmp = 2532819117, tmp));
- assertEquals(-2097118208, x <<= (x>>>x));
- assertEquals(-2147483648, x <<= (tmp = 761285045, tmp));
- assertEquals(2147483648, x >>>= x);
- assertEquals(-935909870282997800, x *= ((-2583300643)|x));
- assertEquals(-370753566.54721737, x %= (-1084543510.4524941));
- assertEquals(-177, x >>= (-946264747.6588805));
- assertEquals(-416077682, x ^= (tmp = 416077761, tmp));
- assertEquals(NaN, x %= ((((tmp = 779607408, tmp)*(((tmp = -3007128117, tmp)*(851442866.6153773))+x))&(1283388806))/(-876363553)));
- assertEquals(NaN, x %= (x/(tmp = -1668413939.652408, tmp)));
- assertEquals(-1726405921, x ^= (tmp = -1726405921, tmp));
- assertEquals(-1, x >>= ((3031008213.807012)>>x));
- assertEquals(4294967295, x >>>= ((x>>>x)&(tmp = 2788082290, tmp)));
- assertEquals(8544111670008449000, x *= (tmp = 1989331020.0417833, tmp));
- assertEquals(268435456, x <<= (tmp = 3121736017.2098465, tmp));
- assertEquals(-2.1011176170964474e+26, x -= (((tmp = 1392503299, tmp)*(tmp = 1446108825.1572113, tmp))*(x^(tmp = 372776014.213725, tmp))));
- assertEquals(0, x |= x);
- assertEquals(0, x >>= ((-112413907.70074797)*(-702798603)));
- assertEquals(1829518838, x |= (tmp = -2465448458, tmp));
- assertEquals(57172463, x >>= ((tmp = 2979642955.241792, tmp)%(tmp = -2464398693.291434, tmp)));
- assertEquals(114344926, x += x);
- assertEquals(113279134, x &= (2397742238.6877637));
- assertEquals(54, x >>= (1908522709.6377516));
- assertEquals(-2.966982919573829e-7, x /= (tmp = -182003070, tmp));
- assertEquals(0, x <<= (-1078417156));
- assertEquals(-147831390, x ^= (((-147831390)>>>x)+x));
- assertEquals(0, x -= x);
- assertEquals(-242221450.44696307, x -= (tmp = 242221450.44696307, tmp));
- assertEquals(-484442900, x <<= (((tmp = -2033947265.088614, tmp)&x)/(x^(tmp = -2893953848, tmp))));
- assertEquals(-3227648, x <<= (x<<((tmp = -193993010, tmp)*((983187830)|(3146465242.2783365)))));
- assertEquals(-6455296, x += x);
- assertEquals(-1771542585, x -= (x^(tmp = -1767335879, tmp)));
- assertEquals(-0, x %= x);
- assertEquals(0, x >>>= ((((tmp = -1612864670.4532743, tmp)*(tmp = 786265765.210487, tmp))*((((tmp = -893735877.3250401, tmp)*((x^(tmp = -2804782464.233885, tmp))<<x))&(x-x))^x))<<x));
- assertEquals(0, x -= (x>>>(-1648118674.380736)));
- assertEquals(0, x >>= ((tmp = -2706058813.0028524, tmp)>>(2745047169)));
- assertEquals(0, x += x);
- assertEquals(0, x %= (-898267735.137356));
- assertEquals(0, x >>>= x);
- assertEquals(0, x >>= ((265527509)/((tmp = 2190845136.7048635, tmp)+((x>>x)>>>((x%(x-x))&((((-2080184609.8989801)&((-327231633)>>>((tmp = 864849136, tmp)%(((-524363239)*(((((tmp = 2245852565.3713694, tmp)&(1918365.8978698254))>>>(tmp = -2463081769, tmp))-(((2438244059.471446)|((((-135303645.38470244)*(-861663832.2253196))%(tmp = 1273185196.0261836, tmp))|((2261539338.832875)%((320267076.2363237)+x))))>>(tmp = -2731398821, tmp)))/(tmp = -1947938611, tmp)))^x))))>>(tmp = 833666235, tmp))|x))))));
- assertEquals(-1116704570, x ^= (-1116704570));
- assertEquals(1379561710, x ^= (tmp = -280362968.19654894, tmp));
- assertEquals(-1673822208, x <<= x);
- assertEquals(-1673822208, x |= (x<<(tmp = 1389479193.9038138, tmp)));
- assertEquals(2559712, x >>>= (-2703763734.0354066));
- assertEquals(2593499, x ^= (x>>>((tmp = 148668150.03291285, tmp)^(tmp = -1580360304, tmp))));
- assertEquals(2070393855, x |= (tmp = -2227002907, tmp));
- assertEquals(304197770, x &= (tmp = 2453257354, tmp));
- assertEquals(304197770, x <<= ((-669331453.8814087)-(x^(x^(tmp = 33804899.98928583, tmp)))));
- assertEquals(297068, x >>= x);
- assertEquals(Infinity, x /= (x-x));
- assertEquals(NaN, x %= x);
- assertEquals(0, x ^= x);
- assertEquals(0, x %= ((tmp = 1723087085, tmp)%(2859382131.304421)));
- assertEquals(0, x %= (((tmp = 2935439763, tmp)<<(-3163992768.637094))%(tmp = 67176733, tmp)));
- assertEquals(0, x &= (tmp = 2480771277, tmp));
- assertEquals(0, x >>>= (x+(tmp = -3168690063, tmp)));
- assertEquals(0, x *= ((tmp = -1915275449.1806245, tmp)>>>((tmp = -1644482094.1822858, tmp)/(tmp = -432927173, tmp))));
- assertEquals(0, x += (((2766509428.071809)/(x/((942453848.5423365)/(((tmp = -1284574492, tmp)&((tmp = 760186450.7301528, tmp)-(2464974117.358138)))/((x/(x|(672536969)))*(x>>(-1272232579)))))))>>(x*(-3175565978))));
- assertEquals(-1277710521, x -= (1277710521));
- assertEquals(-1277710521, x >>= (((tmp = -2349135858, tmp)-x)-x));
- assertEquals(-1277710521, x >>= ((tmp = 2135645051, tmp)*(tmp = -2468555366, tmp)));
- assertEquals(-155971, x >>= (-1294859507));
- assertEquals(-0, x %= x);
- assertEquals(0, x >>>= (((861078292.6597499)|(-268063679))-(((((-221864206.9494424)-(-3186868203.2201176))&(tmp = 1287132927, tmp))<<(((tmp = 1964887915, tmp)<<((25908382)^(tmp = -688293519.875164, tmp)))*(2075946055)))&(x-((x>>x)&(1395338223.7954774))))));
- assertEquals(788002218, x -= (-788002218));
- assertEquals(716399906, x &= (-1145868506));
- assertEquals(145776674, x &= (-1661931477.360386));
- assertEquals(145776674, x |= x);
- assertEquals(-0.05255700469257692, x /= (tmp = -2773686873, tmp));
- assertEquals(-660918434, x |= (-660918434.2915542));
- assertEquals(1223537346, x ^= (tmp = -1871274596, tmp));
- assertEquals(305884336, x >>= (x&x));
- assertEquals(-1.1123775647978218e-8, x *= ((tmp = -793393031.4229445, tmp)/((tmp = -503919284, tmp)*(((((tmp = 429810625, tmp)>>>x)-((2091544148.870375)<<(((((x^x)%x)|x)/(-260773261))<<((tmp = -1323834653, tmp)&x))))*((-1231800099.3724015)+x))*((x+((-559726167)^x))>>>((-549148877)<<((((tmp = 1196115201, tmp)/((tmp = -2654658968.390111, tmp)%(tmp = -1044419580, tmp)))*(((((x>>>(733571228))+(2919762692.511447))/(-2718451983.570547))^x)+((2891533060.1804514)^((tmp = -2514488663, tmp)&x))))<<(tmp = -2526139641.6733007, tmp))))))));
- assertEquals(0, x >>>= x);
- assertEquals(0, x *= x);
- assertEquals(0, x |= x);
- assertEquals(3076984066.336236, x -= ((tmp = -3076984066.336236, tmp)+((tmp = -446575828.5155368, tmp)&x)));
- assertEquals(1, x /= x);
- assertEquals(1513281647.839972, x *= (1513281647.839972));
- assertEquals(1251138155, x ^= ((tmp = 2124481052, tmp)&(2431937351.4392214)));
- assertEquals(1, x /= x);
- assertEquals(0, x &= (tmp = 627050040, tmp));
- assertEquals(497153016, x ^= (497153016));
- assertEquals(-1112801283, x |= (tmp = 2752196557, tmp));
- assertEquals(0.5735447276296568, x /= ((((tmp = -500878794, tmp)%(tmp = -2559962372.2930336, tmp))%(2661010102))+(tmp = -1439338297, tmp)));
- assertEquals(1.0244795995097235e-9, x /= (559840067));
- assertEquals(0.43468811912309857, x *= (424301391));
- assertEquals(-1972757928, x ^= (tmp = -1972757928.9227014, tmp));
- assertEquals(-606757265, x ^= (tmp = -2923461577.264596, tmp));
- assertEquals(-37, x >>= (((-2736561559.7474318)%(tmp = -27668972.662741184, tmp))*(2774711606)));
- assertEquals(-1923785671, x += ((-1923785597)+x));
- assertEquals(-3877639176, x += (tmp = -1953853505, tmp));
- assertEquals(-4688259242, x -= ((810620066.4394455)>>(((-1474285107.459875)>>x)/(((((-570672326.4007359)>>(tmp = -3086802075, tmp))%x)>>>(((tmp = 286938819.28193486, tmp)>>>((1712478502)>>(tmp = 3045149117.796816, tmp)))<<(tmp = 750463263.292952, tmp)))&(tmp = 2055350255.5669963, tmp)))));
- assertEquals(-0, x %= x);
- assertEquals(0, x <<= (1037856162.5105649));
- assertEquals(0, x *= x);
- assertEquals(0, x &= (997845077.4917375));
- assertEquals(0, x *= x);
- assertEquals(0, x *= x);
- assertEquals(0, x <<= (((x<<x)&(57691805))>>(786927663)));
- assertEquals(0, x ^= x);
- assertEquals(0, x += x);
- assertEquals(0, x &= (-2131910624.1429484));
- assertEquals(0, x >>>= (-43787814));
- assertEquals(-2415062021, x += (tmp = -2415062021, tmp));
- assertEquals(-4830124042, x += x);
- assertEquals(-186683401, x |= (tmp = 1960135383, tmp));
- assertEquals(NaN, x *= ((tmp = -1674740173.9864025, tmp)%(((((((-432895485.7261934)-x)^x)>>>(((-1627743078.3383338)>>(179992151))<<((tmp = 911484278.0555259, tmp)|(((tmp = -3042492703, tmp)>>(((-663866035.302746)>>(((x-((440661929.50030375)>>>(tmp = 263692082, tmp)))*x)+x))/((1546004407)^(((tmp = 2023662889.1594632, tmp)*(tmp = -2456602312, tmp))+(tmp = 755602286.1810379, tmp)))))%((tmp = -336449961, tmp)|(tmp = 206780145, tmp))))))/(1068005219.1508512))<<(tmp = -474008862.6864624, tmp))/(((((((1518711056.5437899)>>>(tmp = 287418286.63085747, tmp))<<(tmp = 2823048707, tmp))^(((x<<(x^(-1600970311)))&(x>>(((tmp = 157300110.7636031, tmp)*(tmp = -3047000529, tmp))&(1743024951.3535223))))>>x))-(tmp = -2895435807, tmp))*((tmp = -314120704, tmp)&(tmp = 1759205369, tmp)))>>(tmp = 1833555960.046526, tmp)))));
- assertEquals(NaN, x -= (tmp = 694955369, tmp));
- assertEquals(NaN, x *= (x%x));
- assertEquals(0, x |= x);
- assertEquals(0, x ^= x);
- assertEquals(0, x &= x);
- assertEquals(NaN, x /= (x+x));
- assertEquals(NaN, x %= ((tmp = -1595988845, tmp)*((1754043345)>>>(-601631332))));
- assertEquals(0, x >>>= (tmp = 862768754.5445609, tmp));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x *= (tmp = -1774545519, tmp));
- assertEquals(0, x >>>= (tmp = -2492937784, tmp));
- assertEquals(0, x %= ((((x<<(-1657262788.2028513))&((x^(tmp = -671811451, tmp))<<(-2984124996)))^(1455422699.7504625))-((-340550620)>>x)));
- assertEquals(918278025, x ^= ((tmp = -918278027, tmp)^((tmp = 2889422870, tmp)/(tmp = -657306935.7725658, tmp))));
- assertEquals(918278025, x %= (2603186571.0582614));
- assertEquals(107034679.32509923, x %= (tmp = -811243345.6749008, tmp));
- assertEquals(53517339, x >>= (x%((((x*((tmp = -983766424, tmp)^(-1881545357.8686862)))|(tmp = -1429937087, tmp))>>((x<<x)>>((((tmp = -2347470476, tmp)&x)+((x&x)<<(396061331.6476157)))*(tmp = -3136296453.209073, tmp))))>>>(((tmp = 908427836, tmp)|(tmp = 207737064, tmp))|(((1253036041)-(tmp = 2705074182, tmp))+(-431215157.82083917))))));
- assertEquals(53477378, x &= ((((-1128036654.165636)*x)+x)>>(x>>(3080099059))));
- assertEquals(0, x >>= (-590692293));
- assertEquals(0, x %= (-2395850570.9700127));
- assertEquals(0, x *= ((tmp = 1377485272, tmp)&(1129370608)));
- assertEquals(0, x += (x>>>(x%(((((tmp = -1746827236, tmp)+((tmp = -326913490, tmp)&((-58256967)&x)))*(tmp = -1176487022.001651, tmp))>>>(-2089147643))-x))));
- assertEquals(0, x <<= (tmp = 1073298160.2914447, tmp));
- assertEquals(-837811832, x ^= (-837811832));
- assertEquals(102760448, x <<= (tmp = 2833582450.4544373, tmp));
- assertEquals(0, x &= (((((((tmp = 2595641175, tmp)*x)+(tmp = -2049260172.1025927, tmp))%((2986747823)>>(tmp = -2120598518, tmp)))&((tmp = -2742408622, tmp)&x))>>x)*((1043474247.9601482)&(tmp = 1686365779.9885998, tmp))));
- assertEquals(0, x >>= ((tmp = 1717862848, tmp)-(tmp = 1077024446.4160957, tmp)));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x /= (-1669429787.975099));
- assertEquals(NaN, x -= (-2299895633.4807186));
- assertEquals(138173970, x ^= (138173970.56627905));
- assertEquals(-2084183776, x <<= (3073345316));
- assertEquals(-0, x %= x);
- assertEquals(0, x >>= (-3080556066.068573));
- assertEquals(0, x &= ((tmp = -2587514820, tmp)*(x-((x^(1995672257))*(1125326747.2339358)))));
- assertEquals(NaN, x %= x);
- assertEquals(0, x >>= (tmp = 2139186585, tmp));
- assertEquals(-1904096640, x |= ((-602301360.1919911)*(-1270444810)));
- assertEquals(1073741824, x <<= (tmp = -1069467849, tmp));
- assertEquals(1073741824, x ^= (x-x));
- assertEquals(536870912, x >>>= (-1579466367.160293));
- assertEquals(512, x >>= (972402804.3890183));
- assertEquals(512, x &= (tmp = 2664796831, tmp));
- assertEquals(16777216, x <<= (-2738292561));
- assertEquals(0, x >>>= ((((1397663615.3889246)|(1117420260.6730964))-(-1173734560))<<((tmp = 1007006104.0172879, tmp)<<((tmp = -623002097, tmp)%(tmp = -35829654.379403114, tmp)))));
- assertEquals(1200191544, x ^= (tmp = -3094775752, tmp));
- assertEquals(71, x >>>= x);
- assertEquals(71, x |= x);
- assertEquals(1394763772, x += (1394763701));
- assertEquals(-1.492717171027427, x /= ((x&(tmp = 1243787435, tmp))-(2043911970.26752)));
- assertEquals(-1.1002448961224718e-8, x /= ((((835185744)*(((tmp = 2165818437, tmp)^(tmp = 2567417009.1166553, tmp))/x))/x)/(((63485842.39971793)^(2668248282.597389))/x)));
- assertEquals(0, x <<= (tmp = 1598238578.637568, tmp));
- assertEquals(0, x |= (x&((tmp = -1812945547.5373957, tmp)>>>x)));
- assertEquals(0, x >>>= (x+(-1969679729.7299538)));
- assertEquals(1582033662, x += (tmp = 1582033662, tmp));
- assertEquals(1, x >>>= x);
- assertEquals(-550748739, x += ((tmp = -550748740, tmp)/(x&((2537822642.235506)^((-2167656297)%(tmp = 1161201210, tmp))))));
- assertEquals(-268921, x >>= (tmp = 1916069547.7381654, tmp));
- assertEquals(-0.00021776939364231114, x /= (tmp = 1234888868, tmp));
- assertEquals(0, x <<= (-1036375023));
- assertEquals(0, x &= ((((x/(2398886792.27443))&(x|((-1813057854.1797302)-x)))&(x/(((tmp = 3091133731.4967556, tmp)|(3013139691.823039))<<x)))>>>(2542784636.963599)));
- assertEquals(0, x += ((x*x)/(tmp = 347079383, tmp)));
- assertEquals(788347904, x |= ((1462257124.6374629)*((3180592147.4065146)-(x&(1922244678)))));
- assertEquals(2130672735, x |= (tmp = -2846986145, tmp));
- assertEquals(-1331327970, x ^= ((656251304)-(tmp = 1489152359, tmp)));
- assertEquals(-0.14377179742889856, x %= (((2889747597.813753)-(1730428996))/(((tmp = -1378710998, tmp)&x)|x)));
- assertEquals(-1754612583.143772, x += ((-1754725729)^((-2285838408)>>>(1434074349))));
- assertEquals(-0, x %= x);
- assertEquals(0, x &= (tmp = -1031961332, tmp));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x /= (3059476325));
- assertEquals(NaN, x *= ((x*((((tmp = 13529540.462185979, tmp)&x)^((x<<(-1312696238.1628869))&(-2029766712.3852897)))>>x))/x));
- assertEquals(1657339940, x ^= ((tmp = -488956817.1491232, tmp)&(tmp = -2352413900.1983714, tmp)));
- assertEquals(-530683621952432200, x *= (tmp = -320202035.2882054, tmp));
- assertEquals(229226258, x ^= ((tmp = -1263410990.026416, tmp)+(((-808046349)&(tmp = -1294442506, tmp))&((tmp = 1147437219, tmp)<<((tmp = -820299900, tmp)-(tmp = -1947748943.3443851, tmp))))));
- assertEquals(7163320, x >>= (-2631307131));
- assertEquals(-68, x |= (((-1271721343)>>x)%x));
- assertEquals(-39956523818.38862, x *= (587595938.505715));
- assertEquals(0, x -= x);
- assertEquals(0, x >>>= ((x^(x+x))<<(tmp = 265212367, tmp)));
- assertEquals(0, x |= (((x>>((tmp = 2294761023, tmp)/(x>>(2125624288))))&((-2125650113)|(tmp = 1014409884, tmp)))%(tmp = -527324757, tmp)));
- assertEquals(0, x >>= ((tmp = 2267075595, tmp)*(-1681569641.8304193)));
- assertEquals(0, x >>>= x);
- assertEquals(0.5738410949707031, x -= ((tmp = -1846572645.573841, tmp)%((((((x^(((-156613905.64173532)/x)<<x))+((x|((2405109060)>>>x))^x))/(570585894.8542807))+(x&(-2544708558)))^((((tmp = -2539082152.490635, tmp)+((((-657138283)/(2204743293))-((tmp = -1422552246.565012, tmp)+x))<<(x-x)))>>(x/(x>>>(tmp = -3027022305.484394, tmp))))<<x))&((-2066650303.3258202)/(tmp = -1666842593.0050385, tmp)))));
- assertEquals(0, x >>>= ((((tmp = 2473451837.613817, tmp)>>((2526373359.1434193)>>(x<<x)))+((tmp = -579162065, tmp)+((tmp = -3115798169.551487, tmp)-(tmp = 933004398.9618305, tmp))))&(tmp = 131167062, tmp)));
- assertEquals(-2067675316, x ^= (-2067675316.6300585));
- assertEquals(543772, x >>>= x);
- assertEquals(-1073741824, x <<= x);
- assertEquals(3221225472, x >>>= ((x*(1478586441.081221))&(tmp = -3050416829.2279186, tmp)));
- assertEquals(0, x ^= x);
- assertEquals(0, x *= x);
- assertEquals(-1017771903.0298333, x -= (1017771903.0298333));
- assertEquals(0.6404112721149928, x /= ((tmp = -144667370, tmp)^(-2849599562)));
- assertEquals(-2410517638773644000, x -= (((tmp = 1759631550, tmp)*x)*((((tmp = -2949481475, tmp)>>>x)*x)|(tmp = -2977983804, tmp))));
- assertEquals(-0, x %= (x+((((tmp = -1307866327.7569134, tmp)<<((x&((tmp = -2380043169.8405933, tmp)|x))>>(472992789.7639668)))|(((((x<<(tmp = -1416427232.7298179, tmp))%(-1404989679.409946))*((x/(tmp = -992416608, tmp))/(tmp = 524646495, tmp)))-(tmp = 734405570, tmp))>>x))/(1079256317.7325506))));
- assertEquals(0, x <<= (tmp = 2459834668, tmp));
- assertEquals(-0, x /= (tmp = -1892164840.5719755, tmp));
- assertEquals(0, x >>= (x|(((1299844244)>>>(((tmp = -2422924469.9824634, tmp)|x)-((((1914590293.2194016)+(-3033885853.8243046))-((tmp = -1720088308, tmp)%x))<<(tmp = 2210817619, tmp))))<<x)));
- assertEquals(0, x <<= (((tmp = 3192483902.841396, tmp)>>>(((x^(2944537154))|(tmp = -1334426566, tmp))*(((((((-2705218389)&x)+(1987320749))+(tmp = -111851605, tmp))|(2894234323))-(265580345))&x)))%(((tmp = 1431928204.6987057, tmp)&(tmp = 914901046, tmp))&(x>>>x))));
- assertEquals(0, x >>>= (tmp = 1941940941, tmp));
- assertEquals(0, x %= (3089014384));
- assertEquals(0, x += ((tmp = 2948646615, tmp)*x));
- assertEquals(-0, x /= (tmp = -1480146895, tmp));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x %= (-2995257724.158043));
- assertEquals(NaN, x %= (tmp = 2714835455, tmp));
- assertEquals(NaN, x /= (tmp = -311440765.98078775, tmp));
- assertEquals(NaN, x -= (-1600234513.697098));
- assertEquals(0, x <<= x);
- assertEquals(0, x <<= (-1499045929));
- assertEquals(-0, x *= (-2491783113));
- assertEquals(0, x ^= (x%((x>>(((1234398704.3681123)>>>x)%(x+x)))>>(402257223.4673699))));
- assertEquals(-643225204, x ^= (((-55960194.698637486)+((((721411198)-(((tmp = 1308676208.7953796, tmp)%(2242904895))-x))>>((((tmp = 332791012, tmp)&((tmp = -2094787948, tmp)/((x/(2427791092))^(2444944499.6414557))))%(((x+(1253986263.5049214))+(((((3135584075.248715)+((tmp = -2569819028.5414333, tmp)%(440908176.1619092)))>>>(x<<((3061615025)-x)))%x)%(x+((2369612016)*((((tmp = 1173615806, tmp)*(-1910894327))&(2428053015.077821))*(-55668334.70082307))))))<<(tmp = -2129259989.0307562, tmp)))+(1579400360)))%((-3053590451.8996153)>>x)))+(x>>(x%(x^((-1772493876)^x))))));
- assertEquals(413738663060841600, x *= x);
- assertEquals(1581062538.4501781, x %= ((tmp = -1298397672.0300272, tmp)-((2237197923)+(tmp = -1385478459, tmp))));
- assertEquals(755644566.8709538, x %= (tmp = -825417971.5792243, tmp));
- assertEquals(1, x /= x);
- assertEquals(0, x >>>= ((89330582)%(-1012731642.4855506)));
- assertEquals(0, x >>>= x);
- assertEquals(NaN, x %= ((x>>>((x/(tmp = -1848848941.2352903, tmp))>>>(tmp = -71862893, tmp)))&(-2385996598.2015553)));
- assertEquals(NaN, x += (-2292484503.318904));
- assertEquals(NaN, x *= (2961064461));
- assertEquals(NaN, x += (x<<((2076798243.6442)/((tmp = -81541044.75366282, tmp)^((3041366498.551101)+((2126874365)/(tmp = -177610359, tmp)))))));
- assertEquals(NaN, x %= ((x/((x/x)+x))>>>x));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x += (1171761980.678));
- assertEquals(NaN, x += ((2355675823)<<(-390497521)));
- assertEquals(NaN, x %= x);
- assertEquals(0, x &= (tmp = -658428225.56619, tmp));
- assertEquals(0, x ^= x);
- assertEquals(0, x <<= (1643310725.5713737));
- assertEquals(0, x <<= x);
- assertEquals(0, x <<= (-397005335.3712895));
- assertEquals(0, x >>>= (tmp = -2804713458.166788, tmp));
- assertEquals(0, x <<= (((((((tmp = 1879988501, tmp)%(1528081313.9360204))+(1376936736))*((((x>>>((1736268617.339198)>>>(-2598735297.4277673)))<<((((((((-2742982036)/(231867353.4549594))-(875335564))<<x)|((2241386341.742653)<<((-22024910.828409433)&(x<<x))))*(-756987803.5693252))+x)^(tmp = 1084498737, tmp)))<<(1920373881.8464394))&(2370827451.82652)))&(x^(tmp = -891503574, tmp)))<<x)>>>((-1519588625.2332087)^(483024636.2600144))));
- assertEquals(52193878.40997505, x -= ((tmp = -341753803.40997505, tmp)%(tmp = -96519975, tmp)));
- assertEquals(-1665844168.938803, x -= (1718038047.348778));
- assertEquals(3.6962232549405003e-19, x /= (((((-809583468.5507183)>>>((tmp = 286797763, tmp)%((1579183142.7321532)/(1853824036.001172))))<<x)>>(((x|x)^((tmp = -2641304815, tmp)<<(x<<x)))>>(((((268338128.8300134)&(-1778318362.8509881))*(751081373.346478))<<(((525066612)>>(-1139761212))*(2949167563.299916)))<<x)))+((tmp = 664905121, tmp)*((-2208280205)*(3069462420)))));
- assertEquals(4710721795.110161, x += (((217604832)+((1307891481.781326)-x))+(tmp = 3185225481.328835, tmp)));
- assertEquals(0, x %= x);
- assertEquals(0, x -= (((x>>>(x/(tmp = 46977522.46204984, tmp)))>>(-2466993199.615269))&(tmp = 14524430.287991166, tmp)));
- assertEquals(0, x >>= x);
- assertEquals(0, x /= (tmp = 578120637, tmp));
- assertEquals(-17267104, x -= (((tmp = 1515285919.495792, tmp)+(((tmp = -1364790286.7057304, tmp)+((954599071)>>((897770243.1509961)*x)))^x))>>>(566027942.1732262)));
- assertEquals(-17267104, x &= x);
- assertEquals(189138241, x ^= ((tmp = 1565742675.9503145, tmp)-((tmp = 1737806643, tmp)|((x*(tmp = -1382435297.5955122, tmp))*(-2820516692.153056)))));
- assertEquals(189138241, x %= (x*(tmp = -1670678493, tmp)));
- assertEquals(1693, x %= ((-2328713314)>>>(1623637325)));
- assertEquals(1693, x %= ((-1019394014)*(x|x)));
- assertEquals(3386, x += x);
- assertEquals(9268970871604, x *= (2737439714));
- assertEquals(-4720.120483643183, x /= (tmp = -1963714889, tmp));
- assertEquals(-1, x >>= ((x^(((-2404688047.455056)|((1439590234.6203847)<<(tmp = -2496557617, tmp)))/((x<<((tmp = 1865549512.282249, tmp)/(((360384191.55661833)>>(tmp = -1225297117.344188, tmp))>>>(2703264010.4122753))))*(1521960888.0071676))))%(tmp = 2834001448.0508294, tmp)));
- assertEquals(63, x >>>= (x&(-3079339174.6490154)));
- assertEquals(0, x >>>= (1039770956.6196513));
- assertEquals(0, x >>>= (-1074820214));
- assertEquals(0, x >>>= (x/x));
- assertEquals(0, x >>= ((tmp = -449117604.2811785, tmp)&x));
- assertEquals(-0, x /= (tmp = -118266935.1241343, tmp));
- assertEquals(2226140134, x += (tmp = 2226140134, tmp));
- assertEquals(2068827161, x ^= ((tmp = -1950744808.846384, tmp)>>((2258661151)^((tmp = -1118176421.8650177, tmp)<<(2828634014)))));
- assertEquals(123, x >>>= (-1779624840.0515127));
- assertEquals(0, x >>>= (x|((tmp = -239082904, tmp)<<(tmp = 1404827607, tmp))));
- assertEquals(0, x >>>= x);
- assertEquals(1793109749, x ^= (tmp = -2501857547.710491, tmp));
- assertEquals(855, x >>>= x);
- assertEquals(0, x >>>= (-847289833));
- assertEquals(0, x %= (-2271241045));
- assertEquals(169648072, x ^= (((tmp = 169648072.66759944, tmp)^x)|x));
- assertEquals(176025927479164930, x *= ((tmp = 1111997198.8803885, tmp)<<(tmp = 2913623691, tmp)));
- assertEquals(176025926613281700, x += ((tmp = -865883245, tmp)<<(x+(-2624661650))));
- assertEquals(3406506912, x >>>= ((x|(tmp = 2436016535, tmp))*(((tmp = -1222337225, tmp)<<((1765930268)&x))*(tmp = 1600702938, tmp))));
- assertEquals(1.694694170868292, x %= (x/(-1597121830.794548)));
- assertEquals(0, x >>= (tmp = -2443203089, tmp));
- assertEquals(0, x >>>= (1323174858.2229874));
- assertEquals(0, x &= ((tmp = 846556929.2764134, tmp)|(((1483000635.0020065)|(-3151225553))|(tmp = -229028309, tmp))));
- assertEquals(0, x >>= x);
- assertEquals(0, x >>= ((((((-2677334787)>>>x)>>((tmp = 496077992, tmp)&((((x<<(x*(tmp = 1095163344.2352686, tmp)))+(-952017952))%((x<<((x*x)/(tmp = 2983152477, tmp)))^((tmp = -939521852.1514642, tmp)^(tmp = 143967625.83755958, tmp))))*((tmp = 551827709.8366535, tmp)>>>x))))^((-1552681253.69869)-(-1874069995)))>>>(x>>(x%(tmp = -2554673215, tmp))))|(tmp = -190693051.77664518, tmp)));
- assertEquals(0, x /= (tmp = 427402761.37668264, tmp));
- assertEquals(0, x <<= x);
- assertEquals(0, x |= (x>>>(((((-543326164.0673618)>>>(-2344090136.707964))>>>((((-563350246.6026886)/x)/(1525481037.3332934))&(tmp = -2917983401.88958, tmp)))^(-1094667845.1208413))^x)));
- assertEquals(0, x &= (1080322749.897747));
- assertEquals(0, x %= (tmp = -1572157280, tmp));
- assertEquals(0, x >>>= x);
- assertEquals(0, x %= ((377280936)|x));
- assertEquals(708335912, x -= (tmp = -708335912, tmp));
- assertEquals(2766937, x >>>= x);
- assertEquals(547342779, x += (tmp = 544575842, tmp));
- assertEquals(546273751, x -= ((x>>>(472833385.9560914))|((tmp = -1164832103.9970903, tmp)/(3147856452.1699758))));
- assertEquals(546273751, x &= x);
- assertEquals(0, x ^= x);
- assertEquals(0, x >>>= (tmp = -3181805175, tmp));
- assertEquals(-375546685, x |= (-375546685.08261824));
- assertEquals(1089992785780217200, x *= (tmp = -2902416209, tmp));
- assertEquals(0, x %= x);
- assertEquals(-1854981526, x -= ((x-x)-(-1854981526)));
- assertEquals(-3709963052, x += x);
- assertEquals(-316772482, x %= (tmp = -1696595285, tmp));
- assertEquals(-316772482, x |= x);
- assertEquals(1, x /= x);
- assertEquals(0, x -= x);
- assertEquals(-1418375842, x ^= (-1418375842));
- assertEquals(-2, x >>= x);
- assertEquals(-4, x += x);
- assertEquals(-8388608, x &= (x<<(-350555339.30086184)));
- assertEquals(-16777216, x += x);
- assertEquals(-0, x %= x);
- assertEquals(1083355129, x += (tmp = 1083355129, tmp));
- assertEquals(0, x &= (((tmp = 389729053, tmp)-(tmp = 2944192190.0939536, tmp))/(x-(2081712461.2657034))));
- assertEquals(0, x += x);
- assertEquals(-3, x += ((3147270119.5831738)>>((2455837253.1801558)%((-2100649096)>>(((290236808.01408327)|(x&((2661741230.3235292)|((tmp = 1686874589.4690177, tmp)<<x))))*(x+(tmp = 2327674670, tmp)))))));
- assertEquals(-3, x %= ((x>>(((-2962686431)%x)>>((((2438370783)-(tmp = 2667305770.4839745, tmp))>>>x)>>>x)))<<((x&(tmp = 1428498616, tmp))|((tmp = 2621728539.102742, tmp)/(-204559901)))));
- assertEquals(2, x ^= (x|((((tmp = 1751230118.6865973, tmp)/(-867465831.207304))>>((-808143600.0912395)+(-2882191493.0506454)))^x)));
- assertEquals(2, x %= (-2015954220.2250996));
- assertEquals(0, x >>>= (tmp = 401373999, tmp));
- assertEquals(0, x >>= (2371830723));
- assertEquals(0, x >>>= ((((tmp = 2765919396, tmp)-x)-(530310269.7131671))|(tmp = -615761207.9006102, tmp)));
- assertEquals(-145389011, x ^= (tmp = -145389011, tmp));
- assertEquals(-145389011, x |= x);
- assertEquals(1632929832, x &= (-2518898392));
- assertEquals(4190540017.751949, x += (tmp = 2557610185.751949, tmp));
- assertEquals(4980024282.153588, x += ((1841304364.1177452)%(tmp = 1051820099.7161053, tmp)));
- assertEquals(0, x >>>= (((((1379314342.4233718)>>((-2782805860)^((x%(tmp = 1328845288, tmp))>>>(tmp = 901403219.858733, tmp))))+(x/((tmp = -3078904299, tmp)/x)))/x)|(x|(1399702815))));
- assertEquals(-1820494882, x ^= (tmp = -1820494882.407127, tmp));
- assertEquals(-305870376, x %= (tmp = -757312253, tmp));
- assertEquals(-577530443, x += (x|(tmp = -1958083619.6653333, tmp)));
- assertEquals(333541412591776260, x *= x);
- assertEquals(-949341696, x >>= ((((1550069663)<<((x>>>(tmp = 2406565178.902887, tmp))>>>((1844746612.632984)/((tmp = 2233757197, tmp)*((-1524891464.1028347)>>(tmp = 2498623474.5616803, tmp))))))&x)<<(x&(tmp = -370379833.3884752, tmp))));
- assertEquals(-277202090, x |= ((-762200848.8405354)-(tmp = 1749136282, tmp)));
- assertEquals(0.13704539927239265, x /= (tmp = -2022702633.373563, tmp));
- assertEquals(0, x -= x);
- assertEquals(0, x %= ((132951580.19304836)-((427623236.27544415)-(1212242858))));
- assertEquals(0, x &= ((449148576)&(-1609588210.249217)));
- assertEquals(0, x >>= x);
- assertEquals(0, x -= x);
- assertEquals(-0, x /= (tmp = -1640777090.9694843, tmp));
- assertEquals(0, x &= (((tmp = -1923412153, tmp)>>>((x>>(tmp = 3027958119.0651507, tmp))+(60243350)))>>(tmp = -2610106062, tmp)));
- assertEquals(0, x ^= (((-186998676)/(tmp = 2697937056, tmp))-x));
- assertEquals(-1147950080, x |= ((2425449461)*(tmp = -2525854833, tmp)));
- assertEquals(457688198, x ^= (2698274950.660941));
- assertEquals(8724, x %= ((1174351031)>>>((371599047.36048746)+(3025292010))));
- assertEquals(0, x <<= (tmp = -710011617, tmp));
- assertEquals(0, x >>>= (1693410026));
- assertEquals(1443005362, x ^= ((tmp = -2851961934, tmp)+((((x%x)-(tmp = 547622400, tmp))<<(((tmp = 722396486.5553623, tmp)|x)>>>((((tmp = -542268973.5080287, tmp)<<(tmp = 1347854903.771954, tmp))>>>(tmp = -889664427.7115686, tmp))&((tmp = 1549560114, tmp)*(tmp = 964918035, tmp)))))&(-2422502602.920377))));
- assertEquals(3986573462, x -= (-2543568100));
- assertEquals(7973146924, x += x);
- assertEquals(-1, x >>= (-75987297));
- assertEquals(-12, x += ((2940824338.64834)>>(tmp = 3061467355, tmp)));
- assertEquals(-3.8229398525977614e-8, x /= (313894554));
- assertEquals(-2.890709270374084e-17, x /= (tmp = 1322491989, tmp));
- assertEquals(0, x |= (x-x));
- assertEquals(0, x >>>= (tmp = -1205300664, tmp));
- assertEquals(-0, x /= (((2869505187.6914144)>>(tmp = 1541407065, tmp))/(((-571132581)>>>(x>>x))/((x^(170373762.8793683))>>>((((tmp = -363073421.05897164, tmp)|(((tmp = -1591421637, tmp)>>(1095719702.8838692))&(636687681.9145031)))^x)^(x|x))))));
- assertEquals(-1487828433, x ^= (-1487828433.3462324));
- assertEquals(-0, x %= x);
- assertEquals(1716342498, x -= ((tmp = 2578624798, tmp)^x));
- assertEquals(1636, x >>= ((264194540)>>>(-801900756)));
- assertEquals(0, x >>>= ((tmp = 2502688876, tmp)+((x<<(x|((-628272226.0338528)|((x<<(-2083074091))>>>(tmp = 1692123246.8418589, tmp)))))>>(1594759826.990993))));
- assertEquals(0, x <<= (tmp = -904399643, tmp));
- assertEquals(NaN, x /= ((x^(x-x))%((tmp = 1744962024.4882128, tmp)%x)));
- assertEquals(NaN, x /= (-1013142883.1845908));
- assertEquals(NaN, x /= ((tmp = 793633198, tmp)^(-2993598490.8659954)));
- assertEquals(0, x &= (x>>((tmp = 1200937851, tmp)<<(((tmp = -2807378465, tmp)&(tmp = -143778237, tmp))|(tmp = -1200772223, tmp)))));
- assertEquals(0, x <<= x);
- assertEquals(88144, x |= (((((tmp = 3002723937.8560686, tmp)*(tmp = -3171720774.2612267, tmp))%(((tmp = -2586705978.7271833, tmp)%((x+(-1553704278))&(2405085526.501994)))>>((-240842053)>>>(((((tmp = -1886367228.4794896, tmp)>>>x)^(tmp = 2604098316, tmp))^(tmp = 1362808529, tmp))<<((tmp = -1062263918, tmp)|((-172718753)%(tmp = -1910172365.4882073, tmp)))))))^((1444153362)>>((x&((-1205465523.2604182)^(tmp = -2062463383, tmp)))>>(tmp = 956712476, tmp))))>>((((-1004215312)^((((-1707378612.5424936)^(tmp = 2372161553, tmp))/((tmp = 1802586581, tmp)*((2082257.1896460056)&((tmp = -1270773477, tmp)^(tmp = 942517360.3447798, tmp)))))+x))%((((666494127)^(x^x))>>>(tmp = -2592829775, tmp))+((-1601528223)+((x+(tmp = -2417034771.7409983, tmp))>>>((tmp = -730673817, tmp)*x)))))>>x)));
- assertEquals(-2603179111.7557006, x -= ((2603267255.755627)+(x/(1200979191.2823262))));
- assertEquals(1691788185, x >>= (tmp = 3088840032, tmp));
- assertEquals(-168382533, x |= (tmp = -780750941.4590135, tmp));
- assertEquals(-168382533, x >>= (60741120.48285198));
- assertEquals(-134287365, x |= (x*(tmp = 834637940.7151251, tmp)));
- assertEquals(-1481917089, x -= (tmp = 1347629724, tmp));
- assertEquals(1, x >>>= x);
- assertEquals(262144, x <<= (2680216914));
- assertEquals(1075132032, x ^= (x-((tmp = 3220359552.3398685, tmp)^(((-434474746.6039338)|((((((((tmp = 1945689314.9683735, tmp)>>(1300022273))>>>(333705550))&x)%(588357521))-(x+(x^(((tmp = -134560382, tmp)+x)-((((994246147.7195556)-(-1506599689.7383268))%(x<<x))>>((1256426985.5269494)+(tmp = 1860295952.8232574, tmp)))))))^(((tmp = 917333220.2226384, tmp)>>x)>>>(tmp = 865898066, tmp)))%((x|(x%((tmp = -2660580370, tmp)&(tmp = 2966426022, tmp))))*x)))/(((tmp = 682585452, tmp)&(-3219368609))+((tmp = -1330253964, tmp)+((x&(2857161427))/x)))))));
- assertEquals(274944, x &= ((2606953028.1319966)-(-1707165702)));
- assertEquals(266752, x &= ((x<<((x+(x+(x^(-1570175484))))^x))^(x+(x<<(tmp = 90330700.84649956, tmp)))));
- assertEquals(266752, x &= ((((x*(tmp = 2033225408, tmp))-(x-((tmp = 1507658653, tmp)/(-3016036094))))>>>((1497480588)>>(2784070758)))|(tmp = -3025904401.93921, tmp)));
- assertEquals(-1680442631, x |= ((x/(445284843))|((tmp = 2614520057.2723284, tmp)<<x)));
- assertEquals(40851947, x >>>= (tmp = -1577031386.938616, tmp));
- assertEquals(2493, x >>= ((3044630989.3662357)-(-2670572992.8580284)));
- assertEquals(-0.0000017317105653562252, x /= (-1439617017.9207587));
- assertEquals(0, x &= (2359806567));
- assertEquals(623768541, x ^= (623768541));
- assertEquals(1028567149.0716183, x += (((tmp = 1307794561, tmp)%(x>>x))-(-404798608.0716183)));
- assertEquals(-1.2971762489811298, x /= (tmp = -792927830.6471529, tmp));
- assertEquals(-1.2971762489811298, x %= ((-2426421701.2490773)/(-689566815.3393874)));
- assertEquals(-2147483648, x <<= x);
- assertEquals(-2147483648, x &= (tmp = -869991477, tmp));
- assertEquals(-268435456, x >>= (1383186659));
- assertEquals(0, x -= x);
- assertEquals(-2009742037, x |= (-2009742037.5389993));
- assertEquals(-1386630820, x ^= (627864695));
- assertEquals(-1033479103975173600, x *= (tmp = 745316697.9046186, tmp));
- assertEquals(-1628048487, x |= (2662654361));
- assertEquals(325551, x >>>= (340874477));
- assertEquals(-1235730537, x ^= (tmp = 3059533880.0725217, tmp));
- assertEquals(-1235730537, x %= (2247137328));
- assertEquals(-220200960, x <<= ((x>>x)-x));
- assertEquals(0, x <<= ((tmp = 337220439.90653336, tmp)|(tmp = 2901619168.375105, tmp)));
- assertEquals(0, x >>>= ((-2114406183)/x));
- assertEquals(0, x %= ((1425828626.3896675)/x));
- assertEquals(0, x >>>= ((3213757494)>>>(2595550834.3436537)));
- assertEquals(0, x <<= x);
- assertEquals(-0, x /= ((1544519069.5634403)/((tmp = -1332146306, tmp)&(-762835430.0022461))));
- assertEquals(0, x ^= x);
- assertEquals(0, x >>= (x|((((x*((-786272700)+x))<<x)+((tmp = -1868484904, tmp)-(tmp = -1692200376, tmp)))+(-1010450257.6674457))));
- assertEquals(0, x -= x);
- assertEquals(0, x ^= (x>>>(706010741)));
- assertEquals(-964928697, x |= (-964928697));
- assertEquals(1, x /= x);
- assertEquals(0, x >>= ((((tmp = 1778003555.3780043, tmp)>>(x%((tmp = -766158535, tmp)^((-2681449292.8257303)%((x-(x|(tmp = 1966478387.2443752, tmp)))^(((tmp = -1848398085, tmp)&x)>>>(tmp = -2860470842, tmp)))))))%(tmp = 2315077030, tmp))^x));
- assertEquals(0, x ^= x);
- assertEquals(-288007757, x ^= ((tmp = 183607156.1803962, tmp)-(tmp = 471614914, tmp)));
- assertEquals(-270573581, x |= (tmp = -849475741.9424644, tmp));
- assertEquals(-2129929, x |= (((((1942852445)&(tmp = 1280372312, tmp))*(x*(tmp = -1601900291, tmp)))^((509080002.81080174)-(tmp = 2699498226.9164257, tmp)))>>(((-335361221)>>(tmp = 843134832, tmp))%(-35532542))));
- assertEquals(-232622355, x ^= ((-3060885134.5375547)-(((tmp = 1965966723, tmp)-((tmp = 1248630129.6970558, tmp)<<(tmp = 1859637857.5027392, tmp)))*x)));
- assertEquals(-52149658093200070, x *= (224181627.31264615));
- assertEquals(-697122968, x ^= (x-(x+(tmp = 2747211186.407712, tmp))));
- assertEquals(-2146269688, x &= ((tmp = -1466710519, tmp)^(x/(1419998975))));
- assertEquals(-536567422, x >>= (((((tmp = -1760701688.999274, tmp)>>(-1821976334))/(((tmp = -1660849531, tmp)>>>x)-((x+((tmp = -2489545009.4327965, tmp)>>>((tmp = -267360771.39148235, tmp)^x)))*(((-1453528661)%x)>>>(((243967010.3118453)/((((((2977476024)>>>((-1630798246)<<x))&(591563895.2506002))*(((2668543723.9720144)>>>x)|(1600638279)))^x)>>(x<<(tmp = -152589389, tmp))))>>>(x|(2821305924.9225664)))))))+(618968002.8307843))%(tmp = -1005408074.368274, tmp)));
- assertEquals(40962, x &= (114403906));
- assertEquals(19741977727890, x *= ((-2367133915.963945)>>>(-3119344126)));
- assertEquals(1313341440, x <<= x);
- assertEquals(626, x >>>= ((((-333992843)%(tmp = -2742280618.6046286, tmp))>>>x)|x));
- assertEquals(0, x <<= (2598188575));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x %= x);
- assertEquals(0, x ^= (x%((2507288229.3233204)&(tmp = -1714553169.9276752, tmp))));
- assertEquals(0, x /= ((633436914.3859445)>>>(tmp = 1579804050.6442273, tmp)));
- assertEquals(0, x *= ((tmp = 1172218326, tmp)<<((tmp = -2491306095.8456626, tmp)*(((tmp = 1305371897.9753594, tmp)>>((x^(((3077992060)*x)<<(492815553.904796)))>>((652151523)|x)))%x))));
- assertEquals(0, x <<= x);
- assertEquals(0, x %= (1118131711));
- assertEquals(0, x &= ((tmp = 2734673884, tmp)|(x-((tmp = 2694578672.8975897, tmp)*(((x>>(2350811280.974167))*(1052548515))&(x^(x*(tmp = -1336287059.0982835, tmp))))))));
- assertEquals(-2632782867.1256156, x += ((tmp = -2743992725.1256156, tmp)+(tmp = 111209858, tmp)));
- assertEquals(-0, x %= x);
- assertEquals(0, x >>>= (((tmp = -2050519887, tmp)^(106865302.74529803))>>(1642851915.2909596)));
- assertEquals(-171964826, x |= (tmp = -171964826.6087358, tmp));
- assertEquals(-2.113405951193522, x /= (tmp = 81368572.80206144, tmp));
- assertEquals(3, x >>>= x);
- assertEquals(0, x %= x);
- assertEquals(-1717345907.837667, x += (-1717345907.837667));
- assertEquals(-100964883, x |= (tmp = -109574931.80629134, tmp));
- assertEquals(-33849857, x |= (-974111718.2433801));
- assertEquals(1, x >>>= (tmp = -2556222849.005595, tmp));
- assertEquals(1, x /= x);
- assertEquals(0, x >>>= (-1796630999.4739401));
- assertEquals(0, x >>>= x);
- assertEquals(2031695758, x += (((x/(((tmp = -2364918403, tmp)%(x^((tmp = 277767803.6375599, tmp)>>((((tmp = 540036080, tmp)/(x|(2665298931)))/(x|((x>>(-2035456216.6165116))<<(2143184420.5651584))))^x))))&(tmp = 927798419.8784283, tmp)))-(-2031695758))>>>x));
- assertEquals(2031695758, x |= x);
- assertEquals(2031695758, x <<= (((x>>(x%x))|(tmp = -1164531232.7384055, tmp))*x));
- assertEquals(124004, x >>>= x);
- assertEquals(529846352, x += ((529722348)%((2417645298.865121)|(x>>(x>>>(x+x))))));
- assertEquals(60067920, x &= (((tmp = -3166008541.8486233, tmp)-x)|(x%x)));
- assertEquals(1415594240755200, x *= ((-2786707452.873729)>>(((tmp = -2369315809, tmp)*((1559868465)|(1011218835.1735028)))>>>x)));
- assertEquals(1415595182259140, x += (941503939.9023957));
- assertEquals(0, x <<= ((tmp = 2887184784.265529, tmp)/(-2575891671.0881453)));
- assertEquals(0, x &= ((tmp = -1546339583, tmp)>>>(tmp = -587433830, tmp)));
- assertEquals(0, x *= (((tmp = 1356991166.5990682, tmp)%(tmp = -284401292, tmp))*(1869973719.9757812)));
- assertEquals(NaN, x %= x);
- assertEquals(0, x ^= (((tmp = 92575404.43720293, tmp)>>>(263475358.17717505))%x));
- assertEquals(0, x <<= (((561514358)*(tmp = -439584969, tmp))%((((-3005411368.7172136)+x)|(-2230472917))&x)));
- assertEquals(0, x >>= ((x>>>x)-((x-(1630649280.510933))+x)));
- assertEquals(0, x >>= (tmp = -1772403084.7012017, tmp));
- assertEquals(0, x *= x);
- assertEquals(0, x += x);
- assertEquals(0, x &= x);
- assertEquals(0, x >>= (tmp = 1622680387, tmp));
- assertEquals(1033887633558225200, x -= ((-510616337)*(tmp = 2024783695, tmp)));
- assertEquals(-2.8073538539158063e+27, x *= (tmp = -2715337492, tmp));
- assertEquals(-2.8073538539158063e+27, x -= ((tmp = -1664804757, tmp)&((tmp = -226616419, tmp)>>>(1006711498))));
- assertEquals(1894539615, x |= (tmp = -2400427681.1831083, tmp));
- assertEquals(7400545, x >>= (774629608.4463601));
- assertEquals(456756268, x += (449355723));
- assertEquals(285771784, x &= (-1316427366));
- assertEquals(17, x >>= ((tmp = -220509931.20787525, tmp)*(((tmp = 2518859292, tmp)+(-1477543005.1586645))>>(tmp = 3172820250.687789, tmp))));
- assertEquals(85924262443, x *= (x*((tmp = -2856669745.965829, tmp)&(((tmp = 401420695, tmp)^(tmp = 2355371132, tmp))|(tmp = 590645330.021911, tmp)))));
- assertEquals(1703875715, x ^= ((-2576394029.7843904)-x));
- assertEquals(1703875715, x %= (tmp = 2234144310, tmp));
- assertEquals(271405807, x ^= (1973569132));
- assertEquals(1060178, x >>>= (tmp = -84823096, tmp));
- assertEquals(8, x >>>= (tmp = 2246120561.905554, tmp));
- assertEquals(-2846791089, x += (-2846791097));
- assertEquals(104933962, x &= (x-(-2969030955.99584)));
- assertEquals(489215611.96215343, x -= (-384281649.96215343));
- assertEquals(489215611, x |= x);
- assertEquals(1186191360, x <<= ((tmp = 774407142.993727, tmp)%x));
- assertEquals(1186191360, x %= (1555004022));
- assertEquals(-1697134080, x ^= (tmp = -597421568, tmp));
- assertEquals(-1102053376, x <<= ((-927370769.4059179)^((tmp = 1093490918, tmp)>>(((-2522227493.3821955)%x)+(-2657319903)))));
- assertEquals(1086450058, x ^= (-23991926.187098265));
- assertEquals(1086450058, x |= x);
- assertEquals(-1.6554590588410778, x /= (x|(x<<(x+x))));
- assertEquals(67108863, x >>>= ((-926530233)+x));
- assertEquals(494553310, x ^= (tmp = 512079649, tmp));
- assertEquals(207751168, x &= (2892146720.6261826));
- assertEquals(207751168, x &= x);
- assertEquals(207751168, x |= x);
- assertEquals(6340, x >>>= (((((x<<(x-((-2819638321)*((x<<x)+x))))>>x)+(tmp = 2016170261, tmp))+(tmp = 2755496043.772017, tmp))+(-841368625.1402085)));
- assertEquals(6340, x ^= ((x/(tmp = -192734784, tmp))>>>(((-140306239)&x)-x)));
- assertEquals(1, x /= x);
- assertEquals(0, x >>= x);
- assertEquals(26786600, x ^= (tmp = 26786600, tmp));
- assertEquals(-0.014657576899542954, x /= ((-1454855938.0338)+(-372635753.3681567)));
- assertEquals(0, x &= ((tmp = 2480635933, tmp)&(-2986584704.9165974)));
- assertEquals(-2108639122, x += ((tmp = 2108639123.8683565, tmp)^((-881296055)/(((x<<(2026200582))|(tmp = -862495245.138771, tmp))-(-1111596494.892467)))));
- assertEquals(1893466112, x <<= (tmp = 607974481, tmp));
- assertEquals(1893466112, x |= x);
- assertEquals(1133122783.997418, x += ((tmp = -760343332, tmp)-((x-(tmp = -878561823.4218843, tmp))/(tmp = -693454632.596637, tmp))));
- assertEquals(8, x >>>= (tmp = 700339003.3919828, tmp));
- assertEquals(4.605305035175536e-9, x /= (1737127060.8343256));
- assertEquals(4.605305035175536e-9, x -= ((x%(897221779))>>>x));
- assertEquals(-1864423625.5704088, x += (tmp = -1864423625.5704088, tmp));
- assertEquals(1132240092, x <<= (1304417186.1193643));
- assertEquals(-2088985380, x ^= (x<<x));
- assertEquals(-4, x >>= ((tmp = 1959823884.0935726, tmp)%(-1679792398.569136)));
- assertEquals(-268435456, x <<= ((tmp = 2586838136, tmp)|((tmp = -481716750.718518, tmp)>>>((1485826674.882607)/(tmp = -2826294011, tmp)))));
- assertEquals(-32768, x >>= (2060648973));
- assertEquals(1, x /= x);
- assertEquals(-2838976297, x -= (tmp = 2838976298, tmp));
- assertEquals(-1382985298, x <<= ((tmp = -2104305023, tmp)&x));
- assertEquals(10, x >>>= (x+x));
- assertEquals(10, x -= (x>>>(361588901.70779836)));
- assertEquals(854603510, x -= (-854603500));
- assertEquals(-557842432, x <<= (tmp = 1212985813.6094751, tmp));
- assertEquals(-459390188241943040, x *= (tmp = 823512450.6304014, tmp));
- assertEquals(-232800033621957060, x /= ((((((686635689)/(tmp = 2013252543, tmp))*(tmp = -1591617746.8678951, tmp))|(((tmp = -1777454093.5611362, tmp)>>>((tmp = 2680809394, tmp)^(((x>>((((((tmp = -265022244, tmp)%((tmp = -3075004537, tmp)>>(((((1427784269.5686688)^((tmp = -1095171528.911587, tmp)^(-942424985.7979553)))>>(-1279441481.1987405))*((2493620394)>>(-2769016043)))/(x&((tmp = 2059033657, tmp)%(((tmp = 1948606940.1488457, tmp)-(tmp = -2645984114.13219, tmp))^x))))))^x)^x)%(x%((((tmp = 3209433446.4551353, tmp)%(tmp = 1364430104.0424738, tmp))/(tmp = -2103044578.349498, tmp))+(tmp = -2613222750, tmp))))*(2099218034)))&(((tmp = -378500985.49700975, tmp)>>(((x+x)|(x%(((-1841907486)<<(-1220613546.194021))<<(tmp = -1260884176, tmp))))^(tmp = 1858784116, tmp)))>>>((x%x)%((x>>>(tmp = -2540799113.7667685, tmp))|x))))/((((tmp = 642072894.6455215, tmp)-(-324951103.6679399))*(tmp = 1424524615, tmp))+((x<<(tmp = -904578863.5945344, tmp))*(tmp = 49233475.435349464, tmp))))))<<(tmp = 1680210257, tmp)))+((tmp = -1516431503, tmp)>>>(-1105406695.3068116)))/(-275019361.6764543)));
- assertEquals(192359387.42913792, x /= (-1210234846));
- assertEquals(192359387.42913792, x %= (-2920206625.0154076));
- assertEquals(192359387.42913803, x -= (((((((tmp = -1263203016.3258834, tmp)-(2432034005.6011124))&x)<<(1479434294))>>((tmp = -1695856315.523002, tmp)>>>(tmp = 557391345, tmp)))/(tmp = -1280240246.2501266, tmp))%((tmp = -2196489823.034029, tmp)>>(((x&((912221637.1101809)+((tmp = -3003677979.652423, tmp)>>(tmp = -716129460.1668484, tmp))))-((x+(x-(-2780610859)))>>>(-2445608016)))<<((x*(x+(x+(((-2124412727.9007604)%(tmp = -593539041.5539455, tmp))&(tmp = 2404054468.768749, tmp)))))%(x>>(tmp = -2913066344.404591, tmp)))))));
- assertEquals(11740, x >>= (688848398.7228824));
- assertEquals(11740, x >>= ((1545765912)*(307650529.9764147)));
- assertEquals(23480, x += x);
- assertEquals(0, x >>>= ((tmp = 1313078391, tmp)|x));
- assertEquals(1726251264, x -= ((1939413887)<<(1004888744.2840619)));
- assertEquals(765324793.5278986, x %= (960926470.4721014));
- assertEquals(747387, x >>= ((2483010044)-(tmp = -413698190, tmp)));
- assertEquals(1, x /= x);
- assertEquals(3016811624, x *= (3016811624));
- assertEquals(17408, x &= (((tmp = -991624868, tmp)<<(((63107932)/(tmp = 2659939199, tmp))|(tmp = -1968768911.3575773, tmp)))>>(((-2876822038.9910746)|(tmp = 2550230179.243425, tmp))<<((x*(x<<((x<<((tmp = -1627718523.616604, tmp)|((2154120561.254636)-(x%(x<<(1484563622.1791654))))))<<((((x^(tmp = 3016524169, tmp))<<(((x+(tmp = 1887816698.2455955, tmp))+x)-x))-(-3023329069))-x))))+x))));
- assertEquals(0, x <<= (((1247441062.177967)/(-1717276234))+x));
- assertEquals(0, x |= ((x%((-1648299429.4520087)>>(-137511052)))>>(tmp = 221301016.4926411, tmp)));
- assertEquals(0, x /= ((-2598501544.913707)>>>(-2177037696)));
- assertEquals(NaN, x %= (x>>x));
- assertEquals(0, x &= (tmp = 1852419158, tmp));
- assertEquals(-829029120, x |= (((2122339180)*((((((tmp = 768748914, tmp)<<((1008490427)&((1937367899.957056)-(((635094486)>>(((tmp = -795046025, tmp)*(2665104134.4455256))^(tmp = 706594584.2462804, tmp)))/(504397522)))))/(-556057788))>>((x/(tmp = -2732280594, tmp))-x))+(-1989667473))+(tmp = 2766802447.789895, tmp)))<<(((tmp = -2969169096, tmp)-x)+(tmp = 2093593159.0942125, tmp))));
- assertEquals(0.6451933462602606, x /= ((-1284931292)<<(x<<(tmp = 1294716764, tmp))));
- assertEquals(1515416866.520901, x *= (2348779440));
- assertEquals(-1620606242886682600, x *= ((-993898625.5357854)&(((tmp = -571100481, tmp)/x)*((2428590177.311031)%(tmp = -2671379453, tmp)))));
- assertEquals(-1137472828, x %= (tmp = -1195183004, tmp));
- assertEquals(-3096634005473250000, x *= (tmp = 2722380640, tmp));
- assertEquals(-3096634003996758500, x -= (-1476491033.833419));
- assertEquals(-3096634000805538000, x += (3191220521.978341));
- assertEquals(-3096634000805468000, x += ((((tmp = -3024976741, tmp)&(952616360))|((x*(-1547952311))+(x*x)))>>>(tmp = 981373323, tmp)));
- assertEquals(-3096633998655594000, x += (2149873927));
- assertEquals(-118812224101.54297, x %= (((2641881276.9898443)*(((502159480)^x)<<x))%((tmp = -2840045365.547772, tmp)*(((((-2297661528)>>>(x>>(-229103883.94961858)))&(((-1285047374.6746495)<<((-360045084)>>>((x-(tmp = -956123411.1260898, tmp))%x)))>>((tmp = -2375660287.5213504, tmp)+((((tmp = -2753478891, tmp)>>>(((tmp = 101438098, tmp)>>(((tmp = -2736502951, tmp)<<((tmp = -3084561882.368902, tmp)&(tmp = 1491700884, tmp)))|x))&(tmp = 1627412882.6404104, tmp)))>>>(tmp = 1039002116.6784904, tmp))<<((tmp = -2840130800, tmp)-(tmp = -740035567, tmp))))))&(tmp = -416316142, tmp))>>x))));
- assertEquals(86, x >>>= (tmp = -293489896.5572462, tmp));
- assertEquals(172, x += (x%((((-2635082487.364155)|((-2361650420.634912)&(-2147095650.7451198)))<<((tmp = 2258905145.9231243, tmp)%((((tmp = -1365987098.5130103, tmp)*(((((((932437391)/x)/(289270413.0780891))%(x-x))+((((2194986374.917528)>>(((((tmp = -1553805025, tmp)|x)^(((x>>(-564400586.0780811))^(tmp = 1738428582.0238137, tmp))>>(tmp = 1717774140, tmp)))&(tmp = -2789427438, tmp))%(((tmp = -1386118057, tmp)*(-2333221237.7915535))*(x>>>(((((41346648.46438944)&x)%(-478973697.6792319))|(tmp = 2108106738, tmp))/x)))))-(tmp = -133437701.64136505, tmp))>>>x))+(tmp = -1567210003, tmp))*(x+((x&x)-(2942851671)))))>>>(tmp = -446377136, tmp))*((((((tmp = 1597203255, tmp)>>>(619157171))|(-2766246629.005985))>>((tmp = 3130227370, tmp)%x))*(tmp = 2072227901.6101904, tmp))|((tmp = 1369019520, tmp)^(759659487))))))>>>x)));
- assertEquals(1996475731, x ^= ((1456327892.2281098)|(1728022827)));
- assertEquals(0, x %= x);
- assertEquals(0, x &= (1323847974));
- assertEquals(3076829073.8848357, x += (3076829073.8848357));
- assertEquals(9569842648396755000, x *= (3110293883.2782717));
- assertEquals(9569842646260304000, x -= (2136450372.9038036));
- assertEquals(9.158188827418242e+37, x *= x);
- assertEquals(0, x <<= ((x&(tmp = -2241179286, tmp))+((tmp = 2553144081, tmp)&((tmp = -1914709694, tmp)^(tmp = -1469651409.0651562, tmp)))));
- assertEquals(0, x <<= x);
- assertEquals(0, x /= (2177840666.276347));
- assertEquals(0, x %= (-690827104));
- assertEquals(0, x >>>= x);
- assertEquals(0, x ^= x);
- assertEquals(-0, x /= (tmp = -803415280, tmp));
- assertEquals(-2355576914.316743, x += (-2355576914.316743));
- assertEquals(-833671722514674000, x *= ((3053388806.692315)-(tmp = 2699474775.081724, tmp)));
- assertEquals(1, x /= x);
- assertEquals(1898147684, x += ((tmp = 1898147683, tmp)|(x<<x)));
- assertEquals(2.192324660388075, x %= ((tmp = 2630187518, tmp)/((2868794982.790862)|(490860748))));
- assertEquals(0, x >>>= ((2751021779)/(-952522559)));
- assertEquals(321040461, x ^= ((321040461.153594)-x));
- assertEquals(-2.3814602031636922, x /= ((tmp = -170472190, tmp)|x));
- assertEquals(-1, x >>= (2200125174.177402));
- assertEquals(-2964432647.9379396, x += (-2964432646.9379396));
- assertEquals(-370116502.93793964, x %= (tmp = -518863229, tmp));
- assertEquals(777927355.2283959, x -= (-1148043858.1663356));
- assertEquals(0, x *= ((tmp = 1134913539, tmp)&(((x>>>((tmp = -989822787, tmp)>>>x))%x)&(tmp = 1078636160.7313156, tmp))));
- assertEquals(-1089245637, x ^= (3205721659.3548856));
- assertEquals(-1192493056, x <<= (-1173291054));
- assertEquals(78013832, x += ((tmp = 2462999944, tmp)+x));
- assertEquals(0, x %= x);
- assertEquals(0, x >>>= (1794908927.7409873));
- assertEquals(1708338504, x += ((-2586628792.3484306)<<x));
- assertEquals(12, x >>= (-545794789.3827574));
- assertEquals(0, x &= ((2753207225)<<(((-1776581207.557251)+((tmp = -2414140402, tmp)*x))+(x<<(x|(tmp = 772358560.3022032, tmp))))));
- assertEquals(0, x <<= ((tmp = -2755724712.152605, tmp)/((x>>(-732875466))&x)));
- assertEquals(NaN, x *= (((tmp = 2617815318.1134562, tmp)/x)%(x|((((((-851659337.194871)<<(tmp = 2072294700, tmp))%((x+(2193880878.5566335))^((tmp = 3005338026, tmp)-(2947963290))))/x)/(x+(2091745239.4210382)))-(x>>x)))));
- assertEquals(NaN, x /= (tmp = -427684595.0278094, tmp));
- assertEquals(NaN, x /= (tmp = -263945678, tmp));
- assertEquals(0, x <<= x);
- assertEquals(0, x <<= x);
- assertEquals(0, x -= (((x>>((x&x)-(tmp = -673697315, tmp)))>>(((1575095242.2330558)/(x-(-1816886266)))%(-1580195729)))>>>x));
- assertEquals(0, x >>>= x);
- assertEquals(0, x >>= (-2815518206));
- assertEquals(0, x -= (x/(1795634670.692437)));
- assertEquals(-2753579891, x += (tmp = -2753579891, tmp));
- assertEquals(2.7773776150171776, x /= (tmp = -991431585, tmp));
- assertEquals(5.554755230034355, x += x);
- assertEquals(3.362161997528237e-9, x /= (1652137890.4758453));
- assertEquals(3.362161997528237e-9, x %= (tmp = -10848734.527020693, tmp));
- assertEquals(1, x /= x);
- assertEquals(-2978012493, x -= (x+(2978012493)));
- assertEquals(-5.158905851797543, x /= (((x+((tmp = -2548840164, tmp)>>x))<<(x^((tmp = -533281232.7294345, tmp)&x)))&(tmp = -1502692171, tmp)));
- assertEquals(-5.158905851797543, x %= (-3009435255.5612025));
- assertEquals(-20971520, x <<= ((tmp = -2728812464, tmp)%(2619809573.672677)));
- assertEquals(-1900019712, x &= (2398099552));
- assertEquals(-1991377, x %= ((tmp = 1562364373.7334614, tmp)>>>(((x-(-946283217))<<(-2044590694))^(((tmp = 1681238509, tmp)>>(-2801649769))-x))));
- assertEquals(1, x /= x);
- assertEquals(1, x %= (x/(x-x)));
- assertEquals(1.3525631913093335e-9, x /= (739336991));
- assertEquals(0, x &= ((x&(x|(-1530424204)))<<((((tmp = -295143065.9115021, tmp)>>x)+x)<<x)));
- assertEquals(0, x <<= (-1311017801));
- assertEquals(-0, x /= (-667133339.1918633));
- assertEquals(1038307283, x += (1038307283));
- assertEquals(506985, x >>>= ((tmp = 1550624472.9157984, tmp)^x));
- assertEquals(506985, x >>>= ((254646626)<<(tmp = 1572845412.744642, tmp)));
- assertEquals(32447040, x <<= (tmp = -2427326042, tmp));
- assertEquals(0, x -= (x<<((x|x)>>>x)));
- assertEquals(0, x &= x);
- assertEquals(0, x &= ((-484420357)|((tmp = 807540590.6132902, tmp)/(x/x))));
- assertEquals(-890607324, x ^= ((tmp = -890607324, tmp)>>((((-2876826295)>>x)<<((tmp = 2351495148.117994, tmp)>>(tmp = 1368611893.274765, tmp)))*(tmp = 1531795251, tmp))));
- assertEquals(-729075363, x += (x+(tmp = 1052139285, tmp)));
- assertEquals(531550884933581760, x *= x);
- assertEquals(1980836332, x ^= ((-746269795.2320724)-((2400458512)>>((1290672548)>>>((((1536843439.5629003)&(3185059975.158061))*(tmp = -1339249276.2667086, tmp))&x)))));
- assertEquals(941373096, x %= ((x+(-451098412))^(tmp = 1725497732, tmp)));
- assertEquals(-1766019323, x += (tmp = -2707392419, tmp));
- assertEquals(2528947973, x >>>= (x^(-896237435.3809054)));
- assertEquals(-263192576, x <<= (-866361580));
- assertEquals(-2008, x >>= (-2608071791));
- assertEquals(-88, x %= (((-1076807218.4792447)&((tmp = 601044863, tmp)>>((tmp = 1228976729, tmp)+((((-2711426325)*x)|x)|(x%(-2700007330.3266068))))))&(tmp = 3147972836.778858, tmp)));
- assertEquals(1762886843, x ^= (tmp = 2532080403, tmp));
- assertEquals(1762886843, x %= ((((((tmp = -2059247788, tmp)>>x)/x)+(x<<x))^x)>>>(-1969283040.3683646)));
- assertEquals(4812334726.587896, x += (tmp = 3049447883.587897, tmp));
- assertEquals(1, x /= x);
- assertEquals(1, x *= x);
- assertEquals(-2150507334, x -= ((tmp = 1578221999, tmp)+(tmp = 572285336, tmp)));
- assertEquals(-4546475858941548500, x *= ((tmp = -931533139.5546813, tmp)^(tmp = 3061503275, tmp)));
- assertEquals(-269064192, x |= ((207217276.91936445)<<(tmp = -957353678.4997551, tmp)));
- assertEquals(1, x /= x);
- assertEquals(1, x <<= (((1463856021.8616743)%(x*(tmp = -2286419102, tmp)))/(-2852887593)));
- assertEquals(2223868564.8383617, x *= (tmp = 2223868564.8383617, tmp));
- assertEquals(918797189.9033995, x -= ((1305071374.9349623)%(x+(2211992629))));
- assertEquals(-2212004787.4668465, x -= (tmp = 3130801977.370246, tmp));
- assertEquals(31783, x >>= (2951958960));
- assertEquals(31783, x ^= ((((tmp = -2441511566, tmp)&((tmp = 91427553.90168321, tmp)+((tmp = 3001737720.327718, tmp)%x)))>>>(-2263859841))>>>((2109161329)>>(tmp = -2816295136.7443414, tmp))));
- assertEquals(4068224, x <<= (x%((tmp = -682576250.4464607, tmp)*(x/(((x-x)>>>(x&((((x<<(x<<x))>>>((((2243036981.528562)/(((-1839328916.9411087)>>(-1907748022.162144))<<(x+x)))+((tmp = 2362574171, tmp)<<(tmp = 1987834539, tmp)))|(-444329240)))|(399451601.1717081))>>x)))&(968363335.6089249))))));
- assertEquals(0.0030991932898194294, x /= ((tmp = 1067316540.5529796, tmp)^(-2388640366)));
- assertEquals(0, x >>= x);
- assertEquals(0, x >>>= (tmp = -393433349.1636851, tmp));
- assertEquals(0, x *= (((x^(((1806955787.471396)<<x)^((517668047.55566347)>>>(x%(x<<(tmp = -276586733.4844558, tmp))))))%(1661242196.1472542))|x));
- assertEquals(0, x |= (x>>x));
- assertEquals(-155236210, x |= (tmp = -155236210.19366312, tmp));
- assertEquals(-606392, x >>= ((tmp = -1533446042.97781, tmp)^x));
- assertEquals(-1, x >>= (936126810));
- assertEquals(2325115611, x -= (-2325115612));
- assertEquals(0, x -= x);
- assertEquals(0, x >>= (tmp = -354826623, tmp));
- assertEquals(-0, x *= (-1232528947.7321298));
- assertEquals(0, x |= x);
- assertEquals(0, x <<= (((tmp = 187758893.4254812, tmp)&(x-(tmp = 648201576, tmp)))&(385106597)));
- assertEquals(0, x >>= (tmp = 2554891961, tmp));
- assertEquals(-1311492611.2970417, x += (-1311492611.2970417));
- assertEquals(-688179220.3221785, x += (623313390.9748632));
- assertEquals(1416835528, x &= (tmp = 1953739224, tmp));
- assertEquals(-11.04719252755072, x /= (-128252995));
- assertEquals(-6.287413042114223e-9, x /= (tmp = 1757033052.1558928, tmp));
- assertEquals(-4231171, x |= (((((2022730885.7773404)*((-2495777565.221855)|(tmp = 274627292, tmp)))<<(-3072596920.4902725))>>>((-2215057529)+(-1134713759.4247034)))^((tmp = -1888181788, tmp)/(572025985.2748461))));
- assertEquals(-4194305, x |= ((tmp = 167328318.038759, tmp)>>>(153800904.34551537)));
- assertEquals(-1316525687, x -= (1312331382));
- assertEquals(1448723245.7863903, x += (2765248932.7863903));
- assertEquals(1.7219707102205526, x /= (tmp = 841317008, tmp));
- assertEquals(1872027792.5217001, x *= (x|(tmp = 1087142645.6665378, tmp)));
- assertEquals(3504488055973669400, x *= x);
- assertEquals(-1075254784, x |= x);
- assertEquals(-5, x >>= (((844461331.8957539)-((x&x)<<((tmp = 1443904777, tmp)+(tmp = 736164505.3670597, tmp))))-(((tmp = 1348422110, tmp)>>((tmp = -2878252514, tmp)/(-1175443113)))|((-2138724317)%(2057081133)))));
- assertEquals(-3.038875804165675e-9, x /= (1645345292.8698258));
- assertEquals(1.25204541454491e-18, x /= (-2427129055.274914));
- assertEquals(-1.7151576137235622e-9, x *= (-1369884505.6247284));
- assertEquals(1590804618, x ^= (1590804618.4910607));
- assertEquals(5061318665300252000, x *= (x+x));
- assertEquals(5061318665300252000, x %= ((tmp = 1102144242, tmp)*x));
- assertEquals(-7, x >>= (2772167516.624264));
- assertEquals(16383, x >>>= (-2979259214.5855684));
- assertEquals(47108415435, x *= ((2944456517.839616)>>>(1041288554.5330646)));
- assertEquals(61, x >>>= (x^(((-1305163705)<<((948566605)-x))-x)));
- assertEquals(0, x %= x);
- assertEquals(0, x ^= (((tmp = 1918861879.3521824, tmp)/((x%(tmp = 945292773.7188392, tmp))%(x|x)))>>x));
- assertEquals(-0, x *= ((((x|((2810775287)|(tmp = 1265530406, tmp)))^((tmp = 3198912504.175658, tmp)-(((tmp = 1422607729.281712, tmp)<<(tmp = 2969836271.8682737, tmp))&x)))<<((tmp = 844656612, tmp)*(((((tmp = -828311659, tmp)%(((-2083870654)>>>(x^(((((933133782)-(tmp = 1033670745, tmp))-(629026895.4391923))%((-605095673.8097742)*((((-227510375.38460112)*x)+x)&(((((tmp = 472873752.68609154, tmp)^(tmp = 2815407038.712165, tmp))+((x>>>((tmp = -1331030665.3510115, tmp)>>>(2281234581)))-(x>>>x)))&(tmp = -2160840573.325921, tmp))&x))))<<(tmp = 1411888595, tmp))))|(((tmp = -915703839.0444739, tmp)/((x+(418836101.8158506))%(-1112605325.4404268)))&((-3098311830.6721926)-x))))-((49446671.477988124)*(-2522433127)))+((tmp = 443068797, tmp)>>(tmp = 418030554.97275746, tmp)))*((tmp = 38931296.738208175, tmp)+(1842742215.3282685)))))-((tmp = 1325672181.205841, tmp)^(tmp = 669284428, tmp))));
- assertEquals(-0, x *= (tmp = 93843030, tmp));
- assertEquals(0, x ^= x);
- assertEquals(0, x ^= x);
- assertEquals(0, x <<= x);
- assertEquals(0, x >>>= (x%((((((tmp = -107458601, tmp)>>(x*((x|((tmp = 2117286494, tmp)>>((x^(tmp = 114214295.42048478, tmp))>>>(tmp = 1032826615, tmp))))&((x*x)&(-225386977.67686415)))))^((-780566702.5911419)+(-1113319771)))|(((x^x)<<(1288064444))>>(-2292704291.619477)))>>(365125945))-((tmp = -1986270727.235776, tmp)/x))));
- assertEquals(-0, x *= (((-18925517.67125845)|((((-1975220517)+(tmp = -1250070128.296064, tmp))+(1085931410.5895243))<<(((x|(((x*(tmp = 160207581.50536323, tmp))|(tmp = 1798744469.7958293, tmp))-x))>>>(((x+((x%x)&((((x^x)<<((tmp = 2538012074.623554, tmp)^x))*x)&x)))/(x+(tmp = -2563837407, tmp)))/(tmp = 2189564730, tmp)))/(((-1703793330.5770798)<<((176432492)|x))<<(1347017755.345185)))))<<(((tmp = -577100582.7258489, tmp)&x)/(-31246973))));
- assertEquals(0, x >>>= x);
- assertEquals(NaN, x %= ((x*(tmp = 1167625971, tmp))&(((tmp = -770445060, tmp)>>((339248786)^((2058689781.2387645)-((-2381162024)*(660448066)))))&x)));
- assertEquals(NaN, x += ((3088519732.515986)-(-267270786.06493092)));
- assertEquals(0, x &= (tmp = 2748768426.3393354, tmp));
- assertEquals(-1109969306, x ^= ((-1109969306)>>>x));
- assertEquals(-1109969306, x %= (tmp = 1150376563.581773, tmp));
- assertEquals(-2058145178, x &= (-2057586057));
- assertEquals(-850185626, x |= ((x^(tmp = 1223093422, tmp))&((-589909669)<<(2299786170))));
- assertEquals(1489215443, x += (2339401069));
- assertEquals(-23592960, x <<= x);
- assertEquals(2063937322, x ^= (-2053296342.2317986));
- assertEquals(12922122, x %= (x^((-2259987830)>>(x*(((tmp = -799867804.7716949, tmp)&(tmp = -1068744142, tmp))*(((((1091932754.8596292)-((tmp = -1778727010, tmp)>>(((tmp = 1207737073.2689717, tmp)-(x-(tmp = -1191958946, tmp)))+(-631801383.7488799))))-(-618332177))>>>(-156558558))>>>(3032101547.6262517)))))));
- assertEquals(12922122, x &= x);
- assertEquals(Infinity, x /= (x%x));
- assertEquals(0, x &= (x*(-227800722.62070823)));
- assertEquals(-865648691, x ^= (-865648691));
- assertEquals(1, x /= (x%(tmp = 1524739353.8907173, tmp)));
- assertEquals(16, x <<= (x<<(2335214658.789205)));
- assertEquals(0, x &= ((tmp = 570332368.1239192, tmp)^(-2278439501)));
- assertEquals(1881145344, x -= (((-569715735.8853142)+(2093355159))<<(tmp = 2788920949, tmp)));
- assertEquals(0, x ^= x);
- assertEquals(NaN, x -= ((tmp = -1427789954, tmp)%((((((411038329.49866784)-x)-(x<<((-1330832247)+x)))/x)^((x*(845763550.2134092))>>(tmp = 1427987604.5938706, tmp)))>>>(1857667535))));
- assertEquals(NaN, x /= (-313793473));
- assertEquals(0, x >>>= (x/x));
- assertEquals(1869358566, x -= (-1869358566));
- assertEquals(-1901664519209545200, x += ((tmp = 944729941.3936644, tmp)*(-2012918653)));
- assertEquals(-1901664519209545200, x += ((tmp = 1348246793, tmp)/(x&x)));
- assertEquals(-1576791552, x &= (tmp = 2719250966.739456, tmp));
- assertEquals(-305087899, x ^= (-2955630491.030272));
- assertEquals(0, x ^= (x%(1575252839.559443)));
- assertEquals(4184604407, x += ((((tmp = -244720076.17657042, tmp)|(2819320515))^((((tmp = 1222623743.9184055, tmp)*(-95662379.577173))/(x/(x+(((x-(tmp = -3024718107.6310973, tmp))^(-1494390781))&(tmp = 2284054218.8323536, tmp)))))>>>(tmp = 2090069761, tmp)))>>>(x%x)));
- assertEquals(3148907440, x -= (((tmp = -332379100.7695112, tmp)-(-1145399547))^(((((((tmp = 3133792677.785844, tmp)+x)<<(2306999139.5799255))>>((tmp = -2051266106, tmp)*(((((x+(((-728654312.8954825)>>(x>>>(((x%x)&(-1587152364))|(((((-2114138294)&x)&(1547554688))^x)-(-1856094268)))))*(((-1135018784)&((x+(tmp = -1444020289, tmp))|x))+x)))>>x)&x)/(2449005489))<<((131073798.64314616)%(x>>>((-2592101383.2205048)^(tmp = -757096673.0381112, tmp)))))))^(2766467316.8307915))-(-2465892914.515834))-((((tmp = 234064056, tmp)^((x>>>(1622627548.7944543))+(-1750474146)))|(-1959662039.4687617))^((-1222880974)&(-2794536175.906498))))));
- assertEquals(-1157627488, x &= (-1156639323));
- assertEquals(-1342170624, x <<= ((x/((((1829945345.0613894)/(x*((tmp = 1278865203.0854595, tmp)/(((tmp = -2298274086.519347, tmp)+(tmp = -545203761, tmp))-(tmp = 2712195820, tmp)))))>>>((tmp = 240870798.9384452, tmp)-(tmp = -3188865300.4768195, tmp)))>>>(x%((648799266)>>>(tmp = 24460403.864815235, tmp)))))|((tmp = 232533924, tmp)|x)));
- assertEquals(-2684341248, x += x);
- assertEquals(1073755136, x &= (((-662718514.9245079)>>(tmp = -1915462105, tmp))+(tmp = 1478850441.8689613, tmp)));
- assertEquals(-1073755136, x /= (x|((tmp = -1767915185, tmp)|((325827419.1430224)|(((-1343423676)|(tmp = -1929549501, tmp))|(-866933068.9585254))))));
- assertEquals(-1073755136, x %= ((tmp = 547342356, tmp)-((tmp = 2213249646.7047653, tmp)-((((((-2463314705)^(tmp = -993331620, tmp))^(((x%x)>>(tmp = 1798026491.3658786, tmp))-(((1024072781)/(tmp = -2407354455, tmp))%(1973295010))))<<(-1966787233))^x)|(-1787730004)))));
- assertEquals(-1073754452, x |= (tmp = 3099823788.077907, tmp));
- assertEquals(-1540683096, x &= (-1540674632.7013893));
- assertEquals(-1540683052, x ^= ((tmp = -126183090, tmp)>>>((-622437575.5788481)|((((tmp = -2947914022, tmp)%(((tmp = 2512586745, tmp)>>x)>>>((27238232.23677671)/(tmp = 3203958551, tmp))))/(tmp = 2906005721.402535, tmp))^((((tmp = 1763897860.737334, tmp)^(1445562340.2485332))/x)+(-2393501217.716533))))));
- assertEquals(-1258599433, x |= (tmp = 351291767.59661686, tmp));
- assertEquals(-1241560065, x |= (626346046.5083935));
- assertEquals(-1241560065, x ^= ((2263372092)/((tmp = -2868907862, tmp)>>>x)));
- assertEquals(-893685228, x -= (tmp = -347874837, tmp));
- assertEquals(3401282068, x >>>= (x*x));
- assertEquals(0, x %= x);
- assertEquals(0, x >>>= x);
- assertEquals(-2079237393, x ^= (tmp = 2215729903, tmp));
- assertEquals(NaN, x %= ((((tmp = 3203450436, tmp)/(2867575150.6528325))&(1864945829))&((x&((((tmp = -1927086741.3438427, tmp)|x)|(-1783290909.3240588))*((-1074778499.0697656)*(x-((tmp = -848983542.8456669, tmp)^(tmp = -1324673961, tmp))))))>>(tmp = -2144580304.245896, tmp))));
- assertEquals(-43334009, x |= (x^(-43334009.72683525)));
- assertEquals(-43334009, x &= x);
- assertEquals(-43334009, x %= (tmp = 1252450645.060542, tmp));
- assertEquals(-43334009, x |= (((((((tmp = 968062202, tmp)/(x|(tmp = 2766801984, tmp)))*((2173353793.938968)>>(((tmp = -2459317247, tmp)<<(tmp = -2333601397, tmp))>>>((tmp = -578254251.8969193, tmp)*(tmp = 839964110.7893236, tmp)))))&(((1675305119)&(tmp = -929153707, tmp))*((x*x)*x)))/x)|(x/(tmp = 384740559.43867135, tmp)))%(1657362591)));
- assertEquals(0, x -= x);
- assertEquals(0, x %= (-1334758781.1087842));
- assertEquals(0, x -= x);
- assertEquals(-54, x += ((tmp = -1787151355.470972, tmp)>>((tmp = 237028977, tmp)>>(((2829473542)<<(x>>>(((((((x-(-1950724753))*(((x>>>(2807353513.6283565))<<((-583810779.1155353)>>(x*x)))>>(-1068513265)))^(x^(-696263908.5131407)))%(((tmp = -1325619399, tmp)<<((tmp = -1030194450, tmp)-x))^x))+((-2852768585.3718724)>>(tmp = -3160022361, tmp)))%(x&x))>>(tmp = 2667222702.5454206, tmp))))+((804998368.8915854)<<x)))));
- assertEquals(-54, x %= (-1601267268.4306633));
- assertEquals(1, x >>>= (tmp = -543199585.579128, tmp));
- assertEquals(4.732914708226396e-10, x /= (tmp = 2112862922, tmp));
- assertEquals(-4266932650, x -= ((((x^((((tmp = 2784618443, tmp)^(tmp = -2271260297.9010153, tmp))|((((tmp = -599752639.7516592, tmp)*(2751967680.3680997))^(tmp = -1478450055.578217, tmp))*x))-x))&((tmp = -520061982, tmp)-((tmp = 1400176711.9637299, tmp)^(((2100417541)|(x+(tmp = -674592897.0420957, tmp)))>>x))))^(tmp = -365650686.7947228, tmp))>>>((-2943521813)&(((tmp = -1888789582, tmp)>>(tmp = 700459655.488978, tmp))+(tmp = -1725725703.655931, tmp)))));
- assertEquals(224277168, x <<= (tmp = 2885115011.8229475, tmp));
- assertEquals(224277168, x %= (tmp = -2655345206.442777, tmp));
- assertEquals(850395136, x <<= (x-(((((-769868538.1729524)/((tmp = -298603579, tmp)%(x^x)))+((2691475692)|(((x>>>(628995710.4745524))^(x<<(((tmp = -1046054749, tmp)|(919868171))-x)))^((-1377678789.8170452)&((3065147797)%(tmp = 2638804433, tmp))))))^(tmp = -2036295169, tmp))&(((tmp = -157844758.08476114, tmp)*(tmp = -2819601496, tmp))&((((tmp = 78921441, tmp)<<(653551762.5197772))/(1801316098))*(-1479268961.8276927))))));
- assertEquals(1645565728, x ^= (tmp = 1353013024, tmp));
- assertEquals(1645565728, x >>>= x);
- assertEquals(3020513544, x += (1374947816));
- assertEquals(0, x %= x);
- assertEquals(0, x %= ((((((tmp = -304228072.4115715, tmp)>>>((-90523260.45975709)-(tmp = -3013349171.084838, tmp)))%((-1640997281)*((tmp = -1600634553, tmp)%((tmp = 557387864, tmp)<<((888796080.766409)|(x^((((x%(((((tmp = 1164377954.1041703, tmp)*x)|(2742407432.192806))&((tmp = 1707928950, tmp)<<(1279554132.4481683)))+(tmp = -2108725405.7752397, tmp)))%(tmp = -465060827, tmp))^((tmp = 2422773793, tmp)+x))^((((((((tmp = -1755376249, tmp)^((-267446806)^x))/(((tmp = -1808578662.4939392, tmp)+((tmp = -1997100217, tmp)+x))+(((tmp = -2469853122.411479, tmp)/x)>>(tmp = 660624616.7956645, tmp))))%((x<<((((((tmp = -1701946558, tmp)-(tmp = 133302235, tmp))>>>x)/(738231394))<<(-1060468151.4959564))&(((((-1877380837.4678264)|(tmp = 2366186363, tmp))%x)>>>(-2382914822.1745577))>>((-1874291848.9775913)<<(tmp = 2522973186, tmp)))))<<(-2672141993)))|(tmp = 732379966, tmp))%x)^x)^x))))))))%(tmp = 2385998902.7287374, tmp))*x)+(tmp = -2195749866.017106, tmp)));
- assertEquals(401488, x ^= (((-320896627)>>>(tmp = 2812780333.9572906, tmp))&(tmp = -2088849328, tmp)));
- assertEquals(-1661116571.0046256, x += (tmp = -1661518059.0046256, tmp));
- assertEquals(-1616122720, x <<= x);
- assertEquals(-1616122720, x >>= x);
- assertEquals(-390439413, x %= (tmp = -1225683307, tmp));
- assertEquals(-84189205, x |= ((x|(2054757858))^(((x<<(((x|x)|(((x>>>((-2938303938.1397676)<<((2993545056)^((tmp = -643895708.5427527, tmp)/((1371449825.5345795)-(1896270238.695752))))))-(tmp = 1061837650, tmp))+(x+(tmp = 3072396681, tmp))))>>(x-((((tmp = -1877865355.1550744, tmp)&x)%(-2766344937))>>>(2055121782)))))-((x<<x)|(tmp = -2742351880.1974454, tmp)))<<((-2600270279.219802)>>(-1625612979)))));
- assertEquals(-168378410, x += x);
- assertEquals(-168378410, x &= x);
- assertEquals(-1534983792, x &= (-1501412943));
- assertEquals(-1821543761, x ^= (938439487));
- assertEquals(-1821543761, x &= (x^(((tmp = -4237854, tmp)>>x)/x)));
- assertEquals(2358, x >>>= (2954252724.620632));
- assertEquals(4716, x <<= ((-75522382.8757689)/((tmp = 1074334479, tmp)|((tmp = -720387522, tmp)>>(x>>>(-3085295162.6877327))))));
- assertEquals(-1313079316, x |= (2981887904.020387));
- assertEquals(-1957790646, x -= (644711330));
- assertEquals(17831, x >>>= ((tmp = -2550108342, tmp)-(((tmp = 454671414.0146706, tmp)+(-661129693.9333956))>>(x>>>(((tmp = 1752959432.3473055, tmp)*(-2619510342.1812334))%(tmp = -456773274.2411971, tmp))))));
- assertEquals(689287937.6879716, x -= ((tmp = -397126863.6879716, tmp)-(((x>>x)^(x/(-1387467129.6278908)))|((x>>((tmp = -2361114214.8413954, tmp)<<(tmp = -805670024.4717407, tmp)))<<(-2724018098)))));
- assertEquals(1378575875.3759432, x += x);
- assertEquals(84112428460187.8, x *= (((((2681425112.3513584)%(tmp = -1757945333, tmp))|x)>>(-1793353713.0003397))%x));
- assertEquals(-3221, x >>= (-1976874128));
- assertEquals(-3221, x %= (((tmp = 2318583056.834932, tmp)|((tmp = -1016115125, tmp)+((-472566636.32567954)+x)))|(tmp = 3135899138.065598, tmp)));
- assertEquals(-6596608, x <<= x);
- assertEquals(-1249902592, x <<= (((tmp = -2025951709.5051148, tmp)/((-465639441)<<(-2273423897.9682302)))*((tmp = -2408892408.0294642, tmp)-(tmp = 1017739741, tmp))));
- assertEquals(73802092170444800, x *= (tmp = -59046275, tmp));
- assertEquals(-1619001344, x <<= x);
- assertEquals(0, x <<= (tmp = 1610670303, tmp));
- assertEquals(-0, x *= ((((x+(tmp = 2039867675, tmp))|(tmp = 399355061, tmp))<<(1552355369.313559))^x));
- assertEquals(0, x *= x);
- assertEquals(0, x >>>= (((2875576018.0610805)>>x)%(tmp = -2600467554, tmp)));
- assertEquals(2290405226.139538, x -= (-2290405226.139538));
- assertEquals(0, x %= x);
- assertEquals(0, x ^= (((tmp = 2542309844.485515, tmp)-x)%((-2950029429.0027323)/(tmp = 2943628481, tmp))));
- assertEquals(0, x += x);
- assertEquals(0, x -= x);
- assertEquals(0, x >>>= (tmp = 2337330038, tmp));
- assertEquals(0, x += (x/(((292272669.0808271)&(tmp = 2923699026.224247, tmp))^(tmp = 367745855, tmp))));
- assertEquals(0, x &= x);
- assertEquals(0, x %= ((tmp = 1565155613.3644123, tmp)<<(-308403859.5844681)));
- assertEquals(-1845345399.3731332, x += (tmp = -1845345399.3731332, tmp));
- assertEquals(5158590659731951000, x *= (-2795460763.8680177));
- assertEquals(-364664, x >>= (1837745292.5701954));
- assertEquals(1, x /= x);
- assertEquals(-860616114.8182092, x += ((tmp = 2076961323.1817908, tmp)+(-2937577439)));
- assertEquals(-860616115, x ^= ((x*(tmp = 2841422442.583121, tmp))>>>((tmp = 1929082917.9039137, tmp)>>(-2602087246.7521305))));
- assertEquals(-38387843, x |= (3114677624));
- assertEquals(2927507837, x += (tmp = 2965895680, tmp));
- assertEquals(1, x /= x);
- assertEquals(-1792887531, x *= (-1792887531));
- assertEquals(-0, x %= ((x^x)+x));
- assertEquals(-0, x %= (tmp = 2800752702.562547, tmp));
- assertEquals(1384510548, x ^= (tmp = 1384510548, tmp));
- assertEquals(42251, x >>= (1645421551.363844));
- assertEquals(0, x >>>= (17537561));
- assertEquals(-2076742862, x ^= (tmp = 2218224434, tmp));
- assertEquals(-2.790313825067623, x /= (744268563.3934636));
- assertEquals(5313538, x &= (((((tmp = -2406579239.0691676, tmp)+((-1470174628)+(((tmp = -783981599, tmp)<<(tmp = -1789801141.272646, tmp))^(((((((tmp = -844643189.5616491, tmp)&(tmp = -252337862, tmp))&(x|x))%((-3159642145.7728815)+(tmp = 2149920003.9525595, tmp)))&(x>>(1737589807.9431858)))-((((((((1610161800)<<(497024994))>>x)<<x)/x)>>>x)&x)-(757420763.2141517)))-(tmp = -3061016994.9596977, tmp)))))/(tmp = 1810041920.4089384, tmp))&(tmp = 5887654.786785364, tmp))&((tmp = 1626414403.2432103, tmp)+(x%x))));
- assertEquals(-2147483648, x <<= (tmp = 1304102366.8011155, tmp));
- assertEquals(-208418816, x %= (((((-2850404799)*(x+(3158771063.226051)))*(-2017465205))/(x>>x))>>(x%(tmp = 2760203322, tmp))));
- assertEquals(-2189223477, x -= (1980804661));
- assertEquals(-859239912, x ^= (tmp = 2974421971.3544703, tmp));
- assertEquals(-1599850415, x ^= (tmp = -2475871671.140151, tmp));
- assertEquals(-1600636847, x += ((((tmp = -1311002944, tmp)<<((tmp = -1137871342, tmp)<<(tmp = 115719116, tmp)))/(413107255.6242596))<<(x>>((((-1908022173)&(((-1519897333)^((x>>(x*(tmp = -2886087774.426503, tmp)))*(tmp = 530910975, tmp)))+(-2579617265.889692)))+((2518127437.127563)>>>((tmp = 481642471.56441486, tmp)>>>(792447239))))^(x<<(248857393.6819017))))));
- assertEquals(-191, x >>= (-1591265193));
- assertEquals(-192.27421813247196, x += ((tmp = 2627329028.207775, tmp)/(tmp = -2061914644.9523563, tmp)));
- assertEquals(1230613220, x ^= (tmp = 3064354212.307105, tmp));
- assertEquals(1230613220, x &= x);
- assertEquals(1230613220, x %= (1833479205.1064768));
- assertEquals(1230613220, x >>>= ((((1559450742.1425748)|((2151905260.956583)*(1213275165)))%(514723483.12764716))>>>x));
- assertEquals(1230613493, x |= ((((3004939197.578903)*(tmp = -576274956, tmp))+((tmp = 1037832416.2243971, tmp)^x))>>>(tmp = 2273969109.7735467, tmp)));
- assertEquals(2461226986, x += x);
- assertEquals(-27981, x >>= ((692831755.8048055)^((tmp = -1593598757, tmp)%(x-((((-1470536513.882593)|((tmp = -2716394020.466401, tmp)|(tmp = 2399097686, tmp)))&x)%x)))));
- assertEquals(-1.4660454948034359e+23, x *= (((x>>>((((((tmp = -3056016696, tmp)<<(-2882888332))*(2041143608.321916))&(((tmp = -634710040, tmp)|(tmp = -2559412457, tmp))>>(1916553549.7552106)))%((-2150969350.3643866)*x))<<((x*(tmp = 2657960438.247278, tmp))|x)))%((tmp = 526041379, tmp)*(tmp = 2514771352.4509397, tmp)))*(1219908294.8107886)));
- assertEquals(-1.4660454948034359e+23, x -= ((1709004428)>>(((x|(-422745730.626189))%x)>>x)));
- assertEquals(-2247766068, x %= (-3105435508));
- assertEquals(-386845856.0649812, x -= (-1860920211.9350188));
- assertEquals(-386846803.0649812, x -= ((((-3214465921)|((tmp = -1326329034, tmp)+(((tmp = -1203188938.9833462, tmp)%((((((-1318276502)+(x+x))^((x<<x)%(x>>>x)))+(tmp = -439689881, tmp))+((-1455448168.695214)^(x-((-388589993)>>((((940252202)^(-2218777278))|x)/(tmp = -1007511556, tmp))))))&(-140407706.28176737)))-(x/((888903270.7746506)-((tmp = -2885938478.632409, tmp)<<(((((tmp = -1750518830.270917, tmp)>>(((((((tmp = 868557365.7908674, tmp)/(tmp = -2805687195.5172157, tmp))*x)|((((((-1342484550)-((tmp = 1089284576, tmp)^(tmp = 120651272, tmp)))<<(tmp = 2230578669.4642825, tmp))-(x*x))%(x^(((tmp = -3177941534, tmp)+(x>>(-1595660968)))/(-1738933247))))>>>(tmp = 2860175623, tmp)))-(((2392690115.8475947)>>>(tmp = -1754609670.2068992, tmp))>>>(tmp = 2615573062, tmp)))-(tmp = 2590387730, tmp))^((x+((((x-(tmp = -2823664112.4548965, tmp))*(200070977))>>>(((x|((((tmp = 1361398, tmp)>>((tmp = 1649209268, tmp)%x))+x)+(x>>>(tmp = -2379989262.1245675, tmp))))|(x^((tmp = -647953298.7526417, tmp)-x)))&(tmp = -1881232501.1945808, tmp)))>>>x))%(x^(tmp = -1737853471.005935, tmp)))))>>>(427363558))>>>((tmp = -3076726422.0846386, tmp)^(-1518782569.1853383)))/x)))))))|x)>>>(1854299126)));
- assertEquals(-386846803.0649812, x -= (x%x));
- assertEquals(238532, x >>>= (-448890706.10774803));
- assertEquals(232, x >>>= (-791593878));
- assertEquals(232, x <<= (((x^((x-x)&(tmp = 1219114201, tmp)))/(tmp = -427332955, tmp))%(tmp = 1076283154, tmp)));
- assertEquals(210, x ^= (x>>>((2975097430)>>>x)));
- assertEquals(1, x /= x);
- assertEquals(2317899531, x *= (2317899531));
- assertEquals(1131786, x >>>= x);
- assertEquals(2301667519.6379366, x += ((tmp = 193109669.63793683, tmp)+(tmp = 2107426064, tmp)));
- assertEquals(3842614963.6379366, x += (((-1676516834)>>>(tmp = -1817478916.5658965, tmp))^(((tmp = 1122659711, tmp)>>>(tmp = -2190796437, tmp))|(tmp = -2754023244, tmp))));
- assertEquals(-452352333, x &= x);
- assertEquals(-863, x >>= x);
- assertEquals(-3.777863669459606e-7, x /= (2284359827.424491));
- assertEquals(-3.777863669459606e-7, x %= ((tmp = -2509759238, tmp)>>>x));
- assertEquals(0, x <<= (-814314066.6614306));
- assertEquals(0, x %= (tmp = 190720260, tmp));
- assertEquals(2301702913, x += (2301702913));
- assertEquals(-249158048, x >>= (tmp = -2392013853.302008, tmp));
- assertEquals(-249158048, x >>= x);
- assertEquals(-498316096, x += x);
- assertEquals(-498316096, x %= (tmp = 2981330372.914731, tmp));
- assertEquals(106616.2199211318, x *= (((((tmp = 1020104482.2766557, tmp)^((tmp = -416114189.96786, tmp)>>>(1844055704)))|(tmp = 1665418123, tmp))>>(1826111980.6564898))/(-2446724367)));
- assertEquals(106616, x |= x);
- assertEquals(1094927345, x -= (((-1229759420)|(741260479.7854375))-x));
- assertEquals(8353, x >>= x);
- assertEquals(0, x >>>= (tmp = -327942828, tmp));
- assertEquals(-953397616.8888416, x += (tmp = -953397616.8888416, tmp));
- assertEquals(-1906641240.7776833, x += (x+((-3033450184.9106326)>>>(tmp = 2090901325.5617187, tmp))));
- assertEquals(-1906641240.7776833, x %= (tmp = 2584965124.3953505, tmp));
- assertEquals(-1098907671, x |= (tmp = -1272590495, tmp));
- assertEquals(-1.8305258600334393, x /= (600323489));
- assertEquals(-1, x &= x);
- assertEquals(-1, x |= ((x+x)-x));
- assertEquals(1, x *= x);
- assertEquals(867473898, x ^= (tmp = 867473899.0274491, tmp));
- assertEquals(6, x >>>= (tmp = 1174763611.341228, tmp));
- assertEquals(0, x >>= ((689882795)^(2250084531)));
- assertEquals(0, x /= (tmp = 2545625607, tmp));
- assertEquals(0, x >>= x);
- assertEquals(0, x += x);
- assertEquals(0, x -= (x*(-1098372339.5157008)));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x -= (tmp = -1797344676.375759, tmp));
- assertEquals(1121476698, x |= (tmp = 1121476698, tmp));
- assertEquals(1, x /= x);
- assertEquals(1, x &= (-191233693));
- assertEquals(330137888.92595553, x += (330137887.92595553));
- assertEquals(-1792236714, x ^= (tmp = 2256609910, tmp));
- assertEquals(269000724, x &= (316405813.62093115));
- assertEquals(256, x >>= x);
- assertEquals(256, x %= ((2556320341.54669)|(1066176021.2344948)));
- assertEquals(256, x |= x);
- assertEquals(131072, x <<= ((-1650561175.8467631)|x));
- assertEquals(-286761951, x -= ((tmp = 287024095, tmp)-((-2293511421)&(x|x))));
- assertEquals(-1561852927, x &= (3002663949.0989227));
- assertEquals(-460778761, x %= (tmp = -550537083, tmp));
- assertEquals(-3023749308.0492287, x += (tmp = -2562970547.0492287, tmp));
- assertEquals(-481313332.04922867, x %= ((x|((tmp = -855929299, tmp)%((2181641323)%(x|(220607471.33018696)))))&x));
- assertEquals(17510668, x &= (tmp = 363557663, tmp));
- assertEquals(12552, x &= (3020225307));
- assertEquals(1814655896, x |= ((x<<(((-1475967464)*(-3122830185))*x))+(x^(-2480340864.2661023))));
- assertEquals(-3209124403525266400, x -= ((1146847590)*(tmp = 2798213497, tmp)));
- assertEquals(-6418248807050533000, x += x);
- assertEquals(1.1856589432073933e+28, x *= (-1847324681.313275));
- assertEquals(-1238853292, x ^= (-1238853292));
- assertEquals(-77428331, x >>= (x&((((2043976651.8514216)>>>x)^(x>>>(((tmp = -1785122464.9720652, tmp)%x)<<(1570073474.271266))))*x)));
- assertEquals(2011, x >>>= x);
- assertEquals(2011, x &= x);
- assertEquals(0, x >>= (-2682377538));
- assertEquals(-1.1367252770299785, x -= (((tmp = 2704334195.566802, tmp)/(2379056972))%((((-1764065164)*((((468315142.8822602)>>((x%(((tmp = 2537190513.506641, tmp)+((x&(x|((tmp = -947458639, tmp)^(2653736677.417406))))*((x<<((1243371170.1759553)>>>(((tmp = 1572208816, tmp)<<((tmp = 963855806.1090456, tmp)>>>x))%((-3078281718.7743487)*x))))^(-1154518374))))^(-2839738226.6314087)))^((-2865141241.190915)*(-2400659423.8207664))))>>((tmp = 32940590, tmp)/(tmp = 2917024064.570817, tmp)))+(((27601850)/(tmp = 3168834986, tmp))>>x)))+(tmp = 2528181032.600125, tmp))/(3162473952))));
- assertEquals(-1697395408.7948515, x -= (1697395407.6581264));
- assertEquals(1536992607912062500, x *= (tmp = -905500627.5781817, tmp));
- assertEquals(102759872, x >>= (tmp = -707887133.4484048, tmp));
- assertEquals(102759872, x %= (tmp = -1764067619.7913327, tmp));
- assertEquals(12543, x >>>= (-144142995.1469829));
- assertEquals(-2059555229.2592103, x += ((-2059555229.2592103)-x));
- assertEquals(-537022593, x |= (tmp = -2770761410.407701, tmp));
- assertEquals(23777505, x ^= (-560496738.6854918));
- assertEquals(-64329014115772310, x *= ((tmp = -2729234369.198843, tmp)+x));
- assertEquals(189083830, x ^= (tmp = 933619934, tmp));
- assertEquals(189083830, x %= ((tmp = -2918083254, tmp)-(x|(x^(-2481479224.0329475)))));
- assertEquals(378167660, x += x);
- assertEquals(-0.45833387791900504, x /= ((tmp = 2727991875.241294, tmp)<<(tmp = 2570034571.9084663, tmp)));
- assertEquals(0, x <<= x);
- assertEquals(-0, x /= (tmp = -67528553.30662966, tmp));
- assertEquals(0, x <<= (938440044.3983492));
- assertEquals(-945479171, x ^= (tmp = -945479171, tmp));
- assertEquals(-225632619284361200, x *= (238643670.00884593));
- assertEquals(-0, x %= x);
- assertEquals(-585826304, x ^= ((-1256265560)<<(tmp = 1144713549, tmp)));
- assertEquals(-671583855, x ^= (183333265.1468178));
- assertEquals(-484311040, x <<= x);
- assertEquals(-3969762.62295082, x /= ((((tmp = -1164308668.931008, tmp)-x)%x)>>>(((397816647)>>(-1605343671.4070785))<<x)));
- assertEquals(758097879, x ^= ((tmp = -2871307491, tmp)^(-2043176492.646442)));
- assertEquals(0, x *= ((x>>(tmp = 1983292927, tmp))&(tmp = -860505131.4484091, tmp)));
- assertEquals(0, x <<= x);
- assertEquals(0, x &= x);
- assertEquals(0, x %= ((3132981707)-(-2832016477)));
- assertEquals(0, x >>= (x<<((1830195133.0342631)>>>(tmp = -1003969250, tmp))));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x += (tmp = 273271019.87603223, tmp));
- assertEquals(NaN, x += (625749326.1155348));
- assertEquals(0, x >>= (tmp = -531039433.3702333, tmp));
- assertEquals(0, x -= (((tmp = 2029464099, tmp)-(x-(tmp = -329058111.411458, tmp)))*(x<<x)));
- assertEquals(-0, x *= ((-1112957170.5613296)|((tmp = 847344494, tmp)>>>(tmp = 2735119927, tmp))));
- assertEquals(-0, x /= (tmp = 544636506, tmp));
- assertEquals(0, x >>>= (x^(545093699)));
- assertEquals(0, x %= (((tmp = -2208409647.5052004, tmp)+(3083455385.374988))+(((-482178732.7077277)*x)>>>((2661060565)*(-2125201239)))));
- assertEquals(0, x >>>= (-212334007.34016395));
- assertEquals(0.7004300865203454, x -= ((2032883941)/(-2902336693.0154715)));
- assertEquals(0, x <<= (x<<((265868133.50175047)>>>(1162631094))));
- assertEquals(604920272.4394834, x -= (-604920272.4394834));
- assertEquals(604920272, x &= x);
- assertEquals(0, x <<= (((-1961880051.1127694)%(tmp = 1715021796, tmp))|((tmp = 2474759639.4587016, tmp)|(243416152.55635))));
- assertEquals(-46419074, x |= (((tmp = -518945938.5238774, tmp)%((x+(tmp = 242636408, tmp))+(-1974062910)))|(1546269242.0259726)));
- assertEquals(-46419074, x += ((-629802130)*((tmp = -658144149, tmp)%((-905005358.5370393)>>>x))));
- assertEquals(-46419074, x |= (x%(-1103652494)));
- assertEquals(7892881050983985, x *= (-170035297.36469936));
- assertEquals(1105701997.4273424, x %= ((((-490612260.0023911)>>>(tmp = 1803426906, tmp))^(x%(2725270344.2568116)))-(1010563167.8934317)));
- assertEquals(1088619532, x &= (-2232199650));
- assertEquals(1073807364, x &= (-888024506.5008001));
- assertEquals(1153062254980628500, x *= x);
- assertEquals(1153062255703627000, x -= (tmp = -722998613.897227, tmp));
- assertEquals(-1141418584, x |= (3017232552.4814596));
- assertEquals(-373464140, x ^= (-2914372068));
- assertEquals(994050048, x <<= x);
- assertEquals(0, x ^= x);
- assertEquals(0, x &= (tmp = -3166402389, tmp));
- assertEquals(0, x &= ((-1760842506.337213)|(tmp = 2538748127.795164, tmp)));
- assertEquals(-0, x /= (-2635127769.808626));
- assertEquals(0, x &= ((((tmp = 1414701581, tmp)^(((2425608769)/((x<<x)^(x-x)))^((tmp = -2641946468.737288, tmp)|(tmp = -313564549.1754241, tmp))))*(tmp = -2126027460, tmp))|(-2255015479)));
- assertEquals(225482894, x ^= (225482894.8767246));
- assertEquals(0, x ^= x);
- assertEquals(306216231, x += (tmp = 306216231, tmp));
- assertEquals(306216231, x -= ((-465875275.19848967)&((-806775661.4260025)/((((-184966089.49763203)>>>((x>>x)+((tmp = -1951107532, tmp)|x)))%x)*((2704859526.4047284)%((x*x)>>x))))));
- assertEquals(30754, x &= (1706162402.033193));
- assertEquals(30454.010307602264, x -= (((590456519)>>>(tmp = 2713582726.8181214, tmp))/x));
- assertEquals(8419062, x |= ((2848886788)<<(tmp = 2993383029.402275, tmp)));
- assertEquals(16, x >>= (tmp = -1651287021, tmp));
- assertEquals(1, x /= x);
- assertEquals(-1407643485, x ^= (-1407643486));
- assertEquals(2, x >>>= (-1126004674));
- assertEquals(470812081, x ^= ((-2411718964)>>>x));
- assertEquals(550443688.6407901, x += (tmp = 79631607.6407901, tmp));
- assertEquals(3669092443.64079, x -= (-3118648755));
- assertEquals(-625874853, x <<= (((tmp = -1640437346, tmp)/(((x*x)>>>x)<<x))/x));
- assertEquals(-1431439050363516700, x *= (2287101077));
- assertEquals(-1921660672, x |= ((((((((-1912249689.9978154)&(-1676922742.5343294))*(2625527768))<<((820676465)^(((x+(tmp = -852743692, tmp))&((x-((((1361714551)/(311531668))>>>(tmp = -1330495518.8175917, tmp))<<(((tmp = 1369938417.8760853, tmp)*(-1217947853.8942266))<<(-2048029668))))-(-513455284)))>>>(tmp = 1980267333.6201067, tmp))))<<(((1503464217.2901971)>>(tmp = 2258265389, tmp))>>>(1868451148)))&(x-(x^(tmp = -1565209787, tmp))))*x)<<(tmp = -2426550685, tmp)));
- assertEquals(-1921660672, x %= (((tmp = 523950472.3315773, tmp)+(((2971865706)^x)-x))&(-1773969177)));
- assertEquals(420176973.1169958, x += (2341837645.116996));
- assertEquals(420176973, x >>>= (((tmp = -2485489141, tmp)<<((tmp = -2520928568.360244, tmp)+x))&(543950045.0932506)));
- assertEquals(50, x ^= (x|((tmp = 2001660699.5898843, tmp)>>>(tmp = 1209151128, tmp))));
- assertEquals(138212770720.96973, x *= (2764255414.4193945));
- assertEquals(-28683, x |= (((-535647551)|x)>>((((2065261509)>>(-354214733))*x)+(-3218217378.2592907))));
- assertEquals(1627048838, x ^= (tmp = -1627044749, tmp));
- assertEquals(-839408795, x ^= (2903337187.480303));
- assertEquals(-1000652427, x += (tmp = -161243632, tmp));
- assertEquals(740237908.4196916, x += ((tmp = 1587000348, tmp)+(tmp = 153889987.41969144, tmp)));
- assertEquals(Infinity, x /= (((((-615607376.1012697)&(57343184.023578644))+((-1967741575)|(-3082318496)))<<(((tmp = -958212971.99792, tmp)>>(tmp = 2962656321.3519197, tmp))-(x|(x*(969365195)))))<<(tmp = -1739470562.344624, tmp)));
- assertEquals(-Infinity, x /= ((tmp = -1736849852, tmp)%x));
- assertEquals(0, x <<= x);
- assertEquals(0, x %= (tmp = -226505646, tmp));
- assertEquals(1982856549, x -= (((x+(-1982856549))%(-2274946222))>>(x%(((tmp = -1289577208.9097936, tmp)>>x)^(778147661)))));
- assertEquals(1648018703, x ^= ((3085618856)+((tmp = 1546283467, tmp)&(((x|((-2376306530)*(((((((tmp = -2807616416, tmp)%(((((tmp = 347097983.1491085, tmp)<<x)|(((((1135380667)/(x>>>(tmp = 1679395106, tmp)))^((1277761947)<<((tmp = -1614841203.5244312, tmp)>>x)))%((tmp = 1552249234.2065845, tmp)>>>x))>>>(tmp = -1677859287, tmp)))>>>(2605907565))/(tmp = 2291657422.221277, tmp)))%(((tmp = 425501732.6666014, tmp)>>>(1327403879.455553))+x))>>((tmp = -3075752653.2474413, tmp)&(x-(tmp = -71834630, tmp))))|((((2532199449.6500597)*(-842197612.4577162))%x)>>x))*(((1220047194.5100307)<<((tmp = 1642962251, tmp)<<((-662340)>>>((tmp = -1672316631.3251066, tmp)<<((tmp = 1762690952.542441, tmp)-(x/(1904755683.3277364)))))))>>x))|(((((tmp = 1625817700.7052522, tmp)%(tmp = -2990984460, tmp))|(2395645662))-((2619930607.550086)>>x))^(tmp = 130618712, tmp)))))&((-3142462204.4628367)/(1078126534.8819227)))%(((tmp = -256343715.2267704, tmp)+x)^(tmp = 2009243755, tmp))))));
- assertEquals(1937698223, x |= (((tmp = 866354374.7435778, tmp)+(tmp = 2751925259.3264275, tmp))%(-2252220455)));
- assertEquals(0, x -= x);
- assertEquals(-823946290.6515498, x -= (tmp = 823946290.6515498, tmp));
- assertEquals(706970324, x ^= (-457174758));
- assertEquals(32916, x &= (25740724));
- assertEquals(0, x >>>= ((-1658933418.6445677)|(tmp = -846929510.4794133, tmp)));
- assertEquals(0, x ^= ((-834208600)/((-1256752740)&(tmp = 1973248337.8973258, tmp))));
- assertEquals(-1639195806, x += (-1639195806));
- assertEquals(-1559416478, x ^= ((tmp = 1349893449.0193534, tmp)*(tmp = 2044785568.1713037, tmp)));
- assertEquals(0, x &= ((x>>(tmp = 1720833612, tmp))/((x+(-1305879952.5854573))^x)));
- assertEquals(-0, x *= (tmp = -1713182743, tmp));
- assertEquals(0, x >>= x);
- assertEquals(NaN, x /= (((x%((x>>>(((-1515761763.5499895)^(-3076528507.626539))<<(tmp = 1293944457.8983147, tmp)))<<(tmp = 276867491.8483894, tmp)))>>(tmp = -2831726496.6887417, tmp))%((((tmp = 1780632637.3666987, tmp)^x)%((208921173.18897665)>>(tmp = 633138136, tmp)))+x)));
- assertEquals(0, x >>= (tmp = -2755513767.0561147, tmp));
- assertEquals(0, x |= x);
- assertEquals(840992300.0324914, x -= ((-840992300.0324914)+x));
- assertEquals(840992300, x &= x);
- assertEquals(-1094140277, x ^= (2364029095));
- assertEquals(-Infinity, x /= ((((((1257084956)<<(2009241695))>>(x+x))*x)>>>x)>>>(205318919.85870552)));
- assertEquals(-Infinity, x -= (((x>>>(tmp = 3037168809.20163, tmp))&x)*(x&(((806151109)*x)-(tmp = -1741679480.58333, tmp)))));
- assertEquals(400659949, x ^= (tmp = 400659949, tmp));
- assertEquals(5, x >>= (tmp = 1175519290, tmp));
- assertEquals(5, x |= x);
- assertEquals(0, x >>= x);
- assertEquals(0, x >>= ((1317772443)&(x<<x)));
- assertEquals(-1123981819, x ^= (tmp = 3170985477, tmp));
- assertEquals(1123864651, x ^= ((x%(((x&x)&(-2606227299.7590737))<<((tmp = -2018123078.1859496, tmp)*x)))|(x+(((((1935939774.8139446)/((-1303958190)/(2802816697.32639)))<<((2880056582)*x))+x)+x))));
- assertEquals(1543368927, x |= (-2795691884));
- assertEquals(NaN, x /= (x%((tmp = -1129915114, tmp)<<x)));
- assertEquals(NaN, x += (tmp = -3045743135, tmp));
- assertEquals(NaN, x -= (tmp = -2849555731.8207827, tmp));
- assertEquals(NaN, x /= (((((2127485827)>>>((((tmp = 363239924, tmp)>>x)|((((tmp = -1419142286.0523334, tmp)-(x<<x))^(tmp = -1990365089.8283136, tmp))*((tmp = 2780242444.0739098, tmp)>>>(((-2336511023.342298)&x)/(tmp = 2296926221.402897, tmp)))))>>((tmp = 1378982475.6839466, tmp)>>(tmp = -816522530, tmp))))&(x^(tmp = -1668642255.0586753, tmp)))%(((tmp = 921249300.1500335, tmp)^x)*(tmp = -2228816905, tmp)))>>x));
- assertEquals(-1460685191, x |= (tmp = 2834282105, tmp));
- assertEquals(-1463439264, x &= (tmp = 2881860064.146755, tmp));
- assertEquals(20.98100714963762, x /= (((3017150580.7875347)^((250499372.5339837)<<(tmp = -42767556.30788112, tmp)))|(x%(-2829281526))));
- assertEquals(1, x /= x);
- assertEquals(2, x += x);
- assertEquals(8, x <<= x);
- assertEquals(0, x >>>= ((730174750)>>>x));
- assertEquals(0, x ^= x);
- assertEquals(-1459637373, x ^= (2835329923.456409));
- assertEquals(-1233115861, x ^= (511678120));
- assertEquals(95682857, x >>>= ((tmp = 1534570885, tmp)|(tmp = -414425499.3786578, tmp)));
- assertEquals(70254633, x &= (-1502067585));
- assertEquals(51384749748909710, x *= (tmp = 731407276, tmp));
- assertEquals(9390482.873469353, x %= (tmp = -592576964.7982686, tmp));
- assertEquals(4695241, x >>>= (tmp = -1879898431.5395758, tmp));
- assertEquals(-3129811912538149000, x += (((-727481809)^((3106908604)%x))*((((tmp = -1218123690, tmp)^(x>>((-942923806)^x)))/(x+x))>>>(-1508881888.969373))));
- assertEquals(1596870236, x ^= (-1135673764.9721224));
- assertEquals(0, x ^= x);
- assertEquals(2133782410, x |= (((-2202469371)>>((tmp = 1327588406.183342, tmp)/(tmp = 253581265.7246865, tmp)))-((tmp = 2226575446.838795, tmp)^x)));
- assertEquals(-81895217.83608055, x -= (tmp = 2215677627.8360806, tmp));
- assertEquals(812089344, x <<= ((tmp = 882824005, tmp)/(((x>>((((((((tmp = 1211145185, tmp)/((-137817273)-(((tmp = 2165480503.1144185, tmp)-(-1840859887.1288517))*((155886014.8393339)>>((-1984526598)<<(tmp = 1331249058.3246582, tmp))))))>>(x*x))%(2830324652))%(933701061))|(1346496215))^(tmp = -988800810, tmp))+x))>>>x)<<(-2372088384))));
- assertEquals(812089344, x <<= x);
- assertEquals(8472, x %= ((((x|(((x%(tmp = 2772099481.664402, tmp))+(2894690616))-x))&(x&(((-715790638.6454093)>>(tmp = -1447931029, tmp))-(tmp = 1761027889, tmp))))^x)%(((tmp = 830969811, tmp)|x)|((-1102267929)-(3193018687)))));
- assertEquals(-0.0000028559857417864914, x /= (-2966401364));
- assertEquals(0, x >>= x);
- assertEquals(-701800392, x += (tmp = -701800392, tmp));
- assertEquals(2034756873, x -= (tmp = -2736557265, tmp));
- assertEquals(-0.9475075048394501, x /= (((((82879340.27231383)+((tmp = -2876678920.653639, tmp)*(-2801097850)))<<x)>>>((x<<(((((x|x)&(tmp = -1572694766, tmp))>>(x+(x/((x-(((tmp = 1435301275, tmp)|(tmp = 983577854.212041, tmp))>>(tmp = 632633852.1644179, tmp)))+x))))>>>x)|(-850932021)))>>x))<<(-821983991)));
- assertEquals(0, x >>= (x>>(2424003553.0883207)));
- assertEquals(2599386349, x -= (-2599386349));
- assertEquals(-68157441, x |= (((tmp = -1170343454.9327996, tmp)+((((tmp = 448468098, tmp)|(x>>(x>>(((x>>(((x/(x&(x<<x)))<<(2436876051.2588806))^(3010167261)))%((tmp = 2577616315.7538686, tmp)>>>(-2953152591.015912)))%((tmp = -1304628613, tmp)/(x&((x|((-2000952119)%((691146914)/((tmp = 1480966978.7766845, tmp)<<((tmp = 2644449477.392441, tmp)|(-2143869305.871568))))))+(tmp = -315254308, tmp))))))))&(-2060205555))|((-604140518.8186448)^(x*x))))%(x*((tmp = 1383244000.2807684, tmp)/(3195793656)))));
- assertEquals(-68157441, x |= x);
- assertEquals(-1, x >>= x);
- assertEquals(-2147483648, x <<= x);
- assertEquals(-1.5257198286933313, x /= (tmp = 1407521622, tmp));
- assertEquals(1149084989.47428, x += (((tmp = 1149084991.9004865, tmp)&x)^((((((2797053000)/(x^x))*(-2829253694))>>>((tmp = -610924351, tmp)>>x))>>>(tmp = -675681012, tmp))<<(2812852729))));
- assertEquals(0, x %= x);
- assertEquals(0, x <<= ((tmp = -584069073, tmp)*(-2953140326)));
- assertEquals(0, x <<= (tmp = -481515023.6404002, tmp));
- assertEquals(-1441535370, x ^= (2853431926));
- assertEquals(2853431926, x >>>= (((((((tmp = 2215663525.9620194, tmp)%((-1102832735.9274108)/x))>>x)&(3220898702.76322))&(((2077584946)*((x>>x)<<((tmp = 1845701049, tmp)-x)))/(tmp = 1947184202.5737212, tmp)))|(((tmp = 2976351488, tmp)^(-42517339))%((2648230244.410125)^(1520051731.31089))))/(1761635964)));
- assertEquals(43539, x >>>= (tmp = 1361671184.7432632, tmp));
- assertEquals(21769, x >>= ((tmp = -804932298.9572575, tmp)>>((((tmp = 1749006993.253409, tmp)+(276536978))^x)|(2698166994))));
- assertEquals(1103025563, x |= (tmp = 1103007891, tmp));
- assertEquals(1327594607, x += (tmp = 224569044, tmp));
- assertEquals(1327594607, x |= x);
- assertEquals(-478674944, x <<= (((672378508)&x)^(((-2070209708.6470091)|x)|(x>>>x))));
- assertEquals(-478674943, x ^= ((-1832457698.6345716)>>>((tmp = -3077714019, tmp)/(1809383028))));
- assertEquals(229129701056053250, x *= x);
- assertEquals(1, x /= x);
- assertEquals(2, x <<= (-1522529727));
- assertEquals(2, x &= x);
- assertEquals(-2016989182, x |= ((((tmp = -1267845511, tmp)*(1225350332))+((tmp = -1397690831.5717893, tmp)>>>(tmp = -2575382994, tmp)))+x));
- assertEquals(-241, x >>= (tmp = 931869591, tmp));
- assertEquals(-1048087547, x &= (tmp = -1048087403.1163051, tmp));
- assertEquals(-4004486369.844599, x += (tmp = -2956398822.844599, tmp));
- assertEquals(-4004486368.844599, x -= (((2701878498)>>x)|(x|(-1079354967))));
- assertEquals(1, x >>= (tmp = -1583689092, tmp));
- assertEquals(1, x *= (x>>(x%x)));
- assertEquals(0, x %= x);
- assertEquals(-0, x *= (-120818969));
- assertEquals(0, x >>= ((tmp = 1794099660, tmp)/(((x&(((-321906091)^(tmp = -3009885933.8449526, tmp))&((tmp = -140917780, tmp)|(2037803173.4075825))))&x)&(tmp = -745357154, tmp))));
- assertEquals(0, x <<= (563984257.3493614));
- assertEquals(NaN, x %= ((((x>>(tmp = -2190891392.320677, tmp))-x)<<(462714956))<<((tmp = -84413570, tmp)|((x|(-2787022855))-((tmp = 2028532622, tmp)|(tmp = 1103757073.9178817, tmp))))));
- assertEquals(NaN, x *= ((2137674085.3142445)|((tmp = -1054749859.2353804, tmp)%x)));
- assertEquals(NaN, x /= (x>>>(((((tmp = 597103360.9069608, tmp)>>>(-2850217714.1866236))-((tmp = 1125150527, tmp)*x))%(tmp = -982662312, tmp))|((x/(((968656808.6069037)*(((128484784.15362918)>>x)^x))&((((x/((((tmp = 748775979, tmp)*((x-(((tmp = 709571811.9883962, tmp)%(-2083567026))%(x/(tmp = -680467505, tmp))))/((tmp = -167543858, tmp)/(tmp = -3113588783, tmp))))/x)<<(-2605415230)))>>>(tmp = 3133054172, tmp))%(tmp = -1904650393, tmp))*((x|(-1193709562))*(tmp = -1731312795.718104, tmp)))))/((tmp = -672386301, tmp)/(tmp = 808898833.4163612, tmp))))));
- assertEquals(-9, x |= (((((tmp = 150377964.57195818, tmp)/(tmp = 2161910879.0514045, tmp))-(-2381625849))>>(-2715928517))/(((452113643)^(-2502232011))/((-3076471740)^(((tmp = 1664851172, tmp)*(((-1460011714)>>>x)<<((-2870606437)%x)))*((tmp = -2836565755.609597, tmp)-((x/(tmp = -871461415, tmp))-(2278867564))))))));
- assertEquals(-1, x >>= x);
- assertEquals(-1, x |= ((-1319927272)>>>(-2866709980)));
- assertEquals(-1, x >>= ((2345179803.155703)&(-978025218.2243443)));
- assertEquals(1, x /= x);
- assertEquals(-260730973, x |= (tmp = -260730973, tmp));
- assertEquals(1174405120, x <<= (2681054073));
- assertEquals(1174405120, x &= x);
- assertEquals(1073741824, x &= (tmp = 2017166572.7622075, tmp));
- assertEquals(1073741824, x |= x);
- assertEquals(168806102, x %= ((((tmp = -2939969193.950067, tmp)|((-2325174027.614815)/(-2329212715)))*(x/(((((-2927776738)/(x|x))+(x%(tmp = -3007347037.698492, tmp)))<<(-1898633380))>>(tmp = 204338085.45241892, tmp))))^x));
- assertEquals(168806102, x %= ((-832849739.5197744)&(tmp = -141908598, tmp)));
- assertEquals(-401033205.05225074, x -= (tmp = 569839307.0522507, tmp));
- assertEquals(-401033205, x &= x);
- assertEquals(-401130402, x ^= ((x*(tmp = 311418759.22436893, tmp))>>x));
- assertEquals(793533469, x ^= (-950312893.5201888));
- assertEquals(756, x >>>= (-1096189516));
- assertEquals(711, x += ((tmp = -753105189, tmp)>>(599823192.5381484)));
- assertEquals(0, x >>>= ((tmp = -2859668634.4641137, tmp)+(-1160392986.1521513)));
- assertEquals(2427599726.176195, x -= (-2427599726.176195));
- assertEquals(1942312465.2523103, x -= (485287260.92388475));
- assertEquals(0, x >>>= ((tmp = -1740656456, tmp)/(tmp = 1339746799.9335847, tmp)));
- assertEquals(0, x <<= ((-7017077.38786912)*((-699490904.4551768)^x)));
- assertEquals(0, x <<= (tmp = 715662384, tmp));
- assertEquals(0, x *= (x>>>(2149735450.0758677)));
- assertEquals(NaN, x /= x);
- assertEquals(0, x >>= ((397078885)*((851639692.8982519)-x)));
- assertEquals(0, x &= (-2526654445));
- assertEquals(0, x %= (-1204924598));
- assertEquals(251639720, x ^= (x|(tmp = 251639720, tmp)));
- assertEquals(695433573, x ^= (663539405));
- assertEquals(-1038050104, x -= (1733483677));
- assertEquals(0, x ^= x);
- assertEquals(NaN, x %= x);
- assertEquals(0, x &= (392107269));
- assertEquals(0, x %= (-3084908458.241551));
- assertEquals(0, x ^= x);
- assertEquals(-2121660509, x ^= (tmp = -2121660509.7861986, tmp));
- assertEquals(2285041855588855800, x *= (x|(3209046634)));
- assertEquals(54915072, x >>>= (x%(((((x%((((tmp = -1429433339.5078833, tmp)|(tmp = 2906845137, tmp))^(3207260333))&(-848438650)))-(-2721099735))&(141851917.19978714))+x)/x)));
- assertEquals(54915072, x &= x);
- assertEquals(54915072, x %= (x+(1855489160)));
- assertEquals(70078753, x ^= ((((((-1648661736)+(x%((-1421237596)+(tmp = 2053180992.3857927, tmp))))+(tmp = 38606889, tmp))<<((-241334284)%((x>>(215316122))*(tmp = 396488307, tmp))))+((tmp = -2900704565, tmp)^x))^(((1103481003.1111188)^x)-(tmp = 1304113534, tmp))));
- assertEquals(1149501440, x <<= ((x>>(tmp = 3203172843, tmp))*(tmp = -192535531, tmp)));
- assertEquals(0, x ^= x);
- assertEquals(0, x >>= ((tmp = 2751499787, tmp)&((tmp = 2217654798, tmp)*(tmp = -2798728014, tmp))));
- assertEquals(NaN, x /= ((((-2019592425)>>>((((-1571930240.741224)>>>((-183952981)/((((1990518443.672842)>>(((((2051371284)%(685322833.6793983))>>>(2662885938))<<(-1212029669.6675105))|((-2790877875)<<(1546643473))))<<x)-(tmp = 804296674.4579233, tmp))))-(tmp = -417759051.68770766, tmp))/((-621859758)>>>x)))&x)<<(tmp = -48558935.55320549, tmp)));
- assertEquals(0, x <<= (x&x));
- assertEquals(0, x *= (x%(tmp = 301196068, tmp)));
- assertEquals(398290944, x |= (((tmp = 1904146839, tmp)+(1521017178))*(-3174245888.562067)));
- assertEquals(1256401076, x ^= (1566464180));
- assertEquals(149620758, x %= ((tmp = 532626355, tmp)^(tmp = -382971203, tmp)));
- assertEquals(149620791, x |= (x>>x));
- assertEquals(-0.07034576194938641, x /= ((tmp = -1977313182.7573922, tmp)-x));
- assertEquals(0, x <<= x);
- assertEquals(0, x &= x);
- assertEquals(0, x /= ((2182424851.139966)%(((-2768516150)+x)>>>x)));
- assertEquals(0, x %= (-504299638.53962016));
- assertEquals(-0, x *= (-2915134629.6909094));
- assertEquals(0, x <<= ((tmp = 952692723.402582, tmp)%(2146335996.785011)));
- assertEquals(230457472, x |= ((tmp = -574776101.8681948, tmp)*(683185125)));
- assertEquals(933795934, x ^= (tmp = 974395614, tmp));
- assertEquals(933801974, x ^= (x>>>((-148683729)*(((tmp = 2912596991.415531, tmp)^(-2883672328))/x))));
- assertEquals(222, x >>= (-3060224682));
- assertEquals(27, x >>>= (1429156099.1338701));
- assertEquals(754519106, x ^= (tmp = 754519129.7281355, tmp));
- assertEquals(188629776, x >>>= ((x>>>((1247267193)<<(tmp = -936228622, tmp)))%((tmp = 978604324.8236886, tmp)*((tmp = -3018953108, tmp)^(((tmp = 259650195, tmp)>>>(tmp = 2762928902.7901163, tmp))*(x>>((tmp = 787444263.5542864, tmp)/(x>>>(((-2039193776)<<(tmp = -1408159169, tmp))-(1238893783))))))))));
- assertEquals(188629775.33987066, x += ((tmp = 1040520414, tmp)/((-1576237184)|((tmp = -970083705, tmp)&(((tmp = -312062761.12228274, tmp)|(1171754278.2968853))<<(-2069846597.7723892))))));
- assertEquals(1473670, x >>>= ((tmp = 202409672, tmp)^x));
- assertEquals(2171703268900, x *= (x>>(((tmp = 840468550, tmp)&(-3208057101.2136793))/x)));
- assertEquals(0, x ^= x);
- assertEquals(0, x ^= (x&((tmp = 2569871408.2405066, tmp)|((tmp = -3149374622, tmp)<<(x-(x|((tmp = -821239139.1626894, tmp)>>>x)))))));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x %= (tmp = 1926106354, tmp));
- assertEquals(0, x >>= ((x/(-2848416))/(tmp = 2484293767, tmp)));
- assertEquals(0, x <<= ((tmp = -2484137114, tmp)>>>(tmp = -887083772.8318355, tmp)));
- assertEquals(0, x >>= (tmp = -2651389432, tmp));
- assertEquals(0, x ^= x);
- assertEquals(1041871201, x += ((tmp = 1041871201.9272791, tmp)|(x<<(-1136959830))));
- assertEquals(651390879501530900, x *= ((tmp = 1250424964.0346212, tmp)>>x));
- assertEquals(1965815296.245636, x %= ((2650603245.655831)+((-1610821947.8640454)>>>(((878987151.6917406)*((((784630543)%(((1448720244)>>(((tmp = 3036767847, tmp)+((tmp = 1012548422, tmp)<<(1957000200)))-x))/(x>>x)))<<((tmp = 914710268, tmp)*(((x^(1559603121))<<(tmp = 3181816736, tmp))|((-1964115655)+x))))-(-1055603890)))&(946797797.0616649)))));
- assertEquals(1965815296.245636, x %= (tmp = -2601038357.593118, tmp));
- assertEquals(-769384440.872302, x += (-2735199737.117938));
- assertEquals(-769384440.872302, x %= (2193123162));
- assertEquals(1, x /= x);
- assertEquals(1, x -= (((x>>>(-1968465925))*((tmp = 563037904, tmp)>>((tmp = 3009534415.769578, tmp)>>((-2567240601.7038674)<<(tmp = -1258402723.4150183, tmp)))))%(3112239470.276867)));
- assertEquals(1, x |= x);
- assertEquals(1505461527, x ^= (tmp = 1505461526.5858076, tmp));
- assertEquals(406553877, x &= (tmp = 2558242293, tmp));
- assertEquals(406553877, x |= x);
- assertEquals(-574902339, x |= ((-709809495)%(tmp = -2880884811.410611, tmp)));
- assertEquals(-20281777.349363208, x %= (22184822.46602547));
- assertEquals(1, x /= x);
- assertEquals(-4360732, x ^= ((x|(tmp = 3178620274, tmp))>>(((2686286888)&(((-1107223053.8716578)/(((-2955575332.3675404)+(-2770518721))|(-2705016953.640522)))-x))^((1473641110.4633303)*((((-1466496401)<<x)+x)%(1805868749.082736))))));
- assertEquals(-1158545408, x <<= ((((x/((-2710098221.691819)-(-2421462965.788145)))/(((((x>>>(tmp = 1994541591.1032422, tmp))+(tmp = -1276676679.9747126, tmp))&((tmp = 1764029634.2493339, tmp)+((x|(tmp = -3050446156, tmp))-((tmp = -9441859, tmp)/(((-2072420232)&x)*(-1003199889))))))+(tmp = -2443230628, tmp))*x))*((x&((((x|(747566933))*(((2039741506)>>>((tmp = -2456000554, tmp)>>>(-1566360933.7788877)))^((tmp = 960600745, tmp)/x)))&(x^(((-2649310348.777452)^((2224282875)-(tmp = -2129141087.3182096, tmp)))<<((x<<x)+((-1307892509.3874407)-(x|(tmp = -2831643528.9720087, tmp)))))))/(((tmp = -35502946, tmp)<<((tmp = 1091279222, tmp)>>(((-2686069468.8930416)-x)+(tmp = 367442353.2904701, tmp))))%(1218262628))))/x))^(-919079153.7857773)));
- assertEquals(747, x >>>= (1229157974));
- assertEquals(747, x |= x);
- assertEquals(NaN, x %= (((3086718766.4715977)*((7912648.497568846)*((-2713828337.1659327)*(-176492425.4011252))))<<(tmp = -1074475173, tmp)));
- assertEquals(0, x >>>= ((((444923201)<<x)>>>(-883391420.2142565))*((((617245412)<<x)>>>x)*(-913086143.2793813))));
- assertEquals(1941802406, x ^= (tmp = -2353164890, tmp));
- assertEquals(14, x >>>= (-1600311077.4571416));
- assertEquals(-18229482703.7246, x += (((x+(-993157139.7880647))%x)*(1862419512.1781366)));
- assertEquals(-14.531388114858734, x /= ((tmp = -1649072797.951641, tmp)<<x));
- assertEquals(0, x ^= x);
- assertEquals(0, x >>= ((x/x)^x));
- assertEquals(2, x ^= ((-1597416259)/(-738770020)));
- assertEquals(0, x >>= (tmp = -387850072.74833393, tmp));
- assertEquals(0, x >>>= ((2491085477.186817)>>(x*(((tmp = -1592498533, tmp)+(tmp = 2086841852, tmp))&(-3174019330.8288536)))));
- assertEquals(0, x >>= x);
- assertEquals(0, x >>>= (tmp = -3045348659.45243, tmp));
- assertEquals(-1208573479, x |= ((3086393817)-x));
- assertEquals(1460649854142163500, x *= x);
- assertEquals(1588199424, x <<= (-1902076952));
- assertEquals(1586102272, x &= (tmp = 2139876091.9142454, tmp));
- assertEquals(-460908552.5528109, x -= (tmp = 2047010824.552811, tmp));
- assertEquals(-460908552.5528109, x %= (tmp = 507904117.09368753, tmp));
- assertEquals(-460908552.5528109, x %= (2749577642.527038));
- assertEquals(234012, x >>>= (-340465746.91275));
- assertEquals(0, x >>>= x);
- assertEquals(0, x %= (tmp = -2601875531, tmp));
- assertEquals(0, x %= (x|(tmp = 650979981.1158671, tmp)));
- assertEquals(0, x %= (tmp = -2286020987, tmp));
- assertEquals(0, x |= x);
- assertEquals(0, x &= (x|((tmp = 2568101411, tmp)-(-1438002403))));
- assertEquals(0, x >>>= (1399248574));
- assertEquals(0, x %= (-1906670287.2043698));
- assertEquals(0, x >>= (1019286379.6962404));
- assertEquals(0, x |= (x/(tmp = -82583591.62643051, tmp)));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x *= (x^(1874776436)));
- assertEquals(NaN, x -= ((-1238826797)-(-2971588236.7228813)));
- assertEquals(0, x <<= (2064632559));
- assertEquals(-0.5967273958864694, x += (((tmp = 1502995019, tmp)>>x)/(-2518729707)));
- assertEquals(0, x >>>= x);
- assertEquals(-0, x /= (-1923030890));
- assertEquals(NaN, x %= x);
- assertEquals(0, x >>= (tmp = 1081732779.9449487, tmp));
- assertEquals(-820183066, x |= ((tmp = -3169007292.4721155, tmp)|(-1912588318)));
- assertEquals(0, x -= x);
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x /= (tmp = 287181840, tmp));
- assertEquals(0, x &= (x/((tmp = -1139766051, tmp)<<(x&(tmp = 2779004578, tmp)))));
- assertEquals(0, x >>= (((tmp = -1816938028, tmp)+(-224851993.3139863))*(-2933829524)));
- assertEquals(0, x |= ((((tmp = 305077929.1808746, tmp)&((x-(((((tmp = 2122810346.7475111, tmp)<<(717271979))*(tmp = 256854043.72633624, tmp))%((x+(tmp = -318657223.9992106, tmp))*((1993144830)<<(2594890698.603228))))^((((tmp = 257370667, tmp)>>>((((x^(3160746820))>>>(2049640466.8116226))>>>(2543930504.7117066))^(x-x)))^(x%(964838975)))^x)))%(x*x)))>>>x)*(tmp = -46861540, tmp)));
- assertEquals(747575633, x ^= ((-2406502427)-(-3154078060.3794584)));
- assertEquals(0, x *= (x%x));
- assertEquals(0, x <<= (1313773705.3087234));
- assertEquals(0, x >>>= ((x+x)>>>(3068164056)));
- assertEquals(-0, x *= (tmp = -1771797797, tmp));
- assertEquals(1784146970, x ^= (tmp = 1784146970, tmp));
- assertEquals(1784146970, x >>>= (tmp = -2219972320.7195597, tmp));
- assertEquals(1744830464, x <<= ((((-2769476584)-(((1798431604)>>(tmp = 1337687914.799577, tmp))>>>((-2802941943.15014)>>x)))>>>(tmp = 646033678, tmp))-x));
- assertEquals(3044433348102455300, x *= x);
- assertEquals(0, x >>= ((tmp = 1592076570.1900845, tmp)-((645774223.6317859)>>x)));
- assertEquals(0, x >>= (x>>>(-3045822290.1536255)));
- assertEquals(-0, x *= (tmp = -2450298800.986624, tmp));
- assertEquals(0, x >>= (tmp = 1379605393, tmp));
- assertEquals(0, x &= (((x-((((tmp = 837939461.6683749, tmp)+((((-813261853.3247359)|(x&(((-2565113940)*(tmp = -2725085381.240134, tmp))|x)))%(-1457259320))-(x+((tmp = -273947066, tmp)%((1164825698.879649)>>(1653138880.3434052))))))>>>(2823967606.411492))>>>((((((((1189235604.9646997)/(tmp = -2875620103.4002438, tmp))-(tmp = -801261493, tmp))<<(((1832556579.5095325)<<x)|((tmp = -2740330665, tmp)>>(tmp = -2352814025, tmp))))-(tmp = -1445043552.99499, tmp))&(x<<(((((445325471)*(1293047043.1808558))>>>(((1901837408.5910044)-(tmp = -2349093446.5313253, tmp))>>>(tmp = 1000847053.1861948, tmp)))*(x>>>(1771853406.6567078)))>>x)))>>>x)>>>(x^((tmp = 2813422715, tmp)-(x+(-342599947)))))))&(x>>>x))*x));
- assertEquals(NaN, x %= ((tmp = -3027713526, tmp)-((((x%(((((x/((2711155710)^(((((x>>>x)%((1098599291.155015)^(((((tmp = 1855724377.8987885, tmp)/(x|x))*((-1963179786)*((x-((-1634717702)%x))<<x)))>>(2008859507))>>((tmp = 2635024299.7983694, tmp)^(tmp = -602049246, tmp)))))*(x>>x))&(tmp = -1925103609, tmp))*((tmp = 2106913531.2828505, tmp)%((tmp = -200970069, tmp)*(-2809001910.951446))))))%x)*((1990098169)>>((x<<(2303347904.2601404))%x)))|(2767962065.9846206))+(201589933.301661)))>>(((tmp = 1921071149.5140274, tmp)>>(1054558799.1731887))|x))*(x/((((-2833879637.345674)>>>(tmp = 2849099601, tmp))%x)+(x%(x%(((tmp = 1983018049, tmp)^(tmp = -2659637454, tmp))>>((-1335497229.6945198)-(x+(((((tmp = 1136612609.848967, tmp)%(2471741030.01762))<<(x|(((tmp = 1644081190.1972675, tmp)&(-1422527338))^(2379264356.265957))))/(tmp = 2979299484.1884174, tmp))/x)))))))))*((tmp = 1858298882, tmp)^((tmp = -547417134.9651439, tmp)*x)))));
- assertEquals(-7664, x |= ((2286000258.825538)>>(1716389170)));
- assertEquals(-1, x >>= x);
- assertEquals(-1231640486.3023372, x += ((tmp = 1231640485.3023372, tmp)*x));
- assertEquals(-2463280972.6046743, x += x);
- assertEquals(1746, x >>>= x);
- assertEquals(1746, x >>>= (((tmp = -562546488.0669937, tmp)*((-2475357745.8508205)&((x%(821425388.8633704))%((((-2315481592.687686)&(((tmp = 3130530521.7453523, tmp)+x)-x))^(-973033390.1773088))/x))))<<x));
- assertEquals(1746, x %= (-1544973951.076033));
- assertEquals(27936, x <<= (-525441532.33816123));
- assertEquals(27936, x %= (x*((tmp = 344991423.5336287, tmp)+(-2267207281))));
- assertEquals(27, x >>>= (tmp = 1249792906, tmp));
- assertEquals(0, x >>>= (tmp = -1068989615, tmp));
- assertEquals(0, x >>>= (tmp = 347969658.92579734, tmp));
- assertEquals(-2656611892, x -= (2656611892));
- assertEquals(1944539596, x |= (((tmp = 3000889963, tmp)-x)<<((tmp = 2917390580.5323124, tmp)^(-996041439))));
- assertEquals(1944539596, x |= x);
- assertEquals(-739740167.0752468, x -= ((1712009965.0752468)+(x>>((tmp = -740611560.99014, tmp)>>>((tmp = -1033267419.6253037, tmp)&(862184116.3583733))))));
- assertEquals(-1479480334.1504936, x += x);
- assertEquals(-4294967296.150494, x -= (x>>>((1219235492.3661718)&(3138970355.0665245))));
- assertEquals(0, x >>= (x*x));
- assertEquals(-0, x *= ((-2202530054.6558375)-(-676578695)));
- assertEquals(-0, x %= (1336025846));
- assertEquals(0, x &= x);
- assertEquals(0, x /= (1759366510));
- assertEquals(630007622, x |= (630007622));
- assertEquals(-0.22460286863455903, x /= (tmp = -2804984753, tmp));
- assertEquals(1102410276.775397, x -= (-1102410277));
- assertEquals(1102410276.775397, x %= ((((-2569525203)&x)*(x|(-1932675298)))/((-2376634450)>>>(x>>>(tmp = 936937604.9491489, tmp)))));
- assertEquals(33642, x >>= (3028252527));
- assertEquals(2181106522.688034, x -= (-2181072880.688034));
- assertEquals(-2113861630, x &= (2523921542));
- assertEquals(-2147483646, x &= (-1996601566.9370148));
- assertEquals(-2147483648, x &= (tmp = -665669175.1968856, tmp));
- assertEquals(-2858673260.1367273, x -= (tmp = 711189612.1367272, tmp));
- assertEquals(350657, x >>= (tmp = -170243892.25474262, tmp));
- assertEquals(-0.0001405571562140975, x /= (-2494764474.7868776));
- assertEquals(0, x ^= x);
- assertEquals(NaN, x /= ((x&(-2041236879))*((tmp = -2182530229, tmp)^((1274197078)*x))));
- assertEquals(0, x |= (x&(x-(1794950303))));
- assertEquals(1222105379, x |= (tmp = 1222105379, tmp));
- assertEquals(729884484, x ^= (tmp = 1666645607.6907792, tmp));
- assertEquals(729884484, x %= (tmp = -2896922082, tmp));
- assertEquals(8768, x &= ((tmp = 358940932, tmp)>>>(3159687631.3308897)));
- assertEquals(1892384495, x |= (-2402591569));
- assertEquals(1892470533, x += ((((x^(-2266612043))>>>(tmp = -531009952, tmp))<<(x>>>((-1365315963.5698428)>>>((x+((-3168207800.184341)-(tmp = 1776222157.609917, tmp)))+(-1588857469.3596382)))))>>>x));
- assertEquals(143587205, x += (tmp = -1748883328, tmp));
- assertEquals(0, x ^= x);
- assertEquals(0, x >>= (tmp = 2334880462.3195543, tmp));
- assertEquals(0, x &= ((tmp = 1819359625.4396145, tmp)|(tmp = -1323513565, tmp)));
- assertEquals(-1102259874, x ^= (3192707422));
- assertEquals(2567457772588852700, x *= (-2329267202));
- assertEquals(-16783687, x |= ((-2212476227.060922)^(378973700.78452563)));
- assertEquals(4278183609, x >>>= ((((((((tmp = 1766363150.197206, tmp)*(-2774552871))%x)>>>((3071429820)&((((((tmp = 351068445.27642524, tmp)<<(tmp = 2646575765, tmp))^(806452682))<<((x>>>(-2217968415.505327))<<(1564726716)))|x)-(tmp = -3110814468.9023848, tmp))))+x)^x)>>>(tmp = -617705282.0788529, tmp))>>>x));
- assertEquals(4314933530, x -= ((1032195469.789219)|(tmp = -448053861.9531791, tmp)));
- assertEquals(9709850, x %= (((tmp = -3056286252.5853324, tmp)*x)&x));
- assertEquals(9709850, x %= (tmp = -2596800940, tmp));
- assertEquals(2655489828.9461126, x -= (tmp = -2645779978.9461126, tmp));
- assertEquals(369266212, x &= (((335712316.24874604)|(tmp = 33648215, tmp))-((x/(2639848695))<<((-499681175)<<(-2490554556)))));
- assertEquals(-2147483648, x <<= (-834465507));
- assertEquals(1073741824, x >>>= (((tmp = 3018385473.1824775, tmp)>>(x*(-2574502558.216812)))|(((tmp = -1742844828, tmp)*(1698724455))&x)));
- assertEquals(-270818218, x += (-1344560042));
- assertEquals(360710144, x <<= x);
- assertEquals(0, x <<= (tmp = 612718075, tmp));
- assertEquals(0, x <<= x);
- assertEquals(-0, x /= (tmp = -1922423684, tmp));
- assertEquals(-0, x *= ((((tmp = 741806213.3264687, tmp)%(-711184803.2022421))+((tmp = -3209040938, tmp)&(525355849.044886)))&(x<<(tmp = -698610297, tmp))));
- assertEquals(0, x <<= (-482471790));
- assertEquals(0, x &= ((-921538707)/(tmp = -482498765.988616, tmp)));
- assertEquals(0, x ^= (x^x));
- assertEquals(-351721702, x ^= (-351721702.8850286));
- assertEquals(726242219625599900, x -= ((2064820612)*x));
- assertEquals(1452484439251199700, x += x);
- assertEquals(2.52318299412847e-15, x %= ((((x<<((2508143285)+x))>>(-2493225905.011774))%(1867009511.0792103))/((((x<<(2542171236))>>((x|x)&(tmp = -384528563, tmp)))+((-1168755343)*(1731980691.6745195)))+(tmp = -1608066022.71164, tmp))));
- assertEquals(79905008, x += ((((-2702081714.590131)&(x+(tmp = -1254725471.2121565, tmp)))*(3088309981))%(((tmp = 1476844981.1453142, tmp)|((((tmp = -1243556934.7291331, tmp)%x)^(-1302096154))+((660489180)/(tmp = -681535480.8642154, tmp))))^(tmp = -8410710, tmp))));
- assertEquals(1215822204, x ^= ((-3008054900)>>>(tmp = -1990206464.460693, tmp)));
- assertEquals(-394790532, x |= ((((-1334779133.2038574)+(tmp = -1407958866.832946, tmp))<<(1699208315))-(((x^(x%x))<<(3216443))>>(x+((((2576716374.3081336)|((tmp = 2316167191.348064, tmp)&((51086351.20208645)&((x|(tmp = -357261999, tmp))^(x/x)))))*(-45901631.10155654))*(((-439588079)>>>((-2358959768.7634916)|(1613636894.9373643)))+(((-908627176)<<x)%(x%((-1669567978)>>>((x>>(1289400876))+(tmp = 2726174270, tmp)))))))))));
- assertEquals(-0.17717467607696327, x /= (2228255982.974148));
- assertEquals(-1905616474, x ^= (tmp = 2389350822.851587, tmp));
- assertEquals(-0, x %= x);
- assertEquals(2818124981.508915, x -= (-2818124981.508915));
- assertEquals(-1476842315, x |= x);
- assertEquals(73408564, x &= (-3147390604.3453345));
- assertEquals(70, x >>>= x);
- assertEquals(1, x >>= x);
- assertEquals(3086527319.899181, x *= (3086527319.899181));
- assertEquals(-145, x >>= x);
- assertEquals(-145, x %= (tmp = -2500421077.3982406, tmp));
- assertEquals(-1, x >>= (tmp = -2970678326.712191, tmp));
- assertEquals(-1, x %= ((tmp = -535932632.4668834, tmp)+(((-1226598339.347982)<<((tmp = 616949449, tmp)/(tmp = 2779464046, tmp)))/(214578501.67984307))));
- assertEquals(1, x *= x);
- assertEquals(1, x >>= ((tmp = 11080208, tmp)<<(460763913)));
- assertEquals(-1.8406600706723492e-19, x /= ((tmp = -2334126306.1720915, tmp)*(tmp = 2327566272.5901165, tmp)));
- assertEquals(856681434186007200, x -= ((tmp = -2286974992.8133907, tmp)*(374591518)));
- assertEquals(3126084224, x >>>= x);
- assertEquals(-1160460669, x |= (tmp = 181716099, tmp));
- assertEquals(873988096, x <<= (tmp = 406702419, tmp));
- assertEquals(0, x <<= ((tmp = 802107965.4672925, tmp)-((tmp = 1644174603, tmp)>>((tmp = 604679952, tmp)+(tmp = -515450096.51425123, tmp)))));
- assertEquals(NaN, x %= ((x>>(tmp = 2245570378, tmp))*(tmp = 1547616585, tmp)));
- assertEquals(NaN, x /= ((tmp = -776657947.0382309, tmp)&(tmp = 163929332.28270507, tmp)));
- assertEquals(NaN, x *= (tmp = 243725679.78916526, tmp));
- assertEquals(NaN, x /= (x>>x));
- assertEquals(0, x <<= ((tmp = -1293291295.5735884, tmp)%(((((63309078)>>>x)&(x&(-2835108260.025297)))+x)>>>(-1317213424))));
- assertEquals(0, x *= ((((tmp = -1140319441.0068483, tmp)*(tmp = 2102496185, tmp))&(-2326380427))<<(tmp = -2765904696, tmp)));
- assertEquals(0, x /= (tmp = 2709618593, tmp));
- assertEquals(0, x >>= (-1753085095.7670164));
- assertEquals(1766381484, x |= (-2528585812));
- assertEquals(1766381484, x %= (2735943476.6363373));
- assertEquals(1766381484, x %= (x*(tmp = 2701354268, tmp)));
- assertEquals(-2147483648, x <<= (-323840707.4949653));
- assertEquals(4611686018427388000, x *= (x<<x));
- assertEquals(0, x <<= (3066735113));
- assertEquals(0, x ^= ((((x*x)^(tmp = -2182795086.39927, tmp))<<(x^(tmp = 1661144992.4371827, tmp)))<<((((-2885512572.176741)*(tmp = 609919485, tmp))|(tmp = 929399391.0790694, tmp))>>>((((((((((399048996)>>((-107976581.61751771)>>>x))|(((-1502100015)<<(tmp = -1108852531.9494338, tmp))&(x/(tmp = -3198795871.7239237, tmp))))+((-2627653357)>>x))>>>x)*(1066736757.2718519))%(tmp = 1326732482.201604, tmp))/(tmp = 2513496019.814191, tmp))>>>((1694891519)>>>(-2860217254.378931)))<<(tmp = 31345503, tmp)))));
- assertEquals(0, x ^= (x/((-2556481161)>>>(x/(x%(x&(1302923615.7148068)))))));
- assertEquals(NaN, x /= x);
- assertEquals(NaN, x += (tmp = 846522031, tmp));
- assertEquals(0, x >>= (x+(-1420249556.419045)));
- assertEquals(0, x ^= (((x%(-1807673170))&x)-x));
- assertEquals(-3484.311990686845, x -= ((((((-510347602.0068991)>>>x)<<((tmp = 1647999950, tmp)&(((305407727)>>((1781066601.791009)&x))<<((tmp = -998795238, tmp)%(((x/x)+x)<<(((2586995491.434947)<<x)-((((tmp = 545715607.9395425, tmp)*x)>>>x)>>>(((((2332534960.4595165)^(-3159493972.3695474))<<(tmp = 867030294, tmp))|(2950723135.753855))^(((3150916666)<<x)>>((tmp = 414988690, tmp)|((tmp = -1879594606, tmp)/(tmp = 1485647336.933429, tmp))))))))))))>>(tmp = -2676293177, tmp))%(617312699.1995015))/((((tmp = -1742121185, tmp)^((((x&x)<<(tmp = 698266916, tmp))/(-1860886248))+((-213304430)%((((((-2508973021.1333447)+(tmp = 2678876318.4903, tmp))&(tmp = -43584540, tmp))-x)^(-2251323850.4611115))-x))))>>>(tmp = 2555971284, tmp))%((((tmp = 16925106, tmp)^x)&x)|((x/((x|(tmp = -2787677257.125139, tmp))<<(-853699567)))+(tmp = -1721553520, tmp))))));
- assertEquals(-447873933.26863855, x += (-447870448.9566479));
- assertEquals(200591060101520900, x *= x);
- assertEquals(200591062202483420, x -= (-2100962536));
- assertEquals(-5.261023346568228e+24, x *= ((tmp = -419641692.6377077, tmp)>>(tmp = -224703100, tmp)));
- assertEquals(1269498660, x |= (195756836));
- assertEquals(1269498660, x |= x);
- assertEquals(1269498660, x |= x);
- assertEquals(-37.75978948486164, x /= (((tmp = -595793780, tmp)+((tmp = 2384365752, tmp)>>>(1597707155)))|((968887032)^(tmp = 2417905313.4337964, tmp))));
- assertEquals(-37.75978948486164, x %= (tmp = -1846958365.291661, tmp));
- assertEquals(1102319266.6421175, x += (1102319304.401907));
- assertEquals(-1664202255175155200, x -= ((x^(tmp = 407408729, tmp))*x));
- assertEquals(-752874653, x ^= (tmp = 314673507, tmp));
- assertEquals(-72474761, x |= (tmp = -2538726025.8884344, tmp));
- assertEquals(-72474761, x |= x);
- assertEquals(-122849418, x += ((tmp = -2332080457, tmp)|(((((30496388.145492196)*(((-1654329438.451212)|(-2205923896))&(x>>(tmp = -1179784444.957002, tmp))))&(tmp = 319312118, tmp))*(651650825))|(((-2305190283)|x)>>>(-428229803)))));
- assertEquals(994, x >>>= x);
- assertEquals(614292, x *= (((((2565736877)/((tmp = 649009094, tmp)>>>(((x>>>(2208471260))>>(x>>>x))%x)))&(tmp = 357846438, tmp))<<(tmp = -2175355851, tmp))%x));
- assertEquals(1792008118, x |= (tmp = 1791924774.5121183, tmp));
- assertEquals(1246238208, x &= (tmp = 1264064009.9569638, tmp));
- assertEquals(-88877082, x ^= (2969289190.285704));
- assertEquals(0.044923746573582474, x /= ((tmp = -3057438043, tmp)^(-1009304907)));
- assertEquals(0, x <<= ((-828383918)-((((x>>(734512101))*(tmp = -3108890379, tmp))-(x|((tmp = 3081370585.3127823, tmp)^((-271087194)-(x/(tmp = -2777995324.4073873, tmp))))))%x)));
- assertEquals(1604111507.3365753, x -= (-1604111507.3365753));
- assertEquals(-1721314970, x ^= (tmp = -956686859, tmp));
- assertEquals(-102247425, x |= (tmp = -2535095555, tmp));
- assertEquals(-102247425, x %= (-955423877));
- assertEquals(1053144489850425, x *= (((tmp = 1583243590.9550207, tmp)&(1356978114.8592746))|(tmp = -10299961.622774363, tmp)));
- assertEquals(-0.0043728190668037336, x /= ((-1196259252.435701)*(((-689529982)|(tmp = -1698518652.4373918, tmp))<<x)));
- assertEquals(-2, x ^= (((x+(tmp = 2961627388, tmp))>>(tmp = 231666110.84104693, tmp))|x));
- assertEquals(-1, x >>= (tmp = -83214419.92958307, tmp));
- assertEquals(-1, x %= (-1303878209.6288595));
- assertEquals(2944850457.5213213, x -= (tmp = -2944850458.5213213, tmp));
- assertEquals(-1.6607884436053055, x /= (-1773164107));
- assertEquals(-0.6607884436053055, x %= ((x>>(1240245489.8629928))%(tmp = -3044136221, tmp)));
- assertEquals(-0, x *= ((x*x)>>>((1069542313.7656753)+x)));
- assertEquals(0, x >>>= (tmp = -202931587.00212693, tmp));
- assertEquals(-0, x *= (-375274420));
- assertEquals(0, x |= ((x/(((tmp = -876417141, tmp)*(x>>>x))&(-2406962078)))<<x));
- assertEquals(0, x &= ((tmp = -650283599.0780096, tmp)*(tmp = 513255913.34108484, tmp)));
- assertEquals(3027255453.458466, x += (3027255453.458466));
- assertEquals(-12568623413253943000, x *= (((x-(198689694.92141533))|x)-x));
- assertEquals(-12568623410285185000, x -= (tmp = -2968758030.3694654, tmp));
- assertEquals(-2008903680, x &= (3111621747.7679076));
- assertEquals(-110045263.26583672, x += (tmp = 1898858416.7341633, tmp));
- assertEquals(15964, x >>>= (1141042034));
- assertEquals(31928, x += x);
- assertEquals(0, x ^= x);
- assertEquals(-1159866377, x |= (-1159866377));
- assertEquals(0, x ^= x);
- assertEquals(3072699529.4306993, x -= (tmp = -3072699529.4306993, tmp));
- assertEquals(1, x /= x);
- assertEquals(-1471195029, x |= (2823772267.429641));
- assertEquals(-4152937108, x += (-2681742079));
- assertEquals(142030188, x |= x);
- assertEquals(270, x >>= (tmp = 1013826483, tmp));
- assertEquals(0, x >>>= (529670686));
- assertEquals(-2912300367, x -= (2912300367));
- assertEquals(2213791134963007500, x *= (x<<((((-3214746140)>>(tmp = -588929463, tmp))+((tmp = -3084290306, tmp)>>x))>>x)));
- assertEquals(2213791133466809900, x -= (tmp = 1496197641, tmp));
- assertEquals(69834416, x >>>= (x|(((2755815509.6323137)^(x%(((x*((((tmp = 375453453, tmp)<<(x*x))>>(tmp = -973199642, tmp))*x))>>((tmp = -356288629, tmp)>>(tmp = 2879464644, tmp)))<<((((1353647167.9291127)>>>(x/x))<<((2919449101)/(2954998123.5529594)))^x))))&((-2317273650)>>>(tmp = 34560010.71060455, tmp)))));
- assertEquals(69834416, x >>>= (x^(-2117657680.8646245)));
- assertEquals(2217318064, x -= ((tmp = 2035883891, tmp)<<(tmp = -1884739265, tmp)));
- assertEquals(-1272875686, x ^= (tmp = 805889002.7165648, tmp));
- assertEquals(-1272875686, x >>= (x&(((1750455903)*x)>>((722098015)%((tmp = 1605335626, tmp)>>(tmp = -565369634, tmp))))));
- assertEquals(-1274351316, x -= (x>>>((tmp = 2382002632, tmp)-((tmp = -2355012843, tmp)+(1465018311.6735773)))));
- assertEquals(-2982908522.4418216, x -= ((tmp = 1635549038.4418216, tmp)+(((1952167017.720186)&((tmp = -2284822073.1002254, tmp)>>(-1403893917)))%(tmp = 655347757, tmp))));
- assertEquals(312, x >>>= x);
- assertEquals(1248, x <<= (2376583906));
- assertEquals(0, x ^= x);
- assertEquals(0, x *= ((((tmp = 1914053541.881434, tmp)>>>(tmp = 1583032186, tmp))>>>(-2511688231))%(tmp = -2647173031, tmp)));
- assertEquals(0, x >>>= (tmp = -2320612994.2421227, tmp));
- assertEquals(0, x %= (((x+(tmp = -720216298.5403998, tmp))<<(414712685))>>(tmp = 480416588, tmp)));
- assertEquals(0, x >>= ((((3039442014.271272)<<x)%(-2402430612.9724464))&((-2141451461.3664773)%((x>>(1361764256))/((tmp = -1723952801.9320493, tmp)%(477351810.2485285))))));
- assertEquals(-0, x /= (tmp = -1627035877, tmp));
- assertEquals(0, x >>>= (tmp = 1745193212, tmp));
- assertEquals(0, x >>>= (2309131575));
- assertEquals(NaN, x %= (((x*(tmp = -1730907131.6124666, tmp))%((((1481750041)|(x>>((((x>>>(tmp = 3128156522.5936565, tmp))/(tmp = -1277222645.9880452, tmp))^(tmp = -2327254789, tmp))+x)))>>>(-1161176960))>>>(tmp = 3135906272.5466847, tmp)))*(((((-2230902834.464362)^(1822893689.8183987))+(((tmp = 1597326356, tmp)/(x&((tmp = -3044163063.587389, tmp)>>(tmp = 2844997555, tmp))))%(x^x)))>>((x|x)/x))^(2634614167.2529745))));
- assertEquals(0, x &= (3081901595));
- assertEquals(0, x &= (-2453019214.8914948));
- assertEquals(0, x &= x);
- assertEquals(0, x >>>= (-596810618.3666217));
- assertEquals(0, x >>= (((908276623)|x)/x));
- assertEquals(0, x ^= x);
- assertEquals(958890056, x |= (tmp = 958890056.474458, tmp));
- assertEquals(1325436928, x <<= (tmp = -2474326583, tmp));
- assertEquals(711588532333838300, x *= ((-148161646.68183947)<<(tmp = -1149179108.8049204, tmp)));
- assertEquals(0, x ^= (((2862565506)%x)/(tmp = -2865813112, tmp)));
- assertEquals(-2064806628, x += (((tmp = -2677361175.7317276, tmp)/((817159440)>>>(tmp = 1895467706, tmp)))^(x|(tmp = -2309094859, tmp))));
- assertEquals(-69806982479424, x *= ((x&(tmp = 2857559765.1909904, tmp))&(-3166908966.754988)));
- assertEquals(-430255744, x %= ((((((-2968574724.119535)<<x)<<((tmp = 1603913671, tmp)%((-1495838556.661653)^(tmp = 1778219751, tmp))))*(-400364265))<<((((1607866371.235576)-(1961740136))|(1259754297))&(tmp = -1018024797.1352971, tmp)))^x));
- assertEquals(6.828637393208647e-7, x /= (x*(tmp = 1464421, tmp)));
- assertEquals(0, x &= x);
- assertEquals(-0, x *= (((tmp = -2510016276, tmp)-(2088209546))<<((tmp = -1609442851.3789036, tmp)+(tmp = 1919930212, tmp))));
- assertEquals(-0, x %= (tmp = 1965117998, tmp));
- assertEquals(-290294792.53186846, x += ((tmp = -2361555894.5318685, tmp)%(2071261102)));
- assertEquals(-70873, x >>= (tmp = 2206814124, tmp));
- assertEquals(-141746, x += x);
- assertEquals(-141733.9831459089, x -= (((tmp = -806523527, tmp)>>>(tmp = 1897214891, tmp))/x));
- assertEquals(-141733.9831459089, x %= ((tmp = 1996295696, tmp)<<(tmp = 3124244672, tmp)));
- assertEquals(141733.9831459089, x /= (x>>(2688555704.561076)));
- assertEquals(3196954517.3075542, x -= (tmp = -3196812783.3244085, tmp));
- assertEquals(-19929155, x |= (((x|x)+x)^((tmp = 391754876, tmp)-(((((((tmp = -3051902902.5100636, tmp)*(x/(1546924993)))|(tmp = 1494375949, tmp))/((((-795378522)/(tmp = 509984856, tmp))>>>(tmp = -106173186, tmp))+x))|x)|(1916921307))>>>x))));
- assertEquals(1279271449, x &= ((tmp = 1289446971, tmp)&(tmp = 1836102619, tmp)));
- assertEquals(17876992, x <<= (-207633461));
- assertEquals(0, x >>= (tmp = -903885218.9406946, tmp));
- assertEquals(0, x >>>= x);
- assertEquals(-2999, x -= (((754533336.2183633)%(tmp = 557970276.0537136, tmp))>>(tmp = -1171045520, tmp)));
- assertEquals(-0.000003020470363504361, x /= (tmp = 992891715.2229724, tmp));
- assertEquals(1, x /= x);
- assertEquals(0.45768595820301217, x %= ((tmp = 673779031, tmp)/(tmp = -1242414872.3263657, tmp)));
- assertEquals(-980843052.1872087, x += (tmp = -980843052.6448946, tmp));
- assertEquals(-Infinity, x /= ((((tmp = 317747175.8024508, tmp)&(x&(((tmp = 1632953053, tmp)>>x)/x)))%x)/(3145184986)));
- assertEquals(0, x &= (x<<x));
- assertEquals(0, x ^= (x-((2969023660.5619783)/x)));
- assertEquals(0, x *= x);
- assertEquals(NaN, x %= (x/(((x-x)/((tmp = -1622970458.3812745, tmp)-(1626134522)))&((((((tmp = 1384729039.4149384, tmp)^(x%(tmp = -2736365959, tmp)))+((-1465172172)%x))>>(tmp = -1839184810.2603343, tmp))^(((tmp = 1756918419, tmp)>>>(x+(x%(tmp = -2011122996.9794662, tmp))))<<(-3026600748.902623)))*((tmp = -2040286580, tmp)>>(-2899217430.655154))))));
- assertEquals(0, x >>>= (tmp = 2100066003.3046467, tmp));
- assertEquals(1362012169, x ^= (tmp = 1362012169, tmp));
- assertEquals(1476312683, x |= ((457898409)>>>(-3079768830.723079)));
- assertEquals(1441711, x >>>= (905040778.7770994));
- assertEquals(2078530607521, x *= x);
- assertEquals(-208193103, x |= ((tmp = -241750000, tmp)^x));
- assertEquals(745036378, x ^= (((tmp = -1737151062.4726632, tmp)<<x)|(tmp = -1900321813, tmp)));
- assertEquals(1744830464, x <<= x);
- assertEquals(212992, x >>>= ((1210741037)-(x-(x>>>((x^(-1273817997.0036907))+((2401915056.5471)%(x<<(tmp = 1696738364.277438, tmp))))))));
- assertEquals(0.0001604311565639742, x /= (1327622418));
- assertEquals(0, x <<= (tmp = 166631979.34529006, tmp));
- assertEquals(0, x *= ((((tmp = 657814984, tmp)/(((-831055031)>>>(1531978379.1768064))|((tmp = 2470027754.302619, tmp)^(-223467597))))/(tmp = 1678697269.468965, tmp))&(tmp = -1756260071.4360774, tmp)));
- assertEquals(-2049375053, x ^= (tmp = -2049375053, tmp));
- assertEquals(-1879109889, x |= (tmp = -1963586818.0436726, tmp));
- assertEquals(718239919, x ^= (tmp = -1523550640.1925273, tmp));
- assertEquals(-1361085185, x |= (-1939964707));
- assertEquals(2, x >>>= (1864136030.7395325));
- assertEquals(0.794648722849246, x %= ((-668830999)*(((-2227700170.7193384)%(x^(x>>>x)))/(tmp = 399149892, tmp))));
- assertEquals(0, x >>= x);
- assertEquals(0, x *= x);
- assertEquals(0, x &= ((tmp = -2389008496.5948563, tmp)|((((tmp = -2635919193.905919, tmp)*((-64464127)<<(2136112830.1317358)))>>((184057979)*(-1204959085.8362718)))>>>(-442946870.3341484))));
- assertEquals(-243793920, x -= ((tmp = 3002998032, tmp)<<((537875759)<<x)));
- assertEquals(0, x -= x);
- assertEquals(0, x *= ((((66852616.82442963)/((((x^x)&(2975318321.223734))+(((tmp = -1388210811.1249495, tmp)^((((-680567297.7620237)%(x-(tmp = -672906716.4672911, tmp)))-x)*(tmp = -1452125821.0132627, tmp)))*(((2770387154.5427895)%x)%x)))-x))<<((-1481832432.924325)>>(tmp = 3109693867, tmp)))>>>(x/(((((((tmp = 928294418, tmp)^(((-1018314535)/(tmp = -3167523001, tmp))%((((((tmp = -1639338126, tmp)-(tmp = -2613558829, tmp))&x)/x)%(tmp = 513624872, tmp))/((-520660667)&x))))*(2620452414))^((tmp = 2337189239.5949326, tmp)*(3200887846.7954993)))>>>((tmp = 1173330667, tmp)^x))<<x)>>(((tmp = -2475534594.982338, tmp)*x)|x)))));
- assertEquals(0, x /= (2520915286));
- assertEquals(0, x &= x);
- assertEquals(0, x >>= (-1908119327));
- assertEquals(0, x >>>= (tmp = 549007635, tmp));
- assertEquals(0, x >>= (-994747873.8117285));
- assertEquals(0, x <<= ((((x>>>((-3084793026.846681)%((1107295502)&(tmp = -296613957.8133817, tmp))))&((19637717.166736007)/(x+x)))+x)/(-2479724242)));
- assertEquals(-695401420, x += (-695401420));
- assertEquals(-695401394, x += (x>>>(tmp = 2340097307.6556053, tmp)));
- assertEquals(-555745552, x -= (x|(-483851950.68644)));
- assertEquals(-17825792, x <<= x);
- assertEquals(-17825792, x >>= x);
- assertEquals(-17, x %= ((tmp = 1799361095, tmp)|((x>>(((-1201252592)<<((((543273288)+(-2859945716.606924))*x)<<((-3030193601)<<(3081129914.9217644))))|((1471431587.981769)>>(-246180750))))|(((tmp = -2689251055.1605787, tmp)>>x)&(((2131333169)^x)-((tmp = -951555489, tmp)/x))))));
- assertEquals(-8912896, x <<= (1146444211));
- assertEquals(2854567584, x += (tmp = 2863480480, tmp));
- assertEquals(426232502.24151134, x %= (1214167540.8792443));
- assertEquals(1806802048, x ^= (-2368317898));
- assertEquals(432537600, x <<= (tmp = 2831272652.589364, tmp));
- assertEquals(432537600, x %= (((1713810619.3880467)-x)&((-2853023009.553296)&(tmp = -3158798098.3355417, tmp))));
- assertEquals(-509804066, x += (tmp = -942341666, tmp));
- assertEquals(-509804066, x %= (-732349220));
- assertEquals(259900185710132350, x *= x);
- assertEquals(711598501.7021885, x %= ((tmp = 2020395586.2280731, tmp)-(tmp = 3031459563.1386633, tmp)));
- assertEquals(711598503.0618857, x += ((tmp = 967558548.4141241, tmp)/x));
- assertEquals(711598503, x &= x);
- assertEquals(711598503, x ^= (((((1609355669.1963444)+((((tmp = -2660082403.258437, tmp)+(tmp = -235367868, tmp))&(x/x))*((-2595932186.69466)|((tmp = -3039202860, tmp)<<x))))>>>(-951354869))-((tmp = -691482949.6335375, tmp)/(tmp = -1735502400, tmp)))/(tmp = 798440377, tmp)));
- assertEquals(558262613882868500, x *= (784519095.4299527));
- assertEquals(558262611968479000, x -= ((((tmp = 1039039153.4026555, tmp)/(-3138845051.6240187))*(tmp = 633557994, tmp))&(1981507217)));
- assertEquals(1170427648, x |= ((x>>((((-1086327124)%((tmp = -1818798806.368613, tmp)^(tmp = 2183576654.9959817, tmp)))>>x)&((((((tmp = 1315985464.0330539, tmp)&(2774283689.333836))%x)*((2722693772.8994813)&(tmp = -2720671984.945404, tmp)))^(tmp = -76808019, tmp))<<((tmp = 685037799.2336662, tmp)^((tmp = 1057250849, tmp)&(tmp = 1469205111.2989025, tmp))))))+(x*(((tmp = 448288818.47173154, tmp)-(-2527606231))-((8387088.402292728)>>x)))));
- assertEquals(558, x >>>= (tmp = 2732701109, tmp));
- assertEquals(558, x &= x);
- assertEquals(-0.00015855057024653912, x /= ((x+(((tmp = -1963815633, tmp)-(x>>x))-((x|x)>>x)))/x));
- assertEquals(1.3458861596445712e-13, x /= (-1178038492.4116466));
- assertEquals(0, x <<= (-104550232));
- assertEquals(0, x >>>= (x>>(tmp = -255275244.12613606, tmp)));
- assertEquals(0, x >>= x);
- assertEquals(375, x |= ((1576819294.6991196)>>>(-2570246122)));
- assertEquals(96000, x <<= ((2252913843.0150948)>>>(-49239716)));
- assertEquals(6144000, x <<= ((((tmp = -2478967279, tmp)&((x%((tmp = -1705332610.8018858, tmp)+(x+(tmp = 590766349, tmp))))<<(tmp = 1759375933, tmp)))+(-2024465658.849834))&(1564539207.3650014)));
- assertEquals(-1149239296, x <<= (1862803657.7241006));
- assertEquals(-9, x >>= (((tmp = 463306384.05696774, tmp)^x)|((x>>((((-2098070856.799663)<<((-2054870274.9012866)<<(((-2582579691)/(829257170.0266814))<<(((((tmp = -1753535573.7074275, tmp)<<((x>>(-197886116))%((2487188445)%(tmp = 2465391564.873364, tmp))))&(((tmp = -500069832, tmp)&(tmp = 3016637032, tmp))&((tmp = 2525942628, tmp)|((((-920996215)|x)^((((tmp = -687548533.419106, tmp)&(1423222636.058937))<<((tmp = -1096532228, tmp)>>((((tmp = -3124481449.2740726, tmp)^(tmp = 2724328271.808975, tmp))>>x)*x)))+(-1661789589.5808442)))+(((x*(tmp = -1224371664.9549093, tmp))^((tmp = 3202970043, tmp)^x))/(tmp = 131494054.58501709, tmp))))))|(((tmp = -1654136720, tmp)<<x)>>((1652979932.362416)-(tmp = -863732721, tmp))))^(-113307998)))))^(-90820449.91417909))*((tmp = 641519890, tmp)-((((x<<(tmp = 2349936514.071881, tmp))*(2324420443.587892))^x)%(x<<((tmp = -1838473742, tmp)/(((-3154172718.4274178)-x)+x)))))))|(x>>>((tmp = 2096024376.4308293, tmp)<<x)))));
- assertEquals(81, x *= x);
- assertEquals(81, x &= x);
- assertEquals(81, x %= (tmp = 2223962994, tmp));
- assertEquals(81, x ^= ((x/(((-1606183420.099584)|(-1242175583))&(((x|((tmp = 828718431.3311573, tmp)/(x>>x)))+(((-2207542725.4531174)^(x*x))*(tmp = 551575809.955105, tmp)))/x)))&((x>>x)&x)));
- assertEquals(81, x %= (tmp = 279598358.6976975, tmp));
- assertEquals(101.72338484518858, x -= (((tmp = 2452584495.44003, tmp)%((-1181192721)+(((x>>(((x&x)^x)+((x>>>((x+(-2472793823.57181))/(((2854104951)>>(-1208718359.6554642))>>>(1089411895.694705))))/(x|(-2821482890.1780205)))))^(-1786654551))/(-29404242.70557475))))/(((-4352531)<<((-1227287545)<<x))%(-2558589438))));
- assertEquals(101.72338484518858, x %= (-943645643));
- assertEquals(0, x -= x);
- assertEquals(0, x >>>= (-2440404084));
- assertEquals(0, x >>= (tmp = 1029680958.405923, tmp));
- assertEquals(0, x >>>= (1213820208.7204895));
- assertEquals(-0, x /= (tmp = -103093683, tmp));
- assertEquals(0, x >>>= (-2098144813));
- assertEquals(-0, x /= (((-3087283334)+(((tmp = -3129028112.6859293, tmp)%(tmp = 2413829931.1605015, tmp))-(2578195237.8071446)))|x));
- assertEquals(-15, x |= ((((-178926550.92823577)>>>(-965071271))^((tmp = -484633724.7237625, tmp)-(tmp = 473098919.1486404, tmp)))>>((-2264998310.203265)%(tmp = -499034672, tmp))));
- assertEquals(0, x ^= x);
- assertEquals(0, x >>= (((-3207915976.698118)<<(tmp = 2347058630, tmp))|(tmp = -2396250098.559627, tmp)));
- assertEquals(NaN, x %= x);
- assertEquals(NaN, x *= (621843222));
- assertEquals(0, x >>= (((-2409032228.7238913)*x)-(tmp = -887793239, tmp)));
- assertEquals(NaN, x /= x);
- assertEquals(1193017666, x ^= (tmp = 1193017666, tmp));
- assertEquals(3.5844761899682753, x /= (tmp = 332829011.206393, tmp));
- assertEquals(-888572929, x |= (((tmp = 1032409228, tmp)+(tmp = -1920982163.7853453, tmp))+x));
- assertEquals(-1817051951333455600, x *= (((-1506265102)^(tmp = -775881816, tmp))-(tmp = -32116372.59181881, tmp)));
- assertEquals(-1638479616, x |= x);
- assertEquals(-114489, x %= (((tmp = -247137297.37866855, tmp)>>>((((((-322805409)-x)^x)>>((((((((x>>>(tmp = -900610424.7148039, tmp))/(-1155208489.6240904))|((-2874045803)|(tmp = 3050499811, tmp)))+(x/((tmp = -613902712, tmp)^((-982142626.2892077)*((((tmp = -3201753245.6026397, tmp)|((1739238762.0423079)^x))/(243217629.47237313))^((tmp = -11944405.987132788, tmp)/(tmp = 2054031985.633406, tmp)))))))*(tmp = 2696108952.450961, tmp))*x)>>>(tmp = 3058430643.0660386, tmp))>>(x<<x)))>>(-984468302.7450335))%((tmp = 1302320585.246251, tmp)>>>x)))%(tmp = -2436842285.8208156, tmp)));
- assertEquals(2047, x >>>= (2380161237));
- assertEquals(0, x >>= x);
- assertEquals(0, x &= (tmp = 980821012.975836, tmp));
- assertEquals(-1090535537, x -= ((-3064511503.1214876)&((tmp = -2598316939.163751, tmp)<<((tmp = -969452391.8925576, tmp)*x))));
- assertEquals(-2181071074, x += x);
- assertEquals(1, x >>>= ((2902525386.449062)>>x));
- assertEquals(1, x += (x&(tmp = -2643758684.6636515, tmp)));
- assertEquals(1, x %= ((tmp = -2646526891.7004848, tmp)/x));
- assertEquals(448735695.7888887, x -= (tmp = -448735694.7888887, tmp));
- assertEquals(1, x /= x);
- assertEquals(1, x >>= ((-480385726)<<(2641021142)));
- assertEquals(1, x %= (375099107.9200462));
- assertEquals(1, x >>= (((x&((tmp = -2402469116.9903326, tmp)%(tmp = -2862459555.860298, tmp)))*(tmp = -2834162871.0586414, tmp))%(((x>>>(tmp = 721589907.5073895, tmp))*(x^x))%(((tmp = 2844611489.231776, tmp)^((983556913)&(906035409.6693488)))^(x>>>(1239322375))))));
- assertEquals(268435456, x <<= (tmp = 178807644.80966163, tmp));
- assertEquals(44, x %= ((tmp = 2527026779.081539, tmp)>>>(2736129559)));
- assertEquals(88, x += x);
- assertEquals(0, x >>>= x);
- assertEquals(0, x -= x);
- assertEquals(-1523121602, x |= (2771845694));
- assertEquals(-2, x >>= x);
- assertEquals(-4, x += x);
- assertEquals(-256, x <<= (((2522793132.8616533)>>(tmp = 77232772.94058788, tmp))+(3118669244.49152)));
- assertEquals(4294967040, x >>>= x);
- assertEquals(-256, x &= x);
- assertEquals(1278370155.835435, x -= (-1278370411.835435));
- assertEquals(-3.488228054921667, x /= (tmp = -366481243.6881058, tmp));
- assertEquals(1.162742684973889, x /= ((x|(((((2404819175.562809)*(tmp = -2524589506, tmp))&(tmp = -675727145, tmp))>>>(x*x))&((-413250006)<<(tmp = 2408322715, tmp))))|((2940367603)>>>x)));
- assertEquals(0, x >>>= ((2513665793)-(tmp = 1249857454.3367786, tmp)));
- assertEquals(0, x ^= x);
- assertEquals(0, x ^= x);
- assertEquals(1989998348.6336238, x -= (-1989998348.6336238));
- assertEquals(903237918.986834, x %= (1086760429.6467898));
- assertEquals(-4.4185765232981975, x /= (-204418304));
- assertEquals(1471621914, x ^= (tmp = -1471621914.1771696, tmp));
- assertEquals(1471621914, x |= ((((((x<<(tmp = -2676407394.536844, tmp))%(((343324258)+(x/(x>>(((-221193011)>>>x)|x))))>>(((-2737713893)^((tmp = -49214797.00735545, tmp)+((-2818106123.172874)/(tmp = -2361786565.3028684, tmp))))<<(1859353297.6355076))))*(tmp = -751970685, tmp))|((tmp = 2502717391.425871, tmp)/(tmp = -2647169430, tmp)))*((tmp = -1647567294, tmp)&(((tmp = 1819557651, tmp)/x)>>((((-3073469753)/x)-(((tmp = -1973810496.6407511, tmp)&((x-(x+(tmp = -2986851659, tmp)))>>>(tmp = -2226975699, tmp)))|(418770782.142766)))<<x))))*(((((tmp = 125466732, tmp)/((((1453655756.398259)|(((874792086.7064595)-(194880772.91499102))>>>x))%(x<<(tmp = -1445557137, tmp)))<<x))>>>(tmp = -1953751906, tmp))/((tmp = -2140573172.2979035, tmp)*((-108581964)^x)))|(-481484013.0393069))));
- assertEquals(1454179065, x += ((tmp = 947147038.2829313, tmp)|(tmp = -154822975.3629098, tmp)));
- assertEquals(1, x /= x);
- assertEquals(1, x %= ((((((tmp = -2262250297.991866, tmp)-(tmp = 481953960, tmp))/(1629215187.6020458))|(2515244216))>>>((tmp = -3040594752.2184515, tmp)-(tmp = -1116041279, tmp)))^(((-182133502)-(1065160192.6609197))+(((((-1850040207)^(tmp = -1570328610, tmp))^(tmp = 20542725.09256518, tmp))*x)|(2386866629)))));
- assertEquals(1, x &= (2889186303));
- assertEquals(0, x >>= (((-1323093107.050538)>>(x%x))-(((((((-1736522840)+(tmp = -2623890690.8318863, tmp))*(959395040.5565329))*(233734920))<<((x+(x%((tmp = -2370717284.4370327, tmp)%(tmp = 2109311949, tmp))))-(tmp = -1005532894, tmp)))|(861703605))>>>((2399820772)/x))));
- assertEquals(0, x >>= x);
- assertEquals(57233408, x |= ((tmp = 2655923764.4179816, tmp)*(-1353634624.3025436)));
- assertEquals(997939728, x |= (980552208.9005274));
- assertEquals(1859642592476610800, x *= (1863481872));
- assertEquals(-977190656, x <<= x);
- assertEquals(4.378357529141239e+26, x *= ((((x/(((tmp = 2429520991, tmp)/(x/(tmp = 784592802, tmp)))-(tmp = -2704781982, tmp)))*(tmp = -2161015768.2322354, tmp))&((((-3164868762)>>(tmp = 2390893153.32907, tmp))^x)>>(-2422626718.322538)))*(tmp = 278291869, tmp)));
- assertEquals(4.378357529141239e+26, x -= (1710777896.992369));
- assertEquals(0, x &= (((((tmp = -2532956158.400033, tmp)|((2195255831.279001)|(1051047432)))|(-1628591858))|(tmp = -2042607521.947963, tmp))>>((-1471225208)/(((-133621318)>>(1980416325.7358408))*((1741069593.1036062)-(x|(2133911581.991011)))))));
- assertEquals(-0, x /= (-656083507));
- assertEquals(NaN, x += ((tmp = -1071410982.2789869, tmp)%x));
- assertEquals(NaN, x *= (tmp = -1513535145.3146675, tmp));
- assertEquals(0, x >>= ((2831245247.5267224)>>(x<<((x+(((3068824580.7922907)|(1708295544.275714))*((tmp = -1662930228.1170444, tmp)-(((tmp = 1979994889, tmp)<<(tmp = -1826911988, tmp))&((x/(x<<(1909384611.043981)))+(1958052414.7139997))))))<<(tmp = 2481909816.56558, tmp)))));
- assertEquals(0, x *= (((tmp = -2979739958.1614842, tmp)&x)+x));
- assertEquals(-0, x *= ((-332769864.50313234)^x));
- assertEquals(0, x >>= ((((689018886.1436445)+(tmp = -2819546038.620694, tmp))|(((tmp = -1459669934.9066005, tmp)|x)/x))<<(((tmp = 2640360389, tmp)/((x%((-1947492547.9056122)%((1487212416.2083092)-(-1751984129))))^x))%(tmp = 2666842881, tmp))));
- assertEquals(-1801321460, x |= (tmp = 2493645836, tmp));
- assertEquals(-1801321460, x %= (2400405136));
- assertEquals(-2905399858195810300, x *= (tmp = 1612926911, tmp));
- assertEquals(-2905399858195810300, x -= (x>>(tmp = 1603910263.9593458, tmp)));
- assertEquals(-238798848, x &= ((tmp = -2638646212.767516, tmp)/(((tmp = 1755616291.436998, tmp)>>>(tmp = 1083349775, tmp))-(x%(((tmp = 1728859105.53634, tmp)^(1931522619.0403612))/(tmp = 712460587.0025489, tmp))))));
- assertEquals(-2363873607.2302856, x += (-2125074759.230286));
- assertEquals(1712665, x &= (((117229515)>>>(((1707090894.1915488)>>>((-1696008695)>>(((-1045367326.7522249)<<(tmp = -209334716, tmp))-x)))|(-1707909786.080653)))%(1260761349.172689)));
- assertEquals(1073741824, x <<= (tmp = -289437762.34742975, tmp));
- assertEquals(1073741824, x &= (tmp = 2079141140, tmp));
- assertEquals(0, x <<= ((x^(-3139646716.1615124))-(((-362323071.74237394)|(tmp = 2989896849, tmp))*(tmp = -218217991, tmp))));
- assertEquals(0, x &= (tmp = -1476835288.425903, tmp));
- assertEquals(0, x >>>= (tmp = 61945262.70868635, tmp));
- assertEquals(0, x ^= x);
- assertEquals(-2735263498.7189775, x -= (2735263498.7189775));
- assertEquals(-1182289920, x <<= (x+x));
- assertEquals(-1182289580, x ^= ((2858446263.2258)>>>(2387398039.6273785)));
- assertEquals(696693056, x &= ((2178665823)*(-51848583)));
- assertEquals(1652555776, x <<= (((tmp = 2943916975, tmp)-((-1544273901)>>(-1671503106.2896929)))|x));
- assertEquals(6455296, x >>>= (tmp = 1492638248.675439, tmp));
- assertEquals(2097152, x &= (((x|x)*(2873891571.7000637))^((2165264807)+(tmp = 451721563, tmp))));
- assertEquals(2097152, x %= (tmp = 1089484582.1455994, tmp));
- assertEquals(2097152, x <<= x);
- assertEquals(2097152, x &= ((tmp = 119096343.4032247, tmp)^((-1947874541)*x)));
- assertEquals(0, x &= (tmp = 2363070677, tmp));
- assertEquals(0, x &= ((tmp = -1897325383, tmp)>>>((2368480527)>>>((tmp = 1837528979, tmp)*(-1838904077)))));
- assertEquals(-1898659416, x ^= (-1898659416.1125412));
- assertEquals(-725506048, x <<= x);
- assertEquals(1392943104, x <<= (295287938.9104482));
- assertEquals(-63620329, x ^= ((tmp = -3175925826.5573816, tmp)-(tmp = 2474613927, tmp)));
- assertEquals(-1135111726, x -= ((tmp = -1133259081, tmp)^(((tmp = -742228219, tmp)>>((-7801909.587711811)%((tmp = -642758873, tmp)+(tmp = 2893927824.6036444, tmp))))^((tmp = -2145465178.9142997, tmp)+x))));
- assertEquals(0, x ^= x);
- assertEquals(660714589, x |= (660714589));
- assertEquals(660714676, x ^= ((-376720042.8047826)>>>(2196220344)));
- assertEquals(660714676, x |= ((((((((x<<(-1140465568))-(tmp = -1648489774.1573918, tmp))%(((tmp = -2955505390.573639, tmp)*x)<<((((tmp = -1769375963, tmp)*(tmp = -440619797, tmp))&((tmp = 1904284066, tmp)%(-2420852665.0629807)))+(-324601009.2063596))))>>(tmp = 2317210783.9757776, tmp))^((tmp = 750057067.4541628, tmp)^(tmp = -1391814244.7286487, tmp)))>>((344544658.6054913)%((tmp = -1508630423.218488, tmp)&(tmp = 1918909238.2974637, tmp))))>>((-647746783.685822)&(tmp = 2444858958.3595476, tmp)))&x));
- assertEquals(-962337195, x ^= (tmp = -507358495.30825853, tmp));
- assertEquals(-182008925.58535767, x %= (tmp = -195082067.35366058, tmp));
- assertEquals(502070, x >>>= (tmp = 1459732237.1447744, tmp));
- assertEquals(-2391009930.7235765, x -= (tmp = 2391512000.7235765, tmp));
- assertEquals(1568669696, x <<= x);
- assertEquals(0, x <<= (tmp = -571056688.2717848, tmp));
- assertEquals(1770376226, x ^= (tmp = 1770376226.0584736, tmp));
- assertEquals(0, x ^= x);
- assertEquals(0, x &= ((((x<<x)>>>x)|x)|(((tmp = -2141573723, tmp)^x)|(64299956))));
- assertEquals(0, x ^= x);
- assertEquals(0, x &= x);
- assertEquals(0, x <<= (1106060336.7362857));
- assertEquals(-0, x /= (x|(tmp = 2760823963, tmp)));
- assertEquals(0, x <<= ((-2436225757)|(-1800598694.4062433)));
- assertEquals(0, x >>>= ((-728332508.9870625)<<x));
- assertEquals(-173377680, x ^= ((tmp = -173377680, tmp)%(tmp = -2843994892, tmp)));
- assertEquals(-173377680, x |= ((((-819217898)&(tmp = -1321650255, tmp))&(x+((x^x)<<((1700753064)>>((((((-1038799327)>>((782275464)^x))-(tmp = -2113814317.8539028, tmp))>>(2143804838))&x)-((2970418921)/(-3073015285.6587048)))))))&((-1759593079.4077306)%((1699128805)-((tmp = -467193967, tmp)&(((2225788267.3466334)*(((2687946762.5504274)+x)>>>x))<<(-1853556066.880512)))))));
- assertEquals(-0.5520657226957338, x /= ((tmp = -755493878, tmp)&(tmp = 918108389, tmp)));
- assertEquals(0.30477656217556287, x *= x);
- assertEquals(0, x &= ((tmp = -2746007517, tmp)<<(2749629340)));
- assertEquals(0, x ^= ((x%(tmp = 1683077876, tmp))%(-162706778)));
- assertEquals(0, x *= (tmp = 10203423, tmp));
- assertEquals(119043212.1461842, x += (tmp = 119043212.1461842, tmp));
- assertEquals(587202560, x <<= (tmp = 658697910.7051642, tmp));
- assertEquals(-138689730, x |= (x-(tmp = 1296317634.5661907, tmp)));
- assertEquals(-138663011, x -= ((-1751010109.5506423)>>(152829872)));
- assertEquals(-138663011, x %= (-1266200468));
- assertEquals(-138663011, x &= (x|((tmp = -571277275.622529, tmp)<<x)));
- assertEquals(-138663011, x >>= ((971259905.1265712)*(tmp = 2203764981, tmp)));
- assertEquals(-138663011, x %= (-904715829));
- assertEquals(-138663011, x |= ((tmp = -2823047885.283391, tmp)>>>(((tmp = 533217000, tmp)|(650754598.7836078))|(-1475565890))));
- assertEquals(-1610612736, x <<= x);
- assertEquals(-1610612736, x &= x);
- assertEquals(163840, x >>>= (-188885010));
- assertEquals(-1224224814, x |= (tmp = 3070742482, tmp));
- assertEquals(1498726395213334500, x *= x);
- assertEquals(1723591210, x |= ((tmp = 615164458, tmp)|x));
- assertEquals(1721910480, x ^= (x>>>x));
- assertEquals(4505284605.764313, x -= (tmp = -2783374125.7643127, tmp));
- assertEquals(-9504912393868483000, x *= (((tmp = 2896651872, tmp)<<(-2896385692.9017262))&(((((tmp = -2081179810.20238, tmp)|(tmp = -2484863999, tmp))>>((tmp = 1560885110.2665749, tmp)/(((tmp = 934324123.4289343, tmp)<<((tmp = -1591614157.0496385, tmp)+x))/(((x%(((tmp = 1672629986.8055913, tmp)%x)>>(tmp = 2116315086.2559657, tmp)))/(((-2687682697.5806303)>>x)/(-2034391222.5029132)))%(x-((((((tmp = 2598594967, tmp)/(((((((2950032233)%x)/x)^(tmp = -2126753451.3732262, tmp))<<(tmp = -3019113473, tmp))+(tmp = -2021220129.2320697, tmp))%((((-587645875.4666483)>>(((((x+x)+x)&(tmp = 533801785, tmp))|x)-((tmp = -2224808495.678903, tmp)/(1501942300))))>>>(-2558947646))>>((2798508249.020792)>>>x))))>>>((1060584557)/((((((((x&x)|(1426725365))>>>(tmp = 1500508838, tmp))>>(-1328705938))*((tmp = -2288009425.598777, tmp)>>>(((2586897285.9759064)%((-1605651559.2122297)>>>(tmp = 1936736684.4887302, tmp)))+((tmp = 2316261040, tmp)^(570340750.353874)))))&(x^((tmp = -2266524143, tmp)-(tmp = 2358520476, tmp))))+(tmp = 1449254900.9222453, tmp))%((-100598196)%((tmp = -2985318242.153491, tmp)>>((620722274.4565848)>>(871118975)))))))<<x)*(tmp = -1287065606.4143271, tmp))>>>(1038059916.2438471)))))))+((x/(-276990308.1264961))&(tmp = 2471016351.2195315, tmp)))|(((((tmp = -1288792769.3210807, tmp)+((tmp = -641817194, tmp)*(x<<(((-1933817364)>>(((tmp = 2084673536, tmp)|x)&x))&(tmp = -2752464480, tmp)))))%((796026752)*x))+(((tmp = -3083359669, tmp)|x)-((715303522)|(tmp = 181297266, tmp))))*(-1691520182.3207517)))));
- assertEquals(0, x <<= (-2322389800));
- assertEquals(0, x *= (tmp = 3188682235, tmp));
- assertEquals(0, x |= (x>>>((tmp = -2729325231.8288336, tmp)^((-393497076.96012783)*(x/(tmp = -2198942459.9466457, tmp))))));
- assertEquals(0, x ^= x);
- assertEquals(0, x %= (2835024997.4447937));
- assertEquals(0, x <<= x);
- assertEquals(0, x >>= (tmp = 1109824126, tmp));
- assertEquals(0, x <<= (3013043386));
- assertEquals(206825782.74659085, x -= (-206825782.74659085));
- assertEquals(-645346761227699500, x *= (-3120243292));
- assertEquals(6825462, x >>= ((tmp = 1457908135, tmp)<<x));
- assertEquals(-612366097.9189918, x -= (619191559.9189918));
- assertEquals(-612306090.9189918, x -= ((2328676543.893506)>>x));
- assertEquals(0, x ^= (x>>(((x>>>(1856200611.2269292))&(tmp = 2003217473, tmp))%((((((-107135673)+(((3062079356.170611)<<(tmp = -676928983, tmp))>>((tmp = -1487074941.2638814, tmp)|((-1601614031)/(1317006144.5025365)))))+x)*(((1163301641)>>>(448796567))/((x%((tmp = 72293197.34410787, tmp)+(-2304112723)))/((455610361)%(-2799431520)))))>>>(-217305041.09432888))<<(x-(tmp = -2168353649, tmp))))));
- assertEquals(0, x >>= x);
- assertEquals(-Infinity, x -= (((-1651597599.8950624)+(1780404320))/x));
- assertEquals(0, x <<= (tmp = 2246420272.4321294, tmp));
- assertEquals(0, x *= ((2793605382)-(tmp = -272299011, tmp)));
- assertEquals(0, x *= x);
- assertEquals(0, x <<= x);
- assertEquals(0, x >>= (tmp = 2556413090, tmp));
- assertEquals(0, x >>= ((tmp = -1784710085, tmp)%x));
- assertEquals(0, x %= (tmp = -1929880813, tmp));
- assertEquals(0, x *= (2586983368));
- assertEquals(0, x &= x);
- assertEquals(0, x <<= (-2144588807));
- assertEquals(0, x ^= ((x<<(((((((-596537598)+((x-(((((((tmp = -3179604796, tmp)/((tmp = 1156725365.3543215, tmp)>>>(tmp = -2762144319, tmp)))%(x<<x))&((tmp = 1750241928.1271567, tmp)&(x/((tmp = 1781306819, tmp)|x))))+((((2893068644)/((tmp = -576164593.9720252, tmp)<<((2724671.48995471)&(tmp = -573132475, tmp))))%(tmp = -1355625108, tmp))&(tmp = -302869512.5880568, tmp)))+x)<<x))>>((tmp = -2569172808, tmp)/x)))^x)-(tmp = -1174006275.2213159, tmp))&x)&(((((((-2303274799)>>(tmp = -814839320, tmp))/(tmp = 183887306.09810615, tmp))>>(((tmp = 1054106394.3704875, tmp)|x)>>>x))-(x-(tmp = 1313696830, tmp)))-((tmp = 2373274399.0742035, tmp)|((((tmp = -3163779539.4902935, tmp)*(tmp = -3056125181.726942, tmp))&(((x^(x^(x/((tmp = -576441696.6015451, tmp)<<(tmp = -26223719.920306206, tmp)))))>>(tmp = -2332835940, tmp))|((-146303509.41093707)&(tmp = -2676964025, tmp))))/((((x*(tmp = 1059918020, tmp))|((((2341797349)|(tmp = -744763805.1381104, tmp))<<x)+((2991320875.552578)^(2920702604.701831))))^(-1721756138))^(((tmp = -2794367554, tmp)>>((-2671235923.2097874)<<(x&((((tmp = -621472314.0859051, tmp)-(((x*x)+x)>>>((tmp = 1834038956, tmp)+x)))*x)^(tmp = -2090567586.321468, tmp)))))<<(321395210))))))>>>(tmp = -1207661719, tmp)))+(-2877264053.3805156)))/(x%(tmp = -2226991657.709366, tmp))));
- assertEquals(0, x *= (tmp = 986904991.061398, tmp));
- assertEquals(0, x -= (x%(650819306.6671969)));
- assertEquals(0, x >>>= (905893666.2871252));
- assertEquals(0, x += (((tmp = 2501942710.4804144, tmp)&x)/((tmp = -851080399.1751502, tmp)-(-1168623992))));
- assertEquals(-0, x *= (tmp = -2014577821.4554045, tmp));
- assertEquals(0, x &= (tmp = 1995246018, tmp));
- assertEquals(0, x %= (1724355237.7031958));
- assertEquals(-954696411, x += (((-2825222201)+(((1662353496.1795506)>>>(x-x))|(tmp = 225015046, tmp)))^(x&x)));
- assertEquals(-2158427339993389800, x *= (2260852052.1539803));
- assertEquals(19559, x >>>= (-862409169.4978967));
- assertEquals(-0.000012241163878671237, x /= (x^(tmp = 2697144215.160239, tmp)));
- assertEquals(0, x -= x);
- assertEquals(1448177644, x |= (tmp = 1448177644.624848, tmp));
- assertEquals(1448177644, x %= (((-1497553637.4976408)+(402228446))<<x));
- assertEquals(2304640553, x -= (-856462909));
- assertEquals(152436736, x &= ((766686903)*(((tmp = 660964683.1744609, tmp)|((((tmp = 297369746, tmp)-(x+((tmp = -2677127146, tmp)/x)))>>(((((((x%(x<<x))-(((((529254728)|((x|(-1407086127.6088922))&(tmp = -1968465008.5000398, tmp)))/(x%x))&((((-2761805265.92574)-x)*(x^(tmp = 110730179, tmp)))%((177220657.06030762)*(((2532585190.671373)/x)+(-1465143151)))))<<((tmp = -3008848338, tmp)<<(-2475597073))))|((-192996756.38619018)|((((1445996780)|(x>>>((((tmp = -2482370545.791443, tmp)*(tmp = -270543594, tmp))^x)*((1346780586)/(tmp = -625613363.885356, tmp)))))-(x<<(x/(-562307527))))&(-125701272))))*((x&x)%(tmp = 752963070, tmp)))>>>(tmp = 17419750.79086232, tmp))*x)^(x^((-157821212.04674292)-(tmp = 503849221.598824, tmp)))))-(tmp = 1479418449, tmp)))>>>((((((-78138548.2193842)<<(((2319032860.806689)-(tmp = -1564963892.5137577, tmp))>>>(-73673322.28957987)))<<((1797573493.3467085)*x))>>(tmp = 759994997, tmp))>>>(-1066441220))&(((((((tmp = 1972048857, tmp)*(((x&((-1347017320.0747669)>>>x))*(-2332716925.705054))%(-376976019.24362826)))>>>((tmp = -466479974, tmp)+x))&(-2282789473.3675604))|(((((((((269205423.7510414)-(tmp = 21919626.105656862, tmp))*((x-(tmp = -378670528, tmp))>>(tmp = -1045706598, tmp)))>>(tmp = -3062647341.234485, tmp))>>>x)|(tmp = -285399599.9386575, tmp))%(tmp = 2731214562, tmp))|((((tmp = 837093165.3438574, tmp)|(tmp = -2956931321, tmp))+((1871874558.3292787)<<((x|((tmp = -3169147427, tmp)%(((x^x)%(1479885041))%((1769991217)%(tmp = -1899472458, tmp)))))*(tmp = -837098563.71806, tmp))))>>(tmp = -1866722748, tmp)))-(2037734340.8345597)))>>((tmp = -1262019180.5332131, tmp)+(x*(1274173993.9800131))))*(tmp = 2336989321.855402, tmp))))));
- assertEquals(4, x >>= (tmp = -2577728327, tmp));
- assertEquals(16, x *= (x<<((2622323372.580596)*(tmp = -1947643367, tmp))));
- assertEquals(33554432, x <<= (tmp = -2938370507, tmp));
- assertEquals(-2399497018.987414, x -= (tmp = 2433051450.987414, tmp));
- assertEquals(1, x /= x);
- assertEquals(2, x <<= x);
- assertEquals(0, x >>= (x&x));
- assertEquals(0, x <<= x);
-}
-f();
diff --git a/deps/v8/test/mjsunit/object-define-property.js b/deps/v8/test/mjsunit/object-define-property.js
index fdaf82d10..970a80334 100644
--- a/deps/v8/test/mjsunit/object-define-property.js
+++ b/deps/v8/test/mjsunit/object-define-property.js
@@ -27,7 +27,7 @@
// Tests the object.defineProperty method - ES 15.2.3.6
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --es5-readonly
// Check that an exception is thrown when null is passed as object.
var exception = false;
@@ -1057,6 +1057,8 @@ assertEquals(999, o[999]);
// Regression test: Bizzare behavior on non-strict arguments object.
+// TODO(yangguo): Tests disabled, needs investigation!
+/*
(function test(arg0) {
// Here arguments[0] is a fast alias on arg0.
Object.defineProperty(arguments, "0", {
@@ -1075,7 +1077,7 @@ assertEquals(999, o[999]);
assertEquals(2, arg0);
assertEquals(3, arguments[0]);
})(0);
-
+*/
// Regression test: We should never observe the hole value.
var objectWithGetter = {};
@@ -1085,3 +1087,106 @@ assertEquals(undefined, objectWithGetter.__lookupSetter__('foo'));
var objectWithSetter = {};
objectWithSetter.__defineSetter__('foo', function(x) {});
assertEquals(undefined, objectWithSetter.__lookupGetter__('foo'));
+
+// An object with a getter on the prototype chain.
+function getter() { return 111; }
+function anotherGetter() { return 222; }
+
+function testGetterOnProto(expected, o) {
+ assertEquals(expected, o.quebec);
+}
+
+obj1 = {};
+Object.defineProperty(obj1, "quebec", { get: getter, configurable: true });
+obj2 = Object.create(obj1);
+obj3 = Object.create(obj2);
+
+testGetterOnProto(111, obj3);
+testGetterOnProto(111, obj3);
+%OptimizeFunctionOnNextCall(testGetterOnProto);
+testGetterOnProto(111, obj3);
+testGetterOnProto(111, obj3);
+
+Object.defineProperty(obj1, "quebec", { get: anotherGetter });
+
+testGetterOnProto(222, obj3);
+testGetterOnProto(222, obj3);
+%OptimizeFunctionOnNextCall(testGetterOnProto);
+testGetterOnProto(222, obj3);
+testGetterOnProto(222, obj3);
+
+// An object with a setter on the prototype chain.
+var modifyMe;
+function setter(x) { modifyMe = x+1; }
+function anotherSetter(x) { modifyMe = x+2; }
+
+function testSetterOnProto(expected, o) {
+ modifyMe = 333;
+ o.romeo = 444;
+ assertEquals(expected, modifyMe);
+}
+
+obj1 = {};
+Object.defineProperty(obj1, "romeo", { set: setter, configurable: true });
+obj2 = Object.create(obj1);
+obj3 = Object.create(obj2);
+
+testSetterOnProto(445, obj3);
+testSetterOnProto(445, obj3);
+%OptimizeFunctionOnNextCall(testSetterOnProto);
+testSetterOnProto(445, obj3);
+testSetterOnProto(445, obj3);
+
+Object.defineProperty(obj1, "romeo", { set: anotherSetter });
+
+testSetterOnProto(446, obj3);
+testSetterOnProto(446, obj3);
+%OptimizeFunctionOnNextCall(testSetterOnProto);
+testSetterOnProto(446, obj3);
+testSetterOnProto(446, obj3);
+
+// Removing a setter on the prototype chain.
+function testSetterOnProtoStrict(o) {
+ "use strict";
+ o.sierra = 12345;
+}
+
+obj1 = {};
+Object.defineProperty(obj1, "sierra",
+ { get: getter, set: setter, configurable: true });
+obj2 = Object.create(obj1);
+obj3 = Object.create(obj2);
+
+testSetterOnProtoStrict(obj3);
+testSetterOnProtoStrict(obj3);
+%OptimizeFunctionOnNextCall(testSetterOnProtoStrict);
+testSetterOnProtoStrict(obj3);
+testSetterOnProtoStrict(obj3);
+
+Object.defineProperty(obj1, "sierra",
+ { get: getter, set: undefined, configurable: true });
+
+exception = false;
+try {
+ testSetterOnProtoStrict(obj3);
+} catch (e) {
+ exception = true;
+ assertTrue(/which has only a getter/.test(e));
+}
+assertTrue(exception);
+
+// Test assignment to a getter-only property on the prototype chain. This makes
+// sure that crankshaft re-checks its assumptions and doesn't rely only on type
+// feedback (which would be monomorphic here).
+
+function Assign(o) {
+ o.blubb = 123;
+}
+
+function C() {}
+
+Assign(new C);
+Assign(new C);
+%OptimizeFunctionOnNextCall(Assign);
+Object.defineProperty(C.prototype, "blubb", {get: function() { return -42; }});
+Assign(new C);
diff --git a/deps/v8/test/mjsunit/packed-elements.js b/deps/v8/test/mjsunit/packed-elements.js
index 7f333e56e..cfcdf8031 100644
--- a/deps/v8/test/mjsunit/packed-elements.js
+++ b/deps/v8/test/mjsunit/packed-elements.js
@@ -96,9 +96,9 @@ function test6() {
function test_with_optimization(f) {
// Run tests in a loop to make sure that inlined Array() constructor runs out
// of new space memory and must fall back on runtime impl.
- for (i = 0; i < 250000; ++i) f();
+ for (i = 0; i < 25000; ++i) f();
%OptimizeFunctionOnNextCall(f);
- for (i = 0; i < 250000; ++i) f(); // Make sure GC happens
+ for (i = 0; i < 25000; ++i) f(); // Make sure GC happens
}
if (has_packed_elements) {
diff --git a/deps/v8/test/mjsunit/parse-int-float.js b/deps/v8/test/mjsunit/parse-int-float.js
index 2e4f64843..5a9b6f33c 100644
--- a/deps/v8/test/mjsunit/parse-int-float.js
+++ b/deps/v8/test/mjsunit/parse-int-float.js
@@ -29,10 +29,10 @@ assertEquals(0, parseInt('0'));
assertEquals(0, parseInt(' 0'));
assertEquals(0, parseInt(' 0 '));
-assertEquals(63, parseInt('077'));
-assertEquals(63, parseInt(' 077'));
-assertEquals(63, parseInt(' 077 '));
-assertEquals(-63, parseInt(' -077'));
+assertEquals(77, parseInt('077'));
+assertEquals(77, parseInt(' 077'));
+assertEquals(77, parseInt(' 077 '));
+assertEquals(-77, parseInt(' -077'));
assertEquals(3, parseInt('11', 2));
assertEquals(4, parseInt('11', 3));
diff --git a/deps/v8/test/mjsunit/pixel-array-rounding.js b/deps/v8/test/mjsunit/pixel-array-rounding.js
index ef5a10bdf..0c307e62e 100644..100755
--- a/deps/v8/test/mjsunit/pixel-array-rounding.js
+++ b/deps/v8/test/mjsunit/pixel-array-rounding.js
@@ -27,7 +27,7 @@
// Flags: --allow-natives-syntax
-var pixels = new PixelArray(8);
+var pixels = new Uint8ClampedArray(8);
function f() {
for (var i = 0; i < 8; i++) {
diff --git a/deps/v8/test/mjsunit/regexp-capture-3.js b/deps/v8/test/mjsunit/regexp-capture-3.js
index b676f01c2..b676f01c2 100644..100755
--- a/deps/v8/test/mjsunit/regexp-capture-3.js
+++ b/deps/v8/test/mjsunit/regexp-capture-3.js
diff --git a/deps/v8/test/mjsunit/regexp-global.js b/deps/v8/test/mjsunit/regexp-global.js
index cc360d3ce..093dba17c 100644
--- a/deps/v8/test/mjsunit/regexp-global.js
+++ b/deps/v8/test/mjsunit/regexp-global.js
@@ -139,3 +139,116 @@ str = str.replace(/\b(?=u(p))/g, function(match, capture) {
});
assertEquals("1up 1up 1up 1up", str);
+
+
+// Create regexp that has a *lot* of captures.
+var re_string = "(a)";
+for (var i = 0; i < 500; i++) {
+ re_string = "(" + re_string + ")";
+}
+re_string = re_string + "1";
+// re_string = "(((...((a))...)))1"
+
+var regexps = new Array();
+var last_match_expectations = new Array();
+var first_capture_expectations = new Array();
+
+// Atomic regexp.
+regexps.push(/a1/g);
+last_match_expectations.push("a1");
+first_capture_expectations.push("");
+// Small regexp (no capture);
+regexps.push(/\w1/g);
+last_match_expectations.push("a1");
+first_capture_expectations.push("");
+// Small regexp (one capture).
+regexps.push(/(a)1/g);
+last_match_expectations.push("a1");
+first_capture_expectations.push("a");
+// Large regexp (a lot of captures).
+regexps.push(new RegExp(re_string, "g"));
+last_match_expectations.push("a1");
+first_capture_expectations.push("a");
+
+function test_replace(result_expectation,
+ subject,
+ regexp,
+ replacement) {
+ for (var i = 0; i < regexps.length; i++) {
+ // Overwrite last match info.
+ "deadbeef".replace(/(dead)beef/, "$1holeycow");
+ // Conduct tests.
+ assertEquals(result_expectation, subject.replace(regexps[i], replacement));
+ if (subject.length == 0) {
+ assertEquals("deadbeef", RegExp.lastMatch);
+ assertEquals("dead", RegExp["$1"]);
+ } else {
+ assertEquals(last_match_expectations[i], RegExp.lastMatch);
+ assertEquals(first_capture_expectations[i], RegExp["$1"]);
+ }
+ }
+}
+
+
+function test_match(result_expectation,
+ subject,
+ regexp) {
+ for (var i = 0; i < regexps.length; i++) {
+ // Overwrite last match info.
+ "deadbeef".replace(/(dead)beef/, "$1holeycow");
+ // Conduct tests.
+ if (result_expectation == null) {
+ assertNull(subject.match(regexps[i]));
+ } else {
+ assertArrayEquals(result_expectation, subject.match(regexps[i]));
+ }
+ if (subject.length == 0) {
+ assertEquals("deadbeef", RegExp.lastMatch);
+ assertEquals("dead", RegExp["$1"]);
+ } else {
+ assertEquals(last_match_expectations[i], RegExp.lastMatch);
+ assertEquals(first_capture_expectations[i], RegExp["$1"]);
+ }
+ }
+}
+
+
+// Test for different number of matches.
+for (var m = 0; m < 200; m++) {
+ // Create string that matches m times.
+ var subject = "";
+ var test_1_expectation = "";
+ var test_2_expectation = "";
+ var test_3_expectation = (m == 0) ? null : new Array();
+ for (var i = 0; i < m; i++) {
+ subject += "a11";
+ test_1_expectation += "x1";
+ test_2_expectation += "1";
+ test_3_expectation.push("a1");
+ }
+
+ // Test 1a: String.replace with string.
+ test_replace(test_1_expectation, subject, /a1/g, "x");
+
+ // Test 1b: String.replace with function.
+ function f() { return "x"; }
+ test_replace(test_1_expectation, subject, /a1/g, f);
+
+ // Test 2a: String.replace with empty string.
+ test_replace(test_2_expectation, subject, /a1/g, "");
+
+ // Test 3a: String.match.
+ test_match(test_3_expectation, subject, /a1/g);
+}
+
+
+// Test String hashing (compiling regular expression includes hashing).
+var crosscheck = "\x80";
+for (var i = 0; i < 12; i++) crosscheck += crosscheck;
+new RegExp(crosscheck);
+
+var subject = "ascii~only~string~here~";
+var replacement = "\x80";
+var result = subject.replace(/~/g, replacement);
+for (var i = 0; i < 5; i++) result += result;
+new RegExp(result);
diff --git a/deps/v8/test/mjsunit/regexp-results-cache.js b/deps/v8/test/mjsunit/regexp-results-cache.js
new file mode 100644
index 000000000..7ee8c3fac
--- /dev/null
+++ b/deps/v8/test/mjsunit/regexp-results-cache.js
@@ -0,0 +1,78 @@
+// Copyright 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.
+
+// Long string to trigger caching.
+var string =
+"Friends, Romans, countrymen, lend me your ears! \
+ I come to bury Caesar, not to praise him. \
+ The evil that men do lives after them, \
+ The good is oft interred with their bones; \
+ So let it be with Caesar. The noble Brutus \
+ Hath told you Caesar was ambitious; \
+ If it were so, it was a grievous fault, \
+ And grievously hath Caesar answer'd it. \
+ Here, under leave of Brutus and the rest- \
+ For Brutus is an honorable man; \
+ So are they all, all honorable men- \
+ Come I to speak in Caesar's funeral. \
+ He was my friend, faithful and just to me; \
+ But Brutus says he was ambitious, \
+ And Brutus is an honorable man. \
+ He hath brought many captives home to Rome, \
+ Whose ransoms did the general coffers fill. \
+ Did this in Caesar seem ambitious? \
+ When that the poor have cried, Caesar hath wept; \
+ Ambition should be made of sterner stuff: \
+ Yet Brutus says he was ambitious, \
+ And Brutus is an honorable man. \
+ You all did see that on the Lupercal \
+ I thrice presented him a kingly crown, \
+ Which he did thrice refuse. Was this ambition? \
+ Yet Brutus says he was ambitious, \
+ And sure he is an honorable man. \
+ I speak not to disprove what Brutus spoke, \
+ But here I am to speak what I do know. \
+ You all did love him once, not without cause; \
+ What cause withholds you then to mourn for him? \
+ O judgement, thou art fled to brutish beasts, \
+ And men have lost their reason. Bear with me; \
+ My heart is in the coffin there with Caesar, \
+ And I must pause till it come back to me.";
+
+var replaced = string.replace(/\b\w+\b/g, function() { return "foo"; });
+for (var i = 0; i < 3; i++) {
+ assertEquals(replaced,
+ string.replace(/\b\w+\b/g, function() { return "foo"; }));
+}
+
+// Check that the result is in a COW array.
+var words = string.split(" ");
+assertEquals("Friends,", words[0]);
+words[0] = "Enemies,";
+words = string.split(" ");
+assertEquals("Friends,", words[0]);
+
diff --git a/deps/v8/test/mjsunit/regress/regress-1117.js b/deps/v8/test/mjsunit/regress/regress-1117.js
index b013a223e..981a1b7a3 100644
--- a/deps/v8/test/mjsunit/regress/regress-1117.js
+++ b/deps/v8/test/mjsunit/regress/regress-1117.js
@@ -25,11 +25,20 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
// Test that we actually return the right value (-0) when we multiply
// constant 0 with a negative integer.
function foo(y) {return 0 * y; }
-for( var i = 0; i< 1000000; i++){
- foo(42);
-}
assertEquals(1/foo(-42), -Infinity);
+assertEquals(1/foo(-42), -Infinity);
+%OptimizeFunctionOnNextCall(foo);
+assertEquals(1/foo(-42), -Infinity);
+
+function bar(x) { return x * 0; }
+assertEquals(Infinity, 1/bar(5));
+assertEquals(Infinity, 1/bar(5));
+%OptimizeFunctionOnNextCall(bar);
+assertEquals(-Infinity, 1/bar(-5));
+
diff --git a/deps/v8/test/mjsunit/regress/regress-1118.js b/deps/v8/test/mjsunit/regress/regress-1118.js
index 7e0461db4..3e3920f3d 100644
--- a/deps/v8/test/mjsunit/regress/regress-1118.js
+++ b/deps/v8/test/mjsunit/regress/regress-1118.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --noparallel-recompilation
// An exception thrown in a function optimized by on-stack replacement (OSR)
// should be able to construct a receiver from all optimized stack frames.
diff --git a/deps/v8/test/mjsunit/regress/regress-131994.js b/deps/v8/test/mjsunit/regress/regress-131994.js
new file mode 100644
index 000000000..8347653a9
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-131994.js
@@ -0,0 +1,70 @@
+// Copyright 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.
+
+// Flags: --expose-debug-as debug
+
+// Test that a variable in the local scope that shadows a context-allocated
+// variable is correctly resolved when being evaluated in the debugger.
+
+Debug = debug.Debug;
+
+var exception = false;
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ var breakpoint = exec_state.frame(0);
+ try {
+ // Assert correct break point.
+ assertTrue(breakpoint.sourceLineText().indexOf("// Break") > -1);
+ // Assert correct value.
+ assertEquals(3, breakpoint.evaluate('x').value());
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+function h() {
+ var x; // Context-allocated due to g().
+
+ var g = function g() {
+ x = -7;
+ };
+
+ var f = function f() {
+ var x = 3; // Allocated in the local scope.
+ debugger; // Break.
+ };
+
+ f();
+}
+
+h();
+
+assertFalse(exception);
+
diff --git a/deps/v8/test/mjsunit/regress/regress-136048.js b/deps/v8/test/mjsunit/regress/regress-136048.js
new file mode 100644
index 000000000..c9972e96f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-136048.js
@@ -0,0 +1,34 @@
+// Copyright 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.
+
+try {
+ /foo/\u0069
+} catch (e) {
+ assertEquals(
+ "SyntaxError: Invalid flags supplied to RegExp constructor '\\u0069'",
+ e.toString());
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-137768.js b/deps/v8/test/mjsunit/regress/regress-137768.js
new file mode 100644
index 000000000..9fbd7f30a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-137768.js
@@ -0,0 +1,73 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+// Create elements in a constructor function to ensure map sharing.
+function TestConstructor() {
+ this[0] = 1;
+ this[1] = 2;
+ this[2] = 3;
+}
+
+function bad_func(o,a) {
+ var s = 0;
+ for (var i = 0; i < 1; ++i) {
+ o.newFileToChangeMap = undefined;
+ var x = a[0];
+ s += x;
+ }
+ return s;
+}
+
+o = new Object();
+a = new TestConstructor();
+bad_func(o, a);
+
+// Make sure that we're out of pre-monomorphic state for the member add of
+// 'newFileToChangeMap' which causes a map transition.
+o = new Object();
+a = new TestConstructor();
+bad_func(o, a);
+
+// Optimize, before the fix, the element load and subsequent tagged-to-i were
+// hoisted above the map check, which can't be hoisted due to the map-changing
+// store.
+o = new Object();
+a = new TestConstructor();
+%OptimizeFunctionOnNextCall(bad_func);
+bad_func(o, a);
+
+// Pass in a array of doubles. Before the fix, the optimized load and
+// tagged-to-i will treat part of a double value as a pointer and de-ref it
+// before the map check was executed that should have deopt.
+o = new Object();
+// Pass in an elements buffer where the bit representation of the double numbers
+// are two adjacent small 32-bit values with the lowest bit set to one, causing
+// tagged-to-i to SIGSEGV.
+a = [2.122e-314, 2.122e-314, 2.122e-314];
+bad_func(o, a);
diff --git a/deps/v8/test/mjsunit/regress/regress-143967.js b/deps/v8/test/mjsunit/regress/regress-143967.js
new file mode 100644
index 000000000..7c12e6715
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-143967.js
@@ -0,0 +1,34 @@
+// Copyright 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.
+
+// Check that Accessors::FunctionGetPrototype traverses the prototype
+// chain correctly and doesn't get stuck.
+
+var functionWithoutProto = [].filter;
+var obj = Object.create(functionWithoutProto);
+functionWithoutProto.__proto__ = function() {};
+assertEquals(functionWithoutProto.prototype, obj.prototype);
diff --git a/deps/v8/test/mjsunit/regress/regress-148378.js b/deps/v8/test/mjsunit/regress/regress-148378.js
new file mode 100644
index 000000000..d37cea1cf
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-148378.js
@@ -0,0 +1,38 @@
+// Copyright 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.
+
+"a".replace(/a/g, function() { return "c"; });
+
+function test() {
+ try {
+ test();
+ } catch(e) {
+ "b".replace(/(b)/g, function() { return "c"; });
+ }
+}
+
+test();
diff --git a/deps/v8/test/mjsunit/regress/regress-1563.js b/deps/v8/test/mjsunit/regress/regress-1563.js
index c25b6c7f6..884b12595 100644
--- a/deps/v8/test/mjsunit/regress/regress-1563.js
+++ b/deps/v8/test/mjsunit/regress/regress-1563.js
@@ -27,7 +27,7 @@
// Flags: --allow-natives-syntax
-obj = new PixelArray(10);
+obj = new Uint8ClampedArray(10);
// Test that undefined gets properly clamped in Crankshafted pixel array
// assignments.
diff --git a/deps/v8/test/mjsunit/regress/regress-1591.js b/deps/v8/test/mjsunit/regress/regress-1591.js
new file mode 100644
index 000000000..69efd0bd8
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-1591.js
@@ -0,0 +1,48 @@
+// Copyright 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.
+
+var stack;
+var used_custom_lookup = false;
+
+({
+ __lookupGetter__ : function() {
+ used_custom_lookup = true;
+ },
+
+ test : function() {
+ try {
+ f();
+ } catch (err) {
+ stack = err.stack;
+ }
+ }
+}).test();
+
+var expected_message = "ReferenceError: f is not defined";
+assertTrue(stack.indexOf(expected_message) >= 0);
+assertFalse(used_custom_lookup);
+
diff --git a/deps/v8/test/mjsunit/regress/regress-1969.js b/deps/v8/test/mjsunit/regress/regress-1969.js
deleted file mode 100644
index 2728c2cae..000000000
--- a/deps/v8/test/mjsunit/regress/regress-1969.js
+++ /dev/null
@@ -1,5045 +0,0 @@
-// Copyright 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.
-
-// Flags: --allow-natives-syntax
-
-f();
-f();
-%OptimizeFunctionOnNextCall(f);
-var start = (new Date()).getTime();
-var array = f();
-var end = (new Date()).getTime();
-
-// Assert that recompiling and executing f() takes less than a second.
-assertTrue((end - start) < 1000);
-
-for (var i = 0; i < 5000; i++) assertEquals(0, array[i]);
-
-function f() {
- var a = new Array(5000);
- a[0]=0;
- a[1]=0;
- a[2]=0;
- a[3]=0;
- a[4]=0;
- a[5]=0;
- a[6]=0;
- a[7]=0;
- a[8]=0;
- a[9]=0;
- a[10]=0;
- a[11]=0;
- a[12]=0;
- a[13]=0;
- a[14]=0;
- a[15]=0;
- a[16]=0;
- a[17]=0;
- a[18]=0;
- a[19]=0;
- a[20]=0;
- a[21]=0;
- a[22]=0;
- a[23]=0;
- a[24]=0;
- a[25]=0;
- a[26]=0;
- a[27]=0;
- a[28]=0;
- a[29]=0;
- a[30]=0;
- a[31]=0;
- a[32]=0;
- a[33]=0;
- a[34]=0;
- a[35]=0;
- a[36]=0;
- a[37]=0;
- a[38]=0;
- a[39]=0;
- a[40]=0;
- a[41]=0;
- a[42]=0;
- a[43]=0;
- a[44]=0;
- a[45]=0;
- a[46]=0;
- a[47]=0;
- a[48]=0;
- a[49]=0;
- a[50]=0;
- a[51]=0;
- a[52]=0;
- a[53]=0;
- a[54]=0;
- a[55]=0;
- a[56]=0;
- a[57]=0;
- a[58]=0;
- a[59]=0;
- a[60]=0;
- a[61]=0;
- a[62]=0;
- a[63]=0;
- a[64]=0;
- a[65]=0;
- a[66]=0;
- a[67]=0;
- a[68]=0;
- a[69]=0;
- a[70]=0;
- a[71]=0;
- a[72]=0;
- a[73]=0;
- a[74]=0;
- a[75]=0;
- a[76]=0;
- a[77]=0;
- a[78]=0;
- a[79]=0;
- a[80]=0;
- a[81]=0;
- a[82]=0;
- a[83]=0;
- a[84]=0;
- a[85]=0;
- a[86]=0;
- a[87]=0;
- a[88]=0;
- a[89]=0;
- a[90]=0;
- a[91]=0;
- a[92]=0;
- a[93]=0;
- a[94]=0;
- a[95]=0;
- a[96]=0;
- a[97]=0;
- a[98]=0;
- a[99]=0;
- a[100]=0;
- a[101]=0;
- a[102]=0;
- a[103]=0;
- a[104]=0;
- a[105]=0;
- a[106]=0;
- a[107]=0;
- a[108]=0;
- a[109]=0;
- a[110]=0;
- a[111]=0;
- a[112]=0;
- a[113]=0;
- a[114]=0;
- a[115]=0;
- a[116]=0;
- a[117]=0;
- a[118]=0;
- a[119]=0;
- a[120]=0;
- a[121]=0;
- a[122]=0;
- a[123]=0;
- a[124]=0;
- a[125]=0;
- a[126]=0;
- a[127]=0;
- a[128]=0;
- a[129]=0;
- a[130]=0;
- a[131]=0;
- a[132]=0;
- a[133]=0;
- a[134]=0;
- a[135]=0;
- a[136]=0;
- a[137]=0;
- a[138]=0;
- a[139]=0;
- a[140]=0;
- a[141]=0;
- a[142]=0;
- a[143]=0;
- a[144]=0;
- a[145]=0;
- a[146]=0;
- a[147]=0;
- a[148]=0;
- a[149]=0;
- a[150]=0;
- a[151]=0;
- a[152]=0;
- a[153]=0;
- a[154]=0;
- a[155]=0;
- a[156]=0;
- a[157]=0;
- a[158]=0;
- a[159]=0;
- a[160]=0;
- a[161]=0;
- a[162]=0;
- a[163]=0;
- a[164]=0;
- a[165]=0;
- a[166]=0;
- a[167]=0;
- a[168]=0;
- a[169]=0;
- a[170]=0;
- a[171]=0;
- a[172]=0;
- a[173]=0;
- a[174]=0;
- a[175]=0;
- a[176]=0;
- a[177]=0;
- a[178]=0;
- a[179]=0;
- a[180]=0;
- a[181]=0;
- a[182]=0;
- a[183]=0;
- a[184]=0;
- a[185]=0;
- a[186]=0;
- a[187]=0;
- a[188]=0;
- a[189]=0;
- a[190]=0;
- a[191]=0;
- a[192]=0;
- a[193]=0;
- a[194]=0;
- a[195]=0;
- a[196]=0;
- a[197]=0;
- a[198]=0;
- a[199]=0;
- a[200]=0;
- a[201]=0;
- a[202]=0;
- a[203]=0;
- a[204]=0;
- a[205]=0;
- a[206]=0;
- a[207]=0;
- a[208]=0;
- a[209]=0;
- a[210]=0;
- a[211]=0;
- a[212]=0;
- a[213]=0;
- a[214]=0;
- a[215]=0;
- a[216]=0;
- a[217]=0;
- a[218]=0;
- a[219]=0;
- a[220]=0;
- a[221]=0;
- a[222]=0;
- a[223]=0;
- a[224]=0;
- a[225]=0;
- a[226]=0;
- a[227]=0;
- a[228]=0;
- a[229]=0;
- a[230]=0;
- a[231]=0;
- a[232]=0;
- a[233]=0;
- a[234]=0;
- a[235]=0;
- a[236]=0;
- a[237]=0;
- a[238]=0;
- a[239]=0;
- a[240]=0;
- a[241]=0;
- a[242]=0;
- a[243]=0;
- a[244]=0;
- a[245]=0;
- a[246]=0;
- a[247]=0;
- a[248]=0;
- a[249]=0;
- a[250]=0;
- a[251]=0;
- a[252]=0;
- a[253]=0;
- a[254]=0;
- a[255]=0;
- a[256]=0;
- a[257]=0;
- a[258]=0;
- a[259]=0;
- a[260]=0;
- a[261]=0;
- a[262]=0;
- a[263]=0;
- a[264]=0;
- a[265]=0;
- a[266]=0;
- a[267]=0;
- a[268]=0;
- a[269]=0;
- a[270]=0;
- a[271]=0;
- a[272]=0;
- a[273]=0;
- a[274]=0;
- a[275]=0;
- a[276]=0;
- a[277]=0;
- a[278]=0;
- a[279]=0;
- a[280]=0;
- a[281]=0;
- a[282]=0;
- a[283]=0;
- a[284]=0;
- a[285]=0;
- a[286]=0;
- a[287]=0;
- a[288]=0;
- a[289]=0;
- a[290]=0;
- a[291]=0;
- a[292]=0;
- a[293]=0;
- a[294]=0;
- a[295]=0;
- a[296]=0;
- a[297]=0;
- a[298]=0;
- a[299]=0;
- a[300]=0;
- a[301]=0;
- a[302]=0;
- a[303]=0;
- a[304]=0;
- a[305]=0;
- a[306]=0;
- a[307]=0;
- a[308]=0;
- a[309]=0;
- a[310]=0;
- a[311]=0;
- a[312]=0;
- a[313]=0;
- a[314]=0;
- a[315]=0;
- a[316]=0;
- a[317]=0;
- a[318]=0;
- a[319]=0;
- a[320]=0;
- a[321]=0;
- a[322]=0;
- a[323]=0;
- a[324]=0;
- a[325]=0;
- a[326]=0;
- a[327]=0;
- a[328]=0;
- a[329]=0;
- a[330]=0;
- a[331]=0;
- a[332]=0;
- a[333]=0;
- a[334]=0;
- a[335]=0;
- a[336]=0;
- a[337]=0;
- a[338]=0;
- a[339]=0;
- a[340]=0;
- a[341]=0;
- a[342]=0;
- a[343]=0;
- a[344]=0;
- a[345]=0;
- a[346]=0;
- a[347]=0;
- a[348]=0;
- a[349]=0;
- a[350]=0;
- a[351]=0;
- a[352]=0;
- a[353]=0;
- a[354]=0;
- a[355]=0;
- a[356]=0;
- a[357]=0;
- a[358]=0;
- a[359]=0;
- a[360]=0;
- a[361]=0;
- a[362]=0;
- a[363]=0;
- a[364]=0;
- a[365]=0;
- a[366]=0;
- a[367]=0;
- a[368]=0;
- a[369]=0;
- a[370]=0;
- a[371]=0;
- a[372]=0;
- a[373]=0;
- a[374]=0;
- a[375]=0;
- a[376]=0;
- a[377]=0;
- a[378]=0;
- a[379]=0;
- a[380]=0;
- a[381]=0;
- a[382]=0;
- a[383]=0;
- a[384]=0;
- a[385]=0;
- a[386]=0;
- a[387]=0;
- a[388]=0;
- a[389]=0;
- a[390]=0;
- a[391]=0;
- a[392]=0;
- a[393]=0;
- a[394]=0;
- a[395]=0;
- a[396]=0;
- a[397]=0;
- a[398]=0;
- a[399]=0;
- a[400]=0;
- a[401]=0;
- a[402]=0;
- a[403]=0;
- a[404]=0;
- a[405]=0;
- a[406]=0;
- a[407]=0;
- a[408]=0;
- a[409]=0;
- a[410]=0;
- a[411]=0;
- a[412]=0;
- a[413]=0;
- a[414]=0;
- a[415]=0;
- a[416]=0;
- a[417]=0;
- a[418]=0;
- a[419]=0;
- a[420]=0;
- a[421]=0;
- a[422]=0;
- a[423]=0;
- a[424]=0;
- a[425]=0;
- a[426]=0;
- a[427]=0;
- a[428]=0;
- a[429]=0;
- a[430]=0;
- a[431]=0;
- a[432]=0;
- a[433]=0;
- a[434]=0;
- a[435]=0;
- a[436]=0;
- a[437]=0;
- a[438]=0;
- a[439]=0;
- a[440]=0;
- a[441]=0;
- a[442]=0;
- a[443]=0;
- a[444]=0;
- a[445]=0;
- a[446]=0;
- a[447]=0;
- a[448]=0;
- a[449]=0;
- a[450]=0;
- a[451]=0;
- a[452]=0;
- a[453]=0;
- a[454]=0;
- a[455]=0;
- a[456]=0;
- a[457]=0;
- a[458]=0;
- a[459]=0;
- a[460]=0;
- a[461]=0;
- a[462]=0;
- a[463]=0;
- a[464]=0;
- a[465]=0;
- a[466]=0;
- a[467]=0;
- a[468]=0;
- a[469]=0;
- a[470]=0;
- a[471]=0;
- a[472]=0;
- a[473]=0;
- a[474]=0;
- a[475]=0;
- a[476]=0;
- a[477]=0;
- a[478]=0;
- a[479]=0;
- a[480]=0;
- a[481]=0;
- a[482]=0;
- a[483]=0;
- a[484]=0;
- a[485]=0;
- a[486]=0;
- a[487]=0;
- a[488]=0;
- a[489]=0;
- a[490]=0;
- a[491]=0;
- a[492]=0;
- a[493]=0;
- a[494]=0;
- a[495]=0;
- a[496]=0;
- a[497]=0;
- a[498]=0;
- a[499]=0;
- a[500]=0;
- a[501]=0;
- a[502]=0;
- a[503]=0;
- a[504]=0;
- a[505]=0;
- a[506]=0;
- a[507]=0;
- a[508]=0;
- a[509]=0;
- a[510]=0;
- a[511]=0;
- a[512]=0;
- a[513]=0;
- a[514]=0;
- a[515]=0;
- a[516]=0;
- a[517]=0;
- a[518]=0;
- a[519]=0;
- a[520]=0;
- a[521]=0;
- a[522]=0;
- a[523]=0;
- a[524]=0;
- a[525]=0;
- a[526]=0;
- a[527]=0;
- a[528]=0;
- a[529]=0;
- a[530]=0;
- a[531]=0;
- a[532]=0;
- a[533]=0;
- a[534]=0;
- a[535]=0;
- a[536]=0;
- a[537]=0;
- a[538]=0;
- a[539]=0;
- a[540]=0;
- a[541]=0;
- a[542]=0;
- a[543]=0;
- a[544]=0;
- a[545]=0;
- a[546]=0;
- a[547]=0;
- a[548]=0;
- a[549]=0;
- a[550]=0;
- a[551]=0;
- a[552]=0;
- a[553]=0;
- a[554]=0;
- a[555]=0;
- a[556]=0;
- a[557]=0;
- a[558]=0;
- a[559]=0;
- a[560]=0;
- a[561]=0;
- a[562]=0;
- a[563]=0;
- a[564]=0;
- a[565]=0;
- a[566]=0;
- a[567]=0;
- a[568]=0;
- a[569]=0;
- a[570]=0;
- a[571]=0;
- a[572]=0;
- a[573]=0;
- a[574]=0;
- a[575]=0;
- a[576]=0;
- a[577]=0;
- a[578]=0;
- a[579]=0;
- a[580]=0;
- a[581]=0;
- a[582]=0;
- a[583]=0;
- a[584]=0;
- a[585]=0;
- a[586]=0;
- a[587]=0;
- a[588]=0;
- a[589]=0;
- a[590]=0;
- a[591]=0;
- a[592]=0;
- a[593]=0;
- a[594]=0;
- a[595]=0;
- a[596]=0;
- a[597]=0;
- a[598]=0;
- a[599]=0;
- a[600]=0;
- a[601]=0;
- a[602]=0;
- a[603]=0;
- a[604]=0;
- a[605]=0;
- a[606]=0;
- a[607]=0;
- a[608]=0;
- a[609]=0;
- a[610]=0;
- a[611]=0;
- a[612]=0;
- a[613]=0;
- a[614]=0;
- a[615]=0;
- a[616]=0;
- a[617]=0;
- a[618]=0;
- a[619]=0;
- a[620]=0;
- a[621]=0;
- a[622]=0;
- a[623]=0;
- a[624]=0;
- a[625]=0;
- a[626]=0;
- a[627]=0;
- a[628]=0;
- a[629]=0;
- a[630]=0;
- a[631]=0;
- a[632]=0;
- a[633]=0;
- a[634]=0;
- a[635]=0;
- a[636]=0;
- a[637]=0;
- a[638]=0;
- a[639]=0;
- a[640]=0;
- a[641]=0;
- a[642]=0;
- a[643]=0;
- a[644]=0;
- a[645]=0;
- a[646]=0;
- a[647]=0;
- a[648]=0;
- a[649]=0;
- a[650]=0;
- a[651]=0;
- a[652]=0;
- a[653]=0;
- a[654]=0;
- a[655]=0;
- a[656]=0;
- a[657]=0;
- a[658]=0;
- a[659]=0;
- a[660]=0;
- a[661]=0;
- a[662]=0;
- a[663]=0;
- a[664]=0;
- a[665]=0;
- a[666]=0;
- a[667]=0;
- a[668]=0;
- a[669]=0;
- a[670]=0;
- a[671]=0;
- a[672]=0;
- a[673]=0;
- a[674]=0;
- a[675]=0;
- a[676]=0;
- a[677]=0;
- a[678]=0;
- a[679]=0;
- a[680]=0;
- a[681]=0;
- a[682]=0;
- a[683]=0;
- a[684]=0;
- a[685]=0;
- a[686]=0;
- a[687]=0;
- a[688]=0;
- a[689]=0;
- a[690]=0;
- a[691]=0;
- a[692]=0;
- a[693]=0;
- a[694]=0;
- a[695]=0;
- a[696]=0;
- a[697]=0;
- a[698]=0;
- a[699]=0;
- a[700]=0;
- a[701]=0;
- a[702]=0;
- a[703]=0;
- a[704]=0;
- a[705]=0;
- a[706]=0;
- a[707]=0;
- a[708]=0;
- a[709]=0;
- a[710]=0;
- a[711]=0;
- a[712]=0;
- a[713]=0;
- a[714]=0;
- a[715]=0;
- a[716]=0;
- a[717]=0;
- a[718]=0;
- a[719]=0;
- a[720]=0;
- a[721]=0;
- a[722]=0;
- a[723]=0;
- a[724]=0;
- a[725]=0;
- a[726]=0;
- a[727]=0;
- a[728]=0;
- a[729]=0;
- a[730]=0;
- a[731]=0;
- a[732]=0;
- a[733]=0;
- a[734]=0;
- a[735]=0;
- a[736]=0;
- a[737]=0;
- a[738]=0;
- a[739]=0;
- a[740]=0;
- a[741]=0;
- a[742]=0;
- a[743]=0;
- a[744]=0;
- a[745]=0;
- a[746]=0;
- a[747]=0;
- a[748]=0;
- a[749]=0;
- a[750]=0;
- a[751]=0;
- a[752]=0;
- a[753]=0;
- a[754]=0;
- a[755]=0;
- a[756]=0;
- a[757]=0;
- a[758]=0;
- a[759]=0;
- a[760]=0;
- a[761]=0;
- a[762]=0;
- a[763]=0;
- a[764]=0;
- a[765]=0;
- a[766]=0;
- a[767]=0;
- a[768]=0;
- a[769]=0;
- a[770]=0;
- a[771]=0;
- a[772]=0;
- a[773]=0;
- a[774]=0;
- a[775]=0;
- a[776]=0;
- a[777]=0;
- a[778]=0;
- a[779]=0;
- a[780]=0;
- a[781]=0;
- a[782]=0;
- a[783]=0;
- a[784]=0;
- a[785]=0;
- a[786]=0;
- a[787]=0;
- a[788]=0;
- a[789]=0;
- a[790]=0;
- a[791]=0;
- a[792]=0;
- a[793]=0;
- a[794]=0;
- a[795]=0;
- a[796]=0;
- a[797]=0;
- a[798]=0;
- a[799]=0;
- a[800]=0;
- a[801]=0;
- a[802]=0;
- a[803]=0;
- a[804]=0;
- a[805]=0;
- a[806]=0;
- a[807]=0;
- a[808]=0;
- a[809]=0;
- a[810]=0;
- a[811]=0;
- a[812]=0;
- a[813]=0;
- a[814]=0;
- a[815]=0;
- a[816]=0;
- a[817]=0;
- a[818]=0;
- a[819]=0;
- a[820]=0;
- a[821]=0;
- a[822]=0;
- a[823]=0;
- a[824]=0;
- a[825]=0;
- a[826]=0;
- a[827]=0;
- a[828]=0;
- a[829]=0;
- a[830]=0;
- a[831]=0;
- a[832]=0;
- a[833]=0;
- a[834]=0;
- a[835]=0;
- a[836]=0;
- a[837]=0;
- a[838]=0;
- a[839]=0;
- a[840]=0;
- a[841]=0;
- a[842]=0;
- a[843]=0;
- a[844]=0;
- a[845]=0;
- a[846]=0;
- a[847]=0;
- a[848]=0;
- a[849]=0;
- a[850]=0;
- a[851]=0;
- a[852]=0;
- a[853]=0;
- a[854]=0;
- a[855]=0;
- a[856]=0;
- a[857]=0;
- a[858]=0;
- a[859]=0;
- a[860]=0;
- a[861]=0;
- a[862]=0;
- a[863]=0;
- a[864]=0;
- a[865]=0;
- a[866]=0;
- a[867]=0;
- a[868]=0;
- a[869]=0;
- a[870]=0;
- a[871]=0;
- a[872]=0;
- a[873]=0;
- a[874]=0;
- a[875]=0;
- a[876]=0;
- a[877]=0;
- a[878]=0;
- a[879]=0;
- a[880]=0;
- a[881]=0;
- a[882]=0;
- a[883]=0;
- a[884]=0;
- a[885]=0;
- a[886]=0;
- a[887]=0;
- a[888]=0;
- a[889]=0;
- a[890]=0;
- a[891]=0;
- a[892]=0;
- a[893]=0;
- a[894]=0;
- a[895]=0;
- a[896]=0;
- a[897]=0;
- a[898]=0;
- a[899]=0;
- a[900]=0;
- a[901]=0;
- a[902]=0;
- a[903]=0;
- a[904]=0;
- a[905]=0;
- a[906]=0;
- a[907]=0;
- a[908]=0;
- a[909]=0;
- a[910]=0;
- a[911]=0;
- a[912]=0;
- a[913]=0;
- a[914]=0;
- a[915]=0;
- a[916]=0;
- a[917]=0;
- a[918]=0;
- a[919]=0;
- a[920]=0;
- a[921]=0;
- a[922]=0;
- a[923]=0;
- a[924]=0;
- a[925]=0;
- a[926]=0;
- a[927]=0;
- a[928]=0;
- a[929]=0;
- a[930]=0;
- a[931]=0;
- a[932]=0;
- a[933]=0;
- a[934]=0;
- a[935]=0;
- a[936]=0;
- a[937]=0;
- a[938]=0;
- a[939]=0;
- a[940]=0;
- a[941]=0;
- a[942]=0;
- a[943]=0;
- a[944]=0;
- a[945]=0;
- a[946]=0;
- a[947]=0;
- a[948]=0;
- a[949]=0;
- a[950]=0;
- a[951]=0;
- a[952]=0;
- a[953]=0;
- a[954]=0;
- a[955]=0;
- a[956]=0;
- a[957]=0;
- a[958]=0;
- a[959]=0;
- a[960]=0;
- a[961]=0;
- a[962]=0;
- a[963]=0;
- a[964]=0;
- a[965]=0;
- a[966]=0;
- a[967]=0;
- a[968]=0;
- a[969]=0;
- a[970]=0;
- a[971]=0;
- a[972]=0;
- a[973]=0;
- a[974]=0;
- a[975]=0;
- a[976]=0;
- a[977]=0;
- a[978]=0;
- a[979]=0;
- a[980]=0;
- a[981]=0;
- a[982]=0;
- a[983]=0;
- a[984]=0;
- a[985]=0;
- a[986]=0;
- a[987]=0;
- a[988]=0;
- a[989]=0;
- a[990]=0;
- a[991]=0;
- a[992]=0;
- a[993]=0;
- a[994]=0;
- a[995]=0;
- a[996]=0;
- a[997]=0;
- a[998]=0;
- a[999]=0;
- a[1000]=0;
- a[1001]=0;
- a[1002]=0;
- a[1003]=0;
- a[1004]=0;
- a[1005]=0;
- a[1006]=0;
- a[1007]=0;
- a[1008]=0;
- a[1009]=0;
- a[1010]=0;
- a[1011]=0;
- a[1012]=0;
- a[1013]=0;
- a[1014]=0;
- a[1015]=0;
- a[1016]=0;
- a[1017]=0;
- a[1018]=0;
- a[1019]=0;
- a[1020]=0;
- a[1021]=0;
- a[1022]=0;
- a[1023]=0;
- a[1024]=0;
- a[1025]=0;
- a[1026]=0;
- a[1027]=0;
- a[1028]=0;
- a[1029]=0;
- a[1030]=0;
- a[1031]=0;
- a[1032]=0;
- a[1033]=0;
- a[1034]=0;
- a[1035]=0;
- a[1036]=0;
- a[1037]=0;
- a[1038]=0;
- a[1039]=0;
- a[1040]=0;
- a[1041]=0;
- a[1042]=0;
- a[1043]=0;
- a[1044]=0;
- a[1045]=0;
- a[1046]=0;
- a[1047]=0;
- a[1048]=0;
- a[1049]=0;
- a[1050]=0;
- a[1051]=0;
- a[1052]=0;
- a[1053]=0;
- a[1054]=0;
- a[1055]=0;
- a[1056]=0;
- a[1057]=0;
- a[1058]=0;
- a[1059]=0;
- a[1060]=0;
- a[1061]=0;
- a[1062]=0;
- a[1063]=0;
- a[1064]=0;
- a[1065]=0;
- a[1066]=0;
- a[1067]=0;
- a[1068]=0;
- a[1069]=0;
- a[1070]=0;
- a[1071]=0;
- a[1072]=0;
- a[1073]=0;
- a[1074]=0;
- a[1075]=0;
- a[1076]=0;
- a[1077]=0;
- a[1078]=0;
- a[1079]=0;
- a[1080]=0;
- a[1081]=0;
- a[1082]=0;
- a[1083]=0;
- a[1084]=0;
- a[1085]=0;
- a[1086]=0;
- a[1087]=0;
- a[1088]=0;
- a[1089]=0;
- a[1090]=0;
- a[1091]=0;
- a[1092]=0;
- a[1093]=0;
- a[1094]=0;
- a[1095]=0;
- a[1096]=0;
- a[1097]=0;
- a[1098]=0;
- a[1099]=0;
- a[1100]=0;
- a[1101]=0;
- a[1102]=0;
- a[1103]=0;
- a[1104]=0;
- a[1105]=0;
- a[1106]=0;
- a[1107]=0;
- a[1108]=0;
- a[1109]=0;
- a[1110]=0;
- a[1111]=0;
- a[1112]=0;
- a[1113]=0;
- a[1114]=0;
- a[1115]=0;
- a[1116]=0;
- a[1117]=0;
- a[1118]=0;
- a[1119]=0;
- a[1120]=0;
- a[1121]=0;
- a[1122]=0;
- a[1123]=0;
- a[1124]=0;
- a[1125]=0;
- a[1126]=0;
- a[1127]=0;
- a[1128]=0;
- a[1129]=0;
- a[1130]=0;
- a[1131]=0;
- a[1132]=0;
- a[1133]=0;
- a[1134]=0;
- a[1135]=0;
- a[1136]=0;
- a[1137]=0;
- a[1138]=0;
- a[1139]=0;
- a[1140]=0;
- a[1141]=0;
- a[1142]=0;
- a[1143]=0;
- a[1144]=0;
- a[1145]=0;
- a[1146]=0;
- a[1147]=0;
- a[1148]=0;
- a[1149]=0;
- a[1150]=0;
- a[1151]=0;
- a[1152]=0;
- a[1153]=0;
- a[1154]=0;
- a[1155]=0;
- a[1156]=0;
- a[1157]=0;
- a[1158]=0;
- a[1159]=0;
- a[1160]=0;
- a[1161]=0;
- a[1162]=0;
- a[1163]=0;
- a[1164]=0;
- a[1165]=0;
- a[1166]=0;
- a[1167]=0;
- a[1168]=0;
- a[1169]=0;
- a[1170]=0;
- a[1171]=0;
- a[1172]=0;
- a[1173]=0;
- a[1174]=0;
- a[1175]=0;
- a[1176]=0;
- a[1177]=0;
- a[1178]=0;
- a[1179]=0;
- a[1180]=0;
- a[1181]=0;
- a[1182]=0;
- a[1183]=0;
- a[1184]=0;
- a[1185]=0;
- a[1186]=0;
- a[1187]=0;
- a[1188]=0;
- a[1189]=0;
- a[1190]=0;
- a[1191]=0;
- a[1192]=0;
- a[1193]=0;
- a[1194]=0;
- a[1195]=0;
- a[1196]=0;
- a[1197]=0;
- a[1198]=0;
- a[1199]=0;
- a[1200]=0;
- a[1201]=0;
- a[1202]=0;
- a[1203]=0;
- a[1204]=0;
- a[1205]=0;
- a[1206]=0;
- a[1207]=0;
- a[1208]=0;
- a[1209]=0;
- a[1210]=0;
- a[1211]=0;
- a[1212]=0;
- a[1213]=0;
- a[1214]=0;
- a[1215]=0;
- a[1216]=0;
- a[1217]=0;
- a[1218]=0;
- a[1219]=0;
- a[1220]=0;
- a[1221]=0;
- a[1222]=0;
- a[1223]=0;
- a[1224]=0;
- a[1225]=0;
- a[1226]=0;
- a[1227]=0;
- a[1228]=0;
- a[1229]=0;
- a[1230]=0;
- a[1231]=0;
- a[1232]=0;
- a[1233]=0;
- a[1234]=0;
- a[1235]=0;
- a[1236]=0;
- a[1237]=0;
- a[1238]=0;
- a[1239]=0;
- a[1240]=0;
- a[1241]=0;
- a[1242]=0;
- a[1243]=0;
- a[1244]=0;
- a[1245]=0;
- a[1246]=0;
- a[1247]=0;
- a[1248]=0;
- a[1249]=0;
- a[1250]=0;
- a[1251]=0;
- a[1252]=0;
- a[1253]=0;
- a[1254]=0;
- a[1255]=0;
- a[1256]=0;
- a[1257]=0;
- a[1258]=0;
- a[1259]=0;
- a[1260]=0;
- a[1261]=0;
- a[1262]=0;
- a[1263]=0;
- a[1264]=0;
- a[1265]=0;
- a[1266]=0;
- a[1267]=0;
- a[1268]=0;
- a[1269]=0;
- a[1270]=0;
- a[1271]=0;
- a[1272]=0;
- a[1273]=0;
- a[1274]=0;
- a[1275]=0;
- a[1276]=0;
- a[1277]=0;
- a[1278]=0;
- a[1279]=0;
- a[1280]=0;
- a[1281]=0;
- a[1282]=0;
- a[1283]=0;
- a[1284]=0;
- a[1285]=0;
- a[1286]=0;
- a[1287]=0;
- a[1288]=0;
- a[1289]=0;
- a[1290]=0;
- a[1291]=0;
- a[1292]=0;
- a[1293]=0;
- a[1294]=0;
- a[1295]=0;
- a[1296]=0;
- a[1297]=0;
- a[1298]=0;
- a[1299]=0;
- a[1300]=0;
- a[1301]=0;
- a[1302]=0;
- a[1303]=0;
- a[1304]=0;
- a[1305]=0;
- a[1306]=0;
- a[1307]=0;
- a[1308]=0;
- a[1309]=0;
- a[1310]=0;
- a[1311]=0;
- a[1312]=0;
- a[1313]=0;
- a[1314]=0;
- a[1315]=0;
- a[1316]=0;
- a[1317]=0;
- a[1318]=0;
- a[1319]=0;
- a[1320]=0;
- a[1321]=0;
- a[1322]=0;
- a[1323]=0;
- a[1324]=0;
- a[1325]=0;
- a[1326]=0;
- a[1327]=0;
- a[1328]=0;
- a[1329]=0;
- a[1330]=0;
- a[1331]=0;
- a[1332]=0;
- a[1333]=0;
- a[1334]=0;
- a[1335]=0;
- a[1336]=0;
- a[1337]=0;
- a[1338]=0;
- a[1339]=0;
- a[1340]=0;
- a[1341]=0;
- a[1342]=0;
- a[1343]=0;
- a[1344]=0;
- a[1345]=0;
- a[1346]=0;
- a[1347]=0;
- a[1348]=0;
- a[1349]=0;
- a[1350]=0;
- a[1351]=0;
- a[1352]=0;
- a[1353]=0;
- a[1354]=0;
- a[1355]=0;
- a[1356]=0;
- a[1357]=0;
- a[1358]=0;
- a[1359]=0;
- a[1360]=0;
- a[1361]=0;
- a[1362]=0;
- a[1363]=0;
- a[1364]=0;
- a[1365]=0;
- a[1366]=0;
- a[1367]=0;
- a[1368]=0;
- a[1369]=0;
- a[1370]=0;
- a[1371]=0;
- a[1372]=0;
- a[1373]=0;
- a[1374]=0;
- a[1375]=0;
- a[1376]=0;
- a[1377]=0;
- a[1378]=0;
- a[1379]=0;
- a[1380]=0;
- a[1381]=0;
- a[1382]=0;
- a[1383]=0;
- a[1384]=0;
- a[1385]=0;
- a[1386]=0;
- a[1387]=0;
- a[1388]=0;
- a[1389]=0;
- a[1390]=0;
- a[1391]=0;
- a[1392]=0;
- a[1393]=0;
- a[1394]=0;
- a[1395]=0;
- a[1396]=0;
- a[1397]=0;
- a[1398]=0;
- a[1399]=0;
- a[1400]=0;
- a[1401]=0;
- a[1402]=0;
- a[1403]=0;
- a[1404]=0;
- a[1405]=0;
- a[1406]=0;
- a[1407]=0;
- a[1408]=0;
- a[1409]=0;
- a[1410]=0;
- a[1411]=0;
- a[1412]=0;
- a[1413]=0;
- a[1414]=0;
- a[1415]=0;
- a[1416]=0;
- a[1417]=0;
- a[1418]=0;
- a[1419]=0;
- a[1420]=0;
- a[1421]=0;
- a[1422]=0;
- a[1423]=0;
- a[1424]=0;
- a[1425]=0;
- a[1426]=0;
- a[1427]=0;
- a[1428]=0;
- a[1429]=0;
- a[1430]=0;
- a[1431]=0;
- a[1432]=0;
- a[1433]=0;
- a[1434]=0;
- a[1435]=0;
- a[1436]=0;
- a[1437]=0;
- a[1438]=0;
- a[1439]=0;
- a[1440]=0;
- a[1441]=0;
- a[1442]=0;
- a[1443]=0;
- a[1444]=0;
- a[1445]=0;
- a[1446]=0;
- a[1447]=0;
- a[1448]=0;
- a[1449]=0;
- a[1450]=0;
- a[1451]=0;
- a[1452]=0;
- a[1453]=0;
- a[1454]=0;
- a[1455]=0;
- a[1456]=0;
- a[1457]=0;
- a[1458]=0;
- a[1459]=0;
- a[1460]=0;
- a[1461]=0;
- a[1462]=0;
- a[1463]=0;
- a[1464]=0;
- a[1465]=0;
- a[1466]=0;
- a[1467]=0;
- a[1468]=0;
- a[1469]=0;
- a[1470]=0;
- a[1471]=0;
- a[1472]=0;
- a[1473]=0;
- a[1474]=0;
- a[1475]=0;
- a[1476]=0;
- a[1477]=0;
- a[1478]=0;
- a[1479]=0;
- a[1480]=0;
- a[1481]=0;
- a[1482]=0;
- a[1483]=0;
- a[1484]=0;
- a[1485]=0;
- a[1486]=0;
- a[1487]=0;
- a[1488]=0;
- a[1489]=0;
- a[1490]=0;
- a[1491]=0;
- a[1492]=0;
- a[1493]=0;
- a[1494]=0;
- a[1495]=0;
- a[1496]=0;
- a[1497]=0;
- a[1498]=0;
- a[1499]=0;
- a[1500]=0;
- a[1501]=0;
- a[1502]=0;
- a[1503]=0;
- a[1504]=0;
- a[1505]=0;
- a[1506]=0;
- a[1507]=0;
- a[1508]=0;
- a[1509]=0;
- a[1510]=0;
- a[1511]=0;
- a[1512]=0;
- a[1513]=0;
- a[1514]=0;
- a[1515]=0;
- a[1516]=0;
- a[1517]=0;
- a[1518]=0;
- a[1519]=0;
- a[1520]=0;
- a[1521]=0;
- a[1522]=0;
- a[1523]=0;
- a[1524]=0;
- a[1525]=0;
- a[1526]=0;
- a[1527]=0;
- a[1528]=0;
- a[1529]=0;
- a[1530]=0;
- a[1531]=0;
- a[1532]=0;
- a[1533]=0;
- a[1534]=0;
- a[1535]=0;
- a[1536]=0;
- a[1537]=0;
- a[1538]=0;
- a[1539]=0;
- a[1540]=0;
- a[1541]=0;
- a[1542]=0;
- a[1543]=0;
- a[1544]=0;
- a[1545]=0;
- a[1546]=0;
- a[1547]=0;
- a[1548]=0;
- a[1549]=0;
- a[1550]=0;
- a[1551]=0;
- a[1552]=0;
- a[1553]=0;
- a[1554]=0;
- a[1555]=0;
- a[1556]=0;
- a[1557]=0;
- a[1558]=0;
- a[1559]=0;
- a[1560]=0;
- a[1561]=0;
- a[1562]=0;
- a[1563]=0;
- a[1564]=0;
- a[1565]=0;
- a[1566]=0;
- a[1567]=0;
- a[1568]=0;
- a[1569]=0;
- a[1570]=0;
- a[1571]=0;
- a[1572]=0;
- a[1573]=0;
- a[1574]=0;
- a[1575]=0;
- a[1576]=0;
- a[1577]=0;
- a[1578]=0;
- a[1579]=0;
- a[1580]=0;
- a[1581]=0;
- a[1582]=0;
- a[1583]=0;
- a[1584]=0;
- a[1585]=0;
- a[1586]=0;
- a[1587]=0;
- a[1588]=0;
- a[1589]=0;
- a[1590]=0;
- a[1591]=0;
- a[1592]=0;
- a[1593]=0;
- a[1594]=0;
- a[1595]=0;
- a[1596]=0;
- a[1597]=0;
- a[1598]=0;
- a[1599]=0;
- a[1600]=0;
- a[1601]=0;
- a[1602]=0;
- a[1603]=0;
- a[1604]=0;
- a[1605]=0;
- a[1606]=0;
- a[1607]=0;
- a[1608]=0;
- a[1609]=0;
- a[1610]=0;
- a[1611]=0;
- a[1612]=0;
- a[1613]=0;
- a[1614]=0;
- a[1615]=0;
- a[1616]=0;
- a[1617]=0;
- a[1618]=0;
- a[1619]=0;
- a[1620]=0;
- a[1621]=0;
- a[1622]=0;
- a[1623]=0;
- a[1624]=0;
- a[1625]=0;
- a[1626]=0;
- a[1627]=0;
- a[1628]=0;
- a[1629]=0;
- a[1630]=0;
- a[1631]=0;
- a[1632]=0;
- a[1633]=0;
- a[1634]=0;
- a[1635]=0;
- a[1636]=0;
- a[1637]=0;
- a[1638]=0;
- a[1639]=0;
- a[1640]=0;
- a[1641]=0;
- a[1642]=0;
- a[1643]=0;
- a[1644]=0;
- a[1645]=0;
- a[1646]=0;
- a[1647]=0;
- a[1648]=0;
- a[1649]=0;
- a[1650]=0;
- a[1651]=0;
- a[1652]=0;
- a[1653]=0;
- a[1654]=0;
- a[1655]=0;
- a[1656]=0;
- a[1657]=0;
- a[1658]=0;
- a[1659]=0;
- a[1660]=0;
- a[1661]=0;
- a[1662]=0;
- a[1663]=0;
- a[1664]=0;
- a[1665]=0;
- a[1666]=0;
- a[1667]=0;
- a[1668]=0;
- a[1669]=0;
- a[1670]=0;
- a[1671]=0;
- a[1672]=0;
- a[1673]=0;
- a[1674]=0;
- a[1675]=0;
- a[1676]=0;
- a[1677]=0;
- a[1678]=0;
- a[1679]=0;
- a[1680]=0;
- a[1681]=0;
- a[1682]=0;
- a[1683]=0;
- a[1684]=0;
- a[1685]=0;
- a[1686]=0;
- a[1687]=0;
- a[1688]=0;
- a[1689]=0;
- a[1690]=0;
- a[1691]=0;
- a[1692]=0;
- a[1693]=0;
- a[1694]=0;
- a[1695]=0;
- a[1696]=0;
- a[1697]=0;
- a[1698]=0;
- a[1699]=0;
- a[1700]=0;
- a[1701]=0;
- a[1702]=0;
- a[1703]=0;
- a[1704]=0;
- a[1705]=0;
- a[1706]=0;
- a[1707]=0;
- a[1708]=0;
- a[1709]=0;
- a[1710]=0;
- a[1711]=0;
- a[1712]=0;
- a[1713]=0;
- a[1714]=0;
- a[1715]=0;
- a[1716]=0;
- a[1717]=0;
- a[1718]=0;
- a[1719]=0;
- a[1720]=0;
- a[1721]=0;
- a[1722]=0;
- a[1723]=0;
- a[1724]=0;
- a[1725]=0;
- a[1726]=0;
- a[1727]=0;
- a[1728]=0;
- a[1729]=0;
- a[1730]=0;
- a[1731]=0;
- a[1732]=0;
- a[1733]=0;
- a[1734]=0;
- a[1735]=0;
- a[1736]=0;
- a[1737]=0;
- a[1738]=0;
- a[1739]=0;
- a[1740]=0;
- a[1741]=0;
- a[1742]=0;
- a[1743]=0;
- a[1744]=0;
- a[1745]=0;
- a[1746]=0;
- a[1747]=0;
- a[1748]=0;
- a[1749]=0;
- a[1750]=0;
- a[1751]=0;
- a[1752]=0;
- a[1753]=0;
- a[1754]=0;
- a[1755]=0;
- a[1756]=0;
- a[1757]=0;
- a[1758]=0;
- a[1759]=0;
- a[1760]=0;
- a[1761]=0;
- a[1762]=0;
- a[1763]=0;
- a[1764]=0;
- a[1765]=0;
- a[1766]=0;
- a[1767]=0;
- a[1768]=0;
- a[1769]=0;
- a[1770]=0;
- a[1771]=0;
- a[1772]=0;
- a[1773]=0;
- a[1774]=0;
- a[1775]=0;
- a[1776]=0;
- a[1777]=0;
- a[1778]=0;
- a[1779]=0;
- a[1780]=0;
- a[1781]=0;
- a[1782]=0;
- a[1783]=0;
- a[1784]=0;
- a[1785]=0;
- a[1786]=0;
- a[1787]=0;
- a[1788]=0;
- a[1789]=0;
- a[1790]=0;
- a[1791]=0;
- a[1792]=0;
- a[1793]=0;
- a[1794]=0;
- a[1795]=0;
- a[1796]=0;
- a[1797]=0;
- a[1798]=0;
- a[1799]=0;
- a[1800]=0;
- a[1801]=0;
- a[1802]=0;
- a[1803]=0;
- a[1804]=0;
- a[1805]=0;
- a[1806]=0;
- a[1807]=0;
- a[1808]=0;
- a[1809]=0;
- a[1810]=0;
- a[1811]=0;
- a[1812]=0;
- a[1813]=0;
- a[1814]=0;
- a[1815]=0;
- a[1816]=0;
- a[1817]=0;
- a[1818]=0;
- a[1819]=0;
- a[1820]=0;
- a[1821]=0;
- a[1822]=0;
- a[1823]=0;
- a[1824]=0;
- a[1825]=0;
- a[1826]=0;
- a[1827]=0;
- a[1828]=0;
- a[1829]=0;
- a[1830]=0;
- a[1831]=0;
- a[1832]=0;
- a[1833]=0;
- a[1834]=0;
- a[1835]=0;
- a[1836]=0;
- a[1837]=0;
- a[1838]=0;
- a[1839]=0;
- a[1840]=0;
- a[1841]=0;
- a[1842]=0;
- a[1843]=0;
- a[1844]=0;
- a[1845]=0;
- a[1846]=0;
- a[1847]=0;
- a[1848]=0;
- a[1849]=0;
- a[1850]=0;
- a[1851]=0;
- a[1852]=0;
- a[1853]=0;
- a[1854]=0;
- a[1855]=0;
- a[1856]=0;
- a[1857]=0;
- a[1858]=0;
- a[1859]=0;
- a[1860]=0;
- a[1861]=0;
- a[1862]=0;
- a[1863]=0;
- a[1864]=0;
- a[1865]=0;
- a[1866]=0;
- a[1867]=0;
- a[1868]=0;
- a[1869]=0;
- a[1870]=0;
- a[1871]=0;
- a[1872]=0;
- a[1873]=0;
- a[1874]=0;
- a[1875]=0;
- a[1876]=0;
- a[1877]=0;
- a[1878]=0;
- a[1879]=0;
- a[1880]=0;
- a[1881]=0;
- a[1882]=0;
- a[1883]=0;
- a[1884]=0;
- a[1885]=0;
- a[1886]=0;
- a[1887]=0;
- a[1888]=0;
- a[1889]=0;
- a[1890]=0;
- a[1891]=0;
- a[1892]=0;
- a[1893]=0;
- a[1894]=0;
- a[1895]=0;
- a[1896]=0;
- a[1897]=0;
- a[1898]=0;
- a[1899]=0;
- a[1900]=0;
- a[1901]=0;
- a[1902]=0;
- a[1903]=0;
- a[1904]=0;
- a[1905]=0;
- a[1906]=0;
- a[1907]=0;
- a[1908]=0;
- a[1909]=0;
- a[1910]=0;
- a[1911]=0;
- a[1912]=0;
- a[1913]=0;
- a[1914]=0;
- a[1915]=0;
- a[1916]=0;
- a[1917]=0;
- a[1918]=0;
- a[1919]=0;
- a[1920]=0;
- a[1921]=0;
- a[1922]=0;
- a[1923]=0;
- a[1924]=0;
- a[1925]=0;
- a[1926]=0;
- a[1927]=0;
- a[1928]=0;
- a[1929]=0;
- a[1930]=0;
- a[1931]=0;
- a[1932]=0;
- a[1933]=0;
- a[1934]=0;
- a[1935]=0;
- a[1936]=0;
- a[1937]=0;
- a[1938]=0;
- a[1939]=0;
- a[1940]=0;
- a[1941]=0;
- a[1942]=0;
- a[1943]=0;
- a[1944]=0;
- a[1945]=0;
- a[1946]=0;
- a[1947]=0;
- a[1948]=0;
- a[1949]=0;
- a[1950]=0;
- a[1951]=0;
- a[1952]=0;
- a[1953]=0;
- a[1954]=0;
- a[1955]=0;
- a[1956]=0;
- a[1957]=0;
- a[1958]=0;
- a[1959]=0;
- a[1960]=0;
- a[1961]=0;
- a[1962]=0;
- a[1963]=0;
- a[1964]=0;
- a[1965]=0;
- a[1966]=0;
- a[1967]=0;
- a[1968]=0;
- a[1969]=0;
- a[1970]=0;
- a[1971]=0;
- a[1972]=0;
- a[1973]=0;
- a[1974]=0;
- a[1975]=0;
- a[1976]=0;
- a[1977]=0;
- a[1978]=0;
- a[1979]=0;
- a[1980]=0;
- a[1981]=0;
- a[1982]=0;
- a[1983]=0;
- a[1984]=0;
- a[1985]=0;
- a[1986]=0;
- a[1987]=0;
- a[1988]=0;
- a[1989]=0;
- a[1990]=0;
- a[1991]=0;
- a[1992]=0;
- a[1993]=0;
- a[1994]=0;
- a[1995]=0;
- a[1996]=0;
- a[1997]=0;
- a[1998]=0;
- a[1999]=0;
- a[2000]=0;
- a[2001]=0;
- a[2002]=0;
- a[2003]=0;
- a[2004]=0;
- a[2005]=0;
- a[2006]=0;
- a[2007]=0;
- a[2008]=0;
- a[2009]=0;
- a[2010]=0;
- a[2011]=0;
- a[2012]=0;
- a[2013]=0;
- a[2014]=0;
- a[2015]=0;
- a[2016]=0;
- a[2017]=0;
- a[2018]=0;
- a[2019]=0;
- a[2020]=0;
- a[2021]=0;
- a[2022]=0;
- a[2023]=0;
- a[2024]=0;
- a[2025]=0;
- a[2026]=0;
- a[2027]=0;
- a[2028]=0;
- a[2029]=0;
- a[2030]=0;
- a[2031]=0;
- a[2032]=0;
- a[2033]=0;
- a[2034]=0;
- a[2035]=0;
- a[2036]=0;
- a[2037]=0;
- a[2038]=0;
- a[2039]=0;
- a[2040]=0;
- a[2041]=0;
- a[2042]=0;
- a[2043]=0;
- a[2044]=0;
- a[2045]=0;
- a[2046]=0;
- a[2047]=0;
- a[2048]=0;
- a[2049]=0;
- a[2050]=0;
- a[2051]=0;
- a[2052]=0;
- a[2053]=0;
- a[2054]=0;
- a[2055]=0;
- a[2056]=0;
- a[2057]=0;
- a[2058]=0;
- a[2059]=0;
- a[2060]=0;
- a[2061]=0;
- a[2062]=0;
- a[2063]=0;
- a[2064]=0;
- a[2065]=0;
- a[2066]=0;
- a[2067]=0;
- a[2068]=0;
- a[2069]=0;
- a[2070]=0;
- a[2071]=0;
- a[2072]=0;
- a[2073]=0;
- a[2074]=0;
- a[2075]=0;
- a[2076]=0;
- a[2077]=0;
- a[2078]=0;
- a[2079]=0;
- a[2080]=0;
- a[2081]=0;
- a[2082]=0;
- a[2083]=0;
- a[2084]=0;
- a[2085]=0;
- a[2086]=0;
- a[2087]=0;
- a[2088]=0;
- a[2089]=0;
- a[2090]=0;
- a[2091]=0;
- a[2092]=0;
- a[2093]=0;
- a[2094]=0;
- a[2095]=0;
- a[2096]=0;
- a[2097]=0;
- a[2098]=0;
- a[2099]=0;
- a[2100]=0;
- a[2101]=0;
- a[2102]=0;
- a[2103]=0;
- a[2104]=0;
- a[2105]=0;
- a[2106]=0;
- a[2107]=0;
- a[2108]=0;
- a[2109]=0;
- a[2110]=0;
- a[2111]=0;
- a[2112]=0;
- a[2113]=0;
- a[2114]=0;
- a[2115]=0;
- a[2116]=0;
- a[2117]=0;
- a[2118]=0;
- a[2119]=0;
- a[2120]=0;
- a[2121]=0;
- a[2122]=0;
- a[2123]=0;
- a[2124]=0;
- a[2125]=0;
- a[2126]=0;
- a[2127]=0;
- a[2128]=0;
- a[2129]=0;
- a[2130]=0;
- a[2131]=0;
- a[2132]=0;
- a[2133]=0;
- a[2134]=0;
- a[2135]=0;
- a[2136]=0;
- a[2137]=0;
- a[2138]=0;
- a[2139]=0;
- a[2140]=0;
- a[2141]=0;
- a[2142]=0;
- a[2143]=0;
- a[2144]=0;
- a[2145]=0;
- a[2146]=0;
- a[2147]=0;
- a[2148]=0;
- a[2149]=0;
- a[2150]=0;
- a[2151]=0;
- a[2152]=0;
- a[2153]=0;
- a[2154]=0;
- a[2155]=0;
- a[2156]=0;
- a[2157]=0;
- a[2158]=0;
- a[2159]=0;
- a[2160]=0;
- a[2161]=0;
- a[2162]=0;
- a[2163]=0;
- a[2164]=0;
- a[2165]=0;
- a[2166]=0;
- a[2167]=0;
- a[2168]=0;
- a[2169]=0;
- a[2170]=0;
- a[2171]=0;
- a[2172]=0;
- a[2173]=0;
- a[2174]=0;
- a[2175]=0;
- a[2176]=0;
- a[2177]=0;
- a[2178]=0;
- a[2179]=0;
- a[2180]=0;
- a[2181]=0;
- a[2182]=0;
- a[2183]=0;
- a[2184]=0;
- a[2185]=0;
- a[2186]=0;
- a[2187]=0;
- a[2188]=0;
- a[2189]=0;
- a[2190]=0;
- a[2191]=0;
- a[2192]=0;
- a[2193]=0;
- a[2194]=0;
- a[2195]=0;
- a[2196]=0;
- a[2197]=0;
- a[2198]=0;
- a[2199]=0;
- a[2200]=0;
- a[2201]=0;
- a[2202]=0;
- a[2203]=0;
- a[2204]=0;
- a[2205]=0;
- a[2206]=0;
- a[2207]=0;
- a[2208]=0;
- a[2209]=0;
- a[2210]=0;
- a[2211]=0;
- a[2212]=0;
- a[2213]=0;
- a[2214]=0;
- a[2215]=0;
- a[2216]=0;
- a[2217]=0;
- a[2218]=0;
- a[2219]=0;
- a[2220]=0;
- a[2221]=0;
- a[2222]=0;
- a[2223]=0;
- a[2224]=0;
- a[2225]=0;
- a[2226]=0;
- a[2227]=0;
- a[2228]=0;
- a[2229]=0;
- a[2230]=0;
- a[2231]=0;
- a[2232]=0;
- a[2233]=0;
- a[2234]=0;
- a[2235]=0;
- a[2236]=0;
- a[2237]=0;
- a[2238]=0;
- a[2239]=0;
- a[2240]=0;
- a[2241]=0;
- a[2242]=0;
- a[2243]=0;
- a[2244]=0;
- a[2245]=0;
- a[2246]=0;
- a[2247]=0;
- a[2248]=0;
- a[2249]=0;
- a[2250]=0;
- a[2251]=0;
- a[2252]=0;
- a[2253]=0;
- a[2254]=0;
- a[2255]=0;
- a[2256]=0;
- a[2257]=0;
- a[2258]=0;
- a[2259]=0;
- a[2260]=0;
- a[2261]=0;
- a[2262]=0;
- a[2263]=0;
- a[2264]=0;
- a[2265]=0;
- a[2266]=0;
- a[2267]=0;
- a[2268]=0;
- a[2269]=0;
- a[2270]=0;
- a[2271]=0;
- a[2272]=0;
- a[2273]=0;
- a[2274]=0;
- a[2275]=0;
- a[2276]=0;
- a[2277]=0;
- a[2278]=0;
- a[2279]=0;
- a[2280]=0;
- a[2281]=0;
- a[2282]=0;
- a[2283]=0;
- a[2284]=0;
- a[2285]=0;
- a[2286]=0;
- a[2287]=0;
- a[2288]=0;
- a[2289]=0;
- a[2290]=0;
- a[2291]=0;
- a[2292]=0;
- a[2293]=0;
- a[2294]=0;
- a[2295]=0;
- a[2296]=0;
- a[2297]=0;
- a[2298]=0;
- a[2299]=0;
- a[2300]=0;
- a[2301]=0;
- a[2302]=0;
- a[2303]=0;
- a[2304]=0;
- a[2305]=0;
- a[2306]=0;
- a[2307]=0;
- a[2308]=0;
- a[2309]=0;
- a[2310]=0;
- a[2311]=0;
- a[2312]=0;
- a[2313]=0;
- a[2314]=0;
- a[2315]=0;
- a[2316]=0;
- a[2317]=0;
- a[2318]=0;
- a[2319]=0;
- a[2320]=0;
- a[2321]=0;
- a[2322]=0;
- a[2323]=0;
- a[2324]=0;
- a[2325]=0;
- a[2326]=0;
- a[2327]=0;
- a[2328]=0;
- a[2329]=0;
- a[2330]=0;
- a[2331]=0;
- a[2332]=0;
- a[2333]=0;
- a[2334]=0;
- a[2335]=0;
- a[2336]=0;
- a[2337]=0;
- a[2338]=0;
- a[2339]=0;
- a[2340]=0;
- a[2341]=0;
- a[2342]=0;
- a[2343]=0;
- a[2344]=0;
- a[2345]=0;
- a[2346]=0;
- a[2347]=0;
- a[2348]=0;
- a[2349]=0;
- a[2350]=0;
- a[2351]=0;
- a[2352]=0;
- a[2353]=0;
- a[2354]=0;
- a[2355]=0;
- a[2356]=0;
- a[2357]=0;
- a[2358]=0;
- a[2359]=0;
- a[2360]=0;
- a[2361]=0;
- a[2362]=0;
- a[2363]=0;
- a[2364]=0;
- a[2365]=0;
- a[2366]=0;
- a[2367]=0;
- a[2368]=0;
- a[2369]=0;
- a[2370]=0;
- a[2371]=0;
- a[2372]=0;
- a[2373]=0;
- a[2374]=0;
- a[2375]=0;
- a[2376]=0;
- a[2377]=0;
- a[2378]=0;
- a[2379]=0;
- a[2380]=0;
- a[2381]=0;
- a[2382]=0;
- a[2383]=0;
- a[2384]=0;
- a[2385]=0;
- a[2386]=0;
- a[2387]=0;
- a[2388]=0;
- a[2389]=0;
- a[2390]=0;
- a[2391]=0;
- a[2392]=0;
- a[2393]=0;
- a[2394]=0;
- a[2395]=0;
- a[2396]=0;
- a[2397]=0;
- a[2398]=0;
- a[2399]=0;
- a[2400]=0;
- a[2401]=0;
- a[2402]=0;
- a[2403]=0;
- a[2404]=0;
- a[2405]=0;
- a[2406]=0;
- a[2407]=0;
- a[2408]=0;
- a[2409]=0;
- a[2410]=0;
- a[2411]=0;
- a[2412]=0;
- a[2413]=0;
- a[2414]=0;
- a[2415]=0;
- a[2416]=0;
- a[2417]=0;
- a[2418]=0;
- a[2419]=0;
- a[2420]=0;
- a[2421]=0;
- a[2422]=0;
- a[2423]=0;
- a[2424]=0;
- a[2425]=0;
- a[2426]=0;
- a[2427]=0;
- a[2428]=0;
- a[2429]=0;
- a[2430]=0;
- a[2431]=0;
- a[2432]=0;
- a[2433]=0;
- a[2434]=0;
- a[2435]=0;
- a[2436]=0;
- a[2437]=0;
- a[2438]=0;
- a[2439]=0;
- a[2440]=0;
- a[2441]=0;
- a[2442]=0;
- a[2443]=0;
- a[2444]=0;
- a[2445]=0;
- a[2446]=0;
- a[2447]=0;
- a[2448]=0;
- a[2449]=0;
- a[2450]=0;
- a[2451]=0;
- a[2452]=0;
- a[2453]=0;
- a[2454]=0;
- a[2455]=0;
- a[2456]=0;
- a[2457]=0;
- a[2458]=0;
- a[2459]=0;
- a[2460]=0;
- a[2461]=0;
- a[2462]=0;
- a[2463]=0;
- a[2464]=0;
- a[2465]=0;
- a[2466]=0;
- a[2467]=0;
- a[2468]=0;
- a[2469]=0;
- a[2470]=0;
- a[2471]=0;
- a[2472]=0;
- a[2473]=0;
- a[2474]=0;
- a[2475]=0;
- a[2476]=0;
- a[2477]=0;
- a[2478]=0;
- a[2479]=0;
- a[2480]=0;
- a[2481]=0;
- a[2482]=0;
- a[2483]=0;
- a[2484]=0;
- a[2485]=0;
- a[2486]=0;
- a[2487]=0;
- a[2488]=0;
- a[2489]=0;
- a[2490]=0;
- a[2491]=0;
- a[2492]=0;
- a[2493]=0;
- a[2494]=0;
- a[2495]=0;
- a[2496]=0;
- a[2497]=0;
- a[2498]=0;
- a[2499]=0;
- a[2500]=0;
- a[2501]=0;
- a[2502]=0;
- a[2503]=0;
- a[2504]=0;
- a[2505]=0;
- a[2506]=0;
- a[2507]=0;
- a[2508]=0;
- a[2509]=0;
- a[2510]=0;
- a[2511]=0;
- a[2512]=0;
- a[2513]=0;
- a[2514]=0;
- a[2515]=0;
- a[2516]=0;
- a[2517]=0;
- a[2518]=0;
- a[2519]=0;
- a[2520]=0;
- a[2521]=0;
- a[2522]=0;
- a[2523]=0;
- a[2524]=0;
- a[2525]=0;
- a[2526]=0;
- a[2527]=0;
- a[2528]=0;
- a[2529]=0;
- a[2530]=0;
- a[2531]=0;
- a[2532]=0;
- a[2533]=0;
- a[2534]=0;
- a[2535]=0;
- a[2536]=0;
- a[2537]=0;
- a[2538]=0;
- a[2539]=0;
- a[2540]=0;
- a[2541]=0;
- a[2542]=0;
- a[2543]=0;
- a[2544]=0;
- a[2545]=0;
- a[2546]=0;
- a[2547]=0;
- a[2548]=0;
- a[2549]=0;
- a[2550]=0;
- a[2551]=0;
- a[2552]=0;
- a[2553]=0;
- a[2554]=0;
- a[2555]=0;
- a[2556]=0;
- a[2557]=0;
- a[2558]=0;
- a[2559]=0;
- a[2560]=0;
- a[2561]=0;
- a[2562]=0;
- a[2563]=0;
- a[2564]=0;
- a[2565]=0;
- a[2566]=0;
- a[2567]=0;
- a[2568]=0;
- a[2569]=0;
- a[2570]=0;
- a[2571]=0;
- a[2572]=0;
- a[2573]=0;
- a[2574]=0;
- a[2575]=0;
- a[2576]=0;
- a[2577]=0;
- a[2578]=0;
- a[2579]=0;
- a[2580]=0;
- a[2581]=0;
- a[2582]=0;
- a[2583]=0;
- a[2584]=0;
- a[2585]=0;
- a[2586]=0;
- a[2587]=0;
- a[2588]=0;
- a[2589]=0;
- a[2590]=0;
- a[2591]=0;
- a[2592]=0;
- a[2593]=0;
- a[2594]=0;
- a[2595]=0;
- a[2596]=0;
- a[2597]=0;
- a[2598]=0;
- a[2599]=0;
- a[2600]=0;
- a[2601]=0;
- a[2602]=0;
- a[2603]=0;
- a[2604]=0;
- a[2605]=0;
- a[2606]=0;
- a[2607]=0;
- a[2608]=0;
- a[2609]=0;
- a[2610]=0;
- a[2611]=0;
- a[2612]=0;
- a[2613]=0;
- a[2614]=0;
- a[2615]=0;
- a[2616]=0;
- a[2617]=0;
- a[2618]=0;
- a[2619]=0;
- a[2620]=0;
- a[2621]=0;
- a[2622]=0;
- a[2623]=0;
- a[2624]=0;
- a[2625]=0;
- a[2626]=0;
- a[2627]=0;
- a[2628]=0;
- a[2629]=0;
- a[2630]=0;
- a[2631]=0;
- a[2632]=0;
- a[2633]=0;
- a[2634]=0;
- a[2635]=0;
- a[2636]=0;
- a[2637]=0;
- a[2638]=0;
- a[2639]=0;
- a[2640]=0;
- a[2641]=0;
- a[2642]=0;
- a[2643]=0;
- a[2644]=0;
- a[2645]=0;
- a[2646]=0;
- a[2647]=0;
- a[2648]=0;
- a[2649]=0;
- a[2650]=0;
- a[2651]=0;
- a[2652]=0;
- a[2653]=0;
- a[2654]=0;
- a[2655]=0;
- a[2656]=0;
- a[2657]=0;
- a[2658]=0;
- a[2659]=0;
- a[2660]=0;
- a[2661]=0;
- a[2662]=0;
- a[2663]=0;
- a[2664]=0;
- a[2665]=0;
- a[2666]=0;
- a[2667]=0;
- a[2668]=0;
- a[2669]=0;
- a[2670]=0;
- a[2671]=0;
- a[2672]=0;
- a[2673]=0;
- a[2674]=0;
- a[2675]=0;
- a[2676]=0;
- a[2677]=0;
- a[2678]=0;
- a[2679]=0;
- a[2680]=0;
- a[2681]=0;
- a[2682]=0;
- a[2683]=0;
- a[2684]=0;
- a[2685]=0;
- a[2686]=0;
- a[2687]=0;
- a[2688]=0;
- a[2689]=0;
- a[2690]=0;
- a[2691]=0;
- a[2692]=0;
- a[2693]=0;
- a[2694]=0;
- a[2695]=0;
- a[2696]=0;
- a[2697]=0;
- a[2698]=0;
- a[2699]=0;
- a[2700]=0;
- a[2701]=0;
- a[2702]=0;
- a[2703]=0;
- a[2704]=0;
- a[2705]=0;
- a[2706]=0;
- a[2707]=0;
- a[2708]=0;
- a[2709]=0;
- a[2710]=0;
- a[2711]=0;
- a[2712]=0;
- a[2713]=0;
- a[2714]=0;
- a[2715]=0;
- a[2716]=0;
- a[2717]=0;
- a[2718]=0;
- a[2719]=0;
- a[2720]=0;
- a[2721]=0;
- a[2722]=0;
- a[2723]=0;
- a[2724]=0;
- a[2725]=0;
- a[2726]=0;
- a[2727]=0;
- a[2728]=0;
- a[2729]=0;
- a[2730]=0;
- a[2731]=0;
- a[2732]=0;
- a[2733]=0;
- a[2734]=0;
- a[2735]=0;
- a[2736]=0;
- a[2737]=0;
- a[2738]=0;
- a[2739]=0;
- a[2740]=0;
- a[2741]=0;
- a[2742]=0;
- a[2743]=0;
- a[2744]=0;
- a[2745]=0;
- a[2746]=0;
- a[2747]=0;
- a[2748]=0;
- a[2749]=0;
- a[2750]=0;
- a[2751]=0;
- a[2752]=0;
- a[2753]=0;
- a[2754]=0;
- a[2755]=0;
- a[2756]=0;
- a[2757]=0;
- a[2758]=0;
- a[2759]=0;
- a[2760]=0;
- a[2761]=0;
- a[2762]=0;
- a[2763]=0;
- a[2764]=0;
- a[2765]=0;
- a[2766]=0;
- a[2767]=0;
- a[2768]=0;
- a[2769]=0;
- a[2770]=0;
- a[2771]=0;
- a[2772]=0;
- a[2773]=0;
- a[2774]=0;
- a[2775]=0;
- a[2776]=0;
- a[2777]=0;
- a[2778]=0;
- a[2779]=0;
- a[2780]=0;
- a[2781]=0;
- a[2782]=0;
- a[2783]=0;
- a[2784]=0;
- a[2785]=0;
- a[2786]=0;
- a[2787]=0;
- a[2788]=0;
- a[2789]=0;
- a[2790]=0;
- a[2791]=0;
- a[2792]=0;
- a[2793]=0;
- a[2794]=0;
- a[2795]=0;
- a[2796]=0;
- a[2797]=0;
- a[2798]=0;
- a[2799]=0;
- a[2800]=0;
- a[2801]=0;
- a[2802]=0;
- a[2803]=0;
- a[2804]=0;
- a[2805]=0;
- a[2806]=0;
- a[2807]=0;
- a[2808]=0;
- a[2809]=0;
- a[2810]=0;
- a[2811]=0;
- a[2812]=0;
- a[2813]=0;
- a[2814]=0;
- a[2815]=0;
- a[2816]=0;
- a[2817]=0;
- a[2818]=0;
- a[2819]=0;
- a[2820]=0;
- a[2821]=0;
- a[2822]=0;
- a[2823]=0;
- a[2824]=0;
- a[2825]=0;
- a[2826]=0;
- a[2827]=0;
- a[2828]=0;
- a[2829]=0;
- a[2830]=0;
- a[2831]=0;
- a[2832]=0;
- a[2833]=0;
- a[2834]=0;
- a[2835]=0;
- a[2836]=0;
- a[2837]=0;
- a[2838]=0;
- a[2839]=0;
- a[2840]=0;
- a[2841]=0;
- a[2842]=0;
- a[2843]=0;
- a[2844]=0;
- a[2845]=0;
- a[2846]=0;
- a[2847]=0;
- a[2848]=0;
- a[2849]=0;
- a[2850]=0;
- a[2851]=0;
- a[2852]=0;
- a[2853]=0;
- a[2854]=0;
- a[2855]=0;
- a[2856]=0;
- a[2857]=0;
- a[2858]=0;
- a[2859]=0;
- a[2860]=0;
- a[2861]=0;
- a[2862]=0;
- a[2863]=0;
- a[2864]=0;
- a[2865]=0;
- a[2866]=0;
- a[2867]=0;
- a[2868]=0;
- a[2869]=0;
- a[2870]=0;
- a[2871]=0;
- a[2872]=0;
- a[2873]=0;
- a[2874]=0;
- a[2875]=0;
- a[2876]=0;
- a[2877]=0;
- a[2878]=0;
- a[2879]=0;
- a[2880]=0;
- a[2881]=0;
- a[2882]=0;
- a[2883]=0;
- a[2884]=0;
- a[2885]=0;
- a[2886]=0;
- a[2887]=0;
- a[2888]=0;
- a[2889]=0;
- a[2890]=0;
- a[2891]=0;
- a[2892]=0;
- a[2893]=0;
- a[2894]=0;
- a[2895]=0;
- a[2896]=0;
- a[2897]=0;
- a[2898]=0;
- a[2899]=0;
- a[2900]=0;
- a[2901]=0;
- a[2902]=0;
- a[2903]=0;
- a[2904]=0;
- a[2905]=0;
- a[2906]=0;
- a[2907]=0;
- a[2908]=0;
- a[2909]=0;
- a[2910]=0;
- a[2911]=0;
- a[2912]=0;
- a[2913]=0;
- a[2914]=0;
- a[2915]=0;
- a[2916]=0;
- a[2917]=0;
- a[2918]=0;
- a[2919]=0;
- a[2920]=0;
- a[2921]=0;
- a[2922]=0;
- a[2923]=0;
- a[2924]=0;
- a[2925]=0;
- a[2926]=0;
- a[2927]=0;
- a[2928]=0;
- a[2929]=0;
- a[2930]=0;
- a[2931]=0;
- a[2932]=0;
- a[2933]=0;
- a[2934]=0;
- a[2935]=0;
- a[2936]=0;
- a[2937]=0;
- a[2938]=0;
- a[2939]=0;
- a[2940]=0;
- a[2941]=0;
- a[2942]=0;
- a[2943]=0;
- a[2944]=0;
- a[2945]=0;
- a[2946]=0;
- a[2947]=0;
- a[2948]=0;
- a[2949]=0;
- a[2950]=0;
- a[2951]=0;
- a[2952]=0;
- a[2953]=0;
- a[2954]=0;
- a[2955]=0;
- a[2956]=0;
- a[2957]=0;
- a[2958]=0;
- a[2959]=0;
- a[2960]=0;
- a[2961]=0;
- a[2962]=0;
- a[2963]=0;
- a[2964]=0;
- a[2965]=0;
- a[2966]=0;
- a[2967]=0;
- a[2968]=0;
- a[2969]=0;
- a[2970]=0;
- a[2971]=0;
- a[2972]=0;
- a[2973]=0;
- a[2974]=0;
- a[2975]=0;
- a[2976]=0;
- a[2977]=0;
- a[2978]=0;
- a[2979]=0;
- a[2980]=0;
- a[2981]=0;
- a[2982]=0;
- a[2983]=0;
- a[2984]=0;
- a[2985]=0;
- a[2986]=0;
- a[2987]=0;
- a[2988]=0;
- a[2989]=0;
- a[2990]=0;
- a[2991]=0;
- a[2992]=0;
- a[2993]=0;
- a[2994]=0;
- a[2995]=0;
- a[2996]=0;
- a[2997]=0;
- a[2998]=0;
- a[2999]=0;
- a[3000]=0;
- a[3001]=0;
- a[3002]=0;
- a[3003]=0;
- a[3004]=0;
- a[3005]=0;
- a[3006]=0;
- a[3007]=0;
- a[3008]=0;
- a[3009]=0;
- a[3010]=0;
- a[3011]=0;
- a[3012]=0;
- a[3013]=0;
- a[3014]=0;
- a[3015]=0;
- a[3016]=0;
- a[3017]=0;
- a[3018]=0;
- a[3019]=0;
- a[3020]=0;
- a[3021]=0;
- a[3022]=0;
- a[3023]=0;
- a[3024]=0;
- a[3025]=0;
- a[3026]=0;
- a[3027]=0;
- a[3028]=0;
- a[3029]=0;
- a[3030]=0;
- a[3031]=0;
- a[3032]=0;
- a[3033]=0;
- a[3034]=0;
- a[3035]=0;
- a[3036]=0;
- a[3037]=0;
- a[3038]=0;
- a[3039]=0;
- a[3040]=0;
- a[3041]=0;
- a[3042]=0;
- a[3043]=0;
- a[3044]=0;
- a[3045]=0;
- a[3046]=0;
- a[3047]=0;
- a[3048]=0;
- a[3049]=0;
- a[3050]=0;
- a[3051]=0;
- a[3052]=0;
- a[3053]=0;
- a[3054]=0;
- a[3055]=0;
- a[3056]=0;
- a[3057]=0;
- a[3058]=0;
- a[3059]=0;
- a[3060]=0;
- a[3061]=0;
- a[3062]=0;
- a[3063]=0;
- a[3064]=0;
- a[3065]=0;
- a[3066]=0;
- a[3067]=0;
- a[3068]=0;
- a[3069]=0;
- a[3070]=0;
- a[3071]=0;
- a[3072]=0;
- a[3073]=0;
- a[3074]=0;
- a[3075]=0;
- a[3076]=0;
- a[3077]=0;
- a[3078]=0;
- a[3079]=0;
- a[3080]=0;
- a[3081]=0;
- a[3082]=0;
- a[3083]=0;
- a[3084]=0;
- a[3085]=0;
- a[3086]=0;
- a[3087]=0;
- a[3088]=0;
- a[3089]=0;
- a[3090]=0;
- a[3091]=0;
- a[3092]=0;
- a[3093]=0;
- a[3094]=0;
- a[3095]=0;
- a[3096]=0;
- a[3097]=0;
- a[3098]=0;
- a[3099]=0;
- a[3100]=0;
- a[3101]=0;
- a[3102]=0;
- a[3103]=0;
- a[3104]=0;
- a[3105]=0;
- a[3106]=0;
- a[3107]=0;
- a[3108]=0;
- a[3109]=0;
- a[3110]=0;
- a[3111]=0;
- a[3112]=0;
- a[3113]=0;
- a[3114]=0;
- a[3115]=0;
- a[3116]=0;
- a[3117]=0;
- a[3118]=0;
- a[3119]=0;
- a[3120]=0;
- a[3121]=0;
- a[3122]=0;
- a[3123]=0;
- a[3124]=0;
- a[3125]=0;
- a[3126]=0;
- a[3127]=0;
- a[3128]=0;
- a[3129]=0;
- a[3130]=0;
- a[3131]=0;
- a[3132]=0;
- a[3133]=0;
- a[3134]=0;
- a[3135]=0;
- a[3136]=0;
- a[3137]=0;
- a[3138]=0;
- a[3139]=0;
- a[3140]=0;
- a[3141]=0;
- a[3142]=0;
- a[3143]=0;
- a[3144]=0;
- a[3145]=0;
- a[3146]=0;
- a[3147]=0;
- a[3148]=0;
- a[3149]=0;
- a[3150]=0;
- a[3151]=0;
- a[3152]=0;
- a[3153]=0;
- a[3154]=0;
- a[3155]=0;
- a[3156]=0;
- a[3157]=0;
- a[3158]=0;
- a[3159]=0;
- a[3160]=0;
- a[3161]=0;
- a[3162]=0;
- a[3163]=0;
- a[3164]=0;
- a[3165]=0;
- a[3166]=0;
- a[3167]=0;
- a[3168]=0;
- a[3169]=0;
- a[3170]=0;
- a[3171]=0;
- a[3172]=0;
- a[3173]=0;
- a[3174]=0;
- a[3175]=0;
- a[3176]=0;
- a[3177]=0;
- a[3178]=0;
- a[3179]=0;
- a[3180]=0;
- a[3181]=0;
- a[3182]=0;
- a[3183]=0;
- a[3184]=0;
- a[3185]=0;
- a[3186]=0;
- a[3187]=0;
- a[3188]=0;
- a[3189]=0;
- a[3190]=0;
- a[3191]=0;
- a[3192]=0;
- a[3193]=0;
- a[3194]=0;
- a[3195]=0;
- a[3196]=0;
- a[3197]=0;
- a[3198]=0;
- a[3199]=0;
- a[3200]=0;
- a[3201]=0;
- a[3202]=0;
- a[3203]=0;
- a[3204]=0;
- a[3205]=0;
- a[3206]=0;
- a[3207]=0;
- a[3208]=0;
- a[3209]=0;
- a[3210]=0;
- a[3211]=0;
- a[3212]=0;
- a[3213]=0;
- a[3214]=0;
- a[3215]=0;
- a[3216]=0;
- a[3217]=0;
- a[3218]=0;
- a[3219]=0;
- a[3220]=0;
- a[3221]=0;
- a[3222]=0;
- a[3223]=0;
- a[3224]=0;
- a[3225]=0;
- a[3226]=0;
- a[3227]=0;
- a[3228]=0;
- a[3229]=0;
- a[3230]=0;
- a[3231]=0;
- a[3232]=0;
- a[3233]=0;
- a[3234]=0;
- a[3235]=0;
- a[3236]=0;
- a[3237]=0;
- a[3238]=0;
- a[3239]=0;
- a[3240]=0;
- a[3241]=0;
- a[3242]=0;
- a[3243]=0;
- a[3244]=0;
- a[3245]=0;
- a[3246]=0;
- a[3247]=0;
- a[3248]=0;
- a[3249]=0;
- a[3250]=0;
- a[3251]=0;
- a[3252]=0;
- a[3253]=0;
- a[3254]=0;
- a[3255]=0;
- a[3256]=0;
- a[3257]=0;
- a[3258]=0;
- a[3259]=0;
- a[3260]=0;
- a[3261]=0;
- a[3262]=0;
- a[3263]=0;
- a[3264]=0;
- a[3265]=0;
- a[3266]=0;
- a[3267]=0;
- a[3268]=0;
- a[3269]=0;
- a[3270]=0;
- a[3271]=0;
- a[3272]=0;
- a[3273]=0;
- a[3274]=0;
- a[3275]=0;
- a[3276]=0;
- a[3277]=0;
- a[3278]=0;
- a[3279]=0;
- a[3280]=0;
- a[3281]=0;
- a[3282]=0;
- a[3283]=0;
- a[3284]=0;
- a[3285]=0;
- a[3286]=0;
- a[3287]=0;
- a[3288]=0;
- a[3289]=0;
- a[3290]=0;
- a[3291]=0;
- a[3292]=0;
- a[3293]=0;
- a[3294]=0;
- a[3295]=0;
- a[3296]=0;
- a[3297]=0;
- a[3298]=0;
- a[3299]=0;
- a[3300]=0;
- a[3301]=0;
- a[3302]=0;
- a[3303]=0;
- a[3304]=0;
- a[3305]=0;
- a[3306]=0;
- a[3307]=0;
- a[3308]=0;
- a[3309]=0;
- a[3310]=0;
- a[3311]=0;
- a[3312]=0;
- a[3313]=0;
- a[3314]=0;
- a[3315]=0;
- a[3316]=0;
- a[3317]=0;
- a[3318]=0;
- a[3319]=0;
- a[3320]=0;
- a[3321]=0;
- a[3322]=0;
- a[3323]=0;
- a[3324]=0;
- a[3325]=0;
- a[3326]=0;
- a[3327]=0;
- a[3328]=0;
- a[3329]=0;
- a[3330]=0;
- a[3331]=0;
- a[3332]=0;
- a[3333]=0;
- a[3334]=0;
- a[3335]=0;
- a[3336]=0;
- a[3337]=0;
- a[3338]=0;
- a[3339]=0;
- a[3340]=0;
- a[3341]=0;
- a[3342]=0;
- a[3343]=0;
- a[3344]=0;
- a[3345]=0;
- a[3346]=0;
- a[3347]=0;
- a[3348]=0;
- a[3349]=0;
- a[3350]=0;
- a[3351]=0;
- a[3352]=0;
- a[3353]=0;
- a[3354]=0;
- a[3355]=0;
- a[3356]=0;
- a[3357]=0;
- a[3358]=0;
- a[3359]=0;
- a[3360]=0;
- a[3361]=0;
- a[3362]=0;
- a[3363]=0;
- a[3364]=0;
- a[3365]=0;
- a[3366]=0;
- a[3367]=0;
- a[3368]=0;
- a[3369]=0;
- a[3370]=0;
- a[3371]=0;
- a[3372]=0;
- a[3373]=0;
- a[3374]=0;
- a[3375]=0;
- a[3376]=0;
- a[3377]=0;
- a[3378]=0;
- a[3379]=0;
- a[3380]=0;
- a[3381]=0;
- a[3382]=0;
- a[3383]=0;
- a[3384]=0;
- a[3385]=0;
- a[3386]=0;
- a[3387]=0;
- a[3388]=0;
- a[3389]=0;
- a[3390]=0;
- a[3391]=0;
- a[3392]=0;
- a[3393]=0;
- a[3394]=0;
- a[3395]=0;
- a[3396]=0;
- a[3397]=0;
- a[3398]=0;
- a[3399]=0;
- a[3400]=0;
- a[3401]=0;
- a[3402]=0;
- a[3403]=0;
- a[3404]=0;
- a[3405]=0;
- a[3406]=0;
- a[3407]=0;
- a[3408]=0;
- a[3409]=0;
- a[3410]=0;
- a[3411]=0;
- a[3412]=0;
- a[3413]=0;
- a[3414]=0;
- a[3415]=0;
- a[3416]=0;
- a[3417]=0;
- a[3418]=0;
- a[3419]=0;
- a[3420]=0;
- a[3421]=0;
- a[3422]=0;
- a[3423]=0;
- a[3424]=0;
- a[3425]=0;
- a[3426]=0;
- a[3427]=0;
- a[3428]=0;
- a[3429]=0;
- a[3430]=0;
- a[3431]=0;
- a[3432]=0;
- a[3433]=0;
- a[3434]=0;
- a[3435]=0;
- a[3436]=0;
- a[3437]=0;
- a[3438]=0;
- a[3439]=0;
- a[3440]=0;
- a[3441]=0;
- a[3442]=0;
- a[3443]=0;
- a[3444]=0;
- a[3445]=0;
- a[3446]=0;
- a[3447]=0;
- a[3448]=0;
- a[3449]=0;
- a[3450]=0;
- a[3451]=0;
- a[3452]=0;
- a[3453]=0;
- a[3454]=0;
- a[3455]=0;
- a[3456]=0;
- a[3457]=0;
- a[3458]=0;
- a[3459]=0;
- a[3460]=0;
- a[3461]=0;
- a[3462]=0;
- a[3463]=0;
- a[3464]=0;
- a[3465]=0;
- a[3466]=0;
- a[3467]=0;
- a[3468]=0;
- a[3469]=0;
- a[3470]=0;
- a[3471]=0;
- a[3472]=0;
- a[3473]=0;
- a[3474]=0;
- a[3475]=0;
- a[3476]=0;
- a[3477]=0;
- a[3478]=0;
- a[3479]=0;
- a[3480]=0;
- a[3481]=0;
- a[3482]=0;
- a[3483]=0;
- a[3484]=0;
- a[3485]=0;
- a[3486]=0;
- a[3487]=0;
- a[3488]=0;
- a[3489]=0;
- a[3490]=0;
- a[3491]=0;
- a[3492]=0;
- a[3493]=0;
- a[3494]=0;
- a[3495]=0;
- a[3496]=0;
- a[3497]=0;
- a[3498]=0;
- a[3499]=0;
- a[3500]=0;
- a[3501]=0;
- a[3502]=0;
- a[3503]=0;
- a[3504]=0;
- a[3505]=0;
- a[3506]=0;
- a[3507]=0;
- a[3508]=0;
- a[3509]=0;
- a[3510]=0;
- a[3511]=0;
- a[3512]=0;
- a[3513]=0;
- a[3514]=0;
- a[3515]=0;
- a[3516]=0;
- a[3517]=0;
- a[3518]=0;
- a[3519]=0;
- a[3520]=0;
- a[3521]=0;
- a[3522]=0;
- a[3523]=0;
- a[3524]=0;
- a[3525]=0;
- a[3526]=0;
- a[3527]=0;
- a[3528]=0;
- a[3529]=0;
- a[3530]=0;
- a[3531]=0;
- a[3532]=0;
- a[3533]=0;
- a[3534]=0;
- a[3535]=0;
- a[3536]=0;
- a[3537]=0;
- a[3538]=0;
- a[3539]=0;
- a[3540]=0;
- a[3541]=0;
- a[3542]=0;
- a[3543]=0;
- a[3544]=0;
- a[3545]=0;
- a[3546]=0;
- a[3547]=0;
- a[3548]=0;
- a[3549]=0;
- a[3550]=0;
- a[3551]=0;
- a[3552]=0;
- a[3553]=0;
- a[3554]=0;
- a[3555]=0;
- a[3556]=0;
- a[3557]=0;
- a[3558]=0;
- a[3559]=0;
- a[3560]=0;
- a[3561]=0;
- a[3562]=0;
- a[3563]=0;
- a[3564]=0;
- a[3565]=0;
- a[3566]=0;
- a[3567]=0;
- a[3568]=0;
- a[3569]=0;
- a[3570]=0;
- a[3571]=0;
- a[3572]=0;
- a[3573]=0;
- a[3574]=0;
- a[3575]=0;
- a[3576]=0;
- a[3577]=0;
- a[3578]=0;
- a[3579]=0;
- a[3580]=0;
- a[3581]=0;
- a[3582]=0;
- a[3583]=0;
- a[3584]=0;
- a[3585]=0;
- a[3586]=0;
- a[3587]=0;
- a[3588]=0;
- a[3589]=0;
- a[3590]=0;
- a[3591]=0;
- a[3592]=0;
- a[3593]=0;
- a[3594]=0;
- a[3595]=0;
- a[3596]=0;
- a[3597]=0;
- a[3598]=0;
- a[3599]=0;
- a[3600]=0;
- a[3601]=0;
- a[3602]=0;
- a[3603]=0;
- a[3604]=0;
- a[3605]=0;
- a[3606]=0;
- a[3607]=0;
- a[3608]=0;
- a[3609]=0;
- a[3610]=0;
- a[3611]=0;
- a[3612]=0;
- a[3613]=0;
- a[3614]=0;
- a[3615]=0;
- a[3616]=0;
- a[3617]=0;
- a[3618]=0;
- a[3619]=0;
- a[3620]=0;
- a[3621]=0;
- a[3622]=0;
- a[3623]=0;
- a[3624]=0;
- a[3625]=0;
- a[3626]=0;
- a[3627]=0;
- a[3628]=0;
- a[3629]=0;
- a[3630]=0;
- a[3631]=0;
- a[3632]=0;
- a[3633]=0;
- a[3634]=0;
- a[3635]=0;
- a[3636]=0;
- a[3637]=0;
- a[3638]=0;
- a[3639]=0;
- a[3640]=0;
- a[3641]=0;
- a[3642]=0;
- a[3643]=0;
- a[3644]=0;
- a[3645]=0;
- a[3646]=0;
- a[3647]=0;
- a[3648]=0;
- a[3649]=0;
- a[3650]=0;
- a[3651]=0;
- a[3652]=0;
- a[3653]=0;
- a[3654]=0;
- a[3655]=0;
- a[3656]=0;
- a[3657]=0;
- a[3658]=0;
- a[3659]=0;
- a[3660]=0;
- a[3661]=0;
- a[3662]=0;
- a[3663]=0;
- a[3664]=0;
- a[3665]=0;
- a[3666]=0;
- a[3667]=0;
- a[3668]=0;
- a[3669]=0;
- a[3670]=0;
- a[3671]=0;
- a[3672]=0;
- a[3673]=0;
- a[3674]=0;
- a[3675]=0;
- a[3676]=0;
- a[3677]=0;
- a[3678]=0;
- a[3679]=0;
- a[3680]=0;
- a[3681]=0;
- a[3682]=0;
- a[3683]=0;
- a[3684]=0;
- a[3685]=0;
- a[3686]=0;
- a[3687]=0;
- a[3688]=0;
- a[3689]=0;
- a[3690]=0;
- a[3691]=0;
- a[3692]=0;
- a[3693]=0;
- a[3694]=0;
- a[3695]=0;
- a[3696]=0;
- a[3697]=0;
- a[3698]=0;
- a[3699]=0;
- a[3700]=0;
- a[3701]=0;
- a[3702]=0;
- a[3703]=0;
- a[3704]=0;
- a[3705]=0;
- a[3706]=0;
- a[3707]=0;
- a[3708]=0;
- a[3709]=0;
- a[3710]=0;
- a[3711]=0;
- a[3712]=0;
- a[3713]=0;
- a[3714]=0;
- a[3715]=0;
- a[3716]=0;
- a[3717]=0;
- a[3718]=0;
- a[3719]=0;
- a[3720]=0;
- a[3721]=0;
- a[3722]=0;
- a[3723]=0;
- a[3724]=0;
- a[3725]=0;
- a[3726]=0;
- a[3727]=0;
- a[3728]=0;
- a[3729]=0;
- a[3730]=0;
- a[3731]=0;
- a[3732]=0;
- a[3733]=0;
- a[3734]=0;
- a[3735]=0;
- a[3736]=0;
- a[3737]=0;
- a[3738]=0;
- a[3739]=0;
- a[3740]=0;
- a[3741]=0;
- a[3742]=0;
- a[3743]=0;
- a[3744]=0;
- a[3745]=0;
- a[3746]=0;
- a[3747]=0;
- a[3748]=0;
- a[3749]=0;
- a[3750]=0;
- a[3751]=0;
- a[3752]=0;
- a[3753]=0;
- a[3754]=0;
- a[3755]=0;
- a[3756]=0;
- a[3757]=0;
- a[3758]=0;
- a[3759]=0;
- a[3760]=0;
- a[3761]=0;
- a[3762]=0;
- a[3763]=0;
- a[3764]=0;
- a[3765]=0;
- a[3766]=0;
- a[3767]=0;
- a[3768]=0;
- a[3769]=0;
- a[3770]=0;
- a[3771]=0;
- a[3772]=0;
- a[3773]=0;
- a[3774]=0;
- a[3775]=0;
- a[3776]=0;
- a[3777]=0;
- a[3778]=0;
- a[3779]=0;
- a[3780]=0;
- a[3781]=0;
- a[3782]=0;
- a[3783]=0;
- a[3784]=0;
- a[3785]=0;
- a[3786]=0;
- a[3787]=0;
- a[3788]=0;
- a[3789]=0;
- a[3790]=0;
- a[3791]=0;
- a[3792]=0;
- a[3793]=0;
- a[3794]=0;
- a[3795]=0;
- a[3796]=0;
- a[3797]=0;
- a[3798]=0;
- a[3799]=0;
- a[3800]=0;
- a[3801]=0;
- a[3802]=0;
- a[3803]=0;
- a[3804]=0;
- a[3805]=0;
- a[3806]=0;
- a[3807]=0;
- a[3808]=0;
- a[3809]=0;
- a[3810]=0;
- a[3811]=0;
- a[3812]=0;
- a[3813]=0;
- a[3814]=0;
- a[3815]=0;
- a[3816]=0;
- a[3817]=0;
- a[3818]=0;
- a[3819]=0;
- a[3820]=0;
- a[3821]=0;
- a[3822]=0;
- a[3823]=0;
- a[3824]=0;
- a[3825]=0;
- a[3826]=0;
- a[3827]=0;
- a[3828]=0;
- a[3829]=0;
- a[3830]=0;
- a[3831]=0;
- a[3832]=0;
- a[3833]=0;
- a[3834]=0;
- a[3835]=0;
- a[3836]=0;
- a[3837]=0;
- a[3838]=0;
- a[3839]=0;
- a[3840]=0;
- a[3841]=0;
- a[3842]=0;
- a[3843]=0;
- a[3844]=0;
- a[3845]=0;
- a[3846]=0;
- a[3847]=0;
- a[3848]=0;
- a[3849]=0;
- a[3850]=0;
- a[3851]=0;
- a[3852]=0;
- a[3853]=0;
- a[3854]=0;
- a[3855]=0;
- a[3856]=0;
- a[3857]=0;
- a[3858]=0;
- a[3859]=0;
- a[3860]=0;
- a[3861]=0;
- a[3862]=0;
- a[3863]=0;
- a[3864]=0;
- a[3865]=0;
- a[3866]=0;
- a[3867]=0;
- a[3868]=0;
- a[3869]=0;
- a[3870]=0;
- a[3871]=0;
- a[3872]=0;
- a[3873]=0;
- a[3874]=0;
- a[3875]=0;
- a[3876]=0;
- a[3877]=0;
- a[3878]=0;
- a[3879]=0;
- a[3880]=0;
- a[3881]=0;
- a[3882]=0;
- a[3883]=0;
- a[3884]=0;
- a[3885]=0;
- a[3886]=0;
- a[3887]=0;
- a[3888]=0;
- a[3889]=0;
- a[3890]=0;
- a[3891]=0;
- a[3892]=0;
- a[3893]=0;
- a[3894]=0;
- a[3895]=0;
- a[3896]=0;
- a[3897]=0;
- a[3898]=0;
- a[3899]=0;
- a[3900]=0;
- a[3901]=0;
- a[3902]=0;
- a[3903]=0;
- a[3904]=0;
- a[3905]=0;
- a[3906]=0;
- a[3907]=0;
- a[3908]=0;
- a[3909]=0;
- a[3910]=0;
- a[3911]=0;
- a[3912]=0;
- a[3913]=0;
- a[3914]=0;
- a[3915]=0;
- a[3916]=0;
- a[3917]=0;
- a[3918]=0;
- a[3919]=0;
- a[3920]=0;
- a[3921]=0;
- a[3922]=0;
- a[3923]=0;
- a[3924]=0;
- a[3925]=0;
- a[3926]=0;
- a[3927]=0;
- a[3928]=0;
- a[3929]=0;
- a[3930]=0;
- a[3931]=0;
- a[3932]=0;
- a[3933]=0;
- a[3934]=0;
- a[3935]=0;
- a[3936]=0;
- a[3937]=0;
- a[3938]=0;
- a[3939]=0;
- a[3940]=0;
- a[3941]=0;
- a[3942]=0;
- a[3943]=0;
- a[3944]=0;
- a[3945]=0;
- a[3946]=0;
- a[3947]=0;
- a[3948]=0;
- a[3949]=0;
- a[3950]=0;
- a[3951]=0;
- a[3952]=0;
- a[3953]=0;
- a[3954]=0;
- a[3955]=0;
- a[3956]=0;
- a[3957]=0;
- a[3958]=0;
- a[3959]=0;
- a[3960]=0;
- a[3961]=0;
- a[3962]=0;
- a[3963]=0;
- a[3964]=0;
- a[3965]=0;
- a[3966]=0;
- a[3967]=0;
- a[3968]=0;
- a[3969]=0;
- a[3970]=0;
- a[3971]=0;
- a[3972]=0;
- a[3973]=0;
- a[3974]=0;
- a[3975]=0;
- a[3976]=0;
- a[3977]=0;
- a[3978]=0;
- a[3979]=0;
- a[3980]=0;
- a[3981]=0;
- a[3982]=0;
- a[3983]=0;
- a[3984]=0;
- a[3985]=0;
- a[3986]=0;
- a[3987]=0;
- a[3988]=0;
- a[3989]=0;
- a[3990]=0;
- a[3991]=0;
- a[3992]=0;
- a[3993]=0;
- a[3994]=0;
- a[3995]=0;
- a[3996]=0;
- a[3997]=0;
- a[3998]=0;
- a[3999]=0;
- a[4000]=0;
- a[4001]=0;
- a[4002]=0;
- a[4003]=0;
- a[4004]=0;
- a[4005]=0;
- a[4006]=0;
- a[4007]=0;
- a[4008]=0;
- a[4009]=0;
- a[4010]=0;
- a[4011]=0;
- a[4012]=0;
- a[4013]=0;
- a[4014]=0;
- a[4015]=0;
- a[4016]=0;
- a[4017]=0;
- a[4018]=0;
- a[4019]=0;
- a[4020]=0;
- a[4021]=0;
- a[4022]=0;
- a[4023]=0;
- a[4024]=0;
- a[4025]=0;
- a[4026]=0;
- a[4027]=0;
- a[4028]=0;
- a[4029]=0;
- a[4030]=0;
- a[4031]=0;
- a[4032]=0;
- a[4033]=0;
- a[4034]=0;
- a[4035]=0;
- a[4036]=0;
- a[4037]=0;
- a[4038]=0;
- a[4039]=0;
- a[4040]=0;
- a[4041]=0;
- a[4042]=0;
- a[4043]=0;
- a[4044]=0;
- a[4045]=0;
- a[4046]=0;
- a[4047]=0;
- a[4048]=0;
- a[4049]=0;
- a[4050]=0;
- a[4051]=0;
- a[4052]=0;
- a[4053]=0;
- a[4054]=0;
- a[4055]=0;
- a[4056]=0;
- a[4057]=0;
- a[4058]=0;
- a[4059]=0;
- a[4060]=0;
- a[4061]=0;
- a[4062]=0;
- a[4063]=0;
- a[4064]=0;
- a[4065]=0;
- a[4066]=0;
- a[4067]=0;
- a[4068]=0;
- a[4069]=0;
- a[4070]=0;
- a[4071]=0;
- a[4072]=0;
- a[4073]=0;
- a[4074]=0;
- a[4075]=0;
- a[4076]=0;
- a[4077]=0;
- a[4078]=0;
- a[4079]=0;
- a[4080]=0;
- a[4081]=0;
- a[4082]=0;
- a[4083]=0;
- a[4084]=0;
- a[4085]=0;
- a[4086]=0;
- a[4087]=0;
- a[4088]=0;
- a[4089]=0;
- a[4090]=0;
- a[4091]=0;
- a[4092]=0;
- a[4093]=0;
- a[4094]=0;
- a[4095]=0;
- a[4096]=0;
- a[4097]=0;
- a[4098]=0;
- a[4099]=0;
- a[4100]=0;
- a[4101]=0;
- a[4102]=0;
- a[4103]=0;
- a[4104]=0;
- a[4105]=0;
- a[4106]=0;
- a[4107]=0;
- a[4108]=0;
- a[4109]=0;
- a[4110]=0;
- a[4111]=0;
- a[4112]=0;
- a[4113]=0;
- a[4114]=0;
- a[4115]=0;
- a[4116]=0;
- a[4117]=0;
- a[4118]=0;
- a[4119]=0;
- a[4120]=0;
- a[4121]=0;
- a[4122]=0;
- a[4123]=0;
- a[4124]=0;
- a[4125]=0;
- a[4126]=0;
- a[4127]=0;
- a[4128]=0;
- a[4129]=0;
- a[4130]=0;
- a[4131]=0;
- a[4132]=0;
- a[4133]=0;
- a[4134]=0;
- a[4135]=0;
- a[4136]=0;
- a[4137]=0;
- a[4138]=0;
- a[4139]=0;
- a[4140]=0;
- a[4141]=0;
- a[4142]=0;
- a[4143]=0;
- a[4144]=0;
- a[4145]=0;
- a[4146]=0;
- a[4147]=0;
- a[4148]=0;
- a[4149]=0;
- a[4150]=0;
- a[4151]=0;
- a[4152]=0;
- a[4153]=0;
- a[4154]=0;
- a[4155]=0;
- a[4156]=0;
- a[4157]=0;
- a[4158]=0;
- a[4159]=0;
- a[4160]=0;
- a[4161]=0;
- a[4162]=0;
- a[4163]=0;
- a[4164]=0;
- a[4165]=0;
- a[4166]=0;
- a[4167]=0;
- a[4168]=0;
- a[4169]=0;
- a[4170]=0;
- a[4171]=0;
- a[4172]=0;
- a[4173]=0;
- a[4174]=0;
- a[4175]=0;
- a[4176]=0;
- a[4177]=0;
- a[4178]=0;
- a[4179]=0;
- a[4180]=0;
- a[4181]=0;
- a[4182]=0;
- a[4183]=0;
- a[4184]=0;
- a[4185]=0;
- a[4186]=0;
- a[4187]=0;
- a[4188]=0;
- a[4189]=0;
- a[4190]=0;
- a[4191]=0;
- a[4192]=0;
- a[4193]=0;
- a[4194]=0;
- a[4195]=0;
- a[4196]=0;
- a[4197]=0;
- a[4198]=0;
- a[4199]=0;
- a[4200]=0;
- a[4201]=0;
- a[4202]=0;
- a[4203]=0;
- a[4204]=0;
- a[4205]=0;
- a[4206]=0;
- a[4207]=0;
- a[4208]=0;
- a[4209]=0;
- a[4210]=0;
- a[4211]=0;
- a[4212]=0;
- a[4213]=0;
- a[4214]=0;
- a[4215]=0;
- a[4216]=0;
- a[4217]=0;
- a[4218]=0;
- a[4219]=0;
- a[4220]=0;
- a[4221]=0;
- a[4222]=0;
- a[4223]=0;
- a[4224]=0;
- a[4225]=0;
- a[4226]=0;
- a[4227]=0;
- a[4228]=0;
- a[4229]=0;
- a[4230]=0;
- a[4231]=0;
- a[4232]=0;
- a[4233]=0;
- a[4234]=0;
- a[4235]=0;
- a[4236]=0;
- a[4237]=0;
- a[4238]=0;
- a[4239]=0;
- a[4240]=0;
- a[4241]=0;
- a[4242]=0;
- a[4243]=0;
- a[4244]=0;
- a[4245]=0;
- a[4246]=0;
- a[4247]=0;
- a[4248]=0;
- a[4249]=0;
- a[4250]=0;
- a[4251]=0;
- a[4252]=0;
- a[4253]=0;
- a[4254]=0;
- a[4255]=0;
- a[4256]=0;
- a[4257]=0;
- a[4258]=0;
- a[4259]=0;
- a[4260]=0;
- a[4261]=0;
- a[4262]=0;
- a[4263]=0;
- a[4264]=0;
- a[4265]=0;
- a[4266]=0;
- a[4267]=0;
- a[4268]=0;
- a[4269]=0;
- a[4270]=0;
- a[4271]=0;
- a[4272]=0;
- a[4273]=0;
- a[4274]=0;
- a[4275]=0;
- a[4276]=0;
- a[4277]=0;
- a[4278]=0;
- a[4279]=0;
- a[4280]=0;
- a[4281]=0;
- a[4282]=0;
- a[4283]=0;
- a[4284]=0;
- a[4285]=0;
- a[4286]=0;
- a[4287]=0;
- a[4288]=0;
- a[4289]=0;
- a[4290]=0;
- a[4291]=0;
- a[4292]=0;
- a[4293]=0;
- a[4294]=0;
- a[4295]=0;
- a[4296]=0;
- a[4297]=0;
- a[4298]=0;
- a[4299]=0;
- a[4300]=0;
- a[4301]=0;
- a[4302]=0;
- a[4303]=0;
- a[4304]=0;
- a[4305]=0;
- a[4306]=0;
- a[4307]=0;
- a[4308]=0;
- a[4309]=0;
- a[4310]=0;
- a[4311]=0;
- a[4312]=0;
- a[4313]=0;
- a[4314]=0;
- a[4315]=0;
- a[4316]=0;
- a[4317]=0;
- a[4318]=0;
- a[4319]=0;
- a[4320]=0;
- a[4321]=0;
- a[4322]=0;
- a[4323]=0;
- a[4324]=0;
- a[4325]=0;
- a[4326]=0;
- a[4327]=0;
- a[4328]=0;
- a[4329]=0;
- a[4330]=0;
- a[4331]=0;
- a[4332]=0;
- a[4333]=0;
- a[4334]=0;
- a[4335]=0;
- a[4336]=0;
- a[4337]=0;
- a[4338]=0;
- a[4339]=0;
- a[4340]=0;
- a[4341]=0;
- a[4342]=0;
- a[4343]=0;
- a[4344]=0;
- a[4345]=0;
- a[4346]=0;
- a[4347]=0;
- a[4348]=0;
- a[4349]=0;
- a[4350]=0;
- a[4351]=0;
- a[4352]=0;
- a[4353]=0;
- a[4354]=0;
- a[4355]=0;
- a[4356]=0;
- a[4357]=0;
- a[4358]=0;
- a[4359]=0;
- a[4360]=0;
- a[4361]=0;
- a[4362]=0;
- a[4363]=0;
- a[4364]=0;
- a[4365]=0;
- a[4366]=0;
- a[4367]=0;
- a[4368]=0;
- a[4369]=0;
- a[4370]=0;
- a[4371]=0;
- a[4372]=0;
- a[4373]=0;
- a[4374]=0;
- a[4375]=0;
- a[4376]=0;
- a[4377]=0;
- a[4378]=0;
- a[4379]=0;
- a[4380]=0;
- a[4381]=0;
- a[4382]=0;
- a[4383]=0;
- a[4384]=0;
- a[4385]=0;
- a[4386]=0;
- a[4387]=0;
- a[4388]=0;
- a[4389]=0;
- a[4390]=0;
- a[4391]=0;
- a[4392]=0;
- a[4393]=0;
- a[4394]=0;
- a[4395]=0;
- a[4396]=0;
- a[4397]=0;
- a[4398]=0;
- a[4399]=0;
- a[4400]=0;
- a[4401]=0;
- a[4402]=0;
- a[4403]=0;
- a[4404]=0;
- a[4405]=0;
- a[4406]=0;
- a[4407]=0;
- a[4408]=0;
- a[4409]=0;
- a[4410]=0;
- a[4411]=0;
- a[4412]=0;
- a[4413]=0;
- a[4414]=0;
- a[4415]=0;
- a[4416]=0;
- a[4417]=0;
- a[4418]=0;
- a[4419]=0;
- a[4420]=0;
- a[4421]=0;
- a[4422]=0;
- a[4423]=0;
- a[4424]=0;
- a[4425]=0;
- a[4426]=0;
- a[4427]=0;
- a[4428]=0;
- a[4429]=0;
- a[4430]=0;
- a[4431]=0;
- a[4432]=0;
- a[4433]=0;
- a[4434]=0;
- a[4435]=0;
- a[4436]=0;
- a[4437]=0;
- a[4438]=0;
- a[4439]=0;
- a[4440]=0;
- a[4441]=0;
- a[4442]=0;
- a[4443]=0;
- a[4444]=0;
- a[4445]=0;
- a[4446]=0;
- a[4447]=0;
- a[4448]=0;
- a[4449]=0;
- a[4450]=0;
- a[4451]=0;
- a[4452]=0;
- a[4453]=0;
- a[4454]=0;
- a[4455]=0;
- a[4456]=0;
- a[4457]=0;
- a[4458]=0;
- a[4459]=0;
- a[4460]=0;
- a[4461]=0;
- a[4462]=0;
- a[4463]=0;
- a[4464]=0;
- a[4465]=0;
- a[4466]=0;
- a[4467]=0;
- a[4468]=0;
- a[4469]=0;
- a[4470]=0;
- a[4471]=0;
- a[4472]=0;
- a[4473]=0;
- a[4474]=0;
- a[4475]=0;
- a[4476]=0;
- a[4477]=0;
- a[4478]=0;
- a[4479]=0;
- a[4480]=0;
- a[4481]=0;
- a[4482]=0;
- a[4483]=0;
- a[4484]=0;
- a[4485]=0;
- a[4486]=0;
- a[4487]=0;
- a[4488]=0;
- a[4489]=0;
- a[4490]=0;
- a[4491]=0;
- a[4492]=0;
- a[4493]=0;
- a[4494]=0;
- a[4495]=0;
- a[4496]=0;
- a[4497]=0;
- a[4498]=0;
- a[4499]=0;
- a[4500]=0;
- a[4501]=0;
- a[4502]=0;
- a[4503]=0;
- a[4504]=0;
- a[4505]=0;
- a[4506]=0;
- a[4507]=0;
- a[4508]=0;
- a[4509]=0;
- a[4510]=0;
- a[4511]=0;
- a[4512]=0;
- a[4513]=0;
- a[4514]=0;
- a[4515]=0;
- a[4516]=0;
- a[4517]=0;
- a[4518]=0;
- a[4519]=0;
- a[4520]=0;
- a[4521]=0;
- a[4522]=0;
- a[4523]=0;
- a[4524]=0;
- a[4525]=0;
- a[4526]=0;
- a[4527]=0;
- a[4528]=0;
- a[4529]=0;
- a[4530]=0;
- a[4531]=0;
- a[4532]=0;
- a[4533]=0;
- a[4534]=0;
- a[4535]=0;
- a[4536]=0;
- a[4537]=0;
- a[4538]=0;
- a[4539]=0;
- a[4540]=0;
- a[4541]=0;
- a[4542]=0;
- a[4543]=0;
- a[4544]=0;
- a[4545]=0;
- a[4546]=0;
- a[4547]=0;
- a[4548]=0;
- a[4549]=0;
- a[4550]=0;
- a[4551]=0;
- a[4552]=0;
- a[4553]=0;
- a[4554]=0;
- a[4555]=0;
- a[4556]=0;
- a[4557]=0;
- a[4558]=0;
- a[4559]=0;
- a[4560]=0;
- a[4561]=0;
- a[4562]=0;
- a[4563]=0;
- a[4564]=0;
- a[4565]=0;
- a[4566]=0;
- a[4567]=0;
- a[4568]=0;
- a[4569]=0;
- a[4570]=0;
- a[4571]=0;
- a[4572]=0;
- a[4573]=0;
- a[4574]=0;
- a[4575]=0;
- a[4576]=0;
- a[4577]=0;
- a[4578]=0;
- a[4579]=0;
- a[4580]=0;
- a[4581]=0;
- a[4582]=0;
- a[4583]=0;
- a[4584]=0;
- a[4585]=0;
- a[4586]=0;
- a[4587]=0;
- a[4588]=0;
- a[4589]=0;
- a[4590]=0;
- a[4591]=0;
- a[4592]=0;
- a[4593]=0;
- a[4594]=0;
- a[4595]=0;
- a[4596]=0;
- a[4597]=0;
- a[4598]=0;
- a[4599]=0;
- a[4600]=0;
- a[4601]=0;
- a[4602]=0;
- a[4603]=0;
- a[4604]=0;
- a[4605]=0;
- a[4606]=0;
- a[4607]=0;
- a[4608]=0;
- a[4609]=0;
- a[4610]=0;
- a[4611]=0;
- a[4612]=0;
- a[4613]=0;
- a[4614]=0;
- a[4615]=0;
- a[4616]=0;
- a[4617]=0;
- a[4618]=0;
- a[4619]=0;
- a[4620]=0;
- a[4621]=0;
- a[4622]=0;
- a[4623]=0;
- a[4624]=0;
- a[4625]=0;
- a[4626]=0;
- a[4627]=0;
- a[4628]=0;
- a[4629]=0;
- a[4630]=0;
- a[4631]=0;
- a[4632]=0;
- a[4633]=0;
- a[4634]=0;
- a[4635]=0;
- a[4636]=0;
- a[4637]=0;
- a[4638]=0;
- a[4639]=0;
- a[4640]=0;
- a[4641]=0;
- a[4642]=0;
- a[4643]=0;
- a[4644]=0;
- a[4645]=0;
- a[4646]=0;
- a[4647]=0;
- a[4648]=0;
- a[4649]=0;
- a[4650]=0;
- a[4651]=0;
- a[4652]=0;
- a[4653]=0;
- a[4654]=0;
- a[4655]=0;
- a[4656]=0;
- a[4657]=0;
- a[4658]=0;
- a[4659]=0;
- a[4660]=0;
- a[4661]=0;
- a[4662]=0;
- a[4663]=0;
- a[4664]=0;
- a[4665]=0;
- a[4666]=0;
- a[4667]=0;
- a[4668]=0;
- a[4669]=0;
- a[4670]=0;
- a[4671]=0;
- a[4672]=0;
- a[4673]=0;
- a[4674]=0;
- a[4675]=0;
- a[4676]=0;
- a[4677]=0;
- a[4678]=0;
- a[4679]=0;
- a[4680]=0;
- a[4681]=0;
- a[4682]=0;
- a[4683]=0;
- a[4684]=0;
- a[4685]=0;
- a[4686]=0;
- a[4687]=0;
- a[4688]=0;
- a[4689]=0;
- a[4690]=0;
- a[4691]=0;
- a[4692]=0;
- a[4693]=0;
- a[4694]=0;
- a[4695]=0;
- a[4696]=0;
- a[4697]=0;
- a[4698]=0;
- a[4699]=0;
- a[4700]=0;
- a[4701]=0;
- a[4702]=0;
- a[4703]=0;
- a[4704]=0;
- a[4705]=0;
- a[4706]=0;
- a[4707]=0;
- a[4708]=0;
- a[4709]=0;
- a[4710]=0;
- a[4711]=0;
- a[4712]=0;
- a[4713]=0;
- a[4714]=0;
- a[4715]=0;
- a[4716]=0;
- a[4717]=0;
- a[4718]=0;
- a[4719]=0;
- a[4720]=0;
- a[4721]=0;
- a[4722]=0;
- a[4723]=0;
- a[4724]=0;
- a[4725]=0;
- a[4726]=0;
- a[4727]=0;
- a[4728]=0;
- a[4729]=0;
- a[4730]=0;
- a[4731]=0;
- a[4732]=0;
- a[4733]=0;
- a[4734]=0;
- a[4735]=0;
- a[4736]=0;
- a[4737]=0;
- a[4738]=0;
- a[4739]=0;
- a[4740]=0;
- a[4741]=0;
- a[4742]=0;
- a[4743]=0;
- a[4744]=0;
- a[4745]=0;
- a[4746]=0;
- a[4747]=0;
- a[4748]=0;
- a[4749]=0;
- a[4750]=0;
- a[4751]=0;
- a[4752]=0;
- a[4753]=0;
- a[4754]=0;
- a[4755]=0;
- a[4756]=0;
- a[4757]=0;
- a[4758]=0;
- a[4759]=0;
- a[4760]=0;
- a[4761]=0;
- a[4762]=0;
- a[4763]=0;
- a[4764]=0;
- a[4765]=0;
- a[4766]=0;
- a[4767]=0;
- a[4768]=0;
- a[4769]=0;
- a[4770]=0;
- a[4771]=0;
- a[4772]=0;
- a[4773]=0;
- a[4774]=0;
- a[4775]=0;
- a[4776]=0;
- a[4777]=0;
- a[4778]=0;
- a[4779]=0;
- a[4780]=0;
- a[4781]=0;
- a[4782]=0;
- a[4783]=0;
- a[4784]=0;
- a[4785]=0;
- a[4786]=0;
- a[4787]=0;
- a[4788]=0;
- a[4789]=0;
- a[4790]=0;
- a[4791]=0;
- a[4792]=0;
- a[4793]=0;
- a[4794]=0;
- a[4795]=0;
- a[4796]=0;
- a[4797]=0;
- a[4798]=0;
- a[4799]=0;
- a[4800]=0;
- a[4801]=0;
- a[4802]=0;
- a[4803]=0;
- a[4804]=0;
- a[4805]=0;
- a[4806]=0;
- a[4807]=0;
- a[4808]=0;
- a[4809]=0;
- a[4810]=0;
- a[4811]=0;
- a[4812]=0;
- a[4813]=0;
- a[4814]=0;
- a[4815]=0;
- a[4816]=0;
- a[4817]=0;
- a[4818]=0;
- a[4819]=0;
- a[4820]=0;
- a[4821]=0;
- a[4822]=0;
- a[4823]=0;
- a[4824]=0;
- a[4825]=0;
- a[4826]=0;
- a[4827]=0;
- a[4828]=0;
- a[4829]=0;
- a[4830]=0;
- a[4831]=0;
- a[4832]=0;
- a[4833]=0;
- a[4834]=0;
- a[4835]=0;
- a[4836]=0;
- a[4837]=0;
- a[4838]=0;
- a[4839]=0;
- a[4840]=0;
- a[4841]=0;
- a[4842]=0;
- a[4843]=0;
- a[4844]=0;
- a[4845]=0;
- a[4846]=0;
- a[4847]=0;
- a[4848]=0;
- a[4849]=0;
- a[4850]=0;
- a[4851]=0;
- a[4852]=0;
- a[4853]=0;
- a[4854]=0;
- a[4855]=0;
- a[4856]=0;
- a[4857]=0;
- a[4858]=0;
- a[4859]=0;
- a[4860]=0;
- a[4861]=0;
- a[4862]=0;
- a[4863]=0;
- a[4864]=0;
- a[4865]=0;
- a[4866]=0;
- a[4867]=0;
- a[4868]=0;
- a[4869]=0;
- a[4870]=0;
- a[4871]=0;
- a[4872]=0;
- a[4873]=0;
- a[4874]=0;
- a[4875]=0;
- a[4876]=0;
- a[4877]=0;
- a[4878]=0;
- a[4879]=0;
- a[4880]=0;
- a[4881]=0;
- a[4882]=0;
- a[4883]=0;
- a[4884]=0;
- a[4885]=0;
- a[4886]=0;
- a[4887]=0;
- a[4888]=0;
- a[4889]=0;
- a[4890]=0;
- a[4891]=0;
- a[4892]=0;
- a[4893]=0;
- a[4894]=0;
- a[4895]=0;
- a[4896]=0;
- a[4897]=0;
- a[4898]=0;
- a[4899]=0;
- a[4900]=0;
- a[4901]=0;
- a[4902]=0;
- a[4903]=0;
- a[4904]=0;
- a[4905]=0;
- a[4906]=0;
- a[4907]=0;
- a[4908]=0;
- a[4909]=0;
- a[4910]=0;
- a[4911]=0;
- a[4912]=0;
- a[4913]=0;
- a[4914]=0;
- a[4915]=0;
- a[4916]=0;
- a[4917]=0;
- a[4918]=0;
- a[4919]=0;
- a[4920]=0;
- a[4921]=0;
- a[4922]=0;
- a[4923]=0;
- a[4924]=0;
- a[4925]=0;
- a[4926]=0;
- a[4927]=0;
- a[4928]=0;
- a[4929]=0;
- a[4930]=0;
- a[4931]=0;
- a[4932]=0;
- a[4933]=0;
- a[4934]=0;
- a[4935]=0;
- a[4936]=0;
- a[4937]=0;
- a[4938]=0;
- a[4939]=0;
- a[4940]=0;
- a[4941]=0;
- a[4942]=0;
- a[4943]=0;
- a[4944]=0;
- a[4945]=0;
- a[4946]=0;
- a[4947]=0;
- a[4948]=0;
- a[4949]=0;
- a[4950]=0;
- a[4951]=0;
- a[4952]=0;
- a[4953]=0;
- a[4954]=0;
- a[4955]=0;
- a[4956]=0;
- a[4957]=0;
- a[4958]=0;
- a[4959]=0;
- a[4960]=0;
- a[4961]=0;
- a[4962]=0;
- a[4963]=0;
- a[4964]=0;
- a[4965]=0;
- a[4966]=0;
- a[4967]=0;
- a[4968]=0;
- a[4969]=0;
- a[4970]=0;
- a[4971]=0;
- a[4972]=0;
- a[4973]=0;
- a[4974]=0;
- a[4975]=0;
- a[4976]=0;
- a[4977]=0;
- a[4978]=0;
- a[4979]=0;
- a[4980]=0;
- a[4981]=0;
- a[4982]=0;
- a[4983]=0;
- a[4984]=0;
- a[4985]=0;
- a[4986]=0;
- a[4987]=0;
- a[4988]=0;
- a[4989]=0;
- a[4990]=0;
- a[4991]=0;
- a[4992]=0;
- a[4993]=0;
- a[4994]=0;
- a[4995]=0;
- a[4996]=0;
- a[4997]=0;
- a[4998]=0;
- a[4999]=0;
- return a;
-}
diff --git a/deps/v8/test/mjsunit/regress/regress-2119.js b/deps/v8/test/mjsunit/regress/regress-2119.js
new file mode 100644
index 000000000..54840c238
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2119.js
@@ -0,0 +1,36 @@
+// Copyright 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.
+
+// Flags: --nouse-ic
+
+function strict_function() {
+ "use strict"
+ undeclared = 1;
+}
+
+assertThrows(strict_function);
+
diff --git a/deps/v8/test/mjsunit/regress/regress-2172.js b/deps/v8/test/mjsunit/regress/regress-2172.js
new file mode 100644
index 000000000..5d06f4eef
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2172.js
@@ -0,0 +1,35 @@
+// Copyright 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.
+
+for (var i = 0; i < 10000; i++){
+ (i + "\0").split(/(.)\1/i);
+}
+
+for (var i = 0; i < 10000; i++){
+ (i + "\u1234\0").split(/(.)\1/i);
+}
+
diff --git a/deps/v8/test/mjsunit/regress/regress-2185-2.js b/deps/v8/test/mjsunit/regress/regress-2185-2.js
new file mode 100644
index 000000000..b1eedb933
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2185-2.js
@@ -0,0 +1,145 @@
+// Copyright 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.
+
+// These tests used to time out before this was fixed.
+
+var LEN = 2e4;
+
+function short() {
+ var sum = 0;
+ for (var i = 0; i < 1000; i++) {
+ var a = [1, 4, 34, 23, 6, 123, 3, 2, 11, 515, 4, 33, 22, 2, 2, 1, 0, 123,
+ 23, 42, 43, 1002, 44, 43, 101, 23, 55, 11, 101, 102, 45, 11, 404,
+ 31415, 34, 53, 453, 45, 34, 5, 2, 35, 5, 345, 36, 45, 345, 3, 45,
+ 3, 5, 5, 2, 2342344, 2234, 23, 2718, 1500, 2, 19, 22, 43, 41, 0,
+ -1, 33, 45, 78];
+ a.sort(function(a, b) { return a - b; });
+ sum += a[0];
+ }
+ return sum;
+}
+
+function short_bench(name, array) {
+ var start = new Date();
+ short();
+ var end = new Date();
+ var ms = end - start;
+ print("Short " + Math.floor(ms) + "ms");
+}
+
+function sawseq(a, tooth) {
+ var count = 0;
+ while (true) {
+ for (var i = 0; i < tooth; i++) {
+ a.push(i);
+ if (++count >= LEN) return a;
+ }
+ }
+}
+
+function sawseq2(a, tooth) {
+ var count = 0;
+ while (true) {
+ for (var i = 0; i < tooth; i++) {
+ a.push(i);
+ if (++count >= LEN) return a;
+ }
+ for (var i = 0; i < tooth; i++) {
+ a.push(tooth - i);
+ if (++count >= LEN) return a;
+ }
+ }
+}
+
+function sawseq3(a, tooth) {
+ var count = 0;
+ while (true) {
+ for (var i = 0; i < tooth; i++) {
+ a.push(tooth - i);
+ if (++count >= LEN) return a;
+ }
+ }
+}
+
+function up(a) {
+ for (var i = 0; i < LEN; i++) {
+ a.push(i);
+ }
+ return a;
+}
+
+function down(a) {
+ for (var i = 0; i < LEN; i++) {
+ a.push(LEN - i);
+ }
+ return a;
+}
+
+function ran(a) {
+ for (var i = 0; i < LEN; i++) {
+ a.push(Math.floor(Math.random() * LEN));
+ }
+ return a;
+}
+
+var random = ran([]);
+var asc = up([]);
+var desc = down([]);
+var asc_desc = down(up([]));
+var desc_asc = up(down([]));
+var asc_asc = up(up([]));
+var desc_desc = down(down([]));
+var saw1 = sawseq([], 1000);
+var saw2 = sawseq([], 500);
+var saw3 = sawseq([], 200);
+var saw4 = sawseq2([], 200);
+var saw5 = sawseq3([], 200);
+
+function bench(name, array) {
+ var start = new Date();
+ array.sort(function(a, b) { return a - b; });
+ var end = new Date();
+ for (var i = 0; i < array.length - 1; i++) {
+ if (array[i] > array[i + 1]) throw name + " " + i;
+ }
+ var ms = end - start;
+ print(name + " " + Math.floor(ms) + "ms");
+}
+
+short_bench();
+bench("random", random);
+bench("up", asc);
+bench("down", desc);
+bench("saw 1000", saw1);
+bench("saw 500", saw2);
+bench("saw 200", saw3);
+bench("saw 200 symmetric", saw4);
+bench("saw 200 down", saw4);
+bench("up, down", asc_desc);
+bench("up, up", asc_asc);
+bench("down, down", desc_desc);
+bench("down, up", desc_asc);
diff --git a/deps/v8/test/mjsunit/regress/regress-2185.js b/deps/v8/test/mjsunit/regress/regress-2185.js
new file mode 100644
index 000000000..895f322fc
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2185.js
@@ -0,0 +1,36 @@
+// Copyright 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.
+
+var a = [];
+
+for (var i = 0; i < 2; i++) {
+ for (var j = 0; j < 30000; j++) {
+ a.push(j);
+ }
+}
+
+a.sort(function(a, b) { return a - b; } );
diff --git a/deps/v8/test/mjsunit/regress/regress-2186.js b/deps/v8/test/mjsunit/regress/regress-2186.js
new file mode 100644
index 000000000..0921dcead
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2186.js
@@ -0,0 +1,49 @@
+// Copyright 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.
+
+// Flags: --harmony-collections
+
+function heapify(i) {
+ return 2.0 * (i / 2);
+}
+heapify(1);
+
+var ONE = 1;
+var ANOTHER_ONE = heapify(ONE);
+assertSame(ONE, ANOTHER_ONE);
+assertEquals("number", typeof ONE);
+assertEquals("number", typeof ANOTHER_ONE);
+
+var set = new Set;
+set.add(ONE);
+assertTrue(set.has(ONE));
+assertTrue(set.has(ANOTHER_ONE));
+
+var map = new Map;
+map.set(ONE, 23);
+assertSame(23, map.get(ONE));
+assertSame(23, map.get(ANOTHER_ONE));
diff --git a/deps/v8/test/mjsunit/regress/regress-2193.js b/deps/v8/test/mjsunit/regress/regress-2193.js
new file mode 100644
index 000000000..50509bfcb
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2193.js
@@ -0,0 +1,58 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax --cache-optimized-code
+
+function bozo() {};
+function MakeClosure() {
+ return function f(use_literals) {
+ if (use_literals) {
+ return [1,2,3,3,4,5,6,7,8,9,bozo];
+ } else {
+ return 0;
+ }
+ }
+}
+
+// Create two closures that share the same literal boilerplates.
+var closure1 = MakeClosure();
+var closure2 = MakeClosure();
+var expected = [1,2,3,3,4,5,6,7,8,9,bozo];
+
+// Make sure we generate optimized code for the first closure after
+// warming it up properly so that the literals boilerplate is generated
+// and the optimized code uses CreateArrayLiteralShallow runtime call.
+assertEquals(0, closure1(false));
+assertEquals(expected, closure1(true));
+%OptimizeFunctionOnNextCall(closure1);
+assertEquals(expected, closure1(true));
+
+// Optimize the second closure, which should reuse the optimized code
+// from the first closure with the same literal boilerplates.
+assertEquals(0, closure2(false));
+%OptimizeFunctionOnNextCall(closure2);
+assertEquals(expected, closure2(true));
diff --git a/deps/v8/test/mjsunit/regress/regress-2219.js b/deps/v8/test/mjsunit/regress/regress-2219.js
new file mode 100644
index 000000000..946c75bd8
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2219.js
@@ -0,0 +1,32 @@
+// Copyright 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.
+
+// Flags: --harmony-proxies --expose-gc
+
+var p = Proxy.create({getPropertyDescriptor: function() { gc() }});
+var o = Object.create(p);
+assertSame(23, o.x = 23);
diff --git a/deps/v8/test/mjsunit/regress/regress-2225.js b/deps/v8/test/mjsunit/regress/regress-2225.js
new file mode 100644
index 000000000..9957d8d46
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2225.js
@@ -0,0 +1,65 @@
+// Copyright 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.
+
+// Flags: --harmony-proxies
+
+var proxy_has_x = false;
+var proxy = Proxy.create({ getPropertyDescriptor:function(key) {
+ assertSame('x', key);
+ if (proxy_has_x) {
+ return { configurable:true, writable:false, value:19 };
+ }
+}});
+
+// Test __lookupGetter__/__lookupSetter__ with proxy.
+assertSame(undefined, Object.prototype.__lookupGetter__.call(proxy, 'foo'));
+assertSame(undefined, Object.prototype.__lookupSetter__.call(proxy, 'bar'));
+assertSame(undefined, Object.prototype.__lookupGetter__.call(proxy, '123'));
+assertSame(undefined, Object.prototype.__lookupSetter__.call(proxy, '456'));
+
+// Test __lookupGetter__/__lookupSetter__ with proxy in prototype chain.
+var object = Object.create(proxy);
+assertSame(undefined, Object.prototype.__lookupGetter__.call(object, 'foo'));
+assertSame(undefined, Object.prototype.__lookupSetter__.call(object, 'bar'));
+assertSame(undefined, Object.prototype.__lookupGetter__.call(object, '123'));
+assertSame(undefined, Object.prototype.__lookupSetter__.call(object, '456'));
+
+// Test inline constructors with proxy as prototype.
+function f() { this.x = 23; }
+f.prototype = proxy;
+proxy_has_x = false;
+assertSame(23, new f().x);
+proxy_has_x = true;
+assertSame(19, new f().x);
+
+// Test inline constructors with proxy in prototype chain.
+function g() { this.x = 42; }
+g.prototype.__proto__ = proxy;
+proxy_has_x = false;
+assertSame(42, new g().x);
+proxy_has_x = true;
+assertSame(19, new g().x);
diff --git a/deps/v8/test/mjsunit/regress/regress-2226.js b/deps/v8/test/mjsunit/regress/regress-2226.js
new file mode 100644
index 000000000..1ac3d3062
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2226.js
@@ -0,0 +1,36 @@
+// Copyright 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.
+
+var foo = function() { 0; /* foo function */ };
+var bar = function() { 1; /* bar function */ };
+var baz = function() { 2; /* baz function */ };
+
+var test = foo.test = bar.test = baz;
+
+assertEquals(baz, test);
+assertEquals(baz, foo.test);
+assertEquals(baz, bar.test);
diff --git a/deps/v8/test/mjsunit/regress/regress-2249.js b/deps/v8/test/mjsunit/regress/regress-2249.js
new file mode 100644
index 000000000..07d687d81
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2249.js
@@ -0,0 +1,33 @@
+// Copyright 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.
+
+// Flags: --gc-interval=10 --stress-compaction
+
+var o = {};
+o[Math.pow(2,30)-1] = 0;
+o[Math.pow(2,31)-1] = 0;
+o[1] = 0;
diff --git a/deps/v8/test/mjsunit/regress/regress-2250.js b/deps/v8/test/mjsunit/regress/regress-2250.js
new file mode 100644
index 000000000..b3b0db3fc
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2250.js
@@ -0,0 +1,68 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+// The original problem from the bug: In the example below SMI check for b
+// generated for inlining of equals invocation (marked with (*)) will be hoisted
+// out of the loop across the typeof b === "object" condition and cause an
+// immediate deopt. Another problem here is that no matter how many time we
+// deopt and reopt we will continue to produce the wrong code.
+//
+// The fix is to notice when a deopt and subsequent reopt doesn't find
+// additional type information, indicating that optimistic LICM should be
+// disabled during compilation.
+
+function eq(a, b) {
+ if (typeof b === "object") {
+ return b.equals(a); // (*)
+ }
+ return a === b;
+}
+
+Object.prototype.equals = function (other) {
+ return (this === other);
+};
+
+function test() {
+ for (var i = 0; !eq(i, 10); i++)
+ ;
+}
+
+eq({}, {});
+eq({}, {});
+eq(1, 1);
+eq(1, 1);
+test();
+%OptimizeFunctionOnNextCall(test);
+test();
+%OptimizeFunctionOnNextCall(test);
+// Second compilation should have noticed that LICM wasn't a good idea, and now
+// function should no longer deopt when called.
+test();
+assertTrue(2 != %GetOptimizationStatus(test));
+
diff --git a/deps/v8/test/mjsunit/regress/regress-2261.js b/deps/v8/test/mjsunit/regress/regress-2261.js
new file mode 100644
index 000000000..000e07de5
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2261.js
@@ -0,0 +1,113 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+// Test materialization of the arguments object when deoptimizing a
+// strict mode closure after modifying an argument.
+
+(function () {
+ var forceDeopt = 0;
+ function inner(x) {
+ "use strict";
+ x = 2;
+ // Do not remove this %DebugPrint as it makes sure the deopt happens
+ // after the assignment and is not hoisted above the assignment.
+ %DebugPrint(arguments[0]);
+ forceDeopt + 1;
+ return arguments[0];
+ }
+
+ assertEquals(1, inner(1));
+ assertEquals(1, inner(1));
+ %OptimizeFunctionOnNextCall(inner);
+ assertEquals(1, inner(1));
+ forceDeopt = "not a number";
+ assertEquals(1, inner(1));
+})();
+
+
+// Test materialization of the arguments object when deoptimizing an
+// inlined strict mode closure after modifying an argument.
+
+(function () {
+ var forceDeopt = 0;
+ function inner(x) {
+ "use strict";
+ x = 2;
+ // Do not remove this %DebugPrint as it makes sure the deopt happens
+ // after the assignment and is not hoisted above the assignment.
+ %DebugPrint(arguments[0]);
+ forceDeopt + 1;
+ return arguments[0];
+ }
+
+ function outer(x) {
+ return inner(x);
+ }
+
+ assertEquals(1, outer(1));
+ assertEquals(1, outer(1));
+ %OptimizeFunctionOnNextCall(outer);
+ assertEquals(1, outer(1));
+ forceDeopt = "not a number";
+ assertEquals(1, outer(1));
+})();
+
+
+// Test materialization of the multiple arguments objects when
+// deoptimizing several inlined closure after modifying an argument.
+
+(function () {
+ var forceDeopt = 0;
+ function inner(x,y,z) {
+ "use strict";
+ x = 3;
+ // Do not remove this %DebugPrint as it makes sure the deopt happens
+ // after the assignment and is not hoisted above the assignment.
+ %DebugPrint(arguments[0]);
+ forceDeopt + 1;
+ return arguments[0];
+ }
+
+ function middle(x) {
+ "use strict";
+ x = 2;
+ return inner(10*x, 20*x, 30*x) + arguments[0];
+ }
+
+ function outer(x) {
+ return middle(x);
+ }
+
+ assertEquals(21, outer(1));
+ assertEquals(21, outer(1));
+ %OptimizeFunctionOnNextCall(outer);
+ assertEquals(21, outer(1));
+ forceDeopt = "not a number";
+ assertEquals(21, outer(1));
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-2284.js b/deps/v8/test/mjsunit/regress/regress-2284.js
new file mode 100644
index 000000000..561401998
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2284.js
@@ -0,0 +1,32 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+assertThrows("%foobar();", TypeError);
+assertThrows("%constructor();", TypeError);
+assertThrows("%constructor(23);", TypeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-2285.js b/deps/v8/test/mjsunit/regress/regress-2285.js
new file mode 100644
index 000000000..efda4cde3
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2285.js
@@ -0,0 +1,32 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+assertThrows(function() { %_CallFunction(null, 0, ""); });
+assertThrows(function() { %_CallFunction(null, 0, 1); });
+
diff --git a/deps/v8/test/mjsunit/regress/regress-2286.js b/deps/v8/test/mjsunit/regress/regress-2286.js
new file mode 100644
index 000000000..372451ec4
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2286.js
@@ -0,0 +1,32 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+assertThrows("f()", ReferenceError);
+assertThrows("%f()", TypeError);
+assertThrows("%_f()", SyntaxError);
diff --git a/deps/v8/test/mjsunit/regress/regress-2289.js b/deps/v8/test/mjsunit/regress/regress-2289.js
new file mode 100644
index 000000000..e89ec6e14
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2289.js
@@ -0,0 +1,34 @@
+// Copyright 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.
+
+var foo = "a";
+for (var i = 0; i < 12; i++) foo += foo;
+foo = foo + 'b' + foo;
+
+foo.replace(/b/, "a");
+
+
diff --git a/deps/v8/test/mjsunit/regress/regress-2294.js b/deps/v8/test/mjsunit/regress/regress-2294.js
new file mode 100644
index 000000000..43ba10df0
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2294.js
@@ -0,0 +1,70 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+var clampedArray = new Uint8ClampedArray(10);
+
+function test() {
+ clampedArray[0] = 0.499;
+ assertEquals(0, clampedArray[0]);
+ clampedArray[0] = 0.5;
+ assertEquals(0, clampedArray[0]);
+ clampedArray[0] = 0.501;
+ assertEquals(1, clampedArray[0]);
+ clampedArray[0] = 1.499;
+ assertEquals(1, clampedArray[0]);
+ clampedArray[0] = 1.5;
+ assertEquals(2, clampedArray[0]);
+ clampedArray[0] = 1.501;
+ assertEquals(2, clampedArray[0]);
+ clampedArray[0] = 2.5;
+ assertEquals(2, clampedArray[0]);
+ clampedArray[0] = 3.5;
+ assertEquals(4, clampedArray[0]);
+ clampedArray[0] = 252.5;
+ assertEquals(252, clampedArray[0]);
+ clampedArray[0] = 253.5;
+ assertEquals(254, clampedArray[0]);
+ clampedArray[0] = 254.5;
+ assertEquals(254, clampedArray[0]);
+ clampedArray[0] = 256.5;
+ assertEquals(255, clampedArray[0]);
+ clampedArray[0] = -0.5;
+ assertEquals(0, clampedArray[0]);
+ clampedArray[0] = -1.5;
+ assertEquals(0, clampedArray[0]);
+ clampedArray[0] = 1000000000000;
+ assertEquals(255, clampedArray[0]);
+ clampedArray[0] = -1000000000000;
+ assertEquals(0, clampedArray[0]);
+}
+
+test();
+test();
+%OptimizeFunctionOnNextCall(test);
+test();
diff --git a/deps/v8/test/mjsunit/regress/regress-2296.js b/deps/v8/test/mjsunit/regress/regress-2296.js
new file mode 100644
index 000000000..c00f14f17
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2296.js
@@ -0,0 +1,40 @@
+// Copyright 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.
+
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug
+
+function listener(event, exec_state, event_data, data) {
+ event_data.script().setSource(1);
+};
+
+Debug.setListener(listener);
+
+eval('0');
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/regress/regress-2318.js b/deps/v8/test/mjsunit/regress/regress-2318.js
new file mode 100644
index 000000000..ca67ab2ca
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2318.js
@@ -0,0 +1,66 @@
+// Copyright 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.
+
+// Flags: --expose-debug-as debug --nostack-trace-on-abort
+
+function f() {
+ var i = 0;
+
+ // Stack-allocate to reach the end of stack quickly.
+ var _A0 = 00; var _A1 = 01; var _A2 = 02; var _A3 = 03; var _A4 = 04;
+ var _B0 = 05; var _B1 = 06; var _B2 = 07; var _B3 = 08; var _B4 = 09;
+ var _C0 = 10; var _C1 = 11; var _C2 = 12; var _C3 = 13; var _C4 = 14;
+ var _D0 = 15; var _D1 = 16; var _D2 = 17; var _D3 = 18; var _D4 = 19;
+ var _E0 = 20; var _E1 = 21; var _E2 = 22; var _E3 = 23; var _E4 = 24;
+ var _F0 = 25; var _F1 = 26; var _F2 = 27; var _F3 = 28; var _F4 = 29;
+ var _G0 = 30; var _G1 = 31; var _G2 = 32; var _G3 = 33; var _G4 = 34;
+ var _H0 = 35; var _H1 = 36; var _H2 = 37; var _H3 = 38; var _H4 = 39;
+ var _I0 = 40; var _I1 = 41; var _I2 = 42; var _I3 = 43; var _I4 = 44;
+ var _J0 = 45; var _J1 = 46; var _J2 = 47; var _J3 = 48; var _J4 = 49;
+ var _K0 = 50; var _K1 = 51; var _K2 = 52; var _K3 = 53; var _K4 = 54;
+ var _L0 = 55; var _L1 = 56; var _L2 = 57; var _L3 = 58; var _L4 = 59;
+ var _M0 = 60; var _M1 = 61; var _M2 = 62; var _M3 = 63; var _M4 = 64;
+ var _N0 = 65; var _N1 = 66; var _N2 = 67; var _N3 = 68; var _N4 = 69;
+ var _O0 = 70; var _O1 = 71; var _O2 = 72; var _O3 = 73; var _O4 = 74;
+ var _P0 = 75; var _P1 = 76; var _P2 = 77; var _P3 = 78; var _P4 = 79;
+ var _Q0 = 80; var _Q1 = 81; var _Q2 = 82; var _Q3 = 83; var _Q4 = 84;
+ var _R0 = 85; var _R1 = 86; var _R2 = 87; var _R3 = 88; var _R4 = 89;
+ var _S0 = 90; var _S1 = 91; var _S2 = 92; var _S3 = 93; var _S4 = 94;
+ var _T0 = 95; var _T1 = 96; var _T2 = 97; var _T3 = 98; var _T4 = 99;
+
+ f();
+};
+
+Debug = debug.Debug;
+var bp = Debug.setBreakPoint(f, 0);
+
+function listener(event, exec_state, event_data, data) {
+ result = exec_state.frame().evaluate("i").value();
+};
+
+Debug.setListener(listener);
+assertThrows(function() { f(); }, RangeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-2322.js b/deps/v8/test/mjsunit/regress/regress-2322.js
new file mode 100644
index 000000000..1195bab67
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2322.js
@@ -0,0 +1,36 @@
+// Copyright 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.
+
+// Flags: --harmony-scoping
+
+"use strict";
+
+assertThrows("'use strict'; for (let x in x);", ReferenceError);
+
+let s;
+for (let pppp in {}) {};
+assertThrows(function() { pppp = true }, ReferenceError);
diff --git a/deps/v8/test/mjsunit/regress/regress-2326.js b/deps/v8/test/mjsunit/regress/regress-2326.js
new file mode 100644
index 000000000..d2edf2b16
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2326.js
@@ -0,0 +1,54 @@
+// Copyright 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.
+
+// This tests that we do not share optimized code across closures that
+// were optimized using OSR (for a particular OSR entry AST id) even if
+// caching of optimized code kicks in.
+
+function makeClosure() {
+ function f(mode, iterations) {
+ var accumulator = 0;
+ if (mode == 1) {
+ while (--iterations > 0) accumulator = Math.ceil(accumulator);
+ return 1;
+ } else {
+ while (--iterations > 0) accumulator = Math.floor(accumulator);
+ return 2;
+ }
+ }
+ return f;
+}
+
+// Generate two closures sharing the same underlying function literal.
+var f1 = makeClosure();
+var f2 = makeClosure();
+
+// This function should be optimized via OSR in the first tight loop.
+assertSame(1, f1(1, 100000));
+
+// This function should be optimized via OSR in the second tight loop.
+assertSame(2, f2(2, 100000));
diff --git a/deps/v8/test/mjsunit/regress/regress-2336.js b/deps/v8/test/mjsunit/regress/regress-2336.js
new file mode 100644
index 000000000..edfff6021
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2336.js
@@ -0,0 +1,53 @@
+// Copyright 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.
+
+// Flags: --expose-debug-as debug --expose-gc
+
+// Check that we can cope with a debug listener that runs in the
+// GC epilogue and causes enough allocation to trigger a new GC during
+// the epilogue.
+
+var f = eval("(function f() { return 42; })");
+
+Debug = debug.Debug;
+
+var called = false;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.ScriptCollected) {
+ if (!called) {
+ called = true;
+ gc();
+ }
+ }
+};
+
+Debug.scripts();
+Debug.setListener(listener);
+f = void 0;
+gc();
+assertTrue(called);
diff --git a/deps/v8/test/mjsunit/regress/regress-2339.js b/deps/v8/test/mjsunit/regress/regress-2339.js
new file mode 100644
index 000000000..b16821dba
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2339.js
@@ -0,0 +1,59 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+/**
+ * The possible optimization states of a function. Must be in sync with the
+ * return values of Runtime_GetOptimizationStatus() in runtime.cc!
+ */
+
+var OptimizationState = {
+ YES: 1,
+ NO: 2,
+ ALWAYS: 3,
+ NEVER: 4
+};
+
+function simple() {
+ return simple_two_args(0, undefined);
+}
+
+function simple_two_args(always_zero, always_undefined) {
+ var always_five = always_undefined || 5;
+ return always_zero * always_five * .5;
+}
+
+
+simple();
+simple();
+%OptimizeFunctionOnNextCall(simple);
+simple();
+var raw_optimized = %GetOptimizationStatus(simple);
+assertFalse(raw_optimized == OptimizationState.NO);
+gc();
+
diff --git a/deps/v8/test/mjsunit/regress/regress-2346.js b/deps/v8/test/mjsunit/regress/regress-2346.js
new file mode 100644
index 000000000..4c88b3e28
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2346.js
@@ -0,0 +1,123 @@
+// Copyright 2010 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.
+
+// This file only tests very simple descriptors that always have
+// configurable, enumerable, and writable set to true.
+// A range of more elaborate tests are performed in
+// object-define-property.js
+
+// Flags: --stress-runs=5
+
+function get() { return x; }
+function set(x) { this.x = x; }
+
+var obj = {x: 1};
+obj.__defineGetter__("accessor", get);
+obj.__defineSetter__("accessor", set);
+var a = new Array();
+a[1] = 42;
+obj[1] = 42;
+
+var descIsData = Object.getOwnPropertyDescriptor(obj, 'x');
+assertTrue(descIsData.enumerable);
+assertTrue(descIsData.writable);
+assertTrue(descIsData.configurable);
+
+var descIsAccessor = Object.getOwnPropertyDescriptor(obj, 'accessor');
+assertTrue(descIsAccessor.enumerable);
+assertTrue(descIsAccessor.configurable);
+assertTrue(descIsAccessor.get == get);
+assertTrue(descIsAccessor.set == set);
+
+var descIsNotData = Object.getOwnPropertyDescriptor(obj, 'not-x');
+assertTrue(descIsNotData == undefined);
+
+var descIsNotAccessor = Object.getOwnPropertyDescriptor(obj, 'not-accessor');
+assertTrue(descIsNotAccessor == undefined);
+
+var descArray = Object.getOwnPropertyDescriptor(a, '1');
+assertTrue(descArray.enumerable);
+assertTrue(descArray.configurable);
+assertTrue(descArray.writable);
+assertEquals(descArray.value, 42);
+
+var descObjectElement = Object.getOwnPropertyDescriptor(obj, '1');
+assertTrue(descObjectElement.enumerable);
+assertTrue(descObjectElement.configurable);
+assertTrue(descObjectElement.writable);
+assertEquals(descObjectElement.value, 42);
+
+// String objects.
+var a = new String('foobar');
+for (var i = 0; i < a.length; i++) {
+ var descStringObject = Object.getOwnPropertyDescriptor(a, i);
+ assertTrue(descStringObject.enumerable);
+ assertFalse(descStringObject.configurable);
+ assertFalse(descStringObject.writable);
+ assertEquals(descStringObject.value, a.substring(i, i+1));
+}
+
+// Support for additional attributes on string objects.
+a.x = 42;
+a[10] = 'foo';
+var descStringProperty = Object.getOwnPropertyDescriptor(a, 'x');
+assertTrue(descStringProperty.enumerable);
+assertTrue(descStringProperty.configurable);
+assertTrue(descStringProperty.writable);
+assertEquals(descStringProperty.value, 42);
+
+var descStringElement = Object.getOwnPropertyDescriptor(a, '10');
+assertTrue(descStringElement.enumerable);
+assertTrue(descStringElement.configurable);
+assertTrue(descStringElement.writable);
+assertEquals(descStringElement.value, 'foo');
+
+// Test that elements in the prototype chain is not returned.
+var proto = {};
+proto[10] = 42;
+
+var objWithProto = new Array();
+objWithProto.prototype = proto;
+objWithProto[0] = 'bar';
+var descWithProto = Object.getOwnPropertyDescriptor(objWithProto, '10');
+assertEquals(undefined, descWithProto);
+
+// Test elements on global proxy object.
+var global = (function() { return this; })();
+
+global[42] = 42;
+
+function el_getter() { return 239; };
+function el_setter() {};
+Object.defineProperty(global, '239', {get: el_getter, set: el_setter});
+
+var descRegularElement = Object.getOwnPropertyDescriptor(global, '42');
+assertEquals(42, descRegularElement.value);
+
+var descAccessorElement = Object.getOwnPropertyDescriptor(global, '239');
+assertEquals(el_getter, descAccessorElement.get);
+assertEquals(el_setter, descAccessorElement.set);
diff --git a/deps/v8/test/mjsunit/regress/regress-2373.js b/deps/v8/test/mjsunit/regress/regress-2373.js
new file mode 100644
index 000000000..16a87ece6
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2373.js
@@ -0,0 +1,29 @@
+// Copyright 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.
+
+var o = JSON.parse('{"a":2600753951}');
+assertEquals(2600753951, o.a);
diff --git a/deps/v8/test/mjsunit/regress/regress-2374.js b/deps/v8/test/mjsunit/regress/regress-2374.js
new file mode 100644
index 000000000..b12e5f28c
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2374.js
@@ -0,0 +1,33 @@
+// Copyright 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.
+
+var msg = '{"result":{"profile":{"head":{"functionName":"(root)","url":"","lineNumber":0,"totalTime":495.7243772462511,"selfTime":0,"numberOfCalls":0,"visible":true,"callUID":2771605942,"children":[{"functionName":"(program)","url":"","lineNumber":0,"totalTime":495.7243772462511,"selfTime":495.7243772462511,"numberOfCalls":0,"visible":true,"callUID":1902715303,"children":[]}]},"bottomUpHead":{"functionName":"(root)","url":"","lineNumber":0,"totalTime":495.7243772462511,"selfTime":0,"numberOfCalls":0,"visible":true,"callUID":2771605942,"children":[{"functionName":"(program)","url":"","lineNumber":0,"totalTime":495.7243772462511,"selfTime":495.7243772462511,"numberOfCalls":0,"visible":true,"callUID":1902715303,"children":[]}]}}},"id":41}';
+
+var obj = JSON.parse(msg);
+var obj2 = JSON.parse(msg);
+
+assertEquals(JSON.stringify(obj), JSON.stringify(obj2));
diff --git a/deps/v8/test/mjsunit/regress/regress-builtin-array-op.js b/deps/v8/test/mjsunit/regress/regress-builtin-array-op.js
new file mode 100644
index 000000000..1e37af364
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-builtin-array-op.js
@@ -0,0 +1,38 @@
+// Copyright 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.
+
+// Test that we invoke the correct sort function in
+// array operations.
+
+var foo = "hest";
+Array.prototype.sort = function(fn) { foo = "fisk"; };
+Function.prototype.call = function() { foo = "caramel"; };
+var a = [2,3,1];
+a[100000] = 0;
+a.join();
+assertEquals("hest", foo);
+
diff --git a/deps/v8/test/mjsunit/regress/regress-cnlt-elements.js b/deps/v8/test/mjsunit/regress/regress-cnlt-elements.js
new file mode 100644
index 000000000..634534c53
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-cnlt-elements.js
@@ -0,0 +1,43 @@
+// Copyright 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.
+
+// Flags: --expose-gc
+
+var a = JSON.parse('{"b":1,"c":2,"d":3,"e":4}');
+var b = JSON.parse('{"12040200":1, "a":2, "b":2}');
+var c = JSON.parse('{"24050300":1}');
+b = null;
+gc();
+gc();
+c.a1 = 2;
+c.a2 = 2;
+c.a3 = 2;
+c.a4 = 2;
+c.a5 = 2;
+c.a6 = 2;
+c.a7 = 2;
+c.a8 = 2;
diff --git a/deps/v8/test/mjsunit/regress/regress-cnlt-enum-indices.js b/deps/v8/test/mjsunit/regress/regress-cnlt-enum-indices.js
new file mode 100644
index 000000000..03582bbbe
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-cnlt-enum-indices.js
@@ -0,0 +1,45 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+var o = {};
+var o2 = {};
+
+o.a = 1;
+o2.a = 1;
+function f() { return 10; }
+// Adds a non-field enumerable property.
+Object.defineProperty(o, "b", { get: f, enumerable: true });
+Object.defineProperty(o2, "b", { get: f, enumerable: true });
+assertTrue(%HaveSameMap(o, o2));
+o.c = 2;
+
+for (var x in o) { }
+o = null;
+
+gc();
diff --git a/deps/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js b/deps/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js
new file mode 100644
index 000000000..ee72fafc8
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js
@@ -0,0 +1,46 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+DontEnum = 2;
+
+var o = {};
+%SetProperty(o, "a", 0, DontEnum);
+
+var o2 = {};
+%SetProperty(o2, "a", 0, DontEnum);
+
+assertTrue(%HaveSameMap(o, o2));
+
+o.y = 2;
+
+for (var v in o) { print(v); }
+o = {};
+gc();
+
+for (var v in o2) { print(v); }
diff --git a/deps/v8/test/mjsunit/regress/regress-convert-enum.js b/deps/v8/test/mjsunit/regress/regress-convert-enum.js
new file mode 100644
index 000000000..c624cad5a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-convert-enum.js
@@ -0,0 +1,60 @@
+// Copyright 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.
+
+// Flags: --expose-gc
+
+// Create a transition tree A (no descriptors) -> B (descriptor for a) -> C
+// (descriptor for a and c), that all share the descriptor array [a,c]. C is the
+// owner of the descriptor array.
+var o = {};
+o.a = 1;
+o.c = 2;
+
+// Add a transition B -> D where D has its own descriptor array [a,b] where b is
+// a constant function.
+var o1 = {};
+o1.a = 1;
+
+// Install an enumeration cache in the descriptor array [a,c] at map B.
+for (var x in o1) { }
+o1.b = function() { return 1; };
+
+// Return ownership of the descriptor array [a,c] to B and trim it to [a].
+o = null;
+gc();
+
+// Convert the transition B -> D into a transition to B -> E so that E uses the
+// instance descriptors [a,b] with b being a field.
+var o2 = {};
+o2.a = 1;
+o2.b = 10;
+
+// Create an object with map B and iterate over it.
+var o3 = {};
+o3.a = 1;
+
+for (var y in o3) { }
diff --git a/deps/v8/test/mjsunit/regress/regress-convert-enum2.js b/deps/v8/test/mjsunit/regress/regress-convert-enum2.js
new file mode 100644
index 000000000..cdc7fbe2b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-convert-enum2.js
@@ -0,0 +1,46 @@
+// Copyright 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.
+
+var o = {};
+o.a = 1;
+o.b = function() { return 1; };
+o.d = 2;
+
+for (var x in o) { }
+
+var o1 = {};
+o1.a = 1;
+o1.b = 10;
+o1.c = 20;
+
+var keys = ["a", "b", "c"];
+
+var i = 0;
+for (var y in o1) {
+ assertEquals(keys[i], y);
+ i += 1;
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-convert-transition.js b/deps/v8/test/mjsunit/regress/regress-convert-transition.js
new file mode 100644
index 000000000..057dc8045
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-convert-transition.js
@@ -0,0 +1,40 @@
+// Copyright 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.
+
+var input = '{ "a1":1, "a2":1, "a3":1, "a4":1, "a5":1, "a6":1, "a7":1,\
+ "a8":1, "a9":1, "a10":1, "a11":1, "a12":1, "a13":1}';
+var a = JSON.parse(input);
+a.a = function() { return 10; };
+
+// Force conversion of field to slow mode.
+var b = JSON.parse(input);
+b.a = 10;
+
+// Add another property to the object that would transition to a.
+var c = JSON.parse(input);
+c.x = 10;
+assertEquals(undefined, c.a);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-119926.js b/deps/v8/test/mjsunit/regress/regress-crbug-119926.js
index 26b84fad7..1ad250a2b 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-119926.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-119926.js
@@ -25,9 +25,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --gc-global
+
// Test that array elements don't break upon garbage collection.
var a = new Array(500);
-for (var i = 0; i < 500000; i++) {
+for (var i = 0; i < 100000; i++) {
a[i] = new Object();
}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-125148.js b/deps/v8/test/mjsunit/regress/regress-crbug-125148.js
index 025f9a5a4..0f7bcd8ca 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-125148.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-125148.js
@@ -27,26 +27,64 @@
// Flags: --allow-natives-syntax
-var A = {
- foo: function() { assertUnreachable(); }
+function ToDictionaryMode(x) {
+ %OptimizeObjectForAddingMultipleProperties(x, 100);
}
-var B = {
- b: 2,
- foo: function() { return 1; }
-}
-B.__proto__ = A;
+var A, B, C;
-var C = {};
-C.__proto__ = B;
+// The initial bug report was about calling a know function...
+A = {};
+Object.defineProperty(A, "foo", { value: function() { assertUnreachable(); }});
-function bar(x) {
- return x.foo();
-}
+B = Object.create(A);
+Object.defineProperty(B, "foo", { value: function() { return 111; }});
-for (var i = 0; i < 3; i++) {
- assertEquals(1, bar(C));
-}
-%OptimizeObjectForAddingMultipleProperties(B, 100); // Force dictionary mode.
+C = Object.create(B);
+
+function bar(x) { return x.foo(); }
+
+assertEquals(111, bar(C));
+assertEquals(111, bar(C));
+ToDictionaryMode(B);
%OptimizeFunctionOnNextCall(bar);
-assertEquals(1, bar(C));
+assertEquals(111, bar(C));
+
+// Although this was not in the initial bug report: The same for getters...
+A = {};
+Object.defineProperty(A, "baz", { get: function() { assertUnreachable(); }});
+
+B = Object.create(A);
+Object.defineProperty(B, "baz", { get: function() { return 111; }});
+
+C = Object.create(B);
+
+function boo(x) { return x.baz; }
+
+assertEquals(111, boo(C));
+assertEquals(111, boo(C));
+ToDictionaryMode(B);
+%OptimizeFunctionOnNextCall(boo);
+assertEquals(111, boo(C));
+
+// And once more for setters...
+A = {};
+Object.defineProperty(A, "huh", { set: function(x) { assertUnreachable(); }});
+
+B = Object.create(A);
+var setterValue;
+Object.defineProperty(B, "huh", { set: function(x) { setterValue = x; }});
+
+C = Object.create(B);
+
+function fuu(x) {
+ setterValue = 222;
+ x.huh = 111;
+ return setterValue;
+}
+
+assertEquals(111, fuu(C));
+assertEquals(111, fuu(C));
+ToDictionaryMode(B);
+%OptimizeFunctionOnNextCall(fuu);
+assertEquals(111, fuu(C));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-134609.js b/deps/v8/test/mjsunit/regress/regress-crbug-134609.js
new file mode 100644
index 000000000..da7d85dcb
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-134609.js
@@ -0,0 +1,59 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax --inline-accessors
+
+var forceDeopt = {x:0};
+
+var objectWithGetterProperty = (function (value) {
+ var obj = {};
+ Object.defineProperty(obj, "getterProperty", {
+ get: function foo() {
+ forceDeopt.x;
+ return value;
+ },
+ });
+ return obj;
+})("bad");
+
+function test() {
+ var iAmContextAllocated = "good";
+ objectWithGetterProperty.getterProperty;
+ return iAmContextAllocated;
+
+ // Make sure that the local variable is context allocated.
+ function unused() { iAmContextAllocated; }
+}
+
+assertEquals("good", test());
+assertEquals("good", test());
+%OptimizeFunctionOnNextCall(test);
+assertEquals("good", test());
+
+// At this point, foo should have been inlined into test. Let's deopt...
+delete forceDeopt.x;
+assertEquals("good", test());
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-135008.js b/deps/v8/test/mjsunit/regress/regress-crbug-135008.js
new file mode 100644
index 000000000..2be396e80
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-135008.js
@@ -0,0 +1,45 @@
+// Copyright 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.
+
+// Filler long enough to trigger lazy parsing.
+var filler = "//" + new Array(1024).join('x');
+
+var scope = { x:23 };
+
+with(scope) {
+ eval(
+ "scope.f = (function outer() {" +
+ " function inner() {" +
+ " return x;" +
+ " }" +
+ " return inner;" +
+ "})();" +
+ filler
+ );
+};
+
+assertSame(23, scope.f());
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-135066.js b/deps/v8/test/mjsunit/regress/regress-crbug-135066.js
new file mode 100644
index 000000000..1aeca8b1a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-135066.js
@@ -0,0 +1,53 @@
+// Copyright 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.
+
+// Filler long enough to trigger lazy parsing.
+var filler = "//" + new Array(1024).join('x');
+
+// Test strict eval in global context.
+eval(
+ "'use strict';" +
+ "var x = 23;" +
+ "var f = function bozo1() {" +
+ " return x;" +
+ "};" +
+ "assertSame(23, f());" +
+ filler
+);
+
+// Test default eval in strict context.
+(function() {
+ "use strict";
+ eval(
+ "var y = 42;" +
+ "var g = function bozo2() {" +
+ " return y;" +
+ "};" +
+ "assertSame(42, g());" +
+ filler
+ );
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-137689.js b/deps/v8/test/mjsunit/regress/regress-crbug-137689.js
new file mode 100644
index 000000000..ef79d240f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-137689.js
@@ -0,0 +1,47 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+function getter() { return 10; }
+function setter(v) { }
+function getter2() { return 20; }
+
+var o = {};
+var o2 = {};
+
+Object.defineProperty(o, "foo", { get: getter, configurable: true });
+Object.defineProperty(o2, "foo", { get: getter, configurable: true });
+assertTrue(%HaveSameMap(o, o2));
+
+Object.defineProperty(o, "bar", { get: getter2 });
+Object.defineProperty(o2, "bar", { get: getter2 });
+assertTrue(%HaveSameMap(o, o2));
+
+Object.defineProperty(o, "foo", { set: setter, configurable: true });
+Object.defineProperty(o2, "foo", { set: setter, configurable: true });
+assertTrue(%HaveSameMap(o, o2));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-138887.js b/deps/v8/test/mjsunit/regress/regress-crbug-138887.js
new file mode 100644
index 000000000..8d8e1694b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-138887.js
@@ -0,0 +1,48 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+function worker1(ignored) {
+ return 100;
+}
+
+function factory(worker) {
+ return function(call_depth) {
+ if (call_depth == 0) return 10;
+ return 1 + worker(call_depth - 1);
+ }
+}
+
+var f1 = factory(worker1);
+var f2 = factory(f1);
+assertEquals(11, f2(1)); // Result: 1 + f1(0) == 1 + 10.
+assertEquals(11, f2(1));
+%OptimizeFunctionOnNextCall(f1);
+assertEquals(10, f1(0)); // Terminates immediately -> returns 10.
+%OptimizeFunctionOnNextCall(f2);
+assertEquals(102, f2(1000)); // 1 + f1(999) == 1 + 1 + worker1(998) == 102
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-140083.js b/deps/v8/test/mjsunit/regress/regress-crbug-140083.js
new file mode 100644
index 000000000..e38192cd8
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-140083.js
@@ -0,0 +1,44 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+// Test that the absence of a setter in a compound/count operation works.
+
+Object.defineProperty(Object.prototype, "foo",
+ { get: function() { return 123; } });
+
+function bar(o) {
+ o.foo += 42;
+ o.foo++;
+}
+
+var baz = {};
+bar(baz);
+bar(baz);
+%OptimizeFunctionOnNextCall(bar)
+bar(baz);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-142087.js b/deps/v8/test/mjsunit/regress/regress-crbug-142087.js
new file mode 100644
index 000000000..881ca60fb
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-142087.js
@@ -0,0 +1,38 @@
+// Copyright 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.
+
+var string = "What are you looking for?";
+
+var expected_match = [""];
+for (var i = 0; i < string.length; i++) {
+ expected_match.push("");
+}
+
+string.replace(/(_)|(_|)/g, "");
+assertArrayEquals(expected_match, string.match(/(_)|(_|)/g, ""));
+
+'***************************************'.match(/((\\)|(\*)|(\$))/g, ".");
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-142218.js b/deps/v8/test/mjsunit/regress/regress-crbug-142218.js
new file mode 100644
index 000000000..373f83bca
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-142218.js
@@ -0,0 +1,44 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+length = 1 << 16;
+a = new Array(length);
+
+function insert_element(key) {
+ a[key] = 42;
+}
+
+insert_element(1);
+%OptimizeFunctionOnNextCall(insert_element);
+insert_element(new Object());
+count = 0;
+for (var i = 0; i < length; i++) {
+ if (a[i] != undefined) count++;
+}
+assertEquals(1, count);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-145961.js b/deps/v8/test/mjsunit/regress/regress-crbug-145961.js
new file mode 100644
index 000000000..eb88945e0
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-145961.js
@@ -0,0 +1,39 @@
+// Copyright 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.
+
+// This test causes the operands to be passed in as Integer32 registers.
+// Flags: --allow-natives-syntax
+function test() {
+ var a = new Int32Array(2);
+ var x = a[0];
+ return Math.min(x, x);
+}
+
+assertEquals(0, test());
+assertEquals(0, test());
+%OptimizeFunctionOnNextCall(test);
+assertEquals(0, test());
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-146910.js b/deps/v8/test/mjsunit/regress/regress-crbug-146910.js
new file mode 100644
index 000000000..120f80973
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-146910.js
@@ -0,0 +1,38 @@
+// Copyright 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.
+
+var x = [];
+assertSame(0, x.length);
+assertSame(undefined, x[0]);
+
+Object.defineProperty(x, '0', { value: 7, configurable: false });
+assertSame(1, x.length);
+assertSame(7, x[0]);
+
+x.length = 0;
+assertSame(1, x.length);
+assertSame(7, x[0]);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-147475.js b/deps/v8/test/mjsunit/regress/regress-crbug-147475.js
new file mode 100644
index 000000000..180744c73
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-147475.js
@@ -0,0 +1,48 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+function worker1(ignored) {
+ return 100;
+}
+
+function factory(worker) {
+ return function(call_depth) {
+ if (call_depth == 0) return 10;
+ return 1 + worker(call_depth - 1);
+ }
+}
+
+var f1 = factory(worker1);
+var f2 = factory(f1);
+assertEquals(11, f2(1));
+%OptimizeFunctionOnNextCall(f1);
+assertEquals(10, f1(0));
+%OptimizeFunctionOnNextCall(f2);
+assertEquals(102, f2(2));
+assertEquals(102, f2(2));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-148376.js b/deps/v8/test/mjsunit/regress/regress-crbug-148376.js
new file mode 100644
index 000000000..55bb5f16f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-148376.js
@@ -0,0 +1,35 @@
+// Copyright 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.
+
+function defineSetter(o) {
+ o.__defineSetter__('property', function() {});
+}
+
+defineSetter(Object.prototype);
+property = 0;
+defineSetter(this);
+var keys = Object.keys(this);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-150545.js b/deps/v8/test/mjsunit/regress/regress-crbug-150545.js
new file mode 100644
index 000000000..68efdbf2d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-150545.js
@@ -0,0 +1,53 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+// Test that we do not generate OSR entry points that have an arguments
+// stack height different from zero. The OSR machinery cannot generate
+// frames for that.
+
+(function() {
+ "use strict";
+
+ var instantReturn = false;
+ function inner() {
+ if (instantReturn) return;
+ assertSame(3, arguments.length);
+ assertSame(1, arguments[0]);
+ assertSame(2, arguments[1]);
+ assertSame(3, arguments[2]);
+ }
+
+ function outer() {
+ inner(1,2,3);
+ // Trigger OSR.
+ while (%GetOptimizationStatus(outer) == 2) {}
+ }
+
+ outer();
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-150729.js b/deps/v8/test/mjsunit/regress/regress-crbug-150729.js
new file mode 100644
index 000000000..15aa587d1
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-150729.js
@@ -0,0 +1,39 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+var t = 0;
+function burn() {
+ i = [t, 1];
+ var M = [i[0], Math.cos(t) + i[7074959]];
+ t += .05;
+}
+for (var j = 0; j < 5; j++) {
+ if (j == 2) %OptimizeFunctionOnNextCall(burn);
+ burn();
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-debug-code-recompilation.js b/deps/v8/test/mjsunit/regress/regress-debug-code-recompilation.js
index 1a608b14a..4723ec130 100644
--- a/deps/v8/test/mjsunit/regress/regress-debug-code-recompilation.js
+++ b/deps/v8/test/mjsunit/regress/regress-debug-code-recompilation.js
@@ -25,7 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --hydrogen-filter=Debug.setBreakPoint --expose-debug-as debug
+// Flags: --allow-natives-syntax --hydrogen-filter=Debug.setBreakPoint
+// Flags: --expose-debug-as debug
Debug = debug.Debug
diff --git a/deps/v8/test/mjsunit/regress/regress-load-elements.js b/deps/v8/test/mjsunit/regress/regress-load-elements.js
new file mode 100644
index 000000000..68cdc8e8a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-load-elements.js
@@ -0,0 +1,49 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+function bad_func(o,a) {
+ for (var i = 0; i < 1; ++i) {
+ o.prop = 0;
+ var x = a[0];
+ }
+}
+
+o = new Object();
+a = {};
+a[0] = 1;
+bad_func(o, a);
+
+o = new Object();
+bad_func(o, a);
+
+// Optimize. Before the fix, the elements-load and subsequent fixed-array-length
+// were hoisted above the map check. This is invalid since not all types
+// necessarily have elements.
+%OptimizeFunctionOnNextCall(bad_func);
+bad_func(o, "");
diff --git a/deps/v8/test/mjsunit/regress/regress-undefined-store-keyed-fast-element.js b/deps/v8/test/mjsunit/regress/regress-undefined-store-keyed-fast-element.js
new file mode 100644
index 000000000..9e6ec9db0
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-undefined-store-keyed-fast-element.js
@@ -0,0 +1,37 @@
+// Copyright 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.
+
+// Flags: --allow-natives-syntax
+
+function f(v) {
+ return [0.0, 0.1, 0.2, v];
+}
+
+assertEquals([0.0, 0.1, 0.2, NaN], f(NaN));
+assertEquals([0.0, 0.1, 0.2, NaN], f(NaN));
+%OptimizeFunctionOnNextCall(f);
+assertEquals([0.0, 0.1, 0.2, undefined], f(undefined));
diff --git a/deps/v8/test/mjsunit/str-to-num.js b/deps/v8/test/mjsunit/str-to-num.js
index bbfa7d33a..cbec87fab 100644
--- a/deps/v8/test/mjsunit/str-to-num.js
+++ b/deps/v8/test/mjsunit/str-to-num.js
@@ -147,7 +147,6 @@ assertEquals(15, toNumber("0Xf"));
assertEquals(15, toNumber("0XF"));
assertEquals(0, toNumber("0x000"));
-assertEquals(-Infinity, 1 / toNumber("-0x000"));
assertEquals(0, toNumber("0x000" + repeat('0', 1000)));
assertEquals(9, toNumber("0x009"));
assertEquals(10, toNumber("0x00a"));
@@ -157,7 +156,6 @@ assertEquals(15, toNumber("0x00F"));
assertEquals(15, toNumber("0x00F "));
assertEquals(Infinity, toNumber("0x" + repeat('0', 1000) + '1'
+ repeat('0', 1000)));
-assertEquals(-Infinity, toNumber("-0x1" + repeat('0', 1000)));
assertEquals(0x1000000 * 0x10000000, toNumber("0x10000000000000"));
assertEquals(0x1000000 * 0x10000000 + 1, toNumber("0x10000000000001"));
@@ -207,3 +205,10 @@ assertTrue(isNaN(toNumber("1" + repeat('0', 1000) + 'junk')), "1e1000 junk");
for (var i = 1; i < 12; i++) {
assertEquals(toNumber('1' + repeat('0', i)), Math.pow(10.0, i));
}
+
+assertTrue(isNaN(toNumber("+0x0")));
+assertTrue(isNaN(toNumber("+0xFF")));
+assertTrue(isNaN(toNumber("+0x012")));
+assertTrue(isNaN(toNumber("-0x0")));
+assertTrue(isNaN(toNumber("-0xFF")));
+assertTrue(isNaN(toNumber("-0x012"))); \ No newline at end of file
diff --git a/deps/v8/test/mjsunit/string-charcodeat.js b/deps/v8/test/mjsunit/string-charcodeat.js
index 8be6a092e..72dc8190a 100644
--- a/deps/v8/test/mjsunit/string-charcodeat.js
+++ b/deps/v8/test/mjsunit/string-charcodeat.js
@@ -231,3 +231,6 @@ for (var i = 0; i < 5; i++) {
}
%OptimizeFunctionOnNextCall(directlyOnPrototype);
directlyOnPrototype();
+
+assertTrue(isNaN(%_StringCharCodeAt("ABC", -1)));
+assertTrue(isNaN(%_StringCharCodeAt("ABC", 4)));
diff --git a/deps/v8/test/mjsunit/testcfg.py b/deps/v8/test/mjsunit/testcfg.py
index 87ed4fae8..21139562e 100644
--- a/deps/v8/test/mjsunit/testcfg.py
+++ b/deps/v8/test/mjsunit/testcfg.py
@@ -25,17 +25,88 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import test
import os
-from os.path import join, dirname, exists
import re
-import tempfile
+
+from testrunner.local import testsuite
+from testrunner.objects import testcase
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
FILES_PATTERN = re.compile(r"//\s+Files:(.*)")
SELF_SCRIPT_PATTERN = re.compile(r"//\s+Env: TEST_FILE_NAME")
+class MjsunitTestSuite(testsuite.TestSuite):
+
+ def __init__(self, name, root):
+ super(MjsunitTestSuite, self).__init__(name, root)
+
+ def ListTests(self, context):
+ tests = []
+ for dirname, dirs, files in os.walk(self.root):
+ for dotted in [x for x in dirs if x.startswith('.')]:
+ dirs.remove(dotted)
+ dirs.sort()
+ files.sort()
+ for filename in files:
+ if filename.endswith(".js") and filename != "mjsunit.js":
+ testname = join(dirname[len(self.root) + 1:], filename[:-3])
+ test = testcase.TestCase(self, testname)
+ tests.append(test)
+ return tests
+
+ def GetFlagsForTestCase(self, testcase, context):
+ source = self.GetSourceForTest(testcase)
+ flags = []
+ flags_match = re.findall(FLAGS_PATTERN, source)
+ for match in flags_match:
+ flags += match.strip().split()
+ flags += context.mode_flags
+
+ files_list = [] # List of file names to append to command arguments.
+ files_match = FILES_PATTERN.search(source);
+ # Accept several lines of 'Files:'.
+ while True:
+ if files_match:
+ files_list += files_match.group(1).strip().split()
+ files_match = FILES_PATTERN.search(source, files_match.end())
+ else:
+ break
+ files = [ os.path.normpath(os.path.join(self.root, '..', '..', f))
+ for f in files_list ]
+ testfilename = os.path.join(self.root, testcase.path + self.suffix())
+ if SELF_SCRIPT_PATTERN.search(source):
+ env = ["-e", "TEST_FILE_NAME=\"%s\"" % testfilename]
+ files = env + files
+ files.append(os.path.join(self.root, "mjsunit.js"))
+ files.append(testfilename)
+
+ flags += files
+ if context.isolates:
+ flags.append("--isolate")
+ flags += files
+
+ return testcase.flags + flags
+
+ def GetSourceForTest(self, testcase):
+ filename = os.path.join(self.root, testcase.path + self.suffix())
+ with open(filename) as f:
+ return f.read()
+
+
+def GetSuite(name, root):
+ return MjsunitTestSuite(name, root)
+
+
+# Deprecated definitions below.
+# TODO(jkummerow): Remove when SCons is no longer supported.
+
+
+from os.path import dirname, exists, join, normpath
+import tempfile
+import test
+
+
class MjsunitTestCase(test.TestCase):
def __init__(self, path, file, mode, context, config, isolates):
@@ -56,9 +127,9 @@ class MjsunitTestCase(test.TestCase):
def GetVmCommand(self, source):
result = self.config.context.GetVmCommand(self, self.mode)
- flags_match = FLAGS_PATTERN.search(source)
- if flags_match:
- result += flags_match.group(1).strip().split()
+ flags_match = re.findall(FLAGS_PATTERN, source);
+ for match in flags_match:
+ result += match.strip().split()
return result
def GetVmArguments(self, source):
diff --git a/deps/v8/test/mjsunit/typed-array-slice.js b/deps/v8/test/mjsunit/typed-array-slice.js
new file mode 100644
index 000000000..c6e7e9415
--- /dev/null
+++ b/deps/v8/test/mjsunit/typed-array-slice.js
@@ -0,0 +1,61 @@
+// Copyright 2011 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.
+
+// Flags: --allow-natives-syntax
+
+// This is a regression test for overlapping key and value registers.
+
+var types = [Array, Int8Array, Uint8Array, Int16Array, Uint16Array,
+ Int32Array, Uint32Array, Uint8ClampedArray, Float32Array,
+ Float64Array];
+
+var results1 = [-2, -2, 254, -2, 65534, -2, 4294967294, 0, -2, -2];
+var results2 = [undefined, -1, 255, -1, 65535, -1, 4294967295, 0, -1, -1];
+var results3 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+var results4 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+
+const kElementCount = 40;
+
+function do_slice(a) {
+ return Array.prototype.slice.call(a, 4, 8);
+}
+
+for (var t = 0; t < types.length; t++) {
+ var type = types[t];
+ var a = new type(kElementCount);
+ for (var i = 0; i < kElementCount; ++i ) {
+ a[i] = i-6;
+ }
+ delete a[5];
+ var sliced = do_slice(a);
+
+ %ClearFunctionTypeFeedback(do_slice);
+ assertEquals(results1[t], sliced[0]);
+ assertEquals(results2[t], sliced[1]);
+ assertEquals(results3[t], sliced[2]);
+ assertEquals(results4[t], sliced[3]);
+}
diff --git a/deps/v8/test/mjsunit/unbox-double-arrays.js b/deps/v8/test/mjsunit/unbox-double-arrays.js
index ac039930c..5d061ae8c 100644
--- a/deps/v8/test/mjsunit/unbox-double-arrays.js
+++ b/deps/v8/test/mjsunit/unbox-double-arrays.js
@@ -28,6 +28,8 @@
// Test dictionary -> double elements -> dictionary elements round trip
// Flags: --allow-natives-syntax --unbox-double-arrays --expose-gc
+// Flags: --noparallel-recompilation
+
var large_array_size = 100000;
var approx_dict_to_elements_threshold = 70000;
diff --git a/deps/v8/test/mozilla/mozilla.status b/deps/v8/test/mozilla/mozilla.status
index 87d7bd290..4f2fbdea5 100644
--- a/deps/v8/test/mozilla/mozilla.status
+++ b/deps/v8/test/mozilla/mozilla.status
@@ -126,13 +126,13 @@ ecma/Date/15.9.2.2-5: PASS || FAIL
ecma/Date/15.9.2.2-6: PASS || FAIL
# 1026139: These date tests fail on arm and mips
-ecma/Date/15.9.5.29-1: PASS || FAIL if ($arch == arm || $arch == mips)
-ecma/Date/15.9.5.34-1: PASS || FAIL if ($arch == arm || $arch == mips)
-ecma/Date/15.9.5.28-1: PASS || FAIL if ($arch == arm || $arch == mips)
+ecma/Date/15.9.5.29-1: PASS || FAIL if ($arch == arm || $arch == mipsel)
+ecma/Date/15.9.5.34-1: PASS || FAIL if ($arch == arm || $arch == mipsel)
+ecma/Date/15.9.5.28-1: PASS || FAIL if ($arch == arm || $arch == mipsel)
# 1050186: Arm/MIPS vm is broken; probably unrelated to dates
-ecma/Array/15.4.4.5-3: PASS || FAIL if ($arch == arm || $arch == mips)
-ecma/Date/15.9.5.22-2: PASS || FAIL if ($arch == arm || $arch == mips)
+ecma/Array/15.4.4.5-3: PASS || FAIL if ($arch == arm || $arch == mipsel)
+ecma/Date/15.9.5.22-2: PASS || FAIL if ($arch == arm || $arch == mipsel)
# Flaky test that fails due to what appears to be a bug in the test.
# Occurs depending on current time
@@ -368,6 +368,10 @@ ecma/GlobalObject/15.1.2.6: FAIL_OK
ecma/GlobalObject/15.1.2.7: FAIL_OK
+# Leading zero no longer signal octal numbers (ECMA-262 Annex E 15.1.2.2).
+ecma/GlobalObject/15.1.2.2-2: FAIL_OK
+
+
# Tests that rely on specific details of function decompilation or
# print strings for errors. Non-ECMA behavior.
js1_2/function/tostring-2: FAIL_OK
@@ -603,6 +607,10 @@ ecma_2/RegExp/function-001: FAIL_OK
ecma_2/RegExp/properties-001: FAIL_OK
+# Negative hexadecimal literals are parsed as NaN. This test is outdated.
+ecma/TypeConversion/9.3.1-3: FAIL_OK
+
+
##################### FAILING TESTS #####################
# This section is for tests that fail in V8 and pass in JSC.
@@ -633,7 +641,7 @@ js1_5/Expressions/regress-394673: FAIL
# Bug 762: http://code.google.com/p/v8/issues/detail?id=762
# We do not correctly handle assignments within "with"
-/ecma_3/Statements/12.10-01: FAIL
+ecma_3/Statements/12.10-01: FAIL
# We do not throw an exception when a const is redeclared.
# (We only fail section 1 of the test.)
@@ -818,12 +826,6 @@ js1_5/decompilation/regress-383721: PASS || FAIL
js1_5/decompilation/regress-406555: PASS || FAIL
js1_5/decompilation/regress-460870: PASS || FAIL
-# These tests take an unreasonable amount of time so we skip them
-# in fast mode.
-
-js1_5/Regress/regress-312588: TIMEOUT || SKIP if $FAST == yes
-js1_5/Regress/regress-271716-n: PASS || SKIP if $FAST == yes
-
[ $arch == arm ]
@@ -848,40 +850,7 @@ js1_5/Regress/regress-451322: SKIP
js1_5/GC/regress-203278-2: PASS || TIMEOUT
-[ $fast == yes && $arch == arm ]
-
-# In fast mode on arm we try to skip all tests that would time out,
-# since running the tests takes so long in the first place.
-
-js1_5/Regress/regress-280769-2: SKIP
-js1_5/Regress/regress-280769-3: SKIP
-js1_5/Regress/regress-244470: SKIP
-js1_5/Regress/regress-203278-1: SKIP
-js1_5/Regress/regress-290575: SKIP
-js1_5/Regress/regress-159334: SKIP
-js1_5/Regress/regress-321971: SKIP
-js1_5/Regress/regress-347306-01: SKIP
-js1_5/Regress/regress-280769-1: SKIP
-js1_5/Regress/regress-280769-5: SKIP
-js1_5/GC/regress-306788: SKIP
-js1_5/GC/regress-278725: SKIP
-js1_5/GC/regress-203278-3: SKIP
-js1_5/GC/regress-311497: SKIP
-js1_5/Array/regress-99120-02: SKIP
-ecma/Date/15.9.5.22-1: SKIP
-ecma/Date/15.9.5.20: SKIP
-ecma/Date/15.9.5.12-2: SKIP
-ecma/Date/15.9.5.8: SKIP
-ecma/Date/15.9.5.9: SKIP
-ecma/Date/15.9.5.11-2: SKIP
-ecma/Expressions/11.7.2: SKIP
-ecma/Expressions/11.10-2: SKIP
-ecma/Expressions/11.7.3: SKIP
-ecma/Expressions/11.10-3: SKIP
-ecma/Expressions/11.7.1: SKIP
-ecma_3/RegExp/regress-209067: SKIP
-
-[ $arch == mips ]
+[ $arch == mipsel ]
# Times out and print so much output that we need to skip it to not
# hang the builder.
@@ -902,37 +871,3 @@ js1_5/Regress/regress-451322: SKIP
# BUG(1040): Allow this test to timeout.
js1_5/GC/regress-203278-2: PASS || TIMEOUT
-
-
-[ $fast == yes && $arch == mips ]
-
-# In fast mode on mips we try to skip all tests that would time out,
-# since running the tests takes so long in the first place.
-
-js1_5/Regress/regress-280769-2: SKIP
-js1_5/Regress/regress-280769-3: SKIP
-js1_5/Regress/regress-244470: SKIP
-js1_5/Regress/regress-203278-1: SKIP
-js1_5/Regress/regress-290575: SKIP
-js1_5/Regress/regress-159334: SKIP
-js1_5/Regress/regress-321971: SKIP
-js1_5/Regress/regress-347306-01: SKIP
-js1_5/Regress/regress-280769-1: SKIP
-js1_5/Regress/regress-280769-5: SKIP
-js1_5/GC/regress-306788: SKIP
-js1_5/GC/regress-278725: SKIP
-js1_5/GC/regress-203278-3: SKIP
-js1_5/GC/regress-311497: SKIP
-js1_5/Array/regress-99120-02: SKIP
-ecma/Date/15.9.5.22-1: SKIP
-ecma/Date/15.9.5.20: SKIP
-ecma/Date/15.9.5.12-2: SKIP
-ecma/Date/15.9.5.8: SKIP
-ecma/Date/15.9.5.9: SKIP
-ecma/Date/15.9.5.11-2: SKIP
-ecma/Expressions/11.7.2: SKIP
-ecma/Expressions/11.10-2: SKIP
-ecma/Expressions/11.7.3: SKIP
-ecma/Expressions/11.10-3: SKIP
-ecma/Expressions/11.7.1: SKIP
-ecma_3/RegExp/regress-209067: SKIP
diff --git a/deps/v8/test/mozilla/testcfg.py b/deps/v8/test/mozilla/testcfg.py
index e88164d22..5aeac4cc6 100644
--- a/deps/v8/test/mozilla/testcfg.py
+++ b/deps/v8/test/mozilla/testcfg.py
@@ -26,12 +26,19 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import test
import os
-from os.path import join, exists
+import shutil
+import subprocess
+import tarfile
+
+from testrunner.local import testsuite
+from testrunner.objects import testcase
+
+MOZILLA_VERSION = "2010-06-29"
-EXCLUDED = ['CVS']
+
+EXCLUDED = ["CVS"]
FRAMEWORK = """
@@ -54,6 +61,117 @@ TEST_DIRS = """
""".split()
+class MozillaTestSuite(testsuite.TestSuite):
+
+ def __init__(self, name, root):
+ super(MozillaTestSuite, self).__init__(name, root)
+ self.testroot = os.path.join(root, "data")
+
+ def ListTests(self, context):
+ tests = []
+ for testdir in TEST_DIRS:
+ current_root = os.path.join(self.testroot, testdir)
+ for dirname, dirs, files in os.walk(current_root):
+ for dotted in [x for x in dirs if x.startswith(".")]:
+ dirs.remove(dotted)
+ for excluded in EXCLUDED:
+ if excluded in dirs:
+ dirs.remove(excluded)
+ dirs.sort()
+ files.sort()
+ for filename in files:
+ if filename.endswith(".js") and not filename in FRAMEWORK:
+ testname = os.path.join(dirname[len(self.testroot) + 1:],
+ filename[:-3])
+ case = testcase.TestCase(self, testname)
+ tests.append(case)
+ return tests
+
+ def GetFlagsForTestCase(self, testcase, context):
+ result = []
+ result += context.mode_flags
+ result += ["--expose-gc"]
+ result += [os.path.join(self.root, "mozilla-shell-emulation.js")]
+ testfilename = testcase.path + ".js"
+ testfilepath = testfilename.split(os.path.sep)
+ for i in xrange(len(testfilepath)):
+ script = os.path.join(self.testroot,
+ reduce(os.path.join, testfilepath[:i], ""),
+ "shell.js")
+ if os.path.exists(script):
+ result.append(script)
+ result.append(os.path.join(self.testroot, testfilename))
+ return testcase.flags + result
+
+ def GetSourceForTest(self, testcase):
+ filename = join(self.testroot, testcase.path + ".js")
+ with open(filename) as f:
+ return f.read()
+
+ def IsNegativeTest(self, testcase):
+ return testcase.path.endswith("-n")
+
+ def IsFailureOutput(self, output, testpath):
+ if output.exit_code != 0:
+ return True
+ return "FAILED!" in output.stdout
+
+ def DownloadData(self):
+ old_cwd = os.getcwd()
+ os.chdir(os.path.abspath(self.root))
+
+ # Maybe we're still up to date?
+ versionfile = "CHECKED_OUT_VERSION"
+ checked_out_version = None
+ if os.path.exists(versionfile):
+ with open(versionfile) as f:
+ checked_out_version = f.read()
+ if checked_out_version == MOZILLA_VERSION:
+ os.chdir(old_cwd)
+ return
+
+ # If we have a local archive file with the test data, extract it.
+ directory_name = "data"
+ if os.path.exists(directory_name):
+ os.rename(directory_name, "data.old")
+ archive_file = "downloaded_%s.tar.gz" % MOZILLA_VERSION
+ if os.path.exists(archive_file):
+ with tarfile.open(archive_file, "r:gz") as tar:
+ tar.extractall()
+ with open(versionfile, "w") as f:
+ f.write(MOZILLA_VERSION)
+ os.chdir(old_cwd)
+ return
+
+ # No cached copy. Check out via CVS, and pack as .tar.gz for later use.
+ command = ("cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot"
+ " co -D %s mozilla/js/tests" % MOZILLA_VERSION)
+ code = subprocess.call(command, shell=True)
+ if code != 0:
+ os.chdir(old_cwd)
+ raise Exception("Error checking out Mozilla test suite!")
+ os.rename(join("mozilla", "js", "tests"), directory_name)
+ shutil.rmtree("mozilla")
+ with tarfile.open(archive_file, "w:gz") as tar:
+ tar.add("data")
+ with open(versionfile, "w") as f:
+ f.write(MOZILLA_VERSION)
+ os.chdir(old_cwd)
+
+
+def GetSuite(name, root):
+ return MozillaTestSuite(name, root)
+
+
+# Deprecated definitions below.
+# TODO(jkummerow): Remove when SCons is no longer supported.
+
+
+from os.path import exists
+from os.path import join
+import test
+
+
class MozillaTestCase(test.TestCase):
def __init__(self, filename, path, context, root, mode, framework):
diff --git a/deps/v8/test/preparser/preparser.status b/deps/v8/test/preparser/preparser.status
index 6f15fedd8..40c5caf74 100644
--- a/deps/v8/test/preparser/preparser.status
+++ b/deps/v8/test/preparser/preparser.status
@@ -31,3 +31,8 @@ prefix preparser
# escapes (we need to parse to distinguish octal escapes from valid
# back-references).
strict-octal-regexp: FAIL
+
+[ $arch == android_arm || $arch == android_ia32 ]
+# Remove this once the issue above is fixed. Android test runner does not
+# handle "FAIL" test expectation correctly.
+strict-octal-regexp: SKIP
diff --git a/deps/v8/test/preparser/strict-identifiers.pyt b/deps/v8/test/preparser/strict-identifiers.pyt
index aa3d5210d..f97908868 100644
--- a/deps/v8/test/preparser/strict-identifiers.pyt
+++ b/deps/v8/test/preparser/strict-identifiers.pyt
@@ -285,4 +285,4 @@ for reserved_word in reserved_words + strict_reserved_words:
# Future reserved words in strict mode behave like normal identifiers
# in a non strict context.
for reserved_word in strict_reserved_words:
- non_strict_use({"id": id}, None)
+ non_strict_use({"id": reserved_word}, None)
diff --git a/deps/v8/test/preparser/testcfg.py b/deps/v8/test/preparser/testcfg.py
index 88c06a31a..61c14c9bd 100644
--- a/deps/v8/test/preparser/testcfg.py
+++ b/deps/v8/test/preparser/testcfg.py
@@ -25,13 +25,109 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import test
+
import os
-from os.path import join, dirname, exists, isfile
-import platform
-import utils
import re
+from testrunner.local import testsuite
+from testrunner.local import utils
+from testrunner.objects import testcase
+
+
+class PreparserTestSuite(testsuite.TestSuite):
+ def __init__(self, name, root):
+ super(PreparserTestSuite, self).__init__(name, root)
+
+ def shell(self):
+ return "preparser"
+
+ def _GetExpectations(self):
+ expects_file = join(self.root, "preparser.expectation")
+ expectations_map = {}
+ if not os.path.exists(expects_file): return expectations_map
+ rule_regex = re.compile("^([\w\-]+)(?::([\w\-]+))?(?::(\d+),(\d+))?$")
+ for line in utils.ReadLinesFrom(expects_file):
+ rule_match = rule_regex.match(line)
+ if not rule_match: continue
+ expects = []
+ if (rule_match.group(2)):
+ expects += [rule_match.group(2)]
+ if (rule_match.group(3)):
+ expects += [rule_match.group(3), rule_match.group(4)]
+ expectations_map[rule_match.group(1)] = " ".join(expects)
+ return expectations_map
+
+ def _ParsePythonTestTemplates(self, result, filename):
+ pathname = join(self.root, filename + ".pyt")
+ def Test(name, source, expectation):
+ source = source.replace("\n", " ")
+ testname = os.path.join(filename, name)
+ flags = ["-e", source]
+ if expectation:
+ flags += ["throws", expectation]
+ test = testcase.TestCase(self, testname, flags=flags)
+ result.append(test)
+ def Template(name, source):
+ def MkTest(replacement, expectation):
+ testname = name
+ testsource = source
+ for key in replacement.keys():
+ testname = testname.replace("$" + key, replacement[key]);
+ testsource = testsource.replace("$" + key, replacement[key]);
+ Test(testname, testsource, expectation)
+ return MkTest
+ execfile(pathname, {"Test": Test, "Template": Template})
+
+ def ListTests(self, context):
+ expectations = self._GetExpectations()
+ result = []
+
+ # Find all .js files in this directory.
+ filenames = [f[:-3] for f in os.listdir(self.root) if f.endswith(".js")]
+ filenames.sort()
+ for f in filenames:
+ throws = expectations.get(f, None)
+ flags = [f + ".js"]
+ if throws:
+ flags += ["throws", throws]
+ test = testcase.TestCase(self, f, flags=flags)
+ result.append(test)
+
+ # Find all .pyt files in this directory.
+ filenames = [f[:-4] for f in os.listdir(self.root) if f.endswith(".pyt")]
+ filenames.sort()
+ for f in filenames:
+ self._ParsePythonTestTemplates(result, f)
+ return result
+
+ def GetFlagsForTestCase(self, testcase, context):
+ first = testcase.flags[0]
+ if first != "-e":
+ testcase.flags[0] = os.path.join(self.root, first)
+ return testcase.flags
+
+ def GetSourceForTest(self, testcase):
+ if testcase.flags[0] == "-e":
+ return testcase.flags[1]
+ with open(testcase.flags[0]) as f:
+ return f.read()
+
+ def VariantFlags(self):
+ return [[]];
+
+
+def GetSuite(name, root):
+ return PreparserTestSuite(name, root)
+
+
+# Deprecated definitions below.
+# TODO(jkummerow): Remove when SCons is no longer supported.
+
+
+from os.path import join, exists, isfile
+import test
+
+
class PreparserTestCase(test.TestCase):
def __init__(self, root, path, executable, mode, throws, context, source):
@@ -50,7 +146,7 @@ class PreparserTestCase(test.TestCase):
def HasSource(self):
return self.source is not None
- def GetSource():
+ def GetSource(self):
return self.source
def BuildCommand(self, path):
diff --git a/deps/v8/test/sputnik/sputnik.status b/deps/v8/test/sputnik/sputnik.status
index 52d126e65..67d1c75fe 100644
--- a/deps/v8/test/sputnik/sputnik.status
+++ b/deps/v8/test/sputnik/sputnik.status
@@ -216,7 +216,7 @@ S15.1.3.4_A2.3_T1: SKIP
S15.1.3.1_A2.5_T1: SKIP
S15.1.3.2_A2.5_T1: SKIP
-[ $arch == mips ]
+[ $arch == mipsel ]
# BUG(3251225): Tests that timeout with --nocrankshaft.
S15.1.3.1_A2.5_T1: SKIP
diff --git a/deps/v8/test/sputnik/testcfg.py b/deps/v8/test/sputnik/testcfg.py
index 1032c134f..b6f374667 100644
--- a/deps/v8/test/sputnik/testcfg.py
+++ b/deps/v8/test/sputnik/testcfg.py
@@ -33,6 +33,11 @@ import test
import time
+def GetSuite(name, root):
+ # Not implemented.
+ return None
+
+
class SputnikTestCase(test.TestCase):
def __init__(self, case, path, context, mode):
diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status
index 567a78ec8..06b43c717 100644
--- a/deps/v8/test/test262/test262.status
+++ b/deps/v8/test/test262/test262.status
@@ -41,10 +41,6 @@ S15.12.2_A1: FAIL
##################### DELIBERATE INCOMPATIBILITIES #####################
-# We deliberately treat arguments to parseInt() with a leading zero as
-# octal numbers in order to not break the web.
-S15.1.2.2_A5.1_T1: FAIL_OK
-
# This tests precision of Math.tan and Math.sin. The implementation for those
# trigonometric functions are platform/compiler dependent. Furthermore, the
# expectation values by far deviates from the actual result given by an
@@ -75,33 +71,19 @@ S15.9.3.1_A5_T6: PASS || FAIL_OK
############################ SKIPPED TESTS #############################
# These tests take a looong time to run in debug mode.
-S15.1.3.2_A2.5_T1: PASS, SKIP if $mode == debug
S15.1.3.1_A2.5_T1: PASS, SKIP if $mode == debug
+S15.1.3.2_A2.5_T1: PASS, SKIP if $mode == debug
-[ $arch == arm ]
+[ $arch == arm || $arch == mipsel ]
-# BUG(3251225): Tests that timeout with --nocrankshaft.
-S15.1.3.1_A2.5_T1: SKIP
-S15.1.3.2_A2.5_T1: SKIP
-S15.1.3.1_A2.4_T1: SKIP
-S15.1.3.1_A2.5_T1: SKIP
-S15.1.3.2_A2.4_T1: SKIP
-S15.1.3.2_A2.5_T1: SKIP
-S15.1.3.3_A2.3_T1: SKIP
-S15.1.3.4_A2.3_T1: SKIP
-S15.1.3.1_A2.5_T1: SKIP
-S15.1.3.2_A2.5_T1: SKIP
-
-[ $arch == mips ]
+# TODO(mstarzinger): Causes stack overflow on simulators due to eager
+# compilation of parenthesized function literals. Needs investigation.
+S13.2.1_A1_T1: SKIP
# BUG(3251225): Tests that timeout with --nocrankshaft.
-S15.1.3.1_A2.5_T1: SKIP
-S15.1.3.2_A2.5_T1: SKIP
S15.1.3.1_A2.4_T1: SKIP
S15.1.3.1_A2.5_T1: SKIP
S15.1.3.2_A2.4_T1: SKIP
S15.1.3.2_A2.5_T1: SKIP
S15.1.3.3_A2.3_T1: SKIP
S15.1.3.4_A2.3_T1: SKIP
-S15.1.3.1_A2.5_T1: SKIP
-S15.1.3.2_A2.5_T1: SKIP
diff --git a/deps/v8/test/test262/testcfg.py b/deps/v8/test/test262/testcfg.py
index c394cc8a5..875a4e5ed 100644
--- a/deps/v8/test/test262/testcfg.py
+++ b/deps/v8/test/test262/testcfg.py
@@ -26,19 +26,107 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import test
-import os
-from os.path import join, exists
-import urllib
import hashlib
+import os
import sys
import tarfile
+import urllib
+
+from testrunner.local import testsuite
+from testrunner.objects import testcase
+
+
+TEST_262_ARCHIVE_REVISION = "fb327c439e20" # This is the r334 revision.
+TEST_262_ARCHIVE_MD5 = "307acd166ec34629592f240dc12d57ed"
+TEST_262_URL = "http://hg.ecmascript.org/tests/test262/archive/%s.tar.bz2"
+TEST_262_HARNESS = ["sta.js"]
+
+
+class Test262TestSuite(testsuite.TestSuite):
+
+ def __init__(self, name, root):
+ super(Test262TestSuite, self).__init__(name, root)
+ self.testroot = os.path.join(root, "data", "test", "suite")
+ self.harness = [os.path.join(self.root, "data", "test", "harness", f)
+ for f in TEST_262_HARNESS]
+ self.harness += [os.path.join(self.root, "harness-adapt.js")]
+
+ def CommonTestName(self, testcase):
+ return testcase.path.split(os.path.sep)[-1]
+ def ListTests(self, context):
+ tests = []
+ for dirname, dirs, files in os.walk(self.testroot):
+ for dotted in [x for x in dirs if x.startswith(".")]:
+ dirs.remove(dotted)
+ dirs.sort()
+ files.sort()
+ for filename in files:
+ if filename.endswith(".js"):
+ testname = os.path.join(dirname[len(self.testroot) + 1:],
+ filename[:-3])
+ case = testcase.TestCase(self, testname)
+ tests.append(case)
+ return tests
+
+ def GetFlagsForTestCase(self, testcase, context):
+ return (testcase.flags + context.mode_flags + self.harness +
+ [os.path.join(self.testroot, testcase.path + ".js")])
+
+ def GetSourceForTest(self, testcase):
+ filename = os.path.join(self.testroot, testcase.path + ".js")
+ with open(filename) as f:
+ return f.read()
+
+ def IsNegativeTest(self, testcase):
+ return "@negative" in self.GetSourceForTest(testcase)
+
+ def IsFailureOutput(self, output, testpath):
+ if output.exit_code != 0:
+ return True
+ return "FAILED!" in output.stdout
-TEST_262_ARCHIVE_REVISION = 'fb327c439e20' # This is the r334 revision.
-TEST_262_ARCHIVE_MD5 = '307acd166ec34629592f240dc12d57ed'
-TEST_262_URL = 'http://hg.ecmascript.org/tests/test262/archive/%s.tar.bz2'
-TEST_262_HARNESS = ['sta.js']
+ def DownloadData(self):
+ revision = TEST_262_ARCHIVE_REVISION
+ archive_url = TEST_262_URL % revision
+ archive_name = os.path.join(self.root, "test262-%s.tar.bz2" % revision)
+ directory_name = os.path.join(self.root, "data")
+ directory_old_name = os.path.join(self.root, "data.old")
+ if not os.path.exists(archive_name):
+ print "Downloading test data from %s ..." % archive_url
+ urllib.urlretrieve(archive_url, archive_name)
+ if os.path.exists(directory_name):
+ os.rename(directory_name, directory_old_name)
+ if not os.path.exists(directory_name):
+ print "Extracting test262-%s.tar.bz2 ..." % revision
+ md5 = hashlib.md5()
+ with open(archive_name, "rb") as f:
+ for chunk in iter(lambda: f.read(8192), ""):
+ md5.update(chunk)
+ if md5.hexdigest() != TEST_262_ARCHIVE_MD5:
+ os.remove(archive_name)
+ raise Exception("Hash mismatch of test data file")
+ archive = tarfile.open(archive_name, "r:bz2")
+ if sys.platform in ("win32", "cygwin"):
+ # Magic incantation to allow longer path names on Windows.
+ archive.extractall(u"\\\\?\\%s" % self.root)
+ else:
+ archive.extractall(self.root)
+ os.rename(os.path.join(self.root, "test262-%s" % revision),
+ directory_name)
+
+
+def GetSuite(name, root):
+ return Test262TestSuite(name, root)
+
+
+# Deprecated definitions below.
+# TODO(jkummerow): Remove when SCons is no longer supported.
+
+
+from os.path import exists
+from os.path import join
+import test
class Test262TestCase(test.TestCase):
diff --git a/deps/v8/tools/android-build.sh b/deps/v8/tools/android-build.sh
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/deps/v8/tools/android-build.sh
diff --git a/deps/v8/tools/android-ll-prof.sh b/deps/v8/tools/android-ll-prof.sh
new file mode 100755
index 000000000..436f262bb
--- /dev/null
+++ b/deps/v8/tools/android-ll-prof.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+# Copyright 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.
+
+# Runs d8 with the given arguments on the device under 'perf' and
+# processes the profiler trace and v8 logs using ll_prof.py.
+#
+# Usage:
+# > ./tools/android-ll-prof.sh (debug|release) "args to d8" "args to ll_prof.py"
+#
+# The script creates deploy directory deploy/data/local/tmp/v8, copies there
+# the d8 binary either from out/android_arm.release or out/android_arm.debug,
+# and then sync the deploy directory with /data/local/tmp/v8 on the device.
+# You can put JS files in the deploy directory before running the script.
+# Note: $ANDROID_NDK_ROOT must be set.
+
+MODE=$1
+RUN_ARGS=$2
+LL_PROF_ARGS=$3
+
+BASE=`cd $(dirname "$0")/..; pwd`
+DEPLOY="$BASE/deploy"
+
+set +e
+mkdir -p "$DEPLOY/data/local/tmp/v8"
+
+cp "$BASE/out/android_arm.$MODE/d8" "$DEPLOY/data/local/tmp/v8/d8"
+
+adb -p "$DEPLOY" sync data
+
+adb shell "cd /data/local/tmp/v8;\
+ perf record -R -e cycles -c 10000 -f -i \
+ ./d8 --ll_prof --gc-fake-mmap=/data/local/tmp/__v8_gc__ $RUN_ARGS"
+
+adb pull /data/local/tmp/v8/v8.log .
+adb pull /data/local/tmp/v8/v8.log.ll .
+adb pull /data/perf.data .
+
+ARCH=arm-linux-androideabi-4.6
+TOOLCHAIN="${ANDROID_NDK_ROOT}/toolchains/$ARCH/prebuilt/linux-x86/bin"
+
+$BASE/tools/ll_prof.py --host-root="$BASE/deploy" \
+ --gc-fake-mmap=/data/local/tmp/__v8_gc__ \
+ --objdump="$TOOLCHAIN/arm-linux-androideabi-objdump" \
+ $LL_PROF_ARGS
diff --git a/deps/v8/tools/android-run.py b/deps/v8/tools/android-run.py
new file mode 100755
index 000000000..1693c5b06
--- /dev/null
+++ b/deps/v8/tools/android-run.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+#
+# Copyright 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.
+
+# This script executes the passed command line on Android device
+# using 'adb shell' command. Unfortunately, 'adb shell' always
+# returns exit code 0, ignoring the exit code of executed command.
+# Since we need to return non-zero exit code if the command failed,
+# we augment the passed command line with exit code checking statement
+# and output special error string in case of non-zero exit code.
+# Then we parse the output of 'adb shell' and look for that error string.
+
+import os
+from os.path import join, dirname, abspath
+import subprocess
+import sys
+import tempfile
+
+def Check(output, errors):
+ failed = any([s.startswith('/system/bin/sh:') or s.startswith('ANDROID')
+ for s in output.split('\n')])
+ return 1 if failed else 0
+
+def Execute(cmdline):
+ (fd_out, outname) = tempfile.mkstemp()
+ (fd_err, errname) = tempfile.mkstemp()
+ process = subprocess.Popen(
+ args=cmdline,
+ shell=True,
+ stdout=fd_out,
+ stderr=fd_err,
+ )
+ exit_code = process.wait()
+ os.close(fd_out)
+ os.close(fd_err)
+ output = file(outname).read()
+ errors = file(errname).read()
+ os.unlink(outname)
+ os.unlink(errname)
+ sys.stdout.write(output)
+ sys.stderr.write(errors)
+ return exit_code or Check(output, errors)
+
+def Escape(arg):
+ def ShouldEscape():
+ for x in arg:
+ if not x.isalnum() and x != '-' and x != '_':
+ return True
+ return False
+
+ return arg if not ShouldEscape() else '"%s"' % (arg.replace('"', '\\"'))
+
+def WriteToTemporaryFile(data):
+ (fd, fname) = tempfile.mkstemp()
+ os.close(fd)
+ tmp_file = open(fname, "w")
+ tmp_file.write(data)
+ tmp_file.close()
+ return fname
+
+def Main():
+ if (len(sys.argv) == 1):
+ print("Usage: %s <command-to-run-on-device>" % sys.argv[0])
+ return 1
+ workspace = abspath(join(dirname(sys.argv[0]), '..'))
+ android_workspace = os.getenv("ANDROID_V8", "/data/local/v8")
+ args = [Escape(arg) for arg in sys.argv[1:]]
+ script = (" ".join(args) + "\n"
+ "case $? in\n"
+ " 0) ;;\n"
+ " *) echo \"ANDROID: Error returned by test\";;\n"
+ "esac\n")
+ script = script.replace(workspace, android_workspace)
+ script_file = WriteToTemporaryFile(script)
+ android_script_file = android_workspace + "/" + script_file
+ command = ("adb push '%s' %s;" % (script_file, android_script_file) +
+ "adb shell 'sh %s';" % android_script_file +
+ "adb shell 'rm %s'" % android_script_file)
+ error_code = Execute(command)
+ os.unlink(script_file)
+ return error_code
+
+if __name__ == '__main__':
+ sys.exit(Main())
diff --git a/deps/v8/tools/android-sync.sh b/deps/v8/tools/android-sync.sh
new file mode 100755
index 000000000..5d4ef2eff
--- /dev/null
+++ b/deps/v8/tools/android-sync.sh
@@ -0,0 +1,105 @@
+#!/bin/bash
+# Copyright 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.
+
+# This script pushes android binaries and test data to the device.
+# The first argument can be either "android.release" or "android.debug".
+# The second argument is a relative path to the output directory with binaries.
+# The third argument is the absolute path to the V8 directory on the host.
+# The fourth argument is the absolute path to the V8 directory on the device.
+
+if [ ${#@} -lt 4 ] ; then
+ echo "$0: Error: need 4 arguments"
+ exit 1
+fi
+
+ARCH_MODE=$1
+OUTDIR=$2
+HOST_V8=$3
+ANDROID_V8=$4
+
+function LINUX_MD5 {
+ local HASH=$(md5sum $1)
+ echo ${HASH%% *}
+}
+
+function DARWIN_MD5 {
+ local HASH=$(md5 $1)
+ echo ${HASH} | cut -f2 -d "=" | cut -f2 -d " "
+}
+
+host_os=$(uname -s)
+case "${host_os}" in
+ "Linux")
+ MD5=LINUX_MD5
+ ;;
+ "Darwin")
+ MD5=DARWIN_MD5
+ ;;
+ *)
+ echo "$0: Host platform ${host_os} is not supported" >& 2
+ exit 1
+esac
+
+function sync_file {
+ local FILE=$1
+ local ANDROID_HASH=$(adb shell "md5 \"$ANDROID_V8/$FILE\"")
+ local HOST_HASH=$($MD5 "$HOST_V8/$FILE")
+ if [ "${ANDROID_HASH%% *}" != "${HOST_HASH}" ]; then
+ adb push "$HOST_V8/$FILE" "$ANDROID_V8/$FILE" &> /dev/null
+ fi
+ echo -n "."
+}
+
+function sync_dir {
+ local DIR=$1
+ echo -n "sync to $ANDROID_V8/$DIR"
+ for FILE in $(find "$HOST_V8/$DIR" -not -path "*.svn*" -type f); do
+ local RELATIVE_FILE=${FILE:${#HOST_V8}}
+ sync_file "$RELATIVE_FILE"
+ done
+ echo ""
+}
+
+echo -n "sync to $ANDROID_V8/$OUTDIR/$ARCH_MODE"
+sync_file "$OUTDIR/$ARCH_MODE/cctest"
+sync_file "$OUTDIR/$ARCH_MODE/d8"
+sync_file "$OUTDIR/$ARCH_MODE/preparser"
+echo ""
+echo -n "sync to $ANDROID_V8/tools"
+sync_file tools/consarray.js
+sync_file tools/codemap.js
+sync_file tools/csvparser.js
+sync_file tools/profile.js
+sync_file tools/splaytree.js
+sync_file tools/profile_view.js
+sync_file tools/logreader.js
+sync_file tools/tickprocessor.js
+echo ""
+sync_dir test/message
+sync_dir test/mjsunit
+sync_dir test/preparser
diff --git a/deps/v8/tools/bash-completion.sh b/deps/v8/tools/bash-completion.sh
index 9f65c6773..9f65c6773 100644..100755
--- a/deps/v8/tools/bash-completion.sh
+++ b/deps/v8/tools/bash-completion.sh
diff --git a/deps/v8/tools/check-static-initializers.sh b/deps/v8/tools/check-static-initializers.sh
index 1103a9778..1103a9778 100644..100755
--- a/deps/v8/tools/check-static-initializers.sh
+++ b/deps/v8/tools/check-static-initializers.sh
diff --git a/deps/v8/tools/common-includes.sh b/deps/v8/tools/common-includes.sh
index 2b806caa5..7785e9fc3 100644
--- a/deps/v8/tools/common-includes.sh
+++ b/deps/v8/tools/common-includes.sh
@@ -36,9 +36,7 @@ TEMP_BRANCH=$BRANCHNAME-temporary-branch-created-by-script
VERSION_FILE="src/version.cc"
CHANGELOG_ENTRY_FILE="$PERSISTFILE_BASENAME-changelog-entry"
PATCH_FILE="$PERSISTFILE_BASENAME-patch"
-PATCH_OUTPUT_FILE="$PERSISTFILE_BASENAME-patch-output"
COMMITMSG_FILE="$PERSISTFILE_BASENAME-commitmsg"
-TOUCHED_FILES_FILE="$PERSISTFILE_BASENAME-touched-files"
TRUNK_REVISION_FILE="$PERSISTFILE_BASENAME-trunkrevision"
START_STEP=0
CURRENT_STEP=0
@@ -180,26 +178,21 @@ the uploaded CL."
done
}
-# Takes a file containing the patch to apply as first argument.
-apply_patch() {
- patch $REVERSE_PATCH -p1 < "$1" > "$PATCH_OUTPUT_FILE" || \
- { cat "$PATCH_OUTPUT_FILE" && die "Applying the patch failed."; }
- tee < "$PATCH_OUTPUT_FILE" >(grep "patching file" \
- | awk '{print $NF}' >> "$TOUCHED_FILES_FILE")
- rm "$PATCH_OUTPUT_FILE"
+wait_for_resolving_conflicts() {
+ echo "Applying the patch \"$1\" failed. Either type \"ABORT<Return>\", or \
+resolve the conflicts, stage *all* touched files with 'git add', and \
+type \"RESOLVED<Return>\""
+ unset ANSWER
+ while [ "$ANSWER" != "RESOLVED" ] ; do
+ [[ "$ANSWER" == "ABORT" ]] && die "Applying the patch failed."
+ [[ -n "$ANSWER" ]] && echo "That was not 'RESOLVED' or 'ABORT'."
+ echo -n "> "
+ read ANSWER
+ done
}
-stage_files() {
- # Stage added and modified files.
- TOUCHED_FILES=$(cat "$TOUCHED_FILES_FILE")
- for FILE in $TOUCHED_FILES ; do
- git add "$FILE"
- done
- # Stage deleted files.
- DELETED_FILES=$(git status -s -uno --porcelain | grep "^ D" \
- | awk '{print $NF}')
- for FILE in $DELETED_FILES ; do
- git rm "$FILE"
- done
- rm -f "$TOUCHED_FILES_FILE"
+# Takes a file containing the patch to apply as first argument.
+apply_patch() {
+ git apply --index --reject $REVERSE_PATCH "$1" || \
+ wait_for_resolving_conflicts "$1";
}
diff --git a/deps/v8/tools/fuzz-harness.sh b/deps/v8/tools/fuzz-harness.sh
index efbf8646c..efbf8646c 100644..100755
--- a/deps/v8/tools/fuzz-harness.sh
+++ b/deps/v8/tools/fuzz-harness.sh
diff --git a/deps/v8/tools/gen-postmortem-metadata.py b/deps/v8/tools/gen-postmortem-metadata.py
index f59cfd303..7bee763bc 100644
--- a/deps/v8/tools/gen-postmortem-metadata.py
+++ b/deps/v8/tools/gen-postmortem-metadata.py
@@ -76,16 +76,23 @@ consts_misc = [
{ 'name': 'SmiTag', 'value': 'kSmiTag' },
{ 'name': 'SmiTagMask', 'value': 'kSmiTagMask' },
{ 'name': 'SmiValueShift', 'value': 'kSmiTagSize' },
+ { 'name': 'SmiShiftSize', 'value': 'kSmiShiftSize' },
{ 'name': 'PointerSizeLog2', 'value': 'kPointerSizeLog2' },
- { 'name': 'prop_idx_transitions',
- 'value': 'DescriptorArray::kTransitionsIndex' },
+ { 'name': 'prop_desc_key',
+ 'value': 'DescriptorArray::kDescriptorKey' },
+ { 'name': 'prop_desc_details',
+ 'value': 'DescriptorArray::kDescriptorDetails' },
+ { 'name': 'prop_desc_value',
+ 'value': 'DescriptorArray::kDescriptorValue' },
+ { 'name': 'prop_desc_size',
+ 'value': 'DescriptorArray::kDescriptorSize' },
{ 'name': 'prop_idx_first',
'value': 'DescriptorArray::kFirstIndex' },
{ 'name': 'prop_type_field',
'value': 'FIELD' },
{ 'name': 'prop_type_first_phantom',
- 'value': 'MAP_TRANSITION' },
+ 'value': 'Code::MAP_TRANSITION' },
{ 'name': 'prop_type_mask',
'value': 'PropertyDetails::TypeField::kMask' },
@@ -107,7 +114,7 @@ extras_accessors = [
'JSObject, elements, Object, kElementsOffset',
'FixedArray, data, uintptr_t, kHeaderSize',
'Map, instance_attributes, int, kInstanceAttributesOffset',
- 'Map, instance_descriptors, int, kInstanceDescriptorsOrBitField3Offset',
+ 'Map, transitions, uintptr_t, kTransitionsOrBackPointerOffset',
'Map, inobject_properties, int, kInObjectPropertiesOffset',
'Map, instance_size, int, kInstanceSizeOffset',
'HeapNumber, value, double, kValueOffset',
diff --git a/deps/v8/tools/grokdump.py b/deps/v8/tools/grokdump.py
index a9f0cb9dd..46ead5e46 100755
--- a/deps/v8/tools/grokdump.py
+++ b/deps/v8/tools/grokdump.py
@@ -27,17 +27,18 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import bisect
import cmd
+import codecs
import ctypes
+import disasm
import mmap
import optparse
import os
-import disasm
-import sys
-import types
-import codecs
import re
import struct
+import sys
+import types
USAGE="""usage: %prog [OPTIONS] [DUMP-FILE]
@@ -180,6 +181,11 @@ MINIDUMP_LOCATION_DESCRIPTOR = Descriptor([
("rva", ctypes.c_uint32)
])
+MINIDUMP_STRING = Descriptor([
+ ("length", ctypes.c_uint32),
+ ("buffer", lambda t: ctypes.c_uint8 * (t.length + 2))
+])
+
MINIDUMP_DIRECTORY = Descriptor([
("stream_type", ctypes.c_uint32),
("location", MINIDUMP_LOCATION_DESCRIPTOR.ctype)
@@ -400,6 +406,24 @@ MINIDUMP_THREAD_LIST = Descriptor([
("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count)
])
+MINIDUMP_RAW_MODULE = Descriptor([
+ ("base_of_image", ctypes.c_uint64),
+ ("size_of_image", ctypes.c_uint32),
+ ("checksum", ctypes.c_uint32),
+ ("time_date_stamp", ctypes.c_uint32),
+ ("module_name_rva", ctypes.c_uint32),
+ ("version_info", ctypes.c_uint32 * 13),
+ ("cv_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype),
+ ("misc_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype),
+ ("reserved0", ctypes.c_uint32 * 2),
+ ("reserved1", ctypes.c_uint32 * 2)
+])
+
+MINIDUMP_MODULE_LIST = Descriptor([
+ ("number_of_modules", ctypes.c_uint32),
+ ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules)
+])
+
MINIDUMP_RAW_SYSTEM_INFO = Descriptor([
("processor_architecture", ctypes.c_uint16)
])
@@ -407,6 +431,20 @@ MINIDUMP_RAW_SYSTEM_INFO = Descriptor([
MD_CPU_ARCHITECTURE_X86 = 0
MD_CPU_ARCHITECTURE_AMD64 = 9
+class FuncSymbol:
+ def __init__(self, start, size, name):
+ self.start = start
+ self.end = self.start + size
+ self.name = name
+
+ def __cmp__(self, other):
+ if isinstance(other, FuncSymbol):
+ return self.start - other.start
+ return self.start - other
+
+ def Covers(self, addr):
+ return (self.start <= addr) and (addr < self.end)
+
class MinidumpReader(object):
"""Minidump (.dmp) reader."""
@@ -430,8 +468,13 @@ class MinidumpReader(object):
self.exception_context = None
self.memory_list = None
self.memory_list64 = None
+ self.module_list = None
self.thread_map = {}
+ self.symdir = options.symdir
+ self.modules_with_symbols = []
+ self.symbols = []
+
# Find MDRawSystemInfo stream and determine arch.
for d in directories:
if d.stream_type == MD_SYSTEM_INFO_STREAM:
@@ -461,6 +504,11 @@ class MinidumpReader(object):
for thread in thread_list.threads:
DebugPrint(thread)
self.thread_map[thread.id] = thread
+ elif d.stream_type == MD_MODULE_LIST_STREAM:
+ assert self.module_list is None
+ self.module_list = MINIDUMP_MODULE_LIST.Read(
+ self.minidump, d.location.rva)
+ assert ctypes.sizeof(self.module_list) == d.location.data_size
elif d.stream_type == MD_MEMORY_LIST_STREAM:
print >>sys.stderr, "Warning: This is not a full minidump!"
assert self.memory_list is None
@@ -644,6 +692,66 @@ class MinidumpReader(object):
def Register(self, name):
return self.exception_context.__getattribute__(name)
+ def ReadMinidumpString(self, rva):
+ string = bytearray(MINIDUMP_STRING.Read(self.minidump, rva).buffer)
+ string = string.decode("utf16")
+ return string[0:len(string) - 1]
+
+ # Load FUNC records from a BreakPad symbol file
+ #
+ # http://code.google.com/p/google-breakpad/wiki/SymbolFiles
+ #
+ def _LoadSymbolsFrom(self, symfile, baseaddr):
+ print "Loading symbols from %s" % (symfile)
+ funcs = []
+ with open(symfile) as f:
+ for line in f:
+ result = re.match(
+ r"^FUNC ([a-f0-9]+) ([a-f0-9]+) ([a-f0-9]+) (.*)$", line)
+ if result is not None:
+ start = int(result.group(1), 16)
+ size = int(result.group(2), 16)
+ name = result.group(4).rstrip()
+ bisect.insort_left(self.symbols,
+ FuncSymbol(baseaddr + start, size, name))
+ print " ... done"
+
+ def TryLoadSymbolsFor(self, modulename, module):
+ try:
+ symfile = os.path.join(self.symdir,
+ modulename.replace('.', '_') + ".pdb.sym")
+ self._LoadSymbolsFrom(symfile, module.base_of_image)
+ self.modules_with_symbols.append(module)
+ except Exception as e:
+ print " ... failure (%s)" % (e)
+
+ # Returns true if address is covered by some module that has loaded symbols.
+ def _IsInModuleWithSymbols(self, addr):
+ for module in self.modules_with_symbols:
+ start = module.base_of_image
+ end = start + module.size_of_image
+ if (start <= addr) and (addr < end):
+ return True
+ return False
+
+ # Find symbol covering the given address and return its name in format
+ # <symbol name>+<offset from the start>
+ def FindSymbol(self, addr):
+ if not self._IsInModuleWithSymbols(addr):
+ return None
+
+ i = bisect.bisect_left(self.symbols, addr)
+ symbol = None
+ if (0 < i) and self.symbols[i - 1].Covers(addr):
+ symbol = self.symbols[i - 1]
+ elif (i < len(self.symbols)) and self.symbols[i].Covers(addr):
+ symbol = self.symbols[i]
+ else:
+ return None
+ diff = addr - symbol.start
+ return "%s+0x%x" % (symbol.name, diff)
+
+
# List of V8 instance types. Obtained by adding the code below to any .cc file.
#
@@ -1051,12 +1159,30 @@ class ConsString(String):
class Oddball(HeapObject):
+ # Should match declarations in objects.h
+ KINDS = [
+ "False",
+ "True",
+ "TheHole",
+ "Null",
+ "ArgumentMarker",
+ "Undefined",
+ "Other"
+ ]
+
def ToStringOffset(self):
return self.heap.PointerSize()
+ def ToNumberOffset(self):
+ return self.ToStringOffset() + self.heap.PointerSize()
+
+ def KindOffset(self):
+ return self.ToNumberOffset() + self.heap.PointerSize()
+
def __init__(self, heap, map, address):
HeapObject.__init__(self, heap, map, address)
self.to_string = self.ObjectField(self.ToStringOffset())
+ self.kind = self.SmiField(self.KindOffset())
def Print(self, p):
p.Print(str(self))
@@ -1065,7 +1191,10 @@ class Oddball(HeapObject):
if self.to_string:
return "Oddball(%08x, <%s>)" % (self.address, self.to_string.GetChars())
else:
- return "Oddball(%08x, kind=%s)" % (self.address, "???")
+ kind = "???"
+ if 0 <= self.kind < len(Oddball.KINDS):
+ kind = Oddball.KINDS[self.kind]
+ return "Oddball(%08x, kind=%s)" % (self.address, kind)
class FixedArray(HeapObject):
@@ -1086,7 +1215,13 @@ class FixedArray(HeapObject):
base_offset = self.ElementsOffset()
for i in xrange(self.length):
offset = base_offset + 4 * i
- p.Print("[%08d] = %s" % (i, self.ObjectField(offset)))
+ try:
+ p.Print("[%08d] = %s" % (i, self.ObjectField(offset)))
+ except TypeError:
+ p.Dedent()
+ p.Print("...")
+ p.Print("}")
+ return
p.Dedent()
p.Print("}")
@@ -1394,7 +1529,7 @@ class InspectionPadawan(object):
if known_map:
return known_map
found_obj = self.heap.FindObject(tagged_address)
- if found_obj: return found_ob
+ if found_obj: return found_obj
address = tagged_address - 1
if self.reader.IsValidAddress(address):
map_tagged_address = self.reader.ReadUIntPtr(address)
@@ -1451,6 +1586,24 @@ class InspectionShell(cmd.Cmd):
self.padawan = InspectionPadawan(reader, heap)
self.prompt = "(grok) "
+ def do_da(self, address):
+ """
+ Print ASCII string starting at specified address.
+ """
+ address = int(address, 16)
+ string = ""
+ while self.reader.IsValidAddress(address):
+ code = self.reader.ReadU8(address)
+ if code < 128:
+ string += chr(code)
+ else:
+ break
+ address += 1
+ if string == "":
+ print "Not an ASCII string at %s" % self.reader.FormatIntPtr(address)
+ else:
+ print "%s\n" % string
+
def do_dd(self, address):
"""
Interpret memory at the given address (if available) as a sequence
@@ -1510,23 +1663,23 @@ class InspectionShell(cmd.Cmd):
"""
self.padawan.PrintKnowledge()
- def do_km(self, address):
+ def do_kd(self, address):
"""
Teach V8 heap layout information to the inspector. Set the first
- map-space page by passing any pointer into that page.
+ data-space page by passing any pointer into that page.
"""
address = int(address, 16)
page_address = address & ~self.heap.PageAlignmentMask()
- self.padawan.known_first_map_page = page_address
+ self.padawan.known_first_data_page = page_address
- def do_kd(self, address):
+ def do_km(self, address):
"""
Teach V8 heap layout information to the inspector. Set the first
- data-space page by passing any pointer into that page.
+ map-space page by passing any pointer into that page.
"""
address = int(address, 16)
page_address = address & ~self.heap.PageAlignmentMask()
- self.padawan.known_first_data_page = page_address
+ self.padawan.known_first_map_page = page_address
def do_kp(self, address):
"""
@@ -1537,6 +1690,17 @@ class InspectionShell(cmd.Cmd):
page_address = address & ~self.heap.PageAlignmentMask()
self.padawan.known_first_pointer_page = page_address
+ def do_list(self, smth):
+ """
+ List all available memory regions.
+ """
+ def print_region(reader, start, size, location):
+ print " %s - %s (%d bytes)" % (reader.FormatIntPtr(start),
+ reader.FormatIntPtr(start + size),
+ size)
+ print "Available memory regions:"
+ self.reader.ForEachMemoryRegion(print_region)
+
def do_s(self, word):
"""
Search for a given word in available memory regions. The given word
@@ -1560,27 +1724,34 @@ class InspectionShell(cmd.Cmd):
"""
raise NotImplementedError
- def do_list(self, smth):
+ def do_u(self, args):
"""
- List all available memory regions.
+ u 0x<address> 0x<size>
+ Unassemble memory in the region [address, address + size)
"""
- def print_region(reader, start, size, location):
- print " %s - %s (%d bytes)" % (reader.FormatIntPtr(start),
- reader.FormatIntPtr(start + size),
- size)
- print "Available memory regions:"
- self.reader.ForEachMemoryRegion(print_region)
-
+ args = args.split(' ')
+ start = int(args[0], 16)
+ size = int(args[1], 16)
+ lines = self.reader.GetDisasmLines(start, size)
+ for line in lines:
+ print FormatDisasmLine(start, self.heap, line)
+ print
EIP_PROXIMITY = 64
CONTEXT_FOR_ARCH = {
MD_CPU_ARCHITECTURE_AMD64:
- ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip'],
+ ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip',
+ 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15'],
MD_CPU_ARCHITECTURE_X86:
['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip']
}
+KNOWN_MODULES = {'chrome.exe', 'chrome.dll'}
+
+def GetModuleName(reader, module):
+ name = reader.ReadMinidumpString(module.module_name_rva)
+ return str(os.path.basename(str(name).replace("\\", "/")))
def AnalyzeMinidump(options, minidump_name):
reader = MinidumpReader(options, minidump_name)
@@ -1599,6 +1770,13 @@ def AnalyzeMinidump(options, minidump_name):
# TODO(vitalyr): decode eflags.
print " eflags: %s" % bin(reader.exception_context.eflags)[2:]
print
+ print " modules:"
+ for module in reader.module_list.modules:
+ name = GetModuleName(reader, module)
+ if name in KNOWN_MODULES:
+ print " %s at %08X" % (name, module.base_of_image)
+ reader.TryLoadSymbolsFor(name, module)
+ print
stack_top = reader.ExceptionSP()
stack_bottom = exception_thread.stack.start + \
@@ -1611,6 +1789,9 @@ def AnalyzeMinidump(options, minidump_name):
heap = V8Heap(reader, stack_map)
print "Disassembly around exception.eip:"
+ eip_symbol = reader.FindSymbol(reader.ExceptionIP())
+ if eip_symbol is not None:
+ print eip_symbol
disasm_start = reader.ExceptionIP() - EIP_PROXIMITY
disasm_bytes = 2 * EIP_PROXIMITY
if (options.full):
@@ -1639,8 +1820,10 @@ def AnalyzeMinidump(options, minidump_name):
for slot in xrange(stack_top, stack_bottom, reader.PointerSize()):
maybe_address = reader.ReadUIntPtr(slot)
heap_object = heap.FindObject(maybe_address)
- print "%s: %s" % (reader.FormatIntPtr(slot),
- reader.FormatIntPtr(maybe_address))
+ maybe_symbol = reader.FindSymbol(maybe_address)
+ print "%s: %s %s" % (reader.FormatIntPtr(slot),
+ reader.FormatIntPtr(maybe_address),
+ maybe_symbol or "")
if heap_object:
heap_object.Print(Printer())
print
@@ -1654,6 +1837,8 @@ if __name__ == "__main__":
help="start an interactive inspector shell")
parser.add_option("-f", "--full", dest="full", action="store_true",
help="dump all information contained in the minidump")
+ parser.add_option("--symdir", dest="symdir", default=".",
+ help="directory containing *.pdb.sym file with symbols")
options, args = parser.parse_args()
if len(args) != 1:
parser.print_help()
diff --git a/deps/v8/tools/gyp/v8.gyp b/deps/v8/tools/gyp/v8.gyp
index ea82d3181..7a54ef4fc 100644
--- a/deps/v8/tools/gyp/v8.gyp
+++ b/deps/v8/tools/gyp/v8.gyp
@@ -234,10 +234,10 @@
'../../src/ast.h',
'../../src/atomicops.h',
'../../src/atomicops_internals_x86_gcc.cc',
- '../../src/bignum.cc',
- '../../src/bignum.h',
'../../src/bignum-dtoa.cc',
'../../src/bignum-dtoa.h',
+ '../../src/bignum.cc',
+ '../../src/bignum.h',
'../../src/bootstrapper.cc',
'../../src/bootstrapper.h',
'../../src/builtins.cc',
@@ -268,21 +268,21 @@
'../../src/conversions.h',
'../../src/counters.cc',
'../../src/counters.h',
- '../../src/cpu.h',
'../../src/cpu-profiler-inl.h',
'../../src/cpu-profiler.cc',
'../../src/cpu-profiler.h',
+ '../../src/cpu.h',
'../../src/data-flow.cc',
'../../src/data-flow.h',
'../../src/date.cc',
'../../src/date.h',
+ '../../src/dateparser-inl.h',
'../../src/dateparser.cc',
'../../src/dateparser.h',
- '../../src/dateparser-inl.h',
- '../../src/debug.cc',
- '../../src/debug.h',
'../../src/debug-agent.cc',
'../../src/debug-agent.h',
+ '../../src/debug.cc',
+ '../../src/debug.h',
'../../src/deoptimizer.cc',
'../../src/deoptimizer.h',
'../../src/disasm.h',
@@ -293,19 +293,25 @@
'../../src/double.h',
'../../src/dtoa.cc',
'../../src/dtoa.h',
- '../../src/elements.cc',
- '../../src/elements.h',
'../../src/elements-kind.cc',
'../../src/elements-kind.h',
+ '../../src/elements.cc',
+ '../../src/elements.h',
'../../src/execution.cc',
'../../src/execution.h',
+ '../../src/extensions/externalize-string-extension.cc',
+ '../../src/extensions/externalize-string-extension.h',
+ '../../src/extensions/gc-extension.cc',
+ '../../src/extensions/gc-extension.h',
+ '../../src/extensions/statistics-extension.cc',
+ '../../src/extensions/statistics-extension.h',
'../../src/factory.cc',
'../../src/factory.h',
'../../src/fast-dtoa.cc',
'../../src/fast-dtoa.h',
- '../../src/flag-definitions.h',
'../../src/fixed-dtoa.cc',
'../../src/fixed-dtoa.h',
+ '../../src/flag-definitions.h',
'../../src/flags.cc',
'../../src/flags.h',
'../../src/frames-inl.h',
@@ -315,6 +321,8 @@
'../../src/full-codegen.h',
'../../src/func-name-inferrer.cc',
'../../src/func-name-inferrer.h',
+ '../../src/gdb-jit.cc',
+ '../../src/gdb-jit.h',
'../../src/global-handles.cc',
'../../src/global-handles.h',
'../../src/globals.h',
@@ -323,14 +331,14 @@
'../../src/handles.h',
'../../src/hashmap.h',
'../../src/heap-inl.h',
- '../../src/heap.cc',
- '../../src/heap.h',
'../../src/heap-profiler.cc',
'../../src/heap-profiler.h',
- '../../src/hydrogen.cc',
- '../../src/hydrogen.h',
+ '../../src/heap.cc',
+ '../../src/heap.h',
'../../src/hydrogen-instructions.cc',
'../../src/hydrogen-instructions.h',
+ '../../src/hydrogen.cc',
+ '../../src/hydrogen.h',
'../../src/ic-inl.h',
'../../src/ic.cc',
'../../src/ic.h',
@@ -342,19 +350,19 @@
'../../src/interface.h',
'../../src/interpreter-irregexp.cc',
'../../src/interpreter-irregexp.h',
+ '../../src/isolate.cc',
+ '../../src/isolate.h',
'../../src/json-parser.h',
'../../src/jsregexp.cc',
'../../src/jsregexp.h',
- '../../src/isolate.cc',
- '../../src/isolate.h',
'../../src/lazy-instance.h',
'../../src/list-inl.h',
'../../src/list.h',
- '../../src/lithium.cc',
- '../../src/lithium.h',
+ '../../src/lithium-allocator-inl.h',
'../../src/lithium-allocator.cc',
'../../src/lithium-allocator.h',
- '../../src/lithium-allocator-inl.h',
+ '../../src/lithium.cc',
+ '../../src/lithium.h',
'../../src/liveedit.cc',
'../../src/liveedit.h',
'../../src/liveobjectlist-inl.h',
@@ -372,14 +380,16 @@
'../../src/messages.h',
'../../src/natives.h',
'../../src/objects-debug.cc',
- '../../src/objects-printer.cc',
'../../src/objects-inl.h',
+ '../../src/objects-printer.cc',
'../../src/objects-visiting.cc',
'../../src/objects-visiting.h',
'../../src/objects.cc',
'../../src/objects.h',
'../../src/once.cc',
'../../src/once.h',
+ '../../src/optimizing-compiler-thread.h',
+ '../../src/optimizing-compiler-thread.cc',
'../../src/parser.cc',
'../../src/parser.h',
'../../src/platform-posix.h',
@@ -394,12 +404,12 @@
'../../src/preparser.h',
'../../src/prettyprinter.cc',
'../../src/prettyprinter.h',
- '../../src/property.cc',
- '../../src/property.h',
- '../../src/property-details.h',
'../../src/profile-generator-inl.h',
'../../src/profile-generator.cc',
'../../src/profile-generator.h',
+ '../../src/property-details.h',
+ '../../src/property.cc',
+ '../../src/property.h',
'../../src/regexp-macro-assembler-irregexp-inl.h',
'../../src/regexp-macro-assembler-irregexp.cc',
'../../src/regexp-macro-assembler-irregexp.h',
@@ -411,16 +421,16 @@
'../../src/regexp-stack.h',
'../../src/rewriter.cc',
'../../src/rewriter.h',
- '../../src/runtime.cc',
- '../../src/runtime.h',
'../../src/runtime-profiler.cc',
'../../src/runtime-profiler.h',
+ '../../src/runtime.cc',
+ '../../src/runtime.h',
'../../src/safepoint-table.cc',
'../../src/safepoint-table.h',
- '../../src/scanner.cc',
- '../../src/scanner.h',
'../../src/scanner-character-streams.cc',
'../../src/scanner-character-streams.h',
+ '../../src/scanner.cc',
+ '../../src/scanner.h',
'../../src/scopeinfo.cc',
'../../src/scopeinfo.h',
'../../src/scopes.cc',
@@ -428,7 +438,7 @@
'../../src/serialize.cc',
'../../src/serialize.h',
'../../src/small-pointer-list.h',
- '../../src/smart-array-pointer.h',
+ '../../src/smart-pointers.h',
'../../src/snapshot-common.cc',
'../../src/snapshot.h',
'../../src/spaces-inl.h',
@@ -447,6 +457,9 @@
'../../src/stub-cache.h',
'../../src/token.cc',
'../../src/token.h',
+ '../../src/transitions-inl.h',
+ '../../src/transitions.cc',
+ '../../src/transitions.h',
'../../src/type-info.cc',
'../../src/type-info.h',
'../../src/unbound-queue-inl.h',
@@ -479,10 +492,6 @@
'../../src/zone-inl.h',
'../../src/zone.cc',
'../../src/zone.h',
- '../../src/extensions/externalize-string-extension.cc',
- '../../src/extensions/externalize-string-extension.h',
- '../../src/extensions/gc-extension.cc',
- '../../src/extensions/gc-extension.h',
],
'conditions': [
['want_separate_host_toolset==1', {
@@ -555,7 +564,7 @@
'../../src/ia32/stub-cache-ia32.cc',
],
}],
- ['v8_target_arch=="mips"', {
+ ['v8_target_arch=="mipsel"', {
'sources': [
'../../src/mips/assembler-mips.cc',
'../../src/mips/assembler-mips.h',
diff --git a/deps/v8/tools/linux-tick-processor b/deps/v8/tools/linux-tick-processor
index 7070ce6fc..93f143f9a 100755
--- a/deps/v8/tools/linux-tick-processor
+++ b/deps/v8/tools/linux-tick-processor
@@ -12,21 +12,21 @@ done
tools_path=`cd $(dirname "$0");pwd`
if [ ! "$D8_PATH" ]; then
d8_public=`which d8`
- if [ -x $d8_public ]; then D8_PATH=$(dirname "$d8_public"); fi
+ if [ -x "$d8_public" ]; then D8_PATH=$(dirname "$d8_public"); fi
fi
-[ "$D8_PATH" ] || D8_PATH=$tools_path/..
+[ -n "$D8_PATH" ] || D8_PATH=$tools_path/..
d8_exec=$D8_PATH/d8
-if [ ! -x $d8_exec ]; then
+if [ ! -x "$d8_exec" ]; then
D8_PATH=`pwd`/out/native
d8_exec=$D8_PATH/d8
fi
-if [ ! -x $d8_exec ]; then
+if [ ! -x "$d8_exec" ]; then
d8_exec=`grep -m 1 -o '".*/d8"' $log_file | sed 's/"//g'`
fi
-if [ ! -x $d8_exec ]; then
+if [ ! -x "$d8_exec" ]; then
echo "d8 shell not found in $D8_PATH"
echo "To build, execute 'make native' from the V8 directory"
exit 1
diff --git a/deps/v8/tools/ll_prof.py b/deps/v8/tools/ll_prof.py
index 51ba672ac..3afe179d2 100755
--- a/deps/v8/tools/ll_prof.py
+++ b/deps/v8/tools/ll_prof.py
@@ -68,15 +68,9 @@ Examples:
"""
-# Must match kGcFakeMmap.
-V8_GC_FAKE_MMAP = "/tmp/__v8_gc__"
-
JS_ORIGIN = "js"
JS_SNAPSHOT_ORIGIN = "js-snapshot"
-OBJDUMP_BIN = disasm.OBJDUMP_BIN
-
-
class Code(object):
"""Code object."""
@@ -639,7 +633,7 @@ class TraceReader(object):
# Read null-terminated filename.
filename = self.trace[offset + self.header_size + ctypes.sizeof(mmap_info):
offset + header.size]
- mmap_info.filename = filename[:filename.find(chr(0))]
+ mmap_info.filename = HOST_ROOT + filename[:filename.find(chr(0))]
return mmap_info
def ReadSample(self, header, offset):
@@ -858,6 +852,15 @@ if __name__ == "__main__":
default=False,
action="store_true",
help="no auxiliary messages [default: %default]")
+ parser.add_option("--gc-fake-mmap",
+ default="/tmp/__v8_gc__",
+ help="gc fake mmap file [default: %default]")
+ parser.add_option("--objdump",
+ default="/usr/bin/objdump",
+ help="objdump tool to use [default: %default]")
+ parser.add_option("--host-root",
+ default="",
+ help="Path to the host root [default: %default]")
options, args = parser.parse_args()
if not options.quiet:
@@ -869,6 +872,14 @@ if __name__ == "__main__":
print "V8 log: %s, %s.ll (no snapshot)" % (options.log, options.log)
print "Perf trace file: %s" % options.trace
+ V8_GC_FAKE_MMAP = options.gc_fake_mmap
+ HOST_ROOT = options.host_root
+ if os.path.exists(options.objdump):
+ disasm.OBJDUMP_BIN = options.objdump
+ OBJDUMP_BIN = options.objdump
+ else:
+ print "Cannot find %s, falling back to default objdump" % options.objdump
+
# Stats.
events = 0
ticks = 0
@@ -905,7 +916,7 @@ if __name__ == "__main__":
if header.type == PERF_RECORD_MMAP:
start = time.time()
mmap_info = trace_reader.ReadMmap(header, offset)
- if mmap_info.filename == V8_GC_FAKE_MMAP:
+ if mmap_info.filename == HOST_ROOT + V8_GC_FAKE_MMAP:
log_reader.ReadUpToGC()
else:
library_repo.Load(mmap_info, code_map, options)
diff --git a/deps/v8/tools/merge-to-branch.sh b/deps/v8/tools/merge-to-branch.sh
index aa590a313..e0011edff 100644..100755
--- a/deps/v8/tools/merge-to-branch.sh
+++ b/deps/v8/tools/merge-to-branch.sh
@@ -186,7 +186,6 @@ if [ $START_STEP -le $CURRENT_STEP ] ; then
if [ -n "$EXTRA_PATCH" ] ; then
apply_patch "$EXTRA_PATCH"
fi
- stage_files
fi
let CURRENT_STEP+=1
@@ -205,8 +204,9 @@ if [ $START_STEP -le $CURRENT_STEP ] ; then
your EDITOR on $VERSION_FILE so you can make arbitrary changes. When \
you're done, save the file and exit your EDITOR.)"
if [ $? -eq 0 ] ; then
+ echo $NEWPATCH $VERSION_FILE
sed -e "/#define PATCH_LEVEL/s/[0-9]*$/$NEWPATCH/" \
- -i "$VERSION_FILE"
+ -i.bak "$VERSION_FILE" || die "Could not increment patch level"
else
$EDITOR "$VERSION_FILE"
fi
diff --git a/deps/v8/tools/presubmit.py b/deps/v8/tools/presubmit.py
index a0b81e85f..efa8724e7 100755
--- a/deps/v8/tools/presubmit.py
+++ b/deps/v8/tools/presubmit.py
@@ -307,6 +307,7 @@ class SourceProcessor(SourceFileProcessor):
or (name == 'DerivedSources'))
IGNORE_COPYRIGHTS = ['cpplint.py',
+ 'daemon.py',
'earley-boyer.js',
'raytrace.js',
'crypto.js',
diff --git a/deps/v8/tools/push-to-trunk.sh b/deps/v8/tools/push-to-trunk.sh
index ff6dd1d77..8512d1287 100755
--- a/deps/v8/tools/push-to-trunk.sh
+++ b/deps/v8/tools/push-to-trunk.sh
@@ -268,7 +268,6 @@ if [ $START_STEP -le $CURRENT_STEP ] ; then
echo ">>> Step $CURRENT_STEP: Apply squashed changes."
rm -f "$TOUCHED_FILES_FILE"
apply_patch "$PATCH_FILE"
- stage_files
rm -f "$PATCH_FILE"
fi
@@ -304,11 +303,22 @@ fi
let CURRENT_STEP+=1
if [ $START_STEP -le $CURRENT_STEP ] ; then
echo ">>> Step $CURRENT_STEP: Commit to SVN."
- git svn dcommit | tee >(grep -E "^Committed r[0-9]+" \
- | sed -e 's/^Committed r\([0-9]\+\)/\1/' \
- > "$TRUNK_REVISION_FILE") \
+ git svn dcommit 2>&1 | tee >(grep -E "^Committed r[0-9]+" \
+ | sed -e 's/^Committed r\([0-9]\+\)/\1/' \
+ > "$TRUNK_REVISION_FILE") \
|| die "'git svn dcommit' failed."
TRUNK_REVISION=$(cat "$TRUNK_REVISION_FILE")
+ # Sometimes grepping for the revision fails. No idea why. If you figure
+ # out why it is flaky, please do fix it properly.
+ if [ -z "$TRUNK_REVISION" ] ; then
+ echo "Sorry, grepping for the SVN revision failed. Please look for it in \
+the last command's output above and provide it manually (just the number, \
+without the leading \"r\")."
+ while [ -z "$TRUNK_REVISION" ] ; do
+ echo -n "> "
+ read TRUNK_REVISION
+ done
+ fi
persist "TRUNK_REVISION"
rm -f "$TRUNK_REVISION_FILE"
fi
diff --git a/deps/v8/tools/run-tests.py b/deps/v8/tools/run-tests.py
new file mode 100755
index 000000000..a49f6560a
--- /dev/null
+++ b/deps/v8/tools/run-tests.py
@@ -0,0 +1,364 @@
+#!/usr/bin/env python
+#
+# Copyright 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.
+
+
+import multiprocessing
+import optparse
+import os
+from os.path import join
+import subprocess
+import sys
+import time
+
+from testrunner.local import execution
+from testrunner.local import progress
+from testrunner.local import testsuite
+from testrunner.local import utils
+from testrunner.local import verbose
+from testrunner.network import network_execution
+from testrunner.objects import context
+
+
+ARCH_GUESS = utils.DefaultArch()
+DEFAULT_TESTS = ["mjsunit", "cctest", "message", "preparser"]
+TIMEOUT_DEFAULT = 60
+TIMEOUT_SCALEFACTOR = {"debug" : 4,
+ "release" : 1 }
+
+# Use this to run several variants of the tests.
+VARIANT_FLAGS = [[],
+ ["--stress-opt", "--always-opt"],
+ ["--nocrankshaft"]]
+MODE_FLAGS = {
+ "debug" : ["--nobreak-on-abort", "--nodead-code-elimination",
+ "--enable-slow-asserts", "--debug-code", "--verify-heap"],
+ "release" : ["--nobreak-on-abort", "--nodead-code-elimination"]}
+
+SUPPORTED_ARCHS = ["android_arm",
+ "android_ia32",
+ "arm",
+ "ia32",
+ "mipsel",
+ "x64"]
+
+
+def BuildOptions():
+ result = optparse.OptionParser()
+ result.add_option("--arch",
+ help=("The architecture to run tests for, "
+ "'auto' or 'native' for auto-detect"),
+ default="ia32,x64,arm")
+ result.add_option("--arch-and-mode",
+ help="Architecture and mode in the format 'arch.mode'",
+ default=None)
+ result.add_option("--buildbot",
+ help="Adapt to path structure used on buildbots",
+ default=False, action="store_true")
+ result.add_option("--cat", help="Print the source of the tests",
+ default=False, action="store_true")
+ result.add_option("--command-prefix",
+ help="Prepended to each shell command used to run a test",
+ default="")
+ result.add_option("--download-data", help="Download missing test suite data",
+ default=False, action="store_true")
+ result.add_option("--extra-flags",
+ help="Additional flags to pass to each test command",
+ default="")
+ result.add_option("--isolates", help="Whether to test isolates",
+ default=False, action="store_true")
+ result.add_option("-j", help="The number of parallel tasks to run",
+ default=0, type="int")
+ result.add_option("-m", "--mode",
+ help="The test modes in which to run (comma-separated)",
+ default="release,debug")
+ result.add_option("--no-network", "--nonetwork",
+ help="Don't distribute tests on the network",
+ default=(utils.GuessOS() != "linux"),
+ dest="no_network", action="store_true")
+ result.add_option("--no-presubmit", "--nopresubmit",
+ help='Skip presubmit checks',
+ default=False, dest="no_presubmit", action="store_true")
+ result.add_option("--no-stress", "--nostress",
+ help="Don't run crankshaft --always-opt --stress-op test",
+ default=False, dest="no_stress", action="store_true")
+ result.add_option("--outdir", help="Base directory with compile output",
+ default="out")
+ result.add_option("-p", "--progress",
+ help=("The style of progress indicator"
+ " (verbose, dots, color, mono)"),
+ choices=progress.PROGRESS_INDICATORS.keys(), default="mono")
+ result.add_option("--report", help="Print a summary of the tests to be run",
+ default=False, action="store_true")
+ result.add_option("--shard-count",
+ help="Split testsuites into this number of shards",
+ default=1, type="int")
+ result.add_option("--shard-run",
+ help="Run this shard from the split up tests.",
+ default=1, type="int")
+ result.add_option("--shell", help="DEPRECATED! use --shell-dir", default="")
+ result.add_option("--shell-dir", help="Directory containing executables",
+ default="")
+ result.add_option("--stress-only",
+ help="Only run tests with --always-opt --stress-opt",
+ default=False, action="store_true")
+ result.add_option("--time", help="Print timing information after running",
+ default=False, action="store_true")
+ result.add_option("-t", "--timeout", help="Timeout in seconds",
+ default= -1, type="int")
+ result.add_option("-v", "--verbose", help="Verbose output",
+ default=False, action="store_true")
+ result.add_option("--valgrind", help="Run tests through valgrind",
+ default=False, action="store_true")
+ result.add_option("--warn-unused", help="Report unused rules",
+ default=False, action="store_true")
+ return result
+
+
+def ProcessOptions(options):
+ global VARIANT_FLAGS
+
+ # Architecture and mode related stuff.
+ if options.arch_and_mode:
+ tokens = options.arch_and_mode.split(".")
+ options.arch = tokens[0]
+ options.mode = tokens[1]
+ options.mode = options.mode.split(",")
+ for mode in options.mode:
+ if not mode in ["debug", "release"]:
+ print "Unknown mode %s" % mode
+ return False
+ if options.arch in ["auto", "native"]:
+ options.arch = ARCH_GUESS
+ options.arch = options.arch.split(",")
+ for arch in options.arch:
+ if not arch in SUPPORTED_ARCHS:
+ print "Unknown architecture %s" % arch
+ return False
+
+ # Special processing of other options, sorted alphabetically.
+
+ if options.buildbot:
+ # Buildbots run presubmit tests as a separate step.
+ options.no_presubmit = True
+ options.no_network = True
+ if options.command_prefix:
+ print("Specifying --command-prefix disables network distribution, "
+ "running tests locally.")
+ options.no_network = True
+ if options.j == 0:
+ options.j = multiprocessing.cpu_count()
+ if options.no_stress:
+ VARIANT_FLAGS = [[], ["--nocrankshaft"]]
+ if not options.shell_dir:
+ if options.shell:
+ print "Warning: --shell is deprecated, use --shell-dir instead."
+ options.shell_dir = os.path.dirname(options.shell)
+ if options.stress_only:
+ VARIANT_FLAGS = [["--stress-opt", "--always-opt"]]
+ if options.valgrind:
+ run_valgrind = os.path.join("tools", "run-valgrind.py")
+ # This is OK for distributed running, so we don't need to set no_network.
+ options.command_prefix = ("python -u " + run_valgrind +
+ options.command_prefix)
+ return True
+
+
+def ShardTests(tests, shard_count, shard_run):
+ if shard_count < 2:
+ return tests
+ if shard_run < 1 or shard_run > shard_count:
+ print "shard-run not a valid number, should be in [1:shard-count]"
+ print "defaulting back to running all tests"
+ return tests
+ count = 0
+ shard = []
+ for test in tests:
+ if count % shard_count == shard_run - 1:
+ shard.append(test)
+ count += 1
+ return shard
+
+
+def Main():
+ parser = BuildOptions()
+ (options, args) = parser.parse_args()
+ if not ProcessOptions(options):
+ parser.print_help()
+ return 1
+
+ exit_code = 0
+ workspace = os.path.abspath(join(os.path.dirname(sys.argv[0]), ".."))
+ if not options.no_presubmit:
+ print ">>> running presubmit tests"
+ code = subprocess.call(
+ [sys.executable, join(workspace, "tools", "presubmit.py")])
+ exit_code = code
+
+ suite_paths = utils.GetSuitePaths(join(workspace, "test"))
+
+ if len(args) == 0:
+ suite_paths = [ s for s in suite_paths if s in DEFAULT_TESTS ]
+ else:
+ args_suites = set()
+ for arg in args:
+ suite = arg.split(os.path.sep)[0]
+ if not suite in args_suites:
+ args_suites.add(suite)
+ suite_paths = [ s for s in suite_paths if s in args_suites ]
+
+ suites = []
+ for root in suite_paths:
+ suite = testsuite.TestSuite.LoadTestSuite(
+ os.path.join(workspace, "test", root))
+ if suite:
+ suites.append(suite)
+
+ if options.download_data:
+ for s in suites:
+ s.DownloadData()
+
+ for mode in options.mode:
+ for arch in options.arch:
+ code = Execute(arch, mode, args, options, suites, workspace)
+ exit_code = exit_code or code
+ return exit_code
+
+
+def Execute(arch, mode, args, options, suites, workspace):
+ print(">>> Running tests for %s.%s" % (arch, mode))
+
+ shell_dir = options.shell_dir
+ if not shell_dir:
+ if options.buildbot:
+ shell_dir = os.path.join(workspace, options.outdir, mode)
+ mode = mode.lower()
+ else:
+ shell_dir = os.path.join(workspace, options.outdir,
+ "%s.%s" % (arch, mode))
+ shell_dir = os.path.relpath(shell_dir)
+
+ # Populate context object.
+ mode_flags = MODE_FLAGS[mode]
+ timeout = options.timeout
+ if timeout == -1:
+ # Simulators are slow, therefore allow a longer default timeout.
+ if arch in ["android", "arm", "mipsel"]:
+ timeout = 2 * TIMEOUT_DEFAULT;
+ else:
+ timeout = TIMEOUT_DEFAULT;
+
+ options.timeout *= TIMEOUT_SCALEFACTOR[mode]
+ ctx = context.Context(arch, mode, shell_dir,
+ mode_flags, options.verbose,
+ timeout, options.isolates,
+ options.command_prefix,
+ options.extra_flags)
+
+ # Find available test suites and read test cases from them.
+ variables = {
+ "mode": mode,
+ "arch": arch,
+ "system": utils.GuessOS(),
+ "isolates": options.isolates
+ }
+ all_tests = []
+ num_tests = 0
+ test_id = 0
+ for s in suites:
+ s.ReadStatusFile(variables)
+ s.ReadTestCases(ctx)
+ all_tests += s.tests
+ if len(args) > 0:
+ s.FilterTestCasesByArgs(args)
+ s.FilterTestCasesByStatus(options.warn_unused)
+ if options.cat:
+ verbose.PrintTestSource(s.tests)
+ continue
+ variant_flags = s.VariantFlags() or VARIANT_FLAGS
+ s.tests = [ t.CopyAddingFlags(v) for t in s.tests for v in variant_flags ]
+ s.tests = ShardTests(s.tests, options.shard_count, options.shard_run)
+ num_tests += len(s.tests)
+ for t in s.tests:
+ t.id = test_id
+ test_id += 1
+
+ if options.cat:
+ return 0 # We're done here.
+
+ if options.report:
+ verbose.PrintReport(all_tests)
+
+ if num_tests == 0:
+ print "No tests to run."
+ return 0
+
+ # Run the tests, either locally or distributed on the network.
+ try:
+ start_time = time.time()
+ progress_indicator = progress.PROGRESS_INDICATORS[options.progress]()
+
+ run_networked = not options.no_network
+ if not run_networked:
+ print("Network distribution disabled, running tests locally.")
+ elif utils.GuessOS() != "linux":
+ print("Network distribution is only supported on Linux, sorry!")
+ run_networked = False
+ peers = []
+ if run_networked:
+ peers = network_execution.GetPeers()
+ if not peers:
+ print("No connection to distribution server; running tests locally.")
+ run_networked = False
+ elif len(peers) == 1:
+ print("No other peers on the network; running tests locally.")
+ run_networked = False
+ elif num_tests <= 100:
+ print("Less than 100 tests, running them locally.")
+ run_networked = False
+
+ if run_networked:
+ runner = network_execution.NetworkedRunner(suites, progress_indicator,
+ ctx, peers, workspace)
+ else:
+ runner = execution.Runner(suites, progress_indicator, ctx)
+
+ exit_code = runner.Run(options.j)
+ if runner.terminate:
+ return exit_code
+ overall_duration = time.time() - start_time
+ except KeyboardInterrupt:
+ return 1
+
+ if options.time:
+ verbose.PrintTestDurations(suites, overall_duration)
+ return exit_code
+
+
+if __name__ == "__main__":
+ sys.exit(Main())
diff --git a/deps/v8/tools/status-file-converter.py b/deps/v8/tools/status-file-converter.py
new file mode 100755
index 000000000..ba063ee8c
--- /dev/null
+++ b/deps/v8/tools/status-file-converter.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+#
+# Copyright 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.
+
+
+import sys
+from testrunner.local import old_statusfile
+
+if len(sys.argv) != 2:
+ print "Usage: %s foo.status" % sys.argv[0]
+ print "Will read foo.status and print the converted version to stdout."
+ sys.exit(1)
+
+print old_statusfile.ConvertNotation(sys.argv[1]).GetOutput()
diff --git a/deps/v8/tools/test-server.py b/deps/v8/tools/test-server.py
new file mode 100755
index 000000000..df547ed94
--- /dev/null
+++ b/deps/v8/tools/test-server.py
@@ -0,0 +1,224 @@
+#!/usr/bin/env python
+#
+# Copyright 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.
+
+
+import os
+import subprocess
+import sys
+
+
+PIDFILE = "/tmp/v8-distributed-testing-server.pid"
+ROOT = os.path.abspath(os.path.dirname(sys.argv[0]))
+
+
+def _PrintUsage():
+ print("""Usage: python %s COMMAND
+
+Where COMMAND can be any of:
+ start Starts the server. Forks to the background.
+ stop Stops the server.
+ restart Stops, then restarts the server.
+ setup Creates or updates the environment for the server to run.
+ update Alias for "setup".
+ trust <keyfile> Adds the given public key to the list of trusted keys.
+ help Displays this help text.
+ """ % sys.argv[0])
+
+
+def _IsDaemonRunning():
+ return os.path.exists(PIDFILE)
+
+
+def _Cmd(cmd):
+ code = subprocess.call(cmd, shell=True)
+ if code != 0:
+ print("Command '%s' returned error code %d" % (cmd, code))
+ sys.exit(code)
+
+
+def Update():
+ # Create directory for private data storage.
+ data_dir = os.path.join(ROOT, "data")
+ if not os.path.exists(data_dir):
+ os.makedirs(data_dir)
+
+ # Create directory for trusted public keys of peers (and self).
+ trusted_dir = os.path.join(ROOT, "trusted")
+ if not os.path.exists(trusted_dir):
+ os.makedirs(trusted_dir)
+
+ # Install UltraJSON. It is much faster than Python's builtin json.
+ try:
+ import ujson #@UnusedImport
+ except ImportError:
+ # Install pip if it doesn't exist.
+ code = subprocess.call("which pip > /dev/null", shell=True)
+ if code != 0:
+ apt_get_code = subprocess.call("which apt-get > /dev/null", shell=True)
+ if apt_get_code == 0:
+ print("Installing pip...")
+ _Cmd("sudo apt-get install python-pip")
+ else:
+ print("Please install pip on your machine. You can get it at: "
+ "http://www.pip-installer.org/en/latest/installing.html "
+ "or via your distro's package manager.")
+ sys.exit(1)
+ print("Using pip to install UltraJSON...")
+ _Cmd("sudo pip install ujson")
+
+ # Make sure we have a key pair for signing binaries.
+ privkeyfile = os.path.expanduser("~/.ssh/v8_dtest")
+ if not os.path.exists(privkeyfile):
+ _Cmd("ssh-keygen -t rsa -f %s -N '' -q" % privkeyfile)
+ fingerprint = subprocess.check_output("ssh-keygen -lf %s" % privkeyfile,
+ shell=True)
+ fingerprint = fingerprint.split(" ")[1].replace(":", "")[:16]
+ pubkeyfile = os.path.join(trusted_dir, "%s.pem" % fingerprint)
+ if (not os.path.exists(pubkeyfile) or
+ os.path.getmtime(pubkeyfile) < os.path.getmtime(privkeyfile)):
+ _Cmd("openssl rsa -in %s -out %s -pubout" % (privkeyfile, pubkeyfile))
+ with open(pubkeyfile, "a") as f:
+ f.write(fingerprint + "\n")
+ datafile = os.path.join(data_dir, "mypubkey")
+ with open(datafile, "w") as f:
+ f.write(fingerprint + "\n")
+
+ # Check out or update the server implementation in the current directory.
+ testrunner_dir = os.path.join(ROOT, "testrunner")
+ if os.path.exists(os.path.join(testrunner_dir, "server/daemon.py")):
+ _Cmd("cd %s; svn up" % testrunner_dir)
+ else:
+ path = ("http://v8.googlecode.com/svn/branches/bleeding_edge/"
+ "tools/testrunner")
+ _Cmd("svn checkout --force %s %s" % (path, testrunner_dir))
+
+ # Update this very script.
+ path = ("http://v8.googlecode.com/svn/branches/bleeding_edge/"
+ "tools/test-server.py")
+ scriptname = os.path.abspath(sys.argv[0])
+ _Cmd("svn cat %s > %s" % (path, scriptname))
+
+ # The testcfg.py files currently need to be able to import the old test.py
+ # script, so we temporarily need to make that available.
+ # TODO(jkummerow): Remove this when removing test.py.
+ for filename in ("test.py", "utils.py"):
+ url = ("http://v8.googlecode.com/svn/branches/bleeding_edge/"
+ "tools/%s" % filename)
+ filepath = os.path.join(os.path.dirname(scriptname), filename)
+ _Cmd("svn cat %s > %s" % (url, filepath))
+
+ # Check out or update V8.
+ v8_dir = os.path.join(ROOT, "v8")
+ if os.path.exists(v8_dir):
+ _Cmd("cd %s; git fetch" % v8_dir)
+ else:
+ _Cmd("git clone git://github.com/v8/v8.git %s" % v8_dir)
+
+ print("Finished.")
+
+
+# Handle "setup" here, because when executing that we can't import anything
+# else yet.
+if __name__ == "__main__" and len(sys.argv) == 2:
+ if sys.argv[1] in ("setup", "update"):
+ if _IsDaemonRunning():
+ print("Please stop the server before updating. Exiting.")
+ sys.exit(1)
+ Update()
+ sys.exit(0)
+ # Other parameters are handled below.
+
+
+#==========================================================
+# At this point we can assume that the implementation is available,
+# so we can import it.
+try:
+ from testrunner.server import constants
+ from testrunner.server import local_handler
+ from testrunner.server import main
+except Exception, e:
+ print(e)
+ print("Failed to import implementation. Have you run 'setup'?")
+ sys.exit(1)
+
+
+def _StartDaemon(daemon):
+ if not os.path.isdir(os.path.join(ROOT, "v8")):
+ print("No 'v8' working directory found. Have you run 'setup'?")
+ sys.exit(1)
+ daemon.start()
+
+
+if __name__ == "__main__":
+ if len(sys.argv) == 2:
+ arg = sys.argv[1]
+ if arg == "start":
+ daemon = main.Server(PIDFILE, ROOT)
+ _StartDaemon(daemon)
+ elif arg == "stop":
+ daemon = main.Server(PIDFILE, ROOT)
+ daemon.stop()
+ elif arg == "restart":
+ daemon = main.Server(PIDFILE, ROOT)
+ daemon.stop()
+ _StartDaemon(daemon)
+ elif arg in ("help", "-h", "--help"):
+ _PrintUsage()
+ elif arg == "status":
+ if not _IsDaemonRunning():
+ print("Server not running.")
+ else:
+ print(local_handler.LocalQuery([constants.REQUEST_STATUS]))
+ else:
+ print("Unknown command")
+ _PrintUsage()
+ sys.exit(2)
+ elif len(sys.argv) == 3:
+ arg = sys.argv[1]
+ if arg == "approve":
+ filename = sys.argv[2]
+ if not os.path.exists(filename):
+ print("%s does not exist.")
+ sys.exit(1)
+ filename = os.path.abspath(filename)
+ if _IsDaemonRunning():
+ response = local_handler.LocalQuery([constants.ADD_TRUSTED, filename])
+ else:
+ daemon = main.Server(PIDFILE, ROOT)
+ response = daemon.CopyToTrusted(filename)
+ print("Added certificate %s to trusted certificates." % response)
+ else:
+ print("Unknown command")
+ _PrintUsage()
+ sys.exit(2)
+ else:
+ print("Unknown command")
+ _PrintUsage()
+ sys.exit(2)
+ sys.exit(0)
diff --git a/deps/v8/tools/test-wrapper-gypbuild.py b/deps/v8/tools/test-wrapper-gypbuild.py
index d99d055e5..4dd6338dc 100755
--- a/deps/v8/tools/test-wrapper-gypbuild.py
+++ b/deps/v8/tools/test-wrapper-gypbuild.py
@@ -95,11 +95,14 @@ def BuildOptions():
default=1, type="int")
result.add_option("--time", help="Print timing information after running",
default=False, action="store_true")
- result.add_option("--suppress-dialogs", help="Suppress Windows dialogs for crashing tests",
- dest="suppress_dialogs", default=True, action="store_true")
- result.add_option("--no-suppress-dialogs", help="Display Windows dialogs for crashing tests",
- dest="suppress_dialogs", action="store_false")
- result.add_option("--isolates", help="Whether to test isolates", default=False, action="store_true")
+ result.add_option("--suppress-dialogs",
+ help="Suppress Windows dialogs for crashing tests",
+ dest="suppress_dialogs", default=True, action="store_true")
+ result.add_option("--no-suppress-dialogs",
+ help="Display Windows dialogs for crashing tests",
+ dest="suppress_dialogs", action="store_false")
+ result.add_option("--isolates", help="Whether to test isolates",
+ default=False, action="store_true")
result.add_option("--store-unexpected-output",
help="Store the temporary JS files from tests that fails",
dest="store_unexpected_output", default=True, action="store_true")
@@ -148,7 +151,8 @@ def ProcessOptions(options):
print "Unknown mode %s" % mode
return False
for arch in options.arch:
- if not arch in ['ia32', 'x64', 'arm', 'mips']:
+ if not arch in ['ia32', 'x64', 'arm', 'mipsel', 'android_arm',
+ 'android_ia32']:
print "Unknown architecture %s" % arch
return False
if options.buildbot:
@@ -217,9 +221,10 @@ def Main():
if not options.no_presubmit:
print ">>> running presubmit tests"
- returncodes += subprocess.call([workspace + '/tools/presubmit.py'])
+ returncodes += subprocess.call([sys.executable,
+ workspace + '/tools/presubmit.py'])
- args_for_children = ['python']
+ args_for_children = [sys.executable]
args_for_children += [workspace + '/tools/test.py'] + PassOnOptions(options)
args_for_children += ['--no-build', '--build-system=gyp']
for arg in args:
diff --git a/deps/v8/tools/test.py b/deps/v8/tools/test.py
index 5131ad761..b3b62b3a6 100755
--- a/deps/v8/tools/test.py
+++ b/deps/v8/tools/test.py
@@ -140,9 +140,9 @@ def EscapeCommand(command):
parts = []
for part in command:
if ' ' in part:
- # Escape spaces. We may need to escape more characters for this
- # to work properly.
- parts.append('"%s"' % part)
+ # Escape spaces and double quotes. We may need to escape more characters
+ # for this to work properly.
+ parts.append('"%s"' % part.replace('"', '\\"'))
else:
parts.append(part)
return " ".join(parts)
@@ -299,8 +299,6 @@ class MonochromeProgressIndicator(CompactProgressIndicator):
'status_line': "[%(mins)02i:%(secs)02i|%%%(remaining) 4d|+%(passed) 4d|-%(failed) 4d]: %(test)s",
'stdout': '%s',
'stderr': '%s',
- 'clear': lambda last_line_length: ("\r" + (" " * last_line_length) + "\r"),
- 'max_length': 78
}
super(MonochromeProgressIndicator, self).__init__(cases, templates)
@@ -686,8 +684,9 @@ SUFFIX = {
'debug' : '_g',
'release' : '' }
FLAGS = {
- 'debug' : ['--nobreak-on-abort', '--enable-slow-asserts', '--debug-code', '--verify-heap'],
- 'release' : ['--nobreak-on-abort']}
+ 'debug' : ['--nobreak-on-abort', '--nodead-code-elimination',
+ '--enable-slow-asserts', '--debug-code', '--verify-heap'],
+ 'release' : ['--nobreak-on-abort', '--nodead-code-elimination']}
TIMEOUT_SCALEFACTOR = {
'debug' : 4,
'release' : 1 }
@@ -1283,7 +1282,7 @@ def ProcessOptions(options):
options.scons_flags.append("arch=" + options.arch)
# Simulators are slow, therefore allow a longer default timeout.
if options.timeout == -1:
- if options.arch == 'arm' or options.arch == 'mips':
+ if options.arch in ['android', 'arm', 'mipsel']:
options.timeout = 2 * TIMEOUT_DEFAULT;
else:
options.timeout = TIMEOUT_DEFAULT;
@@ -1372,8 +1371,9 @@ def GetSpecialCommandProcessor(value):
else:
pos = value.find('@')
import urllib
- prefix = urllib.unquote(value[:pos]).split()
- suffix = urllib.unquote(value[pos+1:]).split()
+ import shlex
+ prefix = shlex.split(urllib.unquote(value[:pos]))
+ suffix = shlex.split(urllib.unquote(value[pos+1:]))
def ExpandCommand(args):
return prefix + args + suffix
return ExpandCommand
diff --git a/deps/v8/tools/testrunner/README b/deps/v8/tools/testrunner/README
new file mode 100644
index 000000000..8f0c01f52
--- /dev/null
+++ b/deps/v8/tools/testrunner/README
@@ -0,0 +1,174 @@
+Test suite runner for V8, including support for distributed running.
+====================================================================
+
+
+Local usage instructions:
+=========================
+
+Run the main script with --help to get detailed usage instructions:
+
+$ tools/run-tests.py --help
+
+The interface is mostly the same as it was for the old test runner.
+You'll likely want something like this:
+
+$ tools/run-tests.py --nonetwork --arch ia32 --mode release
+
+--nonetwork is the default on Mac and Windows. If you don't specify --arch
+and/or --mode, all available values will be used and run in turn (e.g.,
+omitting --mode from the above example will run ia32 in both Release and Debug
+modes).
+
+
+Networked usage instructions:
+=============================
+
+Networked running is only supported on Linux currently. Make sure that all
+machines participating in the cluster are binary-compatible (e.g. mixing
+Ubuntu Lucid and Precise doesn't work).
+
+Setup:
+------
+
+1.) Copy tools/test-server.py to a new empty directory anywhere on your hard
+ drive (preferably not inside your V8 checkout just to keep things clean).
+ Please do create a copy, not just a symlink.
+
+2.) Navigate to the new directory and let the server setup itself:
+
+$ ./test-server.py setup
+
+ This will install PIP and UltraJSON, create a V8 working directory, and
+ generate a keypair.
+
+3.) Swap public keys with someone who's already part of the networked cluster.
+
+$ cp trusted/`cat data/mypubkey`.pem /where/peers/can/see/it/myname.pem
+$ ./test-server.py approve /wherever/they/put/it/yourname.pem
+
+
+Usage:
+------
+
+1.) Start your server:
+
+$ ./test-server.py start
+
+2.) (Optionally) inspect the server's status:
+
+$ ./test-server.py status
+
+3.) From your regular V8 working directory, run tests:
+
+$ tool/run-tests.py --arch ia32 --mode debug
+
+4.) (Optionally) enjoy the speeeeeeeeeeeeeeeed
+
+
+Architecture overview:
+======================
+
+Code organization:
+------------------
+
+This section is written from the point of view of the tools/ directory.
+
+./run-tests.py:
+ Main script. Parses command-line options and drives the test execution
+ procedure from a high level. Imports the actual implementation of all
+ steps from the testrunner/ directory.
+
+./test-server.py:
+ Interface to interact with the server. Contains code to setup the server's
+ working environment and can start and stop server daemon processes.
+ Imports some stuff from the testrunner/server/ directory.
+
+./testrunner/local/*:
+ Implementation needed to run tests locally. Used by run-tests.py. Inspired by
+ (and partly copied verbatim from) the original test.py script.
+
+./testrunner/local/old_statusfile.py:
+ Provides functionality to read an old-style <testsuite>.status file and
+ convert it to new-style syntax. This can be removed once the new-style
+ syntax becomes authoritative (and old-style syntax is no longer supported).
+ ./status-file-converter.py provides a stand-alone interface to this.
+
+./testrunner/objects/*:
+ A bunch of data container classes, used by the scripts in the various other
+ directories; serializable for transmission over the network.
+
+./testrunner/network/*:
+ Equivalents and extensions of some of the functionality in ./testrunner/local/
+ as required when dispatching tests to peers on the network.
+
+./testrunner/network/network_execution.py:
+ Drop-in replacement for ./testrunner/local/execution that distributes
+ test jobs to network peers instead of running them locally.
+
+./testrunner/network/endpoint.py:
+ Receiving end of a network distributed job, uses the implementation
+ in ./testrunner/local/execution.py for actually running the tests.
+
+./testrunner/server/*:
+ Implementation of the daemon that accepts and runs test execution jobs from
+ peers on the network. Should ideally have no dependencies on any of the other
+ directories, but that turned out to be impractical, so there are a few
+ exceptions.
+
+./testrunner/server/compression.py:
+ Defines a wrapper around Python TCP sockets that provides JSON based
+ serialization, gzip based compression, and ensures message completeness.
+
+
+Networking architecture:
+------------------------
+
+The distribution stuff is designed to be a layer between deciding which tests
+to run on the one side, and actually running them on the other. The frontend
+that the user interacts with is the same for local and networked execution,
+and the actual test execution and result gathering code is the same too.
+
+The server daemon starts four separate servers, each listening on another port:
+- "Local": Communication with a run-tests.py script running on the same host.
+ The test driving script e.g. needs to ask for available peers. It then talks
+ to those peers directly (one of them will be the locally running server).
+- "Work": Listens for test job requests from run-tests.py scripts on the network
+ (including localhost). Accepts an arbitrary number of connections at the
+ same time, but only works on them in a serialized fashion.
+- "Status": Used for communication with other servers on the network, e.g. for
+ exchanging trusted public keys to create the transitive trust closure.
+- "Discovery": Used to detect presence of other peers on the network.
+ In contrast to the other three, this uses UDP (as opposed to TCP).
+
+
+Give us a diagram! We love diagrams!
+------------------------------------
+ .
+ Machine A . Machine B
+ .
++------------------------------+ .
+| run-tests.py | .
+| with flag: | .
+|--nonetwork --network | .
+| | / | | .
+| | / | | .
+| v / v | .
+|BACKEND / distribution | .
++--------- / --------| \ ------+ .
+ / | \_____________________
+ / | . \
+ / | . \
++----- v ----------- v --------+ . +---- v -----------------------+
+| LocalHandler | WorkHandler | . | WorkHandler | LocalHandler |
+| | | | . | | | |
+| | v | . | v | |
+| | BACKEND | . | BACKEND | |
+|------------- +---------------| . |---------------+--------------|
+| Discovery | StatusHandler <----------> StatusHandler | Discovery |
++---- ^ -----------------------+ . +-------------------- ^ -------+
+ | . |
+ +---------------------------------------------------------+
+
+Note that the three occurrences of "BACKEND" are the same code
+(testrunner/local/execution.py and its imports), but running from three
+distinct directories (and on two different machines).
diff --git a/deps/v8/tools/testrunner/__init__.py b/deps/v8/tools/testrunner/__init__.py
new file mode 100644
index 000000000..202a26270
--- /dev/null
+++ b/deps/v8/tools/testrunner/__init__.py
@@ -0,0 +1,26 @@
+# Copyright 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.
diff --git a/deps/v8/tools/testrunner/local/__init__.py b/deps/v8/tools/testrunner/local/__init__.py
new file mode 100644
index 000000000..202a26270
--- /dev/null
+++ b/deps/v8/tools/testrunner/local/__init__.py
@@ -0,0 +1,26 @@
+# Copyright 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.
diff --git a/deps/v8/tools/testrunner/local/commands.py b/deps/v8/tools/testrunner/local/commands.py
new file mode 100644
index 000000000..01f170dc8
--- /dev/null
+++ b/deps/v8/tools/testrunner/local/commands.py
@@ -0,0 +1,153 @@
+# Copyright 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.
+
+
+import os
+import signal
+import subprocess
+import sys
+import tempfile
+import time
+
+from ..local import utils
+from ..objects import output
+
+
+def KillProcessWithID(pid):
+ if utils.IsWindows():
+ os.popen('taskkill /T /F /PID %d' % pid)
+ else:
+ os.kill(pid, signal.SIGTERM)
+
+
+MAX_SLEEP_TIME = 0.1
+INITIAL_SLEEP_TIME = 0.0001
+SLEEP_TIME_FACTOR = 1.25
+
+SEM_INVALID_VALUE = -1
+SEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h
+
+
+def Win32SetErrorMode(mode):
+ prev_error_mode = SEM_INVALID_VALUE
+ try:
+ import ctypes
+ prev_error_mode = \
+ ctypes.windll.kernel32.SetErrorMode(mode) #@UndefinedVariable
+ except ImportError:
+ pass
+ return prev_error_mode
+
+
+def RunProcess(verbose, timeout, args, **rest):
+ if verbose: print "#", " ".join(args)
+ popen_args = args
+ prev_error_mode = SEM_INVALID_VALUE
+ if utils.IsWindows():
+ popen_args = subprocess.list2cmdline(args)
+ # Try to change the error mode to avoid dialogs on fatal errors. Don't
+ # touch any existing error mode flags by merging the existing error mode.
+ # See http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx.
+ error_mode = SEM_NOGPFAULTERRORBOX
+ prev_error_mode = Win32SetErrorMode(error_mode)
+ Win32SetErrorMode(error_mode | prev_error_mode)
+ process = subprocess.Popen(
+ shell=utils.IsWindows(),
+ args=popen_args,
+ **rest
+ )
+ if (utils.IsWindows() and prev_error_mode != SEM_INVALID_VALUE):
+ Win32SetErrorMode(prev_error_mode)
+ # Compute the end time - if the process crosses this limit we
+ # consider it timed out.
+ if timeout is None: end_time = None
+ else: end_time = time.time() + timeout
+ timed_out = False
+ # Repeatedly check the exit code from the process in a
+ # loop and keep track of whether or not it times out.
+ exit_code = None
+ sleep_time = INITIAL_SLEEP_TIME
+ try:
+ while exit_code is None:
+ if (not end_time is None) and (time.time() >= end_time):
+ # Kill the process and wait for it to exit.
+ KillProcessWithID(process.pid)
+ exit_code = process.wait()
+ timed_out = True
+ else:
+ exit_code = process.poll()
+ time.sleep(sleep_time)
+ sleep_time = sleep_time * SLEEP_TIME_FACTOR
+ if sleep_time > MAX_SLEEP_TIME:
+ sleep_time = MAX_SLEEP_TIME
+ return (exit_code, timed_out)
+ except KeyboardInterrupt:
+ raise
+
+
+def PrintError(string):
+ sys.stderr.write(string)
+ sys.stderr.write("\n")
+
+
+def CheckedUnlink(name):
+ # On Windows, when run with -jN in parallel processes,
+ # OS often fails to unlink the temp file. Not sure why.
+ # Need to retry.
+ # Idea from https://bugs.webkit.org/attachment.cgi?id=75982&action=prettypatch
+ retry_count = 0
+ while retry_count < 30:
+ try:
+ os.unlink(name)
+ return
+ except OSError, e:
+ retry_count += 1
+ time.sleep(retry_count * 0.1)
+ PrintError("os.unlink() " + str(e))
+
+
+def Execute(args, verbose=False, timeout=None):
+ args = [ c for c in args if c != "" ]
+ (fd_out, outname) = tempfile.mkstemp()
+ (fd_err, errname) = tempfile.mkstemp()
+ try:
+ (exit_code, timed_out) = RunProcess(
+ verbose,
+ timeout,
+ args=args,
+ stdout=fd_out,
+ stderr=fd_err
+ )
+ except:
+ raise
+ os.close(fd_out)
+ os.close(fd_err)
+ out = file(outname).read()
+ errors = file(errname).read()
+ CheckedUnlink(outname)
+ CheckedUnlink(errname)
+ return output.Output(exit_code, timed_out, out, errors)
diff --git a/deps/v8/tools/testrunner/local/execution.py b/deps/v8/tools/testrunner/local/execution.py
new file mode 100644
index 000000000..600436791
--- /dev/null
+++ b/deps/v8/tools/testrunner/local/execution.py
@@ -0,0 +1,182 @@
+# Copyright 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.
+
+
+import multiprocessing
+import os
+import threading
+import time
+
+from . import commands
+from . import utils
+
+
+BREAK_NOW = -1
+EXCEPTION = -2
+
+
+class Job(object):
+ def __init__(self, command, dep_command, test_id, timeout, verbose):
+ self.command = command
+ self.dep_command = dep_command
+ self.id = test_id
+ self.timeout = timeout
+ self.verbose = verbose
+
+
+def RunTest(job):
+ try:
+ start_time = time.time()
+ if job.dep_command is not None:
+ dep_output = commands.Execute(job.dep_command, job.verbose, job.timeout)
+ # TODO(jkummerow): We approximate the test suite specific function
+ # IsFailureOutput() by just checking the exit code here. Currently
+ # only cctests define dependencies, for which this simplification is
+ # correct.
+ if dep_output.exit_code != 0:
+ return (job.id, dep_output, time.time() - start_time)
+ output = commands.Execute(job.command, job.verbose, job.timeout)
+ return (job.id, output, time.time() - start_time)
+ except KeyboardInterrupt:
+ return (-1, BREAK_NOW, 0)
+ except Exception, e:
+ print(">>> EXCEPTION: %s" % e)
+ return (-1, EXCEPTION, 0)
+
+
+class Runner(object):
+
+ def __init__(self, suites, progress_indicator, context):
+ self.tests = [ t for s in suites for t in s.tests ]
+ self._CommonInit(len(self.tests), progress_indicator, context)
+
+ def _CommonInit(self, num_tests, progress_indicator, context):
+ self.indicator = progress_indicator
+ progress_indicator.runner = self
+ self.context = context
+ self.succeeded = 0
+ self.total = num_tests
+ self.remaining = num_tests
+ self.failed = []
+ self.crashed = 0
+ self.terminate = False
+ self.lock = threading.Lock()
+
+ def Run(self, jobs):
+ self.indicator.Starting()
+ self._RunInternal(jobs)
+ self.indicator.Done()
+ if self.failed:
+ return 1
+ return 0
+
+ def _RunInternal(self, jobs):
+ pool = multiprocessing.Pool(processes=jobs)
+ test_map = {}
+ queue = []
+ queued_exception = None
+ for test in self.tests:
+ assert test.id >= 0
+ test_map[test.id] = test
+ try:
+ command = self.GetCommand(test)
+ except Exception, e:
+ # If this failed, save the exception and re-raise it later (after
+ # all other tests have had a chance to run).
+ queued_exception = e
+ continue
+ timeout = self.context.timeout
+ if ("--stress-opt" in test.flags or
+ "--stress-opt" in self.context.mode_flags or
+ "--stress-opt" in self.context.extra_flags):
+ timeout *= 4
+ if test.dependency is not None:
+ dep_command = [ c.replace(test.path, test.dependency) for c in command ]
+ else:
+ dep_command = None
+ job = Job(command, dep_command, test.id, timeout, self.context.verbose)
+ queue.append(job)
+ try:
+ kChunkSize = 1
+ it = pool.imap_unordered(RunTest, queue, kChunkSize)
+ for result in it:
+ test_id = result[0]
+ if test_id < 0:
+ if result[1] == BREAK_NOW:
+ self.terminate = True
+ else:
+ continue
+ if self.terminate:
+ pool.terminate()
+ pool.join()
+ raise BreakNowException("User pressed Ctrl+C or IO went wrong")
+ test = test_map[test_id]
+ self.indicator.AboutToRun(test)
+ test.output = result[1]
+ test.duration = result[2]
+ if test.suite.HasUnexpectedOutput(test):
+ self.failed.append(test)
+ if test.output.HasCrashed():
+ self.crashed += 1
+ else:
+ self.succeeded += 1
+ self.remaining -= 1
+ self.indicator.HasRun(test)
+ except KeyboardInterrupt:
+ pool.terminate()
+ pool.join()
+ raise
+ except Exception, e:
+ print("Exception: %s" % e)
+ pool.terminate()
+ pool.join()
+ raise
+ if queued_exception:
+ raise queued_exception
+ return
+
+
+ def GetCommand(self, test):
+ d8testflag = []
+ shell = test.suite.shell()
+ if shell == "d8":
+ d8testflag = ["--test"]
+ if utils.IsWindows():
+ shell += ".exe"
+ cmd = ([self.context.command_prefix] +
+ [os.path.abspath(os.path.join(self.context.shell_dir, shell))] +
+ d8testflag +
+ test.suite.GetFlagsForTestCase(test, self.context) +
+ [self.context.extra_flags])
+ return cmd
+
+
+class BreakNowException(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
diff --git a/deps/v8/tools/testrunner/local/old_statusfile.py b/deps/v8/tools/testrunner/local/old_statusfile.py
new file mode 100644
index 000000000..a16941b83
--- /dev/null
+++ b/deps/v8/tools/testrunner/local/old_statusfile.py
@@ -0,0 +1,460 @@
+# Copyright 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.
+
+
+import cStringIO
+import re
+
+# These outcomes can occur in a TestCase's outcomes list:
+SKIP = 'SKIP'
+FAIL = 'FAIL'
+PASS = 'PASS'
+OKAY = 'OKAY'
+TIMEOUT = 'TIMEOUT'
+CRASH = 'CRASH'
+SLOW = 'SLOW'
+# These are just for the status files and are mapped below in DEFS:
+FAIL_OK = 'FAIL_OK'
+PASS_OR_FAIL = 'PASS_OR_FAIL'
+
+KEYWORDS = {SKIP: SKIP,
+ FAIL: FAIL,
+ PASS: PASS,
+ OKAY: OKAY,
+ TIMEOUT: TIMEOUT,
+ CRASH: CRASH,
+ SLOW: SLOW,
+ FAIL_OK: FAIL_OK,
+ PASS_OR_FAIL: PASS_OR_FAIL}
+
+class Expression(object):
+ pass
+
+
+class Constant(Expression):
+
+ def __init__(self, value):
+ self.value = value
+
+ def Evaluate(self, env, defs):
+ return self.value
+
+
+class Variable(Expression):
+
+ def __init__(self, name):
+ self.name = name
+
+ def GetOutcomes(self, env, defs):
+ if self.name in env: return set([env[self.name]])
+ else: return set([])
+
+ def Evaluate(self, env, defs):
+ return env[self.name]
+
+ def __str__(self):
+ return self.name
+
+ def string(self, logical):
+ return self.__str__()
+
+
+class Outcome(Expression):
+
+ def __init__(self, name):
+ self.name = name
+
+ def GetOutcomes(self, env, defs):
+ if self.name in defs:
+ return defs[self.name].GetOutcomes(env, defs)
+ else:
+ return set([self.name])
+
+ def __str__(self):
+ if self.name in KEYWORDS:
+ return "%s" % KEYWORDS[self.name]
+ return "'%s'" % self.name
+
+ def string(self, logical):
+ if logical:
+ return "%s" % self.name
+ return self.__str__()
+
+
+class Operation(Expression):
+
+ def __init__(self, left, op, right):
+ self.left = left
+ self.op = op
+ self.right = right
+
+ def Evaluate(self, env, defs):
+ if self.op == '||' or self.op == ',':
+ return self.left.Evaluate(env, defs) or self.right.Evaluate(env, defs)
+ elif self.op == 'if':
+ return False
+ elif self.op == '==':
+ return not self.left.GetOutcomes(env, defs).isdisjoint(self.right.GetOutcomes(env, defs))
+ elif self.op == '!=':
+ return self.left.GetOutcomes(env, defs).isdisjoint(self.right.GetOutcomes(env, defs))
+ else:
+ assert self.op == '&&'
+ return self.left.Evaluate(env, defs) and self.right.Evaluate(env, defs)
+
+ def GetOutcomes(self, env, defs):
+ if self.op == '||' or self.op == ',':
+ return self.left.GetOutcomes(env, defs) | self.right.GetOutcomes(env, defs)
+ elif self.op == 'if':
+ if self.right.Evaluate(env, defs): return self.left.GetOutcomes(env, defs)
+ else: return set([])
+ else:
+ assert self.op == '&&'
+ return self.left.GetOutcomes(env, defs) & self.right.GetOutcomes(env, defs)
+
+ def __str__(self):
+ return self.string(False)
+
+ def string(self, logical=False):
+ if self.op == 'if':
+ return "['%s', %s]" % (self.right.string(True), self.left.string(logical))
+ elif self.op == "||" or self.op == ",":
+ if logical:
+ return "%s or %s" % (self.left.string(True), self.right.string(True))
+ else:
+ return "%s, %s" % (self.left, self.right)
+ elif self.op == "&&":
+ return "%s and %s" % (self.left.string(True), self.right.string(True))
+ return "%s %s %s" % (self.left.string(logical), self.op,
+ self.right.string(logical))
+
+
+def IsAlpha(string):
+ for char in string:
+ if not (char.isalpha() or char.isdigit() or char == '_'):
+ return False
+ return True
+
+
+class Tokenizer(object):
+ """A simple string tokenizer that chops expressions into variables,
+ parens and operators"""
+
+ def __init__(self, expr):
+ self.index = 0
+ self.expr = expr
+ self.length = len(expr)
+ self.tokens = None
+
+ def Current(self, length=1):
+ if not self.HasMore(length): return ""
+ return self.expr[self.index:self.index + length]
+
+ def HasMore(self, length=1):
+ return self.index < self.length + (length - 1)
+
+ def Advance(self, count=1):
+ self.index = self.index + count
+
+ def AddToken(self, token):
+ self.tokens.append(token)
+
+ def SkipSpaces(self):
+ while self.HasMore() and self.Current().isspace():
+ self.Advance()
+
+ def Tokenize(self):
+ self.tokens = [ ]
+ while self.HasMore():
+ self.SkipSpaces()
+ if not self.HasMore():
+ return None
+ if self.Current() == '(':
+ self.AddToken('(')
+ self.Advance()
+ elif self.Current() == ')':
+ self.AddToken(')')
+ self.Advance()
+ elif self.Current() == '$':
+ self.AddToken('$')
+ self.Advance()
+ elif self.Current() == ',':
+ self.AddToken(',')
+ self.Advance()
+ elif IsAlpha(self.Current()):
+ buf = ""
+ while self.HasMore() and IsAlpha(self.Current()):
+ buf += self.Current()
+ self.Advance()
+ self.AddToken(buf)
+ elif self.Current(2) == '&&':
+ self.AddToken('&&')
+ self.Advance(2)
+ elif self.Current(2) == '||':
+ self.AddToken('||')
+ self.Advance(2)
+ elif self.Current(2) == '==':
+ self.AddToken('==')
+ self.Advance(2)
+ elif self.Current(2) == '!=':
+ self.AddToken('!=')
+ self.Advance(2)
+ else:
+ return None
+ return self.tokens
+
+
+class Scanner(object):
+ """A simple scanner that can serve out tokens from a given list"""
+
+ def __init__(self, tokens):
+ self.tokens = tokens
+ self.length = len(tokens)
+ self.index = 0
+
+ def HasMore(self):
+ return self.index < self.length
+
+ def Current(self):
+ return self.tokens[self.index]
+
+ def Advance(self):
+ self.index = self.index + 1
+
+
+def ParseAtomicExpression(scan):
+ if scan.Current() == "true":
+ scan.Advance()
+ return Constant(True)
+ elif scan.Current() == "false":
+ scan.Advance()
+ return Constant(False)
+ elif IsAlpha(scan.Current()):
+ name = scan.Current()
+ scan.Advance()
+ return Outcome(name)
+ elif scan.Current() == '$':
+ scan.Advance()
+ if not IsAlpha(scan.Current()):
+ return None
+ name = scan.Current()
+ scan.Advance()
+ return Variable(name.lower())
+ elif scan.Current() == '(':
+ scan.Advance()
+ result = ParseLogicalExpression(scan)
+ if (not result) or (scan.Current() != ')'):
+ return None
+ scan.Advance()
+ return result
+ else:
+ return None
+
+
+BINARIES = ['==', '!=']
+def ParseOperatorExpression(scan):
+ left = ParseAtomicExpression(scan)
+ if not left: return None
+ while scan.HasMore() and (scan.Current() in BINARIES):
+ op = scan.Current()
+ scan.Advance()
+ right = ParseOperatorExpression(scan)
+ if not right:
+ return None
+ left = Operation(left, op, right)
+ return left
+
+
+def ParseConditionalExpression(scan):
+ left = ParseOperatorExpression(scan)
+ if not left: return None
+ while scan.HasMore() and (scan.Current() == 'if'):
+ scan.Advance()
+ right = ParseOperatorExpression(scan)
+ if not right:
+ return None
+ left = Operation(left, 'if', right)
+ return left
+
+
+LOGICALS = ["&&", "||", ","]
+def ParseLogicalExpression(scan):
+ left = ParseConditionalExpression(scan)
+ if not left: return None
+ while scan.HasMore() and (scan.Current() in LOGICALS):
+ op = scan.Current()
+ scan.Advance()
+ right = ParseConditionalExpression(scan)
+ if not right:
+ return None
+ left = Operation(left, op, right)
+ return left
+
+
+def ParseCondition(expr):
+ """Parses a logical expression into an Expression object"""
+ tokens = Tokenizer(expr).Tokenize()
+ if not tokens:
+ print "Malformed expression: '%s'" % expr
+ return None
+ scan = Scanner(tokens)
+ ast = ParseLogicalExpression(scan)
+ if not ast:
+ print "Malformed expression: '%s'" % expr
+ return None
+ if scan.HasMore():
+ print "Malformed expression: '%s'" % expr
+ return None
+ return ast
+
+
+class Section(object):
+ """A section of the configuration file. Sections are enabled or
+ disabled prior to running the tests, based on their conditions"""
+
+ def __init__(self, condition):
+ self.condition = condition
+ self.rules = [ ]
+
+ def AddRule(self, rule):
+ self.rules.append(rule)
+
+
+class Rule(object):
+ """A single rule that specifies the expected outcome for a single
+ test."""
+
+ def __init__(self, raw_path, path, value):
+ self.raw_path = raw_path
+ self.path = path
+ self.value = value
+
+ def GetOutcomes(self, env, defs):
+ return self.value.GetOutcomes(env, defs)
+
+ def Contains(self, path):
+ if len(self.path) > len(path):
+ return False
+ for i in xrange(len(self.path)):
+ if not self.path[i].match(path[i]):
+ return False
+ return True
+
+
+HEADER_PATTERN = re.compile(r'\[([^]]+)\]')
+RULE_PATTERN = re.compile(r'\s*([^: ]*)\s*:(.*)')
+DEF_PATTERN = re.compile(r'^def\s*(\w+)\s*=(.*)$')
+PREFIX_PATTERN = re.compile(r'^\s*prefix\s+([\w\_\.\-\/]+)$')
+
+
+class ConvertNotation(object):
+ def __init__(self, path):
+ self.path = path
+ self.indent = ""
+ self.comment = []
+ self.init = False
+ self.section = False
+ self.out = cStringIO.StringIO()
+
+ def OpenGlobal(self):
+ if self.init: return
+ self.WriteComment()
+ print >> self.out, "["
+ self.init = True
+
+ def CloseGlobal(self):
+ if not self.init: return
+ print >> self.out, "]"
+ self.init = False
+
+ def OpenSection(self, condition="ALWAYS"):
+ if self.section: return
+ self.OpenGlobal()
+ if type(condition) != str:
+ condition = "'%s'" % condition.string(True)
+ print >> self.out, "%s[%s, {" % (self.indent, condition)
+ self.indent += " " * 2
+ self.section = condition
+
+ def CloseSection(self):
+ if not self.section: return
+ self.indent = self.indent[:-2]
+ print >> self.out, "%s}], # %s" % (self.indent, self.section)
+ self.section = False
+
+ def WriteComment(self):
+ if not self.comment: return
+ for c in self.comment:
+ if len(c.strip()) == 0:
+ print >> self.out, ""
+ else:
+ print >> self.out, "%s%s" % (self.indent, c),
+ self.comment = []
+
+ def GetOutput(self):
+ with open(self.path) as f:
+ for line in f:
+ if line[0] == '#':
+ self.comment += [line]
+ continue
+ if len(line.strip()) == 0:
+ self.comment += [line]
+ continue
+ header_match = HEADER_PATTERN.match(line)
+ if header_match:
+ condition = ParseCondition(header_match.group(1).strip())
+ self.CloseSection()
+ self.WriteComment()
+ self.OpenSection(condition)
+ continue
+ rule_match = RULE_PATTERN.match(line)
+ if rule_match:
+ self.OpenSection()
+ self.WriteComment()
+ path = rule_match.group(1).strip()
+ value_str = rule_match.group(2).strip()
+ comment = ""
+ if '#' in value_str:
+ pos = value_str.find('#')
+ comment = " %s" % value_str[pos:].strip()
+ value_str = value_str[:pos].strip()
+ value = ParseCondition(value_str)
+ print >> self.out, ("%s'%s': [%s],%s" %
+ (self.indent, path, value, comment))
+ continue
+ def_match = DEF_PATTERN.match(line)
+ if def_match:
+ # Custom definitions are deprecated.
+ continue
+ prefix_match = PREFIX_PATTERN.match(line)
+ if prefix_match:
+ continue
+ print "Malformed line: '%s'." % line
+ self.CloseSection()
+ self.CloseGlobal()
+ result = self.out.getvalue()
+ self.out.close()
+ return result
diff --git a/deps/v8/tools/testrunner/local/progress.py b/deps/v8/tools/testrunner/local/progress.py
new file mode 100644
index 000000000..9075a954f
--- /dev/null
+++ b/deps/v8/tools/testrunner/local/progress.py
@@ -0,0 +1,238 @@
+# Copyright 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.
+
+
+import sys
+import time
+
+def EscapeCommand(command):
+ parts = []
+ for part in command:
+ if ' ' in part:
+ # Escape spaces. We may need to escape more characters for this
+ # to work properly.
+ parts.append('"%s"' % part)
+ else:
+ parts.append(part)
+ return " ".join(parts)
+
+
+class ProgressIndicator(object):
+
+ def __init__(self):
+ self.runner = None
+
+ def Starting(self):
+ pass
+
+ def Done(self):
+ pass
+
+ def AboutToRun(self, test):
+ pass
+
+ def HasRun(self, test):
+ pass
+
+ def PrintFailureHeader(self, test):
+ if test.suite.IsNegativeTest(test):
+ negative_marker = '[negative] '
+ else:
+ negative_marker = ''
+ print "=== %(label)s %(negative)s===" % {
+ 'label': test.GetLabel(),
+ 'negative': negative_marker
+ }
+
+
+class SimpleProgressIndicator(ProgressIndicator):
+ """Abstract base class for {Verbose,Dots}ProgressIndicator"""
+
+ def Starting(self):
+ print 'Running %i tests' % self.runner.total
+
+ def Done(self):
+ print
+ for failed in self.runner.failed:
+ self.PrintFailureHeader(failed)
+ if failed.output.stderr:
+ print "--- stderr ---"
+ print failed.output.stderr.strip()
+ if failed.output.stdout:
+ print "--- stdout ---"
+ print failed.output.stdout.strip()
+ print "Command: %s" % EscapeCommand(self.runner.GetCommand(failed))
+ if failed.output.HasCrashed():
+ print "--- CRASHED ---"
+ if failed.output.HasTimedOut():
+ print "--- TIMEOUT ---"
+ if len(self.runner.failed) == 0:
+ print "==="
+ print "=== All tests succeeded"
+ print "==="
+ else:
+ print
+ print "==="
+ print "=== %i tests failed" % len(self.runner.failed)
+ if self.runner.crashed > 0:
+ print "=== %i tests CRASHED" % self.runner.crashed
+ print "==="
+
+
+class VerboseProgressIndicator(SimpleProgressIndicator):
+
+ def AboutToRun(self, test):
+ print 'Starting %s...' % test.GetLabel()
+ sys.stdout.flush()
+
+ def HasRun(self, test):
+ if test.suite.HasUnexpectedOutput(test):
+ if test.output.HasCrashed():
+ outcome = 'CRASH'
+ else:
+ outcome = 'FAIL'
+ else:
+ outcome = 'pass'
+ print 'Done running %s: %s' % (test.GetLabel(), outcome)
+
+
+class DotsProgressIndicator(SimpleProgressIndicator):
+
+ def HasRun(self, test):
+ total = self.runner.succeeded + len(self.runner.failed)
+ if (total > 1) and (total % 50 == 1):
+ sys.stdout.write('\n')
+ if test.suite.HasUnexpectedOutput(test):
+ if test.output.HasCrashed():
+ sys.stdout.write('C')
+ sys.stdout.flush()
+ elif test.output.HasTimedOut():
+ sys.stdout.write('T')
+ sys.stdout.flush()
+ else:
+ sys.stdout.write('F')
+ sys.stdout.flush()
+ else:
+ sys.stdout.write('.')
+ sys.stdout.flush()
+
+
+class CompactProgressIndicator(ProgressIndicator):
+ """Abstract base class for {Color,Monochrome}ProgressIndicator"""
+
+ def __init__(self, templates):
+ super(CompactProgressIndicator, self).__init__()
+ self.templates = templates
+ self.last_status_length = 0
+ self.start_time = time.time()
+
+ def Done(self):
+ self.PrintProgress('Done')
+ print "" # Line break.
+
+ def AboutToRun(self, test):
+ self.PrintProgress(test.GetLabel())
+
+ def HasRun(self, test):
+ if test.suite.HasUnexpectedOutput(test):
+ self.ClearLine(self.last_status_length)
+ self.PrintFailureHeader(test)
+ stdout = test.output.stdout.strip()
+ if len(stdout):
+ print self.templates['stdout'] % stdout
+ stderr = test.output.stderr.strip()
+ if len(stderr):
+ print self.templates['stderr'] % stderr
+ print "Command: %s" % EscapeCommand(self.runner.GetCommand(test))
+ if test.output.HasCrashed():
+ print "exit code: %d" % test.output.exit_code
+ print "--- CRASHED ---"
+ if test.output.HasTimedOut():
+ print "--- TIMEOUT ---"
+
+ def Truncate(self, string, length):
+ if length and (len(string) > (length - 3)):
+ return string[:(length - 3)] + "..."
+ else:
+ return string
+
+ def PrintProgress(self, name):
+ self.ClearLine(self.last_status_length)
+ elapsed = time.time() - self.start_time
+ status = self.templates['status_line'] % {
+ 'passed': self.runner.succeeded,
+ 'remaining': (((self.runner.total - self.runner.remaining) * 100) //
+ self.runner.total),
+ 'failed': len(self.runner.failed),
+ 'test': name,
+ 'mins': int(elapsed) / 60,
+ 'secs': int(elapsed) % 60
+ }
+ status = self.Truncate(status, 78)
+ self.last_status_length = len(status)
+ print status,
+ sys.stdout.flush()
+
+
+class ColorProgressIndicator(CompactProgressIndicator):
+
+ def __init__(self):
+ templates = {
+ 'status_line': ("[%(mins)02i:%(secs)02i|"
+ "\033[34m%%%(remaining) 4d\033[0m|"
+ "\033[32m+%(passed) 4d\033[0m|"
+ "\033[31m-%(failed) 4d\033[0m]: %(test)s"),
+ 'stdout': "\033[1m%s\033[0m",
+ 'stderr': "\033[31m%s\033[0m",
+ }
+ super(ColorProgressIndicator, self).__init__(templates)
+
+ def ClearLine(self, last_line_length):
+ print "\033[1K\r",
+
+
+class MonochromeProgressIndicator(CompactProgressIndicator):
+
+ def __init__(self):
+ templates = {
+ 'status_line': ("[%(mins)02i:%(secs)02i|%%%(remaining) 4d|"
+ "+%(passed) 4d|-%(failed) 4d]: %(test)s"),
+ 'stdout': '%s',
+ 'stderr': '%s',
+ }
+ super(MonochromeProgressIndicator, self).__init__(templates)
+
+ def ClearLine(self, last_line_length):
+ print ("\r" + (" " * last_line_length) + "\r"),
+
+
+PROGRESS_INDICATORS = {
+ 'verbose': VerboseProgressIndicator,
+ 'dots': DotsProgressIndicator,
+ 'color': ColorProgressIndicator,
+ 'mono': MonochromeProgressIndicator
+}
diff --git a/deps/v8/tools/testrunner/local/statusfile.py b/deps/v8/tools/testrunner/local/statusfile.py
new file mode 100644
index 000000000..bf1de45f6
--- /dev/null
+++ b/deps/v8/tools/testrunner/local/statusfile.py
@@ -0,0 +1,145 @@
+# Copyright 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.
+
+
+# These imports are required for the on-demand conversion from
+# old to new status file format.
+from os.path import exists
+from os.path import getmtime
+
+from . import old_statusfile
+
+
+# These outcomes can occur in a TestCase's outcomes list:
+SKIP = "SKIP"
+FAIL = "FAIL"
+PASS = "PASS"
+OKAY = "OKAY"
+TIMEOUT = "TIMEOUT"
+CRASH = "CRASH"
+SLOW = "SLOW"
+# These are just for the status files and are mapped below in DEFS:
+FAIL_OK = "FAIL_OK"
+PASS_OR_FAIL = "PASS_OR_FAIL"
+
+ALWAYS = "ALWAYS"
+
+KEYWORDS = {}
+for key in [SKIP, FAIL, PASS, OKAY, TIMEOUT, CRASH, SLOW, FAIL_OK,
+ PASS_OR_FAIL, ALWAYS]:
+ KEYWORDS[key] = key
+
+DEFS = {FAIL_OK: [FAIL, OKAY],
+ PASS_OR_FAIL: [PASS, FAIL]}
+
+# Support arches, modes to be written as keywords instead of strings.
+VARIABLES = {ALWAYS: True}
+for var in ["debug", "release", "android_arm", "android_ia32", "arm", "ia32",
+ "mipsel", "x64"]:
+ VARIABLES[var] = var
+
+
+def DoSkip(outcomes):
+ return SKIP in outcomes or SLOW in outcomes
+
+
+def IsFlaky(outcomes):
+ return ((PASS in outcomes) and (FAIL in outcomes) and
+ (not CRASH in outcomes) and (not OKAY in outcomes))
+
+
+def IsFailOk(outcomes):
+ return (FAIL in outcomes) and (OKAY in outcomes)
+
+
+def _AddOutcome(result, new):
+ global DEFS
+ if new in DEFS:
+ mapped = DEFS[new]
+ if type(mapped) == list:
+ for m in mapped:
+ _AddOutcome(result, m)
+ elif type(mapped) == str:
+ _AddOutcome(result, mapped)
+ else:
+ result.add(new)
+
+
+def _ParseOutcomeList(rule, outcomes, target_dict, variables):
+ result = set([])
+ if type(outcomes) == str:
+ outcomes = [outcomes]
+ for item in outcomes:
+ if type(item) == str:
+ _AddOutcome(result, item)
+ elif type(item) == list:
+ if not eval(item[0], variables): continue
+ for outcome in item[1:]:
+ assert type(outcome) == str
+ _AddOutcome(result, outcome)
+ else:
+ assert False
+ if len(result) == 0: return
+ if rule in target_dict:
+ target_dict[rule] |= result
+ else:
+ target_dict[rule] = result
+
+
+def ReadStatusFile(path, variables):
+ # As long as the old-format .status files are authoritative, just
+ # create the converted version on demand and cache it to speed up
+ # subsequent runs.
+ if path.endswith(".status"):
+ newpath = path + "2"
+ if not exists(newpath) or getmtime(newpath) < getmtime(path):
+ print "Converting status file."
+ converted = old_statusfile.ConvertNotation(path).GetOutput()
+ with open(newpath, 'w') as f:
+ f.write(converted)
+ path = newpath
+
+ with open(path) as f:
+ global KEYWORDS
+ contents = eval(f.read(), KEYWORDS)
+
+ rules = {}
+ wildcards = {}
+ variables.update(VARIABLES)
+ for section in contents:
+ assert type(section) == list
+ assert len(section) == 2
+ if not eval(section[0], variables): continue
+ section = section[1]
+ assert type(section) == dict
+ for rule in section:
+ assert type(rule) == str
+ if rule[-1] == '*':
+ _ParseOutcomeList(rule, section[rule], wildcards, variables)
+ else:
+ _ParseOutcomeList(rule, section[rule], rules, variables)
+ return rules, wildcards
diff --git a/deps/v8/tools/testrunner/local/testsuite.py b/deps/v8/tools/testrunner/local/testsuite.py
new file mode 100644
index 000000000..de5cddd11
--- /dev/null
+++ b/deps/v8/tools/testrunner/local/testsuite.py
@@ -0,0 +1,184 @@
+# Copyright 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.
+
+
+import imp
+import os
+
+from . import statusfile
+
+class TestSuite(object):
+
+ @staticmethod
+ def LoadTestSuite(root):
+ name = root.split(os.path.sep)[-1]
+ f = None
+ try:
+ (f, pathname, description) = imp.find_module("testcfg", [root])
+ module = imp.load_module("testcfg", f, pathname, description)
+ suite = module.GetSuite(name, root)
+ finally:
+ if f:
+ f.close()
+ return suite
+
+ def __init__(self, name, root):
+ self.name = name # string
+ self.root = root # string containing path
+ self.tests = None # list of TestCase objects
+ self.rules = None # dictionary mapping test path to list of outcomes
+ self.wildcards = None # dictionary mapping test paths to list of outcomes
+ self.total_duration = None # float, assigned on demand
+
+ def shell(self):
+ return "d8"
+
+ def suffix(self):
+ return ".js"
+
+ def status_file(self):
+ return "%s/%s.status" % (self.root, self.name)
+
+ # Used in the status file and for stdout printing.
+ def CommonTestName(self, testcase):
+ return testcase.path
+
+ def ListTests(self, context):
+ raise NotImplementedError
+
+ def VariantFlags(self):
+ return None
+
+ def DownloadData(self):
+ pass
+
+ def ReadStatusFile(self, variables):
+ (self.rules, self.wildcards) = \
+ statusfile.ReadStatusFile(self.status_file(), variables)
+
+ def ReadTestCases(self, context):
+ self.tests = self.ListTests(context)
+
+ def FilterTestCasesByStatus(self, warn_unused_rules):
+ filtered = []
+ used_rules = set()
+ for t in self.tests:
+ testname = self.CommonTestName(t)
+ if testname in self.rules:
+ used_rules.add(testname)
+ outcomes = self.rules[testname]
+ t.outcomes = outcomes # Even for skipped tests, as the TestCase
+ # object stays around and PrintReport() uses it.
+ if statusfile.DoSkip(outcomes):
+ continue # Don't add skipped tests to |filtered|.
+ if len(self.wildcards) != 0:
+ skip = False
+ for rule in self.wildcards:
+ assert rule[-1] == '*'
+ if testname.startswith(rule[:-1]):
+ used_rules.add(rule)
+ outcomes = self.wildcards[rule]
+ t.outcomes = outcomes
+ if statusfile.DoSkip(outcomes):
+ skip = True
+ break # "for rule in self.wildcards"
+ if skip: continue # "for t in self.tests"
+ filtered.append(t)
+ self.tests = filtered
+
+ if not warn_unused_rules:
+ return
+
+ for rule in self.rules:
+ if rule not in used_rules:
+ print("Unused rule: %s -> %s" % (rule, self.rules[rule]))
+ for rule in self.wildcards:
+ if rule not in used_rules:
+ print("Unused rule: %s -> %s" % (rule, self.wildcards[rule]))
+
+ def FilterTestCasesByArgs(self, args):
+ filtered = []
+ filtered_args = []
+ for a in args:
+ argpath = a.split(os.path.sep)
+ if argpath[0] != self.name:
+ continue
+ if len(argpath) == 1 or (len(argpath) == 2 and argpath[1] == '*'):
+ return # Don't filter, run all tests in this suite.
+ path = os.path.sep.join(argpath[1:])
+ if path[-1] == '*':
+ path = path[:-1]
+ filtered_args.append(path)
+ for t in self.tests:
+ for a in filtered_args:
+ if t.path.startswith(a):
+ filtered.append(t)
+ break
+ self.tests = filtered
+
+ def GetFlagsForTestCase(self, testcase, context):
+ raise NotImplementedError
+
+ def GetSourceForTest(self, testcase):
+ return "(no source available)"
+
+ def IsFailureOutput(self, output, testpath):
+ return output.exit_code != 0
+
+ def IsNegativeTest(self, testcase):
+ return False
+
+ def HasFailed(self, testcase):
+ execution_failed = self.IsFailureOutput(testcase.output, testcase.path)
+ if self.IsNegativeTest(testcase):
+ return not execution_failed
+ else:
+ return execution_failed
+
+ def HasUnexpectedOutput(self, testcase):
+ if testcase.output.HasCrashed():
+ outcome = statusfile.CRASH
+ elif testcase.output.HasTimedOut():
+ outcome = statusfile.TIMEOUT
+ elif self.HasFailed(testcase):
+ outcome = statusfile.FAIL
+ else:
+ outcome = statusfile.PASS
+ if not testcase.outcomes:
+ return outcome != statusfile.PASS
+ return not outcome in testcase.outcomes
+
+ def StripOutputForTransmit(self, testcase):
+ if not self.HasUnexpectedOutput(testcase):
+ testcase.output.stdout = ""
+ testcase.output.stderr = ""
+
+ def CalculateTotalDuration(self):
+ self.total_duration = 0.0
+ for t in self.tests:
+ self.total_duration += t.duration
+ return self.total_duration
diff --git a/deps/v8/tools/testrunner/local/utils.py b/deps/v8/tools/testrunner/local/utils.py
new file mode 100644
index 000000000..b7caa121f
--- /dev/null
+++ b/deps/v8/tools/testrunner/local/utils.py
@@ -0,0 +1,108 @@
+# Copyright 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.
+
+
+import os
+from os.path import exists
+from os.path import isdir
+from os.path import join
+import platform
+import re
+
+
+def GetSuitePaths(test_root):
+ def IsSuite(path):
+ return isdir(path) and exists(join(path, 'testcfg.py'))
+ return [ f for f in os.listdir(test_root) if IsSuite(join(test_root, f)) ]
+
+
+# Reads a file into an array of strings
+def ReadLinesFrom(name):
+ lines = []
+ with open(name) as f:
+ for line in f:
+ if line.startswith('#'): continue
+ if '#' in line:
+ line = line[:line.find('#')]
+ line = line.strip()
+ if not line: continue
+ lines.append(line)
+ return lines
+
+
+def GuessOS():
+ system = platform.system()
+ if system == 'Linux':
+ return 'linux'
+ elif system == 'Darwin':
+ return 'macos'
+ elif system.find('CYGWIN') >= 0:
+ return 'cygwin'
+ elif system == 'Windows' or system == 'Microsoft':
+ # On Windows Vista platform.system() can return 'Microsoft' with some
+ # versions of Python, see http://bugs.python.org/issue1082
+ return 'win32'
+ elif system == 'FreeBSD':
+ return 'freebsd'
+ elif system == 'OpenBSD':
+ return 'openbsd'
+ elif system == 'SunOS':
+ return 'solaris'
+ elif system == 'NetBSD':
+ return 'netbsd'
+ else:
+ return None
+
+
+# This will default to building the 32 bit VM even on machines that are
+# capable of running the 64 bit VM.
+def DefaultArch():
+ machine = platform.machine()
+ machine = machine.lower() # Windows 7 capitalizes 'AMD64'.
+ if machine.startswith('arm'):
+ return 'arm'
+ elif (not machine) or (not re.match('(x|i[3-6])86$', machine) is None):
+ return 'ia32'
+ elif machine == 'i86pc':
+ return 'ia32'
+ elif machine == 'x86_64':
+ return 'ia32'
+ elif machine == 'amd64':
+ return 'ia32'
+ else:
+ return None
+
+
+def GuessWordsize():
+ if '64' in platform.machine():
+ return '64'
+ else:
+ return '32'
+
+
+def IsWindows():
+ return GuessOS() == 'win32'
diff --git a/deps/v8/tools/testrunner/local/verbose.py b/deps/v8/tools/testrunner/local/verbose.py
new file mode 100644
index 000000000..f69346752
--- /dev/null
+++ b/deps/v8/tools/testrunner/local/verbose.py
@@ -0,0 +1,99 @@
+# Copyright 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.
+
+
+import sys
+import time
+
+from . import statusfile
+
+
+REPORT_TEMPLATE = (
+"""Total: %(total)i tests
+ * %(skipped)4d tests will be skipped
+ * %(timeout)4d tests are expected to timeout sometimes
+ * %(nocrash)4d tests are expected to be flaky but not crash
+ * %(pass)4d tests are expected to pass
+ * %(fail_ok)4d tests are expected to fail that we won't fix
+ * %(fail)4d tests are expected to fail that we should fix""")
+
+
+def PrintReport(tests):
+ total = len(tests)
+ skipped = timeout = nocrash = passes = fail_ok = fail = 0
+ for t in tests:
+ if "outcomes" not in dir(t) or not t.outcomes:
+ passes += 1
+ continue
+ o = t.outcomes
+ if statusfile.DoSkip(o):
+ skipped += 1
+ continue
+ if statusfile.TIMEOUT in o: timeout += 1
+ if statusfile.IsFlaky(o): nocrash += 1
+ if list(o) == [statusfile.PASS]: passes += 1
+ if statusfile.IsFailOk(o): fail_ok += 1
+ if list(o) == [statusfile.FAIL]: fail += 1
+ print REPORT_TEMPLATE % {
+ "total": total,
+ "skipped": skipped,
+ "timeout": timeout,
+ "nocrash": nocrash,
+ "pass": passes,
+ "fail_ok": fail_ok,
+ "fail": fail
+ }
+
+
+def PrintTestSource(tests):
+ for test in tests:
+ suite = test.suite
+ source = suite.GetSourceForTest(test).strip()
+ if len(source) > 0:
+ print "--- begin source: %s/%s ---" % (suite.name, test.path)
+ print source
+ print "--- end source: %s/%s ---" % (suite.name, test.path)
+
+
+def FormatTime(d):
+ millis = round(d * 1000) % 1000
+ return time.strftime("%M:%S.", time.gmtime(d)) + ("%03i" % millis)
+
+
+def PrintTestDurations(suites, overall_time):
+ # Write the times to stderr to make it easy to separate from the
+ # test output.
+ print
+ sys.stderr.write("--- Total time: %s ---\n" % FormatTime(overall_time))
+ timed_tests = [ t for s in suites for t in s.tests
+ if t.duration is not None ]
+ timed_tests.sort(lambda a, b: cmp(b.duration, a.duration))
+ index = 1
+ for entry in timed_tests[:20]:
+ t = FormatTime(entry.duration)
+ sys.stderr.write("%4i (%s) %s\n" % (index, t, entry.GetLabel()))
+ index += 1
diff --git a/deps/v8/tools/testrunner/network/__init__.py b/deps/v8/tools/testrunner/network/__init__.py
new file mode 100644
index 000000000..202a26270
--- /dev/null
+++ b/deps/v8/tools/testrunner/network/__init__.py
@@ -0,0 +1,26 @@
+# Copyright 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.
diff --git a/deps/v8/tools/testrunner/network/distro.py b/deps/v8/tools/testrunner/network/distro.py
new file mode 100644
index 000000000..9d5a471d4
--- /dev/null
+++ b/deps/v8/tools/testrunner/network/distro.py
@@ -0,0 +1,90 @@
+# Copyright 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.
+
+
+class Shell(object):
+ def __init__(self, shell):
+ self.shell = shell
+ self.tests = []
+ self.total_duration = 0.0
+
+ def AddSuite(self, suite):
+ self.tests += suite.tests
+ self.total_duration += suite.total_duration
+
+ def SortTests(self):
+ self.tests.sort(cmp=lambda x, y: cmp(x.duration, y.duration))
+
+
+def Assign(suites, peers):
+ total_work = 0.0
+ for s in suites:
+ total_work += s.CalculateTotalDuration()
+
+ total_power = 0.0
+ for p in peers:
+ p.assigned_work = 0.0
+ total_power += p.jobs * p.relative_performance
+ for p in peers:
+ p.needed_work = total_work * p.jobs * p.relative_performance / total_power
+
+ shells = {}
+ for s in suites:
+ shell = s.shell()
+ if not shell in shells:
+ shells[shell] = Shell(shell)
+ shells[shell].AddSuite(s)
+ # Convert |shells| to list and sort it, shortest total_duration first.
+ shells = [ shells[s] for s in shells ]
+ shells.sort(cmp=lambda x, y: cmp(x.total_duration, y.total_duration))
+ # Sort tests within each shell, longest duration last (so it's
+ # pop()'ed first).
+ for s in shells: s.SortTests()
+ # Sort peers, least needed_work first.
+ peers.sort(cmp=lambda x, y: cmp(x.needed_work, y.needed_work))
+ index = 0
+ for shell in shells:
+ while len(shell.tests) > 0:
+ while peers[index].needed_work <= 0:
+ index += 1
+ if index == len(peers):
+ print("BIG FAT WARNING: Assigning tests to peers failed. "
+ "Remaining tests: %d. Going to slow mode." % len(shell.tests))
+ # Pick the least-busy peer. Sorting the list for each test
+ # is terribly slow, but this is just an emergency fallback anyway.
+ peers.sort(cmp=lambda x, y: cmp(x.needed_work, y.needed_work))
+ peers[0].ForceAddOneTest(shell.tests.pop(), shell)
+ # If the peer already has a shell assigned and would need this one
+ # and then yet another, try to avoid it.
+ peer = peers[index]
+ if (shell.total_duration < peer.needed_work and
+ len(peer.shells) > 0 and
+ index < len(peers) - 1 and
+ shell.total_duration <= peers[index + 1].needed_work):
+ peers[index + 1].AddTests(shell)
+ else:
+ peer.AddTests(shell)
diff --git a/deps/v8/tools/testrunner/network/endpoint.py b/deps/v8/tools/testrunner/network/endpoint.py
new file mode 100644
index 000000000..5dc2b9f90
--- /dev/null
+++ b/deps/v8/tools/testrunner/network/endpoint.py
@@ -0,0 +1,124 @@
+# Copyright 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.
+
+
+import multiprocessing
+import os
+import Queue
+import threading
+import time
+
+from ..local import execution
+from ..local import progress
+from ..local import testsuite
+from ..local import utils
+from ..server import compression
+
+
+class EndpointProgress(progress.ProgressIndicator):
+ def __init__(self, sock, server, ctx):
+ super(EndpointProgress, self).__init__()
+ self.sock = sock
+ self.server = server
+ self.context = ctx
+ self.results_queue = [] # Accessors must synchronize themselves.
+ self.sender_lock = threading.Lock()
+ self.senderthread = threading.Thread(target=self._SenderThread)
+ self.senderthread.start()
+
+ def HasRun(self, test):
+ # The runners that call this have a lock anyway, so this is safe.
+ self.results_queue.append(test)
+
+ def _SenderThread(self):
+ keep_running = True
+ tests = []
+ self.sender_lock.acquire()
+ while keep_running:
+ time.sleep(0.1)
+ # This should be "atomic enough" without locking :-)
+ # (We don't care which list any new elements get appended to, as long
+ # as we don't lose any and the last one comes last.)
+ current = self.results_queue
+ self.results_queue = []
+ for c in current:
+ if c is None:
+ keep_running = False
+ else:
+ tests.append(c)
+ if keep_running and len(tests) < 1:
+ continue # Wait for more results.
+ if len(tests) < 1: break # We're done here.
+ result = []
+ for t in tests:
+ result.append(t.PackResult())
+ try:
+ compression.Send(result, self.sock)
+ except:
+ self.runner.terminate = True
+ for t in tests:
+ self.server.CompareOwnPerf(t, self.context.arch, self.context.mode)
+ tests = []
+ self.sender_lock.release()
+
+
+def Execute(workspace, ctx, tests, sock, server):
+ suite_paths = utils.GetSuitePaths(os.path.join(workspace, "test"))
+ suites = []
+ for root in suite_paths:
+ suite = testsuite.TestSuite.LoadTestSuite(
+ os.path.join(workspace, "test", root))
+ if suite:
+ suites.append(suite)
+
+ suites_dict = {}
+ for s in suites:
+ suites_dict[s.name] = s
+ s.tests = []
+ for t in tests:
+ suite = suites_dict[t.suite]
+ t.suite = suite
+ suite.tests.append(t)
+
+ suites = [ s for s in suites if len(s.tests) > 0 ]
+ for s in suites:
+ s.DownloadData()
+
+ progress_indicator = EndpointProgress(sock, server, ctx)
+ runner = execution.Runner(suites, progress_indicator, ctx)
+ try:
+ runner.Run(server.jobs)
+ except IOError, e:
+ if e.errno == 2:
+ message = ("File not found: %s, maybe you forgot to 'git add' it?" %
+ e.filename)
+ else:
+ message = "%s" % e
+ compression.Send([[-1, message]], sock)
+ progress_indicator.HasRun(None) # Sentinel to signal the end.
+ progress_indicator.sender_lock.acquire() # Released when sending is done.
+ progress_indicator.sender_lock.release()
diff --git a/deps/v8/tools/testrunner/network/network_execution.py b/deps/v8/tools/testrunner/network/network_execution.py
new file mode 100644
index 000000000..ddb59e60b
--- /dev/null
+++ b/deps/v8/tools/testrunner/network/network_execution.py
@@ -0,0 +1,253 @@
+# Copyright 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.
+
+
+import os
+import socket
+import subprocess
+import threading
+import time
+
+from . import distro
+from . import perfdata
+from ..local import execution
+from ..objects import peer
+from ..objects import workpacket
+from ..server import compression
+from ..server import constants
+from ..server import local_handler
+from ..server import signatures
+
+
+def GetPeers():
+ data = local_handler.LocalQuery([constants.REQUEST_PEERS])
+ if not data: return []
+ return [ peer.Peer.Unpack(p) for p in data ]
+
+
+class NetworkedRunner(execution.Runner):
+ def __init__(self, suites, progress_indicator, context, peers, workspace):
+ self.suites = suites
+ num_tests = 0
+ datapath = os.path.join("out", "testrunner_data")
+ self.perf_data_manager = perfdata.PerfDataManager(datapath)
+ self.perfdata = self.perf_data_manager.GetStore(context.arch, context.mode)
+ for s in suites:
+ for t in s.tests:
+ t.duration = self.perfdata.FetchPerfData(t) or 1.0
+ num_tests += len(s.tests)
+ self._CommonInit(num_tests, progress_indicator, context)
+ self.tests = [] # Only used if we need to fall back to local execution.
+ self.tests_lock = threading.Lock()
+ self.peers = peers
+ self.pubkey_fingerprint = None # Fetched later.
+ self.base_rev = subprocess.check_output(
+ "cd %s; git log -1 --format=%%H --grep=git-svn-id" % workspace,
+ shell=True).strip()
+ self.base_svn_rev = subprocess.check_output(
+ "cd %s; git log -1 %s" # Get commit description.
+ " | grep -e '^\s*git-svn-id:'" # Extract "git-svn-id" line.
+ " | awk '{print $2}'" # Extract "repository@revision" part.
+ " | sed -e 's/.*@//'" % # Strip away "repository@".
+ (workspace, self.base_rev), shell=True).strip()
+ self.patch = subprocess.check_output(
+ "cd %s; git diff %s" % (workspace, self.base_rev), shell=True)
+ self.binaries = {}
+ self.initialization_lock = threading.Lock()
+ self.initialization_lock.acquire() # Released when init is done.
+ self._OpenLocalConnection()
+ self.local_receiver_thread = threading.Thread(
+ target=self._ListenLocalConnection)
+ self.local_receiver_thread.daemon = True
+ self.local_receiver_thread.start()
+ self.initialization_lock.acquire()
+ self.initialization_lock.release()
+
+ def _OpenLocalConnection(self):
+ self.local_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ code = self.local_socket.connect_ex(("localhost", constants.CLIENT_PORT))
+ if code != 0:
+ raise RuntimeError("Failed to connect to local server")
+ compression.Send([constants.REQUEST_PUBKEY_FINGERPRINT], self.local_socket)
+
+ def _ListenLocalConnection(self):
+ release_lock_countdown = 1 # Pubkey.
+ self.local_receiver = compression.Receiver(self.local_socket)
+ while not self.local_receiver.IsDone():
+ data = self.local_receiver.Current()
+ if data[0] == constants.REQUEST_PUBKEY_FINGERPRINT:
+ pubkey = data[1]
+ if not pubkey: raise RuntimeError("Received empty public key")
+ self.pubkey_fingerprint = pubkey
+ release_lock_countdown -= 1
+ if release_lock_countdown == 0:
+ self.initialization_lock.release()
+ release_lock_countdown -= 1 # Prevent repeated triggering.
+ self.local_receiver.Advance()
+
+ def Run(self, jobs):
+ self.indicator.Starting()
+ need_libv8 = False
+ for s in self.suites:
+ shell = s.shell()
+ if shell not in self.binaries:
+ path = os.path.join(self.context.shell_dir, shell)
+ # Check if this is a shared library build.
+ try:
+ ldd = subprocess.check_output("ldd %s | grep libv8\\.so" % (path),
+ shell=True)
+ ldd = ldd.strip().split(" ")
+ assert ldd[0] == "libv8.so"
+ assert ldd[1] == "=>"
+ need_libv8 = True
+ binary_needs_libv8 = True
+ libv8 = signatures.ReadFileAndSignature(ldd[2])
+ except:
+ binary_needs_libv8 = False
+ binary = signatures.ReadFileAndSignature(path)
+ if binary[0] is None:
+ print("Error: Failed to create signature.")
+ assert binary[1] != 0
+ return binary[1]
+ binary.append(binary_needs_libv8)
+ self.binaries[shell] = binary
+ if need_libv8:
+ self.binaries["libv8.so"] = libv8
+ distro.Assign(self.suites, self.peers)
+ # Spawn one thread for each peer.
+ threads = []
+ for p in self.peers:
+ thread = threading.Thread(target=self._TalkToPeer, args=[p])
+ threads.append(thread)
+ thread.start()
+ try:
+ for thread in threads:
+ # Use a timeout so that signals (Ctrl+C) will be processed.
+ thread.join(timeout=10000000)
+ self._AnalyzePeerRuntimes()
+ except KeyboardInterrupt:
+ self.terminate = True
+ raise
+ except Exception, _e:
+ # If there's an exception we schedule an interruption for any
+ # remaining threads...
+ self.terminate = True
+ # ...and then reraise the exception to bail out.
+ raise
+ compression.Send(constants.END_OF_STREAM, self.local_socket)
+ self.local_socket.close()
+ if self.tests:
+ self._RunInternal(jobs)
+ self.indicator.Done()
+ return not self.failed
+
+ def _TalkToPeer(self, peer):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.settimeout(self.context.timeout + 10)
+ code = sock.connect_ex((peer.address, constants.PEER_PORT))
+ if code == 0:
+ try:
+ peer.runtime = None
+ start_time = time.time()
+ packet = workpacket.WorkPacket(peer=peer, context=self.context,
+ base_revision=self.base_svn_rev,
+ patch=self.patch,
+ pubkey=self.pubkey_fingerprint)
+ data, test_map = packet.Pack(self.binaries)
+ compression.Send(data, sock)
+ compression.Send(constants.END_OF_STREAM, sock)
+ rec = compression.Receiver(sock)
+ while not rec.IsDone() and not self.terminate:
+ data_list = rec.Current()
+ for data in data_list:
+ test_id = data[0]
+ if test_id < 0:
+ # The peer is reporting an error.
+ with self.lock:
+ print("\nPeer %s reports error: %s" % (peer.address, data[1]))
+ continue
+ test = test_map.pop(test_id)
+ test.MergeResult(data)
+ try:
+ self.perfdata.UpdatePerfData(test)
+ except Exception, e:
+ print("UpdatePerfData exception: %s" % e)
+ pass # Just keep working.
+ with self.lock:
+ perf_key = self.perfdata.GetKey(test)
+ compression.Send(
+ [constants.INFORM_DURATION, perf_key, test.duration,
+ self.context.arch, self.context.mode],
+ self.local_socket)
+ self.indicator.AboutToRun(test)
+ if test.suite.HasUnexpectedOutput(test):
+ self.failed.append(test)
+ if test.output.HasCrashed():
+ self.crashed += 1
+ else:
+ self.succeeded += 1
+ self.remaining -= 1
+ self.indicator.HasRun(test)
+ rec.Advance()
+ peer.runtime = time.time() - start_time
+ except KeyboardInterrupt:
+ sock.close()
+ raise
+ except Exception, e:
+ print("Got exception: %s" % e)
+ pass # Fall back to local execution.
+ else:
+ compression.Send([constants.UNRESPONSIVE_PEER, peer.address],
+ self.local_socket)
+ sock.close()
+ if len(test_map) > 0:
+ # Some tests have not received any results. Run them locally.
+ print("\nNo results for %d tests, running them locally." % len(test_map))
+ self._EnqueueLocally(test_map)
+
+ def _EnqueueLocally(self, test_map):
+ with self.tests_lock:
+ for test in test_map:
+ self.tests.append(test_map[test])
+
+ def _AnalyzePeerRuntimes(self):
+ total_runtime = 0.0
+ total_work = 0.0
+ for p in self.peers:
+ if p.runtime is None:
+ return
+ total_runtime += p.runtime
+ total_work += p.assigned_work
+ for p in self.peers:
+ p.assigned_work /= total_work
+ p.runtime /= total_runtime
+ perf_correction = p.assigned_work / p.runtime
+ old_perf = p.relative_performance
+ p.relative_performance = (old_perf + perf_correction) / 2.0
+ compression.Send([constants.UPDATE_PERF, p.address,
+ p.relative_performance],
+ self.local_socket)
diff --git a/deps/v8/tools/testrunner/network/perfdata.py b/deps/v8/tools/testrunner/network/perfdata.py
new file mode 100644
index 000000000..2979dc486
--- /dev/null
+++ b/deps/v8/tools/testrunner/network/perfdata.py
@@ -0,0 +1,120 @@
+# Copyright 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.
+
+
+import os
+import shelve
+import threading
+
+
+class PerfDataEntry(object):
+ def __init__(self):
+ self.avg = 0.0
+ self.count = 0
+
+ def AddResult(self, result):
+ kLearnRateLimiter = 99 # Greater value means slower learning.
+ # We use an approximation of the average of the last 100 results here:
+ # The existing average is weighted with kLearnRateLimiter (or less
+ # if there are fewer data points).
+ effective_count = min(self.count, kLearnRateLimiter)
+ self.avg = self.avg * effective_count + result
+ self.count = effective_count + 1
+ self.avg /= self.count
+
+
+class PerfDataStore(object):
+ def __init__(self, datadir, arch, mode):
+ filename = os.path.join(datadir, "%s.%s.perfdata" % (arch, mode))
+ self.database = shelve.open(filename, protocol=2)
+ self.closed = False
+ self.lock = threading.Lock()
+
+ def __del__(self):
+ self.close()
+
+ def close(self):
+ if self.closed: return
+ self.database.close()
+ self.closed = True
+
+ def GetKey(self, test):
+ """Computes the key used to access data for the given testcase."""
+ flags = "".join(test.flags)
+ return str("%s.%s.%s" % (test.suitename(), test.path, flags))
+
+ def FetchPerfData(self, test):
+ """Returns the observed duration for |test| as read from the store."""
+ key = self.GetKey(test)
+ if key in self.database:
+ return self.database[key].avg
+ return None
+
+ def UpdatePerfData(self, test):
+ """Updates the persisted value in the store with test.duration."""
+ testkey = self.GetKey(test)
+ self.RawUpdatePerfData(testkey, test.duration)
+
+ def RawUpdatePerfData(self, testkey, duration):
+ with self.lock:
+ if testkey in self.database:
+ entry = self.database[testkey]
+ else:
+ entry = PerfDataEntry()
+ entry.AddResult(duration)
+ self.database[testkey] = entry
+
+
+class PerfDataManager(object):
+ def __init__(self, datadir):
+ self.datadir = os.path.abspath(datadir)
+ if not os.path.exists(self.datadir):
+ os.makedirs(self.datadir)
+ self.stores = {} # Keyed by arch, then mode.
+ self.closed = False
+ self.lock = threading.Lock()
+
+ def __del__(self):
+ self.close()
+
+ def close(self):
+ if self.closed: return
+ for arch in self.stores:
+ modes = self.stores[arch]
+ for mode in modes:
+ store = modes[mode]
+ store.close()
+ self.closed = True
+
+ def GetStore(self, arch, mode):
+ with self.lock:
+ if not arch in self.stores:
+ self.stores[arch] = {}
+ modes = self.stores[arch]
+ if not mode in modes:
+ modes[mode] = PerfDataStore(self.datadir, arch, mode)
+ return modes[mode]
diff --git a/deps/v8/tools/testrunner/objects/__init__.py b/deps/v8/tools/testrunner/objects/__init__.py
new file mode 100644
index 000000000..202a26270
--- /dev/null
+++ b/deps/v8/tools/testrunner/objects/__init__.py
@@ -0,0 +1,26 @@
+# Copyright 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.
diff --git a/deps/v8/tools/testrunner/objects/context.py b/deps/v8/tools/testrunner/objects/context.py
new file mode 100644
index 000000000..b72284b64
--- /dev/null
+++ b/deps/v8/tools/testrunner/objects/context.py
@@ -0,0 +1,50 @@
+# Copyright 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.
+
+
+class Context():
+ def __init__(self, arch, mode, shell_dir, mode_flags, verbose, timeout,
+ isolates, command_prefix, extra_flags):
+ self.arch = arch
+ self.mode = mode
+ self.shell_dir = shell_dir
+ self.mode_flags = mode_flags
+ self.verbose = verbose
+ self.timeout = timeout
+ self.isolates = isolates
+ self.command_prefix = command_prefix
+ self.extra_flags = extra_flags
+
+ def Pack(self):
+ return [self.arch, self.mode, self.mode_flags, self.timeout, self.isolates,
+ self.extra_flags]
+
+ @staticmethod
+ def Unpack(packed):
+ # For the order of the fields, refer to Pack() above.
+ return Context(packed[0], packed[1], None, packed[2], False,
+ packed[3], packed[4], "", packed[5])
diff --git a/deps/v8/tools/testrunner/objects/output.py b/deps/v8/tools/testrunner/objects/output.py
new file mode 100644
index 000000000..87b4c84e1
--- /dev/null
+++ b/deps/v8/tools/testrunner/objects/output.py
@@ -0,0 +1,60 @@
+# Copyright 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.
+
+
+import signal
+
+from ..local import utils
+
+class Output(object):
+
+ def __init__(self, exit_code, timed_out, stdout, stderr):
+ self.exit_code = exit_code
+ self.timed_out = timed_out
+ self.stdout = stdout
+ self.stderr = stderr
+
+ def HasCrashed(self):
+ if utils.IsWindows():
+ return 0x80000000 & self.exit_code and not (0x3FFFFF00 & self.exit_code)
+ else:
+ # Timed out tests will have exit_code -signal.SIGTERM.
+ if self.timed_out:
+ return False
+ return (self.exit_code < 0 and
+ self.exit_code != -signal.SIGABRT)
+
+ def HasTimedOut(self):
+ return self.timed_out
+
+ def Pack(self):
+ return [self.exit_code, self.timed_out, self.stdout, self.stderr]
+
+ @staticmethod
+ def Unpack(packed):
+ # For the order of the fields, refer to Pack() above.
+ return Output(packed[0], packed[1], packed[2], packed[3])
diff --git a/deps/v8/tools/testrunner/objects/peer.py b/deps/v8/tools/testrunner/objects/peer.py
new file mode 100644
index 000000000..18a6bec7a
--- /dev/null
+++ b/deps/v8/tools/testrunner/objects/peer.py
@@ -0,0 +1,80 @@
+# Copyright 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.
+
+
+class Peer(object):
+ def __init__(self, address, jobs, rel_perf, pubkey):
+ self.address = address # string: IP address
+ self.jobs = jobs # integer: number of CPUs
+ self.relative_performance = rel_perf
+ self.pubkey = pubkey # string: pubkey's fingerprint
+ self.shells = set() # set of strings
+ self.needed_work = 0
+ self.assigned_work = 0
+ self.tests = [] # list of TestCase objects
+ self.trusting_me = False # This peer trusts my public key.
+ self.trusted = False # I trust this peer's public key.
+
+ def __str__(self):
+ return ("Peer at %s, jobs: %d, performance: %.2f, trust I/O: %s/%s" %
+ (self.address, self.jobs, self.relative_performance,
+ self.trusting_me, self.trusted))
+
+ def AddTests(self, shell):
+ """Adds tests from |shell| to this peer.
+
+ Stops when self.needed_work reaches zero, or when all of shell's tests
+ are assigned."""
+ assert self.needed_work > 0
+ if shell.shell not in self.shells:
+ self.shells.add(shell.shell)
+ while len(shell.tests) > 0 and self.needed_work > 0:
+ t = shell.tests.pop()
+ self.needed_work -= t.duration
+ self.assigned_work += t.duration
+ shell.total_duration -= t.duration
+ self.tests.append(t)
+
+ def ForceAddOneTest(self, test, shell):
+ """Forcibly adds another test to this peer, disregarding needed_work."""
+ if shell.shell not in self.shells:
+ self.shells.add(shell.shell)
+ self.needed_work -= test.duration
+ self.assigned_work += test.duration
+ shell.total_duration -= test.duration
+ self.tests.append(test)
+
+
+ def Pack(self):
+ """Creates a JSON serializable representation of this Peer."""
+ return [self.address, self.jobs, self.relative_performance]
+
+ @staticmethod
+ def Unpack(packed):
+ """Creates a Peer object built from a packed representation."""
+ pubkey_dummy = "" # Callers of this don't care (only the server does).
+ return Peer(packed[0], packed[1], packed[2], pubkey_dummy)
diff --git a/deps/v8/tools/testrunner/objects/testcase.py b/deps/v8/tools/testrunner/objects/testcase.py
new file mode 100644
index 000000000..cfc522ea7
--- /dev/null
+++ b/deps/v8/tools/testrunner/objects/testcase.py
@@ -0,0 +1,83 @@
+# Copyright 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.
+
+
+from . import output
+
+class TestCase(object):
+ def __init__(self, suite, path, flags=[], dependency=None):
+ self.suite = suite # TestSuite object
+ self.path = path # string, e.g. 'div-mod', 'test-api/foo'
+ self.flags = flags # list of strings, flags specific to this test case
+ self.dependency = dependency # |path| for testcase that must be run first
+ self.outcomes = None
+ self.output = None
+ self.id = None # int, used to map result back to TestCase instance
+ self.duration = None # assigned during execution
+
+ def CopyAddingFlags(self, flags):
+ copy = TestCase(self.suite, self.path, self.flags + flags, self.dependency)
+ copy.outcomes = self.outcomes
+ return copy
+
+ def PackTask(self):
+ """
+ Extracts those parts of this object that are required to run the test
+ and returns them as a JSON serializable object.
+ """
+ assert self.id is not None
+ return [self.suitename(), self.path, self.flags,
+ self.dependency, list(self.outcomes or []), self.id]
+
+ @staticmethod
+ def UnpackTask(task):
+ """Creates a new TestCase object based on packed task data."""
+ # For the order of the fields, refer to PackTask() above.
+ test = TestCase(str(task[0]), task[1], task[2], task[3])
+ test.outcomes = set(task[4])
+ test.id = task[5]
+ return test
+
+ def SetSuiteObject(self, suites):
+ self.suite = suites[self.suite]
+
+ def PackResult(self):
+ """Serializes the output of the TestCase after it has run."""
+ self.suite.StripOutputForTransmit(self)
+ return [self.id, self.output.Pack(), self.duration]
+
+ def MergeResult(self, result):
+ """Applies the contents of a Result to this object."""
+ assert result[0] == self.id
+ self.output = output.Output.Unpack(result[1])
+ self.duration = result[2]
+
+ def suitename(self):
+ return self.suite.name
+
+ def GetLabel(self):
+ return self.suitename() + "/" + self.suite.CommonTestName(self)
diff --git a/deps/v8/tools/testrunner/objects/workpacket.py b/deps/v8/tools/testrunner/objects/workpacket.py
new file mode 100644
index 000000000..d07efe76e
--- /dev/null
+++ b/deps/v8/tools/testrunner/objects/workpacket.py
@@ -0,0 +1,90 @@
+# Copyright 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.
+
+
+from . import context
+from . import testcase
+
+class WorkPacket(object):
+ def __init__(self, peer=None, context=None, tests=None, binaries=None,
+ base_revision=None, patch=None, pubkey=None):
+ self.peer = peer
+ self.context = context
+ self.tests = tests
+ self.binaries = binaries
+ self.base_revision = base_revision
+ self.patch = patch
+ self.pubkey_fingerprint = pubkey
+
+ def Pack(self, binaries_dict):
+ """
+ Creates a JSON serializable object containing the data of this
+ work packet.
+ """
+ need_libv8 = False
+ binaries = []
+ for shell in self.peer.shells:
+ prefetched_binary = binaries_dict[shell]
+ binaries.append({"name": shell,
+ "blob": prefetched_binary[0],
+ "sign": prefetched_binary[1]})
+ if prefetched_binary[2]:
+ need_libv8 = True
+ if need_libv8:
+ libv8 = binaries_dict["libv8.so"]
+ binaries.append({"name": "libv8.so",
+ "blob": libv8[0],
+ "sign": libv8[1]})
+ tests = []
+ test_map = {}
+ for t in self.peer.tests:
+ test_map[t.id] = t
+ tests.append(t.PackTask())
+ result = {
+ "binaries": binaries,
+ "pubkey": self.pubkey_fingerprint,
+ "context": self.context.Pack(),
+ "base_revision": self.base_revision,
+ "patch": self.patch,
+ "tests": tests
+ }
+ return result, test_map
+
+ @staticmethod
+ def Unpack(packed):
+ """
+ Creates a WorkPacket object from the given packed representation.
+ """
+ binaries = packed["binaries"]
+ pubkey_fingerprint = packed["pubkey"]
+ ctx = context.Context.Unpack(packed["context"])
+ base_revision = packed["base_revision"]
+ patch = packed["patch"]
+ tests = [ testcase.TestCase.UnpackTask(t) for t in packed["tests"] ]
+ return WorkPacket(context=ctx, tests=tests, binaries=binaries,
+ base_revision=base_revision, patch=patch,
+ pubkey=pubkey_fingerprint)
diff --git a/deps/v8/tools/testrunner/server/__init__.py b/deps/v8/tools/testrunner/server/__init__.py
new file mode 100644
index 000000000..202a26270
--- /dev/null
+++ b/deps/v8/tools/testrunner/server/__init__.py
@@ -0,0 +1,26 @@
+# Copyright 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.
diff --git a/deps/v8/tools/testrunner/server/compression.py b/deps/v8/tools/testrunner/server/compression.py
new file mode 100644
index 000000000..ce90c4f59
--- /dev/null
+++ b/deps/v8/tools/testrunner/server/compression.py
@@ -0,0 +1,112 @@
+# Copyright 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.
+
+
+import cStringIO as StringIO
+try:
+ import ujson as json
+except ImportError:
+ print("You should install UltraJSON, it is much faster!")
+ import json
+import os
+import struct
+import zlib
+
+from . import constants
+
+def Send(obj, sock):
+ """
+ Sends a JSON encodable object over the specified socket (zlib-compressed).
+ """
+ obj = json.dumps(obj)
+ compression_level = 2 # 1 = fastest, 9 = best compression
+ compressed = zlib.compress(obj, compression_level)
+ payload = struct.pack('>i', len(compressed)) + compressed
+ sock.sendall(payload)
+
+
+class Receiver(object):
+ def __init__(self, sock):
+ self.sock = sock
+ self.data = StringIO.StringIO()
+ self.datalength = 0
+ self._next = self._GetNext()
+
+ def IsDone(self):
+ return self._next == None
+
+ def Current(self):
+ return self._next
+
+ def Advance(self):
+ try:
+ self._next = self._GetNext()
+ except:
+ raise
+
+ def _GetNext(self):
+ try:
+ while self.datalength < constants.SIZE_T:
+ try:
+ chunk = self.sock.recv(8192)
+ except:
+ raise
+ if not chunk: return None
+ self._AppendData(chunk)
+ size = self._PopData(constants.SIZE_T)
+ size = struct.unpack(">i", size)[0]
+ while self.datalength < size:
+ try:
+ chunk = self.sock.recv(8192)
+ except:
+ raise
+ if not chunk: return None
+ self._AppendData(chunk)
+ result = self._PopData(size)
+ result = zlib.decompress(result)
+ result = json.loads(result)
+ if result == constants.END_OF_STREAM:
+ return None
+ return result
+ except:
+ raise
+
+ def _AppendData(self, new):
+ self.data.seek(0, os.SEEK_END)
+ self.data.write(new)
+ self.datalength += len(new)
+
+ def _PopData(self, length):
+ self.data.seek(0)
+ chunk = self.data.read(length)
+ remaining = self.data.read()
+ self.data.close()
+ self.data = StringIO.StringIO()
+ self.data.write(remaining)
+ assert self.datalength - length == len(remaining)
+ self.datalength = len(remaining)
+ return chunk
diff --git a/deps/v8/tools/testrunner/server/constants.py b/deps/v8/tools/testrunner/server/constants.py
new file mode 100644
index 000000000..5aefcbad0
--- /dev/null
+++ b/deps/v8/tools/testrunner/server/constants.py
@@ -0,0 +1,51 @@
+# Copyright 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.
+
+
+CLIENT_PORT = 9991 # Port for the local client to connect to.
+PEER_PORT = 9992 # Port for peers on the network to connect to.
+PRESENCE_PORT = 9993 # Port for presence daemon.
+STATUS_PORT = 9994 # Port for network requests not related to workpackets.
+
+END_OF_STREAM = "end of dtest stream" # Marker for end of network requests.
+SIZE_T = 4 # Number of bytes used for network request size header.
+
+# Messages understood by the local request handler.
+ADD_TRUSTED = "add trusted"
+INFORM_DURATION = "inform about duration"
+REQUEST_PEERS = "get peers"
+UNRESPONSIVE_PEER = "unresponsive peer"
+REQUEST_PUBKEY_FINGERPRINT = "get pubkey fingerprint"
+REQUEST_STATUS = "get status"
+UPDATE_PERF = "update performance"
+
+# Messages understood by the status request handler.
+LIST_TRUSTED_PUBKEYS = "list trusted pubkeys"
+GET_SIGNED_PUBKEY = "pass on signed pubkey"
+NOTIFY_NEW_TRUSTED = "new trusted peer"
+TRUST_YOU_NOW = "trust you now"
+DO_YOU_TRUST = "do you trust"
diff --git a/deps/v8/tools/testrunner/server/daemon.py b/deps/v8/tools/testrunner/server/daemon.py
new file mode 100644
index 000000000..baa66fbea
--- /dev/null
+++ b/deps/v8/tools/testrunner/server/daemon.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+
+# This code has been written by Sander Marechal and published at:
+# http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
+# where the author has placed it in the public domain (see comment #6 at
+# http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/#c6
+# ).
+# Some minor modifications have been made by the V8 authors. The work remains
+# in the public domain.
+
+import atexit
+import os
+from signal import SIGTERM
+from signal import SIGINT
+import sys
+import time
+
+
+class Daemon(object):
+ """
+ A generic daemon class.
+
+ Usage: subclass the Daemon class and override the run() method
+ """
+ def __init__(self, pidfile, stdin='/dev/null',
+ stdout='/dev/null', stderr='/dev/null'):
+ self.stdin = stdin
+ self.stdout = stdout
+ self.stderr = stderr
+ self.pidfile = pidfile
+
+ def daemonize(self):
+ """
+ do the UNIX double-fork magic, see Stevens' "Advanced
+ Programming in the UNIX Environment" for details (ISBN 0201563177)
+ http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
+ """
+ try:
+ pid = os.fork()
+ if pid > 0:
+ # exit first parent
+ sys.exit(0)
+ except OSError, e:
+ sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
+ sys.exit(1)
+
+ # decouple from parent environment
+ os.chdir("/")
+ os.setsid()
+ os.umask(0)
+
+ # do second fork
+ try:
+ pid = os.fork()
+ if pid > 0:
+ # exit from second parent
+ sys.exit(0)
+ except OSError, e:
+ sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
+ sys.exit(1)
+
+ # redirect standard file descriptors
+ sys.stdout.flush()
+ sys.stderr.flush()
+ si = file(self.stdin, 'r')
+ so = file(self.stdout, 'a+')
+ se = file(self.stderr, 'a+', 0)
+ # TODO: (debug) re-enable this!
+ #os.dup2(si.fileno(), sys.stdin.fileno())
+ #os.dup2(so.fileno(), sys.stdout.fileno())
+ #os.dup2(se.fileno(), sys.stderr.fileno())
+
+ # write pidfile
+ atexit.register(self.delpid)
+ pid = str(os.getpid())
+ file(self.pidfile, 'w+').write("%s\n" % pid)
+
+ def delpid(self):
+ os.remove(self.pidfile)
+
+ def start(self):
+ """
+ Start the daemon
+ """
+ # Check for a pidfile to see if the daemon already runs
+ try:
+ pf = file(self.pidfile, 'r')
+ pid = int(pf.read().strip())
+ pf.close()
+ except IOError:
+ pid = None
+
+ if pid:
+ message = "pidfile %s already exist. Daemon already running?\n"
+ sys.stderr.write(message % self.pidfile)
+ sys.exit(1)
+
+ # Start the daemon
+ self.daemonize()
+ self.run()
+
+ def stop(self):
+ """
+ Stop the daemon
+ """
+ # Get the pid from the pidfile
+ try:
+ pf = file(self.pidfile, 'r')
+ pid = int(pf.read().strip())
+ pf.close()
+ except IOError:
+ pid = None
+
+ if not pid:
+ message = "pidfile %s does not exist. Daemon not running?\n"
+ sys.stderr.write(message % self.pidfile)
+ return # not an error in a restart
+
+ # Try killing the daemon process
+ try:
+ # Give the process a one-second chance to exit gracefully.
+ os.kill(pid, SIGINT)
+ time.sleep(1)
+ while 1:
+ os.kill(pid, SIGTERM)
+ time.sleep(0.1)
+ except OSError, err:
+ err = str(err)
+ if err.find("No such process") > 0:
+ if os.path.exists(self.pidfile):
+ os.remove(self.pidfile)
+ else:
+ print str(err)
+ sys.exit(1)
+
+ def restart(self):
+ """
+ Restart the daemon
+ """
+ self.stop()
+ self.start()
+
+ def run(self):
+ """
+ You should override this method when you subclass Daemon. It will be
+ called after the process has been daemonized by start() or restart().
+ """
diff --git a/deps/v8/tools/testrunner/server/local_handler.py b/deps/v8/tools/testrunner/server/local_handler.py
new file mode 100644
index 000000000..3b3ac495d
--- /dev/null
+++ b/deps/v8/tools/testrunner/server/local_handler.py
@@ -0,0 +1,119 @@
+# Copyright 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.
+
+
+import socket
+import SocketServer
+import StringIO
+
+from . import compression
+from . import constants
+
+
+def LocalQuery(query):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ code = sock.connect_ex(("localhost", constants.CLIENT_PORT))
+ if code != 0: return None
+ compression.Send(query, sock)
+ compression.Send(constants.END_OF_STREAM, sock)
+ rec = compression.Receiver(sock)
+ data = None
+ while not rec.IsDone():
+ data = rec.Current()
+ assert data[0] == query[0]
+ data = data[1]
+ rec.Advance()
+ sock.close()
+ return data
+
+
+class LocalHandler(SocketServer.BaseRequestHandler):
+ def handle(self):
+ rec = compression.Receiver(self.request)
+ while not rec.IsDone():
+ data = rec.Current()
+ action = data[0]
+
+ if action == constants.REQUEST_PEERS:
+ with self.server.daemon.peer_list_lock:
+ response = [ p.Pack() for p in self.server.daemon.peers
+ if p.trusting_me ]
+ compression.Send([action, response], self.request)
+
+ elif action == constants.UNRESPONSIVE_PEER:
+ self.server.daemon.DeletePeer(data[1])
+
+ elif action == constants.REQUEST_PUBKEY_FINGERPRINT:
+ compression.Send([action, self.server.daemon.pubkey_fingerprint],
+ self.request)
+
+ elif action == constants.REQUEST_STATUS:
+ compression.Send([action, self._GetStatusMessage()], self.request)
+
+ elif action == constants.ADD_TRUSTED:
+ fingerprint = self.server.daemon.CopyToTrusted(data[1])
+ compression.Send([action, fingerprint], self.request)
+
+ elif action == constants.INFORM_DURATION:
+ test_key = data[1]
+ test_duration = data[2]
+ arch = data[3]
+ mode = data[4]
+ self.server.daemon.AddPerfData(test_key, test_duration, arch, mode)
+
+ elif action == constants.UPDATE_PERF:
+ address = data[1]
+ perf = data[2]
+ self.server.daemon.UpdatePeerPerformance(data[1], data[2])
+
+ rec.Advance()
+ compression.Send(constants.END_OF_STREAM, self.request)
+
+ def _GetStatusMessage(self):
+ sio = StringIO.StringIO()
+ sio.write("Peers:\n")
+ with self.server.daemon.peer_list_lock:
+ for p in self.server.daemon.peers:
+ sio.write("%s\n" % p)
+ sio.write("My own jobs: %d, relative performance: %.2f\n" %
+ (self.server.daemon.jobs, self.server.daemon.relative_perf))
+ # Low-priority TODO: Return more information. Ideas:
+ # - currently running anything,
+ # - time since last job,
+ # - time since last repository fetch
+ # - number of workpackets/testcases handled since startup
+ # - slowest test(s)
+ result = sio.getvalue()
+ sio.close()
+ return result
+
+
+class LocalSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
+ def __init__(self, daemon):
+ SocketServer.TCPServer.__init__(self, ("localhost", constants.CLIENT_PORT),
+ LocalHandler)
+ self.daemon = daemon
diff --git a/deps/v8/tools/testrunner/server/main.py b/deps/v8/tools/testrunner/server/main.py
new file mode 100644
index 000000000..1000713ca
--- /dev/null
+++ b/deps/v8/tools/testrunner/server/main.py
@@ -0,0 +1,245 @@
+# Copyright 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.
+
+
+import multiprocessing
+import os
+import shutil
+import subprocess
+import threading
+import time
+
+from . import daemon
+from . import local_handler
+from . import presence_handler
+from . import signatures
+from . import status_handler
+from . import work_handler
+from ..network import perfdata
+
+
+class Server(daemon.Daemon):
+
+ def __init__(self, pidfile, root, stdin="/dev/null",
+ stdout="/dev/null", stderr="/dev/null"):
+ super(Server, self).__init__(pidfile, stdin, stdout, stderr)
+ self.root = root
+ self.local_handler = None
+ self.local_handler_thread = None
+ self.work_handler = None
+ self.work_handler_thread = None
+ self.status_handler = None
+ self.status_handler_thread = None
+ self.presence_daemon = None
+ self.presence_daemon_thread = None
+ self.peers = []
+ self.jobs = multiprocessing.cpu_count()
+ self.peer_list_lock = threading.Lock()
+ self.perf_data_lock = None
+ self.presence_daemon_lock = None
+ self.datadir = os.path.join(self.root, "data")
+ pubkey_fingerprint_filename = os.path.join(self.datadir, "mypubkey")
+ with open(pubkey_fingerprint_filename) as f:
+ self.pubkey_fingerprint = f.read().strip()
+ self.relative_perf_filename = os.path.join(self.datadir, "myperf")
+ if os.path.exists(self.relative_perf_filename):
+ with open(self.relative_perf_filename) as f:
+ try:
+ self.relative_perf = float(f.read())
+ except:
+ self.relative_perf = 1.0
+ else:
+ self.relative_perf = 1.0
+
+ def run(self):
+ os.nice(20)
+ self.ip = presence_handler.GetOwnIP()
+ self.perf_data_manager = perfdata.PerfDataManager(self.datadir)
+ self.perf_data_lock = threading.Lock()
+
+ self.local_handler = local_handler.LocalSocketServer(self)
+ self.local_handler_thread = threading.Thread(
+ target=self.local_handler.serve_forever)
+ self.local_handler_thread.start()
+
+ self.work_handler = work_handler.WorkSocketServer(self)
+ self.work_handler_thread = threading.Thread(
+ target=self.work_handler.serve_forever)
+ self.work_handler_thread.start()
+
+ self.status_handler = status_handler.StatusSocketServer(self)
+ self.status_handler_thread = threading.Thread(
+ target=self.status_handler.serve_forever)
+ self.status_handler_thread.start()
+
+ self.presence_daemon = presence_handler.PresenceDaemon(self)
+ self.presence_daemon_thread = threading.Thread(
+ target=self.presence_daemon.serve_forever)
+ self.presence_daemon_thread.start()
+
+ self.presence_daemon.FindPeers()
+ time.sleep(0.5) # Give those peers some time to reply.
+
+ with self.peer_list_lock:
+ for p in self.peers:
+ if p.address == self.ip: continue
+ status_handler.RequestTrustedPubkeys(p, self)
+
+ while True:
+ try:
+ self.PeriodicTasks()
+ time.sleep(60)
+ except Exception, e:
+ print("MAIN LOOP EXCEPTION: %s" % e)
+ self.Shutdown()
+ break
+ except KeyboardInterrupt:
+ self.Shutdown()
+ break
+
+ def Shutdown(self):
+ with open(self.relative_perf_filename, "w") as f:
+ f.write("%s" % self.relative_perf)
+ self.presence_daemon.shutdown()
+ self.presence_daemon.server_close()
+ self.local_handler.shutdown()
+ self.local_handler.server_close()
+ self.work_handler.shutdown()
+ self.work_handler.server_close()
+ self.status_handler.shutdown()
+ self.status_handler.server_close()
+
+ def PeriodicTasks(self):
+ # If we know peers we don't trust, see if someone else trusts them.
+ with self.peer_list_lock:
+ for p in self.peers:
+ if p.trusted: continue
+ if self.IsTrusted(p.pubkey):
+ p.trusted = True
+ status_handler.ITrustYouNow(p)
+ continue
+ for p2 in self.peers:
+ if not p2.trusted: continue
+ status_handler.TryTransitiveTrust(p2, p.pubkey, self)
+ # TODO: Ping for more peers waiting to be discovered.
+ # TODO: Update the checkout (if currently idle).
+
+ def AddPeer(self, peer):
+ with self.peer_list_lock:
+ for p in self.peers:
+ if p.address == peer.address:
+ return
+ self.peers.append(peer)
+ if peer.trusted:
+ status_handler.ITrustYouNow(peer)
+
+ def DeletePeer(self, peer_address):
+ with self.peer_list_lock:
+ for i in xrange(len(self.peers)):
+ if self.peers[i].address == peer_address:
+ del self.peers[i]
+ return
+
+ def MarkPeerAsTrusting(self, peer_address):
+ with self.peer_list_lock:
+ for p in self.peers:
+ if p.address == peer_address:
+ p.trusting_me = True
+ break
+
+ def UpdatePeerPerformance(self, peer_address, performance):
+ with self.peer_list_lock:
+ for p in self.peers:
+ if p.address == peer_address:
+ p.relative_performance = performance
+
+ def CopyToTrusted(self, pubkey_filename):
+ with open(pubkey_filename, "r") as f:
+ lines = f.readlines()
+ fingerprint = lines[-1].strip()
+ target_filename = self._PubkeyFilename(fingerprint)
+ shutil.copy(pubkey_filename, target_filename)
+ with self.peer_list_lock:
+ for peer in self.peers:
+ if peer.address == self.ip: continue
+ if peer.pubkey == fingerprint:
+ status_handler.ITrustYouNow(peer)
+ else:
+ result = self.SignTrusted(fingerprint)
+ status_handler.NotifyNewTrusted(peer, result)
+ return fingerprint
+
+ def _PubkeyFilename(self, pubkey_fingerprint):
+ return os.path.join(self.root, "trusted", "%s.pem" % pubkey_fingerprint)
+
+ def IsTrusted(self, pubkey_fingerprint):
+ return os.path.exists(self._PubkeyFilename(pubkey_fingerprint))
+
+ def ListTrusted(self):
+ path = os.path.join(self.root, "trusted")
+ if not os.path.exists(path): return []
+ return [ f[:-4] for f in os.listdir(path) if f.endswith(".pem") ]
+
+ def SignTrusted(self, pubkey_fingerprint):
+ if not self.IsTrusted(pubkey_fingerprint):
+ return []
+ filename = self._PubkeyFilename(pubkey_fingerprint)
+ result = signatures.ReadFileAndSignature(filename) # Format: [key, sig].
+ return [pubkey_fingerprint, result[0], result[1], self.pubkey_fingerprint]
+
+ def AcceptNewTrusted(self, data):
+ # The format of |data| matches the return value of |SignTrusted()|.
+ if not data: return
+ fingerprint = data[0]
+ pubkey = data[1]
+ signature = data[2]
+ signer = data[3]
+ if not self.IsTrusted(signer):
+ return
+ if self.IsTrusted(fingerprint):
+ return # Already trust this guy.
+ filename = self._PubkeyFilename(fingerprint)
+ signer_pubkeyfile = self._PubkeyFilename(signer)
+ if not signatures.VerifySignature(filename, pubkey, signature,
+ signer_pubkeyfile):
+ return
+ return # Nothing more to do.
+
+ def AddPerfData(self, test_key, duration, arch, mode):
+ data_store = self.perf_data_manager.GetStore(arch, mode)
+ data_store.RawUpdatePerfData(str(test_key), duration)
+
+ def CompareOwnPerf(self, test, arch, mode):
+ data_store = self.perf_data_manager.GetStore(arch, mode)
+ observed = data_store.FetchPerfData(test)
+ if not observed: return
+ own_perf_estimate = observed / test.duration
+ with self.perf_data_lock:
+ kLearnRateLimiter = 9999
+ self.relative_perf *= kLearnRateLimiter
+ self.relative_perf += own_perf_estimate
+ self.relative_perf /= (kLearnRateLimiter + 1)
diff --git a/deps/v8/tools/testrunner/server/presence_handler.py b/deps/v8/tools/testrunner/server/presence_handler.py
new file mode 100644
index 000000000..1dc2ef163
--- /dev/null
+++ b/deps/v8/tools/testrunner/server/presence_handler.py
@@ -0,0 +1,120 @@
+# Copyright 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.
+
+
+import socket
+import SocketServer
+import threading
+try:
+ import ujson as json
+except:
+ import json
+
+from . import constants
+from ..objects import peer
+
+
+STARTUP_REQUEST = "V8 test peer starting up"
+STARTUP_RESPONSE = "Let's rock some tests!"
+EXIT_REQUEST = "V8 testing peer going down"
+
+
+def GetOwnIP():
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s.connect(("8.8.8.8", 80))
+ ip = s.getsockname()[0]
+ s.close()
+ return ip
+
+
+class PresenceHandler(SocketServer.BaseRequestHandler):
+
+ def handle(self):
+ data = json.loads(self.request[0].strip())
+
+ if data[0] == STARTUP_REQUEST:
+ jobs = data[1]
+ relative_perf = data[2]
+ pubkey_fingerprint = data[3]
+ trusted = self.server.daemon.IsTrusted(pubkey_fingerprint)
+ response = [STARTUP_RESPONSE, self.server.daemon.jobs,
+ self.server.daemon.relative_perf,
+ self.server.daemon.pubkey_fingerprint, trusted]
+ response = json.dumps(response)
+ self.server.SendTo(self.client_address[0], response)
+ p = peer.Peer(self.client_address[0], jobs, relative_perf,
+ pubkey_fingerprint)
+ p.trusted = trusted
+ self.server.daemon.AddPeer(p)
+
+ elif data[0] == STARTUP_RESPONSE:
+ jobs = data[1]
+ perf = data[2]
+ pubkey_fingerprint = data[3]
+ p = peer.Peer(self.client_address[0], jobs, perf, pubkey_fingerprint)
+ p.trusted = self.server.daemon.IsTrusted(pubkey_fingerprint)
+ p.trusting_me = data[4]
+ self.server.daemon.AddPeer(p)
+
+ elif data[0] == EXIT_REQUEST:
+ self.server.daemon.DeletePeer(self.client_address[0])
+ if self.client_address[0] == self.server.daemon.ip:
+ self.server.shutdown_lock.release()
+
+
+class PresenceDaemon(SocketServer.ThreadingMixIn, SocketServer.UDPServer):
+ def __init__(self, daemon):
+ self.daemon = daemon
+ address = (daemon.ip, constants.PRESENCE_PORT)
+ SocketServer.UDPServer.__init__(self, address, PresenceHandler)
+ self.shutdown_lock = threading.Lock()
+
+ def shutdown(self):
+ self.shutdown_lock.acquire()
+ self.SendToAll(json.dumps([EXIT_REQUEST]))
+ self.shutdown_lock.acquire()
+ self.shutdown_lock.release()
+ SocketServer.UDPServer.shutdown(self)
+
+ def SendTo(self, target, message):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ sock.sendto(message, (target, constants.PRESENCE_PORT))
+ sock.close()
+
+ def SendToAll(self, message):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ ip = self.daemon.ip.split(".")
+ for i in range(1, 254):
+ ip[-1] = str(i)
+ sock.sendto(message, (".".join(ip), constants.PRESENCE_PORT))
+ sock.close()
+
+ def FindPeers(self):
+ request = [STARTUP_REQUEST, self.daemon.jobs, self.daemon.relative_perf,
+ self.daemon.pubkey_fingerprint]
+ request = json.dumps(request)
+ self.SendToAll(request)
diff --git a/deps/v8/tools/testrunner/server/signatures.py b/deps/v8/tools/testrunner/server/signatures.py
new file mode 100644
index 000000000..9957a18a2
--- /dev/null
+++ b/deps/v8/tools/testrunner/server/signatures.py
@@ -0,0 +1,63 @@
+# Copyright 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.
+
+
+import base64
+import os
+import subprocess
+
+
+def ReadFileAndSignature(filename):
+ with open(filename, "rb") as f:
+ file_contents = base64.b64encode(f.read())
+ signature_file = filename + ".signature"
+ if (not os.path.exists(signature_file) or
+ os.path.getmtime(signature_file) < os.path.getmtime(filename)):
+ private_key = "~/.ssh/v8_dtest"
+ code = subprocess.call("openssl dgst -out %s -sign %s %s" %
+ (signature_file, private_key, filename),
+ shell=True)
+ if code != 0: return [None, code]
+ with open(signature_file) as f:
+ signature = base64.b64encode(f.read())
+ return [file_contents, signature]
+
+
+def VerifySignature(filename, file_contents, signature, pubkeyfile):
+ with open(filename, "wb") as f:
+ f.write(base64.b64decode(file_contents))
+ signature_file = filename + ".foreign_signature"
+ with open(signature_file, "wb") as f:
+ f.write(base64.b64decode(signature))
+ code = subprocess.call("openssl dgst -verify %s -signature %s %s" %
+ (pubkeyfile, signature_file, filename),
+ shell=True)
+ matched = (code == 0)
+ if not matched:
+ os.remove(signature_file)
+ os.remove(filename)
+ return matched
diff --git a/deps/v8/tools/testrunner/server/status_handler.py b/deps/v8/tools/testrunner/server/status_handler.py
new file mode 100644
index 000000000..3f2271dc6
--- /dev/null
+++ b/deps/v8/tools/testrunner/server/status_handler.py
@@ -0,0 +1,112 @@
+# Copyright 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.
+
+
+import socket
+import SocketServer
+
+from . import compression
+from . import constants
+
+
+def _StatusQuery(peer, query):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ code = sock.connect_ex((peer.address, constants.STATUS_PORT))
+ if code != 0:
+ # TODO(jkummerow): disconnect (after 3 failures?)
+ return
+ compression.Send(query, sock)
+ compression.Send(constants.END_OF_STREAM, sock)
+ rec = compression.Receiver(sock)
+ data = None
+ while not rec.IsDone():
+ data = rec.Current()
+ assert data[0] == query[0]
+ data = data[1]
+ rec.Advance()
+ sock.close()
+ return data
+
+
+def RequestTrustedPubkeys(peer, server):
+ pubkey_list = _StatusQuery(peer, [constants.LIST_TRUSTED_PUBKEYS])
+ for pubkey in pubkey_list:
+ if server.IsTrusted(pubkey): continue
+ result = _StatusQuery(peer, [constants.GET_SIGNED_PUBKEY, pubkey])
+ server.AcceptNewTrusted(result)
+
+
+def NotifyNewTrusted(peer, data):
+ _StatusQuery(peer, [constants.NOTIFY_NEW_TRUSTED] + data)
+
+
+def ITrustYouNow(peer):
+ _StatusQuery(peer, [constants.TRUST_YOU_NOW])
+
+
+def TryTransitiveTrust(peer, pubkey, server):
+ if _StatusQuery(peer, [constants.DO_YOU_TRUST, pubkey]):
+ result = _StatusQuery(peer, [constants.GET_SIGNED_PUBKEY, pubkey])
+ server.AcceptNewTrusted(result)
+
+
+class StatusHandler(SocketServer.BaseRequestHandler):
+ def handle(self):
+ rec = compression.Receiver(self.request)
+ while not rec.IsDone():
+ data = rec.Current()
+ action = data[0]
+
+ if action == constants.LIST_TRUSTED_PUBKEYS:
+ response = self.server.daemon.ListTrusted()
+ compression.Send([action, response], self.request)
+
+ elif action == constants.GET_SIGNED_PUBKEY:
+ response = self.server.daemon.SignTrusted(data[1])
+ compression.Send([action, response], self.request)
+
+ elif action == constants.NOTIFY_NEW_TRUSTED:
+ self.server.daemon.AcceptNewTrusted(data[1:])
+ pass # No response.
+
+ elif action == constants.TRUST_YOU_NOW:
+ self.server.daemon.MarkPeerAsTrusting(self.client_address[0])
+ pass # No response.
+
+ elif action == constants.DO_YOU_TRUST:
+ response = self.server.daemon.IsTrusted(data[1])
+ compression.Send([action, response], self.request)
+
+ rec.Advance()
+ compression.Send(constants.END_OF_STREAM, self.request)
+
+
+class StatusSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
+ def __init__(self, daemon):
+ address = (daemon.ip, constants.STATUS_PORT)
+ SocketServer.TCPServer.__init__(self, address, StatusHandler)
+ self.daemon = daemon
diff --git a/deps/v8/tools/testrunner/server/work_handler.py b/deps/v8/tools/testrunner/server/work_handler.py
new file mode 100644
index 000000000..6bf7d43cf
--- /dev/null
+++ b/deps/v8/tools/testrunner/server/work_handler.py
@@ -0,0 +1,150 @@
+# Copyright 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.
+
+
+import os
+import SocketServer
+import stat
+import subprocess
+import threading
+
+from . import compression
+from . import constants
+from . import signatures
+from ..network import endpoint
+from ..objects import workpacket
+
+
+class WorkHandler(SocketServer.BaseRequestHandler):
+
+ def handle(self):
+ rec = compression.Receiver(self.request)
+ while not rec.IsDone():
+ data = rec.Current()
+ with self.server.job_lock:
+ self._WorkOnWorkPacket(data)
+ rec.Advance()
+
+ def _WorkOnWorkPacket(self, data):
+ server_root = self.server.daemon.root
+ v8_root = os.path.join(server_root, "v8")
+ os.chdir(v8_root)
+ packet = workpacket.WorkPacket.Unpack(data)
+ self.ctx = packet.context
+ self.ctx.shell_dir = os.path.join("out",
+ "%s.%s" % (self.ctx.arch, self.ctx.mode))
+ if not os.path.isdir(self.ctx.shell_dir):
+ os.makedirs(self.ctx.shell_dir)
+ for binary in packet.binaries:
+ if not self._UnpackBinary(binary, packet.pubkey_fingerprint):
+ return
+
+ if not self._CheckoutRevision(packet.base_revision):
+ return
+
+ if not self._ApplyPatch(packet.patch):
+ return
+
+ tests = packet.tests
+ endpoint.Execute(v8_root, self.ctx, tests, self.request, self.server.daemon)
+ self._SendResponse()
+
+ def _SendResponse(self, error_message=None):
+ try:
+ if error_message:
+ compression.Send([[-1, error_message]], self.request)
+ compression.Send(constants.END_OF_STREAM, self.request)
+ return
+ except Exception, e:
+ pass # Peer is gone. There's nothing we can do.
+ # Clean up.
+ self._Call("git checkout -f")
+ self._Call("git clean -f -d")
+ self._Call("rm -rf %s" % self.ctx.shell_dir)
+
+ def _UnpackBinary(self, binary, pubkey_fingerprint):
+ binary_name = binary["name"]
+ if binary_name == "libv8.so":
+ libdir = os.path.join(self.ctx.shell_dir, "lib.target")
+ if not os.path.exists(libdir): os.makedirs(libdir)
+ target = os.path.join(libdir, binary_name)
+ else:
+ target = os.path.join(self.ctx.shell_dir, binary_name)
+ pubkeyfile = "../trusted/%s.pem" % pubkey_fingerprint
+ if not signatures.VerifySignature(target, binary["blob"],
+ binary["sign"], pubkeyfile):
+ self._SendResponse("Signature verification failed")
+ return False
+ os.chmod(target, stat.S_IRWXU)
+ return True
+
+ def _CheckoutRevision(self, base_svn_revision):
+ get_hash_cmd = (
+ "git log -1 --format=%%H --remotes --grep='^git-svn-id:.*@%s'" %
+ base_svn_revision)
+ try:
+ base_revision = subprocess.check_output(get_hash_cmd, shell=True)
+ if not base_revision: raise ValueError
+ except:
+ self._Call("git fetch")
+ try:
+ base_revision = subprocess.check_output(get_hash_cmd, shell=True)
+ if not base_revision: raise ValueError
+ except:
+ self._SendResponse("Base revision not found.")
+ return False
+ code = self._Call("git checkout -f %s" % base_revision)
+ if code != 0:
+ self._SendResponse("Error trying to check out base revision.")
+ return False
+ code = self._Call("git clean -f -d")
+ if code != 0:
+ self._SendResponse("Failed to reset checkout")
+ return False
+ return True
+
+ def _ApplyPatch(self, patch):
+ if not patch: return True # Just skip if the patch is empty.
+ patchfilename = "_dtest_incoming_patch.patch"
+ with open(patchfilename, "w") as f:
+ f.write(patch)
+ code = self._Call("git apply %s" % patchfilename)
+ if code != 0:
+ self._SendResponse("Error applying patch.")
+ return False
+ return True
+
+ def _Call(self, cmd):
+ return subprocess.call(cmd, shell=True)
+
+
+class WorkSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
+ def __init__(self, daemon):
+ address = (daemon.ip, constants.PEER_PORT)
+ SocketServer.TCPServer.__init__(self, address, WorkHandler)
+ self.job_lock = threading.Lock()
+ self.daemon = daemon
diff --git a/deps/v8/tools/tickprocessor-driver.js b/deps/v8/tools/tickprocessor-driver.js
index 9af5ab6c7..313c6d4c9 100644
--- a/deps/v8/tools/tickprocessor-driver.js
+++ b/deps/v8/tools/tickprocessor-driver.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -50,7 +50,7 @@ if (params.snapshotLogFileName) {
snapshotLogProcessor.processLogFile(params.snapshotLogFileName);
}
var tickProcessor = new TickProcessor(
- new (entriesProviders[params.platform])(params.nm),
+ new (entriesProviders[params.platform])(params.nm, params.targetRootFS),
params.separateIc,
params.callGraphSize,
params.ignoreUnknown,
diff --git a/deps/v8/tools/tickprocessor.js b/deps/v8/tools/tickprocessor.js
index 05a336925..4c4886d87 100644
--- a/deps/v8/tools/tickprocessor.js
+++ b/deps/v8/tools/tickprocessor.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 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:
@@ -608,10 +608,11 @@ CppEntriesProvider.prototype.parseNextLine = function() {
};
-function UnixCppEntriesProvider(nmExec) {
+function UnixCppEntriesProvider(nmExec, targetRootFS) {
this.symbols = [];
this.parsePos = 0;
this.nmExec = nmExec;
+ this.targetRootFS = targetRootFS;
this.FUNC_RE = /^([0-9a-fA-F]{8,16}) ([0-9a-fA-F]{8,16} )?[tTwW] (.*)$/;
};
inherits(UnixCppEntriesProvider, CppEntriesProvider);
@@ -619,6 +620,7 @@ inherits(UnixCppEntriesProvider, CppEntriesProvider);
UnixCppEntriesProvider.prototype.loadSymbols = function(libName) {
this.parsePos = 0;
+ libName = this.targetRootFS + libName;
try {
this.symbols = [
os.system(this.nmExec, ['-C', '-n', '-S', libName], -1, -1),
@@ -656,8 +658,8 @@ UnixCppEntriesProvider.prototype.parseNextLine = function() {
};
-function MacCppEntriesProvider(nmExec) {
- UnixCppEntriesProvider.call(this, nmExec);
+function MacCppEntriesProvider(nmExec, targetRootFS) {
+ UnixCppEntriesProvider.call(this, nmExec, targetRootFS);
// Note an empty group. It is required, as UnixCppEntriesProvider expects 3 groups.
this.FUNC_RE = /^([0-9a-fA-F]{8,16}) ()[iItT] (.*)$/;
};
@@ -666,6 +668,7 @@ inherits(MacCppEntriesProvider, UnixCppEntriesProvider);
MacCppEntriesProvider.prototype.loadSymbols = function(libName) {
this.parsePos = 0;
+ libName = this.targetRootFS + libName;
try {
this.symbols = [os.system(this.nmExec, ['-n', '-f', libName], -1, -1), ''];
} catch (e) {
@@ -675,7 +678,8 @@ MacCppEntriesProvider.prototype.loadSymbols = function(libName) {
};
-function WindowsCppEntriesProvider() {
+function WindowsCppEntriesProvider(_ignored_nmExec, targetRootFS) {
+ this.targetRootFS = targetRootFS;
this.symbols = '';
this.parsePos = 0;
};
@@ -698,6 +702,7 @@ WindowsCppEntriesProvider.EXE_IMAGE_BASE = 0x00400000;
WindowsCppEntriesProvider.prototype.loadSymbols = function(libName) {
+ libName = this.targetRootFS + libName;
var fileNameFields = libName.match(WindowsCppEntriesProvider.FILENAME_RE);
if (!fileNameFields) return;
var mapFileName = fileNameFields[1] + '.map';
@@ -785,6 +790,8 @@ function ArgumentsProcessor(args) {
'Specify that we are running on Mac OS X platform'],
'--nm': ['nm', 'nm',
'Specify the \'nm\' executable to use (e.g. --nm=/my_dir/nm)'],
+ '--target': ['targetRootFS', '',
+ 'Specify the target root directory for cross environment'],
'--snapshot-log': ['snapshotLogFileName', 'snapshot.log',
'Specify snapshot log file to use (e.g. --snapshot-log=snapshot.log)']
};
@@ -804,6 +811,7 @@ ArgumentsProcessor.DEFAULTS = {
callGraphSize: 5,
ignoreUnknown: false,
separateIc: false,
+ targetRootFS: '',
nm: 'nm'
};
diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown
index b414943c6..3f5650ff3 100644
--- a/doc/api/addons.markdown
+++ b/doc/api/addons.markdown
@@ -6,30 +6,35 @@ knowledge of several libraries:
- V8 JavaScript, a C++ library. Used for interfacing with JavaScript:
creating objects, calling functions, etc. Documented mostly in the
- `v8.h` header file (`deps/v8/include/v8.h` in the Node source tree),
- which is also available [online](http://izs.me/v8-docs/main.html).
+ `v8.h` header file (`deps/v8/include/v8.h` in the Node source
+ tree), which is also available
+ [online](http://izs.me/v8-docs/main.html).
- - [libuv](https://github.com/joyent/libuv), C event loop library. Anytime one
- needs to wait for a file descriptor to become readable, wait for a timer, or
- wait for a signal to received one will need to interface with libuv. That is,
- if you perform any I/O, libuv will need to be used.
+ - [libuv](https://github.com/joyent/libuv), C event loop library.
+ Anytime one needs to wait for a file descriptor to become readable,
+ wait for a timer, or wait for a signal to received one will need to
+ interface with libuv. That is, if you perform any I/O, libuv will
+ need to be used.
- Internal Node libraries. Most importantly is the `node::ObjectWrap`
class which you will likely want to derive from.
- Others. Look in `deps/` for what else is available.
-Node statically compiles all its dependencies into the executable. When
-compiling your module, you don't need to worry about linking to any of these
-libraries.
+Node statically compiles all its dependencies into the executable.
+When compiling your module, you don't need to worry about linking to
+any of these libraries.
+All of the following examples are available for
+[download](https://github.com/rvagg/node-addon-examples) and may be
+used as a starting-point for your own Addon.
## Hello world
To get started let's make a small Addon which is the C++ equivalent of
the following JavaScript code:
- exports.hello = function() { return 'world'; };
+ module.exports.hello = function() { return 'world'; };
First we create a file `hello.cc`:
@@ -43,15 +48,16 @@ First we create a file `hello.cc`:
return scope.Close(String::New("world"));
}
- void init(Handle<Object> target) {
- target->Set(String::NewSymbol("hello"),
+ void init(Handle<Object> exports) {
+ exports->Set(String::NewSymbol("hello"),
FunctionTemplate::New(Method)->GetFunction());
}
+
NODE_MODULE(hello, init)
Note that all Node addons must export an initialization function:
- void Initialize (Handle<Object> target);
+ void Initialize (Handle<Object> exports);
NODE_MODULE(module_name, Initialize)
There is no semi-colon after `NODE_MODULE` as it's not a function (see `node.h`).
@@ -154,8 +160,8 @@ function calls and return a result. This is the main and only needed source
return scope.Close(num);
}
- void Init(Handle<Object> target) {
- target->Set(String::NewSymbol("add"),
+ void Init(Handle<Object> exports) {
+ exports->Set(String::NewSymbol("add"),
FunctionTemplate::New(Add)->GetFunction());
}
@@ -189,18 +195,23 @@ there. Here's `addon.cc`:
return scope.Close(Undefined());
}
- void Init(Handle<Object> target) {
- target->Set(String::NewSymbol("runCallback"),
+ void Init(Handle<Object> exports, Handle<Object> module) {
+ module->Set(String::NewSymbol("exports"),
FunctionTemplate::New(RunCallback)->GetFunction());
}
NODE_MODULE(addon, Init)
+Note that this example uses a two-argument form of `Init()` that receives
+the full `module` object as the second argument. This allows the addon
+to completely overwrite `exports` with a single function instead of
+adding the function as a property of `exports`.
+
To test it run the following JavaScript snippet:
var addon = require('./build/Release/addon');
- addon.runCallback(function(msg){
+ addon(function(msg){
console.log(msg); // 'hello world'
});
@@ -225,8 +236,8 @@ the string passed to `createObject()`:
return scope.Close(obj);
}
- void Init(Handle<Object> target) {
- target->Set(String::NewSymbol("createObject"),
+ void Init(Handle<Object> exports, Handle<Object> module) {
+ module->Set(String::NewSymbol("exports"),
FunctionTemplate::New(CreateObject)->GetFunction());
}
@@ -236,8 +247,8 @@ To test it in JavaScript:
var addon = require('./build/Release/addon');
- var obj1 = addon.createObject('hello');
- var obj2 = addon.createObject('world');
+ var obj1 = addon('hello');
+ var obj2 = addon('world');
console.log(obj1.msg+' '+obj2.msg); // 'hello world'
@@ -266,8 +277,8 @@ wraps a C++ function:
return scope.Close(fn);
}
- void Init(Handle<Object> target) {
- target->Set(String::NewSymbol("createFunction"),
+ void Init(Handle<Object> exports, Handle<Object> module) {
+ module->Set(String::NewSymbol("exports"),
FunctionTemplate::New(CreateFunction)->GetFunction());
}
@@ -278,7 +289,7 @@ To test:
var addon = require('./build/Release/addon');
- var fn = addon.createFunction();
+ var fn = addon();
console.log(fn()); // 'hello world'
@@ -294,8 +305,8 @@ module `addon.cc`:
using namespace v8;
- void InitAll(Handle<Object> target) {
- MyObject::Init(target);
+ void InitAll(Handle<Object> exports) {
+ MyObject::Init(exports);
}
NODE_MODULE(addon, InitAll)
@@ -309,7 +320,7 @@ Then in `myobject.h` make your wrapper inherit from `node::ObjectWrap`:
class MyObject : public node::ObjectWrap {
public:
- static void Init(v8::Handle<v8::Object> target);
+ static void Init(v8::Handle<v8::Object> exports);
private:
MyObject();
@@ -335,7 +346,7 @@ prototype:
MyObject::MyObject() {};
MyObject::~MyObject() {};
- void MyObject::Init(Handle<Object> target) {
+ void MyObject::Init(Handle<Object> exports) {
// Prepare constructor template
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
tpl->SetClassName(String::NewSymbol("MyObject"));
@@ -345,7 +356,7 @@ prototype:
FunctionTemplate::New(PlusOne)->GetFunction());
Persistent<Function> constructor = Persistent<Function>::New(tpl->GetFunction());
- target->Set(String::NewSymbol("MyObject"), constructor);
+ exports->Set(String::NewSymbol("MyObject"), constructor);
}
Handle<Value> MyObject::New(const Arguments& args) {
@@ -399,10 +410,10 @@ Let's register our `createObject` method in `addon.cc`:
return scope.Close(MyObject::NewInstance(args));
}
- void InitAll(Handle<Object> target) {
+ void InitAll(Handle<Object> exports, Handle<Object> module) {
MyObject::Init();
- target->Set(String::NewSymbol("createObject"),
+ module->Set(String::NewSymbol("exports"),
FunctionTemplate::New(CreateObject)->GetFunction());
}
@@ -490,14 +501,14 @@ The implementation is similar to the above in `myobject.cc`:
Test it with:
- var addon = require('./build/Release/addon');
+ var createObject = require('./build/Release/addon');
- var obj = addon.createObject(10);
+ var obj = createObject(10);
console.log( obj.plusOne() ); // 11
console.log( obj.plusOne() ); // 12
console.log( obj.plusOne() ); // 13
- var obj2 = addon.createObject(20);
+ var obj2 = createObject(20);
console.log( obj2.plusOne() ); // 21
console.log( obj2.plusOne() ); // 22
console.log( obj2.plusOne() ); // 23
@@ -533,13 +544,13 @@ In the following `addon.cc` we introduce a function `add()` that can take on two
return scope.Close(Number::New(sum));
}
- void InitAll(Handle<Object> target) {
+ void InitAll(Handle<Object> exports) {
MyObject::Init();
- target->Set(String::NewSymbol("createObject"),
+ exports->Set(String::NewSymbol("createObject"),
FunctionTemplate::New(CreateObject)->GetFunction());
- target->Set(String::NewSymbol("add"),
+ exports->Set(String::NewSymbol("add"),
FunctionTemplate::New(Add)->GetFunction());
}
diff --git a/doc/api/assert.markdown b/doc/api/assert.markdown
index c93c1e778..5849f6d93 100644
--- a/doc/api/assert.markdown
+++ b/doc/api/assert.markdown
@@ -74,7 +74,7 @@ Custom error validation:
"unexpected error"
);
-## assert.doesNotThrow(block, [error], [message])
+## assert.doesNotThrow(block, [message])
Expects `block` not to throw an error, see assert.throws for details.
diff --git a/doc/api/buffer.markdown b/doc/api/buffer.markdown
index b7da01bf3..fb118a954 100644
--- a/doc/api/buffer.markdown
+++ b/doc/api/buffer.markdown
@@ -40,22 +40,16 @@ encoding method. Here are the different string encodings.
* `'hex'` - Encode each byte as two hexadecimal characters.
-`Buffer` can also be used with Typed Array Views and DataViews.
+A `Buffer` object can also be used with typed arrays. The buffer object is
+cloned to an `ArrayBuffer` that is used as the backing store for the typed
+array. The memory of the buffer and the `ArrayBuffer` is not shared.
- var buff = new Buffer(4);
- var ui16 = new Uint16Array(buff);
- var view = new DataView(buff);
+NOTE: Node.js v0.8 simply retained a reference to the buffer in `array.buffer`
+instead of cloning it.
- ui16[0] = 1;
- ui16[1] = 2;
- console.log(buff);
-
- view.setInt16(0, 1); // set big-endian int16 at byte offset 0
- view.setInt16(2, 2, true); // set little-endian int16 at byte offset 2
- console.log(buff);
-
- // <Buffer 01 00 02 00>
- // <Buffer 00 01 02 00>
+While more efficient, it introduces subtle incompatibilities with the typed
+arrays specification. `ArrayBuffer#slice()` makes a copy of the slice while
+`Buffer#slice()` creates a view.
## Class: Buffer
@@ -82,6 +76,13 @@ Allocates a new buffer using an `array` of octets.
Allocates a new buffer containing the given `str`.
`encoding` defaults to `'utf8'`.
+### Class Method: Buffer.isEncoding(encoding)
+
+* `encoding` {String} The encoding string to test
+
+Returns true if the `encoding` is a valid encoding argument, or false
+otherwise.
+
### buf.write(string, [offset], [length], [encoding])
* `string` String - data to be written to buffer
@@ -118,6 +119,25 @@ Decodes and returns a string from buffer data encoded with `encoding`
See `buffer.write()` example, above.
+### buf.toJSON()
+
+Returns a JSON-representation of the Buffer instance, which is identical to the
+output for JSON Arrays. `JSON.stringify` implicitly calls this function when
+stringifying a Buffer instance.
+
+Example:
+
+ var buf = new Buffer('test');
+ var json = JSON.stringify(buf);
+
+ console.log(json);
+ // '[116,101,115,116]'
+
+ var copy = new Buffer(JSON.parse(json));
+
+ console.log(copy);
+ // <Buffer 74 65 73 74>
+
### buf[index]
<!--type=property-->
@@ -213,6 +233,9 @@ Does copy between buffers. The source and target regions can be overlapped.
`targetStart` and `sourceStart` default to `0`.
`sourceEnd` defaults to `buffer.length`.
+All values passed that are `undefined`/`NaN` or are out of bounds are set equal
+to their respective defaults.
+
Example: build two Buffers, then copy `buf1` from byte 16 through byte 19
into `buf2`, starting at the 8th byte in `buf2`.
@@ -237,7 +260,7 @@ into `buf2`, starting at the 8th byte in `buf2`.
Returns a new buffer which references the same memory as the old, but offset
and cropped by the `start` (defaults to `0`) and `end` (defaults to
-`buffer.length`) indexes.
+`buffer.length`) indexes. Negative indexes start from the end of the buffer.
**Modifying the new buffer slice will modify memory in the original buffer!**
@@ -600,7 +623,7 @@ complement signed integer into `buffer`.
* `noAssert` Boolean, Optional, Default: false
Writes `value` to the buffer at the specified offset with specified endian
-format. Note, `value` must be a valid 32 bit float.
+format. Note, behavior is unspecified if `value` is not a 32 bit float.
Set `noAssert` to true to skip validation of `value` and `offset`. This means
that `value` may be too large for the specific function and `offset` may be
diff --git a/doc/api/child_process.markdown b/doc/api/child_process.markdown
index 913a37636..76d42d570 100644
--- a/doc/api/child_process.markdown
+++ b/doc/api/child_process.markdown
@@ -43,6 +43,10 @@ See `waitpid(2)`.
### Event: 'close'
+* `code` {Number} the exit code, if it exited normally.
+* `signal` {String} the signal passed to kill the child process, if it
+ was killed by the parent.
+
This event is emitted when the stdio streams of a child process have all
terminated. This is distinct from 'exit', since multiple processes
might share the same stdio streams.
@@ -114,7 +118,7 @@ be sent `'SIGTERM'`. See `signal(7)` for a list of available signals.
var spawn = require('child_process').spawn,
grep = spawn('grep', ['ssh']);
- grep.on('exit', function (code, signal) {
+ grep.on('close', function (code, signal) {
console.log('child process terminated due to receipt of signal '+signal);
});
@@ -168,7 +172,7 @@ The `sendHandle` option to `child.send()` is for sending a TCP server or
socket object to another process. The child will receive the object as its
second argument to the `message` event.
-**send server object**
+#### Example: sending server object
Here is an example of sending a server:
@@ -196,7 +200,7 @@ And the child would the receive the server object as:
Note that the server is now shared between the parent and child, this means
that some connections will be handled by the parent and some by the child.
-**send socket object**
+#### Example: sending socket object
Here is an example of sending a socket. It will spawn two children and handle
connections with the remote address `74.125.127.100` as VIP by sending the
@@ -281,7 +285,7 @@ Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the exit cod
console.log('stderr: ' + data);
});
- ls.on('exit', function (code) {
+ ls.on('close', function (code) {
console.log('child process exited with code ' + code);
});
@@ -300,7 +304,7 @@ Example: A very elaborate way to run 'ps ax | grep ssh'
console.log('ps stderr: ' + data);
});
- ps.on('exit', function (code) {
+ ps.on('close', function (code) {
if (code !== 0) {
console.log('ps process exited with code ' + code);
}
@@ -315,7 +319,7 @@ Example: A very elaborate way to run 'ps ax | grep ssh'
console.log('grep stderr: ' + data);
});
- grep.on('exit', function (code) {
+ grep.on('close', function (code) {
if (code !== 0) {
console.log('grep process exited with code ' + code);
}
@@ -520,6 +524,7 @@ leaner than `child_process.exec`. It has the same options.
* `cwd` {String} Current working directory of the child process
* `env` {Object} Environment key-value pairs
* `encoding` {String} (Default: 'utf8')
+ * `execPath` {String} Executable used to create the child process
* Return: ChildProcess object
This is a special case of the `spawn()` functionality for spawning Node
@@ -538,4 +543,10 @@ These child Nodes are still whole new instances of V8. Assume at least 30ms
startup and 10mb memory for each new Node. That is, you cannot create many
thousands of them.
+The `execPath` property in the `options` object allows for a process to be
+created for the child rather than the current `node` executable. This should be
+done with care and by default will talk over the fd represented an
+environmental variable `NODE_CHANNEL_FD` on the child process. The input and
+output on this fd is expected to be line delimited JSON objects.
+
[EventEmitter]: events.html#events_class_events_eventemitter
diff --git a/doc/api/cluster.markdown b/doc/api/cluster.markdown
index e6c74157c..af0a7a4ae 100644
--- a/doc/api/cluster.markdown
+++ b/doc/api/cluster.markdown
@@ -33,10 +33,11 @@ all share server ports.
Running node will now share port 8000 between the workers:
- % node server.js
- Worker 2438 online
- Worker 2437 online
-
+ % NODE_DEBUG=cluster node server.js
+ 23521,Master Worker 23524 online
+ 23521,Master Worker 23526 online
+ 23521,Master Worker 23523 online
+ 23521,Master Worker 23528 online
This feature was introduced recently, and may change in future versions.
Please try it out and provide feedback.
@@ -469,7 +470,7 @@ on the specified worker.
cluster.fork().on('online', function() {
// Worker is online
- };
+ });
### Event: 'listening'
@@ -480,7 +481,7 @@ on the specified worker.
cluster.fork().on('listening', function(address) {
// Worker is listening
- };
+ });
### Event: 'disconnect'
@@ -489,7 +490,7 @@ on the specified worker.
cluster.fork().on('disconnect', function() {
// Worker has disconnected
- };
+ });
### Event: 'exit'
@@ -509,4 +510,4 @@ is terminated. See [child_process event: 'exit'](child_process.html#child_proce
} else {
console.log("worker success!");
}
- };
+ });
diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown
index e6cff32ab..de574bc37 100644
--- a/doc/api/crypto.markdown
+++ b/doc/api/crypto.markdown
@@ -5,38 +5,67 @@
Use `require('crypto')` to access this module.
-The crypto module requires OpenSSL to be available on the underlying platform.
-It offers a way of encapsulating secure credentials to be used as part
-of a secure HTTPS net or http connection.
+The crypto module offers a way of encapsulating secure credentials to be
+used as part of a secure HTTPS net or http connection.
+
+It also offers a set of wrappers for OpenSSL's hash, hmac, cipher,
+decipher, sign and verify methods.
+
+
+## crypto.getCiphers()
+
+Returns an array with the names of the supported ciphers.
+
+Example:
+
+ var ciphers = crypto.getCiphers();
+ console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...]
+
+
+## crypto.getHashes()
+
+Returns an array with the names of the supported hash algorithms.
+
+Example:
+
+ var hashes = crypto.getHashes();
+ console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]
-It also offers a set of wrappers for OpenSSL's hash, hmac, cipher, decipher, sign and verify methods.
## crypto.createCredentials(details)
-Creates a credentials object, with the optional details being a dictionary with keys:
+Creates a credentials object, with the optional details being a
+dictionary with keys:
-* `pfx` : A string or buffer holding the PFX or PKCS12 encoded private key, certificate and CA certificates
+* `pfx` : A string or buffer holding the PFX or PKCS12 encoded private
+ key, certificate and CA certificates
* `key` : A string holding the PEM encoded private key
* `passphrase` : A string of passphrase for the private key or pfx
* `cert` : A string holding the PEM encoded certificate
-* `ca` : Either a string or list of strings of PEM encoded CA certificates to trust.
-* `crl` : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List)
-* `ciphers`: A string describing the ciphers to use or exclude. Consult
- <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT> for details
- on the format.
-
-If no 'ca' details are given, then node.js will use the default publicly trusted list of CAs as given in
+* `ca` : Either a string or list of strings of PEM encoded CA
+ certificates to trust.
+* `crl` : Either a string or list of strings of PEM encoded CRLs
+ (Certificate Revocation List)
+* `ciphers`: A string describing the ciphers to use or exclude.
+ Consult
+ <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>
+ for details on the format.
+
+If no 'ca' details are given, then node.js will use the default
+publicly trusted list of CAs as given in
<http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt>.
## crypto.createHash(algorithm)
-Creates and returns a hash object, a cryptographic hash with the given algorithm
-which can be used to generate hash digests.
+Creates and returns a hash object, a cryptographic hash with the given
+algorithm which can be used to generate hash digests.
-`algorithm` is dependent on the available algorithms supported by the version
-of OpenSSL on the platform. Examples are `'sha1'`, `'md5'`, `'sha256'`, `'sha512'`, etc.
-On recent releases, `openssl list-message-digest-algorithms` will display the available digest algorithms.
+`algorithm` is dependent on the available algorithms supported by the
+version of OpenSSL on the platform. Examples are `'sha1'`, `'md5'`,
+`'sha256'`, `'sha512'`, etc. On recent releases, `openssl
+list-message-digest-algorithms` will display the available digest
+algorithms.
Example: this program that takes the sha1 sum of a file
@@ -60,30 +89,43 @@ Example: this program that takes the sha1 sum of a file
The class for creating hash digests of data.
+It is a [stream](stream.html) that is both readable and writable. The
+written data is used to compute the hash. Once the writable side of
+the stream is ended, use the `read()` method to get the computed hash
+digest. The legacy `update` and `digest` methods are also supported.
+
Returned by `crypto.createHash`.
### hash.update(data, [input_encoding])
-Updates the hash content with the given `data`, the encoding of which is given
-in `input_encoding` and can be `'utf8'`, `'ascii'` or `'binary'`.
-Defaults to `'binary'`.
+Updates the hash content with the given `data`, the encoding of which
+is given in `input_encoding` and can be `'utf8'`, `'ascii'` or
+`'binary'`. If no encoding is provided, then a buffer is expected.
+
This can be called many times with new data as it is streamed.
### hash.digest([encoding])
-Calculates the digest of all of the passed data to be hashed.
-The `encoding` can be `'hex'`, `'binary'` or `'base64'`.
-Defaults to `'binary'`.
+Calculates the digest of all of the passed data to be hashed. The
+`encoding` can be `'hex'`, `'binary'` or `'base64'`. If no encoding
+is provided, then a buffer is returned.
-Note: `hash` object can not be used after `digest()` method has been called.
+Note: `hash` object can not be used after `digest()` method been
+called.
## crypto.createHmac(algorithm, key)
-Creates and returns a hmac object, a cryptographic hmac with the given algorithm and key.
+Creates and returns a hmac object, a cryptographic hmac with the given
+algorithm and key.
+
+It is a [stream](stream.html) that is both readable and writable. The
+written data is used to compute the hmac. Once the writable side of
+the stream is ended, use the `read()` method to get the computed
+digest. The legacy `update` and `digest` methods are also supported.
-`algorithm` is dependent on the available algorithms supported by OpenSSL - see createHash above.
-`key` is the hmac key to be used.
+`algorithm` is dependent on the available algorithms supported by
+OpenSSL - see createHash above. `key` is the hmac key to be used.
## Class: Hmac
@@ -93,38 +135,45 @@ Returned by `crypto.createHmac`.
### hmac.update(data)
-Update the hmac content with the given `data`.
-This can be called many times with new data as it is streamed.
+Update the hmac content with the given `data`. This can be called
+many times with new data as it is streamed.
### hmac.digest([encoding])
-Calculates the digest of all of the passed data to the hmac.
-The `encoding` can be `'hex'`, `'binary'` or `'base64'`.
-Defaults to `'binary'`.
+Calculates the digest of all of the passed data to the hmac. The
+`encoding` can be `'hex'`, `'binary'` or `'base64'`. If no encoding
+is provided, then a buffer is returned.
-Note: `hmac` object can not be used after `digest()` method been called.
+Note: `hmac` object can not be used after `digest()` method been
+called.
## crypto.createCipher(algorithm, password)
-Creates and returns a cipher object, with the given algorithm and password.
+Creates and returns a cipher object, with the given algorithm and
+password.
+
+`algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On
+recent releases, `openssl list-cipher-algorithms` will display the
+available cipher algorithms. `password` is used to derive key and IV,
+which must be a `'binary'` encoded string or a [buffer](buffer.html).
-`algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc.
-On recent releases, `openssl list-cipher-algorithms` will display the
-available cipher algorithms.
-`password` is used to derive key and IV, which must be a `'binary'` encoded
-string or a [buffer](buffer.html).
+It is a [stream](stream.html) that is both readable and writable. The
+written data is used to compute the hash. Once the writable side of
+the stream is ended, use the `read()` method to get the computed hash
+digest. The legacy `update` and `digest` methods are also supported.
## crypto.createCipheriv(algorithm, key, iv)
-Creates and returns a cipher object, with the given algorithm, key and iv.
+Creates and returns a cipher object, with the given algorithm, key and
+iv.
-`algorithm` is the same as the argument to `createCipher()`.
-`key` is the raw key used by the algorithm.
-`iv` is an [initialization
+`algorithm` is the same as the argument to `createCipher()`. `key` is
+the raw key used by the algorithm. `iv` is an [initialization
vector](http://en.wikipedia.org/wiki/Initialization_vector).
-`key` and `iv` must be `'binary'` encoded strings or [buffers](buffer.html).
+`key` and `iv` must be `'binary'` encoded strings or
+[buffers](buffer.html).
## Class: Cipher
@@ -132,40 +181,51 @@ Class for encrypting data.
Returned by `crypto.createCipher` and `crypto.createCipheriv`.
+Cipher objects are [streams](stream.html) that are both readable and
+writable. The written plain text data is used to produce the
+encrypted data on the the readable side. The legacy `update` and
+`final` methods are also supported.
+
### cipher.update(data, [input_encoding], [output_encoding])
Updates the cipher with `data`, the encoding of which is given in
-`input_encoding` and can be `'utf8'`, `'ascii'` or `'binary'`.
-Defaults to `'binary'`.
+`input_encoding` and can be `'utf8'`, `'ascii'` or `'binary'`. If no
+encoding is provided, then a buffer is expected.
-The `output_encoding` specifies the output format of the enciphered data,
-and can be `'binary'`, `'base64'` or `'hex'`. Defaults to `'binary'`.
+The `output_encoding` specifies the output format of the enciphered
+data, and can be `'binary'`, `'base64'` or `'hex'`. If no encoding is
+provided, then a buffer iis returned.
-Returns the enciphered contents, and can be called many times with new data as it is streamed.
+Returns the enciphered contents, and can be called many times with new
+data as it is streamed.
### cipher.final([output_encoding])
-Returns any remaining enciphered contents, with `output_encoding` being one of:
-`'binary'`, `'base64'` or `'hex'`. Defaults to `'binary'`.
+Returns any remaining enciphered contents, with `output_encoding`
+being one of: `'binary'`, `'base64'` or `'hex'`. If no encoding is
+provided, then a buffer is returned.
-Note: `cipher` object can not be used after `final()` method been called.
+Note: `cipher` object can not be used after `final()` method been
+called.
### cipher.setAutoPadding(auto_padding=true)
-You can disable automatic padding of the input data to block size. If `auto_padding` is false,
-the length of the entire input data must be a multiple of the cipher's block size or `final` will fail.
-Useful for non-standard padding, e.g. using `0x0` instead of PKCS padding. You must call this before `cipher.final`.
+You can disable automatic padding of the input data to block size. If
+`auto_padding` is false, the length of the entire input data must be a
+multiple of the cipher's block size or `final` will fail. Useful for
+non-standard padding, e.g. using `0x0` instead of PKCS padding. You
+must call this before `cipher.final`.
## crypto.createDecipher(algorithm, password)
-Creates and returns a decipher object, with the given algorithm and key.
-This is the mirror of the [createCipher()][] above.
+Creates and returns a decipher object, with the given algorithm and
+key. This is the mirror of the [createCipher()][] above.
## crypto.createDecipheriv(algorithm, key, iv)
-Creates and returns a decipher object, with the given algorithm, key and iv.
-This is the mirror of the [createCipheriv()][] above.
+Creates and returns a decipher object, with the given algorithm, key
+and iv. This is the mirror of the [createCipheriv()][] above.
## Class: Decipher
@@ -173,54 +233,72 @@ Class for decrypting data.
Returned by `crypto.createDecipher` and `crypto.createDecipheriv`.
+Decipher objects are [streams](stream.html) that are both readable and
+writable. The written enciphered data is used to produce the
+plain-text data on the the readable side. The legacy `update` and
+`final` methods are also supported.
+
### decipher.update(data, [input_encoding], [output_encoding])
-Updates the decipher with `data`, which is encoded in `'binary'`, `'base64'`
-or `'hex'`. Defaults to `'binary'`.
+Updates the decipher with `data`, which is encoded in `'binary'`,
+`'base64'` or `'hex'`. If no encoding is provided, then a buffer is
+expected.
-The `output_decoding` specifies in what format to return the deciphered
-plaintext: `'binary'`, `'ascii'` or `'utf8'`. Defaults to `'binary'`.
+The `output_decoding` specifies in what format to return the
+deciphered plaintext: `'binary'`, `'ascii'` or `'utf8'`. If no
+encoding is provided, then a buffer is returned.
### decipher.final([output_encoding])
-Returns any remaining plaintext which is deciphered,
-with `output_encoding` being one of: `'binary'`, `'ascii'` or `'utf8'`.
-Defaults to `'binary'`.
+Returns any remaining plaintext which is deciphered, with
+`output_encoding` being one of: `'binary'`, `'ascii'` or `'utf8'`. If
+no encoding is provided, then a buffer is returned.
-Note: `decipher` object can not be used after `final()` method been called.
+Note: `decipher` object can not be used after `final()` method been
+called.
### decipher.setAutoPadding(auto_padding=true)
-You can disable auto padding if the data has been encrypted without standard block padding to prevent
-`decipher.final` from checking and removing it. Can only work if the input data's length is a multiple of the
-ciphers block size. You must call this before streaming data to `decipher.update`.
+You can disable auto padding if the data has been encrypted without
+standard block padding to prevent `decipher.final` from checking and
+removing it. Can only work if the input data's length is a multiple of
+the ciphers block size. You must call this before streaming data to
+`decipher.update`.
## crypto.createSign(algorithm)
-Creates and returns a signing object, with the given algorithm.
-On recent OpenSSL releases, `openssl list-public-key-algorithms` will display
-the available signing algorithms. Examples are `'RSA-SHA256'`.
+Creates and returns a signing object, with the given algorithm. On
+recent OpenSSL releases, `openssl list-public-key-algorithms` will
+display the available signing algorithms. Examples are `'RSA-SHA256'`.
-## Class: Signer
+## Class: Sign
Class for generating signatures.
Returned by `crypto.createSign`.
-### signer.update(data)
+Sign objects are writable [streams](stream.html). The written data is
+used to generate the signature. Once all of the data has been
+written, the `sign` method will return the signature. The legacy
+`update` method is also supported.
-Updates the signer object with data.
-This can be called many times with new data as it is streamed.
+### sign.update(data)
+
+Updates the sign object with data. This can be called many times
+with new data as it is streamed.
-### signer.sign(private_key, [output_format])
+### sign.sign(private_key, [output_format])
-Calculates the signature on all the updated data passed through the signer.
-`private_key` is a string containing the PEM encoded private key for signing.
+Calculates the signature on all the updated data passed through the
+sign. `private_key` is a string containing the PEM encoded private
+key for signing.
-Returns the signature in `output_format` which can be `'binary'`, `'hex'` or
-`'base64'`. Defaults to `'binary'`.
+Returns the signature in `output_format` which can be `'binary'`,
+`'hex'` or `'base64'`. If no encoding is provided, then a buffer is
+returned.
-Note: `signer` object can not be used after `sign()` method been called.
+Note: `sign` object can not be used after `sign()` method been
+called.
## crypto.createVerify(algorithm)
@@ -233,33 +311,42 @@ Class for verifying signatures.
Returned by `crypto.createVerify`.
+Verify objects are writable [streams](stream.html). The written data
+is used to validate against the supplied signature. Once all of the
+data has been written, the `verify` method will return true if the
+supplied signature is valid. The legacy `update` method is also
+supported.
+
### verifier.update(data)
-Updates the verifier object with data.
-This can be called many times with new data as it is streamed.
+Updates the verifier object with data. This can be called many times
+with new data as it is streamed.
### verifier.verify(object, signature, [signature_format])
-Verifies the signed data by using the `object` and `signature`. `object` is a
-string containing a PEM encoded object, which can be one of RSA public key,
-DSA public key, or X.509 certificate. `signature` is the previously calculated
-signature for the data, in the `signature_format` which can be `'binary'`,
-`'hex'` or `'base64'`. Defaults to `'binary'`.
+Verifies the signed data by using the `object` and `signature`.
+`object` is a string containing a PEM encoded object, which can be
+one of RSA public key, DSA public key, or X.509 certificate.
+`signature` is the previously calculated signature for the data, in
+the `signature_format` which can be `'binary'`, `'hex'` or `'base64'`.
+If no encoding is specified, then a buffer is expected.
-Returns true or false depending on the validity of the signature for the data and public key.
+Returns true or false depending on the validity of the signature for
+the data and public key.
-Note: `verifier` object can not be used after `verify()` method been called.
+Note: `verifier` object can not be used after `verify()` method been
+called.
## crypto.createDiffieHellman(prime_length)
-Creates a Diffie-Hellman key exchange object and generates a prime of the
-given bit length. The generator used is `2`.
+Creates a Diffie-Hellman key exchange object and generates a prime of
+the given bit length. The generator used is `2`.
## crypto.createDiffieHellman(prime, [encoding])
-Creates a Diffie-Hellman key exchange object using the supplied prime. The
-generator used is `2`. Encoding can be `'binary'`, `'hex'`, or `'base64'`.
-Defaults to `'binary'`.
+Creates a Diffie-Hellman key exchange object using the supplied prime.
+The generator used is `2`. Encoding can be `'binary'`, `'hex'`, or
+`'base64'`. If no encoding is specified, then a buffer is expected.
## Class: DiffieHellman
@@ -269,64 +356,70 @@ Returned by `crypto.createDiffieHellman`.
### diffieHellman.generateKeys([encoding])
-Generates private and public Diffie-Hellman key values, and returns the
-public key in the specified encoding. This key should be transferred to the
-other party. Encoding can be `'binary'`, `'hex'`, or `'base64'`.
-Defaults to `'binary'`.
+Generates private and public Diffie-Hellman key values, and returns
+the public key in the specified encoding. This key should be
+transferred to the other party. Encoding can be `'binary'`, `'hex'`,
+or `'base64'`. If no encoding is provided, then a buffer is returned.
### diffieHellman.computeSecret(other_public_key, [input_encoding], [output_encoding])
-Computes the shared secret using `other_public_key` as the other party's
-public key and returns the computed shared secret. Supplied key is
-interpreted using specified `input_encoding`, and secret is encoded using
-specified `output_encoding`. Encodings can be `'binary'`, `'hex'`, or
-`'base64'`. The input encoding defaults to `'binary'`.
-If no output encoding is given, the input encoding is used as output encoding.
+Computes the shared secret using `other_public_key` as the other
+party's public key and returns the computed shared secret. Supplied
+key is interpreted using specified `input_encoding`, and secret is
+encoded using specified `output_encoding`. Encodings can be
+`'binary'`, `'hex'`, or `'base64'`. If the input encoding is not
+provided, then a buffer is expected.
+
+If no output encoding is given, then a buffer is returned.
### diffieHellman.getPrime([encoding])
-Returns the Diffie-Hellman prime in the specified encoding, which can be
-`'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`.
+Returns the Diffie-Hellman prime in the specified encoding, which can
+be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided,
+then a buffer is returned.
### diffieHellman.getGenerator([encoding])
-Returns the Diffie-Hellman prime in the specified encoding, which can be
-`'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`.
+Returns the Diffie-Hellman prime in the specified encoding, which can
+be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided,
+then a buffer is returned.
### diffieHellman.getPublicKey([encoding])
-Returns the Diffie-Hellman public key in the specified encoding, which can
-be `'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`.
+Returns the Diffie-Hellman public key in the specified encoding, which
+can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided,
+then a buffer is returned.
### diffieHellman.getPrivateKey([encoding])
-Returns the Diffie-Hellman private key in the specified encoding, which can
-be `'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`.
+Returns the Diffie-Hellman private key in the specified encoding,
+which can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is
+provided, then a buffer is returned.
### diffieHellman.setPublicKey(public_key, [encoding])
-Sets the Diffie-Hellman public key. Key encoding can be `'binary'`, `'hex'`,
-or `'base64'`. Defaults to `'binary'`.
+Sets the Diffie-Hellman public key. Key encoding can be `'binary'`,
+`'hex'` or `'base64'`. If no encoding is provided, then a buffer is
+expected.
-### diffieHellman.setPrivateKey(public_key, [encoding])
+### diffieHellman.setPrivateKey(private_key, [encoding])
-Sets the Diffie-Hellman private key. Key encoding can be `'binary'`, `'hex'`,
-or `'base64'`. Defaults to `'binary'`.
+Sets the Diffie-Hellman private key. Key encoding can be `'binary'`,
+`'hex'` or `'base64'`. If no encoding is provided, then a buffer is
+expected.
## crypto.getDiffieHellman(group_name)
-Creates a predefined Diffie-Hellman key exchange object.
-The supported groups are: `'modp1'`, `'modp2'`, `'modp5'`
-(defined in [RFC 2412][])
-and `'modp14'`, `'modp15'`, `'modp16'`, `'modp17'`, `'modp18'`
-(defined in [RFC 3526][]).
-The returned object mimics the interface of objects created by
-[crypto.createDiffieHellman()][] above, but
-will not allow to change the keys (with
-[diffieHellman.setPublicKey()][] for example).
-The advantage of using this routine is that the parties don't have to
-generate nor exchange group modulus beforehand, saving both processor and
-communication time.
+Creates a predefined Diffie-Hellman key exchange object. The
+supported groups are: `'modp1'`, `'modp2'`, `'modp5'` (defined in [RFC
+2412][]) and `'modp14'`, `'modp15'`, `'modp16'`, `'modp17'`,
+`'modp18'` (defined in [RFC 3526][]). The returned object mimics the
+interface of objects created by [crypto.createDiffieHellman()][]
+above, but will not allow to change the keys (with
+[diffieHellman.setPublicKey()][] for example). The advantage of using
+this routine is that the parties don't have to generate nor exchange
+group modulus beforehand, saving both processor and communication
+time.
Example (obtaining a shared secret):
@@ -337,8 +430,8 @@ Example (obtaining a shared secret):
alice.generateKeys();
bob.generateKeys();
- var alice_secret = alice.computeSecret(bob.getPublicKey(), 'binary', 'hex');
- var bob_secret = bob.computeSecret(alice.getPublicKey(), 'binary', 'hex');
+ var alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
+ var bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);
@@ -349,6 +442,10 @@ Asynchronous PBKDF2 applies pseudorandom function HMAC-SHA1 to derive
a key of given length from the given password, salt and iterations.
The callback gets two arguments `(err, derivedKey)`.
+## crypto.pbkdf2Sync(password, salt, iterations, keylen)
+
+Synchronous PBKDF2 function. Returns derivedKey or throws error.
+
## crypto.randomBytes(size, [callback])
Generates cryptographically strong pseudo-random data. Usage:
@@ -367,35 +464,46 @@ Generates cryptographically strong pseudo-random data. Usage:
// handle error
}
-## Proposed API Changes in Future Versions of Node
+## crypto.DEFAULT_ENCODING
+
+The default encoding to use for functions that can take either strings
+or buffers. The default value is `'buffer'`, which makes it default
+to using Buffer objects. This is here to make the crypto module more
+easily compatible with legacy programs that expected `'binary'` to be
+the default encoding.
+
+Note that new programs will probably expect buffers, so only use this
+as a temporary measure.
+
+## Recent API Changes
The Crypto module was added to Node before there was the concept of a
unified Stream API, and before there were Buffer objects for handling
binary data.
As such, the streaming classes don't have the typical methods found on
-other Node classes, and many methods accept and return Binary-encoded
-strings by default rather than Buffers.
+other Node classes, and many methods accepted and returned
+Binary-encoded strings by default rather than Buffers. This was
+changed to use Buffers by default instead.
-A future version of node will make Buffers the default data type.
-This will be a breaking change for some use cases, but not all.
+This is a breaking change for some use cases, but not all.
For example, if you currently use the default arguments to the Sign
class, and then pass the results to the Verify class, without ever
inspecting the data, then it will continue to work as before. Where
-you now get a binary string and then present the binary string to the
-Verify object, you'll get a Buffer, and present the Buffer to the
-Verify object.
+you once got a binary string and then presented the binary string to
+the Verify object, you'll now get a Buffer, and present the Buffer to
+the Verify object.
-However, if you are doing things with the string data that will not
+However, if you were doing things with the string data that will not
work properly on Buffers (such as, concatenating them, storing in
databases, etc.), or you are passing binary strings to the crypto
functions without an encoding argument, then you will need to start
providing encoding arguments to specify which encoding you'd like to
-use.
-
-Also, a Streaming API will be provided, but this will be done in such
-a way as to preserve the legacy API surface.
+use. To switch to the previous style of using binary strings by
+default, set the `crypto.DEFAULT_ENCODING` field to 'binary'. Note
+that new programs will probably expect buffers, so only use this as a
+temporary measure.
[createCipher()]: #crypto_crypto_createcipher_algorithm_password
diff --git a/doc/api/debugger.markdown b/doc/api/debugger.markdown
index ed37f0c02..63f2d49c8 100644
--- a/doc/api/debugger.markdown
+++ b/doc/api/debugger.markdown
@@ -136,3 +136,10 @@ breakpoint)
The V8 debugger can be enabled and accessed either by starting Node with
the `--debug` command-line flag or by signaling an existing Node process
with `SIGUSR1`.
+
+Once a process has been set in debug mode with this it can be connected to
+with the node debugger. Either connect to the `pid` or the URI to the debugger.
+The syntax is:
+
+* `node debug -p <pid>` - Connects to the process via the `pid`
+* `node debug <URI> - Connects to the process via the URI such as localhost:5858
diff --git a/doc/api/dgram.markdown b/doc/api/dgram.markdown
index a14a42bde..2c52c5612 100644
--- a/doc/api/dgram.markdown
+++ b/doc/api/dgram.markdown
@@ -207,3 +207,15 @@ this.
If `multicastInterface` is not specified, the OS will try to drop membership to all valid
interfaces.
+
+### dgram.unref()
+
+Calling `unref` on a socket will allow the program to exit if this is the only
+active socket in the event system. If the socket is already `unref`d calling
+`unref` again will have no effect.
+
+### dgram.ref()
+
+Opposite of `unref`, calling `ref` on a previously `unref`d socket will *not*
+let the program exit if it's the only socket left (the default behavior). If
+the socket is `ref`d calling `ref` again will have no effect.
diff --git a/doc/api/documentation.markdown b/doc/api/documentation.markdown
index 70a76c248..6ef71896b 100644
--- a/doc/api/documentation.markdown
+++ b/doc/api/documentation.markdown
@@ -31,32 +31,46 @@ proven, and so relied upon, that they are unlikely to ever change at
all. Others are brand new and experimental, or known to be hazardous
and in the process of being redesigned.
-The notices look like this:
-
- Stability: 1 Experimental
-
The stability indices are as follows:
-* **0 - Deprecated** This feature is known to be problematic, and changes are
+```
+Stability: 0 - Deprecated
+This feature is known to be problematic, and changes are
planned. Do not rely on it. Use of the feature may cause warnings. Backwards
compatibility should not be expected.
+```
-* **1 - Experimental** This feature was introduced recently, and may change
+```
+Stability: 1 - Experimental
+This feature was introduced recently, and may change
or be removed in future versions. Please try it out and provide feedback.
If it addresses a use-case that is important to you, tell the node core team.
+```
-* **2 - Unstable** The API is in the process of settling, but has not yet had
+```
+Stability: 2 - Unstable
+The API is in the process of settling, but has not yet had
sufficient real-world testing to be considered stable. Backwards-compatibility
will be maintained if reasonable.
+```
-* **3 - Stable** The API has proven satisfactory, but cleanup in the underlying
+```
+Stability: 3 - Stable
+The API has proven satisfactory, but cleanup in the underlying
code may cause minor changes. Backwards-compatibility is guaranteed.
+```
-* **4 - API Frozen** This API has been tested extensively in production and is
+```
+Stability: 4 - API Frozen
+This API has been tested extensively in production and is
unlikely to ever have to change.
+```
-* **5 - Locked** Unless serious bugs are found, this code will not ever
+```
+Stability: 5 - Locked
+Unless serious bugs are found, this code will not ever
change. Please do not suggest changes in this area; they will be refused.
+```
## JSON Output
diff --git a/doc/api/domain.markdown b/doc/api/domain.markdown
index 24acd295b..4161e2579 100644
--- a/doc/api/domain.markdown
+++ b/doc/api/domain.markdown
@@ -27,11 +27,11 @@ Any time an Error object is routed through a domain, a few extra fields
are added to it.
* `error.domain` The domain that first handled the error.
-* `error.domain_emitter` The event emitter that emitted an 'error' event
+* `error.domainEmitter` The event emitter that emitted an 'error' event
with the error object.
-* `error.domain_bound` The callback function which was bound to the
+* `error.domainBound` The callback function which was bound to the
domain, and passed an error as its first argument.
-* `error.domain_thrown` A boolean indicating whether the error was
+* `error.domainThrown` A boolean indicating whether the error was
thrown, emitted, or passed to a bound callback function.
## Implicit Binding
diff --git a/doc/api/events.markdown b/doc/api/events.markdown
index b9be5dc5a..7998684e7 100644
--- a/doc/api/events.markdown
+++ b/doc/api/events.markdown
@@ -26,7 +26,7 @@ If there is no listener for it, then the default action is to print a stack
trace and exit the program.
All EventEmitters emit the event `'newListener'` when new listeners are
-added.
+added and `'removeListener'` when a listener is removed.
### emitter.addListener(event, listener)
### emitter.on(event, listener)
@@ -64,9 +64,6 @@ Remove a listener from the listener array for the specified event.
Removes all listeners, or those of the specified event.
-Note that this will **invalidate** any arrays that have previously been
-returned by `emitter.listeners(event)`.
-
### emitter.setMaxListeners(n)
@@ -85,19 +82,6 @@ Returns an array of listeners for the specified event.
});
console.log(util.inspect(server.listeners('connection'))); // [ [Function] ]
-This array **may** be a mutable reference to the same underlying list of
-listeners that is used by the event subsystem. However, certain
-actions (specifically, removeAllListeners) will invalidate this
-reference.
-
-If you would like to get a copy of the listeners at a specific point in
-time that is guaranteed not to change, make a copy, for example by doing
-`emitter.listeners(event).slice(0)`.
-
-In a future release of node, this behavior **may** change to always
-return a copy, for consistency. In your programs, please do not rely on
-being able to modify the EventEmitter listeners using array methods.
-Always use the 'on' method to add new listeners.
### emitter.emit(event, [arg1], [arg2], [...])
diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown
index a6b31e63f..100bcc19d 100644
--- a/doc/api/fs.markdown
+++ b/doc/api/fs.markdown
@@ -59,8 +59,31 @@ In busy processes, the programmer is _strongly encouraged_ to use the
asynchronous versions of these calls. The synchronous versions will block
the entire process until they complete--halting all connections.
-Relative path to filename can be used, remember however that this path will be relative
-to `process.cwd()`.
+Relative path to filename can be used, remember however that this path will be
+relative to `process.cwd()`.
+
+Most fs functions let you omit the callback argument. If you do, a default
+callback is used that rethrows errors. To get a trace to the original call
+site, set the NODE_DEBUG environment variable:
+
+ $ cat script.js
+ function bad() {
+ require('fs').readFile('/');
+ }
+ bad();
+
+ $ env NODE_DEBUG=fs node script.js
+ fs.js:66
+ throw err;
+ ^
+ Error: EISDIR, read
+ at rethrow (fs.js:61:21)
+ at maybeCallback (fs.js:79:42)
+ at Object.fs.readFile (fs.js:153:18)
+ at bad (/path/to/script.js:2:17)
+ at Object.<anonymous> (/path/to/script.js:5:1)
+ <etc.>
+
## fs.rename(oldPath, newPath, [callback])
@@ -71,15 +94,24 @@ to the completion callback.
Synchronous rename(2).
-## fs.truncate(fd, len, [callback])
+## fs.ftruncate(fd, len, [callback])
Asynchronous ftruncate(2). No arguments other than a possible exception are
given to the completion callback.
-## fs.truncateSync(fd, len)
+## fs.ftruncateSync(fd, len)
Synchronous ftruncate(2).
+## fs.truncate(path, len, [callback])
+
+Asynchronous truncate(2). No arguments other than a possible exception are
+given to the completion callback.
+
+## fs.truncateSync(path, len)
+
+Synchronous truncate(2).
+
## fs.chown(path, uid, gid, [callback])
Asynchronous chown(2). No arguments other than a possible exception are given
@@ -602,13 +634,20 @@ Returns a new ReadStream object (See `Readable Stream`).
encoding: null,
fd: null,
mode: 0666,
- bufferSize: 64 * 1024
+ bufferSize: 64 * 1024,
+ autoClose: true
}
`options` can include `start` and `end` values to read a range of bytes from
the file instead of the entire file. Both `start` and `end` are inclusive and
start at 0. The `encoding` can be `'utf8'`, `'ascii'`, or `'base64'`.
+If `autoClose` is false, then the file descriptor won't be closed, even if
+there's an error. It is your responsiblity to close it and make sure
+there's no file descriptor leak. If `autoClose` is set to true (default
+behavior), on `error` or `end` the file descriptor will be closed
+automatically.
+
An example to read the last 10 bytes of a file which is 100 bytes long:
fs.createReadStream('sample.txt', {start: 90, end: 99});
diff --git a/doc/api/http.markdown b/doc/api/http.markdown
index 59a9f8a30..6c1e2b412 100644
--- a/doc/api/http.markdown
+++ b/doc/api/http.markdown
@@ -56,7 +56,7 @@ This is an [EventEmitter][] with the following events:
Emitted each time there is a request. Note that there may be multiple requests
per connection (in the case of keep-alive connections).
- `request` is an instance of `http.ServerRequest` and `response` is
+ `request` is an instance of `http.IncomingMessage` and `response` is
an instance of `http.ServerResponse`
### Event: 'connection'
@@ -127,10 +127,13 @@ sent to the server on that socket.
### Event: 'clientError'
-`function (exception) { }`
+`function (exception, socket) { }`
If a client connection emits an 'error' event - it will forwarded here.
+`socket` is the `net.Socket` object that the error originated from.
+
+
### server.listen(port, [hostname], [backlog], [callback])
Begin accepting connections on the specified port and hostname. If the
@@ -185,133 +188,6 @@ Limits maximum incoming headers count, equal to 1000 by default. If set to 0 -
no limit will be applied.
-## Class: http.ServerRequest
-
-This object is created internally by a HTTP server -- not by
-the user -- and passed as the first argument to a `'request'` listener.
-
-The request implements the [Readable Stream][] interface. This is an
-[EventEmitter][] with the following events:
-
-### Event: 'data'
-
-`function (chunk) { }`
-
-Emitted when a piece of the message body is received. The chunk is a string if
-an encoding has been set with `request.setEncoding()`, otherwise it's a
-[Buffer][].
-
-Note that the __data will be lost__ if there is no listener when a
-`ServerRequest` emits a `'data'` event.
-
-### Event: 'end'
-
-`function () { }`
-
-Emitted exactly once for each request. After that, no more `'data'` events
-will be emitted on the request.
-
-### Event: 'close'
-
-`function () { }`
-
-Indicates that the underlaying connection was terminated before
-`response.end()` was called or able to flush.
-
-Just like `'end'`, this event occurs only once per request, and no more `'data'`
-events will fire afterwards.
-
-Note: `'close'` can fire after `'end'`, but not vice versa.
-
-### request.method
-
-The request method as a string. Read only. Example:
-`'GET'`, `'DELETE'`.
-
-
-### request.url
-
-Request URL string. This contains only the URL that is
-present in the actual HTTP request. If the request is:
-
- GET /status?name=ryan HTTP/1.1\r\n
- Accept: text/plain\r\n
- \r\n
-
-Then `request.url` will be:
-
- '/status?name=ryan'
-
-If you would like to parse the URL into its parts, you can use
-`require('url').parse(request.url)`. Example:
-
- node> require('url').parse('/status?name=ryan')
- { href: '/status?name=ryan',
- search: '?name=ryan',
- query: 'name=ryan',
- pathname: '/status' }
-
-If you would like to extract the params from the query string,
-you can use the `require('querystring').parse` function, or pass
-`true` as the second argument to `require('url').parse`. Example:
-
- node> require('url').parse('/status?name=ryan', true)
- { href: '/status?name=ryan',
- search: '?name=ryan',
- query: { name: 'ryan' },
- pathname: '/status' }
-
-
-
-### request.headers
-
-Read only map of header names and values. Header names are lower-cased.
-Example:
-
- // Prints something like:
- //
- // { 'user-agent': 'curl/7.22.0',
- // host: '127.0.0.1:8000',
- // accept: '*/*' }
- console.log(request.headers);
-
-
-### request.trailers
-
-Read only; HTTP trailers (if present). Only populated after the 'end' event.
-
-### request.httpVersion
-
-The HTTP protocol version as a string. Read only. Examples:
-`'1.1'`, `'1.0'`.
-Also `request.httpVersionMajor` is the first integer and
-`request.httpVersionMinor` is the second.
-
-
-### request.setEncoding([encoding])
-
-Set the encoding for the request body. See [stream.setEncoding()][] for more
-information.
-
-### request.pause()
-
-Pauses request from emitting events. Useful to throttle back an upload.
-
-
-### request.resume()
-
-Resumes a paused request.
-
-### request.connection
-
-The `net.Socket` object associated with the connection.
-
-
-With HTTPS support, use request.connection.verifyPeer() and
-request.connection.getPeerCertificate() to obtain the client's
-authentication details.
-
-
## Class: http.ServerResponse
@@ -387,6 +263,10 @@ or
response.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]);
+### response.headersSent
+
+Boolean (read-only). True if headers were sent, false otherwise.
+
### response.sendDate
When true, the Date header will be automatically generated and sent in
@@ -630,7 +510,7 @@ data chunk or when closing the connection.
To get the response, add a listener for `'response'` to the request object.
`'response'` will be emitted from the request object when the response
headers have been received. The `'response'` event is executed with one
-argument which is an instance of `http.ClientResponse`.
+argument which is an instance of `http.IncomingMessage`.
During the `'response'` event, one can add listeners to the
response object; particularly to listen for the `'data'` event. Note that
@@ -667,7 +547,7 @@ The request implements the [Writable Stream][] interface. This is an
`function (response) { }`
Emitted when a response is received to this request. This event is emitted only
-once. The `response` argument will be an instance of `http.ClientResponse`.
+once. The `response` argument will be an instance of `http.IncomingMessage`.
Options:
@@ -843,24 +723,26 @@ Once a socket is assigned to this request and is connected
Once a socket is assigned to this request and is connected
[socket.setKeepAlive()][] will be called.
-## http.ClientResponse
-This object is created when making a request with `http.request()`. It is
-passed to the `'response'` event of the request object.
+## http.IncomingMessage
-The response implements the [Readable Stream][] interface. This is an
-[EventEmitter][] with the following events:
+An `IncomingMessage` object is created by `http.Server` or `http.ClientRequest`
+and passed as the first argument to the `'request'` and `'response'` event
+respectively. It may be used to access response status, headers and data.
+It implements the [Readable Stream][] interface. `http.IncomingMessage` is an
+[EventEmitter][] with the following events:
### Event: 'data'
`function (chunk) { }`
-Emitted when a piece of the message body is received.
+Emitted when a piece of the message body is received. The chunk is a string if
+an encoding has been set with `message.setEncoding()`, otherwise it's
+a [Buffer][].
Note that the __data will be lost__ if there is no listener when a
-`ClientResponse` emits a `'data'` event.
-
+`IncomingMessage` emits a `'data'` event.
### Event: 'end'
@@ -869,7 +751,6 @@ Note that the __data will be lost__ if there is no listener when a
Emitted exactly once for each response. After that, no more `'data'` events
will be emitted on the response.
-
### Event: 'close'
`function () { }`
@@ -883,38 +764,103 @@ event for more information.
Note: `'close'` can fire after `'end'`, but not vice versa.
+### message.httpVersion
-### response.statusCode
-
-The 3-digit HTTP response status code. E.G. `404`.
+In case of server request, the HTTP version sent by the client. In the case of
+client response, the HTTP version of the connected-to server.
+Probably either `'1.1'` or `'1.0'`.
-### response.httpVersion
-
-The HTTP version of the connected-to server. Probably either
-`'1.1'` or `'1.0'`.
Also `response.httpVersionMajor` is the first integer and
`response.httpVersionMinor` is the second.
-### response.headers
+### message.headers
-The response headers object.
+The request/response headers object.
-### response.trailers
+Read only map of header names and values. Header names are lower-cased.
+Example:
-The response trailers object. Only populated after the 'end' event.
+ // Prints something like:
+ //
+ // { 'user-agent': 'curl/7.22.0',
+ // host: '127.0.0.1:8000',
+ // accept: '*/*' }
+ console.log(request.headers);
+
+### message.trailers
+
+The request/response trailers object. Only populated after the 'end' event.
-### response.setEncoding([encoding])
+### message.setEncoding([encoding])
-Set the encoding for the response body. See [stream.setEncoding()][] for more
+Set the encoding for data emitted by the `'data'` event. See [stream.setEncoding()][] for more
information.
-### response.pause()
+Should be set before any `'data'` events have been emitted.
+
+### message.pause()
+
+Pauses request/response from emitting events. Useful to throttle back a download.
+
+### message.resume()
+
+Resumes a paused request/response.
+
+### message.method
+
+**Only valid for request obtained from `http.Server`.**
+
+The request method as a string. Read only. Example:
+`'GET'`, `'DELETE'`.
+
+### message.url
+
+**Only valid for request obtained from `http.Server`.**
+
+Request URL string. This contains only the URL that is
+present in the actual HTTP request. If the request is:
+
+ GET /status?name=ryan HTTP/1.1\r\n
+ Accept: text/plain\r\n
+ \r\n
-Pauses response from emitting events. Useful to throttle back a download.
+Then `request.url` will be:
+
+ '/status?name=ryan'
+
+If you would like to parse the URL into its parts, you can use
+`require('url').parse(request.url)`. Example:
-### response.resume()
+ node> require('url').parse('/status?name=ryan')
+ { href: '/status?name=ryan',
+ search: '?name=ryan',
+ query: 'name=ryan',
+ pathname: '/status' }
+
+If you would like to extract the params from the query string,
+you can use the `require('querystring').parse` function, or pass
+`true` as the second argument to `require('url').parse`. Example:
+
+ node> require('url').parse('/status?name=ryan', true)
+ { href: '/status?name=ryan',
+ search: '?name=ryan',
+ query: { name: 'ryan' },
+ pathname: '/status' }
+
+### message.statusCode
+
+**Only valid for response obtained from `http.ClientRequest`.**
+
+The 3-digit HTTP response status code. E.G. `404`.
+
+### message.socket
+
+The `net.Socket` object associated with the connection.
+
+With HTTPS support, use request.connection.verifyPeer() and
+request.connection.getPeerCertificate() to obtain the client's
+authentication details.
-Resumes a paused response.
[Agent]: #http_class_http_agent
['checkContinue']: #http_event_checkcontinue
@@ -922,7 +868,7 @@ Resumes a paused response.
[EventEmitter]: events.html#events_class_events_eventemitter
[global Agent]: #http_http_globalagent
[http.request()]: #http_http_request_options_callback
-[http.ServerRequest]: #http_class_http_serverrequest
+[http.IncomingMessage]: #http_class_http_incomingmessage
['listening']: net.html#net_event_listening
[net.Server.close()]: net.html#net_server_close_callback
[net.Server.listen(path)]: net.html#net_server_listen_path_callback
diff --git a/doc/api/https.markdown b/doc/api/https.markdown
index 1e2642d98..4ae61e6a7 100644
--- a/doc/api/https.markdown
+++ b/doc/api/https.markdown
@@ -125,7 +125,7 @@ The following options from [tls.connect()][] can also be specified. However, a
- `rejectUnauthorized`: If `true`, the server certificate is verified against
the list of supplied CAs. An `'error'` event is emitted if verification
fails. Verification happens at the connection level, *before* the HTTP
- request is sent. Default `false`.
+ request is sent. Default `true`.
In order to specify these options, use a custom `Agent`.
diff --git a/doc/api/net.markdown b/doc/api/net.markdown
index 7f81c2603..160e2375e 100644
--- a/doc/api/net.markdown
+++ b/doc/api/net.markdown
@@ -207,6 +207,18 @@ Example:
Don't call `server.address()` until the `'listening'` event has been emitted.
+### server.unref()
+
+Calling `unref` on a server will allow the program to exit if this is the only
+active server in the event system. If the server is already `unref`d calling
+`unref` again will have no effect.
+
+### server.ref()
+
+Opposite of `unref`, calling `ref` on a previously `unref`d server will *not*
+let the program exit if it's the only server left (the default behavior). If
+the server is `ref`d calling `ref` again will have no effect.
+
### server.maxConnections
Set this property to reject connections when the server's connection count gets
@@ -217,12 +229,22 @@ with `child_process.fork()`.
### server.connections
+This function is **deprecated**; please use [server.getConnections()][] instead.
The number of concurrent connections on the server.
-This becomes `null` when sending a socket to a child with `child_process.fork()`.
+This becomes `null` when sending a socket to a child with
+`child_process.fork()`. To poll forks and get current number of active
+connections use asynchronous `server.getConnections` instead.
`net.Server` is an [EventEmitter][] with the following events:
+### server.getConnections(callback)
+
+Asynchronously get the number of concurrent connections on the server. Works
+when sockets were sent to forks.
+
+Callback should take two arguments `err` and `count`.
+
### Event: 'listening'
Emitted when the server has been bound after calling `server.listen`.
@@ -384,6 +406,18 @@ socket as reported by the operating system. Returns an object with
three properties, e.g.
`{ port: 12346, family: 'IPv4', address: '127.0.0.1' }`
+### socket.unref()
+
+Calling `unref` on a socket will allow the program to exit if this is the only
+active socket in the event system. If the socket is already `unref`d calling
+`unref` again will have no effect.
+
+### socket.ref()
+
+Opposite of `unref`, calling `ref` on a previously `unref`d socket will *not*
+let the program exit if it's the only socket left (the default behavior). If
+the socket is `ref`d calling `ref` again will have no effect.
+
### socket.remoteAddress
The string representation of the remote IP address. For example,
@@ -394,6 +428,17 @@ The string representation of the remote IP address. For example,
The numeric representation of the remote port. For example,
`80` or `21`.
+### socket.localAddress
+
+The string representation of the local IP address the remote client is
+connecting on. For example, if you are listening on `'0.0.0.0'` and the
+client connects on `'192.168.1.1'`, the value would be `'192.168.1.1'`.
+
+### socket.localPort
+
+The numeric representation of the local port. For example,
+`80` or `21`.
+
### socket.bytesRead
The amount of received bytes.
diff --git a/doc/api/os.markdown b/doc/api/os.markdown
index b5fffcf1c..ae620e895 100644
--- a/doc/api/os.markdown
+++ b/doc/api/os.markdown
@@ -6,10 +6,14 @@ Provides a few basic operating-system related utility functions.
Use `require('os')` to access this module.
-## os.tmpDir()
+## os.tmpdir()
Returns the operating system's default directory for temp files.
+## os.endianness()
+
+Returns the endianness of the CPU. Possible values are `"BE"` or `"LE"`.
+
## os.hostname()
Returns the hostname of the operating system.
@@ -48,7 +52,9 @@ Returns the amount of free system memory in bytes.
## os.cpus()
-Returns an array of objects containing information about each CPU/core installed: model, speed (in MHz), and times (an object containing the number of CPU ticks spent in: user, nice, sys, idle, and irq).
+Returns an array of objects containing information about each CPU/core
+installed: model, speed (in MHz), and times (an object containing the number of
+milliseconds the CPU/core spent in: user, nice, sys, idle, and irq).
Example inspection of os.cpus:
diff --git a/doc/api/path.markdown b/doc/api/path.markdown
index d178b53f1..2541c62d8 100644
--- a/doc/api/path.markdown
+++ b/doc/api/path.markdown
@@ -14,7 +14,7 @@ Normalize a string path, taking care of `'..'` and `'.'` parts.
When multiple slashes are found, they're replaced by a single one;
when the path contains a trailing slash, it is preserved.
-On windows backslashes are used.
+On Windows backslashes are used.
Example:
@@ -44,7 +44,7 @@ Resolves `to` to an absolute path.
If `to` isn't already absolute `from` arguments are prepended in right to left
order, until an absolute path is found. If after using all `from` paths still
no absolute path is found, the current working directory is used as well. The
-resulting path is normalized, and trailing slashes are removed unless the path
+resulting path is normalized, and trailing slashes are removed unless the path
gets resolved to the root directory. Non-string arguments are ignored.
Another way to think of it is as a sequence of `cd` commands in a shell.
@@ -143,14 +143,36 @@ an empty string. Examples:
The platform-specific file separator. `'\\'` or `'/'`.
-An example on linux:
+An example on *nix:
'foo/bar/baz'.split(path.sep)
// returns
['foo', 'bar', 'baz']
-An example on windows:
+An example on Windows:
'foo\\bar\\baz'.split(path.sep)
// returns
['foo', 'bar', 'baz']
+
+## path.delimiter
+
+The platform-specific path delimiter, `;` or `':'`.
+
+An example on *nix:
+
+ console.log(process.env.PATH)
+ // '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'
+
+ process.env.PATH.split(path.delimiter)
+ // returns
+ ['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin']
+
+An example on Windows:
+
+ console.log(process.env.PATH)
+ // 'C:\Windows\system32;C:\Windows;C:\Program Files\nodejs\'
+
+ process.env.PATH.split(path.delimiter)
+ // returns
+ ['C:\Windows\system32', 'C:\Windows', 'C:\Program Files\nodejs\']
diff --git a/doc/api/process.markdown b/doc/api/process.markdown
index 793813353..a6f160d94 100644
--- a/doc/api/process.markdown
+++ b/doc/api/process.markdown
@@ -15,10 +15,10 @@ timers may not be scheduled.
Example of listening for `exit`:
- process.on('exit', function () {
- process.nextTick(function () {
- console.log('This will not run');
- });
+ process.on('exit', function() {
+ setTimeout(function() {
+ console.log('This will not run');
+ }, 0);
console.log('About to exit.');
});
@@ -30,11 +30,11 @@ a stack trace and exit) will not occur.
Example of listening for `uncaughtException`:
- process.on('uncaughtException', function (err) {
+ process.on('uncaughtException', function(err) {
console.log('Caught exception: ' + err);
});
- setTimeout(function () {
+ setTimeout(function() {
console.log('This will still run.');
}, 500);
@@ -70,7 +70,7 @@ Example of listening for `SIGINT`:
// Start reading from stdin so we don't exit.
process.stdin.resume();
- process.on('SIGINT', function () {
+ process.on('SIGINT', function() {
console.log('Got SIGINT. Press Control-D to exit.');
});
@@ -84,7 +84,7 @@ A `Writable Stream` to `stdout`.
Example: the definition of `console.log`
- console.log = function (d) {
+ console.log = function(d) {
process.stdout.write(d + '\n');
};
@@ -114,11 +114,11 @@ Example of opening standard input and listening for both events:
process.stdin.resume();
process.stdin.setEncoding('utf8');
- process.stdin.on('data', function (chunk) {
+ process.stdin.on('data', function(chunk) {
process.stdout.write('data: ' + chunk);
});
- process.stdin.on('end', function () {
+ process.stdin.on('end', function() {
process.stdout.write('end');
});
@@ -130,7 +130,7 @@ An array containing the command line arguments. The first element will be
next elements will be any additional command line arguments.
// print process.argv
- process.argv.forEach(function (val, index, array) {
+ process.argv.forEach(function(val, index, array) {
console.log(index + ': ' + val);
});
@@ -261,6 +261,43 @@ blocks while resolving it to a numerical ID.
}
+## process.getgroups()
+
+Note: this function is only available on POSIX platforms (i.e. not Windows)
+
+Returns an array with the supplementary group IDs. POSIX leaves it unspecified
+if the effective group ID is included but node.js ensures it always is.
+
+
+## process.setgroups(groups)
+
+Note: this function is only available on POSIX platforms (i.e. not Windows)
+
+Sets the supplementary group IDs. This is a privileged operation, meaning you
+need to be root or have the CAP_SETGID capability.
+
+The list can contain group IDs, group names or both.
+
+
+## process.initgroups(user, extra_group)
+
+Note: this function is only available on POSIX platforms (i.e. not Windows)
+
+Reads /etc/group and initializes the group access list, using all groups of
+which the user is a member. This is a privileged operation, meaning you need
+to be root or have the CAP_SETGID capability.
+
+`user` is a user name or user ID. `extra_group` is a group name or group ID.
+
+Some care needs to be taken when dropping privileges. Example:
+
+ console.log(process.getgroups()); // [ 0 ]
+ process.initgroups('bnoordhuis', 1000); // switch user
+ console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ]
+ process.setgid(1000); // drop root gid
+ console.log(process.getgroups()); // [ 27, 30, 46, 1000 ]
+
+
## process.version
A compiled-in property that exposes `NODE_VERSION`.
@@ -298,8 +335,10 @@ An example of the possible output looks like:
variables:
{ host_arch: 'x64',
node_install_npm: 'true',
- node_install_waf: 'true',
node_prefix: '',
+ node_shared_cares: 'false',
+ node_shared_http_parser: 'false',
+ node_shared_libuv: 'false',
node_shared_v8: 'false',
node_shared_zlib: 'false',
node_use_dtrace: 'false',
@@ -322,11 +361,11 @@ may do something other than kill the target process.
Example of sending a signal to yourself:
- process.on('SIGHUP', function () {
+ process.on('SIGHUP', function() {
console.log('Got SIGHUP signal.');
});
- setTimeout(function () {
+ setTimeout(function() {
console.log('Exiting.');
process.exit(0);
}, 100);
@@ -382,12 +421,85 @@ This will generate:
On the next loop around the event loop call this callback.
This is *not* a simple alias to `setTimeout(fn, 0)`, it's much more
-efficient.
+efficient. It typically runs before any other I/O events fire, but there
+are some exceptions. See `process.maxTickDepth` below.
- process.nextTick(function () {
+ process.nextTick(function() {
console.log('nextTick callback');
});
+This is important in developing APIs where you want to give the user the
+chance to assign event handlers after an object has been constructed,
+but before any I/O has occurred.
+
+ function MyThing(options) {
+ this.setupOptions(options);
+
+ process.nextTick(function() {
+ this.startDoingStuff();
+ }.bind(this));
+ }
+
+ var thing = new MyThing();
+ thing.getReadyForStuff();
+
+ // thing.startDoingStuff() gets called now, not before.
+
+It is very important for APIs to be either 100% synchronous or 100%
+asynchronous. Consider this example:
+
+ // WARNING! DO NOT USE! BAD UNSAFE HAZARD!
+ function maybeSync(arg, cb) {
+ if (arg) {
+ cb();
+ return;
+ }
+
+ fs.stat('file', cb);
+ }
+
+This API is hazardous. If you do this:
+
+ maybeSync(true, function() {
+ foo();
+ });
+ bar();
+
+then it's not clear whether `foo()` or `bar()` will be called first.
+
+This approach is much better:
+
+ function definitelyAsync(arg, cb) {
+ if (arg) {
+ process.nextTick(cb);
+ return;
+ }
+
+ fs.stat('file', cb);
+ }
+
+## process.maxTickDepth
+
+* {Number} Default = 1000
+
+Callbacks passed to `process.nextTick` will *usually* be called at the
+end of the current flow of execution, and are thus approximately as fast
+as calling a function synchronously. Left unchecked, this would starve
+the event loop, preventing any I/O from occurring.
+
+Consider this code:
+
+ process.nextTick(function foo() {
+ process.nextTick(foo);
+ });
+
+In order to avoid the situation where Node is blocked by an infinite
+loop of recursive series of nextTick calls, it defers to allow some I/O
+to be done every so often.
+
+The `process.maxTickDepth` value is the maximum depth of
+nextTick-calling nextTick-callbacks that will be evaluated before
+allowing other forms of I/O to occur.
## process.umask([mask])
@@ -420,7 +532,7 @@ a diff reading, useful for benchmarks and measuring intervals:
var time = process.hrtime();
// [ 1800216, 25 ]
- setTimeout(function () {
+ setTimeout(function() {
var diff = process.hrtime(time);
// [ 1, 552 ]
diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown
index 5e0c6f642..ebb771dd5 100644
--- a/doc/api/stream.markdown
+++ b/doc/api/stream.markdown
@@ -7,186 +7,527 @@ Node. For example a request to an HTTP server is a stream, as is
stdout. Streams are readable, writable, or both. All streams are
instances of [EventEmitter][]
-You can load up the Stream base class by doing `require('stream')`.
+You can load the Stream base classes by doing `require('stream')`.
+There are base classes provided for Readable streams, Writable
+streams, Duplex streams, and Transform streams.
-## Readable Stream
+## Compatibility
+
+In earlier versions of Node, the Readable stream interface was
+simpler, but also less powerful and less useful.
+
+* Rather than waiting for you to call the `read()` method, `'data'`
+ events would start emitting immediately. If you needed to do some
+ I/O to decide how to handle data, then you had to store the chunks
+ in some kind of buffer so that they would not be lost.
+* The `pause()` method was advisory, rather than guaranteed. This
+ meant that you still had to be prepared to receive `'data'` events
+ even when the stream was in a paused state.
+
+In Node v0.10, the Readable class described below was added. For
+backwards compatibility with older Node programs, Readable streams
+switch into "old mode" when a `'data'` event handler is added, or when
+the `pause()` or `resume()` methods are called. The effect is that,
+even if you are not using the new `read()` method and `'readable'`
+event, you no longer have to worry about losing `'data'` chunks.
+
+Most programs will continue to function normally. However, this
+introduces an edge case in the following conditions:
+
+* No `'data'` event handler is added.
+* The `pause()` and `resume()` methods are never called.
+
+For example, consider the following code:
+
+```javascript
+// WARNING! BROKEN!
+net.createServer(function(socket) {
+
+ // we add an 'end' method, but never consume the data
+ socket.on('end', function() {
+ // It will never get here.
+ socket.end('I got your message (but didnt read it)\n');
+ });
+
+}).listen(1337);
+```
+
+In versions of node prior to v0.10, the incoming message data would be
+simply discarded. However, in Node v0.10 and beyond, the socket will
+remain paused forever.
+
+The workaround in this situation is to call the `resume()` method to
+trigger "old mode" behavior:
+
+```javascript
+// Workaround
+net.createServer(function(socket) {
+
+ socket.on('end', function() {
+ socket.end('I got your message (but didnt read it)\n');
+ });
+
+ // start the flow of data, discarding it.
+ socket.resume();
+
+}).listen(1337);
+```
+
+In addition to new Readable streams switching into old-mode, pre-v0.10
+style streams can be wrapped in a Readable class using the `wrap()`
+method.
+
+## Class: stream.Readable
<!--type=class-->
A `Readable Stream` has the following methods, members, and events.
-### Event: 'data'
+Note that `stream.Readable` is an abstract class designed to be
+extended with an underlying implementation of the `_read(size, cb)`
+method. (See below.)
-`function (data) { }`
+### new stream.Readable([options])
-The `'data'` event emits either a `Buffer` (by default) or a string if
-`setEncoding()` was used.
+* `options` {Object}
+ * `bufferSize` {Number} The size of the chunks to consume from the
+ underlying resource. Default=16kb
+ * `highWaterMark` {Number} The maximum number of bytes to store in
+ the internal buffer before ceasing to read from the underlying
+ resource. Default=16kb
+ * `encoding` {String} If specified, then buffers will be decoded to
+ strings using the specified encoding. Default=null
+ * `objectMode` {Boolean} Whether this stream should behave
+ as a stream of objects. Meaning that stream.read(n) returns
+ a single value instead of a Buffer of size n
-Note that the __data will be lost__ if there is no listener when a
-`Readable Stream` emits a `'data'` event.
+In classes that extend the Readable class, make sure to call the
+constructor so that the buffering settings can be properly
+initialized.
-### Event: 'end'
+### readable.\_read(size, callback)
+
+* `size` {Number} Number of bytes to read asynchronously
+* `callback` {Function} Called with an error or with data
+
+All Readable stream implementations must provide a `_read` method
+to fetch data from the underlying resource.
+
+Note: **This function MUST NOT be called directly.** It should be
+implemented by child classes, and called by the internal Readable
+class methods only.
+
+Call the callback using the standard `callback(error, data)` pattern.
+When no more data can be fetched, call `callback(null, null)` to
+signal the EOF.
+
+This method is prefixed with an underscore because it is internal to
+the class that defines it, and should not be called directly by user
+programs. However, you **are** expected to override this method in
+your own extension classes.
+
+### readable.push(chunk)
-`function () { }`
+* `chunk` {Buffer | null | String} Chunk of data to push into the read queue
+* return {Boolean} Whether or not more pushes should be performed
+
+The `Readable` class works by putting data into a read queue to be
+pulled out later by calling the `read()` method when the `'readable'`
+event fires.
+
+The `push()` method will explicitly insert some data into the read
+queue. If it is called with `null` then it will signal the end of the
+data.
+
+In some cases, you may be wrapping a lower-level source which has some
+sort of pause/resume mechanism, and a data callback. In those cases,
+you could wrap the low-level source object by doing something like
+this:
+
+```javascript
+// source is an object with readStop() and readStart() methods,
+// and an `ondata` member that gets called when it has data, and
+// an `onend` member that gets called when the data is over.
+
+var stream = new Readable();
+
+source.ondata = function(chunk) {
+ // if push() returns false, then we need to stop reading from source
+ if (!stream.push(chunk))
+ source.readStop();
+};
+
+source.onend = function() {
+ stream.push(null);
+};
+
+// _read will be called when the stream wants to pull more data in
+stream._read = function(size, cb) {
+ source.readStart();
+};
+```
+
+### readable.wrap(stream)
+
+* `stream` {Stream} An "old style" readable stream
+
+If you are using an older Node library that emits `'data'` events and
+has a `pause()` method that is advisory only, then you can use the
+`wrap()` method to create a Readable stream that uses the old stream
+as its data source.
+
+For example:
+
+```javascript
+var OldReader = require('./old-api-module.js').OldReader;
+var oreader = new OldReader;
+var Readable = require('stream').Readable;
+var myReader = new Readable().wrap(oreader);
+
+myReader.on('readable', function() {
+ myReader.read(); // etc.
+});
+```
+
+### Event: 'readable'
+
+When there is data ready to be consumed, this event will fire.
+
+When this event emits, call the `read()` method to consume the data.
+
+### Event: 'end'
Emitted when the stream has received an EOF (FIN in TCP terminology).
Indicates that no more `'data'` events will happen. If the stream is
also writable, it may be possible to continue writing.
-### Event: 'error'
+### Event: 'data'
+
+The `'data'` event emits either a `Buffer` (by default) or a string if
+`setEncoding()` was used.
+
+Note that adding a `'data'` event listener will switch the Readable
+stream into "old mode", where data is emitted as soon as it is
+available, rather than waiting for you to call `read()` to consume it.
-`function (exception) { }`
+### Event: 'error'
Emitted if there was an error receiving data.
### Event: 'close'
-`function () { }`
-
Emitted when the underlying resource (for example, the backing file
descriptor) has been closed. Not all streams will emit this.
-### stream.readable
-
-A boolean that is `true` by default, but turns `false` after an
-`'error'` occurred, the stream came to an `'end'`, or `destroy()` was
-called.
-
-### stream.setEncoding([encoding])
+### readable.setEncoding(encoding)
Makes the `'data'` event emit a string instead of a `Buffer`. `encoding`
-can be `'utf8'`, `'utf16le'` (`'ucs2'`), `'ascii'`, or `'hex'`. Defaults
-to `'utf8'`.
+can be `'utf8'`, `'utf16le'` (`'ucs2'`), `'ascii'`, or `'hex'`.
-### stream.pause()
+The encoding can also be set by specifying an `encoding` field to the
+constructor.
-Issues an advisory signal to the underlying communication layer,
-requesting that no further data be sent until `resume()` is called.
+### readable.read([size])
-Note that, due to the advisory nature, certain streams will not be
-paused immediately, and so `'data'` events may be emitted for some
-indeterminate period of time even after `pause()` is called. You may
-wish to buffer such `'data'` events.
+* `size` {Number | null} Optional number of bytes to read.
+* Return: {Buffer | String | null}
-### stream.resume()
+Call this method to consume data once the `'readable'` event is
+emitted.
-Resumes the incoming `'data'` events after a `pause()`.
+The `size` argument will set a minimum number of bytes that you are
+interested in. If not set, then the entire content of the internal
+buffer is returned.
-### stream.destroy()
+If there is no data to consume, or if there are fewer bytes in the
+internal buffer than the `size` argument, then `null` is returned, and
+a future `'readable'` event will be emitted when more is available.
-Closes the underlying file descriptor. Stream is no longer `writable`
-nor `readable`. The stream will not emit any more 'data', or 'end'
-events. Any queued write data will not be sent. The stream should emit
-'close' event once its resources have been disposed of.
+Note that calling `stream.read(0)` will always return `null`, and will
+trigger a refresh of the internal buffer, but otherwise be a no-op.
+### readable.pipe(destination, [options])
-### stream.pipe(destination, [options])
+* `destination` {Writable Stream}
+* `options` {Object} Optional
+ * `end` {Boolean} Default=true
-This is a `Stream.prototype` method available on all `Stream`s.
-
-Connects this read stream to `destination` WriteStream. Incoming data on
-this stream gets written to `destination`. The destination and source
-streams are kept in sync by pausing and resuming as necessary.
+Connects this readable stream to `destination` WriteStream. Incoming
+data on this stream gets written to `destination`. Properly manages
+back-pressure so that a slow destination will not be overwhelmed by a
+fast readable stream.
This function returns the `destination` stream.
-Emulating the Unix `cat` command:
-
- process.stdin.resume(); process.stdin.pipe(process.stdout);
+For example, emulating the Unix `cat` command:
+ process.stdin.pipe(process.stdout);
By default `end()` is called on the destination when the source stream
emits `end`, so that `destination` is no longer writable. Pass `{ end:
false }` as `options` to keep the destination stream open.
-This keeps `process.stdout` open so that "Goodbye" can be written at the
+This keeps `writer` open so that "Goodbye" can be written at the
end.
- process.stdin.resume();
+ reader.pipe(writer, { end: false });
+ reader.on("end", function() {
+ writer.end("Goodbye\n");
+ });
+
+Note that `process.stderr` and `process.stdout` are never closed until
+the process exits, regardless of the specified options.
- process.stdin.pipe(process.stdout, { end: false });
+### readable.unpipe([destination])
- process.stdin.on("end", function() {
- process.stdout.write("Goodbye\n"); });
+* `destination` {Writable Stream} Optional
+Undo a previously established `pipe()`. If no destination is
+provided, then all previously established pipes are removed.
+
+### readable.pause()
+
+Switches the readable stream into "old mode", where data is emitted
+using a `'data'` event rather than being buffered for consumption via
+the `read()` method.
+
+Ceases the flow of data. No `'data'` events are emitted while the
+stream is in a paused state.
+
+### readable.resume()
+
+Switches the readable stream into "old mode", where data is emitted
+using a `'data'` event rather than being buffered for consumption via
+the `read()` method.
+
+Resumes the incoming `'data'` events after a `pause()`.
-## Writable Stream
+
+## Class: stream.Writable
<!--type=class-->
-A `Writable Stream` has the following methods, members, and events.
+A `Writable` Stream has the following methods, members, and events.
-### Event: 'drain'
+Note that `stream.Writable` is an abstract class designed to be
+extended with an underlying implementation of the `_write(chunk, cb)`
+method. (See below.)
-`function () { }`
+### new stream.Writable([options])
-Emitted when the stream's write queue empties and it's safe to write without
-buffering again. Listen for it when `stream.write()` returns `false`.
+* `options` {Object}
+ * `highWaterMark` {Number} Buffer level when `write()` starts
+ returning false. Default=16kb
+ * `decodeStrings` {Boolean} Whether or not to decode strings into
+ Buffers before passing them to `_write()`. Default=true
-The `'drain'` event can happen at *any* time, regardless of whether or not
-`stream.write()` has previously returned `false`. To avoid receiving unwanted
-`'drain'` events, listen using `stream.once()`.
+In classes that extend the Writable class, make sure to call the
+constructor so that the buffering settings can be properly
+initialized.
-### Event: 'error'
+### writable.\_write(chunk, callback)
+
+* `chunk` {Buffer | Array} The data to be written
+* `callback` {Function} Called with an error, or null when finished
+
+All Writable stream implementations must provide a `_write` method to
+send data to the underlying resource.
+
+Note: **This function MUST NOT be called directly.** It should be
+implemented by child classes, and called by the internal Writable
+class methods only.
+
+Call the callback using the standard `callback(error)` pattern to
+signal that the write completed successfully or with an error.
+
+If the `decodeStrings` flag is set in the constructor options, then
+`chunk` will be an array rather than a Buffer. This is to support
+implementations that have an optimized handling for certain string
+data encodings.
+
+This method is prefixed with an underscore because it is internal to
+the class that defines it, and should not be called directly by user
+programs. However, you **are** expected to override this method in
+your own extension classes.
+
+
+### writable.write(chunk, [encoding], [callback])
+
+* `chunk` {Buffer | String} Data to be written
+* `encoding` {String} Optional. If `chunk` is a string, then encoding
+ defaults to `'utf8'`
+* `callback` {Function} Optional. Called when this chunk is
+ successfully written.
+* Returns {Boolean}
+
+Writes `chunk` to the stream. Returns `true` if the data has been
+flushed to the underlying resource. Returns `false` to indicate that
+the buffer is full, and the data will be sent out in the future. The
+`'drain'` event will indicate when the buffer is empty again.
-`function (exception) { }`
+The specifics of when `write()` will return false, is determined by
+the `highWaterMark` option provided to the constructor.
-Emitted on error with the exception `exception`.
+### writable.end([chunk], [encoding], [callback])
+
+* `chunk` {Buffer | String} Optional final data to be written
+* `encoding` {String} Optional. If `chunk` is a string, then encoding
+ defaults to `'utf8'`
+* `callback` {Function} Optional. Called when the final chunk is
+ successfully written.
+
+Call this method to signal the end of the data being written to the
+stream.
+
+### Event: 'drain'
+
+Emitted when the stream's write queue empties and it's safe to write
+without buffering again. Listen for it when `stream.write()` returns
+`false`.
### Event: 'close'
-`function () { }`
+Emitted when the underlying resource (for example, the backing file
+descriptor) has been closed. Not all streams will emit this.
-Emitted when the underlying file descriptor has been closed.
+### Event: 'finish'
+
+When `end()` is called and there are no more chunks to write, this
+event is emitted.
### Event: 'pipe'
-`function (src) { }`
+* `source` {Readable Stream}
Emitted when the stream is passed to a readable stream's pipe method.
-### stream.writable
+### Event 'unpipe'
+
+* `source` {Readable Stream}
+
+Emitted when a previously established `pipe()` is removed using the
+source Readable stream's `unpipe()` method.
+
+## Class: stream.Duplex
+
+<!--type=class-->
+
+A "duplex" stream is one that is both Readable and Writable, such as a
+TCP socket connection.
+
+Note that `stream.Duplex` is an abstract class designed to be
+extended with an underlying implementation of the `_read(size, cb)`
+and `_write(chunk, callback)` methods as you would with a Readable or
+Writable stream class.
+
+Since JavaScript doesn't have multiple prototypal inheritance, this
+class prototypally inherits from Readable, and then parasitically from
+Writable. It is thus up to the user to implement both the lowlevel
+`_read(n,cb)` method as well as the lowlevel `_write(chunk,cb)` method
+on extension duplex classes.
+
+### new stream.Duplex(options)
+
+* `options` {Object} Passed to both Writable and Readable
+ constructors. Also has the following fields:
+ * `allowHalfOpen` {Boolean} Default=true. If set to `false`, then
+ the stream will automatically end the readable side when the
+ writable side ends and vice versa.
+
+In classes that extend the Duplex class, make sure to call the
+constructor so that the buffering settings can be properly
+initialized.
+
+## Class: stream.Transform
+
+A "transform" stream is a duplex stream where the output is causally
+connected in some way to the input, such as a zlib stream or a crypto
+stream.
+
+There is no requirement that the output be the same size as the input,
+the same number of chunks, or arrive at the same time. For example, a
+Hash stream will only ever have a single chunk of output which is
+provided when the input is ended. A zlib stream will either produce
+much smaller or much larger than its input.
+
+Rather than implement the `_read()` and `_write()` methods, Transform
+classes must implement the `_transform()` method, and may optionally
+also implement the `_flush()` method. (See below.)
+
+### new stream.Transform([options])
+
+* `options` {Object} Passed to both Writable and Readable
+ constructors.
+
+In classes that extend the Transform class, make sure to call the
+constructor so that the buffering settings can be properly
+initialized.
+
+### transform.\_transform(chunk, outputFn, callback)
+
+* `chunk` {Buffer} The chunk to be transformed.
+* `outputFn` {Function} Call this function with any output data to be
+ passed to the readable interface.
+* `callback` {Function} Call this function (optionally with an error
+ argument) when you are done processing the supplied chunk.
-A boolean that is `true` by default, but turns `false` after an
-`'error'` occurred or `end()` / `destroy()` was called.
+All Transform stream implementations must provide a `_transform`
+method to accept input and produce output.
-### stream.write(string, [encoding])
+Note: **This function MUST NOT be called directly.** It should be
+implemented by child classes, and called by the internal Transform
+class methods only.
-Writes `string` with the given `encoding` to the stream. Returns `true`
-if the string has been flushed to the kernel buffer. Returns `false` to
-indicate that the kernel buffer is full, and the data will be sent out
-in the future. The `'drain'` event will indicate when the kernel buffer
-is empty again. The `encoding` defaults to `'utf8'`.
+`_transform` should do whatever has to be done in this specific
+Transform class, to handle the bytes being written, and pass them off
+to the readable portion of the interface. Do asynchronous I/O,
+process things, and so on.
-### stream.write(buffer)
+Call the callback function only when the current chunk is completely
+consumed. Note that this may mean that you call the `outputFn` zero
+or more times, depending on how much data you want to output as a
+result of this chunk.
-Same as the above except with a raw buffer.
+This method is prefixed with an underscore because it is internal to
+the class that defines it, and should not be called directly by user
+programs. However, you **are** expected to override this method in
+your own extension classes.
-### stream.end()
+### transform.\_flush(outputFn, callback)
-Terminates the stream with EOF or FIN. This call will allow queued
-write data to be sent before closing the stream.
+* `outputFn` {Function} Call this function with any output data to be
+ passed to the readable interface.
+* `callback` {Function} Call this function (optionally with an error
+ argument) when you are done flushing any remaining data.
-### stream.end(string, encoding)
+Note: **This function MUST NOT be called directly.** It MAY be implemented
+by child classes, and if so, will be called by the internal Transform
+class methods only.
-Sends `string` with the given `encoding` and terminates the stream with
-EOF or FIN. This is useful to reduce the number of packets sent.
+In some cases, your transform operation may need to emit a bit more
+data at the end of the stream. For example, a `Zlib` compression
+stream will store up some internal state so that it can optimally
+compress the output. At the end, however, it needs to do the best it
+can with what is left, so that the data will be complete.
-### stream.end(buffer)
+In those cases, you can implement a `_flush` method, which will be
+called at the very end, after all the written data is consumed, but
+before emitting `end` to signal the end of the readable side. Just
+like with `_transform`, call `outputFn` zero or more times, as
+appropriate, and call `callback` when the flush operation is complete.
-Same as above but with a `buffer`.
+This method is prefixed with an underscore because it is internal to
+the class that defines it, and should not be called directly by user
+programs. However, you **are** expected to override this method in
+your own extension classes.
-### stream.destroy()
-Closes the underlying file descriptor. Stream is no longer `writable`
-nor `readable`. The stream will not emit any more 'data', or 'end'
-events. Any queued write data will not be sent. The stream should emit
-'close' event once its resources have been disposed of.
+## Class: stream.PassThrough
-### stream.destroySoon()
+This is a trivial implementation of a `Transform` stream that simply
+passes the input bytes across to the output. Its purpose is mainly
+for examples and testing, but there are occasionally use cases where
+it can come in handy.
-After the write queue is drained, close the file descriptor.
-`destroySoon()` can still destroy straight away, as long as there is no
-data left in the queue for writes.
[EventEmitter]: events.html#events_class_events_eventemitter
diff --git a/doc/api/string_decoder.markdown b/doc/api/string_decoder.markdown
index 2ad2fb1e4..b8a6252d6 100644
--- a/doc/api/string_decoder.markdown
+++ b/doc/api/string_decoder.markdown
@@ -19,6 +19,10 @@ additional support for utf8.
Accepts a single argument, `encoding` which defaults to `utf8`.
-### StringDecoder.write(buffer)
+### decoder.write(buffer)
-Returns a decoded string. \ No newline at end of file
+Returns a decoded string.
+
+### decoder.end()
+
+Returns any trailing bytes that were left in the buffer.
diff --git a/doc/api/timers.markdown b/doc/api/timers.markdown
index 114a4b73c..6bf14318e 100644
--- a/doc/api/timers.markdown
+++ b/doc/api/timers.markdown
@@ -29,3 +29,38 @@ you can also pass arguments to the callback.
## clearInterval(intervalId)
Stops a interval from triggering.
+
+## unref()
+
+The opaque value returned by `setTimeout` and `setInterval` also has the method
+`timer.unref()` which will allow you to create a timer that is active but if
+it is the only item left in the event loop won't keep the program running.
+If the timer is already `unref`d calling `unref` again will have no effect.
+
+In the case of `setTimeout` when you `unref` you create a separate timer that
+will wakeup the event loop, creating too many of these may adversely effect
+event loop performance -- use wisely.
+
+## ref()
+
+If you had previously `unref()`d a timer you can call `ref()` to explicitly
+request the timer hold the program open. If the timer is already `ref`d calling
+`ref` again will have no effect.
+
+## setImmediate(callback, [arg], [...])
+
+To schedule the "immediate" execution of `callback` after I/O events
+callbacks and before `setTimeout` and `setInterval` . Returns an
+`immediateId` for possible use with `clearImmediate()`. Optionally you
+can also pass arguments to the callback.
+
+Immediates are queued in the order created, and are popped off the queue once
+per loop iteration. This is different from `process.nextTick` which will
+execute `process.maxTickDepth` queued callbacks per iteration. `setImmediate`
+will yield to the event loop after firing a queued callback to make sure I/O is
+not being starved. While order is preserved for execution, other I/O events may
+fire between any two scheduled immediate callbacks.
+
+## clearImmediate(immediateId)
+
+Stops an immediate from triggering.
diff --git a/doc/api/tls.markdown b/doc/api/tls.markdown
index 40a25e7f5..28bc05630 100644
--- a/doc/api/tls.markdown
+++ b/doc/api/tls.markdown
@@ -120,6 +120,12 @@ automatically set as a listener for the [secureConnection][] event. The
acceptable cipher. Unfortunately, `AES256-SHA` is a CBC cipher and therefore
susceptible to BEAST attacks. Do *not* use it.
+ - `handshakeTimeout`: Abort the connection if the SSL/TLS handshake does not
+ finish in this many milliseconds. The default is 120 seconds.
+
+ A `'clientError'` is emitted on the `tls.Server` object whenever a handshake
+ times out.
+
- `honorCipherOrder` : When choosing a cipher, use the server's preferences
instead of the client preferences.
@@ -208,6 +214,15 @@ You can test this server by connecting to it with `openssl s_client`:
openssl s_client -connect 127.0.0.1:8000
+## tls.SLAB_BUFFER_SIZE
+
+Size of slab buffer used by all tls servers and clients.
+Default: `10 * 1024 * 1024`.
+
+
+Don't change the defaults unless you know what you are doing.
+
+
## tls.connect(options, [callback])
## tls.connect(port, [host], [options], [callback])
@@ -240,7 +255,7 @@ Creates a new client connection to the given `port` and `host` (old API) or
- `rejectUnauthorized`: If `true`, the server certificate is verified against
the list of supplied CAs. An `'error'` event is emitted if verification
- fails. Default: `false`.
+ fails. Default: `true`.
- `NPNProtocols`: An array of string or `Buffer` containing supported NPN
protocols. `Buffer` should have following format: `0x05hello0x05world`,
@@ -367,11 +382,32 @@ SNI.
### Event: 'clientError'
-`function (exception) { }`
+`function (exception, securePair) { }`
When a client connection emits an 'error' event before secure connection is
established - it will be forwarded here.
+`securePair` is the `tls.SecurePair` that the error originated from.
+
+
+### Event: 'newSession'
+
+`function (sessionId, sessionData) { }`
+
+Emitted on creation of TLS session. May be used to store sessions in external
+storage.
+
+
+### Event: 'resumeSession'
+
+`function (sessionId, callback) { }`
+
+Emitted when client wants to resume previous TLS session. Event listener may
+perform lookup in external storage using given `sessionId`, and invoke
+`callback(null, sessionData)` once finished. If session can't be resumed
+(i.e. doesn't exist in storage) one may call `callback(null, null)`. Calling
+`callback(err)` will terminate incoming connection and destroy socket.
+
### server.listen(port, [host], [callback])
@@ -413,6 +449,15 @@ gets high.
The number of concurrent connections on the server.
+## Class: CryptoStream
+
+This is an encrypted stream.
+
+### cryptoStream.bytesWritten
+
+A proxy to the underlying socket's bytesWritten accessor, this will return
+the total bytes written to the socket, *including the TLS overhead*.
+
## Class: tls.CleartextStream
This is a stream on top of the *Encrypted* stream that makes it possible to
diff --git a/doc/api/util.markdown b/doc/api/util.markdown
index 58bbfb7e0..f9fa728d6 100644
--- a/doc/api/util.markdown
+++ b/doc/api/util.markdown
@@ -66,27 +66,53 @@ Output with timestamp on `stdout`.
require('util').log('Timestamped message.');
-## util.inspect(object, [showHidden], [depth], [colors])
+## util.inspect(object, [options])
Return a string representation of `object`, which is useful for debugging.
-If `showHidden` is `true`, then the object's non-enumerable properties will be
-shown too. Defaults to `false`.
+An optional *options* object may be passed that alters certain aspects of the
+formatted string:
-If `depth` is provided, it tells `inspect` how many times to recurse while
-formatting the object. This is useful for inspecting large complicated objects.
+ - `showHidden` - if `true` then the object's non-enumerable properties will be
+ shown too. Defaults to `false`.
-The default is to only recurse twice. To make it recurse indefinitely, pass
-in `null` for `depth`.
+ - `depth` - tells `inspect` how many times to recurse while formatting the
+ object. This is useful for inspecting large complicated objects. Defaults to
+ `2`. To make it recurse indefinitely pass `null`.
-If `colors` is `true`, the output will be styled with ANSI color codes.
-Defaults to `false`.
+ - `colors` - if `true`, then the output will be styled with ANSI color codes.
+ Defaults to `false`. Colors are customizable, see below.
+
+ - `customInspect` - if `false`, then custom `inspect()` functions defined on the
+ objects being inspected won't be called. Defaults to `true`.
Example of inspecting all properties of the `util` object:
var util = require('util');
- console.log(util.inspect(util, true, null));
+ console.log(util.inspect(util, { showHidden: true, depth: null }));
+
+### Customizing `util.inspect` colors
+
+Color output (if enabled) of `util.inspect` is customizable globally
+via `util.inspect.styles` and `util.inspect.colors` objects.
+
+`util.inspect.styles` is a map assigning each style a color
+from `util.inspect.colors`.
+Highlighted styles and their default values are:
+ * `number` (yellow)
+ * `boolean` (yellow)
+ * `string` (green)
+ * `date` (magenta)
+ * `regexp` (red)
+ * `null` (bold)
+ * `undefined` (grey)
+ * `special` - only function at this time (cyan)
+ * `name` (intentionally no styling)
+
+Predefined color codes are: `white`, `grey`, `black`, `blue`, `cyan`,
+`green`, `magenta`, `red` and `yellow`.
+There are also `bold`, `italic`, `underline` and `inverse` codes.
Objects also may define their own `inspect(depth)` function which `util.inspect()`
will invoke and use the result of when inspecting the object:
diff --git a/doc/api/zlib.markdown b/doc/api/zlib.markdown
index 66c928460..5dcde3248 100644
--- a/doc/api/zlib.markdown
+++ b/doc/api/zlib.markdown
@@ -139,6 +139,21 @@ Returns a new [Unzip](#zlib_class_zlib_unzip) object with an
[options](#zlib_options).
+## Class: zlib.Zlib
+
+Not exported by the `zlib` module. It is documented here because it is the base
+class of the compressor/decompressor classes.
+
+### zlib.flush(callback)
+
+Flush pending data. Don't call this frivolously, premature flushes negatively
+impact the effectiveness of the compression algorithm.
+
+### zlib.reset()
+
+Reset the compressor/decompressor to factory defaults. Only applicable to
+the inflate and deflate algorithms.
+
## Class: zlib.Gzip
Compress data using gzip.
diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css
index 5523984ce..de3f07c58 100644
--- a/doc/api_assets/style.css
+++ b/doc/api_assets/style.css
@@ -67,6 +67,30 @@ code a:hover {
margin: 0;
}
+.api_stability_0 {
+ border-color: #D60027;
+}
+
+.api_stability_1 {
+ border-color: #EC5315;
+}
+
+.api_stability_2 {
+ border-color: #FFD700;
+}
+
+.api_stability_3 {
+ border-color: #AEC516;
+}
+
+.api_stability_4 {
+ border-color: #009431;
+}
+
+.api_stability_5 {
+ border-color: #0084B6;
+}
+
ul.plain {
list-style: none;
}
diff --git a/doc/blog/feature/streams2.md b/doc/blog/feature/streams2.md
index 38479e81d..9adef3956 100644
--- a/doc/blog/feature/streams2.md
+++ b/doc/blog/feature/streams2.md
@@ -111,7 +111,7 @@ feedback.
A stream is an abstract interface implemented by various objects in
Node. For example a request to an HTTP server is a stream, as is
stdout. Streams are readable, writable, or both. All streams are
-instances of EventEmitter.
+instances of [EventEmitter][]
You can load the Stream base classes by doing `require('stream')`.
There are base classes provided for Readable streams, Writable
@@ -198,13 +198,14 @@ method. (See below.)
* `options` {Object}
* `bufferSize` {Number} The size of the chunks to consume from the
underlying resource. Default=16kb
- * `lowWaterMark` {Number} The minimum number of bytes to store in
- the internal buffer before emitting `readable`. Default=0
* `highWaterMark` {Number} The maximum number of bytes to store in
the internal buffer before ceasing to read from the underlying
resource. Default=16kb
* `encoding` {String} If specified, then buffers will be decoded to
strings using the specified encoding. Default=null
+ * `objectMode` {Boolean} Whether this stream should behave
+ as a stream of objects. Meaning that stream.read(n) returns
+ a single value instead of a Buffer of size n
In classes that extend the Readable class, make sure to call the
constructor so that the buffering settings can be properly
@@ -218,7 +219,7 @@ initialized.
All Readable stream implementations must provide a `_read` method
to fetch data from the underlying resource.
-**This function MUST NOT be called directly.** It should be
+Note: **This function MUST NOT be called directly.** It should be
implemented by child classes, and called by the internal Readable
class methods only.
@@ -231,6 +232,46 @@ the class that defines it, and should not be called directly by user
programs. However, you **are** expected to override this method in
your own extension classes.
+### readable.push(chunk)
+
+* `chunk` {Buffer | null | String} Chunk of data to push into the read queue
+* return {Boolean} Whether or not more pushes should be performed
+
+The `Readable` class works by putting data into a read queue to be
+pulled out later by calling the `read()` method when the `'readable'`
+event fires.
+
+The `push()` method will explicitly insert some data into the read
+queue. If it is called with `null` then it will signal the end of the
+data.
+
+In some cases, you may be wrapping a lower-level source which has some
+sort of pause/resume mechanism, and a data callback. In those cases,
+you could wrap the low-level source object by doing something like
+this:
+
+```javascript
+// source is an object with readStop() and readStart() methods,
+// and an `ondata` member that gets called when it has data, and
+// an `onend` member that gets called when the data is over.
+
+var stream = new Readable();
+
+source.ondata = function(chunk) {
+ // if push() returns false, then we need to stop reading from source
+ if (!stream.push(chunk))
+ source.readStop();
+};
+
+source.onend = function() {
+ stream.push(null);
+};
+
+// _read will be called when the stream wants to pull more data in
+stream._read = function(size, cb) {
+ source.readStart();
+};
+```
### readable.wrap(stream)
@@ -256,9 +297,7 @@ myReader.on('readable', function() {
### Event: 'readable'
-When there is data ready to be consumed, this event will fire. The
-number of bytes that are required to be considered "readable" depends
-on the `lowWaterMark` option set in the constructor.
+When there is data ready to be consumed, this event will fire.
When this event emits, call the `read()` method to consume the data.
@@ -385,8 +424,6 @@ method. (See below.)
* `options` {Object}
* `highWaterMark` {Number} Buffer level when `write()` starts
returning false. Default=16kb
- * `lowWaterMark` {Number} The buffer level when `'drain'` is
- emitted. Default=0
* `decodeStrings` {Boolean} Whether or not to decode strings into
Buffers before passing them to `_write()`. Default=true
@@ -402,7 +439,7 @@ initialized.
All Writable stream implementations must provide a `_write` method to
send data to the underlying resource.
-**This function MUST NOT be called directly.** It should be
+Note: **This function MUST NOT be called directly.** It should be
implemented by child classes, and called by the internal Writable
class methods only.
@@ -434,16 +471,16 @@ flushed to the underlying resource. Returns `false` to indicate that
the buffer is full, and the data will be sent out in the future. The
`'drain'` event will indicate when the buffer is empty again.
-The specifics of when `write()` will return false, and when a
-subsequent `'drain'` event will be emitted, are determined by the
-`highWaterMark` and `lowWaterMark` options provided to the
-constructor.
+The specifics of when `write()` will return false, is determined by
+the `highWaterMark` option provided to the constructor.
-### writable.end([chunk], [encoding])
+### writable.end([chunk], [encoding], [callback])
* `chunk` {Buffer | String} Optional final data to be written
* `encoding` {String} Optional. If `chunk` is a string, then encoding
defaults to `'utf8'`
+* `callback` {Function} Optional. Called when the final chunk is
+ successfully written.
Call this method to signal the end of the data being written to the
stream.
@@ -459,6 +496,11 @@ without buffering again. Listen for it when `stream.write()` returns
Emitted when the underlying resource (for example, the backing file
descriptor) has been closed. Not all streams will emit this.
+### Event: 'finish'
+
+When `end()` is called and there are no more chunks to write, this
+event is emitted.
+
### Event: 'pipe'
* `source` {Readable Stream}
@@ -538,7 +580,7 @@ initialized.
All Transform stream implementations must provide a `_transform`
method to accept input and produce output.
-**This function MUST NOT be called directly.** It should be
+Note: **This function MUST NOT be called directly.** It should be
implemented by child classes, and called by the internal Transform
class methods only.
@@ -564,7 +606,7 @@ your own extension classes.
* `callback` {Function} Call this function (optionally with an error
argument) when you are done flushing any remaining data.
-**This function MUST NOT be called directly.** It MAY be implemented
+Note: **This function MUST NOT be called directly.** It MAY be implemented
by child classes, and if so, will be called by the internal Transform
class methods only.
@@ -592,3 +634,6 @@ This is a trivial implementation of a `Transform` stream that simply
passes the input bytes across to the output. Its purpose is mainly
for examples and testing, but there are occasionally use cases where
it can come in handy.
+
+
+[EventEmitter]: http://nodejs.org/api/events.html#events_class_events_eventemitter
diff --git a/doc/blog/release/v0.9.0.md b/doc/blog/release/v0.9.0.md
new file mode 100644
index 000000000..61499e532
--- /dev/null
+++ b/doc/blog/release/v0.9.0.md
@@ -0,0 +1,61 @@
+category: release
+version: 0.9.0
+date: Fri Jul 20 11:37:15 PDT 2012
+title: Version 0.9.0 (Unstable)
+slug: version-0-9-0-unstable
+
+2012.07.20, Version 0.9.0 (Unstable)
+
+* punycode: update to v1.1.1 (Mathias Bynens)
+
+* c-ares: upgrade to 1.9.0 (Saúl Ibarra Corretgé)
+
+* dns: ignore rogue DNS servers reported by windows (Saúl Ibarra Corretgé)
+
+* unix: speed up uv_async_send() (Ben Noordhuis)
+
+* darwin: get cpu model correctly on mac (Xidorn Quan)
+
+* nextTick: Handle tick callbacks before any other I/O (isaacs)
+
+* Enable color customization of `util.inspect` (Pavel Lang)
+
+* tls: Speed and memory improvements (Fedor Indutny)
+
+* readline: Use one history item for reentered line (Vladimir Beloborodov)
+
+* Fix #3521 Make process.env more like a regular Object (isaacs)
+
+
+Source Code: http://nodejs.org/dist/v0.9.0/node-v0.9.0.tar.gz
+
+Macintosh Installer (Universal): http://nodejs.org/dist/v0.9.0/node-v0.9.0.pkg
+
+Windows Installer: http://nodejs.org/dist/v0.9.0/node-v0.9.0-x86.msi
+
+Windows x64 Installer: http://nodejs.org/dist/v0.9.0/x64/node-v0.9.0-x64.msi
+
+Windows x64 Files: http://nodejs.org/dist/v0.9.0/x64/
+
+Other release files: http://nodejs.org/dist/v0.9.0/
+
+Website: http://nodejs.org/docs/v0.9.0/
+
+Documentation: http://nodejs.org/docs/v0.9.0/api/
+
+Shasums:
+
+```
+4d6881934f5e41da651b478f914f71543d21d3cc node-v0.9.0-x86.msi
+ec00cc6f0830f64cd9e8246a299abf9a2a6ed73e node-v0.9.0.pkg
+912d0eb3139b8f6f99199dae5ec1ecb300ed9c9b node-v0.9.0.tar.gz
+7e56dddbb1d3e243549db7182f1bf2dd4518eaae node.exe
+31718ad3e0de9b0ea6c207966a13d4bafaf9ef64 node.exp
+0738b4d91de4c87cdee2547d83144668cb232c24 node.lib
+baca86ec3c12a5261abb940cd8107bdeb40713cc node.pdb
+cf3892596a7d2a27a63672b537b06b8828125fe9 x64/node-v0.9.0-x64.msi
+cad4bf9b2be85476d1a897ea17b3f927ec49c96a x64/node.exe
+29ea3654f7728efef6fa046943ded57af42b91f3 x64/node.exp
+1dfa57b111d5942b4fe701b625176eae73c82d82 x64/node.lib
+9093b2120f8adf0236f965982e4a32697af2af5d x64/node.pdb
+```
diff --git a/lib/_debugger.js b/lib/_debugger.js
index c39a0ba58..239220962 100644
--- a/lib/_debugger.js
+++ b/lib/_debugger.js
@@ -36,7 +36,7 @@ exports.start = function(argv, stdin, stdout) {
}
// Setup input/output streams
- stdin = stdin || process.openStdin();
+ stdin = stdin || process.stdin;
stdout = stdout || process.stdout;
var args = ['--debug-brk'].concat(argv),
@@ -759,6 +759,15 @@ function Interface(stdin, stdout, args) {
};
if (parseInt(process.env['NODE_NO_READLINE'], 10)) {
opts.terminal = false;
+ } else if (parseInt(process.env['NODE_FORCE_READLINE'], 10)) {
+ opts.terminal = true;
+
+ // Emulate Ctrl+C if we're emulating terminal
+ if (!this.stdout.isTTY) {
+ process.on('SIGINT', function() {
+ self.repl.rli.emit('SIGINT');
+ });
+ }
}
if (parseInt(process.env['NODE_DISABLE_COLORS'], 10)) {
opts.useColors = false;
@@ -773,10 +782,10 @@ function Interface(stdin, stdout, args) {
process.exit(0);
});
- process.on('exit', function() {
- self.killChild();
- });
-
+ // Handle all possible exits
+ process.on('exit', this.killChild.bind(this));
+ process.once('SIGTERM', process.exit.bind(process, 0));
+ process.once('SIGHUP', process.exit.bind(process, 0));
var proto = Interface.prototype,
ignored = ['pause', 'resume', 'exitRepl', 'handleBreak',
@@ -952,7 +961,7 @@ Interface.prototype.controlEval = function(code, context, filename, callback) {
try {
// Repeat last command if empty line are going to be evaluated
if (this.repl.rli.history && this.repl.rli.history.length > 0) {
- if (code === '(undefined\n)') {
+ if (code === '(\n)') {
code = '(' + this.repl.rli.history[0] + '\n)';
}
}
diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js
new file mode 100644
index 000000000..c5a741c46
--- /dev/null
+++ b/lib/_stream_duplex.js
@@ -0,0 +1,69 @@
+// 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.
+
+// a duplex stream is just a stream that is both readable and writable.
+// Since JS doesn't have multiple prototypal inheritance, this class
+// prototypally inherits from Readable, and then parasitically from
+// Writable.
+
+module.exports = Duplex;
+var util = require('util');
+var Readable = require('_stream_readable');
+var Writable = require('_stream_writable');
+
+util.inherits(Duplex, Readable);
+
+Object.keys(Writable.prototype).forEach(function(method) {
+ if (!Duplex.prototype[method])
+ Duplex.prototype[method] = Writable.prototype[method];
+});
+
+function Duplex(options) {
+ if (!(this instanceof Duplex))
+ return new Duplex(options);
+
+ Readable.call(this, options);
+ Writable.call(this, options);
+
+ if (options && options.readable === false)
+ this.readable = false;
+
+ if (options && options.writable === false)
+ this.writable = false;
+
+ this.allowHalfOpen = true;
+ if (options && options.allowHalfOpen === false)
+ this.allowHalfOpen = false;
+
+ this.once('end', onend);
+}
+
+// the no-half-open enforcer
+function onend() {
+ // if we allow half-open state, or if the writable side ended,
+ // then we're ok.
+ if (this.allowHalfOpen || this._writableState.ended)
+ return;
+
+ // no more data can be written.
+ // But allow more writes to happen in this tick.
+ process.nextTick(this.end.bind(this));
+}
diff --git a/lib/_stream_passthrough.js b/lib/_stream_passthrough.js
new file mode 100644
index 000000000..0f2fe14c7
--- /dev/null
+++ b/lib/_stream_passthrough.js
@@ -0,0 +1,41 @@
+// 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.
+
+// a passthrough stream.
+// basically just the most minimal sort of Transform stream.
+// Every written chunk gets output as-is.
+
+module.exports = PassThrough;
+
+var Transform = require('_stream_transform');
+var util = require('util');
+util.inherits(PassThrough, Transform);
+
+function PassThrough(options) {
+ if (!(this instanceof PassThrough))
+ return new PassThrough(options);
+
+ Transform.call(this, options);
+}
+
+PassThrough.prototype._transform = function(chunk, output, cb) {
+ cb(null, chunk);
+};
diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js
new file mode 100644
index 000000000..e75e201e0
--- /dev/null
+++ b/lib/_stream_readable.js
@@ -0,0 +1,846 @@
+// 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.
+
+module.exports = Readable;
+Readable.ReadableState = ReadableState;
+
+var Stream = require('stream');
+var util = require('util');
+var StringDecoder;
+
+util.inherits(Readable, Stream);
+
+function ReadableState(options, stream) {
+ options = options || {};
+
+ // the argument passed to this._read(n,cb)
+ this.bufferSize = options.bufferSize || 16 * 1024;
+
+ // the point at which it stops calling _read() to fill the buffer
+ // Note: 0 is a valid value, means "don't call _read preemptively ever"
+ var hwm = options.highWaterMark;
+ this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;
+
+ // cast to ints.
+ this.bufferSize = ~~this.bufferSize;
+ this.highWaterMark = ~~this.highWaterMark;
+
+ this.buffer = [];
+ this.length = 0;
+ this.pipes = null;
+ this.pipesCount = 0;
+ this.flowing = false;
+ this.ended = false;
+ this.endEmitted = false;
+ this.reading = false;
+
+ // a flag to be able to tell if the onwrite cb is called immediately,
+ // or on a later tick. We set this to true at first, becuase any
+ // actions that shouldn't happen until "later" should generally also
+ // not happen before the first write call.
+ this.sync = true;
+
+ this.onread = function(er, data) {
+ onread(stream, er, data);
+ };
+
+ // whenever we return null, then we set a flag to say
+ // that we're awaiting a 'readable' event emission.
+ this.needReadable = false;
+ this.emittedReadable = false;
+
+
+ // object stream flag. Used to make read(n) ignore n and to
+ // make all the buffer merging and length checks go away
+ this.objectMode = !!options.objectMode;
+
+ // when piping, we only care about 'readable' events that happen
+ // after read()ing all the bytes and not getting any pushback.
+ this.ranOut = false;
+
+ // the number of writers that are awaiting a drain event in .pipe()s
+ this.awaitDrain = 0;
+ this.pipeChunkSize = null;
+
+ this.decoder = null;
+ if (options.encoding) {
+ if (!StringDecoder)
+ StringDecoder = require('string_decoder').StringDecoder;
+ this.decoder = new StringDecoder(options.encoding);
+ }
+}
+
+function Readable(options) {
+ if (!(this instanceof Readable))
+ return new Readable(options);
+
+ this._readableState = new ReadableState(options, this);
+
+ // legacy
+ this.readable = true;
+
+ Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function(chunk) {
+ var rs = this._readableState;
+ rs.onread(null, chunk);
+
+ // if it's past the high water mark, we can push in some more.
+ // Also, if we have no data yet, we can stand some
+ // more bytes. This is to work around cases where hwm=0,
+ // such as the repl. Also, if the push() triggered a
+ // readable event, and the user called read(largeNumber) such that
+ // needReadable was set, then we ought to push more, so that another
+ // 'readable' event will be triggered.
+ return rs.needReadable ||
+ rs.length < rs.highWaterMark ||
+ rs.length === 0;
+};
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function(enc) {
+ if (!StringDecoder)
+ StringDecoder = require('string_decoder').StringDecoder;
+ this._readableState.decoder = new StringDecoder(enc);
+};
+
+
+function howMuchToRead(n, state) {
+ if (state.length === 0 && state.ended)
+ return 0;
+
+ if (state.objectMode)
+ return n === 0 ? 0 : 1;
+
+ if (isNaN(n) || n === null) {
+ // only flow one buffer at a time
+ if (state.flowing && state.buffer.length)
+ return state.buffer[0].length;
+ else
+ return state.length;
+ }
+
+ if (n <= 0)
+ return 0;
+
+ // don't have that much. return null, unless we've ended.
+ if (n > state.length) {
+ if (!state.ended) {
+ state.needReadable = true;
+ return 0;
+ } else
+ return state.length;
+ }
+
+ return n;
+}
+
+// you can override either this method, or _read(n, cb) below.
+Readable.prototype.read = function(n) {
+ var state = this._readableState;
+ var nOrig = n;
+
+ if (typeof n !== 'number' || n > 0)
+ state.emittedReadable = false;
+
+ // if we're doing read(0) to trigger a readable event, but we
+ // already have a bunch of data in the buffer, then just trigger
+ // the 'readable' event and move on.
+ if (n === 0 &&
+ state.needReadable &&
+ state.length >= state.highWaterMark) {
+ emitReadable(this);
+ return null;
+ }
+
+ n = howMuchToRead(n, state);
+
+ // if we've ended, and we're now clear, then finish it up.
+ if (n === 0 && state.ended) {
+ if (state.length === 0)
+ endReadable(this);
+ return null;
+ }
+
+ // All the actual chunk generation logic needs to be
+ // *below* the call to _read. The reason is that in certain
+ // synthetic stream cases, such as passthrough streams, _read
+ // may be a completely synchronous operation which may change
+ // the state of the read buffer, providing enough data when
+ // before there was *not* enough.
+ //
+ // So, the steps are:
+ // 1. Figure out what the state of things will be after we do
+ // a read from the buffer.
+ //
+ // 2. If that resulting state will trigger a _read, then call _read.
+ // Note that this may be asynchronous, or synchronous. Yes, it is
+ // deeply ugly to write APIs this way, but that still doesn't mean
+ // that the Readable class should behave improperly, as streams are
+ // designed to be sync/async agnostic.
+ // Take note if the _read call is sync or async (ie, if the read call
+ // has returned yet), so that we know whether or not it's safe to emit
+ // 'readable' etc.
+ //
+ // 3. Actually pull the requested chunks out of the buffer and return.
+
+ // if we need a readable event, then we need to do some reading.
+ var doRead = state.needReadable;
+
+ // if we currently have less than the highWaterMark, then also read some
+ if (state.length - n <= state.highWaterMark)
+ doRead = true;
+
+ // however, if we've ended, then there's no point, and if we're already
+ // reading, then it's unnecessary.
+ if (state.ended || state.reading)
+ doRead = false;
+
+ if (doRead) {
+ state.reading = true;
+ state.sync = true;
+ // if the length is currently zero, then we *need* a readable event.
+ if (state.length === 0)
+ state.needReadable = true;
+ // call internal read method
+ this._read(state.bufferSize, state.onread);
+ state.sync = false;
+ }
+
+ // If _read called its callback synchronously, then `reading`
+ // will be false, and we need to re-evaluate how much data we
+ // can return to the user.
+ if (doRead && !state.reading)
+ n = howMuchToRead(nOrig, state);
+
+ var ret;
+ if (n > 0)
+ ret = fromList(n, state);
+ else
+ ret = null;
+
+ if (ret === null) {
+ state.needReadable = true;
+ n = 0;
+ }
+
+ state.length -= n;
+
+ // If we have nothing in the buffer, then we want to know
+ // as soon as we *do* get something into the buffer.
+ if (state.length === 0 && !state.ended)
+ state.needReadable = true;
+
+ // If we happened to read() exactly the remaining amount in the
+ // buffer, and the EOF has been seen at this point, then make sure
+ // that we emit 'end' on the very next tick.
+ if (state.ended && !state.endEmitted && state.length === 0)
+ endReadable(this);
+
+ return ret;
+};
+
+function onread(stream, er, chunk) {
+ var state = stream._readableState;
+ var sync = state.sync;
+
+ // If we get something that is not a buffer, string, null, or undefined,
+ // and we're not in objectMode, then that's an error.
+ // Otherwise stream chunks are all considered to be of length=1, and the
+ // watermarks determine how many objects to keep in the buffer, rather than
+ // how many bytes or characters.
+ if (!Buffer.isBuffer(chunk) &&
+ 'string' !== typeof chunk &&
+ chunk !== null &&
+ chunk !== undefined &&
+ !state.objectMode &&
+ !er) {
+ er = new TypeError('Invalid non-string/buffer chunk');
+ }
+
+ state.reading = false;
+ if (er)
+ return stream.emit('error', er);
+
+ if (chunk === null || chunk === undefined) {
+ // eof
+ state.ended = true;
+ if (state.decoder) {
+ chunk = state.decoder.end();
+ if (chunk && chunk.length) {
+ state.buffer.push(chunk);
+ state.length += state.objectMode ? 1 : chunk.length;
+ }
+ }
+
+ // if we've ended and we have some data left, then emit
+ // 'readable' now to make sure it gets picked up.
+ if (state.length > 0)
+ emitReadable(stream);
+ else
+ endReadable(stream);
+ return;
+ }
+
+ // at this point, if we got a zero-length buffer or string,
+ // and we're not in object-mode, then there's really no point
+ // continuing. it means that there is nothing to read right
+ // now, but as we have not received the EOF-signaling null,
+ // we're not ended. we've already unset the reading flag,
+ // so just get out of here.
+ if (!state.objectMode &&
+ (chunk || typeof chunk === 'string') &&
+ 0 === chunk.length)
+ return;
+
+ if (state.decoder)
+ chunk = state.decoder.write(chunk);
+
+ // update the buffer info.
+ state.length += state.objectMode ? 1 : chunk.length;
+ state.buffer.push(chunk);
+
+ // if we haven't gotten any data,
+ // and we haven't ended, then don't bother telling the user
+ // that it's time to read more data. Otherwise, emitting 'readable'
+ // probably will trigger another stream.read(), which can trigger
+ // another _read(n,cb) before this one returns!
+ if (state.length === 0) {
+ state.reading = true;
+ stream._read(state.bufferSize, state.onread);
+ return;
+ }
+
+ if (state.needReadable)
+ emitReadable(stream);
+ else if (state.sync)
+ process.nextTick(function() {
+ maybeReadMore(stream, state);
+ });
+ else
+ maybeReadMore(stream, state);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow. This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+ var state = stream._readableState;
+ state.needReadable = false;
+ if (state.emittedReadable)
+ return;
+
+ state.emittedReadable = true;
+ if (state.sync)
+ process.nextTick(function() {
+ emitReadable_(stream);
+ });
+ else
+ emitReadable_(stream);
+}
+
+function emitReadable_(stream) {
+ var state = stream._readableState;
+ stream.emit('readable');
+ maybeReadMore(stream, state);
+}
+
+function maybeReadMore(stream, state) {
+ // at this point, the user has presumably seen the 'readable' event,
+ // and called read() to consume some data. that may have triggered
+ // in turn another _read(n,cb) call, in which case reading = true if
+ // it's in progress.
+ // However, if we're not ended, or reading, and the length < hwm,
+ // then go ahead and try to read some more right now preemptively.
+ if (!state.reading && !state.ending && !state.ended &&
+ state.length < state.highWaterMark) {
+ stream.read(0);
+ }
+}
+
+// abstract method. to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function(n, cb) {
+ process.nextTick(function() {
+ cb(new Error('not implemented'));
+ });
+};
+
+Readable.prototype.pipe = function(dest, pipeOpts) {
+ var src = this;
+ var state = this._readableState;
+
+ switch (state.pipesCount) {
+ case 0:
+ state.pipes = dest;
+ break;
+ case 1:
+ state.pipes = [state.pipes, dest];
+ break;
+ default:
+ state.pipes.push(dest);
+ break;
+ }
+ state.pipesCount += 1;
+
+ if ((!pipeOpts || pipeOpts.end !== false) &&
+ dest !== process.stdout &&
+ dest !== process.stderr) {
+ src.once('end', onend);
+ } else {
+ src.once('end', cleanup);
+ }
+
+ dest.on('unpipe', onunpipe);
+ function onunpipe(readable) {
+ if (readable !== src) return;
+ cleanup();
+ }
+
+ if (pipeOpts && pipeOpts.chunkSize)
+ state.pipeChunkSize = pipeOpts.chunkSize;
+
+ function onend() {
+ dest.end();
+ }
+
+ // when the dest drains, it reduces the awaitDrain counter
+ // on the source. This would be more elegant with a .once()
+ // handler in flow(), but adding and removing repeatedly is
+ // too slow.
+ var ondrain = pipeOnDrain(src);
+ dest.on('drain', ondrain);
+
+ function cleanup() {
+ // cleanup event handlers once the pipe is broken
+ dest.removeListener('close', onclose);
+ dest.removeListener('finish', onfinish);
+ dest.removeListener('drain', ondrain);
+ dest.removeListener('error', onerror);
+ dest.removeListener('unpipe', onunpipe);
+ src.removeListener('end', onend);
+ src.removeListener('end', cleanup);
+
+ // if the reader is waiting for a drain event from this
+ // specific writer, then it would cause it to never start
+ // flowing again.
+ // So, if this is awaiting a drain, then we just call it now.
+ // If we don't know, then assume that we are waiting for one.
+ if (!dest._writableState || dest._writableState.needDrain)
+ ondrain();
+ }
+
+ // if the dest has an error, then stop piping into it.
+ // however, don't suppress the throwing behavior for this.
+ function onerror(er) {
+ unpipe();
+ if (dest.listeners('error').length === 0)
+ dest.emit('error', er);
+ }
+ dest.once('error', onerror);
+
+ // Both close and finish should trigger unpipe, but only once.
+ function onclose() {
+ dest.removeListener('finish', onfinish);
+ unpipe();
+ }
+ dest.once('close', onclose);
+ function onfinish() {
+ dest.removeListener('close', onclose);
+ unpipe();
+ }
+ dest.once('finish', onfinish);
+
+ function unpipe() {
+ src.unpipe(dest);
+ }
+
+ // tell the dest that it's being piped to
+ dest.emit('pipe', src);
+
+ // start the flow if it hasn't been started already.
+ if (!state.flowing) {
+ // the handler that waits for readable events after all
+ // the data gets sucked out in flow.
+ // This would be easier to follow with a .once() handler
+ // in flow(), but that is too slow.
+ this.on('readable', pipeOnReadable);
+
+ state.flowing = true;
+ process.nextTick(function() {
+ flow(src);
+ });
+ }
+
+ return dest;
+};
+
+function pipeOnDrain(src) {
+ return function() {
+ var dest = this;
+ var state = src._readableState;
+ state.awaitDrain--;
+ if (state.awaitDrain === 0)
+ flow(src);
+ };
+}
+
+function flow(src) {
+ var state = src._readableState;
+ var chunk;
+ state.awaitDrain = 0;
+
+ function write(dest, i, list) {
+ var written = dest.write(chunk);
+ if (false === written) {
+ state.awaitDrain++;
+ }
+ }
+
+ while (state.pipesCount &&
+ null !== (chunk = src.read(state.pipeChunkSize))) {
+
+ if (state.pipesCount === 1)
+ write(state.pipes, 0, null);
+ else
+ state.pipes.forEach(write);
+
+ src.emit('data', chunk);
+
+ // if anyone needs a drain, then we have to wait for that.
+ if (state.awaitDrain > 0)
+ return;
+ }
+
+ // if every destination was unpiped, either before entering this
+ // function, or in the while loop, then stop flowing.
+ //
+ // NB: This is a pretty rare edge case.
+ if (state.pipesCount === 0) {
+ state.flowing = false;
+
+ // if there were data event listeners added, then switch to old mode.
+ if (src.listeners('data').length)
+ emitDataEvents(src);
+ return;
+ }
+
+ // at this point, no one needed a drain, so we just ran out of data
+ // on the next readable event, start it over again.
+ state.ranOut = true;
+}
+
+function pipeOnReadable() {
+ if (this._readableState.ranOut) {
+ this._readableState.ranOut = false;
+ flow(this);
+ }
+}
+
+
+Readable.prototype.unpipe = function(dest) {
+ var state = this._readableState;
+
+ // if we're not piping anywhere, then do nothing.
+ if (state.pipesCount === 0)
+ return this;
+
+ // just one destination. most common case.
+ if (state.pipesCount === 1) {
+ // passed in one, but it's not the right one.
+ if (dest && dest !== state.pipes)
+ return this;
+
+ if (!dest)
+ dest = state.pipes;
+
+ // got a match.
+ state.pipes = null;
+ state.pipesCount = 0;
+ this.removeListener('readable', pipeOnReadable);
+ state.flowing = false;
+ if (dest)
+ dest.emit('unpipe', this);
+ return this;
+ }
+
+ // slow case. multiple pipe destinations.
+
+ if (!dest) {
+ // remove all.
+ var dests = state.pipes;
+ var len = state.pipesCount;
+ state.pipes = null;
+ state.pipesCount = 0;
+ this.removeListener('readable', pipeOnReadable);
+ state.flowing = false;
+
+ for (var i = 0; i < len; i++)
+ dests[i].emit('unpipe', this);
+ return this;
+ }
+
+ // try to find the right one.
+ var i = state.pipes.indexOf(dest);
+ if (i === -1)
+ return this;
+
+ state.pipes.splice(i, 1);
+ state.pipesCount -= 1;
+ if (state.pipesCount === 1)
+ state.pipes = state.pipes[0];
+
+ dest.emit('unpipe', this);
+
+ return this;
+};
+
+// kludge for on('data', fn) consumers. Sad.
+// This is *not* part of the new readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.on = function(ev, fn) {
+ var res = Stream.prototype.on.call(this, ev, fn);
+
+ // https://github.com/isaacs/readable-stream/issues/16
+ // if we're already flowing, then no need to set up data events.
+ if (ev === 'data' && !this._readableState.flowing)
+ emitDataEvents(this);
+
+ return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function() {
+ emitDataEvents(this);
+ this.read(0);
+ this.emit('resume');
+};
+
+Readable.prototype.pause = function() {
+ emitDataEvents(this, true);
+ this.emit('pause');
+};
+
+function emitDataEvents(stream, startPaused) {
+ var state = stream._readableState;
+
+ if (state.flowing) {
+ // https://github.com/isaacs/readable-stream/issues/16
+ throw new Error('Cannot switch to old mode now.');
+ }
+
+ var paused = startPaused || false;
+ var readable = false;
+
+ // convert to an old-style stream.
+ stream.readable = true;
+ stream.pipe = Stream.prototype.pipe;
+ stream.on = stream.addListener = Stream.prototype.on;
+
+ stream.on('readable', function() {
+ readable = true;
+
+ var c;
+ while (!paused && (null !== (c = stream.read())))
+ stream.emit('data', c);
+
+ if (c === null) {
+ readable = false;
+ stream._readableState.needReadable = true;
+ }
+ });
+
+ stream.pause = function() {
+ paused = true;
+ this.emit('pause');
+ };
+
+ stream.resume = function() {
+ paused = false;
+ if (readable)
+ process.nextTick(function() {
+ stream.emit('readable');
+ });
+ else
+ this.read(0);
+ this.emit('resume');
+ };
+
+ // now make it start, just in case it hadn't already.
+ stream.emit('readable');
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function(stream) {
+ var state = this._readableState;
+ var paused = false;
+
+ var self = this;
+ stream.on('end', function() {
+ state.ended = true;
+ if (state.decoder) {
+ var chunk = state.decoder.end();
+ if (chunk && chunk.length)
+ self.push(chunk);
+ }
+
+ self.push(null);
+ });
+
+ stream.on('data', function(chunk) {
+ if (state.decoder)
+ chunk = state.decoder.write(chunk);
+ if (!chunk || !chunk.length)
+ return;
+
+ var ret = self.push(chunk);
+ if (!ret) {
+ paused = true;
+ stream.pause();
+ }
+ });
+
+ // proxy all the other methods.
+ // important when wrapping filters and duplexes.
+ for (var i in stream) {
+ if (typeof stream[i] === 'function' &&
+ typeof this[i] === 'undefined') {
+ this[i] = function(method) { return function() {
+ return stream[method].apply(stream, arguments);
+ }}(i);
+ }
+ }
+
+ // proxy certain important events.
+ var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+ events.forEach(function(ev) {
+ stream.on(ev, self.emit.bind(self, ev));
+ });
+
+ // when we try to consume some more bytes, simply unpause the
+ // underlying stream.
+ self._read = function(n, cb) {
+ if (paused) {
+ stream.resume();
+ paused = false;
+ }
+ };
+};
+
+
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+ var list = state.buffer;
+ var length = state.length;
+ var stringMode = !!state.decoder;
+ var objectMode = !!state.objectMode;
+ var ret;
+
+ // nothing in the list, definitely empty.
+ if (list.length === 0)
+ return null;
+
+ if (length === 0)
+ ret = null;
+ else if (objectMode)
+ ret = list.shift();
+ else if (!n || n >= length) {
+ // read it all, truncate the array.
+ if (stringMode)
+ ret = list.join('');
+ else
+ ret = Buffer.concat(list, length);
+ list.length = 0;
+ } else {
+ // read just some of it.
+ if (n < list[0].length) {
+ // just take a part of the first list item.
+ // slice is the same for buffers and strings.
+ var buf = list[0];
+ ret = buf.slice(0, n);
+ list[0] = buf.slice(n);
+ } else if (n === list[0].length) {
+ // first list is a perfect match
+ ret = list.shift();
+ } else {
+ // complex case.
+ // we have enough to cover it, but it spans past the first buffer.
+ if (stringMode)
+ ret = '';
+ else
+ ret = new Buffer(n);
+
+ var c = 0;
+ for (var i = 0, l = list.length; i < l && c < n; i++) {
+ var buf = list[0];
+ var cpy = Math.min(n - c, buf.length);
+
+ if (stringMode)
+ ret += buf.slice(0, cpy);
+ else
+ buf.copy(ret, c, 0, cpy);
+
+ if (cpy < buf.length)
+ list[0] = buf.slice(cpy);
+ else
+ list.shift();
+
+ c += cpy;
+ }
+ }
+ }
+
+ return ret;
+}
+
+function endReadable(stream) {
+ var state = stream._readableState;
+
+ // If we get here before consuming all the bytes, then that is a
+ // bug in node. Should never happen.
+ if (state.length > 0)
+ throw new Error('endReadable called on non-empty stream');
+
+ if (state.endEmitted)
+ return;
+ state.ended = true;
+ state.endEmitted = true;
+ process.nextTick(function() {
+ stream.readable = false;
+ stream.emit('end');
+ });
+}
diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js
new file mode 100644
index 000000000..0ee5a5030
--- /dev/null
+++ b/lib/_stream_transform.js
@@ -0,0 +1,203 @@
+// 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.
+
+
+// a transform stream is a readable/writable stream where you do
+// something with the data. Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored. (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation. For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes. When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up. When you call read(), that calls _read(n,cb) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer. When
+// _read(n,cb) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks. If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk. However,
+// a pathological inflate type of transform can cause excessive buffering
+// here. For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output. In this case, you could write a very small
+// amount of input, and end up with a very large amount of output. In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform. A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+module.exports = Transform;
+
+var Duplex = require('_stream_duplex');
+var util = require('util');
+util.inherits(Transform, Duplex);
+
+
+function TransformState(options, stream) {
+ var ts = this;
+ this.output = function(chunk) {
+ ts.needTransform = false;
+ stream.push(chunk);
+ };
+
+ this.afterTransform = function(er, data) {
+ return afterTransform(stream, er, data);
+ };
+
+ this.needTransform = false;
+ this.transforming = false;
+ this.writecb = null;
+ this.writechunk = null;
+}
+
+function afterTransform(stream, er, data) {
+ var ts = stream._transformState;
+ ts.transforming = false;
+
+ var cb = ts.writecb;
+
+ if (!cb)
+ return this.emit('error', new Error('no writecb in Transform class'));
+
+ ts.writechunk = null;
+ ts.writecb = null;
+
+ if (data !== null && data !== undefined)
+ ts.output(data);
+
+ if (cb)
+ cb(er);
+
+ var rs = stream._readableState;
+ if (rs.needReadable || rs.length < rs.highWaterMark) {
+ stream._read();
+ }
+}
+
+
+function Transform(options) {
+ if (!(this instanceof Transform))
+ return new Transform(options);
+
+ Duplex.call(this, options);
+
+ var ts = this._transformState = new TransformState(options, this);
+
+ // when the writable side finishes, then flush out anything remaining.
+ var stream = this;
+
+ // start out asking for a readable event once data is transformed.
+ this._readableState.needReadable = true;
+
+ // we have implemented the _read method, and done the other things
+ // that Readable wants before the first _read call, so unset the
+ // sync guard flag.
+ this._readableState.sync = false;
+
+ this.once('finish', function() {
+ if ('function' === typeof this._flush)
+ this._flush(ts.output, function(er) {
+ done(stream, er);
+ });
+ else
+ done(stream);
+ });
+}
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `output(newChunk)` to pass along transformed output
+// to the readable side. You may call 'output' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk. If you pass
+// an error, then that'll put the hurt on the whole operation. If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function(chunk, output, cb) {
+ throw new Error('not implemented');
+};
+
+Transform.prototype._write = function(chunk, cb) {
+ var ts = this._transformState;
+ ts.writecb = cb;
+ ts.writechunk = chunk;
+ if (ts.transforming)
+ return;
+ var rs = this._readableState;
+ if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark)
+ this._read();
+};
+
+// Doesn't matter what the args are here.
+// the output and callback functions passed to _transform do all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function(n, cb) {
+ var ts = this._transformState;
+
+ if (ts.writechunk && ts.writecb && !ts.transforming) {
+ ts.transforming = true;
+ this._transform(ts.writechunk, ts.output, ts.afterTransform);
+ return;
+ }
+
+ // mark that we need a transform, so that any data that comes in
+ // will get processed, now that we've asked for it.
+ ts.needTransform = true;
+};
+
+
+function done(stream, er) {
+ if (er)
+ return stream.emit('error', er);
+
+ // if there's nothing in the write buffer, then that means
+ // that nothing more will ever be provided
+ var ws = stream._writableState;
+ var rs = stream._readableState;
+ var ts = stream._transformState;
+
+ if (ws.length)
+ throw new Error('calling transform done when ws.length != 0');
+
+ if (ts.transforming)
+ throw new Error('calling transform done when still transforming');
+
+ return stream.push(null);
+}
diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js
new file mode 100644
index 000000000..b8f88be27
--- /dev/null
+++ b/lib/_stream_writable.js
@@ -0,0 +1,328 @@
+// 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.
+
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, cb), and it'll handle all
+// the drain event emission and buffering.
+
+module.exports = Writable;
+Writable.WritableState = WritableState;
+
+var util = require('util');
+var assert = require('assert');
+var Stream = require('stream');
+
+util.inherits(Writable, Stream);
+
+function WritableState(options, stream) {
+ options = options || {};
+
+ // the point at which write() starts returning false
+ // Note: 0 is a valid value, means that we always return false if
+ // the entire buffer is not flushed immediately on write()
+ var hwm = options.highWaterMark;
+ this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;
+
+ // object stream flag to indicate whether or not this stream
+ // contains buffers or objects.
+ this.objectMode = !!options.objectMode;
+
+ // cast to ints.
+ this.highWaterMark = ~~this.highWaterMark;
+
+ this.needDrain = false;
+ // at the start of calling end()
+ this.ending = false;
+ // when end() has been called, and returned
+ this.ended = false;
+ // when 'finish' has emitted
+ this.finished = false;
+ // when 'finish' is being emitted
+ this.finishing = false;
+
+ // should we decode strings into buffers before passing to _write?
+ // this is here so that some node-core streams can optimize string
+ // handling at a lower level.
+ var noDecode = options.decodeStrings === false;
+ this.decodeStrings = !noDecode;
+
+ // not an actual buffer we keep track of, but a measurement
+ // of how much we're waiting to get pushed to some underlying
+ // socket or file.
+ this.length = 0;
+
+ // a flag to see when we're in the middle of a write.
+ this.writing = false;
+
+ // a flag to be able to tell if the onwrite cb is called immediately,
+ // or on a later tick. We set this to true at first, becuase any
+ // actions that shouldn't happen until "later" should generally also
+ // not happen before the first write call.
+ this.sync = true;
+
+ // a flag to know if we're processing previously buffered items, which
+ // may call the _write() callback in the same tick, so that we don't
+ // end up in an overlapped onwrite situation.
+ this.bufferProcessing = false;
+
+ // the callback that's passed to _write(chunk,cb)
+ this.onwrite = function(er) {
+ onwrite(stream, er);
+ };
+
+ // the callback that the user supplies to write(chunk,encoding,cb)
+ this.writecb = null;
+
+ // the amount that is being written when _write is called.
+ this.writelen = 0;
+
+ this.buffer = [];
+}
+
+function Writable(options) {
+ // Writable ctor is applied to Duplexes, though they're not
+ // instanceof Writable, they're instanceof Readable.
+ if (!(this instanceof Writable) && !(this instanceof Stream.Duplex))
+ return new Writable(options);
+
+ this._writableState = new WritableState(options, this);
+
+ // legacy.
+ this.writable = true;
+
+ Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function() {
+ this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+// Override this method or _write(chunk, cb)
+Writable.prototype.write = function(chunk, encoding, cb) {
+ var state = this._writableState;
+
+ if (typeof encoding === 'function') {
+ cb = encoding;
+ encoding = null;
+ }
+
+ if (state.ended) {
+ var er = new Error('write after end');
+ if (typeof cb === 'function')
+ cb(er);
+ this.emit('error', er);
+ return;
+ }
+
+ // If we get something that is not a buffer, string, null, or undefined,
+ // and we're not in objectMode, then that's an error.
+ // Otherwise stream chunks are all considered to be of length=1, and the
+ // watermarks determine how many objects to keep in the buffer, rather than
+ // how many bytes or characters.
+ if (!Buffer.isBuffer(chunk) &&
+ 'string' !== typeof chunk &&
+ chunk !== null &&
+ chunk !== undefined &&
+ !state.objectMode) {
+ var er = new TypeError('Invalid non-string/buffer chunk');
+ if (typeof cb === 'function')
+ cb(er);
+ this.emit('error', er);
+ return;
+ }
+
+ var len;
+ if (state.objectMode)
+ len = 1;
+ else {
+ len = chunk.length;
+ if (false === state.decodeStrings)
+ chunk = [chunk, encoding || 'utf8'];
+ else if (typeof chunk === 'string') {
+ chunk = new Buffer(chunk, encoding);
+ len = chunk.length;
+ }
+ }
+
+ state.length += len;
+
+ var ret = state.length < state.highWaterMark;
+ if (ret === false)
+ state.needDrain = true;
+
+ // if we're already writing something, then just put this
+ // in the queue, and wait our turn.
+ if (state.writing) {
+ state.buffer.push([chunk, cb]);
+ return ret;
+ }
+
+ state.writing = true;
+ state.sync = true;
+ state.writelen = len;
+ state.writecb = cb;
+ this._write(chunk, state.onwrite);
+ state.sync = false;
+
+ return ret;
+};
+
+function onwrite(stream, er) {
+ var state = stream._writableState;
+ var sync = state.sync;
+ var cb = state.writecb;
+ var len = state.writelen;
+
+ state.writing = false;
+ state.writelen = null;
+ state.writecb = null;
+
+ if (er) {
+ if (cb) {
+ // If _write(chunk,cb) calls cb() in this tick, we still defer
+ // the *user's* write callback to the next tick.
+ // Never present an external API that is *sometimes* async!
+ if (sync)
+ process.nextTick(function() {
+ cb(er);
+ });
+ else
+ cb(er);
+ }
+
+ // backwards compatibility. still emit if there was a cb.
+ stream.emit('error', er);
+ return;
+ }
+ state.length -= len;
+
+ if (cb) {
+ // Don't call the cb until the next tick if we're in sync mode.
+ if (sync)
+ process.nextTick(cb);
+ else
+ cb();
+ }
+
+ if (state.length === 0 && (state.ended || state.ending) &&
+ !state.finished && !state.finishing) {
+ // emit 'finish' at the very end.
+ state.finishing = true;
+ stream.emit('finish');
+ state.finished = true;
+ return;
+ }
+
+ if (state.length === 0 && state.needDrain) {
+ // Must force callback to be called on nextTick, so that we don't
+ // emit 'drain' before the write() consumer gets the 'false' return
+ // value, and has a chance to attach a 'drain' listener.
+ process.nextTick(function() {
+ if (!state.needDrain)
+ return;
+ state.needDrain = false;
+ stream.emit('drain');
+ });
+ }
+
+ // if there's something in the buffer waiting, then process it
+ // It would be nice if there were TCO in JS, and we could just
+ // shift the top off the buffer and _write that, but that approach
+ // causes RangeErrors when you have a very large number of very
+ // small writes, and is not very efficient otherwise.
+ if (!state.bufferProcessing && state.buffer.length) {
+ state.bufferProcessing = true;
+
+ for (var c = 0; c < state.buffer.length; c++) {
+ var chunkCb = state.buffer[c];
+ var chunk = chunkCb[0];
+ cb = chunkCb[1];
+
+ if (state.objectMode)
+ len = 1;
+ else if (false === state.decodeStrings)
+ len = chunk[0].length;
+ else
+ len = chunk.length;
+
+ state.writelen = len;
+ state.writecb = cb;
+ state.writechunk = chunk;
+ state.writing = true;
+ state.sync = true;
+ stream._write(chunk, state.onwrite);
+ state.sync = false;
+
+ // if we didn't call the onwrite immediately, then
+ // it means that we need to wait until it does.
+ // also, that means that the chunk and cb are currently
+ // being processed, so move the buffer counter past them.
+ if (state.writing) {
+ c++;
+ break;
+ }
+ }
+
+ state.bufferProcessing = false;
+ if (c < state.buffer.length)
+ state.buffer = state.buffer.slice(c);
+ else
+ state.buffer.length = 0;
+ }
+}
+
+Writable.prototype._write = function(chunk, cb) {
+ process.nextTick(function() {
+ cb(new Error('not implemented'));
+ });
+};
+
+Writable.prototype.end = function(chunk, encoding, cb) {
+ var state = this._writableState;
+
+ // ignore unnecessary end() calls.
+ if (state.ending || state.ended || state.finished)
+ return;
+
+ if (typeof chunk === 'function') {
+ cb = chunk;
+ chunk = null;
+ encoding = null;
+ } else if (typeof encoding === 'function') {
+ cb = encoding;
+ encoding = null;
+ }
+
+ state.ending = true;
+ if (chunk)
+ this.write(chunk, encoding, cb);
+ else if (state.length === 0 && !state.finishing && !state.finished) {
+ state.finishing = true;
+ this.emit('finish');
+ state.finished = true;
+ if (cb) process.nextTick(cb);
+ } else if (cb) {
+ this.once('finish', cb);
+ }
+
+ state.ended = true;
+};
diff --git a/lib/assert.js b/lib/assert.js
index 70dc0b0ee..a2afdcfb0 100644
--- a/lib/assert.js
+++ b/lib/assert.js
@@ -277,7 +277,7 @@ function expectedException(actual, expected) {
return false;
}
- if (expected instanceof RegExp) {
+ if (Object.prototype.toString.call(expected) == '[object RegExp]') {
return expected.test(actual);
} else if (actual instanceof expected) {
return true;
@@ -327,7 +327,7 @@ assert.throws = function(block, /*optional*/error, /*optional*/message) {
};
// EXTENSION! This is annoying to write outside this module.
-assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
+assert.doesNotThrow = function(block, /*optional*/message) {
_throws.apply(this, [false].concat(pSlice.call(arguments)));
};
diff --git a/lib/buffer.js b/lib/buffer.js
index 6bfbc93cd..3378dcebf 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -29,31 +29,27 @@ exports.INSPECT_MAX_BYTES = 50;
SlowBuffer.prototype.__proto__ = Buffer.prototype;
+function clamp(index, len, defaultValue) {
+ if (typeof index !== 'number') return defaultValue;
+ index = ~~index; // Coerce to integer.
+ if (index >= len) return len;
+ if (index >= 0) return index;
+ index += len;
+ if (index >= 0) return index;
+ return 0;
+}
+
+
function toHex(n) {
if (n < 16) return '0' + n.toString(16);
return n.toString(16);
}
-SlowBuffer.prototype.hexSlice = function(start, end) {
- var len = this.length;
-
- if (!start || start < 0) start = 0;
- if (!end || end < 0 || end > len) end = len;
-
- var out = '';
- for (var i = start; i < end; i++) {
- out += toHex(this[i]);
- }
- return out;
-};
-
-
-
SlowBuffer.prototype.toString = function(encoding, start, end) {
encoding = String(encoding || 'utf8').toLowerCase();
start = +start || 0;
- if (typeof end == 'undefined') end = this.length;
+ if (typeof end !== 'number') end = this.length;
// Fastpath empty strings
if (+end == start) {
@@ -84,38 +80,8 @@ SlowBuffer.prototype.toString = function(encoding, start, end) {
return this.ucs2Slice(start, end);
default:
- throw new Error('Unknown encoding');
- }
-};
-
-
-SlowBuffer.prototype.hexWrite = function(string, offset, length) {
- offset = +offset || 0;
- var remaining = this.length - offset;
- if (!length) {
- length = remaining;
- } else {
- length = +length;
- if (length > remaining) {
- length = remaining;
- }
- }
-
- // must be an even number of digits
- var strLen = string.length;
- if (strLen % 2) {
- throw new Error('Invalid hex string');
+ throw new TypeError('Unknown encoding: ' + encoding);
}
- if (length > strLen / 2) {
- length = strLen / 2;
- }
- for (var i = 0; i < length; i++) {
- var byte = parseInt(string.substr(i * 2, 2), 16);
- if (isNaN(byte)) throw new Error('Invalid hex string');
- this[offset + i] = byte;
- }
- SlowBuffer._charsWritten = i * 2;
- return i;
};
@@ -170,35 +136,20 @@ SlowBuffer.prototype.write = function(string, offset, length, encoding) {
return this.ucs2Write(string, offset, length);
default:
- throw new Error('Unknown encoding');
+ throw new TypeError('Unknown encoding: ' + encoding);
}
};
// slice(start, end)
SlowBuffer.prototype.slice = function(start, end) {
- if (end === undefined) end = this.length;
-
- if (end > this.length) {
- throw new Error('oob');
- }
- if (start > end) {
- throw new Error('oob');
- }
-
- return new Buffer(this, end - start, +start);
+ var len = this.length;
+ start = clamp(start, len, 0);
+ end = clamp(end, len, len);
+ return new Buffer(this, end - start, start);
};
-function coerce(length) {
- // Coerce length to a number (possibly NaN), round up
- // in case it's fractional (e.g. 123.456). Since NaN
- // comparisons are always false, use to return zero.
- length = Math.ceil(+length);
- return length > 0 ? length : 0;
-}
-
-
var zeroBuffer = new SlowBuffer(0);
// Buffer
@@ -212,30 +163,30 @@ function Buffer(subject, encoding, offset) {
// Are we slicing?
if (typeof offset === 'number') {
if (!Buffer.isBuffer(subject)) {
- throw new Error('First argument must be a Buffer when slicing');
+ throw new TypeError('First argument must be a Buffer when slicing');
}
- this.length = coerce(encoding);
+ this.length = +encoding > 0 ? Math.ceil(encoding) : 0;
this.parent = subject.parent ? subject.parent : subject;
this.offset = offset;
} else {
// Find the length
switch (type = typeof subject) {
case 'number':
- this.length = coerce(subject);
+ this.length = +subject > 0 ? Math.ceil(subject) : 0;
break;
case 'string':
this.length = Buffer.byteLength(subject, encoding);
break;
- case 'object': // Assume object is an array
- this.length = coerce(subject.length);
+ case 'object': // Assume object is array-ish
+ this.length = +subject.length > 0 ? Math.ceil(subject.length) : 0;
break;
default:
- throw new Error('First argument needs to be a number, ' +
- 'array or string.');
+ throw new TypeError('First argument needs to be a number, ' +
+ 'array or string.');
}
if (this.length > Buffer.poolSize) {
@@ -257,14 +208,24 @@ function Buffer(subject, encoding, offset) {
this.offset = 0;
}
- // Treat array-ish objects as a byte array.
- if (isArrayIsh(subject)) {
- for (var i = 0; i < this.length; i++) {
- this.parent[i + this.offset] = subject[i];
+ // optimize by branching logic for new allocations
+ if (typeof subject !== 'number') {
+ if (type === 'string') {
+ // We are a string
+ this.length = this.write(subject, 0, encoding);
+ // if subject is buffer then use built-in copy method
+ } else if (Buffer.isBuffer(subject)) {
+ if (subject.parent)
+ subject.parent.copy(this.parent,
+ this.offset,
+ subject.offset,
+ this.length + subject.offset);
+ else
+ subject.copy(this.parent, this.offset, 0, this.length);
+ } else if (isArrayIsh(subject)) {
+ for (var i = 0; i < this.length; i++)
+ this.parent[i + this.offset] = subject[i];
}
- } else if (type == 'string') {
- // We are a string
- this.length = this.write(subject, 0, encoding);
}
}
@@ -272,7 +233,7 @@ function Buffer(subject, encoding, offset) {
}
function isArrayIsh(subject) {
- return Array.isArray(subject) || Buffer.isBuffer(subject) ||
+ return Array.isArray(subject) ||
subject && typeof subject === 'object' &&
typeof subject.length === 'number';
}
@@ -280,6 +241,29 @@ function isArrayIsh(subject) {
exports.SlowBuffer = SlowBuffer;
exports.Buffer = Buffer;
+
+Buffer.isEncoding = function(encoding) {
+ switch (encoding && encoding.toLowerCase()) {
+ case 'hex':
+ case 'utf8':
+ case 'utf-8':
+ case 'ascii':
+ case 'binary':
+ case 'base64':
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ case 'raw':
+ return true;
+
+ default:
+ return false;
+ }
+};
+
+
+
Buffer.poolSize = 8 * 1024;
var pool;
@@ -313,15 +297,17 @@ Buffer.prototype.inspect = function inspect() {
};
-Buffer.prototype.get = function get(i) {
- if (i < 0 || i >= this.length) throw new Error('oob');
- return this.parent[this.offset + i];
+Buffer.prototype.get = function get(offset) {
+ if (offset < 0 || offset >= this.length)
+ throw new RangeError('offset is out of bounds');
+ return this.parent[this.offset + offset];
};
-Buffer.prototype.set = function set(i, v) {
- if (i < 0 || i >= this.length) throw new Error('oob');
- return this.parent[this.offset + i] = v;
+Buffer.prototype.set = function set(offset, v) {
+ if (offset < 0 || offset >= this.length)
+ throw new RangeError('offset is out of bounds');
+ return this.parent[this.offset + offset] = v;
};
@@ -385,7 +371,7 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
break;
default:
- throw new Error('Unknown encoding');
+ throw new TypeError('Unknown encoding: ' + encoding);
}
Buffer._charsWritten = SlowBuffer._charsWritten;
@@ -394,17 +380,22 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
};
+Buffer.prototype.toJSON = function() {
+ return Array.prototype.slice.call(this, 0);
+};
+
+
// toString(encoding, start=0, end=buffer.length)
Buffer.prototype.toString = function(encoding, start, end) {
encoding = String(encoding || 'utf8').toLowerCase();
- if (typeof start == 'undefined' || start < 0) {
+ if (typeof start !== 'number' || start < 0) {
start = 0;
} else if (start > this.length) {
start = this.length;
}
- if (typeof end == 'undefined' || end > this.length) {
+ if (typeof end !== 'number' || end > this.length) {
end = this.length;
} else if (end < 0) {
end = 0;
@@ -437,7 +428,7 @@ Buffer.prototype.toString = function(encoding, start, end) {
return this.parent.ucs2Slice(start, end);
default:
- throw new Error('Unknown encoding');
+ throw new TypeError('Unknown encoding: ' + encoding);
}
};
@@ -455,22 +446,22 @@ Buffer.prototype.fill = function fill(value, start, end) {
if (typeof value === 'string') {
value = value.charCodeAt(0);
}
- if (!(typeof value === 'number') || isNaN(value)) {
- throw new Error('value is not a number');
+ if (typeof value !== 'number' || isNaN(value)) {
+ throw new TypeError('value is not a number');
}
- if (end < start) throw new Error('end < start');
+ if (end < start) throw new RangeError('end < start');
// Fill 0 bytes; we're done
if (end === start) return 0;
if (this.length == 0) return 0;
if (start < 0 || start >= this.length) {
- throw new Error('start out of bounds');
+ throw new RangeError('start out of bounds');
}
if (end < 0 || end > this.length) {
- throw new Error('end out of bounds');
+ throw new RangeError('end out of bounds');
}
return this.parent.fill(value,
@@ -481,7 +472,7 @@ Buffer.prototype.fill = function fill(value, start, end) {
Buffer.concat = function(list, length) {
if (!Array.isArray(list)) {
- throw new Error('Usage: Buffer.concat(list, [length])');
+ throw new TypeError('Usage: Buffer.concat(list, [length])');
}
if (list.length === 0) {
@@ -513,37 +504,26 @@ Buffer.concat = function(list, length) {
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function(target, target_start, start, end) {
- var source = this;
- start || (start = 0);
- end || (end = this.length);
- target_start || (target_start = 0);
-
- if (end < start) throw new Error('sourceEnd < sourceStart');
+ // set undefined/NaN or out of bounds values equal to their default
+ if (!(target_start >= 0)) target_start = 0;
+ if (!(start >= 0)) start = 0;
+ if (!(end < this.length)) end = this.length;
// Copy 0 bytes; we're done
- if (end === start) return 0;
- if (target.length == 0 || source.length == 0) return 0;
-
- if (target_start < 0 || target_start >= target.length) {
- throw new Error('targetStart out of bounds');
- }
-
- if (start < 0 || start >= source.length) {
- throw new Error('sourceStart out of bounds');
- }
+ if (end === start ||
+ target.length === 0 ||
+ this.length === 0 ||
+ start > this.length)
+ return 0;
- if (end < 0 || end > source.length) {
- throw new Error('sourceEnd out of bounds');
- }
+ if (end < start)
+ throw new RangeError('sourceEnd < sourceStart');
- // Are we oob?
- if (end > this.length) {
- end = this.length;
- }
+ if (target_start >= target.length)
+ throw new RangeError('targetStart out of bounds');
- if (target.length - target_start < end - start) {
+ if (target.length - target_start < end - start)
end = target.length - target_start + start;
- }
return this.parent.copy(target.parent || target,
target_start + (target.offset || 0),
@@ -554,11 +534,10 @@ Buffer.prototype.copy = function(target, target_start, start, end) {
// slice(start, end)
Buffer.prototype.slice = function(start, end) {
- if (end === undefined) end = this.length;
- if (end > this.length) throw new Error('oob');
- if (start > end) throw new Error('oob');
- if (start < 0) throw new Error('start out of bounds');
- return new Buffer(this.parent, end - start, +start + this.offset);
+ var len = this.length;
+ start = clamp(start, len, 0);
+ end = clamp(end, len, len);
+ return new Buffer(this.parent, end - start, start + this.offset);
};
@@ -588,35 +567,28 @@ Buffer.prototype.asciiWrite = function(string, offset) {
return this.write(string, offset, 'ascii');
};
-Buffer.prototype.readUInt8 = function(offset, noAssert) {
- var buffer = this;
- if (!noAssert) {
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
+/*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ * This check is far too slow internally for fast buffers.
+ */
+function checkOffset(offset, ext, length) {
+ if ((offset % 1) !== 0 || offset < 0)
+ throw new RangeError('offset is not uint');
+ if (offset + ext > length)
+ throw new RangeError('Trying to access beyond buffer length');
+}
- assert.ok(offset < buffer.length,
- 'Trying to read beyond buffer length');
- }
- return buffer[offset];
+Buffer.prototype.readUInt8 = function(offset, noAssert) {
+ if (!noAssert)
+ checkOffset(offset, 1, this.length);
+ return this[offset];
};
-function readUInt16(buffer, offset, isBigEndian, noAssert) {
- var val = 0;
-
-
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 1 < buffer.length,
- 'Trying to read beyond buffer length');
- }
+function readUInt16(buffer, offset, isBigEndian) {
+ var val = 0;
if (isBigEndian) {
val = buffer[offset] << 8;
val |= buffer[offset + 1];
@@ -628,28 +600,24 @@ function readUInt16(buffer, offset, isBigEndian, noAssert) {
return val;
}
+
Buffer.prototype.readUInt16LE = function(offset, noAssert) {
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
return readUInt16(this, offset, false, noAssert);
};
+
Buffer.prototype.readUInt16BE = function(offset, noAssert) {
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
return readUInt16(this, offset, true, noAssert);
};
+
function readUInt32(buffer, offset, isBigEndian, noAssert) {
var val = 0;
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 3 < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
if (isBigEndian) {
val = buffer[offset + 1] << 16;
val |= buffer[offset + 2] << 8;
@@ -665,11 +633,17 @@ function readUInt32(buffer, offset, isBigEndian, noAssert) {
return val;
}
+
Buffer.prototype.readUInt32LE = function(offset, noAssert) {
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
return readUInt32(this, offset, false, noAssert);
};
+
Buffer.prototype.readUInt32BE = function(offset, noAssert) {
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
return readUInt32(this, offset, true, noAssert);
};
@@ -719,188 +693,107 @@ Buffer.prototype.readUInt32BE = function(offset, noAssert) {
* (0x007f + 1) * -1
* (0x0080) * -1
*/
-Buffer.prototype.readInt8 = function(offset, noAssert) {
- var buffer = this;
- var neg;
-
- if (!noAssert) {
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- neg = buffer[offset] & 0x80;
- if (!neg) {
- return (buffer[offset]);
- }
- return ((0xff - buffer[offset] + 1) * -1);
+Buffer.prototype.readInt8 = function(offset, noAssert) {
+ if (!noAssert)
+ checkOffset(offset, 1, this.length);
+ if (!(this[offset] & 0x80))
+ return (this[offset]);
+ return ((0xff - this[offset] + 1) * -1);
};
-function readInt16(buffer, offset, isBigEndian, noAssert) {
- var neg, val;
-
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
- assert.ok(offset + 1 < buffer.length,
- 'Trying to read beyond buffer length');
- }
+function readInt16(buffer, offset, isBigEndian) {
+ var val = readUInt16(buffer, offset, isBigEndian);
- val = readUInt16(buffer, offset, isBigEndian, noAssert);
- neg = val & 0x8000;
- if (!neg) {
+ if (!(val & 0x8000))
return val;
- }
-
return (0xffff - val + 1) * -1;
}
+
Buffer.prototype.readInt16LE = function(offset, noAssert) {
- return readInt16(this, offset, false, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ return readInt16(this, offset, false);
};
+
Buffer.prototype.readInt16BE = function(offset, noAssert) {
- return readInt16(this, offset, true, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ return readInt16(this, offset, true);
};
-function readInt32(buffer, offset, isBigEndian, noAssert) {
- var neg, val;
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
+function readInt32(buffer, offset, isBigEndian) {
+ var val = readUInt32(buffer, offset, isBigEndian);
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 3 < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- val = readUInt32(buffer, offset, isBigEndian, noAssert);
- neg = val & 0x80000000;
- if (!neg) {
+ if (!(val & 0x80000000))
return (val);
- }
-
return (0xffffffff - val + 1) * -1;
}
+
Buffer.prototype.readInt32LE = function(offset, noAssert) {
- return readInt32(this, offset, false, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ return readInt32(this, offset, false);
};
+
Buffer.prototype.readInt32BE = function(offset, noAssert) {
- return readInt32(this, offset, true, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ return readInt32(this, offset, true);
};
-function readFloat(buffer, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset + 3 < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- return require('buffer_ieee754').readIEEE754(buffer, offset, isBigEndian,
- 23, 4);
-}
-
Buffer.prototype.readFloatLE = function(offset, noAssert) {
- return readFloat(this, offset, false, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+ return this.parent.readFloatLE(this.offset + offset, !!noAssert);
};
+
Buffer.prototype.readFloatBE = function(offset, noAssert) {
- return readFloat(this, offset, true, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+ return this.parent.readFloatBE(this.offset + offset, !!noAssert);
};
-function readDouble(buffer, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset + 7 < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- return require('buffer_ieee754').readIEEE754(buffer, offset, isBigEndian,
- 52, 8);
-}
Buffer.prototype.readDoubleLE = function(offset, noAssert) {
- return readDouble(this, offset, false, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 8, this.length);
+ return this.parent.readDoubleLE(this.offset + offset, !!noAssert);
};
+
Buffer.prototype.readDoubleBE = function(offset, noAssert) {
- return readDouble(this, offset, true, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 8, this.length);
+ return this.parent.readDoubleBE(this.offset + offset, !!noAssert);
};
-/*
- * We have to make sure that the value is a valid integer. This means that it is
- * non-negative. It has no fractional component and that it does not exceed the
- * maximum allowed value.
- *
- * value The number to check for validity
- *
- * max The maximum value
- */
-function verifuint(value, max) {
- assert.ok(typeof (value) == 'number',
- 'cannot write a non-number as a number');
-
- assert.ok(value >= 0,
- 'specified a negative value for writing an unsigned value');
-
- assert.ok(value <= max, 'value is larger than maximum value for type');
-
- assert.ok(Math.floor(value) === value, 'value has a fractional component');
+function checkInt(buffer, value, offset, ext, max, min) {
+ if ((value % 1) !== 0 || value > max || value < min)
+ throw TypeError('value is out of bounds');
+ if ((offset % 1) !== 0 || offset < 0)
+ throw TypeError('offset is not uint');
+ if (offset + ext > buffer.length || buffer.length + offset < 0)
+ throw RangeError('Trying to write outside buffer length');
}
-Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
- var buffer = this;
-
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset < buffer.length,
- 'trying to write beyond buffer length');
-
- verifuint(value, 0xff);
- }
- buffer[offset] = value;
+Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
+ if (!noAssert)
+ checkInt(this, value, offset, 1, 0xff, 0);
+ this[offset] = value;
};
-function writeUInt16(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 1 < buffer.length,
- 'trying to write beyond buffer length');
-
- verifuint(value, 0xffff);
- }
+function writeUInt16(buffer, value, offset, isBigEndian) {
if (isBigEndian) {
buffer[offset] = (value & 0xff00) >>> 8;
buffer[offset + 1] = value & 0x00ff;
@@ -910,31 +803,22 @@ function writeUInt16(buffer, value, offset, isBigEndian, noAssert) {
}
}
+
Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
- writeUInt16(this, value, offset, false, noAssert);
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0xffff, 0);
+ writeUInt16(this, value, offset, false);
};
+
Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
- writeUInt16(this, value, offset, true, noAssert);
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0xffff, 0);
+ writeUInt16(this, value, offset, true);
};
-function writeUInt32(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 3 < buffer.length,
- 'trying to write beyond buffer length');
-
- verifuint(value, 0xffffffff);
- }
+function writeUInt32(buffer, value, offset, isBigEndian) {
if (isBigEndian) {
buffer[offset] = (value >>> 24) & 0xff;
buffer[offset + 1] = (value >>> 16) & 0xff;
@@ -948,12 +832,18 @@ function writeUInt32(buffer, value, offset, isBigEndian, noAssert) {
}
}
+
Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
- writeUInt32(this, value, offset, false, noAssert);
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0xffffffff, 0);
+ writeUInt32(this, value, offset, false);
};
+
Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
- writeUInt32(this, value, offset, true, noAssert);
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0xffffffff, 0);
+ writeUInt32(this, value, offset, true);
};
@@ -994,170 +884,69 @@ Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
* hacky, but it should work and get the job done which is our goal here.
*/
-/*
- * A series of checks to make sure we actually have a signed 32-bit number
- */
-function verifsint(value, max, min) {
- assert.ok(typeof (value) == 'number',
- 'cannot write a non-number as a number');
-
- assert.ok(value <= max, 'value larger than maximum allowed value');
-
- assert.ok(value >= min, 'value smaller than minimum allowed value');
-
- assert.ok(Math.floor(value) === value, 'value has a fractional component');
-}
-
-function verifIEEE754(value, max, min) {
- assert.ok(typeof (value) == 'number',
- 'cannot write a non-number as a number');
-
- assert.ok(value <= max, 'value larger than maximum allowed value');
-
- assert.ok(value >= min, 'value smaller than minimum allowed value');
-}
-
Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
- var buffer = this;
-
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset < buffer.length,
- 'Trying to write beyond buffer length');
-
- verifsint(value, 0x7f, -0x80);
- }
-
- if (value >= 0) {
- buffer.writeUInt8(value, offset, noAssert);
- } else {
- buffer.writeUInt8(0xff + value + 1, offset, noAssert);
- }
+ if (!noAssert)
+ checkInt(this, value, offset, 1, 0x7f, -0x80);
+ if (value < 0) value = 0xff + value + 1;
+ this[offset] = value;
};
-function writeInt16(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 1 < buffer.length,
- 'Trying to write beyond buffer length');
-
- verifsint(value, 0x7fff, -0x8000);
- }
-
- if (value >= 0) {
- writeUInt16(buffer, value, offset, isBigEndian, noAssert);
- } else {
- writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert);
- }
-}
Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
- writeInt16(this, value, offset, false, noAssert);
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0x7fff, -0x8000);
+ if (value < 0) value = 0xffff + value + 1;
+ writeUInt16(this, value, offset, false);
};
+
Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
- writeInt16(this, value, offset, true, noAssert);
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0x7fff, -0x8000);
+ if (value < 0) value = 0xffff + value + 1;
+ writeUInt16(this, value, offset, true);
};
-function writeInt32(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 3 < buffer.length,
- 'Trying to write beyond buffer length');
-
- verifsint(value, 0x7fffffff, -0x80000000);
- }
-
- if (value >= 0) {
- writeUInt32(buffer, value, offset, isBigEndian, noAssert);
- } else {
- writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert);
- }
-}
Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
- writeInt32(this, value, offset, false, noAssert);
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
+ if (value < 0) value = 0xffffffff + value + 1;
+ writeUInt32(this, value, offset, false);
};
+
Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
- writeInt32(this, value, offset, true, noAssert);
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
+ if (value < 0) value = 0xffffffff + value + 1;
+ writeUInt32(this, value, offset, true);
};
-function writeFloat(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 3 < buffer.length,
- 'Trying to write beyond buffer length');
-
- verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38);
- }
-
- require('buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian,
- 23, 4);
-}
Buffer.prototype.writeFloatLE = function(value, offset, noAssert) {
- writeFloat(this, value, offset, false, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+ this.parent.writeFloatLE(value, this.offset + offset, !!noAssert);
};
+
Buffer.prototype.writeFloatBE = function(value, offset, noAssert) {
- writeFloat(this, value, offset, true, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+ this.parent.writeFloatBE(value, this.offset + offset, !!noAssert);
};
-function writeDouble(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 7 < buffer.length,
- 'Trying to write beyond buffer length');
-
- verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308);
- }
-
- require('buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian,
- 52, 8);
-}
Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) {
- writeDouble(this, value, offset, false, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 8, this.length);
+ this.parent.writeDoubleLE(value, this.offset + offset, !!noAssert);
};
+
Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) {
- writeDouble(this, value, offset, true, noAssert);
+ if (!noAssert)
+ checkOffset(offset, 8, this.length);
+ this.parent.writeDoubleBE(value, this.offset + offset, !!noAssert);
};
diff --git a/lib/buffer_ieee754.js b/lib/buffer_ieee754.js
deleted file mode 100644
index 943ce7acd..000000000
--- a/lib/buffer_ieee754.js
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2008, Fair Oaks Labs, 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 Fair Oaks Labs, 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.
-//
-//
-// Modifications to writeIEEE754 to support negative zeroes made by Brian White
-
-exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) {
- var e, m,
- eLen = nBytes * 8 - mLen - 1,
- eMax = (1 << eLen) - 1,
- eBias = eMax >> 1,
- nBits = -7,
- i = isBE ? 0 : (nBytes - 1),
- d = isBE ? 1 : -1,
- s = buffer[offset + i];
-
- i += d;
-
- e = s & ((1 << (-nBits)) - 1);
- s >>= (-nBits);
- nBits += eLen;
- for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
-
- m = e & ((1 << (-nBits)) - 1);
- e >>= (-nBits);
- nBits += mLen;
- for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
-
- if (e === 0) {
- e = 1 - eBias;
- } else if (e === eMax) {
- return m ? NaN : ((s ? -1 : 1) * Infinity);
- } else {
- m = m + Math.pow(2, mLen);
- e = e - eBias;
- }
- return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
-};
-
-exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) {
- var e, m, c,
- eLen = nBytes * 8 - mLen - 1,
- eMax = (1 << eLen) - 1,
- eBias = eMax >> 1,
- rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
- i = isBE ? (nBytes - 1) : 0,
- d = isBE ? -1 : 1,
- s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
-
- value = Math.abs(value);
-
- if (isNaN(value) || value === Infinity) {
- m = isNaN(value) ? 1 : 0;
- e = eMax;
- } else {
- e = Math.floor(Math.log(value) / Math.LN2);
- if (value * (c = Math.pow(2, -e)) < 1) {
- e--;
- c *= 2;
- }
- if (e + eBias >= 1) {
- value += rt / c;
- } else {
- value += rt * Math.pow(2, 1 - eBias);
- }
- if (value * c >= 2) {
- e++;
- c /= 2;
- }
-
- if (e + eBias >= eMax) {
- m = 0;
- e = eMax;
- } else if (e + eBias >= 1) {
- m = (value * c - 1) * Math.pow(2, mLen);
- e = e + eBias;
- } else {
- m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
- e = 0;
- }
- }
-
- for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);
-
- e = (e << mLen) | m;
- eLen += mLen;
- for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);
-
- buffer[offset + i - d] |= s * 128;
-};
diff --git a/lib/child_process.js b/lib/child_process.js
index 9b31586c4..4a9922e53 100644
--- a/lib/child_process.js
+++ b/lib/child_process.js
@@ -65,7 +65,6 @@ function createSocket(pipe, readable) {
if (readable) {
s.writable = false;
s.readable = true;
- s.resume();
} else {
s.writable = true;
s.readable = false;
@@ -109,29 +108,25 @@ var handleConversion = {
'net.Socket': {
send: function(message, socket) {
- // pause socket so no data is lost, will be resumed later
- socket.pause();
-
- // if the socket wsa created by net.Server
+ // if the socket was created by net.Server
if (socket.server) {
// the slave should keep track of the socket
message.key = socket.server._connectionKey;
var firstTime = !this._channel.sockets.send[message.key];
-
- // add socket to connections list
var socketList = getSocketList('send', this, message.key);
- socketList.add(socket);
// the server should no longer expose a .connection property
- // and when asked to close it should query the socket status from slaves
- if (firstTime) {
- socket.server._setupSlave(socketList);
- }
+ // and when asked to close it should query the socket status from
+ // the slaves
+ if (firstTime) socket.server._setupSlave(socketList);
+
+ // Act like socket is detached
+ socket.server._connections--;
}
// remove handle from socket object, it will be closed when the socket
- // has been send
+ // will be sent
var handle = socket._handle;
handle.onread = function() {};
socket._handle = null;
@@ -139,21 +134,38 @@ var handleConversion = {
return handle;
},
+ postSend: function(handle) {
+ // Close the Socket handle after sending it
+ handle.close();
+ },
+
got: function(message, handle, emit) {
var socket = new net.Socket({handle: handle});
socket.readable = socket.writable = true;
- socket.pause();
// if the socket was created by net.Server we will track the socket
if (message.key) {
// add socket to connections list
var socketList = getSocketList('got', this, message.key);
- socketList.add(socket);
+ socketList.add({
+ socket: socket
+ });
}
emit(socket);
- socket.resume();
+ }
+ },
+
+ 'dgram.Native': {
+ simultaneousAccepts: false,
+
+ send: function(message, handle) {
+ return handle;
+ },
+
+ got: function(message, handle, emit) {
+ emit(handle);
}
}
};
@@ -165,39 +177,47 @@ function SocketListSend(slave, key) {
var self = this;
this.key = key;
- this.list = [];
this.slave = slave;
-
- slave.once('disconnect', function() {
- self.flush();
- });
-
- this.slave.on('internalMessage', function(msg) {
- if (msg.cmd !== 'NODE_SOCKET_CLOSED' || msg.key !== self.key) return;
- self.flush();
- });
}
util.inherits(SocketListSend, EventEmitter);
-SocketListSend.prototype.add = function(socket) {
- this.list.push(socket);
-};
+SocketListSend.prototype._request = function(msg, cmd, callback) {
+ var self = this;
-SocketListSend.prototype.flush = function() {
- var list = this.list;
- this.list = [];
+ if (!this.slave.connected) return onclose();
+ this.slave.send(msg);
- list.forEach(function(socket) {
- socket.destroy();
- });
+ function onclose() {
+ self.slave.removeListener('internalMessage', onreply);
+ callback(new Error('Slave closed before reply'));
+ };
+
+ function onreply(msg) {
+ if (!(msg.cmd === cmd && msg.key === self.key)) return;
+ self.slave.removeListener('disconnect', onclose);
+ self.slave.removeListener('internalMessage', onreply);
+
+ callback(null, msg);
+ };
+
+ this.slave.once('disconnect', onclose);
+ this.slave.on('internalMessage', onreply);
};
-SocketListSend.prototype.update = function() {
- if (this.slave.connected === false) return;
+SocketListSend.prototype.close = function close(callback) {
+ this._request({
+ cmd: 'NODE_SOCKET_NOTIFY_CLOSE',
+ key: this.key
+ }, 'NODE_SOCKET_ALL_CLOSED', callback);
+};
- this.slave.send({
- cmd: 'NODE_SOCKET_FETCH',
+SocketListSend.prototype.getConnections = function getConnections(callback) {
+ this._request({
+ cmd: 'NODE_SOCKET_GET_COUNT',
key: this.key
+ }, 'NODE_SOCKET_COUNT', function(err, msg) {
+ if (err) return callback(err);
+ callback(null, msg.count);
});
};
@@ -207,45 +227,50 @@ function SocketListReceive(slave, key) {
var self = this;
+ this.connections = 0;
this.key = key;
- this.list = [];
this.slave = slave;
- slave.on('internalMessage', function(msg) {
- if (msg.cmd !== 'NODE_SOCKET_FETCH' || msg.key !== self.key) return;
+ function onempty() {
+ if (!self.slave.connected) return;
- if (self.list.length === 0) {
- self.flush();
- return;
- }
-
- self.on('itemRemoved', function removeMe() {
- if (self.list.length !== 0) return;
- self.removeListener('itemRemoved', removeMe);
- self.flush();
+ self.slave.send({
+ cmd: 'NODE_SOCKET_ALL_CLOSED',
+ key: self.key
});
+ }
+
+ this.slave.on('internalMessage', function(msg) {
+ if (msg.key !== self.key) return;
+
+ if (msg.cmd === 'NODE_SOCKET_NOTIFY_CLOSE') {
+ // Already empty
+ if (self.connections === 0) return onempty();
+
+ // Wait for sockets to get closed
+ self.once('empty', onempty);
+ } else if (msg.cmd === 'NODE_SOCKET_GET_COUNT') {
+ if (!self.slave.connected) return;
+ self.slave.send({
+ cmd: 'NODE_SOCKET_COUNT',
+ key: self.key,
+ count: self.connections
+ });
+ }
});
}
util.inherits(SocketListReceive, EventEmitter);
-SocketListReceive.prototype.flush = function() {
- this.list = [];
+SocketListReceive.prototype.add = function(obj) {
+ var self = this;
- if (this.slave.connected) {
- this.slave.send({
- cmd: 'NODE_SOCKET_CLOSED',
- key: this.key
- });
- }
-};
+ this.connections++;
-SocketListReceive.prototype.add = function(socket) {
- var self = this;
- this.list.push(socket);
+ // Notify previous owner of socket about its state change
+ obj.socket.once('close', function() {
+ self.connections--;
- socket.on('close', function() {
- self.list.splice(self.list.indexOf(socket), 1);
- self.emit('itemRemoved');
+ if (self.connections === 0) self.emit('empty');
});
};
@@ -342,18 +367,20 @@ function setupChannel(target, channel) {
// this message will be handled by an internalMessage event handler
message = {
cmd: 'NODE_HANDLE',
- type: 'net.',
msg: message
};
- switch (handle.constructor.name) {
- case 'Socket':
- message.type += 'Socket'; break;
- case 'Server':
- message.type += 'Server'; break;
- case 'Pipe':
- case 'TCP':
- message.type += 'Native'; break;
+ if (handle instanceof net.Socket) {
+ message.type = 'net.Socket';
+ } else if (handle instanceof net.Server) {
+ message.type = 'net.Server';
+ } else if (handle instanceof process.binding('tcp_wrap').TCP ||
+ handle instanceof process.binding('pipe_wrap').Pipe) {
+ message.type = 'net.Native';
+ } else if (handle instanceof process.binding('udp_wrap').UDP) {
+ message.type = 'dgram.Native';
+ } else {
+ throw new TypeError("This handle type can't be sent");
}
var obj = handleConversion[message.type];
@@ -370,17 +397,18 @@ function setupChannel(target, channel) {
var string = JSON.stringify(message) + '\n';
var writeReq = channel.writeUtf8String(string, handle);
- // Close the Socket handle after sending it
- if (message && message.type === 'net.Socket') {
- handle.close();
- }
-
if (!writeReq) {
- var er = errnoException(errno, 'write', 'cannot write to IPC channel.');
+ var er = errnoException(process._errno,
+ 'write',
+ 'cannot write to IPC channel.');
this.emit('error', er);
}
- writeReq.oncomplete = nop;
+ if (obj && obj.postSend) {
+ writeReq.oncomplete = obj.postSend.bind(null, handle);
+ } else {
+ writeReq.oncomplete = nop;
+ }
/* If the master is > 2 read() calls behind, please stop sending. */
return channel.writeQueueSize < (65536 * 2);
@@ -444,7 +472,9 @@ exports.fork = function(modulePath /*, args, options*/) {
options.stdio = options.silent ? ['pipe', 'pipe', 'pipe', 'ipc'] :
[0, 1, 2, 'ipc'];
- return spawn(process.execPath, args, options);
+ options.execPath = options.execPath || process.execPath;
+
+ return spawn(options.execPath, args, options);
};
@@ -452,7 +482,18 @@ exports._forkChild = function(fd) {
// set process.send()
var p = createPipe(true);
p.open(fd);
+ p.unref();
setupChannel(process, p);
+
+ var refs = 0;
+ process.on('newListener', function(name) {
+ if (name !== 'message' && name !== 'disconnect') return;
+ if (++refs === 1) p.ref();
+ });
+ process.on('removeListener', function(name) {
+ if (name !== 'message' && name !== 'disconnect') return;
+ if (--refs === 0) p.unref();
+ });
};
@@ -578,7 +619,7 @@ exports.execFile = function(file /* args, options, callback */) {
child.stdout.addListener('data', function(chunk) {
stdout += chunk;
if (stdout.length > options.maxBuffer) {
- err = new Error('maxBuffer exceeded.');
+ err = new Error('stdout maxBuffer exceeded.');
kill();
}
});
@@ -586,7 +627,7 @@ exports.execFile = function(file /* args, options, callback */) {
child.stderr.addListener('data', function(chunk) {
stderr += chunk;
if (stderr.length > options.maxBuffer) {
- err = new Error('maxBuffer exceeded.');
+ err = new Error('stderr maxBuffer exceeded.');
kill();
}
});
@@ -643,10 +684,15 @@ function maybeClose(subprocess) {
function ChildProcess() {
EventEmitter.call(this);
+ // Initialize TCPWrap and PipeWrap
+ process.binding('tcp_wrap');
+ process.binding('pipe_wrap');
+
var self = this;
this._closesNeeded = 1;
this._closesGot = 0;
+ this.connected = false;
this.signalCode = null;
this.exitCode = null;
@@ -662,6 +708,12 @@ function ChildProcess() {
// - normally terminated processes don't touch this.signalCode
// - signaled processes don't touch this.exitCode
//
+ // new in 0.9.x:
+ //
+ // - spawn failures are reported with exitCode == -1
+ //
+ var err = (exitCode == -1) ? errnoException(process._errno, 'spawn') : null;
+
if (signalCode) {
self.signalCode = signalCode;
} else {
@@ -675,7 +727,21 @@ function ChildProcess() {
self._handle.close();
self._handle = null;
- self.emit('exit', self.exitCode, self.signalCode);
+ if (exitCode == -1) {
+ self.emit('error', err);
+ } else {
+ self.emit('exit', self.exitCode, self.signalCode);
+ }
+
+ // if any of the stdio streams have not been touched,
+ // then pull all the data through so that it can get the
+ // eof and emit a 'close' event.
+ // Do it on nextTick so that the user has one last chance
+ // to consume the output, if for example they only want to
+ // start reading the data once the process exits.
+ process.nextTick(function() {
+ flushStdio(self);
+ });
maybeClose(self);
};
@@ -683,6 +749,17 @@ function ChildProcess() {
util.inherits(ChildProcess, EventEmitter);
+function flushStdio(subprocess) {
+ subprocess.stdio.forEach(function(stream, fd, stdio) {
+ if (!stream || !stream.readable || stream._consuming ||
+ stream._readableState.flowing)
+ return;
+ stream.resume();
+ });
+}
+
+
+
function getHandleWrapType(stream) {
if (stream instanceof handleWraps.Pipe) return 'pipe';
if (stream instanceof handleWraps.TTY) return 'tty';
@@ -791,7 +868,7 @@ ChildProcess.prototype.spawn = function(options) {
this._handle.close();
this._handle = null;
- throw errnoException(errno, 'spawn');
+ throw errnoException(process._errno, 'spawn');
}
this.pid = this._handle.pid;
@@ -876,14 +953,14 @@ ChildProcess.prototype.kill = function(sig) {
/* Success. */
this.killed = true;
return true;
- } else if (errno == 'ESRCH') {
+ } else if (process._errno == 'ESRCH') {
/* Already dead. */
- } else if (errno == 'EINVAL' || errno == 'ENOSYS') {
+ } else if (process._errno == 'EINVAL' || process._errno == 'ENOSYS') {
/* The underlying platform doesn't support this signal. */
- throw errnoException(errno, 'kill');
+ throw errnoException(process._errno, 'kill');
} else {
/* Other error, almost certainly EPERM. */
- this.emit('error', errnoException(errno, 'kill'));
+ this.emit('error', errnoException(process._errno, 'kill'));
}
}
diff --git a/lib/cluster.js b/lib/cluster.js
index 8f7df3e12..6c0f8f469 100644
--- a/lib/cluster.js
+++ b/lib/cluster.js
@@ -105,10 +105,31 @@ cluster.setupMaster = function(options) {
// Get filename and arguments
options = options || {};
+ // By default, V8 writes the profile data of all processes to a single
+ // v8.log.
+ //
+ // Running that log file through a tick processor produces bogus numbers
+ // because many events won't match up with the recorded memory mappings
+ // and you end up with graphs where 80+% of ticks is unaccounted for.
+ //
+ // Fixing the tick processor to deal with multi-process output is not very
+ // useful because the processes may be running wildly disparate workloads.
+ //
+ // That's why we fix up the command line arguments to include
+ // a "--logfile=v8-%p.log" argument (where %p is expanded to the PID)
+ // unless it already contains a --logfile argument.
+ var execArgv = options.execArgv || process.execArgv;
+ if (execArgv.some(function(s) { return /^--prof/.test(s); }) &&
+ !execArgv.some(function(s) { return /^--logfile=/.test(s); }))
+ {
+ execArgv = execArgv.slice();
+ execArgv.push('--logfile=v8-%p.log');
+ }
+
// Set settings object
settings = cluster.settings = {
exec: options.exec || process.argv[1],
- execArgv: options.execArgv || process.execArgv,
+ execArgv: execArgv,
args: options.args || process.argv.slice(2),
silent: options.silent || false
};
@@ -206,8 +227,14 @@ if (cluster.isMaster) {
if (serverHandlers.hasOwnProperty(key)) {
handler = serverHandlers[key];
+ } else if (message.addressType === 'udp4' ||
+ message.addressType === 'udp6') {
+ var dgram = require('dgram');
+ handler = dgram._createSocketHandle.apply(net, args);
+ serverHandlers[key] = handler;
} else {
- handler = serverHandlers[key] = net._createServerHandle.apply(net, args);
+ handler = net._createServerHandle.apply(net, args);
+ serverHandlers[key] = handler;
}
// echo callback with the fd handler associated with it
@@ -238,9 +265,9 @@ if (cluster.isMaster) {
messageHandler.suicide = function(message, worker) {
worker.suicide = true;
};
-
}
+
// Messages to a worker will be handled using these methods
else if (cluster.isWorker) {
@@ -520,7 +547,8 @@ cluster._setupWorker = function() {
sendInternalMessage(worker, { cmd: 'online' });
};
-// Internal function. Called by lib/net.js when attempting to bind a server.
+// Internal function. Called by net.js and dgram.js when attempting to bind a
+// TCP server or UDP socket.
cluster._getServer = function(tcpSelf, address, port, addressType, fd, cb) {
// This can only be called from a worker.
assert(cluster.isWorker);
@@ -535,7 +563,7 @@ cluster._getServer = function(tcpSelf, address, port, addressType, fd, cb) {
sendInternalMessage(cluster.worker, {
cmd: 'listening',
address: address,
- port: port,
+ port: tcpSelf.address().port || port,
addressType: addressType,
fd: fd
});
diff --git a/lib/console.js b/lib/console.js
index 64d21a426..51d5a36f9 100644
--- a/lib/console.js
+++ b/lib/console.js
@@ -21,57 +21,88 @@
var util = require('util');
-exports.log = function() {
- process.stdout.write(util.format.apply(this, arguments) + '\n');
+function Console(stdout, stderr) {
+ if (!(this instanceof Console)) {
+ return new Console(stdout, stderr);
+ }
+ if (!stdout || typeof stdout.write !== 'function') {
+ throw new TypeError('Console expects a writable stream instance');
+ }
+ if (!stderr) {
+ stderr = stdout;
+ }
+ var prop = {
+ writable: true,
+ enumerable: false,
+ configurable: true
+ };
+ prop.value = stdout;
+ Object.defineProperty(this, '_stdout', prop);
+ prop.value = stderr;
+ Object.defineProperty(this, '_stderr', prop);
+ prop.value = {};
+ Object.defineProperty(this, '_times', prop);
+
+ // bind the prototype functions to this Console instance
+ Object.keys(Console.prototype).forEach(function(k) {
+ this[k] = this[k].bind(this);
+ }, this);
+}
+
+Console.prototype.log = function() {
+ this._stdout.write(util.format.apply(this, arguments) + '\n');
};
-exports.info = exports.log;
+Console.prototype.info = Console.prototype.log;
-exports.warn = function() {
- process.stderr.write(util.format.apply(this, arguments) + '\n');
+Console.prototype.warn = function() {
+ this._stderr.write(util.format.apply(this, arguments) + '\n');
};
-exports.error = exports.warn;
+Console.prototype.error = Console.prototype.warn;
-exports.dir = function(object) {
- process.stdout.write(util.inspect(object) + '\n');
+Console.prototype.dir = function(object) {
+ this._stdout.write(util.inspect(object) + '\n');
};
-var times = {};
-exports.time = function(label) {
- times[label] = Date.now();
+Console.prototype.time = function(label) {
+ this._times[label] = Date.now();
};
-exports.timeEnd = function(label) {
- var time = times[label];
+Console.prototype.timeEnd = function(label) {
+ var time = this._times[label];
if (!time) {
throw new Error('No such label: ' + label);
}
var duration = Date.now() - time;
- exports.log('%s: %dms', label, duration);
+ this.log('%s: %dms', label, duration);
};
-exports.trace = function(label) {
+Console.prototype.trace = function() {
// TODO probably can to do this better with V8's debug object once that is
// exposed.
var err = new Error;
err.name = 'Trace';
- err.message = label || '';
+ err.message = util.format.apply(this, arguments);
Error.captureStackTrace(err, arguments.callee);
- console.error(err.stack);
+ this.error(err.stack);
};
-exports.assert = function(expression) {
+Console.prototype.assert = function(expression) {
if (!expression) {
var arr = Array.prototype.slice.call(arguments, 1);
require('assert').ok(false, util.format.apply(this, arr));
}
};
+
+
+module.exports = new Console(process.stdout, process.stderr);
+module.exports.Console = Console;
diff --git a/lib/crypto.js b/lib/crypto.js
index 67d9ab7cf..224c9da5d 100644
--- a/lib/crypto.js
+++ b/lib/crypto.js
@@ -19,27 +19,43 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
+// Note: In 0.8 and before, crypto functions all defaulted to using
+// binary-encoded strings rather than buffers.
+
+exports.DEFAULT_ENCODING = 'buffer';
try {
var binding = process.binding('crypto');
var SecureContext = binding.SecureContext;
- var Hmac = binding.Hmac;
- var Hash = binding.Hash;
- var Cipher = binding.Cipher;
- var Decipher = binding.Decipher;
- var Sign = binding.Sign;
- var Verify = binding.Verify;
- var DiffieHellman = binding.DiffieHellman;
- var DiffieHellmanGroup = binding.DiffieHellmanGroup;
- var PBKDF2 = binding.PBKDF2;
var randomBytes = binding.randomBytes;
var pseudoRandomBytes = binding.pseudoRandomBytes;
+ var getCiphers = binding.getCiphers;
+ var getHashes = binding.getHashes;
var crypto = true;
} catch (e) {
var crypto = false;
}
+var stream = require('stream');
+var util = require('util');
+
+// This is here because many functions accepted binary strings without
+// any explicit encoding in older versions of node, and we don't want
+// to break them unnecessarily.
+function toBuf(str, encoding) {
+ encoding = encoding || 'binary';
+ if (typeof str === 'string') {
+ if (encoding === 'buffer')
+ encoding = 'binary';
+ str = new Buffer(str, encoding);
+ }
+ return str;
+}
+
+
+var assert = require('assert');
+var StringDecoder = require('string_decoder').StringDecoder;
function Credentials(secureProtocol, flags, context) {
if (!(this instanceof Credentials)) {
@@ -116,10 +132,17 @@ exports.createCredentials = function(options, context) {
}
if (options.pfx) {
- if (options.passphrase) {
- c.context.loadPKCS12(options.pfx, options.passphrase);
+ var pfx = options.pfx;
+ var passphrase = options.passphrase;
+
+ pfx = toBuf(pfx);
+ if (passphrase)
+ passphrase = toBuf(passphrase);
+
+ if (passphrase) {
+ c.context.loadPKCS12(pfx, passphrase);
} else {
- c.context.loadPKCS12(options.pfx);
+ c.context.loadPKCS12(pfx);
}
}
@@ -127,69 +150,429 @@ exports.createCredentials = function(options, context) {
};
-exports.Hash = Hash;
-exports.createHash = function(hash) {
- return new Hash(hash);
+exports.createHash = exports.Hash = Hash;
+function Hash(algorithm, options) {
+ if (!(this instanceof Hash))
+ return new Hash(algorithm);
+ this._binding = new binding.Hash(algorithm);
+ stream.Transform.call(this, options);
+}
+
+util.inherits(Hash, stream.Transform);
+
+Hash.prototype._transform = function(chunk, output, callback) {
+ this._binding.update(chunk);
+ callback();
};
+Hash.prototype._flush = function(output, callback) {
+ output(this._binding.digest());
+ callback();
+};
-exports.Hmac = Hmac;
-exports.createHmac = function(hmac, key) {
- return (new Hmac).init(hmac, key);
+Hash.prototype.update = function(data, encoding) {
+ encoding = encoding || exports.DEFAULT_ENCODING;
+ data = toBuf(data, encoding);
+ this._binding.update(data);
+ return this;
};
-exports.Cipher = Cipher;
-exports.createCipher = function(cipher, password) {
- return (new Cipher).init(cipher, password);
+Hash.prototype.digest = function(outputEncoding) {
+ outputEncoding = outputEncoding || exports.DEFAULT_ENCODING;
+ var result = this._binding.digest();
+ if (outputEncoding && outputEncoding !== 'buffer')
+ result = result.toString(outputEncoding);
+ return result;
};
-exports.createCipheriv = function(cipher, key, iv) {
- return (new Cipher).initiv(cipher, key, iv);
+exports.createHmac = exports.Hmac = Hmac;
+
+function Hmac(hmac, key, options) {
+ if (!(this instanceof Hmac))
+ return new Hmac(hmac, key);
+ this._binding = new binding.Hmac();
+ this._binding.init(hmac, toBuf(key));
+ stream.Transform.call(this, options);
+}
+
+util.inherits(Hmac, stream.Transform);
+
+Hmac.prototype.update = Hash.prototype.update;
+Hmac.prototype.digest = Hash.prototype.digest;
+Hmac.prototype._flush = Hash.prototype._flush;
+Hmac.prototype._transform = Hash.prototype._transform;
+
+
+function getDecoder(decoder, encoding) {
+ decoder = decoder || new StringDecoder(encoding);
+ assert(decoder.encoding === encoding, 'Cannot change encoding');
+ return decoder;
+}
+
+
+exports.createCipher = exports.Cipher = Cipher;
+function Cipher(cipher, password, options) {
+ if (!(this instanceof Cipher))
+ return new Cipher(cipher, password);
+ this._binding = new binding.Cipher;
+
+ this._binding.init(cipher, toBuf(password));
+ this._decoder = null;
+
+ stream.Transform.call(this, options);
+}
+
+util.inherits(Cipher, stream.Transform);
+
+Cipher.prototype._transform = function(chunk, output, callback) {
+ output(this._binding.update(chunk));
+ callback();
};
+Cipher.prototype._flush = function(output, callback) {
+ output(this._binding.final());
+ callback();
+};
+
+Cipher.prototype.update = function(data, inputEncoding, outputEncoding) {
+ inputEncoding = inputEncoding || exports.DEFAULT_ENCODING;
+ outputEncoding = outputEncoding || exports.DEFAULT_ENCODING;
+ data = toBuf(data, inputEncoding);
+
+ var ret = this._binding.update(data);
+
+ if (outputEncoding && outputEncoding !== 'buffer') {
+ this._decoder = getDecoder(this._decoder, outputEncoding);
+ ret = this._decoder.write(ret);
+ }
+
+ return ret;
+};
+
+
+Cipher.prototype.final = function(outputEncoding) {
+ outputEncoding = outputEncoding || exports.DEFAULT_ENCODING;
+ var ret = this._binding.final();
-exports.Decipher = Decipher;
-exports.createDecipher = function(cipher, password) {
- return (new Decipher).init(cipher, password);
+ if (outputEncoding && outputEncoding !== 'buffer') {
+ this._decoder = getDecoder(this._decoder, outputEncoding);
+ ret = this._decoder.end(ret);
+ }
+
+ return ret;
};
-exports.createDecipheriv = function(cipher, key, iv) {
- return (new Decipher).initiv(cipher, key, iv);
+Cipher.prototype.setAutoPadding = function(ap) {
+ this._binding.setAutoPadding(ap);
+ return this;
};
-exports.Sign = Sign;
-exports.createSign = function(algorithm) {
- return (new Sign).init(algorithm);
+
+exports.createCipheriv = exports.Cipheriv = Cipheriv;
+function Cipheriv(cipher, key, iv, options) {
+ if (!(this instanceof Cipheriv))
+ return new Cipheriv(cipher, key, iv);
+ this._binding = new binding.Cipher();
+ this._binding.initiv(cipher, toBuf(key), toBuf(iv));
+ this._decoder = null;
+
+ stream.Transform.call(this, options);
+}
+
+util.inherits(Cipheriv, stream.Transform);
+
+Cipheriv.prototype._transform = Cipher.prototype._transform;
+Cipheriv.prototype._flush = Cipher.prototype._flush;
+Cipheriv.prototype.update = Cipher.prototype.update;
+Cipheriv.prototype.final = Cipher.prototype.final;
+Cipheriv.prototype.setAutoPadding = Cipher.prototype.setAutoPadding;
+
+
+
+exports.createDecipher = exports.Decipher = Decipher;
+function Decipher(cipher, password, options) {
+ if (!(this instanceof Decipher))
+ return new Decipher(cipher, password);
+
+ this._binding = new binding.Decipher;
+ this._binding.init(cipher, toBuf(password));
+ this._decoder = null;
+
+ stream.Transform.call(this, options);
+}
+
+util.inherits(Decipher, stream.Transform);
+
+Decipher.prototype._transform = Cipher.prototype._transform;
+Decipher.prototype._flush = Cipher.prototype._flush;
+Decipher.prototype.update = Cipher.prototype.update;
+Decipher.prototype.final = Cipher.prototype.final;
+Decipher.prototype.finaltol = Cipher.prototype.final;
+Decipher.prototype.setAutoPadding = Cipher.prototype.setAutoPadding;
+
+
+
+exports.createDecipheriv = exports.Decipheriv = Decipheriv;
+function Decipheriv(cipher, key, iv, options) {
+ if (!(this instanceof Decipheriv))
+ return new Decipheriv(cipher, key, iv);
+
+ this._binding = new binding.Decipher;
+ this._binding.initiv(cipher, toBuf(key), toBuf(iv));
+ this._decoder = null;
+
+ stream.Transform.call(this, options);
+}
+
+util.inherits(Decipheriv, stream.Transform);
+
+Decipheriv.prototype._transform = Cipher.prototype._transform;
+Decipheriv.prototype._flush = Cipher.prototype._flush;
+Decipheriv.prototype.update = Cipher.prototype.update;
+Decipheriv.prototype.final = Cipher.prototype.final;
+Decipheriv.prototype.finaltol = Cipher.prototype.final;
+Decipheriv.prototype.setAutoPadding = Cipher.prototype.setAutoPadding;
+
+
+
+exports.createSign = exports.Sign = Sign;
+function Sign(algorithm, options) {
+ if (!(this instanceof Sign))
+ return new Sign(algorithm);
+ this._binding = new binding.Sign();
+ this._binding.init(algorithm);
+
+ stream.Writable.call(this, options);
+}
+
+util.inherits(Sign, stream.Writable);
+
+Sign.prototype._write = function(chunk, callback) {
+ this._binding.update(chunk);
+ callback();
};
-exports.Verify = Verify;
-exports.createVerify = function(algorithm) {
- return (new Verify).init(algorithm);
+Sign.prototype.update = Hash.prototype.update;
+
+Sign.prototype.sign = function(key, encoding) {
+ encoding = encoding || exports.DEFAULT_ENCODING;
+ var ret = this._binding.sign(toBuf(key));
+
+ if (encoding && encoding !== 'buffer')
+ ret = ret.toString(encoding);
+
+ return ret;
};
-exports.DiffieHellman = DiffieHellman;
-exports.createDiffieHellman = function(size_or_key, enc) {
- if (!size_or_key) {
- return new DiffieHellman();
- } else if (!enc) {
- return new DiffieHellman(size_or_key);
- } else {
- return new DiffieHellman(size_or_key, enc);
+
+
+exports.createVerify = exports.Verify = Verify;
+function Verify(algorithm, options) {
+ if (!(this instanceof Verify))
+ return new Verify(algorithm);
+
+ this._binding = new binding.Verify;
+ this._binding.init(algorithm);
+
+ stream.Writable.call(this, options);
+}
+
+util.inherits(Verify, stream.Writable);
+
+Verify.prototype._write = Sign.prototype._write;
+Verify.prototype.update = Sign.prototype.update;
+
+Verify.prototype.verify = function(object, signature, sigEncoding) {
+ sigEncoding = sigEncoding || exports.DEFAULT_ENCODING;
+ return this._binding.verify(toBuf(object), toBuf(signature, sigEncoding));
+};
+
+
+
+exports.createDiffieHellman = exports.DiffieHellman = DiffieHellman;
+
+function DiffieHellman(sizeOrKey, encoding) {
+ if (!(this instanceof DiffieHellman))
+ return new DiffieHellman(sizeOrKey, encoding);
+
+ if (!sizeOrKey)
+ this._binding = new binding.DiffieHellman();
+ else {
+ encoding = encoding || exports.DEFAULT_ENCODING;
+ sizeOrKey = toBuf(sizeOrKey, encoding);
+ this._binding = new binding.DiffieHellman(sizeOrKey);
}
+}
+
+
+exports.DiffieHellmanGroup =
+ exports.createDiffieHellmanGroup =
+ exports.getDiffieHellman = DiffieHellmanGroup;
+
+function DiffieHellmanGroup(name) {
+ if (!(this instanceof DiffieHellmanGroup))
+ return new DiffieHellmanGroup(name);
+ this._binding = new binding.DiffieHellmanGroup(name);
+}
+
+
+DiffieHellmanGroup.prototype.generateKeys =
+ DiffieHellman.prototype.generateKeys =
+ dhGenerateKeys;
+
+function dhGenerateKeys(encoding) {
+ var keys = this._binding.generateKeys();
+ encoding = encoding || exports.DEFAULT_ENCODING;
+ if (encoding && encoding !== 'buffer')
+ keys = keys.toString(encoding);
+ return keys;
+}
+
+
+DiffieHellmanGroup.prototype.computeSecret =
+ DiffieHellman.prototype.computeSecret =
+ dhComputeSecret;
+
+function dhComputeSecret(key, inEnc, outEnc) {
+ inEnc = inEnc || exports.DEFAULT_ENCODING;
+ outEnc = outEnc || exports.DEFAULT_ENCODING;
+ var ret = this._binding.computeSecret(toBuf(key, inEnc));
+ if (outEnc && outEnc !== 'buffer')
+ ret = ret.toString(outEnc);
+ return ret;
+}
+
+
+DiffieHellmanGroup.prototype.getPrime =
+ DiffieHellman.prototype.getPrime =
+ dhGetPrime;
+
+function dhGetPrime(encoding) {
+ var prime = this._binding.getPrime();
+ encoding = encoding || exports.DEFAULT_ENCODING;
+ if (encoding && encoding !== 'buffer')
+ prime = prime.toString(encoding);
+ return prime;
+}
+
+
+DiffieHellmanGroup.prototype.getGenerator =
+ DiffieHellman.prototype.getGenerator =
+ dhGetGenerator;
+
+function dhGetGenerator(encoding) {
+ var generator = this._binding.getGenerator();
+ encoding = encoding || exports.DEFAULT_ENCODING;
+ if (encoding && encoding !== 'buffer')
+ generator = generator.toString(encoding);
+ return generator;
+}
+
+DiffieHellmanGroup.prototype.getPublicKey =
+ DiffieHellman.prototype.getPublicKey =
+ dhGetPublicKey;
+
+function dhGetPublicKey(encoding) {
+ var key = this._binding.getPublicKey();
+ encoding = encoding || exports.DEFAULT_ENCODING;
+ if (encoding && encoding !== 'buffer')
+ key = key.toString(encoding);
+ return key;
+}
+
+
+DiffieHellmanGroup.prototype.getPrivateKey =
+ DiffieHellman.prototype.getPrivateKey =
+ dhGetPrivateKey;
+
+function dhGetPrivateKey(encoding) {
+ var key = this._binding.getPrivateKey();
+ encoding = encoding || exports.DEFAULT_ENCODING;
+ if (encoding && encoding !== 'buffer')
+ key = key.toString(encoding);
+ return key;
+}
+
+
+DiffieHellman.prototype.setPublicKey = function(key, encoding) {
+ encoding = encoding || exports.DEFAULT_ENCODING;
+ this._binding.setPublicKey(toBuf(key, encoding));
+ return this;
};
-exports.getDiffieHellman = function(group_name) {
- return new DiffieHellmanGroup(group_name);
+
+
+DiffieHellman.prototype.setPrivateKey = function(key, encoding) {
+ encoding = encoding || exports.DEFAULT_ENCODING;
+ this._binding.setPrivateKey(toBuf(key, encoding));
+ return this;
+};
+
+
+
+exports.pbkdf2 = function(password, salt, iterations, keylen, callback) {
+ if (typeof callback !== 'function')
+ throw new Error('No callback provided to pbkdf2');
+
+ return pbkdf2(password, salt, iterations, keylen, callback);
+};
+
+
+exports.pbkdf2Sync = function(password, salt, iterations, keylen) {
+ return pbkdf2(password, salt, iterations, keylen);
};
-exports.pbkdf2 = PBKDF2;
+
+function pbkdf2(password, salt, iterations, keylen, callback) {
+ password = toBuf(password);
+ salt = toBuf(salt);
+
+ if (exports.DEFAULT_ENCODING === 'buffer')
+ return binding.PBKDF2(password, salt, iterations, keylen, callback);
+
+ // at this point, we need to handle encodings.
+ var encoding = exports.DEFAULT_ENCODING;
+ if (callback) {
+ binding.PBKDF2(password, salt, iterations, keylen, function(er, ret) {
+ if (ret)
+ ret = ret.toString(encoding);
+ callback(er, ret);
+ });
+ } else {
+ var ret = binding.PBKDF2(password, salt, iterations, keylen);
+ return ret.toString(encoding);
+ }
+}
+
+
exports.randomBytes = randomBytes;
exports.pseudoRandomBytes = pseudoRandomBytes;
exports.rng = randomBytes;
exports.prng = pseudoRandomBytes;
+
+
+exports.getCiphers = function() {
+ return getCiphers.call(null, arguments).sort();
+};
+
+
+exports.getHashes = function() {
+ var names = getHashes.call(null, arguments);
+
+ // Drop all-caps names in favor of their lowercase aliases,
+ // for example, 'sha1' instead of 'SHA1'.
+ var ctx = {};
+ names = names.forEach(function(name) {
+ if (/^[0-9A-Z\-]+$/.test(name)) name = name.toLowerCase();
+ ctx[name] = true;
+ });
+ names = Object.getOwnPropertyNames(ctx);
+
+ return names.sort();
+};
diff --git a/lib/dgram.js b/lib/dgram.js
index 88405dec9..91c224368 100644
--- a/lib/dgram.js
+++ b/lib/dgram.js
@@ -19,12 +19,18 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
+var assert = require('assert');
var util = require('util');
var events = require('events');
var UDP = process.binding('udp_wrap').UDP;
+var BIND_STATE_UNBOUND = 0;
+var BIND_STATE_BINDING = 1;
+var BIND_STATE_BOUND = 2;
+
// lazily loaded
+var cluster = null;
var dns = null;
var net = null;
@@ -43,11 +49,6 @@ function isIP(address) {
function lookup(address, family, callback) {
- // implicit 'bind before send' needs to run on the same tick
- var matchedFamily = isIP(address);
- if (matchedFamily)
- return callback(null, address, matchedFamily);
-
if (!dns)
dns = require('dns');
@@ -87,6 +88,24 @@ function newHandle(type) {
}
+exports._createSocketHandle = function(address, port, addressType, fd) {
+ // Opening an existing fd is not supported for UDP handles.
+ assert(typeof fd !== 'number' || fd < 0);
+
+ var handle = newHandle(addressType);
+
+ if (port || address) {
+ var r = handle.bind(address, port || 0, 0);
+ if (r == -1) {
+ handle.close();
+ handle = null;
+ }
+ }
+
+ return handle;
+};
+
+
function Socket(type, listener) {
events.EventEmitter.call(this);
@@ -95,7 +114,7 @@ function Socket(type, listener) {
this._handle = handle;
this._receiving = false;
- this._bound = false;
+ this._bindState = BIND_STATE_UNBOUND;
this.type = type;
this.fd = null; // compatibility hack
@@ -111,30 +130,73 @@ exports.createSocket = function(type, listener) {
};
-Socket.prototype.bind = function(port, address) {
+function startListening(socket) {
+ socket._handle.onmessage = onMessage;
+ // Todo: handle errors
+ socket._handle.recvStart();
+ socket._receiving = true;
+ socket._bindState = BIND_STATE_BOUND;
+ socket.fd = -42; // compatibility hack
+
+ socket.emit('listening');
+}
+
+
+Socket.prototype.bind = function(port, address, callback) {
var self = this;
self._healthCheck();
+ if (this._bindState != BIND_STATE_UNBOUND)
+ throw new Error('Socket is already bound');
+
+ this._bindState = BIND_STATE_BINDING;
+
+ if (typeof callback === 'function')
+ self.once('listening', callback);
+
// resolve address first
self._handle.lookup(address, function(err, ip) {
- if (!err) {
- if (self._handle.bind(ip, port || 0, /*flags=*/0)) {
- err = errnoException(errno, 'bind');
- }
- else {
- self._bound = true;
- self._startReceiving();
- self.emit('listening');
- }
+ if (err) {
+ self._bindState = BIND_STATE_UNBOUND;
+ self.emit('error', err);
+ return;
}
- if (err) {
- // caller may not have had a chance yet to register its
- // error event listener so defer the error to the next tick
- process.nextTick(function() {
- self.emit('error', err);
+ if (!cluster)
+ cluster = require('cluster');
+
+ if (cluster.isWorker) {
+ cluster._getServer(self, ip, port, self.type, -1, function(handle) {
+ if (!self._handle)
+ // handle has been closed in the mean time.
+ return handle.close();
+
+ // Set up the handle that we got from master.
+ handle.lookup = self._handle.lookup;
+ handle.bind = self._handle.bind;
+ handle.send = self._handle.send;
+ handle.owner = self;
+
+ // Replace the existing handle by the handle we got from master.
+ self._handle.close();
+ self._handle = handle;
+
+ startListening(self);
});
+
+ } else {
+ if (!self._handle)
+ return; // handle has been closed in the mean time
+
+ if (self._handle.bind(ip, port || 0, /*flags=*/ 0)) {
+ self.emit('error', errnoException(process._errno, 'bind'));
+ self._bindState = BIND_STATE_UNBOUND;
+ // Todo: close?
+ return;
+ }
+
+ startListening(self);
}
});
};
@@ -177,7 +239,27 @@ Socket.prototype.send = function(buffer,
callback = callback || noop;
self._healthCheck();
- self._startReceiving();
+
+ if (self._bindState == BIND_STATE_UNBOUND)
+ self.bind(0, null);
+
+ // If the socket hasn't been bound yet, push the outbound packet onto the
+ // send queue and send after binding is complete.
+ if (self._bindState != BIND_STATE_BOUND) {
+ // If the send queue hasn't been initialized yet, do it, and install an
+ // event handler that flushes the send queue after binding is done.
+ if (!self._sendQueue) {
+ self._sendQueue = [];
+ self.once('listening', function() {
+ // Flush the send queue.
+ for (var i = 0; i < self._sendQueue.length; i++)
+ self.send.apply(self, self._sendQueue[i]);
+ self._sendQueue = undefined;
+ });
+ }
+ self._sendQueue.push([buffer, offset, length, port, address, callback]);
+ return;
+ }
self._handle.lookup(address, function(err, ip) {
if (err) {
@@ -192,7 +274,7 @@ Socket.prototype.send = function(buffer,
}
else {
// don't emit as error, dgram_legacy.js compatibility
- var err = errnoException(errno, 'send');
+ var err = errnoException(process._errno, 'send');
process.nextTick(function() {
callback(err);
});
@@ -205,10 +287,6 @@ Socket.prototype.send = function(buffer,
function afterSend(status, handle, req, buffer) {
var self = handle.owner;
- // CHECKME socket's been closed by user, don't call callback?
- if (handle !== self._handle)
- void(0);
-
if (req.cb)
req.cb(null, buffer.length); // compatibility with dgram_legacy.js
}
@@ -228,7 +306,7 @@ Socket.prototype.address = function() {
var address = this._handle.getsockname();
if (!address)
- throw errnoException(errno, 'getsockname');
+ throw errnoException(process._errno, 'getsockname');
return address;
};
@@ -236,7 +314,7 @@ Socket.prototype.address = function() {
Socket.prototype.setBroadcast = function(arg) {
if (this._handle.setBroadcast((arg) ? 1 : 0)) {
- throw errnoException(errno, 'setBroadcast');
+ throw errnoException(process._errno, 'setBroadcast');
}
};
@@ -247,7 +325,7 @@ Socket.prototype.setTTL = function(arg) {
}
if (this._handle.setTTL(arg)) {
- throw errnoException(errno, 'setTTL');
+ throw errnoException(process._errno, 'setTTL');
}
return arg;
@@ -260,7 +338,7 @@ Socket.prototype.setMulticastTTL = function(arg) {
}
if (this._handle.setMulticastTTL(arg)) {
- throw errnoException(errno, 'setMulticastTTL');
+ throw errnoException(process._errno, 'setMulticastTTL');
}
return arg;
@@ -271,7 +349,7 @@ Socket.prototype.setMulticastLoopback = function(arg) {
arg = arg ? 1 : 0;
if (this._handle.setMulticastLoopback(arg)) {
- throw errnoException(errno, 'setMulticastLoopback');
+ throw errnoException(process._errno, 'setMulticastLoopback');
}
return arg; // 0.4 compatibility
@@ -287,7 +365,7 @@ Socket.prototype.addMembership = function(multicastAddress,
}
if (this._handle.addMembership(multicastAddress, interfaceAddress)) {
- throw new errnoException(errno, 'addMembership');
+ throw new errnoException(process._errno, 'addMembership');
}
};
@@ -301,7 +379,7 @@ Socket.prototype.dropMembership = function(multicastAddress,
}
if (this._handle.dropMembership(multicastAddress, interfaceAddress)) {
- throw new errnoException(errno, 'dropMembership');
+ throw new errnoException(process._errno, 'dropMembership');
}
};
@@ -312,34 +390,10 @@ Socket.prototype._healthCheck = function() {
};
-Socket.prototype._startReceiving = function() {
- if (this._receiving)
- return;
-
- if (!this._bound) {
- this.bind(); // bind to random port
-
- // sanity check
- if (!this._bound)
- throw new Error('implicit bind failed');
- }
-
- this._handle.onmessage = onMessage;
- this._handle.recvStart();
- this._receiving = true;
- this.fd = -42; // compatibility hack
-};
-
-
Socket.prototype._stopReceiving = function() {
if (!this._receiving)
return;
- // Black hole messages coming in when reading is stopped. Libuv might do
- // this, but node applications (e.g. test/simple/test-dgram-pingpong) may
- // not expect it.
- this._handle.onmessage = noop;
-
this._handle.recvStop();
this._receiving = false;
this.fd = null; // compatibility hack
@@ -348,12 +402,25 @@ Socket.prototype._stopReceiving = function() {
function onMessage(handle, slab, start, len, rinfo) {
var self = handle.owner;
- if (!slab) return self.emit('error', errnoException(errno, 'recvmsg'));
+ if (!slab) {
+ return self.emit('error', errnoException(process._errno, 'recvmsg'));
+ }
rinfo.size = len; // compatibility
self.emit('message', slab.slice(start, start + len), rinfo);
}
+Socket.prototype.ref = function() {
+ if (this._handle)
+ this._handle.ref();
+};
+
+
+Socket.prototype.unref = function() {
+ if (this._handle)
+ this._handle.unref();
+};
+
// TODO share with net_uv and others
function errnoException(errorno, syscall) {
var e = new Error(syscall + ' ' + errorno);
diff --git a/lib/dns.js b/lib/dns.js
index fb7a8138c..86b01ce71 100644
--- a/lib/dns.js
+++ b/lib/dns.js
@@ -121,14 +121,14 @@ exports.lookup = function(domain, family, callback) {
callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4);
}
} else {
- callback(errnoException(errno, 'getaddrinfo'));
+ callback(errnoException(process._errno, 'getaddrinfo'));
}
}
var wrap = cares.getaddrinfo(domain, family);
if (!wrap) {
- throw errnoException(errno, 'getaddrinfo');
+ throw errnoException(process._errno, 'getaddrinfo');
}
wrap.oncomplete = onanswer;
@@ -146,14 +146,14 @@ function resolver(bindingName) {
if (!status) {
callback(null, result);
} else {
- callback(errnoException(errno, bindingName));
+ callback(errnoException(process._errno, bindingName));
}
}
callback = makeAsync(callback);
var wrap = binding(name, onanswer);
if (!wrap) {
- throw errnoException(errno, bindingName);
+ throw errnoException(process._errno, bindingName);
}
callback.immediately = true;
diff --git a/lib/domain.js b/lib/domain.js
index fe71235e1..5d38177db 100644
--- a/lib/domain.js
+++ b/lib/domain.js
@@ -32,6 +32,10 @@ var endMethods = ['end', 'abort', 'destroy', 'destroySoon'];
// a few side effects.
events.usingDomains = true;
+// replace tickers with domain specific implementation
+process.nextTick = process._nextDomainTick;
+process._tickCallback = process._tickDomainCallback;
+
exports.Domain = Domain;
exports.create = exports.createDomain = function(cb) {
@@ -46,31 +50,10 @@ exports._stack = stack;
exports.active = null;
-// loading this file the first time sets up the global
-// uncaughtException handler.
-process.on('uncaughtException', uncaughtHandler);
-
-function uncaughtHandler(er) {
- // if there's an active domain, then handle this there.
- // Note that if this error emission throws, then it'll just crash.
- if (exports.active && !exports.active._disposed) {
- util._extend(er, {
- domain: exports.active,
- domain_thrown: true
- });
- exports.active.emit('error', er);
- if (exports.active) exports.active.exit();
- } else if (process.listeners('uncaughtException').length === 1) {
- // if there are other handlers, then they'll take care of it.
- // but if not, then we need to crash now.
- throw er;
- }
-}
-
inherits(Domain, EventEmitter);
function Domain() {
- EventEmitter.apply(this);
+ EventEmitter.call(this);
this.members = [];
}
@@ -161,8 +144,8 @@ Domain.prototype.bind = function(cb, interceptError) {
(arguments[0] instanceof Error)) {
var er = arguments[0];
util._extend(er, {
- domain_bound: cb,
- domain_thrown: false,
+ domainBound: cb,
+ domainThrown: false,
domain: self
});
self.emit('error', er);
diff --git a/lib/events.js b/lib/events.js
index 017df7504..223015ec6 100644
--- a/lib/events.js
+++ b/lib/events.js
@@ -44,15 +44,13 @@ exports.EventEmitter = EventEmitter;
// that to be increased. Set to zero for unlimited.
var defaultMaxListeners = 10;
EventEmitter.prototype.setMaxListeners = function(n) {
- if (!this._events) this._events = {};
this._maxListeners = n;
};
// non-global reference, for speed.
var PROCESS;
-EventEmitter.prototype.emit = function() {
- var type = arguments[0];
+EventEmitter.prototype.emit = function(type) {
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events || !this._events.error ||
@@ -60,9 +58,9 @@ EventEmitter.prototype.emit = function() {
{
if (this.domain) {
var er = arguments[1];
- er.domain_emitter = this;
+ er.domainEmitter = this;
er.domain = this.domain;
- er.domain_thrown = false;
+ er.domainThrown = false;
this.domain.emit('error', er);
return false;
}
@@ -142,10 +140,12 @@ EventEmitter.prototype.addListener = function(type, listener) {
if (!this._events) this._events = {};
- // To avoid recursion in the case that type == "newListeners"! Before
- // adding it to the listeners, first emit "newListeners".
- this.emit('newListener', type, typeof listener.listener === 'function' ?
- listener.listener : listener);
+ // To avoid recursion in the case that type == "newListener"! Before
+ // adding it to the listeners, first emit "newListener".
+ if (this._events.newListener) {
+ this.emit('newListener', type, typeof listener.listener === 'function' ?
+ listener.listener : listener);
+ }
if (!this._events[type]) {
// Optimize the case of one listener. Don't need the extra array object.
@@ -198,6 +198,7 @@ EventEmitter.prototype.once = function(type, listener) {
return this;
};
+// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function(type, listener) {
if ('function' !== typeof listener) {
throw new Error('removeListener only takes instances of Function');
@@ -222,32 +223,66 @@ EventEmitter.prototype.removeListener = function(type, listener) {
if (position < 0) return this;
list.splice(position, 1);
if (list.length == 0)
- delete this._events[type];
+ this._events[type] = null;
+
+ if (this._events.removeListener) {
+ this.emit('removeListener', type, listener);
+ }
} else if (list === listener ||
(list.listener && list.listener === listener))
{
- delete this._events[type];
+ this._events[type] = null;
+
+ if (this._events.removeListener) {
+ this.emit('removeListener', type, listener);
+ }
}
return this;
};
EventEmitter.prototype.removeAllListeners = function(type) {
+ if (!this._events) return this;
+
+ // fast path
+ if (!this._events.removeListener) {
+ if (arguments.length === 0) {
+ this._events = {};
+ } else if (type && this._events && this._events[type]) {
+ this._events[type] = null;
+ }
+ return this;
+ }
+
+ // slow(ish) path, emit 'removeListener' events for all removals
if (arguments.length === 0) {
+ for (var key in this._events) {
+ if (key === 'removeListener') continue;
+ this.removeAllListeners(key);
+ }
+ this.removeAllListeners('removeListener');
this._events = {};
return this;
}
- // does not use listeners(), so no side effect of creating _events[type]
- if (type && this._events && this._events[type]) this._events[type] = null;
+ var listeners = this._events[type];
+ if (isArray(listeners)) {
+ while (listeners.length) {
+ // LIFO order
+ this.removeListener(type, listeners[listeners.length - 1]);
+ }
+ } else if (listeners) {
+ this.removeListener(type, listeners);
+ }
+ this._events[type] = null;
+
return this;
};
EventEmitter.prototype.listeners = function(type) {
- if (!this._events) this._events = {};
- if (!this._events[type]) this._events[type] = [];
+ if (!this._events || !this._events[type]) return [];
if (!isArray(this._events[type])) {
- this._events[type] = [this._events[type]];
+ return [this._events[type]];
}
- return this._events[type];
+ return this._events[type].slice(0);
};
diff --git a/lib/fs.js b/lib/fs.js
index 5bbcf057c..8188f7170 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -34,8 +34,10 @@ var fs = exports;
var Stream = require('stream').Stream;
var EventEmitter = require('events').EventEmitter;
+var Readable = Stream.Readable;
+var Writable = Stream.Writable;
+
var kMinPoolSpace = 128;
-var kPoolSize = 40 * 1024;
var O_APPEND = constants.O_APPEND || 0;
var O_CREAT = constants.O_CREAT || 0;
@@ -52,6 +54,65 @@ var O_WRONLY = constants.O_WRONLY || 0;
var isWindows = process.platform === 'win32';
+var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
+
+function rethrow() {
+ // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
+ // is fairly slow to generate.
+ if (DEBUG) {
+ var backtrace = new Error;
+ return function(err) {
+ if (err) {
+ backtrace.message = err.message;
+ err = backtrace;
+ throw err;
+ }
+ };
+ }
+
+ return function(err) {
+ if (err) {
+ throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs
+ }
+ };
+}
+
+function maybeCallback(cb) {
+ return typeof cb === 'function' ? cb : rethrow();
+}
+
+// Ensure that callbacks run in the global context. Only use this function
+// for callbacks that are passed to the binding layer, callbacks that are
+// invoked from JS already run in the proper scope.
+function makeCallback(cb) {
+ if (typeof cb !== 'function') {
+ return rethrow();
+ }
+
+ return function() {
+ return cb.apply(null, arguments);
+ };
+}
+
+function assertEncoding(encoding) {
+ if (encoding && !Buffer.isEncoding(encoding)) {
+ throw new Error('Unknown encoding: ' + encoding);
+ }
+}
+
+function nullCheck(path, callback) {
+ if (('' + path).indexOf('\u0000') !== -1) {
+ var er = new Error('Path must be a string without null bytes.');
+ if (!callback)
+ throw er;
+ process.nextTick(function() {
+ callback(er);
+ });
+ return false;
+ }
+ return true;
+}
+
fs.Stats = binding.Stats;
fs.Stats.prototype._checkModeProperty = function(property) {
@@ -87,13 +148,16 @@ fs.Stats.prototype.isSocket = function() {
};
fs.exists = function(path, callback) {
- binding.stat(pathModule._makeLong(path), function(err, stats) {
+ if (!nullCheck(path, cb)) return;
+ binding.stat(pathModule._makeLong(path), cb);
+ function cb(err, stats) {
if (callback) callback(err ? false : true);
- });
+ }
};
fs.existsSync = function(path) {
try {
+ nullCheck(path);
binding.stat(pathModule._makeLong(path));
return true;
} catch (e) {
@@ -103,8 +167,9 @@ fs.existsSync = function(path) {
fs.readFile = function(path, encoding_) {
var encoding = typeof(encoding_) === 'string' ? encoding_ : null;
- var callback = arguments[arguments.length - 1];
- if (typeof(callback) !== 'function') callback = function() {};
+ var callback = maybeCallback(arguments[arguments.length - 1]);
+
+ assertEncoding(encoding);
// first, stat the file, so we know the size.
var size;
@@ -179,6 +244,8 @@ fs.readFile = function(path, encoding_) {
};
fs.readFileSync = function(path, encoding) {
+ assertEncoding(encoding);
+
var fd = fs.openSync(path, constants.O_RDONLY, 438 /*=0666*/);
var size;
@@ -284,21 +351,6 @@ Object.defineProperty(exports, '_stringToFlags', {
});
-// Ensure that callbacks run in the global context. Only use this function
-// for callbacks that are passed to the binding layer, callbacks that are
-// invoked from JS already run in the proper scope.
-function makeCallback(cb) {
- if (typeof cb !== 'function') {
- // faster than returning a ref to a global no-op function
- return function() {};
- }
-
- return function() {
- return cb.apply(null, arguments);
- };
-}
-
-
// Yes, the follow could be easily DRYed up but I provide the explicit
// list to make the arguments clear.
@@ -327,6 +379,7 @@ fs.open = function(path, flags, mode, callback) {
callback = makeCallback(arguments[arguments.length - 1]);
mode = modeNum(mode, 438 /*=0666*/);
+ if (!nullCheck(path, callback)) return;
binding.open(pathModule._makeLong(path),
stringToFlags(flags),
mode,
@@ -335,6 +388,7 @@ fs.open = function(path, flags, mode, callback) {
fs.openSync = function(path, flags, mode) {
mode = modeNum(mode, 438 /*=0666*/);
+ nullCheck(path);
return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
};
@@ -343,6 +397,9 @@ fs.read = function(fd, buffer, offset, length, position, callback) {
// legacy string interface (fd, length, position, encoding, callback)
var cb = arguments[4],
encoding = arguments[3];
+
+ assertEncoding(encoding);
+
position = arguments[2];
length = arguments[1];
buffer = new Buffer(length);
@@ -371,6 +428,9 @@ fs.readSync = function(fd, buffer, offset, length, position) {
// legacy string interface (fd, length, position, encoding, callback)
legacy = true;
var encoding = arguments[3];
+
+ assertEncoding(encoding);
+
position = arguments[2];
length = arguments[1];
buffer = new Buffer(length);
@@ -392,6 +452,7 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
// legacy string interface (fd, data, position, encoding, callback)
callback = arguments[4];
position = arguments[2];
+ assertEncoding(arguments[3]);
buffer = new Buffer('' + arguments[1], arguments[3]);
offset = 0;
@@ -407,9 +468,11 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
return;
}
+ callback = maybeCallback(callback);
+
function wrapper(err, written) {
// Retain a reference to buffer so that it can't be GC'ed too soon.
- callback && callback(err, written || 0, buffer);
+ callback(err, written || 0, buffer);
}
binding.write(fd, buffer, offset, length, position, wrapper);
@@ -419,6 +482,7 @@ fs.writeSync = function(fd, buffer, offset, length, position) {
if (!Buffer.isBuffer(buffer)) {
// legacy string interface (fd, data, position, encoding)
position = arguments[2];
+ assertEncoding(arguments[3]);
buffer = new Buffer('' + arguments[1], arguments[3]);
offset = 0;
@@ -430,29 +494,86 @@ fs.writeSync = function(fd, buffer, offset, length, position) {
};
fs.rename = function(oldPath, newPath, callback) {
+ callback = makeCallback(callback);
+ if (!nullCheck(oldPath, callback)) return;
+ if (!nullCheck(newPath, callback)) return;
binding.rename(pathModule._makeLong(oldPath),
pathModule._makeLong(newPath),
- makeCallback(callback));
+ callback);
};
fs.renameSync = function(oldPath, newPath) {
+ nullCheck(oldPath);
+ nullCheck(newPath);
return binding.rename(pathModule._makeLong(oldPath),
pathModule._makeLong(newPath));
};
-fs.truncate = function(fd, len, callback) {
- binding.truncate(fd, len, makeCallback(callback));
+fs.truncate = function(path, len, callback) {
+ if (typeof path === 'number') {
+ // legacy
+ return fs.ftruncate(path, len, callback);
+ }
+ if (typeof len === 'function') {
+ callback = len;
+ len = 0;
+ } else if (typeof len === 'undefined') {
+ len = 0;
+ }
+ callback = maybeCallback(callback);
+ fs.open(path, 'w', function(er, fd) {
+ if (er) return callback(er);
+ binding.ftruncate(fd, len, function(er) {
+ fs.close(fd, function(er2) {
+ callback(er || er2);
+ });
+ });
+ });
+};
+
+fs.truncateSync = function(path, len) {
+ if (typeof path === 'number') {
+ // legacy
+ return fs.ftruncateSync(path, len);
+ }
+ if (typeof len === 'undefined') {
+ len = 0;
+ }
+ // allow error to be thrown, but still close fd.
+ var fd = fs.openSync(path, 'w');
+ try {
+ var ret = fs.ftruncateSync(fd, len);
+ } finally {
+ fs.closeSync(fd);
+ }
+ return ret;
+};
+
+fs.ftruncate = function(fd, len, callback) {
+ if (typeof len === 'function') {
+ callback = len;
+ len = 0;
+ } else if (typeof len === 'undefined') {
+ len = 0;
+ }
+ binding.ftruncate(fd, len, makeCallback(callback));
};
-fs.truncateSync = function(fd, len) {
- return binding.truncate(fd, len);
+fs.ftruncateSync = function(fd, len) {
+ if (typeof len === 'undefined') {
+ len = 0;
+ }
+ return binding.ftruncate(fd, len);
};
fs.rmdir = function(path, callback) {
- binding.rmdir(pathModule._makeLong(path), makeCallback(callback));
+ callback = makeCallback(callback);
+ if (!nullCheck(path, callback)) return;
+ binding.rmdir(pathModule._makeLong(path), callback);
};
fs.rmdirSync = function(path) {
+ nullCheck(path);
return binding.rmdir(pathModule._makeLong(path));
};
@@ -474,29 +595,27 @@ fs.fsyncSync = function(fd) {
fs.mkdir = function(path, mode, callback) {
if (typeof mode === 'function') callback = mode;
+ callback = makeCallback(callback);
+ if (!nullCheck(path, callback)) return;
binding.mkdir(pathModule._makeLong(path),
modeNum(mode, 511 /*=0777*/),
- makeCallback(callback));
+ callback);
};
fs.mkdirSync = function(path, mode) {
+ nullCheck(path);
return binding.mkdir(pathModule._makeLong(path),
modeNum(mode, 511 /*=0777*/));
};
-fs.sendfile = function(outFd, inFd, inOffset, length, callback) {
- binding.sendfile(outFd, inFd, inOffset, length, makeCallback(callback));
-};
-
-fs.sendfileSync = function(outFd, inFd, inOffset, length) {
- return binding.sendfile(outFd, inFd, inOffset, length);
-};
-
fs.readdir = function(path, callback) {
- binding.readdir(pathModule._makeLong(path), makeCallback(callback));
+ callback = makeCallback(callback);
+ if (!nullCheck(path, callback)) return;
+ binding.readdir(pathModule._makeLong(path), callback);
};
fs.readdirSync = function(path) {
+ nullCheck(path);
return binding.readdir(pathModule._makeLong(path));
};
@@ -505,11 +624,15 @@ fs.fstat = function(fd, callback) {
};
fs.lstat = function(path, callback) {
- binding.lstat(pathModule._makeLong(path), makeCallback(callback));
+ callback = makeCallback(callback);
+ if (!nullCheck(path, callback)) return;
+ binding.lstat(pathModule._makeLong(path), callback);
};
fs.stat = function(path, callback) {
- binding.stat(pathModule._makeLong(path), makeCallback(callback));
+ callback = makeCallback(callback);
+ if (!nullCheck(path, callback)) return;
+ binding.stat(pathModule._makeLong(path), callback);
};
fs.fstatSync = function(fd) {
@@ -517,18 +640,23 @@ fs.fstatSync = function(fd) {
};
fs.lstatSync = function(path) {
+ nullCheck(path);
return binding.lstat(pathModule._makeLong(path));
};
fs.statSync = function(path) {
+ nullCheck(path);
return binding.stat(pathModule._makeLong(path));
};
fs.readlink = function(path, callback) {
- binding.readlink(pathModule._makeLong(path), makeCallback(callback));
+ callback = makeCallback(callback);
+ if (!nullCheck(path, callback)) return;
+ binding.readlink(pathModule._makeLong(path), callback);
};
fs.readlinkSync = function(path) {
+ nullCheck(path);
return binding.readlink(pathModule._makeLong(path));
};
@@ -549,6 +677,9 @@ fs.symlink = function(destination, path, type_, callback) {
var type = (typeof type_ === 'string' ? type_ : null);
var callback = makeCallback(arguments[arguments.length - 1]);
+ if (!nullCheck(destination, callback)) return;
+ if (!nullCheck(path, callback)) return;
+
binding.symlink(preprocessSymlinkDestination(destination, type),
pathModule._makeLong(path),
type,
@@ -558,27 +689,39 @@ fs.symlink = function(destination, path, type_, callback) {
fs.symlinkSync = function(destination, path, type) {
type = (typeof type === 'string' ? type : null);
+ nullCheck(destination);
+ nullCheck(path);
+
return binding.symlink(preprocessSymlinkDestination(destination, type),
pathModule._makeLong(path),
type);
};
fs.link = function(srcpath, dstpath, callback) {
+ callback = makeCallback(callback);
+ if (!nullCheck(srcpath, callback)) return;
+ if (!nullCheck(dstpath, callback)) return;
+
binding.link(pathModule._makeLong(srcpath),
pathModule._makeLong(dstpath),
- makeCallback(callback));
+ callback);
};
fs.linkSync = function(srcpath, dstpath) {
+ nullCheck(srcpath);
+ nullCheck(dstpath);
return binding.link(pathModule._makeLong(srcpath),
pathModule._makeLong(dstpath));
};
fs.unlink = function(path, callback) {
- binding.unlink(pathModule._makeLong(path), makeCallback(callback));
+ callback = makeCallback(callback);
+ if (!nullCheck(path, callback)) return;
+ binding.unlink(pathModule._makeLong(path), callback);
};
fs.unlinkSync = function(path) {
+ nullCheck(path);
return binding.unlink(pathModule._makeLong(path));
};
@@ -592,7 +735,7 @@ fs.fchmodSync = function(fd, mode) {
if (constants.hasOwnProperty('O_SYMLINK')) {
fs.lchmod = function(path, mode, callback) {
- callback = callback || (function() {});
+ callback = maybeCallback(callback);
fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) {
if (err) {
callback(err);
@@ -631,18 +774,21 @@ if (constants.hasOwnProperty('O_SYMLINK')) {
fs.chmod = function(path, mode, callback) {
+ callback = makeCallback(callback);
+ if (!nullCheck(path, callback)) return;
binding.chmod(pathModule._makeLong(path),
modeNum(mode),
- makeCallback(callback));
+ callback);
};
fs.chmodSync = function(path, mode) {
+ nullCheck(path);
return binding.chmod(pathModule._makeLong(path), modeNum(mode));
};
if (constants.hasOwnProperty('O_SYMLINK')) {
fs.lchown = function(path, uid, gid, callback) {
- callback = callback || (function() {});
+ callback = maybeCallback(callback);
fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) {
if (err) {
callback(err);
@@ -667,10 +813,13 @@ fs.fchownSync = function(fd, uid, gid) {
};
fs.chown = function(path, uid, gid, callback) {
- binding.chown(pathModule._makeLong(path), uid, gid, makeCallback(callback));
+ callback = makeCallback(callback);
+ if (!nullCheck(path, callback)) return;
+ binding.chown(pathModule._makeLong(path), uid, gid, callback);
};
fs.chownSync = function(path, uid, gid) {
+ nullCheck(path);
return binding.chown(pathModule._makeLong(path), uid, gid);
};
@@ -690,13 +839,16 @@ function toUnixTimestamp(time) {
fs._toUnixTimestamp = toUnixTimestamp;
fs.utimes = function(path, atime, mtime, callback) {
+ callback = makeCallback(callback);
+ if (!nullCheck(path, callback)) return;
binding.utimes(pathModule._makeLong(path),
toUnixTimestamp(atime),
toUnixTimestamp(mtime),
- makeCallback(callback));
+ callback);
};
fs.utimesSync = function(path, atime, mtime) {
+ nullCheck(path);
atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime);
binding.utimes(pathModule._makeLong(path), atime, mtime);
@@ -715,8 +867,7 @@ fs.futimesSync = function(fd, atime, mtime) {
};
function writeAll(fd, buffer, offset, length, position, callback) {
- var callback_ = arguments[arguments.length - 1];
- callback = (typeof(callback_) == 'function' ? callback_ : null);
+ callback = maybeCallback(arguments[arguments.length - 1]);
// write(fd, buffer, offset, length, position, callback)
fs.write(fd, buffer, offset, length, position, function(writeErr, written) {
@@ -739,8 +890,9 @@ function writeAll(fd, buffer, offset, length, position, callback) {
fs.writeFile = function(path, data, encoding_, callback) {
var encoding = (typeof(encoding_) == 'string' ? encoding_ : 'utf8');
- var callback_ = arguments[arguments.length - 1];
- callback = (typeof(callback_) == 'function' ? callback_ : null);
+ assertEncoding(encoding);
+
+ callback = maybeCallback(arguments[arguments.length - 1]);
fs.open(path, 'w', 438 /*=0666*/, function(openErr, fd) {
if (openErr) {
if (callback) callback(openErr);
@@ -753,6 +905,8 @@ fs.writeFile = function(path, data, encoding_, callback) {
};
fs.writeFileSync = function(path, data, encoding) {
+ assertEncoding(encoding);
+
var fd = fs.openSync(path, 'w');
if (!Buffer.isBuffer(data)) {
data = new Buffer('' + data, encoding || 'utf8');
@@ -770,8 +924,9 @@ fs.writeFileSync = function(path, data, encoding) {
fs.appendFile = function(path, data, encoding_, callback) {
var encoding = (typeof(encoding_) == 'string' ? encoding_ : 'utf8');
- var callback_ = arguments[arguments.length - 1];
- callback = (typeof(callback_) == 'function' ? callback_ : null);
+ assertEncoding(encoding);
+
+ callback = maybeCallback(arguments[arguments.length - 1]);
fs.open(path, 'a', 438 /*=0666*/, function(err, fd) {
if (err) return callback(err);
@@ -781,6 +936,8 @@ fs.appendFile = function(path, data, encoding_, callback) {
};
fs.appendFileSync = function(path, data, encoding) {
+ assertEncoding(encoding);
+
var fd = fs.openSync(path, 'a');
if (!Buffer.isBuffer(data)) {
data = new Buffer('' + data, encoding || 'utf8');
@@ -821,7 +978,7 @@ function FSWatcher() {
this._handle.onchange = function(status, event, filename) {
if (status) {
self._handle.close();
- self.emit('error', errnoException(errno, 'watch'));
+ self.emit('error', errnoException(process._errno, 'watch'));
} else {
self.emit('change', event, filename);
}
@@ -830,11 +987,12 @@ function FSWatcher() {
util.inherits(FSWatcher, EventEmitter);
FSWatcher.prototype.start = function(filename, persistent) {
+ nullCheck(filename);
var r = this._handle.start(pathModule._makeLong(filename), persistent);
if (r) {
this._handle.close();
- throw errnoException(errno, 'watch');
+ throw errnoException(process._errno, 'watch');
}
};
@@ -843,6 +1001,7 @@ FSWatcher.prototype.close = function() {
};
fs.watch = function(filename) {
+ nullCheck(filename);
var watcher;
var options;
var listener;
@@ -897,6 +1056,7 @@ util.inherits(StatWatcher, EventEmitter);
StatWatcher.prototype.start = function(filename, persistent, interval) {
+ nullCheck(filename);
this._handle.start(pathModule._makeLong(filename), persistent, interval);
};
@@ -914,6 +1074,7 @@ function inStatWatchers(filename) {
fs.watchFile = function(filename) {
+ nullCheck(filename);
var stat;
var listener;
@@ -947,6 +1108,7 @@ fs.watchFile = function(filename) {
};
fs.unwatchFile = function(filename, listener) {
+ nullCheck(filename);
if (!inStatWatchers(filename)) return;
var stat = statWatchers[filename];
@@ -1083,7 +1245,7 @@ fs.realpathSync = function realpathSync(p, cache) {
fs.realpath = function realpath(p, cache, cb) {
if (typeof cb !== 'function') {
- cb = cache;
+ cb = maybeCallback(cache);
cache = null;
}
@@ -1207,8 +1369,8 @@ fs.realpath = function realpath(p, cache, cb) {
var pool;
-function allocNewPool() {
- pool = new Buffer(kPoolSize);
+function allocNewPool(poolSize) {
+ pool = new Buffer(poolSize);
pool.used = 0;
}
@@ -1218,32 +1380,31 @@ fs.createReadStream = function(path, options) {
return new ReadStream(path, options);
};
-var ReadStream = fs.ReadStream = function(path, options) {
- if (!(this instanceof ReadStream)) return new ReadStream(path, options);
+util.inherits(ReadStream, Readable);
+fs.ReadStream = ReadStream;
- Stream.call(this);
+function ReadStream(path, options) {
+ if (!(this instanceof ReadStream))
+ return new ReadStream(path, options);
- var self = this;
-
- this.path = path;
- this.fd = null;
- this.readable = true;
- this.paused = false;
+ // a little bit bigger buffer and water marks by default
+ options = util._extend({
+ bufferSize: 64 * 1024,
+ highWaterMark: 64 * 1024
+ }, options || {});
- this.flags = 'r';
- this.mode = 438; /*=0666*/
- this.bufferSize = 64 * 1024;
+ Readable.call(this, options);
- options = options || {};
-
- // Mixin options into this
- var keys = Object.keys(options);
- for (var index = 0, length = keys.length; index < length; index++) {
- var key = keys[index];
- this[key] = options[key];
- }
+ this.path = path;
+ this.fd = options.hasOwnProperty('fd') ? options.fd : null;
+ this.flags = options.hasOwnProperty('flags') ? options.flags : 'r';
+ this.mode = options.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/
- if (this.encoding) this.setEncoding(this.encoding);
+ this.start = options.hasOwnProperty('start') ? options.start : undefined;
+ this.end = options.hasOwnProperty('end') ? options.end : undefined;
+ this.autoClose = options.hasOwnProperty('autoClose') ?
+ options.autoClose : true;
+ this.pos = undefined;
if (this.start !== undefined) {
if ('number' !== typeof this.start) {
@@ -1262,192 +1423,155 @@ var ReadStream = fs.ReadStream = function(path, options) {
this.pos = this.start;
}
- if (this.fd !== null) {
- process.nextTick(function() {
- self._read();
- });
- return;
- }
+ if (typeof this.fd !== 'number')
+ this.open();
- fs.open(this.path, this.flags, this.mode, function(err, fd) {
- if (err) {
- self.emit('error', err);
- self.readable = false;
+ this.on('end', function() {
+ if (this.autoClose) {
+ this.destroy();
+ }
+ });
+}
+
+fs.FileReadStream = fs.ReadStream; // support the legacy name
+
+ReadStream.prototype.open = function() {
+ var self = this;
+ fs.open(this.path, this.flags, this.mode, function(er, fd) {
+ if (er) {
+ if (this.autoClose) {
+ self.destroy();
+ }
+ self.emit('error', er);
return;
}
self.fd = fd;
self.emit('open', fd);
- self._read();
+ // start the flow of data.
+ self.read();
});
};
-util.inherits(ReadStream, Stream);
-fs.FileReadStream = fs.ReadStream; // support the legacy name
-
-ReadStream.prototype.setEncoding = function(encoding) {
- var StringDecoder = require('string_decoder').StringDecoder; // lazy load
- this._decoder = new StringDecoder(encoding);
-};
-
-
-ReadStream.prototype._read = function() {
- var self = this;
- if (!this.readable || this.paused || this.reading) return;
+ReadStream.prototype._read = function(n, cb) {
+ if (typeof this.fd !== 'number')
+ return this.once('open', function() {
+ this._read(n, cb);
+ });
- this.reading = true;
+ if (this.destroyed)
+ return;
if (!pool || pool.length - pool.used < kMinPoolSpace) {
// discard the old pool. Can't add to the free list because
// users might have refernces to slices on it.
pool = null;
- allocNewPool();
+ allocNewPool(this._readableState.bufferSize);
}
- // Grab another reference to the pool in the case that while we're in the
- // thread pool another read() finishes up the pool, and allocates a new
- // one.
+ // Grab another reference to the pool in the case that while we're
+ // in the thread pool another read() finishes up the pool, and
+ // allocates a new one.
var thisPool = pool;
- var toRead = Math.min(pool.length - pool.used, ~~this.bufferSize);
+ var toRead = Math.min(pool.length - pool.used, n);
var start = pool.used;
- if (this.pos !== undefined) {
+ if (this.pos !== undefined)
toRead = Math.min(this.end - this.pos + 1, toRead);
- }
- function afterRead(err, bytesRead) {
- self.reading = false;
- if (err) {
- fs.close(self.fd, function() {
- self.fd = null;
- self.emit('error', err);
- self.readable = false;
- });
- return;
- }
+ // already read everything we were supposed to read!
+ // treat as EOF.
+ if (toRead <= 0)
+ return cb();
- if (bytesRead === 0) {
- self.emit('end');
- self.destroy();
- return;
- }
-
- var b = thisPool.slice(start, start + bytesRead);
+ // the actual read.
+ var self = this;
+ fs.read(this.fd, pool, pool.used, toRead, this.pos, onread);
- // Possible optimizition here?
- // Reclaim some bytes if bytesRead < toRead?
- // Would need to ensure that pool === thisPool.
+ // move the pool positions, and internal position for reading.
+ if (this.pos !== undefined)
+ this.pos += toRead;
+ pool.used += toRead;
- // do not emit events if the stream is paused
- if (self.paused) {
- self.buffer = b;
- return;
+ function onread(er, bytesRead) {
+ if (er) {
+ if (self.autoClose) {
+ self.destroy();
+ }
+ return cb(er);
}
- // do not emit events anymore after we declared the stream unreadable
- if (!self.readable) return;
-
- self._emitData(b);
- self._read();
- }
-
- fs.read(this.fd, pool, pool.used, toRead, this.pos, afterRead);
+ var b = null;
+ if (bytesRead > 0)
+ b = thisPool.slice(start, start + bytesRead);
- if (this.pos !== undefined) {
- this.pos += toRead;
+ cb(null, b);
}
- pool.used += toRead;
};
-ReadStream.prototype._emitData = function(d) {
- if (this._decoder) {
- var string = this._decoder.write(d);
- if (string.length) this.emit('data', string);
- } else {
- this.emit('data', d);
- }
+ReadStream.prototype.destroy = function() {
+ if (this.destroyed)
+ return;
+ this.destroyed = true;
+
+ if ('number' === typeof this.fd)
+ this.close();
};
-ReadStream.prototype.destroy = function(cb) {
+ReadStream.prototype.close = function(cb) {
var self = this;
-
- if (!this.readable) {
- if (cb) process.nextTick(function() { cb(null); });
- return;
+ if (cb)
+ this.once('close', cb);
+ if (this.closed || 'number' !== typeof this.fd) {
+ if ('number' !== typeof this.fd) {
+ this.once('open', close);
+ return;
+ }
+ return process.nextTick(this.emit.bind(this, 'close'));
}
- this.readable = false;
-
- function close() {
- fs.close(self.fd, function(err) {
- if (err) {
- if (cb) cb(err);
- self.emit('error', err);
- return;
- }
+ this.closed = true;
+ close();
- if (cb) cb(null);
- self.emit('close');
+ function close(fd) {
+ fs.close(fd || self.fd, function(er) {
+ if (er)
+ self.emit('error', er);
+ else
+ self.emit('close');
});
- }
-
- if (this.fd === null) {
- this.addListener('open', close);
- } else {
- close();
+ self.fd = null;
}
};
-ReadStream.prototype.pause = function() {
- this.paused = true;
-};
-
-
-ReadStream.prototype.resume = function() {
- this.paused = false;
-
- if (this.buffer) {
- var buffer = this.buffer;
- this.buffer = null;
- this._emitData(buffer);
- }
-
- // hasn't opened yet.
- if (null == this.fd) return;
-
- this._read();
-};
-
fs.createWriteStream = function(path, options) {
return new WriteStream(path, options);
};
-var WriteStream = fs.WriteStream = function(path, options) {
- if (!(this instanceof WriteStream)) return new WriteStream(path, options);
+util.inherits(WriteStream, Writable);
+fs.WriteStream = WriteStream;
+function WriteStream(path, options) {
+ if (!(this instanceof WriteStream))
+ return new WriteStream(path, options);
- Stream.call(this);
+ options = options || {};
+
+ Writable.call(this, options);
this.path = path;
this.fd = null;
- this.writable = true;
- this.flags = 'w';
- this.encoding = 'binary';
- this.mode = 438; /*=0666*/
- this.bytesWritten = 0;
-
- options = options || {};
+ this.fd = options.hasOwnProperty('fd') ? options.fd : null;
+ this.flags = options.hasOwnProperty('flags') ? options.flags : 'w';
+ this.mode = options.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/
- // Mixin options into this
- var keys = Object.keys(options);
- for (var index = 0, length = keys.length; index < length; index++) {
- var key = keys[index];
- this[key] = options[key];
- }
+ this.start = options.hasOwnProperty('start') ? options.start : undefined;
+ this.pos = undefined;
+ this.bytesWritten = 0;
if (this.start !== undefined) {
if ('number' !== typeof this.start) {
@@ -1460,159 +1584,54 @@ var WriteStream = fs.WriteStream = function(path, options) {
this.pos = this.start;
}
- this.busy = false;
- this._queue = [];
+ if ('number' !== typeof this.fd)
+ this.open();
- if (this.fd === null) {
- this._open = fs.open;
- this._queue.push([this._open, this.path, this.flags, this.mode, undefined]);
- this.flush();
- }
-};
-util.inherits(WriteStream, Stream);
+ // dispose on finish.
+ this.once('finish', this.close);
+}
fs.FileWriteStream = fs.WriteStream; // support the legacy name
-WriteStream.prototype.flush = function() {
- if (this.busy) return;
- var self = this;
-
- var args = this._queue.shift();
- if (!args) {
- if (this.drainable) { this.emit('drain'); }
- return;
- }
-
- this.busy = true;
-
- var method = args.shift(),
- cb = args.pop();
-
- args.push(function(err) {
- self.busy = false;
-
- if (err) {
- self.writable = false;
-
- function emit() {
- self.fd = null;
- if (cb) cb(err);
- self.emit('error', err);
- }
-
- if (self.fd === null) {
- emit();
- } else {
- fs.close(self.fd, emit);
- }
-
- return;
- }
-
- if (method == fs.write) {
- self.bytesWritten += arguments[1];
- if (cb) {
- // write callback
- cb(null, arguments[1]);
- }
-
- } else if (method === self._open) {
- // save reference for file pointer
- self.fd = arguments[1];
- self.emit('open', self.fd);
- } else if (method === fs.close) {
- // stop flushing after close
- if (cb) {
- cb(null);
- }
- self.emit('close');
+WriteStream.prototype.open = function() {
+ fs.open(this.path, this.flags, this.mode, function(er, fd) {
+ if (er) {
+ this.destroy();
+ this.emit('error', er);
return;
}
- self.flush();
- });
-
- // Inject the file pointer
- if (method !== self._open) {
- args.unshift(this.fd);
- }
-
- method.apply(this, args);
+ this.fd = fd;
+ this.emit('open', fd);
+ }.bind(this));
};
-WriteStream.prototype.write = function(data) {
- if (!this.writable) {
- this.emit('error', new Error('stream not writable'));
- return false;
- }
- this.drainable = true;
+WriteStream.prototype._write = function(data, cb) {
+ if (!Buffer.isBuffer(data))
+ return this.emit('error', new Error('Invalid data'));
- var cb;
- if (typeof(arguments[arguments.length - 1]) == 'function') {
- cb = arguments[arguments.length - 1];
- }
+ if (typeof this.fd !== 'number')
+ return this.once('open', this._write.bind(this, data, cb));
- if (!Buffer.isBuffer(data)) {
- var encoding = 'utf8';
- if (typeof(arguments[1]) == 'string') encoding = arguments[1];
- data = new Buffer('' + data, encoding);
- }
-
- this._queue.push([fs.write, data, 0, data.length, this.pos, cb]);
+ var self = this;
+ fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) {
+ if (er) {
+ self.destroy();
+ return cb(er);
+ }
+ self.bytesWritten += bytes;
+ cb();
+ });
- if (this.pos !== undefined) {
+ if (this.pos !== undefined)
this.pos += data.length;
- }
-
- this.flush();
-
- return false;
};
-WriteStream.prototype.end = function(data, encoding, cb) {
- if (typeof(data) === 'function') {
- cb = data;
- } else if (typeof(encoding) === 'function') {
- cb = encoding;
- this.write(data);
- } else if (arguments.length > 0) {
- this.write(data, encoding);
- }
- this.writable = false;
- this._queue.push([fs.close, cb]);
- this.flush();
-};
-
-WriteStream.prototype.destroy = function(cb) {
- var self = this;
- if (!this.writable) {
- if (cb) process.nextTick(function() { cb(null); });
- return;
- }
- this.writable = false;
-
- function close() {
- fs.close(self.fd, function(err) {
- if (err) {
- if (cb) { cb(err); }
- self.emit('error', err);
- return;
- }
-
- if (cb) { cb(null); }
- self.emit('close');
- });
- }
-
- if (this.fd === null) {
- this.addListener('open', close);
- } else {
- close();
- }
-};
+WriteStream.prototype.destroy = ReadStream.prototype.destroy;
+WriteStream.prototype.close = ReadStream.prototype.close;
// There is no shutdown() for files.
WriteStream.prototype.destroySoon = WriteStream.prototype.end;
@@ -1649,6 +1668,7 @@ SyncWriteStream.prototype.write = function(data, arg1, arg2) {
throw new Error('bad arg');
}
}
+ assertEncoding(encoding);
// Change strings to buffers. SLOW
if (typeof data == 'string') {
diff --git a/lib/http.js b/lib/http.js
index 212b8becb..e5c709da0 100644
--- a/lib/http.js
+++ b/lib/http.js
@@ -27,8 +27,6 @@ var EventEmitter = require('events').EventEmitter;
var FreeList = require('freelist').FreeList;
var HTTPParser = process.binding('http_parser').HTTPParser;
var assert = require('assert').ok;
-var END_OF_FILE = {};
-
var debug;
if (process.env.NODE_DEBUG && /http/.test(process.env.NODE_DEBUG)) {
@@ -37,6 +35,16 @@ if (process.env.NODE_DEBUG && /http/.test(process.env.NODE_DEBUG)) {
debug = function() { };
}
+function readStart(socket) {
+ if (!socket || !socket._handle || !socket._handle.readStart) return;
+ socket._handle.readStart();
+}
+
+function readStop(socket) {
+ if (!socket || !socket._handle || !socket._handle.readStop) return;
+ socket._handle.readStop();
+}
+
// Only called in the slow case where slow means
// that the request headers were either fragmented
// across multiple TCP packets or too large to be
@@ -114,45 +122,58 @@ function parserOnHeadersComplete(info) {
return skipBody;
}
+// XXX This is a mess.
+// TODO: http.Parser should be a Writable emits request/response events.
function parserOnBody(b, start, len) {
var parser = this;
- var slice = b.slice(start, start + len);
- if (parser.incoming._paused || parser.incoming._pendings.length) {
- parser.incoming._pendings.push(slice);
- } else {
- parser.incoming._emitData(slice);
+ var stream = parser.incoming;
+
+ // if the stream has already been removed, then drop it.
+ if (!stream)
+ return;
+
+ var socket = stream.socket;
+
+ // pretend this was the result of a stream._read call.
+ if (len > 0 && !stream._dumped) {
+ var slice = b.slice(start, start + len);
+ var ret = stream.push(slice);
+ if (!ret)
+ readStop(socket);
}
}
function parserOnMessageComplete() {
var parser = this;
- parser.incoming.complete = true;
-
- // Emit any trailing headers.
- var headers = parser._headers;
- if (headers) {
- for (var i = 0, n = headers.length; i < n; i += 2) {
- var k = headers[i];
- var v = headers[i + 1];
- parser.incoming._addHeaderLine(k, v);
+ var stream = parser.incoming;
+
+ if (stream) {
+ stream.complete = true;
+ // Emit any trailing headers.
+ var headers = parser._headers;
+ if (headers) {
+ for (var i = 0, n = headers.length; i < n; i += 2) {
+ var k = headers[i];
+ var v = headers[i + 1];
+ parser.incoming._addHeaderLine(k, v);
+ }
+ parser._headers = [];
+ parser._url = '';
}
- parser._headers = [];
- parser._url = '';
+
+ if (!stream.upgrade)
+ // For upgraded connections, also emit this after parser.execute
+ stream.push(null);
}
- if (!parser.incoming.upgrade) {
- // For upgraded connections, also emit this after parser.execute
- if (parser.incoming._paused || parser.incoming._pendings.length) {
- parser.incoming._pendings.push(END_OF_FILE);
- } else {
- parser.incoming.readable = false;
- parser.incoming._emitEnd();
- }
+ if (stream && !parser.incoming._pendings.length) {
+ // For emit end event
+ stream.push(null);
}
if (parser.socket.readable) {
// force to read the next incoming message
- parser.socket.resume();
+ readStart(parser.socket);
}
}
@@ -230,7 +251,7 @@ var STATUS_CODES = exports.STATUS_CODES = {
502 : 'Bad Gateway',
503 : 'Service Unavailable',
504 : 'Gateway Time-out',
- 505 : 'HTTP Version not supported',
+ 505 : 'HTTP Version Not Supported',
506 : 'Variant Also Negotiates', // RFC 2295
507 : 'Insufficient Storage', // RFC 4918
509 : 'Bandwidth Limit Exceeded',
@@ -263,9 +284,12 @@ function utcDate() {
/* Abstract base class for ServerRequest and ClientResponse. */
function IncomingMessage(socket) {
- Stream.call(this);
+ Stream.Readable.call(this);
+
+ // XXX This implementation is kind of all over the place
+ // When the parser emits body chunks, they go in this list.
+ // _read() pulls them out, and when it finds EOF, it ends.
- // TODO Remove one of these eventually.
this.socket = socket;
this.connection = socket;
@@ -276,97 +300,50 @@ function IncomingMessage(socket) {
this.readable = true;
- this._paused = false;
this._pendings = [];
-
- this._endEmitted = false;
+ this._pendingIndex = 0;
// request (server) only
this.url = '';
-
this.method = null;
// response (client) only
this.statusCode = null;
this.client = this.socket;
-}
-util.inherits(IncomingMessage, Stream);
-
-exports.IncomingMessage = IncomingMessage;
-
-
-IncomingMessage.prototype.destroy = function(error) {
- this.socket.destroy(error);
-};
-
-
-IncomingMessage.prototype.setEncoding = function(encoding) {
- var StringDecoder = require('string_decoder').StringDecoder; // lazy load
- this._decoder = new StringDecoder(encoding);
-};
-
-
-IncomingMessage.prototype.pause = function() {
- this._paused = true;
- this.socket.pause();
-};
+ // flag for backwards compatibility grossness.
+ this._consuming = false;
+ // flag for when we decide that this message cannot possibly be
+ // read by the user, so there's no point continuing to handle it.
+ this._dumped = false;
+}
+util.inherits(IncomingMessage, Stream.Readable);
-IncomingMessage.prototype.resume = function() {
- this._paused = false;
- if (this.socket) {
- this.socket.resume();
- }
-
- this._emitPending();
-};
+exports.IncomingMessage = IncomingMessage;
-IncomingMessage.prototype._emitPending = function(callback) {
- if (this._pendings.length) {
- var self = this;
- process.nextTick(function() {
- while (!self._paused && self._pendings.length) {
- var chunk = self._pendings.shift();
- if (chunk !== END_OF_FILE) {
- assert(Buffer.isBuffer(chunk));
- self._emitData(chunk);
- } else {
- assert(self._pendings.length === 0);
- self.readable = false;
- self._emitEnd();
- }
- }
- if (callback) {
- callback();
- }
- });
- } else if (callback) {
- callback();
- }
+IncomingMessage.prototype.read = function(n) {
+ this._consuming = true;
+ this.read = Stream.Readable.prototype.read;
+ return this.read(n);
};
-IncomingMessage.prototype._emitData = function(d) {
- if (this._decoder) {
- var string = this._decoder.write(d);
- if (string.length) {
- this.emit('data', string);
- }
- } else {
- this.emit('data', d);
- }
+IncomingMessage.prototype._read = function(n, callback) {
+ // We actually do almost nothing here, because the parserOnBody
+ // function fills up our internal buffer directly. However, we
+ // do need to unpause the underlying socket so that it flows.
+ if (!this.socket.readable)
+ return callback(null, null);
+ else
+ readStart(this.socket);
};
-IncomingMessage.prototype._emitEnd = function() {
- if (!this._endEmitted) {
- this.emit('end');
- }
-
- this._endEmitted = true;
+IncomingMessage.prototype.destroy = function(error) {
+ this.socket.destroy(error);
};
@@ -384,7 +361,7 @@ IncomingMessage.prototype._addHeaderLine = function(field, value) {
switch (field) {
// Array headers:
case 'set-cookie':
- if (field in dest) {
+ if (dest[field] !== undefined) {
dest[field].push(value);
} else {
dest[field] = [value];
@@ -404,7 +381,7 @@ IncomingMessage.prototype._addHeaderLine = function(field, value) {
case 'proxy-authenticate':
case 'sec-websocket-extensions':
case 'sec-websocket-protocol':
- if (field in dest) {
+ if (dest[field] !== undefined) {
dest[field] += ', ' + value;
} else {
dest[field] = value;
@@ -415,20 +392,33 @@ IncomingMessage.prototype._addHeaderLine = function(field, value) {
default:
if (field.slice(0, 2) == 'x-') {
// except for x-
- if (field in dest) {
+ if (dest[field] !== undefined) {
dest[field] += ', ' + value;
} else {
dest[field] = value;
}
} else {
// drop duplicates
- if (!(field in dest)) dest[field] = value;
+ if (dest[field] === undefined) dest[field] = value;
}
break;
}
};
+// Call this instead of resume() if we want to just
+// dump all the data to /dev/null
+IncomingMessage.prototype._dump = function() {
+ if (this._dumped)
+ return;
+
+ this._dumped = true;
+ this.socket.parser.incoming = null;
+ this.push(null);
+ readStart(this.socket);
+};
+
+
function OutgoingMessage() {
Stream.call(this);
@@ -556,47 +546,20 @@ OutgoingMessage.prototype._buffer = function(data, encoding) {
OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {
- var sentConnectionHeader = false;
- var sentContentLengthHeader = false;
- var sentTransferEncodingHeader = false;
- var sentDateHeader = false;
- var sentExpect = false;
-
// firstLine in the case of request is: 'GET /index.html HTTP/1.1\r\n'
// in the case of response it is: 'HTTP/1.1 200 OK\r\n'
- var messageHeader = firstLine;
+ var state = {
+ sentConnectionHeader: false,
+ sentContentLengthHeader: false,
+ sentTransferEncodingHeader: false,
+ sentDateHeader: false,
+ sentExpect: false,
+ messageHeader: firstLine
+ };
+
var field, value;
var self = this;
- function store(field, value) {
- // Protect against response splitting. The if statement is there to
- // minimize the performance impact in the common case.
- if (/[\r\n]/.test(value))
- value = value.replace(/[\r\n]+[ \t]*/g, '');
-
- messageHeader += field + ': ' + value + CRLF;
-
- if (connectionExpression.test(field)) {
- sentConnectionHeader = true;
- if (closeExpression.test(value)) {
- self._last = true;
- } else {
- self.shouldKeepAlive = true;
- }
-
- } else if (transferEncodingExpression.test(field)) {
- sentTransferEncodingHeader = true;
- if (chunkExpression.test(value)) self.chunkedEncoding = true;
-
- } else if (contentLengthExpression.test(field)) {
- sentContentLengthHeader = true;
- } else if (dateExpression.test(field)) {
- sentDateHeader = true;
- } else if (expectExpression.test(field)) {
- sentExpect = true;
- }
- }
-
if (headers) {
var keys = Object.keys(headers);
var isArray = (Array.isArray(headers));
@@ -614,37 +577,58 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {
if (Array.isArray(value)) {
for (var j = 0; j < value.length; j++) {
- store(field, value[j]);
+ storeHeader(this, state, field, value[j]);
}
} else {
- store(field, value);
+ storeHeader(this, state, field, value);
}
}
}
// Date header
- if (this.sendDate == true && sentDateHeader == false) {
- messageHeader += 'Date: ' + utcDate() + CRLF;
+ if (this.sendDate == true && state.sentDateHeader == false) {
+ state.messageHeader += 'Date: ' + utcDate() + CRLF;
+ }
+
+ // Force the connection to close when the response is a 204 No Content or
+ // a 304 Not Modified and the user has set a "Transfer-Encoding: chunked"
+ // header.
+ //
+ // RFC 2616 mandates that 204 and 304 responses MUST NOT have a body but
+ // node.js used to send out a zero chunk anyway to accommodate clients
+ // that don't have special handling for those responses.
+ //
+ // It was pointed out that this might confuse reverse proxies to the point
+ // of creating security liabilities, so suppress the zero chunk and force
+ // the connection to close.
+ var statusCode = this.statusCode;
+ if ((statusCode == 204 || statusCode === 304) &&
+ this.chunkedEncoding === true) {
+ debug(statusCode + ' response should not use chunked encoding,' +
+ ' closing connection.');
+ this.chunkedEncoding = false;
+ this.shouldKeepAlive = false;
}
// keep-alive logic
- if (sentConnectionHeader === false) {
+ if (state.sentConnectionHeader === false) {
var shouldSendKeepAlive = this.shouldKeepAlive &&
- (sentContentLengthHeader ||
+ (state.sentContentLengthHeader ||
this.useChunkedEncodingByDefault ||
this.agent);
if (shouldSendKeepAlive) {
- messageHeader += 'Connection: keep-alive\r\n';
+ state.messageHeader += 'Connection: keep-alive\r\n';
} else {
this._last = true;
- messageHeader += 'Connection: close\r\n';
+ state.messageHeader += 'Connection: close\r\n';
}
}
- if (sentContentLengthHeader == false && sentTransferEncodingHeader == false) {
+ if (state.sentContentLengthHeader == false &&
+ state.sentTransferEncodingHeader == false) {
if (this._hasBody) {
if (this.useChunkedEncodingByDefault) {
- messageHeader += 'Transfer-Encoding: chunked\r\n';
+ state.messageHeader += 'Transfer-Encoding: chunked\r\n';
this.chunkedEncoding = true;
} else {
this._last = true;
@@ -655,14 +639,43 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {
}
}
- this._header = messageHeader + CRLF;
+ this._header = state.messageHeader + CRLF;
this._headerSent = false;
// wait until the first body chunk, or close(), is sent to flush,
// UNLESS we're sending Expect: 100-continue.
- if (sentExpect) this._send('');
+ if (state.sentExpect) this._send('');
};
+function storeHeader(self, state, field, value) {
+ // Protect against response splitting. The if statement is there to
+ // minimize the performance impact in the common case.
+ if (/[\r\n]/.test(value))
+ value = value.replace(/[\r\n]+[ \t]*/g, '');
+
+ state.messageHeader += field + ': ' + value + CRLF;
+
+ if (connectionExpression.test(field)) {
+ state.sentConnectionHeader = true;
+ if (closeExpression.test(value)) {
+ self._last = true;
+ } else {
+ self.shouldKeepAlive = true;
+ }
+
+ } else if (transferEncodingExpression.test(field)) {
+ state.sentTransferEncodingHeader = true;
+ if (chunkExpression.test(value)) self.chunkedEncoding = true;
+
+ } else if (contentLengthExpression.test(field)) {
+ state.sentContentLengthHeader = true;
+ } else if (dateExpression.test(field)) {
+ state.sentDateHeader = true;
+ } else if (expectExpression.test(field)) {
+ state.sentExpect = true;
+ }
+}
+
OutgoingMessage.prototype.setHeader = function(name, value) {
if (arguments.length < 2) {
@@ -727,6 +740,12 @@ OutgoingMessage.prototype._renderHeaders = function() {
};
+Object.defineProperty(OutgoingMessage.prototype, 'headersSent', {
+ configurable: true,
+ enumerable: true,
+ get: function() { return !!this._header; }
+});
+
OutgoingMessage.prototype.write = function(chunk, encoding) {
if (!this._header) {
@@ -921,9 +940,11 @@ OutgoingMessage.prototype._finish = function() {
assert(this.connection);
if (this instanceof ServerResponse) {
DTRACE_HTTP_SERVER_RESPONSE(this.connection);
+ COUNTER_HTTP_SERVER_RESPONSE();
} else {
assert(this instanceof ClientRequest);
DTRACE_HTTP_CLIENT_REQUEST(this, this.connection);
+ COUNTER_HTTP_CLIENT_REQUEST();
}
this.emit('finish');
};
@@ -1064,7 +1085,7 @@ ServerResponse.prototype.writeHead = function(statusCode) {
var field;
for (var i = 0, len = obj.length; i < len; ++i) {
field = obj[i][0];
- if (field in headers) {
+ if (headers[field] !== undefined) {
obj.push([field, headers[field]]);
}
}
@@ -1106,7 +1127,7 @@ ServerResponse.prototype.writeHead = function(statusCode) {
// don't keep alive connections where the client expects 100 Continue
// but we sent a final status; they may put extra bytes on the wire.
- if (this._expect_continue && ! this._sent100) {
+ if (this._expect_continue && !this._sent100) {
this.shouldKeepAlive = false;
}
@@ -1412,11 +1433,10 @@ function socketCloseListener() {
// Socket closed before we emitted 'end' below.
req.res.emit('aborted');
var res = req.res;
- req.res._emitPending(function() {
- res._emitEnd();
+ res.on('end', function() {
res.emit('close');
- res = null;
});
+ res.push(null);
} else if (!req.res && !req._hadError) {
// This socket error fired before we started to
// receive a response. The error needs to
@@ -1528,11 +1548,13 @@ function socketOnData(d, start, end) {
}
+// client
function parserOnIncomingClient(res, shouldKeepAlive) {
var parser = this;
var socket = this.socket;
var req = socket._httpMessage;
+
// propogate "domain" setting...
if (req.domain && !res.domain) {
debug('setting "res.domain"');
@@ -1579,15 +1601,22 @@ function parserOnIncomingClient(res, shouldKeepAlive) {
DTRACE_HTTP_CLIENT_RESPONSE(socket, req);
- req.emit('response', res);
+ COUNTER_HTTP_CLIENT_RESPONSE();
req.res = res;
res.req = req;
-
+ var handled = req.emit('response', res);
res.on('end', responseOnEnd);
+ // If the user did not listen for the 'response' event, then they
+ // can't possibly read the data, so we ._dump() it into the void
+ // so that the socket doesn't hang there in a paused state.
+ if (!handled)
+ res._dump();
+
return isHeadResponse;
}
+// client
function responseOnEnd() {
var res = this;
var req = res.req;
@@ -1759,6 +1788,10 @@ function Server(requestListener) {
this.httpAllowHalfOpen = false;
this.addListener('connection', connectionListener);
+
+ this.addListener('clientError', function(err, conn) {
+ conn.destroy(err);
+ });
}
util.inherits(Server, net.Server);
@@ -1818,7 +1851,7 @@ function connectionListener(socket) {
}
socket.addListener('error', function(e) {
- self.emit('clientError', e);
+ self.emit('clientError', e, this);
});
socket.ondata = function(d, start, end) {
@@ -1880,9 +1913,10 @@ function connectionListener(socket) {
incoming.push(req);
var res = new ServerResponse(req);
- debug('server response shouldKeepAlive: ' + shouldKeepAlive);
+
res.shouldKeepAlive = shouldKeepAlive;
DTRACE_HTTP_SERVER_REQUEST(req, socket);
+ COUNTER_HTTP_SERVER_REQUEST();
if (socket._httpMessage) {
// There are already pending outgoing res, append.
@@ -1901,6 +1935,12 @@ function connectionListener(socket) {
incoming.shift();
+ // if the user never called req.read(), and didn't pipe() or
+ // .resume() or .on('data'), then we call req._dump() so that the
+ // bytes will be pulled off the wire.
+ if (!req._consuming)
+ req._dump();
+
res.detachSocket(socket);
if (res._last) {
@@ -1914,7 +1954,7 @@ function connectionListener(socket) {
}
});
- if ('expect' in req.headers &&
+ if (req.headers.expect !== undefined &&
(req.httpVersionMajor == 1 && req.httpVersionMinor == 1) &&
continueExpression.test(req.headers['expect'])) {
res._expect_continue = true;
@@ -1968,6 +2008,11 @@ Client.prototype.request = function(method, path, headers) {
// but it will get removed when we remove this legacy interface.
c.on('socket', function(s) {
s.on('end', function() {
+ if (self._decoder) {
+ var ret = self._decoder.end();
+ if (ret)
+ self.emit('data', ret);
+ }
self.emit('end');
});
});
diff --git a/lib/https.js b/lib/https.js
index a243b2bc2..000590a76 100644
--- a/lib/https.js
+++ b/lib/https.js
@@ -21,6 +21,7 @@
var tls = require('tls');
var http = require('http');
+var util = require('util');
var url = require('url');
var inherits = require('util').inherits;
@@ -38,6 +39,10 @@ function Server(opts, requestListener) {
if (requestListener) {
this.addListener('request', requestListener);
}
+
+ this.addListener('clientError', function(err, conn) {
+ conn.destroy(err);
+ });
}
inherits(Server, tls.Server);
@@ -52,26 +57,25 @@ exports.createServer = function(opts, requestListener) {
// HTTPS agents.
-function createConnection(/* [port, host, options] */) {
- var options = {};
-
- if (typeof arguments[0] === 'object') {
- options = arguments[0];
- } else if (typeof arguments[1] === 'object') {
- options = arguments[1];
- options.port = arguments[0];
- } else if (typeof arguments[2] === 'object') {
- options = arguments[2];
- options.port = arguments[0];
- options.host = arguments[1];
+function createConnection(port, host, options) {
+ if (typeof port === 'object') {
+ options = port;
+ } else if (typeof host === 'object') {
+ options = host;
+ } else if (typeof options === 'object') {
+ options = options;
} else {
- if (typeof arguments[0] === 'number') {
- options.port = arguments[0];
- }
- if (typeof arguments[1] === 'string') {
- options.host = arguments[1];
- }
+ options = {};
+ }
+
+ if (typeof port === 'number') {
+ options.port = port;
}
+
+ if (typeof host === 'string') {
+ options.host = host;
+ }
+
return tls.connect(options);
}
@@ -97,11 +101,25 @@ exports.request = function(options, cb) {
throw new Error('Protocol:' + options.protocol + ' not supported.');
}
- if (options.agent === undefined) {
- options.agent = globalAgent;
+ options = util._extend({
+ createConnection: createConnection,
+ defaultPort: 443
+ }, options);
+
+ if (typeof options.agent === 'undefined') {
+ if (typeof options.ca === 'undefined' &&
+ typeof options.cert === 'undefined' &&
+ typeof options.ciphers === 'undefined' &&
+ typeof options.key === 'undefined' &&
+ typeof options.passphrase === 'undefined' &&
+ typeof options.pfx === 'undefined' &&
+ typeof options.rejectUnauthorized === 'undefined') {
+ options.agent = globalAgent;
+ } else {
+ options.agent = new Agent(options);
+ }
}
- options.createConnection = createConnection;
- options.defaultPort = options.defaultPort || 443;
+
return new http.ClientRequest(options, cb);
};
diff --git a/lib/module.js b/lib/module.js
index 613039474..27bba73ac 100644
--- a/lib/module.js
+++ b/lib/module.js
@@ -359,6 +359,8 @@ Module.prototype.load = function(filename) {
Module.prototype.require = function(path) {
+ assert(typeof path === 'string', 'path must be a string');
+ assert(path, 'missing path');
return Module._load(path, this);
};
@@ -437,7 +439,12 @@ Module.prototype._compile = function(content, filename) {
var compiledWrapper = runInThisContext(wrapper, filename, true);
if (global.v8debug) {
if (!resolvedArgv) {
- resolvedArgv = Module._resolveFilename(process.argv[1], null);
+ // we enter the repl if we're not given a filename argument.
+ if (process.argv[1]) {
+ resolvedArgv = Module._resolveFilename(process.argv[1], null);
+ } else {
+ resolvedArgv = 'repl';
+ }
}
// Set breakpoint on module start
@@ -481,27 +488,35 @@ Module._extensions['.json'] = function(module, filename) {
//Native extension for .node
-Module._extensions['.node'] = function(module, filename) {
- process.dlopen(filename, module.exports);
-};
+Module._extensions['.node'] = process.dlopen;
// bootstrap main module.
Module.runMain = function() {
// Load the main module--the command line argument.
Module._load(process.argv[1], null, true);
+ // Handle any nextTicks added in the first tick of the program
+ process._tickCallback();
};
Module._initPaths = function() {
+ var isWindows = process.platform === 'win32';
+
+ if (isWindows) {
+ var homeDir = process.env.USERPROFILE;
+ } else {
+ var homeDir = process.env.HOME;
+ }
+
var paths = [path.resolve(process.execPath, '..', '..', 'lib', 'node')];
- if (process.env['HOME']) {
- paths.unshift(path.resolve(process.env['HOME'], '.node_libraries'));
- paths.unshift(path.resolve(process.env['HOME'], '.node_modules'));
+ if (homeDir) {
+ paths.unshift(path.resolve(homeDir, '.node_libraries'));
+ paths.unshift(path.resolve(homeDir, '.node_modules'));
}
if (process.env['NODE_PATH']) {
- var splitter = process.platform === 'win32' ? ';' : ':';
+ var splitter = isWindows ? ';' : ':';
paths = process.env['NODE_PATH'].split(splitter).concat(paths);
}
diff --git a/lib/net.js b/lib/net.js
index c8d7f6091..d5e85b17e 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -20,7 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var events = require('events');
-var Stream = require('stream');
+var stream = require('stream');
var timers = require('timers');
var util = require('util');
var assert = require('assert');
@@ -42,16 +42,16 @@ function createTCP() {
}
-/* Bit flags for socket._flags */
-var FLAG_GOT_EOF = 1 << 0;
-var FLAG_SHUTDOWN = 1 << 1;
-var FLAG_DESTROY_SOON = 1 << 2;
-var FLAG_SHUTDOWN_QUEUED = 1 << 3;
-
-
var debug;
if (process.env.NODE_DEBUG && /net/.test(process.env.NODE_DEBUG)) {
- debug = function(x) { console.error('NET:', x); };
+ var pid = process.pid;
+ debug = function(x) {
+ // if console is not set up yet, then skip this.
+ if (!console.error)
+ return;
+ console.error('NET: %d', pid,
+ util.format.apply(util, arguments).slice(0, 500));
+ };
} else {
debug = function() { };
}
@@ -110,12 +110,8 @@ function normalizeConnectArgs(args) {
exports._normalizeConnectArgs = normalizeConnectArgs;
-/* called when creating new Socket, or when re-using a closed Socket */
+// called when creating new Socket, or when re-using a closed Socket
function initSocketHandle(self) {
- self._pendingWriteReqs = 0;
-
- self._flags = 0;
- self._connectQueueSize = 0;
self.destroyed = false;
self.errorEmitted = false;
self.bytesRead = 0;
@@ -131,7 +127,8 @@ function initSocketHandle(self) {
function Socket(options) {
if (!(this instanceof Socket)) return new Socket(options);
- Stream.call(this);
+ this._connecting = false;
+ this._handle = null;
switch (typeof options) {
case 'number':
@@ -142,25 +139,126 @@ function Socket(options) {
break;
}
- if (typeof options.fd === 'undefined') {
- this._handle = options && options.handle; // private
- } else {
+ stream.Duplex.call(this, options);
+
+ if (options.handle) {
+ this._handle = options.handle; // private
+ } else if (typeof options.fd !== 'undefined') {
this._handle = createPipe();
this._handle.open(options.fd);
- this.readable = this.writable = true;
+ this.readable = options.readable !== false;
+ this.writable = options.writable !== false;
+ } else {
+ // these will be set once there is a connection
+ this.readable = this.writable = false;
}
+ this.onend = null;
+
+ // shut down the socket when we're finished with it.
+ this.on('finish', onSocketFinish);
+ this.on('_socketEnd', onSocketEnd);
+
initSocketHandle(this);
- this.allowHalfOpen = options && options.allowHalfOpen;
+
+ this._pendingWrite = null;
+
+ // handle strings directly
+ this._writableState.decodeStrings = false;
+
+ // default to *not* allowing half open sockets
+ this.allowHalfOpen = options && options.allowHalfOpen || false;
+
+ // if we have a handle, then start the flow of data into the
+ // buffer. if not, then this will happen when we connect
+ if (this._handle && options.readable !== false)
+ this.read(0);
}
-util.inherits(Socket, Stream);
+util.inherits(Socket, stream.Duplex);
+
+// the user has called .end(), and all the bytes have been
+// sent out to the other side.
+// If allowHalfOpen is false, or if the readable side has
+// ended already, then destroy.
+// If allowHalfOpen is true, then we need to do a shutdown,
+// so that only the writable side will be cleaned up.
+function onSocketFinish() {
+ debug('onSocketFinish');
+ if (!this.readable || this._readableState.ended) {
+ debug('oSF: ended, destroy', this._readableState);
+ return this.destroy();
+ }
+
+ debug('oSF: not ended, call shutdown()');
+
+ // otherwise, just shutdown, or destroy() if not possible
+ if (!this._handle || !this._handle.shutdown)
+ return this.destroy();
+
+ var shutdownReq = this._handle.shutdown();
+ if (!shutdownReq)
+ return this._destroy(errnoException(process._errno, 'shutdown'));
+
+ shutdownReq.oncomplete = afterShutdown;
+}
+
+
+function afterShutdown(status, handle, req) {
+ var self = handle.owner;
+
+ debug('afterShutdown destroyed=%j', self.destroyed,
+ self._readableState);
+
+ // callback may come after call to destroy.
+ if (self.destroyed)
+ return;
+
+ if (self._readableState.ended) {
+ debug('readableState ended, destroying');
+ self.destroy();
+ } else {
+ self.once('_socketEnd', self.destroy);
+ }
+}
+
+// the EOF has been received, and no more bytes are coming.
+// if the writable side has ended already, then clean everything
+// up.
+function onSocketEnd() {
+ // XXX Should not have to do as much crap in this function.
+ // ended should already be true, since this is called *after*
+ // the EOF errno and onread has returned null to the _read cb.
+ debug('onSocketEnd', this._readableState);
+ this._readableState.ended = true;
+ if (this._readableState.endEmitted) {
+ this.readable = false;
+ } else {
+ this.once('end', function() {
+ this.readable = false;
+ });
+ this.read(0);
+ }
+
+ if (!this.allowHalfOpen)
+ this.destroySoon();
+}
exports.Socket = Socket;
exports.Stream = Socket; // Legacy naming.
+Socket.prototype.read = function(n) {
+ if (n === 0)
+ return stream.Readable.prototype.read.call(this, n);
+
+ this.read = stream.Readable.prototype.read;
+ this._consuming = true;
+ return this.read(n);
+};
+
Socket.prototype.listen = function() {
+ debug('socket.listen');
var self = this;
self.on('connection', arguments[0]);
listen(self, null, null, null);
@@ -230,96 +328,62 @@ Object.defineProperty(Socket.prototype, 'readyState', {
Object.defineProperty(Socket.prototype, 'bufferSize', {
get: function() {
if (this._handle) {
- return this._handle.writeQueueSize + this._connectQueueSize;
+ return this._handle.writeQueueSize + this._writableState.length;
}
}
});
-Socket.prototype.pause = function() {
- this._paused = true;
- if (this._handle && !this._connecting) {
- this._handle.readStop();
+// Just call handle.readStart until we have enough in the buffer
+Socket.prototype._read = function(n, callback) {
+ debug('_read');
+ if (this._connecting || !this._handle) {
+ debug('_read wait for connection');
+ this.once('connect', this._read.bind(this, n, callback));
+ return;
}
-};
+ assert(callback === this._readableState.onread);
+ assert(this._readableState.reading = true);
-Socket.prototype.resume = function() {
- this._paused = false;
- if (this._handle && !this._connecting) {
- this._handle.readStart();
+ if (!this._handle.reading) {
+ debug('Socket._read readStart');
+ this._handle.reading = true;
+ var r = this._handle.readStart();
+ if (r)
+ this._destroy(errnoException(process._errno, 'read'));
+ } else {
+ debug('readStart already has been called.');
}
};
Socket.prototype.end = function(data, encoding) {
- if (this._connecting && ((this._flags & FLAG_SHUTDOWN_QUEUED) == 0)) {
- // still connecting, add data to buffer
- if (data) this.write(data, encoding);
- this.writable = false;
- this._flags |= FLAG_SHUTDOWN_QUEUED;
- }
-
- if (!this.writable) return;
+ stream.Duplex.prototype.end.call(this, data, encoding);
this.writable = false;
-
- if (data) this.write(data, encoding);
DTRACE_NET_STREAM_END(this);
- if (!this.readable) {
- this.destroySoon();
- } else {
- this._flags |= FLAG_SHUTDOWN;
- var shutdownReq = this._handle.shutdown();
-
- if (!shutdownReq) {
- this._destroy(errnoException(errno, 'shutdown'));
- return false;
- }
-
- shutdownReq.oncomplete = afterShutdown;
- }
-
- return true;
+ // just in case we're waiting for an EOF.
+ if (this.readable && !this._readableState.endEmitted)
+ this.read(0);
+ return;
};
-function afterShutdown(status, handle, req) {
- var self = handle.owner;
-
- assert.ok(self._flags & FLAG_SHUTDOWN);
- assert.ok(!self.writable);
-
- // callback may come after call to destroy.
- if (self.destroyed) {
- return;
- }
-
- if (self._flags & FLAG_GOT_EOF || !self.readable) {
- self._destroy();
- } else {
- }
-}
-
-
Socket.prototype.destroySoon = function() {
- this.writable = false;
- this._flags |= FLAG_DESTROY_SOON;
-
- if (this._pendingWriteReqs == 0) {
- this._destroy();
- }
-};
-
+ if (this.writable)
+ this.end();
-Socket.prototype._connectQueueCleanUp = function(exception) {
- this._connecting = false;
- this._connectQueueSize = 0;
- this._connectQueue = null;
+ if (this._writableState.finishing || this._writableState.finished)
+ this.destroy();
+ else
+ this.once('finish', this.destroy);
};
Socket.prototype._destroy = function(exception, cb) {
+ debug('destroy');
+
var self = this;
function fireErrorCallbacks() {
@@ -333,13 +397,12 @@ Socket.prototype._destroy = function(exception, cb) {
};
if (this.destroyed) {
+ debug('already destroyed, fire error callbacks');
fireErrorCallbacks();
return;
}
- self._connectQueueCleanUp();
-
- debug('destroy');
+ self._connecting = false;
this.readable = this.writable = false;
@@ -347,6 +410,8 @@ Socket.prototype._destroy = function(exception, cb) {
debug('close');
if (this._handle) {
+ if (this !== process.stderr)
+ debug('close handle');
this._handle.close();
this._handle.onread = noop;
this._handle = null;
@@ -355,12 +420,15 @@ Socket.prototype._destroy = function(exception, cb) {
fireErrorCallbacks();
process.nextTick(function() {
+ debug('emit close');
self.emit('close', exception ? true : false);
});
this.destroyed = true;
if (this.server) {
+ COUNTER_NET_SERVER_CONNECTION_CLOSE(this);
+ debug('has server');
this.server._connections--;
if (this.server._emitCloseIfDrained) {
this.server._emitCloseIfDrained();
@@ -370,10 +438,13 @@ Socket.prototype._destroy = function(exception, cb) {
Socket.prototype.destroy = function(exception) {
+ debug('destroy', exception);
this._destroy(exception);
};
+// This function is called whenever the handle gets a
+// buffer, or when there's an error reading.
function onread(buffer, offset, length) {
var handle = this;
var self = handle.owner;
@@ -382,58 +453,63 @@ function onread(buffer, offset, length) {
timers.active(self);
var end = offset + length;
+ debug('onread', process._errno, offset, length, end);
if (buffer) {
- // Emit 'data' event.
+ debug('got data');
- if (self._decoder) {
- // Emit a string.
- var string = self._decoder.write(buffer.slice(offset, end));
- if (string.length) self.emit('data', string);
- } else {
- // Emit a slice. Attempt to avoid slicing the buffer if no one is
- // listening for 'data'.
- if (self._events && self._events['data']) {
- self.emit('data', buffer.slice(offset, end));
- }
+ // read success.
+ // In theory (and in practice) calling readStop right now
+ // will prevent this from being called again until _read() gets
+ // called again.
+
+ // if we didn't get any bytes, that doesn't necessarily mean EOF.
+ // wait for the next one.
+ if (offset === end) {
+ debug('not any data, keep waiting');
+ return;
}
+ // if it's not enough data, we'll just call handle.readStart()
+ // again right away.
self.bytesRead += length;
// Optimization: emit the original buffer with end points
+ var ret = true;
if (self.ondata) self.ondata(buffer, offset, end);
+ else ret = self.push(buffer.slice(offset, end));
+
+ if (handle.reading && !ret) {
+ handle.reading = false;
+ debug('readStop');
+ var r = handle.readStop();
+ if (r)
+ self._destroy(errnoException(process._errno, 'read'));
+ }
+
+ } else if (process._errno == 'EOF') {
+ debug('EOF');
- } else if (errno == 'EOF') {
- // EOF
- self.readable = false;
+ if (self._readableState.length === 0)
+ self.readable = false;
- assert.ok(!(self._flags & FLAG_GOT_EOF));
- self._flags |= FLAG_GOT_EOF;
+ if (self.onend) self.once('end', self.onend);
- // We call destroy() before end(). 'close' not emitted until nextTick so
- // the 'end' event will come first as required.
- if (!self.writable) self._destroy();
+ // send a null to the _read cb to signal the end of data.
+ self.push(null);
- if (!self.allowHalfOpen) self.end();
- if (self._events && self._events['end']) self.emit('end');
- if (self.onend) self.onend();
+ // internal end event so that we know that the actual socket
+ // is no longer readable, and we can start the shutdown
+ // procedure. No need to wait for all the data to be consumed.
+ self.emit('_socketEnd');
} else {
+ debug('error', process._errno);
// Error
- if (errno == 'ECONNRESET') {
- self._destroy();
- } else {
- self._destroy(errnoException(errno, 'read'));
- }
+ self._destroy(errnoException(process._errno, 'read'));
}
}
-Socket.prototype.setEncoding = function(encoding) {
- var StringDecoder = require('string_decoder').StringDecoder; // lazy load
- this._decoder = new StringDecoder(encoding);
-};
-
-
Socket.prototype._getpeername = function() {
if (!this._handle || !this._handle.getpeername) {
return {};
@@ -459,60 +535,54 @@ Socket.prototype.__defineGetter__('remotePort', function() {
});
-/*
- * Arguments data, [encoding], [cb]
- */
-Socket.prototype.write = function(data, arg1, arg2) {
- var encoding, cb;
-
- // parse arguments
- if (arg1) {
- if (typeof arg1 === 'string') {
- encoding = arg1;
- cb = arg2;
- } else if (typeof arg1 === 'function') {
- cb = arg1;
- } else {
- throw new Error('bad arg');
+Socket.prototype._getsockname = function() {
+ if (!this._handle || !this._handle.getsockname) {
+ return {};
+ }
+ if (!this._sockname) {
+ this._sockname = this._handle.getsockname();
+ if (this._sockname === null) {
+ return {};
}
}
+ return this._sockname;
+};
- if (typeof data === 'string') {
- encoding = (encoding || 'utf8').toLowerCase();
- switch (encoding) {
- case 'utf8':
- case 'utf-8':
- case 'ascii':
- case 'ucs2':
- case 'ucs-2':
- case 'utf16le':
- case 'utf-16le':
- // This encoding can be handled in the binding layer.
- break;
- default:
- data = new Buffer(data, encoding);
- }
- } else if (!Buffer.isBuffer(data)) {
- throw new TypeError('First argument must be a buffer or a string.');
- }
+Socket.prototype.__defineGetter__('localAddress', function() {
+ return this._getsockname().address;
+});
+
+
+Socket.prototype.__defineGetter__('localPort', function() {
+ return this._getsockname().port;
+});
- // If we are still connecting, then buffer this for later.
- if (this._connecting) {
- this._connectQueueSize += data.length;
- if (this._connectQueue) {
- this._connectQueue.push([data, encoding, cb]);
- } else {
- this._connectQueue = [[data, encoding, cb]];
- }
- return false;
- }
- return this._write(data, encoding, cb);
+Socket.prototype.write = function(chunk, encoding, cb) {
+ if (typeof chunk !== 'string' && !Buffer.isBuffer(chunk))
+ throw new TypeError('invalid data');
+ return stream.Duplex.prototype.write.apply(this, arguments);
};
-Socket.prototype._write = function(data, encoding, cb) {
+Socket.prototype._write = function(dataEncoding, cb) {
+ // assert(Array.isArray(dataEncoding));
+ var data = dataEncoding[0];
+ var encoding = dataEncoding[1] || 'utf8';
+
+ // If we are still connecting, then buffer this for later.
+ // The Writable logic will buffer up any more writes while
+ // waiting for this one to be done.
+ if (this._connecting) {
+ this._pendingWrite = dataEncoding;
+ this.once('connect', function() {
+ this._write(dataEncoding, cb);
+ });
+ return;
+ }
+ this._pendingWrite = null;
+
timers.active(this);
if (!this._handle) {
@@ -520,63 +590,59 @@ Socket.prototype._write = function(data, encoding, cb) {
return false;
}
- var writeReq;
+ var enc = Buffer.isBuffer(data) ? 'buffer' : encoding;
+ var writeReq = createWriteReq(this._handle, data, enc);
- if (Buffer.isBuffer(data)) {
- writeReq = this._handle.writeBuffer(data);
+ if (!writeReq || typeof writeReq !== 'object')
+ return this._destroy(errnoException(process._errno, 'write'), cb);
- } else {
- switch (encoding) {
- case 'utf8':
- case 'utf-8':
- writeReq = this._handle.writeUtf8String(data);
- break;
-
- case 'ascii':
- writeReq = this._handle.writeAsciiString(data);
- break;
+ writeReq.oncomplete = afterWrite;
+ this._bytesDispatched += writeReq.bytes;
- case 'ucs2':
- case 'ucs-2':
- case 'utf16le':
- case 'utf-16le':
- writeReq = this._handle.writeUcs2String(data);
- break;
+ // If it was entirely flushed, we can write some more right now.
+ // However, if more is left in the queue, then wait until that clears.
+ if (this._handle.writeQueueSize === 0)
+ cb();
+ else
+ writeReq.cb = cb;
+};
- default:
- assert(0);
- }
- }
+function createWriteReq(handle, data, encoding) {
+ switch (encoding) {
+ case 'buffer':
+ return handle.writeBuffer(data);
- if (!writeReq || typeof writeReq !== 'object') {
- this._destroy(errnoException(errno, 'write'), cb);
- return false;
- }
+ case 'utf8':
+ case 'utf-8':
+ return handle.writeUtf8String(data);
- writeReq.oncomplete = afterWrite;
- writeReq.cb = cb;
+ case 'ascii':
+ return handle.writeAsciiString(data);
- this._pendingWriteReqs++;
- this._bytesDispatched += writeReq.bytes;
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return handle.writeUcs2String(data);
- return this._handle.writeQueueSize == 0;
-};
+ default:
+ return handle.writeBuffer(new Buffer(data, encoding));
+ }
+}
Socket.prototype.__defineGetter__('bytesWritten', function() {
var bytes = this._bytesDispatched,
- connectQueue = this._connectQueue;
+ state = this._writableState,
+ pending = this._pendingWrite;
- if (connectQueue) {
- connectQueue.forEach(function(el) {
- var data = el[0];
- if (Buffer.isBuffer(data)) {
- bytes += data.length;
- } else {
- bytes += Buffer.byteLength(data, el[1]);
- }
- }, this);
- }
+ state.buffer.forEach(function(el) {
+ el = el[0];
+ bytes += Buffer.byteLength(el[0], el[1]);
+ });
+
+ if (pending)
+ bytes += Buffer.byteLength(pending[0], pending[1]);
return bytes;
});
@@ -584,30 +650,29 @@ Socket.prototype.__defineGetter__('bytesWritten', function() {
function afterWrite(status, handle, req) {
var self = handle.owner;
+ var state = self._writableState;
+ if (self !== process.stderr && self !== process.stdout)
+ debug('afterWrite', status, req);
// callback may come after call to destroy.
if (self.destroyed) {
+ debug('afterWrite destroyed');
return;
}
if (status) {
- self._destroy(errnoException(errno, 'write'), req.cb);
+ debug('write failure', errnoException(process._errno, 'write'));
+ self._destroy(errnoException(process._errno, 'write'), req.cb);
return;
}
timers.active(self);
- self._pendingWriteReqs--;
-
- if (self._pendingWriteReqs == 0) {
- self.emit('drain');
- }
-
- if (req.cb) req.cb();
+ if (self !== process.stderr && self !== process.stdout)
+ debug('afterWrite call cb');
- if (self._pendingWriteReqs == 0 && self._flags & FLAG_DESTROY_SOON) {
- self._destroy();
- }
+ if (req.cb)
+ req.cb.call(self);
}
@@ -626,7 +691,7 @@ function connect(self, address, port, addressType, localAddress) {
}
if (r) {
- self._destroy(errnoException(errno, 'bind'));
+ self._destroy(errnoException(process._errno, 'bind'));
return;
}
}
@@ -643,7 +708,7 @@ function connect(self, address, port, addressType, localAddress) {
if (connectReq !== null) {
connectReq.oncomplete = afterConnect;
} else {
- self._destroy(errnoException(errno, 'connect'));
+ self._destroy(errnoException(process._errno, 'connect'));
}
}
@@ -657,10 +722,21 @@ Socket.prototype.connect = function(options, cb) {
return Socket.prototype.connect.apply(this, args);
}
+ if (this.destroyed) {
+ this._readableState.reading = false;
+ this._readableState.ended = false;
+ this._writableState.ended = false;
+ this._writableState.ending = false;
+ this._writableState.finished = false;
+ this._writableState.finishing = false;
+ this.destroyed = false;
+ this._handle = null;
+ }
+
var self = this;
var pipe = !!options.path;
- if (this.destroyed || !this._handle) {
+ if (!this._handle) {
this._handle = pipe ? createPipe() : createTCP();
initSocketHandle(this);
}
@@ -716,6 +792,19 @@ Socket.prototype.connect = function(options, cb) {
};
+Socket.prototype.ref = function() {
+ if (this._handle)
+ this._handle.ref();
+};
+
+
+Socket.prototype.unref = function() {
+ if (this._handle)
+ this._handle.unref();
+};
+
+
+
function afterConnect(status, handle, req, readable, writable) {
var self = handle.owner;
@@ -736,29 +825,16 @@ function afterConnect(status, handle, req, readable, writable) {
self.writable = writable;
timers.active(self);
- if (self.readable && !self._paused) {
- handle.readStart();
- }
-
- if (self._connectQueue) {
- debug('Drain the connect queue');
- var connectQueue = self._connectQueue;
- for (var i = 0; i < connectQueue.length; i++) {
- self._write.apply(self, connectQueue[i]);
- }
- self._connectQueueCleanUp();
- }
-
self.emit('connect');
- if (self._flags & FLAG_SHUTDOWN_QUEUED) {
- // end called before connected - call end now with no data
- self._flags &= ~FLAG_SHUTDOWN_QUEUED;
- self.end();
- }
+ // start the first read, or get an immediate EOF.
+ // this doesn't actually consume any bytes, because len=0.
+ if (readable)
+ self.read(0);
+
} else {
- self._connectQueueCleanUp();
- self._destroy(errnoException(errno, 'connect'));
+ self._connecting = false;
+ self._destroy(errnoException(process._errno, 'connect'));
}
}
@@ -797,24 +873,25 @@ function Server(/* [ options, ] listener */) {
this._connections = 0;
- // when server is using slaves .connections is not reliable
- // so null will be return if thats the case
Object.defineProperty(this, 'connections', {
- get: function() {
+ get: util.deprecate(function() {
+
if (self._usingSlaves) {
return null;
}
return self._connections;
- },
- set: function(val) {
+ }, 'connections property is deprecated. Use getConnections() method'),
+ set: util.deprecate(function(val) {
return (self._connections = val);
- },
+ }, 'connections property is deprecated. Use getConnections() method'),
configurable: true, enumerable: true
});
- this.allowHalfOpen = options.allowHalfOpen || false;
-
this._handle = null;
+ this._usingSlaves = false;
+ this._slaves = [];
+
+ this.allowHalfOpen = options.allowHalfOpen || false;
}
util.inherits(Server, events.EventEmitter);
exports.Server = Server;
@@ -845,7 +922,7 @@ var createServerHandle = exports._createServerHandle =
default:
// Not a fd we can listen on. This will trigger an error.
debug('listen invalid fd=' + fd + ' type=' + type);
- global.errno = 'EINVAL'; // hack, callers expect that errno is set
+ process._errno = 'EINVAL'; // hack, callers expect that errno is set
handle = null;
break;
}
@@ -882,20 +959,24 @@ var createServerHandle = exports._createServerHandle =
Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
+ debug('listen2', address, port, addressType, backlog);
var self = this;
var r = 0;
// If there is not yet a handle, we need to create one and bind.
// In the case of a server sent via IPC, we don't need to do this.
if (!self._handle) {
+ debug('_listen2: create a handle');
self._handle = createServerHandle(address, port, addressType, fd);
if (!self._handle) {
- var error = errnoException(errno, 'listen');
+ var error = errnoException(process._errno, 'listen');
process.nextTick(function() {
self.emit('error', error);
});
return;
}
+ } else {
+ debug('_listen2: have a handle already');
}
self._handle.onconnection = onconnection;
@@ -907,7 +988,7 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
r = self._handle.listen(backlog || 511);
if (r) {
- var ex = errnoException(errno, 'listen');
+ var ex = errnoException(process._errno, 'listen');
self._handle.close();
self._handle = null;
process.nextTick(function() {
@@ -1015,7 +1096,7 @@ function onconnection(clientHandle) {
debug('onconnection');
if (!clientHandle) {
- self.emit('error', errnoException(errno, 'accept'));
+ self.emit('error', errnoException(process._errno, 'accept'));
return;
}
@@ -1030,18 +1111,56 @@ function onconnection(clientHandle) {
});
socket.readable = socket.writable = true;
- clientHandle.readStart();
self._connections++;
socket.server = self;
DTRACE_NET_SERVER_CONNECTION(socket);
+ COUNTER_NET_SERVER_CONNECTION(socket);
self.emit('connection', socket);
socket.emit('connect');
}
+Server.prototype.getConnections = function(cb) {
+ function end(err, connections) {
+ process.nextTick(function() {
+ cb(err, connections);
+ });
+ }
+
+ if (!this._usingSlaves) {
+ return end(null, this._connections);
+ }
+
+ // Poll slaves
+ var left = this._slaves.length,
+ total = this._connections;
+
+ function oncount(err, count) {
+ if (err) {
+ left = -1;
+ return end(err);
+ }
+
+ total += count;
+ if (--left === 0) return end(null, total);
+ }
+
+ this._slaves.forEach(function(slave) {
+ slave.getConnections(oncount);
+ });
+};
+
+
Server.prototype.close = function(cb) {
+ function onSlaveClose() {
+ if (--left !== 0) return;
+
+ self._connections = 0;
+ self._emitCloseIfDrained();
+ }
+
if (!this._handle) {
// Throw error. Follows net_legacy behaviour.
throw new Error('Not running');
@@ -1052,25 +1171,38 @@ Server.prototype.close = function(cb) {
}
this._handle.close();
this._handle = null;
- this._emitCloseIfDrained();
- // fetch new socket lists
if (this._usingSlaves) {
- this._slaves.forEach(function(socketList) {
- if (socketList.list.length === 0) return;
- socketList.update();
+ var self = this,
+ left = this._slaves.length;
+
+ // Increment connections to be sure that, even if all sockets will be closed
+ // during polling of slaves, `close` event will be emitted only once.
+ this._connections++;
+
+ // Poll slaves
+ this._slaves.forEach(function(slave) {
+ slave.close(onSlaveClose);
});
+ } else {
+ this._emitCloseIfDrained();
}
return this;
};
Server.prototype._emitCloseIfDrained = function() {
+ debug('SERVER _emitCloseIfDrained');
var self = this;
- if (self._handle || self._connections) return;
+ if (self._handle || self._connections) {
+ debug('SERVER handle? %j connections? %d',
+ !!self._handle, self._connections);
+ return;
+ }
process.nextTick(function() {
+ debug('SERVER: emit close');
self.emit('close');
});
};
@@ -1080,15 +1212,21 @@ Server.prototype.listenFD = util.deprecate(function(fd, type) {
return this.listen({ fd: fd });
}, 'listenFD is deprecated. Use listen({fd: <number>}).');
-// when sending a socket using fork IPC this function is executed
Server.prototype._setupSlave = function(socketList) {
- if (!this._usingSlaves) {
- this._usingSlaves = true;
- this._slaves = [];
- }
+ this._usingSlaves = true;
this._slaves.push(socketList);
};
+Server.prototype.ref = function() {
+ if (this._handle)
+ this._handle.ref();
+};
+
+Server.prototype.unref = function() {
+ if (this._handle)
+ this._handle.unref();
+};
+
// TODO: isIP should be moved to the DNS code. Putting it here now because
// this is what the legacy system did.
diff --git a/lib/os.js b/lib/os.js
index 1fe873103..673b7dd7d 100644
--- a/lib/os.js
+++ b/lib/os.js
@@ -22,6 +22,7 @@
var binding = process.binding('os');
var util = require('util');
+exports.endianness = binding.getEndianness;
exports.hostname = binding.getHostname;
exports.loadavg = binding.getLoadAvg;
exports.uptime = binding.getUptime;
@@ -40,13 +41,15 @@ exports.platform = function() {
return process.platform;
};
-exports.tmpDir = function() {
+exports.tmpdir = function() {
return process.env.TMPDIR ||
process.env.TMP ||
process.env.TEMP ||
(process.platform === 'win32' ? 'c:\\windows\\temp' : '/tmp');
};
+exports.tmpDir = exports.tmpdir;
+
exports.getNetworkInterfaces = util.deprecate(function() {
return exports.networkInterfaces();
}, 'getNetworkInterfaces is now called `os.networkInterfaces`.');
diff --git a/lib/path.js b/lib/path.js
index 438b05d8e..da0f8bee6 100644
--- a/lib/path.js
+++ b/lib/path.js
@@ -33,7 +33,7 @@ function normalizeArray(parts, allowAboveRoot) {
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
- if (last == '.') {
+ if (last === '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
@@ -59,11 +59,11 @@ if (isWindows) {
// Regex to split a windows path into three parts: [*, device, slash,
// tail] windows-only
var splitDeviceRe =
- /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/;
+ /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
// Regex to split the tail part of the above into [*, dir, basename, ext]
var splitTailRe =
- /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/\\]*)?)$/;
+ /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
// Function to split a filename into [root, dir, basename, ext]
// windows version
@@ -74,12 +74,16 @@ if (isWindows) {
tail = result[3] || '';
// Split the tail into dir, basename and extension
var result2 = splitTailRe.exec(tail),
- dir = result2[1] || '',
- basename = result2[2] || '',
- ext = result2[3] || '';
+ dir = result2[1],
+ basename = result2[2],
+ ext = result2[3];
return [device, dir, basename, ext];
};
+ var normalizeUNCRoot = function(device) {
+ return '\\\\' + device.replace(/^[\\\/]+/, '').replace(/[\\\/]+/g, '\\');
+ };
+
// path.resolve([from ...], to)
// windows version
exports.resolve = function() {
@@ -101,14 +105,16 @@ if (isWindows) {
path = process.env['=' + resolvedDevice];
// Verify that a drive-local cwd was found and that it actually points
// to our drive. If not, default to the drive's root.
- if (!path || path.slice(0, 3).toLowerCase() !==
+ if (!path || path.substr(0, 3).toLowerCase() !==
resolvedDevice.toLowerCase() + '\\') {
path = resolvedDevice + '\\';
}
}
// Skip empty and invalid entries
- if (typeof path !== 'string' || !path) {
+ if (typeof path !== 'string') {
+ throw new TypeError('Arguments to path.resolve must be strings');
+ } else if (!path) {
continue;
}
@@ -138,8 +144,11 @@ if (isWindows) {
}
}
- // Replace slashes (in UNC share name) by backslashes
- resolvedDevice = resolvedDevice.replace(/\//g, '\\');
+ // Convert slashes to backslashes when `resolvedDevice` points to an UNC
+ // root. Also squash multiple slashes into a single one where appropriate.
+ if (isUnc) {
+ resolvedDevice = normalizeUNCRoot(resolvedDevice);
+ }
// At this point the path should be resolved to a full absolute path,
// but handle relative paths to be safe (might happen when process.cwd()
@@ -180,7 +189,10 @@ if (isWindows) {
}
// Convert slashes to backslashes when `device` points to an UNC root.
- device = device.replace(/\//g, '\\');
+ // Also squash multiple slashes into a single one where appropriate.
+ if (isUnc) {
+ device = normalizeUNCRoot(device);
+ }
return device + (isAbsolute ? '\\' : '') + tail;
};
@@ -188,17 +200,30 @@ if (isWindows) {
// windows version
exports.join = function() {
function f(p) {
- return p && typeof p === 'string';
+ if (typeof p !== 'string') {
+ throw new TypeError('Arguments to path.join must be strings');
+ }
+ return p;
}
- var paths = Array.prototype.slice.call(arguments, 0).filter(f);
+ var paths = Array.prototype.filter.call(arguments, f);
var joined = paths.join('\\');
- // Make sure that the joined path doesn't start with two slashes
- // - it will be mistaken for an unc path by normalize() -
- // unless the paths[0] also starts with two slashes
- if (/^[\\\/]{2}/.test(joined) && !/^[\\\/]{2}/.test(paths[0])) {
- joined = joined.slice(1);
+ // Make sure that the joined path doesn't start with two slashes, because
+ // normalize() will mistake it for an UNC path then.
+ //
+ // This step is skipped when it is very clear that the user actually
+ // intended to point at an UNC path. This is assumed when the first
+ // non-empty string arguments starts with exactly two slashes followed by
+ // at least one more non-slash character.
+ //
+ // Note that for normalize() to treat a path as an UNC path it needs to
+ // have at least 2 components, so we don't filter for that here.
+ // This means that the user can use join to construct UNC paths from
+ // a server name and a share name; for example:
+ // path.join('//server', 'share') -> '\\\\server\\share\')
+ if (!/^[\\\/]{2}[^\\\/]/.test(paths[0])) {
+ joined = joined.replace(/^[\\\/]{2,}/, '\\');
}
return exports.normalize(joined);
@@ -262,16 +287,16 @@ if (isWindows) {
};
exports.sep = '\\';
+ exports.delimiter = ';';
} else /* posix */ {
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
- /^(\/?)([\s\S]+\/(?!$)|\/)?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/]*)?)$/;
+ /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var splitPath = function(filename) {
- var result = splitPathRe.exec(filename);
- return [result[1] || '', result[2] || '', result[3] || '', result[4] || ''];
+ return splitPathRe.exec(filename).slice(1);
};
// path.resolve([from ...], to)
@@ -284,7 +309,9 @@ if (isWindows) {
var path = (i >= 0) ? arguments[i] : process.cwd();
// Skip empty and invalid entries
- if (typeof path !== 'string' || !path) {
+ if (typeof path !== 'string') {
+ throw new TypeError('Arguments to path.resolve must be strings');
+ } else if (!path) {
continue;
}
@@ -307,7 +334,7 @@ if (isWindows) {
// posix version
exports.normalize = function(path) {
var isAbsolute = path.charAt(0) === '/',
- trailingSlash = path.slice(-1) === '/';
+ trailingSlash = path.substr(-1) === '/';
// Normalize the path
path = normalizeArray(path.split('/').filter(function(p) {
@@ -329,7 +356,10 @@ if (isWindows) {
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(paths.filter(function(p, index) {
- return p && typeof p === 'string';
+ if (typeof p !== 'string') {
+ throw new TypeError('Arguments to path.join must be strings');
+ }
+ return p;
}).join('/'));
};
@@ -378,6 +408,7 @@ if (isWindows) {
};
exports.sep = '/';
+ exports.delimiter = ':';
}
@@ -393,7 +424,7 @@ exports.dirname = function(path) {
if (dir) {
// It has a dirname, strip trailing slash
- dir = dir.substring(0, dir.length - 1);
+ dir = dir.substr(0, dir.length - 1);
}
return root + dir;
@@ -427,18 +458,21 @@ exports.existsSync = util.deprecate(function(path) {
if (isWindows) {
exports._makeLong = function(path) {
- path = '' + path;
+ // Note: this will *probably* throw somewhere.
+ if (typeof path !== 'string')
+ return path;
+
if (!path) {
return '';
}
var resolvedPath = exports.resolve(path);
- if (resolvedPath.match(/^[a-zA-Z]\:\\/)) {
+ if (/^[a-zA-Z]\:\\/.test(resolvedPath)) {
// path is local filesystem path, which needs to be converted
// to long UNC path.
return '\\\\?\\' + resolvedPath;
- } else if (resolvedPath.match(/^\\\\[^?.]/)) {
+ } else if (/^\\\\[^?.]/.test(resolvedPath)) {
// path is network UNC path, which needs to be converted
// to long UNC path.
return '\\\\?\\UNC\\' + resolvedPath.substring(2);
diff --git a/lib/punycode.js b/lib/punycode.js
index 887c968b3..163923c40 100644
--- a/lib/punycode.js
+++ b/lib/punycode.js
@@ -1,4 +1,4 @@
-/*! http://mths.be/punycode by @mathias */
+/*! http://mths.be/punycode v1.2.0 by @mathias */
;(function(root) {
/**
@@ -29,14 +29,13 @@
delimiter = '-', // '\x2D'
/** Regular expressions */
- regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
regexPunycode = /^xn--/,
+ regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
+ regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators
/** Error messages */
errors = {
- 'overflow': 'Overflow: input needs wider integers to process.',
- 'ucs2decode': 'UCS-2(decode): illegal sequence',
- 'ucs2encode': 'UCS-2(encode): illegal value',
+ 'overflow': 'Overflow: input needs wider integers to process',
'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
'invalid-input': 'Invalid input'
},
@@ -87,8 +86,7 @@
* function.
*/
function mapDomain(string, fn) {
- var glue = '.';
- return map(string.split(glue), fn).join(glue);
+ return map(string.split(regexSeparators), fn).join('.');
}
/**
@@ -112,14 +110,17 @@
extra;
while (counter < length) {
value = string.charCodeAt(counter++);
- if ((value & 0xF800) == 0xD800) {
+ if ((value & 0xF800) == 0xD800 && counter < length) {
+ // high surrogate, and there is a next character
extra = string.charCodeAt(counter++);
- if ((value & 0xFC00) != 0xD800 || (extra & 0xFC00) != 0xDC00) {
- error('ucs2decode');
+ if ((extra & 0xFC00) == 0xDC00) { // low surrogate
+ output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
+ } else {
+ output.push(value, extra);
}
- value = ((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000;
+ } else {
+ output.push(value);
}
- output.push(value);
}
return output;
}
@@ -135,9 +136,6 @@
function ucs2encode(array) {
return map(array, function(value) {
var output = '';
- if ((value & 0xF800) == 0xD800) {
- error('ucs2encode');
- }
if (value > 0xFFFF) {
value -= 0x10000;
output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
@@ -200,7 +198,7 @@
}
/**
- * Converts a basic code point to lowercase is `flag` is falsy, or to
+ * Converts a basic code point to lowercase if `flag` is falsy, or to
* uppercase if `flag` is truthy. The code point is unchanged if it's
* caseless. The behavior is undefined if `codePoint` is not a basic code
* point.
@@ -472,7 +470,7 @@
* @memberOf punycode
* @type String
*/
- 'version': '1.0.0',
+ 'version': '1.2.0',
/**
* An object of methods to convert from JavaScript's internal character
* representation (UCS-2) to decimal Unicode code points, and back.
diff --git a/lib/readline.js b/lib/readline.js
index 8457ad666..a2d7e1c82 100644
--- a/lib/readline.js
+++ b/lib/readline.js
@@ -49,6 +49,8 @@ function Interface(input, output, completer, terminal) {
return new Interface(input, output, completer, terminal);
}
+ this._sawReturn = false;
+
EventEmitter.call(this);
if (arguments.length === 1) {
@@ -205,12 +207,14 @@ Interface.prototype._onLine = function(line) {
Interface.prototype._addHistory = function() {
if (this.line.length === 0) return '';
- this.history.unshift(this.line);
- this.historyIndex = -1;
+ if (this.history.length === 0 || this.history[0] !== this.line) {
+ this.history.unshift(this.line);
- // Only store so many
- if (this.history.length > kHistorySize) this.history.pop();
+ // Only store so many
+ if (this.history.length > kHistorySize) this.history.pop();
+ }
+ this.historyIndex = -1;
return this.history[0];
};
@@ -290,23 +294,32 @@ Interface.prototype.write = function(d, key) {
this.terminal ? this._ttyWrite(d, key) : this._normalWrite(d);
};
+// \r\n, \n, or \r followed by something other than \n
+var lineEnding = /\r?\n|\r(?!\n)/;
Interface.prototype._normalWrite = function(b) {
if (b === undefined) {
return;
}
var string = this._decoder.write(b);
+ if (this._sawReturn) {
+ string = string.replace(/^\n/, '');
+ this._sawReturn = false;
+ }
+
if (this._line_buffer) {
string = this._line_buffer + string;
this._line_buffer = null;
}
- if (string.indexOf('\n') !== -1) {
+ if (lineEnding.test(string)) {
+ this._sawReturn = /\r$/.test(string);
+
// got one or more newlines; process into "line" events
- var lines = string.split('\n');
+ var lines = string.split(lineEnding);
// either '' or (concievably) the unfinished portion of the next line
string = lines.pop();
this._line_buffer = string;
lines.forEach(function(line) {
- this._onLine(line + '\n');
+ this._onLine(line);
}, this);
} else if (string) {
// no newlines this time, save what we have for next time
@@ -731,11 +744,23 @@ Interface.prototype._ttyWrite = function(s, key) {
} else {
/* No modifier keys used */
+ // \r bookkeeping is only relevant if a \n comes right after.
+ if (this._sawReturn && key.name !== 'enter')
+ this._sawReturn = false;
+
switch (key.name) {
- case 'enter':
+ case 'return': // carriage return, i.e. \r
+ this._sawReturn = true;
this._line();
break;
+ case 'enter':
+ if (this._sawReturn)
+ this._sawReturn = false;
+ else
+ this._line();
+ break;
+
case 'backspace':
this._deleteLeft();
break;
@@ -799,12 +824,14 @@ exports.Interface = Interface;
*/
function emitKeypressEvents(stream) {
- if (stream._emitKeypress) return;
- stream._emitKeypress = true;
+ if (stream._keypressDecoder) return;
+ var StringDecoder = require('string_decoder').StringDecoder; // lazy load
+ stream._keypressDecoder = new StringDecoder('utf8');
function onData(b) {
if (stream.listeners('keypress').length > 0) {
- emitKey(stream, b);
+ var r = stream._keypressDecoder.write(b);
+ if (r) emitKey(stream, r);
} else {
// Nobody's watching anyway
stream.removeListener('data', onData);
@@ -881,8 +908,12 @@ function emitKey(stream, s) {
key.sequence = s;
- if (s === '\r' || s === '\n') {
- // enter
+ if (s === '\r') {
+ // carriage return
+ key.name = 'return';
+
+ } else if (s === '\n') {
+ // enter, should have been called linefeed
key.name = 'enter';
} else if (s === '\t') {
diff --git a/lib/repl.js b/lib/repl.js
index ba334cfda..e19a92e49 100644
--- a/lib/repl.js
+++ b/lib/repl.js
@@ -22,7 +22,7 @@
/* A repl library that you can include in your own code to get a runtime
* interface to your program.
*
- * var repl = require("/repl.js");
+ * var repl = require("repl");
* // start repl on stdin
* repl.start("prompt> ");
*
@@ -47,6 +47,7 @@ var vm = require('vm');
var path = require('path');
var fs = require('fs');
var rl = require('readline');
+var Console = require('console').Console;
var EventEmitter = require('events').EventEmitter;
// If obj.hasOwnProperty has been overridden, then calling
@@ -68,8 +69,8 @@ module.paths = require('module')._nodeModulePaths(module.filename);
exports.writer = util.inspect;
exports._builtinLibs = ['assert', 'buffer', 'child_process', 'cluster',
- 'crypto', 'dgram', 'dns', 'events', 'fs', 'http', 'https', 'net',
- 'os', 'path', 'punycode', 'querystring', 'readline', 'repl',
+ 'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'net',
+ 'os', 'path', 'punycode', 'querystring', 'readline', 'stream',
'string_decoder', 'tls', 'tty', 'url', 'util', 'vm', 'zlib'];
@@ -116,9 +117,6 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
cb(err, result);
};
- self.resetContext();
- self.bufferedCommand = '';
-
if (!input && !output) {
// legacy API, passing a 'stream'/'socket' option
if (!stream) {
@@ -136,10 +134,12 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
}
}
-
self.inputStream = input;
self.outputStream = output;
+ self.resetContext();
+ self.bufferedCommand = '';
+
self.prompt = (prompt != undefined ? prompt : '> ');
function complete(text, callback) {
@@ -206,7 +206,7 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
// Check to see if a REPL keyword was used. If it returns true,
// display next prompt and return.
- if (cmd && cmd.charAt(0) === '.') {
+ if (cmd && cmd.charAt(0) === '.' && isNaN(parseFloat(cmd))) {
var matches = cmd.match(/^(\.[^\s]+)\s*(.*)$/);
var keyword = matches && matches[1];
var rest = matches && matches[2];
@@ -218,21 +218,6 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
}
}
- // Check if a builtin module name was used and then include it
- // if there's no conflict.
- if (exports._builtinLibs.indexOf(cmd) !== -1) {
- var lib = require(cmd);
- if (cmd in self.context && lib !== self.context[cmd]) {
- self.outputStream.write('A different "' + cmd +
- '" already exists globally\n');
- } else {
- self.context._ = self.context[cmd] = lib;
- self.outputStream.write(self.writer(lib) + '\n');
- }
- self.displayPrompt();
- return;
- }
-
if (!skipCatchall) {
var evalCmd = self.bufferedCommand + cmd + '\n';
@@ -275,7 +260,7 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
self.outputStream.write('npm should be run outside of the ' +
'node repl, in your normal shell.\n' +
'(Press Control-D to exit.)\n');
- self.bufferedCmd = '';
+ self.bufferedCommand = '';
self.displayPrompt();
return;
}
@@ -331,21 +316,39 @@ REPLServer.prototype.createContext = function() {
} else {
context = vm.createContext();
for (var i in global) context[i] = global[i];
+ context.console = new Console(this.outputStream);
+ context.global = context;
+ context.global.global = context;
}
context.module = module;
context.require = require;
- context.global = context;
- context.global.global = context;
this.lines = [];
this.lines.level = [];
+ // make built-in modules available directly
+ // (loaded lazily)
+ exports._builtinLibs.forEach(function(name) {
+ Object.defineProperty(context, name, {
+ get: function() {
+ var lib = require(name);
+ context._ = context[name] = lib;
+ return lib;
+ },
+ // allow the creation of other globals with this name
+ set: function(val) {
+ delete context[name];
+ context[name] = val;
+ },
+ configurable: true
+ });
+ });
+
return context;
};
REPLServer.prototype.resetContext = function() {
- for (var i in require.cache) delete require.cache[i];
this.context = this.createContext();
};
@@ -437,11 +440,7 @@ REPLServer.prototype.complete = function(line, callback) {
completionGroupsLoaded();
} else if (match = line.match(requireRE)) {
// require('...<Tab>')
- //TODO: suggest require.exts be exposed to be introspec registered
- //extensions?
- //TODO: suggest include the '.' in exts in internal repr: parity with
- //`path.extname`.
- var exts = ['.js', '.node'];
+ var exts = Object.keys(require.extensions);
var indexRe = new RegExp('^index(' + exts.map(regexpEscape).join('|') +
')$');
diff --git a/lib/stream.js b/lib/stream.js
index c03b8b77d..481d7644e 100644
--- a/lib/stream.js
+++ b/lib/stream.js
@@ -19,17 +19,30 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
+module.exports = Stream;
+
var events = require('events');
var util = require('util');
-function Stream() {
- events.EventEmitter.call(this);
-}
util.inherits(Stream, events.EventEmitter);
-module.exports = Stream;
+Stream.Readable = require('_stream_readable');
+Stream.Writable = require('_stream_writable');
+Stream.Duplex = require('_stream_duplex');
+Stream.Transform = require('_stream_transform');
+Stream.PassThrough = require('_stream_passthrough');
+
// Backwards-compat with node 0.4.x
Stream.Stream = Stream;
+
+
+// old-style streams. Note that the pipe method (the only relevant
+// part of this class) is overridden in the Readable class.
+
+function Stream() {
+ events.EventEmitter.call(this);
+}
+
Stream.prototype.pipe = function(dest, options) {
var source = this;
@@ -99,14 +112,12 @@ Stream.prototype.pipe = function(dest, options) {
source.removeListener('end', cleanup);
source.removeListener('close', cleanup);
- dest.removeListener('end', cleanup);
dest.removeListener('close', cleanup);
}
source.on('end', cleanup);
source.on('close', cleanup);
- dest.on('end', cleanup);
dest.on('close', cleanup);
dest.emit('pipe', source);
diff --git a/lib/string_decoder.js b/lib/string_decoder.js
index 879e59064..6b1e30895 100644
--- a/lib/string_decoder.js
+++ b/lib/string_decoder.js
@@ -19,8 +19,15 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
+function assertEncoding(encoding) {
+ if (encoding && !Buffer.isEncoding(encoding)) {
+ throw new Error('Unknown encoding: ' + encoding);
+ }
+}
+
var StringDecoder = exports.StringDecoder = function(encoding) {
this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
+ assertEncoding(encoding);
switch (this.encoding) {
case 'utf8':
// CESU-8 represents each of Surrogate Pair by 3-bytes
@@ -32,6 +39,11 @@ var StringDecoder = exports.StringDecoder = function(encoding) {
this.surrogateSize = 2;
this.detectIncompleteChar = utf16DetectIncompleteChar;
break;
+ case 'base64':
+ // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
+ this.surrogateSize = 3;
+ this.detectIncompleteChar = base64DetectIncompleteChar;
+ break;
default:
this.write = passThroughWrite;
return;
@@ -145,6 +157,21 @@ StringDecoder.prototype.detectIncompleteChar = function(buffer) {
return i;
};
+StringDecoder.prototype.end = function(buffer) {
+ var res = '';
+ if (buffer && buffer.length)
+ res = this.write(buffer);
+
+ if (this.charReceived) {
+ var cr = this.charReceived;
+ var buf = this.charBuffer;
+ var enc = this.encoding;
+ res += buf.slice(0, cr).toString(enc);
+ }
+
+ return res;
+};
+
function passThroughWrite(buffer) {
return buffer.toString(this.encoding);
}
@@ -154,3 +181,9 @@ function utf16DetectIncompleteChar(buffer) {
this.charLength = incomplete ? 2 : 0;
return incomplete;
}
+
+function base64DetectIncompleteChar(buffer) {
+ var incomplete = this.charReceived = buffer.length % 3;
+ this.charLength = incomplete ? 3 : 0;
+ return incomplete;
+}
diff --git a/lib/timers.js b/lib/timers.js
index 6d6066a01..68890ab9f 100644
--- a/lib/timers.js
+++ b/lib/timers.js
@@ -47,11 +47,10 @@ if (process.env.NODE_DEBUG && /timer/.test(process.env.NODE_DEBUG)) {
// value = list
var lists = {};
-
// the main function - creates lists on demand and the watchers associated
// with them.
function insert(item, msecs) {
- item._idleStart = new Date();
+ item._idleStart = Date.now();
item._idleTimeout = msecs;
if (msecs < 0) return;
@@ -67,55 +66,65 @@ function insert(item, msecs) {
L.init(list);
lists[msecs] = list;
+ list.msecs = msecs;
+ list.ontimeout = listOnTimeout;
+ }
+
+ L.append(list, item);
+ assert(!L.isEmpty(list)); // list is not empty
+}
+
+function listOnTimeout() {
+ var msecs = this.msecs;
+ var list = this;
+
+ debug('timeout callback ' + msecs);
- list.ontimeout = function() {
- debug('timeout callback ' + msecs);
-
- var now = new Date();
- debug('now: ' + now);
-
- var first;
- while (first = L.peek(list)) {
- var diff = now - first._idleStart;
- if (diff + 1 < msecs) {
- list.start(msecs - diff, 0);
- debug(msecs + ' list wait because diff is ' + diff);
- return;
- } else {
- L.remove(first);
- assert(first !== L.peek(list));
-
- if (!first._onTimeout) continue;
-
- // v0.4 compatibility: if the timer callback throws and the user's
- // uncaughtException handler ignores the exception, other timers that
- // expire on this tick should still run. If #2582 goes through, this
- // hack should be removed.
- //
- // https://github.com/joyent/node/issues/2631
- if (first.domain) {
- if (first.domain._disposed) continue;
- first.domain.enter();
- }
- try {
- first._onTimeout();
- } catch (e) {
- if (!process.listeners('uncaughtException').length) throw e;
- process.emit('uncaughtException', e);
- }
- if (first.domain) first.domain.exit();
+ var now = Date.now();
+ debug('now: ' + now);
+
+ var first;
+ while (first = L.peek(list)) {
+ var diff = now - first._idleStart;
+ if (diff + 1 < msecs) {
+ list.start(msecs - diff, 0);
+ debug(msecs + ' list wait because diff is ' + diff);
+ return;
+ } else {
+ L.remove(first);
+ assert(first !== L.peek(list));
+
+ if (!first._onTimeout) continue;
+
+ // v0.4 compatibility: if the timer callback throws and the
+ // domain or uncaughtException handler ignore the exception,
+ // other timers that expire on this tick should still run.
+ //
+ // https://github.com/joyent/node/issues/2631
+ var domain = first.domain;
+ if (domain && domain._disposed) continue;
+ try {
+ if (domain)
+ domain.enter();
+ var threw = true;
+ first._onTimeout();
+ if (domain)
+ domain.exit();
+ threw = false;
+ } finally {
+ if (threw) {
+ process.nextTick(function() {
+ list.ontimeout();
+ });
}
}
-
- debug(msecs + ' list empty');
- assert(L.isEmpty(list));
- list.close();
- delete lists[msecs];
- };
+ }
}
- L.append(list, item);
- assert(!L.isEmpty(list)); // list is not empty
+ debug(msecs + ' list empty');
+ assert(L.isEmpty(list));
+ list.close();
+ delete lists[msecs];
}
@@ -151,11 +160,12 @@ exports.enroll = function(item, msecs) {
exports.active = function(item) {
var msecs = item._idleTimeout;
if (msecs >= 0) {
+
var list = lists[msecs];
if (!list || L.isEmpty(list)) {
insert(item, msecs);
} else {
- item._idleStart = new Date();
+ item._idleStart = Date.now();
L.append(list, item);
}
}
@@ -176,9 +186,7 @@ exports.setTimeout = function(callback, after) {
after = 1; // schedule on next tick, follows browser behaviour
}
- timer = { _idleTimeout: after };
- timer._idlePrev = timer;
- timer._idleNext = timer;
+ timer = new Timeout(after);
if (arguments.length <= 2) {
timer._onTimeout = callback;
@@ -209,7 +217,7 @@ exports.setTimeout = function(callback, after) {
exports.clearTimeout = function(timer) {
if (timer && (timer.ontimeout || timer._onTimeout)) {
timer.ontimeout = timer._onTimeout = null;
- if (timer instanceof Timer) {
+ if (timer instanceof Timer || timer instanceof Timeout) {
timer.close(); // for after === 0
} else {
exports.unenroll(timer);
@@ -245,3 +253,102 @@ exports.clearInterval = function(timer) {
timer.close();
}
};
+
+var Timeout = function(after) {
+ this._idleTimeout = after;
+ this._idlePrev = this;
+ this._idleNext = this;
+ this._when = Date.now() + after;
+};
+
+Timeout.prototype.unref = function() {
+ if (!this._handle) {
+ var delay = this._when - Date.now();
+ if (delay < 0) delay = 0;
+ exports.unenroll(this);
+ this._handle = new Timer();
+ this._handle.ontimeout = this._onTimeout;
+ this._handle.start(delay, 0);
+ this._handle.domain = this.domain;
+ this._handle.unref();
+ } else {
+ this._handle.unref();
+ }
+};
+
+Timeout.prototype.ref = function() {
+ if (this._handle)
+ this._handle.ref();
+};
+
+Timeout.prototype.close = function() {
+ this._onTimeout = null;
+ if (this._handle) {
+ this._handle.ontimeout = null;
+ this._handle.close();
+ } else {
+ exports.unenroll(this);
+ }
+};
+
+
+var immediateQueue = {};
+L.init(immediateQueue);
+
+
+function processImmediate() {
+ var immediate = L.shift(immediateQueue);
+
+ if (L.isEmpty(immediateQueue)) {
+ process._needImmediateCallback = false;
+ }
+
+ if (immediate._onImmediate) {
+ if (immediate.domain) immediate.domain.enter();
+
+ immediate._onImmediate();
+
+ if (immediate.domain) immediate.domain.exit();
+ }
+}
+
+
+exports.setImmediate = function(callback) {
+ var immediate = {}, args;
+
+ L.init(immediate);
+
+ immediate._onImmediate = callback;
+
+ if (arguments.length > 1) {
+ args = Array.prototype.slice.call(arguments, 1);
+
+ immediate._onImmediate = function() {
+ callback.apply(null, args);
+ };
+ }
+
+ if (!process._needImmediateCallback) {
+ process._needImmediateCallback = true;
+ process._immediateCallback = processImmediate;
+ }
+
+ if (process.domain) immediate.domain = process.domain;
+
+ L.append(immediateQueue, immediate);
+
+ return immediate;
+};
+
+
+exports.clearImmediate = function(immediate) {
+ if (!immediate) return;
+
+ immediate._onImmediate = undefined;
+
+ L.remove(immediate);
+
+ if (L.isEmpty(immediateQueue)) {
+ process._needImmediateCallback = false;
+ }
+};
diff --git a/lib/tls.js b/lib/tls.js
index 79e667513..2a780373a 100644
--- a/lib/tls.js
+++ b/lib/tls.js
@@ -24,8 +24,7 @@ var util = require('util');
var net = require('net');
var url = require('url');
var events = require('events');
-var Stream = require('stream');
-var END_OF_FILE = 42;
+var stream = require('stream');
var assert = require('assert').ok;
var constants = require('constants');
@@ -39,6 +38,8 @@ var DEFAULT_CIPHERS = 'ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:' + // TLS 1.2
exports.CLIENT_RENEG_LIMIT = 3;
exports.CLIENT_RENEG_WINDOW = 600;
+exports.SLAB_BUFFER_SIZE = 10 * 1024 * 1024;
+
var debug;
if (process.env.NODE_DEBUG && /tls/.test(process.env.NODE_DEBUG)) {
@@ -194,7 +195,6 @@ function checkServerIdentity(host, cert) {
exports.checkServerIdentity = checkServerIdentity;
-
function SlabBuffer() {
this.create();
}
@@ -202,20 +202,23 @@ function SlabBuffer() {
SlabBuffer.prototype.create = function create() {
this.isFull = false;
- this.pool = new Buffer(10 * 1024 * 1024);
+ this.pool = new Buffer(exports.SLAB_BUFFER_SIZE);
this.offset = 0;
this.remaining = this.pool.length;
};
-SlabBuffer.prototype.use = function use(context, fn) {
+SlabBuffer.prototype.use = function use(context, fn, size) {
if (this.remaining === 0) {
this.isFull = true;
return 0;
}
- var bytes = fn.call(context, this.pool, this.offset, this.remaining);
+ var actualSize = this.remaining;
+ if (size !== null) actualSize = Math.min(size, actualSize);
+
+ var bytes = fn.call(context, this.pool, this.offset, actualSize);
if (bytes > 0) {
this.offset += bytes;
this.remaining -= bytes;
@@ -227,96 +230,236 @@ SlabBuffer.prototype.use = function use(context, fn) {
};
-var slabBuffer = new SlabBuffer();
+var slabBuffer = null;
// Base class of both CleartextStream and EncryptedStream
-function CryptoStream(pair) {
- Stream.call(this);
+function CryptoStream(pair, options) {
+ stream.Duplex.call(this, options);
this.pair = pair;
+ this._pending = null;
+ this._pendingCallback = null;
+ this._doneFlag = false;
+ this._resumingSession = false;
+ this._reading = true;
+ this._destroyed = false;
+ this._ended = false;
+ this._finished = false;
+ this._opposite = null;
+
+ if (slabBuffer === null) slabBuffer = new SlabBuffer();
+ this._buffer = slabBuffer;
- this.readable = this.writable = true;
+ this.once('finish', onCryptoStreamFinish);
- this._paused = false;
- this._needDrain = false;
- this._pending = [];
- this._pendingCallbacks = [];
- this._pendingBytes = 0;
- this._buffer = slabBuffer;
+ // net.Socket calls .onend too
+ this.once('end', onCryptoStreamEnd);
}
-util.inherits(CryptoStream, Stream);
+util.inherits(CryptoStream, stream.Duplex);
-CryptoStream.prototype.write = function(data /* , encoding, cb */) {
- if (this == this.pair.cleartext) {
- debug('cleartext.write called with ' + data.length + ' bytes');
+function onCryptoStreamFinish() {
+ this._finished = true;
+
+ if (this === this.pair.cleartext) {
+ debug('cleartext.onfinish');
+ if (this.pair.ssl) {
+ // Generate close notify
+ // NOTE: first call checks if client has sent us shutdown,
+ // second call enqueues shutdown into the BIO.
+ if (this.pair.ssl.shutdown() !== 1) {
+ this.pair.ssl.shutdown();
+ }
+ }
} else {
- debug('encrypted.write called with ' + data.length + ' bytes');
+ debug('encrypted.onfinish');
}
- if (!this.writable) {
- throw new Error('CryptoStream is not writable');
- }
+ // Try to read just to get sure that we won't miss EOF
+ if (this._opposite.readable) this._opposite.read(0);
- var encoding, cb;
+ if (this._opposite._ended) {
+ this._done();
- // parse arguments
- if (typeof arguments[1] == 'string') {
- encoding = arguments[1];
- cb = arguments[2];
- } else {
- cb = arguments[1];
+ // No half-close, sorry
+ if (this === this.pair.cleartext) this._opposite._done();
}
+}
- // Transform strings into buffers.
- if (typeof data == 'string') {
- data = new Buffer(data, encoding);
+function onCryptoStreamEnd() {
+ this._ended = true;
+ if (this === this.pair.cleartext) {
+ debug('cleartext.onend');
+ } else {
+ debug('encrypted.onend');
}
- debug((this === this.pair.cleartext ? 'clear' : 'encrypted') + 'In data');
+ if (this.onend) this.onend();
+}
+
- this._pending.push(data);
- this._pendingCallbacks.push(cb);
- this._pendingBytes += data.length;
+CryptoStream.prototype._write = function write(data, cb) {
+ assert(this._pending === null);
- this.pair._writeCalled = true;
- this.pair.cycle();
+ // Black-hole data
+ if (!this.pair.ssl) return cb(null);
- // In the following cases, write() should return a false,
- // then this stream should eventually emit 'drain' event.
- //
- // 1. There are pending data more than 128k bytes.
- // 2. A forward stream shown below is paused.
- // A) EncryptedStream for CleartextStream.write().
- // B) CleartextStream for EncryptedStream.write().
+ // When resuming session don't accept any new data.
+ // And do not put too much data into openssl, before writing it from encrypted
+ // side.
//
- if (!this._needDrain) {
- if (this._pendingBytes >= 128 * 1024) {
- this._needDrain = true;
+ // TODO(indutny): Remove magic number, use watermark based limits
+ if (!this._resumingSession &&
+ this._opposite._internallyPendingBytes() < 128 * 1024) {
+ // Write current buffer now
+ var written;
+ if (this === this.pair.cleartext) {
+ debug('cleartext.write called with ' + data.length + ' bytes');
+ written = this.pair.ssl.clearIn(data, 0, data.length);
} else {
+ debug('encrypted.write called with ' + data.length + ' bytes');
+ written = this.pair.ssl.encIn(data, 0, data.length);
+ }
+
+ var self = this;
+
+ // Force SSL_read call to cycle some states/data inside OpenSSL
+ this.pair.cleartext.read(0);
+
+ // Cycle encrypted data
+ if (this.pair.encrypted._internallyPendingBytes()) {
+ this.pair.encrypted.read(0);
+ }
+
+ // Handle and report errors
+ if (this.pair.ssl && this.pair.ssl.error) {
+ return cb(this.pair.error());
+ }
+
+ // Get NPN and Server name when ready
+ this.pair.maybeInitFinished();
+
+ // Whole buffer was written
+ if (written === data.length) {
if (this === this.pair.cleartext) {
- this._needDrain = this.pair.encrypted._paused;
+ debug('cleartext.write succeed with ' + data.length + ' bytes');
} else {
- this._needDrain = this.pair.cleartext._paused;
+ debug('encrypted.write succeed with ' + data.length + ' bytes');
}
+
+ return cb(null);
}
+ assert(written === 0 || written === -1);
+ } else {
+ debug('cleartext.write queue is full');
+
+ // Force SSL_read call to cycle some states/data inside OpenSSL
+ this.pair.cleartext.read(0);
+ }
+
+ // No write has happened
+ this._pending = data;
+ this._pendingCallback = cb;
+
+ if (this === this.pair.cleartext) {
+ debug('cleartext.write queued with ' + data.length + ' bytes');
+ } else {
+ debug('encrypted.write queued with ' + data.length + ' bytes');
}
- return !this._needDrain;
};
-CryptoStream.prototype.pause = function() {
- debug('paused ' + (this == this.pair.cleartext ? 'cleartext' : 'encrypted'));
- this._paused = true;
+CryptoStream.prototype._writePending = function writePending() {
+ var data = this._pending,
+ cb = this._pendingCallback;
+
+ this._pending = null;
+ this._pendingCallback = null;
+ this._write(data, cb);
};
-CryptoStream.prototype.resume = function() {
- debug('resume ' + (this == this.pair.cleartext ? 'cleartext' : 'encrypted'));
- this._paused = false;
- this.pair.cycle();
+CryptoStream.prototype._read = function read(size, cb) {
+ // XXX: EOF?!
+ if (!this.pair.ssl) return cb(null, null);
+
+ // Wait for session to be resumed
+ if (this._resumingSession || !this._reading) return cb(null, '');
+
+ var out;
+ if (this === this.pair.cleartext) {
+ debug('cleartext.read called with ' + size + ' bytes');
+ out = this.pair.ssl.clearOut;
+ } else {
+ debug('encrypted.read called with ' + size + ' bytes');
+ out = this.pair.ssl.encOut;
+ }
+
+ var bytesRead = 0,
+ start = this._buffer.offset;
+ do {
+ var read = this._buffer.use(this.pair.ssl, out, size);
+ if (read > 0) {
+ bytesRead += read;
+ size -= read;
+ }
+
+ // Handle and report errors
+ if (this.pair.ssl && this.pair.ssl.error) {
+ this.pair.error();
+ break;
+ }
+
+ // Get NPN and Server name when ready
+ this.pair.maybeInitFinished();
+ } while (read > 0 && !this._buffer.isFull && bytesRead < size);
+
+ // Create new buffer if previous was filled up
+ var pool = this._buffer.pool;
+ if (this._buffer.isFull) this._buffer.create();
+
+ assert(bytesRead >= 0);
+
+ if (this === this.pair.cleartext) {
+ debug('cleartext.read succeed with ' + bytesRead + ' bytes');
+ } else {
+ debug('encrypted.read succeed with ' + bytesRead + ' bytes');
+ }
+
+ // Try writing pending data
+ if (this._pending !== null) this._writePending();
+
+ if (bytesRead === 0) {
+ // EOF when cleartext has finished and we have nothing to read
+ if (this._opposite._finished && this._internallyPendingBytes() === 0) {
+ // Perform graceful shutdown
+ this._done();
+
+ // No half-open, sorry!
+ if (this === this.pair.cleartext)
+ this._opposite._done();
+
+ return cb(null, null);
+ }
+
+ // Bail out
+ return cb(null, '');
+ }
+
+ // Give them requested data
+ if (this.ondata) {
+ var self = this;
+ this.ondata(pool, start, start + bytesRead);
+
+ // Consume data automatically
+ // simple/test-https-drain fails without it
+ process.nextTick(function() {
+ self.read(bytesRead);
+ });
+ }
+ return cb(null, pool.slice(start, start + bytesRead));
};
@@ -334,11 +477,9 @@ CryptoStream.prototype.setKeepAlive = function(enable, initialDelay) {
if (this.socket) this.socket.setKeepAlive(enable, initialDelay);
};
-
-CryptoStream.prototype.setEncoding = function(encoding) {
- var StringDecoder = require('string_decoder').StringDecoder; // lazy load
- this._decoder = new StringDecoder(encoding);
-};
+CryptoStream.prototype.__defineGetter__('bytesWritten', function() {
+ return this.socket ? this.socket.bytesWritten : 0;
+});
// Example:
@@ -404,53 +545,74 @@ CryptoStream.prototype.getCipher = function(err) {
};
-CryptoStream.prototype.end = function(d) {
- if (this.pair._doneFlag) return;
- if (!this.writable) return;
-
- if (d) {
- this.write(d);
+CryptoStream.prototype.end = function(chunk, encoding) {
+ if (this === this.pair.cleartext) {
+ debug('cleartext.end');
+ } else {
+ debug('encrypted.end');
}
- this._pending.push(END_OF_FILE);
- this._pendingCallbacks.push(null);
-
- // If this is an encrypted stream then we need to disable further 'data'
- // events.
+ // Write pending data first
+ if (this._pending !== null) this._writePending();
this.writable = false;
- this.pair.cycle();
+ stream.Duplex.prototype.end.call(this, chunk, encoding);
};
CryptoStream.prototype.destroySoon = function(err) {
- if (this.writable) {
- this.end();
+ if (this === this.pair.cleartext) {
+ debug('cleartext.destroySoon');
} else {
- this.destroy();
+ debug('encrypted.destroySoon');
}
+
+ if (this.writable)
+ this.end();
+
+ if (this._writableState.finishing || this._writableState.finished)
+ this.destroy();
+ else
+ this.once('finish', this.destroy);
};
CryptoStream.prototype.destroy = function(err) {
- if (this.pair._doneFlag) return;
- this.pair.destroy();
+ if (this._destroyed) return;
+ this._destroyed = true;
+ this.readable = this.writable = false;
+
+ // Destroy both ends
+ if (this === this.pair.cleartext) {
+ debug('cleartext.destroy');
+ } else {
+ debug('encrypted.destroy');
+ }
+ this._opposite.destroy();
+
+ var self = this;
+ process.nextTick(function() {
+ // Force EOF
+ self.push(null);
+
+ // Emit 'close' event
+ self.emit('close', err ? true : false);
+ });
};
CryptoStream.prototype._done = function() {
this._doneFlag = true;
+ if (this === this.pair.encrypted && !this.pair._secureEstablished)
+ return this.pair.error();
+
if (this.pair.cleartext._doneFlag &&
this.pair.encrypted._doneFlag &&
!this.pair._doneFlag) {
// If both streams are done:
- if (!this.pair._secureEstablished) {
- this.pair.error();
- } else {
- this.pair.destroy();
- }
+ this.pair.destroy();
}
};
@@ -473,182 +635,20 @@ Object.defineProperty(CryptoStream.prototype, 'readyState', {
});
-// Move decrypted, clear data out into the application.
-// From the user's perspective this occurs as a 'data' event
-// on the pair.cleartext.
-// also
-// Move encrypted data to the stream. From the user's perspective this
-// occurs as a 'data' event on the pair.encrypted. Usually the application
-// will have some code which pipes the stream to a socket:
-//
-// pair.encrypted.on('data', function (d) {
-// socket.write(d);
-// });
-//
-CryptoStream.prototype._push = function() {
- if (this == this.pair.encrypted && !this.writable) {
- // If the encrypted side got EOF, we do not attempt
- // to write out data anymore.
- return;
- }
-
- while (!this._paused) {
- var chunkBytes = 0,
- bytesRead = 0,
- start = this._buffer.offset;
-
- do {
- chunkBytes = this._buffer.use(this, this._pusher);
- if (chunkBytes > 0) bytesRead += chunkBytes;
-
- if (this.pair.ssl && this.pair.ssl.error) {
- this.pair.error();
- return;
- }
-
- this.pair.maybeInitFinished();
-
- } while (chunkBytes > 0 && !this._buffer.isFull);
-
- var pool = this._buffer.pool;
-
- // Create new buffer if previous was filled up
- if (this._buffer.isFull) this._buffer.create();
-
- assert(bytesRead >= 0);
-
- // Bail out if we didn't read any data.
- if (bytesRead == 0) {
- if (this._internallyPendingBytes() == 0 && this._destroyAfterPush) {
- this._done();
- }
- return;
- }
-
- var chunk = pool.slice(start, start + bytesRead);
-
- if (this === this.pair.cleartext) {
- debug('cleartext emit "data" with ' + bytesRead + ' bytes');
- } else {
- debug('encrypted emit "data" with ' + bytesRead + ' bytes');
- }
-
- if (this._decoder) {
- var string = this._decoder.write(chunk);
- if (string.length) this.emit('data', string);
- } else {
- this.emit('data', chunk);
- }
-
- // Optimization: emit the original buffer with end points
- if (this.ondata) this.ondata(pool, start, start + bytesRead);
- }
-};
-
-
-// Push in any clear data coming from the application.
-// This arrives via some code like this:
-//
-// pair.cleartext.write("hello world");
-//
-// also
-//
-// Push in incoming encrypted data from the socket.
-// This arrives via some code like this:
-//
-// socket.on('data', function (d) {
-// pair.encrypted.write(d)
-// });
-//
-CryptoStream.prototype._pull = function() {
- var havePending = this._pending.length > 0;
-
- assert(havePending || this._pendingBytes == 0);
-
- while (this._pending.length > 0) {
- if (!this.pair.ssl) break;
-
- var tmp = this._pending.shift();
- var cb = this._pendingCallbacks.shift();
-
- assert(this._pending.length === this._pendingCallbacks.length);
-
- if (tmp === END_OF_FILE) {
- // Sending EOF
- if (this === this.pair.encrypted) {
- debug('end encrypted ' + this.pair.fd);
- this.pair.cleartext._destroyAfterPush = true;
- } else {
- // CleartextStream
- assert(this === this.pair.cleartext);
- debug('end cleartext');
-
- this.pair.ssl.shutdown();
-
- // TODO check if we get EAGAIN From shutdown, would have to do it
- // again. should unshift END_OF_FILE back onto pending and wait for
- // next cycle.
-
- this.pair.encrypted._destroyAfterPush = true;
- }
- this.pair.cycle();
- this._done();
- return;
- }
-
- if (tmp.length == 0) continue;
+function CleartextStream(pair, options) {
+ CryptoStream.call(this, pair, options);
- var rv = this._puller(tmp);
-
- if (this.pair.ssl && this.pair.ssl.error) {
- this.pair.error();
- return;
- }
-
- this.pair.maybeInitFinished();
-
- if (rv === 0 || rv < 0) {
- this._pending.unshift(tmp);
- this._pendingCallbacks.unshift(cb);
- break;
- }
-
- this._pendingBytes -= tmp.length;
- assert(this._pendingBytes >= 0);
-
- if (cb) cb();
-
- assert(rv === tmp.length);
- }
-
- // If pending data has cleared, 'drain' event should be emitted
- // after write() returns a false.
- // Except when a forward stream shown below is paused.
- // A) EncryptedStream for CleartextStream._pull().
- // B) CleartextStream for EncryptedStream._pull().
- //
- if (this._needDrain && this._pending.length === 0) {
- var paused;
- if (this === this.pair.cleartext) {
- paused = this.pair.encrypted._paused;
- } else {
- paused = this.pair.cleartext._paused;
- }
- if (!paused) {
- debug('drain ' + (this === this.pair.cleartext ? 'clear' : 'encrypted'));
- var self = this;
- process.nextTick(function() {
- self.emit('drain');
- });
- this._needDrain = false;
- if (this.__destroyOnDrain) this.end();
+ var self = this;
+ this._handle = {
+ readStop: function() {
+ self._reading = false;
+ },
+ readStart: function() {
+ if (self._reading) return;
+ self._reading = true;
+ self.read(0);
}
- }
-};
-
-
-function CleartextStream(pair) {
- CryptoStream.call(this, pair);
+ };
}
util.inherits(CleartextStream, CryptoStream);
@@ -662,22 +662,11 @@ CleartextStream.prototype._internallyPendingBytes = function() {
};
-CleartextStream.prototype._puller = function(b) {
- debug('clearIn ' + b.length + ' bytes');
- return this.pair.ssl.clearIn(b, 0, b.length);
-};
-
-
-CleartextStream.prototype._pusher = function(pool, offset, length) {
- debug('reading from clearOut');
- if (!this.pair.ssl) return -1;
- return this.pair.ssl.clearOut(pool, offset, length);
-};
-
CleartextStream.prototype.address = function() {
return this.socket && this.socket.address();
};
+
CleartextStream.prototype.__defineGetter__('remoteAddress', function() {
return this.socket && this.socket.remoteAddress;
});
@@ -687,9 +676,8 @@ CleartextStream.prototype.__defineGetter__('remotePort', function() {
return this.socket && this.socket.remotePort;
});
-
-function EncryptedStream(pair) {
- CryptoStream.call(this, pair);
+function EncryptedStream(pair, options) {
+ CryptoStream.call(this, pair, options);
}
util.inherits(EncryptedStream, CryptoStream);
@@ -703,35 +691,28 @@ EncryptedStream.prototype._internallyPendingBytes = function() {
};
-EncryptedStream.prototype._puller = function(b) {
- debug('writing from encIn');
- return this.pair.ssl.encIn(b, 0, b.length);
-};
-
-
-EncryptedStream.prototype._pusher = function(pool, offset, length) {
- debug('reading from encOut');
- if (!this.pair.ssl) return -1;
- return this.pair.ssl.encOut(pool, offset, length);
-};
-
-
function onhandshakestart() {
debug('onhandshakestart');
- var self = this, ssl = this.ssl;
+ var self = this;
+ var ssl = self.ssl;
+ var now = Date.now();
+
+ assert(now >= ssl.lastHandshakeTime);
- if (ssl.timer === null) {
- ssl.timer = setTimeout(function timeout() {
- ssl.handshakes = 0;
- ssl.timer = null;
- }, exports.CLIENT_RENEG_WINDOW * 1000);
+ if ((now - ssl.lastHandshakeTime) >= exports.CLIENT_RENEG_WINDOW * 1000) {
+ ssl.handshakes = 0;
}
- else if (++ssl.handshakes > exports.CLIENT_RENEG_LIMIT) {
+
+ var first = (ssl.lastHandshakeTime === 0);
+ ssl.lastHandshakeTime = now;
+ if (first) return;
+
+ if (++ssl.handshakes > exports.CLIENT_RENEG_LIMIT) {
// Defer the error event to the next tick. We're being called from OpenSSL's
// state machine and OpenSSL is not re-entrant. We cannot allow the user's
// callback to destroy the connection right now, it would crash and burn.
- process.nextTick(function() {
+ setImmediate(function() {
var err = new Error('TLS session renegotiation attack detected.');
if (self.cleartext) self.cleartext.emit('error', err);
});
@@ -745,6 +726,39 @@ function onhandshakedone() {
}
+function onclienthello(hello) {
+ var self = this,
+ once = false;
+
+ this._resumingSession = true;
+ function callback(err, session) {
+ if (once) return;
+ once = true;
+
+ if (err) return self.socket.destroy(err);
+
+ self.ssl.loadSession(session);
+
+ // Cycle data
+ self._resumingSession = false;
+ self.cleartext.read(0);
+ self.encrypted.read(0);
+ }
+
+ if (hello.sessionId.length <= 0 ||
+ !this.server ||
+ !this.server.emit('resumeSession', hello.sessionId, callback)) {
+ callback(null, null);
+ }
+}
+
+
+function onnewsession(key, session) {
+ if (!this.server) return;
+ this.server.emit('newSession', key, session);
+}
+
+
/**
* Provides a pair of streams to do encrypted communication.
*/
@@ -765,11 +779,13 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
events.EventEmitter.call(this);
+ this.server = options.server;
this._secureEstablished = false;
this._isServer = isServer ? true : false;
this._encWriteState = true;
this._clearWriteState = true;
this._doneFlag = false;
+ this._destroying = false;
if (!credentials) {
this.credentials = crypto.createCredentials();
@@ -787,15 +803,18 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
this._requestCert = requestCert ? true : false;
this.ssl = new Connection(this.credentials.context,
- this._isServer ? true : false,
- this._isServer ? this._requestCert : options.servername,
- this._rejectUnauthorized);
+ this._isServer ? true : false,
+ this._isServer ? this._requestCert :
+ options.servername,
+ this._rejectUnauthorized);
if (this._isServer) {
this.ssl.onhandshakestart = onhandshakestart.bind(this);
this.ssl.onhandshakedone = onhandshakedone.bind(this);
+ this.ssl.onclienthello = onclienthello.bind(this);
+ this.ssl.onnewsession = onnewsession.bind(this);
+ this.ssl.lastHandshakeTime = 0;
this.ssl.handshakes = 0;
- this.ssl.timer = null;
}
if (process.features.tls_sni) {
@@ -811,17 +830,20 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
}
/* Acts as a r/w stream to the cleartext side of the stream. */
- this.cleartext = new CleartextStream(this);
+ this.cleartext = new CleartextStream(this, options.cleartext);
/* Acts as a r/w stream to the encrypted side of the stream. */
- this.encrypted = new EncryptedStream(this);
+ this.encrypted = new EncryptedStream(this, options.encrypted);
+
+ /* Let streams know about each other */
+ this.cleartext._opposite = this.encrypted;
+ this.encrypted._opposite = this.cleartext;
process.nextTick(function() {
/* The Connection may be destroyed by an abort call */
if (self.ssl) {
self.ssl.start();
}
- self.cycle();
});
}
@@ -840,81 +862,6 @@ exports.createSecurePair = function(credentials,
};
-
-
-/* Attempt to cycle OpenSSLs buffers in various directions.
- *
- * An SSL Connection can be viewed as four separate piplines,
- * interacting with one has no connection to the behavoir of
- * any of the other 3 -- This might not sound reasonable,
- * but consider things like mid-stream renegotiation of
- * the ciphers.
- *
- * The four pipelines, using terminology of the client (server is just
- * reversed):
- * (1) Encrypted Output stream (Writing encrypted data to peer)
- * (2) Encrypted Input stream (Reading encrypted data from peer)
- * (3) Cleartext Output stream (Decrypted content from the peer)
- * (4) Cleartext Input stream (Cleartext content to send to the peer)
- *
- * This function attempts to pull any available data out of the Cleartext
- * input stream (4), and the Encrypted input stream (2). Then it pushes any
- * data available from the cleartext output stream (3), and finally from the
- * Encrypted output stream (1)
- *
- * It is called whenever we do something with OpenSSL -- post reciving
- * content, trying to flush, trying to change ciphers, or shutting down the
- * connection.
- *
- * Because it is also called everywhere, we also check if the connection has
- * completed negotiation and emit 'secure' from here if it has.
- */
-SecurePair.prototype.cycle = function(depth) {
- if (this._doneFlag) return;
-
- depth = depth ? depth : 0;
-
- if (depth == 0) this._writeCalled = false;
-
- var established = this._secureEstablished;
-
- if (!this.cycleEncryptedPullLock) {
- this.cycleEncryptedPullLock = true;
- debug('encrypted._pull');
- this.encrypted._pull();
- this.cycleEncryptedPullLock = false;
- }
-
- if (!this.cycleCleartextPullLock) {
- this.cycleCleartextPullLock = true;
- debug('cleartext._pull');
- this.cleartext._pull();
- this.cycleCleartextPullLock = false;
- }
-
- if (!this.cycleCleartextPushLock) {
- this.cycleCleartextPushLock = true;
- debug('cleartext._push');
- this.cleartext._push();
- this.cycleCleartextPushLock = false;
- }
-
- if (!this.cycleEncryptedPushLock) {
- this.cycleEncryptedPushLock = true;
- debug('encrypted._push');
- this.encrypted._push();
- this.cycleEncryptedPushLock = false;
- }
-
- if ((!established && this._secureEstablished) ||
- (depth == 0 && this._writeCalled)) {
- // If we were not established but now we are, let's cycle again.
- // Or if there is some data to write...
- this.cycle(depth + 1);
- }
-};
-
-
SecurePair.prototype.maybeInitFinished = function() {
if (this.ssl && !this._secureEstablished && this.ssl.isInitFinished()) {
if (process.features.tls_npn) {
@@ -933,28 +880,20 @@ SecurePair.prototype.maybeInitFinished = function() {
SecurePair.prototype.destroy = function() {
- var self = this;
+ if (this._destroying) return;
if (!this._doneFlag) {
- this._doneFlag = true;
+ debug('SecurePair.destroy');
+ this._destroying = true;
- if (this.ssl.timer) {
- clearTimeout(this.ssl.timer);
- this.ssl.timer = null;
- }
+ // SecurePair should be destroyed only after it's streams
+ this.cleartext.destroy();
+ this.encrypted.destroy();
+ this._doneFlag = true;
this.ssl.error = null;
this.ssl.close();
this.ssl = null;
-
- self.encrypted.writable = self.encrypted.readable = false;
- self.cleartext.writable = self.cleartext.readable = false;
-
- process.nextTick(function() {
- self.cleartext.emit('end');
- self.encrypted.emit('close');
- self.cleartext.emit('close');
- });
}
};
@@ -968,6 +907,7 @@ SecurePair.prototype.error = function() {
}
this.destroy();
this.emit('error', error);
+ return error;
} else {
var err = this.ssl.error;
this.ssl.error = null;
@@ -980,6 +920,8 @@ SecurePair.prototype.error = function() {
} else {
this.cleartext.emit('error', err);
}
+
+ return err;
}
};
@@ -1022,13 +964,13 @@ SecurePair.prototype.error = function() {
// If true clients whose certificates are invalid for any reason will not
// be allowed to make connections. If false, they will simply be marked as
// unauthorized but secure communication will continue. By default this is
-// false.
+// true.
//
//
//
// Options:
// - requestCert. Send verify request. Default to false.
-// - rejectUnauthorized. Boolean, default to false.
+// - rejectUnauthorized. Boolean, default to true.
// - key. string.
// - cert: string.
// - ca: string or array of strings.
@@ -1077,6 +1019,10 @@ function Server(/* [options], listener */) {
// Handle option defaults:
this.setOptions(options);
+ if (!self.pfx && (!self.cert || !self.key)) {
+ throw new Error('Missing PFX or certificate + private key.');
+ }
+
var sharedCreds = crypto.createCredentials({
pfx: self.pfx,
key: self.key,
@@ -1090,6 +1036,12 @@ function Server(/* [options], listener */) {
sessionIdContext: self.sessionIdContext
});
+ var timeout = options.handshakeTimeout || (120 * 1000);
+
+ if (typeof timeout !== 'number') {
+ throw new TypeError('handshakeTimeout must be a number');
+ }
+
// constructor call
net.Server.call(this, function(socket) {
var creds = crypto.createCredentials(null, sharedCreds.context);
@@ -1099,14 +1051,29 @@ function Server(/* [options], listener */) {
self.requestCert,
self.rejectUnauthorized,
{
+ server: self,
NPNProtocols: self.NPNProtocols,
- SNICallback: self.SNICallback
+ SNICallback: self.SNICallback,
+
+ // Stream options
+ cleartext: self._cleartext,
+ encrypted: self._encrypted
});
var cleartext = pipe(pair, socket);
cleartext._controlReleased = false;
- pair.on('secure', function() {
+ function listener() {
+ pair.emit('error', new Error('TLS handshake timeout'));
+ }
+
+ if (timeout > 0) {
+ socket.setTimeout(timeout, listener);
+ }
+
+ pair.once('secure', function() {
+ socket.setTimeout(0, listener);
+
pair.cleartext.authorized = false;
pair.cleartext.npnProtocol = pair.npnProtocol;
pair.cleartext.servername = pair.servername;
@@ -1134,7 +1101,7 @@ function Server(/* [options], listener */) {
}
});
pair.on('error', function(err) {
- self.emit('clientError', err);
+ self.emit('clientError', err, this);
});
});
@@ -1189,6 +1156,8 @@ Server.prototype.setOptions = function(options) {
.update(process.argv.join(' '))
.digest('hex');
}
+ if (options.cleartext) this.cleartext = options.cleartext;
+ if (options.encrypted) this.encrypted = options.encrypted;
};
// SNI Contexts High-Level API
@@ -1251,6 +1220,11 @@ exports.connect = function(/* [port, host], options, cb */) {
var options = args[0];
var cb = args[1];
+ var defaults = {
+ rejectUnauthorized: '0' !== process.env.NODE_TLS_REJECT_UNAUTHORIZED
+ };
+ options = util._extend(defaults, options || {});
+
var socket = options.socket ? options.socket : new net.Stream();
var sslcontext = crypto.createCredentials(options);
@@ -1261,11 +1235,16 @@ exports.connect = function(/* [port, host], options, cb */) {
options.rejectUnauthorized === true ? true : false,
{
NPNProtocols: this.NPNProtocols,
- servername: hostname
+ servername: hostname,
+ cleartext: options.cleartext,
+ encrypted: options.encrypted
});
if (options.session) {
- pair.ssl.setSession(options.session);
+ var session = options.session;
+ if (typeof session === 'string')
+ session = new Buffer(session, 'binary');
+ pair.ssl.setSession(session);
}
var cleartext = pipe(pair, socket);
@@ -1331,6 +1310,22 @@ function pipe(pair, socket) {
cleartext.encrypted = pair.encrypted;
cleartext.authorized = false;
+ // cycle the data whenever the socket drains, so that
+ // we can pull some more into it. normally this would
+ // be handled by the fact that pipe() triggers read() calls
+ // on writable.drain, but CryptoStreams are a bit more
+ // complicated. Since the encrypted side actually gets
+ // its data from the cleartext side, we have to give it a
+ // light kick to get in motion again.
+ socket.on('drain', function() {
+ if (pair.encrypted._pending)
+ pair.encrypted._writePending();
+ if (pair.cleartext._pending)
+ pair.cleartext._writePending();
+ pair.encrypted.read(0);
+ pair.cleartext.read(0);
+ });
+
function onerror(e) {
if (cleartext._controlReleased) {
cleartext.emit('error', e);
@@ -1339,7 +1334,6 @@ function pipe(pair, socket) {
function onclose() {
socket.removeListener('error', onerror);
- socket.removeListener('end', onclose);
socket.removeListener('timeout', ontimeout);
}
diff --git a/lib/tty.js b/lib/tty.js
index 9fa18fd38..98d498a17 100644
--- a/lib/tty.js
+++ b/lib/tty.js
@@ -40,47 +40,42 @@ exports.setRawMode = util.deprecate(function(flag) {
}, 'tty.setRawMode: Use `process.stdin.setRawMode()` instead.');
-function ReadStream(fd) {
- if (!(this instanceof ReadStream)) return new ReadStream(fd);
- net.Socket.call(this, {
+function ReadStream(fd, options) {
+ if (!(this instanceof ReadStream))
+ return new ReadStream(fd, options);
+
+ options = util._extend({
+ highWaterMark: 0,
+ readable: true,
+ writable: false,
handle: new TTY(fd, true)
- });
+ }, options);
+
+ net.Socket.call(this, options);
- this.readable = true;
- this.writable = false;
this.isRaw = false;
+ this.isTTY = true;
}
inherits(ReadStream, net.Socket);
exports.ReadStream = ReadStream;
-ReadStream.prototype.pause = function() {
- return net.Socket.prototype.pause.call(this);
-};
-
-ReadStream.prototype.resume = function() {
- return net.Socket.prototype.resume.call(this);
-};
-
ReadStream.prototype.setRawMode = function(flag) {
flag = !!flag;
this._handle.setRawMode(flag);
this.isRaw = flag;
};
-ReadStream.prototype.isTTY = true;
-
function WriteStream(fd) {
if (!(this instanceof WriteStream)) return new WriteStream(fd);
net.Socket.call(this, {
- handle: new TTY(fd, false)
+ handle: new TTY(fd, false),
+ readable: false,
+ writable: true
});
- this.readable = false;
- this.writable = true;
-
var winSize = this._handle.getWindowSize();
if (winSize) {
this.columns = winSize[0];
@@ -99,7 +94,7 @@ WriteStream.prototype._refreshSize = function() {
var oldRows = this.rows;
var winSize = this._handle.getWindowSize();
if (!winSize) {
- this.emit('error', errnoException(errno, 'getWindowSize'));
+ this.emit('error', errnoException(process._errno, 'getWindowSize'));
return;
}
var newCols = winSize[0];
diff --git a/lib/url.js b/lib/url.js
index 77686ed0f..b8ba3fb1d 100644
--- a/lib/url.js
+++ b/lib/url.js
@@ -26,6 +26,22 @@ exports.resolve = urlResolve;
exports.resolveObject = urlResolveObject;
exports.format = urlFormat;
+exports.Url = Url;
+
+function Url() {
+ this.protocol = null;
+ this.slashes = null;
+ this.auth = null;
+ this.host = null;
+ this.port = null;
+ this.hostname = null;
+ this.hash = null;
+ this.search = null;
+ this.query = null;
+ this.pathname = null;
+ this.path = null;
+}
+
// Reference: RFC 3986, RFC 1808, RFC 2396
// define these here so at least they only have to be
@@ -90,14 +106,19 @@ var protocolPattern = /^([a-z0-9.+-]+:)/i,
querystring = require('querystring');
function urlParse(url, parseQueryString, slashesDenoteHost) {
- if (url && typeof(url) === 'object' && url.href) return url;
+ if (url && typeof(url) === 'object' && url instanceof Url) return url;
+
+ var u = new Url;
+ u.parse(url, parseQueryString, slashesDenoteHost);
+ return u;
+}
+Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
if (typeof url !== 'string') {
throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
}
- var out = {},
- rest = url;
+ var rest = url;
// trim before proceeding.
// This is to support parse stuff like " http://foo.com \n"
@@ -107,7 +128,7 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
if (proto) {
proto = proto[0];
var lowerProto = proto.toLowerCase();
- out.protocol = lowerProto;
+ this.protocol = lowerProto;
rest = rest.substr(proto.length);
}
@@ -119,7 +140,7 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
var slashes = rest.substr(0, 2) === '//';
if (slashes && !(proto && hostlessProtocol[proto])) {
rest = rest.substr(2);
- out.slashes = true;
+ this.slashes = true;
}
}
@@ -149,7 +170,7 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
if (hasAuth) {
// pluck off the auth portion.
- out.auth = decodeURIComponent(auth);
+ this.auth = decodeURIComponent(auth);
rest = rest.substr(atSign + 1);
}
}
@@ -162,35 +183,28 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
}
if (firstNonHost !== -1) {
- out.host = rest.substr(0, firstNonHost);
+ this.host = rest.substr(0, firstNonHost);
rest = rest.substr(firstNonHost);
} else {
- out.host = rest;
+ this.host = rest;
rest = '';
}
// pull out port.
- var p = parseHost(out.host);
- var keys = Object.keys(p);
- for (var i = 0, l = keys.length; i < l; i++) {
- var key = keys[i];
- out[key] = p[key];
- }
+ this.parseHost();
// we've indicated that there is a hostname,
// so even if it's empty, it has to be present.
- out.hostname = out.hostname || '';
+ this.hostname = this.hostname || '';
// if hostname begins with [ and ends with ]
// assume that it's an IPv6 address.
- var ipv6Hostname = out.hostname[0] === '[' &&
- out.hostname[out.hostname.length - 1] === ']';
+ var ipv6Hostname = this.hostname[0] === '[' &&
+ this.hostname[this.hostname.length - 1] === ']';
// validate a little.
- if (out.hostname.length > hostnameMaxLen) {
- out.hostname = '';
- } else if (!ipv6Hostname) {
- var hostparts = out.hostname.split(/\./);
+ if (!ipv6Hostname) {
+ var hostparts = this.hostname.split(/\./);
for (var i = 0, l = hostparts.length; i < l; i++) {
var part = hostparts[i];
if (!part) continue;
@@ -218,38 +232,44 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
if (notHost.length) {
rest = '/' + notHost.join('.') + rest;
}
- out.hostname = validParts.join('.');
+ this.hostname = validParts.join('.');
break;
}
}
}
}
- // hostnames are always lower case.
- out.hostname = out.hostname.toLowerCase();
+ if (this.hostname.length > hostnameMaxLen) {
+ this.hostname = '';
+ } else {
+ // hostnames are always lower case.
+ this.hostname = this.hostname.toLowerCase();
+ }
if (!ipv6Hostname) {
// IDNA Support: Returns a puny coded representation of "domain".
// It only converts the part of the domain name that
// has non ASCII characters. I.e. it dosent matter if
// you call it with a domain that already is in ASCII.
- var domainArray = out.hostname.split('.');
+ var domainArray = this.hostname.split('.');
var newOut = [];
for (var i = 0; i < domainArray.length; ++i) {
var s = domainArray[i];
newOut.push(s.match(/[^A-Za-z0-9_-]/) ?
'xn--' + punycode.encode(s) : s);
}
- out.hostname = newOut.join('.');
+ this.hostname = newOut.join('.');
}
- out.host = (out.hostname || '') +
- ((out.port) ? ':' + out.port : '');
- out.href += out.host;
+ var p = this.port ? ':' + this.port : '';
+ var h = this.hostname || '';
+ this.host = h + p;
+ this.href += this.host;
// strip [ and ] from the hostname
+ // the host field still retains them, though
if (ipv6Hostname) {
- out.hostname = out.hostname.substr(1, out.hostname.length - 2);
+ this.hostname = this.hostname.substr(1, this.hostname.length - 2);
if (rest[0] !== '/') {
rest = '/' + rest;
}
@@ -278,38 +298,39 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
var hash = rest.indexOf('#');
if (hash !== -1) {
// got a fragment string.
- out.hash = rest.substr(hash);
+ this.hash = rest.substr(hash);
rest = rest.slice(0, hash);
}
var qm = rest.indexOf('?');
if (qm !== -1) {
- out.search = rest.substr(qm);
- out.query = rest.substr(qm + 1);
+ this.search = rest.substr(qm);
+ this.query = rest.substr(qm + 1);
if (parseQueryString) {
- out.query = querystring.parse(out.query);
+ this.query = querystring.parse(this.query);
}
rest = rest.slice(0, qm);
} else if (parseQueryString) {
// no query string, but parseQueryString still requested
- out.search = '';
- out.query = {};
+ this.search = '';
+ this.query = {};
}
- if (rest) out.pathname = rest;
+ if (rest) this.pathname = rest;
if (slashedProtocol[proto] &&
- out.hostname && !out.pathname) {
- out.pathname = '/';
+ this.hostname && !this.pathname) {
+ this.pathname = '/';
}
//to support http.request
- if (out.pathname || out.search) {
- out.path = (out.pathname ? out.pathname : '') +
- (out.search ? out.search : '');
+ if (this.pathname || this.search) {
+ var p = this.pathname || '';
+ var s = this.search || '';
+ this.path = p + s;
}
// finally, reconstruct the href based on what has been validated.
- out.href = urlFormat(out);
- return out;
-}
+ this.href = this.format();
+ return this;
+};
// format a parsed object into a url string
function urlFormat(obj) {
@@ -318,43 +339,47 @@ function urlFormat(obj) {
// this way, you can call url_format() on strings
// to clean up potentially wonky urls.
if (typeof(obj) === 'string') obj = urlParse(obj);
+ if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
+ return obj.format();
+}
- var auth = obj.auth || '';
+Url.prototype.format = function() {
+ var auth = this.auth || '';
if (auth) {
auth = encodeURIComponent(auth);
auth = auth.replace(/%3A/i, ':');
auth += '@';
}
- var protocol = obj.protocol || '',
- pathname = obj.pathname || '',
- hash = obj.hash || '',
+ var protocol = this.protocol || '',
+ pathname = this.pathname || '',
+ hash = this.hash || '',
host = false,
query = '';
- if (obj.host !== undefined) {
- host = auth + obj.host;
- } else if (obj.hostname !== undefined) {
- host = auth + (obj.hostname.indexOf(':') === -1 ?
- obj.hostname :
- '[' + obj.hostname + ']');
- if (obj.port) {
- host += ':' + obj.port;
+ if (this.host) {
+ host = auth + this.host;
+ } else if (this.hostname) {
+ host = auth + (this.hostname.indexOf(':') === -1 ?
+ this.hostname :
+ '[' + this.hostname + ']');
+ if (this.port) {
+ host += ':' + this.port;
}
}
- if (obj.query && typeof obj.query === 'object' &&
- Object.keys(obj.query).length) {
- query = querystring.stringify(obj.query);
+ if (this.query && typeof this.query === 'object' &&
+ Object.keys(this.query).length) {
+ query = querystring.stringify(this.query);
}
- var search = obj.search || (query && ('?' + query)) || '';
+ var search = this.search || (query && ('?' + query)) || '';
if (protocol && protocol.substr(-1) !== ':') protocol += ':';
// only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
// unless they had them to begin with.
- if (obj.slashes ||
+ if (this.slashes ||
(!protocol || slashedProtocol[protocol]) && host !== false) {
host = '//' + (host || '');
if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
@@ -365,40 +390,68 @@ function urlFormat(obj) {
if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
if (search && search.charAt(0) !== '?') search = '?' + search;
+ pathname = pathname.replace(/[?#]/g, function(match) {
+ return encodeURIComponent(match);
+ });
+ search = search.replace('#', '%23');
+
return protocol + host + pathname + search + hash;
-}
+};
function urlResolve(source, relative) {
- return urlFormat(urlResolveObject(source, relative));
+ return urlParse(source, false, true).resolve(relative);
}
+Url.prototype.resolve = function(relative) {
+ return this.resolveObject(urlParse(relative, false, true)).format();
+};
+
function urlResolveObject(source, relative) {
if (!source) return relative;
+ return urlParse(source, false, true).resolveObject(relative);
+}
+
+Url.prototype.resolveObject = function(relative) {
+ if (typeof relative === 'string') {
+ var rel = new Url();
+ rel.parse(relative, false, true);
+ relative = rel;
+ }
- source = urlParse(urlFormat(source), false, true);
- relative = urlParse(urlFormat(relative), false, true);
+ var result = new Url();
+ Object.keys(this).forEach(function(k) {
+ result[k] = this[k];
+ }, this);
// hash is always overridden, no matter what.
- source.hash = relative.hash;
+ // even href="" will remove it.
+ result.hash = relative.hash;
+ // if the relative url is empty, then there's nothing left to do here.
if (relative.href === '') {
- source.href = urlFormat(source);
- return source;
+ result.href = result.format();
+ return result;
}
// hrefs like //foo/bar always cut to the protocol.
if (relative.slashes && !relative.protocol) {
- relative.protocol = source.protocol;
+ // take everything except the protocol from relative
+ Object.keys(relative).forEach(function(k) {
+ if (k !== 'protocol')
+ result[k] = relative[k];
+ });
+
//urlParse appends trailing / to urls like http://www.example.com
- if (slashedProtocol[relative.protocol] &&
- relative.hostname && !relative.pathname) {
- relative.path = relative.pathname = '/';
+ if (slashedProtocol[result.protocol] &&
+ result.hostname && !result.pathname) {
+ result.path = result.pathname = '/';
}
- relative.href = urlFormat(relative);
- return relative;
+
+ result.href = result.format();
+ return result;
}
- if (relative.protocol && relative.protocol !== source.protocol) {
+ if (relative.protocol && relative.protocol !== result.protocol) {
// if it's a known url protocol, then changing
// the protocol does weird things
// first, if it's not file:, then we MUST have a host,
@@ -408,10 +461,14 @@ function urlResolveObject(source, relative) {
// because that's known to be hostless.
// anything else is assumed to be absolute.
if (!slashedProtocol[relative.protocol]) {
- relative.href = urlFormat(relative);
- return relative;
+ Object.keys(relative).forEach(function(k) {
+ result[k] = relative[k];
+ });
+ result.href = result.format();
+ return result;
}
- source.protocol = relative.protocol;
+
+ result.protocol = relative.protocol;
if (!relative.host && !hostlessProtocol[relative.protocol]) {
var relPath = (relative.pathname || '').split('/');
while (relPath.length && !(relative.host = relPath.shift()));
@@ -419,72 +476,72 @@ function urlResolveObject(source, relative) {
if (!relative.hostname) relative.hostname = '';
if (relPath[0] !== '') relPath.unshift('');
if (relPath.length < 2) relPath.unshift('');
- relative.pathname = relPath.join('/');
+ result.pathname = relPath.join('/');
+ } else {
+ result.pathname = relative.pathname;
}
- source.pathname = relative.pathname;
- source.search = relative.search;
- source.query = relative.query;
- source.host = relative.host || '';
- source.auth = relative.auth;
- source.hostname = relative.hostname || relative.host;
- source.port = relative.port;
- //to support http.request
- if (source.pathname !== undefined || source.search !== undefined) {
- source.path = (source.pathname ? source.pathname : '') +
- (source.search ? source.search : '');
+ result.search = relative.search;
+ result.query = relative.query;
+ result.host = relative.host || '';
+ result.auth = relative.auth;
+ result.hostname = relative.hostname || relative.host;
+ result.port = relative.port;
+ // to support http.request
+ if (result.pathname || result.search) {
+ var p = result.pathname || '';
+ var s = result.search || '';
+ result.path = p + s;
}
- source.slashes = source.slashes || relative.slashes;
- source.href = urlFormat(source);
- return source;
+ result.slashes = result.slashes || relative.slashes;
+ result.href = result.format();
+ return result;
}
- var isSourceAbs = (source.pathname && source.pathname.charAt(0) === '/'),
+ var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
isRelAbs = (
- relative.host !== undefined ||
+ relative.host ||
relative.pathname && relative.pathname.charAt(0) === '/'
),
mustEndAbs = (isRelAbs || isSourceAbs ||
- (source.host && relative.pathname)),
+ (result.host && relative.pathname)),
removeAllDots = mustEndAbs,
- srcPath = source.pathname && source.pathname.split('/') || [],
+ srcPath = result.pathname && result.pathname.split('/') || [],
relPath = relative.pathname && relative.pathname.split('/') || [],
- psychotic = source.protocol &&
- !slashedProtocol[source.protocol];
+ psychotic = result.protocol && !slashedProtocol[result.protocol];
// if the url is a non-slashed url, then relative
// links like ../.. should be able
// to crawl up to the hostname, as well. This is strange.
- // source.protocol has already been set by now.
+ // result.protocol has already been set by now.
// Later on, put the first path part into the host field.
if (psychotic) {
-
- delete source.hostname;
- delete source.port;
- if (source.host) {
- if (srcPath[0] === '') srcPath[0] = source.host;
- else srcPath.unshift(source.host);
+ result.hostname = '';
+ result.port = null;
+ if (result.host) {
+ if (srcPath[0] === '') srcPath[0] = result.host;
+ else srcPath.unshift(result.host);
}
- delete source.host;
+ result.host = '';
if (relative.protocol) {
- delete relative.hostname;
- delete relative.port;
+ relative.hostname = null;
+ relative.port = null;
if (relative.host) {
if (relPath[0] === '') relPath[0] = relative.host;
else relPath.unshift(relative.host);
}
- delete relative.host;
+ relative.host = null;
}
mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
}
if (isRelAbs) {
// it's absolute.
- source.host = (relative.host || relative.host === '') ?
- relative.host : source.host;
- source.hostname = (relative.hostname || relative.hostname === '') ?
- relative.hostname : source.hostname;
- source.search = relative.search;
- source.query = relative.query;
+ result.host = (relative.host || relative.host === '') ?
+ relative.host : result.host;
+ result.hostname = (relative.hostname || relative.hostname === '') ?
+ relative.hostname : result.hostname;
+ result.search = relative.search;
+ result.query = relative.query;
srcPath = relPath;
// fall through to the dot-handling below.
} else if (relPath.length) {
@@ -493,53 +550,55 @@ function urlResolveObject(source, relative) {
if (!srcPath) srcPath = [];
srcPath.pop();
srcPath = srcPath.concat(relPath);
- source.search = relative.search;
- source.query = relative.query;
- } else if ('search' in relative) {
+ result.search = relative.search;
+ result.query = relative.query;
+ } else if (relative.search !== null && relative.search !== undefined) {
// just pull out the search.
// like href='?foo'.
// Put this after the other two cases because it simplifies the booleans
if (psychotic) {
- source.hostname = source.host = srcPath.shift();
+ result.hostname = result.host = srcPath.shift();
//occationaly the auth can get stuck only in host
//this especialy happens in cases like
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
- var authInHost = source.host && source.host.indexOf('@') > 0 ?
- source.host.split('@') : false;
+ var authInHost = result.host && result.host.indexOf('@') > 0 ?
+ result.host.split('@') : false;
if (authInHost) {
- source.auth = authInHost.shift();
- source.host = source.hostname = authInHost.shift();
+ result.auth = authInHost.shift();
+ result.host = result.hostname = authInHost.shift();
}
}
- source.search = relative.search;
- source.query = relative.query;
+ result.search = relative.search;
+ result.query = relative.query;
//to support http.request
- if (source.pathname !== undefined || source.search !== undefined) {
- source.path = (source.pathname ? source.pathname : '') +
- (source.search ? source.search : '');
+ if (result.pathname !== null || result.search !== null) {
+ result.path = (result.pathname ? result.pathname : '') +
+ (result.search ? result.search : '');
}
- source.href = urlFormat(source);
- return source;
+ result.href = result.format();
+ return result;
}
+
if (!srcPath.length) {
// no path at all. easy.
// we've already handled the other stuff above.
- delete source.pathname;
+ result.pathname = null;
//to support http.request
- if (!source.search) {
- source.path = '/' + source.search;
+ if (result.search) {
+ result.path = '/' + result.search;
} else {
- delete source.path;
+ result.path = null;
}
- source.href = urlFormat(source);
- return source;
+ result.href = result.format();
+ return result;
}
+
// if a url ENDs in . or .., then it must get a trailing slash.
// however, if it ends in anything else non-slashy,
// then it must NOT get a trailing slash.
var last = srcPath.slice(-1)[0];
var hasTrailingSlash = (
- (source.host || relative.host) && (last === '.' || last === '..') ||
+ (result.host || relative.host) && (last === '.' || last === '..') ||
last === '');
// strip single dots, resolve double dots to parent dir
@@ -579,47 +638,52 @@ function urlResolveObject(source, relative) {
// put the host back
if (psychotic) {
- source.hostname = source.host = isAbsolute ? '' :
+ result.hostname = result.host = isAbsolute ? '' :
srcPath.length ? srcPath.shift() : '';
//occationaly the auth can get stuck only in host
//this especialy happens in cases like
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
- var authInHost = source.host && source.host.indexOf('@') > 0 ?
- source.host.split('@') : false;
+ var authInHost = result.host && result.host.indexOf('@') > 0 ?
+ result.host.split('@') : false;
if (authInHost) {
- source.auth = authInHost.shift();
- source.host = source.hostname = authInHost.shift();
+ result.auth = authInHost.shift();
+ result.host = result.hostname = authInHost.shift();
}
}
- mustEndAbs = mustEndAbs || (source.host && srcPath.length);
+ mustEndAbs = mustEndAbs || (result.host && srcPath.length);
if (mustEndAbs && !isAbsolute) {
srcPath.unshift('');
}
- source.pathname = srcPath.join('/');
- //to support request.http
- if (source.pathname !== undefined || source.search !== undefined) {
- source.path = (source.pathname ? source.pathname : '') +
- (source.search ? source.search : '');
+ if (!srcPath.length) {
+ result.pathname = null;
+ result.path = null;
+ } else {
+ result.pathname = srcPath.join('/');
}
- source.auth = relative.auth || source.auth;
- source.slashes = source.slashes || relative.slashes;
- source.href = urlFormat(source);
- return source;
-}
-function parseHost(host) {
- var out = {};
+ //to support request.http
+ if (result.pathname !== null || result.search !== null) {
+ result.path = (result.pathname ? result.pathname : '') +
+ (result.search ? result.search : '');
+ }
+ result.auth = relative.auth || result.auth;
+ result.slashes = result.slashes || relative.slashes;
+ result.href = result.format();
+ return result;
+};
+
+Url.prototype.parseHost = function() {
+ var host = this.host;
var port = portPattern.exec(host);
if (port) {
port = port[0];
if (port !== ':') {
- out.port = port.substr(1);
+ this.port = port.substr(1);
}
host = host.substr(0, host.length - port.length);
}
- if (host) out.hostname = host;
- return out;
-}
+ if (host) this.hostname = host;
+};
diff --git a/lib/util.js b/lib/util.js
index d9a5c2b22..a71876adb 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -110,25 +110,38 @@ var error = exports.error = function(x) {
* in the best way possible given the different types.
*
* @param {Object} obj The object to print out.
- * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
- * properties of objects.
- * @param {Number} depth Depth in which to descend in object. Default is 2.
- * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
- * output. Default is false (no coloring).
+ * @param {Object} opts Optional options object that alters the output.
*/
-function inspect(obj, showHidden, depth, colors) {
+/* legacy: obj, showHidden, depth, colors*/
+function inspect(obj, opts) {
+ // default options
var ctx = {
- showHidden: showHidden,
seen: [],
- stylize: colors ? stylizeWithColor : stylizeNoColor
+ stylize: stylizeNoColor
};
- return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
+ // legacy...
+ if (arguments.length >= 3) ctx.depth = arguments[2];
+ if (arguments.length >= 4) ctx.colors = arguments[3];
+ if (typeof opts === 'boolean') {
+ // legacy...
+ ctx.showHidden = opts;
+ } else if (opts) {
+ // got an "options" object
+ exports._extend(ctx, opts);
+ }
+ // set default options
+ if (typeof ctx.showHidden === 'undefined') ctx.showHidden = false;
+ if (typeof ctx.depth === 'undefined') ctx.depth = 2;
+ if (typeof ctx.colors === 'undefined') ctx.colors = false;
+ if (typeof ctx.customInspect === 'undefined') ctx.customInspect = true;
+ if (ctx.colors) ctx.stylize = stylizeWithColor;
+ return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
-var colors = {
+inspect.colors = {
'bold' : [1, 22],
'italic' : [3, 23],
'underline' : [4, 24],
@@ -145,7 +158,7 @@ var colors = {
};
// Don't use 'blue' not visible on cmd.exe
-var styles = {
+inspect.styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
@@ -159,11 +172,11 @@ var styles = {
function stylizeWithColor(str, styleType) {
- var style = styles[styleType];
+ var style = inspect.styles[styleType];
if (style) {
- return '\u001b[' + colors[style][0] + 'm' + str +
- '\u001b[' + colors[style][1] + 'm';
+ return '\u001b[' + inspect.colors[style][0] + 'm' + str +
+ '\u001b[' + inspect.colors[style][1] + 'm';
} else {
return str;
}
@@ -189,7 +202,7 @@ function arrayToHash(array) {
function formatValue(ctx, value, recurseTimes) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
- if (value && typeof value.inspect === 'function' &&
+ if (ctx.customInspect && value && typeof value.inspect === 'function' &&
// Filter out the util module, it's inspect function is special
value.inspect !== exports.inspect &&
// Also filter out any prototype objects using the circular check.
@@ -482,7 +495,7 @@ exports.exec = exports.deprecate(function() {
}, 'util.exec is now called `child_process.exec`.');
-exports.pump = function(readStream, writeStream, callback) {
+function pump(readStream, writeStream, callback) {
var callbackCalled = false;
function call(a, b, c) {
@@ -517,7 +530,9 @@ exports.pump = function(readStream, writeStream, callback) {
readStream.destroy();
call(err);
});
-};
+}
+exports.pump = exports.deprecate(pump,
+ 'util.pump() is deprecated. Use readableStream.pipe() instead.');
/**
diff --git a/lib/zlib.js b/lib/zlib.js
index b0826a8f5..409286bc1 100644
--- a/lib/zlib.js
+++ b/lib/zlib.js
@@ -19,9 +19,10 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
+var Transform = require('_stream_transform');
+
var binding = process.binding('zlib');
var util = require('util');
-var Stream = require('stream');
var assert = require('assert').ok;
// zlib doesn't provide these, so kludge them in following the same
@@ -138,34 +139,36 @@ function zlibBuffer(engine, buffer, callback) {
var buffers = [];
var nread = 0;
+ engine.on('error', onError);
+ engine.on('end', onEnd);
+
+ engine.end(buffer);
+ flow();
+
+ function flow() {
+ var chunk;
+ while (null !== (chunk = engine.read())) {
+ buffers.push(chunk);
+ nread += chunk.length;
+ }
+ engine.once('readable', flow);
+ }
+
function onError(err) {
engine.removeListener('end', onEnd);
- engine.removeListener('error', onError);
+ engine.removeListener('readable', flow);
callback(err);
}
- function onData(chunk) {
- buffers.push(chunk);
- nread += chunk.length;
- }
-
function onEnd() {
var buf = Buffer.concat(buffers, nread);
buffers = [];
callback(null, buf);
- engine._clear();
+ engine.close();
}
-
- engine.on('error', onError);
- engine.on('data', onData);
- engine.on('end', onEnd);
-
- engine.write(buffer);
- engine.end();
}
-
// generic zlib
// minimal 2-byte header
function Deflate(opts) {
@@ -218,15 +221,13 @@ function Unzip(opts) {
// you call the .write() method.
function Zlib(opts, mode) {
- Stream.call(this);
-
this._opts = opts = opts || {};
- this._queue = [];
- this._processing = false;
- this._ended = false;
- this.readable = true;
- this.writable = true;
- this._flush = binding.Z_NO_FLUSH;
+ this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK;
+
+ Transform.call(this, opts);
+
+ // means a different thing there.
+ this._readableState.chunkSize = null;
if (opts.chunkSize) {
if (opts.chunkSize < exports.Z_MIN_CHUNK ||
@@ -275,13 +276,12 @@ function Zlib(opts, mode) {
this._binding = new binding.Zlib(mode);
var self = this;
+ this._hadError = false;
this._binding.onerror = function(message, errno) {
// there is no way to cleanly recover.
// continuing only obscures problems.
self._binding = null;
self._hadError = true;
- self._queue.length = 0;
- self._processing = false;
var error = new Error(message);
error.errno = errno;
@@ -295,99 +295,81 @@ function Zlib(opts, mode) {
opts.strategy || exports.Z_DEFAULT_STRATEGY,
opts.dictionary);
- this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK;
this._buffer = new Buffer(this._chunkSize);
this._offset = 0;
- var self = this;
-}
-
-util.inherits(Zlib, Stream);
-
-Zlib.prototype.write = function write(chunk, cb) {
- if (this._hadError) return true;
-
- if (this._ended) {
- return this.emit('error', new Error('Cannot write after end'));
- }
-
- if (arguments.length === 1 && typeof chunk === 'function') {
- cb = chunk;
- chunk = null;
- }
-
- if (!chunk) {
- chunk = null;
- } else if (typeof chunk === 'string') {
- chunk = new Buffer(chunk);
- } else if (!Buffer.isBuffer(chunk)) {
- return this.emit('error', new Error('Invalid argument'));
- }
-
+ this._closed = false;
- var empty = this._queue.length === 0;
+ this.once('end', this.close);
+}
- this._queue.push([chunk, cb]);
- this._process();
- if (!empty) {
- this._needDrain = true;
- }
- return empty;
-};
+util.inherits(Zlib, Transform);
Zlib.prototype.reset = function reset() {
return this._binding.reset();
};
-Zlib.prototype.flush = function flush(cb) {
- this._flush = binding.Z_SYNC_FLUSH;
- return this.write(cb);
+Zlib.prototype._flush = function(output, callback) {
+ this._transform(null, output, callback);
};
-Zlib.prototype.end = function end(chunk, cb) {
- if (this._hadError) return true;
+Zlib.prototype.flush = function(callback) {
+ var ws = this._writableState;
+ var ts = this._transformState;
- var self = this;
- this._ending = true;
- var ret = this.write(chunk, function() {
- self.emit('end');
- if (cb) cb();
- });
- this._ended = true;
- return ret;
-};
+ if (ws.writing) {
+ ws.needDrain = true;
+ var self = this;
+ this.once('drain', function() {
+ self._flush(ts.output, callback);
+ });
+ return;
+ }
-Zlib.prototype._clear = function() {
- return this._binding.clear();
+ this._flush(ts.output, callback || function() {});
};
-Zlib.prototype._process = function() {
- if (this._hadError) return;
+Zlib.prototype.close = function(callback) {
+ if (callback)
+ process.nextTick(callback);
- if (this._processing || this._paused) return;
-
- if (this._queue.length === 0) {
- if (this._needDrain) {
- this._needDrain = false;
- this.emit('drain');
- }
- // nothing to do, waiting for more data at this point.
+ if (this._closed)
return;
- }
- var req = this._queue.shift();
- var cb = req.pop();
- var chunk = req.pop();
+ this._closed = true;
- if (this._ending && this._queue.length === 0) {
- this._flush = binding.Z_FINISH;
- }
+ this._binding.close();
var self = this;
+ process.nextTick(function() {
+ self.emit('close');
+ });
+};
+
+Zlib.prototype._transform = function(chunk, output, cb) {
+ var flushFlag;
+ var ws = this._writableState;
+ var ending = ws.ending || ws.ended;
+ var last = ending && (!chunk || ws.length === chunk.length);
+
+ if (chunk !== null && !Buffer.isBuffer(chunk))
+ return cb(new Error('invalid input'));
+
+ // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag.
+ // If it's explicitly flushing at some other time, then we use
+ // Z_FULL_FLUSH. Otherwise, use Z_NO_FLUSH for maximum compression
+ // goodness.
+ if (last)
+ flushFlag = binding.Z_FINISH;
+ else if (chunk === null)
+ flushFlag = binding.Z_FULL_FLUSH;
+ else
+ flushFlag = binding.Z_NO_FLUSH;
+
var availInBefore = chunk && chunk.length;
var availOutBefore = this._chunkSize - this._offset;
-
var inOff = 0;
- var req = this._binding.write(this._flush,
+
+ var req = this._binding.write(flushFlag,
chunk, // in
inOff, // in_off
availInBefore, // in_len
@@ -397,23 +379,23 @@ Zlib.prototype._process = function() {
req.buffer = chunk;
req.callback = callback;
- this._processing = req;
+ var self = this;
function callback(availInAfter, availOutAfter, buffer) {
- if (self._hadError) return;
+ if (self._hadError)
+ return;
var have = availOutBefore - availOutAfter;
-
assert(have >= 0, 'have should not go down');
if (have > 0) {
var out = self._buffer.slice(self._offset, self._offset + have);
self._offset += have;
- self.emit('data', out);
+ // serve some output to the consumer.
+ output(out);
}
- // XXX Maybe have a 'min buffer' size so we don't dip into the
- // thread pool with only 1 byte available or something?
+ // exhausted the output buffer, or used all the input create a new one.
if (availOutAfter === 0 || self._offset >= self._chunkSize) {
availOutBefore = self._chunkSize;
self._offset = 0;
@@ -428,7 +410,7 @@ Zlib.prototype._process = function() {
inOff += (availInBefore - availInAfter);
availInBefore = availInAfter;
- var newReq = self._binding.write(self._flush,
+ var newReq = self._binding.write(flushFlag,
chunk,
inOff,
availInBefore,
@@ -437,34 +419,14 @@ Zlib.prototype._process = function() {
self._chunkSize);
newReq.callback = callback; // this same function
newReq.buffer = chunk;
- self._processing = newReq;
return;
}
// finished with the chunk.
- self._processing = false;
- if (cb) cb();
- self._process();
+ cb();
}
};
-Zlib.prototype.pause = function() {
- this._paused = true;
- this.emit('pause');
-};
-
-Zlib.prototype.resume = function() {
- this._paused = false;
- this._process();
-};
-
-Zlib.prototype.destroy = function() {
- this.readable = false;
- this.writable = false;
- this._ended = true;
- this.emit('close');
-};
-
util.inherits(Deflate, Zlib);
util.inherits(Inflate, Zlib);
util.inherits(Gzip, Zlib);
diff --git a/node.gyp b/node.gyp
index 2473879a1..b07a1e0ca 100644
--- a/node.gyp
+++ b/node.gyp
@@ -6,9 +6,15 @@
'werror': '',
'node_use_dtrace%': 'false',
'node_use_etw%': 'false',
+ 'node_use_perfctr%': 'false',
+ 'node_has_winsdk%': 'false',
'node_shared_v8%': 'false',
'node_shared_zlib%': 'false',
+ 'node_shared_http_parser%': 'false',
+ 'node_shared_cares%': 'false',
+ 'node_shared_libuv%': 'false',
'node_use_openssl%': 'true',
+ 'node_use_systemtap%': 'false',
'node_shared_openssl%': 'false',
'library_files': [
'src/node.js',
@@ -16,7 +22,6 @@
'lib/_linklist.js',
'lib/assert.js',
'lib/buffer.js',
- 'lib/buffer_ieee754.js',
'lib/child_process.js',
'lib/console.js',
'lib/constants.js',
@@ -39,6 +44,11 @@
'lib/readline.js',
'lib/repl.js',
'lib/stream.js',
+ 'lib/_stream_readable.js',
+ 'lib/_stream_writable.js',
+ 'lib/_stream_duplex.js',
+ 'lib/_stream_transform.js',
+ 'lib/_stream_passthrough.js',
'lib/string_decoder.js',
'lib/sys.js',
'lib/timers.js',
@@ -57,13 +67,12 @@
'type': 'executable',
'dependencies': [
- 'deps/http_parser/http_parser.gyp:http_parser',
- 'deps/uv/uv.gyp:uv',
'node_js2c#host',
],
'include_dirs': [
'src',
+ 'tools/msvs/genfiles',
'deps/uv/src/ares',
'<(SHARED_INTERMEDIATE_DIR)' # for node_natives.h
],
@@ -86,6 +95,7 @@
'src/node_string.cc',
'src/node_zlib.cc',
'src/pipe_wrap.cc',
+ 'src/signal_wrap.cc',
'src/stream_wrap.cc',
'src/slab_allocator.cc',
'src/tcp_wrap.cc',
@@ -117,6 +127,7 @@
'src/req_wrap.h',
'src/slab_allocator.h',
'src/stream_wrap.h',
+ 'src/tree.h',
'src/v8_typed_array.h',
'deps/http_parser/http_parser.h',
'<(SHARED_INTERMEDIATE_DIR)/node_natives.h',
@@ -144,7 +155,6 @@
}, {
'defines': [ 'HAVE_OPENSSL=0' ]
}],
-
[ 'node_use_dtrace=="true"', {
'defines': [ 'HAVE_DTRACE=1' ],
'dependencies': [ 'node_dtrace_header' ],
@@ -158,13 +168,18 @@
#
'sources': [
'src/node_dtrace.cc',
- 'src/node_dtrace_provider.cc'
+ 'src/node_dtrace_provider.cc',
+ 'src/node_dtrace_ustack.cc',
+ ],
+ } ],
+ [ 'node_use_systemtap=="true"', {
+ 'defines': [ 'HAVE_SYSTEMTAP=1', 'STAP_SDT_V1=1' ],
+ 'dependencies': [ 'node_systemtap_header' ],
+ 'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)' ],
+ 'sources': [
+ 'src/node_dtrace.cc',
+ '<(SHARED_INTERMEDIATE_DIR)/node_systemtap.h',
],
- 'conditions': [ [
- 'target_arch=="ia32"', {
- 'sources': [ 'src/node_dtrace_ustack.cc' ]
- }
- ] ],
} ],
[ 'node_use_etw=="true"', {
'defines': [ 'HAVE_ETW=1' ],
@@ -174,8 +189,19 @@
'src/node_win32_etw_provider-inl.h',
'src/node_win32_etw_provider.cc',
'src/node_dtrace.cc',
- '<(SHARED_INTERMEDIATE_DIR)/node_etw_provider.h',
- '<(SHARED_INTERMEDIATE_DIR)/node_etw_provider.rc',
+ 'tools/msvs/genfiles/node_etw_provider.h',
+ 'tools/msvs/genfiles/node_etw_provider.rc',
+ ]
+ } ],
+ [ 'node_use_perfctr=="true"', {
+ 'defines': [ 'HAVE_PERFCTR=1' ],
+ 'dependencies': [ 'node_perfctr' ],
+ 'sources': [
+ 'src/node_win32_perfctr_provider.h',
+ 'src/node_win32_perfctr_provider.cc',
+ 'src/node_counters.cc',
+ 'src/node_counters.h',
+ 'tools/msvs/genfiles/node_perfctr_provider.rc',
]
} ],
[ 'node_shared_v8=="false"', {
@@ -190,6 +216,18 @@
'dependencies': [ 'deps/zlib/zlib.gyp:zlib' ],
}],
+ [ 'node_shared_http_parser=="false"', {
+ 'dependencies': [ 'deps/http_parser/http_parser.gyp:http_parser' ],
+ }],
+
+ [ 'node_shared_cares=="false"', {
+ 'dependencies': [ 'deps/cares/cares.gyp:cares' ],
+ }],
+
+ [ 'node_shared_libuv=="false"', {
+ 'dependencies': [ 'deps/uv/uv.gyp:libuv' ],
+ }],
+
[ 'OS=="win"', {
'sources': [
'src/res/node.rc',
@@ -203,10 +241,6 @@
'libraries': [ '-lpsapi.lib' ]
}, { # POSIX
'defines': [ '__POSIX__' ],
- 'sources': [
- 'src/node_signal_watcher.cc',
- 'src/node_io_watcher.cc',
- ],
}],
[ 'OS=="mac"', {
'libraries': [ '-framework Carbon' ],
@@ -239,7 +273,7 @@
],
}],
],
- 'msvs-settings': {
+ 'msvs_settings': {
'VCLinkerTool': {
'SubSystem': 1, # /subsystem:console
},
@@ -250,18 +284,46 @@
'target_name': 'node_etw',
'type': 'none',
'conditions': [
- [ 'node_use_etw=="true"', {
+ [ 'node_use_etw=="true" and node_has_winsdk=="true"', {
'actions': [
{
'action_name': 'node_etw',
'inputs': [ 'src/res/node_etw_provider.man' ],
- 'outputs': [ '<(SHARED_INTERMEDIATE_DIR)' ],
- 'action': [ 'mc <@(_inputs) -h <@(_outputs) -r <@(_outputs)' ]
+ 'outputs': [
+ 'tools/msvs/genfiles/node_etw_provider.rc',
+ 'tools/msvs/genfiles/node_etw_provider.h',
+ 'tools/msvs/genfiles/node_etw_providerTEMP.BIN',
+ ],
+ 'action': [ 'mc <@(_inputs) -h tools/msvs/genfiles -r tools/msvs/genfiles' ]
}
]
} ]
]
},
+ # generate perf counter header and resource files
+ {
+ 'target_name': 'node_perfctr',
+ 'type': 'none',
+ 'conditions': [
+ [ 'node_use_perfctr=="true" and node_has_winsdk=="true"', {
+ 'actions': [
+ {
+ 'action_name': 'node_perfctr_man',
+ 'inputs': [ 'src/res/node_perfctr_provider.man' ],
+ 'outputs': [
+ 'tools/msvs/genfiles/node_perfctr_provider.h',
+ 'tools/msvs/genfiles/node_perfctr_provider.rc',
+ 'tools/msvs/genfiles/MSG00001.BIN',
+ ],
+ 'action': [ 'ctrpp <@(_inputs) '
+ '-o tools/msvs/genfiles/node_perfctr_provider.h '
+ '-rc tools/msvs/genfiles/node_perfctr_provider.rc'
+ ]
+ },
+ ],
+ } ]
+ ]
+ },
{
'target_name': 'node_js2c',
'type': 'none',
@@ -269,38 +331,31 @@
'actions': [
{
'action_name': 'node_js2c',
-
'inputs': [
'<@(library_files)',
'./config.gypi',
],
-
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/node_natives.h',
],
-
- # FIXME can the following conditions be shorted by just setting
- # macros.py into some variable which then gets included in the
- # action?
-
'conditions': [
- [ 'node_use_dtrace=="true" or node_use_etw=="true"', {
- 'action': [
- 'python',
- 'tools/js2c.py',
- '<@(_outputs)',
- '<@(_inputs)',
+ [ 'node_use_dtrace=="false"'
+ ' and node_use_etw=="false"'
+ ' and node_use_systemtap=="false"',
+ {
+ 'inputs': ['src/macros.py']
+ }
],
- }, { # No Dtrace
+ [ 'node_use_perfctr=="false"', {
+ 'inputs': [ 'src/perfctr_macros.py' ]
+ }]
+ ],
'action': [
- 'python',
+ '<(python)',
'tools/js2c.py',
'<@(_outputs)',
'<@(_inputs)',
- 'src/macros.py'
],
- }]
- ],
},
],
}, # end node_js2c
@@ -322,6 +377,23 @@
]
},
{
+ 'target_name': 'node_systemtap_header',
+ 'type': 'none',
+ 'conditions': [
+ [ 'node_use_systemtap=="true"', {
+ 'actions': [
+ {
+ 'action_name': 'node_systemtap_header',
+ 'inputs': [ 'src/node_systemtap.d' ],
+ 'outputs': [ '<(SHARED_INTERMEDIATE_DIR)/node_systemtap.h' ],
+ 'action': [ 'dtrace', '-h', '-C', '-s', '<@(_inputs)',
+ '-o', '<@(_outputs)' ]
+ }
+ ]
+ } ]
+ ]
+ },
+ {
'target_name': 'node_dtrace_provider',
'type': 'none',
'conditions': [
@@ -347,7 +419,7 @@
'target_name': 'node_dtrace_ustack',
'type': 'none',
'conditions': [
- [ 'node_use_dtrace=="true" and target_arch=="ia32"', {
+ [ 'node_use_dtrace=="true"', {
'actions': [
{
'action_name': 'node_dtrace_ustack_constants',
@@ -372,9 +444,19 @@
'outputs': [
'<(PRODUCT_DIR)/obj.target/node/src/node_dtrace_ustack.o'
],
- 'action': [
- 'dtrace', '-32', '-I<(SHARED_INTERMEDIATE_DIR)', '-Isrc',
- '-C', '-G', '-s', 'src/v8ustack.d', '-o', '<@(_outputs)',
+ 'conditions': [
+ [ 'target_arch=="ia32"', {
+ 'action': [
+ 'dtrace', '-32', '-I<(SHARED_INTERMEDIATE_DIR)', '-Isrc',
+ '-C', '-G', '-s', 'src/v8ustack.d', '-o', '<@(_outputs)',
+ ]
+ } ],
+ [ 'target_arch=="x64"', {
+ 'action': [
+ 'dtrace', '-64', '-I<(SHARED_INTERMEDIATE_DIR)', '-Isrc',
+ '-C', '-G', '-s', 'src/v8ustack.d', '-o', '<@(_outputs)',
+ ]
+ } ],
]
}
]
@@ -383,4 +465,3 @@
}
] # end targets
}
-
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc
index 049fdb97d..4cfe4b2ea 100644
--- a/src/cares_wrap.cc
+++ b/src/cares_wrap.cc
@@ -20,33 +20,23 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CARES_STATICLIB
+#include "ares.h"
#include "node.h"
#include "req_wrap.h"
+#include "tree.h"
#include "uv.h"
-#include <string.h>
-
#if defined(__OpenBSD__) || defined(__MINGW32__) || defined(_MSC_VER)
# include <nameser.h>
#else
# include <arpa/nameser.h>
#endif
-// Temporary hack: libuv should provide uv_inet_pton and uv_inet_ntop.
-#if defined(__MINGW32__) || defined(_MSC_VER)
- extern "C" {
-# include <inet_net_pton.h>
-# include <inet_ntop.h>
- }
-# define uv_inet_pton ares_inet_pton
-# define uv_inet_ntop ares_inet_ntop
-
-#else // __POSIX__
-# include <arpa/inet.h>
-# define uv_inet_pton inet_pton
-# define uv_inet_ntop inet_ntop
-#endif
-
namespace node {
@@ -69,9 +59,139 @@ using v8::Value;
typedef class ReqWrap<uv_getaddrinfo_t> GetAddrInfoReqWrap;
-static Persistent<String> oncomplete_sym;
+struct ares_task_t {
+ UV_HANDLE_FIELDS
+ ares_socket_t sock;
+ uv_poll_t poll_watcher;
+ RB_ENTRY(ares_task_t) node;
+};
+
+static Persistent<String> oncomplete_sym;
static ares_channel ares_channel;
+static uv_timer_t ares_timer;
+static RB_HEAD(ares_task_list, ares_task_t) ares_tasks;
+
+
+static int cmp_ares_tasks(const ares_task_t* a, const ares_task_t* b) {
+ if (a->sock < b->sock) return -1;
+ if (a->sock > b->sock) return 1;
+ return 0;
+}
+
+
+RB_GENERATE_STATIC(ares_task_list, ares_task_t, node, cmp_ares_tasks)
+
+
+
+/* This is called once per second by loop->timer. It is used to constantly */
+/* call back into c-ares for possibly processing timeouts. */
+static void ares_timeout(uv_timer_t* handle, int status) {
+ assert(!RB_EMPTY(&ares_tasks));
+ ares_process_fd(ares_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
+}
+
+
+static void ares_poll_cb(uv_poll_t* watcher, int status, int events) {
+ ares_task_t* task = container_of(watcher, ares_task_t, poll_watcher);
+
+ /* Reset the idle timer */
+ uv_timer_again(&ares_timer);
+
+ if (status < 0) {
+ /* An error happened. Just pretend that the socket is both readable and */
+ /* writable. */
+ ares_process_fd(ares_channel, task->sock, task->sock);
+ return;
+ }
+
+ /* Process DNS responses */
+ ares_process_fd(ares_channel,
+ events & UV_READABLE ? task->sock : ARES_SOCKET_BAD,
+ events & UV_WRITABLE ? task->sock : ARES_SOCKET_BAD);
+}
+
+
+static void ares_poll_close_cb(uv_handle_t* watcher) {
+ ares_task_t* task = container_of(watcher, ares_task_t, poll_watcher);
+ free(task);
+}
+
+
+/* Allocates and returns a new ares_task_t */
+static ares_task_t* ares_task_create(uv_loop_t* loop, ares_socket_t sock) {
+ ares_task_t* task = (ares_task_t*) malloc(sizeof *task);
+
+ if (task == NULL) {
+ /* Out of memory. */
+ return NULL;
+ }
+
+ task->loop = loop;
+ task->sock = sock;
+
+ if (uv_poll_init_socket(loop, &task->poll_watcher, sock) < 0) {
+ /* This should never happen. */
+ free(task);
+ return NULL;
+ }
+
+ return task;
+}
+
+
+/* Callback from ares when socket operation is started */
+static void ares_sockstate_cb(void* data, ares_socket_t sock,
+ int read, int write) {
+ uv_loop_t* loop = (uv_loop_t*) data;
+ ares_task_t* task;
+
+ ares_task_t lookup_task;
+ lookup_task.sock = sock;
+ task = RB_FIND(ares_task_list, &ares_tasks, &lookup_task);
+
+ if (read || write) {
+ if (!task) {
+ /* New socket */
+
+ /* If this is the first socket then start the timer. */
+ if (!uv_is_active((uv_handle_t*) &ares_timer)) {
+ assert(RB_EMPTY(&ares_tasks));
+ uv_timer_start(&ares_timer, ares_timeout, 1000, 1000);
+ }
+
+ task = ares_task_create(loop, sock);
+ if (task == NULL) {
+ /* This should never happen unless we're out of memory or something */
+ /* is seriously wrong. The socket won't be polled, but the the query */
+ /* will eventually time out. */
+ return;
+ }
+
+ RB_INSERT(ares_task_list, &ares_tasks, task);
+ }
+
+ /* This should never fail. If it fails anyway, the query will eventually */
+ /* time out. */
+ uv_poll_start(&task->poll_watcher,
+ (read ? UV_READABLE : 0) | (write ? UV_WRITABLE : 0),
+ ares_poll_cb);
+
+ } else {
+ /* read == 0 and write == 0 this is c-ares's way of notifying us that */
+ /* the socket is now closed. We must free the data associated with */
+ /* socket. */
+ assert(task &&
+ "When an ares socket is closed we should have a handle for it");
+
+ RB_REMOVE(ares_task_list, &ares_tasks, task);
+ uv_close((uv_handle_t*) &task->poll_watcher, ares_poll_close_cb);
+
+ if (RB_EMPTY(&ares_tasks)) {
+ uv_timer_stop(&ares_timer);
+ }
+ }
+}
static Local<Array> HostentToAddresses(struct hostent* host) {
@@ -191,7 +311,7 @@ class QueryWrap {
static void Callback(void *arg, int status, int timeouts,
unsigned char* answer_buf, int answer_len) {
- QueryWrap* wrap = reinterpret_cast<QueryWrap*>(arg);
+ QueryWrap* wrap = static_cast<QueryWrap*>(arg);
if (status != ARES_SUCCESS) {
wrap->ParseError(status);
@@ -204,7 +324,7 @@ class QueryWrap {
static void Callback(void *arg, int status, int timeouts,
struct hostent* host) {
- QueryWrap* wrap = reinterpret_cast<QueryWrap*>(arg);
+ QueryWrap* wrap = static_cast<QueryWrap*>(arg);
if (status != ARES_SUCCESS) {
wrap->ParseError(status);
@@ -371,7 +491,8 @@ class QueryMxWrap: public QueryWrap {
mx_current = mx_current->next) {
Local<Object> mx_record = Object::New();
mx_record->Set(exchange_symbol, String::New(mx_current->host));
- mx_record->Set(priority_symbol, Integer::New(mx_current->priority));
+ mx_record->Set(priority_symbol,
+ Integer::New(mx_current->priority));
mx_records->Set(Integer::New(i++), mx_record);
}
@@ -473,9 +594,12 @@ class QuerySrvWrap: public QueryWrap {
srv_current = srv_current->next) {
Local<Object> srv_record = Object::New();
srv_record->Set(name_symbol, String::New(srv_current->host));
- srv_record->Set(port_symbol, Integer::New(srv_current->port));
- srv_record->Set(priority_symbol, Integer::New(srv_current->priority));
- srv_record->Set(weight_symbol, Integer::New(srv_current->weight));
+ srv_record->Set(port_symbol,
+ Integer::New(srv_current->port));
+ srv_record->Set(priority_symbol,
+ Integer::New(srv_current->priority));
+ srv_record->Set(weight_symbol,
+ Integer::New(srv_current->weight));
srv_records->Set(Integer::New(i++), srv_record);
}
@@ -492,10 +616,10 @@ class GetHostByAddrWrap: public QueryWrap {
int length, family;
char address_buffer[sizeof(struct in6_addr)];
- if (uv_inet_pton(AF_INET, name, &address_buffer) == 1) {
+ if (uv_inet_pton(AF_INET, name, &address_buffer).code == UV_OK) {
length = sizeof(struct in_addr);
family = AF_INET;
- } else if (uv_inet_pton(AF_INET6, name, &address_buffer) == 1) {
+ } else if (uv_inet_pton(AF_INET6, name, &address_buffer).code == UV_OK) {
length = sizeof(struct in6_addr);
family = AF_INET6;
} else {
@@ -637,11 +761,15 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
if (address->ai_family == AF_INET) {
// Juggle pointers
addr = (char*) &((struct sockaddr_in*) address->ai_addr)->sin_addr;
- const char* c = uv_inet_ntop(address->ai_family, addr, ip,
- INET6_ADDRSTRLEN);
+ uv_err_t err = uv_inet_ntop(address->ai_family,
+ addr,
+ ip,
+ INET6_ADDRSTRLEN);
+ if (err.code != UV_OK)
+ continue;
// Create JavaScript string
- Local<String> s = String::New(c);
+ Local<String> s = String::New(ip);
results->Set(n, s);
n++;
}
@@ -659,11 +787,15 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
if (address->ai_family == AF_INET6) {
// Juggle pointers
addr = (char*) &((struct sockaddr_in6*) address->ai_addr)->sin6_addr;
- const char* c = uv_inet_ntop(address->ai_family, addr, ip,
- INET6_ADDRSTRLEN);
+ uv_err_t err = uv_inet_ntop(address->ai_family,
+ addr,
+ ip,
+ INET6_ADDRSTRLEN);
+ if (err.code != UV_OK)
+ continue;
// Create JavaScript string
- Local<String> s = String::New(c);
+ Local<String> s = String::New(ip);
results->Set(n, s);
n++;
}
@@ -691,11 +823,11 @@ static Handle<Value> IsIP(const Arguments& args) {
String::AsciiValue ip(args[0]);
char address_buffer[sizeof(struct in6_addr)];
- if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 1) {
+ if (uv_inet_pton(AF_INET, *ip, &address_buffer).code == UV_OK) {
return scope.Close(v8::Integer::New(4));
}
- if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 1) {
+ if (uv_inet_pton(AF_INET6, *ip, &address_buffer).code == UV_OK) {
return scope.Close(v8::Integer::New(6));
}
@@ -754,8 +886,20 @@ static void Initialize(Handle<Object> target) {
assert(r == ARES_SUCCESS);
struct ares_options options;
- uv_ares_init_options(uv_default_loop(), &ares_channel, &options, 0);
- assert(r == 0);
+ memset(&options, 0, sizeof(options));
+ options.flags = ARES_FLAG_NOCHECKRESP;
+ options.sock_state_cb = ares_sockstate_cb;
+ options.sock_state_cb_data = uv_default_loop();
+
+ /* We do the call to ares_init_option for caller. */
+ r = ares_init_options(&ares_channel,
+ &options,
+ ARES_OPT_FLAGS | ARES_OPT_SOCK_STATE_CB);
+ assert(r == ARES_SUCCESS);
+
+ /* Initialize the timeout timer. The timer won't be started until the */
+ /* first socket is opened. */
+ uv_timer_init(uv_default_loop(), &ares_timer);
NODE_SET_METHOD(target, "queryA", Query<QueryAWrap>);
NODE_SET_METHOD(target, "queryAaaa", Query<QueryAaaaWrap>);
@@ -770,9 +914,12 @@ static void Initialize(Handle<Object> target) {
NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo);
NODE_SET_METHOD(target, "isIP", IsIP);
- target->Set(String::NewSymbol("AF_INET"), Integer::New(AF_INET));
- target->Set(String::NewSymbol("AF_INET6"), Integer::New(AF_INET6));
- target->Set(String::NewSymbol("AF_UNSPEC"), Integer::New(AF_UNSPEC));
+ target->Set(String::NewSymbol("AF_INET"),
+ Integer::New(AF_INET));
+ target->Set(String::NewSymbol("AF_INET6"),
+ Integer::New(AF_INET6));
+ target->Set(String::NewSymbol("AF_UNSPEC"),
+ Integer::New(AF_UNSPEC));
oncomplete_sym = NODE_PSYMBOL("oncomplete");
}
diff --git a/src/eio-emul.h b/src/eio-emul.h
deleted file mode 100644
index 03fc5dfcc..000000000
--- a/src/eio-emul.h
+++ /dev/null
@@ -1,71 +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.
- */
-
-#ifndef NODE_EIO_EMUL_H_
-#define NODE_EIO_EMUL_H_
-
-#define eio_nop(a,b,c) eio_nop(a,b,c,(&uv_default_loop()->uv_eio_channel))
-#define eio_busy(a,b,c,d) eio_busy(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_sync(a,b,c) eio_sync(a,b,c,(&uv_default_loop()->uv_eio_channel))
-#define eio_fsync(a,b,c,d) eio_fsync(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_msync(a,b,c,d,e,f) eio_msync(a,b,c,d,e,f,(&uv_default_loop()->uv_eio_channel))
-#define eio_fdatasync(a,b,c,d) eio_fdatasync(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_syncfs(a,b,c,d) eio_syncfs(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_sync_file_range(a,b,c,d,e,f,g) eio_sync_file_range(a,b,c,d,e,f,g,(&uv_default_loop()->uv_eio_channel))
-#define eio_mtouch(a,b,c,d,e,f) eio_mtouch(a,b,c,d,e,f,(&uv_default_loop()->uv_eio_channel))
-#define eio_mlock(a,b,c,d,e) eio_mlock(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_mlockall(a,b,c,d) eio_mlockall(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_fallocate(a,b,c,d,e,f,g) eio_fallocate(a,b,c,d,e,f,g,(&uv_default_loop()->uv_eio_channel))
-#define eio_close(a,b,c,d) eio_close(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_readahead(a,b,c,d,e,f) eio_readahead(a,b,c,d,e,f,(&uv_default_loop()->uv_eio_channel))
-#define eio_read(a,b,c,d,e,f,g) eio_read(a,b,c,d,e,f,g,(&uv_default_loop()->uv_eio_channel))
-#define eio_write(a,b,c,d,e,f,g) eio_write(a,b,c,d,e,f,g,(&uv_default_loop()->uv_eio_channel))
-#define eio_fstat(a,b,c,d) eio_fstat(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_fstatvfs(a,b,c,d) eio_fstatvfs(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_futime(a,b,c,d,e,f) eio_futime(a,b,c,d,e,f,(&uv_default_loop()->uv_eio_channel))
-#define eio_ftruncate(a,b,c,d,e) eio_ftruncate(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_fchmod(a,b,c,d,e) eio_fchmod(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_fchown(a,b,c,d,e,f) eio_fchown(a,b,c,d,e,f,(&uv_default_loop()->uv_eio_channel))
-#define eio_dup2(a,b,c,d,e) eio_dup2(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_sendfile(a,b,c,d,e,f,g) eio_sendfile(a,b,c,d,e,f,g,(&uv_default_loop()->uv_eio_channel))
-#define eio_open(a,b,c,d,e,f) eio_open(a,b,c,d,e,f,(&uv_default_loop()->uv_eio_channel))
-#define eio_utime(a,b,c,d,e,f) eio_utime(a,b,c,d,e,f,(&uv_default_loop()->uv_eio_channel))
-#define eio_truncate(a,b,c,d,e) eio_truncate(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_chown(a,b,c,d,e,f) eio_chown(a,b,c,d,e,f,(&uv_default_loop()->uv_eio_channel))
-#define eio_chmod(a,b,c,d,e) eio_chmod(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_mkdir(a,b,c,d,e) eio_mkdir(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_readlink(a,b,c,d) eio_readlink(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_realpath(a,b,c,d) eio_realpath(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_stat(a,b,c,d) eio_stat(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_lstat(a,b,c,d) eio_lstat(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_statvfs(a,b,c,d) eio_statvfs(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_unlink(a,b,c,d) eio_unlink(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_rmdir(a,b,c,d) eio_rmdir(a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_readdir(a,b,c,d,e) eio_readdir(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_mknod(a,b,c,d,e,f) eio_mknod(a,b,c,d,e,f,(&uv_default_loop()->uv_eio_channel))
-#define eio_link(a,b,c,d,e) eio_link(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_symlink(a,b,c,d,e) eio_symlink(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_rename(a,b,c,d,e) eio_rename(a,b,c,d,e,(&uv_default_loop()->uv_eio_channel))
-#define eio_custom(a,b,c,d) eio_custom((void (*)(eio_req*))a,b,c,d,(&uv_default_loop()->uv_eio_channel))
-#define eio_grp(a,b) eio_grp(a,b,(&uv_default_loop()->uv_eio_channel))
-
-#endif /* NODE_EIO_EMUL_H_ */
diff --git a/src/ev-emul.h b/src/ev-emul.h
deleted file mode 100644
index 3ec861397..000000000
--- a/src/ev-emul.h
+++ /dev/null
@@ -1,268 +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.
- */
-
-#ifndef NODE_EV_EMUL_H_
-#define NODE_EV_EMUL_H_
-
-#include "uv.h"
-
-#include <stdio.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#undef ev_init
-#undef ev_set_cb
-#undef ev_set_priority
-#undef ev_is_active
-#undef ev_timer_init
-#undef ev_timer_set
-#undef ev_io_init
-#undef ev_io_set
-
-#undef EV_P
-#undef EV_P_
-#undef EV_A
-#undef EV_A_
-#undef EV_DEFAULT
-#undef EV_DEFAULT_
-#undef EV_DEFAULT_UC
-#undef EV_DEFAULT_UC_
-
-#define EV_P void
-#define EV_P_
-#define EV_A
-#define EV_A_
-#define EV_DEFAULT
-#define EV_DEFAULT_
-#define EV_DEFAULT_UC
-#define EV_DEFAULT_UC_
-
-#define ev_init(w, cb_) \
- do { \
- void* data = (w)->data; \
- memset((w), 0, sizeof(*(w))); \
- (w)->data = data; \
- (w)->cb = (cb_); \
- } \
- while (0)
-
-#define ev_set_cb(w, cb_) \
- do \
- (w)->cb = (cb_); \
- while (0)
-
-#define ev_is_active(w) \
- (uv_is_active((uv_handle_t*) &(w)->handle))
-
-#define __uv_container_of(ptr, type, field) \
- ((type*) ((char*) (ptr) - offsetof(type, field)))
-
-#define __uv_warn_of(old_, new_) \
- do { \
- if (__uv_warn_##old_ || node::no_deprecation) break; \
- __uv_warn_##old_ = 1; \
- fputs("WARNING: " #old_ " is deprecated, use " #new_ "\n", stderr); \
- } \
- while (0)
-
-static int __uv_warn_ev_io __attribute__((unused));
-static int __uv_warn_ev_timer __attribute__((unused));
-static int __uv_warn_ev_ref __attribute__((unused));
-static int __uv_warn_ev_unref __attribute__((unused));
-
-struct __ev_io;
-typedef struct __ev_io __ev_io;
-typedef void (*__ev_io_cb)(__ev_io*, int);
-
-struct __ev_timer;
-typedef struct __ev_timer __ev_timer;
-typedef void (*__ev_timer_cb)(__ev_timer*, int);
-
-/* Field order matters. Don't touch. */
-struct __ev_io {
- __ev_io_cb cb;
- void* data;
- int flags; /* bit 1 == initialized, yes or no? */
- uv_poll_t handle;
- int fd;
- int events;
-};
-
-/* Field order matters. Don't touch. */
-struct __ev_timer {
- __ev_timer_cb cb;
- void* data;
- int flags;
- uv_timer_t handle;
- double delay;
- double repeat;
-};
-
-
-inline static void __uv_poll_cb(uv_poll_t* handle, int status, int events) {
- __ev_io* w = __uv_container_of(handle, __ev_io, handle);
- w->cb(w, events);
- (void) status;
-}
-
-
-inline static void __uv_timer_cb(uv_timer_t* handle, int status) {
- __ev_timer* w = __uv_container_of(handle, __ev_timer, handle);
- w->cb(w, 0);
- (void) status;
-}
-
-
-inline static void __ev_io_init(__ev_io* w, __ev_io_cb cb, int fd, int events) {
- __uv_warn_of(ev_io, uv_poll_t);
- ev_init(w, cb);
- w->fd = fd;
- w->events = events;
-}
-
-
-inline static void __ev_io_set(__ev_io* w, int fd, int events) {
- __uv_warn_of(ev_io, uv_poll_t);
- w->fd = fd;
- w->events = events;
-}
-
-
-inline static void __ev_io_start(__ev_io* w) {
- __uv_warn_of(ev_io, uv_poll_t);
- if (!(w->flags & 1)) {
- uv_poll_init(uv_default_loop(), &w->handle, w->fd);
- w->flags |= 1;
- }
- uv_poll_start(&w->handle, w->events, __uv_poll_cb);
-}
-
-
-inline static void __ev_io_stop(__ev_io* w) {
- __uv_warn_of(ev_io, uv_poll_t);
- uv_poll_stop(&w->handle);
-}
-
-
-inline static void __ev_timer_init(__ev_timer* w,
- __ev_timer_cb cb,
- double delay,
- double repeat) {
- __uv_warn_of(ev_timer, uv_timer_t);
- ev_init(w, cb);
- w->delay = delay;
- w->repeat = repeat;
-}
-
-
-inline static void __ev_timer_set(__ev_timer* w,
- double delay,
- double repeat) {
- __uv_warn_of(ev_timer, uv_timer_t);
- w->delay = delay;
- w->repeat = repeat;
-}
-
-
-inline static void __ev_timer_start(__ev_timer* w) {
- __uv_warn_of(ev_timer, uv_timer_t);
- if (!(w->flags & 1)) {
- uv_timer_init(uv_default_loop(), &w->handle);
- w->flags |= 1;
- }
- uv_timer_start(&w->handle,
- __uv_timer_cb,
- (int64_t) (w->delay * 1000),
- (int64_t) (w->repeat * 1000));
-}
-
-
-inline static void __ev_timer_stop(__ev_timer* w) {
- __uv_warn_of(ev_timer, uv_timer_t);
- uv_timer_stop(&w->handle);
-}
-
-
-inline static void __ev_timer_again(__ev_timer* w) {
- __uv_warn_of(ev_timer, uv_timer_t);
- if (w->flags & 1)
- uv_timer_again(&w->handle);
- else
- __ev_timer_start(w); /* work around node-zookeeper bug */
-}
-
-
-/* Evil. Using this will void your warranty. */
-inline static void __ev_ref(void) {
- __uv_warn_of(ev_ref, uv_ref);
- uv_default_loop()->active_handles++;
-}
-
-
-/* Evil. Using this will void your warranty. */
-inline static void __ev_unref(void) {
- __uv_warn_of(ev_unref, uv_unref);
- uv_default_loop()->active_handles--;
-}
-
-
-inline static double __ev_now(...) {
- return uv_hrtime() / 1e9;
-}
-
-
-inline static void __ev_set_priority(...) {
-}
-
-
-#define ev_io __ev_io
-#define ev_io_init __ev_io_init
-#define ev_io_set __ev_io_set
-#define ev_io_start __ev_io_start
-#define ev_io_stop __ev_io_stop
-
-#define ev_timer __ev_timer
-#define ev_timer_init __ev_timer_init
-#define ev_timer_set __ev_timer_set
-#define ev_timer_start __ev_timer_start
-#define ev_timer_stop __ev_timer_stop
-#define ev_timer_again __ev_timer_again
-
-#define ev_ref __ev_ref
-#define ev_unref __ev_unref
-
-#define ev_now __ev_now
-#define ev_set_priority __ev_set_priority
-
-#undef __uv_container_of
-#undef __uv_warn_of
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* NODE_EV_EMUL_H_ */
diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc
index bb4573300..7e3eb8c52 100644
--- a/src/fs_event_wrap.cc
+++ b/src/fs_event_wrap.cc
@@ -51,7 +51,7 @@ private:
FSEventWrap::FSEventWrap(Handle<Object> object): HandleWrap(object,
(uv_handle_t*)&handle_) {
- handle_.data = reinterpret_cast<void*>(this);
+ handle_.data = static_cast<void*>(this);
initialized_ = false;
}
@@ -119,7 +119,7 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
HandleScope scope;
Local<String> eventStr;
- FSEventWrap* wrap = reinterpret_cast<FSEventWrap*>(handle->data);
+ FSEventWrap* wrap = static_cast<FSEventWrap*>(handle->data);
assert(wrap->object_.IsEmpty() == false);
@@ -152,7 +152,8 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
Local<Value> argv[3] = {
Integer::New(status),
eventStr,
- filename ? (Local<Value>)String::New(filename) : Local<Value>::New(v8::Null())
+ filename ? static_cast<Local<Value> >(String::New(filename))
+ : Local<Value>::New(v8::Null())
};
if (onchange_sym.IsEmpty()) {
@@ -174,7 +175,9 @@ Handle<Value> FSEventWrap::Close(const Arguments& args) {
void* ptr = args.Holder()->GetPointerFromInternalField(0);
FSEventWrap* wrap = static_cast<FSEventWrap*>(ptr);
- if (wrap == NULL || wrap->initialized_ == false) return Undefined();
+ if (wrap == NULL || wrap->initialized_ == false) {
+ return Undefined();
+ }
wrap->initialized_ = false;
return HandleWrap::Close(args);
diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc
index ead7da1f7..817a4cfe1 100644
--- a/src/handle_wrap.cc
+++ b/src/handle_wrap.cc
@@ -23,6 +23,12 @@
#include "ngx-queue.h"
#include "handle_wrap.h"
+#define UNWRAP_NO_ABORT(type) \
+ assert(!args.Holder().IsEmpty()); \
+ assert(args.Holder()->InternalFieldCount() > 0); \
+ type* wrap = static_cast<type*>( \
+ args.Holder()->GetPointerFromInternalField(0));
+
namespace node {
using v8::Array;
@@ -53,10 +59,12 @@ void HandleWrap::Initialize(Handle<Object> target) {
Handle<Value> HandleWrap::Ref(const Arguments& args) {
HandleScope scope;
- UNWRAP(HandleWrap)
+ UNWRAP_NO_ABORT(HandleWrap)
- uv_ref(wrap->handle__);
- wrap->unref_ = false;
+ if (wrap) {
+ uv_ref(wrap->handle__);
+ wrap->unref_ = false;
+ }
return v8::Undefined();
}
@@ -65,10 +73,12 @@ Handle<Value> HandleWrap::Ref(const Arguments& args) {
Handle<Value> HandleWrap::Unref(const Arguments& args) {
HandleScope scope;
- UNWRAP(HandleWrap)
+ UNWRAP_NO_ABORT(HandleWrap)
- uv_unref(wrap->handle__);
- wrap->unref_ = true;
+ if (wrap) {
+ uv_unref(wrap->handle__);
+ wrap->unref_ = true;
+ }
return v8::Undefined();
}
diff --git a/src/handle_wrap.h b/src/handle_wrap.h
index a358e812a..951b9386f 100644
--- a/src/handle_wrap.h
+++ b/src/handle_wrap.h
@@ -53,6 +53,8 @@ class HandleWrap {
static v8::Handle<v8::Value> Ref(const v8::Arguments& args);
static v8::Handle<v8::Value> Unref(const v8::Arguments& args);
+ inline uv_handle_t* GetHandle() { return handle__; };
+
protected:
HandleWrap(v8::Handle<v8::Object> object, uv_handle_t* handle);
virtual ~HandleWrap();
diff --git a/src/node.cc b/src/node.cc
index 3d4008e5a..847ebaffb 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -23,12 +23,16 @@
#include "req_wrap.h"
#include "handle_wrap.h"
+#include "ares.h"
#include "uv.h"
#include "v8-debug.h"
-#if defined HAVE_DTRACE || defined HAVE_ETW
+#if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP
# include "node_dtrace.h"
#endif
+#if defined HAVE_PERFCTR
+# include "node_counters.h"
+#endif
#include <locale.h>
#include <signal.h>
@@ -62,14 +66,8 @@ typedef int mode_t;
#endif
#include "node_buffer.h"
-#ifdef __POSIX__
-# include "node_io_watcher.h"
-#endif
#include "node_file.h"
#include "node_http_parser.h"
-#ifdef __POSIX__
-# include "node_signal_watcher.h"
-#endif
#include "node_constants.h"
#include "node_javascript.h"
#include "node_version.h"
@@ -77,6 +75,9 @@ typedef int mode_t;
#if HAVE_OPENSSL
# include "node_crypto.h"
#endif
+#if HAVE_SYSTEMTAP
+#include "node_systemtap.h"
+#endif
#include "node_script.h"
#include "v8_typed_array.h"
@@ -99,6 +100,11 @@ Persistent<String> process_symbol;
Persistent<String> domain_symbol;
static Persistent<Object> process;
+static Persistent<Function> process_tickDomainCallback;
+static Persistent<Function> process_tickFromSpinner;
+static Persistent<Function> process_tickCallback;
+
+static Persistent<String> exports_symbol;
static Persistent<String> errno_symbol;
static Persistent<String> syscall_symbol;
@@ -109,9 +115,7 @@ static Persistent<String> rss_symbol;
static Persistent<String> heap_total_symbol;
static Persistent<String> heap_used_symbol;
-static Persistent<String> listeners_symbol;
-static Persistent<String> uncaught_exception_symbol;
-static Persistent<String> emit_symbol;
+static Persistent<String> fatal_exception_symbol;
static Persistent<String> enter_symbol;
static Persistent<String> exit_symbol;
@@ -131,12 +135,21 @@ static int max_stack_size = 0;
// used by C++ modules as well
bool no_deprecation = false;
-static uv_check_t check_tick_watcher;
-static uv_prepare_t prepare_tick_watcher;
static uv_idle_t tick_spinner;
static bool need_tick_cb;
static Persistent<String> tick_callback_sym;
+static uv_check_t check_immediate_watcher;
+static uv_idle_t idle_immediate_dummy;
+static bool need_immediate_cb;
+static Persistent<String> immediate_callback_sym;
+
+// for quick ref to tickCallback values
+static struct {
+ uint32_t length;
+ uint32_t index;
+ uint32_t depth;
+} tick_infobox;
#ifdef OPENSSL_NPN_NEGOTIATED
static bool use_npn = true;
@@ -150,86 +163,20 @@ static bool use_sni = true;
static bool use_sni = false;
#endif
-#ifdef __POSIX__
-// Buffer for getpwnam_r(), getgrpam_r() and other misc callers; keep this
-// scoped at file-level rather than method-level to avoid excess stack usage.
-static char getbuf[PATH_MAX + 1];
-#endif
-
-// We need to notify V8 when we're idle so that it can run the garbage
-// collector. The interface to this is V8::IdleNotification(). It returns
-// true if the heap hasn't be fully compacted, and needs to be run again.
-// Returning false means that it doesn't have anymore work to do.
-//
-// A rather convoluted algorithm has been devised to determine when Node is
-// idle. You'll have to figure it out for yourself.
-static uv_check_t gc_check;
-static uv_idle_t gc_idle;
-static uv_timer_t gc_timer;
-bool need_gc;
-
// process-relative uptime base, initialized at start-up
static double prog_start_time;
-#define FAST_TICK 700.
-#define GC_WAIT_TIME 5000.
-#define RPM_SAMPLES 100
-#define TICK_TIME(n) tick_times[(tick_time_head - (n)) % RPM_SAMPLES]
-static int64_t tick_times[RPM_SAMPLES];
-static int tick_time_head;
-
-static void CheckStatus(uv_timer_t* watcher, int status);
-
-static void StartGCTimer () {
- if (!uv_is_active((uv_handle_t*) &gc_timer)) {
- uv_timer_start(&gc_timer, node::CheckStatus, 5000, 5000);
- }
-}
-
-static void StopGCTimer () {
- if (uv_is_active((uv_handle_t*) &gc_timer)) {
- uv_timer_stop(&gc_timer);
- }
-}
-
-static void Idle(uv_idle_t* watcher, int status) {
- assert((uv_idle_t*) watcher == &gc_idle);
-
- if (V8::IdleNotification()) {
- uv_idle_stop(&gc_idle);
- StopGCTimer();
- }
-}
-
-
-// Called directly after every call to select() (or epoll, or whatever)
-static void Check(uv_check_t* watcher, int status) {
- assert(watcher == &gc_check);
-
- tick_times[tick_time_head] = uv_now(uv_default_loop());
- tick_time_head = (tick_time_head + 1) % RPM_SAMPLES;
-
- StartGCTimer();
-
- for (int i = 0; i < (int)(GC_WAIT_TIME/FAST_TICK); i++) {
- double d = TICK_TIME(i+1) - TICK_TIME(i+2);
- //printf("d = %f\n", d);
- // If in the last 5 ticks the difference between
- // ticks was less than 0.7 seconds, then continue.
- if (d < FAST_TICK) {
- //printf("---\n");
- return;
- }
- }
+static volatile bool debugger_running = false;
+static uv_async_t dispatch_debug_messages_async;
- // Otherwise start the gc!
+// Declared in node_internals.h
+Isolate* node_isolate = NULL;
- //fprintf(stderr, "start idle 2\n");
- uv_idle_start(&gc_idle, node::Idle);
-}
+static void Spin(uv_idle_t* handle, int status) {
+ assert((uv_idle_t*) handle == &tick_spinner);
+ assert(status == 0);
-static void Tick(void) {
// Avoid entering a V8 scope.
if (!need_tick_cb) return;
need_tick_cb = false;
@@ -238,18 +185,19 @@ static void Tick(void) {
HandleScope scope;
- if (tick_callback_sym.IsEmpty()) {
- // Lazily set the symbol
- tick_callback_sym = NODE_PSYMBOL("_tickCallback");
+ if (process_tickFromSpinner.IsEmpty()) {
+ Local<Value> cb_v = process->Get(String::New("_tickFromSpinner"));
+ if (!cb_v->IsFunction()) {
+ fprintf(stderr, "process._tickFromSpinner assigned to non-function\n");
+ abort();
+ }
+ Local<Function> cb = cb_v.As<Function>();
+ process_tickFromSpinner = Persistent<Function>::New(cb);
}
- Local<Value> cb_v = process->Get(tick_callback_sym);
- if (!cb_v->IsFunction()) return;
- Local<Function> cb = Local<Function>::Cast(cb_v);
-
TryCatch try_catch;
- cb->Call(process, 0, NULL);
+ process_tickFromSpinner->Call(process, 0, NULL);
if (try_catch.HasCaught()) {
FatalException(try_catch);
@@ -257,40 +205,34 @@ static void Tick(void) {
}
-static void Spin(uv_idle_t* handle, int status) {
- assert((uv_idle_t*) handle == &tick_spinner);
- assert(status == 0);
- Tick();
-}
-
-static void StartTickSpinner() {
+static Handle<Value> NeedTickCallback(const Arguments& args) {
need_tick_cb = true;
- // TODO: this tick_spinner shouldn't be necessary. An ev_prepare should be
- // sufficent, the problem is only in the case of the very last "tick" -
- // there is nothing left to do in the event loop and libev will exit. The
- // ev_prepare callback isn't called before exiting. Thus we start this
- // tick_spinner to keep the event loop alive long enough to handle it.
uv_idle_start(&tick_spinner, Spin);
-}
-
-static Handle<Value> NeedTickCallback(const Arguments& args) {
- StartTickSpinner();
return Undefined();
}
-static void PrepareTick(uv_prepare_t* handle, int status) {
- assert(handle == &prepare_tick_watcher);
+
+static void CheckImmediate(uv_check_t* handle, int status) {
+ assert(handle == &check_immediate_watcher);
assert(status == 0);
- Tick();
+
+ HandleScope scope;
+
+ if (immediate_callback_sym.IsEmpty()) {
+ immediate_callback_sym = NODE_PSYMBOL("_immediateCallback");
+ }
+
+ MakeCallback(process, immediate_callback_sym, 0, NULL);
}
-static void CheckTick(uv_check_t* handle, int status) {
- assert(handle == &check_tick_watcher);
+static void IdleImmediateDummy(uv_idle_t* handle, int status) {
+ // Do nothing. Only for maintaining event loop
+ assert(handle == &idle_immediate_dummy);
assert(status == 0);
- Tick();
}
+
static inline const char *errno_string(int errorno) {
#define ERRNO_CASE(e) case e: return #e;
switch (errorno) {
@@ -705,6 +647,10 @@ const char *signo_string(int signo) {
SIGNO_CASE(SIGTSTP);
#endif
+#ifdef SIGBREAK
+ SIGNO_CASE(SIGBREAK);
+#endif
+
#ifdef SIGTTIN
SIGNO_CASE(SIGTTIN);
#endif
@@ -939,101 +885,124 @@ Local<Value> WinapiErrnoException(int errorno,
#endif
-Handle<Value> FromConstructorTemplate(Persistent<FunctionTemplate>& t,
+Handle<Value> FromConstructorTemplate(Persistent<FunctionTemplate> t,
const Arguments& args) {
HandleScope scope;
+ Local<Value> argv[32];
+ unsigned argc = args.Length();
+ if (argc > ARRAY_SIZE(argv)) argc = ARRAY_SIZE(argv);
+ for (unsigned i = 0; i < argc; ++i) argv[i] = args[i];
+ return scope.Close(t->GetFunction()->NewInstance(argc, argv));
+}
- const int argc = args.Length();
- Local<Value>* argv = new Local<Value>[argc];
- for (int i = 0; i < argc; ++i) {
- argv[i] = args[i];
+Handle<Value>
+MakeDomainCallback(const Handle<Object> object,
+ const Handle<Function> callback,
+ int argc,
+ Handle<Value> argv[]) {
+ // lazy load _tickDomainCallback
+ if (process_tickDomainCallback.IsEmpty()) {
+ Local<Value> cb_v = process->Get(String::New("_tickDomainCallback"));
+ if (!cb_v->IsFunction()) {
+ fprintf(stderr, "process._tickDomainCallback assigned to non-function\n");
+ abort();
+ }
+ Local<Function> cb = cb_v.As<Function>();
+ process_tickDomainCallback = Persistent<Function>::New(cb);
}
- Local<Object> instance = t->GetFunction()->NewInstance(argc, argv);
+ // lazy load domain specific symbols
+ if (enter_symbol.IsEmpty()) {
+ enter_symbol = NODE_PSYMBOL("enter");
+ exit_symbol = NODE_PSYMBOL("exit");
+ disposed_symbol = NODE_PSYMBOL("_disposed");
+ }
- delete[] argv;
+ Local<Value> domain_v = object->Get(domain_symbol);
+ Local<Object> domain;
+ Local<Function> enter;
+ Local<Function> exit;
- return scope.Close(instance);
-}
+ TryCatch try_catch;
+ domain = domain_v->ToObject();
+ assert(!domain.IsEmpty());
+ if (domain->Get(disposed_symbol)->IsTrue()) {
+ // domain has been disposed of.
+ return Undefined();
+ }
+ enter = Local<Function>::Cast(domain->Get(enter_symbol));
+ assert(!enter.IsEmpty());
+ enter->Call(domain, 0, NULL);
-// MakeCallback may only be made directly off the event loop.
-// That is there can be no JavaScript stack frames underneath it.
-// (Is there any way to assert that?)
-//
-// Maybe make this a method of a node::Handle super class
-//
-Handle<Value>
-MakeCallback(const Handle<Object> object,
- const char* method,
- int argc,
- Handle<Value> argv[]) {
- HandleScope scope;
+ if (try_catch.HasCaught()) {
+ FatalException(try_catch);
+ return Undefined();
+ }
- Handle<Value> ret =
- MakeCallback(object, String::NewSymbol(method), argc, argv);
+ Local<Value> ret = callback->Call(object, argc, argv);
- return scope.Close(ret);
-}
+ if (try_catch.HasCaught()) {
+ FatalException(try_catch);
+ return Undefined();
+ }
-Handle<Value>
-MakeCallback(const Handle<Object> object,
- const Handle<String> symbol,
- int argc,
- Handle<Value> argv[]) {
- HandleScope scope;
+ exit = Local<Function>::Cast(domain->Get(exit_symbol));
+ assert(!exit.IsEmpty());
+ exit->Call(domain, 0, NULL);
+
+ if (try_catch.HasCaught()) {
+ FatalException(try_catch);
+ return Undefined();
+ }
- Local<Value> callback_v = object->Get(symbol);
- if (!callback_v->IsFunction()) {
- String::Utf8Value method(symbol);
- // XXX: If the object has a domain attached, handle it there?
- // At least, would be good to get *some* sort of indication
- // of how we got here, even if it's not catchable.
- fprintf(stderr, "Non-function in MakeCallback. method = %s\n", *method);
- abort();
+ if (tick_infobox.length == 0) {
+ tick_infobox.index = 0;
+ tick_infobox.depth = 0;
+ return ret;
}
- Local<Function> callback = Local<Function>::Cast(callback_v);
+ // process nextTicks after call
+ process_tickDomainCallback->Call(process, 0, NULL);
- return scope.Close(MakeCallback(object, callback, argc, argv));
+ if (try_catch.HasCaught()) {
+ FatalException(try_catch);
+ return Undefined();
+ }
+
+ return ret;
}
+
Handle<Value>
MakeCallback(const Handle<Object> object,
- const Handle<Function> callback,
+ const Handle<String> symbol,
int argc,
Handle<Value> argv[]) {
HandleScope scope;
+ Local<Function> callback = object->Get(symbol).As<Function>();
+ Local<Value> domain = object->Get(domain_symbol);
+
// TODO Hook for long stack traces to be made here.
- TryCatch try_catch;
+ // has domain, off with you
+ if (!domain->IsNull() && !domain->IsUndefined())
+ return scope.Close(MakeDomainCallback(object, callback, argc, argv));
- if (enter_symbol.IsEmpty()) {
- enter_symbol = NODE_PSYMBOL("enter");
- exit_symbol = NODE_PSYMBOL("exit");
- disposed_symbol = NODE_PSYMBOL("_disposed");
- }
-
- Local<Value> domain_v = object->Get(domain_symbol);
- Local<Object> domain;
- Local<Function> enter;
- Local<Function> exit;
- if (domain_v->IsObject()) {
- domain = domain_v->ToObject();
- if (domain->Get(disposed_symbol)->BooleanValue()) {
- // domain has been disposed of.
- return Undefined();
+ // lazy load no domain next tick callbacks
+ if (process_tickCallback.IsEmpty()) {
+ Local<Value> cb_v = process->Get(String::New("_tickCallback"));
+ if (!cb_v->IsFunction()) {
+ fprintf(stderr, "process._tickCallback assigned to non-function\n");
+ abort();
}
- enter = Local<Function>::Cast(domain->Get(enter_symbol));
- enter->Call(domain, 0, NULL);
+ Local<Function> cb = cb_v.As<Function>();
+ process_tickCallback = Persistent<Function>::New(cb);
}
- if (try_catch.HasCaught()) {
- FatalException(try_catch);
- return Undefined();
- }
+ TryCatch try_catch;
Local<Value> ret = callback->Call(object, argc, argv);
@@ -1042,11 +1011,15 @@ MakeCallback(const Handle<Object> object,
return Undefined();
}
- if (domain_v->IsObject()) {
- exit = Local<Function>::Cast(domain->Get(exit_symbol));
- exit->Call(domain, 0, NULL);
+ if (tick_infobox.length == 0) {
+ tick_infobox.index = 0;
+ tick_infobox.depth = 0;
+ return scope.Close(ret);
}
+ // process nextTicks after call
+ process_tickCallback->Call(process, 0, NULL);
+
if (try_catch.HasCaught()) {
FatalException(try_catch);
return Undefined();
@@ -1056,20 +1029,34 @@ MakeCallback(const Handle<Object> object,
}
+Handle<Value>
+MakeCallback(const Handle<Object> object,
+ const char* method,
+ int argc,
+ Handle<Value> argv[]) {
+ HandleScope scope;
+
+ Handle<Value> ret =
+ MakeCallback(object, String::NewSymbol(method), argc, argv);
+
+ return scope.Close(ret);
+}
+
+
void SetErrno(uv_err_t err) {
HandleScope scope;
+ static Persistent<String> errno_symbol;
if (errno_symbol.IsEmpty()) {
- errno_symbol = NODE_PSYMBOL("errno");
+ errno_symbol = NODE_PSYMBOL("_errno");
}
if (err.code == UV_UNKNOWN) {
char errno_buf[100];
snprintf(errno_buf, 100, "Unknown system errno %d", err.sys_errno_);
- Context::GetCurrent()->Global()->Set(errno_symbol, String::New(errno_buf));
+ process->Set(errno_symbol, String::New(errno_buf));
} else {
- Context::GetCurrent()->Global()->Set(errno_symbol,
- String::NewSymbol(uv_err_name(err)));
+ process->Set(errno_symbol, String::NewSymbol(uv_err_name(err)));
}
}
@@ -1099,6 +1086,8 @@ enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
return UCS2;
} else if (strcasecmp(*encoding, "binary") == 0) {
return BINARY;
+ } else if (strcasecmp(*encoding, "buffer") == 0) {
+ return BUFFER;
} else if (strcasecmp(*encoding, "hex") == 0) {
return HEX;
} else if (strcasecmp(*encoding, "raw") == 0) {
@@ -1121,6 +1110,11 @@ enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) {
HandleScope scope;
+ if (encoding == BUFFER) {
+ return scope.Close(
+ Buffer::New(static_cast<const char*>(buf), len)->handle_);
+ }
+
if (!len) return scope.Close(String::Empty());
if (encoding == BINARY) {
@@ -1151,7 +1145,7 @@ ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
return -1;
}
- if (encoding == BINARY && Buffer::HasInstance(val)) {
+ if ((encoding == BUFFER || encoding == BINARY) && Buffer::HasInstance(val)) {
return Buffer::Length(val->ToObject());
}
@@ -1190,7 +1184,8 @@ ssize_t DecodeWrite(char *buf,
bool is_buffer = Buffer::HasInstance(val);
- if (is_buffer && encoding == BINARY) { // fast path, copy buffer data
+ if (is_buffer && (encoding == BINARY || encoding == BUFFER)) {
+ // fast path, copy buffer data
const char* data = Buffer::Data(val.As<Object>());
size_t size = Buffer::Length(val.As<Object>());
size_t len = size < buflen ? size : buflen;
@@ -1342,13 +1337,13 @@ Local<Value> ExecuteString(Handle<String> source, Handle<Value> filename) {
Local<v8::Script> script = v8::Script::Compile(source, filename);
if (script.IsEmpty()) {
ReportException(try_catch, true);
- exit(1);
+ exit(3);
}
Local<Value> result = script->Run();
if (result.IsEmpty()) {
ReportException(try_catch, true);
- exit(1);
+ exit(4);
}
return scope.Close(result);
@@ -1481,6 +1476,108 @@ static Handle<Value> Umask(const Arguments& args) {
#ifdef __POSIX__
+static const uid_t uid_not_found = static_cast<uid_t>(-1);
+static const gid_t gid_not_found = static_cast<gid_t>(-1);
+
+
+static uid_t uid_by_name(const char* name) {
+ struct passwd pwd;
+ struct passwd* pp;
+ char buf[8192];
+ int rc;
+
+ errno = 0;
+ pp = NULL;
+
+ if ((rc = getpwnam_r(name, &pwd, buf, sizeof(buf), &pp)) == 0 && pp != NULL) {
+ return pp->pw_uid;
+ }
+
+ return uid_not_found;
+}
+
+
+static char* name_by_uid(uid_t uid) {
+ struct passwd pwd;
+ struct passwd* pp;
+ char buf[8192];
+ int rc;
+
+ errno = 0;
+ pp = NULL;
+
+ if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 && pp != NULL) {
+ return strdup(pp->pw_name);
+ }
+
+ if (rc == 0) {
+ errno = ENOENT;
+ }
+
+ return NULL;
+}
+
+
+static gid_t gid_by_name(const char* name) {
+ struct group pwd;
+ struct group* pp;
+ char buf[8192];
+ int rc;
+
+ errno = 0;
+ pp = NULL;
+
+ if ((rc = getgrnam_r(name, &pwd, buf, sizeof(buf), &pp)) == 0 && pp != NULL) {
+ return pp->gr_gid;
+ }
+
+ return gid_not_found;
+}
+
+
+#if 0 // For future use.
+static const char* name_by_gid(gid_t gid) {
+ struct group pwd;
+ struct group* pp;
+ char buf[8192];
+ int rc;
+
+ errno = 0;
+ pp = NULL;
+
+ if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 && pp != NULL) {
+ return strdup(pp->gr_name);
+ }
+
+ if (rc == 0) {
+ errno = ENOENT;
+ }
+
+ return NULL;
+}
+#endif
+
+
+static uid_t uid_by_name(Handle<Value> value) {
+ if (value->IsUint32()) {
+ return static_cast<uid_t>(value->Uint32Value());
+ } else {
+ String::Utf8Value name(value);
+ return uid_by_name(*name);
+ }
+}
+
+
+static gid_t gid_by_name(Handle<Value> value) {
+ if (value->IsUint32()) {
+ return static_cast<gid_t>(value->Uint32Value());
+ } else {
+ String::Utf8Value name(value);
+ return gid_by_name(*name);
+ }
+}
+
+
static Handle<Value> GetUid(const Arguments& args) {
HandleScope scope;
int uid = getuid();
@@ -1498,40 +1595,20 @@ static Handle<Value> GetGid(const Arguments& args) {
static Handle<Value> SetGid(const Arguments& args) {
HandleScope scope;
- if (args.Length() < 1) {
- return ThrowException(Exception::Error(
- String::New("setgid requires 1 argument")));
- }
-
- int gid;
-
- if (args[0]->IsNumber()) {
- gid = args[0]->Int32Value();
- } else if (args[0]->IsString()) {
- String::Utf8Value grpnam(args[0]);
- struct group grp, *grpp = NULL;
- int err;
-
- errno = 0;
- if ((err = getgrnam_r(*grpnam, &grp, getbuf, ARRAY_SIZE(getbuf), &grpp)) ||
- grpp == NULL) {
- if (errno == 0)
- return ThrowException(Exception::Error(
- String::New("setgid group id does not exist")));
- else
- return ThrowException(ErrnoException(errno, "getgrnam_r"));
- }
+ if (!args[0]->IsUint32() && !args[0]->IsString()) {
+ return ThrowTypeError("setgid argument must be a number or a string");
+ }
- gid = grpp->gr_gid;
- } else {
- return ThrowException(Exception::Error(
- String::New("setgid argument must be a number or a string")));
+ gid_t gid = gid_by_name(args[0]);
+
+ if (gid == gid_not_found) {
+ return ThrowError("setgid group id does not exist");
}
- int result;
- if ((result = setgid(gid)) != 0) {
+ if (setgid(gid)) {
return ThrowException(ErrnoException(errno, "setgid"));
}
+
return Undefined();
}
@@ -1539,122 +1616,163 @@ static Handle<Value> SetGid(const Arguments& args) {
static Handle<Value> SetUid(const Arguments& args) {
HandleScope scope;
- if (args.Length() < 1) {
- return ThrowException(Exception::Error(
- String::New("setuid requires 1 argument")));
- }
-
- int uid;
-
- if (args[0]->IsNumber()) {
- uid = args[0]->Int32Value();
- } else if (args[0]->IsString()) {
- String::Utf8Value pwnam(args[0]);
- struct passwd pwd, *pwdp = NULL;
- int err;
-
- errno = 0;
- if ((err = getpwnam_r(*pwnam, &pwd, getbuf, ARRAY_SIZE(getbuf), &pwdp)) ||
- pwdp == NULL) {
- if (errno == 0)
- return ThrowException(Exception::Error(
- String::New("setuid user id does not exist")));
- else
- return ThrowException(ErrnoException(errno, "getpwnam_r"));
- }
+ if (!args[0]->IsUint32() && !args[0]->IsString()) {
+ return ThrowTypeError("setuid argument must be a number or a string");
+ }
- uid = pwdp->pw_uid;
- } else {
- return ThrowException(Exception::Error(
- String::New("setuid argument must be a number or a string")));
+ uid_t uid = uid_by_name(args[0]);
+
+ if (uid == uid_not_found) {
+ return ThrowError("setuid user id does not exist");
}
- int result;
- if ((result = setuid(uid)) != 0) {
+ if (setuid(uid)) {
return ThrowException(ErrnoException(errno, "setuid"));
}
+
return Undefined();
}
-#endif // __POSIX__
+static Handle<Value> GetGroups(const Arguments& args) {
+ HandleScope scope;
+ int ngroups = getgroups(0, NULL);
-v8::Handle<v8::Value> Exit(const v8::Arguments& args) {
- HandleScope scope;
- exit(args[0]->IntegerValue());
- return Undefined();
+ if (ngroups == -1) {
+ return ThrowException(ErrnoException(errno, "getgroups"));
+ }
+
+ gid_t* groups = new gid_t[ngroups];
+
+ ngroups = getgroups(ngroups, groups);
+
+ if (ngroups == -1) {
+ delete[] groups;
+ return ThrowException(ErrnoException(errno, "getgroups"));
+ }
+
+ Local<Array> groups_list = Array::New(ngroups);
+ bool seen_egid = false;
+ gid_t egid = getegid();
+
+ for (int i = 0; i < ngroups; i++) {
+ groups_list->Set(i, Integer::New(groups[i]));
+ if (groups[i] == egid) seen_egid = true;
+ }
+
+ delete[] groups;
+
+ if (seen_egid == false) {
+ groups_list->Set(ngroups, Integer::New(egid));
+ }
+
+ return scope.Close(groups_list);
}
-static void CheckStatus(uv_timer_t* watcher, int status) {
- assert(watcher == &gc_timer);
+static Handle<Value> SetGroups(const Arguments& args) {
+ HandleScope scope;
- // check memory
- if (!uv_is_active((uv_handle_t*) &gc_idle)) {
- HeapStatistics stats;
- V8::GetHeapStatistics(&stats);
- if (stats.total_heap_size() > 1024 * 1024 * 128) {
- // larger than 128 megs, just start the idle watcher
- uv_idle_start(&gc_idle, node::Idle);
- return;
- }
+ if (!args[0]->IsArray()) {
+ return ThrowTypeError("argument 1 must be an array");
}
- double d = uv_now(uv_default_loop()) - TICK_TIME(3);
+ Local<Array> groups_list = args[0].As<Array>();
+ size_t size = groups_list->Length();
+ gid_t* groups = new gid_t[size];
- //printfb("timer d = %f\n", d);
+ for (size_t i = 0; i < size; i++) {
+ gid_t gid = gid_by_name(groups_list->Get(i));
- if (d >= GC_WAIT_TIME - 1.) {
- //fprintf(stderr, "start idle\n");
- uv_idle_start(&gc_idle, node::Idle);
+ if (gid == gid_not_found) {
+ delete[] groups;
+ return ThrowError("group name not found");
+ }
+
+ groups[i] = gid;
}
+
+ int rc = setgroups(size, groups);
+ delete[] groups;
+
+ if (rc == -1) {
+ return ThrowException(ErrnoException(errno, "setgroups"));
+ }
+
+ return Undefined();
}
-static Handle<Value> Uptime(const Arguments& args) {
+static Handle<Value> InitGroups(const Arguments& args) {
HandleScope scope;
- double uptime;
- uv_err_t err = uv_uptime(&uptime);
+ if (!args[0]->IsUint32() && !args[0]->IsString()) {
+ return ThrowTypeError("argument 1 must be a number or a string");
+ }
- if (err.code != UV_OK) {
- return Undefined();
+ if (!args[1]->IsUint32() && !args[1]->IsString()) {
+ return ThrowTypeError("argument 2 must be a number or a string");
}
- return scope.Close(Number::New(uptime - prog_start_time));
+ String::Utf8Value arg0(args[0]);
+ gid_t extra_group;
+ bool must_free;
+ char* user;
+
+ if (args[0]->IsUint32()) {
+ user = name_by_uid(args[0]->Uint32Value());
+ must_free = true;
+ } else {
+ user = *arg0;
+ must_free = false;
+ }
+
+ if (user == NULL) {
+ return ThrowError("initgroups user not found");
+ }
+
+ extra_group = gid_by_name(args[1]);
+
+ if (extra_group == gid_not_found) {
+ if (must_free) free(user);
+ return ThrowError("initgroups extra group not found");
+ }
+
+ int rc = initgroups(user, extra_group);
+
+ if (must_free) {
+ free(user);
+ }
+
+ if (rc) {
+ return ThrowException(ErrnoException(errno, "initgroups"));
+ }
+
+ return Undefined();
}
+#endif // __POSIX__
+
-v8::Handle<v8::Value> UVCounters(const v8::Arguments& args) {
+v8::Handle<v8::Value> Exit(const v8::Arguments& args) {
HandleScope scope;
+ exit(args[0]->IntegerValue());
+ return Undefined();
+}
- uv_counters_t* c = &uv_default_loop()->counters;
- Local<Object> obj = Object::New();
+static Handle<Value> Uptime(const Arguments& args) {
+ HandleScope scope;
+ double uptime;
-#define setc(name) \
- obj->Set(String::New(#name), Integer::New(static_cast<int32_t>(c->name)));
-
- setc(eio_init)
- setc(req_init)
- setc(handle_init)
- setc(stream_init)
- setc(tcp_init)
- setc(udp_init)
- setc(pipe_init)
- setc(tty_init)
- setc(prepare_init)
- setc(check_init)
- setc(idle_init)
- setc(async_init)
- setc(timer_init)
- setc(process_init)
- setc(fs_event_init)
-
-#undef setc
+ uv_err_t err = uv_uptime(&uptime);
- return scope.Close(obj);
+ if (err.code != UV_OK) {
+ return Undefined();
+ }
+
+ return scope.Close(Number::New(uptime - prog_start_time));
}
@@ -1746,13 +1864,12 @@ Handle<Value> Hrtime(const v8::Arguments& args) {
typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
-// DLOpen is node.dlopen(). Used to load 'module.node' dynamically shared
-// objects.
+// DLOpen is process.dlopen(module, filename).
+// Used to load 'module.node' dynamically shared objects.
Handle<Value> DLOpen(const v8::Arguments& args) {
HandleScope scope;
char symbol[1024], *base, *pos;
uv_lib_t lib;
- node_module_struct compat_mod;
int r;
if (args.Length() < 2) {
@@ -1761,8 +1878,13 @@ Handle<Value> DLOpen(const v8::Arguments& args) {
return ThrowException(exception);
}
- String::Utf8Value filename(args[0]); // Cast
- Local<Object> target = args[1]->ToObject(); // Cast
+ Local<Object> module = args[0]->ToObject(); // Cast
+ String::Utf8Value filename(args[1]); // Cast
+
+ if (exports_symbol.IsEmpty()) {
+ exports_symbol = NODE_PSYMBOL("exports");
+ }
+ Local<Object> exports = module->Get(exports_symbol)->ToObject();
if (uv_dlopen(*filename, &lib)) {
Local<String> errmsg = String::New(uv_dlerror(&lib));
@@ -1773,7 +1895,7 @@ Handle<Value> DLOpen(const v8::Arguments& args) {
return ThrowException(Exception::Error(errmsg));
}
- String::Utf8Value path(args[0]);
+ String::Utf8Value path(args[1]);
base = *path;
/* Find the shared library filename within the full path. */
@@ -1806,31 +1928,31 @@ Handle<Value> DLOpen(const v8::Arguments& args) {
return ThrowException(exception);
}
- // Get the init() function from the dynamically shared object.
+ /* Replace dashes with underscores. When loading foo-bar.node,
+ * look for foo_bar_module, not foo-bar_module.
+ */
+ for (pos = symbol; *pos != '\0'; ++pos) {
+ if (*pos == '-') *pos = '_';
+ }
+
node_module_struct *mod;
if (uv_dlsym(&lib, symbol, reinterpret_cast<void**>(&mod))) {
- /* Start Compatibility hack: Remove once everyone is using NODE_MODULE macro */
- memset(&compat_mod, 0, sizeof compat_mod);
-
- mod = &compat_mod;
- mod->version = NODE_MODULE_VERSION;
-
- if (uv_dlsym(&lib, "init", reinterpret_cast<void**>(&mod->register_func))) {
- Local<String> errmsg = String::New(uv_dlerror(&lib));
- uv_dlclose(&lib);
- return ThrowException(Exception::Error(errmsg));
- }
- /* End Compatibility hack */
+ char errmsg[1024];
+ snprintf(errmsg, sizeof(errmsg), "Symbol %s not found.", symbol);
+ return ThrowError(errmsg);
}
if (mod->version != NODE_MODULE_VERSION) {
- Local<Value> exception = Exception::Error(
- String::New("Module version mismatch, refusing to load."));
- return ThrowException(exception);
+ char errmsg[1024];
+ snprintf(errmsg,
+ sizeof(errmsg),
+ "Module version mismatch. Expected %d, got %d.",
+ NODE_MODULE_VERSION, mod->version);
+ return ThrowError(errmsg);
}
// Execute the C++ module
- mod->register_func(target);
+ mod->register_func(exports, module);
// Tell coverity that 'handle' should not be freed when we return.
// coverity[leaked_storage]
@@ -1844,58 +1966,44 @@ static void OnFatalError(const char* location, const char* message) {
} else {
fprintf(stderr, "FATAL ERROR: %s\n", message);
}
- exit(1);
+ exit(5);
}
void FatalException(TryCatch &try_catch) {
HandleScope scope;
- if (listeners_symbol.IsEmpty()) {
- listeners_symbol = NODE_PSYMBOL("listeners");
- uncaught_exception_symbol = NODE_PSYMBOL("uncaughtException");
- emit_symbol = NODE_PSYMBOL("emit");
- }
-
- Local<Value> listeners_v = process->Get(listeners_symbol);
- assert(listeners_v->IsFunction());
-
- Local<Function> listeners = Local<Function>::Cast(listeners_v);
-
- Local<String> uncaught_exception_symbol_l = Local<String>::New(uncaught_exception_symbol);
- Local<Value> argv[1] = { uncaught_exception_symbol_l };
- Local<Value> ret = listeners->Call(process, 1, argv);
+ if (fatal_exception_symbol.IsEmpty())
+ fatal_exception_symbol = NODE_PSYMBOL("_fatalException");
- assert(ret->IsArray());
+ Local<Value> fatal_v = process->Get(fatal_exception_symbol);
- Local<Array> listener_array = Local<Array>::Cast(ret);
-
- uint32_t length = listener_array->Length();
- // Report and exit if process has no "uncaughtException" listener
- if (length == 0) {
+ if (!fatal_v->IsFunction()) {
+ // failed before the process._fatalException function was added!
+ // this is probably pretty bad. Nothing to do but report and exit.
ReportException(try_catch, true);
- exit(1);
+ exit(6);
}
- // Otherwise fire the process "uncaughtException" event
- Local<Value> emit_v = process->Get(emit_symbol);
- assert(emit_v->IsFunction());
-
- Local<Function> emit = Local<Function>::Cast(emit_v);
+ Local<Function> fatal_f = Local<Function>::Cast(fatal_v);
Local<Value> error = try_catch.Exception();
- Local<Value> event_argv[2] = { uncaught_exception_symbol_l, error };
+ Local<Value> argv[] = { error };
+
+ TryCatch fatal_try_catch;
- TryCatch event_try_catch;
- emit->Call(process, 2, event_argv);
+ // this will return true if the JS layer handled it, false otherwise
+ Local<Value> caught = fatal_f->Call(process, ARRAY_SIZE(argv), argv);
- if (event_try_catch.HasCaught()) {
- // the uncaught exception event threw, so we must exit.
- ReportException(event_try_catch, true);
- exit(1);
+ if (fatal_try_catch.HasCaught()) {
+ // the fatal exception function threw, so we must exit
+ ReportException(fatal_try_catch, true);
+ exit(7);
}
- // This makes sure uncaught exceptions don't interfere with process.nextTick
- StartTickSpinner();
+ if (false == caught->BooleanValue()) {
+ ReportException(try_catch, true);
+ exit(8);
+ }
}
@@ -1928,7 +2036,9 @@ static Handle<Value> Binding(const Arguments& args) {
if ((modp = get_builtin_module(*module_v)) != NULL) {
exports = Object::New();
- modp->register_func(exports);
+ // Internal bindings don't have a "module" object,
+ // only exports.
+ modp->register_func(exports, Undefined());
binding_cache->Set(module, exports);
} else if (!strcmp(*module_v, "constants")) {
@@ -1936,13 +2046,6 @@ static Handle<Value> Binding(const Arguments& args) {
DefineConstants(exports);
binding_cache->Set(module, exports);
-#ifdef __POSIX__
- } else if (!strcmp(*module_v, "io_watcher")) {
- exports = Object::New();
- IOWatcher::Initialize(exports);
- binding_cache->Set(module, exports);
-#endif
-
} else if (!strcmp(*module_v, "natives")) {
exports = Object::New();
DefineJavaScript(exports);
@@ -1999,8 +2102,8 @@ static Handle<Value> EnvGetter(Local<String> property,
return scope.Close(String::New(reinterpret_cast<uint16_t*>(buffer), result));
}
#endif
- // Not found
- return Undefined();
+ // Not found. Fetch from prototype.
+ return scope.Close(info.Data().As<Object>()->Get(property));
}
@@ -2032,7 +2135,7 @@ static Handle<Integer> EnvQuery(Local<String> property,
#ifdef __POSIX__
String::Utf8Value key(property);
if (getenv(*key)) {
- return scope.Close(Integer::New(None));
+ return scope.Close(Integer::New(0));
}
#else // _WIN32
String::Value key(property);
@@ -2045,7 +2148,7 @@ static Handle<Integer> EnvQuery(Local<String> property,
v8::DontDelete ||
v8::DontEnum));
} else {
- return scope.Close(Integer::New(None));
+ return scope.Close(Integer::New(0));
}
}
#endif
@@ -2163,6 +2266,35 @@ static Handle<Value> DebugProcess(const Arguments& args);
static Handle<Value> DebugPause(const Arguments& args);
static Handle<Value> DebugEnd(const Arguments& args);
+
+Handle<Value> NeedImmediateCallbackGetter(Local<String> property,
+ const AccessorInfo& info) {
+ return Boolean::New(need_immediate_cb);
+}
+
+
+static void NeedImmediateCallbackSetter(Local<String> property,
+ Local<Value> value,
+ const AccessorInfo& info) {
+ HandleScope scope;
+
+ bool bool_value = value->BooleanValue();
+
+ if (need_immediate_cb == bool_value) return;
+
+ need_immediate_cb = bool_value;
+
+ if (need_immediate_cb) {
+ uv_check_start(&check_immediate_watcher, node::CheckImmediate);
+ // idle handle is needed only to maintain event loop
+ uv_idle_start(&idle_immediate_dummy, node::IdleImmediateDummy);
+ } else {
+ uv_check_stop(&check_immediate_watcher);
+ uv_idle_stop(&idle_immediate_dummy);
+ }
+}
+
+
Handle<Object> SetupProcessObject(int argc, char *argv[]) {
HandleScope scope;
@@ -2250,12 +2382,15 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
EnvQuery,
EnvDeleter,
EnvEnumerator,
- Undefined());
+ Object::New());
Local<Object> env = envTemplate->NewInstance();
process->Set(String::NewSymbol("env"), env);
process->Set(String::NewSymbol("pid"), Integer::New(getpid()));
process->Set(String::NewSymbol("features"), GetFeatures());
+ process->SetAccessor(String::New("_needImmediateCallback"),
+ NeedImmediateCallbackGetter,
+ NeedImmediateCallbackSetter);
// -e, --eval
if (eval_string) {
@@ -2314,6 +2449,10 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
NODE_SET_METHOD(process, "setgid", SetGid);
NODE_SET_METHOD(process, "getgid", GetGid);
+
+ NODE_SET_METHOD(process, "getgroups", GetGroups);
+ NODE_SET_METHOD(process, "setgroups", SetGroups);
+ NODE_SET_METHOD(process, "initgroups", InitGroups);
#endif // __POSIX__
NODE_SET_METHOD(process, "_kill", Kill);
@@ -2328,10 +2467,16 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
NODE_SET_METHOD(process, "uptime", Uptime);
NODE_SET_METHOD(process, "memoryUsage", MemoryUsage);
- NODE_SET_METHOD(process, "uvCounters", UVCounters);
NODE_SET_METHOD(process, "binding", Binding);
+ // values use to cross communicate with processNextTick
+ Local<Object> info_box = Object::New();
+ info_box->SetIndexedPropertiesToExternalArrayData(&tick_infobox,
+ kExternalUnsignedIntArray,
+ 3);
+ process->Set(String::NewSymbol("_tickInfoBox"), info_box);
+
return process;
}
@@ -2343,11 +2488,14 @@ static void AtExit() {
static void SignalExit(int signal) {
uv_tty_reset_mode();
- _exit(1);
+ _exit(128 + signal);
}
void Load(Handle<Object> process_l) {
+ process_symbol = NODE_PSYMBOL("process");
+ domain_symbol = NODE_PSYMBOL("domain");
+
// Compile, execute the src/node.js file. (Which was included as static C
// string in node_natives.h. 'natve_node' is the string containing that
// source code.)
@@ -2378,15 +2526,18 @@ void Load(Handle<Object> process_l) {
Local<Object> global = v8::Context::GetCurrent()->Global();
Local<Value> args[1] = { Local<Value>::New(process_l) };
-#if defined HAVE_DTRACE || defined HAVE_ETW
+#if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP
InitDTrace(global);
#endif
+#if defined HAVE_PERFCTR
+ InitPerfCounters(global);
+#endif
+
f->Call(global, 1, args);
if (try_catch.HasCaught()) {
- ReportException(try_catch, true);
- exit(11);
+ FatalException(try_catch);
}
}
@@ -2416,7 +2567,7 @@ static void ParseDebugOpt(const char* arg) {
if (p) fprintf(stderr, "Debug port must be in range 1025 to 65535.\n");
PrintHelp();
- exit(1);
+ exit(12);
}
static void PrintHelp() {
@@ -2426,7 +2577,7 @@ static void PrintHelp() {
"Options:\n"
" -v, --version print node's version\n"
" -e, --eval script evaluate script\n"
- " -p, --print print result of --eval\n"
+ " -p, --print evaluate script and print result\n"
" -i, --interactive always enter the REPL even if stdin\n"
" does not appear to be a terminal\n"
" --no-deprecation silence deprecation warnings\n"
@@ -2469,20 +2620,36 @@ static void ParseArgs(int argc, char **argv) {
} else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
PrintHelp();
exit(0);
- } else if (strcmp(arg, "--eval") == 0 || strcmp(arg, "-e") == 0 ||
- strcmp(arg, "-pe") == 0) {
- if (argc <= i + 1) {
- fprintf(stderr, "Error: --eval requires an argument\n");
- exit(1);
- }
- if (arg[1] == 'p') {
- print_eval = true;
+ } else if (strcmp(arg, "--eval") == 0 ||
+ strcmp(arg, "-e") == 0 ||
+ strcmp(arg, "--print") == 0 ||
+ strcmp(arg, "-pe") == 0 ||
+ strcmp(arg, "-p") == 0) {
+ bool is_eval = strchr(arg, 'e') != NULL;
+ bool is_print = strchr(arg, 'p') != NULL;
+
+ // argument to -p and --print is optional
+ if (is_eval == true && i + 1 >= argc) {
+ fprintf(stderr, "Error: %s requires an argument\n", arg);
+ exit(13);
}
+
+ print_eval = print_eval || is_print;
argv[i] = const_cast<char*>("");
+
+ // --eval, -e and -pe always require an argument
+ if (is_eval == true) {
+ eval_string = argv[++i];
+ continue;
+ }
+
+ // next arg is the expression to evaluate unless it starts with:
+ // - a dash, then it's another switch
+ // - "\\-", then it's an escaped expression, drop the backslash
+ if (argv[i + 1] == NULL) continue;
+ if (argv[i + 1][0] == '-') continue;
eval_string = argv[++i];
- } else if (strcmp(arg, "--print") == 0 || strcmp(arg, "-p") == 0) {
- print_eval = true;
- argv[i] = const_cast<char*>("");
+ if (strncmp(eval_string, "\\-", 2) == 0) ++eval_string;
} else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
force_repl = true;
argv[i] = const_cast<char*>("");
@@ -2503,13 +2670,6 @@ static void ParseArgs(int argc, char **argv) {
}
-static Isolate* node_isolate = NULL;
-static volatile bool debugger_running = false;
-
-
-static uv_async_t dispatch_debug_messages_async;
-
-
// Called from the main thread.
static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle, int status) {
v8::Debug::ProcessDebugMessages();
@@ -2554,7 +2714,7 @@ static void EnableDebug(bool wait_connect) {
#ifdef __POSIX__
-static void EnableDebugSignalHandler(int signal) {
+static void EnableDebugSignalHandler(uv_signal_t* handle, int) {
// Break once process will return execution to v8
v8::Debug::DebugBreak(node_isolate);
@@ -2817,25 +2977,11 @@ char** Init(int argc, char *argv[]) {
RegisterSignalHandler(SIGTERM, SignalExit);
#endif // __POSIX__
- uv_prepare_init(uv_default_loop(), &prepare_tick_watcher);
- uv_prepare_start(&prepare_tick_watcher, PrepareTick);
- uv_unref(reinterpret_cast<uv_handle_t*>(&prepare_tick_watcher));
-
- uv_check_init(uv_default_loop(), &check_tick_watcher);
- uv_check_start(&check_tick_watcher, node::CheckTick);
- uv_unref(reinterpret_cast<uv_handle_t*>(&check_tick_watcher));
-
uv_idle_init(uv_default_loop(), &tick_spinner);
- uv_check_init(uv_default_loop(), &gc_check);
- uv_check_start(&gc_check, node::Check);
- uv_unref(reinterpret_cast<uv_handle_t*>(&gc_check));
-
- uv_idle_init(uv_default_loop(), &gc_idle);
- uv_unref(reinterpret_cast<uv_handle_t*>(&gc_idle));
-
- uv_timer_init(uv_default_loop(), &gc_timer);
- uv_unref(reinterpret_cast<uv_handle_t*>(&gc_timer));
+ uv_check_init(uv_default_loop(), &check_immediate_watcher);
+ uv_unref((uv_handle_t*) &check_immediate_watcher);
+ uv_idle_init(uv_default_loop(), &idle_immediate_dummy);
V8::SetFatalErrorHandler(node::OnFatalError);
@@ -2850,7 +2996,10 @@ char** Init(int argc, char *argv[]) {
#ifdef _WIN32
RegisterDebugSignalHandler();
#else // Posix
- RegisterSignalHandler(SIGUSR1, EnableDebugSignalHandler);
+ static uv_signal_t signal_watcher;
+ uv_signal_init(uv_default_loop(), &signal_watcher);
+ uv_signal_start(&signal_watcher, EnableDebugSignalHandler, SIGUSR1);
+ uv_unref((uv_handle_t*)&signal_watcher);
#endif // __POSIX__
}
@@ -2955,9 +3104,6 @@ int Start(int argc, char *argv[]) {
Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
- process_symbol = NODE_PSYMBOL("process");
- domain_symbol = NODE_PSYMBOL("domain");
-
// Use original argv, as we're just copying values out of it.
Handle<Object> process_l = SetupProcessObject(argc, argv);
v8_typed_array::AttachBindings(context->Global());
@@ -2971,7 +3117,7 @@ int Start(int argc, char *argv[]) {
// there are no watchers on the loop (except for the ones that were
// uv_unref'd) then this function exits. As long as there are active
// watchers, it blocks.
- uv_run(uv_default_loop());
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
EmitExit(process_l);
RunAtExit();
diff --git a/src/node.h b/src/node.h
index 40e9705c2..5769a7b9c 100644
--- a/src/node.h
+++ b/src/node.h
@@ -83,6 +83,7 @@
# endif
#endif
+
namespace node {
NODE_EXTERN extern bool no_deprecation;
@@ -103,7 +104,7 @@ void EmitExit(v8::Handle<v8::Object> process);
#define NODE_DEFINE_CONSTANT(target, constant) \
(target)->Set(v8::String::NewSymbol(#constant), \
- v8::Integer::New(constant), \
+ v8::Number::New(constant), \
static_cast<v8::PropertyAttribute>( \
v8::ReadOnly|v8::DontDelete))
@@ -127,7 +128,7 @@ void SetPrototypeMethod(target_t target,
#define NODE_SET_METHOD node::SetMethod
#define NODE_SET_PROTOTYPE_METHOD node::SetPrototypeMethod
-enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX};
+enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v,
enum encoding _default = BINARY);
NODE_EXTERN void FatalException(v8::TryCatch &try_catch);
@@ -149,18 +150,6 @@ NODE_EXTERN ssize_t DecodeWrite(char *buf,
v8::Local<v8::Object> BuildStatsObject(const uv_statbuf_t* s);
-/**
- * Call this when your constructor is invoked as a regular function, e.g.
- * Buffer(10) instead of new Buffer(10).
- * @param constructorTemplate Constructor template to instantiate from.
- * @param args The arguments object passed to your constructor.
- * @see v8::Arguments::IsConstructCall
- */
-v8::Handle<v8::Value> FromConstructorTemplate(
- v8::Persistent<v8::FunctionTemplate>& constructorTemplate,
- const v8::Arguments& args);
-
-
static inline v8::Persistent<v8::Function>* cb_persist(
const v8::Local<v8::Value> &v) {
v8::Persistent<v8::Function> *fn = new v8::Persistent<v8::Function>();
@@ -198,11 +187,15 @@ NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(int errorno,
const char *signo_string(int errorno);
+
+NODE_EXTERN typedef void (* addon_register_func)(
+ v8::Handle<v8::Object> exports, v8::Handle<v8::Value> module);
+
struct node_module_struct {
int version;
void *dso_handle;
const char *filename;
- void (*register_func) (v8::Handle<v8::Object> target);
+ node::addon_register_func register_func;
const char *modname;
};
@@ -212,9 +205,9 @@ node_module_struct* get_builtin_module(const char *name);
* When this version number is changed, node.js will refuse
* to load older modules. This should be done whenever
* an API is broken in the C++ side, including in v8 or
- * other dependencies
+ * other dependencies.
*/
-#define NODE_MODULE_VERSION (1)
+#define NODE_MODULE_VERSION 0x000B /* v0.11 */
#define NODE_STANDARD_MODULE_STUFF \
NODE_MODULE_VERSION, \
@@ -232,7 +225,7 @@ node_module_struct* get_builtin_module(const char *name);
NODE_MODULE_EXPORT node::node_module_struct modname ## _module = \
{ \
NODE_STANDARD_MODULE_STUFF, \
- regfunc, \
+ (node::addon_register_func)regfunc, \
NODE_STRINGIFY(modname) \
}; \
}
@@ -266,9 +259,4 @@ MakeCallback(const v8::Handle<v8::Object> object,
} // namespace node
-#if !defined(NODE_WANT_INTERNALS) && !defined(_WIN32)
-# include "ev-emul.h"
-# include "eio-emul.h"
-#endif
-
#endif // SRC_NODE_H_
diff --git a/src/node.js b/src/node.js
index 1abd0b650..90c681255 100644
--- a/src/node.js
+++ b/src/node.js
@@ -38,6 +38,9 @@
process.EventEmitter = EventEmitter; // process.EventEmitter is deprecated
+ // do this good and early, since it handles errors.
+ startup.processFatal();
+
startup.globalVariables();
startup.globalTimeouts();
startup.globalConsole();
@@ -107,13 +110,12 @@
// global.v8debug object about a connection, and runMain when
// that occurs. --isaacs
- setTimeout(Module.runMain, 50);
+ var debugTimeout = +process.env.NODE_DEBUG_TIMEOUT || 50;
+ setTimeout(Module.runMain, debugTimeout);
} else {
- // REMOVEME: nextTick should not be necessary. This hack to get
- // test/simple/test-exception-handler2.js working.
// Main entry point into most programs:
- process.nextTick(Module.runMain);
+ Module.runMain();
}
} else {
@@ -139,7 +141,6 @@
} else {
// Read all of stdin - execute it.
- process.stdin.resume();
process.stdin.setEncoding('utf8');
var code = '';
@@ -161,6 +162,9 @@
global.GLOBAL = global;
global.root = global;
global.Buffer = NativeModule.require('buffer').Buffer;
+ process.binding('buffer').setFastBufferConstructor(global.Buffer);
+ process.domain = null;
+ process._exiting = false;
};
startup.globalTimeouts = function() {
@@ -183,6 +187,16 @@
var t = NativeModule.require('timers');
return t.clearInterval.apply(this, arguments);
};
+
+ global.setImmediate = function() {
+ var t = NativeModule.require('timers');
+ return t.setImmediate.apply(this, arguments);
+ };
+
+ global.clearImmediate = function() {
+ var t = NativeModule.require('timers');
+ return t.clearImmediate.apply(this, arguments);
+ };
};
startup.globalConsole = function() {
@@ -201,6 +215,68 @@
return startup._lazyConstants;
};
+ startup.processFatal = function() {
+ // call into the active domain, or emit uncaughtException,
+ // and exit if there are no listeners.
+ process._fatalException = function(er) {
+ var caught = false;
+ if (process.domain) {
+ var domain = process.domain;
+
+ // ignore errors on disposed domains.
+ //
+ // XXX This is a bit stupid. We should probably get rid of
+ // domain.dispose() altogether. It's almost always a terrible
+ // idea. --isaacs
+ if (domain._disposed)
+ return true;
+
+ er.domain = domain;
+ er.domainThrown = true;
+ // wrap this in a try/catch so we don't get infinite throwing
+ try {
+ // One of three things will happen here.
+ //
+ // 1. There is a handler, caught = true
+ // 2. There is no handler, caught = false
+ // 3. It throws, caught = false
+ //
+ // If caught is false after this, then there's no need to exit()
+ // the domain, because we're going to crash the process anyway.
+ caught = domain.emit('error', er);
+
+ // Exit all domains on the stack. Uncaught exceptions end the
+ // current tick and no domains should be left on the stack between
+ // ticks. Since a domain exists, this require will not be loading
+ // it for the first time and should be safe.
+ var domainModule = NativeModule.require('domain');
+ domainModule._stack.length = 0;
+ domainModule.active = process.domain = null;
+ } catch (er2) {
+ caught = false;
+ }
+ } else {
+ caught = process.emit('uncaughtException', er);
+ }
+ // if someone handled it, then great. otherwise, die in C++ land
+ // since that means that we'll exit the process, emit the 'exit' event
+ if (!caught) {
+ try {
+ if (!process._exiting) {
+ process._exiting = true;
+ process.emit('exit', 1);
+ }
+ } catch (er) {
+ // nothing to be done about it at this point.
+ }
+ }
+ // if we handled an error, then make sure any ticks get processed
+ if (caught)
+ process._needTickCallback();
+ return caught;
+ };
+ };
+
var assert;
startup.processAssert = function() {
// Note that calls to assert() are pre-processed out by JS2C for the
@@ -224,39 +300,198 @@
if (value === 'false') return false;
return value;
});
- }
+ };
startup.processNextTick = function() {
+ var _needTickCallback = process._needTickCallback;
var nextTickQueue = [];
- var nextTickIndex = 0;
-
- process._tickCallback = function() {
- var nextTickLength = nextTickQueue.length;
- if (nextTickLength === 0) return;
-
- while (nextTickIndex < nextTickLength) {
- var tock = nextTickQueue[nextTickIndex++];
- var callback = tock.callback;
- if (tock.domain) {
- if (tock.domain._disposed) continue;
- tock.domain.enter();
+ var needSpinner = true;
+ var inTick = false;
+
+ // this infobox thing is used so that the C++ code in src/node.cc
+ // can have easy accesss to our nextTick state, and avoid unnecessary
+ // calls into process._tickCallback.
+ // order is [length, index, depth]
+ // Never write code like this without very good reason!
+ var infoBox = process._tickInfoBox;
+ var length = 0;
+ var index = 1;
+ var depth = 2;
+
+ process._tickCallback = _tickCallback;
+ process._tickFromSpinner = _tickFromSpinner;
+ // needs to be accessible from cc land
+ process._tickDomainCallback = _tickDomainCallback;
+ process.nextTick = nextTick;
+ process._nextDomainTick = _nextDomainTick;
+
+ // the maximum number of times it'll process something like
+ // nextTick(function f(){nextTick(f)})
+ // It's unlikely, but not illegal, to hit this limit. When
+ // that happens, it yields to libuv's tick spinner.
+ // This is a loop counter, not a stack depth, so we aren't using
+ // up lots of memory here. I/O can sneak in before nextTick if this
+ // limit is hit, which is not ideal, but not terrible.
+ process.maxTickDepth = 1000;
+
+ function tickDone(tickDepth_) {
+ if (infoBox[length] !== 0) {
+ if (infoBox[length] <= infoBox[index]) {
+ nextTickQueue = [];
+ infoBox[length] = 0;
+ } else {
+ nextTickQueue.splice(0, infoBox[index]);
+ infoBox[length] = nextTickQueue.length;
+ if (needSpinner) {
+ _needTickCallback();
+ needSpinner = false;
+ }
}
- callback();
- if (tock.domain) {
- tock.domain.exit();
+ }
+ inTick = false;
+ infoBox[index] = 0;
+ infoBox[depth] = tickDepth_;
+ }
+
+ function maxTickWarn() {
+ // XXX Remove all this maxTickDepth stuff in 0.11
+ var msg = '(node) warning: Recursive process.nextTick detected. ' +
+ 'This will break in the next version of node. ' +
+ 'Please use setImmediate for recursive deferral.';
+ if (process.traceDeprecation)
+ console.trace(msg);
+ else
+ console.error(msg);
+ }
+
+ function _tickFromSpinner() {
+ needSpinner = true;
+ // coming from spinner, reset!
+ if (infoBox[depth] !== 0)
+ infoBox[depth] = 0;
+ // no callbacks to run
+ if (infoBox[length] === 0)
+ return infoBox[index] = infoBox[depth] = 0;
+ process._tickCallback();
+ }
+
+ // run callbacks that have no domain
+ // using domains will cause this to be overridden
+ function _tickCallback() {
+ var callback, nextTickLength, threw;
+
+ if (inTick) return;
+ if (infoBox[length] === 0) {
+ infoBox[index] = 0;
+ infoBox[depth] = 0;
+ return;
+ }
+ inTick = true;
+
+ while (infoBox[depth]++ < process.maxTickDepth) {
+ nextTickLength = infoBox[length];
+ if (infoBox[index] === nextTickLength)
+ return tickDone(0);
+
+ while (infoBox[index] < nextTickLength) {
+ callback = nextTickQueue[infoBox[index]++].callback;
+ threw = true;
+ try {
+ callback();
+ threw = false;
+ } finally {
+ if (threw) tickDone(infoBox[depth]);
+ }
}
}
- nextTickQueue.splice(0, nextTickIndex);
- nextTickIndex = 0;
- };
+ tickDone(0);
+ }
- process.nextTick = function(callback) {
- var tock = { callback: callback };
- if (process.domain) tock.domain = process.domain;
- nextTickQueue.push(tock);
- process._needTickCallback();
- };
+ function _tickDomainCallback() {
+ var nextTickLength, tock, callback, threw;
+
+ // if you add a nextTick in a domain's error handler, then
+ // it's possible to cycle indefinitely. Normally, the tickDone
+ // in the finally{} block below will prevent this, however if
+ // that error handler ALSO triggers multiple MakeCallbacks, then
+ // it'll try to keep clearing the queue, since the finally block
+ // fires *before* the error hits the top level and is handled.
+ if (infoBox[depth] >= process.maxTickDepth)
+ return _needTickCallback();
+
+ if (inTick) return;
+ inTick = true;
+
+ // always do this at least once. otherwise if process.maxTickDepth
+ // is set to some negative value, or if there were repeated errors
+ // preventing depth from being cleared, we'd never process any
+ // of them.
+ while (infoBox[depth]++ < process.maxTickDepth) {
+ nextTickLength = infoBox[length];
+ if (infoBox[index] === nextTickLength)
+ return tickDone(0);
+
+ while (infoBox[index] < nextTickLength) {
+ tock = nextTickQueue[infoBox[index]++];
+ callback = tock.callback;
+ if (tock.domain) {
+ if (tock.domain._disposed) continue;
+ tock.domain.enter();
+ }
+ threw = true;
+ try {
+ callback();
+ threw = false;
+ } finally {
+ // finally blocks fire before the error hits the top level,
+ // so we can't clear the depth at this point.
+ if (threw) tickDone(infoBox[depth]);
+ }
+ if (tock.domain) {
+ tock.domain.exit();
+ }
+ }
+ }
+
+ tickDone(0);
+ }
+
+ function nextTick(callback) {
+ // on the way out, don't bother. it won't get fired anyway.
+ if (process._exiting)
+ return;
+ if (infoBox[depth] >= process.maxTickDepth)
+ maxTickWarn();
+
+ var obj = { callback: callback, domain: null };
+
+ nextTickQueue.push(obj);
+ infoBox[length]++;
+
+ if (needSpinner) {
+ _needTickCallback();
+ needSpinner = false;
+ }
+ }
+
+ function _nextDomainTick(callback) {
+ // on the way out, don't bother. it won't get fired anyway.
+ if (process._exiting)
+ return;
+ if (infoBox[depth] >= process.maxTickDepth)
+ maxTickWarn();
+
+ var obj = { callback: callback, domain: process.domain };
+
+ nextTickQueue.push(obj);
+ infoBox[length]++;
+
+ if (needSpinner) {
+ _needTickCallback();
+ needSpinner = false;
+ }
+ }
};
function evalScript(name) {
@@ -320,13 +555,18 @@
case 'PIPE':
var net = NativeModule.require('net');
- stream = new net.Stream(fd);
+ stream = new net.Socket({
+ fd: fd,
+ readable: false,
+ writable: true
+ });
- // FIXME Should probably have an option in net.Stream to create a
+ // FIXME Should probably have an option in net.Socket to create a
// stream from an existing fd which is writable only. But for now
// we'll just add this hack and set the `readable` member to false.
// Test: ./node test/fixtures/echo.js < /etc/passwd
stream.readable = false;
+ stream.read = null;
stream._type = 'pipe';
// FIXME Hack to have stream not keep the event loop alive.
@@ -386,18 +626,25 @@
switch (tty_wrap.guessHandleType(fd)) {
case 'TTY':
var tty = NativeModule.require('tty');
- stdin = new tty.ReadStream(fd);
+ stdin = new tty.ReadStream(fd, {
+ highWaterMark: 0,
+ readable: true,
+ writable: false
+ });
break;
case 'FILE':
var fs = NativeModule.require('fs');
- stdin = new fs.ReadStream(null, {fd: fd});
+ stdin = new fs.ReadStream(null, { fd: fd });
break;
case 'PIPE':
var net = NativeModule.require('net');
- stdin = new net.Stream(fd);
- stdin.readable = true;
+ stdin = new net.Socket({
+ fd: fd,
+ readable: true,
+ writable: false
+ });
break;
default:
@@ -409,16 +656,23 @@
stdin.fd = fd;
// stdin starts out life in a paused state, but node doesn't
- // know yet. Call pause() explicitly to unref() it.
- stdin.pause();
-
- // when piping stdin to a destination stream,
- // let the data begin to flow.
- var pipe = stdin.pipe;
- stdin.pipe = function(dest, opts) {
- stdin.resume();
- return pipe.call(stdin, dest, opts);
- };
+ // know yet. Explicitly to readStop() it to put it in the
+ // not-reading state.
+ if (stdin._handle && stdin._handle.readStop) {
+ stdin._handle.reading = false;
+ stdin._readableState.reading = false;
+ stdin._handle.readStop();
+ }
+
+ // if the user calls stdin.pause(), then we need to stop reading
+ // immediately, so that the process can close down.
+ stdin.on('pause', function() {
+ if (!stdin._handle)
+ return;
+ stdin._readableState.reading = false;
+ stdin._handle.reading = false;
+ stdin._handle.readStop();
+ });
return stdin;
});
@@ -454,7 +708,7 @@
}
if (r) {
- throw errnoException(errno, 'kill');
+ throw errnoException(process._errno, 'kill');
}
return true;
@@ -468,40 +722,47 @@
// Load events module in order to access prototype elements on process like
// process.addListener.
- var signalWatchers = {};
+ var signalWraps = {};
var addListener = process.addListener;
var removeListener = process.removeListener;
function isSignal(event) {
- return event.slice(0, 3) === 'SIG' && startup.lazyConstants()[event];
+ return event.slice(0, 3) === 'SIG' &&
+ startup.lazyConstants().hasOwnProperty(event);
}
// Wrap addListener for the special signal types
process.on = process.addListener = function(type, listener) {
- var ret = addListener.apply(this, arguments);
- if (isSignal(type)) {
- if (!signalWatchers.hasOwnProperty(type)) {
- var b = process.binding('signal_watcher');
- var w = new b.SignalWatcher(startup.lazyConstants()[type]);
- w.callback = function() { process.emit(type); };
- signalWatchers[type] = w;
- w.start();
-
- } else if (this.listeners(type).length === 1) {
- signalWatchers[type].start();
+ if (isSignal(type) &&
+ !signalWraps.hasOwnProperty(type)) {
+ var Signal = process.binding('signal_wrap').Signal;
+ var wrap = new Signal();
+
+ wrap.unref();
+
+ wrap.onsignal = function() { process.emit(type); };
+
+ var signum = startup.lazyConstants()[type];
+ var r = wrap.start(signum);
+ if (r) {
+ wrap.close();
+ throw errnoException(process._errno, 'uv_signal_start');
}
+
+ signalWraps[type] = wrap;
}
- return ret;
+ return addListener.apply(this, arguments);
};
process.removeListener = function(type, listener) {
var ret = removeListener.apply(this, arguments);
if (isSignal(type)) {
- assert(signalWatchers.hasOwnProperty(type));
+ assert(signalWraps.hasOwnProperty(type));
if (this.listeners(type).length === 0) {
- signalWatchers[type].stop();
+ signalWraps[type].close();
+ delete signalWraps[type];
}
}
@@ -583,8 +844,8 @@
var nativeModule = new NativeModule(id);
- nativeModule.compile();
nativeModule.cache();
+ nativeModule.compile();
return nativeModule.exports;
};
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index 3f8ebefe0..aeedf3104 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -27,13 +27,8 @@
#include "v8-profiler.h"
#include <assert.h>
-#include <stdlib.h> // malloc, free
#include <string.h> // memcpy
-#ifdef __POSIX__
-# include <arpa/inet.h> // htons, htonl
-#endif
-
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define BUFFER_CLASS_ID (0xBABE)
@@ -66,6 +61,7 @@ using namespace v8;
static Persistent<String> length_symbol;
static Persistent<String> chars_written_sym;
static Persistent<String> write_sym;
+static Persistent<Function> fast_buffer_constructor;
Persistent<FunctionTemplate> Buffer::constructor_template;
@@ -139,14 +135,14 @@ Buffer* Buffer::New(size_t length) {
}
-Buffer* Buffer::New(char* data, size_t length) {
+Buffer* Buffer::New(const char* data, size_t length) {
HandleScope scope;
Local<Value> arg = Integer::NewFromUnsigned(0);
Local<Object> obj = constructor_template->GetFunction()->NewInstance(1, &arg);
Buffer *buffer = ObjectWrap::Unwrap<Buffer>(obj);
- buffer->Replace(data, length, NULL, NULL);
+ buffer->Replace(const_cast<char*>(data), length, NULL, NULL);
return buffer;
}
@@ -201,6 +197,8 @@ Buffer::~Buffer() {
}
+// if replace doesn't have a callback, data must be copied
+// const_cast in Buffer::New requires this
void Buffer::Replace(char *data, size_t length,
free_callback callback, void *hint) {
HandleScope scope;
@@ -279,9 +277,26 @@ Handle<Value> Buffer::Ucs2Slice(const Arguments &args) {
return scope.Close(string);
}
-static const char *base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789+/";
+
+Handle<Value> Buffer::HexSlice(const Arguments &args) {
+ HandleScope scope;
+ Buffer* parent = ObjectWrap::Unwrap<Buffer>(args.This());
+ SLICE_ARGS(args[0], args[1])
+ char* src = parent->data_ + start;
+ uint32_t dstlen = (end - start) * 2;
+ if (dstlen == 0) return scope.Close(String::Empty());
+ char* dst = new char[dstlen];
+ for (uint32_t i = 0, k = 0; k < dstlen; i += 1, k += 2) {
+ static const char hex[] = "0123456789abcdef";
+ uint8_t val = static_cast<uint8_t>(src[i]);
+ dst[k + 0] = hex[val >> 4];
+ dst[k + 1] = hex[val & 15];
+ }
+ Local<String> string = String::New(dst, dstlen);
+ delete[] dst;
+ return scope.Close(string);
+}
+
// supports regular and URL-safe base64
static const int unbase64_table[] =
@@ -310,69 +325,65 @@ Handle<Value> Buffer::Base64Slice(const Arguments &args) {
Buffer *parent = ObjectWrap::Unwrap<Buffer>(args.This());
SLICE_ARGS(args[0], args[1])
- int n = end - start;
- int out_len = (n + 2 - ((n + 2) % 3)) / 3 * 4;
- char *out = new char[out_len];
-
- uint8_t bitbuf[3];
- int i = start; // data() index
- int j = 0; // out index
- char c;
- bool b1_oob, b2_oob;
-
- while (i < end) {
- bitbuf[0] = parent->data_[i++];
-
- if (i < end) {
- bitbuf[1] = parent->data_[i];
- b1_oob = false;
- } else {
- bitbuf[1] = 0;
- b1_oob = true;
- }
- i++;
-
- if (i < end) {
- bitbuf[2] = parent->data_[i];
- b2_oob = false;
- } else {
- bitbuf[2] = 0;
- b2_oob = true;
- }
- i++;
+ unsigned slen = end - start;
+ const char* src = parent->data_ + start;
+ unsigned dlen = (slen + 2 - ((slen + 2) % 3)) / 3 * 4;
+ char* dst = new char[dlen];
- c = bitbuf[0] >> 2;
- assert(c < 64);
- out[j++] = base64_table[(int)c];
- assert(j < out_len);
+ unsigned a;
+ unsigned b;
+ unsigned c;
+ unsigned i;
+ unsigned k;
+ unsigned n;
- c = ((bitbuf[0] & 0x03) << 4) | (bitbuf[1] >> 4);
- assert(c < 64);
- out[j++] = base64_table[(int)c];
- assert(j < out_len);
+ static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
- if (b1_oob) {
- out[j++] = '=';
- } else {
- c = ((bitbuf[1] & 0x0F) << 2) | (bitbuf[2] >> 6);
- assert(c < 64);
- out[j++] = base64_table[(int)c];
- }
- assert(j < out_len);
+ i = 0;
+ k = 0;
+ n = slen / 3 * 3;
- if (b2_oob) {
- out[j++] = '=';
- } else {
- c = bitbuf[2] & 0x3F;
- assert(c < 64);
- out[j++] = base64_table[(int)c];
+ while (i < n) {
+ a = src[i + 0] & 0xff;
+ b = src[i + 1] & 0xff;
+ c = src[i + 2] & 0xff;
+
+ dst[k + 0] = table[a >> 2];
+ dst[k + 1] = table[((a & 3) << 4) | (b >> 4)];
+ dst[k + 2] = table[((b & 0x0f) << 2) | (c >> 6)];
+ dst[k + 3] = table[c & 0x3f];
+
+ i += 3;
+ k += 4;
+ }
+
+ if (n != slen) {
+ switch (slen - n) {
+ case 1:
+ a = src[i + 0] & 0xff;
+ dst[k + 0] = table[a >> 2];
+ dst[k + 1] = table[(a & 3) << 4];
+ dst[k + 2] = '=';
+ dst[k + 3] = '=';
+ break;
+
+ case 2:
+ a = src[i + 0] & 0xff;
+ b = src[i + 1] & 0xff;
+ dst[k + 0] = table[a >> 2];
+ dst[k + 1] = table[((a & 3) << 4) | (b >> 4)];
+ dst[k + 2] = table[(b & 0x0f) << 2];
+ dst[k + 3] = '=';
+ break;
}
- assert(j <= out_len);
}
- Local<String> string = String::New(out, out_len);
- delete [] out;
+ Local<String> string = String::New(dst, dlen);
+ delete [] dst;
+
return scope.Close(string);
}
@@ -405,11 +416,10 @@ Handle<Value> Buffer::Copy(const Arguments &args) {
Buffer *source = ObjectWrap::Unwrap<Buffer>(args.This());
if (!Buffer::HasInstance(args[0])) {
- return ThrowException(Exception::TypeError(String::New(
- "First arg should be a Buffer")));
+ return ThrowTypeError("First arg should be a Buffer");
}
- Local<Object> target = args[0]->ToObject();
+ Local<Value> target = args[0];
char* target_data = Buffer::Data(target);
size_t target_length = Buffer::Length(target);
size_t target_start = args[1]->IsUndefined() ? 0 : args[1]->Uint32Value();
@@ -418,8 +428,7 @@ Handle<Value> Buffer::Copy(const Arguments &args) {
: args[3]->Uint32Value();
if (source_end < source_start) {
- return ThrowException(Exception::Error(String::New(
- "sourceEnd < sourceStart")));
+ return ThrowRangeError("sourceEnd < sourceStart");
}
// Copy 0 bytes; we're done
@@ -428,18 +437,15 @@ Handle<Value> Buffer::Copy(const Arguments &args) {
}
if (target_start >= target_length) {
- return ThrowException(Exception::Error(String::New(
- "targetStart out of bounds")));
+ return ThrowRangeError("targetStart out of bounds");
}
if (source_start >= source->length_) {
- return ThrowException(Exception::Error(String::New(
- "sourceStart out of bounds")));
+ return ThrowRangeError("sourceStart out of bounds");
}
if (source_end > source->length_) {
- return ThrowException(Exception::Error(String::New(
- "sourceEnd out of bounds")));
+ return ThrowRangeError("sourceEnd out of bounds");
}
size_t to_copy = MIN(MIN(source_end - source_start,
@@ -478,8 +484,7 @@ Handle<Value> Buffer::Utf8Write(const Arguments &args) {
}
if (length > 0 && offset >= buffer->length_) {
- return ThrowException(Exception::TypeError(String::New(
- "Offset is out of bounds")));
+ return ThrowTypeError("Offset is out of bounds");
}
size_t max_length = args[2]->IsUndefined() ? buffer->length_ - offset
@@ -509,8 +514,7 @@ Handle<Value> Buffer::Ucs2Write(const Arguments &args) {
Buffer *buffer = ObjectWrap::Unwrap<Buffer>(args.This());
if (!args[0]->IsString()) {
- return ThrowException(Exception::TypeError(String::New(
- "Argument must be a string")));
+ return ThrowTypeError("Argument must be a string");
}
Local<String> s = args[0]->ToString();
@@ -541,6 +545,72 @@ Handle<Value> Buffer::Ucs2Write(const Arguments &args) {
}
+inline unsigned hex2bin(char c) {
+ if (c >= '0' && c <= '9') return c - '0';
+ if (c >= 'A' && c <= 'F') return 10 + (c - 'A');
+ if (c >= 'a' && c <= 'f') return 10 + (c - 'a');
+ return static_cast<unsigned>(-1);
+}
+
+
+Handle<Value> Buffer::HexWrite(const Arguments& args) {
+ HandleScope scope;
+ Buffer* parent = ObjectWrap::Unwrap<Buffer>(args.This());
+
+ if (args[0]->IsString() == false) {
+ return ThrowTypeError("Argument must be a string");
+ }
+
+ Local<String> s = args[0].As<String>();
+
+ if (s->Length() % 2 != 0) {
+ return ThrowTypeError("Invalid hex string");
+ }
+
+ uint32_t start = args[1]->Uint32Value();
+ uint32_t size = args[2]->Uint32Value();
+ uint32_t end = start + size;
+
+ if (start >= parent->length_) {
+ Local<Integer> val = Integer::New(0);
+ constructor_template->GetFunction()->Set(chars_written_sym, val);
+ return scope.Close(val);
+ }
+
+ if (end < start || end > parent->length_) { // Overflow + bounds check.
+ end = parent->length_;
+ size = parent->length_ - start;
+ }
+
+ if (size == 0) {
+ Local<Integer> val = Integer::New(0);
+ constructor_template->GetFunction()->Set(chars_written_sym, val);
+ return scope.Close(val);
+ }
+
+ char* dst = parent->data_ + start;
+ String::AsciiValue string(s);
+ const char* src = *string;
+ uint32_t max = string.length() / 2;
+
+ if (max > size) {
+ max = size;
+ }
+
+ for (uint32_t i = 0; i < max; ++i) {
+ unsigned a = hex2bin(src[i * 2 + 0]);
+ unsigned b = hex2bin(src[i * 2 + 1]);
+ if (!~a || !~b) return ThrowTypeError("Invalid hex string");
+ dst[i] = a * 16 + b;
+ }
+
+ constructor_template->GetFunction()->Set(chars_written_sym,
+ Integer::New(max * 2));
+
+ return scope.Close(Integer::New(max));
+}
+
+
// var charsWritten = buffer.asciiWrite(string, offset);
Handle<Value> Buffer::AsciiWrite(const Arguments &args) {
HandleScope scope;
@@ -548,8 +618,7 @@ Handle<Value> Buffer::AsciiWrite(const Arguments &args) {
Buffer *buffer = ObjectWrap::Unwrap<Buffer>(args.This());
if (!args[0]->IsString()) {
- return ThrowException(Exception::TypeError(String::New(
- "Argument must be a string")));
+ return ThrowTypeError("Argument must be a string");
}
Local<String> s = args[0]->ToString();
@@ -557,8 +626,7 @@ Handle<Value> Buffer::AsciiWrite(const Arguments &args) {
size_t offset = args[1]->Int32Value();
if (length > 0 && offset >= buffer->length_) {
- return ThrowException(Exception::TypeError(String::New(
- "Offset is out of bounds")));
+ return ThrowTypeError("Offset is out of bounds");
}
size_t max_length = args[2]->IsUndefined() ? buffer->length_ - offset
@@ -587,8 +655,7 @@ Handle<Value> Buffer::Base64Write(const Arguments &args) {
Buffer *buffer = ObjectWrap::Unwrap<Buffer>(args.This());
if (!args[0]->IsString()) {
- return ThrowException(Exception::TypeError(String::New(
- "Argument must be a string")));
+ return ThrowTypeError("Argument must be a string");
}
String::AsciiValue s(args[0]);
@@ -599,8 +666,7 @@ Handle<Value> Buffer::Base64Write(const Arguments &args) {
max_length = MIN(length, MIN(buffer->length_ - offset, max_length));
if (max_length && offset >= buffer->length_) {
- return ThrowException(Exception::TypeError(String::New(
- "Offset is out of bounds")));
+ return ThrowTypeError("Offset is out of bounds");
}
char a, b, c, d;
@@ -651,8 +717,7 @@ Handle<Value> Buffer::BinaryWrite(const Arguments &args) {
Buffer *buffer = ObjectWrap::Unwrap<Buffer>(args.This());
if (!args[0]->IsString()) {
- return ThrowException(Exception::TypeError(String::New(
- "Argument must be a string")));
+ return ThrowTypeError("Argument must be a string");
}
Local<String> s = args[0]->ToString();
@@ -660,8 +725,7 @@ Handle<Value> Buffer::BinaryWrite(const Arguments &args) {
size_t offset = args[1]->Int32Value();
if (s->Length() > 0 && offset >= buffer->length_) {
- return ThrowException(Exception::TypeError(String::New(
- "Offset is out of bounds")));
+ return ThrowTypeError("Offset is out of bounds");
}
char *p = (char*)buffer->data_ + offset;
@@ -679,13 +743,129 @@ Handle<Value> Buffer::BinaryWrite(const Arguments &args) {
}
+static bool is_big_endian() {
+ const union { uint8_t u8[2]; uint16_t u16; } u = {{0, 1}};
+ return u.u16 == 1 ? true : false;
+}
+
+
+static void swizzle(char* buf, size_t len) {
+ char t;
+ for (size_t i = 0; i < len / 2; ++i) {
+ t = buf[i];
+ buf[i] = buf[len - i - 1];
+ buf[len - i - 1] = t;
+ }
+}
+
+
+template <typename T, bool ENDIANNESS>
+Handle<Value> ReadFloatGeneric(const Arguments& args) {
+ double offset_tmp = args[0]->NumberValue();
+ int64_t offset = static_cast<int64_t>(offset_tmp);
+ bool doAssert = !args[1]->BooleanValue();
+
+ if (doAssert) {
+ if (offset_tmp != offset || offset < 0)
+ return ThrowTypeError("offset is not uint");
+ size_t len = static_cast<size_t>(
+ args.This()->GetIndexedPropertiesExternalArrayDataLength());
+ if (offset + sizeof(T) > len)
+ return ThrowRangeError("Trying to read beyond buffer length");
+ }
+
+ T val;
+ char* data = static_cast<char*>(
+ args.This()->GetIndexedPropertiesExternalArrayData());
+ char* ptr = data + offset;
+
+ memcpy(&val, ptr, sizeof(T));
+ if (ENDIANNESS != is_big_endian())
+ swizzle(reinterpret_cast<char*>(&val), sizeof(T));
+
+ // TODO: when Number::New is updated to accept an Isolate, make the change
+ return Number::New(val);
+}
+
+
+Handle<Value> Buffer::ReadFloatLE(const Arguments& args) {
+ return ReadFloatGeneric<float, false>(args);
+}
+
+
+Handle<Value> Buffer::ReadFloatBE(const Arguments& args) {
+ return ReadFloatGeneric<float, true>(args);
+}
+
+
+Handle<Value> Buffer::ReadDoubleLE(const Arguments& args) {
+ return ReadFloatGeneric<double, false>(args);
+}
+
+
+Handle<Value> Buffer::ReadDoubleBE(const Arguments& args) {
+ return ReadFloatGeneric<double, true>(args);
+}
+
+
+template <typename T, bool ENDIANNESS>
+Handle<Value> WriteFloatGeneric(const Arguments& args) {
+ bool doAssert = !args[2]->BooleanValue();
+
+ if (doAssert) {
+ if (!args[0]->IsNumber())
+ return ThrowTypeError("value not a number");
+ if (!args[1]->IsUint32())
+ return ThrowTypeError("offset is not uint");
+ }
+
+ T val = static_cast<T>(args[0]->NumberValue());
+ size_t offset = args[1]->Uint32Value();
+ char* data = static_cast<char*>(
+ args.This()->GetIndexedPropertiesExternalArrayData());
+ char* ptr = data + offset;
+
+ if (doAssert) {
+ size_t len = static_cast<size_t>(
+ args.This()->GetIndexedPropertiesExternalArrayDataLength());
+ if (offset + sizeof(T) > len || offset + sizeof(T) < offset)
+ return ThrowRangeError("Trying to write beyond buffer length");
+ }
+
+ memcpy(ptr, &val, sizeof(T));
+ if (ENDIANNESS != is_big_endian())
+ swizzle(ptr, sizeof(T));
+
+ return Undefined();
+}
+
+
+Handle<Value> Buffer::WriteFloatLE(const Arguments& args) {
+ return WriteFloatGeneric<float, false>(args);
+}
+
+
+Handle<Value> Buffer::WriteFloatBE(const Arguments& args) {
+ return WriteFloatGeneric<float, true>(args);
+}
+
+
+Handle<Value> Buffer::WriteDoubleLE(const Arguments& args) {
+ return WriteFloatGeneric<double, false>(args);
+}
+
+
+Handle<Value> Buffer::WriteDoubleBE(const Arguments& args) {
+ return WriteFloatGeneric<double, true>(args);
+}
+
+
// var nbytes = Buffer.byteLength("string", "utf8")
Handle<Value> Buffer::ByteLength(const Arguments &args) {
HandleScope scope;
if (!args[0]->IsString()) {
- return ThrowException(Exception::TypeError(String::New(
- "Argument must be a string")));
+ return ThrowTypeError("Argument must be a string");
}
Local<String> s = args[0]->ToString();
@@ -699,8 +879,7 @@ Handle<Value> Buffer::MakeFastBuffer(const Arguments &args) {
HandleScope scope;
if (!Buffer::HasInstance(args[0])) {
- return ThrowException(Exception::TypeError(String::New(
- "First argument must be a Buffer")));
+ return ThrowTypeError("First argument must be a Buffer");
}
Buffer *buffer = ObjectWrap::Unwrap<Buffer>(args[0]->ToObject());
@@ -729,22 +908,31 @@ Handle<Value> Buffer::MakeFastBuffer(const Arguments &args) {
}
-bool Buffer::HasInstance(v8::Handle<v8::Value> val) {
+bool Buffer::HasInstance(Handle<Value> val) {
if (!val->IsObject()) return false;
- v8::Local<v8::Object> obj = val->ToObject();
+ Local<Object> obj = val->ToObject();
- if (obj->GetIndexedPropertiesExternalArrayDataType() == kExternalUnsignedByteArray)
- return true;
+ ExternalArrayType type = obj->GetIndexedPropertiesExternalArrayDataType();
+ if (type != kExternalUnsignedByteArray)
+ return false;
// Also check for SlowBuffers that are empty.
if (constructor_template->HasInstance(obj))
return true;
- return false;
+ assert(!fast_buffer_constructor.IsEmpty());
+ return obj->GetConstructor()->StrictEquals(fast_buffer_constructor);
+}
+
+
+Handle<Value> SetFastBufferConstructor(const Arguments& args) {
+ assert(args[0]->IsFunction());
+ fast_buffer_constructor = Persistent<Function>::New(args[0].As<Function>());
+ return Undefined();
}
-class RetainedBufferInfo: public v8::RetainedObjectInfo {
+class RetainedBufferInfo: public RetainedObjectInfo {
public:
RetainedBufferInfo(Buffer* buffer);
virtual void Dispose();
@@ -826,6 +1014,7 @@ void Buffer::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor_template, "asciiSlice", Buffer::AsciiSlice);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "base64Slice", Buffer::Base64Slice);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "ucs2Slice", Buffer::Ucs2Slice);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "hexSlice", Buffer::HexSlice);
// TODO NODE_SET_PROTOTYPE_METHOD(t, "utf16Slice", Utf16Slice);
// copy
NODE_SET_PROTOTYPE_METHOD(constructor_template, "utf8Slice", Buffer::Utf8Slice);
@@ -835,6 +1024,15 @@ void Buffer::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor_template, "binaryWrite", Buffer::BinaryWrite);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "base64Write", Buffer::Base64Write);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "ucs2Write", Buffer::Ucs2Write);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "hexWrite", Buffer::HexWrite);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "readFloatLE", Buffer::ReadFloatLE);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "readFloatBE", Buffer::ReadFloatBE);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "readDoubleLE", Buffer::ReadDoubleLE);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "readDoubleBE", Buffer::ReadDoubleBE);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "writeFloatLE", Buffer::WriteFloatLE);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "writeFloatBE", Buffer::WriteFloatBE);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "writeDoubleLE", Buffer::WriteDoubleLE);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "writeDoubleBE", Buffer::WriteDoubleBE);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "fill", Buffer::Fill);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "copy", Buffer::Copy);
@@ -846,6 +1044,8 @@ void Buffer::Initialize(Handle<Object> target) {
Buffer::MakeFastBuffer);
target->Set(String::NewSymbol("SlowBuffer"), constructor_template->GetFunction());
+ target->Set(String::NewSymbol("setFastBufferConstructor"),
+ FunctionTemplate::New(SetFastBufferConstructor)->GetFunction());
HeapProfiler::DefineWrapperClass(BUFFER_CLASS_ID, WrapperInfo);
}
diff --git a/src/node_buffer.h b/src/node_buffer.h
index 38c1e2d29..5743f9b26 100644
--- a/src/node_buffer.h
+++ b/src/node_buffer.h
@@ -72,16 +72,21 @@ class NODE_EXTERN Buffer: public ObjectWrap {
static bool HasInstance(v8::Handle<v8::Value> val);
- static inline char* Data(v8::Handle<v8::Object> obj) {
- return (char*)obj->GetIndexedPropertiesExternalArrayData();
+ static inline char* Data(v8::Handle<v8::Value> val) {
+ assert(val->IsObject());
+ void* data = val.As<v8::Object>()->GetIndexedPropertiesExternalArrayData();
+ return static_cast<char*>(data);
}
static inline char* Data(Buffer *b) {
return Buffer::Data(b->handle_);
}
- static inline size_t Length(v8::Handle<v8::Object> obj) {
- return (size_t)obj->GetIndexedPropertiesExternalArrayDataLength();
+ static inline size_t Length(v8::Handle<v8::Value> val) {
+ assert(val->IsObject());
+ int len = val.As<v8::Object>()
+ ->GetIndexedPropertiesExternalArrayDataLength();
+ return static_cast<size_t>(len);
}
static inline size_t Length(Buffer *b) {
@@ -97,10 +102,14 @@ class NODE_EXTERN Buffer: public ObjectWrap {
static v8::Handle<v8::Object> New(v8::Handle<v8::String> string);
static void Initialize(v8::Handle<v8::Object> target);
- static Buffer* New(size_t length); // public constructor
- static Buffer* New(char *data, size_t len); // public constructor
+
+ // public constructor
+ static Buffer* New(size_t length);
+ // public constructor - data is copied
+ static Buffer* New(const char *data, size_t len);
+ // public constructor
static Buffer* New(char *data, size_t length,
- free_callback callback, void *hint); // public constructor
+ free_callback callback, void *hint);
private:
static v8::Handle<v8::Value> New(const v8::Arguments &args);
@@ -109,11 +118,21 @@ class NODE_EXTERN Buffer: public ObjectWrap {
static v8::Handle<v8::Value> Base64Slice(const v8::Arguments &args);
static v8::Handle<v8::Value> Utf8Slice(const v8::Arguments &args);
static v8::Handle<v8::Value> Ucs2Slice(const v8::Arguments &args);
+ static v8::Handle<v8::Value> HexSlice(const v8::Arguments &args);
static v8::Handle<v8::Value> BinaryWrite(const v8::Arguments &args);
static v8::Handle<v8::Value> Base64Write(const v8::Arguments &args);
static v8::Handle<v8::Value> AsciiWrite(const v8::Arguments &args);
static v8::Handle<v8::Value> Utf8Write(const v8::Arguments &args);
static v8::Handle<v8::Value> Ucs2Write(const v8::Arguments &args);
+ static v8::Handle<v8::Value> HexWrite(const v8::Arguments &args);
+ static v8::Handle<v8::Value> ReadFloatLE(const v8::Arguments &args);
+ static v8::Handle<v8::Value> ReadFloatBE(const v8::Arguments &args);
+ static v8::Handle<v8::Value> ReadDoubleLE(const v8::Arguments &args);
+ static v8::Handle<v8::Value> ReadDoubleBE(const v8::Arguments &args);
+ static v8::Handle<v8::Value> WriteFloatLE(const v8::Arguments &args);
+ static v8::Handle<v8::Value> WriteFloatBE(const v8::Arguments &args);
+ static v8::Handle<v8::Value> WriteDoubleLE(const v8::Arguments &args);
+ static v8::Handle<v8::Value> WriteDoubleBE(const v8::Arguments &args);
static v8::Handle<v8::Value> ByteLength(const v8::Arguments &args);
static v8::Handle<v8::Value> MakeFastBuffer(const v8::Arguments &args);
static v8::Handle<v8::Value> Fill(const v8::Arguments &args);
diff --git a/src/node_constants.cc b/src/node_constants.cc
index 7999f51ea..2aea278cb 100644
--- a/src/node_constants.cc
+++ b/src/node_constants.cc
@@ -106,6 +106,9 @@ void DefineConstants(Handle<Object> target) {
NODE_DEFINE_CONSTANT(target, O_SYMLINK);
#endif
+#ifdef O_DIRECT
+ NODE_DEFINE_CONSTANT(target, O_DIRECT);
+#endif
#ifdef S_IRWXU
NODE_DEFINE_CONSTANT(target, S_IRWXU);
@@ -791,6 +794,10 @@ void DefineConstants(Handle<Object> target) {
NODE_DEFINE_CONSTANT(target, SIGTSTP);
#endif
+#ifdef SIGBREAK
+ NODE_DEFINE_CONSTANT(target, SIGBREAK);
+#endif
+
#ifdef SIGTTIN
NODE_DEFINE_CONSTANT(target, SIGTTIN);
#endif
diff --git a/src/node_counters.cc b/src/node_counters.cc
new file mode 100644
index 000000000..3c8d49c00
--- /dev/null
+++ b/src/node_counters.cc
@@ -0,0 +1,149 @@
+// 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.
+
+#include "node_counters.h"
+
+#include "uv.h"
+
+#include <string.h>
+
+
+namespace node {
+
+using namespace v8;
+
+
+static uint64_t counter_gc_start_time;
+static uint64_t counter_gc_end_time;
+
+#define SLURP_OBJECT(obj, member, valp) \
+ if (!(obj)->IsObject()) { \
+ return (ThrowException(Exception::Error(String::New("expected " \
+ "object for " #obj " to contain object member " #member)))); \
+ } \
+ *valp = Local<Object>::Cast(obj->Get(String::New(#member)));
+
+
+Handle<Value> COUNTER_NET_SERVER_CONNECTION(const Arguments& args) {
+ NODE_COUNT_SERVER_CONN_OPEN();
+ return Undefined();
+}
+
+
+Handle<Value> COUNTER_NET_SERVER_CONNECTION_CLOSE(const Arguments& args) {
+ NODE_COUNT_SERVER_CONN_CLOSE();
+ return Undefined();
+}
+
+
+Handle<Value> COUNTER_HTTP_SERVER_REQUEST(const Arguments& args) {
+ NODE_COUNT_HTTP_SERVER_REQUEST();
+ return Undefined();
+}
+
+
+Handle<Value> COUNTER_HTTP_SERVER_RESPONSE(const Arguments& args) {
+ NODE_COUNT_HTTP_SERVER_RESPONSE();
+ return Undefined();
+}
+
+
+Handle<Value> COUNTER_HTTP_CLIENT_REQUEST(const Arguments& args) {
+ NODE_COUNT_HTTP_CLIENT_REQUEST();
+ return Undefined();
+}
+
+
+Handle<Value> COUNTER_HTTP_CLIENT_RESPONSE(const Arguments& args) {
+ NODE_COUNT_HTTP_CLIENT_RESPONSE();
+ return Undefined();
+}
+
+
+static void counter_gc_start(GCType type, GCCallbackFlags flags) {
+ counter_gc_start_time = NODE_COUNT_GET_GC_RAWTIME();
+
+ return;
+}
+
+
+static void counter_gc_done(GCType type, GCCallbackFlags flags) {
+ uint64_t endgc = NODE_COUNT_GET_GC_RAWTIME();
+ if (endgc != 0) {
+ uint64_t totalperiod = endgc - counter_gc_end_time;
+ uint64_t gcperiod = endgc - counter_gc_start_time;
+
+ if (totalperiod > 0) {
+ unsigned int percent = static_cast<unsigned int>((gcperiod * 100) / totalperiod);
+
+ NODE_COUNT_GC_PERCENTTIME(percent);
+ counter_gc_end_time = endgc;
+ }
+ }
+
+ return;
+}
+
+
+#define NODE_PROBE(name) #name, name
+
+void InitPerfCounters(Handle<Object> target) {
+ HandleScope scope;
+
+ static struct {
+ const char* name;
+ Handle<Value> (*func)(const Arguments&);
+ Persistent<FunctionTemplate> templ;
+ } tab[] = {
+ { NODE_PROBE(COUNTER_NET_SERVER_CONNECTION) },
+ { NODE_PROBE(COUNTER_NET_SERVER_CONNECTION_CLOSE) },
+ { NODE_PROBE(COUNTER_HTTP_SERVER_REQUEST) },
+ { NODE_PROBE(COUNTER_HTTP_SERVER_RESPONSE) },
+ { NODE_PROBE(COUNTER_HTTP_CLIENT_REQUEST) },
+ { NODE_PROBE(COUNTER_HTTP_CLIENT_RESPONSE) }
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(tab); i++) {
+ tab[i].templ = Persistent<FunctionTemplate>::New(
+ FunctionTemplate::New(tab[i].func));
+ target->Set(String::NewSymbol(tab[i].name), tab[i].templ->GetFunction());
+ }
+
+ // Only Windows performance counters supported
+ // To enable other OS, use conditional compilation here
+ InitPerfCountersWin32();
+
+ // init times for GC percent calculation and hook callbacks
+ counter_gc_start_time = NODE_COUNT_GET_GC_RAWTIME();
+ counter_gc_end_time = counter_gc_start_time;
+
+ v8::V8::AddGCPrologueCallback(counter_gc_start);
+ v8::V8::AddGCEpilogueCallback(counter_gc_done);
+}
+
+
+void TermPerfCounters(Handle<Object> target) {
+ // Only Windows performance counters supported
+ // To enable other OS, use conditional compilation here
+ TermPerfCountersWin32();
+}
+
+}
diff --git a/src/node_counters.h b/src/node_counters.h
new file mode 100644
index 000000000..c55d99b90
--- /dev/null
+++ b/src/node_counters.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef NODE_COUNTERS_H_
+#define NODE_COUNTERS_H_
+
+#include "node.h"
+#include "v8.h"
+
+namespace node {
+
+void InitPerfCounters(v8::Handle<v8::Object> target);
+void TermPerfCounters(v8::Handle<v8::Object> target);
+
+}
+
+#ifdef HAVE_PERFCTR
+#include "node_win32_perfctr_provider.h"
+#else
+#define NODE_COUNTER_ENABLED() (false)
+#define NODE_COUNT_HTTP_SERVER_REQUEST()
+#define NODE_COUNT_HTTP_SERVER_RESPONSE()
+#define NODE_COUNT_HTTP_CLIENT_REQUEST()
+#define NODE_COUNT_HTTP_CLIENT_RESPONSE()
+#define NODE_COUNT_SERVER_CONN_OPEN()
+#define NODE_COUNT_SERVER_CONN_CLOSE()
+#define NODE_COUNT_NET_BYTES_SENT(bytes)
+#define NODE_COUNT_NET_BYTES_RECV(bytes)
+#define NODE_COUNT_GET_GC_RAWTIME()
+#define NODE_COUNT_GC_PERCENTTIME()
+#define NODE_COUNT_PIPE_BYTES_SENT(bytes)
+#define NODE_COUNT_PIPE_BYTES_RECV(bytes)
+#endif
+
+#endif
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 7e168b6f3..44d2171d1 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -33,26 +33,17 @@
#endif
#include <stdlib.h>
-
#include <errno.h>
-/* Sigh. */
-#ifdef _WIN32
-# include <windows.h>
-#else
-# include <pthread.h>
-#endif
-
-
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
# define OPENSSL_CONST const
#else
# define OPENSSL_CONST
#endif
-#define ASSERT_IS_STRING_OR_BUFFER(val) \
- if (!val->IsString() && !Buffer::HasInstance(val)) { \
- return ThrowException(Exception::TypeError(String::New("Not a string or buffer"))); \
+#define ASSERT_IS_BUFFER(val) \
+ if (!Buffer::HasInstance(val)) { \
+ return ThrowException(Exception::TypeError(String::New("Not a buffer"))); \
}
static const char PUBLIC_KEY_PFX[] = "-----BEGIN PUBLIC KEY-----";
@@ -84,18 +75,17 @@ static Persistent<String> version_symbol;
static Persistent<String> ext_key_usage_symbol;
static Persistent<String> onhandshakestart_sym;
static Persistent<String> onhandshakedone_sym;
+static Persistent<String> onclienthello_sym;
+static Persistent<String> onnewsession_sym;
+static Persistent<String> sessionid_sym;
static Persistent<FunctionTemplate> secure_context_constructor;
static uv_rwlock_t* locks;
-static unsigned long crypto_id_cb(void) {
-#ifdef _WIN32
- return (unsigned long) GetCurrentThreadId();
-#else /* !_WIN32 */
- return (unsigned long) pthread_self();
-#endif /* !_WIN32 */
+static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
+ CRYPTO_THREADID_set_numeric(tid, uv_thread_self());
}
@@ -129,6 +119,22 @@ static void crypto_lock_cb(int mode, int n, const char* file, int line) {
}
+Handle<Value> ThrowCryptoErrorHelper(unsigned long err, bool is_type_error) {
+ HandleScope scope;
+ char errmsg[128];
+ ERR_error_string_n(err, errmsg, sizeof(errmsg));
+ return is_type_error ? ThrowTypeError(errmsg) : ThrowError(errmsg);
+}
+
+
+Handle<Value> ThrowCryptoError(unsigned long err) {
+ return ThrowCryptoErrorHelper(err, false);
+}
+
+
+Handle<Value> ThrowCryptoTypeError(unsigned long err) {
+ return ThrowCryptoErrorHelper(err, true);
+}
void SecureContext::Initialize(Handle<Object> target) {
@@ -217,15 +223,71 @@ Handle<Value> SecureContext::Init(const Arguments& args) {
}
sc->ctx_ = SSL_CTX_new(method);
- // Enable session caching?
- SSL_CTX_set_session_cache_mode(sc->ctx_, SSL_SESS_CACHE_SERVER);
- // SSL_CTX_set_session_cache_mode(sc->ctx_,SSL_SESS_CACHE_OFF);
+
+ // SSL session cache configuration
+ SSL_CTX_set_session_cache_mode(sc->ctx_,
+ SSL_SESS_CACHE_SERVER |
+ SSL_SESS_CACHE_NO_INTERNAL |
+ SSL_SESS_CACHE_NO_AUTO_CLEAR);
+ SSL_CTX_sess_set_get_cb(sc->ctx_, GetSessionCallback);
+ SSL_CTX_sess_set_new_cb(sc->ctx_, NewSessionCallback);
sc->ca_store_ = NULL;
return True();
}
+SSL_SESSION* SecureContext::GetSessionCallback(SSL* s,
+ unsigned char* key,
+ int len,
+ int* copy) {
+ HandleScope scope;
+
+ Connection* p = static_cast<Connection*>(SSL_get_app_data(s));
+
+ *copy = 0;
+ SSL_SESSION* sess = p->next_sess_;
+ p->next_sess_ = NULL;
+
+ return sess;
+}
+
+
+void SessionDataFree(char* data, void* hint) {
+ delete[] data;
+}
+
+
+int SecureContext::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
+ HandleScope scope;
+
+ Connection* p = static_cast<Connection*>(SSL_get_app_data(s));
+
+ // Check if session is small enough to be stored
+ int size = i2d_SSL_SESSION(sess, NULL);
+ if (size > kMaxSessionSize) return 0;
+
+ // Serialize session
+ char* serialized = new char[size];
+ unsigned char* pserialized = reinterpret_cast<unsigned char*>(serialized);
+ memset(serialized, 0, size);
+ i2d_SSL_SESSION(sess, &pserialized);
+
+ Handle<Value> argv[2] = {
+ Buffer::New(reinterpret_cast<char*>(sess->session_id),
+ sess->session_id_length)->handle_,
+ Buffer::New(serialized, size, SessionDataFree, NULL)->handle_
+ };
+
+ if (onnewsession_sym.IsEmpty()) {
+ onnewsession_sym = NODE_PSYMBOL("onnewsession");
+ }
+ MakeCallback(p->handle_, onnewsession_sym, ARRAY_SIZE(argv), argv);
+
+ return 0;
+}
+
+
// Takes a string or buffer and loads it into a BIO.
// Caller responsible for BIO_free-ing the returned object.
static BIO* LoadBIO (Handle<Value> v) {
@@ -240,9 +302,8 @@ static BIO* LoadBIO (Handle<Value> v) {
String::Utf8Value s(v);
r = BIO_write(bio, *s, s.length());
} else if (Buffer::HasInstance(v)) {
- Local<Object> buffer_obj = v->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(v);
+ size_t buffer_length = Buffer::Length(v);
r = BIO_write(bio, buffer_data, buffer_length);
}
@@ -302,9 +363,7 @@ Handle<Value> SecureContext::SetKey(const Arguments& args) {
return ThrowException(Exception::Error(
String::New("PEM_read_bio_PrivateKey")));
}
- char string[120];
- ERR_error_string_n(err, string, sizeof string);
- return ThrowException(Exception::Error(String::New(string)));
+ return ThrowCryptoError(err);
}
SSL_CTX_use_PrivateKey(sc->ctx_, key);
@@ -404,9 +463,7 @@ Handle<Value> SecureContext::SetCert(const Arguments& args) {
return ThrowException(Exception::Error(
String::New("SSL_CTX_use_certificate_chain")));
}
- char string[120];
- ERR_error_string_n(err, string, sizeof string);
- return ThrowException(Exception::Error(String::New(string)));
+ return ThrowCryptoError(err);
}
return True();
@@ -535,13 +592,11 @@ Handle<Value> SecureContext::SetOptions(const Arguments& args) {
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
- if (args.Length() != 1 || !args[0]->IsUint32()) {
+ if (args.Length() != 1 || !args[0]->IntegerValue()) {
return ThrowException(Exception::TypeError(String::New("Bad parameter")));
}
- unsigned int opts = args[0]->Uint32Value();
-
- SSL_CTX_set_options(sc->ctx_, opts);
+ SSL_CTX_set_options(sc->ctx_, args[0]->IntegerValue());
return True();
}
@@ -611,9 +666,9 @@ Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) {
}
if (args.Length() >= 2) {
- ASSERT_IS_STRING_OR_BUFFER(args[1]);
+ ASSERT_IS_BUFFER(args[1]);
- int passlen = DecodeBytes(args[1], BINARY);
+ int passlen = Buffer::Length(args[1]);
if (passlen < 0) {
BIO_free(in);
return ThrowException(Exception::TypeError(
@@ -655,7 +710,7 @@ Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) {
if (!ret) {
unsigned long err = ERR_get_error();
- const char *str = ERR_reason_error_string(err);
+ const char* str = ERR_reason_error_string(err);
return ThrowException(Exception::Error(String::New(str)));
}
@@ -663,6 +718,150 @@ Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) {
}
+size_t ClientHelloParser::Write(const uint8_t* data, size_t len) {
+ HandleScope scope;
+
+ // Just accumulate data, everything will be pushed to BIO later
+ if (state_ == kPaused) return 0;
+
+ // Copy incoming data to the internal buffer
+ // (which has a size of the biggest possible TLS frame)
+ size_t available = sizeof(data_) - offset_;
+ size_t copied = len < available ? len : available;
+ memcpy(data_ + offset_, data, copied);
+ offset_ += copied;
+
+ // Vars for parsing hello
+ bool is_clienthello = false;
+ uint8_t session_size = -1;
+ uint8_t* session_id = NULL;
+ Local<Object> hello;
+ Handle<Value> argv[1];
+
+ switch (state_) {
+ case kWaiting:
+ // >= 5 bytes for header parsing
+ if (offset_ < 5) break;
+
+ if (data_[0] == kChangeCipherSpec || data_[0] == kAlert ||
+ data_[0] == kHandshake || data_[0] == kApplicationData) {
+ frame_len_ = (data_[3] << 8) + data_[4];
+ state_ = kTLSHeader;
+ body_offset_ = 5;
+ } else {
+ frame_len_ = (data_[0] << 8) + data_[1];
+ state_ = kSSLHeader;
+ if (*data_ & 0x40) {
+ // header with padding
+ body_offset_ = 3;
+ } else {
+ // without padding
+ body_offset_ = 2;
+ }
+ }
+
+ // Sanity check (too big frame, or too small)
+ if (frame_len_ >= sizeof(data_)) {
+ // Let OpenSSL handle it
+ Finish();
+ return copied;
+ }
+ case kTLSHeader:
+ case kSSLHeader:
+ // >= 5 + frame size bytes for frame parsing
+ if (offset_ < body_offset_ + frame_len_) break;
+
+ // Skip unsupported frames and gather some data from frame
+
+ // TODO: Check protocol version
+ if (data_[body_offset_] == kClientHello) {
+ is_clienthello = true;
+ uint8_t* body;
+ size_t session_offset;
+
+ if (state_ == kTLSHeader) {
+ // Skip frame header, hello header, protocol version and random data
+ session_offset = body_offset_ + 4 + 2 + 32;
+
+ if (session_offset + 1 < offset_) {
+ body = data_ + session_offset;
+ session_size = *body;
+ session_id = body + 1;
+ }
+ } else if (state_ == kSSLHeader) {
+ // Skip header, version
+ session_offset = body_offset_ + 3;
+
+ if (session_offset + 4 < offset_) {
+ body = data_ + session_offset;
+
+ int ciphers_size = (body[0] << 8) + body[1];
+
+ if (body + 4 + ciphers_size < data_ + offset_) {
+ session_size = (body[2] << 8) + body[3];
+ session_id = body + 4 + ciphers_size;
+ }
+ }
+ } else {
+ // Whoa? How did we get here?
+ abort();
+ }
+
+ // Check if we overflowed (do not reply with any private data)
+ if (session_id == NULL ||
+ session_size > 32 ||
+ session_id + session_size > data_ + offset_) {
+ Finish();
+ return copied;
+ }
+
+ // TODO: Parse other things?
+ }
+
+ // Not client hello - let OpenSSL handle it
+ if (!is_clienthello) {
+ Finish();
+ return copied;
+ }
+
+ // Parse frame, call javascript handler and
+ // move parser into the paused state
+ if (onclienthello_sym.IsEmpty()) {
+ onclienthello_sym = NODE_PSYMBOL("onclienthello");
+ }
+ if (sessionid_sym.IsEmpty()) {
+ sessionid_sym = NODE_PSYMBOL("sessionId");
+ }
+
+ state_ = kPaused;
+ hello = Object::New();
+ hello->Set(sessionid_sym,
+ Buffer::New(reinterpret_cast<char*>(session_id),
+ session_size)->handle_);
+
+ argv[0] = hello;
+ MakeCallback(conn_->handle_, onclienthello_sym, 1, argv);
+ break;
+ case kEnded:
+ default:
+ break;
+ }
+
+ return copied;
+}
+
+
+void ClientHelloParser::Finish() {
+ assert(state_ != kEnded);
+ state_ = kEnded;
+
+ // Write all accumulated data
+ int r = BIO_write(conn_->bio_read_, reinterpret_cast<char*>(data_), offset_);
+ conn_->HandleBIOError(conn_->bio_read_, "BIO_write", r);
+ conn_->SetShutdownFlags();
+}
+
+
#ifdef SSL_PRINT_DEBUG
# define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
#else
@@ -701,8 +900,19 @@ int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
}
-int Connection::HandleSSLError(const char* func, int rv) {
- if (rv >= 0) return rv;
+int Connection::HandleSSLError(const char* func, int rv, ZeroStatus zs) {
+ // Forcibly clear OpenSSL's error stack on return. This stops stale errors
+ // from popping up later in the lifecycle of the SSL connection where they
+ // would cause spurious failures. It's a rather blunt method, though.
+ // ERR_clear_error() isn't necessarily cheap either.
+ struct ClearErrorOnReturn {
+ ~ClearErrorOnReturn() { ERR_clear_error(); }
+ };
+ ClearErrorOnReturn clear_error_on_return;
+ (void) &clear_error_on_return; // Silence unused variable warning.
+
+ if (rv > 0) return rv;
+ if ((rv == 0) && (zs == kZeroIsNotAnError)) return rv;
int err = SSL_get_error(ssl_, rv);
@@ -785,6 +995,7 @@ void Connection::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "getPeerCertificate", Connection::GetPeerCertificate);
NODE_SET_PROTOTYPE_METHOD(t, "getSession", Connection::GetSession);
NODE_SET_PROTOTYPE_METHOD(t, "setSession", Connection::SetSession);
+ NODE_SET_PROTOTYPE_METHOD(t, "loadSession", Connection::LoadSession);
NODE_SET_PROTOTYPE_METHOD(t, "isSessionReused", Connection::IsSessionReused);
NODE_SET_PROTOTYPE_METHOD(t, "isInitFinished", Connection::IsInitFinished);
NODE_SET_PROTOTYPE_METHOD(t, "verifyError", Connection::VerifyError);
@@ -857,7 +1068,7 @@ static int VerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) {
#ifdef OPENSSL_NPN_NEGOTIATED
int Connection::AdvertiseNextProtoCallback_(SSL *s,
- const unsigned char **data,
+ const unsigned char** data,
unsigned int *len,
void *arg) {
@@ -876,7 +1087,7 @@ int Connection::AdvertiseNextProtoCallback_(SSL *s,
}
int Connection::SelectNextProtoCallback_(SSL *s,
- unsigned char **out, unsigned char *outlen,
+ unsigned char** out, unsigned char* outlen,
const unsigned char* in,
unsigned int inlen, void *arg) {
Connection *p = static_cast<Connection*> SSL_get_app_data(s);
@@ -1092,9 +1303,8 @@ Handle<Value> Connection::EncIn(const Arguments& args) {
String::New("Second argument should be a buffer")));
}
- Local<Object> buffer_obj = args[0]->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(args[0]);
+ size_t buffer_length = Buffer::Length(args[0]);
size_t off = args[1]->Int32Value();
if (off >= buffer_length) {
@@ -1108,9 +1318,17 @@ Handle<Value> Connection::EncIn(const Arguments& args) {
String::New("off + len > buffer.length")));
}
- int bytes_written = BIO_write(ss->bio_read_, buffer_data + off, len);
- ss->HandleBIOError(ss->bio_read_, "BIO_write", bytes_written);
- ss->SetShutdownFlags();
+ int bytes_written;
+ char* data = buffer_data + off;
+
+ if (ss->is_server_ && !ss->hello_parser_.ended()) {
+ bytes_written = ss->hello_parser_.Write(reinterpret_cast<uint8_t*>(data),
+ len);
+ } else {
+ bytes_written = BIO_write(ss->bio_read_, data, len);
+ ss->HandleBIOError(ss->bio_read_, "BIO_write", bytes_written);
+ ss->SetShutdownFlags();
+ }
return scope.Close(Integer::New(bytes_written));
}
@@ -1131,9 +1349,8 @@ Handle<Value> Connection::ClearOut(const Arguments& args) {
String::New("Second argument should be a buffer")));
}
- Local<Object> buffer_obj = args[0]->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(args[0]);
+ size_t buffer_length = Buffer::Length(args[0]);
size_t off = args[1]->Int32Value();
if (off >= buffer_length) {
@@ -1152,17 +1369,17 @@ Handle<Value> Connection::ClearOut(const Arguments& args) {
if (ss->is_server_) {
rv = SSL_accept(ss->ssl_);
- ss->HandleSSLError("SSL_accept:ClearOut", rv);
+ ss->HandleSSLError("SSL_accept:ClearOut", rv, kZeroIsAnError);
} else {
rv = SSL_connect(ss->ssl_);
- ss->HandleSSLError("SSL_connect:ClearOut", rv);
+ ss->HandleSSLError("SSL_connect:ClearOut", rv, kZeroIsAnError);
}
if (rv < 0) return scope.Close(Integer::New(rv));
}
int bytes_read = SSL_read(ss->ssl_, buffer_data + off, len);
- ss->HandleSSLError("SSL_read:ClearOut", bytes_read);
+ ss->HandleSSLError("SSL_read:ClearOut", bytes_read, kZeroIsNotAnError);
ss->SetShutdownFlags();
return scope.Close(Integer::New(bytes_read));
@@ -1204,9 +1421,8 @@ Handle<Value> Connection::EncOut(const Arguments& args) {
String::New("Second argument should be a buffer")));
}
- Local<Object> buffer_obj = args[0]->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(args[0]);
+ size_t buffer_length = Buffer::Length(args[0]);
size_t off = args[1]->Int32Value();
if (off >= buffer_length) {
@@ -1244,9 +1460,8 @@ Handle<Value> Connection::ClearIn(const Arguments& args) {
String::New("Second argument should be a buffer")));
}
- Local<Object> buffer_obj = args[0]->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(args[0]);
+ size_t buffer_length = Buffer::Length(args[0]);
size_t off = args[1]->Int32Value();
if (off > buffer_length) {
@@ -1264,10 +1479,10 @@ Handle<Value> Connection::ClearIn(const Arguments& args) {
int rv;
if (ss->is_server_) {
rv = SSL_accept(ss->ssl_);
- ss->HandleSSLError("SSL_accept:ClearIn", rv);
+ ss->HandleSSLError("SSL_accept:ClearIn", rv, kZeroIsAnError);
} else {
rv = SSL_connect(ss->ssl_);
- ss->HandleSSLError("SSL_connect:ClearIn", rv);
+ ss->HandleSSLError("SSL_connect:ClearIn", rv, kZeroIsAnError);
}
if (rv < 0) return scope.Close(Integer::New(rv));
@@ -1275,7 +1490,7 @@ Handle<Value> Connection::ClearIn(const Arguments& args) {
int bytes_written = SSL_write(ss->ssl_, buffer_data + off, len);
- ss->HandleSSLError("SSL_write:ClearIn", bytes_written);
+ ss->HandleSSLError("SSL_write:ClearIn", bytes_written, kZeroIsAnError);
ss->SetShutdownFlags();
return scope.Close(Integer::New(bytes_written));
@@ -1431,13 +1646,14 @@ Handle<Value> Connection::SetSession(const Arguments& args) {
Connection *ss = Connection::Unwrap(args);
- if (args.Length() < 1 || !args[0]->IsString()) {
+ if (args.Length() < 1 ||
+ (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
return ThrowException(exception);
}
- ASSERT_IS_STRING_OR_BUFFER(args[0]);
- ssize_t slen = DecodeBytes(args[0], BINARY);
+ ASSERT_IS_BUFFER(args[0]);
+ ssize_t slen = Buffer::Length(args[0]);
if (slen < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
@@ -1449,7 +1665,7 @@ Handle<Value> Connection::SetSession(const Arguments& args) {
ssize_t wlen = DecodeWrite(sbuf, slen, args[0], BINARY);
assert(wlen == slen);
- const unsigned char* p = (unsigned char*) sbuf;
+ const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, wlen);
delete [] sbuf;
@@ -1468,13 +1684,40 @@ Handle<Value> Connection::SetSession(const Arguments& args) {
return True();
}
+Handle<Value> Connection::LoadSession(const Arguments& args) {
+ HandleScope scope;
+
+ Connection *ss = Connection::Unwrap(args);
+
+ if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
+ ssize_t slen = Buffer::Length(args[0].As<Object>());
+ char* sbuf = Buffer::Data(args[0].As<Object>());
+
+ const unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
+ SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, slen);
+
+ // Setup next session and move hello to the BIO buffer
+ if (ss->next_sess_ != NULL) {
+ SSL_SESSION_free(ss->next_sess_);
+ }
+ ss->next_sess_ = sess;
+ }
+
+ ss->hello_parser_.Finish();
+
+ return True();
+}
+
Handle<Value> Connection::IsSessionReused(const Arguments& args) {
HandleScope scope;
Connection *ss = Connection::Unwrap(args);
- if (ss->ssl_ == NULL) return False();
- return SSL_session_reused(ss->ssl_) ? True() : False();
+ if (ss->ssl_ == NULL || SSL_session_reused(ss->ssl_) == false) {
+ return False();
+ }
+
+ return True();
}
@@ -1487,10 +1730,10 @@ Handle<Value> Connection::Start(const Arguments& args) {
int rv;
if (ss->is_server_) {
rv = SSL_accept(ss->ssl_);
- ss->HandleSSLError("SSL_accept:Start", rv);
+ ss->HandleSSLError("SSL_accept:Start", rv, kZeroIsAnError);
} else {
rv = SSL_connect(ss->ssl_);
- ss->HandleSSLError("SSL_connect:Start", rv);
+ ss->HandleSSLError("SSL_connect:Start", rv, kZeroIsAnError);
}
return scope.Close(Integer::New(rv));
@@ -1507,8 +1750,7 @@ Handle<Value> Connection::Shutdown(const Arguments& args) {
if (ss->ssl_ == NULL) return False();
int rv = SSL_shutdown(ss->ssl_);
-
- ss->HandleSSLError("SSL_shutdown", rv);
+ ss->HandleSSLError("SSL_shutdown", rv, kZeroIsNotAnError);
ss->SetShutdownFlags();
return scope.Close(Integer::New(rv));
@@ -1534,8 +1776,11 @@ Handle<Value> Connection::IsInitFinished(const Arguments& args) {
Connection *ss = Connection::Unwrap(args);
- if (ss->ssl_ == NULL) return False();
- return SSL_is_init_finished(ss->ssl_) ? True() : False();
+ if (ss->ssl_ == NULL || SSL_is_init_finished(ss->ssl_) == false) {
+ return False();
+ }
+
+ return True();
}
@@ -1695,9 +1940,9 @@ Handle<Value> Connection::GetCurrentCipher(const Arguments& args) {
c = SSL_get_current_cipher(ss->ssl_);
if ( c == NULL ) return Undefined();
Local<Object> info = Object::New();
- const char *cipher_name = SSL_CIPHER_get_name(c);
+ const char* cipher_name = SSL_CIPHER_get_name(c);
info->Set(name_symbol, String::New(cipher_name));
- const char *cipher_version = SSL_CIPHER_get_version(c);
+ const char* cipher_version = SSL_CIPHER_get_version(c);
info->Set(version_symbol, String::New(cipher_version));
return scope.Close(info);
}
@@ -1721,7 +1966,7 @@ Handle<Value> Connection::GetNegotiatedProto(const Arguments& args) {
Connection *ss = Connection::Unwrap(args);
if (ss->is_server_) {
- const unsigned char *npn_proto;
+ const unsigned char* npn_proto;
unsigned int npn_proto_len;
SSL_get0_next_proto_negotiated(ss->ssl_, &npn_proto, &npn_proto_len);
@@ -1790,197 +2035,6 @@ Handle<Value> Connection::SetSNICallback(const Arguments& args) {
}
#endif
-static void HexEncode(unsigned char *md_value,
- int md_len,
- char** md_hexdigest,
- int* md_hex_len) {
- *md_hex_len = (2*(md_len));
- *md_hexdigest = new char[*md_hex_len + 1];
-
- char* buff = *md_hexdigest;
- const int len = *md_hex_len;
- for (int i = 0; i < len; i += 2) {
- // nibble nibble
- const int index = i / 2;
- const char msb = (md_value[index] >> 4) & 0x0f;
- const char lsb = md_value[index] & 0x0f;
-
- buff[i] = (msb < 10) ? msb + '0' : (msb - 10) + 'a';
- buff[i + 1] = (lsb < 10) ? lsb + '0' : (lsb - 10) + 'a';
- }
- // null terminator
- buff[*md_hex_len] = '\0';
-}
-
-#define hex2i(c) ((c) <= '9' ? ((c) - '0') : (c) <= 'Z' ? ((c) - 'A' + 10) \
- : ((c) - 'a' + 10))
-
-static void HexDecode(unsigned char *input,
- int length,
- char** buf64,
- int* buf64_len) {
- *buf64_len = (length/2);
- *buf64 = new char[length/2 + 1];
- char *b = *buf64;
- for(int i = 0; i < length-1; i+=2) {
- b[i/2] = (hex2i(input[i])<<4) | (hex2i(input[i+1]));
- }
-}
-
-
-void base64(unsigned char *input, int length, char** buf64, int* buf64_len) {
- BIO *b64 = BIO_new(BIO_f_base64());
- BIO *bmem = BIO_new(BIO_s_mem());
- b64 = BIO_push(b64, bmem);
- BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
- int len = BIO_write(b64, input, length);
- assert(len == length);
- int r = BIO_flush(b64);
- assert(r == 1);
-
- BUF_MEM *bptr;
- BIO_get_mem_ptr(b64, &bptr);
-
- *buf64_len = bptr->length;
- *buf64 = new char[*buf64_len+1];
- memcpy(*buf64, bptr->data, *buf64_len);
- char* b = *buf64;
- b[*buf64_len] = 0;
-
- BIO_free_all(b64);
-}
-
-
-void unbase64(unsigned char *input,
- int length,
- char** buffer,
- int* buffer_len) {
- BIO *b64, *bmem;
- *buffer = new char[length];
- memset(*buffer, 0, length);
-
- b64 = BIO_new(BIO_f_base64());
- BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
- bmem = BIO_new_mem_buf(input, length);
- bmem = BIO_push(b64, bmem);
-
- *buffer_len = BIO_read(bmem, *buffer, length);
- BIO_free_all(bmem);
-}
-
-
-// LengthWithoutIncompleteUtf8 from V8 d8-posix.cc
-// see http://v8.googlecode.com/svn/trunk/src/d8-posix.cc
-static int LengthWithoutIncompleteUtf8(char* buffer, int len) {
- int answer = len;
- // 1-byte encoding.
- static const int kUtf8SingleByteMask = 0x80;
- static const int kUtf8SingleByteValue = 0x00;
- // 2-byte encoding.
- static const int kUtf8TwoByteMask = 0xe0;
- static const int kUtf8TwoByteValue = 0xc0;
- // 3-byte encoding.
- static const int kUtf8ThreeByteMask = 0xf0;
- static const int kUtf8ThreeByteValue = 0xe0;
- // 4-byte encoding.
- static const int kUtf8FourByteMask = 0xf8;
- static const int kUtf8FourByteValue = 0xf0;
- // Subsequent bytes of a multi-byte encoding.
- static const int kMultiByteMask = 0xc0;
- static const int kMultiByteValue = 0x80;
- int multi_byte_bytes_seen = 0;
- while (answer > 0) {
- int c = buffer[answer - 1];
- // Ends in valid single-byte sequence?
- if ((c & kUtf8SingleByteMask) == kUtf8SingleByteValue) return answer;
- // Ends in one or more subsequent bytes of a multi-byte value?
- if ((c & kMultiByteMask) == kMultiByteValue) {
- multi_byte_bytes_seen++;
- answer--;
- } else {
- if ((c & kUtf8TwoByteMask) == kUtf8TwoByteValue) {
- if (multi_byte_bytes_seen >= 1) {
- return answer + 2;
- }
- return answer - 1;
- } else if ((c & kUtf8ThreeByteMask) == kUtf8ThreeByteValue) {
- if (multi_byte_bytes_seen >= 2) {
- return answer + 3;
- }
- return answer - 1;
- } else if ((c & kUtf8FourByteMask) == kUtf8FourByteValue) {
- if (multi_byte_bytes_seen >= 3) {
- return answer + 4;
- }
- return answer - 1;
- } else {
- return answer; // Malformed UTF-8.
- }
- }
- }
- return 0;
-}
-
-
-// local decrypt final without strict padding check
-// to work with php mcrypt
-// see http://www.mail-archive.com/openssl-dev@openssl.org/msg19927.html
-int local_EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx,
- unsigned char *out,
- int *outl) {
- int i,b;
- int n;
-
- *outl=0;
- b=ctx->cipher->block_size;
-
- if (ctx->flags & EVP_CIPH_NO_PADDING) {
- if(ctx->buf_len) {
- EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
- return 0;
- }
- *outl = 0;
- return 1;
- }
-
- if (b > 1) {
- if (ctx->buf_len || !ctx->final_used) {
- EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
- return(0);
- }
-
- if (b > (int)(sizeof(ctx->final) / sizeof(ctx->final[0]))) {
- EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
- return(0);
- }
-
- n=ctx->final[b-1];
-
- if (n > b) {
- EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
- return(0);
- }
-
- for (i=0; i<n; i++) {
- if (ctx->final[--b] != n) {
- EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
- return(0);
- }
- }
-
- n=ctx->cipher->block_size-n;
-
- for (i=0; i<n; i++) {
- out[i]=ctx->final[i];
- }
- *outl=n;
- } else {
- *outl=0;
- }
-
- return(1);
-}
-
class Cipher : public ObjectWrap {
public:
@@ -2020,8 +2074,8 @@ class Cipher : public ObjectWrap {
return false;
}
EVP_CipherInit_ex(&ctx, NULL, NULL,
- (unsigned char *)key,
- (unsigned char *)iv, true);
+ (unsigned char*)key,
+ (unsigned char*)iv, true);
initialised_ = true;
return true;
}
@@ -2030,7 +2084,7 @@ class Cipher : public ObjectWrap {
bool CipherInitIv(char* cipherType,
char* key,
int key_len,
- char *iv,
+ char* iv,
int iv_len) {
cipher = EVP_get_cipherbyname(cipherType);
if(!cipher) {
@@ -2052,8 +2106,8 @@ class Cipher : public ObjectWrap {
return false;
}
EVP_CipherInit_ex(&ctx, NULL, NULL,
- (unsigned char *)key,
- (unsigned char *)iv, true);
+ (unsigned char*)key,
+ (unsigned char*)iv, true);
initialised_ = true;
return true;
}
@@ -2062,9 +2116,7 @@ class Cipher : public ObjectWrap {
if (!initialised_) return 0;
*out_len=len+EVP_CIPHER_CTX_block_size(&ctx);
*out= new unsigned char[*out_len];
-
- EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
- return 1;
+ return EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
}
int SetAutoPadding(bool auto_padding) {
@@ -2097,8 +2149,6 @@ class Cipher : public ObjectWrap {
Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
- cipher->incomplete_base64 = NULL;
-
if (args.Length() <= 1
|| !args[0]->IsString()
|| !(args[1]->IsString() || Buffer::HasInstance(args[1])))
@@ -2107,8 +2157,8 @@ class Cipher : public ObjectWrap {
"Must give cipher-type, key")));
}
- ASSERT_IS_STRING_OR_BUFFER(args[1]);
- ssize_t key_buf_len = DecodeBytes(args[1], BINARY);
+ ASSERT_IS_BUFFER(args[1]);
+ ssize_t key_buf_len = Buffer::Length(args[1]);
if (key_buf_len < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
@@ -2125,9 +2175,7 @@ class Cipher : public ObjectWrap {
delete [] key_buf;
- if (!r) {
- return ThrowException(Exception::Error(String::New("CipherInit error")));
- }
+ if (!r) return ThrowCryptoError(ERR_get_error());
return args.This();
}
@@ -2138,7 +2186,6 @@ class Cipher : public ObjectWrap {
HandleScope scope;
- cipher->incomplete_base64 = NULL;
if (args.Length() <= 2
|| !args[0]->IsString()
@@ -2149,16 +2196,16 @@ class Cipher : public ObjectWrap {
"Must give cipher-type, key, and iv as argument")));
}
- ASSERT_IS_STRING_OR_BUFFER(args[1]);
- ssize_t key_len = DecodeBytes(args[1], BINARY);
+ ASSERT_IS_BUFFER(args[1]);
+ ssize_t key_len = Buffer::Length(args[1]);
if (key_len < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
return ThrowException(exception);
}
- ASSERT_IS_STRING_OR_BUFFER(args[2]);
- ssize_t iv_len = DecodeBytes(args[2], BINARY);
+ ASSERT_IS_BUFFER(args[2]);
+ ssize_t iv_len = Buffer::Length(args[2]);
if (iv_len < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
@@ -2180,9 +2227,7 @@ class Cipher : public ObjectWrap {
delete [] key_buf;
delete [] iv_buf;
- if (!r) {
- return ThrowException(Exception::Error(String::New("CipherInitIv error")));
- }
+ if (!r) return ThrowCryptoError(ERR_get_error());
return args.This();
}
@@ -2192,87 +2237,22 @@ class Cipher : public ObjectWrap {
HandleScope scope;
- ASSERT_IS_STRING_OR_BUFFER(args[0]);
+ ASSERT_IS_BUFFER(args[0]);
- enum encoding enc = ParseEncoding(args[1]);
- ssize_t len = DecodeBytes(args[0], enc);
-
- if (len < 0) {
- Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
- return ThrowException(exception);
- }
-
- unsigned char *out=0;
+ unsigned char* out=0;
int out_len=0, r;
- if (Buffer::HasInstance(args[0])) {
- Local<Object> buffer_obj = args[0]->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(args[0]);
+ size_t buffer_length = Buffer::Length(args[0]);
- r = cipher->CipherUpdate(buffer_data, buffer_length, &out, &out_len);
- } else {
- char* buf = new char[len];
- ssize_t written = DecodeWrite(buf, len, args[0], enc);
- assert(written == len);
- r = cipher->CipherUpdate(buf, len,&out,&out_len);
- delete [] buf;
- }
+ r = cipher->CipherUpdate(buffer_data, buffer_length, &out, &out_len);
- if (!r) {
+ if (r == 0) {
delete [] out;
- Local<Value> exception = Exception::TypeError(String::New("DecipherUpdate fail"));
- return ThrowException(exception);
+ return ThrowCryptoTypeError(ERR_get_error());
}
Local<Value> outString;
- if (out_len==0) {
- outString=String::New("");
- } else {
- char* out_hexdigest;
- int out_hex_len;
- enum encoding enc = ParseEncoding(args[2], BINARY);
- if (enc == HEX) {
- // Hex encoding
- HexEncode(out, out_len, &out_hexdigest, &out_hex_len);
- outString = Encode(out_hexdigest, out_hex_len, BINARY);
- delete [] out_hexdigest;
- } else if (enc == BASE64) {
- // Base64 encoding
- // Check to see if we need to add in previous base64 overhang
- if (cipher->incomplete_base64!=NULL){
- unsigned char* complete_base64 = new unsigned char[out_len+cipher->incomplete_base64_len+1];
- memcpy(complete_base64, cipher->incomplete_base64, cipher->incomplete_base64_len);
- memcpy(&complete_base64[cipher->incomplete_base64_len], out, out_len);
- delete [] out;
-
- delete [] cipher->incomplete_base64;
- cipher->incomplete_base64=NULL;
-
- out=complete_base64;
- out_len += cipher->incomplete_base64_len;
- }
-
- // Check to see if we need to trim base64 stream
- if (out_len%3!=0){
- cipher->incomplete_base64_len = out_len%3;
- cipher->incomplete_base64 = new char[cipher->incomplete_base64_len+1];
- memcpy(cipher->incomplete_base64,
- &out[out_len-cipher->incomplete_base64_len],
- cipher->incomplete_base64_len);
- out_len -= cipher->incomplete_base64_len;
- out[out_len]=0;
- }
-
- base64(out, out_len, &out_hexdigest, &out_hex_len);
- outString = Encode(out_hexdigest, out_hex_len, BINARY);
- delete [] out_hexdigest;
- } else if (enc == BINARY) {
- outString = Encode(out, out_len, BINARY);
- } else {
- fprintf(stderr, "node-crypto : Cipher .update encoding "
- "can be binary, hex or base64\n");
- }
- }
+ outString = Encode(out, out_len, BUFFER);
if (out) delete [] out;
@@ -2295,8 +2275,6 @@ class Cipher : public ObjectWrap {
unsigned char* out_value = NULL;
int out_len = -1;
- char* out_hexdigest;
- int out_hex_len;
Local<Value> outString ;
int r = cipher->CipherFinal(&out_value, &out_len);
@@ -2307,44 +2285,11 @@ class Cipher : public ObjectWrap {
if (out_len == 0 || r == 0) {
// out_value always get allocated.
delete[] out_value;
- if (r == 0) {
- Local<Value> exception = Exception::TypeError(
- String::New("CipherFinal fail"));
- return ThrowException(exception);
- } else {
- return scope.Close(String::New(""));
- }
+ out_value = NULL;
+ if (r == 0) return ThrowCryptoTypeError(ERR_get_error());
}
- enum encoding enc = ParseEncoding(args[0], BINARY);
- if (enc == HEX) {
- // Hex encoding
- HexEncode(out_value, out_len, &out_hexdigest, &out_hex_len);
- outString = Encode(out_hexdigest, out_hex_len, BINARY);
- delete [] out_hexdigest;
- } else if (enc == BASE64) {
- // Check to see if we need to add in previous base64 overhang
- if (cipher->incomplete_base64!=NULL){
- unsigned char* complete_base64 = new unsigned char[out_len+cipher->incomplete_base64_len+1];
- memcpy(complete_base64, cipher->incomplete_base64, cipher->incomplete_base64_len);
- memcpy(&complete_base64[cipher->incomplete_base64_len], out_value, out_len);
- delete [] out_value;
-
- delete [] cipher->incomplete_base64;
- cipher->incomplete_base64=NULL;
-
- out_value=complete_base64;
- out_len += cipher->incomplete_base64_len;
- }
- base64(out_value, out_len, &out_hexdigest, &out_hex_len);
- outString = Encode(out_hexdigest, out_hex_len, BINARY);
- delete [] out_hexdigest;
- } else if (enc == BINARY) {
- outString = Encode(out_value, out_len, BINARY);
- } else {
- fprintf(stderr, "node-crypto : Cipher .final encoding "
- "can be binary, hex or base64\n");
- }
+ outString = Encode(out_value, out_len, BUFFER);
delete [] out_value;
return scope.Close(outString);
@@ -2366,9 +2311,6 @@ class Cipher : public ObjectWrap {
EVP_CIPHER_CTX ctx; /* coverity[member_decl] */
const EVP_CIPHER *cipher; /* coverity[member_decl] */
bool initialised_;
- char* incomplete_base64; /* coverity[member_decl] */
- int incomplete_base64_len; /* coverity[member_decl] */
-
};
@@ -2387,9 +2329,8 @@ class Decipher : public ObjectWrap {
NODE_SET_PROTOTYPE_METHOD(t, "init", DecipherInit);
NODE_SET_PROTOTYPE_METHOD(t, "initiv", DecipherInitIv);
NODE_SET_PROTOTYPE_METHOD(t, "update", DecipherUpdate);
- NODE_SET_PROTOTYPE_METHOD(t, "final", DecipherFinal<false>);
- // This is completely undocumented:
- NODE_SET_PROTOTYPE_METHOD(t, "finaltol", DecipherFinal<true>);
+ NODE_SET_PROTOTYPE_METHOD(t, "final", DecipherFinal);
+ NODE_SET_PROTOTYPE_METHOD(t, "finaltol", DecipherFinal); // remove someday
NODE_SET_PROTOTYPE_METHOD(t, "setAutoPadding", SetAutoPadding);
target->Set(String::NewSymbol("Decipher"), t->GetFunction());
@@ -2421,8 +2362,8 @@ class Decipher : public ObjectWrap {
return false;
}
EVP_CipherInit_ex(&ctx, NULL, NULL,
- (unsigned char *)key,
- (unsigned char *)iv, false);
+ (unsigned char*)key,
+ (unsigned char*)iv, false);
initialised_ = true;
return true;
}
@@ -2431,7 +2372,7 @@ class Decipher : public ObjectWrap {
bool DecipherInitIv(char* cipherType,
char* key,
int key_len,
- char *iv,
+ char* iv,
int iv_len) {
cipher_ = EVP_get_cipherbyname(cipherType);
if(!cipher_) {
@@ -2453,8 +2394,8 @@ class Decipher : public ObjectWrap {
return false;
}
EVP_CipherInit_ex(&ctx, NULL, NULL,
- (unsigned char *)key,
- (unsigned char *)iv, false);
+ (unsigned char*)key,
+ (unsigned char*)iv, false);
initialised_ = true;
return true;
}
@@ -2469,8 +2410,7 @@ class Decipher : public ObjectWrap {
*out_len=len+EVP_CIPHER_CTX_block_size(&ctx);
*out= new unsigned char[*out_len];
- EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
- return 1;
+ return EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
}
int SetAutoPadding(bool auto_padding) {
@@ -2479,7 +2419,6 @@ class Decipher : public ObjectWrap {
}
// coverity[alloc_arg]
- template <bool TOLERATE_PADDING>
int DecipherFinal(unsigned char** out, int *out_len) {
int r;
@@ -2490,11 +2429,7 @@ class Decipher : public ObjectWrap {
}
*out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx)];
- if (TOLERATE_PADDING) {
- r = local_EVP_DecryptFinal_ex(&ctx,*out,out_len);
- } else {
- r = EVP_CipherFinal_ex(&ctx,*out,out_len);
- }
+ r = EVP_CipherFinal_ex(&ctx,*out,out_len);
EVP_CIPHER_CTX_cleanup(&ctx);
initialised_ = false;
return r;
@@ -2516,9 +2451,6 @@ class Decipher : public ObjectWrap {
HandleScope scope;
- cipher->incomplete_utf8 = NULL;
- cipher->incomplete_hex_flag = false;
-
if (args.Length() <= 1
|| !args[0]->IsString()
|| !(args[1]->IsString() || Buffer::HasInstance(args[1])))
@@ -2527,8 +2459,8 @@ class Decipher : public ObjectWrap {
"Must give cipher-type, key as argument")));
}
- ASSERT_IS_STRING_OR_BUFFER(args[1]);
- ssize_t key_len = DecodeBytes(args[1], BINARY);
+ ASSERT_IS_BUFFER(args[1]);
+ ssize_t key_len = Buffer::Length(args[1]);
if (key_len < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
@@ -2557,9 +2489,6 @@ class Decipher : public ObjectWrap {
HandleScope scope;
- cipher->incomplete_utf8 = NULL;
- cipher->incomplete_hex_flag = false;
-
if (args.Length() <= 2
|| !args[0]->IsString()
|| !(args[1]->IsString() || Buffer::HasInstance(args[1]))
@@ -2569,16 +2498,16 @@ class Decipher : public ObjectWrap {
"Must give cipher-type, key, and iv as argument")));
}
- ASSERT_IS_STRING_OR_BUFFER(args[1]);
- ssize_t key_len = DecodeBytes(args[1], BINARY);
+ ASSERT_IS_BUFFER(args[1]);
+ ssize_t key_len = Buffer::Length(args[1]);
if (key_len < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
return ThrowException(exception);
}
- ASSERT_IS_STRING_OR_BUFFER(args[2]);
- ssize_t iv_len = DecodeBytes(args[2], BINARY);
+ ASSERT_IS_BUFFER(args[2]);
+ ssize_t iv_len = Buffer::Length(args[2]);
if (iv_len < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
@@ -2612,121 +2541,30 @@ class Decipher : public ObjectWrap {
Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
- ASSERT_IS_STRING_OR_BUFFER(args[0]);
+ ASSERT_IS_BUFFER(args[0]);
- ssize_t len = DecodeBytes(args[0], BINARY);
- if (len < 0) {
- return ThrowException(Exception::Error(String::New(
- "node`DecodeBytes() failed")));
- }
+ ssize_t len;
char* buf;
// if alloc_buf then buf must be deleted later
bool alloc_buf = false;
- if (Buffer::HasInstance(args[0])) {
- Local<Object> buffer_obj = args[0]->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(args[0]);
+ size_t buffer_length = Buffer::Length(args[0]);
- buf = buffer_data;
- len = buffer_length;
- } else {
- alloc_buf = true;
- buf = new char[len];
- ssize_t written = DecodeWrite(buf, len, args[0], BINARY);
- assert(written == len);
- }
-
- char* ciphertext;
- int ciphertext_len;
-
- enum encoding enc = ParseEncoding(args[1], BINARY);
- if (enc == HEX) {
- // Hex encoding
- // Do we have a previous hex carry over?
- if (cipher->incomplete_hex_flag) {
- char* complete_hex = new char[len+2];
- memcpy(complete_hex, &cipher->incomplete_hex, 1);
- memcpy(complete_hex+1, buf, len);
- if (alloc_buf) delete [] buf;
- alloc_buf = true;
- buf = complete_hex;
- len += 1;
- }
- // Do we have an incomplete hex stream?
- if ((len>0) && (len % 2 !=0)) {
- len--;
- cipher->incomplete_hex=buf[len];
- cipher->incomplete_hex_flag=true;
- buf[len]=0;
- }
- HexDecode((unsigned char*)buf, len, (char **)&ciphertext, &ciphertext_len);
+ buf = buffer_data;
+ len = buffer_length;
- if (alloc_buf) {
- delete [] buf;
- }
- buf = ciphertext;
- len = ciphertext_len;
- alloc_buf = true;
-
- } else if (enc == BASE64) {
- unbase64((unsigned char*)buf, len, (char **)&ciphertext, &ciphertext_len);
- if (alloc_buf) {
- delete [] buf;
- }
- buf = ciphertext;
- len = ciphertext_len;
- alloc_buf = true;
-
- } else if (enc == BINARY) {
- // Binary - do nothing
-
- } else {
- fprintf(stderr, "node-crypto : Decipher .update encoding "
- "can be binary, hex or base64\n");
- }
-
- unsigned char *out=0;
+ unsigned char* out=0;
int out_len=0;
int r = cipher->DecipherUpdate(buf, len, &out, &out_len);
if (!r) {
delete [] out;
- Local<Value> exception = Exception::TypeError(String::New("DecipherUpdate fail"));
- return ThrowException(exception);
+ return ThrowCryptoTypeError(ERR_get_error());
}
Local<Value> outString;
- if (out_len==0) {
- outString=String::New("");
- } else {
- enum encoding enc = ParseEncoding(args[2], BINARY);
- if (enc == UTF8) {
- // See if we have any overhang from last utf8 partial ending
- if (cipher->incomplete_utf8!=NULL) {
- char* complete_out = new char[cipher->incomplete_utf8_len + out_len];
- memcpy(complete_out, cipher->incomplete_utf8, cipher->incomplete_utf8_len);
- memcpy((char *)complete_out+cipher->incomplete_utf8_len, out, out_len);
- delete [] out;
-
- delete [] cipher->incomplete_utf8;
- cipher->incomplete_utf8 = NULL;
-
- out = (unsigned char*)complete_out;
- out_len += cipher->incomplete_utf8_len;
- }
- // Check to see if we have a complete utf8 stream
- int utf8_len = LengthWithoutIncompleteUtf8((char *)out, out_len);
- if (utf8_len<out_len) { // We have an incomplete ut8 ending
- cipher->incomplete_utf8_len = out_len-utf8_len;
- cipher->incomplete_utf8 = new unsigned char[cipher->incomplete_utf8_len+1];
- memcpy(cipher->incomplete_utf8, &out[utf8_len], cipher->incomplete_utf8_len);
- }
- outString = Encode(out, utf8_len, enc);
- } else {
- outString = Encode(out, out_len, enc);
- }
- }
+ outString = Encode(out, out_len, BUFFER);
if (out) delete [] out;
@@ -2744,7 +2582,6 @@ class Decipher : public ObjectWrap {
return Undefined();
}
- template <bool TOLERATE_PADDING>
static Handle<Value> DecipherFinal(const Arguments& args) {
HandleScope scope;
@@ -2754,45 +2591,18 @@ class Decipher : public ObjectWrap {
int out_len = -1;
Local<Value> outString;
- int r = cipher->DecipherFinal<TOLERATE_PADDING>(&out_value, &out_len);
+ int r = cipher->DecipherFinal(&out_value, &out_len);
assert(out_value != NULL);
assert(out_len != -1);
if (out_len == 0 || r == 0) {
delete [] out_value; // allocated even if out_len == 0
- if (r == 0) {
- Local<Value> exception = Exception::TypeError(
- String::New("DecipherFinal fail"));
- return ThrowException(exception);
- } else {
- return scope.Close(String::New(""));
- }
+ out_value = NULL;
+ if (r == 0) return ThrowCryptoTypeError(ERR_get_error());
}
- if (args.Length() == 0 || !args[0]->IsString()) {
- outString = Encode(out_value, out_len, BINARY);
- } else {
- enum encoding enc = ParseEncoding(args[0]);
- if (enc == UTF8) {
- // See if we have any overhang from last utf8 partial ending
- if (cipher->incomplete_utf8!=NULL) {
- char* complete_out = new char[cipher->incomplete_utf8_len + out_len];
- memcpy(complete_out, cipher->incomplete_utf8, cipher->incomplete_utf8_len);
- memcpy((char *)complete_out+cipher->incomplete_utf8_len, out_value, out_len);
-
- delete [] cipher->incomplete_utf8;
- cipher->incomplete_utf8=NULL;
-
- outString = Encode(complete_out, cipher->incomplete_utf8_len+out_len, enc);
- delete [] complete_out;
- } else {
- outString = Encode(out_value, out_len, enc);
- }
- } else {
- outString = Encode(out_value, out_len, enc);
- }
- }
+ outString = Encode(out_value, out_len, BUFFER);
delete [] out_value;
return scope.Close(outString);
}
@@ -2812,10 +2622,6 @@ class Decipher : public ObjectWrap {
EVP_CIPHER_CTX ctx;
const EVP_CIPHER *cipher_;
bool initialised_;
- unsigned char* incomplete_utf8;
- int incomplete_utf8_len;
- char incomplete_hex;
- bool incomplete_hex_flag;
};
@@ -2844,7 +2650,11 @@ class Hmac : public ObjectWrap {
return false;
}
HMAC_CTX_init(&ctx);
- HMAC_Init(&ctx, key, key_len, md);
+ if (key_len == 0) {
+ HMAC_Init(&ctx, "", 0, md);
+ } else {
+ HMAC_Init(&ctx, key, key_len, md);
+ }
initialised_ = true;
return true;
@@ -2886,8 +2696,8 @@ class Hmac : public ObjectWrap {
"Must give hashtype string as argument")));
}
- ASSERT_IS_STRING_OR_BUFFER(args[1]);
- ssize_t len = DecodeBytes(args[1], BINARY);
+ ASSERT_IS_BUFFER(args[1]);
+ ssize_t len = Buffer::Length(args[1]);
if (len < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
@@ -2899,9 +2709,8 @@ class Hmac : public ObjectWrap {
bool r;
if( Buffer::HasInstance(args[1])) {
- Local<Object> buffer_obj = args[1]->ToObject();
- char* buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(args[1]);
+ size_t buffer_length = Buffer::Length(args[1]);
r = hmac->HmacInit(*hashType, buffer_data, buffer_length);
} else {
@@ -2926,30 +2735,14 @@ class Hmac : public ObjectWrap {
HandleScope scope;
- ASSERT_IS_STRING_OR_BUFFER(args[0]);
- enum encoding enc = ParseEncoding(args[1]);
- ssize_t len = DecodeBytes(args[0], enc);
-
- if (len < 0) {
- Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
- return ThrowException(exception);
- }
+ ASSERT_IS_BUFFER(args[0]);
int r;
- if( Buffer::HasInstance(args[0])) {
- Local<Object> buffer_obj = args[0]->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(args[0]);
+ size_t buffer_length = Buffer::Length(args[0]);
- r = hmac->HmacUpdate(buffer_data, buffer_length);
- } else {
- char* buf = new char[len];
- ssize_t written = DecodeWrite(buf, len, args[0], enc);
- assert(written == len);
- r = hmac->HmacUpdate(buf, len);
- delete [] buf;
- }
+ r = hmac->HmacUpdate(buffer_data, buffer_length);
if (!r) {
Local<Value> exception = Exception::TypeError(String::New("HmacUpdate fail"));
@@ -2966,31 +2759,16 @@ class Hmac : public ObjectWrap {
unsigned char* md_value = NULL;
unsigned int md_len = 0;
- char* md_hexdigest;
- int md_hex_len;
Local<Value> outString;
int r = hmac->HmacDigest(&md_value, &md_len);
- if (md_len == 0 || r == 0) {
- return scope.Close(String::New(""));
+ if (r == 0) {
+ md_value = NULL;
+ md_len = 0;
}
- enum encoding enc = ParseEncoding(args[0], BINARY);
- if (enc == HEX) {
- // Hex encoding
- HexEncode(md_value, md_len, &md_hexdigest, &md_hex_len);
- outString = Encode(md_hexdigest, md_hex_len, BINARY);
- delete [] md_hexdigest;
- } else if (enc == BASE64) {
- base64(md_value, md_len, &md_hexdigest, &md_hex_len);
- outString = Encode(md_hexdigest, md_hex_len, BINARY);
- delete [] md_hexdigest;
- } else if (enc == BINARY) {
- outString = Encode(md_value, md_len, BINARY);
- } else {
- fprintf(stderr, "node-crypto : Hmac .digest encoding "
- "can be binary, hex or base64\n");
- }
+ outString = Encode(md_value, md_len, BUFFER);
+
delete [] md_value;
return scope.Close(outString);
}
@@ -3072,29 +2850,13 @@ class Hash : public ObjectWrap {
Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
- ASSERT_IS_STRING_OR_BUFFER(args[0]);
- enum encoding enc = ParseEncoding(args[1]);
- ssize_t len = DecodeBytes(args[0], enc);
-
- if (len < 0) {
- Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
- return ThrowException(exception);
- }
+ ASSERT_IS_BUFFER(args[0]);
int r;
- if (Buffer::HasInstance(args[0])) {
- Local<Object> buffer_obj = args[0]->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
- r = hash->HashUpdate(buffer_data, buffer_length);
- } else {
- char* buf = new char[len];
- ssize_t written = DecodeWrite(buf, len, args[0], enc);
- assert(written == len);
- r = hash->HashUpdate(buf, len);
- delete[] buf;
- }
+ char* buffer_data = Buffer::Data(args[0]);
+ size_t buffer_length = Buffer::Length(args[0]);
+ r = hash->HashUpdate(buffer_data, buffer_length);
if (!r) {
Local<Value> exception = Exception::TypeError(String::New("HashUpdate fail"));
@@ -3120,32 +2882,9 @@ class Hash : public ObjectWrap {
EVP_MD_CTX_cleanup(&hash->mdctx);
hash->initialised_ = false;
- if (md_len == 0) {
- return scope.Close(String::New(""));
- }
-
Local<Value> outString;
- enum encoding enc = ParseEncoding(args[0], BINARY);
- if (enc == HEX) {
- // Hex encoding
- char* md_hexdigest;
- int md_hex_len;
- HexEncode(md_value, md_len, &md_hexdigest, &md_hex_len);
- outString = Encode(md_hexdigest, md_hex_len, BINARY);
- delete [] md_hexdigest;
- } else if (enc == BASE64) {
- char* md_hexdigest;
- int md_hex_len;
- base64(md_value, md_len, &md_hexdigest, &md_hex_len);
- outString = Encode(md_hexdigest, md_hex_len, BINARY);
- delete [] md_hexdigest;
- } else if (enc == BINARY) {
- outString = Encode(md_value, md_len, BINARY);
- } else {
- fprintf(stderr, "node-crypto : Hash .digest encoding "
- "can be binary, hex or base64\n");
- }
+ outString = Encode(md_value, md_len, BUFFER);
return scope.Close(outString);
}
@@ -3263,30 +3002,14 @@ class Sign : public ObjectWrap {
HandleScope scope;
- ASSERT_IS_STRING_OR_BUFFER(args[0]);
- enum encoding enc = ParseEncoding(args[1]);
- ssize_t len = DecodeBytes(args[0], enc);
-
- if (len < 0) {
- Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
- return ThrowException(exception);
- }
+ ASSERT_IS_BUFFER(args[0]);
int r;
- if (Buffer::HasInstance(args[0])) {
- Local<Object> buffer_obj = args[0]->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(args[0]);
+ size_t buffer_length = Buffer::Length(args[0]);
- r = sign->SignUpdate(buffer_data, buffer_length);
- } else {
- char* buf = new char[len];
- ssize_t written = DecodeWrite(buf, len, args[0], enc);
- assert(written == len);
- r = sign->SignUpdate(buf, len);
- delete [] buf;
- }
+ r = sign->SignUpdate(buffer_data, buffer_length);
if (!r) {
Local<Value> exception = Exception::TypeError(String::New("SignUpdate fail"));
@@ -3303,52 +3026,27 @@ class Sign : public ObjectWrap {
unsigned char* md_value;
unsigned int md_len;
- char* md_hexdigest;
- int md_hex_len;
Local<Value> outString;
md_len = 8192; // Maximum key size is 8192 bits
md_value = new unsigned char[md_len];
- ASSERT_IS_STRING_OR_BUFFER(args[0]);
- ssize_t len = DecodeBytes(args[0], BINARY);
-
- if (len < 0) {
- delete [] md_value;
- Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
- return ThrowException(exception);
- }
+ ASSERT_IS_BUFFER(args[0]);
+ ssize_t len = Buffer::Length(args[0]);
char* buf = new char[len];
- ssize_t written = DecodeWrite(buf, len, args[0], BINARY);
+ ssize_t written = DecodeWrite(buf, len, args[0], BUFFER);
assert(written == len);
int r = sign->SignFinal(&md_value, &md_len, buf, len);
+ if (r == 0) {
+ md_value = NULL;
+ md_len = r;
+ }
delete [] buf;
- if (md_len == 0 || r == 0) {
- delete [] md_value;
- return scope.Close(String::New(""));
- }
-
- enum encoding enc = ParseEncoding(args[1], BINARY);
- if (enc == HEX) {
- // Hex encoding
- HexEncode(md_value, md_len, &md_hexdigest, &md_hex_len);
- outString = Encode(md_hexdigest, md_hex_len, BINARY);
- delete [] md_hexdigest;
- } else if (enc == BASE64) {
- base64(md_value, md_len, &md_hexdigest, &md_hex_len);
- outString = Encode(md_hexdigest, md_hex_len, BINARY);
- delete [] md_hexdigest;
- } else if (enc == BINARY) {
- outString = Encode(md_value, md_len, BINARY);
- } else {
- outString = String::New("");
- fprintf(stderr, "node-crypto : Sign .sign encoding "
- "can be binary, hex or base64\n");
- }
+ outString = Encode(md_value, md_len, BUFFER);
delete [] md_value;
return scope.Close(outString);
@@ -3515,30 +3213,14 @@ class Verify : public ObjectWrap {
Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
- ASSERT_IS_STRING_OR_BUFFER(args[0]);
- enum encoding enc = ParseEncoding(args[1]);
- ssize_t len = DecodeBytes(args[0], enc);
-
- if (len < 0) {
- Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
- return ThrowException(exception);
- }
+ ASSERT_IS_BUFFER(args[0]);
int r;
- if(Buffer::HasInstance(args[0])) {
- Local<Object> buffer_obj = args[0]->ToObject();
- char *buffer_data = Buffer::Data(buffer_obj);
- size_t buffer_length = Buffer::Length(buffer_obj);
+ char* buffer_data = Buffer::Data(args[0]);
+ size_t buffer_length = Buffer::Length(args[0]);
- r = verify->VerifyUpdate(buffer_data, buffer_length);
- } else {
- char* buf = new char[len];
- ssize_t written = DecodeWrite(buf, len, args[0], enc);
- assert(written == len);
- r = verify->VerifyUpdate(buf, len);
- delete [] buf;
- }
+ r = verify->VerifyUpdate(buffer_data, buffer_length);
if (!r) {
Local<Value> exception = Exception::TypeError(String::New("VerifyUpdate fail"));
@@ -3554,8 +3236,8 @@ class Verify : public ObjectWrap {
Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
- ASSERT_IS_STRING_OR_BUFFER(args[0]);
- ssize_t klen = DecodeBytes(args[0], BINARY);
+ ASSERT_IS_BUFFER(args[0]);
+ ssize_t klen = Buffer::Length(args[0]);
if (klen < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
@@ -3566,8 +3248,8 @@ class Verify : public ObjectWrap {
ssize_t kwritten = DecodeWrite(kbuf, klen, args[0], BINARY);
assert(kwritten == klen);
- ASSERT_IS_STRING_OR_BUFFER(args[1]);
- ssize_t hlen = DecodeBytes(args[1], BINARY);
+ ASSERT_IS_BUFFER(args[1]);
+ ssize_t hlen = Buffer::Length(args[1]);
if (hlen < 0) {
delete [] kbuf;
@@ -3576,30 +3258,12 @@ class Verify : public ObjectWrap {
}
unsigned char* hbuf = new unsigned char[hlen];
- ssize_t hwritten = DecodeWrite((char *)hbuf, hlen, args[1], BINARY);
+ ssize_t hwritten = DecodeWrite((char*)hbuf, hlen, args[1], BINARY);
assert(hwritten == hlen);
- unsigned char* dbuf;
- int dlen;
int r=-1;
- enum encoding enc = ParseEncoding(args[2], BINARY);
- if (enc == HEX) {
- // Hex encoding
- HexDecode(hbuf, hlen, (char **)&dbuf, &dlen);
- r = verify->VerifyFinal(kbuf, klen, dbuf, dlen);
- delete [] dbuf;
- } else if (enc == BASE64) {
- // Base64 encoding
- unbase64(hbuf, hlen, (char **)&dbuf, &dlen);
- r = verify->VerifyFinal(kbuf, klen, dbuf, dlen);
- delete [] dbuf;
- } else if (enc == BINARY) {
- r = verify->VerifyFinal(kbuf, klen, hbuf, hlen);
- } else {
- fprintf(stderr, "node-crypto : Verify .verify encoding "
- "can be binary, hex or base64\n");
- }
+ r = verify->VerifyFinal(kbuf, klen, hbuf, hlen);
delete [] kbuf;
delete [] hbuf;
@@ -3730,30 +3394,9 @@ class DiffieHellman : public ObjectWrap {
if (args[0]->IsInt32()) {
initialized = diffieHellman->Init(args[0]->Int32Value());
} else {
- if (args[0]->IsString()) {
- char* buf;
- int len;
- if (args.Length() > 1 && args[1]->IsString()) {
- len = DecodeWithEncoding(args[0], args[1], &buf);
- } else {
- len = DecodeBinary(args[0], &buf);
- }
-
- if (len == -1) {
- delete[] buf;
- return ThrowException(Exception::Error(
- String::New("Invalid argument")));
- } else {
- initialized = diffieHellman->Init(
- reinterpret_cast<unsigned char*>(buf), len);
- delete[] buf;
- }
- } else if (Buffer::HasInstance(args[0])) {
- Local<Object> buffer = args[0]->ToObject();
- initialized = diffieHellman->Init(
- reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
- Buffer::Length(buffer));
- }
+ initialized = diffieHellman->Init(
+ reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
+ Buffer::Length(args[0]));
}
}
@@ -3790,11 +3433,7 @@ class DiffieHellman : public ObjectWrap {
BN_bn2bin(diffieHellman->dh->pub_key,
reinterpret_cast<unsigned char*>(data));
- if (args.Length() > 0 && args[0]->IsString()) {
- outString = EncodeWithEncoding(args[0], data, dataSize);
- } else {
- outString = Encode(data, dataSize, BINARY);
- }
+ outString = Encode(data, dataSize, BUFFER);
delete[] data;
return scope.Close(outString);
@@ -3816,11 +3455,7 @@ class DiffieHellman : public ObjectWrap {
Local<Value> outString;
- if (args.Length() > 0 && args[0]->IsString()) {
- outString = EncodeWithEncoding(args[0], data, dataSize);
- } else {
- outString = Encode(data, dataSize, BINARY);
- }
+ outString = Encode(data, dataSize, BUFFER);
delete[] data;
@@ -3843,11 +3478,7 @@ class DiffieHellman : public ObjectWrap {
Local<Value> outString;
- if (args.Length() > 0 && args[0]->IsString()) {
- outString = EncodeWithEncoding(args[0], data, dataSize);
- } else {
- outString = Encode(data, dataSize, BINARY);
- }
+ outString = Encode(data, dataSize, BUFFER);
delete[] data;
@@ -3876,11 +3507,7 @@ class DiffieHellman : public ObjectWrap {
Local<Value> outString;
- if (args.Length() > 0 && args[0]->IsString()) {
- outString = EncodeWithEncoding(args[0], data, dataSize);
- } else {
- outString = Encode(data, dataSize, BINARY);
- }
+ outString = Encode(data, dataSize, BUFFER);
delete[] data;
@@ -3909,11 +3536,7 @@ class DiffieHellman : public ObjectWrap {
Local<Value> outString;
- if (args.Length() > 0 && args[0]->IsString()) {
- outString = EncodeWithEncoding(args[0], data, dataSize);
- } else {
- outString = Encode(data, dataSize, BINARY);
- }
+ outString = Encode(data, dataSize, BUFFER);
delete[] data;
@@ -3936,30 +3559,10 @@ class DiffieHellman : public ObjectWrap {
return ThrowException(Exception::Error(
String::New("First argument must be other party's public key")));
} else {
- if (args[0]->IsString()) {
- char* buf;
- int len;
- if (args.Length() > 1) {
- len = DecodeWithEncoding(args[0], args[1], &buf);
- } else {
- len = DecodeBinary(args[0], &buf);
- }
- if (len == -1) {
- delete[] buf;
- return ThrowException(Exception::Error(
- String::New("Invalid argument")));
- }
- key = BN_bin2bn(reinterpret_cast<unsigned char*>(buf), len, 0);
- delete[] buf;
- } else if (Buffer::HasInstance(args[0])) {
- Local<Object> buffer = args[0]->ToObject();
- key = BN_bin2bn(
- reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
- Buffer::Length(buffer), 0);
- } else {
- return ThrowException(Exception::Error(
- String::New("First argument must be other party's public key")));
- }
+ ASSERT_IS_BUFFER(args[0]);
+ key = BN_bin2bn(
+ reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
+ Buffer::Length(args[0]), 0);
}
int dataSize = DH_size(diffieHellman->dh);
@@ -4007,13 +3610,7 @@ class DiffieHellman : public ObjectWrap {
Local<Value> outString;
- if (args.Length() > 2 && args[2]->IsString()) {
- outString = EncodeWithEncoding(args[2], data, dataSize);
- } else if (args.Length() > 1 && args[1]->IsString()) {
- outString = EncodeWithEncoding(args[1], data, dataSize);
- } else {
- outString = Encode(data, dataSize, BINARY);
- }
+ outString = Encode(data, dataSize, BUFFER);
delete[] data;
return scope.Close(outString);
@@ -4033,32 +3630,11 @@ class DiffieHellman : public ObjectWrap {
return ThrowException(Exception::Error(
String::New("First argument must be public key")));
} else {
- if (args[0]->IsString()) {
- char* buf;
- int len;
- if (args.Length() > 1) {
- len = DecodeWithEncoding(args[0], args[1], &buf);
- } else {
- len = DecodeBinary(args[0], &buf);
- }
- if (len == -1) {
- delete[] buf;
- return ThrowException(Exception::Error(
- String::New("Invalid argument")));
- }
- diffieHellman->dh->pub_key =
- BN_bin2bn(reinterpret_cast<unsigned char*>(buf), len, 0);
- delete[] buf;
- } else if (Buffer::HasInstance(args[0])) {
- Local<Object> buffer = args[0]->ToObject();
- diffieHellman->dh->pub_key =
- BN_bin2bn(
- reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
- Buffer::Length(buffer), 0);
- } else {
- return ThrowException(Exception::Error(
- String::New("First argument must be public key")));
- }
+ ASSERT_IS_BUFFER(args[0]);
+ diffieHellman->dh->pub_key =
+ BN_bin2bn(
+ reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
+ Buffer::Length(args[0]), 0);
}
return args.This();
@@ -4079,32 +3655,11 @@ class DiffieHellman : public ObjectWrap {
return ThrowException(Exception::Error(
String::New("First argument must be private key")));
} else {
- if (args[0]->IsString()) {
- char* buf;
- int len;
- if (args.Length() > 1) {
- len = DecodeWithEncoding(args[0], args[1], &buf);
- } else {
- len = DecodeBinary(args[0], &buf);
- }
- if (len == -1) {
- delete[] buf;
- return ThrowException(Exception::Error(
- String::New("Invalid argument")));
- }
- diffieHellman->dh->priv_key =
- BN_bin2bn(reinterpret_cast<unsigned char*>(buf), len, 0);
- delete[] buf;
- } else if (Buffer::HasInstance(args[0])) {
- Local<Object> buffer = args[0]->ToObject();
- diffieHellman->dh->priv_key =
- BN_bin2bn(
- reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
- Buffer::Length(buffer), 0);
- } else {
- return ThrowException(Exception::Error(
- String::New("First argument must be private key")));
- }
+ ASSERT_IS_BUFFER(args[0]);
+ diffieHellman->dh->priv_key =
+ BN_bin2bn(
+ reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
+ Buffer::Length(args[0]), 0);
}
return args.This();
@@ -4132,81 +3687,13 @@ class DiffieHellman : public ObjectWrap {
return true;
}
- static int DecodeBinary(Handle<Value> str, char** buf) {
- int len = DecodeBytes(str);
- *buf = new char[len];
- int written = DecodeWrite(*buf, len, str, BINARY);
- if (written != len) {
- return -1;
- }
- return len;
- }
-
- static int DecodeWithEncoding(Handle<Value> str, Handle<Value> encoding_v,
- char** buf) {
- int len = DecodeBinary(str, buf);
- if (len == -1) {
- return len;
- }
- enum encoding enc = ParseEncoding(encoding_v, (enum encoding) -1);
- char* retbuf = 0;
- int retlen;
-
- if (enc == HEX) {
- HexDecode((unsigned char*)*buf, len, &retbuf, &retlen);
-
- } else if (enc == BASE64) {
- unbase64((unsigned char*)*buf, len, &retbuf, &retlen);
-
- } else if (enc == BINARY) {
- // Binary - do nothing
- } else {
- fprintf(stderr, "node-crypto : Diffie-Hellman parameter encoding "
- "can be binary, hex or base64\n");
- }
-
- if (retbuf != 0) {
- delete [] *buf;
- *buf = retbuf;
- len = retlen;
- }
-
- return len;
- }
-
- static Local<Value> EncodeWithEncoding(Handle<Value> encoding_v, char* buf,
- int len) {
- HandleScope scope;
-
- Local<Value> outString;
- enum encoding enc = ParseEncoding(encoding_v, (enum encoding) -1);
- char* retbuf;
- int retlen;
-
- if (enc == HEX) {
- // Hex encoding
- HexEncode(reinterpret_cast<unsigned char*>(buf), len, &retbuf, &retlen);
- outString = Encode(retbuf, retlen, BINARY);
- delete [] retbuf;
- } else if (enc == BASE64) {
- base64(reinterpret_cast<unsigned char*>(buf), len, &retbuf, &retlen);
- outString = Encode(retbuf, retlen, BINARY);
- delete [] retbuf;
- } else if (enc == BINARY) {
- outString = Encode(buf, len, BINARY);
- } else {
- fprintf(stderr, "node-crypto : Diffie-Hellman parameter encoding "
- "can be binary, hex or base64\n");
- }
-
- return scope.Close(outString);
- }
-
bool initialised_;
DH* dh;
};
+
struct pbkdf2_req {
+ uv_work_t work_req;
int err;
char* pass;
size_t passlen;
@@ -4218,75 +3705,77 @@ struct pbkdf2_req {
Persistent<Object> obj;
};
-void
-EIO_PBKDF2(uv_work_t* req) {
- pbkdf2_req* request = (pbkdf2_req*)req->data;
- request->err = PKCS5_PBKDF2_HMAC_SHA1(
- request->pass,
- request->passlen,
- (unsigned char*)request->salt,
- request->saltlen,
- request->iter,
- request->keylen,
- (unsigned char*)request->key);
- memset(request->pass, 0, request->passlen);
- memset(request->salt, 0, request->saltlen);
+
+void EIO_PBKDF2(pbkdf2_req* req) {
+ req->err = PKCS5_PBKDF2_HMAC_SHA1(
+ req->pass,
+ req->passlen,
+ (unsigned char*)req->salt,
+ req->saltlen,
+ req->iter,
+ req->keylen,
+ (unsigned char*)req->key);
+ memset(req->pass, 0, req->passlen);
+ memset(req->salt, 0, req->saltlen);
}
-void
-EIO_PBKDF2After(uv_work_t* req) {
- HandleScope scope;
- pbkdf2_req* request = (pbkdf2_req*)req->data;
- delete req;
+void EIO_PBKDF2(uv_work_t* work_req) {
+ pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
+ EIO_PBKDF2(req);
+}
- Local<Value> argv[2];
- if (request->err) {
+
+void EIO_PBKDF2After(pbkdf2_req* req, Local<Value> argv[2]) {
+ if (req->err) {
argv[0] = Local<Value>::New(Undefined());
- argv[1] = Encode(request->key, request->keylen, BINARY);
- memset(request->key, 0, request->keylen);
+ argv[1] = Encode(req->key, req->keylen, BUFFER);
+ memset(req->key, 0, req->keylen);
} else {
argv[0] = Exception::Error(String::New("PBKDF2 error"));
argv[1] = Local<Value>::New(Undefined());
}
- MakeCallback(request->obj, "ondone", ARRAY_SIZE(argv), argv);
+ delete[] req->pass;
+ delete[] req->salt;
+ delete[] req->key;
+ delete req;
+}
- delete[] request->pass;
- delete[] request->salt;
- delete[] request->key;
- request->obj.Dispose();
- request->obj.Clear();
- delete request;
+void EIO_PBKDF2After(uv_work_t* work_req, int status) {
+ assert(status == 0);
+ pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
+ HandleScope scope;
+ Local<Value> argv[2];
+ Persistent<Object> obj = req->obj;
+ EIO_PBKDF2After(req, argv);
+ MakeCallback(obj, "ondone", ARRAY_SIZE(argv), argv);
+ obj.Dispose();
}
-Handle<Value>
-PBKDF2(const Arguments& args) {
+
+Handle<Value> PBKDF2(const Arguments& args) {
HandleScope scope;
const char* type_error = NULL;
char* pass = NULL;
char* salt = NULL;
- char* key = NULL;
ssize_t passlen = -1;
ssize_t saltlen = -1;
ssize_t keylen = -1;
ssize_t pass_written = -1;
ssize_t salt_written = -1;
ssize_t iter = -1;
- Local<Function> callback;
- pbkdf2_req* request = NULL;
- uv_work_t* req = NULL;
- Persistent<Object> obj;
+ pbkdf2_req* req = NULL;
- if (args.Length() != 5) {
+ if (args.Length() != 4 && args.Length() != 5) {
type_error = "Bad parameter";
goto err;
}
- ASSERT_IS_STRING_OR_BUFFER(args[0]);
- passlen = DecodeBytes(args[0], BINARY);
+ ASSERT_IS_BUFFER(args[0]);
+ passlen = Buffer::Length(args[0]);
if (passlen < 0) {
type_error = "Bad password";
goto err;
@@ -4296,8 +3785,8 @@ PBKDF2(const Arguments& args) {
pass_written = DecodeWrite(pass, passlen, args[0], BINARY);
assert(pass_written == passlen);
- ASSERT_IS_STRING_OR_BUFFER(args[1]);
- saltlen = DecodeBytes(args[1], BINARY);
+ ASSERT_IS_BUFFER(args[1]);
+ saltlen = Buffer::Length(args[1]);
if (saltlen < 0) {
type_error = "Bad salt";
goto err;
@@ -4329,34 +3818,33 @@ PBKDF2(const Arguments& args) {
goto err;
}
- key = new char[keylen];
+ req = new pbkdf2_req;
+ req->err = 0;
+ req->pass = pass;
+ req->passlen = passlen;
+ req->salt = salt;
+ req->saltlen = saltlen;
+ req->iter = iter;
+ req->key = new char[keylen];
+ req->keylen = keylen;
- if (!args[4]->IsFunction()) {
- type_error = "Callback not a function";
- goto err;
+ if (args[4]->IsFunction()) {
+ req->obj = Persistent<Object>::New(Object::New());
+ req->obj->Set(String::New("ondone"), args[4]);
+ uv_queue_work(uv_default_loop(),
+ &req->work_req,
+ EIO_PBKDF2,
+ EIO_PBKDF2After);
+ return Undefined();
+ } else {
+ Local<Value> argv[2];
+ EIO_PBKDF2(req);
+ EIO_PBKDF2After(req, argv);
+ if (argv[0]->IsObject()) return ThrowException(argv[0]);
+ return scope.Close(argv[1]);
}
- obj = Persistent<Object>::New(Object::New());
- obj->Set(String::New("ondone"), args[4]);
-
- request = new pbkdf2_req;
- request->err = 0;
- request->pass = pass;
- request->passlen = passlen;
- request->salt = salt;
- request->saltlen = saltlen;
- request->iter = iter;
- request->key = key;
- request->keylen = keylen;
- request->obj = obj;
-
- req = new uv_work_t();
- req->data = request;
- uv_queue_work(uv_default_loop(), req, EIO_PBKDF2, EIO_PBKDF2After);
- return Undefined();
-
err:
- delete[] key;
delete[] salt;
delete[] pass;
return ThrowException(Exception::TypeError(String::New(type_error)));
@@ -4429,16 +3917,15 @@ void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
}
-void RandomBytesAfter(uv_work_t* work_req) {
+void RandomBytesAfter(uv_work_t* work_req, int status) {
+ assert(status == 0);
RandomBytesRequest* req = container_of(work_req,
RandomBytesRequest,
work_req_);
-
HandleScope scope;
Local<Value> argv[2];
RandomBytesCheck(req, argv);
MakeCallback(req->obj_, "ondone", ARRAY_SIZE(argv), argv);
-
delete req;
}
@@ -4486,6 +3973,52 @@ Handle<Value> RandomBytes(const Arguments& args) {
}
+Handle<Value> GetCiphers(const Arguments& args) {
+ HandleScope scope;
+
+ SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
+ if (ctx == NULL) {
+ return ThrowError("SSL_CTX_new() failed.");
+ }
+
+ SSL* ssl = SSL_new(ctx);
+ if (ssl == NULL) {
+ SSL_CTX_free(ctx);
+ return ThrowError("SSL_new() failed.");
+ }
+
+ Local<Array> arr = Array::New();
+ STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl);
+
+ for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
+ SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
+ arr->Set(i, String::New(SSL_CIPHER_get_name(cipher)));
+ }
+
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+
+ return scope.Close(arr);
+}
+
+
+static void add_hash_to_array(const EVP_MD* md,
+ const char* from,
+ const char* to,
+ void* arg) {
+ Local<Array>& arr = *static_cast<Local<Array>*>(arg);
+ arr->Set(arr->Length(), String::New(from));
+}
+
+
+Handle<Value> GetHashes(const Arguments& args) {
+ HandleScope scope;
+ Local<Array> arr = Array::New();
+ EVP_MD_do_all_sorted(add_hash_to_array, &arr);
+ return scope.Close(arr);
+}
+
+
void InitCrypto(Handle<Object> target) {
HandleScope scope;
@@ -4497,7 +4030,7 @@ void InitCrypto(Handle<Object> target) {
crypto_lock_init();
CRYPTO_set_locking_callback(crypto_lock_cb);
- CRYPTO_set_id_callback(crypto_id_cb);
+ CRYPTO_THREADID_set_callback(crypto_threadid_cb);
// Turn off compression. Saves memory - do it in userland.
#if !defined(OPENSSL_NO_COMP)
@@ -4525,6 +4058,8 @@ void InitCrypto(Handle<Object> target) {
NODE_SET_METHOD(target, "PBKDF2", PBKDF2);
NODE_SET_METHOD(target, "randomBytes", RandomBytes<false>);
NODE_SET_METHOD(target, "pseudoRandomBytes", RandomBytes<true>);
+ NODE_SET_METHOD(target, "getCiphers", GetCiphers);
+ NODE_SET_METHOD(target, "getHashes", GetHashes);
subject_symbol = NODE_PSYMBOL("subject");
issuer_symbol = NODE_PSYMBOL("issuer");
diff --git a/src/node_crypto.h b/src/node_crypto.h
index fe433596a..ee3cf93ba 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -49,6 +49,9 @@ namespace crypto {
static X509_STORE* root_cert_store;
+// Forward declaration
+class Connection;
+
class SecureContext : ObjectWrap {
public:
static void Initialize(v8::Handle<v8::Object> target);
@@ -58,6 +61,8 @@ class SecureContext : ObjectWrap {
X509_STORE *ca_store_;
protected:
+ static const int kMaxSessionSize = 10 * 1024;
+
static v8::Handle<v8::Value> New(const v8::Arguments& args);
static v8::Handle<v8::Value> Init(const v8::Arguments& args);
static v8::Handle<v8::Value> SetKey(const v8::Arguments& args);
@@ -71,6 +76,12 @@ class SecureContext : ObjectWrap {
static v8::Handle<v8::Value> Close(const v8::Arguments& args);
static v8::Handle<v8::Value> LoadPKCS12(const v8::Arguments& args);
+ static SSL_SESSION* GetSessionCallback(SSL* s,
+ unsigned char* key,
+ int len,
+ int* copy);
+ static int NewSessionCallback(SSL* s, SSL_SESSION* sess);
+
SecureContext() : ObjectWrap() {
ctx_ = NULL;
ca_store_ = NULL;
@@ -100,6 +111,51 @@ class SecureContext : ObjectWrap {
private:
};
+class ClientHelloParser {
+ public:
+ enum FrameType {
+ kChangeCipherSpec = 20,
+ kAlert = 21,
+ kHandshake = 22,
+ kApplicationData = 23,
+ kOther = 255
+ };
+
+ enum HandshakeType {
+ kClientHello = 1
+ };
+
+ enum ParseState {
+ kWaiting,
+ kTLSHeader,
+ kSSLHeader,
+ kPaused,
+ kEnded
+ };
+
+ ClientHelloParser(Connection* c) : conn_(c),
+ state_(kWaiting),
+ offset_(0),
+ body_offset_(0),
+ written_(0) {
+ }
+
+ size_t Write(const uint8_t* data, size_t len);
+ void Finish();
+
+ inline bool ended() { return state_ == kEnded; }
+
+ private:
+ Connection* conn_;
+ ParseState state_;
+ size_t frame_len_;
+
+ uint8_t data_[18432];
+ size_t offset_;
+ size_t body_offset_;
+ size_t written_;
+};
+
class Connection : ObjectWrap {
public:
static void Initialize(v8::Handle<v8::Object> target);
@@ -126,6 +182,7 @@ class Connection : ObjectWrap {
static v8::Handle<v8::Value> GetPeerCertificate(const v8::Arguments& args);
static v8::Handle<v8::Value> GetSession(const v8::Arguments& args);
static v8::Handle<v8::Value> SetSession(const v8::Arguments& args);
+ static v8::Handle<v8::Value> LoadSession(const v8::Arguments& args);
static v8::Handle<v8::Value> IsSessionReused(const v8::Arguments& args);
static v8::Handle<v8::Value> IsInitFinished(const v8::Arguments& args);
static v8::Handle<v8::Value> VerifyError(const v8::Arguments& args);
@@ -157,7 +214,13 @@ class Connection : ObjectWrap {
#endif
int HandleBIOError(BIO *bio, const char* func, int rv);
- int HandleSSLError(const char* func, int rv);
+
+ enum ZeroStatus {
+ kZeroIsNotAnError,
+ kZeroIsAnError
+ };
+
+ int HandleSSLError(const char* func, int rv, ZeroStatus zs);
void ClearError();
void SetShutdownFlags();
@@ -168,9 +231,10 @@ class Connection : ObjectWrap {
return ss;
}
- Connection() : ObjectWrap() {
+ Connection() : ObjectWrap(), hello_parser_(this) {
bio_read_ = bio_write_ = NULL;
ssl_ = NULL;
+ next_sess_ = NULL;
}
~Connection() {
@@ -179,6 +243,11 @@ class Connection : ObjectWrap {
ssl_ = NULL;
}
+ if (next_sess_ != NULL) {
+ SSL_SESSION_free(next_sess_);
+ next_sess_ = NULL;
+ }
+
#ifdef OPENSSL_NPN_NEGOTIATED
if (!npnProtos_.IsEmpty()) npnProtos_.Dispose();
if (!selectedNPNProto_.IsEmpty()) selectedNPNProto_.Dispose();
@@ -198,7 +267,13 @@ class Connection : ObjectWrap {
BIO *bio_write_;
SSL *ssl_;
+ ClientHelloParser hello_parser_;
+
bool is_server_; /* coverity[member_decl] */
+ SSL_SESSION* next_sess_;
+
+ friend class ClientHelloParser;
+ friend class SecureContext;
};
void InitCrypto(v8::Handle<v8::Object> target);
diff --git a/src/node_dtrace.cc b/src/node_dtrace.cc
index e560999c5..df42af2a9 100644
--- a/src/node_dtrace.cc
+++ b/src/node_dtrace.cc
@@ -19,14 +19,23 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-#include "node_dtrace.h"
-#include <string.h>
#ifdef HAVE_DTRACE
+#include "node_dtrace.h"
+#include <string.h>
#include "node_provider.h"
#elif HAVE_ETW
+#include "node_dtrace.h"
+#include <string.h>
#include "node_win32_etw_provider.h"
#include "node_win32_etw_provider-inl.h"
+#elif HAVE_SYSTEMTAP
+#include <string.h>
+#include <node.h>
+#include <v8.h>
+#include <sys/sdt.h>
+#include "node_systemtap.h"
+#include "node_dtrace.h"
#else
#define NODE_HTTP_SERVER_REQUEST(arg0, arg1)
#define NODE_HTTP_SERVER_REQUEST_ENABLED() (0)
@@ -118,67 +127,86 @@ using namespace v8;
Handle<Value> DTRACE_NET_SERVER_CONNECTION(const Arguments& args) {
+#ifndef HAVE_SYSTEMTAP
if (!NODE_NET_SERVER_CONNECTION_ENABLED())
return Undefined();
+#endif
HandleScope scope;
SLURP_CONNECTION(args[0], conn);
+#ifdef HAVE_SYSTEMTAP
+ NODE_NET_SERVER_CONNECTION(conn.fd, conn.remote, conn.port, \
+ conn.buffered);
+#else
NODE_NET_SERVER_CONNECTION(&conn);
+#endif
return Undefined();
}
Handle<Value> DTRACE_NET_STREAM_END(const Arguments& args) {
+#ifndef HAVE_SYSTEMTAP
if (!NODE_NET_STREAM_END_ENABLED())
return Undefined();
+#endif
HandleScope scope;
SLURP_CONNECTION(args[0], conn);
+#ifdef HAVE_SYSTEMTAP
+ NODE_NET_STREAM_END(conn.fd, conn.remote, conn.port, conn.buffered);
+#else
NODE_NET_STREAM_END(&conn);
+#endif
return Undefined();
}
Handle<Value> DTRACE_NET_SOCKET_READ(const Arguments& args) {
+#ifndef HAVE_SYSTEMTAP
if (!NODE_NET_SOCKET_READ_ENABLED())
return Undefined();
+#endif
HandleScope scope;
- int nbytes;
SLURP_CONNECTION(args[0], conn);
+#ifdef HAVE_SYSTEMTAP
+ NODE_NET_SOCKET_READ(conn.fd, conn.remote, conn.port, conn.buffered);
+#else
if (!args[1]->IsNumber()) {
return (ThrowException(Exception::Error(String::New("expected "
"argument 1 to be number of bytes"))));
}
-
- nbytes = args[1]->Int32Value();
-
+ int nbytes = args[1]->Int32Value();
NODE_NET_SOCKET_READ(&conn, nbytes);
+#endif
return Undefined();
}
Handle<Value> DTRACE_NET_SOCKET_WRITE(const Arguments& args) {
+#ifndef HAVE_SYSTEMTAP
if (!NODE_NET_SOCKET_WRITE_ENABLED())
return Undefined();
+#endif
HandleScope scope;
- int nbytes;
SLURP_CONNECTION(args[0], conn);
+#ifdef HAVE_SYSTEMTAP
+ NODE_NET_SOCKET_WRITE(conn.fd, conn.remote, conn.port, conn.buffered);
+#else
if (!args[1]->IsNumber()) {
return (ThrowException(Exception::Error(String::New("expected "
"argument 1 to be number of bytes"))));
}
-
- nbytes = args[1]->Int32Value();
-
+ int nbytes = args[1]->Int32Value();
NODE_NET_SOCKET_WRITE(&conn, nbytes);
+#endif
return Undefined();
}
@@ -186,8 +214,10 @@ Handle<Value> DTRACE_NET_SOCKET_WRITE(const Arguments& args) {
Handle<Value> DTRACE_HTTP_SERVER_REQUEST(const Arguments& args) {
node_dtrace_http_server_request_t req;
+#ifndef HAVE_SYSTEMTAP
if (!NODE_HTTP_SERVER_REQUEST_ENABLED())
return Undefined();
+#endif
HandleScope scope;
@@ -213,18 +243,29 @@ Handle<Value> DTRACE_HTTP_SERVER_REQUEST(const Arguments& args) {
SLURP_CONNECTION(args[1], conn);
+#ifdef HAVE_SYSTEMTAP
+ NODE_HTTP_SERVER_REQUEST(&req, conn.fd, conn.remote, conn.port, \
+ conn.buffered);
+#else
NODE_HTTP_SERVER_REQUEST(&req, &conn);
+#endif
return Undefined();
}
Handle<Value> DTRACE_HTTP_SERVER_RESPONSE(const Arguments& args) {
+#ifndef HAVE_SYSTEMTAP
if (!NODE_HTTP_SERVER_RESPONSE_ENABLED())
return Undefined();
+#endif
HandleScope scope;
SLURP_CONNECTION(args[0], conn);
+#ifdef HAVE_SYSTEMTAP
+ NODE_HTTP_SERVER_RESPONSE(conn.fd, conn.remote, conn.port, conn.buffered);
+#else
NODE_HTTP_SERVER_RESPONSE(&conn);
+#endif
return Undefined();
}
@@ -233,8 +274,10 @@ Handle<Value> DTRACE_HTTP_CLIENT_REQUEST(const Arguments& args) {
node_dtrace_http_client_request_t req;
char *header;
+#ifndef HAVE_SYSTEMTAP
if (!NODE_HTTP_CLIENT_REQUEST_ENABLED())
return Undefined();
+#endif
HandleScope scope;
@@ -263,26 +306,40 @@ Handle<Value> DTRACE_HTTP_CLIENT_REQUEST(const Arguments& args) {
*header = '\0';
SLURP_CONNECTION_HTTP_CLIENT(args[1], conn);
+#ifdef HAVE_SYSTEMTAP
+ NODE_HTTP_CLIENT_REQUEST(&req, conn.fd, conn.remote, conn.port, \
+ conn.buffered);
+#else
NODE_HTTP_CLIENT_REQUEST(&req, &conn);
+#endif
return Undefined();
}
Handle<Value> DTRACE_HTTP_CLIENT_RESPONSE(const Arguments& args) {
+#ifndef HAVE_SYSTEMTAP
if (!NODE_HTTP_CLIENT_RESPONSE_ENABLED())
return Undefined();
-
+#endif
HandleScope scope;
SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(args[0], args[1], conn);
+#ifdef HAVE_SYSTEMTAP
+ NODE_HTTP_CLIENT_RESPONSE(conn.fd, conn.remote, conn.port, conn.buffered);
+#else
NODE_HTTP_CLIENT_RESPONSE(&conn);
+#endif
return Undefined();
}
-#define NODE_PROBE(name) #name, name
+#define NODE_PROBE(name) #name, name, Persistent<FunctionTemplate>()
static int dtrace_gc_start(GCType type, GCCallbackFlags flags) {
+#ifdef HAVE_SYSTEMTAP
+ NODE_GC_START();
+#else
NODE_GC_START(type, flags);
+#endif
/*
* We avoid the tail-call elimination of the USDT probe (which screws up
* args) by forcing a return of 0.
@@ -291,7 +348,11 @@ static int dtrace_gc_start(GCType type, GCCallbackFlags flags) {
}
static int dtrace_gc_done(GCType type, GCCallbackFlags flags) {
+#ifdef HAVE_SYSTEMTAP
+ NODE_GC_DONE();
+#else
NODE_GC_DONE(type, flags);
+#endif
return 0;
}
@@ -308,11 +369,10 @@ void InitDTrace(Handle<Object> target) {
{ NODE_PROBE(DTRACE_HTTP_SERVER_REQUEST) },
{ NODE_PROBE(DTRACE_HTTP_SERVER_RESPONSE) },
{ NODE_PROBE(DTRACE_HTTP_CLIENT_REQUEST) },
- { NODE_PROBE(DTRACE_HTTP_CLIENT_RESPONSE) },
- { NULL }
+ { NODE_PROBE(DTRACE_HTTP_CLIENT_RESPONSE) }
};
- for (int i = 0; tab[i].name != NULL; i++) {
+ for (unsigned int i = 0; i < ARRAY_SIZE(tab); i++) {
tab[i].templ = Persistent<FunctionTemplate>::New(
FunctionTemplate::New(tab[i].func));
target->Set(String::NewSymbol(tab[i].name), tab[i].templ->GetFunction());
@@ -322,7 +382,7 @@ void InitDTrace(Handle<Object> target) {
init_etw();
#endif
-#if defined HAVE_DTRACE || defined HAVE_ETW
+#if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP
v8::V8::AddGCPrologueCallback((GCPrologueCallback)dtrace_gc_start);
v8::V8::AddGCEpilogueCallback((GCEpilogueCallback)dtrace_gc_done);
#endif
diff --git a/src/node_extensions.h b/src/node_extensions.h
index 7a7702c9f..4238f8c52 100644
--- a/src/node_extensions.h
+++ b/src/node_extensions.h
@@ -22,16 +22,12 @@
NODE_EXT_LIST_START
NODE_EXT_LIST_ITEM(node_buffer)
-NODE_EXT_LIST_ITEM(node_typed_array)
#if HAVE_OPENSSL
NODE_EXT_LIST_ITEM(node_crypto)
#endif
NODE_EXT_LIST_ITEM(node_evals)
NODE_EXT_LIST_ITEM(node_fs)
NODE_EXT_LIST_ITEM(node_http_parser)
-#ifdef __POSIX__
-NODE_EXT_LIST_ITEM(node_signal_watcher)
-#endif
NODE_EXT_LIST_ITEM(node_os)
NODE_EXT_LIST_ITEM(node_zlib)
@@ -44,6 +40,7 @@ NODE_EXT_LIST_ITEM(node_cares_wrap)
NODE_EXT_LIST_ITEM(node_tty_wrap)
NODE_EXT_LIST_ITEM(node_process_wrap)
NODE_EXT_LIST_ITEM(node_fs_event_wrap)
+NODE_EXT_LIST_ITEM(node_signal_wrap)
NODE_EXT_LIST_END
diff --git a/src/node_file.cc b/src/node_file.cc
index 59ff414c6..9e4396126 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -144,8 +144,6 @@ static void After(uv_fs_t *req) {
break;
case UV_FS_OPEN:
- /* pass thru */
- case UV_FS_SENDFILE:
argv[1] = Integer::New(req->result);
break;
@@ -499,7 +497,7 @@ static Handle<Value> Rename(const Arguments& args) {
}
}
-static Handle<Value> Truncate(const Arguments& args) {
+static Handle<Value> FTruncate(const Arguments& args) {
HandleScope scope;
if (args.Length() < 2 || !args[0]->IsInt32()) {
@@ -603,30 +601,6 @@ static Handle<Value> MKDir(const Arguments& args) {
}
}
-static Handle<Value> SendFile(const Arguments& args) {
- HandleScope scope;
-
- if (args.Length() < 4 ||
- !args[0]->IsUint32() ||
- !args[1]->IsUint32() ||
- !args[2]->IsUint32() ||
- !args[3]->IsUint32()) {
- return THROW_BAD_ARGS;
- }
-
- int out_fd = args[0]->Uint32Value();
- int in_fd = args[1]->Uint32Value();
- off_t in_offset = args[2]->Uint32Value();
- size_t length = args[3]->Uint32Value();
-
- if (args[4]->IsFunction()) {
- ASYNC_CALL(sendfile, args[4], out_fd, in_fd, in_offset, length)
- } else {
- SYNC_CALL(sendfile, 0, out_fd, in_fd, in_offset, length)
- return scope.Close(Integer::New(SYNC_RESULT));
- }
-}
-
static Handle<Value> ReadDir(const Arguments& args) {
HandleScope scope;
@@ -954,10 +928,9 @@ void File::Initialize(Handle<Object> target) {
NODE_SET_METHOD(target, "fdatasync", Fdatasync);
NODE_SET_METHOD(target, "fsync", Fsync);
NODE_SET_METHOD(target, "rename", Rename);
- NODE_SET_METHOD(target, "truncate", Truncate);
+ NODE_SET_METHOD(target, "ftruncate", FTruncate);
NODE_SET_METHOD(target, "rmdir", RMDir);
NODE_SET_METHOD(target, "mkdir", MKDir);
- NODE_SET_METHOD(target, "sendfile", SendFile);
NODE_SET_METHOD(target, "readdir", ReadDir);
NODE_SET_METHOD(target, "stat", Stat);
NODE_SET_METHOD(target, "lstat", LStat);
diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc
index b29afe256..493f1e065 100644
--- a/src/node_http_parser.cc
+++ b/src/node_http_parser.cc
@@ -81,19 +81,19 @@ static char* current_buffer_data;
static size_t current_buffer_len;
-#define HTTP_CB(name) \
- static int name(http_parser* p_) { \
- Parser* self = container_of(p_, Parser, parser_); \
- return self->name##_(); \
- } \
- int name##_()
-
-
-#define HTTP_DATA_CB(name) \
- static int name(http_parser* p_, const char* at, size_t length) { \
- Parser* self = container_of(p_, Parser, parser_); \
- return self->name##_(at, length); \
- } \
+#define HTTP_CB(name) \
+ static int name(http_parser* p_) { \
+ Parser* self = container_of(p_, Parser, parser_); \
+ return self->name##_(); \
+ } \
+ int name##_()
+
+
+#define HTTP_DATA_CB(name) \
+ static int name(http_parser* p_, const char* at, size_t length) { \
+ Parser* self = container_of(p_, Parser, parser_); \
+ return self->name##_(at, length); \
+ } \
int name##_(const char* at, size_t length)
@@ -269,17 +269,23 @@ public:
// STATUS
if (parser_.type == HTTP_RESPONSE) {
- message_info->Set(status_code_sym, Integer::New(parser_.status_code));
+ message_info->Set(status_code_sym,
+ Integer::New(parser_.status_code));
}
// VERSION
- message_info->Set(version_major_sym, Integer::New(parser_.http_major));
- message_info->Set(version_minor_sym, Integer::New(parser_.http_minor));
+ message_info->Set(version_major_sym,
+ Integer::New(parser_.http_major));
+ message_info->Set(version_minor_sym,
+ Integer::New(parser_.http_minor));
message_info->Set(should_keep_alive_sym,
- http_should_keep_alive(&parser_) ? True() : False());
+ http_should_keep_alive(&parser_) ? True()
+ : False());
- message_info->Set(upgrade_sym, parser_.upgrade ? True() : False());
+ message_info->Set(upgrade_sym,
+ parser_.upgrade ? True()
+ : False());
Local<Value> argv[1] = { message_info };
@@ -558,8 +564,12 @@ void InitHttpParser(Handle<Object> target) {
t->SetClassName(String::NewSymbol("HTTPParser"));
PropertyAttribute attrib = (PropertyAttribute) (ReadOnly | DontDelete);
- t->Set(String::NewSymbol("REQUEST"), Integer::New(HTTP_REQUEST), attrib);
- t->Set(String::NewSymbol("RESPONSE"), Integer::New(HTTP_RESPONSE), attrib);
+ t->Set(String::NewSymbol("REQUEST"),
+ Integer::New(HTTP_REQUEST),
+ attrib);
+ t->Set(String::NewSymbol("RESPONSE"),
+ Integer::New(HTTP_RESPONSE),
+ attrib);
NODE_SET_PROTOTYPE_METHOD(t, "execute", Parser::Execute);
NODE_SET_PROTOTYPE_METHOD(t, "finish", Parser::Finish);
diff --git a/src/node_internals.h b/src/node_internals.h
index 80aa4e536..50f826dd8 100644
--- a/src/node_internals.h
+++ b/src/node_internals.h
@@ -28,6 +28,9 @@
namespace node {
+// Defined in node.cc
+extern v8::Isolate* node_isolate;
+
#ifdef _WIN32
// emulate snprintf() on windows, _snprintf() doesn't zero-terminate the buffer
// on overflow...
@@ -86,14 +89,18 @@ inline static v8::Handle<v8::Value> ThrowRangeError(const char* errmsg) {
#define UNWRAP(type) \
assert(!args.Holder().IsEmpty()); \
assert(args.Holder()->InternalFieldCount() > 0); \
- type* wrap = \
- static_cast<type*>(args.Holder()->GetPointerFromInternalField(0)); \
+ type* wrap = static_cast<type*>( \
+ args.Holder()->GetPointerFromInternalField(0)); \
if (!wrap) { \
fprintf(stderr, #type ": Aborting due to unwrap failure at %s:%d\n", \
__FILE__, __LINE__); \
abort(); \
}
+v8::Handle<v8::Value> FromConstructorTemplate(
+ v8::Persistent<v8::FunctionTemplate> t,
+ const v8::Arguments& args);
+
} // namespace node
#endif // SRC_NODE_INTERNALS_H_
diff --git a/src/node_io_watcher.cc b/src/node_io_watcher.cc
deleted file mode 100644
index f238d60e2..000000000
--- a/src/node_io_watcher.cc
+++ /dev/null
@@ -1,166 +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.
-
-#include "node_io_watcher.h"
-
-#include "node.h"
-#include "v8.h"
-
-#include <assert.h>
-
-namespace node {
-
-using namespace v8;
-
-Persistent<FunctionTemplate> IOWatcher::constructor_template;
-Persistent<String> callback_symbol;
-
-
-void IOWatcher::Initialize(Handle<Object> target) {
- HandleScope scope;
-
- Local<FunctionTemplate> t = FunctionTemplate::New(IOWatcher::New);
- constructor_template = Persistent<FunctionTemplate>::New(t);
- constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
- constructor_template->SetClassName(String::NewSymbol("IOWatcher"));
-
- NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", IOWatcher::Start);
- NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", IOWatcher::Stop);
- NODE_SET_PROTOTYPE_METHOD(constructor_template, "set", IOWatcher::Set);
-
- target->Set(String::NewSymbol("IOWatcher"), constructor_template->GetFunction());
-
- callback_symbol = NODE_PSYMBOL("callback");
-}
-
-
-void IOWatcher::Callback(EV_P_ ev_io *w, int revents) {
- IOWatcher *io = static_cast<IOWatcher*>(w->data);
- assert(w == &io->watcher_);
- HandleScope scope;
-
- Local<Value> callback_v = io->handle_->Get(callback_symbol);
- if (!callback_v->IsFunction()) {
- io->Stop();
- return;
- }
-
- Local<Function> callback = Local<Function>::Cast(callback_v);
-
- Local<Value> argv[2];
- argv[0] = Local<Value>::New(revents & EV_READ ? True() : False());
- argv[1] = Local<Value>::New(revents & EV_WRITE ? True() : False());
-
- MakeCallback(io->handle_, callback, ARRAY_SIZE(argv), argv);
-}
-
-
-//
-// var io = new process.IOWatcher();
-// process.callback = function (readable, writable) { ... };
-// io.set(fd, true, false);
-// io.start();
-//
-Handle<Value> IOWatcher::New(const Arguments& args) {
- if (!args.IsConstructCall()) {
- return FromConstructorTemplate(constructor_template, args);
- }
-
- if (!no_deprecation) {
- fprintf(stderr, "WARNING: don't use IOWatcher, it'll be removed in v0.9\n");
- }
-
- HandleScope scope;
- IOWatcher *s = new IOWatcher();
- s->Wrap(args.This());
- return args.This();
-}
-
-
-Handle<Value> IOWatcher::Start(const Arguments& args) {
- HandleScope scope;
- IOWatcher *io = ObjectWrap::Unwrap<IOWatcher>(args.Holder());
- io->Start();
- return Undefined();
-}
-
-
-Handle<Value> IOWatcher::Stop(const Arguments& args) {
- HandleScope scope;
- IOWatcher *io = ObjectWrap::Unwrap<IOWatcher>(args.Holder());
- io->Stop();
- return Undefined();
-}
-
-
-void IOWatcher::Start() {
- if (!ev_is_active(&watcher_)) {
- ev_io_start(EV_DEFAULT_UC_ &watcher_);
- Ref();
- }
-}
-
-
-void IOWatcher::Stop() {
- if (ev_is_active(&watcher_)) {
- ev_io_stop(EV_DEFAULT_UC_ &watcher_);
- Unref();
- }
-}
-
-
-Handle<Value> IOWatcher::Set(const Arguments& args) {
- HandleScope scope;
-
- IOWatcher *io = ObjectWrap::Unwrap<IOWatcher>(args.Holder());
-
- if (!args[0]->IsInt32()) {
- return ThrowException(Exception::TypeError(
- String::New("First arg should be a file descriptor.")));
- }
-
- int fd = args[0]->Int32Value();
-
- if (!args[1]->IsBoolean()) {
- return ThrowException(Exception::TypeError(
- String::New("Second arg should boolean (readable).")));
- }
-
- int events = 0;
-
- if (args[1]->IsTrue()) events |= EV_READ;
-
- if (!args[2]->IsBoolean()) {
- return ThrowException(Exception::TypeError(
- String::New("Third arg should boolean (writable).")));
- }
-
- if (args[2]->IsTrue()) events |= EV_WRITE;
-
- assert(!io->watcher_.active);
- ev_io_set(&io->watcher_, fd, events);
-
- return Undefined();
-}
-
-
-
-} // namespace node
diff --git a/src/node_io_watcher.h b/src/node_io_watcher.h
deleted file mode 100644
index d14289c86..000000000
--- a/src/node_io_watcher.h
+++ /dev/null
@@ -1,64 +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.
-
-#ifndef NODE_IO_H_
-#define NODE_IO_H_
-
-#include "node_object_wrap.h"
-#include "uv-private/ev.h"
-
-namespace node {
-
-class IOWatcher : ObjectWrap {
- public:
- static void Initialize(v8::Handle<v8::Object> target);
-
- protected:
- static v8::Persistent<v8::FunctionTemplate> constructor_template;
-
- IOWatcher() : ObjectWrap() {
- ev_init(&watcher_, IOWatcher::Callback);
- watcher_.data = this;
- }
-
- ~IOWatcher() {
- ev_io_stop(EV_DEFAULT_UC_ &watcher_);
- assert(!ev_is_active(&watcher_));
- assert(!ev_is_pending(&watcher_));
- }
-
- static v8::Handle<v8::Value> New(const v8::Arguments& args);
- static v8::Handle<v8::Value> Start(const v8::Arguments& args);
- static v8::Handle<v8::Value> Stop(const v8::Arguments& args);
- static v8::Handle<v8::Value> Set(const v8::Arguments& args);
-
- private:
- static void Callback(EV_P_ ev_io *watcher, int revents);
-
- void Start();
- void Stop();
-
- ev_io watcher_;
-};
-
-} // namespace node
-#endif // NODE_IO_H_
-
diff --git a/src/node_os.cc b/src/node_os.cc
index f823ed454..d9712b8bf 100644
--- a/src/node_os.cc
+++ b/src/node_os.cc
@@ -41,6 +41,14 @@ namespace node {
using namespace v8;
+static Handle<Value> GetEndianness(const Arguments& args) {
+ HandleScope scope;
+ int i = 1;
+ bool big = (*(char *)&i) == 0;
+ Local<String> endianness = String::New(big ? "BE" : "LE");
+ return scope.Close(endianness);
+}
+
static Handle<Value> GetHostname(const Arguments& args) {
HandleScope scope;
char s[255];
@@ -116,19 +124,20 @@ static Handle<Value> GetCPUInfo(const Arguments& args) {
for (i = 0; i < count; i++) {
Local<Object> times_info = Object::New();
times_info->Set(String::New("user"),
- Number::New(cpu_infos[i].cpu_times.user));
+ Integer::New(cpu_infos[i].cpu_times.user));
times_info->Set(String::New("nice"),
- Number::New(cpu_infos[i].cpu_times.nice));
+ Integer::New(cpu_infos[i].cpu_times.nice));
times_info->Set(String::New("sys"),
- Number::New(cpu_infos[i].cpu_times.sys));
+ Integer::New(cpu_infos[i].cpu_times.sys));
times_info->Set(String::New("idle"),
- Number::New(cpu_infos[i].cpu_times.idle));
+ Integer::New(cpu_infos[i].cpu_times.idle));
times_info->Set(String::New("irq"),
- Number::New(cpu_infos[i].cpu_times.irq));
+ Integer::New(cpu_infos[i].cpu_times.irq));
Local<Object> cpu_info = Object::New();
cpu_info->Set(String::New("model"), String::New(cpu_infos[i].model));
- cpu_info->Set(String::New("speed"), Integer::New(cpu_infos[i].speed));
+ cpu_info->Set(String::New("speed"),
+ Integer::New(cpu_infos[i].speed));
cpu_info->Set(String::New("times"), times_info);
(*cpus)->Set(i,cpu_info);
}
@@ -198,9 +207,8 @@ static Handle<Value> GetInterfaceAddresses(const Arguments& args) {
uv_err_t err = uv_interface_addresses(&interfaces, &count);
- if (err.code != UV_OK) {
- return Undefined();
- }
+ if (err.code != UV_OK)
+ return ThrowException(UVException(err.code, "uv_interface_addresses"));
ret = Object::New();
@@ -227,8 +235,10 @@ static Handle<Value> GetInterfaceAddresses(const Arguments& args) {
o = Object::New();
o->Set(String::New("address"), String::New(ip));
o->Set(String::New("family"), family);
- o->Set(String::New("internal"), interfaces[i].is_internal ?
- True() : False());
+
+ const bool internal = interfaces[i].is_internal;
+ o->Set(String::New("internal"),
+ internal ? True() : False());
ifarr->Set(ifarr->Length(), o);
}
@@ -242,6 +252,7 @@ static Handle<Value> GetInterfaceAddresses(const Arguments& args) {
void OS::Initialize(v8::Handle<v8::Object> target) {
HandleScope scope;
+ NODE_SET_METHOD(target, "getEndianness", GetEndianness);
NODE_SET_METHOD(target, "getHostname", GetHostname);
NODE_SET_METHOD(target, "getLoadAvg", GetLoadAvg);
NODE_SET_METHOD(target, "getUptime", GetUptime);
diff --git a/src/node_signal_watcher.cc b/src/node_signal_watcher.cc
deleted file mode 100644
index 8cfd272ec..000000000
--- a/src/node_signal_watcher.cc
+++ /dev/null
@@ -1,119 +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.
-
-#include "node_signal_watcher.h"
-#include <assert.h>
-
-namespace node {
-
-using namespace v8;
-
-Persistent<FunctionTemplate> SignalWatcher::constructor_template;
-static Persistent<String> callback_symbol;
-
-void SignalWatcher::Initialize(Handle<Object> target) {
- HandleScope scope;
-
- Local<FunctionTemplate> t = FunctionTemplate::New(SignalWatcher::New);
- constructor_template = Persistent<FunctionTemplate>::New(t);
- constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
- constructor_template->SetClassName(String::NewSymbol("SignalWatcher"));
-
- NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", SignalWatcher::Start);
- NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", SignalWatcher::Stop);
-
- target->Set(String::NewSymbol("SignalWatcher"),
- constructor_template->GetFunction());
-
- callback_symbol = NODE_PSYMBOL("callback");
-}
-
-void SignalWatcher::Callback(EV_P_ ev_signal *watcher, int revents) {
- SignalWatcher *w = static_cast<SignalWatcher*>(watcher->data);
-
- assert(watcher == &w->watcher_);
- assert(revents == EV_SIGNAL);
-
- HandleScope scope;
-
- Local<Value> callback_v = w->handle_->Get(callback_symbol);
- if (!callback_v->IsFunction()) {
- w->Stop();
- return;
- }
-
- Local<Function> callback = Local<Function>::Cast(callback_v);
-
- MakeCallback(w->handle_, callback, 0, NULL);
-}
-
-Handle<Value> SignalWatcher::New(const Arguments& args) {
- if (!args.IsConstructCall()) {
- return FromConstructorTemplate(constructor_template, args);
- }
-
- HandleScope scope;
-
- if (args.Length() != 1 || !args[0]->IsInt32()) {
- return ThrowException(String::New("Bad arguments"));
- }
-
- int sig = args[0]->Int32Value();
-
- SignalWatcher *w = new SignalWatcher(sig);
- w->Wrap(args.Holder());
-
- return args.This();
-}
-
-Handle<Value> SignalWatcher::Start(const Arguments& args) {
- HandleScope scope;
- SignalWatcher *w = ObjectWrap::Unwrap<SignalWatcher>(args.Holder());
- w->Start();
- return Undefined();
-}
-
-void SignalWatcher::Start () {
- if (!watcher_.active) {
- ev_signal_start(EV_DEFAULT_UC_ &watcher_);
- ev_unref(EV_DEFAULT_UC);
- Ref();
- }
-}
-
-Handle<Value> SignalWatcher::Stop(const Arguments& args) {
- HandleScope scope;
- SignalWatcher *w = ObjectWrap::Unwrap<SignalWatcher>(args.Holder());
- w->Stop();
- return Undefined();
-}
-
-void SignalWatcher::Stop () {
- if (watcher_.active) {
- ev_ref(EV_DEFAULT_UC);
- ev_signal_stop(EV_DEFAULT_UC_ &watcher_);
- Unref();
- }
-}
-
-} // namespace node
-
-NODE_MODULE(node_signal_watcher, node::SignalWatcher::Initialize)
diff --git a/src/node_signal_watcher.h b/src/node_signal_watcher.h
deleted file mode 100644
index f46022bd3..000000000
--- a/src/node_signal_watcher.h
+++ /dev/null
@@ -1,62 +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.
-
-#ifndef NODE_SIGNAL_WATCHER_H_
-#define NODE_SIGNAL_WATCHER_H_
-
-#include "node.h"
-#include "v8.h"
-#include "uv-private/ev.h"
-
-namespace node {
-
-class SignalWatcher : ObjectWrap {
- public:
- static void Initialize(v8::Handle<v8::Object> target);
-
- protected:
- static v8::Persistent<v8::FunctionTemplate> constructor_template;
-
- SignalWatcher(int sig) : ObjectWrap() {
- ev_signal_init(&watcher_, SignalWatcher::Callback, sig);
- watcher_.data = this;
- }
-
- ~SignalWatcher() {
- ev_signal_stop(EV_DEFAULT_UC_ &watcher_);
- }
-
- static v8::Handle<v8::Value> New(const v8::Arguments& args);
- static v8::Handle<v8::Value> Start(const v8::Arguments& args);
- static v8::Handle<v8::Value> Stop(const v8::Arguments& args);
-
- private:
- static void Callback(EV_P_ ev_signal *watcher, int revents);
-
- void Start();
- void Stop();
-
- ev_signal watcher_;
-};
-
-} // namespace node
-#endif // NODE_SIGNAL_WATCHER_H_
-
diff --git a/src/node_systemtap.d b/src/node_systemtap.d
new file mode 100644
index 000000000..5247cc7fc
--- /dev/null
+++ b/src/node_systemtap.d
@@ -0,0 +1,51 @@
+// 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.
+
+// Hints:
+// This .d defines compiled in probes
+// probes are handles (untyped pointers)
+// v8 forward declared objs (dtrace_connection_t) are defined
+// in node_dtrace.cc which builds an InitDtrace object which
+// gets populated with the probes
+// The probes gather the following:
+// PROBE_REQUEST(req, fd, remote, port, buffered)
+// PROBE_OTHER(fd, remote, port, buffered)
+// other notes:
+// using any PROBE_ENABLED() macros in dtrace.cc sdt broke it
+// can only pass strings/ints/primitives not dtrace_connection_t
+// conn or other structs
+// verify probe existence by using
+// $ stap -l 'process("out/Release/node").mark("*")'
+// TODO: write .stp scripts (node.stp, node_v8ustack.stp + ???)
+
+
+provider node {
+ probe http__client__request(string, int, string, int, int);
+ probe http__client__response(int, string, int, int);
+ probe http__server__request(string, int, string, int, int);
+ probe http__server__response(int, string, int, int);
+ probe net__server__connection(int, string, int, int);
+ probe net__socket__read(int, string, int, int);
+ probe net__socket__write(int, string, int, int);
+ probe net__stream__end(int, string, int, int);
+ probe gc__done();
+ probe gc__start();
+};
diff --git a/src/node_version.h b/src/node_version.h
index bc689339d..a20506933 100644
--- a/src/node_version.h
+++ b/src/node_version.h
@@ -23,8 +23,8 @@
#define NODE_VERSION_H
#define NODE_MAJOR_VERSION 0
-#define NODE_MINOR_VERSION 8
-#define NODE_PATCH_VERSION 22
+#define NODE_MINOR_VERSION 9
+#define NODE_PATCH_VERSION 11
#ifndef NODE_TAG
# define NODE_TAG ""
diff --git a/src/node_win32_etw_provider-inl.h b/src/node_win32_etw_provider-inl.h
index 9d3f4e546..db59eea57 100644
--- a/src/node_win32_etw_provider-inl.h
+++ b/src/node_win32_etw_provider-inl.h
@@ -42,6 +42,20 @@ extern int events_enabled;
#define ETW_WRITE_INT32_DATA(data_descriptor, data) \
EventDataDescCreate(data_descriptor, data, sizeof(int32_t));
+#define ETW_WRITE_INT64_DATA(data_descriptor, data) \
+ EventDataDescCreate(data_descriptor, data, sizeof(int64_t));
+
+#define ETW_WRITE_ADDRESS_DATA(data_descriptor, data) \
+ EventDataDescCreate(data_descriptor, data, sizeof(intptr_t));
+
+#define ETW_WRITE_INT16_DATA(data_descriptor, data) \
+ EventDataDescCreate(data_descriptor, data, sizeof(int16_t));
+
+#define ETW_WRITE_WSTRING_DATA_LENGTH(data_descriptor, data, data_len_bytes) \
+ EventDataDescCreate(data_descriptor, \
+ data, \
+ data_len_bytes);
+
#define ETW_WRITE_NET_CONNECTION(descriptors, conn) \
ETW_WRITE_INT32_DATA(descriptors, &conn->fd); \
ETW_WRITE_INT32_DATA(descriptors + 1, &conn->port); \
@@ -61,6 +75,34 @@ extern int events_enabled;
ETW_WRITE_INT32_DATA(descriptors, &type); \
ETW_WRITE_INT32_DATA(descriptors + 1, &flags);
+#define ETW_WRITE_V8ADDRESSCHANGE(descriptors, addr1, addr2) \
+ ETW_WRITE_ADDRESS_DATA(descriptors, &addr1); \
+ ETW_WRITE_ADDRESS_DATA(descriptors + 1, &addr2);
+
+#define ETW_WRITE_JSMETHOD_LOADUNLOAD(descriptors, \
+ context, \
+ startAddr, \
+ size, \
+ id, \
+ flags, \
+ rangeId, \
+ sourceId, \
+ line, \
+ col, \
+ name, \
+ name_len_bytes) \
+ ETW_WRITE_ADDRESS_DATA(descriptors, &context); \
+ ETW_WRITE_ADDRESS_DATA(descriptors + 1, &startAddr); \
+ ETW_WRITE_INT64_DATA(descriptors + 2, &size); \
+ ETW_WRITE_INT32_DATA(descriptors + 3, &id); \
+ ETW_WRITE_INT16_DATA(descriptors + 4, &flags); \
+ ETW_WRITE_INT16_DATA(descriptors + 5, &rangeId); \
+ ETW_WRITE_INT64_DATA(descriptors + 6, &sourceId); \
+ ETW_WRITE_INT32_DATA(descriptors + 7, &line); \
+ ETW_WRITE_INT32_DATA(descriptors + 8, &col); \
+ ETW_WRITE_WSTRING_DATA_LENGTH(descriptors + 9, name, name_len_bytes);
+
+
#define ETW_WRITE_EVENT(eventDescriptor, dataDescriptors) \
DWORD status = event_write(node_provider, \
&eventDescriptor, \
@@ -133,6 +175,83 @@ void NODE_GC_DONE(GCType type, GCCallbackFlags flags) {
}
+void NODE_V8SYMBOL_REMOVE(const void* addr1, const void* addr2) {
+ if (events_enabled > 0) {
+ EVENT_DATA_DESCRIPTOR descriptors[2];
+ ETW_WRITE_V8ADDRESSCHANGE(descriptors, addr1, addr2);
+ ETW_WRITE_EVENT(NODE_V8SYMBOL_REMOVE_EVENT, descriptors);
+ }
+}
+
+
+void NODE_V8SYMBOL_MOVE(const void* addr1, const void* addr2) {
+ if (events_enabled > 0) {
+ EVENT_DATA_DESCRIPTOR descriptors[2];
+ ETW_WRITE_V8ADDRESSCHANGE(descriptors, addr1, addr2);
+ ETW_WRITE_EVENT(NODE_V8SYMBOL_MOVE_EVENT, descriptors);
+ }
+}
+
+
+void NODE_V8SYMBOL_RESET() {
+ if (events_enabled > 0) {
+ int val = 0;
+ EVENT_DATA_DESCRIPTOR descriptors[1];
+ ETW_WRITE_INT32_DATA(descriptors, &val);
+ ETW_WRITE_EVENT(NODE_V8SYMBOL_RESET_EVENT, descriptors);
+ }
+}
+
+#define SETSYMBUF(s) \
+ wcscpy(symbuf, s); \
+ symbol_len = ARRAY_SIZE(s) - 1;
+
+void NODE_V8SYMBOL_ADD(LPCSTR symbol,
+ int symbol_len,
+ const void* addr1,
+ int len) {
+ if (events_enabled > 0) {
+ wchar_t symbuf[128];
+ if (symbol == NULL) {
+ SETSYMBUF(L"NULL");
+ } else {
+ symbol_len = MultiByteToWideChar(CP_ACP, 0, symbol, symbol_len, symbuf, 128);
+ if (symbol_len == 0) {
+ SETSYMBUF(L"Invalid");
+ } else {
+ if (symbol_len > 127) {
+ symbol_len = 127;
+ }
+ symbuf[symbol_len] = L'\0';
+ }
+ }
+ void* context = NULL;
+ INT64 size = (INT64)len;
+ INT32 id = (INT32)addr1;
+ INT16 flags = 0;
+ INT16 rangeid = 1;
+ INT32 col = 1;
+ INT32 line = 1;
+ INT64 sourceid = 0;
+ EVENT_DATA_DESCRIPTOR descriptors[10];
+ ETW_WRITE_JSMETHOD_LOADUNLOAD(descriptors,
+ context,
+ addr1,
+ size,
+ id,
+ flags,
+ rangeid,
+ sourceid,
+ line,
+ col,
+ symbuf,
+ symbol_len * sizeof(symbuf[0]));
+ ETW_WRITE_EVENT(MethodLoad, descriptors);
+ }
+}
+#undef SETSYMBUF
+
+
bool NODE_HTTP_SERVER_REQUEST_ENABLED() { return events_enabled > 0; }
bool NODE_HTTP_SERVER_RESPONSE_ENABLED() { return events_enabled > 0; }
bool NODE_HTTP_CLIENT_REQUEST_ENABLED() { return events_enabled > 0; }
@@ -141,5 +260,6 @@ bool NODE_NET_SERVER_CONNECTION_ENABLED() { return events_enabled > 0; }
bool NODE_NET_STREAM_END_ENABLED() { return events_enabled > 0; }
bool NODE_NET_SOCKET_READ_ENABLED() { return events_enabled > 0; }
bool NODE_NET_SOCKET_WRITE_ENABLED() { return events_enabled > 0; }
+bool NODE_V8SYMBOL_ENABLED() { return events_enabled > 0; }
}
#endif // SRC_ETW_INL_H_ \ No newline at end of file
diff --git a/src/node_win32_etw_provider.cc b/src/node_win32_etw_provider.cc
index 78f465c46..26769b0e5 100644
--- a/src/node_win32_etw_provider.cc
+++ b/src/node_win32_etw_provider.cc
@@ -22,6 +22,7 @@
#include "node_dtrace.h"
#include "node_win32_etw_provider.h"
#include "node_etw_provider.h"
+#include "node_win32_etw_provider-inl.h"
namespace node {
@@ -33,10 +34,110 @@ EventRegisterFunc event_register;
EventUnregisterFunc event_unregister;
EventWriteFunc event_write;
int events_enabled;
+static uv_async_t dispatch_etw_events_change_async;
+
+struct v8tags {
+ char prefix[32 - sizeof(size_t)];
+ size_t prelen;
+};
+
+// The v8 CODE_ADDED event name has a prefix indicating the type of event.
+// Many of these are internal to v8.
+// The trace_codes array specifies which types are written.
+struct v8tags trace_codes[] = {
+#define MAKE_V8TAG(s) { s, sizeof(s) - 1 }
+ MAKE_V8TAG("LazyCompile:"),
+ MAKE_V8TAG("Script:"),
+ MAKE_V8TAG("Function:"),
+ MAKE_V8TAG("RegExp:"),
+ MAKE_V8TAG("Eval:")
+#undef MAKE_V8TAG
+};
+
+/* Below are some code prefixes which are not being written.
+ * "Builtin:"
+ * "Stub:"
+ * "CallIC:"
+ * "LoadIC:"
+ * "KeyedLoadIC:"
+ * "StoreIC:"
+ * "KeyedStoreIC:"
+ * "CallPreMonomorphic:"
+ * "CallInitialize:"
+ * "CallMiss:"
+ * "CallMegamorphic:"
+ */
+
+// v8 sometimes puts a '*' or '~' in front of the name.
+#define V8_MARKER1 '*'
+#define V8_MARKER2 '~'
+
+
+// If prefix is not in filtered list return -1,
+// else return length of prefix and marker.
+int FilterCodeEvents(const char* name, size_t len) {
+ for (int i = 0; i < ARRAY_SIZE(trace_codes); i++) {
+ size_t prelen = trace_codes[i].prelen;
+ if (prelen < len) {
+ if (strncmp(name, trace_codes[i].prefix, prelen) == 0) {
+ if (name[prelen] == V8_MARKER1 || name[prelen] == V8_MARKER2)
+ prelen++;
+ return prelen;
+ }
+ }
+ }
+ return -1;
+}
+
+
+// callback from V8 module passes symbol and address info for stack walk
+void CodeAddressNotification(const JitCodeEvent* jevent) {
+ int pre_offset = 0;
+ if (NODE_V8SYMBOL_ENABLED()) {
+ switch (jevent->type) {
+ case JitCodeEvent::CODE_ADDED:
+ pre_offset = FilterCodeEvents(jevent->name.str, jevent->name.len);
+ if (pre_offset >= 0) {
+ // skip over prefix and marker
+ NODE_V8SYMBOL_ADD(jevent->name.str + pre_offset,
+ jevent->name.len - pre_offset,
+ jevent->code_start,
+ jevent->code_len);
+ }
+ break;
+ case JitCodeEvent::CODE_REMOVED:
+ NODE_V8SYMBOL_REMOVE(jevent->code_start, 0);
+ break;
+ case JitCodeEvent::CODE_MOVED:
+ NODE_V8SYMBOL_MOVE(jevent->code_start, jevent->new_code_start);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+// Call v8 to enable or disable code event callbacks.
+// Must be on default thread to do this.
+// Note: It is possible to call v8 from ETW thread, but then
+// event callbacks are received in the same thread. Attempts
+// to write ETW events in this thread will fail.
+void etw_events_change_async(uv_async_t* handle, int status) {
+ if (events_enabled > 0) {
+ NODE_V8SYMBOL_RESET();
+ V8::SetJitCodeEventHandler(v8::kJitCodeEventEnumExisting,
+ CodeAddressNotification);
+ } else {
+ V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
+ }
+}
+
// This callback is called by ETW when consumers of our provider
// are enabled or disabled.
// The callback is dispatched on ETW thread.
+// Before calling into V8 to enable code events, switch to default thread.
void NTAPI etw_events_enable_callback(
LPCGUID SourceId,
ULONG IsEnabled,
@@ -47,8 +148,14 @@ void NTAPI etw_events_enable_callback(
PVOID CallbackContext) {
if (IsEnabled) {
events_enabled++;
+ if (events_enabled == 1) {
+ uv_async_send(&dispatch_etw_events_change_async);
+ }
} else {
events_enabled--;
+ if (events_enabled == 0) {
+ uv_async_send(&dispatch_etw_events_change_async);
+ }
}
}
@@ -64,6 +171,12 @@ void init_etw() {
GetProcAddress(advapi, "EventUnregister");
event_write = (EventWriteFunc)GetProcAddress(advapi, "EventWrite");
+ // create async object used to invoke main thread from callback
+ uv_async_init(uv_default_loop(),
+ &dispatch_etw_events_change_async,
+ etw_events_change_async);
+ uv_unref((uv_handle_t*) &dispatch_etw_events_change_async);
+
if (event_register) {
DWORD status = event_register(&NODE_ETW_PROVIDER,
etw_events_enable_callback,
@@ -82,6 +195,7 @@ void shutdown_etw() {
}
events_enabled = 0;
+ V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
if (advapi) {
FreeLibrary(advapi);
diff --git a/src/node_win32_etw_provider.h b/src/node_win32_etw_provider.h
index adfff37e5..cfc2c8658 100644
--- a/src/node_win32_etw_provider.h
+++ b/src/node_win32_etw_provider.h
@@ -66,6 +66,13 @@ INLINE void NODE_NET_SERVER_CONNECTION(node_dtrace_connection_t* conn);
INLINE void NODE_NET_STREAM_END(node_dtrace_connection_t* conn);
INLINE void NODE_GC_START(GCType type, GCCallbackFlags flags);
INLINE void NODE_GC_DONE(GCType type, GCCallbackFlags flags);
+INLINE void NODE_V8SYMBOL_REMOVE(const void* addr1, const void* addr2);
+INLINE void NODE_V8SYMBOL_MOVE(const void* addr1, const void* addr2);
+INLINE void NODE_V8SYMBOL_RESET();
+INLINE void NODE_V8SYMBOL_ADD(LPCSTR symbol,
+ int symbol_len,
+ const void* addr1,
+ int len);
INLINE bool NODE_HTTP_SERVER_REQUEST_ENABLED();
INLINE bool NODE_HTTP_SERVER_RESPONSE_ENABLED();
@@ -75,6 +82,7 @@ INLINE bool NODE_NET_SERVER_CONNECTION_ENABLED();
INLINE bool NODE_NET_STREAM_END_ENABLED();
INLINE bool NODE_NET_SOCKET_READ_ENABLED();
INLINE bool NODE_NET_SOCKET_WRITE_ENABLED();
+INLINE bool NODE_V8SYMBOL_ENABLED();
#define NODE_NET_SOCKET_READ(arg0, arg1)
#define NODE_NET_SOCKET_WRITE(arg0, arg1)
diff --git a/src/node_win32_perfctr_provider.cc b/src/node_win32_perfctr_provider.cc
new file mode 100644
index 000000000..903150ed6
--- /dev/null
+++ b/src/node_win32_perfctr_provider.cc
@@ -0,0 +1,345 @@
+// 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.
+
+#include "node_counters.h"
+#include <perflib.h>
+#include "node_win32_perfctr_provider.h"
+
+#define __INIT_node_perfctr_provider_IMP
+#include <node_perfctr_provider.h>
+
+typedef ULONG (WINAPI *PerfStartProviderExFunc)(
+ __in LPGUID ProviderGuid,
+ __in_opt PPERF_PROVIDER_CONTEXT ProviderContext,
+ __out PHANDLE Provider
+ );
+
+typedef ULONG (WINAPI *PerfStopProviderFunc)(
+ __in HANDLE ProviderHandle
+ );
+
+typedef ULONG (WINAPI *PerfSetCounterSetInfoFunc)(
+ __in HANDLE ProviderHandle,
+ __inout_bcount(TemplateSize) PPERF_COUNTERSET_INFO Template,
+ __in ULONG TemplateSize
+ );
+
+typedef PPERF_COUNTERSET_INSTANCE (WINAPI *PerfCreateInstanceFunc)(
+ __in HANDLE ProviderHandle,
+ __in LPCGUID CounterSetGuid,
+ __in PCWSTR Name,
+ __in ULONG Id
+ );
+
+typedef ULONG (WINAPI *PerfDeleteInstanceFunc)(
+ __in HANDLE Provider,
+ __in PPERF_COUNTERSET_INSTANCE InstanceBlock
+ );
+
+typedef ULONG (WINAPI *PerfSetULongCounterValueFunc)(
+ __in HANDLE Provider,
+ __inout PPERF_COUNTERSET_INSTANCE Instance,
+ __in ULONG CounterId,
+ __in ULONG Value
+ );
+
+typedef ULONG (WINAPI *PerfSetULongLongCounterValueFunc)(
+ __in HANDLE Provider,
+ __inout PPERF_COUNTERSET_INSTANCE Instance,
+ __in ULONG CounterId,
+ __in ULONGLONG Value
+ );
+
+typedef ULONG (WINAPI *PerfIncrementULongCounterValueFunc)(
+ __in HANDLE Provider,
+ __inout PPERF_COUNTERSET_INSTANCE Instance,
+ __in ULONG CounterId,
+ __in ULONG Value
+ );
+
+typedef ULONG (WINAPI *PerfIncrementULongLongCounterValueFunc)(
+ __in HANDLE Provider,
+ __inout PPERF_COUNTERSET_INSTANCE Instance,
+ __in ULONG CounterId,
+ __in ULONGLONG Value
+ );
+
+typedef ULONG (WINAPI *PerfDecrementULongCounterValueFunc)(
+ __in HANDLE Provider,
+ __inout PPERF_COUNTERSET_INSTANCE Instance,
+ __in ULONG CounterId,
+ __in ULONG Value
+ );
+
+typedef ULONG (WINAPI *PerfDecrementULongLongCounterValueFunc)(
+ __in HANDLE Provider,
+ __inout PPERF_COUNTERSET_INSTANCE Instance,
+ __in ULONG CounterId,
+ __in ULONGLONG Value
+ );
+
+
+HMODULE advapimod;
+PerfStartProviderExFunc perfctr_startProvider;
+PerfStopProviderFunc perfctr_stopProvider;
+PerfSetCounterSetInfoFunc perfctr_setCounterSetInfo;
+PerfCreateInstanceFunc perfctr_createInstance;
+PerfDeleteInstanceFunc perfctr_deleteInstance;
+PerfSetULongCounterValueFunc perfctr_setULongValue;
+PerfSetULongLongCounterValueFunc perfctr_setULongLongValue;
+PerfIncrementULongCounterValueFunc perfctr_incrementULongValue;
+PerfIncrementULongLongCounterValueFunc perfctr_incrementULongLongValue;
+PerfDecrementULongCounterValueFunc perfctr_decrementULongValue;
+PerfDecrementULongLongCounterValueFunc perfctr_decrementULongLongValue;
+
+PPERF_COUNTERSET_INSTANCE perfctr_instance;
+
+
+#define NODE_COUNTER_HTTP_SERVER_REQUEST 1
+#define NODE_COUNTER_HTTP_SERVER_RESPONSE 2
+#define NODE_COUNTER_HTTP_CLIENT_REQUEST 3
+#define NODE_COUNTER_HTTP_CLIENT_RESPONSE 4
+#define NODE_COUNTER_SERVER_CONNS 5
+#define NODE_COUNTER_NET_BYTES_SENT 6
+#define NODE_COUNTER_NET_BYTES_RECV 7
+#define NODE_COUNTER_GC_PERCENTTIME 8
+#define NODE_COUNTER_PIPE_BYTES_SENT 9
+#define NODE_COUNTER_PIPE_BYTES_RECV 10
+
+
+namespace node {
+
+
+EXTERN_C DECLSPEC_SELECTANY HANDLE NodeCounterProvider = NULL;
+
+void InitPerfCountersWin32() {
+ ULONG status;
+ PERF_PROVIDER_CONTEXT providerContext;
+
+ // create instance name using pid
+#define INST_MAX_LEN 32
+#define INST_PREFIX_LEN 5
+#define INST_PREFIX L"node_"
+
+ wchar_t Inst[INST_MAX_LEN];
+ DWORD pid = GetCurrentProcessId();
+ wcscpy_s(Inst, INST_MAX_LEN, INST_PREFIX);
+ _itow_s(pid, Inst + INST_PREFIX_LEN, INST_MAX_LEN - INST_PREFIX_LEN, 10);
+
+ advapimod = LoadLibrary("advapi32.dll");
+ if (advapimod) {
+ perfctr_startProvider = (PerfStartProviderExFunc)
+ GetProcAddress(advapimod, "PerfStartProviderEx");
+ perfctr_stopProvider = (PerfStopProviderFunc)
+ GetProcAddress(advapimod, "PerfStopProvider");
+ perfctr_setCounterSetInfo = (PerfSetCounterSetInfoFunc)
+ GetProcAddress(advapimod, "PerfSetCounterSetInfo");
+ perfctr_createInstance = (PerfCreateInstanceFunc)
+ GetProcAddress(advapimod, "PerfCreateInstance");
+ perfctr_deleteInstance = (PerfDeleteInstanceFunc)
+ GetProcAddress(advapimod, "PerfDeleteInstance");
+ perfctr_setULongValue = (PerfSetULongCounterValueFunc)
+ GetProcAddress(advapimod, "PerfSetULongCounterValue");
+ perfctr_setULongLongValue = (PerfSetULongLongCounterValueFunc)
+ GetProcAddress(advapimod, "PerfSetULongLongCounterValue");
+ perfctr_incrementULongValue = (PerfIncrementULongCounterValueFunc)
+ GetProcAddress(advapimod, "PerfIncrementULongCounterValue");
+ perfctr_incrementULongLongValue = (PerfIncrementULongLongCounterValueFunc)
+ GetProcAddress(advapimod, "PerfIncrementULongLongCounterValue");
+ perfctr_decrementULongValue = (PerfDecrementULongCounterValueFunc)
+ GetProcAddress(advapimod, "PerfDecrementULongCounterValue");
+ perfctr_decrementULongLongValue = (PerfDecrementULongLongCounterValueFunc)
+ GetProcAddress(advapimod, "PerfDecrementULongLongCounterValue");
+
+ ZeroMemory(&providerContext, sizeof(providerContext));
+ providerContext.ContextSize = sizeof(providerContext);
+
+ if (!perfctr_startProvider ||
+ !perfctr_setCounterSetInfo ||
+ !perfctr_createInstance) {
+ NodeCounterProvider = NULL;
+ return;
+ }
+
+ status = perfctr_startProvider(&NodeCounterSetGuid,
+ &providerContext,
+ &NodeCounterProvider);
+ if (status != ERROR_SUCCESS) {
+ NodeCounterProvider = NULL;
+ return;
+ }
+
+ status = perfctr_setCounterSetInfo(NodeCounterProvider,
+ &NodeCounterSetInfo.CounterSet,
+ sizeof(NodeCounterSetInfo));
+ if (status != ERROR_SUCCESS) {
+ perfctr_stopProvider(NodeCounterProvider);
+ NodeCounterProvider = NULL;
+ return;
+ }
+
+ perfctr_instance = perfctr_createInstance(NodeCounterProvider,
+ &NodeCounterSetGuid,
+ Inst,
+ 1);
+ if (perfctr_instance == NULL) {
+ perfctr_stopProvider(NodeCounterProvider);
+ NodeCounterProvider = NULL;
+ }
+ }
+}
+
+
+void TermPerfCountersWin32() {
+ if (NodeCounterProvider != NULL &&
+ perfctr_stopProvider != NULL) {
+ perfctr_stopProvider(NodeCounterProvider);
+ NodeCounterProvider = NULL;
+ }
+
+ if (advapimod) {
+ FreeLibrary(advapimod);
+ advapimod = NULL;
+ }
+}
+
+
+void NODE_COUNT_HTTP_SERVER_REQUEST() {
+ if (NodeCounterProvider != NULL && perfctr_incrementULongValue != NULL) {
+ perfctr_incrementULongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_HTTP_SERVER_REQUEST,
+ 1);
+ }
+}
+
+
+void NODE_COUNT_HTTP_SERVER_RESPONSE() {
+ if (NodeCounterProvider != NULL && perfctr_incrementULongValue != NULL) {
+ perfctr_incrementULongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_HTTP_SERVER_RESPONSE,
+ 1);
+ }
+}
+
+
+void NODE_COUNT_HTTP_CLIENT_REQUEST() {
+ if (NodeCounterProvider != NULL && perfctr_incrementULongValue != NULL) {
+ perfctr_incrementULongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_HTTP_CLIENT_REQUEST,
+ 1);
+ }
+}
+
+
+void NODE_COUNT_HTTP_CLIENT_RESPONSE() {
+ if (NodeCounterProvider != NULL && perfctr_incrementULongValue != NULL) {
+ perfctr_incrementULongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_HTTP_CLIENT_RESPONSE,
+ 1);
+ }
+}
+
+
+void NODE_COUNT_SERVER_CONN_OPEN() {
+ if (NodeCounterProvider != NULL && perfctr_incrementULongValue != NULL) {
+ perfctr_incrementULongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_SERVER_CONNS,
+ 1);
+ }
+}
+
+
+void NODE_COUNT_SERVER_CONN_CLOSE() {
+ if (NodeCounterProvider != NULL && perfctr_decrementULongValue != NULL) {
+ perfctr_decrementULongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_SERVER_CONNS,
+ 1);
+ }
+}
+
+
+void NODE_COUNT_NET_BYTES_SENT(int bytes) {
+ if (NodeCounterProvider != NULL && perfctr_incrementULongLongValue != NULL) {
+ perfctr_incrementULongLongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_NET_BYTES_SENT,
+ static_cast<ULONGLONG>(bytes));
+ }
+}
+
+
+void NODE_COUNT_NET_BYTES_RECV(int bytes) {
+ if (NodeCounterProvider != NULL && perfctr_incrementULongLongValue != NULL) {
+ perfctr_incrementULongLongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_NET_BYTES_RECV,
+ static_cast<ULONGLONG>(bytes));
+ }
+}
+
+
+uint64_t NODE_COUNT_GET_GC_RAWTIME() {
+ LARGE_INTEGER timegc;
+ if (QueryPerformanceCounter(&timegc)) {
+ return timegc.QuadPart;
+ } else {
+ return static_cast<uint64_t>(GetTickCount());
+ }
+}
+
+
+void NODE_COUNT_GC_PERCENTTIME(unsigned int percent) {
+ if (NodeCounterProvider != NULL && perfctr_setULongValue != NULL) {
+ perfctr_setULongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_GC_PERCENTTIME,
+ percent);
+ }
+}
+
+
+void NODE_COUNT_PIPE_BYTES_SENT(int bytes) {
+ if (NodeCounterProvider != NULL && perfctr_incrementULongLongValue != NULL) {
+ perfctr_incrementULongLongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_PIPE_BYTES_SENT,
+ static_cast<ULONGLONG>(bytes));
+ }
+}
+
+
+void NODE_COUNT_PIPE_BYTES_RECV(int bytes) {
+ if (NodeCounterProvider != NULL && perfctr_incrementULongLongValue != NULL) {
+ perfctr_incrementULongLongValue(NodeCounterProvider,
+ perfctr_instance,
+ NODE_COUNTER_PIPE_BYTES_RECV,
+ static_cast<ULONGLONG>(bytes));
+ }
+}
+
+
+}
diff --git a/src/node_win32_perfctr_provider.h b/src/node_win32_perfctr_provider.h
new file mode 100644
index 000000000..1b16a3fec
--- /dev/null
+++ b/src/node_win32_perfctr_provider.h
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef SRC_WINPERFCTRS_H_
+#define SRC_WINPERFCTRS_H_
+
+#if defined(_MSC_VER)
+# define INLINE __forceinline
+#else
+# define INLINE inline
+#endif
+
+namespace node {
+
+extern HANDLE NodeCounterProvider;
+
+INLINE bool NODE_COUNTER_ENABLED() { return NodeCounterProvider != NULL; }
+void NODE_COUNT_HTTP_SERVER_REQUEST();
+void NODE_COUNT_HTTP_SERVER_RESPONSE();
+void NODE_COUNT_HTTP_CLIENT_REQUEST();
+void NODE_COUNT_HTTP_CLIENT_RESPONSE();
+void NODE_COUNT_SERVER_CONN_OPEN();
+void NODE_COUNT_SERVER_CONN_CLOSE();
+void NODE_COUNT_NET_BYTES_SENT(int bytes);
+void NODE_COUNT_NET_BYTES_RECV(int bytes);
+uint64_t NODE_COUNT_GET_GC_RAWTIME();
+void NODE_COUNT_GC_PERCENTTIME(unsigned int percent);
+void NODE_COUNT_PIPE_BYTES_SENT(int bytes);
+void NODE_COUNT_PIPE_BYTES_RECV(int bytes);
+
+void InitPerfCountersWin32();
+void TermPerfCountersWin32();
+
+}
+
+#endif
+
diff --git a/src/node_zlib.cc b/src/node_zlib.cc
index 7c7f966cd..ebaba6bb1 100644
--- a/src/node_zlib.cc
+++ b/src/node_zlib.cc
@@ -78,13 +78,13 @@ class ZCtx : public ObjectWrap {
~ZCtx() {
- Clear();
+ Close();
}
- void Clear() {
+ void Close() {
assert(!write_in_progress_ && "write in progress");
- assert(init_done_ && "clear before init");
+ assert(init_done_ && "close before init");
assert(mode_ <= UNZIP);
if (mode_ == DEFLATE || mode_ == GZIP || mode_ == DEFLATERAW) {
@@ -104,10 +104,10 @@ class ZCtx : public ObjectWrap {
}
- static Handle<Value> Clear(const Arguments& args) {
+ static Handle<Value> Close(const Arguments& args) {
HandleScope scope;
ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This());
- ctx->Clear();
+ ctx->Close();
return scope.Close(Undefined());
}
@@ -125,7 +125,19 @@ class ZCtx : public ObjectWrap {
ctx->write_in_progress_ = true;
ctx->Ref();
+ assert(!args[0]->IsUndefined() && "must provide flush value");
+
unsigned int flush = args[0]->Uint32Value();
+
+ if (flush != Z_NO_FLUSH &&
+ flush != Z_PARTIAL_FLUSH &&
+ flush != Z_SYNC_FLUSH &&
+ flush != Z_FULL_FLUSH &&
+ flush != Z_FINISH &&
+ flush != Z_BLOCK) {
+ assert(0 && "Invalid flush value");
+ }
+
Bytef *in;
Bytef *out;
size_t in_off, in_len, out_off, out_len;
@@ -229,7 +241,9 @@ class ZCtx : public ObjectWrap {
}
// v8 land!
- static void After(uv_work_t* work_req) {
+ static void After(uv_work_t* work_req, int status) {
+ assert(status == 0);
+
HandleScope scope;
ZCtx *ctx = container_of(work_req, ZCtx, work_req_);
@@ -496,7 +510,7 @@ void InitZlib(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(z, "write", ZCtx::Write);
NODE_SET_PROTOTYPE_METHOD(z, "init", ZCtx::Init);
- NODE_SET_PROTOTYPE_METHOD(z, "clear", ZCtx::Clear);
+ NODE_SET_PROTOTYPE_METHOD(z, "close", ZCtx::Close);
NODE_SET_PROTOTYPE_METHOD(z, "reset", ZCtx::Reset);
z->SetClassName(String::NewSymbol("Zlib"));
@@ -505,6 +519,7 @@ void InitZlib(Handle<Object> target) {
callback_sym = NODE_PSYMBOL("callback");
onerror_sym = NODE_PSYMBOL("onerror");
+ // valid flush values.
NODE_DEFINE_CONSTANT(target, Z_NO_FLUSH);
NODE_DEFINE_CONSTANT(target, Z_PARTIAL_FLUSH);
NODE_DEFINE_CONSTANT(target, Z_SYNC_FLUSH);
diff --git a/src/perfctr_macros.py b/src/perfctr_macros.py
new file mode 100644
index 000000000..2f7e3cbf8
--- /dev/null
+++ b/src/perfctr_macros.py
@@ -0,0 +1,9 @@
+# This file is used by tools/js2c.py to preprocess out the performance counters
+# symbols in builds that don't support counters. This is not used in builds
+# that support performance counters.
+macro COUNTER_NET_SERVER_CONNECTION(x) = ;
+macro COUNTER_NET_SERVER_CONNECTION_CLOSE(x) = ;
+macro COUNTER_HTTP_SERVER_REQUEST(x) = ;
+macro COUNTER_HTTP_SERVER_RESPONSE(x) = ;
+macro COUNTER_HTTP_CLIENT_REQUEST(x) = ;
+macro COUNTER_HTTP_CLIENT_RESPONSE(x) = ;
diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc
index 2ae74ec23..3952a0799 100644
--- a/src/pipe_wrap.cc
+++ b/src/pipe_wrap.cc
@@ -28,20 +28,21 @@
namespace node {
-using v8::Object;
+using v8::Arguments;
+using v8::Boolean;
+using v8::Context;
+using v8::Function;
+using v8::FunctionTemplate;
using v8::Handle;
+using v8::HandleScope;
+using v8::Integer;
using v8::Local;
+using v8::Object;
using v8::Persistent;
-using v8::Value;
-using v8::HandleScope;
-using v8::FunctionTemplate;
+using v8::PropertyAttribute;
using v8::String;
-using v8::Function;
using v8::TryCatch;
-using v8::Context;
-using v8::Arguments;
-using v8::Integer;
-using v8::Boolean;
+using v8::Value;
Persistent<Function> pipeConstructor;
@@ -82,8 +83,18 @@ void PipeWrap::Initialize(Handle<Object> target) {
t->InstanceTemplate()->SetInternalFieldCount(1);
+ enum PropertyAttribute attributes =
+ static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
+ t->InstanceTemplate()->SetAccessor(String::New("fd"),
+ StreamWrap::GetFD,
+ NULL,
+ Handle<Value>(),
+ v8::DEFAULT,
+ attributes);
+
NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);
NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);
+ NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref);
NODE_SET_PROTOTYPE_METHOD(t, "readStart", StreamWrap::ReadStart);
NODE_SET_PROTOTYPE_METHOD(t, "readStop", StreamWrap::ReadStop);
@@ -128,7 +139,7 @@ PipeWrap::PipeWrap(Handle<Object> object, bool ipc)
int r = uv_pipe_init(uv_default_loop(), &handle_, ipc);
assert(r == 0); // How do we proxy this error up to javascript?
// Suggestion: uv_pipe_init() returns void.
- handle_.data = reinterpret_cast<void*>(this);
+ handle_.data = static_cast<void*>(this);
UpdateWriteQueueSize();
}
diff --git a/src/process_wrap.cc b/src/process_wrap.cc
index b156692ac..784300f9a 100644
--- a/src/process_wrap.cc
+++ b/src/process_wrap.cc
@@ -250,7 +250,8 @@ class ProcessWrap : public HandleWrap {
else {
wrap->SetHandle((uv_handle_t*)&wrap->process_);
assert(wrap->process_.data == wrap);
- wrap->object_->Set(String::New("pid"), Integer::New(wrap->process_.pid));
+ wrap->object_->Set(String::New("pid"),
+ Integer::New(wrap->process_.pid));
}
if (options.args) {
@@ -294,9 +295,14 @@ class ProcessWrap : public HandleWrap {
String::New(signo_string(term_signal))
};
+ if (exit_status == -1) {
+ SetErrno(uv_last_error(uv_default_loop()));
+ }
+
if (onexit_sym.IsEmpty()) {
onexit_sym = NODE_PSYMBOL("onexit");
}
+
MakeCallback(wrap->object_, onexit_sym, ARRAY_SIZE(argv), argv);
}
diff --git a/src/res/node_etw_provider.man b/src/res/node_etw_provider.man
index 2d96a20c3..efdc26d3d 100644
--- a/src/res/node_etw_provider.man
+++ b/src/res/node_etw_provider.man
@@ -1,15 +1,25 @@
<instrumentationManifest
- xmlns="http://schemas.microsoft.com/win/2004/08/events"
+ xmlns="http://schemas.microsoft.com/win/2004/08/events"
xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<instrumentation>
<events>
- <provider name="NodeJS-ETW-provider"
- guid="{77754E9B-264B-4D8D-B981-E4135C1ECB0C}"
- symbol="NODE_ETW_PROVIDER"
- resourceFileName="node.exe"
+ <provider name="NodeJS-ETW-provider"
+ guid="{77754E9B-264B-4D8D-B981-E4135C1ECB0C}"
+ symbol="NODE_ETW_PROVIDER"
+ resourceFileName="node.exe"
messageFileName="node.exe">
+ <tasks>
+ <task name="MethodRuntime" value="1"
+ symbol="JSCRIPT_METHOD_RUNTIME_TASK">
+ <opcodes>
+ <opcode name="MethodLoad" value="10"
+ symbol="JSCRIPT_METHOD_METHODLOAD_OPCODE"/>
+ </opcodes>
+ </task>
+ </tasks>
+
<opcodes>
<opcode name="NODE_HTTP_SERVER_REQUEST" value="10"/>
<opcode name="NODE_HTTP_SERVER_RESPONSE" value="11"/>
@@ -19,6 +29,9 @@
<opcode name="NODE_NET_STREAM_END" value="15"/>
<opcode name="NODE_GC_START" value="16"/>
<opcode name="NODE_GC_DONE" value="17"/>
+ <opcode name="NODE_V8SYMBOL_REMOVE" value="21"/>
+ <opcode name="NODE_V8SYMBOL_MOVE" value="22"/>
+ <opcode name="NODE_V8SYMBOL_RESET" value="23"/>
</opcodes>
<templates>
@@ -52,49 +65,87 @@
<data name="gctype" inType="win:UInt32" />
<data name="gccallbackflags" inType="win:UInt32" />
</template>
+
+ <template tid="V8AddressChange">
+ <data name="addr1" inType="win:Pointer" outType="win:HexInt64"/>
+ <data name="addr2" inType="win:Pointer" outType="win:HexInt64"/>
+ </template>
+
+ <template tid="MethodLoadUnload">
+ <data name="ScriptContextID" inType="win:Pointer" outType="win:HexInt64"/>
+ <data name="MethodStartAddress" inType="win:Pointer" outType="win:HexInt64" />
+ <data name="MethodSize" inType="win:UInt64" />
+ <data name="MethodID" inType="win:UInt32" />
+ <data name="MethodFlags" inType="win:UInt16" />
+ <data name="MethodAddressRangeID" inType="win:UInt16" />
+ <data name="SourceID" inType="win:UInt64" />
+ <data name="Line" inType="win:UInt32" outType="xs:unsignedInt" />
+ <data name="Column" inType="win:UInt32" outType="xs:unsignedInt" />
+ <data name="MethodName" inType="win:UnicodeString" outType="xs:string" />
+ </template>
</templates>
<events>
- <event value="1"
+ <event value="1"
opcode="NODE_HTTP_SERVER_REQUEST"
template="node_http_server_request"
symbol="NODE_HTTP_SERVER_REQUEST_EVENT"
level="win:Informational"/>
- <event value="2"
+ <event value="2"
opcode="NODE_HTTP_SERVER_RESPONSE"
template="node_connection"
symbol="NODE_HTTP_SERVER_RESPONSE_EVENT"
level="win:Informational"/>
- <event value="3"
+ <event value="3"
opcode="NODE_HTTP_CLIENT_REQUEST"
template="node_http_client_request"
symbol="NODE_HTTP_CLIENT_REQUEST_EVENT"
level="win:Informational"/>
- <event value="4"
+ <event value="4"
opcode="NODE_HTTP_CLIENT_RESPONSE"
template="node_connection"
symbol="NODE_HTTP_CLIENT_RESPONSE_EVENT"
level="win:Informational"/>
- <event value="5"
+ <event value="5"
opcode="NODE_NET_SERVER_CONNECTION"
template="node_connection"
symbol="NODE_NET_SERVER_CONNECTION_EVENT"
level="win:Informational"/>
- <event value="6"
+ <event value="6"
opcode="NODE_NET_STREAM_END"
template="node_connection"
symbol="NODE_NET_STREAM_END_EVENT"
level="win:Informational"/>
- <event value="7"
+ <event value="7"
opcode="NODE_GC_START"
template="node_gc"
symbol="NODE_GC_START_EVENT"
level="win:Informational"/>
- <event value="8"
+ <event value="8"
opcode="NODE_GC_DONE"
template="node_gc"
symbol="NODE_GC_DONE_EVENT"
level="win:Informational"/>
+ <event value="9"
+ level="win:Informational"
+ opcode="MethodLoad"
+ symbol="MethodLoad"
+ task="MethodRuntime"
+ template="MethodLoadUnload"/>
+ <event value="21"
+ opcode="NODE_V8SYMBOL_REMOVE"
+ template="V8AddressChange"
+ symbol="NODE_V8SYMBOL_REMOVE_EVENT"
+ level="win:Informational" />
+ <event value="22"
+ opcode="NODE_V8SYMBOL_MOVE"
+ template="V8AddressChange"
+ symbol="NODE_V8SYMBOL_MOVE_EVENT"
+ level="win:Informational" />
+ <event value="23"
+ opcode="NODE_V8SYMBOL_RESET"
+ symbol="NODE_V8SYMBOL_RESET_EVENT"
+ level="win:Informational" />
</events>
</provider>
</events>
diff --git a/src/res/node_perfctr_provider.man b/src/res/node_perfctr_provider.man
new file mode 100644
index 000000000..fb8e59778
--- /dev/null
+++ b/src/res/node_perfctr_provider.man
@@ -0,0 +1,107 @@
+<instrumentationManifest
+ xmlns="http://schemas.microsoft.com/win/2004/08/events"
+ xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <instrumentation>
+ <counters xmlns="http://schemas.microsoft.com/win/2005/12/counters"
+ schemaVersion="1.1">
+ <provider symbol="NodeCounterProvider"
+ applicationIdentity="node.exe"
+ providerType="userMode"
+ providerGuid="{1E2E15D7-3760-470E-8699-B9DB5248EDD5}">
+ <counterSet symbol="NodeCounterSet"
+ guid="{3A22A8EC-297C-48AC-AB15-33EC93033FD8}"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet"
+ name="Node.js"
+ description="Node.js performance counters"
+ instances="multipleAggregate">
+
+ <counter id="1"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet.httpsrvreq"
+ name="HTTP server requests"
+ description="Number of HTTP server requests"
+ type="perf_counter_counter"
+ detailLevel="standard"
+ aggregate="sum" />
+
+ <counter id="2"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet.httpsrvrsp"
+ name="HTTP server responses"
+ description="Number of HTTP server responses"
+ type="perf_counter_counter"
+ detailLevel="standard"
+ aggregate="sum" />
+
+ <counter id="3"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet.httpclireq"
+ name="HTTP client requests"
+ description="Number of HTTP client requests"
+ type="perf_counter_counter"
+ detailLevel="standard"
+ aggregate="sum" />
+
+ <counter id="4"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet.httpclirsp"
+ name="HTTP client responses"
+ description="Number of HTTP client responses"
+ type="perf_counter_counter"
+ detailLevel="standard"
+ aggregate="sum" />
+
+ <counter id="5"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet.netsrvconn"
+ name="Active server connections"
+ description="Number of server connections"
+ type="perf_counter_rawcount"
+ detailLevel="standard"
+ aggregate="sum" />
+
+ <counter id="6"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet.netbytesent"
+ name="Network bytes sent"
+ description="Number of bytes sent using TCP"
+ type="perf_counter_bulk_count"
+ detailLevel="standard"
+ defaultScale="-3"
+ aggregate="sum" />
+
+ <counter id="7"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet.netbyterecv"
+ name="Network bytes received"
+ description="Number of bytes received using TCP"
+ type="perf_counter_bulk_count"
+ detailLevel="standard"
+ defaultScale="-3"
+ aggregate="sum" />
+
+ <counter id="8"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet.gctime"
+ name="%Time in GC"
+ description="Percent of time for last GC"
+ type="perf_counter_rawcount"
+ detailLevel="standard"
+ aggregate="avg" />
+
+ <counter id="9"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet.pipebytesent"
+ name="Pipe bytes sent"
+ description="Number of bytes sent using pipe"
+ type="perf_counter_bulk_count"
+ detailLevel="standard"
+ defaultScale="-3"
+ aggregate="sum" />
+
+ <counter id="10"
+ uri="Microsoft.Windows.System.PerfCounters.NodeCounterSet.pipebyterecv"
+ name="Pipe bytes received"
+ description="Number of bytes received using pipe"
+ type="perf_counter_bulk_count"
+ detailLevel="standard"
+ defaultScale="-3"
+ aggregate="sum" />
+
+ </counterSet>
+ </provider>
+ </counters>
+ </instrumentation>
+</instrumentationManifest>
diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc
new file mode 100644
index 000000000..6d93cf096
--- /dev/null
+++ b/src/signal_wrap.cc
@@ -0,0 +1,132 @@
+// 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.
+
+#include "node.h"
+#include "handle_wrap.h"
+
+
+namespace node {
+
+using v8::Object;
+using v8::Handle;
+using v8::Local;
+using v8::Persistent;
+using v8::Value;
+using v8::HandleScope;
+using v8::FunctionTemplate;
+using v8::String;
+using v8::Function;
+using v8::TryCatch;
+using v8::Context;
+using v8::Arguments;
+using v8::Integer;
+
+static Persistent<String> onsignal_sym;
+
+
+class SignalWrap : public HandleWrap {
+ public:
+ static void Initialize(Handle<Object> target) {
+ HandleScope scope;
+
+ HandleWrap::Initialize(target);
+
+ Local<FunctionTemplate> constructor = FunctionTemplate::New(New);
+ constructor->InstanceTemplate()->SetInternalFieldCount(1);
+ constructor->SetClassName(String::NewSymbol("Signal"));
+
+ NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "ref", HandleWrap::Ref);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "unref", HandleWrap::Unref);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "start", Start);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "stop", Stop);
+
+ onsignal_sym = NODE_PSYMBOL("onsignal");
+
+ target->Set(String::NewSymbol("Signal"), constructor->GetFunction());
+ }
+
+ private:
+ static Handle<Value> New(const Arguments& args) {
+ // This constructor should not be exposed to public javascript.
+ // Therefore we assert that we are not trying to call this as a
+ // normal function.
+ assert(args.IsConstructCall());
+
+ HandleScope scope;
+ new SignalWrap(args.This());
+
+ return scope.Close(args.This());
+ }
+
+ SignalWrap(Handle<Object> object)
+ : HandleWrap(object, reinterpret_cast<uv_handle_t*>(&handle_)) {
+ int r = uv_signal_init(uv_default_loop(), &handle_);
+ assert(r == 0);
+ }
+
+ ~SignalWrap() {
+ }
+
+ static Handle<Value> Start(const Arguments& args) {
+ HandleScope scope;
+
+ UNWRAP(SignalWrap)
+
+ int signum = args[0]->Int32Value();
+
+ int r = uv_signal_start(&wrap->handle_, OnSignal, signum);
+
+ if (r) SetErrno(uv_last_error(uv_default_loop()));
+
+ return scope.Close(Integer::New(r));
+ }
+
+ static Handle<Value> Stop(const Arguments& args) {
+ HandleScope scope;
+
+ UNWRAP(SignalWrap)
+
+ int r = uv_signal_stop(&wrap->handle_);
+
+ if (r) SetErrno(uv_last_error(uv_default_loop()));
+
+ return scope.Close(Integer::New(r));
+ }
+
+ static void OnSignal(uv_signal_t* handle, int signum) {
+ HandleScope scope;
+
+ SignalWrap* wrap = container_of(handle, SignalWrap, handle_);
+ assert(wrap);
+
+ Local<Value> argv[1] = { Integer::New(signum) };
+ MakeCallback(wrap->object_, onsignal_sym, ARRAY_SIZE(argv), argv);
+ }
+
+ uv_signal_t handle_;
+};
+
+
+} // namespace node
+
+
+NODE_MODULE(node_signal_wrap, node::SignalWrap::Initialize)
diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc
index e79d212c4..544c1f8ce 100644
--- a/src/stream_wrap.cc
+++ b/src/stream_wrap.cc
@@ -27,6 +27,8 @@
#include "pipe_wrap.h"
#include "tcp_wrap.h"
#include "req_wrap.h"
+#include "udp_wrap.h"
+#include "node_counters.h"
#include <stdlib.h> // abort()
#include <limits.h> // INT_MAX
@@ -36,22 +38,22 @@
namespace node {
-using v8::Object;
+using v8::AccessorInfo;
+using v8::Arguments;
+using v8::Context;
+using v8::Exception;
+using v8::Function;
+using v8::FunctionTemplate;
using v8::Handle;
+using v8::HandleScope;
+using v8::Integer;
using v8::Local;
+using v8::Number;
+using v8::Object;
using v8::Persistent;
-using v8::Value;
-using v8::HandleScope;
-using v8::FunctionTemplate;
using v8::String;
-using v8::Function;
using v8::TryCatch;
-using v8::Context;
-using v8::Arguments;
-using v8::Integer;
-using v8::Number;
-using v8::Exception;
-
+using v8::Value;
typedef class ReqWrap<uv_shutdown_t> ShutdownWrap;
@@ -76,6 +78,7 @@ static Persistent<String> bytes_sym;
static Persistent<String> write_queue_size_sym;
static Persistent<String> onread_sym;
static Persistent<String> oncomplete_sym;
+static Persistent<String> handle_sym;
static SlabAllocator* slab_allocator;
static bool initialized;
@@ -114,16 +117,30 @@ StreamWrap::StreamWrap(Handle<Object> object, uv_stream_t* stream)
}
+Handle<Value> StreamWrap::GetFD(Local<String>, const AccessorInfo& args) {
+#if defined(_WIN32)
+ return v8::Null();
+#else
+ HandleScope scope;
+ UNWRAP(StreamWrap)
+ int fd = -1;
+ if (wrap != NULL && wrap->stream_ != NULL) fd = wrap->stream_->io_watcher.fd;
+ return scope.Close(Integer::New(fd));
+#endif
+}
+
+
void StreamWrap::SetHandle(uv_handle_t* h) {
HandleWrap::SetHandle(h);
- stream_ = (uv_stream_t*)h;
+ stream_ = reinterpret_cast<uv_stream_t*>(h);
stream_->data = this;
}
void StreamWrap::UpdateWriteQueueSize() {
HandleScope scope;
- object_->Set(write_queue_size_sym, Integer::New(stream_->write_queue_size));
+ object_->Set(write_queue_size_sym,
+ Integer::New(stream_->write_queue_size));
}
@@ -170,6 +187,28 @@ uv_buf_t StreamWrap::OnAlloc(uv_handle_t* handle, size_t suggested_size) {
}
+template <class WrapType, class UVType>
+static Local<Object> AcceptHandle(uv_stream_t* pipe) {
+ HandleScope scope;
+ Local<Object> wrap_obj;
+ WrapType* wrap;
+ UVType* handle;
+
+ wrap_obj = WrapType::Instantiate();
+ if (wrap_obj.IsEmpty())
+ return Local<Object>();
+
+ wrap = static_cast<WrapType*>(
+ wrap_obj->GetPointerFromInternalField(0));
+ handle = wrap->UVHandle();
+
+ if (uv_accept(pipe, reinterpret_cast<uv_stream_t*>(handle)))
+ abort();
+
+ return scope.Close(wrap_obj);
+}
+
+
void StreamWrap::OnReadCommon(uv_stream_t* handle, ssize_t nread,
uv_buf_t buf, uv_handle_type pending) {
HandleScope scope;
@@ -209,23 +248,26 @@ void StreamWrap::OnReadCommon(uv_stream_t* handle, ssize_t nread,
Local<Object> pending_obj;
if (pending == UV_TCP) {
- pending_obj = TCPWrap::Instantiate();
+ pending_obj = AcceptHandle<TCPWrap, uv_tcp_t>(handle);
} else if (pending == UV_NAMED_PIPE) {
- pending_obj = PipeWrap::Instantiate();
+ pending_obj = AcceptHandle<PipeWrap, uv_pipe_t>(handle);
+ } else if (pending == UV_UDP) {
+ pending_obj = AcceptHandle<UDPWrap, uv_udp_t>(handle);
} else {
- // We only support sending UV_TCP and UV_NAMED_PIPE right now.
assert(pending == UV_UNKNOWN_HANDLE);
}
if (!pending_obj.IsEmpty()) {
- assert(pending_obj->InternalFieldCount() > 0);
- StreamWrap* pending_wrap =
- static_cast<StreamWrap*>(pending_obj->GetPointerFromInternalField(0));
- if (uv_accept(handle, pending_wrap->GetStream())) abort();
argv[3] = pending_obj;
argc++;
}
+ if (wrap->stream_->type == UV_TCP) {
+ NODE_COUNT_NET_BYTES_RECV(nread);
+ } else if (wrap->stream_->type == UV_NAMED_PIPE) {
+ NODE_COUNT_PIPE_BYTES_RECV(nread);
+ }
+
MakeCallback(wrap->object_, onread_sym, argc, argv);
}
@@ -237,7 +279,7 @@ void StreamWrap::OnRead(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
void StreamWrap::OnRead2(uv_pipe_t* handle, ssize_t nread, uv_buf_t buf,
uv_handle_type pending) {
- OnReadCommon((uv_stream_t*)handle, nread, buf, pending);
+ OnReadCommon(reinterpret_cast<uv_stream_t*>(handle), nread, buf, pending);
}
@@ -251,14 +293,6 @@ Handle<Value> StreamWrap::WriteBuffer(const Arguments& args) {
Local<Object> buffer_obj = args[0]->ToObject();
size_t offset = 0;
size_t length = Buffer::Length(buffer_obj);
-
- if (length > INT_MAX) {
- uv_err_t err;
- err.code = UV_ENOBUFS;
- SetErrno(err);
- return scope.Close(v8::Null());
- }
-
char* storage = new char[sizeof(WriteWrap)];
WriteWrap* req_wrap = new (storage) WriteWrap();
@@ -275,7 +309,8 @@ Handle<Value> StreamWrap::WriteBuffer(const Arguments& args) {
StreamWrap::AfterWrite);
req_wrap->Dispatched();
- req_wrap->object_->Set(bytes_sym, Number::New((uint32_t) length));
+ req_wrap->object_->Set(bytes_sym,
+ Integer::NewFromUnsigned(length));
wrap->UpdateWriteQueueSize();
@@ -285,6 +320,12 @@ Handle<Value> StreamWrap::WriteBuffer(const Arguments& args) {
delete[] storage;
return scope.Close(v8::Null());
} else {
+ if (wrap->stream_->type == UV_TCP) {
+ NODE_COUNT_NET_BYTES_SENT(length);
+ } else if (wrap->stream_->type == UV_NAMED_PIPE) {
+ NODE_COUNT_PIPE_BYTES_SENT(length);
+ }
+
return scope.Close(req_wrap->object_);
}
}
@@ -389,21 +430,29 @@ Handle<Value> StreamWrap::WriteStringImpl(const Arguments& args) {
StreamWrap::AfterWrite);
} else {
- uv_stream_t* send_stream = NULL;
+ uv_handle_t* send_handle = NULL;
if (args[1]->IsObject()) {
- Local<Object> send_stream_obj = args[1]->ToObject();
- assert(send_stream_obj->InternalFieldCount() > 0);
- StreamWrap* send_stream_wrap = static_cast<StreamWrap*>(
- send_stream_obj->GetPointerFromInternalField(0));
- send_stream = send_stream_wrap->GetStream();
+ Local<Object> send_handle_obj = args[1]->ToObject();
+ assert(send_handle_obj->InternalFieldCount() > 0);
+ HandleWrap* send_handle_wrap = static_cast<HandleWrap*>(
+ send_handle_obj->GetPointerFromInternalField(0));
+ send_handle = send_handle_wrap->GetHandle();
+
+ // Reference StreamWrap instance to prevent it from being garbage
+ // collected before `AfterWrite` is called.
+ if (handle_sym.IsEmpty()) {
+ handle_sym = NODE_PSYMBOL("handle");
+ }
+ assert(!req_wrap->object_.IsEmpty());
+ req_wrap->object_->Set(handle_sym, send_handle_obj);
}
r = uv_write2(&req_wrap->req_,
wrap->stream_,
&buf,
1,
- send_stream,
+ reinterpret_cast<uv_stream_t*>(send_handle),
StreamWrap::AfterWrite);
}
@@ -418,6 +467,12 @@ Handle<Value> StreamWrap::WriteStringImpl(const Arguments& args) {
delete[] storage;
return scope.Close(v8::Null());
} else {
+ if (wrap->stream_->type == UV_TCP) {
+ NODE_COUNT_NET_BYTES_SENT(buf.len);
+ } else if (wrap->stream_->type == UV_NAMED_PIPE) {
+ NODE_COUNT_PIPE_BYTES_SENT(buf.len);
+ }
+
return scope.Close(req_wrap->object_);
}
}
@@ -448,6 +503,11 @@ void StreamWrap::AfterWrite(uv_write_t* req, int status) {
assert(req_wrap->object_.IsEmpty() == false);
assert(wrap->object_.IsEmpty() == false);
+ // Unref handle property
+ if (!handle_sym.IsEmpty()) {
+ req_wrap->object_->Delete(handle_sym);
+ }
+
if (status) {
SetErrno(uv_last_error(uv_default_loop()));
}
diff --git a/src/stream_wrap.h b/src/stream_wrap.h
index c51083c09..77bd234a9 100644
--- a/src/stream_wrap.h
+++ b/src/stream_wrap.h
@@ -42,6 +42,9 @@ class StreamWrap : public HandleWrap {
static void Initialize(v8::Handle<v8::Object> target);
+ static v8::Handle<v8::Value> GetFD(v8::Local<v8::String>,
+ const v8::AccessorInfo&);
+
// JavaScript functions
static v8::Handle<v8::Value> ReadStart(const v8::Arguments& args);
static v8::Handle<v8::Value> ReadStop(const v8::Arguments& args);
diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc
index 5e6f1c2ec..4c55f2eff 100644
--- a/src/tcp_wrap.cc
+++ b/src/tcp_wrap.cc
@@ -28,20 +28,6 @@
#include <stdlib.h>
-// Temporary hack: libuv should provide uv_inet_pton and uv_inet_ntop.
-#if defined(__MINGW32__) || defined(_MSC_VER)
- extern "C" {
-# include <inet_net_pton.h>
-# include <inet_ntop.h>
- }
-# define uv_inet_pton ares_inet_pton
-# define uv_inet_ntop ares_inet_ntop
-
-#else // __POSIX__
-# include <arpa/inet.h>
-# define uv_inet_pton inet_pton
-# define uv_inet_ntop inet_ntop
-#endif
namespace node {
@@ -53,9 +39,10 @@ using v8::Handle;
using v8::HandleScope;
using v8::Integer;
using v8::Local;
-using v8::Object;
using v8::Null;
+using v8::Object;
using v8::Persistent;
+using v8::PropertyAttribute;
using v8::String;
using v8::TryCatch;
using v8::Undefined;
@@ -94,8 +81,20 @@ void TCPWrap::Initialize(Handle<Object> target) {
t->InstanceTemplate()->SetInternalFieldCount(1);
+ enum PropertyAttribute attributes =
+ static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
+ t->InstanceTemplate()->SetAccessor(String::New("fd"),
+ StreamWrap::GetFD,
+ NULL,
+ Handle<Value>(),
+ v8::DEFAULT,
+ attributes);
+
NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);
+ NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref);
+ NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);
+
NODE_SET_PROTOTYPE_METHOD(t, "readStart", StreamWrap::ReadStart);
NODE_SET_PROTOTYPE_METHOD(t, "readStop", StreamWrap::ReadStop);
NODE_SET_PROTOTYPE_METHOD(t, "shutdown", StreamWrap::Shutdown);
@@ -327,8 +326,8 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) {
// Unwrap the client javascript object.
assert(client_obj->InternalFieldCount() > 0);
- TCPWrap* client_wrap =
- static_cast<TCPWrap*>(client_obj->GetPointerFromInternalField(0));
+ TCPWrap* client_wrap = static_cast<TCPWrap*>(
+ client_obj->GetPointerFromInternalField(0));
if (uv_accept(handle, (uv_stream_t*)&client_wrap->handle_)) return;
diff --git a/src/timer_wrap.cc b/src/timer_wrap.cc
index 4332a68ba..92964af7a 100644
--- a/src/timer_wrap.cc
+++ b/src/timer_wrap.cc
@@ -52,6 +52,8 @@ class TimerWrap : public HandleWrap {
constructor->SetClassName(String::NewSymbol("Timer"));
NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "ref", HandleWrap::Ref);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "unref", HandleWrap::Unref);
NODE_SET_PROTOTYPE_METHOD(constructor, "start", Start);
NODE_SET_PROTOTYPE_METHOD(constructor, "stop", Stop);
diff --git a/src/tree.h b/src/tree.h
new file mode 100644
index 000000000..f936416e3
--- /dev/null
+++ b/src/tree.h
@@ -0,0 +1,768 @@
+/*-
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef UV_TREE_H_
+#define UV_TREE_H_
+
+#ifndef UV__UNUSED
+# if __GNUC__
+# define UV__UNUSED __attribute__((unused))
+# else
+# define UV__UNUSED
+# endif
+#endif
+
+/*
+ * This file defines data structures for different types of trees:
+ * splay trees and red-black trees.
+ *
+ * A splay tree is a self-organizing data structure. Every operation
+ * on the tree causes a splay to happen. The splay moves the requested
+ * node to the root of the tree and partly rebalances it.
+ *
+ * This has the benefit that request locality causes faster lookups as
+ * the requested nodes move to the top of the tree. On the other hand,
+ * every lookup causes memory writes.
+ *
+ * The Balance Theorem bounds the total access time for m operations
+ * and n inserts on an initially empty tree as O((m + n)lg n). The
+ * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
+ *
+ * A red-black tree is a binary search tree with the node color as an
+ * extra attribute. It fulfills a set of conditions:
+ * - every search path from the root to a leaf consists of the
+ * same number of black nodes,
+ * - each red node (except for the root) has a black parent,
+ * - each leaf node is black.
+ *
+ * Every operation on a red-black tree is bounded as O(lg n).
+ * The maximum height of a red-black tree is 2lg (n+1).
+ */
+
+#define SPLAY_HEAD(name, type) \
+struct name { \
+ struct type *sph_root; /* root of the tree */ \
+}
+
+#define SPLAY_INITIALIZER(root) \
+ { NULL }
+
+#define SPLAY_INIT(root) do { \
+ (root)->sph_root = NULL; \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ENTRY(type) \
+struct { \
+ struct type *spe_left; /* left element */ \
+ struct type *spe_right; /* right element */ \
+}
+
+#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
+#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
+#define SPLAY_ROOT(head) (head)->sph_root
+#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
+
+/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
+#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
+ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
+ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
+ (head)->sph_root = tmp; \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
+ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
+ SPLAY_LEFT(tmp, field) = (head)->sph_root; \
+ (head)->sph_root = tmp; \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_LINKLEFT(head, tmp, field) do { \
+ SPLAY_LEFT(tmp, field) = (head)->sph_root; \
+ tmp = (head)->sph_root; \
+ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_LINKRIGHT(head, tmp, field) do { \
+ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
+ tmp = (head)->sph_root; \
+ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
+ SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
+ SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field); \
+ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
+ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
+} while (/*CONSTCOND*/ 0)
+
+/* Generates prototypes and inline functions */
+
+#define SPLAY_PROTOTYPE(name, type, field, cmp) \
+void name##_SPLAY(struct name *, struct type *); \
+void name##_SPLAY_MINMAX(struct name *, int); \
+struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
+struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
+ \
+/* Finds the node with the same key as elm */ \
+static __inline struct type * \
+name##_SPLAY_FIND(struct name *head, struct type *elm) \
+{ \
+ if (SPLAY_EMPTY(head)) \
+ return(NULL); \
+ name##_SPLAY(head, elm); \
+ if ((cmp)(elm, (head)->sph_root) == 0) \
+ return (head->sph_root); \
+ return (NULL); \
+} \
+ \
+static __inline struct type * \
+name##_SPLAY_NEXT(struct name *head, struct type *elm) \
+{ \
+ name##_SPLAY(head, elm); \
+ if (SPLAY_RIGHT(elm, field) != NULL) { \
+ elm = SPLAY_RIGHT(elm, field); \
+ while (SPLAY_LEFT(elm, field) != NULL) { \
+ elm = SPLAY_LEFT(elm, field); \
+ } \
+ } else \
+ elm = NULL; \
+ return (elm); \
+} \
+ \
+static __inline struct type * \
+name##_SPLAY_MIN_MAX(struct name *head, int val) \
+{ \
+ name##_SPLAY_MINMAX(head, val); \
+ return (SPLAY_ROOT(head)); \
+}
+
+/* Main splay operation.
+ * Moves node close to the key of elm to top
+ */
+#define SPLAY_GENERATE(name, type, field, cmp) \
+struct type * \
+name##_SPLAY_INSERT(struct name *head, struct type *elm) \
+{ \
+ if (SPLAY_EMPTY(head)) { \
+ SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
+ } else { \
+ int __comp; \
+ name##_SPLAY(head, elm); \
+ __comp = (cmp)(elm, (head)->sph_root); \
+ if(__comp < 0) { \
+ SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); \
+ SPLAY_RIGHT(elm, field) = (head)->sph_root; \
+ SPLAY_LEFT((head)->sph_root, field) = NULL; \
+ } else if (__comp > 0) { \
+ SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); \
+ SPLAY_LEFT(elm, field) = (head)->sph_root; \
+ SPLAY_RIGHT((head)->sph_root, field) = NULL; \
+ } else \
+ return ((head)->sph_root); \
+ } \
+ (head)->sph_root = (elm); \
+ return (NULL); \
+} \
+ \
+struct type * \
+name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
+{ \
+ struct type *__tmp; \
+ if (SPLAY_EMPTY(head)) \
+ return (NULL); \
+ name##_SPLAY(head, elm); \
+ if ((cmp)(elm, (head)->sph_root) == 0) { \
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
+ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
+ } else { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
+ name##_SPLAY(head, elm); \
+ SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
+ } \
+ return (elm); \
+ } \
+ return (NULL); \
+} \
+ \
+void \
+name##_SPLAY(struct name *head, struct type *elm) \
+{ \
+ struct type __node, *__left, *__right, *__tmp; \
+ int __comp; \
+ \
+ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
+ __left = __right = &__node; \
+ \
+ while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \
+ if (__comp < 0) { \
+ __tmp = SPLAY_LEFT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if ((cmp)(elm, __tmp) < 0){ \
+ SPLAY_ROTATE_RIGHT(head, __tmp, field); \
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
+ break; \
+ } \
+ SPLAY_LINKLEFT(head, __right, field); \
+ } else if (__comp > 0) { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if ((cmp)(elm, __tmp) > 0){ \
+ SPLAY_ROTATE_LEFT(head, __tmp, field); \
+ if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
+ break; \
+ } \
+ SPLAY_LINKRIGHT(head, __left, field); \
+ } \
+ } \
+ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
+} \
+ \
+/* Splay with either the minimum or the maximum element \
+ * Used to find minimum or maximum element in tree. \
+ */ \
+void name##_SPLAY_MINMAX(struct name *head, int __comp) \
+{ \
+ struct type __node, *__left, *__right, *__tmp; \
+ \
+ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
+ __left = __right = &__node; \
+ \
+ while (1) { \
+ if (__comp < 0) { \
+ __tmp = SPLAY_LEFT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if (__comp < 0){ \
+ SPLAY_ROTATE_RIGHT(head, __tmp, field); \
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
+ break; \
+ } \
+ SPLAY_LINKLEFT(head, __right, field); \
+ } else if (__comp > 0) { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if (__comp > 0) { \
+ SPLAY_ROTATE_LEFT(head, __tmp, field); \
+ if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
+ break; \
+ } \
+ SPLAY_LINKRIGHT(head, __left, field); \
+ } \
+ } \
+ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
+}
+
+#define SPLAY_NEGINF -1
+#define SPLAY_INF 1
+
+#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
+#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
+#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
+#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
+#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
+ : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
+#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
+ : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
+
+#define SPLAY_FOREACH(x, name, head) \
+ for ((x) = SPLAY_MIN(name, head); \
+ (x) != NULL; \
+ (x) = SPLAY_NEXT(name, head, x))
+
+/* Macros that define a red-black tree */
+#define RB_HEAD(name, type) \
+struct name { \
+ struct type *rbh_root; /* root of the tree */ \
+}
+
+#define RB_INITIALIZER(root) \
+ { NULL }
+
+#define RB_INIT(root) do { \
+ (root)->rbh_root = NULL; \
+} while (/*CONSTCOND*/ 0)
+
+#define RB_BLACK 0
+#define RB_RED 1
+#define RB_ENTRY(type) \
+struct { \
+ struct type *rbe_left; /* left element */ \
+ struct type *rbe_right; /* right element */ \
+ struct type *rbe_parent; /* parent element */ \
+ int rbe_color; /* node color */ \
+}
+
+#define RB_LEFT(elm, field) (elm)->field.rbe_left
+#define RB_RIGHT(elm, field) (elm)->field.rbe_right
+#define RB_PARENT(elm, field) (elm)->field.rbe_parent
+#define RB_COLOR(elm, field) (elm)->field.rbe_color
+#define RB_ROOT(head) (head)->rbh_root
+#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
+
+#define RB_SET(elm, parent, field) do { \
+ RB_PARENT(elm, field) = parent; \
+ RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
+ RB_COLOR(elm, field) = RB_RED; \
+} while (/*CONSTCOND*/ 0)
+
+#define RB_SET_BLACKRED(black, red, field) do { \
+ RB_COLOR(black, field) = RB_BLACK; \
+ RB_COLOR(red, field) = RB_RED; \
+} while (/*CONSTCOND*/ 0)
+
+#ifndef RB_AUGMENT
+#define RB_AUGMENT(x) do {} while (0)
+#endif
+
+#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
+ (tmp) = RB_RIGHT(elm, field); \
+ if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
+ RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
+ } \
+ RB_AUGMENT(elm); \
+ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
+ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
+ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
+ else \
+ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
+ } else \
+ (head)->rbh_root = (tmp); \
+ RB_LEFT(tmp, field) = (elm); \
+ RB_PARENT(elm, field) = (tmp); \
+ RB_AUGMENT(tmp); \
+ if ((RB_PARENT(tmp, field))) \
+ RB_AUGMENT(RB_PARENT(tmp, field)); \
+} while (/*CONSTCOND*/ 0)
+
+#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
+ (tmp) = RB_LEFT(elm, field); \
+ if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
+ RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
+ } \
+ RB_AUGMENT(elm); \
+ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
+ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
+ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
+ else \
+ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
+ } else \
+ (head)->rbh_root = (tmp); \
+ RB_RIGHT(tmp, field) = (elm); \
+ RB_PARENT(elm, field) = (tmp); \
+ RB_AUGMENT(tmp); \
+ if ((RB_PARENT(tmp, field))) \
+ RB_AUGMENT(RB_PARENT(tmp, field)); \
+} while (/*CONSTCOND*/ 0)
+
+/* Generates prototypes and inline functions */
+#define RB_PROTOTYPE(name, type, field, cmp) \
+ RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
+#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
+ RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
+#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
+attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \
+attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
+attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
+attr struct type *name##_RB_INSERT(struct name *, struct type *); \
+attr struct type *name##_RB_FIND(struct name *, struct type *); \
+attr struct type *name##_RB_NFIND(struct name *, struct type *); \
+attr struct type *name##_RB_NEXT(struct type *); \
+attr struct type *name##_RB_PREV(struct type *); \
+attr struct type *name##_RB_MINMAX(struct name *, int); \
+ \
+
+/* Main rb operation.
+ * Moves node close to the key of elm to top
+ */
+#define RB_GENERATE(name, type, field, cmp) \
+ RB_GENERATE_INTERNAL(name, type, field, cmp,)
+#define RB_GENERATE_STATIC(name, type, field, cmp) \
+ RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
+#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
+attr void \
+name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
+{ \
+ struct type *parent, *gparent, *tmp; \
+ while ((parent = RB_PARENT(elm, field)) != NULL && \
+ RB_COLOR(parent, field) == RB_RED) { \
+ gparent = RB_PARENT(parent, field); \
+ if (parent == RB_LEFT(gparent, field)) { \
+ tmp = RB_RIGHT(gparent, field); \
+ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
+ RB_COLOR(tmp, field) = RB_BLACK; \
+ RB_SET_BLACKRED(parent, gparent, field); \
+ elm = gparent; \
+ continue; \
+ } \
+ if (RB_RIGHT(parent, field) == elm) { \
+ RB_ROTATE_LEFT(head, parent, tmp, field); \
+ tmp = parent; \
+ parent = elm; \
+ elm = tmp; \
+ } \
+ RB_SET_BLACKRED(parent, gparent, field); \
+ RB_ROTATE_RIGHT(head, gparent, tmp, field); \
+ } else { \
+ tmp = RB_LEFT(gparent, field); \
+ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
+ RB_COLOR(tmp, field) = RB_BLACK; \
+ RB_SET_BLACKRED(parent, gparent, field); \
+ elm = gparent; \
+ continue; \
+ } \
+ if (RB_LEFT(parent, field) == elm) { \
+ RB_ROTATE_RIGHT(head, parent, tmp, field); \
+ tmp = parent; \
+ parent = elm; \
+ elm = tmp; \
+ } \
+ RB_SET_BLACKRED(parent, gparent, field); \
+ RB_ROTATE_LEFT(head, gparent, tmp, field); \
+ } \
+ } \
+ RB_COLOR(head->rbh_root, field) = RB_BLACK; \
+} \
+ \
+attr void \
+name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, \
+ struct type *elm) \
+{ \
+ struct type *tmp; \
+ while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
+ elm != RB_ROOT(head)) { \
+ if (RB_LEFT(parent, field) == elm) { \
+ tmp = RB_RIGHT(parent, field); \
+ if (RB_COLOR(tmp, field) == RB_RED) { \
+ RB_SET_BLACKRED(tmp, parent, field); \
+ RB_ROTATE_LEFT(head, parent, tmp, field); \
+ tmp = RB_RIGHT(parent, field); \
+ } \
+ if ((RB_LEFT(tmp, field) == NULL || \
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
+ (RB_RIGHT(tmp, field) == NULL || \
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
+ RB_COLOR(tmp, field) = RB_RED; \
+ elm = parent; \
+ parent = RB_PARENT(elm, field); \
+ } else { \
+ if (RB_RIGHT(tmp, field) == NULL || \
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { \
+ struct type *oleft; \
+ if ((oleft = RB_LEFT(tmp, field)) \
+ != NULL) \
+ RB_COLOR(oleft, field) = RB_BLACK; \
+ RB_COLOR(tmp, field) = RB_RED; \
+ RB_ROTATE_RIGHT(head, tmp, oleft, field); \
+ tmp = RB_RIGHT(parent, field); \
+ } \
+ RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
+ RB_COLOR(parent, field) = RB_BLACK; \
+ if (RB_RIGHT(tmp, field)) \
+ RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \
+ RB_ROTATE_LEFT(head, parent, tmp, field); \
+ elm = RB_ROOT(head); \
+ break; \
+ } \
+ } else { \
+ tmp = RB_LEFT(parent, field); \
+ if (RB_COLOR(tmp, field) == RB_RED) { \
+ RB_SET_BLACKRED(tmp, parent, field); \
+ RB_ROTATE_RIGHT(head, parent, tmp, field); \
+ tmp = RB_LEFT(parent, field); \
+ } \
+ if ((RB_LEFT(tmp, field) == NULL || \
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
+ (RB_RIGHT(tmp, field) == NULL || \
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
+ RB_COLOR(tmp, field) = RB_RED; \
+ elm = parent; \
+ parent = RB_PARENT(elm, field); \
+ } else { \
+ if (RB_LEFT(tmp, field) == NULL || \
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { \
+ struct type *oright; \
+ if ((oright = RB_RIGHT(tmp, field)) \
+ != NULL) \
+ RB_COLOR(oright, field) = RB_BLACK; \
+ RB_COLOR(tmp, field) = RB_RED; \
+ RB_ROTATE_LEFT(head, tmp, oright, field); \
+ tmp = RB_LEFT(parent, field); \
+ } \
+ RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
+ RB_COLOR(parent, field) = RB_BLACK; \
+ if (RB_LEFT(tmp, field)) \
+ RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \
+ RB_ROTATE_RIGHT(head, parent, tmp, field); \
+ elm = RB_ROOT(head); \
+ break; \
+ } \
+ } \
+ } \
+ if (elm) \
+ RB_COLOR(elm, field) = RB_BLACK; \
+} \
+ \
+attr struct type * \
+name##_RB_REMOVE(struct name *head, struct type *elm) \
+{ \
+ struct type *child, *parent, *old = elm; \
+ int color; \
+ if (RB_LEFT(elm, field) == NULL) \
+ child = RB_RIGHT(elm, field); \
+ else if (RB_RIGHT(elm, field) == NULL) \
+ child = RB_LEFT(elm, field); \
+ else { \
+ struct type *left; \
+ elm = RB_RIGHT(elm, field); \
+ while ((left = RB_LEFT(elm, field)) != NULL) \
+ elm = left; \
+ child = RB_RIGHT(elm, field); \
+ parent = RB_PARENT(elm, field); \
+ color = RB_COLOR(elm, field); \
+ if (child) \
+ RB_PARENT(child, field) = parent; \
+ if (parent) { \
+ if (RB_LEFT(parent, field) == elm) \
+ RB_LEFT(parent, field) = child; \
+ else \
+ RB_RIGHT(parent, field) = child; \
+ RB_AUGMENT(parent); \
+ } else \
+ RB_ROOT(head) = child; \
+ if (RB_PARENT(elm, field) == old) \
+ parent = elm; \
+ (elm)->field = (old)->field; \
+ if (RB_PARENT(old, field)) { \
+ if (RB_LEFT(RB_PARENT(old, field), field) == old) \
+ RB_LEFT(RB_PARENT(old, field), field) = elm; \
+ else \
+ RB_RIGHT(RB_PARENT(old, field), field) = elm; \
+ RB_AUGMENT(RB_PARENT(old, field)); \
+ } else \
+ RB_ROOT(head) = elm; \
+ RB_PARENT(RB_LEFT(old, field), field) = elm; \
+ if (RB_RIGHT(old, field)) \
+ RB_PARENT(RB_RIGHT(old, field), field) = elm; \
+ if (parent) { \
+ left = parent; \
+ do { \
+ RB_AUGMENT(left); \
+ } while ((left = RB_PARENT(left, field)) != NULL); \
+ } \
+ goto color; \
+ } \
+ parent = RB_PARENT(elm, field); \
+ color = RB_COLOR(elm, field); \
+ if (child) \
+ RB_PARENT(child, field) = parent; \
+ if (parent) { \
+ if (RB_LEFT(parent, field) == elm) \
+ RB_LEFT(parent, field) = child; \
+ else \
+ RB_RIGHT(parent, field) = child; \
+ RB_AUGMENT(parent); \
+ } else \
+ RB_ROOT(head) = child; \
+color: \
+ if (color == RB_BLACK) \
+ name##_RB_REMOVE_COLOR(head, parent, child); \
+ return (old); \
+} \
+ \
+/* Inserts a node into the RB tree */ \
+attr struct type * \
+name##_RB_INSERT(struct name *head, struct type *elm) \
+{ \
+ struct type *tmp; \
+ struct type *parent = NULL; \
+ int comp = 0; \
+ tmp = RB_ROOT(head); \
+ while (tmp) { \
+ parent = tmp; \
+ comp = (cmp)(elm, parent); \
+ if (comp < 0) \
+ tmp = RB_LEFT(tmp, field); \
+ else if (comp > 0) \
+ tmp = RB_RIGHT(tmp, field); \
+ else \
+ return (tmp); \
+ } \
+ RB_SET(elm, parent, field); \
+ if (parent != NULL) { \
+ if (comp < 0) \
+ RB_LEFT(parent, field) = elm; \
+ else \
+ RB_RIGHT(parent, field) = elm; \
+ RB_AUGMENT(parent); \
+ } else \
+ RB_ROOT(head) = elm; \
+ name##_RB_INSERT_COLOR(head, elm); \
+ return (NULL); \
+} \
+ \
+/* Finds the node with the same key as elm */ \
+attr struct type * \
+name##_RB_FIND(struct name *head, struct type *elm) \
+{ \
+ struct type *tmp = RB_ROOT(head); \
+ int comp; \
+ while (tmp) { \
+ comp = cmp(elm, tmp); \
+ if (comp < 0) \
+ tmp = RB_LEFT(tmp, field); \
+ else if (comp > 0) \
+ tmp = RB_RIGHT(tmp, field); \
+ else \
+ return (tmp); \
+ } \
+ return (NULL); \
+} \
+ \
+/* Finds the first node greater than or equal to the search key */ \
+attr struct type * \
+name##_RB_NFIND(struct name *head, struct type *elm) \
+{ \
+ struct type *tmp = RB_ROOT(head); \
+ struct type *res = NULL; \
+ int comp; \
+ while (tmp) { \
+ comp = cmp(elm, tmp); \
+ if (comp < 0) { \
+ res = tmp; \
+ tmp = RB_LEFT(tmp, field); \
+ } \
+ else if (comp > 0) \
+ tmp = RB_RIGHT(tmp, field); \
+ else \
+ return (tmp); \
+ } \
+ return (res); \
+} \
+ \
+/* ARGSUSED */ \
+attr struct type * \
+name##_RB_NEXT(struct type *elm) \
+{ \
+ if (RB_RIGHT(elm, field)) { \
+ elm = RB_RIGHT(elm, field); \
+ while (RB_LEFT(elm, field)) \
+ elm = RB_LEFT(elm, field); \
+ } else { \
+ if (RB_PARENT(elm, field) && \
+ (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
+ elm = RB_PARENT(elm, field); \
+ else { \
+ while (RB_PARENT(elm, field) && \
+ (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
+ elm = RB_PARENT(elm, field); \
+ elm = RB_PARENT(elm, field); \
+ } \
+ } \
+ return (elm); \
+} \
+ \
+/* ARGSUSED */ \
+attr struct type * \
+name##_RB_PREV(struct type *elm) \
+{ \
+ if (RB_LEFT(elm, field)) { \
+ elm = RB_LEFT(elm, field); \
+ while (RB_RIGHT(elm, field)) \
+ elm = RB_RIGHT(elm, field); \
+ } else { \
+ if (RB_PARENT(elm, field) && \
+ (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
+ elm = RB_PARENT(elm, field); \
+ else { \
+ while (RB_PARENT(elm, field) && \
+ (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
+ elm = RB_PARENT(elm, field); \
+ elm = RB_PARENT(elm, field); \
+ } \
+ } \
+ return (elm); \
+} \
+ \
+attr struct type * \
+name##_RB_MINMAX(struct name *head, int val) \
+{ \
+ struct type *tmp = RB_ROOT(head); \
+ struct type *parent = NULL; \
+ while (tmp) { \
+ parent = tmp; \
+ if (val < 0) \
+ tmp = RB_LEFT(tmp, field); \
+ else \
+ tmp = RB_RIGHT(tmp, field); \
+ } \
+ return (parent); \
+}
+
+#define RB_NEGINF -1
+#define RB_INF 1
+
+#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
+#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
+#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
+#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
+#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
+#define RB_PREV(name, x, y) name##_RB_PREV(y)
+#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
+#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
+
+#define RB_FOREACH(x, name, head) \
+ for ((x) = RB_MIN(name, head); \
+ (x) != NULL; \
+ (x) = name##_RB_NEXT(x))
+
+#define RB_FOREACH_FROM(x, name, y) \
+ for ((x) = (y); \
+ ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
+ (x) = (y))
+
+#define RB_FOREACH_SAFE(x, name, head, y) \
+ for ((x) = RB_MIN(name, head); \
+ ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
+ (x) = (y))
+
+#define RB_FOREACH_REVERSE(x, name, head) \
+ for ((x) = RB_MAX(name, head); \
+ (x) != NULL; \
+ (x) = name##_RB_PREV(x))
+
+#define RB_FOREACH_REVERSE_FROM(x, name, y) \
+ for ((x) = (y); \
+ ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
+ (x) = (y))
+
+#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \
+ for ((x) = RB_MAX(name, head); \
+ ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
+ (x) = (y))
+
+#endif /* UV_TREE_H_ */
diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc
index fde871759..4be53c8e7 100644
--- a/src/tty_wrap.cc
+++ b/src/tty_wrap.cc
@@ -28,20 +28,21 @@
namespace node {
-using v8::Object;
+using v8::Arguments;
+using v8::Context;
+using v8::Function;
+using v8::FunctionTemplate;
using v8::Handle;
+using v8::HandleScope;
+using v8::Integer;
using v8::Local;
+using v8::Object;
using v8::Persistent;
-using v8::Value;
-using v8::HandleScope;
-using v8::FunctionTemplate;
+using v8::PropertyAttribute;
using v8::String;
-using v8::Function;
using v8::TryCatch;
-using v8::Context;
-using v8::Arguments;
-using v8::Integer;
using v8::Undefined;
+using v8::Value;
void TTYWrap::Initialize(Handle<Object> target) {
@@ -54,6 +55,15 @@ void TTYWrap::Initialize(Handle<Object> target) {
t->InstanceTemplate()->SetInternalFieldCount(1);
+ enum PropertyAttribute attributes =
+ static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
+ t->InstanceTemplate()->SetAccessor(String::New("fd"),
+ StreamWrap::GetFD,
+ NULL,
+ Handle<Value>(),
+ v8::DEFAULT,
+ attributes);
+
NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);
NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);
@@ -118,7 +128,12 @@ Handle<Value> TTYWrap::IsTTY(const Arguments& args) {
HandleScope scope;
int fd = args[0]->Int32Value();
assert(fd >= 0);
- return uv_guess_handle(fd) == UV_TTY ? v8::True() : v8::False();
+
+ if (uv_guess_handle(fd) == UV_TTY) {
+ return v8::True();
+ }
+
+ return v8::False();
}
diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc
index c5f0aa76d..73b722f67 100644
--- a/src/udp_wrap.cc
+++ b/src/udp_wrap.cc
@@ -30,31 +30,32 @@
#define SLAB_SIZE (1024 * 1024)
-// Temporary hack: libuv should provide uv_inet_pton and uv_inet_ntop.
-// Clean this up in tcp_wrap.cc too.
-#if defined(__MINGW32__) || defined(_MSC_VER)
- extern "C" {
-# include <inet_net_pton.h>
-# include <inet_ntop.h>
- }
-# define uv_inet_pton ares_inet_pton
-# define uv_inet_ntop ares_inet_ntop
-
-#else // __POSIX__
-# include <arpa/inet.h>
-# define uv_inet_pton inet_pton
-# define uv_inet_ntop inet_ntop
-#endif
-
-using namespace v8;
namespace node {
+using v8::AccessorInfo;
+using v8::Arguments;
+using v8::False;
+using v8::Function;
+using v8::FunctionTemplate;
+using v8::Handle;
+using v8::HandleScope;
+using v8::Integer;
+using v8::Local;
+using v8::Null;
+using v8::Object;
+using v8::Persistent;
+using v8::PropertyAttribute;
+using v8::String;
+using v8::True;
+using v8::Value;
+
typedef ReqWrap<uv_udp_send_t> SendWrap;
// see tcp_wrap.cc
Local<Object> AddressToJS(const sockaddr* addr);
+static Persistent<Function> constructor;
static Persistent<String> buffer_sym;
static Persistent<String> oncomplete_sym;
static Persistent<String> onmessage_sym;
@@ -95,6 +96,15 @@ void UDPWrap::Initialize(Handle<Object> target) {
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(String::NewSymbol("UDP"));
+ enum PropertyAttribute attributes =
+ static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
+ t->InstanceTemplate()->SetAccessor(String::New("fd"),
+ UDPWrap::GetFD,
+ NULL,
+ Handle<Value>(),
+ v8::DEFAULT,
+ attributes);
+
NODE_SET_PROTOTYPE_METHOD(t, "bind", Bind);
NODE_SET_PROTOTYPE_METHOD(t, "send", Send);
NODE_SET_PROTOTYPE_METHOD(t, "bind6", Bind6);
@@ -110,8 +120,12 @@ void UDPWrap::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "setBroadcast", SetBroadcast);
NODE_SET_PROTOTYPE_METHOD(t, "setTTL", SetTTL);
- target->Set(String::NewSymbol("UDP"),
- Persistent<FunctionTemplate>::New(t)->GetFunction());
+ NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref);
+ NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);
+
+ constructor = Persistent<Function>::New(
+ Persistent<FunctionTemplate>::New(t)->GetFunction());
+ target->Set(String::NewSymbol("UDP"), constructor);
}
@@ -124,6 +138,19 @@ Handle<Value> UDPWrap::New(const Arguments& args) {
return scope.Close(args.This());
}
+
+Handle<Value> UDPWrap::GetFD(Local<String>, const AccessorInfo& args) {
+#if defined(_WIN32)
+ return v8::Null();
+#else
+ HandleScope scope;
+ UNWRAP(UDPWrap)
+ int fd = (wrap == NULL) ? -1 : wrap->handle_.io_watcher.fd;
+ return scope.Close(Integer::New(fd));
+#endif
+}
+
+
Handle<Value> UDPWrap::DoBind(const Arguments& args, int family) {
HandleScope scope;
int r;
@@ -169,7 +196,7 @@ Handle<Value> UDPWrap::Bind6(const Arguments& args) {
#define X(name, fn) \
Handle<Value> UDPWrap::name(const Arguments& args) { \
HandleScope scope; \
- UNWRAP(UDPWrap) \
+ UNWRAP(UDPWrap) \
assert(args.Length() == 1); \
int flag = args[0]->Int32Value(); \
int r = fn(&wrap->handle_, flag); \
@@ -404,6 +431,17 @@ UDPWrap* UDPWrap::Unwrap(Local<Object> obj) {
}
+Local<Object> UDPWrap::Instantiate() {
+ // If this assert fires then Initialize hasn't been called yet.
+ assert(constructor.IsEmpty() == false);
+
+ HandleScope scope;
+ Local<Object> obj = constructor->NewInstance();
+
+ return scope.Close(obj);
+}
+
+
uv_udp_t* UDPWrap::UVHandle() {
return &handle_;
}
diff --git a/src/udp_wrap.h b/src/udp_wrap.h
index 9ca2eaea9..dc4ddfb8e 100644
--- a/src/udp_wrap.h
+++ b/src/udp_wrap.h
@@ -7,42 +7,38 @@
namespace node {
-using v8::Object;
-using v8::Handle;
-using v8::Local;
-using v8::Value;
-using v8::String;
-using v8::Arguments;
-
class UDPWrap: public HandleWrap {
public:
- static void Initialize(Handle<Object> target);
- static Handle<Value> New(const Arguments& args);
- static Handle<Value> Bind(const Arguments& args);
- static Handle<Value> Send(const Arguments& args);
- static Handle<Value> Bind6(const Arguments& args);
- static Handle<Value> Send6(const Arguments& args);
- static Handle<Value> RecvStart(const Arguments& args);
- static Handle<Value> RecvStop(const Arguments& args);
- static Handle<Value> GetSockName(const Arguments& args);
- static Handle<Value> AddMembership(const Arguments& args);
- static Handle<Value> DropMembership(const Arguments& args);
- static Handle<Value> SetMulticastTTL(const Arguments& args);
- static Handle<Value> SetMulticastLoopback(const Arguments& args);
- static Handle<Value> SetBroadcast(const Arguments& args);
- static Handle<Value> SetTTL(const Arguments& args);
- static UDPWrap* Unwrap(Local<Object> obj);
-
+ static void Initialize(v8::Handle<v8::Object> target);
+ static v8::Handle<v8::Value> GetFD(v8::Local<v8::String>,
+ const v8::AccessorInfo&);
+ static v8::Handle<v8::Value> New(const v8::Arguments& args);
+ static v8::Handle<v8::Value> Bind(const v8::Arguments& args);
+ static v8::Handle<v8::Value> Send(const v8::Arguments& args);
+ static v8::Handle<v8::Value> Bind6(const v8::Arguments& args);
+ static v8::Handle<v8::Value> Send6(const v8::Arguments& args);
+ static v8::Handle<v8::Value> RecvStart(const v8::Arguments& args);
+ static v8::Handle<v8::Value> RecvStop(const v8::Arguments& args);
+ static v8::Handle<v8::Value> GetSockName(const v8::Arguments& args);
+ static v8::Handle<v8::Value> AddMembership(const v8::Arguments& args);
+ static v8::Handle<v8::Value> DropMembership(const v8::Arguments& args);
+ static v8::Handle<v8::Value> SetMulticastTTL(const v8::Arguments& args);
+ static v8::Handle<v8::Value> SetMulticastLoopback(const v8::Arguments& args);
+ static v8::Handle<v8::Value> SetBroadcast(const v8::Arguments& args);
+ static v8::Handle<v8::Value> SetTTL(const v8::Arguments& args);
+ static UDPWrap* Unwrap(v8::Local<v8::Object> obj);
+
+ static v8::Local<v8::Object> Instantiate();
uv_udp_t* UVHandle();
private:
- UDPWrap(Handle<Object> object);
+ UDPWrap(v8::Handle<v8::Object> object);
virtual ~UDPWrap();
- static Handle<Value> DoBind(const Arguments& args, int family);
- static Handle<Value> DoSend(const Arguments& args, int family);
- static Handle<Value> SetMembership(const Arguments& args,
- uv_membership membership);
+ static v8::Handle<v8::Value> DoBind(const v8::Arguments& args, int family);
+ static v8::Handle<v8::Value> DoSend(const v8::Arguments& args, int family);
+ static v8::Handle<v8::Value> SetMembership(const v8::Arguments& args,
+ uv_membership membership);
static uv_buf_t OnAlloc(uv_handle_t* handle, size_t suggested_size);
static void OnSend(uv_udp_send_t* req, int status);
diff --git a/src/v8_typed_array.cc b/src/v8_typed_array.cc
index 783ce3417..012fb706c 100644
--- a/src/v8_typed_array.cc
+++ b/src/v8_typed_array.cc
@@ -24,6 +24,7 @@
#include <stdint.h>
#include "v8_typed_array.h"
+#include "v8_typed_array_bswap.h"
#include "node_buffer.h"
#include "node.h"
#include "v8.h"
@@ -34,25 +35,6 @@ using node::ThrowRangeError;
using node::ThrowTypeError;
using node::ThrowError;
-int SizeOfArrayElementForType(v8::ExternalArrayType type) {
- switch (type) {
- case v8::kExternalByteArray:
- case v8::kExternalUnsignedByteArray:
- return 1;
- case v8::kExternalShortArray:
- case v8::kExternalUnsignedShortArray:
- return 2;
- case v8::kExternalIntArray:
- case v8::kExternalUnsignedIntArray:
- case v8::kExternalFloatArray:
- return 4;
- case v8::kExternalDoubleArray:
- return 8;
- default:
- return 0;
- }
-}
-
struct BatchedMethods {
const char* name;
v8::Handle<v8::Value> (*func)(const v8::Arguments& args);
@@ -72,6 +54,13 @@ class ArrayBuffer {
v8::Local<v8::ObjectTemplate> instance = ft_cache->InstanceTemplate();
instance->SetInternalFieldCount(1); // Buffer.
+ v8::Local<v8::Signature> default_signature = v8::Signature::New(ft_cache);
+
+ instance->Set(v8::String::New("slice"),
+ v8::FunctionTemplate::New(&ArrayBuffer::slice,
+ v8::Handle<v8::Value>(),
+ default_signature));
+
return ft_cache;
}
@@ -84,7 +73,7 @@ class ArrayBuffer {
v8::Object* obj = v8::Object::Cast(*value);
void* ptr = obj->GetIndexedPropertiesExternalArrayData();
- int element_size = SizeOfArrayElementForType(
+ int element_size = v8_typed_array::SizeOfArrayElementForType(
obj->GetIndexedPropertiesExternalArrayDataType());
int size =
obj->GetIndexedPropertiesExternalArrayDataLength() * element_size;
@@ -99,7 +88,7 @@ class ArrayBuffer {
static v8::Handle<v8::Value> V8New(const v8::Arguments& args) {
if (!args.IsConstructCall())
- return ThrowTypeError("Constructor cannot be called as a function.");
+ return node::FromConstructorTemplate(GetTemplate(), args);
// To match Chrome, we allow "new ArrayBuffer()".
// if (args.Length() != 1)
@@ -140,12 +129,72 @@ class ArrayBuffer {
return args.This();
}
+
+ static v8::Handle<v8::Value> slice(const v8::Arguments& args) {
+ if (args.Length() < 1)
+ return ThrowError("Wrong number of arguments.");
+
+ unsigned int length =
+ args.This()->Get(v8::String::New("byteLength"))->Uint32Value();
+ int begin = args[0]->Int32Value();
+ int end = length;
+ if (args.Length() > 1)
+ end = args[1]->Int32Value();
+
+ if (begin < 0) begin = length + begin;
+ if (begin < 0) begin = 0;
+ if (static_cast<unsigned>(begin) > length) begin = length;
+
+ if (end < 0) end = length + end;
+ if (end < 0) end = 0;
+ if (static_cast<unsigned>(end) > length) end = length;
+
+ if (begin > end) begin = end;
+
+ unsigned int slice_length = end - begin;
+ v8::Local<v8::Value> argv[] = {
+ v8::Integer::New(slice_length)};
+ v8::Local<v8::Object> buffer = ArrayBuffer::GetTemplate()->
+ GetFunction()->NewInstance(1, argv);
+
+ if (buffer.IsEmpty()) return v8::Undefined(); // constructor failed
+
+ void* src = args.This()->GetPointerFromInternalField(0);
+ void* dest = buffer->GetPointerFromInternalField(0);
+ memcpy(dest, static_cast<char*>(src) + begin, slice_length);
+
+ return buffer;
+ }
};
static bool checkAlignment(size_t val, unsigned int bytes) {
return (val & (bytes - 1)) == 0; // Handles bytes == 0.
}
+template <v8::ExternalArrayType TEAType>
+struct TEANameTrait {
+ static const char* const name;
+};
+
+template <> const char* const
+ TEANameTrait<v8::kExternalByteArray>::name = "Int8Array";
+template <> const char* const
+ TEANameTrait<v8::kExternalUnsignedByteArray>::name = "Uint8Array";
+template <> const char* const
+ TEANameTrait<v8::kExternalPixelArray>::name = "Uint8ClampedArray";
+template <> const char* const
+ TEANameTrait<v8::kExternalShortArray>::name = "Int16Array";
+template <> const char* const
+ TEANameTrait<v8::kExternalUnsignedShortArray>::name = "Uint16Array";
+template <> const char* const
+ TEANameTrait<v8::kExternalIntArray>::name = "Int32Array";
+template <> const char* const
+ TEANameTrait<v8::kExternalUnsignedIntArray>::name = "Uint32Array";
+template <> const char* const
+ TEANameTrait<v8::kExternalFloatArray>::name = "Float32Array";
+template <> const char* const
+ TEANameTrait<v8::kExternalDoubleArray>::name = "Float64Array";
+
template <unsigned int TBytes, v8::ExternalArrayType TEAType>
class TypedArray {
public:
@@ -157,7 +206,7 @@ class TypedArray {
v8::HandleScope scope;
ft_cache = v8::Persistent<v8::FunctionTemplate>::New(
v8::FunctionTemplate::New(&TypedArray<TBytes, TEAType>::V8New));
- ft_cache->SetClassName(v8::String::New(TypeName()));
+ ft_cache->SetClassName(v8::String::New(TEANameTrait<TEAType>::name));
v8::Local<v8::ObjectTemplate> instance = ft_cache->InstanceTemplate();
instance->SetInternalFieldCount(0);
@@ -192,7 +241,7 @@ class TypedArray {
private:
static v8::Handle<v8::Value> V8New(const v8::Arguments& args) {
if (!args.IsConstructCall())
- return ThrowTypeError("Constructor cannot be called as a function.");
+ return node::FromConstructorTemplate(GetTemplate(), args);
// To match Chrome, we allow "new Float32Array()".
// if (args.Length() != 1)
@@ -202,16 +251,14 @@ class TypedArray {
unsigned int length = 0;
unsigned int byte_offset = 0;
- // [m1k3] added support for Buffer constructor
- if (node::Buffer::HasInstance(args[0])
- || ArrayBuffer::HasInstance(args[0])) { // ArrayBuffer constructor.
+ if (ArrayBuffer::HasInstance(args[0])) { // ArrayBuffer constructor.
buffer = v8::Local<v8::Object>::Cast(args[0]);
size_t buflen =
buffer->GetIndexedPropertiesExternalArrayDataLength();
if (!args[1]->IsUndefined() && args[1]->Int32Value() < 0)
return ThrowRangeError("Byte offset out of range.");
- byte_offset = args[1]->IsUndefined() ? 0 : args[1]->Uint32Value();
+ byte_offset = args[1]->Uint32Value();
if (args.Length() > 2) {
if (args[2]->Int32Value() < 0)
@@ -306,27 +353,9 @@ class TypedArray {
if (args.Length() < 1)
return ThrowError("Wrong number of arguments.");
- if (args[0]->IsNumber()) {
- unsigned int index = args[0]->Uint32Value();
- void* ptr = args.This()->GetIndexedPropertiesExternalArrayData();
-
- if (TEAType == v8::kExternalByteArray)
- return v8::Integer::New(reinterpret_cast<char*>(ptr)[index]);
- else if (TEAType == v8::kExternalUnsignedByteArray)
- return v8::Integer::New(reinterpret_cast<unsigned char*>(ptr)[index]);
- else if (TEAType == v8::kExternalShortArray)
- return v8::Integer::New(reinterpret_cast<short*>(ptr)[index]);
- else if (TEAType == v8::kExternalUnsignedShortArray)
- return v8::Integer::New(reinterpret_cast<unsigned short*>(ptr)[index]);
- else if (TEAType == v8::kExternalIntArray)
- return v8::Integer::New(reinterpret_cast<int*>(ptr)[index]);
- else if (TEAType == v8::kExternalUnsignedIntArray)
- return v8::Integer::New(reinterpret_cast<unsigned int*>(ptr)[index]);
- else if (TEAType == v8::kExternalFloatArray)
- return v8::Number::New(reinterpret_cast<float*>(ptr)[index]);
- else if (TEAType == v8::kExternalDoubleArray)
- return v8::Number::New(reinterpret_cast<double*>(ptr)[index]);
- }
+ if (args[0]->IsNumber())
+ return args.This()->Get(args[0]->Uint32Value());
+
return v8::Undefined();
}
@@ -337,38 +366,8 @@ class TypedArray {
//if (!args[0]->IsObject())
// return ThrowTypeError("Type error.");
- if (args[0]->IsNumber()) {
- // index, <type> value
- unsigned int index = args[0]->Uint32Value();
- void* ptr = args.This()->GetIndexedPropertiesExternalArrayData();
- if (TEAType == v8::kExternalByteArray)
- reinterpret_cast<char*>(ptr)[index] = (char) args[1]->Int32Value();
- else if (TEAType == v8::kExternalUnsignedByteArray)
- reinterpret_cast<unsigned char*>(ptr)[index] =
- (unsigned char) args[1]->Int32Value();
- else if (TEAType == v8::kExternalShortArray)
- reinterpret_cast<short*>(ptr)[index] = (short) args[1]->Int32Value();
- else if (TEAType == v8::kExternalUnsignedShortArray)
- reinterpret_cast<unsigned short*>(ptr)[index] =
- (unsigned short) args[1]->Int32Value();
- else if (TEAType == v8::kExternalIntArray)
- reinterpret_cast<int*>(ptr)[index] = (int) args[1]->Int32Value();
- else if (TEAType == v8::kExternalUnsignedIntArray)
- reinterpret_cast<unsigned int*>(ptr)[index] =
- (unsigned int) args[1]->Int32Value();
- else if (TEAType == v8::kExternalFloatArray)
- reinterpret_cast<float*>(ptr)[index] = (float) args[1]->NumberValue();
- else if (TEAType == v8::kExternalDoubleArray)
- reinterpret_cast<double*>(ptr)[index] = (double) args[1]->NumberValue();
- else if (TEAType == v8::kExternalPixelArray) {
- int value = args[1]->Int32Value();
- if (value < 0)
- value = 0;
- else if (value > 255)
- value = 255;
- reinterpret_cast<unsigned char*>(ptr)[index] =
- (unsigned char) value;
- }
+ if (args[0]->IsNumber()) { // index, <type> value
+ args.This()->Set(args[0]->Uint32Value(), args[1]);
} else if (args[0]->IsObject()) {
v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(args[0]);
@@ -458,23 +457,6 @@ class TypedArray {
return TypedArray<TBytes, TEAType>::GetTemplate()->
GetFunction()->NewInstance(3, argv);
}
-
- static const char* TypeName() {
- switch (TEAType) {
- case v8::kExternalByteArray: return "Int8Array";
- case v8::kExternalUnsignedByteArray: return "Uint8Array";
- case v8::kExternalShortArray: return "Int16Array";
- case v8::kExternalUnsignedShortArray: return "Uint16Array";
- case v8::kExternalIntArray: return "Int32Array";
- case v8::kExternalUnsignedIntArray: return "Uint32Array";
- case v8::kExternalFloatArray: return "Float32Array";
- case v8::kExternalDoubleArray: return "Float64Array";
- case v8::kExternalPixelArray: return "Uint8ClampedArray";
- }
- abort();
- // Please the compiler
- return "";
- }
};
class Int8Array : public TypedArray<1, v8::kExternalByteArray> { };
@@ -631,7 +613,7 @@ class DataView {
private:
static v8::Handle<v8::Value> V8New(const v8::Arguments& args) {
if (!args.IsConstructCall())
- return ThrowTypeError("Constructor cannot be called as a function.");
+ return node::FromConstructorTemplate(GetTemplate(), args);
if (args.Length() < 1)
return ThrowError("Wrong number of arguments.");
@@ -640,13 +622,12 @@ class DataView {
return ThrowError("Object must be an ArrayBuffer.");
v8::Handle<v8::Object> buffer = v8::Handle<v8::Object>::Cast(args[0]);
- if (!buffer->HasIndexedPropertiesInExternalArrayData())
+ if (!ArrayBuffer::HasInstance(buffer))
return ThrowError("Object must be an ArrayBuffer.");
unsigned int byte_length =
buffer->GetIndexedPropertiesExternalArrayDataLength();
- unsigned int byte_offset =
- args[1]->IsUndefined() ? 0 : args[1]->Uint32Value();
+ unsigned int byte_offset = args[1]->Uint32Value();
if (args[1]->Int32Value() < 0 || byte_offset >= byte_length)
return ThrowRangeError("byteOffset out of range.");
@@ -684,44 +665,18 @@ class DataView {
return args.This();
}
- // TODO(deanm): This isn't beautiful or optimal.
- static void swizzle(char* buf, size_t len) {
- for (size_t i = 0; i < len / 2; ++i) {
- char t = buf[i];
- buf[i] = buf[len - i - 1];
- buf[len - i - 1] = t;
- }
- }
-
- template <typename T>
- static T getValue(void* ptr, unsigned int index, bool swiz) {
- char buf[sizeof(T)];
- memcpy(buf, reinterpret_cast<char*>(ptr) + index, sizeof(T));
- if (swiz)
- swizzle(buf, sizeof(T));
- T val;
- memcpy(&val, buf, sizeof(T));
- return val;
- }
-
- template <typename T>
- static void setValue(void* ptr, unsigned int index, T val, bool swiz) {
- char buf[sizeof(T)];
- memcpy(buf, &val, sizeof(T));
- if (swiz)
- swizzle(buf, sizeof(T));
- memcpy(reinterpret_cast<char*>(ptr) + index, buf, sizeof(T));
- }
-
template <typename T>
static v8::Handle<v8::Value> getGeneric(const v8::Arguments& args) {
if (args.Length() < 1)
return ThrowError("Wrong number of arguments.");
unsigned int index = args[0]->Uint32Value();
- bool little_endian = args[1]->BooleanValue();
+ // NOTE(deanm): args[1]->BooleanValue when the argument was not passed in
+ // gives us the right answer, but seems to be very slow. This seems to be
+ // the cost of calling BooleanValue() on undefined.
+ bool little_endian = args.Length() > 1 ? args[1]->BooleanValue() : false;
// TODO(deanm): All of these things should be cacheable.
- int element_size = SizeOfArrayElementForType(
+ int element_size = v8_typed_array::SizeOfArrayElementForType(
args.This()->GetIndexedPropertiesExternalArrayDataType());
assert(element_size > 0);
int size = args.This()->GetIndexedPropertiesExternalArrayDataLength();
@@ -732,8 +687,20 @@ class DataView {
return ThrowError("Index out of range.");
}
- void* ptr = args.This()->GetIndexedPropertiesExternalArrayData();
- return cTypeToValue<T>(getValue<T>(ptr, index, !little_endian));
+ void* ptr = reinterpret_cast<char*>(
+ args.This()->GetIndexedPropertiesExternalArrayData()) + index;
+
+ T val;
+#if V8_TYPED_ARRAY_LITTLE_ENDIAN
+ if (!little_endian) {
+#else
+ if (little_endian) {
+#endif
+ val = v8_typed_array::LoadAndSwapBytes<T>(ptr);
+ } else {
+ memcpy(&val, ptr, sizeof(T));
+ }
+ return cTypeToValue<T>(val);
}
template <typename T>
@@ -742,9 +709,12 @@ class DataView {
return ThrowError("Wrong number of arguments.");
unsigned int index = args[0]->Int32Value();
- bool little_endian = args[2]->BooleanValue();
+ // NOTE(deanm): args[1]->BooleanValue when the argument was not passed in
+ // gives us the right answer, but seems to be very slow. This seems to be
+ // the cost of calling BooleanValue() on undefined.
+ bool little_endian = args.Length() > 2 ? args[2]->BooleanValue() : false;
// TODO(deanm): All of these things should be cacheable.
- int element_size = SizeOfArrayElementForType(
+ int element_size = v8_typed_array::SizeOfArrayElementForType(
args.This()->GetIndexedPropertiesExternalArrayDataType());
assert(element_size > 0);
int size = args.This()->GetIndexedPropertiesExternalArrayDataLength();
@@ -755,8 +725,19 @@ class DataView {
return ThrowError("Index out of range.");
}
- void* ptr = args.This()->GetIndexedPropertiesExternalArrayData();
- setValue<T>(ptr, index, valueToCType<T>(args[1]), !little_endian);
+ void* ptr = reinterpret_cast<char*>(
+ args.This()->GetIndexedPropertiesExternalArrayData()) + index;
+
+ T val = valueToCType<T>(args[1]);
+#if V8_TYPED_ARRAY_LITTLE_ENDIAN
+ if (!little_endian) {
+#else
+ if (little_endian) {
+#endif
+ v8_typed_array::SwapBytesAndStore<T>(ptr, val);
+ } else {
+ memcpy(ptr, &val, sizeof(T));
+ }
return v8::Undefined();
}
@@ -857,6 +838,24 @@ void AttachBindings(v8::Handle<v8::Object> obj) {
DataView::GetTemplate()->GetFunction());
}
-} // namespace v8_typed_array
+int SizeOfArrayElementForType(v8::ExternalArrayType type) {
+ switch (type) {
+ case v8::kExternalByteArray:
+ case v8::kExternalUnsignedByteArray:
+ case v8::kExternalPixelArray:
+ return 1;
+ case v8::kExternalShortArray:
+ case v8::kExternalUnsignedShortArray:
+ return 2;
+ case v8::kExternalIntArray:
+ case v8::kExternalUnsignedIntArray:
+ case v8::kExternalFloatArray:
+ return 4;
+ case v8::kExternalDoubleArray:
+ return 8;
+ default:
+ return 0;
+ }
+}
-NODE_MODULE(node_typed_array, v8_typed_array::AttachBindings)
+} // namespace v8_typed_array
diff --git a/src/v8_typed_array.h b/src/v8_typed_array.h
index 47b66945c..dc518ccdd 100644
--- a/src/v8_typed_array.h
+++ b/src/v8_typed_array.h
@@ -28,6 +28,8 @@ namespace v8_typed_array {
void AttachBindings(v8::Handle<v8::Object> obj);
+int SizeOfArrayElementForType(v8::ExternalArrayType type);
+
} // namespace v8_typed_array
#endif // V8_TYPED_ARRAY_H_
diff --git a/src/v8_typed_array_bswap.h b/src/v8_typed_array_bswap.h
new file mode 100644
index 000000000..87939bbd5
--- /dev/null
+++ b/src/v8_typed_array_bswap.h
@@ -0,0 +1,201 @@
+// V8 Typed Array implementation.
+// (c) Dean McNamee <dean@gmail.com>, 2012.
+//
+// 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.
+
+#ifndef V8_TYPED_ARRAY_BSWAP_H_
+#define V8_TYPED_ARRAY_BSWAP_H_
+
+// Windows will always be little endian (including ARM), so we just need to
+// worry about gcc.
+#if defined (__ppc__) || defined (__ppc64__) || defined(__ARMEB__)
+#define V8_TYPED_ARRAY_BIG_ENDIAN 1
+#else
+#define V8_TYPED_ARRAY_LITTLE_ENDIAN 1
+#endif
+
+#if defined (_MSC_VER) && (_MSC_VER < 1600)
+ typedef unsigned char uint8_t;
+ typedef signed char int8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef signed __int16 int16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int64 uint64_t;
+ typedef signed __int64 int64_t;
+ // Definitions to avoid ICU redefinition issue
+ #define U_HAVE_INT8_T 1
+ #define U_HAVE_UINT8_T 1
+ #define U_HAVE_INT16_T 1
+ #define U_HAVE_UINT16_T 1
+ #define U_HAVE_INT32_T 1
+ #define U_HAVE_UINT32_T 1
+ #define U_HAVE_INT64_T 1
+ #define U_HAVE_UINT64_T 1
+#else
+ #include <stdint.h>
+#endif
+
+#if defined (_MSC_VER)
+#define V8_TYPED_ARRAY_BSWAP16 _byteswap_ushort
+#define V8_TYPED_ARRAY_BSWAP32 _byteswap_ulong
+#define V8_TYPED_ARRAY_BSWAP64 _byteswap_uint64
+#else
+// On LLVM based compilers we can feature test, but for GCC we unfortunately
+// have to rely on the version. Additionally __builtin_bswap32/64 were added
+// in GCC 4.3, but __builtin_bswap16 was not added until GCC 4.8.
+// We should be able to assume GCC/LLVM here (and can use ULL constants, etc).
+// Fallback swap macros taken from QEMU bswap.h
+#ifdef __has_builtin
+#define V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN(x) __has_builtin(x)
+#define V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN16(x) __has_builtin(x)
+#else
+#define V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN(x) (defined(__GNUC__) && \
+ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
+#define V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN16(x) (defined(__GNUC__) && \
+ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
+#endif
+
+#if V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN(__builtin_bswap64)
+#define V8_TYPED_ARRAY_BSWAP64 __builtin_bswap64
+#else
+#define V8_TYPED_ARRAY_BSWAP64(x) \
+({ \
+ uint64_t __x = (x); \
+ ((uint64_t)( \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
+})
+#endif
+
+#if V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN(__builtin_bswap32)
+#define V8_TYPED_ARRAY_BSWAP32 __builtin_bswap32
+#else
+#define V8_TYPED_ARRAY_BSWAP32(x) \
+({ \
+ uint32_t __x = (x); \
+ ((uint32_t)( \
+ (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
+ (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
+ (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
+ (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
+})
+#endif
+
+#if V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN16(__builtin_bswap16)
+#define V8_TYPED_ARRAY_BSWAP16 __builtin_bswap16
+#else
+#define V8_TYPED_ARRAY_BSWAP16(x) \
+({ \
+ uint16_t __x = (x); \
+ ((uint16_t)( \
+ (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
+ (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
+})
+#endif
+#endif
+
+
+namespace v8_typed_array {
+
+template <typename T>
+inline T SwapBytes(T x) {
+ typedef char NoSwapBytesForType[sizeof(T) == 0 ? 1 : -1];
+ return 0;
+}
+
+template <>
+inline signed char SwapBytes(signed char x) { return x; }
+template <>
+inline unsigned char SwapBytes(unsigned char x) { return x; }
+template <>
+inline uint16_t SwapBytes(uint16_t x) { return V8_TYPED_ARRAY_BSWAP16(x); }
+template <>
+inline int16_t SwapBytes(int16_t x) { return V8_TYPED_ARRAY_BSWAP16(x); }
+template <>
+inline uint32_t SwapBytes(uint32_t x) { return V8_TYPED_ARRAY_BSWAP32(x); }
+template <>
+inline int32_t SwapBytes(int32_t x) { return V8_TYPED_ARRAY_BSWAP32(x); }
+template <>
+inline uint64_t SwapBytes(uint64_t x) { return V8_TYPED_ARRAY_BSWAP64(x); }
+template <>
+inline int64_t SwapBytes(int64_t x) { return V8_TYPED_ARRAY_BSWAP64(x); }
+
+template <typename T> // General implementation for all non-FP types.
+inline T LoadAndSwapBytes(void* ptr) {
+ T val;
+ memcpy(&val, ptr, sizeof(T));
+ return SwapBytes(val);
+}
+
+template <>
+inline float LoadAndSwapBytes<float>(void* ptr) {
+ typedef char VerifySizesAreEqual[sizeof(uint32_t) == sizeof(float) ? 1 : -1];
+ uint32_t swappable;
+ float val;
+ memcpy(&swappable, ptr, sizeof(swappable));
+ swappable = SwapBytes(swappable);
+ memcpy(&val, &swappable, sizeof(swappable));
+ return val;
+}
+
+template <>
+inline double LoadAndSwapBytes<double>(void* ptr) {
+ typedef char VerifySizesAreEqual[sizeof(uint64_t) == sizeof(double) ? 1 : -1];
+ uint64_t swappable;
+ double val;
+ memcpy(&swappable, ptr, sizeof(swappable));
+ swappable = SwapBytes(swappable);
+ memcpy(&val, &swappable, sizeof(swappable));
+ return val;
+}
+
+template <typename T> // General implementation for all non-FP types.
+inline void SwapBytesAndStore(void* ptr, T val) {
+ val = SwapBytes(val);
+ memcpy(ptr, &val, sizeof(T));
+}
+
+template <>
+inline void SwapBytesAndStore(void* ptr, float val) {
+ typedef char VerifySizesAreEqual[sizeof(uint32_t) == sizeof(float) ? 1 : -1];
+ uint32_t swappable;
+ memcpy(&swappable, &val, sizeof(swappable));
+ swappable = SwapBytes(swappable);
+ memcpy(ptr, &swappable, sizeof(swappable));
+}
+
+template <>
+inline void SwapBytesAndStore(void* ptr, double val) {
+ typedef char VerifySizesAreEqual[sizeof(uint64_t) == sizeof(double) ? 1 : -1];
+ uint64_t swappable;
+ memcpy(&swappable, &val, sizeof(swappable));
+ swappable = SwapBytes(swappable);
+ memcpy(ptr, &swappable, sizeof(swappable));
+}
+
+} // namespace v8_typed_array
+
+#endif // V8_TYPED_ARRAY_BSWAP_H_
diff --git a/src/v8abbr.h b/src/v8abbr.h
index ac4a16939..9a51e09f5 100644
--- a/src/v8abbr.h
+++ b/src/v8abbr.h
@@ -7,9 +7,9 @@
#define V8_ABBR_H
/* Frame pointer offsets */
-#define V8_OFF_FP_FUNC ((uint32_t)V8DBG_OFF_FP_FUNCTION)
-#define V8_OFF_FP_CONTEXT ((uint32_t)V8DBG_OFF_FP_CONTEXT)
-#define V8_OFF_FP_MARKER ((uint32_t)V8DBG_OFF_FP_MARKER)
+#define V8_OFF_FP_FUNC V8DBG_OFF_FP_FUNCTION
+#define V8_OFF_FP_CONTEXT V8DBG_OFF_FP_CONTEXT
+#define V8_OFF_FP_MARKER V8DBG_OFF_FP_MARKER
/* Stack frame types */
#define V8_FT_ENTRY V8DBG_FRAMETYPE_ENTRYFRAME
@@ -22,9 +22,9 @@
#define V8_FT_ADAPTOR V8DBG_FRAMETYPE_ARGUMENTSADAPTORFRAME
/* Identification masks and tags */
-#define V8_SmiTagMask V8DBG_SMITAGMASK
-#define V8_SmiTag V8DBG_SMITAG
-#define V8_SmiValueShift V8_SmiTagMask
+#define V8_SmiTagMask (V8DBG_SMITAGMASK)
+#define V8_SmiTag (V8DBG_SMITAG)
+#define V8_SmiValueShift (V8DBG_SMISHIFTSIZE + V8DBG_SMITAGMASK)
#define V8_HeapObjectTagMask V8DBG_HEAPOBJECTTAGMASK
#define V8_HeapObjectTag V8DBG_HEAPOBJECTTAG
@@ -45,7 +45,7 @@
#define V8_IT_CODE V8DBG_TYPE_CODE__CODE_TYPE
/* Node-specific offsets */
-#define NODE_OFF_EXTSTR_DATA 0x4
+#define NODE_OFF_EXTSTR_DATA sizeof(void*)
/* Heap class->field offsets */
#define V8_OFF_HEAP(off) ((off) - 1)
diff --git a/src/v8ustack.d b/src/v8ustack.d
index 27e903449..d643f8fb8 100644
--- a/src/v8ustack.d
+++ b/src/v8ustack.d
@@ -14,11 +14,13 @@
#include <v8abbr.h>
/*
- * V8 represents small integers (SMI) using the upper 31 bits of a 32-bit
+ * V8 represents small integers (SMI) using the upper 31 bits of a 32/64-bit
* value. To extract the actual integer value, we must shift it over.
*/
-#define IS_SMI(value) ((value & V8_SmiTagMask) == V8_SmiTag)
-#define SMI_VALUE(value) ((uint32_t)(value) >> V8_SmiValueShift)
+#define IS_SMI(value) \
+ ((value & V8_SmiTagMask) == V8_SmiTag)
+#define SMI_VALUE(value) \
+ ((uint32_t) ((value) >> V8_SmiValueShift))
/*
* Heap objects usually start off with a Map pointer, itself another heap
@@ -32,7 +34,8 @@
/*
* Determine the encoding and representation of a V8 string.
*/
-#define V8_TYPE_STRING(type) (((type) & V8_IsNotStringMask) == V8_StringTag)
+#define V8_TYPE_STRING(type) \
+ (((type) & V8_IsNotStringMask) == V8_StringTag)
#define V8_STRENC_ASCII(type) \
(((type) & V8_StringEncodingMask) == V8_AsciiStringTag)
@@ -59,20 +62,57 @@
/*
* General helper macros
*/
-#define COPYIN_UINT8(addr) (*(uint8_t *)copyin((addr), sizeof (uint8_t)))
-#define COPYIN_UINT32(addr) (*(uint32_t *)copyin((addr), sizeof (uint32_t)))
+#define COPYIN_UINT8(addr) (*(uint8_t*) copyin((addr), sizeof(uint8_t)))
+#define COPYIN_UINT32(addr) (*(uint32_t*) copyin((addr), sizeof(uint32_t)))
+#define COPYIN_UINT64(addr) (*(uint64_t*) copyin((addr), sizeof(uint64_t)))
+
+#if defined(__i386)
+# define COPYIN_PTR(addr) COPYIN_UINT32(addr)
+# define off_t uint32_t
+# define APPEND_PTR(p) APPEND_PTR_32(p)
+#else
+# define COPYIN_PTR(addr) COPYIN_UINT64(addr)
+# define off_t uint64_t
+# define APPEND_PTR(p) APPEND_PTR_64(p)
+#endif
#define APPEND_CHR(c) (this->buf[this->off++] = (c))
+#define APPEND_CHR4(s0, s1, s2, s3) \
+ APPEND_CHR(s0); \
+ APPEND_CHR(s1); \
+ APPEND_CHR(s2); \
+ APPEND_CHR(s3);
+#define APPEND_CHR8(s0, s1, s2, s3, s4, s5, s6, s7) \
+ APPEND_CHR4(s0, s1, s2, s3) \
+ APPEND_CHR4(s4, s5, s6, s7)
#define APPEND_DGT(i, d) \
- (((i) / (d)) ? APPEND_CHR('0' + ((i)/(d) % 10)) : 0)
+ (((i) / (d)) ? APPEND_CHR('0' + ((i)/(d) % 10)) : 0)
#define APPEND_NUM(i) \
- APPEND_DGT((i), 10000); \
- APPEND_DGT((i), 1000); \
- APPEND_DGT((i), 100); \
- APPEND_DGT((i), 10); \
- APPEND_DGT((i), 1);
+ APPEND_DGT((i), 100000); \
+ APPEND_DGT((i), 10000); \
+ APPEND_DGT((i), 1000); \
+ APPEND_DGT((i), 100); \
+ APPEND_DGT((i), 10); \
+ APPEND_DGT((i), 1);
+
+#define APPEND_HEX(d) \
+ APPEND_CHR((d) < 10 ? '0' + (d) : 'a' - 10 + (d))
+
+#define APPEND_PTR_32(p) \
+ APPEND_HEX((p >> 28) & 0xf); \
+ APPEND_HEX((p >> 24) & 0xf); \
+ APPEND_HEX((p >> 20) & 0xf); \
+ APPEND_HEX((p >> 16) & 0xf); \
+ APPEND_HEX((p >> 12) & 0xf); \
+ APPEND_HEX((p >> 8) & 0xf); \
+ APPEND_HEX((p >> 4) & 0xf); \
+ APPEND_HEX((p) & 0xf);
+
+#define APPEND_PTR_64(p) \
+ APPEND_PTR_32(p >> 32) \
+ APPEND_PTR_32(p)
/*
* The following macros are used to output ASCII SeqStrings, ConsStrings, and
@@ -92,13 +132,13 @@
*
* ExternalString pointer to a char* outside the V8 heap
*/
-
+
/*
* Load "len" and "attrs" for the given "str".
*/
#define LOAD_STRFIELDS(str, len, attrs) \
- len = SMI_VALUE(COPYIN_UINT32(str + V8_OFF_STR_LENGTH)); \
- this->map = V8_MAP_PTR(COPYIN_UINT32(str + V8_OFF_HEAPOBJ_MAP)); \
+ len = SMI_VALUE(COPYIN_PTR(str + V8_OFF_STR_LENGTH)); \
+ this->map = V8_MAP_PTR(COPYIN_PTR(str + V8_OFF_HEAPOBJ_MAP)); \
attrs = COPYIN_UINT8(this->map + V8_OFF_MAP_ATTRS);
/*
@@ -106,26 +146,26 @@
* SeqString.
*/
#define APPEND_SEQSTR(str, len, attrs) \
-dtrace:helper:ustack: \
-/!this->done && len > 0 && ASCII_SEQSTR(attrs)/ \
-{ \
+ dtrace:helper:ustack: \
+ /!this->done && len > 0 && ASCII_SEQSTR(attrs)/ \
+ { \
copyinto(str + V8_OFF_STR_CHARS, len, this->buf + this->off); \
this->off += len; \
-}
+ }
/*
* Print out the given Node.js ExternalString, or do nothing if the string is
* not an ASCII ExternalString.
*/
#define APPEND_NODESTR(str, len, attrs) \
-dtrace:helper:ustack: \
-/!this->done && len > 0 && ASCII_EXTSTR(attrs)/ \
-{ \
- this->resource = COPYIN_UINT32(str + V8_OFF_EXTSTR_RSRC); \
- this->dataptr = COPYIN_UINT32(this->resource + NODE_OFF_EXTSTR_DATA); \
+ dtrace:helper:ustack: \
+ /!this->done && len > 0 && ASCII_EXTSTR(attrs)/ \
+ { \
+ this->resource = COPYIN_PTR(str + V8_OFF_EXTSTR_RSRC); \
+ this->dataptr = COPYIN_PTR(this->resource + NODE_OFF_EXTSTR_DATA); \
copyinto(this->dataptr, len, this->buf + this->off); \
this->off += len; \
-}
+ }
/*
* Recall that each ConsString points to two other strings which are
@@ -144,7 +184,7 @@ dtrace:helper:ustack: \
* s0 s7
* / \ / \
* / \ / \ <-- 2nd expansion
- * / \ / \
+ * / \ / \
* s1 s4 s8 s11
* / \ / \ / \ / \ <-- 3rd expansion
* s2 s3 s5 s6 s9 s10 s12 s13
@@ -157,27 +197,27 @@ dtrace:helper:ustack: \
* leafs in the tree above) to get the final output.
*/
#define EXPAND_START() \
-dtrace:helper:ustack: \
-/!this->done/ \
-{ \
- this->s0str = this->s1str = this->s2str = 0; \
- this->s3str = this->s4str = this->s5str = 0; \
- this->s6str = this->s7str = this->s8str = 0; \
- this->s9str = this->s10str = this->s11str = 0; \
- this->s12str = this->s13str = 0; \
+ dtrace:helper:ustack: \
+ /!this->done/ \
+ { \
+ this->s0str = this->s1str = this->s2str = (off_t) 0; \
+ this->s3str = this->s4str = this->s5str = (off_t) 0; \
+ this->s6str = this->s7str = this->s8str = (off_t) 0; \
+ this->s9str = this->s10str = this->s11str = (off_t) 0; \
+ this->s12str = this->s13str = (off_t) 0; \
\
- this->s0len = this->s1len = this->s2len = 0; \
- this->s3len = this->s4len = this->s5len = 0; \
- this->s6len = this->s7len = this->s8len = 0; \
- this->s9len = this->s10len = this->s11len = 0; \
- this->s12len = this->s13len = 0; \
+ this->s0len = this->s1len = this->s2len = (off_t) 0; \
+ this->s3len = this->s4len = this->s5len = (off_t) 0; \
+ this->s6len = this->s7len = this->s8len = (off_t) 0; \
+ this->s9len = this->s10len = this->s11len = (off_t) 0; \
+ this->s12len = this->s13len = (off_t) 0; \
\
this->s0attrs = this->s1attrs = this->s2attrs = 0; \
this->s3attrs = this->s4attrs = this->s5attrs = 0; \
this->s6attrs = this->s7attrs = this->s8attrs = 0; \
this->s9attrs = this->s10attrs = this->s11attrs = 0; \
this->s12attrs = this->s13attrs = 0; \
-}
+ }
/*
* Expand the ConsString "str" (represented by "str", "len", and "attrs") into
@@ -185,61 +225,61 @@ dtrace:helper:ustack: \
* by "s2s", "s2l", "s2a"). If "str" is not a ConsString, do nothing.
*/
#define EXPAND_STR(str, len, attrs, s1s, s1l, s1a, s2s, s2l, s2a) \
-dtrace:helper:ustack: \
-/!this->done && len > 0 && ASCII_CONSSTR(attrs)/ \
-{ \
+ dtrace:helper:ustack: \
+ /!this->done && len > 0 && ASCII_CONSSTR(attrs)/ \
+ { \
len = 0; \
\
- s1s = COPYIN_UINT32(str + V8_OFF_CONSSTR_CAR); \
+ s1s = COPYIN_PTR(str + V8_OFF_CONSSTR_CAR); \
LOAD_STRFIELDS(s1s, s1l, s1a) \
\
- s2s = COPYIN_UINT32(str + V8_OFF_CONSSTR_CDR); \
+ s2s = COPYIN_PTR(str + V8_OFF_CONSSTR_CDR); \
LOAD_STRFIELDS(s2s, s2l, s2a) \
-}
+ }
/*
* Print out a ConsString by expanding it up to three levels and printing out
* the resulting SeqStrings.
*/
#define APPEND_CONSSTR(str, len, attrs) \
- EXPAND_START() \
- EXPAND_STR(str, len, attrs, \
- this->s0str, this->s0len, this->s0attrs, \
- this->s7str, this->s7len, this->s7attrs) \
- EXPAND_STR(this->s0str, this->s0len, this->s0attrs, \
- this->s1str, this->s1len, this->s1attrs, \
- this->s4str, this->s4len, this->s4attrs) \
- EXPAND_STR(this->s1str, this->s1len, this->s1attrs, \
- this->s2str, this->s2len, this->s2attrs, \
- this->s3str, this->s3len, this->s3attrs) \
- EXPAND_STR(this->s4str, this->s4len, this->s4attrs, \
- this->s5str, this->s5len, this->s5attrs, \
- this->s6str, this->s6len, this->s6attrs) \
- EXPAND_STR(this->s7str, this->s7len, this->s7attrs, \
- this->s8str, this->s8len, this->s8attrs, \
- this->s11str, this->s11len, this->s11attrs) \
- EXPAND_STR(this->s8str, this->s8len, this->s8attrs, \
- this->s9str, this->s9len, this->s9attrs, \
- this->s10str, this->s10len, this->s10attrs) \
- EXPAND_STR(this->s11str, this->s11len, this->s11attrs, \
- this->s12str, this->s12len, this->s12attrs, \
- this->s13str, this->s13len, this->s13attrs) \
+ EXPAND_START() \
+ EXPAND_STR(str, len, attrs, \
+ this->s0str, this->s0len, this->s0attrs, \
+ this->s7str, this->s7len, this->s7attrs) \
+ EXPAND_STR(this->s0str, this->s0len, this->s0attrs, \
+ this->s1str, this->s1len, this->s1attrs, \
+ this->s4str, this->s4len, this->s4attrs) \
+ EXPAND_STR(this->s1str, this->s1len, this->s1attrs, \
+ this->s2str, this->s2len, this->s2attrs, \
+ this->s3str, this->s3len, this->s3attrs) \
+ EXPAND_STR(this->s4str, this->s4len, this->s4attrs, \
+ this->s5str, this->s5len, this->s5attrs, \
+ this->s6str, this->s6len, this->s6attrs) \
+ EXPAND_STR(this->s7str, this->s7len, this->s7attrs, \
+ this->s8str, this->s8len, this->s8attrs, \
+ this->s11str, this->s11len, this->s11attrs) \
+ EXPAND_STR(this->s8str, this->s8len, this->s8attrs, \
+ this->s9str, this->s9len, this->s9attrs, \
+ this->s10str, this->s10len, this->s10attrs) \
+ EXPAND_STR(this->s11str, this->s11len, this->s11attrs, \
+ this->s12str, this->s12len, this->s12attrs, \
+ this->s13str, this->s13len, this->s13attrs) \
\
- APPEND_SEQSTR(str, len, attrs) \
- APPEND_SEQSTR(this->s0str, this->s0len, this->s0attrs) \
- APPEND_SEQSTR(this->s1str, this->s1len, this->s1attrs) \
- APPEND_SEQSTR(this->s2str, this->s2len, this->s2attrs) \
- APPEND_SEQSTR(this->s3str, this->s3len, this->s3attrs) \
- APPEND_SEQSTR(this->s4str, this->s4len, this->s4attrs) \
- APPEND_SEQSTR(this->s5str, this->s5len, this->s5attrs) \
- APPEND_SEQSTR(this->s6str, this->s6len, this->s6attrs) \
- APPEND_SEQSTR(this->s7str, this->s7len, this->s7attrs) \
- APPEND_SEQSTR(this->s8str, this->s8len, this->s8attrs) \
- APPEND_SEQSTR(this->s9str, this->s9len, this->s9attrs) \
- APPEND_SEQSTR(this->s10str, this->s10len, this->s10attrs) \
- APPEND_SEQSTR(this->s11str, this->s11len, this->s11attrs) \
- APPEND_SEQSTR(this->s12str, this->s12len, this->s12attrs) \
- APPEND_SEQSTR(this->s13str, this->s13len, this->s13attrs) \
+ APPEND_SEQSTR(str, len, attrs) \
+ APPEND_SEQSTR(this->s0str, this->s0len, this->s0attrs) \
+ APPEND_SEQSTR(this->s1str, this->s1len, this->s1attrs) \
+ APPEND_SEQSTR(this->s2str, this->s2len, this->s2attrs) \
+ APPEND_SEQSTR(this->s3str, this->s3len, this->s3attrs) \
+ APPEND_SEQSTR(this->s4str, this->s4len, this->s4attrs) \
+ APPEND_SEQSTR(this->s5str, this->s5len, this->s5attrs) \
+ APPEND_SEQSTR(this->s6str, this->s6len, this->s6attrs) \
+ APPEND_SEQSTR(this->s7str, this->s7len, this->s7attrs) \
+ APPEND_SEQSTR(this->s8str, this->s8len, this->s8attrs) \
+ APPEND_SEQSTR(this->s9str, this->s9len, this->s9attrs) \
+ APPEND_SEQSTR(this->s10str, this->s10len, this->s10attrs) \
+ APPEND_SEQSTR(this->s11str, this->s11len, this->s11attrs) \
+ APPEND_SEQSTR(this->s12str, this->s12len, this->s12attrs) \
+ APPEND_SEQSTR(this->s13str, this->s13len, this->s13attrs) \
/*
@@ -248,8 +288,8 @@ dtrace:helper:ustack: \
* expanded ConsString.
*/
#define APPEND_V8STR(str, len, attrs) \
- APPEND_CONSSTR(str, len, attrs) \
- APPEND_NODESTR(str, len, attrs)
+ APPEND_CONSSTR(str, len, attrs) \
+ APPEND_NODESTR(str, len, attrs)
/*
* In this first clause we initialize all variables. We must explicitly clear
@@ -261,26 +301,26 @@ dtrace:helper:ustack:
this->fp = arg1;
/* output/flow control */
- this->buf = (char *)alloca(128);
+ this->buf = (char*) alloca(128);
this->off = 0;
this->done = 0;
/* program state */
- this->ctx = 0;
- this->marker = 0;
- this->func = 0;
- this->shared = 0;
- this->map = 0;
+ this->ctx = (off_t) 0;
+ this->marker = (off_t) 0;
+ this->func = (off_t) 0;
+ this->shared = (off_t) 0;
+ this->map = (off_t) 0;
this->attrs = 0;
- this->funcnamestr = 0;
+ this->funcnamestr = (off_t) 0;
this->funcnamelen = 0;
this->funcnameattrs = 0;
- this->script = 0;
- this->scriptnamestr = 0;
+ this->script = (off_t) 0;
+ this->scriptnamestr = (off_t) 0;
this->scriptnamelen = 0;
this->scriptnameattrs = 0;
- this->position = 0;
- this->line_ends = 0;
+ this->position = 0;
+ this->line_ends = (off_t) 0;
this->le_attrs = 0;
/* binary search fields */
@@ -295,27 +335,15 @@ dtrace:helper:ustack:
*/
dtrace:helper:ustack:
{
- this->ctx = COPYIN_UINT32(this->fp + V8_OFF_FP_CONTEXT);
+ this->ctx = COPYIN_PTR(this->fp + V8_OFF_FP_CONTEXT);
}
dtrace:helper:ustack:
/IS_SMI(this->ctx) && SMI_VALUE(this->ctx) == V8_FT_ADAPTOR/
{
this->done = 1;
- APPEND_CHR('<');
- APPEND_CHR('<');
- APPEND_CHR(' ');
- APPEND_CHR('a');
- APPEND_CHR('d');
- APPEND_CHR('a');
- APPEND_CHR('p');
- APPEND_CHR('t');
- APPEND_CHR('o');
- APPEND_CHR('r');
- APPEND_CHR(' ');
- APPEND_CHR('>');
- APPEND_CHR('>');
- APPEND_CHR('\0');
+ APPEND_CHR8('<','<',' ','a','d','a','p','t');
+ APPEND_CHR8('o','r',' ','>','>','\0','\0','\0');
stringof(this->buf);
}
@@ -325,7 +353,7 @@ dtrace:helper:ustack:
dtrace:helper:ustack:
/!this->done/
{
- this->marker = COPYIN_UINT32(this->fp + V8_OFF_FP_MARKER);
+ this->marker = COPYIN_PTR(this->fp + V8_OFF_FP_MARKER);
}
dtrace:helper:ustack:
@@ -333,18 +361,8 @@ dtrace:helper:ustack:
SMI_VALUE(this->marker) == V8_FT_ENTRY/
{
this->done = 1;
- APPEND_CHR('<');
- APPEND_CHR('<');
- APPEND_CHR(' ');
- APPEND_CHR('e');
- APPEND_CHR('n');
- APPEND_CHR('t');
- APPEND_CHR('r');
- APPEND_CHR('y');
- APPEND_CHR(' ');
- APPEND_CHR('>');
- APPEND_CHR('>');
- APPEND_CHR('\0');
+ APPEND_CHR8('<','<',' ','e','n','t','r','y');
+ APPEND_CHR4(' ','>','>','\0');
stringof(this->buf);
}
@@ -353,27 +371,9 @@ dtrace:helper:ustack:
SMI_VALUE(this->marker) == V8_FT_ENTRYCONSTRUCT/
{
this->done = 1;
- APPEND_CHR('<');
- APPEND_CHR('<');
- APPEND_CHR(' ');
- APPEND_CHR('e');
- APPEND_CHR('n');
- APPEND_CHR('t');
- APPEND_CHR('r');
- APPEND_CHR('y');
- APPEND_CHR('_');
- APPEND_CHR('c');
- APPEND_CHR('o');
- APPEND_CHR('n');
- APPEND_CHR('s');
- APPEND_CHR('t');
- APPEND_CHR('r');
- APPEND_CHR('u');
- APPEND_CHR('c');
- APPEND_CHR('t');
- APPEND_CHR(' ');
- APPEND_CHR('>');
- APPEND_CHR('>');
+ APPEND_CHR8('<','<',' ','e','n','t','r','y');
+ APPEND_CHR8('_','c','o','n','s','t','r','u');
+ APPEND_CHR4('t',' ','>','>');
APPEND_CHR('\0');
stringof(this->buf);
}
@@ -383,17 +383,8 @@ dtrace:helper:ustack:
SMI_VALUE(this->marker) == V8_FT_EXIT/
{
this->done = 1;
- APPEND_CHR('<');
- APPEND_CHR('<');
- APPEND_CHR(' ');
- APPEND_CHR('e');
- APPEND_CHR('x');
- APPEND_CHR('i');
- APPEND_CHR('t');
- APPEND_CHR(' ');
- APPEND_CHR('>');
- APPEND_CHR('>');
- APPEND_CHR('\0');
+ APPEND_CHR8('<','<',' ','e','x','i','t',' ');
+ APPEND_CHR4('>','>','\0','\0');
stringof(this->buf);
}
@@ -402,21 +393,8 @@ dtrace:helper:ustack:
SMI_VALUE(this->marker) == V8_FT_INTERNAL/
{
this->done = 1;
- APPEND_CHR('<');
- APPEND_CHR('<');
- APPEND_CHR(' ');
- APPEND_CHR('i');
- APPEND_CHR('n');
- APPEND_CHR('t');
- APPEND_CHR('e');
- APPEND_CHR('r');
- APPEND_CHR('n');
- APPEND_CHR('a');
- APPEND_CHR('l');
- APPEND_CHR(' ');
- APPEND_CHR('>');
- APPEND_CHR('>');
- APPEND_CHR('\0');
+ APPEND_CHR8('<','<',' ','i','n','t','e','r');
+ APPEND_CHR8('n','a','l',' ','>','>','\0','\0');
stringof(this->buf);
}
@@ -425,24 +403,9 @@ dtrace:helper:ustack:
SMI_VALUE(this->marker) == V8_FT_CONSTRUCT/
{
this->done = 1;
- APPEND_CHR('<');
- APPEND_CHR('<');
- APPEND_CHR(' ');
- APPEND_CHR('c');
- APPEND_CHR('o');
- APPEND_CHR('n');
- APPEND_CHR('s');
- APPEND_CHR('t');
- APPEND_CHR('r');
- APPEND_CHR('u');
- APPEND_CHR('c');
- APPEND_CHR('t');
- APPEND_CHR('o');
- APPEND_CHR('r');
- APPEND_CHR(' ');
- APPEND_CHR('>');
- APPEND_CHR('>');
- APPEND_CHR('\0');
+ APPEND_CHR8('<','<',' ','c','o','n','s','t');
+ APPEND_CHR8('r','u','c','t','o','r',' ','>');
+ APPEND_CHR4('>','\0','\0','\0');
stringof(this->buf);
}
@@ -454,8 +417,8 @@ dtrace:helper:ustack:
dtrace:helper:ustack:
/!this->done/
{
- this->func = COPYIN_UINT32(this->fp + V8_OFF_FP_FUNC);
- this->map = V8_MAP_PTR(COPYIN_UINT32(this->func + V8_OFF_HEAPOBJ_MAP));
+ this->func = COPYIN_PTR(this->fp + V8_OFF_FP_FUNC);
+ this->map = V8_MAP_PTR(COPYIN_PTR(this->func + V8_OFF_HEAPOBJ_MAP));
this->attrs = COPYIN_UINT8(this->map + V8_OFF_MAP_ATTRS);
}
@@ -463,27 +426,10 @@ dtrace:helper:ustack:
/!this->done && this->attrs == V8_IT_CODE/
{
this->done = 1;
- APPEND_CHR('<');
- APPEND_CHR('<');
- APPEND_CHR(' ');
- APPEND_CHR('i');
- APPEND_CHR('n');
- APPEND_CHR('t');
- APPEND_CHR('e');
- APPEND_CHR('r');
- APPEND_CHR('n');
- APPEND_CHR('a');
- APPEND_CHR('l');
- APPEND_CHR(' ');
- APPEND_CHR('c');
- APPEND_CHR('o');
- APPEND_CHR('d');
- APPEND_CHR('e');
- APPEND_CHR(' ');
- APPEND_CHR('>');
- APPEND_CHR('>');
- APPEND_CHR('\0');
- stringof(this->buf);
+ APPEND_CHR8('<','<',' ','i','n','t','e','r');
+ APPEND_CHR8('n','a','l',' ','c','o','d','e');
+ APPEND_CHR4(' ','>','>','\0');
+ stringof(this->buf);
}
/*
@@ -497,8 +443,8 @@ dtrace:helper:ustack:
this->map = 0;
this->attrs = 0;
- this->shared = COPYIN_UINT32(this->func + V8_OFF_FUNC_SHARED);
- this->funcnamestr = COPYIN_UINT32(this->shared + V8_OFF_SHARED_NAME);
+ this->shared = COPYIN_PTR(this->func + V8_OFF_FUNC_SHARED);
+ this->funcnamestr = COPYIN_PTR(this->shared + V8_OFF_SHARED_NAME);
LOAD_STRFIELDS(this->funcnamestr, this->funcnamelen,
this->funcnameattrs);
}
@@ -511,18 +457,11 @@ dtrace:helper:ustack:
* some object then V8 will have computed an inferred name that we can
* include in the stack trace.
*/
- APPEND_CHR('(');
- APPEND_CHR('a');
- APPEND_CHR('n');
- APPEND_CHR('o');
- APPEND_CHR('n');
- APPEND_CHR(')');
- APPEND_CHR(' ');
- APPEND_CHR('a');
+ APPEND_CHR8('(','a','n','o','n',')',' ','a');
APPEND_CHR('s');
APPEND_CHR(' ');
- this->funcnamestr = COPYIN_UINT32(this->shared + V8_OFF_SHARED_INFERRED);
+ this->funcnamestr = COPYIN_PTR(this->shared + V8_OFF_SHARED_INFERRED);
LOAD_STRFIELDS(this->funcnamestr, this->funcnamelen,
this->funcnameattrs);
}
@@ -531,10 +470,7 @@ dtrace:helper:ustack:
/!this->done && this->funcnamelen == 0/
{
APPEND_CHR('(');
- APPEND_CHR('a');
- APPEND_CHR('n');
- APPEND_CHR('o');
- APPEND_CHR('n');
+ APPEND_CHR4('a','n','o','n');
APPEND_CHR(')');
}
@@ -546,16 +482,19 @@ APPEND_V8STR(this->funcnamestr, this->funcnamelen, this->funcnameattrs)
dtrace:helper:ustack:
/!this->done/
{
- this->script = COPYIN_UINT32(this->shared + V8_OFF_SHARED_SCRIPT);
- this->scriptnamestr = COPYIN_UINT32(this->script +
- V8_OFF_SCRIPT_NAME);
+ this->script = COPYIN_PTR(this->shared + V8_OFF_SHARED_SCRIPT);
+ this->scriptnamestr = COPYIN_PTR(this->script + V8_OFF_SCRIPT_NAME);
LOAD_STRFIELDS(this->scriptnamestr, this->scriptnamelen,
this->scriptnameattrs);
- APPEND_CHR(' ');
- APPEND_CHR('a');
- APPEND_CHR('t');
- APPEND_CHR(' ');
+ APPEND_CHR4(' ','a','t',' ');
+}
+
+dtrace:helper:ustack:
+/!this->done && this->scriptnamelen == 0/
+{
+ APPEND_CHR8('<','u','n','k','n','o','w','n');
+ APPEND_CHR('>');
}
APPEND_V8STR(this->scriptnamestr, this->scriptnamelen, this->scriptnameattrs)
@@ -567,9 +506,8 @@ dtrace:helper:ustack:
/!this->done/
{
this->position = COPYIN_UINT32(this->shared + V8_OFF_SHARED_FUNTOK);
- this->line_ends = COPYIN_UINT32(this->script + V8_OFF_SCRIPT_LENDS);
- this->map = V8_MAP_PTR(COPYIN_UINT32(this->line_ends +
- V8_OFF_HEAPOBJ_MAP));
+ this->line_ends = COPYIN_PTR(this->script + V8_OFF_SCRIPT_LENDS);
+ this->map = V8_MAP_PTR(COPYIN_PTR(this->line_ends + V8_OFF_HEAPOBJ_MAP));
this->le_attrs = COPYIN_UINT8(this->map + V8_OFF_MAP_ATTRS);
}
@@ -581,14 +519,7 @@ dtrace:helper:ustack:
* undefined because V8 has not had to compute it yet. In this case we
* just show the raw position and call it a day.
*/
- APPEND_CHR(' ');
- APPEND_CHR('p');
- APPEND_CHR('o');
- APPEND_CHR('s');
- APPEND_CHR('i');
- APPEND_CHR('t');
- APPEND_CHR('i');
- APPEND_CHR('o');
+ APPEND_CHR8(' ','p','o','s','i','t','i','o');
APPEND_CHR('n');
APPEND_CHR(' ');
APPEND_NUM(this->position);
@@ -607,11 +538,11 @@ dtrace:helper:ustack:
/!this->done/
{
/* initialize binary search */
- this->bsearch_line = this->position < COPYIN_UINT32(
- this->line_ends + V8_OFF_FA_DATA) ? 1 : 0;
+ this->bsearch_line = this->position <
+ SMI_VALUE(COPYIN_PTR(this->line_ends + V8_OFF_FA_DATA)) ? 1 : 0;
this->bsearch_min = 0;
this->bsearch_max = this->bsearch_line != 0 ? 0 :
- SMI_VALUE(COPYIN_UINT32(this->line_ends + V8_OFF_FA_SIZE)) - 1;
+ SMI_VALUE(COPYIN_PTR(this->line_ends + V8_OFF_FA_SIZE)) - 1;
}
/*
@@ -620,27 +551,29 @@ dtrace:helper:ustack:
* to 32768 lines of code.
*/
#define BSEARCH_LOOP \
-dtrace:helper:ustack: \
-/!this->done && this->bsearch_max >= 1/ \
-{ \
+ dtrace:helper:ustack: \
+ /!this->done && this->bsearch_max >= 1/ \
+ { \
this->ii = (this->bsearch_min + this->bsearch_max) >> 1; \
-} \
+ } \
\
-dtrace:helper:ustack: \
-/!this->done && this->bsearch_max >= 1 && \
- this->position > COPYIN_UINT32(this->line_ends + V8_OFF_FA_DATA + \
- this->ii * sizeof (uint32_t))/ \
-{ \
+ dtrace:helper:ustack: \
+ /!this->done && this->bsearch_max >= 1 && \
+ this->position > SMI_VALUE( \
+ COPYIN_PTR(this->line_ends + V8_OFF_FA_DATA + \
+ this->ii * sizeof (uint32_t)))/ \
+ { \
this->bsearch_min = this->ii + 1; \
-} \
+ } \
\
-dtrace:helper:ustack: \
-/!this->done && this->bsearch_max >= 1 && \
- this->position <= COPYIN_UINT32(this->line_ends + V8_OFF_FA_DATA + \
- (this->ii - 1) * sizeof (uint32_t))/ \
-{ \
+ dtrace:helper:ustack: \
+ /!this->done && this->bsearch_max >= 1 && \
+ this->position <= SMI_VALUE( \
+ COPYIN_PTR(this->line_ends + V8_OFF_FA_DATA + \
+ (this->ii - 1) * sizeof (uint32_t)))/ \
+ { \
this->bsearch_max = this->ii - 1; \
-}
+ }
BSEARCH_LOOP
BSEARCH_LOOP
@@ -668,13 +601,12 @@ dtrace:helper:ustack:
/!this->done/
{
APPEND_CHR(' ');
- APPEND_CHR('l');
- APPEND_CHR('i');
- APPEND_CHR('n');
- APPEND_CHR('e');
+ APPEND_CHR4('l','i','n','e');
APPEND_CHR(' ');
APPEND_NUM(this->bsearch_line);
APPEND_CHR('\0');
this->done = 1;
stringof(this->buf);
}
+
+/* vim: set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab: */
diff --git a/test/addons/async-hello-world/binding.cc b/test/addons/async-hello-world/binding.cc
new file mode 100644
index 000000000..d0303f7ae
--- /dev/null
+++ b/test/addons/async-hello-world/binding.cc
@@ -0,0 +1,65 @@
+#include <unistd.h>
+#include <node.h>
+#include <v8.h>
+#include <uv.h>
+
+using namespace v8;
+using namespace node;
+
+struct async_req {
+ uv_work_t req;
+ int input;
+ int output;
+ Persistent<Function> callback;
+};
+
+void DoAsync (uv_work_t *r) {
+ async_req *req = reinterpret_cast<async_req *>(r->data);
+ sleep(1); // simulate CPU intensive process...
+ req->output = req->input * 2;
+}
+
+void AfterAsync (uv_work_t *r) {
+ HandleScope scope;
+ async_req *req = reinterpret_cast<async_req *>(r->data);
+
+ Handle<Value> argv[2] = { Null(), Integer::New(req->output) };
+
+ TryCatch try_catch;
+
+ req->callback->Call(Context::GetCurrent()->Global(), 2, argv);
+
+ // cleanup
+ req->callback.Dispose();
+ delete req;
+
+ if (try_catch.HasCaught()) {
+ FatalException(try_catch);
+ }
+}
+
+Handle<Value> Method(const Arguments& args) {
+ HandleScope scope;
+
+ async_req *req = new async_req;
+ req->req.data = req;
+
+ req->input = args[0]->IntegerValue();
+ req->output = 0;
+
+ Local<Function> callback = Local<Function>::Cast(args[1]);
+ req->callback = Persistent<Function>::New(callback);
+
+ uv_queue_work(uv_default_loop(),
+ &req->req,
+ DoAsync,
+ (uv_after_work_cb)AfterAsync);
+
+ return Undefined();
+}
+
+void init(Handle<Object> exports, Handle<Object> module) {
+ NODE_SET_METHOD(module, "exports", Method);
+}
+
+NODE_MODULE(binding, init);
diff --git a/test/addons/async-hello-world/binding.gyp b/test/addons/async-hello-world/binding.gyp
new file mode 100644
index 000000000..3bfb84493
--- /dev/null
+++ b/test/addons/async-hello-world/binding.gyp
@@ -0,0 +1,8 @@
+{
+ 'targets': [
+ {
+ 'target_name': 'binding',
+ 'sources': [ 'binding.cc' ]
+ }
+ ]
+}
diff --git a/test/addons/async-hello-world/test.js b/test/addons/async-hello-world/test.js
new file mode 100644
index 000000000..83f5e7206
--- /dev/null
+++ b/test/addons/async-hello-world/test.js
@@ -0,0 +1,15 @@
+var assert = require('assert');
+var binding = require('./build/Release/binding');
+var called = false;
+
+process.on('exit', function () {
+ assert(called);
+});
+
+binding(5, function (err, val) {
+ assert.equal(null, err);
+ assert.equal(10, val);
+ process.nextTick(function () {
+ called = true;
+ });
+});
diff --git a/test/addons/hello-world-function-export/binding.cc b/test/addons/hello-world-function-export/binding.cc
new file mode 100644
index 000000000..dcdb6b8ce
--- /dev/null
+++ b/test/addons/hello-world-function-export/binding.cc
@@ -0,0 +1,15 @@
+#include <node.h>
+#include <v8.h>
+
+using namespace v8;
+
+Handle<Value> Method(const Arguments& args) {
+ HandleScope scope;
+ return scope.Close(String::New("world"));
+}
+
+void init(Handle<Object> exports, Handle<Object> module) {
+ NODE_SET_METHOD(module, "exports", Method);
+}
+
+NODE_MODULE(binding, init);
diff --git a/test/addons/hello-world-function-export/binding.gyp b/test/addons/hello-world-function-export/binding.gyp
new file mode 100644
index 000000000..3bfb84493
--- /dev/null
+++ b/test/addons/hello-world-function-export/binding.gyp
@@ -0,0 +1,8 @@
+{
+ 'targets': [
+ {
+ 'target_name': 'binding',
+ 'sources': [ 'binding.cc' ]
+ }
+ ]
+}
diff --git a/test/addons/hello-world-function-export/test.js b/test/addons/hello-world-function-export/test.js
new file mode 100644
index 000000000..238e10538
--- /dev/null
+++ b/test/addons/hello-world-function-export/test.js
@@ -0,0 +1,4 @@
+var assert = require('assert');
+var binding = require('./build/Release/binding');
+assert.equal('world', binding());
+console.log('binding.hello() =', binding());
diff --git a/test/common.js b/test/common.js
index 4f96369f3..28faaf978 100644
--- a/test/common.js
+++ b/test/common.js
@@ -26,7 +26,7 @@ exports.testDir = path.dirname(__filename);
exports.fixturesDir = path.join(exports.testDir, 'fixtures');
exports.libDir = path.join(exports.testDir, '../lib');
exports.tmpDir = path.join(exports.testDir, 'tmp');
-exports.PORT = 12346;
+exports.PORT = +process.env.NODE_COMMON_PORT || 12346;
if (process.platform === 'win32') {
exports.PIPE = '\\\\.\\pipe\\libuv-test';
@@ -63,6 +63,17 @@ exports.ddCommand = function(filename, kilobytes) {
};
+exports.spawnCat = function(options) {
+ var spawn = require('child_process').spawn;
+
+ if (process.platform === 'win32') {
+ return spawn('more', [], options);
+ } else {
+ return spawn('cat', [], options);
+ }
+};
+
+
exports.spawnPwd = function(options) {
var spawn = require('child_process').spawn;
@@ -81,17 +92,15 @@ process.on('exit', function() {
if (!exports.globalCheck) return;
var knownGlobals = [setTimeout,
setInterval,
+ setImmediate,
clearTimeout,
clearInterval,
+ clearImmediate,
console,
Buffer,
process,
global];
- if (global.errno) {
- knownGlobals.push(errno);
- }
-
if (global.gc) {
knownGlobals.push(gc);
}
@@ -106,6 +115,14 @@ process.on('exit', function() {
knownGlobals.push(DTRACE_NET_SOCKET_READ);
knownGlobals.push(DTRACE_NET_SOCKET_WRITE);
}
+ if (global.COUNTER_NET_SERVER_CONNECTION) {
+ knownGlobals.push(COUNTER_NET_SERVER_CONNECTION);
+ knownGlobals.push(COUNTER_NET_SERVER_CONNECTION_CLOSE);
+ knownGlobals.push(COUNTER_HTTP_SERVER_REQUEST);
+ knownGlobals.push(COUNTER_HTTP_SERVER_RESPONSE);
+ knownGlobals.push(COUNTER_HTTP_CLIENT_REQUEST);
+ knownGlobals.push(COUNTER_HTTP_CLIENT_RESPONSE);
+ }
if (global.ArrayBuffer) {
knownGlobals.push(ArrayBuffer);
@@ -142,7 +159,9 @@ process.on('exit', function() {
var mustCallChecks = [];
-function runCallChecks() {
+function runCallChecks(exitCode) {
+ if (exitCode !== 0) return;
+
var failed = mustCallChecks.filter(function(context) {
return context.actual !== context.expected;
});
diff --git a/test/disabled/test-debug-brk-file.js b/test/disabled/test-debug-brk-file.js
new file mode 100644
index 000000000..ee9f4a58a
--- /dev/null
+++ b/test/disabled/test-debug-brk-file.js
@@ -0,0 +1,108 @@
+// 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');
+var assert = require('assert');
+var spawn = require('child_process').spawn;
+var path = require('path');
+var net = require('net');
+
+var isDone = false;
+var targetPath = path.resolve(common.fixturesDir, 'debug-target.js');
+
+var child = spawn(process.execPath, ['--debug-brk=' + common.PORT, targetPath]);
+child.stderr.on('data', function() {
+ child.emit('debug_start');
+});
+
+child.on('exit', function() {
+ assert(isDone);
+ console.log('ok');
+});
+
+child.once('debug_start', function() {
+ // delayed for some time until debug agent is ready
+ setTimeout(function() {
+ debug_client_connect();
+ }, 200);
+});
+
+
+function debug_client_connect() {
+ var msg = null;
+ var tmpBuf = '';
+
+ var conn = net.connect({port: common.PORT});
+ conn.setEncoding('utf8');
+ conn.on('data', function(data) {
+ tmpBuf += data;
+ parse();
+ });
+
+ function parse() {
+ if (!msg) {
+ msg = {
+ headers: null,
+ contentLength: 0
+ };
+ }
+ if (!msg.headers) {
+ var offset = tmpBuf.indexOf('\r\n\r\n');
+ if (offset < 0) return;
+ msg.headers = tmpBuf.substring(0, offset);
+ tmpBuf = tmpBuf.slice(offset + 4);
+ var matches = /Content-Length: (\d+)/.exec(msg.headers);
+ if (matches[1]) {
+ msg.contentLength = +(matches[1]);
+ }
+ }
+ if (msg.headers && Buffer.byteLength(tmpBuf) >= msg.contentLength) {
+ try {
+ var b = Buffer(tmpBuf);
+ var body = b.toString('utf8', 0, msg.contentLength);
+ tmpBuf = b.toString('utf8', msg.contentLength, b.length);
+
+ // get breakpoint list and check if it exists on line 0
+ if (!body.length) {
+ var req = JSON.stringify({'seq': 1, 'type': 'request',
+ 'command': 'listbreakpoints'});
+ conn.write('Content-Length: ' + req.length + '\r\n\r\n' + req);
+ return;
+ }
+
+ var obj = JSON.parse(body);
+ if (obj.type === 'response' && obj.command === 'listbreakpoints' &&
+ !obj.running) {
+ obj.body.breakpoints.forEach(function(bpoint) {
+ if (bpoint.line === 0) isDone = true;
+ });
+ }
+
+ var req = JSON.stringify({'seq': 100, 'type': 'request',
+ 'command': 'disconnect'});
+ conn.write('Content-Length: ' + req.length + '\r\n\r\n' + req);
+ } finally {
+ msg = null;
+ parse();
+ }
+ }
+ }
+}
diff --git a/test/simple/test-eio-race.js b/test/disabled/test-eio-race.js
index 558d09a9c..558d09a9c 100644
--- a/test/simple/test-eio-race.js
+++ b/test/disabled/test-eio-race.js
diff --git a/test/disabled/test-eio-race2.js b/test/disabled/test-eio-race2.js
new file mode 100644
index 000000000..df63a3150
--- /dev/null
+++ b/test/disabled/test-eio-race2.js
@@ -0,0 +1,43 @@
+// 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');
+var assert = require('assert');
+var path = require('path');
+var testTxt = path.join(common.fixturesDir, 'x.txt');
+var fs = require('fs');
+
+setTimeout(function() {
+ // put this in a timeout, just so it doesn't get bunched up with the
+ // require() calls..
+ var N = 30;
+ for (var i = 0; i < N; i++) {
+ console.log('start ' + i);
+ fs.readFile(testTxt, function(err, data) {
+ if (err) {
+ console.log('error! ' + e);
+ process.exit(1);
+ } else {
+ console.log('finish');
+ }
+ });
+ }
+}, 100);
diff --git a/test/simple/test-eio-race4.js b/test/disabled/test-eio-race4.js
index 8eaeda217..8eaeda217 100644
--- a/test/simple/test-eio-race4.js
+++ b/test/disabled/test-eio-race4.js
diff --git a/test/disabled/test-fs-sendfile.js b/test/disabled/test-fs-sendfile.js
deleted file mode 100644
index 44169bda6..000000000
--- a/test/disabled/test-fs-sendfile.js
+++ /dev/null
@@ -1,52 +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');
-var assert = require('assert');
-
-var net = require('net');
-var util = require('util');
-var x = path.join(common.fixturesDir, 'x.txt');
-var expected = 'xyz';
-
-var server = net.createServer(function(socket) {
- socket.on('receive', function(data) {
- found = data;
- client.close();
- socket.close();
- server.close();
- assert.equal(expected, found);
- });
-});
-server.listen(common.PORT);
-
-var client = net.createConnection(common.PORT);
-client.on('connect', function() {
- fs.open(x, 'r').addCallback(function(fd) {
- fs.sendfile(client.fd, fd, 0, expected.length)
- .addCallback(function(size) {
- assert.equal(expected.length, size);
- });
- });
-});
diff --git a/test/fixtures/GH-892-request.js b/test/fixtures/GH-892-request.js
index a43398e98..58b95a932 100644
--- a/test/fixtures/GH-892-request.js
+++ b/test/fixtures/GH-892-request.js
@@ -19,7 +19,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-// Called by test/simple/test-regress-GH-892.js
+// Called by test/pummel/test-regress-GH-892.js
var https = require('https');
var fs = require('fs');
@@ -32,13 +32,15 @@ var gotResponse = false;
var options = {
method: 'POST',
- port: PORT
+ port: PORT,
+ rejectUnauthorized: false
};
var req = https.request(options, function(res) {
assert.equal(200, res.statusCode);
gotResponse = true;
console.error('DONE');
+ res.resume();
});
req.end(new Buffer(bytesExpected));
diff --git a/test/fixtures/breakpoints_utf8.js b/test/fixtures/breakpoints_utf8.js
index cd05c7602..8f0eb9dfc 100644
--- a/test/fixtures/breakpoints_utf8.js
+++ b/test/fixtures/breakpoints_utf8.js
@@ -17,3 +17,7 @@ b();
setInterval(function() {
}, 5000);
+
+
+now = new Date();
+debugger;
diff --git a/test/fixtures/catch-stdout-error.js b/test/fixtures/catch-stdout-error.js
index a24494614..bdd09b5ab 100644
--- a/test/fixtures/catch-stdout-error.js
+++ b/test/fixtures/catch-stdout-error.js
@@ -25,7 +25,7 @@ function write() {
} catch (ex) {
throw new Error('this should never happen');
}
- process.nextTick(function() {
+ setImmediate(function() {
write();
});
}
diff --git a/test/fixtures/child-process-spawn-node.js b/test/fixtures/child-process-spawn-node.js
index 9bc6c1987..01a494ee5 100644
--- a/test/fixtures/child-process-spawn-node.js
+++ b/test/fixtures/child-process-spawn-node.js
@@ -1,10 +1,10 @@
var assert = require('assert');
-process.on('message', function(m) {
+function onmessage(m) {
console.log('CHILD got message:', m);
assert.ok(m.hello);
- // Note that we have to force exit.
- process.exit();
-});
+ process.removeListener('message', onmessage);
+}
+process.on('message', onmessage);
process.send({ foo: 'bar' });
diff --git a/test/fixtures/create-file.js b/test/fixtures/create-file.js
index 1e87bc92d..c711da671 100644
--- a/test/fixtures/create-file.js
+++ b/test/fixtures/create-file.js
@@ -24,6 +24,4 @@ var fs = require('fs');
var file_name = process.argv[2];
var file_size = parseInt(process.argv[3]);
-var fd = fs.openSync(file_name, 'w');
-fs.truncateSync(fd, file_size);
-fs.closeSync(fd);
+fs.truncateSync(file_name, file_size);
diff --git a/test/fixtures/debug-target.js b/test/fixtures/debug-target.js
new file mode 100644
index 000000000..d61710565
--- /dev/null
+++ b/test/fixtures/debug-target.js
@@ -0,0 +1,4 @@
+var a = 0;
+a += 1;
+a += 2;
+a += 3;
diff --git a/test/fixtures/fork2.js b/test/fixtures/fork2.js
deleted file mode 100644
index 900183ad9..000000000
--- a/test/fixtures/fork2.js
+++ /dev/null
@@ -1,23 +0,0 @@
-var assert = require('assert');
-var net = require('net');
-
-var connections = 0;
-
-process.on('message', function(m, serverHandle) {
- console.log('CHILD got message:', m);
- assert.ok(m.hello);
-
- assert.ok(serverHandle);
-
- var server = new net.Server(function(c) {
- connections++;
- console.log('CHILD got connection');
- c.destroy();
- process.send({ childConnections: connections });
- });
-
- server.listen(serverHandle, /* backlog */ 9, function() {
- process.send({ gotHandle: true });
- });
-});
-
diff --git a/test/fixtures/test-fs-readfile-error.js b/test/fixtures/test-fs-readfile-error.js
new file mode 100644
index 000000000..3f8d9a731
--- /dev/null
+++ b/test/fixtures/test-fs-readfile-error.js
@@ -0,0 +1,22 @@
+// 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.
+
+require('fs').readFile('/'); // throws EISDIR
diff --git a/test/fixtures/x1024.txt b/test/fixtures/x1024.txt
new file mode 100644
index 000000000..c6a9d2f1a
--- /dev/null
+++ b/test/fixtures/x1024.txt
@@ -0,0 +1 @@
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ No newline at end of file
diff --git a/test/simple/test-http-dns-fail.js b/test/internet/test-http-dns-fail.js
index 7d87b8e7f..7d87b8e7f 100644
--- a/test/simple/test-http-dns-fail.js
+++ b/test/internet/test-http-dns-fail.js
diff --git a/test/simple/test-net-connect-timeout.js b/test/internet/test-net-connect-timeout.js
index a5a11a8b0..a5a11a8b0 100644
--- a/test/simple/test-net-connect-timeout.js
+++ b/test/internet/test-net-connect-timeout.js
diff --git a/test/message/error_exit.js b/test/message/error_exit.js
new file mode 100644
index 000000000..f872386e9
--- /dev/null
+++ b/test/message/error_exit.js
@@ -0,0 +1,29 @@
+// 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 assert = require('assert');
+
+process.on('exit', function(code) {
+ console.error('Exiting with code=%d', code);
+});
+
+assert.equal(1, 2);
diff --git a/test/message/error_exit.out b/test/message/error_exit.out
new file mode 100644
index 000000000..11ea76fd7
--- /dev/null
+++ b/test/message/error_exit.out
@@ -0,0 +1,14 @@
+Exiting with code=1
+
+assert.js:*
+ throw new assert.AssertionError({
+ ^
+AssertionError: 1 == 2
+ at Object.<anonymous> (*test*message*error_exit.js:*:*)
+ at Module._compile (module.js:*:*)
+ at Object.Module._extensions..js (module.js:*:*)
+ at Module.load (module.js:*:*)
+ at Function.Module._load (module.js:*:*)
+ at Function.Module.runMain (module.js:*:*)
+ at startup (node.js:*:*)
+ at node.js:*:*
diff --git a/test/message/max_tick_depth.js b/test/message/max_tick_depth.js
new file mode 100644
index 000000000..9e10b901f
--- /dev/null
+++ b/test/message/max_tick_depth.js
@@ -0,0 +1,30 @@
+// 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');
+
+process.maxTickDepth = 10;
+var i = 20;
+process.nextTick(function f() {
+ console.error('tick %d', i);
+ if (i-- > 0)
+ process.nextTick(f);
+});
diff --git a/test/message/max_tick_depth.out b/test/message/max_tick_depth.out
new file mode 100644
index 000000000..f28548450
--- /dev/null
+++ b/test/message/max_tick_depth.out
@@ -0,0 +1,23 @@
+tick 20
+tick 19
+tick 18
+tick 17
+tick 16
+tick 15
+tick 14
+tick 13
+tick 12
+tick 11
+(node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
+tick 10
+tick 9
+tick 8
+tick 7
+tick 6
+tick 5
+tick 4
+tick 3
+tick 2
+tick 1
+(node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
+tick 0
diff --git a/test/message/max_tick_depth_trace.js b/test/message/max_tick_depth_trace.js
new file mode 100644
index 000000000..e58d04b41
--- /dev/null
+++ b/test/message/max_tick_depth_trace.js
@@ -0,0 +1,31 @@
+// 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');
+
+process.maxTickDepth = 10;
+process.traceDeprecation = true;
+var i = 20;
+process.nextTick(function f() {
+ console.error('tick %d', i);
+ if (i-- > 0)
+ process.nextTick(f);
+});
diff --git a/test/message/max_tick_depth_trace.out b/test/message/max_tick_depth_trace.out
new file mode 100644
index 000000000..22184a691
--- /dev/null
+++ b/test/message/max_tick_depth_trace.out
@@ -0,0 +1,35 @@
+tick 20
+tick 19
+tick 18
+tick 17
+tick 16
+tick 15
+tick 14
+tick 13
+tick 12
+tick 11
+Trace: (node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
+ at maxTickWarn (node.js:*:*)
+ at process.nextTick (node.js:*:*)
+ at f (*test*message*max_tick_depth_trace.js:*:*)
+ at process._tickCallback (node.js:*:*)
+ at Function.Module.runMain (module.js:*:*)
+ at startup (node.js:*:*)
+ at node.js:*:*
+tick 10
+tick 9
+tick 8
+tick 7
+tick 6
+tick 5
+tick 4
+tick 3
+tick 2
+tick 1
+Trace: (node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
+ at maxTickWarn (node.js:*:*)
+ at process.nextTick (node.js:*:*)
+ at f (*test*message*max_tick_depth_trace.js:*:*)
+ at process._tickCallback (node.js:*:*)
+ at process._tickFromSpinner (node.js:*:*)
+tick 0
diff --git a/test/message/nexttick_throw.js b/test/message/nexttick_throw.js
new file mode 100644
index 000000000..14b2990de
--- /dev/null
+++ b/test/message/nexttick_throw.js
@@ -0,0 +1,33 @@
+// 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');
+var assert = require('assert');
+
+process.nextTick(function() {
+ process.nextTick(function() {
+ process.nextTick(function() {
+ process.nextTick(function() {
+ undefined_reference_error_maker;
+ });
+ });
+ });
+});
diff --git a/test/message/nexttick_throw.out b/test/message/nexttick_throw.out
new file mode 100644
index 000000000..baced2ce8
--- /dev/null
+++ b/test/message/nexttick_throw.out
@@ -0,0 +1,10 @@
+
+*test*message*nexttick_throw.js:*
+ undefined_reference_error_maker;
+ ^
+ReferenceError: undefined_reference_error_maker is not defined
+ at *test*message*nexttick_throw.js:*:*
+ at process._tickCallback (node.js:*:*)
+ at Function.Module.runMain (module.js:*:*)
+ at startup (node.js:*:*)
+ at node.js:*:*
diff --git a/test/message/stdin_messages.out b/test/message/stdin_messages.out
index 7cdd79edb..cd7c12a7b 100644
--- a/test/message/stdin_messages.out
+++ b/test/message/stdin_messages.out
@@ -9,7 +9,8 @@ SyntaxError: Strict mode code may not include a with statement
at evalScript (node.js:*:*)
at Socket.<anonymous> (node.js:*:*)
at Socket.EventEmitter.emit (events.js:*:*)
- at Pipe.onread (net.js:*:*)
+ at _stream_readable.js:*:*
+ at process._tickCallback (node.js:*:*)
42
42
@@ -17,25 +18,27 @@ SyntaxError: Strict mode code may not include a with statement
throw new Error("hello")
^
Error: hello
- at [stdin]:1:7
+ at [stdin]:1:*
at Object.<anonymous> ([stdin]-wrapper:*:*)
at Module._compile (module.js:*:*)
at evalScript (node.js:*:*)
at Socket.<anonymous> (node.js:*:*)
at Socket.EventEmitter.emit (events.js:*:*)
- at Pipe.onread (net.js:*:*)
+ at _stream_readable.js:*:*
+ at process._tickCallback (node.js:*:*)
[stdin]:1
throw new Error("hello")
^
Error: hello
- at [stdin]:1:7
+ at [stdin]:1:*
at Object.<anonymous> ([stdin]-wrapper:*:*)
at Module._compile (module.js:*:*)
at evalScript (node.js:*:*)
at Socket.<anonymous> (node.js:*:*)
at Socket.EventEmitter.emit (events.js:*:*)
- at Pipe.onread (net.js:*:*)
+ at _stream_readable.js:*:*
+ at process._tickCallback (node.js:*:*)
100
[stdin]:1
@@ -48,7 +51,8 @@ ReferenceError: y is not defined
at evalScript (node.js:*:*)
at Socket.<anonymous> (node.js:*:*)
at Socket.EventEmitter.emit (events.js:*:*)
- at Pipe.onread (net.js:*:*)
+ at _stream_readable.js:*:*
+ at process._tickCallback (node.js:*:*)
[stdin]:1
var ______________________________________________; throw 10
diff --git a/test/message/timeout_throw.js b/test/message/timeout_throw.js
new file mode 100644
index 000000000..6704ee4da
--- /dev/null
+++ b/test/message/timeout_throw.js
@@ -0,0 +1,27 @@
+// 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');
+var assert = require('assert');
+
+setTimeout(function() {
+ undefined_reference_error_maker;
+});
diff --git a/test/message/timeout_throw.out b/test/message/timeout_throw.out
new file mode 100644
index 000000000..f6e207e38
--- /dev/null
+++ b/test/message/timeout_throw.out
@@ -0,0 +1,6 @@
+*test*message*timeout_throw.js:*
+ undefined_reference_error_maker;
+ ^
+ReferenceError: undefined_reference_error_maker is not defined
+ at null._onTimeout (*test*message*timeout_throw.js:*:*)
+ at Timer.listOnTimeout [as ontimeout] (timers.js:*:*)
diff --git a/test/message/undefined_reference_in_new_context.js b/test/message/undefined_reference_in_new_context.js
index cdd232d53..90cf43549 100644
--- a/test/message/undefined_reference_in_new_context.js
+++ b/test/message/undefined_reference_in_new_context.js
@@ -30,7 +30,7 @@ common.error('before');
var Script = process.binding('evals').NodeScript;
// undefined reference
-script = new Script('foo.bar = 5;');
+var script = new Script('foo.bar = 5;');
script.runInNewContext();
common.error('after');
diff --git a/test/message/undefined_reference_in_new_context.out b/test/message/undefined_reference_in_new_context.out
index f4e9b5c29..f8095ce33 100644
--- a/test/message/undefined_reference_in_new_context.out
+++ b/test/message/undefined_reference_in_new_context.out
@@ -9,6 +9,7 @@ ReferenceError: foo is not defined
at Module._compile (module.js:*)
at *..js (module.js:*)
at Module.load (module.js:*)
- at *._load (module.js:*)
- at Module.runMain (module.js:*)
- at *._tickCallback (node.js:*)
+ at Function.Module._load (module.js:*:*)
+ at Function.Module.runMain (module.js:*:*)
+ at startup (node.js:*:*)
+ at node.js:*:*
diff --git a/test/pummel/test-crypto-dh.js b/test/pummel/test-crypto-dh.js
index 8637a7f0a..e4e883f69 100644
--- a/test/pummel/test-crypto-dh.js
+++ b/test/pummel/test-crypto-dh.js
@@ -66,5 +66,5 @@ for (var name in hashes) {
group2.generateKeys();
var key1 = group1.computeSecret(group2.getPublicKey());
var key2 = group2.computeSecret(group1.getPublicKey());
- assert.equal(key1, key2);
+ assert.deepEqual(key1, key2);
}
diff --git a/test/pummel/test-dh-regr.js b/test/pummel/test-dh-regr.js
index 2e626bd0b..2910dedc2 100644
--- a/test/pummel/test-dh-regr.js
+++ b/test/pummel/test-dh-regr.js
@@ -33,7 +33,7 @@ for (var i = 0; i < 2000; i++) {
a.generateKeys();
b.generateKeys();
- assert.equal(
+ assert.deepEqual(
a.computeSecret(b.getPublicKey()),
b.computeSecret(a.getPublicKey()),
'secrets should be equal!'
diff --git a/test/pummel/test-dtrace-jsstack.js b/test/pummel/test-dtrace-jsstack.js
new file mode 100644
index 000000000..6779a766a
--- /dev/null
+++ b/test/pummel/test-dtrace-jsstack.js
@@ -0,0 +1,107 @@
+// 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');
+var assert = require('assert');
+var os = require('os');
+var util = require('util');
+
+if (os.type() != 'SunOS') {
+ console.error('Skipping because DTrace not available.');
+ process.exit(0);
+}
+
+/*
+ * Some functions to create a recognizable stack.
+ */
+var frames = [ 'stalloogle', 'bagnoogle', 'doogle' ];
+var expected;
+
+var stalloogle = function (str) {
+ expected = str;
+ os.loadavg();
+};
+
+var bagnoogle = function (arg0, arg1) {
+ stalloogle(arg0 + ' is ' + arg1 + ' except that it is read-only');
+};
+
+var done = false;
+
+var doogle = function () {
+ if (!done)
+ setTimeout(doogle, 10);
+
+ bagnoogle('The bfs command', '(almost) like ed(1)');
+};
+
+var spawn = require('child_process').spawn;
+var prefix = '/var/tmp/node';
+var corefile = prefix + '.' + process.pid;
+
+/*
+ * We're going to use DTrace to stop us, gcore us, and set us running again
+ * when we call getloadavg() -- with the implicit assumption that our
+ * deepest function is the only caller of os.loadavg().
+ */
+var dtrace = spawn('dtrace', [ '-qwn', 'syscall::getloadavg:entry/pid == ' +
+ process.pid + '/{ustack(100, 8192); exit(0); }' ]);
+
+var output = '';
+
+dtrace.stderr.on('data', function (data) {
+ console.log('dtrace: ' + data);
+});
+
+dtrace.stdout.on('data', function (data) {
+ output += data;
+});
+
+dtrace.on('exit', function (code) {
+ if (code != 0) {
+ console.error('dtrace exited with code ' + code);
+ process.exit(code);
+ }
+
+ done = true;
+
+ var sentinel = '(anon) as ';
+ var lines = output.split('\n');
+
+ for (var i = 0; i < lines.length; i++) {
+ var line = lines[i];
+
+ if (line.indexOf(sentinel) == -1 || frames.length === 0)
+ continue;
+
+ var frame = line.substr(line.indexOf(sentinel) + sentinel.length);
+ var top = frames.shift();
+
+ assert.equal(frame.indexOf(top), 0, 'unexpected frame where ' +
+ top + ' was expected');
+ }
+
+ assert.equal(frames.length, 0, 'did not find expected frame ' + frames[0]);
+ process.exit(0);
+});
+
+setTimeout(doogle, 10);
+
diff --git a/test/pummel/test-http-upload-timeout.js b/test/pummel/test-http-upload-timeout.js
index 417749cde..8a37de4ac 100644
--- a/test/pummel/test-http-upload-timeout.js
+++ b/test/pummel/test-http-upload-timeout.js
@@ -41,6 +41,7 @@ server.on('request', function(req, res) {
server.close();
}
});
+ req.resume();
});
server.listen(common.PORT, '127.0.0.1', function() {
diff --git a/test/pummel/test-https-ci-reneg-attack.js b/test/pummel/test-https-ci-reneg-attack.js
index 83b76b458..f7b0ac5d9 100644
--- a/test/pummel/test-https-ci-reneg-attack.js
+++ b/test/pummel/test-https-ci-reneg-attack.js
@@ -89,7 +89,7 @@ function test(next) {
var closed = false;
child.stdin.on('error', function(err) {
- assert.equal(err.code, 'EPIPE');
+ assert.equal(err.code, 'ECONNRESET');
closed = true;
});
child.stdin.on('close', function() {
diff --git a/test/pummel/test-https-large-response.js b/test/pummel/test-https-large-response.js
index e5382c45d..370415dcb 100644
--- a/test/pummel/test-https-large-response.js
+++ b/test/pummel/test-https-large-response.js
@@ -19,9 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
var common = require('../common');
var assert = require('assert');
@@ -53,7 +50,10 @@ var count = 0;
var gotResEnd = false;
server.listen(common.PORT, function() {
- https.get({ port: common.PORT }, function(res) {
+ https.get({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function(res) {
console.log('response!');
res.on('data', function(d) {
diff --git a/test/pummel/test-net-connect-econnrefused.js b/test/pummel/test-net-connect-econnrefused.js
index bb3ef5945..86231c73c 100644
--- a/test/pummel/test-net-connect-econnrefused.js
+++ b/test/pummel/test-net-connect-econnrefused.js
@@ -27,7 +27,7 @@ var net = require('net');
var ROUNDS = 5;
var ATTEMPTS_PER_ROUND = 200;
-var rounds = 0;
+var rounds = 1;
var reqs = 0;
pummel();
@@ -39,21 +39,20 @@ function pummel() {
net.createConnection(common.PORT).on('error', function(err) {
assert.equal(err.code, 'ECONNREFUSED');
if (--pending > 0) return;
- if (++rounds < ROUNDS) return pummel();
- check();
+ if (rounds == ROUNDS) return check();
+ rounds++;
+ pummel();
});
reqs++;
}
}
function check() {
- process.nextTick(function() {
- process.nextTick(function() {
- assert.equal(process._getActiveRequests().length, 0);
- assert.equal(process._getActiveHandles().length, 0);
- check_called = true;
- });
- });
+ setTimeout(function() {
+ assert.equal(process._getActiveRequests().length, 0);
+ assert.equal(process._getActiveHandles().length, 1); // the timer
+ check_called = true;
+ }, 0);
}
var check_called = false;
diff --git a/test/pummel/test-net-connect-memleak.js b/test/pummel/test-net-connect-memleak.js
index 269acbf64..c3f2daac2 100644
--- a/test/pummel/test-net-connect-memleak.js
+++ b/test/pummel/test-net-connect-memleak.js
@@ -30,7 +30,7 @@ net.createServer(function() {}).listen(common.PORT);
(function() {
// 2**26 == 64M entries
- for (var i = 0, junk = [123.456]; i < 26; ++i) junk = junk.concat(junk);
+ for (var i = 0, junk = [0]; i < 26; ++i) junk = junk.concat(junk);
net.createConnection(common.PORT, '127.0.0.1', function() {
assert(junk.length != 0); // keep reference alive
diff --git a/test/pummel/test-net-timeout2.js b/test/pummel/test-net-timeout2.js
index 5f9c03ee5..cc0516cc2 100644
--- a/test/pummel/test-net-timeout2.js
+++ b/test/pummel/test-net-timeout2.js
@@ -54,8 +54,8 @@ var server = net.createServer(function(socket) {
});
-server.listen(8888, function() {
- var s = net.connect(8888);
+server.listen(common.PORT, function() {
+ var s = net.connect(common.PORT);
s.pipe(process.stdout);
});
diff --git a/test/pummel/test-net-write-callbacks.js b/test/pummel/test-net-write-callbacks.js
index 45d1d59f3..aca418257 100644
--- a/test/pummel/test-net-write-callbacks.js
+++ b/test/pummel/test-net-write-callbacks.js
@@ -38,14 +38,27 @@ var server = net.Server(function(socket) {
});
});
+var lastCalled = -1;
+function makeCallback(c) {
+ var called = false;
+ return function() {
+ if (called)
+ throw new Error('called callback #' + c + ' more than once');
+ called = true;
+ if (c < lastCalled)
+ throw new Error('callbacks out of order. last=' + lastCalled +
+ ' current=' + c);
+ lastCalled = c;
+ cbcount++;
+ };
+}
+
server.listen(common.PORT, function() {
var client = net.createConnection(common.PORT);
client.on('connect', function() {
for (var i = 0; i < N; i++) {
- client.write('hello world', function() {
- cbcount++;
- });
+ client.write('hello world', makeCallback(i));
}
client.end();
});
diff --git a/test/pummel/test-postmortem-findjsobjects.js b/test/pummel/test-postmortem-findjsobjects.js
new file mode 100644
index 000000000..568e2ff05
--- /dev/null
+++ b/test/pummel/test-postmortem-findjsobjects.js
@@ -0,0 +1,99 @@
+// 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');
+var assert = require('assert');
+var os = require('os');
+var util = require('util');
+
+if (os.type() != 'SunOS') {
+ console.error('Skipping because postmortem debugging not available.');
+ process.exit(0);
+}
+
+/*
+ * Now we're going to fork ourselves to gcore
+ */
+var spawn = require('child_process').spawn;
+var prefix = '/var/tmp/node';
+var corefile = prefix + '.' + process.pid;
+var gcore = spawn('gcore', [ '-o', prefix, process.pid + '' ]);
+var output = '';
+var unlinkSync = require('fs').unlinkSync;
+var args = [ corefile ];
+
+if (process.env.MDB_LIBRARY_PATH && process.env.MDB_LIBRARY_PATH != '')
+ args = args.concat([ '-L', process.env.MDB_LIBRARY_PATH ]);
+
+function LanguageH(chapter) { this.OBEY = 'CHAPTER ' + parseInt(chapter, 10); }
+var obj = new LanguageH(1);
+
+gcore.stderr.on('data', function (data) {
+ console.log('gcore: ' + data);
+});
+
+gcore.on('exit', function (code) {
+ if (code != 0) {
+ console.error('gcore exited with code ' + code);
+ process.exit(code);
+ }
+
+ var mdb = spawn('mdb', args, { stdio: 'pipe' });
+
+ mdb.on('exit', function (code) {
+ var retained = '; core retained as ' + corefile;
+
+ if (code != 0) {
+ console.error('mdb exited with code ' + util.inspect(code) + retained);
+ process.exit(code);
+ }
+
+ var lines = output.split('\n');
+ var found = 0, i, expected = 'OBEY: ' + obj.OBEY, nexpected = 2;
+
+ for (var i = 0; i < lines.length; i++) {
+ if (lines[i].indexOf(expected) != -1)
+ found++;
+ }
+
+ assert.equal(found, nexpected, 'expected ' + nexpected +
+ ' objects, found ' + found + retained);
+
+ unlinkSync(corefile);
+ process.exit(0);
+ });
+
+ mdb.stdout.on('data', function (data) {
+ output += data;
+ });
+
+ mdb.stderr.on('data', function (data) {
+ console.log('mdb stderr: ' + data);
+ });
+
+ mdb.stdin.write('::load v8.so\n');
+ mdb.stdin.write('::findjsobjects -c LanguageH | ');
+ mdb.stdin.write('::findjsobjects | ::jsprint\n');
+ mdb.stdin.write('::findjsobjects -p OBEY | ');
+ mdb.stdin.write('::findjsobjects | ::jsprint\n');
+ mdb.stdin.end();
+});
+
diff --git a/test/pummel/test-postmortem-jsstack.js b/test/pummel/test-postmortem-jsstack.js
new file mode 100644
index 000000000..735e39e21
--- /dev/null
+++ b/test/pummel/test-postmortem-jsstack.js
@@ -0,0 +1,179 @@
+// 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');
+var assert = require('assert');
+var os = require('os');
+var util = require('util');
+
+if (os.type() != 'SunOS') {
+ console.error('Skipping because postmortem debugging not available.');
+ process.exit(0);
+}
+
+/*
+ * Some functions to create a recognizable stack.
+ */
+var frames = [ 'stalloogle', 'bagnoogle', 'doogle' ];
+var expected;
+
+var stalloogle = function (str) {
+ expected = str;
+ os.loadavg();
+};
+
+var bagnoogle = function (arg0, arg1) {
+ stalloogle(arg0 + ' is ' + arg1 + ' except that it is read-only');
+};
+
+var done = false;
+
+var doogle = function () {
+ if (!done)
+ setTimeout(doogle, 10);
+
+ bagnoogle('The bfs command', '(almost) like ed(1)');
+};
+
+var spawn = require('child_process').spawn;
+var prefix = '/var/tmp/node';
+var corefile = prefix + '.' + process.pid;
+var args = [ corefile ];
+
+if (process.env.MDB_LIBRARY_PATH && process.env.MDB_LIBRARY_PATH != '')
+ args = args.concat([ '-L', process.env.MDB_LIBRARY_PATH ]);
+
+/*
+ * We're going to use DTrace to stop us, gcore us, and set us running again
+ * when we call getloadavg() -- with the implicit assumption that our
+ * deepest function is the only caller of os.loadavg().
+ */
+var dtrace = spawn('dtrace', [ '-qwn', 'syscall::getloadavg:entry/pid == ' +
+ process.pid + '/{stop(); system("gcore -o ' +
+ prefix + ' %d", pid); system("prun %d", pid); exit(0); }' ]);
+
+var output = '';
+var unlinkSync = require('fs').unlinkSync;
+
+dtrace.stderr.on('data', function (data) {
+ console.log('dtrace: ' + data);
+});
+
+dtrace.on('exit', function (code) {
+ if (code != 0) {
+ console.error('dtrace exited with code ' + code);
+ process.exit(code);
+ }
+
+ done = true;
+
+ /*
+ * We have our core file. Now we need to fire up mdb to analyze it...
+ */
+ var mdb = spawn('mdb', args, { stdio: 'pipe' });
+
+ mdb.on('exit', function (code) {
+ var retained = '; core retained as ' + corefile;
+
+ if (code != 0) {
+ console.error('mdb exited with code ' + code + retained);
+ process.exit(code);
+ }
+
+ var sentinel = '<anonymous> (as ';
+ var arg1 = ' arg1: ';
+ var lines = output.split('\n');
+ var matched = 0;
+ var straddr = undefined;
+
+ for (var i = 0; i < lines.length; i++) {
+ var line = lines[i];
+
+ if (matched == 1 && line.indexOf(arg1) === 0) {
+ straddr = line.substr(arg1.length).split(' ')[0];
+ }
+
+ if (line.indexOf(sentinel) == -1 || frames.length === 0)
+ continue;
+
+ var frame = line.substr(line.indexOf(sentinel) + sentinel.length);
+ var top = frames.shift();
+
+ assert.equal(frame.indexOf(top), 0, 'unexpected frame where ' +
+ top + ' was expected' + retained);
+
+ matched++;
+ }
+
+ assert.equal(frames.length, 0, 'did not find expected frame ' +
+ frames[0] + retained);
+
+ assert.notEqual(straddr, undefined,
+ 'did not find arg1 for top frame' + retained);
+
+ /*
+ * Now we're going to take one more swing at the core file to print out
+ * the argument string that we found.
+ */
+ output = '';
+ mdb = spawn('mdb', args, { stdio: 'pipe' });
+
+ mdb.on('exit', function (code) {
+ if (code != 0) {
+ console.error('mdb (second) exited with code ' + code + retained);
+ process.exit(code);
+ }
+
+ assert.notEqual(output.indexOf(expected), -1, 'did not find arg1 (' +
+ straddr + ') to contain expected string' + retained);
+
+ unlinkSync(corefile);
+ process.exit(0);
+ });
+
+ mdb.stdout.on('data', function (data) {
+ output += data;
+ });
+
+ mdb.stderr.on('data', function (data) {
+ console.log('mdb (second) stderr: ' + data);
+ });
+
+ mdb.stdin.write('::load v8.so\n');
+ mdb.stdin.write(straddr + '::v8str\n');
+ mdb.stdin.end();
+ });
+
+ mdb.stdout.on('data', function (data) {
+ output += data;
+ });
+
+ mdb.stderr.on('data', function (data) {
+ console.log('mdb stderr: ' + data);
+ });
+
+ mdb.stdin.write('::load v8.so\n');
+ mdb.stdin.write('::jsstack -v\n');
+ mdb.stdin.end();
+});
+
+setTimeout(doogle, 10);
+
diff --git a/test/pummel/test-tls-ci-reneg-attack.js b/test/pummel/test-tls-ci-reneg-attack.js
index 778e288ca..b077ef4b2 100644
--- a/test/pummel/test-tls-ci-reneg-attack.js
+++ b/test/pummel/test-tls-ci-reneg-attack.js
@@ -87,7 +87,7 @@ function test(next) {
var closed = false;
child.stdin.on('error', function(err) {
- assert.equal(err.code, 'EPIPE');
+ assert.equal(err.code, 'ECONNRESET');
closed = true;
});
child.stdin.on('close', function() {
diff --git a/test/pummel/test-tls-connect-memleak.js b/test/pummel/test-tls-connect-memleak.js
index 3454b6d66..ceee4372d 100644
--- a/test/pummel/test-tls-connect-memleak.js
+++ b/test/pummel/test-tls-connect-memleak.js
@@ -35,7 +35,7 @@ tls.createServer({
(function() {
// 2**26 == 64M entries
- for (var i = 0, junk = [123.456]; i < 26; ++i) junk = junk.concat(junk);
+ for (var i = 0, junk = [0]; i < 26; ++i) junk = junk.concat(junk);
var options = { rejectUnauthorized: false };
tls.connect(common.PORT, '127.0.0.1', options, function() {
diff --git a/test/pummel/test-tls-throttle.js b/test/pummel/test-tls-throttle.js
index fcbc8c74b..a7119944a 100644
--- a/test/pummel/test-tls-throttle.js
+++ b/test/pummel/test-tls-throttle.js
@@ -19,11 +19,9 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
// Server sends a large string. Client counts bytes and pauses every few
// seconds. Makes sure that pause and resume work properly.
+
var common = require('../common');
var assert = require('assert');
var tls = require('tls');
@@ -55,7 +53,10 @@ var server = tls.Server(options, function(socket) {
var recvCount = 0;
server.listen(common.PORT, function() {
- var client = tls.connect(common.PORT);
+ var client = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ });
client.on('data', function(d) {
process.stdout.write('.');
diff --git a/test/simple/net-socket-readystate.js b/test/simple/net-socket-readystate.js
new file mode 100644
index 000000000..107d68e95
--- /dev/null
+++ b/test/simple/net-socket-readystate.js
@@ -0,0 +1,51 @@
+// 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');
+var net = require('net');
+var assert = require('assert');
+
+var sock = new net.Socket();
+
+var server = net.createServer().listen(common.PORT, function() {
+ assert(!sock.readable);
+ assert(!sock.writable);
+ assert.equal(sock.readyState, 'closed');
+
+ sock.connect(common.PORT, function() {
+ assert.equal(sock.readable, true);
+ assert.equal(sock.writable, true);
+ assert.equal(sock.readyState, 'open');
+
+ sock.end();
+ assert(!sock.writable);
+ assert.equal(sock.readyState, 'readOnly');
+
+ server.close();
+ sock.on('close', function() {
+ assert(!sock.readable);
+ assert(!sock.writable);
+ assert.equal(sock.readyState, 'closed');
+ });
+ });
+
+ assert.equal(sock.readyState, 'opening');
+});
diff --git a/test/simple/test-arraybuffer-slice.js b/test/simple/test-arraybuffer-slice.js
new file mode 100644
index 000000000..7703cf73f
--- /dev/null
+++ b/test/simple/test-arraybuffer-slice.js
@@ -0,0 +1,89 @@
+// 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.
+
+/*
+ * Tests to verify slice functionality of ArrayBuffer.
+ * (http://www.khronos.org/registry/typedarray/specs/latest/#5)
+ */
+
+var common = require('../common');
+var assert = require('assert');
+
+var buffer = new ArrayBuffer(8);
+var sub;
+var i;
+
+for (var i = 0; i < 8; i++) {
+ buffer[i] = i;
+}
+
+// slice a copy of buffer
+sub = buffer.slice(2, 6);
+
+// make sure it copied correctly
+assert.ok(sub instanceof ArrayBuffer);
+assert.equal(sub.byteLength, 4);
+
+for (i = 0; i < 4; i++) {
+ assert.equal(sub[i], i+2);
+}
+
+// modifications to the new slice shouldn't affect the original
+sub[0] = 999;
+
+for (i = 0; i < 8; i++) {
+ assert.equal(buffer[i], i);
+}
+
+// test optional end param
+sub = buffer.slice(5);
+
+assert.ok(sub instanceof ArrayBuffer);
+assert.equal(sub.byteLength, 3);
+for (i = 0; i < 3; i++) {
+ assert.equal(sub[i], i+5);
+}
+
+// test clamping
+sub = buffer.slice(-3, -1);
+
+assert.ok(sub instanceof ArrayBuffer);
+assert.equal(sub.byteLength, 2);
+for (i = 0; i < 2; i++) {
+ assert.equal(sub[i], i+5);
+}
+
+// test invalid clamping range
+sub = buffer.slice(-1, -3);
+
+assert.ok(sub instanceof ArrayBuffer);
+assert.equal(sub.byteLength, 0);
+
+// test wrong number of arguments
+var gotError = false;
+
+try {
+ sub = buffer.slice();
+} catch (e) {
+ gotError = true;
+}
+
+assert.ok(gotError); \ No newline at end of file
diff --git a/test/simple/test-buffer.js b/test/simple/test-buffer.js
index 11165f88c..b0ab6ed53 100644
--- a/test/simple/test-buffer.js
+++ b/test/simple/test-buffer.js
@@ -25,20 +25,29 @@ var assert = require('assert');
var SlowBuffer = require('buffer').SlowBuffer;
var Buffer = require('buffer').Buffer;
+// counter to ensure unique value is always copied
+var cntr = 0;
+
+// Regression test for segfault introduced in commit e501ce4.
+['base64','binary','ucs2','utf8','ascii'].forEach(function(encoding) {
+ var buf = new SlowBuffer(0);
+ buf.write('', encoding);
+});
+
var b = Buffer(1024); // safe constructor
-console.log('b.length == ' + b.length);
+console.log('b.length == %d', b.length);
assert.strictEqual(1024, b.length);
b[0] = -1;
-assert.equal(b[0], 255);
+assert.strictEqual(b[0], 255);
for (var i = 0; i < 1024; i++) {
b[i] = i % 256;
}
for (var i = 0; i < 1024; i++) {
- assert.equal(i % 256, b[i]);
+ assert.strictEqual(i % 256, b[i]);
}
var c = new Buffer(512);
@@ -46,39 +55,79 @@ console.log('c.length == %d', c.length);
assert.strictEqual(512, c.length);
// copy 512 bytes, from 0 to 512.
+b.fill(++cntr);
+c.fill(++cntr);
var copied = b.copy(c, 0, 0, 512);
-console.log('copied ' + copied + ' bytes from b into c');
-assert.equal(512, copied);
+console.log('copied %d bytes from b into c', copied);
+assert.strictEqual(512, copied);
for (var i = 0; i < c.length; i++) {
- common.print('.');
- assert.equal(i % 256, c[i]);
+ assert.strictEqual(b[i], c[i]);
}
-console.log('');
-// try to copy 513 bytes, and hope we don't overrun c, which is only 512 long
-var copied = b.copy(c, 0, 0, 513);
-console.log('copied ' + copied + ' bytes from b into c');
-assert.strictEqual(512, copied);
+// copy c into b, without specifying sourceEnd
+b.fill(++cntr);
+c.fill(++cntr);
+var copied = c.copy(b, 0, 0);
+console.log('copied %d bytes from c into b w/o sourceEnd', copied);
+assert.strictEqual(c.length, copied);
for (var i = 0; i < c.length; i++) {
- assert.equal(i % 256, c[i]);
+ assert.strictEqual(c[i], b[i]);
}
-// copy all of c back into b, without specifying sourceEnd
-var copied = c.copy(b, 0, 0);
-console.log('copied ' + copied + ' bytes from c back into b');
-assert.strictEqual(512, copied);
-for (var i = 0; i < b.length; i++) {
- assert.equal(i % 256, b[i]);
+// copy c into b, without specifying sourceStart
+b.fill(++cntr);
+c.fill(++cntr);
+var copied = c.copy(b, 0);
+console.log('copied %d bytes from c into b w/o sourceStart', copied);
+assert.strictEqual(c.length, copied);
+for (var i = 0; i < c.length; i++) {
+ assert.strictEqual(c[i], b[i]);
+}
+
+// copy longer buffer b to shorter c without targetStart
+b.fill(++cntr);
+c.fill(++cntr);
+var copied = b.copy(c);
+console.log('copied %d bytes from b into c w/o targetStart', copied);
+assert.strictEqual(c.length, copied);
+for (var i = 0; i < c.length; i++) {
+ assert.strictEqual(b[i], c[i]);
+}
+
+// copy starting near end of b to c
+b.fill(++cntr);
+c.fill(++cntr);
+var copied = b.copy(c, 0, b.length - Math.floor(c.length / 2));
+console.log('copied %d bytes from end of b into beginning of c', copied);
+assert.strictEqual(Math.floor(c.length / 2), copied);
+for (var i = 0; i < Math.floor(c.length / 2); i++) {
+ assert.strictEqual(b[b.length - Math.floor(c.length / 2) + i], c[i]);
+}
+for (var i = Math.floor(c.length /2) + 1; i < c.length; i++) {
+ assert.strictEqual(c[c.length-1], c[i]);
+}
+
+// try to copy 513 bytes, and check we don't overrun c
+b.fill(++cntr);
+c.fill(++cntr);
+var copied = b.copy(c, 0, 0, 513);
+console.log('copied %d bytes from b trying to overrun c', copied);
+assert.strictEqual(c.length, copied);
+for (var i = 0; i < c.length; i++) {
+ assert.strictEqual(b[i], c[i]);
}
// copy 768 bytes from b into b
+b.fill(++cntr);
+b.fill(++cntr, 256);
var copied = b.copy(b, 0, 256, 1024);
-console.log('copied ' + copied + ' bytes from b into c');
+console.log('copied %d bytes from b into b', copied);
assert.strictEqual(768, copied);
-for (var i = 0; i < c.length; i++) {
- assert.equal(i % 256, c[i]);
+for (var i = 0; i < b.length; i++) {
+ assert.strictEqual(cntr, b[i]);
}
+
// copy from fast to slow buffer
var sb = new SlowBuffer(b.length);
var copied = b.copy(sb);
@@ -96,53 +145,71 @@ try {
} catch (err) {
caught_error = err;
}
-assert.strictEqual('sourceEnd < sourceStart', caught_error.message);
-// try to copy to before the beginning of c
-caught_error = null;
-try {
- var copied = b.copy(c, -1, 0, 10);
-} catch (err) {
- caught_error = err;
+// copy from b to c with negative sourceStart
+b.fill(++cntr);
+c.fill(++cntr);
+var copied = b.copy(c, 0, -1);
+assert.strictEqual(c.length, copied);
+console.log('copied %d bytes from b into c w/ negative sourceStart', copied);
+for (var i = 0; i < c.length; i++) {
+ assert.strictEqual(b[i], c[i]);
}
-assert.strictEqual('targetStart out of bounds', caught_error.message);
-// try to copy to after the end of c
-caught_error = null;
-try {
- var copied = b.copy(c, 512, 0, 10);
-} catch (err) {
- caught_error = err;
+// check sourceEnd resets to targetEnd if former is greater than the latter
+b.fill(++cntr);
+c.fill(++cntr);
+var copied = b.copy(c, 0, 0, 1025);
+console.log('copied %d bytes from b into c', copied);
+for (var i = 0; i < c.length; i++) {
+ assert.strictEqual(b[i], c[i]);
}
-assert.strictEqual('targetStart out of bounds', caught_error.message);
-// try to copy starting before the beginning of b
-caught_error = null;
-try {
- var copied = b.copy(c, 0, -1, 1);
-} catch (err) {
- caught_error = err;
+// copy from fast buffer to slow buffer without parameters
+var sb = new SlowBuffer(b.length);
+sb.fill(++cntr, 0, sb.length);
+b.fill(++cntr);
+var copied = b.copy(sb);
+console.log('copied %d bytes from fast buffer to slow buffer', copied);
+for (var i = 0 ; i < b.length; i++) {
+ assert.strictEqual(b[i], sb[i]);
}
-assert.strictEqual('sourceStart out of bounds', caught_error.message);
-// try to copy starting after the end of b
+// throw with negative sourceEnd
+console.log('test copy at negative sourceEnd');
+assert.throws(function() {
+ b.copy(c, 0, 0, -1);
+}, RangeError);
+
+// throw when sourceStart is greater than sourceEnd
+assert.throws(function() {
+ b.copy(c, 0, 100, 10);
+}, RangeError);
+
+// throw attempting to copy after end of c
+assert.throws(function() {
+ b.copy(c, 512, 0, 10);
+}, RangeError);
+
+var caught_error;
+
+// invalid encoding for Buffer.toString
caught_error = null;
try {
- var copied = b.copy(c, 0, 1024, 1025);
+ var copied = b.toString('invalid');
} catch (err) {
caught_error = err;
}
-assert.strictEqual('sourceStart out of bounds', caught_error.message);
-
-// a too-low sourceEnd will get caught by earlier checks
+assert.strictEqual('Unknown encoding: invalid', caught_error.message);
-// try to copy ending after the end of b
+// invalid encoding for Buffer.write
+caught_error = null;
try {
- var copied = b.copy(c, 0, 1023, 1025);
+ var copied = b.write('test string', 0, 5, 'invalid');
} catch (err) {
caught_error = err;
}
-assert.strictEqual('sourceEnd out of bounds', caught_error.message);
+assert.strictEqual('Unknown encoding: invalid', caught_error.message);
// try to create 0-length buffers
new Buffer('');
@@ -615,6 +682,24 @@ assert.equal(0xad, b[1]);
assert.equal(0xbe, b[2]);
assert.equal(0xef, b[3]);
+// testing invalid encoding on SlowBuffer.toString
+caught_error = null;
+try {
+ var copied = b.toString('invalid');
+} catch (err) {
+ caught_error = err;
+}
+assert.strictEqual('Unknown encoding: invalid', caught_error.message);
+
+// testing invalid encoding on SlowBuffer.write
+caught_error = null;
+try {
+ var copied = b.write('some string', 0, 5, 'invalid');
+} catch (err) {
+ caught_error = err;
+}
+assert.strictEqual('Unknown encoding: invalid', caught_error.message);
+
// This should not segfault the program.
assert.throws(function() {
@@ -747,6 +832,30 @@ assert.equal(b.toString(), 'xxx');
// issue GH-3416
Buffer(Buffer(0), 0, 0);
+[ 'hex',
+ 'utf8',
+ 'utf-8',
+ 'ascii',
+ 'binary',
+ 'base64',
+ 'ucs2',
+ 'ucs-2',
+ 'utf16le',
+ 'utf-16le' ].forEach(function(enc) {
+ assert.equal(Buffer.isEncoding(enc), true);
+ });
+
+[ 'utf9',
+ 'utf-7',
+ 'Unicode-FTW',
+ 'new gnu gun' ].forEach(function(enc) {
+ assert.equal(Buffer.isEncoding(enc), false);
+ });
+
+
+// GH-3905
+assert.equal(JSON.stringify(Buffer('test')), '[116,101,115,116]');
+
// issue GH-4331
assert.throws(function() {
new Buffer(0xFFFFFFFF);
@@ -755,6 +864,51 @@ assert.throws(function() {
new Buffer(0xFFFFFFFFF);
}, TypeError);
+
+// attempt to overflow buffers, similar to previous bug in array buffers
+assert.throws(function() {
+ var buf = new Buffer(8);
+ buf.readFloatLE(0xffffffff);
+}, /Trying to access beyond buffer length/);
+
+assert.throws(function() {
+ var buf = new Buffer(8);
+ buf.writeFloatLE(0.0, 0xffffffff);
+}, /Trying to access beyond buffer length/);
+
+assert.throws(function() {
+ var buf = new SlowBuffer(8);
+ buf.readFloatLE(0xffffffff);
+}, /Trying to read beyond buffer length/);
+
+assert.throws(function() {
+ var buf = new SlowBuffer(8);
+ buf.writeFloatLE(0.0, 0xffffffff);
+}, /Trying to write beyond buffer length/);
+
+
+// ensure negative values can't get past offset
+assert.throws(function() {
+ var buf = new Buffer(8);
+ buf.readFloatLE(-1);
+}, /offset is not uint/);
+
+assert.throws(function() {
+ var buf = new Buffer(8);
+ buf.writeFloatLE(0.0, -1);
+}, /offset is not uint/);
+
+assert.throws(function() {
+ var buf = new SlowBuffer(8);
+ buf.readFloatLE(-1);
+}, /offset is not uint/);
+
+assert.throws(function() {
+ var buf = new SlowBuffer(8);
+ buf.writeFloatLE(0.0, -1);
+}, /offset is not uint/);
+
+
// SlowBuffer sanity checks.
assert.throws(function() {
var len = 0xfffff;
@@ -772,29 +926,23 @@ assert.throws(function() {
}, RangeError);
assert.throws(function() {
- var len = 0xfffff;
- var sbuf = new SlowBuffer(len);
- sbuf = sbuf.slice(-len); // Should throw.
- for (var i = 0; i < len; ++i) sbuf[i] = 0x42; // Try to force segfault.
-}, RangeError);
-
-assert.throws(function() {
var sbuf = new SlowBuffer(1);
var buf = new Buffer(sbuf, 1, 0);
buf.length = 0xffffffff;
buf.slice(0xffffff0, 0xffffffe); // Should throw.
}, Error);
-assert.throws(function() {
- var sbuf = new SlowBuffer(8);
- var buf = new Buffer(sbuf, 8, 0);
- buf.slice(-8); // Should throw. Throws Error instead of RangeError
- // for the sake of v0.8 compatibility.
-}, Error);
-
-assert.throws(function() {
- var sbuf = new SlowBuffer(16);
- var buf = new Buffer(sbuf, 8, 8);
- buf.slice(-8); // Should throw. Throws Error instead of RangeError
- // for the sake of v0.8 compatibility.
-}, Error);
+(function() {
+ var buf = new Buffer('0123456789');
+ assert.equal(buf.slice(-10, 10), '0123456789');
+ assert.equal(buf.slice(-20, 10), '0123456789');
+ assert.equal(buf.slice(-20, -10), '');
+ assert.equal(buf.slice(0, -1), '012345678');
+ assert.equal(buf.slice(2, -2), '234567');
+ assert.equal(buf.slice(0, 65536), '0123456789');
+ assert.equal(buf.slice(65536, 0), '');
+ for (var i = 0, s = buf.toString(); i < buf.length; ++i) {
+ assert.equal(buf.slice(-i), s.slice(-i));
+ assert.equal(buf.slice(0, -i), s.slice(0, -i));
+ }
+})();
diff --git a/test/simple/test-child-process-cwd.js b/test/simple/test-child-process-cwd.js
index dc8283b7a..b06e8e479 100644
--- a/test/simple/test-child-process-cwd.js
+++ b/test/simple/test-child-process-cwd.js
@@ -53,6 +53,8 @@ function testCwd(options, forCode, forData) {
});
returns++;
+
+ return child;
}
// Assume these exist, and 'pwd' gives us the right directory back
@@ -64,8 +66,19 @@ if (process.platform == 'win32') {
testCwd({cwd: '/'}, 0, '/');
}
-// Assume this doesn't exist, we expect exitcode=127
-testCwd({cwd: 'does-not-exist'}, 127);
+// Assume does-not-exist doesn't exist, expect exitCode=-1 and errno=ENOENT
+(function() {
+ var errors = 0;
+
+ testCwd({cwd: 'does-not-exist'}, -1).on('error', function(e) {
+ assert.equal(e.code, 'ENOENT');
+ errors++;
+ });
+
+ process.on('exit', function() {
+ assert.equal(errors, 1);
+ });
+})();
// Spawn() shouldn't try to chdir() so this should just work
testCwd(undefined, 0);
diff --git a/test/simple/test-child-process-disconnect.js b/test/simple/test-child-process-disconnect.js
index 2136aaf3e..162e7dde8 100644
--- a/test/simple/test-child-process-disconnect.js
+++ b/test/simple/test-child-process-disconnect.js
@@ -31,6 +31,8 @@ if (process.argv[2] === 'child') {
server.on('connection', function(socket) {
+ socket.resume();
+
process.on('disconnect', function() {
socket.end((process.connected).toString());
});
diff --git a/test/simple/test-child-process-exec-error.js b/test/simple/test-child-process-exec-error.js
new file mode 100644
index 000000000..2afe11443
--- /dev/null
+++ b/test/simple/test-child-process-exec-error.js
@@ -0,0 +1,45 @@
+// 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');
+var assert = require('assert');
+var child_process = require('child_process');
+
+function test(fun, code) {
+ var errors = 0;
+
+ fun('does-not-exist', function(err) {
+ assert.equal(err.code, code);
+ errors++;
+ });
+
+ process.on('exit', function() {
+ assert.equal(errors, 1);
+ });
+}
+
+if (process.platform === 'win32') {
+ test(child_process.exec, 1); // exit code of cmd.exe
+} else {
+ test(child_process.exec, 127); // exit code of /bin/sh
+}
+
+test(child_process.execFile, 'ENOENT');
diff --git a/test/simple/test-child-process-fork-exec-path.js b/test/simple/test-child-process-fork-exec-path.js
new file mode 100755
index 000000000..36ce11f37
--- /dev/null
+++ b/test/simple/test-child-process-fork-exec-path.js
@@ -0,0 +1,57 @@
+// 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 assert = require('assert');
+var cp = require('child_process');
+var fs = require('fs');
+var path = require('path');
+var common = require('../common');
+var msg = {test: 'this'};
+var nodePath = process.execPath;
+var symlinkPath = path.join(common.tmpDir, 'node-symlink');
+
+if (process.env.FORK) {
+ assert(process.send);
+ assert.equal(process.argv[0], symlinkPath);
+ process.send(msg);
+ process.exit();
+}
+else {
+ try {
+ fs.unlinkSync(symlinkPath);
+ }
+ catch (e) {
+ if (e.code !== 'ENOENT') throw e;
+ }
+ fs.symlinkSync(nodePath, symlinkPath);
+
+ var child = require('child_process').fork(__filename, {
+ execPath: symlinkPath,
+ env: { FORK: 'true' }
+ });
+ child.on('message', common.mustCall(function(recv) {
+ assert.deepEqual(msg, recv);
+ }));
+ child.on('exit', common.mustCall(function(code) {
+ fs.unlinkSync(symlinkPath);
+ assert.equal(code, 0);
+ }));
+}
diff --git a/test/simple/test-child-process-fork-getconnections.js b/test/simple/test-child-process-fork-getconnections.js
new file mode 100644
index 000000000..326c6d9f6
--- /dev/null
+++ b/test/simple/test-child-process-fork-getconnections.js
@@ -0,0 +1,106 @@
+// 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 assert = require('assert');
+var common = require('../common');
+var fork = require('child_process').fork;
+var net = require('net');
+var count = 12;
+
+if (process.argv[2] === 'child') {
+ var sockets = [];
+ var id = process.argv[3];
+
+ process.on('message', function(m, socket) {
+ if (socket) {
+ sockets.push(socket);
+ }
+
+ if (m.cmd === 'close') {
+ sockets[m.id].once('close', function() {
+ process.send({ id: m.id, status: 'closed' });
+ });
+ sockets[m.id].destroy();
+ }
+ });
+} else {
+ var child = fork(process.argv[1], ['child']);
+
+ var server = net.createServer();
+ var sockets = [];
+ var sent = 0;
+
+ server.on('connection', function(socket) {
+ child.send({ cmd: 'new' }, socket, { track: false });
+ sockets.push(socket);
+
+ if (sockets.length === count) {
+ closeSockets(0);
+ server.close();
+ }
+ });
+
+ var disconnected = 0;
+ server.on('listening', function() {
+
+ var j = count, client;
+ while (j--) {
+ client = net.connect(common.PORT, '127.0.0.1');
+ client.on('close', function() {
+ console.error('[m] CLIENT: close event');
+ disconnected += 1;
+ });
+ // XXX This resume() should be unnecessary.
+ // a stream high water mark should be enough to keep
+ // consuming the input.
+ client.resume();
+ }
+ });
+
+ function closeSockets(i) {
+ if (i === count) return;
+
+ sent++;
+ child.send({ id: i, cmd: 'close' });
+ child.once('message', function(m) {
+ assert(m.status === 'closed');
+ server.getConnections(function(err, num) {
+ closeSockets(i + 1);
+ });
+ });
+ };
+
+ var closeEmitted = false;
+ server.on('close', function() {
+ console.error('[m] server close');
+ closeEmitted = true;
+
+ child.kill();
+ });
+
+ server.listen(common.PORT, '127.0.0.1');
+
+ process.on('exit', function() {
+ assert.equal(sent, count);
+ assert.equal(disconnected, count);
+ assert.ok(closeEmitted);
+ });
+}
diff --git a/test/simple/test-child-process-fork-net2.js b/test/simple/test-child-process-fork-net2.js
index 48713566a..a8e8039b2 100644
--- a/test/simple/test-child-process-fork-net2.js
+++ b/test/simple/test-child-process-fork-net2.js
@@ -23,61 +23,93 @@ var assert = require('assert');
var common = require('../common');
var fork = require('child_process').fork;
var net = require('net');
+var count = 12;
if (process.argv[2] === 'child') {
-
- var endMe = null;
+ var needEnd = [];
+ var id = process.argv[3];
process.on('message', function(m, socket) {
if (!socket) return;
+ console.error('[%d] got socket', id, m);
+
// will call .end('end') or .write('write');
socket[m](m);
+ socket.resume();
+
+ socket.on('data', function() {
+ console.error('[%d] socket.data', id, m);
+ });
+
+ socket.on('end', function() {
+ console.error('[%d] socket.end', id, m);
+ });
+
// store the unfinished socket
if (m === 'write') {
- endMe = socket;
+ needEnd.push(socket);
}
+
+ socket.on('close', function() {
+ console.error('[%d] socket.close', id, m);
+ });
+
+ socket.on('finish', function() {
+ console.error('[%d] socket finished', id, m);
+ });
});
process.on('message', function(m) {
if (m !== 'close') return;
- endMe.end('end');
- endMe = null;
+ console.error('[%d] got close message', id);
+ needEnd.forEach(function(endMe, i) {
+ console.error('[%d] ending %d', id, i);
+ endMe.end('end');
+ });
});
process.on('disconnect', function() {
- endMe.end('end');
- endMe = null;
+ console.error('[%d] process disconnect, ending', id);
+ needEnd.forEach(function(endMe, i) {
+ console.error('[%d] ending %d', id, i);
+ endMe.end('end');
+ });
});
} else {
- var child1 = fork(process.argv[1], ['child']);
- var child2 = fork(process.argv[1], ['child']);
- var child3 = fork(process.argv[1], ['child']);
+ var child1 = fork(process.argv[1], ['child', '1']);
+ var child2 = fork(process.argv[1], ['child', '2']);
+ var child3 = fork(process.argv[1], ['child', '3']);
var server = net.createServer();
- var connected = 0;
+ var connected = 0,
+ closed = 0;
server.on('connection', function(socket) {
- switch (connected) {
+ switch (connected % 6) {
case 0:
- child1.send('end', socket); break;
+ child1.send('end', socket, { track: false }); break;
case 1:
- child1.send('write', socket); break;
+ child1.send('write', socket, { track: true }); break;
case 2:
- child2.send('end', socket); break;
+ child2.send('end', socket, { track: true }); break;
case 3:
- child2.send('write', socket); break;
+ child2.send('write', socket, { track: false }); break;
case 4:
- child3.send('end', socket); break;
+ child3.send('end', socket, { track: false }); break;
case 5:
- child3.send('write', socket); break;
+ child3.send('write', socket, { track: false }); break;
}
connected += 1;
- if (connected === 6) {
+ socket.once('close', function() {
+ console.log('[m] socket closed, total %d', ++closed);
+ });
+
+ if (connected === count) {
closeServer();
}
});
@@ -85,17 +117,23 @@ if (process.argv[2] === 'child') {
var disconnected = 0;
server.on('listening', function() {
- var j = 6, client;
+ var j = count, client;
while (j--) {
client = net.connect(common.PORT, '127.0.0.1');
client.on('close', function() {
+ console.error('[m] CLIENT: close event');
disconnected += 1;
});
+ // XXX This resume() should be unnecessary.
+ // a stream high water mark should be enough to keep
+ // consuming the input.
+ client.resume();
}
});
var closeEmitted = false;
server.on('close', function() {
+ console.error('[m] server close');
closeEmitted = true;
child1.kill();
@@ -107,14 +145,19 @@ if (process.argv[2] === 'child') {
var timeElasped = 0;
var closeServer = function() {
+ console.error('[m] closeServer');
var startTime = Date.now();
server.on('close', function() {
+ console.error('[m] emit(close)');
timeElasped = Date.now() - startTime;
});
+ console.error('[m] calling server.close');
server.close();
setTimeout(function() {
+ assert(!closeEmitted);
+ console.error('[m] sending close to children');
child1.send('close');
child2.send('close');
child3.disconnect();
@@ -122,8 +165,8 @@ if (process.argv[2] === 'child') {
};
process.on('exit', function() {
- assert.equal(disconnected, 6);
- assert.equal(connected, 6);
+ assert.equal(disconnected, count);
+ assert.equal(connected, count);
assert.ok(closeEmitted);
assert.ok(timeElasped >= 190 && timeElasped <= 1000,
'timeElasped was not between 190 and 1000 ms');
diff --git a/test/simple/test-child-process-fork-ref.js b/test/simple/test-child-process-fork-ref.js
new file mode 100644
index 000000000..21954ec73
--- /dev/null
+++ b/test/simple/test-child-process-fork-ref.js
@@ -0,0 +1,57 @@
+// 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');
+var assert = require('assert');
+var fork = require('child_process').fork;
+
+if (process.argv[2] === 'child') {
+ process.send('1');
+
+ // check that child don't instantly die
+ setTimeout(function() {
+ process.send('2');
+ }, 200);
+
+ process.on('disconnect', function () {
+ process.stdout.write('3');
+ });
+
+} else {
+ var child = fork(__filename, ['child'], {silent: true});
+
+ var ipc = [], stdout = '';
+
+ child.on('message', function (msg) {
+ ipc.push(msg);
+
+ if (msg === '2') child.disconnect();
+ });
+
+ child.stdout.on('data', function (chunk) {
+ stdout += chunk;
+ });
+
+ child.once('exit', function () {
+ assert.deepEqual(ipc, ['1', '2']);
+ assert.equal(stdout, '3');
+ });
+}
diff --git a/test/simple/test-child-process-fork-ref2.js b/test/simple/test-child-process-fork-ref2.js
new file mode 100644
index 000000000..3d604142b
--- /dev/null
+++ b/test/simple/test-child-process-fork-ref2.js
@@ -0,0 +1,45 @@
+// 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');
+var assert = require('assert');
+var fork = require('child_process').fork;
+
+if (process.argv[2] === 'child') {
+ console.log('child -> call disconnect');
+ process.disconnect();
+
+ setTimeout(function() {
+ console.log('child -> will this keep it alive?');
+ process.on('message', function () { });
+ }, 400);
+
+} else {
+ var child = fork(__filename, ['child']);
+
+ child.on('disconnect', function () {
+ console.log('parent -> disconnect');
+ });
+
+ child.once('exit', function () {
+ console.log('parent -> exit');
+ });
+}
diff --git a/test/simple/test-child-process-fork2.js b/test/simple/test-child-process-fork2.js
deleted file mode 100644
index 6add596e1..000000000
--- a/test/simple/test-child-process-fork2.js
+++ /dev/null
@@ -1,73 +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 assert = require('assert');
-var common = require('../common');
-var fork = require('child_process').fork;
-var net = require('net');
-
-var socketCloses = 0;
-var N = 10;
-
-var n = fork(common.fixturesDir + '/fork2.js');
-
-var messageCount = 0;
-
-var server = new net.Server(function(c) {
- console.log('PARENT got connection');
- c.destroy();
-});
-
-server.listen(common.PORT, /* backlog */ 9, function() {
- console.log('PARENT send child server handle');
- n.send({ hello: 'world' }, server._handle);
-});
-
-function makeConnections() {
- for (var i = 0; i < N; i++) {
- var socket = net.connect(common.PORT, function() {
- console.log('CLIENT connected');
- });
-
- socket.on('close', function() {
- socketCloses++;
- console.log('CLIENT closed ' + socketCloses);
- if (socketCloses == N) {
- n.kill();
- server.close();
- }
- });
- }
-}
-
-n.on('message', function(m) {
- console.log('PARENT got message:', m);
- if (m.gotHandle) {
- makeConnections();
- }
- messageCount++;
-});
-
-process.on('exit', function() {
- assert.equal(10, socketCloses);
- assert.ok(messageCount > 1);
-});
-
diff --git a/test/simple/test-child-process-fork3.js b/test/simple/test-child-process-fork3.js
new file mode 100644
index 000000000..0f75b029e
--- /dev/null
+++ b/test/simple/test-child-process-fork3.js
@@ -0,0 +1,25 @@
+// 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');
+var child_process = require('child_process');
+
+child_process.fork(common.fixturesDir + '/empty.js'); // should not hang
diff --git a/test/simple/test-child-process-ipc.js b/test/simple/test-child-process-ipc.js
index 8ccc505a8..e8144e439 100644
--- a/test/simple/test-child-process-ipc.js
+++ b/test/simple/test-child-process-ipc.js
@@ -42,10 +42,13 @@ child.stdout.setEncoding('utf8');
child.stdout.on('data', function(data) {
console.log('child said: ' + JSON.stringify(data));
if (!gotHelloWorld) {
+ console.error('testing for hello world');
assert.equal('hello world\r\n', data);
gotHelloWorld = true;
+ console.error('writing echo me');
child.stdin.write('echo me\r\n');
} else {
+ console.error('testing for echo me');
assert.equal('echo me\r\n', data);
gotEcho = true;
child.stdin.end();
diff --git a/test/simple/test-child-process-kill-throw.js b/test/simple/test-child-process-kill-throw.js
index f85bf5154..4beba7e7a 100644
--- a/test/simple/test-child-process-kill-throw.js
+++ b/test/simple/test-child-process-kill-throw.js
@@ -32,7 +32,7 @@ if (process.argv[2] === 'child') {
child.on('exit', function() {
child._handle = {
kill: function() {
- global.errno = 42;
+ process._errno = 42;
return -1;
}
};
diff --git a/test/simple/test-child-process-stdio-inherit.js b/test/simple/test-child-process-stdio-inherit.js
new file mode 100644
index 000000000..b63095475
--- /dev/null
+++ b/test/simple/test-child-process-stdio-inherit.js
@@ -0,0 +1,54 @@
+// 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');
+var assert = require('assert');
+var spawn = require('child_process').spawn;
+
+if (process.argv[2] === 'parent')
+ parent();
+else
+ grandparent();
+
+function grandparent() {
+ var child = spawn(process.execPath, [__filename, 'parent']);
+ child.stderr.pipe(process.stderr);
+ var output = '';
+ var input = 'asdfasdf';
+
+ child.stdout.on('data', function(chunk) {
+ output += chunk;
+ });
+ child.stdout.setEncoding('utf8');
+
+ child.stdin.end(input);
+
+ child.on('close', function(code, signal) {
+ assert.equal(code, 0);
+ assert.equal(signal, null);
+ assert.equal(output, input);
+ });
+}
+
+function parent() {
+ // should not immediately exit.
+ var child = common.spawnCat({ stdio: 'inherit' });
+}
diff --git a/test/simple/test-cli-eval.js b/test/simple/test-cli-eval.js
index 7e3e0cd6e..acb85d4ca 100644
--- a/test/simple/test-cli-eval.js
+++ b/test/simple/test-cli-eval.js
@@ -39,26 +39,30 @@ var filename = __filename.replace(/\\/g, '/');
child.exec(nodejs + ' --eval 42',
function(err, stdout, stderr) {
assert.equal(stdout, '');
+ assert.equal(stderr, '');
});
// assert that "42\n" is written to stderr
child.exec(nodejs + ' --eval "console.error(42)"',
function(err, stdout, stderr) {
+ assert.equal(stdout, '');
assert.equal(stderr, '42\n');
});
// assert that the expected output is written to stdout
-['--print --eval', '-p -e', '-pe'].forEach(function(s) {
+['--print', '-p -e', '-pe', '-p'].forEach(function(s) {
var cmd = nodejs + ' ' + s + ' ';
child.exec(cmd + '42',
function(err, stdout, stderr) {
assert.equal(stdout, '42\n');
+ assert.equal(stderr, '');
});
child.exec(cmd + "'[]'",
function(err, stdout, stderr) {
assert.equal(stdout, '[]\n');
+ assert.equal(stderr, '');
});
});
@@ -79,3 +83,10 @@ child.exec(nodejs + ' -e ""', function(status, stdout, stderr) {
assert.equal(stdout, '');
assert.equal(stderr, '');
});
+
+// "\\-42" should be interpreted as an escaped expression, not a switch
+child.exec(nodejs + ' -p "\\-42"',
+ function(err, stdout, stderr) {
+ assert.equal(stdout, '-42\n');
+ assert.equal(stderr, '');
+ });
diff --git a/test/simple/test-cluster-dgram-1.js b/test/simple/test-cluster-dgram-1.js
new file mode 100644
index 000000000..c6dc095d0
--- /dev/null
+++ b/test/simple/test-cluster-dgram-1.js
@@ -0,0 +1,115 @@
+// 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 NUM_WORKERS = 4;
+var PACKETS_PER_WORKER = 10;
+
+var assert = require('assert');
+var cluster = require('cluster');
+var common = require('../common');
+var dgram = require('dgram');
+
+
+if (process.platform === 'win32') {
+ console.warn("dgram clustering is currently not supported on windows.");
+ process.exit(0);
+}
+
+if (cluster.isMaster)
+ master();
+else
+ worker();
+
+
+function master() {
+ var listening = 0;
+
+ // Fork 4 workers.
+ for (var i = 0; i < NUM_WORKERS; i++)
+ cluster.fork();
+
+ // Wait until all workers are listening.
+ cluster.on('listening', function() {
+ if (++listening < NUM_WORKERS)
+ return;
+
+ // Start sending messages.
+ var buf = new Buffer('hello world');
+ var socket = dgram.createSocket('udp4');
+ var sent = 0;
+ doSend();
+
+ function doSend() {
+ socket.send(buf, 0, buf.length, common.PORT, '127.0.0.1', afterSend);
+ }
+
+ function afterSend() {
+ sent++;
+ if (sent < NUM_WORKERS * PACKETS_PER_WORKER) {
+ doSend();
+ } else {
+ console.log('master sent %d packets', sent);
+ socket.close();
+ }
+ }
+ });
+
+ // Set up event handlers for every worker. Each worker sends a message when
+ // it has received the expected number of packets. After that it disconnects.
+ for (var key in cluster.workers) {
+ if (cluster.workers.hasOwnProperty(key))
+ setupWorker(cluster.workers[key]);
+ }
+
+ function setupWorker(worker) {
+ var received = 0;
+
+ worker.on('message', function(msg) {
+ received = msg.received;
+ console.log('worker %d received %d packets', worker.id, received);
+ });
+
+ worker.on('disconnect', function() {
+ assert(received === PACKETS_PER_WORKER);
+ console.log('worker %d disconnected', worker.id);
+ });
+ }
+}
+
+
+function worker() {
+ var received = 0;
+
+ // Create udp socket and start listening.
+ var socket = dgram.createSocket('udp4');
+
+ socket.on('message', function(data, info) {
+ received++;
+
+ // Every 10 messages, notify the master.
+ if (received == PACKETS_PER_WORKER) {
+ process.send({received: received});
+ process.disconnect();
+ }
+ });
+
+ socket.bind(common.PORT);
+}
diff --git a/test/simple/test-cluster-dgram-2.js b/test/simple/test-cluster-dgram-2.js
new file mode 100644
index 000000000..d06ad7935
--- /dev/null
+++ b/test/simple/test-cluster-dgram-2.js
@@ -0,0 +1,81 @@
+// 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 condonitions:
+//
+// 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 NUM_WORKERS = 4;
+var PACKETS_PER_WORKER = 10;
+
+var assert = require('assert');
+var cluster = require('cluster');
+var common = require('../common');
+var dgram = require('dgram');
+
+
+if (process.platform === 'win32') {
+ console.warn("dgram clustering is currently not supported on windows.");
+ process.exit(0);
+}
+
+if (cluster.isMaster)
+ master();
+else
+ worker();
+
+
+function master() {
+ var i;
+ var received = 0;
+
+ // Start listening on a socket.
+ var socket = dgram.createSocket('udp4');
+ socket.bind(common.PORT);
+
+ // Disconnect workers when the expected number of messages have been
+ // received.
+ socket.on('message', function(data, info) {
+ received++;
+
+ if (received == PACKETS_PER_WORKER * NUM_WORKERS) {
+ console.log('master received %d packets', received);
+
+ // Close the socket.
+ socket.close();
+
+ // Disconnect all workers.
+ cluster.disconnect();
+ }
+ });
+
+ // Fork workers.
+ for (var i = 0; i < NUM_WORKERS; i++)
+ cluster.fork();
+}
+
+
+function worker() {
+ // Create udp socket and send packets to master.
+ var socket = dgram.createSocket('udp4');
+ var buf = new Buffer('hello world');
+
+ for (var i = 0; i < PACKETS_PER_WORKER; i++)
+ socket.send(buf, 0, buf.length, common.PORT, '127.0.0.1');
+
+ console.log('worker %d sent %d packets', cluster.worker.id, PACKETS_PER_WORKER);
+}
diff --git a/test/simple/test-cluster-eaddrinuse.js b/test/simple/test-cluster-eaddrinuse.js
new file mode 100644
index 000000000..73b1df0a5
--- /dev/null
+++ b/test/simple/test-cluster-eaddrinuse.js
@@ -0,0 +1,63 @@
+// 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.
+
+// Check that having a worker bind to a port that's already taken doesn't
+// leave the master process in a confused state. Releasing the port and
+// trying again should Just Work[TM].
+
+var common = require('../common');
+var assert = require('assert');
+var cluster = require('cluster');
+var fork = require('child_process').fork;
+var net = require('net');
+
+var id = '' + process.argv[2];
+
+if (id === 'undefined') {
+ var server = net.createServer(assert.fail);
+ server.listen(common.PORT, function() {
+ var worker = fork(__filename, ['worker']);
+ worker.on('message', function(msg) {
+ if (msg !== 'stop-listening') return;
+ server.close(function() {
+ worker.send('stopped-listening');
+ });
+ });
+ });
+}
+else if (id === 'worker') {
+ var server = net.createServer(assert.fail);
+ server.listen(common.PORT, assert.fail);
+ server.on('error', common.mustCall(function(e) {
+ assert(e.code, 'EADDRINUSE');
+ process.send('stop-listening');
+ process.once('message', function(msg) {
+ if (msg !== 'stopped-listening') return;
+ server = net.createServer(assert.fail);
+ server.listen(common.PORT, common.mustCall(function() {
+ server.close();
+ }));
+ });
+ }));
+}
+else {
+ assert(0); // Bad argument.
+}
diff --git a/test/simple/test-cluster-http-pipe.js b/test/simple/test-cluster-http-pipe.js
index 46d429ad6..7123bf627 100644
--- a/test/simple/test-cluster-http-pipe.js
+++ b/test/simple/test-cluster-http-pipe.js
@@ -53,6 +53,7 @@ http.createServer(function(req, res) {
}).listen(common.PIPE, function() {
var self = this;
http.get({ socketPath: common.PIPE, path: '/' }, function(res) {
+ res.resume();
res.on('end', function(err) {
if (err) throw err;
process.send('DONE');
diff --git a/test/simple/test-cluster-listening-port.js b/test/simple/test-cluster-listening-port.js
new file mode 100644
index 000000000..605ffd053
--- /dev/null
+++ b/test/simple/test-cluster-listening-port.js
@@ -0,0 +1,44 @@
+// 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 assert = require('assert');
+var cluster = require('cluster');
+var net = require('net');
+
+if (cluster.isMaster) {
+ var port = null;
+ cluster.fork();
+ cluster.on('listening', function(worker, address) {
+ port = address.port;
+ // ensure that the port is not 0 or null
+ assert(port);
+ // ensure that the port is numerical
+ assert.strictEqual(typeof(port), 'number');
+ worker.destroy();
+ });
+ process.on('exit', function() {
+ // ensure that the 'listening' handler has been called
+ assert(port);
+ });
+}
+else {
+ net.createServer(assert.fail).listen(0);
+}
diff --git a/test/simple/test-cluster-master-error.js b/test/simple/test-cluster-master-error.js
index 5e0e3fac6..ee2ed9eb4 100644
--- a/test/simple/test-cluster-master-error.js
+++ b/test/simple/test-cluster-master-error.js
@@ -62,7 +62,8 @@ if (cluster.isWorker) {
// throw accidently error
process.nextTick(function() {
- throw 'accidently error';
+ console.error('about to throw');
+ throw new Error('accidently error');
});
}
@@ -110,7 +111,7 @@ if (cluster.isWorker) {
master.on('exit', function(code) {
// Check that the cluster died accidently
- existMaster = (code === 1);
+ existMaster = !!code;
// Give the workers time to shut down
setTimeout(checkWorkers, 200);
diff --git a/test/simple/test-cluster-message.js b/test/simple/test-cluster-message.js
index 313355f7f..3a76dbc74 100644
--- a/test/simple/test-cluster-message.js
+++ b/test/simple/test-cluster-message.js
@@ -81,6 +81,7 @@ else if (cluster.isMaster) {
var check = function(type, result) {
checks[type].receive = true;
checks[type].correct = result;
+ console.error('check', checks);
var missing = false;
forEach(checks, function(type) {
@@ -88,6 +89,7 @@ else if (cluster.isMaster) {
});
if (missing === false) {
+ console.error('end client');
client.end();
}
};
diff --git a/test/simple/test-cluster-net-send.js b/test/simple/test-cluster-net-send.js
new file mode 100644
index 000000000..846ae5d7a
--- /dev/null
+++ b/test/simple/test-cluster-net-send.js
@@ -0,0 +1,67 @@
+// 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');
+var assert = require('assert');
+var fork = require('child_process').fork;
+var net = require('net');
+
+if (process.argv[2] !== 'child') {
+ console.error('[%d] master', process.pid);
+
+ var worker = fork(__filename, ['child']);
+ var called = false;
+
+ worker.once('message', function(msg, handle) {
+ assert.equal(msg, 'handle');
+ assert.ok(handle);
+ worker.send('got');
+
+ handle.on('data', function(data) {
+ called = true;
+ assert.equal(data.toString(), 'hello');
+ worker.kill();
+ });
+ });
+
+ process.once('exit', function() {
+ assert.ok(called);
+ });
+} else {
+ console.error('[%d] worker', process.pid);
+
+ var server = net.createServer(function(c) {
+ process.once('message', function(msg) {
+ assert.equal(msg, 'got');
+ c.end('hello');
+ });
+ });
+ server.listen(common.PORT, function() {
+ var socket = net.connect(common.PORT, '127.0.0.1', function() {
+ process.send('handle', socket);
+ });
+ });
+
+ process.on('disconnect', function() {
+ process.exit();
+ server.close();
+ });
+}
diff --git a/test/simple/test-console-instance.js b/test/simple/test-console-instance.js
new file mode 100644
index 000000000..e0166ebd3
--- /dev/null
+++ b/test/simple/test-console-instance.js
@@ -0,0 +1,80 @@
+// 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');
+var assert = require('assert');
+var Stream = require('stream');
+var Console = require('console').Console;
+var called = false;
+
+// ensure the Console instance doesn't write to the
+// process' "stdout" or "stderr" streams
+process.stdout.write = process.stderr.write = function() {
+ throw new Error('write() should not be called!');
+};
+
+// make sure that the "Console" function exists
+assert.equal('function', typeof Console);
+
+// make sure that the Console constructor throws
+// when not given a writable stream instance
+assert.throws(function () {
+ new Console();
+}, /Console expects a writable stream/);
+
+var out = new Stream();
+var err = new Stream();
+out.writable = err.writable = true;
+out.write = err.write = function(d) {};
+
+var c = new Console(out, err);
+
+out.write = err.write = function(d) {
+ assert.equal(d, 'test\n');
+ called = true;
+};
+
+assert(!called);
+c.log('test');
+assert(called);
+
+called = false;
+c.error('test');
+assert(called);
+
+out.write = function(d) {
+ assert.equal('{ foo: 1 }\n', d);
+ called = true;
+};
+
+called = false;
+c.dir({ foo: 1 });
+assert(called);
+
+// ensure that the console functions are bound to the console instance
+called = 0;
+out.write = function(d) {
+ called++;
+ assert.equal(d, called + ' ' + (called - 1) + ' [ 1, 2, 3 ]\n');
+};
+[1, 2, 3].forEach(c.log);
+assert.equal(3, called);
diff --git a/test/simple/test-console.js b/test/simple/test-console.js
index d07ca50ae..bef8772a8 100644
--- a/test/simple/test-console.js
+++ b/test/simple/test-console.js
@@ -43,13 +43,17 @@ console.log('foo', 'bar');
console.log('%s %s', 'foo', 'bar', 'hop');
console.log({slashes: '\\\\'});
+console._stderr = process.stdout;
+console.trace('This is a %j %d', { formatted: 'trace' }, 10, 'foo');
+
global.process.stdout.write = stdout_write;
+
assert.equal('foo\n', strings.shift());
assert.equal('foo bar\n', strings.shift());
assert.equal('foo bar hop\n', strings.shift());
assert.equal("{ slashes: '\\\\\\\\' }\n", strings.shift());
-
-process.stderr.write('hello world');
+assert.equal('Trace: This is a {"formatted":"trace"} 10 foo',
+ strings.shift().split('\n').shift());
assert.throws(function () {
console.timeEnd('no such label');
diff --git a/test/simple/test-crypto-binary-default.js b/test/simple/test-crypto-binary-default.js
new file mode 100644
index 000000000..85c5447a2
--- /dev/null
+++ b/test/simple/test-crypto-binary-default.js
@@ -0,0 +1,690 @@
+// 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.
+
+// This is the same as test/simple/test-crypto, but from before the shift
+// to use buffers by default.
+
+
+var common = require('../common');
+var assert = require('assert');
+
+try {
+ var crypto = require('crypto');
+} catch (e) {
+ console.log('Not compiled with OPENSSL support.');
+ process.exit();
+}
+
+crypto.DEFAULT_ENCODING = 'binary';
+
+var fs = require('fs');
+var path = require('path');
+
+// Test Certificates
+var caPem = fs.readFileSync(common.fixturesDir + '/test_ca.pem', 'ascii');
+var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii');
+var certPfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx');
+var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii');
+var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem',
+ 'ascii');
+var rsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_rsa_privkey.pem',
+ 'ascii');
+
+try {
+ var credentials = crypto.createCredentials(
+ {key: keyPem,
+ cert: certPem,
+ ca: caPem});
+} catch (e) {
+ console.log('Not compiled with OPENSSL support.');
+ process.exit();
+}
+
+// PFX tests
+assert.doesNotThrow(function() {
+ crypto.createCredentials({pfx:certPfx, passphrase:'sample'});
+});
+
+assert.throws(function() {
+ crypto.createCredentials({pfx:certPfx});
+}, 'mac verify failure');
+
+assert.throws(function() {
+ crypto.createCredentials({pfx:certPfx, passphrase:'test'});
+}, 'mac verify failure');
+
+assert.throws(function() {
+ crypto.createCredentials({pfx:'sample', passphrase:'test'});
+}, 'not enough data');
+
+// Test HMAC
+var h1 = crypto.createHmac('sha1', 'Node')
+ .update('some data')
+ .update('to hmac')
+ .digest('hex');
+assert.equal(h1, '19fd6e1ba73d9ed2224dd5094a71babe85d9a892', 'test HMAC');
+
+// Test HMAC-SHA-* (rfc 4231 Test Cases)
+var rfc4231 = [
+ {
+ key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'),
+ data: new Buffer('4869205468657265', 'hex'), // 'Hi There'
+ hmac: {
+ sha224: '896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22',
+ sha256:
+ 'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c' +
+ '2e32cff7',
+ sha384:
+ 'afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c' +
+ '7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6',
+ sha512:
+ '87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b305' +
+ '45e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f170' +
+ '2e696c203a126854'
+ }
+ },
+ {
+ key: new Buffer('4a656665', 'hex'), // 'Jefe'
+ data: new Buffer('7768617420646f2079612077616e7420666f72206e6f74686' +
+ '96e673f', 'hex'), // 'what do ya want for nothing?'
+ hmac: {
+ sha224: 'a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44',
+ sha256:
+ '5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b9' +
+ '64ec3843',
+ sha384:
+ 'af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec373' +
+ '6322445e8e2240ca5e69e2c78b3239ecfab21649',
+ sha512:
+ '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7' +
+ 'ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b' +
+ '636e070a38bce737'
+ }
+ },
+ {
+ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+ data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddddddd' +
+ 'ddddddddddddddddddddddddddddddddddddddddddddddddddd',
+ 'hex'),
+ hmac: {
+ sha224: '7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea',
+ sha256:
+ '773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514' +
+ 'ced565fe',
+ sha384:
+ '88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e5' +
+ '5966144b2a5ab39dc13814b94e3ab6e101a34f27',
+ sha512:
+ 'fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33' +
+ 'b2279d39bf3e848279a722c806b485a47e67c807b946a337bee89426' +
+ '74278859e13292fb'
+ }
+ },
+ {
+ key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819',
+ 'hex'),
+ data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' +
+ 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd',
+ 'hex'),
+ hmac: {
+ sha224: '6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a',
+ sha256:
+ '82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff4' +
+ '6729665b',
+ sha384:
+ '3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e' +
+ '1f573b4e6801dd23c4a7d679ccf8a386c674cffb',
+ sha512:
+ 'b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050' +
+ '361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2d' +
+ 'e2adebeb10a298dd'
+ }
+ },
+
+ {
+ key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'),
+ // 'Test With Truncation'
+ data: new Buffer('546573742057697468205472756e636174696f6e', 'hex'),
+ hmac: {
+ sha224: '0e2aea68a90c8d37c988bcdb9fca6fa8',
+ sha256: 'a3b6167473100ee06e0c796c2955552b',
+ sha384: '3abf34c3503b2a23a46efc619baef897',
+ sha512: '415fad6271580a531d4179bc891d87a6'
+ },
+ truncate: true
+ },
+ {
+ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaa', 'hex'),
+ // 'Test Using Larger Than Block-Size Key - Hash Key First'
+ data: new Buffer('54657374205573696e67204c6172676572205468616e20426' +
+ 'c6f636b2d53697a65204b6579202d2048617368204b657920' +
+ '4669727374', 'hex'),
+ hmac: {
+ sha224: '95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e',
+ sha256:
+ '60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f' +
+ '0ee37f54',
+ sha384:
+ '4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05' +
+ '033ac4c60c2ef6ab4030fe8296248df163f44952',
+ sha512:
+ '80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b0137' +
+ '83f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec' +
+ '8b915a985d786598'
+ }
+ },
+ {
+ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaa', 'hex'),
+ // 'This is a test using a larger than block-size key and a larger ' +
+ // 'than block-size data. The key needs to be hashed before being ' +
+ // 'used by the HMAC algorithm.'
+ data: new Buffer('5468697320697320612074657374207573696e672061206c6' +
+ '172676572207468616e20626c6f636b2d73697a65206b6579' +
+ '20616e642061206c6172676572207468616e20626c6f636b2' +
+ 'd73697a6520646174612e20546865206b6579206e65656473' +
+ '20746f20626520686173686564206265666f7265206265696' +
+ 'e6720757365642062792074686520484d414320616c676f72' +
+ '6974686d2e', 'hex'),
+ hmac: {
+ sha224: '3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1',
+ sha256:
+ '9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f5153' +
+ '5c3a35e2',
+ sha384:
+ '6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82' +
+ '461e99c5a678cc31e799176d3860e6110c46523e',
+ sha512:
+ 'e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d' +
+ '20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de04460' +
+ '65c97440fa8c6a58'
+ }
+ }
+];
+
+for (var i = 0, l = rfc4231.length; i < l; i++) {
+ for (var hash in rfc4231[i]['hmac']) {
+ var result = crypto.createHmac(hash, rfc4231[i]['key'])
+ .update(rfc4231[i]['data'])
+ .digest('hex');
+ if (rfc4231[i]['truncate']) {
+ result = result.substr(0, 32); // first 128 bits == 32 hex chars
+ }
+ assert.equal(rfc4231[i]['hmac'][hash],
+ result,
+ 'Test HMAC-' + hash + ': Test case ' + (i + 1) + ' rfc 4231');
+ }
+}
+
+// Test HMAC-MD5/SHA1 (rfc 2202 Test Cases)
+var rfc2202_md5 = [
+ {
+ key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'),
+ data: 'Hi There',
+ hmac: '9294727a3638bb1c13f48ef8158bfc9d'
+ },
+ {
+ key: 'Jefe',
+ data: 'what do ya want for nothing?',
+ hmac: '750c783e6ab0b503eaa86e310a5db738'
+ },
+ {
+ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+ data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddddddd' +
+ 'ddddddddddddddddddddddddddddddddddddddddddddddddddd',
+ 'hex'),
+ hmac: '56be34521d144c88dbb8c733f0e8b3f6'
+ },
+ {
+ key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819',
+ 'hex'),
+ data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' +
+ 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' +
+ 'cdcdcdcdcd',
+ 'hex'),
+ hmac: '697eaf0aca3a3aea3a75164746ffaa79'
+ },
+ {
+ key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'),
+ data: 'Test With Truncation',
+ hmac: '56461ef2342edc00f9bab995690efd4c'
+ },
+ {
+ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaa',
+ 'hex'),
+ data: 'Test Using Larger Than Block-Size Key - Hash Key First',
+ hmac: '6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd'
+ },
+ {
+ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaa',
+ 'hex'),
+ data:
+ 'Test Using Larger Than Block-Size Key and Larger Than One ' +
+ 'Block-Size Data',
+ hmac: '6f630fad67cda0ee1fb1f562db3aa53e'
+ }
+];
+var rfc2202_sha1 = [
+ {
+ key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'),
+ data: 'Hi There',
+ hmac: 'b617318655057264e28bc0b6fb378c8ef146be00'
+ },
+ {
+ key: 'Jefe',
+ data: 'what do ya want for nothing?',
+ hmac: 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79'
+ },
+ {
+ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+ data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddd' +
+ 'ddddddddddddddddddddddddddddddddddddddddddddd' +
+ 'dddddddddd',
+ 'hex'),
+ hmac: '125d7342b9ac11cd91a39af48aa17b4f63f175d3'
+ },
+ {
+ key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819',
+ 'hex'),
+ data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' +
+ 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' +
+ 'cdcdcdcdcd',
+ 'hex'),
+ hmac: '4c9007f4026250c6bc8414f9bf50c86c2d7235da'
+ },
+ {
+ key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'),
+ data: 'Test With Truncation',
+ hmac: '4c1a03424b55e07fe7f27be1d58bb9324a9a5a04'
+ },
+ {
+ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaa',
+ 'hex'),
+ data: 'Test Using Larger Than Block-Size Key - Hash Key First',
+ hmac: 'aa4ae5e15272d00e95705637ce8a3b55ed402112'
+ },
+ {
+ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
+ 'aaaaaaaaaaaaaaaaaaaaaa',
+ 'hex'),
+ data:
+ 'Test Using Larger Than Block-Size Key and Larger Than One ' +
+ 'Block-Size Data',
+ hmac: 'e8e99d0f45237d786d6bbaa7965c7808bbff1a91'
+ }
+];
+
+for (var i = 0, l = rfc2202_md5.length; i < l; i++) {
+ assert.equal(rfc2202_md5[i]['hmac'],
+ crypto.createHmac('md5', rfc2202_md5[i]['key'])
+ .update(rfc2202_md5[i]['data'])
+ .digest('hex'),
+ 'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202');
+}
+for (var i = 0, l = rfc2202_sha1.length; i < l; i++) {
+ assert.equal(rfc2202_sha1[i]['hmac'],
+ crypto.createHmac('sha1', rfc2202_sha1[i]['key'])
+ .update(rfc2202_sha1[i]['data'])
+ .digest('hex'),
+ 'Test HMAC-SHA1 : Test case ' + (i + 1) + ' rfc 2202');
+}
+
+// Test hashing
+var a0 = crypto.createHash('sha1').update('Test123').digest('hex');
+var a1 = crypto.createHash('md5').update('Test123').digest('binary');
+var a2 = crypto.createHash('sha256').update('Test123').digest('base64');
+var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary
+var a4 = crypto.createHash('sha1').update('Test123').digest('buffer');
+
+assert.equal(a0, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1');
+assert.equal(a1, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' +
+ '\u00bd\u008c', 'Test MD5 as binary');
+assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=',
+ 'Test SHA256 as base64');
+
+assert.equal(a3, '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' +
+ '\u0094\u0015l\u00b8\u008dQ+\u00db\u001d\u00c4\u00b5}\u00b2' +
+ '\u00d6\u0092\u00a3\u00df\u00a2i\u00a1\u009b\n\n*\u000f' +
+ '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' +
+ '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'',
+ 'Test SHA512 as assumed binary');
+
+assert.deepEqual(a4,
+ new Buffer('8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'hex'),
+ 'Test SHA1');
+
+// Test multiple updates to same hash
+var h1 = crypto.createHash('sha1').update('Test123').digest('hex');
+var h2 = crypto.createHash('sha1').update('Test').update('123').digest('hex');
+assert.equal(h1, h2, 'multipled updates');
+
+// Test hashing for binary files
+var fn = path.join(common.fixturesDir, 'sample.png');
+var sha1Hash = crypto.createHash('sha1');
+var fileStream = fs.createReadStream(fn);
+fileStream.on('data', function(data) {
+ sha1Hash.update(data);
+});
+fileStream.on('close', function() {
+ assert.equal(sha1Hash.digest('hex'),
+ '22723e553129a336ad96e10f6aecdf0f45e4149e',
+ 'Test SHA1 of sample.png');
+});
+
+// Issue #2227: unknown digest method should throw an error.
+assert.throws(function() {
+ crypto.createHash('xyzzy');
+});
+
+// Test signing and verifying
+var s1 = crypto.createSign('RSA-SHA1')
+ .update('Test123')
+ .sign(keyPem, 'base64');
+var verified = crypto.createVerify('RSA-SHA1')
+ .update('Test')
+ .update('123')
+ .verify(certPem, s1, 'base64');
+assert.strictEqual(verified, true, 'sign and verify (base 64)');
+
+var s2 = crypto.createSign('RSA-SHA256')
+ .update('Test123')
+ .sign(keyPem); // binary
+var verified = crypto.createVerify('RSA-SHA256')
+ .update('Test')
+ .update('123')
+ .verify(certPem, s2); // binary
+assert.strictEqual(verified, true, 'sign and verify (binary)');
+
+var s3 = crypto.createSign('RSA-SHA1')
+ .update('Test123')
+ .sign(keyPem, 'buffer');
+var verified = crypto.createVerify('RSA-SHA1')
+ .update('Test')
+ .update('123')
+ .verify(certPem, s3);
+assert.strictEqual(verified, true, 'sign and verify (buffer)');
+
+
+function testCipher1(key) {
+ // Test encryption and decryption
+ var plaintext = 'Keep this a secret? No! Tell everyone about node.js!';
+ var cipher = crypto.createCipher('aes192', key);
+
+ // encrypt plaintext which is in utf8 format
+ // to a ciphertext which will be in hex
+ var ciph = cipher.update(plaintext, 'utf8', 'hex');
+ // Only use binary or hex, not base64.
+ ciph += cipher.final('hex');
+
+ var decipher = crypto.createDecipher('aes192', key);
+ var txt = decipher.update(ciph, 'hex', 'utf8');
+ txt += decipher.final('utf8');
+
+ assert.equal(txt, plaintext, 'encryption and decryption');
+}
+
+
+function testCipher2(key) {
+ // encryption and decryption with Base64
+ // reported in https://github.com/joyent/node/issues/738
+ var plaintext =
+ '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' +
+ 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' +
+ 'jAfaFg**';
+ var cipher = crypto.createCipher('aes256', key);
+
+ // encrypt plaintext which is in utf8 format
+ // to a ciphertext which will be in Base64
+ var ciph = cipher.update(plaintext, 'utf8', 'base64');
+ ciph += cipher.final('base64');
+
+ var decipher = crypto.createDecipher('aes256', key);
+ var txt = decipher.update(ciph, 'base64', 'utf8');
+ txt += decipher.final('utf8');
+
+ assert.equal(txt, plaintext, 'encryption and decryption with Base64');
+}
+
+
+function testCipher3(key, iv) {
+ // Test encyrption and decryption with explicit key and iv
+ var plaintext =
+ '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' +
+ 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' +
+ 'jAfaFg**';
+ var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv);
+ var ciph = cipher.update(plaintext, 'utf8', 'hex');
+ ciph += cipher.final('hex');
+
+ var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv);
+ var txt = decipher.update(ciph, 'hex', 'utf8');
+ txt += decipher.final('utf8');
+
+ assert.equal(txt, plaintext, 'encryption and decryption with key and iv');
+}
+
+
+function testCipher4(key, iv) {
+ // Test encyrption and decryption with explicit key and iv
+ var plaintext =
+ '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' +
+ 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' +
+ 'jAfaFg**';
+ var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv);
+ var ciph = cipher.update(plaintext, 'utf8', 'buffer');
+ ciph = Buffer.concat([ciph, cipher.final('buffer')]);
+
+ var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv);
+ var txt = decipher.update(ciph, 'buffer', 'utf8');
+ txt += decipher.final('utf8');
+
+ assert.equal(txt, plaintext, 'encryption and decryption with key and iv');
+}
+
+
+testCipher1('MySecretKey123');
+testCipher1(new Buffer('MySecretKey123'));
+
+testCipher2('0123456789abcdef');
+testCipher2(new Buffer('0123456789abcdef'));
+
+testCipher3('0123456789abcd0123456789', '12345678');
+testCipher3('0123456789abcd0123456789', new Buffer('12345678'));
+testCipher3(new Buffer('0123456789abcd0123456789'), '12345678');
+testCipher3(new Buffer('0123456789abcd0123456789'), new Buffer('12345678'));
+
+testCipher4(new Buffer('0123456789abcd0123456789'), new Buffer('12345678'));
+
+
+// update() should only take buffers / strings
+assert.throws(function() {
+ crypto.createHash('sha1').update({foo: 'bar'});
+}, /buffer/);
+
+
+// Test Diffie-Hellman with two parties sharing a secret,
+// using various encodings as we go along
+var dh1 = crypto.createDiffieHellman(256);
+var p1 = dh1.getPrime('buffer');
+var dh2 = crypto.createDiffieHellman(p1, 'base64');
+var key1 = dh1.generateKeys();
+var key2 = dh2.generateKeys('hex');
+var secret1 = dh1.computeSecret(key2, 'hex', 'base64');
+var secret2 = dh2.computeSecret(key1, 'binary', 'buffer');
+
+assert.equal(secret1, secret2.toString('base64'));
+
+// Create "another dh1" using generated keys from dh1,
+// and compute secret again
+var dh3 = crypto.createDiffieHellman(p1, 'buffer');
+var privkey1 = dh1.getPrivateKey();
+dh3.setPublicKey(key1);
+dh3.setPrivateKey(privkey1);
+
+assert.equal(dh1.getPrime(), dh3.getPrime());
+assert.equal(dh1.getGenerator(), dh3.getGenerator());
+assert.equal(dh1.getPublicKey(), dh3.getPublicKey());
+assert.equal(dh1.getPrivateKey(), dh3.getPrivateKey());
+
+var secret3 = dh3.computeSecret(key2, 'hex', 'base64');
+
+assert.equal(secret1, secret3);
+
+// https://github.com/joyent/node/issues/2338
+assert.throws(function() {
+ var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' +
+ '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' +
+ '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' +
+ 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF';
+ crypto.createDiffieHellman(p, 'hex');
+});
+
+// Test RSA key signing/verification
+var rsaSign = crypto.createSign('RSA-SHA1');
+var rsaVerify = crypto.createVerify('RSA-SHA1');
+assert.ok(rsaSign);
+assert.ok(rsaVerify);
+
+rsaSign.update(rsaPubPem);
+var rsaSignature = rsaSign.sign(rsaKeyPem, 'hex');
+assert.equal(rsaSignature,
+ '5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7c' +
+ '8f020d7e2688b122bfb54c724ac9ee169f83f66d2fe90abeb95e8' +
+ 'e1290e7e177152a4de3d944cf7d4883114a20ed0f78e70e25ef0f' +
+ '60f06b858e6af42a2f276ede95bbc6bc9a9bbdda15bd663186a6f' +
+ '40819a7af19e577bb2efa5e579a1f5ce8a0d4ca8b8f6');
+
+rsaVerify.update(rsaPubPem);
+assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true);
+
+
+//
+// Test RSA signing and verification
+//
+(function() {
+ var privateKey = fs.readFileSync(
+ common.fixturesDir + '/test_rsa_privkey_2.pem');
+
+ var publicKey = fs.readFileSync(
+ common.fixturesDir + '/test_rsa_pubkey_2.pem');
+
+ var input = 'I AM THE WALRUS';
+
+ var signature =
+ '79d59d34f56d0e94aa6a3e306882b52ed4191f07521f25f505a078dc2f89' +
+ '396e0c8ac89e996fde5717f4cb89199d8fec249961fcb07b74cd3d2a4ffa' +
+ '235417b69618e4bcd76b97e29975b7ce862299410e1b522a328e44ac9bb2' +
+ '8195e0268da7eda23d9825ac43c724e86ceeee0d0d4465678652ccaf6501' +
+ '0ddfb299bedeb1ad';
+
+ var sign = crypto.createSign('RSA-SHA256');
+ sign.update(input);
+
+ var output = sign.sign(privateKey, 'hex');
+ assert.equal(output, signature);
+
+ var verify = crypto.createVerify('RSA-SHA256');
+ verify.update(input);
+
+ assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true);
+})();
+
+
+//
+// Test DSA signing and verification
+//
+(function() {
+ var privateKey = fs.readFileSync(
+ common.fixturesDir + '/test_dsa_privkey.pem');
+
+ var publicKey = fs.readFileSync(
+ common.fixturesDir + '/test_dsa_pubkey.pem');
+
+ var input = 'I AM THE WALRUS';
+
+ // DSA signatures vary across runs so there is no static string to verify
+ // against
+ var sign = crypto.createSign('DSS1');
+ sign.update(input);
+ var signature = sign.sign(privateKey, 'hex');
+
+ var verify = crypto.createVerify('DSS1');
+ verify.update(input);
+
+ assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true);
+})();
+
+
+//
+// Test PBKDF2 with RFC 6070 test vectors (except #4)
+//
+function testPBKDF2(password, salt, iterations, keylen, expected) {
+ var actual = crypto.pbkdf2Sync(password, salt, iterations, keylen);
+ assert.equal(actual, expected);
+
+ crypto.pbkdf2(password, salt, iterations, keylen, function(err, actual) {
+ assert.equal(actual, expected);
+ });
+}
+
+
+testPBKDF2('password', 'salt', 1, 20,
+ '\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24' +
+ '\xaf\x60\x12\x06\x2f\xe0\x37\xa6');
+
+testPBKDF2('password', 'salt', 2, 20,
+ '\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a' +
+ '\xce\x1d\x41\xf0\xd8\xde\x89\x57');
+
+testPBKDF2('password', 'salt', 4096, 20,
+ '\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26' +
+ '\xf7\x21\xd0\x65\xa4\x29\xc1');
+
+testPBKDF2('passwordPASSWORDpassword',
+ 'saltSALTsaltSALTsaltSALTsaltSALTsalt',
+ 4096,
+ 25,
+ '\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62' +
+ '\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38');
+
+testPBKDF2('pass\0word', 'sa\0lt', 4096, 16,
+ '\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34' +
+ '\x25\xe0\xc3');
diff --git a/test/simple/test-crypto-ecb.js b/test/simple/test-crypto-ecb.js
index 1ffaa4f24..e5b893cfc 100644
--- a/test/simple/test-crypto-ecb.js
+++ b/test/simple/test-crypto-ecb.js
@@ -32,6 +32,8 @@ try {
process.exit();
}
+crypto.DEFAULT_ENCODING = 'buffer';
+
// Testing whether EVP_CipherInit_ex is functioning correctly.
// Reference: bug#1997
diff --git a/test/simple/test-crypto-padding-aes256.js b/test/simple/test-crypto-padding-aes256.js
new file mode 100644
index 000000000..dd293feb1
--- /dev/null
+++ b/test/simple/test-crypto-padding-aes256.js
@@ -0,0 +1,69 @@
+// 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');
+var assert = require('assert');
+
+try {
+ var crypto = require('crypto');
+} catch (e) {
+ console.log('Not compiled with OpenSSL support.');
+ process.exit();
+}
+
+crypto.DEFAULT_ENCODING = 'buffer';
+
+function aes256(decipherFinal) {
+ var iv = new Buffer('00000000000000000000000000000000', 'hex');
+ var key = new Buffer('0123456789abcdef0123456789abcdef' +
+ '0123456789abcdef0123456789abcdef', 'hex');
+
+ function encrypt(val, pad) {
+ var c = crypto.createCipheriv('aes256', key, iv);
+ c.setAutoPadding(pad);
+ return c.update(val, 'utf8', 'binary') + c.final('binary');
+ }
+
+ function decrypt(val, pad) {
+ var c = crypto.createDecipheriv('aes256', key, iv);
+ c.setAutoPadding(pad);
+ return c.update(val, 'binary', 'utf8') + c[decipherFinal]('utf8');
+ }
+
+ // echo 0123456789abcdef0123456789abcdef \
+ // | openssl enc -e -aes256 -nopad -K <key> -iv <iv> \
+ // | openssl enc -d -aes256 -nopad -K <key> -iv <iv>
+ var plaintext = '0123456789abcdef0123456789abcdef'; // multiple of block size
+ var encrypted = encrypt(plaintext, false);
+ var decrypted = decrypt(encrypted, false);
+ assert.equal(decrypted, plaintext);
+
+ // echo 0123456789abcdef0123456789abcde \
+ // | openssl enc -e -aes256 -K <key> -iv <iv> \
+ // | openssl enc -d -aes256 -K <key> -iv <iv>
+ plaintext = '0123456789abcdef0123456789abcde'; // not a multiple
+ encrypted = encrypt(plaintext, true);
+ decrypted = decrypt(encrypted, true);
+ assert.equal(decrypted, plaintext);
+}
+
+aes256('final');
+aes256('finaltol');
diff --git a/test/simple/test-crypto-padding.js b/test/simple/test-crypto-padding.js
index f3f663217..22edbf481 100644
--- a/test/simple/test-crypto-padding.js
+++ b/test/simple/test-crypto-padding.js
@@ -29,6 +29,8 @@ try {
process.exit();
}
+crypto.DEFAULT_ENCODING = 'buffer';
+
/*
* Input data
diff --git a/test/simple/test-crypto-random.js b/test/simple/test-crypto-random.js
index 284c7ed11..321c8574c 100644
--- a/test/simple/test-crypto-random.js
+++ b/test/simple/test-crypto-random.js
@@ -29,6 +29,8 @@ try {
process.exit();
}
+crypto.DEFAULT_ENCODING = 'buffer';
+
// bump, we register a lot of exit listeners
process.setMaxListeners(256);
diff --git a/test/simple/test-crypto.js b/test/simple/test-crypto.js
index 535af760f..291ac504b 100644
--- a/test/simple/test-crypto.js
+++ b/test/simple/test-crypto.js
@@ -32,6 +32,8 @@ try {
process.exit();
}
+crypto.DEFAULT_ENCODING = 'buffer';
+
var fs = require('fs');
var path = require('path');
@@ -79,6 +81,62 @@ var h1 = crypto.createHmac('sha1', 'Node')
.digest('hex');
assert.equal(h1, '19fd6e1ba73d9ed2224dd5094a71babe85d9a892', 'test HMAC');
+// Test HMAC (Wikipedia Test Cases)
+var wikipedia = [
+ {
+ key: 'key', data: 'The quick brown fox jumps over the lazy dog',
+ hmac: { // HMACs lifted from Wikipedia.
+ md5: '80070713463e7749b90c2dc24911e275',
+ sha1: 'de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9',
+ sha256:
+ 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc' +
+ '2d1a3cd8'
+ }
+ },
+ {
+ key: 'key', data: '',
+ hmac: { // Intermediate test to help debugging.
+ md5: '63530468a04e386459855da0063b6596',
+ sha1: 'f42bb0eeb018ebbd4597ae7213711ec60760843f',
+ sha256:
+ '5d5d139563c95b5967b9bd9a8c9b233a9dedb45072794cd232dc1b74' +
+ '832607d0'
+ }
+ },
+ {
+ key: '', data: 'The quick brown fox jumps over the lazy dog',
+ hmac: { // Intermediate test to help debugging.
+ md5: 'ad262969c53bc16032f160081c4a07a0',
+ sha1: '2ba7f707ad5f187c412de3106583c3111d668de8',
+ sha256:
+ 'fb011e6154a19b9a4c767373c305275a5a69e8b68b0b4c9200c383dc' +
+ 'ed19a416'
+ }
+ },
+ {
+ key: '', data: '',
+ hmac: { // HMACs lifted from Wikipedia.
+ md5: '74e6f7298a9c2d168935f58c001bad88',
+ sha1: 'fbdb1d1b18aa6c08324b7d64b71fb76370690e1d',
+ sha256:
+ 'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c71214' +
+ '4292c5ad'
+ }
+ },
+]
+
+for (var i = 0, l = wikipedia.length; i < l; i++) {
+ for (var hash in wikipedia[i]['hmac']) {
+ var result = crypto.createHmac(hash, wikipedia[i]['key'])
+ .update(wikipedia[i]['data'])
+ .digest('hex');
+ assert.equal(wikipedia[i]['hmac'][hash],
+ result,
+ 'Test HMAC-' + hash + ': Test case ' + (i + 1) + ' wikipedia');
+ }
+}
+
+
// Test HMAC-SHA-* (rfc 4231 Test Cases)
var rfc4231 = [
{
@@ -228,15 +286,20 @@ var rfc4231 = [
for (var i = 0, l = rfc4231.length; i < l; i++) {
for (var hash in rfc4231[i]['hmac']) {
+ var str = crypto.createHmac(hash, rfc4231[i].key);
+ str.end(rfc4231[i].data);
+ var strRes = str.read().toString('hex');
var result = crypto.createHmac(hash, rfc4231[i]['key'])
.update(rfc4231[i]['data'])
.digest('hex');
if (rfc4231[i]['truncate']) {
result = result.substr(0, 32); // first 128 bits == 32 hex chars
+ strRes = strRes.substr(0, 32);
}
assert.equal(rfc4231[i]['hmac'][hash],
result,
'Test HMAC-' + hash + ': Test case ' + (i + 1) + ' rfc 4231');
+ assert.equal(strRes, result, 'Should get same result from stream');
}
}
@@ -369,18 +432,42 @@ var a0 = crypto.createHash('sha1').update('Test123').digest('hex');
var a1 = crypto.createHash('md5').update('Test123').digest('binary');
var a2 = crypto.createHash('sha256').update('Test123').digest('base64');
var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary
+var a4 = crypto.createHash('sha1').update('Test123').digest('buffer');
+
+// stream interface
+var a5 = crypto.createHash('sha512');
+a5.end('Test123');
+a5 = a5.read();
+
+var a6 = crypto.createHash('sha512');
+a6.write('Te');
+a6.write('st');
+a6.write('123');
+a6.end();
+a6 = a6.read();
assert.equal(a0, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1');
assert.equal(a1, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' +
'\u00bd\u008c', 'Test MD5 as binary');
assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=',
'Test SHA256 as base64');
-assert.equal(a3, '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' +
- '\u0094\u0015l\u00b8\u008dQ+\u00db\u001d\u00c4\u00b5}\u00b2' +
- '\u00d6\u0092\u00a3\u00df\u00a2i\u00a1\u009b\n\n*\u000f' +
- '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' +
- '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'',
- 'Test SHA512 as assumed binary');
+assert.deepEqual(
+ a3,
+ new Buffer(
+ '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' +
+ '\u0094\u0015l\u00b8\u008dQ+\u00db\u001d\u00c4\u00b5}\u00b2' +
+ '\u00d6\u0092\u00a3\u00df\u00a2i\u00a1\u009b\n\n*\u000f' +
+ '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' +
+ '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'',
+ 'binary'),
+ 'Test SHA512 as assumed buffer');
+assert.deepEqual(a4,
+ new Buffer('8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'hex'),
+ 'Test SHA1');
+
+// stream interface should produce the same result.
+assert.deepEqual(a5, a3, 'stream interface is consistent');
+assert.deepEqual(a6, a3, 'stream interface is consistent');
// Test multiple updates to same hash
var h1 = crypto.createHash('sha1').update('Test123').digest('hex');
@@ -409,6 +496,11 @@ assert.throws(function() {
var s1 = crypto.createSign('RSA-SHA1')
.update('Test123')
.sign(keyPem, 'base64');
+var s1stream = crypto.createSign('RSA-SHA1');
+s1stream.end('Test123');
+s1stream = s1stream.sign(keyPem, 'base64');
+assert.equal(s1, s1stream, 'Stream produces same output');
+
var verified = crypto.createVerify('RSA-SHA1')
.update('Test')
.update('123')
@@ -417,13 +509,41 @@ assert.strictEqual(verified, true, 'sign and verify (base 64)');
var s2 = crypto.createSign('RSA-SHA256')
.update('Test123')
- .sign(keyPem); // binary
+ .sign(keyPem, 'binary');
+var s2stream = crypto.createSign('RSA-SHA256');
+s2stream.end('Test123');
+s2stream = s2stream.sign(keyPem, 'binary');
+assert.equal(s2, s2stream, 'Stream produces same output');
+
var verified = crypto.createVerify('RSA-SHA256')
.update('Test')
.update('123')
- .verify(certPem, s2); // binary
+ .verify(certPem, s2, 'binary');
assert.strictEqual(verified, true, 'sign and verify (binary)');
+var verStream = crypto.createVerify('RSA-SHA256');
+verStream.write('Tes');
+verStream.write('t12');
+verStream.end('3');
+verified = verStream.verify(certPem, s2, 'binary');
+assert.strictEqual(verified, true, 'sign and verify (stream)');
+
+var s3 = crypto.createSign('RSA-SHA1')
+ .update('Test123')
+ .sign(keyPem, 'buffer');
+var verified = crypto.createVerify('RSA-SHA1')
+ .update('Test')
+ .update('123')
+ .verify(certPem, s3);
+assert.strictEqual(verified, true, 'sign and verify (buffer)');
+
+var verStream = crypto.createVerify('RSA-SHA1');
+verStream.write('Tes');
+verStream.write('t12');
+verStream.end('3');
+verified = verStream.verify(certPem, s3);
+assert.strictEqual(verified, true, 'sign and verify (stream)');
+
function testCipher1(key) {
// Test encryption and decryption
@@ -441,6 +561,20 @@ function testCipher1(key) {
txt += decipher.final('utf8');
assert.equal(txt, plaintext, 'encryption and decryption');
+
+ // streaming cipher interface
+ // NB: In real life, it's not guaranteed that you can get all of it
+ // in a single read() like this. But in this case, we know it's
+ // quite small, so there's no harm.
+ var cStream = crypto.createCipher('aes192', key);
+ cStream.end(plaintext);
+ ciph = cStream.read();
+
+ var dStream = crypto.createDecipher('aes192', key);
+ dStream.end(ciph);
+ txt = dStream.read().toString('utf8');
+
+ assert.equal(txt, plaintext, 'encryption and decryption with streams');
}
@@ -481,6 +615,38 @@ function testCipher3(key, iv) {
txt += decipher.final('utf8');
assert.equal(txt, plaintext, 'encryption and decryption with key and iv');
+
+ // streaming cipher interface
+ // NB: In real life, it's not guaranteed that you can get all of it
+ // in a single read() like this. But in this case, we know it's
+ // quite small, so there's no harm.
+ var cStream = crypto.createCipheriv('des-ede3-cbc', key, iv);
+ cStream.end(plaintext);
+ ciph = cStream.read();
+
+ var dStream = crypto.createDecipheriv('des-ede3-cbc', key, iv);
+ dStream.end(ciph);
+ txt = dStream.read().toString('utf8');
+
+ assert.equal(txt, plaintext, 'streaming cipher iv');
+}
+
+
+function testCipher4(key, iv) {
+ // Test encyrption and decryption with explicit key and iv
+ var plaintext =
+ '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' +
+ 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' +
+ 'jAfaFg**';
+ var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv);
+ var ciph = cipher.update(plaintext, 'utf8', 'buffer');
+ ciph = Buffer.concat([ciph, cipher.final('buffer')]);
+
+ var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv);
+ var txt = decipher.update(ciph, 'buffer', 'utf8');
+ txt += decipher.final('utf8');
+
+ assert.equal(txt, plaintext, 'encryption and decryption with key and iv');
}
@@ -495,36 +661,38 @@ testCipher3('0123456789abcd0123456789', new Buffer('12345678'));
testCipher3(new Buffer('0123456789abcd0123456789'), '12345678');
testCipher3(new Buffer('0123456789abcd0123456789'), new Buffer('12345678'));
+testCipher4(new Buffer('0123456789abcd0123456789'), new Buffer('12345678'));
+
// update() should only take buffers / strings
assert.throws(function() {
crypto.createHash('sha1').update({foo: 'bar'});
-}, /string or buffer/);
+}, /buffer/);
// Test Diffie-Hellman with two parties sharing a secret,
// using various encodings as we go along
var dh1 = crypto.createDiffieHellman(256);
-var p1 = dh1.getPrime('base64');
+var p1 = dh1.getPrime('buffer');
var dh2 = crypto.createDiffieHellman(p1, 'base64');
var key1 = dh1.generateKeys();
var key2 = dh2.generateKeys('hex');
var secret1 = dh1.computeSecret(key2, 'hex', 'base64');
-var secret2 = dh2.computeSecret(key1, 'binary', 'base64');
+var secret2 = dh2.computeSecret(key1, 'binary', 'buffer');
-assert.equal(secret1, secret2);
+assert.equal(secret1, secret2.toString('base64'));
// Create "another dh1" using generated keys from dh1,
// and compute secret again
-var dh3 = crypto.createDiffieHellman(p1, 'base64');
+var dh3 = crypto.createDiffieHellman(p1, 'buffer');
var privkey1 = dh1.getPrivateKey();
dh3.setPublicKey(key1);
dh3.setPrivateKey(privkey1);
-assert.equal(dh1.getPrime(), dh3.getPrime());
-assert.equal(dh1.getGenerator(), dh3.getGenerator());
-assert.equal(dh1.getPublicKey(), dh3.getPublicKey());
-assert.equal(dh1.getPrivateKey(), dh3.getPrivateKey());
+assert.deepEqual(dh1.getPrime(), dh3.getPrime());
+assert.deepEqual(dh1.getGenerator(), dh3.getGenerator());
+assert.deepEqual(dh1.getPublicKey(), dh3.getPublicKey());
+assert.deepEqual(dh1.getPrivateKey(), dh3.getPrivateKey());
var secret3 = dh3.computeSecret(key2, 'hex', 'base64');
@@ -534,6 +702,16 @@ assert.throws(function() {
dh3.computeSecret('');
}, /key is too small/i);
+// Create a shared using a DH group.
+var alice = crypto.createDiffieHellmanGroup('modp5');
+var bob = crypto.createDiffieHellmanGroup('modp5');
+alice.generateKeys();
+bob.generateKeys();
+var aSecret = alice.computeSecret(bob.getPublicKey()).toString('hex');
+var bSecret = bob.computeSecret(alice.getPublicKey()).toString('hex');
+assert.equal(aSecret, bSecret);
+
+
// https://github.com/joyent/node/issues/2338
assert.throws(function() {
var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' +
@@ -622,46 +800,68 @@ assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true);
//
// Test PBKDF2 with RFC 6070 test vectors (except #4)
//
-crypto.pbkdf2('password', 'salt', 1, 20, function(err, result) {
- assert.equal(result,
- '\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24' +
- '\xaf\x60\x12\x06\x2f\xe0\x37\xa6',
- 'pbkdf1 test vector 1');
-});
+function testPBKDF2(password, salt, iterations, keylen, expected) {
+ var actual = crypto.pbkdf2Sync(password, salt, iterations, keylen);
+ assert.equal(actual.toString('binary'), expected);
-crypto.pbkdf2('password', 'salt', 2, 20, function(err, result) {
- assert.equal(result,
- '\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a' +
- '\xce\x1d\x41\xf0\xd8\xde\x89\x57',
- 'pbkdf1 test vector 2');
-});
+ crypto.pbkdf2(password, salt, iterations, keylen, function(err, actual) {
+ assert.equal(actual.toString('binary'), expected);
+ });
+}
-crypto.pbkdf2('password', 'salt', 4096, 20, function(err, result) {
- assert.equal(result,
- '\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26' +
- '\xf7\x21\xd0\x65\xa4\x29\xc1',
- 'pbkdf1 test vector 3');
-});
-crypto.pbkdf2(
- 'passwordPASSWORDpassword',
- 'saltSALTsaltSALTsaltSALTsaltSALTsalt',
- 4096,
- 25, function(err, result) {
- assert.equal(result,
- '\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62' +
- '\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38',
- 'pbkdf1 test vector 5');
- });
-
-crypto.pbkdf2('pass\0word', 'sa\0lt', 4096, 16, function(err, result) {
- assert.equal(result,
- '\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34' +
- '\x25\xe0\xc3',
- 'pbkdf1 test vector 6');
-});
+testPBKDF2('password', 'salt', 1, 20,
+ '\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24' +
+ '\xaf\x60\x12\x06\x2f\xe0\x37\xa6');
-// Error path should not leak memory (check with valgrind).
-assert.throws(function() {
- crypto.pbkdf2('password', 'salt', 1, 20, null);
-});
+testPBKDF2('password', 'salt', 2, 20,
+ '\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a' +
+ '\xce\x1d\x41\xf0\xd8\xde\x89\x57');
+
+testPBKDF2('password', 'salt', 4096, 20,
+ '\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26' +
+ '\xf7\x21\xd0\x65\xa4\x29\xc1');
+
+testPBKDF2('passwordPASSWORDpassword',
+ 'saltSALTsaltSALTsaltSALTsaltSALTsalt',
+ 4096,
+ 25,
+ '\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62' +
+ '\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38');
+
+testPBKDF2('pass\0word', 'sa\0lt', 4096, 16,
+ '\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34' +
+ '\x25\xe0\xc3');
+
+function assertSorted(list) {
+ for (var i = 0, k = list.length - 1; i < k; ++i) {
+ var a = list[i + 0];
+ var b = list[i + 1];
+ assert(a <= b);
+ }
+}
+
+// Assume that we have at least AES256-SHA.
+assert.notEqual(0, crypto.getCiphers());
+assert.notEqual(-1, crypto.getCiphers().indexOf('AES256-SHA'));
+assertSorted(crypto.getCiphers());
+
+// Assert that we have sha and sha1 but not SHA and SHA1.
+assert.notEqual(0, crypto.getHashes());
+assert.notEqual(-1, crypto.getHashes().indexOf('sha1'));
+assert.notEqual(-1, crypto.getHashes().indexOf('sha'));
+assert.equal(-1, crypto.getHashes().indexOf('SHA1'));
+assert.equal(-1, crypto.getHashes().indexOf('SHA'));
+assertSorted(crypto.getHashes());
+
+(function() {
+ var c = crypto.createDecipher('aes-128-ecb', '');
+ assert.throws(function() { c.final('utf8') }, /invalid public key/);
+})();
+
+// Base64 padding regression test, see #4837.
+(function() {
+ var c = crypto.createCipher('aes-256-cbc', 'secret');
+ var s = c.update('test', 'utf8', 'base64') + c.final('base64');
+ assert.equal(s, '375oxUQCIocvxmC5At+rvA==');
+})();
diff --git a/test/simple/test-debug-brk-no-arg.js b/test/simple/test-debug-brk-no-arg.js
new file mode 100644
index 000000000..f02527cf6
--- /dev/null
+++ b/test/simple/test-debug-brk-no-arg.js
@@ -0,0 +1,35 @@
+// 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');
+var assert = require('assert');
+var spawn = require('child_process').spawn;
+
+var child = spawn(process.execPath, ['--debug-brk=' + common.PORT]);
+child.stderr.once('data', function(c) {
+ console.error('%j', c.toString());
+ child.stdin.end();
+});
+
+child.on('exit', function(c) {
+ assert(c === 0);
+ console.log('ok');
+});
diff --git a/test/simple/test-debugger-client.js b/test/simple/test-debugger-client.js
index 5102a7b37..8b4ba2c19 100644
--- a/test/simple/test-debugger-client.js
+++ b/test/simple/test-debugger-client.js
@@ -22,12 +22,20 @@
+process.env.NODE_DEBUGGER_TIMEOUT = 2000;
var common = require('../common');
var assert = require('assert');
var debug = require('_debugger');
+var debugPort = common.PORT + 1337;
+debug.port = debugPort;
var spawn = require('child_process').spawn;
+setTimeout(function() {
+ if (nodeProcess) nodeProcess.kill('SIGTERM');
+ throw new Error('timeout');
+}, 10000).unref();
+
var resCount = 0;
var p = new debug.Protocol();
@@ -143,12 +151,16 @@ addTest(function(client, done) {
var connectCount = 0;
+var script = 'setTimeout(function () { console.log("blah"); });' +
+ 'setInterval(function () {}, 1000000);';
+
+var nodeProcess;
function doTest(cb, done) {
- var nodeProcess = spawn(process.execPath,
- ['-e', 'setInterval(function () { console.log("blah"); }, 100);']);
+ var args = ['--debug=' + debugPort, '-e', script];
+ nodeProcess = spawn(process.execPath, args);
- nodeProcess.stdout.once('data', function() {
+ nodeProcess.stdout.once('data', function(c) {
console.log('>>> new node process: %d', nodeProcess.pid);
process._debugProcess(nodeProcess.pid);
console.log('>>> starting debugger session');
@@ -158,15 +170,21 @@ function doTest(cb, done) {
nodeProcess.stderr.setEncoding('utf8');
var b = '';
nodeProcess.stderr.on('data', function(data) {
+ console.error('got stderr data %j', data);
+ nodeProcess.stderr.resume();
b += data;
- if (didTryConnect == false && /debugger listening on port/.test(b)) {
+ if (didTryConnect == false &&
+ b.match(/debugger listening on port/)) {
didTryConnect = true;
setTimeout(function() {
// Wait for some data before trying to connect
var c = new debug.Client();
- process.stdout.write('>>> connecting...');
+ console.error('>>> connecting...');
c.connect(debug.port);
+ c.on('break', function(brk) {
+ c.reqContinue(function() {});
+ });
c.on('ready', function() {
connectCount++;
console.log('ready!');
@@ -176,7 +194,7 @@ function doTest(cb, done) {
done();
});
});
- }, 100);
+ });
}
});
}
@@ -194,7 +212,8 @@ function run() {
run();
-process.on('exit', function() {
- assert.equal(expectedConnections, connectCount);
+process.on('exit', function(code) {
+ if (!code)
+ assert.equal(expectedConnections, connectCount);
});
diff --git a/test/simple/test-debugger-repl-utf8.js b/test/simple/test-debugger-repl-utf8.js
index e14191360..73314b8a6 100644
--- a/test/simple/test-debugger-repl-utf8.js
+++ b/test/simple/test-debugger-repl-utf8.js
@@ -19,160 +19,9 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
var common = require('../common');
-var assert = require('assert');
-var spawn = require('child_process').spawn;
-var debug = require('_debugger');
-
-var port = common.PORT + 1337;
-
var script = common.fixturesDir + '/breakpoints_utf8.js';
+process.env.NODE_DEBUGGER_TEST_SCRIPT = script;
-var child = spawn(process.execPath, ['debug', '--port=' + port, script]);
-
-console.error('./node', 'debug', '--port=' + port, script);
-
-var buffer = '';
-child.stdout.setEncoding('utf-8');
-child.stdout.on('data', function(data) {
- data = (buffer + data.toString()).split(/\n/g);
- buffer = data.pop();
- data.forEach(function(line) {
- child.emit('line', line);
- });
-});
-child.stderr.pipe(process.stdout);
-
-var expected = [];
-
-child.on('line', function(line) {
- line = line.replace(/^(debug> )+/, 'debug> ');
- console.error('line> ' + line);
- assert.ok(expected.length > 0, 'Got unexpected line: ' + line);
-
- var expectedLine = expected[0].lines.shift();
- assert.ok(line.match(expectedLine) !== null, line + ' != ' + expectedLine);
-
- if (expected[0].lines.length === 0) {
- var callback = expected[0].callback;
- expected.shift();
- callback && callback();
- }
-});
-
-function addTest(input, output) {
- function next() {
- if (expected.length > 0) {
- child.stdin.write(expected[0].input + '\n');
-
- if (!expected[0].lines) {
- setTimeout(function() {
- var callback = expected[0].callback;
- expected.shift();
-
- callback && callback();
- }, 50);
- }
- } else {
- finish();
- }
- };
- expected.push({input: input, lines: output, callback: next});
-}
-
-// Initial lines
-addTest(null, [
- /listening on port \d+/,
- /connecting... ok/,
- /break in .*:1/,
- /1/, /2/, /3/
-]);
-
-// Next
-addTest('n', [
- /break in .*:11/,
- /9/, /10/, /11/, /12/, /13/
-]);
-
-// Watch
-addTest('watch("\'x\'")');
-
-// Continue
-addTest('c', [
- /break in .*:5/,
- /Watchers/,
- /0:\s+'x' = "x"/,
- /()/,
- /3/, /4/, /5/, /6/, /7/
-]);
-
-// Show watchers
-addTest('watchers', [
- /0:\s+'x' = "x"/
-]);
-
-// Unwatch
-addTest('unwatch("\'x\'")');
-
-// Step out
-addTest('o', [
- /break in .*:12/,
- /10/, /11/, /12/, /13/, /14/
-]);
-
-// Continue
-addTest('c', [
- /break in .*:5/,
- /3/, /4/, /5/, /6/, /7/
-]);
-
-// Set breakpoint by function name
-addTest('sb("setInterval()", "!(setInterval.flag++)")', [
- /1/, /2/, /3/, /4/, /5/, /6/, /7/, /8/, /9/, /10/
-]);
-
-// Continue
-addTest('c', [
- /break in node.js:\d+/,
- /\d/, /\d/, /\d/, /\d/, /\d/
-]);
-
-function finish() {
- process.exit(0);
-}
-
-function quit() {
- if (quit.called) return;
- quit.called = true;
- child.stdin.write('quit');
-}
-
-setTimeout(function() {
- console.error('dying badly');
- var err = 'Timeout';
- if (expected.length > 0 && expected[0].lines) {
- err = err + '. Expected: ' + expected[0].lines.shift();
- }
- quit();
- child.kill('SIGKILL');
-
- // give the sigkill time to work.
- setTimeout(function() {
- throw new Error(err);
- }, 100);
-
-}, 5000);
-
-process.once('uncaughtException', function(e) {
- quit();
- console.error(e.toString());
- process.exit(1);
-});
+require('./test-debugger-repl.js');
-process.on('exit', function(code) {
- quit();
- if (code === 0) {
- assert.equal(expected.length, 0);
- }
-});
diff --git a/test/simple/test-debugger-repl.js b/test/simple/test-debugger-repl.js
index 14092bc4a..26c597398 100644
--- a/test/simple/test-debugger-repl.js
+++ b/test/simple/test-debugger-repl.js
@@ -19,7 +19,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
+process.env.NODE_DEBUGGER_TIMEOUT = 2000;
var common = require('../common');
var assert = require('assert');
var spawn = require('child_process').spawn;
@@ -27,7 +27,8 @@ var debug = require('_debugger');
var port = common.PORT + 1337;
-var script = common.fixturesDir + '/breakpoints.js';
+var script = process.env.NODE_DEBUGGER_TEST_SCRIPT ||
+ common.fixturesDir + '/breakpoints.js';
var child = spawn(process.execPath, ['debug', '--port=' + port, script]);
@@ -42,13 +43,13 @@ child.stdout.on('data', function(data) {
child.emit('line', line);
});
});
-child.stderr.pipe(process.stdout);
+child.stderr.pipe(process.stderr);
var expected = [];
child.on('line', function(line) {
- line = line.replace(/^(debug> )+/, 'debug> ');
- console.error('line> ' + line);
+ line = line.replace(/^(debug> *)+/, '');
+ console.log(line);
assert.ok(expected.length > 0, 'Got unexpected line: ' + line);
var expectedLine = expected[0].lines.shift();
@@ -64,23 +65,17 @@ child.on('line', function(line) {
function addTest(input, output) {
function next() {
if (expected.length > 0) {
- var res = child.stdin.write(expected[0].input + '\n'),
- callback;
+ console.log('debug> ' + expected[0].input);
+ child.stdin.write(expected[0].input + '\n');
if (!expected[0].lines) {
- callback = expected[0].callback;
+ var callback = expected[0].callback;
expected.shift();
- }
- if (callback) {
- if (res !== true) {
- child.stdin.on('drain', callback);
- } else {
- process.nextTick(callback);
- }
+ callback && callback();
}
} else {
- finish();
+ quit();
}
};
expected.push({input: input, lines: output, callback: next});
@@ -101,7 +96,7 @@ addTest('n', [
]);
// Watch
-addTest('watch("\'x\'"), true', [/true/]);
+addTest('watch("\'x\'")');
// Continue
addTest('c', [
@@ -118,7 +113,7 @@ addTest('watchers', [
]);
// Unwatch
-addTest('unwatch("\'x\'"), true', [/true/]);
+addTest('unwatch("\'x\'")');
// Step out
addTest('o', [
@@ -143,53 +138,47 @@ addTest('c', [
/\d/, /\d/, /\d/, /\d/, /\d/
]);
-addTest('c', [
- /break in .*breakpoints.js:\d+/,
- /\d/, /\d/, /\d/, /\d/, /\d/
-]);
-
-addTest('repl', [
- /Press Ctrl \+ C to leave debug repl/
-]);
+addTest('quit', []);
-addTest('now', [
- /\w* \w* \d* \d* \d*:\d*:\d* GMT[+-]\d* (\w*)/
-]);
-
-function finish() {
- process.exit(0);
-}
+var childClosed = false;
+child.on('close', function(code) {
+ assert(!code);
+ childClosed = true;
+});
+var quitCalled = false;
function quit() {
- if (quit.called) return;
- quit.called = true;
+ if (quitCalled || childClosed) return;
+ quitCalled = true;
child.stdin.write('quit');
+ child.kill('SIGTERM');
}
setTimeout(function() {
+ console.error('dying badly buffer=%j', buffer);
var err = 'Timeout';
if (expected.length > 0 && expected[0].lines) {
err = err + '. Expected: ' + expected[0].lines.shift();
}
- quit();
- child.kill('SIGKILL');
- // give the sigkill time to work.
- setTimeout(function() {
+ child.on('close', function() {
+ console.error('child is closed');
throw new Error(err);
- }, 100);
+ });
-}, 5000);
+ quit();
+}, 5000).unref();
process.once('uncaughtException', function(e) {
+ console.error('UncaughtException', e, e.stack);
quit();
console.error(e.toString());
process.exit(1);
});
process.on('exit', function(code) {
+ console.error('process exit', code);
quit();
- if (code === 0) {
- assert.equal(expected.length, 0);
- }
+ if (code === 0)
+ assert(childClosed);
});
diff --git a/test/simple/test-dgram-broadcast-multi-process.js b/test/simple/test-dgram-broadcast-multi-process.js
index 7b3aa4d81..ad5b4eba8 100644
--- a/test/simple/test-dgram-broadcast-multi-process.js
+++ b/test/simple/test-dgram-broadcast-multi-process.js
@@ -23,7 +23,7 @@ var common = require('../common'),
assert = require('assert'),
dgram = require('dgram'),
util = require('util'),
- assert = require('assert'),
+ networkInterfaces = require('os').networkInterfaces(),
Buffer = require('buffer').Buffer,
fork = require('child_process').fork,
LOCAL_BROADCAST_HOST = '255.255.255.255',
@@ -35,6 +35,19 @@ var common = require('../common'),
new Buffer('Fourth message to send')
];
+// take the first non-internal interface as the address for binding
+get_bindAddress: for (var name in networkInterfaces) {
+ var interfaces = networkInterfaces[name];
+ for(var i = 0; i < interfaces.length; i++) {
+ var localInterface = interfaces[i];
+ if (!localInterface.internal && localInterface.family === 'IPv4') {
+ var bindAddress = localInterface.address;
+ break get_bindAddress;
+ }
+ }
+}
+assert.ok(bindAddress);
+
if (process.argv[2] !== 'child') {
var workers = {},
listeners = 3,
@@ -146,8 +159,12 @@ if (process.argv[2] !== 'child') {
var sendSocket = dgram.createSocket('udp4');
- sendSocket.bind(common.PORT);
- sendSocket.setBroadcast(true);
+ // bind the address explicitly for sending
+ // INADDR_BROADCAST to only one interface
+ sendSocket.bind(common.PORT, bindAddress);
+ sendSocket.on('listening', function () {
+ sendSocket.setBroadcast(true);
+ });
sendSocket.on('close', function() {
console.error('[PARENT] sendSocket closed');
@@ -187,6 +204,9 @@ if (process.argv[2] === 'child') {
var listenSocket = dgram.createSocket('udp4');
listenSocket.on('message', function(buf, rinfo) {
+ // receive udp messages only sent from parent
+ if (rinfo.address !== bindAddress) return;
+
console.error('[CHILD] %s received %s from %j',
process.pid,
util.inspect(buf.toString()),
diff --git a/test/simple/test-dgram-implicit-bind.js b/test/simple/test-dgram-implicit-bind.js
new file mode 100644
index 000000000..6039629c4
--- /dev/null
+++ b/test/simple/test-dgram-implicit-bind.js
@@ -0,0 +1,49 @@
+// 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');
+var assert = require('assert');
+var dgram = require('dgram');
+
+var source = dgram.createSocket('udp4');
+var target = dgram.createSocket('udp4');
+var messages = 0;
+
+process.on('exit', function() {
+ assert.equal(messages, 2);
+});
+
+target.on('message', function(buf) {
+ if (buf.toString() === 'abc') ++messages;
+ if (buf.toString() === 'def') ++messages;
+ if (messages === 2) {
+ source.close();
+ target.close();
+ }
+});
+
+target.on('listening', function() {
+ // Second .send() call should not throw a bind error.
+ source.send(Buffer('abc'), 0, 3, common.PORT, '127.0.0.1');
+ source.send(Buffer('def'), 0, 3, common.PORT, '127.0.0.1');
+});
+
+target.bind(common.PORT);
diff --git a/test/simple/test-dgram-listen-after-bind.js b/test/simple/test-dgram-listen-after-bind.js
new file mode 100644
index 000000000..e5f1c4d65
--- /dev/null
+++ b/test/simple/test-dgram-listen-after-bind.js
@@ -0,0 +1,43 @@
+// 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');
+var assert = require('assert');
+var dgram = require('dgram');
+
+var socket = dgram.createSocket('udp4');
+
+socket.bind();
+
+var fired = false;
+var timer = setTimeout(function () {
+ socket.close();
+}, 100);
+
+socket.on('listening', function () {
+ clearTimeout(timer);
+ fired = true;
+ socket.close();
+});
+
+socket.on('close', function () {
+ assert(fired, 'listening should fire after bind');
+});
diff --git a/test/simple/test-dgram-multicast-multi-process.js b/test/simple/test-dgram-multicast-multi-process.js
index 4f0782065..86fd7d705 100644
--- a/test/simple/test-dgram-multicast-multi-process.js
+++ b/test/simple/test-dgram-multicast-multi-process.js
@@ -149,10 +149,13 @@ if (process.argv[2] !== 'child') {
// call is what creates the actual socket...
sendSocket.bind();
- sendSocket.setTTL(1);
- sendSocket.setBroadcast(true);
- sendSocket.setMulticastTTL(1);
- sendSocket.setMulticastLoopback(true);
+ // The socket is actually created async now
+ sendSocket.on('listening', function () {
+ sendSocket.setTTL(1);
+ sendSocket.setBroadcast(true);
+ sendSocket.setMulticastTTL(1);
+ sendSocket.setMulticastLoopback(true);
+ });
sendSocket.on('close', function() {
console.error('[PARENT] sendSocket closed');
@@ -221,5 +224,7 @@ if (process.argv[2] === 'child') {
listenSocket.bind(common.PORT);
- listenSocket.addMembership(LOCAL_BROADCAST_HOST);
+ listenSocket.on('listening', function () {
+ listenSocket.addMembership(LOCAL_BROADCAST_HOST);
+ });
}
diff --git a/test/simple/test-dgram-multicast-setTTL.js b/test/simple/test-dgram-multicast-setTTL.js
index 8d1c0a06a..2ef0c167a 100644
--- a/test/simple/test-dgram-multicast-setTTL.js
+++ b/test/simple/test-dgram-multicast-setTTL.js
@@ -26,16 +26,18 @@ var common = require('../common'),
socket = dgram.createSocket('udp4');
socket.bind(common.PORT);
-socket.setMulticastTTL(16);
+socket.on('listening', function () {
+ socket.setMulticastTTL(16);
-//Try to set an invalid TTL (valid ttl is > 0 and < 256)
-try {
- socket.setMulticastTTL(1000);
-} catch (e) {
- thrown = true;
-}
+ //Try to set an invalid TTL (valid ttl is > 0 and < 256)
+ try {
+ socket.setMulticastTTL(1000);
+ } catch (e) {
+ thrown = true;
+ }
-assert(thrown, 'Setting an invalid multicast TTL should throw some error');
+ assert(thrown, 'Setting an invalid multicast TTL should throw some error');
-//close the socket
-socket.close();
+ //close the socket
+ socket.close();
+});
diff --git a/test/simple/test-dgram-pingpong.js b/test/simple/test-dgram-pingpong.js
index 18b39b5aa..0353cd727 100644
--- a/test/simple/test-dgram-pingpong.js
+++ b/test/simple/test-dgram-pingpong.js
@@ -27,6 +27,7 @@ var assert = require('assert');
var Buffer = require('buffer').Buffer;
var dgram = require('dgram');
+var debug = false;
var tests_run = 0;
function pingPongTest(port, host) {
@@ -36,8 +37,8 @@ function pingPongTest(port, host) {
var sent_final_ping = false;
var server = dgram.createSocket('udp4', function(msg, rinfo) {
- console.log('server got: ' + msg +
- ' from ' + rinfo.address + ':' + rinfo.port);
+ if (debug) console.log('server got: ' + msg +
+ ' from ' + rinfo.address + ':' + rinfo.port);
if (/PING/.exec(msg)) {
var buf = new Buffer(4);
@@ -61,8 +62,8 @@ function pingPongTest(port, host) {
client = dgram.createSocket('udp4');
client.on('message', function(msg, rinfo) {
- console.log('client got: ' + msg +
- ' from ' + rinfo.address + ':' + rinfo.port);
+ if (debug) console.log('client got: ' + msg +
+ ' from ' + rinfo.address + ':' + rinfo.port);
assert.equal('PONG', msg.toString('ascii'));
count += 1;
diff --git a/test/simple/test-dgram-unref.js b/test/simple/test-dgram-unref.js
new file mode 100644
index 000000000..38abbac27
--- /dev/null
+++ b/test/simple/test-dgram-unref.js
@@ -0,0 +1,39 @@
+// 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');
+var assert = require('assert');
+
+var dgram = require('dgram');
+var closed = false;
+
+var s = dgram.createSocket('udp4');
+s.bind();
+s.unref();
+
+setTimeout(function() {
+ closed = true;
+ s.close();
+}, 1000).unref();
+
+process.on('exit', function() {
+ assert.strictEqual(closed, false, 'Unrefd socket should not hold loop open');
+});
diff --git a/test/simple/test-domain-http-server.js b/test/simple/test-domain-http-server.js
index f9962d3b8..666f5d190 100644
--- a/test/simple/test-domain-http-server.js
+++ b/test/simple/test-domain-http-server.js
@@ -33,12 +33,13 @@ var disposeEmit = 0;
var server = http.createServer(function(req, res) {
var dom = domain.create();
+ req.resume();
dom.add(req);
dom.add(res);
dom.on('error', function(er) {
serverCaught++;
- console.log('server error', er);
+ console.log('horray! got a server error', er);
// try to send a 500. If that fails, oh well.
res.writeHead(500, {'content-type':'text/plain'});
res.end(er.stack || er.message || 'Unknown error');
@@ -81,12 +82,7 @@ function next() {
dom.on('error', function(er) {
clientCaught++;
console.log('client error', er);
- // kill everything.
- dom.dispose();
- });
-
- dom.on('dispose', function() {
- disposeEmit += 1;
+ req.socket.destroy();
});
var req = http.get({ host: 'localhost', port: common.PORT, path: p });
@@ -106,6 +102,7 @@ function next() {
d += c;
});
res.on('end', function() {
+ console.error('trying to parse json', d);
d = JSON.parse(d);
console.log('json!', d);
});
@@ -116,6 +113,5 @@ function next() {
process.on('exit', function() {
assert.equal(serverCaught, 2);
assert.equal(clientCaught, 2);
- assert.equal(disposeEmit, 2);
console.log('ok');
});
diff --git a/test/simple/test-domain-implicit-fs.js b/test/simple/test-domain-implicit-fs.js
index 665a821ab..c701c9315 100644
--- a/test/simple/test-domain-implicit-fs.js
+++ b/test/simple/test-domain-implicit-fs.js
@@ -36,8 +36,8 @@ d.on('error', function(er) {
console.error('caught', er);
assert.strictEqual(er.domain, d);
- assert.strictEqual(er.domain_thrown, true);
- assert.ok(!er.domain_emitter);
+ assert.strictEqual(er.domainThrown, true);
+ assert.ok(!er.domainEmitter);
assert.strictEqual(er.code, 'ENOENT');
assert.ok(/\bthis file does not exist\b/i.test(er.path));
assert.strictEqual(typeof er.errno, 'number');
diff --git a/test/simple/test-domain-nested.js b/test/simple/test-domain-nested.js
new file mode 100644
index 000000000..efd672b25
--- /dev/null
+++ b/test/simple/test-domain-nested.js
@@ -0,0 +1,42 @@
+// 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.
+
+
+// Make sure that the nested domains don't cause the domain stack to grow
+
+var assert = require('assert');
+var domain = require('domain');
+
+process.on('exit', function(c) {
+ assert.equal(domain._stack.length, 0);
+});
+
+domain.create().run(function() {
+ domain.create().run(function() {
+ domain.create().run(function() {
+ domain.create().on("error", function(e) {
+ // Don't need to do anything here
+ }).run(function() {
+ throw new Error("died")
+ })
+ })
+ })
+})
diff --git a/test/simple/test-domain-stack.js b/test/simple/test-domain-stack.js
index 4d3eeb897..eecb85b4b 100644
--- a/test/simple/test-domain-stack.js
+++ b/test/simple/test-domain-stack.js
@@ -44,3 +44,7 @@ var foo = a.bind(function() {
for (var i = 0; i < 1000; i++) {
process.nextTick(foo);
}
+
+process.on('exit', function(c) {
+ if (!c) console.log('ok');
+});
diff --git a/test/simple/test-domain-timers.js b/test/simple/test-domain-timers.js
new file mode 100644
index 000000000..388673c08
--- /dev/null
+++ b/test/simple/test-domain-timers.js
@@ -0,0 +1,60 @@
+// 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 domain = require('domain');
+var assert = require('assert');
+var common = require('../common.js');
+
+var timeout_err, timeout, immediate_err;
+
+var timeoutd = domain.create();
+
+timeoutd.on('error', function(e) {
+ timeout_err = e;
+ clearTimeout(timeout);
+});
+
+timeoutd.run(function() {
+ setTimeout(function() {
+ throw new Error('Timeout UNREFd');
+ }).unref();
+});
+
+var immediated = domain.create();
+
+immediated.on('error', function(e) {
+ immediate_err = e;
+});
+
+immediated.run(function() {
+ setImmediate(function() {
+ throw new Error('Immediate Error');
+ });
+});
+
+timeout = setTimeout(function() {}, 10 * 1000);
+
+process.on('exit', function() {
+ assert.equal(timeout_err.message, 'Timeout UNREFd',
+ 'Domain should catch timer error');
+ assert.equal(immediate_err.message, 'Immediate Error',
+ 'Domain should catch immediate error');
+});
diff --git a/test/simple/test-domain.js b/test/simple/test-domain.js
index a478c1e91..f77217e4a 100644
--- a/test/simple/test-domain.js
+++ b/test/simple/test-domain.js
@@ -26,14 +26,15 @@ var common = require('../common');
var assert = require('assert');
var domain = require('domain');
var events = require('events');
+var fs = require('fs');
var caught = 0;
-var expectCaught = 8;
+var expectCaught = 0;
var d = new domain.Domain();
var e = new events.EventEmitter();
d.on('error', function(er) {
- console.error('caught', er);
+ console.error('caught', er && (er.message || er));
var er_message = er.message;
var er_path = er.path
@@ -52,28 +53,28 @@ d.on('error', function(er) {
switch (er_message) {
case 'emitted':
assert.equal(er.domain, d);
- assert.equal(er.domain_emitter, e);
- assert.equal(er.domain_thrown, false);
+ assert.equal(er.domainEmitter, e);
+ assert.equal(er.domainThrown, false);
break;
case 'bound':
- assert.ok(!er.domain_emitter);
+ assert.ok(!er.domainEmitter);
assert.equal(er.domain, d);
- assert.equal(er.domain_bound, fn);
- assert.equal(er.domain_thrown, false);
+ assert.equal(er.domainBound, fn);
+ assert.equal(er.domainThrown, false);
break;
case 'thrown':
- assert.ok(!er.domain_emitter);
+ assert.ok(!er.domainEmitter);
assert.equal(er.domain, d);
- assert.equal(er.domain_thrown, true);
+ assert.equal(er.domainThrown, true);
break;
case "ENOENT, open 'this file does not exist'":
assert.equal(er.domain, d);
- assert.equal(er.domain_thrown, false);
- assert.equal(typeof er.domain_bound, 'function');
- assert.ok(!er.domain_emitter);
+ assert.equal(er.domainThrown, false);
+ assert.equal(typeof er.domainBound, 'function');
+ assert.ok(!er.domainEmitter);
assert.equal(er.code, 'ENOENT');
assert.equal(er_path, 'this file does not exist');
assert.equal(typeof er.errno, 'number');
@@ -84,50 +85,102 @@ d.on('error', function(er) {
assert.equal(er.code, 'ENOENT');
assert.equal(er_path, 'stream for nonexistent file');
assert.equal(er.domain, d);
- assert.equal(er.domain_emitter, fst);
- assert.ok(!er.domain_bound);
- assert.equal(er.domain_thrown, false);
+ assert.equal(er.domainEmitter, fst);
+ assert.ok(!er.domainBound);
+ assert.equal(er.domainThrown, false);
break;
case 'implicit':
- assert.equal(er.domain_emitter, implicit);
+ assert.equal(er.domainEmitter, implicit);
assert.equal(er.domain, d);
- assert.equal(er.domain_thrown, false);
- assert.ok(!er.domain_bound);
+ assert.equal(er.domainThrown, false);
+ assert.ok(!er.domainBound);
break;
case 'implicit timer':
assert.equal(er.domain, d);
- assert.equal(er.domain_thrown, true);
- assert.ok(!er.domain_emitter);
- assert.ok(!er.domain_bound);
+ assert.equal(er.domainThrown, true);
+ assert.ok(!er.domainEmitter);
+ assert.ok(!er.domainBound);
break;
case 'Cannot call method \'isDirectory\' of undefined':
assert.equal(er.domain, d);
- assert.ok(!er.domain_emitter);
- assert.ok(!er.domain_bound);
+ assert.ok(!er.domainEmitter);
+ assert.ok(!er.domainBound);
+ break;
+
+ case 'nextTick execution loop':
+ assert.equal(er.domain, d);
+ assert.ok(!er.domainEmitter);
+ assert.ok(!er.domainBound);
break;
default:
- console.error('unexpected error, throwing %j', er.message);
+ console.error('unexpected error, throwing %j', er.message, er);
throw er;
}
caught++;
});
+
+
process.on('exit', function() {
- console.error('exit');
- assert.equal(caught, expectCaught);
+ console.error('exit', caught, expectCaught);
+ assert.equal(caught, expectCaught, 'caught the expected number of errors');
console.log('ok');
});
+// revert to using the domain when a callback is passed to nextTick in
+// the middle of a tickCallback loop
+d.run(function() {
+ process.nextTick(function() {
+ throw new Error('nextTick execution loop');
+ });
+});
+expectCaught++;
+
+
+
+// catch thrown errors no matter how many times we enter the event loop
+// this only uses implicit binding, except for the first function
+// passed to d.run(). The rest are implicitly bound by virtue of being
+// set up while in the scope of the d domain.
+d.run(function() {
+ process.nextTick(function() {
+ var i = setInterval(function () {
+ clearInterval(i);
+ setTimeout(function() {
+ fs.stat('this file does not exist', function(er, stat) {
+ // uh oh! stat isn't set!
+ // pretty common error.
+ console.log(stat.isDirectory());
+ });
+ });
+ });
+ });
+});
+expectCaught++;
+
+
+
+// implicit addition of a timer created within a domain-bound context.
+d.run(function() {
+ setTimeout(function() {
+ throw new Error('implicit timer');
+ });
+});
+expectCaught++;
+
+
+
// Event emitters added to the domain have their errors routed.
d.add(e);
e.emit('error', new Error('emitted'));
+expectCaught++;
@@ -141,6 +194,9 @@ function fn(er) {
var bound = d.intercept(fn);
bound(new Error('bound'));
+expectCaught++;
+
+
// intercepted should never pass first argument to callback
function fn2(data) {
@@ -169,36 +225,16 @@ function thrower() {
throw new Error('thrown');
}
setTimeout(d.bind(thrower), 100);
+expectCaught++;
// Pass an intercepted function to an fs operation that fails.
-var fs = require('fs');
fs.open('this file does not exist', 'r', d.intercept(function(er) {
console.error('should not get here!', er);
throw new Error('should not get here!');
}, true));
-
-
-
-// catch thrown errors no matter how many times we enter the event loop
-// this only uses implicit binding, except for the first function
-// passed to d.run(). The rest are implicitly bound by virtue of being
-// set up while in the scope of the d domain.
-d.run(function() {
- process.nextTick(function() {
- var i = setInterval(function () {
- clearInterval(i);
- setTimeout(function() {
- fs.stat('this file does not exist', function(er, stat) {
- // uh oh! stat isn't set!
- // pretty common error.
- console.log(stat.isDirectory());
- });
- });
- });
- });
-});
+expectCaught++;
@@ -213,16 +249,9 @@ setTimeout(function() {
// escape from the domain, but implicit is still bound to it.
implicit.emit('error', new Error('implicit'));
}, 10);
+expectCaught++;
-
-// implicit addition of a timer created within a domain-bound context.
-d.run(function() {
- setTimeout(function() {
- throw new Error('implicit timer');
- });
-});
-
var result = d.run(function () {
return 'return value';
});
@@ -231,3 +260,4 @@ assert.equal(result, 'return value');
var fst = fs.createReadStream('stream for nonexistent file')
d.add(fst)
+expectCaught++;
diff --git a/test/simple/test-eio-limit.js b/test/simple/test-eio-limit.js
deleted file mode 100644
index 5902db439..000000000
--- a/test/simple/test-eio-limit.js
+++ /dev/null
@@ -1,50 +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');
-var assert = require('assert'),
- zlib = require('zlib'),
- started = 0,
- done = 0;
-
-function repeat(fn) {
- if (started != 0) {
- assert.ok(started - done < 200);
- }
-
- process.nextTick(function() {
- fn();
- repeat(fn);
- });
-}
-
-repeat(function() {
- if (started > 1000) return process.exit(0);
-
- for (var i = 0; i < 30; i++) {
- started++;
- var deflate = zlib.createDeflate();
- deflate.write('123');
- deflate.flush(function() {
- done++;
- });
- }
-});
diff --git a/test/simple/test-eio-race2.js b/test/simple/test-eio-race2.js
deleted file mode 100644
index d6439f14c..000000000
--- a/test/simple/test-eio-race2.js
+++ /dev/null
@@ -1,45 +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');
-var assert = require('assert');
-var path = require('path');
-var testTxt = path.join(common.fixturesDir, 'x.txt');
-var fs = require('fs');
-
-setTimeout(function() {
- // put this in a timeout, just so it doesn't get bunched up with the
- // require() calls..
- var N = 30;
- for (var i = 0; i < N; i++) {
- console.log('start ' + i);
- fs.readFile(testTxt, function(err, data) {
- if (err) {
- console.log('error! ' + e);
- process.exit(1);
- } else {
- console.log('finish');
- }
- });
- }
-}, 100);
-
-
diff --git a/test/simple/test-event-emitter-listeners-side-effects.js b/test/simple/test-event-emitter-listeners-side-effects.js
new file mode 100644
index 000000000..92a5bef97
--- /dev/null
+++ b/test/simple/test-event-emitter-listeners-side-effects.js
@@ -0,0 +1,61 @@
+
+// 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');
+var assert = require('assert');
+var events = require('events');
+
+var EventEmitter = require('events').EventEmitter;
+var assert = require('assert');
+
+var e = new EventEmitter;
+var fl; // foo listeners
+
+fl = e.listeners('foo');
+assert(Array.isArray(fl));
+assert(fl.length === 0);
+assert.equal(e._events, null);
+
+e.on('foo', assert.fail);
+fl = e.listeners('foo');
+assert(e._events.foo === assert.fail);
+assert(Array.isArray(fl));
+assert(fl.length === 1);
+assert(fl[0] === assert.fail);
+
+e.listeners('bar');
+assert(!e._events.hasOwnProperty('bar'));
+
+e.on('foo', assert.ok);
+fl = e.listeners('foo');
+
+assert(Array.isArray(e._events.foo));
+assert(e._events.foo.length === 2);
+assert(e._events.foo[0] === assert.fail);
+assert(e._events.foo[1] === assert.ok);
+
+assert(Array.isArray(fl));
+assert(fl.length === 2);
+assert(fl[0] === assert.fail);
+assert(fl[1] === assert.ok);
+
+console.log('ok');
diff --git a/test/simple/test-event-emitter-listeners.js b/test/simple/test-event-emitter-listeners.js
new file mode 100644
index 000000000..3e622835b
--- /dev/null
+++ b/test/simple/test-event-emitter-listeners.js
@@ -0,0 +1,52 @@
+
+// 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');
+var assert = require('assert');
+var events = require('events');
+
+function listener() {}
+function listener2() {}
+
+var e1 = new events.EventEmitter();
+e1.on('foo', listener);
+var fooListeners = e1.listeners('foo');
+assert.deepEqual(e1.listeners('foo'), [listener]);
+e1.removeAllListeners('foo');
+assert.deepEqual(e1.listeners('foo'), []);
+assert.deepEqual(fooListeners, [listener]);
+
+var e2 = new events.EventEmitter();
+e2.on('foo', listener);
+var e2ListenersCopy = e2.listeners('foo');
+assert.deepEqual(e2ListenersCopy, [listener]);
+assert.deepEqual(e2.listeners('foo'), [listener]);
+e2ListenersCopy.push(listener2);
+assert.deepEqual(e2.listeners('foo'), [listener]);
+assert.deepEqual(e2ListenersCopy, [listener, listener2]);
+
+var e3 = new events.EventEmitter();
+e3.on('foo', listener);
+var e3ListenersCopy = e3.listeners('foo');
+e3.on('foo', listener2);
+assert.deepEqual(e3.listeners('foo'), [listener, listener2]);
+assert.deepEqual(e3ListenersCopy, [listener]);
diff --git a/test/simple/test-event-emitter-remove-all-listeners.js b/test/simple/test-event-emitter-remove-all-listeners.js
index 38cfb79c6..2cd31ebd2 100644
--- a/test/simple/test-event-emitter-remove-all-listeners.js
+++ b/test/simple/test-event-emitter-remove-all-listeners.js
@@ -24,6 +24,17 @@ var assert = require('assert');
var events = require('events');
+function expect(expected) {
+ var actual = [];
+ process.on('exit', function() {
+ assert.deepEqual(actual.sort(), expected.sort());
+ });
+ function listener(name) {
+ actual.push(name)
+ }
+ return common.mustCall(listener, expected.length);
+}
+
function listener() {}
var e1 = new events.EventEmitter();
@@ -34,6 +45,7 @@ e1.on('baz', listener);
var fooListeners = e1.listeners('foo');
var barListeners = e1.listeners('bar');
var bazListeners = e1.listeners('baz');
+e1.on('removeListener', expect(['bar', 'baz', 'baz']));
e1.removeAllListeners('bar');
e1.removeAllListeners('baz');
assert.deepEqual(e1.listeners('foo'), [listener]);
@@ -52,6 +64,9 @@ assert.notEqual(e1.listeners('baz'), bazListeners);
var e2 = new events.EventEmitter();
e2.on('foo', listener);
e2.on('bar', listener);
+// expect LIFO order
+e2.on('removeListener', expect(['foo', 'bar', 'removeListener']));
+e2.on('removeListener', expect(['foo', 'bar']));
e2.removeAllListeners();
console.error(e2);
assert.deepEqual([], e2.listeners('foo'));
diff --git a/test/simple/test-event-emitter-remove-listeners.js b/test/simple/test-event-emitter-remove-listeners.js
index 70526668c..78133a4f3 100644
--- a/test/simple/test-event-emitter-remove-listeners.js
+++ b/test/simple/test-event-emitter-remove-listeners.js
@@ -23,7 +23,6 @@ var common = require('../common');
var assert = require('assert');
var events = require('events');
-
var count = 0;
function listener1() {
@@ -41,21 +40,45 @@ function listener3() {
count++;
}
+function remove1() {
+ assert(0);
+}
+
+function remove2() {
+ assert(0);
+}
+
var e1 = new events.EventEmitter();
e1.on('hello', listener1);
+e1.on('removeListener', common.mustCall(function(name, cb) {
+ assert.equal(name, 'hello');
+ assert.equal(cb, listener1);
+}));
e1.removeListener('hello', listener1);
assert.deepEqual([], e1.listeners('hello'));
var e2 = new events.EventEmitter();
e2.on('hello', listener1);
+e2.on('removeListener', assert.fail);
e2.removeListener('hello', listener2);
assert.deepEqual([listener1], e2.listeners('hello'));
var e3 = new events.EventEmitter();
e3.on('hello', listener1);
e3.on('hello', listener2);
+e3.on('removeListener', common.mustCall(function(name, cb) {
+ assert.equal(name, 'hello');
+ assert.equal(cb, listener1);
+}));
e3.removeListener('hello', listener1);
assert.deepEqual([listener2], e3.listeners('hello'));
-
-
+var e4 = new events.EventEmitter();
+e4.on('removeListener', common.mustCall(function(name, cb) {
+ if (cb !== remove1) return;
+ this.removeListener('quux', remove2);
+ this.emit('quux');
+}, 2));
+e4.on('quux', remove1);
+e4.on('quux', remove2);
+e4.removeListener('quux', remove1);
diff --git a/test/simple/test-event-emitter-set-max-listeners-side-effects.js b/test/simple/test-event-emitter-set-max-listeners-side-effects.js
new file mode 100644
index 000000000..a50479784
--- /dev/null
+++ b/test/simple/test-event-emitter-set-max-listeners-side-effects.js
@@ -0,0 +1,30 @@
+// 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');
+var assert = require('assert');
+var events = require('events');
+
+var e = new events.EventEmitter;
+
+assert.strictEqual(e._events, null);
+e.setMaxListeners(5);
+assert.strictEqual(e._events, null);
diff --git a/test/simple/test-file-write-stream.js b/test/simple/test-file-write-stream.js
index 5d2286cbd..d4d146a84 100644
--- a/test/simple/test-file-write-stream.js
+++ b/test/simple/test-file-write-stream.js
@@ -22,46 +22,49 @@
var common = require('../common');
var assert = require('assert');
-var path = require('path'),
- fs = require('fs'),
- fn = path.join(common.tmpDir, 'write.txt'),
- file = fs.createWriteStream(fn),
+var path = require('path');
+var fs = require('fs');
+var fn = path.join(common.tmpDir, 'write.txt');
+var file = fs.createWriteStream(fn, {
+ highWaterMark: 10
+ });
- EXPECTED = '012345678910',
+var EXPECTED = '012345678910';
- callbacks = {
+var callbacks = {
open: -1,
drain: -2,
- close: -1,
- endCb: -1
+ close: -1
};
file
.on('open', function(fd) {
+ console.error('open!');
callbacks.open++;
assert.equal('number', typeof fd);
})
.on('error', function(err) {
throw err;
+ console.error('error!', err.stack);
})
.on('drain', function() {
+ console.error('drain!', callbacks.drain);
callbacks.drain++;
if (callbacks.drain == -1) {
- assert.equal(EXPECTED, fs.readFileSync(fn));
+ assert.equal(EXPECTED, fs.readFileSync(fn, 'utf8'));
file.write(EXPECTED);
} else if (callbacks.drain == 0) {
- assert.equal(EXPECTED + EXPECTED, fs.readFileSync(fn));
- file.end(function(err) {
- assert.ok(!err);
- callbacks.endCb++;
- });
+ assert.equal(EXPECTED + EXPECTED, fs.readFileSync(fn, 'utf8'));
+ file.end();
}
})
.on('close', function() {
+ console.error('close!');
assert.strictEqual(file.bytesWritten, EXPECTED.length * 2);
callbacks.close++;
assert.throws(function() {
+ console.error('write after end should not be allowed');
file.write('should not work anymore');
});
@@ -70,7 +73,7 @@ file
for (var i = 0; i < 11; i++) {
(function(i) {
- assert.strictEqual(false, file.write(i));
+ file.write('' + i);
})(i);
}
@@ -78,4 +81,5 @@ process.on('exit', function() {
for (var k in callbacks) {
assert.equal(0, callbacks[k], k + ' count off by ' + callbacks[k]);
}
+ console.log('ok');
});
diff --git a/test/simple/test-file-write-stream2.js b/test/simple/test-file-write-stream2.js
index 9b5d7ffef..68361bb52 100644
--- a/test/simple/test-file-write-stream2.js
+++ b/test/simple/test-file-write-stream2.js
@@ -22,18 +22,18 @@
var common = require('../common');
var assert = require('assert');
-var path = require('path'),
- fs = require('fs'),
- util = require('util');
+var path = require('path');
+var fs = require('fs');
+var util = require('util');
-var filepath = path.join(common.tmpDir, 'write.txt'),
- file;
+var filepath = path.join(common.tmpDir, 'write.txt');
+var file;
var EXPECTED = '012345678910';
-var cb_expected = 'write open drain write drain close error ',
- cb_occurred = '';
+var cb_expected = 'write open drain write drain close error ';
+var cb_occurred = '';
var countDrains = 0;
@@ -47,6 +47,8 @@ process.on('exit', function() {
assert.strictEqual(cb_occurred, cb_expected,
'events missing or out of order: "' +
cb_occurred + '" !== "' + cb_expected + '"');
+ } else {
+ console.log('ok');
}
});
@@ -59,22 +61,29 @@ function removeTestFile() {
removeTestFile();
-file = fs.createWriteStream(filepath);
+// drain at 0, return false at 10.
+file = fs.createWriteStream(filepath, {
+ highWaterMark: 11
+});
file.on('open', function(fd) {
+ console.error('open');
cb_occurred += 'open ';
assert.equal(typeof fd, 'number');
});
file.on('drain', function() {
+ console.error('drain');
cb_occurred += 'drain ';
++countDrains;
if (countDrains === 1) {
- assert.equal(fs.readFileSync(filepath), EXPECTED);
- file.write(EXPECTED);
+ console.error('drain=1, write again');
+ assert.equal(fs.readFileSync(filepath, 'utf8'), EXPECTED);
+ console.error('ondrain write ret=%j', file.write(EXPECTED));
cb_occurred += 'write ';
} else if (countDrains == 2) {
- assert.equal(fs.readFileSync(filepath), EXPECTED + EXPECTED);
+ console.error('second drain, end');
+ assert.equal(fs.readFileSync(filepath, 'utf8'), EXPECTED + EXPECTED);
file.end();
}
});
@@ -88,11 +97,15 @@ file.on('close', function() {
file.on('error', function(err) {
cb_occurred += 'error ';
- assert.ok(err.message.indexOf('not writable') >= 0);
+ assert.ok(err.message.indexOf('write after end') >= 0);
});
for (var i = 0; i < 11; i++) {
- assert.strictEqual(file.write(i), false);
+ var ret = file.write(i + '');
+ console.error('%d %j', i, ret);
+
+ // return false when i hits 10
+ assert(ret === (i != 10));
}
cb_occurred += 'write ';
diff --git a/test/simple/test-fs-empty-readStream.js b/test/simple/test-fs-empty-readStream.js
index a9b378fea..d181c2198 100644
--- a/test/simple/test-fs-empty-readStream.js
+++ b/test/simple/test-fs-empty-readStream.js
@@ -32,12 +32,13 @@ fs.open(emptyFile, 'r', function (error, fd) {
var read = fs.createReadStream(emptyFile, { 'fd': fd });
read.once('data', function () {
- throw new Error("data event should not emit");
+ throw new Error('data event should not emit');
});
var readEmit = false;
read.once('end', function () {
readEmit = true;
+ console.error('end event 1');
});
setTimeout(function () {
@@ -52,12 +53,13 @@ fs.open(emptyFile, 'r', function (error, fd) {
read.pause();
read.once('data', function () {
- throw new Error("data event should not emit");
+ throw new Error('data event should not emit');
});
var readEmit = false;
read.once('end', function () {
readEmit = true;
+ console.error('end event 2');
});
setTimeout(function () {
diff --git a/test/simple/test-fs-long-path.js b/test/simple/test-fs-long-path.js
index eac58f68e..82691556a 100644
--- a/test/simple/test-fs-long-path.js
+++ b/test/simple/test-fs-long-path.js
@@ -47,5 +47,6 @@ fs.writeFile(fullPath, 'ok', function(err) {
});
process.on('exit', function() {
+ fs.unlinkSync(fullPath);
assert.equal(2, successes);
});
diff --git a/test/simple/test-fs-null-bytes.js b/test/simple/test-fs-null-bytes.js
new file mode 100644
index 000000000..5dec223ba
--- /dev/null
+++ b/test/simple/test-fs-null-bytes.js
@@ -0,0 +1,75 @@
+// 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');
+var assert = require('assert');
+var fs = require('fs');
+
+function check(async, sync) {
+ var expected = /Path must be a string without null bytes./;
+ var argsSync = Array.prototype.slice.call(arguments, 2);
+ var argsAsync = argsSync.concat(function(er) {
+ assert(er && er.message.match(expected));
+ });
+
+ if (sync)
+ assert.throws(function() {
+ console.error(sync.name, argsSync);
+ sync.apply(null, argsSync);
+ }, expected);
+
+ if (async)
+ async.apply(null, argsAsync);
+}
+
+check(fs.appendFile, fs.appendFileSync, 'foo\u0000bar');
+check(fs.chmod, fs.chmodSync, 'foo\u0000bar', '0644');
+check(fs.chown, fs.chownSync, 'foo\u0000bar', 12, 34);
+check(fs.link, fs.linkSync, 'foo\u0000bar', 'foobar');
+check(fs.link, fs.linkSync, 'foobar', 'foo\u0000bar');
+check(fs.lstat, fs.lstatSync, 'foo\u0000bar');
+check(fs.mkdir, fs.mkdirSync, 'foo\u0000bar', '0755');
+check(fs.open, fs.openSync, 'foo\u0000bar', 'r');
+check(fs.readFile, fs.readFileSync, 'foo\u0000bar');
+check(fs.readdir, fs.readdirSync, 'foo\u0000bar');
+check(fs.readlink, fs.readlinkSync, 'foo\u0000bar');
+check(fs.realpath, fs.realpathSync, 'foo\u0000bar');
+check(fs.rename, fs.renameSync, 'foo\u0000bar', 'foobar');
+check(fs.rename, fs.renameSync, 'foobar', 'foo\u0000bar');
+check(fs.rmdir, fs.rmdirSync, 'foo\u0000bar');
+check(fs.stat, fs.statSync, 'foo\u0000bar');
+check(fs.symlink, fs.symlinkSync, 'foo\u0000bar', 'foobar');
+check(fs.symlink, fs.symlinkSync, 'foobar', 'foo\u0000bar');
+check(fs.truncate, fs.truncateSync, 'foo\u0000bar');
+check(fs.unlink, fs.unlinkSync, 'foo\u0000bar');
+check(null, fs.unwatchFile, 'foo\u0000bar', assert.fail);
+check(fs.utimes, fs.utimesSync, 'foo\u0000bar', 0, 0);
+check(null, fs.watch, 'foo\u0000bar', assert.fail);
+check(null, fs.watchFile, 'foo\u0000bar', assert.fail);
+check(fs.writeFile, fs.writeFileSync, 'foo\u0000bar');
+
+// an 'error' for exists means that it doesn't exist.
+// one of many reasons why this file is the absolute worst.
+fs.exists('foo\u0000bar', function(exists) {
+ assert(!exists);
+});
+assert(!fs.existsSync('foo\u0000bar'));
+
diff --git a/test/simple/test-fs-read-stream-err.js b/test/simple/test-fs-read-stream-err.js
index 2c285f183..54aa21799 100644
--- a/test/simple/test-fs-read-stream-err.js
+++ b/test/simple/test-fs-read-stream-err.js
@@ -23,28 +23,41 @@ var common = require('../common');
var assert = require('assert');
var fs = require('fs');
-var stream = fs.createReadStream(__filename, { bufferSize: 64 });
+var stream = fs.createReadStream(__filename, {
+ bufferSize: 64
+});
var err = new Error('BAM');
-stream.on('data', function(buf) {
- var fd = stream.fd;
+stream.on('error', common.mustCall(function errorHandler(err_) {
+ console.error('error event');
+ process.nextTick(function() {
+ assert.equal(stream.fd, null);
+ assert.equal(err_, err);
+ });
+}));
+
+fs.close = common.mustCall(function(fd_, cb) {
+ assert.equal(fd_, stream.fd);
+ process.nextTick(cb);
+});
+var read = fs.read;
+fs.read = function() {
+ // first time is ok.
+ read.apply(fs, arguments);
+ // then it breaks
fs.read = function() {
var cb = arguments[arguments.length - 1];
process.nextTick(function() {
cb(err);
});
+ // and should not be called again!
+ fs.read = function() {
+ throw new Error('BOOM!');
+ };
};
+};
- fs.close = common.mustCall(function(fd_, cb) {
- assert.equal(fd_, fd);
- process.nextTick(cb);
- });
-
- stream.on('error', common.mustCall(function(err_) {
- assert.equal(stream.fd, null);
- assert.equal(err_, err);
- }));
-
+stream.on('data', function(buf) {
stream.on('data', assert.fail); // no more 'data' events should follow
});
diff --git a/test/simple/test-fs-read-stream.js b/test/simple/test-fs-read-stream.js
index d500fc45e..9452f95c6 100644
--- a/test/simple/test-fs-read-stream.js
+++ b/test/simple/test-fs-read-stream.js
@@ -34,7 +34,7 @@ var fs = require('fs');
var fn = path.join(common.fixturesDir, 'elipses.txt');
var rangeFile = path.join(common.fixturesDir, 'x.txt');
-var callbacks = { open: 0, end: 0, close: 0, destroy: 0 };
+var callbacks = { open: 0, end: 0, close: 0 };
var paused = false;
@@ -60,12 +60,10 @@ file.on('data', function(data) {
paused = true;
file.pause();
- assert.ok(file.paused);
setTimeout(function() {
paused = false;
file.resume();
- assert.ok(!file.paused);
}, 10);
});
@@ -77,22 +75,10 @@ file.on('end', function(chunk) {
file.on('close', function() {
callbacks.close++;
- assert.ok(!file.readable);
//assert.equal(fs.readFileSync(fn), fileContent);
});
-var file2 = fs.createReadStream(fn);
-file2.destroy(function(err) {
- assert.ok(!err);
- callbacks.destroy++;
-
- file2.destroy(function(err) {
- assert.ok(!err);
- callbacks.destroy++;
- });
-});
-
var file3 = fs.createReadStream(fn, {encoding: 'utf8'});
file3.length = 0;
file3.on('data', function(data) {
@@ -112,12 +98,10 @@ file3.on('close', function() {
process.on('exit', function() {
assert.equal(1, callbacks.open);
assert.equal(1, callbacks.end);
- assert.equal(2, callbacks.destroy);
-
assert.equal(2, callbacks.close);
-
assert.equal(30000, file.length);
assert.equal(10000, file3.length);
+ console.error('ok');
});
var file4 = fs.createReadStream(rangeFile, {bufferSize: 1, start: 1, end: 2});
@@ -167,3 +151,41 @@ stream.on('end', function() {
var pauseRes = fs.createReadStream(rangeFile);
pauseRes.pause();
pauseRes.resume();
+
+var file7 = fs.createReadStream(rangeFile, {autoClose: false });
+file7.on('data', function() {});
+file7.on('end', function() {
+ process.nextTick(function() {
+ assert(!file7.closed);
+ assert(!file7.destroyed);
+ file7Next();
+ });
+});
+
+function file7Next(){
+ // This will tell us if the fd is usable again or not.
+ file7 = fs.createReadStream(null, {fd: file7.fd, start: 0 });
+ file7.data = '';
+ file7.on('data', function(data) {
+ file7.data += data;
+ });
+ file7.on('end', function(err) {
+ assert.equal(file7.data, 'xyz\n');
+ process.nextTick(function() {
+ assert(file7.closed);
+ assert(file7.destroyed);
+ });
+ });
+}
+
+// Just to make sure autoClose won't close the stream because of error.
+var file8 = fs.createReadStream(null, {fd: 13337, autoClose: false });
+file8.on('data', function() {});
+file8.on('error', common.mustCall(function() {}));
+file8.on('end', function() {
+ process.nextTick(function() {
+ assert(!file8.closed);
+ assert(!file8.destroyed);
+ assert(file8.fd);
+ });
+});
diff --git a/test/simple/test-fs-readfile-error.js b/test/simple/test-fs-readfile-error.js
new file mode 100644
index 000000000..72e1e2e7f
--- /dev/null
+++ b/test/simple/test-fs-readfile-error.js
@@ -0,0 +1,55 @@
+// 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');
+var assert = require('assert');
+var exec = require('child_process').exec;
+var path = require('path');
+
+var callbacks = 0;
+
+function test(env, cb) {
+ var filename = path.join(common.fixturesDir, 'test-fs-readfile-error.js');
+ var execPath = process.execPath + ' ' + filename;
+ var options = { env: env || {} };
+ exec(execPath, options, function(err, stdout, stderr) {
+ assert(err);
+ assert.equal(stdout, '');
+ assert.notEqual(stderr, '');
+ cb('' + stderr);
+ });
+}
+
+test({ NODE_DEBUG: '' }, function(data) {
+ assert(/EISDIR/.test(data));
+ assert(!/test-fs-readfile-error/.test(data));
+ callbacks++;
+});
+
+test({ NODE_DEBUG: 'fs' }, function(data) {
+ assert(/EISDIR/.test(data));
+ assert(/test-fs-readfile-error/.test(data));
+ callbacks++;
+});
+
+process.on('exit', function() {
+ assert.equal(callbacks, 2);
+});
diff --git a/test/simple/test-fs-truncate.js b/test/simple/test-fs-truncate.js
new file mode 100644
index 000000000..09476b2ad
--- /dev/null
+++ b/test/simple/test-fs-truncate.js
@@ -0,0 +1,135 @@
+// 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');
+var assert = require('assert');
+var path = require('path');
+var fs = require('fs');
+var tmp = common.tmpDir;
+var filename = path.resolve(tmp, 'truncate-file.txt');
+var data = new Buffer(1024 * 16);
+data.fill('x');
+
+var stat;
+
+// truncateSync
+fs.writeFileSync(filename, data);
+stat = fs.statSync(filename);
+assert.equal(stat.size, 1024 * 16);
+
+fs.truncateSync(filename, 1024);
+stat = fs.statSync(filename);
+assert.equal(stat.size, 1024);
+
+fs.truncateSync(filename);
+stat = fs.statSync(filename);
+assert.equal(stat.size, 0);
+
+// ftruncateSync
+fs.writeFileSync(filename, data);
+var fd = fs.openSync(filename, 'r+');
+
+stat = fs.statSync(filename);
+assert.equal(stat.size, 1024 * 16);
+
+fs.ftruncateSync(fd, 1024);
+stat = fs.statSync(filename);
+assert.equal(stat.size, 1024);
+
+fs.ftruncateSync(fd);
+stat = fs.statSync(filename);
+assert.equal(stat.size, 0);
+
+fs.closeSync(fd);
+
+// async tests
+var success = 0;
+testTruncate(function(er) {
+ if (er) throw er;
+ success++;
+ testFtruncate(function(er) {
+ if (er) throw er;
+ success++;
+ });
+});
+
+process.on('exit', function() {
+ assert.equal(success, 2);
+ console.log('ok');
+});
+
+function testTruncate(cb) {
+ fs.writeFile(filename, data, function(er) {
+ if (er) return cb(er);
+ fs.stat(filename, function(er, stat) {
+ if (er) return cb(er);
+ assert.equal(stat.size, 1024 * 16);
+
+ fs.truncate(filename, 1024, function(er) {
+ if (er) return cb(er);
+ fs.stat(filename, function(er, stat) {
+ if (er) return cb(er);
+ assert.equal(stat.size, 1024);
+
+ fs.truncate(filename, function(er) {
+ if (er) return cb(er);
+ fs.stat(filename, function(er, stat) {
+ if (er) return cb(er);
+ assert.equal(stat.size, 0);
+ cb();
+ });
+ });
+ });
+ });
+ });
+ });
+}
+
+
+function testFtruncate(cb) {
+ fs.writeFile(filename, data, function(er) {
+ if (er) return cb(er);
+ fs.stat(filename, function(er, stat) {
+ if (er) return cb(er);
+ assert.equal(stat.size, 1024 * 16);
+
+ fs.open(filename, 'w', function(er, fd) {
+ if (er) return cb(er);
+ fs.ftruncate(fd, 1024, function(er) {
+ if (er) return cb(er);
+ fs.stat(filename, function(er, stat) {
+ if (er) return cb(er);
+ assert.equal(stat.size, 1024);
+
+ fs.ftruncate(fd, function(er) {
+ if (er) return cb(er);
+ fs.stat(filename, function(er, stat) {
+ if (er) return cb(er);
+ assert.equal(stat.size, 0);
+ fs.close(fd, cb);
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+}
diff --git a/test/simple/test-fs-watch.js b/test/simple/test-fs-watch.js
index 2ad05f2e1..88c335912 100644
--- a/test/simple/test-fs-watch.js
+++ b/test/simple/test-fs-watch.js
@@ -24,7 +24,9 @@ var assert = require('assert');
var path = require('path');
var fs = require('fs');
-var expectFilePath = process.platform == 'win32' || process.platform == 'linux';
+var expectFilePath = process.platform === 'win32' ||
+ process.platform === 'linux' ||
+ process.platform === 'darwin';
var watchSeenOne = 0;
var watchSeenTwo = 0;
@@ -63,7 +65,10 @@ assert.doesNotThrow(
var watcher = fs.watch(filepathOne)
watcher.on('change', function(event, filename) {
assert.equal('change', event);
- if (expectFilePath) {
+
+ // darwin only shows the file path for subdir watching,
+ // not for individual file watching.
+ if (expectFilePath && process.platform !== 'darwin') {
assert.equal('watch.txt', filename);
} else {
assert.equal(null, filename);
@@ -87,7 +92,10 @@ assert.doesNotThrow(
function() {
var watcher = fs.watch(filepathTwo, function(event, filename) {
assert.equal('change', event);
- if (expectFilePath) {
+
+ // darwin only shows the file path for subdir watching,
+ // not for individual file watching.
+ if (expectFilePath && process.platform !== 'darwin') {
assert.equal('hasOwnProperty', filename);
} else {
assert.equal(null, filename);
diff --git a/test/simple/test-fs-write-stream-end.js b/test/simple/test-fs-write-stream-end.js
index 6c0f29c34..7bbc5d68e 100644
--- a/test/simple/test-fs-write-stream-end.js
+++ b/test/simple/test-fs-write-stream-end.js
@@ -21,26 +21,22 @@
var common = require('../common');
var assert = require('assert');
+var path = require('path');
+var fs = require('fs');
-var path = require('path'),
- fs = require('fs');
-
-var writeEndOk = false;
(function() {
- debugger;
- var file = path.join(common.tmpDir, 'write-end-test.txt');
+ var file = path.join(common.tmpDir, 'write-end-test0.txt');
var stream = fs.createWriteStream(file);
+ stream.end();
+ stream.on('close', common.mustCall(function() { }));
+})();
- stream.end('a\n', 'utf8', function() {
+(function() {
+ var file = path.join(common.tmpDir, 'write-end-test1.txt');
+ var stream = fs.createWriteStream(file);
+ stream.end('a\n', 'utf8');
+ stream.on('close', common.mustCall(function() {
var content = fs.readFileSync(file, 'utf8');
assert.equal(content, 'a\n');
- writeEndOk = true;
- });
-
+ }));
})();
-
-
-process.on('exit', function() {
- assert.ok(writeEndOk);
-});
-
diff --git a/test/simple/test-fs-write-stream-err.js b/test/simple/test-fs-write-stream-err.js
index 94d249f89..53ef4e34e 100644
--- a/test/simple/test-fs-write-stream-err.js
+++ b/test/simple/test-fs-write-stream-err.js
@@ -23,30 +23,49 @@ var common = require('../common');
var assert = require('assert');
var fs = require('fs');
-var stream = fs.createWriteStream(common.tmpDir + '/out');
+var stream = fs.createWriteStream(common.tmpDir + '/out', {
+ highWaterMark: 10
+});
var err = new Error('BAM');
-stream.write(new Buffer(256), function() {
- var fd = stream.fd;
+var write = fs.write;
+var writeCalls = 0;
+fs.write = function() {
+ switch (writeCalls++) {
+ case 0:
+ console.error('first write');
+ // first time is ok.
+ return write.apply(fs, arguments);
+ case 1:
+ // then it breaks
+ console.error('second write');
+ var cb = arguments[arguments.length - 1];
+ return process.nextTick(function() {
+ cb(err);
+ });
+ default:
+ // and should not be called again!
+ throw new Error('BOOM!');
+ }
+};
- fs.write = function() {
- var cb = arguments[arguments.length - 1];
- process.nextTick(function() {
- cb(err);
- });
- };
+fs.close = common.mustCall(function(fd_, cb) {
+ console.error('fs.close', fd_, stream.fd);
+ assert.equal(fd_, stream.fd);
+ process.nextTick(cb);
+});
- fs.close = function(fd_, cb) {
- assert.equal(fd_, fd);
- process.nextTick(cb);
- };
+stream.on('error', common.mustCall(function(err_) {
+ console.error('error handler');
+ assert.equal(stream.fd, null);
+ assert.equal(err_, err);
+}));
- stream.write(new Buffer(256), common.mustCall(function(err_) {
- assert.equal(err_, err);
- }));
- stream.on('error', common.mustCall(function(err_) {
- assert.equal(stream.fd, null);
+stream.write(new Buffer(256), function() {
+ console.error('first cb');
+ stream.write(new Buffer(256), common.mustCall(function(err_) {
+ console.error('second cb');
assert.equal(err_, err);
}));
});
diff --git a/test/simple/test-http-1.0-keep-alive.js b/test/simple/test-http-1.0-keep-alive.js
index 623facb17..851409d28 100644
--- a/test/simple/test-http-1.0-keep-alive.js
+++ b/test/simple/test-http-1.0-keep-alive.js
@@ -115,6 +115,7 @@ function check(tests) {
function server(req, res) {
if (current + 1 === test.responses.length) this.close();
var ctx = test.responses[current];
+ console.error('< SERVER SENDING RESPONSE', ctx);
res.writeHead(200, ctx.headers);
ctx.chunks.slice(0, -1).forEach(function(chunk) { res.write(chunk) });
res.end(ctx.chunks[ctx.chunks.length - 1]);
@@ -126,16 +127,19 @@ function check(tests) {
function connected() {
var ctx = test.requests[current];
+ console.error(' > CLIENT SENDING REQUEST', ctx);
conn.setEncoding('utf8');
conn.write(ctx.data);
function onclose() {
+ console.error(' > CLIENT CLOSE');
if (!ctx.expectClose) throw new Error('unexpected close');
client();
}
conn.on('close', onclose);
function ondata(s) {
+ console.error(' > CLIENT ONDATA %j %j', s.length, s.toString());
current++;
if (ctx.expectClose) return;
conn.removeListener('close', onclose);
diff --git a/test/simple/test-http-abort-client.js b/test/simple/test-http-abort-client.js
index 6acdd6f40..f15238af1 100644
--- a/test/simple/test-http-abort-client.js
+++ b/test/simple/test-http-abort-client.js
@@ -46,13 +46,21 @@ server.listen(common.PORT, function() {
res.on('data', function(chunk) {
console.log('Read ' + chunk.length + ' bytes');
- console.log(chunk.toString());
+ console.log(' chunk=%j', chunk.toString());
});
res.on('end', function() {
console.log('Response ended.');
});
+ res.on('aborted', function() {
+ console.log('Response aborted.');
+ });
+
+ res.socket.on('close', function() {
+ console.log('socket closed, but not res');
+ })
+
// it would be nice if this worked:
res.on('close', function() {
console.log('Response aborted');
diff --git a/test/simple/test-http-agent.js b/test/simple/test-http-agent.js
index a1ce456e5..fc66dc49f 100644
--- a/test/simple/test-http-agent.js
+++ b/test/simple/test-http-agent.js
@@ -40,10 +40,14 @@ server.listen(common.PORT, function() {
setTimeout(function() {
for (var j = 0; j < M; j++) {
http.get({ port: common.PORT, path: '/' }, function(res) {
- console.log(res.statusCode);
- if (++responses == N * M) server.close();
+ console.log('%d %d', responses, res.statusCode);
+ if (++responses == N * M) {
+ console.error('Received all responses, closing server');
+ server.close();
+ }
+ res.resume();
}).on('error', function(e) {
- console.log(e.message);
+ console.log('Error!', e);
process.exit(1);
});
}
diff --git a/test/simple/test-http-byteswritten.js b/test/simple/test-http-byteswritten.js
new file mode 100644
index 000000000..b5e8e579a
--- /dev/null
+++ b/test/simple/test-http-byteswritten.js
@@ -0,0 +1,43 @@
+// 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');
+var assert = require('assert');
+var fs = require('fs');
+var http = require('http');
+
+var body = 'hello world\n';
+
+var httpServer = http.createServer(function(req, res) {
+ res.on('finish', function() {
+ assert(typeof(req.connection.bytesWritten) === 'number');
+ assert(req.connection.bytesWritten > 0);
+ httpServer.close();
+ console.log('ok');
+ });
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
+ res.end(body);
+});
+
+httpServer.listen(common.PORT, function() {
+ http.get({ port: common.PORT });
+});
+
diff --git a/test/simple/test-http-chunked-304.js b/test/simple/test-http-chunked-304.js
new file mode 100644
index 000000000..24c5fa151
--- /dev/null
+++ b/test/simple/test-http-chunked-304.js
@@ -0,0 +1,63 @@
+// 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');
+var assert = require('assert');
+var http = require('http');
+var net = require('net');
+
+// RFC 2616, section 10.2.5:
+//
+// The 204 response MUST NOT contain a message-body, and thus is always
+// terminated by the first empty line after the header fields.
+//
+// Likewise for 304 responses. Verify that no empty chunk is sent when
+// the user explicitly sets a Transfer-Encoding header.
+
+test(204, function() {
+ test(304);
+});
+
+function test(statusCode, next) {
+ var server = http.createServer(function(req, res) {
+ res.writeHead(statusCode, { 'Transfer-Encoding': 'chunked' });
+ res.end();
+ server.close();
+ });
+
+ server.listen(common.PORT, function() {
+ var conn = net.createConnection(common.PORT, function() {
+ conn.write('GET / HTTP/1.1\r\n\r\n');
+
+ var resp = '';
+ conn.setEncoding('utf8');
+ conn.on('data', function(data) {
+ resp += data;
+ });
+
+ conn.on('end', common.mustCall(function() {
+ assert.equal(/^Connection: close\r\n$/m.test(resp), true);
+ assert.equal(/^0\r\n$/m.test(resp), false);
+ if (next) process.nextTick(next);
+ }));
+ });
+ });
+}
diff --git a/test/simple/test-http-client-agent.js b/test/simple/test-http-client-agent.js
index f7112e3bf..aedf64ba7 100644
--- a/test/simple/test-http-client-agent.js
+++ b/test/simple/test-http-client-agent.js
@@ -61,6 +61,7 @@ function request(i) {
server.close();
}
});
+ res.resume();
});
}
diff --git a/test/simple/test-http-client-pipe-end.js b/test/simple/test-http-client-pipe-end.js
index 7cb592e4c..51edebbe1 100644
--- a/test/simple/test-http-client-pipe-end.js
+++ b/test/simple/test-http-client-pipe-end.js
@@ -26,6 +26,7 @@ var assert = require('assert');
var http = require('http');
var server = http.createServer(function(req, res) {
+ req.resume();
req.once('end', function() {
res.writeHead(200);
res.end();
@@ -50,9 +51,9 @@ server.listen(common.PIPE, function() {
function sched(cb, ticks) {
function fn() {
if (--ticks)
- process.nextTick(fn);
+ setImmediate(fn);
else
cb();
}
- process.nextTick(fn);
+ setImmediate(fn);
}
diff --git a/test/simple/test-http-client-timeout-with-data.js b/test/simple/test-http-client-timeout-with-data.js
index d169065bd..4e1aae6ff 100644
--- a/test/simple/test-http-client-timeout-with-data.js
+++ b/test/simple/test-http-client-timeout-with-data.js
@@ -41,7 +41,7 @@ var options = {
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Length':'2'});
res.write('*');
- setTimeout(function() { res.end('*') }, 20);
+ setTimeout(function() { res.end('*') }, 100);
});
server.listen(options.port, options.host, function() {
@@ -49,7 +49,7 @@ server.listen(options.port, options.host, function() {
req.end();
function onresponse(res) {
- req.setTimeout(10, function() {
+ req.setTimeout(50, function() {
assert.equal(nchunks, 1); // should have received the first chunk by now
ntimeouts++;
});
diff --git a/test/simple/test-http-conn-reset.js b/test/simple/test-http-conn-reset.js
index 908d433c1..9c293721c 100644
--- a/test/simple/test-http-conn-reset.js
+++ b/test/simple/test-http-conn-reset.js
@@ -45,7 +45,6 @@ function onListen() {
});
req.on('error', function(err) {
assert.equal(err.code, 'ECONNRESET');
- assert.equal(err.message, 'socket hang up');
caughtError = true;
});
req.end();
diff --git a/test/simple/test-http-connect.js b/test/simple/test-http-connect.js
index 668dda796..3643cec18 100644
--- a/test/simple/test-http-connect.js
+++ b/test/simple/test-http-connect.js
@@ -73,7 +73,11 @@ server.listen(common.PORT, function() {
assert(!socket.onend);
assert.equal(socket.listeners('connect').length, 0);
assert.equal(socket.listeners('data').length, 0);
- assert.equal(socket.listeners('end').length, 0);
+
+ // the stream.Duplex onend listener
+ // allow 0 here, so that i can run the same test on streams1 impl
+ assert(socket.listeners('end').length <= 1);
+
assert.equal(socket.listeners('free').length, 0);
assert.equal(socket.listeners('close').length, 0);
assert.equal(socket.listeners('error').length, 0);
diff --git a/test/simple/test-http-date-header.js b/test/simple/test-http-date-header.js
index 8ed528171..b11507c01 100644
--- a/test/simple/test-http-date-header.js
+++ b/test/simple/test-http-date-header.js
@@ -49,6 +49,7 @@ server.addListener('listening', function() {
server.close();
process.exit();
});
+ res.resume();
});
req.end();
});
diff --git a/test/simple/test-http-default-encoding.js b/test/simple/test-http-default-encoding.js
index 4e4741a06..b06f7c83a 100644
--- a/test/simple/test-http-default-encoding.js
+++ b/test/simple/test-http-default-encoding.js
@@ -50,6 +50,7 @@ server.listen(common.PORT, function() {
method: 'POST'
}, function(res) {
console.log(res.statusCode);
+ res.resume();
}).on('error', function(e) {
console.log(e.message);
process.exit(1);
diff --git a/test/simple/test-http-header-read.js b/test/simple/test-http-header-read.js
index de20df604..338377592 100644
--- a/test/simple/test-http-header-read.js
+++ b/test/simple/test-http-header-read.js
@@ -30,7 +30,9 @@ var s = http.createServer(function(req, res) {
var contentType = 'Content-Type';
var plain = 'text/plain';
res.setHeader(contentType, plain);
+ assert.ok(!res.headersSent);
res.writeHead(200);
+ assert.ok(res.headersSent);
res.end('hello world\n');
// This checks that after the headers have been sent, getHeader works
// and does not throw an exception (Issue 752)
@@ -48,5 +50,6 @@ function runTest() {
response.on('end', function() {
s.close();
});
+ response.resume();
});
}
diff --git a/test/simple/test-http-header-response-splitting.js b/test/simple/test-http-header-response-splitting.js
index 044618436..1d3a85ce8 100644
--- a/test/simple/test-http-header-response-splitting.js
+++ b/test/simple/test-http-header-response-splitting.js
@@ -49,15 +49,17 @@ var server = http.createServer(function(req, res) {
}
res.end('Hi mars!');
});
-server.listen(common.PORT);
-for (var i = 0; i < 5; i++) {
- var req = http.get({ port: common.PORT, path: '/' }, function(res) {
- assert.strictEqual(res.headers.test, 'foo invalid: bar');
- assert.strictEqual(res.headers.invalid, undefined);
- responses++;
- });
-}
+server.listen(common.PORT, function() {
+ for (var i = 0; i < 5; i++) {
+ var req = http.get({ port: common.PORT, path: '/' }, function(res) {
+ assert.strictEqual(res.headers.test, 'foo invalid: bar');
+ assert.strictEqual(res.headers.invalid, undefined);
+ responses++;
+ res.resume();
+ });
+ }
+});
process.on('exit', function() {
assert.strictEqual(responses, 5);
diff --git a/test/simple/test-http-host-headers.js b/test/simple/test-http-host-headers.js
index 2e92ae577..ca7f70947 100644
--- a/test/simple/test-http-host-headers.js
+++ b/test/simple/test-http-host-headers.js
@@ -19,9 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
var http = require('http'),
https = require('https'),
fs = require('fs'),
@@ -60,13 +57,14 @@ function testHttp() {
var counter = 0;
- function cb() {
+ function cb(res) {
counter--;
console.log('back from http request. counter = ' + counter);
if (counter === 0) {
httpServer.close();
testHttps();
}
+ res.resume();
}
httpServer.listen(common.PORT, function(er) {
@@ -74,35 +72,50 @@ function testHttp() {
if (er) throw er;
- http.get({ method: 'GET',
+ http.get({
+ method: 'GET',
path: '/' + (counter++),
host: 'localhost',
//agent: false,
- port: common.PORT }, cb).on('error', thrower);
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower);
- http.request({ method: 'GET',
+ http.request({
+ method: 'GET',
path: '/' + (counter++),
host: 'localhost',
//agent: false,
- port: common.PORT }, cb).on('error', thrower).end();
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower).end();
- http.request({ method: 'POST',
+ http.request({
+ method: 'POST',
path: '/' + (counter++),
host: 'localhost',
//agent: false,
- port: common.PORT }, cb).on('error', thrower).end();
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower).end();
- http.request({ method: 'PUT',
+ http.request({
+ method: 'PUT',
path: '/' + (counter++),
host: 'localhost',
//agent: false,
- port: common.PORT }, cb).on('error', thrower).end();
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower).end();
- http.request({ method: 'DELETE',
+ http.request({
+ method: 'DELETE',
path: '/' + (counter++),
host: 'localhost',
//agent: false,
- port: common.PORT }, cb).on('error', thrower).end();
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower).end();
});
}
@@ -112,52 +125,71 @@ function testHttps() {
var counter = 0;
- function cb() {
+ function cb(res) {
counter--;
console.log('back from https request. counter = ' + counter);
if (counter === 0) {
httpsServer.close();
console.log('ok');
}
+ res.resume();
}
httpsServer.listen(common.PORT, function(er) {
if (er) throw er;
- https.get({ method: 'GET',
+ https.get({
+ method: 'GET',
path: '/' + (counter++),
host: 'localhost',
//agent: false,
- port: common.PORT }, cb).on('error', thrower);
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower);
- https.request({ method: 'GET',
+ https.request({
+ method: 'GET',
path: '/' + (counter++),
host: 'localhost',
//agent: false,
- port: common.PORT }, cb).on('error', thrower).end();
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower).end();
- https.request({ method: 'POST',
+ https.request({
+ method: 'POST',
path: '/' + (counter++),
host: 'localhost',
//agent: false,
- port: common.PORT }, cb).on('error', thrower).end();
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower).end();
- https.request({ method: 'PUT',
+ https.request({
+ method: 'PUT',
path: '/' + (counter++),
host: 'localhost',
//agent: false,
- port: common.PORT }, cb).on('error', thrower).end();
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower).end();
- https.request({ method: 'DELETE',
+ https.request({
+ method: 'DELETE',
path: '/' + (counter++),
host: 'localhost',
//agent: false,
- port: common.PORT }, cb).on('error', thrower).end();
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower).end();
- https.get({ method: 'GET',
+ https.get({
+ method: 'GET',
path: '/setHostFalse' + (counter++),
host: 'localhost',
setHost: false,
- port: common.PORT }, cb).on('error', thrower).end();
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, cb).on('error', thrower).end();
});
}
diff --git a/test/simple/test-http-keep-alive-close-on-header.js b/test/simple/test-http-keep-alive-close-on-header.js
index 8fd7348dd..53c73ae46 100644
--- a/test/simple/test-http-keep-alive-close-on-header.js
+++ b/test/simple/test-http-keep-alive-close-on-header.js
@@ -44,8 +44,9 @@ server.listen(common.PORT, function() {
headers: headers,
port: common.PORT,
agent: agent
- }, function() {
+ }, function(res) {
assert.equal(1, agent.sockets['localhost:' + common.PORT].length);
+ res.resume();
});
request.on('socket', function(s) {
s.on('connect', function() {
@@ -60,8 +61,9 @@ server.listen(common.PORT, function() {
headers: headers,
port: common.PORT,
agent: agent
- }, function() {
+ }, function(res) {
assert.equal(1, agent.sockets['localhost:' + common.PORT].length);
+ res.resume();
});
request.on('socket', function(s) {
s.on('connect', function() {
@@ -80,6 +82,7 @@ server.listen(common.PORT, function() {
assert.equal(1, agent.sockets['localhost:' + common.PORT].length);
server.close();
});
+ response.resume();
});
request.on('socket', function(s) {
s.on('connect', function() {
diff --git a/test/simple/test-http-keep-alive.js b/test/simple/test-http-keep-alive.js
index aa03639de..4e8a6e816 100644
--- a/test/simple/test-http-keep-alive.js
+++ b/test/simple/test-http-keep-alive.js
@@ -42,6 +42,7 @@ server.listen(common.PORT, function() {
}, function(response) {
assert.equal(agent.sockets[name].length, 1);
assert.equal(agent.requests[name].length, 2);
+ response.resume();
});
http.get({
@@ -49,6 +50,7 @@ server.listen(common.PORT, function() {
}, function(response) {
assert.equal(agent.sockets[name].length, 1);
assert.equal(agent.requests[name].length, 1);
+ response.resume();
});
http.get({
@@ -59,6 +61,7 @@ server.listen(common.PORT, function() {
assert(!agent.requests.hasOwnProperty(name));
server.close();
});
+ response.resume();
});
});
diff --git a/test/simple/test-http-localaddress-bind-error.js b/test/simple/test-http-localaddress-bind-error.js
index 0f9cdbbc0..719525cc6 100644
--- a/test/simple/test-http-localaddress-bind-error.js
+++ b/test/simple/test-http-localaddress-bind-error.js
@@ -33,6 +33,7 @@ var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('You are from: ' + req.connection.remoteAddress);
});
+ req.resume();
});
server.listen(common.PORT, "127.0.0.1", function() {
diff --git a/test/simple/test-http-localaddress.js b/test/simple/test-http-localaddress.js
index 1843d821b..d5778e09b 100644
--- a/test/simple/test-http-localaddress.js
+++ b/test/simple/test-http-localaddress.js
@@ -36,6 +36,7 @@ var server = http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('You are from: ' + req.connection.remoteAddress);
});
+ req.resume();
});
server.listen(common.PORT, "127.0.0.1", function() {
@@ -50,6 +51,7 @@ server.listen(common.PORT, "127.0.0.1", function() {
server.close();
process.exit();
});
+ res.resume();
});
req.end();
});
diff --git a/test/simple/test-http-many-keep-alive-connections.js b/test/simple/test-http-many-keep-alive-connections.js
index 4714cd523..adbebbdcc 100644
--- a/test/simple/test-http-many-keep-alive-connections.js
+++ b/test/simple/test-http-many-keep-alive-connections.js
@@ -55,6 +55,7 @@ server.listen(common.PORT, function() {
server.close();
}
});
+ res.resume();
}).on('error', function(e) {
console.log(e.message);
process.exit(1);
diff --git a/test/simple/test-http-multi-line-headers.js b/test/simple/test-http-multi-line-headers.js
index a212a04da..92bf9ecc8 100644
--- a/test/simple/test-http-multi-line-headers.js
+++ b/test/simple/test-http-multi-line-headers.js
@@ -40,10 +40,8 @@ var server = net.createServer(function(conn) {
'\r\n' +
body;
- conn.write(response, function() {
- conn.destroy();
- server.close();
- });
+ conn.end(response);
+ server.close();
});
server.listen(common.PORT, function() {
@@ -51,6 +49,7 @@ server.listen(common.PORT, function() {
assert.equal(res.headers['content-type'],
'text/plain;x-unix-mode=0600;name="hello.txt"');
gotResponse = true;
+ res.destroy();
});
});
diff --git a/test/simple/test-http-parser-free.js b/test/simple/test-http-parser-free.js
index bbf4a5027..7b35781f4 100644
--- a/test/simple/test-http-parser-free.js
+++ b/test/simple/test-http-parser-free.js
@@ -44,6 +44,7 @@ server.listen(common.PORT, function() {
if (++responses === N) {
server.close();
}
+ res.resume();
});
})(i);
}
diff --git a/test/simple/test-http-request-end-twice.js b/test/simple/test-http-request-end-twice.js
index f33cc6df3..aa5877222 100644
--- a/test/simple/test-http-request-end-twice.js
+++ b/test/simple/test-http-request-end-twice.js
@@ -36,6 +36,7 @@ server.listen(common.PORT, function() {
assert.ok(!req.end());
server.close();
});
+ res.resume();
});
});
diff --git a/test/simple/test-http-request-end.js b/test/simple/test-http-request-end.js
index f5da0faf2..f64dcc305 100644
--- a/test/simple/test-http-request-end.js
+++ b/test/simple/test-http-request-end.js
@@ -47,6 +47,7 @@ server.listen(common.PORT, function() {
method: 'POST'
}, function(res) {
console.log(res.statusCode);
+ res.resume();
}).on('error', function(e) {
console.log(e.message);
process.exit(1);
diff --git a/test/simple/test-http-res-write-end-dont-take-array.js b/test/simple/test-http-res-write-end-dont-take-array.js
index f4b3f8cce..0d68afc3f 100644
--- a/test/simple/test-http-res-write-end-dont-take-array.js
+++ b/test/simple/test-http-res-write-end-dont-take-array.js
@@ -53,11 +53,13 @@ var server = http.createServer(function(req, res) {
server.listen(common.PORT, function() {
// just make a request, other tests handle responses
- http.get({port: common.PORT}, function() {
+ http.get({port: common.PORT}, function(res) {
+ res.resume();
// lazy serial test, becuase we can only call end once per request
test += 1;
// do it again to test .end(Buffer);
- http.get({port: common.PORT}, function() {
+ http.get({port: common.PORT}, function(res) {
+ res.resume();
server.close();
});
});
diff --git a/test/simple/test-http-response-no-headers.js b/test/simple/test-http-response-no-headers.js
index cc5250d82..d16d8a4ce 100644
--- a/test/simple/test-http-response-no-headers.js
+++ b/test/simple/test-http-response-no-headers.js
@@ -41,9 +41,7 @@ function test(httpVersion, callback) {
var reply = 'HTTP/' + httpVersion + ' 200 OK\r\n\r\n' +
expected[httpVersion];
- conn.write(reply, function() {
- conn.destroy();
- });
+ conn.end(reply);
});
server.listen(common.PORT, '127.0.0.1', function() {
diff --git a/test/simple/test-http-response-readable.js b/test/simple/test-http-response-readable.js
index b31fcc3d1..b48c06fb4 100644
--- a/test/simple/test-http-response-readable.js
+++ b/test/simple/test-http-response-readable.js
@@ -35,6 +35,7 @@ testServer.listen(common.PORT, function() {
assert.equal(res.readable, false, 'res.readable set to false after end');
testServer.close();
});
+ res.resume();
});
});
diff --git a/test/simple/test-http-server-stale-close.js b/test/simple/test-http-server-stale-close.js
index e8ecf318e..aa42a049b 100644
--- a/test/simple/test-http-server-stale-close.js
+++ b/test/simple/test-http-server-stale-close.js
@@ -22,6 +22,7 @@
var common = require('../common');
var assert = require('assert');
var http = require('http');
+var util = require('util');
var fork = require('child_process').fork;
if (process.env.NODE_TEST_FORK) {
@@ -45,7 +46,7 @@ else {
});
server.listen(common.PORT, function() {
fork(__filename, {
- env: {NODE_TEST_FORK: '1'}
+ env: util._extend(process.env, {NODE_TEST_FORK: '1'})
});
});
}
diff --git a/test/simple/test-http-set-trailers.js b/test/simple/test-http-set-trailers.js
index a0896df5a..445a3eeaa 100644
--- a/test/simple/test-http-set-trailers.js
+++ b/test/simple/test-http-set-trailers.js
@@ -106,6 +106,7 @@ server.on('listening', function() {
process.exit();
}
});
+ res.resume();
});
outstanding_reqs++;
});
diff --git a/test/simple/test-http-status-code.js b/test/simple/test-http-status-code.js
index 395623869..ca56230d2 100644
--- a/test/simple/test-http-status-code.js
+++ b/test/simple/test-http-status-code.js
@@ -59,6 +59,7 @@ function nextTest() {
testIdx += 1;
nextTest();
});
+ response.resume();
});
}
diff --git a/test/simple/test-http-timeout.js b/test/simple/test-http-timeout.js
index 5170d795a..ddd01c8a8 100644
--- a/test/simple/test-http-timeout.js
+++ b/test/simple/test-http-timeout.js
@@ -25,7 +25,8 @@ var assert = require('assert');
var http = require('http');
-var port = 12345;
+var port = common.PORT;
+
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('OK');
@@ -55,6 +56,8 @@ server.listen(port, function() {
server.close();
}
})
+
+ res.resume();
});
req.setTimeout(1000, callback);
diff --git a/test/simple/test-http-url.parse-https.request.js b/test/simple/test-http-url.parse-https.request.js
index 6756db548..bcf37526a 100644
--- a/test/simple/test-http-url.parse-https.request.js
+++ b/test/simple/test-http-url.parse-https.request.js
@@ -33,6 +33,7 @@ var httpsOptions = {
};
var testURL = url.parse('https://localhost:' + common.PORT);
+testURL.rejectUnauthorized = false;
function check(request) {
// assert that I'm https
diff --git a/test/simple/test-https-agent.js b/test/simple/test-https-agent.js
index 41aa03486..34fa15c73 100644
--- a/test/simple/test-https-agent.js
+++ b/test/simple/test-https-agent.js
@@ -19,9 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
if (!process.versions.openssl) {
console.error('Skipping because node compiled without OpenSSL.');
process.exit(0);
@@ -52,7 +49,12 @@ server.listen(common.PORT, function() {
for (var i = 0; i < N; i++) {
setTimeout(function() {
for (var j = 0; j < M; j++) {
- https.get({ port: common.PORT, path: '/' }, function(res) {
+ https.get({
+ path: '/',
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function(res) {
+ res.resume();
console.log(res.statusCode);
if (++responses == N * M) server.close();
}).on('error', function(e) {
diff --git a/test/simple/test-https-byteswritten.js b/test/simple/test-https-byteswritten.js
new file mode 100644
index 000000000..21c300efa
--- /dev/null
+++ b/test/simple/test-https-byteswritten.js
@@ -0,0 +1,56 @@
+// 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.
+
+if (!process.versions.openssl) {
+ console.error('Skipping because node compiled without OpenSSL.');
+ process.exit(0);
+}
+
+var common = require('../common');
+var assert = require('assert');
+var fs = require('fs');
+var http = require('http');
+var https = require('https');
+
+var options = {
+ key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
+ cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
+};
+
+var body = 'hello world\n';
+
+var httpsServer = https.createServer(options, function(req, res) {
+ res.on('finish', function() {
+ assert(typeof(req.connection.bytesWritten) === 'number');
+ assert(req.connection.bytesWritten > 0);
+ httpsServer.close();
+ console.log('ok');
+ });
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
+ res.end(body);
+});
+
+httpsServer.listen(common.PORT, function() {
+ https.get({
+ port: common.PORT,
+ rejectUnauthorized: false
+ });
+});
diff --git a/test/simple/test-https-client-get-url.js b/test/simple/test-https-client-get-url.js
index c6ddb032d..ae5613c14 100644
--- a/test/simple/test-https-client-get-url.js
+++ b/test/simple/test-https-client-get-url.js
@@ -24,6 +24,9 @@ if (!process.versions.openssl) {
process.exit(0);
}
+// disable strict server certificate validation by the client
+process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
+
var common = require('../common');
var assert = require('assert');
var https = require('https');
diff --git a/test/simple/test-https-client-reject.js b/test/simple/test-https-client-reject.js
index 700caee68..45788a8c8 100644
--- a/test/simple/test-https-client-reject.js
+++ b/test/simple/test-https-client-reject.js
@@ -47,21 +47,21 @@ var server = https.createServer(options, function(req, res) {
function unauthorized() {
var req = https.request({
- port: common.PORT
+ port: common.PORT,
+ rejectUnauthorized: false
}, function(res) {
assert(!req.socket.authorized);
rejectUnauthorized();
});
req.on('error', function(err) {
- assert(false);
+ throw err;
});
req.end();
}
function rejectUnauthorized() {
var options = {
- port: common.PORT,
- rejectUnauthorized: true
+ port: common.PORT
};
options.agent = new https.Agent(options);
var req = https.request(options, function(res) {
@@ -76,7 +76,6 @@ function rejectUnauthorized() {
function authorized() {
var options = {
port: common.PORT,
- rejectUnauthorized: true,
ca: [fs.readFileSync(path.join(common.fixturesDir, 'test_cert.pem'))]
};
options.agent = new https.Agent(options);
diff --git a/test/simple/test-https-drain.js b/test/simple/test-https-drain.js
index 314944b76..5509a2474 100644
--- a/test/simple/test-https-drain.js
+++ b/test/simple/test-https-drain.js
@@ -47,8 +47,9 @@ var server = https.createServer(options, function(req, res) {
server.listen(common.PORT, function() {
var resumed = false;
var req = https.request({
+ method: 'POST',
port: common.PORT,
- method: 'POST'
+ rejectUnauthorized: false
}, function(res) {
var timer;
res.pause();
diff --git a/test/simple/test-https-eof-for-eom.js b/test/simple/test-https-eof-for-eom.js
index d5b5111c2..2b35835e9 100644
--- a/test/simple/test-https-eof-for-eom.js
+++ b/test/simple/test-https-eof-for-eom.js
@@ -19,9 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
// I hate HTTP. One way of terminating an HTTP response is to not send
// a content-length header, not send a transfer-encoding: chunked header,
// and simply terminate the TCP connection. That is identity
@@ -74,7 +71,10 @@ var bodyBuffer = '';
server.listen(common.PORT, function() {
console.log('1) Making Request');
- var req = https.get({ port: common.PORT }, function(res) {
+ var req = https.get({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function(res) {
server.close();
console.log('3) Client got response headers.');
diff --git a/test/simple/test-https-localaddress-bind-error.js b/test/simple/test-https-localaddress-bind-error.js
index 157df0580..0c4f8da4c 100644
--- a/test/simple/test-https-localaddress-bind-error.js
+++ b/test/simple/test-https-localaddress-bind-error.js
@@ -39,6 +39,7 @@ var server = https.createServer(options, function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('You are from: ' + req.connection.remoteAddress);
});
+ req.resume();
});
server.listen(common.PORT, "127.0.0.1", function() {
diff --git a/test/simple/test-https-localaddress.js b/test/simple/test-https-localaddress.js
index b171225be..f577af3ac 100644
--- a/test/simple/test-https-localaddress.js
+++ b/test/simple/test-https-localaddress.js
@@ -42,20 +42,25 @@ var server = https.createServer(options, function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('You are from: ' + req.connection.remoteAddress);
});
+ req.resume();
});
server.listen(common.PORT, "127.0.0.1", function() {
- var options = { host: 'localhost',
+ var options = {
+ host: 'localhost',
port: common.PORT,
path: '/',
method: 'GET',
- localAddress: '127.0.0.2' };
+ localAddress: '127.0.0.2',
+ rejectUnauthorized: false
+ };
var req = https.request(options, function(res) {
res.on('end', function() {
server.close();
process.exit();
});
+ res.resume();
});
req.end();
});
diff --git a/test/simple/test-https-no-reader.js b/test/simple/test-https-no-reader.js
new file mode 100644
index 000000000..5e63e1407
--- /dev/null
+++ b/test/simple/test-https-no-reader.js
@@ -0,0 +1,68 @@
+// 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.
+
+if (!process.versions.openssl) {
+ console.error('Skipping because node compiled without OpenSSL.');
+ process.exit(0);
+}
+
+var common = require('../common');
+var assert = require('assert');
+var https = require('https');
+var Buffer = require('buffer').Buffer;
+var fs = require('fs');
+var path = require('path');
+
+var options = {
+ key: fs.readFileSync(path.join(common.fixturesDir, 'test_key.pem')),
+ cert: fs.readFileSync(path.join(common.fixturesDir, 'test_cert.pem'))
+};
+
+var buf = new Buffer(1024 * 1024);
+var sent = 0;
+var received = 0;
+
+var server = https.createServer(options, function(req, res) {
+ res.writeHead(200);
+ for (var i = 0; i < 50; i++) {
+ res.write(buf);
+ }
+ res.end();
+});
+
+server.listen(common.PORT, function() {
+ var resumed = false;
+ var req = https.request({
+ method: 'POST',
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function(res) {
+ res.read(0);
+
+ setTimeout(function() {
+ // Read buffer should be somewhere near high watermark
+ // (i.e. should not leak)
+ assert(res._readableState.length < 100 * 1024);
+ process.exit(0);
+ }, 5000);
+ });
+ req.end();
+});
diff --git a/test/simple/test-https-pfx.js b/test/simple/test-https-pfx.js
index bfed64afd..9da1ff8ee 100644
--- a/test/simple/test-https-pfx.js
+++ b/test/simple/test-https-pfx.js
@@ -32,12 +32,13 @@ var options = {
path: '/',
pfx: pfx,
passphrase: 'sample',
- requestCert: true
+ requestCert: true,
+ rejectUnauthorized: false
};
var server = https.createServer(options, function(req, res) {
assert.equal(req.socket.authorized, false); // not a client cert
- assert.equal(req.socket.authorizationError, 'UNABLE_TO_GET_ISSUER_CERT');
+ assert.equal(req.socket.authorizationError, 'DEPTH_ZERO_SELF_SIGNED_CERT');
res.writeHead(200);
res.end('OK');
});
diff --git a/test/simple/test-https-socket-options.js b/test/simple/test-https-socket-options.js
index f0216647b..21b1118f7 100644
--- a/test/simple/test-https-socket-options.js
+++ b/test/simple/test-https-socket-options.js
@@ -19,9 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
if (!process.versions.openssl) {
console.error('Skipping because node compiled without OpenSSL.');
process.exit(0);
@@ -53,8 +50,12 @@ var server_http = http.createServer(function(req, res) {
server_http.listen(common.PORT, function() {
- var req = http.request({ port: common.PORT }, function(res) {
+ var req = http.request({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function(res) {
server_http.close();
+ res.resume();
});
// These methods should exist on the request and get passed down to the socket
req.setNoDelay(true);
@@ -72,8 +73,12 @@ var server_https = https.createServer(options, function(req, res) {
});
server_https.listen(common.PORT+1, function() {
- var req = https.request({ port: common.PORT+1 }, function(res) {
+ var req = https.request({
+ port: common.PORT + 1,
+ rejectUnauthorized: false
+ }, function(res) {
server_https.close();
+ res.resume();
});
// These methods should exist on the request and get passed down to the socket
req.setNoDelay(true);
diff --git a/test/simple/test-https-strict.js b/test/simple/test-https-strict.js
index e62c0d51a..720b0a6db 100644
--- a/test/simple/test-https-strict.js
+++ b/test/simple/test-https-strict.js
@@ -24,6 +24,9 @@ if (!process.versions.openssl) {
process.exit(0);
}
+// disable strict server certificate validation by the client
+process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
+
var common = require('../common');
var assert = require('assert');
@@ -167,6 +170,7 @@ function makeReq(path, port, error, host, ca) {
server2.close();
server3.close();
}
+ res.resume();
})
}
diff --git a/test/simple/test-https-timeout-server-2.js b/test/simple/test-https-timeout-server-2.js
new file mode 100644
index 000000000..076a0ec26
--- /dev/null
+++ b/test/simple/test-https-timeout-server-2.js
@@ -0,0 +1,51 @@
+// 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.
+
+if (!process.versions.openssl) process.exit();
+
+var common = require('../common');
+var assert = require('assert');
+var https = require('https');
+var net = require('net');
+var tls = require('tls');
+var fs = require('fs');
+
+var options = {
+ key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
+ cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
+};
+
+var server = https.createServer(options, assert.fail);
+
+server.on('secureConnection', function(cleartext) {
+ cleartext.setTimeout(50, function() {
+ cleartext.destroy();
+ server.close();
+ });
+});
+
+server.listen(common.PORT, function() {
+ tls.connect({
+ host: '127.0.0.1',
+ port: common.PORT,
+ rejectUnauthorized: false
+ });
+});
diff --git a/test/simple/test-https-timeout-server.js b/test/simple/test-https-timeout-server.js
new file mode 100644
index 000000000..18dc4b8fb
--- /dev/null
+++ b/test/simple/test-https-timeout-server.js
@@ -0,0 +1,58 @@
+// 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.
+
+if (!process.versions.openssl) process.exit();
+
+var common = require('../common');
+var assert = require('assert');
+var https = require('https');
+var net = require('net');
+var tls = require('tls');
+var fs = require('fs');
+
+var clientErrors = 0;
+
+process.on('exit', function() {
+ assert.equal(clientErrors, 1);
+});
+
+var options = {
+ key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
+ cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem'),
+ handshakeTimeout: 50
+};
+
+var server = https.createServer(options, assert.fail);
+
+server.on('clientError', function(err, conn) {
+ // Don't hesitate to update the asserts if the internal structure of
+ // the cleartext object ever changes. We're checking that the https.Server
+ // has closed the client connection.
+ assert.equal(conn._secureEstablished, false);
+ assert.equal(conn._doneFlag, true);
+ assert.equal(conn.ssl, null);
+ server.close();
+ clientErrors++;
+});
+
+server.listen(common.PORT, function() {
+ net.connect({ host: '127.0.0.1', port: common.PORT });
+});
diff --git a/test/simple/test-https-timeout.js b/test/simple/test-https-timeout.js
index 8a8ae00c3..8b79204d4 100644
--- a/test/simple/test-https-timeout.js
+++ b/test/simple/test-https-timeout.js
@@ -43,7 +43,8 @@ var server = https.createServer(options, function() {
host: 'localhost',
port: common.PORT,
path: '/',
- method: 'GET'
+ method: 'GET',
+ rejectUnauthorized: false
});
req.setTimeout(10);
req.end();
diff --git a/test/simple/test-module-loading.js b/test/simple/test-module-loading.js
index eadd6679c..8687c3b98 100644
--- a/test/simple/test-module-loading.js
+++ b/test/simple/test-module-loading.js
@@ -270,6 +270,17 @@ assert.deepEqual(children, {
});
+// require() must take string, and must be truthy
+assert.throws(function() {
+ console.error('require non-string');
+ require({ foo: 'bar' });
+}, 'path must be a string');
+
+assert.throws(function() {
+ console.error('require empty string');
+ require('');
+}, 'missing path');
+
process.on('exit', function() {
assert.ok(common.indirectInstanceOf(a.A, Function));
assert.equal('A done', a.A());
diff --git a/test/simple/test-net-after-close.js b/test/simple/test-net-after-close.js
index 65fda2190..2f3d4c379 100644
--- a/test/simple/test-net-after-close.js
+++ b/test/simple/test-net-after-close.js
@@ -25,12 +25,14 @@ var net = require('net');
var closed = false;
var server = net.createServer(function(s) {
+ console.error('SERVER: got connection');
s.end();
});
server.listen(common.PORT, function() {
var c = net.createConnection(common.PORT);
c.on('close', function() {
+ console.error('connection closed');
assert.strictEqual(c._handle, null);
closed = true;
assert.doesNotThrow(function() {
diff --git a/test/simple/test-net-binary.js b/test/simple/test-net-binary.js
index 349e2da00..310046584 100644
--- a/test/simple/test-net-binary.js
+++ b/test/simple/test-net-binary.js
@@ -41,12 +41,14 @@ for (var i = 255; i >= 0; i--) {
// safe constructor
var echoServer = net.Server(function(connection) {
+ console.error('SERVER got connection');
connection.setEncoding('binary');
connection.on('data', function(chunk) {
- common.error('recved: ' + JSON.stringify(chunk));
+ common.error('SERVER recved: ' + JSON.stringify(chunk));
connection.write(chunk, 'binary');
});
connection.on('end', function() {
+ console.error('SERVER ending');
connection.end();
});
});
@@ -55,29 +57,42 @@ echoServer.listen(common.PORT);
var recv = '';
echoServer.on('listening', function() {
+ console.error('SERVER listening');
var j = 0;
- var c = net.createConnection(common.PORT);
+ var c = net.createConnection({
+ port: common.PORT
+ });
c.setEncoding('binary');
c.on('data', function(chunk) {
- if (j < 256) {
- common.error('write ' + j);
+ console.error('CLIENT data %j', chunk);
+ var n = j + chunk.length;
+ while (j < n && j < 256) {
+ common.error('CLIENT write ' + j);
c.write(String.fromCharCode(j), 'binary');
j++;
- } else {
+ }
+ if (j === 256) {
+ console.error('CLIENT ending');
c.end();
}
recv += chunk;
});
c.on('connect', function() {
+ console.error('CLIENT connected, writing');
c.write(binaryString, 'binary');
});
c.on('close', function() {
+ console.error('CLIENT closed');
console.dir(recv);
echoServer.close();
});
+
+ c.on('finish', function() {
+ console.error('CLIENT finished');
+ });
});
process.on('exit', function() {
diff --git a/test/simple/test-net-buffersize.js b/test/simple/test-net-buffersize.js
new file mode 100644
index 000000000..5759503a1
--- /dev/null
+++ b/test/simple/test-net-buffersize.js
@@ -0,0 +1,51 @@
+// 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');
+var assert = require('assert');
+var net = require('net');
+
+var iter = 10;
+
+var server = net.createServer(function(socket) {
+ socket.on('readable', function() {
+ socket.read();
+ });
+
+ socket.on('end', function() {
+ server.close();
+ });
+});
+
+server.listen(common.PORT, function() {
+ var client = net.connect(common.PORT);
+
+ client.on('finish', function() {
+ assert.strictEqual(client.bufferSize, 0);
+ });
+
+ for (var i = 1; i < iter; i++) {
+ client.write('a');
+ assert.strictEqual(client.bufferSize, i);
+ }
+
+ client.end();
+});
diff --git a/test/simple/test-net-bytes-stats.js b/test/simple/test-net-bytes-stats.js
index a406e991c..0cb08009e 100644
--- a/test/simple/test-net-bytes-stats.js
+++ b/test/simple/test-net-bytes-stats.js
@@ -34,33 +34,40 @@ var count = 0;
var tcp = net.Server(function(s) {
console.log('tcp server connection');
+ // trigger old mode.
+ s.resume();
+
s.on('end', function() {
bytesRead += s.bytesRead;
console.log('tcp socket disconnect #' + count);
});
});
-tcp.listen(common.PORT, function() {
+tcp.listen(common.PORT, function doTest() {
+ console.error('listening');
var socket = net.createConnection(tcpPort);
socket.on('connect', function() {
count++;
- console.log('tcp client connection #' + count);
+ console.error('CLIENT connect #%d', count);
socket.write('foo', function() {
+ console.error('CLIENT: write cb');
socket.end('bar');
});
});
- socket.on('end', function() {
+ socket.on('finish', function() {
bytesWritten += socket.bytesWritten;
- console.log('tcp client disconnect #' + count);
+ console.error('CLIENT end event #%d', count);
});
socket.on('close', function() {
+ console.error('CLIENT close event #%d', count);
console.log('Bytes read: ' + bytesRead);
console.log('Bytes written: ' + bytesWritten);
if (count < 2) {
+ console.error('RECONNECTING');
socket.connect(tcpPort);
} else {
tcp.close();
diff --git a/test/simple/test-net-can-reset-timeout.js b/test/simple/test-net-can-reset-timeout.js
index bb9b07142..b9ea97efe 100644
--- a/test/simple/test-net-can-reset-timeout.js
+++ b/test/simple/test-net-can-reset-timeout.js
@@ -28,6 +28,8 @@ var timeoutCount = 0;
var server = net.createServer(function(stream) {
stream.setTimeout(100);
+ stream.resume();
+
stream.on('timeout', function() {
console.log('timeout');
// try to reset the timeout.
diff --git a/test/simple/test-net-connect-buffer.js b/test/simple/test-net-connect-buffer.js
index 095059362..679e18e90 100644
--- a/test/simple/test-net-connect-buffer.js
+++ b/test/simple/test-net-connect-buffer.js
@@ -38,6 +38,7 @@ var tcp = net.Server(function(s) {
});
s.on('end', function() {
+ console.error('SERVER: end', buf.toString());
assert.equal(buf, "L'État, c'est moi");
console.log('tcp socket disconnect');
s.end();
@@ -50,7 +51,7 @@ var tcp = net.Server(function(s) {
});
tcp.listen(common.PORT, function() {
- var socket = net.Stream();
+ var socket = net.Stream({ highWaterMark: 0 });
console.log('Connecting to socket ');
@@ -77,6 +78,7 @@ tcp.listen(common.PORT, function() {
{}
].forEach(function(v) {
function f() {
+ console.error('write', v);
socket.write(v);
}
assert.throws(f, TypeError);
@@ -90,12 +92,17 @@ tcp.listen(common.PORT, function() {
// We're still connecting at this point so the datagram is first pushed onto
// the connect queue. Make sure that it's not added to `bytesWritten` again
// when the actual write happens.
- var r = socket.write(a, function() {
+ var r = socket.write(a, function(er) {
+ console.error('write cb');
dataWritten = true;
assert.ok(connectHappened);
- assert.equal(socket.bytesWritten, Buffer(a + b).length);
+ console.error('socket.bytesWritten', socket.bytesWritten);
+ //assert.equal(socket.bytesWritten, Buffer(a + b).length);
console.error('data written');
});
+ console.error('socket.bytesWritten', socket.bytesWritten);
+ console.error('write returned', r);
+
assert.equal(socket.bytesWritten, Buffer(a).length);
assert.equal(false, r);
diff --git a/test/simple/test-net-connect-options.js b/test/simple/test-net-connect-options.js
index 8df692ef7..6be3696da 100644
--- a/test/simple/test-net-connect-options.js
+++ b/test/simple/test-net-connect-options.js
@@ -27,6 +27,7 @@ var serverGotEnd = false;
var clientGotEnd = false;
var server = net.createServer({allowHalfOpen: true}, function(socket) {
+ socket.resume();
socket.on('end', function() {
serverGotEnd = true;
});
@@ -39,6 +40,8 @@ server.listen(common.PORT, function() {
port: common.PORT,
allowHalfOpen: true
}, function() {
+ console.error('client connect cb');
+ client.resume();
client.on('end', function() {
clientGotEnd = true;
setTimeout(function() {
@@ -53,6 +56,7 @@ server.listen(common.PORT, function() {
});
process.on('exit', function() {
+ console.error('exit', serverGotEnd, clientGotEnd);
assert(serverGotEnd);
assert(clientGotEnd);
});
diff --git a/test/simple/test-net-connect-unref.js b/test/simple/test-net-connect-unref.js
new file mode 100644
index 000000000..29f43b10e
--- /dev/null
+++ b/test/simple/test-net-connect-unref.js
@@ -0,0 +1,45 @@
+// 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');
+var assert = require('assert');
+var net = require('net');
+
+var client, killed = false, ended = false;
+var TIMEOUT = 10 * 1000
+
+client = net.createConnection(53, '8.8.8.8', function() {
+ client.unref();
+});
+
+client.on('close', function() {
+ ended = true;
+});
+
+setTimeout(function() {
+ killed = true;
+ client.end();
+}, TIMEOUT).unref();
+
+process.on('exit', function() {
+ assert.strictEqual(killed, false, 'A client should have connected');
+ assert.strictEqual(ended, false, 'A client should stay connected');
+});
diff --git a/test/simple/test-net-end-without-connect.js b/test/simple/test-net-end-without-connect.js
new file mode 100644
index 000000000..156071a0d
--- /dev/null
+++ b/test/simple/test-net-end-without-connect.js
@@ -0,0 +1,26 @@
+// 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');
+var net = require('net');
+
+var sock = new net.Socket;
+sock.end(); // Should not throw.
diff --git a/test/simple/test-net-local-address-port.js b/test/simple/test-net-local-address-port.js
new file mode 100644
index 000000000..0f59cec9b
--- /dev/null
+++ b/test/simple/test-net-local-address-port.js
@@ -0,0 +1,47 @@
+// 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');
+var assert = require('assert');
+var net = require('net');
+
+var conns = 0, conns_closed = 0;
+
+var server = net.createServer(function(socket) {
+ conns++;
+ assert.equal('127.0.0.1', socket.localAddress);
+ assert.equal(socket.localPort, common.PORT);
+ socket.on('end', function() {
+ server.close();
+ });
+ socket.resume();
+});
+
+server.listen(common.PORT, '127.0.0.1', function() {
+ var client = net.createConnection(common.PORT, '127.0.0.1');
+ client.on('connect', function() {
+ client.end();
+ });
+});
+
+process.on('exit', function() {
+ assert.equal(1, conns);
+});
diff --git a/test/simple/test-net-pingpong.js b/test/simple/test-net-pingpong.js
index a81f0dc80..1e7b6681a 100644
--- a/test/simple/test-net-pingpong.js
+++ b/test/simple/test-net-pingpong.js
@@ -60,6 +60,8 @@ function pingPongTest(port, host) {
});
socket.on('end', function() {
+ console.error(socket);
+ assert.equal(true, socket.allowHalfOpen);
assert.equal(true, socket.writable); // because allowHalfOpen
assert.equal(false, socket.readable);
socket.end();
@@ -129,10 +131,11 @@ function pingPongTest(port, host) {
}
/* All are run at once, so run on different ports */
+console.log(common.PIPE);
pingPongTest(common.PIPE);
-pingPongTest(20988);
-pingPongTest(20989, 'localhost');
-pingPongTest(20997, '::1');
+pingPongTest(common.PORT);
+pingPongTest(common.PORT + 1, 'localhost');
+pingPongTest(common.PORT + 2, '::1');
process.on('exit', function() {
assert.equal(4, tests_run);
diff --git a/test/simple/test-net-reconnect.js b/test/simple/test-net-reconnect.js
index f7fcb8b29..58e0fef62 100644
--- a/test/simple/test-net-reconnect.js
+++ b/test/simple/test-net-reconnect.js
@@ -30,39 +30,49 @@ var client_recv_count = 0;
var disconnect_count = 0;
var server = net.createServer(function(socket) {
+ console.error('SERVER: got socket connection');
+ socket.resume();
+
socket.on('connect', function() {
+ console.error('SERVER connect, writing');
socket.write('hello\r\n');
});
socket.on('end', function() {
+ console.error('SERVER socket end, calling end()');
socket.end();
});
socket.on('close', function(had_error) {
- //console.log('server had_error: ' + JSON.stringify(had_error));
+ console.log('SERVER had_error: ' + JSON.stringify(had_error));
assert.equal(false, had_error);
});
});
server.listen(common.PORT, function() {
- console.log('listening');
+ console.log('SERVER listening');
var client = net.createConnection(common.PORT);
client.setEncoding('UTF8');
client.on('connect', function() {
- console.log('client connected.');
+ console.error('CLIENT connected', client._writableState);
});
client.on('data', function(chunk) {
client_recv_count += 1;
console.log('client_recv_count ' + client_recv_count);
assert.equal('hello\r\n', chunk);
+ console.error('CLIENT: calling end', client._writableState);
client.end();
});
+ client.on('end', function() {
+ console.error('CLIENT end');
+ });
+
client.on('close', function(had_error) {
- console.log('disconnect');
+ console.log('CLIENT disconnect');
assert.equal(false, had_error);
if (disconnect_count++ < N)
client.connect(common.PORT); // reconnect
diff --git a/test/simple/test-net-remote-address-port.js b/test/simple/test-net-remote-address-port.js
index 9b585fce9..5d1ae3c8e 100644
--- a/test/simple/test-net-remote-address-port.js
+++ b/test/simple/test-net-remote-address-port.js
@@ -34,6 +34,7 @@ var server = net.createServer(function(socket) {
socket.on('end', function() {
if (++conns_closed == 2) server.close();
});
+ socket.resume();
});
server.listen(common.PORT, 'localhost', function() {
diff --git a/test/simple/test-net-server-unref.js b/test/simple/test-net-server-unref.js
new file mode 100644
index 000000000..d20cbe506
--- /dev/null
+++ b/test/simple/test-net-server-unref.js
@@ -0,0 +1,39 @@
+// 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');
+var assert = require('assert');
+
+var net = require('net');
+var closed = false;
+
+var s = net.createServer();
+s.listen();
+s.unref();
+
+setTimeout(function() {
+ closed = true;
+ s.close();
+}, 1000).unref();
+
+process.on('exit', function() {
+ assert.strictEqual(closed, false, 'Unrefd socket should not hold loop open');
+});
diff --git a/test/simple/test-net-write-after-close.js b/test/simple/test-net-write-after-close.js
index b77e9af72..3b98bbc42 100644
--- a/test/simple/test-net-write-after-close.js
+++ b/test/simple/test-net-write-after-close.js
@@ -32,12 +32,16 @@ process.on('exit', function() {
});
var server = net.createServer(function(socket) {
+ socket.resume();
+
socket.on('error', function(error) {
+ console.error('got error, closing server', error);
server.close();
gotError = true;
});
setTimeout(function() {
+ console.error('about to try to write');
socket.write('test', function(e) {
gotWriteCB = true;
});
diff --git a/test/simple/test-next-tick-error-spin.js b/test/simple/test-next-tick-error-spin.js
new file mode 100644
index 000000000..4ed31511b
--- /dev/null
+++ b/test/simple/test-next-tick-error-spin.js
@@ -0,0 +1,69 @@
+// 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');
+var assert = require('assert');
+
+if (process.argv[2] !== 'child') {
+ var spawn = require('child_process').spawn;
+ var child = spawn(process.execPath, [__filename, 'child'], {
+ stdio: 'pipe'//'inherit'
+ });
+ var timer = setTimeout(function() {
+ throw new Error('child is hung');
+ }, 500);
+ child.on('exit', function(code) {
+ console.error('ok');
+ assert(!code);
+ clearTimeout(timer);
+ });
+} else {
+
+ var domain = require('domain');
+ var d = domain.create();
+ process.maxTickDepth = 10;
+
+ // in the error handler, we trigger several MakeCallback events
+ d.on('error', function(e) {
+ console.log('a')
+ console.log('b')
+ console.log('c')
+ console.log('d')
+ console.log('e')
+ f();
+ });
+
+ function f() {
+ process.nextTick(function() {
+ d.run(function() {
+ throw(new Error('x'));
+ });
+ });
+ }
+
+ f();
+ setTimeout(function () {
+ console.error('broke in!');
+ //process.stdout.close();
+ //process.stderr.close();
+ process.exit(0);
+ });
+}
diff --git a/test/simple/test-next-tick-intentional-starvation.js b/test/simple/test-next-tick-intentional-starvation.js
new file mode 100644
index 000000000..1a76b27e4
--- /dev/null
+++ b/test/simple/test-next-tick-intentional-starvation.js
@@ -0,0 +1,64 @@
+// 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');
+var assert = require('assert');
+
+// this is the inverse of test-next-tick-starvation.
+// it verifies that process.nextTick will *always* come before other
+// events, up to the limit of the process.maxTickDepth value.
+
+// WARNING: unsafe!
+process.maxTickDepth = Infinity;
+
+var ran = false;
+var starved = false;
+var start = +new Date();
+var timerRan = false;
+
+function spin() {
+ ran = true;
+ var now = +new Date();
+ if (now - start > 100) {
+ console.log('The timer is starving, just as we planned.');
+ starved = true;
+
+ // now let it out.
+ return;
+ }
+
+ process.nextTick(spin);
+}
+
+function onTimeout() {
+ if (!starved) throw new Error('The timer escaped!');
+ console.log('The timer ran once the ban was lifted');
+ timerRan = true;
+}
+
+spin();
+setTimeout(onTimeout, 50);
+
+process.on('exit', function() {
+ assert.ok(ran);
+ assert.ok(starved);
+ assert.ok(timerRan);
+});
diff --git a/test/simple/test-next-tick.js b/test/simple/test-next-tick.js
index 894729cc6..2e40658c9 100644
--- a/test/simple/test-next-tick.js
+++ b/test/simple/test-next-tick.js
@@ -44,7 +44,9 @@ process.nextTick(function() {
complete++;
});
-
process.on('exit', function() {
assert.equal(5, complete);
+ process.nextTick(function() {
+ throw new Error('this should not occur');
+ });
});
diff --git a/test/simple/test-os.js b/test/simple/test-os.js
index b141f0008..79de1b14a 100644
--- a/test/simple/test-os.js
+++ b/test/simple/test-os.js
@@ -31,13 +31,17 @@ process.env.TMPDIR = '/tmpdir';
process.env.TMP = '/tmp';
process.env.TEMP = '/temp';
var t = ( process.platform === 'win32' ? 'c:\\windows\\temp' : '/tmp' );
-assert.equal(os.tmpDir(), '/tmpdir');
+assert.equal(os.tmpdir(), '/tmpdir');
process.env.TMPDIR = '';
-assert.equal(os.tmpDir(), '/tmp');
+assert.equal(os.tmpdir(), '/tmp');
process.env.TMP = '';
-assert.equal(os.tmpDir(), '/temp');
+assert.equal(os.tmpdir(), '/temp');
process.env.TEMP = '';
-assert.equal(os.tmpDir(), t);
+assert.equal(os.tmpdir(), t);
+
+var endianness = os.endianness();
+console.log('endianness = %s', endianness);
+assert.ok(/[BL]E/.test(endianness));
var hostname = os.hostname();
console.log('hostname = %s', hostname);
diff --git a/test/simple/test-path-makelong.js b/test/simple/test-path-makelong.js
index 0ec298fe3..d9d8efd40 100644
--- a/test/simple/test-path-makelong.js
+++ b/test/simple/test-path-makelong.js
@@ -19,11 +19,11 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-if (process.platform === 'win32') {
- var assert = require('assert');
- var path = require('path');
- var common = require('../common');
+var assert = require('assert');
+var path = require('path');
+var common = require('../common');
+if (process.platform === 'win32') {
var file = path.join(common.fixturesDir, 'a.js');
var resolvedFile = path.resolve(file);
@@ -36,3 +36,9 @@ if (process.platform === 'win32') {
assert.equal('\\\\.\\pipe\\somepipe',
path._makeLong('\\\\.\\pipe\\somepipe'));
}
+
+assert.equal(path._makeLong(null), null);
+assert.equal(path._makeLong(100), 100);
+assert.equal(path._makeLong(path), path);
+assert.equal(path._makeLong(false), false);
+assert.equal(path._makeLong(true), true);
diff --git a/test/simple/test-path.js b/test/simple/test-path.js
index 38a8dab89..da076d494 100644
--- a/test/simple/test-path.js
+++ b/test/simple/test-path.js
@@ -30,6 +30,29 @@ var f = __filename;
assert.equal(path.basename(f), 'test-path.js');
assert.equal(path.basename(f, '.js'), 'test-path');
+assert.equal(path.basename(''), '');
+assert.equal(path.basename('/dir/basename.ext'), 'basename.ext');
+assert.equal(path.basename('/basename.ext'), 'basename.ext');
+assert.equal(path.basename('basename.ext'), 'basename.ext');
+assert.equal(path.basename('basename.ext/'), 'basename.ext');
+assert.equal(path.basename('basename.ext//'), 'basename.ext');
+
+if (isWindows) {
+ // On Windows a backslash acts as a path separator.
+ assert.equal(path.basename('\\dir\\basename.ext'), 'basename.ext');
+ assert.equal(path.basename('\\basename.ext'), 'basename.ext');
+ assert.equal(path.basename('basename.ext'), 'basename.ext');
+ assert.equal(path.basename('basename.ext\\'), 'basename.ext');
+ assert.equal(path.basename('basename.ext\\\\'), 'basename.ext');
+
+} else {
+ // On unix a backslash is just treated as any other character.
+ assert.equal(path.basename('\\dir\\basename.ext'), '\\dir\\basename.ext');
+ assert.equal(path.basename('\\basename.ext'), '\\basename.ext');
+ assert.equal(path.basename('basename.ext'), 'basename.ext');
+ assert.equal(path.basename('basename.ext\\'), 'basename.ext\\');
+ assert.equal(path.basename('basename.ext\\\\'), 'basename.ext\\\\');
+}
// POSIX filenames may include control characters
// c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html
@@ -46,7 +69,9 @@ assert.equal(path.dirname(f).substr(-11),
assert.equal(path.dirname('/a/b/'), '/a');
assert.equal(path.dirname('/a/b'), '/a');
assert.equal(path.dirname('/a'), '/');
+assert.equal(path.dirname(''), '.');
assert.equal(path.dirname('/'), '/');
+assert.equal(path.dirname('////'), '/');
if (isWindows) {
assert.equal(path.dirname('c:\\'), 'c:\\');
@@ -114,18 +139,34 @@ assert.equal(path.extname('..file..'), '.');
assert.equal(path.extname('...'), '.');
assert.equal(path.extname('...ext'), '.ext');
assert.equal(path.extname('....'), '.');
-assert.equal(path.extname('file.ext/'), '');
+assert.equal(path.extname('file.ext/'), '.ext');
+assert.equal(path.extname('file.ext//'), '.ext');
+assert.equal(path.extname('file/'), '');
+assert.equal(path.extname('file//'), '');
+assert.equal(path.extname('file./'), '.');
+assert.equal(path.extname('file.//'), '.');
if (isWindows) {
// On windows, backspace is a path separator.
assert.equal(path.extname('.\\'), '');
assert.equal(path.extname('..\\'), '');
- assert.equal(path.extname('file.ext\\'), '');
+ assert.equal(path.extname('file.ext\\'), '.ext');
+ assert.equal(path.extname('file.ext\\\\'), '.ext');
+ assert.equal(path.extname('file\\'), '');
+ assert.equal(path.extname('file\\\\'), '');
+ assert.equal(path.extname('file.\\'), '.');
+ assert.equal(path.extname('file.\\\\'), '.');
+
} else {
// On unix, backspace is a valid name component like any other character.
assert.equal(path.extname('.\\'), '');
assert.equal(path.extname('..\\'), '.\\');
assert.equal(path.extname('file.ext\\'), '.ext\\');
+ assert.equal(path.extname('file.ext\\\\'), '.ext\\\\');
+ assert.equal(path.extname('file\\'), '');
+ assert.equal(path.extname('file\\\\'), '');
+ assert.equal(path.extname('file.\\'), '.\\');
+ assert.equal(path.extname('file.\\\\'), '.\\\\');
}
// path.join tests
@@ -172,9 +213,65 @@ var joinTests =
[[' ', '.'], ' '],
[[' ', '/'], ' /'],
[[' ', ''], ' '],
- // filtration of non-strings.
- [['x', true, 7, 'y', null, {}], 'x/y']
+ [['/', 'foo'], '/foo'],
+ [['/', '/foo'], '/foo'],
+ [['/', '//foo'], '/foo'],
+ [['/', '', '/foo'], '/foo'],
+ [['', '/', 'foo'], '/foo'],
+ [['', '/', '/foo'], '/foo']
];
+
+// Windows-specific join tests
+if (isWindows) {
+ joinTests = joinTests.concat(
+ [// UNC path expected
+ [['//foo/bar'], '//foo/bar/'],
+ [['\\/foo/bar'], '//foo/bar/'],
+ [['\\\\foo/bar'], '//foo/bar/'],
+ // UNC path expected - server and share separate
+ [['//foo', 'bar'], '//foo/bar/'],
+ [['//foo/', 'bar'], '//foo/bar/'],
+ [['//foo', '/bar'], '//foo/bar/'],
+ // UNC path expected - questionable
+ [['//foo', '', 'bar'], '//foo/bar/'],
+ [['//foo/', '', 'bar'], '//foo/bar/'],
+ [['//foo/', '', '/bar'], '//foo/bar/'],
+ // UNC path expected - even more questionable
+ [['', '//foo', 'bar'], '//foo/bar/'],
+ [['', '//foo/', 'bar'], '//foo/bar/'],
+ [['', '//foo/', '/bar'], '//foo/bar/'],
+ // No UNC path expected (no double slash in first component)
+ [['\\', 'foo/bar'], '/foo/bar'],
+ [['\\', '/foo/bar'], '/foo/bar'],
+ [['', '/', '/foo/bar'], '/foo/bar'],
+ // No UNC path expected (no non-slashes in first component - questionable)
+ [['//', 'foo/bar'], '/foo/bar'],
+ [['//', '/foo/bar'], '/foo/bar'],
+ [['\\\\', '/', '/foo/bar'], '/foo/bar'],
+ [['//'], '/'],
+ // No UNC path expected (share name missing - questionable).
+ [['//foo'], '/foo'],
+ [['//foo/'], '/foo/'],
+ [['//foo', '/'], '/foo/'],
+ [['//foo', '', '/'], '/foo/'],
+ // No UNC path expected (too many leading slashes - questionable)
+ [['///foo/bar'], '/foo/bar'],
+ [['////foo', 'bar'], '/foo/bar'],
+ [['\\\\\\/foo/bar'], '/foo/bar'],
+ // Drive-relative vs drive-absolute paths. This merely describes the
+ // status quo, rather than being obviously right
+ [['c:'], 'c:.'],
+ [['c:.'], 'c:.'],
+ [['c:', ''], 'c:.'],
+ [['', 'c:'], 'c:.'],
+ [['c:.', '/'], 'c:./'],
+ [['c:.', 'file'], 'c:file'],
+ [['c:', '/'], 'c:/'],
+ [['c:', 'file'], 'c:/file']
+ ]);
+}
+
+// Run the join tests.
joinTests.forEach(function(test) {
var actual = path.join.apply(path, test[0]);
var expected = isWindows ? test[1].replace(/\//g, '\\') : test[1];
@@ -185,6 +282,16 @@ joinTests.forEach(function(test) {
// assert.equal(actual, expected, message);
});
assert.equal(failures.length, 0, failures.join(''));
+var joinThrowTests = [true, false, 7, null, {}, undefined, [], NaN];
+joinThrowTests.forEach(function(test) {
+ assert.throws(function() {
+ path.join(test);
+ }, TypeError);
+ assert.throws(function() {
+ path.resolve(test);
+ }, TypeError);
+});
+
// path normalize tests
if (isWindows) {
@@ -215,7 +322,13 @@ if (isWindows) {
[['c:/ignore', 'c:/some/file'], 'c:\\some\\file'],
[['d:/ignore', 'd:some/dir//'], 'd:\\ignore\\some\\dir'],
[['.'], process.cwd()],
- [['//server/share', '..', 'relative\\'], '\\\\server\\share\\relative']];
+ [['//server/share', '..', 'relative\\'], '\\\\server\\share\\relative'],
+ [['c:/', '//'], 'c:\\'],
+ [['c:/', '//dir'], 'c:\\dir'],
+ [['c:/', '//server/share'], '\\\\server\\share\\'],
+ [['c:/', '//server//share'], '\\\\server\\share\\'],
+ [['c:/', '///some//dir'], 'c:\\some\\dir']
+ ];
} else {
// Posix
var resolveTests =
@@ -277,9 +390,18 @@ assert.equal(failures.length, 0, failures.join(''));
// path.sep tests
if (isWindows) {
- // windows
- assert.equal(path.sep, '\\');
+ // windows
+ assert.equal(path.sep, '\\');
+} else {
+ // posix
+ assert.equal(path.sep, '/');
+}
+
+// path.delimiter tests
+if (isWindows) {
+ // windows
+ assert.equal(path.delimiter, ';');
} else {
- // posix
- assert.equal(path.sep, '/');
+ // posix
+ assert.equal(path.delimiter, ':');
}
diff --git a/test/simple/test-pipe-file-to-http.js b/test/simple/test-pipe-file-to-http.js
index 99fad6ebb..1b3ba7089 100644
--- a/test/simple/test-pipe-file-to-http.js
+++ b/test/simple/test-pipe-file-to-http.js
@@ -31,6 +31,7 @@ var clientReqComplete = false;
var count = 0;
var server = http.createServer(function(req, res) {
+ console.error('SERVER request');
var timeoutId;
assert.equal('POST', req.method);
req.pause();
@@ -63,6 +64,8 @@ server.on('listening', function() {
cp.exec(cmd, function(err, stdout, stderr) {
if (err) throw err;
+ console.error('EXEC returned successfully stdout=%d stderr=%d',
+ stdout.length, stderr.length);
makeRequest();
});
});
@@ -75,8 +78,15 @@ function makeRequest() {
});
common.error('pipe!');
+
var s = fs.ReadStream(filename);
s.pipe(req);
+ s.on('data', function(chunk) {
+ console.error('FS data chunk=%d', chunk.length);
+ });
+ s.on('end', function() {
+ console.error('FS end');
+ });
s.on('close', function(err) {
if (err) throw err;
clientReqComplete = true;
@@ -84,7 +94,10 @@ function makeRequest() {
});
req.on('response', function(res) {
+ console.error('RESPONSE', res.statusCode, res.headers);
+ res.resume();
res.on('end', function() {
+ console.error('RESPONSE end');
server.close();
});
});
diff --git a/test/simple/test-pipe-unref.js b/test/simple/test-pipe-unref.js
new file mode 100644
index 000000000..9f715a9d1
--- /dev/null
+++ b/test/simple/test-pipe-unref.js
@@ -0,0 +1,39 @@
+// 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');
+var assert = require('assert');
+
+var net = require('net');
+var closed = false;
+
+var s = net.Server();
+s.listen(common.PIPE);
+s.unref();
+
+setTimeout(function() {
+ closed = true;
+ s.close();
+}, 1000).unref();
+
+process.on('exit', function() {
+ assert.strictEqual(closed, false, 'Unrefd socket should not hold loop open');
+});
diff --git a/test/simple/test-pipe.js b/test/simple/test-pipe.js
index 3dd243725..9f1dae885 100644
--- a/test/simple/test-pipe.js
+++ b/test/simple/test-pipe.js
@@ -125,6 +125,7 @@ function startClient() {
});
req.write(buffer);
req.end();
+ console.error('ended request', req);
}
process.on('exit', function() {
diff --git a/test/simple/test-process-active-wraps.js b/test/simple/test-process-active-wraps.js
index 3fdf993c1..fe68e15f0 100644
--- a/test/simple/test-process-active-wraps.js
+++ b/test/simple/test-process-active-wraps.js
@@ -46,11 +46,16 @@ function expect(activeHandles, activeRequests) {
expect(2, 1); // client handle doesn't shut down until next tick
})();
+// Force the nextTicks to be deferred to a later time.
+process.maxTickDepth = 1;
+
process.nextTick(function() {
process.nextTick(function() {
process.nextTick(function() {
- // the handles should be gone but the connect req could still be alive
- assert.equal(process._getActiveHandles().length, 0);
+ process.nextTick(function() {
+ // the handles should be gone but the connect req could still be alive
+ assert.equal(process._getActiveHandles().length, 0);
+ });
});
});
});
diff --git a/test/simple/test-process-env.js b/test/simple/test-process-env.js
index fdf35ba77..919d0d54e 100644
--- a/test/simple/test-process-env.js
+++ b/test/simple/test-process-env.js
@@ -47,8 +47,18 @@ if (process.argv[2] == 'you-are-the-child') {
// failed assertion results in process exiting with status code 1
assert.equal(false, 'NODE_PROCESS_ENV_DELETED' in process.env);
assert.equal(42, process.env.NODE_PROCESS_ENV);
+ assert.equal('asdf', process.env.hasOwnProperty);
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
+ var has = hasOwnProperty.call(process.env, 'hasOwnProperty');
+ assert.equal(true, has);
process.exit(0);
} else {
+ assert.equal(Object.prototype.hasOwnProperty, process.env.hasOwnProperty);
+ var has = process.env.hasOwnProperty('hasOwnProperty');
+ assert.equal(false, has);
+
+ process.env.hasOwnProperty = 'asdf';
+
process.env.NODE_PROCESS_ENV = 42;
assert.equal(42, process.env.NODE_PROCESS_ENV);
diff --git a/test/simple/test-process-getgroups.js b/test/simple/test-process-getgroups.js
new file mode 100644
index 000000000..c24a17ace
--- /dev/null
+++ b/test/simple/test-process-getgroups.js
@@ -0,0 +1,41 @@
+// 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');
+var assert = require('assert');
+var exec = require('child_process').exec;
+
+if (typeof process.getgroups === 'function') {
+ var groups = process.getgroups();
+ assert(Array.isArray(groups));
+ assert(groups.length > 0);
+ exec('id -G', function(err, stdout) {
+ if (err) throw err;
+ var real_groups = stdout.match(/\d+/g).map(Number);
+ assert.equal(groups.length, real_groups.length);
+ check(groups, real_groups);
+ check(real_groups, groups);
+ });
+}
+
+function check(a, b) {
+ for (var i = 0; i < a.length; ++i) assert(b.indexOf(a[i]) !== -1);
+}
diff --git a/test/simple/test-punycode.js b/test/simple/test-punycode.js
index f3d6dd781..fa6a9c0ec 100644
--- a/test/simple/test-punycode.js
+++ b/test/simple/test-punycode.js
@@ -179,4 +179,17 @@ for (var encoded in tests) {
}
}
+// BMP code point
+assert.equal(punycode.ucs2.encode([0x61]), 'a');
+// supplementary code point (surrogate pair)
+assert.equal(punycode.ucs2.encode([0x1D306]), '\uD834\uDF06');
+// high surrogate
+assert.equal(punycode.ucs2.encode([0xD800]), '\uD800');
+// high surrogate followed by non-surrogates
+assert.equal(punycode.ucs2.encode([0xD800, 0x61, 0x62]), '\uD800ab');
+// low surrogate
+assert.equal(punycode.ucs2.encode([0xDC00]), '\uDC00');
+// low surrogate followed by non-surrogates
+assert.equal(punycode.ucs2.encode([0xDC00, 0x61, 0x62]), '\uDC00ab');
+
assert.equal(errors, 0);
diff --git a/test/simple/test-readline-interface.js b/test/simple/test-readline-interface.js
index 568b73a29..fc20d1d21 100644
--- a/test/simple/test-readline-interface.js
+++ b/test/simple/test-readline-interface.js
@@ -32,100 +32,147 @@ function FakeInput() {
inherits(FakeInput, EventEmitter);
FakeInput.prototype.resume = function() {};
FakeInput.prototype.pause = function() {};
+FakeInput.prototype.write = function() {};
+FakeInput.prototype.end = function() {};
-var fi;
-var rli;
-var called;
-
-// sending a full line
-fi = new FakeInput();
-rli = new readline.Interface(fi, {});
-called = false;
-rli.on('line', function(line) {
- called = true;
- assert.equal(line, 'asdf\n');
-});
-fi.emit('data', 'asdf\n');
-assert.ok(called);
-
-// sending a blank line
-fi = new FakeInput();
-rli = new readline.Interface(fi, {});
-called = false;
-rli.on('line', function(line) {
- called = true;
- assert.equal(line, '\n');
-});
-fi.emit('data', '\n');
-assert.ok(called);
-
-// sending a single character with no newline
-fi = new FakeInput();
-rli = new readline.Interface(fi, {});
-called = false;
-rli.on('line', function(line) {
- called = true;
-});
-fi.emit('data', 'a');
-assert.ok(!called);
-rli.close();
-
-// sending a single character with no newline and then a newline
-fi = new FakeInput();
-rli = new readline.Interface(fi, {});
-called = false;
-rli.on('line', function(line) {
- called = true;
- assert.equal(line, 'a\n');
-});
-fi.emit('data', 'a');
-assert.ok(!called);
-fi.emit('data', '\n');
-assert.ok(called);
-rli.close();
-
-// sending multiple newlines at once
-fi = new FakeInput();
-rli = new readline.Interface(fi, {});
-var expectedLines = ['foo\n', 'bar\n', 'baz\n'];
-var callCount = 0;
-rli.on('line', function(line) {
- assert.equal(line, expectedLines[callCount]);
- callCount++;
-});
-fi.emit('data', expectedLines.join(''));
-assert.equal(callCount, expectedLines.length);
-rli.close();
-
-// sending multiple newlines at once that does not end with a new line
-fi = new FakeInput();
-rli = new readline.Interface(fi, {});
-var expectedLines = ['foo\n', 'bar\n', 'baz\n', 'bat'];
-var callCount = 0;
-rli.on('line', function(line) {
- assert.equal(line, expectedLines[callCount]);
- callCount++;
-});
-fi.emit('data', expectedLines.join(''));
-assert.equal(callCount, expectedLines.length - 1);
-rli.close();
-
-// sending a multi-byte utf8 char over multiple writes
-var buf = Buffer('☮', 'utf8');
-fi = new FakeInput();
-rli = new readline.Interface(fi, {});
-callCount = 0;
-rli.on('line', function(line) {
- callCount++;
- assert.equal(line, buf.toString('utf8') + '\n');
-});
-[].forEach.call(buf, function(i) {
- fi.emit('data', Buffer([i]));
-});
-assert.equal(callCount, 0);
-fi.emit('data', '\n');
-assert.equal(callCount, 1);
-rli.close();
+[ true, false ].forEach(function(terminal) {
+ var fi;
+ var rli;
+ var called;
+
+ // sending a full line
+ fi = new FakeInput();
+ rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
+ called = false;
+ rli.on('line', function(line) {
+ called = true;
+ assert.equal(line, 'asdf');
+ });
+ fi.emit('data', 'asdf\n');
+ assert.ok(called);
+
+ // sending a blank line
+ fi = new FakeInput();
+ rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
+ called = false;
+ rli.on('line', function(line) {
+ called = true;
+ assert.equal(line, '');
+ });
+ fi.emit('data', '\n');
+ assert.ok(called);
-assert.deepEqual(fi.listeners('end'), []);
-assert.deepEqual(fi.listeners('data'), []);
+ // sending a single character with no newline
+ fi = new FakeInput();
+ rli = new readline.Interface(fi, {});
+ called = false;
+ rli.on('line', function(line) {
+ called = true;
+ });
+ fi.emit('data', 'a');
+ assert.ok(!called);
+ rli.close();
+
+ // sending a single character with no newline and then a newline
+ fi = new FakeInput();
+ rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
+ called = false;
+ rli.on('line', function(line) {
+ called = true;
+ assert.equal(line, 'a');
+ });
+ fi.emit('data', 'a');
+ assert.ok(!called);
+ fi.emit('data', '\n');
+ assert.ok(called);
+ rli.close();
+
+ // sending multiple newlines at once
+ fi = new FakeInput();
+ rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
+ var expectedLines = ['foo', 'bar', 'baz'];
+ var callCount = 0;
+ rli.on('line', function(line) {
+ assert.equal(line, expectedLines[callCount]);
+ callCount++;
+ });
+ fi.emit('data', expectedLines.join('\n') + '\n');
+ assert.equal(callCount, expectedLines.length);
+ rli.close();
+
+ // sending multiple newlines at once that does not end with a new line
+ fi = new FakeInput();
+ rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
+ expectedLines = ['foo', 'bar', 'baz', 'bat'];
+ callCount = 0;
+ rli.on('line', function(line) {
+ assert.equal(line, expectedLines[callCount]);
+ callCount++;
+ });
+ fi.emit('data', expectedLines.join('\n'));
+ assert.equal(callCount, expectedLines.length - 1);
+ rli.close();
+
+ // \r\n should emit one line event, not two
+ fi = new FakeInput();
+ rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
+ expectedLines = ['foo', 'bar', 'baz', 'bat'];
+ callCount = 0;
+ rli.on('line', function(line) {
+ assert.equal(line, expectedLines[callCount]);
+ callCount++;
+ });
+ fi.emit('data', expectedLines.join('\r\n'));
+ assert.equal(callCount, expectedLines.length - 1);
+ rli.close();
+
+ // \r\n should emit one line event when split across multiple writes.
+ fi = new FakeInput();
+ rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
+ expectedLines = ['foo', 'bar', 'baz', 'bat'];
+ callCount = 0;
+ rli.on('line', function(line) {
+ assert.equal(line, expectedLines[callCount]);
+ callCount++;
+ });
+ expectedLines.forEach(function(line) {
+ fi.emit('data', line + '\r');
+ fi.emit('data', '\n');
+ });
+ assert.equal(callCount, expectedLines.length);
+ rli.close();
+
+ // \r should behave like \n when alone
+ fi = new FakeInput();
+ rli = new readline.Interface({ input: fi, output: fi, terminal: true });
+ expectedLines = ['foo', 'bar', 'baz', 'bat'];
+ callCount = 0;
+ rli.on('line', function(line) {
+ assert.equal(line, expectedLines[callCount]);
+ callCount++;
+ });
+ fi.emit('data', expectedLines.join('\r'));
+ assert.equal(callCount, expectedLines.length - 1);
+ rli.close();
+
+
+ // sending a multi-byte utf8 char over multiple writes
+ var buf = Buffer('☮', 'utf8');
+ fi = new FakeInput();
+ rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
+ callCount = 0;
+ rli.on('line', function(line) {
+ callCount++;
+ assert.equal(line, buf.toString('utf8'));
+ });
+ [].forEach.call(buf, function(i) {
+ fi.emit('data', Buffer([i]));
+ });
+ assert.equal(callCount, 0);
+ fi.emit('data', '\n');
+ assert.equal(callCount, 1);
+ rli.close();
+
+ assert.deepEqual(fi.listeners('end'), []);
+ assert.deepEqual(fi.listeners(terminal ? 'keypress' : 'data'), []);
+});
diff --git a/test/simple/test-regress-GH-1531.js b/test/simple/test-regress-GH-1531.js
index 58086e087..60cd9498d 100644
--- a/test/simple/test-regress-GH-1531.js
+++ b/test/simple/test-regress-GH-1531.js
@@ -43,9 +43,10 @@ var server = https.createServer(options, function(req, res) {
server.listen(common.PORT, function() {
https.get({
+ agent: false,
path: '/',
port: common.PORT,
- agent: false
+ rejectUnauthorized: false
}, function(res) {
console.error(res.statusCode);
gotCallback = true;
diff --git a/test/simple/test-regress-GH-1697.js b/test/simple/test-regress-GH-1697.js
index 82aed3ec8..fdf2c42e9 100644
--- a/test/simple/test-regress-GH-1697.js
+++ b/test/simple/test-regress-GH-1697.js
@@ -37,7 +37,7 @@ if (process.argv[2] === 'server') {
});
});
- server.listen(1234, '127.0.0.1', function() {
+ server.listen(common.PORT, '127.0.0.1', function() {
console.log('Server running.');
});
@@ -49,7 +49,7 @@ if (process.argv[2] === 'server') {
serverProcess.stderr.pipe(process.stdout);
serverProcess.stdout.once('data', function() {
- var client = net.createConnection(1234, '127.0.0.1');
+ var client = net.createConnection(common.PORT, '127.0.0.1');
client.on('connect', function() {
var alot = new Buffer(1024),
alittle = new Buffer(1);
diff --git a/test/simple/test-regress-GH-877.js b/test/simple/test-regress-GH-877.js
index d431118fd..1cdca9f7d 100644
--- a/test/simple/test-regress-GH-877.js
+++ b/test/simple/test-regress-GH-877.js
@@ -48,6 +48,7 @@ server.listen(common.PORT, '127.0.0.1', function() {
if (++responses == N) {
server.close();
}
+ res.resume();
});
assert.equal(req.agent, agent);
diff --git a/test/simple/test-repl-autolibs.js b/test/simple/test-repl-autolibs.js
index 0f4ae8b38..b6f929471 100644
--- a/test/simple/test-repl-autolibs.js
+++ b/test/simple/test-repl-autolibs.js
@@ -48,8 +48,9 @@ function test1(){
putIn.write = function (data) {
gotWrite = true;
if (data.length) {
+
// inspect output matches repl output
- assert.equal(data, util.inspect(require('fs'), null, null, false) + '\n');
+ assert.equal(data, util.inspect(require('fs'), null, 2, false) + '\n');
// globally added lib matches required lib
assert.equal(global.fs, require('fs'));
test2();
@@ -66,7 +67,7 @@ function test2(){
gotWrite = true;
if (data.length) {
// repl response error message
- assert.equal(data.indexOf('A different'), 0);
+ assert.equal(data, '{}\n');
// original value wasn't overwritten
assert.equal(val, global.url);
}
diff --git a/test/simple/test-repl-console.js b/test/simple/test-repl-console.js
new file mode 100644
index 000000000..3dca14b7f
--- /dev/null
+++ b/test/simple/test-repl-console.js
@@ -0,0 +1,43 @@
+// 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'),
+ assert = require('assert'),
+ Stream = require('stream'),
+ repl = require('repl');
+
+// create a dummy stream that does nothing
+var stream = new Stream();
+stream.write = stream.pause = stream.resume = function(){};
+stream.readable = stream.writable = true;
+
+var r = repl.start({
+ input: stream,
+ output: stream,
+ useGlobal: false
+});
+
+
+// ensure that the repl context gets its own "console" instance
+assert(r.context.console);
+
+// ensure that the repl console instance is not the global one
+assert.notStrictEqual(r.context.console, console);
diff --git a/test/simple/test-repl-require-cache.js b/test/simple/test-repl-require-cache.js
new file mode 100644
index 000000000..ea2d6d6bd
--- /dev/null
+++ b/test/simple/test-repl-require-cache.js
@@ -0,0 +1,33 @@
+// 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'),
+ assert = require('assert'),
+ repl = require('repl');
+
+// https://github.com/joyent/node/issues/3226
+
+require.cache.something = 1;
+assert.equal(require.cache.something, 1);
+
+repl.start({ useGlobal: false }).rli.close();
+
+assert.equal(require.cache.something, 1);
diff --git a/test/simple/test-repl.js b/test/simple/test-repl.js
index aeca81c09..793346775 100644
--- a/test/simple/test-repl.js
+++ b/test/simple/test-repl.js
@@ -119,6 +119,12 @@ function error_test() {
// You can recover with the .break command
{ client: client_unix, send: '.break',
expect: prompt_unix },
+ // Floating point numbers are not interpreted as REPL commands.
+ { client: client_unix, send: '.1234',
+ expect: '0.1234' },
+ // Floating point expressions are not interpreted as REPL commands
+ { client: client_unix, send: '.1+.1',
+ expect: '0.2' },
// Can parse valid JSON
{ client: client_unix, send: 'JSON.parse(\'{"valid": "json"}\');',
expect: '{ valid: \'json\' }'},
@@ -166,7 +172,11 @@ function error_test() {
{ client: client_unix, send: '(function () {\n\nreturn 1;\n})()',
expect: '1' },
{ client: client_unix, send: '{\n\na: 1\n}',
- expect: '{ a: 1 }' }
+ expect: '{ a: 1 }' },
+ { client: client_unix, send: 'url.format("http://google.com")',
+ expect: 'http://google.com/' },
+ { client: client_unix, send: 'var path = 42; path',
+ expect: '42' }
]);
}
diff --git a/test/simple/test-script-context.js b/test/simple/test-script-context.js
index f29af2303..8095a713e 100644
--- a/test/simple/test-script-context.js
+++ b/test/simple/test-script-context.js
@@ -42,7 +42,6 @@ result = script.runInContext(context);
assert.equal(3, context.foo);
assert.equal('lala', context.thing);
-
// Issue GH-227:
Script.runInNewContext('', null, 'some.js');
@@ -69,3 +68,10 @@ function isTypeError(o) {
assert.throws(function() { script.runInContext(e); }, isTypeError);
assert.throws(function() { vm.runInContext('', e); }, isTypeError);
}));
+
+// Issue GH-693:
+common.debug('test RegExp as argument to assert.throws');
+script = vm.createScript('var assert = require(\'assert\'); assert.throws(' +
+ 'function() { throw "hello world"; }, /hello/);',
+ 'some.js');
+script.runInNewContext({ require : require });
diff --git a/test/simple/test-setproctitle.js b/test/simple/test-setproctitle.js
index 7ae138233..778e20012 100644
--- a/test/simple/test-setproctitle.js
+++ b/test/simple/test-setproctitle.js
@@ -22,7 +22,7 @@
// Original test written by Jakub Lekstan <kuebzky@gmail.com>
// FIXME add sunos support
-if ('linux freebsd'.indexOf(process.platform) === -1) {
+if ('linux freebsd darwin'.indexOf(process.platform) === -1) {
console.error('Skipping test, platform not supported.');
process.exit();
}
@@ -40,6 +40,10 @@ assert.equal(process.title, title);
exec('ps -p ' + process.pid + ' -o args=', function(error, stdout, stderr) {
assert.equal(error, null);
assert.equal(stderr, '');
+
+ // freebsd always add ' (procname)' to the process title
+ if (process.platform === 'freebsd') title += ' (node)';
+
// omitting trailing whitespace and \n
assert.equal(stdout.replace(/\s+$/, ''), title);
});
diff --git a/test/simple/test-stdio-readable-writable.js b/test/simple/test-stdio-readable-writable.js
new file mode 100644
index 000000000..5123f9688
--- /dev/null
+++ b/test/simple/test-stdio-readable-writable.js
@@ -0,0 +1,32 @@
+// 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');
+var assert = require('assert');
+
+assert(process.stdout.writable);
+assert(!process.stdout.readable);
+
+assert(process.stderr.writable);
+assert(!process.stderr.readable);
+
+assert(!process.stdin.writable);
+assert(process.stdin.readable);
diff --git a/test/simple/test-stdout-cannot-be-closed-child-process-pipe.js b/test/simple/test-stdout-cannot-be-closed-child-process-pipe.js
new file mode 100644
index 000000000..2e79c5af1
--- /dev/null
+++ b/test/simple/test-stdout-cannot-be-closed-child-process-pipe.js
@@ -0,0 +1,52 @@
+// 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');
+var assert = require('assert');
+
+if (process.argv[2] === 'child')
+ process.stdout.end('foo');
+else
+ parent();
+
+function parent() {
+ var spawn = require('child_process').spawn;
+ var child = spawn(process.execPath, [__filename, 'child']);
+ var out = '';
+ var err = '';
+
+ child.stdout.setEncoding('utf8');
+ child.stderr.setEncoding('utf8');
+
+ child.stdout.on('data', function(c) {
+ out += c;
+ });
+ child.stderr.on('data', function(c) {
+ err += c;
+ });
+
+ child.on('close', function(code, signal) {
+ assert(code);
+ assert.equal(out, 'foo');
+ assert(/process\.stdout cannot be closed/.test(err));
+ console.log('ok');
+ });
+}
diff --git a/test/simple/test-stdout-stderr-reading.js b/test/simple/test-stdout-stderr-reading.js
new file mode 100644
index 000000000..5b67a0d06
--- /dev/null
+++ b/test/simple/test-stdout-stderr-reading.js
@@ -0,0 +1,94 @@
+// 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');
+var assert = require('assert');
+
+// verify that stdout is never read from.
+var net = require('net');
+var read = net.Socket.prototype.read;
+
+net.Socket.prototype.read = function() {
+ if (this.fd === 1)
+ throw new Error('reading from stdout!');
+ if (this.fd === 2)
+ throw new Error('reading from stderr!');
+ return read.apply(this, arguments);
+};
+
+if (process.argv[2] === 'child')
+ child();
+else
+ parent();
+
+function parent() {
+ var spawn = require('child_process').spawn;
+ var node = process.execPath;
+ var closes = 0;
+
+ var c1 = spawn(node, [__filename, 'child']);
+ var c1out = '';
+ c1.stdout.setEncoding('utf8');
+ c1.stdout.on('data', function(chunk) {
+ c1out += chunk;
+ });
+ c1.stderr.setEncoding('utf8');
+ c1.stderr.on('data', function(chunk) {
+ console.error('c1err: ' + chunk.split('\n').join('\nc1err: '));
+ });
+ c1.on('close', function(code, signal) {
+ closes++;
+ assert(!code);
+ assert(!signal);
+ assert.equal(c1out, 'ok\n');
+ console.log('ok');
+ });
+
+ var c2 = spawn(node, ['-e', 'console.log("ok")']);
+ var c2out = '';
+ c2.stdout.setEncoding('utf8');
+ c2.stdout.on('data', function(chunk) {
+ c2out += chunk;
+ });
+ c1.stderr.setEncoding('utf8');
+ c1.stderr.on('data', function(chunk) {
+ console.error('c1err: ' + chunk.split('\n').join('\nc1err: '));
+ });
+ c2.on('close', function(code, signal) {
+ closes++;
+ assert(!code);
+ assert(!signal);
+ assert.equal(c2out, 'ok\n');
+ console.log('ok');
+ });
+
+ process.on('exit', function() {
+ assert.equal(closes, 2, 'saw both closes');
+ });
+}
+
+function child() {
+ // should not be reading *ever* in here.
+ net.Socket.prototype.read = function() {
+ throw new Error('no reading allowed in child');
+ };
+ console.log('ok');
+}
diff --git a/test/simple/test-stdout-to-file.js b/test/simple/test-stdout-to-file.js
index 83ea4f03f..94181ef81 100644
--- a/test/simple/test-stdout-to-file.js
+++ b/test/simple/test-stdout-to-file.js
@@ -30,7 +30,7 @@ var fs = require('fs');
var scriptString = path.join(common.fixturesDir, 'print-chars.js');
var scriptBuffer = path.join(common.fixturesDir, 'print-chars-from-buffer.js');
-var tmpFile = path.join(common.fixturesDir, 'stdout.txt');
+var tmpFile = path.join(common.tmpDir, 'stdout.txt');
function test(size, useBuffer, cb) {
var cmd = '"' + process.argv[0] + '"' +
diff --git a/test/simple/test-stream-big-push.js b/test/simple/test-stream-big-push.js
new file mode 100644
index 000000000..f54bcc30d
--- /dev/null
+++ b/test/simple/test-stream-big-push.js
@@ -0,0 +1,84 @@
+// 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');
+var assert = require('assert');
+var stream = require('stream');
+var str = 'asdfasdfasdfasdfasdf';
+
+var r = new stream.Readable({
+ highWaterMark: 5,
+ encoding: 'utf8'
+});
+
+var reads = 0;
+var eofed = false;
+var ended = false;
+
+r._read = function(n, cb) {
+ if (reads === 0) {
+ setTimeout(function() {
+ cb(null, str);
+ });
+ reads++;
+ } else if (reads === 1) {
+ var ret = r.push(str);
+ assert.equal(ret, false);
+ reads++;
+ } else {
+ assert(!eofed);
+ eofed = true;
+ cb(null, null);
+ }
+};
+
+r.on('end', function() {
+ ended = true;
+});
+
+// push some data in to start.
+// we've never gotten any read event at this point.
+var ret = r.push(str);
+// should be false. > hwm
+assert(!ret);
+var chunk = r.read();
+assert.equal(chunk, str);
+chunk = r.read();
+assert.equal(chunk, null);
+
+r.once('readable', function() {
+ // this time, we'll get *all* the remaining data, because
+ // it's been added synchronously, as the read WOULD take
+ // us below the hwm, and so it triggered a _read() again,
+ // which synchronously added more, which we then return.
+ chunk = r.read();
+ assert.equal(chunk, str + str);
+
+ chunk = r.read();
+ assert.equal(chunk, null);
+});
+
+process.on('exit', function() {
+ assert(eofed);
+ assert(ended);
+ assert.equal(reads, 2);
+ console.log('ok');
+});
diff --git a/test/simple/test-stream-pipe-cleanup.js b/test/simple/test-stream-pipe-cleanup.js
index 5a72a48fb..f68935852 100644
--- a/test/simple/test-stream-pipe-cleanup.js
+++ b/test/simple/test-stream-pipe-cleanup.js
@@ -47,15 +47,17 @@ function Readable() {
}
util.inherits(Readable, stream.Stream);
+function Duplex() {
+ this.readable = true;
+ Writable.call(this);
+}
+util.inherits(Duplex, Writable);
+
var i = 0;
var limit = 100;
var w = new Writable();
-console.error = function(text) {
- throw new Error(text);
-};
-
var r;
for (i = 0; i < limit; i++) {
@@ -83,14 +85,38 @@ r = new Readable();
for (i = 0; i < limit; i++) {
w = new Writable();
r.pipe(w);
- w.emit('end');
-}
-assert.equal(0, w.listeners('end').length);
-
-for (i = 0; i < limit; i++) {
- w = new Writable();
- r.pipe(w);
w.emit('close');
}
assert.equal(0, w.listeners('close').length);
+r = new Readable();
+w = new Writable();
+var d = new Duplex();
+r.pipe(d); // pipeline A
+d.pipe(w); // pipeline B
+assert.equal(r.listeners('end').length, 2); // A.onend, A.cleanup
+assert.equal(r.listeners('close').length, 2); // A.onclose, A.cleanup
+assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup
+assert.equal(d.listeners('close').length, 3); // A.cleanup, B.onclose, B.cleanup
+assert.equal(w.listeners('end').length, 0);
+assert.equal(w.listeners('close').length, 1); // B.cleanup
+
+r.emit('end');
+assert.equal(d.endCalls, 1);
+assert.equal(w.endCalls, 0);
+assert.equal(r.listeners('end').length, 0);
+assert.equal(r.listeners('close').length, 0);
+assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup
+assert.equal(d.listeners('close').length, 2); // B.onclose, B.cleanup
+assert.equal(w.listeners('end').length, 0);
+assert.equal(w.listeners('close').length, 1); // B.cleanup
+
+d.emit('end');
+assert.equal(d.endCalls, 1);
+assert.equal(w.endCalls, 1);
+assert.equal(r.listeners('end').length, 0);
+assert.equal(r.listeners('close').length, 0);
+assert.equal(d.listeners('end').length, 0);
+assert.equal(d.listeners('close').length, 0);
+assert.equal(w.listeners('end').length, 0);
+assert.equal(w.listeners('close').length, 0);
diff --git a/test/simple/test-stream-push-order.js b/test/simple/test-stream-push-order.js
new file mode 100644
index 000000000..900a8c778
--- /dev/null
+++ b/test/simple/test-stream-push-order.js
@@ -0,0 +1,51 @@
+// 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 Readable = require('stream').Readable;
+var assert = require('assert');
+
+var s = new Readable({
+ highWaterMark: 20,
+ encoding: 'ascii'
+});
+
+var list = ['1', '2', '3', '4', '5', '6'];
+
+s._read = function (n, cb) {
+ var one = list.shift();
+ if (!one)
+ return cb(null, null);
+
+ var two = list.shift();
+ s.push(one);
+ cb(null, two);
+};
+
+var v = s.read(0);
+
+// ACTUALLY [1, 3, 5, 6, 4, 2]
+
+process.on("exit", function () {
+ assert.deepEqual(s._readableState.buffer,
+ ['1', '2', '3', '4', '5', '6']);
+ console.log("ok");
+});
diff --git a/test/simple/test-stream2-basic.js b/test/simple/test-stream2-basic.js
new file mode 100644
index 000000000..c24ec243f
--- /dev/null
+++ b/test/simple/test-stream2-basic.js
@@ -0,0 +1,452 @@
+// 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 R = require('_stream_readable');
+var assert = require('assert');
+
+var util = require('util');
+var EE = require('events').EventEmitter;
+
+function TestReader(n) {
+ R.apply(this);
+ this._buffer = new Buffer(n || 100);
+ this._buffer.fill('x');
+ this._pos = 0;
+ this._bufs = 10;
+}
+
+util.inherits(TestReader, R);
+
+TestReader.prototype.read = function(n) {
+ var max = this._buffer.length - this._pos;
+ n = n || max;
+ n = Math.max(n, 0);
+ var toRead = Math.min(n, max);
+ if (toRead === 0) {
+ // simulate the read buffer filling up with some more bytes some time
+ // in the future.
+ setTimeout(function() {
+ this._pos = 0;
+ this._bufs -= 1;
+ if (this._bufs <= 0) {
+ // read them all!
+ if (!this.ended) {
+ this.emit('end');
+ this.ended = true;
+ }
+ } else {
+ this.emit('readable');
+ }
+ }.bind(this), 10);
+ return null;
+ }
+
+ var ret = this._buffer.slice(this._pos, this._pos + toRead);
+ this._pos += toRead;
+ return ret;
+};
+
+/////
+
+function TestWriter() {
+ EE.apply(this);
+ this.received = [];
+ this.flush = false;
+}
+
+util.inherits(TestWriter, EE);
+
+TestWriter.prototype.write = function(c) {
+ this.received.push(c.toString());
+ this.emit('write', c);
+ return true;
+
+ // flip back and forth between immediate acceptance and not.
+ this.flush = !this.flush;
+ if (!this.flush) setTimeout(this.emit.bind(this, 'drain'), 10);
+ return this.flush;
+};
+
+TestWriter.prototype.end = function(c) {
+ if (c) this.write(c);
+ this.emit('end', this.received);
+};
+
+////////
+
+// tiny node-tap lookalike.
+var tests = [];
+var count = 0;
+
+function test(name, fn) {
+ count++;
+ tests.push([name, fn]);
+}
+
+function run() {
+ var next = tests.shift();
+ if (!next)
+ return console.error('ok');
+
+ var name = next[0];
+ var fn = next[1];
+ console.log('# %s', name);
+ fn({
+ same: assert.deepEqual,
+ equal: assert.equal,
+ end: function () {
+ count--;
+ run();
+ }
+ });
+}
+
+// ensure all tests have run
+process.on("exit", function () {
+ assert.equal(count, 0);
+});
+
+process.nextTick(run);
+
+
+test('a most basic test', function(t) {
+ var r = new TestReader(20);
+
+ var reads = [];
+ var expect = [ 'x',
+ 'xx',
+ 'xxx',
+ 'xxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxxxxx',
+ 'xxxxxxxxx',
+ 'xxx',
+ 'xxxxxxxxxxxx',
+ 'xxxxxxxx',
+ 'xxxxxxxxxxxxxxx',
+ 'xxxxx',
+ 'xxxxxxxxxxxxxxxxxx',
+ 'xx',
+ 'xxxxxxxxxxxxxxxxxxxx',
+ 'xxxxxxxxxxxxxxxxxxxx',
+ 'xxxxxxxxxxxxxxxxxxxx',
+ 'xxxxxxxxxxxxxxxxxxxx',
+ 'xxxxxxxxxxxxxxxxxxxx' ];
+
+ r.on('end', function() {
+ t.same(reads, expect);
+ t.end();
+ });
+
+ var readSize = 1;
+ function flow() {
+ var res;
+ while (null !== (res = r.read(readSize++))) {
+ reads.push(res.toString());
+ }
+ r.once('readable', flow);
+ }
+
+ flow();
+});
+
+test('pipe', function(t) {
+ var r = new TestReader(5);
+
+ var expect = [ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx' ]
+
+ var w = new TestWriter;
+ var flush = true;
+ w.on('end', function(received) {
+ t.same(received, expect);
+ t.end();
+ });
+
+ r.pipe(w);
+});
+
+
+
+[1,2,3,4,5,6,7,8,9].forEach(function(SPLIT) {
+ test('unpipe', function(t) {
+ var r = new TestReader(5);
+
+ // unpipe after 3 writes, then write to another stream instead.
+ var expect = [ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx' ];
+ expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ];
+
+ var w = [ new TestWriter(), new TestWriter() ];
+
+ var writes = SPLIT;
+ w[0].on('write', function() {
+ if (--writes === 0) {
+ r.unpipe();
+ t.equal(r._readableState.pipes, null);
+ w[0].end();
+ r.pipe(w[1]);
+ t.equal(r._readableState.pipes, w[1]);
+ }
+ });
+
+ var ended = 0;
+
+ var ended0 = false;
+ var ended1 = false;
+ w[0].on('end', function(results) {
+ t.equal(ended0, false);
+ ended0 = true;
+ ended++;
+ t.same(results, expect[0]);
+ });
+
+ w[1].on('end', function(results) {
+ t.equal(ended1, false);
+ ended1 = true;
+ ended++;
+ t.equal(ended, 2);
+ t.same(results, expect[1]);
+ t.end();
+ });
+
+ r.pipe(w[0]);
+ });
+});
+
+
+// both writers should get the same exact data.
+test('multipipe', function(t) {
+ var r = new TestReader(5);
+ var w = [ new TestWriter, new TestWriter ];
+
+ var expect = [ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx' ];
+
+ var c = 2;
+ w[0].on('end', function(received) {
+ t.same(received, expect, 'first');
+ if (--c === 0) t.end();
+ });
+ w[1].on('end', function(received) {
+ t.same(received, expect, 'second');
+ if (--c === 0) t.end();
+ });
+
+ r.pipe(w[0]);
+ r.pipe(w[1]);
+});
+
+
+[1,2,3,4,5,6,7,8,9].forEach(function(SPLIT) {
+ test('multi-unpipe', function(t) {
+ var r = new TestReader(5);
+
+ // unpipe after 3 writes, then write to another stream instead.
+ var expect = [ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx',
+ 'xxxxx' ];
+ expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ];
+
+ var w = [ new TestWriter(), new TestWriter(), new TestWriter() ];
+
+ var writes = SPLIT;
+ w[0].on('write', function() {
+ if (--writes === 0) {
+ r.unpipe();
+ w[0].end();
+ r.pipe(w[1]);
+ }
+ });
+
+ var ended = 0;
+
+ w[0].on('end', function(results) {
+ ended++;
+ t.same(results, expect[0]);
+ });
+
+ w[1].on('end', function(results) {
+ ended++;
+ t.equal(ended, 2);
+ t.same(results, expect[1]);
+ t.end();
+ });
+
+ r.pipe(w[0]);
+ r.pipe(w[2]);
+ });
+});
+
+test('back pressure respected', function (t) {
+ function noop() {}
+
+ var r = new R({ objectMode: true });
+ r._read = noop;
+ var counter = 0;
+ r.push(["one"]);
+ r.push(["two"]);
+ r.push(["three"]);
+ r.push(["four"]);
+ r.push(null);
+
+ var w1 = new R();
+ w1.write = function (chunk) {
+ assert.equal(chunk[0], "one");
+ w1.emit("close");
+ process.nextTick(function () {
+ r.pipe(w2);
+ r.pipe(w3);
+ })
+ };
+ w1.end = noop;
+
+ r.pipe(w1);
+
+ var expected = ["two", "two", "three", "three", "four", "four"];
+
+ var w2 = new R();
+ w2.write = function (chunk) {
+ assert.equal(chunk[0], expected.shift());
+ assert.equal(counter, 0);
+
+ counter++;
+
+ if (chunk[0] === "four") {
+ return true;
+ }
+
+ setTimeout(function () {
+ counter--;
+ w2.emit("drain");
+ }, 10);
+
+ return false;
+ }
+ w2.end = noop;
+
+ var w3 = new R();
+ w3.write = function (chunk) {
+ assert.equal(chunk[0], expected.shift());
+ assert.equal(counter, 1);
+
+ counter++;
+
+ if (chunk[0] === "four") {
+ return true;
+ }
+
+ setTimeout(function () {
+ counter--;
+ w3.emit("drain");
+ }, 50);
+
+ return false;
+ };
+ w3.end = function () {
+ assert.equal(counter, 2);
+ assert.equal(expected.length, 0);
+ t.end();
+ };
+});
+
+test('read(0) for ended streams', function (t) {
+ var r = new R();
+ var written = false;
+ var ended = false;
+ r._read = function () {};
+
+ r.push(new Buffer("foo"));
+ r.push(null);
+
+ var v = r.read(0);
+
+ assert.equal(v, null);
+
+ var w = new R();
+
+ w.write = function (buffer) {
+ written = true;
+ assert.equal(ended, false);
+ assert.equal(buffer.toString(), "foo")
+ };
+
+ w.end = function () {
+ ended = true;
+ assert.equal(written, true);
+ t.end();
+ };
+
+ r.pipe(w);
+})
+
+test('sync _read ending', function (t) {
+ var r = new R();
+ var called = false;
+ r._read = function (n, cb) {
+ cb(null, null);
+ };
+
+ r.once('end', function () {
+ called = true;
+ })
+
+ r.read();
+
+ process.nextTick(function () {
+ assert.equal(called, true);
+ t.end();
+ })
+});
diff --git a/test/simple/test-stream2-compatibility.js b/test/simple/test-stream2-compatibility.js
new file mode 100644
index 000000000..cb07278d5
--- /dev/null
+++ b/test/simple/test-stream2-compatibility.js
@@ -0,0 +1,50 @@
+// 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 R = require('_stream_readable');
+var assert = require('assert');
+
+var util = require('util');
+var EE = require('events').EventEmitter;
+
+var ondataCalled = 0;
+
+function TestReader() {
+ R.apply(this);
+ this._buffer = new Buffer(100);
+ this._buffer.fill('x');
+
+ this.on('data', function() {
+ ondataCalled++;
+ });
+}
+
+util.inherits(TestReader, R);
+
+TestReader.prototype._read = function(n, cb) {
+ cb(null, this._buffer);
+ this._buffer = new Buffer(0);
+};
+
+var reader = new TestReader();
+assert.equal(ondataCalled, 1);
diff --git a/test/simple/test-stream2-finish-pipe.js b/test/simple/test-stream2-finish-pipe.js
new file mode 100644
index 000000000..686af2449
--- /dev/null
+++ b/test/simple/test-stream2-finish-pipe.js
@@ -0,0 +1,41 @@
+// 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 stream = require('stream');
+var Buffer = require('buffer').Buffer;
+
+var R = new stream.Readable();
+R._read = function(size, cb) {
+ cb(null, new Buffer(size));
+};
+
+var W = new stream.Writable();
+W._write = function(data, cb) {
+ cb(null);
+};
+
+R.pipe(W);
+
+// This might sound unrealistic, but it happens in net.js. When
+// `socket.allowHalfOpen === false`, EOF will cause `.destroySoon()` call which
+// ends the writable side of net.Socket.
+W.end();
diff --git a/test/simple/test-stream2-fs.js b/test/simple/test-stream2-fs.js
new file mode 100644
index 000000000..70cd8ba4d
--- /dev/null
+++ b/test/simple/test-stream2-fs.js
@@ -0,0 +1,76 @@
+// 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 R = require('_stream_readable');
+var assert = require('assert');
+
+var fs = require('fs');
+var FSReadable = fs.ReadStream;
+
+var path = require('path');
+var file = path.resolve(common.fixturesDir, 'x1024.txt');
+
+var size = fs.statSync(file).size;
+
+// expect to see chunks no more than 10 bytes each.
+var expectLengths = [];
+for (var i = size; i > 0; i -= 10) {
+ expectLengths.push(Math.min(i, 10));
+}
+
+var util = require('util');
+var Stream = require('stream');
+
+util.inherits(TestWriter, Stream);
+
+function TestWriter() {
+ Stream.apply(this);
+ this.buffer = [];
+ this.length = 0;
+}
+
+TestWriter.prototype.write = function(c) {
+ this.buffer.push(c.toString());
+ this.length += c.length;
+ return true;
+};
+
+TestWriter.prototype.end = function(c) {
+ if (c) this.buffer.push(c.toString());
+ this.emit('results', this.buffer);
+}
+
+var r = new FSReadable(file, { bufferSize: 10 });
+var w = new TestWriter();
+
+w.on('results', function(res) {
+ console.error(res, w.length);
+ assert.equal(w.length, size);
+ var l = 0;
+ assert.deepEqual(res.map(function (c) {
+ return c.length;
+ }), expectLengths);
+ console.log('ok');
+});
+
+r.pipe(w, { chunkSize: 10 });
diff --git a/test/simple/test-stream2-httpclient-response-end.js b/test/simple/test-stream2-httpclient-response-end.js
new file mode 100644
index 000000000..15cffc2ac
--- /dev/null
+++ b/test/simple/test-stream2-httpclient-response-end.js
@@ -0,0 +1,52 @@
+// 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 assert = require('assert');
+var http = require('http');
+var msg = 'Hello';
+var readable_event = false;
+var end_event = false;
+var server = http.createServer(function(req, res) {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+ res.end(msg);
+}).listen(common.PORT, function() {
+ http.get({port: common.PORT}, function(res) {
+ var data = '';
+ res.on('readable', function() {
+ console.log('readable event');
+ readable_event = true;
+ data += res.read();
+ });
+ res.on('end', function() {
+ console.log('end event');
+ end_event = true;
+ assert.strictEqual(msg, data);
+ server.close();
+ });
+ });
+});
+
+process.on('exit', function() {
+ assert(readable_event);
+ assert(end_event);
+});
+
diff --git a/test/simple/test-stream2-large-read-stall.js b/test/simple/test-stream2-large-read-stall.js
new file mode 100644
index 000000000..2fbfbcab3
--- /dev/null
+++ b/test/simple/test-stream2-large-read-stall.js
@@ -0,0 +1,82 @@
+// 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 assert = require('assert');
+
+// If everything aligns so that you do a read(n) of exactly the
+// remaining buffer, then make sure that 'end' still emits.
+
+var READSIZE = 100;
+var PUSHSIZE = 20;
+var PUSHCOUNT = 1000;
+var HWM = 50;
+
+var Readable = require('stream').Readable;
+var r = new Readable({
+ highWaterMark: HWM
+});
+var rs = r._readableState;
+
+r._read = push;
+
+r.on('readable', function() {
+ console.error('>> readable');
+ do {
+ console.error(' > read(%d)', READSIZE);
+ var ret = r.read(READSIZE);
+ console.error(' < %j (%d remain)', ret && ret.length, rs.length);
+ } while (ret && ret.length === READSIZE);
+
+ console.error('<< after read()',
+ ret && ret.length,
+ rs.needReadable,
+ rs.length);
+});
+
+var endEmitted = false;
+r.on('end', function() {
+ endEmitted = true;
+ console.error('end');
+});
+
+var pushes = 0;
+function push() {
+ if (pushes > PUSHCOUNT)
+ return;
+
+ if (pushes++ === PUSHCOUNT) {
+ console.error(' push(EOF)');
+ return r.push(null);
+ }
+
+ console.error(' push #%d', pushes);
+ if (r.push(new Buffer(PUSHSIZE)))
+ setTimeout(push);
+}
+
+// start the flow
+var ret = r.read(0);
+
+process.on('exit', function() {
+ assert.equal(pushes, PUSHCOUNT + 1);
+ assert(endEmitted);
+});
diff --git a/test/simple/test-stream2-objects.js b/test/simple/test-stream2-objects.js
new file mode 100644
index 000000000..7ff30c850
--- /dev/null
+++ b/test/simple/test-stream2-objects.js
@@ -0,0 +1,348 @@
+// 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 Readable = require('_stream_readable');
+var Writable = require('_stream_writable');
+var assert = require('assert');
+
+// tiny node-tap lookalike.
+var tests = [];
+var count = 0;
+
+function test(name, fn) {
+ count++;
+ tests.push([name, fn]);
+}
+
+function run() {
+ var next = tests.shift();
+ if (!next)
+ return console.error('ok');
+
+ var name = next[0];
+ var fn = next[1];
+ console.log('# %s', name);
+ fn({
+ same: assert.deepEqual,
+ equal: assert.equal,
+ end: function() {
+ count--;
+ run();
+ }
+ });
+}
+
+// ensure all tests have run
+process.on('exit', function() {
+ assert.equal(count, 0);
+});
+
+process.nextTick(run);
+
+function toArray(callback) {
+ var stream = new Writable({ objectMode: true });
+ var list = [];
+ stream.write = function(chunk) {
+ list.push(chunk);
+ };
+
+ stream.end = function() {
+ callback(list);
+ };
+
+ return stream;
+}
+
+function fromArray(list) {
+ var r = new Readable({ objectMode: true });
+ r._read = noop;
+ list.forEach(function(chunk) {
+ r.push(chunk);
+ });
+ r.push(null);
+
+ return r;
+}
+
+function noop() {}
+
+test('can read objects from stream', function(t) {
+ var r = fromArray([{ one: '1'}, { two: '2' }]);
+
+ var v1 = r.read();
+ var v2 = r.read();
+ var v3 = r.read();
+
+ assert.deepEqual(v1, { one: '1' });
+ assert.deepEqual(v2, { two: '2' });
+ assert.deepEqual(v3, null);
+
+ t.end();
+});
+
+test('can pipe objects into stream', function(t) {
+ var r = fromArray([{ one: '1'}, { two: '2' }]);
+
+ r.pipe(toArray(function(list) {
+ assert.deepEqual(list, [
+ { one: '1' },
+ { two: '2' }
+ ]);
+
+ t.end();
+ }));
+});
+
+test('read(n) is ignored', function(t) {
+ var r = fromArray([{ one: '1'}, { two: '2' }]);
+
+ var value = r.read(2);
+
+ assert.deepEqual(value, { one: '1' });
+
+ t.end();
+});
+
+test('can read objects from _read (sync)', function(t) {
+ var r = new Readable({ objectMode: true });
+ var list = [{ one: '1'}, { two: '2' }];
+ r._read = function(n, cb) {
+ var item = list.shift();
+ cb(null, item || null);
+ };
+
+ r.pipe(toArray(function(list) {
+ assert.deepEqual(list, [
+ { one: '1' },
+ { two: '2' }
+ ]);
+
+ t.end();
+ }));
+});
+
+test('can read objects from _read (async)', function(t) {
+ var r = new Readable({ objectMode: true });
+ var list = [{ one: '1'}, { two: '2' }];
+ r._read = function(n, cb) {
+ var item = list.shift();
+ process.nextTick(function() {
+ cb(null, item || null);
+ });
+ };
+
+ r.pipe(toArray(function(list) {
+ assert.deepEqual(list, [
+ { one: '1' },
+ { two: '2' }
+ ]);
+
+ t.end();
+ }));
+});
+
+test('can read strings as objects', function(t) {
+ var r = new Readable({
+ objectMode: true
+ });
+ r._read = noop;
+ var list = ['one', 'two', 'three'];
+ list.forEach(function(str) {
+ r.push(str);
+ });
+ r.push(null);
+
+ r.pipe(toArray(function(array) {
+ assert.deepEqual(array, list);
+
+ t.end();
+ }));
+});
+
+test('read(0) for object streams', function(t) {
+ var r = new Readable({
+ objectMode: true
+ });
+ r._read = noop;
+
+ r.push('foobar');
+ r.push(null);
+
+ var v = r.read(0);
+
+ r.pipe(toArray(function(array) {
+ assert.deepEqual(array, ['foobar']);
+
+ t.end();
+ }));
+});
+
+test('falsey values', function(t) {
+ var r = new Readable({
+ objectMode: true
+ });
+ r._read = noop;
+
+ r.push(false);
+ r.push(0);
+ r.push('');
+ r.push(null);
+
+ r.pipe(toArray(function(array) {
+ assert.deepEqual(array, [false, 0, '']);
+
+ t.end();
+ }));
+});
+
+test('high watermark _read', function(t) {
+ var r = new Readable({
+ highWaterMark: 6,
+ objectMode: true
+ });
+ var calls = 0;
+ var list = ['1', '2', '3', '4', '5', '6', '7', '8'];
+
+ r._read = function() {
+ calls++;
+ };
+
+ list.forEach(function(c) {
+ r.push(c);
+ });
+
+ var v = r.read();
+
+ assert.equal(calls, 0);
+ assert.equal(v, '1');
+
+ var v2 = r.read();
+
+ assert.equal(calls, 1);
+ assert.equal(v2, '2');
+
+ t.end();
+});
+
+test('high watermark push', function(t) {
+ var r = new Readable({
+ highWaterMark: 6,
+ objectMode: true
+ });
+ r._read = function() {};
+ for (var i = 0; i < 6; i++) {
+ var bool = r.push(i);
+ assert.equal(bool, i === 5 ? false : true);
+ }
+
+ t.end();
+});
+
+test('can write objects to stream', function(t) {
+ var w = new Writable({ objectMode: true });
+
+ w._write = function(chunk, cb) {
+ assert.deepEqual(chunk, { foo: 'bar' });
+ cb();
+ };
+
+ w.on('finish', function() {
+ t.end();
+ });
+
+ w.write({ foo: 'bar' });
+ w.end();
+});
+
+test('can write multiple objects to stream', function(t) {
+ var w = new Writable({ objectMode: true });
+ var list = [];
+
+ w._write = function(chunk, cb) {
+ list.push(chunk);
+ cb();
+ };
+
+ w.on('finish', function() {
+ assert.deepEqual(list, [0, 1, 2, 3, 4]);
+
+ t.end();
+ });
+
+ w.write(0);
+ w.write(1);
+ w.write(2);
+ w.write(3);
+ w.write(4);
+ w.end();
+});
+
+test('can write strings as objects', function(t) {
+ var w = new Writable({
+ objectMode: true
+ });
+ var list = [];
+
+ w._write = function(chunk, cb) {
+ list.push(chunk);
+ process.nextTick(cb);
+ };
+
+ w.on('finish', function() {
+ assert.deepEqual(list, ['0', '1', '2', '3', '4']);
+
+ t.end();
+ });
+
+ w.write('0');
+ w.write('1');
+ w.write('2');
+ w.write('3');
+ w.write('4');
+ w.end();
+});
+
+test('buffers finish until cb is called', function(t) {
+ var w = new Writable({
+ objectMode: true
+ });
+ var called = false;
+
+ w._write = function(chunk, cb) {
+ assert.equal(chunk, 'foo');
+
+ process.nextTick(function() {
+ called = true;
+ cb();
+ });
+ };
+
+ w.on('finish', function() {
+ assert.equal(called, true);
+
+ t.end();
+ });
+
+ w.write('foo');
+ w.end();
+});
diff --git a/test/simple/test-stream2-pipe-error-handling.js b/test/simple/test-stream2-pipe-error-handling.js
new file mode 100644
index 000000000..c17139f5d
--- /dev/null
+++ b/test/simple/test-stream2-pipe-error-handling.js
@@ -0,0 +1,105 @@
+// 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');
+var assert = require('assert');
+var stream = require('stream');
+
+(function testErrorListenerCatches() {
+ var count = 1000;
+
+ var source = new stream.Readable();
+ source._read = function(n, cb) {
+ n = Math.min(count, n);
+ count -= n;
+ cb(null, new Buffer(n));
+ };
+
+ var unpipedDest;
+ source.unpipe = function(dest) {
+ unpipedDest = dest;
+ stream.Readable.prototype.unpipe.call(this, dest);
+ };
+
+ var dest = new stream.Writable();
+ dest._write = function(chunk, cb) {
+ cb();
+ };
+
+ source.pipe(dest);
+
+ var gotErr = null;
+ dest.on('error', function(err) {
+ gotErr = err;
+ });
+
+ var unpipedSource;
+ dest.on('unpipe', function(src) {
+ unpipedSource = src;
+ });
+
+ var err = new Error('This stream turned into bacon.');
+ dest.emit('error', err);
+ assert.strictEqual(gotErr, err);
+ assert.strictEqual(unpipedSource, source);
+ assert.strictEqual(unpipedDest, dest);
+})();
+
+(function testErrorWithoutListenerThrows() {
+ var count = 1000;
+
+ var source = new stream.Readable();
+ source._read = function(n, cb) {
+ n = Math.min(count, n);
+ count -= n;
+ cb(null, new Buffer(n));
+ };
+
+ var unpipedDest;
+ source.unpipe = function(dest) {
+ unpipedDest = dest;
+ stream.Readable.prototype.unpipe.call(this, dest);
+ };
+
+ var dest = new stream.Writable();
+ dest._write = function(chunk, cb) {
+ cb();
+ };
+
+ source.pipe(dest);
+
+ var unpipedSource;
+ dest.on('unpipe', function(src) {
+ unpipedSource = src;
+ });
+
+ var err = new Error('This stream turned into bacon.');
+
+ var gotErr = null;
+ try {
+ dest.emit('error', err);
+ } catch (e) {
+ gotErr = e;
+ }
+ assert.strictEqual(gotErr, err);
+ assert.strictEqual(unpipedSource, source);
+ assert.strictEqual(unpipedDest, dest);
+})();
diff --git a/test/simple/test-stream2-push.js b/test/simple/test-stream2-push.js
new file mode 100644
index 000000000..29b438d32
--- /dev/null
+++ b/test/simple/test-stream2-push.js
@@ -0,0 +1,138 @@
+// 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 stream = require('stream');
+var Readable = stream.Readable;
+var Writable = stream.Writable;
+var assert = require('assert');
+
+var util = require('util');
+var EE = require('events').EventEmitter;
+
+
+// a mock thing a bit like the net.Socket/tcp_wrap.handle interaction
+
+var stream = new Readable({
+ highWaterMark: 16,
+ encoding: 'utf8'
+});
+
+var source = new EE;
+
+stream._read = function() {
+ console.error('stream._read');
+ readStart();
+};
+
+var ended = false;
+stream.on('end', function() {
+ ended = true;
+});
+
+source.on('data', function(chunk) {
+ var ret = stream.push(chunk);
+ console.error('data', stream._readableState.length);
+ if (!ret)
+ readStop();
+});
+
+source.on('end', function() {
+ stream.push(null);
+});
+
+var reading = false;
+
+function readStart() {
+ console.error('readStart');
+ reading = true;
+}
+
+function readStop() {
+ console.error('readStop');
+ reading = false;
+ process.nextTick(function() {
+ var r = stream.read();
+ if (r !== null)
+ writer.write(r);
+ });
+}
+
+var writer = new Writable({
+ decodeStrings: false
+});
+
+var written = [];
+
+var expectWritten =
+ [ 'asdfgasdfgasdfgasdfg',
+ 'asdfgasdfgasdfgasdfg',
+ 'asdfgasdfgasdfgasdfg',
+ 'asdfgasdfgasdfgasdfg',
+ 'asdfgasdfgasdfgasdfg',
+ 'asdfgasdfgasdfgasdfg' ];
+
+writer._write = function(chunk, cb) {
+ console.error('WRITE %s', chunk[0]);
+ written.push(chunk[0]);
+ process.nextTick(cb);
+};
+
+writer.on('finish', finish);
+
+
+// now emit some chunks.
+
+var chunk = "asdfg";
+
+var set = 0;
+readStart();
+data();
+function data() {
+ assert(reading);
+ source.emit('data', chunk);
+ assert(reading);
+ source.emit('data', chunk);
+ assert(reading);
+ source.emit('data', chunk);
+ assert(reading);
+ source.emit('data', chunk);
+ assert(!reading);
+ if (set++ < 5)
+ setTimeout(data, 10);
+ else
+ end();
+}
+
+function finish() {
+ console.error('finish');
+ assert.deepEqual(written, expectWritten);
+ console.log('ok');
+}
+
+function end() {
+ source.emit('end');
+ assert(!reading);
+ writer.end(stream.read());
+ setTimeout(function() {
+ assert(ended);
+ });
+}
diff --git a/test/simple/test-stream2-read-sync-stack.js b/test/simple/test-stream2-read-sync-stack.js
new file mode 100644
index 000000000..4e5ab1729
--- /dev/null
+++ b/test/simple/test-stream2-read-sync-stack.js
@@ -0,0 +1,54 @@
+// 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');
+var assert = require('assert');
+var Readable = require('stream').Readable;
+var r = new Readable();
+var N = 256 * 1024;
+
+// Go ahead and allow the pathological case for this test.
+// Yes, it's an infinite loop, that's the point.
+process.maxTickDepth = N + 2;
+
+var reads = 0;
+r._read = function(n, cb) {
+ var chunk = reads++ === N ? null : new Buffer(1);
+ cb(null, chunk);
+};
+
+r.on('readable', function onReadable() {
+ if (!(r._readableState.length % 256))
+ console.error('readable', r._readableState.length);
+ r.read(N * 2);
+});
+
+var ended = false;
+r.on('end', function onEnd() {
+ ended = true;
+});
+
+r.read(0);
+
+process.on('exit', function() {
+ assert(ended);
+ console.log('ok');
+});
diff --git a/test/simple/test-stream2-readable-empty-buffer-no-eof.js b/test/simple/test-stream2-readable-empty-buffer-no-eof.js
new file mode 100644
index 000000000..6cc7c73f0
--- /dev/null
+++ b/test/simple/test-stream2-readable-empty-buffer-no-eof.js
@@ -0,0 +1,118 @@
+// 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');
+var assert = require('assert');
+
+var Readable = require('stream').Readable;
+
+test1();
+test2();
+
+function test1() {
+ var r = new Readable();
+
+ // should not end when we get a Buffer(0) or '' as the _read result
+ // that just means that there is *temporarily* no data, but to go
+ // ahead and try again later.
+ //
+ // note that this is very unusual. it only works for crypto streams
+ // because the other side of the stream will call read(0) to cycle
+ // data through openssl. that's why we set the timeouts to call
+ // r.read(0) again later, otherwise there is no more work being done
+ // and the process just exits.
+
+ var buf = new Buffer(5);
+ buf.fill('x');
+ var reads = 5;
+ r._read = function(n, cb) {
+ switch (reads--) {
+ case 0:
+ return cb(null, null); // EOF
+ case 1:
+ return cb(null, buf);
+ case 2:
+ setTimeout(r.read.bind(r, 0), 10);
+ return cb(null, new Buffer(0)); // Not-EOF!
+ case 3:
+ setTimeout(r.read.bind(r, 0), 10);
+ return process.nextTick(function() {
+ return cb(null, new Buffer(0));
+ });
+ case 4:
+ setTimeout(r.read.bind(r, 0), 10);
+ return setTimeout(function() {
+ return cb(null, new Buffer(0));
+ });
+ case 5:
+ return setTimeout(function() {
+ return cb(null, buf);
+ });
+ default:
+ throw new Error('unreachable');
+ }
+ };
+
+ var results = [];
+ function flow() {
+ var chunk;
+ while (null !== (chunk = r.read()))
+ results.push(chunk + '');
+ }
+ r.on('readable', flow);
+ r.on('end', function() {
+ results.push('EOF');
+ });
+ flow();
+
+ process.on('exit', function() {
+ assert.deepEqual(results, [ 'xxxxx', 'xxxxx', 'EOF' ]);
+ console.log('ok');
+ });
+}
+
+function test2() {
+ var r = new Readable({ encoding: 'base64' });
+ var reads = 5;
+ r._read = function(n, cb) {
+ if (!reads--)
+ return cb(null, null); // EOF
+ else
+ return cb(null, new Buffer('x'));
+ };
+
+ var results = [];
+ function flow() {
+ var chunk;
+ while (null !== (chunk = r.read()))
+ results.push(chunk + '');
+ }
+ r.on('readable', flow);
+ r.on('end', function() {
+ results.push('EOF');
+ });
+ flow();
+
+ process.on('exit', function() {
+ assert.deepEqual(results, [ 'eHh4', 'eHg=', 'EOF' ]);
+ console.log('ok');
+ });
+}
diff --git a/test/simple/test-stream2-readable-from-list.js b/test/simple/test-stream2-readable-from-list.js
new file mode 100644
index 000000000..7c96ffe00
--- /dev/null
+++ b/test/simple/test-stream2-readable-from-list.js
@@ -0,0 +1,120 @@
+// 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 assert = require('assert');
+var common = require('../common.js');
+var fromList = require('_stream_readable')._fromList;
+
+// tiny node-tap lookalike.
+var tests = [];
+var count = 0;
+
+function test(name, fn) {
+ count++;
+ tests.push([name, fn]);
+}
+
+function run() {
+ var next = tests.shift();
+ if (!next)
+ return console.error('ok');
+
+ var name = next[0];
+ var fn = next[1];
+ console.log('# %s', name);
+ fn({
+ same: assert.deepEqual,
+ equal: assert.equal,
+ end: function () {
+ count--;
+ run();
+ }
+ });
+}
+
+// ensure all tests have run
+process.on("exit", function () {
+ assert.equal(count, 0);
+});
+
+process.nextTick(run);
+
+
+
+test('buffers', function(t) {
+ // have a length
+ var len = 16;
+ var list = [ new Buffer('foog'),
+ new Buffer('bark'),
+ new Buffer('bazy'),
+ new Buffer('kuel') ];
+
+ // read more than the first element.
+ var ret = fromList(6, { buffer: list, length: 16 });
+ t.equal(ret.toString(), 'foogba');
+
+ // read exactly the first element.
+ ret = fromList(2, { buffer: list, length: 10 });
+ t.equal(ret.toString(), 'rk');
+
+ // read less than the first element.
+ ret = fromList(2, { buffer: list, length: 8 });
+ t.equal(ret.toString(), 'ba');
+
+ // read more than we have.
+ ret = fromList(100, { buffer: list, length: 6 });
+ t.equal(ret.toString(), 'zykuel');
+
+ // all consumed.
+ t.same(list, []);
+
+ t.end();
+});
+
+test('strings', function(t) {
+ // have a length
+ var len = 16;
+ var list = [ 'foog',
+ 'bark',
+ 'bazy',
+ 'kuel' ];
+
+ // read more than the first element.
+ var ret = fromList(6, { buffer: list, length: 16, decoder: true });
+ t.equal(ret, 'foogba');
+
+ // read exactly the first element.
+ ret = fromList(2, { buffer: list, length: 10, decoder: true });
+ t.equal(ret, 'rk');
+
+ // read less than the first element.
+ ret = fromList(2, { buffer: list, length: 8, decoder: true });
+ t.equal(ret, 'ba');
+
+ // read more than we have.
+ ret = fromList(100, { buffer: list, length: 6, decoder: true });
+ t.equal(ret, 'zykuel');
+
+ // all consumed.
+ t.same(list, []);
+
+ t.end();
+});
diff --git a/test/simple/test-stream2-readable-legacy-drain.js b/test/simple/test-stream2-readable-legacy-drain.js
new file mode 100644
index 000000000..a1fffd9bb
--- /dev/null
+++ b/test/simple/test-stream2-readable-legacy-drain.js
@@ -0,0 +1,75 @@
+// 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');
+var assert = require('assert');
+
+var Stream = require('stream');
+var Readable = Stream.Readable;
+
+var r = new Readable();
+var N = 256;
+var reads = 0;
+r._read = function(n, cb) {
+ return cb(null, ++reads === N ? null : new Buffer(1));
+};
+
+var rended = false;
+r.on('end', function() {
+ rended = true;
+});
+
+var w = new Stream();
+w.writable = true;
+var writes = 0;
+var buffered = 0;
+w.write = function(c) {
+ writes += c.length;
+ buffered += c.length;
+ process.nextTick(drain);
+ return false;
+};
+
+function drain() {
+ assert(buffered <= 2);
+ buffered = 0;
+ w.emit('drain');
+}
+
+
+var wended = false;
+w.end = function() {
+ wended = true;
+};
+
+// Just for kicks, let's mess with the drain count.
+// This verifies that even if it gets negative in the
+// pipe() cleanup function, we'll still function properly.
+r.on('readable', function() {
+ w.emit('drain');
+});
+
+r.pipe(w);
+process.on('exit', function() {
+ assert(rended);
+ assert(wended);
+ console.error('ok');
+});
diff --git a/test/simple/test-stream2-readable-non-empty-end.js b/test/simple/test-stream2-readable-non-empty-end.js
new file mode 100644
index 000000000..351bef609
--- /dev/null
+++ b/test/simple/test-stream2-readable-non-empty-end.js
@@ -0,0 +1,78 @@
+// 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 assert = require('assert');
+var common = require('../common.js');
+var Readable = require('_stream_readable');
+
+var len = 0;
+var chunks = new Array(10);
+for (var i = 1; i <= 10; i++) {
+ chunks[i-1] = new Buffer(i);
+ len += i;
+}
+
+var test = new Readable();
+var n = 0;
+test._read = function(size, cb) {
+ var chunk = chunks[n++];
+ setTimeout(function() {
+ cb(null, chunk);
+ });
+};
+
+test.on('end', thrower);
+function thrower() {
+ throw new Error('this should not happen!');
+}
+
+var bytesread = 0;
+test.on('readable', function() {
+ var b = len - bytesread - 1;
+ var res = test.read(b);
+ if (res) {
+ bytesread += res.length;
+ console.error('br=%d len=%d', bytesread, len);
+ setTimeout(next);
+ }
+ test.read(0);
+});
+test.read(0);
+
+function next() {
+ // now let's make 'end' happen
+ test.removeListener('end', thrower);
+
+ var endEmitted = false;
+ process.on('exit', function() {
+ assert(endEmitted, 'end should be emitted by now');
+ });
+ test.on('end', function() {
+ endEmitted = true;
+ });
+
+ // one to get the last byte
+ var r = test.read();
+ assert(r);
+ assert.equal(r.length, 1);
+ r = test.read();
+ assert.equal(r, null);
+}
diff --git a/test/simple/test-stream2-set-encoding.js b/test/simple/test-stream2-set-encoding.js
new file mode 100644
index 000000000..3571bac4f
--- /dev/null
+++ b/test/simple/test-stream2-set-encoding.js
@@ -0,0 +1,314 @@
+// 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 assert = require('assert');
+var R = require('_stream_readable');
+var util = require('util');
+
+// tiny node-tap lookalike.
+var tests = [];
+var count = 0;
+
+function test(name, fn) {
+ count++;
+ tests.push([name, fn]);
+}
+
+function run() {
+ var next = tests.shift();
+ if (!next)
+ return console.error('ok');
+
+ var name = next[0];
+ var fn = next[1];
+ console.log('# %s', name);
+ fn({
+ same: assert.deepEqual,
+ equal: assert.equal,
+ end: function () {
+ count--;
+ run();
+ }
+ });
+}
+
+// ensure all tests have run
+process.on("exit", function () {
+ assert.equal(count, 0);
+});
+
+process.nextTick(run);
+
+/////
+
+util.inherits(TestReader, R);
+
+function TestReader(n, opts) {
+ R.call(this, util._extend({
+ bufferSize: 5
+ }, opts));
+
+ this.pos = 0;
+ this.len = n || 100;
+}
+
+TestReader.prototype._read = function(n, cb) {
+ setTimeout(function() {
+
+ if (this.pos >= this.len) {
+ return cb();
+ }
+
+ n = Math.min(n, this.len - this.pos);
+ if (n <= 0) {
+ return cb();
+ }
+
+ this.pos += n;
+ var ret = new Buffer(n);
+ ret.fill('a');
+
+ console.log("cb(null, ret)", ret)
+
+ return cb(null, ret);
+ }.bind(this), 1);
+};
+
+test('setEncoding utf8', function(t) {
+ var tr = new TestReader(100);
+ tr.setEncoding('utf8');
+ var out = [];
+ var expect =
+ [ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa' ];
+
+ tr.on('readable', function flow() {
+ var chunk;
+ while (null !== (chunk = tr.read(10)))
+ out.push(chunk);
+ });
+
+ tr.on('end', function() {
+ t.same(out, expect);
+ t.end();
+ });
+
+ // just kick it off.
+ tr.emit('readable');
+});
+
+
+test('setEncoding hex', function(t) {
+ var tr = new TestReader(100);
+ tr.setEncoding('hex');
+ var out = [];
+ var expect =
+ [ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161' ];
+
+ tr.on('readable', function flow() {
+ var chunk;
+ while (null !== (chunk = tr.read(10)))
+ out.push(chunk);
+ });
+
+ tr.on('end', function() {
+ t.same(out, expect);
+ t.end();
+ });
+
+ // just kick it off.
+ tr.emit('readable');
+});
+
+test('setEncoding hex with read(13)', function(t) {
+ var tr = new TestReader(100);
+ tr.setEncoding('hex');
+ var out = [];
+ var expect =
+ [ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "16161" ];
+
+ tr.on('readable', function flow() {
+ console.log("readable once")
+ var chunk;
+ while (null !== (chunk = tr.read(13)))
+ out.push(chunk);
+ });
+
+ tr.on('end', function() {
+ console.log("END")
+ t.same(out, expect);
+ t.end();
+ });
+
+ // just kick it off.
+ tr.emit('readable');
+});
+
+test('encoding: utf8', function(t) {
+ var tr = new TestReader(100, { encoding: 'utf8' });
+ var out = [];
+ var expect =
+ [ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa',
+ 'aaaaaaaaaa' ];
+
+ tr.on('readable', function flow() {
+ var chunk;
+ while (null !== (chunk = tr.read(10)))
+ out.push(chunk);
+ });
+
+ tr.on('end', function() {
+ t.same(out, expect);
+ t.end();
+ });
+
+ // just kick it off.
+ tr.emit('readable');
+});
+
+
+test('encoding: hex', function(t) {
+ var tr = new TestReader(100, { encoding: 'hex' });
+ var out = [];
+ var expect =
+ [ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161',
+ '6161616161' ];
+
+ tr.on('readable', function flow() {
+ var chunk;
+ while (null !== (chunk = tr.read(10)))
+ out.push(chunk);
+ });
+
+ tr.on('end', function() {
+ t.same(out, expect);
+ t.end();
+ });
+
+ // just kick it off.
+ tr.emit('readable');
+});
+
+test('encoding: hex with read(13)', function(t) {
+ var tr = new TestReader(100, { encoding: 'hex' });
+ var out = [];
+ var expect =
+ [ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "1616161616161",
+ "6161616161616",
+ "16161" ];
+
+ tr.on('readable', function flow() {
+ var chunk;
+ while (null !== (chunk = tr.read(13)))
+ out.push(chunk);
+ });
+
+ tr.on('end', function() {
+ t.same(out, expect);
+ t.end();
+ });
+
+ // just kick it off.
+ tr.emit('readable');
+});
diff --git a/test/simple/test-stream2-stderr-sync.js b/test/simple/test-stream2-stderr-sync.js
new file mode 100644
index 000000000..992c79db4
--- /dev/null
+++ b/test/simple/test-stream2-stderr-sync.js
@@ -0,0 +1,130 @@
+// 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.
+
+// Make sure that sync writes to stderr get processed before exiting.
+
+var common = require('../common.js');
+var assert = require('assert');
+
+function parent() {
+ var spawn = require('child_process').spawn;
+ var assert = require('assert');
+ var i = 0;
+ children.forEach(function(_, c) {
+ var child = spawn(process.execPath, [__filename, '' + c]);
+ var err = '';
+
+ child.stderr.on('data', function(c) {
+ err += c;
+ });
+
+ child.on('close', function() {
+ assert.equal(err, 'child ' + c + '\nfoo\nbar\nbaz\n');
+ console.log('ok %d child #%d', ++i, c);
+ if (i === children.length)
+ console.log('1..' + i);
+ });
+ });
+}
+
+function child0() {
+ // Just a very simple wrapper around TTY(2)
+ // Essentially the same as stderr, but without all the net stuff.
+ var Writable = require('stream').Writable;
+ var util = require('util');
+
+ // a lowlevel stderr writer
+ var TTY = process.binding('tty_wrap').TTY;
+ var handle = new TTY(2, false);
+
+ util.inherits(W, Writable);
+
+ function W(opts) {
+ Writable.call(this, opts);
+ }
+
+ W.prototype._write = function(chunk, cb) {
+ var req = handle.writeUtf8String(chunk.toString() + '\n');
+ // here's the problem.
+ // it needs to tell the Writable machinery that it's ok to write
+ // more, but that the current buffer length is handle.writeQueueSize
+ req.oncomplete = afterWrite
+ if (req.writeQueueSize === 0)
+ req.cb = cb;
+ else
+ cb();
+ }
+ function afterWrite(status, handle, req) {
+ if (req.cb)
+ req.cb();
+ }
+
+ var w = new W
+ w.write('child 0');
+ w.write('foo');
+ w.write('bar');
+ w.write('baz');
+}
+
+// using console.error
+function child1() {
+ console.error('child 1');
+ console.error('foo');
+ console.error('bar');
+ console.error('baz');
+}
+
+// using process.stderr
+function child2() {
+ process.stderr.write('child 2\n');
+ process.stderr.write('foo\n');
+ process.stderr.write('bar\n');
+ process.stderr.write('baz\n');
+}
+
+// using a net socket
+function child3() {
+ var net = require('net');
+ var socket = new net.Socket({ fd: 2 });
+ socket.write('child 3\n');
+ socket.write('foo\n');
+ socket.write('bar\n');
+ socket.write('baz\n');
+}
+
+
+function child4() {
+ console.error('child 4\nfoo\nbar\nbaz');
+}
+
+function child5() {
+ process.stderr.write('child 5\nfoo\nbar\nbaz\n');
+}
+
+var children = [ child0, child1, child2, child3, child4, child5 ];
+
+if (!process.argv[2]) {
+ parent();
+} else {
+ children[process.argv[2]]();
+ // immediate process.exit to kill any waiting stuff.
+ process.exit();
+}
diff --git a/test/simple/test-stream2-transform.js b/test/simple/test-stream2-transform.js
new file mode 100644
index 000000000..998e1f8e5
--- /dev/null
+++ b/test/simple/test-stream2-transform.js
@@ -0,0 +1,437 @@
+// 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 assert = require('assert');
+var common = require('../common.js');
+var PassThrough = require('_stream_passthrough');
+var Transform = require('_stream_transform');
+
+// tiny node-tap lookalike.
+var tests = [];
+var count = 0;
+
+function test(name, fn) {
+ count++;
+ tests.push([name, fn]);
+}
+
+function run() {
+ var next = tests.shift();
+ if (!next)
+ return console.error('ok');
+
+ var name = next[0];
+ var fn = next[1];
+ console.log('# %s', name);
+ fn({
+ same: assert.deepEqual,
+ equal: assert.equal,
+ ok: assert,
+ end: function () {
+ count--;
+ run();
+ }
+ });
+}
+
+// ensure all tests have run
+process.on("exit", function () {
+ assert.equal(count, 0);
+});
+
+process.nextTick(run);
+
+/////
+
+test('writable side consumption', function(t) {
+ var tx = new Transform({
+ highWaterMark: 10
+ });
+
+ var transformed = 0;
+ tx._transform = function(chunk, output, cb) {
+ transformed += chunk.length;
+ output(chunk);
+ cb();
+ };
+
+ for (var i = 1; i <= 10; i++) {
+ tx.write(new Buffer(i));
+ }
+ tx.end();
+
+ t.equal(tx._readableState.length, 10);
+ t.equal(transformed, 10);
+ t.equal(tx._transformState.writechunk.length, 5);
+ t.same(tx._writableState.buffer.map(function(c) {
+ return c[0].length;
+ }), [6, 7, 8, 9, 10]);
+
+ t.end();
+});
+
+test('passthrough', function(t) {
+ var pt = new PassThrough();
+
+ pt.write(new Buffer('foog'));
+ pt.write(new Buffer('bark'));
+ pt.write(new Buffer('bazy'));
+ pt.write(new Buffer('kuel'));
+ pt.end();
+
+ t.equal(pt.read(5).toString(), 'foogb');
+ t.equal(pt.read(5).toString(), 'arkba');
+ t.equal(pt.read(5).toString(), 'zykue');
+ t.equal(pt.read(5).toString(), 'l');
+ t.end();
+});
+
+test('simple transform', function(t) {
+ var pt = new Transform;
+ pt._transform = function(c, output, cb) {
+ var ret = new Buffer(c.length);
+ ret.fill('x');
+ output(ret);
+ cb();
+ };
+
+ pt.write(new Buffer('foog'));
+ pt.write(new Buffer('bark'));
+ pt.write(new Buffer('bazy'));
+ pt.write(new Buffer('kuel'));
+ pt.end();
+
+ t.equal(pt.read(5).toString(), 'xxxxx');
+ t.equal(pt.read(5).toString(), 'xxxxx');
+ t.equal(pt.read(5).toString(), 'xxxxx');
+ t.equal(pt.read(5).toString(), 'x');
+ t.end();
+});
+
+test('async passthrough', function(t) {
+ var pt = new Transform;
+ pt._transform = function(chunk, output, cb) {
+ setTimeout(function() {
+ output(chunk);
+ cb();
+ }, 10);
+ };
+
+ pt.write(new Buffer('foog'));
+ pt.write(new Buffer('bark'));
+ pt.write(new Buffer('bazy'));
+ pt.write(new Buffer('kuel'));
+ pt.end();
+
+ setTimeout(function() {
+ t.equal(pt.read(5).toString(), 'foogb');
+ t.equal(pt.read(5).toString(), 'arkba');
+ t.equal(pt.read(5).toString(), 'zykue');
+ t.equal(pt.read(5).toString(), 'l');
+ t.end();
+ }, 100);
+});
+
+test('assymetric transform (expand)', function(t) {
+ var pt = new Transform;
+
+ // emit each chunk 2 times.
+ pt._transform = function(chunk, output, cb) {
+ setTimeout(function() {
+ output(chunk);
+ setTimeout(function() {
+ output(chunk);
+ cb();
+ }, 10)
+ }, 10);
+ };
+
+ pt.write(new Buffer('foog'));
+ pt.write(new Buffer('bark'));
+ pt.write(new Buffer('bazy'));
+ pt.write(new Buffer('kuel'));
+ pt.end();
+
+ setTimeout(function() {
+ t.equal(pt.read(5).toString(), 'foogf');
+ t.equal(pt.read(5).toString(), 'oogba');
+ t.equal(pt.read(5).toString(), 'rkbar');
+ t.equal(pt.read(5).toString(), 'kbazy');
+ t.equal(pt.read(5).toString(), 'bazyk');
+ t.equal(pt.read(5).toString(), 'uelku');
+ t.equal(pt.read(5).toString(), 'el');
+ t.end();
+ }, 200);
+});
+
+test('assymetric transform (compress)', function(t) {
+ var pt = new Transform;
+
+ // each output is the first char of 3 consecutive chunks,
+ // or whatever's left.
+ pt.state = '';
+
+ pt._transform = function(chunk, output, cb) {
+ if (!chunk)
+ chunk = '';
+ var s = chunk.toString();
+ setTimeout(function() {
+ this.state += s.charAt(0);
+ if (this.state.length === 3) {
+ output(new Buffer(this.state));
+ this.state = '';
+ }
+ cb();
+ }.bind(this), 10);
+ };
+
+ pt._flush = function(output, cb) {
+ // just output whatever we have.
+ setTimeout(function() {
+ output(new Buffer(this.state));
+ this.state = '';
+ cb();
+ }.bind(this), 10);
+ };
+
+ pt.write(new Buffer('aaaa'));
+ pt.write(new Buffer('bbbb'));
+ pt.write(new Buffer('cccc'));
+ pt.write(new Buffer('dddd'));
+ pt.write(new Buffer('eeee'));
+ pt.write(new Buffer('aaaa'));
+ pt.write(new Buffer('bbbb'));
+ pt.write(new Buffer('cccc'));
+ pt.write(new Buffer('dddd'));
+ pt.write(new Buffer('eeee'));
+ pt.write(new Buffer('aaaa'));
+ pt.write(new Buffer('bbbb'));
+ pt.write(new Buffer('cccc'));
+ pt.write(new Buffer('dddd'));
+ pt.end();
+
+ // 'abcdeabcdeabcd'
+ setTimeout(function() {
+ t.equal(pt.read(5).toString(), 'abcde');
+ t.equal(pt.read(5).toString(), 'abcde');
+ t.equal(pt.read(5).toString(), 'abcd');
+ t.end();
+ }, 200);
+});
+
+
+test('passthrough event emission', function(t) {
+ var pt = new PassThrough();
+ var emits = 0;
+ pt.on('readable', function() {
+ var state = pt._readableState;
+ console.error('>>> emit readable %d', emits);
+ emits++;
+ });
+
+ var i = 0;
+
+ pt.write(new Buffer('foog'));
+
+ console.error('need emit 0');
+ pt.write(new Buffer('bark'));
+
+ console.error('should have emitted readable now 1 === %d', emits);
+ t.equal(emits, 1);
+
+ t.equal(pt.read(5).toString(), 'foogb');
+ t.equal(pt.read(5) + '', 'null');
+
+ console.error('need emit 1');
+
+ pt.write(new Buffer('bazy'));
+ console.error('should have emitted, but not again');
+ pt.write(new Buffer('kuel'));
+
+ console.error('should have emitted readable now 2 === %d', emits);
+ t.equal(emits, 2);
+
+ t.equal(pt.read(5).toString(), 'arkba');
+ t.equal(pt.read(5).toString(), 'zykue');
+ t.equal(pt.read(5), null);
+
+ console.error('need emit 2');
+
+ pt.end();
+
+ t.equal(emits, 3);
+
+ t.equal(pt.read(5).toString(), 'l');
+ t.equal(pt.read(5), null);
+
+ console.error('should not have emitted again');
+ t.equal(emits, 3);
+ t.end();
+});
+
+test('passthrough event emission reordered', function(t) {
+ var pt = new PassThrough;
+ var emits = 0;
+ pt.on('readable', function() {
+ console.error('emit readable', emits)
+ emits++;
+ });
+
+ pt.write(new Buffer('foog'));
+ console.error('need emit 0');
+ pt.write(new Buffer('bark'));
+ console.error('should have emitted readable now 1 === %d', emits);
+ t.equal(emits, 1);
+
+ t.equal(pt.read(5).toString(), 'foogb');
+ t.equal(pt.read(5), null);
+
+ console.error('need emit 1');
+ pt.once('readable', function() {
+ t.equal(pt.read(5).toString(), 'arkba');
+
+ t.equal(pt.read(5), null);
+
+ console.error('need emit 2');
+ pt.once('readable', function() {
+ t.equal(pt.read(5).toString(), 'zykue');
+ t.equal(pt.read(5), null);
+ pt.once('readable', function() {
+ t.equal(pt.read(5).toString(), 'l');
+ t.equal(pt.read(5), null);
+ t.equal(emits, 4);
+ t.end();
+ });
+ pt.end();
+ });
+ pt.write(new Buffer('kuel'));
+ });
+
+ pt.write(new Buffer('bazy'));
+});
+
+test('passthrough facaded', function(t) {
+ console.error('passthrough facaded');
+ var pt = new PassThrough;
+ var datas = [];
+ pt.on('data', function(chunk) {
+ datas.push(chunk.toString());
+ });
+
+ pt.on('end', function() {
+ t.same(datas, ['foog', 'bark', 'bazy', 'kuel']);
+ t.end();
+ });
+
+ pt.write(new Buffer('foog'));
+ setTimeout(function() {
+ pt.write(new Buffer('bark'));
+ setTimeout(function() {
+ pt.write(new Buffer('bazy'));
+ setTimeout(function() {
+ pt.write(new Buffer('kuel'));
+ setTimeout(function() {
+ pt.end();
+ }, 10);
+ }, 10);
+ }, 10);
+ }, 10);
+});
+
+test('object transform (json parse)', function(t) {
+ console.error('json parse stream');
+ var jp = new Transform({ objectMode: true });
+ jp._transform = function(data, output, cb) {
+ try {
+ output(JSON.parse(data));
+ cb();
+ } catch (er) {
+ cb(er);
+ }
+ };
+
+ // anything except null/undefined is fine.
+ // those are "magic" in the stream API, because they signal EOF.
+ var objects = [
+ { foo: 'bar' },
+ 100,
+ "string",
+ { nested: { things: [ { foo: 'bar' }, 100, "string" ] } }
+ ];
+
+ var ended = false;
+ jp.on('end', function() {
+ ended = true;
+ });
+
+ objects.forEach(function(obj) {
+ jp.write(JSON.stringify(obj));
+ var res = jp.read();
+ t.same(res, obj);
+ });
+
+ jp.end();
+
+ process.nextTick(function() {
+ t.ok(ended);
+ t.end();
+ })
+});
+
+test('object transform (json stringify)', function(t) {
+ console.error('json parse stream');
+ var js = new Transform({ objectMode: true });
+ js._transform = function(data, output, cb) {
+ try {
+ output(JSON.stringify(data));
+ cb();
+ } catch (er) {
+ cb(er);
+ }
+ };
+
+ // anything except null/undefined is fine.
+ // those are "magic" in the stream API, because they signal EOF.
+ var objects = [
+ { foo: 'bar' },
+ 100,
+ "string",
+ { nested: { things: [ { foo: 'bar' }, 100, "string" ] } }
+ ];
+
+ var ended = false;
+ js.on('end', function() {
+ ended = true;
+ });
+
+ objects.forEach(function(obj) {
+ js.write(obj);
+ var res = js.read();
+ t.equal(res, JSON.stringify(obj));
+ });
+
+ js.end();
+
+ process.nextTick(function() {
+ t.ok(ended);
+ t.end();
+ })
+});
diff --git a/test/simple/test-stream2-unpipe-drain.js b/test/simple/test-stream2-unpipe-drain.js
new file mode 100644
index 000000000..0fc963e80
--- /dev/null
+++ b/test/simple/test-stream2-unpipe-drain.js
@@ -0,0 +1,76 @@
+// 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 assert = require('assert');
+var stream = require('stream');
+var crypto = require('crypto');
+
+var util = require('util');
+
+function TestWriter() {
+ stream.Writable.call(this);
+}
+util.inherits(TestWriter, stream.Writable);
+
+TestWriter.prototype._write = function (buffer, callback) {
+ console.log('write called');
+ // super slow write stream (callback never called)
+};
+
+var dest = new TestWriter();
+
+function TestReader(id) {
+ stream.Readable.call(this);
+ this.reads = 0;
+}
+util.inherits(TestReader, stream.Readable);
+
+TestReader.prototype._read = function (size, callback) {
+ this.reads += 1;
+ crypto.randomBytes(size, callback);
+};
+
+var src1 = new TestReader();
+var src2 = new TestReader();
+
+src1.pipe(dest);
+
+src1.once('readable', function () {
+ process.nextTick(function () {
+
+ src2.pipe(dest);
+
+ src2.once('readable', function () {
+ process.nextTick(function () {
+
+ src1.unpipe(dest);
+ });
+ });
+ });
+});
+
+
+process.on('exit', function () {
+ assert.equal(src1.reads, 2);
+ assert.equal(src2.reads, 2);
+});
diff --git a/test/simple/test-stream2-unpipe-leak.js b/test/simple/test-stream2-unpipe-leak.js
new file mode 100644
index 000000000..a560bfa0c
--- /dev/null
+++ b/test/simple/test-stream2-unpipe-leak.js
@@ -0,0 +1,63 @@
+// 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 assert = require('assert');
+var stream = require('stream');
+
+var util = require('util');
+
+function TestWriter() {
+ stream.Writable.call(this);
+}
+util.inherits(TestWriter, stream.Writable);
+
+TestWriter.prototype._write = function (buffer, callback) {
+ callback(null);
+};
+
+var dest = new TestWriter();
+
+function TestReader() {
+ stream.Readable.call(this);
+}
+util.inherits(TestReader, stream.Readable);
+
+TestReader.prototype._read = function (size, callback) {
+ callback(new Buffer('hallo'));
+};
+
+var src = new TestReader();
+
+for (var i = 0; i < 10; i++) {
+ src.pipe(dest);
+ src.unpipe(dest);
+}
+
+assert.equal(src.listeners('end').length, 0);
+assert.equal(src.listeners('readable').length, 0);
+
+assert.equal(dest.listeners('unpipe').length, 0);
+assert.equal(dest.listeners('drain').length, 0);
+assert.equal(dest.listeners('error').length, 0);
+assert.equal(dest.listeners('close').length, 0);
+assert.equal(dest.listeners('finish').length, 0);
diff --git a/test/simple/test-stream2-writable.js b/test/simple/test-stream2-writable.js
new file mode 100644
index 000000000..efd49021b
--- /dev/null
+++ b/test/simple/test-stream2-writable.js
@@ -0,0 +1,313 @@
+// 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 W = require('_stream_writable');
+var D = require('_stream_duplex');
+var assert = require('assert');
+
+var util = require('util');
+util.inherits(TestWriter, W);
+
+function TestWriter() {
+ W.apply(this, arguments);
+ this.buffer = [];
+ this.written = 0;
+}
+
+TestWriter.prototype._write = function(chunk, cb) {
+ // simulate a small unpredictable latency
+ setTimeout(function() {
+ this.buffer.push(chunk.toString());
+ this.written += chunk.length;
+ cb();
+ }.bind(this), Math.floor(Math.random() * 10));
+};
+
+var chunks = new Array(50);
+for (var i = 0; i < chunks.length; i++) {
+ chunks[i] = new Array(i + 1).join('x');
+}
+
+// tiny node-tap lookalike.
+var tests = [];
+var count = 0;
+
+function test(name, fn) {
+ count++;
+ tests.push([name, fn]);
+}
+
+function run() {
+ var next = tests.shift();
+ if (!next)
+ return console.error('ok');
+
+ var name = next[0];
+ var fn = next[1];
+ console.log('# %s', name);
+ fn({
+ same: assert.deepEqual,
+ equal: assert.equal,
+ end: function () {
+ count--;
+ run();
+ }
+ });
+}
+
+// ensure all tests have run
+process.on("exit", function () {
+ assert.equal(count, 0);
+});
+
+process.nextTick(run);
+
+test('write fast', function(t) {
+ var tw = new TestWriter({
+ highWaterMark: 100
+ });
+
+ tw.on('finish', function() {
+ t.same(tw.buffer, chunks, 'got chunks in the right order');
+ t.end();
+ });
+
+ chunks.forEach(function(chunk) {
+ // screw backpressure. Just buffer it all up.
+ tw.write(chunk);
+ });
+ tw.end();
+});
+
+test('write slow', function(t) {
+ var tw = new TestWriter({
+ highWaterMark: 100
+ });
+
+ tw.on('finish', function() {
+ t.same(tw.buffer, chunks, 'got chunks in the right order');
+ t.end();
+ });
+
+ var i = 0;
+ (function W() {
+ tw.write(chunks[i++]);
+ if (i < chunks.length)
+ setTimeout(W, 10);
+ else
+ tw.end();
+ })();
+});
+
+test('write backpressure', function(t) {
+ var tw = new TestWriter({
+ highWaterMark: 50
+ });
+
+ var drains = 0;
+
+ tw.on('finish', function() {
+ t.same(tw.buffer, chunks, 'got chunks in the right order');
+ t.equal(drains, 17);
+ t.end();
+ });
+
+ tw.on('drain', function() {
+ drains++;
+ });
+
+ var i = 0;
+ (function W() {
+ do {
+ var ret = tw.write(chunks[i++]);
+ } while (ret !== false && i < chunks.length);
+
+ if (i < chunks.length) {
+ assert(tw._writableState.length >= 50);
+ tw.once('drain', W);
+ } else {
+ tw.end();
+ }
+ })();
+});
+
+test('write bufferize', function(t) {
+ var tw = new TestWriter({
+ highWaterMark: 100
+ });
+
+ var encodings =
+ [ 'hex',
+ 'utf8',
+ 'utf-8',
+ 'ascii',
+ 'binary',
+ 'base64',
+ 'ucs2',
+ 'ucs-2',
+ 'utf16le',
+ 'utf-16le',
+ undefined ];
+
+ tw.on('finish', function() {
+ t.same(tw.buffer, chunks, 'got the expected chunks');
+ });
+
+ chunks.forEach(function(chunk, i) {
+ var enc = encodings[ i % encodings.length ];
+ chunk = new Buffer(chunk);
+ tw.write(chunk.toString(enc), enc);
+ });
+ t.end();
+});
+
+test('write no bufferize', function(t) {
+ var tw = new TestWriter({
+ highWaterMark: 100,
+ decodeStrings: false
+ });
+
+ tw._write = function(chunk, cb) {
+ assert(Array.isArray(chunk));
+ assert(typeof chunk[0] === 'string');
+ chunk = new Buffer(chunk[0], chunk[1]);
+ return TestWriter.prototype._write.call(this, chunk, cb);
+ };
+
+ var encodings =
+ [ 'hex',
+ 'utf8',
+ 'utf-8',
+ 'ascii',
+ 'binary',
+ 'base64',
+ 'ucs2',
+ 'ucs-2',
+ 'utf16le',
+ 'utf-16le',
+ undefined ];
+
+ tw.on('finish', function() {
+ t.same(tw.buffer, chunks, 'got the expected chunks');
+ });
+
+ chunks.forEach(function(chunk, i) {
+ var enc = encodings[ i % encodings.length ];
+ chunk = new Buffer(chunk);
+ tw.write(chunk.toString(enc), enc);
+ });
+ t.end();
+});
+
+test('write callbacks', function (t) {
+ var callbacks = chunks.map(function(chunk, i) {
+ return [i, function(er) {
+ callbacks._called[i] = chunk;
+ }];
+ }).reduce(function(set, x) {
+ set['callback-' + x[0]] = x[1];
+ return set;
+ }, {});
+ callbacks._called = [];
+
+ var tw = new TestWriter({
+ highWaterMark: 100
+ });
+
+ tw.on('finish', function() {
+ process.nextTick(function() {
+ t.same(tw.buffer, chunks, 'got chunks in the right order');
+ t.same(callbacks._called, chunks, 'called all callbacks');
+ t.end();
+ });
+ });
+
+ chunks.forEach(function(chunk, i) {
+ tw.write(chunk, callbacks['callback-' + i]);
+ });
+ tw.end();
+});
+
+test('end callback', function (t) {
+ var tw = new TestWriter();
+ tw.end(function () {
+ t.end();
+ });
+});
+
+test('end callback with chunk', function (t) {
+ var tw = new TestWriter();
+ tw.end(new Buffer('hello world'), function () {
+ t.end();
+ });
+});
+
+test('end callback with chunk and encoding', function (t) {
+ var tw = new TestWriter();
+ tw.end('hello world', 'ascii', function () {
+ t.end();
+ });
+});
+
+test('end callback after .write() call', function (t) {
+ var tw = new TestWriter();
+ tw.write(new Buffer('hello world'));
+ tw.end(function () {
+ t.end();
+ });
+});
+
+test('encoding should be ignored for buffers', function(t) {
+ var tw = new W();
+ var hex = '018b5e9a8f6236ffe30e31baf80d2cf6eb';
+ tw._write = function(chunk, cb) {
+ t.equal(chunk.toString('hex'), hex);
+ t.end();
+ };
+ var buf = new Buffer(hex, 'hex');
+ tw.write(buf, 'binary');
+});
+
+test('writables are not pipable', function(t) {
+ var w = new W();
+ w._write = function() {};
+ var gotError = false;
+ w.on('error', function(er) {
+ gotError = true;
+ });
+ w.pipe(process.stdout);
+ assert(gotError);
+ t.end();
+});
+
+test('duplexes are pipable', function(t) {
+ var d = new D();
+ d._read = function() {};
+ d._write = function() {};
+ var gotError = false;
+ d.on('error', function(er) {
+ gotError = true;
+ });
+ d.pipe(process.stdout);
+ assert(!gotError);
+ t.end();
+});
diff --git a/test/simple/test-string-decoder-end.js b/test/simple/test-string-decoder-end.js
new file mode 100644
index 000000000..fea55d410
--- /dev/null
+++ b/test/simple/test-string-decoder-end.js
@@ -0,0 +1,75 @@
+// 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.
+
+// verify that the string decoder works getting 1 byte at a time,
+// the whole buffer at once, and that both match the .toString(enc)
+// result of the entire buffer.
+
+var assert = require('assert');
+var SD = require('string_decoder').StringDecoder;
+var encodings = ['base64', 'hex', 'utf8', 'utf16le', 'ucs2'];
+
+var bufs = [ '☃💩', 'asdf' ].map(function(b) {
+ return new Buffer(b);
+});
+
+// also test just arbitrary bytes from 0-15.
+for (var i = 1; i <= 16; i++) {
+ var bytes = new Array(i).join('.').split('.').map(function(_, j) {
+ return j + 0x78;
+ });
+ bufs.push(new Buffer(bytes));
+}
+
+encodings.forEach(testEncoding);
+
+console.log('ok');
+
+function testEncoding(encoding) {
+ bufs.forEach(function(buf) {
+ testBuf(encoding, buf);
+ });
+}
+
+function testBuf(encoding, buf) {
+ console.error('# %s', encoding, buf);
+
+ // write one byte at a time.
+ var s = new SD(encoding);
+ var res1 = '';
+ for (var i = 0; i < buf.length; i++) {
+ res1 += s.write(buf.slice(i, i + 1));
+ }
+ res1 += s.end();
+
+ // write the whole buffer at once.
+ var res2 = '';
+ var s = new SD(encoding);
+ res2 += s.write(buf);
+ res2 += s.end();
+
+ // .toString() on the buffer
+ var res3 = buf.toString(encoding);
+
+ console.log('expect=%j', res3);
+ assert.equal(res1, res3, 'one byte at a time should match toString');
+ assert.equal(res2, res3, 'all bytes at once should match toString');
+}
diff --git a/test/simple/test-tcp-wrap-connect.js b/test/simple/test-tcp-wrap-connect.js
index b8ac6aae3..3da8d932e 100644
--- a/test/simple/test-tcp-wrap-connect.js
+++ b/test/simple/test-tcp-wrap-connect.js
@@ -54,6 +54,7 @@ var shutdownCount = 0;
var server = require('net').Server(function(s) {
console.log('got connection');
connectCount++;
+ s.resume();
s.on('end', function() {
console.log('got eof');
endCount++;
diff --git a/test/simple/test-tcp-wrap.js b/test/simple/test-tcp-wrap.js
index 1e9e115a9..10f7038c8 100644
--- a/test/simple/test-tcp-wrap.js
+++ b/test/simple/test-tcp-wrap.js
@@ -33,7 +33,7 @@ assert.equal(0, r);
// Should not be able to bind to the same port again
var r = handle.bind('0.0.0.0', common.PORT);
assert.equal(-1, r);
-console.log(errno);
-assert.equal(errno, 'EINVAL');
+console.log(process._errno);
+assert.equal(process._errno, 'EINVAL');
handle.close();
diff --git a/test/simple/test-timers-immediate.js b/test/simple/test-timers-immediate.js
new file mode 100644
index 000000000..0bd8ae964
--- /dev/null
+++ b/test/simple/test-timers-immediate.js
@@ -0,0 +1,53 @@
+// 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');
+var assert = require('assert');
+
+var immediateA = false,
+ immediateB = false,
+ immediateC = [],
+ before;
+
+setImmediate(function() {
+ try {
+ immediateA = process.hrtime(before);
+ } catch(e) {
+ console.log('failed to get hrtime with offset');
+ }
+ clearImmediate(immediateB);
+});
+
+before = process.hrtime();
+
+immediateB = setImmediate(function() {
+ immediateB = true;
+});
+
+setImmediate(function(x, y, z) {
+ immediateC = [x, y, z];
+}, 1, 2, 3);
+
+process.on('exit', function() {
+ assert.ok(immediateA, 'Immediate should happen after normal execution');
+ assert.notStrictEqual(immediateB, true, 'immediateB should not fire');
+ assert.deepEqual(immediateC, [1, 2, 3], 'immediateC args should match');
+});
diff --git a/test/simple/test-timers-uncaught-exception.js b/test/simple/test-timers-uncaught-exception.js
index 0d2f488df..6e07fe084 100644
--- a/test/simple/test-timers-uncaught-exception.js
+++ b/test/simple/test-timers-uncaught-exception.js
@@ -27,24 +27,32 @@ var timer1 = 0;
var timer2 = 0;
// the first timer throws...
+console.error('set first timer');
setTimeout(function() {
+ console.error('first timer');
timer1++;
throw new Error('BAM!');
}, 100);
// ...but the second one should still run
+console.error('set second timer');
setTimeout(function() {
+ console.error('second timer');
assert.equal(timer1, 1);
timer2++;
}, 100);
function uncaughtException(err) {
+ console.error('uncaught handler');
assert.equal(err.message, 'BAM!');
exceptions++;
}
process.on('uncaughtException', uncaughtException);
+var exited = false;
process.on('exit', function() {
+ assert(!exited);
+ exited = true;
process.removeListener('uncaughtException', uncaughtException);
assert.equal(exceptions, 1);
assert.equal(timer1, 1);
diff --git a/test/simple/test-timers-unref.js b/test/simple/test-timers-unref.js
new file mode 100644
index 000000000..4be557e50
--- /dev/null
+++ b/test/simple/test-timers-unref.js
@@ -0,0 +1,62 @@
+// 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');
+var assert = require('assert');
+
+var interval_fired = false,
+ timeout_fired = false,
+ unref_interval = false,
+ unref_timer = false,
+ interval, check_unref, checks = 0;
+
+var LONG_TIME = 10 * 1000;
+var SHORT_TIME = 100;
+
+setInterval(function() {
+ interval_fired = true;
+}, LONG_TIME).unref();
+
+setTimeout(function() {
+ timeout_fired = true;
+}, LONG_TIME).unref();
+
+interval = setInterval(function() {
+ unref_interval = true;
+ clearInterval(interval);
+}, SHORT_TIME).unref();
+
+setTimeout(function() {
+ unref_timer = true;
+}, SHORT_TIME).unref();
+
+check_unref = setInterval(function() {
+ if (checks > 5 || (unref_interval && unref_timer))
+ clearInterval(check_unref);
+ checks += 1;
+}, 100);
+
+process.on('exit', function() {
+ assert.strictEqual(interval_fired, false, 'Interval should not fire');
+ assert.strictEqual(timeout_fired, false, 'Timeout should not fire');
+ assert.strictEqual(unref_timer, true, 'An unrefd timeout should still fire');
+ assert.strictEqual(unref_interval, true, 'An unrefd interval should still fire');
+});
diff --git a/test/simple/test-tls-client-reject.js b/test/simple/test-tls-client-reject.js
index 5f5056e33..410096fc1 100644
--- a/test/simple/test-tls-client-reject.js
+++ b/test/simple/test-tls-client-reject.js
@@ -48,7 +48,10 @@ var server = tls.createServer(options, function(socket) {
});
function unauthorized() {
- var socket = tls.connect(common.PORT, function() {
+ var socket = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
assert(!socket.authorized);
socket.end();
rejectUnauthorized();
@@ -60,9 +63,7 @@ function unauthorized() {
}
function rejectUnauthorized() {
- var socket = tls.connect(common.PORT, {
- rejectUnauthorized: true
- }, function() {
+ var socket = tls.connect(common.PORT, function() {
assert(false);
});
socket.on('error', function(err) {
@@ -74,7 +75,6 @@ function rejectUnauthorized() {
function authorized() {
var socket = tls.connect(common.PORT, {
- rejectUnauthorized: true,
ca: [fs.readFileSync(path.join(common.fixturesDir, 'test_cert.pem'))]
}, function() {
assert(socket.authorized);
diff --git a/test/simple/test-tls-client-resume.js b/test/simple/test-tls-client-resume.js
index 9fc84da3e..7271134df 100644
--- a/test/simple/test-tls-client-resume.js
+++ b/test/simple/test-tls-client-resume.js
@@ -50,7 +50,10 @@ var server = tls.Server(options, function(socket) {
server.listen(common.PORT, function() {
var session1 = null;
- var client1 = tls.connect({port: common.PORT}, function() {
+ var client1 = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
console.log('connect1');
assert.ok(!client1.isSessionReused(), 'Session *should not* be reused.');
session1 = client1.getSession();
@@ -59,7 +62,12 @@ server.listen(common.PORT, function() {
client1.on('close', function() {
console.log('close1');
- var opts = { 'session': session1, port: common.PORT };
+ var opts = {
+ port: common.PORT,
+ rejectUnauthorized: false,
+ session: session1
+ };
+
var client2 = tls.connect(opts, function() {
console.log('connect2');
assert.ok(client2.isSessionReused(), 'Session *should* be reused.');
diff --git a/test/simple/test-tls-client-verify.js b/test/simple/test-tls-client-verify.js
index 9b1083f06..cc4e21572 100644
--- a/test/simple/test-tls-client-verify.js
+++ b/test/simple/test-tls-client-verify.js
@@ -134,7 +134,8 @@ function runTest(testIndex) {
port: common.PORT,
ca: tcase.ca.map(loadPEM),
key: loadPEM(tcase.key),
- cert: loadPEM(tcase.cert)
+ cert: loadPEM(tcase.cert),
+ rejectUnauthorized: false
};
diff --git a/test/simple/test-tls-connect-given-socket.js b/test/simple/test-tls-connect-given-socket.js
index e341dfc82..5cb62992f 100644
--- a/test/simple/test-tls-connect-given-socket.js
+++ b/test/simple/test-tls-connect-given-socket.js
@@ -38,8 +38,14 @@ var server = tls.createServer(options, function(socket) {
serverConnected = true;
socket.end('Hello');
}).listen(common.PORT, function() {
- var socket = net.connect(common.PORT, function() {
- var client = tls.connect({socket: socket}, function() {
+ var socket = net.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
+ var client = tls.connect({
+ rejectUnauthorized: false,
+ socket: socket
+ }, function() {
clientConnected = true;
var data = '';
client.on('data', function(chunk) {
diff --git a/test/simple/test-tls-connect-pipe.js b/test/simple/test-tls-connect-pipe.js
index f58aaabcf..98031c0ad 100644
--- a/test/simple/test-tls-connect-pipe.js
+++ b/test/simple/test-tls-connect-pipe.js
@@ -37,7 +37,8 @@ var server = tls.Server(options, function(socket) {
server.close();
});
server.listen(common.PIPE, function() {
- var client = tls.connect(common.PIPE, function() {
+ var options = { rejectUnauthorized: false };
+ var client = tls.connect(common.PIPE, options, function() {
++clientConnected;
client.end();
});
diff --git a/test/simple/test-tls-connect-simple.js b/test/simple/test-tls-connect-simple.js
index 6c07f4cb0..e896dd9e2 100644
--- a/test/simple/test-tls-connect-simple.js
+++ b/test/simple/test-tls-connect-simple.js
@@ -39,12 +39,18 @@ var server = tls.Server(options, function(socket) {
});
server.listen(common.PORT, function() {
- var client1 = tls.connect({port: common.PORT}, function() {
+ var client1 = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
++clientConnected;
client1.end();
});
- var client2 = tls.connect({port: common.PORT});
+ var client2 = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ });
client2.on('secureConnect', function() {
++clientConnected;
client2.end();
diff --git a/test/simple/test-tls-fast-writing.js b/test/simple/test-tls-fast-writing.js
new file mode 100644
index 000000000..894ec346a
--- /dev/null
+++ b/test/simple/test-tls-fast-writing.js
@@ -0,0 +1,80 @@
+// 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');
+var assert = require('assert');
+
+var tls = require('tls');
+var fs = require('fs');
+
+var PORT = common.PORT;
+var dir = common.fixturesDir;
+var options = { key: fs.readFileSync(dir + '/test_key.pem'),
+ cert: fs.readFileSync(dir + '/test_cert.pem'),
+ ca: [ fs.readFileSync(dir + '/test_ca.pem') ] };
+
+var server = tls.createServer(options, onconnection);
+var gotChunk = false;
+var gotDrain = false;
+
+var timer = setTimeout(function() {
+ console.log('not ok - timed out');
+ process.exit(1);
+}, 500);
+
+function onconnection(conn) {
+ conn.on('data', function(c) {
+ if (!gotChunk) {
+ gotChunk = true;
+ console.log('ok - got chunk');
+ }
+
+ // just some basic sanity checks.
+ assert(c.length);
+ assert(Buffer.isBuffer(c));
+
+ if (gotDrain)
+ process.exit(0);
+ });
+}
+
+server.listen(PORT, function() {
+ var chunk = new Buffer(1024);
+ chunk.fill('x');
+ var opt = { port: PORT, rejectUnauthorized: false };
+ var conn = tls.connect(opt, function() {
+ conn.on('drain', ondrain);
+ write();
+ });
+ function ondrain() {
+ if (!gotDrain) {
+ gotDrain = true;
+ console.log('ok - got drain');
+ }
+ if (gotChunk)
+ process.exit(0);
+ write();
+ }
+ function write() {
+ // this needs to return false eventually
+ while (false !== conn.write(chunk));
+ }
+});
diff --git a/test/simple/test-tls-getcipher.js b/test/simple/test-tls-getcipher.js
index 2f8c290b7..22a280e58 100644
--- a/test/simple/test-tls-getcipher.js
+++ b/test/simple/test-tls-getcipher.js
@@ -43,7 +43,11 @@ var server = tls.createServer(options, function(cleartextStream) {
});
server.listen(common.PORT, '127.0.0.1', function() {
- var client = tls.connect(common.PORT, '127.0.0.1', function() {
+ var client = tls.connect({
+ host: '127.0.0.1',
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
var cipher = client.getCipher();
assert.equal(cipher.name, cipher_list[0]);
assert(cipher_version_pattern.test(cipher.version));
diff --git a/test/simple/test-tls-handshake-nohang.js b/test/simple/test-tls-handshake-nohang.js
new file mode 100644
index 000000000..de36ebb50
--- /dev/null
+++ b/test/simple/test-tls-handshake-nohang.js
@@ -0,0 +1,28 @@
+// 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');
+var assert = require('assert');
+var tls = require('tls');
+
+// neither should hang
+tls.createSecurePair(null, false, false, false);
+tls.createSecurePair(null, true, false, false);
diff --git a/test/simple/test-tls-honorcipherorder.js b/test/simple/test-tls-honorcipherorder.js
index cc2584390..539a12abf 100644
--- a/test/simple/test-tls-honorcipherorder.js
+++ b/test/simple/test-tls-honorcipherorder.js
@@ -46,7 +46,10 @@ function test(honorCipherOrder, clientCipher, expectedCipher, cb) {
nconns++;
});
server.listen(common.PORT, localhost, function() {
- var coptions = {secureProtocol: SSL_Method};
+ var coptions = {
+ rejectUnauthorized: false,
+ secureProtocol: SSL_Method
+ };
if (clientCipher) {
coptions.ciphers = clientCipher;
}
diff --git a/test/simple/test-tls-junk-closes-server.js b/test/simple/test-tls-junk-closes-server.js
index d4f9f1d86..57db7f5a3 100644
--- a/test/simple/test-tls-junk-closes-server.js
+++ b/test/simple/test-tls-junk-closes-server.js
@@ -34,7 +34,7 @@ var options = {
cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem')
};
-var server = tls.createServer(function(s) {
+var server = tls.createServer(options, function(s) {
s.write('welcome!\n');
s.pipe(s);
});
diff --git a/test/simple/test-tls-npn-server-client.js b/test/simple/test-tls-npn-server-client.js
index cf8014a50..86e10bedc 100644
--- a/test/simple/test-tls-npn-server-client.js
+++ b/test/simple/test-tls-npn-server-client.js
@@ -52,19 +52,22 @@ var clientsOptions = [{
key: serverOptions.key,
cert: serverOptions.cert,
crl: serverOptions.crl,
- NPNProtocols: ['a', 'b', 'c']
+ NPNProtocols: ['a', 'b', 'c'],
+ rejectUnauthorized: false
},{
port: serverPort,
key: serverOptions.key,
cert: serverOptions.cert,
crl: serverOptions.crl,
- NPNProtocols: ['c', 'b', 'e']
+ NPNProtocols: ['c', 'b', 'e'],
+ rejectUnauthorized: false
},{
port: serverPort,
key: serverOptions.key,
cert: serverOptions.cert,
crl: serverOptions.crl,
- NPNProtocols: ['first-priority-unsupported', 'x', 'y']
+ NPNProtocols: ['first-priority-unsupported', 'x', 'y'],
+ rejectUnauthorized: false
}];
var serverResults = [],
diff --git a/test/simple/test-tls-over-http-tunnel.js b/test/simple/test-tls-over-http-tunnel.js
index 4a5e22140..9fa82ae3e 100644
--- a/test/simple/test-tls-over-http-tunnel.js
+++ b/test/simple/test-tls-over-http-tunnel.js
@@ -19,9 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
if (!process.versions.openssl) {
console.error('Skipping because node compiled without OpenSSL.');
process.exit(0);
@@ -150,7 +147,8 @@ proxy.listen(proxyPort, function() {
key: key,
cert: cert,
socket: socket, // reuse the socket
- agent: false
+ agent: false,
+ rejectUnauthorized: false
}, function(res) {
assert.equal(200, res.statusCode);
@@ -164,6 +162,12 @@ proxy.listen(proxyPort, function() {
proxy.close();
server.close();
});
+ }).on('error', function(er) {
+ // We're ok with getting ECONNRESET in this test, but it's
+ // timing-dependent, and thus unreliable. Any other errors
+ // are just failures, though.
+ if (er.code !== 'ECONNRESET')
+ throw er;
}).end();
}
});
diff --git a/test/simple/test-tls-passphrase.js b/test/simple/test-tls-passphrase.js
index e3c0f2a84..e9a5c5a5d 100644
--- a/test/simple/test-tls-passphrase.js
+++ b/test/simple/test-tls-passphrase.js
@@ -50,7 +50,8 @@ server.listen(common.PORT, function() {
port: common.PORT,
key: key,
passphrase: 'passphrase',
- cert: cert
+ cert: cert,
+ rejectUnauthorized: false
}, function() {
++connectCount;
});
@@ -64,7 +65,8 @@ assert.throws(function() {
port: common.PORT,
key: key,
passphrase: 'invalid',
- cert: cert
+ cert: cert,
+ rejectUnauthorized: false
});
});
diff --git a/test/simple/test-tls-pause-close.js b/test/simple/test-tls-pause-close.js
index a53d017a1..8e5d897d1 100644
--- a/test/simple/test-tls-pause-close.js
+++ b/test/simple/test-tls-pause-close.js
@@ -66,7 +66,10 @@ var server = tls.createServer(options, function(s) {
});
server.listen(common.PORT, function() {
- var c = tls.connect({port: common.PORT}, function() {
+ var c = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
console.log('client connected');
c.socket.on('end', function() {
console.log('client socket ended');
diff --git a/test/simple/test-tls-pause.js b/test/simple/test-tls-pause.js
index 9ca3dfb2b..5eaac8da1 100644
--- a/test/simple/test-tls-pause.js
+++ b/test/simple/test-tls-pause.js
@@ -41,16 +41,27 @@ var received = 0;
var server = tls.Server(options, function(socket) {
socket.pipe(socket);
+ socket.on('data', function(c) {
+ console.error('data', c.length);
+ });
});
server.listen(common.PORT, function() {
var resumed = false;
- var client = tls.connect({port: common.PORT}, function() {
+ var client = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
+ console.error('connected');
client.pause();
common.debug('paused');
send();
function send() {
- if (client.write(new Buffer(bufSize))) {
+ console.error('sending');
+ var ret = client.write(new Buffer(bufSize));
+ console.error('write => %j', ret);
+ if (false !== ret) {
+ console.error('write again');
sent += bufSize;
assert.ok(sent < 100 * 1024 * 1024); // max 100MB
return process.nextTick(send);
@@ -59,12 +70,15 @@ server.listen(common.PORT, function() {
common.debug('sent: ' + sent);
resumed = true;
client.resume();
- common.debug('resumed');
+ console.error('resumed', client);
}
});
client.on('data', function(data) {
+ console.error('data');
assert.ok(resumed);
received += data.length;
+ console.error('received', received);
+ console.error('sent', sent);
if (received >= sent) {
common.debug('received: ' + received);
client.end();
diff --git a/test/simple/test-tls-peer-certificate-multi-keys.js b/test/simple/test-tls-peer-certificate-multi-keys.js
index 070b52876..a321d2cba 100644
--- a/test/simple/test-tls-peer-certificate-multi-keys.js
+++ b/test/simple/test-tls-peer-certificate-multi-keys.js
@@ -42,7 +42,10 @@ var server = tls.createServer(options, function(cleartext) {
cleartext.end('World');
});
server.listen(common.PORT, function() {
- var socket = tls.connect({port: common.PORT}, function() {
+ var socket = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
var peerCert = socket.getPeerCertificate();
common.debug(util.inspect(peerCert));
assert.deepEqual(peerCert.subject.OU,
diff --git a/test/simple/test-tls-peer-certificate.js b/test/simple/test-tls-peer-certificate.js
index ea3245a56..2f0b72797 100644
--- a/test/simple/test-tls-peer-certificate.js
+++ b/test/simple/test-tls-peer-certificate.js
@@ -42,7 +42,10 @@ var server = tls.createServer(options, function(cleartext) {
cleartext.end('World');
});
server.listen(common.PORT, function() {
- var socket = tls.connect({port: common.PORT}, function() {
+ var socket = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
var peerCert = socket.getPeerCertificate();
common.debug(util.inspect(peerCert));
assert.equal(peerCert.subject.subjectAltName,
diff --git a/test/simple/test-tls-remote.js b/test/simple/test-tls-remote.js
index 9aa51ab41..c711a294a 100644
--- a/test/simple/test-tls-remote.js
+++ b/test/simple/test-tls-remote.js
@@ -48,7 +48,11 @@ server.listen(common.PORT, '127.0.0.1', function() {
assert.equal(server.address().address, '127.0.0.1');
assert.equal(server.address().port, common.PORT);
- var c = tls.connect({port: common.PORT, host: '127.0.0.1'}, function() {
+ var c = tls.connect({
+ host: '127.0.0.1',
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
assert.equal(c.address().address, c.socket.address().address);
assert.equal(c.address().port, c.socket.address().port);
diff --git a/test/simple/test-tls-request-timeout.js b/test/simple/test-tls-request-timeout.js
index c44ecef3f..7f46bd213 100644
--- a/test/simple/test-tls-request-timeout.js
+++ b/test/simple/test-tls-request-timeout.js
@@ -42,7 +42,10 @@ var server = tls.Server(options, function(socket) {
});
server.listen(common.PORT, function() {
- var socket = tls.connect({port: common.PORT});
+ var socket = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ });
});
process.on('exit', function() {
diff --git a/test/simple/test-tls-server-missing-options.js b/test/simple/test-tls-server-missing-options.js
new file mode 100644
index 000000000..53846d1f2
--- /dev/null
+++ b/test/simple/test-tls-server-missing-options.js
@@ -0,0 +1,38 @@
+// 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.
+
+if (!process.versions.openssl) {
+ console.error('Skipping because node compiled without OpenSSL.');
+ process.exit(0);
+}
+
+var common = require('../common');
+var assert = require('assert');
+var https = require('https');
+var tls = require('tls');
+
+assert.throws(function() {
+ tls.createServer({ /* empty */}).listen(0);
+}, /missing.+certificate/i);
+
+assert.throws(function() {
+ https.createServer({ /* empty */}).listen(0);
+}, /missing.+certificate/i);
diff --git a/test/simple/test-tls-server-slab.js b/test/simple/test-tls-server-slab.js
new file mode 100644
index 000000000..de4ac01f4
--- /dev/null
+++ b/test/simple/test-tls-server-slab.js
@@ -0,0 +1,66 @@
+// 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');
+var assert = require('assert');
+var tls = require('tls');
+var fs = require('fs');
+
+var clientConnected = 0;
+var serverConnected = 0;
+
+var options = {
+ key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
+ cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
+};
+
+tls.SLAB_BUFFER_SIZE = 100 * 1024;
+
+var server = tls.Server(options, function(socket) {
+ assert(socket._buffer.pool.length == tls.SLAB_BUFFER_SIZE);
+ if (++serverConnected === 2) {
+ server.close();
+ }
+});
+
+server.listen(common.PORT, function() {
+ var client1 = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
+ ++clientConnected;
+ client1.end();
+ });
+
+ var client2 = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ });
+ client2.on('secureConnect', function() {
+ ++clientConnected;
+ client2.end();
+ });
+});
+
+process.on('exit', function() {
+ assert.equal(clientConnected, 2);
+ assert.equal(serverConnected, 2);
+});
diff --git a/test/simple/test-tls-session-cache.js b/test/simple/test-tls-session-cache.js
index 64e419935..695a75984 100644
--- a/test/simple/test-tls-session-cache.js
+++ b/test/simple/test-tls-session-cache.js
@@ -50,18 +50,43 @@ function doTest() {
requestCert: true
};
var requestCount = 0;
+ var session;
var server = tls.createServer(options, function(cleartext) {
+ cleartext.on('error', function(er) {
+ // We're ok with getting ECONNRESET in this test, but it's
+ // timing-dependent, and thus unreliable. Any other errors
+ // are just failures, though.
+ if (er.code !== 'ECONNRESET')
+ throw er;
+ });
++requestCount;
cleartext.end();
});
+ server.on('newSession', function(id, data) {
+ assert.ok(!session);
+ session = {
+ id: id,
+ data: data
+ };
+ });
+ server.on('resumeSession', function(id, callback) {
+ assert.ok(session);
+ assert.equal(session.id.toString('hex'), id.toString('hex'));
+
+ // Just to check that async really works there
+ setTimeout(function() {
+ callback(null, session.data);
+ }, 100);
+ });
server.listen(common.PORT, function() {
var client = spawn('openssl', [
's_client',
'-connect', 'localhost:' + common.PORT,
'-key', join(common.fixturesDir, 'agent.key'),
'-cert', join(common.fixturesDir, 'agent.crt'),
- '-reconnect'
+ '-reconnect',
+ '-no_ticket'
], {
customFds: [0, 1, 2]
});
@@ -72,6 +97,8 @@ function doTest() {
});
process.on('exit', function() {
+ assert.ok(session);
+
// initial request + reconnect requests (5 times)
assert.equal(requestCount, 6);
});
diff --git a/test/simple/test-tls-set-ciphers.js b/test/simple/test-tls-set-ciphers.js
index 576094dcb..a473a1d26 100644
--- a/test/simple/test-tls-set-ciphers.js
+++ b/test/simple/test-tls-set-ciphers.js
@@ -33,7 +33,7 @@ if (process.platform === 'win32') {
var options = {
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'),
- ciphers: 'NULL-MD5' // it's ultra-fast!
+ ciphers: 'RC4-MD5'
};
var reply = 'I AM THE WALRUS'; // something recognizable
@@ -51,8 +51,8 @@ var server = tls.createServer(options, function(conn) {
});
server.listen(common.PORT, '127.0.0.1', function() {
- var cmd = 'openssl s_client -cipher NULL-MD5 -connect 127.0.0.1:' +
- common.PORT;
+ var cmd = 'openssl s_client -cipher ' + options.ciphers +
+ ' -connect 127.0.0.1:' + common.PORT;
exec(cmd, function(err, stdout, stderr) {
if (err) throw err;
diff --git a/test/simple/test-tls-set-encoding.js b/test/simple/test-tls-set-encoding.js
index 8850a677e..0f6beafd1 100644
--- a/test/simple/test-tls-set-encoding.js
+++ b/test/simple/test-tls-set-encoding.js
@@ -41,7 +41,10 @@ var server = tls.Server(options, function(socket) {
server.listen(common.PORT, function() {
- var client = tls.connect({port: common.PORT});
+ var client = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ });
var buffer = '';
diff --git a/test/simple/test-tls-sni-server-client.js b/test/simple/test-tls-sni-server-client.js
index 093d0fd11..8de57e2d4 100644
--- a/test/simple/test-tls-sni-server-client.js
+++ b/test/simple/test-tls-sni-server-client.js
@@ -64,19 +64,22 @@ var clientsOptions = [{
key: loadPEM('agent1-key'),
cert: loadPEM('agent1-cert'),
ca: [loadPEM('ca1-cert')],
- servername: 'a.example.com'
+ servername: 'a.example.com',
+ rejectUnauthorized: false
},{
port: serverPort,
key: loadPEM('agent2-key'),
cert: loadPEM('agent2-cert'),
ca: [loadPEM('ca2-cert')],
- servername: 'b.test.com'
+ servername: 'b.test.com',
+ rejectUnauthorized: false
},{
port: serverPort,
key: loadPEM('agent3-key'),
cert: loadPEM('agent3-cert'),
ca: [loadPEM('ca1-cert')],
- servername: 'c.wrong.com'
+ servername: 'c.wrong.com',
+ rejectUnauthorized: false
}];
var serverResults = [],
diff --git a/test/simple/test-tls-timeout-server-2.js b/test/simple/test-tls-timeout-server-2.js
new file mode 100644
index 000000000..dfa9be3de
--- /dev/null
+++ b/test/simple/test-tls-timeout-server-2.js
@@ -0,0 +1,47 @@
+// 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.
+
+if (!process.versions.openssl) process.exit();
+
+var common = require('../common');
+var assert = require('assert');
+var tls = require('tls');
+var fs = require('fs');
+
+var options = {
+ key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
+ cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
+};
+
+var server = tls.createServer(options, function(cleartext) {
+ cleartext.setTimeout(50, function() {
+ cleartext.destroy();
+ server.close();
+ });
+});
+
+server.listen(common.PORT, function() {
+ tls.connect({
+ host: '127.0.0.1',
+ port: common.PORT,
+ rejectUnauthorized: false
+ });
+});
diff --git a/test/simple/test-tls-timeout-server.js b/test/simple/test-tls-timeout-server.js
new file mode 100644
index 000000000..2c9b973ab
--- /dev/null
+++ b/test/simple/test-tls-timeout-server.js
@@ -0,0 +1,52 @@
+// 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.
+
+if (!process.versions.openssl) process.exit();
+
+var common = require('../common');
+var assert = require('assert');
+var net = require('net');
+var tls = require('tls');
+var fs = require('fs');
+
+var clientErrors = 0;
+
+process.on('exit', function() {
+ assert.equal(clientErrors, 1);
+});
+
+var options = {
+ key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
+ cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem'),
+ handshakeTimeout: 50
+};
+
+var server = tls.createServer(options, assert.fail);
+
+server.on('clientError', function(err, conn) {
+ conn.destroy();
+ server.close();
+ clientErrors++;
+});
+
+server.listen(common.PORT, function() {
+ net.connect({ host: '127.0.0.1', port: common.PORT });
+});
diff --git a/test/simple/test-tty-wrap.js b/test/simple/test-tty-wrap.js
index da661c401..610b92b43 100644
--- a/test/simple/test-tty-wrap.js
+++ b/test/simple/test-tty-wrap.js
@@ -33,20 +33,16 @@ if (isTTY(1) == false) {
var handle = new TTY(1);
var callbacks = 0;
-var req1 = handle.write(Buffer('hello world\n'));
+var req1 = handle.writeBuffer(Buffer('hello world\n'));
req1.oncomplete = function() {
callbacks++;
};
-var req2 = handle.write(Buffer('hello world\n'));
+var req2 = handle.writeBuffer(Buffer('hello world\n'));
req2.oncomplete = function() {
callbacks++;
};
-handle.close();
-
process.on('exit', function() {
assert.equal(2, callbacks);
});
-
-
diff --git a/test/simple/test-typed-arrays.js b/test/simple/test-typed-arrays.js
index cf6b76007..9b55ee87c 100644
--- a/test/simple/test-typed-arrays.js
+++ b/test/simple/test-typed-arrays.js
@@ -47,34 +47,22 @@ var assert = require('assert');
assert.equal(obj.toString(), expected);
assert.equal(Object.prototype.toString.call(obj), expected);
- obj = new DataView(obj);
+ obj = new DataView(obj.buffer || obj);
assert.equal(obj.toString(), '[object DataView]');
assert.equal(Object.prototype.toString.call(obj), '[object DataView]');
-});
-// initialize a zero-filled buffer
-var buffer = new Buffer(16);
-buffer.fill(0);
-
-// only one of these instantiations should succeed, as the other ones will be
-// unaligned
-var errors = 0;
-var offset;
-for (var i = 0; i < 8; i++) {
- try {
- new Float64Array(buffer, i);
- offset = i;
- } catch (e) {
- errors += 1;
- }
-}
+ // Calling constructor as function should work.
+ clazz(32);
+});
-assert.equal(errors, 7);
+// Calling constructor as function should work.
+DataView(ArrayBuffer(32));
-var uint8 = new Uint8Array(buffer, offset);
-var uint16 = new Uint16Array(buffer, offset);
-var uint16slice = new Uint16Array(buffer, offset + 2, 2);
-var uint32 = new Uint32Array(buffer, offset);
+var buffer = new ArrayBuffer(16);
+var uint8 = new Uint8Array(buffer);
+var uint16 = new Uint16Array(buffer);
+var uint16slice = new Uint16Array(buffer, 2, 2);
+var uint32 = new Uint32Array(buffer);
assert.equal(uint8.BYTES_PER_ELEMENT, 1);
assert.equal(uint16.BYTES_PER_ELEMENT, 2);
@@ -82,14 +70,14 @@ assert.equal(uint16slice.BYTES_PER_ELEMENT, 2);
assert.equal(uint32.BYTES_PER_ELEMENT, 4);
// now change the underlying buffer
-buffer[offset ] = 0x08;
-buffer[offset + 1] = 0x09;
-buffer[offset + 2] = 0x0a;
-buffer[offset + 3] = 0x0b;
-buffer[offset + 4] = 0x0c;
-buffer[offset + 5] = 0x0d;
-buffer[offset + 6] = 0x0e;
-buffer[offset + 7] = 0x0f;
+buffer[0] = 0x08;
+buffer[1] = 0x09;
+buffer[2] = 0x0a;
+buffer[3] = 0x0b;
+buffer[4] = 0x0c;
+buffer[5] = 0x0d;
+buffer[6] = 0x0e;
+buffer[7] = 0x0f;
/*
This is what we expect the variables to look like at this point (on
@@ -192,3 +180,70 @@ assert.throws(function() {
var buf = new DataView(new ArrayBuffer(8));
buf.setFloat64(0xffffffff, 0.0, true);
}, /Index out of range/);
+
+// DataView::setGeneric() default endianness regression test,
+// see https://github.com/joyent/node/issues/4626
+(function() {
+ var buf = new Uint8Array(2);
+ var view = new DataView(buf.buffer);
+ view.setUint16(0, 1);
+ assert.equal(view.getUint16(0), 1);
+})();
+
+(function() {
+ // Typed array should make a copy of the buffer object, i.e. it's not shared.
+ var b = new Buffer([0]);
+ var a = new Uint8Array(b);
+ assert.notEqual(a.buffer, b);
+ assert.equal(a[0], 0);
+ assert.equal(b[0], 0);
+ a[0] = 1;
+ assert.equal(a[0], 1);
+ assert.equal(b[0], 0);
+ a[0] = 0;
+ b[0] = 1;
+ assert.equal(a[0], 0);
+ assert.equal(b[0], 1);
+})();
+
+(function() {
+ // Backing store should not be shared.
+ var a = new Uint8Array(1);
+ var b = new Uint8Array(a);
+ a[0] = 0;
+ b[0] = 1;
+ assert.equal(a[0], 0);
+ assert.equal(b[0], 1);
+ assert.notEqual(a, b.buffer);
+ assert.notEqual(a.buffer, b.buffer);
+})();
+
+(function() {
+ // Backing store should not be shared.
+ var a = new Uint8Array(2);
+ var b = new Uint16Array(a);
+ a[0] = 0;
+ a[1] = 0;
+ b[0] = 257;
+ assert.equal(a[0], 0);
+ assert.equal(a[1], 0);
+ assert.equal(b[0], 257);
+ assert.notEqual(a, b.buffer);
+ assert.notEqual(a.buffer, b.buffer);
+})();
+
+(function() {
+ // Backing store should be shared.
+ var abuf = new ArrayBuffer(32);
+ var a = new Uint8Array(abuf);
+ var b = new Uint8Array(abuf);
+ a[0] = 0;
+ b[0] = 1;
+ assert.equal(a[0], 1);
+ assert.equal(b[0], 1);
+ assert.equal(a.buffer, b.buffer);
+})();
+
+assert.throws(function() {
+ new DataView(new Int8Array(1));
+});
diff --git a/test/simple/test-url.js b/test/simple/test-url.js
index 764a541b6..6630da102 100644
--- a/test/simple/test-url.js
+++ b/test/simple/test-url.js
@@ -748,6 +748,12 @@ for (var u in parseTests) {
spaced = url.parse(' \t ' + u + '\n\t');
expected = parseTests[u];
+ Object.keys(actual).forEach(function (i) {
+ if (expected[i] === undefined && actual[i] === null) {
+ expected[i] = null;
+ }
+ });
+
assert.deepEqual(actual, expected);
assert.deepEqual(spaced, expected);
@@ -784,6 +790,11 @@ var parseTestsWithQueryString = {
for (var u in parseTestsWithQueryString) {
var actual = url.parse(u, true);
var expected = parseTestsWithQueryString[u];
+ for (var i in actual) {
+ if (actual[i] === null && expected[i] === undefined) {
+ expected[i] = null;
+ }
+ }
assert.deepEqual(actual, expected);
}
@@ -932,6 +943,50 @@ var formatTests = {
'protocol': 'coap',
'host': '[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616',
'pathname': '/s/stopButton'
+ },
+
+ // encode context-specific delimiters in path and query, but do not touch
+ // other non-delimiter chars like `%`.
+ // <https://github.com/joyent/node/issues/4082>
+
+ // `#`,`?` in path
+ '/path/to/%%23%3F+=&.txt?foo=theA1#bar' : {
+ href : '/path/to/%%23%3F+=&.txt?foo=theA1#bar',
+ pathname: '/path/to/%#?+=&.txt',
+ query: {
+ foo: 'theA1'
+ },
+ hash: "#bar"
+ },
+
+ // `#`,`?` in path + `#` in query
+ '/path/to/%%23%3F+=&.txt?foo=the%231#bar' : {
+ href : '/path/to/%%23%3F+=&.txt?foo=the%231#bar',
+ pathname: '/path/to/%#?+=&.txt',
+ query: {
+ foo: 'the#1'
+ },
+ hash: "#bar"
+ },
+
+ // `?` and `#` in path and search
+ 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag': {
+ href: 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag',
+ protocol: 'http:',
+ hostname: 'ex.com',
+ hash: '#frag',
+ search: '?abc=the#1?&foo=bar',
+ pathname: '/foo?100%m#r',
+ },
+
+ // `?` and `#` in search only
+ 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag': {
+ href: 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag',
+ protocol: 'http:',
+ hostname: 'ex.com',
+ hash: '#frag',
+ search: '?abc=the#1?&foo=bar',
+ pathname: '/fooA100%mBr',
}
};
for (var u in formatTests) {
@@ -1316,15 +1371,6 @@ relativeTests.forEach(function(relativeTest) {
var actual = url.resolveObject(url.parse(relativeTest[0]), relativeTest[1]),
expected = url.parse(relativeTest[2]);
- //because of evaluation order
- //resolveObject(parse(x), y) == parse(resolve(x, y)) will differ by
- //false-ish values. remove all except host and hostname
- for (var i in actual) {
- if (actual[i] === undefined ||
- (!emptyIsImportant.hasOwnProperty(i) && !actual[i])) {
- delete actual[i];
- }
- }
assert.deepEqual(actual, expected);
@@ -1353,16 +1399,6 @@ relativeTests2.forEach(function(relativeTest) {
var actual = url.resolveObject(url.parse(relativeTest[1]), relativeTest[0]),
expected = url.parse(relativeTest[2]);
- //because of evaluation order
- //resolveObject(parse(x), y) == parse(resolve(x, y)) will differ by
- //false-ish values. remove all except host and hostname
- for (var i in actual) {
- if (actual[i] === undefined ||
- (!emptyIsImportant.hasOwnProperty(i) && !actual[i])) {
- delete actual[i];
- }
- }
-
assert.deepEqual(actual, expected);
var expected = relativeTest[2],
diff --git a/test/simple/test-util-inspect.js b/test/simple/test-util-inspect.js
index b6f5bfa8d..0b04c93c7 100644
--- a/test/simple/test-util-inspect.js
+++ b/test/simple/test-util-inspect.js
@@ -77,8 +77,6 @@ var ex = util.inspect(new Error('FAIL'), true);
assert.ok(ex.indexOf('[Error: FAIL]') != -1);
assert.ok(ex.indexOf('[stack]') != -1);
assert.ok(ex.indexOf('[message]') != -1);
-assert.ok(ex.indexOf('[arguments]') != -1);
-assert.ok(ex.indexOf('[type]') != -1);
// GH-1941
// should not throw:
@@ -108,9 +106,52 @@ assert.doesNotThrow(function() {
var x = { inspect: util.inspect };
assert.ok(util.inspect(x).indexOf('inspect') != -1);
+// util.inspect.styles and util.inspect.colors
+function test_color_style(style, input, implicit) {
+ var color_name = util.inspect.styles[style];
+ var color = ['', ''];
+ if(util.inspect.colors[color_name])
+ color = util.inspect.colors[color_name];
+
+ var without_color = util.inspect(input, false, 0, false);
+ var with_color = util.inspect(input, false, 0, true);
+ var expect = '\u001b[' + color[0] + 'm' + without_color +
+ '\u001b[' + color[1] + 'm';
+ assert.equal(with_color, expect, 'util.inspect color for style '+style);
+}
+
+test_color_style('special', function(){});
+test_color_style('number', 123.456);
+test_color_style('boolean', true);
+test_color_style('undefined', undefined);
+test_color_style('null', null);
+test_color_style('string', 'test string');
+test_color_style('date', new Date);
+test_color_style('regexp', /regexp/);
+
// an object with "hasOwnProperty" overwritten should not throw
assert.doesNotThrow(function() {
util.inspect({
hasOwnProperty: null
});
});
+
+// new API, accepts an "options" object
+var subject = { foo: 'bar', hello: 31, a: { b: { c: { d: 0 } } } };
+Object.defineProperty(subject, 'hidden', { enumerable: false, value: null });
+
+assert(util.inspect(subject, { showHidden: false }).indexOf('hidden') === -1);
+assert(util.inspect(subject, { showHidden: true }).indexOf('hidden') !== -1);
+assert(util.inspect(subject, { colors: false }).indexOf('\u001b[32m') === -1);
+assert(util.inspect(subject, { colors: true }).indexOf('\u001b[32m') !== -1);
+assert(util.inspect(subject, { depth: 2 }).indexOf('c: [Object]') !== -1);
+assert(util.inspect(subject, { depth: 0 }).indexOf('a: [Object]') !== -1);
+assert(util.inspect(subject, { depth: null }).indexOf('{ d: 0 }') !== -1);
+
+// "customInspect" option can enable/disable calling inspect() on objects
+subject = { inspect: function() { return 123; } };
+
+assert(util.inspect(subject, { customInspect: true }).indexOf('123') !== -1);
+assert(util.inspect(subject, { customInspect: true }).indexOf('inspect') === -1);
+assert(util.inspect(subject, { customInspect: false }).indexOf('123') === -1);
+assert(util.inspect(subject, { customInspect: false }).indexOf('inspect') !== -1);
diff --git a/test/simple/test-writedouble.js b/test/simple/test-writedouble.js
index 829ba29a7..69bed9249 100644
--- a/test/simple/test-writedouble.js
+++ b/test/simple/test-writedouble.js
@@ -123,6 +123,69 @@ function test(clazz) {
ASSERT.equal(0x00, buffer[13]);
ASSERT.equal(0x00, buffer[14]);
ASSERT.equal(0x80, buffer[15]);
+
+ buffer.writeDoubleBE(Infinity, 0);
+ buffer.writeDoubleLE(Infinity, 8);
+ ASSERT.equal(0x7F, buffer[0]);
+ ASSERT.equal(0xF0, buffer[1]);
+ ASSERT.equal(0x00, buffer[2]);
+ ASSERT.equal(0x00, buffer[3]);
+ ASSERT.equal(0x00, buffer[4]);
+ ASSERT.equal(0x00, buffer[5]);
+ ASSERT.equal(0x00, buffer[6]);
+ ASSERT.equal(0x00, buffer[7]);
+ ASSERT.equal(0x00, buffer[8]);
+ ASSERT.equal(0x00, buffer[9]);
+ ASSERT.equal(0x00, buffer[10]);
+ ASSERT.equal(0x00, buffer[11]);
+ ASSERT.equal(0x00, buffer[12]);
+ ASSERT.equal(0x00, buffer[13]);
+ ASSERT.equal(0xF0, buffer[14]);
+ ASSERT.equal(0x7F, buffer[15]);
+ ASSERT.equal(Infinity, buffer.readDoubleBE(0));
+ ASSERT.equal(Infinity, buffer.readDoubleLE(8));
+
+ buffer.writeDoubleBE(-Infinity, 0);
+ buffer.writeDoubleLE(-Infinity, 8);
+ ASSERT.equal(0xFF, buffer[0]);
+ ASSERT.equal(0xF0, buffer[1]);
+ ASSERT.equal(0x00, buffer[2]);
+ ASSERT.equal(0x00, buffer[3]);
+ ASSERT.equal(0x00, buffer[4]);
+ ASSERT.equal(0x00, buffer[5]);
+ ASSERT.equal(0x00, buffer[6]);
+ ASSERT.equal(0x00, buffer[7]);
+ ASSERT.equal(0x00, buffer[8]);
+ ASSERT.equal(0x00, buffer[9]);
+ ASSERT.equal(0x00, buffer[10]);
+ ASSERT.equal(0x00, buffer[11]);
+ ASSERT.equal(0x00, buffer[12]);
+ ASSERT.equal(0x00, buffer[13]);
+ ASSERT.equal(0xF0, buffer[14]);
+ ASSERT.equal(0xFF, buffer[15]);
+ ASSERT.equal(-Infinity, buffer.readDoubleBE(0));
+ ASSERT.equal(-Infinity, buffer.readDoubleLE(8));
+
+ buffer.writeDoubleBE(NaN, 0);
+ buffer.writeDoubleLE(NaN, 8);
+ ASSERT.equal(0x7F, buffer[0]);
+ ASSERT.equal(0xF8, buffer[1]);
+ ASSERT.equal(0x00, buffer[2]);
+ ASSERT.equal(0x00, buffer[3]);
+ ASSERT.equal(0x00, buffer[4]);
+ ASSERT.equal(0x00, buffer[5]);
+ ASSERT.equal(0x00, buffer[6]);
+ ASSERT.equal(0x00, buffer[7]);
+ ASSERT.equal(0x00, buffer[8]);
+ ASSERT.equal(0x00, buffer[9]);
+ ASSERT.equal(0x00, buffer[10]);
+ ASSERT.equal(0x00, buffer[11]);
+ ASSERT.equal(0x00, buffer[12]);
+ ASSERT.equal(0x00, buffer[13]);
+ ASSERT.equal(0xF8, buffer[14]);
+ ASSERT.equal(0x7F, buffer[15]);
+ ASSERT.ok(isNaN(buffer.readDoubleBE(0)));
+ ASSERT.ok(isNaN(buffer.readDoubleLE(8)));
}
diff --git a/test/simple/test-writefloat.js b/test/simple/test-writefloat.js
index d10cb7547..626a11f19 100644
--- a/test/simple/test-writefloat.js
+++ b/test/simple/test-writefloat.js
@@ -40,17 +40,6 @@ function test(clazz) {
ASSERT.equal(0x80, buffer[6]);
ASSERT.equal(0x3f, buffer[7]);
- buffer.writeFloatBE(1.793662034335766e-43, 0);
- buffer.writeFloatLE(1.793662034335766e-43, 4);
- ASSERT.equal(0x00, buffer[0]);
- ASSERT.equal(0x00, buffer[1]);
- ASSERT.equal(0x00, buffer[2]);
- ASSERT.equal(0x80, buffer[3]);
- ASSERT.equal(0x80, buffer[4]);
- ASSERT.equal(0x00, buffer[5]);
- ASSERT.equal(0x00, buffer[6]);
- ASSERT.equal(0x00, buffer[7]);
-
buffer.writeFloatBE(1 / 3, 0);
buffer.writeFloatLE(1 / 3, 4);
ASSERT.equal(0x3e, buffer[0]);
@@ -73,6 +62,17 @@ function test(clazz) {
ASSERT.equal(0x7f, buffer[6]);
ASSERT.equal(0x7f, buffer[7]);
+ buffer.writeFloatLE(1.1754943508222875e-38, 0);
+ buffer.writeFloatBE(1.1754943508222875e-38, 4);
+ ASSERT.equal(0x00, buffer[0]);
+ ASSERT.equal(0x00, buffer[1]);
+ ASSERT.equal(0x80, buffer[2]);
+ ASSERT.equal(0x00, buffer[3]);
+ ASSERT.equal(0x00, buffer[4]);
+ ASSERT.equal(0x80, buffer[5]);
+ ASSERT.equal(0x00, buffer[6]);
+ ASSERT.equal(0x00, buffer[7]);
+
buffer.writeFloatBE(0 * -1, 0);
buffer.writeFloatLE(0 * -1, 4);
ASSERT.equal(0x80, buffer[0]);
@@ -83,6 +83,45 @@ function test(clazz) {
ASSERT.equal(0x00, buffer[5]);
ASSERT.equal(0x00, buffer[6]);
ASSERT.equal(0x80, buffer[7]);
+
+ buffer.writeFloatBE(Infinity, 0);
+ buffer.writeFloatLE(Infinity, 4);
+ ASSERT.equal(0x7F, buffer[0]);
+ ASSERT.equal(0x80, buffer[1]);
+ ASSERT.equal(0x00, buffer[2]);
+ ASSERT.equal(0x00, buffer[3]);
+ ASSERT.equal(0x00, buffer[4]);
+ ASSERT.equal(0x00, buffer[5]);
+ ASSERT.equal(0x80, buffer[6]);
+ ASSERT.equal(0x7F, buffer[7]);
+ ASSERT.equal(Infinity, buffer.readFloatBE(0));
+ ASSERT.equal(Infinity, buffer.readFloatLE(4));
+
+ buffer.writeFloatBE(-Infinity, 0);
+ buffer.writeFloatLE(-Infinity, 4);
+ ASSERT.equal(0xFF, buffer[0]);
+ ASSERT.equal(0x80, buffer[1]);
+ ASSERT.equal(0x00, buffer[2]);
+ ASSERT.equal(0x00, buffer[3]);
+ ASSERT.equal(0x00, buffer[4]);
+ ASSERT.equal(0x00, buffer[5]);
+ ASSERT.equal(0x80, buffer[6]);
+ ASSERT.equal(0xFF, buffer[7]);
+ ASSERT.equal(-Infinity, buffer.readFloatBE(0));
+ ASSERT.equal(-Infinity, buffer.readFloatLE(4));
+
+ buffer.writeFloatBE(NaN, 0);
+ buffer.writeFloatLE(NaN, 4);
+ ASSERT.equal(0x7F, buffer[0]);
+ ASSERT.equal(0xc0, buffer[1]);
+ ASSERT.equal(0x00, buffer[2]);
+ ASSERT.equal(0x00, buffer[3]);
+ ASSERT.equal(0x00, buffer[4]);
+ ASSERT.equal(0x00, buffer[5]);
+ ASSERT.equal(0xc0, buffer[6]);
+ ASSERT.equal(0x7F, buffer[7]);
+ ASSERT.ok(isNaN(buffer.readFloatBE(0)));
+ ASSERT.ok(isNaN(buffer.readFloatLE(4)));
}
diff --git a/test/simple/test-zlib-destroy.js b/test/simple/test-zlib-destroy.js
deleted file mode 100644
index 7a1120e28..000000000
--- a/test/simple/test-zlib-destroy.js
+++ /dev/null
@@ -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');
-var assert = require('assert');
-var zlib = require('zlib');
-
-['Deflate', 'Inflate', 'Gzip', 'Gunzip', 'DeflateRaw', 'InflateRaw', 'Unzip']
- .forEach(function (name) {
- var a = false;
- var zStream = new zlib[name]();
- zStream.on('close', function () {
- a = true;
- });
- zStream.destroy();
-
- assert.equal(a, true, name+'#destroy() must emit \'close\'');
- });
diff --git a/test/simple/test-zlib-invalid-input.js b/test/simple/test-zlib-invalid-input.js
index f97c5831a..c3d8b5b47 100644
--- a/test/simple/test-zlib-invalid-input.js
+++ b/test/simple/test-zlib-invalid-input.js
@@ -50,13 +50,6 @@ unzips.forEach(function (uz, i) {
uz.on('error', function(er) {
console.error('Error event', er);
hadError[i] = true;
-
- // to be friendly to the Stream API, zlib objects just return true and
- // ignore data on the floor after an error. It's up to the user to
- // catch the 'error' event and do something intelligent. They do not
- // emit any more data, however.
- assert.equal(uz.write('also invalid'), true);
- assert.equal(uz.end(), true);
});
uz.on('end', function(er) {
diff --git a/test/simple/test-zlib-random-byte-pipes.js b/test/simple/test-zlib-random-byte-pipes.js
index f9723cc40..fc1db1cbb 100644
--- a/test/simple/test-zlib-random-byte-pipes.js
+++ b/test/simple/test-zlib-random-byte-pipes.js
@@ -150,8 +150,25 @@ var inp = new RandomReadStream({ total: 1024, block: 256, jitter: 16 });
var out = new HashStream();
var gzip = zlib.createGzip();
var gunz = zlib.createGunzip();
+
inp.pipe(gzip).pipe(gunz).pipe(out);
+inp.on('data', function(c) {
+ console.error('inp data', c.length);
+});
+
+gzip.on('data', function(c) {
+ console.error('gzip data', c.length);
+});
+
+gunz.on('data', function(c) {
+ console.error('gunz data', c.length);
+});
+
+out.on('data', function(c) {
+ console.error('out data', c.length);
+});
+
var didSomething = false;
out.on('data', function(c) {
didSomething = true;
diff --git a/tools/addon.gypi b/tools/addon.gypi
deleted file mode 100644
index 89e71c0c5..000000000
--- a/tools/addon.gypi
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- 'target_defaults': {
- 'type': 'loadable_module',
- 'product_extension': 'node',
- 'product_prefix': '',
- 'include_dirs': [
- '<(node_root_dir)/src',
- '<(node_root_dir)/deps/uv/include',
- '<(node_root_dir)/deps/v8/include'
- ],
-
- 'conditions': [
- [ 'OS=="mac"', {
- 'libraries': [ '-undefined dynamic_lookup' ],
- }],
- [ 'OS=="win"', {
- 'libraries': [ '-l<(node_root_dir)/$(Configuration)/node.lib' ],
- }],
- [ 'OS=="freebsd" or OS=="openbsd" or OS=="solaris" or (OS=="linux" and target_arch!="ia32")', {
- 'cflags': [ '-fPIC' ],
- }]
- ]
- }
-}
diff --git a/tools/doc/html.js b/tools/doc/html.js
index 63c7c1407..087f726a3 100644
--- a/tools/doc/html.js
+++ b/tools/doc/html.js
@@ -69,6 +69,11 @@ function parseLists(input) {
var output = [];
output.links = input.links;
input.forEach(function(tok) {
+ if (tok.type === 'code' && tok.text.match(/Stability:.*/g)) {
+ tok.text = parseAPIHeader(tok.text);
+ output.push({ type: 'html', text: tok.text });
+ return;
+ }
if (state === null) {
if (tok.type === 'heading') {
state = 'AFTERHEADING';
@@ -122,6 +127,11 @@ function parseListItem(text) {
return text;
}
+function parseAPIHeader(text) {
+ text = text.replace(/(.*:)\s(\d)([\s\S]*)/,
+ '<pre class="api_stability_$2">$1 $2$3</pre>');
+ return text;
+}
// section is just the first heading
function getSection(lexed) {
diff --git a/tools/genv8constants.py b/tools/genv8constants.py
index efc644152..45b4ae317 100755
--- a/tools/genv8constants.py
+++ b/tools/genv8constants.py
@@ -10,16 +10,32 @@
import re
import subprocess
import sys
+import errno
if len(sys.argv) != 3:
print "usage: objsym.py outfile libv8_base.a"
sys.exit(2);
outfile = file(sys.argv[1], 'w');
-pipe = subprocess.Popen([ 'objdump', '-z', '-D', sys.argv[2] ],
- bufsize=-1, stdout=subprocess.PIPE).stdout;
-pattern = re.compile('00000000 <(v8dbg_.*)>:');
-numpattern = re.compile('[0-9a-fA-F]{2}');
+try:
+ pipe = subprocess.Popen([ 'objdump', '-z', '-D', sys.argv[2] ],
+ bufsize=-1, stdout=subprocess.PIPE).stdout;
+except OSError, e:
+ if e.errno == errno.ENOENT:
+ print '''
+ Node.js compile error: could not find objdump
+
+ Check that GNU binutils are installed and included in PATH
+ '''
+ else:
+ print 'problem running objdump: ', e.strerror
+
+ sys.exit()
+
+pattern = re.compile('([0-9a-fA-F]{8}|[0-9a-fA-F]{16}) <(.*)>:');
+v8dbg = re.compile('^v8dbg.*$')
+numpattern = re.compile('^[0-9a-fA-F]{2} $');
+octets = 4
outfile.write("""
/*
@@ -32,13 +48,29 @@ outfile.write("""
#ifndef V8_CONSTANTS_H
#define V8_CONSTANTS_H
-#if defined(__i386)
""");
curr_sym = None;
curr_val = 0;
curr_octet = 0;
+def out_reset():
+ global curr_sym, curr_val, curr_octet
+ curr_sym = None;
+ curr_val = 0;
+ curr_octet = 0;
+
+def out_define():
+ global curr_sym, curr_val, curr_octet, outfile, octets
+ if curr_sym != None:
+ wrapped_val = curr_val & 0xffffffff;
+ if curr_val & 0x80000000 != 0:
+ wrapped_val = 0x100000000 - wrapped_val;
+ outfile.write("#define %s -0x%x\n" % (curr_sym.upper(), wrapped_val));
+ else:
+ outfile.write("#define %s 0x%x\n" % (curr_sym.upper(), wrapped_val));
+ out_reset();
+
for line in pipe:
if curr_sym != None:
#
@@ -51,32 +83,32 @@ for line in pipe:
for i in range (0, 3):
# 6-character margin, 2-characters + 1 space for each field
idx = 6 + i * 3;
- octetstr = line[idx:idx+2]
+ octetstr = line[idx:idx+3]
if not numpattern.match(octetstr):
break;
+ if curr_octet > octets:
+ break;
+
curr_val += int('0x%s' % octetstr, 16) << (curr_octet * 8);
curr_octet += 1;
- if curr_octet < 4:
- continue;
-
- outfile.write("#define %s 0x%x\n" % (curr_sym.upper(), curr_val));
- curr_sym = None;
- curr_val = 0;
- curr_octet = 0;
- continue;
-
match = pattern.match(line)
if match == None:
continue;
- curr_sym = match.group(1);
+ # Print previous symbol
+ out_define();
+
+ v8match = v8dbg.match(match.group(2));
+ if v8match != None:
+ out_reset();
+ curr_sym = match.group(2);
+
+# Print last symbol
+out_define();
outfile.write("""
-#else
-#error "only i386 is supported for DTrace ustack helper"
-#endif
#endif /* V8_CONSTANTS_H */
""");
diff --git a/tools/gyp/gyptest.py b/tools/gyp/gyptest.py
index c84f3d330..6c6b00944 100755
--- a/tools/gyp/gyptest.py
+++ b/tools/gyp/gyptest.py
@@ -171,7 +171,9 @@ def main(argv=None):
os.chdir(opts.chdir)
if opts.path:
- os.environ['PATH'] += ':' + ':'.join(opts.path)
+ extra_path = [os.path.abspath(p) for p in opts.path]
+ extra_path = os.pathsep.join(extra_path)
+ os.environ['PATH'] += os.pathsep + extra_path
if not args:
if not opts.all:
diff --git a/tools/gyp/pylib/gyp/MSVSNew.py b/tools/gyp/pylib/gyp/MSVSNew.py
index 086597378..253fe6198 100644
--- a/tools/gyp/pylib/gyp/MSVSNew.py
+++ b/tools/gyp/pylib/gyp/MSVSNew.py
@@ -59,7 +59,13 @@ def MakeGuid(name, seed='msvs_new'):
#------------------------------------------------------------------------------
-class MSVSFolder(object):
+class MSVSSolutionEntry(object):
+ def __cmp__(self, other):
+ # Sort by name then guid (so things are in order on vs2008).
+ return cmp((self.name, self.get_guid()), (other.name, other.get_guid()))
+
+
+class MSVSFolder(MSVSSolutionEntry):
"""Folder in a Visual Studio project or solution."""
def __init__(self, path, name = None, entries = None,
@@ -85,7 +91,7 @@ class MSVSFolder(object):
self.guid = guid
# Copy passed lists (or set to empty lists)
- self.entries = list(entries or [])
+ self.entries = sorted(list(entries or []))
self.items = list(items or [])
self.entry_type_guid = ENTRY_TYPE_GUIDS['folder']
@@ -100,7 +106,7 @@ class MSVSFolder(object):
#------------------------------------------------------------------------------
-class MSVSProject(object):
+class MSVSProject(MSVSSolutionEntry):
"""Visual Studio project."""
def __init__(self, path, name = None, dependencies = None, guid = None,
@@ -229,15 +235,7 @@ class MSVSSolution:
if isinstance(e, MSVSFolder):
entries_to_check += e.entries
- # Sort by name then guid (so things are in order on vs2008).
- def NameThenGuid(a, b):
- if a.name < b.name: return -1
- if a.name > b.name: return 1
- if a.get_guid() < b.get_guid(): return -1
- if a.get_guid() > b.get_guid(): return 1
- return 0
-
- all_entries = sorted(all_entries, NameThenGuid)
+ all_entries = sorted(all_entries)
# Open file and print header
f = writer(self.path)
diff --git a/tools/gyp/pylib/gyp/MSVSVersion.py b/tools/gyp/pylib/gyp/MSVSVersion.py
index eeec2e615..97caf6698 100644
--- a/tools/gyp/pylib/gyp/MSVSVersion.py
+++ b/tools/gyp/pylib/gyp/MSVSVersion.py
@@ -9,6 +9,7 @@ import os
import re
import subprocess
import sys
+import gyp
class VisualStudioVersion(object):
@@ -193,6 +194,8 @@ def _CreateVersion(name, path, sdk_based=False):
autodetected if GYP_MSVS_VERSION is not explicitly specified. If a version is
passed in that doesn't match a value in versions python will throw a error.
"""
+ if path:
+ path = os.path.normpath(path)
versions = {
'2012': VisualStudioVersion('2012',
'Visual Studio 2012',
@@ -264,6 +267,14 @@ def _CreateVersion(name, path, sdk_based=False):
return versions[str(name)]
+def _ConvertToCygpath(path):
+ """Convert to cygwin path if we are using cygwin."""
+ if sys.platform == 'cygwin':
+ p = subprocess.Popen(['cygpath', path], stdout=subprocess.PIPE)
+ path = p.communicate()[0].strip()
+ return path
+
+
def _DetectVisualStudioVersions(versions_to_check, force_express):
"""Collect the list of installed visual studio versions.
@@ -294,6 +305,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
path = _RegistryGetValue(keys[index], 'InstallDir')
if not path:
continue
+ path = _ConvertToCygpath(path)
# Check for full.
full_path = os.path.join(path, 'devenv.exe')
express_path = os.path.join(path, 'vcexpress.exe')
@@ -314,6 +326,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
path = _RegistryGetValue(keys[index], version)
if not path:
continue
+ path = _ConvertToCygpath(path)
versions.append(_CreateVersion(version_to_year[version] + 'e',
os.path.join(path, '..'), sdk_based=True))
diff --git a/tools/gyp/pylib/gyp/__init__.py b/tools/gyp/pylib/gyp/__init__.py
index 54488e5e6..ac300a903 100755
--- a/tools/gyp/pylib/gyp/__init__.py
+++ b/tools/gyp/pylib/gyp/__init__.py
@@ -12,6 +12,7 @@ import re
import shlex
import sys
import traceback
+from gyp.common import GypError
# Default debug modes for GYP
debug = {}
@@ -44,15 +45,9 @@ def FindBuildFiles():
return build_files
-class GypError(Exception):
- """Error class representing an error, which is to be presented
- to the user. The main entry point will catch and display this.
- """
- pass
-
-
def Load(build_files, format, default_variables={},
- includes=[], depth='.', params=None, check=False, circular_check=True):
+ includes=[], depth='.', params=None, check=False,
+ circular_check=True):
"""
Loads one or more specified build files.
default_variables and includes will be copied before use.
@@ -130,7 +125,8 @@ def Load(build_files, format, default_variables={},
# Process the input specific to this generator.
result = gyp.input.Load(build_files, default_variables, includes[:],
- depth, generator_input_info, check, circular_check)
+ depth, generator_input_info, check, circular_check,
+ params['parallel'])
return [generator] + result
def NameValueListToDict(name_value_list):
@@ -317,9 +313,14 @@ def gyp_main(args):
help='do not read options from environment variables')
parser.add_option('--check', dest='check', action='store_true',
help='check format of gyp files')
+ parser.add_option('--parallel', action='store_true',
+ env_name='GYP_PARALLEL',
+ help='Use multiprocessing for speed (experimental)')
parser.add_option('--toplevel-dir', dest='toplevel_dir', action='store',
default=None, metavar='DIR', type='path',
help='directory to use as the root of the source tree')
+ parser.add_option('--build', dest='configs', action='append',
+ help='configuration for build after project generation')
# --no-circular-check disables the check for circular relationships between
# .gyp files. These relationships should not exist, but they've only been
# observed to be harmful with the Xcode generator. Chromium's .gyp files
@@ -374,6 +375,9 @@ def gyp_main(args):
if g_o:
options.generator_output = g_o
+ if not options.parallel and options.use_environment:
+ options.parallel = bool(os.environ.get('GYP_PARALLEL'))
+
for mode in options.debug:
gyp.debug[mode] = 1
@@ -484,7 +488,8 @@ def gyp_main(args):
'cwd': os.getcwd(),
'build_files_arg': build_files_arg,
'gyp_binary': sys.argv[0],
- 'home_dot_gyp': home_dot_gyp}
+ 'home_dot_gyp': home_dot_gyp,
+ 'parallel': options.parallel}
# Start with the default variables from the command line.
[generator, flat_list, targets, data] = Load(build_files, format,
@@ -502,6 +507,13 @@ def gyp_main(args):
# generate targets in the order specified in flat_list.
generator.GenerateOutput(flat_list, targets, data, params)
+ if options.configs:
+ valid_configs = targets[flat_list[0]]['configurations'].keys()
+ for conf in options.configs:
+ if conf not in valid_configs:
+ raise GypError('Invalid config specified via --build: %s' % conf)
+ generator.PerformBuild(data, options.configs, params)
+
# Done
return 0
diff --git a/tools/gyp/pylib/gyp/common.py b/tools/gyp/pylib/gyp/common.py
index 6962684e1..e917a59a3 100644
--- a/tools/gyp/pylib/gyp/common.py
+++ b/tools/gyp/pylib/gyp/common.py
@@ -27,6 +27,13 @@ class memoize(object):
return result
+class GypError(Exception):
+ """Error class representing an error, which is to be presented
+ to the user. The main entry point will catch and display this.
+ """
+ pass
+
+
def ExceptionAppend(e, msg):
"""Append a message to the given exception's message."""
if not e.args:
@@ -371,6 +378,8 @@ def GetFlavor(params):
return 'solaris'
if sys.platform.startswith('freebsd'):
return 'freebsd'
+ if sys.platform.startswith('dragonfly'):
+ return 'dragonflybsd'
return 'linux'
diff --git a/tools/gyp/pylib/gyp/common_test.py b/tools/gyp/pylib/gyp/common_test.py
index aabaf344b..7fbac09d0 100755
--- a/tools/gyp/pylib/gyp/common_test.py
+++ b/tools/gyp/pylib/gyp/common_test.py
@@ -8,6 +8,7 @@
import gyp.common
import unittest
+import sys
class TestTopologicallySorted(unittest.TestCase):
@@ -40,5 +41,32 @@ class TestTopologicallySorted(unittest.TestCase):
graph.keys(), GetEdge)
+class TestGetFlavor(unittest.TestCase):
+ """Test that gyp.common.GetFlavor works as intended"""
+ original_platform = ''
+
+ def setUp(self):
+ self.original_platform = sys.platform
+
+ def tearDown(self):
+ sys.platform = self.original_platform
+
+ def assertFlavor(self, expected, argument, param):
+ sys.platform = argument
+ self.assertEqual(expected, gyp.common.GetFlavor(param))
+
+ def test_platform_default(self):
+ self.assertFlavor('dragonflybsd', 'dragonfly3', {})
+ self.assertFlavor('freebsd' , 'freebsd9' , {})
+ self.assertFlavor('freebsd' , 'freebsd10' , {})
+ self.assertFlavor('solaris' , 'sunos5' , {});
+ self.assertFlavor('solaris' , 'sunos' , {});
+ self.assertFlavor('linux' , 'linux2' , {});
+ self.assertFlavor('linux' , 'linux3' , {});
+
+ def test_param(self):
+ self.assertFlavor('foobar', 'linux2' , {'flavor': 'foobar'})
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/tools/gyp/pylib/gyp/generator/android.py b/tools/gyp/pylib/gyp/generator/android.py
index 0cecf7a64..872ec844c 100644
--- a/tools/gyp/pylib/gyp/generator/android.py
+++ b/tools/gyp/pylib/gyp/generator/android.py
@@ -38,12 +38,22 @@ generator_default_variables = {
'RULE_INPUT_PATH': '$(RULE_SOURCES)',
'RULE_INPUT_EXT': '$(suffix $<)',
'RULE_INPUT_NAME': '$(notdir $<)',
+ 'CONFIGURATION_NAME': 'NOT_USED_ON_ANDROID',
}
# Make supports multiple toolsets
generator_supports_multiple_toolsets = True
+# Generator-specific gyp specs.
+generator_additional_non_configuration_keys = [
+ # Boolean to declare that this target does not want its name mangled.
+ 'android_unmangled_name',
+]
+generator_additional_path_sections = []
+generator_extra_sources_for_rules = []
+
+
SHARED_FOOTER = """\
# "gyp_all_modules" is a concatenation of the "gyp_all_modules" targets from
# all the included sub-makefiles. This is just here to clarify.
@@ -153,7 +163,7 @@ class AndroidMkWriter(object):
extra_outputs = []
extra_sources = []
- self.android_class = MODULE_CLASSES.get(self.type, 'NONE')
+ self.android_class = MODULE_CLASSES.get(self.type, 'GYP')
self.android_module = self.ComputeAndroidModule(spec)
(self.android_stem, self.android_suffix) = self.ComputeOutputParts(spec)
self.output = self.output_binary = self.ComputeOutput(spec)
@@ -576,6 +586,10 @@ class AndroidMkWriter(object):
distinguish gyp-generated module names.
"""
+ if int(spec.get('android_unmangled_name', 0)):
+ assert self.type != 'shared_library' or self.target.startswith('lib')
+ return self.target
+
if self.type == 'shared_library':
# For reasons of convention, the Android build system requires that all
# shared library modules are named 'libfoo' when generating -l flags.
@@ -838,10 +852,11 @@ class AndroidMkWriter(object):
# Add an alias from the gyp target name to the Android module name. This
# simplifies manual builds of the target, and is required by the test
# framework.
- self.WriteLn('# Alias gyp target name.')
- self.WriteLn('.PHONY: %s' % self.target)
- self.WriteLn('%s: %s' % (self.target, self.android_module))
- self.WriteLn('')
+ if self.target != self.android_module:
+ self.WriteLn('# Alias gyp target name.')
+ self.WriteLn('.PHONY: %s' % self.target)
+ self.WriteLn('%s: %s' % (self.target, self.android_module))
+ self.WriteLn('')
# Add the command to trigger build of the target type depending
# on the toolset. Ex: BUILD_STATIC_LIBRARY vs. BUILD_HOST_STATIC_LIBRARY
@@ -989,7 +1004,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
default_configuration = 'Default'
srcdir = '.'
- makefile_name = 'GypAndroid.mk' + options.suffix
+ makefile_name = 'GypAndroid' + options.suffix + '.mk'
makefile_path = os.path.join(options.toplevel_dir, makefile_name)
assert not options.generator_output, (
'The Android backend does not support options.generator_output.')
diff --git a/tools/gyp/pylib/gyp/generator/dump_dependency_json.py b/tools/gyp/pylib/gyp/generator/dump_dependency_json.py
index acee72ebb..f8480dd28 100644
--- a/tools/gyp/pylib/gyp/generator/dump_dependency_json.py
+++ b/tools/gyp/pylib/gyp/generator/dump_dependency_json.py
@@ -1,10 +1,12 @@
-# Copyright (c) 2011 Google Inc. All rights reserved.
+# Copyright (c) 2012 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import collections
+import os
import gyp
import gyp.common
+import gyp.msvs_emulation
import json
import sys
@@ -22,7 +24,8 @@ for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME',
'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT',
'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX',
'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX',
- 'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX']:
+ 'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX',
+ 'CONFIGURATION_NAME']:
generator_default_variables[unused] = ''
@@ -32,6 +35,30 @@ def CalculateVariables(default_variables, params):
default_variables.setdefault(key, val)
default_variables.setdefault('OS', gyp.common.GetFlavor(params))
+ flavor = gyp.common.GetFlavor(params)
+ if flavor =='win':
+ # Copy additional generator configuration data from VS, which is shared
+ # by the Windows Ninja generator.
+ import gyp.generator.msvs as msvs_generator
+ generator_additional_non_configuration_keys = getattr(msvs_generator,
+ 'generator_additional_non_configuration_keys', [])
+ generator_additional_path_sections = getattr(msvs_generator,
+ 'generator_additional_path_sections', [])
+
+ # Set a variable so conditions can be based on msvs_version.
+ msvs_version = gyp.msvs_emulation.GetVSVersion(generator_flags)
+ default_variables['MSVS_VERSION'] = msvs_version.ShortName()
+
+ # To determine processor word size on Windows, in addition to checking
+ # PROCESSOR_ARCHITECTURE (which reflects the word size of the current
+ # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which
+ # contains the actual word size of the system when running thru WOW64).
+ if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or
+ '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')):
+ default_variables['MSVS_OS_BITS'] = 64
+ else:
+ default_variables['MSVS_OS_BITS'] = 32
+
def CalculateGeneratorInputInfo(params):
"""Calculate the generator specific info that gets fed to input (called by
diff --git a/tools/gyp/pylib/gyp/generator/make.py b/tools/gyp/pylib/gyp/generator/make.py
index 4648bd9b2..bcc2cc619 100644
--- a/tools/gyp/pylib/gyp/generator/make.py
+++ b/tools/gyp/pylib/gyp/generator/make.py
@@ -24,9 +24,9 @@
import os
import re
import sys
+import subprocess
import gyp
import gyp.common
-import gyp.system_test
import gyp.xcode_emulation
from gyp.common import GetEnvironFallback
@@ -125,7 +125,10 @@ SPACE_REPLACEMENT = '?'
LINK_COMMANDS_LINUX = """\
quiet_cmd_alink = AR($(TOOLSET)) $@
-cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) $(ARFLAGS.$(TOOLSET)) $@ $(filter %.o,$^)
+cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^)
+
+quiet_cmd_alink_thin = AR($(TOOLSET)) $@
+cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^)
# Due to circular dependencies between libraries :(, we wrap the
# special "figure out circular dependencies" flags around the entire
@@ -158,7 +161,7 @@ cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSE
LINK_COMMANDS_MAC = """\
quiet_cmd_alink = LIBTOOL-STATIC $@
-cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool -static -o $@ $(filter %.o,$^)
+cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %.o,$^)
quiet_cmd_link = LINK($(TOOLSET)) $@
cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS)
@@ -176,7 +179,10 @@ cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSE
LINK_COMMANDS_ANDROID = """\
quiet_cmd_alink = AR($(TOOLSET)) $@
-cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) $(ARFLAGS.$(TOOLSET)) $@ $(filter %.o,$^)
+cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^)
+
+quiet_cmd_alink_thin = AR($(TOOLSET)) $@
+cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^)
# Due to circular dependencies between libraries :(, we wrap the
# special "figure out circular dependencies" flags around the entire
@@ -262,10 +268,7 @@ CXXFLAGS.target ?= $(CXXFLAGS)
LINK.target ?= %(LINK.target)s
LDFLAGS.target ?= $(LDFLAGS)
AR.target ?= $(AR)
-ARFLAGS.target ?= %(ARFLAGS.target)s
-# N.B.: the logic of which commands to run should match the computation done
-# in gyp's make.py where ARFLAGS.host etc. is computed.
# TODO(evan): move all cross-compilation logic to gyp-time so we don't need
# to replicate this environment fallback in make as well.
CC.host ?= %(CC.host)s
@@ -275,7 +278,6 @@ CXXFLAGS.host ?=
LINK.host ?= %(LINK.host)s
LDFLAGS.host ?=
AR.host ?= %(AR.host)s
-ARFLAGS.host := %(ARFLAGS.host)s
# Define a dir function that can handle spaces.
# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions
@@ -721,9 +723,12 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
else:
self.output = self.output_binary = self.ComputeOutput(spec)
+ self.is_standalone_static_library = bool(
+ spec.get('standalone_static_library', 0))
self._INSTALLABLE_TARGETS = ('executable', 'loadable_module',
'shared_library')
- if self.type in self._INSTALLABLE_TARGETS:
+ if (self.is_standalone_static_library or
+ self.type in self._INSTALLABLE_TARGETS):
self.alias = os.path.basename(self.output)
install_path = self._InstallableTargetInstallPath()
else:
@@ -838,6 +843,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
actions)
part_of_all: flag indicating this target is part of 'all'
"""
+ env = self.GetSortedXcodeEnv()
for action in actions:
name = StringToMakefileVariable('%s_%s' % (self.qualified_target,
action['action_name']))
@@ -858,7 +864,11 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
extra_mac_bundle_resources += outputs
# Write the actual command.
- command = gyp.common.EncodePOSIXShellList(action['action'])
+ action_commands = action['action']
+ if self.flavor == 'mac':
+ action_commands = [gyp.xcode_emulation.ExpandEnvVars(command, env)
+ for command in action_commands]
+ command = gyp.common.EncodePOSIXShellList(action_commands)
if 'message' in action:
self.WriteLn('quiet_cmd_%s = ACTION %s $@' % (name, action['message']))
else:
@@ -907,7 +917,6 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
"Spaces in action output filenames not supported (%s)" % output)
# See the comment in WriteCopies about expanding env vars.
- env = self.GetSortedXcodeEnv()
outputs = [gyp.xcode_emulation.ExpandEnvVars(o, env) for o in outputs]
inputs = [gyp.xcode_emulation.ExpandEnvVars(i, env) for i in inputs]
@@ -933,6 +942,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
rules (used to make other pieces dependent on these rules)
part_of_all: flag indicating this target is part of 'all'
"""
+ env = self.GetSortedXcodeEnv()
for rule in rules:
name = StringToMakefileVariable('%s_%s' % (self.qualified_target,
rule['rule_name']))
@@ -972,6 +982,10 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
# amount of pain.
actions += ['@touch --no-create $@']
+ # See the comment in WriteCopies about expanding env vars.
+ outputs = [gyp.xcode_emulation.ExpandEnvVars(o, env) for o in outputs]
+ inputs = [gyp.xcode_emulation.ExpandEnvVars(i, env) for i in inputs]
+
outputs = map(self.Absolutify, outputs)
all_outputs += outputs
# Only write the 'obj' and 'builddir' rules for the "primary" output
@@ -996,6 +1010,9 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
# action, cd_action, and mkdirs get written to a toplevel variable
# called cmd_foo. Toplevel variables can't handle things that change
# per makefile like $(TARGET), so hardcode the target.
+ if self.flavor == 'mac':
+ action = [gyp.xcode_emulation.ExpandEnvVars(command, env)
+ for command in action]
action = gyp.common.EncodePOSIXShellList(action)
action = action.replace('$(TARGET)', self.target)
cd_action = cd_action.replace('$(TARGET)', self.target)
@@ -1049,7 +1066,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
outputs = []
for copy in copies:
for path in copy['files']:
- # Absolutify() calls normpath, stripping trailing slashes.
+ # Absolutify() may call normpath, and will strip trailing slashes.
path = Sourceify(self.Absolutify(path))
filename = os.path.split(path)[1]
output = Sourceify(self.Absolutify(os.path.join(copy['destination'],
@@ -1419,6 +1436,9 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
ldflags.append(r'-Wl,-rpath-link=\$(builddir)/lib.%s/' %
self.toolset)
self.WriteList(ldflags, 'LDFLAGS_%s' % configname)
+ if self.flavor == 'mac':
+ self.WriteList(self.xcode_settings.GetLibtoolflags(configname),
+ 'LIBTOOLFLAGS_%s' % configname)
libraries = spec.get('libraries')
if libraries:
# Remove duplicate entries
@@ -1430,6 +1450,10 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
QuoteSpaces(self.output_binary))
self.WriteLn('%s: LIBS := $(LIBS)' % QuoteSpaces(self.output_binary))
+ if self.flavor == 'mac':
+ self.WriteLn('%s: GYP_LIBTOOLFLAGS := $(LIBTOOLFLAGS_$(BUILDTYPE))' %
+ QuoteSpaces(self.output_binary))
+
# Postbuild actions. Like actions, but implicitly depend on the target's
# output.
postbuilds = []
@@ -1517,8 +1541,13 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
for link_dep in link_deps:
assert ' ' not in link_dep, (
"Spaces in alink input filenames not supported (%s)" % link_dep)
- self.WriteDoCmd([self.output_binary], link_deps, 'alink', part_of_all,
- postbuilds=postbuilds)
+ if (self.flavor not in ('mac', 'win') and not
+ self.is_standalone_static_library):
+ self.WriteDoCmd([self.output_binary], link_deps, 'alink_thin',
+ part_of_all, postbuilds=postbuilds)
+ else:
+ self.WriteDoCmd([self.output_binary], link_deps, 'alink', part_of_all,
+ postbuilds=postbuilds)
elif self.type == 'shared_library':
self.WriteLn('%s: LD_INPUTS := %s' % (
QuoteSpaces(self.output_binary),
@@ -1558,9 +1587,12 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
# 1) They need to install to the build dir or "product" dir.
# 2) They get shortcuts for building (e.g. "make chrome").
# 3) They are part of "make all".
- if self.type in self._INSTALLABLE_TARGETS:
+ if (self.type in self._INSTALLABLE_TARGETS or
+ self.is_standalone_static_library):
if self.type == 'shared_library':
file_desc = 'shared library'
+ elif self.type == 'static_library':
+ file_desc = 'static library'
else:
file_desc = 'executable'
install_path = self._InstallableTargetInstallPath()
@@ -1830,9 +1862,10 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
"""Convert a subdirectory-relative path into a base-relative path.
Skips over paths that contain variables."""
if '$(' in path:
- # path is no existing file in this case, but calling normpath is still
- # important for trimming trailing slashes.
- return os.path.normpath(path)
+ # Don't call normpath in this case, as it might collapse the
+ # path too aggressively if it features '..'. However it's still
+ # important to strip trailing slashes.
+ return path.rstrip('/')
return os.path.normpath(os.path.join(self.path, path))
@@ -1881,39 +1914,15 @@ def WriteAutoRegenerationRule(params, root_makefile, makefile_name,
build_files_args)})
-def RunSystemTests(flavor):
- """Run tests against the system to compute default settings for commands.
-
- Returns:
- dictionary of settings matching the block of command-lines used in
- SHARED_HEADER. E.g. the dictionary will contain a ARFLAGS.target
- key for the default ARFLAGS for the target ar command.
- """
- # Compute flags used for building static archives.
- # N.B.: this fallback logic should match the logic in SHARED_HEADER.
- # See comment there for more details.
- ar_target = GetEnvironFallback(('AR_target', 'AR'), 'ar')
- cc_target = GetEnvironFallback(('CC_target', 'CC'), 'cc')
- arflags_target = 'crs'
- # ar -T enables thin archives on Linux. OS X's ar supports a -T flag, but it
- # does something useless (it limits filenames in the archive to 15 chars).
- if flavor != 'mac' and gyp.system_test.TestArSupportsT(ar_command=ar_target,
- cc_command=cc_target):
- arflags_target = 'crsT'
-
- ar_host = os.environ.get('AR_host', 'ar')
- cc_host = os.environ.get('CC_host', 'gcc')
- arflags_host = 'crs'
- # It feels redundant to compute this again given that most builds aren't
- # cross-compiles, but due to quirks of history CC_host defaults to 'gcc'
- # while CC_target defaults to 'cc', so the commands really are different
- # even though they're nearly guaranteed to run the same code underneath.
- if flavor != 'mac' and gyp.system_test.TestArSupportsT(ar_command=ar_host,
- cc_command=cc_host):
- arflags_host = 'crsT'
-
- return { 'ARFLAGS.target': arflags_target,
- 'ARFLAGS.host': arflags_host }
+def PerformBuild(data, configurations, params):
+ options = params['options']
+ for config in configurations:
+ arguments = ['make']
+ if options.toplevel_dir and options.toplevel_dir != '.':
+ arguments += '-C', options.toplevel_dir
+ arguments.append('BUILDTYPE=' + config)
+ print 'Building [%s]: %s' % (config, arguments)
+ subprocess.check_call(arguments)
def GenerateOutput(target_list, target_dicts, data, params):
@@ -1991,12 +2000,11 @@ def GenerateOutput(target_list, target_dicts, data, params):
'flock_index': 2,
'extra_commands': SHARED_HEADER_SUN_COMMANDS,
})
- elif flavor == 'freebsd':
+ elif flavor == 'freebsd' or flavor == 'dragonflybsd':
header_params.update({
'flock': 'lockf',
})
- header_params.update(RunSystemTests(flavor))
header_params.update({
'CC.target': GetEnvironFallback(('CC_target', 'CC'), '$(CC)'),
'AR.target': GetEnvironFallback(('AR_target', 'AR'), '$(AR)'),
diff --git a/tools/gyp/pylib/gyp/generator/msvs.py b/tools/gyp/pylib/gyp/generator/msvs.py
index 70152486b..47cbd36ec 100644
--- a/tools/gyp/pylib/gyp/generator/msvs.py
+++ b/tools/gyp/pylib/gyp/generator/msvs.py
@@ -18,6 +18,7 @@ import gyp.MSVSSettings as MSVSSettings
import gyp.MSVSToolFile as MSVSToolFile
import gyp.MSVSUserFile as MSVSUserFile
import gyp.MSVSVersion as MSVSVersion
+from gyp.common import GypError
# Regular expression for validating Visual Studio GUIDs. If the GUID
@@ -1026,7 +1027,7 @@ def _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config):
# Get the information for this configuration
include_dirs, resource_include_dirs = _GetIncludeDirs(config)
libraries = _GetLibraries(spec)
- out_file, vc_tool, _ = _GetOutputFilePathAndTool(spec)
+ out_file, vc_tool, _ = _GetOutputFilePathAndTool(spec, msbuild=False)
defines = _GetDefines(config)
defines = [_EscapeCppDefineForMSVS(d) for d in defines]
disabled_warnings = _GetDisabledWarnings(config)
@@ -1123,6 +1124,8 @@ def _GetLibraries(spec):
unique_libraries_list = []
for entry in reversed(libraries):
library = re.sub('^\-l', '', entry)
+ if not os.path.splitext(library)[1]:
+ library += '.lib'
if library not in found:
found.add(library)
unique_libraries_list.append(library)
@@ -1130,7 +1133,7 @@ def _GetLibraries(spec):
return unique_libraries_list
-def _GetOutputFilePathAndTool(spec):
+def _GetOutputFilePathAndTool(spec, msbuild):
"""Returns the path and tool to use for this target.
Figures out the path of the file this spec will create and the name of
@@ -1154,10 +1157,14 @@ def _GetOutputFilePathAndTool(spec):
output_file_props = output_file_map.get(spec['type'])
if output_file_props and int(spec.get('msvs_auto_output_file', 1)):
vc_tool, msbuild_tool, out_dir, suffix = output_file_props
+ if spec.get('standalone_static_library', 0):
+ out_dir = '$(OutDir)'
out_dir = spec.get('product_dir', out_dir)
product_extension = spec.get('product_extension')
if product_extension:
suffix = '.' + product_extension
+ elif msbuild:
+ suffix = '$(TargetExt)'
prefix = spec.get('product_prefix', '')
product_name = spec.get('product_name', '$(ProjectName)')
out_file = ntpath.join(out_dir, prefix + product_name + suffix)
@@ -1666,7 +1673,7 @@ def _CreateProjectObjects(target_list, target_dicts, options, msvs_version):
build_file = gyp.common.BuildFile(qualified_target)
# Create object for this project.
obj = MSVSNew.MSVSProject(
- _FixPath(proj_path),
+ proj_path,
name=spec['target_name'],
guid=guid,
spec=spec,
@@ -1779,6 +1786,25 @@ def _ShardTargets(target_list, target_dicts):
return (new_target_list, new_target_dicts)
+def PerformBuild(data, configurations, params):
+ options = params['options']
+ msvs_version = params['msvs_version']
+ devenv = os.path.join(msvs_version.path, 'Common7', 'IDE', 'devenv.com')
+
+ for build_file, build_file_dict in data.iteritems():
+ (build_file_root, build_file_ext) = os.path.splitext(build_file)
+ if build_file_ext != '.gyp':
+ continue
+ sln_path = build_file_root + options.suffix + '.sln'
+ if options.generator_output:
+ sln_path = os.path.join(options.generator_output, sln_path)
+
+ for config in configurations:
+ arguments = [devenv, sln_path, '/Build', config]
+ print 'Building [%s]: %s' % (config, arguments)
+ rtn = subprocess.check_call(arguments)
+
+
def GenerateOutput(target_list, target_dicts, data, params):
"""Generate .sln and .vcproj files.
@@ -2571,13 +2597,13 @@ def _GetMSBuildAttributes(spec, config, build_file):
config_type = _GetMSVSConfigurationType(spec, build_file)
config_type = _ConvertMSVSConfigurationType(config_type)
msbuild_attributes = config.get('msbuild_configuration_attributes', {})
- msbuild_attributes['ConfigurationType'] = config_type
+ msbuild_attributes.setdefault('ConfigurationType', config_type)
output_dir = msbuild_attributes.get('OutputDirectory',
- '$(SolutionDir)$(Configuration)\\')
- msbuild_attributes['OutputDirectory'] = _FixPath(output_dir)
+ '$(SolutionDir)$(Configuration)')
+ msbuild_attributes['OutputDirectory'] = _FixPath(output_dir) + '\\'
if 'IntermediateDirectory' not in msbuild_attributes:
- intermediate = '$(Configuration)\\'
- msbuild_attributes['IntermediateDirectory'] = _FixPath(intermediate)
+ intermediate = _FixPath('$(Configuration)') + '\\'
+ msbuild_attributes['IntermediateDirectory'] = intermediate
if 'CharacterSet' in msbuild_attributes:
msbuild_attributes['CharacterSet'] = _ConvertMSVSCharacterSet(
msbuild_attributes['CharacterSet'])
@@ -2754,7 +2780,7 @@ def _FinalizeMSBuildSettings(spec, configuration):
msbuild_settings = MSVSSettings.ConvertToMSBuildSettings(msvs_settings)
include_dirs, resource_include_dirs = _GetIncludeDirs(configuration)
libraries = _GetLibraries(spec)
- out_file, _, msbuild_tool = _GetOutputFilePathAndTool(spec)
+ out_file, _, msbuild_tool = _GetOutputFilePathAndTool(spec, msbuild=True)
defines = _GetDefines(configuration)
if converted:
# Visual Studio 2010 has TR1
@@ -3009,7 +3035,7 @@ def _GenerateMSBuildProject(project, options, version, generator_flags):
extension_to_rule_name)
missing_sources = _VerifySourcesExist(sources, project_dir)
- for (_, configuration) in configurations.iteritems():
+ for configuration in configurations.itervalues():
_FinalizeMSBuildSettings(spec, configuration)
# Add attributes to root element
diff --git a/tools/gyp/pylib/gyp/generator/msvs_test.py b/tools/gyp/pylib/gyp/generator/msvs_test.py
index 5a69c1c28..c0b021df5 100755
--- a/tools/gyp/pylib/gyp/generator/msvs_test.py
+++ b/tools/gyp/pylib/gyp/generator/msvs_test.py
@@ -1,6 +1,5 @@
#!/usr/bin/env python
-
-# Copyright (c) 2011 Google Inc. All rights reserved.
+# Copyright (c) 2012 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -27,6 +26,9 @@ class TestSequenceFunctions(unittest.TestCase):
msvs._GetLibraries({'other':'foo', 'libraries': ['a.lib']}),
['a.lib'])
self.assertEqual(
+ msvs._GetLibraries({'libraries': ['-la']}),
+ ['a.lib'])
+ self.assertEqual(
msvs._GetLibraries({'libraries': ['a.lib', 'b.lib', 'c.lib', '-lb.lib',
'-lb.lib', 'd.lib', 'a.lib']}),
['c.lib', 'b.lib', 'd.lib', 'a.lib'])
diff --git a/tools/gyp/pylib/gyp/generator/ninja.py b/tools/gyp/pylib/gyp/generator/ninja.py
index d2b8fdce1..fa6bd86ac 100644
--- a/tools/gyp/pylib/gyp/generator/ninja.py
+++ b/tools/gyp/pylib/gyp/generator/ninja.py
@@ -4,15 +4,16 @@
import copy
import hashlib
+import multiprocessing
import os.path
import re
+import signal
import subprocess
import sys
import gyp
import gyp.common
import gyp.msvs_emulation
import gyp.MSVSVersion
-import gyp.system_test
import gyp.xcode_emulation
from gyp.common import GetEnvironFallback
@@ -354,7 +355,8 @@ class NinjaWriter:
self.ninja.newline()
return targets[0]
- def WriteSpec(self, spec, config_name, generator_flags):
+ def WriteSpec(self, spec, config_name, generator_flags,
+ case_sensitive_filesystem):
"""The main entry point for NinjaWriter: write the build rules for a spec.
Returns a Target object, which represents the output paths for this spec.
@@ -366,6 +368,8 @@ class NinjaWriter:
self.toolset = spec['toolset']
config = spec['configurations'][config_name]
self.target = Target(spec['type'])
+ self.is_standalone_static_library = bool(
+ spec.get('standalone_static_library', 0))
self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec)
self.xcode_settings = self.msvs_settings = None
@@ -374,8 +378,8 @@ class NinjaWriter:
if self.flavor == 'win':
self.msvs_settings = gyp.msvs_emulation.MsvsSettings(spec,
generator_flags)
- target_platform = self.msvs_settings.GetTargetPlatform(config_name)
- self.ninja.variable('arch', self.win_env[target_platform])
+ arch = self.msvs_settings.GetArch(config_name)
+ self.ninja.variable('arch', self.win_env[arch])
# Compute predepends for all rules.
# actions_depends is the dependencies this target depends on before running
@@ -421,6 +425,8 @@ class NinjaWriter:
if sources:
pch = None
if self.flavor == 'win':
+ gyp.msvs_emulation.VerifyMissingSources(
+ sources, self.abs_build_dir, generator_flags, self.GypPathToNinja)
pch = gyp.msvs_emulation.PrecompiledHeader(
self.msvs_settings, config_name, self.GypPathToNinja)
else:
@@ -428,7 +434,8 @@ class NinjaWriter:
self.xcode_settings, self.GypPathToNinja,
lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))
link_deps = self.WriteSources(
- config_name, config, sources, compile_depends_stamp, pch)
+ config_name, config, sources, compile_depends_stamp, pch,
+ case_sensitive_filesystem, spec)
# Some actions/rules output 'sources' that are already object files.
link_deps += [self.GypPathToNinja(f)
for f in sources if f.endswith(self.obj_ext)]
@@ -502,7 +509,7 @@ class NinjaWriter:
outputs += self.WriteRules(spec['rules'], extra_sources, prebuild,
extra_mac_bundle_resources)
if 'copies' in spec:
- outputs += self.WriteCopies(spec['copies'], prebuild)
+ outputs += self.WriteCopies(spec['copies'], prebuild, mac_bundle_depends)
if 'sources' in spec and self.flavor == 'win':
outputs += self.WriteWinIdlFiles(spec, prebuild)
@@ -549,11 +556,8 @@ class NinjaWriter:
is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(action)
if self.flavor == 'win' else False)
args = action['action']
- args = [self.msvs_settings.ConvertVSMacros(
- arg, self.base_to_build, config=self.config_name)
- for arg in args] if self.flavor == 'win' else args
- rule_name = self.WriteNewNinjaRule(name, args, description,
- is_cygwin, env=env)
+ rule_name, _ = self.WriteNewNinjaRule(name, args, description,
+ is_cygwin, env=env)
inputs = [self.GypPathToNinja(i, env) for i in action['inputs']]
if int(action.get('process_outputs_as_sources', False)):
@@ -573,6 +577,7 @@ class NinjaWriter:
def WriteRules(self, rules, extra_sources, prebuild,
extra_mac_bundle_resources):
+ env = self.GetSortedXcodeEnv()
all_outputs = []
for rule in rules:
# First write out a rule for the rule action.
@@ -588,10 +593,8 @@ class NinjaWriter:
('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name)
is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(rule)
if self.flavor == 'win' else False)
- args = [self.msvs_settings.ConvertVSMacros(
- arg, self.base_to_build, config=self.config_name)
- for arg in args] if self.flavor == 'win' else args
- rule_name = self.WriteNewNinjaRule(name, args, description, is_cygwin)
+ rule_name, args = self.WriteNewNinjaRule(
+ name, args, description, is_cygwin, env=env)
# TODO: if the command references the outputs directly, we should
# simplify it to just use $out.
@@ -648,10 +651,10 @@ class NinjaWriter:
else:
assert var == None, repr(var)
- inputs = map(self.GypPathToNinja, inputs)
- outputs = map(self.GypPathToNinja, outputs)
+ inputs = [self.GypPathToNinja(i, env) for i in inputs]
+ outputs = [self.GypPathToNinja(o, env) for o in outputs]
extra_bindings.append(('unique_name',
- re.sub('[^a-zA-Z0-9_]', '_', outputs[0])))
+ hashlib.md5(outputs[0]).hexdigest()))
self.ninja.build(outputs, rule_name, self.GypPathToNinja(source),
implicit=inputs,
order_only=prebuild,
@@ -661,7 +664,7 @@ class NinjaWriter:
return all_outputs
- def WriteCopies(self, copies, prebuild):
+ def WriteCopies(self, copies, prebuild, mac_bundle_depends):
outputs = []
env = self.GetSortedXcodeEnv()
for copy in copies:
@@ -673,6 +676,15 @@ class NinjaWriter:
dst = self.GypPathToNinja(os.path.join(copy['destination'], basename),
env)
outputs += self.ninja.build(dst, 'copy', src, order_only=prebuild)
+ if self.is_mac_bundle:
+ # gyp has mac_bundle_resources to copy things into a bundle's
+ # Resources folder, but there's no built-in way to copy files to other
+ # places in the bundle. Hence, some targets use copies for this. Check
+ # if this file is copied into the current bundle, and if so add it to
+ # the bundle depends so that dependent targets get rebuilt if the copy
+ # input changes.
+ if dst.startswith(self.xcode_settings.GetBundleContentsFolderPath()):
+ mac_bundle_depends.append(dst)
return outputs
@@ -709,7 +721,7 @@ class NinjaWriter:
bundle_depends.append(out)
def WriteSources(self, config_name, config, sources, predepends,
- precompiled_header):
+ precompiled_header, case_sensitive_filesystem, spec):
"""Write build rules to compile all of |sources|."""
if self.toolset == 'host':
self.ninja.variable('ar', '$ar_host')
@@ -781,10 +793,13 @@ class NinjaWriter:
obj_ext = self.obj_ext
if ext in ('cc', 'cpp', 'cxx'):
command = 'cxx'
- elif ext == 'c' or (ext in ('s', 'S') and self.flavor != 'win'):
+ elif ext == 'c' or (ext == 'S' and self.flavor != 'win'):
command = 'cc'
+ elif ext == 's' and self.flavor != 'win': # Doesn't generate .o.d files.
+ command = 'cc_s'
elif (self.flavor == 'win' and ext == 'asm' and
- self.msvs_settings.GetTargetPlatform(config_name) == 'Win32'):
+ self.msvs_settings.GetArch(config_name) == 'x86' and
+ not self.msvs_settings.HasExplicitAsmRules(spec)):
# Asm files only get auto assembled for x86 (not x64).
command = 'asm'
# Add the _asm suffix as msvs is capable of handling .cc and
@@ -802,6 +817,12 @@ class NinjaWriter:
continue
input = self.GypPathToNinja(source)
output = self.GypPathToUniqueOutput(filename + obj_ext)
+ # Ninja's depfile handling gets confused when the case of a filename
+ # changes on a case-insensitive file system. To work around that, always
+ # convert .o filenames to lowercase on such file systems. See
+ # https://github.com/martine/ninja/issues/402 for details.
+ if not case_sensitive_filesystem:
+ output = output.lower()
implicit = precompiled_header.GetObjDependencies([input], [output])
self.ninja.build(output, command, input,
implicit=[gch for _, _, gch in implicit],
@@ -918,10 +939,12 @@ class NinjaWriter:
extra_bindings.append(('lib',
gyp.common.EncodePOSIXShellArgument(output)))
if self.flavor == 'win':
- self.target.import_lib = output + '.lib'
extra_bindings.append(('dll', output))
- extra_bindings.append(('implib', self.target.import_lib))
- output = [output, self.target.import_lib]
+ if '/NOENTRY' not in ldflags:
+ self.target.import_lib = output + '.lib'
+ extra_bindings.append(('implibflag',
+ '/IMPLIB:%s' % self.target.import_lib))
+ output = [output, self.target.import_lib]
else:
output = [output, output + '.TOC']
@@ -939,10 +962,21 @@ class NinjaWriter:
self.target.binary = compile_deps
elif spec['type'] == 'static_library':
self.target.binary = self.ComputeOutput(spec)
- self.ninja.build(self.target.binary, 'alink', link_deps,
- order_only=compile_deps,
- variables=[('postbuilds', self.GetPostbuildCommand(
- spec, self.target.binary, self.target.binary))])
+ variables = []
+ postbuild = self.GetPostbuildCommand(
+ spec, self.target.binary, self.target.binary)
+ if postbuild:
+ variables.append(('postbuilds', postbuild))
+ if self.xcode_settings:
+ variables.append(('libtool_flags',
+ self.xcode_settings.GetLibtoolflags(config_name)))
+ if (self.flavor not in ('mac', 'win') and not
+ self.is_standalone_static_library):
+ self.ninja.build(self.target.binary, 'alink_thin', link_deps,
+ order_only=compile_deps, variables=variables)
+ else:
+ self.ninja.build(self.target.binary, 'alink', link_deps,
+ order_only=compile_deps, variables=variables)
else:
self.WriteLink(spec, config_name, config, link_deps)
return self.target.binary
@@ -1126,7 +1160,7 @@ class NinjaWriter:
elif self.flavor == 'win' and self.toolset == 'target':
type_in_output_root += ['shared_library']
- if type in type_in_output_root:
+ if type in type_in_output_root or self.is_standalone_static_library:
return filename
elif type == 'shared_library':
libdir = 'lib'
@@ -1142,10 +1176,22 @@ class NinjaWriter:
values = []
self.ninja.variable(var, ' '.join(values))
- def WriteNewNinjaRule(self, name, args, description, is_cygwin, env={}):
+ def WriteNewNinjaRule(self, name, args, description, is_cygwin, env):
"""Write out a new ninja "rule" statement for a given command.
- Returns the name of the new rule."""
+ Returns the name of the new rule, and a copy of |args| with variables
+ expanded."""
+
+ if self.flavor == 'win':
+ args = [self.msvs_settings.ConvertVSMacros(
+ arg, self.base_to_build, config=self.config_name)
+ for arg in args]
+ description = self.msvs_settings.ConvertVSMacros(
+ description, config=self.config_name)
+ elif self.flavor == 'mac':
+ # |env| is an empty list on non-mac.
+ args = [gyp.xcode_emulation.ExpandEnvVars(arg, env) for arg in args]
+ description = gyp.xcode_emulation.ExpandEnvVars(description, env)
# TODO: we shouldn't need to qualify names; we do it because
# currently the ninja rule namespace is global, but it really
@@ -1156,11 +1202,12 @@ class NinjaWriter:
rule_name += '.' + name
rule_name = re.sub('[^a-zA-Z0-9_]', '_', rule_name)
- args = args[:]
-
- if self.flavor == 'win':
- description = self.msvs_settings.ConvertVSMacros(
- description, config=self.config_name)
+ # Remove variable references, but not if they refer to the magic rule
+ # variables. This is not quite right, as it also protects these for
+ # actions, not just for rules where they are valid. Good enough.
+ protect = [ '${root}', '${dirname}', '${source}', '${ext}', '${name}' ]
+ protect = '(?!' + '|'.join(map(re.escape, protect)) + ')'
+ description = re.sub(protect + r'\$', '_', description)
# gyp dictates that commands are run from the base directory.
# cd into the directory before running, and adjust paths in
@@ -1182,10 +1229,6 @@ class NinjaWriter:
else:
env = self.ComputeExportEnvString(env)
command = gyp.common.EncodePOSIXShellList(args)
- if env:
- # If an environment is passed in, variables in the command should be
- # read from it, instead of from ninja's internal variables.
- command = ninja_syntax.escape(command)
command = 'cd %s; ' % self.build_to_base + env + command
# GYP rules/actions express being no-ops by not touching their outputs.
@@ -1195,7 +1238,7 @@ class NinjaWriter:
rspfile=rspfile, rspfile_content=rspfile_content)
self.ninja.newline()
- return rule_name
+ return rule_name, args
def CalculateVariables(default_variables, params):
@@ -1278,16 +1321,26 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
flavor = gyp.common.GetFlavor(params)
generator_flags = params.get('generator_flags', {})
+ # generator_dir: relative path from pwd to where make puts build files.
+ # Makes migrating from make to ninja easier, ninja doesn't put anything here.
+ generator_dir = os.path.relpath(params['options'].generator_output or '.')
+
+ # output_dir: relative path from generator_dir to the build directory.
+ output_dir = generator_flags.get('output_dir', 'out')
+
# build_dir: relative path from source root to our output files.
# e.g. "out/Debug"
- build_dir = os.path.join(generator_flags.get('output_dir', 'out'),
- config_name)
+ build_dir = os.path.normpath(os.path.join(generator_dir,
+ output_dir,
+ config_name))
toplevel_build = os.path.join(options.toplevel_dir, build_dir)
master_ninja = ninja_syntax.Writer(
OpenOutput(os.path.join(toplevel_build, 'build.ninja')),
width=120)
+ case_sensitive_filesystem = not os.path.exists(
+ os.path.join(toplevel_build, 'BUILD.NINJA'))
# Put build-time support tools in out/{config_name}.
gyp.common.CopyTool(flavor, toplevel_build)
@@ -1380,8 +1433,6 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
else:
master_ninja.variable('ld_host', flock + ' linker.lock ' + ld_host)
- if flavor == 'mac':
- master_ninja.variable('mac_tool', os.path.join('.', 'gyp-mac-tool'))
master_ninja.newline()
if flavor != 'win':
@@ -1392,25 +1443,28 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
'$cflags_pch_c -c $in -o $out'),
depfile='$out.d')
master_ninja.rule(
+ 'cc_s',
+ description='CC $out',
+ command=('$cc $defines $includes $cflags $cflags_c '
+ '$cflags_pch_c -c $in -o $out'))
+ master_ninja.rule(
'cxx',
description='CXX $out',
command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_cc '
'$cflags_pch_cc -c $in -o $out'),
depfile='$out.d')
else:
- # TODO(scottmg): Requires fork of ninja for dependency and linking
- # support: https://github.com/sgraham/ninja
# Template for compile commands mostly shared between compiling files
# and generating PCH. In the case of PCH, the "output" is specified by /Fp
# rather than /Fo (for object files), but we still need to specify an /Fo
# when compiling PCH.
- cc_template = ('ninja-deplist-helper -r . -q -f cl -o $out.dl -e $arch '
- '--command '
+ cc_template = ('ninja -t msvc -r . -o $out -e $arch '
+ '-- '
'$cc /nologo /showIncludes /FC '
'@$out.rsp '
'$cflags_pch_c /c $in %(outspec)s /Fd$pdbname ')
- cxx_template = ('ninja-deplist-helper -r . -q -f cl -o $out.dl -e $arch '
- '--command '
+ cxx_template = ('ninja -t msvc -r . -o $out -e $arch '
+ '-- '
'$cxx /nologo /showIncludes /FC '
'@$out.rsp '
'$cflags_pch_cc /c $in %(outspec)s $pchobj /Fd$pdbname ')
@@ -1418,28 +1472,28 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
'cc',
description='CC $out',
command=cc_template % {'outspec': '/Fo$out'},
- depfile='$out.dl',
+ depfile='$out.d',
rspfile='$out.rsp',
rspfile_content='$defines $includes $cflags $cflags_c')
master_ninja.rule(
'cc_pch',
description='CC PCH $out',
command=cc_template % {'outspec': '/Fp$out /Fo$out.obj'},
- depfile='$out.dl',
+ depfile='$out.d',
rspfile='$out.rsp',
rspfile_content='$defines $includes $cflags $cflags_c')
master_ninja.rule(
'cxx',
description='CXX $out',
command=cxx_template % {'outspec': '/Fo$out'},
- depfile='$out.dl',
+ depfile='$out.d',
rspfile='$out.rsp',
rspfile_content='$defines $includes $cflags $cflags_cc')
master_ninja.rule(
'cxx_pch',
description='CXX PCH $out',
command=cxx_template % {'outspec': '/Fp$out /Fo$out.obj'},
- depfile='$out.dl',
+ depfile='$out.d',
rspfile='$out.rsp',
rspfile_content='$defines $includes $cflags $cflags_cc')
master_ninja.rule(
@@ -1466,6 +1520,10 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
master_ninja.rule(
'alink',
description='AR $out',
+ command='rm -f $out && $ar rcs $out $in')
+ master_ninja.rule(
+ 'alink_thin',
+ description='AR $out',
command='rm -f $out && $ar rcsT $out $in')
# This allows targets that only need to depend on $lib's API to declare an
@@ -1514,7 +1572,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
rspfile_content='$in_newline $libflags')
dlldesc = 'LINK(DLL) $dll'
dllcmd = ('%s gyp-win-tool link-wrapper $arch '
- '$ld /nologo /IMPLIB:$implib /DLL /OUT:$dll '
+ '$ld /nologo $implibflag /DLL /OUT:$dll '
'/PDB:$dll.pdb @$dll.rsp' % sys.executable)
dllcmd += (' && %s gyp-win-tool manifest-wrapper $arch '
'$mt -nologo -manifest $manifests -out:$dll.manifest' %
@@ -1556,7 +1614,8 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
'alink',
description='LIBTOOL-STATIC $out, POSTBUILDS',
command='rm -f $out && '
- './gyp-mac-tool filter-libtool libtool -static -o $out $in'
+ './gyp-mac-tool filter-libtool libtool $libtool_flags '
+ '-static -o $out $in'
'$postbuilds')
# Record the public interface of $lib in $lib.TOC. See the corresponding
@@ -1607,11 +1666,11 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
master_ninja.rule(
'mac_tool',
description='MACTOOL $mactool_cmd $in',
- command='$env $mac_tool $mactool_cmd $in $out')
+ command='$env ./gyp-mac-tool $mactool_cmd $in $out')
master_ninja.rule(
'package_framework',
description='PACKAGE FRAMEWORK $out, POSTBUILDS',
- command='$mac_tool package-framework $out $version$postbuilds '
+ command='./gyp-mac-tool package-framework $out $version$postbuilds '
'&& touch $out')
if flavor == 'win':
master_ninja.rule(
@@ -1673,7 +1732,8 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
flavor, abs_build_dir=abs_build_dir)
master_ninja.subninja(output_file)
- target = writer.WriteSpec(spec, config_name, generator_flags)
+ target = writer.WriteSpec(
+ spec, config_name, generator_flags, case_sensitive_filesystem)
if target:
if name != target.FinalOutput() and spec['toolset'] == 'target':
target_short_names.setdefault(name, []).append(target)
@@ -1694,19 +1754,46 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
if all_outputs:
master_ninja.newline()
master_ninja.build('all', 'phony', list(all_outputs))
- master_ninja.default('all')
+ master_ninja.default(generator_flags.get('default_target', 'all'))
-def GenerateOutput(target_list, target_dicts, data, params):
- if params['options'].generator_output:
- raise NotImplementedError, "--generator_output not implemented for ninja"
+def PerformBuild(data, configurations, params):
+ options = params['options']
+ for config in configurations:
+ builddir = os.path.join(options.toplevel_dir, 'out', config)
+ arguments = ['ninja', '-C', builddir]
+ print 'Building [%s]: %s' % (config, arguments)
+ subprocess.check_call(arguments)
+
+
+def CallGenerateOutputForConfig(arglist):
+ # Ignore the interrupt signal so that the parent process catches it and
+ # kills all multiprocessing children.
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+
+ (target_list, target_dicts, data, params, config_name) = arglist
+ GenerateOutputForConfig(target_list, target_dicts, data, params, config_name)
+
+def GenerateOutput(target_list, target_dicts, data, params):
user_config = params.get('generator_flags', {}).get('config', None)
if user_config:
GenerateOutputForConfig(target_list, target_dicts, data, params,
user_config)
else:
config_names = target_dicts[target_list[0]]['configurations'].keys()
- for config_name in config_names:
- GenerateOutputForConfig(target_list, target_dicts, data, params,
- config_name)
+ if params['parallel']:
+ try:
+ pool = multiprocessing.Pool(len(config_names))
+ arglists = []
+ for config_name in config_names:
+ arglists.append(
+ (target_list, target_dicts, data, params, config_name))
+ pool.map(CallGenerateOutputForConfig, arglists)
+ except KeyboardInterrupt, e:
+ pool.terminate()
+ raise e
+ else:
+ for config_name in config_names:
+ GenerateOutputForConfig(target_list, target_dicts, data, params,
+ config_name)
diff --git a/tools/gyp/pylib/gyp/generator/scons.py b/tools/gyp/pylib/gyp/generator/scons.py
index 4d0feb0c9..fe7cb581b 100644
--- a/tools/gyp/pylib/gyp/generator/scons.py
+++ b/tools/gyp/pylib/gyp/generator/scons.py
@@ -8,6 +8,7 @@ import gyp.SCons as SCons
import os.path
import pprint
import re
+import subprocess
# TODO: remove when we delete the last WriteList() call in this module
@@ -960,6 +961,30 @@ def TargetFilename(target, build_file=None, output_suffix=''):
return output_file
+def PerformBuild(data, configurations, params):
+ options = params['options']
+
+ # Due to the way we test gyp on the chromium typbots
+ # we need to look for 'scons.py' as well as the more common 'scons'
+ # TODO(sbc): update the trybots to have a more normal install
+ # of scons.
+ scons = 'scons'
+ paths = os.environ['PATH'].split(os.pathsep)
+ for scons_name in ['scons', 'scons.py']:
+ for path in paths:
+ test_scons = os.path.join(path, scons_name)
+ print 'looking for: %s' % test_scons
+ if os.path.exists(test_scons):
+ print "found scons: %s" % scons
+ scons = test_scons
+ break
+
+ for config in configurations:
+ arguments = [scons, '-C', options.toplevel_dir, '--mode=%s' % config]
+ print "Building [%s]: %s" % (config, arguments)
+ subprocess.check_call(arguments)
+
+
def GenerateOutput(target_list, target_dicts, data, params):
"""
Generates all the output files for the specified targets.
diff --git a/tools/gyp/pylib/gyp/generator/xcode.py b/tools/gyp/pylib/gyp/generator/xcode.py
index 9ea4fbdff..7b21bae8a 100644
--- a/tools/gyp/pylib/gyp/generator/xcode.py
+++ b/tools/gyp/pylib/gyp/generator/xcode.py
@@ -587,6 +587,25 @@ def EscapeXCodeArgument(s):
return '"' + s + '"'
+
+def PerformBuild(data, configurations, params):
+ options = params['options']
+
+ for build_file, build_file_dict in data.iteritems():
+ (build_file_root, build_file_ext) = os.path.splitext(build_file)
+ if build_file_ext != '.gyp':
+ continue
+ xcodeproj_path = build_file_root + options.suffix + '.xcodeproj'
+ if options.generator_output:
+ xcodeproj_path = os.path.join(options.generator_output, xcodeproj_path)
+
+ for config in configurations:
+ arguments = ['xcodebuild', '-project', xcodeproj_path]
+ arguments += ['-configuration', config]
+ print "Building [%s]: %s" % (config, arguments)
+ subprocess.check_call(arguments)
+
+
def GenerateOutput(target_list, target_dicts, data, params):
options = params['options']
generator_flags = params.get('generator_flags', {})
diff --git a/tools/gyp/pylib/gyp/input.py b/tools/gyp/pylib/gyp/input.py
index 2678bab2c..65236671f 100644
--- a/tools/gyp/pylib/gyp/input.py
+++ b/tools/gyp/pylib/gyp/input.py
@@ -12,12 +12,17 @@ from compiler.ast import Stmt
import compiler
import copy
import gyp.common
+import multiprocessing
import optparse
import os.path
import re
import shlex
+import signal
import subprocess
import sys
+import threading
+import time
+from gyp.common import GypError
# A list of types that are treated as linkable.
@@ -79,6 +84,7 @@ base_non_configuration_keys = [
'rules',
'run_as',
'sources',
+ 'standalone_static_library',
'suppress_wildcard',
'target_name',
'toolset',
@@ -102,6 +108,7 @@ invalid_configuration_keys = [
'libraries',
'link_settings',
'sources',
+ 'standalone_static_library',
'target_name',
'type',
]
@@ -175,9 +182,9 @@ def CheckNode(node, keypath):
assert isinstance(c[n], Const)
key = c[n].getChildren()[0]
if key in dict:
- raise KeyError, "Key '" + key + "' repeated at level " + \
- repr(len(keypath) + 1) + " with key path '" + \
- '.'.join(keypath) + "'"
+ raise GypError("Key '" + key + "' repeated at level " +
+ repr(len(keypath) + 1) + " with key path '" +
+ '.'.join(keypath) + "'")
kp = list(keypath) # Make a copy of the list for descending this node.
kp.append(key)
dict[key] = CheckNode(c[n + 1], kp)
@@ -205,7 +212,7 @@ def LoadOneBuildFile(build_file_path, data, aux_data, variables, includes,
if os.path.exists(build_file_path):
build_file_contents = open(build_file_path).read()
else:
- raise Exception("%s not found (cwd: %s)" % (build_file_path, os.getcwd()))
+ raise GypError("%s not found (cwd: %s)" % (build_file_path, os.getcwd()))
build_file_data = None
try:
@@ -329,7 +336,7 @@ def ProcessToolsetsInDict(data):
# a build file that contains targets and is expected to provide a targets dict
# that contains the targets...
def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes,
- depth, check):
+ depth, check, load_dependencies):
# If depth is set, predefine the DEPTH variable to be a relative path from
# this build file's directory to the directory identified by depth.
if depth:
@@ -348,7 +355,7 @@ def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes,
if build_file_path in data['target_build_files']:
# Already loaded.
- return
+ return False
data['target_build_files'].add(build_file_path)
gyp.DebugOutput(gyp.DEBUG_INCLUDES,
@@ -363,7 +370,7 @@ def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes,
# Set up the included_files key indicating which .gyp files contributed to
# this target dict.
if 'included_files' in build_file_data:
- raise KeyError, build_file_path + ' must not contain included_files key'
+ raise GypError(build_file_path + ' must not contain included_files key')
included = GetIncludedBuildFiles(build_file_path, aux_data)
build_file_data['included_files'] = []
@@ -390,25 +397,25 @@ def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes,
# Look at each project's target_defaults dict, and merge settings into
# targets.
if 'target_defaults' in build_file_data:
+ if 'targets' not in build_file_data:
+ raise GypError("Unable to find targets in build file %s" %
+ build_file_path)
+
index = 0
- if 'targets' in build_file_data:
- while index < len(build_file_data['targets']):
- # This procedure needs to give the impression that target_defaults is
- # used as defaults, and the individual targets inherit from that.
- # The individual targets need to be merged into the defaults. Make
- # a deep copy of the defaults for each target, merge the target dict
- # as found in the input file into that copy, and then hook up the
- # copy with the target-specific data merged into it as the replacement
- # target dict.
- old_target_dict = build_file_data['targets'][index]
- new_target_dict = copy.deepcopy(build_file_data['target_defaults'])
- MergeDicts(new_target_dict, old_target_dict,
- build_file_path, build_file_path)
- build_file_data['targets'][index] = new_target_dict
- index = index + 1
- else:
- raise Exception, \
- "Unable to find targets in build file %s" % build_file_path
+ while index < len(build_file_data['targets']):
+ # This procedure needs to give the impression that target_defaults is
+ # used as defaults, and the individual targets inherit from that.
+ # The individual targets need to be merged into the defaults. Make
+ # a deep copy of the defaults for each target, merge the target dict
+ # as found in the input file into that copy, and then hook up the
+ # copy with the target-specific data merged into it as the replacement
+ # target dict.
+ old_target_dict = build_file_data['targets'][index]
+ new_target_dict = copy.deepcopy(build_file_data['target_defaults'])
+ MergeDicts(new_target_dict, old_target_dict,
+ build_file_path, build_file_path)
+ build_file_data['targets'][index] = new_target_dict
+ index += 1
# No longer needed.
del build_file_data['target_defaults']
@@ -418,22 +425,182 @@ def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes,
# in other words, you can't put a "dependencies" section inside a "post"
# conditional within a target.
+ dependencies = []
if 'targets' in build_file_data:
for target_dict in build_file_data['targets']:
if 'dependencies' not in target_dict:
continue
for dependency in target_dict['dependencies']:
- other_build_file = \
- gyp.common.ResolveTarget(build_file_path, dependency, None)[0]
- try:
- LoadTargetBuildFile(other_build_file, data, aux_data, variables,
- includes, depth, check)
- except Exception, e:
- gyp.common.ExceptionAppend(
- e, 'while loading dependencies of %s' % build_file_path)
- raise
+ dependencies.append(
+ gyp.common.ResolveTarget(build_file_path, dependency, None)[0])
+
+ if load_dependencies:
+ for dependency in dependencies:
+ try:
+ LoadTargetBuildFile(dependency, data, aux_data, variables,
+ includes, depth, check, load_dependencies)
+ except Exception, e:
+ gyp.common.ExceptionAppend(
+ e, 'while loading dependencies of %s' % build_file_path)
+ raise
+ else:
+ return (build_file_path, dependencies)
+
+
+def CallLoadTargetBuildFile(global_flags,
+ build_file_path, data,
+ aux_data, variables,
+ includes, depth, check):
+ """Wrapper around LoadTargetBuildFile for parallel processing.
+
+ This wrapper is used when LoadTargetBuildFile is executed in
+ a worker process.
+ """
+
+ try:
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+
+ # Apply globals so that the worker process behaves the same.
+ for key, value in global_flags.iteritems():
+ globals()[key] = value
+
+ # Save the keys so we can return data that changed.
+ data_keys = set(data)
+ aux_data_keys = set(aux_data)
+
+ result = LoadTargetBuildFile(build_file_path, data,
+ aux_data, variables,
+ includes, depth, check, False)
+ if not result:
+ return result
+
+ (build_file_path, dependencies) = result
+
+ data_out = {}
+ for key in data:
+ if key == 'target_build_files':
+ continue
+ if key not in data_keys:
+ data_out[key] = data[key]
+ aux_data_out = {}
+ for key in aux_data:
+ if key not in aux_data_keys:
+ aux_data_out[key] = aux_data[key]
+
+ # This gets serialized and sent back to the main process via a pipe.
+ # It's handled in LoadTargetBuildFileCallback.
+ return (build_file_path,
+ data_out,
+ aux_data_out,
+ dependencies)
+ except Exception, e:
+ print "Exception: ", e
+ return None
+
+
+class ParallelProcessingError(Exception):
+ pass
+
+
+class ParallelState(object):
+ """Class to keep track of state when processing input files in parallel.
+
+ If build files are loaded in parallel, use this to keep track of
+ state during farming out and processing parallel jobs. It's stored
+ in a global so that the callback function can have access to it.
+ """
+
+ def __init__(self):
+ # The multiprocessing pool.
+ self.pool = None
+ # The condition variable used to protect this object and notify
+ # the main loop when there might be more data to process.
+ self.condition = None
+ # The "data" dict that was passed to LoadTargetBuildFileParallel
+ self.data = None
+ # The "aux_data" dict that was passed to LoadTargetBuildFileParallel
+ self.aux_data = None
+ # The number of parallel calls outstanding; decremented when a response
+ # was received.
+ self.pending = 0
+ # The set of all build files that have been scheduled, so we don't
+ # schedule the same one twice.
+ self.scheduled = set()
+ # A list of dependency build file paths that haven't been scheduled yet.
+ self.dependencies = []
+ # Flag to indicate if there was an error in a child process.
+ self.error = False
- return data
+ def LoadTargetBuildFileCallback(self, result):
+ """Handle the results of running LoadTargetBuildFile in another process.
+ """
+ self.condition.acquire()
+ if not result:
+ self.error = True
+ self.condition.notify()
+ self.condition.release()
+ return
+ (build_file_path0, data0, aux_data0, dependencies0) = result
+ self.data['target_build_files'].add(build_file_path0)
+ for key in data0:
+ self.data[key] = data0[key]
+ for key in aux_data0:
+ self.aux_data[key] = aux_data0[key]
+ for new_dependency in dependencies0:
+ if new_dependency not in self.scheduled:
+ self.scheduled.add(new_dependency)
+ self.dependencies.append(new_dependency)
+ self.pending -= 1
+ self.condition.notify()
+ self.condition.release()
+
+
+def LoadTargetBuildFileParallel(build_file_path, data, aux_data,
+ variables, includes, depth, check):
+ parallel_state = ParallelState()
+ parallel_state.condition = threading.Condition()
+ parallel_state.dependencies = [build_file_path]
+ parallel_state.scheduled = set([build_file_path])
+ parallel_state.pending = 0
+ parallel_state.data = data
+ parallel_state.aux_data = aux_data
+
+ try:
+ parallel_state.condition.acquire()
+ while parallel_state.dependencies or parallel_state.pending:
+ if parallel_state.error:
+ break
+ if not parallel_state.dependencies:
+ parallel_state.condition.wait()
+ continue
+
+ dependency = parallel_state.dependencies.pop()
+
+ parallel_state.pending += 1
+ data_in = {}
+ data_in['target_build_files'] = data['target_build_files']
+ aux_data_in = {}
+ global_flags = {
+ 'path_sections': globals()['path_sections'],
+ 'non_configuration_keys': globals()['non_configuration_keys'],
+ 'absolute_build_file_paths': globals()['absolute_build_file_paths'],
+ 'multiple_toolsets': globals()['multiple_toolsets']}
+
+ if not parallel_state.pool:
+ parallel_state.pool = multiprocessing.Pool(8)
+ parallel_state.pool.apply_async(
+ CallLoadTargetBuildFile,
+ args = (global_flags, dependency,
+ data_in, aux_data_in,
+ variables, includes, depth, check),
+ callback = parallel_state.LoadTargetBuildFileCallback)
+ except KeyboardInterrupt, e:
+ parallel_state.pool.terminate()
+ raise e
+
+ parallel_state.condition.release()
+ if parallel_state.error:
+ sys.exit()
# Look for the bracket that matches the first bracket seen in a
@@ -693,8 +860,8 @@ def ExpandVariables(input, phase, variables, build_file):
os.chdir(oldwd)
assert replacement != None
elif command_string:
- raise Exception("Unknown command string '%s' in '%s'." %
- (command_string, contents))
+ raise GypError("Unknown command string '%s' in '%s'." %
+ (command_string, contents))
else:
# Fix up command with platform specific workarounds.
contents = FixupPlatformCommand(contents)
@@ -710,8 +877,8 @@ def ExpandVariables(input, phase, variables, build_file):
sys.stderr.write(p_stderr)
# Simulate check_call behavior, since check_call only exists
# in python 2.5 and later.
- raise Exception("Call to '%s' returned exit status %d." %
- (contents, p.returncode))
+ raise GypError("Call to '%s' returned exit status %d." %
+ (contents, p.returncode))
replacement = p_stdout.rstrip()
cached_command_results[cache_key] = replacement
@@ -735,8 +902,8 @@ def ExpandVariables(input, phase, variables, build_file):
# ],
replacement = []
else:
- raise KeyError, 'Undefined variable ' + contents + \
- ' in ' + build_file
+ raise GypError('Undefined variable ' + contents +
+ ' in ' + build_file)
else:
replacement = variables[contents]
@@ -744,10 +911,10 @@ def ExpandVariables(input, phase, variables, build_file):
for item in replacement:
if (not contents[-1] == '/' and
not isinstance(item, str) and not isinstance(item, int)):
- raise TypeError, 'Variable ' + contents + \
- ' must expand to a string or list of strings; ' + \
- 'list contains a ' + \
- item.__class__.__name__
+ raise GypError('Variable ' + contents +
+ ' must expand to a string or list of strings; ' +
+ 'list contains a ' +
+ item.__class__.__name__)
# Run through the list and handle variable expansions in it. Since
# the list is guaranteed not to contain dicts, this won't do anything
# with conditions sections.
@@ -755,9 +922,9 @@ def ExpandVariables(input, phase, variables, build_file):
build_file)
elif not isinstance(replacement, str) and \
not isinstance(replacement, int):
- raise TypeError, 'Variable ' + contents + \
- ' must expand to a string or list of strings; ' + \
- 'found a ' + replacement.__class__.__name__
+ raise GypError('Variable ' + contents +
+ ' must expand to a string or list of strings; ' +
+ 'found a ' + replacement.__class__.__name__)
if expand_to_list:
# Expanding in list context. It's guaranteed that there's only one
@@ -855,12 +1022,12 @@ def ProcessConditionsInDict(the_dict, phase, variables, build_file):
for condition in conditions_list:
if not isinstance(condition, list):
- raise TypeError, conditions_key + ' must be a list'
+ raise GypError(conditions_key + ' must be a list')
if len(condition) != 2 and len(condition) != 3:
# It's possible that condition[0] won't work in which case this
# attempt will raise its own IndexError. That's probably fine.
- raise IndexError, conditions_key + ' ' + condition[0] + \
- ' must be length 2 or 3, not ' + str(len(condition))
+ raise GypError(conditions_key + ' ' + condition[0] +
+ ' must be length 2 or 3, not ' + str(len(condition)))
[cond_expr, true_dict] = condition[0:2]
false_dict = None
@@ -1110,7 +1277,7 @@ def BuildTargetsDict(data):
target['target_name'],
target['toolset'])
if target_name in targets:
- raise KeyError, 'Duplicate target definitions for ' + target_name
+ raise GypError('Duplicate target definitions for ' + target_name)
targets[target_name] = target
return targets
@@ -1151,8 +1318,8 @@ def QualifyDependencies(targets):
# appears in the "dependencies" list.
if dependency_key != 'dependencies' and \
dependency not in target_dict['dependencies']:
- raise KeyError, 'Found ' + dependency + ' in ' + dependency_key + \
- ' of ' + target + ', but not in dependencies'
+ raise GypError('Found ' + dependency + ' in ' + dependency_key +
+ ' of ' + target + ', but not in dependencies')
def ExpandWildcardDependencies(targets, data):
@@ -1191,8 +1358,8 @@ def ExpandWildcardDependencies(targets, data):
if dependency_build_file == target_build_file:
# It's an error for a target to depend on all other targets in
# the same file, because a target cannot depend on itself.
- raise KeyError, 'Found wildcard in ' + dependency_key + ' of ' + \
- target + ' referring to same build file'
+ raise GypError('Found wildcard in ' + dependency_key + ' of ' +
+ target + ' referring to same build file')
# Take the wildcard out and adjust the index so that the next
# dependency in the list will be processed the next time through the
@@ -1249,7 +1416,7 @@ class DependencyGraphNode(object):
dependents: List of DependencyGraphNodes that depend on this one.
"""
- class CircularException(Exception):
+ class CircularException(GypError):
pass
def __init__(self, ref):
@@ -1396,14 +1563,14 @@ class DependencyGraphNode(object):
# but that's presently the easiest way to access the target dicts so that
# this function can find target types.
- if not 'target_name' in targets[self.ref]:
- raise Exception("Missing 'target_name' field in target.")
+ if 'target_name' not in targets[self.ref]:
+ raise GypError("Missing 'target_name' field in target.")
- try:
- target_type = targets[self.ref]['type']
- except KeyError, e:
- raise Exception("Missing 'type' field in target %s" %
- targets[self.ref]['target_name'])
+ if 'type' not in targets[self.ref]:
+ raise GypError("Missing 'type' field in target %s" %
+ targets[self.ref]['target_name'])
+
+ target_type = targets[self.ref]['type']
is_linkable = target_type in linkable_types
@@ -1447,7 +1614,7 @@ def BuildDependencyList(targets):
# access.
dependency_nodes = {}
for target, spec in targets.iteritems():
- if not target in dependency_nodes:
+ if target not in dependency_nodes:
dependency_nodes[target] = DependencyGraphNode(target)
# Set up the dependency links. Targets that have no dependencies are treated
@@ -1456,21 +1623,18 @@ def BuildDependencyList(targets):
for target, spec in targets.iteritems():
target_node = dependency_nodes[target]
target_build_file = gyp.common.BuildFile(target)
- if not 'dependencies' in spec or len(spec['dependencies']) == 0:
+ dependencies = spec.get('dependencies')
+ if not dependencies:
target_node.dependencies = [root_node]
root_node.dependents.append(target_node)
else:
- dependencies = spec['dependencies']
- for index in xrange(0, len(dependencies)):
- try:
- dependency = dependencies[index]
- dependency_node = dependency_nodes[dependency]
- target_node.dependencies.append(dependency_node)
- dependency_node.dependents.append(target_node)
- except KeyError, e:
- gyp.common.ExceptionAppend(e,
- 'while trying to load target %s' % target)
- raise
+ for dependency in dependencies:
+ dependency_node = dependency_nodes.get(dependency)
+ if not dependency_node:
+ raise GypError("Dependency '%s' not found while "
+ "trying to load target %s" % (dependency, target))
+ target_node.dependencies.append(dependency_node)
+ dependency_node.dependents.append(target_node)
flat_list = root_node.FlattenToList()
@@ -1478,9 +1642,9 @@ def BuildDependencyList(targets):
# (cycle). If you need to figure out what's wrong, look for elements of
# targets that are not in flat_list.
if len(flat_list) != len(targets):
- raise DependencyGraphNode.CircularException, \
- 'Some targets not reachable, cycle in dependency graph detected: ' + \
- ' '.join(set(flat_list) ^ set(targets))
+ raise DependencyGraphNode.CircularException(
+ 'Some targets not reachable, cycle in dependency graph detected: ' +
+ ' '.join(set(flat_list) ^ set(targets)))
return [dependency_nodes, flat_list]
@@ -1502,18 +1666,22 @@ def VerifyNoGYPFileCircularDependencies(targets):
for dependency in target_dependencies:
try:
dependency_build_file = gyp.common.BuildFile(dependency)
- if dependency_build_file == build_file:
- # A .gyp file is allowed to refer back to itself.
- continue
- dependency_node = dependency_nodes[dependency_build_file]
- if dependency_node not in build_file_node.dependencies:
- build_file_node.dependencies.append(dependency_node)
- dependency_node.dependents.append(build_file_node)
- except KeyError, e:
+ except GypError, e:
gyp.common.ExceptionAppend(
e, 'while computing dependencies of .gyp file %s' % build_file)
raise
+ if dependency_build_file == build_file:
+ # A .gyp file is allowed to refer back to itself.
+ continue
+ dependency_node = dependency_nodes.get(dependency_build_file)
+ if not dependency_node:
+ raise GypError("Dependancy '%s' not found" % dependency_build_file)
+ if dependency_node not in build_file_node.dependencies:
+ build_file_node.dependencies.append(dependency_node)
+ dependency_node.dependents.append(build_file_node)
+
+
# Files that have no dependencies are treated as dependent on root_node.
root_node = DependencyGraphNode(None)
for build_file_node in dependency_nodes.itervalues():
@@ -1552,8 +1720,8 @@ def DoDependentSettings(key, flat_list, targets, dependency_nodes):
elif key == 'link_settings':
dependencies = dependency_nodes[target].LinkDependencies(targets)
else:
- raise KeyError, "DoDependentSettings doesn't know how to determine " + \
- 'dependencies for ' + key
+ raise GypError("DoDependentSettings doesn't know how to determine "
+ 'dependencies for ' + key)
for dependency in dependencies:
dependency_dict = targets[dependency]
@@ -1819,8 +1987,8 @@ def MergeDicts(to, fro, to_file, fro_file):
# and prepend are the only policies that can coexist.
for list_incompatible in lists_incompatible:
if list_incompatible in fro:
- raise KeyError, 'Incompatible list policies ' + k + ' and ' + \
- list_incompatible
+ raise GypError('Incompatible list policies ' + k + ' and ' +
+ list_incompatible)
if list_base in to:
if ext == '?':
@@ -1952,8 +2120,8 @@ def SetUpConfigurations(target, target_dict):
configuration_dict = target_dict['configurations'][configuration]
for key in configuration_dict.keys():
if key in invalid_configuration_keys:
- raise KeyError, ('%s not allowed in the %s configuration, found in '
- 'target %s' % (key, configuration, target))
+ raise GypError('%s not allowed in the %s configuration, found in '
+ 'target %s' % (key, configuration, target))
@@ -2084,9 +2252,9 @@ def ProcessListFiltersInDict(name, the_dict):
# to be created.
excluded_key = list_key + '_excluded'
if excluded_key in the_dict:
- raise KeyError, \
- name + ' key ' + excluded_key + ' must not be present prior ' + \
- ' to applying exclusion/regex filters for ' + list_key
+ raise GypError(name + ' key ' + excluded_key +
+ ' must not be present prior '
+ ' to applying exclusion/regex filters for ' + list_key)
excluded_list = []
@@ -2136,9 +2304,14 @@ def ValidateTargetType(target, target_dict):
'none')
target_type = target_dict.get('type', None)
if target_type not in VALID_TARGET_TYPES:
- raise Exception("Target %s has an invalid target type '%s'. "
- "Must be one of %s." %
- (target, target_type, '/'.join(VALID_TARGET_TYPES)))
+ raise GypError("Target %s has an invalid target type '%s'. "
+ "Must be one of %s." %
+ (target, target_type, '/'.join(VALID_TARGET_TYPES)))
+ if (target_dict.get('standalone_static_library', 0) and
+ not target_type == 'static_library'):
+ raise GypError('Target %s has type %s but standalone_static_library flag is'
+ ' only valid for static_library type.' % (target,
+ target_type))
def ValidateSourcesInTarget(target, target_dict, build_file):
@@ -2162,10 +2335,10 @@ def ValidateSourcesInTarget(target, target_dict, build_file):
error += ' %s: %s\n' % (basename, ' '.join(files))
if error:
- print ('static library %s has several files with the same basename:\n' %
- target + error + 'Some build systems, e.g. MSVC08, '
- 'cannot handle that.')
- raise KeyError, 'Duplicate basenames in sources section, see list above'
+ print('static library %s has several files with the same basename:\n' %
+ target + error + 'Some build systems, e.g. MSVC08, '
+ 'cannot handle that.')
+ raise GypError('Duplicate basenames in sources section, see list above')
def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules):
@@ -2189,25 +2362,25 @@ def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules):
# Make sure that there's no conflict among rule names and extensions.
rule_name = rule['rule_name']
if rule_name in rule_names:
- raise KeyError, 'rule %s exists in duplicate, target %s' % \
- (rule_name, target)
+ raise GypError('rule %s exists in duplicate, target %s' %
+ (rule_name, target))
rule_names[rule_name] = rule
rule_extension = rule['extension']
if rule_extension in rule_extensions:
- raise KeyError, ('extension %s associated with multiple rules, ' +
- 'target %s rules %s and %s') % \
- (rule_extension, target,
- rule_extensions[rule_extension]['rule_name'],
- rule_name)
+ raise GypError(('extension %s associated with multiple rules, ' +
+ 'target %s rules %s and %s') %
+ (rule_extension, target,
+ rule_extensions[rule_extension]['rule_name'],
+ rule_name))
rule_extensions[rule_extension] = rule
# Make sure rule_sources isn't already there. It's going to be
# created below if needed.
if 'rule_sources' in rule:
- raise KeyError, \
- 'rule_sources must not exist in input, target %s rule %s' % \
- (target, rule_name)
+ raise GypError(
+ 'rule_sources must not exist in input, target %s rule %s' %
+ (target, rule_name))
extension = rule['extension']
rule_sources = []
@@ -2231,28 +2404,28 @@ def ValidateRunAsInTarget(target, target_dict, build_file):
if not run_as:
return
if not isinstance(run_as, dict):
- raise Exception("The 'run_as' in target %s from file %s should be a "
- "dictionary." %
- (target_name, build_file))
+ raise GypError("The 'run_as' in target %s from file %s should be a "
+ "dictionary." %
+ (target_name, build_file))
action = run_as.get('action')
if not action:
- raise Exception("The 'run_as' in target %s from file %s must have an "
- "'action' section." %
- (target_name, build_file))
+ raise GypError("The 'run_as' in target %s from file %s must have an "
+ "'action' section." %
+ (target_name, build_file))
if not isinstance(action, list):
- raise Exception("The 'action' for 'run_as' in target %s from file %s "
- "must be a list." %
- (target_name, build_file))
+ raise GypError("The 'action' for 'run_as' in target %s from file %s "
+ "must be a list." %
+ (target_name, build_file))
working_directory = run_as.get('working_directory')
if working_directory and not isinstance(working_directory, str):
- raise Exception("The 'working_directory' for 'run_as' in target %s "
- "in file %s should be a string." %
- (target_name, build_file))
+ raise GypError("The 'working_directory' for 'run_as' in target %s "
+ "in file %s should be a string." %
+ (target_name, build_file))
environment = run_as.get('environment')
if environment and not isinstance(environment, dict):
- raise Exception("The 'environment' for 'run_as' in target %s "
- "in file %s should be a dictionary." %
- (target_name, build_file))
+ raise GypError("The 'environment' for 'run_as' in target %s "
+ "in file %s should be a dictionary." %
+ (target_name, build_file))
def ValidateActionsInTarget(target, target_dict, build_file):
@@ -2262,15 +2435,15 @@ def ValidateActionsInTarget(target, target_dict, build_file):
for action in actions:
action_name = action.get('action_name')
if not action_name:
- raise Exception("Anonymous action in target %s. "
- "An action must have an 'action_name' field." %
- target_name)
+ raise GypError("Anonymous action in target %s. "
+ "An action must have an 'action_name' field." %
+ target_name)
inputs = action.get('inputs', None)
if inputs is None:
- raise Exception('Action in target %s has no inputs.' % target_name)
+ raise GypError('Action in target %s has no inputs.' % target_name)
action_command = action.get('action')
if action_command and not action_command[0]:
- raise Exception("Empty action as command in target %s." % target_name)
+ raise GypError("Empty action as command in target %s." % target_name)
def TurnIntIntoStrInDict(the_dict):
@@ -2327,13 +2500,13 @@ def VerifyNoCollidingTargets(targets):
key = subdir + ':' + name
if key in used:
# Complain if this target is already used.
- raise Exception('Duplicate target name "%s" in directory "%s" used both '
- 'in "%s" and "%s".' % (name, subdir, gyp, used[key]))
+ raise GypError('Duplicate target name "%s" in directory "%s" used both '
+ 'in "%s" and "%s".' % (name, subdir, gyp, used[key]))
used[key] = gyp
def Load(build_files, variables, includes, depth, generator_input_info, check,
- circular_check):
+ circular_check, parallel):
# Set up path_sections and non_configuration_keys with the default data plus
# the generator-specifc data.
global path_sections
@@ -2374,8 +2547,13 @@ def Load(build_files, variables, includes, depth, generator_input_info, check,
# used as keys to the data dict and for references between input files.
build_file = os.path.normpath(build_file)
try:
- LoadTargetBuildFile(build_file, data, aux_data, variables, includes,
- depth, check)
+ if parallel:
+ print >>sys.stderr, 'Using parallel processing (experimental).'
+ LoadTargetBuildFileParallel(build_file, data, aux_data,
+ variables, includes, depth, check)
+ else:
+ LoadTargetBuildFile(build_file, data, aux_data,
+ variables, includes, depth, check, True)
except Exception, e:
gyp.common.ExceptionAppend(e, 'while trying to load %s' % build_file)
raise
diff --git a/tools/gyp/pylib/gyp/mac_tool.py b/tools/gyp/pylib/gyp/mac_tool.py
index b918c5826..69267694d 100755
--- a/tools/gyp/pylib/gyp/mac_tool.py
+++ b/tools/gyp/pylib/gyp/mac_tool.py
@@ -163,9 +163,10 @@ class MacTool(object):
"""Calls libtool and filters out 'libtool: file: foo.o has no symbols'."""
libtool_re = re.compile(r'^libtool: file: .* has no symbols$')
libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE)
- for line in libtoolout.stderr:
+ _, err = libtoolout.communicate()
+ for line in err.splitlines():
if not libtool_re.match(line):
- sys.stderr.write(line)
+ print >>sys.stderr, line
return libtoolout.returncode
def ExecPackageFramework(self, framework, version):
diff --git a/tools/gyp/pylib/gyp/msvs_emulation.py b/tools/gyp/pylib/gyp/msvs_emulation.py
index 4a55aca05..840a79b67 100644
--- a/tools/gyp/pylib/gyp/msvs_emulation.py
+++ b/tools/gyp/pylib/gyp/msvs_emulation.py
@@ -152,6 +152,7 @@ class MsvsSettings(object):
('msvs_disabled_warnings', list),
('msvs_precompiled_header', str),
('msvs_precompiled_source', str),
+ ('msvs_configuration_platform', str),
('msvs_target_platform', str),
]
configs = spec['configurations']
@@ -165,8 +166,7 @@ class MsvsSettings(object):
def GetVSMacroEnv(self, base_to_build=None, config=None):
"""Get a dict of variables mapping internal VS macro names to their gyp
equivalents."""
- target_platform = self.GetTargetPlatform(config)
- target_platform = {'x86': 'Win32'}.get(target_platform, target_platform)
+ target_platform = 'Win32' if self.GetArch(config) == 'x86' else 'x64'
replacements = {
'$(VSInstallDir)': self.vs_version.Path(),
'$(VCInstallDir)': os.path.join(self.vs_version.Path(), 'VC') + '\\',
@@ -215,29 +215,40 @@ class MsvsSettings(object):
return self.parent._GetAndMunge(self.field, self.base_path + [name],
default=default, prefix=prefix, append=self.append, map=map)
- def GetTargetPlatform(self, config):
- target_platform = self.msvs_target_platform.get(config, '')
- if not target_platform:
- target_platform = 'Win32'
- return {'Win32': 'x86'}.get(target_platform, target_platform)
-
- def _RealConfig(self, config):
- target_platform = self.GetTargetPlatform(config)
- if target_platform == 'x64' and not config.endswith('_x64'):
+ def GetArch(self, config):
+ """Get architecture based on msvs_configuration_platform and
+ msvs_target_platform. Returns either 'x86' or 'x64'."""
+ configuration_platform = self.msvs_configuration_platform.get(config, '')
+ platform = self.msvs_target_platform.get(config, '')
+ if not platform: # If no specific override, use the configuration's.
+ platform = configuration_platform
+ # Map from platform to architecture.
+ return {'Win32': 'x86', 'x64': 'x64'}.get(platform, 'x86')
+
+ def _TargetConfig(self, config):
+ """Returns the target-specific configuration."""
+ # There's two levels of architecture/platform specification in VS. The
+ # first level is globally for the configuration (this is what we consider
+ # "the" config at the gyp level, which will be something like 'Debug' or
+ # 'Release_x64'), and a second target-specific configuration, which is an
+ # override for the global one. |config| is remapped here to take into
+ # account the local target-specific overrides to the global configuration.
+ arch = self.GetArch(config)
+ if arch == 'x64' and not config.endswith('_x64'):
config += '_x64'
+ if arch == 'x86' and config.endswith('_x64'):
+ config = config.rsplit('_', 1)[0]
return config
def _Setting(self, path, config,
default=None, prefix='', append=None, map=None):
"""_GetAndMunge for msvs_settings."""
- config = self._RealConfig(config)
return self._GetAndMunge(
self.msvs_settings[config], path, default, prefix, append, map)
def _ConfigAttrib(self, path, config,
default=None, prefix='', append=None, map=None):
"""_GetAndMunge for msvs_configuration_attributes."""
- config = self._RealConfig(config)
return self._GetAndMunge(
self.msvs_configuration_attributes[config],
path, default, prefix, append, map)
@@ -245,7 +256,7 @@ class MsvsSettings(object):
def AdjustIncludeDirs(self, include_dirs, config):
"""Updates include_dirs to expand VS specific paths, and adds the system
include dirs used for platform SDK and similar."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
includes = include_dirs + self.msvs_system_include_dirs[config]
includes.extend(self._Setting(
('VCCLCompilerTool', 'AdditionalIncludeDirectories'), config, default=[]))
@@ -254,7 +265,7 @@ class MsvsSettings(object):
def GetComputedDefines(self, config):
"""Returns the set of defines that are injected to the defines list based
on other VS settings."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
defines = []
if self._ConfigAttrib(['CharacterSet'], config) == '1':
defines.extend(('_UNICODE', 'UNICODE'))
@@ -267,7 +278,7 @@ class MsvsSettings(object):
def GetOutputName(self, config, expand_special):
"""Gets the explicitly overridden output name for a target or returns None
if it's not overridden."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
type = self.spec['type']
root = 'VCLibrarianTool' if type == 'static_library' else 'VCLinkerTool'
# TODO(scottmg): Handle OutputDirectory without OutputFile.
@@ -277,9 +288,19 @@ class MsvsSettings(object):
output_file, config=config))
return output_file
+ def GetPDBName(self, config, expand_special):
+ """Gets the explicitly overridden pdb name for a target or returns None
+ if it's not overridden."""
+ config = self._TargetConfig(config)
+ output_file = self._Setting(('VCLinkerTool', 'ProgramDatabaseFile'), config)
+ if output_file:
+ output_file = expand_special(self.ConvertVSMacros(
+ output_file, config=config))
+ return output_file
+
def GetCflags(self, config):
"""Returns the flags that need to be added to .c and .cc compilations."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
cflags = []
cflags.extend(['/wd' + w for w in self.msvs_disabled_warnings[config]])
cl = self._GetWrapper(self, self.msvs_settings[config],
@@ -302,6 +323,7 @@ class MsvsSettings(object):
cl('RuntimeLibrary',
map={'0': 'T', '1': 'Td', '2': 'D', '3': 'Dd'}, prefix='/M')
cl('ExceptionHandling', map={'1': 'sc','2': 'a'}, prefix='/EH')
+ cl('EnablePREfast', map={'true': '/analyze'})
cl('AdditionalOptions', prefix='')
# ninja handles parallelism by itself, don't have the compiler do it too.
cflags = filter(lambda x: not x.startswith('/MP'), cflags)
@@ -310,13 +332,13 @@ class MsvsSettings(object):
def GetPrecompiledHeader(self, config, gyp_to_build_path):
"""Returns an object that handles the generation of precompiled header
build steps."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
return _PchHelper(self, config, gyp_to_build_path)
def _GetPchFlags(self, config, extension):
"""Get the flags to be added to the cflags for precompiled header support.
"""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
# The PCH is only built once by a particular source file. Usage of PCH must
# only be for the same language (i.e. C vs. C++), so only include the pch
# flags when the language matches.
@@ -329,18 +351,18 @@ class MsvsSettings(object):
def GetCflagsC(self, config):
"""Returns the flags that need to be added to .c compilations."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
return self._GetPchFlags(config, '.c')
def GetCflagsCC(self, config):
"""Returns the flags that need to be added to .cc compilations."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
return ['/TP'] + self._GetPchFlags(config, '.cc')
def _GetAdditionalLibraryDirectories(self, root, config, gyp_to_build_path):
"""Get and normalize the list of paths in AdditionalLibraryDirectories
setting."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
libpaths = self._Setting((root, 'AdditionalLibraryDirectories'),
config, default=[])
libpaths = [os.path.normpath(
@@ -350,7 +372,7 @@ class MsvsSettings(object):
def GetLibFlags(self, config, gyp_to_build_path):
"""Returns the flags that need to be added to lib commands."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
libflags = []
lib = self._GetWrapper(self, self.msvs_settings[config],
'VCLibrarianTool', append=libflags)
@@ -374,7 +396,7 @@ class MsvsSettings(object):
manifest_base_name, is_executable):
"""Returns the flags that need to be added to link commands, and the
manifest files."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
ldflags = []
ld = self._GetWrapper(self, self.msvs_settings[config],
'VCLinkerTool', append=ldflags)
@@ -387,6 +409,9 @@ class MsvsSettings(object):
out = self.GetOutputName(config, expand_special)
if out:
ldflags.append('/OUT:' + out)
+ pdb = self.GetPDBName(config, expand_special)
+ if pdb:
+ ldflags.append('/PDB:' + pdb)
ld('AdditionalOptions', prefix='')
ld('SubSystem', map={'1': 'CONSOLE', '2': 'WINDOWS'}, prefix='/SUBSYSTEM:')
ld('LinkIncremental', map={'1': ':NO', '2': ''}, prefix='/INCREMENTAL')
@@ -401,6 +426,7 @@ class MsvsSettings(object):
ld('IgnoreDefaultLibraryNames', prefix='/NODEFAULTLIB:')
ld('ResourceOnlyDLL', map={'true': '/NOENTRY'})
ld('EntryPointSymbol', prefix='/ENTRY:')
+ ld('Profile', map={ 'true': '/PROFILE'})
# TODO(scottmg): This should sort of be somewhere else (not really a flag).
ld('AdditionalDependencies', prefix='')
# TODO(scottmg): These too.
@@ -466,14 +492,14 @@ class MsvsSettings(object):
def IsUseLibraryDependencyInputs(self, config):
"""Returns whether the target should be linked via Use Library Dependency
Inputs (using component .objs of a given .lib)."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
uldi = self._Setting(('VCLinkerTool', 'UseLibraryDependencyInputs'), config)
return uldi == 'true'
def GetRcflags(self, config, gyp_to_ninja_path):
"""Returns the flags that need to be added to invocations of the resource
compiler."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
rcflags = []
rc = self._GetWrapper(self, self.msvs_settings[config],
'VCResourceCompilerTool', append=rcflags)
@@ -510,18 +536,27 @@ class MsvsSettings(object):
return int(rule.get('msvs_cygwin_shell',
self.spec.get('msvs_cygwin_shell', 1))) != 0
- def HasExplicitIdlRules(self, spec):
- """Determine if there's an explicit rule for idl files. When there isn't we
- need to generate implicit rules to build MIDL .idl files."""
+ def _HasExplicitRuleForExtension(self, spec, extension):
+ """Determine if there's an explicit rule for a particular extension."""
for rule in spec.get('rules', []):
- if rule['extension'] == 'idl' and int(rule.get('msvs_external_rule', 0)):
+ if rule['extension'] == extension:
return True
return False
+ def HasExplicitIdlRules(self, spec):
+ """Determine if there's an explicit rule for idl files. When there isn't we
+ need to generate implicit rules to build MIDL .idl files."""
+ return self._HasExplicitRuleForExtension(spec, 'idl')
+
+ def HasExplicitAsmRules(self, spec):
+ """Determine if there's an explicit rule for asm files. When there isn't we
+ need to generate implicit rules to assemble .asm files."""
+ return self._HasExplicitRuleForExtension(spec, 'asm')
+
def GetIdlBuildData(self, source, config):
"""Determine the implicit outputs for an idl file. Returns output
directory, outputs, and variables and flags that are required."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
midl_get = self._GetWrapper(self, self.msvs_settings[config], 'VCMIDLTool')
def midl(name, default=None):
return self.ConvertVSMacros(midl_get(name, default=default),
@@ -689,3 +724,19 @@ def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags, open_out):
f = open_out(os.path.join(toplevel_build_dir, 'environment.' + arch), 'wb')
f.write(env_block)
f.close()
+
+def VerifyMissingSources(sources, build_dir, generator_flags, gyp_to_ninja):
+ """Emulate behavior of msvs_error_on_missing_sources present in the msvs
+ generator: Check that all regular source files, i.e. not created at run time,
+ exist on disk. Missing files cause needless recompilation when building via
+ VS, and we want this check to match for people/bots that build using ninja,
+ so they're not surprised when the VS build fails."""
+ if int(generator_flags.get('msvs_error_on_missing_sources', 0)):
+ no_specials = filter(lambda x: '$' not in x, sources)
+ relative = [os.path.join(build_dir, gyp_to_ninja(s)) for s in no_specials]
+ missing = filter(lambda x: not os.path.exists(x), relative)
+ if missing:
+ # They'll look like out\Release\..\..\stuff\things.cc, so normalize the
+ # path for a slightly less crazy looking output.
+ cleaned_up = [os.path.normpath(x) for x in missing]
+ raise Exception('Missing input files:\n%s' % '\n'.join(cleaned_up))
diff --git a/tools/gyp/pylib/gyp/ninja_syntax.py b/tools/gyp/pylib/gyp/ninja_syntax.py
index ae85d0f54..0f3603a8c 100644
--- a/tools/gyp/pylib/gyp/ninja_syntax.py
+++ b/tools/gyp/pylib/gyp/ninja_syntax.py
@@ -12,8 +12,8 @@ use Python.
import textwrap
import re
-def escape_spaces(word):
- return word.replace('$ ','$$ ').replace(' ','$ ')
+def escape_path(word):
+ return word.replace('$ ','$$ ').replace(' ','$ ').replace(':', '$:')
class Writer(object):
def __init__(self, output, width=78):
@@ -35,8 +35,7 @@ class Writer(object):
self._line('%s = %s' % (key, value), indent)
def rule(self, name, command, description=None, depfile=None,
- generator=False, restat=False, rspfile=None,
- rspfile_content=None):
+ generator=False, restat=False, rspfile=None, rspfile_content=None):
self._line('rule %s' % name)
self.variable('command', command, indent=1)
if description:
@@ -56,15 +55,15 @@ class Writer(object):
variables=None):
outputs = self._as_list(outputs)
all_inputs = self._as_list(inputs)[:]
- out_outputs = list(map(escape_spaces, outputs))
- all_inputs = list(map(escape_spaces, all_inputs))
+ out_outputs = list(map(escape_path, outputs))
+ all_inputs = list(map(escape_path, all_inputs))
if implicit:
- implicit = map(escape_spaces, self._as_list(implicit))
+ implicit = map(escape_path, self._as_list(implicit))
all_inputs.append('|')
all_inputs.extend(implicit)
if order_only:
- order_only = map(escape_spaces, self._as_list(order_only))
+ order_only = map(escape_path, self._as_list(order_only))
all_inputs.append('||')
all_inputs.extend(order_only)
diff --git a/tools/gyp/pylib/gyp/system_test.py b/tools/gyp/pylib/gyp/system_test.py
deleted file mode 100755
index 51c71e36b..000000000
--- a/tools/gyp/pylib/gyp/system_test.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2011 Google Inc. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import tempfile
-import shutil
-import subprocess
-
-
-def TestCommands(commands, files={}, env={}):
- """Run commands in a temporary directory, returning true if they all succeed.
- Return false on failures or if any commands produce output.
-
- Arguments:
- commands: an array of shell-interpretable commands, e.g. ['ls -l', 'pwd']
- each will be expanded with Python %-expansion using env first.
- files: a dictionary mapping filename to contents;
- files will be created in the temporary directory before running
- the command.
- env: a dictionary of strings to expand commands with.
- """
- tempdir = tempfile.mkdtemp()
- try:
- for name, contents in files.items():
- f = open(os.path.join(tempdir, name), 'wb')
- f.write(contents)
- f.close()
- for command in commands:
- proc = subprocess.Popen(command % env, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- cwd=tempdir)
- output = proc.communicate()[0]
- if proc.returncode != 0 or output:
- return False
- return True
- finally:
- shutil.rmtree(tempdir)
- return False
-
-
-def TestArSupportsT(ar_command='ar', cc_command='cc'):
- """Test whether 'ar' supports the 'T' flag."""
- return TestCommands(['%(cc)s -c test.c',
- '%(ar)s crsT test.a test.o',
- '%(cc)s test.a'],
- files={'test.c': 'int main(){}'},
- env={'ar': ar_command, 'cc': cc_command})
-
-
-def main():
- # Run the various test functions and print the results.
- def RunTest(description, function, **kwargs):
- print "Testing " + description + ':',
- if function(**kwargs):
- print 'ok'
- else:
- print 'fail'
- RunTest("ar 'T' flag", TestArSupportsT)
- RunTest("ar 'T' flag with ccache", TestArSupportsT, cc_command='ccache cc')
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/tools/gyp/pylib/gyp/win_tool.py b/tools/gyp/pylib/gyp/win_tool.py
index c9c6a7b5a..7b0657363 100644..100755
--- a/tools/gyp/pylib/gyp/win_tool.py
+++ b/tools/gyp/pylib/gyp/win_tool.py
@@ -9,13 +9,13 @@
These functions are executed via gyp-win-tool when using the ninja generator.
"""
+from ctypes import windll, wintypes
import os
import shutil
import subprocess
import sys
-import win32con
-import win32file
-import pywintypes
+
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
def main(args):
@@ -26,19 +26,28 @@ def main(args):
class LinkLock(object):
- """A flock-style lock to limit the number of concurrent links to one. Based on
- http://code.activestate.com/recipes/65203-portalocker-cross-platform-posixnt-api-for-flock-s/
+ """A flock-style lock to limit the number of concurrent links to one.
+
+ Uses a session-local mutex based on the file's directory.
"""
def __enter__(self):
- self.file = open('LinkLock', 'w+')
- self.file_handle = win32file._get_osfhandle(self.file.fileno())
- win32file.LockFileEx(self.file_handle, win32con.LOCKFILE_EXCLUSIVE_LOCK,
- 0, -0x10000, pywintypes.OVERLAPPED())
+ name = 'Local\\%s' % BASE_DIR.replace('\\', '_').replace(':', '_')
+ self.mutex = windll.kernel32.CreateMutexW(
+ wintypes.c_int(0),
+ wintypes.c_int(0),
+ wintypes.create_unicode_buffer(name))
+ assert self.mutex
+ result = windll.kernel32.WaitForSingleObject(
+ self.mutex, wintypes.c_int(0xFFFFFFFF))
+ # 0x80 means another process was killed without releasing the mutex, but
+ # that this process has been given ownership. This is fine for our
+ # purposes.
+ assert result in (0, 0x80), (
+ "%s, %s" % (result, windll.kernel32.GetLastError()))
def __exit__(self, type, value, traceback):
- win32file.UnlockFileEx(
- self.file_handle, 0, -0x10000, pywintypes.OVERLAPPED())
- self.file.close()
+ windll.kernel32.ReleaseMutex(self.mutex)
+ windll.kernel32.CloseHandle(self.mutex)
class WinTool(object):
@@ -170,16 +179,6 @@ class WinTool(object):
print line
return popen.returncode
- def ExecClWrapper(self, arch, depname, *args):
- """Runs cl.exe and filters output through ninja-deplist-helper to get
- dependendency information which is stored in |depname|."""
- env = self._GetEnv(arch)
- args = ' '.join(args) + \
- '| ninja-deplist-helper -r . -q -f cl -o ' + depname + '"'
- popen = subprocess.Popen(args, shell=True, env=env)
- popen.wait()
- return popen.returncode
-
def ExecActionWrapper(self, arch, rspfile, *dir):
"""Runs an action command line from a response file using the environment
for |arch|. If |dir| is supplied, use that as the working directory."""
diff --git a/tools/gyp/pylib/gyp/xcode_emulation.py b/tools/gyp/pylib/gyp/xcode_emulation.py
index 32b6f3524..ef5b46046 100644
--- a/tools/gyp/pylib/gyp/xcode_emulation.py
+++ b/tools/gyp/pylib/gyp/xcode_emulation.py
@@ -562,6 +562,22 @@ class XcodeSettings(object):
self.configname = None
return ldflags
+ def GetLibtoolflags(self, configname):
+ """Returns flags that need to be passed to the static linker.
+
+ Args:
+ configname: The name of the configuration to get ld flags for.
+ """
+ self.configname = configname
+ libtoolflags = []
+
+ for libtoolflag in self._Settings().get('OTHER_LDFLAGS', []):
+ libtoolflags.append(libtoolflag)
+ # TODO(thakis): ARCHS?
+
+ self.configname = None
+ return libtoolflags
+
def GetPerTargetSettings(self):
"""Gets a list of all the per-target settings. This will only fetch keys
whose values are the same across all configurations."""
@@ -923,6 +939,11 @@ def _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration,
'TARGET_BUILD_DIR' : built_products_dir,
'TEMP_DIR' : '${TMPDIR}',
}
+ if xcode_settings.GetPerTargetSetting('SDKROOT'):
+ env['SDKROOT'] = xcode_settings._SdkPath()
+ else:
+ env['SDKROOT'] = ''
+
if spec['type'] in (
'executable', 'static_library', 'shared_library', 'loadable_module'):
env['EXECUTABLE_NAME'] = xcode_settings.GetExecutableName()
diff --git a/tools/gyp/pylib/gyp/xcodeproj_file.py b/tools/gyp/pylib/gyp/xcodeproj_file.py
index 5124ed0bf..ec4cb96bc 100644
--- a/tools/gyp/pylib/gyp/xcodeproj_file.py
+++ b/tools/gyp/pylib/gyp/xcodeproj_file.py
@@ -254,7 +254,7 @@ class XCObject(object):
but in some cases an object's parent may wish to push a
hashable value into its child, and it can do so by appending
to _hashables.
- Attribues:
+ Attributes:
id: The object's identifier, a 24-character uppercase hexadecimal string.
Usually, objects being created should not set id until the entire
project file structure is built. At that point, UpdateIDs() should
@@ -392,7 +392,10 @@ class XCObject(object):
return hashables
- def ComputeIDs(self, recursive=True, overwrite=True, hash=None):
+ def HashablesForChild(self):
+ return None
+
+ def ComputeIDs(self, recursive=True, overwrite=True, seed_hash=None):
"""Set "id" properties deterministically.
An object's "id" property is set based on a hash of its class type and
@@ -419,8 +422,10 @@ class XCObject(object):
hash.update(struct.pack('>i', len(data)))
hash.update(data)
- if hash is None:
- hash = _new_sha1()
+ if seed_hash is None:
+ seed_hash = _new_sha1()
+
+ hash = seed_hash.copy()
hashables = self.Hashables()
assert len(hashables) > 0
@@ -428,8 +433,17 @@ class XCObject(object):
_HashUpdate(hash, hashable)
if recursive:
+ hashables_for_child = self.HashablesForChild()
+ if hashables_for_child is None:
+ child_hash = hash
+ else:
+ assert len(hashables_for_child) > 0
+ child_hash = seed_hash.copy()
+ for hashable in hashables_for_child:
+ _HashUpdate(child_hash, hashable)
+
for child in self.Children():
- child.ComputeIDs(recursive, overwrite, hash.copy())
+ child.ComputeIDs(recursive, overwrite, child_hash)
if overwrite or self.id is None:
# Xcode IDs are only 96 bits (24 hex characters), but a SHA-1 digest is
@@ -1104,6 +1118,26 @@ class PBXGroup(XCHierarchicalElement):
for child in self._properties.get('children', []):
self._AddChildToDicts(child)
+ def Hashables(self):
+ # super
+ hashables = XCHierarchicalElement.Hashables(self)
+
+ # It is not sufficient to just rely on name and parent to build a unique
+ # hashable : a node could have two child PBXGroup sharing a common name.
+ # To add entropy the hashable is enhanced with the names of all its
+ # children.
+ for child in self._properties.get('children', []):
+ child_name = child.Name()
+ if child_name != None:
+ hashables.append(child_name)
+
+ return hashables
+
+ def HashablesForChild(self):
+ # To avoid a circular reference the hashables used to compute a child id do
+ # not include the child names.
+ return XCHierarchicalElement.Hashables(self)
+
def _AddChildToDicts(self, child):
# Sets up this PBXGroup object's dicts to reference the child properly.
child_path = child.PathFromSourceTreeAndPath()
@@ -1440,40 +1474,41 @@ class PBXFileReference(XCFileLikeElement, XCContainerPortal, XCRemoteObject):
# TODO(mark): This is the replacement for a replacement for a quick hack.
# It is no longer incredibly sucky, but this list needs to be extended.
extension_map = {
- 'a': 'archive.ar',
- 'app': 'wrapper.application',
- 'bdic': 'file',
- 'bundle': 'wrapper.cfbundle',
- 'c': 'sourcecode.c.c',
- 'cc': 'sourcecode.cpp.cpp',
- 'cpp': 'sourcecode.cpp.cpp',
- 'css': 'text.css',
- 'cxx': 'sourcecode.cpp.cpp',
- 'dylib': 'compiled.mach-o.dylib',
- 'framework': 'wrapper.framework',
- 'h': 'sourcecode.c.h',
- 'hxx': 'sourcecode.cpp.h',
- 'icns': 'image.icns',
- 'java': 'sourcecode.java',
- 'js': 'sourcecode.javascript',
- 'm': 'sourcecode.c.objc',
- 'mm': 'sourcecode.cpp.objcpp',
- 'nib': 'wrapper.nib',
- 'o': 'compiled.mach-o.objfile',
- 'pdf': 'image.pdf',
- 'pl': 'text.script.perl',
- 'plist': 'text.plist.xml',
- 'pm': 'text.script.perl',
- 'png': 'image.png',
- 'py': 'text.script.python',
- 'r': 'sourcecode.rez',
- 'rez': 'sourcecode.rez',
- 's': 'sourcecode.asm',
- 'strings': 'text.plist.strings',
- 'ttf': 'file',
- 'xcconfig': 'text.xcconfig',
- 'xib': 'file.xib',
- 'y': 'sourcecode.yacc',
+ 'a': 'archive.ar',
+ 'app': 'wrapper.application',
+ 'bdic': 'file',
+ 'bundle': 'wrapper.cfbundle',
+ 'c': 'sourcecode.c.c',
+ 'cc': 'sourcecode.cpp.cpp',
+ 'cpp': 'sourcecode.cpp.cpp',
+ 'css': 'text.css',
+ 'cxx': 'sourcecode.cpp.cpp',
+ 'dylib': 'compiled.mach-o.dylib',
+ 'framework': 'wrapper.framework',
+ 'h': 'sourcecode.c.h',
+ 'hxx': 'sourcecode.cpp.h',
+ 'icns': 'image.icns',
+ 'java': 'sourcecode.java',
+ 'js': 'sourcecode.javascript',
+ 'm': 'sourcecode.c.objc',
+ 'mm': 'sourcecode.cpp.objcpp',
+ 'nib': 'wrapper.nib',
+ 'o': 'compiled.mach-o.objfile',
+ 'pdf': 'image.pdf',
+ 'pl': 'text.script.perl',
+ 'plist': 'text.plist.xml',
+ 'pm': 'text.script.perl',
+ 'png': 'image.png',
+ 'py': 'text.script.python',
+ 'r': 'sourcecode.rez',
+ 'rez': 'sourcecode.rez',
+ 's': 'sourcecode.asm',
+ 'strings': 'text.plist.strings',
+ 'ttf': 'file',
+ 'xcconfig': 'text.xcconfig',
+ 'xcdatamodel': 'wrapper.xcdatamodel',
+ 'xib': 'file.xib',
+ 'y': 'sourcecode.yacc',
}
if is_dir:
diff --git a/tools/gyp_addon b/tools/gyp_addon
deleted file mode 100755
index b6f2d643b..000000000
--- a/tools/gyp_addon
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env python
-import os
-import sys
-
-script_dir = os.path.dirname(__file__)
-node_root = os.path.abspath(os.path.join(script_dir, os.pardir))
-module_root = os.getcwd()
-if sys.platform == 'win32':
- output_dir = os.path.join(module_root, 'build')
-else:
- output_dir = 'build'
-
-sys.path.insert(0, os.path.join(node_root, 'tools', 'gyp', 'pylib'))
-import gyp
-
-if __name__ == '__main__':
- args = sys.argv[1:]
- addon_gypi = os.path.join(node_root, 'tools', 'addon.gypi')
- common_gypi = os.path.join(node_root, 'common.gypi')
- config_gypi = os.path.join(node_root, 'config.gypi')
- args.extend(['-I', addon_gypi])
- args.extend(['-I', common_gypi])
- if os.path.exists(config_gypi):
- args.extend(['-I', config_gypi])
- args.extend(['-Dlibrary=shared_library'])
- args.extend(['-Dvisibility=default'])
- args.extend(['-Dnode_root_dir=%s' % node_root])
- args.extend(['-Dmodule_root_dir=%s' % module_root])
- args.extend(['--depth=.']);
-
- # Tell gyp to write the Makefile/Solution files into output_dir
- args.extend(['--generator-output', output_dir])
-
- # Tell make to write its output into the same dir
- args.extend(['-Goutput_dir=.'])
-
- gyp_args = list(args)
- rc = gyp.main(gyp_args)
- if rc != 0:
- print 'Error running GYP'
- sys.exit(rc)
-
diff --git a/tools/gyp_node b/tools/gyp_node
index 5c4882f4f..7b495055c 100755
--- a/tools/gyp_node
+++ b/tools/gyp_node
@@ -44,8 +44,7 @@ if __name__ == '__main__':
args.append('--depth=' + node_root)
# There's a bug with windows which doesn't allow this feature.
- if sys.platform != 'win32':
-
+ if sys.platform != 'win32' and 'ninja' not in args:
# Tell gyp to write the Makefiles into output_dir
args.extend(['--generator-output', output_dir])
diff --git a/tools/install.py b/tools/install.py
index 8ff7c395f..c8ad828c1 100755
--- a/tools/install.py
+++ b/tools/install.py
@@ -79,60 +79,6 @@ def try_remove(path, dst):
def install(paths, dst): map(lambda path: try_copy(path, dst), paths)
def uninstall(paths, dst): map(lambda path: try_remove(path, dst), paths)
-def waf_files(action):
- action(['tools/node-waf'], 'bin/node-waf')
- action(['tools/wafadmin/ansiterm.py',
- 'tools/wafadmin/Build.py',
- 'tools/wafadmin/Configure.py',
- 'tools/wafadmin/Constants.py',
- 'tools/wafadmin/Environment.py',
- 'tools/wafadmin/__init__.py',
- 'tools/wafadmin/Logs.py',
- 'tools/wafadmin/Node.py',
- 'tools/wafadmin/Options.py',
- 'tools/wafadmin/pproc.py',
- 'tools/wafadmin/py3kfixes.py',
- 'tools/wafadmin/Runner.py',
- 'tools/wafadmin/Scripting.py',
- 'tools/wafadmin/TaskGen.py',
- 'tools/wafadmin/Task.py',
- 'tools/wafadmin/Utils.py'],
- 'lib/node/wafadmin/')
- action(['tools/wafadmin/Tools/ar.py',
- 'tools/wafadmin/Tools/cc.py',
- 'tools/wafadmin/Tools/ccroot.py',
- 'tools/wafadmin/Tools/compiler_cc.py',
- 'tools/wafadmin/Tools/compiler_cxx.py',
- 'tools/wafadmin/Tools/compiler_d.py',
- 'tools/wafadmin/Tools/config_c.py',
- 'tools/wafadmin/Tools/cxx.py',
- 'tools/wafadmin/Tools/dmd.py',
- 'tools/wafadmin/Tools/d.py',
- 'tools/wafadmin/Tools/gas.py',
- 'tools/wafadmin/Tools/gcc.py',
- 'tools/wafadmin/Tools/gdc.py',
- 'tools/wafadmin/Tools/gnu_dirs.py',
- 'tools/wafadmin/Tools/gob2.py',
- 'tools/wafadmin/Tools/gxx.py',
- 'tools/wafadmin/Tools/icc.py',
- 'tools/wafadmin/Tools/icpc.py',
- 'tools/wafadmin/Tools/__init__.py',
- 'tools/wafadmin/Tools/intltool.py',
- 'tools/wafadmin/Tools/libtool.py',
- 'tools/wafadmin/Tools/misc.py',
- 'tools/wafadmin/Tools/nasm.py',
- 'tools/wafadmin/Tools/node_addon.py',
- 'tools/wafadmin/Tools/osx.py',
- 'tools/wafadmin/Tools/preproc.py',
- 'tools/wafadmin/Tools/python.py',
- 'tools/wafadmin/Tools/suncc.py',
- 'tools/wafadmin/Tools/suncxx.py',
- 'tools/wafadmin/Tools/unittestw.py',
- 'tools/wafadmin/Tools/winres.py',
- 'tools/wafadmin/Tools/xlc.py',
- 'tools/wafadmin/Tools/xlcxx.py'],
- 'lib/node/wafadmin/Tools/')
-
def update_shebang(path, shebang):
print 'updating shebang of %s to %s' % (path, shebang)
s = open(path, 'r').read()
@@ -173,29 +119,7 @@ def npm_files(action):
assert(0) # unhandled action type
def files(action):
- action(['deps/uv/include/ares.h',
- 'deps/uv/include/ares_version.h',
- 'deps/uv/include/uv.h',
- 'deps/v8/include/v8-debug.h',
- 'deps/v8/include/v8-preparser.h',
- 'deps/v8/include/v8-profiler.h',
- 'deps/v8/include/v8-testing.h',
- 'deps/v8/include/v8.h',
- 'deps/v8/include/v8stdint.h',
- 'src/eio-emul.h',
- 'src/ev-emul.h',
- 'src/node.h',
- 'src/node_buffer.h',
- 'src/node_object_wrap.h',
- 'src/node_version.h'],
- 'include/node/')
- action(['deps/uv/include/uv-private/eio.h',
- 'deps/uv/include/uv-private/ev.h',
- 'deps/uv/include/uv-private/ngx-queue.h',
- 'deps/uv/include/uv-private/tree.h',
- 'deps/uv/include/uv-private/uv-unix.h',
- 'deps/uv/include/uv-private/uv-win.h'],
- 'include/node/uv-private/')
+ action(['doc/node.1'], 'share/man/man1/')
action(['out/Release/node'], 'bin/node')
# install unconditionally, checking if the platform supports dtrace doesn't
@@ -208,7 +132,6 @@ def files(action):
else:
action(['doc/node.1'], 'share/man/man1/')
- if 'true' == variables.get('node_install_waf'): waf_files(action)
if 'true' == variables.get('node_install_npm'): npm_files(action)
def run(args):
diff --git a/tools/js2c.py b/tools/js2c.py
index 69ec8a83c..772a0f5f6 100755
--- a/tools/js2c.py
+++ b/tools/js2c.py
@@ -206,7 +206,7 @@ def ReadMacros(lines):
fun = eval("lambda " + ",".join(args) + ': ' + body)
macros[name] = PythonMacro(args, fun)
else:
- raise ("Illegal line: " + line)
+ raise Exception("Illegal line: " + line)
return (constants, macros)
@@ -227,7 +227,7 @@ static const struct _native natives[] = {
%(native_lines)s\
- { NULL, NULL } /* sentinel */
+ { NULL, NULL, 0 } /* sentinel */
};
@@ -266,13 +266,17 @@ def JS2C(source, target):
# Locate the macros file name.
consts = {}
macros = {}
+ macro_lines = []
for s in source:
- if 'macros.py' == (os.path.split(str(s))[1]):
- (consts, macros) = ReadMacros(ReadLines(str(s)))
+ if (os.path.split(str(s))[1]).endswith('macros.py'):
+ macro_lines.extend(ReadLines(str(s)))
else:
modules.append(s)
+ # Process input from all *macro.py files
+ (consts, macros) = ReadMacros(macro_lines)
+
# Build source code lines
source_lines = [ ]
source_lines_empty = []
diff --git a/tools/msvs/genfiles/MSG00001.bin b/tools/msvs/genfiles/MSG00001.bin
new file mode 100644
index 000000000..051a5d8ca
--- /dev/null
+++ b/tools/msvs/genfiles/MSG00001.bin
Binary files differ
diff --git a/tools/msvs/genfiles/node_etw_provider.h b/tools/msvs/genfiles/node_etw_provider.h
new file mode 100644
index 000000000..f9f21ad35
--- /dev/null
+++ b/tools/msvs/genfiles/node_etw_provider.h
@@ -0,0 +1,59 @@
+//**********************************************************************`
+//* This is an include file generated by Message Compiler. *`
+//* *`
+//* Copyright (c) Microsoft Corporation. All Rights Reserved. *`
+//**********************************************************************`
+#pragma once
+//+
+// Provider NodeJS-ETW-provider Event Count 12
+//+
+EXTERN_C __declspec(selectany) const GUID NODE_ETW_PROVIDER = {0x77754e9b, 0x264b, 0x4d8d, {0xb9, 0x81, 0xe4, 0x13, 0x5c, 0x1e, 0xcb, 0x0c}};
+
+//
+// Opcodes
+//
+#define NODE_ETW_PROVIDER_OPCODE_NODE_HTTP_SERVER_REQUEST 0xa
+#define NODE_ETW_PROVIDER_OPCODE_NODE_HTTP_SERVER_RESPONSE 0xb
+#define NODE_ETW_PROVIDER_OPCODE_NODE_HTTP_CLIENT_REQUEST 0xc
+#define NODE_ETW_PROVIDER_OPCODE_NODE_HTTP_CLIENT_RESPONSE 0xd
+#define NODE_ETW_PROVIDER_OPCODE_NODE_NET_SERVER_CONNECTION 0xe
+#define NODE_ETW_PROVIDER_OPCODE_NODE_NET_STREAM_END 0xf
+#define NODE_ETW_PROVIDER_OPCODE_NODE_GC_START 0x10
+#define NODE_ETW_PROVIDER_OPCODE_NODE_GC_DONE 0x11
+#define NODE_ETW_PROVIDER_OPCODE_NODE_V8SYMBOL_REMOVE 0x15
+#define NODE_ETW_PROVIDER_OPCODE_NODE_V8SYMBOL_MOVE 0x16
+#define NODE_ETW_PROVIDER_OPCODE_NODE_V8SYMBOL_RESET 0x17
+#define JSCRIPT_METHOD_METHODLOAD_OPCODE 0xa
+
+//
+// Tasks
+//
+#define JSCRIPT_METHOD_RUNTIME_TASK 0x1
+
+//
+// Event Descriptors
+//
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_HTTP_SERVER_REQUEST_EVENT = {0x1, 0x0, 0x0, 0x4, 0xa, 0x0, 0x0};
+#define NODE_HTTP_SERVER_REQUEST_EVENT_value 0x1
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_HTTP_SERVER_RESPONSE_EVENT = {0x2, 0x0, 0x0, 0x4, 0xb, 0x0, 0x0};
+#define NODE_HTTP_SERVER_RESPONSE_EVENT_value 0x2
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_HTTP_CLIENT_REQUEST_EVENT = {0x3, 0x0, 0x0, 0x4, 0xc, 0x0, 0x0};
+#define NODE_HTTP_CLIENT_REQUEST_EVENT_value 0x3
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_HTTP_CLIENT_RESPONSE_EVENT = {0x4, 0x0, 0x0, 0x4, 0xd, 0x0, 0x0};
+#define NODE_HTTP_CLIENT_RESPONSE_EVENT_value 0x4
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_NET_SERVER_CONNECTION_EVENT = {0x5, 0x0, 0x0, 0x4, 0xe, 0x0, 0x0};
+#define NODE_NET_SERVER_CONNECTION_EVENT_value 0x5
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_NET_STREAM_END_EVENT = {0x6, 0x0, 0x0, 0x4, 0xf, 0x0, 0x0};
+#define NODE_NET_STREAM_END_EVENT_value 0x6
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_GC_START_EVENT = {0x7, 0x0, 0x0, 0x4, 0x10, 0x0, 0x0};
+#define NODE_GC_START_EVENT_value 0x7
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_GC_DONE_EVENT = {0x8, 0x0, 0x0, 0x4, 0x11, 0x0, 0x0};
+#define NODE_GC_DONE_EVENT_value 0x8
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR MethodLoad = {0x9, 0x0, 0x0, 0x4, 0xa, 0x1, 0x0};
+#define MethodLoad_value 0x9
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_V8SYMBOL_REMOVE_EVENT = {0x15, 0x0, 0x0, 0x4, 0x15, 0x0, 0x0};
+#define NODE_V8SYMBOL_REMOVE_EVENT_value 0x15
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_V8SYMBOL_MOVE_EVENT = {0x16, 0x0, 0x0, 0x4, 0x16, 0x0, 0x0};
+#define NODE_V8SYMBOL_MOVE_EVENT_value 0x16
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NODE_V8SYMBOL_RESET_EVENT = {0x17, 0x0, 0x0, 0x4, 0x17, 0x0, 0x0};
+#define NODE_V8SYMBOL_RESET_EVENT_value 0x17
diff --git a/tools/msvs/genfiles/node_etw_provider.rc b/tools/msvs/genfiles/node_etw_provider.rc
new file mode 100644
index 000000000..90b56169b
--- /dev/null
+++ b/tools/msvs/genfiles/node_etw_provider.rc
@@ -0,0 +1,3 @@
+LANGUAGE 0x9,0x1
+1 11 "MSG00001.bin"
+1 WEVT_TEMPLATE "node_etw_providerTEMP.BIN"
diff --git a/tools/msvs/genfiles/node_etw_providerTEMP.BIN b/tools/msvs/genfiles/node_etw_providerTEMP.BIN
new file mode 100644
index 000000000..32bede338
--- /dev/null
+++ b/tools/msvs/genfiles/node_etw_providerTEMP.BIN
Binary files differ
diff --git a/tools/msvs/genfiles/node_perfctr_provider.h b/tools/msvs/genfiles/node_perfctr_provider.h
new file mode 100644
index 000000000..30f0b5862
--- /dev/null
+++ b/tools/msvs/genfiles/node_perfctr_provider.h
@@ -0,0 +1,79 @@
+/* This file was auto-generated from src\res\node_perfctr_provider.man by ctrpp.exe */
+
+#pragma once
+
+
+EXTERN_C DECLSPEC_SELECTANY GUID NodeCounterProviderGuid = { 0x1e2e15d7, 0x3760, 0x470e, 0x86, 0x99, 0xb9, 0xdb, 0x52, 0x48, 0xed, 0xd5 };
+
+EXTERN_C DECLSPEC_SELECTANY GUID NodeCounterSetGuid = { 0x3a22a8ec, 0x297c, 0x48ac, 0xab, 0x15, 0x33, 0xec, 0x93, 0x3, 0x3f, 0xd8 };
+
+
+EXTERN_C DECLSPEC_SELECTANY HANDLE NodeCounterProvider = NULL;
+
+EXTERN_C DECLSPEC_SELECTANY struct {
+ PERF_COUNTERSET_INFO CounterSet;
+ PERF_COUNTER_INFO Counter0;
+ PERF_COUNTER_INFO Counter1;
+ PERF_COUNTER_INFO Counter2;
+ PERF_COUNTER_INFO Counter3;
+ PERF_COUNTER_INFO Counter4;
+ PERF_COUNTER_INFO Counter5;
+ PERF_COUNTER_INFO Counter6;
+ PERF_COUNTER_INFO Counter7;
+ PERF_COUNTER_INFO Counter8;
+ PERF_COUNTER_INFO Counter9;
+} NodeCounterSetInfo = {
+ { { 0x3a22a8ec, 0x297c, 0x48ac, 0xab, 0x15, 0x33, 0xec, 0x93, 0x3, 0x3f, 0xd8 }, { 0x1e2e15d7, 0x3760, 0x470e, 0x86, 0x99, 0xb9, 0xdb, 0x52, 0x48, 0xed, 0xd5 }, 10, PERF_COUNTERSET_MULTI_AGGREGATE },
+ { 1, PERF_COUNTER_COUNTER, 0, sizeof(ULONG), PERF_DETAIL_NOVICE, 0, 0 },
+ { 2, PERF_COUNTER_COUNTER, 0, sizeof(ULONG), PERF_DETAIL_NOVICE, 0, 0 },
+ { 3, PERF_COUNTER_COUNTER, 0, sizeof(ULONG), PERF_DETAIL_NOVICE, 0, 0 },
+ { 4, PERF_COUNTER_COUNTER, 0, sizeof(ULONG), PERF_DETAIL_NOVICE, 0, 0 },
+ { 5, PERF_COUNTER_RAWCOUNT, 0, sizeof(ULONG), PERF_DETAIL_NOVICE, 0, 0 },
+ { 6, PERF_COUNTER_BULK_COUNT, 0, sizeof(ULONGLONG), PERF_DETAIL_NOVICE, 4294967293, 0 },
+ { 7, PERF_COUNTER_BULK_COUNT, 0, sizeof(ULONGLONG), PERF_DETAIL_NOVICE, 4294967293, 0 },
+ { 8, PERF_COUNTER_RAWCOUNT, 0, sizeof(ULONG), PERF_DETAIL_NOVICE, 0, 0 },
+ { 9, PERF_COUNTER_BULK_COUNT, 0, sizeof(ULONGLONG), PERF_DETAIL_NOVICE, 4294967293, 0 },
+ { 10, PERF_COUNTER_BULK_COUNT, 0, sizeof(ULONGLONG), PERF_DETAIL_NOVICE, 4294967293, 0 },
+};
+
+EXTERN_C FORCEINLINE
+VOID
+CounterCleanup(
+ VOID
+ )
+{
+ if (NodeCounterProvider != NULL) {
+ PerfStopProvider(NodeCounterProvider);
+ NodeCounterProvider = NULL;
+ }
+}
+
+EXTERN_C FORCEINLINE
+ULONG
+CounterInitialize(
+ VOID
+ )
+{
+ ULONG Status;
+ PERF_PROVIDER_CONTEXT ProviderContext;
+
+ ZeroMemory(&ProviderContext, sizeof(PERF_PROVIDER_CONTEXT));
+ ProviderContext.ContextSize = sizeof(PERF_PROVIDER_CONTEXT);
+
+ Status = PerfStartProviderEx(&NodeCounterProviderGuid,
+ &ProviderContext,
+ &NodeCounterProvider);
+ if (Status != ERROR_SUCCESS) {
+ NodeCounterProvider = NULL;
+ return Status;
+ }
+
+ Status = PerfSetCounterSetInfo(NodeCounterProvider,
+ &NodeCounterSetInfo.CounterSet,
+ sizeof NodeCounterSetInfo);
+ if (Status != ERROR_SUCCESS) {
+ CounterCleanup();
+ return Status;
+ }
+ return ERROR_SUCCESS;
+}
diff --git a/tools/msvs/genfiles/node_perfctr_provider.rc b/tools/msvs/genfiles/node_perfctr_provider.rc
new file mode 100644
index 000000000..c7816f5fa
--- /dev/null
+++ b/tools/msvs/genfiles/node_perfctr_provider.rc
@@ -0,0 +1,36 @@
+STRINGTABLE
+BEGIN
+ 1 "Node.js"
+ 2 "Node.js" // {Locked} means don't localize
+ 3 "Node.js performance counters"
+ 5 "HTTP server requests"
+ 6 "HTTP server requests" // {Locked} means don't localize
+ 7 "Number of HTTP server requests"
+ 9 "HTTP server responses"
+ 10 "HTTP server responses" // {Locked} means don't localize
+ 11 "Number of HTTP server responses"
+ 13 "HTTP client requests"
+ 14 "HTTP client requests" // {Locked} means don't localize
+ 15 "Number of HTTP client requests"
+ 17 "HTTP client responses"
+ 18 "HTTP client responses" // {Locked} means don't localize
+ 19 "Number of HTTP client responses"
+ 21 "Active server connections"
+ 22 "Active server connections" // {Locked} means don't localize
+ 23 "Number of server connections"
+ 25 "Network bytes sent"
+ 26 "Network bytes sent" // {Locked} means don't localize
+ 27 "Number of bytes sent using TCP"
+ 29 "Network bytes received"
+ 30 "Network bytes received" // {Locked} means don't localize
+ 31 "Number of bytes received using TCP"
+ 33 "%Time in GC"
+ 34 "%Time in GC" // {Locked} means don't localize
+ 35 "Percent of time for last GC"
+ 37 "Pipe bytes sent"
+ 38 "Pipe bytes sent" // {Locked} means don't localize
+ 39 "Number of bytes sent using pipe"
+ 41 "Pipe bytes received"
+ 42 "Pipe bytes received" // {Locked} means don't localize
+ 43 "Number of bytes received using pipe"
+END
diff --git a/tools/msvs/msi/WixUI_en-us.wxl b/tools/msvs/msi/WixUI_en-us.wxl
new file mode 100644
index 000000000..76ca68a1e
--- /dev/null
+++ b/tools/msvs/msi/WixUI_en-us.wxl
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="InstallDirDlgDescription">Choose a custom location or click Next to install</String>
+</WixLocalization>
diff --git a/tools/msvs/msi/nodemsi.wixproj b/tools/msvs/msi/nodemsi.wixproj
index 7cc35c07e..4520e28ae 100644
--- a/tools/msvs/msi/nodemsi.wixproj
+++ b/tools/msvs/msi/nodemsi.wixproj
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -16,26 +15,32 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>..\..\..\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
- <DefineConstants>Debug;ProductVersion=$(NodeVersion);NoETW=$(NoETW);NPMSourceDir=..\..\..\deps\npm\;ProgramFilesFolderId=ProgramFilesFolder</DefineConstants>
+ <DefineConstants>Debug;ProductVersion=$(NodeVersion);NoETW=$(NoETW);NoPerfCtr=$(NoPerfCtr);NPMSourceDir=..\..\..\deps\npm\;ProgramFilesFolderId=ProgramFilesFolder</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>..\..\..\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
- <DefineConstants>Debug;ProductVersion=$(NodeVersion);NoETW=$(NoETW);NPMSourceDir=..\..\..\deps\npm\;ProgramFilesFolderId=ProgramFilesFolder</DefineConstants>
+ <DefineConstants>Debug;ProductVersion=$(NodeVersion);NoETW=$(NoETW);NoPerfCtr=$(NoPerfCtr);NPMSourceDir=..\..\..\deps\npm\;ProgramFilesFolderId=ProgramFilesFolder</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<OutputPath>..\..\..\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
- <DefineConstants>Debug;ProductVersion=$(NodeVersion);NoETW=$(NoETW);NPMSourceDir=..\..\..\deps\npm\;ProgramFilesFolderId=ProgramFiles64Folder</DefineConstants>
+ <DefineConstants>Debug;ProductVersion=$(NodeVersion);NoETW=$(NoETW);NoPerfCtr=$(NoPerfCtr);NPMSourceDir=..\..\..\deps\npm\;ProgramFilesFolderId=ProgramFiles64Folder</DefineConstants>
+ <Cultures>en-US</Cultures>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<OutputPath>..\..\..\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
- <DefineConstants>Debug;ProductVersion=$(NodeVersion);NoETW=$(NoETW);NPMSourceDir=..\..\..\deps\npm\;ProgramFilesFolderId=ProgramFiles64Folder</DefineConstants>
+ <DefineConstants>Debug;ProductVersion=$(NodeVersion);NoETW=$(NoETW);NoPerfCtr=$(NoPerfCtr);NPMSourceDir=..\..\..\deps\npm\;ProgramFilesFolderId=ProgramFiles64Folder</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup>
+ <EnableProjectHarvesting>True</EnableProjectHarvesting>
</PropertyGroup>
<ItemGroup>
<Compile Include="product.wxs" />
- <Compile Include="..\..\..\npm.wxs" />
+ <Compile Include="..\..\..\npm.wxs">
+ <Link>npm.wxs</Link>
+ </Compile>
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixUIExtension">
@@ -47,9 +52,16 @@
<Name>WiXUtilExtension</Name>
</WixExtension>
</ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="WixUI_en-us.wxl" />
+ </ItemGroup>
<Import Project="$(WixTargetsPath)" />
- <Target Name="BeforeBuild">
- <HeatDirectory ToolPath="$(WixToolPath)" Directory="..\..\..\deps\npm" PreprocessorVariable="var.NPMSourceDir" DirectoryRefId="NodeModulesFolder" ComponentGroupName="NPMFiles" GenerateGuidsNow="true" SuppressFragments="false" OutputFile="..\..\..\npm.wxs">
- </HeatDirectory>
- </Target>
-</Project>
+ <Target Name="BeforeBuild">
+ <HeatDirectory ToolPath="$(WixToolPath)" Directory="..\..\..\deps\npm" PreprocessorVariable="var.NPMSourceDir" DirectoryRefId="NodeModulesFolder" ComponentGroupName="NPMFiles" GenerateGuidsNow="true" SuppressFragments="false" OutputFile="..\..\..\npm.wxs">
+ </HeatDirectory>
+ </Target>
+ <PropertyGroup>
+ <PostBuildEvent>move !(TargetPath) $(TargetDir)\$(TargetFileName)
+move !(TargetPdbPath) $(TargetDir)\$(TargetPdbName)</PostBuildEvent>
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/tools/msvs/msi/product.wxs b/tools/msvs/msi/product.wxs
index 443739dc2..7b5e58837 100755
--- a/tools/msvs/msi/product.wxs
+++ b/tools/msvs/msi/product.wxs
@@ -25,6 +25,13 @@
<Icon Id="node.exe" SourceFile="$(var.RepoDir)\src\res\node.ico"/>
<Property Id="ARPPRODUCTICON" Value="node.exe" />
+ <Property Id="ApplicationFolderName" Value="nodejs" />
+ <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
+
+ <Property Id="INSTALLDIR">
+ <RegistrySearch Id='InstallPathRegistry' Type='raw'
+ Root='HKCU' Key='SOFTWARE\Joyent\Node.js\Installer' Name='PreviousPath' />
+ </Property>
<Directory Id="TARGETDIR" Name="SourceDir">
@@ -33,7 +40,7 @@
</Directory>
<Directory Id="$(var.ProgramFilesFolderId)">
- <Directory Id="APPLICATIONROOTDIRECTORY" Name="nodejs">
+ <Directory Id="INSTALLDIR" Name="nodejs">
<Directory Id="NodeModulesFolder" Name="node_modules">
<Directory Id="NPMFolder" Name="npm">
<Component Id="npmrc" Guid="55B2B03F-8F32-4D62-A54A-FA428615591D">
@@ -45,7 +52,12 @@
<File Id="filenodeexe" KeyPath="yes" Source="$(var.SourceDir)\node.exe" />
<?if $(var.NoETW) != 1 ?>
<File Id="node_etw_provider_man" Name="node_etw_provider.man" Source="$(var.RepoDir)\src\res\node_etw_provider.man" >
- <util:EventManifest MessageFile="[APPLICATIONROOTDIRECTORY]node.exe" ResourceFile="[APPLICATIONROOTDIRECTORY]node.exe"/>
+ <util:EventManifest MessageFile="[INSTALLDIR]node.exe" ResourceFile="[INSTALLDIR]node.exe"/>
+ </File>
+ <?endif?>
+ <?if $(var.NoPerfCtr) != 1 ?>
+ <File Id="node_perfctr_provider_man" Name="node_perfctr_provider.man" Source="$(var.RepoDir)\src\res\node_perfctr_provider.man" >
+ <util:PerfCounterManifest ResourceFileDirectory="[INSTALLDIR]"/>
</File>
<?endif?>
<Environment Id="npm_env"
@@ -59,7 +71,7 @@
Name="PATH"
Part="last"
System="yes"
- Value="[APPLICATIONROOTDIRECTORY]" />
+ Value="[INSTALLDIR]" />
</Component>
<Component Id="npmcmd" Guid="31e9986d-74cd-44e1-878c-194d3e997d32">
<File Id="filenpmcmd" KeyPath="yes" Source="$(var.NPMSourceDir)\bin\npm.cmd" />
@@ -75,13 +87,24 @@
<Component Id="nodejsvars" Guid="*">
<File Id="filenodejsvars" KeyPath="yes" Source="$(var.RepoDir)\tools\msvs\nodejsvars.bat" />
</Component>
+ <Component Id="noderegistry" Guid="*" >
+ <RegistryKey Root="HKCU" Key="Software">
+ <RegistryKey Key="Joyent">
+ <RegistryKey Key="Node.js">
+ <RegistryKey Key="Installer">
+ <RegistryValue Name="PreviousPath" Type="string" Value="[INSTALLDIR]" KeyPath="yes" />
+ </RegistryKey>
+ </RegistryKey>
+ </RegistryKey>
+ </RegistryKey>
+ </Component>
</Directory>
</Directory>
<Directory Id="AppDataFolder">
<Directory Id="NPMAppData" Name="npm">
<Component Id="npmappdata_folder" Guid="994B1F7F-60CD-4792-A96D-63BC7FFF29BF" Permanent="yes">
- <RegistryKey Action="none" Key="dummy" Root="HKCU" >
+ <RegistryKey Key="dummy" Root="HKCU" >
<RegistryValue Type="integer" Value="1" KeyPath="yes" />
</RegistryKey >
<CreateFolder/>
@@ -94,13 +117,22 @@
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="9b1ab94a-8f54-4f19-a5c4-b890de474162">
<Shortcut Id="ApplicationStartMenuShortcut" Name="Node.js"
- Description="$(var.ProductDescription)" Target="[APPLICATIONROOTDIRECTORY]node.exe"
- WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
+ Description="$(var.ProductDescription)" Target="[INSTALLDIR]node.exe"
+ WorkingDirectory="INSTALLDIR"/>
<Shortcut Id="NodePromptStartMenuShortcut" Name="Node.js command prompt"
Description="Node.js Command Prompt" Target="[%ComSpec]"
- Arguments='/k "[APPLICATIONROOTDIRECTORY]nodejsvars.bat"'
+ Arguments='/k "[INSTALLDIR]nodejsvars.bat"'
Show="normal"
- WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
+ WorkingDirectory="INSTALLDIR"/>
+ <Shortcut Id="UninstallProduct"
+ Name="Uninstall Node.js"
+ Target="[SystemFolder]msiexec.exe"
+ Arguments="/x [ProductCode]"
+ Description="Uninstalls $(var.ProductName)" />
+ <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
+ <RegistryValue Root="HKCU" Key="Software\Joyent\$(var.ProductName)" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
+ </Component>
+ <Component Id="InternetShortcuts" Guid="3351B877-49BA-4BC0-BF5E-21BA623FD07C">
<util:InternetShortcut Id="OnlineWebsiteShortcut"
Name="Node.js website"
Target="http://nodejs.org"
@@ -109,17 +141,10 @@
Name="Node.js documentation"
Target="http://nodejs.org/dist/v$(var.ProductVersion)/docs/api/"
Type="url"/>
- <Shortcut Id="UninstallProduct"
- Name="Uninstall Node.js"
- Target="[SystemFolder]msiexec.exe"
- Arguments="/x [ProductCode]"
- Description="Uninstalls $(var.ProductName)" />
- <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\Joyent\$(var.ProductName)" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</DirectoryRef>
-
<ComponentGroup Id="allfiles">
<ComponentRef Id="nodeexe"/>
<ComponentRef Id="npmcmd"/>
@@ -130,22 +155,39 @@
<?if $(var.Configuration) = Debug ?>
<ComponentRef Id="nodepdb"/>
<?endif?>
- <ComponentRef Id="ApplicationShortcut" />
<ComponentRef Id="nodejsvars" />
+ <ComponentRef Id="noderegistry" />
+ </ComponentGroup>
+
+ <ComponentGroup Id="application.shortcuts">
+ <ComponentRef Id="ApplicationShortcut" />
+ </ComponentGroup>
+
+ <ComponentGroup Id="internet.shortcuts">
+ <ComponentRef Id="InternetShortcuts"/>
</ComponentGroup>
- <Feature Id="nodejs" Title="node.js engine" Level="1" Description="$(var.ProductDescription)">
+ <Feature Id="nodejs" Title="node.js engine" Level="1" Description="$(var.ProductDescription)" Absent="disallow">
<ComponentGroupRef Id="allfiles" />
<ComponentGroupRef Id="Product.Generated" />
</Feature>
+ <Feature Id="nodejs.shortcuts" Title="node.js shortcuts" Level="1" Description="$(var.ProductDescription) Shortcuts">
+ <Feature Id="nodejs.shortcuts.application" Title="Application Shortcuts" Level="1" Description="$(var.ProductDescription) standard application shortcuts">
+ <ComponentGroupRef Id="application.shortcuts"/>
+ </Feature>
+ <Feature Id="nodejs.shortcuts.internet" Title="Internet Shortcuts" Level="1" Description="$(var.ProductDescription) internet shortcuts to the project's website and online documentation for this version">
+ <ComponentGroupRef Id="internet.shortcuts"/>
+ </Feature>
+ </Feature>
+
<UI Id="NodeInstallUI">
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
- <Property Id="WixUI_Mode" Value="Minimal" />
+ <Property Id="WixUI_Mode" Value="FeatureTree" />
<DialogRef Id="ErrorDlg" />
<DialogRef Id="FatalError" />
@@ -157,20 +199,34 @@
<DialogRef Id="UserExit" />
<DialogRef Id="WelcomeDlg" />
<DialogRef Id="LicenseAgreementDlg"/>
+ <DialogRef Id="InstallDirDlg"/>
+ <DialogRef Id="BrowseDlg"/>
+ <DialogRef Id="InvalidDirDlg"/>
- <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
+ <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
+ <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
<Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
- <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="PrepareDlg">1</Publish>
+ <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAccepted = "1"</Publish>
+ <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="CustomizeDlg" Order="20">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="10">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="10">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="20">1</Publish>
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
- <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="CustomizeDlg" Order="1">NOT Installed OR WixUI_InstallMode = "Change"</Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="3">Installed AND PATCH</Publish>
+ <Publish Dialog="MaintenanceTypeDlg" Control="ChangeButton" Event="NewDialog" Value="CustomizeDlg">1</Publish>
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
+ <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="1">Installed</Publish>
+ <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="2">NOT Installed</Publish>
+ <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Property Id="ARPNOMODIFY" Value="1" />
<Property Id="WIXUI_EXITDIALOGOPTIONALTEXT" Value="Node.js has been succesfully installed. To run Node.js open command prompt (cmd.exe), and run 'node'." />
-
</UI>
<UIRef Id="WixUI_Common" />
diff --git a/tools/node-waf b/tools/node-waf
deleted file mode 100755
index cbf0d0b80..000000000
--- a/tools/node-waf
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env python
-import os, sys
-
-
-join = os.path.join
-bindir = os.path.dirname(os.path.realpath(__file__))
-prefix = join(bindir, "..")
-wafdir = join(prefix, "lib", "node")
-
-w = join(wafdir, 'wafadmin')
-t = join(w, 'Tools')
-sys.path = [w, t] + sys.path
-
-import Scripting
-VERSION="1.5.16"
-Scripting.prepare(t, os.getcwd(), VERSION, wafdir)
-sys.exit(0)
diff --git a/tools/test.py b/tools/test.py
index a8dc89493..140358e4c 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -400,10 +400,20 @@ class TestCase(object):
def Run(self):
self.BeforeRun()
+
try:
result = self.RunCommand(self.GetCommand())
finally:
- self.AfterRun(result)
+ # Tests can leave the tty in non-blocking mode. If the test runner
+ # tries to print to stdout/stderr after that and the tty buffer is
+ # full, it'll die with a EAGAIN OSError. Ergo, put the tty back in
+ # blocking mode before proceeding.
+ if sys.platform != 'win32':
+ from fcntl import fcntl, F_GETFL, F_SETFL
+ from os import O_NONBLOCK
+ for fd in 0,1,2: fcntl(fd, F_SETFL, ~O_NONBLOCK & fcntl(fd, F_GETFL))
+
+ self.AfterRun(result)
return result
def Cleanup(self):
@@ -657,6 +667,7 @@ class LiteralTestSuite(TestSuite):
if not name or name.match(test_name):
full_path = current_path + [test_name]
test.AddTestsToList(result, full_path, path, context, mode)
+ result.sort(cmp=lambda a, b: cmp(a.GetName(), b.GetName()))
return result
def GetTestStatus(self, context, sections, defs):
diff --git a/tools/waf-light b/tools/waf-light
deleted file mode 100755
index b4acc4b19..000000000
--- a/tools/waf-light
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/usr/bin/env python
-# encoding: ISO8859-1
-# Thomas Nagy, 2005-2010
-
-"""
-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. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 AUTHOR 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.
-"""
-
-import os, sys
-if sys.hexversion<0x203000f: raise ImportError("Waf requires Python >= 2.3")
-
-if 'PSYCOWAF' in os.environ:
- try:import psyco;psyco.full()
- except:pass
-
-VERSION="1.5.16"
-REVISION="x"
-INSTALL="x"
-C1='x'
-C2='x'
-cwd = os.getcwd()
-join = os.path.join
-
-WAF='waf'
-def b(x):
- return x
-
-if sys.hexversion>0x300000f:
- WAF='waf3'
- def b(x):
- return x.encode()
-
-def err(m):
- print(('\033[91mError: %s\033[0m' % m))
- sys.exit(1)
-
-def unpack_wafdir(dir):
- f = open(sys.argv[0],'rb')
- c = "corrupted waf (%d)"
- while 1:
- line = f.readline()
- if not line: err("run waf-light from a folder containing wafadmin")
- if line == b('#==>\n'):
- txt = f.readline()
- if not txt: err(c % 1)
- if f.readline()!=b('#<==\n'): err(c % 2)
- break
- if not txt: err(c % 3)
- txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r'))
-
- import shutil, tarfile
- try: shutil.rmtree(dir)
- except OSError: pass
- try:
- for x in ['Tools', '3rdparty']:
- os.makedirs(join(dir, 'wafadmin', x))
- except OSError:
- err("Cannot unpack waf lib into %s\nMove waf into a writeable directory" % dir)
-
- os.chdir(dir)
- tmp = 't.bz2'
- t = open(tmp,'wb')
- t.write(txt)
- t.close()
-
- t = None
- try:
- t = tarfile.open(tmp)
- except:
- try:
- os.system('bunzip2 t.bz2')
- t = tarfile.open('t')
- except:
- os.chdir(cwd)
- try: shutil.rmtree(dir)
- except OSError: pass
- err("Waf cannot be unpacked, check that bzip2 support is present")
-
- for x in t: t.extract(x)
- t.close()
-
- for x in ['Tools', '3rdparty']:
- os.chmod(join('wafadmin',x), 493)
-
- if sys.hexversion>0x300000f:
- sys.path = [join(dir, 'wafadmin')] + sys.path
- import py3kfixes
- py3kfixes.fixdir(dir)
-
- os.chdir(cwd)
-
-def test(dir):
- try: os.stat(join(dir, 'wafadmin')); return os.path.abspath(dir)
- except OSError: pass
-
-def find_lib():
- name = sys.argv[0]
- base = os.path.dirname(os.path.abspath(name))
-
- #devs use $WAFDIR
- w=test(os.environ.get('WAFDIR', ''))
- if w: return w
-
- #waf-light
- if name.endswith('waf-light'):
- w = test(base)
- if w: return w
- err("waf-light requires wafadmin -> export WAFDIR=/folder")
-
- dir = "/lib/%s-%s-%s/" % (WAF, VERSION, REVISION)
- for i in [INSTALL,'/usr','/usr/local','/opt']:
- w = test(i+dir)
- if w: return w
-
- #waf-local
- s = '.%s-%s-%s'
- if sys.platform == 'win32': s = s[1:]
- dir = join(base, s % (WAF, VERSION, REVISION))
- w = test(dir)
- if w: return w
-
- #unpack
- unpack_wafdir(dir)
- return dir
-
-wafdir = find_lib()
-w = join(wafdir, 'wafadmin')
-t = join(w, 'Tools')
-f = join(w, '3rdparty')
-sys.path = [w, t, f] + sys.path
-
-if __name__ == '__main__':
- import Scripting
- Scripting.prepare(t, cwd, VERSION, wafdir)
-
diff --git a/tools/wafadmin/Build.py b/tools/wafadmin/Build.py
deleted file mode 100644
index 675bca1c4..000000000
--- a/tools/wafadmin/Build.py
+++ /dev/null
@@ -1,1021 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005 (ita)
-
-"""
-Dependency tree holder
-
-The class Build holds all the info related to a build:
-* file system representation (tree of Node instances)
-* various cached objects (task signatures, file scan results, ..)
-
-There is only one Build object at a time (bld singleton)
-"""
-
-import os, sys, errno, re, glob, gc, datetime, shutil
-try: import cPickle
-except: import pickle as cPickle
-import Runner, TaskGen, Node, Scripting, Utils, Environment, Task, Logs, Options
-from Logs import debug, error, info
-from Constants import *
-
-SAVED_ATTRS = 'root srcnode bldnode node_sigs node_deps raw_deps task_sigs id_nodes'.split()
-"Build class members to save"
-
-bld = None
-"singleton - safe to use when Waf is not used as a library"
-
-class BuildError(Utils.WafError):
- def __init__(self, b=None, t=[]):
- self.bld = b
- self.tasks = t
- self.ret = 1
- Utils.WafError.__init__(self, self.format_error())
-
- def format_error(self):
- lst = ['Build failed:']
- for tsk in self.tasks:
- txt = tsk.format_error()
- if txt: lst.append(txt)
- sep = ' '
- if len(lst) > 2:
- sep = '\n'
- return sep.join(lst)
-
-def group_method(fun):
- """
- sets a build context method to execute after the current group has finished executing
- this is useful for installing build files:
- * calling install_files/install_as will fail if called too early
- * people do not want to define install method in their task classes
-
- TODO: try it
- """
- def f(*k, **kw):
- if not k[0].is_install:
- return False
-
- postpone = True
- if 'postpone' in kw:
- postpone = kw['postpone']
- del kw['postpone']
-
- # TODO waf 1.6 in theory there should be no reference to the TaskManager internals here
- if postpone:
- m = k[0].task_manager
- if not m.groups: m.add_group()
- m.groups[m.current_group].post_funs.append((fun, k, kw))
- if not 'cwd' in kw:
- kw['cwd'] = k[0].path
- else:
- fun(*k, **kw)
- return f
-
-class BuildContext(Utils.Context):
- "holds the dependency tree"
- def __init__(self):
-
- # not a singleton, but provided for compatibility
- global bld
- bld = self
-
- self.task_manager = Task.TaskManager()
-
- # instead of hashing the nodes, we assign them a unique id when they are created
- self.id_nodes = 0
- self.idx = {}
-
- # map names to environments, the 'Release' must be defined
- self.all_envs = {}
-
- # ======================================= #
- # code for reading the scripts
-
- # project build directory - do not reset() from load_dirs()
- self.bdir = ''
-
- # the current directory from which the code is run
- # the folder changes everytime a wscript is read
- self.path = None
-
- # Manual dependencies.
- self.deps_man = Utils.DefaultDict(list)
-
- # ======================================= #
- # cache variables
-
- # local cache for absolute paths - cache_node_abspath[variant][node]
- self.cache_node_abspath = {}
-
- # list of folders that are already scanned
- # so that we do not need to stat them one more time
- self.cache_scanned_folders = {}
-
- # list of targets to uninstall for removing the empty folders after uninstalling
- self.uninstall = []
-
- # ======================================= #
- # tasks and objects
-
- # build dir variants (release, debug, ..)
- for v in 'cache_node_abspath task_sigs node_deps raw_deps node_sigs'.split():
- var = {}
- setattr(self, v, var)
-
- self.cache_dir_contents = {}
-
- self.all_task_gen = []
- self.task_gen_cache_names = {}
- self.cache_sig_vars = {}
- self.log = None
-
- self.root = None
- self.srcnode = None
- self.bldnode = None
-
- # bind the build context to the nodes in use
- # this means better encapsulation and no build context singleton
- class node_class(Node.Node):
- pass
- self.node_class = node_class
- self.node_class.__module__ = "Node"
- self.node_class.__name__ = "Nodu"
- self.node_class.bld = self
-
- self.is_install = None
-
- def __copy__(self):
- "nodes are not supposed to be copied"
- raise Utils.WafError('build contexts are not supposed to be cloned')
-
- def load(self):
- "load the cache from the disk"
- try:
- env = Environment.Environment(os.path.join(self.cachedir, 'build.config.py'))
- except (IOError, OSError):
- pass
- else:
- if env['version'] < HEXVERSION:
- raise Utils.WafError('Version mismatch! reconfigure the project')
- for t in env['tools']:
- self.setup(**t)
-
- try:
- gc.disable()
- f = data = None
-
- Node.Nodu = self.node_class
-
- try:
- f = open(os.path.join(self.bdir, DBFILE), 'rb')
- except (IOError, EOFError):
- # handle missing file/empty file
- pass
-
- try:
- if f: data = cPickle.load(f)
- except AttributeError:
- # handle file of an old Waf version
- # that has an attribute which no longer exist
- # (e.g. AttributeError: 'module' object has no attribute 'BuildDTO')
- if Logs.verbose > 1: raise
-
- if data:
- for x in SAVED_ATTRS: setattr(self, x, data[x])
- else:
- debug('build: Build cache loading failed')
-
- finally:
- if f: f.close()
- gc.enable()
-
- def save(self):
- "store the cache on disk, see self.load"
- gc.disable()
- self.root.__class__.bld = None
-
- # some people are very nervous with ctrl+c so we have to make a temporary file
- Node.Nodu = self.node_class
- db = os.path.join(self.bdir, DBFILE)
- file = open(db + '.tmp', 'wb')
- data = {}
- for x in SAVED_ATTRS: data[x] = getattr(self, x)
- cPickle.dump(data, file, -1)
- file.close()
-
- # do not use shutil.move
- try: os.unlink(db)
- except OSError: pass
- os.rename(db + '.tmp', db)
- self.root.__class__.bld = self
- gc.enable()
-
- # ======================================= #
-
- def clean(self):
- debug('build: clean called')
-
- # does not clean files created during the configuration
- precious = set([])
- for env in self.all_envs.values():
- for x in env[CFG_FILES]:
- node = self.srcnode.find_resource(x)
- if node:
- precious.add(node.id)
-
- def clean_rec(node):
- for x in list(node.childs.keys()):
- nd = node.childs[x]
-
- tp = nd.id & 3
- if tp == Node.DIR:
- clean_rec(nd)
- elif tp == Node.BUILD:
- if nd.id in precious: continue
- for env in self.all_envs.values():
- try: os.remove(nd.abspath(env))
- except OSError: pass
- node.childs.__delitem__(x)
-
- clean_rec(self.srcnode)
-
- for v in 'node_sigs node_deps task_sigs raw_deps cache_node_abspath'.split():
- setattr(self, v, {})
-
- def compile(self):
- """The cache file is not written if nothing was build at all (build is up to date)"""
- debug('build: compile called')
-
- """
- import cProfile, pstats
- cProfile.run("import Build\nBuild.bld.flush()", 'profi.txt')
- p = pstats.Stats('profi.txt')
- p.sort_stats('cumulative').print_stats(80)
- """
- self.flush()
- #"""
-
- self.generator = Runner.Parallel(self, Options.options.jobs)
-
- def dw(on=True):
- if Options.options.progress_bar:
- if on: sys.stderr.write(Logs.colors.cursor_on)
- else: sys.stderr.write(Logs.colors.cursor_off)
-
- debug('build: executor starting')
-
- back = os.getcwd()
- os.chdir(self.bldnode.abspath())
-
- try:
- try:
- dw(on=False)
- self.generator.start()
- except KeyboardInterrupt:
- dw()
- if Runner.TaskConsumer.consumers:
- self.save()
- raise
- except Exception:
- dw()
- # do not store anything, for something bad happened
- raise
- else:
- dw()
- if Runner.TaskConsumer.consumers:
- self.save()
-
- if self.generator.error:
- raise BuildError(self, self.task_manager.tasks_done)
-
- finally:
- os.chdir(back)
-
- def install(self):
- "this function is called for both install and uninstall"
- debug('build: install called')
-
- self.flush()
-
- # remove empty folders after uninstalling
- if self.is_install < 0:
- lst = []
- for x in self.uninstall:
- dir = os.path.dirname(x)
- if not dir in lst: lst.append(dir)
- lst.sort()
- lst.reverse()
-
- nlst = []
- for y in lst:
- x = y
- while len(x) > 4:
- if not x in nlst: nlst.append(x)
- x = os.path.dirname(x)
-
- nlst.sort()
- nlst.reverse()
- for x in nlst:
- try: os.rmdir(x)
- except OSError: pass
-
- def new_task_gen(self, *k, **kw):
- if self.task_gen_cache_names:
- self.task_gen_cache_names = {}
-
- kw['bld'] = self
- if len(k) == 0:
- ret = TaskGen.task_gen(*k, **kw)
- else:
- cls_name = k[0]
-
- try: cls = TaskGen.task_gen.classes[cls_name]
- except KeyError: raise Utils.WscriptError('%s is not a valid task generator -> %s' %
- (cls_name, [x for x in TaskGen.task_gen.classes]))
- ret = cls(*k, **kw)
- return ret
-
- def __call__(self, *k, **kw):
- if self.task_gen_cache_names:
- self.task_gen_cache_names = {}
-
- kw['bld'] = self
- return TaskGen.task_gen(*k, **kw)
-
- def load_envs(self):
- try:
- lst = Utils.listdir(self.cachedir)
- except OSError, e:
- if e.errno == errno.ENOENT:
- raise Utils.WafError('The project was not configured: run "waf configure" first!')
- else:
- raise
-
- if not lst:
- raise Utils.WafError('The cache directory is empty: reconfigure the project')
-
- for file in lst:
- if file.endswith(CACHE_SUFFIX):
- env = Environment.Environment(os.path.join(self.cachedir, file))
- name = file[:-len(CACHE_SUFFIX)]
-
- self.all_envs[name] = env
-
- self.init_variants()
-
- for env in self.all_envs.values():
- for f in env[CFG_FILES]:
- newnode = self.path.find_or_declare(f)
- try:
- hash = Utils.h_file(newnode.abspath(env))
- except (IOError, AttributeError):
- error("cannot find "+f)
- hash = SIG_NIL
- self.node_sigs[env.variant()][newnode.id] = hash
-
- # TODO: hmmm, these nodes are removed from the tree when calling rescan()
- self.bldnode = self.root.find_dir(self.bldnode.abspath())
- self.path = self.srcnode = self.root.find_dir(self.srcnode.abspath())
- self.cwd = self.bldnode.abspath()
-
- def setup(self, tool, tooldir=None, funs=None):
- "setup tools for build process"
- if isinstance(tool, list):
- for i in tool: self.setup(i, tooldir)
- return
-
- if not tooldir: tooldir = Options.tooldir
-
- module = Utils.load_tool(tool, tooldir)
- if hasattr(module, "setup"): module.setup(self)
-
- def init_variants(self):
- debug('build: init variants')
-
- lstvariants = []
- for env in self.all_envs.values():
- if not env.variant() in lstvariants:
- lstvariants.append(env.variant())
- self.lst_variants = lstvariants
-
- debug('build: list of variants is %r', lstvariants)
-
- for name in lstvariants+[0]:
- for v in 'node_sigs cache_node_abspath'.split():
- var = getattr(self, v)
- if not name in var:
- var[name] = {}
-
- # ======================================= #
- # node and folder handling
-
- # this should be the main entry point
- def load_dirs(self, srcdir, blddir, load_cache=1):
- "this functions should be the start of everything"
-
- assert(os.path.isabs(srcdir))
- assert(os.path.isabs(blddir))
-
- self.cachedir = os.path.join(blddir, CACHE_DIR)
-
- if srcdir == blddir:
- raise Utils.WafError("build dir must be different from srcdir: %s <-> %s " % (srcdir, blddir))
-
- self.bdir = blddir
-
- # try to load the cache file, if it does not exist, nothing happens
- self.load()
-
- if not self.root:
- Node.Nodu = self.node_class
- self.root = Node.Nodu('', None, Node.DIR)
-
- if not self.srcnode:
- self.srcnode = self.root.ensure_dir_node_from_path(srcdir)
- debug('build: srcnode is %s and srcdir %s', self.srcnode.name, srcdir)
-
- self.path = self.srcnode
-
- # create this build dir if necessary
- try: os.makedirs(blddir)
- except OSError: pass
-
- if not self.bldnode:
- self.bldnode = self.root.ensure_dir_node_from_path(blddir)
-
- self.init_variants()
-
- def rescan(self, src_dir_node):
- """
- look the contents of a (folder)node and update its list of childs
-
- The intent is to perform the following steps
- * remove the nodes for the files that have disappeared
- * remove the signatures for the build files that have disappeared
- * cache the results of os.listdir
- * create the build folder equivalent (mkdir) for each variant
- src/bar -> build/Release/src/bar, build/Debug/src/bar
-
- when a folder in the source directory is removed, we do not check recursively
- to remove the unused nodes. To do that, call 'waf clean' and build again.
- """
-
- # do not rescan over and over again
- # TODO use a single variable in waf 1.6
- if self.cache_scanned_folders.get(src_dir_node.id, None): return
- self.cache_scanned_folders[src_dir_node.id] = True
-
- # TODO remove in waf 1.6
- if hasattr(self, 'repository'): self.repository(src_dir_node)
-
- if not src_dir_node.name and sys.platform == 'win32':
- # the root has no name, contains drive letters, and cannot be listed
- return
-
-
- # first, take the case of the source directory
- parent_path = src_dir_node.abspath()
- try:
- lst = set(Utils.listdir(parent_path))
- except OSError:
- lst = set([])
-
- # TODO move this at the bottom
- self.cache_dir_contents[src_dir_node.id] = lst
-
- # hash the existing source files, remove the others
- cache = self.node_sigs[0]
- for x in src_dir_node.childs.values():
- if x.id & 3 != Node.FILE: continue
- if x.name in lst:
- try:
- cache[x.id] = Utils.h_file(x.abspath())
- except IOError:
- raise Utils.WafError('The file %s is not readable or has become a dir' % x.abspath())
- else:
- try: del cache[x.id]
- except KeyError: pass
-
- del src_dir_node.childs[x.name]
-
-
- # first obtain the differences between srcnode and src_dir_node
- h1 = self.srcnode.height()
- h2 = src_dir_node.height()
-
- lst = []
- child = src_dir_node
- while h2 > h1:
- lst.append(child.name)
- child = child.parent
- h2 -= 1
- lst.reverse()
-
- # list the files in the build dirs
- try:
- for variant in self.lst_variants:
- sub_path = os.path.join(self.bldnode.abspath(), variant , *lst)
- self.listdir_bld(src_dir_node, sub_path, variant)
- except OSError:
-
- # listdir failed, remove the build node signatures for all variants
- for node in src_dir_node.childs.values():
- if node.id & 3 != Node.BUILD:
- continue
-
- for dct in self.node_sigs.values():
- if node.id in dct:
- dct.__delitem__(node.id)
-
- # the policy is to avoid removing nodes representing directories
- src_dir_node.childs.__delitem__(node.name)
-
- for variant in self.lst_variants:
- sub_path = os.path.join(self.bldnode.abspath(), variant , *lst)
- try:
- os.makedirs(sub_path)
- except OSError:
- pass
-
- # ======================================= #
- def listdir_src(self, parent_node):
- """do not use, kept for compatibility"""
- pass
-
- def remove_node(self, node):
- """do not use, kept for compatibility"""
- pass
-
- def listdir_bld(self, parent_node, path, variant):
- """in this method we do not add timestamps but we remove them
- when the files no longer exist (file removed in the build dir)"""
-
- i_existing_nodes = [x for x in parent_node.childs.values() if x.id & 3 == Node.BUILD]
-
- lst = set(Utils.listdir(path))
- node_names = set([x.name for x in i_existing_nodes])
- remove_names = node_names - lst
-
- # remove the stamps of the build nodes that no longer exist on the filesystem
- ids_to_remove = [x.id for x in i_existing_nodes if x.name in remove_names]
- cache = self.node_sigs[variant]
- for nid in ids_to_remove:
- if nid in cache:
- cache.__delitem__(nid)
-
- def get_env(self):
- return self.env_of_name('Release')
- def set_env(self, name, val):
- self.all_envs[name] = val
-
- env = property(get_env, set_env)
-
- def add_manual_dependency(self, path, value):
- if isinstance(path, Node.Node):
- node = path
- elif os.path.isabs(path):
- node = self.root.find_resource(path)
- else:
- node = self.path.find_resource(path)
- self.deps_man[node.id].append(value)
-
- def launch_node(self):
- """return the launch directory as a node"""
- # p_ln is kind of private, but public in case if
- try:
- return self.p_ln
- except AttributeError:
- self.p_ln = self.root.find_dir(Options.launch_dir)
- return self.p_ln
-
- def glob(self, pattern, relative=True):
- "files matching the pattern, seen from the current folder"
- path = self.path.abspath()
- files = [self.root.find_resource(x) for x in glob.glob(path+os.sep+pattern)]
- if relative:
- files = [x.path_to_parent(self.path) for x in files if x]
- else:
- files = [x.abspath() for x in files if x]
- return files
-
- ## the following methods are candidates for the stable apis ##
-
- def add_group(self, *k):
- self.task_manager.add_group(*k)
-
- def set_group(self, *k, **kw):
- self.task_manager.set_group(*k, **kw)
-
- def hash_env_vars(self, env, vars_lst):
- """hash environment variables
- ['CXX', ..] -> [env['CXX'], ..] -> md5()"""
-
- # ccroot objects use the same environment for building the .o at once
- # the same environment and the same variables are used
-
- idx = str(id(env)) + str(vars_lst)
- try: return self.cache_sig_vars[idx]
- except KeyError: pass
-
- lst = [str(env[a]) for a in vars_lst]
- ret = Utils.h_list(lst)
- debug('envhash: %r %r', ret, lst)
-
- # next time
- self.cache_sig_vars[idx] = ret
- return ret
-
- def name_to_obj(self, name, env):
- """retrieve a task generator from its name or its target name
- remember that names must be unique"""
- cache = self.task_gen_cache_names
- if not cache:
- # create the index lazily
- for x in self.all_task_gen:
- vt = x.env.variant() + '_'
- if x.name:
- cache[vt + x.name] = x
- else:
- if isinstance(x.target, str):
- target = x.target
- else:
- target = ' '.join(x.target)
- v = vt + target
- if not cache.get(v, None):
- cache[v] = x
- return cache.get(env.variant() + '_' + name, None)
-
- def flush(self, all=1):
- """tell the task generators to create the tasks"""
-
- self.ini = datetime.datetime.now()
- # force the initialization of the mapping name->object in flush
- # name_to_obj can be used in userland scripts, in that case beware of incomplete mapping
- self.task_gen_cache_names = {}
- self.name_to_obj('', self.env)
-
- debug('build: delayed operation TaskGen.flush() called')
-
- if Options.options.compile_targets:
- debug('task_gen: posting objects listed in compile_targets')
-
- # ensure the target names exist, fail before any post()
- target_objects = Utils.DefaultDict(list)
- for target_name in Options.options.compile_targets.split(','):
- # trim target_name (handle cases when the user added spaces to targets)
- target_name = target_name.strip()
- for env in self.all_envs.values():
- obj = self.name_to_obj(target_name, env)
- if obj:
- target_objects[target_name].append(obj)
- if not target_name in target_objects and all:
- raise Utils.WafError("target '%s' does not exist" % target_name)
-
- to_compile = []
- for x in target_objects.values():
- for y in x:
- to_compile.append(id(y))
-
- # tasks must be posted in order of declaration
- # we merely apply a filter to discard the ones we are not interested in
- for i in xrange(len(self.task_manager.groups)):
- g = self.task_manager.groups[i]
- self.task_manager.current_group = i
- if Logs.verbose:
- Logs.debug('group: group %s' % ([x for x in self.task_manager.groups_names if id(self.task_manager.groups_names[x]) == id(g)][0]))
-
- for tg in g.tasks_gen:
- if id(tg) in to_compile:
- if Logs.verbose:
- Logs.debug('group: %s' % tg)
- tg.post()
-
- else:
- debug('task_gen: posting objects (normal)')
- ln = self.launch_node()
- # if the build is started from the build directory, do as if it was started from the top-level
- # for the pretty-printing (Node.py), the two lines below cannot be moved to Build::launch_node
- if ln.is_child_of(self.bldnode) or not ln.is_child_of(self.srcnode):
- ln = self.srcnode
-
- # if the project file is located under the source directory, build all targets by default
- # else 'waf configure build' does nothing
- proj_node = self.root.find_dir(os.path.split(Utils.g_module.root_path)[0])
- if proj_node.id != self.srcnode.id:
- ln = self.srcnode
-
- for i in xrange(len(self.task_manager.groups)):
- g = self.task_manager.groups[i]
- self.task_manager.current_group = i
- if Logs.verbose:
- Logs.debug('group: group %s' % ([x for x in self.task_manager.groups_names if id(self.task_manager.groups_names[x]) == id(g)][0]))
- for tg in g.tasks_gen:
- if not tg.path.is_child_of(ln):
- continue
- if Logs.verbose:
- Logs.debug('group: %s' % tg)
- tg.post()
-
- def env_of_name(self, name):
- try:
- return self.all_envs[name]
- except KeyError:
- error('no such environment: '+name)
- return None
-
- def progress_line(self, state, total, col1, col2):
- n = len(str(total))
-
- Utils.rot_idx += 1
- ind = Utils.rot_chr[Utils.rot_idx % 4]
-
- ini = self.ini
-
- pc = (100.*state)/total
- eta = Utils.get_elapsed_time(ini)
- fs = "[%%%dd/%%%dd][%%s%%2d%%%%%%s][%s][" % (n, n, ind)
- left = fs % (state, total, col1, pc, col2)
- right = '][%s%s%s]' % (col1, eta, col2)
-
- cols = Utils.get_term_cols() - len(left) - len(right) + 2*len(col1) + 2*len(col2)
- if cols < 7: cols = 7
-
- ratio = int((cols*state)/total) - 1
-
- bar = ('='*ratio+'>').ljust(cols)
- msg = Utils.indicator % (left, bar, right)
-
- return msg
-
-
- # do_install is not used anywhere
- def do_install(self, src, tgt, chmod=O644):
- """returns true if the file was effectively installed or uninstalled, false otherwise"""
- if self.is_install > 0:
- if not Options.options.force:
- # check if the file is already there to avoid a copy
- try:
- st1 = os.stat(tgt)
- st2 = os.stat(src)
- except OSError:
- pass
- else:
- # same size and identical timestamps -> make no copy
- if st1.st_mtime >= st2.st_mtime and st1.st_size == st2.st_size:
- return False
-
- srclbl = src.replace(self.srcnode.abspath(None)+os.sep, '')
- info("* installing %s as %s" % (srclbl, tgt))
-
- # following is for shared libs and stale inodes (-_-)
- try: os.remove(tgt)
- except OSError: pass
-
- try:
- shutil.copy2(src, tgt)
- if chmod >= 0: os.chmod(tgt, chmod)
- except IOError:
- try:
- os.stat(src)
- except (OSError, IOError):
- error('File %r does not exist' % src)
- raise Utils.WafError('Could not install the file %r' % tgt)
- return True
-
- elif self.is_install < 0:
- info("* uninstalling %s" % tgt)
-
- self.uninstall.append(tgt)
-
- try:
- os.remove(tgt)
- except OSError, e:
- if e.errno != errno.ENOENT:
- if not getattr(self, 'uninstall_error', None):
- self.uninstall_error = True
- Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)')
- if Logs.verbose > 1:
- Logs.warn('could not remove %s (error code %r)' % (e.filename, e.errno))
- return True
-
- red = re.compile(r"^([A-Za-z]:)?[/\\\\]*")
- def get_install_path(self, path, env=None):
- "installation path prefixed by the destdir, the variables like in '${PREFIX}/bin' are substituted"
- if not env: env = self.env
- destdir = env.get_destdir()
- path = path.replace('/', os.sep)
- destpath = Utils.subst_vars(path, env)
- if destdir:
- destpath = os.path.join(destdir, self.red.sub('', destpath))
- return destpath
-
- def install_dir(self, path, env=None):
- """
- create empty folders for the installation (very rarely used)
- """
- if env:
- assert isinstance(env, Environment.Environment), "invalid parameter"
- else:
- env = self.env
-
- if not path:
- return []
-
- destpath = self.get_install_path(path, env)
-
- if self.is_install > 0:
- info('* creating %s' % destpath)
- Utils.check_dir(destpath)
- elif self.is_install < 0:
- info('* removing %s' % destpath)
- self.uninstall.append(destpath + '/xxx') # yes, ugly
-
- def install_files(self, path, files, env=None, chmod=O644, relative_trick=False, cwd=None):
- """To install files only after they have been built, put the calls in a method named
- post_build on the top-level wscript
-
- The files must be a list and contain paths as strings or as Nodes
-
- The relative_trick flag can be set to install folders, use bld.path.ant_glob() with it
- """
- if env:
- assert isinstance(env, Environment.Environment), "invalid parameter"
- else:
- env = self.env
-
- if not path: return []
-
- if not cwd:
- cwd = self.path
-
- if isinstance(files, str) and '*' in files:
- gl = cwd.abspath() + os.sep + files
- lst = glob.glob(gl)
- else:
- lst = Utils.to_list(files)
-
- if not getattr(lst, '__iter__', False):
- lst = [lst]
-
- destpath = self.get_install_path(path, env)
-
- Utils.check_dir(destpath)
-
- installed_files = []
- for filename in lst:
- if isinstance(filename, str) and os.path.isabs(filename):
- alst = Utils.split_path(filename)
- destfile = os.path.join(destpath, alst[-1])
- else:
- if isinstance(filename, Node.Node):
- nd = filename
- else:
- nd = cwd.find_resource(filename)
- if not nd:
- raise Utils.WafError("Unable to install the file %r (not found in %s)" % (filename, cwd))
-
- if relative_trick:
- destfile = os.path.join(destpath, filename)
- Utils.check_dir(os.path.dirname(destfile))
- else:
- destfile = os.path.join(destpath, nd.name)
-
- filename = nd.abspath(env)
-
- if self.do_install(filename, destfile, chmod):
- installed_files.append(destfile)
- return installed_files
-
- def install_as(self, path, srcfile, env=None, chmod=O644, cwd=None):
- """
- srcfile may be a string or a Node representing the file to install
-
- returns True if the file was effectively installed, False otherwise
- """
- if env:
- assert isinstance(env, Environment.Environment), "invalid parameter"
- else:
- env = self.env
-
- if not path:
- raise Utils.WafError("where do you want to install %r? (%r?)" % (srcfile, path))
-
- if not cwd:
- cwd = self.path
-
- destpath = self.get_install_path(path, env)
-
- dir, name = os.path.split(destpath)
- Utils.check_dir(dir)
-
- # the source path
- if isinstance(srcfile, Node.Node):
- src = srcfile.abspath(env)
- else:
- src = srcfile
- if not os.path.isabs(srcfile):
- node = cwd.find_resource(srcfile)
- if not node:
- raise Utils.WafError("Unable to install the file %r (not found in %s)" % (srcfile, cwd))
- src = node.abspath(env)
-
- return self.do_install(src, destpath, chmod)
-
- def symlink_as(self, path, src, env=None, cwd=None):
- """example: bld.symlink_as('${PREFIX}/lib/libfoo.so', 'libfoo.so.1.2.3') """
-
- if sys.platform == 'win32':
- # well, this *cannot* work
- return
-
- if not path:
- raise Utils.WafError("where do you want to install %r? (%r?)" % (src, path))
-
- tgt = self.get_install_path(path, env)
-
- dir, name = os.path.split(tgt)
- Utils.check_dir(dir)
-
- if self.is_install > 0:
- link = False
- if not os.path.islink(tgt):
- link = True
- elif os.readlink(tgt) != src:
- link = True
-
- if link:
- try: os.remove(tgt)
- except OSError: pass
-
- info('* symlink %s (-> %s)' % (tgt, src))
- os.symlink(src, tgt)
- return 0
-
- else: # UNINSTALL
- try:
- info('* removing %s' % (tgt))
- os.remove(tgt)
- return 0
- except OSError:
- return 1
-
- def exec_command(self, cmd, **kw):
- # 'runner' zone is printed out for waf -v, see wafadmin/Options.py
- debug('runner: system command -> %s', cmd)
- if self.log:
- self.log.write('%s\n' % cmd)
- kw['log'] = self.log
- try:
- if not kw.get('cwd', None):
- kw['cwd'] = self.cwd
- except AttributeError:
- self.cwd = kw['cwd'] = self.bldnode.abspath()
- return Utils.exec_command(cmd, **kw)
-
- def printout(self, s):
- f = self.log or sys.stderr
- f.write(s)
- f.flush()
-
- def add_subdirs(self, dirs):
- self.recurse(dirs, 'build')
-
- def pre_recurse(self, name_or_mod, path, nexdir):
- if not hasattr(self, 'oldpath'):
- self.oldpath = []
- self.oldpath.append(self.path)
- self.path = self.root.find_dir(nexdir)
- return {'bld': self, 'ctx': self}
-
- def post_recurse(self, name_or_mod, path, nexdir):
- self.path = self.oldpath.pop()
-
- ###### user-defined behaviour
-
- def pre_build(self):
- if hasattr(self, 'pre_funs'):
- for m in self.pre_funs:
- m(self)
-
- def post_build(self):
- if hasattr(self, 'post_funs'):
- for m in self.post_funs:
- m(self)
-
- def add_pre_fun(self, meth):
- try: self.pre_funs.append(meth)
- except AttributeError: self.pre_funs = [meth]
-
- def add_post_fun(self, meth):
- try: self.post_funs.append(meth)
- except AttributeError: self.post_funs = [meth]
-
- def use_the_magic(self):
- Task.algotype = Task.MAXPARALLEL
- Task.file_deps = Task.extract_deps
- self.magic = True
-
- install_as = group_method(install_as)
- install_files = group_method(install_files)
- symlink_as = group_method(symlink_as)
-
diff --git a/tools/wafadmin/Configure.py b/tools/wafadmin/Configure.py
deleted file mode 100644
index 846e18521..000000000
--- a/tools/wafadmin/Configure.py
+++ /dev/null
@@ -1,387 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005-2008 (ita)
-
-"""
-Configuration system
-
-A configuration instance is created when "waf configure" is called, it is used to:
-* create data dictionaries (Environment instances)
-* store the list of modules to import
-
-The old model (copied from Scons) was to store logic (mapping file extensions to functions)
-along with the data. In Waf a way was found to separate that logic by adding an indirection
-layer (storing the names in the Environment instances)
-
-In the new model, the logic is more object-oriented, and the user scripts provide the
-logic. The data files (Environments) must contain configuration data only (flags, ..).
-
-Note: the c/c++ related code is in the module config_c
-"""
-
-import os, shlex, sys, time
-try: import cPickle
-except ImportError: import pickle as cPickle
-import Environment, Utils, Options, Logs
-from Logs import warn
-from Constants import *
-
-try:
- from urllib import request
-except:
- from urllib import urlopen
-else:
- urlopen = request.urlopen
-
-conf_template = '''# project %(app)s configured on %(now)s by
-# waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s)
-# using %(args)s
-#
-'''
-
-class ConfigurationError(Utils.WscriptError):
- pass
-
-autoconfig = False
-"reconfigure the project automatically"
-
-def find_file(filename, path_list):
- """find a file in a list of paths
- @param filename: name of the file to search for
- @param path_list: list of directories to search
- @return: the first occurrence filename or '' if filename could not be found
-"""
- for directory in Utils.to_list(path_list):
- if os.path.exists(os.path.join(directory, filename)):
- return directory
- return ''
-
-def find_program_impl(env, filename, path_list=[], var=None, environ=None):
- """find a program in folders path_lst, and sets env[var]
- @param env: environment
- @param filename: name of the program to search for
- @param path_list: list of directories to search for filename
- @param var: environment value to be checked for in env or os.environ
- @return: either the value that is referenced with [var] in env or os.environ
- or the first occurrence filename or '' if filename could not be found
-"""
-
- if not environ:
- environ = os.environ
-
- try: path_list = path_list.split()
- except AttributeError: pass
-
- if var:
- if env[var]: return env[var]
- if var in environ: env[var] = environ[var]
-
- if not path_list: path_list = environ.get('PATH', '').split(os.pathsep)
-
- ext = (Options.platform == 'win32') and '.exe,.com,.bat,.cmd' or ''
- for y in [filename+x for x in ext.split(',')]:
- for directory in path_list:
- x = os.path.join(directory, y)
- if os.path.isfile(x):
- if var: env[var] = x
- return x
- return ''
-
-class ConfigurationContext(Utils.Context):
- tests = {}
- error_handlers = []
- def __init__(self, env=None, blddir='', srcdir=''):
- self.env = None
- self.envname = ''
-
- self.environ = dict(os.environ)
-
- self.line_just = 40
-
- self.blddir = blddir
- self.srcdir = srcdir
- self.all_envs = {}
-
- # curdir: necessary for recursion
- self.cwd = self.curdir = os.getcwd()
-
- self.tools = [] # tools loaded in the configuration, and that will be loaded when building
-
- self.setenv(DEFAULT)
-
- self.lastprog = ''
-
- self.hash = 0
- self.files = []
-
- self.tool_cache = []
-
- if self.blddir:
- self.post_init()
-
- def post_init(self):
-
- self.cachedir = os.path.join(self.blddir, CACHE_DIR)
-
- path = os.path.join(self.blddir, WAF_CONFIG_LOG)
- try: os.unlink(path)
- except (OSError, IOError): pass
-
- try:
- self.log = open(path, 'w')
- except (OSError, IOError):
- self.fatal('could not open %r for writing' % path)
-
- app = Utils.g_module.APPNAME
- if app:
- ver = getattr(Utils.g_module, 'VERSION', '')
- if ver:
- app = "%s (%s)" % (app, ver)
-
- now = time.ctime()
- pyver = sys.hexversion
- systype = sys.platform
- args = " ".join(sys.argv)
- wafver = WAFVERSION
- abi = ABI
- self.log.write(conf_template % vars())
-
- def __del__(self):
- """cleanup function: close config.log"""
-
- # may be ran by the gc, not always after initialization
- if hasattr(self, 'log') and self.log:
- self.log.close()
-
- def fatal(self, msg):
- raise ConfigurationError(msg)
-
- def check_tool(self, input, tooldir=None, funs=None):
- "load a waf tool"
-
- tools = Utils.to_list(input)
- if tooldir: tooldir = Utils.to_list(tooldir)
- for tool in tools:
- tool = tool.replace('++', 'xx')
- if tool == 'java': tool = 'javaw'
- if tool.lower() == 'unittest': tool = 'unittestw'
- # avoid loading the same tool more than once with the same functions
- # used by composite projects
-
- mag = (tool, id(self.env), funs)
- if mag in self.tool_cache:
- continue
- self.tool_cache.append(mag)
-
- if not tooldir:
- # check if the tool exists in the Tools or 3rdparty folders
- _Tools = Options.tooldir[0]
- _3rdparty = os.sep.join((_Tools, '..', '3rdparty'))
- for d in (_Tools, _3rdparty):
- lst = os.listdir(d)
- if tool + '.py' in lst:
- break
- else:
- # try to download the tool from the repository then
- for x in Utils.to_list(Options.remote_repo):
- for sub in ['branches/waf-%s/wafadmin/3rdparty' % WAFVERSION, 'trunk/wafadmin/3rdparty']:
- url = '/'.join((x, sub, tool + '.py'))
- try:
- web = urlopen(url)
- if web.getcode() != 200:
- continue
- except Exception, e:
- # on python3 urlopen throws an exception
- continue
- else:
- try:
- loc = open(_3rdparty + os.sep + tool + '.py', 'wb')
- loc.write(web.read())
- web.close()
- finally:
- loc.close()
- Logs.warn('downloaded %s from %s' % (tool, url))
- else:
- break
-
- module = Utils.load_tool(tool, tooldir)
-
- if funs is not None:
- self.eval_rules(funs)
- else:
- func = getattr(module, 'detect', None)
- if func:
- if type(func) is type(find_file): func(self)
- else: self.eval_rules(func)
-
- self.tools.append({'tool':tool, 'tooldir':tooldir, 'funs':funs})
-
- def sub_config(self, k):
- "executes the configure function of a wscript module"
- self.recurse(k, name='configure')
-
- def pre_recurse(self, name_or_mod, path, nexdir):
- return {'conf': self, 'ctx': self}
-
- def post_recurse(self, name_or_mod, path, nexdir):
- if not autoconfig:
- return
- self.hash = hash((self.hash, getattr(name_or_mod, 'waf_hash_val', name_or_mod)))
- self.files.append(path)
-
- def store(self, file=''):
- "save the config results into the cache file"
- if not os.path.isdir(self.cachedir):
- os.makedirs(self.cachedir)
-
- if not file:
- file = open(os.path.join(self.cachedir, 'build.config.py'), 'w')
- file.write('version = 0x%x\n' % HEXVERSION)
- file.write('tools = %r\n' % self.tools)
- file.close()
-
- if not self.all_envs:
- self.fatal('nothing to store in the configuration context!')
- for key in self.all_envs:
- tmpenv = self.all_envs[key]
- tmpenv.store(os.path.join(self.cachedir, key + CACHE_SUFFIX))
-
- def set_env_name(self, name, env):
- "add a new environment called name"
- self.all_envs[name] = env
- return env
-
- def retrieve(self, name, fromenv=None):
- "retrieve an environment called name"
- try:
- env = self.all_envs[name]
- except KeyError:
- env = Environment.Environment()
- env['PREFIX'] = os.path.abspath(os.path.expanduser(Options.options.prefix))
- self.all_envs[name] = env
- else:
- if fromenv: warn("The environment %s may have been configured already" % name)
- return env
-
- def setenv(self, name):
- "enable the environment called name"
- self.env = self.retrieve(name)
- self.envname = name
-
- def add_os_flags(self, var, dest=None):
- # do not use 'get' to make certain the variable is not defined
- try: self.env.append_value(dest or var, Utils.to_list(self.environ[var]))
- except KeyError: pass
-
- def check_message_1(self, sr):
- self.line_just = max(self.line_just, len(sr))
- for x in ('\n', self.line_just * '-', '\n', sr, '\n'):
- self.log.write(x)
- Utils.pprint('NORMAL', "%s :" % sr.ljust(self.line_just), sep='')
-
- def check_message_2(self, sr, color='GREEN'):
- self.log.write(sr)
- self.log.write('\n')
- Utils.pprint(color, sr)
-
- def check_message(self, th, msg, state, option=''):
- sr = 'Checking for %s %s' % (th, msg)
- self.check_message_1(sr)
- p = self.check_message_2
- if state: p('ok ' + str(option))
- else: p('not found', 'YELLOW')
-
- # FIXME remove in waf 1.6
- # the parameter 'option' is not used (kept for compatibility)
- def check_message_custom(self, th, msg, custom, option='', color='PINK'):
- sr = 'Checking for %s %s' % (th, msg)
- self.check_message_1(sr)
- self.check_message_2(custom, color)
-
- def find_program(self, filename, path_list=[], var=None, mandatory=False):
- "wrapper that adds a configuration message"
-
- ret = None
- if var:
- if self.env[var]:
- ret = self.env[var]
- elif var in os.environ:
- ret = os.environ[var]
-
- if not isinstance(filename, list): filename = [filename]
- if not ret:
- for x in filename:
- ret = find_program_impl(self.env, x, path_list, var, environ=self.environ)
- if ret: break
-
- self.check_message_1('Checking for program %s' % ' or '.join(filename))
- self.log.write(' find program=%r paths=%r var=%r\n -> %r\n' % (filename, path_list, var, ret))
- if ret:
- Utils.pprint('GREEN', str(ret))
- else:
- Utils.pprint('YELLOW', 'not found')
- if mandatory:
- self.fatal('The program %r is required' % filename)
-
- if var:
- self.env[var] = ret
- return ret
-
- def cmd_to_list(self, cmd):
- "commands may be written in pseudo shell like 'ccache g++'"
- if isinstance(cmd, str) and cmd.find(' '):
- try:
- os.stat(cmd)
- except OSError:
- return shlex.split(cmd)
- else:
- return [cmd]
- return cmd
-
- def __getattr__(self, name):
- r = self.__class__.__dict__.get(name, None)
- if r: return r
- if name and name.startswith('require_'):
-
- for k in ['check_', 'find_']:
- n = name.replace('require_', k)
- ret = self.__class__.__dict__.get(n, None)
- if ret:
- def run(*k, **kw):
- r = ret(self, *k, **kw)
- if not r:
- self.fatal('requirement failure')
- return r
- return run
- self.fatal('No such method %r' % name)
-
- def eval_rules(self, rules):
- self.rules = Utils.to_list(rules)
- for x in self.rules:
- f = getattr(self, x)
- if not f: self.fatal("No such method '%s'." % x)
- try:
- f()
- except Exception, e:
- ret = self.err_handler(x, e)
- if ret == BREAK:
- break
- elif ret == CONTINUE:
- continue
- else:
- self.fatal(e)
-
- def err_handler(self, fun, error):
- pass
-
-def conf(f):
- "decorator: attach new configuration functions"
- setattr(ConfigurationContext, f.__name__, f)
- return f
-
-def conftest(f):
- "decorator: attach new configuration tests (registered as strings)"
- ConfigurationContext.tests[f.__name__] = f
- return conf(f)
-
-
diff --git a/tools/wafadmin/Constants.py b/tools/wafadmin/Constants.py
deleted file mode 100644
index 2b531c2ed..000000000
--- a/tools/wafadmin/Constants.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Yinon dot me gmail 2008
-
-"""
-these constants are somewhat public, try not to mess them
-
-maintainer: the version number is updated from the top-level wscript file
-"""
-
-# do not touch these three lines, they are updated automatically
-HEXVERSION=0x105016
-WAFVERSION="1.5.16"
-WAFREVISION = "7610:7647M"
-ABI = 7
-
-# permissions
-O644 = 420
-O755 = 493
-
-MAXJOBS = 99999999
-
-CACHE_DIR = 'c4che'
-CACHE_SUFFIX = '.cache.py'
-DBFILE = '.wafpickle-%d' % ABI
-WSCRIPT_FILE = 'wscript'
-WSCRIPT_BUILD_FILE = 'wscript_build'
-WAF_CONFIG_LOG = 'config.log'
-WAF_CONFIG_H = 'config.h'
-
-SIG_NIL = 'iluvcuteoverload'
-
-VARIANT = '_VARIANT_'
-DEFAULT = 'Release'
-
-SRCDIR = 'srcdir'
-BLDDIR = 'blddir'
-APPNAME = 'APPNAME'
-VERSION = 'VERSION'
-
-DEFINES = 'defines'
-UNDEFINED = ()
-
-BREAK = "break"
-CONTINUE = "continue"
-
-# task scheduler options
-JOBCONTROL = "JOBCONTROL"
-MAXPARALLEL = "MAXPARALLEL"
-NORMAL = "NORMAL"
-
-# task state
-NOT_RUN = 0
-MISSING = 1
-CRASHED = 2
-EXCEPTION = 3
-SKIPPED = 8
-SUCCESS = 9
-
-ASK_LATER = -1
-SKIP_ME = -2
-RUN_ME = -3
-
-
-LOG_FORMAT = "%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s"
-HOUR_FORMAT = "%H:%M:%S"
-
-TEST_OK = True
-
-CFG_FILES = 'cfg_files'
-
-# positive '->' install
-# negative '<-' uninstall
-INSTALL = 1337
-UNINSTALL = -1337
-
diff --git a/tools/wafadmin/Environment.py b/tools/wafadmin/Environment.py
deleted file mode 100644
index 0b6e72ceb..000000000
--- a/tools/wafadmin/Environment.py
+++ /dev/null
@@ -1,210 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005 (ita)
-
-"""Environment representation
-
-There is one gotcha: getitem returns [] if the contents evals to False
-This means env['foo'] = {}; print env['foo'] will print [] not {}
-"""
-
-import os, copy, re
-import Logs, Options, Utils
-from Constants import *
-re_imp = re.compile('^(#)*?([^#=]*?)\ =\ (.*?)$', re.M)
-
-class Environment(object):
- """A safe-to-use dictionary, but do not attach functions to it please (break cPickle)
- An environment instance can be stored into a file and loaded easily
- """
- __slots__ = ("table", "parent")
- def __init__(self, filename=None):
- self.table = {}
- #self.parent = None
-
- if filename:
- self.load(filename)
-
- def __contains__(self, key):
- if key in self.table: return True
- try: return self.parent.__contains__(key)
- except AttributeError: return False # parent may not exist
-
- def __str__(self):
- keys = set()
- cur = self
- while cur:
- keys.update(cur.table.keys())
- cur = getattr(cur, 'parent', None)
- keys = list(keys)
- keys.sort()
- return "\n".join(["%r %r" % (x, self.__getitem__(x)) for x in keys])
-
- def __getitem__(self, key):
- try:
- while 1:
- x = self.table.get(key, None)
- if not x is None:
- return x
- self = self.parent
- except AttributeError:
- return []
-
- def __setitem__(self, key, value):
- self.table[key] = value
-
- def __delitem__(self, key):
- del self.table[key]
-
- def pop(self, key, *args):
- if len(args):
- return self.table.pop(key, *args)
- return self.table.pop(key)
-
- def set_variant(self, name):
- self.table[VARIANT] = name
-
- def variant(self):
- try:
- while 1:
- x = self.table.get(VARIANT, None)
- if not x is None:
- return x
- self = self.parent
- except AttributeError:
- return DEFAULT
-
- def copy(self):
- # TODO waf 1.6 rename this method derive, #368
- newenv = Environment()
- newenv.parent = self
- return newenv
-
- def detach(self):
- """TODO try it
- modifying the original env will not change the copy"""
- tbl = self.get_merged_dict()
- try:
- delattr(self, 'parent')
- except AttributeError:
- pass
- else:
- keys = tbl.keys()
- for x in keys:
- tbl[x] = copy.deepcopy(tbl[x])
- self.table = tbl
-
- def get_flat(self, key):
- s = self[key]
- if isinstance(s, str): return s
- return ' '.join(s)
-
- def _get_list_value_for_modification(self, key):
- """Gets a value that must be a list for further modification. The
- list may be modified inplace and there is no need to
- "self.table[var] = value" afterwards.
- """
- try:
- value = self.table[key]
- except KeyError:
- try: value = self.parent[key]
- except AttributeError: value = []
- if isinstance(value, list):
- value = value[:]
- else:
- value = [value]
- else:
- if not isinstance(value, list):
- value = [value]
- self.table[key] = value
- return value
-
- def append_value(self, var, value):
- current_value = self._get_list_value_for_modification(var)
-
- if isinstance(value, list):
- current_value.extend(value)
- else:
- current_value.append(value)
-
- def prepend_value(self, var, value):
- current_value = self._get_list_value_for_modification(var)
-
- if isinstance(value, list):
- current_value = value + current_value
- # a new list: update the dictionary entry
- self.table[var] = current_value
- else:
- current_value.insert(0, value)
-
- # prepend unique would be ambiguous
- def append_unique(self, var, value):
- current_value = self._get_list_value_for_modification(var)
-
- if isinstance(value, list):
- for value_item in value:
- if value_item not in current_value:
- current_value.append(value_item)
- else:
- if value not in current_value:
- current_value.append(value)
-
- def get_merged_dict(self):
- """compute a merged table"""
- table_list = []
- env = self
- while 1:
- table_list.insert(0, env.table)
- try: env = env.parent
- except AttributeError: break
- merged_table = {}
- for table in table_list:
- merged_table.update(table)
- return merged_table
-
- def store(self, filename):
- "Write the variables into a file"
- file = open(filename, 'w')
- merged_table = self.get_merged_dict()
- keys = list(merged_table.keys())
- keys.sort()
- for k in keys: file.write('%s = %r\n' % (k, merged_table[k]))
- file.close()
-
- def load(self, filename):
- "Retrieve the variables from a file"
- tbl = self.table
- code = Utils.readf(filename)
- for m in re_imp.finditer(code):
- g = m.group
- tbl[g(2)] = eval(g(3))
- Logs.debug('env: %s', self.table)
-
- def get_destdir(self):
- "return the destdir, useful for installing"
- if self.__getitem__('NOINSTALL'): return ''
- return Options.options.destdir
-
- def update(self, d):
- for k, v in d.iteritems():
- self[k] = v
-
-
- def __getattr__(self, name):
- if name in self.__slots__:
- return object.__getattr__(self, name)
- else:
- return self[name]
-
- def __setattr__(self, name, value):
- if name in self.__slots__:
- object.__setattr__(self, name, value)
- else:
- self[name] = value
-
- def __delattr__(self, name):
- if name in self.__slots__:
- object.__delattr__(self, name)
- else:
- del self[name]
-
diff --git a/tools/wafadmin/Logs.py b/tools/wafadmin/Logs.py
deleted file mode 100644
index c160b3773..000000000
--- a/tools/wafadmin/Logs.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005 (ita)
-
-import ansiterm
-import os, re, logging, traceback, sys
-from Constants import *
-
-zones = ''
-verbose = 0
-
-colors_lst = {
-'USE' : True,
-'BOLD' :'\x1b[01;1m',
-'RED' :'\x1b[01;31m',
-'GREEN' :'\x1b[32m',
-'YELLOW':'\x1b[33m',
-'PINK' :'\x1b[35m',
-'BLUE' :'\x1b[01;34m',
-'CYAN' :'\x1b[36m',
-'NORMAL':'\x1b[0m',
-'cursor_on' :'\x1b[?25h',
-'cursor_off' :'\x1b[?25l',
-}
-
-got_tty = False
-term = os.environ.get('TERM', 'dumb')
-if not term in ['dumb', 'emacs']:
- try:
- got_tty = sys.stderr.isatty() or (sys.platform == 'win32' and term in ['xterm', 'msys'])
- except AttributeError:
- pass
-
-import Utils
-
-if not got_tty or 'NOCOLOR' in os.environ:
- colors_lst['USE'] = False
-
-# test
-#if sys.platform == 'win32':
-# colors_lst['USE'] = True
-
-def get_color(cl):
- if not colors_lst['USE']: return ''
- return colors_lst.get(cl, '')
-
-class foo(object):
- def __getattr__(self, a):
- return get_color(a)
- def __call__(self, a):
- return get_color(a)
-
-colors = foo()
-
-re_log = re.compile(r'(\w+): (.*)', re.M)
-class log_filter(logging.Filter):
- def __init__(self, name=None):
- pass
-
- def filter(self, rec):
- rec.c1 = colors.PINK
- rec.c2 = colors.NORMAL
- rec.zone = rec.module
- if rec.levelno >= logging.INFO:
- if rec.levelno >= logging.ERROR:
- rec.c1 = colors.RED
- elif rec.levelno >= logging.WARNING:
- rec.c1 = colors.YELLOW
- else:
- rec.c1 = colors.GREEN
- return True
-
- zone = ''
- m = re_log.match(rec.msg)
- if m:
- zone = rec.zone = m.group(1)
- rec.msg = m.group(2)
-
- if zones:
- return getattr(rec, 'zone', '') in zones or '*' in zones
- elif not verbose > 2:
- return False
- return True
-
-class formatter(logging.Formatter):
- def __init__(self):
- logging.Formatter.__init__(self, LOG_FORMAT, HOUR_FORMAT)
-
- def format(self, rec):
- if rec.levelno >= logging.WARNING or rec.levelno == logging.INFO:
- try:
- return '%s%s%s' % (rec.c1, rec.msg.decode('utf-8'), rec.c2)
- except:
- return rec.c1+rec.msg+rec.c2
- return logging.Formatter.format(self, rec)
-
-def debug(*k, **kw):
- if verbose:
- k = list(k)
- k[0] = k[0].replace('\n', ' ')
- logging.debug(*k, **kw)
-
-def error(*k, **kw):
- logging.error(*k, **kw)
- if verbose > 1:
- if isinstance(k[0], Utils.WafError):
- st = k[0].stack
- else:
- st = traceback.extract_stack()
- if st:
- st = st[:-1]
- buf = []
- for filename, lineno, name, line in st:
- buf.append(' File "%s", line %d, in %s' % (filename, lineno, name))
- if line:
- buf.append(' %s' % line.strip())
- if buf: logging.error("\n".join(buf))
-
-warn = logging.warn
-info = logging.info
-
-def init_log():
- log = logging.getLogger()
- log.handlers = []
- log.filters = []
- hdlr = logging.StreamHandler()
- hdlr.setFormatter(formatter())
- log.addHandler(hdlr)
- log.addFilter(log_filter())
- log.setLevel(logging.DEBUG)
-
-# may be initialized more than once
-init_log()
-
diff --git a/tools/wafadmin/Node.py b/tools/wafadmin/Node.py
deleted file mode 100644
index 33d12f999..000000000
--- a/tools/wafadmin/Node.py
+++ /dev/null
@@ -1,693 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005 (ita)
-
-"""
-Node: filesystem structure, contains lists of nodes
-
-IMPORTANT:
-1. Each file/folder is represented by exactly one node.
-
-2. Most would-be class properties are stored in Build: nodes to depend on, signature, flags, ..
-unused class members increase the .wafpickle file size sensibly with lots of objects.
-
-3. The build is launched from the top of the build dir (for example, in _build_/).
-
-4. Node should not be instantiated directly.
-Each instance of Build.BuildContext has a Node subclass.
-(aka: 'Nodu', see BuildContext initializer)
-The BuildContext is referenced here as self.__class__.bld
-Its Node class is referenced here as self.__class__
-
-The public and advertised apis are the following:
-${TGT} -> dir/to/file.ext
-${TGT[0].base()} -> dir/to/file
-${TGT[0].dir(env)} -> dir/to
-${TGT[0].file()} -> file.ext
-${TGT[0].file_base()} -> file
-${TGT[0].suffix()} -> .ext
-${TGT[0].abspath(env)} -> /path/to/dir/to/file.ext
-
-"""
-
-import os, sys, fnmatch, re, stat
-import Utils, Constants
-
-UNDEFINED = 0
-DIR = 1
-FILE = 2
-BUILD = 3
-
-type_to_string = {UNDEFINED: "unk", DIR: "dir", FILE: "src", BUILD: "bld"}
-
-# These fnmatch expressions are used by default to prune the directory tree
-# while doing the recursive traversal in the find_iter method of the Node class.
-prune_pats = '.git .bzr .hg .svn _MTN _darcs CVS SCCS'.split()
-
-# These fnmatch expressions are used by default to exclude files and dirs
-# while doing the recursive traversal in the find_iter method of the Node class.
-exclude_pats = prune_pats + '*~ #*# .#* %*% ._* .gitignore .cvsignore vssver.scc .DS_Store'.split()
-
-# These Utils.jar_regexp expressions are used by default to exclude files and dirs and also prune the directory tree
-# while doing the recursive traversal in the ant_glob method of the Node class.
-exclude_regs = '''
-**/*~
-**/#*#
-**/.#*
-**/%*%
-**/._*
-**/CVS
-**/CVS/**
-**/.cvsignore
-**/SCCS
-**/SCCS/**
-**/vssver.scc
-**/.svn
-**/.svn/**
-**/.git
-**/.git/**
-**/.gitignore
-**/.bzr
-**/.bzr/**
-**/.hg
-**/.hg/**
-**/_MTN
-**/_MTN/**
-**/_darcs
-**/_darcs/**
-**/.DS_Store'''
-
-class Node(object):
- __slots__ = ("name", "parent", "id", "childs")
- def __init__(self, name, parent, node_type = UNDEFINED):
- self.name = name
- self.parent = parent
-
- # assumption: one build object at a time
- self.__class__.bld.id_nodes += 4
- self.id = self.__class__.bld.id_nodes + node_type
-
- if node_type == DIR: self.childs = {}
-
- # We do not want to add another type attribute (memory)
- # use the id to find out: type = id & 3
- # for setting: new type = type + x - type & 3
-
- if parent and name in parent.childs:
- raise Utils.WafError('node %s exists in the parent files %r already' % (name, parent))
-
- if parent: parent.childs[name] = self
-
- def __setstate__(self, data):
- if len(data) == 4:
- (self.parent, self.name, self.id, self.childs) = data
- else:
- (self.parent, self.name, self.id) = data
-
- def __getstate__(self):
- if getattr(self, 'childs', None) is None:
- return (self.parent, self.name, self.id)
- else:
- return (self.parent, self.name, self.id, self.childs)
-
- def __str__(self):
- if not self.parent: return ''
- return "%s://%s" % (type_to_string[self.id & 3], self.abspath())
-
- def __repr__(self):
- return self.__str__()
-
- def __hash__(self):
- "expensive, make certain it is not used"
- raise Utils.WafError('nodes, you are doing it wrong')
-
- def __copy__(self):
- "nodes are not supposed to be copied"
- raise Utils.WafError('nodes are not supposed to be cloned')
-
- def get_type(self):
- return self.id & 3
-
- def set_type(self, t):
- "dangerous, you are not supposed to use this"
- self.id = self.id + t - self.id & 3
-
- def dirs(self):
- return [x for x in self.childs.values() if x.id & 3 == DIR]
-
- def files(self):
- return [x for x in self.childs.values() if x.id & 3 == FILE]
-
- def get_dir(self, name, default=None):
- node = self.childs.get(name, None)
- if not node or node.id & 3 != DIR: return default
- return node
-
- def get_file(self, name, default=None):
- node = self.childs.get(name, None)
- if not node or node.id & 3 != FILE: return default
- return node
-
- def get_build(self, name, default=None):
- node = self.childs.get(name, None)
- if not node or node.id & 3 != BUILD: return default
- return node
-
- def find_resource(self, lst):
- "Find an existing input file: either a build node declared previously or a source node"
- if isinstance(lst, str):
- lst = Utils.split_path(lst)
-
- if len(lst) == 1:
- parent = self
- else:
- parent = self.find_dir(lst[:-1])
- if not parent: return None
- self.__class__.bld.rescan(parent)
-
- name = lst[-1]
- node = parent.childs.get(name, None)
- if node:
- tp = node.id & 3
- if tp == FILE or tp == BUILD:
- return node
- else:
- return None
-
- tree = self.__class__.bld
- if not name in tree.cache_dir_contents[parent.id]:
- return None
-
- path = parent.abspath() + os.sep + name
- try:
- st = Utils.h_file(path)
- except IOError:
- return None
-
- child = self.__class__(name, parent, FILE)
- tree.node_sigs[0][child.id] = st
- return child
-
- def find_or_declare(self, lst):
- "Used for declaring a build node representing a file being built"
- if isinstance(lst, str):
- lst = Utils.split_path(lst)
-
- if len(lst) == 1:
- parent = self
- else:
- parent = self.find_dir(lst[:-1])
- if not parent: return None
- self.__class__.bld.rescan(parent)
-
- name = lst[-1]
- node = parent.childs.get(name, None)
- if node:
- tp = node.id & 3
- if tp != BUILD:
- raise Utils.WafError('find_or_declare cannot return a build node (build files in the source directory %r?)' % lst)
- return node
- node = self.__class__(name, parent, BUILD)
- return node
-
- def find_dir(self, lst):
- "search a folder in the filesystem"
-
- if isinstance(lst, str):
- lst = Utils.split_path(lst)
-
- current = self
- for name in lst:
- self.__class__.bld.rescan(current)
- prev = current
-
- if not current.parent and name == current.name:
- continue
- elif not name:
- continue
- elif name == '.':
- continue
- elif name == '..':
- current = current.parent or current
- else:
- current = prev.childs.get(name, None)
- if current is None:
- dir_cont = self.__class__.bld.cache_dir_contents
- if prev.id in dir_cont and name in dir_cont[prev.id]:
- if not prev.name:
- if os.sep == '/':
- # cygwin //machine/share
- dirname = os.sep + name
- else:
- # windows c:
- dirname = name
- else:
- # regular path
- dirname = prev.abspath() + os.sep + name
- if not os.path.isdir(dirname):
- return None
- current = self.__class__(name, prev, DIR)
- elif (not prev.name and len(name) == 2 and name[1] == ':') or name.startswith('\\\\'):
- # drive letter or \\ path for windows
- current = self.__class__(name, prev, DIR)
- else:
- return None
- else:
- if current.id & 3 != DIR:
- return None
- return current
-
- def ensure_dir_node_from_path(self, lst):
- "used very rarely, force the construction of a branch of node instance for representing folders"
-
- if isinstance(lst, str):
- lst = Utils.split_path(lst)
-
- current = self
- for name in lst:
- if not name:
- continue
- elif name == '.':
- continue
- elif name == '..':
- current = current.parent or current
- else:
- prev = current
- current = prev.childs.get(name, None)
- if current is None:
- current = self.__class__(name, prev, DIR)
- return current
-
- def exclusive_build_node(self, path):
- """
- create a hierarchy in the build dir (no source folders) for ill-behaving compilers
- the node is not hashed, so you must do it manually
-
- after declaring such a node, find_dir and find_resource should work as expected
- """
- lst = Utils.split_path(path)
- name = lst[-1]
- if len(lst) > 1:
- parent = None
- try:
- parent = self.find_dir(lst[:-1])
- except OSError:
- pass
- if not parent:
- parent = self.ensure_dir_node_from_path(lst[:-1])
- self.__class__.bld.rescan(parent)
- else:
- try:
- self.__class__.bld.rescan(parent)
- except OSError:
- pass
- else:
- parent = self
-
- node = parent.childs.get(name, None)
- if not node:
- node = self.__class__(name, parent, BUILD)
-
- return node
-
- def path_to_parent(self, parent):
- "path relative to a direct ancestor, as string"
- lst = []
- p = self
- h1 = parent.height()
- h2 = p.height()
- while h2 > h1:
- h2 -= 1
- lst.append(p.name)
- p = p.parent
- if lst:
- lst.reverse()
- ret = os.path.join(*lst)
- else:
- ret = ''
- return ret
-
- def find_ancestor(self, node):
- "find a common ancestor for two nodes - for the shortest path in hierarchy"
- dist = self.height() - node.height()
- if dist < 0: return node.find_ancestor(self)
- # now the real code
- cand = self
- while dist > 0:
- cand = cand.parent
- dist -= 1
- if cand == node: return cand
- cursor = node
- while cand.parent:
- cand = cand.parent
- cursor = cursor.parent
- if cand == cursor: return cand
-
- def relpath_gen(self, from_node):
- "string representing a relative path between self to another node"
-
- if self == from_node: return '.'
- if from_node.parent == self: return '..'
-
- # up_path is '../../../' and down_path is 'dir/subdir/subdir/file'
- ancestor = self.find_ancestor(from_node)
- lst = []
- cand = self
- while not cand.id == ancestor.id:
- lst.append(cand.name)
- cand = cand.parent
- cand = from_node
- while not cand.id == ancestor.id:
- lst.append('..')
- cand = cand.parent
- lst.reverse()
- return os.sep.join(lst)
-
- def nice_path(self, env=None):
- "printed in the console, open files easily from the launch directory"
- tree = self.__class__.bld
- ln = tree.launch_node()
-
- if self.id & 3 == FILE: return self.relpath_gen(ln)
- else: return os.path.join(tree.bldnode.relpath_gen(ln), env.variant(), self.relpath_gen(tree.srcnode))
-
- def is_child_of(self, node):
- "does this node belong to the subtree node"
- p = self
- diff = self.height() - node.height()
- while diff > 0:
- diff -= 1
- p = p.parent
- return p.id == node.id
-
- def variant(self, env):
- "variant, or output directory for this node, a source has for variant 0"
- if not env: return 0
- elif self.id & 3 == FILE: return 0
- else: return env.variant()
-
- def height(self):
- "amount of parents"
- # README a cache can be added here if necessary
- d = self
- val = -1
- while d:
- d = d.parent
- val += 1
- return val
-
- # helpers for building things
-
- def abspath(self, env=None):
- """
- absolute path
- @param env [Environment]:
- * obligatory for build nodes: build/variant/src/dir/bar.o
- * optional for dirs: get either src/dir or build/variant/src/dir
- * excluded for source nodes: src/dir/bar.c
-
- Instead of computing the absolute path each time again,
- store the already-computed absolute paths in one of (variants+1) dictionaries:
- bld.cache_node_abspath[0] holds absolute paths for source nodes.
- bld.cache_node_abspath[variant] holds the absolute path for the build nodes
- which reside in the variant given by env.
- """
- ## absolute path - hot zone, so do not touch
-
- # less expensive
- variant = (env and (self.id & 3 != FILE) and env.variant()) or 0
-
- ret = self.__class__.bld.cache_node_abspath[variant].get(self.id, None)
- if ret: return ret
-
- if not variant:
- # source directory
- if not self.parent:
- val = os.sep == '/' and os.sep or ''
- elif not self.parent.name: # root
- val = (os.sep == '/' and os.sep or '') + self.name
- else:
- val = self.parent.abspath() + os.sep + self.name
- else:
- # build directory
- val = os.sep.join((self.__class__.bld.bldnode.abspath(), variant, self.path_to_parent(self.__class__.bld.srcnode)))
- self.__class__.bld.cache_node_abspath[variant][self.id] = val
- return val
-
- def change_ext(self, ext):
- "node of the same path, but with a different extension - hot zone so do not touch"
- name = self.name
- k = name.rfind('.')
- if k >= 0:
- name = name[:k] + ext
- else:
- name = name + ext
-
- return self.parent.find_or_declare([name])
-
- def src_dir(self, env):
- "src path without the file name"
- return self.parent.srcpath(env)
-
- def bld_dir(self, env):
- "build path without the file name"
- return self.parent.bldpath(env)
-
- def bld_base(self, env):
- "build path without the extension: src/dir/foo(.cpp)"
- s = os.path.splitext(self.name)[0]
- return os.path.join(self.bld_dir(env), s)
-
- def bldpath(self, env=None):
- "path seen from the build dir default/src/foo.cpp"
- if self.id & 3 == FILE:
- return self.relpath_gen(self.__class__.bld.bldnode)
- p = self.path_to_parent(self.__class__.bld.srcnode)
- if p is not '':
- return env.variant() + os.sep + p
- return env.variant()
-
- def srcpath(self, env=None):
- "path in the srcdir from the build dir ../src/foo.cpp"
- if self.id & 3 == BUILD:
- return self.bldpath(env)
- return self.relpath_gen(self.__class__.bld.bldnode)
-
- def read(self, env):
- "get the contents of a file, it is not used anywhere for the moment"
- return Utils.readf(self.abspath(env))
-
- def dir(self, env):
- "scons-like"
- return self.parent.abspath(env)
-
- def file(self):
- "scons-like"
- return self.name
-
- def file_base(self):
- "scons-like"
- return os.path.splitext(self.name)[0]
-
- def suffix(self):
- "scons-like - hot zone so do not touch"
- k = max(0, self.name.rfind('.'))
- return self.name[k:]
-
- def find_iter_impl(self, src=True, bld=True, dir=True, accept_name=None, is_prune=None, maxdepth=25):
- """find nodes in the filesystem hierarchy, try to instanciate the nodes passively; same gotcha as ant_glob"""
- bld_ctx = self.__class__.bld
- bld_ctx.rescan(self)
- for name in bld_ctx.cache_dir_contents[self.id]:
- if accept_name(self, name):
- node = self.find_resource(name)
- if node:
- if src and node.id & 3 == FILE:
- yield node
- else:
- node = self.find_dir(name)
- if node and node.id != bld_ctx.bldnode.id:
- if dir:
- yield node
- if not is_prune(self, name):
- if maxdepth:
- for k in node.find_iter_impl(src, bld, dir, accept_name, is_prune, maxdepth=maxdepth - 1):
- yield k
- else:
- if not is_prune(self, name):
- node = self.find_resource(name)
- if not node:
- # not a file, it is a dir
- node = self.find_dir(name)
- if node and node.id != bld_ctx.bldnode.id:
- if maxdepth:
- for k in node.find_iter_impl(src, bld, dir, accept_name, is_prune, maxdepth=maxdepth - 1):
- yield k
-
- if bld:
- for node in self.childs.values():
- if node.id == bld_ctx.bldnode.id:
- continue
- if node.id & 3 == BUILD:
- if accept_name(self, node.name):
- yield node
- raise StopIteration
-
- def find_iter(self, in_pat=['*'], ex_pat=exclude_pats, prune_pat=prune_pats, src=True, bld=True, dir=False, maxdepth=25, flat=False):
- """find nodes recursively, this returns everything but folders by default; same gotcha as ant_glob"""
-
- if not (src or bld or dir):
- raise StopIteration
-
- if self.id & 3 != DIR:
- raise StopIteration
-
- in_pat = Utils.to_list(in_pat)
- ex_pat = Utils.to_list(ex_pat)
- prune_pat = Utils.to_list(prune_pat)
-
- def accept_name(node, name):
- for pat in ex_pat:
- if fnmatch.fnmatchcase(name, pat):
- return False
- for pat in in_pat:
- if fnmatch.fnmatchcase(name, pat):
- return True
- return False
-
- def is_prune(node, name):
- for pat in prune_pat:
- if fnmatch.fnmatchcase(name, pat):
- return True
- return False
-
- ret = self.find_iter_impl(src, bld, dir, accept_name, is_prune, maxdepth=maxdepth)
- if flat:
- return " ".join([x.relpath_gen(self) for x in ret])
-
- return ret
-
- def ant_glob(self, *k, **kw):
- """
- known gotcha: will enumerate the files, but only if the folder exists in the source directory
- """
-
- src=kw.get('src', 1)
- bld=kw.get('bld', 0)
- dir=kw.get('dir', 0)
- excl = kw.get('excl', exclude_regs)
- incl = k and k[0] or kw.get('incl', '**')
-
- def to_pat(s):
- lst = Utils.to_list(s)
- ret = []
- for x in lst:
- x = x.replace('//', '/')
- if x.endswith('/'):
- x += '**'
- lst2 = x.split('/')
- accu = []
- for k in lst2:
- if k == '**':
- accu.append(k)
- else:
- k = k.replace('.', '[.]').replace('*', '.*').replace('?', '.')
- k = '^%s$' % k
- #print "pattern", k
- accu.append(re.compile(k))
- ret.append(accu)
- return ret
-
- def filtre(name, nn):
- ret = []
- for lst in nn:
- if not lst:
- pass
- elif lst[0] == '**':
- ret.append(lst)
- if len(lst) > 1:
- if lst[1].match(name):
- ret.append(lst[2:])
- else:
- ret.append([])
- elif lst[0].match(name):
- ret.append(lst[1:])
- return ret
-
- def accept(name, pats):
- nacc = filtre(name, pats[0])
- nrej = filtre(name, pats[1])
- if [] in nrej:
- nacc = []
- return [nacc, nrej]
-
- def ant_iter(nodi, maxdepth=25, pats=[]):
- nodi.__class__.bld.rescan(nodi)
- for name in nodi.__class__.bld.cache_dir_contents[nodi.id]:
- npats = accept(name, pats)
- if npats and npats[0]:
- accepted = [] in npats[0]
- #print accepted, nodi, name
-
- node = nodi.find_resource(name)
- if node and accepted:
- if src and node.id & 3 == FILE:
- yield node
- else:
- node = nodi.find_dir(name)
- if node and node.id != nodi.__class__.bld.bldnode.id:
- if accepted and dir:
- yield node
- if maxdepth:
- for k in ant_iter(node, maxdepth=maxdepth - 1, pats=npats):
- yield k
- if bld:
- for node in nodi.childs.values():
- if node.id == nodi.__class__.bld.bldnode.id:
- continue
- if node.id & 3 == BUILD:
- npats = accept(node.name, pats)
- if npats and npats[0] and [] in npats[0]:
- yield node
- raise StopIteration
-
- ret = [x for x in ant_iter(self, pats=[to_pat(incl), to_pat(excl)])]
-
- if kw.get('flat', True):
- return " ".join([x.relpath_gen(self) for x in ret])
-
- return ret
-
- def update_build_dir(self, env=None):
-
- if not env:
- for env in bld.all_envs:
- self.update_build_dir(env)
- return
-
- path = self.abspath(env)
-
- lst = Utils.listdir(path)
- try:
- self.__class__.bld.cache_dir_contents[self.id].update(lst)
- except KeyError:
- self.__class__.bld.cache_dir_contents[self.id] = set(lst)
- self.__class__.bld.cache_scanned_folders[self.id] = True
-
- for k in lst:
- npath = path + os.sep + k
- st = os.stat(npath)
- if stat.S_ISREG(st[stat.ST_MODE]):
- ick = self.find_or_declare(k)
- if not (ick.id in self.__class__.bld.node_sigs[env.variant()]):
- self.__class__.bld.node_sigs[env.variant()][ick.id] = Constants.SIG_NIL
- elif stat.S_ISDIR(st[stat.ST_MODE]):
- child = self.find_dir(k)
- if not child:
- child = self.ensure_dir_node_from_path(k)
- child.update_build_dir(env)
-
-
-class Nodu(Node):
- pass
-
diff --git a/tools/wafadmin/Options.py b/tools/wafadmin/Options.py
deleted file mode 100644
index c90bb994a..000000000
--- a/tools/wafadmin/Options.py
+++ /dev/null
@@ -1,279 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Scott Newton, 2005 (scottn)
-# Thomas Nagy, 2006 (ita)
-
-"Custom command-line options"
-
-import os, sys, imp, types, tempfile, optparse
-import Logs, Utils
-from Constants import *
-
-cmds = 'distclean configure build install clean uninstall check dist distcheck'.split()
-
-# TODO remove in waf 1.6 the following two
-commands = {}
-is_install = False
-
-options = {}
-arg_line = []
-launch_dir = ''
-tooldir = ''
-lockfile = os.environ.get('WAFLOCK', '.lock-wscript')
-try: cache_global = os.path.abspath(os.environ['WAFCACHE'])
-except KeyError: cache_global = ''
-platform = Utils.unversioned_sys_platform()
-conf_file = 'conf-runs-%s-%d.pickle' % (platform, ABI)
-
-remote_repo = ['http://waf.googlecode.com/svn/']
-"""remote directory for the plugins"""
-
-
-# Such a command-line should work: JOBS=4 PREFIX=/opt/ DESTDIR=/tmp/ahoj/ waf configure
-default_prefix = os.environ.get('PREFIX')
-if not default_prefix:
- if platform == 'win32': default_prefix = tempfile.gettempdir()
- else: default_prefix = '/usr/local/'
-
-default_jobs = os.environ.get('JOBS', -1)
-if default_jobs < 1:
- try:
- if 'SC_NPROCESSORS_ONLN' in os.sysconf_names:
- default_jobs = os.sysconf('SC_NPROCESSORS_ONLN')
- else:
- default_jobs = int(Utils.cmd_output(['sysctl', '-n', 'hw.ncpu']))
- except:
- if os.name == 'java': # platform.system() == 'Java'
- from java.lang import Runtime
- default_jobs = Runtime.getRuntime().availableProcessors()
- else:
- # environment var defined on win32
- default_jobs = int(os.environ.get('NUMBER_OF_PROCESSORS', 1))
-
-default_destdir = os.environ.get('DESTDIR', '')
-
-def get_usage(self):
- cmds_str = []
- module = Utils.g_module
- if module:
- # create the help messages for commands
- tbl = module.__dict__
- keys = list(tbl.keys())
- keys.sort()
-
- if 'build' in tbl:
- if not module.build.__doc__:
- module.build.__doc__ = 'builds the project'
- if 'configure' in tbl:
- if not module.configure.__doc__:
- module.configure.__doc__ = 'configures the project'
-
- ban = ['set_options', 'init', 'shutdown']
-
- optlst = [x for x in keys if not x in ban
- and type(tbl[x]) is type(parse_args_impl)
- and tbl[x].__doc__
- and not x.startswith('_')]
-
- just = max([len(x) for x in optlst])
-
- for x in optlst:
- cmds_str.append(' %s: %s' % (x.ljust(just), tbl[x].__doc__))
- ret = '\n'.join(cmds_str)
- else:
- ret = ' '.join(cmds)
- return '''waf [command] [options]
-
-Main commands (example: ./waf build -j4)
-%s
-''' % ret
-
-
-setattr(optparse.OptionParser, 'get_usage', get_usage)
-
-def create_parser(module=None):
- Logs.debug('options: create_parser is called')
- parser = optparse.OptionParser(conflict_handler="resolve", version = 'waf %s (%s)' % (WAFVERSION, WAFREVISION))
-
- parser.formatter.width = Utils.get_term_cols()
- p = parser.add_option
-
- p('-j', '--jobs',
- type = 'int',
- default = default_jobs,
- help = 'amount of parallel jobs (%r)' % default_jobs,
- dest = 'jobs')
-
- p('-k', '--keep',
- action = 'store_true',
- default = False,
- help = 'keep running happily on independent task groups',
- dest = 'keep')
-
- p('-v', '--verbose',
- action = 'count',
- default = 0,
- help = 'verbosity level -v -vv or -vvv [default: 0]',
- dest = 'verbose')
-
- p('--nocache',
- action = 'store_true',
- default = False,
- help = 'ignore the WAFCACHE (if set)',
- dest = 'nocache')
-
- p('--zones',
- action = 'store',
- default = '',
- help = 'debugging zones (task_gen, deps, tasks, etc)',
- dest = 'zones')
-
- p('-p', '--progress',
- action = 'count',
- default = 0,
- help = '-p: progress bar; -pp: ide output',
- dest = 'progress_bar')
-
- p('--targets',
- action = 'store',
- default = '',
- help = 'build given task generators, e.g. "target1,target2"',
- dest = 'compile_targets')
-
- gr = optparse.OptionGroup(parser, 'configuration options')
- parser.add_option_group(gr)
- gr.add_option('-b', '--blddir',
- action = 'store',
- default = '',
- help = 'build dir for the project (configuration)',
- dest = 'blddir')
- gr.add_option('-s', '--srcdir',
- action = 'store',
- default = '',
- help = 'src dir for the project (configuration)',
- dest = 'srcdir')
- gr.add_option('--prefix',
- help = 'installation prefix (configuration) [default: %r]' % default_prefix,
- default = default_prefix,
- dest = 'prefix')
-
- gr = optparse.OptionGroup(parser, 'installation options')
- parser.add_option_group(gr)
- gr.add_option('--destdir',
- help = 'installation root [default: %r]' % default_destdir,
- default = default_destdir,
- dest = 'destdir')
- gr.add_option('-f', '--force',
- action = 'store_true',
- default = False,
- help = 'force file installation',
- dest = 'force')
-
- return parser
-
-def parse_args_impl(parser, _args=None):
- global options, commands, arg_line
- (options, args) = parser.parse_args(args=_args)
-
- arg_line = args
- #arg_line = args[:] # copy
-
- # By default, 'waf' is equivalent to 'waf build'
- commands = {}
- for var in cmds: commands[var] = 0
- if not args:
- commands['build'] = 1
- args.append('build')
-
- # Parse the command arguments
- for arg in args:
- commands[arg] = True
-
- # the check thing depends on the build
- if 'check' in args:
- idx = args.index('check')
- try:
- bidx = args.index('build')
- if bidx > idx:
- raise ValueError('build before check')
- except ValueError, e:
- args.insert(idx, 'build')
-
- if args[0] != 'init':
- args.insert(0, 'init')
-
- # TODO -k => -j0
- if options.keep: options.jobs = 1
- if options.jobs < 1: options.jobs = 1
-
- if 'install' in sys.argv or 'uninstall' in sys.argv:
- # absolute path only if set
- options.destdir = options.destdir and os.path.abspath(os.path.expanduser(options.destdir))
-
- Logs.verbose = options.verbose
- Logs.init_log()
-
- if options.zones:
- Logs.zones = options.zones.split(',')
- if not Logs.verbose: Logs.verbose = 1
- elif Logs.verbose > 0:
- Logs.zones = ['runner']
- if Logs.verbose > 2:
- Logs.zones = ['*']
-
-# TODO waf 1.6
-# 1. rename the class to OptionsContext
-# 2. instead of a class attribute, use a module (static 'parser')
-# 3. parse_args_impl was made in times when we did not know about binding new methods to classes
-
-class Handler(Utils.Context):
- """loads wscript modules in folders for adding options
- This class should be named 'OptionsContext'
- A method named 'recurse' is bound when used by the module Scripting"""
-
- parser = None
- # make it possible to access the reference, like Build.bld
-
- def __init__(self, module=None):
- self.parser = create_parser(module)
- self.cwd = os.getcwd()
- Handler.parser = self
-
- def add_option(self, *k, **kw):
- self.parser.add_option(*k, **kw)
-
- def add_option_group(self, *k, **kw):
- return self.parser.add_option_group(*k, **kw)
-
- def get_option_group(self, opt_str):
- return self.parser.get_option_group(opt_str)
-
- def sub_options(self, *k, **kw):
- if not k: raise Utils.WscriptError('folder expected')
- self.recurse(k[0], name='set_options')
-
- def tool_options(self, *k, **kw):
- Utils.python_24_guard()
-
- if not k[0]:
- raise Utils.WscriptError('invalid tool_options call %r %r' % (k, kw))
- tools = Utils.to_list(k[0])
-
- # TODO waf 1.6 remove the global variable tooldir
- path = Utils.to_list(kw.get('tdir', kw.get('tooldir', tooldir)))
-
- for tool in tools:
- tool = tool.replace('++', 'xx')
- if tool == 'java': tool = 'javaw'
- if tool.lower() == 'unittest': tool = 'unittestw'
- module = Utils.load_tool(tool, path)
- try:
- fun = module.set_options
- except AttributeError:
- pass
- else:
- fun(kw.get('option_group', self))
-
- def parse_args(self, args=None):
- parse_args_impl(self.parser, args)
-
diff --git a/tools/wafadmin/Runner.py b/tools/wafadmin/Runner.py
deleted file mode 100644
index 5237c1abd..000000000
--- a/tools/wafadmin/Runner.py
+++ /dev/null
@@ -1,229 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005-2008 (ita)
-
-"Execute the tasks"
-
-import sys, random, time, threading, traceback
-try: from Queue import Queue
-except ImportError: from queue import Queue
-import Build, Utils, Logs, Options
-from Logs import debug, error
-from Constants import *
-
-GAP = 15
-
-run_old = threading.Thread.run
-def run(*args, **kwargs):
- try:
- run_old(*args, **kwargs)
- except (KeyboardInterrupt, SystemExit):
- raise
- except:
- sys.excepthook(*sys.exc_info())
-threading.Thread.run = run
-
-class TaskConsumer(threading.Thread):
- ready = Queue(0)
- consumers = []
-
- def __init__(self):
- threading.Thread.__init__(self)
- self.setDaemon(1)
- self.start()
-
- def run(self):
- try:
- self.loop()
- except:
- pass
-
- def loop(self):
- while 1:
- tsk = TaskConsumer.ready.get()
- m = tsk.master
- if m.stop:
- m.out.put(tsk)
- continue
-
- try:
- tsk.generator.bld.printout(tsk.display())
- if tsk.__class__.stat: ret = tsk.__class__.stat(tsk)
- # actual call to task's run() function
- else: ret = tsk.call_run()
- except Exception, e:
- tsk.err_msg = Utils.ex_stack()
- tsk.hasrun = EXCEPTION
-
- # TODO cleanup
- m.error_handler(tsk)
- m.out.put(tsk)
- continue
-
- if ret:
- tsk.err_code = ret
- tsk.hasrun = CRASHED
- else:
- try:
- tsk.post_run()
- except Utils.WafError:
- pass
- except Exception:
- tsk.err_msg = Utils.ex_stack()
- tsk.hasrun = EXCEPTION
- else:
- tsk.hasrun = SUCCESS
- if tsk.hasrun != SUCCESS:
- m.error_handler(tsk)
-
- m.out.put(tsk)
-
-class Parallel(object):
- """
- keep the consumer threads busy, and avoid consuming cpu cycles
- when no more tasks can be added (end of the build, etc)
- """
- def __init__(self, bld, j=2):
-
- # number of consumers
- self.numjobs = j
-
- self.manager = bld.task_manager
- self.manager.current_group = 0
-
- self.total = self.manager.total()
-
- # tasks waiting to be processed - IMPORTANT
- self.outstanding = []
- self.maxjobs = MAXJOBS
-
- # tasks that are awaiting for another task to complete
- self.frozen = []
-
- # tasks returned by the consumers
- self.out = Queue(0)
-
- self.count = 0 # tasks not in the producer area
-
- self.processed = 1 # progress indicator
-
- self.stop = False # error condition to stop the build
- self.error = False # error flag
-
- def get_next(self):
- "override this method to schedule the tasks in a particular order"
- if not self.outstanding:
- return None
- return self.outstanding.pop(0)
-
- def postpone(self, tsk):
- "override this method to schedule the tasks in a particular order"
- # TODO consider using a deque instead
- if random.randint(0, 1):
- self.frozen.insert(0, tsk)
- else:
- self.frozen.append(tsk)
-
- def refill_task_list(self):
- "called to set the next group of tasks"
-
- while self.count > self.numjobs + GAP or self.count >= self.maxjobs:
- self.get_out()
-
- while not self.outstanding:
- if self.count:
- self.get_out()
-
- if self.frozen:
- self.outstanding += self.frozen
- self.frozen = []
- elif not self.count:
- (jobs, tmp) = self.manager.get_next_set()
- if jobs != None: self.maxjobs = jobs
- if tmp: self.outstanding += tmp
- break
-
- def get_out(self):
- "the tasks that are put to execute are all collected using get_out"
- ret = self.out.get()
- self.manager.add_finished(ret)
- if not self.stop and getattr(ret, 'more_tasks', None):
- self.outstanding += ret.more_tasks
- self.total += len(ret.more_tasks)
- self.count -= 1
-
- def error_handler(self, tsk):
- "by default, errors make the build stop (not thread safe so be careful)"
- if not Options.options.keep:
- self.stop = True
- self.error = True
-
- def start(self):
- "execute the tasks"
-
- if TaskConsumer.consumers:
- # the worker pool is usually loaded lazily (see below)
- # in case it is re-used with a different value of numjobs:
- while len(TaskConsumer.consumers) < self.numjobs:
- TaskConsumer.consumers.append(TaskConsumer())
-
- while not self.stop:
-
- self.refill_task_list()
-
- # consider the next task
- tsk = self.get_next()
- if not tsk:
- if self.count:
- # tasks may add new ones after they are run
- continue
- else:
- # no tasks to run, no tasks running, time to exit
- break
-
- if tsk.hasrun:
- # if the task is marked as "run", just skip it
- self.processed += 1
- self.manager.add_finished(tsk)
- continue
-
- try:
- st = tsk.runnable_status()
- except Exception, e:
- self.processed += 1
- if self.stop and not Options.options.keep:
- tsk.hasrun = SKIPPED
- self.manager.add_finished(tsk)
- continue
- self.error_handler(tsk)
- self.manager.add_finished(tsk)
- tsk.hasrun = EXCEPTION
- tsk.err_msg = Utils.ex_stack()
- continue
-
- if st == ASK_LATER:
- self.postpone(tsk)
- elif st == SKIP_ME:
- self.processed += 1
- tsk.hasrun = SKIPPED
- self.manager.add_finished(tsk)
- else:
- # run me: put the task in ready queue
- tsk.position = (self.processed, self.total)
- self.count += 1
- tsk.master = self
- TaskConsumer.ready.put(tsk)
- self.processed += 1
-
- # create the consumer threads only if there is something to consume
- if not TaskConsumer.consumers:
- TaskConsumer.consumers = [TaskConsumer() for i in xrange(self.numjobs)]
-
- # self.count represents the tasks that have been made available to the consumer threads
- # collect all the tasks after an error else the message may be incomplete
- while self.error and self.count:
- self.get_out()
-
- #print loop
- assert (self.count == 0 or self.stop)
-
diff --git a/tools/wafadmin/Scripting.py b/tools/wafadmin/Scripting.py
deleted file mode 100644
index d975bd934..000000000
--- a/tools/wafadmin/Scripting.py
+++ /dev/null
@@ -1,586 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005 (ita)
-
-"Module called for configuring, compiling and installing targets"
-
-import os, sys, shutil, traceback, datetime, inspect, errno
-
-import Utils, Configure, Build, Logs, Options, Environment, Task
-from Logs import error, warn, info
-from Constants import *
-
-g_gz = 'bz2'
-commands = []
-
-def prepare_impl(t, cwd, ver, wafdir):
- Options.tooldir = [t]
- Options.launch_dir = cwd
-
- # some command-line options can be processed immediately
- if '--version' in sys.argv:
- opt_obj = Options.Handler()
- opt_obj.curdir = cwd
- opt_obj.parse_args()
- sys.exit(0)
-
- # now find the wscript file
- msg1 = 'Waf: Please run waf from a directory containing a file named "%s" or run distclean' % WSCRIPT_FILE
-
- # in theory projects can be configured in an autotool-like manner:
- # mkdir build && cd build && ../waf configure && ../waf
- build_dir_override = None
- candidate = None
-
- lst = os.listdir(cwd)
-
- search_for_candidate = True
- if WSCRIPT_FILE in lst:
- candidate = cwd
-
- elif 'configure' in sys.argv and not WSCRIPT_BUILD_FILE in lst:
- # autotool-like configuration
- calldir = os.path.abspath(os.path.dirname(sys.argv[0]))
- if WSCRIPT_FILE in os.listdir(calldir):
- candidate = calldir
- search_for_candidate = False
- else:
- error('arg[0] directory does not contain a wscript file')
- sys.exit(1)
- build_dir_override = cwd
-
- # climb up to find a script if it is not found
- while search_for_candidate:
- if len(cwd) <= 3:
- break # stop at / or c:
- dirlst = os.listdir(cwd)
- if WSCRIPT_FILE in dirlst:
- candidate = cwd
- if 'configure' in sys.argv and candidate:
- break
- if Options.lockfile in dirlst:
- env = Environment.Environment()
- try:
- env.load(os.path.join(cwd, Options.lockfile))
- except:
- error('could not load %r' % Options.lockfile)
- try:
- os.stat(env['cwd'])
- except:
- candidate = cwd
- else:
- candidate = env['cwd']
- break
- cwd = os.path.dirname(cwd) # climb up
-
- if not candidate:
- # check if the user only wanted to display the help
- if '-h' in sys.argv or '--help' in sys.argv:
- warn('No wscript file found: the help message may be incomplete')
- opt_obj = Options.Handler()
- opt_obj.curdir = cwd
- opt_obj.parse_args()
- else:
- error(msg1)
- sys.exit(0)
-
- # We have found wscript, but there is no guarantee that it is valid
- try:
- os.chdir(candidate)
- except OSError:
- raise Utils.WafError("the folder %r is unreadable" % candidate)
-
- # define the main module containing the functions init, shutdown, ..
- Utils.set_main_module(os.path.join(candidate, WSCRIPT_FILE))
-
- if build_dir_override:
- d = getattr(Utils.g_module, BLDDIR, None)
- if d:
- # test if user has set the blddir in wscript.
- msg = ' Overriding build directory %s with %s' % (d, build_dir_override)
- warn(msg)
- Utils.g_module.blddir = build_dir_override
-
- # bind a few methods and classes by default
-
- def set_def(obj, name=''):
- n = name or obj.__name__
- if not n in Utils.g_module.__dict__:
- setattr(Utils.g_module, n, obj)
-
- for k in [dist, distclean, distcheck, clean, install, uninstall]:
- set_def(k)
-
- set_def(Configure.ConfigurationContext, 'configure_context')
-
- for k in ['build', 'clean', 'install', 'uninstall']:
- set_def(Build.BuildContext, k + '_context')
-
- # now parse the options from the user wscript file
- opt_obj = Options.Handler(Utils.g_module)
- opt_obj.curdir = candidate
- try:
- f = Utils.g_module.set_options
- except AttributeError:
- pass
- else:
- opt_obj.sub_options([''])
- opt_obj.parse_args()
-
- if not 'init' in Utils.g_module.__dict__:
- Utils.g_module.init = Utils.nada
- if not 'shutdown' in Utils.g_module.__dict__:
- Utils.g_module.shutdown = Utils.nada
-
- main()
-
-def prepare(t, cwd, ver, wafdir):
- if WAFVERSION != ver:
- msg = 'Version mismatch: waf %s <> wafadmin %s (wafdir %s)' % (ver, WAFVERSION, wafdir)
- print('\033[91mError: %s\033[0m' % msg)
- sys.exit(1)
-
- #"""
- try:
- prepare_impl(t, cwd, ver, wafdir)
- except Utils.WafError, e:
- error(str(e))
- sys.exit(1)
- except KeyboardInterrupt:
- Utils.pprint('RED', 'Interrupted')
- sys.exit(68)
- """
- import cProfile, pstats
- cProfile.runctx("import Scripting; Scripting.prepare_impl(t, cwd, ver, wafdir)", {},
- {'t': t, 'cwd':cwd, 'ver':ver, 'wafdir':wafdir},
- 'profi.txt')
- p = pstats.Stats('profi.txt')
- p.sort_stats('time').print_stats(45)
- #"""
-
-def main():
- global commands
- commands = Options.arg_line[:]
-
- while commands:
- x = commands.pop(0)
-
- ini = datetime.datetime.now()
- if x == 'configure':
- fun = configure
- elif x == 'build':
- fun = build
- else:
- fun = getattr(Utils.g_module, x, None)
-
- if not fun:
- raise Utils.WscriptError('No such command %r' % x)
-
- ctx = getattr(Utils.g_module, x + '_context', Utils.Context)()
-
- if x in ['init', 'shutdown', 'dist', 'distclean', 'distcheck']:
- # compatibility TODO remove in waf 1.6
- try:
- fun(ctx)
- except TypeError:
- fun()
- else:
- fun(ctx)
-
- ela = ''
- if not Options.options.progress_bar:
- ela = ' (%s)' % Utils.get_elapsed_time(ini)
-
- if x != 'init' and x != 'shutdown':
- info('%r finished successfully%s' % (x, ela))
-
- if not commands and x != 'shutdown':
- commands.append('shutdown')
-
-def configure(conf):
-
- src = getattr(Options.options, SRCDIR, None)
- if not src: src = getattr(Utils.g_module, SRCDIR, None)
- if not src: src = getattr(Utils.g_module, 'top', None)
- if not src:
- src = '.'
- incomplete_src = 1
- src = os.path.abspath(src)
-
- bld = getattr(Options.options, BLDDIR, None)
- if not bld: bld = getattr(Utils.g_module, BLDDIR, None)
- if not bld: bld = getattr(Utils.g_module, 'out', None)
- if not bld:
- bld = 'build'
- incomplete_bld = 1
- if bld == '.':
- raise Utils.WafError('Setting blddir="." may cause distclean problems')
- bld = os.path.abspath(bld)
-
- try: os.makedirs(bld)
- except OSError: pass
-
- # It is not possible to compile specific targets in the configuration
- # this may cause configuration errors if autoconfig is set
- targets = Options.options.compile_targets
- Options.options.compile_targets = None
- Options.is_install = False
-
- conf.srcdir = src
- conf.blddir = bld
- conf.post_init()
-
- if 'incomplete_src' in vars():
- conf.check_message_1('Setting srcdir to')
- conf.check_message_2(src)
- if 'incomplete_bld' in vars():
- conf.check_message_1('Setting blddir to')
- conf.check_message_2(bld)
-
- # calling to main wscript's configure()
- conf.sub_config([''])
-
- conf.store()
-
- # this will write a configure lock so that subsequent builds will
- # consider the current path as the root directory (see prepare_impl).
- # to remove: use 'waf distclean'
- env = Environment.Environment()
- env[BLDDIR] = bld
- env[SRCDIR] = src
- env['argv'] = sys.argv
- env['commands'] = Options.commands
- env['options'] = Options.options.__dict__
-
- # conf.hash & conf.files hold wscript files paths and hash
- # (used only by Configure.autoconfig)
- env['hash'] = conf.hash
- env['files'] = conf.files
- env['environ'] = dict(conf.environ)
- env['cwd'] = os.path.split(Utils.g_module.root_path)[0]
-
- if Utils.g_module.root_path != src:
- # in case the source dir is somewhere else
- env.store(os.path.join(src, Options.lockfile))
-
- env.store(Options.lockfile)
-
- Options.options.compile_targets = targets
-
-def clean(bld):
- '''removes the build files'''
- try:
- proj = Environment.Environment(Options.lockfile)
- except IOError:
- raise Utils.WafError('Nothing to clean (project not configured)')
-
- bld.load_dirs(proj[SRCDIR], proj[BLDDIR])
- bld.load_envs()
-
- bld.is_install = 0 # False
-
- # read the scripts - and set the path to the wscript path (useful for srcdir='/foo/bar')
- bld.add_subdirs([os.path.split(Utils.g_module.root_path)[0]])
-
- try:
- bld.clean()
- finally:
- bld.save()
-
-def check_configured(bld):
- if not Configure.autoconfig:
- return bld
-
- conf_cls = getattr(Utils.g_module, 'configure_context', Utils.Context)
- bld_cls = getattr(Utils.g_module, 'build_context', Utils.Context)
-
- def reconf(proj):
- back = (Options.commands, Options.options.__dict__, Logs.zones, Logs.verbose)
-
- Options.commands = proj['commands']
- Options.options.__dict__ = proj['options']
- conf = conf_cls()
- conf.environ = proj['environ']
- configure(conf)
-
- (Options.commands, Options.options.__dict__, Logs.zones, Logs.verbose) = back
-
- try:
- proj = Environment.Environment(Options.lockfile)
- except IOError:
- conf = conf_cls()
- configure(conf)
- else:
- try:
- bld = bld_cls()
- bld.load_dirs(proj[SRCDIR], proj[BLDDIR])
- bld.load_envs()
- except Utils.WafError:
- reconf(proj)
- return bld_cls()
-
- try:
- proj = Environment.Environment(Options.lockfile)
- except IOError:
- raise Utils.WafError('Auto-config: project does not configure (bug)')
-
- h = 0
- try:
- for file in proj['files']:
- if file.endswith('configure'):
- h = hash((h, Utils.readf(file)))
- else:
- mod = Utils.load_module(file)
- h = hash((h, mod.waf_hash_val))
- except (OSError, IOError):
- warn('Reconfiguring the project: a file is unavailable')
- reconf(proj)
- else:
- if (h != proj['hash']):
- warn('Reconfiguring the project: the configuration has changed')
- reconf(proj)
-
- return bld_cls()
-
-def install(bld):
- '''installs the build files'''
- bld = check_configured(bld)
-
- Options.commands['install'] = True
- Options.commands['uninstall'] = False
- Options.is_install = True
-
- bld.is_install = INSTALL
-
- build_impl(bld)
- bld.install()
-
-def uninstall(bld):
- '''removes the installed files'''
- Options.commands['install'] = False
- Options.commands['uninstall'] = True
- Options.is_install = True
-
- bld.is_install = UNINSTALL
-
- try:
- def runnable_status(self):
- return SKIP_ME
- setattr(Task.Task, 'runnable_status_back', Task.Task.runnable_status)
- setattr(Task.Task, 'runnable_status', runnable_status)
-
- build_impl(bld)
- bld.install()
- finally:
- setattr(Task.Task, 'runnable_status', Task.Task.runnable_status_back)
-
-def build(bld):
- bld = check_configured(bld)
-
- Options.commands['install'] = False
- Options.commands['uninstall'] = False
- Options.is_install = False
-
- bld.is_install = 0 # False
-
- return build_impl(bld)
-
-def build_impl(bld):
- # compile the project and/or install the files
- try:
- proj = Environment.Environment(Options.lockfile)
- except IOError:
- raise Utils.WafError("Project not configured (run 'waf configure' first)")
-
- bld.load_dirs(proj[SRCDIR], proj[BLDDIR])
- bld.load_envs()
-
- info("Waf: Entering directory `%s'" % bld.bldnode.abspath())
- bld.add_subdirs([os.path.split(Utils.g_module.root_path)[0]])
-
- # execute something immediately before the build starts
- bld.pre_build()
-
- try:
- bld.compile()
- finally:
- if Options.options.progress_bar: print('')
- info("Waf: Leaving directory `%s'" % bld.bldnode.abspath())
-
- # execute something immediately after a successful build
- bld.post_build()
-
- bld.install()
-
-excludes = '.bzr .bzrignore .git .gitignore .svn CVS .cvsignore .arch-ids {arch} SCCS BitKeeper .hg _MTN _darcs Makefile Makefile.in config.log .gitattributes .hgignore .hgtags'.split()
-dist_exts = '~ .rej .orig .pyc .pyo .bak .tar.bz2 tar.gz .zip .swp'.split()
-def dont_dist(name, src, build_dir):
- global excludes, dist_exts
-
- if (name.startswith(',,')
- or name.startswith('++')
- or name.startswith('.waf')
- or (src == '.' and name == Options.lockfile)
- or name in excludes
- or name == build_dir
- ):
- return True
-
- for ext in dist_exts:
- if name.endswith(ext):
- return True
-
- return False
-
-# like shutil.copytree
-# exclude files and to raise exceptions immediately
-def copytree(src, dst, build_dir):
- names = os.listdir(src)
- os.makedirs(dst)
- for name in names:
- srcname = os.path.join(src, name)
- dstname = os.path.join(dst, name)
-
- if dont_dist(name, src, build_dir):
- continue
-
- if os.path.isdir(srcname):
- copytree(srcname, dstname, build_dir)
- else:
- shutil.copy2(srcname, dstname)
-
-# TODO in waf 1.6, change this method if "srcdir == blddir" is allowed
-def distclean(ctx=None):
- '''removes the build directory'''
- global commands
- lst = os.listdir('.')
- for f in lst:
- if f == Options.lockfile:
- try:
- proj = Environment.Environment(f)
- except:
- Logs.warn('could not read %r' % f)
- continue
-
- try:
- shutil.rmtree(proj[BLDDIR])
- except IOError:
- pass
- except OSError, e:
- if e.errno != errno.ENOENT:
- Logs.warn('project %r cannot be removed' % proj[BLDDIR])
-
- try:
- os.remove(f)
- except OSError, e:
- if e.errno != errno.ENOENT:
- Logs.warn('file %r cannot be removed' % f)
-
- # remove the local waf cache
- if not commands and f.startswith('.waf'):
- shutil.rmtree(f, ignore_errors=True)
-
-# FIXME waf 1.6 a unique ctx parameter, and remove the optional appname and version
-def dist(appname='', version=''):
- '''makes a tarball for redistributing the sources'''
- # return return (distdirname, tarballname)
- import tarfile
-
- if not appname: appname = Utils.g_module.APPNAME
- if not version: version = Utils.g_module.VERSION
-
- tmp_folder = appname + '-' + version
- if g_gz in ['gz', 'bz2']:
- arch_name = tmp_folder + '.tar.' + g_gz
- else:
- arch_name = tmp_folder + '.' + 'zip'
-
- # remove the previous dir
- try:
- shutil.rmtree(tmp_folder)
- except (OSError, IOError):
- pass
-
- # remove the previous archive
- try:
- os.remove(arch_name)
- except (OSError, IOError):
- pass
-
- # copy the files into the temporary folder
- blddir = getattr(Utils.g_module, BLDDIR, None)
- if not blddir:
- blddir = getattr(Utils.g_module, 'out', None)
- copytree('.', tmp_folder, blddir)
-
- # undocumented hook for additional cleanup
- dist_hook = getattr(Utils.g_module, 'dist_hook', None)
- if dist_hook:
- back = os.getcwd()
- os.chdir(tmp_folder)
- try:
- dist_hook()
- finally:
- # go back to the root directory
- os.chdir(back)
-
- if g_gz in ['gz', 'bz2']:
- tar = tarfile.open(arch_name, 'w:' + g_gz)
- tar.add(tmp_folder)
- tar.close()
- else:
- Utils.zip_folder(tmp_folder, arch_name, tmp_folder)
-
- try: from hashlib import sha1 as sha
- except ImportError: from sha import sha
- try:
- digest = " (sha=%r)" % sha(Utils.readf(arch_name)).hexdigest()
- except:
- digest = ''
-
- info('New archive created: %s%s' % (arch_name, digest))
-
- if os.path.exists(tmp_folder): shutil.rmtree(tmp_folder)
- return arch_name
-
-# FIXME waf 1.6 a unique ctx parameter, and remove the optional appname and version
-def distcheck(appname='', version='', subdir=''):
- '''checks if the sources compile (tarball from 'dist')'''
- import tempfile, tarfile
-
- if not appname: appname = Utils.g_module.APPNAME
- if not version: version = Utils.g_module.VERSION
-
- waf = os.path.abspath(sys.argv[0])
- tarball = dist(appname, version)
-
- path = appname + '-' + version
-
- # remove any previous instance
- if os.path.exists(path):
- shutil.rmtree(path)
-
- t = tarfile.open(tarball)
- for x in t: t.extract(x)
- t.close()
-
- # build_path is the directory for the waf invocation
- if subdir:
- build_path = os.path.join(path, subdir)
- else:
- build_path = path
-
- instdir = tempfile.mkdtemp('.inst', '%s-%s' % (appname, version))
- ret = Utils.pproc.Popen([waf, 'configure', 'build', 'install', 'uninstall', '--destdir=' + instdir], cwd=build_path).wait()
- if ret:
- raise Utils.WafError('distcheck failed with code %i' % ret)
-
- if os.path.exists(instdir):
- raise Utils.WafError('distcheck succeeded, but files were left in %s' % instdir)
-
- shutil.rmtree(path)
-
-# FIXME remove in Waf 1.6 (kept for compatibility)
-def add_subdir(dir, bld):
- bld.recurse(dir, 'build')
-
diff --git a/tools/wafadmin/Task.py b/tools/wafadmin/Task.py
deleted file mode 100644
index 24edf2c36..000000000
--- a/tools/wafadmin/Task.py
+++ /dev/null
@@ -1,1171 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005-2008 (ita)
-
-"""
-Running tasks in parallel is a simple problem, but in practice it is more complicated:
-* dependencies discovered during the build (dynamic task creation)
-* dependencies discovered after files are compiled
-* the amount of tasks and dependencies (graph size) can be huge
-
-This is why the dependency management is split on three different levels:
-1. groups of tasks that run all after another group of tasks
-2. groups of tasks that can be run in parallel
-3. tasks that can run in parallel, but with possible unknown ad-hoc dependencies
-
-The point #1 represents a strict sequential order between groups of tasks, for example a compiler is produced
-and used to compile the rest, whereas #2 and #3 represent partial order constraints where #2 applies to the kind of task
-and #3 applies to the task instances.
-
-#1 is held by the task manager: ordered list of TaskGroups (see bld.add_group)
-#2 is held by the task groups and the task types: precedence after/before (topological sort),
- and the constraints extracted from file extensions
-#3 is held by the tasks individually (attribute run_after),
- and the scheduler (Runner.py) use Task::runnable_status to reorder the tasks
-
---
-
-To try, use something like this in your code:
-import Constants, Task
-Task.algotype = Constants.MAXPARALLEL
-
---
-
-There are two concepts with the tasks (individual units of change):
-* dependency (if 1 is recompiled, recompile 2)
-* order (run 2 after 1)
-
-example 1: if t1 depends on t2 and t2 depends on t3 it is not necessary to make t1 depend on t3 (dependency is transitive)
-example 2: if t1 depends on a node produced by t2, it is not immediately obvious that t1 must run after t2 (order is not obvious)
-
-The role of the Task Manager is to give the tasks in order (groups of task that may be run in parallel one after the other)
-
-"""
-
-import os, shutil, sys, re, random, datetime, tempfile, shlex
-from Utils import md5
-import Build, Runner, Utils, Node, Logs, Options
-from Logs import debug, warn, error
-from Constants import *
-
-algotype = NORMAL
-#algotype = JOBCONTROL
-#algotype = MAXPARALLEL
-
-COMPILE_TEMPLATE_SHELL = '''
-def f(task):
- env = task.env
- wd = getattr(task, 'cwd', None)
- p = env.get_flat
- cmd = \'\'\' %s \'\'\' % s
- return task.exec_command(cmd, cwd=wd)
-'''
-
-COMPILE_TEMPLATE_NOSHELL = '''
-def f(task):
- env = task.env
- wd = getattr(task, 'cwd', None)
- def to_list(xx):
- if isinstance(xx, str): return [xx]
- return xx
- lst = []
- %s
- lst = [x for x in lst if x]
- return task.exec_command(lst, cwd=wd)
-'''
-
-
-"""
-Enable different kind of dependency algorithms:
-1 make groups: first compile all cpps and then compile all links (NORMAL)
-2 parallelize all (each link task run after its dependencies) (MAXPARALLEL)
-3 like 1 but provide additional constraints for the parallelization (MAXJOBS)
-
-In theory 1. will be faster than 2 for waf, but might be slower for builds
-The scheme 2 will not allow for running tasks one by one so it can cause disk thrashing on huge builds
-"""
-
-file_deps = Utils.nada
-"""
-Additional dependency pre-check may be added by replacing the function file_deps.
-e.g. extract_outputs, extract_deps below.
-"""
-
-class TaskManager(object):
- """The manager is attached to the build object, it holds a list of TaskGroup"""
- def __init__(self):
- self.groups = []
- self.tasks_done = []
- self.current_group = 0
- self.groups_names = {}
-
- def get_next_set(self):
- """return the next set of tasks to execute
- the first parameter is the maximum amount of parallelization that may occur"""
- ret = None
- while not ret and self.current_group < len(self.groups):
- ret = self.groups[self.current_group].get_next_set()
- if ret: return ret
- else:
- self.groups[self.current_group].process_install()
- self.current_group += 1
- return (None, None)
-
- def add_group(self, name=None, set=True):
- #if self.groups and not self.groups[0].tasks:
- # error('add_group: an empty group is already present')
- g = TaskGroup()
-
- if name and name in self.groups_names:
- error('add_group: name %s already present' % name)
- self.groups_names[name] = g
- self.groups.append(g)
- if set:
- self.current_group = len(self.groups) - 1
-
- def set_group(self, idx):
- if isinstance(idx, str):
- g = self.groups_names[idx]
- for x in xrange(len(self.groups)):
- if id(g) == id(self.groups[x]):
- self.current_group = x
- else:
- self.current_group = idx
-
- def add_task_gen(self, tgen):
- if not self.groups: self.add_group()
- self.groups[self.current_group].tasks_gen.append(tgen)
-
- def add_task(self, task):
- if not self.groups: self.add_group()
- self.groups[self.current_group].tasks.append(task)
-
- def total(self):
- total = 0
- if not self.groups: return 0
- for group in self.groups:
- total += len(group.tasks)
- return total
-
- def add_finished(self, tsk):
- self.tasks_done.append(tsk)
- bld = tsk.generator.bld
- if bld.is_install:
- f = None
- if 'install' in tsk.__dict__:
- f = tsk.__dict__['install']
- # install=0 to prevent installation
- if f: f(tsk)
- else:
- tsk.install()
-
-class TaskGroup(object):
- "the compilation of one group does not begin until the previous group has finished (in the manager)"
- def __init__(self):
- self.tasks = [] # this list will be consumed
- self.tasks_gen = []
-
- self.cstr_groups = Utils.DefaultDict(list) # tasks having equivalent constraints
- self.cstr_order = Utils.DefaultDict(set) # partial order between the cstr groups
- self.temp_tasks = [] # tasks put on hold
- self.ready = 0
- self.post_funs = []
-
- def reset(self):
- "clears the state of the object (put back the tasks into self.tasks)"
- for x in self.cstr_groups:
- self.tasks += self.cstr_groups[x]
- self.tasks = self.temp_tasks + self.tasks
- self.temp_tasks = []
- self.cstr_groups = Utils.DefaultDict(list)
- self.cstr_order = Utils.DefaultDict(set)
- self.ready = 0
-
- def process_install(self):
- for (f, k, kw) in self.post_funs:
- f(*k, **kw)
-
- def prepare(self):
- "prepare the scheduling"
- self.ready = 1
- file_deps(self.tasks)
- self.make_cstr_groups()
- self.extract_constraints()
-
- def get_next_set(self):
- "next list of tasks to execute using max job settings, returns (maxjobs, task_list)"
- global algotype
- if algotype == NORMAL:
- tasks = self.tasks_in_parallel()
- maxj = MAXJOBS
- elif algotype == JOBCONTROL:
- (maxj, tasks) = self.tasks_by_max_jobs()
- elif algotype == MAXPARALLEL:
- tasks = self.tasks_with_inner_constraints()
- maxj = MAXJOBS
- else:
- raise Utils.WafError("unknown algorithm type %s" % (algotype))
-
- if not tasks: return ()
- return (maxj, tasks)
-
- def make_cstr_groups(self):
- "unite the tasks that have similar constraints"
- self.cstr_groups = Utils.DefaultDict(list)
- for x in self.tasks:
- h = x.hash_constraints()
- self.cstr_groups[h].append(x)
-
- def set_order(self, a, b):
- self.cstr_order[a].add(b)
-
- def compare_exts(self, t1, t2):
- "extension production"
- x = "ext_in"
- y = "ext_out"
- in_ = t1.attr(x, ())
- out_ = t2.attr(y, ())
- for k in in_:
- if k in out_:
- return -1
- in_ = t2.attr(x, ())
- out_ = t1.attr(y, ())
- for k in in_:
- if k in out_:
- return 1
- return 0
-
- def compare_partial(self, t1, t2):
- "partial relations after/before"
- m = "after"
- n = "before"
- name = t2.__class__.__name__
- if name in Utils.to_list(t1.attr(m, ())): return -1
- elif name in Utils.to_list(t1.attr(n, ())): return 1
- name = t1.__class__.__name__
- if name in Utils.to_list(t2.attr(m, ())): return 1
- elif name in Utils.to_list(t2.attr(n, ())): return -1
- return 0
-
- def extract_constraints(self):
- "extract the parallelization constraints from the tasks with different constraints"
- keys = self.cstr_groups.keys()
- max = len(keys)
- # hopefully the length of this list is short
- for i in xrange(max):
- t1 = self.cstr_groups[keys[i]][0]
- for j in xrange(i + 1, max):
- t2 = self.cstr_groups[keys[j]][0]
-
- # add the constraints based on the comparisons
- val = (self.compare_exts(t1, t2)
- or self.compare_partial(t1, t2)
- )
- if val > 0:
- self.set_order(keys[i], keys[j])
- elif val < 0:
- self.set_order(keys[j], keys[i])
-
- def tasks_in_parallel(self):
- "(NORMAL) next list of tasks that may be executed in parallel"
-
- if not self.ready: self.prepare()
-
- keys = self.cstr_groups.keys()
-
- unconnected = []
- remainder = []
-
- for u in keys:
- for k in self.cstr_order.values():
- if u in k:
- remainder.append(u)
- break
- else:
- unconnected.append(u)
-
- toreturn = []
- for y in unconnected:
- toreturn.extend(self.cstr_groups[y])
-
- # remove stuff only after
- for y in unconnected:
- try: self.cstr_order.__delitem__(y)
- except KeyError: pass
- self.cstr_groups.__delitem__(y)
-
- if not toreturn and remainder:
- raise Utils.WafError("circular order constraint detected %r" % remainder)
-
- return toreturn
-
- def tasks_by_max_jobs(self):
- "(JOBCONTROL) returns the tasks that can run in parallel with the max amount of jobs"
- if not self.ready: self.prepare()
- if not self.temp_tasks: self.temp_tasks = self.tasks_in_parallel()
- if not self.temp_tasks: return (None, None)
-
- maxjobs = MAXJOBS
- ret = []
- remaining = []
- for t in self.temp_tasks:
- m = getattr(t, "maxjobs", getattr(self.__class__, "maxjobs", MAXJOBS))
- if m > maxjobs:
- remaining.append(t)
- elif m < maxjobs:
- remaining += ret
- ret = [t]
- maxjobs = m
- else:
- ret.append(t)
- self.temp_tasks = remaining
- return (maxjobs, ret)
-
- def tasks_with_inner_constraints(self):
- """(MAXPARALLEL) returns all tasks in this group, but add the constraints on each task instance
- as an optimization, it might be desirable to discard the tasks which do not have to run"""
- if not self.ready: self.prepare()
-
- if getattr(self, "done", None): return None
-
- for p in self.cstr_order:
- for v in self.cstr_order[p]:
- for m in self.cstr_groups[p]:
- for n in self.cstr_groups[v]:
- n.set_run_after(m)
- self.cstr_order = Utils.DefaultDict(set)
- self.cstr_groups = Utils.DefaultDict(list)
- self.done = 1
- return self.tasks[:] # make a copy
-
-class store_task_type(type):
- "store the task types that have a name ending in _task into a map (remember the existing task types)"
- def __init__(cls, name, bases, dict):
- super(store_task_type, cls).__init__(name, bases, dict)
- name = cls.__name__
-
- if name.endswith('_task'):
- name = name.replace('_task', '')
- if name != 'TaskBase':
- TaskBase.classes[name] = cls
-
-class TaskBase(object):
- """Base class for all Waf tasks
-
- The most important methods are (by usual order of call):
- 1 runnable_status: ask the task if it should be run, skipped, or if we have to ask later
- 2 __str__: string to display to the user
- 3 run: execute the task
- 4 post_run: after the task is run, update the cache about the task
-
- This class should be seen as an interface, it provides the very minimum necessary for the scheduler
- so it does not do much.
-
- For illustration purposes, TaskBase instances try to execute self.fun (if provided)
- """
-
- __metaclass__ = store_task_type
-
- color = "GREEN"
- maxjobs = MAXJOBS
- classes = {}
- stat = None
-
- def __init__(self, *k, **kw):
- self.hasrun = NOT_RUN
-
- try:
- self.generator = kw['generator']
- except KeyError:
- self.generator = self
- self.bld = Build.bld
-
- if kw.get('normal', 1):
- self.generator.bld.task_manager.add_task(self)
-
- def __repr__(self):
- "used for debugging"
- return '\n\t{task: %s %s}' % (self.__class__.__name__, str(getattr(self, "fun", "")))
-
- def __str__(self):
- "string to display to the user"
- if hasattr(self, 'fun'):
- return 'executing: %s\n' % self.fun.__name__
- return self.__class__.__name__ + '\n'
-
- def exec_command(self, *k, **kw):
- "use this for executing commands from tasks"
- # TODO in waf 1.6, eliminate bld.exec_command, and move the cwd processing to here
- if self.env['env']:
- kw['env'] = self.env['env']
- return self.generator.bld.exec_command(*k, **kw)
-
- def runnable_status(self):
- "RUN_ME SKIP_ME or ASK_LATER"
- return RUN_ME
-
- def can_retrieve_cache(self):
- return False
-
- def call_run(self):
- if self.can_retrieve_cache():
- return 0
- return self.run()
-
- def run(self):
- "called if the task must run"
- if hasattr(self, 'fun'):
- return self.fun(self)
- return 0
-
- def post_run(self):
- "update the dependency tree (node stats)"
- pass
-
- def display(self):
- "print either the description (using __str__) or the progress bar or the ide output"
- col1 = Logs.colors(self.color)
- col2 = Logs.colors.NORMAL
-
- if Options.options.progress_bar == 1:
- return self.generator.bld.progress_line(self.position[0], self.position[1], col1, col2)
-
- if Options.options.progress_bar == 2:
- ela = Utils.get_elapsed_time(self.generator.bld.ini)
- try:
- ins = ','.join([n.name for n in self.inputs])
- except AttributeError:
- ins = ''
- try:
- outs = ','.join([n.name for n in self.outputs])
- except AttributeError:
- outs = ''
- return '|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n' % (self.position[1], self.position[0], ins, outs, ela)
-
- total = self.position[1]
- n = len(str(total))
- fs = '[%%%dd/%%%dd] %%s%%s%%s' % (n, n)
- return fs % (self.position[0], self.position[1], col1, str(self), col2)
-
- def attr(self, att, default=None):
- "retrieve an attribute from the instance or from the class (microoptimization here)"
- ret = getattr(self, att, self)
- if ret is self: return getattr(self.__class__, att, default)
- return ret
-
- def hash_constraints(self):
- "identify a task type for all the constraints relevant for the scheduler: precedence, file production"
- a = self.attr
- sum = hash((self.__class__.__name__,
- str(a('before', '')),
- str(a('after', '')),
- str(a('ext_in', '')),
- str(a('ext_out', '')),
- self.__class__.maxjobs))
- return sum
-
- def format_error(self):
- "error message to display to the user (when a build fails)"
- if getattr(self, "err_msg", None):
- return self.err_msg
- elif self.hasrun == CRASHED:
- try:
- return " -> task failed (err #%d): %r" % (self.err_code, self)
- except AttributeError:
- return " -> task failed: %r" % self
- elif self.hasrun == MISSING:
- return " -> missing files: %r" % self
- else:
- return ''
-
- def install(self):
- """
- installation is performed by looking at the task attributes:
- * install_path: installation path like "${PREFIX}/bin"
- * filename: install the first node in the outputs as a file with a particular name, be certain to give os.sep
- * chmod: permissions
- """
- bld = self.generator.bld
- d = self.attr('install')
-
- if self.attr('install_path'):
- lst = [a.relpath_gen(bld.srcnode) for a in self.outputs]
- perm = self.attr('chmod', O644)
- if self.attr('src'):
- # if src is given, install the sources too
- lst += [a.relpath_gen(bld.srcnode) for a in self.inputs]
- if self.attr('filename'):
- dir = self.install_path.rstrip(os.sep) + os.sep + self.attr('filename')
- bld.install_as(dir, lst[0], self.env, perm)
- else:
- bld.install_files(self.install_path, lst, self.env, perm)
-
-class Task(TaskBase):
- """The parent class is quite limited, in this version:
- * file system interaction: input and output nodes
- * persistence: do not re-execute tasks that have already run
- * caching: same files can be saved and retrieved from a cache directory
- * dependencies:
- implicit, like .c files depending on .h files
- explicit, like the input nodes or the dep_nodes
- environment variables, like the CXXFLAGS in self.env
- """
- vars = []
- def __init__(self, env, **kw):
- TaskBase.__init__(self, **kw)
- self.env = env
-
- # inputs and outputs are nodes
- # use setters when possible
- self.inputs = []
- self.outputs = []
-
- self.deps_nodes = []
- self.run_after = []
-
- # Additionally, you may define the following
- #self.dep_vars = 'PREFIX DATADIR'
-
- def __str__(self):
- "string to display to the user"
- env = self.env
- src_str = ' '.join([a.nice_path(env) for a in self.inputs])
- tgt_str = ' '.join([a.nice_path(env) for a in self.outputs])
- if self.outputs: sep = ' -> '
- else: sep = ''
- return '%s: %s%s%s\n' % (self.__class__.__name__.replace('_task', ''), src_str, sep, tgt_str)
-
- def __repr__(self):
- return "".join(['\n\t{task: ', self.__class__.__name__, " ", ",".join([x.name for x in self.inputs]), " -> ", ",".join([x.name for x in self.outputs]), '}'])
-
- def unique_id(self):
- "get a unique id: hash the node paths, the variant, the class, the function"
- try:
- return self.uid
- except AttributeError:
- "this is not a real hot zone, but we want to avoid surprizes here"
- m = md5()
- up = m.update
- up(self.__class__.__name__)
- up(self.env.variant())
- p = None
- for x in self.inputs + self.outputs:
- if p != x.parent.id:
- p = x.parent.id
- up(x.parent.abspath())
- up(x.name)
- self.uid = m.digest()
- return self.uid
-
- def set_inputs(self, inp):
- if isinstance(inp, list): self.inputs += inp
- else: self.inputs.append(inp)
-
- def set_outputs(self, out):
- if isinstance(out, list): self.outputs += out
- else: self.outputs.append(out)
-
- def set_run_after(self, task):
- "set (scheduler) order on another task"
- # TODO: handle list or object
- assert isinstance(task, TaskBase)
- self.run_after.append(task)
-
- def add_file_dependency(self, filename):
- "TODO user-provided file dependencies"
- node = self.generator.bld.path.find_resource(filename)
- self.deps_nodes.append(node)
-
- def signature(self):
- # compute the result one time, and suppose the scan_signature will give the good result
- try: return self.cache_sig[0]
- except AttributeError: pass
-
- self.m = md5()
-
- # explicit deps
- exp_sig = self.sig_explicit_deps()
-
- # env vars
- var_sig = self.sig_vars()
-
- # implicit deps
-
- imp_sig = SIG_NIL
- if self.scan:
- try:
- imp_sig = self.sig_implicit_deps()
- except ValueError:
- return self.signature()
-
- # we now have the signature (first element) and the details (for debugging)
- ret = self.m.digest()
- self.cache_sig = (ret, exp_sig, imp_sig, var_sig)
- return ret
-
- def runnable_status(self):
- "SKIP_ME RUN_ME or ASK_LATER"
- #return 0 # benchmarking
-
- if self.inputs and (not self.outputs):
- if not getattr(self.__class__, 'quiet', None):
- warn("invalid task (no inputs OR outputs): override in a Task subclass or set the attribute 'quiet' %r" % self)
-
- for t in self.run_after:
- if not t.hasrun:
- return ASK_LATER
-
- env = self.env
- bld = self.generator.bld
-
- # first compute the signature
- new_sig = self.signature()
-
- # compare the signature to a signature computed previously
- key = self.unique_id()
- try:
- prev_sig = bld.task_sigs[key][0]
- except KeyError:
- debug("task: task %r must run as it was never run before or the task code changed", self)
- return RUN_ME
-
- # compare the signatures of the outputs
- for node in self.outputs:
- variant = node.variant(env)
- try:
- if bld.node_sigs[variant][node.id] != new_sig:
- return RUN_ME
- except KeyError:
- debug("task: task %r must run as the output nodes do not exist", self)
- return RUN_ME
-
- # debug if asked to
- if Logs.verbose: self.debug_why(bld.task_sigs[key])
-
- if new_sig != prev_sig:
- return RUN_ME
- return SKIP_ME
-
- def post_run(self):
- "called after a successful task run"
- bld = self.generator.bld
- env = self.env
- sig = self.signature()
- ssig = sig.encode('hex')
-
- variant = env.variant()
- for node in self.outputs:
- # check if the node exists ..
- try:
- os.stat(node.abspath(env))
- except OSError:
- self.hasrun = MISSING
- self.err_msg = '-> missing file: %r' % node.abspath(env)
- raise Utils.WafError
-
- # important, store the signature for the next run
- bld.node_sigs[variant][node.id] = sig
- bld.task_sigs[self.unique_id()] = self.cache_sig
-
- # file caching, if possible
- # try to avoid data corruption as much as possible
- if not Options.cache_global or Options.options.nocache or not self.outputs:
- return None
-
- if getattr(self, 'cached', None):
- return None
-
- dname = os.path.join(Options.cache_global, ssig)
- tmpdir = tempfile.mkdtemp(prefix=Options.cache_global)
-
- try:
- shutil.rmtree(dname)
- except:
- pass
-
- try:
- for node in self.outputs:
- variant = node.variant(env)
- dest = os.path.join(tmpdir, node.name)
- shutil.copy2(node.abspath(env), dest)
- except (OSError, IOError):
- try:
- shutil.rmtree(tmpdir)
- except:
- pass
- else:
- try:
- os.rename(tmpdir, dname)
- except OSError:
- try:
- shutil.rmtree(tmpdir)
- except:
- pass
- else:
- try:
- os.chmod(dname, O755)
- except:
- pass
-
- def can_retrieve_cache(self):
- """
- Retrieve build nodes from the cache
- update the file timestamps to help cleaning the least used entries from the cache
- additionally, set an attribute 'cached' to avoid re-creating the same cache files
-
- suppose there are files in cache/dir1/file1 and cache/dir2/file2
- first, read the timestamp of dir1
- then try to copy the files
- then look at the timestamp again, if it has changed, the data may have been corrupt (cache update by another process)
- should an exception occur, ignore the data
- """
- if not Options.cache_global or Options.options.nocache or not self.outputs:
- return None
-
- env = self.env
- sig = self.signature()
- ssig = sig.encode('hex')
-
- # first try to access the cache folder for the task
- dname = os.path.join(Options.cache_global, ssig)
- try:
- t1 = os.stat(dname).st_mtime
- except OSError:
- return None
-
- for node in self.outputs:
- variant = node.variant(env)
-
- orig = os.path.join(dname, node.name)
- try:
- shutil.copy2(orig, node.abspath(env))
- # mark the cache file as used recently (modified)
- os.utime(orig, None)
- except (OSError, IOError):
- debug('task: failed retrieving file')
- return None
-
- # is it the same folder?
- try:
- t2 = os.stat(dname).st_mtime
- except OSError:
- return None
-
- if t1 != t2:
- return None
-
- for node in self.outputs:
- self.generator.bld.node_sigs[variant][node.id] = sig
- if Options.options.progress_bar < 1:
- self.generator.bld.printout('restoring from cache %r\n' % node.bldpath(env))
-
- self.cached = True
- return 1
-
- def debug_why(self, old_sigs):
- "explains why a task is run"
-
- new_sigs = self.cache_sig
- def v(x):
- return x.encode('hex')
-
- debug("Task %r", self)
- msgs = ['Task must run', '* Source file or manual dependency', '* Implicit dependency', '* Environment variable']
- tmp = 'task: -> %s: %s %s'
- for x in xrange(len(msgs)):
- if (new_sigs[x] != old_sigs[x]):
- debug(tmp, msgs[x], v(old_sigs[x]), v(new_sigs[x]))
-
- def sig_explicit_deps(self):
- bld = self.generator.bld
- up = self.m.update
-
- # the inputs
- for x in self.inputs + getattr(self, 'dep_nodes', []):
- if not x.parent.id in bld.cache_scanned_folders:
- bld.rescan(x.parent)
-
- variant = x.variant(self.env)
- try:
- up(bld.node_sigs[variant][x.id])
- except KeyError:
- raise Utils.WafError('Missing node signature for %r (required by %r)' % (x, self))
-
- # manual dependencies, they can slow down the builds
- if bld.deps_man:
- additional_deps = bld.deps_man
- for x in self.inputs + self.outputs:
- try:
- d = additional_deps[x.id]
- except KeyError:
- continue
-
- for v in d:
- if isinstance(v, Node.Node):
- bld.rescan(v.parent)
- variant = v.variant(self.env)
- try:
- v = bld.node_sigs[variant][v.id]
- except KeyError:
- raise Utils.WafError('Missing node signature for %r (required by %r)' % (v, self))
- elif hasattr(v, '__call__'):
- v = v() # dependency is a function, call it
- up(v)
-
- for x in self.deps_nodes:
- v = bld.node_sigs[x.variant(self.env)][x.id]
- up(v)
-
- return self.m.digest()
-
- def sig_vars(self):
- bld = self.generator.bld
- env = self.env
-
- # dependencies on the environment vars
- act_sig = bld.hash_env_vars(env, self.__class__.vars)
- self.m.update(act_sig)
-
- # additional variable dependencies, if provided
- dep_vars = getattr(self, 'dep_vars', None)
- if dep_vars:
- self.m.update(bld.hash_env_vars(env, dep_vars))
-
- return self.m.digest()
-
- #def scan(self, node):
- # """this method returns a tuple containing:
- # * a list of nodes corresponding to real files
- # * a list of names for files not found in path_lst
- # the input parameters may have more parameters that the ones used below
- # """
- # return ((), ())
- scan = None
-
- # compute the signature, recompute it if there is no match in the cache
- def sig_implicit_deps(self):
- "the signature obtained may not be the one if the files have changed, we do it in two steps"
-
- bld = self.generator.bld
-
- # get the task signatures from previous runs
- key = self.unique_id()
- prev_sigs = bld.task_sigs.get(key, ())
- if prev_sigs:
- try:
- # for issue #379
- if prev_sigs[2] == self.compute_sig_implicit_deps():
- return prev_sigs[2]
- except (KeyError, OSError):
- pass
- del bld.task_sigs[key]
- raise ValueError('rescan')
-
- # no previous run or the signature of the dependencies has changed, rescan the dependencies
- (nodes, names) = self.scan()
- if Logs.verbose:
- debug('deps: scanner for %s returned %s %s', str(self), str(nodes), str(names))
-
- # store the dependencies in the cache
- bld.node_deps[key] = nodes
- bld.raw_deps[key] = names
-
- # recompute the signature and return it
- try:
- sig = self.compute_sig_implicit_deps()
- except KeyError:
- try:
- nodes = []
- for k in bld.node_deps.get(self.unique_id(), []):
- if k.id & 3 == 2: # Node.FILE:
- if not k.id in bld.node_sigs[0]:
- nodes.append(k)
- else:
- if not k.id in bld.node_sigs[self.env.variant()]:
- nodes.append(k)
- except:
- nodes = '?'
- raise Utils.WafError('Missing node signature for %r (for implicit dependencies %r)' % (nodes, self))
-
- return sig
-
- def compute_sig_implicit_deps(self):
- """it is intended for .cpp and inferred .h files
- there is a single list (no tree traversal)
- this is the hot spot so ... do not touch"""
- upd = self.m.update
-
- bld = self.generator.bld
- tstamp = bld.node_sigs
- env = self.env
-
- for k in bld.node_deps.get(self.unique_id(), []):
- # unlikely but necessary if it happens
- if not k.parent.id in bld.cache_scanned_folders:
- # if the parent folder is removed, an OSError may be thrown
- bld.rescan(k.parent)
-
- # if the parent folder is removed, a KeyError will be thrown
- if k.id & 3 == 2: # Node.FILE:
- upd(tstamp[0][k.id])
- else:
- upd(tstamp[env.variant()][k.id])
-
- return self.m.digest()
-
-def funex(c):
- dc = {}
- exec(c, dc)
- return dc['f']
-
-reg_act = re.compile(r"(?P<backslash>\\)|(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})", re.M)
-def compile_fun_shell(name, line):
- """Compiles a string (once) into a function, eg:
- simple_task_type('c++', '${CXX} -o ${TGT[0]} ${SRC} -I ${SRC[0].parent.bldpath()}')
-
- The env variables (CXX, ..) on the task must not hold dicts (order)
- The reserved keywords TGT and SRC represent the task input and output nodes
-
- quick test:
- bld(source='wscript', rule='echo "foo\\${SRC[0].name}\\bar"')
- """
-
- extr = []
- def repl(match):
- g = match.group
- if g('dollar'): return "$"
- elif g('backslash'): return '\\\\'
- elif g('subst'): extr.append((g('var'), g('code'))); return "%s"
- return None
-
- line = reg_act.sub(repl, line)
-
- parm = []
- dvars = []
- app = parm.append
- for (var, meth) in extr:
- if var == 'SRC':
- if meth: app('task.inputs%s' % meth)
- else: app('" ".join([a.srcpath(env) for a in task.inputs])')
- elif var == 'TGT':
- if meth: app('task.outputs%s' % meth)
- else: app('" ".join([a.bldpath(env) for a in task.outputs])')
- else:
- if not var in dvars: dvars.append(var)
- app("p('%s')" % var)
- if parm: parm = "%% (%s) " % (',\n\t\t'.join(parm))
- else: parm = ''
-
- c = COMPILE_TEMPLATE_SHELL % (line, parm)
-
- debug('action: %s', c)
- return (funex(c), dvars)
-
-def compile_fun_noshell(name, line):
-
- extr = []
- def repl(match):
- g = match.group
- if g('dollar'): return "$"
- elif g('subst'): extr.append((g('var'), g('code'))); return "<<|@|>>"
- return None
-
- line2 = reg_act.sub(repl, line)
- params = line2.split('<<|@|>>')
-
- buf = []
- dvars = []
- app = buf.append
- for x in xrange(len(extr)):
- params[x] = params[x].strip()
- if params[x]:
- app("lst.extend(%r)" % params[x].split())
- (var, meth) = extr[x]
- if var == 'SRC':
- if meth: app('lst.append(task.inputs%s)' % meth)
- else: app("lst.extend([a.srcpath(env) for a in task.inputs])")
- elif var == 'TGT':
- if meth: app('lst.append(task.outputs%s)' % meth)
- else: app("lst.extend([a.bldpath(env) for a in task.outputs])")
- else:
- app('lst.extend(to_list(env[%r]))' % var)
- if not var in dvars: dvars.append(var)
-
- if params[-1]:
- app("lst.extend(%r)" % shlex.split(params[-1]))
-
- fun = COMPILE_TEMPLATE_NOSHELL % "\n\t".join(buf)
- debug('action: %s', fun)
- return (funex(fun), dvars)
-
-def compile_fun(name, line, shell=None):
- "commands can be launched by the shell or not"
- if line.find('<') > 0 or line.find('>') > 0 or line.find('&&') > 0:
- shell = True
- #else:
- # shell = False
-
- if shell is None:
- if sys.platform == 'win32':
- shell = False
- else:
- shell = True
-
- if shell:
- return compile_fun_shell(name, line)
- else:
- return compile_fun_noshell(name, line)
-
-def simple_task_type(name, line, color='GREEN', vars=[], ext_in=[], ext_out=[], before=[], after=[], shell=None):
- """return a new Task subclass with the function run compiled from the line given"""
- (fun, dvars) = compile_fun(name, line, shell)
- fun.code = line
- return task_type_from_func(name, fun, vars or dvars, color, ext_in, ext_out, before, after)
-
-def task_type_from_func(name, func, vars=[], color='GREEN', ext_in=[], ext_out=[], before=[], after=[]):
- """return a new Task subclass with the function run compiled from the line given"""
- params = {
- 'run': func,
- 'vars': vars,
- 'color': color,
- 'name': name,
- 'ext_in': Utils.to_list(ext_in),
- 'ext_out': Utils.to_list(ext_out),
- 'before': Utils.to_list(before),
- 'after': Utils.to_list(after),
- }
-
- cls = type(Task)(name, (Task,), params)
- TaskBase.classes[name] = cls
- return cls
-
-def always_run(cls):
- """Set all task instances of this class to be executed whenever a build is started
- The task signature is calculated, but the result of the comparation between
- task signatures is bypassed
- """
- old = cls.runnable_status
- def always(self):
- old(self)
- return RUN_ME
- cls.runnable_status = always
-
-def update_outputs(cls):
- """When a command is always run, it is possible that the output only change
- sometimes. By default the build node have as a hash the signature of the task
- which may not change. With this, the output nodes (produced) are hashed,
- and the hashes are set to the build nodes
-
- This may avoid unnecessary recompilations, but it uses more resources
- (hashing the output files) so it is not used by default
- """
- old_post_run = cls.post_run
- def post_run(self):
- old_post_run(self)
- bld = self.outputs[0].__class__.bld
- for output in self.outputs:
- bld.node_sigs[self.env.variant()][output.id] = Utils.h_file(output.abspath(self.env))
- cls.post_run = post_run
-
- old_runnable_status = cls.runnable_status
- def runnable_status(self):
- status = old_runnable_status(self)
- if status != RUN_ME:
- return status
-
- try:
- bld = self.outputs[0].__class__.bld
- new_sig = self.signature()
- prev_sig = bld.task_sigs[self.unique_id()][0]
- if prev_sig == new_sig:
- for x in self.outputs:
- if not x.id in bld.node_sigs[self.env.variant()]:
- return RUN_ME
- return SKIP_ME
- except KeyError:
- pass
- except IndexError:
- pass
- return RUN_ME
- cls.runnable_status = runnable_status
-
-def extract_outputs(tasks):
- """file_deps: Infer additional dependencies from task input and output nodes
- """
- v = {}
- for x in tasks:
- try:
- (ins, outs) = v[x.env.variant()]
- except KeyError:
- ins = {}
- outs = {}
- v[x.env.variant()] = (ins, outs)
-
- for a in getattr(x, 'inputs', []):
- try: ins[a.id].append(x)
- except KeyError: ins[a.id] = [x]
- for a in getattr(x, 'outputs', []):
- try: outs[a.id].append(x)
- except KeyError: outs[a.id] = [x]
-
- for (ins, outs) in v.values():
- links = set(ins.iterkeys()).intersection(outs.iterkeys())
- for k in links:
- for a in ins[k]:
- for b in outs[k]:
- a.set_run_after(b)
-
-def extract_deps(tasks):
- """file_deps: Infer additional dependencies from task input and output nodes and from implicit dependencies
- returned by the scanners - that will only work if all tasks are created
-
- this is aimed at people who have pathological builds and who do not care enough
- to implement the build dependencies properly
-
- with two loops over the list of tasks, do not expect this to be really fast
- """
-
- # first reuse the function above
- extract_outputs(tasks)
-
- # map the output nodes to the tasks producing them
- out_to_task = {}
- for x in tasks:
- v = x.env.variant()
- try:
- lst = x.outputs
- except AttributeError:
- pass
- else:
- for node in lst:
- out_to_task[(v, node.id)] = x
-
- # map the dependencies found to the tasks compiled
- dep_to_task = {}
- for x in tasks:
- try:
- x.signature()
- except: # this is on purpose
- pass
-
- v = x.env.variant()
- key = x.unique_id()
- for k in x.generator.bld.node_deps.get(x.unique_id(), []):
- try: dep_to_task[(v, k.id)].append(x)
- except KeyError: dep_to_task[(v, k.id)] = [x]
-
- # now get the intersection
- deps = set(dep_to_task.keys()).intersection(set(out_to_task.keys()))
-
- # and add the dependencies from task to task
- for idx in deps:
- for k in dep_to_task[idx]:
- k.set_run_after(out_to_task[idx])
-
- # cleanup, remove the signatures
- for x in tasks:
- try:
- delattr(x, 'cache_sig')
- except AttributeError:
- pass
-
diff --git a/tools/wafadmin/TaskGen.py b/tools/wafadmin/TaskGen.py
deleted file mode 100644
index 260d99930..000000000
--- a/tools/wafadmin/TaskGen.py
+++ /dev/null
@@ -1,588 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005-2008 (ita)
-
-"""
-The class task_gen encapsulates the creation of task objects (low-level code)
-The instances can have various parameters, but the creation of task nodes (Task.py)
-is delayed. To achieve this, various methods are called from the method "apply"
-
-The class task_gen contains lots of methods, and a configuration table:
-* the methods to call (self.meths) can be specified dynamically (removing, adding, ..)
-* the order of the methods (self.prec or by default task_gen.prec) is configurable
-* new methods can be inserted dynamically without pasting old code
-
-Additionally, task_gen provides the method apply_core
-* file extensions are mapped to methods: def meth(self, name_or_node)
-* if a mapping is not found in self.mappings, it is searched in task_gen.mappings
-* when called, the functions may modify self.allnodes to re-add source to process
-* the mappings can map an extension or a filename (see the code below)
-
-WARNING: subclasses must reimplement the clone method
-"""
-
-import os, traceback, copy
-import Build, Task, Utils, Logs, Options
-from Logs import debug, error, warn
-from Constants import *
-
-typos = {
-'sources':'source',
-'targets':'target',
-'include':'includes',
-'define':'defines',
-'importpath':'importpaths',
-'install_var':'install_path',
-'install_subdir':'install_path',
-'inst_var':'install_path',
-'inst_dir':'install_path',
-'feature':'features',
-}
-
-class register_obj(type):
- """no decorators for classes, so we use a metaclass
- we store into task_gen.classes the classes that inherit task_gen
- and whose names end in '_taskgen'
- """
- def __init__(cls, name, bases, dict):
- super(register_obj, cls).__init__(name, bases, dict)
- name = cls.__name__
- suffix = '_taskgen'
- if name.endswith(suffix):
- task_gen.classes[name.replace(suffix, '')] = cls
-
-class task_gen(object):
- """
- Most methods are of the form 'def meth(self):' without any parameters
- there are many of them, and they do many different things:
- * task creation
- * task results installation
- * environment modification
- * attribute addition/removal
-
- The inheritance approach is complicated
- * mixing several languages at once
- * subclassing is needed even for small changes
- * inserting new methods is complicated
-
- This new class uses a configuration table:
- * adding new methods easily
- * obtaining the order in which to call the methods
- * postponing the method calls (post() -> apply)
-
- Additionally, a 'traits' static attribute is provided:
- * this list contains methods
- * the methods can remove or add methods from self.meths
- Example1: the attribute 'staticlib' is set on an instance
- a method set in the list of traits is executed when the
- instance is posted, it finds that flag and adds another method for execution
- Example2: a method set in the list of traits finds the msvc
- compiler (from self.env['MSVC']==1); more methods are added to self.meths
- """
-
- __metaclass__ = register_obj
- mappings = {}
- mapped = {}
- prec = Utils.DefaultDict(list)
- traits = Utils.DefaultDict(set)
- classes = {}
-
- def __init__(self, *kw, **kwargs):
- self.prec = Utils.DefaultDict(list)
- "map precedence of function names to call"
- # so we will have to play with directed acyclic graphs
- # detect cycles, etc
-
- self.source = ''
- self.target = ''
-
- # list of methods to execute - does not touch it by hand unless you know
- self.meths = []
-
- # list of mappings extension -> function
- self.mappings = {}
-
- # list of features (see the documentation on traits)
- self.features = list(kw)
-
- # not always a good idea
- self.tasks = []
-
- self.default_chmod = O644
- self.default_install_path = None
-
- # kind of private, beware of what you put in it, also, the contents are consumed
- self.allnodes = []
-
- self.bld = kwargs.get('bld', Build.bld)
- self.env = self.bld.env.copy()
-
- self.path = self.bld.path # emulate chdir when reading scripts
- self.name = '' # give a name to the target (static+shlib with the same targetname ambiguity)
-
- # provide a unique id
- self.idx = self.bld.idx[self.path.id] = self.bld.idx.get(self.path.id, 0) + 1
-
- for key, val in kwargs.iteritems():
- setattr(self, key, val)
-
- self.bld.task_manager.add_task_gen(self)
- self.bld.all_task_gen.append(self)
-
- def __str__(self):
- return ("<task_gen '%s' of type %s defined in %s>"
- % (self.name or self.target, self.__class__.__name__, str(self.path)))
-
- def __setattr__(self, name, attr):
- real = typos.get(name, name)
- if real != name:
- warn('typo %s -> %s' % (name, real))
- if Logs.verbose > 0:
- traceback.print_stack()
- object.__setattr__(self, real, attr)
-
- def to_list(self, value):
- "helper: returns a list"
- if isinstance(value, str): return value.split()
- else: return value
-
- def apply(self):
- "order the methods to execute using self.prec or task_gen.prec"
- keys = set(self.meths)
-
- # add the methods listed in the features
- self.features = Utils.to_list(self.features)
- for x in self.features + ['*']:
- st = task_gen.traits[x]
- if not st:
- warn('feature %r does not exist - bind at least one method to it' % x)
- keys.update(st)
-
- # copy the precedence table
- prec = {}
- prec_tbl = self.prec or task_gen.prec
- for x in prec_tbl:
- if x in keys:
- prec[x] = prec_tbl[x]
-
- # elements disconnected
- tmp = []
- for a in keys:
- for x in prec.values():
- if a in x: break
- else:
- tmp.append(a)
-
- # topological sort
- out = []
- while tmp:
- e = tmp.pop()
- if e in keys: out.append(e)
- try:
- nlst = prec[e]
- except KeyError:
- pass
- else:
- del prec[e]
- for x in nlst:
- for y in prec:
- if x in prec[y]:
- break
- else:
- tmp.append(x)
-
- if prec: raise Utils.WafError("graph has a cycle %s" % str(prec))
- out.reverse()
- self.meths = out
-
- # then we run the methods in order
- debug('task_gen: posting %s %d', self, id(self))
- for x in out:
- try:
- v = getattr(self, x)
- except AttributeError:
- raise Utils.WafError("tried to retrieve %s which is not a valid method" % x)
- debug('task_gen: -> %s (%d)', x, id(self))
- v()
-
- def post(self):
- "runs the code to create the tasks, do not subclass"
- if not self.name:
- if isinstance(self.target, list):
- self.name = ' '.join(self.target)
- else:
- self.name = self.target
-
- if getattr(self, 'posted', None):
- #error("OBJECT ALREADY POSTED" + str( self))
- return
- self.apply()
- debug('task_gen: posted %s', self.name)
- self.posted = True
-
- def get_hook(self, ext):
- try: return self.mappings[ext]
- except KeyError:
- try: return task_gen.mappings[ext]
- except KeyError: return None
-
- # TODO waf 1.6: always set the environment
- # TODO waf 1.6: create_task(self, name, inputs, outputs)
- def create_task(self, name, src=None, tgt=None, env=None):
- env = env or self.env
- task = Task.TaskBase.classes[name](env.copy(), generator=self)
- if src:
- task.set_inputs(src)
- if tgt:
- task.set_outputs(tgt)
- self.tasks.append(task)
- return task
-
- def name_to_obj(self, name):
- return self.bld.name_to_obj(name, self.env)
-
- def find_sources_in_dirs(self, dirnames, excludes=[], exts=[]):
- """
- The attributes "excludes" and "exts" must be lists to avoid the confusion
- find_sources_in_dirs('a', 'b', 'c') <-> find_sources_in_dirs('a b c')
-
- do not use absolute paths
- do not use paths outside of the source tree
- the files or folder beginning by . are not returned
-
- # TODO: remove in Waf 1.6
- """
-
- err_msg = "'%s' attribute must be a list"
- if not isinstance(excludes, list):
- raise Utils.WscriptError(err_msg % 'excludes')
- if not isinstance(exts, list):
- raise Utils.WscriptError(err_msg % 'exts')
-
- lst = []
-
- #make sure dirnames is a list helps with dirnames with spaces
- dirnames = self.to_list(dirnames)
-
- ext_lst = exts or list(self.mappings.keys()) + list(task_gen.mappings.keys())
-
- for name in dirnames:
- anode = self.path.find_dir(name)
-
- if not anode or not anode.is_child_of(self.bld.srcnode):
- raise Utils.WscriptError("Unable to use '%s' - either because it's not a relative path" \
- ", or it's not child of '%s'." % (name, self.bld.srcnode))
-
- self.bld.rescan(anode)
- for name in self.bld.cache_dir_contents[anode.id]:
-
- # ignore hidden files
- if name.startswith('.'):
- continue
-
- (base, ext) = os.path.splitext(name)
- if ext in ext_lst and not name in lst and not name in excludes:
- lst.append((anode.relpath_gen(self.path) or '.') + os.path.sep + name)
-
- lst.sort()
- self.source = self.to_list(self.source)
- if not self.source: self.source = lst
- else: self.source += lst
-
- def clone(self, env):
- ""
- newobj = task_gen(bld=self.bld)
- for x in self.__dict__:
- if x in ['env', 'bld']:
- continue
- elif x in ["path", "features"]:
- setattr(newobj, x, getattr(self, x))
- else:
- setattr(newobj, x, copy.copy(getattr(self, x)))
-
- newobj.__class__ = self.__class__
- if isinstance(env, str):
- newobj.env = self.bld.all_envs[env].copy()
- else:
- newobj.env = env.copy()
-
- return newobj
-
- def get_inst_path(self):
- return getattr(self, '_install_path', getattr(self, 'default_install_path', ''))
-
- def set_inst_path(self, val):
- self._install_path = val
-
- install_path = property(get_inst_path, set_inst_path)
-
-
- def get_chmod(self):
- return getattr(self, '_chmod', getattr(self, 'default_chmod', O644))
-
- def set_chmod(self, val):
- self._chmod = val
-
- chmod = property(get_chmod, set_chmod)
-
-def declare_extension(var, func):
- try:
- for x in Utils.to_list(var):
- task_gen.mappings[x] = func
- except:
- raise Utils.WscriptError('declare_extension takes either a list or a string %r' % var)
- task_gen.mapped[func.__name__] = func
-
-def declare_order(*k):
- assert(len(k) > 1)
- n = len(k) - 1
- for i in xrange(n):
- f1 = k[i]
- f2 = k[i+1]
- if not f1 in task_gen.prec[f2]:
- task_gen.prec[f2].append(f1)
-
-def declare_chain(name='', action='', ext_in='', ext_out='', reentrant=True, color='BLUE',
- install=0, before=[], after=[], decider=None, rule=None, scan=None):
- """
- see Tools/flex.py for an example
- while i do not like such wrappers, some people really do
- """
-
- action = action or rule
- if isinstance(action, str):
- act = Task.simple_task_type(name, action, color=color)
- else:
- act = Task.task_type_from_func(name, action, color=color)
- act.ext_in = tuple(Utils.to_list(ext_in))
- act.ext_out = tuple(Utils.to_list(ext_out))
- act.before = Utils.to_list(before)
- act.after = Utils.to_list(after)
- act.scan = scan
-
- def x_file(self, node):
- if decider:
- ext = decider(self, node)
- else:
- ext = ext_out
-
- if isinstance(ext, str):
- out_source = node.change_ext(ext)
- if reentrant:
- self.allnodes.append(out_source)
- elif isinstance(ext, list):
- out_source = [node.change_ext(x) for x in ext]
- if reentrant:
- for i in xrange((reentrant is True) and len(out_source) or reentrant):
- self.allnodes.append(out_source[i])
- else:
- # XXX: useless: it will fail on Utils.to_list above...
- raise Utils.WafError("do not know how to process %s" % str(ext))
-
- tsk = self.create_task(name, node, out_source)
-
- if node.__class__.bld.is_install:
- tsk.install = install
-
- declare_extension(act.ext_in, x_file)
-
-def bind_feature(name, methods):
- lst = Utils.to_list(methods)
- task_gen.traits[name].update(lst)
-
-"""
-All the following decorators are registration decorators, i.e add an attribute to current class
- (task_gen and its derivatives), with same name as func, which points to func itself.
-For example:
- @taskgen
- def sayHi(self):
- print("hi")
-Now taskgen.sayHi() may be called
-
-If python were really smart, it could infer itself the order of methods by looking at the
-attributes. A prerequisite for execution is to have the attribute set before.
-Intelligent compilers binding aspect-oriented programming and parallelization, what a nice topic for studies.
-"""
-def taskgen(func):
- setattr(task_gen, func.__name__, func)
- return func
-
-def feature(*k):
- def deco(func):
- setattr(task_gen, func.__name__, func)
- for name in k:
- task_gen.traits[name].update([func.__name__])
- return func
- return deco
-
-def before(*k):
- def deco(func):
- setattr(task_gen, func.__name__, func)
- for fun_name in k:
- if not func.__name__ in task_gen.prec[fun_name]:
- task_gen.prec[fun_name].append(func.__name__)
- return func
- return deco
-
-def after(*k):
- def deco(func):
- setattr(task_gen, func.__name__, func)
- for fun_name in k:
- if not fun_name in task_gen.prec[func.__name__]:
- task_gen.prec[func.__name__].append(fun_name)
- return func
- return deco
-
-def extension(var):
- def deco(func):
- setattr(task_gen, func.__name__, func)
- try:
- for x in Utils.to_list(var):
- task_gen.mappings[x] = func
- except:
- raise Utils.WafError('extension takes either a list or a string %r' % var)
- task_gen.mapped[func.__name__] = func
- return func
- return deco
-
-# TODO make certain the decorators may be used here
-
-def apply_core(self):
- """Process the attribute source
- transform the names into file nodes
- try to process the files by name first, later by extension"""
- # get the list of folders to use by the scanners
- # all our objects share the same include paths anyway
- find_resource = self.path.find_resource
-
- for filename in self.to_list(self.source):
- # if self.mappings or task_gen.mappings contains a file of the same name
- x = self.get_hook(filename)
- if x:
- x(self, filename)
- else:
- node = find_resource(filename)
- if not node: raise Utils.WafError("source not found: '%s' in '%s'" % (filename, str(self.path)))
- self.allnodes.append(node)
-
- for node in self.allnodes:
- # self.mappings or task_gen.mappings map the file extension to a function
- x = self.get_hook(node.suffix())
-
- if not x:
- raise Utils.WafError("Cannot guess how to process %s (got mappings %r in %r) -> try conf.check_tool(..)?" % \
- (str(node), self.__class__.mappings.keys(), self.__class__))
- x(self, node)
-feature('*')(apply_core)
-
-def exec_rule(self):
- """Process the attribute rule, when provided the method apply_core will be disabled
- """
- if not getattr(self, 'rule', None):
- return
-
- # someone may have removed it already
- try:
- self.meths.remove('apply_core')
- except ValueError:
- pass
-
- # get the function and the variables
- func = self.rule
-
- vars2 = []
- if isinstance(func, str):
- # use the shell by default for user-defined commands
- (func, vars2) = Task.compile_fun('', self.rule, shell=getattr(self, 'shell', True))
- func.code = self.rule
-
- # create the task class
- name = getattr(self, 'name', None) or self.target or self.rule
- if not isinstance(name, str):
- name = str(self.idx)
- cls = Task.task_type_from_func(name, func, getattr(self, 'vars', vars2))
-
- # now create one instance
- tsk = self.create_task(name)
-
- dep_vars = getattr(self, 'dep_vars', ['ruledeps'])
- if dep_vars:
- tsk.dep_vars = dep_vars
- if isinstance(self.rule, str):
- tsk.env.ruledeps = self.rule
- else:
- # only works if the function is in a global module such as a waf tool
- tsk.env.ruledeps = Utils.h_fun(self.rule)
-
- # we assume that the user knows that without inputs or outputs
- #if not getattr(self, 'target', None) and not getattr(self, 'source', None):
- # cls.quiet = True
-
- if getattr(self, 'target', None):
- cls.quiet = True
- tsk.outputs = [self.path.find_or_declare(x) for x in self.to_list(self.target)]
-
- if getattr(self, 'source', None):
- cls.quiet = True
- tsk.inputs = []
- for x in self.to_list(self.source):
- y = self.path.find_resource(x)
- if not y:
- raise Utils.WafError('input file %r could not be found (%r)' % (x, self.path.abspath()))
- tsk.inputs.append(y)
-
- if self.allnodes:
- tsk.inputs.extend(self.allnodes)
-
- if getattr(self, 'scan', None):
- cls.scan = self.scan
-
- if getattr(self, 'install_path', None):
- tsk.install_path = self.install_path
-
- if getattr(self, 'cwd', None):
- tsk.cwd = self.cwd
-
- if getattr(self, 'on_results', None):
- Task.update_outputs(cls)
-
- if getattr(self, 'always', None):
- Task.always_run(cls)
-
- for x in ['after', 'before', 'ext_in', 'ext_out']:
- setattr(cls, x, getattr(self, x, []))
-feature('*')(exec_rule)
-before('apply_core')(exec_rule)
-
-def sequence_order(self):
- """
- add a strict sequential constraint between the tasks generated by task generators
- it uses the fact that task generators are posted in order
- it will not post objects which belong to other folders
- there is also an awesome trick for executing the method in last position
-
- to use:
- bld(features='javac seq')
- bld(features='jar seq')
-
- to start a new sequence, set the attribute seq_start, for example:
- obj.seq_start = True
- """
- if self.meths and self.meths[-1] != 'sequence_order':
- self.meths.append('sequence_order')
- return
-
- if getattr(self, 'seq_start', None):
- return
-
- # all the tasks previously declared must be run before these
- if getattr(self.bld, 'prev', None):
- self.bld.prev.post()
- for x in self.bld.prev.tasks:
- for y in self.tasks:
- y.set_run_after(x)
-
- self.bld.prev = self
-
-feature('seq')(sequence_order)
-
diff --git a/tools/wafadmin/Tools/__init__.py b/tools/wafadmin/Tools/__init__.py
deleted file mode 100644
index bc6ca230b..000000000
--- a/tools/wafadmin/Tools/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006 (ita)
-
diff --git a/tools/wafadmin/Tools/ar.py b/tools/wafadmin/Tools/ar.py
deleted file mode 100644
index af9b17fd6..000000000
--- a/tools/wafadmin/Tools/ar.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006-2008 (ita)
-# Ralf Habacker, 2006 (rh)
-
-"ar and ranlib"
-
-import os, sys
-import Task, Utils
-from Configure import conftest
-
-ar_str = '${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}'
-cls = Task.simple_task_type('static_link', ar_str, color='YELLOW', ext_in='.o', ext_out='.bin', shell=False)
-cls.maxjobs = 1
-cls.install = Utils.nada
-
-# remove the output in case it already exists
-old = cls.run
-def wrap(self):
- try: os.remove(self.outputs[0].abspath(self.env))
- except OSError: pass
- return old(self)
-setattr(cls, 'run', wrap)
-
-def detect(conf):
- conf.find_program('ar', var='AR')
- conf.find_program('ranlib', var='RANLIB')
- conf.env.ARFLAGS = 'rcs'
-
-@conftest
-def find_ar(conf):
- v = conf.env
- conf.check_tool('ar')
- if not v['AR']: conf.fatal('ar is required for static libraries - not found')
-
-
diff --git a/tools/wafadmin/Tools/cc.py b/tools/wafadmin/Tools/cc.py
deleted file mode 100644
index 59edae44f..000000000
--- a/tools/wafadmin/Tools/cc.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006 (ita)
-
-"Base for c programs/libraries"
-
-import os
-import TaskGen, Build, Utils, Task
-from Logs import debug
-import ccroot
-from TaskGen import feature, before, extension, after
-
-g_cc_flag_vars = [
-'CCDEPS', 'FRAMEWORK', 'FRAMEWORKPATH',
-'STATICLIB', 'LIB', 'LIBPATH', 'LINKFLAGS', 'RPATH',
-'CCFLAGS', 'CPPPATH', 'CPPFLAGS', 'CCDEFINES']
-
-EXT_CC = ['.c']
-
-g_cc_type_vars = ['CCFLAGS', 'LINKFLAGS']
-
-# TODO remove in waf 1.6
-class cc_taskgen(ccroot.ccroot_abstract):
- pass
-
-@feature('cc')
-@before('apply_type_vars')
-@after('default_cc')
-def init_cc(self):
- self.p_flag_vars = set(self.p_flag_vars).union(g_cc_flag_vars)
- self.p_type_vars = set(self.p_type_vars).union(g_cc_type_vars)
-
- if not self.env['CC_NAME']:
- raise Utils.WafError("At least one compiler (gcc, ..) must be selected")
-
-@feature('cc')
-@after('apply_incpaths')
-def apply_obj_vars_cc(self):
- """after apply_incpaths for INC_PATHS"""
- env = self.env
- app = env.append_unique
- cpppath_st = env['CPPPATH_ST']
-
- # local flags come first
- # set the user-defined includes paths
- for i in env['INC_PATHS']:
- app('_CCINCFLAGS', cpppath_st % i.bldpath(env))
- app('_CCINCFLAGS', cpppath_st % i.srcpath(env))
-
- # set the library include paths
- for i in env['CPPPATH']:
- app('_CCINCFLAGS', cpppath_st % i)
-
-@feature('cc')
-@after('apply_lib_vars')
-def apply_defines_cc(self):
- """after uselib is set for CCDEFINES"""
- self.defines = getattr(self, 'defines', [])
- lst = self.to_list(self.defines) + self.to_list(self.env['CCDEFINES'])
- milst = []
-
- # now process the local defines
- for defi in lst:
- if not defi in milst:
- milst.append(defi)
-
- # CCDEFINES_
- libs = self.to_list(self.uselib)
- for l in libs:
- val = self.env['CCDEFINES_'+l]
- if val: milst += val
- self.env['DEFLINES'] = ["%s %s" % (x[0], Utils.trimquotes('='.join(x[1:]))) for x in [y.split('=') for y in milst]]
- y = self.env['CCDEFINES_ST']
- self.env['_CCDEFFLAGS'] = [y%x for x in milst]
-
-@extension(EXT_CC)
-def c_hook(self, node):
- # create the compilation task: cpp or cc
- if getattr(self, 'obj_ext', None):
- obj_ext = self.obj_ext
- else:
- obj_ext = '_%d.o' % self.idx
-
- task = self.create_task('cc', node, node.change_ext(obj_ext))
- try:
- self.compiled_tasks.append(task)
- except AttributeError:
- raise Utils.WafError('Have you forgotten to set the feature "cc" on %s?' % str(self))
- return task
-
-cc_str = '${CC} ${CCFLAGS} ${CPPFLAGS} ${_CCINCFLAGS} ${_CCDEFFLAGS} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT}'
-cls = Task.simple_task_type('cc', cc_str, 'GREEN', ext_out='.o', ext_in='.c', shell=False)
-cls.scan = ccroot.scan
-cls.vars.append('CCDEPS')
-
-link_str = '${LINK_CC} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath(env)} ${LINKFLAGS}'
-cls = Task.simple_task_type('cc_link', link_str, color='YELLOW', ext_in='.o', ext_out='.bin', shell=False)
-cls.maxjobs = 1
-cls.install = Utils.nada
-
diff --git a/tools/wafadmin/Tools/ccroot.py b/tools/wafadmin/Tools/ccroot.py
deleted file mode 100644
index 5e7fcf32e..000000000
--- a/tools/wafadmin/Tools/ccroot.py
+++ /dev/null
@@ -1,625 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005-2008 (ita)
-
-"base for all c/c++ programs and libraries"
-
-import os, sys, re
-import TaskGen, Task, Utils, preproc, Logs, Build, Options
-from Logs import error, debug, warn
-from Utils import md5
-from TaskGen import taskgen, after, before, feature
-from Constants import *
-from Configure import conftest
-try:
- from cStringIO import StringIO
-except ImportError:
- from io import StringIO
-
-import config_c # <- necessary for the configuration, do not touch
-
-USE_TOP_LEVEL = False
-
-def get_cc_version(conf, cc, gcc=False, icc=False):
-
- cmd = cc + ['-dM', '-E', '-']
- try:
- p = Utils.pproc.Popen(cmd, stdin=Utils.pproc.PIPE, stdout=Utils.pproc.PIPE, stderr=Utils.pproc.PIPE)
- p.stdin.write('\n')
- out = p.communicate()[0]
- except:
- conf.fatal('could not determine the compiler version %r' % cmd)
-
- # PY3K: do not touch
- out = str(out)
-
- if gcc:
- if out.find('__INTEL_COMPILER') >= 0:
- conf.fatal('The intel compiler pretends to be gcc')
- if out.find('__GNUC__') < 0:
- conf.fatal('Could not determine the compiler type')
-
- if icc and out.find('__INTEL_COMPILER') < 0:
- conf.fatal('Not icc/icpc')
-
- k = {}
- if icc or gcc:
- out = out.split('\n')
- import shlex
-
- for line in out:
- lst = shlex.split(line)
- if len(lst)>2:
- key = lst[1]
- val = lst[2]
- k[key] = val
-
- def isD(var):
- return var in k
-
- def isT(var):
- return var in k and k[var] != '0'
-
- # Some documentation is available at http://predef.sourceforge.net
- # The names given to DEST_OS must match what Utils.unversioned_sys_platform() returns.
- mp1 = {
- '__linux__' : 'linux',
- '__GNU__' : 'hurd',
- '__FreeBSD__' : 'freebsd',
- '__NetBSD__' : 'netbsd',
- '__OpenBSD__' : 'openbsd',
- '__sun' : 'sunos',
- '__hpux' : 'hpux',
- '__sgi' : 'irix',
- '_AIX' : 'aix',
- '__CYGWIN__' : 'cygwin',
- '__MSYS__' : 'msys',
- '_UWIN' : 'uwin',
- '_WIN64' : 'win32',
- '_WIN32' : 'win32',
- }
-
- for i in mp1:
- if isD(i):
- conf.env.DEST_OS = mp1[i]
- break
- else:
- if isD('__APPLE__') and isD('__MACH__'):
- conf.env.DEST_OS = 'darwin'
- elif isD('__unix__'): # unix must be tested last as it's a generic fallback
- conf.env.DEST_OS = 'generic'
-
- if isD('__ELF__'):
- conf.env.DEST_BINFMT = 'elf'
-
- mp2 = {
- '__x86_64__' : 'x86_64',
- '__i386__' : 'x86',
- '__ia64__' : 'ia',
- '__mips__' : 'mips',
- '__sparc__' : 'sparc',
- '__alpha__' : 'alpha',
- '__arm__' : 'arm',
- '__hppa__' : 'hppa',
- '__powerpc__' : 'powerpc',
- }
- for i in mp2:
- if isD(i):
- conf.env.DEST_CPU = mp2[i]
- break
-
- debug('ccroot: dest platform: ' + ' '.join([conf.env[x] or '?' for x in ('DEST_OS', 'DEST_BINFMT', 'DEST_CPU')]))
- conf.env['CC_VERSION'] = (k['__GNUC__'], k['__GNUC_MINOR__'], k['__GNUC_PATCHLEVEL__'])
- return k
-
-class DEBUG_LEVELS:
- """Will disappear in waf 1.6"""
- ULTRADEBUG = "ultradebug"
- DEBUG = "debug"
- RELEASE = "release"
- OPTIMIZED = "optimized"
- CUSTOM = "custom"
-
- ALL = [ULTRADEBUG, DEBUG, RELEASE, OPTIMIZED, CUSTOM]
-
-def scan(self):
- "look for .h the .cpp need"
- debug('ccroot: _scan_preprocessor(self, node, env, path_lst)')
-
- # TODO waf 1.6 - assume the default input has exactly one file
-
- if len(self.inputs) == 1:
- node = self.inputs[0]
- (nodes, names) = preproc.get_deps(node, self.env, nodepaths = self.env['INC_PATHS'])
- if Logs.verbose:
- debug('deps: deps for %s: %r; unresolved %r', str(node), nodes, names)
- return (nodes, names)
-
- all_nodes = []
- all_names = []
- seen = set()
- for node in self.inputs:
- (nodes, names) = preproc.get_deps(node, self.env, nodepaths = self.env['INC_PATHS'])
- if Logs.verbose:
- debug('deps: deps for %s: %r; unresolved %r', str(node), nodes, names)
- for x in nodes:
- if id(x) in seen: continue
- seen.add(id(x))
- all_nodes.append(x)
- for x in names:
- if not x in all_names:
- all_names.append(x)
- return (all_nodes, all_names)
-
-class ccroot_abstract(TaskGen.task_gen):
- "Parent class for programs and libraries in languages c, c++ and moc (Qt)"
- def __init__(self, *k, **kw):
- # COMPAT remove in waf 1.6 TODO
- if len(k) > 1:
- k = list(k)
- if k[1][0] != 'c':
- k[1] = 'c' + k[1]
- TaskGen.task_gen.__init__(self, *k, **kw)
-
-def get_target_name(self):
- tp = 'program'
- for x in self.features:
- if x in ['cshlib', 'cstaticlib']:
- tp = x.lstrip('c')
-
- pattern = self.env[tp + '_PATTERN']
- if not pattern: pattern = '%s'
-
- dir, name = os.path.split(self.target)
-
- if self.env.DEST_BINFMT == 'pe' and getattr(self, 'vnum', None) and 'cshlib' in self.features:
- # include the version in the dll file name,
- # the import lib file name stays unversionned.
- name = name + '-' + self.vnum.split('.')[0]
-
- return os.path.join(dir, pattern % name)
-
-@feature('cc', 'cxx')
-@before('apply_core')
-def default_cc(self):
- """compiled_tasks attribute must be set before the '.c->.o' tasks can be created"""
- Utils.def_attrs(self,
- includes = '',
- defines= '',
- rpaths = '',
- uselib = '',
- uselib_local = '',
- add_objects = '',
- p_flag_vars = [],
- p_type_vars = [],
- compiled_tasks = [],
- link_task = None)
-
- # The only thing we need for cross-compilation is DEST_BINFMT.
- # At some point, we may reach a case where DEST_BINFMT is not enough, but for now it's sufficient.
- # Currently, cross-compilation is auto-detected only for the gnu and intel compilers.
- if not self.env.DEST_BINFMT:
- # Infer the binary format from the os name.
- self.env.DEST_BINFMT = Utils.unversioned_sys_platform_to_binary_format(
- self.env.DEST_OS or Utils.unversioned_sys_platform())
-
- if not self.env.BINDIR: self.env.BINDIR = Utils.subst_vars('${PREFIX}/bin', self.env)
- if not self.env.LIBDIR: self.env.LIBDIR = Utils.subst_vars('${PREFIX}/lib${LIB_EXT}', self.env)
-
-@feature('cprogram', 'dprogram', 'cstaticlib', 'dstaticlib', 'cshlib', 'dshlib')
-def apply_verif(self):
- """no particular order, used for diagnostic"""
- if not (self.source or getattr(self, 'add_objects', None) or getattr(self, 'uselib_local', None) or getattr(self, 'obj_files', None)):
- raise Utils.WafError('no source files specified for %s' % self)
- if not self.target:
- raise Utils.WafError('no target for %s' % self)
-
-# TODO reference the d programs, shlibs in d.py, not here
-
-@feature('cprogram', 'dprogram')
-@after('default_cc')
-@before('apply_core')
-def vars_target_cprogram(self):
- self.default_install_path = self.env.BINDIR
- self.default_chmod = O755
-
-@after('default_cc')
-@feature('cshlib', 'dshlib')
-@before('apply_core')
-def vars_target_cshlib(self):
- if self.env.DEST_BINFMT == 'pe':
- # set execute bit on libs to avoid 'permission denied' (issue 283)
- self.default_chmod = O755
- self.default_install_path = self.env.BINDIR
- else:
- self.default_install_path = self.env.LIBDIR
-
-@feature('cprogram', 'dprogram', 'cstaticlib', 'dstaticlib', 'cshlib', 'dshlib')
-@after('apply_link', 'vars_target_cprogram', 'vars_target_cshlib')
-def default_link_install(self):
- """you may kill this method to inject your own installation for the first element
- any other install should only process its own nodes and not those from the others"""
- if self.install_path:
- self.bld.install_files(self.install_path, self.link_task.outputs[0], env=self.env, chmod=self.chmod)
-
-@feature('cc', 'cxx')
-@after('apply_type_vars', 'apply_lib_vars', 'apply_core')
-def apply_incpaths(self):
- """used by the scanner
- after processing the uselib for CPPPATH
- after apply_core because some processing may add include paths
- """
- lst = []
- # TODO move the uselib processing out of here
- for lib in self.to_list(self.uselib):
- for path in self.env['CPPPATH_' + lib]:
- if not path in lst:
- lst.append(path)
- if preproc.go_absolute:
- for path in preproc.standard_includes:
- if not path in lst:
- lst.append(path)
-
- for path in self.to_list(self.includes):
- if not path in lst:
- if preproc.go_absolute or not os.path.isabs(path):
- lst.append(path)
- else:
- self.env.prepend_value('CPPPATH', path)
-
- for path in lst:
- node = None
- if os.path.isabs(path):
- if preproc.go_absolute:
- node = self.bld.root.find_dir(path)
- elif path[0] == '#':
- node = self.bld.srcnode
- if len(path) > 1:
- node = node.find_dir(path[1:])
- else:
- node = self.path.find_dir(path)
-
- if node:
- self.env.append_value('INC_PATHS', node)
-
- # TODO WAF 1.6
- if USE_TOP_LEVEL:
- self.env.append_value('INC_PATHS', self.bld.srcnode)
-
-@feature('cc', 'cxx')
-@after('init_cc', 'init_cxx')
-@before('apply_lib_vars')
-def apply_type_vars(self):
- """before apply_lib_vars because we modify uselib
- after init_cc and init_cxx because web need p_type_vars
- """
- for x in self.features:
- if not x in ['cprogram', 'cstaticlib', 'cshlib']:
- continue
- x = x.lstrip('c')
-
- # if the type defines uselib to add, add them
- st = self.env[x + '_USELIB']
- if st: self.uselib = self.uselib + ' ' + st
-
- # each compiler defines variables like 'shlib_CXXFLAGS', 'shlib_LINKFLAGS', etc
- # so when we make a task generator of the type shlib, CXXFLAGS are modified accordingly
- for var in self.p_type_vars:
- compvar = '%s_%s' % (x, var)
- #print compvar
- value = self.env[compvar]
- if value: self.env.append_value(var, value)
-
-@feature('cprogram', 'cshlib', 'cstaticlib')
-@after('apply_core')
-def apply_link(self):
- """executes after apply_core for collecting 'compiled_tasks'
- use a custom linker if specified (self.link='name-of-custom-link-task')"""
- link = getattr(self, 'link', None)
- if not link:
- if 'cstaticlib' in self.features: link = 'static_link'
- elif 'cxx' in self.features: link = 'cxx_link'
- else: link = 'cc_link'
-
- tsk = self.create_task(link)
- outputs = [t.outputs[0] for t in self.compiled_tasks]
- tsk.set_inputs(outputs)
- tsk.set_outputs(self.path.find_or_declare(get_target_name(self)))
-
- self.link_task = tsk
-
-@feature('cc', 'cxx')
-@after('apply_link', 'init_cc', 'init_cxx', 'apply_core')
-def apply_lib_vars(self):
- """after apply_link because of 'link_task'
- after default_cc because of the attribute 'uselib'"""
-
- # after 'apply_core' in case if 'cc' if there is no link
-
- env = self.env
-
- # 1. the case of the libs defined in the project (visit ancestors first)
- # the ancestors external libraries (uselib) will be prepended
- self.uselib = self.to_list(self.uselib)
- names = self.to_list(self.uselib_local)
-
- seen = set([])
- tmp = Utils.deque(names) # consume a copy of the list of names
- while tmp:
- lib_name = tmp.popleft()
- # visit dependencies only once
- if lib_name in seen:
- continue
-
- y = self.name_to_obj(lib_name)
- if not y:
- raise Utils.WafError('object %r was not found in uselib_local (required by %r)' % (lib_name, self.name))
- y.post()
- seen.add(lib_name)
-
- # object has ancestors to process (shared libraries): add them to the end of the list
- if getattr(y, 'uselib_local', None):
- lst = y.to_list(y.uselib_local)
- if 'cshlib' in y.features or 'cprogram' in y.features:
- lst = [x for x in lst if not 'cstaticlib' in self.name_to_obj(x).features]
- tmp.extend(lst)
-
- # link task and flags
- if getattr(y, 'link_task', None):
-
- link_name = y.target[y.target.rfind(os.sep) + 1:]
- if 'cstaticlib' in y.features:
- env.append_value('STATICLIB', link_name)
- elif 'cshlib' in y.features or 'cprogram' in y.features:
- # WARNING some linkers can link against programs
- env.append_value('LIB', link_name)
-
- # the order
- self.link_task.set_run_after(y.link_task)
-
- # for the recompilation
- dep_nodes = getattr(self.link_task, 'dep_nodes', [])
- self.link_task.dep_nodes = dep_nodes + y.link_task.outputs
-
- # add the link path too
- tmp_path = y.link_task.outputs[0].parent.bldpath(self.env)
- if not tmp_path in env['LIBPATH']: env.prepend_value('LIBPATH', tmp_path)
-
- # add ancestors uselib too - but only propagate those that have no staticlib
- for v in self.to_list(y.uselib):
- if not env['STATICLIB_' + v]:
- if not v in self.uselib:
- self.uselib.insert(0, v)
-
- # if the library task generator provides 'export_incdirs', add to the include path
- # the export_incdirs must be a list of paths relative to the other library
- if getattr(y, 'export_incdirs', None):
- for x in self.to_list(y.export_incdirs):
- node = y.path.find_dir(x)
- if not node:
- raise Utils.WafError('object %r: invalid folder %r in export_incdirs' % (y.target, x))
- self.env.append_unique('INC_PATHS', node)
-
- # 2. the case of the libs defined outside
- for x in self.uselib:
- for v in self.p_flag_vars:
- val = self.env[v + '_' + x]
- if val: self.env.append_value(v, val)
-
-@feature('cprogram', 'cstaticlib', 'cshlib')
-@after('init_cc', 'init_cxx', 'apply_link')
-def apply_objdeps(self):
- "add the .o files produced by some other object files in the same manner as uselib_local"
- if not getattr(self, 'add_objects', None): return
-
- seen = []
- names = self.to_list(self.add_objects)
- while names:
- x = names[0]
-
- # visit dependencies only once
- if x in seen:
- names = names[1:]
- continue
-
- # object does not exist ?
- y = self.name_to_obj(x)
- if not y:
- raise Utils.WafError('object %r was not found in uselib_local (required by add_objects %r)' % (x, self.name))
-
- # object has ancestors to process first ? update the list of names
- if getattr(y, 'add_objects', None):
- added = 0
- lst = y.to_list(y.add_objects)
- lst.reverse()
- for u in lst:
- if u in seen: continue
- added = 1
- names = [u]+names
- if added: continue # list of names modified, loop
-
- # safe to process the current object
- y.post()
- seen.append(x)
-
- for t in y.compiled_tasks:
- self.link_task.inputs.extend(t.outputs)
-
-@feature('cprogram', 'cshlib', 'cstaticlib')
-@after('apply_lib_vars')
-def apply_obj_vars(self):
- """after apply_lib_vars for uselib"""
- v = self.env
- lib_st = v['LIB_ST']
- staticlib_st = v['STATICLIB_ST']
- libpath_st = v['LIBPATH_ST']
- staticlibpath_st = v['STATICLIBPATH_ST']
- rpath_st = v['RPATH_ST']
-
- app = v.append_unique
-
- if v['FULLSTATIC']:
- v.append_value('LINKFLAGS', v['FULLSTATIC_MARKER'])
-
- for i in v['RPATH']:
- if i and rpath_st:
- app('LINKFLAGS', rpath_st % i)
-
- for i in v['LIBPATH']:
- app('LINKFLAGS', libpath_st % i)
- app('LINKFLAGS', staticlibpath_st % i)
-
- if v['STATICLIB']:
- v.append_value('LINKFLAGS', v['STATICLIB_MARKER'])
- k = [(staticlib_st % i) for i in v['STATICLIB']]
- app('LINKFLAGS', k)
-
- # fully static binaries ?
- if not v['FULLSTATIC']:
- if v['STATICLIB'] or v['LIB']:
- v.append_value('LINKFLAGS', v['SHLIB_MARKER'])
-
- app('LINKFLAGS', [lib_st % i for i in v['LIB']])
-
-@after('apply_link')
-def process_obj_files(self):
- if not hasattr(self, 'obj_files'): return
- for x in self.obj_files:
- node = self.path.find_resource(x)
- self.link_task.inputs.append(node)
-
-@taskgen
-def add_obj_file(self, file):
- """Small example on how to link object files as if they were source
- obj = bld.create_obj('cc')
- obj.add_obj_file('foo.o')"""
- if not hasattr(self, 'obj_files'): self.obj_files = []
- if not 'process_obj_files' in self.meths: self.meths.append('process_obj_files')
- self.obj_files.append(file)
-
-c_attrs = {
-'cxxflag' : 'CXXFLAGS',
-'cflag' : 'CCFLAGS',
-'ccflag' : 'CCFLAGS',
-'linkflag' : 'LINKFLAGS',
-'ldflag' : 'LINKFLAGS',
-'lib' : 'LIB',
-'libpath' : 'LIBPATH',
-'staticlib': 'STATICLIB',
-'staticlibpath': 'STATICLIBPATH',
-'rpath' : 'RPATH',
-'framework' : 'FRAMEWORK',
-'frameworkpath' : 'FRAMEWORKPATH'
-}
-
-@feature('cc', 'cxx')
-@before('init_cxx', 'init_cc')
-@before('apply_lib_vars', 'apply_obj_vars', 'apply_incpaths', 'init_cc')
-def add_extra_flags(self):
- """case and plural insensitive
- before apply_obj_vars for processing the library attributes
- """
- for x in self.__dict__.keys():
- y = x.lower()
- if y[-1] == 's':
- y = y[:-1]
- if c_attrs.get(y, None):
- self.env.append_unique(c_attrs[y], getattr(self, x))
-
-# ============ the code above must not know anything about import libs ==========
-
-@feature('cshlib')
-@after('apply_link', 'default_cc')
-@before('apply_lib_vars', 'apply_objdeps', 'default_link_install')
-def apply_implib(self):
- """On mswindows, handle dlls and their import libs
- the .dll.a is the import lib and it is required for linking so it is installed too
- """
- if not self.env.DEST_BINFMT == 'pe':
- return
-
- self.meths.remove('default_link_install')
-
- bindir = self.install_path
- if not bindir: return
-
- # install the dll in the bin dir
- dll = self.link_task.outputs[0]
- self.bld.install_files(bindir, dll, self.env, self.chmod)
-
- # add linker flags to generate the import lib
- implib = self.env['implib_PATTERN'] % os.path.split(self.target)[1]
-
- implib = dll.parent.find_or_declare(implib)
- self.link_task.outputs.append(implib)
- self.bld.install_as('${LIBDIR}/%s' % implib.name, implib, self.env)
-
- self.env.append_value('LINKFLAGS', (self.env['IMPLIB_ST'] % implib.bldpath(self.env)).split())
-
-# ============ the code above must not know anything about vnum processing on unix platforms =========
-
-@feature('cshlib')
-@after('apply_link')
-@before('apply_lib_vars', 'default_link_install')
-def apply_vnum(self):
- """
- libfoo.so is installed as libfoo.so.1.2.3
- """
- if not getattr(self, 'vnum', '') or not 'cshlib' in self.features or os.name != 'posix' or self.env.DEST_BINFMT not in ('elf', 'mac-o'):
- return
-
- self.meths.remove('default_link_install')
-
- link = self.link_task
- nums = self.vnum.split('.')
- node = link.outputs[0]
-
- libname = node.name
- if libname.endswith('.dylib'):
- name3 = libname.replace('.dylib', '.%s.dylib' % self.vnum)
- name2 = libname.replace('.dylib', '.%s.dylib' % nums[0])
- else:
- name3 = libname + '.' + self.vnum
- name2 = libname + '.' + nums[0]
-
- if self.env.SONAME_ST:
- v = self.env.SONAME_ST % name2
- self.env.append_value('LINKFLAGS', v.split())
-
- bld = self.bld
- nums = self.vnum.split('.')
-
- path = self.install_path
- if not path: return
-
- bld.install_as(path + os.sep + name3, node, env=self.env)
- bld.symlink_as(path + os.sep + name2, name3)
- bld.symlink_as(path + os.sep + libname, name3)
-
- # the following task is just to enable execution from the build dir :-/
- tsk = self.create_task('vnum')
- tsk.set_inputs([node])
- tsk.set_outputs(node.parent.find_or_declare(name2))
-
-def exec_vnum_link(self):
- path = self.outputs[0].abspath(self.env)
- try:
- os.remove(path)
- except OSError:
- pass
-
- try:
- os.symlink(self.inputs[0].name, path)
- except OSError:
- return 1
-
-cls = Task.task_type_from_func('vnum', func=exec_vnum_link, ext_in='.bin', color='CYAN')
-cls.quiet = 1
-
-# ============ the --as-needed flag should added during the configuration, not at runtime =========
-
-@conftest
-def add_as_needed(conf):
- if conf.env.DEST_BINFMT == 'elf' and 'gcc' in (conf.env.CXX_NAME, conf.env.CC_NAME):
- conf.env.append_unique('LINKFLAGS', '--as-needed')
-
diff --git a/tools/wafadmin/Tools/compiler_cc.py b/tools/wafadmin/Tools/compiler_cc.py
deleted file mode 100644
index f3cb8cdbb..000000000
--- a/tools/wafadmin/Tools/compiler_cc.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Matthias Jahn jahn dôt matthias ât freenet dôt de, 2007 (pmarat)
-
-import os, sys, imp, types, ccroot
-import optparse
-import Utils, Configure, Options
-from Logs import debug
-
-c_compiler = {
- 'win32': ['gcc'],
- 'cygwin': ['gcc'],
- 'darwin': ['gcc'],
- 'aix': ['xlc', 'gcc'],
- 'linux': ['gcc', 'icc', 'suncc'],
- 'sunos': ['gcc', 'suncc'],
- 'irix': ['gcc'],
- 'hpux': ['gcc'],
- 'default': ['gcc']
-}
-
-def __list_possible_compiler(platform):
- try:
- return c_compiler[platform]
- except KeyError:
- return c_compiler["default"]
-
-def detect(conf):
- """
- for each compiler for the platform, try to configure the compiler
- in theory the tools should raise a configuration error if the compiler
- pretends to be something it is not (setting CC=icc and trying to configure gcc)
- """
- try: test_for_compiler = Options.options.check_c_compiler
- except AttributeError: conf.fatal("Add set_options(opt): opt.tool_options('compiler_cc')")
- orig = conf.env
- for compiler in test_for_compiler.split():
- conf.env = orig.copy()
- try:
- conf.check_tool(compiler)
- except Configure.ConfigurationError, e:
- debug('compiler_cc: %r' % e)
- else:
- if conf.env['CC']:
- orig.table = conf.env.get_merged_dict()
- conf.env = orig
- conf.check_message(compiler, '', True)
- conf.env['COMPILER_CC'] = compiler
- break
- conf.check_message(compiler, '', False)
- break
- else:
- conf.fatal('could not configure a c compiler!')
-
-def set_options(opt):
- build_platform = Utils.unversioned_sys_platform()
- possible_compiler_list = __list_possible_compiler(build_platform)
- test_for_compiler = ' '.join(possible_compiler_list)
- cc_compiler_opts = opt.add_option_group("C Compiler Options")
- cc_compiler_opts.add_option('--check-c-compiler', default="%s" % test_for_compiler,
- help='On this platform (%s) the following C-Compiler will be checked by default: "%s"' % (build_platform, test_for_compiler),
- dest="check_c_compiler")
-
- for c_compiler in test_for_compiler.split():
- opt.tool_options('%s' % c_compiler, option_group=cc_compiler_opts)
-
diff --git a/tools/wafadmin/Tools/compiler_cxx.py b/tools/wafadmin/Tools/compiler_cxx.py
deleted file mode 100644
index 6cad1915e..000000000
--- a/tools/wafadmin/Tools/compiler_cxx.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Matthias Jahn jahn dôt matthias ât freenet dôt de 2007 (pmarat)
-
-import os, sys, imp, types, ccroot
-import optparse
-import Utils, Configure, Options
-from Logs import debug
-
-cxx_compiler = {
-'win32': ['g++'],
-'cygwin': ['g++'],
-'darwin': ['g++'],
-'aix': ['xlc++', 'g++'],
-'linux': ['g++', 'icpc', 'sunc++'],
-'sunos': ['g++', 'sunc++'],
-'irix': ['g++'],
-'hpux': ['g++'],
-'default': ['g++']
-}
-
-def __list_possible_compiler(platform):
- try:
- return cxx_compiler[platform]
- except KeyError:
- return cxx_compiler["default"]
-
-def detect(conf):
- try: test_for_compiler = Options.options.check_cxx_compiler
- except AttributeError: raise Configure.ConfigurationError("Add set_options(opt): opt.tool_options('compiler_cxx')")
- orig = conf.env
- for compiler in test_for_compiler.split():
- try:
- conf.env = orig.copy()
- conf.check_tool(compiler)
- except Configure.ConfigurationError, e:
- debug('compiler_cxx: %r' % e)
- else:
- if conf.env['CXX']:
- orig.table = conf.env.get_merged_dict()
- conf.env = orig
- conf.check_message(compiler, '', True)
- conf.env['COMPILER_CXX'] = compiler
- break
- conf.check_message(compiler, '', False)
- break
- else:
- conf.fatal('could not configure a cxx compiler!')
-
-def set_options(opt):
- build_platform = Utils.unversioned_sys_platform()
- possible_compiler_list = __list_possible_compiler(build_platform)
- test_for_compiler = ' '.join(possible_compiler_list)
- cxx_compiler_opts = opt.add_option_group('C++ Compiler Options')
- cxx_compiler_opts.add_option('--check-cxx-compiler', default="%s" % test_for_compiler,
- help='On this platform (%s) the following C++ Compiler will be checked by default: "%s"' % (build_platform, test_for_compiler),
- dest="check_cxx_compiler")
-
- for cxx_compiler in test_for_compiler.split():
- opt.tool_options('%s' % cxx_compiler, option_group=cxx_compiler_opts)
-
diff --git a/tools/wafadmin/Tools/compiler_d.py b/tools/wafadmin/Tools/compiler_d.py
deleted file mode 100644
index 1ea5efa30..000000000
--- a/tools/wafadmin/Tools/compiler_d.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Carlos Rafael Giani, 2007 (dv)
-
-import os, sys, imp, types
-import Utils, Configure, Options
-
-def detect(conf):
- if getattr(Options.options, 'check_dmd_first', None):
- test_for_compiler = ['dmd', 'gdc']
- else:
- test_for_compiler = ['gdc', 'dmd']
-
- for d_compiler in test_for_compiler:
- try:
- conf.check_tool(d_compiler)
- except:
- pass
- else:
- break
- else:
- conf.fatal('no suitable d compiler was found')
-
-def set_options(opt):
- d_compiler_opts = opt.add_option_group('D Compiler Options')
- d_compiler_opts.add_option('--check-dmd-first', action='store_true',
- help='checks for the gdc compiler before dmd (default is the other way round)',
- dest='check_dmd_first',
- default=False)
-
- for d_compiler in ['gdc', 'dmd']:
- opt.tool_options('%s' % d_compiler, option_group=d_compiler_opts)
-
diff --git a/tools/wafadmin/Tools/config_c.py b/tools/wafadmin/Tools/config_c.py
deleted file mode 100644
index 21729d42e..000000000
--- a/tools/wafadmin/Tools/config_c.py
+++ /dev/null
@@ -1,729 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005-2008 (ita)
-
-"""
-c/c++ configuration routines
-"""
-
-import os, imp, sys, shlex, shutil
-from Utils import md5
-import Build, Utils, Configure, Task, Options, Logs, TaskGen
-from Constants import *
-from Configure import conf, conftest
-
-cfg_ver = {
- 'atleast-version': '>=',
- 'exact-version': '==',
- 'max-version': '<=',
-}
-
-SNIP1 = '''
- int main() {
- void *p;
- p=(void*)(%s);
- return 0;
-}
-'''
-
-SNIP2 = '''
-int main() {
- if ((%(type_name)s *) 0) return 0;
- if (sizeof (%(type_name)s)) return 0;
-}
-'''
-
-SNIP3 = '''
-int main() {
- return 0;
-}
-'''
-
-def parse_flags(line, uselib, env):
- """pkg-config still has bugs on some platforms, and there are many -config programs, parsing flags is necessary :-/"""
-
- lst = shlex.split(line)
- while lst:
- x = lst.pop(0)
- st = x[:2]
- ot = x[2:]
-
- if st == '-I' or st == '/I':
- if not ot: ot = lst.pop(0)
- env.append_unique('CPPPATH_' + uselib, ot)
- elif st == '-D':
- if not ot: ot = lst.pop(0)
- env.append_unique('CXXDEFINES_' + uselib, ot)
- env.append_unique('CCDEFINES_' + uselib, ot)
- elif st == '-l':
- if not ot: ot = lst.pop(0)
- env.append_unique('LIB_' + uselib, ot)
- elif st == '-L':
- if not ot: ot = lst.pop(0)
- env.append_unique('LIBPATH_' + uselib, ot)
- elif x == '-pthread' or x.startswith('+'):
- env.append_unique('CCFLAGS_' + uselib, x)
- env.append_unique('CXXFLAGS_' + uselib, x)
- env.append_unique('LINKFLAGS_' + uselib, x)
- elif x == '-framework':
- env.append_unique('FRAMEWORK_' + uselib, lst.pop(0))
- elif x.startswith('-F'):
- env.append_unique('FRAMEWORKPATH_' + uselib, x[2:])
- elif x.startswith('-std'):
- env.append_unique('CCFLAGS_' + uselib, x)
- env.append_unique('LINKFLAGS_' + uselib, x)
- elif x.startswith('-Wl'):
- env.append_unique('LINKFLAGS_' + uselib, x)
- elif x.startswith('-m') or x.startswith('-f'):
- env.append_unique('CCFLAGS_' + uselib, x)
- env.append_unique('CXXFLAGS_' + uselib, x)
-
-@conf
-def ret_msg(self, f, kw):
- """execute a function, when provided"""
- if isinstance(f, str):
- return f
- return f(kw)
-
-@conf
-def validate_cfg(self, kw):
- if not 'path' in kw:
- kw['path'] = 'pkg-config --errors-to-stdout --print-errors'
-
- # pkg-config version
- if 'atleast_pkgconfig_version' in kw:
- if not 'msg' in kw:
- kw['msg'] = 'Checking for pkg-config version >= %s' % kw['atleast_pkgconfig_version']
- return
-
- # pkg-config --modversion
- if 'modversion' in kw:
- return
-
- if 'variables' in kw:
- if not 'msg' in kw:
- kw['msg'] = 'Checking for %s variables' % kw['package']
- return
-
- # checking for the version of a module, for the moment, one thing at a time
- for x in cfg_ver.keys():
- y = x.replace('-', '_')
- if y in kw:
- if not 'package' in kw:
- raise ValueError('%s requires a package' % x)
-
- if not 'msg' in kw:
- kw['msg'] = 'Checking for %s %s %s' % (kw['package'], cfg_ver[x], kw[y])
- return
-
- if not 'msg' in kw:
- kw['msg'] = 'Checking for %s' % (kw['package'] or kw['path'])
- if not 'okmsg' in kw:
- kw['okmsg'] = 'yes'
- if not 'errmsg' in kw:
- kw['errmsg'] = 'not found'
-
-@conf
-def cmd_and_log(self, cmd, kw):
- Logs.debug('runner: %s\n' % cmd)
- if self.log:
- self.log.write('%s\n' % cmd)
-
- try:
- p = Utils.pproc.Popen(cmd, stdout=Utils.pproc.PIPE, stderr=Utils.pproc.PIPE, shell=True)
- (out, err) = p.communicate()
- except OSError, e:
- self.log.write('error %r' % e)
- self.fatal(str(e))
-
- out = str(out)
- err = str(err)
-
- if self.log:
- self.log.write(out)
- self.log.write(err)
-
- if p.returncode:
- if not kw.get('errmsg', ''):
- if kw.get('mandatory', False):
- kw['errmsg'] = out.strip()
- else:
- kw['errmsg'] = 'no'
- self.fatal('fail')
- return out
-
-@conf
-def exec_cfg(self, kw):
-
- # pkg-config version
- if 'atleast_pkgconfig_version' in kw:
- cmd = '%s --atleast-pkgconfig-version=%s' % (kw['path'], kw['atleast_pkgconfig_version'])
- self.cmd_and_log(cmd, kw)
- if not 'okmsg' in kw:
- kw['okmsg'] = 'yes'
- return
-
- # checking for the version of a module
- for x in cfg_ver:
- y = x.replace('-', '_')
- if y in kw:
- self.cmd_and_log('%s --%s=%s %s' % (kw['path'], x, kw[y], kw['package']), kw)
- if not 'okmsg' in kw:
- kw['okmsg'] = 'yes'
- self.define(self.have_define(kw.get('uselib_store', kw['package'])), 1, 0)
- break
-
- # retrieving the version of a module
- if 'modversion' in kw:
- version = self.cmd_and_log('%s --modversion %s' % (kw['path'], kw['modversion']), kw).strip()
- self.define('%s_VERSION' % Utils.quote_define_name(kw.get('uselib_store', kw['modversion'])), version)
- return version
-
- # retrieving variables of a module
- if 'variables' in kw:
- env = kw.get('env', self.env)
- uselib = kw.get('uselib_store', kw['package'].upper())
- vars = Utils.to_list(kw['variables'])
- for v in vars:
- val = self.cmd_and_log('%s --variable=%s %s' % (kw['path'], v, kw['package']), kw).strip()
- var = '%s_%s' % (uselib, v)
- env[var] = val
- if not 'okmsg' in kw:
- kw['okmsg'] = 'yes'
- return
-
- lst = [kw['path']]
- for key, val in kw.get('define_variable', {}).iteritems():
- lst.append('--define-variable=%s=%s' % (key, val))
-
- lst.append(kw.get('args', ''))
- lst.append(kw['package'])
-
- # so we assume the command-line will output flags to be parsed afterwards
- cmd = ' '.join(lst)
- ret = self.cmd_and_log(cmd, kw)
- if not 'okmsg' in kw:
- kw['okmsg'] = 'yes'
-
- self.define(self.have_define(kw.get('uselib_store', kw['package'])), 1, 0)
- parse_flags(ret, kw.get('uselib_store', kw['package'].upper()), kw.get('env', self.env))
- return ret
-
-@conf
-def check_cfg(self, *k, **kw):
- """
- for pkg-config mostly, but also all the -config tools
- conf.check_cfg(path='mpicc', args='--showme:compile --showme:link', package='', uselib_store='OPEN_MPI')
- conf.check_cfg(package='dbus-1', variables='system_bus_default_address session_bus_services_dir')
- """
-
- self.validate_cfg(kw)
- if 'msg' in kw:
- self.check_message_1(kw['msg'])
- ret = None
- try:
- ret = self.exec_cfg(kw)
- except Configure.ConfigurationError, e:
- if 'errmsg' in kw:
- self.check_message_2(kw['errmsg'], 'YELLOW')
- if 'mandatory' in kw and kw['mandatory']:
- if Logs.verbose > 1:
- raise
- else:
- self.fatal('the configuration failed (see %r)' % self.log.name)
- else:
- kw['success'] = ret
- if 'okmsg' in kw:
- self.check_message_2(self.ret_msg(kw['okmsg'], kw))
-
- return ret
-
-# the idea is the following: now that we are certain
-# that all the code here is only for c or c++, it is
-# easy to put all the logic in one function
-#
-# this should prevent code duplication (ita)
-
-# env: an optional environment (modified -> provide a copy)
-# compiler: cc or cxx - it tries to guess what is best
-# type: cprogram, cshlib, cstaticlib
-# code: a c code to execute
-# uselib_store: where to add the variables
-# uselib: parameters to use for building
-# define: define to set, like FOO in #define FOO, if not set, add /* #undef FOO */
-# execute: True or False - will return the result of the execution
-
-@conf
-def validate_c(self, kw):
- """validate the parameters for the test method"""
-
- if not 'env' in kw:
- kw['env'] = self.env.copy()
-
- env = kw['env']
- if not 'compiler' in kw:
- kw['compiler'] = 'cc'
- if env['CXX_NAME'] and Task.TaskBase.classes.get('cxx', None):
- kw['compiler'] = 'cxx'
- if not self.env['CXX']:
- self.fatal('a c++ compiler is required')
- else:
- if not self.env['CC']:
- self.fatal('a c compiler is required')
-
- if not 'type' in kw:
- kw['type'] = 'cprogram'
-
- assert not(kw['type'] != 'cprogram' and kw.get('execute', 0)), 'can only execute programs'
-
-
- #if kw['type'] != 'program' and kw.get('execute', 0):
- # raise ValueError, 'can only execute programs'
-
- def to_header(dct):
- if 'header_name' in dct:
- dct = Utils.to_list(dct['header_name'])
- return ''.join(['#include <%s>\n' % x for x in dct])
- return ''
-
- # set the file name
- if not 'compile_mode' in kw:
- kw['compile_mode'] = (kw['compiler'] == 'cxx') and 'cxx' or 'cc'
-
- if not 'compile_filename' in kw:
- kw['compile_filename'] = 'test.c' + ((kw['compile_mode'] == 'cxx') and 'pp' or '')
-
- #OSX
- if 'framework_name' in kw:
- try: TaskGen.task_gen.create_task_macapp
- except AttributeError: self.fatal('frameworks require the osx tool')
-
- fwkname = kw['framework_name']
- if not 'uselib_store' in kw:
- kw['uselib_store'] = fwkname.upper()
-
- if not kw.get('no_header', False):
- if not 'header_name' in kw:
- kw['header_name'] = []
- fwk = '%s/%s.h' % (fwkname, fwkname)
- if kw.get('remove_dot_h', None):
- fwk = fwk[:-2]
- kw['header_name'] = Utils.to_list(kw['header_name']) + [fwk]
-
- kw['msg'] = 'Checking for framework %s' % fwkname
- kw['framework'] = fwkname
- #kw['frameworkpath'] = set it yourself
-
- if 'function_name' in kw:
- fu = kw['function_name']
- if not 'msg' in kw:
- kw['msg'] = 'Checking for function %s' % fu
- kw['code'] = to_header(kw) + SNIP1 % fu
- if not 'uselib_store' in kw:
- kw['uselib_store'] = fu.upper()
- if not 'define_name' in kw:
- kw['define_name'] = self.have_define(fu)
-
- elif 'type_name' in kw:
- tu = kw['type_name']
- if not 'msg' in kw:
- kw['msg'] = 'Checking for type %s' % tu
- if not 'header_name' in kw:
- kw['header_name'] = 'stdint.h'
- kw['code'] = to_header(kw) + SNIP2 % {'type_name' : tu}
- if not 'define_name' in kw:
- kw['define_name'] = self.have_define(tu.upper())
-
- elif 'header_name' in kw:
- if not 'msg' in kw:
- kw['msg'] = 'Checking for header %s' % kw['header_name']
-
- l = Utils.to_list(kw['header_name'])
- assert len(l)>0, 'list of headers in header_name is empty'
-
- kw['code'] = to_header(kw) + SNIP3
-
- if not 'uselib_store' in kw:
- kw['uselib_store'] = l[0].upper()
-
- if not 'define_name' in kw:
- kw['define_name'] = self.have_define(l[0])
-
- if 'lib' in kw:
- if not 'msg' in kw:
- kw['msg'] = 'Checking for library %s' % kw['lib']
- if not 'uselib_store' in kw:
- kw['uselib_store'] = kw['lib'].upper()
-
- if 'staticlib' in kw:
- if not 'msg' in kw:
- kw['msg'] = 'Checking for static library %s' % kw['staticlib']
- if not 'uselib_store' in kw:
- kw['uselib_store'] = kw['staticlib'].upper()
-
- if 'fragment' in kw:
- # an additional code fragment may be provided to replace the predefined code
- # in custom headers
- kw['code'] = kw['fragment']
- if not 'msg' in kw:
- kw['msg'] = 'Checking for custom code'
- if not 'errmsg' in kw:
- kw['errmsg'] = 'no'
-
- for (flagsname,flagstype) in [('cxxflags','compiler'), ('cflags','compiler'), ('linkflags','linker')]:
- if flagsname in kw:
- if not 'msg' in kw:
- kw['msg'] = 'Checking for %s flags %s' % (flagstype, kw[flagsname])
- if not 'errmsg' in kw:
- kw['errmsg'] = 'no'
-
- if not 'execute' in kw:
- kw['execute'] = False
-
- if not 'errmsg' in kw:
- kw['errmsg'] = 'not found'
-
- if not 'okmsg' in kw:
- kw['okmsg'] = 'yes'
-
- if not 'code' in kw:
- kw['code'] = SNIP3
-
- if not kw.get('success'): kw['success'] = None
-
- assert 'msg' in kw, 'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c'
-
-@conf
-def post_check(self, *k, **kw):
- "set the variables after a test was run successfully"
-
- is_success = False
- if kw['execute']:
- if kw['success']:
- is_success = True
- else:
- is_success = (kw['success'] == 0)
-
- if 'define_name' in kw:
- if 'header_name' in kw or 'function_name' in kw or 'type_name' in kw or 'fragment' in kw:
- if kw['execute']:
- key = kw['success']
- if isinstance(key, str):
- if key:
- self.define(kw['define_name'], key, quote=kw.get('quote', 1))
- else:
- self.define_cond(kw['define_name'], True)
- else:
- self.define_cond(kw['define_name'], False)
- else:
- self.define_cond(kw['define_name'], is_success)
-
- if is_success and 'uselib_store' in kw:
- import cc, cxx
- for k in set(cc.g_cc_flag_vars).union(cxx.g_cxx_flag_vars):
- lk = k.lower()
- # inconsistency: includes -> CPPPATH
- if k == 'CPPPATH': lk = 'includes'
- if k == 'CXXDEFINES': lk = 'defines'
- if k == 'CCDEFINES': lk = 'defines'
- if lk in kw:
- val = kw[lk]
- # remove trailing slash
- if isinstance(val, str):
- val = val.rstrip(os.path.sep)
- self.env.append_unique(k + '_' + kw['uselib_store'], val)
-
-@conf
-def check(self, *k, **kw):
- # so this will be the generic function
- # it will be safer to use check_cxx or check_cc
- self.validate_c(kw)
- self.check_message_1(kw['msg'])
- ret = None
- try:
- ret = self.run_c_code(*k, **kw)
- except Configure.ConfigurationError, e:
- self.check_message_2(kw['errmsg'], 'YELLOW')
- if 'mandatory' in kw and kw['mandatory']:
- if Logs.verbose > 1:
- raise
- else:
- self.fatal('the configuration failed (see %r)' % self.log.name)
- else:
- kw['success'] = ret
- self.check_message_2(self.ret_msg(kw['okmsg'], kw))
-
- self.post_check(*k, **kw)
- if not kw.get('execute', False):
- return ret == 0
- return ret
-
-@conf
-def run_c_code(self, *k, **kw):
- test_f_name = kw['compile_filename']
-
- k = 0
- while k < 10000:
- # make certain to use a fresh folder - necessary for win32
- dir = os.path.join(self.blddir, '.conf_check_%d' % k)
-
- # if the folder already exists, remove it
- try:
- shutil.rmtree(dir)
- except OSError:
- pass
-
- try:
- os.stat(dir)
- except OSError:
- break
-
- k += 1
-
- try:
- os.makedirs(dir)
- except:
- self.fatal('cannot create a configuration test folder %r' % dir)
-
- try:
- os.stat(dir)
- except:
- self.fatal('cannot use the configuration test folder %r' % dir)
-
- bdir = os.path.join(dir, 'testbuild')
-
- if not os.path.exists(bdir):
- os.makedirs(bdir)
-
- env = kw['env']
-
- dest = open(os.path.join(dir, test_f_name), 'w')
- dest.write(kw['code'])
- dest.close()
-
- back = os.path.abspath('.')
-
- bld = Build.BuildContext()
- bld.log = self.log
- bld.all_envs.update(self.all_envs)
- bld.all_envs['Release'] = env
- bld.lst_variants = bld.all_envs.keys()
- bld.load_dirs(dir, bdir)
-
- os.chdir(dir)
-
- bld.rescan(bld.srcnode)
-
- if not 'features' in kw:
- # conf.check(features='cc cprogram pyext', ...)
- kw['features'] = [kw['compile_mode'], kw['type']] # "cprogram cc"
-
- o = bld(features=kw['features'], source=test_f_name, target='testprog')
-
- for k, v in kw.iteritems():
- setattr(o, k, v)
-
- self.log.write("==>\n%s\n<==\n" % kw['code'])
-
- # compile the program
- try:
- bld.compile()
- except Utils.WafError:
- ret = Utils.ex_stack()
- else:
- ret = 0
-
- # chdir before returning
- os.chdir(back)
-
- if ret:
- self.log.write('command returned %r' % ret)
- self.fatal(str(ret))
-
- # if we need to run the program, try to get its result
- # keep the name of the program to execute
- if kw['execute']:
- lastprog = o.link_task.outputs[0].abspath(env)
-
- args = Utils.to_list(kw.get('exec_args', []))
- proc = Utils.pproc.Popen([lastprog] + args, stdout=Utils.pproc.PIPE, stderr=Utils.pproc.PIPE)
- (out, err) = proc.communicate()
- w = self.log.write
- w(str(out))
- w('\n')
- w(str(err))
- w('\n')
- w('returncode %r' % proc.returncode)
- w('\n')
- if proc.returncode:
- self.fatal(Utils.ex_stack())
- ret = out
-
- return ret
-
-@conf
-def check_cxx(self, *k, **kw):
- kw['compiler'] = 'cxx'
- return self.check(*k, **kw)
-
-@conf
-def check_cc(self, *k, **kw):
- kw['compiler'] = 'cc'
- return self.check(*k, **kw)
-
-@conf
-def define(self, define, value, quote=1):
- """store a single define and its state into an internal list for later
- writing to a config header file. Value can only be
- a string or int; other types not supported. String
- values will appear properly quoted in the generated
- header file."""
- assert define and isinstance(define, str)
-
- # ordered_dict is for writing the configuration header in order
- tbl = self.env[DEFINES] or Utils.ordered_dict()
-
- # the user forgot to tell if the value is quoted or not
- if isinstance(value, str):
- if quote:
- tbl[define] = '"%s"' % repr('"'+value)[2:-1].replace('"', '\\"')
- else:
- tbl[define] = value
- elif isinstance(value, int):
- tbl[define] = value
- else:
- raise TypeError('define %r -> %r must be a string or an int' % (define, value))
-
- # add later to make reconfiguring faster
- self.env[DEFINES] = tbl
- self.env[define] = value # <- not certain this is necessary
-
-@conf
-def undefine(self, define):
- """store a single define and its state into an internal list
- for later writing to a config header file"""
- assert define and isinstance(define, str)
-
- tbl = self.env[DEFINES] or Utils.ordered_dict()
-
- value = UNDEFINED
- tbl[define] = value
-
- # add later to make reconfiguring faster
- self.env[DEFINES] = tbl
- self.env[define] = value
-
-@conf
-def define_cond(self, name, value):
- """Conditionally define a name.
- Formally equivalent to: if value: define(name, 1) else: undefine(name)"""
- if value:
- self.define(name, 1)
- else:
- self.undefine(name)
-
-@conf
-def is_defined(self, key):
- defines = self.env[DEFINES]
- if not defines:
- return False
- try:
- value = defines[key]
- except KeyError:
- return False
- else:
- return value != UNDEFINED
-
-@conf
-def get_define(self, define):
- "get the value of a previously stored define"
- try: return self.env[DEFINES][define]
- except KeyError: return None
-
-@conf
-def have_define(self, name):
- "prefix the define with 'HAVE_' and make sure it has valid characters."
- return self.__dict__.get('HAVE_PAT', 'HAVE_%s') % Utils.quote_define_name(name)
-
-@conf
-def write_config_header(self, configfile='', env='', guard='', top=False):
- "save the defines into a file"
- if not configfile: configfile = WAF_CONFIG_H
- waf_guard = guard or '_%s_WAF' % Utils.quote_define_name(configfile)
-
- # configfile -> absolute path
- # there is a good reason to concatenate first and to split afterwards
- if not env: env = self.env
- if top:
- diff = ''
- else:
- diff = Utils.diff_path(self.srcdir, self.curdir)
- full = os.sep.join([self.blddir, env.variant(), diff, configfile])
- full = os.path.normpath(full)
- (dir, base) = os.path.split(full)
-
- try: os.makedirs(dir)
- except: pass
-
- dest = open(full, 'w')
- dest.write('/* Configuration header created by Waf - do not edit */\n')
- dest.write('#ifndef %s\n#define %s\n\n' % (waf_guard, waf_guard))
-
- dest.write(self.get_config_header())
-
- # config files are not removed on "waf clean"
- env.append_unique(CFG_FILES, os.path.join(diff, configfile))
-
- dest.write('\n#endif /* %s */\n' % waf_guard)
- dest.close()
-
-@conf
-def get_config_header(self):
- """Fill-in the contents of the config header. Override when you need to write your own config header."""
- config_header = []
-
- tbl = self.env[DEFINES] or Utils.ordered_dict()
- for key in tbl.allkeys:
- value = tbl[key]
- if value is None:
- config_header.append('#define %s' % key)
- elif value is UNDEFINED:
- config_header.append('/* #undef %s */' % key)
- else:
- config_header.append('#define %s %s' % (key, value))
- return "\n".join(config_header)
-
-@conftest
-def find_cpp(conf):
- v = conf.env
- cpp = None
- if v['CPP']: cpp = v['CPP']
- elif 'CPP' in conf.environ: cpp = conf.environ['CPP']
- if not cpp: cpp = conf.find_program('cpp', var='CPP')
- if not cpp: cpp = v['CC']
- if not cpp: cpp = v['CXX']
- v['CPP'] = cpp
-
-@conftest
-def cc_add_flags(conf):
- conf.add_os_flags('CFLAGS', 'CCFLAGS')
- conf.add_os_flags('CPPFLAGS')
-
-@conftest
-def cxx_add_flags(conf):
- conf.add_os_flags('CXXFLAGS')
- conf.add_os_flags('CPPFLAGS')
-
-@conftest
-def link_add_flags(conf):
- conf.add_os_flags('LINKFLAGS')
- conf.add_os_flags('LDFLAGS', 'LINKFLAGS')
-
-@conftest
-def cc_load_tools(conf):
- conf.check_tool('cc')
-
-@conftest
-def cxx_load_tools(conf):
- conf.check_tool('cxx')
-
diff --git a/tools/wafadmin/Tools/cxx.py b/tools/wafadmin/Tools/cxx.py
deleted file mode 100644
index 052bcef92..000000000
--- a/tools/wafadmin/Tools/cxx.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005 (ita)
-
-"Base for c++ programs and libraries"
-
-import TaskGen, Task, Utils
-from Logs import debug
-import ccroot # <- do not remove
-from TaskGen import feature, before, extension, after
-
-g_cxx_flag_vars = [
-'CXXDEPS', 'FRAMEWORK', 'FRAMEWORKPATH',
-'STATICLIB', 'LIB', 'LIBPATH', 'LINKFLAGS', 'RPATH',
-'CXXFLAGS', 'CCFLAGS', 'CPPPATH', 'CPPFLAGS', 'CXXDEFINES']
-"main cpp variables"
-
-EXT_CXX = ['.cpp', '.cc', '.cxx', '.C', '.c++']
-
-g_cxx_type_vars=['CXXFLAGS', 'LINKFLAGS']
-
-# TODO remove in waf 1.6
-class cxx_taskgen(ccroot.ccroot_abstract):
- pass
-
-@feature('cxx')
-@before('apply_type_vars')
-@after('default_cc')
-def init_cxx(self):
- if not 'cc' in self.features:
- self.mappings['.c'] = TaskGen.task_gen.mappings['.cxx']
-
- self.p_flag_vars = set(self.p_flag_vars).union(g_cxx_flag_vars)
- self.p_type_vars = set(self.p_type_vars).union(g_cxx_type_vars)
-
- if not self.env['CXX_NAME']:
- raise Utils.WafError("At least one compiler (g++, ..) must be selected")
-
-@feature('cxx')
-@after('apply_incpaths')
-def apply_obj_vars_cxx(self):
- """after apply_incpaths for INC_PATHS"""
- env = self.env
- app = env.append_unique
- cxxpath_st = env['CPPPATH_ST']
-
- # local flags come first
- # set the user-defined includes paths
- for i in env['INC_PATHS']:
- app('_CXXINCFLAGS', cxxpath_st % i.bldpath(env))
- app('_CXXINCFLAGS', cxxpath_st % i.srcpath(env))
-
- # set the library include paths
- for i in env['CPPPATH']:
- app('_CXXINCFLAGS', cxxpath_st % i)
-
-@feature('cxx')
-@after('apply_lib_vars')
-def apply_defines_cxx(self):
- """after uselib is set for CXXDEFINES"""
- self.defines = getattr(self, 'defines', [])
- lst = self.to_list(self.defines) + self.to_list(self.env['CXXDEFINES'])
- milst = []
-
- # now process the local defines
- for defi in lst:
- if not defi in milst:
- milst.append(defi)
-
- # CXXDEFINES_USELIB
- libs = self.to_list(self.uselib)
- for l in libs:
- val = self.env['CXXDEFINES_'+l]
- if val: milst += self.to_list(val)
-
- self.env['DEFLINES'] = ["%s %s" % (x[0], Utils.trimquotes('='.join(x[1:]))) for x in [y.split('=') for y in milst]]
- y = self.env['CXXDEFINES_ST']
- self.env['_CXXDEFFLAGS'] = [y%x for x in milst]
-
-@extension(EXT_CXX)
-def cxx_hook(self, node):
- # create the compilation task: cpp or cc
- if getattr(self, 'obj_ext', None):
- obj_ext = self.obj_ext
- else:
- obj_ext = '_%d.o' % self.idx
-
- task = self.create_task('cxx', node, node.change_ext(obj_ext))
- try:
- self.compiled_tasks.append(task)
- except AttributeError:
- raise Utils.WafError('Have you forgotten to set the feature "cxx" on %s?' % str(self))
- return task
-
-cxx_str = '${CXX} ${CXXFLAGS} ${CPPFLAGS} ${_CXXINCFLAGS} ${_CXXDEFFLAGS} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT}'
-cls = Task.simple_task_type('cxx', cxx_str, color='GREEN', ext_out='.o', ext_in='.cxx', shell=False)
-cls.scan = ccroot.scan
-cls.vars.append('CXXDEPS')
-
-link_str = '${LINK_CXX} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath(env)} ${LINKFLAGS}'
-cls = Task.simple_task_type('cxx_link', link_str, color='YELLOW', ext_in='.o', ext_out='.bin', shell=False)
-cls.maxjobs = 1
-cls.install = Utils.nada
-
diff --git a/tools/wafadmin/Tools/d.py b/tools/wafadmin/Tools/d.py
deleted file mode 100644
index 602f5af1b..000000000
--- a/tools/wafadmin/Tools/d.py
+++ /dev/null
@@ -1,540 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Carlos Rafael Giani, 2007 (dv)
-# Thomas Nagy, 2007-2008 (ita)
-
-import os, sys, re, optparse
-import ccroot # <- leave this
-import TaskGen, Utils, Task, Configure, Logs, Build
-from Logs import debug, error
-from TaskGen import taskgen, feature, after, before, extension
-from Configure import conftest
-
-EXT_D = ['.d', '.di', '.D']
-D_METHS = ['apply_core', 'apply_vnum', 'apply_objdeps'] # additional d methods
-
-def filter_comments(filename):
- txt = Utils.readf(filename)
- buf = []
-
- i = 0
- max = len(txt)
- while i < max:
- c = txt[i]
- # skip a string
- if c == '"':
- i += 1
- c = ''
- while i < max:
- p = c
- c = txt[i]
- i += 1
- if i == max: return buf
- if c == '"':
- cnt = 0
- while i < cnt and i < max:
- #print "cntcnt = ", str(cnt), self.txt[self.i-2-cnt]
- if txt[i-2-cnt] == '\\': cnt+=1
- else: break
- #print "cnt is ", str(cnt)
- if (cnt%2)==0: break
- i += 1
- # skip a char
- elif c == "'":
- i += 1
- if i == max: return buf
- c = txt[i]
- if c == '\\':
- i += 1
- if i == max: return buf
- c = txt[i]
- if c == 'x':
- i += 2 # skip two chars
- elif c == 'u':
- i += 4 # skip unicode chars
- i += 1
- if i == max: return buf
- c = txt[i]
- if c != '\'': error("uh-oh, invalid character")
-
- # skip a comment
- elif c == '/':
- if i == max: break
- c = txt[i+1]
- # eat /+ +/ comments
- if c == '+':
- i += 1
- nesting = 1
- prev = 0
- while i < max:
- c = txt[i]
- if c == '+':
- prev = 1
- elif c == '/':
- if prev:
- nesting -= 1
- if nesting == 0: break
- else:
- if i < max:
- i += 1
- c = txt[i]
- if c == '+':
- nesting += 1
- else:
- return buf
- else:
- prev = 0
- i += 1
- # eat /* */ comments
- elif c == '*':
- i += 1
- while i < max:
- c = txt[i]
- if c == '*':
- prev = 1
- elif c == '/':
- if prev: break
- else:
- prev = 0
- i += 1
- # eat // comments
- elif c == '/':
- i += 1
- c = txt[i]
- while i < max and c != '\n':
- i += 1
- c = txt[i]
- # a valid char, add it to the buffer
- else:
- buf.append(c)
- i += 1
- return buf
-
-class d_parser(object):
- def __init__(self, env, incpaths):
- #self.code = ''
- #self.module = ''
- #self.imports = []
-
- self.allnames = []
-
- self.re_module = re.compile("module\s+([^;]+)")
- self.re_import = re.compile("import\s+([^;]+)")
- self.re_import_bindings = re.compile("([^:]+):(.*)")
- self.re_import_alias = re.compile("[^=]+=(.+)")
-
- self.env = env
-
- self.nodes = []
- self.names = []
-
- self.incpaths = incpaths
-
- def tryfind(self, filename):
- found = 0
- for n in self.incpaths:
- found = n.find_resource(filename.replace('.', '/') + '.d')
- if found:
- self.nodes.append(found)
- self.waiting.append(found)
- break
- if not found:
- if not filename in self.names:
- self.names.append(filename)
-
- def get_strings(self, code):
- #self.imports = []
- self.module = ''
- lst = []
-
- # get the module name (if present)
-
- mod_name = self.re_module.search(code)
- if mod_name:
- self.module = re.sub('\s+', '', mod_name.group(1)) # strip all whitespaces
-
- # go through the code, have a look at all import occurrences
-
- # first, lets look at anything beginning with "import" and ending with ";"
- import_iterator = self.re_import.finditer(code)
- if import_iterator:
- for import_match in import_iterator:
- import_match_str = re.sub('\s+', '', import_match.group(1)) # strip all whitespaces
-
- # does this end with an import bindings declaration?
- # (import bindings always terminate the list of imports)
- bindings_match = self.re_import_bindings.match(import_match_str)
- if bindings_match:
- import_match_str = bindings_match.group(1)
- # if so, extract the part before the ":" (since the module declaration(s) is/are located there)
-
- # split the matching string into a bunch of strings, separated by a comma
- matches = import_match_str.split(',')
-
- for match in matches:
- alias_match = self.re_import_alias.match(match)
- if alias_match:
- # is this an alias declaration? (alias = module name) if so, extract the module name
- match = alias_match.group(1)
-
- lst.append(match)
- return lst
-
- def start(self, node):
- self.waiting = [node]
- # while the stack is not empty, add the dependencies
- while self.waiting:
- nd = self.waiting.pop(0)
- self.iter(nd)
-
- def iter(self, node):
- path = node.abspath(self.env) # obtain the absolute path
- code = "".join(filter_comments(path)) # read the file and filter the comments
- names = self.get_strings(code) # obtain the import strings
- for x in names:
- # optimization
- if x in self.allnames: continue
- self.allnames.append(x)
-
- # for each name, see if it is like a node or not
- self.tryfind(x)
-
-def scan(self):
- "look for .d/.di the .d source need"
- env = self.env
- gruik = d_parser(env, env['INC_PATHS'])
- gruik.start(self.inputs[0])
-
- if Logs.verbose:
- debug('deps: nodes found for %s: %s %s' % (str(self.inputs[0]), str(gruik.nodes), str(gruik.names)))
- #debug("deps found for %s: %s" % (str(node), str(gruik.deps)), 'deps')
- return (gruik.nodes, gruik.names)
-
-def get_target_name(self):
- "for d programs and libs"
- v = self.env
- tp = 'program'
- for x in self.features:
- if x in ['dshlib', 'dstaticlib']:
- tp = x.lstrip('d')
- return v['D_%s_PATTERN' % tp] % self.target
-
-d_params = {
-'dflags': '',
-'importpaths':'',
-'libs':'',
-'libpaths':'',
-'generate_headers':False,
-}
-
-@feature('d')
-@before('apply_type_vars')
-def init_d(self):
- for x in d_params:
- setattr(self, x, getattr(self, x, d_params[x]))
-
-class d_taskgen(TaskGen.task_gen):
- def __init__(self, *k, **kw):
- TaskGen.task_gen.__init__(self, *k, **kw)
-
- # COMPAT
- if len(k) > 1:
- self.features.append('d' + k[1])
-
-# okay, we borrow a few methods from ccroot
-TaskGen.bind_feature('d', D_METHS)
-
-@feature('d')
-@before('apply_d_libs')
-def init_d(self):
- Utils.def_attrs(self,
- dflags='',
- importpaths='',
- libs='',
- libpaths='',
- uselib='',
- uselib_local='',
- generate_headers=False, # set to true if you want .di files as well as .o
- compiled_tasks=[],
- add_objects=[],
- link_task=None)
-
-@feature('d')
-@after('apply_d_link', 'init_d')
-@before('apply_vnum')
-def apply_d_libs(self):
- """after apply_link because of 'link_task'
- after default_cc because of the attribute 'uselib'"""
- env = self.env
-
- # 1. the case of the libs defined in the project (visit ancestors first)
- # the ancestors external libraries (uselib) will be prepended
- self.uselib = self.to_list(self.uselib)
- names = self.to_list(self.uselib_local)
-
- seen = set([])
- tmp = Utils.deque(names) # consume a copy of the list of names
- while tmp:
- lib_name = tmp.popleft()
- # visit dependencies only once
- if lib_name in seen:
- continue
-
- y = self.name_to_obj(lib_name)
- if not y:
- raise Utils.WafError('object %r was not found in uselib_local (required by %r)' % (lib_name, self.name))
- y.post()
- seen.add(lib_name)
-
- # object has ancestors to process (shared libraries): add them to the end of the list
- if getattr(y, 'uselib_local', None):
- lst = y.to_list(y.uselib_local)
- if 'dshlib' in y.features or 'dprogram' in y.features:
- lst = [x for x in lst if not 'dstaticlib' in self.name_to_obj(x).features]
- tmp.extend(lst)
-
- # link task and flags
- if getattr(y, 'link_task', None):
-
- link_name = y.target[y.target.rfind(os.sep) + 1:]
- if 'dstaticlib' in y.features or 'dshlib' in y.features:
- env.append_unique('DLINKFLAGS', env.DLIB_ST % link_name)
- env.append_unique('DLINKFLAGS', env.DLIBPATH_ST % y.link_task.outputs[0].parent.bldpath(env))
-
- # the order
- self.link_task.set_run_after(y.link_task)
-
- # for the recompilation
- dep_nodes = getattr(self.link_task, 'dep_nodes', [])
- self.link_task.dep_nodes = dep_nodes + y.link_task.outputs
-
- # add ancestors uselib too - but only propagate those that have no staticlib
- for v in self.to_list(y.uselib):
- if not v in self.uselib:
- self.uselib.insert(0, v)
-
- # if the library task generator provides 'export_incdirs', add to the include path
- # the export_incdirs must be a list of paths relative to the other library
- if getattr(y, 'export_incdirs', None):
- for x in self.to_list(y.export_incdirs):
- node = y.path.find_dir(x)
- if not node:
- raise Utils.WafError('object %r: invalid folder %r in export_incdirs' % (y.target, x))
- self.env.append_unique('INC_PATHS', node)
-
-@feature('dprogram', 'dshlib', 'dstaticlib')
-@after('apply_core')
-def apply_d_link(self):
- link = getattr(self, 'link', None)
- if not link:
- if 'dstaticlib' in self.features: link = 'static_link'
- else: link = 'd_link'
-
- outputs = [t.outputs[0] for t in self.compiled_tasks]
- self.link_task = self.create_task(link, outputs, self.path.find_or_declare(get_target_name(self)))
-
-@feature('d')
-@after('apply_core')
-def apply_d_vars(self):
- env = self.env
- dpath_st = env['DPATH_ST']
- lib_st = env['DLIB_ST']
- libpath_st = env['DLIBPATH_ST']
-
- importpaths = self.to_list(self.importpaths)
- libpaths = []
- libs = []
- uselib = self.to_list(self.uselib)
-
- for i in uselib:
- if env['DFLAGS_' + i]:
- env.append_unique('DFLAGS', env['DFLAGS_' + i])
-
- for x in self.features:
- if not x in ['dprogram', 'dstaticlib', 'dshlib']:
- continue
- x.lstrip('d')
- d_shlib_dflags = env['D_' + x + '_DFLAGS']
- if d_shlib_dflags:
- env.append_unique('DFLAGS', d_shlib_dflags)
-
- # add import paths
- for i in uselib:
- if env['DPATH_' + i]:
- for entry in self.to_list(env['DPATH_' + i]):
- if not entry in importpaths:
- importpaths.append(entry)
-
- # now process the import paths
- for path in importpaths:
- if os.path.isabs(path):
- env.append_unique('_DIMPORTFLAGS', dpath_st % path)
- else:
- node = self.path.find_dir(path)
- self.env.append_unique('INC_PATHS', node)
- env.append_unique('_DIMPORTFLAGS', dpath_st % node.srcpath(env))
- env.append_unique('_DIMPORTFLAGS', dpath_st % node.bldpath(env))
-
- # add library paths
- for i in uselib:
- if env['LIBPATH_' + i]:
- for entry in self.to_list(env['LIBPATH_' + i]):
- if not entry in libpaths:
- libpaths.append(entry)
- libpaths = self.to_list(self.libpaths) + libpaths
-
- # now process the library paths
- # apply same path manipulation as used with import paths
- for path in libpaths:
- if not os.path.isabs(path):
- node = self.path.find_resource(path)
- if not node:
- raise Utils.WafError('could not find libpath %r from %r' % (path, self))
- path = node.abspath(self.env)
-
- env.append_unique('DLINKFLAGS', libpath_st % path)
-
- # add libraries
- for i in uselib:
- if env['LIB_' + i]:
- for entry in self.to_list(env['LIB_' + i]):
- if not entry in libs:
- libs.append(entry)
- libs.extend(self.to_list(self.libs))
-
- # process user flags
- for flag in self.to_list(self.dflags):
- env.append_unique('DFLAGS', flag)
-
- # now process the libraries
- for lib in libs:
- env.append_unique('DLINKFLAGS', lib_st % lib)
-
- # add linker flags
- for i in uselib:
- dlinkflags = env['DLINKFLAGS_' + i]
- if dlinkflags:
- for linkflag in dlinkflags:
- env.append_unique('DLINKFLAGS', linkflag)
-
-@feature('dshlib')
-@after('apply_d_vars')
-def add_shlib_d_flags(self):
- for linkflag in self.env['D_shlib_LINKFLAGS']:
- self.env.append_unique('DLINKFLAGS', linkflag)
-
-@extension(EXT_D)
-def d_hook(self, node):
- # create the compilation task: cpp or cc
- task = self.create_task(self.generate_headers and 'd_with_header' or 'd')
- try: obj_ext = self.obj_ext
- except AttributeError: obj_ext = '_%d.o' % self.idx
-
- task.inputs = [node]
- task.outputs = [node.change_ext(obj_ext)]
- self.compiled_tasks.append(task)
-
- if self.generate_headers:
- header_node = node.change_ext(self.env['DHEADER_ext'])
- task.outputs += [header_node]
-
-d_str = '${D_COMPILER} ${DFLAGS} ${_DIMPORTFLAGS} ${D_SRC_F}${SRC} ${D_TGT_F}${TGT}'
-d_with_header_str = '${D_COMPILER} ${DFLAGS} ${_DIMPORTFLAGS} \
-${D_HDR_F}${TGT[1].bldpath(env)} \
-${D_SRC_F}${SRC} \
-${D_TGT_F}${TGT[0].bldpath(env)}'
-link_str = '${D_LINKER} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F}${TGT} ${DLINKFLAGS}'
-
-def override_exec(cls):
- """stupid dmd wants -of stuck to the file name"""
- old_exec = cls.exec_command
- def exec_command(self, *k, **kw):
- if isinstance(k[0], list):
- lst = k[0]
- for i in xrange(len(lst)):
- if lst[i] == '-of':
- del lst[i]
- lst[i] = '-of' + lst[i]
- break
- return old_exec(self, *k, **kw)
- cls.exec_command = exec_command
-
-cls = Task.simple_task_type('d', d_str, 'GREEN', before='static_link d_link', shell=False)
-cls.scan = scan
-override_exec(cls)
-
-cls = Task.simple_task_type('d_with_header', d_with_header_str, 'GREEN', before='static_link d_link', shell=False)
-override_exec(cls)
-
-cls = Task.simple_task_type('d_link', link_str, color='YELLOW', shell=False)
-override_exec(cls)
-
-# for feature request #104
-@taskgen
-def generate_header(self, filename, install_path):
- if not hasattr(self, 'header_lst'): self.header_lst = []
- self.meths.append('process_header')
- self.header_lst.append([filename, install_path])
-
-@before('apply_core')
-def process_header(self):
- env = self.env
- for i in getattr(self, 'header_lst', []):
- node = self.path.find_resource(i[0])
-
- if not node:
- raise Utils.WafError('file not found on d obj '+i[0])
-
- task = self.create_task('d_header')
- task.set_inputs(node)
- task.set_outputs(node.change_ext('.di'))
-
-d_header_str = '${D_COMPILER} ${D_HEADER} ${SRC}'
-Task.simple_task_type('d_header', d_header_str, color='BLUE', shell=False)
-
-@conftest
-def d_platform_flags(conf):
- v = conf.env
- binfmt = v.DEST_BINFMT or Utils.unversioned_sys_platform_to_binary_format(
- v.DEST_OS or Utils.unversioned_sys_platform())
- if binfmt == 'pe':
- v['D_program_PATTERN'] = '%s.exe'
- v['D_shlib_PATTERN'] = 'lib%s.dll'
- v['D_staticlib_PATTERN'] = 'lib%s.a'
- else:
- v['D_program_PATTERN'] = '%s'
- v['D_shlib_PATTERN'] = 'lib%s.so'
- v['D_staticlib_PATTERN'] = 'lib%s.a'
-
-# quick test #
-if __name__ == "__main__":
- #Logs.verbose = 2
-
- try: arg = sys.argv[1]
- except IndexError: arg = "file.d"
-
- print("".join(filter_comments(arg)))
- # TODO
- paths = ['.']
-
- #gruik = filter()
- #gruik.start(arg)
-
- #code = "".join(gruik.buf)
-
- #print "we have found the following code"
- #print code
-
- #print "now parsing"
- #print "-------------------------------------------"
- """
- parser_ = d_parser()
- parser_.start(arg)
-
- print "module: %s" % parser_.module
- print "imports: ",
- for imp in parser_.imports:
- print imp + " ",
- print
-"""
-
diff --git a/tools/wafadmin/Tools/dmd.py b/tools/wafadmin/Tools/dmd.py
deleted file mode 100644
index 9c7490844..000000000
--- a/tools/wafadmin/Tools/dmd.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Carlos Rafael Giani, 2007 (dv)
-# Thomas Nagy, 2008 (ita)
-
-import sys
-import Utils, ar
-from Configure import conftest
-
-@conftest
-def find_dmd(conf):
- conf.find_program(['dmd', 'ldc'], var='D_COMPILER', mandatory=True)
-
-@conftest
-def common_flags_ldc(conf):
- v = conf.env
- v['DFLAGS'] = ['-d-version=Posix']
- v['DLINKFLAGS'] = []
- v['D_shlib_DFLAGS'] = ['-relocation-model=pic']
-
-@conftest
-def common_flags_dmd(conf):
- v = conf.env
-
- # _DFLAGS _DIMPORTFLAGS
-
- # Compiler is dmd so 'gdc' part will be ignored, just
- # ensure key is there, so wscript can append flags to it
- v['DFLAGS'] = ['-version=Posix']
-
- v['D_SRC_F'] = ''
- v['D_TGT_F'] = ['-c', '-of']
- v['DPATH_ST'] = '-I%s' # template for adding import paths
-
- # linker
- v['D_LINKER'] = v['D_COMPILER']
- v['DLNK_SRC_F'] = ''
- v['DLNK_TGT_F'] = '-of'
-
- v['DLIB_ST'] = '-L-l%s' # template for adding libs
- v['DLIBPATH_ST'] = '-L-L%s' # template for adding libpaths
-
- # linker debug levels
- v['DFLAGS_OPTIMIZED'] = ['-O']
- v['DFLAGS_DEBUG'] = ['-g', '-debug']
- v['DFLAGS_ULTRADEBUG'] = ['-g', '-debug']
- v['DLINKFLAGS'] = ['-quiet']
-
- v['D_shlib_DFLAGS'] = ['-fPIC']
- v['D_shlib_LINKFLAGS'] = ['-L-shared']
-
- v['DHEADER_ext'] = '.di'
- v['D_HDR_F'] = ['-H', '-Hf']
-
-def detect(conf):
- conf.find_dmd()
- conf.check_tool('ar')
- conf.check_tool('d')
- conf.common_flags_dmd()
- conf.d_platform_flags()
-
- if conf.env.D_COMPILER.find('ldc') > -1:
- conf.common_flags_ldc()
-
diff --git a/tools/wafadmin/Tools/gas.py b/tools/wafadmin/Tools/gas.py
deleted file mode 100644
index c983b0a39..000000000
--- a/tools/wafadmin/Tools/gas.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2008 (ita)
-
-"as and gas"
-
-import os, sys
-import Task
-from TaskGen import extension, taskgen, after, before
-
-EXT_ASM = ['.s', '.S', '.asm', '.ASM', '.spp', '.SPP']
-
-as_str = '${AS} ${ASFLAGS} ${_ASINCFLAGS} ${SRC} -o ${TGT}'
-Task.simple_task_type('asm', as_str, 'PINK', ext_out='.o', shell=False)
-
-@extension(EXT_ASM)
-def asm_hook(self, node):
- # create the compilation task: cpp or cc
- try: obj_ext = self.obj_ext
- except AttributeError: obj_ext = '_%d.o' % self.idx
-
- task = self.create_task('asm', node, node.change_ext(obj_ext))
- self.compiled_tasks.append(task)
- self.meths.append('asm_incflags')
-
-@after('apply_obj_vars_cc')
-@after('apply_obj_vars_cxx')
-@before('apply_link')
-def asm_incflags(self):
- self.env.append_value('_ASINCFLAGS', self.env.ASINCFLAGS)
- var = ('cxx' in self.features) and 'CXX' or 'CC'
- self.env.append_value('_ASINCFLAGS', self.env['_%sINCFLAGS' % var])
-
-def detect(conf):
- conf.find_program(['gas', 'as'], var='AS')
- if not conf.env.AS: conf.env.AS = conf.env.CC
- #conf.env.ASFLAGS = ['-c'] <- may be necesary for .S files
-
diff --git a/tools/wafadmin/Tools/gcc.py b/tools/wafadmin/Tools/gcc.py
deleted file mode 100644
index 40a788e63..000000000
--- a/tools/wafadmin/Tools/gcc.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006-2008 (ita)
-# Ralf Habacker, 2006 (rh)
-# Yinon Ehrlich, 2009
-
-import os, sys
-import Configure, Options, Utils
-import ccroot, ar
-from Configure import conftest
-
-@conftest
-def find_gcc(conf):
- cc = conf.find_program(['gcc', 'cc'], var='CC', mandatory=True)
- cc = conf.cmd_to_list(cc)
- ccroot.get_cc_version(conf, cc, gcc=True)
- conf.env.CC_NAME = 'gcc'
- conf.env.CC = cc
-
-@conftest
-def gcc_common_flags(conf):
- v = conf.env
-
- # CPPFLAGS CCDEFINES _CCINCFLAGS _CCDEFFLAGS
-
- v['CCFLAGS_DEBUG'] = ['-g']
-
- v['CCFLAGS_RELEASE'] = ['-O2']
-
- v['CC_SRC_F'] = ''
- v['CC_TGT_F'] = ['-c', '-o', ''] # shell hack for -MD
- v['CPPPATH_ST'] = '-I%s' # template for adding include paths
-
- # linker
- if not v['LINK_CC']: v['LINK_CC'] = v['CC']
- v['CCLNK_SRC_F'] = ''
- v['CCLNK_TGT_F'] = ['-o', ''] # shell hack for -MD
-
- v['LIB_ST'] = '-l%s' # template for adding libs
- v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
- v['STATICLIB_ST'] = '-l%s'
- v['STATICLIBPATH_ST'] = '-L%s'
- v['RPATH_ST'] = '-Wl,-rpath,%s'
- v['CCDEFINES_ST'] = '-D%s'
-
- v['SONAME_ST'] = '-Wl,-h,%s'
- v['SHLIB_MARKER'] = '-Wl,-Bdynamic'
- v['STATICLIB_MARKER'] = '-Wl,-Bstatic'
- v['FULLSTATIC_MARKER'] = '-static'
-
- # program
- v['program_PATTERN'] = '%s'
-
- # shared library
- v['shlib_CCFLAGS'] = ['-fPIC', '-DPIC'] # avoid using -DPIC, -fPIC aleady defines the __PIC__ macro
- v['shlib_LINKFLAGS'] = ['-shared']
- v['shlib_PATTERN'] = 'lib%s.so'
-
- # static lib
- v['staticlib_LINKFLAGS'] = ['-Wl,-Bstatic']
- v['staticlib_PATTERN'] = 'lib%s.a'
-
- # osx stuff
- v['LINKFLAGS_MACBUNDLE'] = ['-bundle', '-undefined', 'dynamic_lookup']
- v['CCFLAGS_MACBUNDLE'] = ['-fPIC']
- v['macbundle_PATTERN'] = '%s.bundle'
-
-@conftest
-def gcc_modifier_win32(conf):
- v = conf.env
- v['program_PATTERN'] = '%s.exe'
-
- v['shlib_PATTERN'] = '%s.dll'
- v['implib_PATTERN'] = 'lib%s.dll.a'
- v['IMPLIB_ST'] = '-Wl,--out-implib,%s'
-
- dest_arch = v['DEST_CPU']
- if dest_arch == 'x86':
- # On 32-bit x86, gcc emits a message telling the -fPIC option is ignored on this arch, so we remove that flag.
- v['shlib_CCFLAGS'] = ['-DPIC'] # TODO this is a wrong define, we don't use -fPIC!
-
- v.append_value('shlib_CCFLAGS', '-DDLL_EXPORT') # TODO adding nonstandard defines like this DLL_EXPORT is not a good idea
-
- # Auto-import is enabled by default even without this option,
- # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages
- # that the linker emits otherwise.
- v.append_value('LINKFLAGS', '-Wl,--enable-auto-import')
-
-@conftest
-def gcc_modifier_cygwin(conf):
- gcc_modifier_win32(conf)
- v = conf.env
- v['shlib_PATTERN'] = 'cyg%s.dll'
- v.append_value('shlib_LINKFLAGS', '-Wl,--enable-auto-image-base')
-
-@conftest
-def gcc_modifier_darwin(conf):
- v = conf.env
- v['shlib_CCFLAGS'] = ['-fPIC', '-compatibility_version', '1', '-current_version', '1']
- v['shlib_LINKFLAGS'] = ['-dynamiclib']
- v['shlib_PATTERN'] = 'lib%s.dylib'
-
- v['staticlib_LINKFLAGS'] = []
-
- v['SHLIB_MARKER'] = ''
- v['STATICLIB_MARKER'] = ''
- v['SONAME_ST'] = ''
-
-@conftest
-def gcc_modifier_aix(conf):
- v = conf.env
- v['program_LINKFLAGS'] = ['-Wl,-brtl']
-
- v['shlib_LINKFLAGS'] = ['-shared','-Wl,-brtl,-bexpfull']
-
- v['SHLIB_MARKER'] = ''
-
-@conftest
-def gcc_modifier_platform(conf):
- # * set configurations specific for a platform.
- # * the destination platform is detected automatically by looking at the macros the compiler predefines,
- # and if it's not recognised, it fallbacks to sys.platform.
- dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform()
- gcc_modifier_func = globals().get('gcc_modifier_' + dest_os)
- if gcc_modifier_func:
- gcc_modifier_func(conf)
-
-def detect(conf):
- conf.find_gcc()
- conf.find_cpp()
- conf.find_ar()
- conf.gcc_common_flags()
- conf.gcc_modifier_platform()
- conf.cc_load_tools()
- conf.cc_add_flags()
- conf.link_add_flags()
-
diff --git a/tools/wafadmin/Tools/gdc.py b/tools/wafadmin/Tools/gdc.py
deleted file mode 100644
index 4d2a3216e..000000000
--- a/tools/wafadmin/Tools/gdc.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Carlos Rafael Giani, 2007 (dv)
-
-import sys
-import Utils, ar
-from Configure import conftest
-
-@conftest
-def find_gdc(conf):
- conf.find_program('gdc', var='D_COMPILER', mandatory=True)
-
-@conftest
-def common_flags_gdc(conf):
- v = conf.env
-
- # _DFLAGS _DIMPORTFLAGS
-
- # for mory info about the meaning of this dict see dmd.py
- v['DFLAGS'] = []
-
- v['D_SRC_F'] = ''
- v['D_TGT_F'] = ['-c', '-o', '']
- v['DPATH_ST'] = '-I%s' # template for adding import paths
-
- # linker
- v['D_LINKER'] = v['D_COMPILER']
- v['DLNK_SRC_F'] = ''
- v['DLNK_TGT_F'] = ['-o', '']
-
- v['DLIB_ST'] = '-l%s' # template for adding libs
- v['DLIBPATH_ST'] = '-L%s' # template for adding libpaths
-
- # debug levels
- v['DLINKFLAGS'] = []
- v['DFLAGS_OPTIMIZED'] = ['-O3']
- v['DFLAGS_DEBUG'] = ['-O0']
- v['DFLAGS_ULTRADEBUG'] = ['-O0']
-
- v['D_shlib_DFLAGS'] = []
- v['D_shlib_LINKFLAGS'] = ['-shared']
-
- v['DHEADER_ext'] = '.di'
- v['D_HDR_F'] = '-fintfc -fintfc-file='
-
-def detect(conf):
- conf.find_gdc()
- conf.check_tool('ar')
- conf.check_tool('d')
- conf.common_flags_gdc()
- conf.d_platform_flags()
-
diff --git a/tools/wafadmin/Tools/gnu_dirs.py b/tools/wafadmin/Tools/gnu_dirs.py
deleted file mode 100644
index 856e4a720..000000000
--- a/tools/wafadmin/Tools/gnu_dirs.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Ali Sabil, 2007
-
-"""
-To use this module do not forget to call
-opt.tool_options('gnu_dirs')
-AND
-conf.check_tool('gnu_dirs')
-
-Add options for the standard GNU directories, this tool will add the options
-found in autotools, and will update the environment with the following
-installation variables:
-
- * PREFIX : architecture-independent files [/usr/local]
- * EXEC_PREFIX : architecture-dependent files [PREFIX]
- * BINDIR : user executables [EXEC_PREFIX/bin]
- * SBINDIR : user executables [EXEC_PREFIX/sbin]
- * LIBEXECDIR : program executables [EXEC_PREFIX/libexec]
- * SYSCONFDIR : read-only single-machine data [PREFIX/etc]
- * SHAREDSTATEDIR : modifiable architecture-independent data [PREFIX/com]
- * LOCALSTATEDIR : modifiable single-machine data [PREFIX/var]
- * LIBDIR : object code libraries [EXEC_PREFIX/lib]
- * INCLUDEDIR : C header files [PREFIX/include]
- * OLDINCLUDEDIR : C header files for non-gcc [/usr/include]
- * DATAROOTDIR : read-only arch.-independent data root [PREFIX/share]
- * DATADIR : read-only architecture-independent data [DATAROOTDIR]
- * INFODIR : info documentation [DATAROOTDIR/info]
- * LOCALEDIR : locale-dependent data [DATAROOTDIR/locale]
- * MANDIR : man documentation [DATAROOTDIR/man]
- * DOCDIR : documentation root [DATAROOTDIR/doc/telepathy-glib]
- * HTMLDIR : html documentation [DOCDIR]
- * DVIDIR : dvi documentation [DOCDIR]
- * PDFDIR : pdf documentation [DOCDIR]
- * PSDIR : ps documentation [DOCDIR]
-"""
-
-import Utils, Options
-
-_options = [x.split(', ') for x in '''
-bindir, user executables, ${EXEC_PREFIX}/bin
-sbindir, system admin executables, ${EXEC_PREFIX}/sbin
-libexecdir, program executables, ${EXEC_PREFIX}/libexec
-sysconfdir, read-only single-machine data, ${PREFIX}/etc
-sharedstatedir, modifiable architecture-independent data, ${PREFIX}/com
-localstatedir, modifiable single-machine data, ${PREFIX}/var
-libdir, object code libraries, ${EXEC_PREFIX}/lib
-includedir, C header files, ${PREFIX}/include
-oldincludedir, C header files for non-gcc, /usr/include
-datarootdir, read-only arch.-independent data root, ${PREFIX}/share
-datadir, read-only architecture-independent data, ${DATAROOTDIR}
-infodir, info documentation, ${DATAROOTDIR}/info
-localedir, locale-dependent data, ${DATAROOTDIR}/locale
-mandir, man documentation, ${DATAROOTDIR}/man
-docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE}
-htmldir, html documentation, ${DOCDIR}
-dvidir, dvi documentation, ${DOCDIR}
-pdfdir, pdf documentation, ${DOCDIR}
-psdir, ps documentation, ${DOCDIR}
-'''.split('\n') if x]
-
-def detect(conf):
- def get_param(varname, default):
- return getattr(Options.options, varname, '') or default
-
- env = conf.env
- env['EXEC_PREFIX'] = get_param('EXEC_PREFIX', env['PREFIX'])
- env['PACKAGE'] = Utils.g_module.APPNAME
-
- complete = False
- iter = 0
- while not complete and iter < len(_options) + 1:
- iter += 1
- complete = True
- for name, help, default in _options:
- name = name.upper()
- if not env[name]:
- try:
- env[name] = Utils.subst_vars(get_param(name, default), env)
- except TypeError:
- complete = False
- if not complete:
- lst = [name for name, _, _ in _options if not env[name.upper()]]
- raise Utils.WafError('Variable substitution failure %r' % lst)
-
-def set_options(opt):
-
- inst_dir = opt.add_option_group('Installation directories',
-'By default, "waf install" will put the files in\
- "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\
- than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"')
-
- for k in ('--prefix', '--destdir'):
- option = opt.parser.get_option(k)
- if option:
- opt.parser.remove_option(k)
- inst_dir.add_option(option)
-
- inst_dir.add_option('--exec-prefix',
- help = 'installation prefix [Default: ${PREFIX}]',
- default = '',
- dest = 'EXEC_PREFIX')
-
- dirs_options = opt.add_option_group('Pre-defined installation directories', '')
-
- for name, help, default in _options:
- option_name = '--' + name
- str_default = default
- str_help = '%s [Default: %s]' % (help, str_default)
- dirs_options.add_option(option_name, help=str_help, default='', dest=name.upper())
-
diff --git a/tools/wafadmin/Tools/gob2.py b/tools/wafadmin/Tools/gob2.py
deleted file mode 100644
index 00aaa32ac..000000000
--- a/tools/wafadmin/Tools/gob2.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Ali Sabil, 2007
-
-import TaskGen
-
-TaskGen.declare_chain(
- name = 'gob2',
- rule = '${GOB2} -o ${TGT[0].bld_dir(env)} ${GOB2FLAGS} ${SRC}',
- ext_in = '.gob',
- ext_out = '.c'
-)
-
-def detect(conf):
- gob2 = conf.find_program('gob2', var='GOB2', mandatory=True)
- conf.env['GOB2'] = gob2
- conf.env['GOB2FLAGS'] = ''
-
diff --git a/tools/wafadmin/Tools/gxx.py b/tools/wafadmin/Tools/gxx.py
deleted file mode 100644
index 133e1164f..000000000
--- a/tools/wafadmin/Tools/gxx.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006 (ita)
-# Ralf Habacker, 2006 (rh)
-# Yinon Ehrlich, 2009
-
-import os, sys
-import Configure, Options, Utils
-import ccroot, ar
-from Configure import conftest
-
-@conftest
-def find_gxx(conf):
- cxx = conf.find_program(['g++', 'c++'], var='CXX', mandatory=True)
- cxx = conf.cmd_to_list(cxx)
- ccroot.get_cc_version(conf, cxx, gcc=True)
- conf.env.CXX_NAME = 'gcc'
- conf.env.CXX = cxx
-
-@conftest
-def gxx_common_flags(conf):
- v = conf.env
-
- # CPPFLAGS CXXDEFINES _CXXINCFLAGS _CXXDEFFLAGS
- v['CXXFLAGS_DEBUG'] = ['-g']
- v['CXXFLAGS_RELEASE'] = ['-O2']
-
- v['CXX_SRC_F'] = ''
- v['CXX_TGT_F'] = ['-c', '-o', ''] # shell hack for -MD
- v['CPPPATH_ST'] = '-I%s' # template for adding include paths
-
- # linker
- if not v['LINK_CXX']: v['LINK_CXX'] = v['CXX']
- v['CXXLNK_SRC_F'] = ''
- v['CXXLNK_TGT_F'] = ['-o', ''] # shell hack for -MD
-
- v['LIB_ST'] = '-l%s' # template for adding libs
- v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
- v['STATICLIB_ST'] = '-l%s'
- v['STATICLIBPATH_ST'] = '-L%s'
- v['RPATH_ST'] = '-Wl,-rpath,%s'
- v['CXXDEFINES_ST'] = '-D%s'
-
- v['SONAME_ST'] = '-Wl,-h,%s'
- v['SHLIB_MARKER'] = '-Wl,-Bdynamic'
- v['STATICLIB_MARKER'] = '-Wl,-Bstatic'
- v['FULLSTATIC_MARKER'] = '-static'
-
- # program
- v['program_PATTERN'] = '%s'
-
- # shared library
- v['shlib_CXXFLAGS'] = ['-fPIC', '-DPIC'] # avoid using -DPIC, -fPIC aleady defines the __PIC__ macro
- v['shlib_LINKFLAGS'] = ['-shared']
- v['shlib_PATTERN'] = 'lib%s.so'
-
- # static lib
- v['staticlib_LINKFLAGS'] = ['-Wl,-Bstatic']
- v['staticlib_PATTERN'] = 'lib%s.a'
-
- # osx stuff
- v['LINKFLAGS_MACBUNDLE'] = ['-bundle', '-undefined', 'dynamic_lookup']
- v['CCFLAGS_MACBUNDLE'] = ['-fPIC']
- v['macbundle_PATTERN'] = '%s.bundle'
-
-@conftest
-def gxx_modifier_win32(conf):
- v = conf.env
- v['program_PATTERN'] = '%s.exe'
-
- v['shlib_PATTERN'] = '%s.dll'
- v['implib_PATTERN'] = 'lib%s.dll.a'
- v['IMPLIB_ST'] = '-Wl,--out-implib,%s'
-
- dest_arch = v['DEST_CPU']
- if dest_arch == 'x86':
- # On 32-bit x86, gcc emits a message telling the -fPIC option is ignored on this arch, so we remove that flag.
- v['shlib_CXXFLAGS'] = ['-DPIC'] # TODO this is a wrong define, we don't use -fPIC!
-
- v.append_value('shlib_CXXFLAGS', '-DDLL_EXPORT') # TODO adding nonstandard defines like this DLL_EXPORT is not a good idea
-
- # Auto-import is enabled by default even without this option,
- # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages
- # that the linker emits otherwise.
- v.append_value('LINKFLAGS', '-Wl,--enable-auto-import')
-
-@conftest
-def gxx_modifier_cygwin(conf):
- gxx_modifier_win32(conf)
- v = conf.env
- v['shlib_PATTERN'] = 'cyg%s.dll'
- v.append_value('shlib_LINKFLAGS', '-Wl,--enable-auto-image-base')
-
-@conftest
-def gxx_modifier_darwin(conf):
- v = conf.env
- v['shlib_CXXFLAGS'] = ['-fPIC', '-compatibility_version', '1', '-current_version', '1']
- v['shlib_LINKFLAGS'] = ['-dynamiclib']
- v['shlib_PATTERN'] = 'lib%s.dylib'
-
- v['staticlib_LINKFLAGS'] = []
-
- v['SHLIB_MARKER'] = ''
- v['STATICLIB_MARKER'] = ''
- v['SONAME_ST'] = ''
-
-@conftest
-def gxx_modifier_aix(conf):
- v = conf.env
- v['program_LINKFLAGS'] = ['-Wl,-brtl']
-
- v['shlib_LINKFLAGS'] = ['-shared', '-Wl,-brtl,-bexpfull']
-
- v['SHLIB_MARKER'] = ''
-
-@conftest
-def gxx_modifier_platform(conf):
- # * set configurations specific for a platform.
- # * the destination platform is detected automatically by looking at the macros the compiler predefines,
- # and if it's not recognised, it fallbacks to sys.platform.
- dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform()
- gxx_modifier_func = globals().get('gxx_modifier_' + dest_os)
- if gxx_modifier_func:
- gxx_modifier_func(conf)
-
-def detect(conf):
- conf.find_gxx()
- conf.find_cpp()
- conf.find_ar()
- conf.gxx_common_flags()
- conf.gxx_modifier_platform()
- conf.cxx_load_tools()
- conf.cxx_add_flags()
-
diff --git a/tools/wafadmin/Tools/icc.py b/tools/wafadmin/Tools/icc.py
deleted file mode 100644
index 9c9a92602..000000000
--- a/tools/wafadmin/Tools/icc.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Stian Selnes, 2008
-# Thomas Nagy 2009
-
-import os, sys
-import Configure, Options, Utils
-import ccroot, ar, gcc
-from Configure import conftest
-
-@conftest
-def find_icc(conf):
- if sys.platform == 'cygwin':
- conf.fatal('The Intel compiler does not work on Cygwin')
-
- v = conf.env
- cc = None
- if v['CC']: cc = v['CC']
- elif 'CC' in conf.environ: cc = conf.environ['CC']
- if not cc: cc = conf.find_program('icc', var='CC')
- if not cc: cc = conf.find_program('ICL', var='CC')
- if not cc: conf.fatal('Intel C Compiler (icc) was not found')
- cc = conf.cmd_to_list(cc)
-
- ccroot.get_cc_version(conf, cc, icc=True)
- v['CC'] = cc
- v['CC_NAME'] = 'icc'
-
-detect = '''
-find_icc
-find_ar
-gcc_common_flags
-gcc_modifier_platform
-cc_load_tools
-cc_add_flags
-link_add_flags
-'''
diff --git a/tools/wafadmin/Tools/icpc.py b/tools/wafadmin/Tools/icpc.py
deleted file mode 100644
index 726e3a497..000000000
--- a/tools/wafadmin/Tools/icpc.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy 2009
-
-import os, sys
-import Configure, Options, Utils
-import ccroot, ar, gxx
-from Configure import conftest
-
-@conftest
-def find_icpc(conf):
- if sys.platform == 'cygwin':
- conf.fatal('The Intel compiler does not work on Cygwin')
-
- v = conf.env
- cxx = None
- if v['CXX']: cxx = v['CXX']
- elif 'CXX' in conf.environ: cxx = conf.environ['CXX']
- if not cxx: cxx = conf.find_program('icpc', var='CXX')
- if not cxx: conf.fatal('Intel C++ Compiler (icpc) was not found')
- cxx = conf.cmd_to_list(cxx)
-
- ccroot.get_cc_version(conf, cxx, icc=True)
- v['CXX'] = cxx
- v['CXX_NAME'] = 'icc'
-
-detect = '''
-find_icpc
-find_ar
-gxx_common_flags
-gxx_modifier_platform
-cxx_load_tools
-cxx_add_flags
-'''
diff --git a/tools/wafadmin/Tools/intltool.py b/tools/wafadmin/Tools/intltool.py
deleted file mode 100644
index deb8f4a63..000000000
--- a/tools/wafadmin/Tools/intltool.py
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006 (ita)
-
-"intltool support"
-
-import os, re
-import Configure, TaskGen, Task, Utils, Runner, Options, Build, config_c
-from TaskGen import feature, before, taskgen
-from Logs import error
-
-"""
-Usage:
-
-bld(features='intltool_in', source='a.po b.po', podir='po', cache='.intlcache', flags='')
-
-"""
-
-class intltool_in_taskgen(TaskGen.task_gen):
- """deprecated"""
- def __init__(self, *k, **kw):
- TaskGen.task_gen.__init__(self, *k, **kw)
-
-@before('apply_core')
-@feature('intltool_in')
-def iapply_intltool_in_f(self):
- try: self.meths.remove('apply_core')
- except ValueError: pass
-
- for i in self.to_list(self.source):
- node = self.path.find_resource(i)
-
- podir = getattr(self, 'podir', 'po')
- podirnode = self.path.find_dir(podir)
- if not podirnode:
- error("could not find the podir %r" % podir)
- continue
-
- cache = getattr(self, 'intlcache', '.intlcache')
- self.env['INTLCACHE'] = os.path.join(self.path.bldpath(self.env), podir, cache)
- self.env['INTLPODIR'] = podirnode.srcpath(self.env)
- self.env['INTLFLAGS'] = getattr(self, 'flags', ['-q', '-u', '-c'])
-
- task = self.create_task('intltool', node, node.change_ext(''))
- task.install_path = self.install_path
-
-class intltool_po_taskgen(TaskGen.task_gen):
- """deprecated"""
- def __init__(self, *k, **kw):
- TaskGen.task_gen.__init__(self, *k, **kw)
-
-
-@feature('intltool_po')
-def apply_intltool_po(self):
- try: self.meths.remove('apply_core')
- except ValueError: pass
-
- self.default_install_path = '${LOCALEDIR}'
- appname = getattr(self, 'appname', 'set_your_app_name')
- podir = getattr(self, 'podir', '')
-
- def install_translation(task):
- out = task.outputs[0]
- filename = out.name
- (langname, ext) = os.path.splitext(filename)
- inst_file = langname + os.sep + 'LC_MESSAGES' + os.sep + appname + '.mo'
- self.bld.install_as(os.path.join(self.install_path, inst_file), out, self.env, self.chmod)
-
- linguas = self.path.find_resource(os.path.join(podir, 'LINGUAS'))
- if linguas:
- # scan LINGUAS file for locales to process
- file = open(linguas.abspath())
- langs = []
- for line in file.readlines():
- # ignore lines containing comments
- if not line.startswith('#'):
- langs += line.split()
- file.close()
- re_linguas = re.compile('[-a-zA-Z_@.]+')
- for lang in langs:
- # Make sure that we only process lines which contain locales
- if re_linguas.match(lang):
- node = self.path.find_resource(os.path.join(podir, re_linguas.match(lang).group() + '.po'))
- task = self.create_task('po')
- task.set_inputs(node)
- task.set_outputs(node.change_ext('.mo'))
- if self.bld.is_install: task.install = install_translation
- else:
- Utils.pprint('RED', "Error no LINGUAS file found in po directory")
-
-Task.simple_task_type('po', '${POCOM} -o ${TGT} ${SRC}', color='BLUE', shell=False)
-Task.simple_task_type('intltool',
- '${INTLTOOL} ${INTLFLAGS} ${INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}',
- color='BLUE', after="cc_link cxx_link", shell=False)
-
-def detect(conf):
- pocom = conf.find_program('msgfmt')
- if not pocom:
- # if msgfmt should not be mandatory, catch the thrown exception in your wscript
- conf.fatal('The program msgfmt (gettext) is mandatory!')
- conf.env['POCOM'] = pocom
-
- # NOTE: it is possible to set INTLTOOL in the environment, but it must not have spaces in it
-
- intltool = conf.find_program('intltool-merge', var='INTLTOOL')
- if not intltool:
- # if intltool-merge should not be mandatory, catch the thrown exception in your wscript
- if Options.platform == 'win32':
- perl = conf.find_program('perl', var='PERL')
- if not perl:
- conf.fatal('The program perl (required by intltool) could not be found')
-
- intltooldir = Configure.find_file('intltool-merge', os.environ['PATH'].split(os.pathsep))
- if not intltooldir:
- conf.fatal('The program intltool-merge (intltool, gettext-devel) is mandatory!')
-
- conf.env['INTLTOOL'] = Utils.to_list(conf.env['PERL']) + [intltooldir + os.sep + 'intltool-merge']
- conf.check_message('intltool', '', True, ' '.join(conf.env['INTLTOOL']))
- else:
- conf.fatal('The program intltool-merge (intltool, gettext-devel) is mandatory!')
-
- def getstr(varname):
- return getattr(Options.options, varname, '')
-
- prefix = conf.env['PREFIX']
- datadir = getstr('datadir')
- if not datadir: datadir = os.path.join(prefix,'share')
-
- conf.define('LOCALEDIR', os.path.join(datadir, 'locale'))
- conf.define('DATADIR', datadir)
-
- if conf.env['CC'] or conf.env['CXX']:
- # Define to 1 if <locale.h> is present
- conf.check(header_name='locale.h')
-
-def set_options(opt):
- opt.add_option('--want-rpath', type='int', default=1, dest='want_rpath', help='set rpath to 1 or 0 [Default 1]')
- opt.add_option('--datadir', type='string', default='', dest='datadir', help='read-only application data')
-
diff --git a/tools/wafadmin/Tools/libtool.py b/tools/wafadmin/Tools/libtool.py
deleted file mode 100644
index a9b56894c..000000000
--- a/tools/wafadmin/Tools/libtool.py
+++ /dev/null
@@ -1,330 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Matthias Jahn, 2008, jahn matthias ath freenet punto de
-# Thomas Nagy, 2008 (ita)
-
-import sys, re, os, optparse
-
-import TaskGen, Task, Utils, preproc
-from Logs import error, debug, warn
-from TaskGen import taskgen, after, before, feature
-
-REVISION="0.1.3"
-
-"""
-if you want to use the code here, you must use something like this:
-obj = obj.create(...)
-obj.features.append("libtool")
-obj.vnum = "1.2.3" # optional, but versioned libraries are common
-"""
-
-# fake libtool files
-fakelibtool_vardeps = ['CXX', 'PREFIX']
-def fakelibtool_build(task):
- # Writes a .la file, used by libtool
- env = task.env
- dest = open(task.outputs[0].abspath(env), 'w')
- sname = task.inputs[0].name
- fu = dest.write
- fu("# Generated by ltmain.sh - GNU libtool 1.5.18 - (pwn3d by BKsys II code name WAF)\n")
- if env['vnum']:
- nums = env['vnum'].split('.')
- libname = task.inputs[0].name
- name3 = libname+'.'+env['vnum']
- name2 = libname+'.'+nums[0]
- name1 = libname
- fu("dlname='%s'\n" % name2)
- strn = " ".join([name3, name2, name1])
- fu("library_names='%s'\n" % (strn) )
- else:
- fu("dlname='%s'\n" % sname)
- fu("library_names='%s %s %s'\n" % (sname, sname, sname) )
- fu("old_library=''\n")
- vars = ' '.join(env['libtoolvars']+env['LINKFLAGS'])
- fu("dependency_libs='%s'\n" % vars)
- fu("current=0\n")
- fu("age=0\nrevision=0\ninstalled=yes\nshouldnotlink=no\n")
- fu("dlopen=''\ndlpreopen=''\n")
- fu("libdir='%s/lib'\n" % env['PREFIX'])
- dest.close()
- return 0
-
-def read_la_file(path):
- sp = re.compile(r'^([^=]+)=\'(.*)\'$')
- dc={}
- file = open(path, "r")
- for line in file.readlines():
- try:
- #print sp.split(line.strip())
- _, left, right, _ = sp.split(line.strip())
- dc[left]=right
- except ValueError:
- pass
- file.close()
- return dc
-
-@feature("libtool")
-@after('apply_link')
-def apply_link_libtool(self):
- if self.type != 'program':
- linktask = self.link_task
- self.latask = self.create_task('fakelibtool', linktask.outputs, linktask.outputs[0].change_ext('.la'))
-
- if self.bld.is_install:
- self.bld.install_files('${PREFIX}/lib', linktask.outputs[0], self.env)
-
-@feature("libtool")
-@before('apply_core')
-def apply_libtool(self):
- self.env['vnum']=self.vnum
-
- paths=[]
- libs=[]
- libtool_files=[]
- libtool_vars=[]
-
- for l in self.env['LINKFLAGS']:
- if l[:2]=='-L':
- paths.append(l[2:])
- elif l[:2]=='-l':
- libs.append(l[2:])
-
- for l in libs:
- for p in paths:
- dict = read_la_file(p+'/lib'+l+'.la')
- linkflags2 = dict.get('dependency_libs', '')
- for v in linkflags2.split():
- if v.endswith('.la'):
- libtool_files.append(v)
- libtool_vars.append(v)
- continue
- self.env.append_unique('LINKFLAGS', v)
- break
-
- self.env['libtoolvars']=libtool_vars
-
- while libtool_files:
- file = libtool_files.pop()
- dict = read_la_file(file)
- for v in dict['dependency_libs'].split():
- if v[-3:] == '.la':
- libtool_files.append(v)
- continue
- self.env.append_unique('LINKFLAGS', v)
-
-Task.task_type_from_func('fakelibtool', vars=fakelibtool_vardeps, func=fakelibtool_build, color='BLUE', after="cc_link cxx_link static_link")
-
-class libtool_la_file:
- def __init__ (self, la_filename):
- self.__la_filename = la_filename
- #remove path and .la suffix
- self.linkname = str(os.path.split(la_filename)[-1])[:-3]
- if self.linkname.startswith("lib"):
- self.linkname = self.linkname[3:]
- # The name that we can dlopen(3).
- self.dlname = None
- # Names of this library
- self.library_names = None
- # The name of the static archive.
- self.old_library = None
- # Libraries that this one depends upon.
- self.dependency_libs = None
- # Version information for libIlmImf.
- self.current = None
- self.age = None
- self.revision = None
- # Is this an already installed library?
- self.installed = None
- # Should we warn about portability when linking against -modules?
- self.shouldnotlink = None
- # Files to dlopen/dlpreopen
- self.dlopen = None
- self.dlpreopen = None
- # Directory that this library needs to be installed in:
- self.libdir = '/usr/lib'
- if not self.__parse():
- raise "file %s not found!!" %(la_filename)
-
- def __parse(self):
- "Retrieve the variables from a file"
- if not os.path.isfile(self.__la_filename): return 0
- la_file=open(self.__la_filename, 'r')
- for line in la_file:
- ln = line.strip()
- if not ln: continue
- if ln[0]=='#': continue
- (key, value) = str(ln).split('=', 1)
- key = key.strip()
- value = value.strip()
- if value == "no": value = False
- elif value == "yes": value = True
- else:
- try: value = int(value)
- except ValueError: value = value.strip("'")
- setattr(self, key, value)
- la_file.close()
- return 1
-
- def get_libs(self):
- """return linkflags for this lib"""
- libs = []
- if self.dependency_libs:
- libs = str(self.dependency_libs).strip().split()
- if libs == None:
- libs = []
- # add la lib and libdir
- libs.insert(0, "-l%s" % self.linkname.strip())
- libs.insert(0, "-L%s" % self.libdir.strip())
- return libs
-
- def __str__(self):
- return '''\
-dlname = "%(dlname)s"
-library_names = "%(library_names)s"
-old_library = "%(old_library)s"
-dependency_libs = "%(dependency_libs)s"
-version = %(current)s.%(age)s.%(revision)s
-installed = "%(installed)s"
-shouldnotlink = "%(shouldnotlink)s"
-dlopen = "%(dlopen)s"
-dlpreopen = "%(dlpreopen)s"
-libdir = "%(libdir)s"''' % self.__dict__
-
-class libtool_config:
- def __init__ (self, la_filename):
- self.__libtool_la_file = libtool_la_file(la_filename)
- tmp = self.__libtool_la_file
- self.__version = [int(tmp.current), int(tmp.age), int(tmp.revision)]
- self.__sub_la_files = []
- self.__sub_la_files.append(la_filename)
- self.__libs = None
-
- def __cmp__(self, other):
- """make it compareable with X.Y.Z versions (Y and Z are optional)"""
- if not other:
- return 1
- othervers = [int(s) for s in str(other).split(".")]
- selfvers = self.__version
- return cmp(selfvers, othervers)
-
- def __str__(self):
- return "\n".join([
- str(self.__libtool_la_file),
- ' '.join(self.__libtool_la_file.get_libs()),
- '* New getlibs:',
- ' '.join(self.get_libs())
- ])
-
- def __get_la_libs(self, la_filename):
- return libtool_la_file(la_filename).get_libs()
-
- def get_libs(self):
- """return the complete uniqe linkflags that do not
- contain .la files anymore"""
- libs_list = list(self.__libtool_la_file.get_libs())
- libs_map = {}
- while len(libs_list) > 0:
- entry = libs_list.pop(0)
- if entry:
- if str(entry).endswith(".la"):
- ## prevents duplicate .la checks
- if entry not in self.__sub_la_files:
- self.__sub_la_files.append(entry)
- libs_list.extend(self.__get_la_libs(entry))
- else:
- libs_map[entry]=1
- self.__libs = libs_map.keys()
- return self.__libs
-
- def get_libs_only_L(self):
- if not self.__libs: self.get_libs()
- libs = self.__libs
- libs = [s for s in libs if str(s).startswith('-L')]
- return libs
-
- def get_libs_only_l(self):
- if not self.__libs: self.get_libs()
- libs = self.__libs
- libs = [s for s in libs if str(s).startswith('-l')]
- return libs
-
- def get_libs_only_other(self):
- if not self.__libs: self.get_libs()
- libs = self.__libs
- libs = [s for s in libs if not(str(s).startswith('-L')or str(s).startswith('-l'))]
- return libs
-
-def useCmdLine():
- """parse cmdline args and control build"""
- usage = '''Usage: %prog [options] PathToFile.la
-example: %prog --atleast-version=2.0.0 /usr/lib/libIlmImf.la
-nor: %prog --libs /usr/lib/libamarok.la'''
- parser = optparse.OptionParser(usage)
- a = parser.add_option
- a("--version", dest = "versionNumber",
- action = "store_true", default = False,
- help = "output version of libtool-config"
- )
- a("--debug", dest = "debug",
- action = "store_true", default = False,
- help = "enable debug"
- )
- a("--libs", dest = "libs",
- action = "store_true", default = False,
- help = "output all linker flags"
- )
- a("--libs-only-l", dest = "libs_only_l",
- action = "store_true", default = False,
- help = "output -l flags"
- )
- a("--libs-only-L", dest = "libs_only_L",
- action = "store_true", default = False,
- help = "output -L flags"
- )
- a("--libs-only-other", dest = "libs_only_other",
- action = "store_true", default = False,
- help = "output other libs (e.g. -pthread)"
- )
- a("--atleast-version", dest = "atleast_version",
- default=None,
- help = "return 0 if the module is at least version ATLEAST_VERSION"
- )
- a("--exact-version", dest = "exact_version",
- default=None,
- help = "return 0 if the module is exactly version EXACT_VERSION"
- )
- a("--max-version", dest = "max_version",
- default=None,
- help = "return 0 if the module is at no newer than version MAX_VERSION"
- )
-
- (options, args) = parser.parse_args()
- if len(args) != 1 and not options.versionNumber:
- parser.error("incorrect number of arguments")
- if options.versionNumber:
- print("libtool-config version %s" % REVISION)
- return 0
- ltf = libtool_config(args[0])
- if options.debug:
- print(ltf)
- if options.atleast_version:
- if ltf >= options.atleast_version: return 0
- sys.exit(1)
- if options.exact_version:
- if ltf == options.exact_version: return 0
- sys.exit(1)
- if options.max_version:
- if ltf <= options.max_version: return 0
- sys.exit(1)
-
- def p(x):
- print(" ".join(x))
- if options.libs: p(ltf.get_libs())
- elif options.libs_only_l: p(ltf.get_libs_only_l())
- elif options.libs_only_L: p(ltf.get_libs_only_L())
- elif options.libs_only_other: p(ltf.get_libs_only_other())
- return 0
-
-if __name__ == '__main__':
- useCmdLine()
-
diff --git a/tools/wafadmin/Tools/misc.py b/tools/wafadmin/Tools/misc.py
deleted file mode 100644
index 9903ee4bd..000000000
--- a/tools/wafadmin/Tools/misc.py
+++ /dev/null
@@ -1,430 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006 (ita)
-
-"""
-Custom objects:
- - execute a function everytime
- - copy a file somewhere else
-"""
-
-import shutil, re, os
-import TaskGen, Node, Task, Utils, Build, Constants
-from TaskGen import feature, taskgen, after, before
-from Logs import debug
-
-def copy_func(tsk):
- "Make a file copy. This might be used to make other kinds of file processing (even calling a compiler is possible)"
- env = tsk.env
- infile = tsk.inputs[0].abspath(env)
- outfile = tsk.outputs[0].abspath(env)
- try:
- shutil.copy2(infile, outfile)
- except (OSError, IOError):
- return 1
- else:
- if tsk.chmod: os.chmod(outfile, tsk.chmod)
- return 0
-
-def action_process_file_func(tsk):
- "Ask the function attached to the task to process it"
- if not tsk.fun: raise Utils.WafError('task must have a function attached to it for copy_func to work!')
- return tsk.fun(tsk)
-
-class cmd_taskgen(TaskGen.task_gen):
- def __init__(self, *k, **kw):
- TaskGen.task_gen.__init__(self, *k, **kw)
-
-@feature('cmd')
-def apply_cmd(self):
- "call a command everytime"
- if not self.fun: raise Utils.WafError('cmdobj needs a function!')
- tsk = Task.TaskBase()
- tsk.fun = self.fun
- tsk.env = self.env
- self.tasks.append(tsk)
- tsk.install_path = self.install_path
-
-class copy_taskgen(TaskGen.task_gen):
- "By default, make a file copy, if fun is provided, fun will make the copy (or call a compiler, etc)"
- def __init__(self, *k, **kw):
- TaskGen.task_gen.__init__(self, *k, **kw)
-
-@feature('copy')
-@before('apply_core')
-def apply_copy(self):
- Utils.def_attrs(self, fun=copy_func)
- self.default_install_path = 0
-
- lst = self.to_list(self.source)
- self.meths.remove('apply_core')
-
- for filename in lst:
- node = self.path.find_resource(filename)
- if not node: raise Utils.WafError('cannot find input file %s for processing' % filename)
-
- target = self.target
- if not target or len(lst)>1: target = node.name
-
- # TODO the file path may be incorrect
- newnode = self.path.find_or_declare(target)
-
- tsk = self.create_task('copy', node, newnode)
- tsk.fun = self.fun
- tsk.chmod = self.chmod
- tsk.install_path = self.install_path
-
- if not tsk.env:
- tsk.debug()
- raise Utils.WafError('task without an environment')
-
-def subst_func(tsk):
- "Substitutes variables in a .in file"
-
- m4_re = re.compile('@(\w+)@', re.M)
-
- env = tsk.env
- infile = tsk.inputs[0].abspath(env)
- outfile = tsk.outputs[0].abspath(env)
-
- code = Utils.readf(infile)
-
- # replace all % by %% to prevent errors by % signs in the input file while string formatting
- code = code.replace('%', '%%')
-
- s = m4_re.sub(r'%(\1)s', code)
-
- di = tsk.dict or {}
- if not di:
- names = m4_re.findall(code)
- for i in names:
- di[i] = env.get_flat(i) or env.get_flat(i.upper())
-
- file = open(outfile, 'w')
- file.write(s % di)
- file.close()
- if tsk.chmod: os.chmod(outfile, tsk.chmod)
-
-class subst_taskgen(TaskGen.task_gen):
- def __init__(self, *k, **kw):
- TaskGen.task_gen.__init__(self, *k, **kw)
-
-@feature('subst')
-@before('apply_core')
-def apply_subst(self):
- Utils.def_attrs(self, fun=subst_func)
- self.default_install_path = 0
- lst = self.to_list(self.source)
- self.meths.remove('apply_core')
-
- self.dict = getattr(self, 'dict', {})
-
- for filename in lst:
- node = self.path.find_resource(filename)
- if not node: raise Utils.WafError('cannot find input file %s for processing' % filename)
-
- if self.target:
- newnode = self.path.find_or_declare(self.target)
- else:
- newnode = node.change_ext('')
-
- try:
- self.dict = self.dict.get_merged_dict()
- except AttributeError:
- pass
-
- if self.dict and not self.env['DICT_HASH']:
- self.env = self.env.copy()
- keys = list(self.dict.keys())
- keys.sort()
- lst = [self.dict[x] for x in keys]
- self.env['DICT_HASH'] = str(Utils.h_list(lst))
-
- tsk = self.create_task('copy', node, newnode)
- tsk.fun = self.fun
- tsk.dict = self.dict
- tsk.dep_vars = ['DICT_HASH']
- tsk.install_path = self.install_path
- tsk.chmod = self.chmod
-
- if not tsk.env:
- tsk.debug()
- raise Utils.WafError('task without an environment')
-
-####################
-## command-output ####
-####################
-
-class cmd_arg(object):
- """command-output arguments for representing files or folders"""
- def __init__(self, name, template='%s'):
- self.name = name
- self.template = template
- self.node = None
-
-class input_file(cmd_arg):
- def find_node(self, base_path):
- assert isinstance(base_path, Node.Node)
- self.node = base_path.find_resource(self.name)
- if self.node is None:
- raise Utils.WafError("Input file %s not found in " % (self.name, base_path))
-
- def get_path(self, env, absolute):
- if absolute:
- return self.template % self.node.abspath(env)
- else:
- return self.template % self.node.srcpath(env)
-
-class output_file(cmd_arg):
- def find_node(self, base_path):
- assert isinstance(base_path, Node.Node)
- self.node = base_path.find_or_declare(self.name)
- if self.node is None:
- raise Utils.WafError("Output file %s not found in " % (self.name, base_path))
-
- def get_path(self, env, absolute):
- if absolute:
- return self.template % self.node.abspath(env)
- else:
- return self.template % self.node.bldpath(env)
-
-class cmd_dir_arg(cmd_arg):
- def find_node(self, base_path):
- assert isinstance(base_path, Node.Node)
- self.node = base_path.find_dir(self.name)
- if self.node is None:
- raise Utils.WafError("Directory %s not found in " % (self.name, base_path))
-
-class input_dir(cmd_dir_arg):
- def get_path(self, dummy_env, dummy_absolute):
- return self.template % self.node.abspath()
-
-class output_dir(cmd_dir_arg):
- def get_path(self, env, dummy_absolute):
- return self.template % self.node.abspath(env)
-
-
-class command_output(Task.Task):
- color = "BLUE"
- def __init__(self, env, command, command_node, command_args, stdin, stdout, cwd, os_env, stderr):
- Task.Task.__init__(self, env, normal=1)
- assert isinstance(command, (str, Node.Node))
- self.command = command
- self.command_args = command_args
- self.stdin = stdin
- self.stdout = stdout
- self.cwd = cwd
- self.os_env = os_env
- self.stderr = stderr
-
- if command_node is not None: self.dep_nodes = [command_node]
- self.dep_vars = [] # additional environment variables to look
-
- def run(self):
- task = self
- #assert len(task.inputs) > 0
-
- def input_path(node, template):
- if task.cwd is None:
- return template % node.bldpath(task.env)
- else:
- return template % node.abspath()
- def output_path(node, template):
- fun = node.abspath
- if task.cwd is None: fun = node.bldpath
- return template % fun(task.env)
-
- if isinstance(task.command, Node.Node):
- argv = [input_path(task.command, '%s')]
- else:
- argv = [task.command]
-
- for arg in task.command_args:
- if isinstance(arg, str):
- argv.append(arg)
- else:
- assert isinstance(arg, cmd_arg)
- argv.append(arg.get_path(task.env, (task.cwd is not None)))
-
- if task.stdin:
- stdin = open(input_path(task.stdin, '%s'))
- else:
- stdin = None
-
- if task.stdout:
- stdout = open(output_path(task.stdout, '%s'), "w")
- else:
- stdout = None
-
- if task.stderr:
- stderr = open(output_path(task.stderr, '%s'), "w")
- else:
- stderr = None
-
- if task.cwd is None:
- cwd = ('None (actually %r)' % os.getcwd())
- else:
- cwd = repr(task.cwd)
- debug("command-output: cwd=%s, stdin=%r, stdout=%r, argv=%r" %
- (cwd, stdin, stdout, argv))
-
- if task.os_env is None:
- os_env = os.environ
- else:
- os_env = task.os_env
- command = Utils.pproc.Popen(argv, stdin=stdin, stdout=stdout, stderr=stderr, cwd=task.cwd, env=os_env)
- return command.wait()
-
-class cmd_output_taskgen(TaskGen.task_gen):
- def __init__(self, *k, **kw):
- TaskGen.task_gen.__init__(self, *k, **kw)
-
-@feature('command-output')
-def init_cmd_output(self):
- Utils.def_attrs(self,
- stdin = None,
- stdout = None,
- stderr = None,
- # the command to execute
- command = None,
-
- # whether it is an external command; otherwise it is assumed
- # to be an executable binary or script that lives in the
- # source or build tree.
- command_is_external = False,
-
- # extra parameters (argv) to pass to the command (excluding
- # the command itself)
- argv = [],
-
- # dependencies to other objects -> this is probably not what you want (ita)
- # values must be 'task_gen' instances (not names!)
- dependencies = [],
-
- # dependencies on env variable contents
- dep_vars = [],
-
- # input files that are implicit, i.e. they are not
- # stdin, nor are they mentioned explicitly in argv
- hidden_inputs = [],
-
- # output files that are implicit, i.e. they are not
- # stdout, nor are they mentioned explicitly in argv
- hidden_outputs = [],
-
- # change the subprocess to this cwd (must use obj.input_dir() or output_dir() here)
- cwd = None,
-
- # OS environment variables to pass to the subprocess
- # if None, use the default environment variables unchanged
- os_env = None)
-
-@feature('command-output')
-@after('init_cmd_output')
-def apply_cmd_output(self):
- if self.command is None:
- raise Utils.WafError("command-output missing command")
- if self.command_is_external:
- cmd = self.command
- cmd_node = None
- else:
- cmd_node = self.path.find_resource(self.command)
- assert cmd_node is not None, ('''Could not find command '%s' in source tree.
-Hint: if this is an external command,
-use command_is_external=True''') % (self.command,)
- cmd = cmd_node
-
- if self.cwd is None:
- cwd = None
- else:
- assert isinstance(cwd, CmdDirArg)
- self.cwd.find_node(self.path)
-
- args = []
- inputs = []
- outputs = []
-
- for arg in self.argv:
- if isinstance(arg, cmd_arg):
- arg.find_node(self.path)
- if isinstance(arg, input_file):
- inputs.append(arg.node)
- if isinstance(arg, output_file):
- outputs.append(arg.node)
-
- if self.stdout is None:
- stdout = None
- else:
- assert isinstance(self.stdout, str)
- stdout = self.path.find_or_declare(self.stdout)
- if stdout is None:
- raise Utils.WafError("File %s not found" % (self.stdout,))
- outputs.append(stdout)
-
- if self.stderr is None:
- stderr = None
- else:
- assert isinstance(self.stderr, str)
- stderr = self.path.find_or_declare(self.stderr)
- if stderr is None:
- raise Utils.WafError("File %s not found" % (self.stderr,))
- outputs.append(stderr)
-
- if self.stdin is None:
- stdin = None
- else:
- assert isinstance(self.stdin, str)
- stdin = self.path.find_resource(self.stdin)
- if stdin is None:
- raise Utils.WafError("File %s not found" % (self.stdin,))
- inputs.append(stdin)
-
- for hidden_input in self.to_list(self.hidden_inputs):
- node = self.path.find_resource(hidden_input)
- if node is None:
- raise Utils.WafError("File %s not found in dir %s" % (hidden_input, self.path))
- inputs.append(node)
-
- for hidden_output in self.to_list(self.hidden_outputs):
- node = self.path.find_or_declare(hidden_output)
- if node is None:
- raise Utils.WafError("File %s not found in dir %s" % (hidden_output, self.path))
- outputs.append(node)
-
- if not (inputs or getattr(self, 'no_inputs', None)):
- raise Utils.WafError('command-output objects must have at least one input file or give self.no_inputs')
- if not (outputs or getattr(self, 'no_outputs', None)):
- raise Utils.WafError('command-output objects must have at least one output file or give self.no_outputs')
-
- task = command_output(self.env, cmd, cmd_node, self.argv, stdin, stdout, cwd, self.os_env, stderr)
- Utils.copy_attrs(self, task, 'before after ext_in ext_out', only_if_set=True)
- self.tasks.append(task)
-
- task.inputs = inputs
- task.outputs = outputs
- task.dep_vars = self.to_list(self.dep_vars)
-
- for dep in self.dependencies:
- assert dep is not self
- dep.post()
- for dep_task in dep.tasks:
- task.set_run_after(dep_task)
-
- if not task.inputs:
- # the case for svnversion, always run, and update the output nodes
- task.runnable_status = type(Task.TaskBase.run)(runnable_status, task, task.__class__) # always run
- task.post_run = type(Task.TaskBase.run)(post_run, task, task.__class__)
-
- # TODO the case with no outputs?
-
-def post_run(self):
- for x in self.outputs:
- h = Utils.h_file(x.abspath(self.env))
- self.generator.bld.node_sigs[self.env.variant()][x.id] = h
-
-def runnable_status(self):
- return Constants.RUN_ME
-
-Task.task_type_from_func('copy', vars=[], func=action_process_file_func)
-TaskGen.task_gen.classes['command-output'] = cmd_output_taskgen
-
diff --git a/tools/wafadmin/Tools/nasm.py b/tools/wafadmin/Tools/nasm.py
deleted file mode 100644
index b99c3c734..000000000
--- a/tools/wafadmin/Tools/nasm.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2008
-
-"""
-Nasm processing
-"""
-
-import os
-import TaskGen, Task, Utils
-from TaskGen import taskgen, before, extension
-
-nasm_str = '${NASM} ${NASM_FLAGS} ${NASM_INCLUDES} ${SRC} -o ${TGT}'
-
-EXT_NASM = ['.s', '.S', '.asm', '.ASM', '.spp', '.SPP']
-
-@before('apply_link')
-def apply_nasm_vars(self):
-
- # flags
- if hasattr(self, 'nasm_flags'):
- for flag in self.to_list(self.nasm_flags):
- self.env.append_value('NASM_FLAGS', flag)
-
- # includes - well, if we suppose it works with c processing
- if hasattr(self, 'includes'):
- for inc in self.to_list(self.includes):
- node = self.path.find_dir(inc)
- if not node:
- raise Utils.WafError('cannot find the dir' + inc)
- self.env.append_value('NASM_INCLUDES', '-I%s' % node.srcpath(self.env))
- self.env.append_value('NASM_INCLUDES', '-I%s' % node.bldpath(self.env))
-
-@extension(EXT_NASM)
-def nasm_file(self, node):
- try: obj_ext = self.obj_ext
- except AttributeError: obj_ext = '_%d.o' % self.idx
-
- task = self.create_task('nasm', node, node.change_ext(obj_ext))
- self.compiled_tasks.append(task)
-
- self.meths.append('apply_nasm_vars')
-
-# create our action here
-Task.simple_task_type('nasm', nasm_str, color='BLUE', ext_out='.o', shell=False)
-
-def detect(conf):
- nasm = conf.find_program(['nasm', 'yasm'], var='NASM', mandatory=True)
-
diff --git a/tools/wafadmin/Tools/node_addon.py b/tools/wafadmin/Tools/node_addon.py
deleted file mode 100644
index 6ea65aec3..000000000
--- a/tools/wafadmin/Tools/node_addon.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import os
-import TaskGen, Utils, Runner, Options, Build
-from TaskGen import extension, taskgen, before, after, feature
-from Configure import conf, conftest
-
-@taskgen
-@before('apply_incpaths', 'apply_lib_vars', 'apply_type_vars')
-@feature('node_addon')
-@before('apply_bundle')
-def init_node_addon(self):
- self.default_install_path = self.env['NODE_PATH']
- self.uselib = self.to_list(getattr(self, 'uselib', ''))
- if not 'NODE' in self.uselib: self.uselib.append('NODE')
- self.env['MACBUNDLE'] = True
-
-@taskgen
-@before('apply_link', 'apply_lib_vars', 'apply_type_vars')
-@after('apply_bundle')
-@feature('node_addon')
-def node_addon_shlib_ext(self):
- self.env['shlib_PATTERN'] = "%s.node"
-
-def detect(conf):
- join = os.path.join
-
- conf.env['PREFIX_NODE'] = get_prefix()
- prefix = conf.env['PREFIX_NODE']
- lib = join(prefix, 'lib')
- nodebin = join(prefix, 'bin', 'node')
-
- conf.env['LIBPATH_NODE'] = lib
- conf.env['CPPPATH_NODE'] = join(prefix, 'include', 'node')
-
- conf.env.append_value('CPPFLAGS_NODE', '-D_GNU_SOURCE')
-
- conf.env.append_value('CCFLAGS_NODE', '-D_LARGEFILE_SOURCE')
- conf.env.append_value('CCFLAGS_NODE', '-D_FILE_OFFSET_BITS=64')
-
- conf.env.append_value('CXXFLAGS_NODE', '-D_LARGEFILE_SOURCE')
- conf.env.append_value('CXXFLAGS_NODE', '-D_FILE_OFFSET_BITS=64')
-
- # with symbols
- conf.env.append_value('CCFLAGS', ['-g'])
- conf.env.append_value('CXXFLAGS', ['-g'])
- # install path
- conf.env['NODE_PATH'] = get_node_path()
- # this changes the install path of cxx task_gen
- conf.env['LIBDIR'] = conf.env['NODE_PATH']
-
- found = os.path.exists(conf.env['NODE_PATH'])
- conf.check_message('node path', '', found, conf.env['NODE_PATH'])
-
- found = os.path.exists(nodebin)
- conf.check_message('node prefix', '', found, prefix)
-
- ## On Cygwin we need to link to the generated symbol definitions
- if Options.platform.startswith('cygwin'): conf.env['LIB_NODE'] = 'node'
-
- ## On Mac OSX we need to use mac bundles
- if Options.platform == 'darwin':
- if 'i386' in Utils.cmd_output(['file', nodebin]):
- conf.env.append_value('CPPFLAGS_NODE', ['-arch', 'i386'])
- conf.env.append_value('CXXFLAGS_NODE', ['-arch', 'i386'])
- conf.env.append_value('LINKFLAGS', ['-arch', 'i386'])
- conf.env['DEST_CPU'] = 'i386'
- conf.check_tool('osx')
-
-def get_node_path():
- join = os.path.join
- nodePath = None
- if not os.environ.has_key('NODE_PATH'):
- if not os.environ.has_key('HOME'):
- nodePath = join(get_prefix(), 'lib', 'node')
- else:
- nodePath = join(os.environ['HOME'], '.node_libraries')
- else:
- nodePath = os.environ['NODE_PATH']
- return nodePath
-
-def get_prefix():
- prefix = None
- if not os.environ.has_key('PREFIX_NODE'):
- prefix = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))
- else:
- prefix = os.environ['PREFIX_NODE']
- return prefix
diff --git a/tools/wafadmin/Tools/osx.py b/tools/wafadmin/Tools/osx.py
deleted file mode 100644
index 7ca95f59f..000000000
--- a/tools/wafadmin/Tools/osx.py
+++ /dev/null
@@ -1,187 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy 2008
-
-"""MacOSX related tools
-
-To compile an executable into a Mac application bundle (a .app), set its 'mac_app' attribute
- obj.mac_app = True
-
-To make a bundled shared library (a .bundle), set the 'mac_bundle' attribute:
- obj.mac_bundle = True
-"""
-
-import os, shutil, sys, platform
-import TaskGen, Task, Build, Options, Utils
-from TaskGen import taskgen, feature, after, before
-from Logs import error, debug
-
-# plist template
-app_info = '''
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
-<plist version="0.9">
-<dict>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleGetInfoString</key>
- <string>Created by Waf</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>NOTE</key>
- <string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
- <key>CFBundleExecutable</key>
- <string>%s</string>
-</dict>
-</plist>
-'''
-
-# see WAF issue 285
-# and also http://trac.macports.org/ticket/17059
-@feature('cc', 'cxx')
-@before('apply_lib_vars')
-def set_macosx_deployment_target(self):
- if self.env['MACOSX_DEPLOYMENT_TARGET']:
- os.environ['MACOSX_DEPLOYMENT_TARGET'] = self.env['MACOSX_DEPLOYMENT_TARGET']
- elif 'MACOSX_DEPLOYMENT_TARGET' not in os.environ:
- if sys.platform == 'darwin':
- os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(platform.mac_ver()[0].split('.')[:2])
-
-@feature('cc', 'cxx')
-@after('apply_lib_vars')
-def apply_framework(self):
- for x in self.to_list(self.env['FRAMEWORKPATH']):
- frameworkpath_st = '-F%s'
- self.env.append_unique('CXXFLAGS', frameworkpath_st % x)
- self.env.append_unique('CCFLAGS', frameworkpath_st % x)
- self.env.append_unique('LINKFLAGS', frameworkpath_st % x)
-
- for x in self.to_list(self.env['FRAMEWORK']):
- self.env.append_value('LINKFLAGS', ['-framework', x])
-
-@taskgen
-def create_bundle_dirs(self, name, out):
- bld = self.bld
- dir = out.parent.get_dir(name)
-
- if not dir:
- dir = out.__class__(name, out.parent, 1)
- bld.rescan(dir)
- contents = out.__class__('Contents', dir, 1)
- bld.rescan(contents)
- macos = out.__class__('MacOS', contents, 1)
- bld.rescan(macos)
- return dir
-
-def bundle_name_for_output(out):
- name = out.name
- k = name.rfind('.')
- if k >= 0:
- name = name[:k] + '.app'
- else:
- name = name + '.app'
- return name
-
-@taskgen
-@after('apply_link')
-@feature('cprogram')
-def create_task_macapp(self):
- """Use env['MACAPP'] to force *all* executables to be transformed into Mac applications
- or use obj.mac_app = True to build specific targets as Mac apps"""
- if self.env['MACAPP'] or getattr(self, 'mac_app', False):
- apptask = self.create_task('macapp')
- apptask.set_inputs(self.link_task.outputs)
-
- out = self.link_task.outputs[0]
-
- name = bundle_name_for_output(out)
- dir = self.create_bundle_dirs(name, out)
-
- n1 = dir.find_or_declare(['Contents', 'MacOS', out.name])
-
- apptask.set_outputs([n1])
- apptask.chmod = 0755
- apptask.install_path = os.path.join(self.install_path, name, 'Contents', 'MacOS')
- self.apptask = apptask
-
-@after('apply_link')
-@feature('cprogram')
-def create_task_macplist(self):
- """Use env['MACAPP'] to force *all* executables to be transformed into Mac applications
- or use obj.mac_app = True to build specific targets as Mac apps"""
- if self.env['MACAPP'] or getattr(self, 'mac_app', False):
- # check if the user specified a plist before using our template
- if not getattr(self, 'mac_plist', False):
- self.mac_plist = app_info
-
- plisttask = self.create_task('macplist')
- plisttask.set_inputs(self.link_task.outputs)
-
- out = self.link_task.outputs[0]
- self.mac_plist = self.mac_plist % (out.name)
-
- name = bundle_name_for_output(out)
- dir = self.create_bundle_dirs(name, out)
-
- n1 = dir.find_or_declare(['Contents', 'Info.plist'])
-
- plisttask.set_outputs([n1])
- plisttask.mac_plist = self.mac_plist
- plisttask.install_path = os.path.join(self.install_path, name, 'Contents')
- self.plisttask = plisttask
-
-@after('apply_link')
-@feature('cshlib')
-def apply_link_osx(self):
- name = self.link_task.outputs[0].name
- if not self.install_path:
- return
- if getattr(self, 'vnum', None):
- name = name.replace('.dylib', '.%s.dylib' % self.vnum)
-
- path = os.path.join(Utils.subst_vars(self.install_path, self.env), name)
- if '-dynamiclib' in self.env['LINKFLAGS']:
- self.env.append_value('LINKFLAGS', '-install_name')
- self.env.append_value('LINKFLAGS', path)
-
-@before('apply_link', 'apply_lib_vars')
-@feature('cc', 'cxx')
-def apply_bundle(self):
- """use env['MACBUNDLE'] to force all shlibs into mac bundles
- or use obj.mac_bundle = True for specific targets only"""
- if not ('cshlib' in self.features or 'shlib' in self.features): return
- if self.env['MACBUNDLE'] or getattr(self, 'mac_bundle', False):
- self.env['shlib_PATTERN'] = self.env['macbundle_PATTERN']
- uselib = self.uselib = self.to_list(self.uselib)
- if not 'MACBUNDLE' in uselib: uselib.append('MACBUNDLE')
-
-@after('apply_link')
-@feature('cshlib')
-def apply_bundle_remove_dynamiclib(self):
- if self.env['MACBUNDLE'] or getattr(self, 'mac_bundle', False):
- if not getattr(self, 'vnum', None):
- try:
- self.env['LINKFLAGS'].remove('-dynamiclib')
- except ValueError:
- pass
-
-# TODO REMOVE IN 1.6 (global variable)
-app_dirs = ['Contents', 'Contents/MacOS', 'Contents/Resources']
-
-def app_build(task):
- env = task.env
- shutil.copy2(task.inputs[0].srcpath(env), task.outputs[0].abspath(env))
-
- return 0
-
-def plist_build(task):
- env = task.env
- f = open(task.outputs[0].abspath(env), "w")
- f.write(task.mac_plist)
- f.close()
-
- return 0
-
-Task.task_type_from_func('macapp', vars=[], func=app_build, after="cxx_link cc_link static_link")
-Task.task_type_from_func('macplist', vars=[], func=plist_build, after="cxx_link cc_link static_link")
-
diff --git a/tools/wafadmin/Tools/preproc.py b/tools/wafadmin/Tools/preproc.py
deleted file mode 100644
index 1a9b0ff15..000000000
--- a/tools/wafadmin/Tools/preproc.py
+++ /dev/null
@@ -1,813 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006-2009 (ita)
-
-"""
-C/C++ preprocessor for finding dependencies
-
-Reasons for using the Waf preprocessor by default
-1. Some c/c++ extensions (Qt) require a custom preprocessor for obtaining the dependencies (.moc files)
-2. Not all compilers provide .d files for obtaining the dependencies (portability)
-3. A naive file scanner will not catch the constructs such as "#include foo()"
-4. A naive file scanner will catch unnecessary dependencies (change an unused header -> recompile everything)
-
-Regarding the speed concerns:
-a. the preprocessing is performed only when files must be compiled
-b. the macros are evaluated only for #if/#elif/#include
-c. the time penalty is about 10%
-d. system headers are not scanned
-
-Now if you do not want the Waf preprocessor, the tool "gccdeps" uses the .d files produced
-during the compilation to track the dependencies (useful when used with the boost libraries).
-It only works with gcc though, and it cannot be used with Qt builds. A dumb
-file scanner will be added in the future, so we will have most bahaviours.
-"""
-# TODO: more varargs, pragma once
-# TODO: dumb file scanner tracking all includes
-
-import re, sys, os, string
-import Logs, Build, Utils
-from Logs import debug, error
-import traceback
-
-class PreprocError(Utils.WafError):
- pass
-
-POPFILE = '-'
-
-
-recursion_limit = 100
-"do not loop too much on header inclusion"
-
-go_absolute = 0
-"set to 1 to track headers on files in /usr/include - else absolute paths are ignored"
-
-standard_includes = ['/usr/include']
-if sys.platform == "win32":
- standard_includes = []
-
-use_trigraphs = 0
-'apply the trigraph rules first'
-
-strict_quotes = 0
-"Keep <> for system includes (do not search for those includes)"
-
-g_optrans = {
-'not':'!',
-'and':'&&',
-'bitand':'&',
-'and_eq':'&=',
-'or':'||',
-'bitor':'|',
-'or_eq':'|=',
-'xor':'^',
-'xor_eq':'^=',
-'compl':'~',
-}
-"these ops are for c++, to reset, set an empty dict"
-
-# ignore #warning and #error
-re_lines = re.compile(\
- '^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',
- re.IGNORECASE | re.MULTILINE)
-
-re_mac = re.compile("^[a-zA-Z_]\w*")
-re_fun = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]')
-re_pragma_once = re.compile('^\s*once\s*', re.IGNORECASE)
-re_nl = re.compile('\\\\\r*\n', re.MULTILINE)
-re_cpp = re.compile(\
- r"""(/\*[^*]*\*+([^/*][^*]*\*+)*/)|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)""",
- re.MULTILINE)
-trig_def = [('??'+a, b) for a, b in zip("=-/!'()<>", r'#~\|^[]{}')]
-chr_esc = {'0':0, 'a':7, 'b':8, 't':9, 'n':10, 'f':11, 'v':12, 'r':13, '\\':92, "'":39}
-
-NUM = 'i'
-OP = 'O'
-IDENT = 'T'
-STR = 's'
-CHAR = 'c'
-
-tok_types = [NUM, STR, IDENT, OP]
-exp_types = [
- r"""0[xX](?P<hex>[a-fA-F0-9]+)(?P<qual1>[uUlL]*)|L*?'(?P<char>(\\.|[^\\'])+)'|(?P<n1>\d+)[Ee](?P<exp0>[+-]*?\d+)(?P<float0>[fFlL]*)|(?P<n2>\d*\.\d+)([Ee](?P<exp1>[+-]*?\d+))?(?P<float1>[fFlL]*)|(?P<n4>\d+\.\d*)([Ee](?P<exp2>[+-]*?\d+))?(?P<float2>[fFlL]*)|(?P<oct>0*)(?P<n0>\d+)(?P<qual2>[uUlL]*)""",
- r'L?"([^"\\]|\\.)*"',
- r'[a-zA-Z_]\w*',
- r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',
-]
-re_clexer = re.compile('|'.join(["(?P<%s>%s)" % (name, part) for name, part in zip(tok_types, exp_types)]), re.M)
-
-accepted = 'a'
-ignored = 'i'
-undefined = 'u'
-skipped = 's'
-
-def repl(m):
- s = m.group(1)
- if s is not None: return ' '
- s = m.group(3)
- if s is None: return ''
- return s
-
-def filter_comments(filename):
- # return a list of tuples : keyword, line
- code = Utils.readf(filename)
- if use_trigraphs:
- for (a, b) in trig_def: code = code.split(a).join(b)
- code = re_nl.sub('', code)
- code = re_cpp.sub(repl, code)
- return [(m.group(2), m.group(3)) for m in re.finditer(re_lines, code)]
-
-prec = {}
-# op -> number, needed for such expressions: #if 1 && 2 != 0
-ops = ['* / %', '+ -', '<< >>', '< <= >= >', '== !=', '& | ^', '&& ||', ',']
-for x in range(len(ops)):
- syms = ops[x]
- for u in syms.split():
- prec[u] = x
-
-def reduce_nums(val_1, val_2, val_op):
- """apply arithmetic rules and try to return an integer result"""
- #print val_1, val_2, val_op
-
- # now perform the operation, make certain a and b are numeric
- try: a = 0 + val_1
- except TypeError: a = int(val_1)
- try: b = 0 + val_2
- except TypeError: b = int(val_2)
-
- d = val_op
- if d == '%': c = a%b
- elif d=='+': c = a+b
- elif d=='-': c = a-b
- elif d=='*': c = a*b
- elif d=='/': c = a/b
- elif d=='^': c = a^b
- elif d=='|': c = a|b
- elif d=='||': c = int(a or b)
- elif d=='&': c = a&b
- elif d=='&&': c = int(a and b)
- elif d=='==': c = int(a == b)
- elif d=='!=': c = int(a != b)
- elif d=='<=': c = int(a <= b)
- elif d=='<': c = int(a < b)
- elif d=='>': c = int(a > b)
- elif d=='>=': c = int(a >= b)
- elif d=='^': c = int(a^b)
- elif d=='<<': c = a<<b
- elif d=='>>': c = a>>b
- else: c = 0
- return c
-
-def get_num(lst):
- if not lst: raise PreprocError("empty list for get_num")
- (p, v) = lst[0]
- if p == OP:
- if v == '(':
- count_par = 1
- i = 1
- while i < len(lst):
- (p, v) = lst[i]
-
- if p == OP:
- if v == ')':
- count_par -= 1
- if count_par == 0:
- break
- elif v == '(':
- count_par += 1
- i += 1
- else:
- raise PreprocError("rparen expected %r" % lst)
-
- (num, _) = get_term(lst[1:i])
- return (num, lst[i+1:])
-
- elif v == '+':
- return get_num(lst[1:])
- elif v == '-':
- num, lst = get_num(lst[1:])
- return (reduce_nums('-1', num, '*'), lst)
- elif v == '!':
- num, lst = get_num(lst[1:])
- return (int(not int(num)), lst)
- elif v == '~':
- return (~ int(num), lst)
- else:
- raise PreprocError("invalid op token %r for get_num" % lst)
- elif p == NUM:
- return v, lst[1:]
- elif p == IDENT:
- # all macros should have been replaced, remaining identifiers eval to 0
- return 0, lst[1:]
- else:
- raise PreprocError("invalid token %r for get_num" % lst)
-
-def get_term(lst):
- if not lst: raise PreprocError("empty list for get_term")
- num, lst = get_num(lst)
- if not lst:
- return (num, [])
- (p, v) = lst[0]
- if p == OP:
- if v == '&&' and not num:
- return (num, [])
- elif v == '||' and num:
- return (num, [])
- elif v == ',':
- # skip
- return get_term(lst[1:])
- elif v == '?':
- count_par = 0
- i = 1
- while i < len(lst):
- (p, v) = lst[i]
-
- if p == OP:
- if v == ')':
- count_par -= 1
- elif v == '(':
- count_par += 1
- elif v == ':':
- if count_par == 0:
- break
- i += 1
- else:
- raise PreprocError("rparen expected %r" % lst)
-
- if int(num):
- return get_term(lst[1:i])
- else:
- return get_term(lst[i+1:])
-
- else:
- num2, lst = get_num(lst[1:])
-
- if not lst:
- # no more tokens to process
- num2 = reduce_nums(num, num2, v)
- return get_term([(NUM, num2)] + lst)
-
- # operator precedence
- p2, v2 = lst[0]
- if p2 != OP:
- raise PreprocError("op expected %r" % lst)
-
- if prec[v2] >= prec[v]:
- num2 = reduce_nums(num, num2, v)
- return get_term([(NUM, num2)] + lst)
- else:
- num3, lst = get_num(lst[1:])
- num3 = reduce_nums(num2, num3, v2)
- return get_term([(NUM, num), (p, v), (NUM, num3)] + lst)
-
-
- raise PreprocError("cannot reduce %r" % lst)
-
-def reduce_eval(lst):
- """take a list of tokens and output true or false (#if/#elif conditions)"""
- num, lst = get_term(lst)
- return (NUM, num)
-
-def stringize(lst):
- """use for converting a list of tokens to a string"""
- lst = [str(v2) for (p2, v2) in lst]
- return "".join(lst)
-
-def paste_tokens(t1, t2):
- """
- here is what we can paste:
- a ## b -> ab
- > ## = -> >=
- a ## 2 -> a2
- """
- p1 = None
- if t1[0] == OP and t2[0] == OP:
- p1 = OP
- elif t1[0] == IDENT and (t2[0] == IDENT or t2[0] == NUM):
- p1 = IDENT
- elif t1[0] == NUM and t2[0] == NUM:
- p1 = NUM
- if not p1:
- raise PreprocError('tokens do not make a valid paste %r and %r' % (t1, t2))
- return (p1, t1[1] + t2[1])
-
-def reduce_tokens(lst, defs, ban=[]):
- """replace the tokens in lst, using the macros provided in defs, and a list of macros that cannot be re-applied"""
- i = 0
-
- while i < len(lst):
- (p, v) = lst[i]
-
- if p == IDENT and v == "defined":
- del lst[i]
- if i < len(lst):
- (p2, v2) = lst[i]
- if p2 == IDENT:
- if v2 in defs:
- lst[i] = (NUM, 1)
- else:
- lst[i] = (NUM, 0)
- elif p2 == OP and v2 == '(':
- del lst[i]
- (p2, v2) = lst[i]
- del lst[i] # remove the ident, and change the ) for the value
- if v2 in defs:
- lst[i] = (NUM, 1)
- else:
- lst[i] = (NUM, 0)
- else:
- raise PreprocError("invalid define expression %r" % lst)
-
- elif p == IDENT and v in defs:
-
- if isinstance(defs[v], str):
- a, b = extract_macro(defs[v])
- defs[v] = b
- macro_def = defs[v]
- to_add = macro_def[1]
-
- if isinstance(macro_def[0], list):
- # macro without arguments
- del lst[i]
- for x in xrange(len(to_add)):
- lst.insert(i, to_add[x])
- i += 1
- else:
- # collect the arguments for the funcall
-
- args = []
- del lst[i]
-
- if i >= len(lst):
- raise PreprocError("expected '(' after %r (got nothing)" % v)
-
- (p2, v2) = lst[i]
- if p2 != OP or v2 != '(':
- raise PreprocError("expected '(' after %r" % v)
-
- del lst[i]
-
- one_param = []
- count_paren = 0
- while i < len(lst):
- p2, v2 = lst[i]
-
- del lst[i]
- if p2 == OP and count_paren == 0:
- if v2 == '(':
- one_param.append((p2, v2))
- count_paren += 1
- elif v2 == ')':
- if one_param: args.append(one_param)
- break
- elif v2 == ',':
- if not one_param: raise PreprocError("empty param in funcall %s" % p)
- args.append(one_param)
- one_param = []
- else:
- one_param.append((p2, v2))
- else:
- one_param.append((p2, v2))
- if v2 == '(': count_paren += 1
- elif v2 == ')': count_paren -= 1
- else:
- raise PreprocError('malformed macro')
-
- # substitute the arguments within the define expression
- accu = []
- arg_table = macro_def[0]
- j = 0
- while j < len(to_add):
- (p2, v2) = to_add[j]
-
- if p2 == OP and v2 == '#':
- # stringize is for arguments only
- if j+1 < len(to_add) and to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table:
- toks = args[arg_table[to_add[j+1][1]]]
- accu.append((STR, stringize(toks)))
- j += 1
- else:
- accu.append((p2, v2))
- elif p2 == OP and v2 == '##':
- # token pasting, how can man invent such a complicated system?
- if accu and j+1 < len(to_add):
- # we have at least two tokens
-
- t1 = accu[-1]
-
- if to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table:
- toks = args[arg_table[to_add[j+1][1]]]
-
- if toks:
- accu[-1] = paste_tokens(t1, toks[0]) #(IDENT, accu[-1][1] + toks[0][1])
- accu.extend(toks[1:])
- else:
- # error, case "a##"
- accu.append((p2, v2))
- accu.extend(toks)
- elif to_add[j+1][0] == IDENT and to_add[j+1][1] == '__VA_ARGS__':
- # TODO not sure
- # first collect the tokens
- va_toks = []
- st = len(macro_def[0])
- pt = len(args)
- for x in args[pt-st+1:]:
- va_toks.extend(x)
- va_toks.append((OP, ','))
- if va_toks: va_toks.pop() # extra comma
- if len(accu)>1:
- (p3, v3) = accu[-1]
- (p4, v4) = accu[-2]
- if v3 == '##':
- # remove the token paste
- accu.pop()
- if v4 == ',' and pt < st:
- # remove the comma
- accu.pop()
- accu += va_toks
- else:
- accu[-1] = paste_tokens(t1, to_add[j+1])
-
- j += 1
- else:
- # invalid paste, case "##a" or "b##"
- accu.append((p2, v2))
-
- elif p2 == IDENT and v2 in arg_table:
- toks = args[arg_table[v2]]
- reduce_tokens(toks, defs, ban+[v])
- accu.extend(toks)
- else:
- accu.append((p2, v2))
-
- j += 1
-
-
- reduce_tokens(accu, defs, ban+[v])
-
- for x in xrange(len(accu)-1, -1, -1):
- lst.insert(i, accu[x])
-
- i += 1
-
-
-def eval_macro(lst, adefs):
- """reduce the tokens from the list lst, and try to return a 0/1 result"""
- reduce_tokens(lst, adefs, [])
- if not lst: raise PreprocError("missing tokens to evaluate")
- (p, v) = reduce_eval(lst)
- return int(v) != 0
-
-def extract_macro(txt):
- """process a macro definition from "#define f(x, y) x * y" into a function or a simple macro without arguments"""
- t = tokenize(txt)
- if re_fun.search(txt):
- p, name = t[0]
-
- p, v = t[1]
- if p != OP: raise PreprocError("expected open parenthesis")
-
- i = 1
- pindex = 0
- params = {}
- prev = '('
-
- while 1:
- i += 1
- p, v = t[i]
-
- if prev == '(':
- if p == IDENT:
- params[v] = pindex
- pindex += 1
- prev = p
- elif p == OP and v == ')':
- break
- else:
- raise PreprocError("unexpected token (3)")
- elif prev == IDENT:
- if p == OP and v == ',':
- prev = v
- elif p == OP and v == ')':
- break
- else:
- raise PreprocError("comma or ... expected")
- elif prev == ',':
- if p == IDENT:
- params[v] = pindex
- pindex += 1
- prev = p
- elif p == OP and v == '...':
- raise PreprocError("not implemented (1)")
- else:
- raise PreprocError("comma or ... expected (2)")
- elif prev == '...':
- raise PreprocError("not implemented (2)")
- else:
- raise PreprocError("unexpected else")
-
- #~ print (name, [params, t[i+1:]])
- return (name, [params, t[i+1:]])
- else:
- (p, v) = t[0]
- return (v, [[], t[1:]])
-
-re_include = re.compile('^\s*(<(?P<a>.*)>|"(?P<b>.*)")')
-def extract_include(txt, defs):
- """process a line in the form "#include foo" to return a string representing the file"""
- m = re_include.search(txt)
- if m:
- if m.group('a'): return '<', m.group('a')
- if m.group('b'): return '"', m.group('b')
-
- # perform preprocessing and look at the result, it must match an include
- toks = tokenize(txt)
- reduce_tokens(toks, defs, ['waf_include'])
-
- if not toks:
- raise PreprocError("could not parse include %s" % txt)
-
- if len(toks) == 1:
- if toks[0][0] == STR:
- return '"', toks[0][1]
- else:
- if toks[0][1] == '<' and toks[-1][1] == '>':
- return stringize(toks).lstrip('<').rstrip('>')
-
- raise PreprocError("could not parse include %s." % txt)
-
-def parse_char(txt):
- if not txt: raise PreprocError("attempted to parse a null char")
- if txt[0] != '\\':
- return ord(txt)
- c = txt[1]
- if c == 'x':
- if len(txt) == 4 and txt[3] in string.hexdigits: return int(txt[2:], 16)
- return int(txt[2:], 16)
- elif c.isdigit():
- if c == '0' and len(txt)==2: return 0
- for i in 3, 2, 1:
- if len(txt) > i and txt[1:1+i].isdigit():
- return (1+i, int(txt[1:1+i], 8))
- else:
- try: return chr_esc[c]
- except KeyError: raise PreprocError("could not parse char literal '%s'" % txt)
-
-def tokenize(s):
- """convert a string into a list of tokens (shlex.split does not apply to c/c++/d)"""
- ret = []
- for match in re_clexer.finditer(s):
- m = match.group
- for name in tok_types:
- v = m(name)
- if v:
- if name == IDENT:
- try: v = g_optrans[v]; name = OP
- except KeyError:
- # c++ specific
- if v.lower() == "true":
- v = 1
- name = NUM
- elif v.lower() == "false":
- v = 0
- name = NUM
- elif name == NUM:
- if m('oct'): v = int(v, 8)
- elif m('hex'): v = int(m('hex'), 16)
- elif m('n0'): v = m('n0')
- else:
- v = m('char')
- if v: v = parse_char(v)
- else: v = m('n2') or m('n4')
- elif name == OP:
- if v == '%:': v = '#'
- elif v == '%:%:': v = '##'
- elif name == STR:
- # remove the quotes around the string
- v = v[1:-1]
- ret.append((name, v))
- break
- return ret
-
-class c_parser(object):
- def __init__(self, nodepaths=None, defines=None):
- #self.lines = txt.split('\n')
- self.lines = []
-
- if defines is None:
- self.defs = {}
- else:
- self.defs = dict(defines) # make a copy
- self.state = []
-
- self.env = None # needed for the variant when searching for files
-
- self.count_files = 0
- self.currentnode_stack = []
-
- self.nodepaths = nodepaths or []
-
- self.nodes = []
- self.names = []
-
- # file added
- self.curfile = ''
- self.ban_includes = []
-
- def tryfind(self, filename):
- self.curfile = filename
-
- # for msvc it should be a for loop on the whole stack
- found = self.currentnode_stack[-1].find_resource(filename)
-
- for n in self.nodepaths:
- if found:
- break
- found = n.find_resource(filename)
-
- if not found:
- if not filename in self.names:
- self.names.append(filename)
- else:
- self.nodes.append(found)
- if filename[-4:] != '.moc':
- self.addlines(found)
- return found
-
- def addlines(self, node):
-
- self.currentnode_stack.append(node.parent)
- filepath = node.abspath(self.env)
-
- self.count_files += 1
- if self.count_files > recursion_limit: raise PreprocError("recursion limit exceeded")
- pc = self.parse_cache
- debug('preproc: reading file %r', filepath)
- try:
- lns = pc[filepath]
- except KeyError:
- pass
- else:
- self.lines = lns + self.lines
- return
-
- try:
- lines = filter_comments(filepath)
- lines.append((POPFILE, ''))
- pc[filepath] = lines # cache the lines filtered
- self.lines = lines + self.lines
- except IOError:
- raise PreprocError("could not read the file %s" % filepath)
- except Exception:
- if Logs.verbose > 0:
- error("parsing %s failed" % filepath)
- traceback.print_exc()
-
- def start(self, node, env):
- debug('preproc: scanning %s (in %s)', node.name, node.parent.name)
-
- self.env = env
- variant = node.variant(env)
- bld = node.__class__.bld
- try:
- self.parse_cache = bld.parse_cache
- except AttributeError:
- bld.parse_cache = {}
- self.parse_cache = bld.parse_cache
-
- self.addlines(node)
- if env['DEFLINES']:
- self.lines = [('define', x) for x in env['DEFLINES']] + self.lines
-
- while self.lines:
- (kind, line) = self.lines.pop(0)
- if kind == POPFILE:
- self.currentnode_stack.pop()
- continue
- try:
- self.process_line(kind, line)
- except Exception, e:
- if Logs.verbose:
- debug('preproc: line parsing failed (%s): %s %s', e, line, Utils.ex_stack())
-
- def process_line(self, token, line):
- ve = Logs.verbose
- if ve: debug('preproc: line is %s - %s state is %s', token, line, self.state)
- state = self.state
-
- # make certain we define the state if we are about to enter in an if block
- if token in ['ifdef', 'ifndef', 'if']:
- state.append(undefined)
- elif token == 'endif':
- state.pop()
-
- # skip lines when in a dead 'if' branch, wait for the endif
- if not token in ['else', 'elif', 'endif']:
- if skipped in self.state or ignored in self.state:
- return
-
- if token == 'if':
- ret = eval_macro(tokenize(line), self.defs)
- if ret: state[-1] = accepted
- else: state[-1] = ignored
- elif token == 'ifdef':
- m = re_mac.search(line)
- if m and m.group(0) in self.defs: state[-1] = accepted
- else: state[-1] = ignored
- elif token == 'ifndef':
- m = re_mac.search(line)
- if m and m.group(0) in self.defs: state[-1] = ignored
- else: state[-1] = accepted
- elif token == 'include' or token == 'import':
- (kind, inc) = extract_include(line, self.defs)
- if inc in self.ban_includes: return
- if token == 'import': self.ban_includes.append(inc)
- if ve: debug('preproc: include found %s (%s) ', inc, kind)
- if kind == '"' or not strict_quotes:
- self.tryfind(inc)
- elif token == 'elif':
- if state[-1] == accepted:
- state[-1] = skipped
- elif state[-1] == ignored:
- if eval_macro(tokenize(line), self.defs):
- state[-1] = accepted
- elif token == 'else':
- if state[-1] == accepted: state[-1] = skipped
- elif state[-1] == ignored: state[-1] = accepted
- elif token == 'define':
- m = re_mac.search(line)
- if m:
- name = m.group(0)
- if ve: debug('preproc: define %s %s', name, line)
- self.defs[name] = line
- else:
- raise PreprocError("invalid define line %s" % line)
- elif token == 'undef':
- m = re_mac.search(line)
- if m and m.group(0) in self.defs:
- self.defs.__delitem__(m.group(0))
- #print "undef %s" % name
- elif token == 'pragma':
- if re_pragma_once.search(line.lower()):
- self.ban_includes.append(self.curfile)
-
-def get_deps(node, env, nodepaths=[]):
- """
- Get the dependencies using a c/c++ preprocessor, this is required for finding dependencies of the kind
- #include some_macro()
- """
-
- gruik = c_parser(nodepaths)
- gruik.start(node, env)
- return (gruik.nodes, gruik.names)
-
-#################### dumb dependency scanner
-
-re_inc = re.compile(\
- '^[ \t]*(#|%:)[ \t]*(include)[ \t]*(.*)\r*$',
- re.IGNORECASE | re.MULTILINE)
-
-def lines_includes(filename):
- code = Utils.readf(filename)
- if use_trigraphs:
- for (a, b) in trig_def: code = code.split(a).join(b)
- code = re_nl.sub('', code)
- code = re_cpp.sub(repl, code)
- return [(m.group(2), m.group(3)) for m in re.finditer(re_inc, code)]
-
-def get_deps_simple(node, env, nodepaths=[], defines={}):
- """
- Get the dependencies by just looking recursively at the #include statements
- """
-
- nodes = []
- names = []
-
- def find_deps(node):
- lst = lines_includes(node.abspath(env))
-
- for (_, line) in lst:
- (t, filename) = extract_include(line, defines)
- if filename in names:
- continue
-
- if filename.endswith('.moc'):
- names.append(filename)
-
- found = None
- for n in nodepaths:
- if found:
- break
- found = n.find_resource(filename)
-
- if not found:
- if not filename in names:
- names.append(filename)
- elif not found in nodes:
- nodes.append(found)
- find_deps(node)
-
- find_deps(node)
- return (nodes, names)
-
-
diff --git a/tools/wafadmin/Tools/python.py b/tools/wafadmin/Tools/python.py
deleted file mode 100644
index e9f904831..000000000
--- a/tools/wafadmin/Tools/python.py
+++ /dev/null
@@ -1,401 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2007 (ita)
-# Gustavo Carneiro (gjc), 2007
-
-"Python support"
-
-import os, sys
-import TaskGen, Utils, Utils, Runner, Options, Build
-from Logs import debug, warn, info
-from TaskGen import extension, taskgen, before, after, feature
-from Configure import conf
-
-EXT_PY = ['.py']
-FRAG_2 = '''
-#ifdef __cplusplus
-extern "C" {
-#endif
- void Py_Initialize(void);
- void Py_Finalize(void);
-#ifdef __cplusplus
-}
-#endif
-int main()
-{
- Py_Initialize();
- Py_Finalize();
- return 0;
-}
-'''
-
-@before('apply_incpaths', 'apply_lib_vars', 'apply_type_vars')
-@feature('pyext')
-@before('apply_bundle')
-def init_pyext(self):
- self.default_install_path = '${PYTHONDIR}'
- self.uselib = self.to_list(getattr(self, 'uselib', ''))
- if not 'PYEXT' in self.uselib:
- self.uselib.append('PYEXT')
- self.env['MACBUNDLE'] = True
-
-@before('apply_link', 'apply_lib_vars', 'apply_type_vars')
-@after('apply_bundle')
-@feature('pyext')
-def pyext_shlib_ext(self):
- # override shlib_PATTERN set by the osx module
- self.env['shlib_PATTERN'] = self.env['pyext_PATTERN']
-
-@before('apply_incpaths', 'apply_lib_vars', 'apply_type_vars')
-@feature('pyembed')
-def init_pyembed(self):
- self.uselib = self.to_list(getattr(self, 'uselib', ''))
- if not 'PYEMBED' in self.uselib:
- self.uselib.append('PYEMBED')
-
-@extension(EXT_PY)
-def process_py(self, node):
- if not (self.bld.is_install and self.install_path):
- return
- def inst_py(ctx):
- install_pyfile(self, node)
- self.bld.add_post_fun(inst_py)
-
-def install_pyfile(self, node):
- path = self.bld.get_install_path(self.install_path + os.sep + node.name, self.env)
-
- self.bld.install_files(self.install_path, [node], self.env, self.chmod, postpone=False)
- if self.bld.is_install < 0:
- info("* removing byte compiled python files")
- for x in 'co':
- try:
- os.remove(path + x)
- except OSError:
- pass
-
- if self.bld.is_install > 0:
- if self.env['PYC'] or self.env['PYO']:
- info("* byte compiling %r" % path)
-
- if self.env['PYC']:
- program = ("""
-import sys, py_compile
-for pyfile in sys.argv[1:]:
- py_compile.compile(pyfile, pyfile + 'c')
-""")
- argv = [self.env['PYTHON'], '-c', program, path]
- ret = Utils.pproc.Popen(argv).wait()
- if ret:
- raise Utils.WafError('bytecode compilation failed %r' % path)
-
- if self.env['PYO']:
- program = ("""
-import sys, py_compile
-for pyfile in sys.argv[1:]:
- py_compile.compile(pyfile, pyfile + 'o')
-""")
- argv = [self.env['PYTHON'], self.env['PYFLAGS_OPT'], '-c', program, path]
- ret = Utils.pproc.Popen(argv).wait()
- if ret:
- raise Utils.WafError('bytecode compilation failed %r' % path)
-
-# COMPAT
-class py_taskgen(TaskGen.task_gen):
- def __init__(self, *k, **kw):
- TaskGen.task_gen.__init__(self, *k, **kw)
-
-@before('apply_core')
-@after('vars_target_cprogram', 'vars_target_cstaticlib')
-@feature('py')
-def init_py(self):
- self.default_install_path = '${PYTHONDIR}'
-
-def _get_python_variables(python_exe, variables, imports=['import sys']):
- """Run a python interpreter and print some variables"""
- program = list(imports)
- program.append('')
- for v in variables:
- program.append("print(repr(%s))" % v)
- os_env = dict(os.environ)
- try:
- del os_env['MACOSX_DEPLOYMENT_TARGET'] # see comments in the OSX tool
- except KeyError:
- pass
- proc = Utils.pproc.Popen([python_exe, "-c", '\n'.join(program)], stdout=Utils.pproc.PIPE, env=os_env)
- output = proc.communicate()[0].split("\n") # do not touch, python3
- if proc.returncode:
- if Options.options.verbose:
- warn("Python program to extract python configuration variables failed:\n%s"
- % '\n'.join(["line %03i: %s" % (lineno+1, line) for lineno, line in enumerate(program)]))
- raise RuntimeError
- return_values = []
- for s in output:
- s = s.strip()
- if not s:
- continue
- if s == 'None':
- return_values.append(None)
- elif s[0] == "'" and s[-1] == "'":
- return_values.append(s[1:-1])
- elif s[0].isdigit():
- return_values.append(int(s))
- else: break
- return return_values
-
-@conf
-def check_python_headers(conf):
- """Check for headers and libraries necessary to extend or embed python.
-
- On success the environment variables xxx_PYEXT and xxx_PYEMBED are added for uselib
-
- PYEXT: for compiling python extensions
- PYEMBED: for embedding a python interpreter"""
-
- if not conf.env['CC_NAME'] and not conf.env['CXX_NAME']:
- conf.fatal('load a compiler first (gcc, g++, ..)')
-
- if not conf.env['PYTHON_VERSION']:
- conf.check_python_version()
-
- env = conf.env
- python = env['PYTHON']
- if not python:
- conf.fatal('could not find the python executable')
-
- ## On Mac OSX we need to use mac bundles for python plugins
- if Options.platform == 'darwin':
- conf.check_tool('osx')
-
- try:
- # Get some python configuration variables using distutils
- v = 'prefix SO SYSLIBS LDFLAGS SHLIBS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET'.split()
- (python_prefix, python_SO, python_SYSLIBS, python_LDFLAGS, python_SHLIBS,
- python_LIBDIR, python_LIBPL, INCLUDEPY, Py_ENABLE_SHARED,
- python_MACOSX_DEPLOYMENT_TARGET) = \
- _get_python_variables(python, ["get_config_var('%s')" % x for x in v],
- ['from distutils.sysconfig import get_config_var'])
- except RuntimeError:
- conf.fatal("Python development headers not found (-v for details).")
-
- conf.log.write("""Configuration returned from %r:
-python_prefix = %r
-python_SO = %r
-python_SYSLIBS = %r
-python_LDFLAGS = %r
-python_SHLIBS = %r
-python_LIBDIR = %r
-python_LIBPL = %r
-INCLUDEPY = %r
-Py_ENABLE_SHARED = %r
-MACOSX_DEPLOYMENT_TARGET = %r
-""" % (python, python_prefix, python_SO, python_SYSLIBS, python_LDFLAGS, python_SHLIBS,
- python_LIBDIR, python_LIBPL, INCLUDEPY, Py_ENABLE_SHARED, python_MACOSX_DEPLOYMENT_TARGET))
-
- if python_MACOSX_DEPLOYMENT_TARGET:
- conf.env['MACOSX_DEPLOYMENT_TARGET'] = python_MACOSX_DEPLOYMENT_TARGET
- conf.environ['MACOSX_DEPLOYMENT_TARGET'] = python_MACOSX_DEPLOYMENT_TARGET
-
- env['pyext_PATTERN'] = '%s'+python_SO
-
- # Check for python libraries for embedding
- if python_SYSLIBS is not None:
- for lib in python_SYSLIBS.split():
- if lib.startswith('-l'):
- lib = lib[2:] # strip '-l'
- env.append_value('LIB_PYEMBED', lib)
-
- if python_SHLIBS is not None:
- for lib in python_SHLIBS.split():
- if lib.startswith('-l'):
- env.append_value('LIB_PYEMBED', lib[2:]) # strip '-l'
- else:
- env.append_value('LINKFLAGS_PYEMBED', lib)
-
- if Options.platform != 'darwin' and python_LDFLAGS:
- env.append_value('LINKFLAGS_PYEMBED', python_LDFLAGS.split())
-
- result = False
- name = 'python' + env['PYTHON_VERSION']
-
- if python_LIBDIR is not None:
- path = [python_LIBDIR]
- conf.log.write("\n\n# Trying LIBDIR: %r\n" % path)
- result = conf.check(lib=name, uselib='PYEMBED', libpath=path)
-
- if not result and python_LIBPL is not None:
- conf.log.write("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
- path = [python_LIBPL]
- result = conf.check(lib=name, uselib='PYEMBED', libpath=path)
-
- if not result:
- conf.log.write("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
- path = [os.path.join(python_prefix, "libs")]
- name = 'python' + env['PYTHON_VERSION'].replace('.', '')
- result = conf.check(lib=name, uselib='PYEMBED', libpath=path)
-
- if result:
- env['LIBPATH_PYEMBED'] = path
- env.append_value('LIB_PYEMBED', name)
- else:
- conf.log.write("\n\n### LIB NOT FOUND\n")
-
- # under certain conditions, python extensions must link to
- # python libraries, not just python embedding programs.
- if (sys.platform == 'win32' or sys.platform.startswith('os2')
- or sys.platform == 'darwin' or Py_ENABLE_SHARED):
- env['LIBPATH_PYEXT'] = env['LIBPATH_PYEMBED']
- env['LIB_PYEXT'] = env['LIB_PYEMBED']
-
- # We check that pythonX.Y-config exists, and if it exists we
- # use it to get only the includes, else fall back to distutils.
- python_config = conf.find_program(
- 'python%s-config' % ('.'.join(env['PYTHON_VERSION'].split('.')[:2])),
- var='PYTHON_CONFIG')
- if not python_config:
- python_config = conf.find_program(
- 'python-config-%s' % ('.'.join(env['PYTHON_VERSION'].split('.')[:2])),
- var='PYTHON_CONFIG')
-
- includes = []
- if python_config:
- for incstr in Utils.cmd_output("%s %s --includes" % (python, python_config)).strip().split():
- # strip the -I or /I
- if (incstr.startswith('-I')
- or incstr.startswith('/I')):
- incstr = incstr[2:]
- # append include path, unless already given
- if incstr not in includes:
- includes.append(incstr)
- conf.log.write("Include path for Python extensions "
- "(found via python-config --includes): %r\n" % (includes,))
- env['CPPPATH_PYEXT'] = includes
- env['CPPPATH_PYEMBED'] = includes
- else:
- conf.log.write("Include path for Python extensions "
- "(found via distutils module): %r\n" % (INCLUDEPY,))
- env['CPPPATH_PYEXT'] = [INCLUDEPY]
- env['CPPPATH_PYEMBED'] = [INCLUDEPY]
-
- # Code using the Python API needs to be compiled with -fno-strict-aliasing
- if env['CC_NAME'] == 'gcc':
- env.append_value('CCFLAGS_PYEMBED', '-fno-strict-aliasing')
- env.append_value('CCFLAGS_PYEXT', '-fno-strict-aliasing')
- if env['CXX_NAME'] == 'gcc':
- env.append_value('CXXFLAGS_PYEMBED', '-fno-strict-aliasing')
- env.append_value('CXXFLAGS_PYEXT', '-fno-strict-aliasing')
-
- # See if it compiles
- conf.check(header_name='Python.h', define_name='HAVE_PYTHON_H',
- uselib='PYEMBED', fragment=FRAG_2,
- errmsg='Could not find the python development headers', mandatory=1)
-
-@conf
-def check_python_version(conf, minver=None):
- """
- Check if the python interpreter is found matching a given minimum version.
- minver should be a tuple, eg. to check for python >= 2.4.2 pass (2,4,2) as minver.
-
- If successful, PYTHON_VERSION is defined as 'MAJOR.MINOR'
- (eg. '2.4') of the actual python version found, and PYTHONDIR is
- defined, pointing to the site-packages directory appropriate for
- this python version, where modules/packages/extensions should be
- installed.
- """
- assert minver is None or isinstance(minver, tuple)
- python = conf.env['PYTHON']
- if not python:
- conf.fatal('could not find the python executable')
-
- # Get python version string
- cmd = [python, "-c", "import sys\nfor x in sys.version_info: print(str(x))"]
- debug('python: Running python command %r' % cmd)
- proc = Utils.pproc.Popen(cmd, stdout=Utils.pproc.PIPE)
- lines = proc.communicate()[0].split()
- assert len(lines) == 5, "found %i lines, expected 5: %r" % (len(lines), lines)
- pyver_tuple = (int(lines[0]), int(lines[1]), int(lines[2]), lines[3], int(lines[4]))
-
- # compare python version with the minimum required
- result = (minver is None) or (pyver_tuple >= minver)
-
- if result:
- # define useful environment variables
- pyver = '.'.join([str(x) for x in pyver_tuple[:2]])
- conf.env['PYTHON_VERSION'] = pyver
-
- if 'PYTHONDIR' in conf.environ:
- pydir = conf.environ['PYTHONDIR']
- else:
- if sys.platform == 'win32':
- (python_LIBDEST, pydir) = \
- _get_python_variables(python,
- ["get_config_var('LIBDEST')",
- "get_python_lib(standard_lib=0, prefix=%r)" % conf.env['PREFIX']],
- ['from distutils.sysconfig import get_config_var, get_python_lib'])
- else:
- python_LIBDEST = None
- (pydir,) = \
- _get_python_variables(python,
- ["get_python_lib(standard_lib=0, prefix=%r)" % conf.env['PREFIX']],
- ['from distutils.sysconfig import get_config_var, get_python_lib'])
- if python_LIBDEST is None:
- if conf.env['LIBDIR']:
- python_LIBDEST = os.path.join(conf.env['LIBDIR'], "python" + pyver)
- else:
- python_LIBDEST = os.path.join(conf.env['PREFIX'], "lib", "python" + pyver)
-
- if hasattr(conf, 'define'): # conf.define is added by the C tool, so may not exist
- conf.define('PYTHONDIR', pydir)
- conf.env['PYTHONDIR'] = pydir
-
- # Feedback
- pyver_full = '.'.join(map(str, pyver_tuple[:3]))
- if minver is None:
- conf.check_message_custom('Python version', '', pyver_full)
- else:
- minver_str = '.'.join(map(str, minver))
- conf.check_message('Python version', ">= %s" % minver_str, result, option=pyver_full)
-
- if not result:
- conf.fatal('The python version is too old (%r)' % pyver_full)
-
-@conf
-def check_python_module(conf, module_name):
- """
- Check if the selected python interpreter can import the given python module.
- """
- result = not Utils.pproc.Popen([conf.env['PYTHON'], "-c", "import %s" % module_name],
- stderr=Utils.pproc.PIPE, stdout=Utils.pproc.PIPE).wait()
- conf.check_message('Python module', module_name, result)
- if not result:
- conf.fatal('Could not find the python module %r' % module_name)
-
-def detect(conf):
-
- if not conf.env.PYTHON:
- conf.env.PYTHON = sys.executable
-
- python = conf.find_program('python', var='PYTHON')
- if not python:
- conf.fatal('Could not find the path of the python executable')
-
- v = conf.env
-
- v['PYCMD'] = '"import sys, py_compile;py_compile.compile(sys.argv[1], sys.argv[2])"'
- v['PYFLAGS'] = ''
- v['PYFLAGS_OPT'] = '-O'
-
- v['PYC'] = getattr(Options.options, 'pyc', 1)
- v['PYO'] = getattr(Options.options, 'pyo', 1)
-
-def set_options(opt):
- opt.add_option('--nopyc',
- action='store_false',
- default=1,
- help = 'Do not install bytecode compiled .pyc files (configuration) [Default:install]',
- dest = 'pyc')
- opt.add_option('--nopyo',
- action='store_false',
- default=1,
- help='Do not install optimised compiled .pyo files (configuration) [Default:install]',
- dest='pyo')
-
diff --git a/tools/wafadmin/Tools/suncc.py b/tools/wafadmin/Tools/suncc.py
deleted file mode 100644
index 138722978..000000000
--- a/tools/wafadmin/Tools/suncc.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006 (ita)
-# Ralf Habacker, 2006 (rh)
-
-import os, optparse
-import Utils, Options, Configure
-import ccroot, ar
-from Configure import conftest
-
-@conftest
-def find_scc(conf):
- v = conf.env
- cc = None
- if v['CC']: cc = v['CC']
- elif 'CC' in conf.environ: cc = conf.environ['CC']
- #if not cc: cc = conf.find_program('gcc', var='CC')
- if not cc: cc = conf.find_program('cc', var='CC')
- if not cc: conf.fatal('suncc was not found')
- cc = conf.cmd_to_list(cc)
-
- try:
- if not Utils.cmd_output(cc + ['-flags']):
- conf.fatal('suncc %r was not found' % cc)
- except ValueError:
- conf.fatal('suncc -flags could not be executed')
-
- v['CC'] = cc
- v['CC_NAME'] = 'sun'
-
-@conftest
-def scc_common_flags(conf):
- v = conf.env
-
- # CPPFLAGS CCDEFINES _CCINCFLAGS _CCDEFFLAGS
-
- v['CC_SRC_F'] = ''
- v['CC_TGT_F'] = ['-c', '-o', '']
- v['CPPPATH_ST'] = '-I%s' # template for adding include paths
-
- # linker
- if not v['LINK_CC']: v['LINK_CC'] = v['CC']
- v['CCLNK_SRC_F'] = ''
- v['CCLNK_TGT_F'] = ['-o', ''] # solaris hack, separate the -o from the target
-
- v['LIB_ST'] = '-l%s' # template for adding libs
- v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
- v['STATICLIB_ST'] = '-l%s'
- v['STATICLIBPATH_ST'] = '-L%s'
- v['CCDEFINES_ST'] = '-D%s'
-
- v['SONAME_ST'] = '-Wl,-h -Wl,%s'
- v['SHLIB_MARKER'] = '-Bdynamic'
- v['STATICLIB_MARKER'] = '-Bstatic'
-
- # program
- v['program_PATTERN'] = '%s'
-
- # shared library
- v['shlib_CCFLAGS'] = ['-Kpic', '-DPIC']
- v['shlib_LINKFLAGS'] = ['-G']
- v['shlib_PATTERN'] = 'lib%s.so'
-
- # static lib
- v['staticlib_LINKFLAGS'] = ['-Bstatic']
- v['staticlib_PATTERN'] = 'lib%s.a'
-
-detect = '''
-find_scc
-find_cpp
-find_ar
-scc_common_flags
-cc_load_tools
-cc_add_flags
-link_add_flags
-'''
-
diff --git a/tools/wafadmin/Tools/suncxx.py b/tools/wafadmin/Tools/suncxx.py
deleted file mode 100644
index b6e9ef856..000000000
--- a/tools/wafadmin/Tools/suncxx.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006 (ita)
-# Ralf Habacker, 2006 (rh)
-
-import os, optparse
-import Utils, Options, Configure
-import ccroot, ar
-from Configure import conftest
-
-@conftest
-def find_sxx(conf):
- v = conf.env
- cc = None
- if v['CXX']: cc = v['CXX']
- elif 'CXX' in conf.environ: cc = conf.environ['CXX']
- if not cc: cc = conf.find_program('c++', var='CXX')
- if not cc: conf.fatal('sunc++ was not found')
- cc = conf.cmd_to_list(cc)
-
- try:
- if not Utils.cmd_output(cc + ['-flags']):
- conf.fatal('sunc++ %r was not found' % cc)
- except ValueError:
- conf.fatal('sunc++ -flags could not be executed')
-
- v['CXX'] = cc
- v['CXX_NAME'] = 'sun'
-
-@conftest
-def sxx_common_flags(conf):
- v = conf.env
-
- # CPPFLAGS CXXDEFINES _CXXINCFLAGS _CXXDEFFLAGS
-
- v['CXX_SRC_F'] = ''
- v['CXX_TGT_F'] = ['-c', '-o', '']
- v['CPPPATH_ST'] = '-I%s' # template for adding include paths
-
- # linker
- if not v['LINK_CXX']: v['LINK_CXX'] = v['CXX']
- v['CXXLNK_SRC_F'] = ''
- v['CXXLNK_TGT_F'] = ['-o', ''] # solaris hack, separate the -o from the target
-
- v['LIB_ST'] = '-l%s' # template for adding libs
- v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
- v['STATICLIB_ST'] = '-l%s'
- v['STATICLIBPATH_ST'] = '-L%s'
- v['CXXDEFINES_ST'] = '-D%s'
-
- v['SONAME_ST'] = '-Wl,-h -Wl,%s'
- v['SHLIB_MARKER'] = '-Bdynamic'
- v['STATICLIB_MARKER'] = '-Bstatic'
-
- # program
- v['program_PATTERN'] = '%s'
-
- # shared library
- v['shlib_CXXFLAGS'] = ['-Kpic', '-DPIC']
- v['shlib_LINKFLAGS'] = ['-G']
- v['shlib_PATTERN'] = 'lib%s.so'
-
- # static lib
- v['staticlib_LINKFLAGS'] = ['-Bstatic']
- v['staticlib_PATTERN'] = 'lib%s.a'
-
-detect = '''
-find_sxx
-find_cpp
-find_ar
-sxx_common_flags
-cxx_load_tools
-cxx_add_flags
-'''
-
diff --git a/tools/wafadmin/Tools/unittestw.py b/tools/wafadmin/Tools/unittestw.py
deleted file mode 100644
index b85ccc0fb..000000000
--- a/tools/wafadmin/Tools/unittestw.py
+++ /dev/null
@@ -1,305 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Carlos Rafael Giani, 2006
-
-"""
-Unit tests run in the shutdown() method, and for c/c++ programs
-
-One should NOT have to give parameters to programs to execute
-
-In the shutdown method, add the following code:
-
- >>> def shutdown():
- ... ut = UnitTest.unit_test()
- ... ut.run()
- ... ut.print_results()
-
-
-Each object to use as a unit test must be a program and must have X{obj.unit_test=1}
-"""
-import os, sys
-import Build, TaskGen, Utils, Options, Logs, Task
-from TaskGen import before, after, feature
-from Constants import *
-
-class unit_test(object):
- "Unit test representation"
- def __init__(self):
- self.returncode_ok = 0 # Unit test returncode considered OK. All returncodes differing from this one
- # will cause the unit test to be marked as "FAILED".
-
- # The following variables are filled with data by run().
-
- # print_results() uses these for printing the unit test summary,
- # but if there is need for direct access to the results,
- # they can be retrieved here, after calling run().
-
- self.num_tests_ok = 0 # Number of successful unit tests
- self.num_tests_failed = 0 # Number of failed unit tests
- self.num_tests_err = 0 # Tests that have not even run
- self.total_num_tests = 0 # Total amount of unit tests
- self.max_label_length = 0 # Maximum label length (pretty-print the output)
-
- self.unit_tests = Utils.ordered_dict() # Unit test dictionary. Key: the label (unit test filename relative
- # to the build dir), value: unit test filename with absolute path
- self.unit_test_results = {} # Dictionary containing the unit test results.
- # Key: the label, value: result (true = success false = failure)
- self.unit_test_erroneous = {} # Dictionary indicating erroneous unit tests.
- # Key: the label, value: true = unit test has an error false = unit test is ok
- self.change_to_testfile_dir = False #True if the test file needs to be executed from the same dir
- self.want_to_see_test_output = False #True to see the stdout from the testfile (for example check suites)
- self.want_to_see_test_error = False #True to see the stderr from the testfile (for example check suites)
- self.run_if_waf_does = 'check' #build was the old default
-
- def run(self):
- "Run the unit tests and gather results (note: no output here)"
-
- self.num_tests_ok = 0
- self.num_tests_failed = 0
- self.num_tests_err = 0
- self.total_num_tests = 0
- self.max_label_length = 0
-
- self.unit_tests = Utils.ordered_dict()
- self.unit_test_results = {}
- self.unit_test_erroneous = {}
-
- ld_library_path = []
-
- # If waf is not building, don't run anything
- if not Options.commands[self.run_if_waf_does]: return
-
- # Get the paths for the shared libraries, and obtain the unit tests to execute
- for obj in Build.bld.all_task_gen:
- try:
- link_task = obj.link_task
- except AttributeError:
- pass
- else:
- lib_path = link_task.outputs[0].parent.abspath(obj.env)
- if lib_path not in ld_library_path:
- ld_library_path.append(lib_path)
-
- unit_test = getattr(obj, 'unit_test', '')
- if unit_test and 'cprogram' in obj.features:
- try:
- output = obj.path
- filename = os.path.join(output.abspath(obj.env), obj.target)
- srcdir = output.abspath()
- label = os.path.join(output.bldpath(obj.env), obj.target)
- self.max_label_length = max(self.max_label_length, len(label))
- self.unit_tests[label] = (filename, srcdir)
- except KeyError:
- pass
- self.total_num_tests = len(self.unit_tests)
- # Now run the unit tests
- Utils.pprint('GREEN', 'Running the unit tests')
- count = 0
- result = 1
-
- for label in self.unit_tests.allkeys:
- file_and_src = self.unit_tests[label]
- filename = file_and_src[0]
- srcdir = file_and_src[1]
- count += 1
- line = Build.bld.progress_line(count, self.total_num_tests, Logs.colors.GREEN, Logs.colors.NORMAL)
- if Options.options.progress_bar and line:
- sys.stderr.write(line)
- sys.stderr.flush()
- try:
- kwargs = {}
- kwargs['env'] = os.environ.copy()
- if self.change_to_testfile_dir:
- kwargs['cwd'] = srcdir
- if not self.want_to_see_test_output:
- kwargs['stdout'] = Utils.pproc.PIPE # PIPE for ignoring output
- if not self.want_to_see_test_error:
- kwargs['stderr'] = Utils.pproc.PIPE # PIPE for ignoring output
- if ld_library_path:
- v = kwargs['env']
- def add_path(dct, path, var):
- dct[var] = os.pathsep.join(Utils.to_list(path) + [os.environ.get(var, '')])
- if sys.platform == 'win32':
- add_path(v, ld_library_path, 'PATH')
- elif sys.platform == 'darwin':
- add_path(v, ld_library_path, 'DYLD_LIBRARY_PATH')
- add_path(v, ld_library_path, 'LD_LIBRARY_PATH')
- else:
- add_path(v, ld_library_path, 'LD_LIBRARY_PATH')
-
- pp = Utils.pproc.Popen(filename, **kwargs)
- pp.wait()
-
- result = int(pp.returncode == self.returncode_ok)
-
- if result:
- self.num_tests_ok += 1
- else:
- self.num_tests_failed += 1
-
- self.unit_test_results[label] = result
- self.unit_test_erroneous[label] = 0
- except OSError:
- self.unit_test_erroneous[label] = 1
- self.num_tests_err += 1
- except KeyboardInterrupt:
- pass
- if Options.options.progress_bar: sys.stdout.write(Logs.colors.cursor_on)
-
- def print_results(self):
- "Pretty-prints a summary of all unit tests, along with some statistics"
-
- # If waf is not building, don't output anything
- if not Options.commands[self.run_if_waf_does]: return
-
- p = Utils.pprint
- # Early quit if no tests were performed
- if self.total_num_tests == 0:
- p('YELLOW', 'No unit tests present')
- return
-
- for label in self.unit_tests.allkeys:
- filename = self.unit_tests[label]
- err = 0
- result = 0
-
- try: err = self.unit_test_erroneous[label]
- except KeyError: pass
-
- try: result = self.unit_test_results[label]
- except KeyError: pass
-
- n = self.max_label_length - len(label)
- if err: n += 4
- elif result: n += 7
- else: n += 3
-
- line = '%s %s' % (label, '.' * n)
-
- if err: p('RED', '%sERROR' % line)
- elif result: p('GREEN', '%sOK' % line)
- else: p('YELLOW', '%sFAILED' % line)
-
- percentage_ok = float(self.num_tests_ok) / float(self.total_num_tests) * 100.0
- percentage_failed = float(self.num_tests_failed) / float(self.total_num_tests) * 100.0
- percentage_erroneous = float(self.num_tests_err) / float(self.total_num_tests) * 100.0
-
- p('NORMAL', '''
-Successful tests: %i (%.1f%%)
-Failed tests: %i (%.1f%%)
-Erroneous tests: %i (%.1f%%)
-
-Total number of tests: %i
-''' % (self.num_tests_ok, percentage_ok, self.num_tests_failed, percentage_failed,
- self.num_tests_err, percentage_erroneous, self.total_num_tests))
- p('GREEN', 'Unit tests finished')
-
-
-############################################################################################
-
-"""
-New unit test system
-
-The targets with feature 'test' are executed after they are built
-bld(features='cprogram cc test', ...)
-
-To display the results:
-import UnitTest
-bld.add_post_fun(UnitTest.summary)
-"""
-
-import threading
-testlock = threading.Lock()
-
-def set_options(opt):
- opt.add_option('--alltests', action='store_true', default=True, help='Exec all unit tests', dest='all_tests')
-
-@feature('test')
-@after('apply_link', 'vars_target_cprogram')
-def make_test(self):
- if not 'cprogram' in self.features:
- Logs.error('test cannot be executed %s' % self)
- return
-
- self.default_install_path = None
- self.create_task('utest', self.link_task.outputs)
-
-def exec_test(self):
-
- status = 0
-
- variant = self.env.variant()
- filename = self.inputs[0].abspath(self.env)
-
- try:
- fu = getattr(self.generator.bld, 'all_test_paths')
- except AttributeError:
- fu = os.environ.copy()
- self.generator.bld.all_test_paths = fu
-
- lst = []
- for obj in self.generator.bld.all_task_gen:
- link_task = getattr(obj, 'link_task', None)
- if link_task and link_task.env.variant() == variant:
- lst.append(link_task.outputs[0].parent.abspath(obj.env))
-
- def add_path(dct, path, var):
- dct[var] = os.pathsep.join(Utils.to_list(path) + [os.environ.get(var, '')])
-
- if sys.platform == 'win32':
- add_path(fu, lst, 'PATH')
- elif sys.platform == 'darwin':
- add_path(fu, lst, 'DYLD_LIBRARY_PATH')
- add_path(fu, lst, 'LD_LIBRARY_PATH')
- else:
- add_path(fu, lst, 'LD_LIBRARY_PATH')
-
-
- cwd = getattr(self.generator, 'ut_cwd', '') or self.inputs[0].parent.abspath(self.env)
- proc = Utils.pproc.Popen(filename, cwd=cwd, env=fu, stderr=Utils.pproc.PIPE, stdout=Utils.pproc.PIPE)
- (stdout, stderr) = proc.communicate()
-
- tup = (filename, proc.returncode, stdout, stderr)
- self.generator.utest_result = tup
-
- testlock.acquire()
- try:
- bld = self.generator.bld
- Logs.debug("ut: %r", tup)
- try:
- bld.utest_results.append(tup)
- except AttributeError:
- bld.utest_results = [tup]
- finally:
- testlock.release()
-
-cls = Task.task_type_from_func('utest', func=exec_test, color='PINK', ext_in='.bin')
-
-old = cls.runnable_status
-def test_status(self):
- if getattr(Options.options, 'all_tests', False):
- return RUN_ME
- return old(self)
-
-cls.runnable_status = test_status
-cls.quiet = 1
-
-def summary(bld):
- lst = getattr(bld, 'utest_results', [])
- if lst:
- Utils.pprint('CYAN', 'execution summary')
-
- total = len(lst)
- tfail = len([x for x in lst if x[1]])
-
- Utils.pprint('CYAN', ' tests that pass %d/%d' % (total-tfail, total))
- for (f, code, out, err) in lst:
- if not code:
- Utils.pprint('CYAN', ' %s' % f)
-
- Utils.pprint('CYAN', ' tests that fail %d/%d' % (tfail, total))
- for (f, code, out, err) in lst:
- if code:
- Utils.pprint('CYAN', ' %s' % f)
-
-
diff --git a/tools/wafadmin/Tools/winres.py b/tools/wafadmin/Tools/winres.py
deleted file mode 100644
index 2500d431d..000000000
--- a/tools/wafadmin/Tools/winres.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Brant Young, 2007
-
-"This hook is called when the class cpp/cc task generator encounters a '.rc' file: X{.rc -> [.res|.rc.o]}"
-
-import os, sys, re
-import TaskGen, Task
-from Utils import quote_whitespace
-from TaskGen import extension
-
-EXT_WINRC = ['.rc']
-
-winrc_str = '${WINRC} ${_CPPDEFFLAGS} ${_CCDEFFLAGS} ${WINRCFLAGS} ${_CPPINCFLAGS} ${_CCINCFLAGS} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}'
-
-@extension(EXT_WINRC)
-def rc_file(self, node):
- obj_ext = '.rc.o'
- if self.env['WINRC_TGT_F'] == '/fo': obj_ext = '.res'
-
- rctask = self.create_task('winrc', node, node.change_ext(obj_ext))
- self.compiled_tasks.append(rctask)
-
-# create our action, for use with rc file
-Task.simple_task_type('winrc', winrc_str, color='BLUE', before='cc cxx', shell=False)
-
-def detect(conf):
- v = conf.env
-
- winrc = v['WINRC']
- v['WINRC_TGT_F'] = '-o'
- v['WINRC_SRC_F'] = '-i'
- # find rc.exe
- if not winrc:
- if v['CC_NAME'] in ['gcc', 'cc', 'g++', 'c++']:
- winrc = conf.find_program('windres', var='WINRC', path_list = v['PATH'])
- elif v['CC_NAME'] == 'msvc':
- winrc = conf.find_program('RC', var='WINRC', path_list = v['PATH'])
- v['WINRC_TGT_F'] = '/fo'
- v['WINRC_SRC_F'] = ''
- if not winrc:
- conf.fatal('winrc was not found!')
-
- v['WINRCFLAGS'] = ''
-
diff --git a/tools/wafadmin/Tools/xlc.py b/tools/wafadmin/Tools/xlc.py
deleted file mode 100644
index e787f7dfc..000000000
--- a/tools/wafadmin/Tools/xlc.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006-2008 (ita)
-# Ralf Habacker, 2006 (rh)
-# Yinon Ehrlich, 2009
-# Michael Kuhn, 2009
-
-import os, sys
-import Configure, Options, Utils
-import ccroot, ar
-from Configure import conftest
-
-@conftest
-def find_xlc(conf):
- cc = conf.find_program(['xlc_r', 'xlc'], var='CC', mandatory=True)
- cc = conf.cmd_to_list(cc)
- conf.env.CC_NAME = 'xlc'
- conf.env.CC = cc
-
-@conftest
-def find_cpp(conf):
- v = conf.env
- cpp = None
- if v['CPP']: cpp = v['CPP']
- elif 'CPP' in conf.environ: cpp = conf.environ['CPP']
- if not cpp: cpp = v['CC']
- v['CPP'] = cpp
-
-@conftest
-def xlc_common_flags(conf):
- v = conf.env
-
- # CPPFLAGS CCDEFINES _CCINCFLAGS _CCDEFFLAGS
- v['CCFLAGS_DEBUG'] = ['-g']
- v['CCFLAGS_RELEASE'] = ['-O2']
-
- v['CC_SRC_F'] = ''
- v['CC_TGT_F'] = ['-c', '-o', ''] # shell hack for -MD
- v['CPPPATH_ST'] = '-I%s' # template for adding include paths
-
- # linker
- if not v['LINK_CC']: v['LINK_CC'] = v['CC']
- v['CCLNK_SRC_F'] = ''
- v['CCLNK_TGT_F'] = ['-o', ''] # shell hack for -MD
-
- v['LIB_ST'] = '-l%s' # template for adding libs
- v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
- v['STATICLIB_ST'] = '-l%s'
- v['STATICLIBPATH_ST'] = '-L%s'
- v['RPATH_ST'] = '-Wl,-rpath,%s'
- v['CCDEFINES_ST'] = '-D%s'
-
- v['SONAME_ST'] = ''
- v['SHLIB_MARKER'] = ''
- v['STATICLIB_MARKER'] = ''
- v['FULLSTATIC_MARKER'] = '-static'
-
- # program
- v['program_LINKFLAGS'] = ['-Wl,-brtl']
- v['program_PATTERN'] = '%s'
-
- # shared library
- v['shlib_CCFLAGS'] = ['-fPIC', '-DPIC'] # avoid using -DPIC, -fPIC aleady defines the __PIC__ macro
- v['shlib_LINKFLAGS'] = ['-G', '-Wl,-brtl,-bexpfull']
- v['shlib_PATTERN'] = 'lib%s.so'
-
- # static lib
- v['staticlib_LINKFLAGS'] = ''
- v['staticlib_PATTERN'] = 'lib%s.a'
-
-def detect(conf):
- conf.find_xlc()
- conf.find_cpp()
- conf.find_ar()
- conf.xlc_common_flags()
- conf.cc_load_tools()
- conf.cc_add_flags()
diff --git a/tools/wafadmin/Tools/xlcxx.py b/tools/wafadmin/Tools/xlcxx.py
deleted file mode 100644
index 696fcae66..000000000
--- a/tools/wafadmin/Tools/xlcxx.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2006 (ita)
-# Ralf Habacker, 2006 (rh)
-# Yinon Ehrlich, 2009
-# Michael Kuhn, 2009
-
-import os, sys
-import Configure, Options, Utils
-import ccroot, ar
-from Configure import conftest
-
-@conftest
-def find_xlcxx(conf):
- cxx = conf.find_program(['xlc++_r', 'xlc++'], var='CXX', mandatory=True)
- cxx = conf.cmd_to_list(cxx)
- conf.env.CXX_NAME = 'xlc++'
- conf.env.CXX = cxx
-
-@conftest
-def find_cpp(conf):
- v = conf.env
- cpp = None
- if v['CPP']: cpp = v['CPP']
- elif 'CPP' in conf.environ: cpp = conf.environ['CPP']
- if not cpp: cpp = v['CXX']
- v['CPP'] = cpp
-
-@conftest
-def xlcxx_common_flags(conf):
- v = conf.env
-
- # CPPFLAGS CXXDEFINES _CXXINCFLAGS _CXXDEFFLAGS
- v['CXXFLAGS_DEBUG'] = ['-g']
- v['CXXFLAGS_RELEASE'] = ['-O2']
-
- v['CXX_SRC_F'] = ''
- v['CXX_TGT_F'] = ['-c', '-o', ''] # shell hack for -MD
- v['CPPPATH_ST'] = '-I%s' # template for adding include paths
-
- # linker
- if not v['LINK_CXX']: v['LINK_CXX'] = v['CXX']
- v['CXXLNK_SRC_F'] = ''
- v['CXXLNK_TGT_F'] = ['-o', ''] # shell hack for -MD
-
- v['LIB_ST'] = '-l%s' # template for adding libs
- v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
- v['STATICLIB_ST'] = '-l%s'
- v['STATICLIBPATH_ST'] = '-L%s'
- v['RPATH_ST'] = '-Wl,-rpath,%s'
- v['CXXDEFINES_ST'] = '-D%s'
-
- v['SONAME_ST'] = ''
- v['SHLIB_MARKER'] = ''
- v['STATICLIB_MARKER'] = ''
- v['FULLSTATIC_MARKER'] = '-static'
-
- # program
- v['program_LINKFLAGS'] = ['-Wl,-brtl']
- v['program_PATTERN'] = '%s'
-
- # shared library
- v['shlib_CXXFLAGS'] = ['-fPIC', '-DPIC'] # avoid using -DPIC, -fPIC aleady defines the __PIC__ macro
- v['shlib_LINKFLAGS'] = ['-G', '-Wl,-brtl,-bexpfull']
- v['shlib_PATTERN'] = 'lib%s.so'
-
- # static lib
- v['staticlib_LINKFLAGS'] = ''
- v['staticlib_PATTERN'] = 'lib%s.a'
-
-def detect(conf):
- conf.find_xlcxx()
- conf.find_cpp()
- conf.find_ar()
- conf.xlcxx_common_flags()
- conf.cxx_load_tools()
- conf.cxx_add_flags()
diff --git a/tools/wafadmin/Utils.py b/tools/wafadmin/Utils.py
deleted file mode 100644
index b86b76f45..000000000
--- a/tools/wafadmin/Utils.py
+++ /dev/null
@@ -1,707 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005 (ita)
-
-"""
-Utilities, the stable ones are the following:
-
-* h_file: compute a unique value for a file (hash), it uses
- the module fnv if it is installed (see waf/utils/fnv & http://code.google.com/p/waf/wiki/FAQ)
- else, md5 (see the python docs)
-
- For large projects (projects with more than 15000 files) or slow hard disks and filesystems (HFS)
- it is possible to use a hashing based on the path and the size (may give broken cache results)
- The method h_file MUST raise an OSError if the file is a folder
-
- import stat
- def h_file(filename):
- st = os.stat(filename)
- if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
- m = Utils.md5()
- m.update(str(st.st_mtime))
- m.update(str(st.st_size))
- m.update(filename)
- return m.digest()
-
- To replace the function in your project, use something like this:
- import Utils
- Utils.h_file = h_file
-
-* h_list
-* h_fun
-* get_term_cols
-* ordered_dict
-
-"""
-
-import os, sys, imp, string, errno, traceback, inspect, re, shutil, datetime, gc
-
-# In python 3.0 we can get rid of all this
-try: from UserDict import UserDict
-except ImportError: from collections import UserDict
-if sys.hexversion >= 0x2060000 or os.name == 'java':
- import subprocess as pproc
-else:
- import pproc
-import Logs
-from Constants import *
-
-try:
- from collections import deque
-except ImportError:
- class deque(list):
- def popleft(self):
- return self.pop(0)
-
-is_win32 = sys.platform == 'win32'
-
-try:
- # defaultdict in python 2.5
- from collections import defaultdict as DefaultDict
-except ImportError:
- class DefaultDict(dict):
- def __init__(self, default_factory):
- super(DefaultDict, self).__init__()
- self.default_factory = default_factory
- def __getitem__(self, key):
- try:
- return super(DefaultDict, self).__getitem__(key)
- except KeyError:
- value = self.default_factory()
- self[key] = value
- return value
-
-class WafError(Exception):
- def __init__(self, *args):
- self.args = args
- try:
- self.stack = traceback.extract_stack()
- except:
- pass
- Exception.__init__(self, *args)
- def __str__(self):
- return str(len(self.args) == 1 and self.args[0] or self.args)
-
-class WscriptError(WafError):
- def __init__(self, message, wscript_file=None):
- if wscript_file:
- self.wscript_file = wscript_file
- self.wscript_line = None
- else:
- try:
- (self.wscript_file, self.wscript_line) = self.locate_error()
- except:
- (self.wscript_file, self.wscript_line) = (None, None)
-
- msg_file_line = ''
- if self.wscript_file:
- msg_file_line = "%s:" % self.wscript_file
- if self.wscript_line:
- msg_file_line += "%s:" % self.wscript_line
- err_message = "%s error: %s" % (msg_file_line, message)
- WafError.__init__(self, err_message)
-
- def locate_error(self):
- stack = traceback.extract_stack()
- stack.reverse()
- for frame in stack:
- file_name = os.path.basename(frame[0])
- is_wscript = (file_name == WSCRIPT_FILE or file_name == WSCRIPT_BUILD_FILE)
- if is_wscript:
- return (frame[0], frame[1])
- return (None, None)
-
-indicator = is_win32 and '\x1b[A\x1b[K%s%s%s\r' or '\x1b[K%s%s%s\r'
-
-try:
- from fnv import new as md5
- import Constants
- Constants.SIG_NIL = 'signofnv'
-
- def h_file(filename):
- m = md5()
- try:
- m.hfile(filename)
- x = m.digest()
- if x is None: raise OSError("not a file")
- return x
- except SystemError:
- raise OSError("not a file" + filename)
-
-except ImportError:
- try:
- try:
- from hashlib import md5
- except ImportError:
- from md5 import md5
-
- def h_file(filename):
- f = open(filename, 'rb')
- m = md5()
- while (filename):
- filename = f.read(100000)
- m.update(filename)
- f.close()
- return m.digest()
- except ImportError:
- # portability fixes may be added elsewhere (although, md5 should be everywhere by now)
- md5 = None
-
-class ordered_dict(UserDict):
- def __init__(self, dict = None):
- self.allkeys = []
- UserDict.__init__(self, dict)
-
- def __delitem__(self, key):
- self.allkeys.remove(key)
- UserDict.__delitem__(self, key)
-
- def __setitem__(self, key, item):
- if key not in self.allkeys: self.allkeys.append(key)
- UserDict.__setitem__(self, key, item)
-
-def exec_command(s, **kw):
- if 'log' in kw:
- kw['stdout'] = kw['stderr'] = kw['log']
- del(kw['log'])
- kw['shell'] = isinstance(s, str)
-
- try:
- proc = pproc.Popen(s, **kw)
- return proc.wait()
- except OSError:
- return -1
-
-if is_win32:
- def exec_command(s, **kw):
- if 'log' in kw:
- kw['stdout'] = kw['stderr'] = kw['log']
- del(kw['log'])
- kw['shell'] = isinstance(s, str)
-
- if len(s) > 2000:
- startupinfo = pproc.STARTUPINFO()
- startupinfo.dwFlags |= pproc.STARTF_USESHOWWINDOW
- kw['startupinfo'] = startupinfo
-
- try:
- if 'stdout' not in kw:
- kw['stdout'] = pproc.PIPE
- kw['stderr'] = pproc.PIPE
- proc = pproc.Popen(s,**kw)
- (stdout, stderr) = proc.communicate()
- Logs.info(stdout)
- if stderr:
- Logs.error(stderr)
- return proc.returncode
- else:
- proc = pproc.Popen(s,**kw)
- return proc.wait()
- except OSError:
- return -1
-
-listdir = os.listdir
-if is_win32:
- def listdir_win32(s):
- if re.match('^[A-Za-z]:$', s):
- # os.path.isdir fails if s contains only the drive name... (x:)
- s += os.sep
- if not os.path.isdir(s):
- e = OSError()
- e.errno = errno.ENOENT
- raise e
- return os.listdir(s)
- listdir = listdir_win32
-
-def waf_version(mini = 0x010000, maxi = 0x100000):
- "Halts if the waf version is wrong"
- ver = HEXVERSION
- try: min_val = mini + 0
- except TypeError: min_val = int(mini.replace('.', '0'), 16)
-
- if min_val > ver:
- Logs.error("waf version should be at least %s (%s found)" % (mini, ver))
- sys.exit(0)
-
- try: max_val = maxi + 0
- except TypeError: max_val = int(maxi.replace('.', '0'), 16)
-
- if max_val < ver:
- Logs.error("waf version should be at most %s (%s found)" % (maxi, ver))
- sys.exit(0)
-
-def python_24_guard():
- if sys.hexversion < 0x20400f0 or sys.hexversion >= 0x3000000:
- raise ImportError("Waf requires Python >= 2.3 but the raw source requires Python 2.4, 2.5 or 2.6")
-
-def ex_stack():
- exc_type, exc_value, tb = sys.exc_info()
- if Logs.verbose > 1:
- exc_lines = traceback.format_exception(exc_type, exc_value, tb)
- return ''.join(exc_lines)
- return str(exc_value)
-
-def to_list(sth):
- if isinstance(sth, str):
- return sth.split()
- else:
- return sth
-
-g_loaded_modules = {}
-"index modules by absolute path"
-
-g_module=None
-"the main module is special"
-
-def load_module(file_path, name=WSCRIPT_FILE):
- "this function requires an absolute path"
- try:
- return g_loaded_modules[file_path]
- except KeyError:
- pass
-
- module = imp.new_module(name)
-
- try:
- code = readf(file_path, m='rU')
- except (IOError, OSError):
- raise WscriptError('Could not read the file %r' % file_path)
-
- module.waf_hash_val = code
-
- sys.path.insert(0, os.path.dirname(file_path))
- try:
- exec(compile(code, file_path, 'exec'), module.__dict__)
- except Exception:
- exc_type, exc_value, tb = sys.exc_info()
- raise WscriptError("".join(traceback.format_exception(exc_type, exc_value, tb)), file_path)
- sys.path.pop(0)
-
- g_loaded_modules[file_path] = module
-
- return module
-
-def set_main_module(file_path):
- "Load custom options, if defined"
- global g_module
- g_module = load_module(file_path, 'wscript_main')
- g_module.root_path = file_path
-
- try:
- g_module.APPNAME
- except:
- g_module.APPNAME = 'noname'
- try:
- g_module.VERSION
- except:
- g_module.VERSION = '1.0'
-
- # note: to register the module globally, use the following:
- # sys.modules['wscript_main'] = g_module
-
-def to_hashtable(s):
- "used for importing env files"
- tbl = {}
- lst = s.split('\n')
- for line in lst:
- if not line: continue
- mems = line.split('=')
- tbl[mems[0]] = mems[1]
- return tbl
-
-def get_term_cols():
- "console width"
- return 80
-try:
- import struct, fcntl, termios
-except ImportError:
- pass
-else:
- if Logs.got_tty:
- def myfun():
- dummy_lines, cols = struct.unpack("HHHH", \
- fcntl.ioctl(sys.stderr.fileno(),termios.TIOCGWINSZ , \
- struct.pack("HHHH", 0, 0, 0, 0)))[:2]
- return cols
- # we actually try the function once to see if it is suitable
- try:
- myfun()
- except:
- pass
- else:
- get_term_cols = myfun
-
-rot_idx = 0
-rot_chr = ['\\', '|', '/', '-']
-"the rotation character in the progress bar"
-
-
-def split_path(path):
- return path.split('/')
-
-def split_path_cygwin(path):
- if path.startswith('//'):
- ret = path.split('/')[2:]
- ret[0] = '/' + ret[0]
- return ret
- return path.split('/')
-
-re_sp = re.compile('[/\\\\]')
-def split_path_win32(path):
- if path.startswith('\\\\'):
- ret = re.split(re_sp, path)[2:]
- ret[0] = '\\' + ret[0]
- return ret
- return re.split(re_sp, path)
-
-if sys.platform == 'cygwin':
- split_path = split_path_cygwin
-elif is_win32:
- split_path = split_path_win32
-
-def copy_attrs(orig, dest, names, only_if_set=False):
- for a in to_list(names):
- u = getattr(orig, a, ())
- if u or not only_if_set:
- setattr(dest, a, u)
-
-def def_attrs(cls, **kw):
- '''
- set attributes for class.
- @param cls [any class]: the class to update the given attributes in.
- @param kw [dictionary]: dictionary of attributes names and values.
-
- if the given class hasn't one (or more) of these attributes, add the attribute with its value to the class.
- '''
- for k, v in kw.iteritems():
- if not hasattr(cls, k):
- setattr(cls, k, v)
-
-def quote_define_name(path):
- fu = re.compile("[^a-zA-Z0-9]").sub("_", path)
- fu = fu.upper()
- return fu
-
-def quote_whitespace(path):
- return (path.strip().find(' ') > 0 and '"%s"' % path or path).replace('""', '"')
-
-def trimquotes(s):
- if not s: return ''
- s = s.rstrip()
- if s[0] == "'" and s[-1] == "'": return s[1:-1]
- return s
-
-def h_list(lst):
- m = md5()
- m.update(str(lst))
- return m.digest()
-
-def h_fun(fun):
- try:
- return fun.code
- except AttributeError:
- try:
- h = inspect.getsource(fun)
- except IOError:
- h = "nocode"
- try:
- fun.code = h
- except AttributeError:
- pass
- return h
-
-def pprint(col, str, label='', sep=os.linesep):
- "print messages in color"
- sys.stderr.write("%s%s%s %s%s" % (Logs.colors(col), str, Logs.colors.NORMAL, label, sep))
-
-def check_dir(dir):
- """If a folder doesn't exists, create it."""
- try:
- os.stat(dir)
- except OSError:
- try:
- os.makedirs(dir)
- except OSError, e:
- raise WafError("Cannot create folder '%s' (original error: %s)" % (dir, e))
-
-def cmd_output(cmd, **kw):
-
- silent = False
- if 'silent' in kw:
- silent = kw['silent']
- del(kw['silent'])
-
- if 'e' in kw:
- tmp = kw['e']
- del(kw['e'])
- kw['env'] = tmp
-
- kw['shell'] = isinstance(cmd, str)
- kw['stdout'] = pproc.PIPE
- if silent:
- kw['stderr'] = pproc.PIPE
-
- try:
- p = pproc.Popen(cmd, **kw)
- output = p.communicate()[0]
- except OSError, e:
- raise ValueError(str(e))
-
- if p.returncode:
- if not silent:
- msg = "command execution failed: %s -> %r" % (cmd, str(output))
- raise ValueError(msg)
- output = ''
- return output
-
-reg_subst = re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}")
-def subst_vars(expr, params):
- "substitute ${PREFIX}/bin in /usr/local/bin"
- def repl_var(m):
- if m.group(1):
- return '\\'
- if m.group(2):
- return '$'
- try:
- # environments may contain lists
- return params.get_flat(m.group(3))
- except AttributeError:
- return params[m.group(3)]
- return reg_subst.sub(repl_var, expr)
-
-def unversioned_sys_platform_to_binary_format(unversioned_sys_platform):
- "infers the binary format from the unversioned_sys_platform name."
-
- if unversioned_sys_platform in ('linux', 'freebsd', 'netbsd', 'openbsd', 'sunos'):
- return 'elf'
- elif unversioned_sys_platform == 'darwin':
- return 'mac-o'
- elif unversioned_sys_platform in ('win32', 'cygwin', 'uwin', 'msys'):
- return 'pe'
- # TODO we assume all other operating systems are elf, which is not true.
- # we may set this to 'unknown' and have ccroot and other tools handle the case "gracefully" (whatever that means).
- return 'elf'
-
-def unversioned_sys_platform():
- """returns an unversioned name from sys.platform.
- sys.plaform is not very well defined and depends directly on the python source tree.
- The version appended to the names is unreliable as it's taken from the build environment at the time python was built,
- i.e., it's possible to get freebsd7 on a freebsd8 system.
- So we remove the version from the name, except for special cases where the os has a stupid name like os2 or win32.
- Some possible values of sys.platform are, amongst others:
- aix3 aix4 atheos beos5 darwin freebsd2 freebsd3 freebsd4 freebsd5 freebsd6 freebsd7
- generic irix5 irix6 linux2 mac netbsd1 next3 os2emx riscos sunos5 unixware7
- Investigating the python source tree may reveal more values.
- """
- s = sys.platform
- if s == 'java':
- # The real OS is hidden under the JVM.
- from java.lang import System
- s = System.getProperty('os.name')
- # see http://lopica.sourceforge.net/os.html for a list of possible values
- if s == 'Mac OS X':
- return 'darwin'
- elif s.startswith('Windows '):
- return 'win32'
- elif s == 'OS/2':
- return 'os2'
- elif s == 'HP-UX':
- return 'hpux'
- elif s in ('SunOS', 'Solaris'):
- return 'sunos'
- else: s = s.lower()
- if s == 'win32' or s.endswith('os2') and s != 'sunos2': return s
- return re.split('\d+$', s)[0]
-
-#@deprecated('use unversioned_sys_platform instead')
-def detect_platform():
- """this function has been in the Utils module for some time.
- It's hard to guess what people have used it for.
- It seems its goal is to return an unversionned sys.platform, but it's not handling all platforms.
- For example, the version is not removed on freebsd and netbsd, amongst others.
- """
- s = sys.platform
-
- # known POSIX
- for x in 'cygwin linux irix sunos hpux aix darwin'.split():
- # sys.platform may be linux2
- if s.find(x) >= 0:
- return x
-
- # unknown POSIX
- if os.name in 'posix java os2'.split():
- return os.name
-
- return s
-
-def load_tool(tool, tooldir=None):
- '''
- load_tool: import a Python module, optionally using several directories.
- @param tool [string]: name of tool to import.
- @param tooldir [list]: directories to look for the tool.
- @return: the loaded module.
-
- Warning: this function is not thread-safe: plays with sys.path,
- so must run in sequence.
- '''
- if tooldir:
- assert isinstance(tooldir, list)
- sys.path = tooldir + sys.path
- try:
- try:
- return __import__(tool)
- except ImportError, e:
- Logs.error('Could not load the tool %r in %r:\n%s' % (tool, sys.path, e))
- raise
- finally:
- if tooldir:
- sys.path = sys.path[len(tooldir):]
-
-def readf(fname, m='r'):
- "get the contents of a file, it is not used anywhere for the moment"
- f = open(fname, m)
- try:
- txt = f.read()
- finally:
- f.close()
- return txt
-
-def nada(*k, **kw):
- """A function that does nothing"""
- pass
-
-def diff_path(top, subdir):
- """difference between two absolute paths"""
- top = os.path.normpath(top).replace('\\', '/').split('/')
- subdir = os.path.normpath(subdir).replace('\\', '/').split('/')
- if len(top) == len(subdir): return ''
- diff = subdir[len(top) - len(subdir):]
- return os.path.join(*diff)
-
-class Context(object):
- """A base class for commands to be executed from Waf scripts"""
-
- def set_curdir(self, dir):
- self.curdir_ = dir
-
- def get_curdir(self):
- try:
- return self.curdir_
- except AttributeError:
- self.curdir_ = os.getcwd()
- return self.get_curdir()
-
- curdir = property(get_curdir, set_curdir)
-
- def recurse(self, dirs, name=''):
- """The function for calling scripts from folders, it tries to call wscript + function_name
- and if that file does not exist, it will call the method 'function_name' from a file named wscript
- the dirs can be a list of folders or a string containing space-separated folder paths
- """
- if not name:
- name = inspect.stack()[1][3]
-
- if isinstance(dirs, str):
- dirs = to_list(dirs)
-
- for x in dirs:
- if os.path.isabs(x):
- nexdir = x
- else:
- nexdir = os.path.join(self.curdir, x)
-
- base = os.path.join(nexdir, WSCRIPT_FILE)
- file_path = base + '_' + name
-
- try:
- txt = readf(file_path, m='rU')
- except (OSError, IOError):
- try:
- module = load_module(base)
- except OSError:
- raise WscriptError('No such script %s' % base)
-
- try:
- f = module.__dict__[name]
- except KeyError:
- raise WscriptError('No function %s defined in %s' % (name, base))
-
- if getattr(self.__class__, 'pre_recurse', None):
- self.pre_recurse(f, base, nexdir)
- old = self.curdir
- self.curdir = nexdir
- try:
- f(self)
- finally:
- self.curdir = old
- if getattr(self.__class__, 'post_recurse', None):
- self.post_recurse(module, base, nexdir)
- else:
- dc = {'ctx': self}
- if getattr(self.__class__, 'pre_recurse', None):
- dc = self.pre_recurse(txt, file_path, nexdir)
- old = self.curdir
- self.curdir = nexdir
- try:
- try:
- exec(compile(txt, file_path, 'exec'), dc)
- except Exception:
- exc_type, exc_value, tb = sys.exc_info()
- raise WscriptError("".join(traceback.format_exception(exc_type, exc_value, tb)), base)
- finally:
- self.curdir = old
- if getattr(self.__class__, 'post_recurse', None):
- self.post_recurse(txt, file_path, nexdir)
-
-if is_win32:
- old = shutil.copy2
- def copy2(src, dst):
- old(src, dst)
- shutil.copystat(src, src)
- setattr(shutil, 'copy2', copy2)
-
-def zip_folder(dir, zip_file_name, prefix):
- """
- prefix represents the app to add in the archive
- """
- import zipfile
- zip = zipfile.ZipFile(zip_file_name, 'w', compression=zipfile.ZIP_DEFLATED)
- base = os.path.abspath(dir)
-
- if prefix:
- if prefix[-1] != os.sep:
- prefix += os.sep
-
- n = len(base)
- for root, dirs, files in os.walk(base):
- for f in files:
- archive_name = prefix + root[n:] + os.sep + f
- zip.write(root + os.sep + f, archive_name, zipfile.ZIP_DEFLATED)
- zip.close()
-
-def get_elapsed_time(start):
- "Format a time delta (datetime.timedelta) using the format DdHhMmS.MSs"
- delta = datetime.datetime.now() - start
- # cast to int necessary for python 3.0
- days = int(delta.days)
- hours = int(delta.seconds / 3600)
- minutes = int((delta.seconds - hours * 3600) / 60)
- seconds = delta.seconds - hours * 3600 - minutes * 60 \
- + float(delta.microseconds) / 1000 / 1000
- result = ''
- if days:
- result += '%dd' % days
- if days or hours:
- result += '%dh' % hours
- if days or hours or minutes:
- result += '%dm' % minutes
- return '%s%.3fs' % (result, seconds)
-
-if os.name == 'java':
- # For Jython (they should really fix the inconsistency)
- try:
- gc.disable()
- gc.enable()
- except NotImplementedError:
- gc.disable = gc.enable
-
diff --git a/tools/wafadmin/__init__.py b/tools/wafadmin/__init__.py
deleted file mode 100644
index 01273cfd0..000000000
--- a/tools/wafadmin/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2005 (ita)
diff --git a/tools/wafadmin/ansiterm.py b/tools/wafadmin/ansiterm.py
deleted file mode 100644
index 8e71313b2..000000000
--- a/tools/wafadmin/ansiterm.py
+++ /dev/null
@@ -1,221 +0,0 @@
-import sys, os
-try:
- if (not sys.stderr.isatty()) or (not sys.stdout.isatty()):
- raise ValueError('not a tty')
-
- from ctypes import *
-
- class COORD(Structure):
- _fields_ = [("X", c_short), ("Y", c_short)]
-
- class SMALL_RECT(Structure):
- _fields_ = [("Left", c_short), ("Top", c_short), ("Right", c_short), ("Bottom", c_short)]
-
- class CONSOLE_SCREEN_BUFFER_INFO(Structure):
- _fields_ = [("Size", COORD), ("CursorPosition", COORD), ("Attributes", c_short), ("Window", SMALL_RECT), ("MaximumWindowSize", COORD)]
-
- class CONSOLE_CURSOR_INFO(Structure):
- _fields_ = [('dwSize',c_ulong), ('bVisible', c_int)]
-
- sbinfo = CONSOLE_SCREEN_BUFFER_INFO()
- csinfo = CONSOLE_CURSOR_INFO()
- hconsole = windll.kernel32.GetStdHandle(-11)
- windll.kernel32.GetConsoleScreenBufferInfo(hconsole, byref(sbinfo))
- if sbinfo.Size.X < 10 or sbinfo.Size.Y < 10: raise Exception('small console')
- windll.kernel32.GetConsoleCursorInfo(hconsole, byref(csinfo))
-except Exception:
- pass
-else:
- import re, threading
-
- to_int = lambda number, default: number and int(number) or default
- wlock = threading.Lock()
-
- STD_OUTPUT_HANDLE = -11
- STD_ERROR_HANDLE = -12
-
- class AnsiTerm(object):
- def __init__(self):
- self.hconsole = windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
- self.cursor_history = []
-
- def screen_buffer_info(self):
- sbinfo = CONSOLE_SCREEN_BUFFER_INFO()
- windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(sbinfo))
- return sbinfo
-
- def clear_line(self, param):
- mode = param and int(param) or 0
- sbinfo = self.screen_buffer_info()
- if mode == 1: # Clear from begining of line to cursor position
- line_start = COORD(0, sbinfo.CursorPosition.Y)
- line_length = sbinfo.Size.X
- elif mode == 2: # Clear entire line
- line_start = COORD(sbinfo.CursorPosition.X, sbinfo.CursorPosition.Y)
- line_length = sbinfo.Size.X - sbinfo.CursorPosition.X
- else: # Clear from cursor position to end of line
- line_start = sbinfo.CursorPosition
- line_length = sbinfo.Size.X - sbinfo.CursorPosition.X
- chars_written = c_int()
- windll.kernel32.FillConsoleOutputCharacterA(self.hconsole, c_char(' '), line_length, line_start, byref(chars_written))
- windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, line_length, line_start, byref(chars_written))
-
- def clear_screen(self, param):
- mode = to_int(param, 0)
- sbinfo = self.screen_buffer_info()
- if mode == 1: # Clear from begining of screen to cursor position
- clear_start = COORD(0, 0)
- clear_length = sbinfo.CursorPosition.X * sbinfo.CursorPosition.Y
- elif mode == 2: # Clear entire screen and return cursor to home
- clear_start = COORD(0, 0)
- clear_length = sbinfo.Size.X * sbinfo.Size.Y
- windll.kernel32.SetConsoleCursorPosition(self.hconsole, clear_start)
- else: # Clear from cursor position to end of screen
- clear_start = sbinfo.CursorPosition
- clear_length = ((sbinfo.Size.X - sbinfo.CursorPosition.X) + sbinfo.Size.X * (sbinfo.Size.Y - sbinfo.CursorPosition.Y))
- chars_written = c_int()
- windll.kernel32.FillConsoleOutputCharacterA(self.hconsole, c_char(' '), clear_length, clear_start, byref(chars_written))
- windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, clear_length, clear_start, byref(chars_written))
-
- def push_cursor(self, param):
- sbinfo = self.screen_buffer_info()
- self.cursor_history.push(sbinfo.CursorPosition)
-
- def pop_cursor(self, param):
- if self.cursor_history:
- old_pos = self.cursor_history.pop()
- windll.kernel32.SetConsoleCursorPosition(self.hconsole, old_pos)
-
- def set_cursor(self, param):
- x, sep, y = param.partition(';')
- x = to_int(x, 1) - 1
- y = to_int(y, 1) - 1
- sbinfo = self.screen_buffer_info()
- new_pos = COORD(
- min(max(0, x), sbinfo.Size.X),
- min(max(0, y), sbinfo.Size.Y)
- )
- windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos)
-
- def set_column(self, param):
- x = to_int(param, 1) - 1
- sbinfo = self.screen_buffer_info()
- new_pos = COORD(
- min(max(0, x), sbinfo.Size.X),
- sbinfo.CursorPosition.Y
- )
- windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos)
-
- def move_cursor(self, x_offset=0, y_offset=0):
- sbinfo = self.screen_buffer_info()
- new_pos = COORD(
- min(max(0, sbinfo.CursorPosition.X + x_offset), sbinfo.Size.X),
- min(max(0, sbinfo.CursorPosition.Y + y_offset), sbinfo.Size.Y)
- )
- windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos)
-
- def move_up(self, param):
- self.move_cursor(y_offset = -to_int(param, 1))
-
- def move_down(self, param):
- self.move_cursor(y_offset = to_int(param, 1))
-
- def move_left(self, param):
- self.move_cursor(x_offset = -to_int(param, 1))
-
- def move_right(self, param):
- self.move_cursor(x_offset = to_int(param, 1))
-
- def next_line(self, param):
- sbinfo = self.screen_buffer_info()
- self.move_cursor(
- x_offset = -sbinfo.CursorPosition.X,
- y_offset = to_int(param, 1)
- )
-
- def prev_line(self, param):
- sbinfo = self.screen_buffer_info()
- self.move_cursor(
- x_offset = -sbinfo.CursorPosition.X,
- y_offset = -to_int(param, 1)
- )
-
- escape_to_color = { (0, 30): 0x0, #black
- (0, 31): 0x4, #red
- (0, 32): 0x2, #green
- (0, 33): 0x4+0x2, #dark yellow
- (0, 34): 0x1, #blue
- (0, 35): 0x1+0x4, #purple
- (0, 36): 0x2+0x4, #cyan
- (0, 37): 0x1+0x2+0x4, #grey
- (1, 30): 0x1+0x2+0x4, #dark gray
- (1, 31): 0x4+0x8, #red
- (1, 32): 0x2+0x8, #light green
- (1, 33): 0x4+0x2+0x8, #yellow
- (1, 34): 0x1+0x8, #light blue
- (1, 35): 0x1+0x4+0x8, #light purple
- (1, 36): 0x1+0x2+0x8, #light cyan
- (1, 37): 0x1+0x2+0x4+0x8, #white
- }
-
- def set_color(self, param):
- intensity, sep, color = param.partition(';')
- intensity = to_int(intensity, 0)
- color = to_int(color, 0)
- if intensity and not color:
- color, intensity = intensity, color
- attrib = self.escape_to_color.get((intensity, color), 0x7)
- windll.kernel32.SetConsoleTextAttribute(self.hconsole, attrib)
-
- def show_cursor(self,param):
- csinfo.bVisible = 1
- windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(csinfo))
-
- def hide_cursor(self,param):
- csinfo.bVisible = 0
- windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(csinfo))
-
- ansi_command_table = {
- 'A': move_up,
- 'B': move_down,
- 'C': move_right,
- 'D': move_left,
- 'E': next_line,
- 'F': prev_line,
- 'G': set_column,
- 'H': set_cursor,
- 'f': set_cursor,
- 'J': clear_screen,
- 'K': clear_line,
- 'h': show_cursor,
- 'l': hide_cursor,
- 'm': set_color,
- 's': push_cursor,
- 'u': pop_cursor,
- }
- # Match either the escape sequence or text not containing escape sequence
- ansi_tokans = re.compile('(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))')
- def write(self, text):
- wlock.acquire()
- for param, cmd, txt in self.ansi_tokans.findall(text):
- if cmd:
- cmd_func = self.ansi_command_table.get(cmd)
- if cmd_func:
- cmd_func(self, param)
- else:
- chars_written = c_int()
- if isinstance(txt, unicode):
- windll.kernel32.WriteConsoleW(self.hconsole, txt, len(txt), byref(chars_written), None)
- else:
- windll.kernel32.WriteConsoleA(self.hconsole, txt, len(txt), byref(chars_written), None)
- wlock.release()
-
- def flush(self):
- pass
-
- def isatty(self):
- return True
-
- sys.stderr = sys.stdout = AnsiTerm()
- os.environ['TERM'] = 'vt100'
-
diff --git a/tools/wafadmin/pproc.py b/tools/wafadmin/pproc.py
deleted file mode 100644
index cb15178b4..000000000
--- a/tools/wafadmin/pproc.py
+++ /dev/null
@@ -1,620 +0,0 @@
-# borrowed from python 2.5.2c1
-# Copyright (c) 2003-2005 by Peter Astrand <astrand@lysator.liu.se>
-# Licensed to PSF under a Contributor Agreement.
-
-import sys
-mswindows = (sys.platform == "win32")
-
-import os
-import types
-import traceback
-import gc
-
-class CalledProcessError(Exception):
- def __init__(self, returncode, cmd):
- self.returncode = returncode
- self.cmd = cmd
- def __str__(self):
- return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
-
-if mswindows:
- import threading
- import msvcrt
- if 0:
- import pywintypes
- from win32api import GetStdHandle, STD_INPUT_HANDLE, \
- STD_OUTPUT_HANDLE, STD_ERROR_HANDLE
- from win32api import GetCurrentProcess, DuplicateHandle, \
- GetModuleFileName, GetVersion
- from win32con import DUPLICATE_SAME_ACCESS, SW_HIDE
- from win32pipe import CreatePipe
- from win32process import CreateProcess, STARTUPINFO, \
- GetExitCodeProcess, STARTF_USESTDHANDLES, \
- STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
- from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
- else:
- from _subprocess import *
- class STARTUPINFO:
- dwFlags = 0
- hStdInput = None
- hStdOutput = None
- hStdError = None
- wShowWindow = 0
- class pywintypes:
- error = IOError
-else:
- import select
- import errno
- import fcntl
- import pickle
-
-__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "CalledProcessError"]
-
-try:
- MAXFD = os.sysconf("SC_OPEN_MAX")
-except:
- MAXFD = 256
-
-try:
- False
-except NameError:
- False = 0
- True = 1
-
-_active = []
-
-def _cleanup():
- for inst in _active[:]:
- if inst.poll(_deadstate=sys.maxint) >= 0:
- try:
- _active.remove(inst)
- except ValueError:
- pass
-
-PIPE = -1
-STDOUT = -2
-
-
-def call(*popenargs, **kwargs):
- return Popen(*popenargs, **kwargs).wait()
-
-def check_call(*popenargs, **kwargs):
- retcode = call(*popenargs, **kwargs)
- cmd = kwargs.get("args")
- if cmd is None:
- cmd = popenargs[0]
- if retcode:
- raise CalledProcessError(retcode, cmd)
- return retcode
-
-
-def list2cmdline(seq):
- result = []
- needquote = False
- for arg in seq:
- bs_buf = []
-
- if result:
- result.append(' ')
-
- needquote = (" " in arg) or ("\t" in arg) or arg == ""
- if needquote:
- result.append('"')
-
- for c in arg:
- if c == '\\':
- bs_buf.append(c)
- elif c == '"':
- result.append('\\' * len(bs_buf)*2)
- bs_buf = []
- result.append('\\"')
- else:
- if bs_buf:
- result.extend(bs_buf)
- bs_buf = []
- result.append(c)
-
- if bs_buf:
- result.extend(bs_buf)
-
- if needquote:
- result.extend(bs_buf)
- result.append('"')
-
- return ''.join(result)
-
-class Popen(object):
- def __init__(self, args, bufsize=0, executable=None,
- stdin=None, stdout=None, stderr=None,
- preexec_fn=None, close_fds=False, shell=False,
- cwd=None, env=None, universal_newlines=False,
- startupinfo=None, creationflags=0):
- _cleanup()
-
- self._child_created = False
- if not isinstance(bufsize, (int, long)):
- raise TypeError("bufsize must be an integer")
-
- if mswindows:
- if preexec_fn is not None:
- raise ValueError("preexec_fn is not supported on Windows platforms")
- if close_fds:
- raise ValueError("close_fds is not supported on Windows platforms")
- else:
- if startupinfo is not None:
- raise ValueError("startupinfo is only supported on Windows platforms")
- if creationflags != 0:
- raise ValueError("creationflags is only supported on Windows platforms")
-
- self.stdin = None
- self.stdout = None
- self.stderr = None
- self.pid = None
- self.returncode = None
- self.universal_newlines = universal_newlines
-
- (p2cread, p2cwrite,
- c2pread, c2pwrite,
- errread, errwrite) = self._get_handles(stdin, stdout, stderr)
-
- self._execute_child(args, executable, preexec_fn, close_fds,
- cwd, env, universal_newlines,
- startupinfo, creationflags, shell,
- p2cread, p2cwrite,
- c2pread, c2pwrite,
- errread, errwrite)
-
- if mswindows:
- if stdin is None and p2cwrite is not None:
- os.close(p2cwrite)
- p2cwrite = None
- if stdout is None and c2pread is not None:
- os.close(c2pread)
- c2pread = None
- if stderr is None and errread is not None:
- os.close(errread)
- errread = None
-
- if p2cwrite:
- self.stdin = os.fdopen(p2cwrite, 'wb', bufsize)
- if c2pread:
- if universal_newlines:
- self.stdout = os.fdopen(c2pread, 'rU', bufsize)
- else:
- self.stdout = os.fdopen(c2pread, 'rb', bufsize)
- if errread:
- if universal_newlines:
- self.stderr = os.fdopen(errread, 'rU', bufsize)
- else:
- self.stderr = os.fdopen(errread, 'rb', bufsize)
-
-
- def _translate_newlines(self, data):
- data = data.replace("\r\n", "\n")
- data = data.replace("\r", "\n")
- return data
-
-
- def __del__(self, sys=sys):
- if not self._child_created:
- return
- self.poll(_deadstate=sys.maxint)
- if self.returncode is None and _active is not None:
- _active.append(self)
-
-
- def communicate(self, input=None):
- if [self.stdin, self.stdout, self.stderr].count(None) >= 2:
- stdout = None
- stderr = None
- if self.stdin:
- if input:
- self.stdin.write(input)
- self.stdin.close()
- elif self.stdout:
- stdout = self.stdout.read()
- elif self.stderr:
- stderr = self.stderr.read()
- self.wait()
- return (stdout, stderr)
-
- return self._communicate(input)
-
-
- if mswindows:
- def _get_handles(self, stdin, stdout, stderr):
- if stdin is None and stdout is None and stderr is None:
- return (None, None, None, None, None, None)
-
- p2cread, p2cwrite = None, None
- c2pread, c2pwrite = None, None
- errread, errwrite = None, None
-
- if stdin is None:
- p2cread = GetStdHandle(STD_INPUT_HANDLE)
- if p2cread is not None:
- pass
- elif stdin is None or stdin == PIPE:
- p2cread, p2cwrite = CreatePipe(None, 0)
- p2cwrite = p2cwrite.Detach()
- p2cwrite = msvcrt.open_osfhandle(p2cwrite, 0)
- elif isinstance(stdin, int):
- p2cread = msvcrt.get_osfhandle(stdin)
- else:
- p2cread = msvcrt.get_osfhandle(stdin.fileno())
- p2cread = self._make_inheritable(p2cread)
-
- if stdout is None:
- c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE)
- if c2pwrite is not None:
- pass
- elif stdout is None or stdout == PIPE:
- c2pread, c2pwrite = CreatePipe(None, 0)
- c2pread = c2pread.Detach()
- c2pread = msvcrt.open_osfhandle(c2pread, 0)
- elif isinstance(stdout, int):
- c2pwrite = msvcrt.get_osfhandle(stdout)
- else:
- c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
- c2pwrite = self._make_inheritable(c2pwrite)
-
- if stderr is None:
- errwrite = GetStdHandle(STD_ERROR_HANDLE)
- if errwrite is not None:
- pass
- elif stderr is None or stderr == PIPE:
- errread, errwrite = CreatePipe(None, 0)
- errread = errread.Detach()
- errread = msvcrt.open_osfhandle(errread, 0)
- elif stderr == STDOUT:
- errwrite = c2pwrite
- elif isinstance(stderr, int):
- errwrite = msvcrt.get_osfhandle(stderr)
- else:
- errwrite = msvcrt.get_osfhandle(stderr.fileno())
- errwrite = self._make_inheritable(errwrite)
-
- return (p2cread, p2cwrite,
- c2pread, c2pwrite,
- errread, errwrite)
- def _make_inheritable(self, handle):
- return DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), 0, 1, DUPLICATE_SAME_ACCESS)
-
- def _find_w9xpopen(self):
- w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)), "w9xpopen.exe")
- if not os.path.exists(w9xpopen):
- w9xpopen = os.path.join(os.path.dirname(sys.exec_prefix), "w9xpopen.exe")
- if not os.path.exists(w9xpopen):
- raise RuntimeError("Cannot locate w9xpopen.exe, which is needed for Popen to work with your shell or platform.")
- return w9xpopen
-
- def _execute_child(self, args, executable, preexec_fn, close_fds,
- cwd, env, universal_newlines,
- startupinfo, creationflags, shell,
- p2cread, p2cwrite,
- c2pread, c2pwrite,
- errread, errwrite):
-
- if not isinstance(args, types.StringTypes):
- args = list2cmdline(args)
-
- if startupinfo is None:
- startupinfo = STARTUPINFO()
- if None not in (p2cread, c2pwrite, errwrite):
- startupinfo.dwFlags |= STARTF_USESTDHANDLES
- startupinfo.hStdInput = p2cread
- startupinfo.hStdOutput = c2pwrite
- startupinfo.hStdError = errwrite
-
- if shell:
- startupinfo.dwFlags |= STARTF_USESHOWWINDOW
- startupinfo.wShowWindow = SW_HIDE
- comspec = os.environ.get("COMSPEC", "cmd.exe")
- args = comspec + " /c " + args
- if (GetVersion() >= 0x80000000L or
- os.path.basename(comspec).lower() == "command.com"):
- w9xpopen = self._find_w9xpopen()
- args = '"%s" %s' % (w9xpopen, args)
- creationflags |= CREATE_NEW_CONSOLE
-
- try:
- hp, ht, pid, tid = CreateProcess(executable, args, None, None, 1, creationflags, env, cwd, startupinfo)
- except pywintypes.error, e:
- raise WindowsError(*e.args)
-
- self._child_created = True
- self._handle = hp
- self.pid = pid
- ht.Close()
-
- if p2cread is not None:
- p2cread.Close()
- if c2pwrite is not None:
- c2pwrite.Close()
- if errwrite is not None:
- errwrite.Close()
-
-
- def poll(self, _deadstate=None):
- if self.returncode is None:
- if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0:
- self.returncode = GetExitCodeProcess(self._handle)
- return self.returncode
-
-
- def wait(self):
- if self.returncode is None:
- obj = WaitForSingleObject(self._handle, INFINITE)
- self.returncode = GetExitCodeProcess(self._handle)
- return self.returncode
-
- def _readerthread(self, fh, buffer):
- buffer.append(fh.read())
-
- def _communicate(self, input):
- stdout = None
- stderr = None
-
- if self.stdout:
- stdout = []
- stdout_thread = threading.Thread(target=self._readerthread, args=(self.stdout, stdout))
- stdout_thread.setDaemon(True)
- stdout_thread.start()
- if self.stderr:
- stderr = []
- stderr_thread = threading.Thread(target=self._readerthread, args=(self.stderr, stderr))
- stderr_thread.setDaemon(True)
- stderr_thread.start()
-
- if self.stdin:
- if input is not None:
- self.stdin.write(input)
- self.stdin.close()
-
- if self.stdout:
- stdout_thread.join()
- if self.stderr:
- stderr_thread.join()
-
- if stdout is not None:
- stdout = stdout[0]
- if stderr is not None:
- stderr = stderr[0]
-
- if self.universal_newlines and hasattr(file, 'newlines'):
- if stdout:
- stdout = self._translate_newlines(stdout)
- if stderr:
- stderr = self._translate_newlines(stderr)
-
- self.wait()
- return (stdout, stderr)
-
- else:
- def _get_handles(self, stdin, stdout, stderr):
- p2cread, p2cwrite = None, None
- c2pread, c2pwrite = None, None
- errread, errwrite = None, None
-
- if stdin is None:
- pass
- elif stdin == PIPE:
- p2cread, p2cwrite = os.pipe()
- elif isinstance(stdin, int):
- p2cread = stdin
- else:
- p2cread = stdin.fileno()
-
- if stdout is None:
- pass
- elif stdout == PIPE:
- c2pread, c2pwrite = os.pipe()
- elif isinstance(stdout, int):
- c2pwrite = stdout
- else:
- c2pwrite = stdout.fileno()
-
- if stderr is None:
- pass
- elif stderr == PIPE:
- errread, errwrite = os.pipe()
- elif stderr == STDOUT:
- errwrite = c2pwrite
- elif isinstance(stderr, int):
- errwrite = stderr
- else:
- errwrite = stderr.fileno()
-
- return (p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite)
-
- def _set_cloexec_flag(self, fd):
- try:
- cloexec_flag = fcntl.FD_CLOEXEC
- except AttributeError:
- cloexec_flag = 1
-
- old = fcntl.fcntl(fd, fcntl.F_GETFD)
- fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag)
-
- def _close_fds(self, but):
- for i in xrange(3, MAXFD):
- if i == but:
- continue
- try:
- os.close(i)
- except:
- pass
-
- def _execute_child(self, args, executable, preexec_fn, close_fds,
- cwd, env, universal_newlines, startupinfo, creationflags, shell,
- p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite):
-
- if isinstance(args, types.StringTypes):
- args = [args]
- else:
- args = list(args)
-
- if shell:
- args = ["/bin/sh", "-c"] + args
-
- if executable is None:
- executable = args[0]
-
- errpipe_read, errpipe_write = os.pipe()
- self._set_cloexec_flag(errpipe_write)
-
- gc_was_enabled = gc.isenabled()
- gc.disable()
- try:
- self.pid = os.fork()
- except:
- if gc_was_enabled:
- gc.enable()
- raise
- self._child_created = True
- if self.pid == 0:
- try:
- if p2cwrite:
- os.close(p2cwrite)
- if c2pread:
- os.close(c2pread)
- if errread:
- os.close(errread)
- os.close(errpipe_read)
-
- if p2cread:
- os.dup2(p2cread, 0)
- if c2pwrite:
- os.dup2(c2pwrite, 1)
- if errwrite:
- os.dup2(errwrite, 2)
-
- if p2cread and p2cread not in (0,):
- os.close(p2cread)
- if c2pwrite and c2pwrite not in (p2cread, 1):
- os.close(c2pwrite)
- if errwrite and errwrite not in (p2cread, c2pwrite, 2):
- os.close(errwrite)
-
- if close_fds:
- self._close_fds(but=errpipe_write)
-
- if cwd is not None:
- os.chdir(cwd)
-
- if preexec_fn:
- apply(preexec_fn)
-
- if env is None:
- os.execvp(executable, args)
- else:
- os.execvpe(executable, args, env)
-
- except:
- exc_type, exc_value, tb = sys.exc_info()
- exc_lines = traceback.format_exception(exc_type, exc_value, tb)
- exc_value.child_traceback = ''.join(exc_lines)
- os.write(errpipe_write, pickle.dumps(exc_value))
-
- os._exit(255)
-
- if gc_was_enabled:
- gc.enable()
- os.close(errpipe_write)
- if p2cread and p2cwrite:
- os.close(p2cread)
- if c2pwrite and c2pread:
- os.close(c2pwrite)
- if errwrite and errread:
- os.close(errwrite)
-
- data = os.read(errpipe_read, 1048576)
- os.close(errpipe_read)
- if data != "":
- os.waitpid(self.pid, 0)
- child_exception = pickle.loads(data)
- raise child_exception
-
- def _handle_exitstatus(self, sts):
- if os.WIFSIGNALED(sts):
- self.returncode = -os.WTERMSIG(sts)
- elif os.WIFEXITED(sts):
- self.returncode = os.WEXITSTATUS(sts)
- else:
- raise RuntimeError("Unknown child exit status!")
-
- def poll(self, _deadstate=None):
- if self.returncode is None:
- try:
- pid, sts = os.waitpid(self.pid, os.WNOHANG)
- if pid == self.pid:
- self._handle_exitstatus(sts)
- except os.error:
- if _deadstate is not None:
- self.returncode = _deadstate
- return self.returncode
-
- def wait(self):
- if self.returncode is None:
- pid, sts = os.waitpid(self.pid, 0)
- self._handle_exitstatus(sts)
- return self.returncode
-
- def _communicate(self, input):
- read_set = []
- write_set = []
- stdout = None
- stderr = None
-
- if self.stdin:
- self.stdin.flush()
- if input:
- write_set.append(self.stdin)
- else:
- self.stdin.close()
- if self.stdout:
- read_set.append(self.stdout)
- stdout = []
- if self.stderr:
- read_set.append(self.stderr)
- stderr = []
-
- input_offset = 0
- while read_set or write_set:
- rlist, wlist, xlist = select.select(read_set, write_set, [])
-
- if self.stdin in wlist:
- bytes_written = os.write(self.stdin.fileno(), buffer(input, input_offset, 512))
- input_offset += bytes_written
- if input_offset >= len(input):
- self.stdin.close()
- write_set.remove(self.stdin)
-
- if self.stdout in rlist:
- data = os.read(self.stdout.fileno(), 1024)
- if data == "":
- self.stdout.close()
- read_set.remove(self.stdout)
- stdout.append(data)
-
- if self.stderr in rlist:
- data = os.read(self.stderr.fileno(), 1024)
- if data == "":
- self.stderr.close()
- read_set.remove(self.stderr)
- stderr.append(data)
-
- if stdout is not None:
- stdout = ''.join(stdout)
- if stderr is not None:
- stderr = ''.join(stderr)
-
- if self.universal_newlines and hasattr(file, 'newlines'):
- if stdout:
- stdout = self._translate_newlines(stdout)
- if stderr:
- stderr = self._translate_newlines(stderr)
-
- self.wait()
- return (stdout, stderr)
-
diff --git a/tools/wafadmin/py3kfixes.py b/tools/wafadmin/py3kfixes.py
deleted file mode 100644
index 6aeb26b64..000000000
--- a/tools/wafadmin/py3kfixes.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Thomas Nagy, 2009 (ita)
-
-"""
-Fixes for py3k go here
-"""
-
-import os
-
-all_modifs = {}
-
-def modif(dir, name, fun):
- if name == '*':
- lst = []
- for y in '. Tools 3rdparty'.split():
- for x in os.listdir(os.path.join(dir, y)):
- if x.endswith('.py'):
- lst.append(y + os.sep + x)
- #lst = [y + os.sep + x for x in os.listdir(os.path.join(dir, y)) for y in '. Tools 3rdparty'.split() if x.endswith('.py')]
- for x in lst:
- modif(dir, x, fun)
- return
-
- filename = os.path.join(dir, name)
- f = open(filename, 'r')
- txt = f.read()
- f.close()
-
- txt = fun(txt)
-
- f = open(filename, 'w')
- f.write(txt)
- f.close()
-
-def subst(filename):
- def do_subst(fun):
- global all_modifs
- try:
- all_modifs[filename] += fun
- except KeyError:
- all_modifs[filename] = [fun]
- return fun
- return do_subst
-
-@subst('Constants.py')
-def r1(code):
- code = code.replace("'iluvcuteoverload'", "b'iluvcuteoverload'")
- code = code.replace("ABI=7", "ABI=37")
- return code
-
-@subst('Tools/ccroot.py')
-def r2(code):
- code = code.replace("p.stdin.write('\\n')", "p.stdin.write(b'\\n')")
- code = code.replace('p.communicate()[0]', 'p.communicate()[0].decode("utf-8")')
- return code
-
-@subst('Utils.py')
-def r3(code):
- code = code.replace("m.update(str(lst))", "m.update(str(lst).encode())")
- code = code.replace('p.communicate()[0]', 'p.communicate()[0].decode("utf-8")')
- return code
-
-@subst('ansiterm.py')
-def r33(code):
- code = code.replace('unicode', 'str')
- return code
-
-@subst('Task.py')
-def r4(code):
- code = code.replace("up(self.__class__.__name__)", "up(self.__class__.__name__.encode())")
- code = code.replace("up(self.env.variant())", "up(self.env.variant().encode())")
- code = code.replace("up(x.parent.abspath())", "up(x.parent.abspath().encode())")
- code = code.replace("up(x.name)", "up(x.name.encode())")
- code = code.replace('class TaskBase(object):\n\t__metaclass__=store_task_type', 'import binascii\n\nclass TaskBase(object, metaclass=store_task_type):')
- code = code.replace('keys=self.cstr_groups.keys()', 'keys=list(self.cstr_groups.keys())')
- code = code.replace("sig.encode('hex')", 'binascii.hexlify(sig)')
- return code
-
-@subst('Build.py')
-def r5(code):
- code = code.replace("cPickle.dump(data,file,-1)", "cPickle.dump(data,file)")
- code = code.replace('for node in src_dir_node.childs.values():', 'for node in list(src_dir_node.childs.values()):')
- return code
-
-@subst('*')
-def r6(code):
- code = code.replace('xrange', 'range')
- code = code.replace('iteritems', 'items')
- code = code.replace('maxint', 'maxsize')
- code = code.replace('iterkeys', 'keys')
- code = code.replace('Error,e:', 'Error as e:')
- code = code.replace('Exception,e:', 'Exception as e:')
- return code
-
-@subst('TaskGen.py')
-def r7(code):
- code = code.replace('class task_gen(object):\n\t__metaclass__=register_obj', 'class task_gen(object, metaclass=register_obj):')
- return code
-
-@subst('Tools/python.py')
-def r8(code):
- code = code.replace('proc.communicate()[0]', 'proc.communicate()[0].decode("utf-8")')
- return code
-
-@subst('Tools/glib2.py')
-def r9(code):
- code = code.replace('f.write(c)', 'f.write(c.encode("utf-8"))')
- return code
-
-@subst('Tools/config_c.py')
-def r10(code):
- code = code.replace("key=kw['success']", "key=kw['success']\n\t\t\t\ttry:\n\t\t\t\t\tkey=key.decode('utf-8')\n\t\t\t\texcept:\n\t\t\t\t\tpass")
- return code
-
-def fixdir(dir):
- global all_modifs
- for k in all_modifs:
- for v in all_modifs[k]:
- modif(os.path.join(dir, 'wafadmin'), k, v)
- #print('substitutions finished')
-
diff --git a/tools/wrk/.gitignore b/tools/wrk/.gitignore
new file mode 100644
index 000000000..ae66e30c0
--- /dev/null
+++ b/tools/wrk/.gitignore
@@ -0,0 +1,2 @@
+obj/*
+/wrk
diff --git a/tools/wrk/LICENSE b/tools/wrk/LICENSE
new file mode 100644
index 000000000..f433b1a53
--- /dev/null
+++ b/tools/wrk/LICENSE
@@ -0,0 +1,177 @@
+
+ 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
diff --git a/tools/wrk/Makefile b/tools/wrk/Makefile
new file mode 100644
index 000000000..59dc693de
--- /dev/null
+++ b/tools/wrk/Makefile
@@ -0,0 +1,35 @@
+CFLAGS := -std=c99 -Wall -O2 -pthread
+LDFLAGS := -pthread
+LIBS := -lm
+ifeq ($(shell uname),SunOS)
+LIBS += -lnsl -lsocket -lresolv
+endif
+
+SRC := wrk.c aprintf.c stats.c units.c ae.c zmalloc.c http_parser.c tinymt64.c
+BIN := wrk
+
+ODIR := obj
+OBJ := $(patsubst %.c,$(ODIR)/%.o,$(SRC))
+
+all: $(BIN)
+
+clean:
+ $(RM) $(BIN) obj/*
+
+$(BIN): $(OBJ)
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+$(OBJ): config.h Makefile | $(ODIR)
+
+$(ODIR):
+ @mkdir $@
+
+$(ODIR)/%.o : %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+.PHONY: all clean
+.SUFFIXES:
+.SUFFIXES: .c .o
+
+vpath %.c src
+vpath %.h src
diff --git a/tools/wrk/NOTICE b/tools/wrk/NOTICE
new file mode 100644
index 000000000..e6cfc3bd8
--- /dev/null
+++ b/tools/wrk/NOTICE
@@ -0,0 +1,115 @@
+=========================================================================
+== NOTICE file corresponding to section 4(d) of the Apache License, ==
+== Version 2.0, in this case for the wrk distribution. ==
+=========================================================================
+
+wrk
+Copyright 2012 Will Glozer, http://glozer.net
+
+=========================================================================
+== Redis Event Library Notice ==
+=========================================================================
+
+This product includes software developed by Salvatore Sanfilippo and
+other contributors to the redis project.
+
+Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
+Copyright (C) 2009 Harish Mallipeddi - harish.mallipeddi@gmail.com
+
+Copyright (c) 2006-2009, Salvatore Sanfilippo
+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 Redis 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.
+
+=========================================================================
+== HTTP Parser Notice ==
+=========================================================================
+
+This product includes software developed by Igor Sysoev, Joyent, Inc.,
+and other Node contributors.
+
+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.
+
+=========================================================================
+== Tiny Mersenne Twister (TinyMT) Notice ==
+=========================================================================
+
+Copyright (c) 2011 Mutsuo Saito, Makoto Matsumoto, Hiroshima University
+and The University of Tokyo. 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 the Hiroshima University 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.
diff --git a/tools/wrk/README b/tools/wrk/README
new file mode 100644
index 000000000..a80768bc2
--- /dev/null
+++ b/tools/wrk/README
@@ -0,0 +1,37 @@
+wrk - a HTTP benchmarking tool
+
+ wrk is a modern HTTP benchmarking tool capable of generating significant
+ load when run on a single multi-core CPU. It combines a multithreaded
+ design with scalable event notification systems such as epoll and kqueue.
+
+Basic Usage
+
+ wrk -t8 -c400 -r10m http://localhost:8080/index.html
+
+ This runs wrk with 8 threads, keeping 400 connections open, and making a
+ total of 10 million HTTP GET requests to http://localhost:8080/index.html
+
+ Output:
+
+ Making 10000000 requests to http://localhost:8080/index.html
+ 8 threads and 400 connections
+ Thread Stats Avg Stdev Max +/- Stdev
+ Latency 439.75us 350.49us 7.60ms 92.88%
+ Req/Sec 61.13k 8.26k 72.00k 87.54%
+ 10000088 requests in 19.87s, 3.42GB read
+ Requests/sec: 503396.23
+ Transfer/sec: 176.16MB
+
+Benchmarking Tips
+
+ The machine running wrk must have a sufficient number of ephemeral ports
+ available and closed sockets should be recycled quickly. To handle the
+ initial connection burst the server's listen(2) backlog should be greater
+ than the number of concurrent connections being tested.
+
+Acknowledgements
+
+ wrk contains code from a number of open source projects including the
+ 'ae' event loop from redis, the nginx/joyent/node.js 'http-parser' and
+ the Tiny Mersenne Twister PRNG. Please consult the NOTICE file for
+ licensing details.
diff --git a/tools/wrk/src/ae.c b/tools/wrk/src/ae.c
new file mode 100644
index 000000000..6ca9a5153
--- /dev/null
+++ b/tools/wrk/src/ae.c
@@ -0,0 +1,435 @@
+/* A simple event-driven programming library. Originally I wrote this code
+ * for the Jim's event-loop (Jim is a Tcl interpreter) but later translated
+ * it in form of a library for easy reuse.
+ *
+ * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
+ * 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 Redis 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.
+ */
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <poll.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+
+#include "ae.h"
+#include "zmalloc.h"
+#include "config.h"
+
+/* Include the best multiplexing layer supported by this system.
+ * The following should be ordered by performances, descending. */
+#ifdef HAVE_EVPORT
+#include "ae_evport.c"
+#else
+ #ifdef HAVE_EPOLL
+ #include "ae_epoll.c"
+ #else
+ #ifdef HAVE_KQUEUE
+ #include "ae_kqueue.c"
+ #else
+ #include "ae_select.c"
+ #endif
+ #endif
+#endif
+
+aeEventLoop *aeCreateEventLoop(int setsize) {
+ aeEventLoop *eventLoop;
+ int i;
+
+ if ((eventLoop = zmalloc(sizeof(*eventLoop))) == NULL) goto err;
+ eventLoop->events = zmalloc(sizeof(aeFileEvent)*setsize);
+ eventLoop->fired = zmalloc(sizeof(aeFiredEvent)*setsize);
+ if (eventLoop->events == NULL || eventLoop->fired == NULL) goto err;
+ eventLoop->setsize = setsize;
+ eventLoop->lastTime = time(NULL);
+ eventLoop->timeEventHead = NULL;
+ eventLoop->timeEventNextId = 0;
+ eventLoop->stop = 0;
+ eventLoop->maxfd = -1;
+ eventLoop->beforesleep = NULL;
+ if (aeApiCreate(eventLoop) == -1) goto err;
+ /* Events with mask == AE_NONE are not set. So let's initialize the
+ * vector with it. */
+ for (i = 0; i < setsize; i++)
+ eventLoop->events[i].mask = AE_NONE;
+ return eventLoop;
+
+err:
+ if (eventLoop) {
+ zfree(eventLoop->events);
+ zfree(eventLoop->fired);
+ zfree(eventLoop);
+ }
+ return NULL;
+}
+
+void aeDeleteEventLoop(aeEventLoop *eventLoop) {
+ aeApiFree(eventLoop);
+ zfree(eventLoop->events);
+ zfree(eventLoop->fired);
+ zfree(eventLoop);
+}
+
+void aeStop(aeEventLoop *eventLoop) {
+ eventLoop->stop = 1;
+}
+
+int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
+ aeFileProc *proc, void *clientData)
+{
+ if (fd >= eventLoop->setsize) {
+ errno = ERANGE;
+ return AE_ERR;
+ }
+ aeFileEvent *fe = &eventLoop->events[fd];
+
+ if (aeApiAddEvent(eventLoop, fd, mask) == -1)
+ return AE_ERR;
+ fe->mask |= mask;
+ if (mask & AE_READABLE) fe->rfileProc = proc;
+ if (mask & AE_WRITABLE) fe->wfileProc = proc;
+ fe->clientData = clientData;
+ if (fd > eventLoop->maxfd)
+ eventLoop->maxfd = fd;
+ return AE_OK;
+}
+
+void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)
+{
+ if (fd >= eventLoop->setsize) return;
+ aeFileEvent *fe = &eventLoop->events[fd];
+
+ if (fe->mask == AE_NONE) return;
+ fe->mask = fe->mask & (~mask);
+ if (fd == eventLoop->maxfd && fe->mask == AE_NONE) {
+ /* Update the max fd */
+ int j;
+
+ for (j = eventLoop->maxfd-1; j >= 0; j--)
+ if (eventLoop->events[j].mask != AE_NONE) break;
+ eventLoop->maxfd = j;
+ }
+ aeApiDelEvent(eventLoop, fd, mask);
+}
+
+int aeGetFileEvents(aeEventLoop *eventLoop, int fd) {
+ if (fd >= eventLoop->setsize) return 0;
+ aeFileEvent *fe = &eventLoop->events[fd];
+
+ return fe->mask;
+}
+
+static void aeGetTime(long *seconds, long *milliseconds)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ *seconds = tv.tv_sec;
+ *milliseconds = tv.tv_usec/1000;
+}
+
+static void aeAddMillisecondsToNow(long long milliseconds, long *sec, long *ms) {
+ long cur_sec, cur_ms, when_sec, when_ms;
+
+ aeGetTime(&cur_sec, &cur_ms);
+ when_sec = cur_sec + milliseconds/1000;
+ when_ms = cur_ms + milliseconds%1000;
+ if (when_ms >= 1000) {
+ when_sec ++;
+ when_ms -= 1000;
+ }
+ *sec = when_sec;
+ *ms = when_ms;
+}
+
+long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,
+ aeTimeProc *proc, void *clientData,
+ aeEventFinalizerProc *finalizerProc)
+{
+ long long id = eventLoop->timeEventNextId++;
+ aeTimeEvent *te;
+
+ te = zmalloc(sizeof(*te));
+ if (te == NULL) return AE_ERR;
+ te->id = id;
+ aeAddMillisecondsToNow(milliseconds,&te->when_sec,&te->when_ms);
+ te->timeProc = proc;
+ te->finalizerProc = finalizerProc;
+ te->clientData = clientData;
+ te->next = eventLoop->timeEventHead;
+ eventLoop->timeEventHead = te;
+ return id;
+}
+
+int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id)
+{
+ aeTimeEvent *te, *prev = NULL;
+
+ te = eventLoop->timeEventHead;
+ while(te) {
+ if (te->id == id) {
+ if (prev == NULL)
+ eventLoop->timeEventHead = te->next;
+ else
+ prev->next = te->next;
+ if (te->finalizerProc)
+ te->finalizerProc(eventLoop, te->clientData);
+ zfree(te);
+ return AE_OK;
+ }
+ prev = te;
+ te = te->next;
+ }
+ return AE_ERR; /* NO event with the specified ID found */
+}
+
+/* Search the first timer to fire.
+ * This operation is useful to know how many time the select can be
+ * put in sleep without to delay any event.
+ * If there are no timers NULL is returned.
+ *
+ * Note that's O(N) since time events are unsorted.
+ * Possible optimizations (not needed by Redis so far, but...):
+ * 1) Insert the event in order, so that the nearest is just the head.
+ * Much better but still insertion or deletion of timers is O(N).
+ * 2) Use a skiplist to have this operation as O(1) and insertion as O(log(N)).
+ */
+static aeTimeEvent *aeSearchNearestTimer(aeEventLoop *eventLoop)
+{
+ aeTimeEvent *te = eventLoop->timeEventHead;
+ aeTimeEvent *nearest = NULL;
+
+ while(te) {
+ if (!nearest || te->when_sec < nearest->when_sec ||
+ (te->when_sec == nearest->when_sec &&
+ te->when_ms < nearest->when_ms))
+ nearest = te;
+ te = te->next;
+ }
+ return nearest;
+}
+
+/* Process time events */
+static int processTimeEvents(aeEventLoop *eventLoop) {
+ int processed = 0;
+ aeTimeEvent *te;
+ long long maxId;
+ time_t now = time(NULL);
+
+ /* If the system clock is moved to the future, and then set back to the
+ * right value, time events may be delayed in a random way. Often this
+ * means that scheduled operations will not be performed soon enough.
+ *
+ * Here we try to detect system clock skews, and force all the time
+ * events to be processed ASAP when this happens: the idea is that
+ * processing events earlier is less dangerous than delaying them
+ * indefinitely, and practice suggests it is. */
+ if (now < eventLoop->lastTime) {
+ te = eventLoop->timeEventHead;
+ while(te) {
+ te->when_sec = 0;
+ te = te->next;
+ }
+ }
+ eventLoop->lastTime = now;
+
+ te = eventLoop->timeEventHead;
+ maxId = eventLoop->timeEventNextId-1;
+ while(te) {
+ long now_sec, now_ms;
+ long long id;
+
+ if (te->id > maxId) {
+ te = te->next;
+ continue;
+ }
+ aeGetTime(&now_sec, &now_ms);
+ if (now_sec > te->when_sec ||
+ (now_sec == te->when_sec && now_ms >= te->when_ms))
+ {
+ int retval;
+
+ id = te->id;
+ retval = te->timeProc(eventLoop, id, te->clientData);
+ processed++;
+ /* After an event is processed our time event list may
+ * no longer be the same, so we restart from head.
+ * Still we make sure to don't process events registered
+ * by event handlers itself in order to don't loop forever.
+ * To do so we saved the max ID we want to handle.
+ *
+ * FUTURE OPTIMIZATIONS:
+ * Note that this is NOT great algorithmically. Redis uses
+ * a single time event so it's not a problem but the right
+ * way to do this is to add the new elements on head, and
+ * to flag deleted elements in a special way for later
+ * deletion (putting references to the nodes to delete into
+ * another linked list). */
+ if (retval != AE_NOMORE) {
+ aeAddMillisecondsToNow(retval,&te->when_sec,&te->when_ms);
+ } else {
+ aeDeleteTimeEvent(eventLoop, id);
+ }
+ te = eventLoop->timeEventHead;
+ } else {
+ te = te->next;
+ }
+ }
+ return processed;
+}
+
+/* Process every pending time event, then every pending file event
+ * (that may be registered by time event callbacks just processed).
+ * Without special flags the function sleeps until some file event
+ * fires, or when the next time event occurs (if any).
+ *
+ * If flags is 0, the function does nothing and returns.
+ * if flags has AE_ALL_EVENTS set, all the kind of events are processed.
+ * if flags has AE_FILE_EVENTS set, file events are processed.
+ * if flags has AE_TIME_EVENTS set, time events are processed.
+ * if flags has AE_DONT_WAIT set the function returns ASAP until all
+ * the events that's possible to process without to wait are processed.
+ *
+ * The function returns the number of events processed. */
+int aeProcessEvents(aeEventLoop *eventLoop, int flags)
+{
+ int processed = 0, numevents;
+
+ /* Nothing to do? return ASAP */
+ if (!(flags & AE_TIME_EVENTS) && !(flags & AE_FILE_EVENTS)) return 0;
+
+ /* Note that we want call select() even if there are no
+ * file events to process as long as we want to process time
+ * events, in order to sleep until the next time event is ready
+ * to fire. */
+ if (eventLoop->maxfd != -1 ||
+ ((flags & AE_TIME_EVENTS) && !(flags & AE_DONT_WAIT))) {
+ int j;
+ aeTimeEvent *shortest = NULL;
+ struct timeval tv, *tvp;
+
+ if (flags & AE_TIME_EVENTS && !(flags & AE_DONT_WAIT))
+ shortest = aeSearchNearestTimer(eventLoop);
+ if (shortest) {
+ long now_sec, now_ms;
+
+ /* Calculate the time missing for the nearest
+ * timer to fire. */
+ aeGetTime(&now_sec, &now_ms);
+ tvp = &tv;
+ tvp->tv_sec = shortest->when_sec - now_sec;
+ if (shortest->when_ms < now_ms) {
+ tvp->tv_usec = ((shortest->when_ms+1000) - now_ms)*1000;
+ tvp->tv_sec --;
+ } else {
+ tvp->tv_usec = (shortest->when_ms - now_ms)*1000;
+ }
+ if (tvp->tv_sec < 0) tvp->tv_sec = 0;
+ if (tvp->tv_usec < 0) tvp->tv_usec = 0;
+ } else {
+ /* If we have to check for events but need to return
+ * ASAP because of AE_DONT_WAIT we need to set the timeout
+ * to zero */
+ if (flags & AE_DONT_WAIT) {
+ tv.tv_sec = tv.tv_usec = 0;
+ tvp = &tv;
+ } else {
+ /* Otherwise we can block */
+ tvp = NULL; /* wait forever */
+ }
+ }
+
+ numevents = aeApiPoll(eventLoop, tvp);
+ for (j = 0; j < numevents; j++) {
+ aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];
+ int mask = eventLoop->fired[j].mask;
+ int fd = eventLoop->fired[j].fd;
+ int rfired = 0;
+
+ /* note the fe->mask & mask & ... code: maybe an already processed
+ * event removed an element that fired and we still didn't
+ * processed, so we check if the event is still valid. */
+ if (fe->mask & mask & AE_READABLE) {
+ rfired = 1;
+ fe->rfileProc(eventLoop,fd,fe->clientData,mask);
+ }
+ if (fe->mask & mask & AE_WRITABLE) {
+ if (!rfired || fe->wfileProc != fe->rfileProc)
+ fe->wfileProc(eventLoop,fd,fe->clientData,mask);
+ }
+ processed++;
+ }
+ }
+ /* Check time events */
+ if (flags & AE_TIME_EVENTS)
+ processed += processTimeEvents(eventLoop);
+
+ return processed; /* return the number of processed file/time events */
+}
+
+/* Wait for milliseconds until the given file descriptor becomes
+ * writable/readable/exception */
+int aeWait(int fd, int mask, long long milliseconds) {
+ struct pollfd pfd;
+ int retmask = 0, retval;
+
+ memset(&pfd, 0, sizeof(pfd));
+ pfd.fd = fd;
+ if (mask & AE_READABLE) pfd.events |= POLLIN;
+ if (mask & AE_WRITABLE) pfd.events |= POLLOUT;
+
+ if ((retval = poll(&pfd, 1, milliseconds))== 1) {
+ if (pfd.revents & POLLIN) retmask |= AE_READABLE;
+ if (pfd.revents & POLLOUT) retmask |= AE_WRITABLE;
+ if (pfd.revents & POLLERR) retmask |= AE_WRITABLE;
+ if (pfd.revents & POLLHUP) retmask |= AE_WRITABLE;
+ return retmask;
+ } else {
+ return retval;
+ }
+}
+
+void aeMain(aeEventLoop *eventLoop) {
+ eventLoop->stop = 0;
+ while (!eventLoop->stop) {
+ if (eventLoop->beforesleep != NULL)
+ eventLoop->beforesleep(eventLoop);
+ aeProcessEvents(eventLoop, AE_ALL_EVENTS);
+ }
+}
+
+char *aeGetApiName(void) {
+ return aeApiName();
+}
+
+void aeSetBeforeSleepProc(aeEventLoop *eventLoop, aeBeforeSleepProc *beforesleep) {
+ eventLoop->beforesleep = beforesleep;
+}
diff --git a/tools/wrk/src/ae.h b/tools/wrk/src/ae.h
new file mode 100644
index 000000000..4d8950242
--- /dev/null
+++ b/tools/wrk/src/ae.h
@@ -0,0 +1,118 @@
+/* A simple event-driven programming library. Originally I wrote this code
+ * for the Jim's event-loop (Jim is a Tcl interpreter) but later translated
+ * it in form of a library for easy reuse.
+ *
+ * Copyright (c) 2006-2012, Salvatore Sanfilippo <antirez at gmail dot com>
+ * 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 Redis 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.
+ */
+
+#ifndef __AE_H__
+#define __AE_H__
+
+#define AE_OK 0
+#define AE_ERR -1
+
+#define AE_NONE 0
+#define AE_READABLE 1
+#define AE_WRITABLE 2
+
+#define AE_FILE_EVENTS 1
+#define AE_TIME_EVENTS 2
+#define AE_ALL_EVENTS (AE_FILE_EVENTS|AE_TIME_EVENTS)
+#define AE_DONT_WAIT 4
+
+#define AE_NOMORE -1
+
+/* Macros */
+#define AE_NOTUSED(V) ((void) V)
+
+struct aeEventLoop;
+
+/* Types and data structures */
+typedef void aeFileProc(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);
+typedef int aeTimeProc(struct aeEventLoop *eventLoop, long long id, void *clientData);
+typedef void aeEventFinalizerProc(struct aeEventLoop *eventLoop, void *clientData);
+typedef void aeBeforeSleepProc(struct aeEventLoop *eventLoop);
+
+/* File event structure */
+typedef struct aeFileEvent {
+ int mask; /* one of AE_(READABLE|WRITABLE) */
+ aeFileProc *rfileProc;
+ aeFileProc *wfileProc;
+ void *clientData;
+} aeFileEvent;
+
+/* Time event structure */
+typedef struct aeTimeEvent {
+ long long id; /* time event identifier. */
+ long when_sec; /* seconds */
+ long when_ms; /* milliseconds */
+ aeTimeProc *timeProc;
+ aeEventFinalizerProc *finalizerProc;
+ void *clientData;
+ struct aeTimeEvent *next;
+} aeTimeEvent;
+
+/* A fired event */
+typedef struct aeFiredEvent {
+ int fd;
+ int mask;
+} aeFiredEvent;
+
+/* State of an event based program */
+typedef struct aeEventLoop {
+ int maxfd; /* highest file descriptor currently registered */
+ int setsize; /* max number of file descriptors tracked */
+ long long timeEventNextId;
+ time_t lastTime; /* Used to detect system clock skew */
+ aeFileEvent *events; /* Registered events */
+ aeFiredEvent *fired; /* Fired events */
+ aeTimeEvent *timeEventHead;
+ int stop;
+ void *apidata; /* This is used for polling API specific data */
+ aeBeforeSleepProc *beforesleep;
+} aeEventLoop;
+
+/* Prototypes */
+aeEventLoop *aeCreateEventLoop(int setsize);
+void aeDeleteEventLoop(aeEventLoop *eventLoop);
+void aeStop(aeEventLoop *eventLoop);
+int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
+ aeFileProc *proc, void *clientData);
+void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask);
+int aeGetFileEvents(aeEventLoop *eventLoop, int fd);
+long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,
+ aeTimeProc *proc, void *clientData,
+ aeEventFinalizerProc *finalizerProc);
+int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id);
+int aeProcessEvents(aeEventLoop *eventLoop, int flags);
+int aeWait(int fd, int mask, long long milliseconds);
+void aeMain(aeEventLoop *eventLoop);
+char *aeGetApiName(void);
+void aeSetBeforeSleepProc(aeEventLoop *eventLoop, aeBeforeSleepProc *beforesleep);
+
+#endif
diff --git a/tools/wrk/src/ae_epoll.c b/tools/wrk/src/ae_epoll.c
new file mode 100644
index 000000000..4823c281e
--- /dev/null
+++ b/tools/wrk/src/ae_epoll.c
@@ -0,0 +1,130 @@
+/* Linux epoll(2) based ae.c module
+ *
+ * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
+ * 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 Redis 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.
+ */
+
+
+#include <sys/epoll.h>
+
+typedef struct aeApiState {
+ int epfd;
+ struct epoll_event *events;
+} aeApiState;
+
+static int aeApiCreate(aeEventLoop *eventLoop) {
+ aeApiState *state = zmalloc(sizeof(aeApiState));
+
+ if (!state) return -1;
+ state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize);
+ if (!state->events) {
+ zfree(state);
+ return -1;
+ }
+ state->epfd = epoll_create(1024); /* 1024 is just an hint for the kernel */
+ if (state->epfd == -1) {
+ zfree(state->events);
+ zfree(state);
+ return -1;
+ }
+ eventLoop->apidata = state;
+ return 0;
+}
+
+static void aeApiFree(aeEventLoop *eventLoop) {
+ aeApiState *state = eventLoop->apidata;
+
+ close(state->epfd);
+ zfree(state->events);
+ zfree(state);
+}
+
+static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
+ aeApiState *state = eventLoop->apidata;
+ struct epoll_event ee;
+ /* If the fd was already monitored for some event, we need a MOD
+ * operation. Otherwise we need an ADD operation. */
+ int op = eventLoop->events[fd].mask == AE_NONE ?
+ EPOLL_CTL_ADD : EPOLL_CTL_MOD;
+
+ ee.events = 0;
+ mask |= eventLoop->events[fd].mask; /* Merge old events */
+ if (mask & AE_READABLE) ee.events |= EPOLLIN;
+ if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
+ ee.data.u64 = 0; /* avoid valgrind warning */
+ ee.data.fd = fd;
+ if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;
+ return 0;
+}
+
+static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) {
+ aeApiState *state = eventLoop->apidata;
+ struct epoll_event ee;
+ int mask = eventLoop->events[fd].mask & (~delmask);
+
+ ee.events = 0;
+ if (mask & AE_READABLE) ee.events |= EPOLLIN;
+ if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
+ ee.data.u64 = 0; /* avoid valgrind warning */
+ ee.data.fd = fd;
+ if (mask != AE_NONE) {
+ epoll_ctl(state->epfd,EPOLL_CTL_MOD,fd,&ee);
+ } else {
+ /* Note, Kernel < 2.6.9 requires a non null event pointer even for
+ * EPOLL_CTL_DEL. */
+ epoll_ctl(state->epfd,EPOLL_CTL_DEL,fd,&ee);
+ }
+}
+
+static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
+ aeApiState *state = eventLoop->apidata;
+ int retval, numevents = 0;
+
+ retval = epoll_wait(state->epfd,state->events,eventLoop->setsize,
+ tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
+ if (retval > 0) {
+ int j;
+
+ numevents = retval;
+ for (j = 0; j < numevents; j++) {
+ int mask = 0;
+ struct epoll_event *e = state->events+j;
+
+ if (e->events & EPOLLIN) mask |= AE_READABLE;
+ if (e->events & EPOLLOUT) mask |= AE_WRITABLE;
+ if (e->events & EPOLLERR) mask |= AE_WRITABLE;
+ if (e->events & EPOLLHUP) mask |= AE_WRITABLE;
+ eventLoop->fired[j].fd = e->data.fd;
+ eventLoop->fired[j].mask = mask;
+ }
+ }
+ return numevents;
+}
+
+static char *aeApiName(void) {
+ return "epoll";
+}
diff --git a/tools/wrk/src/ae_evport.c b/tools/wrk/src/ae_evport.c
new file mode 100644
index 000000000..94413c132
--- /dev/null
+++ b/tools/wrk/src/ae_evport.c
@@ -0,0 +1,315 @@
+/* ae.c module for illumos event ports.
+ *
+ * Copyright (c) 2012, Joyent, 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 Redis 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.
+ */
+
+
+#include <assert.h>
+#include <errno.h>
+#include <port.h>
+#include <poll.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+
+static int evport_debug = 0;
+
+/*
+ * This file implements the ae API using event ports, present on Solaris-based
+ * systems since Solaris 10. Using the event port interface, we associate file
+ * descriptors with the port. Each association also includes the set of poll(2)
+ * events that the consumer is interested in (e.g., POLLIN and POLLOUT).
+ *
+ * There's one tricky piece to this implementation: when we return events via
+ * aeApiPoll, the corresponding file descriptors become dissociated from the
+ * port. This is necessary because poll events are level-triggered, so if the
+ * fd didn't become dissociated, it would immediately fire another event since
+ * the underlying state hasn't changed yet. We must re-associate the file
+ * descriptor, but only after we know that our caller has actually read from it.
+ * The ae API does not tell us exactly when that happens, but we do know that
+ * it must happen by the time aeApiPoll is called again. Our solution is to
+ * keep track of the last fds returned by aeApiPoll and re-associate them next
+ * time aeApiPoll is invoked.
+ *
+ * To summarize, in this module, each fd association is EITHER (a) represented
+ * only via the in-kernel association OR (b) represented by pending_fds and
+ * pending_masks. (b) is only true for the last fds we returned from aeApiPoll,
+ * and only until we enter aeApiPoll again (at which point we restore the
+ * in-kernel association).
+ */
+#define MAX_EVENT_BATCHSZ 512
+
+typedef struct aeApiState {
+ int portfd; /* event port */
+ int npending; /* # of pending fds */
+ int pending_fds[MAX_EVENT_BATCHSZ]; /* pending fds */
+ int pending_masks[MAX_EVENT_BATCHSZ]; /* pending fds' masks */
+} aeApiState;
+
+static int aeApiCreate(aeEventLoop *eventLoop) {
+ int i;
+ aeApiState *state = zmalloc(sizeof(aeApiState));
+ if (!state) return -1;
+
+ state->portfd = port_create();
+ if (state->portfd == -1) {
+ zfree(state);
+ return -1;
+ }
+
+ state->npending = 0;
+
+ for (i = 0; i < MAX_EVENT_BATCHSZ; i++) {
+ state->pending_fds[i] = -1;
+ state->pending_masks[i] = AE_NONE;
+ }
+
+ eventLoop->apidata = state;
+ return 0;
+}
+
+static void aeApiFree(aeEventLoop *eventLoop) {
+ aeApiState *state = eventLoop->apidata;
+
+ close(state->portfd);
+ zfree(state);
+}
+
+static int aeApiLookupPending(aeApiState *state, int fd) {
+ int i;
+
+ for (i = 0; i < state->npending; i++) {
+ if (state->pending_fds[i] == fd)
+ return (i);
+ }
+
+ return (-1);
+}
+
+/*
+ * Helper function to invoke port_associate for the given fd and mask.
+ */
+static int aeApiAssociate(const char *where, int portfd, int fd, int mask) {
+ int events = 0;
+ int rv, err;
+
+ if (mask & AE_READABLE)
+ events |= POLLIN;
+ if (mask & AE_WRITABLE)
+ events |= POLLOUT;
+
+ if (evport_debug)
+ fprintf(stderr, "%s: port_associate(%d, 0x%x) = ", where, fd, events);
+
+ rv = port_associate(portfd, PORT_SOURCE_FD, fd, events,
+ (void *)(uintptr_t)mask);
+ err = errno;
+
+ if (evport_debug)
+ fprintf(stderr, "%d (%s)\n", rv, rv == 0 ? "no error" : strerror(err));
+
+ if (rv == -1) {
+ fprintf(stderr, "%s: port_associate: %s\n", where, strerror(err));
+
+ if (err == EAGAIN)
+ fprintf(stderr, "aeApiAssociate: event port limit exceeded.");
+ }
+
+ return rv;
+}
+
+static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
+ aeApiState *state = eventLoop->apidata;
+ int fullmask, pfd;
+
+ if (evport_debug)
+ fprintf(stderr, "aeApiAddEvent: fd %d mask 0x%x\n", fd, mask);
+
+ /*
+ * Since port_associate's "events" argument replaces any existing events, we
+ * must be sure to include whatever events are already associated when
+ * we call port_associate() again.
+ */
+ fullmask = mask | eventLoop->events[fd].mask;
+ pfd = aeApiLookupPending(state, fd);
+
+ if (pfd != -1) {
+ /*
+ * This fd was recently returned from aeApiPoll. It should be safe to
+ * assume that the consumer has processed that poll event, but we play
+ * it safer by simply updating pending_mask. The fd will be
+ * re-associated as usual when aeApiPoll is called again.
+ */
+ if (evport_debug)
+ fprintf(stderr, "aeApiAddEvent: adding to pending fd %d\n", fd);
+ state->pending_masks[pfd] |= fullmask;
+ return 0;
+ }
+
+ return (aeApiAssociate("aeApiAddEvent", state->portfd, fd, fullmask));
+}
+
+static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
+ aeApiState *state = eventLoop->apidata;
+ int fullmask, pfd;
+
+ if (evport_debug)
+ fprintf(stderr, "del fd %d mask 0x%x\n", fd, mask);
+
+ pfd = aeApiLookupPending(state, fd);
+
+ if (pfd != -1) {
+ if (evport_debug)
+ fprintf(stderr, "deleting event from pending fd %d\n", fd);
+
+ /*
+ * This fd was just returned from aeApiPoll, so it's not currently
+ * associated with the port. All we need to do is update
+ * pending_mask appropriately.
+ */
+ state->pending_masks[pfd] &= ~mask;
+
+ if (state->pending_masks[pfd] == AE_NONE)
+ state->pending_fds[pfd] = -1;
+
+ return;
+ }
+
+ /*
+ * The fd is currently associated with the port. Like with the add case
+ * above, we must look at the full mask for the file descriptor before
+ * updating that association. We don't have a good way of knowing what the
+ * events are without looking into the eventLoop state directly. We rely on
+ * the fact that our caller has already updated the mask in the eventLoop.
+ */
+
+ fullmask = eventLoop->events[fd].mask;
+ if (fullmask == AE_NONE) {
+ /*
+ * We're removing *all* events, so use port_dissociate to remove the
+ * association completely. Failure here indicates a bug.
+ */
+ if (evport_debug)
+ fprintf(stderr, "aeApiDelEvent: port_dissociate(%d)\n", fd);
+
+ if (port_dissociate(state->portfd, PORT_SOURCE_FD, fd) != 0) {
+ perror("aeApiDelEvent: port_dissociate");
+ abort(); /* will not return */
+ }
+ } else if (aeApiAssociate("aeApiDelEvent", state->portfd, fd,
+ fullmask) != 0) {
+ /*
+ * ENOMEM is a potentially transient condition, but the kernel won't
+ * generally return it unless things are really bad. EAGAIN indicates
+ * we've reached an resource limit, for which it doesn't make sense to
+ * retry (counter-intuitively). All other errors indicate a bug. In any
+ * of these cases, the best we can do is to abort.
+ */
+ abort(); /* will not return */
+ }
+}
+
+static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
+ aeApiState *state = eventLoop->apidata;
+ struct timespec timeout, *tsp;
+ int mask, i;
+ uint_t nevents;
+ port_event_t event[MAX_EVENT_BATCHSZ];
+
+ /*
+ * If we've returned fd events before, we must re-associate them with the
+ * port now, before calling port_get(). See the block comment at the top of
+ * this file for an explanation of why.
+ */
+ for (i = 0; i < state->npending; i++) {
+ if (state->pending_fds[i] == -1)
+ /* This fd has since been deleted. */
+ continue;
+
+ if (aeApiAssociate("aeApiPoll", state->portfd,
+ state->pending_fds[i], state->pending_masks[i]) != 0) {
+ /* See aeApiDelEvent for why this case is fatal. */
+ abort();
+ }
+
+ state->pending_masks[i] = AE_NONE;
+ state->pending_fds[i] = -1;
+ }
+
+ state->npending = 0;
+
+ if (tvp != NULL) {
+ timeout.tv_sec = tvp->tv_sec;
+ timeout.tv_nsec = tvp->tv_usec * 1000;
+ tsp = &timeout;
+ } else {
+ tsp = NULL;
+ }
+
+ /*
+ * port_getn can return with errno == ETIME having returned some events (!).
+ * So if we get ETIME, we check nevents, too.
+ */
+ nevents = 1;
+ if (port_getn(state->portfd, event, MAX_EVENT_BATCHSZ, &nevents,
+ tsp) == -1 && (errno != ETIME || nevents == 0)) {
+ if (errno == ETIME || errno == EINTR)
+ return 0;
+
+ /* Any other error indicates a bug. */
+ perror("aeApiPoll: port_get");
+ abort();
+ }
+
+ state->npending = nevents;
+
+ for (i = 0; i < nevents; i++) {
+ mask = 0;
+ if (event[i].portev_events & POLLIN)
+ mask |= AE_READABLE;
+ if (event[i].portev_events & POLLOUT)
+ mask |= AE_WRITABLE;
+
+ eventLoop->fired[i].fd = event[i].portev_object;
+ eventLoop->fired[i].mask = mask;
+
+ if (evport_debug)
+ fprintf(stderr, "aeApiPoll: fd %d mask 0x%x\n",
+ (int)event[i].portev_object, mask);
+
+ state->pending_fds[i] = event[i].portev_object;
+ state->pending_masks[i] = (uintptr_t)event[i].portev_user;
+ }
+
+ return nevents;
+}
+
+static char *aeApiName(void) {
+ return "evport";
+}
diff --git a/tools/wrk/src/ae_kqueue.c b/tools/wrk/src/ae_kqueue.c
new file mode 100644
index 000000000..458772f7e
--- /dev/null
+++ b/tools/wrk/src/ae_kqueue.c
@@ -0,0 +1,132 @@
+/* Kqueue(2)-based ae.c module
+ *
+ * Copyright (C) 2009 Harish Mallipeddi - harish.mallipeddi@gmail.com
+ * 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 Redis 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.
+ */
+
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+
+typedef struct aeApiState {
+ int kqfd;
+ struct kevent *events;
+} aeApiState;
+
+static int aeApiCreate(aeEventLoop *eventLoop) {
+ aeApiState *state = zmalloc(sizeof(aeApiState));
+
+ if (!state) return -1;
+ state->events = zmalloc(sizeof(struct kevent)*eventLoop->setsize);
+ if (!state->events) {
+ zfree(state);
+ return -1;
+ }
+ state->kqfd = kqueue();
+ if (state->kqfd == -1) {
+ zfree(state->events);
+ zfree(state);
+ return -1;
+ }
+ eventLoop->apidata = state;
+
+ return 0;
+}
+
+static void aeApiFree(aeEventLoop *eventLoop) {
+ aeApiState *state = eventLoop->apidata;
+
+ close(state->kqfd);
+ zfree(state->events);
+ zfree(state);
+}
+
+static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
+ aeApiState *state = eventLoop->apidata;
+ struct kevent ke;
+
+ if (mask & AE_READABLE) {
+ EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
+ if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) return -1;
+ }
+ if (mask & AE_WRITABLE) {
+ EV_SET(&ke, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
+ if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) return -1;
+ }
+ return 0;
+}
+
+static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
+ aeApiState *state = eventLoop->apidata;
+ struct kevent ke;
+
+ if (mask & AE_READABLE) {
+ EV_SET(&ke, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
+ kevent(state->kqfd, &ke, 1, NULL, 0, NULL);
+ }
+ if (mask & AE_WRITABLE) {
+ EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
+ kevent(state->kqfd, &ke, 1, NULL, 0, NULL);
+ }
+}
+
+static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
+ aeApiState *state = eventLoop->apidata;
+ int retval, numevents = 0;
+
+ if (tvp != NULL) {
+ struct timespec timeout;
+ timeout.tv_sec = tvp->tv_sec;
+ timeout.tv_nsec = tvp->tv_usec * 1000;
+ retval = kevent(state->kqfd, NULL, 0, state->events, eventLoop->setsize,
+ &timeout);
+ } else {
+ retval = kevent(state->kqfd, NULL, 0, state->events, eventLoop->setsize,
+ NULL);
+ }
+
+ if (retval > 0) {
+ int j;
+
+ numevents = retval;
+ for(j = 0; j < numevents; j++) {
+ int mask = 0;
+ struct kevent *e = state->events+j;
+
+ if (e->filter == EVFILT_READ) mask |= AE_READABLE;
+ if (e->filter == EVFILT_WRITE) mask |= AE_WRITABLE;
+ eventLoop->fired[j].fd = e->ident;
+ eventLoop->fired[j].mask = mask;
+ }
+ }
+ return numevents;
+}
+
+static char *aeApiName(void) {
+ return "kqueue";
+}
diff --git a/tools/wrk/src/ae_select.c b/tools/wrk/src/ae_select.c
new file mode 100644
index 000000000..f732e8e1e
--- /dev/null
+++ b/tools/wrk/src/ae_select.c
@@ -0,0 +1,99 @@
+/* Select()-based ae.c module.
+ *
+ * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
+ * 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 Redis 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.
+ */
+
+
+#include <string.h>
+
+typedef struct aeApiState {
+ fd_set rfds, wfds;
+ /* We need to have a copy of the fd sets as it's not safe to reuse
+ * FD sets after select(). */
+ fd_set _rfds, _wfds;
+} aeApiState;
+
+static int aeApiCreate(aeEventLoop *eventLoop) {
+ aeApiState *state = zmalloc(sizeof(aeApiState));
+
+ if (!state) return -1;
+ FD_ZERO(&state->rfds);
+ FD_ZERO(&state->wfds);
+ eventLoop->apidata = state;
+ return 0;
+}
+
+static void aeApiFree(aeEventLoop *eventLoop) {
+ zfree(eventLoop->apidata);
+}
+
+static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
+ aeApiState *state = eventLoop->apidata;
+
+ if (mask & AE_READABLE) FD_SET(fd,&state->rfds);
+ if (mask & AE_WRITABLE) FD_SET(fd,&state->wfds);
+ return 0;
+}
+
+static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
+ aeApiState *state = eventLoop->apidata;
+
+ if (mask & AE_READABLE) FD_CLR(fd,&state->rfds);
+ if (mask & AE_WRITABLE) FD_CLR(fd,&state->wfds);
+}
+
+static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
+ aeApiState *state = eventLoop->apidata;
+ int retval, j, numevents = 0;
+
+ memcpy(&state->_rfds,&state->rfds,sizeof(fd_set));
+ memcpy(&state->_wfds,&state->wfds,sizeof(fd_set));
+
+ retval = select(eventLoop->maxfd+1,
+ &state->_rfds,&state->_wfds,NULL,tvp);
+ if (retval > 0) {
+ for (j = 0; j <= eventLoop->maxfd; j++) {
+ int mask = 0;
+ aeFileEvent *fe = &eventLoop->events[j];
+
+ if (fe->mask == AE_NONE) continue;
+ if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds))
+ mask |= AE_READABLE;
+ if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds))
+ mask |= AE_WRITABLE;
+ eventLoop->fired[numevents].fd = j;
+ eventLoop->fired[numevents].mask = mask;
+ numevents++;
+ }
+ }
+ return numevents;
+}
+
+static char *aeApiName(void) {
+ return "select";
+}
diff --git a/tools/wrk/src/aprintf.c b/tools/wrk/src/aprintf.c
new file mode 100644
index 000000000..1dcbe2393
--- /dev/null
+++ b/tools/wrk/src/aprintf.c
@@ -0,0 +1,27 @@
+// Copyright (C) 2012 - Will Glozer. All rights reserved.
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+char *aprintf(char **s, const char *fmt, ...) {
+ char *c = NULL;
+ int n, len;
+ va_list ap;
+
+ va_start(ap, fmt);
+ n = vsnprintf(NULL, 0, fmt, ap) + 1;
+ va_end(ap);
+
+ len = *s ? strlen(*s) : 0;
+
+ if ((*s = realloc(*s, (len + n) * sizeof(char)))) {
+ c = *s + len;
+ va_start(ap, fmt);
+ vsnprintf(c, n, fmt, ap);
+ va_end(ap);
+ }
+
+ return c;
+}
diff --git a/tools/wrk/src/aprintf.h b/tools/wrk/src/aprintf.h
new file mode 100644
index 000000000..97bcc6eb7
--- /dev/null
+++ b/tools/wrk/src/aprintf.h
@@ -0,0 +1,6 @@
+#ifndef APRINTF_H
+#define APRINTF_H
+
+char *aprintf(char **, const char *, ...);
+
+#endif /* APRINTF_H */
diff --git a/tools/wrk/src/config.h b/tools/wrk/src/config.h
new file mode 100644
index 000000000..82ed65036
--- /dev/null
+++ b/tools/wrk/src/config.h
@@ -0,0 +1,13 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#if defined(__FreeBSD__) || defined(__APPLE__)
+#define HAVE_KQUEUE
+#elif defined(__sun)
+#define HAVE_EVPORT
+#elif defined(__linux__)
+#define HAVE_EPOLL
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#endif /* CONFIG_H */
diff --git a/tools/wrk/src/http_parser.c b/tools/wrk/src/http_parser.c
new file mode 100644
index 000000000..f2ca661ba
--- /dev/null
+++ b/tools/wrk/src/http_parser.c
@@ -0,0 +1,2058 @@
+/* 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.
+ */
+#include "http_parser.h"
+#include <assert.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#ifndef ULLONG_MAX
+# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */
+#endif
+
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+
+#if HTTP_PARSER_DEBUG
+#define SET_ERRNO(e) \
+do { \
+ parser->http_errno = (e); \
+ parser->error_lineno = __LINE__; \
+} while (0)
+#else
+#define SET_ERRNO(e) \
+do { \
+ parser->http_errno = (e); \
+} while(0)
+#endif
+
+
+/* Run the notify callback FOR, returning ER if it fails */
+#define CALLBACK_NOTIFY_(FOR, ER) \
+do { \
+ assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \
+ \
+ if (settings->on_##FOR) { \
+ if (0 != settings->on_##FOR(parser)) { \
+ SET_ERRNO(HPE_CB_##FOR); \
+ } \
+ \
+ /* We either errored above or got paused; get out */ \
+ if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \
+ return (ER); \
+ } \
+ } \
+} while (0)
+
+/* Run the notify callback FOR and consume the current byte */
+#define CALLBACK_NOTIFY(FOR) CALLBACK_NOTIFY_(FOR, p - data + 1)
+
+/* Run the notify callback FOR and don't consume the current byte */
+#define CALLBACK_NOTIFY_NOADVANCE(FOR) CALLBACK_NOTIFY_(FOR, p - data)
+
+/* Run data callback FOR with LEN bytes, returning ER if it fails */
+#define CALLBACK_DATA_(FOR, LEN, ER) \
+do { \
+ assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \
+ \
+ if (FOR##_mark) { \
+ if (settings->on_##FOR) { \
+ if (0 != settings->on_##FOR(parser, FOR##_mark, (LEN))) { \
+ SET_ERRNO(HPE_CB_##FOR); \
+ } \
+ \
+ /* We either errored above or got paused; get out */ \
+ if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \
+ return (ER); \
+ } \
+ } \
+ FOR##_mark = NULL; \
+ } \
+} while (0)
+
+/* Run the data callback FOR and consume the current byte */
+#define CALLBACK_DATA(FOR) \
+ CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
+
+/* Run the data callback FOR and don't consume the current byte */
+#define CALLBACK_DATA_NOADVANCE(FOR) \
+ CALLBACK_DATA_(FOR, p - FOR##_mark, p - data)
+
+/* Set the mark FOR; non-destructive if mark is already set */
+#define MARK(FOR) \
+do { \
+ if (!FOR##_mark) { \
+ FOR##_mark = p; \
+ } \
+} while (0)
+
+
+#define PROXY_CONNECTION "proxy-connection"
+#define CONNECTION "connection"
+#define CONTENT_LENGTH "content-length"
+#define TRANSFER_ENCODING "transfer-encoding"
+#define UPGRADE "upgrade"
+#define CHUNKED "chunked"
+#define KEEP_ALIVE "keep-alive"
+#define CLOSE "close"
+
+
+static const char *method_strings[] =
+ { "DELETE"
+ , "GET"
+ , "HEAD"
+ , "POST"
+ , "PUT"
+ , "CONNECT"
+ , "OPTIONS"
+ , "TRACE"
+ , "COPY"
+ , "LOCK"
+ , "MKCOL"
+ , "MOVE"
+ , "PROPFIND"
+ , "PROPPATCH"
+ , "UNLOCK"
+ , "REPORT"
+ , "MKACTIVITY"
+ , "CHECKOUT"
+ , "MERGE"
+ , "M-SEARCH"
+ , "NOTIFY"
+ , "SUBSCRIBE"
+ , "UNSUBSCRIBE"
+ , "PATCH"
+ , "PURGE"
+ };
+
+
+/* Tokens as defined by rfc 2616. Also lowercases them.
+ * token = 1*<any CHAR except CTLs or separators>
+ * separators = "(" | ")" | "<" | ">" | "@"
+ * | "," | ";" | ":" | "\" | <">
+ * | "/" | "[" | "]" | "?" | "="
+ * | "{" | "}" | SP | HT
+ */
+static const char tokens[256] = {
+/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
+ 0, '!', 0, '#', '$', '%', '&', '\'',
+/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
+ 0, 0, '*', '+', 0, '-', '.', 0,
+/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
+ '0', '1', '2', '3', '4', '5', '6', '7',
+/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
+ '8', '9', 0, 0, 0, 0, 0, 0,
+/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */
+ 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
+ 'x', 'y', 'z', 0, 0, 0, '^', '_',
+/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
+ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
+ 'x', 'y', 'z', 0, '|', 0, '~', 0 };
+
+
+static const int8_t unhex[256] =
+ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+ ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+ ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+ , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
+ ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
+ ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+ ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
+ ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+ };
+
+
+static const uint8_t normal_url_char[256] = {
+/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
+ 0, 1, 1, 0, 1, 1, 1, 1,
+/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
+ 1, 1, 1, 1, 1, 1, 1, 1,
+/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
+ 1, 1, 1, 1, 1, 1, 1, 1,
+/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
+ 1, 1, 1, 1, 1, 1, 1, 0,
+/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */
+ 1, 1, 1, 1, 1, 1, 1, 1,
+/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */
+ 1, 1, 1, 1, 1, 1, 1, 1,
+/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */
+ 1, 1, 1, 1, 1, 1, 1, 1,
+/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
+ 1, 1, 1, 1, 1, 1, 1, 1,
+/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
+ 1, 1, 1, 1, 1, 1, 1, 1,
+/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
+ 1, 1, 1, 1, 1, 1, 1, 1,
+/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
+ 1, 1, 1, 1, 1, 1, 1, 1,
+/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
+ 1, 1, 1, 1, 1, 1, 1, 0, };
+
+
+enum state
+ { s_dead = 1 /* important that this is > 0 */
+
+ , s_start_req_or_res
+ , s_res_or_resp_H
+ , s_start_res
+ , s_res_H
+ , s_res_HT
+ , s_res_HTT
+ , s_res_HTTP
+ , s_res_first_http_major
+ , s_res_http_major
+ , s_res_first_http_minor
+ , s_res_http_minor
+ , s_res_first_status_code
+ , s_res_status_code
+ , s_res_status
+ , s_res_line_almost_done
+
+ , s_start_req
+
+ , s_req_method
+ , s_req_spaces_before_url
+ , s_req_schema
+ , s_req_schema_slash
+ , s_req_schema_slash_slash
+ , s_req_host_start
+ , s_req_host_v6_start
+ , s_req_host_v6
+ , s_req_host_v6_end
+ , s_req_host
+ , s_req_port_start
+ , s_req_port
+ , s_req_path
+ , s_req_query_string_start
+ , s_req_query_string
+ , s_req_fragment_start
+ , s_req_fragment
+ , s_req_http_start
+ , s_req_http_H
+ , s_req_http_HT
+ , s_req_http_HTT
+ , s_req_http_HTTP
+ , s_req_first_http_major
+ , s_req_http_major
+ , s_req_first_http_minor
+ , s_req_http_minor
+ , s_req_line_almost_done
+
+ , s_header_field_start
+ , s_header_field
+ , s_header_value_start
+ , s_header_value
+ , s_header_value_lws
+
+ , s_header_almost_done
+
+ , s_chunk_size_start
+ , s_chunk_size
+ , s_chunk_parameters
+ , s_chunk_size_almost_done
+
+ , s_headers_almost_done
+ , s_headers_done
+
+ /* Important: 's_headers_done' must be the last 'header' state. All
+ * states beyond this must be 'body' states. It is used for overflow
+ * checking. See the PARSING_HEADER() macro.
+ */
+
+ , s_chunk_data
+ , s_chunk_data_almost_done
+ , s_chunk_data_done
+
+ , s_body_identity
+ , s_body_identity_eof
+
+ , s_message_done
+ };
+
+
+#define PARSING_HEADER(state) (state <= s_headers_done)
+
+
+enum header_states
+ { h_general = 0
+ , h_C
+ , h_CO
+ , h_CON
+
+ , h_matching_connection
+ , h_matching_proxy_connection
+ , h_matching_content_length
+ , h_matching_transfer_encoding
+ , h_matching_upgrade
+
+ , h_connection
+ , h_content_length
+ , h_transfer_encoding
+ , h_upgrade
+
+ , h_matching_transfer_encoding_chunked
+ , h_matching_connection_keep_alive
+ , h_matching_connection_close
+
+ , h_transfer_encoding_chunked
+ , h_connection_keep_alive
+ , h_connection_close
+ };
+
+
+/* Macros for character classes; depends on strict-mode */
+#define CR '\r'
+#define LF '\n'
+#define LOWER(c) (unsigned char)(c | 0x20)
+#define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z')
+#define IS_NUM(c) ((c) >= '0' && (c) <= '9')
+#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c))
+#define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f'))
+
+#if HTTP_PARSER_STRICT
+#define TOKEN(c) (tokens[(unsigned char)c])
+#define IS_URL_CHAR(c) (normal_url_char[(unsigned char) (c)])
+#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
+#else
+#define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c])
+#define IS_URL_CHAR(c) \
+ (normal_url_char[(unsigned char) (c)] || ((c) & 0x80))
+#define IS_HOST_CHAR(c) \
+ (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')
+#endif
+
+
+#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)
+
+
+#if HTTP_PARSER_STRICT
+# define STRICT_CHECK(cond) \
+do { \
+ if (cond) { \
+ SET_ERRNO(HPE_STRICT); \
+ goto error; \
+ } \
+} while (0)
+# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead)
+#else
+# define STRICT_CHECK(cond)
+# define NEW_MESSAGE() start_state
+#endif
+
+
+/* Map errno values to strings for human-readable output */
+#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s },
+static struct {
+ const char *name;
+ const char *description;
+} http_strerror_tab[] = {
+ HTTP_ERRNO_MAP(HTTP_STRERROR_GEN)
+};
+#undef HTTP_STRERROR_GEN
+
+int http_message_needs_eof(http_parser *parser);
+
+/* Our URL parser.
+ *
+ * This is designed to be shared by http_parser_execute() for URL validation,
+ * hence it has a state transition + byte-for-byte interface. In addition, it
+ * is meant to be embedded in http_parser_parse_url(), which does the dirty
+ * work of turning state transitions URL components for its API.
+ *
+ * This function should only be invoked with non-space characters. It is
+ * assumed that the caller cares about (and can detect) the transition between
+ * URL and non-URL states by looking for these.
+ */
+static enum state
+parse_url_char(enum state s, const char ch)
+{
+ assert(!isspace(ch));
+
+ switch (s) {
+ case s_req_spaces_before_url:
+ /* Proxied requests are followed by scheme of an absolute URI (alpha).
+ * All methods except CONNECT are followed by '/' or '*'.
+ */
+
+ if (ch == '/' || ch == '*') {
+ return s_req_path;
+ }
+
+ if (IS_ALPHA(ch)) {
+ return s_req_schema;
+ }
+
+ break;
+
+ case s_req_schema:
+ if (IS_ALPHA(ch)) {
+ return s;
+ }
+
+ if (ch == ':') {
+ return s_req_schema_slash;
+ }
+
+ break;
+
+ case s_req_schema_slash:
+ if (ch == '/') {
+ return s_req_schema_slash_slash;
+ }
+
+ break;
+
+ case s_req_schema_slash_slash:
+ if (ch == '/') {
+ return s_req_host_start;
+ }
+
+ break;
+
+ case s_req_host_start:
+ if (ch == '[') {
+ return s_req_host_v6_start;
+ }
+
+ if (IS_HOST_CHAR(ch)) {
+ return s_req_host;
+ }
+
+ break;
+
+ case s_req_host:
+ if (IS_HOST_CHAR(ch)) {
+ return s_req_host;
+ }
+
+ /* FALLTHROUGH */
+ case s_req_host_v6_end:
+ switch (ch) {
+ case ':':
+ return s_req_port_start;
+
+ case '/':
+ return s_req_path;
+
+ case '?':
+ return s_req_query_string_start;
+ }
+
+ break;
+
+ case s_req_host_v6:
+ if (ch == ']') {
+ return s_req_host_v6_end;
+ }
+
+ /* FALLTHROUGH */
+ case s_req_host_v6_start:
+ if (IS_HEX(ch) || ch == ':') {
+ return s_req_host_v6;
+ }
+ break;
+
+ case s_req_port:
+ switch (ch) {
+ case '/':
+ return s_req_path;
+
+ case '?':
+ return s_req_query_string_start;
+ }
+
+ /* FALLTHROUGH */
+ case s_req_port_start:
+ if (IS_NUM(ch)) {
+ return s_req_port;
+ }
+
+ break;
+
+ case s_req_path:
+ if (IS_URL_CHAR(ch)) {
+ return s;
+ }
+
+ switch (ch) {
+ case '?':
+ return s_req_query_string_start;
+
+ case '#':
+ return s_req_fragment_start;
+ }
+
+ break;
+
+ case s_req_query_string_start:
+ case s_req_query_string:
+ if (IS_URL_CHAR(ch)) {
+ return s_req_query_string;
+ }
+
+ switch (ch) {
+ case '?':
+ /* allow extra '?' in query string */
+ return s_req_query_string;
+
+ case '#':
+ return s_req_fragment_start;
+ }
+
+ break;
+
+ case s_req_fragment_start:
+ if (IS_URL_CHAR(ch)) {
+ return s_req_fragment;
+ }
+
+ switch (ch) {
+ case '?':
+ return s_req_fragment;
+
+ case '#':
+ return s;
+ }
+
+ break;
+
+ case s_req_fragment:
+ if (IS_URL_CHAR(ch)) {
+ return s;
+ }
+
+ switch (ch) {
+ case '?':
+ case '#':
+ return s;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ /* We should never fall out of the switch above unless there's an error */
+ return s_dead;
+}
+
+size_t http_parser_execute (http_parser *parser,
+ const http_parser_settings *settings,
+ const char *data,
+ size_t len)
+{
+ char c, ch;
+ int8_t unhex_val;
+ const char *p = data;
+ const char *header_field_mark = 0;
+ const char *header_value_mark = 0;
+ const char *url_mark = 0;
+ const char *body_mark = 0;
+
+ /* We're in an error state. Don't bother doing anything. */
+ if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
+ return 0;
+ }
+
+ if (len == 0) {
+ switch (parser->state) {
+ case s_body_identity_eof:
+ /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if
+ * we got paused.
+ */
+ CALLBACK_NOTIFY_NOADVANCE(message_complete);
+ return 0;
+
+ case s_dead:
+ case s_start_req_or_res:
+ case s_start_res:
+ case s_start_req:
+ return 0;
+
+ default:
+ SET_ERRNO(HPE_INVALID_EOF_STATE);
+ return 1;
+ }
+ }
+
+
+ if (parser->state == s_header_field)
+ header_field_mark = data;
+ if (parser->state == s_header_value)
+ header_value_mark = data;
+ switch (parser->state) {
+ case s_req_path:
+ case s_req_schema:
+ case s_req_schema_slash:
+ case s_req_schema_slash_slash:
+ case s_req_host_start:
+ case s_req_host_v6_start:
+ case s_req_host_v6:
+ case s_req_host_v6_end:
+ case s_req_host:
+ case s_req_port_start:
+ case s_req_port:
+ case s_req_query_string_start:
+ case s_req_query_string:
+ case s_req_fragment_start:
+ case s_req_fragment:
+ url_mark = data;
+ break;
+ }
+
+ for (p=data; p != data + len; p++) {
+ ch = *p;
+
+ if (PARSING_HEADER(parser->state)) {
+ ++parser->nread;
+ /* Buffer overflow attack */
+ if (parser->nread > HTTP_MAX_HEADER_SIZE) {
+ SET_ERRNO(HPE_HEADER_OVERFLOW);
+ goto error;
+ }
+ }
+
+ reexecute_byte:
+ switch (parser->state) {
+
+ case s_dead:
+ /* this state is used after a 'Connection: close' message
+ * the parser will error out if it reads another message
+ */
+ if (ch == CR || ch == LF)
+ break;
+
+ SET_ERRNO(HPE_CLOSED_CONNECTION);
+ goto error;
+
+ case s_start_req_or_res:
+ {
+ if (ch == CR || ch == LF)
+ break;
+ parser->flags = 0;
+ parser->content_length = ULLONG_MAX;
+
+ if (ch == 'H') {
+ parser->state = s_res_or_resp_H;
+
+ CALLBACK_NOTIFY(message_begin);
+ } else {
+ parser->type = HTTP_REQUEST;
+ parser->state = s_start_req;
+ goto reexecute_byte;
+ }
+
+ break;
+ }
+
+ case s_res_or_resp_H:
+ if (ch == 'T') {
+ parser->type = HTTP_RESPONSE;
+ parser->state = s_res_HT;
+ } else {
+ if (ch != 'E') {
+ SET_ERRNO(HPE_INVALID_CONSTANT);
+ goto error;
+ }
+
+ parser->type = HTTP_REQUEST;
+ parser->method = HTTP_HEAD;
+ parser->index = 2;
+ parser->state = s_req_method;
+ }
+ break;
+
+ case s_start_res:
+ {
+ parser->flags = 0;
+ parser->content_length = ULLONG_MAX;
+
+ switch (ch) {
+ case 'H':
+ parser->state = s_res_H;
+ break;
+
+ case CR:
+ case LF:
+ break;
+
+ default:
+ SET_ERRNO(HPE_INVALID_CONSTANT);
+ goto error;
+ }
+
+ CALLBACK_NOTIFY(message_begin);
+ break;
+ }
+
+ case s_res_H:
+ STRICT_CHECK(ch != 'T');
+ parser->state = s_res_HT;
+ break;
+
+ case s_res_HT:
+ STRICT_CHECK(ch != 'T');
+ parser->state = s_res_HTT;
+ break;
+
+ case s_res_HTT:
+ STRICT_CHECK(ch != 'P');
+ parser->state = s_res_HTTP;
+ break;
+
+ case s_res_HTTP:
+ STRICT_CHECK(ch != '/');
+ parser->state = s_res_first_http_major;
+ break;
+
+ case s_res_first_http_major:
+ if (ch < '0' || ch > '9') {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ parser->http_major = ch - '0';
+ parser->state = s_res_http_major;
+ break;
+
+ /* major HTTP version or dot */
+ case s_res_http_major:
+ {
+ if (ch == '.') {
+ parser->state = s_res_first_http_minor;
+ break;
+ }
+
+ if (!IS_NUM(ch)) {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ parser->http_major *= 10;
+ parser->http_major += ch - '0';
+
+ if (parser->http_major > 999) {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ break;
+ }
+
+ /* first digit of minor HTTP version */
+ case s_res_first_http_minor:
+ if (!IS_NUM(ch)) {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ parser->http_minor = ch - '0';
+ parser->state = s_res_http_minor;
+ break;
+
+ /* minor HTTP version or end of request line */
+ case s_res_http_minor:
+ {
+ if (ch == ' ') {
+ parser->state = s_res_first_status_code;
+ break;
+ }
+
+ if (!IS_NUM(ch)) {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ parser->http_minor *= 10;
+ parser->http_minor += ch - '0';
+
+ if (parser->http_minor > 999) {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ break;
+ }
+
+ case s_res_first_status_code:
+ {
+ if (!IS_NUM(ch)) {
+ if (ch == ' ') {
+ break;
+ }
+
+ SET_ERRNO(HPE_INVALID_STATUS);
+ goto error;
+ }
+ parser->status_code = ch - '0';
+ parser->state = s_res_status_code;
+ break;
+ }
+
+ case s_res_status_code:
+ {
+ if (!IS_NUM(ch)) {
+ switch (ch) {
+ case ' ':
+ parser->state = s_res_status;
+ break;
+ case CR:
+ parser->state = s_res_line_almost_done;
+ break;
+ case LF:
+ parser->state = s_header_field_start;
+ break;
+ default:
+ SET_ERRNO(HPE_INVALID_STATUS);
+ goto error;
+ }
+ break;
+ }
+
+ parser->status_code *= 10;
+ parser->status_code += ch - '0';
+
+ if (parser->status_code > 999) {
+ SET_ERRNO(HPE_INVALID_STATUS);
+ goto error;
+ }
+
+ break;
+ }
+
+ case s_res_status:
+ /* the human readable status. e.g. "NOT FOUND"
+ * we are not humans so just ignore this */
+ if (ch == CR) {
+ parser->state = s_res_line_almost_done;
+ break;
+ }
+
+ if (ch == LF) {
+ parser->state = s_header_field_start;
+ break;
+ }
+ break;
+
+ case s_res_line_almost_done:
+ STRICT_CHECK(ch != LF);
+ parser->state = s_header_field_start;
+ break;
+
+ case s_start_req:
+ {
+ if (ch == CR || ch == LF)
+ break;
+ parser->flags = 0;
+ parser->content_length = ULLONG_MAX;
+
+ if (!IS_ALPHA(ch)) {
+ SET_ERRNO(HPE_INVALID_METHOD);
+ goto error;
+ }
+
+ parser->method = (enum http_method) 0;
+ parser->index = 1;
+ switch (ch) {
+ case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break;
+ case 'D': parser->method = HTTP_DELETE; break;
+ case 'G': parser->method = HTTP_GET; break;
+ case 'H': parser->method = HTTP_HEAD; break;
+ case 'L': parser->method = HTTP_LOCK; break;
+ case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break;
+ case 'N': parser->method = HTTP_NOTIFY; break;
+ case 'O': parser->method = HTTP_OPTIONS; break;
+ case 'P': parser->method = HTTP_POST;
+ /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */
+ break;
+ case 'R': parser->method = HTTP_REPORT; break;
+ case 'S': parser->method = HTTP_SUBSCRIBE; break;
+ case 'T': parser->method = HTTP_TRACE; break;
+ case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break;
+ default:
+ SET_ERRNO(HPE_INVALID_METHOD);
+ goto error;
+ }
+ parser->state = s_req_method;
+
+ CALLBACK_NOTIFY(message_begin);
+
+ break;
+ }
+
+ case s_req_method:
+ {
+ const char *matcher;
+ if (ch == '\0') {
+ SET_ERRNO(HPE_INVALID_METHOD);
+ goto error;
+ }
+
+ matcher = method_strings[parser->method];
+ if (ch == ' ' && matcher[parser->index] == '\0') {
+ parser->state = s_req_spaces_before_url;
+ } else if (ch == matcher[parser->index]) {
+ ; /* nada */
+ } else if (parser->method == HTTP_CONNECT) {
+ if (parser->index == 1 && ch == 'H') {
+ parser->method = HTTP_CHECKOUT;
+ } else if (parser->index == 2 && ch == 'P') {
+ parser->method = HTTP_COPY;
+ } else {
+ goto error;
+ }
+ } else if (parser->method == HTTP_MKCOL) {
+ if (parser->index == 1 && ch == 'O') {
+ parser->method = HTTP_MOVE;
+ } else if (parser->index == 1 && ch == 'E') {
+ parser->method = HTTP_MERGE;
+ } else if (parser->index == 1 && ch == '-') {
+ parser->method = HTTP_MSEARCH;
+ } else if (parser->index == 2 && ch == 'A') {
+ parser->method = HTTP_MKACTIVITY;
+ } else {
+ goto error;
+ }
+ } else if (parser->index == 1 && parser->method == HTTP_POST) {
+ if (ch == 'R') {
+ parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
+ } else if (ch == 'U') {
+ parser->method = HTTP_PUT; /* or HTTP_PURGE */
+ } else if (ch == 'A') {
+ parser->method = HTTP_PATCH;
+ } else {
+ goto error;
+ }
+ } else if (parser->index == 2) {
+ if (parser->method == HTTP_PUT) {
+ if (ch == 'R') parser->method = HTTP_PURGE;
+ } else if (parser->method == HTTP_UNLOCK) {
+ if (ch == 'S') parser->method = HTTP_UNSUBSCRIBE;
+ }
+ } else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
+ parser->method = HTTP_PROPPATCH;
+ } else {
+ SET_ERRNO(HPE_INVALID_METHOD);
+ goto error;
+ }
+
+ ++parser->index;
+ break;
+ }
+
+ case s_req_spaces_before_url:
+ {
+ if (ch == ' ') break;
+
+ MARK(url);
+ if (parser->method == HTTP_CONNECT) {
+ parser->state = s_req_host_start;
+ }
+
+ parser->state = parse_url_char((enum state)parser->state, ch);
+ if (parser->state == s_dead) {
+ SET_ERRNO(HPE_INVALID_URL);
+ goto error;
+ }
+
+ break;
+ }
+
+ case s_req_schema:
+ case s_req_schema_slash:
+ case s_req_schema_slash_slash:
+ case s_req_host_start:
+ case s_req_host_v6_start:
+ case s_req_host_v6:
+ case s_req_port_start:
+ {
+ switch (ch) {
+ /* No whitespace allowed here */
+ case ' ':
+ case CR:
+ case LF:
+ SET_ERRNO(HPE_INVALID_URL);
+ goto error;
+ default:
+ parser->state = parse_url_char((enum state)parser->state, ch);
+ if (parser->state == s_dead) {
+ SET_ERRNO(HPE_INVALID_URL);
+ goto error;
+ }
+ }
+
+ break;
+ }
+
+ case s_req_host:
+ case s_req_host_v6_end:
+ case s_req_port:
+ case s_req_path:
+ case s_req_query_string_start:
+ case s_req_query_string:
+ case s_req_fragment_start:
+ case s_req_fragment:
+ {
+ switch (ch) {
+ case ' ':
+ parser->state = s_req_http_start;
+ CALLBACK_DATA(url);
+ break;
+ case CR:
+ case LF:
+ parser->http_major = 0;
+ parser->http_minor = 9;
+ parser->state = (ch == CR) ?
+ s_req_line_almost_done :
+ s_header_field_start;
+ CALLBACK_DATA(url);
+ break;
+ default:
+ parser->state = parse_url_char((enum state)parser->state, ch);
+ if (parser->state == s_dead) {
+ SET_ERRNO(HPE_INVALID_URL);
+ goto error;
+ }
+ }
+ break;
+ }
+
+ case s_req_http_start:
+ switch (ch) {
+ case 'H':
+ parser->state = s_req_http_H;
+ break;
+ case ' ':
+ break;
+ default:
+ SET_ERRNO(HPE_INVALID_CONSTANT);
+ goto error;
+ }
+ break;
+
+ case s_req_http_H:
+ STRICT_CHECK(ch != 'T');
+ parser->state = s_req_http_HT;
+ break;
+
+ case s_req_http_HT:
+ STRICT_CHECK(ch != 'T');
+ parser->state = s_req_http_HTT;
+ break;
+
+ case s_req_http_HTT:
+ STRICT_CHECK(ch != 'P');
+ parser->state = s_req_http_HTTP;
+ break;
+
+ case s_req_http_HTTP:
+ STRICT_CHECK(ch != '/');
+ parser->state = s_req_first_http_major;
+ break;
+
+ /* first digit of major HTTP version */
+ case s_req_first_http_major:
+ if (ch < '1' || ch > '9') {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ parser->http_major = ch - '0';
+ parser->state = s_req_http_major;
+ break;
+
+ /* major HTTP version or dot */
+ case s_req_http_major:
+ {
+ if (ch == '.') {
+ parser->state = s_req_first_http_minor;
+ break;
+ }
+
+ if (!IS_NUM(ch)) {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ parser->http_major *= 10;
+ parser->http_major += ch - '0';
+
+ if (parser->http_major > 999) {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ break;
+ }
+
+ /* first digit of minor HTTP version */
+ case s_req_first_http_minor:
+ if (!IS_NUM(ch)) {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ parser->http_minor = ch - '0';
+ parser->state = s_req_http_minor;
+ break;
+
+ /* minor HTTP version or end of request line */
+ case s_req_http_minor:
+ {
+ if (ch == CR) {
+ parser->state = s_req_line_almost_done;
+ break;
+ }
+
+ if (ch == LF) {
+ parser->state = s_header_field_start;
+ break;
+ }
+
+ /* XXX allow spaces after digit? */
+
+ if (!IS_NUM(ch)) {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ parser->http_minor *= 10;
+ parser->http_minor += ch - '0';
+
+ if (parser->http_minor > 999) {
+ SET_ERRNO(HPE_INVALID_VERSION);
+ goto error;
+ }
+
+ break;
+ }
+
+ /* end of request line */
+ case s_req_line_almost_done:
+ {
+ if (ch != LF) {
+ SET_ERRNO(HPE_LF_EXPECTED);
+ goto error;
+ }
+
+ parser->state = s_header_field_start;
+ break;
+ }
+
+ case s_header_field_start:
+ {
+ if (ch == CR) {
+ parser->state = s_headers_almost_done;
+ break;
+ }
+
+ if (ch == LF) {
+ /* they might be just sending \n instead of \r\n so this would be
+ * the second \n to denote the end of headers*/
+ parser->state = s_headers_almost_done;
+ goto reexecute_byte;
+ }
+
+ c = TOKEN(ch);
+
+ if (!c) {
+ SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
+ goto error;
+ }
+
+ MARK(header_field);
+
+ parser->index = 0;
+ parser->state = s_header_field;
+
+ switch (c) {
+ case 'c':
+ parser->header_state = h_C;
+ break;
+
+ case 'p':
+ parser->header_state = h_matching_proxy_connection;
+ break;
+
+ case 't':
+ parser->header_state = h_matching_transfer_encoding;
+ break;
+
+ case 'u':
+ parser->header_state = h_matching_upgrade;
+ break;
+
+ default:
+ parser->header_state = h_general;
+ break;
+ }
+ break;
+ }
+
+ case s_header_field:
+ {
+ c = TOKEN(ch);
+
+ if (c) {
+ switch (parser->header_state) {
+ case h_general:
+ break;
+
+ case h_C:
+ parser->index++;
+ parser->header_state = (c == 'o' ? h_CO : h_general);
+ break;
+
+ case h_CO:
+ parser->index++;
+ parser->header_state = (c == 'n' ? h_CON : h_general);
+ break;
+
+ case h_CON:
+ parser->index++;
+ switch (c) {
+ case 'n':
+ parser->header_state = h_matching_connection;
+ break;
+ case 't':
+ parser->header_state = h_matching_content_length;
+ break;
+ default:
+ parser->header_state = h_general;
+ break;
+ }
+ break;
+
+ /* connection */
+
+ case h_matching_connection:
+ parser->index++;
+ if (parser->index > sizeof(CONNECTION)-1
+ || c != CONNECTION[parser->index]) {
+ parser->header_state = h_general;
+ } else if (parser->index == sizeof(CONNECTION)-2) {
+ parser->header_state = h_connection;
+ }
+ break;
+
+ /* proxy-connection */
+
+ case h_matching_proxy_connection:
+ parser->index++;
+ if (parser->index > sizeof(PROXY_CONNECTION)-1
+ || c != PROXY_CONNECTION[parser->index]) {
+ parser->header_state = h_general;
+ } else if (parser->index == sizeof(PROXY_CONNECTION)-2) {
+ parser->header_state = h_connection;
+ }
+ break;
+
+ /* content-length */
+
+ case h_matching_content_length:
+ parser->index++;
+ if (parser->index > sizeof(CONTENT_LENGTH)-1
+ || c != CONTENT_LENGTH[parser->index]) {
+ parser->header_state = h_general;
+ } else if (parser->index == sizeof(CONTENT_LENGTH)-2) {
+ parser->header_state = h_content_length;
+ }
+ break;
+
+ /* transfer-encoding */
+
+ case h_matching_transfer_encoding:
+ parser->index++;
+ if (parser->index > sizeof(TRANSFER_ENCODING)-1
+ || c != TRANSFER_ENCODING[parser->index]) {
+ parser->header_state = h_general;
+ } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
+ parser->header_state = h_transfer_encoding;
+ }
+ break;
+
+ /* upgrade */
+
+ case h_matching_upgrade:
+ parser->index++;
+ if (parser->index > sizeof(UPGRADE)-1
+ || c != UPGRADE[parser->index]) {
+ parser->header_state = h_general;
+ } else if (parser->index == sizeof(UPGRADE)-2) {
+ parser->header_state = h_upgrade;
+ }
+ break;
+
+ case h_connection:
+ case h_content_length:
+ case h_transfer_encoding:
+ case h_upgrade:
+ if (ch != ' ') parser->header_state = h_general;
+ break;
+
+ default:
+ assert(0 && "Unknown header_state");
+ break;
+ }
+ break;
+ }
+
+ if (ch == ':') {
+ parser->state = s_header_value_start;
+ CALLBACK_DATA(header_field);
+ break;
+ }
+
+ if (ch == CR) {
+ parser->state = s_header_almost_done;
+ CALLBACK_DATA(header_field);
+ break;
+ }
+
+ if (ch == LF) {
+ parser->state = s_header_field_start;
+ CALLBACK_DATA(header_field);
+ break;
+ }
+
+ SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
+ goto error;
+ }
+
+ case s_header_value_start:
+ {
+ if (ch == ' ' || ch == '\t') break;
+
+ MARK(header_value);
+
+ parser->state = s_header_value;
+ parser->index = 0;
+
+ if (ch == CR) {
+ parser->header_state = h_general;
+ parser->state = s_header_almost_done;
+ CALLBACK_DATA(header_value);
+ break;
+ }
+
+ if (ch == LF) {
+ parser->state = s_header_field_start;
+ CALLBACK_DATA(header_value);
+ break;
+ }
+
+ c = LOWER(ch);
+
+ switch (parser->header_state) {
+ case h_upgrade:
+ parser->flags |= F_UPGRADE;
+ parser->header_state = h_general;
+ break;
+
+ case h_transfer_encoding:
+ /* looking for 'Transfer-Encoding: chunked' */
+ if ('c' == c) {
+ parser->header_state = h_matching_transfer_encoding_chunked;
+ } else {
+ parser->header_state = h_general;
+ }
+ break;
+
+ case h_content_length:
+ if (!IS_NUM(ch)) {
+ SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+ goto error;
+ }
+
+ parser->content_length = ch - '0';
+ break;
+
+ case h_connection:
+ /* looking for 'Connection: keep-alive' */
+ if (c == 'k') {
+ parser->header_state = h_matching_connection_keep_alive;
+ /* looking for 'Connection: close' */
+ } else if (c == 'c') {
+ parser->header_state = h_matching_connection_close;
+ } else {
+ parser->header_state = h_general;
+ }
+ break;
+
+ default:
+ parser->header_state = h_general;
+ break;
+ }
+ break;
+ }
+
+ case s_header_value:
+ {
+
+ if (ch == CR) {
+ parser->state = s_header_almost_done;
+ CALLBACK_DATA(header_value);
+ break;
+ }
+
+ if (ch == LF) {
+ parser->state = s_header_almost_done;
+ CALLBACK_DATA_NOADVANCE(header_value);
+ goto reexecute_byte;
+ }
+
+ c = LOWER(ch);
+
+ switch (parser->header_state) {
+ case h_general:
+ break;
+
+ case h_connection:
+ case h_transfer_encoding:
+ assert(0 && "Shouldn't get here.");
+ break;
+
+ case h_content_length:
+ {
+ uint64_t t;
+
+ if (ch == ' ') break;
+
+ if (!IS_NUM(ch)) {
+ SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+ goto error;
+ }
+
+ t = parser->content_length;
+ t *= 10;
+ t += ch - '0';
+
+ /* Overflow? */
+ if (t < parser->content_length || t == ULLONG_MAX) {
+ SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+ goto error;
+ }
+
+ parser->content_length = t;
+ break;
+ }
+
+ /* Transfer-Encoding: chunked */
+ case h_matching_transfer_encoding_chunked:
+ parser->index++;
+ if (parser->index > sizeof(CHUNKED)-1
+ || c != CHUNKED[parser->index]) {
+ parser->header_state = h_general;
+ } else if (parser->index == sizeof(CHUNKED)-2) {
+ parser->header_state = h_transfer_encoding_chunked;
+ }
+ break;
+
+ /* looking for 'Connection: keep-alive' */
+ case h_matching_connection_keep_alive:
+ parser->index++;
+ if (parser->index > sizeof(KEEP_ALIVE)-1
+ || c != KEEP_ALIVE[parser->index]) {
+ parser->header_state = h_general;
+ } else if (parser->index == sizeof(KEEP_ALIVE)-2) {
+ parser->header_state = h_connection_keep_alive;
+ }
+ break;
+
+ /* looking for 'Connection: close' */
+ case h_matching_connection_close:
+ parser->index++;
+ if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) {
+ parser->header_state = h_general;
+ } else if (parser->index == sizeof(CLOSE)-2) {
+ parser->header_state = h_connection_close;
+ }
+ break;
+
+ case h_transfer_encoding_chunked:
+ case h_connection_keep_alive:
+ case h_connection_close:
+ if (ch != ' ') parser->header_state = h_general;
+ break;
+
+ default:
+ parser->state = s_header_value;
+ parser->header_state = h_general;
+ break;
+ }
+ break;
+ }
+
+ case s_header_almost_done:
+ {
+ STRICT_CHECK(ch != LF);
+
+ parser->state = s_header_value_lws;
+
+ switch (parser->header_state) {
+ case h_connection_keep_alive:
+ parser->flags |= F_CONNECTION_KEEP_ALIVE;
+ break;
+ case h_connection_close:
+ parser->flags |= F_CONNECTION_CLOSE;
+ break;
+ case h_transfer_encoding_chunked:
+ parser->flags |= F_CHUNKED;
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ case s_header_value_lws:
+ {
+ if (ch == ' ' || ch == '\t')
+ parser->state = s_header_value_start;
+ else
+ {
+ parser->state = s_header_field_start;
+ goto reexecute_byte;
+ }
+ break;
+ }
+
+ case s_headers_almost_done:
+ {
+ STRICT_CHECK(ch != LF);
+
+ if (parser->flags & F_TRAILING) {
+ /* End of a chunked request */
+ parser->state = NEW_MESSAGE();
+ CALLBACK_NOTIFY(message_complete);
+ break;
+ }
+
+ parser->state = s_headers_done;
+
+ /* Set this here so that on_headers_complete() callbacks can see it */
+ parser->upgrade =
+ (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT);
+
+ /* Here we call the headers_complete callback. This is somewhat
+ * different than other callbacks because if the user returns 1, we
+ * will interpret that as saying that this message has no body. This
+ * is needed for the annoying case of recieving a response to a HEAD
+ * request.
+ *
+ * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so
+ * we have to simulate it by handling a change in errno below.
+ */
+ if (settings->on_headers_complete) {
+ switch (settings->on_headers_complete(parser)) {
+ case 0:
+ break;
+
+ case 1:
+ parser->flags |= F_SKIPBODY;
+ break;
+
+ default:
+ SET_ERRNO(HPE_CB_headers_complete);
+ return p - data; /* Error */
+ }
+ }
+
+ if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
+ return p - data;
+ }
+
+ goto reexecute_byte;
+ }
+
+ case s_headers_done:
+ {
+ STRICT_CHECK(ch != LF);
+
+ parser->nread = 0;
+
+ /* Exit, the rest of the connect is in a different protocol. */
+ if (parser->upgrade) {
+ parser->state = NEW_MESSAGE();
+ CALLBACK_NOTIFY(message_complete);
+ return (p - data) + 1;
+ }
+
+ if (parser->flags & F_SKIPBODY) {
+ parser->state = NEW_MESSAGE();
+ CALLBACK_NOTIFY(message_complete);
+ } else if (parser->flags & F_CHUNKED) {
+ /* chunked encoding - ignore Content-Length header */
+ parser->state = s_chunk_size_start;
+ } else {
+ if (parser->content_length == 0) {
+ /* Content-Length header given but zero: Content-Length: 0\r\n */
+ parser->state = NEW_MESSAGE();
+ CALLBACK_NOTIFY(message_complete);
+ } else if (parser->content_length != ULLONG_MAX) {
+ /* Content-Length header given and non-zero */
+ parser->state = s_body_identity;
+ } else {
+ if (parser->type == HTTP_REQUEST ||
+ !http_message_needs_eof(parser)) {
+ /* Assume content-length 0 - read the next */
+ parser->state = NEW_MESSAGE();
+ CALLBACK_NOTIFY(message_complete);
+ } else {
+ /* Read body until EOF */
+ parser->state = s_body_identity_eof;
+ }
+ }
+ }
+
+ break;
+ }
+
+ case s_body_identity:
+ {
+ uint64_t to_read = MIN(parser->content_length,
+ (uint64_t) ((data + len) - p));
+
+ assert(parser->content_length != 0
+ && parser->content_length != ULLONG_MAX);
+
+ /* The difference between advancing content_length and p is because
+ * the latter will automaticaly advance on the next loop iteration.
+ * Further, if content_length ends up at 0, we want to see the last
+ * byte again for our message complete callback.
+ */
+ MARK(body);
+ parser->content_length -= to_read;
+ p += to_read - 1;
+
+ if (parser->content_length == 0) {
+ parser->state = s_message_done;
+
+ /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte.
+ *
+ * The alternative to doing this is to wait for the next byte to
+ * trigger the data callback, just as in every other case. The
+ * problem with this is that this makes it difficult for the test
+ * harness to distinguish between complete-on-EOF and
+ * complete-on-length. It's not clear that this distinction is
+ * important for applications, but let's keep it for now.
+ */
+ CALLBACK_DATA_(body, p - body_mark + 1, p - data);
+ goto reexecute_byte;
+ }
+
+ break;
+ }
+
+ /* read until EOF */
+ case s_body_identity_eof:
+ MARK(body);
+ p = data + len - 1;
+
+ break;
+
+ case s_message_done:
+ parser->state = NEW_MESSAGE();
+ CALLBACK_NOTIFY(message_complete);
+ break;
+
+ case s_chunk_size_start:
+ {
+ assert(parser->nread == 1);
+ assert(parser->flags & F_CHUNKED);
+
+ unhex_val = unhex[(unsigned char)ch];
+ if (unhex_val == -1) {
+ SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
+ goto error;
+ }
+
+ parser->content_length = unhex_val;
+ parser->state = s_chunk_size;
+ break;
+ }
+
+ case s_chunk_size:
+ {
+ uint64_t t;
+
+ assert(parser->flags & F_CHUNKED);
+
+ if (ch == CR) {
+ parser->state = s_chunk_size_almost_done;
+ break;
+ }
+
+ unhex_val = unhex[(unsigned char)ch];
+
+ if (unhex_val == -1) {
+ if (ch == ';' || ch == ' ') {
+ parser->state = s_chunk_parameters;
+ break;
+ }
+
+ SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
+ goto error;
+ }
+
+ t = parser->content_length;
+ t *= 16;
+ t += unhex_val;
+
+ /* Overflow? */
+ if (t < parser->content_length || t == ULLONG_MAX) {
+ SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+ goto error;
+ }
+
+ parser->content_length = t;
+ break;
+ }
+
+ case s_chunk_parameters:
+ {
+ assert(parser->flags & F_CHUNKED);
+ /* just ignore this shit. TODO check for overflow */
+ if (ch == CR) {
+ parser->state = s_chunk_size_almost_done;
+ break;
+ }
+ break;
+ }
+
+ case s_chunk_size_almost_done:
+ {
+ assert(parser->flags & F_CHUNKED);
+ STRICT_CHECK(ch != LF);
+
+ parser->nread = 0;
+
+ if (parser->content_length == 0) {
+ parser->flags |= F_TRAILING;
+ parser->state = s_header_field_start;
+ } else {
+ parser->state = s_chunk_data;
+ }
+ break;
+ }
+
+ case s_chunk_data:
+ {
+ uint64_t to_read = MIN(parser->content_length,
+ (uint64_t) ((data + len) - p));
+
+ assert(parser->flags & F_CHUNKED);
+ assert(parser->content_length != 0
+ && parser->content_length != ULLONG_MAX);
+
+ /* See the explanation in s_body_identity for why the content
+ * length and data pointers are managed this way.
+ */
+ MARK(body);
+ parser->content_length -= to_read;
+ p += to_read - 1;
+
+ if (parser->content_length == 0) {
+ parser->state = s_chunk_data_almost_done;
+ }
+
+ break;
+ }
+
+ case s_chunk_data_almost_done:
+ assert(parser->flags & F_CHUNKED);
+ assert(parser->content_length == 0);
+ STRICT_CHECK(ch != CR);
+ parser->state = s_chunk_data_done;
+ CALLBACK_DATA(body);
+ break;
+
+ case s_chunk_data_done:
+ assert(parser->flags & F_CHUNKED);
+ STRICT_CHECK(ch != LF);
+ parser->nread = 0;
+ parser->state = s_chunk_size_start;
+ break;
+
+ default:
+ assert(0 && "unhandled state");
+ SET_ERRNO(HPE_INVALID_INTERNAL_STATE);
+ goto error;
+ }
+ }
+
+ /* Run callbacks for any marks that we have leftover after we ran our of
+ * bytes. There should be at most one of these set, so it's OK to invoke
+ * them in series (unset marks will not result in callbacks).
+ *
+ * We use the NOADVANCE() variety of callbacks here because 'p' has already
+ * overflowed 'data' and this allows us to correct for the off-by-one that
+ * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p'
+ * value that's in-bounds).
+ */
+
+ assert(((header_field_mark ? 1 : 0) +
+ (header_value_mark ? 1 : 0) +
+ (url_mark ? 1 : 0) +
+ (body_mark ? 1 : 0)) <= 1);
+
+ CALLBACK_DATA_NOADVANCE(header_field);
+ CALLBACK_DATA_NOADVANCE(header_value);
+ CALLBACK_DATA_NOADVANCE(url);
+ CALLBACK_DATA_NOADVANCE(body);
+
+ return len;
+
+error:
+ if (HTTP_PARSER_ERRNO(parser) == HPE_OK) {
+ SET_ERRNO(HPE_UNKNOWN);
+ }
+
+ return (p - data);
+}
+
+
+/* Does the parser need to see an EOF to find the end of the message? */
+int
+http_message_needs_eof (http_parser *parser)
+{
+ if (parser->type == HTTP_REQUEST) {
+ return 0;
+ }
+
+ /* See RFC 2616 section 4.4 */
+ if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
+ parser->status_code == 204 || /* No Content */
+ parser->status_code == 304 || /* Not Modified */
+ parser->flags & F_SKIPBODY) { /* response to a HEAD request */
+ return 0;
+ }
+
+ if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+int
+http_should_keep_alive (http_parser *parser)
+{
+ if (parser->http_major > 0 && parser->http_minor > 0) {
+ /* HTTP/1.1 */
+ if (parser->flags & F_CONNECTION_CLOSE) {
+ return 0;
+ }
+ } else {
+ /* HTTP/1.0 or earlier */
+ if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) {
+ return 0;
+ }
+ }
+
+ return !http_message_needs_eof(parser);
+}
+
+
+const char * http_method_str (enum http_method m)
+{
+ return method_strings[m];
+}
+
+
+void
+http_parser_init (http_parser *parser, enum http_parser_type t)
+{
+ void *data = parser->data; /* preserve application data */
+ memset(parser, 0, sizeof(*parser));
+ parser->data = data;
+ parser->type = t;
+ parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res));
+ parser->http_errno = HPE_OK;
+}
+
+const char *
+http_errno_name(enum http_errno err) {
+ assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0])));
+ return http_strerror_tab[err].name;
+}
+
+const char *
+http_errno_description(enum http_errno err) {
+ assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0])));
+ return http_strerror_tab[err].description;
+}
+
+int
+http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
+ struct http_parser_url *u)
+{
+ enum state s;
+ const char *p;
+ enum http_parser_url_fields uf, old_uf;
+
+ u->port = u->field_set = 0;
+ s = is_connect ? s_req_host_start : s_req_spaces_before_url;
+ uf = old_uf = UF_MAX;
+
+ for (p = buf; p < buf + buflen; p++) {
+ s = parse_url_char(s, *p);
+
+ /* Figure out the next field that we're operating on */
+ switch (s) {
+ case s_dead:
+ return 1;
+
+ /* Skip delimeters */
+ case s_req_schema_slash:
+ case s_req_schema_slash_slash:
+ case s_req_host_start:
+ case s_req_host_v6_start:
+ case s_req_host_v6_end:
+ case s_req_port_start:
+ case s_req_query_string_start:
+ case s_req_fragment_start:
+ continue;
+
+ case s_req_schema:
+ uf = UF_SCHEMA;
+ break;
+
+ case s_req_host:
+ case s_req_host_v6:
+ uf = UF_HOST;
+ break;
+
+ case s_req_port:
+ uf = UF_PORT;
+ break;
+
+ case s_req_path:
+ uf = UF_PATH;
+ break;
+
+ case s_req_query_string:
+ uf = UF_QUERY;
+ break;
+
+ case s_req_fragment:
+ uf = UF_FRAGMENT;
+ break;
+
+ default:
+ assert(!"Unexpected state");
+ return 1;
+ }
+
+ /* Nothing's changed; soldier on */
+ if (uf == old_uf) {
+ u->field_data[uf].len++;
+ continue;
+ }
+
+ u->field_data[uf].off = p - buf;
+ u->field_data[uf].len = 1;
+
+ u->field_set |= (1 << uf);
+ old_uf = uf;
+ }
+
+ /* CONNECT requests can only contain "hostname:port" */
+ if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) {
+ return 1;
+ }
+
+ /* Make sure we don't end somewhere unexpected */
+ switch (s) {
+ case s_req_host_v6_start:
+ case s_req_host_v6:
+ case s_req_host_v6_end:
+ case s_req_host:
+ case s_req_port_start:
+ return 1;
+ default:
+ break;
+ }
+
+ if (u->field_set & (1 << UF_PORT)) {
+ /* Don't bother with endp; we've already validated the string */
+ unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10);
+
+ /* Ports have a max value of 2^16 */
+ if (v > 0xffff) {
+ return 1;
+ }
+
+ u->port = (uint16_t) v;
+ }
+
+ return 0;
+}
+
+void
+http_parser_pause(http_parser *parser, int paused) {
+ /* Users should only be pausing/unpausing a parser that is not in an error
+ * state. In non-debug builds, there's not much that we can do about this
+ * other than ignore it.
+ */
+ if (HTTP_PARSER_ERRNO(parser) == HPE_OK ||
+ HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) {
+ SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK);
+ } else {
+ assert(0 && "Attempting to pause parser in error state");
+ }
+}
diff --git a/tools/wrk/src/http_parser.h b/tools/wrk/src/http_parser.h
new file mode 100644
index 000000000..ae62661a7
--- /dev/null
+++ b/tools/wrk/src/http_parser.h
@@ -0,0 +1,317 @@
+/* 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.
+ */
+#ifndef http_parser_h
+#define http_parser_h
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HTTP_PARSER_VERSION_MAJOR 1
+#define HTTP_PARSER_VERSION_MINOR 0
+
+#include <sys/types.h>
+#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600)
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+typedef unsigned int size_t;
+typedef int ssize_t;
+#else
+#include <stdint.h>
+#endif
+
+/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
+ * faster
+ */
+#ifndef HTTP_PARSER_STRICT
+# define HTTP_PARSER_STRICT 1
+#endif
+
+/* Compile with -DHTTP_PARSER_DEBUG=1 to add extra debugging information to
+ * the error reporting facility.
+ */
+#ifndef HTTP_PARSER_DEBUG
+# define HTTP_PARSER_DEBUG 0
+#endif
+
+
+/* Maximium header size allowed */
+#define HTTP_MAX_HEADER_SIZE (80*1024)
+
+
+typedef struct http_parser http_parser;
+typedef struct http_parser_settings http_parser_settings;
+
+
+/* Callbacks should return non-zero to indicate an error. The parser will
+ * then halt execution.
+ *
+ * The one exception is on_headers_complete. In a HTTP_RESPONSE parser
+ * returning '1' from on_headers_complete will tell the parser that it
+ * should not expect a body. This is used when receiving a response to a
+ * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
+ * chunked' headers that indicate the presence of a body.
+ *
+ * http_data_cb does not return data chunks. It will be call arbitrarally
+ * many times for each string. E.G. you might get 10 callbacks for "on_path"
+ * each providing just a few characters more data.
+ */
+typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
+typedef int (*http_cb) (http_parser*);
+
+
+/* Request Methods */
+#define HTTP_METHOD_MAP(XX) \
+ XX(0, DELETE) \
+ XX(1, GET) \
+ XX(2, HEAD) \
+ XX(3, POST) \
+ XX(4, PUT) \
+ /* pathological */ \
+ XX(5, CONNECT) \
+ XX(6, OPTIONS) \
+ XX(7, TRACE) \
+ /* webdav */ \
+ XX(8, COPY) \
+ XX(9, LOCK) \
+ XX(10, MKCOL) \
+ XX(11, MOVE) \
+ XX(12, PROPFIND) \
+ XX(13, PROPPATCH) \
+ XX(14, UNLOCK) \
+ /* subversion */ \
+ XX(15, REPORT) \
+ XX(16, MKACTIVITY) \
+ XX(17, CHECKOUT) \
+ XX(18, MERGE) \
+ /* upnp */ \
+ XX(19, MSEARCH) \
+ XX(20, NOTIFY) \
+ XX(21, SUBSCRIBE) \
+ XX(22, UNSUBSCRIBE) \
+ /* RFC-5789 */ \
+ XX(23, PATCH) \
+ XX(24, PURGE) \
+
+enum http_method
+ {
+#define XX(num, name) HTTP_##name = num,
+ HTTP_METHOD_MAP(XX)
+#undef X
+ };
+
+
+enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
+
+
+/* Flag values for http_parser.flags field */
+enum flags
+ { F_CHUNKED = 1 << 0
+ , F_CONNECTION_KEEP_ALIVE = 1 << 1
+ , F_CONNECTION_CLOSE = 1 << 2
+ , F_TRAILING = 1 << 3
+ , F_UPGRADE = 1 << 4
+ , F_SKIPBODY = 1 << 5
+ };
+
+
+/* Map for errno-related constants
+ *
+ * The provided argument should be a macro that takes 2 arguments.
+ */
+#define HTTP_ERRNO_MAP(XX) \
+ /* No error */ \
+ XX(OK, "success") \
+ \
+ /* Callback-related errors */ \
+ XX(CB_message_begin, "the on_message_begin callback failed") \
+ XX(CB_url, "the on_url callback failed") \
+ XX(CB_header_field, "the on_header_field callback failed") \
+ XX(CB_header_value, "the on_header_value callback failed") \
+ XX(CB_headers_complete, "the on_headers_complete callback failed") \
+ XX(CB_body, "the on_body callback failed") \
+ XX(CB_message_complete, "the on_message_complete callback failed") \
+ \
+ /* Parsing-related errors */ \
+ XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
+ XX(HEADER_OVERFLOW, \
+ "too many header bytes seen; overflow detected") \
+ XX(CLOSED_CONNECTION, \
+ "data received after completed connection: close message") \
+ XX(INVALID_VERSION, "invalid HTTP version") \
+ XX(INVALID_STATUS, "invalid HTTP status code") \
+ XX(INVALID_METHOD, "invalid HTTP method") \
+ XX(INVALID_URL, "invalid URL") \
+ XX(INVALID_HOST, "invalid host") \
+ XX(INVALID_PORT, "invalid port") \
+ XX(INVALID_PATH, "invalid path") \
+ XX(INVALID_QUERY_STRING, "invalid query string") \
+ XX(INVALID_FRAGMENT, "invalid fragment") \
+ XX(LF_EXPECTED, "LF character expected") \
+ XX(INVALID_HEADER_TOKEN, "invalid character in header") \
+ XX(INVALID_CONTENT_LENGTH, \
+ "invalid character in content-length header") \
+ XX(INVALID_CHUNK_SIZE, \
+ "invalid character in chunk size header") \
+ XX(INVALID_CONSTANT, "invalid constant string") \
+ XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
+ XX(STRICT, "strict mode assertion failed") \
+ XX(PAUSED, "parser is paused") \
+ XX(UNKNOWN, "an unknown error occurred")
+
+
+/* Define HPE_* values for each errno value above */
+#define HTTP_ERRNO_GEN(n, s) HPE_##n,
+enum http_errno {
+ HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
+};
+#undef HTTP_ERRNO_GEN
+
+
+/* Get an http_errno value from an http_parser */
+#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
+
+/* Get the line number that generated the current error */
+#if HTTP_PARSER_DEBUG
+#define HTTP_PARSER_ERRNO_LINE(p) ((p)->error_lineno)
+#else
+#define HTTP_PARSER_ERRNO_LINE(p) 0
+#endif
+
+
+struct http_parser {
+ /** PRIVATE **/
+ unsigned char type : 2; /* enum http_parser_type */
+ unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */
+ unsigned char state; /* enum state from http_parser.c */
+ unsigned char header_state; /* enum header_state from http_parser.c */
+ unsigned char index; /* index into current matcher */
+
+ uint32_t nread; /* # bytes read in various scenarios */
+ uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
+
+ /** READ-ONLY **/
+ unsigned short http_major;
+ unsigned short http_minor;
+ unsigned short status_code; /* responses only */
+ unsigned char method; /* requests only */
+ unsigned char http_errno : 7;
+
+ /* 1 = Upgrade header was present and the parser has exited because of that.
+ * 0 = No upgrade header present.
+ * Should be checked when http_parser_execute() returns in addition to
+ * error checking.
+ */
+ unsigned char upgrade : 1;
+
+#if HTTP_PARSER_DEBUG
+ uint32_t error_lineno;
+#endif
+
+ /** PUBLIC **/
+ void *data; /* A pointer to get hook to the "connection" or "socket" object */
+};
+
+
+struct http_parser_settings {
+ http_cb on_message_begin;
+ http_data_cb on_url;
+ http_data_cb on_header_field;
+ http_data_cb on_header_value;
+ http_cb on_headers_complete;
+ http_data_cb on_body;
+ http_cb on_message_complete;
+};
+
+
+enum http_parser_url_fields
+ { UF_SCHEMA = 0
+ , UF_HOST = 1
+ , UF_PORT = 2
+ , UF_PATH = 3
+ , UF_QUERY = 4
+ , UF_FRAGMENT = 5
+ , UF_MAX = 6
+ };
+
+
+/* Result structure for http_parser_parse_url().
+ *
+ * Callers should index into field_data[] with UF_* values iff field_set
+ * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
+ * because we probably have padding left over), we convert any port to
+ * a uint16_t.
+ */
+struct http_parser_url {
+ uint16_t field_set; /* Bitmask of (1 << UF_*) values */
+ uint16_t port; /* Converted UF_PORT string */
+
+ struct {
+ uint16_t off; /* Offset into buffer in which field starts */
+ uint16_t len; /* Length of run in buffer */
+ } field_data[UF_MAX];
+};
+
+
+void http_parser_init(http_parser *parser, enum http_parser_type type);
+
+
+size_t http_parser_execute(http_parser *parser,
+ const http_parser_settings *settings,
+ const char *data,
+ size_t len);
+
+
+/* If http_should_keep_alive() in the on_headers_complete or
+ * on_message_complete callback returns true, then this will be should be
+ * the last message on the connection.
+ * If you are the server, respond with the "Connection: close" header.
+ * If you are the client, close the connection.
+ */
+int http_should_keep_alive(http_parser *parser);
+
+/* Returns a string version of the HTTP method. */
+const char *http_method_str(enum http_method m);
+
+/* Return a string name of the given error */
+const char *http_errno_name(enum http_errno err);
+
+/* Return a string description of the given error */
+const char *http_errno_description(enum http_errno err);
+
+/* Parse a URL; return nonzero on failure */
+int http_parser_parse_url(const char *buf, size_t buflen,
+ int is_connect,
+ struct http_parser_url *u);
+
+/* Pause or un-pause the parser; a nonzero value pauses */
+void http_parser_pause(http_parser *parser, int paused);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tools/wrk/src/stats.c b/tools/wrk/src/stats.c
new file mode 100644
index 000000000..a114917bf
--- /dev/null
+++ b/tools/wrk/src/stats.c
@@ -0,0 +1,73 @@
+// Copyright (C) 2012 - Will Glozer. All rights reserved.
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "stats.h"
+#include "zmalloc.h"
+
+stats *stats_alloc(uint64_t samples) {
+ stats *stats = zcalloc(sizeof(stats) + sizeof(uint64_t) * samples);
+ stats->samples = samples;
+ return stats;
+}
+
+void stats_free(stats *stats) {
+ zfree(stats);
+}
+
+void stats_record(stats *stats, uint64_t x) {
+ stats->data[stats->index++] = x;
+ if (stats->limit < stats->samples) stats->limit++;
+ if (stats->index == stats->samples) stats->index = 0;
+}
+
+uint64_t stats_min(stats *stats) {
+ uint64_t min = 0;
+ for (uint64_t i = 0; i < stats->limit; i++) {
+ uint64_t x = stats->data[i];
+ if (x < min || min == 0) min = x;
+ }
+ return min;
+}
+
+uint64_t stats_max(stats *stats) {
+ uint64_t max = 0;
+ for (uint64_t i = 0; i < stats->limit; i++) {
+ uint64_t x = stats->data[i];
+ if (x > max || max == 0) max = x;
+ }
+ return max;
+}
+
+long double stats_mean(stats *stats) {
+ uint64_t sum = 0;
+ if (stats->limit == 0) return 0.0;
+ for (uint64_t i = 0; i < stats->limit; i++) {
+ sum += stats->data[i];
+ }
+ return sum / (long double) stats->limit;
+}
+
+long double stats_stdev(stats *stats, long double mean) {
+ long double sum = 0.0;
+ if (stats->limit < 2) return 0.0;
+ for (uint64_t i = 0; i < stats->limit; i++) {
+ sum += powl(stats->data[i] - mean, 2);
+ }
+ return sqrtl(sum / (stats->limit - 1));
+}
+
+long double stats_within_stdev(stats *stats, long double mean, long double stdev, uint64_t n) {
+ long double upper = mean + (stdev * n);
+ long double lower = mean - (stdev * n);
+ uint64_t sum = 0;
+
+ for (uint64_t i = 0; i < stats->limit; i++) {
+ uint64_t x = stats->data[i];
+ if (x >= lower && x <= upper) sum++;
+ }
+
+ return (sum / (long double) stats->limit) * 100;
+}
diff --git a/tools/wrk/src/stats.h b/tools/wrk/src/stats.h
new file mode 100644
index 000000000..04a939313
--- /dev/null
+++ b/tools/wrk/src/stats.h
@@ -0,0 +1,21 @@
+#ifndef STATS_H
+#define STATS_H
+
+typedef struct {
+ uint64_t samples;
+ uint64_t index;
+ uint64_t limit;
+ uint64_t data[];
+} stats;
+
+stats *stats_alloc(uint64_t);
+void stats_free(stats *);
+void stats_record(stats *, uint64_t);
+uint64_t stats_min(stats *);
+uint64_t stats_max(stats *);
+long double stats_mean(stats *);
+long double stats_stdev(stats *stats, long double);
+long double stats_within_stdev(stats *, long double, long double, uint64_t);
+
+#endif /* STATS_H */
+
diff --git a/tools/wrk/src/tinymt64.c b/tools/wrk/src/tinymt64.c
new file mode 100644
index 000000000..fa5a06c1e
--- /dev/null
+++ b/tools/wrk/src/tinymt64.c
@@ -0,0 +1,129 @@
+/**
+ * @file tinymt64.c
+ *
+ * @brief 64-bit Tiny Mersenne Twister only 127 bit internal state
+ *
+ * @author Mutsuo Saito (Hiroshima University)
+ * @author Makoto Matsumoto (The University of Tokyo)
+ *
+ * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto,
+ * Hiroshima University and The University of Tokyo.
+ * All rights reserved.
+ *
+ * The 3-clause BSD License is applied to this software, see
+ * LICENSE.txt
+ */
+#include "tinymt64.h"
+
+#define MIN_LOOP 8
+
+/**
+ * This function represents a function used in the initialization
+ * by init_by_array
+ * @param[in] x 64-bit integer
+ * @return 64-bit integer
+ */
+static uint64_t ini_func1(uint64_t x) {
+ return (x ^ (x >> 59)) * UINT64_C(2173292883993);
+}
+
+/**
+ * This function represents a function used in the initialization
+ * by init_by_array
+ * @param[in] x 64-bit integer
+ * @return 64-bit integer
+ */
+static uint64_t ini_func2(uint64_t x) {
+ return (x ^ (x >> 59)) * UINT64_C(58885565329898161);
+}
+
+/**
+ * This function certificate the period of 2^127-1.
+ * @param random tinymt state vector.
+ */
+static void period_certification(tinymt64_t * random) {
+ if ((random->status[0] & TINYMT64_MASK) == 0 &&
+ random->status[1] == 0) {
+ random->status[0] = 'T';
+ random->status[1] = 'M';
+ }
+}
+
+/**
+ * This function initializes the internal state array with a 64-bit
+ * unsigned integer seed.
+ * @param random tinymt state vector.
+ * @param seed a 64-bit unsigned integer used as a seed.
+ */
+void tinymt64_init(tinymt64_t * random, uint64_t seed) {
+ random->status[0] = seed ^ ((uint64_t)random->mat1 << 32);
+ random->status[1] = random->mat2 ^ random->tmat;
+ for (int i = 1; i < MIN_LOOP; i++) {
+ random->status[i & 1] ^= i + UINT64_C(6364136223846793005)
+ * (random->status[(i - 1) & 1]
+ ^ (random->status[(i - 1) & 1] >> 62));
+ }
+ period_certification(random);
+}
+
+/**
+ * This function initializes the internal state array,
+ * with an array of 64-bit unsigned integers used as seeds
+ * @param random tinymt state vector.
+ * @param init_key the array of 64-bit integers, used as a seed.
+ * @param key_length the length of init_key.
+ */
+void tinymt64_init_by_array(tinymt64_t * random, const uint64_t init_key[],
+ int key_length) {
+ const int lag = 1;
+ const int mid = 1;
+ const int size = 4;
+ int i, j;
+ int count;
+ uint64_t r;
+ uint64_t st[4];
+
+ st[0] = 0;
+ st[1] = random->mat1;
+ st[2] = random->mat2;
+ st[3] = random->tmat;
+ if (key_length + 1 > MIN_LOOP) {
+ count = key_length + 1;
+ } else {
+ count = MIN_LOOP;
+ }
+ r = ini_func1(st[0] ^ st[mid % size]
+ ^ st[(size - 1) % size]);
+ st[mid % size] += r;
+ r += key_length;
+ st[(mid + lag) % size] += r;
+ st[0] = r;
+ count--;
+ for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
+ r = ini_func1(st[i] ^ st[(i + mid) % size] ^ st[(i + size - 1) % size]);
+ st[(i + mid) % size] += r;
+ r += init_key[j] + i;
+ st[(i + mid + lag) % size] += r;
+ st[i] = r;
+ i = (i + 1) % size;
+ }
+ for (; j < count; j++) {
+ r = ini_func1(st[i] ^ st[(i + mid) % size] ^ st[(i + size - 1) % size]);
+ st[(i + mid) % size] += r;
+ r += i;
+ st[(i + mid + lag) % size] += r;
+ st[i] = r;
+ i = (i + 1) % size;
+ }
+ for (j = 0; j < size; j++) {
+ r = ini_func2(st[i] + st[(i + mid) % size] + st[(i + size - 1) % size]);
+ st[(i + mid) % size] ^= r;
+ r -= i;
+ st[(i + mid + lag) % size] ^= r;
+ st[i] = r;
+ i = (i + 1) % size;
+ }
+ random->status[0] = st[0] ^ st[1];
+ random->status[1] = st[2] ^ st[3];
+ period_certification(random);
+}
diff --git a/tools/wrk/src/tinymt64.h b/tools/wrk/src/tinymt64.h
new file mode 100644
index 000000000..015afff32
--- /dev/null
+++ b/tools/wrk/src/tinymt64.h
@@ -0,0 +1,210 @@
+#ifndef TINYMT64_H
+#define TINYMT64_H
+/**
+ * @file tinymt64.h
+ *
+ * @brief Tiny Mersenne Twister only 127 bit internal state
+ *
+ * @author Mutsuo Saito (Hiroshima University)
+ * @author Makoto Matsumoto (The University of Tokyo)
+ *
+ * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto,
+ * Hiroshima University and The University of Tokyo.
+ * All rights reserved.
+ *
+ * The 3-clause BSD License is applied to this software, see
+ * LICENSE.txt
+ */
+
+#include <stdint.h>
+#include <inttypes.h>
+
+#define TINYMT64_MEXP 127
+#define TINYMT64_SH0 12
+#define TINYMT64_SH1 11
+#define TINYMT64_SH8 8
+#define TINYMT64_MASK UINT64_C(0x7fffffffffffffff)
+#define TINYMT64_MUL (1.0 / 18446744073709551616.0)
+
+/*
+ * tinymt64 internal state vector and parameters
+ */
+struct TINYMT64_T {
+ uint64_t status[2];
+ uint32_t mat1;
+ uint32_t mat2;
+ uint64_t tmat;
+};
+
+typedef struct TINYMT64_T tinymt64_t;
+
+void tinymt64_init(tinymt64_t * random, uint64_t seed);
+void tinymt64_init_by_array(tinymt64_t * random, const uint64_t init_key[],
+ int key_length);
+
+#if defined(__GNUC__)
+/**
+ * This function always returns 127
+ * @param random not used
+ * @return always 127
+ */
+inline static int tinymt64_get_mexp(
+ tinymt64_t * random __attribute__((unused))) {
+ return TINYMT64_MEXP;
+}
+#else
+inline static int tinymt64_get_mexp(tinymt64_t * random) {
+ return TINYMT64_MEXP;
+}
+#endif
+
+/**
+ * This function changes internal state of tinymt64.
+ * Users should not call this function directly.
+ * @param random tinymt internal status
+ */
+inline static void tinymt64_next_state(tinymt64_t * random) {
+ uint64_t x;
+
+ random->status[0] &= TINYMT64_MASK;
+ x = random->status[0] ^ random->status[1];
+ x ^= x << TINYMT64_SH0;
+ x ^= x >> 32;
+ x ^= x << 32;
+ x ^= x << TINYMT64_SH1;
+ random->status[0] = random->status[1];
+ random->status[1] = x;
+ random->status[0] ^= -((int64_t)(x & 1)) & random->mat1;
+ random->status[1] ^= -((int64_t)(x & 1)) & (((uint64_t)random->mat2) << 32);
+}
+
+/**
+ * This function outputs 64-bit unsigned integer from internal state.
+ * Users should not call this function directly.
+ * @param random tinymt internal status
+ * @return 64-bit unsigned pseudorandom number
+ */
+inline static uint64_t tinymt64_temper(tinymt64_t * random) {
+ uint64_t x;
+#if defined(LINEARITY_CHECK)
+ x = random->status[0] ^ random->status[1];
+#else
+ x = random->status[0] + random->status[1];
+#endif
+ x ^= random->status[0] >> TINYMT64_SH8;
+ x ^= -((int64_t)(x & 1)) & random->tmat;
+ return x;
+}
+
+/**
+ * This function outputs floating point number from internal state.
+ * Users should not call this function directly.
+ * @param random tinymt internal status
+ * @return floating point number r (1.0 <= r < 2.0)
+ */
+inline static double tinymt64_temper_conv(tinymt64_t * random) {
+ uint64_t x;
+ union {
+ uint64_t u;
+ double d;
+ } conv;
+#if defined(LINEARITY_CHECK)
+ x = random->status[0] ^ random->status[1];
+#else
+ x = random->status[0] + random->status[1];
+#endif
+ x ^= random->status[0] >> TINYMT64_SH8;
+ conv.u = ((x ^ (-((int64_t)(x & 1)) & random->tmat)) >> 12)
+ | UINT64_C(0x3ff0000000000000);
+ return conv.d;
+}
+
+/**
+ * This function outputs floating point number from internal state.
+ * Users should not call this function directly.
+ * @param random tinymt internal status
+ * @return floating point number r (1.0 < r < 2.0)
+ */
+inline static double tinymt64_temper_conv_open(tinymt64_t * random) {
+ uint64_t x;
+ union {
+ uint64_t u;
+ double d;
+ } conv;
+#if defined(LINEARITY_CHECK)
+ x = random->status[0] ^ random->status[1];
+#else
+ x = random->status[0] + random->status[1];
+#endif
+ x ^= random->status[0] >> TINYMT64_SH8;
+ conv.u = ((x ^ (-((int64_t)(x & 1)) & random->tmat)) >> 12)
+ | UINT64_C(0x3ff0000000000001);
+ return conv.d;
+}
+
+/**
+ * This function outputs 64-bit unsigned integer from internal state.
+ * @param random tinymt internal status
+ * @return 64-bit unsigned integer r (0 <= r < 2^64)
+ */
+inline static uint64_t tinymt64_generate_uint64(tinymt64_t * random) {
+ tinymt64_next_state(random);
+ return tinymt64_temper(random);
+}
+
+/**
+ * This function outputs floating point number from internal state.
+ * This function is implemented using multiplying by 1 / 2^64.
+ * @param random tinymt internal status
+ * @return floating point number r (0.0 <= r < 1.0)
+ */
+inline static double tinymt64_generate_double(tinymt64_t * random) {
+ tinymt64_next_state(random);
+ return tinymt64_temper(random) * TINYMT64_MUL;
+}
+
+/**
+ * This function outputs floating point number from internal state.
+ * This function is implemented using union trick.
+ * @param random tinymt internal status
+ * @return floating point number r (0.0 <= r < 1.0)
+ */
+inline static double tinymt64_generate_double01(tinymt64_t * random) {
+ tinymt64_next_state(random);
+ return tinymt64_temper_conv(random) - 1.0;
+}
+
+/**
+ * This function outputs floating point number from internal state.
+ * This function is implemented using union trick.
+ * @param random tinymt internal status
+ * @return floating point number r (1.0 <= r < 2.0)
+ */
+inline static double tinymt64_generate_double12(tinymt64_t * random) {
+ tinymt64_next_state(random);
+ return tinymt64_temper_conv(random);
+}
+
+/**
+ * This function outputs floating point number from internal state.
+ * This function is implemented using union trick.
+ * @param random tinymt internal status
+ * @return floating point number r (0.0 < r <= 1.0)
+ */
+inline static double tinymt64_generate_doubleOC(tinymt64_t * random) {
+ tinymt64_next_state(random);
+ return 2.0 - tinymt64_temper_conv(random);
+}
+
+/**
+ * This function outputs floating point number from internal state.
+ * This function is implemented using union trick.
+ * @param random tinymt internal status
+ * @return floating point number r (0.0 < r < 1.0)
+ */
+inline static double tinymt64_generate_doubleOO(tinymt64_t * random) {
+ tinymt64_next_state(random);
+ return tinymt64_temper_conv_open(random) - 1.0;
+}
+
+#endif
diff --git a/tools/wrk/src/units.c b/tools/wrk/src/units.c
new file mode 100644
index 000000000..b9fc3c0fd
--- /dev/null
+++ b/tools/wrk/src/units.c
@@ -0,0 +1,96 @@
+// Copyright (C) 2012 - Will Glozer. All rights reserved.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <inttypes.h>
+
+#include "units.h"
+#include "aprintf.h"
+
+typedef struct {
+ int scale;
+ char *base;
+ char *units[];
+} units;
+
+units time_units_us = {
+ .scale = 1000,
+ .base = "us",
+ .units = { "ms", "s", NULL }
+};
+
+units time_units_s = {
+ .scale = 60,
+ .base = "s",
+ .units = { "m", "h", NULL }
+};
+
+units binary_units = {
+ .scale = 1024,
+ .base = "",
+ .units = { "K", "M", "G", "T", "P", NULL }
+};
+
+units metric_units = {
+ .scale = 1000,
+ .base = "",
+ .units = { "k", "M", "G", "T", "P", NULL }
+};
+
+static char *format_units(long double n, units *m, int p) {
+ long double amt = n, scale;
+ char *unit = m->base;
+ char *msg = NULL;
+
+ scale = m->scale * 0.85;
+
+ for (int i = 0; m->units[i+1] && amt >= scale; i++) {
+ amt /= m->scale;
+ unit = m->units[i];
+ }
+
+ aprintf(&msg, "%.*Lf%s", p, amt, unit);
+
+ return msg;
+}
+
+static int scan_units(char *s, uint64_t *n, units *m) {
+ uint64_t base, scale = 1;
+ char unit[3] = { 0, 0, 0 };
+ int i, c;
+
+ if ((c = sscanf(s, "%"SCNu64"%2s", &base, unit)) < 1) return -1;
+
+ if (c == 2) {
+ for (i = 0; m->units[i] != NULL; i++) {
+ scale *= m->scale;
+ if (!strncasecmp(unit, m->units[i], sizeof(unit))) break;
+ }
+ if (m->units[i] == NULL) return -1;
+ }
+
+ *n = base * scale;
+ return 0;
+}
+
+char *format_binary(long double n) {
+ return format_units(n, &binary_units, 2);
+}
+
+char *format_metric(long double n) {
+ return format_units(n, &metric_units, 2);
+}
+
+char *format_time_us(long double n) {
+ units *units = &time_units_us;
+ if (n >= 1000000.0) {
+ n /= 1000000.0;
+ units = &time_units_s;
+ }
+ return format_units(n, units, 2);
+}
+
+int scan_metric(char *s, uint64_t *n) {
+ return scan_units(s, n, &metric_units);
+}
diff --git a/tools/wrk/src/units.h b/tools/wrk/src/units.h
new file mode 100644
index 000000000..3c16def4b
--- /dev/null
+++ b/tools/wrk/src/units.h
@@ -0,0 +1,10 @@
+#ifndef UNITS_H
+#define UNITS_H
+
+char *format_binary(long double);
+char *format_metric(long double);
+char *format_time_us(long double);
+
+int scan_metric(char *, uint64_t *);
+
+#endif /* UNITS_H */
diff --git a/tools/wrk/src/wrk.c b/tools/wrk/src/wrk.c
new file mode 100644
index 000000000..ffc07057c
--- /dev/null
+++ b/tools/wrk/src/wrk.c
@@ -0,0 +1,482 @@
+// Copyright (C) 2012 - Will Glozer. All rights reserved.
+
+#include "wrk.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <math.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+
+#include "aprintf.h"
+#include "stats.h"
+#include "units.h"
+#include "zmalloc.h"
+#include "tinymt64.h"
+
+extern char *optarg;
+extern int optind, opterr;
+
+static struct config {
+ struct addrinfo addr;
+ uint64_t threads;
+ uint64_t connections;
+ uint64_t requests;
+ uint64_t timeout;
+} cfg;
+
+static struct {
+ size_t size;
+ char *buf;
+} request;
+
+static struct {
+ stats *latency;
+ stats *requests;
+ pthread_mutex_t mutex;
+} statistics;
+
+static const struct http_parser_settings parser_settings = {
+ .on_message_complete = request_complete
+};
+
+static void usage() {
+ printf("Usage: wrk <options> <url> \n"
+ " Options: \n"
+ " -c, --connections <n> Connections to keep open \n"
+ " -r, --requests <n> Total requests to make \n"
+ " -t, --threads <n> Number of threads to use \n"
+ " \n"
+ " -H, --header <h> Add header to request \n"
+ " -v, --version Print version details \n"
+ " \n"
+ " Numeric arguments may include a SI unit (2k, 2M, 2G)\n");
+}
+
+int main(int argc, char **argv) {
+ struct addrinfo *addrs, *addr;
+ struct http_parser_url parser_url;
+ char *url, **headers;
+ int rc;
+
+ headers = zmalloc((argc / 2) * sizeof(char *));
+
+ if (parse_args(&cfg, &url, headers, argc, argv)) {
+ usage();
+ exit(1);
+ }
+
+ if (http_parser_parse_url(url, strlen(url), 0, &parser_url)) {
+ fprintf(stderr, "invalid URL: %s\n", url);
+ exit(1);
+ }
+
+ char *host = extract_url_part(url, &parser_url, UF_HOST);
+ char *port = extract_url_part(url, &parser_url, UF_PORT);
+ char *service = port ? port : extract_url_part(url, &parser_url, UF_SCHEMA);
+ char *path = &url[parser_url.field_data[UF_PATH].off];
+
+ struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM
+ };
+
+ if ((rc = getaddrinfo(host, service, &hints, &addrs)) != 0) {
+ const char *msg = gai_strerror(rc);
+ fprintf(stderr, "unable to resolve %s:%s %s\n", host, service, msg);
+ exit(1);
+ }
+
+ for (addr = addrs; addr != NULL; addr = addr->ai_next) {
+ int fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
+ if (fd == -1) continue;
+ if (connect(fd, addr->ai_addr, addr->ai_addrlen) == -1) {
+ if (errno == EHOSTUNREACH || errno == ECONNREFUSED) {
+ close(fd);
+ continue;
+ }
+ }
+ close(fd);
+ break;
+ }
+
+ if (addr == NULL) {
+ char *msg = strerror(errno);
+ fprintf(stderr, "unable to connect to %s:%s %s\n", host, service, msg);
+ exit(1);
+ }
+
+ cfg.addr = *addr;
+ request.buf = format_request(host, port, path, headers);
+ request.size = strlen(request.buf);
+
+ pthread_mutex_init(&statistics.mutex, NULL);
+ statistics.latency = stats_alloc(SAMPLES);
+ statistics.requests = stats_alloc(SAMPLES);
+
+ thread *threads = zcalloc(cfg.threads * sizeof(thread));
+ uint64_t connections = cfg.connections / cfg.threads;
+ uint64_t requests = cfg.requests / cfg.threads;
+
+ for (uint64_t i = 0; i < cfg.threads; i++) {
+ thread *t = &threads[i];
+ t->connections = connections;
+ t->requests = requests;
+
+ if (pthread_create(&t->thread, NULL, &thread_main, t)) {
+ char *msg = strerror(errno);
+ fprintf(stderr, "unable to create thread %zu %s\n", i, msg);
+ exit(2);
+ }
+ }
+
+ printf("Making %"PRIu64" requests to %s\n", cfg.requests, url);
+ printf(" %"PRIu64" threads and %"PRIu64" connections\n", cfg.threads, cfg.connections);
+
+ uint64_t start = time_us();
+ uint64_t complete = 0;
+ uint64_t bytes = 0;
+ errors errors = { 0 };
+
+ for (uint64_t i = 0; i < cfg.threads; i++) {
+ thread *t = &threads[i];
+ pthread_join(t->thread, NULL);
+
+ complete += t->complete;
+ bytes += t->bytes;
+
+ errors.connect += t->errors.connect;
+ errors.read += t->errors.read;
+ errors.write += t->errors.write;
+ errors.timeout += t->errors.timeout;
+ errors.status += t->errors.status;
+ }
+
+ uint64_t runtime_us = time_us() - start;
+ long double runtime_s = runtime_us / 1000000.0;
+ long double req_per_s = complete / runtime_s;
+ long double bytes_per_s = bytes / runtime_s;
+
+ print_stats_header();
+ print_stats("Latency", statistics.latency, format_time_us);
+ print_stats("Req/Sec", statistics.requests, format_metric);
+
+ char *runtime_msg = format_time_us(runtime_us);
+
+ printf(" %"PRIu64" requests in %s, %sB read\n", complete, runtime_msg, format_binary(bytes));
+ if (errors.connect || errors.read || errors.write || errors.timeout) {
+ printf(" Socket errors: connect %d, read %d, write %d, timeout %d\n",
+ errors.connect, errors.read, errors.write, errors.timeout);
+ }
+
+ if (errors.status) {
+ printf(" Non-2xx or 3xx responses: %d\n", errors.status);
+ }
+
+ printf("Requests/sec: %9.2Lf\n", req_per_s);
+ printf("Transfer/sec: %10sB\n", format_binary(bytes_per_s));
+
+ return 0;
+}
+
+void *thread_main(void *arg) {
+ thread *thread = arg;
+
+ aeEventLoop *loop = aeCreateEventLoop(10 + cfg.connections * 3);
+ thread->cs = zmalloc(thread->connections * sizeof(connection));
+ thread->loop = loop;
+ tinymt64_init(&thread->rand, time_us());
+
+ connection *c = thread->cs;
+
+ for (uint64_t i = 0; i < thread->connections; i++, c++) {
+ c->thread = thread;
+ c->latency = 0;
+ connect_socket(thread, c);
+ }
+
+ aeCreateTimeEvent(loop, SAMPLE_INTERVAL_MS, sample_rate, thread, NULL);
+ aeCreateTimeEvent(loop, TIMEOUT_INTERVAL_MS, check_timeouts, thread, NULL);
+
+ thread->start = time_us();
+ aeMain(loop);
+
+ aeDeleteEventLoop(loop);
+ zfree(thread->cs);
+
+ return NULL;
+}
+
+static int connect_socket(thread *thread, connection *c) {
+ struct addrinfo addr = cfg.addr;
+ struct aeEventLoop *loop = thread->loop;
+ int fd, flags;
+
+ fd = socket(addr.ai_family, addr.ai_socktype, addr.ai_protocol);
+
+ flags = fcntl(fd, F_GETFL, 0);
+ fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+
+ if (connect(fd, addr.ai_addr, addr.ai_addrlen) == -1) {
+ if (errno != EINPROGRESS) {
+ thread->errors.connect++;
+ goto error;
+ }
+ }
+
+ flags = 1;
+ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(flags));
+
+ if (aeCreateFileEvent(loop, fd, AE_WRITABLE, socket_writeable, c) != AE_OK) {
+ goto error;
+ }
+
+ http_parser_init(&c->parser, HTTP_RESPONSE);
+ c->parser.data = c;
+ c->fd = fd;
+
+ return fd;
+
+ error:
+ close(fd);
+ return -1;
+}
+
+static int reconnect_socket(thread *thread, connection *c) {
+ aeDeleteFileEvent(thread->loop, c->fd, AE_WRITABLE | AE_READABLE);
+ close(c->fd);
+ return connect_socket(thread, c);
+}
+
+static int sample_rate(aeEventLoop *loop, long long id, void *data) {
+ thread *thread = data;
+
+ uint64_t n = rand64(&thread->rand, thread->connections);
+ uint64_t elapsed_ms = (time_us() - thread->start) / 1000;
+ connection *c = thread->cs + n;
+ uint64_t requests = (thread->complete / elapsed_ms) * 1000;
+
+ pthread_mutex_lock(&statistics.mutex);
+ stats_record(statistics.latency, c->latency);
+ stats_record(statistics.requests, requests);
+ pthread_mutex_unlock(&statistics.mutex);
+
+ return SAMPLE_INTERVAL_MS + rand64(&thread->rand, SAMPLE_INTERVAL_MS);
+}
+
+static int request_complete(http_parser *parser) {
+ connection *c = parser->data;
+ thread *thread = c->thread;
+
+ if (parser->status_code > 399) {
+ thread->errors.status++;
+ }
+
+ if (++thread->complete >= thread->requests) {
+ aeStop(thread->loop);
+ goto done;
+ }
+
+ c->latency = time_us() - c->start;
+ if (!http_should_keep_alive(parser)) goto reconnect;
+
+ http_parser_init(parser, HTTP_RESPONSE);
+ aeDeleteFileEvent(thread->loop, c->fd, AE_READABLE);
+ aeCreateFileEvent(thread->loop, c->fd, AE_WRITABLE, socket_writeable, c);
+
+ goto done;
+
+ reconnect:
+ reconnect_socket(thread, c);
+
+ done:
+ return 0;
+}
+
+static int check_timeouts(aeEventLoop *loop, long long id, void *data) {
+ thread *thread = data;
+ connection *c = thread->cs;
+
+ uint64_t maxAge = time_us() - (cfg.timeout * 1000);
+
+ for (uint64_t i = 0; i < thread->connections; i++, c++) {
+ if (maxAge > c->start) {
+ thread->errors.timeout++;
+ }
+ }
+
+ return TIMEOUT_INTERVAL_MS;
+}
+
+static void socket_writeable(aeEventLoop *loop, int fd, void *data, int mask) {
+ connection *c = data;
+
+ if (write(fd, request.buf, request.size) < request.size) goto error;
+ c->start = time_us();
+ aeDeleteFileEvent(loop, fd, AE_WRITABLE);
+ aeCreateFileEvent(loop, fd, AE_READABLE, socket_readable, c);
+
+ return;
+
+ error:
+ c->thread->errors.write++;
+ reconnect_socket(c->thread, c);
+}
+
+static void socket_readable(aeEventLoop *loop, int fd, void *data, int mask) {
+ connection *c = data;
+ ssize_t n;
+
+ if ((n = read(fd, c->buf, sizeof(c->buf))) == -1) goto error;
+ if (http_parser_execute(&c->parser, &parser_settings, c->buf, n) != n) goto error;
+ c->thread->bytes += n;
+
+ return;
+
+ error:
+ c->thread->errors.read++;
+ reconnect_socket(c->thread, c);
+}
+
+static uint64_t time_us() {
+ struct timeval t;
+ gettimeofday(&t, NULL);
+ return (t.tv_sec * 1000000) + t.tv_usec;
+}
+
+static uint64_t rand64(tinymt64_t *state, uint64_t n) {
+ uint64_t x, max = ~UINT64_C(0);
+ max -= max % n;
+ do {
+ x = tinymt64_generate_uint64(state);
+ } while (x >= max);
+ return x % n;
+}
+
+static char *extract_url_part(char *url, struct http_parser_url *parser_url, enum http_parser_url_fields field) {
+ char *part = NULL;
+
+ if (parser_url->field_set & (1 << field)) {
+ uint16_t off = parser_url->field_data[field].off;
+ uint16_t len = parser_url->field_data[field].len;
+ part = zcalloc(len + 1 * sizeof(char));
+ memcpy(part, &url[off], len);
+ }
+
+ return part;
+}
+
+static char *format_request(char *host, char *port, char *path, char **headers) {
+ char *req = NULL;
+
+ aprintf(&req, "GET %s HTTP/1.1\r\n", path);
+ aprintf(&req, "Host: %s", host);
+ if (port) aprintf(&req, ":%s", port);
+ aprintf(&req, "\r\n");
+
+ for (char **h = headers; *h != NULL; h++) {
+ aprintf(&req, "%s\r\n", *h);
+ }
+
+ aprintf(&req, "\r\n");
+ return req;
+}
+
+static struct option longopts[] = {
+ { "connections", required_argument, NULL, 'c' },
+ { "requests", required_argument, NULL, 'r' },
+ { "threads", required_argument, NULL, 't' },
+ { "header", required_argument, NULL, 'H' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { NULL, 0, NULL, 0 }
+};
+
+static int parse_args(struct config *cfg, char **url, char **headers, int argc, char **argv) {
+ char c, **header = headers;
+
+ memset(cfg, 0, sizeof(struct config));
+ cfg->threads = 2;
+ cfg->connections = 10;
+ cfg->requests = 100;
+ cfg->timeout = SOCKET_TIMEOUT_MS;
+
+ while ((c = getopt_long(argc, argv, "t:c:r:H:v?", longopts, NULL)) != -1) {
+ switch (c) {
+ case 't':
+ if (scan_metric(optarg, &cfg->threads)) return -1;
+ break;
+ case 'c':
+ if (scan_metric(optarg, &cfg->connections)) return -1;
+ break;
+ case 'r':
+ if (scan_metric(optarg, &cfg->requests)) return -1;
+ break;
+ case 'H':
+ *header++ = optarg;
+ break;
+ case 'v':
+ printf("wrk %s [%s] ", VERSION, aeGetApiName());
+ printf("Copyright (C) 2012 Will Glozer\n");
+ break;
+ case 'h':
+ case '?':
+ case ':':
+ default:
+ return -1;
+ }
+ }
+
+ if (optind == argc || !cfg->threads || !cfg->requests) return -1;
+
+ if (!cfg->connections || cfg->connections < cfg->threads) {
+ fprintf(stderr, "number of connections must be >= threads\n");
+ return -1;
+ }
+
+ *url = argv[optind];
+ *header = NULL;
+
+ return 0;
+}
+
+static void print_stats_header() {
+ printf(" Thread Stats%6s%11s%8s%12s\n", "Avg", "Stdev", "Max", "+/- Stdev");
+}
+
+static void print_units(long double n, char *(*fmt)(long double), int width) {
+ char *msg = fmt(n);
+ int len = strlen(msg), pad = 2;
+
+ if (isalpha(msg[len-1])) pad--;
+ if (isalpha(msg[len-2])) pad--;
+ width -= pad;
+
+ printf("%*.*s%.*s", width, width, msg, pad, " ");
+
+ free(msg);
+}
+
+static void print_stats(char *name, stats *stats, char *(*fmt)(long double)) {
+ long double mean = stats_mean(stats);
+ long double max = stats_max(stats);
+ long double stdev = stats_stdev(stats, mean);
+
+ printf(" %-10s", name);
+ print_units(mean, fmt, 8);
+ print_units(stdev, fmt, 10);
+ print_units(max, fmt, 9);
+ printf("%8.2Lf%%\n", stats_within_stdev(stats, mean, stdev, 1));
+}
diff --git a/tools/wrk/src/wrk.h b/tools/wrk/src/wrk.h
new file mode 100644
index 000000000..e445b5bf6
--- /dev/null
+++ b/tools/wrk/src/wrk.h
@@ -0,0 +1,75 @@
+#ifndef WRK_H
+#define WRK_H
+
+#include "config.h"
+#include <pthread.h>
+#include <inttypes.h>
+#include <sys/types.h>
+
+#include "stats.h"
+#include "ae.h"
+#include "http_parser.h"
+#include "tinymt64.h"
+
+#define VERSION "1.0.0"
+#define RECVBUF 8192
+#define SAMPLES 100000
+
+#define SOCKET_TIMEOUT_MS 2000
+#define SAMPLE_INTERVAL_MS 100
+#define TIMEOUT_INTERVAL_MS 2000
+
+typedef struct {
+ uint32_t connect;
+ uint32_t read;
+ uint32_t write;
+ uint32_t status;
+ uint32_t timeout;
+} errors;
+
+typedef struct {
+ pthread_t thread;
+ aeEventLoop *loop;
+ uint64_t connections;
+ uint64_t requests;
+ uint64_t complete;
+ uint64_t bytes;
+ uint64_t start;
+ tinymt64_t rand;
+ errors errors;
+ struct connection *cs;
+} thread;
+
+typedef struct connection {
+ thread *thread;
+ http_parser parser;
+ int fd;
+ uint64_t start;
+ uint64_t latency;
+ char buf[RECVBUF];
+} connection;
+
+struct config;
+
+static void *thread_main(void *);
+static int connect_socket(thread *, connection *);
+static int reconnect_socket(thread *, connection *);
+
+static int sample_rate(aeEventLoop *, long long, void *);
+static int check_timeouts(aeEventLoop *, long long, void *);
+
+static void socket_writeable(aeEventLoop *, int, void *, int);
+static void socket_readable(aeEventLoop *, int, void *, int);
+static int request_complete(http_parser *);
+
+static uint64_t time_us();
+static uint64_t rand64(tinymt64_t *, uint64_t);
+
+static char *extract_url_part(char *, struct http_parser_url *, enum http_parser_url_fields);
+static char *format_request(char *, char *, char *, char **);
+
+static int parse_args(struct config *, char **, char **, int, char **);
+static void print_stats_header();
+static void print_stats(char *, stats *, char *(*)(long double));
+
+#endif /* WRK_H */
diff --git a/tools/wrk/src/zmalloc.c b/tools/wrk/src/zmalloc.c
new file mode 100644
index 000000000..89f80d833
--- /dev/null
+++ b/tools/wrk/src/zmalloc.c
@@ -0,0 +1,287 @@
+/* zmalloc - total amount of allocated memory aware version of malloc()
+ *
+ * Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
+ * 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 Redis 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "config.h"
+#include "zmalloc.h"
+
+#ifdef HAVE_MALLOC_SIZE
+#define PREFIX_SIZE (0)
+#else
+#if defined(__sun) || defined(__sparc) || defined(__sparc__)
+#define PREFIX_SIZE (sizeof(long long))
+#else
+#define PREFIX_SIZE (sizeof(size_t))
+#endif
+#endif
+
+/* Explicitly override malloc/free etc when using tcmalloc. */
+#if defined(USE_TCMALLOC)
+#define malloc(size) tc_malloc(size)
+#define calloc(count,size) tc_calloc(count,size)
+#define realloc(ptr,size) tc_realloc(ptr,size)
+#define free(ptr) tc_free(ptr)
+#elif defined(USE_JEMALLOC)
+#define malloc(size) je_malloc(size)
+#define calloc(count,size) je_calloc(count,size)
+#define realloc(ptr,size) je_realloc(ptr,size)
+#define free(ptr) je_free(ptr)
+#endif
+
+#define update_zmalloc_stat_alloc(__n,__size) do { \
+ size_t _n = (__n); \
+ if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
+ if (zmalloc_thread_safe) { \
+ pthread_mutex_lock(&used_memory_mutex); \
+ used_memory += _n; \
+ pthread_mutex_unlock(&used_memory_mutex); \
+ } else { \
+ used_memory += _n; \
+ } \
+} while(0)
+
+#define update_zmalloc_stat_free(__n) do { \
+ size_t _n = (__n); \
+ if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
+ if (zmalloc_thread_safe) { \
+ pthread_mutex_lock(&used_memory_mutex); \
+ used_memory -= _n; \
+ pthread_mutex_unlock(&used_memory_mutex); \
+ } else { \
+ used_memory -= _n; \
+ } \
+} while(0)
+
+static size_t used_memory = 0;
+static int zmalloc_thread_safe = 0;
+pthread_mutex_t used_memory_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void zmalloc_oom(size_t size) {
+ fprintf(stderr, "zmalloc: Out of memory trying to allocate %zu bytes\n",
+ size);
+ fflush(stderr);
+ abort();
+}
+
+void *zmalloc(size_t size) {
+ void *ptr = malloc(size+PREFIX_SIZE);
+
+ if (!ptr) zmalloc_oom(size);
+#ifdef HAVE_MALLOC_SIZE
+ update_zmalloc_stat_alloc(zmalloc_size(ptr),size);
+ return ptr;
+#else
+ *((size_t*)ptr) = size;
+ update_zmalloc_stat_alloc(size+PREFIX_SIZE,size);
+ return (char*)ptr+PREFIX_SIZE;
+#endif
+}
+
+void *zcalloc(size_t size) {
+ void *ptr = calloc(1, size+PREFIX_SIZE);
+
+ if (!ptr) zmalloc_oom(size);
+#ifdef HAVE_MALLOC_SIZE
+ update_zmalloc_stat_alloc(zmalloc_size(ptr),size);
+ return ptr;
+#else
+ *((size_t*)ptr) = size;
+ update_zmalloc_stat_alloc(size+PREFIX_SIZE,size);
+ return (char*)ptr+PREFIX_SIZE;
+#endif
+}
+
+void *zrealloc(void *ptr, size_t size) {
+#ifndef HAVE_MALLOC_SIZE
+ void *realptr;
+#endif
+ size_t oldsize;
+ void *newptr;
+
+ if (ptr == NULL) return zmalloc(size);
+#ifdef HAVE_MALLOC_SIZE
+ oldsize = zmalloc_size(ptr);
+ newptr = realloc(ptr,size);
+ if (!newptr) zmalloc_oom(size);
+
+ update_zmalloc_stat_free(oldsize);
+ update_zmalloc_stat_alloc(zmalloc_size(newptr),size);
+ return newptr;
+#else
+ realptr = (char*)ptr-PREFIX_SIZE;
+ oldsize = *((size_t*)realptr);
+ newptr = realloc(realptr,size+PREFIX_SIZE);
+ if (!newptr) zmalloc_oom(size);
+
+ *((size_t*)newptr) = size;
+ update_zmalloc_stat_free(oldsize);
+ update_zmalloc_stat_alloc(size,size);
+ return (char*)newptr+PREFIX_SIZE;
+#endif
+}
+
+/* Provide zmalloc_size() for systems where this function is not provided by
+ * malloc itself, given that in that case we store an header with this
+ * information as the first bytes of every allocation. */
+#ifndef HAVE_MALLOC_SIZE
+size_t zmalloc_size(void *ptr) {
+ void *realptr = (char*)ptr-PREFIX_SIZE;
+ size_t size = *((size_t*)realptr);
+ /* Assume at least that all the allocations are padded at sizeof(long) by
+ * the underlying allocator. */
+ if (size&(sizeof(long)-1)) size += sizeof(long)-(size&(sizeof(long)-1));
+ return size+PREFIX_SIZE;
+}
+#endif
+
+void zfree(void *ptr) {
+#ifndef HAVE_MALLOC_SIZE
+ void *realptr;
+ size_t oldsize;
+#endif
+
+ if (ptr == NULL) return;
+#ifdef HAVE_MALLOC_SIZE
+ update_zmalloc_stat_free(zmalloc_size(ptr));
+ free(ptr);
+#else
+ realptr = (char*)ptr-PREFIX_SIZE;
+ oldsize = *((size_t*)realptr);
+ update_zmalloc_stat_free(oldsize+PREFIX_SIZE);
+ free(realptr);
+#endif
+}
+
+char *zstrdup(const char *s) {
+ size_t l = strlen(s)+1;
+ char *p = zmalloc(l);
+
+ memcpy(p,s,l);
+ return p;
+}
+
+size_t zmalloc_used_memory(void) {
+ size_t um;
+
+ if (zmalloc_thread_safe) pthread_mutex_lock(&used_memory_mutex);
+ um = used_memory;
+ if (zmalloc_thread_safe) pthread_mutex_unlock(&used_memory_mutex);
+ return um;
+}
+
+void zmalloc_enable_thread_safeness(void) {
+ zmalloc_thread_safe = 1;
+}
+
+/* Get the RSS information in an OS-specific way.
+ *
+ * WARNING: the function zmalloc_get_rss() is not designed to be fast
+ * and may not be called in the busy loops where Redis tries to release
+ * memory expiring or swapping out objects.
+ *
+ * For this kind of "fast RSS reporting" usages use instead the
+ * function RedisEstimateRSS() that is a much faster (and less precise)
+ * version of the funciton. */
+
+#if defined(HAVE_PROCFS)
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+size_t zmalloc_get_rss(void) {
+ int page = sysconf(_SC_PAGESIZE);
+ size_t rss;
+ char buf[4096];
+ char filename[256];
+ int fd, count;
+ char *p, *x;
+
+ snprintf(filename,256,"/proc/%d/stat",getpid());
+ if ((fd = open(filename,O_RDONLY)) == -1) return 0;
+ if (read(fd,buf,4096) <= 0) {
+ close(fd);
+ return 0;
+ }
+ close(fd);
+
+ p = buf;
+ count = 23; /* RSS is the 24th field in /proc/<pid>/stat */
+ while(p && count--) {
+ p = strchr(p,' ');
+ if (p) p++;
+ }
+ if (!p) return 0;
+ x = strchr(p,' ');
+ if (!x) return 0;
+ *x = '\0';
+
+ rss = strtoll(p,NULL,10);
+ rss *= page;
+ return rss;
+}
+#elif defined(HAVE_TASKINFO)
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <mach/task.h>
+#include <mach/mach_init.h>
+
+size_t zmalloc_get_rss(void) {
+ task_t task = MACH_PORT_NULL;
+ struct task_basic_info t_info;
+ mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
+
+ if (task_for_pid(current_task(), getpid(), &task) != KERN_SUCCESS)
+ return 0;
+ task_info(task, TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
+
+ return t_info.resident_size;
+}
+#else
+size_t zmalloc_get_rss(void) {
+ /* If we can't get the RSS in an OS-specific way for this system just
+ * return the memory usage we estimated in zmalloc()..
+ *
+ * Fragmentation will appear to be always 1 (no fragmentation)
+ * of course... */
+ return zmalloc_used_memory();
+}
+#endif
+
+/* Fragmentation = RSS / allocated-bytes */
+float zmalloc_get_fragmentation_ratio(void) {
+ return (float)zmalloc_get_rss()/zmalloc_used_memory();
+}
diff --git a/tools/wrk/src/zmalloc.h b/tools/wrk/src/zmalloc.h
new file mode 100644
index 000000000..995814c86
--- /dev/null
+++ b/tools/wrk/src/zmalloc.h
@@ -0,0 +1,83 @@
+/* zmalloc - total amount of allocated memory aware version of malloc()
+ *
+ * Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
+ * 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 Redis 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.
+ */
+
+#ifndef __ZMALLOC_H
+#define __ZMALLOC_H
+
+/* Double expansion needed for stringification of macro values. */
+#define __xstr(s) __str(s)
+#define __str(s) #s
+
+#if defined(USE_TCMALLOC)
+#define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR))
+#include <google/tcmalloc.h>
+#if TC_VERSION_MAJOR >= 1 && TC_VERSION_MINOR >= 6
+#define HAVE_MALLOC_SIZE 1
+#define zmalloc_size(p) tc_malloc_size(p)
+#else
+#error "Newer version of tcmalloc required"
+#endif
+
+#elif defined(USE_JEMALLOC)
+#define ZMALLOC_LIB ("jemalloc-" __xstr(JEMALLOC_VERSION_MAJOR) "." __xstr(JEMALLOC_VERSION_MINOR) "." __xstr(JEMALLOC_VERSION_BUGFIX))
+#define JEMALLOC_MANGLE
+#include <jemalloc/jemalloc.h>
+#if JEMALLOC_VERSION_MAJOR >= 2 && JEMALLOC_VERSION_MINOR >= 1
+#define HAVE_MALLOC_SIZE 1
+#define zmalloc_size(p) JEMALLOC_P(malloc_usable_size)(p)
+#else
+#error "Newer version of jemalloc required"
+#endif
+
+#elif defined(__APPLE__)
+#include <malloc/malloc.h>
+#define HAVE_MALLOC_SIZE 1
+#define zmalloc_size(p) malloc_size(p)
+#endif
+
+#ifndef ZMALLOC_LIB
+#define ZMALLOC_LIB "libc"
+#endif
+
+void *zmalloc(size_t size);
+void *zcalloc(size_t size);
+void *zrealloc(void *ptr, size_t size);
+void zfree(void *ptr);
+char *zstrdup(const char *s);
+size_t zmalloc_used_memory(void);
+void zmalloc_enable_thread_safeness(void);
+float zmalloc_get_fragmentation_ratio(void);
+size_t zmalloc_get_rss(void);
+
+#ifndef HAVE_MALLOC_SIZE
+size_t zmalloc_size(void *ptr);
+#endif
+
+#endif /* __ZMALLOC_H */
diff --git a/vcbuild.bat b/vcbuild.bat
index a9576263c..0a2bd5e1c 100644
--- a/vcbuild.bat
+++ b/vcbuild.bat
@@ -32,6 +32,9 @@ set buildnodeweak=
set noetw=
set noetw_arg=
set noetw_msi_arg=
+set noperfctr=
+set noperfctr_arg=
+set noperfctr_msi_arg=
:next-arg
if "%1"=="" goto args-done
@@ -46,6 +49,7 @@ if /i "%1"=="nobuild" set nobuild=1&goto arg-ok
if /i "%1"=="nosign" set nosign=1&goto arg-ok
if /i "%1"=="nosnapshot" set nosnapshot=1&goto arg-ok
if /i "%1"=="noetw" set noetw=1&goto arg-ok
+if /i "%1"=="noperfctr" set noperfctr=1&goto arg-ok
if /i "%1"=="licensertf" set licensertf=1&goto arg-ok
if /i "%1"=="test-uv" set test=test-uv&goto arg-ok
if /i "%1"=="test-internet" set test=test-internet&goto arg-ok
@@ -74,16 +78,20 @@ if "%config%"=="Debug" set debug_arg=--debug
if "%target_arch%"=="x64" set msiplatform=x64
if defined nosnapshot set nosnapshot_arg=--without-snapshot
if defined noetw set noetw_arg=--without-etw& set noetw_msi_arg=/p:NoETW=1
+if defined noperfctr set noperfctr_arg=--without-perfctr& set noperfctr_msi_arg=/p:NoPerfCtr=1
:project-gen
@rem Skip project generation if requested.
if defined noprojgen goto msbuild
@rem Generate the VS project.
-python configure %debug_arg% %nosnapshot_arg% %noetw_arg% --dest-cpu=%target_arch%
-if errorlevel 1 goto create-msvs-files-failed
-if not exist node.sln goto create-msvs-files-failed
-echo Project files generated.
+SETLOCAL
+ if defined VS100COMNTOOLS call "%VS100COMNTOOLS%\VCVarsQueryRegistry.bat"
+ python configure %debug_arg% %nosnapshot_arg% %noetw_arg% %noperfctr_arg% --dest-cpu=%target_arch%
+ if errorlevel 1 goto create-msvs-files-failed
+ if not exist node.sln goto create-msvs-files-failed
+ echo Project files generated.
+ENDLOCAL
:msbuild
@rem Skip project generation if requested.
@@ -125,7 +133,7 @@ if not defined msi goto run
python "%~dp0tools\getnodeversion.py" > "%temp%\node_version.txt"
if not errorlevel 0 echo Cannot determine current version of node.js & goto exit
for /F "tokens=*" %%i in (%temp%\node_version.txt) do set NODE_VERSION=%%i
-msbuild "%~dp0tools\msvs\msi\nodemsi.sln" /m /t:Clean,Build /p:Configuration=%config% /p:Platform=%msiplatform% /p:NodeVersion=%NODE_VERSION% %noetw_msi_arg% /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
+msbuild "%~dp0tools\msvs\msi\nodemsi.sln" /m /t:Clean,Build /p:Configuration=%config% /p:Platform=%msiplatform% /p:NodeVersion=%NODE_VERSION% %noetw_msi_arg% %noperfctr_msi_arg% /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
if errorlevel 1 goto exit
if defined nosign goto run
@@ -183,7 +191,7 @@ goto exit
:jslint
echo running jslint
set PYTHONPATH=tools/closure_linter/
-python tools/closure_linter/closure_linter/gjslint.py --unix_mode --strict --nojsdoc -r lib/ -r src/ -r test/ --exclude_files lib/punycode.js
+python tools/closure_linter/closure_linter/gjslint.py --unix_mode --strict --nojsdoc -r lib/ -r src/ --exclude_files lib/punycode.js
goto exit
:help